From 4f4f018e97c60d0c47ba45f23b17625bdb082831 Mon Sep 17 00:00:00 2001 From: TizenOpenSource Date: Thu, 4 Jan 2024 10:37:38 +0900 Subject: [PATCH] Imported Upstream version 3.12.0 --- .azure-pipelines/ci.yml | 48 + .azure-pipelines/posix-deps-apt.sh | 27 + .azure-pipelines/posix-steps.yml | 26 + .azure-pipelines/pr.yml | 28 + .azure-pipelines/prebuild-checks.yml | 24 + .azure-pipelines/windows-layout-steps.yml | 28 + .azure-pipelines/windows-steps.yml | 37 + .devcontainer/Dockerfile | 24 + .devcontainer/devcontainer.json | 81 + .gitattributes | 94 + .github/CODEOWNERS | 168 + .github/CONTRIBUTING.rst | 55 + .github/ISSUE_TEMPLATE/bug.md | 32 + .github/ISSUE_TEMPLATE/config.yml | 7 + .github/ISSUE_TEMPLATE/crash.md | 33 + .github/ISSUE_TEMPLATE/documentation.md | 9 + .github/ISSUE_TEMPLATE/feature.md | 28 + .github/PULL_REQUEST_TEMPLATE.md | 30 + .github/SECURITY.md | 17 + .github/dependabot.yml | 21 + .github/problem-matchers/gcc.json | 18 + .github/problem-matchers/msvc.json | 19 + .github/workflows/build.yml | 641 + .github/workflows/build_msi.yml | 38 + .github/workflows/documentation-links.yml | 27 + .github/workflows/lint.yml | 26 + .github/workflows/mypy.yml | 39 + .../workflows/new-bugs-announce-notifier.yml | 57 + .github/workflows/posix-deps-apt.sh | 25 + .github/workflows/project-updater.yml | 30 + .github/workflows/regen-abidump.sh | 8 + .github/workflows/require-pr-label.yml | 22 + .github/workflows/reusable-docs.yml | 108 + .github/workflows/stale.yml | 28 + .github/workflows/verify-ensurepip-wheels.yml | 33 + .gitignore | 158 + .mailmap | 3 + .pre-commit-config.yaml | 28 + .readthedocs.yml | 18 + Doc/Makefile | 54 +- Doc/README.rst | 3 - Doc/bugs.rst | 2 +- Doc/c-api/allocation.rst | 28 +- Doc/c-api/apiabiversion.rst | 2 +- Doc/c-api/arg.rst | 72 +- Doc/c-api/bool.rst | 31 +- Doc/c-api/buffer.rst | 35 +- Doc/c-api/bytearray.rst | 2 +- Doc/c-api/bytes.rst | 33 +- Doc/c-api/call.rst | 23 +- Doc/c-api/capsule.rst | 6 +- Doc/c-api/cell.rst | 2 +- Doc/c-api/code.rst | 165 +- Doc/c-api/codec.rst | 2 +- Doc/c-api/complex.rst | 16 +- Doc/c-api/concrete.rst | 6 +- Doc/c-api/conversion.rst | 4 +- Doc/c-api/datetime.rst | 71 +- Doc/c-api/dict.rst | 126 +- Doc/c-api/exceptions.rst | 161 +- Doc/c-api/file.rst | 4 +- Doc/c-api/float.rst | 20 +- Doc/c-api/frame.rst | 56 + Doc/c-api/function.rst | 82 +- Doc/c-api/gcsupport.rst | 84 +- Doc/c-api/import.rst | 49 +- Doc/c-api/init.rst | 450 +- Doc/c-api/init_config.rst | 80 +- Doc/c-api/intro.rst | 105 +- Doc/c-api/iterator.rst | 6 +- Doc/c-api/list.rst | 6 +- Doc/c-api/long.rst | 89 +- Doc/c-api/mapping.rst | 47 +- Doc/c-api/marshal.rst | 4 + Doc/c-api/memory.rst | 44 +- Doc/c-api/memoryview.rst | 2 +- Doc/c-api/method.rst | 8 +- Doc/c-api/module.rst | 67 +- Doc/c-api/none.rst | 14 +- Doc/c-api/number.rst | 12 +- Doc/c-api/object.rst | 135 +- Doc/c-api/perfmaps.rst | 50 + Doc/c-api/refcounting.rst | 139 +- Doc/c-api/sequence.rst | 6 +- Doc/c-api/set.rst | 14 +- Doc/c-api/slice.rst | 13 +- Doc/c-api/stable.rst | 87 +- Doc/c-api/structures.rst | 424 +- Doc/c-api/sys.rst | 23 +- Doc/c-api/tuple.rst | 56 +- Doc/c-api/type.rst | 238 +- Doc/c-api/typehints.rst | 2 +- Doc/c-api/typeobj.rst | 487 +- Doc/c-api/unicode.rst | 564 +- Doc/c-api/utilities.rst | 1 + Doc/c-api/veryhigh.rst | 26 +- Doc/c-api/weakref.rst | 18 +- Doc/conf.py | 246 +- Doc/constraints.txt | 24 + Doc/contents.rst | 9 - Doc/data/python3.11.abi | 16643 ----- Doc/data/python3.12.abi | 26477 ++++++++ Doc/data/refcounts.dat | 13 + Doc/data/stable_abi.dat | 20 +- Doc/distributing/index.rst | 180 +- Doc/distutils/_setuptools_disclaimer.rst | 5 - Doc/distutils/apiref.rst | 2041 - Doc/distutils/builtdist.rst | 392 - Doc/distutils/commandref.rst | 105 - Doc/distutils/configfile.rst | 144 - Doc/distutils/examples.rst | 340 - Doc/distutils/extending.rst | 98 - Doc/distutils/index.rst | 49 - Doc/distutils/introduction.rst | 203 - Doc/distutils/packageindex.rst | 16 - Doc/distutils/setupscript.rst | 713 - Doc/distutils/sourcedist.rst | 245 - Doc/distutils/uploading.rst | 8 - Doc/extending/building.rst | 127 +- Doc/extending/embedding.rst | 2 +- Doc/extending/extending.rst | 66 +- Doc/extending/newtypes.rst | 96 +- Doc/extending/newtypes_tutorial.rst | 183 +- Doc/extending/windows.rst | 10 +- Doc/faq/design.rst | 60 +- Doc/faq/extending.rst | 6 +- Doc/faq/general.rst | 14 +- Doc/faq/gui.rst | 11 +- Doc/faq/library.rst | 17 +- Doc/faq/programming.rst | 10 +- Doc/glossary.rst | 35 +- Doc/howto/annotations.rst | 326 +- Doc/howto/argparse.rst | 208 +- Doc/howto/clinic.rst | 1311 +- Doc/howto/curses.rst | 46 +- Doc/howto/descriptor.rst | 108 +- Doc/howto/enum.rst | 105 +- Doc/howto/functional.rst | 10 +- Doc/howto/index.rst | 1 + Doc/howto/instrumentation.rst | 6 +- Doc/howto/isolating-extensions.rst | 28 +- Doc/howto/logging-cookbook.rst | 49 +- Doc/howto/logging.rst | 16 +- Doc/howto/perf_profiling.rst | 208 + Doc/howto/pyporting.rst | 217 +- Doc/howto/regex.rst | 8 +- Doc/howto/sorting.rst | 6 +- Doc/howto/unicode.rst | 10 +- Doc/howto/urllib2.rst | 27 +- {Tools/scripts => Doc/includes}/diff.py | 1 - Doc/includes/email-headers.py | 3 +- {Tools/scripts => Doc/includes}/ndiff.py | 24 +- Doc/includes/{ => newtypes}/custom.c | 4 +- Doc/includes/{ => newtypes}/custom2.c | 28 +- Doc/includes/{ => newtypes}/custom3.c | 42 +- Doc/includes/{ => newtypes}/custom4.c | 38 +- Doc/includes/newtypes/pyproject.toml | 7 + Doc/includes/newtypes/setup.py | 8 + Doc/includes/{ => newtypes}/sublist.c | 0 Doc/includes/{ => newtypes}/test.py | 7 - Doc/includes/setup.py | 9 - Doc/includes/sqlite3/pysqlite_datetime.py | 22 - Doc/includes/turtle-star.py | 10 - Doc/includes/typestruct.h | 3 + Doc/install/index.rst | 1077 - Doc/installing/index.rst | 7 +- Doc/library/__main__.rst | 30 +- Doc/library/_thread.rst | 19 +- Doc/library/abc.rst | 2 +- Doc/library/argparse.rst | 106 +- Doc/library/array.rst | 4 +- Doc/library/ast.rst | 280 +- Doc/library/asynchat.rst | 217 - Doc/library/asyncio-dev.rst | 6 +- Doc/library/asyncio-eventloop.rst | 154 +- Doc/library/asyncio-exceptions.rst | 2 +- Doc/library/asyncio-extending.rst | 2 +- Doc/library/asyncio-future.rst | 2 +- Doc/library/asyncio-platforms.rst | 2 +- Doc/library/asyncio-policy.rst | 25 +- Doc/library/asyncio-runner.rst | 20 +- Doc/library/asyncio-stream.rst | 22 +- Doc/library/asyncio-subprocess.rst | 15 +- Doc/library/asyncio-task.rst | 171 +- Doc/library/asyncore.rst | 365 - Doc/library/atexit.rst | 13 + Doc/library/base64.rst | 2 +- Doc/library/binascii.rst | 4 +- Doc/library/bisect.rst | 68 +- Doc/library/bz2.rst | 5 +- Doc/library/calendar.rst | 223 +- Doc/library/cmath.rst | 70 +- Doc/library/code.rst | 4 +- Doc/library/codecs.rst | 26 +- Doc/library/codeop.rst | 18 +- Doc/library/collections.abc.rst | 18 +- Doc/library/collections.rst | 7 +- Doc/library/compileall.rst | 6 +- Doc/library/concurrent.futures.rst | 24 +- Doc/library/concurrent.rst | 4 +- Doc/library/configparser.rst | 81 +- Doc/library/constants.rst | 6 +- Doc/library/contextlib.rst | 7 + Doc/library/copy.rst | 2 +- Doc/library/copyreg.rst | 8 +- Doc/library/crypt.rst | 1 + Doc/library/csv.rst | 28 +- Doc/library/ctypes.rst | 262 +- Doc/library/curses.ascii.rst | 150 +- Doc/library/curses.rst | 799 +- Doc/library/dataclasses.rst | 169 +- Doc/library/datetime.rst | 104 +- Doc/library/decimal.rst | 210 +- Doc/library/devmode.rst | 25 +- Doc/library/difflib.rst | 35 +- Doc/library/dis.rst | 866 +- Doc/library/distribution.rst | 1 - Doc/library/distutils.rst | 49 - Doc/library/doctest.rst | 4 +- Doc/library/email.charset.rst | 16 +- Doc/library/email.encoders.rst | 2 +- Doc/library/email.generator.rst | 4 +- Doc/library/email.message.rst | 8 +- Doc/library/email.parser.rst | 4 +- Doc/library/email.policy.rst | 1 + Doc/library/email.rst | 3 - Doc/library/email.utils.rst | 22 +- Doc/library/ensurepip.rst | 2 +- Doc/library/enum.rst | 104 +- Doc/library/errno.rst | 28 + Doc/library/exceptions.rst | 68 +- Doc/library/faulthandler.rst | 4 +- Doc/library/fcntl.rst | 14 +- Doc/library/filecmp.rst | 4 +- Doc/library/fileinput.rst | 2 +- Doc/library/fnmatch.rst | 4 +- Doc/library/fractions.rst | 44 +- Doc/library/ftplib.rst | 23 +- Doc/library/functions.rst | 82 +- Doc/library/functools.rst | 58 +- Doc/library/gc.rst | 24 +- Doc/library/gettext.rst | 56 +- Doc/library/glob.rst | 2 +- Doc/library/graphlib.rst | 8 +- Doc/library/gzip.rst | 16 +- Doc/library/hashlib.rst | 184 +- Doc/library/html.entities.rst | 4 +- Doc/library/html.parser.rst | 2 +- Doc/library/http.client.rst | 75 +- Doc/library/http.rst | 25 + Doc/library/http.server.rst | 9 +- Doc/library/idle.rst | 2 +- Doc/library/imaplib.rst | 28 +- Doc/library/imghdr.rst | 4 +- Doc/library/imp.rst | 411 - Doc/library/importlib.metadata.rst | 32 +- Doc/library/importlib.resources.abc.rst | 18 +- Doc/library/importlib.resources.rst | 82 +- Doc/library/importlib.rst | 394 +- Doc/library/inspect.rst | 103 +- Doc/library/internet.rst | 2 +- Doc/library/intro.rst | 2 +- Doc/library/io.rst | 113 +- Doc/library/itertools.rst | 552 +- Doc/library/json.rst | 12 +- Doc/library/kde_example.png | Bin 0 -> 332212 bytes Doc/library/locale.rst | 20 +- Doc/library/logging.config.rst | 89 +- Doc/library/logging.handlers.rst | 23 +- Doc/library/logging.rst | 227 +- Doc/library/lzma.rst | 3 +- Doc/library/mailbox.rst | 8 +- Doc/library/marshal.rst | 4 +- Doc/library/math.rst | 38 +- Doc/library/mmap.rst | 14 +- Doc/library/msvcrt.rst | 2 +- Doc/library/multiprocessing.rst | 123 +- Doc/library/multiprocessing.shared_memory.rst | 44 +- Doc/library/netrc.rst | 16 +- Doc/library/nntplib.rst | 17 + Doc/library/operator.rst | 10 +- Doc/library/optparse.rst | 104 +- Doc/library/os.path.rst | 66 +- Doc/library/os.rst | 614 +- Doc/library/pathlib.rst | 270 +- Doc/library/pdb.rst | 223 +- Doc/library/pickle.rst | 3 +- Doc/library/pkgutil.rst | 42 +- Doc/library/platform.rst | 16 +- Doc/library/plistlib.rst | 23 +- Doc/library/poplib.rst | 22 +- Doc/library/posix.rst | 2 +- Doc/library/pprint.rst | 20 +- Doc/library/profile.rst | 2 +- Doc/library/pty.rst | 2 +- Doc/library/pwd.rst | 2 +- Doc/library/pyexpat.rst | 2 +- Doc/library/python.rst | 1 + Doc/library/queue.rst | 18 +- Doc/library/random.rst | 83 +- Doc/library/re.rst | 126 +- Doc/library/readline.rst | 2 +- Doc/library/reprlib.rst | 81 +- Doc/library/resource.rst | 2 +- Doc/library/runpy.rst | 38 +- Doc/library/sched.rst | 4 +- Doc/library/select.rst | 44 +- Doc/library/selectors.rst | 8 +- Doc/library/shelve.rst | 14 +- Doc/library/shlex.rst | 12 +- Doc/library/shutil.rst | 108 +- Doc/library/signal.rst | 4 +- Doc/library/site.rst | 32 +- Doc/library/smtpd.rst | 268 - Doc/library/smtplib.rst | 53 +- Doc/library/socket.rst | 125 +- Doc/library/socketserver.rst | 10 +- Doc/library/sqlite3.rst | 482 +- Doc/library/ssl.rst | 208 +- Doc/library/stat.rst | 8 +- Doc/library/statistics.rst | 108 +- Doc/library/stdtypes.rst | 348 +- Doc/library/string.rst | 12 +- Doc/library/stringprep.rst | 2 +- Doc/library/struct.rst | 20 +- Doc/library/subprocess.rst | 133 +- Doc/library/superseded.rst | 5 +- Doc/library/symtable.rst | 12 +- Doc/library/sys.monitoring.rst | 300 + Doc/library/sys.rst | 566 +- Doc/library/sysconfig.rst | 191 +- Doc/library/syslog.rst | 21 + Doc/library/tarfile.rst | 469 +- Doc/library/tempfile.rst | 103 +- Doc/library/test.rst | 93 +- Doc/library/textwrap.rst | 4 +- Doc/library/threading.rst | 36 +- Doc/library/timeit.rst | 26 +- Doc/library/tkinter.rst | 4 +- Doc/library/tkinter.ttk.rst | 2 +- Doc/library/token-list.inc | 16 +- Doc/library/token.rst | 2 + Doc/library/tokenize.rst | 14 +- Doc/library/traceback.rst | 101 +- Doc/library/tty.rst | 22 +- Doc/library/turtle.rst | 588 +- Doc/library/types.rst | 63 +- Doc/library/typing.rst | 3287 +- Doc/library/unicodedata.rst | 8 +- Doc/library/unittest.mock-examples.rst | 39 +- Doc/library/unittest.mock.rst | 10 +- Doc/library/unittest.rst | 102 +- Doc/library/urllib.error.rst | 19 +- Doc/library/urllib.parse.rst | 58 +- Doc/library/urllib.request.rst | 10 +- Doc/library/uuid.rst | 117 +- Doc/library/venv.rst | 168 +- Doc/library/warnings.rst | 40 +- Doc/library/wave.rst | 211 +- Doc/library/weakref.rst | 19 +- Doc/library/webbrowser.rst | 17 +- Doc/library/winreg.rst | 8 +- Doc/library/winsound.rst | 4 +- Doc/library/wsgiref.rst | 2 +- Doc/library/xml.etree.elementtree.rst | 17 +- Doc/library/xml.rst | 10 +- Doc/library/xml.sax.handler.rst | 2 +- Doc/library/xml.sax.utils.rst | 7 +- Doc/library/xmlrpc.client.rst | 2 +- Doc/library/xmlrpc.rst | 4 +- Doc/library/zipapp.rst | 124 +- Doc/library/zipfile.rst | 12 +- Doc/library/zipimport.rst | 27 +- Doc/library/zoneinfo.rst | 2 +- Doc/license.rst | 328 +- Doc/make.bat | 388 +- Doc/reference/compound_stmts.rst | 381 +- Doc/reference/datamodel.rst | 2234 +- Doc/reference/executionmodel.rst | 118 +- Doc/reference/expressions.rst | 171 +- Doc/reference/import.rst | 89 +- Doc/reference/introduction.rst | 2 +- Doc/reference/lexical_analysis.rst | 194 +- Doc/reference/simple_stmts.rst | 122 +- Doc/reference/toplevel_components.rst | 10 +- Doc/requirements-oldest-sphinx.txt | 36 + Doc/requirements.txt | 10 +- Doc/tools/.nitignore | 187 + Doc/tools/check-warnings.py | 311 + Doc/tools/extensions/asdl_highlight.py | 3 +- Doc/tools/extensions/c_annotations.py | 36 +- Doc/tools/extensions/peg_highlight.py | 2 +- Doc/tools/extensions/pyspecific.py | 98 +- Doc/tools/extensions/suspicious.py | 251 - Doc/tools/rstlint.py | 408 - Doc/tools/susp-ignored.csv | 398 - Doc/tools/templates/customsourcelink.html | 2 +- Doc/tools/templates/dummy.html | 5 + Doc/tools/templates/indexcontent.html | 1 + Doc/tools/templates/layout.html | 12 +- Doc/tools/templates/search.html | 74 +- Doc/tutorial/appendix.rst | 8 +- Doc/tutorial/classes.rst | 48 +- Doc/tutorial/controlflow.rst | 42 +- Doc/tutorial/datastructures.rst | 12 +- Doc/tutorial/errors.rst | 27 +- Doc/tutorial/floatingpoint.rst | 160 +- Doc/tutorial/inputoutput.rst | 14 +- Doc/tutorial/interactive.rst | 2 +- Doc/tutorial/interpreter.rst | 10 +- Doc/tutorial/introduction.rst | 46 +- Doc/tutorial/modules.rst | 52 +- Doc/tutorial/stdlib.rst | 16 +- Doc/tutorial/stdlib2.rst | 6 +- Doc/tutorial/venv.rst | 8 +- Doc/using/cmdline.rst | 68 +- Doc/using/configure.rst | 211 +- Doc/using/mac.rst | 14 +- Doc/using/unix.rst | 13 +- Doc/using/venv-create.inc | 11 +- Doc/using/windows.rst | 42 +- Doc/whatsnew/2.0.rst | 20 +- Doc/whatsnew/2.1.rst | 20 +- Doc/whatsnew/2.2.rst | 22 +- Doc/whatsnew/2.3.rst | 24 +- Doc/whatsnew/2.4.rst | 8 +- Doc/whatsnew/2.5.rst | 24 +- Doc/whatsnew/2.6.rst | 40 +- Doc/whatsnew/2.7.rst | 37 +- Doc/whatsnew/3.0.rst | 10 +- Doc/whatsnew/3.1.rst | 10 +- Doc/whatsnew/3.10.rst | 95 +- Doc/whatsnew/3.11.rst | 360 +- Doc/whatsnew/3.12.rst | 2420 + Doc/whatsnew/3.2.rst | 78 +- Doc/whatsnew/3.3.rst | 151 +- Doc/whatsnew/3.4.rst | 74 +- Doc/whatsnew/3.5.rst | 28 +- Doc/whatsnew/3.6.rst | 34 +- Doc/whatsnew/3.7.rst | 30 +- Doc/whatsnew/3.8.rst | 39 +- Doc/whatsnew/3.9.rst | 83 +- Doc/whatsnew/index.rst | 1 + Grammar/Tokens | 8 +- Grammar/python.gram | 127 +- Include/README.rst | 6 +- Include/abstract.h | 42 +- Include/boolobject.h | 13 +- Include/bytearrayobject.h | 4 +- Include/bytesobject.h | 2 +- Include/ceval.h | 2 +- Include/complexobject.h | 4 +- Include/cpython/abstract.h | 25 +- Include/cpython/bytearrayobject.h | 8 +- Include/cpython/bytesobject.h | 8 +- Include/cpython/cellobject.h | 19 +- Include/cpython/ceval.h | 11 +- Include/cpython/classobject.h | 38 +- Include/cpython/code.h | 213 +- Include/cpython/compile.h | 19 +- Include/cpython/context.h | 6 +- Include/cpython/dictobject.h | 42 +- Include/cpython/fileobject.h | 1 + Include/cpython/floatobject.h | 10 +- Include/cpython/funcobject.h | 111 +- Include/cpython/genobject.h | 15 +- Include/cpython/import.h | 5 +- Include/cpython/initconfig.h | 7 +- .../interpreteridobject.h} | 17 +- Include/cpython/listobject.h | 10 +- Include/cpython/longintrepr.h | 40 +- Include/cpython/longobject.h | 5 + Include/cpython/memoryobject.h | 52 + Include/cpython/methodobject.h | 20 +- Include/cpython/modsupport.h | 10 +- Include/cpython/object.h | 144 +- Include/cpython/objimpl.h | 16 +- Include/cpython/odictobject.h | 12 +- Include/cpython/picklebufobject.h | 2 +- Include/cpython/pydebug.h | 36 +- Include/cpython/pyerrors.h | 37 +- Include/cpython/pyframe.h | 18 + Include/cpython/pylifecycle.h | 48 +- Include/cpython/pystate.h | 134 +- Include/cpython/pythonrun.h | 28 +- Include/cpython/pytime.h | 8 + Include/cpython/setobject.h | 9 +- Include/cpython/tupleobject.h | 10 +- Include/cpython/unicodeobject.h | 442 +- Include/cpython/warnings.h | 2 +- Include/cpython/weakrefobject.h | 4 +- Include/datetime.h | 92 +- Include/descrobject.h | 56 + Include/dictobject.h | 8 +- Include/exports.h | 12 +- Include/fileobject.h | 8 +- Include/floatobject.h | 2 +- Include/import.h | 2 +- Include/internal/pycore_accu.h | 39 - Include/internal/pycore_asdl.h | 4 +- Include/internal/pycore_ast.h | 82 +- Include/internal/pycore_ast_state.h | 7 + Include/internal/pycore_atexit.h | 57 + Include/internal/pycore_bytesobject.h | 5 - Include/internal/pycore_call.h | 12 + Include/internal/pycore_ceval.h | 61 +- Include/internal/pycore_ceval_state.h | 103 + Include/internal/pycore_code.h | 374 +- Include/internal/pycore_compile.h | 84 +- Include/internal/pycore_context.h | 4 + Include/internal/pycore_descrobject.h | 26 + Include/internal/pycore_dict.h | 81 +- Include/internal/pycore_dict_state.h | 50 + Include/internal/pycore_dtoa.h | 49 +- Include/internal/pycore_faulthandler.h | 99 + Include/internal/pycore_fileutils.h | 25 +- Include/internal/pycore_fileutils_windows.h | 98 + Include/internal/pycore_floatobject.h | 12 + Include/internal/pycore_flowgraph.h | 120 + Include/internal/pycore_format.h | 2 - Include/internal/pycore_frame.h | 123 +- Include/internal/pycore_function.h | 8 + Include/internal/pycore_gc.h | 70 +- Include/internal/pycore_genobject.h | 2 +- Include/internal/pycore_global_objects.h | 49 +- .../pycore_global_objects_fini_generated.h | 1531 + Include/internal/pycore_global_strings.h | 416 +- Include/internal/pycore_hamt.h | 13 +- Include/internal/pycore_hashtable.h | 4 +- Include/internal/pycore_import.h | 160 +- Include/internal/pycore_initconfig.h | 12 +- Include/internal/pycore_instruments.h | 106 + Include/internal/pycore_interp.h | 185 +- Include/internal/pycore_intrinsics.h | 32 + Include/internal/pycore_list.h | 23 +- Include/internal/pycore_long.h | 144 + Include/internal/pycore_memoryobject.h | 18 + Include/internal/pycore_moduleobject.h | 3 + Include/internal/pycore_object.h | 211 +- Include/internal/pycore_object_state.h | 36 + Include/internal/pycore_obmalloc.h | 698 + Include/internal/pycore_obmalloc_init.h | 73 + Include/internal/pycore_opcode.h | 396 +- Include/internal/pycore_opcode_utils.h | 92 + Include/internal/pycore_parser.h | 35 + Include/internal/pycore_pyerrors.h | 13 +- Include/internal/pycore_pyhash.h | 32 +- Include/internal/pycore_pylifecycle.h | 16 +- Include/internal/pycore_pymath.h | 19 - Include/internal/pycore_pymem.h | 62 +- Include/internal/pycore_pymem_init.h | 85 + Include/internal/pycore_pystate.h | 72 +- Include/internal/pycore_pythread.h | 81 + Include/internal/pycore_range.h | 21 + Include/internal/pycore_runtime.h | 82 +- Include/internal/pycore_runtime_init.h | 1283 +- .../internal/pycore_runtime_init_generated.h | 1525 + Include/internal/pycore_signal.h | 63 + Include/internal/pycore_sliceobject.h | 2 + Include/internal/pycore_structseq.h | 15 +- Include/internal/pycore_symtable.h | 36 +- Include/internal/pycore_sysmodule.h | 3 + Include/internal/pycore_time.h | 25 + Include/{token.h => internal/pycore_token.h} | 45 +- Include/internal/pycore_tracemalloc.h | 123 + Include/internal/pycore_tuple.h | 10 +- Include/internal/pycore_typeobject.h | 125 +- Include/internal/pycore_typevarobject.h | 24 + Include/internal/pycore_unicodeobject.h | 10 +- .../internal/pycore_unicodeobject_generated.h | 2093 + Include/internal/pycore_unionobject.h | 4 +- Include/interpreteridobject.h | 17 + Include/iterobject.h | 4 +- Include/listobject.h | 2 +- Include/longobject.h | 2 +- Include/memoryobject.h | 46 +- Include/methodobject.h | 4 +- Include/modsupport.h | 16 +- Include/moduleobject.h | 26 +- Include/object.h | 281 +- Include/objimpl.h | 23 +- Include/opcode.h | 229 +- Include/patchlevel.h | 6 +- Include/py_curses.h | 2 +- Include/pybuffer.h | 5 +- Include/pycapsule.h | 2 +- Include/pydtrace.h | 2 +- Include/pyerrors.h | 10 +- Include/pymacconfig.h | 12 - Include/pymacro.h | 34 +- Include/pymath.h | 25 +- Include/pymem.h | 14 +- Include/pyport.h | 94 +- Include/pystats.h | 110 + Include/pythonrun.h | 4 + Include/pythread.h | 4 +- Include/rangeobject.h | 2 +- Include/setobject.h | 10 +- Include/sliceobject.h | 2 +- Include/structmember.h | 95 +- Include/structseq.h | 4 +- Include/sysmodule.h | 13 + Include/traceback.h | 2 +- Include/tracemalloc.h | 34 + Include/tupleobject.h | 2 +- Include/unicodeobject.h | 47 +- Include/weakrefobject.h | 8 +- Lib/_aix_support.py | 31 +- Lib/_bootsubprocess.py | 97 - Lib/_collections_abc.py | 74 +- Lib/_pydatetime.py | 2647 + Lib/_pydecimal.py | 2 +- Lib/_pyio.py | 26 +- Lib/_pylong.py | 285 + Lib/_strptime.py | 25 +- Lib/abc.py | 2 +- Lib/argparse.py | 64 +- Lib/ast.py | 195 +- Lib/asyncio/__init__.py | 1 + Lib/asyncio/base_events.py | 43 +- Lib/asyncio/base_futures.py | 1 - Lib/asyncio/base_tasks.py | 10 +- Lib/asyncio/constants.py | 3 + Lib/asyncio/coroutines.py | 4 +- Lib/asyncio/events.py | 46 +- Lib/asyncio/futures.py | 4 +- Lib/asyncio/locks.py | 1 - Lib/asyncio/proactor_events.py | 3 +- Lib/asyncio/runners.py | 18 +- Lib/asyncio/selector_events.py | 143 +- Lib/asyncio/sslproto.py | 3 +- Lib/asyncio/streams.py | 36 +- Lib/asyncio/subprocess.py | 14 +- Lib/asyncio/taskgroups.py | 30 +- Lib/asyncio/tasks.py | 267 +- Lib/asyncio/timeouts.py | 19 +- Lib/asyncio/unix_events.py | 117 +- Lib/asyncio/windows_events.py | 82 +- Lib/base64.py | 33 +- Lib/bdb.py | 9 +- Lib/bisect.py | 8 + Lib/cProfile.py | 11 +- Lib/calendar.py | 76 +- Lib/cgitb.py | 2 +- Lib/code.py | 4 +- Lib/codecs.py | 10 - Lib/collections/__init__.py | 45 +- Lib/colorsys.py | 2 +- Lib/compileall.py | 8 +- Lib/concurrent/futures/process.py | 17 +- Lib/concurrent/futures/thread.py | 19 +- Lib/configparser.py | 63 +- Lib/contextlib.py | 15 +- Lib/copy.py | 28 +- Lib/copyreg.py | 12 +- Lib/csv.py | 21 +- Lib/ctypes/__init__.py | 15 +- Lib/ctypes/_aix.py | 8 +- Lib/ctypes/_endian.py | 2 +- Lib/ctypes/macholib/fetch_macholib.bat | 2 +- Lib/ctypes/test/__main__.py | 4 - Lib/ctypes/wintypes.py | 2 +- Lib/curses/ascii.py | 8 +- Lib/curses/textpad.py | 7 +- Lib/dataclasses.py | 174 +- Lib/datetime.py | 2642 +- Lib/dis.py | 65 +- Lib/distutils/README | 11 - Lib/distutils/__init__.py | 20 - Lib/distutils/_msvccompiler.py | 539 - Lib/distutils/archive_util.py | 256 - Lib/distutils/bcppcompiler.py | 393 - Lib/distutils/ccompiler.py | 1116 - Lib/distutils/cmd.py | 403 - Lib/distutils/command/__init__.py | 30 - Lib/distutils/command/bdist.py | 138 - Lib/distutils/command/bdist_dumb.py | 123 - Lib/distutils/command/bdist_rpm.py | 579 - Lib/distutils/command/build.py | 157 - Lib/distutils/command/build_clib.py | 209 - Lib/distutils/command/build_ext.py | 754 - Lib/distutils/command/build_py.py | 416 - Lib/distutils/command/build_scripts.py | 160 - Lib/distutils/command/check.py | 148 - Lib/distutils/command/clean.py | 76 - Lib/distutils/command/command_template | 33 - Lib/distutils/command/config.py | 344 - Lib/distutils/command/install.py | 679 - Lib/distutils/command/install_data.py | 79 - Lib/distutils/command/install_egg_info.py | 77 - Lib/distutils/command/install_headers.py | 47 - Lib/distutils/command/install_lib.py | 217 - Lib/distutils/command/install_scripts.py | 60 - Lib/distutils/command/register.py | 304 - Lib/distutils/command/sdist.py | 494 - Lib/distutils/command/upload.py | 215 - Lib/distutils/config.py | 133 - Lib/distutils/core.py | 234 - Lib/distutils/dep_util.py | 92 - Lib/distutils/dir_util.py | 210 - Lib/distutils/dist.py | 1256 - Lib/distutils/errors.py | 97 - Lib/distutils/extension.py | 241 - Lib/distutils/fancy_getopt.py | 457 - Lib/distutils/file_util.py | 238 - Lib/distutils/filelist.py | 327 - Lib/distutils/msvccompiler.py | 642 - Lib/distutils/spawn.py | 129 - Lib/distutils/sysconfig.py | 346 - Lib/distutils/tests/Setup.sample | 67 - Lib/distutils/tests/__init__.py | 41 - Lib/distutils/tests/includetest.rst | 1 - Lib/distutils/tests/support.py | 209 - Lib/distutils/tests/test_archive_util.py | 396 - Lib/distutils/tests/test_bdist.py | 52 - Lib/distutils/tests/test_bdist_dumb.py | 97 - Lib/distutils/tests/test_bdist_rpm.py | 141 - Lib/distutils/tests/test_build.py | 57 - Lib/distutils/tests/test_build_clib.py | 147 - Lib/distutils/tests/test_build_ext.py | 555 - Lib/distutils/tests/test_build_py.py | 181 - Lib/distutils/tests/test_build_scripts.py | 112 - Lib/distutils/tests/test_check.py | 163 - Lib/distutils/tests/test_clean.py | 49 - Lib/distutils/tests/test_cmd.py | 126 - Lib/distutils/tests/test_config.py | 141 - Lib/distutils/tests/test_config_cmd.py | 103 - Lib/distutils/tests/test_core.py | 140 - Lib/distutils/tests/test_cygwinccompiler.py | 154 - Lib/distutils/tests/test_dep_util.py | 80 - Lib/distutils/tests/test_dir_util.py | 143 - Lib/distutils/tests/test_dist.py | 529 - Lib/distutils/tests/test_extension.py | 70 - Lib/distutils/tests/test_file_util.py | 126 - Lib/distutils/tests/test_filelist.py | 340 - Lib/distutils/tests/test_install.py | 261 - Lib/distutils/tests/test_install_data.py | 75 - Lib/distutils/tests/test_install_headers.py | 39 - Lib/distutils/tests/test_install_lib.py | 117 - Lib/distutils/tests/test_install_scripts.py | 82 - Lib/distutils/tests/test_log.py | 46 - Lib/distutils/tests/test_msvc9compiler.py | 184 - Lib/distutils/tests/test_msvccompiler.py | 81 - Lib/distutils/tests/test_register.py | 324 - Lib/distutils/tests/test_sdist.py | 493 - Lib/distutils/tests/test_spawn.py | 139 - Lib/distutils/tests/test_sysconfig.py | 264 - Lib/distutils/tests/test_text_file.py | 107 - Lib/distutils/tests/test_unixccompiler.py | 145 - Lib/distutils/tests/test_upload.py | 223 - Lib/distutils/tests/test_util.py | 313 - Lib/distutils/tests/test_version.py | 87 - Lib/distutils/tests/test_versionpredicate.py | 13 - Lib/distutils/text_file.py | 286 - Lib/distutils/unixccompiler.py | 329 - Lib/distutils/util.py | 562 - Lib/distutils/version.py | 347 - Lib/distutils/versionpredicate.py | 166 - Lib/doctest.py | 10 +- Lib/email/__init__.py | 1 - Lib/email/_header_value_parser.py | 8 +- Lib/email/base64mime.py | 4 - Lib/email/charset.py | 16 +- Lib/email/encoders.py | 4 - Lib/email/feedparser.py | 6 +- Lib/email/generator.py | 7 +- Lib/email/header.py | 5 - Lib/email/iterators.py | 3 - Lib/email/message.py | 8 +- Lib/email/mime/base.py | 1 - Lib/email/mime/message.py | 1 - Lib/email/mime/multipart.py | 1 - Lib/email/mime/nonmultipart.py | 1 - Lib/email/mime/text.py | 4 +- Lib/email/parser.py | 8 +- Lib/email/utils.py | 48 +- Lib/encodings/idna.py | 10 + Lib/ensurepip/__init__.py | 18 +- ...ne-any.whl => pip-23.2.1-py3-none-any.whl} | Bin 2051534 -> 2086091 bytes .../setuptools-65.5.0-py3-none-any.whl | Bin 1232695 -> 0 bytes Lib/enum.py | 414 +- Lib/filecmp.py | 8 +- Lib/fileinput.py | 2 +- Lib/fractions.py | 402 +- Lib/ftplib.py | 36 +- Lib/functools.py | 28 +- Lib/genericpath.py | 14 +- Lib/getopt.py | 2 +- Lib/gettext.py | 20 +- Lib/gzip.py | 74 +- Lib/hashlib.py | 82 +- Lib/html/__init__.py | 2 +- Lib/html/entities.py | 9 +- Lib/html/parser.py | 3 +- Lib/http/__init__.py | 20 + Lib/http/client.py | 154 +- Lib/http/cookiejar.py | 19 +- Lib/http/server.py | 9 +- Lib/idlelib/NEWS.txt | 23 +- Lib/idlelib/autocomplete_w.py | 10 +- Lib/idlelib/calltip_w.py | 8 +- Lib/idlelib/colorizer.py | 2 +- Lib/idlelib/debugger.py | 7 +- Lib/idlelib/debugobj.py | 2 +- Lib/idlelib/dynoption.py | 25 +- Lib/idlelib/editor.py | 177 +- Lib/idlelib/filelist.py | 4 +- Lib/idlelib/help_about.py | 37 +- Lib/idlelib/idle.bat | 8 +- Lib/idlelib/idle_test/README.txt | 19 +- Lib/idlelib/idle_test/__init__.py | 24 +- Lib/idlelib/idle_test/test_config.py | 2 +- Lib/idlelib/idle_test/test_editor.py | 36 +- Lib/idlelib/idle_test/test_help_about.py | 4 +- Lib/idlelib/idle_test/test_iomenu.py | 6 + Lib/idlelib/idle_test/test_outwin.py | 2 +- Lib/idlelib/idle_test/test_run.py | 3 +- Lib/idlelib/idle_test/test_sidebar.py | 9 +- Lib/idlelib/idle_test/test_stackviewer.py | 14 +- Lib/idlelib/macosx.py | 6 +- Lib/idlelib/multicall.py | 10 +- Lib/idlelib/outwin.py | 4 +- Lib/idlelib/pyshell.py | 32 +- Lib/idlelib/redirector.py | 8 +- Lib/idlelib/rpc.py | 4 +- Lib/idlelib/run.py | 23 +- Lib/idlelib/stackviewer.py | 41 +- Lib/idlelib/textview.py | 2 +- Lib/idlelib/tooltip.py | 8 +- Lib/idlelib/tree.py | 2 +- Lib/idlelib/undo.py | 2 +- Lib/imaplib.py | 25 +- Lib/imghdr.py | 23 +- Lib/imp.py | 346 - Lib/importlib/__init__.py | 46 +- Lib/importlib/_abc.py | 15 - Lib/importlib/_bootstrap.py | 454 +- Lib/importlib/_bootstrap_external.py | 249 +- Lib/importlib/abc.py | 111 +- Lib/importlib/metadata/__init__.py | 305 +- Lib/importlib/metadata/_adapters.py | 21 + Lib/importlib/metadata/_meta.py | 28 +- Lib/importlib/resources/_adapters.py | 4 +- Lib/importlib/resources/_common.py | 148 +- Lib/importlib/resources/_itertools.py | 69 +- Lib/importlib/resources/_legacy.py | 3 +- Lib/importlib/resources/abc.py | 26 +- Lib/importlib/resources/readers.py | 50 +- Lib/importlib/resources/simple.py | 79 +- Lib/importlib/util.py | 144 +- Lib/inspect.py | 312 +- Lib/io.py | 16 - Lib/ipaddress.py | 3 - Lib/keyword.py | 3 +- Lib/lib2to3/pgen2/token.py | 2 +- Lib/locale.py | 23 +- Lib/logging/__init__.py | 119 +- Lib/logging/config.py | 136 +- Lib/logging/handlers.py | 3 +- Lib/mailbox.py | 5 +- Lib/mailcap.py | 4 +- Lib/mimetypes.py | 9 +- Lib/multiprocessing/connection.py | 222 +- Lib/multiprocessing/context.py | 1 + Lib/multiprocessing/forkserver.py | 2 +- Lib/multiprocessing/managers.py | 1 - Lib/multiprocessing/pool.py | 2 +- Lib/multiprocessing/process.py | 2 +- Lib/multiprocessing/queues.py | 2 + Lib/multiprocessing/spawn.py | 12 +- Lib/multiprocessing/synchronize.py | 11 +- Lib/netrc.py | 2 +- Lib/ntpath.py | 204 +- Lib/numbers.py | 31 +- Lib/opcode.py | 294 +- Lib/os.py | 160 +- Lib/pathlib.py | 1618 +- Lib/pdb.py | 227 +- Lib/pickle.py | 10 +- Lib/pkgutil.py | 213 +- Lib/platform.py | 262 +- Lib/plistlib.py | 29 +- Lib/poplib.py | 26 +- Lib/posixpath.py | 61 +- Lib/pprint.py | 16 - Lib/profile.py | 11 +- Lib/pstats.py | 2 - Lib/pty.py | 80 +- Lib/pydoc.py | 91 +- Lib/pydoc_data/topics.py | 3529 +- Lib/quopri.py | 9 +- Lib/random.py | 153 +- Lib/re/__init__.py | 89 +- Lib/re/_constants.py | 2 +- Lib/re/_parser.py | 89 +- Lib/reprlib.py | 57 +- Lib/runpy.py | 7 +- Lib/secrets.py | 3 +- Lib/shlex.py | 9 +- Lib/shutil.py | 302 +- Lib/site.py | 32 +- Lib/smtplib.py | 47 +- Lib/socket.py | 3 +- Lib/socketserver.py | 10 +- Lib/sqlite3/__init__.py | 21 +- Lib/sqlite3/__main__.py | 127 + Lib/sqlite3/dbapi2.py | 37 +- Lib/sqlite3/dump.py | 20 +- Lib/ssl.py | 129 +- Lib/statistics.py | 142 +- Lib/subprocess.py | 313 +- Lib/sunau.py | 4 +- Lib/symtable.py | 15 +- Lib/sysconfig.py | 149 +- Lib/tabnanny.py | 13 +- Lib/tarfile.py | 420 +- Lib/tempfile.py | 111 +- Lib/test/.ruff.toml | 42 + Lib/test/_test_eintr.py | 14 +- Lib/test/_test_embed_set_config.py | 1 - Lib/test/_test_embed_structseq.py | 40 +- Lib/test/_test_multiprocessing.py | 344 +- Lib/test/_test_venv_multiprocessing.py | 2 +- Lib/test/audiodata/pluck-pcm24-ext.wav | Bin 0 -> 19922 bytes Lib/test/audit-tests.py | 74 + Lib/test/bisect_cmd.py | 7 +- Lib/test/{clinic.test => clinic.test.c} | 1566 +- Lib/test/cmath_testcases.txt | 3 + Lib/test/crashers/infinite_loop_re.py | 2 +- Lib/test/datetimetester.py | 145 +- Lib/test/fork_wait.py | 39 +- Lib/test/inspect_fodder.py | 15 +- Lib/test/inspect_fodder2.py | 17 + Lib/test/leakers/test_ctypes.py | 2 +- Lib/test/levenshtein_examples.json | 50002 +++++++++++++++ Lib/test/libregrtest/cmdline.py | 15 +- Lib/test/libregrtest/main.py | 630 +- Lib/test/libregrtest/refleak.py | 21 +- Lib/test/libregrtest/runtest.py | 593 +- Lib/test/libregrtest/runtest_mp.py | 276 +- Lib/test/libregrtest/save_env.py | 16 +- Lib/test/libregrtest/setup.py | 2 +- Lib/test/libregrtest/utils.py | 110 +- Lib/test/list_tests.py | 7 +- Lib/test/lock_tests.py | 1 - Lib/test/mapping_tests.py | 3 +- Lib/test/memory_watchdog.py | 11 +- Lib/test/mock_socket.py | 4 +- Lib/test/mod_generics_cache.py | 5 +- Lib/test/pickletester.py | 1 + Lib/test/profilee.py | 2 +- Lib/test/pydocfodder.py | 80 +- Lib/test/pythoninfo.py | 25 +- Lib/test/setuptools-67.6.1-py3-none-any.whl | Bin 0 -> 1089263 bytes Lib/test/shadowed_super.py | 7 + Lib/test/signalinterproctester.py | 13 +- Lib/{ => test}/smtpd.py | 16 +- Lib/test/string_tests.py | 48 + Lib/test/support/__init__.py | 437 +- .../support/_hypothesis_stubs/__init__.py | 111 + .../support/_hypothesis_stubs/_helpers.py | 43 + .../support/_hypothesis_stubs/strategies.py | 91 + Lib/test/support/ast_helper.py | 43 + Lib/{ => test/support}/asynchat.py | 14 +- Lib/{ => test/support}/asyncore.py | 16 +- Lib/test/support/bytecode_helper.py | 101 + Lib/test/support/hypothesis_helper.py | 38 + Lib/test/support/import_helper.py | 28 + Lib/test/support/interpreters.py | 23 +- Lib/test/support/os_helper.py | 48 +- Lib/test/support/socket_helper.py | 77 +- Lib/test/support/testcase.py | 25 + Lib/test/support/testresult.py | 10 +- Lib/test/support/threading_helper.py | 27 +- Lib/test/support/warnings_helper.py | 2 +- Lib/test/test___all__.py | 7 +- Lib/test/test__opcode.py | 29 +- Lib/test/test__xxinterpchannels.py | 1558 + Lib/test/test__xxsubinterpreters.py | 1588 +- Lib/test/test_abc.py | 17 +- Lib/test/test_argparse.py | 138 +- Lib/test/test_ast.py | 897 +- Lib/test/test_asyncgen.py | 42 +- Lib/test/test_asynchat.py | 293 - Lib/test/test_asyncio/test_base_events.py | 49 +- .../test_asyncio/test_eager_task_factory.py | 361 + Lib/test/test_asyncio/test_events.py | 77 +- Lib/test/test_asyncio/test_futures.py | 21 +- Lib/test/test_asyncio/test_futures2.py | 48 +- Lib/test/test_asyncio/test_locks.py | 4 +- Lib/test/test_asyncio/test_pep492.py | 6 + Lib/test/test_asyncio/test_proactor_events.py | 18 +- Lib/test/test_asyncio/test_runners.py | 20 +- Lib/test/test_asyncio/test_selector_events.py | 183 +- Lib/test/test_asyncio/test_server.py | 27 + Lib/test/test_asyncio/test_sock_lowlevel.py | 6 +- Lib/test/test_asyncio/test_ssl.py | 1 - Lib/test/test_asyncio/test_sslproto.py | 3 + Lib/test/test_asyncio/test_streams.py | 18 +- Lib/test/test_asyncio/test_subprocess.py | 202 +- Lib/test/test_asyncio/test_tasks.py | 93 +- Lib/test/test_asyncio/test_timeouts.py | 31 +- Lib/test/test_asyncio/test_unix_events.py | 202 +- Lib/test/test_asyncio/test_waitfor.py | 129 +- Lib/test/test_asyncio/utils.py | 29 +- Lib/test/test_asyncore.py | 840 - Lib/test/test_atexit.py | 1 - Lib/test/test_audit.py | 55 + Lib/test/test_base64.py | 12 +- Lib/test/test_bdb.py | 10 +- Lib/test/test_bigmem.py | 9 + Lib/test/test_binascii.py | 2 +- Lib/test/test_bisect.py | 28 + Lib/test/test_bool.py | 44 +- Lib/test/test_buffer.py | 353 +- Lib/test/test_bufio.py | 1 - Lib/test/test_builtin.py | 94 +- Lib/test/test_bytes.py | 111 +- Lib/test/test_bz2.py | 8 +- Lib/test/test_calendar.py | 17 +- Lib/test/test_call.py | 241 +- Lib/test/test_capi/check_config.py | 77 + Lib/test/test_capi/test_abstract.py | 694 + Lib/test/test_capi/test_codecs.py | 520 + Lib/test/test_capi/test_dict.py | 378 + Lib/test/test_capi/test_exceptions.py | 367 + Lib/test/test_capi/test_getargs.py | 31 +- Lib/test/test_capi/test_immortal.py | 16 + Lib/test/test_capi/test_long.py | 39 + Lib/test/test_capi/test_mem.py | 169 + Lib/test/test_capi/test_misc.py | 1844 +- Lib/test/test_capi/test_structmembers.py | 91 +- Lib/test/test_capi/test_unicode.py | 1196 +- Lib/test/test_capi/test_watchers.py | 559 + Lib/test/test_check_c_globals.py | 29 - Lib/test/test_class.py | 14 + Lib/test/test_clinic.py | 1830 +- Lib/test/test_cmath.py | 51 +- Lib/test/test_cmd_line.py | 16 +- Lib/test/test_cmd_line_script.py | 33 +- Lib/test/test_code.py | 60 +- Lib/test/test_codecs.py | 110 +- Lib/test/test_codeop.py | 59 +- Lib/test/test_collections.py | 42 +- Lib/test/test_colorsys.py | 10 + Lib/test/test_compare.py | 426 +- Lib/test/test_compile.py | 620 +- Lib/test/test_compileall.py | 12 +- Lib/test/test_compiler_assemble.py | 74 + Lib/test/test_compiler_codegen.py | 54 + Lib/test/test_complex.py | 7 + Lib/test/test_concurrent_futures.py | 1626 - Lib/test/test_concurrent_futures/__init__.py | 16 + Lib/test/test_concurrent_futures/executor.py | 108 + .../test_as_completed.py | 115 + .../test_concurrent_futures/test_deadlock.py | 253 + .../test_concurrent_futures/test_future.py | 291 + Lib/test/test_concurrent_futures/test_init.py | 117 + .../test_process_pool.py | 202 + .../test_concurrent_futures/test_shutdown.py | 343 + .../test_thread_pool.py | 100 + Lib/test/test_concurrent_futures/test_wait.py | 164 + Lib/test/test_concurrent_futures/util.py | 141 + Lib/test/test_configparser.py | 46 +- Lib/test/test_context.py | 2 + Lib/test/test_contextlib.py | 27 +- Lib/test/test_copy.py | 12 +- Lib/test/test_copyreg.py | 10 +- Lib/test/test_coroutines.py | 15 +- .../__init__.py} | 62 +- .../extension.cpp} | 4 +- .../setup.py} | 27 +- Lib/test/test_cprofile.py | 41 +- Lib/test/test_csv.py | 51 +- Lib/test/test_ctypes.py | 10 - .../test => test/test_ctypes}/__init__.py | 0 Lib/test/test_ctypes/__main__.py | 4 + .../test => test/test_ctypes}/test_anon.py | 0 .../test_ctypes}/test_array_in_pointer.py | 0 .../test => test/test_ctypes}/test_arrays.py | 2 +- .../test_ctypes}/test_as_parameter.py | 8 +- .../test_ctypes}/test_bitfields.py | 2 +- .../test => test/test_ctypes}/test_buffers.py | 2 +- .../test => test/test_ctypes}/test_bytes.py | 0 .../test_ctypes}/test_byteswap.py | 8 - .../test_ctypes}/test_callbacks.py | 24 +- .../test => test/test_ctypes}/test_cast.py | 2 +- .../test => test/test_ctypes}/test_cfuncs.py | 2 +- .../test_ctypes}/test_checkretval.py | 2 +- .../test => test/test_ctypes}/test_delattr.py | 0 .../test => test/test_ctypes}/test_errno.py | 0 .../test => test/test_ctypes}/test_find.py | 0 .../test_ctypes}/test_frombuffer.py | 0 .../test => test/test_ctypes}/test_funcptr.py | 0 .../test_ctypes}/test_functions.py | 33 +- .../test_ctypes}/test_incomplete.py | 0 .../test => test/test_ctypes}/test_init.py | 0 .../test_ctypes}/test_internals.py | 0 .../test_ctypes}/test_keeprefs.py | 31 - .../test => test/test_ctypes}/test_libc.py | 0 .../test => test/test_ctypes}/test_loading.py | 26 +- .../test_ctypes}/test_macholib.py | 0 .../test_ctypes}/test_memfunctions.py | 2 +- .../test => test/test_ctypes}/test_numbers.py | 85 +- .../test => test/test_ctypes}/test_objects.py | 8 +- .../test_ctypes}/test_parameters.py | 32 +- .../test => test/test_ctypes}/test_pep3118.py | 51 +- .../test_ctypes}/test_pickling.py | 0 .../test_ctypes}/test_pointers.py | 0 .../test_ctypes}/test_prototypes.py | 2 +- .../test_ctypes}/test_python_api.py | 3 +- .../test_ctypes}/test_random_things.py | 0 .../test_ctypes}/test_refcounts.py | 0 .../test => test/test_ctypes}/test_repr.py | 0 .../test_ctypes}/test_returnfuncptrs.py | 0 .../test_ctypes}/test_simplesubclasses.py | 0 .../test => test/test_ctypes}/test_sizes.py | 3 + .../test => test/test_ctypes}/test_slicing.py | 2 +- .../test_ctypes}/test_stringptr.py | 0 .../test => test/test_ctypes}/test_strings.py | 2 +- .../test_ctypes}/test_struct_fields.py | 0 .../test_ctypes}/test_structures.py | 11 +- .../test_ctypes}/test_unaligned_structures.py | 0 .../test => test/test_ctypes}/test_unicode.py | 2 +- .../test => test/test_ctypes}/test_values.py | 0 .../test_ctypes}/test_varsize_struct.py | 0 .../test => test/test_ctypes}/test_win32.py | 0 .../test_ctypes}/test_wintypes.py | 19 + Lib/test/test_curses.py | 78 + Lib/test/test_dataclasses.py | 275 +- Lib/test/test_datetime.py | 12 +- Lib/test/test_dbm_gnu.py | 14 + Lib/test/test_dbm_ndbm.py | 14 + Lib/test/test_decimal.py | 313 +- Lib/test/test_decorators.py | 1 - Lib/test/test_defaultdict.py | 2 - Lib/test/test_descr.py | 51 +- Lib/test/test_descrtut.py | 2 +- Lib/test/test_dict.py | 19 +- Lib/test/test_dictviews.py | 21 +- Lib/test/test_dis.py | 823 +- Lib/test/test_distutils.py | 30 - Lib/test/test_doctest.py | 16 +- Lib/test/test_dtrace.py | 82 + Lib/test/test_dynamic.py | 10 +- Lib/test/test_eintr.py | 1 + Lib/test/test_email/data/msg_47.txt | 14 + Lib/test/test_email/test_email.py | 32 +- Lib/test/test_email/test_message.py | 6 +- Lib/test/test_email/test_utils.py | 13 +- Lib/test/test_embed.py | 93 +- Lib/test/test_ensurepip.py | 35 +- Lib/test/test_enum.py | 882 +- Lib/test/test_eof.py | 4 +- Lib/test/test_epoll.py | 15 +- Lib/test/test_except_star.py | 110 +- Lib/test/test_exception_group.py | 31 +- Lib/test/test_exceptions.py | 727 +- Lib/test/test_extcall.py | 23 +- Lib/test/test_faulthandler.py | 3 +- Lib/test/test_fcntl.py | 78 +- Lib/test/test_file.py | 2 +- Lib/test/test_fileinput.py | 39 +- Lib/test/test_fileio.py | 15 +- Lib/test/test_float.py | 6 +- Lib/test/test_flufl.py | 1 - Lib/test/test_format.py | 2 + Lib/test/test_fractions.py | 394 +- Lib/test/test_frame.py | 73 +- Lib/test/test_fstring.py | 497 +- Lib/test/test_ftplib.py | 12 +- Lib/test/test_funcattrs.py | 18 + Lib/test/test_functools.py | 137 +- Lib/test/test_future.py | 11 +- Lib/test/test_gc.py | 56 +- Lib/test/test_gdb.py | 24 +- Lib/test/test_generators.py | 99 +- Lib/test/test_genericalias.py | 24 +- Lib/test/test_genericpath.py | 4 + Lib/test/test_getopt.py | 73 +- Lib/test/test_getpath.py | 1 - Lib/test/test_gettext.py | 8 + Lib/test/test_grammar.py | 46 +- Lib/test/test_gzip.py | 61 + Lib/test/test_hashlib.py | 56 +- Lib/test/test_heapq.py | 1 - Lib/test/test_hmac.py | 10 + Lib/test/test_htmlparser.py | 14 + Lib/test/test_http_cookiejar.py | 1 - Lib/test/test_httplib.py | 288 +- Lib/test/test_httpservers.py | 36 +- Lib/test/test_idle.py | 8 +- Lib/test/test_imaplib.py | 31 +- Lib/test/test_imp.py | 494 - Lib/test/test_import/__init__.py | 1301 +- Lib/test/test_importlib/_context.py | 13 + Lib/test/test_importlib/_path.py | 109 + .../test_importlib/builtin/test_finder.py | 50 - .../extension/test_case_sensitivity.py | 2 +- .../test_importlib/extension/test_loader.py | 145 +- .../extension/test_path_hook.py | 2 +- Lib/test/test_importlib/fixtures.py | 158 +- Lib/test/test_importlib/frozen/test_finder.py | 40 - Lib/test/test_importlib/frozen/test_loader.py | 99 +- .../test_importlib/import_/test___loader__.py | 43 - .../import_/test___package__.py | 40 +- Lib/test/test_importlib/import_/test_api.py | 5 - .../test_importlib/import_/test_caching.py | 25 +- .../test_importlib/import_/test_helpers.py | 184 + .../test_importlib/import_/test_meta_path.py | 10 - Lib/test/test_importlib/import_/test_path.py | 73 +- Lib/test/test_importlib/resources/_path.py | 56 + .../resources/data01}/__init__.py | 0 .../{ => resources}/data01/binary.file | Bin .../data01/subdirectory}/__init__.py | 0 .../data01/subdirectory/binary.file | Bin .../{ => resources}/data01/utf-16.file | Bin .../{ => resources}/data01/utf-8.file | 0 .../data02}/__init__.py | 0 .../data02/one}/__init__.py | 0 .../{ => resources}/data02/one/resource1.txt | 0 .../subdirectory/subsubdir/resource.txt | 1 + .../one => resources/data02/two}/__init__.py | 0 .../{ => resources}/data02/two/resource2.txt | 0 .../two => resources/data03}/__init__.py | 0 .../data03/namespace/portion1}/__init__.py | 0 .../data03/namespace/portion2}/__init__.py | 0 .../data03/namespace/resource1.txt | 0 .../namespacedata01/binary.file | Bin .../namespacedata01/utf-16.file | Bin .../namespacedata01/utf-8.file | 0 .../test_compatibilty_files.py | 8 +- .../{ => resources}/test_contents.py | 2 +- .../test_importlib/resources/test_custom.py | 46 + .../test_importlib/resources/test_files.py | 113 + .../{ => resources}/test_open.py | 16 +- .../{ => resources}/test_path.py | 17 +- .../{ => resources}/test_read.py | 14 +- .../{ => resources}/test_reader.py | 16 + .../{ => resources}/test_resource.py | 110 +- .../{ => resources}/update-zips.py | 0 Lib/test/test_importlib/resources/util.py | 51 +- .../zipdata01}/__init__.py | 0 .../{ => resources}/zipdata01/ziptestdata.zip | Bin .../zipdata02}/__init__.py | 0 .../{ => resources}/zipdata02/ziptestdata.zip | Bin .../source/test_case_sensitivity.py | 13 - .../test_importlib/source/test_file_loader.py | 1 - Lib/test/test_importlib/source/test_finder.py | 29 +- .../test_importlib/source/test_path_hook.py | 9 - Lib/test/test_importlib/test_abc.py | 118 +- Lib/test/test_importlib/test_api.py | 71 +- Lib/test/test_importlib/test_files.py | 46 - Lib/test/test_importlib/test_locks.py | 5 + Lib/test/test_importlib/test_main.py | 119 +- Lib/test/test_importlib/test_metadata_api.py | 112 +- .../test_importlib/test_namespace_pkgs.py | 7 +- Lib/test/test_importlib/test_spec.py | 143 - .../test_importlib/test_threaded_import.py | 11 +- Lib/test/test_importlib/test_util.py | 364 +- Lib/test/test_importlib/test_windows.py | 18 +- Lib/test/test_importlib/util.py | 34 +- Lib/test/test_inspect.py | 446 +- Lib/test/test_int.py | 126 + Lib/test/test_interpreters.py | 30 +- Lib/test/test_io.py | 156 +- Lib/test/test_isinstance.py | 13 +- Lib/test/test_iter.py | 106 + Lib/test/test_itertools.py | 177 +- Lib/test/test_json/test_default.py | 11 + Lib/test/test_json/test_float.py | 3 +- Lib/test/test_keyword.py | 19 + Lib/test/test_largefile.py | 4 +- Lib/test/test_launcher.py | 21 +- Lib/test/test_lib2to3.py | 9 - .../tests => test/test_lib2to3}/__init__.py | 0 .../tests => test/test_lib2to3}/__main__.py | 0 .../tests => test/test_lib2to3}/data/README | 0 .../tests => test/test_lib2to3}/data/bom.py | 0 .../tests => test/test_lib2to3}/data/crlf.py | 0 .../test_lib2to3}/data/different_encoding.py | 0 .../test_lib2to3}/data/false_encoding.py | 0 .../test_lib2to3}/data/fixers/bad_order.py | 0 .../data/fixers/myfixes}/__init__.py | 0 .../data/fixers/myfixes/fix_explicit.py | 0 .../data/fixers/myfixes/fix_first.py | 0 .../data/fixers/myfixes/fix_last.py | 0 .../data/fixers/myfixes/fix_parrot.py | 0 .../data/fixers/myfixes/fix_preorder.py | 0 .../test_lib2to3}/data/fixers/no_fixer_cls.py | 0 .../data/fixers/parrot_example.py | 0 .../test_lib2to3}/data/infinite_recursion.py | 0 .../test_lib2to3}/data/py2_test_grammar.py | 2 +- .../test_lib2to3}/data/py3_test_grammar.py | 2 +- .../test_lib2to3}/pytree_idempotency.py | 6 +- .../tests => test/test_lib2to3}/support.py | 21 +- .../test_lib2to3}/test_all_fixers.py | 1 - .../test_lib2to3}/test_fixers.py | 12 +- .../tests => test/test_lib2to3}/test_main.py | 0 .../test_lib2to3}/test_parser.py | 2 +- .../test_lib2to3}/test_pytree.py | 0 .../test_lib2to3}/test_refactor.py | 0 .../tests => test/test_lib2to3}/test_util.py | 0 Lib/test/test_list.py | 2 +- Lib/test/test_listcomps.py | 578 +- Lib/test/test_lltrace.py | 15 +- Lib/test/test_locale.py | 118 +- Lib/test/test_logging.py | 527 +- Lib/test/test_long.py | 44 + Lib/test/test_lzma.py | 28 +- Lib/test/test_mailbox.py | 52 +- Lib/test/test_mailcap.py | 29 +- Lib/test/test_marshal.py | 5 +- Lib/test/test_math.py | 279 +- Lib/test/test_math_property.py | 41 + Lib/test/test_memoryview.py | 9 + Lib/test/test_minidom.py | 25 +- Lib/test/test_mmap.py | 121 +- .../__init__.py} | 48 +- Lib/test/{ => test_module}/bad_getattr.py | 0 Lib/test/{ => test_module}/bad_getattr2.py | 0 Lib/test/{ => test_module}/bad_getattr3.py | 0 Lib/test/{ => test_module}/good_getattr.py | 0 Lib/test/test_monitoring.py | 1745 + Lib/test/test_multibytecodec.py | 1 + .../__init__.py} | 11 +- .../test_multiprocessing_fork/test_manager.py | 7 + .../test_multiprocessing_fork/test_misc.py | 7 + .../test_processes.py | 7 + .../test_multiprocessing_fork/test_threads.py | 7 + .../__init__.py} | 11 +- .../test_manager.py | 7 + .../test_misc.py | 7 + .../test_processes.py | 7 + .../test_threads.py | 7 + .../test_multiprocessing_main_handling.py | 27 +- Lib/test/test_multiprocessing_spawn.py | 12 - .../test_multiprocessing_spawn/__init__.py | 9 + .../test_manager.py | 7 + .../test_multiprocessing_spawn/test_misc.py | 7 + .../test_processes.py | 7 + .../test_threads.py | 7 + Lib/test/test_named_expressions.py | 80 +- Lib/test/test_netrc.py | 6 +- Lib/test/test_nis.py | 1 - Lib/test/test_ntpath.py | 237 +- Lib/test/test_numeric_tower.py | 2 +- Lib/test/test_opcache.py | 52 + Lib/test/test_operator.py | 3 + Lib/test/test_ordered_dict.py | 15 +- Lib/test/test_os.py | 371 +- Lib/test/test_pathlib.py | 921 +- Lib/test/test_patma.py | 27 + Lib/test/test_pdb.py | 372 + Lib/test/test_peepholer.py | 456 +- Lib/test/test_peg_generator/test_c_parser.py | 27 +- Lib/test/test_peg_generator/test_pegen.py | 2 +- Lib/test/test_pep646_syntax.py | 13 +- Lib/test/test_perf_profiler.py | 354 + Lib/test/test_perfmaps.py | 19 + Lib/test/test_pickle.py | 30 + Lib/test/test_pkgutil.py | 57 +- Lib/test/test_platform.py | 67 +- Lib/test/test_plistlib.py | 2 +- Lib/test/test_poll.py | 3 +- Lib/test/test_poplib.py | 14 +- Lib/test/test_positional_only_arg.py | 26 +- Lib/test/test_posix.py | 65 +- Lib/test/test_posixpath.py | 32 + Lib/test/test_pow.py | 11 +- Lib/test/test_pprint.py | 2 +- Lib/test/test_profile.py | 2 +- Lib/test/test_property.py | 154 +- Lib/test/test_pty.py | 114 +- Lib/test/test_py_compile.py | 5 +- Lib/test/test_pydoc.py | 118 +- Lib/test/test_pyexpat.py | 74 +- Lib/test/test_random.py | 137 +- Lib/test/test_range.py | 39 +- Lib/test/test_re.py | 229 +- Lib/test/test_regrtest.py | 662 +- Lib/test/test_reprlib.py | 356 + Lib/test/test_runpy.py | 3 +- Lib/test/test_select.py | 1 - Lib/test/test_selectors.py | 1 + Lib/test/test_set.py | 2 +- Lib/test/test_shelve.py | 2 - Lib/test/test_shlex.py | 6 +- Lib/test/test_shutil.py | 409 +- Lib/test/test_signal.py | 41 +- Lib/test/test_site.py | 11 +- Lib/test/test_slice.py | 12 +- Lib/test/test_smtpd.py | 1019 - Lib/test/test_smtplib.py | 6 +- Lib/test/test_smtpnet.py | 1 + Lib/test/test_socket.py | 207 +- Lib/test/test_socketserver.py | 18 +- Lib/test/test_source_encoding.py | 22 +- Lib/test/test_sqlite3/__init__.py | 5 +- Lib/test/test_sqlite3/test_cli.py | 155 + Lib/test/test_sqlite3/test_dbapi.py | 79 +- Lib/test/test_sqlite3/test_dump.py | 20 + Lib/test/test_sqlite3/test_factory.py | 37 +- Lib/test/test_sqlite3/test_regression.py | 24 +- Lib/test/test_sqlite3/test_transactions.py | 191 +- Lib/test/test_sqlite3/test_types.py | 33 +- Lib/test/test_sqlite3/test_userfunctions.py | 11 +- Lib/test/test_ssl.py | 612 +- Lib/test/test_stable_abi_ctypes.py | 15 +- Lib/test/test_statistics.py | 37 +- Lib/test/test_strftime.py | 12 +- Lib/test/test_string_literals.py | 24 +- Lib/test/test_strptime.py | 10 + Lib/test/test_struct.py | 77 +- Lib/test/test_subclassinit.py | 22 +- Lib/test/test_subprocess.py | 38 +- Lib/test/test_sundry.py | 23 - Lib/test/test_super.py | 145 +- Lib/test/test_support.py | 92 +- Lib/test/test_symtable.py | 36 +- Lib/test/test_syntax.py | 156 +- Lib/test/test_sys.py | 257 +- Lib/test/test_sys_setprofile.py | 22 +- Lib/test/test_sys_settrace.py | 319 +- Lib/test/test_sysconfig.py | 1 - Lib/test/test_syslog.py | 64 + Lib/test/test_tabnanny.py | 44 +- Lib/test/test_tarfile.py | 1222 +- Lib/test/test_tcl.py | 21 +- Lib/test/test_tempfile.py | 135 +- Lib/test/test_thread.py | 31 +- Lib/test/test_threading.py | 316 +- Lib/test/test_threading_local.py | 1 - Lib/test/test_time.py | 2 +- Lib/test/test_timeout.py | 30 +- Lib/test/test_tix.py | 2 +- Lib/test/test_tk.py | 20 - .../test => test/test_tkinter}/README | 0 Lib/test/test_tkinter/__init__.py | 23 + Lib/test/test_tkinter/__main__.py | 4 + .../test => test/test_tkinter}/support.py | 19 +- .../test/test_tkinter/test_colorchooser.py | 2 +- .../test/test_tkinter/test_font.py | 2 +- .../test_tkinter/test_geometry_managers.py | 14 +- .../test/test_tkinter/test_images.py | 22 +- .../test/test_tkinter/test_loadtk.py | 0 .../test/test_tkinter/test_messagebox.py | 2 +- .../test/test_tkinter/test_misc.py | 2 +- .../test/test_tkinter/test_simpledialog.py | 2 +- .../test/test_tkinter/test_text.py | 2 +- .../test/test_tkinter/test_variables.py | 2 +- .../test/test_tkinter/test_widgets.py | 39 +- .../test_tkinter}/widget_tests.py | 7 +- Lib/test/test_tokenize.py | 526 +- Lib/test/test_tomllib/test_misc.py | 27 +- Lib/test/test_tools/test_fixcid.py | 94 - Lib/test/test_tools/test_freeze.py | 1 + Lib/test/test_tools/test_gprof2html.py | 35 - Lib/test/test_tools/test_lll.py | 41 - Lib/test/test_tools/test_md5sum.py | 79 - Lib/test/test_tools/test_pathfix.py | 132 - Lib/test/test_tools/test_pdeps.py | 32 - Lib/test/test_tools/test_pindent.py | 340 - Lib/test/test_tools/test_reindent.py | 4 +- Lib/test/test_tools/test_sundry.py | 32 +- Lib/test/test_trace.py | 18 +- Lib/test/test_traceback.py | 1116 +- .../__init__.py} | 15 +- Lib/test/test_ttk/__main__.py | 4 + .../test/test_ttk/test_extensions.py | 6 +- Lib/{tkinter => }/test/test_ttk/test_style.py | 4 +- .../test/test_ttk/test_widgets.py | 14 +- Lib/test/test_turtle.py | 40 + Lib/test/test_type_aliases.py | 330 + Lib/test/test_type_annotations.py | 111 + Lib/test/test_type_cache.py | 16 +- Lib/test/test_type_comments.py | 3 +- Lib/test/test_type_params.py | 1104 + Lib/test/test_types.py | 167 +- Lib/test/test_typing.py | 1791 +- Lib/test/test_unary.py | 9 +- Lib/test/test_unicode.py | 216 +- Lib/test/test_unicodedata.py | 28 +- Lib/test/test_unittest.py | 16 - Lib/test/test_unittest/__init__.py | 6 + Lib/test/test_unittest/__main__.py | 4 + .../test_unittest}/_test_warnings.py | 11 - .../test => test/test_unittest}/dummy.py | 0 .../test => test/test_unittest}/support.py | 16 + .../test_unittest}/test_assertions.py | 15 +- .../test_unittest}/test_async_case.py | 0 .../test => test/test_unittest}/test_break.py | 7 +- .../test => test/test_unittest}/test_case.py | 134 +- .../test_unittest}/test_discovery.py | 11 +- .../test_unittest}/test_functiontestcase.py | 2 +- .../test_unittest}/test_loader.py | 154 +- .../test_unittest}/test_program.py | 100 +- .../test_unittest}/test_result.py | 25 +- .../test_unittest}/test_runner.py | 204 +- .../test_unittest}/test_setups.py | 0 .../test_unittest}/test_skipping.py | 2 +- .../test => test/test_unittest}/test_suite.py | 2 +- Lib/test/test_unittest/testmock/__init__.py | 6 + .../test_unittest}/testmock/__main__.py | 2 +- .../test_unittest}/testmock/support.py | 0 .../test_unittest}/testmock/testasync.py | 22 +- .../test_unittest}/testmock/testcallable.py | 2 +- .../test_unittest}/testmock/testhelpers.py | 41 +- .../testmock/testmagicmethods.py | 0 .../test_unittest}/testmock/testmock.py | 30 +- .../test_unittest}/testmock/testpatch.py | 54 +- .../test_unittest}/testmock/testsealable.py | 14 +- .../test_unittest}/testmock/testsentinel.py | 0 .../test_unittest}/testmock/testwith.py | 2 +- Lib/test/test_univnewlines.py | 1 - Lib/test/test_unparse.py | 155 +- Lib/test/test_urllib.py | 2 + Lib/test/test_urllib2.py | 85 +- Lib/test/test_urllib2net.py | 7 + Lib/test/test_urllibnet.py | 2 + Lib/test/test_urlparse.py | 124 +- Lib/test/test_uu.py | 28 + Lib/test/test_uuid.py | 95 +- Lib/test/test_venv.py | 35 +- Lib/test/test_wait3.py | 5 +- Lib/test/test_wait4.py | 5 +- Lib/test/test_warnings/__init__.py | 53 +- Lib/test/test_warnings/data/package_helper.py | 10 + Lib/test/test_warnings/data/stacklevel.py | 8 +- Lib/test/test_wave.py | 30 +- Lib/test/test_weakref.py | 13 + Lib/test/test_webbrowser.py | 36 +- Lib/test/test_winreg.py | 16 +- Lib/test/test_winsound.py | 22 + Lib/test/test_with.py | 6 +- Lib/test/test_wmi.py | 74 + Lib/test/test_xml_etree.py | 140 +- Lib/test/test_xml_etree_c.py | 51 +- Lib/test/test_xmlrpc.py | 9 + Lib/test/test_yield_from.py | 527 + Lib/test/test_zipapp.py | 16 + Lib/test/test_zipfile/__init__.py | 5 + Lib/test/test_zipfile/__main__.py | 7 + .../test_zipfile/_path}/__init__.py | 0 Lib/test/test_zipfile/_path/_functools.py | 9 + Lib/test/test_zipfile/_path/_itertools.py | 79 + Lib/test/test_zipfile/_path/_support.py | 9 + Lib/test/test_zipfile/_path/_test_params.py | 39 + .../test_zipfile/_path/test_complexity.py | 103 + Lib/test/test_zipfile/_path/test_path.py | 579 + Lib/test/test_zipfile/_path/write-alpharep.py | 4 + .../test_core.py} | 739 +- Lib/test/test_zipfile64.py | 13 +- Lib/test/test_zipimport.py | 17 - Lib/test/test_zlib.py | 179 +- Lib/test/test_zoneinfo/__init__.py | 1 + Lib/test/test_zoneinfo/test_zoneinfo.py | 26 +- .../test_zoneinfo/test_zoneinfo_property.py | 368 + Lib/test/wheel-0.40.0-py3-none-any.whl | Bin 0 -> 64545 bytes Lib/threading.py | 57 +- Lib/timeit.py | 23 +- Lib/tkinter/__init__.py | 10 +- Lib/tkinter/commondialog.py | 2 +- Lib/tkinter/filedialog.py | 5 +- Lib/tkinter/test/test_ttk/__init__.py | 0 Lib/token.py | 29 +- Lib/tokenize.py | 235 +- Lib/trace.py | 3 +- Lib/traceback.py | 209 +- Lib/tty.py | 70 +- Lib/turtle.py | 164 +- Lib/turtledemo/__main__.py | 24 +- Lib/types.py | 32 +- Lib/typing.py | 1516 +- Lib/unittest/__init__.py | 13 - Lib/unittest/case.py | 93 +- Lib/unittest/loader.py | 37 +- Lib/unittest/main.py | 21 +- Lib/unittest/mock.py | 69 +- Lib/unittest/result.py | 12 + Lib/unittest/runner.py | 53 +- Lib/unittest/test/__init__.py | 25 - Lib/unittest/test/__main__.py | 18 - Lib/unittest/test/testmock/__init__.py | 17 - Lib/urllib/error.py | 2 +- Lib/urllib/parse.py | 81 +- Lib/urllib/request.py | 72 +- Lib/uu.py | 9 +- Lib/uuid.py | 67 +- Lib/venv/__init__.py | 152 +- Lib/venv/scripts/common/Activate.ps1 | 494 +- Lib/venv/scripts/common/activate | 13 +- Lib/venv/scripts/nt/activate.bat | 68 +- Lib/venv/scripts/nt/deactivate.bat | 44 +- Lib/venv/scripts/posix/activate.csh | 1 + Lib/venv/scripts/posix/activate.fish | 2 +- Lib/warnings.py | 29 +- Lib/wave.py | 37 +- Lib/webbrowser.py | 128 +- Lib/wsgiref/handlers.py | 17 +- Lib/wsgiref/validate.py | 5 +- Lib/xdrlib.py | 4 +- Lib/xml/dom/expatbuilder.py | 5 +- Lib/xml/etree/ElementTree.py | 23 +- Lib/xml/sax/__init__.py | 21 +- Lib/xml/sax/_exceptions.py | 4 - Lib/xml/sax/expatreader.py | 6 - Lib/xml/sax/xmlreader.py | 4 +- Lib/xmlrpc/client.py | 9 +- Lib/xmlrpc/server.py | 4 +- Lib/zipapp.py | 2 +- Lib/{zipfile.py => zipfile/__init__.py} | 520 +- Lib/zipfile/__main__.py | 77 + Lib/zipfile/_path/__init__.py | 395 + Lib/zipfile/_path/glob.py | 40 + Lib/zipimport.py | 58 - Lib/zoneinfo/_zoneinfo.py | 2 +- Mac/BuildScript/build-installer.py | 27 +- Mac/BuildScript/resources/ReadMe.rtf | 6 +- Mac/BuildScript/resources/Welcome.rtf | 4 +- Mac/BuildScript/scripts/postflight.ensurepip | 8 +- Mac/BuildScript/scripts/postflight.framework | 4 +- Mac/Makefile.in | 1 - Mac/Tools/pythonw.c | 1 - Makefile.pre.in | 723 +- Misc/ACKS | 48 +- Misc/HISTORY | 12 +- Misc/NEWS | 36474 ----------- Misc/NEWS.d/3.10.0a1.rst | 3509 ++ Misc/NEWS.d/3.10.0a2.rst | 912 + Misc/NEWS.d/3.10.0a3.rst | 1504 + Misc/NEWS.d/3.10.0a4.rst | 995 + Misc/NEWS.d/3.10.0a5.rst | 670 + Misc/NEWS.d/3.10.0a6.rst | 538 + Misc/NEWS.d/3.10.0a7.rst | 983 + Misc/NEWS.d/3.10.0b1.rst | 1808 + Misc/NEWS.d/3.11.0a1.rst | 5098 ++ Misc/NEWS.d/3.11.0a2.rst | 1334 + Misc/NEWS.d/3.11.0a3.rst | 1277 + Misc/NEWS.d/3.11.0a4.rst | 1177 + Misc/NEWS.d/3.11.0a5.rst | 986 + Misc/NEWS.d/3.11.0a6.rst | 1206 + Misc/NEWS.d/3.11.0a7.rst | 1614 + Misc/NEWS.d/3.11.0b1.rst | 2146 + Misc/NEWS.d/3.12.0.rst | 74 + Misc/NEWS.d/3.12.0a1.rst | 6193 ++ Misc/NEWS.d/3.12.0a2.rst | 1102 + Misc/NEWS.d/3.12.0a3.rst | 836 + Misc/NEWS.d/3.12.0a4.rst | 1132 + Misc/NEWS.d/3.12.0a5.rst | 664 + Misc/NEWS.d/3.12.0a6.rst | 821 + Misc/NEWS.d/3.12.0a7.rst | 745 + Misc/NEWS.d/3.12.0b1.rst | 2402 + Misc/NEWS.d/3.12.0b2.rst | 530 + Misc/NEWS.d/3.12.0b3.rst | 411 + Misc/NEWS.d/3.12.0b4.rst | 318 + Misc/NEWS.d/3.12.0rc1.rst | 495 + Misc/NEWS.d/3.12.0rc2.rst | 510 + Misc/NEWS.d/3.12.0rc3.rst | 319 + Misc/NEWS.d/3.5.0.rst | 8 + Misc/NEWS.d/3.5.0a1.rst | 5869 ++ Misc/NEWS.d/3.5.0a2.rst | 405 + Misc/NEWS.d/3.5.0a3.rst | 518 + Misc/NEWS.d/3.5.0a4.rst | 665 + Misc/NEWS.d/3.5.0b1.rst | 848 + Misc/NEWS.d/3.5.0b2.rst | 104 + Misc/NEWS.d/3.5.0b3.rst | 273 + Misc/NEWS.d/3.5.0b4.rst | 255 + Misc/NEWS.d/3.5.0rc1.rst | 241 + Misc/NEWS.d/3.5.0rc2.rst | 56 + Misc/NEWS.d/3.5.0rc3.rst | 76 + Misc/NEWS.d/3.5.0rc4.rst | 17 + Misc/NEWS.d/3.5.1.rst | 17 + Misc/NEWS.d/3.5.1rc1.rst | 1451 + Misc/NEWS.d/3.5.2.rst | 25 + Misc/NEWS.d/3.5.2rc1.rst | 2203 + Misc/NEWS.d/3.5.3.rst | 7 + Misc/NEWS.d/3.5.3rc1.rst | 2163 + Misc/NEWS.d/3.5.4.rst | 8 + Misc/NEWS.d/3.5.4rc1.rst | 1131 + Misc/NEWS.d/3.5.5.rst | 8 + Misc/NEWS.d/3.5.5rc1.rst | 72 + Misc/NEWS.d/3.6.0.rst | 7 + Misc/NEWS.d/3.6.0a1.rst | 3940 ++ Misc/NEWS.d/3.6.0a2.rst | 792 + Misc/NEWS.d/3.6.0a3.rst | 537 + Misc/NEWS.d/3.6.0a4.rst | 685 + Misc/NEWS.d/3.6.0b1.rst | 1608 + Misc/NEWS.d/3.6.0b2.rst | 838 + Misc/NEWS.d/3.6.0b3.rst | 355 + Misc/NEWS.d/3.6.0b4.rst | 327 + Misc/NEWS.d/3.6.0rc1.rst | 122 + Misc/NEWS.d/3.6.0rc2.rst | 45 + Misc/NEWS.d/3.6.1.rst | 31 + Misc/NEWS.d/3.6.1rc1.rst | 940 + Misc/NEWS.d/3.6.2.rst | 7 + Misc/NEWS.d/3.6.2rc1.rst | 941 + Misc/NEWS.d/3.6.2rc2.rst | 39 + Misc/NEWS.d/3.6.3.rst | 27 + Misc/NEWS.d/3.6.3rc1.rst | 1243 + Misc/NEWS.d/3.6.4.rst | 8 + Misc/NEWS.d/3.6.4rc1.rst | 1129 + Misc/NEWS.d/3.6.5.rst | 16 + Misc/NEWS.d/3.6.5rc1.rst | 866 + Misc/NEWS.d/3.6.6.rst | 8 + Misc/NEWS.d/3.6.6rc1.rst | 885 + Misc/NEWS.d/3.7.0.rst | 17 + Misc/NEWS.d/3.7.0a1.rst | 6432 ++ Misc/NEWS.d/3.7.0a2.rst | 683 + Misc/NEWS.d/3.7.0a3.rst | 1615 + Misc/NEWS.d/3.7.0a4.rst | 846 + Misc/NEWS.d/3.7.0b1.rst | 878 + Misc/NEWS.d/3.7.0b2.rst | 654 + Misc/NEWS.d/3.7.0b3.rst | 541 + Misc/NEWS.d/3.7.0b4.rst | 465 + Misc/NEWS.d/3.7.0b5.rst | 592 + Misc/NEWS.d/3.7.0rc1.rst | 275 + Misc/NEWS.d/3.8.0a1.rst | 8978 +++ Misc/NEWS.d/3.8.0a2.rst | 544 + Misc/NEWS.d/3.8.0a3.rst | 872 + Misc/NEWS.d/3.8.0a4.rst | 1411 + Misc/NEWS.d/3.8.0b1.rst | 2052 + Misc/NEWS.d/3.9.0a1.rst | 5772 ++ Misc/NEWS.d/3.9.0a2.rst | 957 + Misc/NEWS.d/3.9.0a3.rst | 905 + Misc/NEWS.d/3.9.0a4.rst | 949 + Misc/NEWS.d/3.9.0a5.rst | 1310 + Misc/NEWS.d/3.9.0a6.rst | 1211 + Misc/NEWS.d/3.9.0b1.rst | 961 + Misc/NEWS.d/next/Build/README.rst | 3 + Misc/NEWS.d/next/C API/README.rst | 3 + Misc/NEWS.d/next/Core and Builtins/README.rst | 3 + Misc/NEWS.d/next/Documentation/README.rst | 3 + Misc/NEWS.d/next/IDLE/README.rst | 3 + Misc/NEWS.d/next/Library/README.rst | 3 + Misc/NEWS.d/next/Security/README.rst | 3 + Misc/NEWS.d/next/Tests/README.rst | 3 + Misc/NEWS.d/next/Tools-Demos/README.rst | 3 + Misc/NEWS.d/next/Windows/README.rst | 3 + Misc/NEWS.d/next/macOS/README.rst | 3 + Misc/README | 1 - Misc/gdbinit | 176 - Misc/python.man | 7 +- Misc/python.pc.in | 2 +- Misc/stable_abi.toml | 94 +- Modules/Setup | 13 +- Modules/Setup.bootstrap.in | 1 + Modules/Setup.stdlib.in | 31 +- Modules/_abc.c | 32 +- Modules/_asynciomodule.c | 1640 +- Modules/_bisectmodule.c | 177 +- Modules/_blake2/blake2module.c | 3 +- Modules/_blake2/blake2module.h | 2 +- Modules/_blake2/clinic/blake2b_impl.c.h | 33 +- Modules/_blake2/clinic/blake2s_impl.c.h | 33 +- Modules/_blake2/impl/blake2-config.h | 2 +- Modules/_blake2/impl/blake2b-round.h | 4 +- Modules/_blake2/impl/blake2s-load-xop.h | 2 +- Modules/_blake2/impl/blake2s-round.h | 2 +- Modules/_bz2module.c | 213 +- Modules/_codecsmodule.c | 62 +- Modules/_collectionsmodule.c | 635 +- Modules/_contextvarsmodule.c | 1 + Modules/_cryptmodule.c | 1 + Modules/_csv.c | 38 +- Modules/_ctypes/_ctypes.c | 488 +- Modules/_ctypes/_ctypes_test.c | 14 + Modules/_ctypes/callbacks.c | 134 +- Modules/_ctypes/callproc.c | 187 +- Modules/_ctypes/cfield.c | 91 +- Modules/_ctypes/ctypes.h | 30 +- Modules/_ctypes/ctypes_dlfcn.h | 27 - Modules/_ctypes/darwin/LICENSE | 31 - Modules/_ctypes/darwin/README | 95 - Modules/_ctypes/darwin/README.ctypes | 11 - Modules/_ctypes/darwin/dlfcn.h | 84 - Modules/_ctypes/darwin/dlfcn_simple.c | 272 - Modules/_ctypes/libffi_osx/LICENSE | 20 - Modules/_ctypes/libffi_osx/README | 500 - Modules/_ctypes/libffi_osx/README.pyobjc | 5 - Modules/_ctypes/libffi_osx/ffi.c | 227 - Modules/_ctypes/libffi_osx/include/ffi.h | 355 - .../_ctypes/libffi_osx/include/ffi_common.h | 102 - .../_ctypes/libffi_osx/include/fficonfig.h | 150 - .../_ctypes/libffi_osx/include/ffitarget.h | 13 - .../libffi_osx/include/ppc-ffitarget.h | 104 - .../libffi_osx/include/x86-ffitarget.h | 88 - .../_ctypes/libffi_osx/powerpc/ppc-darwin.S | 365 - .../_ctypes/libffi_osx/powerpc/ppc-darwin.h | 85 - .../libffi_osx/powerpc/ppc-darwin_closure.S | 308 - .../libffi_osx/powerpc/ppc-ffi_darwin.c | 1776 - .../libffi_osx/powerpc/ppc64-darwin_closure.S | 418 - Modules/_ctypes/libffi_osx/types.c | 115 - Modules/_ctypes/libffi_osx/x86/darwin64.S | 417 - Modules/_ctypes/libffi_osx/x86/x86-darwin.S | 422 - Modules/_ctypes/libffi_osx/x86/x86-ffi64.c | 737 - .../_ctypes/libffi_osx/x86/x86-ffi_darwin.c | 438 - Modules/_ctypes/malloc_closure.c | 3 + Modules/_ctypes/stgdict.c | 166 +- Modules/_curses_panel.c | 31 +- Modules/_cursesmodule.c | 59 +- Modules/_datetimemodule.c | 338 +- Modules/_dbmmodule.c | 39 +- Modules/_decimal/_decimal.c | 220 +- Modules/_decimal/libmpdec/mpdecimal.c | 6 + Modules/_decimal/tests/formathelper.py | 4 +- Modules/_decimal/tests/runall.bat | 258 +- Modules/_elementtree.c | 1201 +- Modules/_functoolsmodule.c | 156 +- Modules/_gdbmmodule.c | 43 +- Modules/_hacl/Hacl_Hash_MD5.c | 1472 + Modules/_hacl/Hacl_Hash_MD5.h | 65 + Modules/_hacl/Hacl_Hash_SHA1.c | 508 + Modules/_hacl/Hacl_Hash_SHA1.h | 65 + Modules/_hacl/Hacl_Hash_SHA2.c | 1345 + Modules/_hacl/Hacl_Hash_SHA2.h | 204 + Modules/_hacl/Hacl_Hash_SHA3.c | 824 + Modules/_hacl/Hacl_Hash_SHA3.h | 130 + Modules/_hacl/Hacl_Streaming_Types.h | 83 + Modules/_hacl/README.md | 29 + .../include/krml/FStar_UInt128_Verified.h | 346 + .../include/krml/FStar_UInt_8_16_32_64.h | 107 + .../krml/fstar_uint128_struct_endianness.h | 68 + Modules/_hacl/include/krml/internal/target.h | 266 + .../_hacl/include/krml/lowstar_endianness.h | 231 + Modules/_hacl/include/krml/types.h | 14 + Modules/_hacl/internal/Hacl_Hash_MD5.h | 61 + Modules/_hacl/internal/Hacl_Hash_SHA1.h | 61 + Modules/_hacl/internal/Hacl_Hash_SHA2.h | 184 + Modules/_hacl/internal/Hacl_Hash_SHA3.h | 65 + Modules/_hacl/python_hacl_namespaces.h | 86 + Modules/_hacl/refresh.sh | 139 + Modules/_hashopenssl.c | 29 +- Modules/_heapqmodule.c | 16 +- Modules/_io/_iomodule.c | 309 +- Modules/_io/_iomodule.h | 117 +- Modules/_io/bufferedio.c | 855 +- Modules/_io/bytesio.c | 188 +- Modules/_io/clinic/_iomodule.c.h | 62 +- Modules/_io/clinic/bufferedio.c.h | 494 +- Modules/_io/clinic/bytesio.c.h | 45 +- Modules/_io/clinic/fileio.c.h | 169 +- Modules/_io/clinic/iobase.c.h | 145 +- Modules/_io/clinic/stringio.c.h | 33 +- Modules/_io/clinic/textio.c.h | 343 +- Modules/_io/clinic/winconsoleio.c.h | 183 +- Modules/_io/fileio.c | 216 +- Modules/_io/iobase.c | 299 +- Modules/_io/stringio.c | 143 +- Modules/_io/textio.c | 507 +- Modules/_io/winconsoleio.c | 178 +- Modules/_json.c | 410 +- Modules/_localemodule.c | 11 +- Modules/_lsprof.c | 279 +- Modules/_lzmamodule.c | 127 +- Modules/_math.h | 5 +- .../clinic/multiprocessing.c.h | 36 +- .../_multiprocessing/clinic/posixshmem.c.h | 58 +- Modules/_multiprocessing/clinic/semaphore.c.h | 95 +- Modules/_multiprocessing/multiprocessing.c | 62 +- Modules/_multiprocessing/multiprocessing.h | 6 +- Modules/_multiprocessing/posixshmem.c | 7 + Modules/_multiprocessing/semaphore.c | 92 +- Modules/_opcode.c | 15 +- Modules/_operator.c | 57 +- Modules/_pickle.c | 1535 +- Modules/_posixsubprocess.c | 411 +- Modules/_queuemodule.c | 4 +- Modules/_randommodule.c | 10 +- Modules/_scproxy.c | 8 +- Modules/_sha3/LICENSE | 22 - Modules/_sha3/README.txt | 8 - Modules/_sha3/sha3.c | 193 - Modules/_sha3/sha3.h | 49 - Modules/_sqlite/clinic/blob.c.h | 8 +- Modules/_sqlite/clinic/connection.c.h | 506 +- Modules/_sqlite/clinic/cursor.c.h | 38 +- Modules/_sqlite/clinic/module.c.h | 73 +- Modules/_sqlite/clinic/row.c.h | 12 +- Modules/_sqlite/connection.c | 477 +- Modules/_sqlite/connection.h | 7 + Modules/_sqlite/cursor.c | 86 +- Modules/_sqlite/microprotocols.c | 4 +- Modules/_sqlite/module.c | 92 +- Modules/_sqlite/module.h | 2 + Modules/_sqlite/statement.c | 1 - Modules/_sqlite/statement.h | 1 - Modules/_sre/clinic/sre.c.h | 372 +- Modules/_sre/sre.c | 382 +- Modules/_sre/sre.h | 11 + Modules/_sre/sre_constants.h | 4 +- Modules/_sre/sre_lib.h | 4 + Modules/_sre/sre_targets.h | 2 +- Modules/_ssl.c | 360 +- Modules/_ssl.h | 3 +- Modules/_ssl/clinic/cert.c.h | 33 +- Modules/_ssl/debughelpers.c | 31 +- Modules/_ssl_data_111.h | 17 +- Modules/_ssl_data_300.h | 152 +- Modules/_ssl_data_31.h | 8605 +++ Modules/_stat.c | 19 +- Modules/_statisticsmodule.c | 3 +- Modules/_struct.c | 370 +- Modules/_testbuffer.c | 18 +- Modules/_testcapi/README.txt | 10 + Modules/_testcapi/abstract.c | 518 + Modules/_testcapi/buffer.c | 102 + Modules/_testcapi/clinic/exceptions.c.h | 491 + Modules/_testcapi/clinic/float.c.h | 88 + Modules/_testcapi/clinic/vectorcall.c.h | 113 + Modules/_testcapi/clinic/watchers.c.h | 198 + Modules/_testcapi/code.c | 121 + Modules/_testcapi/datetime.c | 451 + Modules/_testcapi/dict.c | 308 + Modules/_testcapi/docstring.c | 107 + Modules/_testcapi/exceptions.c | 414 + Modules/_testcapi/float.c | 114 + Modules/_testcapi/gc.c | 344 + Modules/_testcapi/getargs.c | 939 + Modules/_testcapi/heaptype.c | 1259 + Modules/_testcapi/heaptype_relative.c | 343 + Modules/_testcapi/immortal.c | 47 + Modules/_testcapi/long.c | 570 + Modules/_testcapi/mem.c | 724 + Modules/_testcapi/parts.h | 54 + Modules/_testcapi/pyos.c | 60 + Modules/_testcapi/pytime.c | 274 + Modules/_testcapi/structmember.c | 217 + Modules/{ => _testcapi}/testcapi_long.h | 3 +- Modules/_testcapi/unicode.c | 2074 + Modules/_testcapi/util.h | 32 + Modules/_testcapi/vectorcall.c | 406 + Modules/_testcapi/vectorcall_limited.c | 179 + Modules/_testcapi/watchers.c | 715 + Modules/_testcapi_feature_macros.inc | 2 +- Modules/_testcapimodule.c | 8972 +-- Modules/_testclinic.c | 81 + Modules/_testinternalcapi.c | 643 +- Modules/_testmultiphase.c | 88 +- Modules/_testsinglephase.c | 483 + Modules/_threadmodule.c | 64 +- Modules/_tkinter.c | 225 +- Modules/_tracemalloc.c | 1629 +- Modules/_typingmodule.c | 35 +- Modules/_uuidmodule.c | 1 + Modules/_weakref.c | 1 + Modules/_winapi.c | 236 +- Modules/_xxinterpchannelsmodule.c | 2464 + Modules/_xxsubinterpretersmodule.c | 2297 +- Modules/_xxtestfuzz/fuzzer.c | 22 +- Modules/_zoneinfo.c | 699 +- Modules/arraymodule.c | 90 +- Modules/atexitmodule.c | 63 +- Modules/audioop.c | 31 +- Modules/binascii.c | 35 +- Modules/cjkcodecs/_codecs_cn.c | 4 +- Modules/cjkcodecs/_codecs_hk.c | 23 +- Modules/cjkcodecs/_codecs_iso2022.c | 298 +- Modules/cjkcodecs/_codecs_jp.c | 29 +- Modules/cjkcodecs/_codecs_kr.c | 8 +- Modules/cjkcodecs/_codecs_tw.c | 4 +- Modules/cjkcodecs/cjkcodecs.h | 243 +- Modules/cjkcodecs/clinic/multibytecodec.c.h | 142 +- Modules/cjkcodecs/emu_jisx0213_2000.h | 22 +- Modules/cjkcodecs/mappings_hk.h | 1 + Modules/cjkcodecs/mappings_tw.h | 2 + Modules/cjkcodecs/multibytecodec.c | 137 +- Modules/cjkcodecs/multibytecodec.h | 33 +- Modules/clinic/_abc.c.h | 8 +- Modules/clinic/_asynciomodule.c.h | 769 +- Modules/clinic/_bisectmodule.c.h | 124 +- Modules/clinic/_bz2module.c.h | 106 +- Modules/clinic/_codecsmodule.c.h | 118 +- Modules/clinic/_collectionsmodule.c.h | 12 +- Modules/clinic/_contextvarsmodule.c.h | 8 +- Modules/clinic/_cryptmodule.c.h | 8 +- Modules/clinic/_csv.c.h | 83 +- Modules/clinic/_curses_panel.c.h | 47 +- Modules/clinic/_cursesmodule.c.h | 67 +- Modules/clinic/_datetimemodule.c.h | 58 +- Modules/clinic/_dbmmodule.c.h | 34 +- Modules/clinic/_elementtree.c.h | 431 +- Modules/clinic/_functoolsmodule.c.h | 104 + Modules/clinic/_gdbmmodule.c.h | 21 +- Modules/clinic/_hashopenssl.c.h | 508 +- Modules/clinic/_heapqmodule.c.h | 8 +- Modules/clinic/_localemodule.c.h | 8 +- Modules/clinic/_lsprof.c.h | 8 +- Modules/clinic/_lzmamodule.c.h | 74 +- Modules/clinic/_opcode.c.h | 33 +- Modules/clinic/_operator.c.h | 8 +- Modules/clinic/_pickle.c.h | 248 +- Modules/clinic/_posixsubprocess.c.h | 162 + Modules/clinic/_queuemodule.c.h | 90 +- Modules/clinic/_randommodule.c.h | 8 +- Modules/clinic/_ssl.c.h | 283 +- Modules/clinic/_statisticsmodule.c.h | 8 +- Modules/clinic/_struct.c.h | 97 +- Modules/clinic/_testclinic.c.h | 816 +- Modules/clinic/_testinternalcapi.c.h | 209 + Modules/clinic/_testmultiphase.c.h | 33 +- Modules/clinic/_tkinter.c.h | 24 +- Modules/clinic/_tracemalloc.c.h | 8 +- Modules/clinic/_typingmodule.c.h | 8 +- Modules/clinic/_weakref.c.h | 8 +- Modules/clinic/_winapi.c.h | 297 +- Modules/clinic/_zoneinfo.c.h | 375 + Modules/clinic/arraymodule.c.h | 60 +- Modules/clinic/audioop.c.h | 8 +- Modules/clinic/binascii.c.h | 211 +- Modules/clinic/cmathmodule.c.h | 35 +- Modules/clinic/fcntlmodule.c.h | 8 +- Modules/clinic/gcmodule.c.h | 58 +- Modules/clinic/grpmodule.c.h | 58 +- Modules/clinic/itertoolsmodule.c.h | 302 +- Modules/clinic/mathmodule.c.h | 191 +- Modules/clinic/md5module.c.h | 33 +- Modules/clinic/overlapped.c.h | 416 +- Modules/clinic/posixmodule.c.h | 2898 +- Modules/clinic/pwdmodule.c.h | 8 +- Modules/clinic/pyexpat.c.h | 89 +- Modules/clinic/readline.c.h | 8 +- Modules/clinic/resource.c.h | 55 +- Modules/clinic/selectmodule.c.h | 140 +- Modules/clinic/sha1module.c.h | 33 +- Modules/clinic/sha256module.c.h | 173 - Modules/clinic/sha2module.c.h | 440 + Modules/{_sha3 => }/clinic/sha3module.c.h | 35 +- Modules/clinic/sha512module.c.h | 173 - Modules/clinic/signalmodule.c.h | 8 +- Modules/clinic/socketmodule.c.h | 33 +- Modules/clinic/spwdmodule.c.h | 8 +- Modules/clinic/symtablemodule.c.h | 8 +- Modules/clinic/syslogmodule.c.h | 257 + Modules/clinic/termios.c.h | 8 +- Modules/clinic/unicodedata.c.h | 8 +- Modules/clinic/zlibmodule.c.h | 296 +- Modules/cmathmodule.c | 77 +- Modules/errnomodule.c | 10 +- Modules/faulthandler.c | 98 +- Modules/fcntlmodule.c | 15 +- Modules/gc_weakref.txt | 2 +- Modules/gcmodule.c | 156 +- Modules/getaddrinfo.c | 6 +- Modules/getbuildinfo.c | 12 +- Modules/getpath.c | 44 +- Modules/getpath.py | 2 +- Modules/grpmodule.c | 11 +- Modules/hashlib.h | 9 +- Modules/itertoolsmodule.c | 2069 +- Modules/main.c | 27 +- Modules/makesetup | 11 +- Modules/mathmodule.c | 1028 +- Modules/md5module.c | 341 +- Modules/mmapmodule.c | 143 +- Modules/nismodule.c | 6 +- Modules/ossaudiodev.c | 16 +- Modules/overlapped.c | 115 +- Modules/posixmodule.c | 1813 +- Modules/pwdmodule.c | 1 + Modules/pyexpat.c | 148 +- Modules/readline.c | 15 +- Modules/resource.c | 24 +- Modules/selectmodule.c | 19 +- Modules/sha1module.c | 319 +- Modules/sha256module.c | 756 - Modules/sha2module.c | 889 + Modules/{_sha3 => }/sha3module.c | 187 +- Modules/sha512module.c | 819 - Modules/signalmodule.c | 119 +- Modules/socketmodule.c | 1836 +- Modules/socketmodule.h | 18 + Modules/spwdmodule.c | 1 + Modules/symtablemodule.c | 19 +- Modules/syslogmodule.c | 199 +- Modules/termios.c | 5 +- Modules/timemodule.c | 121 +- Modules/tkappinit.c | 74 - Modules/tkinter.h | 8 - Modules/unicodedata.c | 36 +- Modules/unicodedata_db.h | 4919 +- Modules/unicodename_db.h | 52038 ++++++++-------- Modules/xxlimited.c | 13 +- Modules/xxlimited_35.c | 13 +- Modules/xxmodule.c | 16 +- Modules/xxsubtype.c | 24 +- Modules/zlibmodule.c | 632 +- Objects/abstract.c | 43 +- Objects/accu.c | 115 - Objects/boolobject.c | 56 +- Objects/bytearrayobject.c | 36 +- Objects/bytes_methods.c | 12 +- Objects/bytesobject.c | 129 +- Objects/call.c | 103 +- Objects/capsule.c | 3 +- Objects/cellobject.c | 23 +- Objects/classobject.c | 36 +- Objects/clinic/bytearrayobject.c.h | 187 +- Objects/clinic/bytesobject.c.h | 187 +- Objects/clinic/classobject.c.h | 16 +- Objects/clinic/codeobject.c.h | 94 +- Objects/clinic/complexobject.c.h | 33 +- Objects/clinic/descrobject.c.h | 58 +- Objects/clinic/dictobject.c.h | 8 +- Objects/clinic/enumobject.c.h | 37 +- Objects/clinic/floatobject.c.h | 20 +- Objects/clinic/funcobject.c.h | 33 +- Objects/clinic/listobject.c.h | 42 +- Objects/clinic/longobject.c.h | 109 +- Objects/clinic/memoryobject.c.h | 168 +- Objects/clinic/moduleobject.c.h | 33 +- Objects/clinic/odictobject.c.h | 133 +- Objects/clinic/structseq.c.h | 33 +- Objects/clinic/tupleobject.c.h | 12 +- Objects/clinic/typeobject.c.h | 12 +- Objects/clinic/typevarobject.c.h | 786 + Objects/clinic/unicodeobject.c.h | 166 +- Objects/codeobject.c | 683 +- Objects/complexobject.c | 15 +- Objects/descrobject.c | 150 +- Objects/dictobject.c | 822 +- Objects/enumobject.c | 3 +- Objects/exceptions.c | 492 +- Objects/fileobject.c | 64 +- Objects/floatobject.c | 96 +- Objects/frame_layout.md | 22 +- Objects/frameobject.c | 618 +- Objects/funcobject.c | 286 +- Objects/genericaliasobject.c | 73 +- Objects/genobject.c | 375 +- Objects/interpreteridobject.c | 2 +- Objects/iterobject.c | 50 +- Objects/listobject.c | 280 +- Objects/longobject.c | 1873 +- Objects/memoryobject.c | 166 +- Objects/methodobject.c | 15 +- Objects/moduleobject.c | 248 +- Objects/namespaceobject.c | 5 +- Objects/object.c | 747 +- Objects/object_layout.md | 82 + Objects/object_layout_312.gv | 50 + Objects/object_layout_312.png | Bin 0 -> 30688 bytes Objects/object_layout_full_312.gv | 25 + Objects/object_layout_full_312.png | Bin 0 -> 17092 bytes Objects/obmalloc.c | 1467 +- Objects/odictobject.c | 86 +- Objects/rangeobject.c | 211 +- Objects/setobject.c | 66 +- Objects/sliceobject.c | 152 +- Objects/stringlib/asciilib.h | 1 + Objects/stringlib/clinic/transmogrify.h.h | 33 +- Objects/stringlib/count.h | 7 +- Objects/stringlib/eq.h | 10 +- Objects/stringlib/fastsearch.h | 41 +- Objects/stringlib/join.h | 3 +- Objects/stringlib/localeutil.h | 2 +- Objects/stringlib/replace.h | 4 +- Objects/stringlib/stringdefs.h | 1 + .../stringlib_find_two_way_notes.txt | 4 +- Objects/stringlib/transmogrify.h | 3 +- Objects/stringlib/ucs1lib.h | 1 + Objects/stringlib/ucs2lib.h | 4 + Objects/stringlib/ucs4lib.h | 4 + Objects/stringlib/undef.h | 1 + Objects/stringlib/unicode_format.h | 15 +- Objects/stringlib/unicodedefs.h | 32 - Objects/structseq.c | 195 +- Objects/tupleobject.c | 149 +- Objects/typeobject.c | 3142 +- Objects/typevarobject.c | 1689 + Objects/unicodeobject.c | 2203 +- Objects/unicodetype_db.h | 4746 +- Objects/unionobject.c | 27 +- Objects/weakrefobject.c | 45 +- PC/_msi.c | 17 +- PC/_testconsole.c | 12 +- PC/_wmimodule.cpp | 323 + PC/clinic/_msi.c.h | 32 +- PC/clinic/_testconsole.c.h | 58 +- PC/clinic/_wmimodule.cpp.h | 75 + PC/clinic/msvcrtmodule.c.h | 70 +- PC/clinic/winreg.c.h | 666 +- PC/clinic/winsound.c.h | 83 +- PC/config.c | 16 +- PC/config_minimal.c | 6 + PC/empty.c | 6 - PC/launcher.c | 15 +- PC/launcher2.c | 21 +- PC/layout/main.py | 7 +- PC/layout/support/appxmanifest.py | 7 +- PC/layout/support/catalog.py | 2 - PC/layout/support/constants.py | 1 - PC/layout/support/options.py | 7 - PC/layout/support/pip.py | 1 - PC/layout/support/props.py | 2 - PC/layout/support/python.props | 110 +- PC/msvcrtmodule.c | 200 +- PC/pyconfig.h | 76 +- PC/python3dll.c | 15 +- PC/readme.txt | 151 +- PC/testpy.py | 30 - PC/winreg.c | 553 +- PC/winsound.c | 88 +- PCbuild/Directory.Build.props | 8 +- PCbuild/_asyncio.vcxproj | 218 +- PCbuild/_asyncio.vcxproj.filters | 40 +- PCbuild/_bz2.vcxproj | 254 +- PCbuild/_bz2.vcxproj.filters | 116 +- PCbuild/_ctypes.vcxproj | 247 +- PCbuild/_ctypes.vcxproj.filters | 89 +- PCbuild/_ctypes_test.vcxproj | 222 +- PCbuild/_ctypes_test.vcxproj.filters | 56 +- PCbuild/_decimal.vcxproj | 318 +- PCbuild/_decimal.vcxproj.filters | 252 +- PCbuild/_elementtree.vcxproj | 270 +- PCbuild/_elementtree.vcxproj.filters | 170 +- PCbuild/_freeze_module.vcxproj | 875 +- PCbuild/_freeze_module.vcxproj.filters | 982 +- PCbuild/_hashlib.vcxproj | 230 +- PCbuild/_hashlib.vcxproj.filters | 40 +- PCbuild/_lzma.vcxproj | 244 +- PCbuild/_lzma.vcxproj.filters | 40 +- PCbuild/_msi.vcxproj | 228 +- PCbuild/_msi.vcxproj.filters | 40 +- PCbuild/_multiprocessing.vcxproj | 234 +- PCbuild/_multiprocessing.vcxproj.filters | 62 +- PCbuild/_overlapped.vcxproj | 226 +- PCbuild/_overlapped.vcxproj.filters | 40 +- PCbuild/_queue.vcxproj | 218 +- PCbuild/_queue.vcxproj.filters | 40 +- PCbuild/_socket.vcxproj | 232 +- PCbuild/_socket.vcxproj.filters | 56 +- PCbuild/_sqlite3.vcxproj | 274 +- PCbuild/_sqlite3.vcxproj.filters | 152 +- PCbuild/_ssl.vcxproj | 244 +- PCbuild/_ssl.vcxproj.filters | 46 +- PCbuild/_testbuffer.vcxproj | 216 +- PCbuild/_testbuffer.vcxproj.filters | 40 +- PCbuild/_testcapi.vcxproj | 246 +- PCbuild/_testcapi.vcxproj.filters | 105 +- PCbuild/_testclinic.vcxproj | 110 + PCbuild/_testclinic.vcxproj.filters | 21 + PCbuild/_testconsole.vcxproj | 228 +- PCbuild/_testconsole.vcxproj.filters | 44 +- PCbuild/_testembed.vcxproj | 222 +- PCbuild/_testembed.vcxproj.filters | 44 +- PCbuild/_testimportmultiple.vcxproj | 220 +- PCbuild/_testimportmultiple.vcxproj.filters | 40 +- PCbuild/_testinternalcapi.vcxproj | 220 +- PCbuild/_testinternalcapi.vcxproj.filters | 40 +- PCbuild/_testmultiphase.vcxproj | 228 +- PCbuild/_testmultiphase.vcxproj.filters | 44 +- PCbuild/_testsinglephase.vcxproj | 115 + PCbuild/_testsinglephase.vcxproj.filters | 23 + PCbuild/_tkinter.vcxproj | 271 +- PCbuild/_tkinter.vcxproj.filters | 46 +- PCbuild/_uuid.vcxproj | 228 +- PCbuild/_uuid.vcxproj.filters | 42 +- PCbuild/_wmi.vcxproj | 119 + PCbuild/_wmi.vcxproj.filters | 22 + PCbuild/_zoneinfo.vcxproj | 218 +- PCbuild/_zoneinfo.vcxproj.filters | 40 +- PCbuild/blurb.bat | 56 +- PCbuild/build.bat | 370 +- PCbuild/build_env.bat | 2 +- PCbuild/clean.bat | 10 +- PCbuild/env.bat | 54 +- PCbuild/env.ps1 | 4 +- PCbuild/find_msbuild.bat | 126 +- PCbuild/find_python.bat | 182 +- PCbuild/get_externals.bat | 234 +- PCbuild/idle.bat | 54 +- PCbuild/lib.pyproj | 1830 - PCbuild/libffi.props | 40 +- PCbuild/liblzma.vcxproj | 492 +- PCbuild/liblzma.vcxproj.filters | 868 +- PCbuild/openssl.props | 68 +- PCbuild/openssl.vcxproj | 276 +- PCbuild/pcbuild.proj | 318 +- PCbuild/pcbuild.sln | 3171 +- PCbuild/prepare_libffi.bat | 424 +- PCbuild/prepare_ssl.bat | 116 +- PCbuild/prepare_tcltk.bat | 118 +- PCbuild/pyexpat.vcxproj | 238 +- PCbuild/pyexpat.vcxproj.filters | 80 +- PCbuild/pylauncher.vcxproj | 228 +- PCbuild/pylauncher.vcxproj.filters | 54 +- PCbuild/pyproject.props | 498 +- PCbuild/pyshellext.vcxproj | 232 +- PCbuild/pyshellext.vcxproj.filters | 54 +- PCbuild/python.props | 506 +- PCbuild/python.vcxproj | 324 +- PCbuild/python.vcxproj.filters | 52 +- PCbuild/python3dll.vcxproj | 218 +- PCbuild/python3dll.vcxproj.filters | 44 +- PCbuild/python_uwp.vcxproj | 256 +- PCbuild/python_uwp.vcxproj.filters | 50 +- PCbuild/pythoncore.vcxproj | 1259 +- PCbuild/pythoncore.vcxproj.filters | 2701 +- PCbuild/pythonw.vcxproj | 219 +- PCbuild/pythonw.vcxproj.filters | 40 +- PCbuild/pythonw_uwp.vcxproj | 256 +- PCbuild/pythonw_uwp.vcxproj.filters | 50 +- PCbuild/pywlauncher.vcxproj | 226 +- PCbuild/pywlauncher.vcxproj.filters | 54 +- PCbuild/readme.txt | 586 +- PCbuild/regen.targets | 20 +- PCbuild/rt.bat | 156 +- PCbuild/select.vcxproj | 224 +- PCbuild/select.vcxproj.filters | 40 +- PCbuild/sqlite3.vcxproj | 242 +- PCbuild/sqlite3.vcxproj.filters | 62 +- PCbuild/tcl.vcxproj | 152 +- PCbuild/tcltk.props | 133 +- PCbuild/tix.vcxproj | 200 +- PCbuild/tk.vcxproj | 164 +- PCbuild/unicodedata.vcxproj | 224 +- PCbuild/unicodedata.vcxproj.filters | 62 +- PCbuild/venvlauncher.vcxproj | 234 +- PCbuild/venvlauncher.vcxproj.filters | 50 +- PCbuild/venvwlauncher.vcxproj | 234 +- PCbuild/venvwlauncher.vcxproj.filters | 50 +- PCbuild/winsound.vcxproj | 228 +- PCbuild/winsound.vcxproj.filters | 42 +- PCbuild/xxlimited.vcxproj | 222 +- PCbuild/xxlimited.vcxproj.filters | 24 +- PCbuild/xxlimited_35.vcxproj | 222 +- PCbuild/xxlimited_35.vcxproj.filters | 26 +- Parser/Python.asdl | 13 +- Parser/action_helpers.c | 631 +- Parser/asdl_c.py | 93 +- Parser/myreadline.c | 43 +- Parser/parser.c | 13543 ++-- Parser/pegen.c | 118 +- Parser/pegen.h | 35 +- Parser/pegen_errors.c | 33 +- Parser/string_parser.c | 1096 +- Parser/string_parser.h | 39 +- Parser/token.c | 19 +- Parser/tokenizer.c | 1156 +- Parser/tokenizer.h | 68 +- Programs/_bootstrap_python.c | 6 +- Programs/_freeze_module.c | 8 +- Programs/_testembed.c | 31 +- Programs/test_frozenmain.h | 70 +- Python/Python-ast.c | 1684 +- Python/Python-tokenize.c | 227 +- Python/_warnings.c | 258 +- Python/adaptive.md | 13 +- Python/asm_trampoline.S | 28 + Python/assemble.c | 603 + Python/ast.c | 117 +- Python/ast_opt.c | 52 +- Python/ast_unparse.c | 19 +- Python/bltinmodule.c | 453 +- Python/bootstrap_hash.c | 10 +- Python/bytecodes.c | 3506 ++ Python/ceval.c | 6953 +-- Python/ceval_gil.c | 1121 + Python/ceval_gil.h | 344 - Python/ceval_macros.h | 344 + Python/clinic/Python-tokenize.c.h | 70 +- Python/clinic/_warnings.c.h | 198 +- Python/clinic/bltinmodule.c.h | 392 +- Python/clinic/context.c.h | 8 +- Python/clinic/import.c.h | 89 +- Python/clinic/instrumentation.c.h | 311 + Python/clinic/marshal.c.h | 8 +- Python/clinic/sysmodule.c.h | 388 +- Python/clinic/traceback.c.h | 33 +- Python/codecs.c | 36 +- Python/compile.c | 8953 ++- Python/condvar.h | 6 +- Python/context.c | 78 +- Python/deepfreeze/README.txt | 2 +- Python/dtoa.c | 80 +- Python/dynload_shlib.c | 2 +- Python/dynload_win.c | 23 +- Python/errors.c | 482 +- Python/fileutils.c | 383 +- Python/flowgraph.c | 2218 + Python/formatter_unicode.c | 4 +- Python/frame.c | 56 +- Python/frozen.c | 83 +- Python/frozen_modules/README.txt | 2 +- Python/frozenmain.c | 2 +- Python/future.c | 69 +- Python/generated_cases.c.h | 4805 ++ Python/getargs.c | 326 +- Python/getversion.c | 17 +- Python/hamt.c | 227 +- Python/import.c | 3832 +- Python/importdl.c | 23 +- Python/initconfig.c | 140 +- Python/instrumentation.c | 2178 + Python/intrinsics.c | 260 + Python/legacy_tracing.c | 513 + Python/makeopcodetargets.py | 34 +- Python/marshal.c | 193 +- Python/modsupport.c | 58 +- Python/opcode_metadata.h | 1001 + Python/opcode_targets.h | 186 +- Python/perf_trampoline.c | 463 + Python/preconfig.c | 40 +- Python/pylifecycle.c | 582 +- Python/pystate.c | 1971 +- Python/pystrtod.c | 41 +- Python/pythonrun.c | 249 +- Python/pytime.c | 43 +- Python/specialize.c | 1472 +- Python/stdlib_module_names.h | 13 +- Python/structmember.c | 23 +- Python/suggestions.c | 203 +- Python/symtable.c | 682 +- Python/sysmodule.c | 775 +- Python/thread.c | 91 +- Python/thread_nt.h | 40 +- Python/thread_pthread.h | 225 +- Python/thread_pthread_stubs.h | 9 +- Python/traceback.c | 86 +- Python/tracemalloc.c | 1560 + README.rst | 36 +- Tools/README | 25 +- Tools/build/check_extension_modules.py | 484 + Tools/{scripts => build}/deepfreeze.py | 83 +- Tools/{scripts => build}/freeze_modules.py | 14 +- .../generate_global_objects.py | 194 +- Tools/build/generate_levenshtein_examples.py | 70 + Tools/{scripts => build}/generate_opcode_h.py | 103 +- .../{scripts => build}/generate_re_casefix.py | 7 +- .../generate_sre_constants.py | 6 +- .../generate_stdlib_module_names.py | 68 +- Tools/{scripts => build}/generate_token.py | 56 +- .../parse_html5_entities.py | 28 +- Tools/{scripts => build}/smelly.py | 0 Tools/{scripts => build}/stable_abi.py | 21 +- Tools/{scripts => build}/umarshal.py | 8 +- Tools/{scripts => build}/update_file.py | 0 .../verify_ensurepip_wheels.py | 16 +- Tools/buildbot/build.bat | 34 +- Tools/buildbot/buildmsi.bat | 16 +- Tools/buildbot/clean.bat | 34 +- Tools/buildbot/remoteDeploy.bat | 120 +- Tools/buildbot/remotePythonInfo.bat | 70 +- Tools/buildbot/test.bat | 102 +- Tools/c-analyzer/TODO | 1 - Tools/c-analyzer/c_analyzer/__main__.py | 2 - Tools/c-analyzer/c_analyzer/info.py | 4 - Tools/c-analyzer/c_common/fsutil.py | 19 + Tools/c-analyzer/c_common/info.py | 0 Tools/c-analyzer/c_common/iterutil.py | 4 - Tools/c-analyzer/c_common/show.py | 0 Tools/c-analyzer/c_common/tables.py | 285 +- Tools/c-analyzer/c_parser/__init__.py | 8 +- Tools/c-analyzer/c_parser/__main__.py | 4 - Tools/c-analyzer/c_parser/_state_machine.py | 244 - Tools/c-analyzer/c_parser/info.py | 32 +- Tools/c-analyzer/c_parser/parser/__init__.py | 4 +- Tools/c-analyzer/c_parser/parser/_alt.py | 6 - Tools/c-analyzer/c_parser/parser/_common.py | 20 +- Tools/c-analyzer/c_parser/parser/_delim.py | 54 - .../c-analyzer/c_parser/parser/_func_body.py | 25 +- Tools/c-analyzer/c_parser/parser/_global.py | 1 - Tools/c-analyzer/c_parser/parser/_regexes.py | 3 +- .../c_parser/preprocessor/__init__.py | 99 +- .../c_parser/preprocessor/common.py | 23 +- Tools/c-analyzer/c_parser/preprocessor/gcc.py | 174 +- .../c-analyzer/c_parser/preprocessor/pure.py | 2 +- Tools/c-analyzer/check-c-globals.py | 7 +- Tools/c-analyzer/cpython/__main__.py | 112 +- Tools/c-analyzer/cpython/_analyzer.py | 80 +- Tools/c-analyzer/cpython/_builtin_types.py | 365 + Tools/c-analyzer/cpython/_capi.py | 10 +- Tools/c-analyzer/cpython/_parser.py | 198 +- Tools/c-analyzer/cpython/globals-to-fix.tsv | 1085 +- Tools/c-analyzer/cpython/ignored.tsv | 1828 +- Tools/c-analyzer/distutils/README | 2 + .../c-analyzer/distutils}/__init__.py | 0 Tools/c-analyzer/distutils/_msvccompiler.py | 203 + Tools/c-analyzer/distutils/bcppcompiler.py | 109 + Tools/c-analyzer/distutils/ccompiler.py | 470 + .../c-analyzer}/distutils/cygwinccompiler.py | 121 +- {Lib => Tools/c-analyzer}/distutils/debug.py | 0 Tools/c-analyzer/distutils/dep_util.py | 29 + Tools/c-analyzer/distutils/errors.py | 48 + {Lib => Tools/c-analyzer}/distutils/log.py | 14 - .../c-analyzer}/distutils/msvc9compiler.py | 354 +- Tools/c-analyzer/distutils/msvccompiler.py | 327 + Tools/c-analyzer/distutils/spawn.py | 48 + Tools/c-analyzer/distutils/unixccompiler.py | 102 + Tools/c-analyzer/distutils/util.py | 171 + Tools/c-analyzer/table-file.py | 83 +- Tools/cases_generator/README.md | 36 + Tools/cases_generator/generate_cases.py | 1259 + .../cases_generator/interpreter_definition.md | 409 + Tools/cases_generator/lexer.py | 262 + Tools/cases_generator/parser.py | 422 + Tools/cases_generator/plexer.py | 105 + Tools/cases_generator/test_generator.py | 529 + Tools/clinic/clinic.py | 1355 +- Tools/clinic/cpp.py | 33 +- Tools/clinic/mypy.ini | 12 + Tools/clinic/requirements-dev.txt | 2 + Tools/demo/README | 16 - Tools/demo/beer.py | 25 - Tools/demo/eiffel.py | 146 - Tools/demo/hanoi.py | 154 - Tools/demo/life.py | 262 - Tools/demo/markov.py | 125 - Tools/demo/mcast.py | 82 - Tools/demo/queens.py | 85 - Tools/demo/redemo.py | 171 - Tools/demo/rpython.py | 37 - Tools/demo/rpythond.py | 58 - Tools/demo/sortvisu.py | 635 - Tools/demo/spreadsheet.py | 829 - Tools/demo/vector.py | 94 - Tools/freeze/test/freeze.py | 31 +- Tools/gdb/libpython.py | 144 +- Tools/i18n/pygettext.py | 11 +- Tools/importbench/importbench.py | 17 +- Tools/iobench/iobench.py | 96 +- Tools/msi/build.bat | 182 +- Tools/msi/buildrelease.bat | 522 +- Tools/msi/bundle/Default.wxl | 7 +- Tools/msi/bundle/bootstrap/pch.h | 2 +- Tools/msi/bundle/bootstrap/pythonba.sln | 44 +- Tools/msi/bundle/bootstrap/pythonba.vcxproj | 150 +- Tools/msi/bundle/bootstrap/resource.h | 2 +- Tools/msi/bundle/bundle.targets | 1 - Tools/msi/bundle/bundle.wxs | 5 +- Tools/msi/bundle/packagegroups/tools.wxs | 26 - Tools/msi/common.wxs | 8 +- Tools/msi/get_externals.bat | 182 +- Tools/msi/launcher/launcher.wxs | 21 + Tools/msi/lib/lib_files.wxs | 2 +- Tools/msi/make_appx.ps1 | 142 +- Tools/msi/make_cat.ps1 | 90 +- Tools/msi/make_zip.proj | 80 +- Tools/msi/msi.props | 378 +- Tools/msi/sign_build.ps1 | 66 +- Tools/msi/tcltk/tcltk_files.wxs | 3 + Tools/msi/test/test_files.wxs | 2 +- Tools/msi/testrelease.bat | 234 +- Tools/msi/tools/tools.wixproj | 38 - Tools/msi/tools/tools.wxs | 17 - Tools/msi/tools/tools_en-US.wxl | 5 - Tools/msi/tools/tools_files.wxs | 20 - Tools/msi/uploadrelease.bat | 218 +- Tools/msi/uploadrelease.proj | 226 +- Tools/msi/uploadrelease.ps1 | 342 +- Tools/msi/wix.props | 22 +- Tools/nuget/build.bat | 140 +- Tools/nuget/make_pkg.proj | 126 +- Tools/{scripts => patchcheck}/patchcheck.py | 31 +- Tools/{scripts => patchcheck}/reindent.py | 0 Tools/{scripts => patchcheck}/untabify.py | 0 Tools/peg_generator/Makefile | 2 +- .../peg_extension/peg_extension.c | 3 +- Tools/peg_generator/pegen/build.py | 54 +- Tools/peg_generator/pegen/c_generator.py | 11 +- Tools/peg_generator/pegen/grammar.py | 7 - Tools/peg_generator/scripts/benchmark.py | 2 +- .../peg_generator/scripts/grammar_grapher.py | 1 - .../scripts/test_parse_directory.py | 2 - .../scripts/test_pypi_packages.py | 3 +- Tools/requirements-hypothesis.txt | 4 + Tools/scripts/2to3 | 2 +- Tools/scripts/README | 67 +- Tools/scripts/abitype.py | 202 - Tools/scripts/analyze_dxp.py | 129 - Tools/scripts/byext.py | 132 - Tools/scripts/byteyears.py | 61 - Tools/scripts/cleanfuture.py | 275 - Tools/scripts/copytime.py | 26 - Tools/scripts/crlf.py | 23 - Tools/scripts/db2pickle.py | 135 - Tools/scripts/divmod_threshold.py | 56 + Tools/scripts/dutree.doc | 54 - Tools/scripts/dutree.py | 60 - Tools/scripts/eptags.py | 57 - Tools/scripts/find-uname.py | 40 - Tools/scripts/find_recursionlimit.py | 128 - Tools/scripts/finddiv.py | 89 - Tools/scripts/findlinksto.py | 43 - Tools/scripts/findnocoding.py | 107 - Tools/scripts/fixcid.py | 316 - Tools/scripts/fixdiv.py | 378 - Tools/scripts/fixheader.py | 49 - Tools/scripts/fixnotice.py | 109 - Tools/scripts/fixps.py | 31 - Tools/scripts/get-remote-certificate.py | 70 - Tools/scripts/google.py | 25 - Tools/scripts/gprof2html.py | 87 - Tools/scripts/highlight.py | 265 - Tools/scripts/idle3 | 2 +- Tools/scripts/ifdef.py | 111 - Tools/scripts/import_diagnostics.py | 37 - Tools/scripts/lfcr.py | 24 - Tools/scripts/linktree.py | 80 - Tools/scripts/lll.py | 27 - Tools/scripts/mailerdaemon.py | 246 - Tools/scripts/make_ctype.py | 94 - Tools/scripts/md5sum.py | 93 - Tools/scripts/mkreal.py | 65 - Tools/scripts/nm2def.py | 104 - Tools/scripts/objgraph.py | 211 - Tools/scripts/parseentities.py | 64 - Tools/scripts/pathfix.py | 226 - Tools/scripts/pdeps.py | 164 - Tools/scripts/pep384_macrocheck.py | 148 - Tools/scripts/pickle2db.py | 147 - Tools/scripts/pindent.py | 506 - Tools/scripts/ptags.py | 54 - Tools/scripts/pysource.py | 130 - Tools/scripts/reindent-rst.py | 14 - Tools/scripts/rgrep.py | 67 - Tools/scripts/startuptime.py | 22 - Tools/scripts/suff.py | 26 - Tools/scripts/summarize_stats.py | 549 +- Tools/scripts/texi2html.py | 2071 - Tools/scripts/which.py | 61 - Tools/scripts/win_add2path.py | 58 - Tools/ssl/multissltests.py | 10 +- Tools/unicode/genmap_tchinese.py | 239 + Tools/unicode/genwincodecs.bat | 14 +- Tools/unicode/makeunicodedata.py | 49 +- Tools/wasm/.editorconfig | 3 +- Tools/wasm/README.md | 10 +- Tools/wasm/Setup.local.example | 1 + Tools/wasm/config.site-wasm32-emscripten | 3 - Tools/wasm/config.site-wasm32-wasi | 6 +- Tools/wasm/wasm_assets.py | 15 +- Tools/wasm/wasm_build.py | 14 +- aclocal.m4 | 12 +- configure | 25187 +++++--- configure.ac | 2665 +- pyconfig.h.in | 156 +- setup.py | 1628 - 2639 files changed, 483191 insertions(+), 267478 deletions(-) create mode 100644 .azure-pipelines/ci.yml create mode 100755 .azure-pipelines/posix-deps-apt.sh create mode 100644 .azure-pipelines/posix-steps.yml create mode 100644 .azure-pipelines/pr.yml create mode 100644 .azure-pipelines/prebuild-checks.yml create mode 100644 .azure-pipelines/windows-layout-steps.yml create mode 100644 .azure-pipelines/windows-steps.yml create mode 100644 .devcontainer/Dockerfile create mode 100644 .devcontainer/devcontainer.json create mode 100644 .gitattributes create mode 100644 .github/CODEOWNERS create mode 100644 .github/CONTRIBUTING.rst create mode 100644 .github/ISSUE_TEMPLATE/bug.md create mode 100644 .github/ISSUE_TEMPLATE/config.yml create mode 100644 .github/ISSUE_TEMPLATE/crash.md create mode 100644 .github/ISSUE_TEMPLATE/documentation.md create mode 100644 .github/ISSUE_TEMPLATE/feature.md create mode 100644 .github/PULL_REQUEST_TEMPLATE.md create mode 100644 .github/SECURITY.md create mode 100644 .github/dependabot.yml create mode 100644 .github/problem-matchers/gcc.json create mode 100644 .github/problem-matchers/msvc.json create mode 100644 .github/workflows/build.yml create mode 100644 .github/workflows/build_msi.yml create mode 100644 .github/workflows/documentation-links.yml create mode 100644 .github/workflows/lint.yml create mode 100644 .github/workflows/mypy.yml create mode 100644 .github/workflows/new-bugs-announce-notifier.yml create mode 100755 .github/workflows/posix-deps-apt.sh create mode 100644 .github/workflows/project-updater.yml create mode 100644 .github/workflows/regen-abidump.sh create mode 100644 .github/workflows/require-pr-label.yml create mode 100644 .github/workflows/reusable-docs.yml create mode 100644 .github/workflows/stale.yml create mode 100644 .github/workflows/verify-ensurepip-wheels.yml create mode 100644 .gitignore create mode 100644 .mailmap create mode 100644 .pre-commit-config.yaml create mode 100644 .readthedocs.yml create mode 100644 Doc/c-api/perfmaps.rst create mode 100644 Doc/constraints.txt delete mode 100644 Doc/data/python3.11.abi create mode 100644 Doc/data/python3.12.abi delete mode 100644 Doc/distutils/_setuptools_disclaimer.rst delete mode 100644 Doc/distutils/apiref.rst delete mode 100644 Doc/distutils/builtdist.rst delete mode 100644 Doc/distutils/commandref.rst delete mode 100644 Doc/distutils/configfile.rst delete mode 100644 Doc/distutils/examples.rst delete mode 100644 Doc/distutils/extending.rst delete mode 100644 Doc/distutils/index.rst delete mode 100644 Doc/distutils/introduction.rst delete mode 100644 Doc/distutils/packageindex.rst delete mode 100644 Doc/distutils/setupscript.rst delete mode 100644 Doc/distutils/sourcedist.rst delete mode 100644 Doc/distutils/uploading.rst create mode 100644 Doc/howto/perf_profiling.rst rename {Tools/scripts => Doc/includes}/diff.py (98%) mode change 100755 => 100644 rename {Tools/scripts => Doc/includes}/ndiff.py (80%) mode change 100755 => 100644 rename Doc/includes/{ => newtypes}/custom.c (91%) rename Doc/includes/{ => newtypes}/custom2.c (81%) rename Doc/includes/{ => newtypes}/custom3.c (81%) rename Doc/includes/{ => newtypes}/custom4.c (84%) create mode 100644 Doc/includes/newtypes/pyproject.toml create mode 100644 Doc/includes/newtypes/setup.py rename Doc/includes/{ => newtypes}/sublist.c (100%) rename Doc/includes/{ => newtypes}/test.py (94%) delete mode 100644 Doc/includes/setup.py delete mode 100644 Doc/includes/sqlite3/pysqlite_datetime.py delete mode 100644 Doc/includes/turtle-star.py delete mode 100644 Doc/install/index.rst delete mode 100644 Doc/library/asynchat.rst delete mode 100644 Doc/library/asyncore.rst delete mode 100644 Doc/library/distutils.rst delete mode 100644 Doc/library/imp.rst create mode 100644 Doc/library/kde_example.png delete mode 100644 Doc/library/smtpd.rst create mode 100644 Doc/library/sys.monitoring.rst create mode 100644 Doc/requirements-oldest-sphinx.txt create mode 100644 Doc/tools/.nitignore create mode 100644 Doc/tools/check-warnings.py delete mode 100644 Doc/tools/extensions/suspicious.py delete mode 100644 Doc/tools/rstlint.py delete mode 100644 Doc/tools/susp-ignored.csv create mode 100644 Doc/whatsnew/3.12.rst rename Include/{internal/pycore_interpreteridobject.h => cpython/interpreteridobject.h} (51%) create mode 100644 Include/cpython/memoryobject.h delete mode 100644 Include/internal/pycore_accu.h create mode 100644 Include/internal/pycore_atexit.h create mode 100644 Include/internal/pycore_ceval_state.h create mode 100644 Include/internal/pycore_descrobject.h create mode 100644 Include/internal/pycore_dict_state.h create mode 100644 Include/internal/pycore_faulthandler.h create mode 100644 Include/internal/pycore_fileutils_windows.h create mode 100644 Include/internal/pycore_flowgraph.h create mode 100644 Include/internal/pycore_global_objects_fini_generated.h create mode 100644 Include/internal/pycore_instruments.h create mode 100644 Include/internal/pycore_intrinsics.h create mode 100644 Include/internal/pycore_memoryobject.h create mode 100644 Include/internal/pycore_object_state.h create mode 100644 Include/internal/pycore_obmalloc.h create mode 100644 Include/internal/pycore_obmalloc_init.h create mode 100644 Include/internal/pycore_opcode_utils.h create mode 100644 Include/internal/pycore_pymem_init.h create mode 100644 Include/internal/pycore_pythread.h create mode 100644 Include/internal/pycore_range.h create mode 100644 Include/internal/pycore_runtime_init_generated.h create mode 100644 Include/internal/pycore_time.h rename Include/{token.h => internal/pycore_token.h} (70%) create mode 100644 Include/internal/pycore_tracemalloc.h create mode 100644 Include/internal/pycore_typevarobject.h create mode 100644 Include/internal/pycore_unicodeobject_generated.h create mode 100644 Include/interpreteridobject.h create mode 100644 Include/pystats.h delete mode 100644 Lib/_bootsubprocess.py create mode 100644 Lib/_pydatetime.py create mode 100644 Lib/_pylong.py delete mode 100644 Lib/ctypes/test/__main__.py delete mode 100644 Lib/distutils/README delete mode 100644 Lib/distutils/__init__.py delete mode 100644 Lib/distutils/_msvccompiler.py delete mode 100644 Lib/distutils/archive_util.py delete mode 100644 Lib/distutils/bcppcompiler.py delete mode 100644 Lib/distutils/ccompiler.py delete mode 100644 Lib/distutils/cmd.py delete mode 100644 Lib/distutils/command/__init__.py delete mode 100644 Lib/distutils/command/bdist.py delete mode 100644 Lib/distutils/command/bdist_dumb.py delete mode 100644 Lib/distutils/command/bdist_rpm.py delete mode 100644 Lib/distutils/command/build.py delete mode 100644 Lib/distutils/command/build_clib.py delete mode 100644 Lib/distutils/command/build_ext.py delete mode 100644 Lib/distutils/command/build_py.py delete mode 100644 Lib/distutils/command/build_scripts.py delete mode 100644 Lib/distutils/command/check.py delete mode 100644 Lib/distutils/command/clean.py delete mode 100644 Lib/distutils/command/command_template delete mode 100644 Lib/distutils/command/config.py delete mode 100644 Lib/distutils/command/install.py delete mode 100644 Lib/distutils/command/install_data.py delete mode 100644 Lib/distutils/command/install_egg_info.py delete mode 100644 Lib/distutils/command/install_headers.py delete mode 100644 Lib/distutils/command/install_lib.py delete mode 100644 Lib/distutils/command/install_scripts.py delete mode 100644 Lib/distutils/command/register.py delete mode 100644 Lib/distutils/command/sdist.py delete mode 100644 Lib/distutils/command/upload.py delete mode 100644 Lib/distutils/config.py delete mode 100644 Lib/distutils/core.py delete mode 100644 Lib/distutils/dep_util.py delete mode 100644 Lib/distutils/dir_util.py delete mode 100644 Lib/distutils/dist.py delete mode 100644 Lib/distutils/errors.py delete mode 100644 Lib/distutils/extension.py delete mode 100644 Lib/distutils/fancy_getopt.py delete mode 100644 Lib/distutils/file_util.py delete mode 100644 Lib/distutils/filelist.py delete mode 100644 Lib/distutils/msvccompiler.py delete mode 100644 Lib/distutils/spawn.py delete mode 100644 Lib/distutils/sysconfig.py delete mode 100644 Lib/distutils/tests/Setup.sample delete mode 100644 Lib/distutils/tests/__init__.py delete mode 100644 Lib/distutils/tests/includetest.rst delete mode 100644 Lib/distutils/tests/support.py delete mode 100644 Lib/distutils/tests/test_archive_util.py delete mode 100644 Lib/distutils/tests/test_bdist.py delete mode 100644 Lib/distutils/tests/test_bdist_dumb.py delete mode 100644 Lib/distutils/tests/test_bdist_rpm.py delete mode 100644 Lib/distutils/tests/test_build.py delete mode 100644 Lib/distutils/tests/test_build_clib.py delete mode 100644 Lib/distutils/tests/test_build_ext.py delete mode 100644 Lib/distutils/tests/test_build_py.py delete mode 100644 Lib/distutils/tests/test_build_scripts.py delete mode 100644 Lib/distutils/tests/test_check.py delete mode 100644 Lib/distutils/tests/test_clean.py delete mode 100644 Lib/distutils/tests/test_cmd.py delete mode 100644 Lib/distutils/tests/test_config.py delete mode 100644 Lib/distutils/tests/test_config_cmd.py delete mode 100644 Lib/distutils/tests/test_core.py delete mode 100644 Lib/distutils/tests/test_cygwinccompiler.py delete mode 100644 Lib/distutils/tests/test_dep_util.py delete mode 100644 Lib/distutils/tests/test_dir_util.py delete mode 100644 Lib/distutils/tests/test_dist.py delete mode 100644 Lib/distutils/tests/test_extension.py delete mode 100644 Lib/distutils/tests/test_file_util.py delete mode 100644 Lib/distutils/tests/test_filelist.py delete mode 100644 Lib/distutils/tests/test_install.py delete mode 100644 Lib/distutils/tests/test_install_data.py delete mode 100644 Lib/distutils/tests/test_install_headers.py delete mode 100644 Lib/distutils/tests/test_install_lib.py delete mode 100644 Lib/distutils/tests/test_install_scripts.py delete mode 100644 Lib/distutils/tests/test_log.py delete mode 100644 Lib/distutils/tests/test_msvc9compiler.py delete mode 100644 Lib/distutils/tests/test_msvccompiler.py delete mode 100644 Lib/distutils/tests/test_register.py delete mode 100644 Lib/distutils/tests/test_sdist.py delete mode 100644 Lib/distutils/tests/test_spawn.py delete mode 100644 Lib/distutils/tests/test_sysconfig.py delete mode 100644 Lib/distutils/tests/test_text_file.py delete mode 100644 Lib/distutils/tests/test_unixccompiler.py delete mode 100644 Lib/distutils/tests/test_upload.py delete mode 100644 Lib/distutils/tests/test_util.py delete mode 100644 Lib/distutils/tests/test_version.py delete mode 100644 Lib/distutils/tests/test_versionpredicate.py delete mode 100644 Lib/distutils/text_file.py delete mode 100644 Lib/distutils/unixccompiler.py delete mode 100644 Lib/distutils/util.py delete mode 100644 Lib/distutils/version.py delete mode 100644 Lib/distutils/versionpredicate.py rename Lib/ensurepip/_bundled/{pip-22.3.1-py3-none-any.whl => pip-23.2.1-py3-none-any.whl} (54%) delete mode 100644 Lib/ensurepip/_bundled/setuptools-65.5.0-py3-none-any.whl delete mode 100644 Lib/imp.py create mode 100644 Lib/sqlite3/__main__.py create mode 100644 Lib/test/.ruff.toml create mode 100644 Lib/test/audiodata/pluck-pcm24-ext.wav rename Lib/test/{clinic.test => clinic.test.c} (69%) create mode 100644 Lib/test/levenshtein_examples.json create mode 100644 Lib/test/setuptools-67.6.1-py3-none-any.whl create mode 100644 Lib/test/shadowed_super.py rename Lib/{ => test}/smtpd.py (98%) create mode 100644 Lib/test/support/_hypothesis_stubs/__init__.py create mode 100644 Lib/test/support/_hypothesis_stubs/_helpers.py create mode 100644 Lib/test/support/_hypothesis_stubs/strategies.py create mode 100644 Lib/test/support/ast_helper.py rename Lib/{ => test/support}/asynchat.py (97%) rename Lib/{ => test/support}/asyncore.py (98%) create mode 100644 Lib/test/support/hypothesis_helper.py create mode 100644 Lib/test/support/testcase.py create mode 100644 Lib/test/test__xxinterpchannels.py delete mode 100644 Lib/test/test_asynchat.py create mode 100644 Lib/test/test_asyncio/test_eager_task_factory.py delete mode 100644 Lib/test/test_asyncore.py create mode 100644 Lib/test/test_capi/check_config.py create mode 100644 Lib/test/test_capi/test_abstract.py create mode 100644 Lib/test/test_capi/test_codecs.py create mode 100644 Lib/test/test_capi/test_dict.py create mode 100644 Lib/test/test_capi/test_exceptions.py create mode 100644 Lib/test/test_capi/test_immortal.py create mode 100644 Lib/test/test_capi/test_long.py create mode 100644 Lib/test/test_capi/test_mem.py create mode 100644 Lib/test/test_capi/test_watchers.py delete mode 100644 Lib/test/test_check_c_globals.py create mode 100644 Lib/test/test_compiler_assemble.py create mode 100644 Lib/test/test_compiler_codegen.py delete mode 100644 Lib/test/test_concurrent_futures.py create mode 100644 Lib/test/test_concurrent_futures/__init__.py create mode 100644 Lib/test/test_concurrent_futures/executor.py create mode 100644 Lib/test/test_concurrent_futures/test_as_completed.py create mode 100644 Lib/test/test_concurrent_futures/test_deadlock.py create mode 100644 Lib/test/test_concurrent_futures/test_future.py create mode 100644 Lib/test/test_concurrent_futures/test_init.py create mode 100644 Lib/test/test_concurrent_futures/test_process_pool.py create mode 100644 Lib/test/test_concurrent_futures/test_shutdown.py create mode 100644 Lib/test/test_concurrent_futures/test_thread_pool.py create mode 100644 Lib/test/test_concurrent_futures/test_wait.py create mode 100644 Lib/test/test_concurrent_futures/util.py rename Lib/test/{test_cppext.py => test_cppext/__init__.py} (63%) rename Lib/test/{_testcppext.cpp => test_cppext/extension.cpp} (98%) rename Lib/test/{setup_testcppext.py => test_cppext/setup.py} (59%) delete mode 100644 Lib/test/test_ctypes.py rename Lib/{ctypes/test => test/test_ctypes}/__init__.py (100%) create mode 100644 Lib/test/test_ctypes/__main__.py rename Lib/{ctypes/test => test/test_ctypes}/test_anon.py (100%) rename Lib/{ctypes/test => test/test_ctypes}/test_array_in_pointer.py (100%) rename Lib/{ctypes/test => test/test_ctypes}/test_arrays.py (99%) rename Lib/{ctypes/test => test/test_ctypes}/test_as_parameter.py (98%) rename Lib/{ctypes/test => test/test_ctypes}/test_bitfields.py (99%) rename Lib/{ctypes/test => test/test_ctypes}/test_buffers.py (98%) rename Lib/{ctypes/test => test/test_ctypes}/test_bytes.py (100%) rename Lib/{ctypes/test => test/test_ctypes}/test_byteswap.py (98%) rename Lib/{ctypes/test => test/test_ctypes}/test_callbacks.py (95%) rename Lib/{ctypes/test => test/test_ctypes}/test_cast.py (98%) rename Lib/{ctypes/test => test/test_ctypes}/test_cfuncs.py (99%) rename Lib/{ctypes/test => test/test_ctypes}/test_checkretval.py (95%) rename Lib/{ctypes/test => test/test_ctypes}/test_delattr.py (100%) rename Lib/{ctypes/test => test/test_ctypes}/test_errno.py (100%) rename Lib/{ctypes/test => test/test_ctypes}/test_find.py (100%) rename Lib/{ctypes/test => test/test_ctypes}/test_frombuffer.py (100%) rename Lib/{ctypes/test => test/test_ctypes}/test_funcptr.py (100%) rename Lib/{ctypes/test => test/test_ctypes}/test_functions.py (91%) rename Lib/{ctypes/test => test/test_ctypes}/test_incomplete.py (100%) rename Lib/{ctypes/test => test/test_ctypes}/test_init.py (100%) rename Lib/{ctypes/test => test/test_ctypes}/test_internals.py (100%) rename Lib/{ctypes/test => test/test_ctypes}/test_keeprefs.py (80%) rename Lib/{ctypes/test => test/test_ctypes}/test_libc.py (100%) rename Lib/{ctypes/test => test/test_ctypes}/test_loading.py (89%) rename Lib/{ctypes/test => test/test_ctypes}/test_macholib.py (100%) rename Lib/{ctypes/test => test/test_ctypes}/test_memfunctions.py (98%) rename Lib/{ctypes/test => test/test_ctypes}/test_numbers.py (75%) rename Lib/{ctypes/test => test/test_ctypes}/test_objects.py (87%) rename Lib/{ctypes/test => test/test_ctypes}/test_parameters.py (92%) rename Lib/{ctypes/test => test/test_ctypes}/test_pep3118.py (84%) rename Lib/{ctypes/test => test/test_ctypes}/test_pickling.py (100%) rename Lib/{ctypes/test => test/test_ctypes}/test_pointers.py (100%) rename Lib/{ctypes/test => test/test_ctypes}/test_prototypes.py (99%) rename Lib/{ctypes/test => test/test_ctypes}/test_python_api.py (97%) rename Lib/{ctypes/test => test/test_ctypes}/test_random_things.py (100%) rename Lib/{ctypes/test => test/test_ctypes}/test_refcounts.py (100%) rename Lib/{ctypes/test => test/test_ctypes}/test_repr.py (100%) rename Lib/{ctypes/test => test/test_ctypes}/test_returnfuncptrs.py (100%) rename Lib/{ctypes/test => test/test_ctypes}/test_simplesubclasses.py (100%) rename Lib/{ctypes/test => test/test_ctypes}/test_sizes.py (90%) rename Lib/{ctypes/test => test/test_ctypes}/test_slicing.py (99%) rename Lib/{ctypes/test => test/test_ctypes}/test_stringptr.py (100%) rename Lib/{ctypes/test => test/test_ctypes}/test_strings.py (99%) rename Lib/{ctypes/test => test/test_ctypes}/test_struct_fields.py (100%) rename Lib/{ctypes/test => test/test_ctypes}/test_structures.py (98%) rename Lib/{ctypes/test => test/test_ctypes}/test_unaligned_structures.py (100%) rename Lib/{ctypes/test => test/test_ctypes}/test_unicode.py (97%) rename Lib/{ctypes/test => test/test_ctypes}/test_values.py (100%) rename Lib/{ctypes/test => test/test_ctypes}/test_varsize_struct.py (100%) rename Lib/{ctypes/test => test/test_ctypes}/test_win32.py (100%) rename Lib/{ctypes/test => test/test_ctypes}/test_wintypes.py (67%) delete mode 100644 Lib/test/test_distutils.py create mode 100644 Lib/test/test_email/data/msg_47.txt delete mode 100644 Lib/test/test_imp.py create mode 100644 Lib/test/test_importlib/_context.py create mode 100644 Lib/test/test_importlib/_path.py create mode 100644 Lib/test/test_importlib/import_/test_helpers.py create mode 100644 Lib/test/test_importlib/resources/_path.py rename Lib/{lib2to3/tests/data/fixers/myfixes => test/test_importlib/resources/data01}/__init__.py (100%) rename Lib/test/test_importlib/{ => resources}/data01/binary.file (100%) rename Lib/test/test_importlib/{data01 => resources/data01/subdirectory}/__init__.py (100%) rename Lib/test/test_importlib/{ => resources}/data01/subdirectory/binary.file (100%) rename Lib/test/test_importlib/{ => resources}/data01/utf-16.file (100%) rename Lib/test/test_importlib/{ => resources}/data01/utf-8.file (100%) rename Lib/test/test_importlib/{data01/subdirectory => resources/data02}/__init__.py (100%) rename Lib/test/test_importlib/{data02 => resources/data02/one}/__init__.py (100%) rename Lib/test/test_importlib/{ => resources}/data02/one/resource1.txt (100%) create mode 100644 Lib/test/test_importlib/resources/data02/subdirectory/subsubdir/resource.txt rename Lib/test/test_importlib/{data02/one => resources/data02/two}/__init__.py (100%) rename Lib/test/test_importlib/{ => resources}/data02/two/resource2.txt (100%) rename Lib/test/test_importlib/{data02/two => resources/data03}/__init__.py (100%) rename Lib/test/test_importlib/{data03 => resources/data03/namespace/portion1}/__init__.py (100%) rename Lib/test/test_importlib/{data03/namespace/portion1 => resources/data03/namespace/portion2}/__init__.py (100%) rename Lib/test/test_importlib/{ => resources}/data03/namespace/resource1.txt (100%) rename Lib/test/test_importlib/{ => resources}/namespacedata01/binary.file (100%) rename Lib/test/test_importlib/{ => resources}/namespacedata01/utf-16.file (100%) rename Lib/test/test_importlib/{ => resources}/namespacedata01/utf-8.file (100%) rename Lib/test/test_importlib/{ => resources}/test_compatibilty_files.py (93%) rename Lib/test/test_importlib/{ => resources}/test_contents.py (97%) create mode 100644 Lib/test/test_importlib/resources/test_custom.py create mode 100644 Lib/test/test_importlib/resources/test_files.py rename Lib/test/test_importlib/{ => resources}/test_open.py (86%) rename Lib/test/test_importlib/{ => resources}/test_path.py (84%) rename Lib/test/test_importlib/{ => resources}/test_read.py (86%) rename Lib/test/test_importlib/{ => resources}/test_reader.py (85%) rename Lib/test/test_importlib/{ => resources}/test_resource.py (74%) rename Lib/test/test_importlib/{ => resources}/update-zips.py (100%) rename Lib/test/test_importlib/{data03/namespace/portion2 => resources/zipdata01}/__init__.py (100%) rename Lib/test/test_importlib/{ => resources}/zipdata01/ziptestdata.zip (100%) rename Lib/test/test_importlib/{zipdata01 => resources/zipdata02}/__init__.py (100%) rename Lib/test/test_importlib/{ => resources}/zipdata02/ziptestdata.zip (100%) delete mode 100644 Lib/test/test_importlib/test_files.py delete mode 100644 Lib/test/test_lib2to3.py rename Lib/{lib2to3/tests => test/test_lib2to3}/__init__.py (100%) rename Lib/{lib2to3/tests => test/test_lib2to3}/__main__.py (100%) rename Lib/{lib2to3/tests => test/test_lib2to3}/data/README (100%) rename Lib/{lib2to3/tests => test/test_lib2to3}/data/bom.py (100%) rename Lib/{lib2to3/tests => test/test_lib2to3}/data/crlf.py (100%) rename Lib/{lib2to3/tests => test/test_lib2to3}/data/different_encoding.py (100%) rename Lib/{lib2to3/tests => test/test_lib2to3}/data/false_encoding.py (100%) rename Lib/{lib2to3/tests => test/test_lib2to3}/data/fixers/bad_order.py (100%) rename Lib/test/{test_importlib/zipdata02 => test_lib2to3/data/fixers/myfixes}/__init__.py (100%) rename Lib/{lib2to3/tests => test/test_lib2to3}/data/fixers/myfixes/fix_explicit.py (100%) rename Lib/{lib2to3/tests => test/test_lib2to3}/data/fixers/myfixes/fix_first.py (100%) rename Lib/{lib2to3/tests => test/test_lib2to3}/data/fixers/myfixes/fix_last.py (100%) rename Lib/{lib2to3/tests => test/test_lib2to3}/data/fixers/myfixes/fix_parrot.py (100%) rename Lib/{lib2to3/tests => test/test_lib2to3}/data/fixers/myfixes/fix_preorder.py (100%) rename Lib/{lib2to3/tests => test/test_lib2to3}/data/fixers/no_fixer_cls.py (100%) rename Lib/{lib2to3/tests => test/test_lib2to3}/data/fixers/parrot_example.py (100%) rename Lib/{lib2to3/tests => test/test_lib2to3}/data/infinite_recursion.py (100%) rename Lib/{lib2to3/tests => test/test_lib2to3}/data/py2_test_grammar.py (99%) rename Lib/{lib2to3/tests => test/test_lib2to3}/data/py3_test_grammar.py (99%) rename Lib/{lib2to3/tests => test/test_lib2to3}/pytree_idempotency.py (96%) rename Lib/{lib2to3/tests => test/test_lib2to3}/support.py (77%) rename Lib/{lib2to3/tests => test/test_lib2to3}/test_all_fixers.py (99%) rename Lib/{lib2to3/tests => test/test_lib2to3}/test_fixers.py (99%) rename Lib/{lib2to3/tests => test/test_lib2to3}/test_main.py (100%) rename Lib/{lib2to3/tests => test/test_lib2to3}/test_parser.py (99%) rename Lib/{lib2to3/tests => test/test_lib2to3}/test_pytree.py (100%) rename Lib/{lib2to3/tests => test/test_lib2to3}/test_refactor.py (100%) rename Lib/{lib2to3/tests => test/test_lib2to3}/test_util.py (100%) create mode 100644 Lib/test/test_math_property.py rename Lib/test/{test_module.py => test_module/__init__.py} (91%) rename Lib/test/{ => test_module}/bad_getattr.py (100%) rename Lib/test/{ => test_module}/bad_getattr2.py (100%) rename Lib/test/{ => test_module}/bad_getattr3.py (100%) rename Lib/test/{ => test_module}/good_getattr.py (100%) create mode 100644 Lib/test/test_monitoring.py rename Lib/test/{test_multiprocessing_fork.py => test_multiprocessing_fork/__init__.py} (66%) create mode 100644 Lib/test/test_multiprocessing_fork/test_manager.py create mode 100644 Lib/test/test_multiprocessing_fork/test_misc.py create mode 100644 Lib/test/test_multiprocessing_fork/test_processes.py create mode 100644 Lib/test/test_multiprocessing_fork/test_threads.py rename Lib/test/{test_multiprocessing_forkserver.py => test_multiprocessing_forkserver/__init__.py} (58%) create mode 100644 Lib/test/test_multiprocessing_forkserver/test_manager.py create mode 100644 Lib/test/test_multiprocessing_forkserver/test_misc.py create mode 100644 Lib/test/test_multiprocessing_forkserver/test_processes.py create mode 100644 Lib/test/test_multiprocessing_forkserver/test_threads.py delete mode 100644 Lib/test/test_multiprocessing_spawn.py create mode 100644 Lib/test/test_multiprocessing_spawn/__init__.py create mode 100644 Lib/test/test_multiprocessing_spawn/test_manager.py create mode 100644 Lib/test/test_multiprocessing_spawn/test_misc.py create mode 100644 Lib/test/test_multiprocessing_spawn/test_processes.py create mode 100644 Lib/test/test_multiprocessing_spawn/test_threads.py create mode 100644 Lib/test/test_perf_profiler.py create mode 100644 Lib/test/test_perfmaps.py delete mode 100644 Lib/test/test_smtpd.py create mode 100644 Lib/test/test_sqlite3/test_cli.py delete mode 100644 Lib/test/test_tk.py rename Lib/{tkinter/test => test/test_tkinter}/README (100%) create mode 100644 Lib/test/test_tkinter/__init__.py create mode 100644 Lib/test/test_tkinter/__main__.py rename Lib/{tkinter/test => test/test_tkinter}/support.py (89%) rename Lib/{tkinter => }/test/test_tkinter/test_colorchooser.py (96%) rename Lib/{tkinter => }/test/test_tkinter/test_font.py (98%) rename Lib/{tkinter => }/test/test_tkinter/test_geometry_managers.py (99%) rename Lib/{tkinter => }/test/test_tkinter/test_images.py (94%) rename Lib/{tkinter => }/test/test_tkinter/test_loadtk.py (100%) rename Lib/{tkinter => }/test/test_tkinter/test_messagebox.py (94%) rename Lib/{tkinter => }/test/test_tkinter/test_misc.py (99%) rename Lib/{tkinter => }/test/test_tkinter/test_simpledialog.py (93%) rename Lib/{tkinter => }/test/test_tkinter/test_text.py (98%) rename Lib/{tkinter => }/test/test_tkinter/test_variables.py (99%) rename Lib/{tkinter => }/test/test_tkinter/test_widgets.py (98%) rename Lib/{tkinter/test => test/test_tkinter}/widget_tests.py (99%) delete mode 100644 Lib/test/test_tools/test_fixcid.py delete mode 100644 Lib/test/test_tools/test_gprof2html.py delete mode 100644 Lib/test/test_tools/test_lll.py delete mode 100644 Lib/test/test_tools/test_md5sum.py delete mode 100644 Lib/test/test_tools/test_pathfix.py delete mode 100644 Lib/test/test_tools/test_pdeps.py delete mode 100644 Lib/test/test_tools/test_pindent.py rename Lib/test/{test_ttk_guionly.py => test_ttk/__init__.py} (68%) create mode 100644 Lib/test/test_ttk/__main__.py rename Lib/{tkinter => }/test/test_ttk/test_extensions.py (98%) rename Lib/{tkinter => }/test/test_ttk/test_style.py (98%) rename Lib/{tkinter => }/test/test_ttk/test_widgets.py (99%) create mode 100644 Lib/test/test_type_aliases.py create mode 100644 Lib/test/test_type_params.py delete mode 100644 Lib/test/test_unittest.py create mode 100644 Lib/test/test_unittest/__init__.py create mode 100644 Lib/test/test_unittest/__main__.py rename Lib/{unittest/test => test/test_unittest}/_test_warnings.py (84%) rename Lib/{unittest/test => test/test_unittest}/dummy.py (100%) rename Lib/{unittest/test => test/test_unittest}/support.py (92%) rename Lib/{unittest/test => test/test_unittest}/test_assertions.py (96%) rename Lib/{unittest/test => test/test_unittest}/test_async_case.py (100%) rename Lib/{unittest/test => test/test_unittest}/test_break.py (98%) rename Lib/{unittest/test => test/test_unittest}/test_case.py (96%) rename Lib/{unittest/test => test/test_unittest}/test_discovery.py (99%) rename Lib/{unittest/test => test/test_unittest}/test_functiontestcase.py (99%) rename Lib/{unittest/test => test/test_unittest}/test_loader.py (90%) rename Lib/{unittest/test => test/test_unittest}/test_program.py (83%) rename Lib/{unittest/test => test/test_unittest}/test_result.py (98%) rename Lib/{unittest/test => test/test_unittest}/test_runner.py (89%) rename Lib/{unittest/test => test/test_unittest}/test_setups.py (100%) rename Lib/{unittest/test => test/test_unittest}/test_skipping.py (99%) rename Lib/{unittest/test => test/test_unittest}/test_suite.py (99%) create mode 100644 Lib/test/test_unittest/testmock/__init__.py rename Lib/{unittest/test => test/test_unittest}/testmock/__main__.py (86%) rename Lib/{unittest/test => test/test_unittest}/testmock/support.py (100%) rename Lib/{unittest/test => test/test_unittest}/testmock/testasync.py (98%) rename Lib/{unittest/test => test/test_unittest}/testmock/testcallable.py (98%) rename Lib/{unittest/test => test/test_unittest}/testmock/testhelpers.py (96%) rename Lib/{unittest/test => test/test_unittest}/testmock/testmagicmethods.py (100%) rename Lib/{unittest/test => test/test_unittest}/testmock/testmock.py (99%) rename Lib/{unittest/test => test/test_unittest}/testmock/testpatch.py (96%) rename Lib/{unittest/test => test/test_unittest}/testmock/testsealable.py (96%) rename Lib/{unittest/test => test/test_unittest}/testmock/testsentinel.py (100%) rename Lib/{unittest/test => test/test_unittest}/testmock/testwith.py (99%) create mode 100644 Lib/test/test_warnings/data/package_helper.py create mode 100644 Lib/test/test_wmi.py create mode 100644 Lib/test/test_zipfile/__init__.py create mode 100644 Lib/test/test_zipfile/__main__.py rename Lib/{tkinter/test => test/test_zipfile/_path}/__init__.py (100%) create mode 100644 Lib/test/test_zipfile/_path/_functools.py create mode 100644 Lib/test/test_zipfile/_path/_itertools.py create mode 100644 Lib/test/test_zipfile/_path/_support.py create mode 100644 Lib/test/test_zipfile/_path/_test_params.py create mode 100644 Lib/test/test_zipfile/_path/test_complexity.py create mode 100644 Lib/test/test_zipfile/_path/test_path.py create mode 100644 Lib/test/test_zipfile/_path/write-alpharep.py rename Lib/test/{test_zipfile.py => test_zipfile/test_core.py} (88%) create mode 100644 Lib/test/test_zoneinfo/test_zoneinfo_property.py create mode 100644 Lib/test/wheel-0.40.0-py3-none-any.whl delete mode 100644 Lib/tkinter/test/test_ttk/__init__.py delete mode 100644 Lib/unittest/test/__init__.py delete mode 100644 Lib/unittest/test/__main__.py delete mode 100644 Lib/unittest/test/testmock/__init__.py mode change 100755 => 100644 Lib/uu.py rename Lib/{zipfile.py => zipfile/__init__.py} (85%) create mode 100644 Lib/zipfile/__main__.py create mode 100644 Lib/zipfile/_path/__init__.py create mode 100644 Lib/zipfile/_path/glob.py delete mode 100644 Misc/NEWS create mode 100644 Misc/NEWS.d/3.10.0a1.rst create mode 100644 Misc/NEWS.d/3.10.0a2.rst create mode 100644 Misc/NEWS.d/3.10.0a3.rst create mode 100644 Misc/NEWS.d/3.10.0a4.rst create mode 100644 Misc/NEWS.d/3.10.0a5.rst create mode 100644 Misc/NEWS.d/3.10.0a6.rst create mode 100644 Misc/NEWS.d/3.10.0a7.rst create mode 100644 Misc/NEWS.d/3.10.0b1.rst create mode 100644 Misc/NEWS.d/3.11.0a1.rst create mode 100644 Misc/NEWS.d/3.11.0a2.rst create mode 100644 Misc/NEWS.d/3.11.0a3.rst create mode 100644 Misc/NEWS.d/3.11.0a4.rst create mode 100644 Misc/NEWS.d/3.11.0a5.rst create mode 100644 Misc/NEWS.d/3.11.0a6.rst create mode 100644 Misc/NEWS.d/3.11.0a7.rst create mode 100644 Misc/NEWS.d/3.11.0b1.rst create mode 100644 Misc/NEWS.d/3.12.0.rst create mode 100644 Misc/NEWS.d/3.12.0a1.rst create mode 100644 Misc/NEWS.d/3.12.0a2.rst create mode 100644 Misc/NEWS.d/3.12.0a3.rst create mode 100644 Misc/NEWS.d/3.12.0a4.rst create mode 100644 Misc/NEWS.d/3.12.0a5.rst create mode 100644 Misc/NEWS.d/3.12.0a6.rst create mode 100644 Misc/NEWS.d/3.12.0a7.rst create mode 100644 Misc/NEWS.d/3.12.0b1.rst create mode 100644 Misc/NEWS.d/3.12.0b2.rst create mode 100644 Misc/NEWS.d/3.12.0b3.rst create mode 100644 Misc/NEWS.d/3.12.0b4.rst create mode 100644 Misc/NEWS.d/3.12.0rc1.rst create mode 100644 Misc/NEWS.d/3.12.0rc2.rst create mode 100644 Misc/NEWS.d/3.12.0rc3.rst create mode 100644 Misc/NEWS.d/3.5.0.rst create mode 100644 Misc/NEWS.d/3.5.0a1.rst create mode 100644 Misc/NEWS.d/3.5.0a2.rst create mode 100644 Misc/NEWS.d/3.5.0a3.rst create mode 100644 Misc/NEWS.d/3.5.0a4.rst create mode 100644 Misc/NEWS.d/3.5.0b1.rst create mode 100644 Misc/NEWS.d/3.5.0b2.rst create mode 100644 Misc/NEWS.d/3.5.0b3.rst create mode 100644 Misc/NEWS.d/3.5.0b4.rst create mode 100644 Misc/NEWS.d/3.5.0rc1.rst create mode 100644 Misc/NEWS.d/3.5.0rc2.rst create mode 100644 Misc/NEWS.d/3.5.0rc3.rst create mode 100644 Misc/NEWS.d/3.5.0rc4.rst create mode 100644 Misc/NEWS.d/3.5.1.rst create mode 100644 Misc/NEWS.d/3.5.1rc1.rst create mode 100644 Misc/NEWS.d/3.5.2.rst create mode 100644 Misc/NEWS.d/3.5.2rc1.rst create mode 100644 Misc/NEWS.d/3.5.3.rst create mode 100644 Misc/NEWS.d/3.5.3rc1.rst create mode 100644 Misc/NEWS.d/3.5.4.rst create mode 100644 Misc/NEWS.d/3.5.4rc1.rst create mode 100644 Misc/NEWS.d/3.5.5.rst create mode 100644 Misc/NEWS.d/3.5.5rc1.rst create mode 100644 Misc/NEWS.d/3.6.0.rst create mode 100644 Misc/NEWS.d/3.6.0a1.rst create mode 100644 Misc/NEWS.d/3.6.0a2.rst create mode 100644 Misc/NEWS.d/3.6.0a3.rst create mode 100644 Misc/NEWS.d/3.6.0a4.rst create mode 100644 Misc/NEWS.d/3.6.0b1.rst create mode 100644 Misc/NEWS.d/3.6.0b2.rst create mode 100644 Misc/NEWS.d/3.6.0b3.rst create mode 100644 Misc/NEWS.d/3.6.0b4.rst create mode 100644 Misc/NEWS.d/3.6.0rc1.rst create mode 100644 Misc/NEWS.d/3.6.0rc2.rst create mode 100644 Misc/NEWS.d/3.6.1.rst create mode 100644 Misc/NEWS.d/3.6.1rc1.rst create mode 100644 Misc/NEWS.d/3.6.2.rst create mode 100644 Misc/NEWS.d/3.6.2rc1.rst create mode 100644 Misc/NEWS.d/3.6.2rc2.rst create mode 100644 Misc/NEWS.d/3.6.3.rst create mode 100644 Misc/NEWS.d/3.6.3rc1.rst create mode 100644 Misc/NEWS.d/3.6.4.rst create mode 100644 Misc/NEWS.d/3.6.4rc1.rst create mode 100644 Misc/NEWS.d/3.6.5.rst create mode 100644 Misc/NEWS.d/3.6.5rc1.rst create mode 100644 Misc/NEWS.d/3.6.6.rst create mode 100644 Misc/NEWS.d/3.6.6rc1.rst create mode 100644 Misc/NEWS.d/3.7.0.rst create mode 100644 Misc/NEWS.d/3.7.0a1.rst create mode 100644 Misc/NEWS.d/3.7.0a2.rst create mode 100644 Misc/NEWS.d/3.7.0a3.rst create mode 100644 Misc/NEWS.d/3.7.0a4.rst create mode 100644 Misc/NEWS.d/3.7.0b1.rst create mode 100644 Misc/NEWS.d/3.7.0b2.rst create mode 100644 Misc/NEWS.d/3.7.0b3.rst create mode 100644 Misc/NEWS.d/3.7.0b4.rst create mode 100644 Misc/NEWS.d/3.7.0b5.rst create mode 100644 Misc/NEWS.d/3.7.0rc1.rst create mode 100644 Misc/NEWS.d/3.8.0a1.rst create mode 100644 Misc/NEWS.d/3.8.0a2.rst create mode 100644 Misc/NEWS.d/3.8.0a3.rst create mode 100644 Misc/NEWS.d/3.8.0a4.rst create mode 100644 Misc/NEWS.d/3.8.0b1.rst create mode 100644 Misc/NEWS.d/3.9.0a1.rst create mode 100644 Misc/NEWS.d/3.9.0a2.rst create mode 100644 Misc/NEWS.d/3.9.0a3.rst create mode 100644 Misc/NEWS.d/3.9.0a4.rst create mode 100644 Misc/NEWS.d/3.9.0a5.rst create mode 100644 Misc/NEWS.d/3.9.0a6.rst create mode 100644 Misc/NEWS.d/3.9.0b1.rst create mode 100644 Misc/NEWS.d/next/Build/README.rst create mode 100644 Misc/NEWS.d/next/C API/README.rst create mode 100644 Misc/NEWS.d/next/Core and Builtins/README.rst create mode 100644 Misc/NEWS.d/next/Documentation/README.rst create mode 100644 Misc/NEWS.d/next/IDLE/README.rst create mode 100644 Misc/NEWS.d/next/Library/README.rst create mode 100644 Misc/NEWS.d/next/Security/README.rst create mode 100644 Misc/NEWS.d/next/Tests/README.rst create mode 100644 Misc/NEWS.d/next/Tools-Demos/README.rst create mode 100644 Misc/NEWS.d/next/Windows/README.rst create mode 100644 Misc/NEWS.d/next/macOS/README.rst delete mode 100644 Misc/gdbinit delete mode 100644 Modules/_ctypes/ctypes_dlfcn.h delete mode 100644 Modules/_ctypes/darwin/LICENSE delete mode 100644 Modules/_ctypes/darwin/README delete mode 100644 Modules/_ctypes/darwin/README.ctypes delete mode 100644 Modules/_ctypes/darwin/dlfcn.h delete mode 100644 Modules/_ctypes/darwin/dlfcn_simple.c delete mode 100644 Modules/_ctypes/libffi_osx/LICENSE delete mode 100644 Modules/_ctypes/libffi_osx/README delete mode 100644 Modules/_ctypes/libffi_osx/README.pyobjc delete mode 100644 Modules/_ctypes/libffi_osx/ffi.c delete mode 100644 Modules/_ctypes/libffi_osx/include/ffi.h delete mode 100644 Modules/_ctypes/libffi_osx/include/ffi_common.h delete mode 100644 Modules/_ctypes/libffi_osx/include/fficonfig.h delete mode 100644 Modules/_ctypes/libffi_osx/include/ffitarget.h delete mode 100644 Modules/_ctypes/libffi_osx/include/ppc-ffitarget.h delete mode 100644 Modules/_ctypes/libffi_osx/include/x86-ffitarget.h delete mode 100644 Modules/_ctypes/libffi_osx/powerpc/ppc-darwin.S delete mode 100644 Modules/_ctypes/libffi_osx/powerpc/ppc-darwin.h delete mode 100644 Modules/_ctypes/libffi_osx/powerpc/ppc-darwin_closure.S delete mode 100644 Modules/_ctypes/libffi_osx/powerpc/ppc-ffi_darwin.c delete mode 100644 Modules/_ctypes/libffi_osx/powerpc/ppc64-darwin_closure.S delete mode 100644 Modules/_ctypes/libffi_osx/types.c delete mode 100644 Modules/_ctypes/libffi_osx/x86/darwin64.S delete mode 100644 Modules/_ctypes/libffi_osx/x86/x86-darwin.S delete mode 100644 Modules/_ctypes/libffi_osx/x86/x86-ffi64.c delete mode 100644 Modules/_ctypes/libffi_osx/x86/x86-ffi_darwin.c create mode 100644 Modules/_hacl/Hacl_Hash_MD5.c create mode 100644 Modules/_hacl/Hacl_Hash_MD5.h create mode 100644 Modules/_hacl/Hacl_Hash_SHA1.c create mode 100644 Modules/_hacl/Hacl_Hash_SHA1.h create mode 100644 Modules/_hacl/Hacl_Hash_SHA2.c create mode 100644 Modules/_hacl/Hacl_Hash_SHA2.h create mode 100644 Modules/_hacl/Hacl_Hash_SHA3.c create mode 100644 Modules/_hacl/Hacl_Hash_SHA3.h create mode 100644 Modules/_hacl/Hacl_Streaming_Types.h create mode 100644 Modules/_hacl/README.md create mode 100644 Modules/_hacl/include/krml/FStar_UInt128_Verified.h create mode 100644 Modules/_hacl/include/krml/FStar_UInt_8_16_32_64.h create mode 100644 Modules/_hacl/include/krml/fstar_uint128_struct_endianness.h create mode 100644 Modules/_hacl/include/krml/internal/target.h create mode 100644 Modules/_hacl/include/krml/lowstar_endianness.h create mode 100644 Modules/_hacl/include/krml/types.h create mode 100644 Modules/_hacl/internal/Hacl_Hash_MD5.h create mode 100644 Modules/_hacl/internal/Hacl_Hash_SHA1.h create mode 100644 Modules/_hacl/internal/Hacl_Hash_SHA2.h create mode 100644 Modules/_hacl/internal/Hacl_Hash_SHA3.h create mode 100644 Modules/_hacl/python_hacl_namespaces.h create mode 100755 Modules/_hacl/refresh.sh delete mode 100644 Modules/_sha3/LICENSE delete mode 100644 Modules/_sha3/README.txt delete mode 100644 Modules/_sha3/sha3.c delete mode 100644 Modules/_sha3/sha3.h create mode 100644 Modules/_ssl_data_31.h create mode 100644 Modules/_testcapi/README.txt create mode 100644 Modules/_testcapi/abstract.c create mode 100644 Modules/_testcapi/buffer.c create mode 100644 Modules/_testcapi/clinic/exceptions.c.h create mode 100644 Modules/_testcapi/clinic/float.c.h create mode 100644 Modules/_testcapi/clinic/vectorcall.c.h create mode 100644 Modules/_testcapi/clinic/watchers.c.h create mode 100644 Modules/_testcapi/code.c create mode 100644 Modules/_testcapi/datetime.c create mode 100644 Modules/_testcapi/dict.c create mode 100644 Modules/_testcapi/docstring.c create mode 100644 Modules/_testcapi/exceptions.c create mode 100644 Modules/_testcapi/float.c create mode 100644 Modules/_testcapi/gc.c create mode 100644 Modules/_testcapi/getargs.c create mode 100644 Modules/_testcapi/heaptype.c create mode 100644 Modules/_testcapi/heaptype_relative.c create mode 100644 Modules/_testcapi/immortal.c create mode 100644 Modules/_testcapi/long.c create mode 100644 Modules/_testcapi/mem.c create mode 100644 Modules/_testcapi/parts.h create mode 100644 Modules/_testcapi/pyos.c create mode 100644 Modules/_testcapi/pytime.c create mode 100644 Modules/_testcapi/structmember.c rename Modules/{ => _testcapi}/testcapi_long.h (99%) create mode 100644 Modules/_testcapi/unicode.c create mode 100644 Modules/_testcapi/util.h create mode 100644 Modules/_testcapi/vectorcall.c create mode 100644 Modules/_testcapi/vectorcall_limited.c create mode 100644 Modules/_testcapi/watchers.c create mode 100644 Modules/_testsinglephase.c create mode 100644 Modules/_xxinterpchannelsmodule.c create mode 100644 Modules/clinic/_functoolsmodule.c.h create mode 100644 Modules/clinic/_posixsubprocess.c.h create mode 100644 Modules/clinic/_testinternalcapi.c.h create mode 100644 Modules/clinic/_zoneinfo.c.h delete mode 100644 Modules/clinic/sha256module.c.h create mode 100644 Modules/clinic/sha2module.c.h rename Modules/{_sha3 => }/clinic/sha3module.c.h (82%) delete mode 100644 Modules/clinic/sha512module.c.h create mode 100644 Modules/clinic/syslogmodule.c.h delete mode 100644 Modules/sha256module.c create mode 100644 Modules/sha2module.c rename Modules/{_sha3 => }/sha3module.c (77%) delete mode 100644 Modules/sha512module.c delete mode 100644 Objects/accu.c create mode 100644 Objects/clinic/typevarobject.c.h create mode 100644 Objects/object_layout.md create mode 100644 Objects/object_layout_312.gv create mode 100644 Objects/object_layout_312.png create mode 100644 Objects/object_layout_full_312.gv create mode 100644 Objects/object_layout_full_312.png delete mode 100644 Objects/stringlib/unicodedefs.h create mode 100644 Objects/typevarobject.c create mode 100644 PC/_wmimodule.cpp create mode 100644 PC/clinic/_wmimodule.cpp.h delete mode 100644 PC/empty.c delete mode 100644 PC/testpy.py create mode 100644 PCbuild/_testclinic.vcxproj create mode 100644 PCbuild/_testclinic.vcxproj.filters create mode 100644 PCbuild/_testsinglephase.vcxproj create mode 100644 PCbuild/_testsinglephase.vcxproj.filters create mode 100644 PCbuild/_wmi.vcxproj create mode 100644 PCbuild/_wmi.vcxproj.filters delete mode 100644 PCbuild/lib.pyproj create mode 100644 Python/asm_trampoline.S create mode 100644 Python/assemble.c create mode 100644 Python/bytecodes.c create mode 100644 Python/ceval_gil.c delete mode 100644 Python/ceval_gil.h create mode 100644 Python/ceval_macros.h create mode 100644 Python/clinic/instrumentation.c.h create mode 100644 Python/flowgraph.c create mode 100644 Python/generated_cases.c.h create mode 100644 Python/instrumentation.c create mode 100644 Python/intrinsics.c create mode 100644 Python/legacy_tracing.c create mode 100644 Python/opcode_metadata.h create mode 100644 Python/perf_trampoline.c create mode 100644 Python/tracemalloc.c create mode 100644 Tools/build/check_extension_modules.py rename Tools/{scripts => build}/deepfreeze.py (88%) rename Tools/{scripts => build}/freeze_modules.py (98%) rename Tools/{scripts => build}/generate_global_objects.py (56%) create mode 100644 Tools/build/generate_levenshtein_examples.py rename Tools/{scripts => build}/generate_opcode_h.py (54%) rename Tools/{scripts => build}/generate_re_casefix.py (95%) rename Tools/{scripts => build}/generate_sre_constants.py (94%) rename Tools/{scripts => build}/generate_stdlib_module_names.py (66%) rename Tools/{scripts => build}/generate_token.py (85%) rename Tools/{scripts => build}/parse_html5_entities.py (79%) rename Tools/{scripts => build}/smelly.py (100%) rename Tools/{scripts => build}/stable_abi.py (98%) mode change 100755 => 100644 rename Tools/{scripts => build}/umarshal.py (98%) rename Tools/{scripts => build}/update_file.py (100%) rename Tools/{scripts => build}/verify_ensurepip_wheels.py (87%) delete mode 100644 Tools/c-analyzer/c_common/info.py delete mode 100644 Tools/c-analyzer/c_common/show.py delete mode 100644 Tools/c-analyzer/c_parser/_state_machine.py delete mode 100644 Tools/c-analyzer/c_parser/parser/_alt.py delete mode 100644 Tools/c-analyzer/c_parser/parser/_delim.py create mode 100644 Tools/c-analyzer/cpython/_builtin_types.py create mode 100644 Tools/c-analyzer/distutils/README rename {Lib/tkinter/test/test_tkinter => Tools/c-analyzer/distutils}/__init__.py (100%) create mode 100644 Tools/c-analyzer/distutils/_msvccompiler.py create mode 100644 Tools/c-analyzer/distutils/bcppcompiler.py create mode 100644 Tools/c-analyzer/distutils/ccompiler.py rename {Lib => Tools/c-analyzer}/distutils/cygwinccompiler.py (65%) rename {Lib => Tools/c-analyzer}/distutils/debug.py (100%) create mode 100644 Tools/c-analyzer/distutils/dep_util.py create mode 100644 Tools/c-analyzer/distutils/errors.py rename {Lib => Tools/c-analyzer}/distutils/log.py (84%) rename {Lib => Tools/c-analyzer}/distutils/msvc9compiler.py (51%) create mode 100644 Tools/c-analyzer/distutils/msvccompiler.py create mode 100644 Tools/c-analyzer/distutils/spawn.py create mode 100644 Tools/c-analyzer/distutils/unixccompiler.py create mode 100644 Tools/c-analyzer/distutils/util.py create mode 100644 Tools/cases_generator/README.md create mode 100644 Tools/cases_generator/generate_cases.py create mode 100644 Tools/cases_generator/interpreter_definition.md create mode 100644 Tools/cases_generator/lexer.py create mode 100644 Tools/cases_generator/parser.py create mode 100644 Tools/cases_generator/plexer.py create mode 100644 Tools/cases_generator/test_generator.py create mode 100644 Tools/clinic/mypy.ini create mode 100644 Tools/clinic/requirements-dev.txt delete mode 100644 Tools/demo/README delete mode 100755 Tools/demo/beer.py delete mode 100755 Tools/demo/eiffel.py delete mode 100755 Tools/demo/hanoi.py delete mode 100755 Tools/demo/life.py delete mode 100755 Tools/demo/markov.py delete mode 100755 Tools/demo/mcast.py delete mode 100755 Tools/demo/queens.py delete mode 100755 Tools/demo/redemo.py delete mode 100755 Tools/demo/rpython.py delete mode 100755 Tools/demo/rpythond.py delete mode 100755 Tools/demo/sortvisu.py delete mode 100755 Tools/demo/spreadsheet.py delete mode 100755 Tools/demo/vector.py delete mode 100644 Tools/msi/bundle/packagegroups/tools.wxs delete mode 100644 Tools/msi/tools/tools.wixproj delete mode 100644 Tools/msi/tools/tools.wxs delete mode 100644 Tools/msi/tools/tools_en-US.wxl delete mode 100644 Tools/msi/tools/tools_files.wxs rename Tools/{scripts => patchcheck}/patchcheck.py (94%) rename Tools/{scripts => patchcheck}/reindent.py (100%) rename Tools/{scripts => patchcheck}/untabify.py (100%) create mode 100644 Tools/requirements-hypothesis.txt delete mode 100755 Tools/scripts/abitype.py delete mode 100644 Tools/scripts/analyze_dxp.py delete mode 100755 Tools/scripts/byext.py delete mode 100755 Tools/scripts/byteyears.py delete mode 100755 Tools/scripts/cleanfuture.py delete mode 100755 Tools/scripts/copytime.py delete mode 100755 Tools/scripts/crlf.py delete mode 100755 Tools/scripts/db2pickle.py create mode 100644 Tools/scripts/divmod_threshold.py delete mode 100644 Tools/scripts/dutree.doc delete mode 100755 Tools/scripts/dutree.py delete mode 100755 Tools/scripts/eptags.py delete mode 100755 Tools/scripts/find-uname.py delete mode 100755 Tools/scripts/find_recursionlimit.py delete mode 100755 Tools/scripts/finddiv.py delete mode 100755 Tools/scripts/findlinksto.py delete mode 100755 Tools/scripts/findnocoding.py delete mode 100755 Tools/scripts/fixcid.py delete mode 100755 Tools/scripts/fixdiv.py delete mode 100755 Tools/scripts/fixheader.py delete mode 100755 Tools/scripts/fixnotice.py delete mode 100755 Tools/scripts/fixps.py delete mode 100755 Tools/scripts/get-remote-certificate.py delete mode 100755 Tools/scripts/google.py delete mode 100755 Tools/scripts/gprof2html.py delete mode 100755 Tools/scripts/highlight.py delete mode 100755 Tools/scripts/ifdef.py delete mode 100755 Tools/scripts/import_diagnostics.py delete mode 100755 Tools/scripts/lfcr.py delete mode 100755 Tools/scripts/linktree.py delete mode 100755 Tools/scripts/lll.py delete mode 100755 Tools/scripts/mailerdaemon.py delete mode 100755 Tools/scripts/make_ctype.py delete mode 100755 Tools/scripts/md5sum.py delete mode 100755 Tools/scripts/mkreal.py delete mode 100755 Tools/scripts/nm2def.py delete mode 100755 Tools/scripts/objgraph.py delete mode 100755 Tools/scripts/parseentities.py delete mode 100755 Tools/scripts/pathfix.py delete mode 100755 Tools/scripts/pdeps.py delete mode 100644 Tools/scripts/pep384_macrocheck.py delete mode 100755 Tools/scripts/pickle2db.py delete mode 100755 Tools/scripts/pindent.py delete mode 100755 Tools/scripts/ptags.py delete mode 100755 Tools/scripts/pysource.py delete mode 100755 Tools/scripts/reindent-rst.py delete mode 100755 Tools/scripts/rgrep.py delete mode 100644 Tools/scripts/startuptime.py delete mode 100755 Tools/scripts/suff.py delete mode 100755 Tools/scripts/texi2html.py delete mode 100755 Tools/scripts/which.py delete mode 100644 Tools/scripts/win_add2path.py create mode 100644 Tools/unicode/genmap_tchinese.py delete mode 100644 setup.py diff --git a/.azure-pipelines/ci.yml b/.azure-pipelines/ci.yml new file mode 100644 index 00000000..b5b2765e --- /dev/null +++ b/.azure-pipelines/ci.yml @@ -0,0 +1,48 @@ +trigger: ['main', '3.12', '3.11', '3.10', '3.9', '3.8', '3.7'] + +jobs: +- job: Prebuild + displayName: Pre-build checks + + pool: + vmImage: ubuntu-22.04 + + steps: + - template: ./prebuild-checks.yml + + +- job: Windows_CI_Tests + displayName: Windows CI Tests + dependsOn: Prebuild + condition: and(succeeded(), eq(dependencies.Prebuild.outputs['tests.run'], 'true')) + + pool: + vmImage: windows-2022 + + strategy: + matrix: + win32: + arch: win32 + buildOpt: '-p Win32' + testRunTitle: '$(Build.SourceBranchName)-win32' + testRunPlatform: win32 + win64: + arch: amd64 + buildOpt: '-p x64' + testRunTitle: '$(Build.SourceBranchName)-win64' + testRunPlatform: win64 + maxParallel: 4 + + steps: + - template: ./windows-steps.yml + + - template: ./windows-layout-steps.yml + parameters: + kind: nuget + - template: ./windows-layout-steps.yml + parameters: + kind: embed + - template: ./windows-layout-steps.yml + parameters: + kind: appx + fulltest: true diff --git a/.azure-pipelines/posix-deps-apt.sh b/.azure-pipelines/posix-deps-apt.sh new file mode 100755 index 00000000..e0f4ca5d --- /dev/null +++ b/.azure-pipelines/posix-deps-apt.sh @@ -0,0 +1,27 @@ +#!/bin/sh +apt-get update + +apt-get -yq install \ + build-essential \ + zlib1g-dev \ + libbz2-dev \ + liblzma-dev \ + libncurses5-dev \ + libreadline6-dev \ + libsqlite3-dev \ + libssl-dev \ + libgdbm-dev \ + tk-dev \ + lzma \ + lzma-dev \ + liblzma-dev \ + libffi-dev \ + uuid-dev \ + xvfb + +if [ ! -z "$1" ] +then + echo ##vso[task.prependpath]$PWD/multissl/openssl/$1 + echo ##vso[task.setvariable variable=OPENSSL_DIR]$PWD/multissl/openssl/$1 + python3 Tools/ssl/multissltests.py --steps=library --base-directory $PWD/multissl --openssl $1 --system Linux +fi diff --git a/.azure-pipelines/posix-steps.yml b/.azure-pipelines/posix-steps.yml new file mode 100644 index 00000000..e23c7b1d --- /dev/null +++ b/.azure-pipelines/posix-steps.yml @@ -0,0 +1,26 @@ +steps: +- checkout: self + clean: true + fetchDepth: 5 + +# Work around a known issue affecting Ubuntu VMs on Pipelines +- script: sudo setfacl -Rb /home/vsts + displayName: 'Workaround ACL issue' + +- script: sudo ./.azure-pipelines/posix-deps-apt.sh $(openssl_version) + displayName: 'Install dependencies' + +- script: ./configure --with-pydebug + displayName: 'Configure CPython (debug)' + +- script: make -j4 + displayName: 'Build CPython' + +- script: make pythoninfo + displayName: 'Display build info' + +- script: | + git fetch origin + ./python Tools/patchcheck/patchcheck.py --ci true + displayName: 'Run patchcheck.py' + condition: and(succeeded(), eq(variables['Build.Reason'], 'PullRequest')) diff --git a/.azure-pipelines/pr.yml b/.azure-pipelines/pr.yml new file mode 100644 index 00000000..335a4b40 --- /dev/null +++ b/.azure-pipelines/pr.yml @@ -0,0 +1,28 @@ +pr: ['main', '3.12', '3.11', '3.10', '3.9', '3.8', '3.7'] + +jobs: +- job: Prebuild + displayName: Pre-build checks + + pool: + vmImage: ubuntu-22.04 + + steps: + - template: ./prebuild-checks.yml + + +- job: Ubuntu_Patchcheck + displayName: Ubuntu patchcheck + dependsOn: Prebuild + condition: and(succeeded(), eq(dependencies.Prebuild.outputs['tests.run'], 'true')) + + pool: + vmImage: ubuntu-22.04 + + variables: + testRunTitle: '$(system.pullRequest.TargetBranch)-linux' + testRunPlatform: linux + openssl_version: 1.1.1u + + steps: + - template: ./posix-steps.yml diff --git a/.azure-pipelines/prebuild-checks.yml b/.azure-pipelines/prebuild-checks.yml new file mode 100644 index 00000000..2c6460d2 --- /dev/null +++ b/.azure-pipelines/prebuild-checks.yml @@ -0,0 +1,24 @@ +steps: +- checkout: self + fetchDepth: 5 + +- script: echo "##vso[task.setvariable variable=diffTarget]HEAD~1" + displayName: Set default diff target + +- script: | + git fetch -q origin $(System.PullRequest.TargetBranch) + echo "##vso[task.setvariable variable=diffTarget]HEAD \$(git merge-base HEAD FETCH_HEAD)" + displayName: Fetch comparison tree + condition: and(succeeded(), variables['System.PullRequest.TargetBranch']) + +- script: | + if ! git diff --name-only $(diffTarget) | grep -qvE '(\.rst$|^Doc|^Misc)' + then + echo "Only docs were updated: tests.run=false" + echo "##vso[task.setvariable variable=run;isOutput=true]false" + else + echo "Code was updated: tests.run=true" + echo "##vso[task.setvariable variable=run;isOutput=true]true" + fi + displayName: Detect source changes + name: tests diff --git a/.azure-pipelines/windows-layout-steps.yml b/.azure-pipelines/windows-layout-steps.yml new file mode 100644 index 00000000..afd89781 --- /dev/null +++ b/.azure-pipelines/windows-layout-steps.yml @@ -0,0 +1,28 @@ +parameters: + kind: nuget + extraOpts: --precompile + fulltest: false + +steps: +- script: .\python.bat PC\layout -vv -s "$(Build.SourcesDirectory)" -b "$(Py_OutDir)\$(arch)" -t "$(Build.BinariesDirectory)\layout-tmp-${{ parameters.kind }}-$(arch)" --copy "$(Build.BinariesDirectory)\layout-${{ parameters.kind }}-$(arch)" ${{ parameters.extraOpts }} --preset-${{ parameters.kind }} --include-tests + displayName: Create ${{ parameters.kind }} layout + +- script: .\python.exe -m test.pythoninfo + workingDirectory: $(Build.BinariesDirectory)\layout-${{ parameters.kind }}-$(arch) + displayName: Show layout info (${{ parameters.kind }}) + +- ${{ if eq(parameters.fulltest, 'true') }}: + - script: .\python.exe -m test -q -uall -u-cpu -rwW --slowest --timeout=1200 -j0 --junit-xml="$(Build.BinariesDirectory)\test-results-${{ parameters.kind }}.xml" --tempdir "$(Build.BinariesDirectory)\tmp-${{ parameters.kind }}-$(arch)" -i test_launcher + workingDirectory: $(Build.BinariesDirectory)\layout-${{ parameters.kind }}-$(arch) + displayName: ${{ parameters.kind }} Tests + env: + PREFIX: $(Build.BinariesDirectory)\layout-${{ parameters.kind }}-$(arch) + + - task: PublishTestResults@2 + displayName: Publish ${{ parameters.kind }} Test Results + inputs: + testResultsFiles: $(Build.BinariesDirectory)\test-results-${{ parameters.kind }}.xml + mergeTestResults: true + testRunTitle: ${{ parameters.kind }}-$(testRunTitle) + platform: $(testRunPlatform) + condition: succeededOrFailed() diff --git a/.azure-pipelines/windows-steps.yml b/.azure-pipelines/windows-steps.yml new file mode 100644 index 00000000..f502c406 --- /dev/null +++ b/.azure-pipelines/windows-steps.yml @@ -0,0 +1,37 @@ +steps: +- checkout: self + clean: false + fetchDepth: 5 + +- powershell: | + # Relocate build outputs outside of source directory to make cleaning faster + Write-Host '##vso[task.setvariable variable=Py_IntDir]$(Build.BinariesDirectory)\obj' + # UNDONE: Do not build to a different directory because of broken tests + Write-Host '##vso[task.setvariable variable=Py_OutDir]$(Build.SourcesDirectory)\PCbuild' + #Write-Host '##vso[task.setvariable variable=Py_OutDir]$(Build.BinariesDirectory)\bin' + Write-Host '##vso[task.setvariable variable=EXTERNALS_DIR]$(Build.BinariesDirectory)\externals' + displayName: Update build locations + +- script: PCbuild\build.bat -e $(buildOpt) + displayName: 'Build CPython' + env: + IncludeUwp: true + +- script: python.bat -m test.pythoninfo + displayName: 'Display build info' + condition: and(succeeded(), variables['testRunPlatform']) + +- script: PCbuild\rt.bat -q -uall -u-cpu -rwW --slowest --timeout=1200 -j0 --junit-xml="$(Build.BinariesDirectory)\test-results.xml" --tempdir="$(Build.BinariesDirectory)\test" + displayName: 'Tests' + condition: and(succeeded(), variables['testRunPlatform']) + env: + PREFIX: $(Py_OutDir)\$(arch) + +- task: PublishTestResults@2 + displayName: 'Publish Test Results' + inputs: + testResultsFiles: '$(Build.BinariesDirectory)\test-results.xml' + mergeTestResults: true + testRunTitle: $(testRunTitle) + platform: $(testRunPlatform) + condition: and(succeededOrFailed(), variables['testRunPlatform']) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 00000000..efbdcd40 --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,24 @@ +FROM docker.io/library/fedora:37 + +ENV CC=clang + +ENV WASI_SDK_VERSION=19 +ENV WASI_SDK_PATH=/opt/wasi-sdk + +ENV WASMTIME_HOME=/opt/wasmtime +ENV WASMTIME_VERSION=7.0.0 +ENV WASMTIME_CPU_ARCH=x86_64 + +RUN dnf -y --nodocs --setopt=install_weak_deps=False install /usr/bin/{blurb,clang,curl,git,ln,tar,xz} 'dnf-command(builddep)' && \ + dnf -y --nodocs --setopt=install_weak_deps=False builddep python3 && \ + dnf -y clean all + +RUN mkdir ${WASI_SDK_PATH} && \ + curl --location https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-${WASI_SDK_VERSION}/wasi-sdk-${WASI_SDK_VERSION}.0-linux.tar.gz | \ + tar --strip-components 1 --directory ${WASI_SDK_PATH} --extract --gunzip + +RUN mkdir --parents ${WASMTIME_HOME} && \ + curl --location "https://github.com/bytecodealliance/wasmtime/releases/download/v${WASMTIME_VERSION}/wasmtime-v${WASMTIME_VERSION}-${WASMTIME_CPU_ARCH}-linux.tar.xz" | \ + xz --decompress | \ + tar --strip-components 1 --directory ${WASMTIME_HOME} -x && \ + ln -s ${WASMTIME_HOME}/wasmtime /usr/local/bin diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 00000000..9fbaf7fd --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,81 @@ +{ + "build": { + "dockerfile": "Dockerfile" + }, + "onCreateCommand": [ + // Install common tooling. + "dnf", + "install", + "-y", + "which", + "zsh", + "fish" + ], + "updateContentCommand": { + // Using the shell for `nproc` usage. + "python": "./configure --config-cache --with-pydebug && make -s -j `nproc`", + "docs": [ + "make", + "--directory", + "Doc", + "venv", + "html" + ] + }, + "customizations": { + "vscode": { + "extensions": [ + // Highlighting for Parser/Python.asdl. + "brettcannon.zephyr-asdl", + // Highlighting for configure.ac. + "maelvalais.autoconf", + // C auto-complete. + "ms-vscode.cpptools", + // To view built docs. + "ms-vscode.live-server" + // https://github.com/microsoft/vscode-python/issues/18073 + // "ms-python.python" + ], + "settings": { + "C_Cpp.default.compilerPath": "/usr/bin/clang", + "C_Cpp.default.cStandard": "c11", + "C_Cpp.default.defines": [ + "CONFIG_64", + "Py_BUILD_CORE" + ], + "C_Cpp.default.includePath": [ + "${workspaceFolder}/*", + "${workspaceFolder}/Include/**" + ], + // https://github.com/microsoft/vscode-cpptools/issues/10732 + "C_Cpp.errorSquiggles": "disabled", + "editor.insertSpaces": true, + "editor.rulers": [ + 80 + ], + "editor.tabSize": 4, + "editor.trimAutoWhitespace": true, + "files.associations": { + "*.h": "c" + }, + "files.encoding": "utf8", + "files.eol": "\n", + "files.insertFinalNewline": true, + "files.trimTrailingWhitespace": true, + "python.analysis.diagnosticSeverityOverrides": { + // Complains about shadowing the stdlib w/ the stdlib. + "reportShadowedImports": "none", + // Doesn't like _frozen_importlib. + "reportMissingImports": "none" + }, + "python.analysis.extraPaths": [ + "Lib" + ], + "python.defaultInterpreterPath": "./python", + "[restructuredtext]": { + "editor.tabSize": 3 + } + } + } + } +} diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..4ed95069 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,94 @@ +# Binary data types +*.aif binary +*.aifc binary +*.aiff binary +*.au binary +*.bmp binary +*.exe binary +*.icns binary +*.gif binary +*.ico binary +*.jpg binary +*.pck binary +*.png binary +*.psd binary +*.tar binary +*.wav binary +*.whl binary +*.zip binary + +# Specific binary files +Lib/test/sndhdrdata/sndhdr.* binary +PC/classicAppCompat.* binary + +# Text files that should not be subject to eol conversion +[attr]noeol -text + +Lib/test/cjkencodings/* noeol +Lib/test/coding20731.py noeol +Lib/test/decimaltestdata/*.decTest noeol +Lib/test/test_email/data/*.txt noeol +Lib/test/test_importlib/resources/data01/* noeol +Lib/test/test_importlib/resources/namespacedata01/* noeol +Lib/test/xmltestdata/* noeol + +# Shell scripts should have LF even on Windows because of Cygwin +Lib/venv/scripts/common/activate text eol=lf +Lib/venv/scripts/posix/* text eol=lf + +# CRLF files +[attr]dos text eol=crlf + +*.bat dos +*.proj dos +*.props dos +*.ps1 dos +*.sln dos +*.vcxproj* dos +PC/readme.txt dos +PCbuild/readme.txt dos + +# Language aware diff headers +# https://tekin.co.uk/2020/10/better-git-diff-output-for-ruby-python-elixir-and-more +# https://gist.github.com/tekin/12500956bd56784728e490d8cef9cb81 +*.c diff=cpp +*.h diff=cpp +*.css diff=css +*.html diff=html +*.py diff=python +*.md diff=markdown + +# Generated files +# https://github.com/github/linguist/blob/master/docs/overrides.md +# +# To always hide generated files in local diffs, mark them as binary: +# $ git config diff.generated.binary true +# +[attr]generated linguist-generated=true diff=generated + +**/clinic/*.c.h generated +*_db.h generated +Doc/data/stable_abi.dat generated +Doc/library/token-list.inc generated +Include/internal/pycore_ast.h generated +Include/internal/pycore_ast_state.h generated +Include/internal/pycore_opcode.h generated +Include/internal/pycore_*_generated.h generated +Include/opcode.h generated +Include/token.h generated +Lib/keyword.py generated +Lib/test/levenshtein_examples.json generated +Lib/test/test_stable_abi_ctypes.py generated +Lib/token.py generated +Objects/typeslots.inc generated +PC/python3dll.c generated +Parser/parser.c generated +Parser/token.c generated +Programs/test_frozenmain.h generated +Python/Python-ast.c generated +Python/generated_cases.c.h generated +Python/opcode_targets.h generated +Python/stdlib_module_names.h generated +Tools/peg_generator/pegen/grammar_parser.py generated +aclocal.m4 generated +configure generated diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 00000000..913de4e2 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,168 @@ +# See https://help.github.com/articles/about-codeowners/ +# for more info about CODEOWNERS file + +# It uses the same pattern rule for gitignore file +# https://git-scm.com/docs/gitignore#_pattern_format + +# GitHub +.github/** @ezio-melotti @hugovk + +# pre-commit +.pre-commit-config.yaml @hugovk @AlexWaygood +.ruff.toml @hugovk @AlexWaygood + +# Build system +configure* @erlend-aasland @corona10 + +# asyncio +**/*asyncio* @1st1 @asvetlov @gvanrossum @kumaraditya303 @willingc + +# Core +**/*context* @1st1 +**/*genobject* @markshannon +**/*hamt* @1st1 +Objects/set* @rhettinger +Objects/dict* @methane @markshannon +Objects/typevarobject.c @JelleZijlstra +Objects/type* @markshannon +Objects/codeobject.c @markshannon +Objects/frameobject.c @markshannon +Objects/call.c @markshannon +Python/ceval.c @markshannon +Python/compile.c @markshannon @iritkatriel +Python/assemble.c @markshannon @iritkatriel +Python/flowgraph.c @markshannon @iritkatriel +Python/ast_opt.c @isidentical +Lib/test/test_patma.py @brandtbucher +Lib/test/test_peepholer.py @brandtbucher +Lib/test/test_type_*.py @JelleZijlstra + +# Exceptions +Lib/traceback.py @iritkatriel +Lib/test/test_except*.py @iritkatriel +Lib/test/test_traceback.py @iritkatriel +Objects/exceptions.c @iritkatriel +Python/traceback.c @iritkatriel + +# Hashing +**/*hashlib* @tiran +**/*pyhash* @tiran +**/*sha* @tiran +**/*md5* @tiran +**/*blake* @tiran +/Modules/_blake2/** @tiran +/Modules/_sha3/** @tiran + +# logging +**/*logging* @vsajip + +# venv +**/*venv* @vsajip + +# Launcher +/PC/launcher.c @vsajip + +# HTML +/Lib/html/ @ezio-melotti +/Lib/_markupbase.py @ezio-melotti +/Lib/test/test_html*.py @ezio-melotti +/Tools/build/parse_html5_entities.py @ezio-melotti + +# Import (including importlib). +**/*import* @brettcannon @encukou @ericsnowcurrently @ncoghlan @warsaw +**/*importlib/resources/* @jaraco @warsaw @FFY00 +**/importlib/metadata/* @jaraco @warsaw + +# Dates and times +**/*datetime* @pganssle @abalkin +**/*str*time* @pganssle @abalkin +Doc/library/time.rst @pganssle @abalkin +Lib/test/test_time.py @pganssle @abalkin +Modules/timemodule.c @pganssle @abalkin +Python/pytime.c @pganssle @abalkin +Include/pytime.h @pganssle @abalkin + +# Email and related +**/*mail* @python/email-team +**/*smtp* @python/email-team +**/*mime* @python/email-team +**/*imap* @python/email-team +**/*poplib* @python/email-team + +# Garbage collector +/Modules/gcmodule.c @pablogsal +/Doc/library/gc.rst @pablogsal + +# Parser +/Parser/ @pablogsal @lysnikolaou +/Tools/peg_generator/ @pablogsal @lysnikolaou +/Lib/test/test_peg_generator/ @pablogsal @lysnikolaou +/Grammar/python.gram @pablogsal @lysnikolaou + +# AST +Python/ast.c @isidentical +Parser/asdl.py @isidentical +Parser/asdl_c.py @isidentical +Lib/ast.py @isidentical + +# Mock +/Lib/unittest/mock.py @cjw296 +/Lib/test/test_unittest/testmock/* @cjw296 + +# SQLite 3 +**/*sqlite* @berkerpeksag @erlend-aasland + +# subprocess +/Lib/subprocess.py @gpshead +/Lib/test/test_subprocess.py @gpshead +/Modules/*subprocess* @gpshead + +# Windows +/PC/ @python/windows-team +/PCbuild/ @python/windows-team + +# Urllib +**/*robotparser* @berkerpeksag + +# Windows installer packages +/Tools/msi/ @python/windows-team +/Tools/nuget/ @python/windows-team + +# Misc +**/*itertools* @rhettinger +**/*collections* @rhettinger +**/*random* @rhettinger +**/*queue* @rhettinger +**/*bisect* @rhettinger +**/*heapq* @rhettinger +**/*functools* @rhettinger +**/*decimal* @rhettinger + +**/*dataclasses* @ericvsmith + +**/*idlelib* @terryjreedy + +**/*typing* @gvanrossum @Fidget-Spinner @JelleZijlstra @AlexWaygood + +**/*ftplib @giampaolo +**/*shutil @giampaolo + +**/*enum* @ethanfurman +**/*cgi* @ethanfurman +**/*tarfile* @ethanfurman + +**/*tomllib* @encukou @hauntsaninja + +**/*sysconfig* @FFY00 + +**/*cjkcodecs* @corona10 + +# macOS +/Mac/ @python/macos-team +**/*osx_support* @python/macos-team + +# pathlib +**/*pathlib* @barneygale + +# zipfile.Path +**/*zipfile/_path/* @jaraco diff --git a/.github/CONTRIBUTING.rst b/.github/CONTRIBUTING.rst new file mode 100644 index 00000000..2ef9cdc1 --- /dev/null +++ b/.github/CONTRIBUTING.rst @@ -0,0 +1,55 @@ +Contributing to Python +====================== + +Build Status +------------ + +- `Buildbot status overview `_ + +- `GitHub Actions status `_ + + +Thank You +--------- +First off, thanks for contributing to the maintenance of the Python programming +language and the CPython interpreter! Even if your contribution is not +ultimately accepted, the fact you put time and effort into helping out is +greatly appreciated. + + +Contribution Guidelines +----------------------- +Please read the `devguide `_ for +guidance on how to contribute to this project. The documentation covers +everything from how to build the code to submitting a pull request. There are +also suggestions on how you can most effectively help the project. + +Please be aware that our workflow does deviate slightly from the typical GitHub +project. Details on how to properly submit a pull request are covered in +`Lifecycle of a Pull Request `_. +We utilize various bots and status checks to help with this, so do follow the +comments they leave and their "Details" links, respectively. The key points of +our workflow that are not covered by a bot or status check are: + +- All discussions that are not directly related to the code in the pull request + should happen on `GitHub Issues `_. +- Upon your first non-trivial pull request (which includes documentation changes), + feel free to add yourself to ``Misc/ACKS`` + + +Setting Expectations +-------------------- +Due to the fact that this project is entirely volunteer-run (i.e. no one is paid +to work on Python full-time), we unfortunately can make no guarantees as to if +or when a core developer will get around to reviewing your pull request. +If no core developer has done a review or responded to changes made because of a +"changes requested" review, please feel free to email python-dev to ask if +someone could take a look at your pull request. + + +Code of Conduct +--------------- +All interactions for this project are covered by the +`PSF Code of Conduct `_. Everyone is +expected to be open, considerate, and respectful of others no matter their +position within the project. diff --git a/.github/ISSUE_TEMPLATE/bug.md b/.github/ISSUE_TEMPLATE/bug.md new file mode 100644 index 00000000..1d93e073 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug.md @@ -0,0 +1,32 @@ +--- +name: Bug report +about: Submit a bug report +labels: "type-bug" +--- + + + +# Bug report + +A clear and concise description of what the bug is. +Include a minimal, reproducible example (https://stackoverflow.com/help/minimal-reproducible-example), if possible. + +# Your environment + + + +- CPython versions tested on: +- Operating system and architecture: + + diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 00000000..75d17430 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,7 @@ +contact_links: + - name: "Getting help" + about: "Ask questions about using Python and debugging errors on Discourse." + url: "https://discuss.python.org/c/users/7" + - name: "Proposing new features" + about: "Submit major feature proposal (e.g. syntax changes) to an ideas forum first." + url: "https://discuss.python.org/c/ideas/6" diff --git a/.github/ISSUE_TEMPLATE/crash.md b/.github/ISSUE_TEMPLATE/crash.md new file mode 100644 index 00000000..dad3423d --- /dev/null +++ b/.github/ISSUE_TEMPLATE/crash.md @@ -0,0 +1,33 @@ +--- +name: Crash report +about: A hard crash of the interpreter, possibly with a core dump +labels: "type-crash" +--- + + + +# Crash report + +Tell us what happened, ideally including a minimal, reproducible example (https://stackoverflow.com/help/minimal-reproducible-example). + +# Error messages + +Enter any relevant error message caused by the crash, including a core dump if there is one. + +# Your environment + + + +- CPython versions tested on: +- Operating system and architecture: + + diff --git a/.github/ISSUE_TEMPLATE/documentation.md b/.github/ISSUE_TEMPLATE/documentation.md new file mode 100644 index 00000000..174fd391 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/documentation.md @@ -0,0 +1,9 @@ +--- +name: Documentation +about: Report a problem with the documentation +labels: "docs" +--- + +# Documentation + +(A clear and concise description of the issue.) diff --git a/.github/ISSUE_TEMPLATE/feature.md b/.github/ISSUE_TEMPLATE/feature.md new file mode 100644 index 00000000..ed051e94 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature.md @@ -0,0 +1,28 @@ +--- +name: Feature or enhancement +about: Submit a proposal for a new CPython feature or enhancement +labels: "type-feature" +--- + +# Feature or enhancement + +(A clear and concise description of your proposal.) + +# Pitch + +(Explain why this feature or enhancement should be implemented and how it would be used. + Add examples, if applicable.) + +# Previous discussion + + + + + diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 00000000..4cc2f461 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,30 @@ + diff --git a/.github/SECURITY.md b/.github/SECURITY.md new file mode 100644 index 00000000..923720bc --- /dev/null +++ b/.github/SECURITY.md @@ -0,0 +1,17 @@ +# Security Policy + +## Supported Versions + +The Python team applies security fixes according to the table +in [the devguide]( +https://devguide.python.org/versions/#supported-versions +). + +## Reporting a Vulnerability + +Please read the guidelines on reporting security issues [on the +official website](https://www.python.org/dev/security/) for +instructions on how to report a security-related problem to +the Python team responsibly. + +To reach the response team, email `security at python dot org`. diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..f026b0f5 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,21 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "monthly" + labels: + - "skip issue" + - "skip news" + ignore: + - dependency-name: "*" + update-types: + - "version-update:semver-minor" + - "version-update:semver-patch" + - package-ecosystem: "pip" + directory: "/Tools/clinic/" + schedule: + interval: "monthly" + labels: + - "skip issue" + - "skip news" diff --git a/.github/problem-matchers/gcc.json b/.github/problem-matchers/gcc.json new file mode 100644 index 00000000..bd5ab6c0 --- /dev/null +++ b/.github/problem-matchers/gcc.json @@ -0,0 +1,18 @@ +{ + "__comment": "Taken from vscode-cpptools's Extension/package.json gcc rule", + "problemMatcher": [ + { + "owner": "gcc-problem-matcher", + "pattern": [ + { + "regexp": "^(.*):(\\d+):(\\d+):\\s+(?:fatal\\s+)?(warning|error):\\s+(.*)$", + "file": 1, + "line": 2, + "column": 3, + "severity": 4, + "message": 5 + } + ] + } + ] +} \ No newline at end of file diff --git a/.github/problem-matchers/msvc.json b/.github/problem-matchers/msvc.json new file mode 100644 index 00000000..303a36b1 --- /dev/null +++ b/.github/problem-matchers/msvc.json @@ -0,0 +1,19 @@ +{ + "__comment": "Taken from vscode's vs/workbench/contrib/tasks/common/problemMatcher.ts msCompile rule", + "problemMatcher": [ + { + "owner": "msvc-problem-matcher", + "pattern": [ + { + "regexp": "^(?:\\s+\\d+\\>)?([^\\s].*)\\((\\d+),?(\\d+)?(?:,\\d+,\\d+)?\\)\\s*:\\s+(error|warning|info)\\s+(\\w{1,2}\\d+)\\s*:\\s*(.*)$", + "file": 1, + "line": 2, + "column": 3, + "severity": 4, + "code": 5, + "message": 6 + } + ] + } + ] + } \ No newline at end of file diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 00000000..af674de2 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,641 @@ +name: Tests + +# gh-84728: "paths-ignore" is not used to skip documentation-only PRs, because +# it prevents to mark a job as mandatory. A PR cannot be merged if a job is +# mandatory but not scheduled because of "paths-ignore". +on: + workflow_dispatch: + push: + branches: + - 'main' + - '3.12' + - '3.11' + - '3.10' + - '3.9' + - '3.8' + - '3.7' + pull_request: + branches: + - 'main' + - '3.12' + - '3.11' + - '3.10' + - '3.9' + - '3.8' + - '3.7' + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}-reusable + cancel-in-progress: true + +jobs: + check_source: + name: 'Check for source changes' + runs-on: ubuntu-latest + timeout-minutes: 10 + outputs: + run-docs: ${{ steps.docs-changes.outputs.run-docs || false }} + run_tests: ${{ steps.check.outputs.run_tests }} + run_hypothesis: ${{ steps.check.outputs.run_hypothesis }} + config_hash: ${{ steps.config_hash.outputs.hash }} + steps: + - uses: actions/checkout@v4 + - name: Check for source changes + id: check + run: | + if [ -z "$GITHUB_BASE_REF" ]; then + echo "run_tests=true" >> $GITHUB_OUTPUT + else + git fetch origin $GITHUB_BASE_REF --depth=1 + # git diff "origin/$GITHUB_BASE_REF..." (3 dots) may be more + # reliable than git diff "origin/$GITHUB_BASE_REF.." (2 dots), + # but it requires to download more commits (this job uses + # "git fetch --depth=1"). + # + # git diff "origin/$GITHUB_BASE_REF..." (3 dots) works with Git + # 2.26, but Git 2.28 is stricter and fails with "no merge base". + # + # git diff "origin/$GITHUB_BASE_REF.." (2 dots) should be enough on + # GitHub, since GitHub starts by merging origin/$GITHUB_BASE_REF + # into the PR branch anyway. + # + # https://github.com/python/core-workflow/issues/373 + git diff --name-only origin/$GITHUB_BASE_REF.. | grep -qvE '(\.rst$|^Doc|^Misc|^\.pre-commit-config\.yaml$|\.ruff\.toml$)' && echo "run_tests=true" >> $GITHUB_OUTPUT || true + fi + + # Check if we should run hypothesis tests + GIT_BRANCH=${GITHUB_BASE_REF:-${GITHUB_REF#refs/heads/}} + echo $GIT_BRANCH + if $(echo "$GIT_BRANCH" | grep -q -w '3\.\(8\|9\|10\|11\)'); then + echo "Branch too old for hypothesis tests" + echo "run_hypothesis=false" >> $GITHUB_OUTPUT + else + echo "Run hypothesis tests" + echo "run_hypothesis=true" >> $GITHUB_OUTPUT + fi + - name: Compute hash for config cache key + id: config_hash + run: | + echo "hash=${{ hashFiles('configure', 'configure.ac', '.github/workflows/build.yml') }}" >> $GITHUB_OUTPUT + - name: Get a list of the changed documentation-related files + if: github.event_name == 'pull_request' + id: changed-docs-files + uses: Ana06/get-changed-files@v2.2.0 + with: + filter: | + Doc/** + Misc/** + .github/workflows/reusable-docs.yml + format: csv # works for paths with spaces + - name: Check for docs changes + if: >- + github.event_name == 'pull_request' + && steps.changed-docs-files.outputs.added_modified_renamed != '' + id: docs-changes + run: | + echo "run-docs=true" >> "${GITHUB_OUTPUT}" + + check-docs: + name: Docs + needs: check_source + if: fromJSON(needs.check_source.outputs.run-docs) + uses: ./.github/workflows/reusable-docs.yml + + check_abi: + name: 'Check if the ABI has changed' + runs-on: ubuntu-22.04 + needs: check_source + if: needs.check_source.outputs.run_tests == 'true' + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 + - name: Install dependencies + run: | + sudo ./.github/workflows/posix-deps-apt.sh + sudo apt-get install -yq abigail-tools + - name: Build CPython + env: + CFLAGS: -g3 -O0 + run: | + # Build Python with the libpython dynamic library + ./configure --enable-shared + make -j4 + - name: Check for changes in the ABI + id: check + run: | + if ! make check-abidump; then + echo "Generated ABI file is not up to date." + echo "Please add the release manager of this branch as a reviewer of this PR." + echo "" + echo "The up to date ABI file should be attached to this build as an artifact." + echo "" + echo "To learn more about this check: https://devguide.python.org/setup/#regenerate-the-abi-dump" + echo "" + exit 1 + fi + - name: Generate updated ABI files + if: ${{ failure() && steps.check.conclusion == 'failure' }} + run: | + make regen-abidump + - uses: actions/upload-artifact@v3 + name: Publish updated ABI files + if: ${{ failure() && steps.check.conclusion == 'failure' }} + with: + name: abi-data + path: ./Doc/data/*.abi + + check_generated_files: + name: 'Check if generated files are up to date' + runs-on: ubuntu-latest + timeout-minutes: 60 + needs: check_source + if: needs.check_source.outputs.run_tests == 'true' + steps: + - uses: actions/checkout@v4 + - name: Restore config.cache + uses: actions/cache@v3 + with: + path: config.cache + key: ${{ github.job }}-${{ runner.os }}-${{ needs.check_source.outputs.config_hash }} + - uses: actions/setup-python@v4 + with: + python-version: '3.x' + - name: Install Dependencies + run: sudo ./.github/workflows/posix-deps-apt.sh + - name: Add ccache to PATH + run: echo "PATH=/usr/lib/ccache:$PATH" >> $GITHUB_ENV + - name: Configure ccache action + uses: hendrikmuhs/ccache-action@v1.2 + - name: Check Autoconf and aclocal versions + run: | + grep "Generated by GNU Autoconf 2.71" configure + grep "aclocal 1.16.4" aclocal.m4 + grep -q "runstatedir" configure + grep -q "PKG_PROG_PKG_CONFIG" aclocal.m4 + - name: Configure CPython + run: | + # Build Python with the libpython dynamic library + ./configure --config-cache --with-pydebug --enable-shared + - name: Regenerate autoconf files with container image + run: make regen-configure + - name: Build CPython + run: | + # Deepfreeze will usually cause global objects to be added or removed, + # so we run it before regen-global-objects gets rum (in regen-all). + make regen-deepfreeze + make -j4 regen-all + make regen-stdlib-module-names + - name: Check for changes + run: | + git add -u + changes=$(git status --porcelain) + # Check for changes in regenerated files + if test -n "$changes"; then + echo "Generated files not up to date." + echo "Perhaps you forgot to run make regen-all or build.bat --regen. ;)" + echo "configure files must be regenerated with a specific version of autoconf." + echo "$changes" + echo "" + git diff --staged || true + exit 1 + fi + - name: Check exported libpython symbols + run: make smelly + - name: Check limited ABI symbols + run: make check-limited-abi + - name: Check for unsupported C global variables + if: github.event_name == 'pull_request' # $GITHUB_EVENT_NAME + run: make check-c-globals + + build_win32: + name: 'Windows (x86)' + runs-on: windows-latest + timeout-minutes: 60 + needs: check_source + if: needs.check_source.outputs.run_tests == 'true' + env: + IncludeUwp: 'true' + steps: + - uses: actions/checkout@v4 + - name: Build CPython + run: .\PCbuild\build.bat -e -d -p Win32 + - name: Display build info + run: .\python.bat -m test.pythoninfo + - name: Tests + run: .\PCbuild\rt.bat -p Win32 -d -q -uall -u-cpu -rwW --slowest --timeout=1200 -j0 + + build_win_amd64: + name: 'Windows (x64)' + runs-on: windows-latest + timeout-minutes: 60 + needs: check_source + if: needs.check_source.outputs.run_tests == 'true' + env: + IncludeUwp: 'true' + steps: + - uses: actions/checkout@v4 + - name: Register MSVC problem matcher + run: echo "::add-matcher::.github/problem-matchers/msvc.json" + - name: Build CPython + run: .\PCbuild\build.bat -e -d -p x64 + - name: Display build info + run: .\python.bat -m test.pythoninfo + - name: Tests + run: .\PCbuild\rt.bat -p x64 -d -q -uall -u-cpu -rwW --slowest --timeout=1200 -j0 + + build_win_arm64: + name: 'Windows (arm64)' + runs-on: windows-latest + timeout-minutes: 60 + needs: check_source + if: needs.check_source.outputs.run_tests == 'true' + env: + IncludeUwp: 'true' + steps: + - uses: actions/checkout@v4 + - name: Register MSVC problem matcher + run: echo "::add-matcher::.github/problem-matchers/msvc.json" + - name: Build CPython + run: .\PCbuild\build.bat -e -d -p arm64 + + build_macos: + name: 'macOS' + runs-on: macos-latest + timeout-minutes: 60 + needs: check_source + if: needs.check_source.outputs.run_tests == 'true' + env: + HOMEBREW_NO_ANALYTICS: 1 + HOMEBREW_NO_AUTO_UPDATE: 1 + HOMEBREW_NO_INSTALL_CLEANUP: 1 + PYTHONSTRICTEXTENSIONBUILD: 1 + steps: + - uses: actions/checkout@v4 + - name: Restore config.cache + uses: actions/cache@v3 + with: + path: config.cache + key: ${{ github.job }}-${{ runner.os }}-${{ needs.check_source.outputs.config_hash }} + - name: Install Homebrew dependencies + run: brew install pkg-config openssl@3.0 xz gdbm tcl-tk + - name: Configure CPython + run: | + GDBM_CFLAGS="-I$(brew --prefix gdbm)/include" \ + GDBM_LIBS="-L$(brew --prefix gdbm)/lib -lgdbm" \ + ./configure \ + --config-cache \ + --with-pydebug \ + --prefix=/opt/python-dev \ + --with-openssl="$(brew --prefix openssl@3.0)" + - name: Build CPython + run: make -j4 + - name: Display build info + run: make pythoninfo + - name: Tests + run: make buildbottest TESTOPTS="-j4 -uall,-cpu" + + build_ubuntu: + name: 'Ubuntu' + runs-on: ubuntu-20.04 + timeout-minutes: 60 + needs: check_source + if: needs.check_source.outputs.run_tests == 'true' + env: + OPENSSL_VER: 3.0.11 + PYTHONSTRICTEXTENSIONBUILD: 1 + steps: + - uses: actions/checkout@v4 + - name: Register gcc problem matcher + run: echo "::add-matcher::.github/problem-matchers/gcc.json" + - name: Install Dependencies + run: sudo ./.github/workflows/posix-deps-apt.sh + - name: Configure OpenSSL env vars + run: | + echo "MULTISSL_DIR=${GITHUB_WORKSPACE}/multissl" >> $GITHUB_ENV + echo "OPENSSL_DIR=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}" >> $GITHUB_ENV + echo "LD_LIBRARY_PATH=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}/lib" >> $GITHUB_ENV + - name: 'Restore OpenSSL build' + id: cache-openssl + uses: actions/cache@v3 + with: + path: ./multissl/openssl/${{ env.OPENSSL_VER }} + key: ${{ runner.os }}-multissl-openssl-${{ env.OPENSSL_VER }} + - name: Install OpenSSL + if: steps.cache-openssl.outputs.cache-hit != 'true' + run: python3 Tools/ssl/multissltests.py --steps=library --base-directory $MULTISSL_DIR --openssl $OPENSSL_VER --system Linux + - name: Add ccache to PATH + run: | + echo "PATH=/usr/lib/ccache:$PATH" >> $GITHUB_ENV + - name: Configure ccache action + uses: hendrikmuhs/ccache-action@v1.2 + - name: Setup directory envs for out-of-tree builds + run: | + echo "CPYTHON_RO_SRCDIR=$(realpath -m ${GITHUB_WORKSPACE}/../cpython-ro-srcdir)" >> $GITHUB_ENV + echo "CPYTHON_BUILDDIR=$(realpath -m ${GITHUB_WORKSPACE}/../cpython-builddir)" >> $GITHUB_ENV + - name: Create directories for read-only out-of-tree builds + run: mkdir -p $CPYTHON_RO_SRCDIR $CPYTHON_BUILDDIR + - name: Bind mount sources read-only + run: sudo mount --bind -o ro $GITHUB_WORKSPACE $CPYTHON_RO_SRCDIR + - name: Restore config.cache + uses: actions/cache@v3 + with: + path: ${{ env.CPYTHON_BUILDDIR }}/config.cache + key: ${{ github.job }}-${{ runner.os }}-${{ needs.check_source.outputs.config_hash }} + - name: Configure CPython out-of-tree + working-directory: ${{ env.CPYTHON_BUILDDIR }} + run: | + ../cpython-ro-srcdir/configure \ + --config-cache \ + --with-pydebug \ + --with-openssl=$OPENSSL_DIR + - name: Build CPython out-of-tree + working-directory: ${{ env.CPYTHON_BUILDDIR }} + run: make -j4 + - name: Display build info + working-directory: ${{ env.CPYTHON_BUILDDIR }} + run: make pythoninfo + - name: Remount sources writable for tests + # some tests write to srcdir, lack of pyc files slows down testing + run: sudo mount $CPYTHON_RO_SRCDIR -oremount,rw + - name: Tests + working-directory: ${{ env.CPYTHON_BUILDDIR }} + run: xvfb-run make buildbottest TESTOPTS="-j4 -uall,-cpu" + + build_ubuntu_ssltests: + name: 'Ubuntu SSL tests with OpenSSL' + runs-on: ubuntu-20.04 + timeout-minutes: 60 + needs: check_source + if: needs.check_source.outputs.run_tests == 'true' + strategy: + fail-fast: false + matrix: + openssl_ver: [1.1.1w, 3.0.11, 3.1.3] + env: + OPENSSL_VER: ${{ matrix.openssl_ver }} + MULTISSL_DIR: ${{ github.workspace }}/multissl + OPENSSL_DIR: ${{ github.workspace }}/multissl/openssl/${{ matrix.openssl_ver }} + LD_LIBRARY_PATH: ${{ github.workspace }}/multissl/openssl/${{ matrix.openssl_ver }}/lib + steps: + - uses: actions/checkout@v4 + - name: Restore config.cache + uses: actions/cache@v3 + with: + path: config.cache + key: ${{ github.job }}-${{ runner.os }}-${{ needs.check_source.outputs.config_hash }} + - name: Register gcc problem matcher + run: echo "::add-matcher::.github/problem-matchers/gcc.json" + - name: Install Dependencies + run: sudo ./.github/workflows/posix-deps-apt.sh + - name: Configure OpenSSL env vars + run: | + echo "MULTISSL_DIR=${GITHUB_WORKSPACE}/multissl" >> $GITHUB_ENV + echo "OPENSSL_DIR=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}" >> $GITHUB_ENV + echo "LD_LIBRARY_PATH=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}/lib" >> $GITHUB_ENV + - name: 'Restore OpenSSL build' + id: cache-openssl + uses: actions/cache@v3 + with: + path: ./multissl/openssl/${{ env.OPENSSL_VER }} + key: ${{ runner.os }}-multissl-openssl-${{ env.OPENSSL_VER }} + - name: Install OpenSSL + if: steps.cache-openssl.outputs.cache-hit != 'true' + run: python3 Tools/ssl/multissltests.py --steps=library --base-directory $MULTISSL_DIR --openssl $OPENSSL_VER --system Linux + - name: Add ccache to PATH + run: | + echo "PATH=/usr/lib/ccache:$PATH" >> $GITHUB_ENV + - name: Configure ccache action + uses: hendrikmuhs/ccache-action@v1.2 + - name: Configure CPython + run: ./configure --config-cache --with-pydebug --with-openssl=$OPENSSL_DIR + - name: Build CPython + run: make -j4 + - name: Display build info + run: make pythoninfo + - name: SSL tests + run: ./python Lib/test/ssltests.py + + test_hypothesis: + name: "Hypothesis tests on Ubuntu" + runs-on: ubuntu-20.04 + timeout-minutes: 60 + needs: check_source + if: needs.check_source.outputs.run_tests == 'true' && needs.check_source.outputs.run_hypothesis == 'true' + env: + OPENSSL_VER: 3.0.11 + PYTHONSTRICTEXTENSIONBUILD: 1 + steps: + - uses: actions/checkout@v4 + - name: Register gcc problem matcher + run: echo "::add-matcher::.github/problem-matchers/gcc.json" + - name: Install Dependencies + run: sudo ./.github/workflows/posix-deps-apt.sh + - name: Configure OpenSSL env vars + run: | + echo "MULTISSL_DIR=${GITHUB_WORKSPACE}/multissl" >> $GITHUB_ENV + echo "OPENSSL_DIR=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}" >> $GITHUB_ENV + echo "LD_LIBRARY_PATH=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}/lib" >> $GITHUB_ENV + - name: 'Restore OpenSSL build' + id: cache-openssl + uses: actions/cache@v3 + with: + path: ./multissl/openssl/${{ env.OPENSSL_VER }} + key: ${{ runner.os }}-multissl-openssl-${{ env.OPENSSL_VER }} + - name: Install OpenSSL + if: steps.cache-openssl.outputs.cache-hit != 'true' + run: python3 Tools/ssl/multissltests.py --steps=library --base-directory $MULTISSL_DIR --openssl $OPENSSL_VER --system Linux + - name: Add ccache to PATH + run: | + echo "PATH=/usr/lib/ccache:$PATH" >> $GITHUB_ENV + - name: Configure ccache action + uses: hendrikmuhs/ccache-action@v1.2 + - name: Setup directory envs for out-of-tree builds + run: | + echo "CPYTHON_RO_SRCDIR=$(realpath -m ${GITHUB_WORKSPACE}/../cpython-ro-srcdir)" >> $GITHUB_ENV + echo "CPYTHON_BUILDDIR=$(realpath -m ${GITHUB_WORKSPACE}/../cpython-builddir)" >> $GITHUB_ENV + - name: Create directories for read-only out-of-tree builds + run: mkdir -p $CPYTHON_RO_SRCDIR $CPYTHON_BUILDDIR + - name: Bind mount sources read-only + run: sudo mount --bind -o ro $GITHUB_WORKSPACE $CPYTHON_RO_SRCDIR + - name: Restore config.cache + uses: actions/cache@v3 + with: + path: ${{ env.CPYTHON_BUILDDIR }}/config.cache + key: ${{ github.job }}-${{ runner.os }}-${{ needs.check_source.outputs.config_hash }} + - name: Configure CPython out-of-tree + working-directory: ${{ env.CPYTHON_BUILDDIR }} + run: | + ../cpython-ro-srcdir/configure \ + --config-cache \ + --with-pydebug \ + --with-openssl=$OPENSSL_DIR + - name: Build CPython out-of-tree + working-directory: ${{ env.CPYTHON_BUILDDIR }} + run: make -j4 + - name: Display build info + working-directory: ${{ env.CPYTHON_BUILDDIR }} + run: make pythoninfo + - name: Remount sources writable for tests + # some tests write to srcdir, lack of pyc files slows down testing + run: sudo mount $CPYTHON_RO_SRCDIR -oremount,rw + - name: Setup directory envs for out-of-tree builds + run: | + echo "CPYTHON_BUILDDIR=$(realpath -m ${GITHUB_WORKSPACE}/../cpython-builddir)" >> $GITHUB_ENV + - name: "Create hypothesis venv" + working-directory: ${{ env.CPYTHON_BUILDDIR }} + run: | + VENV_LOC=$(realpath -m .)/hypovenv + VENV_PYTHON=$VENV_LOC/bin/python + echo "HYPOVENV=${VENV_LOC}" >> $GITHUB_ENV + echo "VENV_PYTHON=${VENV_PYTHON}" >> $GITHUB_ENV + ./python -m venv $VENV_LOC && $VENV_PYTHON -m pip install -r ${GITHUB_WORKSPACE}/Tools/requirements-hypothesis.txt + - name: 'Restore Hypothesis database' + id: cache-hypothesis-database + uses: actions/cache@v3 + with: + path: ./hypothesis + key: hypothesis-database-${{ github.head_ref || github.run_id }} + restore-keys: | + - hypothesis-database- + - name: "Run tests" + working-directory: ${{ env.CPYTHON_BUILDDIR }} + run: | + # Most of the excluded tests are slow test suites with no property tests + # + # (GH-104097) test_sysconfig is skipped because it has tests that are + # failing when executed from inside a virtual environment. + ${{ env.VENV_PYTHON }} -m test \ + -W \ + -o \ + -j4 \ + -x test_asyncio \ + -x test_multiprocessing_fork \ + -x test_multiprocessing_forkserver \ + -x test_multiprocessing_spawn \ + -x test_concurrent_futures \ + -x test_socket \ + -x test_subprocess \ + -x test_signal \ + -x test_sysconfig + - uses: actions/upload-artifact@v3 + if: always() + with: + name: hypothesis-example-db + path: .hypothesis/examples/ + + + build_asan: + name: 'Address sanitizer' + runs-on: ubuntu-20.04 + timeout-minutes: 60 + needs: check_source + if: needs.check_source.outputs.run_tests == 'true' + env: + OPENSSL_VER: 3.0.11 + PYTHONSTRICTEXTENSIONBUILD: 1 + ASAN_OPTIONS: detect_leaks=0:allocator_may_return_null=1:handle_segv=0 + steps: + - uses: actions/checkout@v4 + - name: Restore config.cache + uses: actions/cache@v3 + with: + path: config.cache + key: ${{ github.job }}-${{ runner.os }}-${{ needs.check_source.outputs.config_hash }} + - name: Register gcc problem matcher + run: echo "::add-matcher::.github/problem-matchers/gcc.json" + - name: Install Dependencies + run: sudo ./.github/workflows/posix-deps-apt.sh + - name: Set up GCC-10 for ASAN + uses: egor-tensin/setup-gcc@v1 + with: + version: 10 + - name: Configure OpenSSL env vars + run: | + echo "MULTISSL_DIR=${GITHUB_WORKSPACE}/multissl" >> $GITHUB_ENV + echo "OPENSSL_DIR=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}" >> $GITHUB_ENV + echo "LD_LIBRARY_PATH=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}/lib" >> $GITHUB_ENV + - name: 'Restore OpenSSL build' + id: cache-openssl + uses: actions/cache@v3 + with: + path: ./multissl/openssl/${{ env.OPENSSL_VER }} + key: ${{ runner.os }}-multissl-openssl-${{ env.OPENSSL_VER }} + - name: Install OpenSSL + if: steps.cache-openssl.outputs.cache-hit != 'true' + run: python3 Tools/ssl/multissltests.py --steps=library --base-directory $MULTISSL_DIR --openssl $OPENSSL_VER --system Linux + - name: Add ccache to PATH + run: | + echo "PATH=/usr/lib/ccache:$PATH" >> $GITHUB_ENV + - name: Configure ccache action + uses: hendrikmuhs/ccache-action@v1.2 + - name: Configure CPython + run: ./configure --config-cache --with-address-sanitizer --without-pymalloc + - name: Build CPython + run: make -j4 + - name: Display build info + run: make pythoninfo + - name: Tests + run: xvfb-run make buildbottest TESTOPTS="-j4 -uall,-cpu" + + all-required-green: # This job does nothing and is only used for the branch protection + name: All required checks pass + if: always() + + needs: + - check_source # Transitive dependency, needed to access `run_tests` value + - check-docs + - check_generated_files + - build_win32 + - build_win_amd64 + - build_win_arm64 + - build_macos + - build_ubuntu + - build_ubuntu_ssltests + - test_hypothesis + - build_asan + + runs-on: ubuntu-latest + + steps: + - name: Check whether the needed jobs succeeded or failed + uses: re-actors/alls-green@05ac9388f0aebcb5727afa17fcccfecd6f8ec5fe + with: + allowed-failures: >- + build_macos, + build_ubuntu_ssltests, + build_win32, + build_win_arm64, + test_hypothesis, + allowed-skips: >- + ${{ + !fromJSON(needs.check_source.outputs.run-docs) + && ' + check-docs, + ' + || '' + }} + ${{ + needs.check_source.outputs.run_tests != 'true' + && ' + check_generated_files, + build_win32, + build_win_amd64, + build_win_arm64, + build_macos, + build_ubuntu, + build_ubuntu_ssltests, + build_asan, + ' + || '' + }} + ${{ + !fromJSON(needs.check_source.outputs.run_hypothesis) + && ' + test_hypothesis, + ' + || '' + }} + jobs: ${{ toJSON(needs) }} diff --git a/.github/workflows/build_msi.yml b/.github/workflows/build_msi.yml new file mode 100644 index 00000000..29282dff --- /dev/null +++ b/.github/workflows/build_msi.yml @@ -0,0 +1,38 @@ +name: TestsMSI + +on: + workflow_dispatch: + push: + branches: + - 'main' + - '3.*' + paths: + - 'Tools/msi/**' + - '.github/workflows/build_msi.yml' + pull_request: + branches: + - 'main' + - '3.*' + paths: + - 'Tools/msi/**' + - '.github/workflows/build_msi.yml' + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + build: + name: Windows Installer + runs-on: windows-latest + timeout-minutes: 60 + strategy: + matrix: + type: [x86, x64, arm64] + steps: + - uses: actions/checkout@v4 + - name: Build CPython installer + run: .\Tools\msi\build.bat --doc -${{ matrix.type }} diff --git a/.github/workflows/documentation-links.yml b/.github/workflows/documentation-links.yml new file mode 100644 index 00000000..43a7afec --- /dev/null +++ b/.github/workflows/documentation-links.yml @@ -0,0 +1,27 @@ +name: Read the Docs PR preview +# Automatically edits a pull request's descriptions with a link +# to the documentation's preview on Read the Docs. + +on: + pull_request_target: + types: + - opened + paths: + - 'Doc/**' + - '.github/workflows/doc.yml' + +permissions: + pull-requests: write + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + documentation-links: + runs-on: ubuntu-latest + steps: + - uses: readthedocs/actions/preview@v1 + with: + project-slug: "cpython-previews" + single-version: "true" diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 00000000..89f65816 --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,26 @@ +name: Lint + +on: [push, pull_request, workflow_dispatch] + +permissions: + contents: read + +env: + FORCE_COLOR: 1 + RUFF_FORMAT: github + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + lint: + runs-on: ubuntu-latest + timeout-minutes: 10 + + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v4 + with: + python-version: "3.x" + - uses: pre-commit/action@v3.0.0 diff --git a/.github/workflows/mypy.yml b/.github/workflows/mypy.yml new file mode 100644 index 00000000..f089a0b2 --- /dev/null +++ b/.github/workflows/mypy.yml @@ -0,0 +1,39 @@ +# Workflow to run mypy on select parts of the CPython repo +name: mypy + +on: + push: + branches: + - main + pull_request: + paths: + - "Tools/clinic/**" + - ".github/workflows/mypy.yml" + workflow_dispatch: + +permissions: + contents: read + +env: + PIP_DISABLE_PIP_VERSION_CHECK: 1 + FORCE_COLOR: 1 + TERM: xterm-256color # needed for FORCE_COLOR to work on mypy on Ubuntu, see https://github.com/python/mypy/issues/13817 + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + mypy: + name: Run mypy on Tools/clinic/ + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v4 + with: + python-version: "3.x" + cache: pip + cache-dependency-path: Tools/clinic/requirements-dev.txt + - run: pip install -r Tools/clinic/requirements-dev.txt + - run: mypy --config-file Tools/clinic/mypy.ini diff --git a/.github/workflows/new-bugs-announce-notifier.yml b/.github/workflows/new-bugs-announce-notifier.yml new file mode 100644 index 00000000..73806c5d --- /dev/null +++ b/.github/workflows/new-bugs-announce-notifier.yml @@ -0,0 +1,57 @@ +name: new-bugs-announce notifier + +on: + issues: + types: + - opened + +permissions: + issues: read + +jobs: + notify-new-bugs-announce: + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/setup-node@v3 + with: + node-version: 14 + - run: npm install mailgun.js form-data + - name: Send notification + uses: actions/github-script@v6 + env: + MAILGUN_API_KEY: ${{ secrets.MAILGUN_PYTHON_ORG_MAILGUN_KEY }} + with: + script: | + const Mailgun = require("mailgun.js"); + const formData = require('form-data'); + const mailgun = new Mailgun(formData); + const DOMAIN = "mailgun.python.org"; + const mg = mailgun.client({username: 'api', key: process.env.MAILGUN_API_KEY}); + github.rest.issues.get({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + }) + .then(function(issue) { + const payload = { + author : issue.data.user.login, + issue : issue.data.number, + title : issue.data.title, + url : issue.data.html_url, + labels : issue.data.labels.map(label => { return label.name }).join(", "), + assignee : issue.data.assignees.map(assignee => { return assignee.login }), + body : issue.data.body + }; + + const data = { + from: "CPython Issues ", + to: "new-bugs-announce@python.org", + subject: `[Issue ${issue.data.number}] ${issue.data.title}`, + template: "new-github-issue", + 'o:tracking-clicks': 'no', + 'h:X-Mailgun-Variables': JSON.stringify(payload) + }; + return mg.messages.create(DOMAIN, data) + }) + .then(msg => console.log(msg)); diff --git a/.github/workflows/posix-deps-apt.sh b/.github/workflows/posix-deps-apt.sh new file mode 100755 index 00000000..a220896f --- /dev/null +++ b/.github/workflows/posix-deps-apt.sh @@ -0,0 +1,25 @@ +#!/bin/sh +apt-get update + +apt-get -yq install \ + build-essential \ + pkg-config \ + ccache \ + gdb \ + lcov \ + libb2-dev \ + libbz2-dev \ + libffi-dev \ + libgdbm-dev \ + libgdbm-compat-dev \ + liblzma-dev \ + libncurses5-dev \ + libreadline6-dev \ + libsqlite3-dev \ + libssl-dev \ + lzma \ + lzma-dev \ + tk-dev \ + uuid-dev \ + xvfb \ + zlib1g-dev diff --git a/.github/workflows/project-updater.yml b/.github/workflows/project-updater.yml new file mode 100644 index 00000000..7574bfc2 --- /dev/null +++ b/.github/workflows/project-updater.yml @@ -0,0 +1,30 @@ +name: Update GH projects + +on: + issues: + types: + - opened + - labeled + +permissions: + contents: read + +jobs: + add-to-project: + name: Add issues to projects + runs-on: ubuntu-latest + timeout-minutes: 10 + strategy: + matrix: + include: + # if an issue has any of these labels, it will be added + # to the corresponding project + - { project: 2, label: "release-blocker, deferred-blocker" } + - { project: 32, label: sprint } + + steps: + - uses: actions/add-to-project@v0.1.0 + with: + project-url: https://github.com/orgs/python/projects/${{ matrix.project }} + github-token: ${{ secrets.ADD_TO_PROJECT_PAT }} + labeled: ${{ matrix.label }} diff --git a/.github/workflows/regen-abidump.sh b/.github/workflows/regen-abidump.sh new file mode 100644 index 00000000..251bb385 --- /dev/null +++ b/.github/workflows/regen-abidump.sh @@ -0,0 +1,8 @@ +set -ex + +export DEBIAN_FRONTEND=noninteractive +./.github/workflows/posix-deps-apt.sh +apt-get install -yq abigail-tools python3 +export CFLAGS="-g3 -O0" +./configure --enable-shared && make +make regen-abidump diff --git a/.github/workflows/require-pr-label.yml b/.github/workflows/require-pr-label.yml new file mode 100644 index 00000000..6efd3116 --- /dev/null +++ b/.github/workflows/require-pr-label.yml @@ -0,0 +1,22 @@ +name: Check labels + +on: + pull_request: + types: [opened, reopened, labeled, unlabeled, synchronize] + +permissions: + issues: write + pull-requests: write + +jobs: + label: + name: DO-NOT-MERGE / unresolved review + runs-on: ubuntu-latest + timeout-minutes: 10 + + steps: + - uses: mheap/github-action-required-labels@v4 + with: + mode: exactly + count: 0 + labels: "DO-NOT-MERGE, awaiting changes, awaiting change review" diff --git a/.github/workflows/reusable-docs.yml b/.github/workflows/reusable-docs.yml new file mode 100644 index 00000000..1c4fa423 --- /dev/null +++ b/.github/workflows/reusable-docs.yml @@ -0,0 +1,108 @@ +name: Docs + +on: + workflow_call: + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + build_doc: + name: 'Docs' + runs-on: ubuntu-latest + timeout-minutes: 60 + env: + branch_base: 'origin/${{ github.event.pull_request.base.ref }}' + branch_pr: 'origin/${{ github.event.pull_request.head.ref }}' + refspec_base: '+${{ github.event.pull_request.base.sha }}:remotes/origin/${{ github.event.pull_request.base.ref }}' + refspec_pr: '+${{ github.event.pull_request.head.sha }}:remotes/origin/${{ github.event.pull_request.head.ref }}' + steps: + - name: 'Check out latest PR branch commit' + uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.sha }} + # Adapted from https://github.com/actions/checkout/issues/520#issuecomment-1167205721 + - name: 'Fetch commits to get branch diff' + run: | + # Fetch enough history to find a common ancestor commit (aka merge-base): + git fetch origin ${{ env.refspec_pr }} --depth=$(( ${{ github.event.pull_request.commits }} + 1 )) \ + --no-tags --prune --no-recurse-submodules + + # This should get the oldest commit in the local fetched history (which may not be the commit the PR branched from): + COMMON_ANCESTOR=$( git rev-list --first-parent --max-parents=0 --max-count=1 ${{ env.branch_pr }} ) + DATE=$( git log --date=iso8601 --format=%cd "${COMMON_ANCESTOR}" ) + + # Get all commits since that commit date from the base branch (eg: master or main): + git fetch origin ${{ env.refspec_base }} --shallow-since="${DATE}" \ + --no-tags --prune --no-recurse-submodules + - name: 'Set up Python' + uses: actions/setup-python@v4 + with: + python-version: '3' + cache: 'pip' + cache-dependency-path: 'Doc/requirements.txt' + - name: 'Install build dependencies' + run: make -C Doc/ venv + + # To annotate PRs with Sphinx nitpicks (missing references) + - name: 'Build HTML documentation' + continue-on-error: true + run: | + set -Eeuo pipefail + # Build docs with the '-n' (nit-picky) option; write warnings to file + make -C Doc/ PYTHON=../python SPHINXOPTS="-q -n -W --keep-going -w sphinx-warnings.txt" html + - name: 'Check warnings' + if: github.event_name == 'pull_request' + run: | + python Doc/tools/check-warnings.py \ + --annotate-diff '${{ env.branch_base }}' '${{ env.branch_pr }}' \ + --fail-if-regression \ + --fail-if-improved + + # This build doesn't use problem matchers or check annotations + build_doc_oldest_supported_sphinx: + name: 'Docs (Oldest Sphinx)' + runs-on: ubuntu-latest + timeout-minutes: 60 + steps: + - uses: actions/checkout@v4 + - name: 'Set up Python' + uses: actions/setup-python@v4 + with: + python-version: '3.11' # known to work with Sphinx 4.2 + cache: 'pip' + cache-dependency-path: 'Doc/requirements-oldest-sphinx.txt' + - name: 'Install build dependencies' + run: make -C Doc/ venv REQUIREMENTS="requirements-oldest-sphinx.txt" + - name: 'Build HTML documentation' + run: make -C Doc/ SPHINXOPTS="-q" SPHINXERRORHANDLING="-W --keep-going" html + + # Run "doctest" on HEAD as new syntax doesn't exist in the latest stable release + doctest: + name: 'Doctest' + runs-on: ubuntu-latest + timeout-minutes: 60 + steps: + - uses: actions/checkout@v4 + - uses: actions/cache@v3 + with: + path: ~/.cache/pip + key: ubuntu-doc-${{ hashFiles('Doc/requirements.txt') }} + restore-keys: | + ubuntu-doc- + - name: 'Install Dependencies' + run: sudo ./.github/workflows/posix-deps-apt.sh && sudo apt-get install wamerican + - name: 'Configure CPython' + run: ./configure --with-pydebug + - name: 'Build CPython' + run: make -j4 + - name: 'Install build dependencies' + run: make -C Doc/ PYTHON=../python venv + # Use "xvfb-run" since some doctest tests open GUI windows + - name: 'Run documentation doctest' + run: xvfb-run make -C Doc/ PYTHON=../python SPHINXERRORHANDLING="-W --keep-going" doctest diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml new file mode 100644 index 00000000..94676f5e --- /dev/null +++ b/.github/workflows/stale.yml @@ -0,0 +1,28 @@ +name: Mark stale pull requests + +on: + schedule: + - cron: "0 0 * * *" + +permissions: + pull-requests: write + +jobs: + stale: + if: github.repository_owner == 'python' + + runs-on: ubuntu-latest + timeout-minutes: 10 + + steps: + - name: "Check PRs" + uses: actions/stale@v8 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + stale-pr-message: 'This PR is stale because it has been open for 30 days with no activity.' + stale-pr-label: 'stale' + days-before-issue-stale: -1 + days-before-pr-stale: 30 + days-before-close: -1 + ascending: true + operations-per-run: 120 diff --git a/.github/workflows/verify-ensurepip-wheels.yml b/.github/workflows/verify-ensurepip-wheels.yml new file mode 100644 index 00000000..4a545037 --- /dev/null +++ b/.github/workflows/verify-ensurepip-wheels.yml @@ -0,0 +1,33 @@ +name: Verify bundled wheels + +on: + workflow_dispatch: + push: + paths: + - 'Lib/ensurepip/_bundled/**' + - '.github/workflows/verify-ensurepip-wheels.yml' + - 'Tools/build/verify_ensurepip_wheels.py' + pull_request: + paths: + - 'Lib/ensurepip/_bundled/**' + - '.github/workflows/verify-ensurepip-wheels.yml' + - 'Tools/build/verify_ensurepip_wheels.py' + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + verify: + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v4 + with: + python-version: '3' + - name: Compare checksum of bundled wheels to the ones published on PyPI + run: ./Tools/build/verify_ensurepip_wheels.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..bde596a7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,158 @@ +##### +# First, rules intended to apply in all subdirectories. +# These contain no slash, or only a trailing slash. + +*.cover +*.iml +*.o +*.lto +*.a +*.so +*.so.* +*.dylib +*.dSYM +*.dll +*.wasm +*.orig +*.pyc +*.pyd +*.pyo +*.rej +*.swp +*~ +*.gc?? +*.profclang? +*.profraw +# Copies of binaries before BOLT optimizations. +*.prebolt +# BOLT profile data. +*.fdata +*.dyn +.gdb_history +.purify +__pycache__ +.hg/ +.svn/ +.idea/ +tags +TAGS +.vs/ +.vscode/ +gmon.out +.coverage +.mypy_cache/ +.pytest_cache/ +.DS_Store + +*.exe + +# Ignore core dumps... but not Tools/msi/core/ or the like. +core +!core/ + + +##### +# Then, rules meant for a specific location relative to the repo root. +# These must contain a non-trailing slash (and may also have a trailing slash.) + +Doc/build/ +Doc/venv/ +Doc/.venv/ +Doc/env/ +Doc/.env/ +Include/pydtrace_probes.h +Lib/lib2to3/*.pickle +Lib/site-packages/* +!Lib/site-packages/README.txt +Lib/test/data/* +!Lib/test/data/README +/_bootstrap_python +/Makefile +/Makefile.pre +Mac/Makefile +Mac/PythonLauncher/Info.plist +Mac/PythonLauncher/Makefile +Mac/PythonLauncher/Python Launcher +Mac/PythonLauncher/Python Launcher.app/* +Mac/Resources/app/Info.plist +Mac/Resources/framework/Info.plist +Mac/pythonw +/*.framework/ +Misc/python.pc +Misc/python-embed.pc +Misc/python-config.sh +Modules/Setup.bootstrap +Modules/Setup.config +Modules/Setup.local +Modules/Setup.stdlib +Modules/config.c +Modules/ld_so_aix +Programs/_freeze_module +Programs/_testembed +PC/python_nt*.h +PC/pythonnt_rc*.h +Modules/python.exp +PC/*/*.exp +PC/*/*.lib +PC/*/*.bsc +PC/*/*.dll +PC/*/*.pdb +PC/*/*.user +PC/*/*.ncb +PC/*/*.suo +PC/*/Win32-temp-* +PC/*/x64-temp-* +PC/*/amd64 +PCbuild/*.user +PCbuild/*.suo +PCbuild/*.*sdf +PCbuild/*-pgi +PCbuild/*-pgo +PCbuild/*.VC.db +PCbuild/*.VC.opendb +PCbuild/amd64/ +PCbuild/arm32/ +PCbuild/arm64/ +PCbuild/obj/ +PCbuild/win32/ +Tools/unicode/data/ +/autom4te.cache +/build/ +/builddir/ +/config.cache +/config.log +/config.status +/config.status.lineno +# hendrikmuhs/ccache-action@v1 +/.ccache +/platform +/profile-clean-stamp +/profile-run-stamp +/profile-bolt-stamp +/Python/deepfreeze/*.c +/pybuilddir.txt +/pyconfig.h +/python-config +/python-config.py +/python.bat +/python-gdb.py +/python.exe-gdb.py +/reflog.txt +/coverage/ +/externals/ +/htmlcov/ +Tools/msi/obj +Tools/ssl/amd64 +Tools/ssl/win32 +Tools/freeze/test/outdir + +# The frozen modules are always generated by the build so we don't +# keep them in the repo. Also see Tools/build/freeze_modules.py. +Python/frozen_modules/*.h +# The manifest can be generated at any time with "make regen-frozen". +Python/frozen_modules/MANIFEST + +# Two-trick pony for OSX and other case insensitive file systems: +# Ignore ./python binary on Unix but still look into ./Python/ directory. +/python +!/Python/ diff --git a/.mailmap b/.mailmap new file mode 100644 index 00000000..013c839e --- /dev/null +++ b/.mailmap @@ -0,0 +1,3 @@ +# This file sets the canonical name for contributors to the repository. +# Documentation: https://git-scm.com/docs/gitmailmap +Amethyst Reese diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 00000000..19f6a037 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,28 @@ +repos: + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.0.288 + hooks: + - id: ruff + name: Run Ruff on Lib/test/ + args: [--exit-non-zero-on-fix] + files: ^Lib/test/ + + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.4.0 + hooks: + - id: check-toml + exclude: ^Lib/test/test_tomllib/ + - id: check-yaml + - id: end-of-file-fixer + types: [python] + exclude: Lib/test/coding20731.py + - id: trailing-whitespace + types_or: [c, python, rst] + + - repo: https://github.com/sphinx-contrib/sphinx-lint + rev: v0.6.8 + hooks: + - id: sphinx-lint + args: [--enable=default-role] + files: ^Doc/|^Misc/NEWS.d/next/ + types: [rst] diff --git a/.readthedocs.yml b/.readthedocs.yml new file mode 100644 index 00000000..898a9ae8 --- /dev/null +++ b/.readthedocs.yml @@ -0,0 +1,18 @@ +# Read the Docs configuration file +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details +# Project page: https://readthedocs.org/projects/cpython-previews/ + +version: 2 + +sphinx: + configuration: Doc/conf.py + +build: + os: ubuntu-22.04 + tools: + python: "3" + + commands: + - make -C Doc venv html + - mkdir _readthedocs + - mv Doc/build/html _readthedocs/html diff --git a/Doc/Makefile b/Doc/Makefile index 1814d4e8..22691895 100644 --- a/Doc/Makefile +++ b/Doc/Makefile @@ -13,6 +13,7 @@ JOBS = auto PAPER = SOURCES = DISTVERSION = $(shell $(PYTHON) tools/extensions/patchlevel.py) +REQUIREMENTS = requirements.txt SPHINXERRORHANDLING = -W # Internal variables. @@ -22,10 +23,7 @@ PAPEROPT_letter = -D latex_elements.papersize=letterpaper ALLSPHINXOPTS = -b $(BUILDER) -d build/doctrees $(PAPEROPT_$(PAPER)) -j $(JOBS) \ $(SPHINXOPTS) $(SPHINXERRORHANDLING) . build/$(BUILDER) $(SOURCES) -.PHONY: help build html htmlhelp latex text texinfo changes linkcheck \ - suspicious coverage doctest pydoc-topics htmlview clean dist check serve \ - autobuild-dev autobuild-stable venv - +.PHONY: help help: @echo "Please use \`make ' where is one of" @echo " clean to remove build files" @@ -43,9 +41,9 @@ help: @echo " doctest to run doctests in the documentation" @echo " pydoc-topics to regenerate the pydoc topics file" @echo " dist to create a \"dist\" directory with archived docs for download" - @echo " suspicious to check for suspicious markup in output text" @echo " check to run a check for frequent markup errors" +.PHONY: build build: -mkdir -p build # Look first for a Misc/NEWS file (building from a source release tarball @@ -72,38 +70,46 @@ build: $(SPHINXBUILD) $(ALLSPHINXOPTS) @echo +.PHONY: html html: BUILDER = html html: build @echo "Build finished. The HTML pages are in build/html." +.PHONY: htmlhelp htmlhelp: BUILDER = htmlhelp htmlhelp: build @echo "Build finished; now you can run HTML Help Workshop with the" \ "build/htmlhelp/pydoc.hhp project file." +.PHONY: latex latex: BUILDER = latex latex: build @echo "Build finished; the LaTeX files are in build/latex." @echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \ "run these through (pdf)latex." +.PHONY: text text: BUILDER = text text: build @echo "Build finished; the text files are in build/text." +.PHONY: texinfo texinfo: BUILDER = texinfo texinfo: build @echo "Build finished; the python.texi file is in build/texinfo." @echo "Run \`make info' in that directory to run it through makeinfo." +.PHONY: epub epub: BUILDER = epub epub: build @echo "Build finished; the epub files are in build/epub." +.PHONY: changes changes: BUILDER = changes changes: build @echo "The overview file is in build/changes." +.PHONY: linkcheck linkcheck: BUILDER = linkcheck linkcheck: @$(MAKE) build BUILDER=$(BUILDER) || { \ @@ -111,22 +117,12 @@ linkcheck: "or in build/$(BUILDER)/output.txt"; \ false; } -suspicious: BUILDER = suspicious -suspicious: - @$(MAKE) build BUILDER=$(BUILDER) || { \ - echo "Suspicious check complete; look for any errors in the above output" \ - "or in build/$(BUILDER)/suspicious.csv. If all issues are false" \ - "positives, append that file to tools/susp-ignored.csv."; \ - false; } - @echo "⚠ make suspicious is deprecated and will be removed soon." - @echo "⚠ Use:" - @echo "⚠ make check" - @echo "⚠ instead." - +.PHONY: coverage coverage: BUILDER = coverage coverage: build @echo "Coverage finished; see c.txt and python.txt in build/coverage" +.PHONY: doctest doctest: BUILDER = doctest doctest: @$(MAKE) build BUILDER=$(BUILDER) || { \ @@ -134,31 +130,37 @@ doctest: "results in build/doctest/output.txt"; \ false; } +.PHONY: pydoc-topics pydoc-topics: BUILDER = pydoc-topics pydoc-topics: build @echo "Building finished; now run this:" \ "cp build/pydoc-topics/topics.py ../Lib/pydoc_data/topics.py" +.PHONY: htmlview htmlview: html $(PYTHON) -c "import os, webbrowser; webbrowser.open('file://' + os.path.realpath('build/html/index.html'))" +.PHONY: clean clean: clean-venv -rm -rf build/* +.PHONY: clean-venv clean-venv: rm -rf $(VENVDIR) +.PHONY: venv venv: @if [ -d $(VENVDIR) ] ; then \ echo "venv already exists."; \ echo "To recreate it, remove it first with \`make clean-venv'."; \ else \ $(PYTHON) -m venv $(VENVDIR); \ - $(VENVDIR)/bin/python3 -m pip install -U pip setuptools; \ - $(VENVDIR)/bin/python3 -m pip install -r requirements.txt; \ + $(VENVDIR)/bin/python3 -m pip install --upgrade pip; \ + $(VENVDIR)/bin/python3 -m pip install -r $(REQUIREMENTS); \ echo "The venv has been created in the $(VENVDIR) directory"; \ fi +.PHONY: dist dist: rm -rf dist mkdir -p dist @@ -213,12 +215,12 @@ dist: rm -r dist/python-$(DISTVERSION)-docs-texinfo rm dist/python-$(DISTVERSION)-docs-texinfo.tar -check: - # Check the docs and NEWS files with sphinx-lint. - # Ignore the tools and venv dirs and check that the default role is not used. - $(SPHINXLINT) -i tools -i $(VENVDIR) --enable default-role - $(SPHINXLINT) --enable default-role ../Misc/NEWS.d/next/ +.PHONY: check +check: venv + $(VENVDIR)/bin/python3 -m pre_commit --version > /dev/null || $(VENVDIR)/bin/python3 -m pip install pre-commit + $(VENVDIR)/bin/python3 -m pre_commit run --all-files +.PHONY: serve serve: @echo "The serve target was removed, use htmlview instead (see bpo-36329)" @@ -230,15 +232,18 @@ serve: # output files) # for development releases: always build +.PHONY: autobuild-dev autobuild-dev: make dist SPHINXOPTS='$(SPHINXOPTS) -Ea -A daily=1' # for quick rebuilds (HTML only) +.PHONY: autobuild-dev-html autobuild-dev-html: make html SPHINXOPTS='$(SPHINXOPTS) -Ea -A daily=1' # for stable releases: only build if not in pre-release stage (alpha, beta) # release candidate downloads are okay, since the stable tree can be in that stage +.PHONY: autobuild-stable autobuild-stable: @case $(DISTVERSION) in *[ab]*) \ echo "Not building; $(DISTVERSION) is not a release version."; \ @@ -246,6 +251,7 @@ autobuild-stable: esac @make autobuild-dev +.PHONY: autobuild-stable-html autobuild-stable-html: @case $(DISTVERSION) in *[ab]*) \ echo "Not building; $(DISTVERSION) is not a release version."; \ diff --git a/Doc/README.rst b/Doc/README.rst index d67cad79..a3bb5fa5 100644 --- a/Doc/README.rst +++ b/Doc/README.rst @@ -93,9 +93,6 @@ Available make targets are: plain text documentation for the labels defined in ``tools/pyspecific.py`` -- pydoc needs these to show topic and keyword help. -* "suspicious", which checks the parsed markup for text that looks like - malformed and thus unconverted reST. - * "check", which checks for frequent markup errors. * "serve", which serves the build/html directory on port 8000. diff --git a/Doc/bugs.rst b/Doc/bugs.rst index 4f30ef19..d98192b3 100644 --- a/Doc/bugs.rst +++ b/Doc/bugs.rst @@ -70,7 +70,7 @@ Click on the "New issue" button in the top bar to report a new issue. The submission form has two fields, "Title" and "Comment". For the "Title" field, enter a *very* short description of the problem; -less than ten words is good. +fewer than ten words is good. In the "Comment" field, describe the problem in detail, including what you expected to happen and what did happen. Be sure to include whether any diff --git a/Doc/c-api/allocation.rst b/Doc/c-api/allocation.rst index 0a8fcc5a..b3609c23 100644 --- a/Doc/c-api/allocation.rst +++ b/Doc/c-api/allocation.rst @@ -27,22 +27,26 @@ Allocating Objects on the Heap length information for a variable-size object. -.. c:function:: TYPE* PyObject_New(TYPE, PyTypeObject *type) +.. c:macro:: PyObject_New(TYPE, typeobj) - Allocate a new Python object using the C structure type *TYPE* and the - Python type object *type*. Fields not defined by the Python object header - are not initialized; the object's reference count will be one. The size of - the memory allocation is determined from the :c:member:`~PyTypeObject.tp_basicsize` field of - the type object. + Allocate a new Python object using the C structure type *TYPE* + and the Python type object *typeobj* (``PyTypeObject*``). + Fields not defined by the Python object header are not initialized. + The caller will own the only reference to the object + (i.e. its reference count will be one). + The size of the memory allocation is determined from the + :c:member:`~PyTypeObject.tp_basicsize` field of the type object. -.. c:function:: TYPE* PyObject_NewVar(TYPE, PyTypeObject *type, Py_ssize_t size) +.. c:macro:: PyObject_NewVar(TYPE, typeobj, size) Allocate a new Python object using the C structure type *TYPE* and the - Python type object *type*. Fields not defined by the Python object header + Python type object *typeobj* (``PyTypeObject*``). + Fields not defined by the Python object header are not initialized. The allocated memory allows for the *TYPE* structure - plus *size* fields of the size given by the :c:member:`~PyTypeObject.tp_itemsize` field of - *type*. This is useful for implementing objects like tuples, which are + plus *size* (``Py_ssize_t``) fields of the size + given by the :c:member:`~PyTypeObject.tp_itemsize` field of + *typeobj*. This is useful for implementing objects like tuples, which are able to determine their size at construction time. Embedding the array of fields into the same allocation decreases the number of allocations, improving the memory management efficiency. @@ -50,8 +54,8 @@ Allocating Objects on the Heap .. c:function:: void PyObject_Del(void *op) - Releases memory allocated to an object using :c:func:`PyObject_New` or - :c:func:`PyObject_NewVar`. This is normally called from the + Releases memory allocated to an object using :c:macro:`PyObject_New` or + :c:macro:`PyObject_NewVar`. This is normally called from the :c:member:`~PyTypeObject.tp_dealloc` handler specified in the object's type. The fields of the object should not be accessed after this call as the memory is no longer a valid Python object. diff --git a/Doc/c-api/apiabiversion.rst b/Doc/c-api/apiabiversion.rst index 62d54296..f6c8284d 100644 --- a/Doc/c-api/apiabiversion.rst +++ b/Doc/c-api/apiabiversion.rst @@ -60,7 +60,7 @@ See :ref:`stable` for a discussion of API and ABI stability across versions. Use this for numeric comparisons, e.g. ``#if PY_VERSION_HEX >= ...``. - This version is also available via the symbol :data:`Py_Version`. + This version is also available via the symbol :c:var:`Py_Version`. .. c:var:: const unsigned long Py_Version diff --git a/Doc/c-api/arg.rst b/Doc/c-api/arg.rst index 6a53c79b..657b10d3 100644 --- a/Doc/c-api/arg.rst +++ b/Doc/c-api/arg.rst @@ -152,48 +152,6 @@ There are three ways strings and buffers can be converted to C: attempting any conversion. Raises :exc:`TypeError` if the object is not a :class:`bytearray` object. The C variable may also be declared as :c:expr:`PyObject*`. -``u`` (:class:`str`) [const Py_UNICODE \*] - Convert a Python Unicode object to a C pointer to a NUL-terminated buffer of - Unicode characters. You must pass the address of a :c:type:`Py_UNICODE` - pointer variable, which will be filled with the pointer to an existing - Unicode buffer. Please note that the width of a :c:type:`Py_UNICODE` - character depends on compilation options (it is either 16 or 32 bits). - The Python string must not contain embedded null code points; if it does, - a :exc:`ValueError` exception is raised. - - .. versionchanged:: 3.5 - Previously, :exc:`TypeError` was raised when embedded null code points - were encountered in the Python string. - - .. deprecated-removed:: 3.3 3.12 - Part of the old-style :c:type:`Py_UNICODE` API; please migrate to using - :c:func:`PyUnicode_AsWideCharString`. - -``u#`` (:class:`str`) [const Py_UNICODE \*, :c:type:`Py_ssize_t`] - This variant on ``u`` stores into two C variables, the first one a pointer to a - Unicode data buffer, the second one its length. This variant allows - null code points. - - .. deprecated-removed:: 3.3 3.12 - Part of the old-style :c:type:`Py_UNICODE` API; please migrate to using - :c:func:`PyUnicode_AsWideCharString`. - -``Z`` (:class:`str` or ``None``) [const Py_UNICODE \*] - Like ``u``, but the Python object may also be ``None``, in which case the - :c:type:`Py_UNICODE` pointer is set to ``NULL``. - - .. deprecated-removed:: 3.3 3.12 - Part of the old-style :c:type:`Py_UNICODE` API; please migrate to using - :c:func:`PyUnicode_AsWideCharString`. - -``Z#`` (:class:`str` or ``None``) [const Py_UNICODE \*, :c:type:`Py_ssize_t`] - Like ``u#``, but the Python object may also be ``None``, in which case the - :c:type:`Py_UNICODE` pointer is set to ``NULL``. - - .. deprecated-removed:: 3.3 3.12 - Part of the old-style :c:type:`Py_UNICODE` API; please migrate to using - :c:func:`PyUnicode_AsWideCharString`. - ``U`` (:class:`str`) [PyObject \*] Requires that the Python object is a Unicode object, without attempting any conversion. Raises :exc:`TypeError` if the object is not a Unicode @@ -263,6 +221,11 @@ There are three ways strings and buffers can be converted to C: them. Instead, the implementation assumes that the byte string object uses the encoding passed in as parameter. +.. versionchanged:: 3.12 + ``u``, ``u#``, ``Z``, and ``Z#`` are removed because they used a legacy + ``Py_UNICODE*`` representation. + + Numbers ------- @@ -330,8 +293,10 @@ Other objects ``O`` (object) [PyObject \*] Store a Python object (without any conversion) in a C object pointer. The C - program thus receives the actual object that was passed. The object's reference - count is not increased. The pointer stored is not ``NULL``. + program thus receives the actual object that was passed. A new + :term:`strong reference` to the object is not created + (i.e. its reference count is not increased). + The pointer stored is not ``NULL``. ``O!`` (object) [*typeobject*, PyObject \*] Store a Python object in a C object pointer. This is similar to ``O``, but @@ -380,7 +345,7 @@ Other objects *items*. Format units for sequences may be nested. It is possible to pass "long" integers (integers whose value exceeds the -platform's :const:`LONG_MAX`) however no proper range checking is done --- the +platform's :c:macro:`LONG_MAX`) however no proper range checking is done --- the most significant bits are silently truncated when the receiving field is too small to receive the value (actually, the semantics are inherited from downcasts in C --- your mileage may vary). @@ -415,7 +380,8 @@ inside nested parentheses. They are: mutually exclude each other. Note that any Python object references which are provided to the caller are -*borrowed* references; do not decrement their reference count! +*borrowed* references; do not release them +(i.e. do not decrement their reference count)! Additional arguments passed to these functions must be addresses of variables whose type is determined by the format string; these are used to store values @@ -492,7 +458,7 @@ API Functions A simpler form of parameter retrieval which does not use a format string to specify the types of the arguments. Functions which use this method to retrieve - their parameters should be declared as :const:`METH_VARARGS` in function or + their parameters should be declared as :c:macro:`METH_VARARGS` in function or method tables. The tuple containing the actual parameters should be passed as *args*; it must actually be a tuple. The length of the tuple must be at least *min* and no more than *max*; *min* and *max* may be equal. Additional @@ -506,7 +472,7 @@ API Functions will be set if there was a failure. This is an example of the use of this function, taken from the sources for the - :mod:`_weakref` helper module for weak references:: + :mod:`!_weakref` helper module for weak references:: static PyObject * weakref_ref(PyObject *self, PyObject *args) @@ -584,7 +550,7 @@ Building values Same as ``s#``. ``u`` (:class:`str`) [const wchar_t \*] - Convert a null-terminated :c:expr:`wchar_t` buffer of Unicode (UTF-16 or UCS-4) + Convert a null-terminated :c:type:`wchar_t` buffer of Unicode (UTF-16 or UCS-4) data to a Python Unicode object. If the Unicode buffer pointer is ``NULL``, ``None`` is returned. @@ -650,8 +616,10 @@ Building values Convert a C :c:type:`Py_complex` structure to a Python complex number. ``O`` (object) [PyObject \*] - Pass a Python object untouched (except for its reference count, which is - incremented by one). If the object passed in is a ``NULL`` pointer, it is assumed + Pass a Python object untouched but create a new + :term:`strong reference` to it + (i.e. its reference count is incremented by one). + If the object passed in is a ``NULL`` pointer, it is assumed that this was caused because the call producing the argument found an error and set an exception. Therefore, :c:func:`Py_BuildValue` will return ``NULL`` but won't raise an exception. If no exception has been raised yet, :exc:`SystemError` is @@ -661,7 +629,7 @@ Building values Same as ``O``. ``N`` (object) [PyObject \*] - Same as ``O``, except it doesn't increment the reference count on the object. + Same as ``O``, except it doesn't create a new :term:`strong reference`. Useful when the object is created by a call to an object constructor in the argument list. diff --git a/Doc/c-api/bool.rst b/Doc/c-api/bool.rst index c197d447..b14fa6a0 100644 --- a/Doc/c-api/bool.rst +++ b/Doc/c-api/bool.rst @@ -6,11 +6,17 @@ Boolean Objects --------------- Booleans in Python are implemented as a subclass of integers. There are only -two booleans, :const:`Py_False` and :const:`Py_True`. As such, the normal +two booleans, :c:data:`Py_False` and :c:data:`Py_True`. As such, the normal creation and deletion functions don't apply to booleans. The following macros are available, however. +.. c:var:: PyTypeObject PyBool_Type + + This instance of :c:type:`PyTypeObject` represents the Python boolean type; it + is the same object as :class:`bool` in the Python layer. + + .. c:function:: int PyBool_Check(PyObject *o) Return true if *o* is of type :c:data:`PyBool_Type`. This function always @@ -19,29 +25,32 @@ are available, however. .. c:var:: PyObject* Py_False - The Python ``False`` object. This object has no methods. It needs to be - treated just like any other object with respect to reference counts. + The Python ``False`` object. This object has no methods and is + `immortal `_. + +.. versionchanged:: 3.12 + :c:data:`Py_False` is immortal. .. c:var:: PyObject* Py_True - The Python ``True`` object. This object has no methods. It needs to be treated - just like any other object with respect to reference counts. + The Python ``True`` object. This object has no methods and is + `immortal `_. + +.. versionchanged:: 3.12 + :c:data:`Py_True` is immortal. .. c:macro:: Py_RETURN_FALSE - Return :const:`Py_False` from a function, properly incrementing its reference - count. + Return :c:data:`Py_False` from a function. .. c:macro:: Py_RETURN_TRUE - Return :const:`Py_True` from a function, properly incrementing its reference - count. + Return :c:data:`Py_True` from a function. .. c:function:: PyObject* PyBool_FromLong(long v) - Return a new reference to :const:`Py_True` or :const:`Py_False` depending on the - truth value of *v*. + Return :c:data:`Py_True` or :c:data:`Py_False`, depending on the truth value of *v*. diff --git a/Doc/c-api/buffer.rst b/Doc/c-api/buffer.rst index a04062fb..e572815f 100644 --- a/Doc/c-api/buffer.rst +++ b/Doc/c-api/buffer.rst @@ -44,7 +44,7 @@ the elements exposed by an :class:`array.array` can be multi-byte values. An example consumer of the buffer interface is the :meth:`~io.BufferedIOBase.write` method of file objects: any object that can export a series of bytes through -the buffer interface can be written to a file. While :meth:`write` only +the buffer interface can be written to a file. While :meth:`!write` only needs read-only access to the internal contents of the object passed to it, other methods such as :meth:`~io.BufferedIOBase.readinto` need write access to the contents of their argument. The buffer interface allows objects to @@ -102,7 +102,9 @@ a buffer, see :c:func:`PyObject_GetBuffer`. .. c:member:: PyObject *obj A new reference to the exporting object. The reference is owned by - the consumer and automatically decremented and set to ``NULL`` by + the consumer and automatically released + (i.e. reference count decremented) + and set to ``NULL`` by :c:func:`PyBuffer_Release`. The field is the equivalent of the return value of any standard C-API function. @@ -159,10 +161,7 @@ a buffer, see :c:func:`PyObject_GetBuffer`. If it is ``0``, :c:member:`~Py_buffer.buf` points to a single item representing a scalar. In this case, :c:member:`~Py_buffer.shape`, :c:member:`~Py_buffer.strides` and :c:member:`~Py_buffer.suboffsets` MUST be ``NULL``. - - The macro :c:macro:`PyBUF_MAX_NDIM` limits the maximum number of dimensions - to 64. Exporters MUST respect this limit, consumers of multi-dimensional - buffers SHOULD be able to handle up to :c:macro:`PyBUF_MAX_NDIM` dimensions. + The maximum number of dimensions is given by :c:macro:`PyBUF_MAX_NDIM`. .. c:member:: Py_ssize_t *shape @@ -215,6 +214,17 @@ a buffer, see :c:func:`PyObject_GetBuffer`. freed when the buffer is released. The consumer MUST NOT alter this value. + +Constants: + +.. c:macro:: PyBUF_MAX_NDIM + + The maximum number of dimensions the memory represents. + Exporters MUST respect this limit, consumers of multi-dimensional + buffers SHOULD be able to handle up to :c:macro:`!PyBUF_MAX_NDIM` dimensions. + Currently set to 64. + + .. _buffer-request-types: Buffer request types @@ -225,7 +235,7 @@ object via :c:func:`PyObject_GetBuffer`. Since the complexity of the logical structure of the memory can vary drastically, the consumer uses the *flags* argument to specify the exact buffer type it can handle. -All :c:data:`Py_buffer` fields are unambiguously defined by the request +All :c:type:`Py_buffer` fields are unambiguously defined by the request type. request-independent fields @@ -438,7 +448,7 @@ Buffer-related functions Send a request to *exporter* to fill in *view* as specified by *flags*. If the exporter cannot provide a buffer of the exact type, it MUST raise - :c:data:`PyExc_BufferError`, set ``view->obj`` to ``NULL`` and + :exc:`BufferError`, set ``view->obj`` to ``NULL`` and return ``-1``. On success, fill in *view*, set ``view->obj`` to a new reference @@ -454,7 +464,8 @@ Buffer-related functions .. c:function:: void PyBuffer_Release(Py_buffer *view) - Release the buffer *view* and decrement the reference count for + Release the buffer *view* and release the :term:`strong reference` + (i.e. decrement the reference count) to the view's supporting object, ``view->obj``. This function MUST be called when the buffer is no longer being used, otherwise reference leaks may occur. @@ -464,7 +475,7 @@ Buffer-related functions .. c:function:: Py_ssize_t PyBuffer_SizeFromFormat(const char *format) - Return the implied :c:data:`~Py_buffer.itemsize` from :c:data:`~Py_buffer.format`. + Return the implied :c:member:`~Py_buffer.itemsize` from :c:member:`~Py_buffer.format`. On error, raise an exception and return -1. .. versionadded:: 3.9 @@ -499,7 +510,7 @@ Buffer-related functions This function fails if *len* != *src->len*. -.. c:function:: int PyObject_CopyData(Py_buffer *dest, Py_buffer *src) +.. c:function:: int PyObject_CopyData(PyObject *dest, PyObject *src) Copy data from *src* to *dest* buffer. Can convert between C-style and or Fortran-style buffers. @@ -524,7 +535,7 @@ Buffer-related functions and :c:macro:`PyBUF_WRITABLE` is set in *flags*. On success, set ``view->obj`` to a new reference to *exporter* and - return 0. Otherwise, raise :c:data:`PyExc_BufferError`, set + return 0. Otherwise, raise :exc:`BufferError`, set ``view->obj`` to ``NULL`` and return ``-1``; If this function is used as part of a :ref:`getbufferproc `, diff --git a/Doc/c-api/bytearray.rst b/Doc/c-api/bytearray.rst index 4bf3cfe1..456f7d89 100644 --- a/Doc/c-api/bytearray.rst +++ b/Doc/c-api/bytearray.rst @@ -5,7 +5,7 @@ Byte Array Objects ------------------ -.. index:: object: bytearray +.. index:: pair: object; bytearray .. c:type:: PyByteArrayObject diff --git a/Doc/c-api/bytes.rst b/Doc/c-api/bytes.rst index 7617487a..61a68f52 100644 --- a/Doc/c-api/bytes.rst +++ b/Doc/c-api/bytes.rst @@ -8,7 +8,7 @@ Bytes Objects These functions raise :exc:`TypeError` when expecting a bytes parameter and called with a non-bytes parameter. -.. index:: object: bytes +.. index:: pair: object; bytes .. c:type:: PyBytesObject @@ -58,48 +58,45 @@ called with a non-bytes parameter. .. % XXX: This should be exactly the same as the table in PyErr_Format. .. % One should just refer to the other. - .. % XXX: The descriptions for %zd and %zu are wrong, but the truth is complicated - .. % because not all compilers support the %z width modifier -- we fake it - .. % when necessary via interpolating PY_FORMAT_SIZE_T. .. tabularcolumns:: |l|l|L| +-------------------+---------------+--------------------------------+ | Format Characters | Type | Comment | +===================+===============+================================+ - | :attr:`%%` | *n/a* | The literal % character. | + | ``%%`` | *n/a* | The literal % character. | +-------------------+---------------+--------------------------------+ - | :attr:`%c` | int | A single byte, | + | ``%c`` | int | A single byte, | | | | represented as a C int. | +-------------------+---------------+--------------------------------+ - | :attr:`%d` | int | Equivalent to | + | ``%d`` | int | Equivalent to | | | | ``printf("%d")``. [1]_ | +-------------------+---------------+--------------------------------+ - | :attr:`%u` | unsigned int | Equivalent to | + | ``%u`` | unsigned int | Equivalent to | | | | ``printf("%u")``. [1]_ | +-------------------+---------------+--------------------------------+ - | :attr:`%ld` | long | Equivalent to | + | ``%ld`` | long | Equivalent to | | | | ``printf("%ld")``. [1]_ | +-------------------+---------------+--------------------------------+ - | :attr:`%lu` | unsigned long | Equivalent to | + | ``%lu`` | unsigned long | Equivalent to | | | | ``printf("%lu")``. [1]_ | +-------------------+---------------+--------------------------------+ - | :attr:`%zd` | :c:type:`\ | Equivalent to | + | ``%zd`` | :c:type:`\ | Equivalent to | | | Py_ssize_t` | ``printf("%zd")``. [1]_ | +-------------------+---------------+--------------------------------+ - | :attr:`%zu` | size_t | Equivalent to | + | ``%zu`` | size_t | Equivalent to | | | | ``printf("%zu")``. [1]_ | +-------------------+---------------+--------------------------------+ - | :attr:`%i` | int | Equivalent to | + | ``%i`` | int | Equivalent to | | | | ``printf("%i")``. [1]_ | +-------------------+---------------+--------------------------------+ - | :attr:`%x` | int | Equivalent to | + | ``%x`` | int | Equivalent to | | | | ``printf("%x")``. [1]_ | +-------------------+---------------+--------------------------------+ - | :attr:`%s` | const char\* | A null-terminated C character | + | ``%s`` | const char\* | A null-terminated C character | | | | array. | +-------------------+---------------+--------------------------------+ - | :attr:`%p` | const void\* | The hex representation of a C | + | ``%p`` | const void\* | The hex representation of a C | | | | pointer. Mostly equivalent to | | | | ``printf("%p")`` except that | | | | it is guaranteed to start with | @@ -187,8 +184,8 @@ called with a non-bytes parameter. .. c:function:: void PyBytes_ConcatAndDel(PyObject **bytes, PyObject *newpart) Create a new bytes object in *\*bytes* containing the contents of *newpart* - appended to *bytes*. This version decrements the reference count of - *newpart*. + appended to *bytes*. This version releases the :term:`strong reference` + to *newpart* (i.e. decrements its reference count). .. c:function:: int _PyBytes_Resize(PyObject **bytes, Py_ssize_t newsize) diff --git a/Doc/c-api/call.rst b/Doc/c-api/call.rst index 36149f15..f4e40144 100644 --- a/Doc/c-api/call.rst +++ b/Doc/c-api/call.rst @@ -57,13 +57,22 @@ This bears repeating: A class supporting vectorcall **must** also implement :c:member:`~PyTypeObject.tp_call` with the same semantics. +.. versionchanged:: 3.12 + + The :c:macro:`Py_TPFLAGS_HAVE_VECTORCALL` flag is now removed from a class + when the class's :py:meth:`~object.__call__` method is reassigned. + (This internally sets :c:member:`~PyTypeObject.tp_call` only, and thus + may make it behave differently than the vectorcall function.) + In earlier Python versions, vectorcall should only be used with + :c:macro:`immutable ` or static types. + A class should not implement vectorcall if that would be slower than *tp_call*. For example, if the callee needs to convert the arguments to an args tuple and kwargs dict anyway, then there is no point in implementing vectorcall. Classes can implement the vectorcall protocol by enabling the -:const:`Py_TPFLAGS_HAVE_VECTORCALL` flag and setting +:c:macro:`Py_TPFLAGS_HAVE_VECTORCALL` flag and setting :c:member:`~PyTypeObject.tp_vectorcall_offset` to the offset inside the object structure where a *vectorcallfunc* appears. This is a pointer to a function with the following signature: @@ -75,7 +84,7 @@ This is a pointer to a function with the following signature: values of the keyword arguments. This can be *NULL* if there are no arguments. - *nargsf* is the number of positional arguments plus possibly the - :const:`PY_VECTORCALL_ARGUMENTS_OFFSET` flag. + :c:macro:`PY_VECTORCALL_ARGUMENTS_OFFSET` flag. To get the actual number of positional arguments from *nargsf*, use :c:func:`PyVectorcall_NARGS`. - *kwnames* is a tuple containing the names of the keyword arguments; @@ -95,7 +104,7 @@ This is a pointer to a function with the following signature: ``args[0]`` may be changed. Whenever they can do so cheaply (without additional allocation), callers - are encouraged to use :const:`PY_VECTORCALL_ARGUMENTS_OFFSET`. + are encouraged to use :c:macro:`PY_VECTORCALL_ARGUMENTS_OFFSET`. Doing so will allow callables such as bound methods to make their onward calls (which include a prepended *self* argument) very efficiently. @@ -156,7 +165,7 @@ Vectorcall Support API This is mostly useful to check whether or not *op* supports vectorcall, which can be done by checking ``PyVectorcall_Function(op) != NULL``. - .. versionadded:: 3.8 + .. versionadded:: 3.9 .. c:function:: PyObject* PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *dict) @@ -165,7 +174,7 @@ Vectorcall Support API This is a specialized function, intended to be put in the :c:member:`~PyTypeObject.tp_call` slot or be used in an implementation of ``tp_call``. - It does not check the :const:`Py_TPFLAGS_HAVE_VECTORCALL` flag + It does not check the :c:macro:`Py_TPFLAGS_HAVE_VECTORCALL` flag and it does not fall back to ``tp_call``. .. versionadded:: 3.8 @@ -383,11 +392,11 @@ please see individual documentation for details. *args[0]*, and the *args* array starting at *args[1]* represents the arguments of the call. There must be at least one positional argument. *nargsf* is the number of positional arguments including *args[0]*, - plus :const:`PY_VECTORCALL_ARGUMENTS_OFFSET` if the value of ``args[0]`` may + plus :c:macro:`PY_VECTORCALL_ARGUMENTS_OFFSET` if the value of ``args[0]`` may temporarily be changed. Keyword arguments can be passed just like in :c:func:`PyObject_Vectorcall`. - If the object has the :const:`Py_TPFLAGS_METHOD_DESCRIPTOR` feature, + If the object has the :c:macro:`Py_TPFLAGS_METHOD_DESCRIPTOR` feature, this will call the unbound method object with the full *args* vector as arguments. diff --git a/Doc/c-api/capsule.rst b/Doc/c-api/capsule.rst index 1c8f4325..cdb8aa33 100644 --- a/Doc/c-api/capsule.rst +++ b/Doc/c-api/capsule.rst @@ -5,7 +5,7 @@ Capsules -------- -.. index:: object: Capsule +.. index:: pair: object; Capsule Refer to :ref:`using-capsules` for more information on using these objects. @@ -64,7 +64,7 @@ Refer to :ref:`using-capsules` for more information on using these objects. The *name* parameter must compare exactly to the name stored in the capsule. If the name stored in the capsule is ``NULL``, the *name* passed in must also - be ``NULL``. Python uses the C function :c:func:`strcmp` to compare capsule + be ``NULL``. Python uses the C function :c:func:`!strcmp` to compare capsule names. @@ -121,7 +121,7 @@ Refer to :ref:`using-capsules` for more information on using these objects. compared.) In other words, if :c:func:`PyCapsule_IsValid` returns a true value, calls to - any of the accessors (any function starting with :c:func:`PyCapsule_Get`) are + any of the accessors (any function starting with ``PyCapsule_Get``) are guaranteed to succeed. Return a nonzero value if the object is valid and matches the name passed in. diff --git a/Doc/c-api/cell.rst b/Doc/c-api/cell.rst index ac4ef5ad..f8cd0344 100644 --- a/Doc/c-api/cell.rst +++ b/Doc/c-api/cell.rst @@ -25,7 +25,7 @@ Cell objects are not likely to be useful elsewhere. The type object corresponding to cell objects. -.. c:function:: int PyCell_Check(ob) +.. c:function:: int PyCell_Check(PyObject *ob) Return true if *ob* is a cell object; *ob* must not be ``NULL``. This function always succeeds. diff --git a/Doc/c-api/code.rst b/Doc/c-api/code.rst index ee39f2ae..5082b0cb 100644 --- a/Doc/c-api/code.rst +++ b/Doc/c-api/code.rst @@ -33,27 +33,46 @@ bound into a function. Return the number of free variables in *co*. -.. c:function:: PyCodeObject* PyCode_New(int argcount, int kwonlyargcount, int nlocals, int stacksize, int flags, PyObject *code, PyObject *consts, PyObject *names, PyObject *varnames, PyObject *freevars, PyObject *cellvars, PyObject *filename, PyObject *name, int firstlineno, PyObject *linetable, PyObject *exceptiontable) +.. c:function:: PyCodeObject* PyUnstable_Code_New(int argcount, int kwonlyargcount, int nlocals, int stacksize, int flags, PyObject *code, PyObject *consts, PyObject *names, PyObject *varnames, PyObject *freevars, PyObject *cellvars, PyObject *filename, PyObject *name, PyObject *qualname, int firstlineno, PyObject *linetable, PyObject *exceptiontable) Return a new code object. If you need a dummy code object to create a frame, - use :c:func:`PyCode_NewEmpty` instead. Calling :c:func:`PyCode_New` directly - will bind you to a precise Python version since the definition of the bytecode - changes often. The many arguments of this function are inter-dependent in complex + use :c:func:`PyCode_NewEmpty` instead. + + Since the definition of the bytecode changes often, calling + :c:func:`PyUnstable_Code_New` directly can bind you to a precise Python version. + + The many arguments of this function are inter-dependent in complex ways, meaning that subtle changes to values are likely to result in incorrect execution or VM crashes. Use this function only with extreme care. .. versionchanged:: 3.11 - Added ``exceptiontable`` parameter. + Added ``qualname`` and ``exceptiontable`` parameters. + + .. index:: single: PyCode_New + + .. versionchanged:: 3.12 -.. c:function:: PyCodeObject* PyCode_NewWithPosOnlyArgs(int argcount, int posonlyargcount, int kwonlyargcount, int nlocals, int stacksize, int flags, PyObject *code, PyObject *consts, PyObject *names, PyObject *varnames, PyObject *freevars, PyObject *cellvars, PyObject *filename, PyObject *name, int firstlineno, PyObject *linetable, PyObject *exceptiontable) + Renamed from ``PyCode_New`` as part of :ref:`unstable-c-api`. + The old name is deprecated, but will remain available until the + signature changes again. - Similar to :c:func:`PyCode_New`, but with an extra "posonlyargcount" for positional-only arguments. - The same caveats that apply to ``PyCode_New`` also apply to this function. +.. c:function:: PyCodeObject* PyUnstable_Code_NewWithPosOnlyArgs(int argcount, int posonlyargcount, int kwonlyargcount, int nlocals, int stacksize, int flags, PyObject *code, PyObject *consts, PyObject *names, PyObject *varnames, PyObject *freevars, PyObject *cellvars, PyObject *filename, PyObject *name, PyObject *qualname, int firstlineno, PyObject *linetable, PyObject *exceptiontable) - .. versionadded:: 3.8 + Similar to :c:func:`PyUnstable_Code_New`, but with an extra "posonlyargcount" for positional-only arguments. + The same caveats that apply to ``PyUnstable_Code_New`` also apply to this function. + + .. index:: single: PyCode_NewWithPosOnlyArgs + + .. versionadded:: 3.8 as ``PyCode_NewWithPosOnlyArgs`` .. versionchanged:: 3.11 - Added ``exceptiontable`` parameter. + Added ``qualname`` and ``exceptiontable`` parameters. + + .. versionchanged:: 3.12 + + Renamed to ``PyUnstable_Code_NewWithPosOnlyArgs``. + The old name is deprecated, but will remain available until the + signature changes again. .. c:function:: PyCodeObject* PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno) @@ -117,3 +136,129 @@ bound into a function. the free variables. On error, ``NULL`` is returned and an exception is raised. .. versionadded:: 3.11 + +.. c:function:: int PyCode_AddWatcher(PyCode_WatchCallback callback) + + Register *callback* as a code object watcher for the current interpreter. + Return an ID which may be passed to :c:func:`PyCode_ClearWatcher`. + In case of error (e.g. no more watcher IDs available), + return ``-1`` and set an exception. + + .. versionadded:: 3.12 + +.. c:function:: int PyCode_ClearWatcher(int watcher_id) + + Clear watcher identified by *watcher_id* previously returned from + :c:func:`PyCode_AddWatcher` for the current interpreter. + Return ``0`` on success, or ``-1`` and set an exception on error + (e.g. if the given *watcher_id* was never registered.) + + .. versionadded:: 3.12 + +.. c:type:: PyCodeEvent + + Enumeration of possible code object watcher events: + - ``PY_CODE_EVENT_CREATE`` + - ``PY_CODE_EVENT_DESTROY`` + + .. versionadded:: 3.12 + +.. c:type:: int (*PyCode_WatchCallback)(PyCodeEvent event, PyCodeObject* co) + + Type of a code object watcher callback function. + + If *event* is ``PY_CODE_EVENT_CREATE``, then the callback is invoked + after `co` has been fully initialized. Otherwise, the callback is invoked + before the destruction of *co* takes place, so the prior state of *co* + can be inspected. + + If *event* is ``PY_CODE_EVENT_DESTROY``, taking a reference in the callback + to the about-to-be-destroyed code object will resurrect it and prevent it + from being freed at this time. When the resurrected object is destroyed + later, any watcher callbacks active at that time will be called again. + + Users of this API should not rely on internal runtime implementation + details. Such details may include, but are not limited to, the exact + order and timing of creation and destruction of code objects. While + changes in these details may result in differences observable by watchers + (including whether a callback is invoked or not), it does not change + the semantics of the Python code being executed. + + If the callback sets an exception, it must return ``-1``; this exception will + be printed as an unraisable exception using :c:func:`PyErr_WriteUnraisable`. + Otherwise it should return ``0``. + + There may already be a pending exception set on entry to the callback. In + this case, the callback should return ``0`` with the same exception still + set. This means the callback may not call any other API that can set an + exception unless it saves and clears the exception state first, and restores + it before returning. + + .. versionadded:: 3.12 + + +Extra information +----------------- + +To support low-level extensions to frame evaluation, such as external +just-in-time compilers, it is possible to attach arbitrary extra data to +code objects. + +These functions are part of the unstable C API tier: +this functionality is a CPython implementation detail, and the API +may change without deprecation warnings. + +.. c:function:: Py_ssize_t PyUnstable_Eval_RequestCodeExtraIndex(freefunc free) + + Return a new an opaque index value used to adding data to code objects. + + You generally call this function once (per interpreter) and use the result + with ``PyCode_GetExtra`` and ``PyCode_SetExtra`` to manipulate + data on individual code objects. + + If *free* is not ``NULL``: when a code object is deallocated, + *free* will be called on non-``NULL`` data stored under the new index. + Use :c:func:`Py_DecRef` when storing :c:type:`PyObject`. + + .. index:: single: _PyEval_RequestCodeExtraIndex + + .. versionadded:: 3.6 as ``_PyEval_RequestCodeExtraIndex`` + + .. versionchanged:: 3.12 + + Renamed to ``PyUnstable_Eval_RequestCodeExtraIndex``. + The old private name is deprecated, but will be available until the API + changes. + +.. c:function:: int PyUnstable_Code_GetExtra(PyObject *code, Py_ssize_t index, void **extra) + + Set *extra* to the extra data stored under the given index. + Return 0 on success. Set an exception and return -1 on failure. + + If no data was set under the index, set *extra* to ``NULL`` and return + 0 without setting an exception. + + .. index:: single: _PyCode_GetExtra + + .. versionadded:: 3.6 as ``_PyCode_GetExtra`` + + .. versionchanged:: 3.12 + + Renamed to ``PyUnstable_Code_GetExtra``. + The old private name is deprecated, but will be available until the API + changes. + +.. c:function:: int PyUnstable_Code_SetExtra(PyObject *code, Py_ssize_t index, void *extra) + + Set the extra data stored under the given index to *extra*. + Return 0 on success. Set an exception and return -1 on failure. + + .. index:: single: _PyCode_SetExtra + + .. versionadded:: 3.6 as ``_PyCode_SetExtra`` + + .. versionchanged:: 3.12 + + Renamed to ``PyUnstable_Code_SetExtra``. + The old private name is deprecated, but will be available until the API + changes. diff --git a/Doc/c-api/codec.rst b/Doc/c-api/codec.rst index 235c77c9..8ae5c4fe 100644 --- a/Doc/c-api/codec.rst +++ b/Doc/c-api/codec.rst @@ -7,7 +7,7 @@ Codec registry and support functions Register a new codec search function. - As side effect, this tries to load the :mod:`encodings` package, if not yet + As side effect, this tries to load the :mod:`!encodings` package, if not yet done, to make sure that it is always first in the list of search functions. .. c:function:: int PyCodec_Unregister(PyObject *search_function) diff --git a/Doc/c-api/complex.rst b/Doc/c-api/complex.rst index 9228ce85..e3fd001c 100644 --- a/Doc/c-api/complex.rst +++ b/Doc/c-api/complex.rst @@ -5,7 +5,7 @@ Complex Number Objects ---------------------- -.. index:: object: complex number +.. index:: pair: object; complex number Python's complex number objects are implemented as two distinct types when viewed from the C API: one is the Python object exposed to Python programs, and @@ -64,7 +64,7 @@ pointers. This is consistent throughout the API. representation. If *divisor* is null, this method returns zero and sets - :c:data:`errno` to :c:data:`EDOM`. + :c:data:`errno` to :c:macro:`!EDOM`. .. c:function:: Py_complex _Py_c_pow(Py_complex num, Py_complex exp) @@ -73,7 +73,7 @@ pointers. This is consistent throughout the API. representation. If *num* is null and *exp* is not a positive real number, - this method returns zero and sets :c:data:`errno` to :c:data:`EDOM`. + this method returns zero and sets :c:data:`errno` to :c:macro:`!EDOM`. Complex Numbers as Python Objects @@ -127,12 +127,12 @@ Complex Numbers as Python Objects Return the :c:type:`Py_complex` value of the complex number *op*. - If *op* is not a Python complex number object but has a :meth:`__complex__` + If *op* is not a Python complex number object but has a :meth:`~object.__complex__` method, this method will first be called to convert *op* to a Python complex - number object. If ``__complex__()`` is not defined then it falls back to - :meth:`__float__`. If ``__float__()`` is not defined then it falls back - to :meth:`__index__`. Upon failure, this method returns ``-1.0`` as a real + number object. If :meth:`!__complex__` is not defined then it falls back to + :meth:`~object.__float__`. If :meth:`!__float__` is not defined then it falls back + to :meth:`~object.__index__`. Upon failure, this method returns ``-1.0`` as a real value. .. versionchanged:: 3.8 - Use :meth:`__index__` if available. + Use :meth:`~object.__index__` if available. diff --git a/Doc/c-api/concrete.rst b/Doc/c-api/concrete.rst index 8d3124a1..880f7b15 100644 --- a/Doc/c-api/concrete.rst +++ b/Doc/c-api/concrete.rst @@ -40,7 +40,7 @@ This section describes Python type objects and the singleton object ``None``. Numeric Objects =============== -.. index:: object: numeric +.. index:: pair: object; numeric .. toctree:: @@ -55,7 +55,7 @@ Numeric Objects Sequence Objects ================ -.. index:: object: sequence +.. index:: pair: object; sequence Generic operations on sequence objects were discussed in the previous chapter; this section deals with the specific kinds of sequence objects that are @@ -77,7 +77,7 @@ intrinsic to the Python language. Container Objects ================= -.. index:: object: mapping +.. index:: pair: object; mapping .. toctree:: diff --git a/Doc/c-api/conversion.rst b/Doc/c-api/conversion.rst index fdb321fe..c5350123 100644 --- a/Doc/c-api/conversion.rst +++ b/Doc/c-api/conversion.rst @@ -119,10 +119,10 @@ The following functions provide locale-independent string to number conversions. .. c:function:: int PyOS_stricmp(const char *s1, const char *s2) Case insensitive comparison of strings. The function works almost - identically to :c:func:`strcmp` except that it ignores the case. + identically to :c:func:`!strcmp` except that it ignores the case. .. c:function:: int PyOS_strnicmp(const char *s1, const char *s2, Py_ssize_t size) Case insensitive comparison of strings. The function works almost - identically to :c:func:`strncmp` except that it ignores the case. + identically to :c:func:`!strncmp` except that it ignores the case. diff --git a/Doc/c-api/datetime.rst b/Doc/c-api/datetime.rst index 72fc07af..97522da7 100644 --- a/Doc/c-api/datetime.rst +++ b/Doc/c-api/datetime.rst @@ -8,11 +8,54 @@ DateTime Objects Various date and time objects are supplied by the :mod:`datetime` module. Before using any of these functions, the header file :file:`datetime.h` must be included in your source (note that this is not included by :file:`Python.h`), -and the macro :c:macro:`PyDateTime_IMPORT` must be invoked, usually as part of +and the macro :c:macro:`!PyDateTime_IMPORT` must be invoked, usually as part of the module initialisation function. The macro puts a pointer to a C structure -into a static variable, :c:data:`PyDateTimeAPI`, that is used by the following +into a static variable, :c:data:`!PyDateTimeAPI`, that is used by the following macros. +.. c:type:: PyDateTime_Date + + This subtype of :c:type:`PyObject` represents a Python date object. + +.. c:type:: PyDateTime_DateTime + + This subtype of :c:type:`PyObject` represents a Python datetime object. + +.. c:type:: PyDateTime_Time + + This subtype of :c:type:`PyObject` represents a Python time object. + +.. c:type:: PyDateTime_Delta + + This subtype of :c:type:`PyObject` represents the difference between two datetime values. + +.. c:var:: PyTypeObject PyDateTime_DateType + + This instance of :c:type:`PyTypeObject` represents the Python date type; + it is the same object as :class:`datetime.date` in the Python layer. + +.. c:var:: PyTypeObject PyDateTime_DateTimeType + + This instance of :c:type:`PyTypeObject` represents the Python datetime type; + it is the same object as :class:`datetime.datetime` in the Python layer. + +.. c:var:: PyTypeObject PyDateTime_TimeType + + This instance of :c:type:`PyTypeObject` represents the Python time type; + it is the same object as :class:`datetime.time` in the Python layer. + +.. c:var:: PyTypeObject PyDateTime_DeltaType + + This instance of :c:type:`PyTypeObject` represents Python type for + the difference between two datetime values; + it is the same object as :class:`datetime.timedelta` in the Python layer. + +.. c:var:: PyTypeObject PyDateTime_TZInfoType + + This instance of :c:type:`PyTypeObject` represents the Python time zone info type; + it is the same object as :class:`datetime.tzinfo` in the Python layer. + + Macro for access to the UTC singleton: .. c:var:: PyObject* PyDateTime_TimeZone_UTC @@ -28,7 +71,7 @@ Type-check macros: .. c:function:: int PyDate_Check(PyObject *ob) Return true if *ob* is of type :c:data:`PyDateTime_DateType` or a subtype of - :c:data:`PyDateTime_DateType`. *ob* must not be ``NULL``. This function always + :c:data:`!PyDateTime_DateType`. *ob* must not be ``NULL``. This function always succeeds. @@ -41,7 +84,7 @@ Type-check macros: .. c:function:: int PyDateTime_Check(PyObject *ob) Return true if *ob* is of type :c:data:`PyDateTime_DateTimeType` or a subtype of - :c:data:`PyDateTime_DateTimeType`. *ob* must not be ``NULL``. This function always + :c:data:`!PyDateTime_DateTimeType`. *ob* must not be ``NULL``. This function always succeeds. @@ -54,7 +97,7 @@ Type-check macros: .. c:function:: int PyTime_Check(PyObject *ob) Return true if *ob* is of type :c:data:`PyDateTime_TimeType` or a subtype of - :c:data:`PyDateTime_TimeType`. *ob* must not be ``NULL``. This function always + :c:data:`!PyDateTime_TimeType`. *ob* must not be ``NULL``. This function always succeeds. @@ -67,7 +110,7 @@ Type-check macros: .. c:function:: int PyDelta_Check(PyObject *ob) Return true if *ob* is of type :c:data:`PyDateTime_DeltaType` or a subtype of - :c:data:`PyDateTime_DeltaType`. *ob* must not be ``NULL``. This function always + :c:data:`!PyDateTime_DeltaType`. *ob* must not be ``NULL``. This function always succeeds. @@ -80,7 +123,7 @@ Type-check macros: .. c:function:: int PyTZInfo_Check(PyObject *ob) Return true if *ob* is of type :c:data:`PyDateTime_TZInfoType` or a subtype of - :c:data:`PyDateTime_TZInfoType`. *ob* must not be ``NULL``. This function always + :c:data:`!PyDateTime_TZInfoType`. *ob* must not be ``NULL``. This function always succeeds. @@ -133,7 +176,7 @@ Macros to create objects: :class:`datetime.timedelta` objects. -.. c:function:: PyObject* PyTimeZone_FromOffset(PyDateTime_DeltaType* offset) +.. c:function:: PyObject* PyTimeZone_FromOffset(PyObject *offset) Return a :class:`datetime.timezone` object with an unnamed fixed offset represented by the *offset* argument. @@ -141,7 +184,7 @@ Macros to create objects: .. versionadded:: 3.7 -.. c:function:: PyObject* PyTimeZone_FromOffsetAndName(PyDateTime_DeltaType* offset, PyUnicode* name) +.. c:function:: PyObject* PyTimeZone_FromOffsetAndName(PyObject *offset, PyObject *name) Return a :class:`datetime.timezone` object with a fixed offset represented by the *offset* argument and with tzname *name*. @@ -150,8 +193,8 @@ Macros to create objects: Macros to extract fields from date objects. The argument must be an instance of -:c:data:`PyDateTime_Date`, including subclasses (such as -:c:data:`PyDateTime_DateTime`). The argument must not be ``NULL``, and the type is +:c:type:`PyDateTime_Date`, including subclasses (such as +:c:type:`PyDateTime_DateTime`). The argument must not be ``NULL``, and the type is not checked: .. c:function:: int PyDateTime_GET_YEAR(PyDateTime_Date *o) @@ -170,7 +213,7 @@ not checked: Macros to extract fields from datetime objects. The argument must be an -instance of :c:data:`PyDateTime_DateTime`, including subclasses. The argument +instance of :c:type:`PyDateTime_DateTime`, including subclasses. The argument must not be ``NULL``, and the type is not checked: .. c:function:: int PyDateTime_DATE_GET_HOUR(PyDateTime_DateTime *o) @@ -208,7 +251,7 @@ must not be ``NULL``, and the type is not checked: Macros to extract fields from time objects. The argument must be an instance of -:c:data:`PyDateTime_Time`, including subclasses. The argument must not be ``NULL``, +:c:type:`PyDateTime_Time`, including subclasses. The argument must not be ``NULL``, and the type is not checked: .. c:function:: int PyDateTime_TIME_GET_HOUR(PyDateTime_Time *o) @@ -246,7 +289,7 @@ and the type is not checked: Macros to extract fields from time delta objects. The argument must be an -instance of :c:data:`PyDateTime_Delta`, including subclasses. The argument must +instance of :c:type:`PyDateTime_Delta`, including subclasses. The argument must not be ``NULL``, and the type is not checked: .. c:function:: int PyDateTime_DELTA_GET_DAYS(PyDateTime_Delta *o) diff --git a/Doc/c-api/dict.rst b/Doc/c-api/dict.rst index 819168d4..5ccbfe64 100644 --- a/Doc/c-api/dict.rst +++ b/Doc/c-api/dict.rst @@ -5,7 +5,7 @@ Dictionary Objects ------------------ -.. index:: object: dictionary +.. index:: pair: object; dictionary .. c:type:: PyDictObject @@ -70,17 +70,14 @@ Dictionary Objects .. c:function:: int PyDict_SetItemString(PyObject *p, const char *key, PyObject *val) - .. index:: single: PyUnicode_FromString() - - Insert *val* into the dictionary *p* using *key* as a key. *key* should - be a :c:expr:`const char*`. The key object is created using - ``PyUnicode_FromString(key)``. Return ``0`` on success or ``-1`` on - failure. This function *does not* steal a reference to *val*. + This is the same as :c:func:`PyDict_SetItem`, but *key* is + specified as a :c:expr:`const char*` UTF-8 encoded bytes string, + rather than a :c:expr:`PyObject*`. .. c:function:: int PyDict_DelItem(PyObject *p, PyObject *key) - Remove the entry in dictionary *p* with key *key*. *key* must be hashable; + Remove the entry in dictionary *p* with key *key*. *key* must be :term:`hashable`; if it isn't, :exc:`TypeError` is raised. If *key* is not in the dictionary, :exc:`KeyError` is raised. Return ``0`` on success or ``-1`` on failure. @@ -88,9 +85,9 @@ Dictionary Objects .. c:function:: int PyDict_DelItemString(PyObject *p, const char *key) - Remove the entry in dictionary *p* which has a key specified by the string *key*. - If *key* is not in the dictionary, :exc:`KeyError` is raised. - Return ``0`` on success or ``-1`` on failure. + This is the same as :c:func:`PyDict_DelItem`, but *key* is + specified as a :c:expr:`const char*` UTF-8 encoded bytes string, + rather than a :c:expr:`PyObject*`. .. c:function:: PyObject* PyDict_GetItem(PyObject *p, PyObject *key) @@ -98,9 +95,11 @@ Dictionary Objects Return the object from dictionary *p* which has a key *key*. Return ``NULL`` if the key *key* is not present, but *without* setting an exception. - Note that exceptions which occur while calling :meth:`__hash__` and - :meth:`__eq__` methods will get suppressed. - To get error reporting use :c:func:`PyDict_GetItemWithError()` instead. + .. note:: + + Exceptions that occur while this calls :meth:`~object.__hash__` and + :meth:`~object.__eq__` methods are silently ignored. + Prefer the :c:func:`PyDict_GetItemWithError` function instead. .. versionchanged:: 3.10 Calling this API without :term:`GIL` held had been allowed for historical @@ -118,12 +117,16 @@ Dictionary Objects .. c:function:: PyObject* PyDict_GetItemString(PyObject *p, const char *key) This is the same as :c:func:`PyDict_GetItem`, but *key* is specified as a - :c:expr:`const char*`, rather than a :c:expr:`PyObject*`. + :c:expr:`const char*` UTF-8 encoded bytes string, rather than a + :c:expr:`PyObject*`. - Note that exceptions which occur while calling :meth:`__hash__` and - :meth:`__eq__` methods and creating a temporary string object - will get suppressed. - To get error reporting use :c:func:`PyDict_GetItemWithError()` instead. + .. note:: + + Exceptions that occur while this calls :meth:`~object.__hash__` and + :meth:`~object.__eq__` methods or while creating the temporary :class:`str` + object are silently ignored. + Prefer using the :c:func:`PyDict_GetItemWithError` function with your own + :c:func:`PyUnicode_FromString` *key* instead. .. c:function:: PyObject* PyDict_SetDefault(PyObject *p, PyObject *key, PyObject *defaultobj) @@ -154,7 +157,7 @@ Dictionary Objects .. c:function:: Py_ssize_t PyDict_Size(PyObject *p) - .. index:: builtin: len + .. index:: pair: built-in function; len Return the number of items in the dictionary. This is equivalent to ``len(p)`` on a dictionary. @@ -238,3 +241,86 @@ Dictionary Objects for key, value in seq2: if override or key not in a: a[key] = value + +.. c:function:: int PyDict_AddWatcher(PyDict_WatchCallback callback) + + Register *callback* as a dictionary watcher. Return a non-negative integer + id which must be passed to future calls to :c:func:`PyDict_Watch`. In case + of error (e.g. no more watcher IDs available), return ``-1`` and set an + exception. + + .. versionadded:: 3.12 + +.. c:function:: int PyDict_ClearWatcher(int watcher_id) + + Clear watcher identified by *watcher_id* previously returned from + :c:func:`PyDict_AddWatcher`. Return ``0`` on success, ``-1`` on error (e.g. + if the given *watcher_id* was never registered.) + + .. versionadded:: 3.12 + +.. c:function:: int PyDict_Watch(int watcher_id, PyObject *dict) + + Mark dictionary *dict* as watched. The callback granted *watcher_id* by + :c:func:`PyDict_AddWatcher` will be called when *dict* is modified or + deallocated. Return ``0`` on success or ``-1`` on error. + + .. versionadded:: 3.12 + +.. c:function:: int PyDict_Unwatch(int watcher_id, PyObject *dict) + + Mark dictionary *dict* as no longer watched. The callback granted + *watcher_id* by :c:func:`PyDict_AddWatcher` will no longer be called when + *dict* is modified or deallocated. The dict must previously have been + watched by this watcher. Return ``0`` on success or ``-1`` on error. + + .. versionadded:: 3.12 + +.. c:type:: PyDict_WatchEvent + + Enumeration of possible dictionary watcher events: ``PyDict_EVENT_ADDED``, + ``PyDict_EVENT_MODIFIED``, ``PyDict_EVENT_DELETED``, ``PyDict_EVENT_CLONED``, + ``PyDict_EVENT_CLEARED``, or ``PyDict_EVENT_DEALLOCATED``. + + .. versionadded:: 3.12 + +.. c:type:: int (*PyDict_WatchCallback)(PyDict_WatchEvent event, PyObject *dict, PyObject *key, PyObject *new_value) + + Type of a dict watcher callback function. + + If *event* is ``PyDict_EVENT_CLEARED`` or ``PyDict_EVENT_DEALLOCATED``, both + *key* and *new_value* will be ``NULL``. If *event* is ``PyDict_EVENT_ADDED`` + or ``PyDict_EVENT_MODIFIED``, *new_value* will be the new value for *key*. + If *event* is ``PyDict_EVENT_DELETED``, *key* is being deleted from the + dictionary and *new_value* will be ``NULL``. + + ``PyDict_EVENT_CLONED`` occurs when *dict* was previously empty and another + dict is merged into it. To maintain efficiency of this operation, per-key + ``PyDict_EVENT_ADDED`` events are not issued in this case; instead a + single ``PyDict_EVENT_CLONED`` is issued, and *key* will be the source + dictionary. + + The callback may inspect but must not modify *dict*; doing so could have + unpredictable effects, including infinite recursion. Do not trigger Python + code execution in the callback, as it could modify the dict as a side effect. + + If *event* is ``PyDict_EVENT_DEALLOCATED``, taking a new reference in the + callback to the about-to-be-destroyed dictionary will resurrect it and + prevent it from being freed at this time. When the resurrected object is + destroyed later, any watcher callbacks active at that time will be called + again. + + Callbacks occur before the notified modification to *dict* takes place, so + the prior state of *dict* can be inspected. + + If the callback sets an exception, it must return ``-1``; this exception will + be printed as an unraisable exception using :c:func:`PyErr_WriteUnraisable`. + Otherwise it should return ``0``. + + There may already be a pending exception set on entry to the callback. In + this case, the callback should return ``0`` with the same exception still + set. This means the callback may not call any other API that can set an + exception unless it saves and clears the exception state first, and restores + it before returning. + + .. versionadded:: 3.12 diff --git a/Doc/c-api/exceptions.rst b/Doc/c-api/exceptions.rst index 087e0a61..6e2ac0a4 100644 --- a/Doc/c-api/exceptions.rst +++ b/Doc/c-api/exceptions.rst @@ -60,9 +60,14 @@ Printing and clearing Call this function **only** when the error indicator is set. Otherwise it will cause a fatal error! - If *set_sys_last_vars* is nonzero, the variables :data:`sys.last_type`, - :data:`sys.last_value` and :data:`sys.last_traceback` will be set to the - type, value and traceback of the printed exception, respectively. + If *set_sys_last_vars* is nonzero, the variable :data:`sys.last_exc` is + set to the printed exception. For backwards compatibility, the + deprecated variables :data:`sys.last_type`, :data:`sys.last_value` and + :data:`sys.last_traceback` are also set to the type, value and traceback + of this exception, respectively. + + .. versionchanged:: 3.12 + The setting of :data:`sys.last_exc` was added. .. c:function:: void PyErr_Print() @@ -78,7 +83,7 @@ Printing and clearing This utility function prints a warning message to ``sys.stderr`` when an exception has been set but it is impossible for the interpreter to actually raise the exception. It is used, for example, when an exception occurs in an - :meth:`__del__` method. + :meth:`~object.__del__` method. The function is called with a single argument *obj* that identifies the context in which the unraisable exception occurred. If possible, @@ -86,6 +91,12 @@ Printing and clearing An exception must be set when calling this function. +.. c:function:: void PyErr_DisplayException(PyObject *exc) + + Print the standard traceback display of ``exc`` to ``sys.stderr``, including + chained exceptions and notes. + + .. versionadded:: 3.12 Raising exceptions ================== @@ -99,7 +110,8 @@ For convenience, some of these functions will always return a This is the most common way to set the error indicator. The first argument specifies the exception type; it is normally one of the standard exceptions, - e.g. :c:data:`PyExc_RuntimeError`. You need not increment its reference count. + e.g. :c:data:`PyExc_RuntimeError`. You need not create a new + :term:`strong reference` to it (e.g. with :c:func:`Py_INCREF`). The second argument is an error message; it is decoded from ``'utf-8'``. @@ -152,9 +164,9 @@ For convenience, some of these functions will always return a This is a convenience function to raise an exception when a C library function has returned an error and set the C variable :c:data:`errno`. It constructs a tuple object whose first item is the integer :c:data:`errno` value and whose - second item is the corresponding error message (gotten from :c:func:`strerror`), + second item is the corresponding error message (gotten from :c:func:`!strerror`), and then calls ``PyErr_SetObject(type, object)``. On Unix, when the - :c:data:`errno` value is :const:`EINTR`, indicating an interrupted system call, + :c:data:`errno` value is :c:macro:`!EINTR`, indicating an interrupted system call, this calls :c:func:`PyErr_CheckSignals`, and if that set the error indicator, leaves it set to that. The function always returns ``NULL``, so a wrapper function around a system call can write ``return PyErr_SetFromErrno(type);`` @@ -166,7 +178,7 @@ For convenience, some of these functions will always return a Similar to :c:func:`PyErr_SetFromErrno`, with the additional behavior that if *filenameObject* is not ``NULL``, it is passed to the constructor of *type* as a third parameter. In the case of :exc:`OSError` exception, - this is used to define the :attr:`filename` attribute of the + this is used to define the :attr:`!filename` attribute of the exception instance. @@ -189,12 +201,12 @@ For convenience, some of these functions will always return a .. c:function:: PyObject* PyErr_SetFromWindowsErr(int ierr) This is a convenience function to raise :exc:`WindowsError`. If called with - *ierr* of ``0``, the error code returned by a call to :c:func:`GetLastError` - is used instead. It calls the Win32 function :c:func:`FormatMessage` to retrieve - the Windows description of error code given by *ierr* or :c:func:`GetLastError`, + *ierr* of ``0``, the error code returned by a call to :c:func:`!GetLastError` + is used instead. It calls the Win32 function :c:func:`!FormatMessage` to retrieve + the Windows description of error code given by *ierr* or :c:func:`!GetLastError`, then it constructs a tuple object whose first item is the *ierr* value and whose second item is the corresponding error message (gotten from - :c:func:`FormatMessage`), and then calls ``PyErr_SetObject(PyExc_WindowsError, + :c:func:`!FormatMessage`), and then calls ``PyErr_SetObject(PyExc_WindowsError, object)``. This function always returns ``NULL``. .. availability:: Windows. @@ -210,17 +222,21 @@ For convenience, some of these functions will always return a .. c:function:: PyObject* PyErr_SetFromWindowsErrWithFilename(int ierr, const char *filename) - Similar to :c:func:`PyErr_SetFromWindowsErrWithFilenameObject`, but the - filename is given as a C string. *filename* is decoded from the filesystem - encoding (:func:`os.fsdecode`). + Similar to :c:func:`PyErr_SetFromWindowsErr`, with the additional behavior + that if *filename* is not ``NULL``, it is decoded from the filesystem + encoding (:func:`os.fsdecode`) and passed to the constructor of + :exc:`OSError` as a third parameter to be used to define the + :attr:`!filename` attribute of the exception instance. .. availability:: Windows. .. c:function:: PyObject* PyErr_SetExcFromWindowsErrWithFilenameObject(PyObject *type, int ierr, PyObject *filename) - Similar to :c:func:`PyErr_SetFromWindowsErrWithFilenameObject`, with an - additional parameter specifying the exception type to be raised. + Similar to :c:func:`PyErr_SetExcFromWindowsErr`, with the additional behavior + that if *filename* is not ``NULL``, it is passed to the constructor of + :exc:`OSError` as a third parameter to be used to define the + :attr:`!filename` attribute of the exception instance. .. availability:: Windows. @@ -400,8 +416,48 @@ Querying the error indicator recursively in subtuples) are searched for a match. +.. c:function:: PyObject *PyErr_GetRaisedException(void) + + Return the exception currently being raised, clearing the error indicator at + the same time. + + This function is used by code that needs to catch exceptions, + or code that needs to save and restore the error indicator temporarily. + + For example:: + + { + PyObject *exc = PyErr_GetRaisedException(); + + /* ... code that might produce other errors ... */ + + PyErr_SetRaisedException(exc); + } + + .. seealso:: :c:func:`PyErr_GetHandledException`, + to save the exception currently being handled. + + .. versionadded:: 3.12 + + +.. c:function:: void PyErr_SetRaisedException(PyObject *exc) + + Set *exc* as the exception currently being raised, + clearing the existing exception if one is set. + + .. warning:: + + This call steals a reference to *exc*, which must be a valid exception. + + .. versionadded:: 3.12 + + .. c:function:: void PyErr_Fetch(PyObject **ptype, PyObject **pvalue, PyObject **ptraceback) + .. deprecated:: 3.12 + + Use :c:func:`PyErr_GetRaisedException` instead. + Retrieve the error indicator into three variables whose addresses are passed. If the error indicator is not set, set all three variables to ``NULL``. If it is set, it will be cleared and you own a reference to each object retrieved. The @@ -409,8 +465,10 @@ Querying the error indicator .. note:: - This function is normally only used by code that needs to catch exceptions or - by code that needs to save and restore the error indicator temporarily, e.g.:: + This function is normally only used by legacy code that needs to catch + exceptions or save and restore the error indicator temporarily. + + For example:: { PyObject *type, *value, *traceback; @@ -424,8 +482,14 @@ Querying the error indicator .. c:function:: void PyErr_Restore(PyObject *type, PyObject *value, PyObject *traceback) - Set the error indicator from the three objects. If the error indicator is - already set, it is cleared first. If the objects are ``NULL``, the error + .. deprecated:: 3.12 + + Use :c:func:`PyErr_SetRaisedException` instead. + + Set the error indicator from the three objects, + *type*, *value*, and *traceback*, + clearing the existing exception if one is set. + If the objects are ``NULL``, the error indicator is cleared. Do not pass a ``NULL`` type and non-``NULL`` value or traceback. The exception type should be a class. Do not pass an invalid exception type or value. (Violating these rules will cause subtle problems @@ -436,13 +500,18 @@ Querying the error indicator .. note:: - This function is normally only used by code that needs to save and restore the - error indicator temporarily. Use :c:func:`PyErr_Fetch` to save the current - error indicator. + This function is normally only used by legacy code that needs to + save and restore the error indicator temporarily. + Use :c:func:`PyErr_Fetch` to save the current error indicator. .. c:function:: void PyErr_NormalizeException(PyObject **exc, PyObject **val, PyObject **tb) + .. deprecated:: 3.12 + + Use :c:func:`PyErr_GetRaisedException` instead, + to avoid any possible de-normalization. + Under certain circumstances, the values returned by :c:func:`PyErr_Fetch` below can be "unnormalized", meaning that ``*exc`` is a class object but ``*val`` is not an instance of the same class. This function can be used to instantiate @@ -543,7 +612,7 @@ Signal Handling .. c:function:: int PyErr_CheckSignals() .. index:: - module: signal + pair: module; signal single: SIGINT single: KeyboardInterrupt (built-in exception) @@ -567,18 +636,18 @@ Signal Handling be interruptible by user requests (such as by pressing Ctrl-C). .. note:: - The default Python signal handler for :const:`SIGINT` raises the + The default Python signal handler for :c:macro:`!SIGINT` raises the :exc:`KeyboardInterrupt` exception. .. c:function:: void PyErr_SetInterrupt() .. index:: - module: signal + pair: module; signal single: SIGINT single: KeyboardInterrupt (built-in exception) - Simulate the effect of a :const:`SIGINT` signal arriving. + Simulate the effect of a :c:macro:`!SIGINT` signal arriving. This is equivalent to ``PyErr_SetInterruptEx(SIGINT)``. .. note:: @@ -589,7 +658,7 @@ Signal Handling .. c:function:: int PyErr_SetInterruptEx(int signum) .. index:: - module: signal + pair: module; signal single: KeyboardInterrupt (built-in exception) Simulate the effect of a signal arriving. The next time @@ -602,7 +671,7 @@ Signal Handling to interrupt an operation). If the given signal isn't handled by Python (it was set to - :data:`signal.SIG_DFL` or :data:`signal.SIG_IGN`), it will be ignored. + :py:const:`signal.SIG_DFL` or :py:const:`signal.SIG_IGN`), it will be ignored. If *signum* is outside of the allowed range of signal numbers, ``-1`` is returned. Otherwise, ``0`` is returned. The error indicator is @@ -690,7 +759,7 @@ Exception Objects .. c:function:: PyObject* PyException_GetCause(PyObject *ex) - Return the cause (either an exception instance, or :const:`None`, + Return the cause (either an exception instance, or ``None``, set by ``raise ... from ...``) associated with the exception as a new reference, as accessible from Python through :attr:`__cause__`. @@ -699,11 +768,33 @@ Exception Objects Set the cause associated with the exception to *cause*. Use ``NULL`` to clear it. There is no type check to make sure that *cause* is either an exception - instance or :const:`None`. This steals a reference to *cause*. + instance or ``None``. This steals a reference to *cause*. :attr:`__suppress_context__` is implicitly set to ``True`` by this function. +.. c:function:: PyObject* PyException_GetArgs(PyObject *ex) + + Return :attr:`~BaseException.args` of exception *ex*. + + +.. c:function:: void PyException_SetArgs(PyObject *ex, PyObject *args) + + Set :attr:`~BaseException.args` of exception *ex* to *args*. + +.. c:function:: PyObject* PyUnstable_Exc_PrepReraiseStar(PyObject *orig, PyObject *excs) + + Implement part of the interpreter's implementation of :keyword:`!except*`. + *orig* is the original exception that was caught, and *excs* is the list of + the exceptions that need to be raised. This list contains the the unhandled + part of *orig*, if any, as well as the exceptions that were raised from the + :keyword:`!except*` clauses (so they have a different traceback from *orig*) and + those that were reraised (and have the same traceback as *orig*). + Return the :exc:`ExceptionGroup` that needs to be reraised in the end, or + ``None`` if there is nothing to reraise. + + .. versionadded:: 3.12 + .. _unicodeexceptions: Unicode Exception Objects @@ -788,7 +879,7 @@ because the :ref:`call protocol ` takes care of recursion handling. Marks a point where a recursive C-level call is about to be performed. - If :const:`USE_STACKCHECK` is defined, this function checks if the OS + If :c:macro:`USE_STACKCHECK` is defined, this function checks if the OS stack overflowed using :c:func:`PyOS_CheckStack`. In this is the case, it sets a :exc:`MemoryError` and returns a nonzero value. @@ -801,7 +892,7 @@ because the :ref:`call protocol ` takes care of recursion handling. depth limit. .. versionchanged:: 3.9 - This function is now also available in the limited API. + This function is now also available in the :ref:`limited API `. .. c:function:: void Py_LeaveRecursiveCall(void) @@ -809,7 +900,7 @@ because the :ref:`call protocol ` takes care of recursion handling. *successful* invocation of :c:func:`Py_EnterRecursiveCall`. .. versionchanged:: 3.9 - This function is now also available in the limited API. + This function is now also available in the :ref:`limited API `. Properly implementing :c:member:`~PyTypeObject.tp_repr` for container types requires special recursion handling. In addition to protecting the stack, diff --git a/Doc/c-api/file.rst b/Doc/c-api/file.rst index 58ed58e5..b36c800e 100644 --- a/Doc/c-api/file.rst +++ b/Doc/c-api/file.rst @@ -5,7 +5,7 @@ File Objects ------------ -.. index:: object: file +.. index:: pair: object; file These APIs are a minimal emulation of the Python 2 C API for built-in file objects, which used to rely on the buffered I/O (:c:expr:`FILE*`) support @@ -93,7 +93,7 @@ the :mod:`io` APIs instead. .. index:: single: Py_PRINT_RAW Write object *obj* to file object *p*. The only supported flag for *flags* is - :const:`Py_PRINT_RAW`; if given, the :func:`str` of the object is written + :c:macro:`Py_PRINT_RAW`; if given, the :func:`str` of the object is written instead of the :func:`repr`. Return ``0`` on success or ``-1`` on failure; the appropriate exception will be set. diff --git a/Doc/c-api/float.rst b/Doc/c-api/float.rst index 023b12c2..4f6ac0d8 100644 --- a/Doc/c-api/float.rst +++ b/Doc/c-api/float.rst @@ -3,9 +3,9 @@ .. _floatobjects: Floating Point Objects ----------------------- +====================== -.. index:: object: floating point +.. index:: pair: object; floating point .. c:type:: PyFloatObject @@ -45,14 +45,14 @@ Floating Point Objects .. c:function:: double PyFloat_AsDouble(PyObject *pyfloat) Return a C :c:expr:`double` representation of the contents of *pyfloat*. If - *pyfloat* is not a Python floating point object but has a :meth:`__float__` + *pyfloat* is not a Python floating point object but has a :meth:`~object.__float__` method, this method will first be called to convert *pyfloat* into a float. - If ``__float__()`` is not defined then it falls back to :meth:`__index__`. + If :meth:`!__float__` is not defined then it falls back to :meth:`~object.__index__`. This method returns ``-1.0`` upon failure, so one should call :c:func:`PyErr_Occurred` to check for errors. .. versionchanged:: 3.8 - Use :meth:`__index__` if available. + Use :meth:`~object.__index__` if available. .. c:function:: double PyFloat_AS_DOUBLE(PyObject *pyfloat) @@ -79,7 +79,7 @@ Floating Point Objects Pack and Unpack functions -========================= +------------------------- The pack and unpack functions provide an efficient platform-independent way to store floating-point values as byte strings. The Pack routines produce a bytes @@ -104,12 +104,12 @@ happens in such cases is partly accidental (alas). .. versionadded:: 3.11 Pack functions --------------- +^^^^^^^^^^^^^^ The pack routines write 2, 4 or 8 bytes, starting at *p*. *le* is an :c:expr:`int` argument, non-zero if you want the bytes string in little-endian format (exponent last, at ``p+1``, ``p+3``, or ``p+6`` ``p+7``), zero if you -want big-endian format (exponent first, at *p*). The :c:data:`PY_BIG_ENDIAN` +want big-endian format (exponent first, at *p*). The :c:macro:`PY_BIG_ENDIAN` constant can be used to use the native endian: it is equal to ``1`` on big endian processor, or ``0`` on little endian processor. @@ -135,12 +135,12 @@ There are two problems on non-IEEE platforms: Unpack functions ----------------- +^^^^^^^^^^^^^^^^ The unpack routines read 2, 4 or 8 bytes, starting at *p*. *le* is an :c:expr:`int` argument, non-zero if the bytes string is in little-endian format (exponent last, at ``p+1``, ``p+3`` or ``p+6`` and ``p+7``), zero if big-endian -(exponent first, at *p*). The :c:data:`PY_BIG_ENDIAN` constant can be used to +(exponent first, at *p*). The :c:macro:`PY_BIG_ENDIAN` constant can be used to use the native endian: it is equal to ``1`` on big endian processor, or ``0`` on little endian processor. diff --git a/Doc/c-api/frame.rst b/Doc/c-api/frame.rst index b52f3477..1accee27 100644 --- a/Doc/c-api/frame.rst +++ b/Doc/c-api/frame.rst @@ -97,6 +97,27 @@ See also :ref:`Reflection `. .. versionadded:: 3.11 +.. c:function:: PyObject* PyFrame_GetVar(PyFrameObject *frame, PyObject *name) + + Get the variable *name* of *frame*. + + * Return a :term:`strong reference` to the variable value on success. + * Raise :exc:`NameError` and return ``NULL`` if the variable does not exist. + * Raise an exception and return ``NULL`` on error. + + *name* type must be a :class:`str`. + + .. versionadded:: 3.12 + + +.. c:function:: PyObject* PyFrame_GetVarString(PyFrameObject *frame, const char *name) + + Similar to :c:func:`PyFrame_GetVar`, but the variable name is a C string + encoded in UTF-8. + + .. versionadded:: 3.12 + + .. c:function:: PyObject* PyFrame_GetLocals(PyFrameObject *frame) Get the *frame*'s ``f_locals`` attribute (:class:`dict`). @@ -109,3 +130,38 @@ See also :ref:`Reflection `. .. c:function:: int PyFrame_GetLineNumber(PyFrameObject *frame) Return the line number that *frame* is currently executing. + + + +Internal Frames +^^^^^^^^^^^^^^^ + +Unless using :pep:`523`, you will not need this. + +.. c:struct:: _PyInterpreterFrame + + The interpreter's internal frame representation. + + .. versionadded:: 3.11 + +.. c:function:: PyObject* PyUnstable_InterpreterFrame_GetCode(struct _PyInterpreterFrame *frame); + + Return a :term:`strong reference` to the code object for the frame. + + .. versionadded:: 3.12 + + +.. c:function:: int PyUnstable_InterpreterFrame_GetLasti(struct _PyInterpreterFrame *frame); + + Return the byte offset into the last executed instruction. + + .. versionadded:: 3.12 + + +.. c:function:: int PyUnstable_InterpreterFrame_GetLine(struct _PyInterpreterFrame *frame); + + Return the currently executing line number, or -1 if there is no line number. + + .. versionadded:: 3.12 + + diff --git a/Doc/c-api/function.rst b/Doc/c-api/function.rst index 56c18396..5857dba8 100644 --- a/Doc/c-api/function.rst +++ b/Doc/c-api/function.rst @@ -5,7 +5,7 @@ Function Objects ---------------- -.. index:: object: function +.. index:: pair: object; function There are a few functions specific to Python functions. @@ -83,6 +83,15 @@ There are a few functions specific to Python functions. Raises :exc:`SystemError` and returns ``-1`` on failure. +.. c:function:: void PyFunction_SetVectorcall(PyFunctionObject *func, vectorcallfunc vectorcall) + + Set the vectorcall field of a given function object *func*. + + Warning: extensions using this API must preserve the behavior + of the unaltered (default) vectorcall function! + + .. versionadded:: 3.12 + .. c:function:: PyObject* PyFunction_GetClosure(PyObject *op) Return the closure associated with the function object *op*. This can be ``NULL`` @@ -109,3 +118,74 @@ There are a few functions specific to Python functions. must be a dictionary or ``Py_None``. Raises :exc:`SystemError` and returns ``-1`` on failure. + + +.. c:function:: int PyFunction_AddWatcher(PyFunction_WatchCallback callback) + + Register *callback* as a function watcher for the current interpreter. + Return an ID which may be passed to :c:func:`PyFunction_ClearWatcher`. + In case of error (e.g. no more watcher IDs available), + return ``-1`` and set an exception. + + .. versionadded:: 3.12 + + +.. c:function:: int PyFunction_ClearWatcher(int watcher_id) + + Clear watcher identified by *watcher_id* previously returned from + :c:func:`PyFunction_AddWatcher` for the current interpreter. + Return ``0`` on success, or ``-1`` and set an exception on error + (e.g. if the given *watcher_id* was never registered.) + + .. versionadded:: 3.12 + + +.. c:type:: PyFunction_WatchEvent + + Enumeration of possible function watcher events: + - ``PyFunction_EVENT_CREATE`` + - ``PyFunction_EVENT_DESTROY`` + - ``PyFunction_EVENT_MODIFY_CODE`` + - ``PyFunction_EVENT_MODIFY_DEFAULTS`` + - ``PyFunction_EVENT_MODIFY_KWDEFAULTS`` + + .. versionadded:: 3.12 + + +.. c:type:: int (*PyFunction_WatchCallback)(PyFunction_WatchEvent event, PyFunctionObject *func, PyObject *new_value) + + Type of a function watcher callback function. + + If *event* is ``PyFunction_EVENT_CREATE`` or ``PyFunction_EVENT_DESTROY`` + then *new_value* will be ``NULL``. Otherwise, *new_value* will hold a + :term:`borrowed reference` to the new value that is about to be stored in + *func* for the attribute that is being modified. + + The callback may inspect but must not modify *func*; doing so could have + unpredictable effects, including infinite recursion. + + If *event* is ``PyFunction_EVENT_CREATE``, then the callback is invoked + after `func` has been fully initialized. Otherwise, the callback is invoked + before the modification to *func* takes place, so the prior state of *func* + can be inspected. The runtime is permitted to optimize away the creation of + function objects when possible. In such cases no event will be emitted. + Although this creates the possibility of an observable difference of + runtime behavior depending on optimization decisions, it does not change + the semantics of the Python code being executed. + + If *event* is ``PyFunction_EVENT_DESTROY``, Taking a reference in the + callback to the about-to-be-destroyed function will resurrect it, preventing + it from being freed at this time. When the resurrected object is destroyed + later, any watcher callbacks active at that time will be called again. + + If the callback sets an exception, it must return ``-1``; this exception will + be printed as an unraisable exception using :c:func:`PyErr_WriteUnraisable`. + Otherwise it should return ``0``. + + There may already be a pending exception set on entry to the callback. In + this case, the callback should return ``0`` with the same exception still + set. This means the callback may not call any other API that can set an + exception unless it saves and clears the exception state first, and restores + it before returning. + + .. versionadded:: 3.12 diff --git a/Doc/c-api/gcsupport.rst b/Doc/c-api/gcsupport.rst index 8c90d1e8..6b2494ee 100644 --- a/Doc/c-api/gcsupport.rst +++ b/Doc/c-api/gcsupport.rst @@ -13,22 +13,20 @@ or strings), do not need to provide any explicit support for garbage collection. To create a container type, the :c:member:`~PyTypeObject.tp_flags` field of the type object must -include the :const:`Py_TPFLAGS_HAVE_GC` and provide an implementation of the +include the :c:macro:`Py_TPFLAGS_HAVE_GC` and provide an implementation of the :c:member:`~PyTypeObject.tp_traverse` handler. If instances of the type are mutable, a :c:member:`~PyTypeObject.tp_clear` implementation must also be provided. -.. data:: Py_TPFLAGS_HAVE_GC - :noindex: - +:c:macro:`Py_TPFLAGS_HAVE_GC` Objects with a type with this flag set must conform with the rules documented here. For convenience these objects will be referred to as container objects. Constructors for container types must conform to two rules: -#. The memory for the object must be allocated using :c:func:`PyObject_GC_New` - or :c:func:`PyObject_GC_NewVar`. +#. The memory for the object must be allocated using :c:macro:`PyObject_GC_New` + or :c:macro:`PyObject_GC_NewVar`. #. Once all the fields which may contain references to other containers are initialized, it must call :c:func:`PyObject_GC_Track`. @@ -52,23 +50,42 @@ rules: :c:member:`~PyTypeObject.tp_flags`, :c:member:`~PyTypeObject.tp_traverse` and :c:member:`~PyTypeObject.tp_clear` fields if the type inherits from a class that implements the garbage collector protocol and the child class - does *not* include the :const:`Py_TPFLAGS_HAVE_GC` flag. + does *not* include the :c:macro:`Py_TPFLAGS_HAVE_GC` flag. + +.. c:macro:: PyObject_GC_New(TYPE, typeobj) + + Analogous to :c:macro:`PyObject_New` but for container objects with the + :c:macro:`Py_TPFLAGS_HAVE_GC` flag set. + +.. c:macro:: PyObject_GC_NewVar(TYPE, typeobj, size) + + Analogous to :c:macro:`PyObject_NewVar` but for container objects with the + :c:macro:`Py_TPFLAGS_HAVE_GC` flag set. -.. c:function:: TYPE* PyObject_GC_New(TYPE, PyTypeObject *type) +.. c:function:: PyObject* PyUnstable_Object_GC_NewWithExtraData(PyTypeObject *type, size_t extra_size) - Analogous to :c:func:`PyObject_New` but for container objects with the - :const:`Py_TPFLAGS_HAVE_GC` flag set. + Analogous to :c:macro:`PyObject_GC_New` but allocates *extra_size* + bytes at the end of the object (at offset + :c:member:`~PyTypeObject.tp_basicsize`). + The allocated memory is initialized to zeros, + except for the :c:type:`Python object header `. + The extra data will be deallocated with the object, but otherwise it is + not managed by Python. -.. c:function:: TYPE* PyObject_GC_NewVar(TYPE, PyTypeObject *type, Py_ssize_t size) + .. warning:: + The function is marked as unstable because the final mechanism + for reserving extra data after an instance is not yet decided. + For allocating a variable number of fields, prefer using + :c:type:`PyVarObject` and :c:member:`~PyTypeObject.tp_itemsize` + instead. - Analogous to :c:func:`PyObject_NewVar` but for container objects with the - :const:`Py_TPFLAGS_HAVE_GC` flag set. + .. versionadded:: 3.12 .. c:function:: TYPE* PyObject_GC_Resize(TYPE, PyVarObject *op, Py_ssize_t newsize) - Resize an object allocated by :c:func:`PyObject_NewVar`. Returns the + Resize an object allocated by :c:macro:`PyObject_NewVar`. Returns the resized object or ``NULL`` on failure. *op* must not be tracked by the collector yet. @@ -111,8 +128,8 @@ rules: .. c:function:: void PyObject_GC_Del(void *op) - Releases memory allocated to an object using :c:func:`PyObject_GC_New` or - :c:func:`PyObject_GC_NewVar`. + Releases memory allocated to an object using :c:macro:`PyObject_GC_New` or + :c:macro:`PyObject_GC_NewVar`. .. c:function:: void PyObject_GC_UnTrack(void *op) @@ -126,7 +143,7 @@ rules: .. versionchanged:: 3.8 - The :c:func:`_PyObject_GC_TRACK` and :c:func:`_PyObject_GC_UNTRACK` macros + The :c:func:`!_PyObject_GC_TRACK` and :c:func:`!_PyObject_GC_UNTRACK` macros have been removed from the public C API. The :c:member:`~PyTypeObject.tp_traverse` handler accepts a function parameter of this type: @@ -228,3 +245,36 @@ garbage collection runs. Returns the current state, 0 for disabled and 1 for enabled. .. versionadded:: 3.10 + + +Querying Garbage Collector State +-------------------------------- + +The C-API provides the following interface for querying information about +the garbage collector. + +.. c:function:: void PyUnstable_GC_VisitObjects(gcvisitobjects_t callback, void *arg) + + Run supplied *callback* on all live GC-capable objects. *arg* is passed through to + all invocations of *callback*. + + .. warning:: + If new objects are (de)allocated by the callback it is undefined if they + will be visited. + + Garbage collection is disabled during operation. Explicitly running a collection + in the callback may lead to undefined behaviour e.g. visiting the same objects + multiple times or not at all. + + .. versionadded:: 3.12 + +.. c:type:: int (*gcvisitobjects_t)(PyObject *object, void *arg) + + Type of the visitor function to be passed to :c:func:`PyUnstable_GC_VisitObjects`. + *arg* is the same as the *arg* passed to ``PyUnstable_GC_VisitObjects``. + Return ``0`` to continue iteration, return ``1`` to stop iteration. Other return + values are reserved for now so behavior on returning anything else is undefined. + + .. versionadded:: 3.12 + + diff --git a/Doc/c-api/import.rst b/Doc/c-api/import.rst index 0922956c..7bc93a81 100644 --- a/Doc/c-api/import.rst +++ b/Doc/c-api/import.rst @@ -41,7 +41,7 @@ Importing Modules .. c:function:: PyObject* PyImport_ImportModuleEx(const char *name, PyObject *globals, PyObject *locals, PyObject *fromlist) - .. index:: builtin: __import__ + .. index:: pair: built-in function; __import__ Import a module. This is best described by referring to the built-in Python function :func:`__import__`. @@ -120,25 +120,25 @@ Importing Modules .. c:function:: PyObject* PyImport_ExecCodeModule(const char *name, PyObject *co) - .. index:: builtin: compile + .. index:: pair: built-in function; compile Given a module name (possibly of the form ``package.module``) and a code object read from a Python bytecode file or obtained from the built-in function :func:`compile`, load the module. Return a new reference to the module object, or ``NULL`` with an exception set if an error occurred. *name* - is removed from :attr:`sys.modules` in error cases, even if *name* was already - in :attr:`sys.modules` on entry to :c:func:`PyImport_ExecCodeModule`. Leaving - incompletely initialized modules in :attr:`sys.modules` is dangerous, as imports of + is removed from :data:`sys.modules` in error cases, even if *name* was already + in :data:`sys.modules` on entry to :c:func:`PyImport_ExecCodeModule`. Leaving + incompletely initialized modules in :data:`sys.modules` is dangerous, as imports of such modules have no way to know that the module object is an unknown (and probably damaged with respect to the module author's intents) state. The module's :attr:`__spec__` and :attr:`__loader__` will be set, if not set already, with the appropriate values. The spec's loader will be set to the module's ``__loader__`` (if set) and to an instance of - :class:`SourceFileLoader` otherwise. + :class:`~importlib.machinery.SourceFileLoader` otherwise. The module's :attr:`__file__` attribute will be set to the code object's - :c:member:`co_filename`. If applicable, :attr:`__cached__` will also + :attr:`!co_filename`. If applicable, :attr:`__cached__` will also be set. This function will reload the module if it was already imported. See @@ -150,6 +150,11 @@ Importing Modules See also :c:func:`PyImport_ExecCodeModuleEx` and :c:func:`PyImport_ExecCodeModuleWithPathnames`. + .. versionchanged:: 3.12 + The setting of :attr:`__cached__` and :attr:`__loader__` is + deprecated. See :class:`~importlib.machinery.ModuleSpec` for + alternatives. + .. c:function:: PyObject* PyImport_ExecCodeModuleEx(const char *name, PyObject *co, const char *pathname) @@ -167,6 +172,10 @@ Importing Modules .. versionadded:: 3.3 + .. versionchanged:: 3.12 + Setting :attr:`__cached__` is deprecated. See + :class:`~importlib.machinery.ModuleSpec` for alternatives. + .. c:function:: PyObject* PyImport_ExecCodeModuleWithPathnames(const char *name, PyObject *co, const char *pathname, const char *cpathname) @@ -177,8 +186,10 @@ Importing Modules .. versionadded:: 3.2 .. versionchanged:: 3.3 - Uses :func:`imp.source_from_cache()` in calculating the source path if + Uses :func:`!imp.source_from_cache()` in calculating the source path if only the bytecode path is provided. + .. versionchanged:: 3.12 + No longer uses the removed :mod:`!imp` module. .. c:function:: long PyImport_GetMagicNumber() @@ -214,7 +225,7 @@ Importing Modules .. c:function:: PyObject* PyImport_GetImporter(PyObject *path) - Return a finder object for a :data:`sys.path`/:attr:`pkg.__path__` item + Return a finder object for a :data:`sys.path`/:attr:`!pkg.__path__` item *path*, possibly by fetching it from the :data:`sys.path_importer_cache` dict. If it wasn't yet cached, traverse :data:`sys.path_hooks` until a hook is found that can handle the path item. Return ``None`` if no hook could; @@ -283,23 +294,25 @@ Importing Modules .. c:struct:: _inittab - Structure describing a single entry in the list of built-in modules. Each of - these structures gives the name and initialization function for a module built - into the interpreter. The name is an ASCII encoded string. Programs which + Structure describing a single entry in the list of built-in modules. + Programs which embed Python may use an array of these structures in conjunction with :c:func:`PyImport_ExtendInittab` to provide additional built-in modules. - The structure is defined in :file:`Include/import.h` as:: + The structure consists of two members: - struct _inittab { - const char *name; /* ASCII encoded string */ - PyObject* (*initfunc)(void); - }; + .. c:member:: const char *name + + The module name, as an ASCII encoded string. + + .. c: member:: PyObject* (*initfunc)(void) + + Initialization function for a module built into the interpreter. .. c:function:: int PyImport_ExtendInittab(struct _inittab *newtab) Add a collection of modules to the table of built-in modules. The *newtab* - array must end with a sentinel entry which contains ``NULL`` for the :attr:`name` + array must end with a sentinel entry which contains ``NULL`` for the :c:member:`~_inittab.name` field; failure to provide the sentinel value can result in a memory fault. Returns ``0`` on success or ``-1`` if insufficient memory could be allocated to extend the internal table. In the event of failure, no modules are added to the diff --git a/Doc/c-api/init.rst b/Doc/c-api/init.rst index a59667c4..8b960b06 100644 --- a/Doc/c-api/init.rst +++ b/Doc/c-api/init.rst @@ -25,7 +25,7 @@ The following functions can be safely called before Python is initialized: * :c:func:`PyImport_AppendInittab` * :c:func:`PyImport_ExtendInittab` - * :c:func:`PyInitFrozenExtensions` + * :c:func:`!PyInitFrozenExtensions` * :c:func:`PyMem_SetAllocator` * :c:func:`PyMem_SetupDebugHooks` * :c:func:`PyObject_SetArenaAllocator` @@ -83,52 +83,93 @@ to 1 and ``-bb`` sets :c:data:`Py_BytesWarningFlag` to 2. .. c:var:: int Py_BytesWarningFlag + This API is kept for backward compatibility: setting + :c:member:`PyConfig.bytes_warning` should be used instead, see :ref:`Python + Initialization Configuration `. + Issue a warning when comparing :class:`bytes` or :class:`bytearray` with :class:`str` or :class:`bytes` with :class:`int`. Issue an error if greater or equal to ``2``. Set by the :option:`-b` option. + .. deprecated:: 3.12 + .. c:var:: int Py_DebugFlag + This API is kept for backward compatibility: setting + :c:member:`PyConfig.parser_debug` should be used instead, see :ref:`Python + Initialization Configuration `. + Turn on parser debugging output (for expert only, depending on compilation options). Set by the :option:`-d` option and the :envvar:`PYTHONDEBUG` environment variable. + .. deprecated:: 3.12 + .. c:var:: int Py_DontWriteBytecodeFlag + This API is kept for backward compatibility: setting + :c:member:`PyConfig.write_bytecode` should be used instead, see :ref:`Python + Initialization Configuration `. + If set to non-zero, Python won't try to write ``.pyc`` files on the import of source modules. Set by the :option:`-B` option and the :envvar:`PYTHONDONTWRITEBYTECODE` environment variable. + .. deprecated:: 3.12 + .. c:var:: int Py_FrozenFlag + This API is kept for backward compatibility: setting + :c:member:`PyConfig.pathconfig_warnings` should be used instead, see + :ref:`Python Initialization Configuration `. + Suppress error messages when calculating the module search path in :c:func:`Py_GetPath`. Private flag used by ``_freeze_module`` and ``frozenmain`` programs. + .. deprecated:: 3.12 + .. c:var:: int Py_HashRandomizationFlag + This API is kept for backward compatibility: setting + :c:member:`PyConfig.hash_seed` and :c:member:`PyConfig.use_hash_seed` should + be used instead, see :ref:`Python Initialization Configuration + `. + Set to ``1`` if the :envvar:`PYTHONHASHSEED` environment variable is set to a non-empty string. If the flag is non-zero, read the :envvar:`PYTHONHASHSEED` environment variable to initialize the secret hash seed. + .. deprecated:: 3.12 + .. c:var:: int Py_IgnoreEnvironmentFlag - Ignore all :envvar:`PYTHON*` environment variables, e.g. + This API is kept for backward compatibility: setting + :c:member:`PyConfig.use_environment` should be used instead, see + :ref:`Python Initialization Configuration `. + + Ignore all :envvar:`!PYTHON*` environment variables, e.g. :envvar:`PYTHONPATH` and :envvar:`PYTHONHOME`, that might be set. Set by the :option:`-E` and :option:`-I` options. + .. deprecated:: 3.12 + .. c:var:: int Py_InspectFlag + This API is kept for backward compatibility: setting + :c:member:`PyConfig.inspect` should be used instead, see + :ref:`Python Initialization Configuration `. + When a script is passed as first argument or the :option:`-c` option is used, enter interactive mode after executing the script or the command, even when :data:`sys.stdin` does not appear to be a terminal. @@ -136,12 +177,24 @@ to 1 and ``-bb`` sets :c:data:`Py_BytesWarningFlag` to 2. Set by the :option:`-i` option and the :envvar:`PYTHONINSPECT` environment variable. + .. deprecated:: 3.12 + .. c:var:: int Py_InteractiveFlag + This API is kept for backward compatibility: setting + :c:member:`PyConfig.interactive` should be used instead, see + :ref:`Python Initialization Configuration `. + Set by the :option:`-i` option. + .. deprecated:: 3.12 + .. c:var:: int Py_IsolatedFlag + This API is kept for backward compatibility: setting + :c:member:`PyConfig.isolated` should be used instead, see + :ref:`Python Initialization Configuration `. + Run Python in isolated mode. In isolated mode :data:`sys.path` contains neither the script's directory nor the user's site-packages directory. @@ -149,8 +202,14 @@ to 1 and ``-bb`` sets :c:data:`Py_BytesWarningFlag` to 2. .. versionadded:: 3.4 + .. deprecated:: 3.12 + .. c:var:: int Py_LegacyWindowsFSEncodingFlag + This API is kept for backward compatibility: setting + :c:member:`PyPreConfig.legacy_windows_fs_encoding` should be used instead, see + :ref:`Python Initialization Configuration `. + If the flag is non-zero, use the ``mbcs`` encoding with ``replace`` error handler, instead of the UTF-8 encoding with ``surrogatepass`` error handler, for the :term:`filesystem encoding and error handler`. @@ -162,10 +221,16 @@ to 1 and ``-bb`` sets :c:data:`Py_BytesWarningFlag` to 2. .. availability:: Windows. + .. deprecated:: 3.12 + .. c:var:: int Py_LegacyWindowsStdioFlag + This API is kept for backward compatibility: setting + :c:member:`PyConfig.legacy_windows_stdio` should be used instead, see + :ref:`Python Initialization Configuration `. + If the flag is non-zero, use :class:`io.FileIO` instead of - :class:`WindowsConsoleIO` for :mod:`sys` standard streams. + :class:`!io._WindowsConsoleIO` for :mod:`sys` standard streams. Set to ``1`` if the :envvar:`PYTHONLEGACYWINDOWSSTDIO` environment variable is set to a non-empty string. @@ -174,8 +239,14 @@ to 1 and ``-bb`` sets :c:data:`Py_BytesWarningFlag` to 2. .. availability:: Windows. + .. deprecated:: 3.12 + .. c:var:: int Py_NoSiteFlag + This API is kept for backward compatibility: setting + :c:member:`PyConfig.site_import` should be used instead, see + :ref:`Python Initialization Configuration `. + Disable the import of the module :mod:`site` and the site-dependent manipulations of :data:`sys.path` that it entails. Also disable these manipulations if :mod:`site` is explicitly imported later (call @@ -183,36 +254,66 @@ to 1 and ``-bb`` sets :c:data:`Py_BytesWarningFlag` to 2. Set by the :option:`-S` option. + .. deprecated:: 3.12 + .. c:var:: int Py_NoUserSiteDirectory + This API is kept for backward compatibility: setting + :c:member:`PyConfig.user_site_directory` should be used instead, see + :ref:`Python Initialization Configuration `. + Don't add the :data:`user site-packages directory ` to :data:`sys.path`. Set by the :option:`-s` and :option:`-I` options, and the :envvar:`PYTHONNOUSERSITE` environment variable. + .. deprecated:: 3.12 + .. c:var:: int Py_OptimizeFlag + This API is kept for backward compatibility: setting + :c:member:`PyConfig.optimization_level` should be used instead, see + :ref:`Python Initialization Configuration `. + Set by the :option:`-O` option and the :envvar:`PYTHONOPTIMIZE` environment variable. + .. deprecated:: 3.12 + .. c:var:: int Py_QuietFlag + This API is kept for backward compatibility: setting + :c:member:`PyConfig.quiet` should be used instead, see :ref:`Python + Initialization Configuration `. + Don't display the copyright and version messages even in interactive mode. Set by the :option:`-q` option. .. versionadded:: 3.2 + .. deprecated:: 3.12 + .. c:var:: int Py_UnbufferedStdioFlag + This API is kept for backward compatibility: setting + :c:member:`PyConfig.buffered_stdio` should be used instead, see :ref:`Python + Initialization Configuration `. + Force the stdout and stderr streams to be unbuffered. Set by the :option:`-u` option and the :envvar:`PYTHONUNBUFFERED` environment variable. + .. deprecated:: 3.12 + .. c:var:: int Py_VerboseFlag + This API is kept for backward compatibility: setting + :c:member:`PyConfig.verbose` should be used instead, see :ref:`Python + Initialization Configuration `. + Print a message each time a module is initialized, showing the place (filename or built-in module) from which it is loaded. If greater or equal to ``2``, print a message for each file that is checked for when @@ -221,6 +322,8 @@ to 1 and ``-bb`` sets :c:data:`Py_BytesWarningFlag` to 2. Set by the :option:`-v` option and the :envvar:`PYTHONVERBOSE` environment variable. + .. deprecated:: 3.12 + Initializing and finalizing the interpreter =========================================== @@ -233,9 +336,9 @@ Initializing and finalizing the interpreter single: PyEval_InitThreads() single: modules (in module sys) single: path (in module sys) - module: builtins - module: __main__ - module: sys + pair: module; builtins + pair: module; __main__ + pair: module; sys triple: module; search; path single: PySys_SetArgv() single: PySys_SetArgvEx() @@ -253,6 +356,9 @@ Initializing and finalizing the interpreter (without calling :c:func:`Py_FinalizeEx` first). There is no return value; it is a fatal error if the initialization fails. + Use the :c:func:`Py_InitializeFromConfig` function to customize the + :ref:`Python Initialization Configuration `. + .. note:: On Windows, changes the console mode from ``O_TEXT`` to ``O_BINARY``, which will also affect non-Python uses of the console using the C Runtime. @@ -264,6 +370,9 @@ Initializing and finalizing the interpreter *initsigs* is ``0``, it skips initialization registration of signal handlers, which might be useful when Python is embedded. + Use the :c:func:`Py_InitializeFromConfig` function to customize the + :ref:`Python Initialization Configuration `. + .. c:function:: int Py_IsInitialized() @@ -292,7 +401,7 @@ Initializing and finalizing the interpreter the application. **Bugs and caveats:** The destruction of modules and objects in modules is done - in random order; this may cause destructors (:meth:`__del__` methods) to fail + in random order; this may cause destructors (:meth:`~object.__del__` methods) to fail when they depend on other objects (even functions) or modules. Dynamically loaded extension modules loaded by Python are not unloaded. Small amounts of memory allocated by the Python interpreter may not be freed (if you find a leak, @@ -376,12 +485,12 @@ Process-wide parameters interpreter will change the contents of this storage. Use :c:func:`Py_DecodeLocale` to decode a bytes string to get a - :c:expr:`wchar_*` string. + :c:expr:`wchar_t *` string. .. deprecated:: 3.11 -.. c:function:: wchar* Py_GetProgramName() +.. c:function:: wchar_t* Py_GetProgramName() .. index:: single: Py_SetProgramName() @@ -404,7 +513,7 @@ Process-wide parameters program name is ``'/usr/local/bin/python'``, the prefix is ``'/usr/local'``. The returned string points into static storage; the caller should not modify its value. This corresponds to the :makevar:`prefix` variable in the top-level - :file:`Makefile` and the ``--prefix`` argument to the :program:`configure` + :file:`Makefile` and the :option:`--prefix` argument to the :program:`configure` script at build time. The value is available to Python code as ``sys.prefix``. It is only useful on Unix. See also the next function. @@ -709,7 +818,7 @@ Process-wide parameters .. deprecated:: 3.11 -.. c:function:: w_char* Py_GetPythonHome() +.. c:function:: wchar_t* Py_GetPythonHome() Return the default "home", that is, the value set by a previous call to :c:func:`Py_SetPythonHome`, or the value of the :envvar:`PYTHONHOME` @@ -872,7 +981,7 @@ the fork, and releasing them afterwards. In addition, it resets any :ref:`lock-objects` in the child. When extending or embedding Python, there is no way to inform Python of additional (non-Python) locks that need to be acquired before or reset after a fork. OS facilities such as -:c:func:`pthread_atfork` would need to be used to accomplish the same thing. +:c:func:`!pthread_atfork` would need to be used to accomplish the same thing. Additionally, when extending or embedding Python, calling :c:func:`fork` directly rather than through :func:`os.fork` (and returning to or calling into Python) may result in a deadlock by one of Python's internal locks @@ -914,8 +1023,11 @@ code, or when embedding the Python interpreter: .. c:type:: PyThreadState This data structure represents the state of a single thread. The only public - data member is :attr:`interp` (:c:expr:`PyInterpreterState *`), which points to - this thread's interpreter state. + data member is: + + .. c:member:: PyInterpreterState *interp + + This thread's interpreter state. .. c:function:: void PyEval_InitThreads() @@ -942,7 +1054,7 @@ code, or when embedding the Python interpreter: .. deprecated:: 3.9 - .. index:: module: _thread + .. index:: pair: module; _thread .. c:function:: int PyEval_ThreadsInitialized() @@ -975,7 +1087,7 @@ code, or when embedding the Python interpreter: .. note:: Calling this function from a thread when the runtime is finalizing will terminate the thread, even if the thread was not created by Python. - You can use :c:func:`_Py_IsFinalizing` or :func:`sys.is_finalizing` to + You can use :c:func:`!_Py_IsFinalizing` or :func:`sys.is_finalizing` to check if the interpreter is in process of being finalized before calling this function to avoid unwanted termination. @@ -1021,7 +1133,7 @@ with sub-interpreters: .. note:: Calling this function from a thread when the runtime is finalizing will terminate the thread, even if the thread was not created by Python. - You can use :c:func:`_Py_IsFinalizing` or :func:`sys.is_finalizing` to + You can use :c:func:`!_Py_IsFinalizing` or :func:`sys.is_finalizing` to check if the interpreter is in process of being finalized before calling this function to avoid unwanted termination. @@ -1287,7 +1399,7 @@ All of the following functions must be called after :c:func:`Py_Initialize`. function does not steal any references to *exc*. To prevent naive misuse, you must write your own C extension to call this. Must be called with the GIL held. Returns the number of thread states modified; this is normally one, but will be - zero if the thread id isn't found. If *exc* is :const:`NULL`, the pending + zero if the thread id isn't found. If *exc* is ``NULL``, the pending exception (if any) for the thread is cleared. This raises no exceptions. .. versionchanged:: 3.7 @@ -1303,7 +1415,7 @@ All of the following functions must be called after :c:func:`Py_Initialize`. .. note:: Calling this function from a thread when the runtime is finalizing will terminate the thread, even if the thread was not created by Python. - You can use :c:func:`_Py_IsFinalizing` or :func:`sys.is_finalizing` to + You can use :c:func:`!_Py_IsFinalizing` or :func:`sys.is_finalizing` to check if the interpreter is in process of being finalized before calling this function to avoid unwanted termination. @@ -1382,12 +1494,101 @@ You can switch between sub-interpreters using the :c:func:`PyThreadState_Swap` function. You can create and destroy them using the following functions: -.. c:function:: PyThreadState* Py_NewInterpreter() +.. c:type:: PyInterpreterConfig + + Structure containing most parameters to configure a sub-interpreter. + Its values are used only in :c:func:`Py_NewInterpreterFromConfig` and + never modified by the runtime. + + .. versionadded:: 3.12 + + Structure fields: + + .. c:member:: int use_main_obmalloc + + If this is ``0`` then the sub-interpreter will use its own + "object" allocator state. + Otherwise it will use (share) the main interpreter's. + + If this is ``0`` then + :c:member:`~PyInterpreterConfig.check_multi_interp_extensions` + must be ``1`` (non-zero). + If this is ``1`` then :c:member:`~PyInterpreterConfig.gil` + must not be :c:macro:`PyInterpreterConfig_OWN_GIL`. + + .. c:member:: int allow_fork + + If this is ``0`` then the runtime will not support forking the + process in any thread where the sub-interpreter is currently active. + Otherwise fork is unrestricted. + + Note that the :mod:`subprocess` module still works + when fork is disallowed. + + .. c:member:: int allow_exec + + If this is ``0`` then the runtime will not support replacing the + current process via exec (e.g. :func:`os.execv`) in any thread + where the sub-interpreter is currently active. + Otherwise exec is unrestricted. + + Note that the :mod:`subprocess` module still works + when exec is disallowed. + + .. c:member:: int allow_threads + + If this is ``0`` then the sub-interpreter's :mod:`threading` module + won't create threads. + Otherwise threads are allowed. + + .. c:member:: int allow_daemon_threads + + If this is ``0`` then the sub-interpreter's :mod:`threading` module + won't create daemon threads. + Otherwise daemon threads are allowed (as long as + :c:member:`~PyInterpreterConfig.allow_threads` is non-zero). + + .. c:member:: int check_multi_interp_extensions + + If this is ``0`` then all extension modules may be imported, + including legacy (single-phase init) modules, + in any thread where the sub-interpreter is currently active. + Otherwise only multi-phase init extension modules + (see :pep:`489`) may be imported. + (Also see :c:macro:`Py_mod_multiple_interpreters`.) + + This must be ``1`` (non-zero) if + :c:member:`~PyInterpreterConfig.use_main_obmalloc` is ``0``. + + .. c:member:: int gil + + This determines the operation of the GIL for the sub-interpreter. + It may be one of the following: + + .. c:namespace:: NULL + + .. c:macro:: PyInterpreterConfig_DEFAULT_GIL + + Use the default selection (:c:macro:`PyInterpreterConfig_SHARED_GIL`). + + .. c:macro:: PyInterpreterConfig_SHARED_GIL + + Use (share) the main interpreter's GIL. + + .. c:macro:: PyInterpreterConfig_OWN_GIL + + Use the sub-interpreter's own GIL. + + If this is :c:macro:`PyInterpreterConfig_OWN_GIL` then + :c:member:`PyInterpreterConfig.use_main_obmalloc` must be ``0``. + + +.. c:function:: PyStatus Py_NewInterpreterFromConfig(PyThreadState **tstate_p, const PyInterpreterConfig *config) .. index:: - module: builtins - module: __main__ - module: sys + pair: module; builtins + pair: module; __main__ + pair: module; sys single: stdout (in module sys) single: stderr (in module sys) single: stdin (in module sys) @@ -1402,16 +1603,47 @@ function. You can create and destroy them using the following functions: ``sys.stdout`` and ``sys.stderr`` (however these refer to the same underlying file descriptors). - The return value points to the first thread state created in the new + The given *config* controls the options with which the interpreter + is initialized. + + Upon success, *tstate_p* will be set to the first thread state + created in the new sub-interpreter. This thread state is made in the current thread state. Note that no actual thread is created; see the discussion of thread states - below. If creation of the new interpreter is unsuccessful, ``NULL`` is - returned; no exception is set since the exception state is stored in the - current thread state and there may not be a current thread state. (Like all - other Python/C API functions, the global interpreter lock must be held before - calling this function and is still held when it returns; however, unlike most - other Python/C API functions, there needn't be a current thread state on - entry.) + below. If creation of the new interpreter is unsuccessful, + *tstate_p* is set to ``NULL``; + no exception is set since the exception state is stored in the + current thread state and there may not be a current thread state. + + Like all other Python/C API functions, the global interpreter lock + must be held before calling this function and is still held when it + returns. Likewise a current thread state must be set on entry. On + success, the returned thread state will be set as current. If the + sub-interpreter is created with its own GIL then the GIL of the + calling interpreter will be released. When the function returns, + the new interpreter's GIL will be held by the current thread and + the previously interpreter's GIL will remain released here. + + .. versionadded:: 3.12 + + Sub-interpreters are most effective when isolated from each other, + with certain functionality restricted:: + + PyInterpreterConfig config = { + .use_main_obmalloc = 0, + .allow_fork = 0, + .allow_exec = 0, + .allow_threads = 1, + .allow_daemon_threads = 0, + .check_multi_interp_extensions = 1, + .gil = PyInterpreterConfig_OWN_GIL, + }; + PyThreadState *tstate = Py_NewInterpreterFromConfig(&config); + + Note that the config is used only briefly and does not get modified. + During initialization the config's values are converted into various + :c:type:`PyInterpreterState` values. A read-only copy of the config + may be stored internally on the :c:type:`PyInterpreterState`. .. index:: single: Py_FinalizeEx() @@ -1446,19 +1678,79 @@ function. You can create and destroy them using the following functions: .. index:: single: close() (in module os) +.. c:function:: PyThreadState* Py_NewInterpreter(void) + + .. index:: + pair: module; builtins + pair: module; __main__ + pair: module; sys + single: stdout (in module sys) + single: stderr (in module sys) + single: stdin (in module sys) + + Create a new sub-interpreter. This is essentially just a wrapper + around :c:func:`Py_NewInterpreterFromConfig` with a config that + preserves the existing behavior. The result is an unisolated + sub-interpreter that shares the main interpreter's GIL, allows + fork/exec, allows daemon threads, and allows single-phase init + modules. + + .. c:function:: void Py_EndInterpreter(PyThreadState *tstate) .. index:: single: Py_FinalizeEx() - Destroy the (sub-)interpreter represented by the given thread state. The given - thread state must be the current thread state. See the discussion of thread - states below. When the call returns, the current thread state is ``NULL``. All - thread states associated with this interpreter are destroyed. (The global - interpreter lock must be held before calling this function and is still held - when it returns.) :c:func:`Py_FinalizeEx` will destroy all sub-interpreters that + Destroy the (sub-)interpreter represented by the given thread state. + The given thread state must be the current thread state. See the + discussion of thread states below. When the call returns, + the current thread state is ``NULL``. All thread states associated + with this interpreter are destroyed. The global interpreter lock + used by the target interpreter must be held before calling this + function. No GIL is held when it returns. + + :c:func:`Py_FinalizeEx` will destroy all sub-interpreters that haven't been explicitly destroyed at that point. +A Per-Interpreter GIL +--------------------- + +Using :c:func:`Py_NewInterpreterFromConfig` you can create +a sub-interpreter that is completely isolated from other interpreters, +including having its own GIL. The most important benefit of this +isolation is that such an interpreter can execute Python code without +being blocked by other interpreters or blocking any others. Thus a +single Python process can truly take advantage of multiple CPU cores +when running Python code. The isolation also encourages a different +approach to concurrency than that of just using threads. +(See :pep:`554`.) + +Using an isolated interpreter requires vigilance in preserving that +isolation. That especially means not sharing any objects or mutable +state without guarantees about thread-safety. Even objects that are +otherwise immutable (e.g. ``None``, ``(1, 5)``) can't normally be shared +because of the refcount. One simple but less-efficient approach around +this is to use a global lock around all use of some state (or object). +Alternately, effectively immutable objects (like integers or strings) +can be made safe in spite of their refcounts by making them "immortal". +In fact, this has been done for the builtin singletons, small integers, +and a number of other builtin objects. + +If you preserve isolation then you will have access to proper multi-core +computing without the complications that come with free-threading. +Failure to preserve isolation will expose you to the full consequences +of free-threading, including races and hard-to-debug crashes. + +Aside from that, one of the main challenges of using multiple isolated +interpreters is how to communicate between them safely (not break +isolation) and efficiently. The runtime and stdlib do not provide +any standard approach to this yet. A future stdlib module would help +mitigate the effort of preserving isolation and expose effective tools +for communicating (and sharing) data between interpreters. + +.. versionadded:: 3.12 + + Bugs and caveats ---------------- @@ -1566,32 +1858,32 @@ Python-level trace functions in previous versions. The type of the trace function registered using :c:func:`PyEval_SetProfile` and :c:func:`PyEval_SetTrace`. The first parameter is the object passed to the registration function as *obj*, *frame* is the frame object to which the event - pertains, *what* is one of the constants :const:`PyTrace_CALL`, - :const:`PyTrace_EXCEPTION`, :const:`PyTrace_LINE`, :const:`PyTrace_RETURN`, - :const:`PyTrace_C_CALL`, :const:`PyTrace_C_EXCEPTION`, :const:`PyTrace_C_RETURN`, - or :const:`PyTrace_OPCODE`, and *arg* depends on the value of *what*: - - +------------------------------+----------------------------------------+ - | Value of *what* | Meaning of *arg* | - +==============================+========================================+ - | :const:`PyTrace_CALL` | Always :c:data:`Py_None`. | - +------------------------------+----------------------------------------+ - | :const:`PyTrace_EXCEPTION` | Exception information as returned by | - | | :func:`sys.exc_info`. | - +------------------------------+----------------------------------------+ - | :const:`PyTrace_LINE` | Always :c:data:`Py_None`. | - +------------------------------+----------------------------------------+ - | :const:`PyTrace_RETURN` | Value being returned to the caller, | - | | or ``NULL`` if caused by an exception. | - +------------------------------+----------------------------------------+ - | :const:`PyTrace_C_CALL` | Function object being called. | - +------------------------------+----------------------------------------+ - | :const:`PyTrace_C_EXCEPTION` | Function object being called. | - +------------------------------+----------------------------------------+ - | :const:`PyTrace_C_RETURN` | Function object being called. | - +------------------------------+----------------------------------------+ - | :const:`PyTrace_OPCODE` | Always :c:data:`Py_None`. | - +------------------------------+----------------------------------------+ + pertains, *what* is one of the constants :c:data:`PyTrace_CALL`, + :c:data:`PyTrace_EXCEPTION`, :c:data:`PyTrace_LINE`, :c:data:`PyTrace_RETURN`, + :c:data:`PyTrace_C_CALL`, :c:data:`PyTrace_C_EXCEPTION`, :c:data:`PyTrace_C_RETURN`, + or :c:data:`PyTrace_OPCODE`, and *arg* depends on the value of *what*: + + +-------------------------------+----------------------------------------+ + | Value of *what* | Meaning of *arg* | + +===============================+========================================+ + | :c:data:`PyTrace_CALL` | Always :c:data:`Py_None`. | + +-------------------------------+----------------------------------------+ + | :c:data:`PyTrace_EXCEPTION` | Exception information as returned by | + | | :func:`sys.exc_info`. | + +-------------------------------+----------------------------------------+ + | :c:data:`PyTrace_LINE` | Always :c:data:`Py_None`. | + +-------------------------------+----------------------------------------+ + | :c:data:`PyTrace_RETURN` | Value being returned to the caller, | + | | or ``NULL`` if caused by an exception. | + +-------------------------------+----------------------------------------+ + | :c:data:`PyTrace_C_CALL` | Function object being called. | + +-------------------------------+----------------------------------------+ + | :c:data:`PyTrace_C_EXCEPTION` | Function object being called. | + +-------------------------------+----------------------------------------+ + | :c:data:`PyTrace_C_RETURN` | Function object being called. | + +-------------------------------+----------------------------------------+ + | :c:data:`PyTrace_OPCODE` | Always :c:data:`Py_None`. | + +-------------------------------+----------------------------------------+ .. c:var:: int PyTrace_CALL @@ -1658,13 +1950,25 @@ Python-level trace functions in previous versions. function as its first parameter, and may be any Python object, or ``NULL``. If the profile function needs to maintain state, using a different value for *obj* for each thread provides a convenient and thread-safe place to store it. The - profile function is called for all monitored events except :const:`PyTrace_LINE` - :const:`PyTrace_OPCODE` and :const:`PyTrace_EXCEPTION`. + profile function is called for all monitored events except :c:data:`PyTrace_LINE` + :c:data:`PyTrace_OPCODE` and :c:data:`PyTrace_EXCEPTION`. See also the :func:`sys.setprofile` function. The caller must hold the :term:`GIL`. +.. c:function:: void PyEval_SetProfileAllThreads(Py_tracefunc func, PyObject *obj) + + Like :c:func:`PyEval_SetProfile` but sets the profile function in all running threads + belonging to the current interpreter instead of the setting it only on the current thread. + + The caller must hold the :term:`GIL`. + + As :c:func:`PyEval_SetProfile`, this function ignores any exceptions raised while + setting the profile functions in all threads. + +.. versionadded:: 3.12 + .. c:function:: void PyEval_SetTrace(Py_tracefunc func, PyObject *obj) @@ -1672,13 +1976,25 @@ Python-level trace functions in previous versions. :c:func:`PyEval_SetProfile`, except the tracing function does receive line-number events and per-opcode events, but does not receive any event related to C function objects being called. Any trace function registered using :c:func:`PyEval_SetTrace` - will not receive :const:`PyTrace_C_CALL`, :const:`PyTrace_C_EXCEPTION` or - :const:`PyTrace_C_RETURN` as a value for the *what* parameter. + will not receive :c:data:`PyTrace_C_CALL`, :c:data:`PyTrace_C_EXCEPTION` or + :c:data:`PyTrace_C_RETURN` as a value for the *what* parameter. See also the :func:`sys.settrace` function. The caller must hold the :term:`GIL`. +.. c:function:: void PyEval_SetTraceAllThreads(Py_tracefunc func, PyObject *obj) + + Like :c:func:`PyEval_SetTrace` but sets the tracing function in all running threads + belonging to the current interpreter instead of the setting it only on the current thread. + + The caller must hold the :term:`GIL`. + + As :c:func:`PyEval_SetTrace`, this function ignores any exceptions raised while + setting the trace functions in all threads. + +.. versionadded:: 3.12 + .. _advanced-debugging: diff --git a/Doc/c-api/init_config.rst b/Doc/c-api/init_config.rst index 24d66201..7c5465b5 100644 --- a/Doc/c-api/init_config.rst +++ b/Doc/c-api/init_config.rst @@ -82,6 +82,8 @@ PyWideStringList If *length* is non-zero, *items* must be non-``NULL`` and all strings must be non-``NULL``. + .. c:namespace:: NULL + Methods: .. c:function:: PyStatus PyWideStringList_Append(PyWideStringList *list, const wchar_t *item) @@ -101,6 +103,8 @@ PyWideStringList Python must be preinitialized to call this function. + .. c:namespace:: PyWideStringList + Structure fields: .. c:member:: Py_ssize_t length @@ -135,6 +139,8 @@ PyStatus Name of the function which created an error, can be ``NULL``. + .. c:namespace:: NULL + Functions to create a status: .. c:function:: PyStatus PyStatus_Ok(void) @@ -210,6 +216,8 @@ PyPreConfig Structure used to preinitialize Python. + .. c:namespace:: NULL + Function to initialize a preconfiguration: .. c:function:: void PyPreConfig_InitPythonConfig(PyPreConfig *preconfig) @@ -222,6 +230,8 @@ PyPreConfig Initialize the preconfiguration with :ref:`Isolated Configuration `. + .. c:namespace:: PyPreConfig + Structure fields: .. c:member:: int allocator @@ -429,6 +439,8 @@ PyConfig When done, the :c:func:`PyConfig_Clear` function must be used to release the configuration memory. + .. c:namespace:: NULL + Structure methods: .. c:function:: void PyConfig_InitPythonConfig(PyConfig *config) @@ -522,11 +534,13 @@ PyConfig Moreover, if :c:func:`PyConfig_SetArgv` or :c:func:`PyConfig_SetBytesArgv` is used, this method must be called before other methods, since the preinitialization configuration depends on command line arguments (if - :c:member:`parse_argv` is non-zero). + :c:member:`~PyConfig.parse_argv` is non-zero). The caller of these methods is responsible to handle exceptions (error or exit) using ``PyStatus_Exception()`` and ``Py_ExitStatusException()``. + .. c:namespace:: PyConfig + Structure fields: .. c:member:: PyWideStringList argv @@ -828,14 +842,34 @@ PyConfig Default: ``0``. + .. c:member:: int int_max_str_digits + + Configures the :ref:`integer string conversion length limitation + `. An initial value of ``-1`` means the value will + be taken from the command line or environment or otherwise default to + 4300 (:data:`sys.int_info.default_max_str_digits`). A value of ``0`` + disables the limitation. Values greater than zero but less than 640 + (:data:`sys.int_info.str_digits_check_threshold`) are unsupported and + will produce an error. + + Configured by the :option:`-X int_max_str_digits <-X>` command line + flag or the :envvar:`PYTHONINTMAXSTRDIGITS` environment variable. + + Default: ``-1`` in Python mode. 4300 + (:data:`sys.int_info.default_max_str_digits`) in isolated mode. + + .. versionadded:: 3.12 + .. c:member:: int isolated If greater than ``0``, enable isolated mode: * Set :c:member:`~PyConfig.safe_path` to ``1``: don't prepend a potentially unsafe path to :data:`sys.path` at Python - startup. - * Set :c:member:`~PyConfig.use_environment` to ``0``. + startup, such as the current directory, the script's directory or an + empty string. + * Set :c:member:`~PyConfig.use_environment` to ``0``: ignore ``PYTHON`` + environment variables. * Set :c:member:`~PyConfig.user_site_directory` to ``0``: don't add the user site directory to :data:`sys.path`. * Python REPL doesn't import :mod:`readline` nor enable default readline @@ -845,12 +879,13 @@ PyConfig Default: ``0`` in Python mode, ``1`` in isolated mode. - See also :c:member:`PyPreConfig.isolated`. + See also the :ref:`Isolated Configuration ` and + :c:member:`PyPreConfig.isolated`. .. c:member:: int legacy_windows_stdio If non-zero, use :class:`io.FileIO` instead of - :class:`io.WindowsConsoleIO` for :data:`sys.stdin`, :data:`sys.stdout` + :class:`!io._WindowsConsoleIO` for :data:`sys.stdin`, :data:`sys.stdout` and :data:`sys.stderr`. Set to ``1`` if the :envvar:`PYTHONLEGACYWINDOWSSTDIO` environment @@ -899,7 +934,7 @@ PyConfig .. c:member:: wchar_t* pythonpath_env Module search paths (:data:`sys.path`) as a string separated by ``DELIM`` - (:data:`os.path.pathsep`). + (:data:`os.pathsep`). Set by the :envvar:`PYTHONPATH` environment variable. @@ -982,6 +1017,9 @@ PyConfig Incremented by the :option:`-d` command line option. Set to the :envvar:`PYTHONDEBUG` environment variable value. + Need a :ref:`debug build of Python ` (the ``Py_DEBUG`` macro + must be defined). + Default: ``0``. .. c:member:: int pathconfig_warnings @@ -1075,7 +1113,7 @@ PyConfig .. c:member:: int show_ref_count - Show total reference count at exit? + Show total reference count at exit (excluding immortal objects)? Set to ``1`` by :option:`-X showrefcount <-X>` command line option. @@ -1096,7 +1134,7 @@ PyConfig Set to ``0`` by the :option:`-S` command line option. - :data:`sys.flags.no_site` is set to the inverted value of + :data:`sys.flags.no_site ` is set to the inverted value of :c:member:`~PyConfig.site_import`. Default: ``1``. @@ -1149,6 +1187,20 @@ PyConfig Default: ``-1`` in Python mode, ``0`` in isolated mode. + .. c:member:: int perf_profiling + + Enable compatibility mode with the perf profiler? + + If non-zero, initialize the perf trampoline. See :ref:`perf_profiling` + for more information. + + Set by :option:`-X perf <-X>` command line option and by the + :envvar:`PYTHONPERFSUPPORT` environment variable. + + Default: ``-1``. + + .. versionadded:: 3.12 + .. c:member:: int use_environment Use :ref:`environment variables `? @@ -1176,13 +1228,13 @@ PyConfig imported, showing the place (filename or built-in module) from which it is loaded. - If greater or equal to ``2``, print a message for each file that is checked - for when searching for a module. Also provides information on module - cleanup at exit. + If greater than or equal to ``2``, print a message for each file that is + checked for when searching for a module. Also provides information on + module cleanup at exit. Incremented by the :option:`-v` command line option. - Set to the :envvar:`PYTHONVERBOSE` environment variable value. + Set by the :envvar:`PYTHONVERBOSE` environment variable value. Default: ``0``. @@ -1533,8 +1585,6 @@ Private provisional API: * :c:member:`PyConfig._init_main`: if set to ``0``, :c:func:`Py_InitializeFromConfig` stops at the "Core" initialization phase. -* :c:member:`PyConfig._isolated_interpreter`: if non-zero, - disallow threads, subprocesses and fork. .. c:function:: PyStatus _Py_InitializeMain(void) @@ -1546,7 +1596,7 @@ applied during the "Main" phase. It may allow to customize Python in Python to override or tune the :ref:`Path Configuration `, maybe install a custom :data:`sys.meta_path` importer or an import hook, etc. -It may become possible to calculatin the :ref:`Path Configuration +It may become possible to calculate the :ref:`Path Configuration ` in Python, after the Core phase and before the Main phase, which is one of the :pep:`432` motivation. diff --git a/Doc/c-api/intro.rst b/Doc/c-api/intro.rst index ac2afa18..26c0168d 100644 --- a/Doc/c-api/intro.rst +++ b/Doc/c-api/intro.rst @@ -78,19 +78,19 @@ used by extension writers. Structure member names do not have a reserved prefix. The header files are typically installed with Python. On Unix, these are located in the directories :file:`{prefix}/include/pythonversion/` and -:file:`{exec_prefix}/include/pythonversion/`, where :envvar:`prefix` and -:envvar:`exec_prefix` are defined by the corresponding parameters to Python's +:file:`{exec_prefix}/include/pythonversion/`, where :option:`prefix <--prefix>` and +:option:`exec_prefix <--exec-prefix>` are defined by the corresponding parameters to Python's :program:`configure` script and *version* is ``'%d.%d' % sys.version_info[:2]``. On Windows, the headers are installed -in :file:`{prefix}/include`, where :envvar:`prefix` is the installation +in :file:`{prefix}/include`, where ``prefix`` is the installation directory specified to the installer. To include the headers, place both directories (if different) on your compiler's search path for includes. Do *not* place the parent directories on the search path and then use ``#include ``; this will break on multi-platform builds since the platform independent headers under -:envvar:`prefix` include the platform specific headers from -:envvar:`exec_prefix`. +:option:`prefix <--prefix>` include the platform specific headers from +:option:`exec_prefix <--exec-prefix>`. C++ users should note that although the API is defined entirely using C, the header files properly declare the entry points to be ``extern "C"``. As a result, @@ -105,6 +105,30 @@ defined closer to where they are useful (e.g. :c:macro:`Py_RETURN_NONE`). Others of a more general utility are defined here. This is not necessarily a complete listing. +.. c:macro:: PyMODINIT_FUNC + + Declare an extension module ``PyInit`` initialization function. The function + return type is :c:expr:`PyObject*`. The macro declares any special linkage + declarations required by the platform, and for C++ declares the function as + ``extern "C"``. + + The initialization function must be named :samp:`PyInit_{name}`, where + *name* is the name of the module, and should be the only non-\ ``static`` + item defined in the module file. Example:: + + static struct PyModuleDef spam_module = { + PyModuleDef_HEAD_INIT, + .m_name = "spam", + ... + }; + + PyMODINIT_FUNC + PyInit_spam(void) + { + return PyModule_Create(&spam_module); + } + + .. c:macro:: Py_ABS(x) Return the absolute value of ``x``. @@ -153,7 +177,7 @@ complete listing. .. c:macro:: Py_GETENV(s) Like ``getenv(s)``, but returns ``NULL`` if :option:`-E` was passed on the - command line (i.e. if ``Py_IgnoreEnvironmentFlag`` is set). + command line (see :c:member:`PyConfig.use_environment`). .. c:macro:: Py_MAX(x, y) @@ -261,7 +285,7 @@ complete listing. Objects, Types and Reference Counts =================================== -.. index:: object: type +.. index:: pair: object; type Most Python/C API functions have one or more arguments as well as a return value of type :c:expr:`PyObject*`. This type is a pointer to an opaque data type @@ -287,52 +311,58 @@ true if (and only if) the object pointed to by *a* is a Python list. Reference Counts ---------------- -The reference count is important because today's computers have a finite (and -often severely limited) memory size; it counts how many different places there -are that have a reference to an object. Such a place could be another object, -or a global (or static) C variable, or a local variable in some C function. -When an object's reference count becomes zero, the object is deallocated. If -it contains references to other objects, their reference count is decremented. -Those other objects may be deallocated in turn, if this decrement makes their -reference count become zero, and so on. (There's an obvious problem with -objects that reference each other here; for now, the solution is "don't do -that.") +The reference count is important because today's computers have a finite +(and often severely limited) memory size; it counts how many different +places there are that have a :term:`strong reference` to an object. +Such a place could be another object, or a global (or static) C variable, +or a local variable in some C function. +When the last :term:`strong reference` to an object is released +(i.e. its reference count becomes zero), the object is deallocated. +If it contains references to other objects, those references are released. +Those other objects may be deallocated in turn, if there are no more +references to them, and so on. (There's an obvious problem with +objects that reference each other here; for now, the solution +is "don't do that.") .. index:: single: Py_INCREF() single: Py_DECREF() -Reference counts are always manipulated explicitly. The normal way is to use -the macro :c:func:`Py_INCREF` to increment an object's reference count by one, -and :c:func:`Py_DECREF` to decrement it by one. The :c:func:`Py_DECREF` macro +Reference counts are always manipulated explicitly. The normal way is +to use the macro :c:func:`Py_INCREF` to take a new reference to an +object (i.e. increment its reference count by one), +and :c:func:`Py_DECREF` to release that reference (i.e. decrement the +reference count by one). The :c:func:`Py_DECREF` macro is considerably more complex than the incref one, since it must check whether the reference count becomes zero and then cause the object's deallocator to be -called. The deallocator is a function pointer contained in the object's type -structure. The type-specific deallocator takes care of decrementing the -reference counts for other objects contained in the object if this is a compound +called. The deallocator is a function pointer contained in the object's type +structure. The type-specific deallocator takes care of releasing references +for other objects contained in the object if this is a compound object type, such as a list, as well as performing any additional finalization that's needed. There's no chance that the reference count can overflow; at least as many bits are used to hold the reference count as there are distinct memory locations in virtual memory (assuming ``sizeof(Py_ssize_t) >= sizeof(void*)``). Thus, the reference count increment is a simple operation. -It is not necessary to increment an object's reference count for every local -variable that contains a pointer to an object. In theory, the object's +It is not necessary to hold a :term:`strong reference` (i.e. increment +the reference count) for every local variable that contains a pointer +to an object. In theory, the object's reference count goes up by one when the variable is made to point to it and it goes down by one when the variable goes out of scope. However, these two cancel each other out, so at the end the reference count hasn't changed. The only real reason to use the reference count is to prevent the object from being deallocated as long as our variable is pointing to it. If we know that there is at least one other reference to the object that lives at least as long as -our variable, there is no need to increment the reference count temporarily. +our variable, there is no need to take a new :term:`strong reference` +(i.e. increment the reference count) temporarily. An important situation where this arises is in objects that are passed as arguments to C functions in an extension module that are called from Python; the call mechanism guarantees to hold a reference to every argument for the duration of the call. However, a common pitfall is to extract an object from a list and hold on to it -for a while without incrementing its reference count. Some other operation might -conceivably remove the object from the list, decrementing its reference count +for a while without taking a new reference. Some other operation might +conceivably remove the object from the list, releasing that reference, and possibly deallocating it. The real danger is that innocent-looking operations may invoke arbitrary Python code which could do this; there is a code path which allows control to flow back to the user from a :c:func:`Py_DECREF`, so @@ -340,7 +370,8 @@ almost any operation is potentially dangerous. A safe approach is to always use the generic operations (functions whose name begins with ``PyObject_``, ``PyNumber_``, ``PySequence_`` or ``PyMapping_``). -These operations always increment the reference count of the object they return. +These operations always create a new :term:`strong reference` +(i.e. increment the reference count) of the object they return. This leaves the caller with the responsibility to call :c:func:`Py_DECREF` when they are done with the result; this soon becomes second nature. @@ -356,7 +387,7 @@ to objects (objects are not owned: they are always shared). "Owning a reference" means being responsible for calling Py_DECREF on it when the reference is no longer needed. Ownership can also be transferred, meaning that the code that receives ownership of the reference then becomes responsible for -eventually decref'ing it by calling :c:func:`Py_DECREF` or :c:func:`Py_XDECREF` +eventually releasing it by calling :c:func:`Py_DECREF` or :c:func:`Py_XDECREF` when it's no longer needed---or passing on this responsibility (usually to its caller). When a function passes ownership of a reference on to its caller, the caller is said to receive a *new* reference. When no ownership is transferred, @@ -414,9 +445,9 @@ For example, the above two blocks of code could be replaced by the following It is much more common to use :c:func:`PyObject_SetItem` and friends with items whose references you are only borrowing, like arguments that were passed in to -the function you are writing. In that case, their behaviour regarding reference -counts is much saner, since you don't have to increment a reference count so you -can give a reference away ("have it be stolen"). For example, this function +the function you are writing. In that case, their behaviour regarding references +is much saner, since you don't have to take a new reference just so you +can give that reference away ("have it be stolen"). For example, this function sets all items of a list (actually, any mutable sequence) to a given item:: int @@ -616,7 +647,7 @@ and lose important information about the exact cause of the error. .. index:: single: sum_sequence() A simple example of detecting exceptions and passing them on is shown in the -:c:func:`sum_sequence` example above. It so happens that this example doesn't +:c:func:`!sum_sequence` example above. It so happens that this example doesn't need to clean up any owned references when it detects an error. The following example function shows some error cleanup. First, to remind you why you like Python, we show the equivalent Python code:: @@ -705,9 +736,9 @@ interpreter can only be used after the interpreter has been initialized. .. index:: single: Py_Initialize() - module: builtins - module: __main__ - module: sys + pair: module; builtins + pair: module; __main__ + pair: module; sys triple: module; search; path single: path (in module sys) diff --git a/Doc/c-api/iterator.rst b/Doc/c-api/iterator.rst index 3fcf0991..6b7ba8c9 100644 --- a/Doc/c-api/iterator.rst +++ b/Doc/c-api/iterator.rst @@ -6,7 +6,7 @@ Iterator Objects ---------------- Python provides two general-purpose iterator objects. The first, a sequence -iterator, works with an arbitrary sequence supporting the :meth:`__getitem__` +iterator, works with an arbitrary sequence supporting the :meth:`~object.__getitem__` method. The second works with a callable object and a sentinel value, calling the callable for each item in the sequence, and ending the iteration when the sentinel value is returned. @@ -19,7 +19,7 @@ sentinel value is returned. types. -.. c:function:: int PySeqIter_Check(op) +.. c:function:: int PySeqIter_Check(PyObject *op) Return true if the type of *op* is :c:data:`PySeqIter_Type`. This function always succeeds. @@ -38,7 +38,7 @@ sentinel value is returned. two-argument form of the :func:`iter` built-in function. -.. c:function:: int PyCallIter_Check(op) +.. c:function:: int PyCallIter_Check(PyObject *op) Return true if the type of *op* is :c:data:`PyCallIter_Type`. This function always succeeds. diff --git a/Doc/c-api/list.rst b/Doc/c-api/list.rst index f9e65354..dbf35611 100644 --- a/Doc/c-api/list.rst +++ b/Doc/c-api/list.rst @@ -5,7 +5,7 @@ List Objects ------------ -.. index:: object: list +.. index:: pair: object; list .. c:type:: PyListObject @@ -45,7 +45,7 @@ List Objects .. c:function:: Py_ssize_t PyList_Size(PyObject *list) - .. index:: builtin: len + .. index:: pair: built-in function; len Return the length of the list object in *list*; this is equivalent to ``len(list)`` on a list object. @@ -138,7 +138,7 @@ List Objects .. c:function:: PyObject* PyList_AsTuple(PyObject *list) - .. index:: builtin: tuple + .. index:: pair: built-in function; tuple Return a new tuple object containing the contents of *list*; equivalent to ``tuple(list)``. diff --git a/Doc/c-api/long.rst b/Doc/c-api/long.rst index b3e455d0..f1354a34 100644 --- a/Doc/c-api/long.rst +++ b/Doc/c-api/long.rst @@ -5,8 +5,8 @@ Integer Objects --------------- -.. index:: object: long integer - object: integer +.. index:: pair: object; long integer + pair: object; integer All integers are implemented as "long" integer objects of arbitrary size. @@ -84,14 +84,15 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate. .. c:function:: PyObject* PyLong_FromString(const char *str, char **pend, int base) Return a new :c:type:`PyLongObject` based on the string value in *str*, which - is interpreted according to the radix in *base*. If *pend* is non-``NULL``, - *\*pend* will point to the first character in *str* which follows the - representation of the number. If *base* is ``0``, *str* is interpreted using - the :ref:`integers` definition; in this case, leading zeros in a - non-zero decimal number raises a :exc:`ValueError`. If *base* is not ``0``, - it must be between ``2`` and ``36``, inclusive. Leading spaces and single - underscores after a base specifier and between digits are ignored. If there - are no digits, :exc:`ValueError` will be raised. + is interpreted according to the radix in *base*, or ``NULL`` on failure. If + *pend* is non-``NULL``, *\*pend* will point to the end of *str* on success or + to the first character that could not be processed on error. If *base* is ``0``, + *str* is interpreted using the :ref:`integers` definition; in this case, leading + zeros in a non-zero decimal number raises a :exc:`ValueError`. If *base* is not + ``0``, it must be between ``2`` and ``36``, inclusive. Leading and trailing + whitespace and single underscores after a base specifier and between digits are + ignored. If there are no digits or *str* is not NULL-terminated following the + digits and trailing whitespace, :exc:`ValueError` will be raised. .. seealso:: Python methods :meth:`int.to_bytes` and :meth:`int.from_bytes` to convert a :c:type:`PyLongObject` to/from an array of bytes in base @@ -120,7 +121,7 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate. single: OverflowError (built-in exception) Return a C :c:expr:`long` representation of *obj*. If *obj* is not an - instance of :c:type:`PyLongObject`, first call its :meth:`__index__` method + instance of :c:type:`PyLongObject`, first call its :meth:`~object.__index__` method (if present) to convert it to a :c:type:`PyLongObject`. Raise :exc:`OverflowError` if the value of *obj* is out of range for a @@ -129,30 +130,30 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate. Returns ``-1`` on error. Use :c:func:`PyErr_Occurred` to disambiguate. .. versionchanged:: 3.8 - Use :meth:`__index__` if available. + Use :meth:`~object.__index__` if available. .. versionchanged:: 3.10 - This function will no longer use :meth:`__int__`. + This function will no longer use :meth:`~object.__int__`. .. c:function:: long PyLong_AsLongAndOverflow(PyObject *obj, int *overflow) Return a C :c:expr:`long` representation of *obj*. If *obj* is not an - instance of :c:type:`PyLongObject`, first call its :meth:`__index__` + instance of :c:type:`PyLongObject`, first call its :meth:`~object.__index__` method (if present) to convert it to a :c:type:`PyLongObject`. - If the value of *obj* is greater than :const:`LONG_MAX` or less than - :const:`LONG_MIN`, set *\*overflow* to ``1`` or ``-1``, respectively, and + If the value of *obj* is greater than :c:macro:`LONG_MAX` or less than + :c:macro:`LONG_MIN`, set *\*overflow* to ``1`` or ``-1``, respectively, and return ``-1``; otherwise, set *\*overflow* to ``0``. If any other exception occurs set *\*overflow* to ``0`` and return ``-1`` as usual. Returns ``-1`` on error. Use :c:func:`PyErr_Occurred` to disambiguate. .. versionchanged:: 3.8 - Use :meth:`__index__` if available. + Use :meth:`~object.__index__` if available. .. versionchanged:: 3.10 - This function will no longer use :meth:`__int__`. + This function will no longer use :meth:`~object.__int__`. .. c:function:: long long PyLong_AsLongLong(PyObject *obj) @@ -161,7 +162,7 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate. single: OverflowError (built-in exception) Return a C :c:expr:`long long` representation of *obj*. If *obj* is not an - instance of :c:type:`PyLongObject`, first call its :meth:`__index__` method + instance of :c:type:`PyLongObject`, first call its :meth:`~object.__index__` method (if present) to convert it to a :c:type:`PyLongObject`. Raise :exc:`OverflowError` if the value of *obj* is out of range for a @@ -170,20 +171,20 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate. Returns ``-1`` on error. Use :c:func:`PyErr_Occurred` to disambiguate. .. versionchanged:: 3.8 - Use :meth:`__index__` if available. + Use :meth:`~object.__index__` if available. .. versionchanged:: 3.10 - This function will no longer use :meth:`__int__`. + This function will no longer use :meth:`~object.__int__`. .. c:function:: long long PyLong_AsLongLongAndOverflow(PyObject *obj, int *overflow) Return a C :c:expr:`long long` representation of *obj*. If *obj* is not an - instance of :c:type:`PyLongObject`, first call its :meth:`__index__` method + instance of :c:type:`PyLongObject`, first call its :meth:`~object.__index__` method (if present) to convert it to a :c:type:`PyLongObject`. - If the value of *obj* is greater than :const:`LLONG_MAX` or less than - :const:`LLONG_MIN`, set *\*overflow* to ``1`` or ``-1``, respectively, + If the value of *obj* is greater than :c:macro:`LLONG_MAX` or less than + :c:macro:`LLONG_MIN`, set *\*overflow* to ``1`` or ``-1``, respectively, and return ``-1``; otherwise, set *\*overflow* to ``0``. If any other exception occurs set *\*overflow* to ``0`` and return ``-1`` as usual. @@ -192,10 +193,10 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate. .. versionadded:: 3.2 .. versionchanged:: 3.8 - Use :meth:`__index__` if available. + Use :meth:`~object.__index__` if available. .. versionchanged:: 3.10 - This function will no longer use :meth:`__int__`. + This function will no longer use :meth:`~object.__int__`. .. c:function:: Py_ssize_t PyLong_AsSsize_t(PyObject *pylong) @@ -266,7 +267,7 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate. .. c:function:: unsigned long PyLong_AsUnsignedLongMask(PyObject *obj) Return a C :c:expr:`unsigned long` representation of *obj*. If *obj* is not - an instance of :c:type:`PyLongObject`, first call its :meth:`__index__` + an instance of :c:type:`PyLongObject`, first call its :meth:`~object.__index__` method (if present) to convert it to a :c:type:`PyLongObject`. If the value of *obj* is out of range for an :c:expr:`unsigned long`, @@ -276,17 +277,17 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate. disambiguate. .. versionchanged:: 3.8 - Use :meth:`__index__` if available. + Use :meth:`~object.__index__` if available. .. versionchanged:: 3.10 - This function will no longer use :meth:`__int__`. + This function will no longer use :meth:`~object.__int__`. .. c:function:: unsigned long long PyLong_AsUnsignedLongLongMask(PyObject *obj) Return a C :c:expr:`unsigned long long` representation of *obj*. If *obj* is not an instance of :c:type:`PyLongObject`, first call its - :meth:`__index__` method (if present) to convert it to a + :meth:`~object.__index__` method (if present) to convert it to a :c:type:`PyLongObject`. If the value of *obj* is out of range for an :c:expr:`unsigned long long`, @@ -296,10 +297,10 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate. to disambiguate. .. versionchanged:: 3.8 - Use :meth:`__index__` if available. + Use :meth:`~object.__index__` if available. .. versionchanged:: 3.10 - This function will no longer use :meth:`__int__`. + This function will no longer use :meth:`~object.__int__`. .. c:function:: double PyLong_AsDouble(PyObject *pylong) @@ -321,3 +322,27 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate. with :c:func:`PyLong_FromVoidPtr`. Returns ``NULL`` on error. Use :c:func:`PyErr_Occurred` to disambiguate. + + +.. c:function:: int PyUnstable_Long_IsCompact(const PyLongObject* op) + + Return 1 if *op* is compact, 0 otherwise. + + This function makes it possible for performance-critical code to implement + a “fast path” for small integers. For compact values use + :c:func:`PyUnstable_Long_CompactValue`; for others fall back to a + :c:func:`PyLong_As* ` function or + :c:func:`calling ` :meth:`int.to_bytes`. + + The speedup is expected to be negligible for most users. + + Exactly what values are considered compact is an implementation detail + and is subject to change. + +.. c:function:: Py_ssize_t PyUnstable_Long_CompactValue(const PyLongObject* op) + + If *op* is compact, as determined by :c:func:`PyUnstable_Long_IsCompact`, + return its value. + + Otherwise, the return value is undefined. + diff --git a/Doc/c-api/mapping.rst b/Doc/c-api/mapping.rst index 3c9d282c..0c42b917 100644 --- a/Doc/c-api/mapping.rst +++ b/Doc/c-api/mapping.rst @@ -13,14 +13,14 @@ See also :c:func:`PyObject_GetItem`, :c:func:`PyObject_SetItem` and Return ``1`` if the object provides the mapping protocol or supports slicing, and ``0`` otherwise. Note that it returns ``1`` for Python classes with - a :meth:`__getitem__` method, since in general it is impossible to + a :meth:`~object.__getitem__` method, since in general it is impossible to determine what type of keys the class supports. This function always succeeds. .. c:function:: Py_ssize_t PyMapping_Size(PyObject *o) Py_ssize_t PyMapping_Length(PyObject *o) - .. index:: builtin: len + .. index:: pair: built-in function; len Returns the number of keys in object *o* on success, and ``-1`` on failure. This is equivalent to the Python expression ``len(o)``. @@ -28,30 +28,28 @@ See also :c:func:`PyObject_GetItem`, :c:func:`PyObject_SetItem` and .. c:function:: PyObject* PyMapping_GetItemString(PyObject *o, const char *key) - Return element of *o* corresponding to the string *key* or ``NULL`` on failure. - This is the equivalent of the Python expression ``o[key]``. - See also :c:func:`PyObject_GetItem`. + This is the same as :c:func:`PyObject_GetItem`, but *key* is + specified as a :c:expr:`const char*` UTF-8 encoded bytes string, + rather than a :c:expr:`PyObject*`. .. c:function:: int PyMapping_SetItemString(PyObject *o, const char *key, PyObject *v) - Map the string *key* to the value *v* in object *o*. Returns ``-1`` on - failure. This is the equivalent of the Python statement ``o[key] = v``. - See also :c:func:`PyObject_SetItem`. This function *does not* steal a - reference to *v*. + This is the same as :c:func:`PyObject_SetItem`, but *key* is + specified as a :c:expr:`const char*` UTF-8 encoded bytes string, + rather than a :c:expr:`PyObject*`. .. c:function:: int PyMapping_DelItem(PyObject *o, PyObject *key) - Remove the mapping for the object *key* from the object *o*. Return ``-1`` - on failure. This is equivalent to the Python statement ``del o[key]``. This is an alias of :c:func:`PyObject_DelItem`. .. c:function:: int PyMapping_DelItemString(PyObject *o, const char *key) - Remove the mapping for the string *key* from the object *o*. Return ``-1`` - on failure. This is equivalent to the Python statement ``del o[key]``. + This is the same as :c:func:`PyObject_DelItem`, but *key* is + specified as a :c:expr:`const char*` UTF-8 encoded bytes string, + rather than a :c:expr:`PyObject*`. .. c:function:: int PyMapping_HasKey(PyObject *o, PyObject *key) @@ -60,20 +58,25 @@ See also :c:func:`PyObject_GetItem`, :c:func:`PyObject_SetItem` and This is equivalent to the Python expression ``key in o``. This function always succeeds. - Note that exceptions which occur while calling the :meth:`__getitem__` - method will get suppressed. - To get error reporting use :c:func:`PyObject_GetItem()` instead. + .. note:: + + Exceptions which occur when this calls :meth:`~object.__getitem__` + method are silently ignored. + For proper error handling, use :c:func:`PyObject_GetItem()` instead. .. c:function:: int PyMapping_HasKeyString(PyObject *o, const char *key) - Return ``1`` if the mapping object has the key *key* and ``0`` otherwise. - This is equivalent to the Python expression ``key in o``. - This function always succeeds. + This is the same as :c:func:`PyMapping_HasKey`, but *key* is + specified as a :c:expr:`const char*` UTF-8 encoded bytes string, + rather than a :c:expr:`PyObject*`. + + .. note:: - Note that exceptions which occur while calling the :meth:`__getitem__` - method and creating a temporary string object will get suppressed. - To get error reporting use :c:func:`PyMapping_GetItemString()` instead. + Exceptions that occur when this calls :meth:`~object.__getitem__` + method or while creating the temporary :class:`str` + object are silently ignored. + For proper error handling, use :c:func:`PyMapping_GetItemString` instead. .. c:function:: PyObject* PyMapping_Keys(PyObject *o) diff --git a/Doc/c-api/marshal.rst b/Doc/c-api/marshal.rst index 8e25968c..489f1580 100644 --- a/Doc/c-api/marshal.rst +++ b/Doc/c-api/marshal.rst @@ -25,12 +25,16 @@ unmarshalling. Version 2 uses a binary format for floating point numbers. the least-significant 32 bits of *value*; regardless of the size of the native :c:expr:`long` type. *version* indicates the file format. + This function can fail, in which case it sets the error indicator. + Use :c:func:`PyErr_Occurred` to check for that. .. c:function:: void PyMarshal_WriteObjectToFile(PyObject *value, FILE *file, int version) Marshal a Python object, *value*, to *file*. *version* indicates the file format. + This function can fail, in which case it sets the error indicator. + Use :c:func:`PyErr_Occurred` to check for that. .. c:function:: PyObject* PyMarshal_WriteObjectToString(PyObject *value, int version) diff --git a/Doc/c-api/memory.rst b/Doc/c-api/memory.rst index 7041c15d..1df8c2b9 100644 --- a/Doc/c-api/memory.rst +++ b/Doc/c-api/memory.rst @@ -136,7 +136,7 @@ need to be held. The :ref:`default raw memory allocator ` uses the following functions: :c:func:`malloc`, :c:func:`calloc`, :c:func:`realloc` -and :c:func:`free`; call ``malloc(1)`` (or ``calloc(1, 1)``) when requesting +and :c:func:`!free`; call ``malloc(1)`` (or ``calloc(1, 1)``) when requesting zero bytes. .. versionadded:: 3.4 @@ -264,14 +264,14 @@ The following type-oriented macros are provided for convenience. Note that *TYPE* refers to any C type. -.. c:function:: TYPE* PyMem_New(TYPE, size_t n) +.. c:macro:: PyMem_New(TYPE, n) Same as :c:func:`PyMem_Malloc`, but allocates ``(n * sizeof(TYPE))`` bytes of memory. Returns a pointer cast to :c:expr:`TYPE*`. The memory will not have been initialized in any way. -.. c:function:: TYPE* PyMem_Resize(void *p, TYPE, size_t n) +.. c:macro:: PyMem_Resize(p, TYPE, n) Same as :c:func:`PyMem_Realloc`, but the memory block is resized to ``(n * sizeof(TYPE))`` bytes. Returns a pointer cast to :c:expr:`TYPE*`. On return, @@ -423,7 +423,7 @@ Customize Memory Allocators +----------------------------------------------------------+---------------------------------------+ .. versionchanged:: 3.5 - The :c:type:`PyMemAllocator` structure was renamed to + The :c:type:`!PyMemAllocator` structure was renamed to :c:type:`PyMemAllocatorEx` and a new ``calloc`` field was added. @@ -431,6 +431,8 @@ Customize Memory Allocators Enum used to identify an allocator domain. Domains: + .. c:namespace:: NULL + .. c:macro:: PYMEM_DOMAIN_RAW Functions: @@ -470,10 +472,14 @@ Customize Memory Allocators The new allocator must return a distinct non-``NULL`` pointer when requesting zero bytes. - For the :c:data:`PYMEM_DOMAIN_RAW` domain, the allocator must be + For the :c:macro:`PYMEM_DOMAIN_RAW` domain, the allocator must be thread-safe: the :term:`GIL ` is not held when the allocator is called. + For the remaining domains, the allocator must also be thread-safe: + the allocator may be called in different interpreters that do not + share a ``GIL``. + If the new allocator is not a hook (does not call the previous allocator), the :c:func:`PyMem_SetupDebugHooks` function must be called to reinstall the debug hooks on top on the new allocator. @@ -498,6 +504,8 @@ Customize Memory Allocators **must** wrap the existing allocator. Substituting the current allocator for some other arbitrary one is **not supported**. + .. versionchanged:: 3.12 + All allocators must be thread-safe. .. c:function:: void PyMem_SetupDebugHooks(void) @@ -536,8 +544,8 @@ Runtime checks: - Detect write before the start of the buffer (buffer underflow). - Detect write after the end of the buffer (buffer overflow). - Check that the :term:`GIL ` is held when - allocator functions of :c:data:`PYMEM_DOMAIN_OBJ` (ex: - :c:func:`PyObject_Malloc`) and :c:data:`PYMEM_DOMAIN_MEM` (ex: + allocator functions of :c:macro:`PYMEM_DOMAIN_OBJ` (ex: + :c:func:`PyObject_Malloc`) and :c:macro:`PYMEM_DOMAIN_MEM` (ex: :c:func:`PyMem_Malloc`) domains are called. On error, the debug hooks use the :mod:`tracemalloc` module to get the @@ -557,9 +565,9 @@ that the treatment of negative indices differs from a Python slice): ``p[-S]`` API identifier (ASCII character): - * ``'r'`` for :c:data:`PYMEM_DOMAIN_RAW`. - * ``'m'`` for :c:data:`PYMEM_DOMAIN_MEM`. - * ``'o'`` for :c:data:`PYMEM_DOMAIN_OBJ`. + * ``'r'`` for :c:macro:`PYMEM_DOMAIN_RAW`. + * ``'m'`` for :c:macro:`PYMEM_DOMAIN_MEM`. + * ``'o'`` for :c:macro:`PYMEM_DOMAIN_OBJ`. ``p[-S+1:0]`` Copies of PYMEM_FORBIDDENBYTE. Used to catch under- writes and reads. @@ -581,7 +589,7 @@ that the treatment of negative indices differs from a Python slice): default). A serial number, incremented by 1 on each call to a malloc-like or - realloc-like function. Big-endian ``size_t``. If "bad memory" is detected + realloc-like function. Big-endian :c:type:`size_t`. If "bad memory" is detected later, the serial number gives an excellent way to set a breakpoint on the next run, to capture the instant at which this block was passed out. The static function bumpserialno() in obmalloc.c is the only place the serial @@ -601,7 +609,7 @@ PYMEM_CLEANBYTE (meaning uninitialized memory is getting used). compiled in release mode. On error, the debug hooks now use :mod:`tracemalloc` to get the traceback where a memory block was allocated. The debug hooks now also check if the GIL is held when functions of - :c:data:`PYMEM_DOMAIN_OBJ` and :c:data:`PYMEM_DOMAIN_MEM` domains are + :c:macro:`PYMEM_DOMAIN_OBJ` and :c:macro:`PYMEM_DOMAIN_MEM` domains are called. .. versionchanged:: 3.8 @@ -622,13 +630,13 @@ with a fixed size of 256 KiB. It falls back to :c:func:`PyMem_RawMalloc` and :c:func:`PyMem_RawRealloc` for allocations larger than 512 bytes. *pymalloc* is the :ref:`default allocator ` of the -:c:data:`PYMEM_DOMAIN_MEM` (ex: :c:func:`PyMem_Malloc`) and -:c:data:`PYMEM_DOMAIN_OBJ` (ex: :c:func:`PyObject_Malloc`) domains. +:c:macro:`PYMEM_DOMAIN_MEM` (ex: :c:func:`PyMem_Malloc`) and +:c:macro:`PYMEM_DOMAIN_OBJ` (ex: :c:func:`PyObject_Malloc`) domains. The arena allocator uses the following functions: -* :c:func:`VirtualAlloc` and :c:func:`VirtualFree` on Windows, -* :c:func:`mmap` and :c:func:`munmap` if available, +* :c:func:`!VirtualAlloc` and :c:func:`!VirtualFree` on Windows, +* :c:func:`!mmap` and :c:func:`!munmap` if available, * :c:func:`malloc` and :c:func:`free` otherwise. This allocator is disabled if Python is configured with the @@ -732,8 +740,8 @@ allocators operating on different heaps. :: free(buf1); /* Fatal -- should be PyMem_Del() */ In addition to the functions aimed at handling raw memory blocks from the Python -heap, objects in Python are allocated and released with :c:func:`PyObject_New`, -:c:func:`PyObject_NewVar` and :c:func:`PyObject_Del`. +heap, objects in Python are allocated and released with :c:macro:`PyObject_New`, +:c:macro:`PyObject_NewVar` and :c:func:`PyObject_Del`. These will be explained in the next chapter on defining and implementing new object types in C. diff --git a/Doc/c-api/memoryview.rst b/Doc/c-api/memoryview.rst index ebd5c776..2aa43318 100644 --- a/Doc/c-api/memoryview.rst +++ b/Doc/c-api/memoryview.rst @@ -3,7 +3,7 @@ .. _memoryview-objects: .. index:: - object: memoryview + pair: object; memoryview MemoryView objects ------------------ diff --git a/Doc/c-api/method.rst b/Doc/c-api/method.rst index 6e7e1e21..0d75ab8e 100644 --- a/Doc/c-api/method.rst +++ b/Doc/c-api/method.rst @@ -5,10 +5,10 @@ Instance Method Objects ----------------------- -.. index:: object: instancemethod +.. index:: pair: object; instancemethod -An instance method is a wrapper for a :c:data:`PyCFunction` and the new way -to bind a :c:data:`PyCFunction` to a class object. It replaces the former call +An instance method is a wrapper for a :c:type:`PyCFunction` and the new way +to bind a :c:type:`PyCFunction` to a class object. It replaces the former call ``PyMethod_New(func, NULL, class)``. @@ -47,7 +47,7 @@ to bind a :c:data:`PyCFunction` to a class object. It replaces the former call Method Objects -------------- -.. index:: object: method +.. index:: pair: object; method Methods are bound function objects. Methods are always bound to an instance of a user-defined class. Unbound methods (methods bound to a class object) are diff --git a/Doc/c-api/module.rst b/Doc/c-api/module.rst index e2ba157b..f941f0c7 100644 --- a/Doc/c-api/module.rst +++ b/Doc/c-api/module.rst @@ -5,7 +5,7 @@ Module Objects -------------- -.. index:: object: module +.. index:: pair: object; module .. c:var:: PyTypeObject PyModule_Type @@ -119,7 +119,7 @@ Module Objects encoded to 'utf-8'. .. deprecated:: 3.2 - :c:func:`PyModule_GetFilename` raises :c:type:`UnicodeEncodeError` on + :c:func:`PyModule_GetFilename` raises :exc:`UnicodeEncodeError` on unencodable filenames, use :c:func:`PyModule_GetFilenameObject` instead. @@ -145,7 +145,7 @@ or request "multi-phase initialization" by returning the definition struct itsel .. c:member:: PyModuleDef_Base m_base - Always initialize this member to :const:`PyModuleDef_HEAD_INIT`. + Always initialize this member to :c:macro:`PyModuleDef_HEAD_INIT`. .. c:member:: const char *m_name @@ -164,7 +164,7 @@ or request "multi-phase initialization" by returning the definition struct itsel This memory area is allocated based on *m_size* on module creation, and freed when the module object is deallocated, after the - :c:member:`m_free` function has been called, if present. + :c:member:`~PyModuleDef.m_free` function has been called, if present. Setting ``m_size`` to ``-1`` means that the module does not support sub-interpreters, because it has global state. @@ -202,7 +202,7 @@ or request "multi-phase initialization" by returning the definition struct itsel This function is not called if the module state was requested but is not allocated yet. This is the case immediately after the module is created and before the module is executed (:c:data:`Py_mod_exec` function). More - precisely, this function is not called if :c:member:`m_size` is greater + precisely, this function is not called if :c:member:`~PyModuleDef.m_size` is greater than 0 and the module state (as returned by :c:func:`PyModule_GetState`) is ``NULL``. @@ -217,7 +217,7 @@ or request "multi-phase initialization" by returning the definition struct itsel This function is not called if the module state was requested but is not allocated yet. This is the case immediately after the module is created and before the module is executed (:c:data:`Py_mod_exec` function). More - precisely, this function is not called if :c:member:`m_size` is greater + precisely, this function is not called if :c:member:`~PyModuleDef.m_size` is greater than 0 and the module state (as returned by :c:func:`PyModule_GetState`) is ``NULL``. @@ -238,7 +238,7 @@ or request "multi-phase initialization" by returning the definition struct itsel This function is not called if the module state was requested but is not allocated yet. This is the case immediately after the module is created and before the module is executed (:c:data:`Py_mod_exec` function). More - precisely, this function is not called if :c:member:`m_size` is greater + precisely, this function is not called if :c:member:`~PyModuleDef.m_size` is greater than 0 and the module state (as returned by :c:func:`PyModule_GetState`) is ``NULL``. @@ -256,7 +256,7 @@ of the following two module creation functions: Create a new module object, given the definition in *def*. This behaves like :c:func:`PyModule_Create2` with *module_api_version* set to - :const:`PYTHON_API_VERSION`. + :c:macro:`PYTHON_API_VERSION`. .. c:function:: PyObject* PyModule_Create2(PyModuleDef *def, int module_api_version) @@ -282,7 +282,7 @@ An alternate way to specify extensions is to request "multi-phase initialization Extension modules created this way behave more like Python modules: the initialization is split between the *creation phase*, when the module object is created, and the *execution phase*, when it is populated. -The distinction is similar to the :py:meth:`__new__` and :py:meth:`__init__` methods +The distinction is similar to the :py:meth:`!__new__` and :py:meth:`!__init__` methods of classes. Unlike modules created using single-phase initialization, these modules are not @@ -293,7 +293,7 @@ By default, multiple modules created from the same definition should be independent: changes to one should not affect the others. This means that all state should be specific to the module object (using e.g. using :c:func:`PyModule_GetState`), or its contents (such as the module's -:attr:`__dict__` or individual classes created with :c:func:`PyType_FromSpec`). +:attr:`~object.__dict__` or individual classes created with :c:func:`PyType_FromSpec`). All modules created using multi-phase initialization are expected to support :ref:`sub-interpreters `. Making sure multiple modules @@ -338,6 +338,7 @@ The available slot types are: The *value* pointer of this slot must point to a function of the signature: .. c:function:: PyObject* create_module(PyObject *spec, PyModuleDef *def) + :noindex: The function receives a :py:class:`~importlib.machinery.ModuleSpec` instance, as defined in :PEP:`451`, and the module definition. @@ -372,10 +373,44 @@ The available slot types are: The signature of the function is: .. c:function:: int exec_module(PyObject* module) + :noindex: If multiple ``Py_mod_exec`` slots are specified, they are processed in the order they appear in the *m_slots* array. +.. c:macro:: Py_mod_multiple_interpreters + + Specifies one of the following values: + + .. c:namespace:: NULL + + .. c:macro:: Py_MOD_MULTIPLE_INTERPRETERS_NOT_SUPPORTED + + The module does not support being imported in subinterpreters. + + .. c:macro:: Py_MOD_MULTIPLE_INTERPRETERS_SUPPORTED + + The module supports being imported in subinterpreters, + but only when they share the main interpreter's GIL. + (See :ref:`isolating-extensions-howto`.) + + .. c:macro:: Py_MOD_PER_INTERPRETER_GIL_SUPPORTED + + The module supports being imported in subinterpreters, + even when they have their own GIL. + (See :ref:`isolating-extensions-howto`.) + + This slot determines whether or not importing this module + in a subinterpreter will fail. + + Multiple ``Py_mod_multiple_interpreters`` slots may not be specified + in one module definition. + + If ``Py_mod_multiple_interpreters`` is not specified, the import + machinery defaults to ``Py_MOD_MULTIPLE_INTERPRETERS_NOT_SUPPORTED``. + + .. versionadded:: 3.12 + See :PEP:`489` for more details on multi-phase initialization. Low-level module creation functions @@ -388,15 +423,15 @@ objects dynamically. Note that both ``PyModule_FromDefAndSpec`` and .. c:function:: PyObject * PyModule_FromDefAndSpec(PyModuleDef *def, PyObject *spec) - Create a new module object, given the definition in *module* and the + Create a new module object, given the definition in *def* and the ModuleSpec *spec*. This behaves like :c:func:`PyModule_FromDefAndSpec2` - with *module_api_version* set to :const:`PYTHON_API_VERSION`. + with *module_api_version* set to :c:macro:`PYTHON_API_VERSION`. .. versionadded:: 3.5 .. c:function:: PyObject * PyModule_FromDefAndSpec2(PyModuleDef *def, PyObject *spec, int module_api_version) - Create a new module object, given the definition in *module* and the + Create a new module object, given the definition in *def* and the ModuleSpec *spec*, assuming the API version *module_api_version*. If that version does not match the version of the running interpreter, a :exc:`RuntimeWarning` is emitted. @@ -498,7 +533,7 @@ state: .. note:: Unlike other functions that steal references, ``PyModule_AddObject()`` - only decrements the reference count of *value* **on success**. + only releases the reference to *value* **on success**. This means that its return value must be checked, and calling code must :c:func:`Py_DECREF` *value* manually on error. @@ -555,7 +590,7 @@ state: ``NULL``-terminated. Return ``-1`` on error, ``0`` on success. -.. c:function:: int PyModule_AddIntMacro(PyObject *module, macro) +.. c:macro:: PyModule_AddIntMacro(module, macro) Add an int constant to *module*. The name and the value are taken from *macro*. For example ``PyModule_AddIntMacro(module, AF_INET)`` adds the int @@ -563,7 +598,7 @@ state: Return ``-1`` on error, ``0`` on success. -.. c:function:: int PyModule_AddStringMacro(PyObject *module, macro) +.. c:macro:: PyModule_AddStringMacro(module, macro) Add a string constant to *module*. diff --git a/Doc/c-api/none.rst b/Doc/c-api/none.rst index 26d2b7aa..dd8bfb56 100644 --- a/Doc/c-api/none.rst +++ b/Doc/c-api/none.rst @@ -5,22 +5,22 @@ The ``None`` Object ------------------- -.. index:: object: None +.. index:: pair: object; None Note that the :c:type:`PyTypeObject` for ``None`` is not directly exposed in the Python/C API. Since ``None`` is a singleton, testing for object identity (using -``==`` in C) is sufficient. There is no :c:func:`PyNone_Check` function for the +``==`` in C) is sufficient. There is no :c:func:`!PyNone_Check` function for the same reason. .. c:var:: PyObject* Py_None - The Python ``None`` object, denoting lack of value. This object has no methods. - It needs to be treated just like any other object with respect to reference - counts. + The Python ``None`` object, denoting lack of value. This object has no methods + and is `immortal `_. +.. versionchanged:: 3.12 + :c:data:`Py_None` is immortal. .. c:macro:: Py_RETURN_NONE - Properly handle returning :c:data:`Py_None` from within a C function (that is, - increment the reference count of ``None`` and return it.) + Return :c:data:`Py_None` from a function. diff --git a/Doc/c-api/number.rst b/Doc/c-api/number.rst index 70b91f8c..13d3c5af 100644 --- a/Doc/c-api/number.rst +++ b/Doc/c-api/number.rst @@ -64,7 +64,7 @@ Number Protocol .. c:function:: PyObject* PyNumber_Divmod(PyObject *o1, PyObject *o2) - .. index:: builtin: divmod + .. index:: pair: built-in function; divmod See the built-in function :func:`divmod`. Returns ``NULL`` on failure. This is the equivalent of the Python expression ``divmod(o1, o2)``. @@ -72,7 +72,7 @@ Number Protocol .. c:function:: PyObject* PyNumber_Power(PyObject *o1, PyObject *o2, PyObject *o3) - .. index:: builtin: pow + .. index:: pair: built-in function; pow See the built-in function :func:`pow`. Returns ``NULL`` on failure. This is the equivalent of the Python expression ``pow(o1, o2, o3)``, where *o3* is optional. @@ -94,7 +94,7 @@ Number Protocol .. c:function:: PyObject* PyNumber_Absolute(PyObject *o) - .. index:: builtin: abs + .. index:: pair: built-in function; abs Returns the absolute value of *o*, or ``NULL`` on failure. This is the equivalent of the Python expression ``abs(o)``. @@ -192,7 +192,7 @@ Number Protocol .. c:function:: PyObject* PyNumber_InPlacePower(PyObject *o1, PyObject *o2, PyObject *o3) - .. index:: builtin: pow + .. index:: pair: built-in function; pow See the built-in function :func:`pow`. Returns ``NULL`` on failure. The operation is done *in-place* when *o1* supports it. This is the equivalent of the Python @@ -238,7 +238,7 @@ Number Protocol .. c:function:: PyObject* PyNumber_Long(PyObject *o) - .. index:: builtin: int + .. index:: pair: built-in function; int Returns the *o* converted to an integer object on success, or ``NULL`` on failure. This is the equivalent of the Python expression ``int(o)``. @@ -246,7 +246,7 @@ Number Protocol .. c:function:: PyObject* PyNumber_Float(PyObject *o) - .. index:: builtin: float + .. index:: pair: built-in function; float Returns the *o* converted to a float object on success, or ``NULL`` on failure. This is the equivalent of the Python expression ``float(o)``. diff --git a/Doc/c-api/object.rst b/Doc/c-api/object.rst index 5a25a2b6..d88de794 100644 --- a/Doc/c-api/object.rst +++ b/Doc/c-api/object.rst @@ -15,15 +15,15 @@ Object Protocol .. c:macro:: Py_RETURN_NOTIMPLEMENTED Properly handle returning :c:data:`Py_NotImplemented` from within a C - function (that is, increment the reference count of NotImplemented and - return it). + function (that is, create a new :term:`strong reference` + to NotImplemented and return it). .. c:function:: int PyObject_Print(PyObject *o, FILE *fp, int flags) Print an object *o*, on file *fp*. Returns ``-1`` on error. The flags argument is used to enable certain printing options. The only option currently supported - is :const:`Py_PRINT_RAW`; if given, the :func:`str` of the object is written + is :c:macro:`Py_PRINT_RAW`; if given, the :func:`str` of the object is written instead of the :func:`repr`. @@ -33,21 +33,25 @@ Object Protocol is equivalent to the Python expression ``hasattr(o, attr_name)``. This function always succeeds. - Note that exceptions which occur while calling :meth:`__getattr__` and - :meth:`__getattribute__` methods will get suppressed. - To get error reporting use :c:func:`PyObject_GetAttr()` instead. + .. note:: + + Exceptions that occur when this calls :meth:`~object.__getattr__` and + :meth:`~object.__getattribute__` methods are silently ignored. + For proper error handling, use :c:func:`PyObject_GetAttr` instead. .. c:function:: int PyObject_HasAttrString(PyObject *o, const char *attr_name) - Returns ``1`` if *o* has the attribute *attr_name*, and ``0`` otherwise. This - is equivalent to the Python expression ``hasattr(o, attr_name)``. This function - always succeeds. + This is the same as :c:func:`PyObject_HasAttr`, but *attr_name* is + specified as a :c:expr:`const char*` UTF-8 encoded bytes string, + rather than a :c:expr:`PyObject*`. - Note that exceptions which occur while calling :meth:`__getattr__` and - :meth:`__getattribute__` methods and creating a temporary string object - will get suppressed. - To get error reporting use :c:func:`PyObject_GetAttrString()` instead. + .. note:: + + Exceptions that occur when this calls :meth:`~object.__getattr__` and + :meth:`~object.__getattribute__` methods or while creating the temporary + :class:`str` object are silently ignored. + For proper error handling, use :c:func:`PyObject_GetAttrString` instead. .. c:function:: PyObject* PyObject_GetAttr(PyObject *o, PyObject *attr_name) @@ -59,9 +63,9 @@ Object Protocol .. c:function:: PyObject* PyObject_GetAttrString(PyObject *o, const char *attr_name) - Retrieve an attribute named *attr_name* from object *o*. Returns the attribute - value on success, or ``NULL`` on failure. This is the equivalent of the Python - expression ``o.attr_name``. + This is the same as :c:func:`PyObject_GetAttr`, but *attr_name* is + specified as a :c:expr:`const char*` UTF-8 encoded bytes string, + rather than a :c:expr:`PyObject*`. .. c:function:: PyObject* PyObject_GenericGetAttr(PyObject *o, PyObject *name) @@ -88,10 +92,9 @@ Object Protocol .. c:function:: int PyObject_SetAttrString(PyObject *o, const char *attr_name, PyObject *v) - Set the value of the attribute named *attr_name*, for object *o*, to the value - *v*. Raise an exception and return ``-1`` on failure; - return ``0`` on success. This is the equivalent of the Python statement - ``o.attr_name = v``. + This is the same as :c:func:`PyObject_SetAttr`, but *attr_name* is + specified as a :c:expr:`const char*` UTF-8 encoded bytes string, + rather than a :c:expr:`PyObject*`. If *v* is ``NULL``, the attribute is deleted, but this feature is deprecated in favour of using :c:func:`PyObject_DelAttrString`. @@ -117,8 +120,9 @@ Object Protocol .. c:function:: int PyObject_DelAttrString(PyObject *o, const char *attr_name) - Delete attribute named *attr_name*, for object *o*. Returns ``-1`` on failure. - This is the equivalent of the Python statement ``del o.attr_name``. + This is the same as :c:func:`PyObject_DelAttr`, but *attr_name* is + specified as a :c:expr:`const char*` UTF-8 encoded bytes string, + rather than a :c:expr:`PyObject*`. .. c:function:: PyObject* PyObject_GenericGetDict(PyObject *o, void *context) @@ -158,8 +162,8 @@ Object Protocol .. c:function:: PyObject* PyObject_RichCompare(PyObject *o1, PyObject *o2, int opid) Compare the values of *o1* and *o2* using the operation specified by *opid*, - which must be one of :const:`Py_LT`, :const:`Py_LE`, :const:`Py_EQ`, - :const:`Py_NE`, :const:`Py_GT`, or :const:`Py_GE`, corresponding to ``<``, + which must be one of :c:macro:`Py_LT`, :c:macro:`Py_LE`, :c:macro:`Py_EQ`, + :c:macro:`Py_NE`, :c:macro:`Py_GT`, or :c:macro:`Py_GE`, corresponding to ``<``, ``<=``, ``==``, ``!=``, ``>``, or ``>=`` respectively. This is the equivalent of the Python expression ``o1 op o2``, where ``op`` is the operator corresponding to *opid*. Returns the value of the comparison on success, or ``NULL`` on failure. @@ -168,8 +172,8 @@ Object Protocol .. c:function:: int PyObject_RichCompareBool(PyObject *o1, PyObject *o2, int opid) Compare the values of *o1* and *o2* using the operation specified by *opid*, - which must be one of :const:`Py_LT`, :const:`Py_LE`, :const:`Py_EQ`, - :const:`Py_NE`, :const:`Py_GT`, or :const:`Py_GE`, corresponding to ``<``, + which must be one of :c:macro:`Py_LT`, :c:macro:`Py_LE`, :c:macro:`Py_EQ`, + :c:macro:`Py_NE`, :c:macro:`Py_GT`, or :c:macro:`Py_GE`, corresponding to ``<``, ``<=``, ``==``, ``!=``, ``>``, or ``>=`` respectively. Returns ``-1`` on error, ``0`` if the result is false, ``1`` otherwise. This is the equivalent of the Python expression ``o1 op o2``, where ``op`` is the operator corresponding to @@ -177,11 +181,20 @@ Object Protocol .. note:: If *o1* and *o2* are the same object, :c:func:`PyObject_RichCompareBool` - will always return ``1`` for :const:`Py_EQ` and ``0`` for :const:`Py_NE`. + will always return ``1`` for :c:macro:`Py_EQ` and ``0`` for :c:macro:`Py_NE`. + +.. c:function:: PyObject* PyObject_Format(PyObject *obj, PyObject *format_spec) + + Format *obj* using *format_spec*. This is equivalent to the Python + expression ``format(obj, format_spec)``. + + *format_spec* may be ``NULL``. In this case the call is equivalent + to ``format(obj)``. + Returns the formatted string on success, ``NULL`` on failure. .. c:function:: PyObject* PyObject_Repr(PyObject *o) - .. index:: builtin: repr + .. index:: pair: built-in function; repr Compute a string representation of object *o*. Returns the string representation on success, ``NULL`` on failure. This is the equivalent of the @@ -193,7 +206,7 @@ Object Protocol .. c:function:: PyObject* PyObject_ASCII(PyObject *o) - .. index:: builtin: ascii + .. index:: pair: built-in function; ascii As :c:func:`PyObject_Repr`, compute a string representation of object *o*, but escape the non-ASCII characters in the string returned by @@ -218,7 +231,7 @@ Object Protocol .. c:function:: PyObject* PyObject_Bytes(PyObject *o) - .. index:: builtin: bytes + .. index:: pair: built-in function; bytes Compute a bytes representation of object *o*. ``NULL`` is returned on failure and a bytes object on success. This is equivalent to the Python @@ -243,7 +256,7 @@ Object Protocol Normally only class objects, i.e. instances of :class:`type` or a derived class, are considered classes. However, objects can override this by having - a :attr:`__bases__` attribute (which must be a tuple of base classes). + a :attr:`~class.__bases__` attribute (which must be a tuple of base classes). .. c:function:: int PyObject_IsInstance(PyObject *inst, PyObject *cls) @@ -260,16 +273,16 @@ Object Protocol is an instance of *cls* if its class is a subclass of *cls*. An instance *inst* can override what is considered its class by having a - :attr:`__class__` attribute. + :attr:`~instance.__class__` attribute. An object *cls* can override if it is considered a class, and what its base - classes are, by having a :attr:`__bases__` attribute (which must be a tuple + classes are, by having a :attr:`~class.__bases__` attribute (which must be a tuple of base classes). .. c:function:: Py_hash_t PyObject_Hash(PyObject *o) - .. index:: builtin: hash + .. index:: pair: built-in function; hash Compute and return the hash value of an object *o*. On failure, return ``-1``. This is the equivalent of the Python expression ``hash(o)``. @@ -281,7 +294,7 @@ Object Protocol .. c:function:: Py_hash_t PyObject_HashNotImplemented(PyObject *o) - Set a :exc:`TypeError` indicating that ``type(o)`` is not hashable and return ``-1``. + Set a :exc:`TypeError` indicating that ``type(o)`` is not :term:`hashable` and return ``-1``. This function receives special treatment when stored in a ``tp_hash`` slot, allowing a type to explicitly indicate to the interpreter that it is not hashable. @@ -303,15 +316,16 @@ Object Protocol .. c:function:: PyObject* PyObject_Type(PyObject *o) - .. index:: builtin: type + .. index:: pair: built-in function; type When *o* is non-``NULL``, returns a type object corresponding to the object type of object *o*. On failure, raises :exc:`SystemError` and returns ``NULL``. This - is equivalent to the Python expression ``type(o)``. This function increments the - reference count of the return value. There's really no reason to use this + is equivalent to the Python expression ``type(o)``. + This function creates a new :term:`strong reference` to the return value. + There's really no reason to use this function instead of the :c:func:`Py_TYPE()` function, which returns a - pointer of type :c:expr:`PyTypeObject*`, except when the incremented reference - count is needed. + pointer of type :c:expr:`PyTypeObject*`, except when a new + :term:`strong reference` is needed. .. c:function:: int PyObject_TypeCheck(PyObject *o, PyTypeObject *type) @@ -323,7 +337,7 @@ Object Protocol .. c:function:: Py_ssize_t PyObject_Size(PyObject *o) Py_ssize_t PyObject_Length(PyObject *o) - .. index:: builtin: len + .. index:: pair: built-in function; len Return the length of object *o*. If the object *o* provides either the sequence and mapping protocols, the sequence length is returned. On error, ``-1`` is @@ -386,3 +400,42 @@ Object Protocol returns ``NULL`` if the object cannot be iterated. .. versionadded:: 3.10 + +.. c:function:: void *PyObject_GetTypeData(PyObject *o, PyTypeObject *cls) + + Get a pointer to subclass-specific data reserved for *cls*. + + The object *o* must be an instance of *cls*, and *cls* must have been + created using negative :c:member:`PyType_Spec.basicsize`. + Python does not check this. + + On error, set an exception and return ``NULL``. + + .. versionadded:: 3.12 + +.. c:function:: Py_ssize_t PyType_GetTypeDataSize(PyTypeObject *cls) + + Return the size of the instance memory space reserved for *cls*, i.e. the size of the + memory :c:func:`PyObject_GetTypeData` returns. + + This may be larger than requested using :c:member:`-PyType_Spec.basicsize `; + it is safe to use this larger size (e.g. with :c:func:`!memset`). + + The type *cls* **must** have been created using + negative :c:member:`PyType_Spec.basicsize`. + Python does not check this. + + On error, set an exception and return a negative value. + + .. versionadded:: 3.12 + +.. c:function:: void *PyObject_GetItemData(PyObject *o) + + Get a pointer to per-item data for a class with + :c:macro:`Py_TPFLAGS_ITEMS_AT_END`. + + On error, set an exception and return ``NULL``. + :py:exc:`TypeError` is raised if *o* does not have + :c:macro:`Py_TPFLAGS_ITEMS_AT_END` set. + + .. versionadded:: 3.12 diff --git a/Doc/c-api/perfmaps.rst b/Doc/c-api/perfmaps.rst new file mode 100644 index 00000000..3d44d2eb --- /dev/null +++ b/Doc/c-api/perfmaps.rst @@ -0,0 +1,50 @@ +.. highlight:: c + +.. _perfmaps: + +Support for Perf Maps +---------------------- + +On supported platforms (as of this writing, only Linux), the runtime can take +advantage of *perf map files* to make Python functions visible to an external +profiling tool (such as `perf `_). +A running process may create a file in the ``/tmp`` directory, which contains entries +that can map a section of executable code to a name. This interface is described in the +`documentation of the Linux Perf tool `_. + +In Python, these helper APIs can be used by libraries and features that rely +on generating machine code on the fly. + +Note that holding the Global Interpreter Lock (GIL) is not required for these APIs. + +.. c:function:: int PyUnstable_PerfMapState_Init(void) + + Open the ``/tmp/perf-$pid.map`` file, unless it's already opened, and create + a lock to ensure thread-safe writes to the file (provided the writes are + done through :c:func:`PyUnstable_WritePerfMapEntry`). Normally, there's no need + to call this explicitly; just use :c:func:`PyUnstable_WritePerfMapEntry` + and it will initialize the state on first call. + + Returns ``0`` on success, ``-1`` on failure to create/open the perf map file, + or ``-2`` on failure to create a lock. Check ``errno`` for more information + about the cause of a failure. + +.. c:function:: int PyUnstable_WritePerfMapEntry(const void *code_addr, unsigned int code_size, const char *entry_name) + + Write one single entry to the ``/tmp/perf-$pid.map`` file. This function is + thread safe. Here is what an example entry looks like:: + + # address size name + 7f3529fcf759 b py::bar:/run/t.py + + Will call :c:func:`PyUnstable_PerfMapState_Init` before writing the entry, if + the perf map file is not already opened. Returns ``0`` on success, or the + same error codes as :c:func:`PyUnstable_PerfMapState_Init` on failure. + +.. c:function:: void PyUnstable_PerfMapState_Fini(void) + + Close the perf map file opened by :c:func:`PyUnstable_PerfMapState_Init`. + This is called by the runtime itself during interpreter shut-down. In + general, there shouldn't be a reason to explicitly call this, except to + handle specific scenarios such as forking. diff --git a/Doc/c-api/refcounting.rst b/Doc/c-api/refcounting.rst index 738bd77e..4ea0378d 100644 --- a/Doc/c-api/refcounting.rst +++ b/Doc/c-api/refcounting.rst @@ -7,37 +7,80 @@ Reference Counting ****************** -The macros in this section are used for managing reference counts of Python -objects. +The functions and macros in this section are used for managing reference counts +of Python objects. + + +.. c:function:: Py_ssize_t Py_REFCNT(PyObject *o) + + Get the reference count of the Python object *o*. + + Note that the returned value may not actually reflect how many + references to the object are actually held. For example, some + objects are "immortal" and have a very high refcount that does not + reflect the actual number of references. Consequently, do not rely + on the returned value to be accurate, other than a value of 0 or 1. + + Use the :c:func:`Py_SET_REFCNT()` function to set an object reference count. + + .. versionchanged:: 3.11 + The parameter type is no longer :c:expr:`const PyObject*`. + + .. versionchanged:: 3.10 + :c:func:`Py_REFCNT()` is changed to the inline static function. + + +.. c:function:: void Py_SET_REFCNT(PyObject *o, Py_ssize_t refcnt) + + Set the object *o* reference counter to *refcnt*. + + Note that this function has no effect on + `immortal `_ + objects. + + .. versionadded:: 3.9 + + .. versionchanged:: 3.12 + Immortal objects are not modified. .. c:function:: void Py_INCREF(PyObject *o) - Increment the reference count for object *o*. + Indicate taking a new :term:`strong reference` to object *o*, + indicating it is in use and should not be destroyed. This function is usually used to convert a :term:`borrowed reference` to a :term:`strong reference` in-place. The :c:func:`Py_NewRef` function can be used to create a new :term:`strong reference`. + When done using the object, release it by calling :c:func:`Py_DECREF`. + The object must not be ``NULL``; if you aren't sure that it isn't ``NULL``, use :c:func:`Py_XINCREF`. + Do not expect this function to actually modify *o* in any way. + For at least `some objects `_, + this function has no effect. + + .. versionchanged:: 3.12 + Immortal objects are not modified. + .. c:function:: void Py_XINCREF(PyObject *o) - Increment the reference count for object *o*. The object may be ``NULL``, in - which case the macro has no effect. + Similar to :c:func:`Py_INCREF`, but the object *o* can be ``NULL``, + in which case this has no effect. See also :c:func:`Py_XNewRef`. .. c:function:: PyObject* Py_NewRef(PyObject *o) - Create a new :term:`strong reference` to an object: increment the reference - count of the object *o* and return the object *o*. + Create a new :term:`strong reference` to an object: + call :c:func:`Py_INCREF` on *o* and return the object *o*. When the :term:`strong reference` is no longer needed, :c:func:`Py_DECREF` - should be called on it to decrement the object reference count. + should be called on it to release the reference. The object *o* must not be ``NULL``; use :c:func:`Py_XNewRef` if *o* can be ``NULL``. @@ -67,9 +110,12 @@ objects. .. c:function:: void Py_DECREF(PyObject *o) - Decrement the reference count for object *o*. + Release a :term:`strong reference` to object *o*, indicating the + reference is no longer used. - If the reference count reaches zero, the object's type's deallocation + Once the last :term:`strong reference` is released + (i.e. the object's reference count reaches 0), + the object's type's deallocation function (which must not be ``NULL``) is invoked. This function is usually used to delete a :term:`strong reference` before @@ -78,10 +124,14 @@ objects. The object must not be ``NULL``; if you aren't sure that it isn't ``NULL``, use :c:func:`Py_XDECREF`. + Do not expect this function to actually modify *o* in any way. + For at least `some objects `_, + this function has no effect. + .. warning:: The deallocation function can cause arbitrary Python code to be invoked (e.g. - when a class instance with a :meth:`__del__` method is deallocated). While + when a class instance with a :meth:`~object.__del__` method is deallocated). While exceptions in such code are not propagated, the executed code has free access to all Python global variables. This means that any object that is reachable from a global variable should be in a consistent state before :c:func:`Py_DECREF` is @@ -89,39 +139,82 @@ objects. reference to the deleted object in a temporary variable, update the list data structure, and then call :c:func:`Py_DECREF` for the temporary variable. + .. versionchanged:: 3.12 + Immortal objects are not modified. + .. c:function:: void Py_XDECREF(PyObject *o) - Decrement the reference count for object *o*. The object may be ``NULL``, in - which case the macro has no effect; otherwise the effect is the same as for - :c:func:`Py_DECREF`, and the same warning applies. + Similar to :c:func:`Py_DECREF`, but the object *o* can be ``NULL``, + in which case this has no effect. + The same warning from :c:func:`Py_DECREF` applies here as well. .. c:function:: void Py_CLEAR(PyObject *o) - Decrement the reference count for object *o*. The object may be ``NULL``, in + Release a :term:`strong reference` for object *o*. + The object may be ``NULL``, in which case the macro has no effect; otherwise the effect is the same as for :c:func:`Py_DECREF`, except that the argument is also set to ``NULL``. The warning for :c:func:`Py_DECREF` does not apply with respect to the object passed because the macro carefully uses a temporary variable and sets the argument to ``NULL`` - before decrementing its reference count. + before releasing the reference. + + It is a good idea to use this macro whenever releasing a reference + to an object that might be traversed during garbage collection. + + .. versionchanged:: 3.12 + The macro argument is now only evaluated once. If the argument has side + effects, these are no longer duplicated. - It is a good idea to use this macro whenever decrementing the reference - count of an object that might be traversed during garbage collection. .. c:function:: void Py_IncRef(PyObject *o) - Increment the reference count for object *o*. A function version of :c:func:`Py_XINCREF`. + Indicate taking a new :term:`strong reference` to object *o*. + A function version of :c:func:`Py_XINCREF`. It can be used for runtime dynamic embedding of Python. .. c:function:: void Py_DecRef(PyObject *o) - Decrement the reference count for object *o*. A function version of :c:func:`Py_XDECREF`. + Release a :term:`strong reference` to object *o*. + A function version of :c:func:`Py_XDECREF`. It can be used for runtime dynamic embedding of Python. -The following functions or macros are only for use within the interpreter core: -:c:func:`_Py_Dealloc`, :c:func:`_Py_ForgetReference`, :c:func:`_Py_NewReference`, -as well as the global variable :c:data:`_Py_RefTotal`. +.. c:macro:: Py_SETREF(dst, src) + + Macro safely releasing a :term:`strong reference` to object *dst* + and setting *dst* to *src*. + + As in case of :c:func:`Py_CLEAR`, "the obvious" code can be deadly:: + + Py_DECREF(dst); + dst = src; + + The safe way is:: + + Py_SETREF(dst, src); + + That arranges to set *dst* to *src* _before_ releasing the reference + to the old value of *dst*, so that any code triggered as a side-effect + of *dst* getting torn down no longer believes *dst* points + to a valid object. + + .. versionadded:: 3.6 + + .. versionchanged:: 3.12 + The macro arguments are now only evaluated once. If an argument has side + effects, these are no longer duplicated. + + +.. c:macro:: Py_XSETREF(dst, src) + + Variant of :c:macro:`Py_SETREF` macro that uses :c:func:`Py_XDECREF` instead + of :c:func:`Py_DECREF`. + + .. versionadded:: 3.6 + .. versionchanged:: 3.12 + The macro arguments are now only evaluated once. If an argument has side + effects, these are no longer duplicated. diff --git a/Doc/c-api/sequence.rst b/Doc/c-api/sequence.rst index c78d273f..ce28839f 100644 --- a/Doc/c-api/sequence.rst +++ b/Doc/c-api/sequence.rst @@ -9,7 +9,7 @@ Sequence Protocol .. c:function:: int PySequence_Check(PyObject *o) Return ``1`` if the object provides the sequence protocol, and ``0`` otherwise. - Note that it returns ``1`` for Python classes with a :meth:`__getitem__` + Note that it returns ``1`` for Python classes with a :meth:`~object.__getitem__` method, unless they are :class:`dict` subclasses, since in general it is impossible to determine what type of keys the class supports. This function always succeeds. @@ -18,7 +18,7 @@ Sequence Protocol .. c:function:: Py_ssize_t PySequence_Size(PyObject *o) Py_ssize_t PySequence_Length(PyObject *o) - .. index:: builtin: len + .. index:: pair: built-in function; len Returns the number of objects in sequence *o* on success, and ``-1`` on failure. This is equivalent to the Python expression ``len(o)``. @@ -120,7 +120,7 @@ Sequence Protocol .. c:function:: PyObject* PySequence_Tuple(PyObject *o) - .. index:: builtin: tuple + .. index:: pair: built-in function; tuple Return a tuple object with the same contents as the sequence or iterable *o*, or ``NULL`` on failure. If *o* is a tuple, a new reference will be returned, diff --git a/Doc/c-api/set.rst b/Doc/c-api/set.rst index f0d905ba..1e8a0950 100644 --- a/Doc/c-api/set.rst +++ b/Doc/c-api/set.rst @@ -9,8 +9,8 @@ Set Objects .. index:: - object: set - object: frozenset + pair: object; set + pair: object; frozenset This section details the public API for :class:`set` and :class:`frozenset` objects. Any functionality not listed below is best accessed using either @@ -107,10 +107,10 @@ or :class:`frozenset` or instances of their subtypes. .. c:function:: Py_ssize_t PySet_Size(PyObject *anyset) - .. index:: builtin: len + .. index:: pair: built-in function; len Return the length of a :class:`set` or :class:`frozenset` object. Equivalent to - ``len(anyset)``. Raises a :exc:`PyExc_SystemError` if *anyset* is not a + ``len(anyset)``. Raises a :exc:`SystemError` if *anyset* is not a :class:`set`, :class:`frozenset`, or an instance of a subtype. @@ -122,9 +122,9 @@ or :class:`frozenset` or instances of their subtypes. .. c:function:: int PySet_Contains(PyObject *anyset, PyObject *key) Return ``1`` if found, ``0`` if not found, and ``-1`` if an error is encountered. Unlike - the Python :meth:`__contains__` method, this function does not automatically + the Python :meth:`~object.__contains__` method, this function does not automatically convert unhashable sets into temporary frozensets. Raise a :exc:`TypeError` if - the *key* is unhashable. Raise :exc:`PyExc_SystemError` if *anyset* is not a + the *key* is unhashable. Raise :exc:`SystemError` if *anyset* is not a :class:`set`, :class:`frozenset`, or an instance of a subtype. @@ -149,7 +149,7 @@ subtypes but not for instances of :class:`frozenset` or its subtypes. error is encountered. Does not raise :exc:`KeyError` for missing keys. Raise a :exc:`TypeError` if the *key* is unhashable. Unlike the Python :meth:`~set.discard` method, this function does not automatically convert unhashable sets into - temporary frozensets. Raise :exc:`PyExc_SystemError` if *set* is not an + temporary frozensets. Raise :exc:`SystemError` if *set* is not an instance of :class:`set` or its subtype. diff --git a/Doc/c-api/slice.rst b/Doc/c-api/slice.rst index 8271d9ac..9e880c6b 100644 --- a/Doc/c-api/slice.rst +++ b/Doc/c-api/slice.rst @@ -34,7 +34,7 @@ Slice Objects *length* as errors. Returns ``0`` on success and ``-1`` on error with no exception set (unless one of - the indices was not :const:`None` and failed to be converted to an integer, + the indices was not ``None`` and failed to be converted to an integer, in which case ``-1`` is returned with an exception set). You probably do not want to use this function. @@ -113,11 +113,14 @@ Slice Objects Ellipsis Object ---------------- +^^^^^^^^^^^^^^^ .. c:var:: PyObject *Py_Ellipsis - The Python ``Ellipsis`` object. This object has no methods. It needs to be - treated just like any other object with respect to reference counts. Like - :c:data:`Py_None` it is a singleton object. + The Python ``Ellipsis`` object. This object has no methods. Like + :c:data:`Py_None`, it is an `immortal `_. + singleton object. + + .. versionchanged:: 3.12 + :c:data:`Py_Ellipsis` is immortal. diff --git a/Doc/c-api/stable.rst b/Doc/c-api/stable.rst index 4ae20e93..63a100a6 100644 --- a/Doc/c-api/stable.rst +++ b/Doc/c-api/stable.rst @@ -6,9 +6,9 @@ C API Stability *************** -Python's C API is covered by the Backwards Compatibility Policy, :pep:`387`. -While the C API will change with every minor release (e.g. from 3.9 to 3.10), -most changes will be source-compatible, typically by only adding new API. +Unless documented otherwise, Python's C API is covered by the Backwards +Compatibility Policy, :pep:`387`. +Most changes to it are source-compatible (typically by only adding new API). Changing existing API or removing API is only done after a deprecation period or to fix serious issues. @@ -18,33 +18,63 @@ way; see :ref:`stable-abi-platform` below). So, code compiled for Python 3.10.0 will work on 3.10.8 and vice versa, but will need to be compiled separately for 3.9.x and 3.10.x. +There are two tiers of C API with different stability expectations: + +- :ref:`Unstable API `, may change in minor versions without + a deprecation period. It is marked by the ``PyUnstable`` prefix in names. +- :ref:`Limited API `, is compatible across several minor releases. + When :c:macro:`Py_LIMITED_API` is defined, only this subset is exposed + from ``Python.h``. + +These are discussed in more detail below. + Names prefixed by an underscore, such as ``_Py_InternalState``, are private API that can change without notice even in patch releases. +If you need to use this API, consider reaching out to +`CPython developers `_ +to discuss adding public API for your use case. + +.. _unstable-c-api: + +Unstable C API +============== + +.. index:: single: PyUnstable + +Any API named with the ``PyUnstable`` prefix exposes CPython implementation +details, and may change in every minor release (e.g. from 3.9 to 3.10) without +any deprecation warnings. +However, it will not change in a bugfix release (e.g. from 3.10.0 to 3.10.1). + +It is generally intended for specialized, low-level tools like debuggers. + +Projects that use this API are expected to follow +CPython development and spend extra effort adjusting to changes. Stable Application Binary Interface =================================== +For simplicity, this document talks about *extensions*, but the Limited API +and Stable ABI work the same way for all uses of the API – for example, +embedding Python. + +.. _limited-c-api: + +Limited C API +------------- + Python 3.2 introduced the *Limited API*, a subset of Python's C API. Extensions that only use the Limited API can be compiled once and work with multiple versions of Python. -Contents of the Limited API are :ref:`listed below `. - -To enable this, Python provides a *Stable ABI*: a set of symbols that will -remain compatible across Python 3.x versions. The Stable ABI contains symbols -exposed in the Limited API, but also other ones – for example, functions -necessary to support older versions of the Limited API. - -(For simplicity, this document talks about *extensions*, but the Limited API -and Stable ABI work the same way for all uses of the API – for example, -embedding Python.) +Contents of the Limited API are :ref:`listed below `. .. c:macro:: Py_LIMITED_API Define this macro before including ``Python.h`` to opt in to only use the Limited API, and to select the Limited API version. - Define ``Py_LIMITED_API`` to the value of :c:data:`PY_VERSION_HEX` + Define ``Py_LIMITED_API`` to the value of :c:macro:`PY_VERSION_HEX` corresponding to the lowest Python version your extension supports. The extension will work without recompilation with all Python 3 releases from the specified one onward, and can use Limited API introduced up to that @@ -57,6 +87,19 @@ embedding Python.) You can also define ``Py_LIMITED_API`` to ``3``. This works the same as ``0x03020000`` (Python 3.2, the version that introduced Limited API). + +.. _stable-abi: + +Stable ABI +---------- + +To enable this, Python provides a *Stable ABI*: a set of symbols that will +remain compatible across Python 3.x versions. + +The Stable ABI contains symbols exposed in the :ref:`Limited API +`, but also other ones – for example, functions necessary to +support older versions of the Limited API. + On Windows, extensions that use the Stable ABI should be linked against ``python3.dll`` rather than a version-specific library such as ``python39.dll``. @@ -101,9 +144,9 @@ Limited API Caveats ------------------- Note that compiling with ``Py_LIMITED_API`` is *not* a complete guarantee that -code conforms to the Limited API or the Stable ABI. ``Py_LIMITED_API`` only -covers definitions, but an API also includes other issues, such as expected -semantics. +code conforms to the :ref:`Limited API ` or the :ref:`Stable ABI +`. ``Py_LIMITED_API`` only covers definitions, but an API also +includes other issues, such as expected semantics. One issue that ``Py_LIMITED_API`` does not guard against is calling a function with arguments that are invalid in a lower Python version. @@ -136,9 +179,9 @@ Platform Considerations ======================= ABI stability depends not only on Python, but also on the compiler used, -lower-level libraries and compiler options. For the purposes of the Stable ABI, -these details define a “platform”. They usually depend on the OS -type and processor architecture +lower-level libraries and compiler options. For the purposes of +the :ref:`Stable ABI `, these details define a “platform”. They +usually depend on the OS type and processor architecture It is the responsibility of each particular distributor of Python to ensure that all Python versions on a particular platform are built @@ -147,12 +190,12 @@ This is the case with Windows and macOS releases from ``python.org`` and many third-party distributors. -.. _stable-abi-list: +.. _limited-api-list: Contents of Limited API ======================= -Currently, the Limited API includes the following items: +Currently, the :ref:`Limited API ` includes the following items: .. limited-api-list:: diff --git a/Doc/c-api/structures.rst b/Doc/c-api/structures.rst index 30760c0d..747cfa62 100644 --- a/Doc/c-api/structures.rst +++ b/Doc/c-api/structures.rst @@ -17,7 +17,8 @@ All Python objects ultimately share a small number of fields at the beginning of the object's representation in memory. These are represented by the :c:type:`PyObject` and :c:type:`PyVarObject` types, which are defined, in turn, by the expansions of some macros also used, whether directly or indirectly, in -the definition of all other Python objects. +the definition of all other Python objects. Additional macros can be found +under :ref:`reference counting `. .. c:type:: PyObject @@ -34,7 +35,7 @@ the definition of all other Python objects. .. c:type:: PyVarObject - This is an extension of :c:type:`PyObject` that adds the :attr:`ob_size` + This is an extension of :c:type:`PyObject` that adds the :c:member:`~PyVarObject.ob_size` field. This is only used for objects that have some notion of *length*. This type does not often appear in the Python/C API. Access to the members must be done by using the macros @@ -121,26 +122,6 @@ the definition of all other Python objects. .. versionadded:: 3.9 -.. c:function:: Py_ssize_t Py_REFCNT(PyObject *o) - - Get the reference count of the Python object *o*. - - Use the :c:func:`Py_SET_REFCNT()` function to set an object reference count. - - .. versionchanged:: 3.11 - The parameter type is no longer :c:expr:`const PyObject*`. - - .. versionchanged:: 3.10 - :c:func:`Py_REFCNT()` is changed to the inline static function. - - -.. c:function:: void Py_SET_REFCNT(PyObject *o, Py_ssize_t refcnt) - - Set the object *o* reference counter to *refcnt*. - - .. versionadded:: 3.9 - - .. c:function:: Py_ssize_t Py_SIZE(PyVarObject *o) Get the size of the Python object *o*. @@ -171,7 +152,7 @@ the definition of all other Python objects. .. c:macro:: PyVarObject_HEAD_INIT(type, size) This is a macro which expands to initialization values for a new - :c:type:`PyVarObject` type, including the :attr:`ob_size` field. + :c:type:`PyVarObject` type, including the :c:member:`~PyVarObject.ob_size` field. This macro expands to:: _PyObject_EXTRA_INIT @@ -198,7 +179,7 @@ Implementing functions and methods .. c:type:: PyCFunctionWithKeywords Type of the functions used to implement Python callables in C - with signature :const:`METH_VARARGS | METH_KEYWORDS`. + with signature :ref:`METH_VARARGS | METH_KEYWORDS `. The function signature is:: PyObject *PyCFunctionWithKeywords(PyObject *self, @@ -209,7 +190,7 @@ Implementing functions and methods .. c:type:: _PyCFunctionFast Type of the functions used to implement Python callables in C - with signature :const:`METH_FASTCALL`. + with signature :c:macro:`METH_FASTCALL`. The function signature is:: PyObject *_PyCFunctionFast(PyObject *self, @@ -219,7 +200,7 @@ Implementing functions and methods .. c:type:: _PyCFunctionFastWithKeywords Type of the functions used to implement Python callables in C - with signature :const:`METH_FASTCALL | METH_KEYWORDS`. + with signature :ref:`METH_FASTCALL | METH_KEYWORDS `. The function signature is:: PyObject *_PyCFunctionFastWithKeywords(PyObject *self, @@ -230,7 +211,7 @@ Implementing functions and methods .. c:type:: PyCMethod Type of the functions used to implement Python callables in C - with signature :const:`METH_METHOD | METH_FASTCALL | METH_KEYWORDS`. + with signature :ref:`METH_METHOD | METH_FASTCALL | METH_KEYWORDS `. The function signature is:: PyObject *PyCMethod(PyObject *self, @@ -247,36 +228,38 @@ Implementing functions and methods Structure used to describe a method of an extension type. This structure has four fields: - .. c:member:: const char* ml_name + .. c:member:: const char *ml_name - name of the method + Name of the method. .. c:member:: PyCFunction ml_meth - pointer to the C implementation + Pointer to the C implementation. .. c:member:: int ml_flags - flags bits indicating how the call should be constructed + Flags bits indicating how the call should be constructed. - .. c:member:: const char* ml_doc + .. c:member:: const char *ml_doc - points to the contents of the docstring + Points to the contents of the docstring. -The :c:member:`ml_meth` is a C function pointer. The functions may be of different +The :c:member:`~PyMethodDef.ml_meth` is a C function pointer. +The functions may be of different types, but they always return :c:expr:`PyObject*`. If the function is not of the :c:type:`PyCFunction`, the compiler will require a cast in the method table. Even though :c:type:`PyCFunction` defines the first parameter as :c:expr:`PyObject*`, it is common that the method implementation uses the specific C type of the *self* object. -The :c:member:`ml_flags` field is a bitfield which can include the following flags. +The :c:member:`~PyMethodDef.ml_flags` field is a bitfield which can include +the following flags. The individual flags indicate either a calling convention or a binding convention. There are these calling conventions: -.. data:: METH_VARARGS +.. c:macro:: METH_VARARGS This is the typical calling convention, where the methods have the type :c:type:`PyCFunction`. The function expects two :c:expr:`PyObject*` values. @@ -286,8 +269,17 @@ There are these calling conventions: using :c:func:`PyArg_ParseTuple` or :c:func:`PyArg_UnpackTuple`. -.. data:: METH_VARARGS | METH_KEYWORDS +.. c:macro:: METH_KEYWORDS + + Can only be used in certain combinations with other flags: + :ref:`METH_VARARGS | METH_KEYWORDS `, + :ref:`METH_FASTCALL | METH_KEYWORDS ` and + :ref:`METH_METHOD | METH_FASTCALL | METH_KEYWORDS `. + + +.. _METH_VARARGS-METH_KEYWORDS: +:c:expr:`METH_VARARGS | METH_KEYWORDS` Methods with these flags must be of type :c:type:`PyCFunctionWithKeywords`. The function expects three parameters: *self*, *args*, *kwargs* where *kwargs* is a dictionary of all the keyword arguments or possibly ``NULL`` @@ -295,7 +287,7 @@ There are these calling conventions: using :c:func:`PyArg_ParseTupleAndKeywords`. -.. data:: METH_FASTCALL +.. c:macro:: METH_FASTCALL Fast calling convention supporting only positional arguments. The methods have the type :c:type:`_PyCFunctionFast`. @@ -307,12 +299,13 @@ There are these calling conventions: .. versionchanged:: 3.10 - ``METH_FASTCALL`` is now part of the stable ABI. + ``METH_FASTCALL`` is now part of the :ref:`stable ABI `. -.. data:: METH_FASTCALL | METH_KEYWORDS +.. _METH_FASTCALL-METH_KEYWORDS: - Extension of :const:`METH_FASTCALL` supporting also keyword arguments, +:c:expr:`METH_FASTCALL | METH_KEYWORDS` + Extension of :c:macro:`METH_FASTCALL` supporting also keyword arguments, with methods of type :c:type:`_PyCFunctionFastWithKeywords`. Keyword arguments are passed the same way as in the :ref:`vectorcall protocol `: @@ -325,10 +318,18 @@ There are these calling conventions: .. versionadded:: 3.7 -.. data:: METH_METHOD | METH_FASTCALL | METH_KEYWORDS +.. c:macro:: METH_METHOD + + Can only be used in the combination with other flags: + :ref:`METH_METHOD | METH_FASTCALL | METH_KEYWORDS `. + + +.. _METH_METHOD-METH_FASTCALL-METH_KEYWORDS: - Extension of :const:`METH_FASTCALL | METH_KEYWORDS` supporting the *defining - class*, that is, the class that contains the method in question. +:c:expr:`METH_METHOD | METH_FASTCALL | METH_KEYWORDS` + Extension of :ref:`METH_FASTCALL | METH_KEYWORDS ` + supporting the *defining class*, that is, + the class that contains the method in question. The defining class might be a superclass of ``Py_TYPE(self)``. The method needs to be of type :c:type:`PyCMethod`, the same as for @@ -338,10 +339,10 @@ There are these calling conventions: .. versionadded:: 3.9 -.. data:: METH_NOARGS +.. c:macro:: METH_NOARGS Methods without parameters don't need to check whether arguments are given if - they are listed with the :const:`METH_NOARGS` flag. They need to be of type + they are listed with the :c:macro:`METH_NOARGS` flag. They need to be of type :c:type:`PyCFunction`. The first parameter is typically named *self* and will hold a reference to the module or object instance. In all cases the second parameter will be ``NULL``. @@ -350,9 +351,9 @@ There are these calling conventions: :c:macro:`Py_UNUSED` can be used to prevent a compiler warning. -.. data:: METH_O +.. c:macro:: METH_O - Methods with a single object argument can be listed with the :const:`METH_O` + Methods with a single object argument can be listed with the :c:macro:`METH_O` flag, instead of invoking :c:func:`PyArg_ParseTuple` with a ``"O"`` argument. They have the type :c:type:`PyCFunction`, with the *self* parameter, and a :c:expr:`PyObject*` parameter representing the single argument. @@ -364,9 +365,9 @@ defined for modules. At most one of these flags may be set for any given method. -.. data:: METH_CLASS +.. c:macro:: METH_CLASS - .. index:: builtin: classmethod + .. index:: pair: built-in function; classmethod The method will be passed the type object as the first parameter rather than an instance of the type. This is used to create *class methods*, @@ -374,9 +375,9 @@ method. function. -.. data:: METH_STATIC +.. c:macro:: METH_STATIC - .. index:: builtin: staticmethod + .. index:: pair: built-in function; staticmethod The method will be passed ``NULL`` as the first parameter rather than an instance of the type. This is used to create *static methods*, similar to @@ -386,13 +387,13 @@ One other constant controls whether a method is loaded in place of another definition with the same method name. -.. data:: METH_COEXIST +.. c:macro:: METH_COEXIST The method will be loaded in place of existing definitions. Without *METH_COEXIST*, the default is to skip repeated definitions. Since slot wrappers are loaded before the method table, the existence of a *sq_contains* slot, for example, would generate a wrapped method named - :meth:`__contains__` and preclude the loading of a corresponding + :meth:`~object.__contains__` and preclude the loading of a corresponding PyCFunction with the same name. With the flag defined, the PyCFunction will be loaded in place of the wrapper object and will co-exist with the slot. This is helpful because calls to PyCFunctions are optimized more @@ -405,84 +406,67 @@ Accessing attributes of extension types .. c:type:: PyMemberDef Structure which describes an attribute of a type which corresponds to a C - struct member. Its fields are: - - +------------------+---------------+-------------------------------+ - | Field | C Type | Meaning | - +==================+===============+===============================+ - | :attr:`name` | const char \* | name of the member | - +------------------+---------------+-------------------------------+ - | :attr:`!type` | int | the type of the member in the | - | | | C struct | - +------------------+---------------+-------------------------------+ - | :attr:`offset` | Py_ssize_t | the offset in bytes that the | - | | | member is located on the | - | | | type's object struct | - +------------------+---------------+-------------------------------+ - | :attr:`flags` | int | flag bits indicating if the | - | | | field should be read-only or | - | | | writable | - +------------------+---------------+-------------------------------+ - | :attr:`doc` | const char \* | points to the contents of the | - | | | docstring | - +------------------+---------------+-------------------------------+ - - :attr:`!type` can be one of many ``T_`` macros corresponding to various C - types. When the member is accessed in Python, it will be converted to the - equivalent Python type. - - =============== ================== - Macro name C type - =============== ================== - T_SHORT short - T_INT int - T_LONG long - T_FLOAT float - T_DOUBLE double - T_STRING const char \* - T_OBJECT PyObject \* - T_OBJECT_EX PyObject \* - T_CHAR char - T_BYTE char - T_UBYTE unsigned char - T_UINT unsigned int - T_USHORT unsigned short - T_ULONG unsigned long - T_BOOL char - T_LONGLONG long long - T_ULONGLONG unsigned long long - T_PYSSIZET Py_ssize_t - =============== ================== - - :c:macro:`T_OBJECT` and :c:macro:`T_OBJECT_EX` differ in that - :c:macro:`T_OBJECT` returns ``None`` if the member is ``NULL`` and - :c:macro:`T_OBJECT_EX` raises an :exc:`AttributeError`. Try to use - :c:macro:`T_OBJECT_EX` over :c:macro:`T_OBJECT` because :c:macro:`T_OBJECT_EX` - handles use of the :keyword:`del` statement on that attribute more correctly - than :c:macro:`T_OBJECT`. - - :attr:`flags` can be ``0`` for write and read access or :c:macro:`READONLY` for - read-only access. Using :c:macro:`T_STRING` for :attr:`type` implies - :c:macro:`READONLY`. :c:macro:`T_STRING` data is interpreted as UTF-8. - Only :c:macro:`T_OBJECT` and :c:macro:`T_OBJECT_EX` - members can be deleted. (They are set to ``NULL``). + struct member. Its fields are, in order: + + .. c:member:: const char* name + + Name of the member. + A NULL value marks the end of a ``PyMemberDef[]`` array. + + The string should be static, no copy is made of it. + + .. c:member:: Py_ssize_t offset + + The offset in bytes that the member is located on the type’s object struct. + + .. c:member:: int type + + The type of the member in the C struct. + See :ref:`PyMemberDef-types` for the possible values. + + .. c:member:: int flags + + Zero or more of the :ref:`PyMemberDef-flags`, combined using bitwise OR. + + .. c:member:: const char* doc + + The docstring, or NULL. + The string should be static, no copy is made of it. + Typically, it is defined using :c:macro:`PyDoc_STR`. + + By default (when :c:member:`~PyMemberDef.flags` is ``0``), members allow + both read and write access. + Use the :c:macro:`Py_READONLY` flag for read-only access. + Certain types, like :c:macro:`Py_T_STRING`, imply :c:macro:`Py_READONLY`. + Only :c:macro:`Py_T_OBJECT_EX` (and legacy :c:macro:`T_OBJECT`) members can + be deleted. .. _pymemberdef-offsets: - Heap allocated types (created using :c:func:`PyType_FromSpec` or similar), - ``PyMemberDef`` may contain definitions for the special members - ``__dictoffset__``, ``__weaklistoffset__`` and ``__vectorcalloffset__``, - corresponding to - :c:member:`~PyTypeObject.tp_dictoffset`, - :c:member:`~PyTypeObject.tp_weaklistoffset` and + For heap-allocated types (created using :c:func:`PyType_FromSpec` or similar), + ``PyMemberDef`` may contain a definition for the special member + ``"__vectorcalloffset__"``, corresponding to :c:member:`~PyTypeObject.tp_vectorcall_offset` in type objects. - These must be defined with ``T_PYSSIZET`` and ``READONLY``, for example:: + These must be defined with ``Py_T_PYSSIZET`` and ``Py_READONLY``, for example:: static PyMemberDef spam_type_members[] = { - {"__dictoffset__", T_PYSSIZET, offsetof(Spam_object, dict), READONLY}, + {"__vectorcalloffset__", Py_T_PYSSIZET, + offsetof(Spam_object, vectorcall), Py_READONLY}, {NULL} /* Sentinel */ }; + (You may need to ``#include `` for :c:func:`!offsetof`.) + + The legacy offsets :c:member:`~PyTypeObject.tp_dictoffset` and + :c:member:`~PyTypeObject.tp_weaklistoffset` can be defined similarly using + ``"__dictoffset__"`` and ``"__weaklistoffset__"`` members, but extensions + are strongly encouraged to use :c:macro:`Py_TPFLAGS_MANAGED_DICT` and + :c:macro:`Py_TPFLAGS_MANAGED_WEAKREF` instead. + + .. versionchanged:: 3.12 + + ``PyMemberDef`` is always available. + Previously, it required including ``"structmember.h"``. .. c:function:: PyObject* PyMember_GetOne(const char *obj_addr, struct PyMemberDef *m) @@ -490,6 +474,10 @@ Accessing attributes of extension types attribute is described by ``PyMemberDef`` *m*. Returns ``NULL`` on error. + .. versionchanged:: 3.12 + + ``PyMember_GetOne`` is always available. + Previously, it required including ``"structmember.h"``. .. c:function:: int PyMember_SetOne(char *obj_addr, struct PyMemberDef *m, PyObject *o) @@ -497,29 +485,185 @@ Accessing attributes of extension types The attribute to set is described by ``PyMemberDef`` *m*. Returns ``0`` if successful and a negative value on failure. + .. versionchanged:: 3.12 + + ``PyMember_SetOne`` is always available. + Previously, it required including ``"structmember.h"``. + +.. _PyMemberDef-flags: + +Member flags +^^^^^^^^^^^^ + +The following flags can be used with :c:member:`PyMemberDef.flags`: + +.. c:macro:: Py_READONLY + + Not writable. + +.. c:macro:: Py_AUDIT_READ + + Emit an ``object.__getattr__`` :ref:`audit event ` + before reading. + +.. c:macro:: Py_RELATIVE_OFFSET + + Indicates that the :c:member:`~PyMemberDef.offset` of this ``PyMemberDef`` + entry indicates an offset from the subclass-specific data, rather than + from ``PyObject``. + + Can only be used as part of :c:member:`Py_tp_members ` + :c:type:`slot ` when creating a class using negative + :c:member:`~PyType_Spec.basicsize`. + It is mandatory in that case. + + This flag is only used in :c:type:`PyTypeSlot`. + When setting :c:member:`~PyTypeObject.tp_members` during + class creation, Python clears it and sets + :c:member:`PyMemberDef.offset` to the offset from the ``PyObject`` struct. + +.. index:: + single: READ_RESTRICTED + single: WRITE_RESTRICTED + single: RESTRICTED + +.. versionchanged:: 3.10 + + The :c:macro:`!RESTRICTED`, :c:macro:`!READ_RESTRICTED` and + :c:macro:`!WRITE_RESTRICTED` macros available with + ``#include "structmember.h"`` are deprecated. + :c:macro:`!READ_RESTRICTED` and :c:macro:`!RESTRICTED` are equivalent to + :c:macro:`Py_AUDIT_READ`; :c:macro:`!WRITE_RESTRICTED` does nothing. + +.. index:: + single: READONLY + +.. versionchanged:: 3.12 + + The :c:macro:`!READONLY` macro was renamed to :c:macro:`Py_READONLY`. + The :c:macro:`!PY_AUDIT_READ` macro was renamed with the ``Py_`` prefix. + The new names are now always available. + Previously, these required ``#include "structmember.h"``. + The header is still available and it provides the old names. + +.. _PyMemberDef-types: + +Member types +^^^^^^^^^^^^ + +:c:member:`PyMemberDef.type` can be one of the following macros corresponding +to various C types. +When the member is accessed in Python, it will be converted to the +equivalent Python type. +When it is set from Python, it will be converted back to the C type. +If that is not possible, an exception such as :exc:`TypeError` or +:exc:`ValueError` is raised. + +Unless marked (D), attributes defined this way cannot be deleted +using e.g. :keyword:`del` or :py:func:`delattr`. + +================================ ============================= ====================== +Macro name C type Python type +================================ ============================= ====================== +.. c:macro:: Py_T_BYTE :c:expr:`char` :py:class:`int` +.. c:macro:: Py_T_SHORT :c:expr:`short` :py:class:`int` +.. c:macro:: Py_T_INT :c:expr:`int` :py:class:`int` +.. c:macro:: Py_T_LONG :c:expr:`long` :py:class:`int` +.. c:macro:: Py_T_LONGLONG :c:expr:`long long` :py:class:`int` +.. c:macro:: Py_T_UBYTE :c:expr:`unsigned char` :py:class:`int` +.. c:macro:: Py_T_UINT :c:expr:`unsigned int` :py:class:`int` +.. c:macro:: Py_T_USHORT :c:expr:`unsigned short` :py:class:`int` +.. c:macro:: Py_T_ULONG :c:expr:`unsigned long` :py:class:`int` +.. c:macro:: Py_T_ULONGLONG :c:expr:`unsigned long long` :py:class:`int` +.. c:macro:: Py_T_PYSSIZET :c:expr:`Py_ssize_t` :py:class:`int` +.. c:macro:: Py_T_FLOAT :c:expr:`float` :py:class:`float` +.. c:macro:: Py_T_DOUBLE :c:expr:`double` :py:class:`float` +.. c:macro:: Py_T_BOOL :c:expr:`char` :py:class:`bool` + (written as 0 or 1) +.. c:macro:: Py_T_STRING :c:expr:`const char *` (*) :py:class:`str` (RO) +.. c:macro:: Py_T_STRING_INPLACE :c:expr:`const char[]` (*) :py:class:`str` (RO) +.. c:macro:: Py_T_CHAR :c:expr:`char` (0-127) :py:class:`str` (**) +.. c:macro:: Py_T_OBJECT_EX :c:expr:`PyObject *` :py:class:`object` (D) +================================ ============================= ====================== + + (*): Zero-terminated, UTF8-encoded C string. + With :c:macro:`!Py_T_STRING` the C representation is a pointer; + with :c:macro:`!Py_T_STRING_INLINE` the string is stored directly + in the structure. + + (**): String of length 1. Only ASCII is accepted. + + (RO): Implies :c:macro:`Py_READONLY`. + + (D): Can be deleted, in which case the pointer is set to ``NULL``. + Reading a ``NULL`` pointer raises :py:exc:`AttributeError`. + +.. index:: + single: T_BYTE + single: T_SHORT + single: T_INT + single: T_LONG + single: T_LONGLONG + single: T_UBYTE + single: T_USHORT + single: T_UINT + single: T_ULONG + single: T_ULONGULONG + single: T_PYSSIZET + single: T_FLOAT + single: T_DOUBLE + single: T_BOOL + single: T_CHAR + single: T_STRING + single: T_STRING_INPLACE + single: T_OBJECT_EX + single: structmember.h + +.. versionadded:: 3.12 + + In previous versions, the macros were only available with + ``#include "structmember.h"`` and were named without the ``Py_`` prefix + (e.g. as ``T_INT``). + The header is still available and contains the old names, along with + the following deprecated types: + + .. c:macro:: T_OBJECT + + Like ``Py_T_OBJECT_EX``, but ``NULL`` is converted to ``None``. + This results in surprising behavior in Python: deleting the attribute + effectively sets it to ``None``. + + .. c:macro:: T_NONE + + Always ``None``. Must be used with :c:macro:`Py_READONLY`. + +Defining Getters and Setters +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. c:type:: PyGetSetDef Structure to define property-like access for a type. See also description of the :c:member:`PyTypeObject.tp_getset` slot. - +-------------+------------------+-----------------------------------+ - | Field | C Type | Meaning | - +=============+==================+===================================+ - | name | const char \* | attribute name | - +-------------+------------------+-----------------------------------+ - | get | getter | C function to get the attribute | - +-------------+------------------+-----------------------------------+ - | set | setter | optional C function to set or | - | | | delete the attribute, if omitted | - | | | the attribute is readonly | - +-------------+------------------+-----------------------------------+ - | doc | const char \* | optional docstring | - +-------------+------------------+-----------------------------------+ - | closure | void \* | optional function pointer, | - | | | providing additional data for | - | | | getter and setter | - +-------------+------------------+-----------------------------------+ + .. c:member:: const char* name + + attribute name + + .. c:member:: getter get + + C function to get the attribute. + + .. c:member:: setter set + + Optional C function to set or delete the attribute, if omitted the attribute is readonly. + + .. c:member:: const char* doc + + optional docstring + + .. c:member:: void* closure + + Optional function pointer, providing additional data for getter and setter. The ``get`` function takes one :c:expr:`PyObject*` parameter (the instance) and a function pointer (the associated ``closure``):: diff --git a/Doc/c-api/sys.rst b/Doc/c-api/sys.rst index 517b57b1..a8a284e6 100644 --- a/Doc/c-api/sys.rst +++ b/Doc/c-api/sys.rst @@ -8,8 +8,9 @@ Operating System Utilities .. c:function:: PyObject* PyOS_FSPath(PyObject *path) Return the file system representation for *path*. If the object is a - :class:`str` or :class:`bytes` object, then its reference count is - incremented. If the object implements the :class:`os.PathLike` interface, + :class:`str` or :class:`bytes` object, then a new + :term:`strong reference` is returned. + If the object implements the :class:`os.PathLike` interface, then :meth:`~os.PathLike.__fspath__` is returned as long as it is a :class:`str` or :class:`bytes` object. Otherwise :exc:`TypeError` is raised and ``NULL`` is returned. @@ -21,10 +22,12 @@ Operating System Utilities Return true (nonzero) if the standard I/O file *fp* with name *filename* is deemed interactive. This is the case for files for which ``isatty(fileno(fp))`` - is true. If the global flag :c:data:`Py_InteractiveFlag` is true, this function + is true. If the :c:member:`PyConfig.interactive` is non-zero, this function also returns true if the *filename* pointer is ``NULL`` or if the name is equal to one of the strings ``''`` or ``'???'``. + This function must not be called before Python is initialized. + .. c:function:: void PyOS_BeforeFork() @@ -95,16 +98,16 @@ Operating System Utilities .. c:function:: int PyOS_CheckStack() Return true when the interpreter runs out of stack space. This is a reliable - check, but is only available when :const:`USE_STACKCHECK` is defined (currently + check, but is only available when :c:macro:`USE_STACKCHECK` is defined (currently on certain versions of Windows using the Microsoft Visual C++ compiler). - :const:`USE_STACKCHECK` will be defined automatically; you should never + :c:macro:`USE_STACKCHECK` will be defined automatically; you should never change the definition in your own code. .. c:function:: PyOS_sighandler_t PyOS_getsig(int i) Return the current signal handler for signal *i*. This is a thin wrapper around - either :c:func:`sigaction` or :c:func:`signal`. Do not call those functions + either :c:func:`!sigaction` or :c:func:`!signal`. Do not call those functions directly! :c:type:`PyOS_sighandler_t` is a typedef alias for :c:expr:`void (\*)(int)`. @@ -112,7 +115,7 @@ Operating System Utilities .. c:function:: PyOS_sighandler_t PyOS_setsig(int i, PyOS_sighandler_t h) Set the signal handler for signal *i* to be *h*; return the old signal handler. - This is a thin wrapper around either :c:func:`sigaction` or :c:func:`signal`. Do + This is a thin wrapper around either :c:func:`!sigaction` or :c:func:`!signal`. Do not call those functions directly! :c:type:`PyOS_sighandler_t` is a typedef alias for :c:expr:`void (\*)(int)`. @@ -165,7 +168,7 @@ Operating System Utilities .. versionchanged:: 3.8 The function now uses the UTF-8 encoding on Windows if - :c:data:`Py_LegacyWindowsFSEncodingFlag` is zero; + :c:member:`PyPreConfig.legacy_windows_fs_encoding` is zero; .. c:function:: char* Py_EncodeLocale(const wchar_t *text, size_t *error_pos) @@ -207,7 +210,7 @@ Operating System Utilities .. versionchanged:: 3.8 The function now uses the UTF-8 encoding on Windows if - :c:data:`Py_LegacyWindowsFSEncodingFlag` is zero. + :c:member:`PyPreConfig.legacy_windows_fs_encoding` is zero. .. _systemfunctions: @@ -412,7 +415,7 @@ Process Control This function should only be invoked when a condition is detected that would make it dangerous to continue using the Python interpreter; e.g., when the object administration appears to be corrupted. On Unix, the standard C library - function :c:func:`abort` is called which will attempt to produce a :file:`core` + function :c:func:`!abort` is called which will attempt to produce a :file:`core` file. The ``Py_FatalError()`` function is replaced with a macro which logs diff --git a/Doc/c-api/tuple.rst b/Doc/c-api/tuple.rst index 0bfd4b30..9bc3dab0 100644 --- a/Doc/c-api/tuple.rst +++ b/Doc/c-api/tuple.rst @@ -5,7 +5,7 @@ Tuple Objects ------------- -.. index:: object: tuple +.. index:: pair: object; tuple .. c:type:: PyTupleObject @@ -69,7 +69,7 @@ Tuple Objects Return the slice of the tuple pointed to by *p* between *low* and *high*, or ``NULL`` on failure. This is the equivalent of the Python expression - ``p[low:high]``. Indexing from the end of the list is not supported. + ``p[low:high]``. Indexing from the end of the tuple is not supported. .. c:function:: int PyTuple_SetItem(PyObject *p, Py_ssize_t pos, PyObject *o) @@ -111,6 +111,8 @@ Tuple Objects raises :exc:`MemoryError` or :exc:`SystemError`. +.. _struct-sequence-objects: + Struct Sequence Objects ----------------------- @@ -142,39 +144,39 @@ type. Contains the meta information of a struct sequence type to create. - +-------------------+------------------------------+--------------------------------------+ - | Field | C Type | Meaning | - +===================+==============================+======================================+ - | ``name`` | ``const char *`` | name of the struct sequence type | - +-------------------+------------------------------+--------------------------------------+ - | ``doc`` | ``const char *`` | pointer to docstring for the type | - | | | or ``NULL`` to omit | - +-------------------+------------------------------+--------------------------------------+ - | ``fields`` | ``PyStructSequence_Field *`` | pointer to ``NULL``-terminated array | - | | | with field names of the new type | - +-------------------+------------------------------+--------------------------------------+ - | ``n_in_sequence`` | ``int`` | number of fields visible to the | - | | | Python side (if used as tuple) | - +-------------------+------------------------------+--------------------------------------+ + .. c:member:: const char *name + + Name of the struct sequence type. + + .. c:member:: const char *doc + + Pointer to docstring for the type or ``NULL`` to omit. + + .. c:member:: PyStructSequence_Field *fields + + Pointer to ``NULL``-terminated array with field names of the new type. + + .. c:member:: int n_in_sequence + + Number of fields visible to the Python side (if used as tuple). .. c:type:: PyStructSequence_Field Describes a field of a struct sequence. As a struct sequence is modeled as a tuple, all fields are typed as :c:expr:`PyObject*`. The index in the - :attr:`fields` array of the :c:type:`PyStructSequence_Desc` determines which + :c:member:`~PyStructSequence_Desc.fields` array of + the :c:type:`PyStructSequence_Desc` determines which field of the struct sequence is described. - +-----------+------------------+-----------------------------------------+ - | Field | C Type | Meaning | - +===========+==================+=========================================+ - | ``name`` | ``const char *`` | name for the field or ``NULL`` to end | - | | | the list of named fields, set to | - | | | :c:data:`PyStructSequence_UnnamedField` | - | | | to leave unnamed | - +-----------+------------------+-----------------------------------------+ - | ``doc`` | ``const char *`` | field docstring or ``NULL`` to omit | - +-----------+------------------+-----------------------------------------+ + .. c:member:: const char *name + + Name for the field or ``NULL`` to end the list of named fields, + set to :c:data:`PyStructSequence_UnnamedField` to leave unnamed. + + .. c:member:: const char *doc + + Field docstring or ``NULL`` to omit. .. c:var:: const char * const PyStructSequence_UnnamedField diff --git a/Doc/c-api/type.rst b/Doc/c-api/type.rst index ac352047..0f58326f 100644 --- a/Doc/c-api/type.rst +++ b/Doc/c-api/type.rst @@ -5,7 +5,7 @@ Type Objects ------------ -.. index:: object: type +.. index:: pair: object; type .. c:type:: PyTypeObject @@ -42,7 +42,7 @@ Type Objects Return the :c:member:`~PyTypeObject.tp_flags` member of *type*. This function is primarily meant for use with ``Py_LIMITED_API``; the individual flag bits are guaranteed to be stable across Python releases, but access to - :c:member:`~PyTypeObject.tp_flags` itself is not part of the limited API. + :c:member:`~PyTypeObject.tp_flags` itself is not part of the :ref:`limited API `. .. versionadded:: 3.2 @@ -50,6 +50,23 @@ Type Objects The return type is now ``unsigned long`` rather than ``long``. +.. c:function:: PyObject* PyType_GetDict(PyTypeObject* type) + + Return the type object's internal namespace, which is otherwise only + exposed via a read-only proxy (``cls.__dict__``). This is a + replacement for accessing :c:member:`~PyTypeObject.tp_dict` directly. + The returned dictionary must be treated as read-only. + + This function is meant for specific embedding and language-binding cases, + where direct access to the dict is necessary and indirect access + (e.g. via the proxy or :c:func:`PyObject_GetAttr`) isn't adequate. + + Extension modules should continue to use ``tp_dict``, + directly or indirectly, when setting up their own types. + + .. versionadded:: 3.12 + + .. c:function:: void PyType_Modified(PyTypeObject *type) Invalidate the internal lookup cache for the type and all of its @@ -57,6 +74,55 @@ Type Objects modification of the attributes or base classes of the type. +.. c:function:: int PyType_AddWatcher(PyType_WatchCallback callback) + + Register *callback* as a type watcher. Return a non-negative integer ID + which must be passed to future calls to :c:func:`PyType_Watch`. In case of + error (e.g. no more watcher IDs available), return ``-1`` and set an + exception. + + .. versionadded:: 3.12 + + +.. c:function:: int PyType_ClearWatcher(int watcher_id) + + Clear watcher identified by *watcher_id* (previously returned from + :c:func:`PyType_AddWatcher`). Return ``0`` on success, ``-1`` on error (e.g. + if *watcher_id* was never registered.) + + An extension should never call ``PyType_ClearWatcher`` with a *watcher_id* + that was not returned to it by a previous call to + :c:func:`PyType_AddWatcher`. + + .. versionadded:: 3.12 + + +.. c:function:: int PyType_Watch(int watcher_id, PyObject *type) + + Mark *type* as watched. The callback granted *watcher_id* by + :c:func:`PyType_AddWatcher` will be called whenever + :c:func:`PyType_Modified` reports a change to *type*. (The callback may be + called only once for a series of consecutive modifications to *type*, if + :c:func:`!_PyType_Lookup` is not called on *type* between the modifications; + this is an implementation detail and subject to change.) + + An extension should never call ``PyType_Watch`` with a *watcher_id* that was + not returned to it by a previous call to :c:func:`PyType_AddWatcher`. + + .. versionadded:: 3.12 + + +.. c:type:: int (*PyType_WatchCallback)(PyObject *type) + + Type of a type-watcher callback function. + + The callback must not modify *type* or cause :c:func:`PyType_Modified` to be + called on *type* or any type in its MRO; violating this rule could cause + infinite recursion. + + .. versionadded:: 3.12 + + .. c:function:: int PyType_HasFeature(PyTypeObject *o, int feature) Return non-zero if the type object *o* sets the feature *feature*. @@ -66,7 +132,7 @@ Type Objects .. c:function:: int PyType_IS_GC(PyTypeObject *o) Return true if the type object includes support for the cycle detector; this - tests the type flag :const:`Py_TPFLAGS_HAVE_GC`. + tests the type flag :c:macro:`Py_TPFLAGS_HAVE_GC`. .. c:function:: int PyType_IsSubtype(PyTypeObject *a, PyTypeObject *b) @@ -99,10 +165,10 @@ Type Objects .. note:: If some of the base classes implements the GC protocol and the provided - type does not include the :const:`Py_TPFLAGS_HAVE_GC` in its flags, then + type does not include the :c:macro:`Py_TPFLAGS_HAVE_GC` in its flags, then the GC protocol will be automatically implemented from its parents. On the contrary, if the type being created does include - :const:`Py_TPFLAGS_HAVE_GC` in its flags then it **must** implement the + :c:macro:`Py_TPFLAGS_HAVE_GC` in its flags then it **must** implement the GC protocol itself by at least implementing the :c:member:`~PyTypeObject.tp_traverse` handle. @@ -149,7 +215,7 @@ Type Objects ``Py_TYPE(self)`` may be a *subclass* of the intended class, and subclasses are not necessarily defined in the same module as their superclass. See :c:type:`PyCMethod` to get the class that defines the method. - See :c:func:`PyType_GetModuleByDef` for cases when ``PyCMethod`` cannot + See :c:func:`PyType_GetModuleByDef` for cases when :c:type:`!PyCMethod` cannot be used. .. versionadded:: 3.9 @@ -183,6 +249,15 @@ Type Objects .. versionadded:: 3.11 +.. c:function:: int PyUnstable_Type_AssignVersionTag(PyTypeObject *type) + + Attempt to assign a version tag to the given type. + + Returns 1 if the type already had a valid version tag or a new one was + assigned, or 0 if a new tag could not be assigned. + + .. versionadded:: 3.12 + Creating Heap-Allocated Types ............................. @@ -190,10 +265,21 @@ Creating Heap-Allocated Types The following functions and structs are used to create :ref:`heap types `. -.. c:function:: PyObject* PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases) +.. c:function:: PyObject* PyType_FromMetaclass(PyTypeObject *metaclass, PyObject *module, PyType_Spec *spec, PyObject *bases) + + Create and return a :ref:`heap type ` from the *spec* + (see :c:macro:`Py_TPFLAGS_HEAPTYPE`). - Creates and returns a :ref:`heap type ` from the *spec* - (:const:`Py_TPFLAGS_HEAPTYPE`). + The metaclass *metaclass* is used to construct the resulting type object. + When *metaclass* is ``NULL``, the metaclass is derived from *bases* + (or *Py_tp_base[s]* slots if *bases* is ``NULL``, see below). + + Metaclasses that override :c:member:`~PyTypeObject.tp_new` are not + supported, except if ``tp_new`` is ``NULL``. + (For backwards compatibility, other ``PyType_From*`` functions allow + such metaclasses. They ignore ``tp_new``, which may result in incomplete + initialization. This is deprecated and in Python 3.14+ such metaclasses will + not be supported.) The *bases* argument can be used to specify base classes; it can either be only one class or a tuple of classes. @@ -210,6 +296,25 @@ The following functions and structs are used to create This function calls :c:func:`PyType_Ready` on the new type. + Note that this function does *not* fully match the behavior of + calling :py:class:`type() ` or using the :keyword:`class` statement. + With user-provided base types or metaclasses, prefer + :ref:`calling ` :py:class:`type` (or the metaclass) + over ``PyType_From*`` functions. + Specifically: + + * :py:meth:`~object.__new__` is not called on the new class + (and it must be set to ``type.__new__``). + * :py:meth:`~object.__init__` is not called on the new class. + * :py:meth:`~object.__init_subclass__` is not called on any bases. + * :py:meth:`~object.__set_name__` is not called on new descriptors. + + .. versionadded:: 3.12 + +.. c:function:: PyObject* PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases) + + Equivalent to ``PyType_FromMetaclass(NULL, module, spec, bases)``. + .. versionadded:: 3.9 .. versionchanged:: 3.10 @@ -217,49 +322,132 @@ The following functions and structs are used to create The function now accepts a single class as the *bases* argument and ``NULL`` as the ``tp_doc`` slot. + .. versionchanged:: 3.12 + + The function now finds and uses a metaclass corresponding to the provided + base classes. Previously, only :class:`type` instances were returned. + + The :c:member:`~PyTypeObject.tp_new` of the metaclass is *ignored*. + which may result in incomplete initialization. + Creating classes whose metaclass overrides + :c:member:`~PyTypeObject.tp_new` is deprecated and in Python 3.14+ it + will be no longer allowed. + .. c:function:: PyObject* PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases) - Equivalent to ``PyType_FromModuleAndSpec(NULL, spec, bases)``. + Equivalent to ``PyType_FromMetaclass(NULL, NULL, spec, bases)``. .. versionadded:: 3.3 + .. versionchanged:: 3.12 + + The function now finds and uses a metaclass corresponding to the provided + base classes. Previously, only :class:`type` instances were returned. + + The :c:member:`~PyTypeObject.tp_new` of the metaclass is *ignored*. + which may result in incomplete initialization. + Creating classes whose metaclass overrides + :c:member:`~PyTypeObject.tp_new` is deprecated and in Python 3.14+ it + will be no longer allowed. + .. c:function:: PyObject* PyType_FromSpec(PyType_Spec *spec) - Equivalent to ``PyType_FromSpecWithBases(spec, NULL)``. + Equivalent to ``PyType_FromMetaclass(NULL, NULL, spec, NULL)``. + + .. versionchanged:: 3.12 + + The function now finds and uses a metaclass corresponding to the + base classes provided in *Py_tp_base[s]* slots. + Previously, only :class:`type` instances were returned. + + The :c:member:`~PyTypeObject.tp_new` of the metaclass is *ignored*. + which may result in incomplete initialization. + Creating classes whose metaclass overrides + :c:member:`~PyTypeObject.tp_new` is deprecated and in Python 3.14+ it + will be no longer allowed. + +.. raw:: html + + + + + + + .. c:type:: PyType_Spec Structure defining a type's behavior. - .. c:member:: const char* PyType_Spec.name + .. c:member:: const char* name Name of the type, used to set :c:member:`PyTypeObject.tp_name`. - .. c:member:: int PyType_Spec.basicsize - .. c:member:: int PyType_Spec.itemsize + .. c:member:: int basicsize + + If positive, specifies the size of the instance in bytes. + It is used to set :c:member:`PyTypeObject.tp_basicsize`. + + If zero, specifies that :c:member:`~PyTypeObject.tp_basicsize` + should be inherited. + + If negative, the absolute value specifies how much space instances of the + class need *in addition* to the superclass. + Use :c:func:`PyObject_GetTypeData` to get a pointer to subclass-specific + memory reserved this way. + + .. versionchanged:: 3.12 + + Previously, this field could not be negative. + + .. c:member:: int itemsize - Size of the instance in bytes, used to set - :c:member:`PyTypeObject.tp_basicsize` and - :c:member:`PyTypeObject.tp_itemsize`. + Size of one element of a variable-size type, in bytes. + Used to set :c:member:`PyTypeObject.tp_itemsize`. + See ``tp_itemsize`` documentation for caveats. - .. c:member:: int PyType_Spec.flags + If zero, :c:member:`~PyTypeObject.tp_itemsize` is inherited. + Extending arbitrary variable-sized classes is dangerous, + since some types use a fixed offset for variable-sized memory, + which can then overlap fixed-sized memory used by a subclass. + To help prevent mistakes, inheriting ``itemsize`` is only possible + in the following situations: + + - The base is not variable-sized (its + :c:member:`~PyTypeObject.tp_itemsize`). + - The requested :c:member:`PyType_Spec.basicsize` is positive, + suggesting that the memory layout of the base class is known. + - The requested :c:member:`PyType_Spec.basicsize` is zero, + suggesting that the subclass does not access the instance's memory + directly. + - With the :c:macro:`Py_TPFLAGS_ITEMS_AT_END` flag. + + .. c:member:: unsigned int flags Type flags, used to set :c:member:`PyTypeObject.tp_flags`. If the ``Py_TPFLAGS_HEAPTYPE`` flag is not set, :c:func:`PyType_FromSpecWithBases` sets it automatically. - .. c:member:: PyType_Slot *PyType_Spec.slots + .. c:member:: PyType_Slot *slots Array of :c:type:`PyType_Slot` structures. Terminated by the special slot value ``{0, NULL}``. + Each slot ID should be specified at most once. + +.. raw:: html + + + + + .. c:type:: PyType_Slot Structure defining optional functionality of a type, containing a slot ID and a value pointer. - .. c:member:: int PyType_Slot.slot + .. c:member:: int slot A slot ID. @@ -283,16 +471,16 @@ The following functions and structs are used to create * :c:member:`~PyTypeObject.tp_weaklist` * :c:member:`~PyTypeObject.tp_vectorcall` * :c:member:`~PyTypeObject.tp_weaklistoffset` - (see :ref:`PyMemberDef `) + (use :c:macro:`Py_TPFLAGS_MANAGED_WEAKREF` instead) * :c:member:`~PyTypeObject.tp_dictoffset` - (see :ref:`PyMemberDef `) + (use :c:macro:`Py_TPFLAGS_MANAGED_DICT` instead) * :c:member:`~PyTypeObject.tp_vectorcall_offset` (see :ref:`PyMemberDef `) Setting :c:data:`Py_tp_bases` or :c:data:`Py_tp_base` may be problematic on some platforms. To avoid issues, use the *bases* argument of - :py:func:`PyType_FromSpecWithBases` instead. + :c:func:`PyType_FromSpecWithBases` instead. .. versionchanged:: 3.9 @@ -301,9 +489,9 @@ The following functions and structs are used to create .. versionchanged:: 3.11 :c:member:`~PyBufferProcs.bf_getbuffer` and :c:member:`~PyBufferProcs.bf_releasebuffer` are now available - under the limited API. + under the :ref:`limited API `. - .. c:member:: void *PyType_Slot.pfunc + .. c:member:: void *pfunc The desired value of the slot. In most cases, this is a pointer to a function. diff --git a/Doc/c-api/typehints.rst b/Doc/c-api/typehints.rst index 4c1957a2..98fe6873 100644 --- a/Doc/c-api/typehints.rst +++ b/Doc/c-api/typehints.rst @@ -35,7 +35,7 @@ two types exist -- :ref:`GenericAlias ` and ... } - .. seealso:: The data model method :meth:`__class_getitem__`. + .. seealso:: The data model method :meth:`~object.__class_getitem__`. .. versionadded:: 3.9 diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst index aa2de334..09880901 100644 --- a/Doc/c-api/typeobj.rst +++ b/Doc/c-api/typeobj.rst @@ -96,7 +96,7 @@ Quick Reference | | | __gt__, | | | | | | | | __ge__ | | | | | +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ - | :c:member:`~PyTypeObject.tp_weaklistoffset` | :c:type:`Py_ssize_t` | | | X | | ? | + | (:c:member:`~PyTypeObject.tp_weaklistoffset`) | :c:type:`Py_ssize_t` | | | X | | ? | +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ | :c:member:`~PyTypeObject.tp_iter` | :c:type:`getiterfunc` | __iter__ | | | | X | +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ @@ -117,7 +117,7 @@ Quick Reference | :c:member:`~PyTypeObject.tp_descr_set` | :c:type:`descrsetfunc` | __set__, | | | | X | | | | __delete__ | | | | | +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ - | :c:member:`~PyTypeObject.tp_dictoffset` | :c:type:`Py_ssize_t` | | | X | | ? | + | (:c:member:`~PyTypeObject.tp_dictoffset`) | :c:type:`Py_ssize_t` | | | X | | ? | +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ | :c:member:`~PyTypeObject.tp_init` | :c:type:`initproc` | __init__ | X | X | | X | +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ @@ -135,7 +135,7 @@ Quick Reference +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ | [:c:member:`~PyTypeObject.tp_cache`] | :c:type:`PyObject` * | | | | | +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ - | [:c:member:`~PyTypeObject.tp_subclasses`] | :c:type:`PyObject` * | __subclasses__ | | | | + | [:c:member:`~PyTypeObject.tp_subclasses`] | void * | __subclasses__ | | | | +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ | [:c:member:`~PyTypeObject.tp_weaklist`] | :c:type:`PyObject` * | | | | | +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ @@ -147,6 +147,8 @@ Quick Reference +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ | :c:member:`~PyTypeObject.tp_vectorcall` | :c:type:`vectorcallfunc` | | | | | | +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ + | [:c:member:`~PyTypeObject.tp_watched`] | unsigned char | | | | | | + +------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+ .. [#slots] @@ -161,9 +163,9 @@ Quick Reference .. [#cols] Columns: - **"O"**: set on :c:type:`PyBaseObject_Type` + **"O"**: set on :c:data:`PyBaseObject_Type` - **"T"**: set on :c:type:`PyType_Type` + **"T"**: set on :c:data:`PyType_Type` **"D"**: default (if slot is set to ``NULL``) @@ -483,17 +485,17 @@ PyObject Slots -------------- The type object structure extends the :c:type:`PyVarObject` structure. The -:attr:`ob_size` field is used for dynamic types (created by :func:`type_new`, +:c:member:`~PyVarObject.ob_size` field is used for dynamic types (created by :c:func:`!type_new`, usually called from a class statement). Note that :c:data:`PyType_Type` (the metatype) initializes :c:member:`~PyTypeObject.tp_itemsize`, which means that its instances (i.e. -type objects) *must* have the :attr:`ob_size` field. +type objects) *must* have the :c:member:`~PyVarObject.ob_size` field. .. c:member:: Py_ssize_t PyObject.ob_refcnt This is the type object's reference count, initialized to ``1`` by the ``PyObject_HEAD_INIT`` macro. Note that for :ref:`statically allocated type - objects `, the type's instances (objects whose :attr:`ob_type` + objects `, the type's instances (objects whose :c:member:`~PyObject.ob_type` points back to the type) do *not* count as references. But for :ref:`dynamically allocated type objects `, the instances *do* count as references. @@ -517,8 +519,8 @@ type objects) *must* have the :attr:`ob_size` field. Foo_Type.ob_type = &PyType_Type; This should be done before any instances of the type are created. - :c:func:`PyType_Ready` checks if :attr:`ob_type` is ``NULL``, and if so, - initializes it to the :attr:`ob_type` field of the base class. + :c:func:`PyType_Ready` checks if :c:member:`~PyObject.ob_type` is ``NULL``, and if so, + initializes it to the :c:member:`~PyObject.ob_type` field of the base class. :c:func:`PyType_Ready` will not change this field if it is non-zero. **Inheritance:** @@ -567,8 +569,8 @@ PyTypeObject Slots Each slot has a section describing inheritance. If :c:func:`PyType_Ready` may set a value when the field is set to ``NULL`` then there will also be -a "Default" section. (Note that many fields set on :c:type:`PyBaseObject_Type` -and :c:type:`PyType_Type` effectively act as defaults.) +a "Default" section. (Note that many fields set on :c:data:`PyBaseObject_Type` +and :c:data:`PyType_Type` effectively act as defaults.) .. c:member:: const char* PyTypeObject.tp_name @@ -577,7 +579,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) name, followed by a dot, followed by the type name; for built-in types, it should be just the type name. If the module is a submodule of a package, the full package name is part of the full module name. For example, a type named - :class:`T` defined in module :mod:`M` in subpackage :mod:`Q` in package :mod:`P` + :class:`!T` defined in module :mod:`!M` in subpackage :mod:`!Q` in package :mod:`!P` should have the :c:member:`~PyTypeObject.tp_name` initializer ``"P.Q.M.T"``. For :ref:`dynamically allocated type objects `, @@ -617,20 +619,20 @@ and :c:type:`PyType_Type` effectively act as defaults.) instances have the same size, given in :c:member:`~PyTypeObject.tp_basicsize`. For a type with variable-length instances, the instances must have an - :attr:`ob_size` field, and the instance size is :c:member:`~PyTypeObject.tp_basicsize` plus N + :c:member:`~PyVarObject.ob_size` field, and the instance size is :c:member:`~PyTypeObject.tp_basicsize` plus N times :c:member:`~PyTypeObject.tp_itemsize`, where N is the "length" of the object. The value of - N is typically stored in the instance's :attr:`ob_size` field. There are - exceptions: for example, ints use a negative :attr:`ob_size` to indicate a + N is typically stored in the instance's :c:member:`~PyVarObject.ob_size` field. There are + exceptions: for example, ints use a negative :c:member:`~PyVarObject.ob_size` to indicate a negative number, and N is ``abs(ob_size)`` there. Also, the presence of an - :attr:`ob_size` field in the instance layout doesn't mean that the instance + :c:member:`~PyVarObject.ob_size` field in the instance layout doesn't mean that the instance structure is variable-length (for example, the structure for the list type has - fixed-length instances, yet those instances have a meaningful :attr:`ob_size` + fixed-length instances, yet those instances have a meaningful :c:member:`~PyVarObject.ob_size` field). The basic size includes the fields in the instance declared by the macro :c:macro:`PyObject_HEAD` or :c:macro:`PyObject_VAR_HEAD` (whichever is used to - declare the instance struct) and this in turn includes the :attr:`_ob_prev` and - :attr:`_ob_next` fields if they are present. This means that the only correct + declare the instance struct) and this in turn includes the :c:member:`~PyObject._ob_prev` and + :c:member:`~PyObject._ob_next` fields if they are present. This means that the only correct way to get an initializer for the :c:member:`~PyTypeObject.tp_basicsize` is to use the ``sizeof`` operator on the struct used to declare the instance layout. The basic size does not include the GC header size. @@ -667,15 +669,15 @@ and :c:type:`PyType_Type` effectively act as defaults.) memory buffers owned by the instance (using the freeing function corresponding to the allocation function used to allocate the buffer), and call the type's :c:member:`~PyTypeObject.tp_free` function. If the type is not subtypable - (doesn't have the :const:`Py_TPFLAGS_BASETYPE` flag bit set), it is + (doesn't have the :c:macro:`Py_TPFLAGS_BASETYPE` flag bit set), it is permissible to call the object deallocator directly instead of via :c:member:`~PyTypeObject.tp_free`. The object deallocator should be the one used to allocate the instance; this is normally :c:func:`PyObject_Del` if the instance was allocated - using :c:func:`PyObject_New` or :c:func:`PyObject_VarNew`, or + using :c:macro:`PyObject_New` or :c:macro:`PyObject_NewVar`, or :c:func:`PyObject_GC_Del` if the instance was allocated using - :c:func:`PyObject_GC_New` or :c:func:`PyObject_GC_NewVar`. + :c:macro:`PyObject_GC_New` or :c:macro:`PyObject_GC_NewVar`. - If the type supports garbage collection (has the :const:`Py_TPFLAGS_HAVE_GC` + If the type supports garbage collection (has the :c:macro:`Py_TPFLAGS_HAVE_GC` flag bit set), the destructor should call :c:func:`PyObject_GC_UnTrack` before clearing any member fields. @@ -687,8 +689,9 @@ and :c:type:`PyType_Type` effectively act as defaults.) Py_TYPE(self)->tp_free((PyObject *)self); } - Finally, if the type is heap allocated (:const:`Py_TPFLAGS_HEAPTYPE`), the - deallocator should decrement the reference count for its type object after + Finally, if the type is heap allocated (:c:macro:`Py_TPFLAGS_HEAPTYPE`), the + deallocator should release the owned reference to its type object + (via :c:func:`Py_DECREF`) after calling the type deallocator. In order to avoid dangling pointers, the recommended way to achieve this is: @@ -714,12 +717,12 @@ and :c:type:`PyType_Type` effectively act as defaults.) a more efficient alternative of the simpler :c:member:`~PyTypeObject.tp_call`. - This field is only used if the flag :const:`Py_TPFLAGS_HAVE_VECTORCALL` + This field is only used if the flag :c:macro:`Py_TPFLAGS_HAVE_VECTORCALL` is set. If so, this must be a positive integer containing the offset in the instance of a :c:type:`vectorcallfunc` pointer. The *vectorcallfunc* pointer may be ``NULL``, in which case the instance behaves - as if :const:`Py_TPFLAGS_HAVE_VECTORCALL` was not set: calling the instance + as if :c:macro:`Py_TPFLAGS_HAVE_VECTORCALL` was not set: calling the instance falls back to :c:member:`~PyTypeObject.tp_call`. Any class that sets ``Py_TPFLAGS_HAVE_VECTORCALL`` must also set @@ -727,29 +730,29 @@ and :c:type:`PyType_Type` effectively act as defaults.) with the *vectorcallfunc* function. This can be done by setting *tp_call* to :c:func:`PyVectorcall_Call`. - .. warning:: - - It is not recommended for :ref:`mutable heap types ` to implement - the vectorcall protocol. - When a user sets :attr:`__call__` in Python code, only *tp_call* is updated, - likely making it inconsistent with the vectorcall function. - .. versionchanged:: 3.8 Before version 3.8, this slot was named ``tp_print``. In Python 2.x, it was used for printing to a file. In Python 3.0 to 3.7, it was unused. + .. versionchanged:: 3.12 + + Before version 3.12, it was not recommended for + :ref:`mutable heap types ` to implement the vectorcall + protocol. + When a user sets :attr:`~object.__call__` in Python code, only *tp_call* is + updated, likely making it inconsistent with the vectorcall function. + Since 3.12, setting ``__call__`` will disable vectorcall optimization + by clearing the :c:macro:`Py_TPFLAGS_HAVE_VECTORCALL` flag. + **Inheritance:** This field is always inherited. - However, the :const:`Py_TPFLAGS_HAVE_VECTORCALL` flag is not - always inherited. If it's not, then the subclass won't use + However, the :c:macro:`Py_TPFLAGS_HAVE_VECTORCALL` flag is not + always inherited. If it's not set, then the subclass won't use :ref:`vectorcall `, except when :c:func:`PyVectorcall_Call` is explicitly called. - This is in particular the case for types without the - :const:`Py_TPFLAGS_IMMUTABLETYPE` flag set (including subclasses defined in - Python). .. c:member:: getattrfunc PyTypeObject.tp_getattr @@ -762,7 +765,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) **Inheritance:** - Group: :attr:`tp_getattr`, :attr:`tp_getattro` + Group: :c:member:`~PyTypeObject.tp_getattr`, :c:member:`~PyTypeObject.tp_getattro` This field is inherited by subtypes together with :c:member:`~PyTypeObject.tp_getattro`: a subtype inherits both :c:member:`~PyTypeObject.tp_getattr` and :c:member:`~PyTypeObject.tp_getattro` from its base type when @@ -779,7 +782,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) **Inheritance:** - Group: :attr:`tp_setattr`, :attr:`tp_setattro` + Group: :c:member:`~PyTypeObject.tp_setattr`, :c:member:`~PyTypeObject.tp_setattro` This field is inherited by subtypes together with :c:member:`~PyTypeObject.tp_setattro`: a subtype inherits both :c:member:`~PyTypeObject.tp_setattr` and :c:member:`~PyTypeObject.tp_setattro` from its base type when @@ -803,7 +806,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) .. c:member:: reprfunc PyTypeObject.tp_repr - .. index:: builtin: repr + .. index:: pair: built-in function; repr An optional pointer to a function that implements the built-in function :func:`repr`. @@ -868,7 +871,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) .. c:member:: hashfunc PyTypeObject.tp_hash - .. index:: builtin: hash + .. index:: pair: built-in function; hash An optional pointer to a function that implements the built-in function :func:`hash`. @@ -881,7 +884,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) normal return value; when an error occurs during the computation of the hash value, the function should set an exception and return ``-1``. - When this field is not set (*and* :attr:`tp_richcompare` is not set), + When this field is not set (*and* :c:member:`~PyTypeObject.tp_richcompare` is not set), an attempt to take the hash of the object raises :exc:`TypeError`. This is the same as setting it to :c:func:`PyObject_HashNotImplemented`. @@ -895,7 +898,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) **Inheritance:** - Group: :attr:`tp_hash`, :attr:`tp_richcompare` + Group: :c:member:`~PyTypeObject.tp_hash`, :c:member:`~PyTypeObject.tp_richcompare` This field is inherited by subtypes together with :c:member:`~PyTypeObject.tp_richcompare`: a subtype inherits both of @@ -954,7 +957,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) **Inheritance:** - Group: :attr:`tp_getattr`, :attr:`tp_getattro` + Group: :c:member:`~PyTypeObject.tp_getattr`, :c:member:`~PyTypeObject.tp_getattro` This field is inherited by subtypes together with :c:member:`~PyTypeObject.tp_getattr`: a subtype inherits both :c:member:`~PyTypeObject.tp_getattr` and :c:member:`~PyTypeObject.tp_getattro` from its base type when @@ -962,7 +965,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) **Default:** - :c:type:`PyBaseObject_Type` uses :c:func:`PyObject_GenericGetAttr`. + :c:data:`PyBaseObject_Type` uses :c:func:`PyObject_GenericGetAttr`. .. c:member:: setattrofunc PyTypeObject.tp_setattro @@ -980,7 +983,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) **Inheritance:** - Group: :attr:`tp_setattr`, :attr:`tp_setattro` + Group: :c:member:`~PyTypeObject.tp_setattr`, :c:member:`~PyTypeObject.tp_setattro` This field is inherited by subtypes together with :c:member:`~PyTypeObject.tp_setattr`: a subtype inherits both :c:member:`~PyTypeObject.tp_setattr` and :c:member:`~PyTypeObject.tp_setattro` from its base type when @@ -988,7 +991,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) **Default:** - :c:type:`PyBaseObject_Type` uses :c:func:`PyObject_GenericSetAttr`. + :c:data:`PyBaseObject_Type` uses :c:func:`PyObject_GenericSetAttr`. .. c:member:: PyBufferProcs* PyTypeObject.tp_as_buffer @@ -1020,31 +1023,32 @@ and :c:type:`PyType_Type` effectively act as defaults.) this flag bit. The flag bits that pertain to extension structures are strictly inherited if the extension structure is inherited, i.e. the base type's value of the flag bit is copied into the subtype together with a pointer to the extension - structure. The :const:`Py_TPFLAGS_HAVE_GC` flag bit is inherited together with + structure. The :c:macro:`Py_TPFLAGS_HAVE_GC` flag bit is inherited together with the :c:member:`~PyTypeObject.tp_traverse` and :c:member:`~PyTypeObject.tp_clear` fields, i.e. if the - :const:`Py_TPFLAGS_HAVE_GC` flag bit is clear in the subtype and the + :c:macro:`Py_TPFLAGS_HAVE_GC` flag bit is clear in the subtype and the :c:member:`~PyTypeObject.tp_traverse` and :c:member:`~PyTypeObject.tp_clear` fields in the subtype exist and have ``NULL`` values. - .. XXX are most flag bits *really* inherited individually? **Default:** - :c:type:`PyBaseObject_Type` uses + :c:data:`PyBaseObject_Type` uses ``Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE``. **Bit Masks:** + .. c:namespace:: NULL + The following bit masks are currently defined; these can be ORed together using the ``|`` operator to form the value of the :c:member:`~PyTypeObject.tp_flags` field. The macro :c:func:`PyType_HasFeature` takes a type and a flags value, *tp* and *f*, and checks whether ``tp->tp_flags & f`` is non-zero. - .. data:: Py_TPFLAGS_HEAPTYPE + .. c:macro:: Py_TPFLAGS_HEAPTYPE This bit is set when the type object itself is allocated on the heap, for example, types created dynamically using :c:func:`PyType_FromSpec`. In this - case, the :attr:`ob_type` field of its instances is considered a reference to + case, the :c:member:`~PyObject.ob_type` field of its instances is considered a reference to the type, and the type object is INCREF'ed when a new instance is created, and DECREF'ed when an instance is destroyed (this does not apply to instances of subtypes; only the type referenced by the instance's ob_type gets INCREF'ed or @@ -1055,7 +1059,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) ??? - .. data:: Py_TPFLAGS_BASETYPE + .. c:macro:: Py_TPFLAGS_BASETYPE This bit is set when the type can be used as the base type of another type. If this bit is clear, the type cannot be subtyped (similar to a "final" class in @@ -1066,7 +1070,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) ??? - .. data:: Py_TPFLAGS_READY + .. c:macro:: Py_TPFLAGS_READY This bit is set when the type object has been fully initialized by :c:func:`PyType_Ready`. @@ -1076,7 +1080,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) ??? - .. data:: Py_TPFLAGS_READYING + .. c:macro:: Py_TPFLAGS_READYING This bit is set while :c:func:`PyType_Ready` is in the process of initializing the type object. @@ -1086,10 +1090,10 @@ and :c:type:`PyType_Type` effectively act as defaults.) ??? - .. data:: Py_TPFLAGS_HAVE_GC + .. c:macro:: Py_TPFLAGS_HAVE_GC This bit is set when the object supports garbage collection. If this bit - is set, instances must be created using :c:func:`PyObject_GC_New` and + is set, instances must be created using :c:macro:`PyObject_GC_New` and destroyed using :c:func:`PyObject_GC_Del`. More information in section :ref:`supporting-cycle-detection`. This bit also implies that the GC-related fields :c:member:`~PyTypeObject.tp_traverse` and :c:member:`~PyTypeObject.tp_clear` are present in @@ -1097,28 +1101,28 @@ and :c:type:`PyType_Type` effectively act as defaults.) **Inheritance:** - Group: :const:`Py_TPFLAGS_HAVE_GC`, :attr:`tp_traverse`, :attr:`tp_clear` + Group: :c:macro:`Py_TPFLAGS_HAVE_GC`, :c:member:`~PyTypeObject.tp_traverse`, :c:member:`~PyTypeObject.tp_clear` - The :const:`Py_TPFLAGS_HAVE_GC` flag bit is inherited - together with the :attr:`tp_traverse` and :attr:`tp_clear` - fields, i.e. if the :const:`Py_TPFLAGS_HAVE_GC` flag bit is - clear in the subtype and the :attr:`tp_traverse` and - :attr:`tp_clear` fields in the subtype exist and have ``NULL`` + The :c:macro:`Py_TPFLAGS_HAVE_GC` flag bit is inherited + together with the :c:member:`~PyTypeObject.tp_traverse` and :c:member:`~PyTypeObject.tp_clear` + fields, i.e. if the :c:macro:`Py_TPFLAGS_HAVE_GC` flag bit is + clear in the subtype and the :c:member:`~PyTypeObject.tp_traverse` and + :c:member:`~PyTypeObject.tp_clear` fields in the subtype exist and have ``NULL`` values. - .. data:: Py_TPFLAGS_DEFAULT + .. c:macro:: Py_TPFLAGS_DEFAULT This is a bitmask of all the bits that pertain to the existence of certain fields in the type object and its extension structures. Currently, it includes - the following bits: :const:`Py_TPFLAGS_HAVE_STACKLESS_EXTENSION`. + the following bits: :c:macro:`Py_TPFLAGS_HAVE_STACKLESS_EXTENSION`. **Inheritance:** ??? - .. data:: Py_TPFLAGS_METHOD_DESCRIPTOR + .. c:macro:: Py_TPFLAGS_METHOD_DESCRIPTOR This bit indicates that objects behave like unbound methods. @@ -1139,21 +1143,68 @@ and :c:type:`PyType_Type` effectively act as defaults.) **Inheritance:** This flag is never inherited by types without the - :const:`Py_TPFLAGS_IMMUTABLETYPE` flag set. For extension types, it is + :c:macro:`Py_TPFLAGS_IMMUTABLETYPE` flag set. For extension types, it is inherited whenever :c:member:`~PyTypeObject.tp_descr_get` is inherited. + .. c:macro:: Py_TPFLAGS_MANAGED_DICT + + This bit indicates that instances of the class have a ``__dict__`` + attribute, and that the space for the dictionary is managed by the VM. + + If this flag is set, :c:macro:`Py_TPFLAGS_HAVE_GC` should also be set. + + .. versionadded:: 3.12 + + **Inheritance:** + + This flag is inherited unless the + :c:member:`~PyTypeObject.tp_dictoffset` field is set in a superclass. + + + .. c:macro:: Py_TPFLAGS_MANAGED_WEAKREF + + This bit indicates that instances of the class should be weakly + referenceable. + + .. versionadded:: 3.12 + + **Inheritance:** + + This flag is inherited unless the + :c:member:`~PyTypeObject.tp_weaklistoffset` field is set in a superclass. + + + .. c:macro:: Py_TPFLAGS_ITEMS_AT_END + + Only usable with variable-size types, i.e. ones with non-zero + :c:member:`~PyTypeObject.tp_itemsize`. + + Indicates that the variable-sized portion of an instance of this type is + at the end of the instance's memory area, at an offset of + ``Py_TYPE(obj)->tp_basicsize`` (which may be different in each + subclass). + + When setting this flag, be sure that all superclasses either + use this memory layout, or are not variable-sized. + Python does not check this. + + .. versionadded:: 3.12 + + **Inheritance:** + + This flag is inherited. .. XXX Document more flags here? - .. data:: Py_TPFLAGS_LONG_SUBCLASS - .. data:: Py_TPFLAGS_LIST_SUBCLASS - .. data:: Py_TPFLAGS_TUPLE_SUBCLASS - .. data:: Py_TPFLAGS_BYTES_SUBCLASS - .. data:: Py_TPFLAGS_UNICODE_SUBCLASS - .. data:: Py_TPFLAGS_DICT_SUBCLASS - .. data:: Py_TPFLAGS_BASE_EXC_SUBCLASS - .. data:: Py_TPFLAGS_TYPE_SUBCLASS + .. c:macro:: Py_TPFLAGS_LONG_SUBCLASS + .. c:macro:: Py_TPFLAGS_LIST_SUBCLASS + .. c:macro:: Py_TPFLAGS_TUPLE_SUBCLASS + .. c:macro:: Py_TPFLAGS_BYTES_SUBCLASS + .. c:macro:: Py_TPFLAGS_UNICODE_SUBCLASS + .. c:macro:: Py_TPFLAGS_DICT_SUBCLASS + .. c:macro:: Py_TPFLAGS_BASE_EXC_SUBCLASS + .. c:macro:: Py_TPFLAGS_TYPE_SUBCLASS These flags are used by functions such as :c:func:`PyLong_Check` to quickly determine if a type is a subclass @@ -1164,7 +1215,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) will behave differently depending on what kind of check is used. - .. data:: Py_TPFLAGS_HAVE_FINALIZE + .. c:macro:: Py_TPFLAGS_HAVE_FINALIZE This bit is set when the :c:member:`~PyTypeObject.tp_finalize` slot is present in the type structure. @@ -1177,7 +1228,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) type structure. - .. data:: Py_TPFLAGS_HAVE_VECTORCALL + .. c:macro:: Py_TPFLAGS_HAVE_VECTORCALL This bit is set when the class implements the :ref:`vectorcall protocol `. @@ -1185,13 +1236,19 @@ and :c:type:`PyType_Type` effectively act as defaults.) **Inheritance:** - This bit is inherited for types with the - :const:`Py_TPFLAGS_IMMUTABLETYPE` flag set, if - :c:member:`~PyTypeObject.tp_call` is also inherited. + This bit is inherited if :c:member:`~PyTypeObject.tp_call` is also + inherited. .. versionadded:: 3.9 - .. data:: Py_TPFLAGS_IMMUTABLETYPE + .. versionchanged:: 3.12 + + This flag is now removed from a class when the class's + :py:meth:`~object.__call__` method is reassigned. + + This flag can now be inherited by mutable classes. + + .. c:macro:: Py_TPFLAGS_IMMUTABLETYPE This bit is set for type objects that are immutable: type attributes cannot be set nor deleted. @@ -1204,7 +1261,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) .. versionadded:: 3.10 - .. data:: Py_TPFLAGS_DISALLOW_INSTANTIATION + .. c:macro:: Py_TPFLAGS_DISALLOW_INSTANTIATION Disallow creating instances of the type: set :c:member:`~PyTypeObject.tp_new` to NULL and don't create the ``__new__`` @@ -1235,7 +1292,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) .. versionadded:: 3.10 - .. data:: Py_TPFLAGS_MAPPING + .. c:macro:: Py_TPFLAGS_MAPPING This bit indicates that instances of the class may match mapping patterns when used as the subject of a :keyword:`match` block. It is automatically @@ -1244,20 +1301,20 @@ and :c:type:`PyType_Type` effectively act as defaults.) .. note:: - :const:`Py_TPFLAGS_MAPPING` and :const:`Py_TPFLAGS_SEQUENCE` are + :c:macro:`Py_TPFLAGS_MAPPING` and :c:macro:`Py_TPFLAGS_SEQUENCE` are mutually exclusive; it is an error to enable both flags simultaneously. **Inheritance:** This flag is inherited by types that do not already set - :const:`Py_TPFLAGS_SEQUENCE`. + :c:macro:`Py_TPFLAGS_SEQUENCE`. .. seealso:: :pep:`634` -- Structural Pattern Matching: Specification .. versionadded:: 3.10 - .. data:: Py_TPFLAGS_SEQUENCE + .. c:macro:: Py_TPFLAGS_SEQUENCE This bit indicates that instances of the class may match sequence patterns when used as the subject of a :keyword:`match` block. It is automatically @@ -1266,19 +1323,29 @@ and :c:type:`PyType_Type` effectively act as defaults.) .. note:: - :const:`Py_TPFLAGS_MAPPING` and :const:`Py_TPFLAGS_SEQUENCE` are + :c:macro:`Py_TPFLAGS_MAPPING` and :c:macro:`Py_TPFLAGS_SEQUENCE` are mutually exclusive; it is an error to enable both flags simultaneously. **Inheritance:** This flag is inherited by types that do not already set - :const:`Py_TPFLAGS_MAPPING`. + :c:macro:`Py_TPFLAGS_MAPPING`. .. seealso:: :pep:`634` -- Structural Pattern Matching: Specification .. versionadded:: 3.10 + .. c:macro:: Py_TPFLAGS_VALID_VERSION_TAG + + Internal. Do not set or unset this flag. + To indicate that a class has changed call :c:func:`PyType_Modified` + + .. warning:: + This flag is present in header files, but is an internal feature and should + not be used. It will be removed in a future version of CPython + + .. c:member:: const char* PyTypeObject.tp_doc An optional pointer to a NUL-terminated C string giving the docstring for this @@ -1293,7 +1360,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) .. c:member:: traverseproc PyTypeObject.tp_traverse An optional pointer to a traversal function for the garbage collector. This is - only used if the :const:`Py_TPFLAGS_HAVE_GC` flag bit is set. The signature is:: + only used if the :c:macro:`Py_TPFLAGS_HAVE_GC` flag bit is set. The signature is:: int tp_traverse(PyObject *self, visitproc visit, void *arg); @@ -1303,8 +1370,8 @@ and :c:type:`PyType_Type` effectively act as defaults.) The :c:member:`~PyTypeObject.tp_traverse` pointer is used by the garbage collector to detect reference cycles. A typical implementation of a :c:member:`~PyTypeObject.tp_traverse` function simply calls :c:func:`Py_VISIT` on each of the instance's members that are Python - objects that the instance owns. For example, this is function :c:func:`local_traverse` from the - :mod:`_thread` extension module:: + objects that the instance owns. For example, this is function :c:func:`!local_traverse` from the + :mod:`!_thread` extension module:: static int local_traverse(localobject *self, visitproc visit, void *arg) @@ -1355,10 +1422,10 @@ and :c:type:`PyType_Type` effectively act as defaults.) **Inheritance:** - Group: :const:`Py_TPFLAGS_HAVE_GC`, :attr:`tp_traverse`, :attr:`tp_clear` + Group: :c:macro:`Py_TPFLAGS_HAVE_GC`, :c:member:`~PyTypeObject.tp_traverse`, :c:member:`~PyTypeObject.tp_clear` This field is inherited by subtypes together with :c:member:`~PyTypeObject.tp_clear` and the - :const:`Py_TPFLAGS_HAVE_GC` flag bit: the flag bit, :c:member:`~PyTypeObject.tp_traverse`, and + :c:macro:`Py_TPFLAGS_HAVE_GC` flag bit: the flag bit, :c:member:`~PyTypeObject.tp_traverse`, and :c:member:`~PyTypeObject.tp_clear` are all inherited from the base type if they are all zero in the subtype. @@ -1366,7 +1433,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) .. c:member:: inquiry PyTypeObject.tp_clear An optional pointer to a clear function for the garbage collector. This is only - used if the :const:`Py_TPFLAGS_HAVE_GC` flag bit is set. The signature is:: + used if the :c:macro:`Py_TPFLAGS_HAVE_GC` flag bit is set. The signature is:: int tp_clear(PyObject *); @@ -1395,9 +1462,10 @@ and :c:type:`PyType_Type` effectively act as defaults.) } The :c:func:`Py_CLEAR` macro should be used, because clearing references is - delicate: the reference to the contained object must not be decremented until + delicate: the reference to the contained object must not be released + (via :c:func:`Py_DECREF`) until after the pointer to the contained object is set to ``NULL``. This is because - decrementing the reference count may cause the contained object to become trash, + releasing the reference may cause the contained object to become trash, triggering a chain of reclamation activity that may include invoking arbitrary Python code (due to finalizers, or weakref callbacks, associated with the contained object). If it's possible for such code to reference *self* again, @@ -1422,10 +1490,10 @@ and :c:type:`PyType_Type` effectively act as defaults.) **Inheritance:** - Group: :const:`Py_TPFLAGS_HAVE_GC`, :attr:`tp_traverse`, :attr:`tp_clear` + Group: :c:macro:`Py_TPFLAGS_HAVE_GC`, :c:member:`~PyTypeObject.tp_traverse`, :c:member:`~PyTypeObject.tp_clear` This field is inherited by subtypes together with :c:member:`~PyTypeObject.tp_traverse` and the - :const:`Py_TPFLAGS_HAVE_GC` flag bit: the flag bit, :c:member:`~PyTypeObject.tp_traverse`, and + :c:macro:`Py_TPFLAGS_HAVE_GC` flag bit: the flag bit, :c:member:`~PyTypeObject.tp_traverse`, and :c:member:`~PyTypeObject.tp_clear` are all inherited from the base type if they are all zero in the subtype. @@ -1447,21 +1515,23 @@ and :c:type:`PyType_Type` effectively act as defaults.) The following constants are defined to be used as the third argument for :c:member:`~PyTypeObject.tp_richcompare` and for :c:func:`PyObject_RichCompare`: - +----------------+------------+ - | Constant | Comparison | - +================+============+ - | :const:`Py_LT` | ``<`` | - +----------------+------------+ - | :const:`Py_LE` | ``<=`` | - +----------------+------------+ - | :const:`Py_EQ` | ``==`` | - +----------------+------------+ - | :const:`Py_NE` | ``!=`` | - +----------------+------------+ - | :const:`Py_GT` | ``>`` | - +----------------+------------+ - | :const:`Py_GE` | ``>=`` | - +----------------+------------+ + .. c:namespace:: NULL + + +--------------------+------------+ + | Constant | Comparison | + +====================+============+ + | .. c:macro:: Py_LT | ``<`` | + +--------------------+------------+ + | .. c:macro:: Py_LE | ``<=`` | + +--------------------+------------+ + | .. c:macro:: Py_EQ | ``==`` | + +--------------------+------------+ + | .. c:macro:: Py_NE | ``!=`` | + +--------------------+------------+ + | .. c:macro:: Py_GT | ``>`` | + +--------------------+------------+ + | .. c:macro:: Py_GE | ``>=`` | + +--------------------+------------+ The following macro is defined to ease writing rich comparison functions: @@ -1473,7 +1543,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) they may be C ints or floats). The third argument specifies the requested operation, as for :c:func:`PyObject_RichCompare`. - The return value's reference count is properly incremented. + The returned value is a new :term:`strong reference`. On error, sets an exception and returns ``NULL`` from the function. @@ -1481,7 +1551,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) **Inheritance:** - Group: :attr:`tp_hash`, :attr:`tp_richcompare` + Group: :c:member:`~PyTypeObject.tp_hash`, :c:member:`~PyTypeObject.tp_richcompare` This field is inherited by subtypes together with :c:member:`~PyTypeObject.tp_hash`: a subtype inherits :c:member:`~PyTypeObject.tp_richcompare` and :c:member:`~PyTypeObject.tp_hash` when @@ -1490,15 +1560,18 @@ and :c:type:`PyType_Type` effectively act as defaults.) **Default:** - :c:type:`PyBaseObject_Type` provides a :attr:`tp_richcompare` + :c:data:`PyBaseObject_Type` provides a :c:member:`~PyTypeObject.tp_richcompare` implementation, which may be inherited. However, if only - :attr:`tp_hash` is defined, not even the inherited function is used + :c:member:`~PyTypeObject.tp_hash` is defined, not even the inherited function is used and instances of the type will not be able to participate in any comparisons. .. c:member:: Py_ssize_t PyTypeObject.tp_weaklistoffset + While this field is still supported, :c:macro:`Py_TPFLAGS_MANAGED_WEAKREF` + should be used instead, if at all possible. + If the instances of this type are weakly referenceable, this field is greater than zero and contains the offset in the instance structure of the weak reference list head (ignoring the GC header, if present); this offset is used by @@ -1509,6 +1582,9 @@ and :c:type:`PyType_Type` effectively act as defaults.) Do not confuse this field with :c:member:`~PyTypeObject.tp_weaklist`; that is the list head for weak references to the type object itself. + It is an error to set both the :c:macro:`Py_TPFLAGS_MANAGED_WEAKREF` bit and + :c:member:`~PyTypeObject.tp_weaklist`. + **Inheritance:** This field is inherited by subtypes, but see the rules listed below. A subtype @@ -1516,19 +1592,12 @@ and :c:type:`PyType_Type` effectively act as defaults.) reference list head than the base type. Since the list head is always found via :c:member:`~PyTypeObject.tp_weaklistoffset`, this should not be a problem. - When a type defined by a class statement has no :attr:`~object.__slots__` declaration, - and none of its base types are weakly referenceable, the type is made weakly - referenceable by adding a weak reference list head slot to the instance layout - and setting the :c:member:`~PyTypeObject.tp_weaklistoffset` of that slot's offset. - - When a type's :attr:`__slots__` declaration contains a slot named - :attr:`__weakref__`, that slot becomes the weak reference list head for - instances of the type, and the slot's offset is stored in the type's - :c:member:`~PyTypeObject.tp_weaklistoffset`. + **Default:** - When a type's :attr:`__slots__` declaration does not contain a slot named - :attr:`__weakref__`, the type inherits its :c:member:`~PyTypeObject.tp_weaklistoffset` from its - base type. + If the :c:macro:`Py_TPFLAGS_MANAGED_WEAKREF` bit is set in the + :c:member:`~PyTypeObject.tp_dict` field, then + :c:member:`~PyTypeObject.tp_weaklistoffset` will be set to a negative value, + to indicate that it is unsafe to use this field. .. c:member:: getiterfunc PyTypeObject.tp_iter @@ -1628,7 +1697,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) to a pointer, are valid C99 address constants. However, the unary '&' operator applied to a non-static variable - like :c:func:`PyBaseObject_Type` is not required to produce an address + like :c:data:`PyBaseObject_Type` is not required to produce an address constant. Compilers may support this (gcc does), MSVC does not. Both compilers are strictly standard conforming in this particular behavior. @@ -1654,7 +1723,19 @@ and :c:type:`PyType_Type` effectively act as defaults.) called; it may also be initialized to a dictionary containing initial attributes for the type. Once :c:func:`PyType_Ready` has initialized the type, extra attributes for the type may be added to this dictionary only if they don't - correspond to overloaded operations (like :meth:`__add__`). + correspond to overloaded operations (like :meth:`~object.__add__`). Once + initialization for the type has finished, this field should be + treated as read-only. + + Some types may not store their dictionary in this slot. + Use :c:func:`PyType_GetDict` to retrieve the dictionary for an arbitrary + type. + + .. versionchanged:: 3.12 + + Internals detail: For static builtin types, this is always ``NULL``. + Instead, the dict for such types is stored on ``PyInterpreterState``. + Use :c:func:`PyType_GetDict` to get the dict for an arbitrary type. **Inheritance:** @@ -1707,6 +1788,9 @@ and :c:type:`PyType_Type` effectively act as defaults.) .. c:member:: Py_ssize_t PyTypeObject.tp_dictoffset + While this field is still supported, :c:macro:`Py_TPFLAGS_MANAGED_DICT` should be + used instead, if at all possible. + If the instances of this type have a dictionary containing instance variables, this field is non-zero and contains the offset in the instances of the type of the instance variable dictionary; this offset is used by @@ -1715,17 +1799,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) Do not confuse this field with :c:member:`~PyTypeObject.tp_dict`; that is the dictionary for attributes of the type object itself. - If the value of this field is greater than zero, it specifies the offset from - the start of the instance structure. If the value is less than zero, it - specifies the offset from the *end* of the instance structure. A negative - offset is more expensive to use, and should only be used when the instance - structure contains a variable-length part. This is used for example to add an - instance variable dictionary to subtypes of :class:`str` or :class:`tuple`. Note - that the :c:member:`~PyTypeObject.tp_basicsize` field should account for the dictionary added to - the end in that case, even though the dictionary is not included in the basic - object layout. On a system with a pointer size of 4 bytes, - :c:member:`~PyTypeObject.tp_dictoffset` should be set to ``-4`` to indicate that the dictionary is - at the very end of the structure. + The value specifies the offset of the dictionary from the start of the instance structure. The :c:member:`~PyTypeObject.tp_dictoffset` should be regarded as write-only. To get the pointer to the dictionary call :c:func:`PyObject_GenericGetDict`. @@ -1733,39 +1807,35 @@ and :c:type:`PyType_Type` effectively act as defaults.) dictionary, so it is may be more efficient to call :c:func:`PyObject_GetAttr` when accessing an attribute on the object. - **Inheritance:** - - This field is inherited by subtypes, but see the rules listed below. A subtype - may override this offset; this means that the subtype instances store the - dictionary at a difference offset than the base type. Since the dictionary is - always found via :c:member:`~PyTypeObject.tp_dictoffset`, this should not be a problem. - - When a type defined by a class statement has no :attr:`~object.__slots__` declaration, - and none of its base types has an instance variable dictionary, a dictionary - slot is added to the instance layout and the :c:member:`~PyTypeObject.tp_dictoffset` is set to - that slot's offset. + It is an error to set both the :c:macro:`Py_TPFLAGS_MANAGED_WEAKREF` bit and + :c:member:`~PyTypeObject.tp_dictoffset`. - When a type defined by a class statement has a :attr:`__slots__` declaration, - the type inherits its :c:member:`~PyTypeObject.tp_dictoffset` from its base type. + **Inheritance:** - (Adding a slot named :attr:`~object.__dict__` to the :attr:`__slots__` declaration does - not have the expected effect, it just causes confusion. Maybe this should be - added as a feature just like :attr:`__weakref__` though.) + This field is inherited by subtypes. A subtype should not override this offset; + doing so could be unsafe, if C code tries to access the dictionary at the + previous offset. + To properly support inheritance, use :c:macro:`Py_TPFLAGS_MANAGED_DICT`. **Default:** This slot has no default. For :ref:`static types `, if the - field is ``NULL`` then no :attr:`__dict__` gets created for instances. + field is ``NULL`` then no :attr:`~object.__dict__` gets created for instances. + + If the :c:macro:`Py_TPFLAGS_MANAGED_DICT` bit is set in the + :c:member:`~PyTypeObject.tp_dict` field, then + :c:member:`~PyTypeObject.tp_dictoffset` will be set to ``-1``, to indicate + that it is unsafe to use this field. .. c:member:: initproc PyTypeObject.tp_init An optional pointer to an instance initialization function. - This function corresponds to the :meth:`__init__` method of classes. Like - :meth:`__init__`, it is possible to create an instance without calling - :meth:`__init__`, and it is possible to reinitialize an instance by calling its - :meth:`__init__` method again. + This function corresponds to the :meth:`~object.__init__` method of classes. Like + :meth:`!__init__`, it is possible to create an instance without calling + :meth:`!__init__`, and it is possible to reinitialize an instance by calling its + :meth:`!__init__` method again. The function signature is:: @@ -1773,7 +1843,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) The self argument is the instance to be initialized; the *args* and *kwds* arguments represent positional and keyword arguments of the call to - :meth:`__init__`. + :meth:`~object.__init__`. The :c:member:`~PyTypeObject.tp_init` function, if not ``NULL``, is called when an instance is created normally by calling its type, after the type's :c:member:`~PyTypeObject.tp_new` function @@ -1812,7 +1882,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) :c:func:`PyType_GenericAlloc`, to force a standard heap allocation strategy. - For static subtypes, :c:type:`PyBaseObject_Type` uses + For static subtypes, :c:data:`PyBaseObject_Type` uses :c:func:`PyType_GenericAlloc`. That is the recommended value for all statically defined types. @@ -1839,7 +1909,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) in :c:member:`~PyTypeObject.tp_new`, while for mutable types, most initialization should be deferred to :c:member:`~PyTypeObject.tp_init`. - Set the :const:`Py_TPFLAGS_DISALLOW_INSTANTIATION` flag to disallow creating + Set the :c:macro:`Py_TPFLAGS_DISALLOW_INSTANTIATION` flag to disallow creating instances of the type in Python. **Inheritance:** @@ -1873,9 +1943,9 @@ and :c:type:`PyType_Type` effectively act as defaults.) In dynamic subtypes, this field is set to a deallocator suitable to match :c:func:`PyType_GenericAlloc` and the value of the - :const:`Py_TPFLAGS_HAVE_GC` flag bit. + :c:macro:`Py_TPFLAGS_HAVE_GC` flag bit. - For static subtypes, :c:type:`PyBaseObject_Type` uses PyObject_Del. + For static subtypes, :c:data:`PyBaseObject_Type` uses :c:func:`PyObject_Del`. .. c:member:: inquiry PyTypeObject.tp_is_gc @@ -1884,7 +1954,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) The garbage collector needs to know whether a particular object is collectible or not. Normally, it is sufficient to look at the object's type's - :c:member:`~PyTypeObject.tp_flags` field, and check the :const:`Py_TPFLAGS_HAVE_GC` flag bit. But + :c:member:`~PyTypeObject.tp_flags` field, and check the :c:macro:`Py_TPFLAGS_HAVE_GC` flag bit. But some types have a mixture of statically and dynamically allocated instances, and the statically allocated instances are not collectible. Such types should define this function; it should return ``1`` for a collectible instance, and @@ -1903,7 +1973,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) **Default:** This slot has no default. If this field is ``NULL``, - :const:`Py_TPFLAGS_HAVE_GC` is used as the functional equivalent. + :c:macro:`Py_TPFLAGS_HAVE_GC` is used as the functional equivalent. .. c:member:: PyObject* PyTypeObject.tp_bases @@ -1952,9 +2022,17 @@ and :c:type:`PyType_Type` effectively act as defaults.) This field is not inherited. -.. c:member:: PyObject* PyTypeObject.tp_subclasses +.. c:member:: void* PyTypeObject.tp_subclasses + + A collection of subclasses. Internal use only. May be an invalid pointer. + + To get a list of subclasses, call the Python method + :py:meth:`~class.__subclasses__`. - List of weak references to subclasses. Internal use only. + .. versionchanged:: 3.12 + + For some types, this field does not hold a valid :c:expr:`PyObject*`. + The type was changed to :c:expr:`void*` to indicate this. **Inheritance:** @@ -1966,6 +2044,13 @@ and :c:type:`PyType_Type` effectively act as defaults.) Weak reference list head, for weak references to this type object. Not inherited. Internal use only. + .. versionchanged:: 3.12 + + Internals detail: For the static builtin types this is always ``NULL``, + even if weakrefs are added. Instead, the weakrefs for each are stored + on ``PyInterpreterState``. Use the public C-API or the internal + ``_PyObject_GET_WEAKREFS_LISTPTR()`` macro to avoid the distinction. + **Inheritance:** This field is not inherited. @@ -2035,7 +2120,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) .. versionchanged:: 3.8 Before version 3.8 it was necessary to set the - :const:`Py_TPFLAGS_HAVE_FINALIZE` flags bit in order for this field to be + :c:macro:`Py_TPFLAGS_HAVE_FINALIZE` flags bit in order for this field to be used. This is no longer required. .. seealso:: "Safe object finalization" (:pep:`442`) @@ -2047,7 +2132,7 @@ and :c:type:`PyType_Type` effectively act as defaults.) In other words, it is used to implement :ref:`vectorcall ` for ``type.__call__``. If ``tp_vectorcall`` is ``NULL``, the default call implementation - using :attr:`__new__` and :attr:`__init__` is used. + using :meth:`~object.__new__` and :meth:`~object.__init__` is used. **Inheritance:** @@ -2056,6 +2141,13 @@ and :c:type:`PyType_Type` effectively act as defaults.) .. versionadded:: 3.9 (the field exists since 3.8 but it's only used since 3.9) +.. c:member:: unsigned char PyTypeObject.tp_watched + + Internal. Do not use. + + .. versionadded:: 3.12 + + .. _static-types: Static Types @@ -2076,7 +2168,7 @@ This results in types that are limited relative to types defined in Python: include any subinterpreter-specific state. Also, since :c:type:`PyTypeObject` is only part of the :ref:`Limited API -` as an opaque struct, any extension modules using static types must be +` as an opaque struct, any extension modules using static types must be compiled for a specific Python minor version. @@ -2087,12 +2179,12 @@ Heap Types An alternative to :ref:`static types ` is *heap-allocated types*, or *heap types* for short, which correspond closely to classes created by -Python's ``class`` statement. Heap types have the :const:`Py_TPFLAGS_HEAPTYPE` +Python's ``class`` statement. Heap types have the :c:macro:`Py_TPFLAGS_HEAPTYPE` flag set. This is done by filling a :c:type:`PyType_Spec` structure and calling :c:func:`PyType_FromSpec`, :c:func:`PyType_FromSpecWithBases`, -or :c:func:`PyType_FromModuleAndSpec`. +:c:func:`PyType_FromModuleAndSpec`, or :c:func:`PyType_FromMetaclass`. .. _number-structs: @@ -2167,8 +2259,8 @@ Number Object Structures .. note:: - The :c:data:`nb_reserved` field should always be ``NULL``. It - was previously called :c:data:`nb_long`, and was renamed in + The :c:member:`~PyNumberMethods.nb_reserved` field should always be ``NULL``. It + was previously called :c:member:`!nb_long`, and was renamed in Python 3.0.1. .. c:member:: binaryfunc PyNumberMethods.nb_add @@ -2239,8 +2331,8 @@ Mapping Object Structures .. c:member:: objobjargproc PyMappingMethods.mp_ass_subscript This function is used by :c:func:`PyObject_SetItem`, - :c:func:`PyObject_DelItem`, :c:func:`PyObject_SetSlice` and - :c:func:`PyObject_DelSlice`. It has the same signature as + :c:func:`PyObject_DelItem`, :c:func:`PySequence_SetSlice` and + :c:func:`PySequence_DelSlice`. It has the same signature as :c:func:`!PyObject_SetItem`, but *v* can also be set to ``NULL`` to delete an item. If this slot is ``NULL``, the object does not support item assignment and deletion. @@ -2286,9 +2378,9 @@ Sequence Object Structures This slot must be filled for the :c:func:`PySequence_Check` function to return ``1``, it can be ``NULL`` otherwise. - Negative indexes are handled as follows: if the :attr:`sq_length` slot is + Negative indexes are handled as follows: if the :c:member:`~PySequenceMethods.sq_length` slot is filled, it is called and the sequence length is used to compute a positive - index which is passed to :attr:`sq_item`. If :attr:`sq_length` is ``NULL``, + index which is passed to :c:member:`~PySequenceMethods.sq_item`. If :c:member:`!sq_length` is ``NULL``, the index is passed as is to the function. .. c:member:: ssizeobjargproc PySequenceMethods.sq_ass_item @@ -2351,7 +2443,7 @@ Buffer Object Structures Except for point (3), an implementation of this function MUST take these steps: - (1) Check if the request can be met. If not, raise :c:data:`PyExc_BufferError`, + (1) Check if the request can be met. If not, raise :exc:`BufferError`, set :c:expr:`view->obj` to ``NULL`` and return ``-1``. (2) Fill in the requested fields. @@ -2462,7 +2554,7 @@ Async Object Structures PyObject *am_aiter(PyObject *self); Must return an :term:`asynchronous iterator` object. - See :meth:`__anext__` for details. + See :meth:`~object.__anext__` for details. This slot may be set to ``NULL`` if an object does not implement asynchronous iteration protocol. @@ -2473,7 +2565,8 @@ Async Object Structures PyObject *am_anext(PyObject *self); - Must return an :term:`awaitable` object. See :meth:`__anext__` for details. + Must return an :term:`awaitable` object. + See :meth:`~object.__anext__` for details. This slot may be set to ``NULL``. .. c:member:: sendfunc PyAsyncMethods.am_send @@ -2498,8 +2591,8 @@ Slot Type typedefs The purpose of this function is to separate memory allocation from memory initialization. It should return a pointer to a block of memory of adequate length for the instance, suitably aligned, and initialized to zeros, but with - :attr:`ob_refcnt` set to ``1`` and :attr:`ob_type` set to the type argument. If - the type's :c:member:`~PyTypeObject.tp_itemsize` is non-zero, the object's :attr:`ob_size` field + :c:member:`~PyObject.ob_refcnt` set to ``1`` and :c:member:`~PyObject.ob_type` set to the type argument. If + the type's :c:member:`~PyTypeObject.tp_itemsize` is non-zero, the object's :c:member:`~PyVarObject.ob_size` field should be initialized to *nitems* and the length of the allocated memory block should be ``tp_basicsize + nitems*tp_itemsize``, rounded up to a multiple of ``sizeof(void*)``; otherwise, *nitems* is not used and the length of the block @@ -2673,8 +2766,6 @@ A type that supports weakrefs, instance dicts, and hashing:: typedef struct { PyObject_HEAD const char *data; - PyObject *inst_dict; - PyObject *weakreflist; } MyObject; static PyTypeObject MyObject_Type = { @@ -2682,9 +2773,9 @@ A type that supports weakrefs, instance dicts, and hashing:: .tp_name = "mymod.MyObject", .tp_basicsize = sizeof(MyObject), .tp_doc = PyDoc_STR("My objects"), - .tp_weaklistoffset = offsetof(MyObject, weakreflist), - .tp_dictoffset = offsetof(MyObject, inst_dict), - .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_MANAGED_DICT | + Py_TPFLAGS_MANAGED_WEAKREF, .tp_new = myobj_new, .tp_traverse = (traverseproc)myobj_traverse, .tp_clear = (inquiry)myobj_clear, @@ -2697,7 +2788,7 @@ A type that supports weakrefs, instance dicts, and hashing:: A str subclass that cannot be subclassed and cannot be called to create instances (e.g. uses a separate factory func) using -:c:data:`Py_TPFLAGS_DISALLOW_INSTANTIATION` flag:: +:c:macro:`Py_TPFLAGS_DISALLOW_INSTANTIATION` flag:: typedef struct { PyUnicodeObject raw; diff --git a/Doc/c-api/unicode.rst b/Doc/c-api/unicode.rst index e72f1515..c10c1511 100644 --- a/Doc/c-api/unicode.rst +++ b/Doc/c-api/unicode.rst @@ -17,26 +17,12 @@ of Unicode characters while staying memory efficient. There are special cases for strings where all code points are below 128, 256, or 65536; otherwise, code points must be below 1114112 (which is the full Unicode range). -:c:expr:`Py_UNICODE*` and UTF-8 representations are created on demand and cached -in the Unicode object. The :c:expr:`Py_UNICODE*` representation is deprecated -and inefficient. - -Due to the transition between the old APIs and the new APIs, Unicode objects -can internally be in two states depending on how they were created: - -* "canonical" Unicode objects are all objects created by a non-deprecated - Unicode API. They use the most efficient representation allowed by the - implementation. - -* "legacy" Unicode objects have been created through one of the deprecated - APIs (typically :c:func:`PyUnicode_FromUnicode`) and only bear the - :c:expr:`Py_UNICODE*` representation; you will have to call - :c:func:`PyUnicode_READY` on them before calling any other API. +UTF-8 representation is created on demand and cached in the Unicode object. .. note:: - The "legacy" Unicode object will be removed in Python 3.12 with deprecated - APIs. All Unicode objects will be "canonical" since then. See :pep:`623` - for more information. + The :c:type:`Py_UNICODE` representation has been removed since Python 3.12 + with deprecated APIs. + See :pep:`623` for more information. Unicode Type @@ -58,7 +44,7 @@ Python: .. c:type:: Py_UNICODE - This is a typedef of :c:expr:`wchar_t`, which is a 16-bit type or 32-bit type + This is a typedef of :c:type:`wchar_t`, which is a 16-bit type or 32-bit type depending on the platform. .. versionchanged:: 3.3 @@ -101,18 +87,12 @@ access to internal read-only data of Unicode objects: .. c:function:: int PyUnicode_READY(PyObject *o) - Ensure the string object *o* is in the "canonical" representation. This is - required before using any of the access macros described below. - - .. XXX expand on when it is not required - - Returns ``0`` on success and ``-1`` with an exception set on failure, which in - particular happens if memory allocation fails. + Returns ``0``. This API is kept only for backward compatibility. .. versionadded:: 3.3 - .. deprecated-removed:: 3.10 3.12 - This API will be removed with :c:func:`PyUnicode_FromUnicode`. + .. deprecated:: 3.10 + This API does nothing since Python 3.12. .. c:function:: Py_ssize_t PyUnicode_GET_LENGTH(PyObject *o) @@ -130,14 +110,12 @@ access to internal read-only data of Unicode objects: Return a pointer to the canonical representation cast to UCS1, UCS2 or UCS4 integer types for direct character access. No checks are performed if the canonical representation has the correct character size; use - :c:func:`PyUnicode_KIND` to select the right macro. Make sure - :c:func:`PyUnicode_READY` has been called before accessing this. + :c:func:`PyUnicode_KIND` to select the right function. .. versionadded:: 3.3 -.. c:macro:: PyUnicode_WCHAR_KIND - PyUnicode_1BYTE_KIND +.. c:macro:: PyUnicode_1BYTE_KIND PyUnicode_2BYTE_KIND PyUnicode_4BYTE_KIND @@ -145,8 +123,8 @@ access to internal read-only data of Unicode objects: .. versionadded:: 3.3 - .. deprecated-removed:: 3.10 3.12 - ``PyUnicode_WCHAR_KIND`` is deprecated. + .. versionchanged:: 3.12 + ``PyUnicode_WCHAR_KIND`` has been removed. .. c:function:: int PyUnicode_KIND(PyObject *o) @@ -155,8 +133,6 @@ access to internal read-only data of Unicode objects: bytes per character this Unicode object uses to store its data. *o* has to be a Unicode object in the "canonical" representation (not checked). - .. XXX document "0" return value? - .. versionadded:: 3.3 @@ -208,49 +184,6 @@ access to internal read-only data of Unicode objects: .. versionadded:: 3.3 -.. c:function:: Py_ssize_t PyUnicode_GET_SIZE(PyObject *o) - - Return the size of the deprecated :c:type:`Py_UNICODE` representation, in - code units (this includes surrogate pairs as 2 units). *o* has to be a - Unicode object (not checked). - - .. deprecated-removed:: 3.3 3.12 - Part of the old-style Unicode API, please migrate to using - :c:func:`PyUnicode_GET_LENGTH`. - - -.. c:function:: Py_ssize_t PyUnicode_GET_DATA_SIZE(PyObject *o) - - Return the size of the deprecated :c:type:`Py_UNICODE` representation in - bytes. *o* has to be a Unicode object (not checked). - - .. deprecated-removed:: 3.3 3.12 - Part of the old-style Unicode API, please migrate to using - :c:func:`PyUnicode_GET_LENGTH`. - - -.. c:function:: Py_UNICODE* PyUnicode_AS_UNICODE(PyObject *o) - const char* PyUnicode_AS_DATA(PyObject *o) - - Return a pointer to a :c:type:`Py_UNICODE` representation of the object. The - returned buffer is always terminated with an extra null code point. It - may also contain embedded null code points, which would cause the string - to be truncated when used in most C functions. The ``AS_DATA`` form - casts the pointer to :c:expr:`const char *`. The *o* argument has to be - a Unicode object (not checked). - - .. versionchanged:: 3.3 - This function is now inefficient -- because in many cases the - :c:type:`Py_UNICODE` representation does not exist and needs to be created - -- and can fail (return ``NULL`` with an exception set). Try to port the - code to use the new :c:func:`PyUnicode_nBYTE_DATA` macros or use - :c:func:`PyUnicode_WRITE` or :c:func:`PyUnicode_READ`. - - .. deprecated-removed:: 3.3 3.12 - Part of the old-style Unicode API, please migrate to using the - :c:func:`PyUnicode_nBYTE_DATA` family of macros. - - .. c:function:: int PyUnicode_IsIdentifier(PyObject *o) Return ``1`` if the string is a valid identifier according to the language @@ -360,40 +293,41 @@ These APIs can be used for fast direct character conversions: .. c:function:: int Py_UNICODE_TODECIMAL(Py_UCS4 ch) Return the character *ch* converted to a decimal positive integer. Return - ``-1`` if this is not possible. This macro does not raise exceptions. + ``-1`` if this is not possible. This function does not raise exceptions. .. c:function:: int Py_UNICODE_TODIGIT(Py_UCS4 ch) Return the character *ch* converted to a single digit integer. Return ``-1`` if - this is not possible. This macro does not raise exceptions. + this is not possible. This function does not raise exceptions. .. c:function:: double Py_UNICODE_TONUMERIC(Py_UCS4 ch) Return the character *ch* converted to a double. Return ``-1.0`` if this is not - possible. This macro does not raise exceptions. + possible. This function does not raise exceptions. These APIs can be used to work with surrogates: -.. c:macro:: Py_UNICODE_IS_SURROGATE(ch) +.. c:function:: int Py_UNICODE_IS_SURROGATE(Py_UCS4 ch) Check if *ch* is a surrogate (``0xD800 <= ch <= 0xDFFF``). -.. c:macro:: Py_UNICODE_IS_HIGH_SURROGATE(ch) +.. c:function:: int Py_UNICODE_IS_HIGH_SURROGATE(Py_UCS4 ch) Check if *ch* is a high surrogate (``0xD800 <= ch <= 0xDBFF``). -.. c:macro:: Py_UNICODE_IS_LOW_SURROGATE(ch) +.. c:function:: int Py_UNICODE_IS_LOW_SURROGATE(Py_UCS4 ch) Check if *ch* is a low surrogate (``0xDC00 <= ch <= 0xDFFF``). -.. c:macro:: Py_UNICODE_JOIN_SURROGATES(high, low) +.. c:function:: Py_UCS4 Py_UNICODE_JOIN_SURROGATES(Py_UCS4 high, Py_UCS4 low) - Join two surrogate characters and return a single Py_UCS4 value. + Join two surrogate characters and return a single :c:type:`Py_UCS4` value. *high* and *low* are respectively the leading and trailing surrogates in a - surrogate pair. + surrogate pair. *high* must be in the range [0xD800; 0xDBFF] and *low* must + be in the range [0xDC00; 0xDFFF]. Creating and accessing Unicode strings @@ -435,12 +369,17 @@ APIs: Create a Unicode object from the char buffer *u*. The bytes will be interpreted as being UTF-8 encoded. The buffer is copied into the new - object. If the buffer is not ``NULL``, the return value might be a shared - object, i.e. modification of the data is not allowed. + object. + The return value might be a shared object, i.e. modification of the data is + not allowed. - If *u* is ``NULL``, this function behaves like :c:func:`PyUnicode_FromUnicode` - with the buffer set to ``NULL``. This usage is deprecated in favor of - :c:func:`PyUnicode_New`, and will be removed in Python 3.12. + This function raises :exc:`SystemError` when: + + * *size* < 0, + * *u* is ``NULL`` and *size* > 0 + + .. versionchanged:: 3.12 + *u* == ``NULL`` with *size* > 0 is not allowed anymore. .. c:function:: PyObject *PyUnicode_FromString(const char *u) @@ -455,105 +394,149 @@ APIs: arguments, calculate the size of the resulting Python Unicode string and return a string with the values formatted into it. The variable arguments must be C types and must correspond exactly to the format characters in the *format* - ASCII-encoded string. The following format characters are allowed: - - .. % This should be exactly the same as the table in PyErr_Format. - .. % The descriptions for %zd and %zu are wrong, but the truth is complicated - .. % because not all compilers support the %z width modifier -- we fake it - .. % when necessary via interpolating PY_FORMAT_SIZE_T. - .. % Similar comments apply to the %ll width modifier and - - .. tabularcolumns:: |l|l|L| - - +-------------------+---------------------+----------------------------------+ - | Format Characters | Type | Comment | - +===================+=====================+==================================+ - | :attr:`%%` | *n/a* | The literal % character. | - +-------------------+---------------------+----------------------------------+ - | :attr:`%c` | int | A single character, | - | | | represented as a C int. | - +-------------------+---------------------+----------------------------------+ - | :attr:`%d` | int | Equivalent to | - | | | ``printf("%d")``. [1]_ | - +-------------------+---------------------+----------------------------------+ - | :attr:`%u` | unsigned int | Equivalent to | - | | | ``printf("%u")``. [1]_ | - +-------------------+---------------------+----------------------------------+ - | :attr:`%ld` | long | Equivalent to | - | | | ``printf("%ld")``. [1]_ | - +-------------------+---------------------+----------------------------------+ - | :attr:`%li` | long | Equivalent to | - | | | ``printf("%li")``. [1]_ | - +-------------------+---------------------+----------------------------------+ - | :attr:`%lu` | unsigned long | Equivalent to | - | | | ``printf("%lu")``. [1]_ | - +-------------------+---------------------+----------------------------------+ - | :attr:`%lld` | long long | Equivalent to | - | | | ``printf("%lld")``. [1]_ | - +-------------------+---------------------+----------------------------------+ - | :attr:`%lli` | long long | Equivalent to | - | | | ``printf("%lli")``. [1]_ | - +-------------------+---------------------+----------------------------------+ - | :attr:`%llu` | unsigned long long | Equivalent to | - | | | ``printf("%llu")``. [1]_ | - +-------------------+---------------------+----------------------------------+ - | :attr:`%zd` | :c:type:`\ | Equivalent to | - | | Py_ssize_t` | ``printf("%zd")``. [1]_ | - +-------------------+---------------------+----------------------------------+ - | :attr:`%zi` | :c:type:`\ | Equivalent to | - | | Py_ssize_t` | ``printf("%zi")``. [1]_ | - +-------------------+---------------------+----------------------------------+ - | :attr:`%zu` | size_t | Equivalent to | - | | | ``printf("%zu")``. [1]_ | - +-------------------+---------------------+----------------------------------+ - | :attr:`%i` | int | Equivalent to | - | | | ``printf("%i")``. [1]_ | - +-------------------+---------------------+----------------------------------+ - | :attr:`%x` | int | Equivalent to | - | | | ``printf("%x")``. [1]_ | - +-------------------+---------------------+----------------------------------+ - | :attr:`%s` | const char\* | A null-terminated C character | - | | | array. | - +-------------------+---------------------+----------------------------------+ - | :attr:`%p` | const void\* | The hex representation of a C | - | | | pointer. Mostly equivalent to | - | | | ``printf("%p")`` except that | - | | | it is guaranteed to start with | - | | | the literal ``0x`` regardless | - | | | of what the platform's | - | | | ``printf`` yields. | - +-------------------+---------------------+----------------------------------+ - | :attr:`%A` | PyObject\* | The result of calling | - | | | :func:`ascii`. | - +-------------------+---------------------+----------------------------------+ - | :attr:`%U` | PyObject\* | A Unicode object. | - +-------------------+---------------------+----------------------------------+ - | :attr:`%V` | PyObject\*, | A Unicode object (which may be | - | | const char\* | ``NULL``) and a null-terminated | - | | | C character array as a second | - | | | parameter (which will be used, | - | | | if the first parameter is | - | | | ``NULL``). | - +-------------------+---------------------+----------------------------------+ - | :attr:`%S` | PyObject\* | The result of calling | - | | | :c:func:`PyObject_Str`. | - +-------------------+---------------------+----------------------------------+ - | :attr:`%R` | PyObject\* | The result of calling | - | | | :c:func:`PyObject_Repr`. | - +-------------------+---------------------+----------------------------------+ - - An unrecognized format character causes all the rest of the format string to be - copied as-is to the result string, and any extra arguments discarded. + ASCII-encoded string. + + A conversion specifier contains two or more characters and has the following + components, which must occur in this order: + + #. The ``'%'`` character, which marks the start of the specifier. + + #. Conversion flags (optional), which affect the result of some conversion + types. + + #. Minimum field width (optional). + If specified as an ``'*'`` (asterisk), the actual width is given in the + next argument, which must be of type :c:expr:`int`, and the object to + convert comes after the minimum field width and optional precision. + + #. Precision (optional), given as a ``'.'`` (dot) followed by the precision. + If specified as ``'*'`` (an asterisk), the actual precision is given in + the next argument, which must be of type :c:expr:`int`, and the value to + convert comes after the precision. + + #. Length modifier (optional). + + #. Conversion type. + + The conversion flag characters are: + + .. tabularcolumns:: |l|L| + + +-------+-------------------------------------------------------------+ + | Flag | Meaning | + +=======+=============================================================+ + | ``0`` | The conversion will be zero padded for numeric values. | + +-------+-------------------------------------------------------------+ + | ``-`` | The converted value is left adjusted (overrides the ``0`` | + | | flag if both are given). | + +-------+-------------------------------------------------------------+ + + The length modifiers for following integer conversions (``d``, ``i``, + ``o``, ``u``, ``x``, or ``X``) specify the type of the argument + (:c:expr:`int` by default): + + .. tabularcolumns:: |l|L| + + +----------+-----------------------------------------------------+ + | Modifier | Types | + +==========+=====================================================+ + | ``l`` | :c:expr:`long` or :c:expr:`unsigned long` | + +----------+-----------------------------------------------------+ + | ``ll`` | :c:expr:`long long` or :c:expr:`unsigned long long` | + +----------+-----------------------------------------------------+ + | ``j`` | :c:type:`intmax_t` or :c:type:`uintmax_t` | + +----------+-----------------------------------------------------+ + | ``z`` | :c:type:`size_t` or :c:type:`ssize_t` | + +----------+-----------------------------------------------------+ + | ``t`` | :c:type:`ptrdiff_t` | + +----------+-----------------------------------------------------+ + + The length modifier ``l`` for following conversions ``s`` or ``V`` specify + that the type of the argument is :c:expr:`const wchar_t*`. + + The conversion specifiers are: + + .. list-table:: + :widths: auto + :header-rows: 1 + + * - Conversion Specifier + - Type + - Comment + + * - ``%`` + - *n/a* + - The literal ``%`` character. + + * - ``d``, ``i`` + - Specified by the length modifier + - The decimal representation of a signed C integer. + + * - ``u`` + - Specified by the length modifier + - The decimal representation of an unsigned C integer. + + * - ``o`` + - Specified by the length modifier + - The octal representation of an unsigned C integer. + + * - ``x`` + - Specified by the length modifier + - The hexadecimal representation of an unsigned C integer (lowercase). + + * - ``X`` + - Specified by the length modifier + - The hexadecimal representation of an unsigned C integer (uppercase). + + * - ``c`` + - :c:expr:`int` + - A single character. + + * - ``s`` + - :c:expr:`const char*` or :c:expr:`const wchar_t*` + - A null-terminated C character array. + + * - ``p`` + - :c:expr:`const void*` + - The hex representation of a C pointer. + Mostly equivalent to ``printf("%p")`` except that it is guaranteed to + start with the literal ``0x`` regardless of what the platform's + ``printf`` yields. + + * - ``A`` + - :c:expr:`PyObject*` + - The result of calling :func:`ascii`. + + * - ``U`` + - :c:expr:`PyObject*` + - A Unicode object. + + * - ``V`` + - :c:expr:`PyObject*`, :c:expr:`const char*` or :c:expr:`const wchar_t*` + - A Unicode object (which may be ``NULL``) and a null-terminated + C character array as a second parameter (which will be used, + if the first parameter is ``NULL``). + + * - ``S`` + - :c:expr:`PyObject*` + - The result of calling :c:func:`PyObject_Str`. + + * - ``R`` + - :c:expr:`PyObject*` + - The result of calling :c:func:`PyObject_Repr`. .. note:: The width formatter unit is number of characters rather than bytes. - The precision formatter unit is number of bytes for ``"%s"`` and + The precision formatter unit is number of bytes or :c:type:`wchar_t` + items (if the length modifier ``l`` is used) for ``"%s"`` and ``"%V"`` (if the ``PyObject*`` argument is ``NULL``), and a number of characters for ``"%A"``, ``"%U"``, ``"%S"``, ``"%R"`` and ``"%V"`` (if the ``PyObject*`` argument is not ``NULL``). - .. [1] For integer specifiers (d, u, ld, li, lu, lld, lli, llu, zd, zi, - zu, i, x): the 0-conversion flag has effect even when a precision is given. + .. note:: + Unlike to C :c:func:`printf` the ``0`` flag has effect even when + a precision is given for integer conversions (``d``, ``i``, ``u``, ``o``, + ``x``, or ``X``). .. versionchanged:: 3.2 Support for ``"%lld"`` and ``"%llu"`` added. @@ -565,6 +548,18 @@ APIs: Support width and precision formatter for ``"%s"``, ``"%A"``, ``"%U"``, ``"%V"``, ``"%S"``, ``"%R"`` added. + .. versionchanged:: 3.12 + Support for conversion specifiers ``o`` and ``X``. + Support for length modifiers ``j`` and ``t``. + Length modifiers are now applied to all integer conversions. + Length modifier ``l`` is now applied to conversion specifiers ``s`` and ``V``. + Support for variable width and precision ``*``. + Support for flag ``-``. + + An unrecognized format character now sets a :exc:`SystemError`. + In previous versions it caused all the rest of the format string to be + copied as-is to the result string, and any extra arguments discarded. + .. c:function:: PyObject* PyUnicode_FromFormatV(const char *format, va_list vargs) @@ -572,6 +567,15 @@ APIs: arguments. +.. c:function:: PyObject* PyUnicode_FromObject(PyObject *obj) + + Copy an instance of a Unicode subtype to a new true Unicode object if + necessary. If *obj* is already a true Unicode object (not a subtype), + return a new :term:`strong reference` to the object. + + Objects other than Unicode or its subtypes will cause a :exc:`TypeError`. + + .. c:function:: PyObject* PyUnicode_FromEncodedObject(PyObject *obj, \ const char *encoding, const char *errors) @@ -604,7 +608,7 @@ APIs: Py_ssize_t how_many) Copy characters from one Unicode object into another. This function performs - character conversion when necessary and falls back to :c:func:`memcpy` if + character conversion when necessary and falls back to :c:func:`!memcpy` if possible. Returns ``-1`` and sets an exception on error, otherwise returns the number of copied characters. @@ -679,88 +683,6 @@ APIs: .. versionadded:: 3.3 -Deprecated Py_UNICODE APIs -"""""""""""""""""""""""""" - -.. deprecated-removed:: 3.3 3.12 - -These API functions are deprecated with the implementation of :pep:`393`. -Extension modules can continue using them, as they will not be removed in Python -3.x, but need to be aware that their use can now cause performance and memory hits. - - -.. c:function:: PyObject* PyUnicode_FromUnicode(const Py_UNICODE *u, Py_ssize_t size) - - Create a Unicode object from the Py_UNICODE buffer *u* of the given size. *u* - may be ``NULL`` which causes the contents to be undefined. It is the user's - responsibility to fill in the needed data. The buffer is copied into the new - object. - - If the buffer is not ``NULL``, the return value might be a shared object. - Therefore, modification of the resulting Unicode object is only allowed when - *u* is ``NULL``. - - If the buffer is ``NULL``, :c:func:`PyUnicode_READY` must be called once the - string content has been filled before using any of the access macros such as - :c:func:`PyUnicode_KIND`. - - .. deprecated-removed:: 3.3 3.12 - Part of the old-style Unicode API, please migrate to using - :c:func:`PyUnicode_FromKindAndData`, :c:func:`PyUnicode_FromWideChar`, or - :c:func:`PyUnicode_New`. - - -.. c:function:: Py_UNICODE* PyUnicode_AsUnicode(PyObject *unicode) - - Return a read-only pointer to the Unicode object's internal - :c:type:`Py_UNICODE` buffer, or ``NULL`` on error. This will create the - :c:expr:`Py_UNICODE*` representation of the object if it is not yet - available. The buffer is always terminated with an extra null code point. - Note that the resulting :c:type:`Py_UNICODE` string may also contain - embedded null code points, which would cause the string to be truncated when - used in most C functions. - - .. deprecated-removed:: 3.3 3.12 - Part of the old-style Unicode API, please migrate to using - :c:func:`PyUnicode_AsUCS4`, :c:func:`PyUnicode_AsWideChar`, - :c:func:`PyUnicode_ReadChar` or similar new APIs. - - -.. c:function:: Py_UNICODE* PyUnicode_AsUnicodeAndSize(PyObject *unicode, Py_ssize_t *size) - - Like :c:func:`PyUnicode_AsUnicode`, but also saves the :c:func:`Py_UNICODE` - array length (excluding the extra null terminator) in *size*. - Note that the resulting :c:expr:`Py_UNICODE*` string - may contain embedded null code points, which would cause the string to be - truncated when used in most C functions. - - .. versionadded:: 3.3 - - .. deprecated-removed:: 3.3 3.12 - Part of the old-style Unicode API, please migrate to using - :c:func:`PyUnicode_AsUCS4`, :c:func:`PyUnicode_AsWideChar`, - :c:func:`PyUnicode_ReadChar` or similar new APIs. - - -.. c:function:: Py_ssize_t PyUnicode_GetSize(PyObject *unicode) - - Return the size of the deprecated :c:type:`Py_UNICODE` representation, in - code units (this includes surrogate pairs as 2 units). - - .. deprecated-removed:: 3.3 3.12 - Part of the old-style Unicode API, please migrate to using - :c:func:`PyUnicode_GET_LENGTH`. - - -.. c:function:: PyObject* PyUnicode_FromObject(PyObject *obj) - - Copy an instance of a Unicode subtype to a new true Unicode object if - necessary. If *obj* is already a true Unicode object (not a subtype), - return the reference with incremented refcount. - - Objects other than Unicode or its subtypes will cause a :exc:`TypeError`. - - Locale Encoding """"""""""""""" @@ -779,8 +701,7 @@ system. cannot contain embedded null characters. Use :c:func:`PyUnicode_DecodeFSDefaultAndSize` to decode a string from - :c:data:`Py_FileSystemDefaultEncoding` (the locale encoding read at - Python startup). + the :term:`filesystem encoding and error handler`. This function ignores the :ref:`Python UTF-8 Mode `. @@ -800,7 +721,7 @@ system. .. c:function:: PyObject* PyUnicode_DecodeLocale(const char *str, const char *errors) Similar to :c:func:`PyUnicode_DecodeLocaleAndSize`, but compute the string - length using :c:func:`strlen`. + length using :c:func:`!strlen`. .. versionadded:: 3.3 @@ -814,9 +735,8 @@ system. *errors* is ``NULL``. Return a :class:`bytes` object. *unicode* cannot contain embedded null characters. - Use :c:func:`PyUnicode_EncodeFSDefault` to encode a string to - :c:data:`Py_FileSystemDefaultEncoding` (the locale encoding read at - Python startup). + Use :c:func:`PyUnicode_EncodeFSDefault` to encode a string to the + :term:`filesystem encoding and error handler`. This function ignores the :ref:`Python UTF-8 Mode `. @@ -837,12 +757,12 @@ system. File System Encoding """""""""""""""""""" -To encode and decode file names and other environment strings, -:c:data:`Py_FileSystemDefaultEncoding` should be used as the encoding, and -:c:data:`Py_FileSystemDefaultEncodeErrors` should be used as the error handler -(:pep:`383` and :pep:`529`). To encode file names to :class:`bytes` during -argument parsing, the ``"O&"`` converter should be used, passing -:c:func:`PyUnicode_FSConverter` as the conversion function: +Functions encoding to and decoding from the :term:`filesystem encoding and +error handler` (:pep:`383` and :pep:`529`). + +To encode file names to :class:`bytes` during argument parsing, the ``"O&"`` +converter should be used, passing :c:func:`PyUnicode_FSConverter` as the +conversion function: .. c:function:: int PyUnicode_FSConverter(PyObject* obj, void* result) @@ -879,12 +799,7 @@ conversion function: Decode a string from the :term:`filesystem encoding and error handler`. - If :c:data:`Py_FileSystemDefaultEncoding` is not set, fall back to the - locale encoding. - - :c:data:`Py_FileSystemDefaultEncoding` is initialized at startup from the - locale encoding and cannot be modified later. If you need to decode a string - from the current locale encoding, use + If you need to decode a string from the current locale encoding, use :c:func:`PyUnicode_DecodeLocaleAndSize`. .. seealso:: @@ -892,7 +807,8 @@ conversion function: The :c:func:`Py_DecodeLocale` function. .. versionchanged:: 3.6 - Use :c:data:`Py_FileSystemDefaultEncodeErrors` error handler. + The :term:`filesystem error handler ` is now used. .. c:function:: PyObject* PyUnicode_DecodeFSDefault(const char *s) @@ -900,28 +816,22 @@ conversion function: Decode a null-terminated string from the :term:`filesystem encoding and error handler`. - If :c:data:`Py_FileSystemDefaultEncoding` is not set, fall back to the - locale encoding. - - Use :c:func:`PyUnicode_DecodeFSDefaultAndSize` if you know the string length. + If the string length is known, use + :c:func:`PyUnicode_DecodeFSDefaultAndSize`. .. versionchanged:: 3.6 - Use :c:data:`Py_FileSystemDefaultEncodeErrors` error handler. + The :term:`filesystem error handler ` is now used. .. c:function:: PyObject* PyUnicode_EncodeFSDefault(PyObject *unicode) - Encode a Unicode object to :c:data:`Py_FileSystemDefaultEncoding` with the - :c:data:`Py_FileSystemDefaultEncodeErrors` error handler, and return - :class:`bytes`. Note that the resulting :class:`bytes` object may contain - null bytes. - - If :c:data:`Py_FileSystemDefaultEncoding` is not set, fall back to the - locale encoding. + Encode a Unicode object to the :term:`filesystem encoding and error + handler`, and return :class:`bytes`. Note that the resulting :class:`bytes` + object can contain null bytes. - :c:data:`Py_FileSystemDefaultEncoding` is initialized at startup from the - locale encoding and cannot be modified later. If you need to encode a string - to the current locale encoding, use :c:func:`PyUnicode_EncodeLocale`. + If you need to encode a string to the current locale encoding, use + :c:func:`PyUnicode_EncodeLocale`. .. seealso:: @@ -930,16 +840,17 @@ conversion function: .. versionadded:: 3.2 .. versionchanged:: 3.6 - Use :c:data:`Py_FileSystemDefaultEncodeErrors` error handler. + The :term:`filesystem error handler ` is now used. wchar_t Support """"""""""""""" -:c:expr:`wchar_t` support for platforms which support it: +:c:type:`wchar_t` support for platforms which support it: .. c:function:: PyObject* PyUnicode_FromWideChar(const wchar_t *w, Py_ssize_t size) - Create a Unicode object from the :c:expr:`wchar_t` buffer *w* of the given *size*. + Create a Unicode object from the :c:type:`wchar_t` buffer *w* of the given *size*. Passing ``-1`` as the *size* indicates that the function must itself compute the length, using wcslen. Return ``NULL`` on failure. @@ -947,9 +858,9 @@ wchar_t Support .. c:function:: Py_ssize_t PyUnicode_AsWideChar(PyObject *unicode, wchar_t *w, Py_ssize_t size) - Copy the Unicode object contents into the :c:expr:`wchar_t` buffer *w*. At most - *size* :c:expr:`wchar_t` characters are copied (excluding a possibly trailing - null termination character). Return the number of :c:expr:`wchar_t` characters + Copy the Unicode object contents into the :c:type:`wchar_t` buffer *w*. At most + *size* :c:type:`wchar_t` characters are copied (excluding a possibly trailing + null termination character). Return the number of :c:type:`wchar_t` characters copied or ``-1`` in case of an error. Note that the resulting :c:expr:`wchar_t*` string may or may not be null-terminated. It is the responsibility of the caller to make sure that the :c:expr:`wchar_t*` string is null-terminated in case this is @@ -963,12 +874,12 @@ wchar_t Support Convert the Unicode object to a wide character string. The output string always ends with a null character. If *size* is not ``NULL``, write the number of wide characters (excluding the trailing null termination character) into - *\*size*. Note that the resulting :c:expr:`wchar_t` string might contain + *\*size*. Note that the resulting :c:type:`wchar_t` string might contain null characters, which would cause the string to be truncated when used with most C functions. If *size* is ``NULL`` and the :c:expr:`wchar_t*` string contains null characters a :exc:`ValueError` is raised. - Returns a buffer allocated by :c:func:`PyMem_Alloc` (use + Returns a buffer allocated by :c:macro:`PyMem_New` (use :c:func:`PyMem_Free` to free it) on success. On error, returns ``NULL`` and *\*size* is undefined. Raises a :exc:`MemoryError` if memory allocation is failed. @@ -995,10 +906,7 @@ constructor. Setting encoding to ``NULL`` causes the default encoding to be used which is UTF-8. The file system calls should use :c:func:`PyUnicode_FSConverter` for encoding file names. This uses the -variable :c:data:`Py_FileSystemDefaultEncoding` internally. This -variable should be treated as read-only: on some systems, it will be a -pointer to a static string, on others, it will change at run-time -(such as when the application invokes setlocale). +:term:`filesystem encoding and error handler` internally. Error handling is set by errors which may also be set to ``NULL`` meaning to use the default handling defined for the codec. Default error handling for all @@ -1084,7 +992,7 @@ These are the UTF-8 codec APIs: The return type is now ``const char *`` rather of ``char *``. .. versionchanged:: 3.10 - This function is a part of the :ref:`limited API `. + This function is a part of the :ref:`limited API `. .. c:function:: const char* PyUnicode_AsUTF8(PyObject *unicode) @@ -1304,9 +1212,9 @@ Character Map Codecs This codec is special in that it can be used to implement many different codecs (and this is in fact what was done to obtain most of the standard codecs -included in the :mod:`encodings` package). The codec uses mappings to encode and +included in the :mod:`!encodings` package). The codec uses mappings to encode and decode characters. The mapping objects provided must support the -:meth:`__getitem__` mapping interface; dictionaries and sequences work well. +:meth:`~object.__getitem__` mapping interface; dictionaries and sequences work well. These are the mapping codec APIs: @@ -1349,7 +1257,7 @@ The following codec API is special in that maps Unicode to Unicode. The mapping table must map Unicode ordinal integers to Unicode ordinal integers or ``None`` (causing deletion of the character). - Mapping tables need only provide the :meth:`__getitem__` interface; dictionaries + Mapping tables need only provide the :meth:`~object.__getitem__` interface; dictionaries and sequences work well. Unmapped character ordinals (ones which cause a :exc:`LookupError`) are left untouched and are copied as-is. @@ -1391,7 +1299,7 @@ the user settings on the machine running the codec. Encode the Unicode object using the specified code page and return a Python bytes object. Return ``NULL`` if an exception was raised by the codec. Use - :c:data:`CP_ACP` code page to get the MBCS encoder. + :c:macro:`!CP_ACP` code page to get the MBCS encoder. .. versionadded:: 3.3 @@ -1510,11 +1418,11 @@ They all return ``NULL`` or ``-1`` if an exception occurs. Rich compare two Unicode strings and return one of the following: * ``NULL`` in case an exception was raised - * :const:`Py_True` or :const:`Py_False` for successful comparisons - * :const:`Py_NotImplemented` in case the type combination is unknown + * :c:data:`Py_True` or :c:data:`Py_False` for successful comparisons + * :c:data:`Py_NotImplemented` in case the type combination is unknown - Possible values for *op* are :const:`Py_GT`, :const:`Py_GE`, :const:`Py_EQ`, - :const:`Py_NE`, :const:`Py_LT`, and :const:`Py_LE`. + Possible values for *op* are :c:macro:`Py_GT`, :c:macro:`Py_GE`, :c:macro:`Py_EQ`, + :c:macro:`Py_NE`, :c:macro:`Py_LT`, and :c:macro:`Py_LE`. .. c:function:: PyObject* PyUnicode_Format(PyObject *format, PyObject *args) @@ -1537,11 +1445,11 @@ They all return ``NULL`` or ``-1`` if an exception occurs. Intern the argument *\*string* in place. The argument must be the address of a pointer variable pointing to a Python Unicode string object. If there is an existing interned string that is the same as *\*string*, it sets *\*string* to - it (decrementing the reference count of the old string object and incrementing - the reference count of the interned string object), otherwise it leaves - *\*string* alone and interns it (incrementing its reference count). - (Clarification: even though there is a lot of talk about reference counts, think - of this function as reference-count-neutral; you own the object after the call + it (releasing the reference to the old string object and creating a new + :term:`strong reference` to the interned string object), otherwise it leaves + *\*string* alone and interns it (creating a new :term:`strong reference`). + (Clarification: even though there is a lot of talk about references, think + of this function as reference-neutral; you own the object after the call if and only if you owned it before the call.) diff --git a/Doc/c-api/utilities.rst b/Doc/c-api/utilities.rst index a805b564..ccbf14e1 100644 --- a/Doc/c-api/utilities.rst +++ b/Doc/c-api/utilities.rst @@ -19,3 +19,4 @@ and parsing function arguments and constructing Python values from C values. conversion.rst reflection.rst codec.rst + perfmaps.rst diff --git a/Doc/c-api/veryhigh.rst b/Doc/c-api/veryhigh.rst index bfb14ac9..324518c0 100644 --- a/Doc/c-api/veryhigh.rst +++ b/Doc/c-api/veryhigh.rst @@ -12,12 +12,12 @@ file or a buffer, but they will not let you interact in a more detailed way with the interpreter. Several of these functions accept a start symbol from the grammar as a -parameter. The available start symbols are :const:`Py_eval_input`, -:const:`Py_file_input`, and :const:`Py_single_input`. These are described +parameter. The available start symbols are :c:data:`Py_eval_input`, +:c:data:`Py_file_input`, and :c:data:`Py_single_input`. These are described following the functions which accept them as parameters. Note also that several of these functions take :c:expr:`FILE*` parameters. One -particular issue which needs to be handled carefully is that the :c:expr:`FILE` +particular issue which needs to be handled carefully is that the :c:type:`FILE` structure for different C libraries can be different and incompatible. Under Windows (at least), it is possible for dynamically linked extensions to actually use different libraries, so care should be taken that :c:expr:`FILE*` parameters @@ -39,7 +39,7 @@ the same library that the Python runtime is using. Note that if an otherwise unhandled :exc:`SystemExit` is raised, this function will not return ``1``, but exit the process, as long as - ``Py_InspectFlag`` is not set. + :c:member:`PyConfig.inspect` is zero. .. c:function:: int Py_BytesMain(int argc, char **argv) @@ -95,7 +95,7 @@ the same library that the Python runtime is using. Note that if an otherwise unhandled :exc:`SystemExit` is raised, this function will not return ``-1``, but exit the process, as long as - ``Py_InspectFlag`` is not set. + :c:member:`PyConfig.inspect` is zero. .. c:function:: int PyRun_SimpleFile(FILE *fp, const char *filename) @@ -167,6 +167,10 @@ the same library that the Python runtime is using. event loops, as done in the :file:`Modules/_tkinter.c` in the Python source code. + .. versionchanged:: 3.12 + This function is only called from the + :ref:`main interpreter `. + .. c:var:: char* (*PyOS_ReadlineFunctionPointer)(FILE *, FILE *, const char *) @@ -187,6 +191,10 @@ the same library that the Python runtime is using. :c:func:`PyMem_RawRealloc`, instead of being allocated by :c:func:`PyMem_Malloc` or :c:func:`PyMem_Realloc`. + .. versionchanged:: 3.12 + This function is only called from the + :ref:`main interpreter `. + .. c:function:: PyObject* PyRun_String(const char *str, int start, PyObject *globals, PyObject *locals) This is a simplified interface to :c:func:`PyRun_StringFlags` below, leaving @@ -248,8 +256,8 @@ the same library that the Python runtime is using. Parse and compile the Python source code in *str*, returning the resulting code object. The start token is given by *start*; this can be used to constrain the - code which can be compiled and should be :const:`Py_eval_input`, - :const:`Py_file_input`, or :const:`Py_single_input`. The filename specified by + code which can be compiled and should be :c:data:`Py_eval_input`, + :c:data:`Py_file_input`, or :c:data:`Py_single_input`. The filename specified by *filename* is used to construct the code object and may appear in tracebacks or :exc:`SyntaxError` exception messages. This returns ``NULL`` if the code cannot be parsed or compiled. @@ -345,7 +353,7 @@ the same library that the Python runtime is using. executed, it is passed as ``PyCompilerFlags *flags``. In this case, ``from __future__ import`` can modify *flags*. - Whenever ``PyCompilerFlags *flags`` is ``NULL``, :attr:`cf_flags` is treated as + Whenever ``PyCompilerFlags *flags`` is ``NULL``, :c:member:`~PyCompilerFlags.cf_flags` is treated as equal to ``0``, and any modification due to ``from __future__ import`` is discarded. @@ -359,7 +367,7 @@ the same library that the Python runtime is using. initialized to ``PY_MINOR_VERSION``. The field is ignored by default, it is used if and only if - ``PyCF_ONLY_AST`` flag is set in *cf_flags*. + ``PyCF_ONLY_AST`` flag is set in :c:member:`~PyCompilerFlags.cf_flags`. .. versionchanged:: 3.8 Added *cf_feature_version* field. diff --git a/Doc/c-api/weakref.rst b/Doc/c-api/weakref.rst index ace743ba..f4650760 100644 --- a/Doc/c-api/weakref.rst +++ b/Doc/c-api/weakref.rst @@ -11,18 +11,18 @@ simple reference object, and the second acts as a proxy for the original object as much as it can. -.. c:function:: int PyWeakref_Check(ob) +.. c:function:: int PyWeakref_Check(PyObject *ob) Return true if *ob* is either a reference or proxy object. This function always succeeds. -.. c:function:: int PyWeakref_CheckRef(ob) +.. c:function:: int PyWeakref_CheckRef(PyObject *ob) Return true if *ob* is a reference object. This function always succeeds. -.. c:function:: int PyWeakref_CheckProxy(ob) +.. c:function:: int PyWeakref_CheckProxy(PyObject *ob) Return true if *ob* is a proxy object. This function always succeeds. @@ -54,7 +54,7 @@ as much as it can. .. c:function:: PyObject* PyWeakref_GetObject(PyObject *ref) Return the referenced object from a weak reference, *ref*. If the referent is - no longer live, returns :const:`Py_None`. + no longer live, returns ``Py_None``. .. note:: @@ -67,3 +67,13 @@ as much as it can. .. c:function:: PyObject* PyWeakref_GET_OBJECT(PyObject *ref) Similar to :c:func:`PyWeakref_GetObject`, but does no error checking. + + +.. c:function:: void PyObject_ClearWeakRefs(PyObject *object) + + This function is called by the :c:member:`~PyTypeObject.tp_dealloc` handler + to clear weak references. + + This iterates through the weak references for *object* and calls callbacks + for those references which have one. It returns when all callbacks have + been attempted. diff --git a/Doc/conf.py b/Doc/conf.py index 98b076c0..9f01bd89 100644 --- a/Doc/conf.py +++ b/Doc/conf.py @@ -38,6 +38,11 @@ try: import _tkinter except ImportError: _tkinter = None +# Treat warnings as errors, done here to prevent warnings in Sphinx code from +# causing spurious test failures. +import warnings +warnings.simplefilter('error') +del warnings ''' manpages_url = 'https://manpages.debian.org/{path}' @@ -61,14 +66,183 @@ today_fmt = '%B %d, %Y' highlight_language = 'python3' # Minimum version of sphinx required -needs_sphinx = '3.2' +needs_sphinx = '4.2' +# Ignore any .rst files in the includes/ directory; +# they're embedded in pages but not rendered individually. # Ignore any .rst files in the venv/ directory. -exclude_patterns = ['venv/*', 'README.rst'] +exclude_patterns = ['includes/*.rst', 'venv/*', 'README.rst'] venvdir = os.getenv('VENVDIR') if venvdir is not None: exclude_patterns.append(venvdir + '/*') +nitpick_ignore = [ + # Standard C functions + ('c:func', 'calloc'), + ('c:func', 'dlopen'), + ('c:func', 'exec'), + ('c:func', 'fcntl'), + ('c:func', 'fork'), + ('c:func', 'free'), + ('c:func', 'gmtime'), + ('c:func', 'localtime'), + ('c:func', 'main'), + ('c:func', 'malloc'), + ('c:func', 'printf'), + ('c:func', 'realloc'), + ('c:func', 'snprintf'), + ('c:func', 'sprintf'), + ('c:func', 'stat'), + ('c:func', 'system'), + ('c:func', 'time'), + ('c:func', 'vsnprintf'), + # Standard C types + ('c:type', 'FILE'), + ('c:type', 'int64_t'), + ('c:type', 'intmax_t'), + ('c:type', 'off_t'), + ('c:type', 'ptrdiff_t'), + ('c:type', 'siginfo_t'), + ('c:type', 'size_t'), + ('c:type', 'ssize_t'), + ('c:type', 'time_t'), + ('c:type', 'uint64_t'), + ('c:type', 'uintmax_t'), + ('c:type', 'uintptr_t'), + ('c:type', 'va_list'), + ('c:type', 'wchar_t'), + ('c:type', '__int64'), + ('c:type', 'unsigned __int64'), + # Standard C structures + ('c:struct', 'in6_addr'), + ('c:struct', 'in_addr'), + ('c:struct', 'stat'), + ('c:struct', 'statvfs'), + # Standard C macros + ('c:macro', 'LLONG_MAX'), + ('c:macro', 'LLONG_MIN'), + ('c:macro', 'LONG_MAX'), + ('c:macro', 'LONG_MIN'), + # Standard C variables + ('c:data', 'errno'), + # Standard environment variables + ('envvar', 'BROWSER'), + ('envvar', 'COLUMNS'), + ('envvar', 'COMSPEC'), + ('envvar', 'DISPLAY'), + ('envvar', 'HOME'), + ('envvar', 'HOMEDRIVE'), + ('envvar', 'HOMEPATH'), + ('envvar', 'IDLESTARTUP'), + ('envvar', 'LANG'), + ('envvar', 'LANGUAGE'), + ('envvar', 'LC_ALL'), + ('envvar', 'LC_CTYPE'), + ('envvar', 'LC_COLLATE'), + ('envvar', 'LC_MESSAGES'), + ('envvar', 'LC_MONETARY'), + ('envvar', 'LC_NUMERIC'), + ('envvar', 'LC_TIME'), + ('envvar', 'LINES'), + ('envvar', 'LOGNAME'), + ('envvar', 'PAGER'), + ('envvar', 'PATH'), + ('envvar', 'PATHEXT'), + ('envvar', 'SOURCE_DATE_EPOCH'), + ('envvar', 'TEMP'), + ('envvar', 'TERM'), + ('envvar', 'TMP'), + ('envvar', 'TMPDIR'), + ('envvar', 'TZ'), + ('envvar', 'USER'), + ('envvar', 'USERNAME'), + ('envvar', 'USERPROFILE'), +] + +# Temporary undocumented names. +# In future this list must be empty. +nitpick_ignore += [ + # C API: Standard Python exception classes + ('c:data', 'PyExc_ArithmeticError'), + ('c:data', 'PyExc_AssertionError'), + ('c:data', 'PyExc_AttributeError'), + ('c:data', 'PyExc_BaseException'), + ('c:data', 'PyExc_BlockingIOError'), + ('c:data', 'PyExc_BrokenPipeError'), + ('c:data', 'PyExc_BufferError'), + ('c:data', 'PyExc_ChildProcessError'), + ('c:data', 'PyExc_ConnectionAbortedError'), + ('c:data', 'PyExc_ConnectionError'), + ('c:data', 'PyExc_ConnectionRefusedError'), + ('c:data', 'PyExc_ConnectionResetError'), + ('c:data', 'PyExc_EOFError'), + ('c:data', 'PyExc_Exception'), + ('c:data', 'PyExc_FileExistsError'), + ('c:data', 'PyExc_FileNotFoundError'), + ('c:data', 'PyExc_FloatingPointError'), + ('c:data', 'PyExc_GeneratorExit'), + ('c:data', 'PyExc_ImportError'), + ('c:data', 'PyExc_IndentationError'), + ('c:data', 'PyExc_IndexError'), + ('c:data', 'PyExc_InterruptedError'), + ('c:data', 'PyExc_IsADirectoryError'), + ('c:data', 'PyExc_KeyboardInterrupt'), + ('c:data', 'PyExc_KeyError'), + ('c:data', 'PyExc_LookupError'), + ('c:data', 'PyExc_MemoryError'), + ('c:data', 'PyExc_ModuleNotFoundError'), + ('c:data', 'PyExc_NameError'), + ('c:data', 'PyExc_NotADirectoryError'), + ('c:data', 'PyExc_NotImplementedError'), + ('c:data', 'PyExc_OSError'), + ('c:data', 'PyExc_OverflowError'), + ('c:data', 'PyExc_PermissionError'), + ('c:data', 'PyExc_ProcessLookupError'), + ('c:data', 'PyExc_RecursionError'), + ('c:data', 'PyExc_ReferenceError'), + ('c:data', 'PyExc_RuntimeError'), + ('c:data', 'PyExc_StopAsyncIteration'), + ('c:data', 'PyExc_StopIteration'), + ('c:data', 'PyExc_SyntaxError'), + ('c:data', 'PyExc_SystemError'), + ('c:data', 'PyExc_SystemExit'), + ('c:data', 'PyExc_TabError'), + ('c:data', 'PyExc_TimeoutError'), + ('c:data', 'PyExc_TypeError'), + ('c:data', 'PyExc_UnboundLocalError'), + ('c:data', 'PyExc_UnicodeDecodeError'), + ('c:data', 'PyExc_UnicodeEncodeError'), + ('c:data', 'PyExc_UnicodeError'), + ('c:data', 'PyExc_UnicodeTranslateError'), + ('c:data', 'PyExc_ValueError'), + ('c:data', 'PyExc_ZeroDivisionError'), + # C API: Standard Python warning classes + ('c:data', 'PyExc_BytesWarning'), + ('c:data', 'PyExc_DeprecationWarning'), + ('c:data', 'PyExc_FutureWarning'), + ('c:data', 'PyExc_ImportWarning'), + ('c:data', 'PyExc_PendingDeprecationWarning'), + ('c:data', 'PyExc_ResourceWarning'), + ('c:data', 'PyExc_RuntimeWarning'), + ('c:data', 'PyExc_SyntaxWarning'), + ('c:data', 'PyExc_UnicodeWarning'), + ('c:data', 'PyExc_UserWarning'), + ('c:data', 'PyExc_Warning'), + # Do not error nit-picky mode builds when _SubParsersAction.add_parser cannot + # be resolved, as the method is currently undocumented. For context, see + # https://github.com/python/cpython/pull/103289. + ('py:meth', '_SubParsersAction.add_parser'), +] + +# gh-106948: Copy standard C types declared in the "c:type" domain to the +# "c:identifier" domain, since "c:function" markup looks for types in the +# "c:identifier" domain. Use list() to not iterate on items which are being +# added +for role, name in list(nitpick_ignore): + if role == 'c:type': + nitpick_ignore.append(('c:identifier', name)) +del role, name + # Disable Docutils smartquotes for several translations smartquotes_excludes = { 'languages': ['ja', 'fr', 'zh_TW', 'zh_CN'], 'builders': ['man', 'text'], @@ -77,6 +251,11 @@ smartquotes_excludes = { # Avoid a warning with Sphinx >= 2.0 master_doc = 'contents' +# Allow translation of index directives +gettext_additional_targets = [ + 'index', +] + # Options for HTML output # ----------------------- @@ -100,6 +279,15 @@ if any('htmlhelp' in arg for arg in sys.argv): # Short title used e.g. for HTML tags. html_short_title = '%s Documentation' % release +# Deployment preview information +# (See .readthedocs.yml and https://docs.readthedocs.io/en/stable/reference/environment-variables.html) +repository_url = os.getenv("READTHEDOCS_GIT_CLONE_URL") +html_context = { + "is_deployment_preview": os.getenv("READTHEDOCS_VERSION_TYPE") == "external", + "repository_url": repository_url.removesuffix(".git") if repository_url else None, + "pr_id": os.getenv("READTHEDOCS_VERSION") +} + # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. html_last_updated_fmt = '%b %d, %Y' @@ -166,8 +354,6 @@ _stdauthor = 'Guido van Rossum and the Python development team' latex_documents = [ ('c-api/index', 'c-api.tex', 'The Python/C API', _stdauthor, 'manual'), - ('distributing/index', 'distributing.tex', - 'Distributing Python Modules', _stdauthor, 'manual'), ('extending/index', 'extending.tex', 'Extending and Embedding Python', _stdauthor, 'manual'), ('installing/index', 'installing.tex', @@ -208,7 +394,6 @@ epub_publisher = 'Python Software Foundation' coverage_ignore_modules = [ r'[T|t][k|K]', r'Tix', - r'distutils.*', ] coverage_ignore_functions = [ @@ -240,8 +425,49 @@ coverage_ignore_c_items = { # Options for the link checker # ---------------------------- -# Ignore certain URLs. -linkcheck_ignore = [r'https://bugs.python.org/(issue)?\d+'] +linkcheck_allowed_redirects = { + # bpo-NNNN -> BPO -> GH Issues + r'https://bugs.python.org/issue\?@action=redirect&bpo=\d+': r'https://github.com/python/cpython/issues/\d+', + # GH-NNNN used to refer to pull requests + r'https://github.com/python/cpython/issues/\d+': r'https://github.com/python/cpython/pull/\d+', + # :source:`something` linking files in the repository + r'https://github.com/python/cpython/tree/.*': 'https://github.com/python/cpython/blob/.*', + # Intentional HTTP use at Misc/NEWS.d/3.5.0a1.rst + r'http://www.python.org/$': 'https://www.python.org/$', + # Used in license page, keep as is + r'https://www.zope.org/': r'https://www.zope.dev/', + # Microsoft's redirects to learn.microsoft.com + r'https://msdn.microsoft.com/.*': 'https://learn.microsoft.com/.*', + r'https://docs.microsoft.com/.*': 'https://learn.microsoft.com/.*', + r'https://go.microsoft.com/fwlink/\?LinkID=\d+': 'https://learn.microsoft.com/.*', + # Language redirects + r'https://toml.io': 'https://toml.io/en/', + r'https://www.redhat.com': 'https://www.redhat.com/en', + # Other redirects + r'https://www.boost.org/libs/.+': r'https://www.boost.org/doc/libs/\d_\d+_\d/.+', + r'https://support.microsoft.com/en-us/help/\d+': 'https://support.microsoft.com/en-us/topic/.+', + r'https://perf.wiki.kernel.org$': 'https://perf.wiki.kernel.org/index.php/Main_Page', + r'https://www.sqlite.org': 'https://www.sqlite.org/index.html', + r'https://mitpress.mit.edu/sicp$': 'https://mitpress.mit.edu/9780262510875/structure-and-interpretation-of-computer-programs/', + r'https://www.python.org/psf/': 'https://www.python.org/psf-landing/', +} + +linkcheck_anchors_ignore = [ + # ignore anchors that start with a '/', e.g. Wikipedia media files: + # https://en.wikipedia.org/wiki/Walrus#/media/File:Pacific_Walrus_-_Bull_(8247646168).jpg + r'\/.*', +] + +linkcheck_ignore = [ + # The crawler gets "Anchor not found" + r'https://developer.apple.com/documentation/.+?#.*', + r'https://devguide.python.org.+?/#.*', + r'https://github.com.+?#.*', + # Robot crawlers not allowed: "403 Client Error: Forbidden" + r'https://support.enthought.com/hc/.*', + # SSLError CertificateError, even though it is valid + r'https://unix.org/version2/whatsnew/lp64_wp.html', +] # Options for extensions @@ -256,7 +482,7 @@ ogp_site_url = 'https://docs.python.org/3/' ogp_site_name = 'Python documentation' ogp_image = '_static/og-image.png' ogp_custom_meta_tags = [ - '<meta property="og:image:width" content="200">', - '<meta property="og:image:height" content="200">', - '<meta name="theme-color" content="#3776ab">', + '<meta property="og:image:width" content="200" />', + '<meta property="og:image:height" content="200" />', + '<meta name="theme-color" content="#3776ab" />', ] diff --git a/Doc/constraints.txt b/Doc/constraints.txt new file mode 100644 index 00000000..147de127 --- /dev/null +++ b/Doc/constraints.txt @@ -0,0 +1,24 @@ +# We have upper bounds on our transitive dependencies here +# To avoid new releases unexpectedly breaking our build. +# This file can be updated on an ad-hoc basis, +# though it will probably have to be updated +# whenever Doc/requirements.txt is updated. + +# Direct dependencies of Sphinx +babel<3 +colorama<0.5 +imagesize<1.5 +Jinja2<3.2 +packaging<24 +Pygments>=2.16.1,<3 +requests<3 +snowballstemmer<3 +sphinxcontrib-applehelp<1.1 +sphinxcontrib-devhelp<1.1 +sphinxcontrib-htmlhelp<2.1 +sphinxcontrib-jsmath<1.1 +sphinxcontrib-qthelp<1.1 +sphinxcontrib-serializinghtml<1.2 + +# Direct dependencies of Jinja2 (Jinja is a dependency of Sphinx, see above) +MarkupSafe<2.2 diff --git a/Doc/contents.rst b/Doc/contents.rst index 8690de77..24ceacb0 100644 --- a/Doc/contents.rst +++ b/Doc/contents.rst @@ -11,7 +11,6 @@ library/index.rst extending/index.rst c-api/index.rst - distributing/index.rst installing/index.rst howto/index.rst faq/index.rst @@ -21,11 +20,3 @@ bugs.rst copyright.rst license.rst - -.. to include legacy packaging docs in build - -.. toctree:: - :hidden: - - distutils/index.rst - install/index.rst diff --git a/Doc/data/python3.11.abi b/Doc/data/python3.11.abi deleted file mode 100644 index 14ffe9ca..00000000 --- a/Doc/data/python3.11.abi +++ /dev/null @@ -1,16643 +0,0 @@ -<abi-corpus path='libpython3.11.so' soname='libpython3.11.so.1.0'> - <elf-needed> - <dependency name='libpthread.so.0'/> - <dependency name='libdl.so.2'/> - <dependency name='libutil.so.1'/> - <dependency name='libm.so.6'/> - <dependency name='libc.so.6'/> - </elf-needed> - <elf-function-symbols> - <elf-symbol name='PyAIter_Check' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyArg_Parse' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyArg_ParseTuple' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyArg_ParseTupleAndKeywords' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyArg_UnpackTuple' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyArg_VaParse' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyArg_VaParseTupleAndKeywords' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyArg_ValidateKeywordArguments' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyAsyncGen_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyBool_FromLong' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyBuffer_FillContiguousStrides' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyBuffer_FillInfo' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyBuffer_FromContiguous' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyBuffer_GetPointer' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyBuffer_IsContiguous' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyBuffer_Release' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyBuffer_SizeFromFormat' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyBuffer_ToContiguous' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyByteArray_AsString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyByteArray_Concat' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyByteArray_FromObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyByteArray_FromStringAndSize' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyByteArray_Resize' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyByteArray_Size' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyBytes_AsString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyBytes_AsStringAndSize' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyBytes_Concat' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyBytes_ConcatAndDel' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyBytes_DecodeEscape' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyBytes_FromFormat' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyBytes_FromFormatV' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyBytes_FromObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyBytes_FromString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyBytes_FromStringAndSize' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyBytes_Repr' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyBytes_Size' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyCFunction_Call' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyCFunction_GetFlags' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyCFunction_GetFunction' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyCFunction_GetSelf' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyCFunction_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyCFunction_NewEx' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyCMethod_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyCallIter_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyCallable_Check' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyCapsule_GetContext' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyCapsule_GetDestructor' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyCapsule_GetName' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyCapsule_GetPointer' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyCapsule_Import' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyCapsule_IsValid' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyCapsule_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyCapsule_SetContext' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyCapsule_SetDestructor' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyCapsule_SetName' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyCapsule_SetPointer' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyCell_Get' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyCell_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyCell_Set' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyClassMethod_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyCode_Addr2Line' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyCode_Addr2Location' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyCode_GetCode' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyCode_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyCode_NewEmpty' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyCode_NewWithPosOnlyArgs' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyCode_Optimize' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyCodec_BackslashReplaceErrors' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyCodec_Decode' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyCodec_Decoder' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyCodec_Encode' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyCodec_Encoder' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyCodec_IgnoreErrors' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyCodec_IncrementalDecoder' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyCodec_IncrementalEncoder' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyCodec_KnownEncoding' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyCodec_LookupError' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyCodec_NameReplaceErrors' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyCodec_Register' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyCodec_RegisterError' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyCodec_ReplaceErrors' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyCodec_StreamReader' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyCodec_StreamWriter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyCodec_StrictErrors' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyCodec_Unregister' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyCodec_XMLCharRefReplaceErrors' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyCompile_OpcodeStackEffect' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyCompile_OpcodeStackEffectWithJump' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyComplex_AsCComplex' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyComplex_FromCComplex' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyComplex_FromDoubles' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyComplex_ImagAsDouble' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyComplex_RealAsDouble' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyConfig_Clear' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyConfig_InitIsolatedConfig' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyConfig_InitPythonConfig' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyConfig_Read' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyConfig_SetArgv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyConfig_SetBytesArgv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyConfig_SetBytesString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyConfig_SetString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyConfig_SetWideStringList' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyContextVar_Get' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyContextVar_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyContextVar_Reset' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyContextVar_Set' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyContext_Copy' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyContext_CopyCurrent' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyContext_Enter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyContext_Exit' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyContext_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyCoro_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyDescr_IsData' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyDescr_NewClassMethod' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyDescr_NewGetSet' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyDescr_NewMember' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyDescr_NewMethod' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyDescr_NewWrapper' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyDictProxy_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyDict_Clear' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyDict_Contains' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyDict_Copy' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyDict_DelItem' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyDict_DelItemString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyDict_GetItem' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyDict_GetItemString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyDict_GetItemWithError' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyDict_Items' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyDict_Keys' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyDict_Merge' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyDict_MergeFromSeq2' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyDict_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyDict_Next' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyDict_SetDefault' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyDict_SetItem' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyDict_SetItemString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyDict_Size' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyDict_Update' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyDict_Values' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyErr_BadArgument' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyErr_BadInternalCall' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyErr_CheckSignals' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyErr_Clear' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyErr_Display' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyErr_ExceptionMatches' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyErr_Fetch' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyErr_Format' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyErr_FormatV' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyErr_GetExcInfo' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyErr_GetHandledException' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyErr_GivenExceptionMatches' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyErr_NewException' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyErr_NewExceptionWithDoc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyErr_NoMemory' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyErr_NormalizeException' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyErr_Occurred' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyErr_Print' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyErr_PrintEx' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyErr_ProgramText' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyErr_ProgramTextObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyErr_RangedSyntaxLocationObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyErr_ResourceWarning' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyErr_Restore' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyErr_SetExcInfo' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyErr_SetFromErrno' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyErr_SetFromErrnoWithFilename' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyErr_SetFromErrnoWithFilenameObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyErr_SetFromErrnoWithFilenameObjects' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyErr_SetHandledException' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyErr_SetImportError' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyErr_SetImportErrorSubclass' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyErr_SetInterrupt' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyErr_SetInterruptEx' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyErr_SetNone' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyErr_SetObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyErr_SetString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyErr_SyntaxLocation' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyErr_SyntaxLocationEx' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyErr_SyntaxLocationObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyErr_WarnEx' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyErr_WarnExplicit' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyErr_WarnExplicitFormat' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyErr_WarnExplicitObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyErr_WarnFormat' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyErr_WriteUnraisable' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyEval_AcquireLock' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyEval_AcquireThread' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyEval_CallFunction' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyEval_CallMethod' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyEval_CallObjectWithKeywords' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyEval_EvalCode' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyEval_EvalCodeEx' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyEval_EvalFrame' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyEval_EvalFrameEx' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyEval_GetBuiltins' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyEval_GetFrame' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyEval_GetFuncDesc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyEval_GetFuncName' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyEval_GetGlobals' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyEval_GetLocals' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyEval_InitThreads' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyEval_MergeCompilerFlags' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyEval_ReleaseLock' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyEval_ReleaseThread' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyEval_RestoreThread' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyEval_SaveThread' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyEval_SetProfile' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyEval_SetTrace' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyEval_ThreadsInitialized' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExceptionClass_Name' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyException_GetCause' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyException_GetContext' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyException_GetTraceback' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyException_SetCause' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyException_SetContext' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyException_SetTraceback' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyFile_FromFd' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyFile_GetLine' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyFile_NewStdPrinter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyFile_OpenCode' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyFile_OpenCodeObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyFile_SetOpenCodeHook' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyFile_WriteObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyFile_WriteString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyFloat_AsDouble' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyFloat_FromDouble' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyFloat_FromString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyFloat_GetInfo' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyFloat_GetMax' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyFloat_GetMin' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyFloat_Pack2' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyFloat_Pack4' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyFloat_Pack8' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyFloat_Unpack2' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyFloat_Unpack4' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyFloat_Unpack8' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyFrame_FastToLocals' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyFrame_FastToLocalsWithError' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyFrame_GetBack' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyFrame_GetBuiltins' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyFrame_GetCode' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyFrame_GetGenerator' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyFrame_GetGlobals' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyFrame_GetLasti' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyFrame_GetLineNumber' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyFrame_GetLocals' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyFrame_LocalsToFast' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyFrame_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyFrozenSet_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyFunction_GetAnnotations' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyFunction_GetClosure' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyFunction_GetCode' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyFunction_GetDefaults' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyFunction_GetGlobals' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyFunction_GetKwDefaults' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyFunction_GetModule' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyFunction_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyFunction_NewWithQualName' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyFunction_SetAnnotations' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyFunction_SetClosure' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyFunction_SetDefaults' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyFunction_SetKwDefaults' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyGC_Collect' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyGC_Disable' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyGC_Enable' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyGC_IsEnabled' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyGILState_Check' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyGILState_Ensure' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyGILState_GetThisThreadState' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyGILState_Release' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyGen_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyGen_NewWithQualName' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyHash_GetFuncDef' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyImport_AddModule' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyImport_AddModuleObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyImport_AppendInittab' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyImport_ExecCodeModule' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyImport_ExecCodeModuleEx' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyImport_ExecCodeModuleObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyImport_ExecCodeModuleWithPathnames' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyImport_ExtendInittab' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyImport_GetImporter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyImport_GetMagicNumber' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyImport_GetMagicTag' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyImport_GetModule' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyImport_GetModuleDict' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyImport_Import' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyImport_ImportFrozenModule' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyImport_ImportFrozenModuleObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyImport_ImportModule' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyImport_ImportModuleLevel' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyImport_ImportModuleLevelObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyImport_ImportModuleNoBlock' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyImport_ReloadModule' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyIndex_Check' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyInit__abc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyInit__ast' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyInit__codecs' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyInit__collections' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyInit__functools' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyInit__imp' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyInit__io' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyInit__locale' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyInit__operator' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyInit__signal' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyInit__sre' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyInit__stat' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyInit__string' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyInit__symtable' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyInit__thread' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyInit__tokenize' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyInit__tracemalloc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyInit__weakref' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyInit_atexit' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyInit_errno' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyInit_faulthandler' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyInit_gc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyInit_itertools' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyInit_posix' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyInit_pwd' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyInit_time' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyInit_xxsubtype' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyInstanceMethod_Function' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyInstanceMethod_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyInterpreterState_Clear' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyInterpreterState_Delete' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyInterpreterState_Get' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyInterpreterState_GetDict' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyInterpreterState_GetID' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyInterpreterState_Head' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyInterpreterState_Main' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyInterpreterState_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyInterpreterState_Next' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyInterpreterState_ThreadHead' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyIter_Check' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyIter_Next' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyIter_Send' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyList_Append' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyList_AsTuple' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyList_GetItem' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyList_GetSlice' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyList_Insert' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyList_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyList_Reverse' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyList_SetItem' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyList_SetSlice' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyList_Size' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyList_Sort' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyLong_AsDouble' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyLong_AsLong' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyLong_AsLongAndOverflow' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyLong_AsLongLong' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyLong_AsLongLongAndOverflow' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyLong_AsSize_t' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyLong_AsSsize_t' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyLong_AsUnsignedLong' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyLong_AsUnsignedLongLong' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyLong_AsUnsignedLongLongMask' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyLong_AsUnsignedLongMask' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyLong_AsVoidPtr' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyLong_FromDouble' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyLong_FromLong' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyLong_FromLongLong' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyLong_FromSize_t' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyLong_FromSsize_t' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyLong_FromString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyLong_FromUnicodeObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyLong_FromUnsignedLong' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyLong_FromUnsignedLongLong' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyLong_FromVoidPtr' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyLong_GetInfo' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyMapping_Check' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyMapping_GetItemString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyMapping_HasKey' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyMapping_HasKeyString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyMapping_Items' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyMapping_Keys' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyMapping_Length' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyMapping_SetItemString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyMapping_Size' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyMapping_Values' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyMarshal_Init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyMarshal_ReadLastObjectFromFile' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyMarshal_ReadLongFromFile' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyMarshal_ReadObjectFromFile' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyMarshal_ReadObjectFromString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyMarshal_ReadShortFromFile' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyMarshal_WriteLongToFile' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyMarshal_WriteObjectToFile' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyMarshal_WriteObjectToString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyMem_Calloc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyMem_Free' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyMem_GetAllocator' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyMem_Malloc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyMem_RawCalloc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyMem_RawFree' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyMem_RawMalloc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyMem_RawRealloc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyMem_Realloc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyMem_SetAllocator' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyMem_SetupDebugHooks' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyMember_GetOne' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyMember_SetOne' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyMemoryView_FromBuffer' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyMemoryView_FromMemory' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyMemoryView_FromObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyMemoryView_GetContiguous' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyMethod_Function' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyMethod_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyMethod_Self' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyModuleDef_Init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyModule_AddFunctions' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyModule_AddIntConstant' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyModule_AddObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyModule_AddObjectRef' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyModule_AddStringConstant' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyModule_AddType' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyModule_Create2' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyModule_ExecDef' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyModule_FromDefAndSpec2' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyModule_GetDef' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyModule_GetDict' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyModule_GetFilename' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyModule_GetFilenameObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyModule_GetName' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyModule_GetNameObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyModule_GetState' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyModule_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyModule_NewObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyModule_SetDocString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyNumber_Absolute' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyNumber_Add' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyNumber_And' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyNumber_AsSsize_t' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyNumber_Check' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyNumber_Divmod' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyNumber_Float' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyNumber_FloorDivide' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyNumber_InPlaceAdd' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyNumber_InPlaceAnd' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyNumber_InPlaceFloorDivide' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyNumber_InPlaceLshift' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyNumber_InPlaceMatrixMultiply' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyNumber_InPlaceMultiply' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyNumber_InPlaceOr' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyNumber_InPlacePower' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyNumber_InPlaceRemainder' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyNumber_InPlaceRshift' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyNumber_InPlaceSubtract' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyNumber_InPlaceTrueDivide' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyNumber_InPlaceXor' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyNumber_Index' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyNumber_Invert' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyNumber_Long' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyNumber_Lshift' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyNumber_MatrixMultiply' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyNumber_Multiply' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyNumber_Negative' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyNumber_Or' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyNumber_Positive' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyNumber_Power' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyNumber_Remainder' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyNumber_Rshift' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyNumber_Subtract' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyNumber_ToBase' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyNumber_TrueDivide' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyNumber_Xor' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyODict_DelItem' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyODict_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyODict_SetItem' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyOS_AfterFork' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyOS_AfterFork_Child' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyOS_AfterFork_Parent' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyOS_BeforeFork' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyOS_FSPath' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyOS_InterruptOccurred' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyOS_Readline' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyOS_double_to_string' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyOS_getsig' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyOS_mystricmp' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyOS_mystrnicmp' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyOS_setsig' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyOS_snprintf' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyOS_string_to_double' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyOS_strtol' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyOS_strtoul' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyOS_vsnprintf' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_ASCII' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_AsCharBuffer' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_AsFileDescriptor' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_AsReadBuffer' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_AsWriteBuffer' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_Bytes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_Call' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_CallFinalizer' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_CallFinalizerFromDealloc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_CallFunction' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_CallFunctionObjArgs' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_CallMethod' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_CallMethodObjArgs' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_CallNoArgs' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_CallObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_CallOneArg' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_Calloc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_CheckBuffer' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_CheckReadBuffer' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_ClearWeakRefs' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_CopyData' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_DelItem' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_DelItemString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_Dir' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_Format' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_Free' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_GC_Del' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_GC_IsFinalized' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_GC_IsTracked' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_GC_Track' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_GC_UnTrack' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_GET_WEAKREFS_LISTPTR' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_GenericGetAttr' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_GenericGetDict' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_GenericSetAttr' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_GenericSetDict' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_GetAIter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_GetArenaAllocator' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_GetAttr' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_GetAttrString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_GetBuffer' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_GetItem' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_GetIter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_HasAttr' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_HasAttrString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_Hash' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_HashNotImplemented' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_IS_GC' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_Init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_InitVar' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_IsInstance' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_IsSubclass' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_IsTrue' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_Length' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_LengthHint' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_Malloc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_Not' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_Print' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_Realloc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_Repr' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_RichCompare' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_RichCompareBool' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_SelfIter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_SetArenaAllocator' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_SetAttr' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_SetAttrString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_SetItem' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_Size' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_Str' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_Type' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_Vectorcall' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_VectorcallDict' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyObject_VectorcallMethod' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyPickleBuffer_FromObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyPickleBuffer_GetBuffer' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyPickleBuffer_Release' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyPreConfig_InitIsolatedConfig' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyPreConfig_InitPythonConfig' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyRun_AnyFile' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyRun_AnyFileEx' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyRun_AnyFileExFlags' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyRun_AnyFileFlags' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyRun_File' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyRun_FileEx' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyRun_FileExFlags' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyRun_FileFlags' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyRun_InteractiveLoop' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyRun_InteractiveLoopFlags' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyRun_InteractiveOne' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyRun_InteractiveOneFlags' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyRun_InteractiveOneObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyRun_SimpleFile' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyRun_SimpleFileEx' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyRun_SimpleFileExFlags' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyRun_SimpleString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyRun_SimpleStringFlags' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyRun_String' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyRun_StringFlags' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PySeqIter_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PySequence_Check' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PySequence_Concat' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PySequence_Contains' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PySequence_Count' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PySequence_DelItem' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PySequence_DelSlice' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PySequence_Fast' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PySequence_GetItem' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PySequence_GetSlice' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PySequence_In' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PySequence_InPlaceConcat' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PySequence_InPlaceRepeat' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PySequence_Index' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PySequence_Length' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PySequence_List' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PySequence_Repeat' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PySequence_SetItem' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PySequence_SetSlice' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PySequence_Size' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PySequence_Tuple' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PySet_Add' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PySet_Clear' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PySet_Contains' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PySet_Discard' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PySet_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PySet_Pop' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PySet_Size' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PySlice_AdjustIndices' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PySlice_GetIndices' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PySlice_GetIndicesEx' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PySlice_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PySlice_Unpack' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyState_AddModule' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyState_FindModule' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyState_RemoveModule' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyStaticMethod_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyStatus_Error' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyStatus_Exception' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyStatus_Exit' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyStatus_IsError' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyStatus_IsExit' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyStatus_NoMemory' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyStatus_Ok' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyStructSequence_GetItem' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyStructSequence_InitType' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyStructSequence_InitType2' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyStructSequence_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyStructSequence_NewType' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyStructSequence_SetItem' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PySymtable_Lookup' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PySys_AddAuditHook' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PySys_AddWarnOption' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PySys_AddWarnOptionUnicode' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PySys_AddXOption' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PySys_Audit' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PySys_FormatStderr' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PySys_FormatStdout' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PySys_GetObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PySys_GetXOptions' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PySys_HasWarnOptions' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PySys_ResetWarnOptions' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PySys_SetArgv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PySys_SetArgvEx' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PySys_SetObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PySys_SetPath' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PySys_WriteStderr' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PySys_WriteStdout' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyThreadState_Clear' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyThreadState_Delete' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyThreadState_DeleteCurrent' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyThreadState_EnterTracing' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyThreadState_Get' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyThreadState_GetDict' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyThreadState_GetFrame' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyThreadState_GetID' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyThreadState_GetInterpreter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyThreadState_LeaveTracing' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyThreadState_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyThreadState_Next' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyThreadState_SetAsyncExc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyThreadState_Swap' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyThread_GetInfo' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyThread_ReInitTLS' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyThread_acquire_lock' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyThread_acquire_lock_timed' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyThread_allocate_lock' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyThread_create_key' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyThread_delete_key' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyThread_delete_key_value' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyThread_exit_thread' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyThread_free_lock' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyThread_get_key_value' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyThread_get_stacksize' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyThread_get_thread_ident' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyThread_get_thread_native_id' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyThread_init_thread' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyThread_release_lock' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyThread_set_key_value' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyThread_set_stacksize' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyThread_start_new_thread' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyThread_tss_alloc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyThread_tss_create' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyThread_tss_delete' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyThread_tss_free' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyThread_tss_get' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyThread_tss_is_created' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyThread_tss_set' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyToken_OneChar' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyToken_ThreeChars' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyToken_TwoChars' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyTraceBack_Here' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyTraceBack_Print' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyTraceMalloc_Track' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyTraceMalloc_Untrack' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyTuple_GetItem' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyTuple_GetSlice' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyTuple_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyTuple_Pack' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyTuple_SetItem' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyTuple_Size' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyType_ClearCache' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyType_FromModuleAndSpec' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyType_FromSpec' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyType_FromSpecWithBases' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyType_GenericAlloc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyType_GenericNew' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyType_GetFlags' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyType_GetModule' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyType_GetModuleByDef' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyType_GetModuleState' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyType_GetName' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyType_GetQualName' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyType_GetSlot' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyType_IsSubtype' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyType_Modified' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyType_Ready' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyType_SUPPORTS_WEAKREFS' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicodeDecodeError_Create' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicodeDecodeError_GetEncoding' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicodeDecodeError_GetEnd' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicodeDecodeError_GetObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicodeDecodeError_GetReason' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicodeDecodeError_GetStart' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicodeDecodeError_SetEnd' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicodeDecodeError_SetReason' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicodeDecodeError_SetStart' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicodeEncodeError_GetEncoding' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicodeEncodeError_GetEnd' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicodeEncodeError_GetObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicodeEncodeError_GetReason' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicodeEncodeError_GetStart' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicodeEncodeError_SetEnd' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicodeEncodeError_SetReason' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicodeEncodeError_SetStart' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicodeTranslateError_GetEnd' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicodeTranslateError_GetObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicodeTranslateError_GetReason' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicodeTranslateError_GetStart' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicodeTranslateError_SetEnd' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicodeTranslateError_SetReason' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicodeTranslateError_SetStart' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_Append' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_AppendAndDel' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_AsASCIIString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_AsCharmapString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_AsDecodedObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_AsDecodedUnicode' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_AsEncodedObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_AsEncodedString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_AsEncodedUnicode' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_AsLatin1String' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_AsRawUnicodeEscapeString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_AsUCS4' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_AsUCS4Copy' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_AsUTF16String' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_AsUTF32String' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_AsUTF8' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_AsUTF8AndSize' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_AsUTF8String' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_AsUnicode' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_AsUnicodeAndSize' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_AsUnicodeEscapeString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_AsWideChar' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_AsWideCharString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_BuildEncodingMap' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_Compare' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_CompareWithASCIIString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_Concat' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_Contains' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_CopyCharacters' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_Count' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_Decode' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_DecodeASCII' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_DecodeCharmap' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_DecodeFSDefault' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_DecodeFSDefaultAndSize' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_DecodeLatin1' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_DecodeLocale' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_DecodeLocaleAndSize' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_DecodeRawUnicodeEscape' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_DecodeUTF16' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_DecodeUTF16Stateful' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_DecodeUTF32' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_DecodeUTF32Stateful' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_DecodeUTF7' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_DecodeUTF7Stateful' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_DecodeUTF8' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_DecodeUTF8Stateful' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_DecodeUnicodeEscape' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_EncodeFSDefault' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_EncodeLocale' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_FSConverter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_FSDecoder' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_Fill' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_Find' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_FindChar' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_Format' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_FromEncodedObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_FromFormat' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_FromFormatV' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_FromKindAndData' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_FromObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_FromOrdinal' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_FromString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_FromStringAndSize' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_FromUnicode' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_FromWideChar' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_GetDefaultEncoding' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_GetLength' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_GetSize' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_InternFromString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_InternImmortal' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_InternInPlace' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_IsIdentifier' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_Join' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_Partition' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_RPartition' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_RSplit' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_ReadChar' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_Replace' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_Resize' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_RichCompare' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_Split' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_Splitlines' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_Substring' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_Tailmatch' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_Translate' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_WriteChar' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyVectorcall_Call' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyVectorcall_Function' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyWeakref_GetObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyWeakref_NewProxy' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyWeakref_NewRef' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyWideStringList_Append' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyWideStringList_Insert' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyWrapper_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_AddPendingCall' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_AtExit' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_BuildValue' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_BytesMain' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_CompileString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_CompileStringExFlags' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_CompileStringFlags' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_CompileStringObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_DecRef' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_DecodeLocale' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_EncodeLocale' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_EndInterpreter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_EnterRecursiveCall' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_Exit' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_ExitStatusException' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_FatalError' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_FdIsInteractive' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_Finalize' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_FinalizeEx' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_FrozenMain' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_GETENV' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_GenericAlias' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_GetArgcArgv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_GetBuildInfo' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_GetCompiler' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_GetCopyright' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_GetExecPrefix' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_GetPath' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_GetPlatform' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_GetPrefix' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_GetProgramFullPath' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_GetProgramName' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_GetPythonHome' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_GetRecursionLimit' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_GetVersion' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_IncRef' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_Initialize' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_InitializeEx' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_InitializeFromConfig' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_Is' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_IsFalse' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_IsInitialized' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_IsNone' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_IsTrue' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_LeaveRecursiveCall' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_Main' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_MakePendingCalls' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_NewInterpreter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_NewRef' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_PreInitialize' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_PreInitializeFromArgs' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_PreInitializeFromBytesArgs' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_ReprEnter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_ReprLeave' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_RunMain' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_SetPath' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_SetProgramName' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_SetPythonHome' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_SetRecursionLimit' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_SetStandardStreamEncoding' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_UniversalNewlineFgets' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_VaBuildValue' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_XNewRef' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyAST_Compile' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyAccu_Accumulate' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyAccu_Destroy' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyAccu_Finish' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyAccu_FinishAsList' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyAccu_Init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyArena_AddPyObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyArena_Free' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyArena_Malloc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyArena_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyArg_BadArgument' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyArg_CheckPositional' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyArg_NoKeywords' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyArg_NoKwnames' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyArg_NoPositional' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyArg_ParseStack' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyArg_ParseStackAndKeywords' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyArg_ParseStackAndKeywords_SizeT' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyArg_ParseStack_SizeT' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyArg_ParseTupleAndKeywordsFast' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyArg_ParseTupleAndKeywordsFast_SizeT' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyArg_ParseTupleAndKeywords_SizeT' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyArg_ParseTuple_SizeT' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyArg_Parse_SizeT' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyArg_UnpackKeywords' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyArg_UnpackKeywordsWithVararg' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyArg_UnpackStack' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyArg_VaParseTupleAndKeywordsFast' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyArg_VaParseTupleAndKeywordsFast_SizeT' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyArg_VaParseTupleAndKeywords_SizeT' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyArg_VaParse_SizeT' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyArgv_AsWstrList' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyBytesWriter_Alloc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyBytesWriter_Dealloc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyBytesWriter_Finish' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyBytesWriter_Init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyBytesWriter_Prepare' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyBytesWriter_Resize' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyBytesWriter_WriteBytes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyBytes_DecodeEscape' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyBytes_Find' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyBytes_FormatEx' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyBytes_FromHex' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyBytes_Join' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyBytes_Repeat' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyBytes_Resize' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyBytes_ReverseFind' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyCode_CheckLineNumber' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyCode_ConstantKey' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyCode_GetExtra' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyCode_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyCode_SetExtra' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyCode_Validate' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyCodecInfo_GetIncrementalDecoder' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyCodecInfo_GetIncrementalEncoder' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyCodec_DecodeText' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyCodec_EncodeText' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyCodec_Lookup' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyCodec_LookupTextEncoding' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyConfig_AsDict' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyConfig_FromDict' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyConfig_InitCompatConfig' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyContext_NewHamtForTests' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyCrossInterpreterData_Lookup' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyCrossInterpreterData_NewObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyCrossInterpreterData_RegisterClass' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyCrossInterpreterData_Release' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyDeadline_Get' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyDeadline_Init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyDebugAllocatorStats' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyDictView_Intersect' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyDictView_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyDict_CheckConsistency' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyDict_ContainsId' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyDict_Contains_KnownHash' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyDict_DebugMallocStats' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyDict_DelItemId' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyDict_DelItemIf' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyDict_DelItem_KnownHash' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyDict_GetItemIdWithError' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyDict_GetItemStringWithError' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyDict_GetItemWithError' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyDict_GetItem_KnownHash' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyDict_HasOnlyStringKeys' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyDict_MaybeUntrack' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyDict_MergeEx' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyDict_NewPresized' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyDict_Next' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyDict_Pop' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyDict_SetItemId' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyDict_SetItem_KnownHash' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyDict_SizeOf' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyErr_BadInternalCall' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyErr_ChainExceptions' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyErr_ChainStackItem' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyErr_CheckSignals' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyErr_CheckSignalsTstate' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyErr_Clear' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyErr_Display' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyErr_ExceptionMatches' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyErr_Fetch' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyErr_Format' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyErr_FormatFromCause' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyErr_FormatFromCauseTstate' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyErr_GetExcInfo' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyErr_GetHandledException' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyErr_GetTopmostException' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyErr_NoMemory' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyErr_NormalizeException' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyErr_Print' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyErr_ProgramDecodedTextObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyErr_Restore' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyErr_SetHandledException' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyErr_SetKeyError' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyErr_SetNone' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyErr_SetObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyErr_SetString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyErr_StackItemToExcInfoTuple' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyErr_TrySetFromCause' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyErr_WriteUnraisableMsg' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyEval_AddPendingCall' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyEval_EvalFrameDefault' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyEval_GetBuiltin' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyEval_GetBuiltinId' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyEval_GetSwitchInterval' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyEval_RequestCodeExtraIndex' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyEval_SetProfile' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyEval_SetSwitchInterval' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyEval_SetTrace' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyEval_SignalAsyncExc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyEval_SignalReceived' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyEval_SliceIndex' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyEval_SliceIndexNotNone' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyFloat_DebugMallocStats' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyFloat_FormatAdvancedWriter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyFrame_IsEntryFrame' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyFunction_Vectorcall' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyGILState_GetInterpreterStateUnsafe' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyGen_FetchStopIterationValue' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyGen_Finalize' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyGen_SetStopIterationValue' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyImport_AcquireLock' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyImport_FixupBuiltin' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyImport_FixupExtensionObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyImport_GetModuleAttr' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyImport_GetModuleAttrString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyImport_GetModuleId' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyImport_IsInitialized' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyImport_ReleaseLock' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyImport_SetModule' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyImport_SetModuleString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyInterpreterID_LookUp' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyInterpreterID_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyInterpreterState_Enable' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyInterpreterState_GetConfig' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyInterpreterState_GetConfigCopy' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyInterpreterState_GetEvalFrameFunc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyInterpreterState_GetIDObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyInterpreterState_GetMainModule' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyInterpreterState_IDDecref' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyInterpreterState_IDIncref' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyInterpreterState_IDInitref' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyInterpreterState_LookUpID' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyInterpreterState_RequireIDRef' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyInterpreterState_RequiresIDRef' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyInterpreterState_SetConfig' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyInterpreterState_SetEvalFrameFunc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyList_DebugMallocStats' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyList_Extend' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyLong_AsByteArray' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyLong_AsInt' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyLong_AsTime_t' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyLong_Copy' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyLong_DivmodNear' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyLong_FileDescriptor_Converter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyLong_Format' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyLong_FormatAdvancedWriter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyLong_FormatBytesWriter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyLong_FormatWriter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyLong_Frexp' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyLong_FromByteArray' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyLong_FromBytes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyLong_FromGid' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyLong_FromTime_t' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyLong_FromUid' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyLong_GCD' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyLong_Lshift' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyLong_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyLong_NumBits' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyLong_Rshift' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyLong_Sign' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyLong_Size_t_Converter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyLong_UnsignedInt_Converter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyLong_UnsignedLongLong_Converter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyLong_UnsignedLong_Converter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyLong_UnsignedShort_Converter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyMem_GetAllocatorName' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyMem_GetCurrentAllocatorName' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyMem_RawStrdup' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyMem_RawWcsdup' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyMem_SetDefaultAllocator' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyMem_SetupAllocators' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyMem_Strdup' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyModuleSpec_IsInitializing' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyModule_Clear' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyModule_ClearDict' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyModule_CreateInitialized' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyNamespace_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyNumber_Index' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyOS_InterruptOccurred' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyOS_IsMainThread' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyOS_URandom' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyOS_URandomNonblock' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyObject_AssertFailed' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyObject_Call' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyObject_CallFunction_SizeT' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyObject_CallMethod' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyObject_CallMethodId' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyObject_CallMethodIdObjArgs' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyObject_CallMethodId_SizeT' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyObject_CallMethod_SizeT' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyObject_Call_Prepend' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyObject_CheckConsistency' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyObject_CheckCrossInterpreterData' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyObject_DebugMallocStats' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyObject_DebugTypeStats' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyObject_Dump' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyObject_FastCall' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyObject_FastCallDictTstate' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyObject_FunctionStr' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyObject_GC_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyObject_GC_NewVar' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyObject_GC_Resize' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyObject_GenericGetAttrWithDict' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyObject_GenericSetAttrWithDict' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyObject_GetAttrId' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyObject_GetCrossInterpreterData' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyObject_GetDictPtr' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyObject_GetMethod' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyObject_GetState' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyObject_HasLen' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyObject_IsAbstract' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyObject_IsFreed' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyObject_LookupAttr' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyObject_LookupAttrId' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyObject_LookupSpecial' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyObject_LookupSpecialId' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyObject_MakeTpCall' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyObject_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyObject_NewVar' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyObject_NextNotImplemented' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyObject_RealIsInstance' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyObject_RealIsSubclass' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyObject_SetAttrId' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyPathConfig_ClearGlobal' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyPreConfig_InitCompatConfig' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyRun_AnyFileObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyRun_InteractiveLoopObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyRun_SimpleFileObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyRuntimeState_Fini' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyRuntimeState_Init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyRuntime_Finalize' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyRuntime_Initialize' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PySequence_BytesToCharpArray' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PySequence_IterSearch' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PySet_NextEntry' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PySet_Update' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PySlice_FromIndices' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PySlice_GetLongIndices' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyStack_AsDict' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyState_AddModule' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyStructSequence_InitType' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyStructSequence_NewType' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PySys_GetAttr' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PySys_GetSizeOf' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyThreadState_DeleteCurrent' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyThreadState_DeleteExcept' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyThreadState_GetDict' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyThreadState_Init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyThreadState_Prealloc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyThreadState_SetCurrent' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyThreadState_Swap' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyThreadState_UncheckedGet' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyThread_CurrentExceptions' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyThread_CurrentFrames' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyThread_at_fork_reinit' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyTime_Add' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyTime_AsMicroseconds' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyTime_AsMilliseconds' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyTime_AsNanoseconds' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyTime_AsNanosecondsObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyTime_AsSecondsDouble' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyTime_AsTimespec' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyTime_AsTimespec_clamp' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyTime_AsTimeval' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyTime_AsTimevalTime_t' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyTime_AsTimeval_clamp' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyTime_FromMillisecondsObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyTime_FromNanoseconds' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyTime_FromNanosecondsObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyTime_FromSeconds' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyTime_FromSecondsObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyTime_FromTimespec' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyTime_FromTimeval' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyTime_GetMonotonicClock' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyTime_GetMonotonicClockWithInfo' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyTime_GetPerfCounter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyTime_GetPerfCounterWithInfo' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyTime_GetSystemClock' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyTime_GetSystemClockWithInfo' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyTime_MulDiv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyTime_ObjectToTime_t' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyTime_ObjectToTimespec' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyTime_ObjectToTimeval' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyTime_gmtime' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyTime_localtime' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyTraceBack_FromFrame' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyTraceBack_Print_Indented' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyTraceMalloc_GetTraceback' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyTraceback_Add' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyTrash_begin' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyTrash_cond' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyTrash_end' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyTuple_DebugMallocStats' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyTuple_MaybeUntrack' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyTuple_Resize' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyType_CalculateMetaclass' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyType_CheckConsistency' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyType_GetDocFromInternalDoc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyType_GetTextSignatureFromInternalDoc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyType_Lookup' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyType_LookupId' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyType_Name' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyUnicodeTranslateError_Create' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyUnicodeWriter_Dealloc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyUnicodeWriter_Finish' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyUnicodeWriter_Init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyUnicodeWriter_PrepareInternal' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyUnicodeWriter_PrepareKindInternal' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyUnicodeWriter_WriteASCIIString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyUnicodeWriter_WriteChar' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyUnicodeWriter_WriteLatin1String' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyUnicodeWriter_WriteStr' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyUnicodeWriter_WriteSubstring' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyUnicode_AsASCIIString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyUnicode_AsLatin1String' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyUnicode_AsUTF8String' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyUnicode_AsUnicode' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyUnicode_CheckConsistency' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyUnicode_Copy' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyUnicode_DecodeRawUnicodeEscapeStateful' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyUnicode_DecodeUnicodeEscapeInternal' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyUnicode_DecodeUnicodeEscapeStateful' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyUnicode_EQ' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyUnicode_EncodeCharmap' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyUnicode_EncodeUTF16' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyUnicode_EncodeUTF32' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyUnicode_EncodeUTF7' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyUnicode_Equal' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyUnicode_EqualToASCIIId' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyUnicode_EqualToASCIIString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyUnicode_FastCopyCharacters' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyUnicode_FastFill' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyUnicode_FindMaxChar' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyUnicode_FormatAdvancedWriter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyUnicode_FormatLong' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyUnicode_FromASCII' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyUnicode_FromId' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyUnicode_InsertThousandsGrouping' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyUnicode_IsAlpha' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyUnicode_IsCaseIgnorable' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyUnicode_IsCased' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyUnicode_IsDecimalDigit' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyUnicode_IsDigit' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyUnicode_IsLinebreak' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyUnicode_IsLowercase' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyUnicode_IsNumeric' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyUnicode_IsPrintable' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyUnicode_IsTitlecase' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyUnicode_IsUppercase' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyUnicode_IsWhitespace' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyUnicode_IsXidContinue' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyUnicode_IsXidStart' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyUnicode_JoinArray' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyUnicode_Ready' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyUnicode_ScanIdentifier' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyUnicode_ToDecimalDigit' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyUnicode_ToDigit' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyUnicode_ToFoldedFull' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyUnicode_ToLowerFull' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyUnicode_ToLowercase' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyUnicode_ToNumeric' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyUnicode_ToTitleFull' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyUnicode_ToTitlecase' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyUnicode_ToUpperFull' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyUnicode_ToUppercase' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyUnicode_TransformDecimalAndSpaceToASCII' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyUnicode_WideCharString_Converter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyUnicode_WideCharString_Opt_Converter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyUnicode_XStrip' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyWarnings_Init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyWeakref_ClearRef' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyWeakref_GetWeakrefCount' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyWideStringList_AsList' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyWideStringList_Clear' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyWideStringList_Copy' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyWideStringList_Extend' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_BreakPoint' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_BuildValue_SizeT' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_CheckFunctionResult' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_CheckRecursiveCall' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_ClearArgcArgv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_ClearStandardStreamEncoding' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_CoerceLegacyLocale' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_Dealloc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_DecRef' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_DecodeLocaleEx' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_DecodeUTF8Ex' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_DecodeUTF8_surrogateescape' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_DisplaySourceLine' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_DumpASCII' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_DumpDecimal' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_DumpExtensionModules' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_DumpHexadecimal' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_DumpTraceback' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_DumpTracebackThreads' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_EncodeLocaleEx' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_EncodeLocaleRaw' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_EncodeUTF8Ex' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_FatalErrorFormat' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_FatalErrorFunc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_FatalError_TstateNULL' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_FatalRefcountErrorFunc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_FdIsInteractive' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_FreeCharPArray' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_GetAllocatedBlocks' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_GetConfig' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_GetConfigsAsDict' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_GetEnv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_GetErrorHandler' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_GetForceASCII' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_GetLocaleEncoding' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_GetLocaleEncodingObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_GetLocaleconvNumeric' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_Get_Getpath_CodeObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_Gid_Converter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_HandleSystemExit' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_HashBytes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_HashDouble' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_HashPointer' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_HashPointerRaw' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_IncRef' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_InitializeMain' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_IsCoreInitialized' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_IsFinalizing' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_IsLocaleCoercionTarget' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_LegacyLocaleDetected' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_NewInterpreter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_NewReference' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_PreInitializeFromConfig' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_PreInitializeFromPyArgv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_ResetForceASCII' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_RestoreSignals' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_SetLocaleFromEnv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_SetProgramFullPath' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_Sigset_Converter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_SourceAsString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_UTF8_Edit_Cost' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_Uid_Converter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_VaBuildStack' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_VaBuildStack_SizeT' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_VaBuildValue_SizeT' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_WriteIndent' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_WriteIndentedMargin' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_add_one_to_index_C' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_add_one_to_index_F' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_c_abs' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_c_diff' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_c_neg' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_c_pow' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_c_prod' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_c_quot' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_c_sum' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_closerange' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_convert_optional_to_ssize_t' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_device_encoding' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_dg_dtoa' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_dg_freedtoa' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_dg_infinity' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_dg_stdnan' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_dg_strtod' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_dup' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_fopen_obj' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_fstat' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_fstat_noraise' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_get_blocking' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_get_env_flag' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_get_inheritable' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_get_xoption' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_gitidentifier' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_gitversion' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_hashtable_clear' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_hashtable_compare_direct' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_hashtable_destroy' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_hashtable_foreach' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_hashtable_get' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_hashtable_hash_ptr' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_hashtable_new' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_hashtable_new_full' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_hashtable_set' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_hashtable_size' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_hashtable_steal' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_normpath' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_open' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_open_noraise' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_parse_inf_or_nan' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_read' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_set_blocking' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_set_inheritable' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_set_inheritable_async_safe' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_stat' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_str_to_int' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_strhex' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_strhex_bytes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_strhex_bytes_with_sep' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_strhex_with_sep' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_string_to_number_with_underscores' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_wfopen' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_wgetcwd' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_wreadlink' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_wrealpath' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_write' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_write_noraise' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - </elf-function-symbols> - <elf-variable-symbols> - <elf-symbol name='PyAsyncGen_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyBaseObject_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyBool_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyByteArrayIter_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyByteArray_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyBytesIter_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyBytes_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyCFunction_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyCMethod_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyCallIter_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyCapsule_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyCell_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyClassMethodDescr_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyClassMethod_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyCode_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyComplex_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyContextToken_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyContextVar_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyContext_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyCoro_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyDictItems_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyDictIterItem_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyDictIterKey_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyDictIterValue_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyDictKeys_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyDictProxy_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyDictRevIterItem_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyDictRevIterKey_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyDictRevIterValue_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyDictValues_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyDict_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyEllipsis_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyEnum_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExc_ArithmeticError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExc_AssertionError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExc_AttributeError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExc_BaseException' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExc_BaseExceptionGroup' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExc_BlockingIOError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExc_BrokenPipeError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExc_BufferError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExc_BytesWarning' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExc_ChildProcessError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExc_ConnectionAbortedError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExc_ConnectionError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExc_ConnectionRefusedError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExc_ConnectionResetError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExc_DeprecationWarning' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExc_EOFError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExc_EncodingWarning' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExc_EnvironmentError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExc_Exception' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExc_FileExistsError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExc_FileNotFoundError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExc_FloatingPointError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExc_FutureWarning' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExc_GeneratorExit' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExc_IOError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExc_ImportError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExc_ImportWarning' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExc_IndentationError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExc_IndexError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExc_InterruptedError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExc_IsADirectoryError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExc_KeyError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExc_KeyboardInterrupt' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExc_LookupError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExc_MemoryError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExc_ModuleNotFoundError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExc_NameError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExc_NotADirectoryError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExc_NotImplementedError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExc_OSError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExc_OverflowError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExc_PendingDeprecationWarning' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExc_PermissionError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExc_ProcessLookupError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExc_RecursionError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExc_ReferenceError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExc_ResourceWarning' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExc_RuntimeError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExc_RuntimeWarning' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExc_StopAsyncIteration' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExc_StopIteration' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExc_SyntaxError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExc_SyntaxWarning' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExc_SystemError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExc_SystemExit' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExc_TabError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExc_TimeoutError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExc_TypeError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExc_UnboundLocalError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExc_UnicodeDecodeError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExc_UnicodeEncodeError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExc_UnicodeError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExc_UnicodeTranslateError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExc_UnicodeWarning' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExc_UserWarning' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExc_ValueError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExc_Warning' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyExc_ZeroDivisionError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyFilter_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyFloat_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyFrame_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyFrozenSet_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyFunction_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyGen_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyGetSetDescr_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyImport_FrozenModules' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyImport_Inittab' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyInstanceMethod_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyListIter_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyListRevIter_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyList_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyLongRangeIter_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyLong_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyMap_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyMemberDescr_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyMemoryView_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyMethodDescr_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyMethod_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyModuleDef_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyModule_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyODictItems_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyODictIter_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyODictKeys_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyODictValues_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyODict_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyOS_InputHook' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyOS_ReadlineFunctionPointer' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyPickleBuffer_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyProperty_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyRangeIter_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyRange_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyReversed_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PySeqIter_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PySetIter_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PySet_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PySlice_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyStaticMethod_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyStdPrinter_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyStructSequence_UnnamedField' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PySuper_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyTraceBack_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyTupleIter_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyTuple_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyType_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicodeIter_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyUnicode_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyWrapperDescr_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='PyZip_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_BytesWarningFlag' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_DebugFlag' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_DontWriteBytecodeFlag' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_FileSystemDefaultEncodeErrors' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_FileSystemDefaultEncoding' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_FrozenFlag' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_GenericAliasType' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_HasFileSystemDefaultEncoding' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_HashRandomizationFlag' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_IgnoreEnvironmentFlag' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_InspectFlag' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_InteractiveFlag' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_IsolatedFlag' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_NoSiteFlag' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_NoUserSiteDirectory' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_OptimizeFlag' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_QuietFlag' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_UTF8Mode' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_UnbufferedStdioFlag' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_VerboseFlag' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_Version' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='Py_hexdigits' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyAsyncGenASend_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyAsyncGenAThrow_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyAsyncGenWrappedValue_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyByteArray_empty_string' size='1' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyBytesIOBuffer_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyCoroWrapper_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyImport_FrozenBootstrap' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyImport_FrozenStdlib' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyImport_FrozenTest' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyInterpreterID_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyLong_DigitValue' size='256' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyManagedBuffer_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyMethodWrapper_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyNamespace_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyNone_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyNotImplemented_Type' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyOS_ReadlineTState' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyParser_TokenNames' size='520' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyRuntime' size='166688' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PySet_Dummy' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyWeakref_CallableProxyType' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyWeakref_ProxyType' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_PyWeakref_RefType' size='408' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_EllipsisObject' size='16' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_FalseStruct' size='32' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_HasFileSystemDefaultEncodeErrors' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_HashSecret' size='24' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_NoneStruct' size='16' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_NotImplementedStruct' size='16' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_PackageContext' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_SwappedOp' size='24' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_TrueStruct' size='32' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_UnhandledKeyboardInterrupt' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_ascii_whitespace' size='128' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_ctype_table' size='1024' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_ctype_tolower' size='256' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_ctype_toupper' size='256' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - <elf-symbol name='_Py_tracemalloc_config' size='12' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> - </elf-variable-symbols> - <abi-instr version='1.0' address-size='64' path='./Modules/getbuildinfo.c' comp-dir-path='/src' language='LANG_C99'> - <type-decl name='char' size-in-bits='8' id='type-id-1'/> - <qualified-type-def type-id='type-id-1' const='yes' id='type-id-2'/> - <pointer-type-def type-id='type-id-2' size-in-bits='64' id='type-id-3'/> - <function-decl name='_Py_gitidentifier' mangled-name='_Py_gitidentifier' filepath='./Modules/getbuildinfo.c' line='59' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_gitidentifier'> - <return type-id='type-id-3'/> - </function-decl> - <function-decl name='_Py_gitversion' mangled-name='_Py_gitversion' filepath='./Modules/getbuildinfo.c' line='53' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_gitversion'> - <return type-id='type-id-3'/> - </function-decl> - <function-decl name='Py_GetBuildInfo' mangled-name='Py_GetBuildInfo' filepath='./Modules/getbuildinfo.c' line='35' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_GetBuildInfo'> - <return type-id='type-id-3'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Parser/token.c' comp-dir-path='/src' language='LANG_C99'> - <qualified-type-def type-id='type-id-3' const='yes' id='type-id-4'/> - - <array-type-def dimensions='1' type-id='type-id-4' size-in-bits='infinite' id='type-id-5'> - <subrange length='infinite' id='type-id-6'/> - - </array-type-def> - <qualified-type-def type-id='type-id-5' const='yes' id='type-id-7'/> - <var-decl name='_PyParser_TokenNames' type-id='type-id-7' mangled-name='_PyParser_TokenNames' visibility='default' filepath='./Include/token.h' line='88' column='1' elf-symbol-id='_PyParser_TokenNames'/> - <type-decl name='int' size-in-bits='32' id='type-id-8'/> - <function-decl name='PyToken_ThreeChars' mangled-name='PyToken_ThreeChars' filepath='Parser/token.c' line='194' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyToken_ThreeChars'> - <parameter type-id='type-id-8' name='c1' filepath='Parser/token.c' line='194' column='1'/> - <parameter type-id='type-id-8' name='c2' filepath='Parser/token.c' line='194' column='1'/> - <parameter type-id='type-id-8' name='c3' filepath='Parser/token.c' line='194' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyToken_TwoChars' mangled-name='PyToken_TwoChars' filepath='Parser/token.c' line='110' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyToken_TwoChars'> - <parameter type-id='type-id-8' name='c1' filepath='Parser/token.c' line='110' column='1'/> - <parameter type-id='type-id-8' name='c2' filepath='Parser/token.c' line='110' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyToken_OneChar' mangled-name='PyToken_OneChar' filepath='Parser/token.c' line='79' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyToken_OneChar'> - <parameter type-id='type-id-8' name='c1' filepath='Parser/token.c' line='79' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Parser/myreadline.c' comp-dir-path='/src' language='LANG_C99'> - <class-decl name='_ts' size-in-bits='2880' is-struct='yes' visibility='default' filepath='./Include/cpython/pystate.h' line='82' column='1' id='type-id-9'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='prev' type-id='type-id-10' visibility='default' filepath='./Include/cpython/pystate.h' line='85' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='next' type-id='type-id-10' visibility='default' filepath='./Include/cpython/pystate.h' line='86' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='interp' type-id='type-id-11' visibility='default' filepath='./Include/cpython/pystate.h' line='87' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='_initialized' type-id='type-id-8' visibility='default' filepath='./Include/cpython/pystate.h' line='93' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='224'> - <var-decl name='_static' type-id='type-id-8' visibility='default' filepath='./Include/cpython/pystate.h' line='96' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='256'> - <var-decl name='recursion_remaining' type-id='type-id-8' visibility='default' filepath='./Include/cpython/pystate.h' line='98' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='288'> - <var-decl name='recursion_limit' type-id='type-id-8' visibility='default' filepath='./Include/cpython/pystate.h' line='99' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='320'> - <var-decl name='recursion_headroom' type-id='type-id-8' visibility='default' filepath='./Include/cpython/pystate.h' line='100' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='352'> - <var-decl name='tracing' type-id='type-id-8' visibility='default' filepath='./Include/cpython/pystate.h' line='105' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='384'> - <var-decl name='tracing_what' type-id='type-id-8' visibility='default' filepath='./Include/cpython/pystate.h' line='106' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='448'> - <var-decl name='cframe' type-id='type-id-12' visibility='default' filepath='./Include/cpython/pystate.h' line='110' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='512'> - <var-decl name='c_profilefunc' type-id='type-id-13' visibility='default' filepath='./Include/cpython/pystate.h' line='112' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='576'> - <var-decl name='c_tracefunc' type-id='type-id-13' visibility='default' filepath='./Include/cpython/pystate.h' line='113' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='640'> - <var-decl name='c_profileobj' type-id='type-id-14' visibility='default' filepath='./Include/cpython/pystate.h' line='114' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='704'> - <var-decl name='c_traceobj' type-id='type-id-14' visibility='default' filepath='./Include/cpython/pystate.h' line='115' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='768'> - <var-decl name='curexc_type' type-id='type-id-14' visibility='default' filepath='./Include/cpython/pystate.h' line='118' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='832'> - <var-decl name='curexc_value' type-id='type-id-14' visibility='default' filepath='./Include/cpython/pystate.h' line='119' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='896'> - <var-decl name='curexc_traceback' type-id='type-id-14' visibility='default' filepath='./Include/cpython/pystate.h' line='120' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='960'> - <var-decl name='exc_info' type-id='type-id-15' visibility='default' filepath='./Include/cpython/pystate.h' line='125' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1024'> - <var-decl name='dict' type-id='type-id-14' visibility='default' filepath='./Include/cpython/pystate.h' line='127' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1088'> - <var-decl name='gilstate_counter' type-id='type-id-8' visibility='default' filepath='./Include/cpython/pystate.h' line='129' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1152'> - <var-decl name='async_exc' type-id='type-id-14' visibility='default' filepath='./Include/cpython/pystate.h' line='131' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1216'> - <var-decl name='thread_id' type-id='type-id-16' visibility='default' filepath='./Include/cpython/pystate.h' line='132' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1280'> - <var-decl name='native_thread_id' type-id='type-id-16' visibility='default' filepath='./Include/cpython/pystate.h' line='138' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1344'> - <var-decl name='trash_delete_nesting' type-id='type-id-8' visibility='default' filepath='./Include/cpython/pystate.h' line='140' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1408'> - <var-decl name='trash_delete_later' type-id='type-id-14' visibility='default' filepath='./Include/cpython/pystate.h' line='141' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1472'> - <var-decl name='on_delete' type-id='type-id-17' visibility='default' filepath='./Include/cpython/pystate.h' line='166' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1536'> - <var-decl name='on_delete_data' type-id='type-id-18' visibility='default' filepath='./Include/cpython/pystate.h' line='167' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1600'> - <var-decl name='coroutine_origin_tracking_depth' type-id='type-id-8' visibility='default' filepath='./Include/cpython/pystate.h' line='169' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1664'> - <var-decl name='async_gen_firstiter' type-id='type-id-14' visibility='default' filepath='./Include/cpython/pystate.h' line='171' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1728'> - <var-decl name='async_gen_finalizer' type-id='type-id-14' visibility='default' filepath='./Include/cpython/pystate.h' line='172' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1792'> - <var-decl name='context' type-id='type-id-14' visibility='default' filepath='./Include/cpython/pystate.h' line='174' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1856'> - <var-decl name='context_ver' type-id='type-id-19' visibility='default' filepath='./Include/cpython/pystate.h' line='175' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1920'> - <var-decl name='id' type-id='type-id-19' visibility='default' filepath='./Include/cpython/pystate.h' line='178' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1984'> - <var-decl name='trace_info' type-id='type-id-20' visibility='default' filepath='./Include/cpython/pystate.h' line='180' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='2368'> - <var-decl name='datastack_chunk' type-id='type-id-21' visibility='default' filepath='./Include/cpython/pystate.h' line='182' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='2432'> - <var-decl name='datastack_top' type-id='type-id-22' visibility='default' filepath='./Include/cpython/pystate.h' line='183' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='2496'> - <var-decl name='datastack_limit' type-id='type-id-22' visibility='default' filepath='./Include/cpython/pystate.h' line='184' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='2560'> - <var-decl name='exc_state' type-id='type-id-23' visibility='default' filepath='./Include/cpython/pystate.h' line='199' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='2688'> - <var-decl name='root_cframe' type-id='type-id-24' visibility='default' filepath='./Include/cpython/pystate.h' line='202' column='1'/> - </data-member> - </class-decl> - <typedef-decl name='PyThreadState' type-id='type-id-9' filepath='./Include/pytypedefs.h' line='24' column='1' id='type-id-25'/> - <pointer-type-def type-id='type-id-25' size-in-bits='64' id='type-id-10'/> - <class-decl name='_is' size-in-bits='862016' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_interp.h' line='78' column='1' id='type-id-26'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='next' type-id='type-id-11' visibility='default' filepath='./Include/internal/pycore_interp.h' line='80' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='threads' type-id='type-id-27' visibility='default' filepath='./Include/internal/pycore_interp.h' line='93' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='320'> - <var-decl name='runtime' type-id='type-id-28' visibility='default' filepath='./Include/internal/pycore_interp.h' line='98' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='384'> - <var-decl name='id' type-id='type-id-29' visibility='default' filepath='./Include/internal/pycore_interp.h' line='100' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='448'> - <var-decl name='id_refcount' type-id='type-id-29' visibility='default' filepath='./Include/internal/pycore_interp.h' line='101' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='512'> - <var-decl name='requires_idref' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_interp.h' line='102' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='576'> - <var-decl name='id_mutex' type-id='type-id-30' visibility='default' filepath='./Include/internal/pycore_interp.h' line='103' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='640'> - <var-decl name='_initialized' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_interp.h' line='109' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='672'> - <var-decl name='finalizing' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_interp.h' line='110' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='704'> - <var-decl name='_static' type-id='type-id-31' visibility='default' filepath='./Include/internal/pycore_interp.h' line='113' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='768'> - <var-decl name='ceval' type-id='type-id-32' visibility='default' filepath='./Include/internal/pycore_interp.h' line='115' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='5184'> - <var-decl name='gc' type-id='type-id-33' visibility='default' filepath='./Include/internal/pycore_interp.h' line='116' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='7104'> - <var-decl name='modules' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_interp.h' line='119' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='7168'> - <var-decl name='modules_by_index' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_interp.h' line='120' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='7232'> - <var-decl name='sysdict' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_interp.h' line='122' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='7296'> - <var-decl name='builtins' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_interp.h' line='124' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='7360'> - <var-decl name='importlib' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_interp.h' line='126' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='7424'> - <var-decl name='override_frozen_modules' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_interp.h' line='129' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='7488'> - <var-decl name='codec_search_path' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_interp.h' line='131' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='7552'> - <var-decl name='codec_search_cache' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_interp.h' line='132' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='7616'> - <var-decl name='codec_error_registry' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_interp.h' line='133' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='7680'> - <var-decl name='codecs_initialized' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_interp.h' line='134' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='7744'> - <var-decl name='config' type-id='type-id-34' visibility='default' filepath='./Include/internal/pycore_interp.h' line='136' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='11136'> - <var-decl name='dlopenflags' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_interp.h' line='138' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='11200'> - <var-decl name='dict' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_interp.h' line='141' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='11264'> - <var-decl name='builtins_copy' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_interp.h' line='143' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='11328'> - <var-decl name='import_func' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_interp.h' line='144' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='11392'> - <var-decl name='eval_frame' type-id='type-id-35' visibility='default' filepath='./Include/internal/pycore_interp.h' line='146' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='11456'> - <var-decl name='co_extra_user_count' type-id='type-id-36' visibility='default' filepath='./Include/internal/pycore_interp.h' line='148' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='11520'> - <var-decl name='co_extra_freefuncs' type-id='type-id-37' visibility='default' filepath='./Include/internal/pycore_interp.h' line='149' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='27840'> - <var-decl name='before_forkers' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_interp.h' line='152' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='27904'> - <var-decl name='after_forkers_parent' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_interp.h' line='153' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='27968'> - <var-decl name='after_forkers_child' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_interp.h' line='154' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='28032'> - <var-decl name='warnings' type-id='type-id-38' visibility='default' filepath='./Include/internal/pycore_interp.h' line='157' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='28288'> - <var-decl name='atexit' type-id='type-id-39' visibility='default' filepath='./Include/internal/pycore_interp.h' line='158' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='28416'> - <var-decl name='audit_hooks' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_interp.h' line='160' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='28480'> - <var-decl name='unicode' type-id='type-id-40' visibility='default' filepath='./Include/internal/pycore_interp.h' line='162' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='28864'> - <var-decl name='float_state' type-id='type-id-41' visibility='default' filepath='./Include/internal/pycore_interp.h' line='163' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='28992'> - <var-decl name='slice_cache' type-id='type-id-42' visibility='default' filepath='./Include/internal/pycore_interp.h' line='166' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='29056'> - <var-decl name='tuple' type-id='type-id-43' visibility='default' filepath='./Include/internal/pycore_interp.h' line='168' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='30976'> - <var-decl name='list' type-id='type-id-44' visibility='default' filepath='./Include/internal/pycore_interp.h' line='169' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='36160'> - <var-decl name='dict_state' type-id='type-id-45' visibility='default' filepath='./Include/internal/pycore_interp.h' line='170' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='46528'> - <var-decl name='async_gen' type-id='type-id-46' visibility='default' filepath='./Include/internal/pycore_interp.h' line='171' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='56896'> - <var-decl name='context' type-id='type-id-47' visibility='default' filepath='./Include/internal/pycore_interp.h' line='172' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='57024'> - <var-decl name='exc_state' type-id='type-id-48' visibility='default' filepath='./Include/internal/pycore_interp.h' line='173' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='57280'> - <var-decl name='ast' type-id='type-id-49' visibility='default' filepath='./Include/internal/pycore_interp.h' line='175' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='72448'> - <var-decl name='type_cache' type-id='type-id-50' visibility='default' filepath='./Include/internal/pycore_interp.h' line='176' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='858880'> - <var-decl name='callable_cache' type-id='type-id-51' visibility='default' filepath='./Include/internal/pycore_interp.h' line='177' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='859072'> - <var-decl name='int_max_str_digits' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_interp.h' line='179' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='859136'> - <var-decl name='_initial_thread' type-id='type-id-25' visibility='default' filepath='./Include/internal/pycore_interp.h' line='192' column='1'/> - </data-member> - </class-decl> - <typedef-decl name='PyInterpreterState' type-id='type-id-26' filepath='./Include/pytypedefs.h' line='25' column='1' id='type-id-52'/> - <pointer-type-def type-id='type-id-52' size-in-bits='64' id='type-id-11'/> - <class-decl name='pythreads' size-in-bits='256' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_interp.h' line='82' column='1' id='type-id-27'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='next_unique_id' type-id='type-id-19' visibility='default' filepath='./Include/internal/pycore_interp.h' line='83' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='head' type-id='type-id-10' visibility='default' filepath='./Include/internal/pycore_interp.h' line='85' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='count' type-id='type-id-53' visibility='default' filepath='./Include/internal/pycore_interp.h' line='87' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='stacksize' type-id='type-id-54' visibility='default' filepath='./Include/internal/pycore_interp.h' line='92' column='1'/> - </data-member> - </class-decl> - <type-decl name='unsigned long int' size-in-bits='64' id='type-id-16'/> - <typedef-decl name='__uint64_t' type-id='type-id-16' filepath='/usr/include/x86_64-linux-gnu/bits/types.h' line='45' column='1' id='type-id-55'/> - <typedef-decl name='uint64_t' type-id='type-id-55' filepath='/usr/include/x86_64-linux-gnu/bits/stdint-uintn.h' line='27' column='1' id='type-id-19'/> - <type-decl name='long int' size-in-bits='64' id='type-id-53'/> - <typedef-decl name='size_t' type-id='type-id-16' filepath='/usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h' line='209' column='1' id='type-id-54'/> - <class-decl name='pyruntimestate' size-in-bits='1333504' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='59' column='1' id='type-id-56'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='_initialized' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='64' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='32'> - <var-decl name='preinitializing' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='67' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='preinitialized' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='70' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='96'> - <var-decl name='core_initialized' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='73' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='initialized' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='76' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='_finalizing' type-id='type-id-57' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='83' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='256'> - <var-decl name='interpreters' type-id='type-id-58' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='102' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='512'> - <var-decl name='xidregistry' type-id='type-id-59' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='107' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='640'> - <var-decl name='main_thread' type-id='type-id-16' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='109' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='704'> - <var-decl name='exitfuncs' type-id='type-id-60' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='112' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='2752'> - <var-decl name='nexitfuncs' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='113' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='2816'> - <var-decl name='ceval' type-id='type-id-61' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='115' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='4544'> - <var-decl name='gilstate' type-id='type-id-62' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='116' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='4800'> - <var-decl name='preconfig' type-id='type-id-63' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='118' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='5120'> - <var-decl name='open_code_hook' type-id='type-id-64' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='122' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='5184'> - <var-decl name='open_code_userdata' type-id='type-id-18' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='123' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='5248'> - <var-decl name='audit_hook_head' type-id='type-id-65' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='124' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='5312'> - <var-decl name='unicode_ids' type-id='type-id-66' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='126' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='5440'> - <var-decl name='global_objects' type-id='type-id-67' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='129' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='471488'> - <var-decl name='_main_interpreter' type-id='type-id-52' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='146' column='1'/> - </data-member> - </class-decl> - <class-decl name='_Py_atomic_address' size-in-bits='64' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_atomic.h' line='45' column='1' id='type-id-68'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='_value' type-id='type-id-69' visibility='default' filepath='./Include/internal/pycore_atomic.h' line='46' column='1'/> - </data-member> - </class-decl> - <type-decl name='atomic_uintptr_t' size-in-bits='64' id='type-id-69'/> - <typedef-decl name='_Py_atomic_address' type-id='type-id-68' filepath='./Include/internal/pycore_atomic.h' line='47' column='1' id='type-id-57'/> - <class-decl name='pyinterpreters' size-in-bits='256' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='85' column='1' id='type-id-58'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='mutex' type-id='type-id-30' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='86' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='head' type-id='type-id-11' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='88' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='main' type-id='type-id-11' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='92' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='next_id' type-id='type-id-29' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='101' column='1'/> - </data-member> - </class-decl> - <type-decl name='void' id='type-id-70'/> - <pointer-type-def type-id='type-id-70' size-in-bits='64' id='type-id-18'/> - <typedef-decl name='PyThread_type_lock' type-id='type-id-18' filepath='./Include/pythread.h' line='4' column='1' id='type-id-30'/> - <typedef-decl name='__int64_t' type-id='type-id-53' filepath='/usr/include/x86_64-linux-gnu/bits/types.h' line='44' column='1' id='type-id-71'/> - <typedef-decl name='int64_t' type-id='type-id-71' filepath='/usr/include/x86_64-linux-gnu/bits/stdint-intn.h' line='27' column='1' id='type-id-29'/> - <class-decl name='_xidregistry' size-in-bits='128' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='104' column='1' id='type-id-59'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='mutex' type-id='type-id-30' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='105' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='head' type-id='type-id-72' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='106' column='1'/> - </data-member> - </class-decl> - <class-decl name='_xidregitem' size-in-bits='192' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_interp.h' line='210' column='1' id='type-id-73'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='cls' type-id='type-id-74' visibility='default' filepath='./Include/internal/pycore_interp.h' line='211' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='getdata' type-id='type-id-75' visibility='default' filepath='./Include/internal/pycore_interp.h' line='212' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='next' type-id='type-id-72' visibility='default' filepath='./Include/internal/pycore_interp.h' line='213' column='1'/> - </data-member> - </class-decl> - <class-decl name='_typeobject' size-in-bits='3264' is-struct='yes' visibility='default' filepath='./Include/cpython/object.h' line='148' column='1' id='type-id-76'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='ob_base' type-id='type-id-77' visibility='default' filepath='./Include/cpython/object.h' line='149' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='tp_name' type-id='type-id-3' visibility='default' filepath='./Include/cpython/object.h' line='150' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='256'> - <var-decl name='tp_basicsize' type-id='type-id-36' visibility='default' filepath='./Include/cpython/object.h' line='151' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='320'> - <var-decl name='tp_itemsize' type-id='type-id-36' visibility='default' filepath='./Include/cpython/object.h' line='151' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='384'> - <var-decl name='tp_dealloc' type-id='type-id-78' visibility='default' filepath='./Include/cpython/object.h' line='155' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='448'> - <var-decl name='tp_vectorcall_offset' type-id='type-id-36' visibility='default' filepath='./Include/cpython/object.h' line='156' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='512'> - <var-decl name='tp_getattr' type-id='type-id-79' visibility='default' filepath='./Include/cpython/object.h' line='157' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='576'> - <var-decl name='tp_setattr' type-id='type-id-80' visibility='default' filepath='./Include/cpython/object.h' line='158' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='640'> - <var-decl name='tp_as_async' type-id='type-id-81' visibility='default' filepath='./Include/cpython/object.h' line='159' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='704'> - <var-decl name='tp_repr' type-id='type-id-82' visibility='default' filepath='./Include/cpython/object.h' line='161' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='768'> - <var-decl name='tp_as_number' type-id='type-id-83' visibility='default' filepath='./Include/cpython/object.h' line='165' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='832'> - <var-decl name='tp_as_sequence' type-id='type-id-84' visibility='default' filepath='./Include/cpython/object.h' line='166' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='896'> - <var-decl name='tp_as_mapping' type-id='type-id-85' visibility='default' filepath='./Include/cpython/object.h' line='167' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='960'> - <var-decl name='tp_hash' type-id='type-id-86' visibility='default' filepath='./Include/cpython/object.h' line='171' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1024'> - <var-decl name='tp_call' type-id='type-id-87' visibility='default' filepath='./Include/cpython/object.h' line='172' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1088'> - <var-decl name='tp_str' type-id='type-id-82' visibility='default' filepath='./Include/cpython/object.h' line='173' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1152'> - <var-decl name='tp_getattro' type-id='type-id-88' visibility='default' filepath='./Include/cpython/object.h' line='174' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1216'> - <var-decl name='tp_setattro' type-id='type-id-89' visibility='default' filepath='./Include/cpython/object.h' line='175' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1280'> - <var-decl name='tp_as_buffer' type-id='type-id-90' visibility='default' filepath='./Include/cpython/object.h' line='178' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1344'> - <var-decl name='tp_flags' type-id='type-id-16' visibility='default' filepath='./Include/cpython/object.h' line='181' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1408'> - <var-decl name='tp_doc' type-id='type-id-3' visibility='default' filepath='./Include/cpython/object.h' line='183' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1472'> - <var-decl name='tp_traverse' type-id='type-id-91' visibility='default' filepath='./Include/cpython/object.h' line='187' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1536'> - <var-decl name='tp_clear' type-id='type-id-92' visibility='default' filepath='./Include/cpython/object.h' line='190' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1600'> - <var-decl name='tp_richcompare' type-id='type-id-93' visibility='default' filepath='./Include/cpython/object.h' line='194' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1664'> - <var-decl name='tp_weaklistoffset' type-id='type-id-36' visibility='default' filepath='./Include/cpython/object.h' line='197' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1728'> - <var-decl name='tp_iter' type-id='type-id-94' visibility='default' filepath='./Include/cpython/object.h' line='200' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1792'> - <var-decl name='tp_iternext' type-id='type-id-95' visibility='default' filepath='./Include/cpython/object.h' line='201' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1856'> - <var-decl name='tp_methods' type-id='type-id-96' visibility='default' filepath='./Include/cpython/object.h' line='204' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1920'> - <var-decl name='tp_members' type-id='type-id-97' visibility='default' filepath='./Include/cpython/object.h' line='205' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1984'> - <var-decl name='tp_getset' type-id='type-id-98' visibility='default' filepath='./Include/cpython/object.h' line='206' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='2048'> - <var-decl name='tp_base' type-id='type-id-74' visibility='default' filepath='./Include/cpython/object.h' line='208' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='2112'> - <var-decl name='tp_dict' type-id='type-id-14' visibility='default' filepath='./Include/cpython/object.h' line='209' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='2176'> - <var-decl name='tp_descr_get' type-id='type-id-99' visibility='default' filepath='./Include/cpython/object.h' line='210' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='2240'> - <var-decl name='tp_descr_set' type-id='type-id-100' visibility='default' filepath='./Include/cpython/object.h' line='211' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='2304'> - <var-decl name='tp_dictoffset' type-id='type-id-36' visibility='default' filepath='./Include/cpython/object.h' line='212' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='2368'> - <var-decl name='tp_init' type-id='type-id-101' visibility='default' filepath='./Include/cpython/object.h' line='213' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='2432'> - <var-decl name='tp_alloc' type-id='type-id-102' visibility='default' filepath='./Include/cpython/object.h' line='214' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='2496'> - <var-decl name='tp_new' type-id='type-id-103' visibility='default' filepath='./Include/cpython/object.h' line='215' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='2560'> - <var-decl name='tp_free' type-id='type-id-104' visibility='default' filepath='./Include/cpython/object.h' line='216' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='2624'> - <var-decl name='tp_is_gc' type-id='type-id-92' visibility='default' filepath='./Include/cpython/object.h' line='217' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='2688'> - <var-decl name='tp_bases' type-id='type-id-14' visibility='default' filepath='./Include/cpython/object.h' line='218' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='2752'> - <var-decl name='tp_mro' type-id='type-id-14' visibility='default' filepath='./Include/cpython/object.h' line='219' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='2816'> - <var-decl name='tp_cache' type-id='type-id-14' visibility='default' filepath='./Include/cpython/object.h' line='220' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='2880'> - <var-decl name='tp_subclasses' type-id='type-id-14' visibility='default' filepath='./Include/cpython/object.h' line='221' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='2944'> - <var-decl name='tp_weaklist' type-id='type-id-14' visibility='default' filepath='./Include/cpython/object.h' line='222' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='3008'> - <var-decl name='tp_del' type-id='type-id-78' visibility='default' filepath='./Include/cpython/object.h' line='223' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='3072'> - <var-decl name='tp_version_tag' type-id='type-id-105' visibility='default' filepath='./Include/cpython/object.h' line='226' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='3136'> - <var-decl name='tp_finalize' type-id='type-id-78' visibility='default' filepath='./Include/cpython/object.h' line='228' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='3200'> - <var-decl name='tp_vectorcall' type-id='type-id-106' visibility='default' filepath='./Include/cpython/object.h' line='229' column='1'/> - </data-member> - </class-decl> - <class-decl name='__anonymous_struct__' size-in-bits='192' is-struct='yes' is-anonymous='yes' naming-typedef-id='type-id-77' visibility='default' filepath='./Include/object.h' line='109' column='1' id='type-id-107'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='ob_base' type-id='type-id-108' visibility='default' filepath='./Include/object.h' line='110' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='ob_size' type-id='type-id-36' visibility='default' filepath='./Include/object.h' line='111' column='1'/> - </data-member> - </class-decl> - <class-decl name='_object' size-in-bits='128' is-struct='yes' visibility='default' filepath='./Include/object.h' line='100' column='1' id='type-id-109'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='ob_refcnt' type-id='type-id-36' visibility='default' filepath='./Include/object.h' line='102' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='ob_type' type-id='type-id-74' visibility='default' filepath='./Include/object.h' line='103' column='1'/> - </data-member> - </class-decl> - <typedef-decl name='__ssize_t' type-id='type-id-53' filepath='/usr/include/x86_64-linux-gnu/bits/types.h' line='193' column='1' id='type-id-110'/> - <typedef-decl name='ssize_t' type-id='type-id-110' filepath='/usr/include/x86_64-linux-gnu/sys/types.h' line='108' column='1' id='type-id-111'/> - <typedef-decl name='Py_ssize_t' type-id='type-id-111' filepath='./Include/pyport.h' line='131' column='1' id='type-id-36'/> - <typedef-decl name='PyTypeObject' type-id='type-id-76' filepath='./Include/pytypedefs.h' line='20' column='1' id='type-id-112'/> - <pointer-type-def type-id='type-id-112' size-in-bits='64' id='type-id-74'/> - <typedef-decl name='PyObject' type-id='type-id-109' filepath='./Include/pytypedefs.h' line='18' column='1' id='type-id-108'/> - <typedef-decl name='PyVarObject' type-id='type-id-107' filepath='./Include/object.h' line='112' column='1' id='type-id-77'/> - <pointer-type-def type-id='type-id-108' size-in-bits='64' id='type-id-14'/> - <pointer-type-def type-id='type-id-113' size-in-bits='64' id='type-id-114'/> - <typedef-decl name='destructor' type-id='type-id-114' filepath='./Include/object.h' line='213' column='1' id='type-id-78'/> - <pointer-type-def type-id='type-id-1' size-in-bits='64' id='type-id-115'/> - <pointer-type-def type-id='type-id-116' size-in-bits='64' id='type-id-117'/> - <typedef-decl name='getattrfunc' type-id='type-id-117' filepath='./Include/object.h' line='214' column='1' id='type-id-79'/> - <pointer-type-def type-id='type-id-118' size-in-bits='64' id='type-id-119'/> - <typedef-decl name='setattrfunc' type-id='type-id-119' filepath='./Include/object.h' line='216' column='1' id='type-id-80'/> - <class-decl name='__anonymous_struct__' size-in-bits='256' is-struct='yes' is-anonymous='yes' naming-typedef-id='type-id-120' visibility='default' filepath='./Include/cpython/object.h' line='130' column='1' id='type-id-121'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='am_await' type-id='type-id-122' visibility='default' filepath='./Include/cpython/object.h' line='131' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='am_aiter' type-id='type-id-122' visibility='default' filepath='./Include/cpython/object.h' line='132' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='am_anext' type-id='type-id-122' visibility='default' filepath='./Include/cpython/object.h' line='133' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='am_send' type-id='type-id-123' visibility='default' filepath='./Include/cpython/object.h' line='134' column='1'/> - </data-member> - </class-decl> - <pointer-type-def type-id='type-id-124' size-in-bits='64' id='type-id-125'/> - <typedef-decl name='unaryfunc' type-id='type-id-125' filepath='./Include/object.h' line='196' column='1' id='type-id-122'/> - <type-decl name='unnamed-enum-underlying-type' is-anonymous='yes' size-in-bits='32' alignment-in-bits='32' id='type-id-126'/> - <enum-decl name='__anonymous_enum__' is-anonymous='yes' filepath='./Include/object.h' line='676' column='1' id='type-id-127'> - <underlying-type type-id='type-id-126'/> - <enumerator name='PYGEN_RETURN' value='0'/> - <enumerator name='PYGEN_ERROR' value='-1'/> - <enumerator name='PYGEN_NEXT' value='1'/> - </enum-decl> - <typedef-decl name='PySendResult' type-id='type-id-127' filepath='./Include/object.h' line='680' column='1' id='type-id-128'/> - <pointer-type-def type-id='type-id-14' size-in-bits='64' id='type-id-22'/> - <pointer-type-def type-id='type-id-129' size-in-bits='64' id='type-id-130'/> - <typedef-decl name='sendfunc' type-id='type-id-130' filepath='./Include/cpython/object.h' line='128' column='1' id='type-id-123'/> - <typedef-decl name='PyAsyncMethods' type-id='type-id-121' filepath='./Include/cpython/object.h' line='135' column='1' id='type-id-120'/> - <pointer-type-def type-id='type-id-120' size-in-bits='64' id='type-id-81'/> - <typedef-decl name='reprfunc' type-id='type-id-125' filepath='./Include/object.h' line='218' column='1' id='type-id-82'/> - <class-decl name='__anonymous_struct__' size-in-bits='2304' is-struct='yes' is-anonymous='yes' naming-typedef-id='type-id-131' visibility='default' filepath='./Include/cpython/object.h' line='61' column='1' id='type-id-132'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='nb_add' type-id='type-id-133' visibility='default' filepath='./Include/cpython/object.h' line='66' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='nb_subtract' type-id='type-id-133' visibility='default' filepath='./Include/cpython/object.h' line='67' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='nb_multiply' type-id='type-id-133' visibility='default' filepath='./Include/cpython/object.h' line='68' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='nb_remainder' type-id='type-id-133' visibility='default' filepath='./Include/cpython/object.h' line='69' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='256'> - <var-decl name='nb_divmod' type-id='type-id-133' visibility='default' filepath='./Include/cpython/object.h' line='70' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='320'> - <var-decl name='nb_power' type-id='type-id-87' visibility='default' filepath='./Include/cpython/object.h' line='71' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='384'> - <var-decl name='nb_negative' type-id='type-id-122' visibility='default' filepath='./Include/cpython/object.h' line='72' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='448'> - <var-decl name='nb_positive' type-id='type-id-122' visibility='default' filepath='./Include/cpython/object.h' line='73' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='512'> - <var-decl name='nb_absolute' type-id='type-id-122' visibility='default' filepath='./Include/cpython/object.h' line='74' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='576'> - <var-decl name='nb_bool' type-id='type-id-92' visibility='default' filepath='./Include/cpython/object.h' line='75' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='640'> - <var-decl name='nb_invert' type-id='type-id-122' visibility='default' filepath='./Include/cpython/object.h' line='76' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='704'> - <var-decl name='nb_lshift' type-id='type-id-133' visibility='default' filepath='./Include/cpython/object.h' line='77' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='768'> - <var-decl name='nb_rshift' type-id='type-id-133' visibility='default' filepath='./Include/cpython/object.h' line='78' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='832'> - <var-decl name='nb_and' type-id='type-id-133' visibility='default' filepath='./Include/cpython/object.h' line='79' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='896'> - <var-decl name='nb_xor' type-id='type-id-133' visibility='default' filepath='./Include/cpython/object.h' line='80' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='960'> - <var-decl name='nb_or' type-id='type-id-133' visibility='default' filepath='./Include/cpython/object.h' line='81' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1024'> - <var-decl name='nb_int' type-id='type-id-122' visibility='default' filepath='./Include/cpython/object.h' line='82' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1088'> - <var-decl name='nb_reserved' type-id='type-id-18' visibility='default' filepath='./Include/cpython/object.h' line='83' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1152'> - <var-decl name='nb_float' type-id='type-id-122' visibility='default' filepath='./Include/cpython/object.h' line='84' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1216'> - <var-decl name='nb_inplace_add' type-id='type-id-133' visibility='default' filepath='./Include/cpython/object.h' line='86' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1280'> - <var-decl name='nb_inplace_subtract' type-id='type-id-133' visibility='default' filepath='./Include/cpython/object.h' line='87' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1344'> - <var-decl name='nb_inplace_multiply' type-id='type-id-133' visibility='default' filepath='./Include/cpython/object.h' line='88' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1408'> - <var-decl name='nb_inplace_remainder' type-id='type-id-133' visibility='default' filepath='./Include/cpython/object.h' line='89' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1472'> - <var-decl name='nb_inplace_power' type-id='type-id-87' visibility='default' filepath='./Include/cpython/object.h' line='90' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1536'> - <var-decl name='nb_inplace_lshift' type-id='type-id-133' visibility='default' filepath='./Include/cpython/object.h' line='91' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1600'> - <var-decl name='nb_inplace_rshift' type-id='type-id-133' visibility='default' filepath='./Include/cpython/object.h' line='92' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1664'> - <var-decl name='nb_inplace_and' type-id='type-id-133' visibility='default' filepath='./Include/cpython/object.h' line='93' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1728'> - <var-decl name='nb_inplace_xor' type-id='type-id-133' visibility='default' filepath='./Include/cpython/object.h' line='94' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1792'> - <var-decl name='nb_inplace_or' type-id='type-id-133' visibility='default' filepath='./Include/cpython/object.h' line='95' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1856'> - <var-decl name='nb_floor_divide' type-id='type-id-133' visibility='default' filepath='./Include/cpython/object.h' line='97' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1920'> - <var-decl name='nb_true_divide' type-id='type-id-133' visibility='default' filepath='./Include/cpython/object.h' line='98' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1984'> - <var-decl name='nb_inplace_floor_divide' type-id='type-id-133' visibility='default' filepath='./Include/cpython/object.h' line='99' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='2048'> - <var-decl name='nb_inplace_true_divide' type-id='type-id-133' visibility='default' filepath='./Include/cpython/object.h' line='100' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='2112'> - <var-decl name='nb_index' type-id='type-id-122' visibility='default' filepath='./Include/cpython/object.h' line='102' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='2176'> - <var-decl name='nb_matrix_multiply' type-id='type-id-133' visibility='default' filepath='./Include/cpython/object.h' line='104' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='2240'> - <var-decl name='nb_inplace_matrix_multiply' type-id='type-id-133' visibility='default' filepath='./Include/cpython/object.h' line='105' column='1'/> - </data-member> - </class-decl> - <pointer-type-def type-id='type-id-134' size-in-bits='64' id='type-id-135'/> - <typedef-decl name='binaryfunc' type-id='type-id-135' filepath='./Include/object.h' line='197' column='1' id='type-id-133'/> - <pointer-type-def type-id='type-id-136' size-in-bits='64' id='type-id-137'/> - <typedef-decl name='ternaryfunc' type-id='type-id-137' filepath='./Include/object.h' line='198' column='1' id='type-id-87'/> - <pointer-type-def type-id='type-id-138' size-in-bits='64' id='type-id-139'/> - <typedef-decl name='inquiry' type-id='type-id-139' filepath='./Include/object.h' line='199' column='1' id='type-id-92'/> - <typedef-decl name='PyNumberMethods' type-id='type-id-132' filepath='./Include/cpython/object.h' line='106' column='1' id='type-id-131'/> - <pointer-type-def type-id='type-id-131' size-in-bits='64' id='type-id-83'/> - <class-decl name='__anonymous_struct__' size-in-bits='640' is-struct='yes' is-anonymous='yes' naming-typedef-id='type-id-140' visibility='default' filepath='./Include/cpython/object.h' line='108' column='1' id='type-id-141'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='sq_length' type-id='type-id-142' visibility='default' filepath='./Include/cpython/object.h' line='109' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='sq_concat' type-id='type-id-133' visibility='default' filepath='./Include/cpython/object.h' line='110' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='sq_repeat' type-id='type-id-143' visibility='default' filepath='./Include/cpython/object.h' line='111' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='sq_item' type-id='type-id-143' visibility='default' filepath='./Include/cpython/object.h' line='112' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='256'> - <var-decl name='was_sq_slice' type-id='type-id-18' visibility='default' filepath='./Include/cpython/object.h' line='113' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='320'> - <var-decl name='sq_ass_item' type-id='type-id-144' visibility='default' filepath='./Include/cpython/object.h' line='114' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='384'> - <var-decl name='was_sq_ass_slice' type-id='type-id-18' visibility='default' filepath='./Include/cpython/object.h' line='115' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='448'> - <var-decl name='sq_contains' type-id='type-id-145' visibility='default' filepath='./Include/cpython/object.h' line='116' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='512'> - <var-decl name='sq_inplace_concat' type-id='type-id-133' visibility='default' filepath='./Include/cpython/object.h' line='118' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='576'> - <var-decl name='sq_inplace_repeat' type-id='type-id-143' visibility='default' filepath='./Include/cpython/object.h' line='119' column='1'/> - </data-member> - </class-decl> - <pointer-type-def type-id='type-id-146' size-in-bits='64' id='type-id-147'/> - <typedef-decl name='lenfunc' type-id='type-id-147' filepath='./Include/object.h' line='200' column='1' id='type-id-142'/> - <pointer-type-def type-id='type-id-148' size-in-bits='64' id='type-id-149'/> - <typedef-decl name='ssizeargfunc' type-id='type-id-149' filepath='./Include/object.h' line='201' column='1' id='type-id-143'/> - <pointer-type-def type-id='type-id-150' size-in-bits='64' id='type-id-151'/> - <typedef-decl name='ssizeobjargproc' type-id='type-id-151' filepath='./Include/object.h' line='203' column='1' id='type-id-144'/> - <pointer-type-def type-id='type-id-152' size-in-bits='64' id='type-id-153'/> - <typedef-decl name='objobjproc' type-id='type-id-153' filepath='./Include/object.h' line='207' column='1' id='type-id-145'/> - <typedef-decl name='PySequenceMethods' type-id='type-id-141' filepath='./Include/cpython/object.h' line='120' column='1' id='type-id-140'/> - <pointer-type-def type-id='type-id-140' size-in-bits='64' id='type-id-84'/> - <class-decl name='__anonymous_struct__' size-in-bits='192' is-struct='yes' is-anonymous='yes' naming-typedef-id='type-id-154' visibility='default' filepath='./Include/cpython/object.h' line='122' column='1' id='type-id-155'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='mp_length' type-id='type-id-142' visibility='default' filepath='./Include/cpython/object.h' line='123' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='mp_subscript' type-id='type-id-133' visibility='default' filepath='./Include/cpython/object.h' line='124' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='mp_ass_subscript' type-id='type-id-156' visibility='default' filepath='./Include/cpython/object.h' line='125' column='1'/> - </data-member> - </class-decl> - <pointer-type-def type-id='type-id-157' size-in-bits='64' id='type-id-158'/> - <typedef-decl name='objobjargproc' type-id='type-id-158' filepath='./Include/object.h' line='205' column='1' id='type-id-156'/> - <typedef-decl name='PyMappingMethods' type-id='type-id-155' filepath='./Include/cpython/object.h' line='126' column='1' id='type-id-154'/> - <pointer-type-def type-id='type-id-154' size-in-bits='64' id='type-id-85'/> - <typedef-decl name='Py_hash_t' type-id='type-id-36' filepath='./Include/pyport.h' line='145' column='1' id='type-id-159'/> - <pointer-type-def type-id='type-id-160' size-in-bits='64' id='type-id-161'/> - <typedef-decl name='hashfunc' type-id='type-id-161' filepath='./Include/object.h' line='219' column='1' id='type-id-86'/> - <typedef-decl name='getattrofunc' type-id='type-id-135' filepath='./Include/object.h' line='215' column='1' id='type-id-88'/> - <typedef-decl name='setattrofunc' type-id='type-id-158' filepath='./Include/object.h' line='217' column='1' id='type-id-89'/> - <class-decl name='__anonymous_struct__' size-in-bits='128' is-struct='yes' is-anonymous='yes' naming-typedef-id='type-id-162' visibility='default' filepath='./Include/cpython/object.h' line='137' column='1' id='type-id-163'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='bf_getbuffer' type-id='type-id-164' visibility='default' filepath='./Include/cpython/object.h' line='138' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='bf_releasebuffer' type-id='type-id-165' visibility='default' filepath='./Include/cpython/object.h' line='139' column='1'/> - </data-member> - </class-decl> - <class-decl name='__anonymous_struct__' size-in-bits='640' is-struct='yes' is-anonymous='yes' naming-typedef-id='type-id-166' visibility='default' filepath='./Include/pybuffer.h' line='20' column='1' id='type-id-167'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='buf' type-id='type-id-18' visibility='default' filepath='./Include/pybuffer.h' line='21' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='obj' type-id='type-id-14' visibility='default' filepath='./Include/pybuffer.h' line='22' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='len' type-id='type-id-36' visibility='default' filepath='./Include/pybuffer.h' line='23' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='itemsize' type-id='type-id-36' visibility='default' filepath='./Include/pybuffer.h' line='24' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='256'> - <var-decl name='readonly' type-id='type-id-8' visibility='default' filepath='./Include/pybuffer.h' line='26' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='288'> - <var-decl name='ndim' type-id='type-id-8' visibility='default' filepath='./Include/pybuffer.h' line='27' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='320'> - <var-decl name='format' type-id='type-id-115' visibility='default' filepath='./Include/pybuffer.h' line='28' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='384'> - <var-decl name='shape' type-id='type-id-168' visibility='default' filepath='./Include/pybuffer.h' line='29' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='448'> - <var-decl name='strides' type-id='type-id-168' visibility='default' filepath='./Include/pybuffer.h' line='30' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='512'> - <var-decl name='suboffsets' type-id='type-id-168' visibility='default' filepath='./Include/pybuffer.h' line='31' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='576'> - <var-decl name='internal' type-id='type-id-18' visibility='default' filepath='./Include/pybuffer.h' line='32' column='1'/> - </data-member> - </class-decl> - <pointer-type-def type-id='type-id-36' size-in-bits='64' id='type-id-168'/> - <typedef-decl name='Py_buffer' type-id='type-id-167' filepath='./Include/pybuffer.h' line='33' column='1' id='type-id-166'/> - <pointer-type-def type-id='type-id-166' size-in-bits='64' id='type-id-169'/> - <pointer-type-def type-id='type-id-170' size-in-bits='64' id='type-id-171'/> - <typedef-decl name='getbufferproc' type-id='type-id-171' filepath='./Include/cpython/object.h' line='54' column='1' id='type-id-164'/> - <pointer-type-def type-id='type-id-172' size-in-bits='64' id='type-id-173'/> - <typedef-decl name='releasebufferproc' type-id='type-id-173' filepath='./Include/cpython/object.h' line='55' column='1' id='type-id-165'/> - <typedef-decl name='PyBufferProcs' type-id='type-id-163' filepath='./Include/cpython/object.h' line='140' column='1' id='type-id-162'/> - <pointer-type-def type-id='type-id-162' size-in-bits='64' id='type-id-90'/> - <pointer-type-def type-id='type-id-174' size-in-bits='64' id='type-id-175'/> - <typedef-decl name='visitproc' type-id='type-id-175' filepath='./Include/object.h' line='208' column='1' id='type-id-176'/> - <pointer-type-def type-id='type-id-177' size-in-bits='64' id='type-id-178'/> - <typedef-decl name='traverseproc' type-id='type-id-178' filepath='./Include/object.h' line='209' column='1' id='type-id-91'/> - <pointer-type-def type-id='type-id-179' size-in-bits='64' id='type-id-180'/> - <typedef-decl name='richcmpfunc' type-id='type-id-180' filepath='./Include/object.h' line='220' column='1' id='type-id-93'/> - <typedef-decl name='getiterfunc' type-id='type-id-125' filepath='./Include/object.h' line='221' column='1' id='type-id-94'/> - <typedef-decl name='iternextfunc' type-id='type-id-125' filepath='./Include/object.h' line='222' column='1' id='type-id-95'/> - <class-decl name='PyMethodDef' size-in-bits='256' is-struct='yes' visibility='default' filepath='./Include/methodobject.h' line='54' column='1' id='type-id-181'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='ml_name' type-id='type-id-3' visibility='default' filepath='./Include/methodobject.h' line='55' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='ml_meth' type-id='type-id-182' visibility='default' filepath='./Include/methodobject.h' line='56' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='ml_flags' type-id='type-id-8' visibility='default' filepath='./Include/methodobject.h' line='57' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='ml_doc' type-id='type-id-3' visibility='default' filepath='./Include/methodobject.h' line='59' column='1'/> - </data-member> - </class-decl> - <typedef-decl name='PyCFunction' type-id='type-id-135' filepath='./Include/methodobject.h' line='19' column='1' id='type-id-182'/> - <typedef-decl name='PyMethodDef' type-id='type-id-181' filepath='./Include/pytypedefs.h' line='14' column='1' id='type-id-183'/> - <pointer-type-def type-id='type-id-183' size-in-bits='64' id='type-id-96'/> - <class-decl name='PyMemberDef' size-in-bits='320' is-struct='yes' visibility='default' is-declaration-only='yes' id='type-id-184'/> - <typedef-decl name='PyMemberDef' type-id='type-id-184' filepath='./Include/pytypedefs.h' line='16' column='1' id='type-id-185'/> - <pointer-type-def type-id='type-id-185' size-in-bits='64' id='type-id-97'/> - <class-decl name='PyGetSetDef' size-in-bits='320' is-struct='yes' visibility='default' filepath='./Include/descrobject.h' line='11' column='1' id='type-id-186'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='name' type-id='type-id-3' visibility='default' filepath='./Include/descrobject.h' line='12' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='get' type-id='type-id-187' visibility='default' filepath='./Include/descrobject.h' line='13' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='set' type-id='type-id-188' visibility='default' filepath='./Include/descrobject.h' line='14' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='doc' type-id='type-id-3' visibility='default' filepath='./Include/descrobject.h' line='15' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='256'> - <var-decl name='closure' type-id='type-id-18' visibility='default' filepath='./Include/descrobject.h' line='16' column='1'/> - </data-member> - </class-decl> - <pointer-type-def type-id='type-id-189' size-in-bits='64' id='type-id-190'/> - <typedef-decl name='getter' type-id='type-id-190' filepath='./Include/descrobject.h' line='8' column='1' id='type-id-187'/> - <pointer-type-def type-id='type-id-191' size-in-bits='64' id='type-id-192'/> - <typedef-decl name='setter' type-id='type-id-192' filepath='./Include/descrobject.h' line='9' column='1' id='type-id-188'/> - <typedef-decl name='PyGetSetDef' type-id='type-id-186' filepath='./Include/pytypedefs.h' line='15' column='1' id='type-id-193'/> - <pointer-type-def type-id='type-id-193' size-in-bits='64' id='type-id-98'/> - <typedef-decl name='descrgetfunc' type-id='type-id-137' filepath='./Include/object.h' line='223' column='1' id='type-id-99'/> - <typedef-decl name='descrsetfunc' type-id='type-id-158' filepath='./Include/object.h' line='224' column='1' id='type-id-100'/> - <typedef-decl name='initproc' type-id='type-id-158' filepath='./Include/object.h' line='225' column='1' id='type-id-101'/> - <pointer-type-def type-id='type-id-194' size-in-bits='64' id='type-id-195'/> - <typedef-decl name='allocfunc' type-id='type-id-195' filepath='./Include/object.h' line='227' column='1' id='type-id-102'/> - <pointer-type-def type-id='type-id-196' size-in-bits='64' id='type-id-197'/> - <typedef-decl name='newfunc' type-id='type-id-197' filepath='./Include/object.h' line='226' column='1' id='type-id-103'/> - <pointer-type-def type-id='type-id-198' size-in-bits='64' id='type-id-17'/> - <typedef-decl name='freefunc' type-id='type-id-17' filepath='./Include/object.h' line='212' column='1' id='type-id-104'/> - <type-decl name='unsigned int' size-in-bits='32' id='type-id-105'/> - <qualified-type-def type-id='type-id-14' const='yes' id='type-id-199'/> - <pointer-type-def type-id='type-id-199' size-in-bits='64' id='type-id-200'/> - <pointer-type-def type-id='type-id-201' size-in-bits='64' id='type-id-202'/> - <typedef-decl name='vectorcallfunc' type-id='type-id-202' filepath='./Include/cpython/object.h' line='57' column='1' id='type-id-106'/> - <class-decl name='_xid' size-in-bits='320' is-struct='yes' visibility='default' filepath='./Include/cpython/pystate.h' line='316' column='1' id='type-id-203'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='data' type-id='type-id-18' visibility='default' filepath='./Include/cpython/pystate.h' line='320' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='obj' type-id='type-id-14' visibility='default' filepath='./Include/cpython/pystate.h' line='327' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='interp' type-id='type-id-29' visibility='default' filepath='./Include/cpython/pystate.h' line='337' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='new_object' type-id='type-id-204' visibility='default' filepath='./Include/cpython/pystate.h' line='342' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='256'> - <var-decl name='free' type-id='type-id-17' visibility='default' filepath='./Include/cpython/pystate.h' line='352' column='1'/> - </data-member> - </class-decl> - <typedef-decl name='_PyCrossInterpreterData' type-id='type-id-203' filepath='./Include/cpython/pystate.h' line='314' column='1' id='type-id-205'/> - <pointer-type-def type-id='type-id-205' size-in-bits='64' id='type-id-206'/> - <pointer-type-def type-id='type-id-207' size-in-bits='64' id='type-id-204'/> - <pointer-type-def type-id='type-id-208' size-in-bits='64' id='type-id-209'/> - <typedef-decl name='crossinterpdatafunc' type-id='type-id-209' filepath='./Include/cpython/pystate.h' line='363' column='1' id='type-id-75'/> - <pointer-type-def type-id='type-id-73' size-in-bits='64' id='type-id-72'/> - <pointer-type-def type-id='type-id-210' size-in-bits='64' id='type-id-211'/> - - <array-type-def dimensions='1' type-id='type-id-211' size-in-bits='2048' id='type-id-60'> - <subrange length='32' type-id='type-id-16' id='type-id-212'/> - - </array-type-def> - <class-decl name='_ceval_runtime_state' size-in-bits='1728' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='20' column='1' id='type-id-61'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='signals_pending' type-id='type-id-213' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='25' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='gil' type-id='type-id-214' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='26' column='1'/> - </data-member> - </class-decl> - <class-decl name='_Py_atomic_int' size-in-bits='32' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_atomic.h' line='49' column='1' id='type-id-215'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='_value' type-id='type-id-216' visibility='default' filepath='./Include/internal/pycore_atomic.h' line='50' column='1'/> - </data-member> - </class-decl> - <type-decl name='atomic_int' size-in-bits='32' id='type-id-216'/> - <typedef-decl name='_Py_atomic_int' type-id='type-id-215' filepath='./Include/internal/pycore_atomic.h' line='51' column='1' id='type-id-213'/> - <class-decl name='_gil_runtime_state' size-in-bits='1664' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_gil.h' line='23' column='1' id='type-id-214'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='interval' type-id='type-id-16' visibility='default' filepath='./Include/internal/pycore_gil.h' line='25' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='last_holder' type-id='type-id-57' visibility='default' filepath='./Include/internal/pycore_gil.h' line='28' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='locked' type-id='type-id-213' visibility='default' filepath='./Include/internal/pycore_gil.h' line='31' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='switch_number' type-id='type-id-16' visibility='default' filepath='./Include/internal/pycore_gil.h' line='33' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='256'> - <var-decl name='cond' type-id='type-id-217' visibility='default' filepath='./Include/internal/pycore_gil.h' line='37' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='640'> - <var-decl name='mutex' type-id='type-id-218' visibility='default' filepath='./Include/internal/pycore_gil.h' line='38' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='960'> - <var-decl name='switch_cond' type-id='type-id-217' visibility='default' filepath='./Include/internal/pycore_gil.h' line='42' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1344'> - <var-decl name='switch_mutex' type-id='type-id-218' visibility='default' filepath='./Include/internal/pycore_gil.h' line='43' column='1'/> - </data-member> - </class-decl> - <union-decl name='__anonymous_union__' size-in-bits='384' is-anonymous='yes' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h' line='75' column='1' id='type-id-219'> - <data-member access='private'> - <var-decl name='__data' type-id='type-id-220' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h' line='77' column='1'/> - </data-member> - <data-member access='private'> - <var-decl name='__size' type-id='type-id-221' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h' line='78' column='1'/> - </data-member> - <data-member access='private'> - <var-decl name='__align' type-id='type-id-222' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h' line='79' column='1'/> - </data-member> - </union-decl> - <class-decl name='__pthread_cond_s' size-in-bits='384' is-struct='yes' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/thread-shared-types.h' line='92' column='1' id='type-id-220'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='' type-id='type-id-223' visibility='default'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='__g_refs' type-id='type-id-224' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/thread-shared-types.h' line='112' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='__g_size' type-id='type-id-224' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/thread-shared-types.h' line='113' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='256'> - <var-decl name='__g1_orig_size' type-id='type-id-105' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/thread-shared-types.h' line='114' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='288'> - <var-decl name='__wrefs' type-id='type-id-105' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/thread-shared-types.h' line='115' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='320'> - <var-decl name='__g_signals' type-id='type-id-224' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/thread-shared-types.h' line='116' column='1'/> - </data-member> - </class-decl> - <union-decl name='__anonymous_union__' size-in-bits='64' is-anonymous='yes' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/thread-shared-types.h' line='94' column='1' id='type-id-223'> - <data-member access='private'> - <var-decl name='__wseq' type-id='type-id-225' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/thread-shared-types.h' line='96' column='1'/> - </data-member> - <data-member access='private'> - <var-decl name='__wseq32' type-id='type-id-226' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/thread-shared-types.h' line='101' column='1'/> - </data-member> - </union-decl> - <type-decl name='long long unsigned int' size-in-bits='64' id='type-id-225'/> - <class-decl name='__anonymous_struct__' size-in-bits='64' is-struct='yes' is-anonymous='yes' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/thread-shared-types.h' line='97' column='1' id='type-id-226'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='__low' type-id='type-id-105' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/thread-shared-types.h' line='99' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='32'> - <var-decl name='__high' type-id='type-id-105' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/thread-shared-types.h' line='100' column='1'/> - </data-member> - </class-decl> - - <array-type-def dimensions='1' type-id='type-id-105' size-in-bits='64' id='type-id-224'> - <subrange length='2' type-id='type-id-16' id='type-id-227'/> - - </array-type-def> - - <array-type-def dimensions='1' type-id='type-id-1' size-in-bits='384' id='type-id-221'> - <subrange length='48' type-id='type-id-16' id='type-id-228'/> - - </array-type-def> - <type-decl name='long long int' size-in-bits='64' id='type-id-222'/> - <typedef-decl name='pthread_cond_t' type-id='type-id-219' filepath='/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h' line='80' column='1' id='type-id-217'/> - <union-decl name='__anonymous_union__' size-in-bits='320' is-anonymous='yes' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h' line='67' column='1' id='type-id-229'> - <data-member access='private'> - <var-decl name='__data' type-id='type-id-230' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h' line='69' column='1'/> - </data-member> - <data-member access='private'> - <var-decl name='__size' type-id='type-id-231' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h' line='70' column='1'/> - </data-member> - <data-member access='private'> - <var-decl name='__align' type-id='type-id-53' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h' line='71' column='1'/> - </data-member> - </union-decl> - <class-decl name='__pthread_mutex_s' size-in-bits='320' is-struct='yes' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/struct_mutex.h' line='22' column='1' id='type-id-230'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='__lock' type-id='type-id-8' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/struct_mutex.h' line='24' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='32'> - <var-decl name='__count' type-id='type-id-105' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/struct_mutex.h' line='25' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='__owner' type-id='type-id-8' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/struct_mutex.h' line='26' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='96'> - <var-decl name='__nusers' type-id='type-id-105' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/struct_mutex.h' line='28' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='__kind' type-id='type-id-8' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/struct_mutex.h' line='32' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='160'> - <var-decl name='__spins' type-id='type-id-232' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/struct_mutex.h' line='34' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='176'> - <var-decl name='__elision' type-id='type-id-232' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/struct_mutex.h' line='35' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='__list' type-id='type-id-233' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/struct_mutex.h' line='36' column='1'/> - </data-member> - </class-decl> - <type-decl name='short int' size-in-bits='16' id='type-id-232'/> - <class-decl name='__pthread_internal_list' size-in-bits='128' is-struct='yes' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/thread-shared-types.h' line='49' column='1' id='type-id-234'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='__prev' type-id='type-id-235' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/thread-shared-types.h' line='51' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='__next' type-id='type-id-235' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/thread-shared-types.h' line='52' column='1'/> - </data-member> - </class-decl> - <pointer-type-def type-id='type-id-234' size-in-bits='64' id='type-id-235'/> - <typedef-decl name='__pthread_list_t' type-id='type-id-234' filepath='/usr/include/x86_64-linux-gnu/bits/thread-shared-types.h' line='53' column='1' id='type-id-233'/> - - <array-type-def dimensions='1' type-id='type-id-1' size-in-bits='320' id='type-id-231'> - <subrange length='40' type-id='type-id-16' id='type-id-236'/> - - </array-type-def> - <typedef-decl name='pthread_mutex_t' type-id='type-id-229' filepath='/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h' line='72' column='1' id='type-id-218'/> - <class-decl name='_gilstate_runtime_state' size-in-bits='256' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='31' column='1' id='type-id-62'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='check_enabled' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='34' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='tstate_current' type-id='type-id-57' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='37' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='autoInterpreterState' type-id='type-id-11' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='42' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='autoTSSkey' type-id='type-id-237' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='43' column='1'/> - </data-member> - </class-decl> - <class-decl name='_Py_tss_t' size-in-bits='64' is-struct='yes' visibility='default' filepath='./Include/cpython/pythread.h' line='31' column='1' id='type-id-238'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='_is_initialized' type-id='type-id-8' visibility='default' filepath='./Include/cpython/pythread.h' line='32' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='32'> - <var-decl name='_key' type-id='type-id-239' visibility='default' filepath='./Include/cpython/pythread.h' line='33' column='1'/> - </data-member> - </class-decl> - <typedef-decl name='pthread_key_t' type-id='type-id-105' filepath='/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h' line='49' column='1' id='type-id-239'/> - <typedef-decl name='Py_tss_t' type-id='type-id-238' filepath='./Include/pythread.h' line='111' column='1' id='type-id-237'/> - <class-decl name='PyPreConfig' size-in-bits='320' is-struct='yes' visibility='default' filepath='./Include/cpython/initconfig.h' line='47' column='1' id='type-id-240'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='_config_init' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='48' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='32'> - <var-decl name='parse_argv' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='52' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='isolated' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='59' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='96'> - <var-decl name='use_environment' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='64' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='configure_locale' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='68' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='160'> - <var-decl name='coerce_c_locale' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='81' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='coerce_c_locale_warn' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='89' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='224'> - <var-decl name='utf8_mode' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='114' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='256'> - <var-decl name='dev_mode' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='120' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='288'> - <var-decl name='allocator' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='124' column='1'/> - </data-member> - </class-decl> - <typedef-decl name='PyPreConfig' type-id='type-id-240' filepath='./Include/cpython/initconfig.h' line='125' column='1' id='type-id-63'/> - <typedef-decl name='Py_OpenCodeHookFunction' type-id='type-id-190' filepath='./Include/cpython/fileobject.h' line='12' column='1' id='type-id-64'/> - <class-decl name='_Py_AuditHookEntry' size-in-bits='192' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='48' column='1' id='type-id-241'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='next' type-id='type-id-65' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='49' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='hookCFunction' type-id='type-id-242' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='50' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='userData' type-id='type-id-18' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='51' column='1'/> - </data-member> - </class-decl> - <pointer-type-def type-id='type-id-241' size-in-bits='64' id='type-id-65'/> - <pointer-type-def type-id='type-id-243' size-in-bits='64' id='type-id-244'/> - <typedef-decl name='Py_AuditHookFunction' type-id='type-id-244' filepath='./Include/cpython/sysmodule.h' line='10' column='1' id='type-id-242'/> - <typedef-decl name='_Py_AuditHookEntry' type-id='type-id-241' filepath='./Include/internal/pycore_runtime.h' line='52' column='1' id='type-id-245'/> - <class-decl name='_Py_unicode_runtime_ids' size-in-bits='128' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_unicodeobject.h' line='28' column='1' id='type-id-66'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='lock' type-id='type-id-30' visibility='default' filepath='./Include/internal/pycore_unicodeobject.h' line='29' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='next_index' type-id='type-id-36' visibility='default' filepath='./Include/internal/pycore_unicodeobject.h' line='32' column='1'/> - </data-member> - </class-decl> - <class-decl name='_Py_global_objects' size-in-bits='466048' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_global_objects.h' line='28' column='1' id='type-id-67'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='singletons' type-id='type-id-246' visibility='default' filepath='./Include/internal/pycore_global_objects.h' line='47' column='1'/> - </data-member> - </class-decl> - <class-decl name='__anonymous_struct__' size-in-bits='466048' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_global_objects.h' line='29' column='1' id='type-id-246'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='small_ints' type-id='type-id-247' visibility='default' filepath='./Include/internal/pycore_global_objects.h' line='35' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='67072'> - <var-decl name='bytes_empty' type-id='type-id-248' visibility='default' filepath='./Include/internal/pycore_global_objects.h' line='37' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='67392'> - <var-decl name='bytes_characters' type-id='type-id-249' visibility='default' filepath='./Include/internal/pycore_global_objects.h' line='41' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='165696'> - <var-decl name='strings' type-id='type-id-250' visibility='default' filepath='./Include/internal/pycore_global_objects.h' line='43' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='465664'> - <var-decl name='_tuple_empty_gc_not_used' type-id='type-id-251' visibility='default' filepath='./Include/internal/pycore_global_objects.h' line='45' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='465792'> - <var-decl name='tuple_empty' type-id='type-id-252' visibility='default' filepath='./Include/internal/pycore_global_objects.h' line='46' column='1'/> - </data-member> - </class-decl> - <class-decl name='_longobject' size-in-bits='256' is-struct='yes' visibility='default' filepath='./Include/cpython/longintrepr.h' line='79' column='1' id='type-id-253'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='ob_base' type-id='type-id-77' visibility='default' filepath='./Include/cpython/longintrepr.h' line='80' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='ob_digit' type-id='type-id-254' visibility='default' filepath='./Include/cpython/longintrepr.h' line='81' column='1'/> - </data-member> - </class-decl> - <typedef-decl name='__uint32_t' type-id='type-id-105' filepath='/usr/include/x86_64-linux-gnu/bits/types.h' line='42' column='1' id='type-id-255'/> - <typedef-decl name='uint32_t' type-id='type-id-255' filepath='/usr/include/x86_64-linux-gnu/bits/stdint-uintn.h' line='26' column='1' id='type-id-256'/> - <typedef-decl name='digit' type-id='type-id-256' filepath='./Include/cpython/longintrepr.h' line='43' column='1' id='type-id-257'/> - - <array-type-def dimensions='1' type-id='type-id-257' size-in-bits='32' id='type-id-254'> - <subrange length='1' type-id='type-id-16' id='type-id-258'/> - - </array-type-def> - <typedef-decl name='PyLongObject' type-id='type-id-253' filepath='./Include/pytypedefs.h' line='19' column='1' id='type-id-259'/> - - <array-type-def dimensions='1' type-id='type-id-259' size-in-bits='67072' id='type-id-247'> - <subrange length='262' type-id='type-id-16' id='type-id-260'/> - - </array-type-def> - <class-decl name='__anonymous_struct__' size-in-bits='320' is-struct='yes' is-anonymous='yes' naming-typedef-id='type-id-248' visibility='default' filepath='./Include/cpython/bytesobject.h' line='5' column='1' id='type-id-261'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='ob_base' type-id='type-id-77' visibility='default' filepath='./Include/cpython/bytesobject.h' line='6' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='ob_shash' type-id='type-id-159' visibility='default' filepath='./Include/cpython/bytesobject.h' line='7' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='256'> - <var-decl name='ob_sval' type-id='type-id-262' visibility='default' filepath='./Include/cpython/bytesobject.h' line='8' column='1'/> - </data-member> - </class-decl> - - <array-type-def dimensions='1' type-id='type-id-1' size-in-bits='8' id='type-id-262'> - <subrange length='1' type-id='type-id-16' id='type-id-258'/> - - </array-type-def> - <typedef-decl name='PyBytesObject' type-id='type-id-261' filepath='./Include/cpython/bytesobject.h' line='15' column='1' id='type-id-248'/> - <class-decl name='__anonymous_struct__' size-in-bits='384' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_global_objects.h' line='38' column='1' id='type-id-263'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='ob' type-id='type-id-248' visibility='default' filepath='./Include/internal/pycore_global_objects.h' line='39' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='320'> - <var-decl name='eos' type-id='type-id-1' visibility='default' filepath='./Include/internal/pycore_global_objects.h' line='40' column='1'/> - </data-member> - </class-decl> - - <array-type-def dimensions='1' type-id='type-id-263' size-in-bits='98304' id='type-id-249'> - <subrange length='256' type-id='type-id-16' id='type-id-264'/> - - </array-type-def> - <class-decl name='_Py_global_strings' size-in-bits='299968' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='29' column='1' id='type-id-250'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='literals' type-id='type-id-265' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='52' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='10112'> - <var-decl name='identifiers' type-id='type-id-266' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='359' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='160704'> - <var-decl name='ascii' type-id='type-id-267' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='363' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='218048'> - <var-decl name='latin1' type-id='type-id-268' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='367' column='1'/> - </data-member> - </class-decl> - <class-decl name='__anonymous_struct__' size-in-bits='10112' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='30' column='1' id='type-id-265'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='_anon_dictcomp' type-id='type-id-269' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='31' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='512'> - <var-decl name='_anon_genexpr' type-id='type-id-270' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='32' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1024'> - <var-decl name='_anon_lambda' type-id='type-id-271' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='33' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1536'> - <var-decl name='_anon_listcomp' type-id='type-id-269' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='34' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='2048'> - <var-decl name='_anon_module' type-id='type-id-271' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='35' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='2560'> - <var-decl name='_anon_setcomp' type-id='type-id-270' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='36' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='3072'> - <var-decl name='_anon_string' type-id='type-id-271' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='37' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='3584'> - <var-decl name='_anon_unknown' type-id='type-id-270' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='38' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='4096'> - <var-decl name='_close_br' type-id='type-id-272' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='39' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='4544'> - <var-decl name='_comma_sep' type-id='type-id-273' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='40' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='4992'> - <var-decl name='_dbl_close_br' type-id='type-id-273' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='41' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='5440'> - <var-decl name='_dbl_open_br' type-id='type-id-273' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='42' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='5888'> - <var-decl name='_dbl_percent' type-id='type-id-273' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='43' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='6336'> - <var-decl name='_dot' type-id='type-id-272' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='44' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='6784'> - <var-decl name='_dot_locals' type-id='type-id-270' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='45' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='7296'> - <var-decl name='_empty' type-id='type-id-274' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='46' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='7744'> - <var-decl name='_list_err' type-id='type-id-275' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='47' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='8320'> - <var-decl name='_newline' type-id='type-id-272' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='48' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='8768'> - <var-decl name='_open_br' type-id='type-id-272' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='49' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='9216'> - <var-decl name='_percent' type-id='type-id-272' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='50' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='9664'> - <var-decl name='_utf_8' type-id='type-id-276' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='51' column='1'/> - </data-member> - </class-decl> - <class-decl name='__anonymous_struct__' size-in-bits='512' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='31' column='1' id='type-id-269'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='_ascii' type-id='type-id-277' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='31' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='384'> - <var-decl name='_data' type-id='type-id-278' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='31' column='1'/> - </data-member> - </class-decl> - <class-decl name='__anonymous_struct__' size-in-bits='384' is-struct='yes' is-anonymous='yes' naming-typedef-id='type-id-277' visibility='default' filepath='./Include/cpython/unicodeobject.h' line='72' column='1' id='type-id-279'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='ob_base' type-id='type-id-108' visibility='default' filepath='./Include/cpython/unicodeobject.h' line='146' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='length' type-id='type-id-36' visibility='default' filepath='./Include/cpython/unicodeobject.h' line='147' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='hash' type-id='type-id-159' visibility='default' filepath='./Include/cpython/unicodeobject.h' line='148' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='256'> - <var-decl name='state' type-id='type-id-280' visibility='default' filepath='./Include/cpython/unicodeobject.h' line='204' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='320'> - <var-decl name='wstr' type-id='type-id-281' visibility='default' filepath='./Include/cpython/unicodeobject.h' line='205' column='1'/> - </data-member> - </class-decl> - <class-decl name='__anonymous_struct__' size-in-bits='32' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/cpython/unicodeobject.h' line='149' column='1' id='type-id-280'> - <data-member access='public' layout-offset-in-bits='30'> - <var-decl name='interned' type-id='type-id-105' visibility='default' filepath='./Include/cpython/unicodeobject.h' line='158' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='27'> - <var-decl name='kind' type-id='type-id-105' visibility='default' filepath='./Include/cpython/unicodeobject.h' line='186' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='26'> - <var-decl name='compact' type-id='type-id-105' visibility='default' filepath='./Include/cpython/unicodeobject.h' line='191' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='25'> - <var-decl name='ascii' type-id='type-id-105' visibility='default' filepath='./Include/cpython/unicodeobject.h' line='195' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='24'> - <var-decl name='ready' type-id='type-id-105' visibility='default' filepath='./Include/cpython/unicodeobject.h' line='200' column='1'/> - </data-member> - </class-decl> - <typedef-decl name='wchar_t' type-id='type-id-8' filepath='/usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h' line='321' column='1' id='type-id-282'/> - <pointer-type-def type-id='type-id-282' size-in-bits='64' id='type-id-281'/> - <typedef-decl name='PyASCIIObject' type-id='type-id-279' filepath='./Include/cpython/unicodeobject.h' line='206' column='1' id='type-id-277'/> - <type-decl name='unsigned char' size-in-bits='8' id='type-id-283'/> - <typedef-decl name='__uint8_t' type-id='type-id-283' filepath='/usr/include/x86_64-linux-gnu/bits/types.h' line='38' column='1' id='type-id-284'/> - <typedef-decl name='uint8_t' type-id='type-id-284' filepath='/usr/include/x86_64-linux-gnu/bits/stdint-uintn.h' line='24' column='1' id='type-id-285'/> - - <array-type-def dimensions='1' type-id='type-id-285' size-in-bits='88' id='type-id-278'> - <subrange length='11' type-id='type-id-16' id='type-id-286'/> - - </array-type-def> - <class-decl name='__anonymous_struct__' size-in-bits='512' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='32' column='1' id='type-id-270'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='_ascii' type-id='type-id-277' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='32' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='384'> - <var-decl name='_data' type-id='type-id-287' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='32' column='1'/> - </data-member> - </class-decl> - - <array-type-def dimensions='1' type-id='type-id-285' size-in-bits='80' id='type-id-287'> - <subrange length='10' type-id='type-id-16' id='type-id-288'/> - - </array-type-def> - <class-decl name='__anonymous_struct__' size-in-bits='512' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='33' column='1' id='type-id-271'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='_ascii' type-id='type-id-277' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='33' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='384'> - <var-decl name='_data' type-id='type-id-289' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='33' column='1'/> - </data-member> - </class-decl> - - <array-type-def dimensions='1' type-id='type-id-285' size-in-bits='72' id='type-id-289'> - <subrange length='9' type-id='type-id-16' id='type-id-290'/> - - </array-type-def> - <class-decl name='__anonymous_struct__' size-in-bits='448' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='39' column='1' id='type-id-272'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='_ascii' type-id='type-id-277' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='39' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='384'> - <var-decl name='_data' type-id='type-id-291' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='39' column='1'/> - </data-member> - </class-decl> - - <array-type-def dimensions='1' type-id='type-id-285' size-in-bits='16' id='type-id-291'> - <subrange length='2' type-id='type-id-16' id='type-id-227'/> - - </array-type-def> - <class-decl name='__anonymous_struct__' size-in-bits='448' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='40' column='1' id='type-id-273'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='_ascii' type-id='type-id-277' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='40' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='384'> - <var-decl name='_data' type-id='type-id-292' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='40' column='1'/> - </data-member> - </class-decl> - - <array-type-def dimensions='1' type-id='type-id-285' size-in-bits='24' id='type-id-292'> - <subrange length='3' type-id='type-id-16' id='type-id-293'/> - - </array-type-def> - <class-decl name='__anonymous_struct__' size-in-bits='448' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='46' column='1' id='type-id-274'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='_ascii' type-id='type-id-277' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='46' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='384'> - <var-decl name='_data' type-id='type-id-294' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='46' column='1'/> - </data-member> - </class-decl> - - <array-type-def dimensions='1' type-id='type-id-285' size-in-bits='8' id='type-id-294'> - <subrange length='1' type-id='type-id-16' id='type-id-258'/> - - </array-type-def> - <class-decl name='__anonymous_struct__' size-in-bits='576' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='47' column='1' id='type-id-275'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='_ascii' type-id='type-id-277' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='47' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='384'> - <var-decl name='_data' type-id='type-id-295' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='47' column='1'/> - </data-member> - </class-decl> - - <array-type-def dimensions='1' type-id='type-id-285' size-in-bits='192' id='type-id-295'> - <subrange length='24' type-id='type-id-16' id='type-id-296'/> - - </array-type-def> - <class-decl name='__anonymous_struct__' size-in-bits='448' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='51' column='1' id='type-id-276'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='_ascii' type-id='type-id-277' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='51' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='384'> - <var-decl name='_data' type-id='type-id-297' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='51' column='1'/> - </data-member> - </class-decl> - - <array-type-def dimensions='1' type-id='type-id-285' size-in-bits='48' id='type-id-297'> - <subrange length='6' type-id='type-id-16' id='type-id-298'/> - - </array-type-def> - <class-decl name='__anonymous_struct__' size-in-bits='150592' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='54' column='1' id='type-id-266'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='_False' type-id='type-id-276' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='55' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='448'> - <var-decl name='_Py_Repr' type-id='type-id-299' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='56' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='896'> - <var-decl name='_TextIOWrapper' type-id='type-id-300' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='57' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1408'> - <var-decl name='_True' type-id='type-id-301' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='58' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1856'> - <var-decl name='_WarningMessage' type-id='type-id-302' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='59' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='2368'> - <var-decl name='__' type-id='type-id-272' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='60' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='2816'> - <var-decl name='___IOBase_closed' type-id='type-id-303' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='61' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='3328'> - <var-decl name='___abc_tpflags__' type-id='type-id-303' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='62' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='3840'> - <var-decl name='___abs__' type-id='type-id-299' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='63' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='4288'> - <var-decl name='___abstractmethods__' type-id='type-id-304' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='64' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='4864'> - <var-decl name='___add__' type-id='type-id-299' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='65' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='5312'> - <var-decl name='___aenter__' type-id='type-id-269' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='66' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='5824'> - <var-decl name='___aexit__' type-id='type-id-270' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='67' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='6336'> - <var-decl name='___aiter__' type-id='type-id-270' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='68' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='6848'> - <var-decl name='___all__' type-id='type-id-299' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='69' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='7296'> - <var-decl name='___and__' type-id='type-id-299' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='70' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='7744'> - <var-decl name='___anext__' type-id='type-id-270' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='71' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='8256'> - <var-decl name='___annotations__' type-id='type-id-303' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='72' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='8768'> - <var-decl name='___args__' type-id='type-id-271' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='73' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='9280'> - <var-decl name='___await__' type-id='type-id-270' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='74' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='9792'> - <var-decl name='___bases__' type-id='type-id-270' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='75' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='10304'> - <var-decl name='___bool__' type-id='type-id-271' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='76' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='10816'> - <var-decl name='___build_class__' type-id='type-id-303' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='77' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='11328'> - <var-decl name='___builtins__' type-id='type-id-305' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='78' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='11840'> - <var-decl name='___bytes__' type-id='type-id-270' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='79' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='12352'> - <var-decl name='___call__' type-id='type-id-271' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='80' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='12864'> - <var-decl name='___cantrace__' type-id='type-id-305' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='81' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='13376'> - <var-decl name='___class__' type-id='type-id-270' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='82' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='13888'> - <var-decl name='___class_getitem__' type-id='type-id-306' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='83' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='14464'> - <var-decl name='___classcell__' type-id='type-id-300' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='84' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='14976'> - <var-decl name='___complex__' type-id='type-id-307' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='85' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='15488'> - <var-decl name='___contains__' type-id='type-id-305' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='86' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='16000'> - <var-decl name='___copy__' type-id='type-id-271' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='87' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='16512'> - <var-decl name='___del__' type-id='type-id-299' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='88' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='16960'> - <var-decl name='___delattr__' type-id='type-id-307' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='89' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='17472'> - <var-decl name='___delete__' type-id='type-id-269' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='90' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='17984'> - <var-decl name='___delitem__' type-id='type-id-307' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='91' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='18496'> - <var-decl name='___dict__' type-id='type-id-271' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='92' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='19008'> - <var-decl name='___dir__' type-id='type-id-299' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='93' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='19456'> - <var-decl name='___divmod__' type-id='type-id-269' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='94' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='19968'> - <var-decl name='___doc__' type-id='type-id-299' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='95' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='20416'> - <var-decl name='___enter__' type-id='type-id-270' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='96' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='20928'> - <var-decl name='___eq__' type-id='type-id-308' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='97' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='21376'> - <var-decl name='___exit__' type-id='type-id-271' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='98' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='21888'> - <var-decl name='___file__' type-id='type-id-271' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='99' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='22400'> - <var-decl name='___float__' type-id='type-id-270' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='100' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='22912'> - <var-decl name='___floordiv__' type-id='type-id-305' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='101' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='23424'> - <var-decl name='___format__' type-id='type-id-269' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='102' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='23936'> - <var-decl name='___fspath__' type-id='type-id-269' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='103' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='24448'> - <var-decl name='___ge__' type-id='type-id-308' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='104' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='24896'> - <var-decl name='___get__' type-id='type-id-299' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='105' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='25344'> - <var-decl name='___getattr__' type-id='type-id-307' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='106' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='25856'> - <var-decl name='___getattribute__' type-id='type-id-309' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='107' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='26432'> - <var-decl name='___getinitargs__' type-id='type-id-303' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='108' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='26944'> - <var-decl name='___getitem__' type-id='type-id-307' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='109' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='27456'> - <var-decl name='___getnewargs__' type-id='type-id-302' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='110' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='27968'> - <var-decl name='___getnewargs_ex__' type-id='type-id-306' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='111' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='28544'> - <var-decl name='___getstate__' type-id='type-id-305' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='112' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='29056'> - <var-decl name='___gt__' type-id='type-id-308' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='113' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='29504'> - <var-decl name='___hash__' type-id='type-id-271' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='114' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='30016'> - <var-decl name='___iadd__' type-id='type-id-271' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='115' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='30528'> - <var-decl name='___iand__' type-id='type-id-271' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='116' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='31040'> - <var-decl name='___ifloordiv__' type-id='type-id-300' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='117' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='31552'> - <var-decl name='___ilshift__' type-id='type-id-307' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='118' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='32064'> - <var-decl name='___imatmul__' type-id='type-id-307' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='119' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='32576'> - <var-decl name='___imod__' type-id='type-id-271' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='120' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='33088'> - <var-decl name='___import__' type-id='type-id-269' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='121' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='33600'> - <var-decl name='___imul__' type-id='type-id-271' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='122' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='34112'> - <var-decl name='___index__' type-id='type-id-270' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='123' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='34624'> - <var-decl name='___init__' type-id='type-id-271' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='124' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='35136'> - <var-decl name='___init_subclass__' type-id='type-id-306' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='125' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='35712'> - <var-decl name='___instancecheck__' type-id='type-id-306' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='126' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='36288'> - <var-decl name='___int__' type-id='type-id-299' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='127' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='36736'> - <var-decl name='___invert__' type-id='type-id-269' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='128' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='37248'> - <var-decl name='___ior__' type-id='type-id-299' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='129' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='37696'> - <var-decl name='___ipow__' type-id='type-id-271' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='130' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='38208'> - <var-decl name='___irshift__' type-id='type-id-307' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='131' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='38720'> - <var-decl name='___isabstractmethod__' type-id='type-id-310' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='132' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='39296'> - <var-decl name='___isub__' type-id='type-id-271' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='133' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='39808'> - <var-decl name='___iter__' type-id='type-id-271' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='134' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='40320'> - <var-decl name='___itruediv__' type-id='type-id-305' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='135' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='40832'> - <var-decl name='___ixor__' type-id='type-id-271' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='136' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='41344'> - <var-decl name='___le__' type-id='type-id-308' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='137' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='41792'> - <var-decl name='___len__' type-id='type-id-299' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='138' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='42240'> - <var-decl name='___length_hint__' type-id='type-id-303' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='139' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='42752'> - <var-decl name='___lltrace__' type-id='type-id-307' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='140' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='43264'> - <var-decl name='___loader__' type-id='type-id-269' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='141' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='43776'> - <var-decl name='___lshift__' type-id='type-id-269' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='142' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='44288'> - <var-decl name='___lt__' type-id='type-id-308' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='143' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='44736'> - <var-decl name='___main__' type-id='type-id-271' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='144' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='45248'> - <var-decl name='___matmul__' type-id='type-id-269' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='145' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='45760'> - <var-decl name='___missing__' type-id='type-id-307' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='146' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='46272'> - <var-decl name='___mod__' type-id='type-id-299' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='147' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='46720'> - <var-decl name='___module__' type-id='type-id-269' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='148' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='47232'> - <var-decl name='___mro_entries__' type-id='type-id-303' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='149' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='47744'> - <var-decl name='___mul__' type-id='type-id-299' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='150' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='48192'> - <var-decl name='___name__' type-id='type-id-271' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='151' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='48704'> - <var-decl name='___ne__' type-id='type-id-308' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='152' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='49152'> - <var-decl name='___neg__' type-id='type-id-299' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='153' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='49600'> - <var-decl name='___new__' type-id='type-id-299' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='154' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='50048'> - <var-decl name='___newobj__' type-id='type-id-269' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='155' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='50560'> - <var-decl name='___newobj_ex__' type-id='type-id-300' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='156' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='51072'> - <var-decl name='___next__' type-id='type-id-271' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='157' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='51584'> - <var-decl name='___notes__' type-id='type-id-270' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='158' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='52096'> - <var-decl name='___or__' type-id='type-id-308' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='159' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='52544'> - <var-decl name='___orig_class__' type-id='type-id-302' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='160' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='53056'> - <var-decl name='___origin__' type-id='type-id-269' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='161' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='53568'> - <var-decl name='___package__' type-id='type-id-307' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='162' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='54080'> - <var-decl name='___parameters__' type-id='type-id-302' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='163' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='54592'> - <var-decl name='___path__' type-id='type-id-271' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='164' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='55104'> - <var-decl name='___pos__' type-id='type-id-299' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='165' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='55552'> - <var-decl name='___pow__' type-id='type-id-299' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='166' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='56000'> - <var-decl name='___prepare__' type-id='type-id-307' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='167' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='56512'> - <var-decl name='___qualname__' type-id='type-id-305' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='168' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='57024'> - <var-decl name='___radd__' type-id='type-id-271' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='169' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='57536'> - <var-decl name='___rand__' type-id='type-id-271' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='170' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='58048'> - <var-decl name='___rdivmod__' type-id='type-id-307' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='171' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='58560'> - <var-decl name='___reduce__' type-id='type-id-269' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='172' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='59072'> - <var-decl name='___reduce_ex__' type-id='type-id-300' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='173' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='59584'> - <var-decl name='___repr__' type-id='type-id-271' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='174' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='60096'> - <var-decl name='___reversed__' type-id='type-id-305' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='175' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='60608'> - <var-decl name='___rfloordiv__' type-id='type-id-300' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='176' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='61120'> - <var-decl name='___rlshift__' type-id='type-id-307' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='177' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='61632'> - <var-decl name='___rmatmul__' type-id='type-id-307' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='178' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='62144'> - <var-decl name='___rmod__' type-id='type-id-271' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='179' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='62656'> - <var-decl name='___rmul__' type-id='type-id-271' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='180' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='63168'> - <var-decl name='___ror__' type-id='type-id-299' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='181' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='63616'> - <var-decl name='___round__' type-id='type-id-270' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='182' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64128'> - <var-decl name='___rpow__' type-id='type-id-271' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='183' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64640'> - <var-decl name='___rrshift__' type-id='type-id-307' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='184' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='65152'> - <var-decl name='___rshift__' type-id='type-id-269' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='185' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='65664'> - <var-decl name='___rsub__' type-id='type-id-271' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='186' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='66176'> - <var-decl name='___rtruediv__' type-id='type-id-305' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='187' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='66688'> - <var-decl name='___rxor__' type-id='type-id-271' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='188' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='67200'> - <var-decl name='___set__' type-id='type-id-299' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='189' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='67648'> - <var-decl name='___set_name__' type-id='type-id-305' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='190' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='68160'> - <var-decl name='___setattr__' type-id='type-id-307' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='191' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='68672'> - <var-decl name='___setitem__' type-id='type-id-307' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='192' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='69184'> - <var-decl name='___setstate__' type-id='type-id-305' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='193' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='69696'> - <var-decl name='___sizeof__' type-id='type-id-269' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='194' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='70208'> - <var-decl name='___slotnames__' type-id='type-id-300' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='195' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='70720'> - <var-decl name='___slots__' type-id='type-id-270' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='196' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='71232'> - <var-decl name='___spec__' type-id='type-id-271' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='197' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='71744'> - <var-decl name='___str__' type-id='type-id-299' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='198' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='72192'> - <var-decl name='___sub__' type-id='type-id-299' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='199' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='72640'> - <var-decl name='___subclasscheck__' type-id='type-id-306' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='200' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='73216'> - <var-decl name='___subclasshook__' type-id='type-id-309' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='201' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='73792'> - <var-decl name='___truediv__' type-id='type-id-307' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='202' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='74304'> - <var-decl name='___trunc__' type-id='type-id-270' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='203' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='74816'> - <var-decl name='___typing_is_unpacked_typevartuple__' type-id='type-id-311' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='204' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='75520'> - <var-decl name='___typing_prepare_subst__' type-id='type-id-312' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='205' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='76160'> - <var-decl name='___typing_subst__' type-id='type-id-309' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='206' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='76736'> - <var-decl name='___typing_unpacked_tuple_args__' type-id='type-id-313' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='207' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='77376'> - <var-decl name='___warningregistry__' type-id='type-id-304' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='208' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='77952'> - <var-decl name='___weakref__' type-id='type-id-307' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='209' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='78464'> - <var-decl name='___xor__' type-id='type-id-299' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='210' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='78912'> - <var-decl name='__abc_impl' type-id='type-id-270' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='211' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='79424'> - <var-decl name='__annotation' type-id='type-id-307' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='212' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='79936'> - <var-decl name='__blksize' type-id='type-id-271' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='213' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='80448'> - <var-decl name='__bootstrap' type-id='type-id-269' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='214' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='80960'> - <var-decl name='__dealloc_warn' type-id='type-id-300' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='215' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='81472'> - <var-decl name='__finalizing' type-id='type-id-307' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='216' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='81984'> - <var-decl name='__find_and_load' type-id='type-id-302' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='217' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='82496'> - <var-decl name='__fix_up_module' type-id='type-id-302' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='218' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='83008'> - <var-decl name='__get_sourcefile' type-id='type-id-303' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='219' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='83520'> - <var-decl name='__handle_fromlist' type-id='type-id-309' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='220' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='84096'> - <var-decl name='__initializing' type-id='type-id-300' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='221' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='84608'> - <var-decl name='__is_text_encoding' type-id='type-id-306' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='222' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='85184'> - <var-decl name='__lock_unlock_module' type-id='type-id-304' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='223' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='85760'> - <var-decl name='__showwarnmsg' type-id='type-id-305' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='224' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='86272'> - <var-decl name='__shutdown' type-id='type-id-270' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='225' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='86784'> - <var-decl name='__slotnames' type-id='type-id-269' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='226' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='87296'> - <var-decl name='__strptime_time' type-id='type-id-302' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='227' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='87808'> - <var-decl name='__uninitialized_submodules' type-id='type-id-314' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='228' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='88448'> - <var-decl name='__warn_unawaited_coroutine' type-id='type-id-314' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='229' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='89088'> - <var-decl name='__xoptions' type-id='type-id-270' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='230' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='89600'> - <var-decl name='_add' type-id='type-id-315' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='231' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='90048'> - <var-decl name='_append' type-id='type-id-308' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='232' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='90496'> - <var-decl name='_big' type-id='type-id-315' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='233' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='90944'> - <var-decl name='_buffer' type-id='type-id-308' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='234' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='91392'> - <var-decl name='_builtins' type-id='type-id-271' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='235' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='91904'> - <var-decl name='_c_call' type-id='type-id-308' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='236' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='92352'> - <var-decl name='_c_exception' type-id='type-id-307' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='237' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='92864'> - <var-decl name='_c_return' type-id='type-id-271' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='238' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='93376'> - <var-decl name='_call' type-id='type-id-301' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='239' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='93824'> - <var-decl name='_clear' type-id='type-id-276' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='240' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='94272'> - <var-decl name='_close' type-id='type-id-276' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='241' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='94720'> - <var-decl name='_closed' type-id='type-id-308' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='242' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='95168'> - <var-decl name='_code' type-id='type-id-301' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='243' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='95616'> - <var-decl name='_copy' type-id='type-id-301' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='244' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='96064'> - <var-decl name='_copyreg' type-id='type-id-299' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='245' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='96512'> - <var-decl name='_decode' type-id='type-id-308' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='246' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='96960'> - <var-decl name='_default' type-id='type-id-299' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='247' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='97408'> - <var-decl name='_defaultaction' type-id='type-id-300' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='248' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='97920'> - <var-decl name='_dictcomp' type-id='type-id-271' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='249' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='98432'> - <var-decl name='_difference_update' type-id='type-id-306' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='250' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='99008'> - <var-decl name='_dispatch_table' type-id='type-id-302' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='251' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='99520'> - <var-decl name='_displayhook' type-id='type-id-307' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='252' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='100032'> - <var-decl name='_enable' type-id='type-id-308' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='253' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='100480'> - <var-decl name='_encode' type-id='type-id-308' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='254' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='100928'> - <var-decl name='_encoding' type-id='type-id-271' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='255' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='101440'> - <var-decl name='_end_lineno' type-id='type-id-269' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='256' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='101952'> - <var-decl name='_end_offset' type-id='type-id-269' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='257' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='102464'> - <var-decl name='_errors' type-id='type-id-308' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='258' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='102912'> - <var-decl name='_excepthook' type-id='type-id-269' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='259' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='103424'> - <var-decl name='_exception' type-id='type-id-270' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='260' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='103936'> - <var-decl name='_extend' type-id='type-id-308' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='261' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='104384'> - <var-decl name='_filename' type-id='type-id-271' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='262' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='104896'> - <var-decl name='_fileno' type-id='type-id-308' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='263' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='105344'> - <var-decl name='_fillvalue' type-id='type-id-270' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='264' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='105856'> - <var-decl name='_filters' type-id='type-id-299' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='265' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='106304'> - <var-decl name='_find_class' type-id='type-id-269' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='266' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='106816'> - <var-decl name='_flush' type-id='type-id-276' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='267' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='107264'> - <var-decl name='_genexpr' type-id='type-id-299' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='268' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='107712'> - <var-decl name='_get' type-id='type-id-315' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='269' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='108160'> - <var-decl name='_get_source' type-id='type-id-269' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='270' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='108672'> - <var-decl name='_getattr' type-id='type-id-299' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='271' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='109120'> - <var-decl name='_getstate' type-id='type-id-271' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='272' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='109632'> - <var-decl name='_ignore' type-id='type-id-308' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='273' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='110080'> - <var-decl name='_importlib' type-id='type-id-270' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='274' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='110592'> - <var-decl name='_inf' type-id='type-id-315' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='275' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='111040'> - <var-decl name='_intersection' type-id='type-id-305' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='276' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='111552'> - <var-decl name='_isatty' type-id='type-id-308' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='277' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='112000'> - <var-decl name='_isinstance' type-id='type-id-269' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='278' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='112512'> - <var-decl name='_items' type-id='type-id-276' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='279' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='112960'> - <var-decl name='_iter' type-id='type-id-301' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='280' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='113408'> - <var-decl name='_join' type-id='type-id-301' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='281' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='113856'> - <var-decl name='_keys' type-id='type-id-301' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='282' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='114304'> - <var-decl name='_lambda' type-id='type-id-308' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='283' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='114752'> - <var-decl name='_last_traceback' type-id='type-id-302' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='284' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='115264'> - <var-decl name='_last_type' type-id='type-id-270' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='285' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='115776'> - <var-decl name='_last_value' type-id='type-id-269' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='286' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='116288'> - <var-decl name='_latin1' type-id='type-id-308' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='287' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='116736'> - <var-decl name='_len' type-id='type-id-315' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='288' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='117184'> - <var-decl name='_line' type-id='type-id-301' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='289' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='117632'> - <var-decl name='_lineno' type-id='type-id-308' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='290' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='118080'> - <var-decl name='_listcomp' type-id='type-id-271' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='291' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='118592'> - <var-decl name='_little' type-id='type-id-308' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='292' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='119040'> - <var-decl name='_locale' type-id='type-id-308' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='293' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='119488'> - <var-decl name='_match' type-id='type-id-276' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='294' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='119936'> - <var-decl name='_metaclass' type-id='type-id-270' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='295' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='120448'> - <var-decl name='_mode' type-id='type-id-301' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='296' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='120896'> - <var-decl name='_modules' type-id='type-id-299' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='297' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='121344'> - <var-decl name='_mro' type-id='type-id-315' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='298' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='121792'> - <var-decl name='_msg' type-id='type-id-315' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='299' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='122240'> - <var-decl name='_n_fields' type-id='type-id-271' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='300' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='122752'> - <var-decl name='_n_sequence_fields' type-id='type-id-306' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='301' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='123328'> - <var-decl name='_n_unnamed_fields' type-id='type-id-309' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='302' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='123904'> - <var-decl name='_name' type-id='type-id-301' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='303' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='124352'> - <var-decl name='_newlines' type-id='type-id-271' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='304' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='124864'> - <var-decl name='_next' type-id='type-id-301' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='305' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='125312'> - <var-decl name='_obj' type-id='type-id-315' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='306' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='125760'> - <var-decl name='_offset' type-id='type-id-308' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='307' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='126208'> - <var-decl name='_onceregistry' type-id='type-id-305' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='308' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='126720'> - <var-decl name='_opcode' type-id='type-id-308' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='309' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='127168'> - <var-decl name='_open' type-id='type-id-301' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='310' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='127616'> - <var-decl name='_parent' type-id='type-id-308' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='311' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128064'> - <var-decl name='_partial' type-id='type-id-299' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='312' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128512'> - <var-decl name='_path' type-id='type-id-301' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='313' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128960'> - <var-decl name='_peek' type-id='type-id-301' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='314' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='129408'> - <var-decl name='_persistent_id' type-id='type-id-300' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='315' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='129920'> - <var-decl name='_persistent_load' type-id='type-id-303' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='316' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='130432'> - <var-decl name='_print_file_and_line' type-id='type-id-304' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='317' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='131008'> - <var-decl name='_ps1' type-id='type-id-315' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='318' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='131456'> - <var-decl name='_ps2' type-id='type-id-315' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='319' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='131904'> - <var-decl name='_raw' type-id='type-id-315' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='320' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='132352'> - <var-decl name='_read' type-id='type-id-301' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='321' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='132800'> - <var-decl name='_read1' type-id='type-id-276' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='322' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='133248'> - <var-decl name='_readable' type-id='type-id-271' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='323' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='133760'> - <var-decl name='_readall' type-id='type-id-299' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='324' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='134208'> - <var-decl name='_readinto' type-id='type-id-271' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='325' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='134720'> - <var-decl name='_readinto1' type-id='type-id-270' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='326' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='135232'> - <var-decl name='_readline' type-id='type-id-271' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='327' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='135744'> - <var-decl name='_reducer_override' type-id='type-id-309' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='328' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='136320'> - <var-decl name='_reload' type-id='type-id-308' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='329' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='136768'> - <var-decl name='_replace' type-id='type-id-299' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='330' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='137216'> - <var-decl name='_reset' type-id='type-id-276' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='331' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='137664'> - <var-decl name='_return' type-id='type-id-308' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='332' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='138112'> - <var-decl name='_reversed' type-id='type-id-271' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='333' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='138624'> - <var-decl name='_seek' type-id='type-id-301' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='334' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='139072'> - <var-decl name='_seekable' type-id='type-id-271' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='335' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='139584'> - <var-decl name='_send' type-id='type-id-301' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='336' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='140032'> - <var-decl name='_setcomp' type-id='type-id-299' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='337' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='140480'> - <var-decl name='_setstate' type-id='type-id-271' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='338' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='140992'> - <var-decl name='_sort' type-id='type-id-301' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='339' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='141440'> - <var-decl name='_stderr' type-id='type-id-308' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='340' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='141888'> - <var-decl name='_stdin' type-id='type-id-276' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='341' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='142336'> - <var-decl name='_stdout' type-id='type-id-308' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='342' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='142784'> - <var-decl name='_strict' type-id='type-id-308' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='343' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='143232'> - <var-decl name='_symmetric_difference_update' type-id='type-id-316' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='344' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='143872'> - <var-decl name='_tell' type-id='type-id-301' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='345' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='144320'> - <var-decl name='_text' type-id='type-id-301' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='346' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='144768'> - <var-decl name='_threading' type-id='type-id-270' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='347' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='145280'> - <var-decl name='_throw' type-id='type-id-276' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='348' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='145728'> - <var-decl name='_top' type-id='type-id-315' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='349' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='146176'> - <var-decl name='_truncate' type-id='type-id-271' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='350' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='146688'> - <var-decl name='_unraisablehook' type-id='type-id-302' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='351' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='147200'> - <var-decl name='_values' type-id='type-id-308' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='352' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='147648'> - <var-decl name='_version' type-id='type-id-299' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='353' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='148096'> - <var-decl name='_warnings' type-id='type-id-271' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='354' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='148608'> - <var-decl name='_warnoptions' type-id='type-id-307' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='355' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='149120'> - <var-decl name='_writable' type-id='type-id-271' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='356' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='149632'> - <var-decl name='_write' type-id='type-id-276' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='357' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='150080'> - <var-decl name='_zipimporter' type-id='type-id-307' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='358' column='1'/> - </data-member> - </class-decl> - <class-decl name='__anonymous_struct__' size-in-bits='448' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='56' column='1' id='type-id-299'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='_ascii' type-id='type-id-277' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='56' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='384'> - <var-decl name='_data' type-id='type-id-317' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='56' column='1'/> - </data-member> - </class-decl> - - <array-type-def dimensions='1' type-id='type-id-285' size-in-bits='64' id='type-id-317'> - <subrange length='8' type-id='type-id-16' id='type-id-318'/> - - </array-type-def> - <class-decl name='__anonymous_struct__' size-in-bits='512' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='57' column='1' id='type-id-300'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='_ascii' type-id='type-id-277' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='57' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='384'> - <var-decl name='_data' type-id='type-id-319' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='57' column='1'/> - </data-member> - </class-decl> - - <array-type-def dimensions='1' type-id='type-id-285' size-in-bits='112' id='type-id-319'> - <subrange length='14' type-id='type-id-16' id='type-id-320'/> - - </array-type-def> - <class-decl name='__anonymous_struct__' size-in-bits='448' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='58' column='1' id='type-id-301'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='_ascii' type-id='type-id-277' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='58' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='384'> - <var-decl name='_data' type-id='type-id-321' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='58' column='1'/> - </data-member> - </class-decl> - - <array-type-def dimensions='1' type-id='type-id-285' size-in-bits='40' id='type-id-321'> - <subrange length='5' type-id='type-id-16' id='type-id-322'/> - - </array-type-def> - <class-decl name='__anonymous_struct__' size-in-bits='512' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='59' column='1' id='type-id-302'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='_ascii' type-id='type-id-277' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='59' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='384'> - <var-decl name='_data' type-id='type-id-323' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='59' column='1'/> - </data-member> - </class-decl> - - <array-type-def dimensions='1' type-id='type-id-285' size-in-bits='120' id='type-id-323'> - <subrange length='15' type-id='type-id-16' id='type-id-324'/> - - </array-type-def> - <class-decl name='__anonymous_struct__' size-in-bits='512' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='61' column='1' id='type-id-303'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='_ascii' type-id='type-id-277' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='61' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='384'> - <var-decl name='_data' type-id='type-id-325' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='61' column='1'/> - </data-member> - </class-decl> - - <array-type-def dimensions='1' type-id='type-id-285' size-in-bits='128' id='type-id-325'> - <subrange length='16' type-id='type-id-16' id='type-id-326'/> - - </array-type-def> - <class-decl name='__anonymous_struct__' size-in-bits='576' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='64' column='1' id='type-id-304'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='_ascii' type-id='type-id-277' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='64' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='384'> - <var-decl name='_data' type-id='type-id-327' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='64' column='1'/> - </data-member> - </class-decl> - - <array-type-def dimensions='1' type-id='type-id-285' size-in-bits='160' id='type-id-327'> - <subrange length='20' type-id='type-id-16' id='type-id-328'/> - - </array-type-def> - <class-decl name='__anonymous_struct__' size-in-bits='512' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='78' column='1' id='type-id-305'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='_ascii' type-id='type-id-277' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='78' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='384'> - <var-decl name='_data' type-id='type-id-329' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='78' column='1'/> - </data-member> - </class-decl> - - <array-type-def dimensions='1' type-id='type-id-285' size-in-bits='104' id='type-id-329'> - <subrange length='13' type-id='type-id-16' id='type-id-330'/> - - </array-type-def> - <class-decl name='__anonymous_struct__' size-in-bits='576' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='83' column='1' id='type-id-306'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='_ascii' type-id='type-id-277' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='83' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='384'> - <var-decl name='_data' type-id='type-id-331' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='83' column='1'/> - </data-member> - </class-decl> - - <array-type-def dimensions='1' type-id='type-id-285' size-in-bits='144' id='type-id-331'> - <subrange length='18' type-id='type-id-16' id='type-id-332'/> - - </array-type-def> - <class-decl name='__anonymous_struct__' size-in-bits='512' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='85' column='1' id='type-id-307'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='_ascii' type-id='type-id-277' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='85' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='384'> - <var-decl name='_data' type-id='type-id-333' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='85' column='1'/> - </data-member> - </class-decl> - - <array-type-def dimensions='1' type-id='type-id-285' size-in-bits='96' id='type-id-333'> - <subrange length='12' type-id='type-id-16' id='type-id-334'/> - - </array-type-def> - <class-decl name='__anonymous_struct__' size-in-bits='448' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='97' column='1' id='type-id-308'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='_ascii' type-id='type-id-277' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='97' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='384'> - <var-decl name='_data' type-id='type-id-335' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='97' column='1'/> - </data-member> - </class-decl> - - <array-type-def dimensions='1' type-id='type-id-285' size-in-bits='56' id='type-id-335'> - <subrange length='7' type-id='type-id-16' id='type-id-336'/> - - </array-type-def> - <class-decl name='__anonymous_struct__' size-in-bits='576' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='107' column='1' id='type-id-309'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='_ascii' type-id='type-id-277' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='107' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='384'> - <var-decl name='_data' type-id='type-id-337' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='107' column='1'/> - </data-member> - </class-decl> - - <array-type-def dimensions='1' type-id='type-id-285' size-in-bits='136' id='type-id-337'> - <subrange length='17' type-id='type-id-16' id='type-id-338'/> - - </array-type-def> - <class-decl name='__anonymous_struct__' size-in-bits='576' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='132' column='1' id='type-id-310'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='_ascii' type-id='type-id-277' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='132' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='384'> - <var-decl name='_data' type-id='type-id-339' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='132' column='1'/> - </data-member> - </class-decl> - - <array-type-def dimensions='1' type-id='type-id-285' size-in-bits='168' id='type-id-339'> - <subrange length='21' type-id='type-id-16' id='type-id-340'/> - - </array-type-def> - <class-decl name='__anonymous_struct__' size-in-bits='704' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='204' column='1' id='type-id-311'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='_ascii' type-id='type-id-277' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='204' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='384'> - <var-decl name='_data' type-id='type-id-341' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='204' column='1'/> - </data-member> - </class-decl> - - <array-type-def dimensions='1' type-id='type-id-285' size-in-bits='288' id='type-id-341'> - <subrange length='36' type-id='type-id-16' id='type-id-342'/> - - </array-type-def> - <class-decl name='__anonymous_struct__' size-in-bits='640' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='205' column='1' id='type-id-312'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='_ascii' type-id='type-id-277' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='205' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='384'> - <var-decl name='_data' type-id='type-id-343' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='205' column='1'/> - </data-member> - </class-decl> - - <array-type-def dimensions='1' type-id='type-id-285' size-in-bits='200' id='type-id-343'> - <subrange length='25' type-id='type-id-16' id='type-id-344'/> - - </array-type-def> - <class-decl name='__anonymous_struct__' size-in-bits='640' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='207' column='1' id='type-id-313'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='_ascii' type-id='type-id-277' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='207' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='384'> - <var-decl name='_data' type-id='type-id-345' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='207' column='1'/> - </data-member> - </class-decl> - - <array-type-def dimensions='1' type-id='type-id-285' size-in-bits='248' id='type-id-345'> - <subrange length='31' type-id='type-id-16' id='type-id-346'/> - - </array-type-def> - <class-decl name='__anonymous_struct__' size-in-bits='640' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='228' column='1' id='type-id-314'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='_ascii' type-id='type-id-277' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='228' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='384'> - <var-decl name='_data' type-id='type-id-347' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='228' column='1'/> - </data-member> - </class-decl> - - <array-type-def dimensions='1' type-id='type-id-285' size-in-bits='208' id='type-id-347'> - <subrange length='26' type-id='type-id-16' id='type-id-348'/> - - </array-type-def> - <class-decl name='__anonymous_struct__' size-in-bits='448' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='231' column='1' id='type-id-315'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='_ascii' type-id='type-id-277' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='231' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='384'> - <var-decl name='_data' type-id='type-id-349' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='231' column='1'/> - </data-member> - </class-decl> - - <array-type-def dimensions='1' type-id='type-id-285' size-in-bits='32' id='type-id-349'> - <subrange length='4' type-id='type-id-16' id='type-id-350'/> - - </array-type-def> - <class-decl name='__anonymous_struct__' size-in-bits='640' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='344' column='1' id='type-id-316'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='_ascii' type-id='type-id-277' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='344' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='384'> - <var-decl name='_data' type-id='type-id-351' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='344' column='1'/> - </data-member> - </class-decl> - - <array-type-def dimensions='1' type-id='type-id-285' size-in-bits='224' id='type-id-351'> - <subrange length='28' type-id='type-id-16' id='type-id-352'/> - - </array-type-def> - - <array-type-def dimensions='1' type-id='type-id-272' size-in-bits='57344' id='type-id-267'> - <subrange length='128' type-id='type-id-16' id='type-id-353'/> - - </array-type-def> - <class-decl name='__anonymous_struct__' size-in-bits='640' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='364' column='1' id='type-id-354'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='_latin1' type-id='type-id-355' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='365' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='576'> - <var-decl name='_data' type-id='type-id-291' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='366' column='1'/> - </data-member> - </class-decl> - <class-decl name='__anonymous_struct__' size-in-bits='576' is-struct='yes' is-anonymous='yes' naming-typedef-id='type-id-355' visibility='default' filepath='./Include/cpython/unicodeobject.h' line='211' column='1' id='type-id-356'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='_base' type-id='type-id-277' visibility='default' filepath='./Include/cpython/unicodeobject.h' line='212' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='384'> - <var-decl name='utf8_length' type-id='type-id-36' visibility='default' filepath='./Include/cpython/unicodeobject.h' line='213' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='448'> - <var-decl name='utf8' type-id='type-id-115' visibility='default' filepath='./Include/cpython/unicodeobject.h' line='215' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='512'> - <var-decl name='wstr_length' type-id='type-id-36' visibility='default' filepath='./Include/cpython/unicodeobject.h' line='216' column='1'/> - </data-member> - </class-decl> - <typedef-decl name='PyCompactUnicodeObject' type-id='type-id-356' filepath='./Include/cpython/unicodeobject.h' line='218' column='1' id='type-id-355'/> - - <array-type-def dimensions='1' type-id='type-id-354' size-in-bits='81920' id='type-id-268'> - <subrange length='128' type-id='type-id-16' id='type-id-353'/> - - </array-type-def> - <class-decl name='__anonymous_struct__' size-in-bits='128' is-struct='yes' is-anonymous='yes' naming-typedef-id='type-id-251' visibility='default' filepath='./Include/internal/pycore_gc.h' line='12' column='1' id='type-id-357'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='_gc_next' type-id='type-id-358' visibility='default' filepath='./Include/internal/pycore_gc.h' line='15' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='_gc_prev' type-id='type-id-358' visibility='default' filepath='./Include/internal/pycore_gc.h' line='19' column='1'/> - </data-member> - </class-decl> - <typedef-decl name='uintptr_t' type-id='type-id-16' filepath='/usr/include/stdint.h' line='90' column='1' id='type-id-358'/> - <typedef-decl name='PyGC_Head' type-id='type-id-357' filepath='./Include/internal/pycore_gc.h' line='20' column='1' id='type-id-251'/> - <class-decl name='__anonymous_struct__' size-in-bits='256' is-struct='yes' is-anonymous='yes' naming-typedef-id='type-id-252' visibility='default' filepath='./Include/cpython/tupleobject.h' line='5' column='1' id='type-id-359'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='ob_base' type-id='type-id-77' visibility='default' filepath='./Include/cpython/tupleobject.h' line='6' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='ob_item' type-id='type-id-360' visibility='default' filepath='./Include/cpython/tupleobject.h' line='10' column='1'/> - </data-member> - </class-decl> - - <array-type-def dimensions='1' type-id='type-id-14' size-in-bits='64' id='type-id-360'> - <subrange length='1' type-id='type-id-16' id='type-id-258'/> - - </array-type-def> - <typedef-decl name='PyTupleObject' type-id='type-id-359' filepath='./Include/cpython/tupleobject.h' line='11' column='1' id='type-id-252'/> - <pointer-type-def type-id='type-id-56' size-in-bits='64' id='type-id-28'/> - <type-decl name='bool' size-in-bits='8' id='type-id-31'/> - <class-decl name='_ceval_state' size-in-bits='4416' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_interp.h' line='46' column='1' id='type-id-32'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='recursion_limit' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_interp.h' line='47' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='32'> - <var-decl name='eval_breaker' type-id='type-id-213' visibility='default' filepath='./Include/internal/pycore_interp.h' line='50' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='gil_drop_request' type-id='type-id-213' visibility='default' filepath='./Include/internal/pycore_interp.h' line='52' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='pending' type-id='type-id-361' visibility='default' filepath='./Include/internal/pycore_interp.h' line='53' column='1'/> - </data-member> - </class-decl> - <class-decl name='_pending_calls' size-in-bits='4288' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_interp.h' line='29' column='1' id='type-id-361'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='lock' type-id='type-id-30' visibility='default' filepath='./Include/internal/pycore_interp.h' line='30' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='calls_to_do' type-id='type-id-213' visibility='default' filepath='./Include/internal/pycore_interp.h' line='32' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='96'> - <var-decl name='async_exc' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_interp.h' line='36' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='calls' type-id='type-id-362' visibility='default' filepath='./Include/internal/pycore_interp.h' line='41' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='4224'> - <var-decl name='first' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_interp.h' line='42' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='4256'> - <var-decl name='last' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_interp.h' line='43' column='1'/> - </data-member> - </class-decl> - <class-decl name='__anonymous_struct__' size-in-bits='128' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_interp.h' line='38' column='1' id='type-id-363'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='func' type-id='type-id-364' visibility='default' filepath='./Include/internal/pycore_interp.h' line='39' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='arg' type-id='type-id-18' visibility='default' filepath='./Include/internal/pycore_interp.h' line='40' column='1'/> - </data-member> - </class-decl> - <pointer-type-def type-id='type-id-365' size-in-bits='64' id='type-id-364'/> - - <array-type-def dimensions='1' type-id='type-id-363' size-in-bits='4096' id='type-id-362'> - <subrange length='32' type-id='type-id-16' id='type-id-212'/> - - </array-type-def> - <class-decl name='_gc_runtime_state' size-in-bits='1920' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_gc.h' line='131' column='1' id='type-id-33'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='trash_delete_later' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_gc.h' line='134' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='trash_delete_nesting' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_gc.h' line='136' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='96'> - <var-decl name='enabled' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_gc.h' line='139' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='debug' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_gc.h' line='140' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='generations' type-id='type-id-366' visibility='default' filepath='./Include/internal/pycore_gc.h' line='142' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='768'> - <var-decl name='generation0' type-id='type-id-367' visibility='default' filepath='./Include/internal/pycore_gc.h' line='143' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='832'> - <var-decl name='permanent_generation' type-id='type-id-368' visibility='default' filepath='./Include/internal/pycore_gc.h' line='145' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1024'> - <var-decl name='generation_stats' type-id='type-id-369' visibility='default' filepath='./Include/internal/pycore_gc.h' line='146' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1600'> - <var-decl name='collecting' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_gc.h' line='148' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1664'> - <var-decl name='garbage' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_gc.h' line='150' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1728'> - <var-decl name='callbacks' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_gc.h' line='152' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1792'> - <var-decl name='long_lived_total' type-id='type-id-36' visibility='default' filepath='./Include/internal/pycore_gc.h' line='159' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1856'> - <var-decl name='long_lived_pending' type-id='type-id-36' visibility='default' filepath='./Include/internal/pycore_gc.h' line='163' column='1'/> - </data-member> - </class-decl> - <class-decl name='gc_generation' size-in-bits='192' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_gc.h' line='114' column='1' id='type-id-368'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='head' type-id='type-id-251' visibility='default' filepath='./Include/internal/pycore_gc.h' line='115' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='threshold' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_gc.h' line='116' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='160'> - <var-decl name='count' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_gc.h' line='117' column='1'/> - </data-member> - </class-decl> - - <array-type-def dimensions='1' type-id='type-id-368' size-in-bits='576' id='type-id-366'> - <subrange length='3' type-id='type-id-16' id='type-id-293'/> - - </array-type-def> - <pointer-type-def type-id='type-id-251' size-in-bits='64' id='type-id-367'/> - <class-decl name='gc_generation_stats' size-in-bits='192' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_gc.h' line='122' column='1' id='type-id-370'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='collections' type-id='type-id-36' visibility='default' filepath='./Include/internal/pycore_gc.h' line='124' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='collected' type-id='type-id-36' visibility='default' filepath='./Include/internal/pycore_gc.h' line='126' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='uncollectable' type-id='type-id-36' visibility='default' filepath='./Include/internal/pycore_gc.h' line='128' column='1'/> - </data-member> - </class-decl> - - <array-type-def dimensions='1' type-id='type-id-370' size-in-bits='576' id='type-id-369'> - <subrange length='3' type-id='type-id-16' id='type-id-293'/> - - </array-type-def> - <class-decl name='PyConfig' size-in-bits='3392' is-struct='yes' visibility='default' filepath='./Include/cpython/initconfig.h' line='134' column='1' id='type-id-371'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='_config_init' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='135' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='32'> - <var-decl name='isolated' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='137' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='use_environment' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='138' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='96'> - <var-decl name='dev_mode' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='139' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='install_signal_handlers' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='140' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='160'> - <var-decl name='use_hash_seed' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='141' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='hash_seed' type-id='type-id-16' visibility='default' filepath='./Include/cpython/initconfig.h' line='142' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='256'> - <var-decl name='faulthandler' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='143' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='288'> - <var-decl name='tracemalloc' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='144' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='320'> - <var-decl name='import_time' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='145' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='352'> - <var-decl name='code_debug_ranges' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='146' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='384'> - <var-decl name='show_ref_count' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='147' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='416'> - <var-decl name='dump_refs' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='148' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='448'> - <var-decl name='dump_refs_file' type-id='type-id-281' visibility='default' filepath='./Include/cpython/initconfig.h' line='149' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='512'> - <var-decl name='malloc_stats' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='150' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='576'> - <var-decl name='filesystem_encoding' type-id='type-id-281' visibility='default' filepath='./Include/cpython/initconfig.h' line='151' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='640'> - <var-decl name='filesystem_errors' type-id='type-id-281' visibility='default' filepath='./Include/cpython/initconfig.h' line='152' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='704'> - <var-decl name='pycache_prefix' type-id='type-id-281' visibility='default' filepath='./Include/cpython/initconfig.h' line='153' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='768'> - <var-decl name='parse_argv' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='154' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='832'> - <var-decl name='orig_argv' type-id='type-id-372' visibility='default' filepath='./Include/cpython/initconfig.h' line='155' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='960'> - <var-decl name='argv' type-id='type-id-372' visibility='default' filepath='./Include/cpython/initconfig.h' line='156' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1088'> - <var-decl name='xoptions' type-id='type-id-372' visibility='default' filepath='./Include/cpython/initconfig.h' line='157' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1216'> - <var-decl name='warnoptions' type-id='type-id-372' visibility='default' filepath='./Include/cpython/initconfig.h' line='158' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1344'> - <var-decl name='site_import' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='159' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1376'> - <var-decl name='bytes_warning' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='160' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1408'> - <var-decl name='warn_default_encoding' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='161' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1440'> - <var-decl name='inspect' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='162' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1472'> - <var-decl name='interactive' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='163' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1504'> - <var-decl name='optimization_level' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='164' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1536'> - <var-decl name='parser_debug' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='165' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1568'> - <var-decl name='write_bytecode' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='166' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1600'> - <var-decl name='verbose' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='167' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1632'> - <var-decl name='quiet' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='168' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1664'> - <var-decl name='user_site_directory' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='169' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1696'> - <var-decl name='configure_c_stdio' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='170' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1728'> - <var-decl name='buffered_stdio' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='171' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1792'> - <var-decl name='stdio_encoding' type-id='type-id-281' visibility='default' filepath='./Include/cpython/initconfig.h' line='172' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1856'> - <var-decl name='stdio_errors' type-id='type-id-281' visibility='default' filepath='./Include/cpython/initconfig.h' line='173' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1920'> - <var-decl name='check_hash_pycs_mode' type-id='type-id-281' visibility='default' filepath='./Include/cpython/initconfig.h' line='177' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1984'> - <var-decl name='use_frozen_modules' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='178' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='2016'> - <var-decl name='safe_path' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='179' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='2048'> - <var-decl name='pathconfig_warnings' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='182' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='2112'> - <var-decl name='program_name' type-id='type-id-281' visibility='default' filepath='./Include/cpython/initconfig.h' line='183' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='2176'> - <var-decl name='pythonpath_env' type-id='type-id-281' visibility='default' filepath='./Include/cpython/initconfig.h' line='184' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='2240'> - <var-decl name='home' type-id='type-id-281' visibility='default' filepath='./Include/cpython/initconfig.h' line='185' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='2304'> - <var-decl name='platlibdir' type-id='type-id-281' visibility='default' filepath='./Include/cpython/initconfig.h' line='186' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='2368'> - <var-decl name='module_search_paths_set' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='189' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='2432'> - <var-decl name='module_search_paths' type-id='type-id-372' visibility='default' filepath='./Include/cpython/initconfig.h' line='190' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='2560'> - <var-decl name='stdlib_dir' type-id='type-id-281' visibility='default' filepath='./Include/cpython/initconfig.h' line='191' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='2624'> - <var-decl name='executable' type-id='type-id-281' visibility='default' filepath='./Include/cpython/initconfig.h' line='192' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='2688'> - <var-decl name='base_executable' type-id='type-id-281' visibility='default' filepath='./Include/cpython/initconfig.h' line='193' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='2752'> - <var-decl name='prefix' type-id='type-id-281' visibility='default' filepath='./Include/cpython/initconfig.h' line='194' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='2816'> - <var-decl name='base_prefix' type-id='type-id-281' visibility='default' filepath='./Include/cpython/initconfig.h' line='195' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='2880'> - <var-decl name='exec_prefix' type-id='type-id-281' visibility='default' filepath='./Include/cpython/initconfig.h' line='196' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='2944'> - <var-decl name='base_exec_prefix' type-id='type-id-281' visibility='default' filepath='./Include/cpython/initconfig.h' line='197' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='3008'> - <var-decl name='skip_source_first_line' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='200' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='3072'> - <var-decl name='run_command' type-id='type-id-281' visibility='default' filepath='./Include/cpython/initconfig.h' line='201' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='3136'> - <var-decl name='run_module' type-id='type-id-281' visibility='default' filepath='./Include/cpython/initconfig.h' line='202' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='3200'> - <var-decl name='run_filename' type-id='type-id-281' visibility='default' filepath='./Include/cpython/initconfig.h' line='203' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='3264'> - <var-decl name='_install_importlib' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='209' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='3296'> - <var-decl name='_init_main' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='212' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='3328'> - <var-decl name='_isolated_interpreter' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='216' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='3360'> - <var-decl name='_is_python_build' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='219' column='1'/> - </data-member> - </class-decl> - <class-decl name='__anonymous_struct__' size-in-bits='128' is-struct='yes' is-anonymous='yes' naming-typedef-id='type-id-372' visibility='default' filepath='./Include/cpython/initconfig.h' line='31' column='1' id='type-id-373'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='length' type-id='type-id-36' visibility='default' filepath='./Include/cpython/initconfig.h' line='34' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='items' type-id='type-id-374' visibility='default' filepath='./Include/cpython/initconfig.h' line='35' column='1'/> - </data-member> - </class-decl> - <pointer-type-def type-id='type-id-281' size-in-bits='64' id='type-id-374'/> - <typedef-decl name='PyWideStringList' type-id='type-id-373' filepath='./Include/cpython/initconfig.h' line='36' column='1' id='type-id-372'/> - <typedef-decl name='PyConfig' type-id='type-id-371' filepath='./Include/cpython/initconfig.h' line='220' column='1' id='type-id-34'/> - <class-decl name='_PyInterpreterFrame' size-in-bits='640' is-struct='yes' visibility='default' is-declaration-only='yes' id='type-id-375'/> - <pointer-type-def type-id='type-id-375' size-in-bits='64' id='type-id-376'/> - <pointer-type-def type-id='type-id-377' size-in-bits='64' id='type-id-378'/> - <typedef-decl name='_PyFrameEvalFunction' type-id='type-id-378' filepath='./Include/cpython/pystate.h' line='264' column='1' id='type-id-35'/> - - <array-type-def dimensions='1' type-id='type-id-104' size-in-bits='16320' id='type-id-37'> - <subrange length='255' type-id='type-id-16' id='type-id-379'/> - - </array-type-def> - <class-decl name='_warnings_runtime_state' size-in-bits='256' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_warnings.h' line='11' column='1' id='type-id-38'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='filters' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_warnings.h' line='14' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='once_registry' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_warnings.h' line='15' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='default_action' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_warnings.h' line='16' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='filters_version' type-id='type-id-53' visibility='default' filepath='./Include/internal/pycore_warnings.h' line='17' column='1'/> - </data-member> - </class-decl> - <class-decl name='atexit_state' size-in-bits='128' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_interp.h' line='64' column='1' id='type-id-39'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='callbacks' type-id='type-id-380' visibility='default' filepath='./Include/internal/pycore_interp.h' line='65' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='ncallbacks' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_interp.h' line='66' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='96'> - <var-decl name='callback_len' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_interp.h' line='67' column='1'/> - </data-member> - </class-decl> - <class-decl name='__anonymous_struct__' size-in-bits='192' is-struct='yes' is-anonymous='yes' naming-typedef-id='type-id-381' visibility='default' filepath='./Include/internal/pycore_interp.h' line='58' column='1' id='type-id-382'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='func' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_interp.h' line='59' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='args' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_interp.h' line='60' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='kwargs' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_interp.h' line='61' column='1'/> - </data-member> - </class-decl> - <typedef-decl name='atexit_callback' type-id='type-id-382' filepath='./Include/internal/pycore_interp.h' line='62' column='1' id='type-id-381'/> - <pointer-type-def type-id='type-id-381' size-in-bits='64' id='type-id-383'/> - <pointer-type-def type-id='type-id-383' size-in-bits='64' id='type-id-380'/> - <class-decl name='_Py_unicode_state' size-in-bits='384' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_unicodeobject.h' line='49' column='1' id='type-id-40'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='fs_codec' type-id='type-id-384' visibility='default' filepath='./Include/internal/pycore_unicodeobject.h' line='50' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='256'> - <var-decl name='ids' type-id='type-id-385' visibility='default' filepath='./Include/internal/pycore_unicodeobject.h' line='53' column='1'/> - </data-member> - </class-decl> - <class-decl name='_Py_unicode_fs_codec' size-in-bits='256' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_unicodeobject.h' line='37' column='1' id='type-id-384'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='encoding' type-id='type-id-115' visibility='default' filepath='./Include/internal/pycore_unicodeobject.h' line='38' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='utf8' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_unicodeobject.h' line='39' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='errors' type-id='type-id-115' visibility='default' filepath='./Include/internal/pycore_unicodeobject.h' line='40' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='error_handler' type-id='type-id-386' visibility='default' filepath='./Include/internal/pycore_unicodeobject.h' line='41' column='1'/> - </data-member> - </class-decl> - <enum-decl name='__anonymous_enum__' is-anonymous='yes' filepath='./Include/internal/pycore_fileutils.h' line='13' column='1' id='type-id-387'> - <underlying-type type-id='type-id-126'/> - <enumerator name='_Py_ERROR_UNKNOWN' value='0'/> - <enumerator name='_Py_ERROR_STRICT' value='1'/> - <enumerator name='_Py_ERROR_SURROGATEESCAPE' value='2'/> - <enumerator name='_Py_ERROR_REPLACE' value='3'/> - <enumerator name='_Py_ERROR_IGNORE' value='4'/> - <enumerator name='_Py_ERROR_BACKSLASHREPLACE' value='5'/> - <enumerator name='_Py_ERROR_SURROGATEPASS' value='6'/> - <enumerator name='_Py_ERROR_XMLCHARREFREPLACE' value='7'/> - <enumerator name='_Py_ERROR_OTHER' value='8'/> - </enum-decl> - <typedef-decl name='_Py_error_handler' type-id='type-id-387' filepath='./Include/internal/pycore_fileutils.h' line='23' column='1' id='type-id-386'/> - <class-decl name='_Py_unicode_ids' size-in-bits='128' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_unicodeobject.h' line='44' column='1' id='type-id-385'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='size' type-id='type-id-36' visibility='default' filepath='./Include/internal/pycore_unicodeobject.h' line='45' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='array' type-id='type-id-22' visibility='default' filepath='./Include/internal/pycore_unicodeobject.h' line='46' column='1'/> - </data-member> - </class-decl> - <class-decl name='_Py_float_state' size-in-bits='128' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_floatobject.h' line='31' column='1' id='type-id-41'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='numfree' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_floatobject.h' line='36' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='free_list' type-id='type-id-388' visibility='default' filepath='./Include/internal/pycore_floatobject.h' line='37' column='1'/> - </data-member> - </class-decl> - <class-decl name='__anonymous_struct__' size-in-bits='192' is-struct='yes' is-anonymous='yes' naming-typedef-id='type-id-389' visibility='default' filepath='./Include/cpython/floatobject.h' line='5' column='1' id='type-id-390'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='ob_base' type-id='type-id-108' visibility='default' filepath='./Include/cpython/floatobject.h' line='6' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='ob_fval' type-id='type-id-391' visibility='default' filepath='./Include/cpython/floatobject.h' line='7' column='1'/> - </data-member> - </class-decl> - <type-decl name='double' size-in-bits='64' id='type-id-391'/> - <typedef-decl name='PyFloatObject' type-id='type-id-390' filepath='./Include/cpython/floatobject.h' line='8' column='1' id='type-id-389'/> - <pointer-type-def type-id='type-id-389' size-in-bits='64' id='type-id-388'/> - <class-decl name='__anonymous_struct__' size-in-bits='320' is-struct='yes' is-anonymous='yes' naming-typedef-id='type-id-392' visibility='default' filepath='./Include/sliceobject.h' line='22' column='1' id='type-id-393'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='ob_base' type-id='type-id-108' visibility='default' filepath='./Include/sliceobject.h' line='23' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='start' type-id='type-id-14' visibility='default' filepath='./Include/sliceobject.h' line='24' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='stop' type-id='type-id-14' visibility='default' filepath='./Include/sliceobject.h' line='24' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='256'> - <var-decl name='step' type-id='type-id-14' visibility='default' filepath='./Include/sliceobject.h' line='24' column='1'/> - </data-member> - </class-decl> - <typedef-decl name='PySliceObject' type-id='type-id-393' filepath='./Include/sliceobject.h' line='25' column='1' id='type-id-392'/> - <pointer-type-def type-id='type-id-392' size-in-bits='64' id='type-id-42'/> - <class-decl name='_Py_tuple_state' size-in-bits='1920' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_tuple.h' line='48' column='1' id='type-id-43'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='free_list' type-id='type-id-394' visibility='default' filepath='./Include/internal/pycore_tuple.h' line='58' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1280'> - <var-decl name='numfree' type-id='type-id-395' visibility='default' filepath='./Include/internal/pycore_tuple.h' line='59' column='1'/> - </data-member> - </class-decl> - <pointer-type-def type-id='type-id-252' size-in-bits='64' id='type-id-396'/> - - <array-type-def dimensions='1' type-id='type-id-396' size-in-bits='1280' id='type-id-394'> - <subrange length='20' type-id='type-id-16' id='type-id-328'/> - - </array-type-def> - - <array-type-def dimensions='1' type-id='type-id-8' size-in-bits='640' id='type-id-395'> - <subrange length='20' type-id='type-id-16' id='type-id-328'/> - - </array-type-def> - <class-decl name='_Py_list_state' size-in-bits='5184' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_list.h' line='31' column='1' id='type-id-44'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='free_list' type-id='type-id-397' visibility='default' filepath='./Include/internal/pycore_list.h' line='33' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='5120'> - <var-decl name='numfree' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_list.h' line='34' column='1'/> - </data-member> - </class-decl> - <class-decl name='__anonymous_struct__' size-in-bits='320' is-struct='yes' is-anonymous='yes' naming-typedef-id='type-id-398' visibility='default' filepath='./Include/cpython/listobject.h' line='5' column='1' id='type-id-399'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='ob_base' type-id='type-id-77' visibility='default' filepath='./Include/cpython/listobject.h' line='6' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='ob_item' type-id='type-id-22' visibility='default' filepath='./Include/cpython/listobject.h' line='8' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='256'> - <var-decl name='allocated' type-id='type-id-36' visibility='default' filepath='./Include/cpython/listobject.h' line='21' column='1'/> - </data-member> - </class-decl> - <typedef-decl name='PyListObject' type-id='type-id-399' filepath='./Include/cpython/listobject.h' line='22' column='1' id='type-id-398'/> - <pointer-type-def type-id='type-id-398' size-in-bits='64' id='type-id-400'/> - - <array-type-def dimensions='1' type-id='type-id-400' size-in-bits='5120' id='type-id-397'> - <subrange length='80' type-id='type-id-16' id='type-id-401'/> - - </array-type-def> - <class-decl name='_Py_dict_state' size-in-bits='10368' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_dict.h' line='29' column='1' id='type-id-45'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='free_list' type-id='type-id-402' visibility='default' filepath='./Include/internal/pycore_dict.h' line='32' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='5120'> - <var-decl name='numfree' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_dict.h' line='33' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='5184'> - <var-decl name='keys_free_list' type-id='type-id-403' visibility='default' filepath='./Include/internal/pycore_dict.h' line='34' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='10304'> - <var-decl name='keys_numfree' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_dict.h' line='35' column='1'/> - </data-member> - </class-decl> - <class-decl name='__anonymous_struct__' size-in-bits='384' is-struct='yes' is-anonymous='yes' naming-typedef-id='type-id-404' visibility='default' filepath='./Include/cpython/dictobject.h' line='11' column='1' id='type-id-405'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='ob_base' type-id='type-id-108' visibility='default' filepath='./Include/cpython/dictobject.h' line='12' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='ma_used' type-id='type-id-36' visibility='default' filepath='./Include/cpython/dictobject.h' line='15' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='ma_version_tag' type-id='type-id-19' visibility='default' filepath='./Include/cpython/dictobject.h' line='19' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='256'> - <var-decl name='ma_keys' type-id='type-id-406' visibility='default' filepath='./Include/cpython/dictobject.h' line='21' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='320'> - <var-decl name='ma_values' type-id='type-id-407' visibility='default' filepath='./Include/cpython/dictobject.h' line='28' column='1'/> - </data-member> - </class-decl> - <class-decl name='_dictkeysobject' size-in-bits='256' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_dict.h' line='87' column='1' id='type-id-408'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='dk_refcnt' type-id='type-id-36' visibility='default' filepath='./Include/internal/pycore_dict.h' line='88' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='dk_log2_size' type-id='type-id-285' visibility='default' filepath='./Include/internal/pycore_dict.h' line='91' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='72'> - <var-decl name='dk_log2_index_bytes' type-id='type-id-285' visibility='default' filepath='./Include/internal/pycore_dict.h' line='94' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='80'> - <var-decl name='dk_kind' type-id='type-id-285' visibility='default' filepath='./Include/internal/pycore_dict.h' line='97' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='96'> - <var-decl name='dk_version' type-id='type-id-256' visibility='default' filepath='./Include/internal/pycore_dict.h' line='100' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='dk_usable' type-id='type-id-36' visibility='default' filepath='./Include/internal/pycore_dict.h' line='103' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='dk_nentries' type-id='type-id-36' visibility='default' filepath='./Include/internal/pycore_dict.h' line='106' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='256'> - <var-decl name='dk_indices' type-id='type-id-409' visibility='default' filepath='./Include/internal/pycore_dict.h' line='121' column='1'/> - </data-member> - </class-decl> - - <array-type-def dimensions='1' type-id='type-id-1' size-in-bits='infinite' id='type-id-409'> - <subrange length='infinite' type-id='type-id-16' id='type-id-6'/> - - </array-type-def> - <typedef-decl name='PyDictKeysObject' type-id='type-id-408' filepath='./Include/cpython/dictobject.h' line='5' column='1' id='type-id-410'/> - <pointer-type-def type-id='type-id-410' size-in-bits='64' id='type-id-406'/> - <class-decl name='_dictvalues' size-in-bits='64' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_dict.h' line='137' column='1' id='type-id-411'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='values' type-id='type-id-360' visibility='default' filepath='./Include/internal/pycore_dict.h' line='138' column='1'/> - </data-member> - </class-decl> - <typedef-decl name='PyDictValues' type-id='type-id-411' filepath='./Include/cpython/dictobject.h' line='6' column='1' id='type-id-412'/> - <pointer-type-def type-id='type-id-412' size-in-bits='64' id='type-id-407'/> - <typedef-decl name='PyDictObject' type-id='type-id-405' filepath='./Include/cpython/dictobject.h' line='29' column='1' id='type-id-404'/> - <pointer-type-def type-id='type-id-404' size-in-bits='64' id='type-id-413'/> - - <array-type-def dimensions='1' type-id='type-id-413' size-in-bits='5120' id='type-id-402'> - <subrange length='80' type-id='type-id-16' id='type-id-401'/> - - </array-type-def> - - <array-type-def dimensions='1' type-id='type-id-406' size-in-bits='5120' id='type-id-403'> - <subrange length='80' type-id='type-id-16' id='type-id-401'/> - - </array-type-def> - <class-decl name='_Py_async_gen_state' size-in-bits='10368' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_genobject.h' line='31' column='1' id='type-id-46'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='value_freelist' type-id='type-id-414' visibility='default' filepath='./Include/internal/pycore_genobject.h' line='37' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='5120'> - <var-decl name='value_numfree' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_genobject.h' line='38' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='5184'> - <var-decl name='asend_freelist' type-id='type-id-415' visibility='default' filepath='./Include/internal/pycore_genobject.h' line='40' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='10304'> - <var-decl name='asend_numfree' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_genobject.h' line='41' column='1'/> - </data-member> - </class-decl> - <class-decl name='_PyAsyncGenWrappedValue' is-struct='yes' visibility='default' is-declaration-only='yes' id='type-id-416'/> - <pointer-type-def type-id='type-id-416' size-in-bits='64' id='type-id-417'/> - - <array-type-def dimensions='1' type-id='type-id-417' size-in-bits='5120' id='type-id-414'> - <subrange length='80' type-id='type-id-16' id='type-id-401'/> - - </array-type-def> - <class-decl name='PyAsyncGenASend' is-struct='yes' visibility='default' is-declaration-only='yes' id='type-id-418'/> - <pointer-type-def type-id='type-id-418' size-in-bits='64' id='type-id-419'/> - - <array-type-def dimensions='1' type-id='type-id-419' size-in-bits='5120' id='type-id-415'> - <subrange length='80' type-id='type-id-16' id='type-id-401'/> - - </array-type-def> - <class-decl name='_Py_context_state' size-in-bits='128' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_context.h' line='30' column='1' id='type-id-47'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='freelist' type-id='type-id-420' visibility='default' filepath='./Include/internal/pycore_context.h' line='33' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='numfree' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_context.h' line='34' column='1'/> - </data-member> - </class-decl> - <class-decl name='_pycontextobject' size-in-bits='384' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_context.h' line='38' column='1' id='type-id-421'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='ob_base' type-id='type-id-108' visibility='default' filepath='./Include/internal/pycore_context.h' line='39' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='ctx_prev' type-id='type-id-420' visibility='default' filepath='./Include/internal/pycore_context.h' line='40' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='ctx_vars' type-id='type-id-422' visibility='default' filepath='./Include/internal/pycore_context.h' line='41' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='256'> - <var-decl name='ctx_weakreflist' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_context.h' line='42' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='320'> - <var-decl name='ctx_entered' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_context.h' line='43' column='1'/> - </data-member> - </class-decl> - <typedef-decl name='PyContext' type-id='type-id-421' filepath='./Include/cpython/context.h' line='9' column='1' id='type-id-423'/> - <pointer-type-def type-id='type-id-423' size-in-bits='64' id='type-id-420'/> - <class-decl name='__anonymous_struct__' size-in-bits='320' is-struct='yes' is-anonymous='yes' naming-typedef-id='type-id-424' visibility='default' filepath='./Include/internal/pycore_hamt.h' line='48' column='1' id='type-id-425'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='ob_base' type-id='type-id-108' visibility='default' filepath='./Include/internal/pycore_hamt.h' line='49' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='h_root' type-id='type-id-426' visibility='default' filepath='./Include/internal/pycore_hamt.h' line='50' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='h_weakreflist' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_hamt.h' line='51' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='256'> - <var-decl name='h_count' type-id='type-id-36' visibility='default' filepath='./Include/internal/pycore_hamt.h' line='52' column='1'/> - </data-member> - </class-decl> - <class-decl name='__anonymous_struct__' size-in-bits='128' is-struct='yes' is-anonymous='yes' naming-typedef-id='type-id-427' visibility='default' filepath='./Include/internal/pycore_hamt.h' line='42' column='1' id='type-id-428'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='ob_base' type-id='type-id-108' visibility='default' filepath='./Include/internal/pycore_hamt.h' line='43' column='1'/> - </data-member> - </class-decl> - <typedef-decl name='PyHamtNode' type-id='type-id-428' filepath='./Include/internal/pycore_hamt.h' line='44' column='1' id='type-id-427'/> - <pointer-type-def type-id='type-id-427' size-in-bits='64' id='type-id-426'/> - <typedef-decl name='PyHamtObject' type-id='type-id-425' filepath='./Include/internal/pycore_hamt.h' line='53' column='1' id='type-id-424'/> - <pointer-type-def type-id='type-id-424' size-in-bits='64' id='type-id-422'/> - <class-decl name='_Py_exc_state' size-in-bits='256' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_exceptions.h' line='22' column='1' id='type-id-48'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='errnomap' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_exceptions.h' line='24' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='memerrors_freelist' type-id='type-id-429' visibility='default' filepath='./Include/internal/pycore_exceptions.h' line='25' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='memerrors_numfree' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_exceptions.h' line='26' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='PyExc_ExceptionGroup' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_exceptions.h' line='28' column='1'/> - </data-member> - </class-decl> - <class-decl name='__anonymous_struct__' size-in-bits='576' is-struct='yes' is-anonymous='yes' naming-typedef-id='type-id-430' visibility='default' filepath='./Include/cpython/pyerrors.h' line='13' column='1' id='type-id-431'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='ob_base' type-id='type-id-108' visibility='default' filepath='./Include/cpython/pyerrors.h' line='14' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='dict' type-id='type-id-14' visibility='default' filepath='./Include/cpython/pyerrors.h' line='14' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='args' type-id='type-id-14' visibility='default' filepath='./Include/cpython/pyerrors.h' line='14' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='256'> - <var-decl name='notes' type-id='type-id-14' visibility='default' filepath='./Include/cpython/pyerrors.h' line='14' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='320'> - <var-decl name='traceback' type-id='type-id-14' visibility='default' filepath='./Include/cpython/pyerrors.h' line='14' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='384'> - <var-decl name='context' type-id='type-id-14' visibility='default' filepath='./Include/cpython/pyerrors.h' line='14' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='448'> - <var-decl name='cause' type-id='type-id-14' visibility='default' filepath='./Include/cpython/pyerrors.h' line='14' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='512'> - <var-decl name='suppress_context' type-id='type-id-1' visibility='default' filepath='./Include/cpython/pyerrors.h' line='14' column='1'/> - </data-member> - </class-decl> - <typedef-decl name='PyBaseExceptionObject' type-id='type-id-431' filepath='./Include/cpython/pyerrors.h' line='15' column='1' id='type-id-430'/> - <pointer-type-def type-id='type-id-430' size-in-bits='64' id='type-id-429'/> - <class-decl name='ast_state' size-in-bits='15168' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='13' column='1' id='type-id-49'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='initialized' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='14' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='32'> - <var-decl name='recursion_depth' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='15' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='recursion_limit' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='16' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='AST_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='17' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='Add_singleton' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='18' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='256'> - <var-decl name='Add_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='19' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='320'> - <var-decl name='And_singleton' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='20' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='384'> - <var-decl name='And_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='21' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='448'> - <var-decl name='AnnAssign_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='22' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='512'> - <var-decl name='Assert_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='23' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='576'> - <var-decl name='Assign_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='24' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='640'> - <var-decl name='AsyncFor_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='25' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='704'> - <var-decl name='AsyncFunctionDef_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='26' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='768'> - <var-decl name='AsyncWith_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='27' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='832'> - <var-decl name='Attribute_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='28' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='896'> - <var-decl name='AugAssign_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='29' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='960'> - <var-decl name='Await_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='30' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1024'> - <var-decl name='BinOp_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='31' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1088'> - <var-decl name='BitAnd_singleton' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='32' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1152'> - <var-decl name='BitAnd_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='33' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1216'> - <var-decl name='BitOr_singleton' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='34' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1280'> - <var-decl name='BitOr_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='35' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1344'> - <var-decl name='BitXor_singleton' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='36' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1408'> - <var-decl name='BitXor_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='37' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1472'> - <var-decl name='BoolOp_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='38' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1536'> - <var-decl name='Break_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='39' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1600'> - <var-decl name='Call_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='40' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1664'> - <var-decl name='ClassDef_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='41' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1728'> - <var-decl name='Compare_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='42' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1792'> - <var-decl name='Constant_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='43' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1856'> - <var-decl name='Continue_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='44' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1920'> - <var-decl name='Del_singleton' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='45' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1984'> - <var-decl name='Del_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='46' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='2048'> - <var-decl name='Delete_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='47' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='2112'> - <var-decl name='DictComp_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='48' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='2176'> - <var-decl name='Dict_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='49' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='2240'> - <var-decl name='Div_singleton' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='50' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='2304'> - <var-decl name='Div_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='51' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='2368'> - <var-decl name='Eq_singleton' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='52' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='2432'> - <var-decl name='Eq_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='53' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='2496'> - <var-decl name='ExceptHandler_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='54' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='2560'> - <var-decl name='Expr_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='55' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='2624'> - <var-decl name='Expression_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='56' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='2688'> - <var-decl name='FloorDiv_singleton' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='57' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='2752'> - <var-decl name='FloorDiv_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='58' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='2816'> - <var-decl name='For_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='59' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='2880'> - <var-decl name='FormattedValue_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='60' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='2944'> - <var-decl name='FunctionDef_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='61' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='3008'> - <var-decl name='FunctionType_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='62' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='3072'> - <var-decl name='GeneratorExp_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='63' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='3136'> - <var-decl name='Global_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='64' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='3200'> - <var-decl name='GtE_singleton' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='65' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='3264'> - <var-decl name='GtE_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='66' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='3328'> - <var-decl name='Gt_singleton' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='67' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='3392'> - <var-decl name='Gt_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='68' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='3456'> - <var-decl name='IfExp_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='69' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='3520'> - <var-decl name='If_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='70' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='3584'> - <var-decl name='ImportFrom_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='71' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='3648'> - <var-decl name='Import_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='72' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='3712'> - <var-decl name='In_singleton' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='73' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='3776'> - <var-decl name='In_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='74' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='3840'> - <var-decl name='Interactive_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='75' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='3904'> - <var-decl name='Invert_singleton' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='76' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='3968'> - <var-decl name='Invert_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='77' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='4032'> - <var-decl name='IsNot_singleton' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='78' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='4096'> - <var-decl name='IsNot_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='79' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='4160'> - <var-decl name='Is_singleton' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='80' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='4224'> - <var-decl name='Is_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='81' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='4288'> - <var-decl name='JoinedStr_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='82' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='4352'> - <var-decl name='LShift_singleton' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='83' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='4416'> - <var-decl name='LShift_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='84' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='4480'> - <var-decl name='Lambda_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='85' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='4544'> - <var-decl name='ListComp_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='86' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='4608'> - <var-decl name='List_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='87' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='4672'> - <var-decl name='Load_singleton' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='88' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='4736'> - <var-decl name='Load_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='89' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='4800'> - <var-decl name='LtE_singleton' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='90' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='4864'> - <var-decl name='LtE_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='91' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='4928'> - <var-decl name='Lt_singleton' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='92' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='4992'> - <var-decl name='Lt_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='93' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='5056'> - <var-decl name='MatMult_singleton' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='94' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='5120'> - <var-decl name='MatMult_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='95' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='5184'> - <var-decl name='MatchAs_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='96' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='5248'> - <var-decl name='MatchClass_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='97' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='5312'> - <var-decl name='MatchMapping_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='98' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='5376'> - <var-decl name='MatchOr_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='99' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='5440'> - <var-decl name='MatchSequence_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='100' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='5504'> - <var-decl name='MatchSingleton_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='101' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='5568'> - <var-decl name='MatchStar_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='102' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='5632'> - <var-decl name='MatchValue_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='103' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='5696'> - <var-decl name='Match_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='104' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='5760'> - <var-decl name='Mod_singleton' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='105' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='5824'> - <var-decl name='Mod_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='106' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='5888'> - <var-decl name='Module_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='107' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='5952'> - <var-decl name='Mult_singleton' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='108' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='6016'> - <var-decl name='Mult_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='109' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='6080'> - <var-decl name='Name_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='110' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='6144'> - <var-decl name='NamedExpr_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='111' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='6208'> - <var-decl name='Nonlocal_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='112' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='6272'> - <var-decl name='NotEq_singleton' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='113' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='6336'> - <var-decl name='NotEq_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='114' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='6400'> - <var-decl name='NotIn_singleton' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='115' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='6464'> - <var-decl name='NotIn_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='116' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='6528'> - <var-decl name='Not_singleton' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='117' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='6592'> - <var-decl name='Not_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='118' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='6656'> - <var-decl name='Or_singleton' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='119' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='6720'> - <var-decl name='Or_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='120' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='6784'> - <var-decl name='Pass_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='121' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='6848'> - <var-decl name='Pow_singleton' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='122' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='6912'> - <var-decl name='Pow_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='123' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='6976'> - <var-decl name='RShift_singleton' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='124' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='7040'> - <var-decl name='RShift_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='125' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='7104'> - <var-decl name='Raise_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='126' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='7168'> - <var-decl name='Return_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='127' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='7232'> - <var-decl name='SetComp_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='128' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='7296'> - <var-decl name='Set_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='129' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='7360'> - <var-decl name='Slice_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='130' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='7424'> - <var-decl name='Starred_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='131' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='7488'> - <var-decl name='Store_singleton' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='132' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='7552'> - <var-decl name='Store_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='133' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='7616'> - <var-decl name='Sub_singleton' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='134' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='7680'> - <var-decl name='Sub_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='135' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='7744'> - <var-decl name='Subscript_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='136' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='7808'> - <var-decl name='TryStar_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='137' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='7872'> - <var-decl name='Try_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='138' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='7936'> - <var-decl name='Tuple_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='139' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='8000'> - <var-decl name='TypeIgnore_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='140' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='8064'> - <var-decl name='UAdd_singleton' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='141' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='8128'> - <var-decl name='UAdd_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='142' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='8192'> - <var-decl name='USub_singleton' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='143' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='8256'> - <var-decl name='USub_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='144' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='8320'> - <var-decl name='UnaryOp_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='145' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='8384'> - <var-decl name='While_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='146' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='8448'> - <var-decl name='With_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='147' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='8512'> - <var-decl name='YieldFrom_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='148' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='8576'> - <var-decl name='Yield_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='149' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='8640'> - <var-decl name='__dict__' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='150' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='8704'> - <var-decl name='__doc__' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='151' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='8768'> - <var-decl name='__match_args__' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='152' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='8832'> - <var-decl name='__module__' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='153' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='8896'> - <var-decl name='_attributes' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='154' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='8960'> - <var-decl name='_fields' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='155' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='9024'> - <var-decl name='alias_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='156' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='9088'> - <var-decl name='annotation' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='157' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='9152'> - <var-decl name='arg' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='158' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='9216'> - <var-decl name='arg_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='159' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='9280'> - <var-decl name='args' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='160' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='9344'> - <var-decl name='argtypes' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='161' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='9408'> - <var-decl name='arguments_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='162' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='9472'> - <var-decl name='asname' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='163' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='9536'> - <var-decl name='ast' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='164' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='9600'> - <var-decl name='attr' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='165' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='9664'> - <var-decl name='bases' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='166' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='9728'> - <var-decl name='body' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='167' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='9792'> - <var-decl name='boolop_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='168' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='9856'> - <var-decl name='cases' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='169' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='9920'> - <var-decl name='cause' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='170' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='9984'> - <var-decl name='cls' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='171' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='10048'> - <var-decl name='cmpop_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='172' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='10112'> - <var-decl name='col_offset' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='173' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='10176'> - <var-decl name='comparators' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='174' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='10240'> - <var-decl name='comprehension_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='175' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='10304'> - <var-decl name='context_expr' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='176' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='10368'> - <var-decl name='conversion' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='177' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='10432'> - <var-decl name='ctx' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='178' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='10496'> - <var-decl name='decorator_list' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='179' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='10560'> - <var-decl name='defaults' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='180' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='10624'> - <var-decl name='elt' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='181' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='10688'> - <var-decl name='elts' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='182' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='10752'> - <var-decl name='end_col_offset' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='183' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='10816'> - <var-decl name='end_lineno' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='184' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='10880'> - <var-decl name='exc' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='185' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='10944'> - <var-decl name='excepthandler_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='186' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='11008'> - <var-decl name='expr_context_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='187' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='11072'> - <var-decl name='expr_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='188' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='11136'> - <var-decl name='finalbody' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='189' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='11200'> - <var-decl name='format_spec' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='190' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='11264'> - <var-decl name='func' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='191' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='11328'> - <var-decl name='generators' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='192' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='11392'> - <var-decl name='guard' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='193' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='11456'> - <var-decl name='handlers' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='194' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='11520'> - <var-decl name='id' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='195' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='11584'> - <var-decl name='ifs' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='196' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='11648'> - <var-decl name='is_async' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='197' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='11712'> - <var-decl name='items' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='198' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='11776'> - <var-decl name='iter' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='199' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='11840'> - <var-decl name='key' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='200' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='11904'> - <var-decl name='keys' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='201' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='11968'> - <var-decl name='keyword_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='202' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='12032'> - <var-decl name='keywords' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='203' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='12096'> - <var-decl name='kind' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='204' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='12160'> - <var-decl name='kw_defaults' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='205' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='12224'> - <var-decl name='kwarg' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='206' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='12288'> - <var-decl name='kwd_attrs' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='207' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='12352'> - <var-decl name='kwd_patterns' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='208' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='12416'> - <var-decl name='kwonlyargs' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='209' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='12480'> - <var-decl name='left' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='210' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='12544'> - <var-decl name='level' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='211' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='12608'> - <var-decl name='lineno' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='212' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='12672'> - <var-decl name='lower' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='213' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='12736'> - <var-decl name='match_case_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='214' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='12800'> - <var-decl name='mod_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='215' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='12864'> - <var-decl name='module' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='216' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='12928'> - <var-decl name='msg' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='217' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='12992'> - <var-decl name='name' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='218' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='13056'> - <var-decl name='names' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='219' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='13120'> - <var-decl name='op' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='220' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='13184'> - <var-decl name='operand' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='221' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='13248'> - <var-decl name='operator_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='222' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='13312'> - <var-decl name='ops' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='223' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='13376'> - <var-decl name='optional_vars' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='224' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='13440'> - <var-decl name='orelse' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='225' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='13504'> - <var-decl name='pattern' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='226' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='13568'> - <var-decl name='pattern_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='227' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='13632'> - <var-decl name='patterns' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='228' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='13696'> - <var-decl name='posonlyargs' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='229' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='13760'> - <var-decl name='rest' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='230' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='13824'> - <var-decl name='returns' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='231' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='13888'> - <var-decl name='right' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='232' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='13952'> - <var-decl name='simple' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='233' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='14016'> - <var-decl name='slice' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='234' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='14080'> - <var-decl name='step' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='235' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='14144'> - <var-decl name='stmt_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='236' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='14208'> - <var-decl name='subject' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='237' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='14272'> - <var-decl name='tag' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='238' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='14336'> - <var-decl name='target' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='239' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='14400'> - <var-decl name='targets' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='240' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='14464'> - <var-decl name='test' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='241' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='14528'> - <var-decl name='type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='242' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='14592'> - <var-decl name='type_comment' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='243' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='14656'> - <var-decl name='type_ignore_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='244' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='14720'> - <var-decl name='type_ignores' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='245' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='14784'> - <var-decl name='unaryop_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='246' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='14848'> - <var-decl name='upper' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='247' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='14912'> - <var-decl name='value' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='248' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='14976'> - <var-decl name='values' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='249' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='15040'> - <var-decl name='vararg' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='250' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='15104'> - <var-decl name='withitem_type' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='251' column='1'/> - </data-member> - </class-decl> - <class-decl name='type_cache' size-in-bits='786432' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_typeobject.h' line='33' column='1' id='type-id-50'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='hashtable' type-id='type-id-432' visibility='default' filepath='./Include/internal/pycore_typeobject.h' line='34' column='1'/> - </data-member> - </class-decl> - <class-decl name='type_cache_entry' size-in-bits='192' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_typeobject.h' line='24' column='1' id='type-id-433'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='version' type-id='type-id-105' visibility='default' filepath='./Include/internal/pycore_typeobject.h' line='25' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='name' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_typeobject.h' line='26' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='value' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_typeobject.h' line='27' column='1'/> - </data-member> - </class-decl> - - <array-type-def dimensions='1' type-id='type-id-433' size-in-bits='786432' id='type-id-432'> - <subrange length='4096' type-id='type-id-16' id='type-id-434'/> - - </array-type-def> - <class-decl name='callable_cache' size-in-bits='192' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_code.h' line='118' column='1' id='type-id-51'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='isinstance' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_code.h' line='119' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='len' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_code.h' line='120' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='list_append' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_code.h' line='121' column='1'/> - </data-member> - </class-decl> - <class-decl name='_PyCFrame' size-in-bits='192' is-struct='yes' visibility='default' filepath='./Include/cpython/pystate.h' line='38' column='1' id='type-id-435'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='use_tracing' type-id='type-id-285' visibility='default' filepath='./Include/cpython/pystate.h' line='49' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='current_frame' type-id='type-id-376' visibility='default' filepath='./Include/cpython/pystate.h' line='51' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='previous' type-id='type-id-12' visibility='default' filepath='./Include/cpython/pystate.h' line='52' column='1'/> - </data-member> - </class-decl> - <pointer-type-def type-id='type-id-435' size-in-bits='64' id='type-id-12'/> - <typedef-decl name='_PyCFrame' type-id='type-id-435' filepath='./Include/cpython/pystate.h' line='53' column='1' id='type-id-24'/> - <class-decl name='_frame' size-in-bits='448' is-struct='yes' visibility='default' is-declaration-only='yes' id='type-id-436'/> - <typedef-decl name='PyFrameObject' type-id='type-id-436' filepath='./Include/pytypedefs.h' line='22' column='1' id='type-id-437'/> - <pointer-type-def type-id='type-id-437' size-in-bits='64' id='type-id-438'/> - <pointer-type-def type-id='type-id-439' size-in-bits='64' id='type-id-440'/> - <typedef-decl name='Py_tracefunc' type-id='type-id-440' filepath='./Include/cpython/pystate.h' line='14' column='1' id='type-id-13'/> - <class-decl name='_err_stackitem' size-in-bits='128' is-struct='yes' visibility='default' filepath='./Include/cpython/pystate.h' line='55' column='1' id='type-id-441'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='exc_value' type-id='type-id-14' visibility='default' filepath='./Include/cpython/pystate.h' line='69' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='previous_item' type-id='type-id-442' visibility='default' filepath='./Include/cpython/pystate.h' line='71' column='1'/> - </data-member> - </class-decl> - <pointer-type-def type-id='type-id-441' size-in-bits='64' id='type-id-442'/> - <typedef-decl name='_PyErr_StackItem' type-id='type-id-441' filepath='./Include/cpython/pystate.h' line='73' column='1' id='type-id-23'/> - <pointer-type-def type-id='type-id-23' size-in-bits='64' id='type-id-15'/> - <class-decl name='__anonymous_struct__' size-in-bits='384' is-struct='yes' is-anonymous='yes' naming-typedef-id='type-id-20' visibility='default' filepath='./Include/cpython/pystate.h' line='31' column='1' id='type-id-443'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='code' type-id='type-id-444' visibility='default' filepath='./Include/cpython/pystate.h' line='32' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='bounds' type-id='type-id-445' visibility='default' filepath='./Include/cpython/pystate.h' line='33' column='1'/> - </data-member> - </class-decl> - <class-decl name='PyCodeObject' size-in-bits='1536' is-struct='yes' visibility='default' filepath='./Include/cpython/code.h' line='103' column='1' id='type-id-446'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='ob_base' type-id='type-id-77' visibility='default' filepath='./Include/cpython/code.h' line='103' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='co_consts' type-id='type-id-14' visibility='default' filepath='./Include/cpython/code.h' line='103' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='256'> - <var-decl name='co_names' type-id='type-id-14' visibility='default' filepath='./Include/cpython/code.h' line='103' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='320'> - <var-decl name='co_exceptiontable' type-id='type-id-14' visibility='default' filepath='./Include/cpython/code.h' line='103' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='384'> - <var-decl name='co_flags' type-id='type-id-8' visibility='default' filepath='./Include/cpython/code.h' line='103' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='416'> - <var-decl name='co_warmup' type-id='type-id-232' visibility='default' filepath='./Include/cpython/code.h' line='103' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='432'> - <var-decl name='_co_linearray_entry_size' type-id='type-id-232' visibility='default' filepath='./Include/cpython/code.h' line='103' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='448'> - <var-decl name='co_argcount' type-id='type-id-8' visibility='default' filepath='./Include/cpython/code.h' line='103' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='480'> - <var-decl name='co_posonlyargcount' type-id='type-id-8' visibility='default' filepath='./Include/cpython/code.h' line='103' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='512'> - <var-decl name='co_kwonlyargcount' type-id='type-id-8' visibility='default' filepath='./Include/cpython/code.h' line='103' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='544'> - <var-decl name='co_stacksize' type-id='type-id-8' visibility='default' filepath='./Include/cpython/code.h' line='103' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='576'> - <var-decl name='co_firstlineno' type-id='type-id-8' visibility='default' filepath='./Include/cpython/code.h' line='103' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='608'> - <var-decl name='co_nlocalsplus' type-id='type-id-8' visibility='default' filepath='./Include/cpython/code.h' line='103' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='640'> - <var-decl name='co_nlocals' type-id='type-id-8' visibility='default' filepath='./Include/cpython/code.h' line='103' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='672'> - <var-decl name='co_nplaincellvars' type-id='type-id-8' visibility='default' filepath='./Include/cpython/code.h' line='103' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='704'> - <var-decl name='co_ncellvars' type-id='type-id-8' visibility='default' filepath='./Include/cpython/code.h' line='103' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='736'> - <var-decl name='co_nfreevars' type-id='type-id-8' visibility='default' filepath='./Include/cpython/code.h' line='103' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='768'> - <var-decl name='co_localsplusnames' type-id='type-id-14' visibility='default' filepath='./Include/cpython/code.h' line='103' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='832'> - <var-decl name='co_localspluskinds' type-id='type-id-14' visibility='default' filepath='./Include/cpython/code.h' line='103' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='896'> - <var-decl name='co_filename' type-id='type-id-14' visibility='default' filepath='./Include/cpython/code.h' line='103' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='960'> - <var-decl name='co_name' type-id='type-id-14' visibility='default' filepath='./Include/cpython/code.h' line='103' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1024'> - <var-decl name='co_qualname' type-id='type-id-14' visibility='default' filepath='./Include/cpython/code.h' line='103' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1088'> - <var-decl name='co_linetable' type-id='type-id-14' visibility='default' filepath='./Include/cpython/code.h' line='103' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1152'> - <var-decl name='co_weakreflist' type-id='type-id-14' visibility='default' filepath='./Include/cpython/code.h' line='103' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1216'> - <var-decl name='_co_code' type-id='type-id-14' visibility='default' filepath='./Include/cpython/code.h' line='103' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1280'> - <var-decl name='_co_linearray' type-id='type-id-115' visibility='default' filepath='./Include/cpython/code.h' line='103' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1344'> - <var-decl name='_co_firsttraceable' type-id='type-id-8' visibility='default' filepath='./Include/cpython/code.h' line='103' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1408'> - <var-decl name='co_extra' type-id='type-id-18' visibility='default' filepath='./Include/cpython/code.h' line='103' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1472'> - <var-decl name='co_code_adaptive' type-id='type-id-262' visibility='default' filepath='./Include/cpython/code.h' line='103' column='1'/> - </data-member> - </class-decl> - <typedef-decl name='PyCodeObject' type-id='type-id-446' filepath='./Include/pytypedefs.h' line='21' column='1' id='type-id-447'/> - <pointer-type-def type-id='type-id-447' size-in-bits='64' id='type-id-444'/> - <class-decl name='_line_offsets' size-in-bits='320' is-struct='yes' visibility='default' filepath='./Include/cpython/code.h' line='179' column='1' id='type-id-448'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='ar_start' type-id='type-id-8' visibility='default' filepath='./Include/cpython/code.h' line='180' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='32'> - <var-decl name='ar_end' type-id='type-id-8' visibility='default' filepath='./Include/cpython/code.h' line='181' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='ar_line' type-id='type-id-8' visibility='default' filepath='./Include/cpython/code.h' line='182' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='opaque' type-id='type-id-449' visibility='default' filepath='./Include/cpython/code.h' line='183' column='1'/> - </data-member> - </class-decl> - <class-decl name='_opaque' size-in-bits='192' is-struct='yes' visibility='default' filepath='./Include/cpython/code.h' line='173' column='1' id='type-id-449'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='computed_line' type-id='type-id-8' visibility='default' filepath='./Include/cpython/code.h' line='174' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='lo_next' type-id='type-id-450' visibility='default' filepath='./Include/cpython/code.h' line='175' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='limit' type-id='type-id-450' visibility='default' filepath='./Include/cpython/code.h' line='176' column='1'/> - </data-member> - </class-decl> - <qualified-type-def type-id='type-id-285' const='yes' id='type-id-451'/> - <pointer-type-def type-id='type-id-451' size-in-bits='64' id='type-id-450'/> - <typedef-decl name='PyCodeAddressRange' type-id='type-id-448' filepath='./Include/cpython/code.h' line='184' column='1' id='type-id-445'/> - <typedef-decl name='PyTraceInfo' type-id='type-id-443' filepath='./Include/cpython/pystate.h' line='34' column='1' id='type-id-20'/> - <class-decl name='_stack_chunk' size-in-bits='256' is-struct='yes' visibility='default' filepath='./Include/cpython/pystate.h' line='75' column='1' id='type-id-452'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='previous' type-id='type-id-453' visibility='default' filepath='./Include/cpython/pystate.h' line='76' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='size' type-id='type-id-54' visibility='default' filepath='./Include/cpython/pystate.h' line='77' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='top' type-id='type-id-54' visibility='default' filepath='./Include/cpython/pystate.h' line='78' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='data' type-id='type-id-360' visibility='default' filepath='./Include/cpython/pystate.h' line='79' column='1'/> - </data-member> - </class-decl> - <pointer-type-def type-id='type-id-452' size-in-bits='64' id='type-id-453'/> - <typedef-decl name='_PyStackChunk' type-id='type-id-452' filepath='./Include/cpython/pystate.h' line='80' column='1' id='type-id-454'/> - <pointer-type-def type-id='type-id-454' size-in-bits='64' id='type-id-21'/> - <var-decl name='_PyOS_ReadlineTState' type-id='type-id-10' mangled-name='_PyOS_ReadlineTState' visibility='default' filepath='./Include/cpython/pythonrun.h' line='120' column='1' elf-symbol-id='_PyOS_ReadlineTState'/> - <pointer-type-def type-id='type-id-455' size-in-bits='64' id='type-id-456'/> - <var-decl name='PyOS_InputHook' type-id='type-id-456' mangled-name='PyOS_InputHook' visibility='default' filepath='./Include/pythonrun.h' line='18' column='1' elf-symbol-id='PyOS_InputHook'/> - <class-decl name='_IO_FILE' size-in-bits='1728' is-struct='yes' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h' line='49' column='1' id='type-id-457'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='_flags' type-id='type-id-8' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h' line='51' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='_IO_read_ptr' type-id='type-id-115' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h' line='54' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='_IO_read_end' type-id='type-id-115' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h' line='55' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='_IO_read_base' type-id='type-id-115' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h' line='56' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='256'> - <var-decl name='_IO_write_base' type-id='type-id-115' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h' line='57' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='320'> - <var-decl name='_IO_write_ptr' type-id='type-id-115' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h' line='58' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='384'> - <var-decl name='_IO_write_end' type-id='type-id-115' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h' line='59' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='448'> - <var-decl name='_IO_buf_base' type-id='type-id-115' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h' line='60' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='512'> - <var-decl name='_IO_buf_end' type-id='type-id-115' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h' line='61' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='576'> - <var-decl name='_IO_save_base' type-id='type-id-115' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h' line='64' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='640'> - <var-decl name='_IO_backup_base' type-id='type-id-115' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h' line='65' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='704'> - <var-decl name='_IO_save_end' type-id='type-id-115' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h' line='66' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='768'> - <var-decl name='_markers' type-id='type-id-458' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h' line='68' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='832'> - <var-decl name='_chain' type-id='type-id-459' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h' line='70' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='896'> - <var-decl name='_fileno' type-id='type-id-8' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h' line='72' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='928'> - <var-decl name='_flags2' type-id='type-id-8' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h' line='73' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='960'> - <var-decl name='_old_offset' type-id='type-id-460' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h' line='74' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1024'> - <var-decl name='_cur_column' type-id='type-id-461' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h' line='77' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1040'> - <var-decl name='_vtable_offset' type-id='type-id-462' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h' line='78' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1048'> - <var-decl name='_shortbuf' type-id='type-id-262' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h' line='79' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1088'> - <var-decl name='_lock' type-id='type-id-463' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h' line='81' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1152'> - <var-decl name='_offset' type-id='type-id-464' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h' line='89' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1216'> - <var-decl name='_codecvt' type-id='type-id-465' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h' line='91' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1280'> - <var-decl name='_wide_data' type-id='type-id-466' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h' line='92' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1344'> - <var-decl name='_freeres_list' type-id='type-id-459' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h' line='93' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1408'> - <var-decl name='_freeres_buf' type-id='type-id-18' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h' line='94' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1472'> - <var-decl name='__pad5' type-id='type-id-54' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h' line='95' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1536'> - <var-decl name='_mode' type-id='type-id-8' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h' line='96' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1568'> - <var-decl name='_unused2' type-id='type-id-467' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h' line='98' column='1'/> - </data-member> - </class-decl> - <class-decl name='_IO_marker' is-struct='yes' visibility='default' is-declaration-only='yes' id='type-id-468'/> - <pointer-type-def type-id='type-id-468' size-in-bits='64' id='type-id-458'/> - <pointer-type-def type-id='type-id-457' size-in-bits='64' id='type-id-459'/> - <typedef-decl name='__off_t' type-id='type-id-53' filepath='/usr/include/x86_64-linux-gnu/bits/types.h' line='152' column='1' id='type-id-460'/> - <type-decl name='unsigned short int' size-in-bits='16' id='type-id-461'/> - <type-decl name='signed char' size-in-bits='8' id='type-id-462'/> - <typedef-decl name='_IO_lock_t' type-id='type-id-70' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h' line='43' column='1' id='type-id-469'/> - <pointer-type-def type-id='type-id-469' size-in-bits='64' id='type-id-463'/> - <typedef-decl name='__off64_t' type-id='type-id-53' filepath='/usr/include/x86_64-linux-gnu/bits/types.h' line='153' column='1' id='type-id-464'/> - <class-decl name='_IO_codecvt' is-struct='yes' visibility='default' is-declaration-only='yes' id='type-id-470'/> - <pointer-type-def type-id='type-id-470' size-in-bits='64' id='type-id-465'/> - <class-decl name='_IO_wide_data' is-struct='yes' visibility='default' is-declaration-only='yes' id='type-id-471'/> - <pointer-type-def type-id='type-id-471' size-in-bits='64' id='type-id-466'/> - - <array-type-def dimensions='1' type-id='type-id-1' size-in-bits='160' id='type-id-467'> - <subrange length='20' type-id='type-id-16' id='type-id-328'/> - - </array-type-def> - <typedef-decl name='FILE' type-id='type-id-457' filepath='/usr/include/x86_64-linux-gnu/bits/types/FILE.h' line='7' column='1' id='type-id-472'/> - <pointer-type-def type-id='type-id-472' size-in-bits='64' id='type-id-473'/> - <pointer-type-def type-id='type-id-474' size-in-bits='64' id='type-id-475'/> - <var-decl name='PyOS_ReadlineFunctionPointer' type-id='type-id-475' mangled-name='PyOS_ReadlineFunctionPointer' visibility='default' filepath='./Include/cpython/pythonrun.h' line='121' column='1' elf-symbol-id='PyOS_ReadlineFunctionPointer'/> - <function-decl name='PyOS_Readline' mangled-name='PyOS_Readline' filepath='Parser/myreadline.c' line='355' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyOS_Readline'> - <parameter type-id='type-id-473' name='sys_stdin' filepath='Parser/myreadline.c' line='355' column='1'/> - <parameter type-id='type-id-473' name='sys_stdout' filepath='Parser/myreadline.c' line='355' column='1'/> - <parameter type-id='type-id-3' name='prompt' filepath='Parser/myreadline.c' line='355' column='1'/> - <return type-id='type-id-115'/> - </function-decl> - <function-type size-in-bits='64' id='type-id-124'> - <parameter type-id='type-id-14'/> - <return type-id='type-id-14'/> - </function-type> - <function-type size-in-bits='64' id='type-id-201'> - <parameter type-id='type-id-14'/> - <parameter type-id='type-id-200'/> - <parameter type-id='type-id-54'/> - <parameter type-id='type-id-14'/> - <return type-id='type-id-14'/> - </function-type> - <function-type size-in-bits='64' id='type-id-134'> - <parameter type-id='type-id-14'/> - <parameter type-id='type-id-14'/> - <return type-id='type-id-14'/> - </function-type> - <function-type size-in-bits='64' id='type-id-136'> - <parameter type-id='type-id-14'/> - <parameter type-id='type-id-14'/> - <parameter type-id='type-id-14'/> - <return type-id='type-id-14'/> - </function-type> - <function-type size-in-bits='64' id='type-id-179'> - <parameter type-id='type-id-14'/> - <parameter type-id='type-id-14'/> - <parameter type-id='type-id-8'/> - <return type-id='type-id-14'/> - </function-type> - <function-type size-in-bits='64' id='type-id-116'> - <parameter type-id='type-id-14'/> - <parameter type-id='type-id-115'/> - <return type-id='type-id-14'/> - </function-type> - <function-type size-in-bits='64' id='type-id-148'> - <parameter type-id='type-id-14'/> - <parameter type-id='type-id-36'/> - <return type-id='type-id-14'/> - </function-type> - <function-type size-in-bits='64' id='type-id-189'> - <parameter type-id='type-id-14'/> - <parameter type-id='type-id-18'/> - <return type-id='type-id-14'/> - </function-type> - <function-type size-in-bits='64' id='type-id-377'> - <parameter type-id='type-id-10'/> - <parameter type-id='type-id-376'/> - <parameter type-id='type-id-8'/> - <return type-id='type-id-14'/> - </function-type> - <function-type size-in-bits='64' id='type-id-196'> - <parameter type-id='type-id-74'/> - <parameter type-id='type-id-14'/> - <parameter type-id='type-id-14'/> - <return type-id='type-id-14'/> - </function-type> - <function-type size-in-bits='64' id='type-id-194'> - <parameter type-id='type-id-74'/> - <parameter type-id='type-id-36'/> - <return type-id='type-id-14'/> - </function-type> - <function-type size-in-bits='64' id='type-id-207'> - <parameter type-id='type-id-206'/> - <return type-id='type-id-14'/> - </function-type> - <function-type size-in-bits='64' id='type-id-474'> - <parameter type-id='type-id-473'/> - <parameter type-id='type-id-473'/> - <parameter type-id='type-id-3'/> - <return type-id='type-id-115'/> - </function-type> - <function-type size-in-bits='64' id='type-id-455'> - <return type-id='type-id-8'/> - </function-type> - <function-type size-in-bits='64' id='type-id-138'> - <parameter type-id='type-id-14'/> - <return type-id='type-id-8'/> - </function-type> - <function-type size-in-bits='64' id='type-id-439'> - <parameter type-id='type-id-14'/> - <parameter type-id='type-id-438'/> - <parameter type-id='type-id-8'/> - <parameter type-id='type-id-14'/> - <return type-id='type-id-8'/> - </function-type> - <function-type size-in-bits='64' id='type-id-152'> - <parameter type-id='type-id-14'/> - <parameter type-id='type-id-14'/> - <return type-id='type-id-8'/> - </function-type> - <function-type size-in-bits='64' id='type-id-157'> - <parameter type-id='type-id-14'/> - <parameter type-id='type-id-14'/> - <parameter type-id='type-id-14'/> - <return type-id='type-id-8'/> - </function-type> - <function-type size-in-bits='64' id='type-id-191'> - <parameter type-id='type-id-14'/> - <parameter type-id='type-id-14'/> - <parameter type-id='type-id-18'/> - <return type-id='type-id-8'/> - </function-type> - <function-type size-in-bits='64' id='type-id-170'> - <parameter type-id='type-id-14'/> - <parameter type-id='type-id-169'/> - <parameter type-id='type-id-8'/> - <return type-id='type-id-8'/> - </function-type> - <function-type size-in-bits='64' id='type-id-208'> - <parameter type-id='type-id-14'/> - <parameter type-id='type-id-206'/> - <return type-id='type-id-8'/> - </function-type> - <function-type size-in-bits='64' id='type-id-118'> - <parameter type-id='type-id-14'/> - <parameter type-id='type-id-115'/> - <parameter type-id='type-id-14'/> - <return type-id='type-id-8'/> - </function-type> - <function-type size-in-bits='64' id='type-id-150'> - <parameter type-id='type-id-14'/> - <parameter type-id='type-id-36'/> - <parameter type-id='type-id-14'/> - <return type-id='type-id-8'/> - </function-type> - <function-type size-in-bits='64' id='type-id-177'> - <parameter type-id='type-id-14'/> - <parameter type-id='type-id-176'/> - <parameter type-id='type-id-18'/> - <return type-id='type-id-8'/> - </function-type> - <function-type size-in-bits='64' id='type-id-174'> - <parameter type-id='type-id-14'/> - <parameter type-id='type-id-18'/> - <return type-id='type-id-8'/> - </function-type> - <function-type size-in-bits='64' id='type-id-243'> - <parameter type-id='type-id-3'/> - <parameter type-id='type-id-14'/> - <parameter type-id='type-id-18'/> - <return type-id='type-id-8'/> - </function-type> - <function-type size-in-bits='64' id='type-id-365'> - <parameter type-id='type-id-18'/> - <return type-id='type-id-8'/> - </function-type> - <function-type size-in-bits='64' id='type-id-129'> - <parameter type-id='type-id-14'/> - <parameter type-id='type-id-14'/> - <parameter type-id='type-id-22'/> - <return type-id='type-id-128'/> - </function-type> - <function-type size-in-bits='64' id='type-id-160'> - <parameter type-id='type-id-14'/> - <return type-id='type-id-159'/> - </function-type> - <function-type size-in-bits='64' id='type-id-146'> - <parameter type-id='type-id-14'/> - <return type-id='type-id-36'/> - </function-type> - <function-type size-in-bits='64' id='type-id-210'> - <return type-id='type-id-70'/> - </function-type> - <function-type size-in-bits='64' id='type-id-113'> - <parameter type-id='type-id-14'/> - <return type-id='type-id-70'/> - </function-type> - <function-type size-in-bits='64' id='type-id-172'> - <parameter type-id='type-id-14'/> - <parameter type-id='type-id-169'/> - <return type-id='type-id-70'/> - </function-type> - <function-type size-in-bits='64' id='type-id-198'> - <parameter type-id='type-id-18'/> - <return type-id='type-id-70'/> - </function-type> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Objects/abstract.c' comp-dir-path='/src' language='LANG_C99'> - <qualified-type-def type-id='type-id-115' const='yes' id='type-id-476'/> - <pointer-type-def type-id='type-id-476' size-in-bits='64' id='type-id-477'/> - <function-decl name='_Py_FreeCharPArray' mangled-name='_Py_FreeCharPArray' filepath='Objects/abstract.c' line='2969' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_FreeCharPArray'> - <parameter type-id='type-id-477' name='array' filepath='Objects/abstract.c' line='2969' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_PySequence_BytesToCharpArray' mangled-name='_PySequence_BytesToCharpArray' filepath='Objects/abstract.c' line='2910' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PySequence_BytesToCharpArray'> - <parameter type-id='type-id-14' name='self' filepath='Objects/abstract.c' line='2910' column='1'/> - <return type-id='type-id-477'/> - </function-decl> - <function-decl name='PyIter_Send' mangled-name='PyIter_Send' filepath='Objects/abstract.c' line='2877' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyIter_Send'> - <parameter type-id='type-id-14' name='iter' filepath='Objects/abstract.c' line='2877' column='1'/> - <parameter type-id='type-id-14' name='arg' filepath='Objects/abstract.c' line='2877' column='1'/> - <parameter type-id='type-id-22' name='result' filepath='Objects/abstract.c' line='2877' column='1'/> - <return type-id='type-id-128'/> - </function-decl> - <function-decl name='PyIter_Next' mangled-name='PyIter_Next' filepath='Objects/abstract.c' line='2861' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyIter_Next'> - <parameter type-id='type-id-14' name='iter' filepath='Objects/abstract.c' line='2861' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyAIter_Check' mangled-name='PyAIter_Check' filepath='Objects/abstract.c' line='2845' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyAIter_Check'> - <parameter type-id='type-id-14' name='obj' filepath='Objects/abstract.c' line='2845' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyIter_Check' mangled-name='PyIter_Check' filepath='Objects/abstract.c' line='2837' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyIter_Check'> - <parameter type-id='type-id-14' name='obj' filepath='Objects/abstract.c' line='2845' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyObject_GetAIter' mangled-name='PyObject_GetAIter' filepath='Objects/abstract.c' line='2817' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_GetAIter'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2817' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyObject_GetIter' mangled-name='PyObject_GetIter' filepath='Objects/abstract.c' line='2791' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_GetIter'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2791' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyObject_RealIsSubclass' mangled-name='_PyObject_RealIsSubclass' filepath='Objects/abstract.c' line='2784' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_RealIsSubclass'> - <parameter type-id='type-id-14' name='derived' filepath='Objects/abstract.c' line='2784' column='1'/> - <parameter type-id='type-id-14' name='cls' filepath='Objects/abstract.c' line='2784' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyObject_RealIsInstance' mangled-name='_PyObject_RealIsInstance' filepath='Objects/abstract.c' line='2778' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_RealIsInstance'> - <parameter type-id='type-id-14' name='derived' filepath='Objects/abstract.c' line='2784' column='1'/> - <parameter type-id='type-id-14' name='cls' filepath='Objects/abstract.c' line='2784' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyObject_IsSubclass' mangled-name='PyObject_IsSubclass' filepath='Objects/abstract.c' line='2770' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_IsSubclass'> - <parameter type-id='type-id-14' name='derived' filepath='Objects/abstract.c' line='2770' column='1'/> - <parameter type-id='type-id-14' name='cls' filepath='Objects/abstract.c' line='2770' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyObject_IsInstance' mangled-name='PyObject_IsInstance' filepath='Objects/abstract.c' line='2682' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_IsInstance'> - <parameter type-id='type-id-14' name='derived' filepath='Objects/abstract.c' line='2770' column='1'/> - <parameter type-id='type-id-14' name='cls' filepath='Objects/abstract.c' line='2770' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyMapping_Values' mangled-name='PyMapping_Values' filepath='Objects/abstract.c' line='2462' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMapping_Values'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2462' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyMapping_Items' mangled-name='PyMapping_Items' filepath='Objects/abstract.c' line='2450' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMapping_Items'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2462' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyMapping_Keys' mangled-name='PyMapping_Keys' filepath='Objects/abstract.c' line='2438' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMapping_Keys'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2462' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyMapping_HasKey' mangled-name='PyMapping_HasKey' filepath='Objects/abstract.c' line='2392' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMapping_HasKey'> - <parameter type-id='type-id-14' name='derived' filepath='Objects/abstract.c' line='2770' column='1'/> - <parameter type-id='type-id-14' name='cls' filepath='Objects/abstract.c' line='2770' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyMapping_HasKeyString' mangled-name='PyMapping_HasKeyString' filepath='Objects/abstract.c' line='2378' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMapping_HasKeyString'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2378' column='1'/> - <parameter type-id='type-id-3' name='key' filepath='Objects/abstract.c' line='2378' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyMapping_SetItemString' mangled-name='PyMapping_SetItemString' filepath='Objects/abstract.c' line='2359' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMapping_SetItemString'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2359' column='1'/> - <parameter type-id='type-id-3' name='key' filepath='Objects/abstract.c' line='2359' column='1'/> - <parameter type-id='type-id-14' name='value' filepath='Objects/abstract.c' line='2359' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyMapping_GetItemString' mangled-name='PyMapping_GetItemString' filepath='Objects/abstract.c' line='2342' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMapping_GetItemString'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2342' column='1'/> - <parameter type-id='type-id-3' name='key' filepath='Objects/abstract.c' line='2342' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyMapping_Length' mangled-name='PyMapping_Length' filepath='Objects/abstract.c' line='2335' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMapping_Length'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2335' column='1'/> - <return type-id='type-id-36'/> - </function-decl> - <function-decl name='PyMapping_Size' mangled-name='PyMapping_Size' filepath='Objects/abstract.c' line='2310' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMapping_Size'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2310' column='1'/> - <return type-id='type-id-36'/> - </function-decl> - <function-decl name='PyMapping_Check' mangled-name='PyMapping_Check' filepath='Objects/abstract.c' line='2303' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMapping_Check'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2303' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PySequence_Index' mangled-name='PySequence_Index' filepath='Objects/abstract.c' line='2295' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySequence_Index'> - <parameter type-id='type-id-14' name='s' filepath='Objects/abstract.c' line='2295' column='1'/> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2295' column='1'/> - <return type-id='type-id-36'/> - </function-decl> - <function-decl name='PySequence_In' mangled-name='PySequence_In' filepath='Objects/abstract.c' line='2289' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySequence_In'> - <parameter type-id='type-id-14' name='derived' filepath='Objects/abstract.c' line='2784' column='1'/> - <parameter type-id='type-id-14' name='cls' filepath='Objects/abstract.c' line='2784' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PySequence_Contains' mangled-name='PySequence_Contains' filepath='Objects/abstract.c' line='2274' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySequence_Contains'> - <parameter type-id='type-id-14' name='seq' filepath='Objects/abstract.c' line='2274' column='1'/> - <parameter type-id='type-id-14' name='ob' filepath='Objects/abstract.c' line='2274' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PySequence_Count' mangled-name='PySequence_Count' filepath='Objects/abstract.c' line='2265' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySequence_Count'> - <parameter type-id='type-id-14' name='s' filepath='Objects/abstract.c' line='2295' column='1'/> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2295' column='1'/> - <return type-id='type-id-36'/> - </function-decl> - <function-decl name='_PySequence_IterSearch' mangled-name='_PySequence_IterSearch' filepath='Objects/abstract.c' line='2180' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PySequence_IterSearch'> - <parameter type-id='type-id-14' name='seq' filepath='Objects/abstract.c' line='2180' column='1'/> - <parameter type-id='type-id-14' name='obj' filepath='Objects/abstract.c' line='2180' column='1'/> - <parameter type-id='type-id-8' name='operation' filepath='Objects/abstract.c' line='2180' column='1'/> - <return type-id='type-id-36'/> - </function-decl> - <function-decl name='PySequence_Fast' mangled-name='PySequence_Fast' filepath='Objects/abstract.c' line='2145' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySequence_Fast'> - <parameter type-id='type-id-14' name='v' filepath='Objects/abstract.c' line='2145' column='1'/> - <parameter type-id='type-id-3' name='m' filepath='Objects/abstract.c' line='2145' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PySequence_List' mangled-name='PySequence_List' filepath='Objects/abstract.c' line='2122' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySequence_List'> - <parameter type-id='type-id-14' name='v' filepath='Objects/abstract.c' line='2122' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PySequence_Tuple' mangled-name='PySequence_Tuple' filepath='Objects/abstract.c' line='2038' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySequence_Tuple'> - <parameter type-id='type-id-14' name='v' filepath='Objects/abstract.c' line='2038' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PySequence_DelSlice' mangled-name='PySequence_DelSlice' filepath='Objects/abstract.c' line='2015' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySequence_DelSlice'> - <parameter type-id='type-id-14' name='s' filepath='Objects/abstract.c' line='2015' column='1'/> - <parameter type-id='type-id-36' name='i1' filepath='Objects/abstract.c' line='2015' column='1'/> - <parameter type-id='type-id-36' name='i2' filepath='Objects/abstract.c' line='2015' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PySequence_SetSlice' mangled-name='PySequence_SetSlice' filepath='Objects/abstract.c' line='1992' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySequence_SetSlice'> - <parameter type-id='type-id-14' name='s' filepath='Objects/abstract.c' line='1992' column='1'/> - <parameter type-id='type-id-36' name='i1' filepath='Objects/abstract.c' line='1992' column='1'/> - <parameter type-id='type-id-36' name='i2' filepath='Objects/abstract.c' line='1992' column='1'/> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='1992' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PySequence_DelItem' mangled-name='PySequence_DelItem' filepath='Objects/abstract.c' line='1959' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySequence_DelItem'> - <parameter type-id='type-id-14' name='s' filepath='Objects/abstract.c' line='1959' column='1'/> - <parameter type-id='type-id-36' name='i' filepath='Objects/abstract.c' line='1959' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PySequence_SetItem' mangled-name='PySequence_SetItem' filepath='Objects/abstract.c' line='1926' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySequence_SetItem'> - <parameter type-id='type-id-14' name='s' filepath='Objects/abstract.c' line='1926' column='1'/> - <parameter type-id='type-id-36' name='i' filepath='Objects/abstract.c' line='1926' column='1'/> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='1926' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PySequence_GetSlice' mangled-name='PySequence_GetSlice' filepath='Objects/abstract.c' line='1904' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySequence_GetSlice'> - <parameter type-id='type-id-14' name='s' filepath='Objects/abstract.c' line='1904' column='1'/> - <parameter type-id='type-id-36' name='i1' filepath='Objects/abstract.c' line='1904' column='1'/> - <parameter type-id='type-id-36' name='i2' filepath='Objects/abstract.c' line='1904' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PySequence_GetItem' mangled-name='PySequence_GetItem' filepath='Objects/abstract.c' line='1874' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySequence_GetItem'> - <parameter type-id='type-id-14' name='s' filepath='Objects/abstract.c' line='1874' column='1'/> - <parameter type-id='type-id-36' name='i' filepath='Objects/abstract.c' line='1874' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PySequence_InPlaceRepeat' mangled-name='PySequence_InPlaceRepeat' filepath='Objects/abstract.c' line='1840' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySequence_InPlaceRepeat'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='1840' column='1'/> - <parameter type-id='type-id-36' name='count' filepath='Objects/abstract.c' line='1840' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PySequence_InPlaceConcat' mangled-name='PySequence_InPlaceConcat' filepath='Objects/abstract.c' line='1811' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySequence_InPlaceConcat'> - <parameter type-id='type-id-14' name='s' filepath='Objects/abstract.c' line='1811' column='1'/> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='1811' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PySequence_Repeat' mangled-name='PySequence_Repeat' filepath='Objects/abstract.c' line='1780' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySequence_Repeat'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='1780' column='1'/> - <parameter type-id='type-id-36' name='count' filepath='Objects/abstract.c' line='1780' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PySequence_Concat' mangled-name='PySequence_Concat' filepath='Objects/abstract.c' line='1754' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySequence_Concat'> - <parameter type-id='type-id-14' name='s' filepath='Objects/abstract.c' line='1754' column='1'/> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='1754' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PySequence_Length' mangled-name='PySequence_Length' filepath='Objects/abstract.c' line='1747' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySequence_Length'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2335' column='1'/> - <return type-id='type-id-36'/> - </function-decl> - <function-decl name='PySequence_Size' mangled-name='PySequence_Size' filepath='Objects/abstract.c' line='1723' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySequence_Size'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2310' column='1'/> - <return type-id='type-id-36'/> - </function-decl> - <function-decl name='PySequence_Check' mangled-name='PySequence_Check' filepath='Objects/abstract.c' line='1714' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySequence_Check'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2303' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyNumber_ToBase' mangled-name='PyNumber_ToBase' filepath='Objects/abstract.c' line='1695' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_ToBase'> - <parameter type-id='type-id-14' name='n' filepath='Objects/abstract.c' line='1695' column='1'/> - <parameter type-id='type-id-8' name='base' filepath='Objects/abstract.c' line='1695' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyNumber_Float' mangled-name='PyNumber_Float' filepath='Objects/abstract.c' line='1634' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_Float'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='1634' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyNumber_Long' mangled-name='PyNumber_Long' filepath='Objects/abstract.c' line='1518' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_Long'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='1518' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyNumber_AsSsize_t' mangled-name='PyNumber_AsSsize_t' filepath='Objects/abstract.c' line='1467' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_AsSsize_t'> - <parameter type-id='type-id-14' name='item' filepath='Objects/abstract.c' line='1467' column='1'/> - <parameter type-id='type-id-14' name='err' filepath='Objects/abstract.c' line='1467' column='1'/> - <return type-id='type-id-36'/> - </function-decl> - <function-decl name='PyNumber_Index' mangled-name='PyNumber_Index' filepath='Objects/abstract.c' line='1455' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_Index'> - <parameter type-id='type-id-14' name='iter' filepath='Objects/abstract.c' line='2861' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyNumber_Index' mangled-name='_PyNumber_Index' filepath='Objects/abstract.c' line='1408' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyNumber_Index'> - <parameter type-id='type-id-14' name='item' filepath='Objects/abstract.c' line='1408' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyIndex_Check' mangled-name='PyIndex_Check' filepath='Objects/abstract.c' line='1396' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyIndex_Check'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2303' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyNumber_Absolute' mangled-name='PyNumber_Absolute' filepath='Objects/abstract.c' line='1378' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_Absolute'> - <parameter type-id='type-id-14' name='iter' filepath='Objects/abstract.c' line='2861' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyNumber_Invert' mangled-name='PyNumber_Invert' filepath='Objects/abstract.c' line='1361' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_Invert'> - <parameter type-id='type-id-14' name='iter' filepath='Objects/abstract.c' line='2861' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyNumber_Positive' mangled-name='PyNumber_Positive' filepath='Objects/abstract.c' line='1344' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_Positive'> - <parameter type-id='type-id-14' name='iter' filepath='Objects/abstract.c' line='2861' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyNumber_Negative' mangled-name='PyNumber_Negative' filepath='Objects/abstract.c' line='1327' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_Negative'> - <parameter type-id='type-id-14' name='iter' filepath='Objects/abstract.c' line='2861' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyNumber_InPlacePower' mangled-name='PyNumber_InPlacePower' filepath='Objects/abstract.c' line='1311' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_InPlacePower'> - <parameter type-id='type-id-14' name='v' filepath='Objects/abstract.c' line='1311' column='1'/> - <parameter type-id='type-id-14' name='w' filepath='Objects/abstract.c' line='1311' column='1'/> - <parameter type-id='type-id-14' name='z' filepath='Objects/abstract.c' line='1311' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyNumber_InPlaceMultiply' mangled-name='PyNumber_InPlaceMultiply' filepath='Objects/abstract.c' line='1282' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_InPlaceMultiply'> - <parameter type-id='type-id-14' name='v' filepath='Objects/abstract.c' line='1282' column='1'/> - <parameter type-id='type-id-14' name='w' filepath='Objects/abstract.c' line='1282' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyNumber_InPlaceAdd' mangled-name='PyNumber_InPlaceAdd' filepath='Objects/abstract.c' line='1259' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_InPlaceAdd'> - <parameter type-id='type-id-14' name='v' filepath='Objects/abstract.c' line='1282' column='1'/> - <parameter type-id='type-id-14' name='w' filepath='Objects/abstract.c' line='1282' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyNumber_InPlaceRemainder' mangled-name='PyNumber_InPlaceRemainder' filepath='Objects/abstract.c' line='1256' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_InPlaceRemainder'> - <parameter type-id='type-id-14' name='v' filepath='Objects/abstract.c' line='1256' column='1'/> - <parameter type-id='type-id-14' name='w' filepath='Objects/abstract.c' line='1256' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyNumber_InPlaceTrueDivide' mangled-name='PyNumber_InPlaceTrueDivide' filepath='Objects/abstract.c' line='1255' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_InPlaceTrueDivide'> - <parameter type-id='type-id-14' name='v' filepath='Objects/abstract.c' line='1256' column='1'/> - <parameter type-id='type-id-14' name='w' filepath='Objects/abstract.c' line='1256' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyNumber_InPlaceFloorDivide' mangled-name='PyNumber_InPlaceFloorDivide' filepath='Objects/abstract.c' line='1254' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_InPlaceFloorDivide'> - <parameter type-id='type-id-14' name='v' filepath='Objects/abstract.c' line='1256' column='1'/> - <parameter type-id='type-id-14' name='w' filepath='Objects/abstract.c' line='1256' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyNumber_InPlaceMatrixMultiply' mangled-name='PyNumber_InPlaceMatrixMultiply' filepath='Objects/abstract.c' line='1253' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_InPlaceMatrixMultiply'> - <parameter type-id='type-id-14' name='v' filepath='Objects/abstract.c' line='1256' column='1'/> - <parameter type-id='type-id-14' name='w' filepath='Objects/abstract.c' line='1256' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyNumber_InPlaceSubtract' mangled-name='PyNumber_InPlaceSubtract' filepath='Objects/abstract.c' line='1252' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_InPlaceSubtract'> - <parameter type-id='type-id-14' name='v' filepath='Objects/abstract.c' line='1256' column='1'/> - <parameter type-id='type-id-14' name='w' filepath='Objects/abstract.c' line='1256' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyNumber_InPlaceRshift' mangled-name='PyNumber_InPlaceRshift' filepath='Objects/abstract.c' line='1251' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_InPlaceRshift'> - <parameter type-id='type-id-14' name='v' filepath='Objects/abstract.c' line='1256' column='1'/> - <parameter type-id='type-id-14' name='w' filepath='Objects/abstract.c' line='1256' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyNumber_InPlaceLshift' mangled-name='PyNumber_InPlaceLshift' filepath='Objects/abstract.c' line='1250' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_InPlaceLshift'> - <parameter type-id='type-id-14' name='v' filepath='Objects/abstract.c' line='1256' column='1'/> - <parameter type-id='type-id-14' name='w' filepath='Objects/abstract.c' line='1256' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyNumber_InPlaceAnd' mangled-name='PyNumber_InPlaceAnd' filepath='Objects/abstract.c' line='1249' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_InPlaceAnd'> - <parameter type-id='type-id-14' name='v' filepath='Objects/abstract.c' line='1256' column='1'/> - <parameter type-id='type-id-14' name='w' filepath='Objects/abstract.c' line='1256' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyNumber_InPlaceXor' mangled-name='PyNumber_InPlaceXor' filepath='Objects/abstract.c' line='1248' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_InPlaceXor'> - <parameter type-id='type-id-14' name='v' filepath='Objects/abstract.c' line='1256' column='1'/> - <parameter type-id='type-id-14' name='w' filepath='Objects/abstract.c' line='1256' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyNumber_InPlaceOr' mangled-name='PyNumber_InPlaceOr' filepath='Objects/abstract.c' line='1247' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_InPlaceOr'> - <parameter type-id='type-id-14' name='v' filepath='Objects/abstract.c' line='1256' column='1'/> - <parameter type-id='type-id-14' name='w' filepath='Objects/abstract.c' line='1256' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyNumber_Power' mangled-name='PyNumber_Power' filepath='Objects/abstract.c' line='1152' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_Power'> - <parameter type-id='type-id-14' name='v' filepath='Objects/abstract.c' line='1311' column='1'/> - <parameter type-id='type-id-14' name='w' filepath='Objects/abstract.c' line='1311' column='1'/> - <parameter type-id='type-id-14' name='z' filepath='Objects/abstract.c' line='1311' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyNumber_Remainder' mangled-name='PyNumber_Remainder' filepath='Objects/abstract.c' line='1146' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_Remainder'> - <parameter type-id='type-id-14' name='v' filepath='Objects/abstract.c' line='1256' column='1'/> - <parameter type-id='type-id-14' name='w' filepath='Objects/abstract.c' line='1256' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyNumber_TrueDivide' mangled-name='PyNumber_TrueDivide' filepath='Objects/abstract.c' line='1140' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_TrueDivide'> - <parameter type-id='type-id-14' name='v' filepath='Objects/abstract.c' line='1256' column='1'/> - <parameter type-id='type-id-14' name='w' filepath='Objects/abstract.c' line='1256' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyNumber_FloorDivide' mangled-name='PyNumber_FloorDivide' filepath='Objects/abstract.c' line='1134' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_FloorDivide'> - <parameter type-id='type-id-14' name='v' filepath='Objects/abstract.c' line='1256' column='1'/> - <parameter type-id='type-id-14' name='w' filepath='Objects/abstract.c' line='1256' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyNumber_MatrixMultiply' mangled-name='PyNumber_MatrixMultiply' filepath='Objects/abstract.c' line='1128' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_MatrixMultiply'> - <parameter type-id='type-id-14' name='v' filepath='Objects/abstract.c' line='1256' column='1'/> - <parameter type-id='type-id-14' name='w' filepath='Objects/abstract.c' line='1256' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyNumber_Multiply' mangled-name='PyNumber_Multiply' filepath='Objects/abstract.c' line='1109' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_Multiply'> - <parameter type-id='type-id-14' name='v' filepath='Objects/abstract.c' line='1282' column='1'/> - <parameter type-id='type-id-14' name='w' filepath='Objects/abstract.c' line='1282' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyNumber_Add' mangled-name='PyNumber_Add' filepath='Objects/abstract.c' line='1071' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_Add'> - <parameter type-id='type-id-14' name='v' filepath='Objects/abstract.c' line='1071' column='1'/> - <parameter type-id='type-id-14' name='w' filepath='Objects/abstract.c' line='1071' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyNumber_Divmod' mangled-name='PyNumber_Divmod' filepath='Objects/abstract.c' line='1068' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_Divmod'> - <parameter type-id='type-id-14' name='v' filepath='Objects/abstract.c' line='1256' column='1'/> - <parameter type-id='type-id-14' name='w' filepath='Objects/abstract.c' line='1256' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyNumber_Subtract' mangled-name='PyNumber_Subtract' filepath='Objects/abstract.c' line='1067' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_Subtract'> - <parameter type-id='type-id-14' name='v' filepath='Objects/abstract.c' line='1256' column='1'/> - <parameter type-id='type-id-14' name='w' filepath='Objects/abstract.c' line='1256' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyNumber_Rshift' mangled-name='PyNumber_Rshift' filepath='Objects/abstract.c' line='1066' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_Rshift'> - <parameter type-id='type-id-14' name='v' filepath='Objects/abstract.c' line='1256' column='1'/> - <parameter type-id='type-id-14' name='w' filepath='Objects/abstract.c' line='1256' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyNumber_Lshift' mangled-name='PyNumber_Lshift' filepath='Objects/abstract.c' line='1065' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_Lshift'> - <parameter type-id='type-id-14' name='v' filepath='Objects/abstract.c' line='1256' column='1'/> - <parameter type-id='type-id-14' name='w' filepath='Objects/abstract.c' line='1256' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyNumber_And' mangled-name='PyNumber_And' filepath='Objects/abstract.c' line='1064' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_And'> - <parameter type-id='type-id-14' name='v' filepath='Objects/abstract.c' line='1256' column='1'/> - <parameter type-id='type-id-14' name='w' filepath='Objects/abstract.c' line='1256' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyNumber_Xor' mangled-name='PyNumber_Xor' filepath='Objects/abstract.c' line='1063' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_Xor'> - <parameter type-id='type-id-14' name='v' filepath='Objects/abstract.c' line='1256' column='1'/> - <parameter type-id='type-id-14' name='w' filepath='Objects/abstract.c' line='1256' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyNumber_Or' mangled-name='PyNumber_Or' filepath='Objects/abstract.c' line='1062' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_Or'> - <parameter type-id='type-id-14' name='v' filepath='Objects/abstract.c' line='1256' column='1'/> - <parameter type-id='type-id-14' name='w' filepath='Objects/abstract.c' line='1256' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyNumber_Check' mangled-name='PyNumber_Check' filepath='Objects/abstract.c' line='832' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_Check'> - <parameter type-id='type-id-14' name='obj' filepath='Objects/abstract.c' line='2845' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyObject_Format' mangled-name='PyObject_Format' filepath='Objects/abstract.c' line='770' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_Format'> - <parameter type-id='type-id-14' name='obj' filepath='Objects/abstract.c' line='770' column='1'/> - <parameter type-id='type-id-14' name='format_spec' filepath='Objects/abstract.c' line='770' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyBuffer_Release' mangled-name='PyBuffer_Release' filepath='Objects/abstract.c' line='755' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyBuffer_Release'> - <parameter type-id='type-id-169' name='view' filepath='Objects/abstract.c' line='755' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyBuffer_FillInfo' mangled-name='PyBuffer_FillInfo' filepath='Objects/abstract.c' line='716' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyBuffer_FillInfo'> - <parameter type-id='type-id-169' name='view' filepath='Objects/abstract.c' line='716' column='1'/> - <parameter type-id='type-id-14' name='obj' filepath='Objects/abstract.c' line='716' column='1'/> - <parameter type-id='type-id-18' name='buf' filepath='Objects/abstract.c' line='716' column='1'/> - <parameter type-id='type-id-36' name='len' filepath='Objects/abstract.c' line='716' column='1'/> - <parameter type-id='type-id-8' name='readonly' filepath='Objects/abstract.c' line='717' column='1'/> - <parameter type-id='type-id-8' name='flags' filepath='Objects/abstract.c' line='717' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyBuffer_FillContiguousStrides' mangled-name='PyBuffer_FillContiguousStrides' filepath='Objects/abstract.c' line='692' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyBuffer_FillContiguousStrides'> - <parameter type-id='type-id-8' name='nd' filepath='Objects/abstract.c' line='692' column='1'/> - <parameter type-id='type-id-168' name='shape' filepath='Objects/abstract.c' line='692' column='1'/> - <parameter type-id='type-id-168' name='strides' filepath='Objects/abstract.c' line='693' column='1'/> - <parameter type-id='type-id-8' name='itemsize' filepath='Objects/abstract.c' line='693' column='1'/> - <parameter type-id='type-id-1' name='fort' filepath='Objects/abstract.c' line='694' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyObject_CopyData' mangled-name='PyObject_CopyData' filepath='Objects/abstract.c' line='621' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_CopyData'> - <parameter type-id='type-id-14' name='dest' filepath='Objects/abstract.c' line='621' column='1'/> - <parameter type-id='type-id-14' name='src' filepath='Objects/abstract.c' line='621' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <qualified-type-def type-id='type-id-166' const='yes' id='type-id-478'/> - <pointer-type-def type-id='type-id-478' size-in-bits='64' id='type-id-479'/> - <function-decl name='PyBuffer_FromContiguous' mangled-name='PyBuffer_FromContiguous' filepath='Objects/abstract.c' line='569' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyBuffer_FromContiguous'> - <parameter type-id='type-id-479' name='view' filepath='Objects/abstract.c' line='569' column='1'/> - <parameter type-id='type-id-18' name='buf' filepath='Objects/abstract.c' line='569' column='1'/> - <parameter type-id='type-id-36' name='len' filepath='Objects/abstract.c' line='569' column='1'/> - <parameter type-id='type-id-1' name='fort' filepath='Objects/abstract.c' line='569' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyBuffer_SizeFromFormat' mangled-name='PyBuffer_SizeFromFormat' filepath='Objects/abstract.c' line='527' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyBuffer_SizeFromFormat'> - <parameter type-id='type-id-3' name='format' filepath='Objects/abstract.c' line='527' column='1'/> - <return type-id='type-id-36'/> - </function-decl> - <qualified-type-def type-id='type-id-36' const='yes' id='type-id-480'/> - <pointer-type-def type-id='type-id-480' size-in-bits='64' id='type-id-481'/> - <function-decl name='_Py_add_one_to_index_C' mangled-name='_Py_add_one_to_index_C' filepath='Objects/abstract.c' line='511' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_add_one_to_index_C'> - <parameter type-id='type-id-8' name='nd' filepath='Objects/abstract.c' line='511' column='1'/> - <parameter type-id='type-id-168' name='index' filepath='Objects/abstract.c' line='511' column='1'/> - <parameter type-id='type-id-481' name='shape' filepath='Objects/abstract.c' line='511' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_Py_add_one_to_index_F' mangled-name='_Py_add_one_to_index_F' filepath='Objects/abstract.c' line='495' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_add_one_to_index_F'> - <parameter type-id='type-id-8' name='nd' filepath='Objects/abstract.c' line='511' column='1'/> - <parameter type-id='type-id-168' name='index' filepath='Objects/abstract.c' line='511' column='1'/> - <parameter type-id='type-id-481' name='shape' filepath='Objects/abstract.c' line='511' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyBuffer_GetPointer' mangled-name='PyBuffer_GetPointer' filepath='Objects/abstract.c' line='479' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyBuffer_GetPointer'> - <parameter type-id='type-id-479' name='view' filepath='Objects/abstract.c' line='479' column='1'/> - <parameter type-id='type-id-481' name='indices' filepath='Objects/abstract.c' line='479' column='1'/> - <return type-id='type-id-18'/> - </function-decl> - <function-decl name='PyBuffer_IsContiguous' mangled-name='PyBuffer_IsContiguous' filepath='Objects/abstract.c' line='463' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyBuffer_IsContiguous'> - <parameter type-id='type-id-479' name='view' filepath='Objects/abstract.c' line='463' column='1'/> - <parameter type-id='type-id-1' name='order' filepath='Objects/abstract.c' line='463' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyObject_GetBuffer' mangled-name='PyObject_GetBuffer' filepath='Objects/abstract.c' line='380' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_GetBuffer'> - <parameter type-id='type-id-14' name='obj' filepath='Objects/abstract.c' line='380' column='1'/> - <parameter type-id='type-id-169' name='view' filepath='Objects/abstract.c' line='380' column='1'/> - <parameter type-id='type-id-8' name='flags' filepath='Objects/abstract.c' line='380' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <pointer-type-def type-id='type-id-18' size-in-bits='64' id='type-id-482'/> - <function-decl name='PyObject_AsWriteBuffer' mangled-name='PyObject_AsWriteBuffer' filepath='Objects/abstract.c' line='351' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_AsWriteBuffer'> - <parameter type-id='type-id-14' name='obj' filepath='Objects/abstract.c' line='351' column='1'/> - <parameter type-id='type-id-482' name='buffer' filepath='Objects/abstract.c' line='352' column='1'/> - <parameter type-id='type-id-168' name='buffer_len' filepath='Objects/abstract.c' line='353' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyObject_AsReadBuffer' mangled-name='PyObject_AsReadBuffer' filepath='Objects/abstract.c' line='344' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_AsReadBuffer'> - <parameter type-id='type-id-14' name='obj' filepath='Objects/abstract.c' line='344' column='1'/> - <parameter type-id='type-id-482' name='buffer' filepath='Objects/abstract.c' line='345' column='1'/> - <parameter type-id='type-id-168' name='buffer_len' filepath='Objects/abstract.c' line='346' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <pointer-type-def type-id='type-id-3' size-in-bits='64' id='type-id-483'/> - <function-decl name='PyObject_AsCharBuffer' mangled-name='PyObject_AsCharBuffer' filepath='Objects/abstract.c' line='337' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_AsCharBuffer'> - <parameter type-id='type-id-14' name='obj' filepath='Objects/abstract.c' line='337' column='1'/> - <parameter type-id='type-id-483' name='buffer' filepath='Objects/abstract.c' line='338' column='1'/> - <parameter type-id='type-id-168' name='buffer_len' filepath='Objects/abstract.c' line='339' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyObject_CheckReadBuffer' mangled-name='PyObject_CheckReadBuffer' filepath='Objects/abstract.c' line='302' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_CheckReadBuffer'> - <parameter type-id='type-id-14' name='obj' filepath='Objects/abstract.c' line='302' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyObject_CheckBuffer' mangled-name='PyObject_CheckBuffer' filepath='Objects/abstract.c' line='291' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_CheckBuffer'> - <parameter type-id='type-id-14' name='obj' filepath='Objects/abstract.c' line='2845' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyObject_DelItemString' mangled-name='PyObject_DelItemString' filepath='Objects/abstract.c' line='271' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_DelItemString'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='271' column='1'/> - <parameter type-id='type-id-3' name='key' filepath='Objects/abstract.c' line='271' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyObject_DelItem' mangled-name='PyObject_DelItem' filepath='Objects/abstract.c' line='237' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_DelItem'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='237' column='1'/> - <parameter type-id='type-id-14' name='key' filepath='Objects/abstract.c' line='237' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyObject_SetItem' mangled-name='PyObject_SetItem' filepath='Objects/abstract.c' line='203' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_SetItem'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='203' column='1'/> - <parameter type-id='type-id-14' name='key' filepath='Objects/abstract.c' line='203' column='1'/> - <parameter type-id='type-id-14' name='value' filepath='Objects/abstract.c' line='203' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyObject_GetItem' mangled-name='PyObject_GetItem' filepath='Objects/abstract.c' line='149' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_GetItem'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='149' column='1'/> - <parameter type-id='type-id-14' name='key' filepath='Objects/abstract.c' line='149' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyObject_LengthHint' mangled-name='PyObject_LengthHint' filepath='Objects/abstract.c' line='91' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_LengthHint'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='91' column='1'/> - <parameter type-id='type-id-36' name='defaultvalue' filepath='Objects/abstract.c' line='91' column='1'/> - <return type-id='type-id-36'/> - </function-decl> - <function-decl name='_PyObject_HasLen' mangled-name='_PyObject_HasLen' filepath='Objects/abstract.c' line='79' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_HasLen'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2303' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyObject_Length' mangled-name='PyObject_Length' filepath='Objects/abstract.c' line='72' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_Length'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2335' column='1'/> - <return type-id='type-id-36'/> - </function-decl> - <function-decl name='PyObject_Size' mangled-name='PyObject_Size' filepath='Objects/abstract.c' line='53' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_Size'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2310' column='1'/> - <return type-id='type-id-36'/> - </function-decl> - <function-decl name='PyObject_Type' mangled-name='PyObject_Type' filepath='Objects/abstract.c' line='39' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_Type'> - <parameter type-id='type-id-14' name='item' filepath='Objects/abstract.c' line='1408' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Objects/accu.c' comp-dir-path='/src' language='LANG_C99'> - <class-decl name='__anonymous_struct__' size-in-bits='128' is-struct='yes' is-anonymous='yes' naming-typedef-id='type-id-484' visibility='default' filepath='./Include/internal/pycore_accu.h' line='24' column='1' id='type-id-485'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='large' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_accu.h' line='25' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='small' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_accu.h' line='26' column='1'/> - </data-member> - </class-decl> - <typedef-decl name='_PyAccu' type-id='type-id-485' filepath='./Include/internal/pycore_accu.h' line='27' column='1' id='type-id-484'/> - <pointer-type-def type-id='type-id-484' size-in-bits='64' id='type-id-486'/> - <function-decl name='_PyAccu_Destroy' mangled-name='_PyAccu_Destroy' filepath='Objects/accu.c' line='111' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyAccu_Destroy'> - <parameter type-id='type-id-486' name='acc' filepath='Objects/accu.c' line='111' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_PyAccu_Finish' mangled-name='_PyAccu_Finish' filepath='Objects/accu.c' line='93' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyAccu_Finish'> - <parameter type-id='type-id-486' name='acc' filepath='Objects/accu.c' line='93' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyAccu_FinishAsList' mangled-name='_PyAccu_FinishAsList' filepath='Objects/accu.c' line='76' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyAccu_FinishAsList'> - <parameter type-id='type-id-486' name='acc' filepath='Objects/accu.c' line='76' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyAccu_Accumulate' mangled-name='_PyAccu_Accumulate' filepath='Objects/accu.c' line='55' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyAccu_Accumulate'> - <parameter type-id='type-id-486' name='acc' filepath='Objects/accu.c' line='55' column='1'/> - <parameter type-id='type-id-14' name='unicode' filepath='Objects/accu.c' line='55' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyAccu_Init' mangled-name='_PyAccu_Init' filepath='Objects/accu.c' line='18' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyAccu_Init'> - <parameter type-id='type-id-486' name='acc' filepath='Objects/accu.c' line='18' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Objects/boolobject.c' comp-dir-path='/src' language='LANG_C99'> - <var-decl name='PyBool_Type' type-id='type-id-112' mangled-name='PyBool_Type' visibility='default' filepath='./Include/boolobject.h' line='10' column='1' elf-symbol-id='PyBool_Type'/> - <var-decl name='_Py_FalseStruct' type-id='type-id-259' mangled-name='_Py_FalseStruct' visibility='default' filepath='./Include/boolobject.h' line='18' column='1' elf-symbol-id='_Py_FalseStruct'/> - <var-decl name='_Py_TrueStruct' type-id='type-id-259' mangled-name='_Py_TrueStruct' visibility='default' filepath='./Include/boolobject.h' line='19' column='1' elf-symbol-id='_Py_TrueStruct'/> - <function-decl name='PyBool_FromLong' mangled-name='PyBool_FromLong' filepath='Objects/boolobject.c' line='18' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyBool_FromLong'> - <parameter type-id='type-id-53' name='ok' filepath='Objects/boolobject.c' line='18' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Objects/bytes_methods.c' comp-dir-path='/src' language='LANG_C99'> - - <array-type-def dimensions='1' type-id='type-id-2' size-in-bits='infinite' id='type-id-487'> - <subrange length='infinite' id='type-id-6'/> - - </array-type-def> - <qualified-type-def type-id='type-id-487' const='yes' id='type-id-488'/> - <var-decl name='_Py_isspace__doc__' type-id='type-id-488' visibility='default' filepath='./Include/internal/pycore_bytes_methods.h' line='42' column='1'/> - <var-decl name='_Py_isalpha__doc__' type-id='type-id-488' visibility='default' filepath='./Include/internal/pycore_bytes_methods.h' line='43' column='1'/> - <var-decl name='_Py_isalnum__doc__' type-id='type-id-488' visibility='default' filepath='./Include/internal/pycore_bytes_methods.h' line='44' column='1'/> - <var-decl name='_Py_isascii__doc__' type-id='type-id-488' visibility='default' filepath='./Include/internal/pycore_bytes_methods.h' line='45' column='1'/> - <var-decl name='_Py_isdigit__doc__' type-id='type-id-488' visibility='default' filepath='./Include/internal/pycore_bytes_methods.h' line='46' column='1'/> - <var-decl name='_Py_islower__doc__' type-id='type-id-488' visibility='default' filepath='./Include/internal/pycore_bytes_methods.h' line='47' column='1'/> - <var-decl name='_Py_isupper__doc__' type-id='type-id-488' visibility='default' filepath='./Include/internal/pycore_bytes_methods.h' line='48' column='1'/> - <var-decl name='_Py_istitle__doc__' type-id='type-id-488' visibility='default' filepath='./Include/internal/pycore_bytes_methods.h' line='49' column='1'/> - <var-decl name='_Py_lower__doc__' type-id='type-id-488' visibility='default' filepath='./Include/internal/pycore_bytes_methods.h' line='50' column='1'/> - <var-decl name='_Py_upper__doc__' type-id='type-id-488' visibility='default' filepath='./Include/internal/pycore_bytes_methods.h' line='51' column='1'/> - <var-decl name='_Py_title__doc__' type-id='type-id-488' visibility='default' filepath='./Include/internal/pycore_bytes_methods.h' line='52' column='1'/> - <var-decl name='_Py_capitalize__doc__' type-id='type-id-488' visibility='default' filepath='./Include/internal/pycore_bytes_methods.h' line='53' column='1'/> - <var-decl name='_Py_swapcase__doc__' type-id='type-id-488' visibility='default' filepath='./Include/internal/pycore_bytes_methods.h' line='54' column='1'/> - <var-decl name='_Py_maketrans__doc__' type-id='type-id-488' visibility='default' filepath='./Include/internal/pycore_bytes_methods.h' line='62' column='1'/> - <var-decl name='_Py_find__doc__' type-id='type-id-488' visibility='default' filepath='./Include/internal/pycore_bytes_methods.h' line='56' column='1'/> - <var-decl name='_Py_index__doc__' type-id='type-id-488' visibility='default' filepath='./Include/internal/pycore_bytes_methods.h' line='57' column='1'/> - <var-decl name='_Py_rfind__doc__' type-id='type-id-488' visibility='default' filepath='./Include/internal/pycore_bytes_methods.h' line='58' column='1'/> - <var-decl name='_Py_rindex__doc__' type-id='type-id-488' visibility='default' filepath='./Include/internal/pycore_bytes_methods.h' line='59' column='1'/> - <var-decl name='_Py_count__doc__' type-id='type-id-488' visibility='default' filepath='./Include/internal/pycore_bytes_methods.h' line='55' column='1'/> - <var-decl name='_Py_startswith__doc__' type-id='type-id-488' visibility='default' filepath='./Include/internal/pycore_bytes_methods.h' line='60' column='1'/> - <var-decl name='_Py_endswith__doc__' type-id='type-id-488' visibility='default' filepath='./Include/internal/pycore_bytes_methods.h' line='61' column='1'/> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Objects/bytearrayobject.c' comp-dir-path='/src' language='LANG_C99'> - <var-decl name='_PyByteArray_empty_string' type-id='type-id-409' mangled-name='_PyByteArray_empty_string' visibility='default' filepath='./Include/cpython/bytearrayobject.h' line='14' column='1' elf-symbol-id='_PyByteArray_empty_string'/> - <var-decl name='PyByteArray_Type' type-id='type-id-112' mangled-name='PyByteArray_Type' visibility='default' filepath='./Include/bytearrayobject.h' line='20' column='1' elf-symbol-id='PyByteArray_Type'/> - <var-decl name='PyByteArrayIter_Type' type-id='type-id-112' mangled-name='PyByteArrayIter_Type' visibility='default' filepath='./Include/bytearrayobject.h' line='21' column='1' elf-symbol-id='PyByteArrayIter_Type'/> - <function-decl name='PyByteArray_Concat' mangled-name='PyByteArray_Concat' filepath='Objects/bytearrayobject.c' line='249' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyByteArray_Concat'> - <parameter type-id='type-id-14' name='a' filepath='Objects/bytearrayobject.c' line='249' column='1'/> - <parameter type-id='type-id-14' name='b' filepath='Objects/bytearrayobject.c' line='249' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyByteArray_Resize' mangled-name='PyByteArray_Resize' filepath='Objects/bytearrayobject.c' line='170' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyByteArray_Resize'> - <parameter type-id='type-id-14' name='self' filepath='Objects/bytearrayobject.c' line='170' column='1'/> - <parameter type-id='type-id-36' name='requested_size' filepath='Objects/bytearrayobject.c' line='170' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyByteArray_AsString' mangled-name='PyByteArray_AsString' filepath='Objects/bytearrayobject.c' line='161' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyByteArray_AsString'> - <parameter type-id='type-id-14' name='self' filepath='Objects/bytearrayobject.c' line='161' column='1'/> - <return type-id='type-id-115'/> - </function-decl> - <function-decl name='PyByteArray_Size' mangled-name='PyByteArray_Size' filepath='Objects/bytearrayobject.c' line='152' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyByteArray_Size'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2335' column='1'/> - <return type-id='type-id-36'/> - </function-decl> - <function-decl name='PyByteArray_FromStringAndSize' mangled-name='PyByteArray_FromStringAndSize' filepath='Objects/bytearrayobject.c' line='108' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyByteArray_FromStringAndSize'> - <parameter type-id='type-id-3' name='bytes' filepath='Objects/bytearrayobject.c' line='108' column='1'/> - <parameter type-id='type-id-36' name='size' filepath='Objects/bytearrayobject.c' line='108' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyByteArray_FromObject' mangled-name='PyByteArray_FromObject' filepath='Objects/bytearrayobject.c' line='82' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyByteArray_FromObject'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2462' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Objects/bytesobject.c' comp-dir-path='/src' language='LANG_C99'> - <var-decl name='PyBytes_Type' type-id='type-id-112' mangled-name='PyBytes_Type' visibility='default' filepath='./Include/bytesobject.h' line='27' column='1' elf-symbol-id='PyBytes_Type'/> - <var-decl name='PyBytesIter_Type' type-id='type-id-112' mangled-name='PyBytesIter_Type' visibility='default' filepath='./Include/bytesobject.h' line='28' column='1' elf-symbol-id='PyBytesIter_Type'/> - <function-decl name='_PyBytes_Repeat' mangled-name='_PyBytes_Repeat' filepath='Objects/bytesobject.c' line='3566' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyBytes_Repeat'> - <parameter type-id='type-id-115' name='dest' filepath='Objects/bytesobject.c' line='3566' column='1'/> - <parameter type-id='type-id-36' name='len_dest' filepath='Objects/bytesobject.c' line='3566' column='1'/> - <parameter type-id='type-id-3' name='src' filepath='Objects/bytesobject.c' line='3567' column='1'/> - <parameter type-id='type-id-36' name='len_src' filepath='Objects/bytesobject.c' line='3567' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <class-decl name='__anonymous_struct__' size-in-bits='4416' is-struct='yes' is-anonymous='yes' naming-typedef-id='type-id-489' visibility='default' filepath='./Include/cpython/bytesobject.h' line='59' column='1' id='type-id-490'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='buffer' type-id='type-id-14' visibility='default' filepath='./Include/cpython/bytesobject.h' line='61' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='allocated' type-id='type-id-36' visibility='default' filepath='./Include/cpython/bytesobject.h' line='64' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='min_size' type-id='type-id-36' visibility='default' filepath='./Include/cpython/bytesobject.h' line='68' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='use_bytearray' type-id='type-id-8' visibility='default' filepath='./Include/cpython/bytesobject.h' line='71' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='224'> - <var-decl name='overallocate' type-id='type-id-8' visibility='default' filepath='./Include/cpython/bytesobject.h' line='75' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='256'> - <var-decl name='use_small_buffer' type-id='type-id-8' visibility='default' filepath='./Include/cpython/bytesobject.h' line='78' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='288'> - <var-decl name='small_buffer' type-id='type-id-491' visibility='default' filepath='./Include/cpython/bytesobject.h' line='79' column='1'/> - </data-member> - </class-decl> - - <array-type-def dimensions='1' type-id='type-id-1' size-in-bits='4096' id='type-id-491'> - <subrange length='512' type-id='type-id-16' id='type-id-492'/> - - </array-type-def> - <typedef-decl name='_PyBytesWriter' type-id='type-id-490' filepath='./Include/cpython/bytesobject.h' line='80' column='1' id='type-id-489'/> - <pointer-type-def type-id='type-id-489' size-in-bits='64' id='type-id-493'/> - <function-decl name='_PyBytesWriter_WriteBytes' mangled-name='_PyBytesWriter_WriteBytes' filepath='Objects/bytesobject.c' line='3549' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyBytesWriter_WriteBytes'> - <parameter type-id='type-id-493' name='writer' filepath='Objects/bytesobject.c' line='3549' column='1'/> - <parameter type-id='type-id-18' name='ptr' filepath='Objects/bytesobject.c' line='3549' column='1'/> - <parameter type-id='type-id-18' name='bytes' filepath='Objects/bytesobject.c' line='3550' column='1'/> - <parameter type-id='type-id-36' name='size' filepath='Objects/bytesobject.c' line='3550' column='1'/> - <return type-id='type-id-18'/> - </function-decl> - <function-decl name='_PyBytesWriter_Finish' mangled-name='_PyBytesWriter_Finish' filepath='Objects/bytesobject.c' line='3505' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyBytesWriter_Finish'> - <parameter type-id='type-id-493' name='writer' filepath='Objects/bytesobject.c' line='3505' column='1'/> - <parameter type-id='type-id-18' name='str' filepath='Objects/bytesobject.c' line='3505' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyBytesWriter_Alloc' mangled-name='_PyBytesWriter_Alloc' filepath='Objects/bytesobject.c' line='3475' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyBytesWriter_Alloc'> - <parameter type-id='type-id-493' name='writer' filepath='Objects/bytesobject.c' line='3475' column='1'/> - <parameter type-id='type-id-36' name='size' filepath='Objects/bytesobject.c' line='3475' column='1'/> - <return type-id='type-id-18'/> - </function-decl> - <function-decl name='_PyBytesWriter_Prepare' mangled-name='_PyBytesWriter_Prepare' filepath='Objects/bytesobject.c' line='3445' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyBytesWriter_Prepare'> - <parameter type-id='type-id-493' name='writer' filepath='Objects/bytesobject.c' line='3445' column='1'/> - <parameter type-id='type-id-18' name='str' filepath='Objects/bytesobject.c' line='3445' column='1'/> - <parameter type-id='type-id-36' name='size' filepath='Objects/bytesobject.c' line='3445' column='1'/> - <return type-id='type-id-18'/> - </function-decl> - <function-decl name='_PyBytesWriter_Resize' mangled-name='_PyBytesWriter_Resize' filepath='Objects/bytesobject.c' line='3375' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyBytesWriter_Resize'> - <parameter type-id='type-id-493' name='writer' filepath='Objects/bytesobject.c' line='3375' column='1'/> - <parameter type-id='type-id-18' name='str' filepath='Objects/bytesobject.c' line='3375' column='1'/> - <parameter type-id='type-id-36' name='size' filepath='Objects/bytesobject.c' line='3375' column='1'/> - <return type-id='type-id-18'/> - </function-decl> - <function-decl name='_PyBytesWriter_Dealloc' mangled-name='_PyBytesWriter_Dealloc' filepath='Objects/bytesobject.c' line='3305' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyBytesWriter_Dealloc'> - <parameter type-id='type-id-493' name='writer' filepath='Objects/bytesobject.c' line='3305' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_PyBytesWriter_Init' mangled-name='_PyBytesWriter_Init' filepath='Objects/bytesobject.c' line='3294' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyBytesWriter_Init'> - <parameter type-id='type-id-493' name='writer' filepath='Objects/bytesobject.c' line='3294' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_PyBytes_Resize' mangled-name='_PyBytes_Resize' filepath='Objects/bytesobject.c' line='3055' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyBytes_Resize'> - <parameter type-id='type-id-22' name='pv' filepath='Objects/bytesobject.c' line='3055' column='1'/> - <parameter type-id='type-id-36' name='newsize' filepath='Objects/bytesobject.c' line='3055' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyBytes_ConcatAndDel' mangled-name='PyBytes_ConcatAndDel' filepath='Objects/bytesobject.c' line='3033' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyBytes_ConcatAndDel'> - <parameter type-id='type-id-22' name='pv' filepath='Objects/bytesobject.c' line='3033' column='1'/> - <parameter type-id='type-id-14' name='w' filepath='Objects/bytesobject.c' line='3033' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyBytes_Concat' mangled-name='PyBytes_Concat' filepath='Objects/bytesobject.c' line='2984' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyBytes_Concat'> - <parameter type-id='type-id-22' name='pv' filepath='Objects/bytesobject.c' line='2984' column='1'/> - <parameter type-id='type-id-14' name='w' filepath='Objects/bytesobject.c' line='2984' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyBytes_FromObject' mangled-name='PyBytes_FromObject' filepath='Objects/bytesobject.c' line='2841' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyBytes_FromObject'> - <parameter type-id='type-id-14' name='v' filepath='Objects/abstract.c' line='2122' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyBytes_FromHex' mangled-name='_PyBytes_FromHex' filepath='Objects/bytesobject.c' line='2381' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyBytes_FromHex'> - <parameter type-id='type-id-14' name='string' filepath='Objects/bytesobject.c' line='2381' column='1'/> - <parameter type-id='type-id-8' name='use_bytearray' filepath='Objects/bytesobject.c' line='2381' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyBytes_Join' mangled-name='_PyBytes_Join' filepath='Objects/bytesobject.c' line='1862' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyBytes_Join'> - <parameter type-id='type-id-14' name='v' filepath='Objects/abstract.c' line='1256' column='1'/> - <parameter type-id='type-id-14' name='w' filepath='Objects/abstract.c' line='1256' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyBytes_Repr' mangled-name='PyBytes_Repr' filepath='Objects/bytesobject.c' line='1302' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyBytes_Repr'> - <parameter type-id='type-id-14' name='obj' filepath='Objects/bytesobject.c' line='1302' column='1'/> - <parameter type-id='type-id-8' name='smartquotes' filepath='Objects/bytesobject.c' line='1302' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyBytes_ReverseFind' mangled-name='_PyBytes_ReverseFind' filepath='Objects/bytesobject.c' line='1293' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyBytes_ReverseFind'> - <parameter type-id='type-id-3' name='haystack' filepath='Objects/bytesobject.c' line='1293' column='1'/> - <parameter type-id='type-id-36' name='len_haystack' filepath='Objects/bytesobject.c' line='1293' column='1'/> - <parameter type-id='type-id-3' name='needle' filepath='Objects/bytesobject.c' line='1294' column='1'/> - <parameter type-id='type-id-36' name='len_needle' filepath='Objects/bytesobject.c' line='1294' column='1'/> - <parameter type-id='type-id-36' name='offset' filepath='Objects/bytesobject.c' line='1295' column='1'/> - <return type-id='type-id-36'/> - </function-decl> - <function-decl name='_PyBytes_Find' mangled-name='_PyBytes_Find' filepath='Objects/bytesobject.c' line='1284' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyBytes_Find'> - <parameter type-id='type-id-3' name='haystack' filepath='Objects/bytesobject.c' line='1293' column='1'/> - <parameter type-id='type-id-36' name='len_haystack' filepath='Objects/bytesobject.c' line='1293' column='1'/> - <parameter type-id='type-id-3' name='needle' filepath='Objects/bytesobject.c' line='1294' column='1'/> - <parameter type-id='type-id-36' name='len_needle' filepath='Objects/bytesobject.c' line='1294' column='1'/> - <parameter type-id='type-id-36' name='offset' filepath='Objects/bytesobject.c' line='1295' column='1'/> - <return type-id='type-id-36'/> - </function-decl> - <pointer-type-def type-id='type-id-115' size-in-bits='64' id='type-id-494'/> - <function-decl name='PyBytes_AsStringAndSize' mangled-name='PyBytes_AsStringAndSize' filepath='Objects/bytesobject.c' line='1237' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyBytes_AsStringAndSize'> - <parameter type-id='type-id-14' name='obj' filepath='Objects/bytesobject.c' line='1237' column='1'/> - <parameter type-id='type-id-494' name='s' filepath='Objects/bytesobject.c' line='1238' column='1'/> - <parameter type-id='type-id-168' name='len' filepath='Objects/bytesobject.c' line='1239' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyBytes_AsString' mangled-name='PyBytes_AsString' filepath='Objects/bytesobject.c' line='1226' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyBytes_AsString'> - <parameter type-id='type-id-14' name='self' filepath='Objects/bytearrayobject.c' line='161' column='1'/> - <return type-id='type-id-115'/> - </function-decl> - <function-decl name='PyBytes_Size' mangled-name='PyBytes_Size' filepath='Objects/bytesobject.c' line='1215' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyBytes_Size'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2335' column='1'/> - <return type-id='type-id-36'/> - </function-decl> - <function-decl name='PyBytes_DecodeEscape' mangled-name='PyBytes_DecodeEscape' filepath='Objects/bytesobject.c' line='1176' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyBytes_DecodeEscape'> - <parameter type-id='type-id-3' name='s' filepath='Objects/bytesobject.c' line='1176' column='1'/> - <parameter type-id='type-id-36' name='len' filepath='Objects/bytesobject.c' line='1177' column='1'/> - <parameter type-id='type-id-3' name='errors' filepath='Objects/bytesobject.c' line='1178' column='1'/> - <parameter type-id='type-id-36' name='_unused_unicode' filepath='Objects/bytesobject.c' line='1179' column='1'/> - <parameter type-id='type-id-3' name='_unused_recode_encoding' filepath='Objects/bytesobject.c' line='1180' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyBytes_DecodeEscape' mangled-name='_PyBytes_DecodeEscape' filepath='Objects/bytesobject.c' line='1062' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyBytes_DecodeEscape'> - <parameter type-id='type-id-3' name='s' filepath='Objects/bytesobject.c' line='1062' column='1'/> - <parameter type-id='type-id-36' name='len' filepath='Objects/bytesobject.c' line='1063' column='1'/> - <parameter type-id='type-id-3' name='errors' filepath='Objects/bytesobject.c' line='1064' column='1'/> - <parameter type-id='type-id-483' name='first_invalid_escape' filepath='Objects/bytesobject.c' line='1065' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyBytes_FormatEx' mangled-name='_PyBytes_FormatEx' filepath='Objects/bytesobject.c' line='581' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyBytes_FormatEx'> - <parameter type-id='type-id-3' name='format' filepath='Objects/bytesobject.c' line='581' column='1'/> - <parameter type-id='type-id-36' name='format_len' filepath='Objects/bytesobject.c' line='581' column='1'/> - <parameter type-id='type-id-14' name='args' filepath='Objects/bytesobject.c' line='582' column='1'/> - <parameter type-id='type-id-8' name='use_bytearray' filepath='Objects/bytesobject.c' line='582' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyBytes_FromFormat' mangled-name='PyBytes_FromFormat' filepath='Objects/bytesobject.c' line='375' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyBytes_FromFormat'> - <parameter type-id='type-id-3' name='format' filepath='Objects/bytesobject.c' line='375' column='1'/> - <parameter is-variadic='yes'/> - <return type-id='type-id-14'/> - </function-decl> - <class-decl name='__va_list_tag' size-in-bits='192' is-struct='yes' visibility='default' id='type-id-495'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='gp_offset' type-id='type-id-105' visibility='default'/> - </data-member> - <data-member access='public' layout-offset-in-bits='32'> - <var-decl name='fp_offset' type-id='type-id-105' visibility='default'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='overflow_arg_area' type-id='type-id-18' visibility='default'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='reg_save_area' type-id='type-id-18' visibility='default'/> - </data-member> - </class-decl> - <pointer-type-def type-id='type-id-495' size-in-bits='64' id='type-id-496'/> - <function-decl name='PyBytes_FromFormatV' mangled-name='PyBytes_FromFormatV' filepath='Objects/bytesobject.c' line='184' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyBytes_FromFormatV'> - <parameter type-id='type-id-3' name='format' filepath='Objects/bytesobject.c' line='184' column='1'/> - <parameter type-id='type-id-496' name='vargs' filepath='Objects/bytesobject.c' line='184' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyBytes_FromString' mangled-name='PyBytes_FromString' filepath='Objects/bytesobject.c' line='147' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyBytes_FromString'> - <parameter type-id='type-id-3' name='str' filepath='Objects/bytesobject.c' line='147' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyBytes_FromStringAndSize' mangled-name='PyBytes_FromStringAndSize' filepath='Objects/bytesobject.c' line='119' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyBytes_FromStringAndSize'> - <parameter type-id='type-id-3' name='str' filepath='Objects/bytesobject.c' line='119' column='1'/> - <parameter type-id='type-id-36' name='size' filepath='Objects/bytesobject.c' line='119' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Objects/call.c' comp-dir-path='/src' language='LANG_C99'> - <function-decl name='_PyStack_AsDict' mangled-name='_PyStack_AsDict' filepath='Objects/call.c' line='935' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyStack_AsDict'> - <parameter type-id='type-id-200' name='values' filepath='Objects/call.c' line='935' column='1'/> - <parameter type-id='type-id-14' name='kwnames' filepath='Objects/call.c' line='935' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyObject_CallFunctionObjArgs' mangled-name='PyObject_CallFunctionObjArgs' filepath='Objects/call.c' line='918' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_CallFunctionObjArgs'> - <parameter type-id='type-id-14' name='callable' filepath='Objects/call.c' line='918' column='1'/> - <parameter is-variadic='yes'/> - <return type-id='type-id-14'/> - </function-decl> - <class-decl name='_Py_Identifier' size-in-bits='128' is-struct='yes' visibility='default' filepath='./Include/cpython/object.h' line='37' column='1' id='type-id-497'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='string' type-id='type-id-3' visibility='default' filepath='./Include/cpython/object.h' line='38' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='index' type-id='type-id-36' visibility='default' filepath='./Include/cpython/object.h' line='41' column='1'/> - </data-member> - </class-decl> - <typedef-decl name='_Py_Identifier' type-id='type-id-497' filepath='./Include/cpython/object.h' line='42' column='1' id='type-id-498'/> - <pointer-type-def type-id='type-id-498' size-in-bits='64' id='type-id-499'/> - <function-decl name='_PyObject_CallMethodIdObjArgs' mangled-name='_PyObject_CallMethodIdObjArgs' filepath='Objects/call.c' line='888' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_CallMethodIdObjArgs'> - <parameter type-id='type-id-14' name='obj' filepath='Objects/call.c' line='888' column='1'/> - <parameter type-id='type-id-499' name='name' filepath='Objects/call.c' line='888' column='1'/> - <parameter is-variadic='yes'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyObject_CallMethodObjArgs' mangled-name='PyObject_CallMethodObjArgs' filepath='Objects/call.c' line='863' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_CallMethodObjArgs'> - <parameter type-id='type-id-14' name='obj' filepath='Objects/call.c' line='863' column='1'/> - <parameter type-id='type-id-14' name='name' filepath='Objects/call.c' line='863' column='1'/> - <parameter is-variadic='yes'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyObject_VectorcallMethod' mangled-name='PyObject_VectorcallMethod' filepath='Objects/call.c' line='829' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_VectorcallMethod'> - <parameter type-id='type-id-14' name='name' filepath='Objects/call.c' line='829' column='1'/> - <parameter type-id='type-id-200' name='args' filepath='Objects/call.c' line='829' column='1'/> - <parameter type-id='type-id-54' name='nargsf' filepath='Objects/call.c' line='830' column='1'/> - <parameter type-id='type-id-14' name='kwnames' filepath='Objects/call.c' line='830' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyObject_CallMethodId_SizeT' mangled-name='_PyObject_CallMethodId_SizeT' filepath='Objects/call.c' line='745' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_CallMethodId_SizeT'> - <parameter type-id='type-id-14' name='obj' filepath='Objects/call.c' line='745' column='1'/> - <parameter type-id='type-id-499' name='name' filepath='Objects/call.c' line='745' column='1'/> - <parameter type-id='type-id-3' name='format' filepath='Objects/call.c' line='746' column='1'/> - <parameter is-variadic='yes'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyObject_CallMethod_SizeT' mangled-name='_PyObject_CallMethod_SizeT' filepath='Objects/call.c' line='721' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_CallMethod_SizeT'> - <parameter type-id='type-id-14' name='obj' filepath='Objects/call.c' line='721' column='1'/> - <parameter type-id='type-id-3' name='name' filepath='Objects/call.c' line='721' column='1'/> - <parameter type-id='type-id-3' name='format' filepath='Objects/call.c' line='722' column='1'/> - <parameter is-variadic='yes'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyObject_CallMethodId' mangled-name='_PyObject_CallMethodId' filepath='Objects/call.c' line='686' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_CallMethodId'> - <parameter type-id='type-id-14' name='obj' filepath='Objects/call.c' line='745' column='1'/> - <parameter type-id='type-id-499' name='name' filepath='Objects/call.c' line='745' column='1'/> - <parameter type-id='type-id-3' name='format' filepath='Objects/call.c' line='746' column='1'/> - <parameter is-variadic='yes'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyObject_CallMethod' mangled-name='_PyObject_CallMethod' filepath='Objects/call.c' line='662' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_CallMethod'> - <parameter type-id='type-id-14' name='obj' filepath='Objects/call.c' line='662' column='1'/> - <parameter type-id='type-id-14' name='name' filepath='Objects/call.c' line='662' column='1'/> - <parameter type-id='type-id-3' name='format' filepath='Objects/call.c' line='663' column='1'/> - <parameter is-variadic='yes'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyEval_CallMethod' mangled-name='PyEval_CallMethod' filepath='Objects/call.c' line='639' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyEval_CallMethod'> - <parameter type-id='type-id-14' name='obj' filepath='Objects/call.c' line='721' column='1'/> - <parameter type-id='type-id-3' name='name' filepath='Objects/call.c' line='721' column='1'/> - <parameter type-id='type-id-3' name='format' filepath='Objects/call.c' line='722' column='1'/> - <parameter is-variadic='yes'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyObject_CallMethod' mangled-name='PyObject_CallMethod' filepath='Objects/call.c' line='612' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_CallMethod'> - <parameter type-id='type-id-14' name='obj' filepath='Objects/call.c' line='721' column='1'/> - <parameter type-id='type-id-3' name='name' filepath='Objects/call.c' line='721' column='1'/> - <parameter type-id='type-id-3' name='format' filepath='Objects/call.c' line='722' column='1'/> - <parameter is-variadic='yes'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyObject_CallFunction_SizeT' mangled-name='_PyObject_CallFunction_SizeT' filepath='Objects/call.c' line='584' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_CallFunction_SizeT'> - <parameter type-id='type-id-14' name='callable' filepath='Objects/call.c' line='584' column='1'/> - <parameter type-id='type-id-3' name='format' filepath='Objects/call.c' line='584' column='1'/> - <parameter is-variadic='yes'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyEval_CallFunction' mangled-name='PyEval_CallFunction' filepath='Objects/call.c' line='569' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyEval_CallFunction'> - <parameter type-id='type-id-14' name='callable' filepath='Objects/call.c' line='584' column='1'/> - <parameter type-id='type-id-3' name='format' filepath='Objects/call.c' line='584' column='1'/> - <parameter is-variadic='yes'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyObject_CallFunction' mangled-name='PyObject_CallFunction' filepath='Objects/call.c' line='551' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_CallFunction'> - <parameter type-id='type-id-14' name='callable' filepath='Objects/call.c' line='584' column='1'/> - <parameter type-id='type-id-3' name='format' filepath='Objects/call.c' line='584' column='1'/> - <parameter is-variadic='yes'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyObject_Call_Prepend' mangled-name='_PyObject_Call_Prepend' filepath='Objects/call.c' line='456' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_Call_Prepend'> - <parameter type-id='type-id-10' name='tstate' filepath='Objects/call.c' line='456' column='1'/> - <parameter type-id='type-id-14' name='callable' filepath='Objects/call.c' line='456' column='1'/> - <parameter type-id='type-id-14' name='obj' filepath='Objects/call.c' line='457' column='1'/> - <parameter type-id='type-id-14' name='args' filepath='Objects/call.c' line='457' column='1'/> - <parameter type-id='type-id-14' name='kwargs' filepath='Objects/call.c' line='457' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyObject_CallObject' mangled-name='PyObject_CallObject' filepath='Objects/call.c' line='438' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_CallObject'> - <parameter type-id='type-id-14' name='callable' filepath='Objects/call.c' line='438' column='1'/> - <parameter type-id='type-id-14' name='args' filepath='Objects/call.c' line='438' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyEval_CallObjectWithKeywords' mangled-name='PyEval_CallObjectWithKeywords' filepath='Objects/call.c' line='405' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyEval_CallObjectWithKeywords'> - <parameter type-id='type-id-14' name='callable' filepath='Objects/call.c' line='405' column='1'/> - <parameter type-id='type-id-14' name='args' filepath='Objects/call.c' line='406' column='1'/> - <parameter type-id='type-id-14' name='kwargs' filepath='Objects/call.c' line='406' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyFunction_Vectorcall' mangled-name='_PyFunction_Vectorcall' filepath='Objects/call.c' line='383' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyFunction_Vectorcall'> - <parameter type-id='type-id-14' name='func' filepath='Objects/call.c' line='383' column='1'/> - <parameter type-id='type-id-200' name='stack' filepath='Objects/call.c' line='383' column='1'/> - <parameter type-id='type-id-54' name='nargsf' filepath='Objects/call.c' line='384' column='1'/> - <parameter type-id='type-id-14' name='kwnames' filepath='Objects/call.c' line='384' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyObject_CallOneArg' mangled-name='PyObject_CallOneArg' filepath='Objects/call.c' line='368' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_CallOneArg'> - <parameter type-id='type-id-14' name='func' filepath='Objects/call.c' line='368' column='1'/> - <parameter type-id='type-id-14' name='arg' filepath='Objects/call.c' line='368' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyCFunction_Call' mangled-name='PyCFunction_Call' filepath='Objects/call.c' line='360' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCFunction_Call'> - <parameter type-id='type-id-14' name='callable' filepath='Objects/call.c' line='405' column='1'/> - <parameter type-id='type-id-14' name='args' filepath='Objects/call.c' line='406' column='1'/> - <parameter type-id='type-id-14' name='kwargs' filepath='Objects/call.c' line='406' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyObject_Call' mangled-name='PyObject_Call' filepath='Objects/call.c' line='352' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_Call'> - <parameter type-id='type-id-14' name='callable' filepath='Objects/call.c' line='405' column='1'/> - <parameter type-id='type-id-14' name='args' filepath='Objects/call.c' line='406' column='1'/> - <parameter type-id='type-id-14' name='kwargs' filepath='Objects/call.c' line='406' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyObject_Call' mangled-name='_PyObject_Call' filepath='Objects/call.c' line='313' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_Call'> - <parameter type-id='type-id-10' name='tstate' filepath='Objects/call.c' line='313' column='1'/> - <parameter type-id='type-id-14' name='callable' filepath='Objects/call.c' line='313' column='1'/> - <parameter type-id='type-id-14' name='args' filepath='Objects/call.c' line='314' column='1'/> - <parameter type-id='type-id-14' name='kwargs' filepath='Objects/call.c' line='314' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyObject_FastCall' mangled-name='_PyObject_FastCall' filepath='Objects/call.c' line='305' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_FastCall'> - <parameter type-id='type-id-14' name='func' filepath='Objects/call.c' line='305' column='1'/> - <parameter type-id='type-id-200' name='args' filepath='Objects/call.c' line='305' column='1'/> - <parameter type-id='type-id-36' name='nargs' filepath='Objects/call.c' line='305' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyObject_Vectorcall' mangled-name='PyObject_Vectorcall' filepath='Objects/call.c' line='295' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_Vectorcall'> - <parameter type-id='type-id-14' name='callable' filepath='Objects/call.c' line='295' column='1'/> - <parameter type-id='type-id-200' name='args' filepath='Objects/call.c' line='295' column='1'/> - <parameter type-id='type-id-54' name='nargsf' filepath='Objects/call.c' line='296' column='1'/> - <parameter type-id='type-id-14' name='kwnames' filepath='Objects/call.c' line='296' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyVectorcall_Call' mangled-name='PyVectorcall_Call' filepath='Objects/call.c' line='266' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyVectorcall_Call'> - <parameter type-id='type-id-14' name='callable' filepath='Objects/call.c' line='266' column='1'/> - <parameter type-id='type-id-14' name='tuple' filepath='Objects/call.c' line='266' column='1'/> - <parameter type-id='type-id-14' name='kwargs' filepath='Objects/call.c' line='266' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyVectorcall_Function' mangled-name='PyVectorcall_Function' filepath='Objects/call.c' line='229' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyVectorcall_Function'> - <parameter type-id='type-id-14' name='callable' filepath='Objects/call.c' line='229' column='1'/> - <return type-id='type-id-106'/> - </function-decl> - <function-decl name='_PyObject_MakeTpCall' mangled-name='_PyObject_MakeTpCall' filepath='Objects/call.c' line='170' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_MakeTpCall'> - <parameter type-id='type-id-10' name='tstate' filepath='Objects/call.c' line='170' column='1'/> - <parameter type-id='type-id-14' name='callable' filepath='Objects/call.c' line='170' column='1'/> - <parameter type-id='type-id-200' name='args' filepath='Objects/call.c' line='171' column='1'/> - <parameter type-id='type-id-36' name='nargs' filepath='Objects/call.c' line='171' column='1'/> - <parameter type-id='type-id-14' name='keywords' filepath='Objects/call.c' line='172' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyObject_VectorcallDict' mangled-name='PyObject_VectorcallDict' filepath='Objects/call.c' line='161' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_VectorcallDict'> - <parameter type-id='type-id-14' name='callable' filepath='Objects/call.c' line='295' column='1'/> - <parameter type-id='type-id-200' name='args' filepath='Objects/call.c' line='295' column='1'/> - <parameter type-id='type-id-54' name='nargsf' filepath='Objects/call.c' line='296' column='1'/> - <parameter type-id='type-id-14' name='kwnames' filepath='Objects/call.c' line='296' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyObject_FastCallDictTstate' mangled-name='_PyObject_FastCallDictTstate' filepath='Objects/call.c' line='117' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_FastCallDictTstate'> - <parameter type-id='type-id-10' name='tstate' filepath='Objects/call.c' line='117' column='1'/> - <parameter type-id='type-id-14' name='callable' filepath='Objects/call.c' line='117' column='1'/> - <parameter type-id='type-id-200' name='args' filepath='Objects/call.c' line='118' column='1'/> - <parameter type-id='type-id-54' name='nargsf' filepath='Objects/call.c' line='118' column='1'/> - <parameter type-id='type-id-14' name='kwargs' filepath='Objects/call.c' line='119' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyObject_CallNoArgs' mangled-name='PyObject_CallNoArgs' filepath='Objects/call.c' line='110' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_CallNoArgs'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2462' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_Py_CheckFunctionResult' mangled-name='_Py_CheckFunctionResult' filepath='Objects/call.c' line='33' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_CheckFunctionResult'> - <parameter type-id='type-id-10' name='tstate' filepath='Objects/call.c' line='33' column='1'/> - <parameter type-id='type-id-14' name='callable' filepath='Objects/call.c' line='33' column='1'/> - <parameter type-id='type-id-14' name='result' filepath='Objects/call.c' line='34' column='1'/> - <parameter type-id='type-id-3' name='where' filepath='Objects/call.c' line='34' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Objects/capsule.c' comp-dir-path='/src' language='LANG_C99'> - <var-decl name='PyCapsule_Type' type-id='type-id-112' mangled-name='PyCapsule_Type' visibility='default' filepath='./Include/pycapsule.h' line='21' column='1' elf-symbol-id='PyCapsule_Type'/> - <function-decl name='PyCapsule_Import' mangled-name='PyCapsule_Import' filepath='Objects/capsule.c' line='195' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCapsule_Import'> - <parameter type-id='type-id-3' name='name' filepath='Objects/capsule.c' line='195' column='1'/> - <parameter type-id='type-id-8' name='no_block' filepath='Objects/capsule.c' line='195' column='1'/> - <return type-id='type-id-18'/> - </function-decl> - <function-decl name='PyCapsule_SetContext' mangled-name='PyCapsule_SetContext' filepath='Objects/capsule.c' line='181' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCapsule_SetContext'> - <parameter type-id='type-id-14' name='o' filepath='Objects/capsule.c' line='181' column='1'/> - <parameter type-id='type-id-18' name='context' filepath='Objects/capsule.c' line='181' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <typedef-decl name='PyCapsule_Destructor' type-id='type-id-114' filepath='./Include/pycapsule.h' line='23' column='1' id='type-id-500'/> - <function-decl name='PyCapsule_SetDestructor' mangled-name='PyCapsule_SetDestructor' filepath='Objects/capsule.c' line='167' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCapsule_SetDestructor'> - <parameter type-id='type-id-14' name='o' filepath='Objects/capsule.c' line='167' column='1'/> - <parameter type-id='type-id-500' name='destructor' filepath='Objects/capsule.c' line='167' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyCapsule_SetName' mangled-name='PyCapsule_SetName' filepath='Objects/capsule.c' line='153' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCapsule_SetName'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2378' column='1'/> - <parameter type-id='type-id-3' name='key' filepath='Objects/abstract.c' line='2378' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyCapsule_SetPointer' mangled-name='PyCapsule_SetPointer' filepath='Objects/capsule.c' line='134' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCapsule_SetPointer'> - <parameter type-id='type-id-14' name='o' filepath='Objects/capsule.c' line='181' column='1'/> - <parameter type-id='type-id-18' name='context' filepath='Objects/capsule.c' line='181' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyCapsule_GetContext' mangled-name='PyCapsule_GetContext' filepath='Objects/capsule.c' line='122' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCapsule_GetContext'> - <parameter type-id='type-id-14' name='o' filepath='Objects/capsule.c' line='122' column='1'/> - <return type-id='type-id-18'/> - </function-decl> - <function-decl name='PyCapsule_GetDestructor' mangled-name='PyCapsule_GetDestructor' filepath='Objects/capsule.c' line='110' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCapsule_GetDestructor'> - <parameter type-id='type-id-14' name='o' filepath='Objects/capsule.c' line='110' column='1'/> - <return type-id='type-id-500'/> - </function-decl> - <function-decl name='PyCapsule_GetName' mangled-name='PyCapsule_GetName' filepath='Objects/capsule.c' line='98' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCapsule_GetName'> - <parameter type-id='type-id-14' name='o' filepath='Objects/capsule.c' line='98' column='1'/> - <return type-id='type-id-3'/> - </function-decl> - <function-decl name='PyCapsule_GetPointer' mangled-name='PyCapsule_GetPointer' filepath='Objects/capsule.c' line='80' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCapsule_GetPointer'> - <parameter type-id='type-id-14' name='o' filepath='Objects/capsule.c' line='80' column='1'/> - <parameter type-id='type-id-3' name='name' filepath='Objects/capsule.c' line='80' column='1'/> - <return type-id='type-id-18'/> - </function-decl> - <function-decl name='PyCapsule_IsValid' mangled-name='PyCapsule_IsValid' filepath='Objects/capsule.c' line='68' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCapsule_IsValid'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2378' column='1'/> - <parameter type-id='type-id-3' name='key' filepath='Objects/abstract.c' line='2378' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyCapsule_New' mangled-name='PyCapsule_New' filepath='Objects/capsule.c' line='44' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCapsule_New'> - <parameter type-id='type-id-18' name='pointer' filepath='Objects/capsule.c' line='44' column='1'/> - <parameter type-id='type-id-3' name='name' filepath='Objects/capsule.c' line='44' column='1'/> - <parameter type-id='type-id-500' name='destructor' filepath='Objects/capsule.c' line='44' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Objects/cellobject.c' comp-dir-path='/src' language='LANG_C99'> - <var-decl name='PyCell_Type' type-id='type-id-112' mangled-name='PyCell_Type' visibility='default' filepath='./Include/cpython/cellobject.h' line='16' column='1' elf-symbol-id='PyCell_Type'/> - <function-decl name='PyCell_Set' mangled-name='PyCell_Set' filepath='Objects/cellobject.c' line='64' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCell_Set'> - <parameter type-id='type-id-14' name='derived' filepath='Objects/abstract.c' line='2770' column='1'/> - <parameter type-id='type-id-14' name='cls' filepath='Objects/abstract.c' line='2770' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyCell_Get' mangled-name='PyCell_Get' filepath='Objects/cellobject.c' line='53' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCell_Get'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2462' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyCell_New' mangled-name='PyCell_New' filepath='Objects/cellobject.c' line='7' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCell_New'> - <parameter type-id='type-id-14' name='item' filepath='Objects/abstract.c' line='1408' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Objects/classobject.c' comp-dir-path='/src' language='LANG_C99'> - <class-decl name='PyMemberDef' size-in-bits='320' is-struct='yes' visibility='default' filepath='./Include/structmember.h' line='18' column='1' id='type-id-184'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='name' type-id='type-id-3' visibility='default' filepath='./Include/structmember.h' line='19' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='type' type-id='type-id-8' visibility='default' filepath='./Include/structmember.h' line='20' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='offset' type-id='type-id-36' visibility='default' filepath='./Include/structmember.h' line='21' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='flags' type-id='type-id-8' visibility='default' filepath='./Include/structmember.h' line='22' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='256'> - <var-decl name='doc' type-id='type-id-3' visibility='default' filepath='./Include/structmember.h' line='23' column='1'/> - </data-member> - </class-decl> - <var-decl name='PyMethod_Type' type-id='type-id-112' mangled-name='PyMethod_Type' visibility='default' filepath='./Include/cpython/classobject.h' line='20' column='1' elf-symbol-id='PyMethod_Type'/> - <var-decl name='PyInstanceMethod_Type' type-id='type-id-112' mangled-name='PyInstanceMethod_Type' visibility='default' filepath='./Include/cpython/classobject.h' line='41' column='1' elf-symbol-id='PyInstanceMethod_Type'/> - <function-decl name='PyInstanceMethod_Function' mangled-name='PyInstanceMethod_Function' filepath='Objects/classobject.c' line='369' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInstanceMethod_Function'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2462' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyInstanceMethod_New' mangled-name='PyInstanceMethod_New' filepath='Objects/classobject.c' line='357' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInstanceMethod_New'> - <parameter type-id='type-id-14' name='item' filepath='Objects/abstract.c' line='1408' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyMethod_New' mangled-name='PyMethod_New' filepath='Objects/classobject.c' line='105' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMethod_New'> - <parameter type-id='type-id-14' name='callable' filepath='Objects/call.c' line='438' column='1'/> - <parameter type-id='type-id-14' name='args' filepath='Objects/call.c' line='438' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyMethod_Self' mangled-name='PyMethod_Self' filepath='Objects/classobject.c' line='31' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMethod_Self'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2462' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyMethod_Function' mangled-name='PyMethod_Function' filepath='Objects/classobject.c' line='21' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMethod_Function'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2462' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Objects/codeobject.c' comp-dir-path='/src' language='LANG_C99'> - <var-decl name='PyCode_Type' type-id='type-id-112' mangled-name='PyCode_Type' visibility='default' filepath='./Include/cpython/code.h' line='140' column='1' elf-symbol-id='PyCode_Type'/> - <function-decl name='_PyCode_ConstantKey' mangled-name='_PyCode_ConstantKey' filepath='Objects/codeobject.c' line='2020' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyCode_ConstantKey'> - <parameter type-id='type-id-14' name='op' filepath='Objects/codeobject.c' line='2020' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyCode_GetCode' mangled-name='PyCode_GetCode' filepath='Objects/codeobject.c' line='1446' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCode_GetCode'> - <parameter type-id='type-id-444' name='co' filepath='Objects/codeobject.c' line='1446' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyCode_SetExtra' mangled-name='_PyCode_SetExtra' filepath='Objects/codeobject.c' line='1351' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyCode_SetExtra'> - <parameter type-id='type-id-14' name='code' filepath='Objects/codeobject.c' line='1351' column='1'/> - <parameter type-id='type-id-36' name='index' filepath='Objects/codeobject.c' line='1351' column='1'/> - <parameter type-id='type-id-18' name='extra' filepath='Objects/codeobject.c' line='1351' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyCode_GetExtra' mangled-name='_PyCode_GetExtra' filepath='Objects/codeobject.c' line='1330' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyCode_GetExtra'> - <parameter type-id='type-id-14' name='code' filepath='Objects/codeobject.c' line='1330' column='1'/> - <parameter type-id='type-id-36' name='index' filepath='Objects/codeobject.c' line='1330' column='1'/> - <parameter type-id='type-id-482' name='extra' filepath='Objects/codeobject.c' line='1330' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <pointer-type-def type-id='type-id-8' size-in-bits='64' id='type-id-501'/> - <function-decl name='PyCode_Addr2Location' mangled-name='PyCode_Addr2Location' filepath='Objects/codeobject.c' line='965' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCode_Addr2Location'> - <parameter type-id='type-id-444' name='co' filepath='Objects/codeobject.c' line='965' column='1'/> - <parameter type-id='type-id-8' name='addrq' filepath='Objects/codeobject.c' line='965' column='1'/> - <parameter type-id='type-id-501' name='start_line' filepath='Objects/codeobject.c' line='966' column='1'/> - <parameter type-id='type-id-501' name='start_column' filepath='Objects/codeobject.c' line='966' column='1'/> - <parameter type-id='type-id-501' name='end_line' filepath='Objects/codeobject.c' line='967' column='1'/> - <parameter type-id='type-id-501' name='end_column' filepath='Objects/codeobject.c' line='967' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <pointer-type-def type-id='type-id-445' size-in-bits='64' id='type-id-502'/> - <function-decl name='_PyCode_CheckLineNumber' mangled-name='_PyCode_CheckLineNumber' filepath='Objects/codeobject.c' line='788' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyCode_CheckLineNumber'> - <parameter type-id='type-id-8' name='lasti' filepath='Objects/codeobject.c' line='788' column='1'/> - <parameter type-id='type-id-502' name='bounds' filepath='Objects/codeobject.c' line='788' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyCode_Addr2Line' mangled-name='PyCode_Addr2Line' filepath='Objects/codeobject.c' line='750' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCode_Addr2Line'> - <parameter type-id='type-id-444' name='co' filepath='Objects/codeobject.c' line='750' column='1'/> - <parameter type-id='type-id-8' name='addrq' filepath='Objects/codeobject.c' line='750' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyCode_NewEmpty' mangled-name='PyCode_NewEmpty' filepath='Objects/codeobject.c' line='646' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCode_NewEmpty'> - <parameter type-id='type-id-3' name='filename' filepath='Objects/codeobject.c' line='646' column='1'/> - <parameter type-id='type-id-3' name='funcname' filepath='Objects/codeobject.c' line='646' column='1'/> - <parameter type-id='type-id-8' name='firstlineno' filepath='Objects/codeobject.c' line='646' column='1'/> - <return type-id='type-id-444'/> - </function-decl> - <function-decl name='PyCode_New' mangled-name='PyCode_New' filepath='Objects/codeobject.c' line='622' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCode_New'> - <parameter type-id='type-id-8' name='argcount' filepath='Objects/codeobject.c' line='622' column='1'/> - <parameter type-id='type-id-8' name='kwonlyargcount' filepath='Objects/codeobject.c' line='622' column='1'/> - <parameter type-id='type-id-8' name='nlocals' filepath='Objects/codeobject.c' line='623' column='1'/> - <parameter type-id='type-id-8' name='stacksize' filepath='Objects/codeobject.c' line='623' column='1'/> - <parameter type-id='type-id-8' name='flags' filepath='Objects/codeobject.c' line='623' column='1'/> - <parameter type-id='type-id-14' name='code' filepath='Objects/codeobject.c' line='624' column='1'/> - <parameter type-id='type-id-14' name='consts' filepath='Objects/codeobject.c' line='624' column='1'/> - <parameter type-id='type-id-14' name='names' filepath='Objects/codeobject.c' line='624' column='1'/> - <parameter type-id='type-id-14' name='varnames' filepath='Objects/codeobject.c' line='625' column='1'/> - <parameter type-id='type-id-14' name='freevars' filepath='Objects/codeobject.c' line='625' column='1'/> - <parameter type-id='type-id-14' name='cellvars' filepath='Objects/codeobject.c' line='625' column='1'/> - <parameter type-id='type-id-14' name='filename' filepath='Objects/codeobject.c' line='626' column='1'/> - <parameter type-id='type-id-14' name='name' filepath='Objects/codeobject.c' line='626' column='1'/> - <parameter type-id='type-id-14' name='qualname' filepath='Objects/codeobject.c' line='626' column='1'/> - <parameter type-id='type-id-8' name='firstlineno' filepath='Objects/codeobject.c' line='627' column='1'/> - <parameter type-id='type-id-14' name='linetable' filepath='Objects/codeobject.c' line='628' column='1'/> - <parameter type-id='type-id-14' name='exceptiontable' filepath='Objects/codeobject.c' line='629' column='1'/> - <return type-id='type-id-444'/> - </function-decl> - <function-decl name='PyCode_NewWithPosOnlyArgs' mangled-name='PyCode_NewWithPosOnlyArgs' filepath='Objects/codeobject.c' line='498' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCode_NewWithPosOnlyArgs'> - <parameter type-id='type-id-8' name='argcount' filepath='Objects/codeobject.c' line='498' column='1'/> - <parameter type-id='type-id-8' name='posonlyargcount' filepath='Objects/codeobject.c' line='498' column='1'/> - <parameter type-id='type-id-8' name='kwonlyargcount' filepath='Objects/codeobject.c' line='498' column='1'/> - <parameter type-id='type-id-8' name='nlocals' filepath='Objects/codeobject.c' line='499' column='1'/> - <parameter type-id='type-id-8' name='stacksize' filepath='Objects/codeobject.c' line='499' column='1'/> - <parameter type-id='type-id-8' name='flags' filepath='Objects/codeobject.c' line='499' column='1'/> - <parameter type-id='type-id-14' name='code' filepath='Objects/codeobject.c' line='500' column='1'/> - <parameter type-id='type-id-14' name='consts' filepath='Objects/codeobject.c' line='500' column='1'/> - <parameter type-id='type-id-14' name='names' filepath='Objects/codeobject.c' line='500' column='1'/> - <parameter type-id='type-id-14' name='varnames' filepath='Objects/codeobject.c' line='501' column='1'/> - <parameter type-id='type-id-14' name='freevars' filepath='Objects/codeobject.c' line='501' column='1'/> - <parameter type-id='type-id-14' name='cellvars' filepath='Objects/codeobject.c' line='501' column='1'/> - <parameter type-id='type-id-14' name='filename' filepath='Objects/codeobject.c' line='502' column='1'/> - <parameter type-id='type-id-14' name='name' filepath='Objects/codeobject.c' line='502' column='1'/> - <parameter type-id='type-id-14' name='qualname' filepath='Objects/codeobject.c' line='503' column='1'/> - <parameter type-id='type-id-8' name='firstlineno' filepath='Objects/codeobject.c' line='503' column='1'/> - <parameter type-id='type-id-14' name='linetable' filepath='Objects/codeobject.c' line='504' column='1'/> - <parameter type-id='type-id-14' name='exceptiontable' filepath='Objects/codeobject.c' line='505' column='1'/> - <return type-id='type-id-444'/> - </function-decl> - <class-decl name='_PyCodeConstructor' size-in-bits='896' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_code.h' line='168' column='1' id='type-id-503'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='filename' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_code.h' line='170' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='name' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_code.h' line='171' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='qualname' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_code.h' line='172' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='flags' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_code.h' line='173' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='256'> - <var-decl name='code' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_code.h' line='176' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='320'> - <var-decl name='firstlineno' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_code.h' line='177' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='384'> - <var-decl name='linetable' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_code.h' line='178' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='448'> - <var-decl name='consts' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_code.h' line='181' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='512'> - <var-decl name='names' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_code.h' line='182' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='576'> - <var-decl name='localsplusnames' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_code.h' line='185' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='640'> - <var-decl name='localspluskinds' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_code.h' line='186' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='704'> - <var-decl name='argcount' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_code.h' line='189' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='736'> - <var-decl name='posonlyargcount' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_code.h' line='190' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='768'> - <var-decl name='kwonlyargcount' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_code.h' line='192' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='800'> - <var-decl name='stacksize' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_code.h' line='195' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='832'> - <var-decl name='exceptiontable' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_code.h' line='198' column='1'/> - </data-member> - </class-decl> - <pointer-type-def type-id='type-id-503' size-in-bits='64' id='type-id-504'/> - <function-decl name='_PyCode_New' mangled-name='_PyCode_New' filepath='Objects/codeobject.c' line='446' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyCode_New'> - <parameter type-id='type-id-504' name='con' filepath='Objects/codeobject.c' line='446' column='1'/> - <return type-id='type-id-444'/> - </function-decl> - <function-decl name='_PyCode_Validate' mangled-name='_PyCode_Validate' filepath='Objects/codeobject.c' line='231' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyCode_Validate'> - <parameter type-id='type-id-504' name='con' filepath='Objects/codeobject.c' line='231' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Objects/complexobject.c' comp-dir-path='/src' language='LANG_C99'> - <var-decl name='PyComplex_Type' type-id='type-id-112' mangled-name='PyComplex_Type' visibility='default' filepath='./Include/complexobject.h' line='11' column='1' elf-symbol-id='PyComplex_Type'/> - <class-decl name='__anonymous_struct__' size-in-bits='128' is-struct='yes' is-anonymous='yes' naming-typedef-id='type-id-505' visibility='default' filepath='./Include/cpython/complexobject.h' line='5' column='1' id='type-id-506'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='real' type-id='type-id-391' visibility='default' filepath='./Include/cpython/complexobject.h' line='6' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='imag' type-id='type-id-391' visibility='default' filepath='./Include/cpython/complexobject.h' line='7' column='1'/> - </data-member> - </class-decl> - <typedef-decl name='Py_complex' type-id='type-id-506' filepath='./Include/cpython/complexobject.h' line='8' column='1' id='type-id-505'/> - <function-decl name='PyComplex_AsCComplex' mangled-name='PyComplex_AsCComplex' filepath='Objects/complexobject.c' line='314' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyComplex_AsCComplex'> - <parameter type-id='type-id-14' name='op' filepath='Objects/complexobject.c' line='314' column='1'/> - <return type-id='type-id-505'/> - </function-decl> - <function-decl name='PyComplex_ImagAsDouble' mangled-name='PyComplex_ImagAsDouble' filepath='Objects/complexobject.c' line='270' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyComplex_ImagAsDouble'> - <parameter type-id='type-id-14' name='op' filepath='Objects/complexobject.c' line='270' column='1'/> - <return type-id='type-id-391'/> - </function-decl> - <function-decl name='PyComplex_RealAsDouble' mangled-name='PyComplex_RealAsDouble' filepath='Objects/complexobject.c' line='259' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyComplex_RealAsDouble'> - <parameter type-id='type-id-14' name='op' filepath='Objects/complexobject.c' line='270' column='1'/> - <return type-id='type-id-391'/> - </function-decl> - <function-decl name='PyComplex_FromDoubles' mangled-name='PyComplex_FromDoubles' filepath='Objects/complexobject.c' line='250' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyComplex_FromDoubles'> - <parameter type-id='type-id-391' name='real' filepath='Objects/complexobject.c' line='250' column='1'/> - <parameter type-id='type-id-391' name='imag' filepath='Objects/complexobject.c' line='250' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyComplex_FromCComplex' mangled-name='PyComplex_FromCComplex' filepath='Objects/complexobject.c' line='228' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyComplex_FromCComplex'> - <parameter type-id='type-id-505' name='cval' filepath='Objects/complexobject.c' line='228' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_Py_c_abs' mangled-name='_Py_c_abs' filepath='Objects/complexobject.c' line='185' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_c_abs'> - <parameter type-id='type-id-505' name='z' filepath='Objects/complexobject.c' line='185' column='1'/> - <return type-id='type-id-391'/> - </function-decl> - <function-decl name='_Py_c_pow' mangled-name='_Py_c_pow' filepath='Objects/complexobject.c' line='129' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_c_pow'> - <parameter type-id='type-id-505' name='a' filepath='Objects/complexobject.c' line='129' column='1'/> - <parameter type-id='type-id-505' name='b' filepath='Objects/complexobject.c' line='129' column='1'/> - <return type-id='type-id-505'/> - </function-decl> - <function-decl name='_Py_c_quot' mangled-name='_Py_c_quot' filepath='Objects/complexobject.c' line='68' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_c_quot'> - <parameter type-id='type-id-505' name='a' filepath='Objects/complexobject.c' line='68' column='1'/> - <parameter type-id='type-id-505' name='b' filepath='Objects/complexobject.c' line='68' column='1'/> - <return type-id='type-id-505'/> - </function-decl> - <function-decl name='_Py_c_prod' mangled-name='_Py_c_prod' filepath='Objects/complexobject.c' line='55' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_c_prod'> - <parameter type-id='type-id-505' name='a' filepath='Objects/complexobject.c' line='55' column='1'/> - <parameter type-id='type-id-505' name='b' filepath='Objects/complexobject.c' line='55' column='1'/> - <return type-id='type-id-505'/> - </function-decl> - <function-decl name='_Py_c_neg' mangled-name='_Py_c_neg' filepath='Objects/complexobject.c' line='46' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_c_neg'> - <parameter type-id='type-id-505' name='a' filepath='Objects/complexobject.c' line='46' column='1'/> - <return type-id='type-id-505'/> - </function-decl> - <function-decl name='_Py_c_diff' mangled-name='_Py_c_diff' filepath='Objects/complexobject.c' line='37' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_c_diff'> - <parameter type-id='type-id-505' name='a' filepath='Objects/complexobject.c' line='55' column='1'/> - <parameter type-id='type-id-505' name='b' filepath='Objects/complexobject.c' line='55' column='1'/> - <return type-id='type-id-505'/> - </function-decl> - <function-decl name='_Py_c_sum' mangled-name='_Py_c_sum' filepath='Objects/complexobject.c' line='28' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_c_sum'> - <parameter type-id='type-id-505' name='a' filepath='Objects/complexobject.c' line='55' column='1'/> - <parameter type-id='type-id-505' name='b' filepath='Objects/complexobject.c' line='55' column='1'/> - <return type-id='type-id-505'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Objects/descrobject.c' comp-dir-path='/src' language='LANG_C99'> - <var-decl name='PyMethodDescr_Type' type-id='type-id-112' mangled-name='PyMethodDescr_Type' visibility='default' filepath='./Include/descrobject.h' line='22' column='1' elf-symbol-id='PyMethodDescr_Type'/> - <var-decl name='PyClassMethodDescr_Type' type-id='type-id-112' mangled-name='PyClassMethodDescr_Type' visibility='default' filepath='./Include/descrobject.h' line='19' column='1' elf-symbol-id='PyClassMethodDescr_Type'/> - <var-decl name='PyMemberDescr_Type' type-id='type-id-112' mangled-name='PyMemberDescr_Type' visibility='default' filepath='./Include/descrobject.h' line='21' column='1' elf-symbol-id='PyMemberDescr_Type'/> - <var-decl name='PyGetSetDescr_Type' type-id='type-id-112' mangled-name='PyGetSetDescr_Type' visibility='default' filepath='./Include/descrobject.h' line='20' column='1' elf-symbol-id='PyGetSetDescr_Type'/> - <var-decl name='PyWrapperDescr_Type' type-id='type-id-112' mangled-name='PyWrapperDescr_Type' visibility='default' filepath='./Include/descrobject.h' line='23' column='1' elf-symbol-id='PyWrapperDescr_Type'/> - <var-decl name='_PyMethodWrapper_Type' type-id='type-id-112' mangled-name='_PyMethodWrapper_Type' visibility='default' filepath='./Include/cpython/descrobject.h' line='60' column='1' elf-symbol-id='_PyMethodWrapper_Type'/> - <var-decl name='PyDictProxy_Type' type-id='type-id-112' mangled-name='PyDictProxy_Type' visibility='default' filepath='./Include/descrobject.h' line='24' column='1' elf-symbol-id='PyDictProxy_Type'/> - <var-decl name='PyProperty_Type' type-id='type-id-112' mangled-name='PyProperty_Type' visibility='default' filepath='./Include/descrobject.h' line='25' column='1' elf-symbol-id='PyProperty_Type'/> - <function-decl name='PyWrapper_New' mangled-name='PyWrapper_New' filepath='Objects/descrobject.c' line='1450' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyWrapper_New'> - <parameter type-id='type-id-14' name='v' filepath='Objects/abstract.c' line='1071' column='1'/> - <parameter type-id='type-id-14' name='w' filepath='Objects/abstract.c' line='1071' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyDictProxy_New' mangled-name='PyDictProxy_New' filepath='Objects/descrobject.c' line='1247' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyDictProxy_New'> - <parameter type-id='type-id-14' name='item' filepath='Objects/abstract.c' line='1408' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyDescr_IsData' mangled-name='PyDescr_IsData' filepath='Objects/descrobject.c' line='1017' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyDescr_IsData'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2303' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <class-decl name='wrapperbase' size-in-bits='448' is-struct='yes' visibility='default' filepath='./Include/cpython/descrobject.h' line='11' column='1' id='type-id-507'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='name' type-id='type-id-3' visibility='default' filepath='./Include/cpython/descrobject.h' line='12' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='offset' type-id='type-id-8' visibility='default' filepath='./Include/cpython/descrobject.h' line='13' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='function' type-id='type-id-18' visibility='default' filepath='./Include/cpython/descrobject.h' line='14' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='wrapper' type-id='type-id-508' visibility='default' filepath='./Include/cpython/descrobject.h' line='15' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='256'> - <var-decl name='doc' type-id='type-id-3' visibility='default' filepath='./Include/cpython/descrobject.h' line='16' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='320'> - <var-decl name='flags' type-id='type-id-8' visibility='default' filepath='./Include/cpython/descrobject.h' line='17' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='384'> - <var-decl name='name_strobj' type-id='type-id-14' visibility='default' filepath='./Include/cpython/descrobject.h' line='18' column='1'/> - </data-member> - </class-decl> - <pointer-type-def type-id='type-id-509' size-in-bits='64' id='type-id-510'/> - <typedef-decl name='wrapperfunc' type-id='type-id-510' filepath='./Include/cpython/descrobject.h' line='5' column='1' id='type-id-508'/> - <pointer-type-def type-id='type-id-507' size-in-bits='64' id='type-id-511'/> - <function-decl name='PyDescr_NewWrapper' mangled-name='PyDescr_NewWrapper' filepath='Objects/descrobject.c' line='1003' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyDescr_NewWrapper'> - <parameter type-id='type-id-74' name='type' filepath='Objects/descrobject.c' line='1003' column='1'/> - <parameter type-id='type-id-511' name='base' filepath='Objects/descrobject.c' line='1003' column='1'/> - <parameter type-id='type-id-18' name='wrapped' filepath='Objects/descrobject.c' line='1003' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyDescr_NewGetSet' mangled-name='PyDescr_NewGetSet' filepath='Objects/descrobject.c' line='991' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyDescr_NewGetSet'> - <parameter type-id='type-id-74' name='type' filepath='Objects/descrobject.c' line='991' column='1'/> - <parameter type-id='type-id-98' name='getset' filepath='Objects/descrobject.c' line='991' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyDescr_NewMember' mangled-name='PyDescr_NewMember' filepath='Objects/descrobject.c' line='979' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyDescr_NewMember'> - <parameter type-id='type-id-74' name='type' filepath='Objects/descrobject.c' line='979' column='1'/> - <parameter type-id='type-id-97' name='member' filepath='Objects/descrobject.c' line='979' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyDescr_NewClassMethod' mangled-name='PyDescr_NewClassMethod' filepath='Objects/descrobject.c' line='967' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyDescr_NewClassMethod'> - <parameter type-id='type-id-74' name='type' filepath='Objects/descrobject.c' line='967' column='1'/> - <parameter type-id='type-id-96' name='method' filepath='Objects/descrobject.c' line='967' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyDescr_NewMethod' mangled-name='PyDescr_NewMethod' filepath='Objects/descrobject.c' line='921' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyDescr_NewMethod'> - <parameter type-id='type-id-74' name='type' filepath='Objects/descrobject.c' line='921' column='1'/> - <parameter type-id='type-id-96' name='method' filepath='Objects/descrobject.c' line='921' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-type size-in-bits='64' id='type-id-509'> - <parameter type-id='type-id-14'/> - <parameter type-id='type-id-14'/> - <parameter type-id='type-id-18'/> - <return type-id='type-id-14'/> - </function-type> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Objects/enumobject.c' comp-dir-path='/src' language='LANG_C99'> - <var-decl name='PyEnum_Type' type-id='type-id-112' mangled-name='PyEnum_Type' visibility='default' filepath='./Include/enumobject.h' line='10' column='1' elf-symbol-id='PyEnum_Type'/> - <var-decl name='PyReversed_Type' type-id='type-id-112' mangled-name='PyReversed_Type' visibility='default' filepath='./Include/enumobject.h' line='11' column='1' elf-symbol-id='PyReversed_Type'/> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Objects/exceptions.c' comp-dir-path='/src' language='LANG_C99'> - <var-decl name='PyExc_EnvironmentError' type-id='type-id-14' mangled-name='PyExc_EnvironmentError' visibility='default' filepath='./Include/pyerrors.h' line='139' column='1' elf-symbol-id='PyExc_EnvironmentError'/> - <var-decl name='PyExc_IOError' type-id='type-id-14' mangled-name='PyExc_IOError' visibility='default' filepath='./Include/pyerrors.h' line='140' column='1' elf-symbol-id='PyExc_IOError'/> - <var-decl name='PyExc_BaseException' type-id='type-id-14' mangled-name='PyExc_BaseException' visibility='default' filepath='./Include/pyerrors.h' line='72' column='1' elf-symbol-id='PyExc_BaseException'/> - <var-decl name='PyExc_Exception' type-id='type-id-14' mangled-name='PyExc_Exception' visibility='default' filepath='./Include/pyerrors.h' line='73' column='1' elf-symbol-id='PyExc_Exception'/> - <var-decl name='PyExc_TypeError' type-id='type-id-14' mangled-name='PyExc_TypeError' visibility='default' filepath='./Include/pyerrors.h' line='110' column='1' elf-symbol-id='PyExc_TypeError'/> - <var-decl name='PyExc_StopAsyncIteration' type-id='type-id-14' mangled-name='PyExc_StopAsyncIteration' visibility='default' filepath='./Include/pyerrors.h' line='76' column='1' elf-symbol-id='PyExc_StopAsyncIteration'/> - <var-decl name='PyExc_StopIteration' type-id='type-id-14' mangled-name='PyExc_StopIteration' visibility='default' filepath='./Include/pyerrors.h' line='78' column='1' elf-symbol-id='PyExc_StopIteration'/> - <var-decl name='PyExc_GeneratorExit' type-id='type-id-14' mangled-name='PyExc_GeneratorExit' visibility='default' filepath='./Include/pyerrors.h' line='79' column='1' elf-symbol-id='PyExc_GeneratorExit'/> - <var-decl name='PyExc_SystemExit' type-id='type-id-14' mangled-name='PyExc_SystemExit' visibility='default' filepath='./Include/pyerrors.h' line='109' column='1' elf-symbol-id='PyExc_SystemExit'/> - <var-decl name='PyExc_BaseExceptionGroup' type-id='type-id-14' mangled-name='PyExc_BaseExceptionGroup' visibility='default' filepath='./Include/pyerrors.h' line='74' column='1' elf-symbol-id='PyExc_BaseExceptionGroup'/> - <var-decl name='PyExc_KeyboardInterrupt' type-id='type-id-14' mangled-name='PyExc_KeyboardInterrupt' visibility='default' filepath='./Include/pyerrors.h' line='95' column='1' elf-symbol-id='PyExc_KeyboardInterrupt'/> - <var-decl name='PyExc_ImportError' type-id='type-id-14' mangled-name='PyExc_ImportError' visibility='default' filepath='./Include/pyerrors.h' line='89' column='1' elf-symbol-id='PyExc_ImportError'/> - <var-decl name='PyExc_ModuleNotFoundError' type-id='type-id-14' mangled-name='PyExc_ModuleNotFoundError' visibility='default' filepath='./Include/pyerrors.h' line='91' column='1' elf-symbol-id='PyExc_ModuleNotFoundError'/> - <var-decl name='PyExc_OSError' type-id='type-id-14' mangled-name='PyExc_OSError' visibility='default' filepath='./Include/pyerrors.h' line='88' column='1' elf-symbol-id='PyExc_OSError'/> - <var-decl name='PyExc_BlockingIOError' type-id='type-id-14' mangled-name='PyExc_BlockingIOError' visibility='default' filepath='./Include/pyerrors.h' line='120' column='1' elf-symbol-id='PyExc_BlockingIOError'/> - <var-decl name='PyExc_ConnectionError' type-id='type-id-14' mangled-name='PyExc_ConnectionError' visibility='default' filepath='./Include/pyerrors.h' line='123' column='1' elf-symbol-id='PyExc_ConnectionError'/> - <var-decl name='PyExc_ChildProcessError' type-id='type-id-14' mangled-name='PyExc_ChildProcessError' visibility='default' filepath='./Include/pyerrors.h' line='122' column='1' elf-symbol-id='PyExc_ChildProcessError'/> - <var-decl name='PyExc_BrokenPipeError' type-id='type-id-14' mangled-name='PyExc_BrokenPipeError' visibility='default' filepath='./Include/pyerrors.h' line='121' column='1' elf-symbol-id='PyExc_BrokenPipeError'/> - <var-decl name='PyExc_ConnectionAbortedError' type-id='type-id-14' mangled-name='PyExc_ConnectionAbortedError' visibility='default' filepath='./Include/pyerrors.h' line='124' column='1' elf-symbol-id='PyExc_ConnectionAbortedError'/> - <var-decl name='PyExc_ConnectionRefusedError' type-id='type-id-14' mangled-name='PyExc_ConnectionRefusedError' visibility='default' filepath='./Include/pyerrors.h' line='125' column='1' elf-symbol-id='PyExc_ConnectionRefusedError'/> - <var-decl name='PyExc_ConnectionResetError' type-id='type-id-14' mangled-name='PyExc_ConnectionResetError' visibility='default' filepath='./Include/pyerrors.h' line='126' column='1' elf-symbol-id='PyExc_ConnectionResetError'/> - <var-decl name='PyExc_FileExistsError' type-id='type-id-14' mangled-name='PyExc_FileExistsError' visibility='default' filepath='./Include/pyerrors.h' line='127' column='1' elf-symbol-id='PyExc_FileExistsError'/> - <var-decl name='PyExc_FileNotFoundError' type-id='type-id-14' mangled-name='PyExc_FileNotFoundError' visibility='default' filepath='./Include/pyerrors.h' line='128' column='1' elf-symbol-id='PyExc_FileNotFoundError'/> - <var-decl name='PyExc_IsADirectoryError' type-id='type-id-14' mangled-name='PyExc_IsADirectoryError' visibility='default' filepath='./Include/pyerrors.h' line='130' column='1' elf-symbol-id='PyExc_IsADirectoryError'/> - <var-decl name='PyExc_NotADirectoryError' type-id='type-id-14' mangled-name='PyExc_NotADirectoryError' visibility='default' filepath='./Include/pyerrors.h' line='131' column='1' elf-symbol-id='PyExc_NotADirectoryError'/> - <var-decl name='PyExc_InterruptedError' type-id='type-id-14' mangled-name='PyExc_InterruptedError' visibility='default' filepath='./Include/pyerrors.h' line='129' column='1' elf-symbol-id='PyExc_InterruptedError'/> - <var-decl name='PyExc_PermissionError' type-id='type-id-14' mangled-name='PyExc_PermissionError' visibility='default' filepath='./Include/pyerrors.h' line='132' column='1' elf-symbol-id='PyExc_PermissionError'/> - <var-decl name='PyExc_ProcessLookupError' type-id='type-id-14' mangled-name='PyExc_ProcessLookupError' visibility='default' filepath='./Include/pyerrors.h' line='133' column='1' elf-symbol-id='PyExc_ProcessLookupError'/> - <var-decl name='PyExc_TimeoutError' type-id='type-id-14' mangled-name='PyExc_TimeoutError' visibility='default' filepath='./Include/pyerrors.h' line='134' column='1' elf-symbol-id='PyExc_TimeoutError'/> - <var-decl name='PyExc_EOFError' type-id='type-id-14' mangled-name='PyExc_EOFError' visibility='default' filepath='./Include/pyerrors.h' line='86' column='1' elf-symbol-id='PyExc_EOFError'/> - <var-decl name='PyExc_RuntimeError' type-id='type-id-14' mangled-name='PyExc_RuntimeError' visibility='default' filepath='./Include/pyerrors.h' line='99' column='1' elf-symbol-id='PyExc_RuntimeError'/> - <var-decl name='PyExc_RecursionError' type-id='type-id-14' mangled-name='PyExc_RecursionError' visibility='default' filepath='./Include/pyerrors.h' line='101' column='1' elf-symbol-id='PyExc_RecursionError'/> - <var-decl name='PyExc_NotImplementedError' type-id='type-id-14' mangled-name='PyExc_NotImplementedError' visibility='default' filepath='./Include/pyerrors.h' line='103' column='1' elf-symbol-id='PyExc_NotImplementedError'/> - <var-decl name='PyExc_NameError' type-id='type-id-14' mangled-name='PyExc_NameError' visibility='default' filepath='./Include/pyerrors.h' line='97' column='1' elf-symbol-id='PyExc_NameError'/> - <var-decl name='PyExc_UnboundLocalError' type-id='type-id-14' mangled-name='PyExc_UnboundLocalError' visibility='default' filepath='./Include/pyerrors.h' line='111' column='1' elf-symbol-id='PyExc_UnboundLocalError'/> - <var-decl name='PyExc_AttributeError' type-id='type-id-14' mangled-name='PyExc_AttributeError' visibility='default' filepath='./Include/pyerrors.h' line='84' column='1' elf-symbol-id='PyExc_AttributeError'/> - <var-decl name='PyExc_SyntaxError' type-id='type-id-14' mangled-name='PyExc_SyntaxError' visibility='default' filepath='./Include/pyerrors.h' line='104' column='1' elf-symbol-id='PyExc_SyntaxError'/> - <var-decl name='PyExc_IndentationError' type-id='type-id-14' mangled-name='PyExc_IndentationError' visibility='default' filepath='./Include/pyerrors.h' line='105' column='1' elf-symbol-id='PyExc_IndentationError'/> - <var-decl name='PyExc_TabError' type-id='type-id-14' mangled-name='PyExc_TabError' visibility='default' filepath='./Include/pyerrors.h' line='106' column='1' elf-symbol-id='PyExc_TabError'/> - <var-decl name='PyExc_LookupError' type-id='type-id-14' mangled-name='PyExc_LookupError' visibility='default' filepath='./Include/pyerrors.h' line='81' column='1' elf-symbol-id='PyExc_LookupError'/> - <var-decl name='PyExc_IndexError' type-id='type-id-14' mangled-name='PyExc_IndexError' visibility='default' filepath='./Include/pyerrors.h' line='93' column='1' elf-symbol-id='PyExc_IndexError'/> - <var-decl name='PyExc_KeyError' type-id='type-id-14' mangled-name='PyExc_KeyError' visibility='default' filepath='./Include/pyerrors.h' line='94' column='1' elf-symbol-id='PyExc_KeyError'/> - <var-decl name='PyExc_ValueError' type-id='type-id-14' mangled-name='PyExc_ValueError' visibility='default' filepath='./Include/pyerrors.h' line='116' column='1' elf-symbol-id='PyExc_ValueError'/> - <var-decl name='PyExc_UnicodeError' type-id='type-id-14' mangled-name='PyExc_UnicodeError' visibility='default' filepath='./Include/pyerrors.h' line='112' column='1' elf-symbol-id='PyExc_UnicodeError'/> - <var-decl name='PyExc_UnicodeEncodeError' type-id='type-id-14' mangled-name='PyExc_UnicodeEncodeError' visibility='default' filepath='./Include/pyerrors.h' line='113' column='1' elf-symbol-id='PyExc_UnicodeEncodeError'/> - <var-decl name='PyExc_UnicodeDecodeError' type-id='type-id-14' mangled-name='PyExc_UnicodeDecodeError' visibility='default' filepath='./Include/pyerrors.h' line='114' column='1' elf-symbol-id='PyExc_UnicodeDecodeError'/> - <var-decl name='PyExc_UnicodeTranslateError' type-id='type-id-14' mangled-name='PyExc_UnicodeTranslateError' visibility='default' filepath='./Include/pyerrors.h' line='115' column='1' elf-symbol-id='PyExc_UnicodeTranslateError'/> - <var-decl name='PyExc_AssertionError' type-id='type-id-14' mangled-name='PyExc_AssertionError' visibility='default' filepath='./Include/pyerrors.h' line='83' column='1' elf-symbol-id='PyExc_AssertionError'/> - <var-decl name='PyExc_ArithmeticError' type-id='type-id-14' mangled-name='PyExc_ArithmeticError' visibility='default' filepath='./Include/pyerrors.h' line='80' column='1' elf-symbol-id='PyExc_ArithmeticError'/> - <var-decl name='PyExc_FloatingPointError' type-id='type-id-14' mangled-name='PyExc_FloatingPointError' visibility='default' filepath='./Include/pyerrors.h' line='87' column='1' elf-symbol-id='PyExc_FloatingPointError'/> - <var-decl name='PyExc_OverflowError' type-id='type-id-14' mangled-name='PyExc_OverflowError' visibility='default' filepath='./Include/pyerrors.h' line='98' column='1' elf-symbol-id='PyExc_OverflowError'/> - <var-decl name='PyExc_ZeroDivisionError' type-id='type-id-14' mangled-name='PyExc_ZeroDivisionError' visibility='default' filepath='./Include/pyerrors.h' line='117' column='1' elf-symbol-id='PyExc_ZeroDivisionError'/> - <var-decl name='PyExc_SystemError' type-id='type-id-14' mangled-name='PyExc_SystemError' visibility='default' filepath='./Include/pyerrors.h' line='108' column='1' elf-symbol-id='PyExc_SystemError'/> - <var-decl name='PyExc_ReferenceError' type-id='type-id-14' mangled-name='PyExc_ReferenceError' visibility='default' filepath='./Include/pyerrors.h' line='107' column='1' elf-symbol-id='PyExc_ReferenceError'/> - <var-decl name='PyExc_MemoryError' type-id='type-id-14' mangled-name='PyExc_MemoryError' visibility='default' filepath='./Include/pyerrors.h' line='96' column='1' elf-symbol-id='PyExc_MemoryError'/> - <var-decl name='PyExc_BufferError' type-id='type-id-14' mangled-name='PyExc_BufferError' visibility='default' filepath='./Include/pyerrors.h' line='85' column='1' elf-symbol-id='PyExc_BufferError'/> - <var-decl name='PyExc_Warning' type-id='type-id-14' mangled-name='PyExc_Warning' visibility='default' filepath='./Include/pyerrors.h' line='146' column='1' elf-symbol-id='PyExc_Warning'/> - <var-decl name='PyExc_UserWarning' type-id='type-id-14' mangled-name='PyExc_UserWarning' visibility='default' filepath='./Include/pyerrors.h' line='147' column='1' elf-symbol-id='PyExc_UserWarning'/> - <var-decl name='PyExc_DeprecationWarning' type-id='type-id-14' mangled-name='PyExc_DeprecationWarning' visibility='default' filepath='./Include/pyerrors.h' line='148' column='1' elf-symbol-id='PyExc_DeprecationWarning'/> - <var-decl name='PyExc_PendingDeprecationWarning' type-id='type-id-14' mangled-name='PyExc_PendingDeprecationWarning' visibility='default' filepath='./Include/pyerrors.h' line='149' column='1' elf-symbol-id='PyExc_PendingDeprecationWarning'/> - <var-decl name='PyExc_SyntaxWarning' type-id='type-id-14' mangled-name='PyExc_SyntaxWarning' visibility='default' filepath='./Include/pyerrors.h' line='150' column='1' elf-symbol-id='PyExc_SyntaxWarning'/> - <var-decl name='PyExc_RuntimeWarning' type-id='type-id-14' mangled-name='PyExc_RuntimeWarning' visibility='default' filepath='./Include/pyerrors.h' line='151' column='1' elf-symbol-id='PyExc_RuntimeWarning'/> - <var-decl name='PyExc_FutureWarning' type-id='type-id-14' mangled-name='PyExc_FutureWarning' visibility='default' filepath='./Include/pyerrors.h' line='152' column='1' elf-symbol-id='PyExc_FutureWarning'/> - <var-decl name='PyExc_ImportWarning' type-id='type-id-14' mangled-name='PyExc_ImportWarning' visibility='default' filepath='./Include/pyerrors.h' line='153' column='1' elf-symbol-id='PyExc_ImportWarning'/> - <var-decl name='PyExc_UnicodeWarning' type-id='type-id-14' mangled-name='PyExc_UnicodeWarning' visibility='default' filepath='./Include/pyerrors.h' line='154' column='1' elf-symbol-id='PyExc_UnicodeWarning'/> - <var-decl name='PyExc_BytesWarning' type-id='type-id-14' mangled-name='PyExc_BytesWarning' visibility='default' filepath='./Include/pyerrors.h' line='155' column='1' elf-symbol-id='PyExc_BytesWarning'/> - <var-decl name='PyExc_EncodingWarning' type-id='type-id-14' mangled-name='PyExc_EncodingWarning' visibility='default' filepath='./Include/pyerrors.h' line='156' column='1' elf-symbol-id='PyExc_EncodingWarning'/> - <var-decl name='PyExc_ResourceWarning' type-id='type-id-14' mangled-name='PyExc_ResourceWarning' visibility='default' filepath='./Include/pyerrors.h' line='157' column='1' elf-symbol-id='PyExc_ResourceWarning'/> - <function-decl name='_PyErr_TrySetFromCause' mangled-name='_PyErr_TrySetFromCause' filepath='Objects/exceptions.c' line='3744' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyErr_TrySetFromCause'> - <parameter type-id='type-id-3' name='format' filepath='Objects/exceptions.c' line='3744' column='1'/> - <parameter is-variadic='yes'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyUnicodeTranslateError_Create' mangled-name='_PyUnicodeTranslateError_Create' filepath='Objects/exceptions.c' line='3139' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicodeTranslateError_Create'> - <parameter type-id='type-id-14' name='object' filepath='Objects/exceptions.c' line='3140' column='1'/> - <parameter type-id='type-id-36' name='start' filepath='Objects/exceptions.c' line='3141' column='1'/> - <parameter type-id='type-id-36' name='end' filepath='Objects/exceptions.c' line='3141' column='1'/> - <parameter type-id='type-id-3' name='reason' filepath='Objects/exceptions.c' line='3141' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyUnicodeDecodeError_Create' mangled-name='PyUnicodeDecodeError_Create' filepath='Objects/exceptions.c' line='3042' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicodeDecodeError_Create'> - <parameter type-id='type-id-3' name='encoding' filepath='Objects/exceptions.c' line='3043' column='1'/> - <parameter type-id='type-id-3' name='object' filepath='Objects/exceptions.c' line='3043' column='1'/> - <parameter type-id='type-id-36' name='length' filepath='Objects/exceptions.c' line='3043' column='1'/> - <parameter type-id='type-id-36' name='start' filepath='Objects/exceptions.c' line='3044' column='1'/> - <parameter type-id='type-id-36' name='end' filepath='Objects/exceptions.c' line='3044' column='1'/> - <parameter type-id='type-id-3' name='reason' filepath='Objects/exceptions.c' line='3044' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyUnicodeTranslateError_SetReason' mangled-name='PyUnicodeTranslateError_SetReason' filepath='Objects/exceptions.c' line='2789' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicodeTranslateError_SetReason'> - <parameter type-id='type-id-14' name='exc' filepath='Objects/exceptions.c' line='2789' column='1'/> - <parameter type-id='type-id-3' name='reason' filepath='Objects/exceptions.c' line='2789' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyUnicodeDecodeError_SetReason' mangled-name='PyUnicodeDecodeError_SetReason' filepath='Objects/exceptions.c' line='2781' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicodeDecodeError_SetReason'> - <parameter type-id='type-id-14' name='exc' filepath='Objects/exceptions.c' line='2789' column='1'/> - <parameter type-id='type-id-3' name='reason' filepath='Objects/exceptions.c' line='2789' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyUnicodeEncodeError_SetReason' mangled-name='PyUnicodeEncodeError_SetReason' filepath='Objects/exceptions.c' line='2773' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicodeEncodeError_SetReason'> - <parameter type-id='type-id-14' name='exc' filepath='Objects/exceptions.c' line='2789' column='1'/> - <parameter type-id='type-id-3' name='reason' filepath='Objects/exceptions.c' line='2789' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyUnicodeTranslateError_GetReason' mangled-name='PyUnicodeTranslateError_GetReason' filepath='Objects/exceptions.c' line='2766' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicodeTranslateError_GetReason'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2462' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyUnicodeDecodeError_GetReason' mangled-name='PyUnicodeDecodeError_GetReason' filepath='Objects/exceptions.c' line='2759' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicodeDecodeError_GetReason'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2462' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyUnicodeEncodeError_GetReason' mangled-name='PyUnicodeEncodeError_GetReason' filepath='Objects/exceptions.c' line='2752' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicodeEncodeError_GetReason'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2462' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyUnicodeTranslateError_SetEnd' mangled-name='PyUnicodeTranslateError_SetEnd' filepath='Objects/exceptions.c' line='2745' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicodeTranslateError_SetEnd'> - <parameter type-id='type-id-14' name='exc' filepath='Objects/exceptions.c' line='2745' column='1'/> - <parameter type-id='type-id-36' name='end' filepath='Objects/exceptions.c' line='2745' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyUnicodeDecodeError_SetEnd' mangled-name='PyUnicodeDecodeError_SetEnd' filepath='Objects/exceptions.c' line='2737' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicodeDecodeError_SetEnd'> - <parameter type-id='type-id-14' name='exc' filepath='Objects/exceptions.c' line='2745' column='1'/> - <parameter type-id='type-id-36' name='end' filepath='Objects/exceptions.c' line='2745' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyUnicodeEncodeError_SetEnd' mangled-name='PyUnicodeEncodeError_SetEnd' filepath='Objects/exceptions.c' line='2729' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicodeEncodeError_SetEnd'> - <parameter type-id='type-id-14' name='exc' filepath='Objects/exceptions.c' line='2745' column='1'/> - <parameter type-id='type-id-36' name='end' filepath='Objects/exceptions.c' line='2745' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyUnicodeTranslateError_GetEnd' mangled-name='PyUnicodeTranslateError_GetEnd' filepath='Objects/exceptions.c' line='2722' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicodeTranslateError_GetEnd'> - <parameter type-id='type-id-14' name='exc' filepath='Objects/exceptions.c' line='2722' column='1'/> - <parameter type-id='type-id-168' name='end' filepath='Objects/exceptions.c' line='2722' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyUnicodeDecodeError_GetEnd' mangled-name='PyUnicodeDecodeError_GetEnd' filepath='Objects/exceptions.c' line='2704' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicodeDecodeError_GetEnd'> - <parameter type-id='type-id-14' name='exc' filepath='Objects/exceptions.c' line='2704' column='1'/> - <parameter type-id='type-id-168' name='end' filepath='Objects/exceptions.c' line='2704' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyUnicodeEncodeError_GetEnd' mangled-name='PyUnicodeEncodeError_GetEnd' filepath='Objects/exceptions.c' line='2685' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicodeEncodeError_GetEnd'> - <parameter type-id='type-id-14' name='exc' filepath='Objects/exceptions.c' line='2704' column='1'/> - <parameter type-id='type-id-168' name='end' filepath='Objects/exceptions.c' line='2704' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyUnicodeTranslateError_SetStart' mangled-name='PyUnicodeTranslateError_SetStart' filepath='Objects/exceptions.c' line='2677' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicodeTranslateError_SetStart'> - <parameter type-id='type-id-14' name='exc' filepath='Objects/exceptions.c' line='2745' column='1'/> - <parameter type-id='type-id-36' name='end' filepath='Objects/exceptions.c' line='2745' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyUnicodeDecodeError_SetStart' mangled-name='PyUnicodeDecodeError_SetStart' filepath='Objects/exceptions.c' line='2669' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicodeDecodeError_SetStart'> - <parameter type-id='type-id-14' name='exc' filepath='Objects/exceptions.c' line='2745' column='1'/> - <parameter type-id='type-id-36' name='end' filepath='Objects/exceptions.c' line='2745' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyUnicodeEncodeError_SetStart' mangled-name='PyUnicodeEncodeError_SetStart' filepath='Objects/exceptions.c' line='2661' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicodeEncodeError_SetStart'> - <parameter type-id='type-id-14' name='exc' filepath='Objects/exceptions.c' line='2745' column='1'/> - <parameter type-id='type-id-36' name='end' filepath='Objects/exceptions.c' line='2745' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyUnicodeTranslateError_GetStart' mangled-name='PyUnicodeTranslateError_GetStart' filepath='Objects/exceptions.c' line='2654' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicodeTranslateError_GetStart'> - <parameter type-id='type-id-14' name='exc' filepath='Objects/exceptions.c' line='2722' column='1'/> - <parameter type-id='type-id-168' name='end' filepath='Objects/exceptions.c' line='2722' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyUnicodeDecodeError_GetStart' mangled-name='PyUnicodeDecodeError_GetStart' filepath='Objects/exceptions.c' line='2636' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicodeDecodeError_GetStart'> - <parameter type-id='type-id-14' name='exc' filepath='Objects/exceptions.c' line='2704' column='1'/> - <parameter type-id='type-id-168' name='end' filepath='Objects/exceptions.c' line='2704' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyUnicodeEncodeError_GetStart' mangled-name='PyUnicodeEncodeError_GetStart' filepath='Objects/exceptions.c' line='2617' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicodeEncodeError_GetStart'> - <parameter type-id='type-id-14' name='exc' filepath='Objects/exceptions.c' line='2704' column='1'/> - <parameter type-id='type-id-168' name='end' filepath='Objects/exceptions.c' line='2704' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyUnicodeTranslateError_GetObject' mangled-name='PyUnicodeTranslateError_GetObject' filepath='Objects/exceptions.c' line='2611' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicodeTranslateError_GetObject'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2462' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyUnicodeDecodeError_GetObject' mangled-name='PyUnicodeDecodeError_GetObject' filepath='Objects/exceptions.c' line='2605' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicodeDecodeError_GetObject'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2462' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyUnicodeEncodeError_GetObject' mangled-name='PyUnicodeEncodeError_GetObject' filepath='Objects/exceptions.c' line='2599' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicodeEncodeError_GetObject'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2462' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyUnicodeDecodeError_GetEncoding' mangled-name='PyUnicodeDecodeError_GetEncoding' filepath='Objects/exceptions.c' line='2593' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicodeDecodeError_GetEncoding'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2462' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyUnicodeEncodeError_GetEncoding' mangled-name='PyUnicodeEncodeError_GetEncoding' filepath='Objects/exceptions.c' line='2587' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicodeEncodeError_GetEncoding'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2462' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyExceptionClass_Name' mangled-name='PyExceptionClass_Name' filepath='Objects/exceptions.c' line='421' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyExceptionClass_Name'> - <parameter type-id='type-id-14' name='ob' filepath='Objects/exceptions.c' line='421' column='1'/> - <return type-id='type-id-3'/> - </function-decl> - <function-decl name='PyException_SetContext' mangled-name='PyException_SetContext' filepath='Objects/exceptions.c' line='415' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyException_SetContext'> - <parameter type-id='type-id-14' name='self' filepath='Objects/exceptions.c' line='415' column='1'/> - <parameter type-id='type-id-14' name='context' filepath='Objects/exceptions.c' line='415' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyException_GetContext' mangled-name='PyException_GetContext' filepath='Objects/exceptions.c' line='406' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyException_GetContext'> - <parameter type-id='type-id-14' name='item' filepath='Objects/abstract.c' line='1408' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyException_SetCause' mangled-name='PyException_SetCause' filepath='Objects/exceptions.c' line='398' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyException_SetCause'> - <parameter type-id='type-id-14' name='self' filepath='Objects/exceptions.c' line='398' column='1'/> - <parameter type-id='type-id-14' name='cause' filepath='Objects/exceptions.c' line='398' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyException_GetCause' mangled-name='PyException_GetCause' filepath='Objects/exceptions.c' line='389' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyException_GetCause'> - <parameter type-id='type-id-14' name='item' filepath='Objects/abstract.c' line='1408' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyException_SetTraceback' mangled-name='PyException_SetTraceback' filepath='Objects/exceptions.c' line='383' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyException_SetTraceback'> - <parameter type-id='type-id-14' name='derived' filepath='Objects/abstract.c' line='2784' column='1'/> - <parameter type-id='type-id-14' name='cls' filepath='Objects/abstract.c' line='2784' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyException_GetTraceback' mangled-name='PyException_GetTraceback' filepath='Objects/exceptions.c' line='374' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyException_GetTraceback'> - <parameter type-id='type-id-14' name='item' filepath='Objects/abstract.c' line='1408' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Objects/genericaliasobject.c' comp-dir-path='/src' language='LANG_C99'> - <var-decl name='Py_GenericAliasType' type-id='type-id-112' mangled-name='Py_GenericAliasType' visibility='default' filepath='./Include/genericaliasobject.h' line='9' column='1' elf-symbol-id='Py_GenericAliasType'/> - <function-decl name='Py_GenericAlias' mangled-name='Py_GenericAlias' filepath='Objects/genericaliasobject.c' line='946' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_GenericAlias'> - <parameter type-id='type-id-14' name='callable' filepath='Objects/call.c' line='438' column='1'/> - <parameter type-id='type-id-14' name='args' filepath='Objects/call.c' line='438' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Objects/genobject.c' comp-dir-path='/src' language='LANG_C99'> - <var-decl name='PyGen_Type' type-id='type-id-112' mangled-name='PyGen_Type' visibility='default' filepath='./Include/cpython/genobject.h' line='38' column='1' elf-symbol-id='PyGen_Type'/> - <var-decl name='PyCoro_Type' type-id='type-id-112' mangled-name='PyCoro_Type' visibility='default' filepath='./Include/cpython/genobject.h' line='57' column='1' elf-symbol-id='PyCoro_Type'/> - <var-decl name='_PyCoroWrapper_Type' type-id='type-id-112' mangled-name='_PyCoroWrapper_Type' visibility='default' filepath='./Include/cpython/genobject.h' line='58' column='1' elf-symbol-id='_PyCoroWrapper_Type'/> - <var-decl name='PyAsyncGen_Type' type-id='type-id-112' mangled-name='PyAsyncGen_Type' visibility='default' filepath='./Include/cpython/genobject.h' line='71' column='1' elf-symbol-id='PyAsyncGen_Type'/> - <var-decl name='_PyAsyncGenASend_Type' type-id='type-id-112' mangled-name='_PyAsyncGenASend_Type' visibility='default' filepath='./Include/cpython/genobject.h' line='72' column='1' elf-symbol-id='_PyAsyncGenASend_Type'/> - <var-decl name='_PyAsyncGenWrappedValue_Type' type-id='type-id-112' mangled-name='_PyAsyncGenWrappedValue_Type' visibility='default' filepath='./Include/cpython/genobject.h' line='73' column='1' elf-symbol-id='_PyAsyncGenWrappedValue_Type'/> - <var-decl name='_PyAsyncGenAThrow_Type' type-id='type-id-112' mangled-name='_PyAsyncGenAThrow_Type' visibility='default' filepath='./Include/cpython/genobject.h' line='74' column='1' elf-symbol-id='_PyAsyncGenAThrow_Type'/> - <class-decl name='_frame' size-in-bits='448' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_frame.h' line='15' column='1' id='type-id-436'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='ob_base' type-id='type-id-108' visibility='default' filepath='./Include/internal/pycore_frame.h' line='16' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='f_back' type-id='type-id-438' visibility='default' filepath='./Include/internal/pycore_frame.h' line='17' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='f_frame' type-id='type-id-376' visibility='default' filepath='./Include/internal/pycore_frame.h' line='18' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='256'> - <var-decl name='f_trace' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_frame.h' line='19' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='320'> - <var-decl name='f_lineno' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_frame.h' line='20' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='352'> - <var-decl name='f_trace_lines' type-id='type-id-1' visibility='default' filepath='./Include/internal/pycore_frame.h' line='21' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='360'> - <var-decl name='f_trace_opcodes' type-id='type-id-1' visibility='default' filepath='./Include/internal/pycore_frame.h' line='22' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='368'> - <var-decl name='f_fast_as_locals' type-id='type-id-1' visibility='default' filepath='./Include/internal/pycore_frame.h' line='23' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='384'> - <var-decl name='_f_frame_data' type-id='type-id-360' visibility='default' filepath='./Include/internal/pycore_frame.h' line='25' column='1'/> - </data-member> - </class-decl> - <class-decl name='_PyInterpreterFrame' size-in-bits='640' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_frame.h' line='47' column='1' id='type-id-375'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='f_func' type-id='type-id-512' visibility='default' filepath='./Include/internal/pycore_frame.h' line='49' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='f_globals' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_frame.h' line='50' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='f_builtins' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_frame.h' line='51' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='f_locals' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_frame.h' line='52' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='256'> - <var-decl name='f_code' type-id='type-id-444' visibility='default' filepath='./Include/internal/pycore_frame.h' line='53' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='320'> - <var-decl name='frame_obj' type-id='type-id-438' visibility='default' filepath='./Include/internal/pycore_frame.h' line='54' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='384'> - <var-decl name='previous' type-id='type-id-376' visibility='default' filepath='./Include/internal/pycore_frame.h' line='56' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='448'> - <var-decl name='prev_instr' type-id='type-id-513' visibility='default' filepath='./Include/internal/pycore_frame.h' line='61' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='512'> - <var-decl name='stacktop' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_frame.h' line='62' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='544'> - <var-decl name='is_entry' type-id='type-id-31' visibility='default' filepath='./Include/internal/pycore_frame.h' line='63' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='552'> - <var-decl name='owner' type-id='type-id-1' visibility='default' filepath='./Include/internal/pycore_frame.h' line='64' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='576'> - <var-decl name='localsplus' type-id='type-id-360' visibility='default' filepath='./Include/internal/pycore_frame.h' line='66' column='1'/> - </data-member> - </class-decl> - <class-decl name='__anonymous_struct__' size-in-bits='1088' is-struct='yes' is-anonymous='yes' naming-typedef-id='type-id-514' visibility='default' filepath='./Include/cpython/funcobject.h' line='36' column='1' id='type-id-515'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='ob_base' type-id='type-id-108' visibility='default' filepath='./Include/cpython/funcobject.h' line='37' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='func_globals' type-id='type-id-14' visibility='default' filepath='./Include/cpython/funcobject.h' line='38' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='func_builtins' type-id='type-id-14' visibility='default' filepath='./Include/cpython/funcobject.h' line='38' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='256'> - <var-decl name='func_name' type-id='type-id-14' visibility='default' filepath='./Include/cpython/funcobject.h' line='38' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='320'> - <var-decl name='func_qualname' type-id='type-id-14' visibility='default' filepath='./Include/cpython/funcobject.h' line='38' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='384'> - <var-decl name='func_code' type-id='type-id-14' visibility='default' filepath='./Include/cpython/funcobject.h' line='38' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='448'> - <var-decl name='func_defaults' type-id='type-id-14' visibility='default' filepath='./Include/cpython/funcobject.h' line='38' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='512'> - <var-decl name='func_kwdefaults' type-id='type-id-14' visibility='default' filepath='./Include/cpython/funcobject.h' line='38' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='576'> - <var-decl name='func_closure' type-id='type-id-14' visibility='default' filepath='./Include/cpython/funcobject.h' line='38' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='640'> - <var-decl name='func_doc' type-id='type-id-14' visibility='default' filepath='./Include/cpython/funcobject.h' line='39' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='704'> - <var-decl name='func_dict' type-id='type-id-14' visibility='default' filepath='./Include/cpython/funcobject.h' line='40' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='768'> - <var-decl name='func_weakreflist' type-id='type-id-14' visibility='default' filepath='./Include/cpython/funcobject.h' line='41' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='832'> - <var-decl name='func_module' type-id='type-id-14' visibility='default' filepath='./Include/cpython/funcobject.h' line='42' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='896'> - <var-decl name='func_annotations' type-id='type-id-14' visibility='default' filepath='./Include/cpython/funcobject.h' line='43' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='960'> - <var-decl name='vectorcall' type-id='type-id-106' visibility='default' filepath='./Include/cpython/funcobject.h' line='44' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1024'> - <var-decl name='func_version' type-id='type-id-256' visibility='default' filepath='./Include/cpython/funcobject.h' line='52' column='1'/> - </data-member> - </class-decl> - <typedef-decl name='PyFunctionObject' type-id='type-id-515' filepath='./Include/cpython/funcobject.h' line='59' column='1' id='type-id-514'/> - <pointer-type-def type-id='type-id-514' size-in-bits='64' id='type-id-512'/> - <typedef-decl name='__uint16_t' type-id='type-id-461' filepath='/usr/include/x86_64-linux-gnu/bits/types.h' line='40' column='1' id='type-id-516'/> - <typedef-decl name='uint16_t' type-id='type-id-516' filepath='/usr/include/x86_64-linux-gnu/bits/stdint-uintn.h' line='25' column='1' id='type-id-517'/> - <typedef-decl name='_Py_CODEUNIT' type-id='type-id-517' filepath='./Include/cpython/code.h' line='19' column='1' id='type-id-518'/> - <pointer-type-def type-id='type-id-518' size-in-bits='64' id='type-id-513'/> - <function-decl name='PyAsyncGen_New' mangled-name='PyAsyncGen_New' filepath='Objects/genobject.c' line='1641' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyAsyncGen_New'> - <parameter type-id='type-id-438' name='f' filepath='Objects/genobject.c' line='1641' column='1'/> - <parameter type-id='type-id-14' name='name' filepath='Objects/genobject.c' line='1641' column='1'/> - <parameter type-id='type-id-14' name='qualname' filepath='Objects/genobject.c' line='1641' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyCoro_New' mangled-name='PyCoro_New' filepath='Objects/genobject.c' line='1360' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCoro_New'> - <parameter type-id='type-id-438' name='f' filepath='Objects/genobject.c' line='1360' column='1'/> - <parameter type-id='type-id-14' name='name' filepath='Objects/genobject.c' line='1360' column='1'/> - <parameter type-id='type-id-14' name='qualname' filepath='Objects/genobject.c' line='1360' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyGen_New' mangled-name='PyGen_New' filepath='Objects/genobject.c' line='1009' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyGen_New'> - <parameter type-id='type-id-438' name='f' filepath='Objects/genobject.c' line='1009' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyGen_NewWithQualName' mangled-name='PyGen_NewWithQualName' filepath='Objects/genobject.c' line='1003' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyGen_NewWithQualName'> - <parameter type-id='type-id-438' name='f' filepath='Objects/genobject.c' line='1003' column='1'/> - <parameter type-id='type-id-14' name='name' filepath='Objects/genobject.c' line='1003' column='1'/> - <parameter type-id='type-id-14' name='qualname' filepath='Objects/genobject.c' line='1003' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyGen_FetchStopIterationValue' mangled-name='_PyGen_FetchStopIterationValue' filepath='Objects/genobject.c' line='649' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyGen_FetchStopIterationValue'> - <parameter type-id='type-id-22' name='pvalue' filepath='Objects/genobject.c' line='649' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyGen_SetStopIterationValue' mangled-name='_PyGen_SetStopIterationValue' filepath='Objects/genobject.c' line='610' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyGen_SetStopIterationValue'> - <parameter type-id='type-id-14' name='obj' filepath='Objects/abstract.c' line='2845' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyGen_Finalize' mangled-name='_PyGen_Finalize' filepath='Objects/genobject.c' line='53' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyGen_Finalize'> - <parameter type-id='type-id-14' name='self' filepath='Objects/genobject.c' line='53' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Objects/fileobject.c' comp-dir-path='/src' language='LANG_C99'> - <var-decl name='PyStdPrinter_Type' type-id='type-id-112' mangled-name='PyStdPrinter_Type' visibility='default' filepath='./Include/cpython/fileobject.h' line='10' column='1' elf-symbol-id='PyStdPrinter_Type'/> - <function-decl name='PyFile_OpenCode' mangled-name='PyFile_OpenCode' filepath='Objects/fileobject.c' line='516' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFile_OpenCode'> - <parameter type-id='type-id-3' name='str' filepath='Objects/bytesobject.c' line='147' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyFile_OpenCodeObject' mangled-name='PyFile_OpenCodeObject' filepath='Objects/fileobject.c' line='491' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFile_OpenCodeObject'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2817' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyFile_SetOpenCodeHook' mangled-name='PyFile_SetOpenCodeHook' filepath='Objects/fileobject.c' line='471' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFile_SetOpenCodeHook'> - <parameter type-id='type-id-64' name='hook' filepath='Objects/fileobject.c' line='471' column='1'/> - <parameter type-id='type-id-18' name='userData' filepath='Objects/fileobject.c' line='471' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyFile_NewStdPrinter' mangled-name='PyFile_NewStdPrinter' filepath='Objects/fileobject.c' line='284' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFile_NewStdPrinter'> - <parameter type-id='type-id-8' name='fd' filepath='Objects/fileobject.c' line='284' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='Py_UniversalNewlineFgets' mangled-name='Py_UniversalNewlineFgets' filepath='Objects/fileobject.c' line='242' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_UniversalNewlineFgets'> - <parameter type-id='type-id-115' name='buf' filepath='Objects/fileobject.c' line='242' column='1'/> - <parameter type-id='type-id-8' name='n' filepath='Objects/fileobject.c' line='242' column='1'/> - <parameter type-id='type-id-473' name='stream' filepath='Objects/fileobject.c' line='242' column='1'/> - <parameter type-id='type-id-14' name='fobj' filepath='Objects/fileobject.c' line='242' column='1'/> - <return type-id='type-id-115'/> - </function-decl> - <function-decl name='_PyLong_FileDescriptor_Converter' mangled-name='_PyLong_FileDescriptor_Converter' filepath='Objects/fileobject.c' line='223' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyLong_FileDescriptor_Converter'> - <parameter type-id='type-id-14' name='o' filepath='Objects/capsule.c' line='181' column='1'/> - <parameter type-id='type-id-18' name='context' filepath='Objects/capsule.c' line='181' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyObject_AsFileDescriptor' mangled-name='PyObject_AsFileDescriptor' filepath='Objects/fileobject.c' line='177' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_AsFileDescriptor'> - <parameter type-id='type-id-14' name='o' filepath='Objects/fileobject.c' line='177' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyFile_WriteString' mangled-name='PyFile_WriteString' filepath='Objects/fileobject.c' line='147' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFile_WriteString'> - <parameter type-id='type-id-3' name='s' filepath='Objects/fileobject.c' line='147' column='1'/> - <parameter type-id='type-id-14' name='f' filepath='Objects/fileobject.c' line='147' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyFile_WriteObject' mangled-name='PyFile_WriteObject' filepath='Objects/fileobject.c' line='117' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFile_WriteObject'> - <parameter type-id='type-id-14' name='v' filepath='Objects/fileobject.c' line='117' column='1'/> - <parameter type-id='type-id-14' name='f' filepath='Objects/fileobject.c' line='117' column='1'/> - <parameter type-id='type-id-8' name='flags' filepath='Objects/fileobject.c' line='117' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyFile_GetLine' mangled-name='PyFile_GetLine' filepath='Objects/fileobject.c' line='53' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFile_GetLine'> - <parameter type-id='type-id-14' name='f' filepath='Objects/fileobject.c' line='53' column='1'/> - <parameter type-id='type-id-8' name='n' filepath='Objects/fileobject.c' line='53' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyFile_FromFd' mangled-name='PyFile_FromFd' filepath='Objects/fileobject.c' line='32' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFile_FromFd'> - <parameter type-id='type-id-8' name='fd' filepath='Objects/fileobject.c' line='32' column='1'/> - <parameter type-id='type-id-3' name='name' filepath='Objects/fileobject.c' line='32' column='1'/> - <parameter type-id='type-id-3' name='mode' filepath='Objects/fileobject.c' line='32' column='1'/> - <parameter type-id='type-id-8' name='buffering' filepath='Objects/fileobject.c' line='32' column='1'/> - <parameter type-id='type-id-3' name='encoding' filepath='Objects/fileobject.c' line='32' column='1'/> - <parameter type-id='type-id-3' name='errors' filepath='Objects/fileobject.c' line='33' column='1'/> - <parameter type-id='type-id-3' name='newline' filepath='Objects/fileobject.c' line='33' column='1'/> - <parameter type-id='type-id-8' name='closefd' filepath='Objects/fileobject.c' line='33' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Objects/floatobject.c' comp-dir-path='/src' language='LANG_C99'> - <var-decl name='PyFloat_Type' type-id='type-id-112' mangled-name='PyFloat_Type' visibility='default' filepath='./Include/floatobject.h' line='14' column='1' elf-symbol-id='PyFloat_Type'/> - <function-decl name='PyFloat_Unpack8' mangled-name='PyFloat_Unpack8' filepath='Objects/floatobject.c' line='2547' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFloat_Unpack8'> - <parameter type-id='type-id-3' name='data' filepath='Objects/floatobject.c' line='2547' column='1'/> - <parameter type-id='type-id-8' name='le' filepath='Objects/floatobject.c' line='2547' column='1'/> - <return type-id='type-id-391'/> - </function-decl> - <function-decl name='PyFloat_Unpack4' mangled-name='PyFloat_Unpack4' filepath='Objects/floatobject.c' line='2468' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFloat_Unpack4'> - <parameter type-id='type-id-3' name='data' filepath='Objects/floatobject.c' line='2547' column='1'/> - <parameter type-id='type-id-8' name='le' filepath='Objects/floatobject.c' line='2547' column='1'/> - <return type-id='type-id-391'/> - </function-decl> - <function-decl name='PyFloat_Unpack2' mangled-name='PyFloat_Unpack2' filepath='Objects/floatobject.c' line='2405' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFloat_Unpack2'> - <parameter type-id='type-id-3' name='data' filepath='Objects/floatobject.c' line='2405' column='1'/> - <parameter type-id='type-id-8' name='le' filepath='Objects/floatobject.c' line='2405' column='1'/> - <return type-id='type-id-391'/> - </function-decl> - <function-decl name='PyFloat_Pack8' mangled-name='PyFloat_Pack8' filepath='Objects/floatobject.c' line='2275' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFloat_Pack8'> - <parameter type-id='type-id-391' name='x' filepath='Objects/floatobject.c' line='2275' column='1'/> - <parameter type-id='type-id-115' name='data' filepath='Objects/floatobject.c' line='2275' column='1'/> - <parameter type-id='type-id-8' name='le' filepath='Objects/floatobject.c' line='2275' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyFloat_Pack4' mangled-name='PyFloat_Pack4' filepath='Objects/floatobject.c' line='2167' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFloat_Pack4'> - <parameter type-id='type-id-391' name='x' filepath='Objects/floatobject.c' line='2275' column='1'/> - <parameter type-id='type-id-115' name='data' filepath='Objects/floatobject.c' line='2275' column='1'/> - <parameter type-id='type-id-8' name='le' filepath='Objects/floatobject.c' line='2275' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyFloat_Pack2' mangled-name='PyFloat_Pack2' filepath='Objects/floatobject.c' line='2062' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFloat_Pack2'> - <parameter type-id='type-id-391' name='x' filepath='Objects/floatobject.c' line='2062' column='1'/> - <parameter type-id='type-id-115' name='data' filepath='Objects/floatobject.c' line='2062' column='1'/> - <parameter type-id='type-id-8' name='le' filepath='Objects/floatobject.c' line='2062' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyFloat_DebugMallocStats' mangled-name='_PyFloat_DebugMallocStats' filepath='Objects/floatobject.c' line='2039' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyFloat_DebugMallocStats'> - <parameter type-id='type-id-473' name='out' filepath='Objects/floatobject.c' line='2039' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyFloat_AsDouble' mangled-name='PyFloat_AsDouble' filepath='Objects/floatobject.c' line='282' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFloat_AsDouble'> - <parameter type-id='type-id-14' name='op' filepath='Objects/floatobject.c' line='282' column='1'/> - <return type-id='type-id-391'/> - </function-decl> - <function-decl name='PyFloat_FromString' mangled-name='PyFloat_FromString' filepath='Objects/floatobject.c' line='193' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFloat_FromString'> - <parameter type-id='type-id-14' name='v' filepath='Objects/floatobject.c' line='193' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyFloat_FromDouble' mangled-name='PyFloat_FromDouble' filepath='Objects/floatobject.c' line='131' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFloat_FromDouble'> - <parameter type-id='type-id-391' name='fval' filepath='Objects/floatobject.c' line='131' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyFloat_GetInfo' mangled-name='PyFloat_GetInfo' filepath='Objects/floatobject.c' line='94' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFloat_GetInfo'> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyFloat_GetMin' mangled-name='PyFloat_GetMin' filepath='Objects/floatobject.c' line='50' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFloat_GetMin'> - <return type-id='type-id-391'/> - </function-decl> - <function-decl name='PyFloat_GetMax' mangled-name='PyFloat_GetMax' filepath='Objects/floatobject.c' line='44' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFloat_GetMax'> - <return type-id='type-id-391'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Objects/frameobject.c' comp-dir-path='/src' language='LANG_C99'> - <var-decl name='PyFrame_Type' type-id='type-id-112' mangled-name='PyFrame_Type' visibility='default' filepath='./Include/cpython/pyframe.h' line='5' column='1' elf-symbol-id='PyFrame_Type'/> - <function-decl name='PyFrame_GetGenerator' mangled-name='PyFrame_GetGenerator' filepath='Objects/frameobject.c' line='1207' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFrame_GetGenerator'> - <parameter type-id='type-id-438' name='frame' filepath='Objects/frameobject.c' line='1207' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyFrame_GetLasti' mangled-name='PyFrame_GetLasti' filepath='Objects/frameobject.c' line='1197' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFrame_GetLasti'> - <parameter type-id='type-id-438' name='frame' filepath='Objects/frameobject.c' line='1197' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyFrame_GetBuiltins' mangled-name='PyFrame_GetBuiltins' filepath='Objects/frameobject.c' line='1191' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFrame_GetBuiltins'> - <parameter type-id='type-id-438' name='f' filepath='Objects/genobject.c' line='1009' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyFrame_GetGlobals' mangled-name='PyFrame_GetGlobals' filepath='Objects/frameobject.c' line='1185' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFrame_GetGlobals'> - <parameter type-id='type-id-438' name='f' filepath='Objects/genobject.c' line='1009' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyFrame_GetLocals' mangled-name='PyFrame_GetLocals' filepath='Objects/frameobject.c' line='1179' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFrame_GetLocals'> - <parameter type-id='type-id-438' name='f' filepath='Objects/genobject.c' line='1009' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyFrame_GetBack' mangled-name='PyFrame_GetBack' filepath='Objects/frameobject.c' line='1161' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFrame_GetBack'> - <parameter type-id='type-id-438' name='frame' filepath='Objects/frameobject.c' line='1161' column='1'/> - <return type-id='type-id-438'/> - </function-decl> - <function-decl name='PyFrame_GetCode' mangled-name='PyFrame_GetCode' filepath='Objects/frameobject.c' line='1150' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFrame_GetCode'> - <parameter type-id='type-id-438' name='frame' filepath='Objects/frameobject.c' line='1150' column='1'/> - <return type-id='type-id-444'/> - </function-decl> - <function-decl name='_PyFrame_IsEntryFrame' mangled-name='_PyFrame_IsEntryFrame' filepath='Objects/frameobject.c' line='1142' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyFrame_IsEntryFrame'> - <parameter type-id='type-id-438' name='frame' filepath='Objects/frameobject.c' line='1142' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyFrame_LocalsToFast' mangled-name='PyFrame_LocalsToFast' filepath='Objects/frameobject.c' line='1133' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFrame_LocalsToFast'> - <parameter type-id='type-id-438' name='f' filepath='Objects/frameobject.c' line='1133' column='1'/> - <parameter type-id='type-id-8' name='clear' filepath='Objects/frameobject.c' line='1133' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyFrame_FastToLocals' mangled-name='PyFrame_FastToLocals' filepath='Objects/frameobject.c' line='1054' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFrame_FastToLocals'> - <parameter type-id='type-id-438' name='f' filepath='Objects/frameobject.c' line='1054' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyFrame_FastToLocalsWithError' mangled-name='PyFrame_FastToLocalsWithError' filepath='Objects/frameobject.c' line='1040' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFrame_FastToLocalsWithError'> - <parameter type-id='type-id-438' name='frame' filepath='Objects/frameobject.c' line='1197' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyFrame_New' mangled-name='PyFrame_New' filepath='Objects/frameobject.c' line='887' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFrame_New'> - <parameter type-id='type-id-10' name='tstate' filepath='Objects/frameobject.c' line='887' column='1'/> - <parameter type-id='type-id-444' name='code' filepath='Objects/frameobject.c' line='887' column='1'/> - <parameter type-id='type-id-14' name='globals' filepath='Objects/frameobject.c' line='888' column='1'/> - <parameter type-id='type-id-14' name='locals' filepath='Objects/frameobject.c' line='888' column='1'/> - <return type-id='type-id-438'/> - </function-decl> - <function-decl name='PyFrame_GetLineNumber' mangled-name='PyFrame_GetLineNumber' filepath='Objects/frameobject.c' line='36' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFrame_GetLineNumber'> - <parameter type-id='type-id-438' name='frame' filepath='Objects/frameobject.c' line='1142' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Objects/funcobject.c' comp-dir-path='/src' language='LANG_C99'> - <var-decl name='PyFunction_Type' type-id='type-id-112' mangled-name='PyFunction_Type' visibility='default' filepath='./Include/cpython/funcobject.h' line='61' column='1' elf-symbol-id='PyFunction_Type'/> - <var-decl name='PyClassMethod_Type' type-id='type-id-112' mangled-name='PyClassMethod_Type' visibility='default' filepath='./Include/cpython/funcobject.h' line='103' column='1' elf-symbol-id='PyClassMethod_Type'/> - <var-decl name='PyStaticMethod_Type' type-id='type-id-112' mangled-name='PyStaticMethod_Type' visibility='default' filepath='./Include/cpython/funcobject.h' line='104' column='1' elf-symbol-id='PyStaticMethod_Type'/> - <function-decl name='PyStaticMethod_New' mangled-name='PyStaticMethod_New' filepath='Objects/funcobject.c' line='1218' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyStaticMethod_New'> - <parameter type-id='type-id-14' name='item' filepath='Objects/abstract.c' line='1408' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyClassMethod_New' mangled-name='PyClassMethod_New' filepath='Objects/funcobject.c' line='1022' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyClassMethod_New'> - <parameter type-id='type-id-14' name='item' filepath='Objects/abstract.c' line='1408' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyFunction_SetAnnotations' mangled-name='PyFunction_SetAnnotations' filepath='Objects/funcobject.c' line='319' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFunction_SetAnnotations'> - <parameter type-id='type-id-14' name='op' filepath='Objects/funcobject.c' line='319' column='1'/> - <parameter type-id='type-id-14' name='annotations' filepath='Objects/funcobject.c' line='319' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyFunction_GetAnnotations' mangled-name='PyFunction_GetAnnotations' filepath='Objects/funcobject.c' line='309' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFunction_GetAnnotations'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2462' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyFunction_SetClosure' mangled-name='PyFunction_SetClosure' filepath='Objects/funcobject.c' line='255' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFunction_SetClosure'> - <parameter type-id='type-id-14' name='op' filepath='Objects/funcobject.c' line='319' column='1'/> - <parameter type-id='type-id-14' name='annotations' filepath='Objects/funcobject.c' line='319' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyFunction_GetClosure' mangled-name='PyFunction_GetClosure' filepath='Objects/funcobject.c' line='245' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFunction_GetClosure'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2462' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyFunction_SetKwDefaults' mangled-name='PyFunction_SetKwDefaults' filepath='Objects/funcobject.c' line='223' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFunction_SetKwDefaults'> - <parameter type-id='type-id-14' name='op' filepath='Objects/funcobject.c' line='319' column='1'/> - <parameter type-id='type-id-14' name='annotations' filepath='Objects/funcobject.c' line='319' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyFunction_GetKwDefaults' mangled-name='PyFunction_GetKwDefaults' filepath='Objects/funcobject.c' line='213' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFunction_GetKwDefaults'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2462' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyFunction_SetDefaults' mangled-name='PyFunction_SetDefaults' filepath='Objects/funcobject.c' line='192' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFunction_SetDefaults'> - <parameter type-id='type-id-14' name='op' filepath='Objects/funcobject.c' line='319' column='1'/> - <parameter type-id='type-id-14' name='annotations' filepath='Objects/funcobject.c' line='319' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyFunction_GetDefaults' mangled-name='PyFunction_GetDefaults' filepath='Objects/funcobject.c' line='182' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFunction_GetDefaults'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2462' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyFunction_GetModule' mangled-name='PyFunction_GetModule' filepath='Objects/funcobject.c' line='172' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFunction_GetModule'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2462' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyFunction_GetGlobals' mangled-name='PyFunction_GetGlobals' filepath='Objects/funcobject.c' line='162' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFunction_GetGlobals'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2462' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyFunction_GetCode' mangled-name='PyFunction_GetCode' filepath='Objects/funcobject.c' line='152' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFunction_GetCode'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2462' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyFunction_New' mangled-name='PyFunction_New' filepath='Objects/funcobject.c' line='146' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFunction_New'> - <parameter type-id='type-id-14' name='v' filepath='Objects/abstract.c' line='1256' column='1'/> - <parameter type-id='type-id-14' name='w' filepath='Objects/abstract.c' line='1256' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyFunction_NewWithQualName' mangled-name='PyFunction_NewWithQualName' filepath='Objects/funcobject.c' line='47' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFunction_NewWithQualName'> - <parameter type-id='type-id-14' name='code' filepath='Objects/funcobject.c' line='47' column='1'/> - <parameter type-id='type-id-14' name='globals' filepath='Objects/funcobject.c' line='47' column='1'/> - <parameter type-id='type-id-14' name='qualname' filepath='Objects/funcobject.c' line='47' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Objects/interpreteridobject.c' comp-dir-path='/src' language='LANG_C99'> - <var-decl name='_PyInterpreterID_Type' type-id='type-id-112' mangled-name='_PyInterpreterID_Type' visibility='default' filepath='./Include/internal/pycore_interpreteridobject.h' line='13' column='1' elf-symbol-id='_PyInterpreterID_Type'/> - <function-decl name='_PyInterpreterID_LookUp' mangled-name='_PyInterpreterID_LookUp' filepath='Objects/interpreteridobject.c' line='287' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyInterpreterID_LookUp'> - <parameter type-id='type-id-14' name='requested_id' filepath='Objects/interpreteridobject.c' line='287' column='1'/> - <return type-id='type-id-11'/> - </function-decl> - <function-decl name='_PyInterpreterState_GetIDObject' mangled-name='_PyInterpreterState_GetIDObject' filepath='Objects/interpreteridobject.c' line='274' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyInterpreterState_GetIDObject'> - <parameter type-id='type-id-11' name='interp' filepath='Objects/interpreteridobject.c' line='274' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyInterpreterID_New' mangled-name='_PyInterpreterID_New' filepath='Objects/interpreteridobject.c' line='268' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyInterpreterID_New'> - <parameter type-id='type-id-29' name='id' filepath='Objects/interpreteridobject.c' line='268' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Objects/iterobject.c' comp-dir-path='/src' language='LANG_C99'> - <var-decl name='PySeqIter_Type' type-id='type-id-112' mangled-name='PySeqIter_Type' visibility='default' filepath='./Include/iterobject.h' line='8' column='1' elf-symbol-id='PySeqIter_Type'/> - <var-decl name='PyCallIter_Type' type-id='type-id-112' mangled-name='PyCallIter_Type' visibility='default' filepath='./Include/iterobject.h' line='9' column='1' elf-symbol-id='PyCallIter_Type'/> - <var-decl name='_PyAnextAwaitable_Type' type-id='type-id-112' visibility='default' filepath='./Include/iterobject.h' line='11' column='1'/> - <function-decl name='PyCallIter_New' mangled-name='PyCallIter_New' filepath='Objects/iterobject.c' line='180' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCallIter_New'> - <parameter type-id='type-id-14' name='callable' filepath='Objects/call.c' line='438' column='1'/> - <parameter type-id='type-id-14' name='args' filepath='Objects/call.c' line='438' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PySeqIter_New' mangled-name='PySeqIter_New' filepath='Objects/iterobject.c' line='14' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySeqIter_New'> - <parameter type-id='type-id-14' name='item' filepath='Objects/abstract.c' line='1408' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Objects/listobject.c' comp-dir-path='/src' language='LANG_C99'> - <var-decl name='PyList_Type' type-id='type-id-112' mangled-name='PyList_Type' visibility='default' filepath='./Include/listobject.h' line='20' column='1' elf-symbol-id='PyList_Type'/> - <var-decl name='PyListIter_Type' type-id='type-id-112' mangled-name='PyListIter_Type' visibility='default' filepath='./Include/listobject.h' line='21' column='1' elf-symbol-id='PyListIter_Type'/> - <var-decl name='PyListRevIter_Type' type-id='type-id-112' mangled-name='PyListRevIter_Type' visibility='default' filepath='./Include/listobject.h' line='22' column='1' elf-symbol-id='PyListRevIter_Type'/> - <function-decl name='PyList_AsTuple' mangled-name='PyList_AsTuple' filepath='Objects/listobject.c' line='2621' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyList_AsTuple'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2462' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyList_Reverse' mangled-name='PyList_Reverse' filepath='Objects/listobject.c' line='2607' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyList_Reverse'> - <parameter type-id='type-id-14' name='obj' filepath='Objects/abstract.c' line='2845' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyList_Sort' mangled-name='PyList_Sort' filepath='Objects/listobject.c' line='2578' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyList_Sort'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2303' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyList_Extend' mangled-name='_PyList_Extend' filepath='Objects/listobject.c' line='996' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyList_Extend'> - <parameter type-id='type-id-400' name='self' filepath='Objects/listobject.c' line='996' column='1'/> - <parameter type-id='type-id-14' name='iterable' filepath='Objects/listobject.c' line='996' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyList_SetSlice' mangled-name='PyList_SetSlice' filepath='Objects/listobject.c' line='734' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyList_SetSlice'> - <parameter type-id='type-id-14' name='a' filepath='Objects/listobject.c' line='734' column='1'/> - <parameter type-id='type-id-36' name='ilow' filepath='Objects/listobject.c' line='734' column='1'/> - <parameter type-id='type-id-36' name='ihigh' filepath='Objects/listobject.c' line='734' column='1'/> - <parameter type-id='type-id-14' name='v' filepath='Objects/listobject.c' line='734' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyList_GetSlice' mangled-name='PyList_GetSlice' filepath='Objects/listobject.c' line='488' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyList_GetSlice'> - <parameter type-id='type-id-14' name='a' filepath='Objects/listobject.c' line='488' column='1'/> - <parameter type-id='type-id-36' name='ilow' filepath='Objects/listobject.c' line='488' column='1'/> - <parameter type-id='type-id-36' name='ihigh' filepath='Objects/listobject.c' line='488' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyList_Append' mangled-name='PyList_Append' filepath='Objects/listobject.c' line='326' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyList_Append'> - <parameter type-id='type-id-14' name='derived' filepath='Objects/abstract.c' line='2784' column='1'/> - <parameter type-id='type-id-14' name='cls' filepath='Objects/abstract.c' line='2784' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyList_Insert' mangled-name='PyList_Insert' filepath='Objects/listobject.c' line='302' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyList_Insert'> - <parameter type-id='type-id-14' name='op' filepath='Objects/listobject.c' line='302' column='1'/> - <parameter type-id='type-id-36' name='where' filepath='Objects/listobject.c' line='302' column='1'/> - <parameter type-id='type-id-14' name='newitem' filepath='Objects/listobject.c' line='302' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyList_SetItem' mangled-name='PyList_SetItem' filepath='Objects/listobject.c' line='252' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyList_SetItem'> - <parameter type-id='type-id-14' name='s' filepath='Objects/abstract.c' line='1926' column='1'/> - <parameter type-id='type-id-36' name='i' filepath='Objects/abstract.c' line='1926' column='1'/> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='1926' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyList_GetItem' mangled-name='PyList_GetItem' filepath='Objects/listobject.c' line='237' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyList_GetItem'> - <parameter type-id='type-id-14' name='op' filepath='Objects/listobject.c' line='237' column='1'/> - <parameter type-id='type-id-36' name='i' filepath='Objects/listobject.c' line='237' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyList_Size' mangled-name='PyList_Size' filepath='Objects/listobject.c' line='213' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyList_Size'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2335' column='1'/> - <return type-id='type-id-36'/> - </function-decl> - <function-decl name='PyList_New' mangled-name='PyList_New' filepath='Objects/listobject.c' line='149' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyList_New'> - <parameter type-id='type-id-36' name='size' filepath='Objects/listobject.c' line='149' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyList_DebugMallocStats' mangled-name='_PyList_DebugMallocStats' filepath='Objects/listobject.c' line='138' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyList_DebugMallocStats'> - <parameter type-id='type-id-473' name='out' filepath='Objects/floatobject.c' line='2039' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Objects/longobject.c' comp-dir-path='/src' language='LANG_C99'> - - <array-type-def dimensions='1' type-id='type-id-283' size-in-bits='2048' id='type-id-519'> - <subrange length='256' type-id='type-id-16' id='type-id-264'/> - - </array-type-def> - <var-decl name='_PyLong_DigitValue' type-id='type-id-519' mangled-name='_PyLong_DigitValue' visibility='default' filepath='./Include/internal/pycore_long.h' line='52' column='1' elf-symbol-id='_PyLong_DigitValue'/> - <var-decl name='PyLong_Type' type-id='type-id-112' mangled-name='PyLong_Type' visibility='default' filepath='./Include/longobject.h' line='10' column='1' elf-symbol-id='PyLong_Type'/> - <function-decl name='PyLong_GetInfo' mangled-name='PyLong_GetInfo' filepath='Objects/longobject.c' line='6072' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyLong_GetInfo'> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyLong_DivmodNear' mangled-name='_PyLong_DivmodNear' filepath='Objects/longobject.c' line='5443' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyLong_DivmodNear'> - <parameter type-id='type-id-14' name='a' filepath='Objects/longobject.c' line='5443' column='1'/> - <parameter type-id='type-id-14' name='b' filepath='Objects/longobject.c' line='5443' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyLong_GCD' mangled-name='_PyLong_GCD' filepath='Objects/longobject.c' line='5081' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyLong_GCD'> - <parameter type-id='type-id-14' name='aarg' filepath='Objects/longobject.c' line='5081' column='1'/> - <parameter type-id='type-id-14' name='barg' filepath='Objects/longobject.c' line='5081' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyLong_Lshift' mangled-name='_PyLong_Lshift' filepath='Objects/longobject.c' line='4880' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyLong_Lshift'> - <parameter type-id='type-id-14' name='a' filepath='Objects/longobject.c' line='4880' column='1'/> - <parameter type-id='type-id-54' name='shiftby' filepath='Objects/longobject.c' line='4880' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyLong_Rshift' mangled-name='_PyLong_Rshift' filepath='Objects/longobject.c' line='4803' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyLong_Rshift'> - <parameter type-id='type-id-14' name='a' filepath='Objects/longobject.c' line='4880' column='1'/> - <parameter type-id='type-id-54' name='shiftby' filepath='Objects/longobject.c' line='4880' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyLong_AsDouble' mangled-name='PyLong_AsDouble' filepath='Objects/longobject.c' line='3023' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyLong_AsDouble'> - <parameter type-id='type-id-14' name='v' filepath='Objects/longobject.c' line='3023' column='1'/> - <return type-id='type-id-391'/> - </function-decl> - <pointer-type-def type-id='type-id-259' size-in-bits='64' id='type-id-520'/> - <function-decl name='_PyLong_Frexp' mangled-name='_PyLong_Frexp' filepath='Objects/longobject.c' line='2911' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyLong_Frexp'> - <parameter type-id='type-id-520' name='a' filepath='Objects/longobject.c' line='2911' column='1'/> - <parameter type-id='type-id-168' name='e' filepath='Objects/longobject.c' line='2911' column='1'/> - <return type-id='type-id-391'/> - </function-decl> - <function-decl name='PyLong_FromUnicodeObject' mangled-name='PyLong_FromUnicodeObject' filepath='Objects/longobject.c' line='2620' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyLong_FromUnicodeObject'> - <parameter type-id='type-id-14' name='u' filepath='Objects/longobject.c' line='2620' column='1'/> - <parameter type-id='type-id-8' name='base' filepath='Objects/longobject.c' line='2620' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyLong_FromBytes' mangled-name='_PyLong_FromBytes' filepath='Objects/longobject.c' line='2600' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyLong_FromBytes'> - <parameter type-id='type-id-3' name='s' filepath='Objects/longobject.c' line='2600' column='1'/> - <parameter type-id='type-id-36' name='len' filepath='Objects/longobject.c' line='2600' column='1'/> - <parameter type-id='type-id-8' name='base' filepath='Objects/longobject.c' line='2600' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyLong_FromString' mangled-name='PyLong_FromString' filepath='Objects/longobject.c' line='2239' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyLong_FromString'> - <parameter type-id='type-id-3' name='str' filepath='Objects/longobject.c' line='2239' column='1'/> - <parameter type-id='type-id-494' name='pend' filepath='Objects/longobject.c' line='2239' column='1'/> - <parameter type-id='type-id-8' name='base' filepath='Objects/longobject.c' line='2239' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyLong_FormatBytesWriter' mangled-name='_PyLong_FormatBytesWriter' filepath='Objects/longobject.c' line='2088' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyLong_FormatBytesWriter'> - <parameter type-id='type-id-493' name='writer' filepath='Objects/longobject.c' line='2088' column='1'/> - <parameter type-id='type-id-115' name='str' filepath='Objects/longobject.c' line='2088' column='1'/> - <parameter type-id='type-id-14' name='obj' filepath='Objects/longobject.c' line='2089' column='1'/> - <parameter type-id='type-id-8' name='base' filepath='Objects/longobject.c' line='2090' column='1'/> - <parameter type-id='type-id-8' name='alternate' filepath='Objects/longobject.c' line='2090' column='1'/> - <return type-id='type-id-115'/> - </function-decl> - <class-decl name='__anonymous_struct__' size-in-bits='448' is-struct='yes' is-anonymous='yes' naming-typedef-id='type-id-521' visibility='default' filepath='./Include/cpython/unicodeobject.h' line='718' column='1' id='type-id-522'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='buffer' type-id='type-id-14' visibility='default' filepath='./Include/cpython/unicodeobject.h' line='719' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='data' type-id='type-id-18' visibility='default' filepath='./Include/cpython/unicodeobject.h' line='720' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='kind' type-id='type-id-523' visibility='default' filepath='./Include/cpython/unicodeobject.h' line='721' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='160'> - <var-decl name='maxchar' type-id='type-id-524' visibility='default' filepath='./Include/cpython/unicodeobject.h' line='722' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='size' type-id='type-id-36' visibility='default' filepath='./Include/cpython/unicodeobject.h' line='723' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='256'> - <var-decl name='pos' type-id='type-id-36' visibility='default' filepath='./Include/cpython/unicodeobject.h' line='724' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='320'> - <var-decl name='min_length' type-id='type-id-36' visibility='default' filepath='./Include/cpython/unicodeobject.h' line='727' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='384'> - <var-decl name='min_char' type-id='type-id-524' visibility='default' filepath='./Include/cpython/unicodeobject.h' line='730' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='416'> - <var-decl name='overallocate' type-id='type-id-283' visibility='default' filepath='./Include/cpython/unicodeobject.h' line='733' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='424'> - <var-decl name='readonly' type-id='type-id-283' visibility='default' filepath='./Include/cpython/unicodeobject.h' line='737' column='1'/> - </data-member> - </class-decl> - <enum-decl name='PyUnicode_Kind' filepath='./Include/cpython/unicodeobject.h' line='304' column='1' id='type-id-523'> - <underlying-type type-id='type-id-126'/> - <enumerator name='PyUnicode_WCHAR_KIND' value='0'/> - <enumerator name='PyUnicode_1BYTE_KIND' value='1'/> - <enumerator name='PyUnicode_2BYTE_KIND' value='2'/> - <enumerator name='PyUnicode_4BYTE_KIND' value='4'/> - </enum-decl> - <typedef-decl name='Py_UCS4' type-id='type-id-256' filepath='./Include/unicodeobject.h' line='102' column='1' id='type-id-524'/> - <typedef-decl name='_PyUnicodeWriter' type-id='type-id-522' filepath='./Include/cpython/unicodeobject.h' line='738' column='1' id='type-id-521'/> - <pointer-type-def type-id='type-id-521' size-in-bits='64' id='type-id-525'/> - <function-decl name='_PyLong_FormatWriter' mangled-name='_PyLong_FormatWriter' filepath='Objects/longobject.c' line='2075' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyLong_FormatWriter'> - <parameter type-id='type-id-525' name='writer' filepath='Objects/longobject.c' line='2075' column='1'/> - <parameter type-id='type-id-14' name='obj' filepath='Objects/longobject.c' line='2076' column='1'/> - <parameter type-id='type-id-8' name='base' filepath='Objects/longobject.c' line='2077' column='1'/> - <parameter type-id='type-id-8' name='alternate' filepath='Objects/longobject.c' line='2077' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyLong_Format' mangled-name='_PyLong_Format' filepath='Objects/longobject.c' line='2061' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyLong_Format'> - <parameter type-id='type-id-14' name='n' filepath='Objects/abstract.c' line='1695' column='1'/> - <parameter type-id='type-id-8' name='base' filepath='Objects/abstract.c' line='1695' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyLong_Size_t_Converter' mangled-name='_PyLong_Size_t_Converter' filepath='Objects/longobject.c' line='1502' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyLong_Size_t_Converter'> - <parameter type-id='type-id-14' name='o' filepath='Objects/capsule.c' line='181' column='1'/> - <parameter type-id='type-id-18' name='context' filepath='Objects/capsule.c' line='181' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyLong_UnsignedLongLong_Converter' mangled-name='_PyLong_UnsignedLongLong_Converter' filepath='Objects/longobject.c' line='1485' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyLong_UnsignedLongLong_Converter'> - <parameter type-id='type-id-14' name='o' filepath='Objects/capsule.c' line='181' column='1'/> - <parameter type-id='type-id-18' name='context' filepath='Objects/capsule.c' line='181' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyLong_UnsignedLong_Converter' mangled-name='_PyLong_UnsignedLong_Converter' filepath='Objects/longobject.c' line='1468' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyLong_UnsignedLong_Converter'> - <parameter type-id='type-id-14' name='o' filepath='Objects/capsule.c' line='181' column='1'/> - <parameter type-id='type-id-18' name='context' filepath='Objects/capsule.c' line='181' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyLong_UnsignedInt_Converter' mangled-name='_PyLong_UnsignedInt_Converter' filepath='Objects/longobject.c' line='1446' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyLong_UnsignedInt_Converter'> - <parameter type-id='type-id-14' name='o' filepath='Objects/capsule.c' line='181' column='1'/> - <parameter type-id='type-id-18' name='context' filepath='Objects/capsule.c' line='181' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyLong_UnsignedShort_Converter' mangled-name='_PyLong_UnsignedShort_Converter' filepath='Objects/longobject.c' line='1424' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyLong_UnsignedShort_Converter'> - <parameter type-id='type-id-14' name='o' filepath='Objects/capsule.c' line='181' column='1'/> - <parameter type-id='type-id-18' name='context' filepath='Objects/capsule.c' line='181' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyLong_AsLongLongAndOverflow' mangled-name='PyLong_AsLongLongAndOverflow' filepath='Objects/longobject.c' line='1348' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyLong_AsLongLongAndOverflow'> - <parameter type-id='type-id-14' name='vv' filepath='Objects/longobject.c' line='1348' column='1'/> - <parameter type-id='type-id-501' name='overflow' filepath='Objects/longobject.c' line='1348' column='1'/> - <return type-id='type-id-222'/> - </function-decl> - <function-decl name='PyLong_AsUnsignedLongLongMask' mangled-name='PyLong_AsUnsignedLongLongMask' filepath='Objects/longobject.c' line='1314' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyLong_AsUnsignedLongLongMask'> - <parameter type-id='type-id-14' name='op' filepath='Objects/longobject.c' line='1314' column='1'/> - <return type-id='type-id-225'/> - </function-decl> - <function-decl name='PyLong_AsUnsignedLongLong' mangled-name='PyLong_AsUnsignedLongLong' filepath='Objects/longobject.c' line='1249' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyLong_AsUnsignedLongLong'> - <parameter type-id='type-id-14' name='vv' filepath='Objects/longobject.c' line='1249' column='1'/> - <return type-id='type-id-225'/> - </function-decl> - <function-decl name='PyLong_AsLongLong' mangled-name='PyLong_AsLongLong' filepath='Objects/longobject.c' line='1197' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyLong_AsLongLong'> - <parameter type-id='type-id-14' name='vv' filepath='Objects/longobject.c' line='1197' column='1'/> - <return type-id='type-id-222'/> - </function-decl> - <function-decl name='PyLong_FromSsize_t' mangled-name='PyLong_FromSsize_t' filepath='Objects/longobject.c' line='1153' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyLong_FromSsize_t'> - <parameter type-id='type-id-36' name='ival' filepath='Objects/longobject.c' line='1153' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyLong_FromLongLong' mangled-name='PyLong_FromLongLong' filepath='Objects/longobject.c' line='1112' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyLong_FromLongLong'> - <parameter type-id='type-id-222' name='ival' filepath='Objects/longobject.c' line='1112' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyLong_AsVoidPtr' mangled-name='PyLong_AsVoidPtr' filepath='Objects/longobject.c' line='1075' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyLong_AsVoidPtr'> - <parameter type-id='type-id-14' name='o' filepath='Objects/capsule.c' line='122' column='1'/> - <return type-id='type-id-18'/> - </function-decl> - <function-decl name='PyLong_FromVoidPtr' mangled-name='PyLong_FromVoidPtr' filepath='Objects/longobject.c' line='1058' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyLong_FromVoidPtr'> - <parameter type-id='type-id-18' name='p' filepath='Objects/longobject.c' line='1058' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <pointer-type-def type-id='type-id-283' size-in-bits='64' id='type-id-526'/> - <function-decl name='_PyLong_AsByteArray' mangled-name='_PyLong_AsByteArray' filepath='Objects/longobject.c' line='923' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyLong_AsByteArray'> - <parameter type-id='type-id-520' name='v' filepath='Objects/longobject.c' line='923' column='1'/> - <parameter type-id='type-id-526' name='bytes' filepath='Objects/longobject.c' line='924' column='1'/> - <parameter type-id='type-id-54' name='n' filepath='Objects/longobject.c' line='924' column='1'/> - <parameter type-id='type-id-8' name='little_endian' filepath='Objects/longobject.c' line='925' column='1'/> - <parameter type-id='type-id-8' name='is_signed' filepath='Objects/longobject.c' line='925' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <qualified-type-def type-id='type-id-283' const='yes' id='type-id-527'/> - <pointer-type-def type-id='type-id-527' size-in-bits='64' id='type-id-528'/> - <function-decl name='_PyLong_FromByteArray' mangled-name='_PyLong_FromByteArray' filepath='Objects/longobject.c' line='812' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyLong_FromByteArray'> - <parameter type-id='type-id-528' name='bytes' filepath='Objects/longobject.c' line='812' column='1'/> - <parameter type-id='type-id-54' name='n' filepath='Objects/longobject.c' line='812' column='1'/> - <parameter type-id='type-id-8' name='little_endian' filepath='Objects/longobject.c' line='813' column='1'/> - <parameter type-id='type-id-8' name='is_signed' filepath='Objects/longobject.c' line='813' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyLong_NumBits' mangled-name='_PyLong_NumBits' filepath='Objects/longobject.c' line='782' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyLong_NumBits'> - <parameter type-id='type-id-14' name='vv' filepath='Objects/longobject.c' line='782' column='1'/> - <return type-id='type-id-54'/> - </function-decl> - <function-decl name='_PyLong_Sign' mangled-name='_PyLong_Sign' filepath='Objects/longobject.c' line='761' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyLong_Sign'> - <parameter type-id='type-id-14' name='obj' filepath='Objects/abstract.c' line='2845' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyLong_AsUnsignedLongMask' mangled-name='PyLong_AsUnsignedLongMask' filepath='Objects/longobject.c' line='737' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyLong_AsUnsignedLongMask'> - <parameter type-id='type-id-14' name='op' filepath='Objects/longobject.c' line='737' column='1'/> - <return type-id='type-id-16'/> - </function-decl> - <function-decl name='PyLong_AsSize_t' mangled-name='PyLong_AsSize_t' filepath='Objects/longobject.c' line='664' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyLong_AsSize_t'> - <parameter type-id='type-id-14' name='vv' filepath='Objects/longobject.c' line='664' column='1'/> - <return type-id='type-id-54'/> - </function-decl> - <function-decl name='PyLong_AsUnsignedLong' mangled-name='PyLong_AsUnsignedLong' filepath='Objects/longobject.c' line='620' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyLong_AsUnsignedLong'> - <parameter type-id='type-id-14' name='vv' filepath='Objects/longobject.c' line='620' column='1'/> - <return type-id='type-id-16'/> - </function-decl> - <function-decl name='PyLong_AsSsize_t' mangled-name='PyLong_AsSsize_t' filepath='Objects/longobject.c' line='565' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyLong_AsSsize_t'> - <parameter type-id='type-id-14' name='vv' filepath='Objects/longobject.c' line='565' column='1'/> - <return type-id='type-id-36'/> - </function-decl> - <function-decl name='_PyLong_AsInt' mangled-name='_PyLong_AsInt' filepath='Objects/longobject.c' line='547' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyLong_AsInt'> - <parameter type-id='type-id-14' name='obj' filepath='Objects/abstract.c' line='302' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyLong_AsLong' mangled-name='PyLong_AsLong' filepath='Objects/longobject.c' line='530' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyLong_AsLong'> - <parameter type-id='type-id-14' name='obj' filepath='Objects/longobject.c' line='530' column='1'/> - <return type-id='type-id-53'/> - </function-decl> - <function-decl name='PyLong_AsLongAndOverflow' mangled-name='PyLong_AsLongAndOverflow' filepath='Objects/longobject.c' line='451' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyLong_AsLongAndOverflow'> - <parameter type-id='type-id-14' name='vv' filepath='Objects/longobject.c' line='451' column='1'/> - <parameter type-id='type-id-501' name='overflow' filepath='Objects/longobject.c' line='451' column='1'/> - <return type-id='type-id-53'/> - </function-decl> - <function-decl name='PyLong_FromDouble' mangled-name='PyLong_FromDouble' filepath='Objects/longobject.c' line='374' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyLong_FromDouble'> - <parameter type-id='type-id-391' name='dval' filepath='Objects/longobject.c' line='374' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyLong_FromSize_t' mangled-name='PyLong_FromSize_t' filepath='Objects/longobject.c' line='366' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyLong_FromSize_t'> - <parameter type-id='type-id-54' name='ival' filepath='Objects/longobject.c' line='366' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyLong_FromUnsignedLongLong' mangled-name='PyLong_FromUnsignedLongLong' filepath='Objects/longobject.c' line='358' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyLong_FromUnsignedLongLong'> - <parameter type-id='type-id-225' name='ival' filepath='Objects/longobject.c' line='358' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyLong_FromUnsignedLong' mangled-name='PyLong_FromUnsignedLong' filepath='Objects/longobject.c' line='350' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyLong_FromUnsignedLong'> - <parameter type-id='type-id-16' name='ival' filepath='Objects/longobject.c' line='350' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyLong_FromLong' mangled-name='PyLong_FromLong' filepath='Objects/longobject.c' line='285' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyLong_FromLong'> - <parameter type-id='type-id-53' name='ival' filepath='Objects/longobject.c' line='285' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyLong_Copy' mangled-name='_PyLong_Copy' filepath='Objects/longobject.c' line='169' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyLong_Copy'> - <parameter type-id='type-id-520' name='src' filepath='Objects/longobject.c' line='169' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyLong_New' mangled-name='_PyLong_New' filepath='Objects/longobject.c' line='142' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyLong_New'> - <parameter type-id='type-id-36' name='size' filepath='Objects/longobject.c' line='142' column='1'/> - <return type-id='type-id-520'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Objects/dictobject.c' comp-dir-path='/src' language='LANG_C99'> - <var-decl name='_pydict_global_version' type-id='type-id-19' visibility='default' filepath='./Include/internal/pycore_dict.h' line='162' column='1'/> - <var-decl name='PyDict_Type' type-id='type-id-112' mangled-name='PyDict_Type' visibility='default' filepath='./Include/dictobject.h' line='15' column='1' elf-symbol-id='PyDict_Type'/> - <var-decl name='PyDictIterKey_Type' type-id='type-id-112' mangled-name='PyDictIterKey_Type' visibility='default' filepath='./Include/dictobject.h' line='79' column='1' elf-symbol-id='PyDictIterKey_Type'/> - <var-decl name='PyDictIterValue_Type' type-id='type-id-112' mangled-name='PyDictIterValue_Type' visibility='default' filepath='./Include/dictobject.h' line='80' column='1' elf-symbol-id='PyDictIterValue_Type'/> - <var-decl name='PyDictIterItem_Type' type-id='type-id-112' mangled-name='PyDictIterItem_Type' visibility='default' filepath='./Include/dictobject.h' line='81' column='1' elf-symbol-id='PyDictIterItem_Type'/> - <var-decl name='PyDictRevIterKey_Type' type-id='type-id-112' mangled-name='PyDictRevIterKey_Type' visibility='default' filepath='./Include/dictobject.h' line='83' column='1' elf-symbol-id='PyDictRevIterKey_Type'/> - <var-decl name='PyDictRevIterItem_Type' type-id='type-id-112' mangled-name='PyDictRevIterItem_Type' visibility='default' filepath='./Include/dictobject.h' line='84' column='1' elf-symbol-id='PyDictRevIterItem_Type'/> - <var-decl name='PyDictRevIterValue_Type' type-id='type-id-112' mangled-name='PyDictRevIterValue_Type' visibility='default' filepath='./Include/dictobject.h' line='85' column='1' elf-symbol-id='PyDictRevIterValue_Type'/> - <var-decl name='PyDictKeys_Type' type-id='type-id-112' mangled-name='PyDictKeys_Type' visibility='default' filepath='./Include/dictobject.h' line='66' column='1' elf-symbol-id='PyDictKeys_Type'/> - <var-decl name='PyDictItems_Type' type-id='type-id-112' mangled-name='PyDictItems_Type' visibility='default' filepath='./Include/dictobject.h' line='68' column='1' elf-symbol-id='PyDictItems_Type'/> - <var-decl name='PyDictValues_Type' type-id='type-id-112' mangled-name='PyDictValues_Type' visibility='default' filepath='./Include/dictobject.h' line='67' column='1' elf-symbol-id='PyDictValues_Type'/> - <function-decl name='PyObject_GenericGetDict' mangled-name='PyObject_GenericGetDict' filepath='Objects/dictobject.c' line='5587' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_GenericGetDict'> - <parameter type-id='type-id-14' name='obj' filepath='Objects/dictobject.c' line='5587' column='1'/> - <parameter type-id='type-id-18' name='context' filepath='Objects/dictobject.c' line='5587' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyDictView_Intersect' mangled-name='_PyDictView_Intersect' filepath='Objects/dictobject.c' line='4799' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyDictView_Intersect'> - <parameter type-id='type-id-14' name='self' filepath='Objects/dictobject.c' line='4799' column='1'/> - <parameter type-id='type-id-14' name='other' filepath='Objects/dictobject.c' line='4799' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyDictView_New' mangled-name='_PyDictView_New' filepath='Objects/dictobject.c' line='4573' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyDictView_New'> - <parameter type-id='type-id-14' name='dict' filepath='Objects/dictobject.c' line='4573' column='1'/> - <parameter type-id='type-id-74' name='type' filepath='Objects/dictobject.c' line='4573' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyDict_DelItemString' mangled-name='PyDict_DelItemString' filepath='Objects/dictobject.c' line='3935' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyDict_DelItemString'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='271' column='1'/> - <parameter type-id='type-id-3' name='key' filepath='Objects/abstract.c' line='271' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyDict_DelItemId' mangled-name='_PyDict_DelItemId' filepath='Objects/dictobject.c' line='3926' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyDict_DelItemId'> - <parameter type-id='type-id-14' name='v' filepath='Objects/dictobject.c' line='3926' column='1'/> - <parameter type-id='type-id-499' name='key' filepath='Objects/dictobject.c' line='3926' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyDict_SetItemString' mangled-name='PyDict_SetItemString' filepath='Objects/dictobject.c' line='3912' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyDict_SetItemString'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2359' column='1'/> - <parameter type-id='type-id-3' name='key' filepath='Objects/abstract.c' line='2359' column='1'/> - <parameter type-id='type-id-14' name='value' filepath='Objects/abstract.c' line='2359' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyDict_SetItemId' mangled-name='_PyDict_SetItemId' filepath='Objects/dictobject.c' line='3902' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyDict_SetItemId'> - <parameter type-id='type-id-14' name='v' filepath='Objects/dictobject.c' line='3902' column='1'/> - <parameter type-id='type-id-499' name='key' filepath='Objects/dictobject.c' line='3902' column='1'/> - <parameter type-id='type-id-14' name='item' filepath='Objects/dictobject.c' line='3902' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyDict_GetItemString' mangled-name='PyDict_GetItemString' filepath='Objects/dictobject.c' line='3888' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyDict_GetItemString'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2342' column='1'/> - <parameter type-id='type-id-3' name='key' filepath='Objects/abstract.c' line='2342' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyDict_ContainsId' mangled-name='_PyDict_ContainsId' filepath='Objects/dictobject.c' line='3724' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyDict_ContainsId'> - <parameter type-id='type-id-14' name='v' filepath='Objects/dictobject.c' line='3926' column='1'/> - <parameter type-id='type-id-499' name='key' filepath='Objects/dictobject.c' line='3926' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyDict_Contains_KnownHash' mangled-name='_PyDict_Contains_KnownHash' filepath='Objects/dictobject.c' line='3711' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyDict_Contains_KnownHash'> - <parameter type-id='type-id-14' name='op' filepath='Objects/dictobject.c' line='3711' column='1'/> - <parameter type-id='type-id-14' name='key' filepath='Objects/dictobject.c' line='3711' column='1'/> - <parameter type-id='type-id-159' name='hash' filepath='Objects/dictobject.c' line='3711' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyDict_Contains' mangled-name='PyDict_Contains' filepath='Objects/dictobject.c' line='3691' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyDict_Contains'> - <parameter type-id='type-id-14' name='op' filepath='Objects/dictobject.c' line='3691' column='1'/> - <parameter type-id='type-id-14' name='key' filepath='Objects/dictobject.c' line='3691' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyDict_SizeOf' mangled-name='_PyDict_SizeOf' filepath='Objects/dictobject.c' line='3573' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyDict_SizeOf'> - <parameter type-id='type-id-413' name='mp' filepath='Objects/dictobject.c' line='3573' column='1'/> - <return type-id='type-id-36'/> - </function-decl> - <function-decl name='PyDict_SetDefault' mangled-name='PyDict_SetDefault' filepath='Objects/dictobject.c' line='3298' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyDict_SetDefault'> - <parameter type-id='type-id-14' name='d' filepath='Objects/dictobject.c' line='3298' column='1'/> - <parameter type-id='type-id-14' name='key' filepath='Objects/dictobject.c' line='3298' column='1'/> - <parameter type-id='type-id-14' name='defaultobj' filepath='Objects/dictobject.c' line='3298' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyDict_Items' mangled-name='PyDict_Items' filepath='Objects/dictobject.c' line='3138' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyDict_Items'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2462' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyDict_Values' mangled-name='PyDict_Values' filepath='Objects/dictobject.c' line='3128' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyDict_Values'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2462' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyDict_Keys' mangled-name='PyDict_Keys' filepath='Objects/dictobject.c' line='3118' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyDict_Keys'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2462' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyDict_Size' mangled-name='PyDict_Size' filepath='Objects/dictobject.c' line='3108' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyDict_Size'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2335' column='1'/> - <return type-id='type-id-36'/> - </function-decl> - <function-decl name='PyDict_Copy' mangled-name='PyDict_Copy' filepath='Objects/dictobject.c' line='3013' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyDict_Copy'> - <parameter type-id='type-id-14' name='o' filepath='Objects/dictobject.c' line='3013' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyDict_MergeEx' mangled-name='_PyDict_MergeEx' filepath='Objects/dictobject.c' line='3001' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyDict_MergeEx'> - <parameter type-id='type-id-14' name='a' filepath='Objects/dictobject.c' line='3001' column='1'/> - <parameter type-id='type-id-14' name='b' filepath='Objects/dictobject.c' line='3001' column='1'/> - <parameter type-id='type-id-8' name='override' filepath='Objects/dictobject.c' line='3001' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyDict_Merge' mangled-name='PyDict_Merge' filepath='Objects/dictobject.c' line='2994' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyDict_Merge'> - <parameter type-id='type-id-14' name='a' filepath='Objects/dictobject.c' line='3001' column='1'/> - <parameter type-id='type-id-14' name='b' filepath='Objects/dictobject.c' line='3001' column='1'/> - <parameter type-id='type-id-8' name='override' filepath='Objects/dictobject.c' line='3001' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyDict_Update' mangled-name='PyDict_Update' filepath='Objects/dictobject.c' line='2988' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyDict_Update'> - <parameter type-id='type-id-14' name='derived' filepath='Objects/abstract.c' line='2784' column='1'/> - <parameter type-id='type-id-14' name='cls' filepath='Objects/abstract.c' line='2784' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyDict_MergeFromSeq2' mangled-name='PyDict_MergeFromSeq2' filepath='Objects/dictobject.c' line='2731' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyDict_MergeFromSeq2'> - <parameter type-id='type-id-14' name='d' filepath='Objects/dictobject.c' line='2731' column='1'/> - <parameter type-id='type-id-14' name='seq2' filepath='Objects/dictobject.c' line='2731' column='1'/> - <parameter type-id='type-id-8' name='override' filepath='Objects/dictobject.c' line='2731' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyDict_Pop' mangled-name='_PyDict_Pop' filepath='Objects/dictobject.c' line='2244' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyDict_Pop'> - <parameter type-id='type-id-14' name='callable' filepath='Objects/call.c' line='405' column='1'/> - <parameter type-id='type-id-14' name='args' filepath='Objects/call.c' line='406' column='1'/> - <parameter type-id='type-id-14' name='kwargs' filepath='Objects/call.c' line='406' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyDict_Next' mangled-name='PyDict_Next' filepath='Objects/dictobject.c' line='2200' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyDict_Next'> - <parameter type-id='type-id-14' name='op' filepath='Objects/dictobject.c' line='2200' column='1'/> - <parameter type-id='type-id-168' name='ppos' filepath='Objects/dictobject.c' line='2200' column='1'/> - <parameter type-id='type-id-22' name='pkey' filepath='Objects/dictobject.c' line='2200' column='1'/> - <parameter type-id='type-id-22' name='pvalue' filepath='Objects/dictobject.c' line='2200' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <pointer-type-def type-id='type-id-159' size-in-bits='64' id='type-id-529'/> - <function-decl name='_PyDict_Next' mangled-name='_PyDict_Next' filepath='Objects/dictobject.c' line='2119' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyDict_Next'> - <parameter type-id='type-id-14' name='op' filepath='Objects/dictobject.c' line='2119' column='1'/> - <parameter type-id='type-id-168' name='ppos' filepath='Objects/dictobject.c' line='2119' column='1'/> - <parameter type-id='type-id-22' name='pkey' filepath='Objects/dictobject.c' line='2119' column='1'/> - <parameter type-id='type-id-22' name='pvalue' filepath='Objects/dictobject.c' line='2120' column='1'/> - <parameter type-id='type-id-529' name='phash' filepath='Objects/dictobject.c' line='2120' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyDict_Clear' mangled-name='PyDict_Clear' filepath='Objects/dictobject.c' line='2077' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyDict_Clear'> - <parameter type-id='type-id-14' name='self' filepath='Objects/genobject.c' line='53' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_PyDict_DelItemIf' mangled-name='_PyDict_DelItemIf' filepath='Objects/dictobject.c' line='2036' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyDict_DelItemIf'> - <parameter type-id='type-id-14' name='op' filepath='Objects/dictobject.c' line='2036' column='1'/> - <parameter type-id='type-id-14' name='key' filepath='Objects/dictobject.c' line='2036' column='1'/> - <parameter type-id='type-id-139' name='predicate' filepath='Objects/dictobject.c' line='2037' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyDict_DelItem_KnownHash' mangled-name='_PyDict_DelItem_KnownHash' filepath='Objects/dictobject.c' line='2007' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyDict_DelItem_KnownHash'> - <parameter type-id='type-id-14' name='op' filepath='Objects/dictobject.c' line='3711' column='1'/> - <parameter type-id='type-id-14' name='key' filepath='Objects/dictobject.c' line='3711' column='1'/> - <parameter type-id='type-id-159' name='hash' filepath='Objects/dictobject.c' line='3711' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyDict_DelItem' mangled-name='PyDict_DelItem' filepath='Objects/dictobject.c' line='1993' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyDict_DelItem'> - <parameter type-id='type-id-14' name='derived' filepath='Objects/abstract.c' line='2770' column='1'/> - <parameter type-id='type-id-14' name='cls' filepath='Objects/abstract.c' line='2770' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyDict_SetItem_KnownHash' mangled-name='_PyDict_SetItem_KnownHash' filepath='Objects/dictobject.c' line='1910' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyDict_SetItem_KnownHash'> - <parameter type-id='type-id-14' name='op' filepath='Objects/dictobject.c' line='1910' column='1'/> - <parameter type-id='type-id-14' name='key' filepath='Objects/dictobject.c' line='1910' column='1'/> - <parameter type-id='type-id-14' name='value' filepath='Objects/dictobject.c' line='1910' column='1'/> - <parameter type-id='type-id-159' name='hash' filepath='Objects/dictobject.c' line='1911' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyDict_SetItem' mangled-name='PyDict_SetItem' filepath='Objects/dictobject.c' line='1896' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyDict_SetItem'> - <parameter type-id='type-id-14' name='op' filepath='Objects/dictobject.c' line='1896' column='1'/> - <parameter type-id='type-id-14' name='key' filepath='Objects/dictobject.c' line='1896' column='1'/> - <parameter type-id='type-id-14' name='value' filepath='Objects/dictobject.c' line='1896' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyDict_GetItemStringWithError' mangled-name='_PyDict_GetItemStringWithError' filepath='Objects/dictobject.c' line='1818' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyDict_GetItemStringWithError'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2342' column='1'/> - <parameter type-id='type-id-3' name='key' filepath='Objects/abstract.c' line='2342' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyDict_GetItemIdWithError' mangled-name='_PyDict_GetItemIdWithError' filepath='Objects/dictobject.c' line='1806' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyDict_GetItemIdWithError'> - <parameter type-id='type-id-14' name='dp' filepath='Objects/dictobject.c' line='1806' column='1'/> - <parameter type-id='type-id-499' name='key' filepath='Objects/dictobject.c' line='1806' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyDict_GetItemWithError' mangled-name='_PyDict_GetItemWithError' filepath='Objects/dictobject.c' line='1795' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyDict_GetItemWithError'> - <parameter type-id='type-id-14' name='callable' filepath='Objects/call.c' line='438' column='1'/> - <parameter type-id='type-id-14' name='args' filepath='Objects/call.c' line='438' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyDict_GetItemWithError' mangled-name='PyDict_GetItemWithError' filepath='Objects/dictobject.c' line='1770' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyDict_GetItemWithError'> - <parameter type-id='type-id-14' name='func' filepath='Objects/call.c' line='368' column='1'/> - <parameter type-id='type-id-14' name='arg' filepath='Objects/call.c' line='368' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyDict_GetItem_KnownHash' mangled-name='_PyDict_GetItem_KnownHash' filepath='Objects/dictobject.c' line='1749' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyDict_GetItem_KnownHash'> - <parameter type-id='type-id-14' name='op' filepath='Objects/dictobject.c' line='1749' column='1'/> - <parameter type-id='type-id-14' name='key' filepath='Objects/dictobject.c' line='1749' column='1'/> - <parameter type-id='type-id-159' name='hash' filepath='Objects/dictobject.c' line='1749' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyDict_GetItem' mangled-name='PyDict_GetItem' filepath='Objects/dictobject.c' line='1649' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyDict_GetItem'> - <parameter type-id='type-id-14' name='op' filepath='Objects/dictobject.c' line='1649' column='1'/> - <parameter type-id='type-id-14' name='key' filepath='Objects/dictobject.c' line='1649' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyDict_NewPresized' mangled-name='_PyDict_NewPresized' filepath='Objects/dictobject.c' line='1595' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyDict_NewPresized'> - <parameter type-id='type-id-36' name='minused' filepath='Objects/dictobject.c' line='1595' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyDict_MaybeUntrack' mangled-name='_PyDict_MaybeUntrack' filepath='Objects/dictobject.c' line='1116' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyDict_MaybeUntrack'> - <parameter type-id='type-id-14' name='op' filepath='Objects/dictobject.c' line='1116' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_PyDict_HasOnlyStringKeys' mangled-name='_PyDict_HasOnlyStringKeys' filepath='Objects/dictobject.c' line='1091' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyDict_HasOnlyStringKeys'> - <parameter type-id='type-id-14' name='dict' filepath='Objects/dictobject.c' line='1091' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyDict_New' mangled-name='PyDict_New' filepath='Objects/dictobject.c' line='838' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyDict_New'> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyDict_CheckConsistency' mangled-name='_PyDict_CheckConsistency' filepath='Objects/dictobject.c' line='502' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyDict_CheckConsistency'> - <parameter type-id='type-id-14' name='op' filepath='Objects/dictobject.c' line='502' column='1'/> - <parameter type-id='type-id-8' name='check_content' filepath='Objects/dictobject.c' line='502' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyDict_DebugMallocStats' mangled-name='_PyDict_DebugMallocStats' filepath='Objects/dictobject.c' line='294' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyDict_DebugMallocStats'> - <parameter type-id='type-id-473' name='out' filepath='Objects/floatobject.c' line='2039' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Objects/odictobject.c' comp-dir-path='/src' language='LANG_C99'> - <var-decl name='PyODict_Type' type-id='type-id-112' mangled-name='PyODict_Type' visibility='default' filepath='./Include/cpython/odictobject.h' line='15' column='1' elf-symbol-id='PyODict_Type'/> - <var-decl name='PyODictIter_Type' type-id='type-id-112' mangled-name='PyODictIter_Type' visibility='default' filepath='./Include/cpython/odictobject.h' line='16' column='1' elf-symbol-id='PyODictIter_Type'/> - <var-decl name='PyODictKeys_Type' type-id='type-id-112' mangled-name='PyODictKeys_Type' visibility='default' filepath='./Include/cpython/odictobject.h' line='17' column='1' elf-symbol-id='PyODictKeys_Type'/> - <var-decl name='PyODictItems_Type' type-id='type-id-112' mangled-name='PyODictItems_Type' visibility='default' filepath='./Include/cpython/odictobject.h' line='18' column='1' elf-symbol-id='PyODictItems_Type'/> - <var-decl name='PyODictValues_Type' type-id='type-id-112' mangled-name='PyODictValues_Type' visibility='default' filepath='./Include/cpython/odictobject.h' line='19' column='1' elf-symbol-id='PyODictValues_Type'/> - <function-decl name='PyODict_DelItem' mangled-name='PyODict_DelItem' filepath='Objects/odictobject.c' line='1624' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyODict_DelItem'> - <parameter type-id='type-id-14' name='od' filepath='Objects/odictobject.c' line='1624' column='1'/> - <parameter type-id='type-id-14' name='key' filepath='Objects/odictobject.c' line='1624' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyODict_SetItem' mangled-name='PyODict_SetItem' filepath='Objects/odictobject.c' line='1615' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyODict_SetItem'> - <parameter type-id='type-id-14' name='od' filepath='Objects/odictobject.c' line='1615' column='1'/> - <parameter type-id='type-id-14' name='key' filepath='Objects/odictobject.c' line='1615' column='1'/> - <parameter type-id='type-id-14' name='value' filepath='Objects/odictobject.c' line='1615' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyODict_New' mangled-name='PyODict_New' filepath='Objects/odictobject.c' line='1591' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyODict_New'> - <return type-id='type-id-14'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Objects/memoryobject.c' comp-dir-path='/src' language='LANG_C99'> - <var-decl name='_PyManagedBuffer_Type' type-id='type-id-112' mangled-name='_PyManagedBuffer_Type' visibility='default' filepath='./Include/memoryobject.h' line='10' column='1' elf-symbol-id='_PyManagedBuffer_Type'/> - <var-decl name='PyMemoryView_Type' type-id='type-id-112' mangled-name='PyMemoryView_Type' visibility='default' filepath='./Include/memoryobject.h' line='12' column='1' elf-symbol-id='PyMemoryView_Type'/> - <function-decl name='PyBuffer_ToContiguous' mangled-name='PyBuffer_ToContiguous' filepath='Objects/memoryobject.c' line='983' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyBuffer_ToContiguous'> - <parameter type-id='type-id-18' name='buf' filepath='Objects/memoryobject.c' line='983' column='1'/> - <parameter type-id='type-id-479' name='src' filepath='Objects/memoryobject.c' line='983' column='1'/> - <parameter type-id='type-id-36' name='len' filepath='Objects/memoryobject.c' line='983' column='1'/> - <parameter type-id='type-id-1' name='order' filepath='Objects/memoryobject.c' line='983' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyMemoryView_GetContiguous' mangled-name='PyMemoryView_GetContiguous' filepath='Objects/memoryobject.c' line='918' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMemoryView_GetContiguous'> - <parameter type-id='type-id-14' name='obj' filepath='Objects/memoryobject.c' line='918' column='1'/> - <parameter type-id='type-id-8' name='buffertype' filepath='Objects/memoryobject.c' line='918' column='1'/> - <parameter type-id='type-id-1' name='order' filepath='Objects/memoryobject.c' line='918' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyMemoryView_FromObject' mangled-name='PyMemoryView_FromObject' filepath='Objects/memoryobject.c' line='786' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMemoryView_FromObject'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='1634' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyMemoryView_FromBuffer' mangled-name='PyMemoryView_FromBuffer' filepath='Objects/memoryobject.c' line='756' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMemoryView_FromBuffer'> - <parameter type-id='type-id-479' name='info' filepath='Objects/memoryobject.c' line='756' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyMemoryView_FromMemory' mangled-name='PyMemoryView_FromMemory' filepath='Objects/memoryobject.c' line='727' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMemoryView_FromMemory'> - <parameter type-id='type-id-115' name='mem' filepath='Objects/memoryobject.c' line='727' column='1'/> - <parameter type-id='type-id-36' name='size' filepath='Objects/memoryobject.c' line='727' column='1'/> - <parameter type-id='type-id-8' name='flags' filepath='Objects/memoryobject.c' line='727' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Objects/methodobject.c' comp-dir-path='/src' language='LANG_C99'> - <var-decl name='PyCFunction_Type' type-id='type-id-112' mangled-name='PyCFunction_Type' visibility='default' filepath='./Include/methodobject.h' line='14' column='1' elf-symbol-id='PyCFunction_Type'/> - <var-decl name='PyCMethod_Type' type-id='type-id-112' mangled-name='PyCMethod_Type' visibility='default' filepath='./Include/cpython/methodobject.h' line='32' column='1' elf-symbol-id='PyCMethod_Type'/> - <function-decl name='PyCFunction_GetFlags' mangled-name='PyCFunction_GetFlags' filepath='Objects/methodobject.c' line='139' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCFunction_GetFlags'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2303' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyCFunction_GetSelf' mangled-name='PyCFunction_GetSelf' filepath='Objects/methodobject.c' line='129' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCFunction_GetSelf'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2462' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyCFunction_GetFunction' mangled-name='PyCFunction_GetFunction' filepath='Objects/methodobject.c' line='119' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCFunction_GetFunction'> - <parameter type-id='type-id-14' name='op' filepath='Objects/methodobject.c' line='119' column='1'/> - <return type-id='type-id-182'/> - </function-decl> - <function-decl name='PyCMethod_New' mangled-name='PyCMethod_New' filepath='Objects/methodobject.c' line='44' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCMethod_New'> - <parameter type-id='type-id-96' name='ml' filepath='Objects/methodobject.c' line='44' column='1'/> - <parameter type-id='type-id-14' name='self' filepath='Objects/methodobject.c' line='44' column='1'/> - <parameter type-id='type-id-14' name='module' filepath='Objects/methodobject.c' line='44' column='1'/> - <parameter type-id='type-id-74' name='cls' filepath='Objects/methodobject.c' line='44' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyCFunction_NewEx' mangled-name='PyCFunction_NewEx' filepath='Objects/methodobject.c' line='38' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCFunction_NewEx'> - <parameter type-id='type-id-96' name='ml' filepath='Objects/methodobject.c' line='38' column='1'/> - <parameter type-id='type-id-14' name='self' filepath='Objects/methodobject.c' line='38' column='1'/> - <parameter type-id='type-id-14' name='module' filepath='Objects/methodobject.c' line='38' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyCFunction_New' mangled-name='PyCFunction_New' filepath='Objects/methodobject.c' line='32' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCFunction_New'> - <parameter type-id='type-id-96' name='ml' filepath='Objects/methodobject.c' line='32' column='1'/> - <parameter type-id='type-id-14' name='self' filepath='Objects/methodobject.c' line='32' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Objects/moduleobject.c' comp-dir-path='/src' language='LANG_C99'> - <var-decl name='PyModuleDef_Type' type-id='type-id-112' mangled-name='PyModuleDef_Type' visibility='default' filepath='./Include/moduleobject.h' line='41' column='1' elf-symbol-id='PyModuleDef_Type'/> - <var-decl name='PyModule_Type' type-id='type-id-112' mangled-name='PyModule_Type' visibility='default' filepath='./Include/moduleobject.h' line='10' column='1' elf-symbol-id='PyModule_Type'/> - <function-decl name='_PyModuleSpec_IsInitializing' mangled-name='_PyModuleSpec_IsInitializing' filepath='Objects/moduleobject.c' line='718' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyModuleSpec_IsInitializing'> - <parameter type-id='type-id-14' name='spec' filepath='Objects/moduleobject.c' line='718' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyModule_ClearDict' mangled-name='_PyModule_ClearDict' filepath='Objects/moduleobject.c' line='586' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyModule_ClearDict'> - <parameter type-id='type-id-14' name='op' filepath='Objects/dictobject.c' line='1116' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_PyModule_Clear' mangled-name='_PyModule_Clear' filepath='Objects/moduleobject.c' line='578' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyModule_Clear'> - <parameter type-id='type-id-14' name='m' filepath='Objects/moduleobject.c' line='578' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyModule_GetState' mangled-name='PyModule_GetState' filepath='Objects/moduleobject.c' line='568' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyModule_GetState'> - <parameter type-id='type-id-14' name='m' filepath='Objects/moduleobject.c' line='568' column='1'/> - <return type-id='type-id-18'/> - </function-decl> - <class-decl name='PyModuleDef' size-in-bits='832' is-struct='yes' visibility='default' filepath='./Include/moduleobject.h' line='74' column='1' id='type-id-530'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='m_base' type-id='type-id-531' visibility='default' filepath='./Include/moduleobject.h' line='75' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='320'> - <var-decl name='m_name' type-id='type-id-3' visibility='default' filepath='./Include/moduleobject.h' line='76' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='384'> - <var-decl name='m_doc' type-id='type-id-3' visibility='default' filepath='./Include/moduleobject.h' line='77' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='448'> - <var-decl name='m_size' type-id='type-id-36' visibility='default' filepath='./Include/moduleobject.h' line='78' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='512'> - <var-decl name='m_methods' type-id='type-id-96' visibility='default' filepath='./Include/moduleobject.h' line='79' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='576'> - <var-decl name='m_slots' type-id='type-id-532' visibility='default' filepath='./Include/moduleobject.h' line='80' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='640'> - <var-decl name='m_traverse' type-id='type-id-91' visibility='default' filepath='./Include/moduleobject.h' line='81' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='704'> - <var-decl name='m_clear' type-id='type-id-92' visibility='default' filepath='./Include/moduleobject.h' line='82' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='768'> - <var-decl name='m_free' type-id='type-id-104' visibility='default' filepath='./Include/moduleobject.h' line='83' column='1'/> - </data-member> - </class-decl> - <class-decl name='PyModuleDef_Base' size-in-bits='320' is-struct='yes' visibility='default' filepath='./Include/moduleobject.h' line='44' column='1' id='type-id-533'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='ob_base' type-id='type-id-108' visibility='default' filepath='./Include/moduleobject.h' line='45' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='m_init' type-id='type-id-534' visibility='default' filepath='./Include/moduleobject.h' line='46' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='m_index' type-id='type-id-36' visibility='default' filepath='./Include/moduleobject.h' line='47' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='256'> - <var-decl name='m_copy' type-id='type-id-14' visibility='default' filepath='./Include/moduleobject.h' line='48' column='1'/> - </data-member> - </class-decl> - <pointer-type-def type-id='type-id-535' size-in-bits='64' id='type-id-534'/> - <typedef-decl name='PyModuleDef_Base' type-id='type-id-533' filepath='./Include/moduleobject.h' line='49' column='1' id='type-id-531'/> - <class-decl name='PyModuleDef_Slot' size-in-bits='128' is-struct='yes' visibility='default' filepath='./Include/moduleobject.h' line='60' column='1' id='type-id-536'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='slot' type-id='type-id-8' visibility='default' filepath='./Include/moduleobject.h' line='61' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='value' type-id='type-id-18' visibility='default' filepath='./Include/moduleobject.h' line='62' column='1'/> - </data-member> - </class-decl> - <typedef-decl name='PyModuleDef_Slot' type-id='type-id-536' filepath='./Include/pytypedefs.h' line='13' column='1' id='type-id-537'/> - <pointer-type-def type-id='type-id-537' size-in-bits='64' id='type-id-532'/> - <typedef-decl name='PyModuleDef' type-id='type-id-530' filepath='./Include/pytypedefs.h' line='12' column='1' id='type-id-538'/> - <pointer-type-def type-id='type-id-538' size-in-bits='64' id='type-id-539'/> - <function-decl name='PyModule_GetDef' mangled-name='PyModule_GetDef' filepath='Objects/moduleobject.c' line='558' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyModule_GetDef'> - <parameter type-id='type-id-14' name='m' filepath='Objects/moduleobject.c' line='558' column='1'/> - <return type-id='type-id-539'/> - </function-decl> - <function-decl name='PyModule_GetFilename' mangled-name='PyModule_GetFilename' filepath='Objects/moduleobject.c' line='545' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyModule_GetFilename'> - <parameter type-id='type-id-14' name='m' filepath='Objects/moduleobject.c' line='545' column='1'/> - <return type-id='type-id-3'/> - </function-decl> - <function-decl name='PyModule_GetFilenameObject' mangled-name='PyModule_GetFilenameObject' filepath='Objects/moduleobject.c' line='522' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyModule_GetFilenameObject'> - <parameter type-id='type-id-14' name='v' filepath='Objects/abstract.c' line='2122' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyModule_GetName' mangled-name='PyModule_GetName' filepath='Objects/moduleobject.c' line='510' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyModule_GetName'> - <parameter type-id='type-id-14' name='o' filepath='Objects/capsule.c' line='98' column='1'/> - <return type-id='type-id-3'/> - </function-decl> - <function-decl name='PyModule_GetNameObject' mangled-name='PyModule_GetNameObject' filepath='Objects/moduleobject.c' line='487' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyModule_GetNameObject'> - <parameter type-id='type-id-14' name='v' filepath='Objects/abstract.c' line='2122' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyModule_GetDict' mangled-name='PyModule_GetDict' filepath='Objects/moduleobject.c' line='477' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyModule_GetDict'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2462' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyModule_SetDocString' mangled-name='PyModule_SetDocString' filepath='Objects/moduleobject.c' line='463' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyModule_SetDocString'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2378' column='1'/> - <parameter type-id='type-id-3' name='key' filepath='Objects/abstract.c' line='2378' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyModule_AddFunctions' mangled-name='PyModule_AddFunctions' filepath='Objects/moduleobject.c' line='449' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyModule_AddFunctions'> - <parameter type-id='type-id-14' name='m' filepath='Objects/moduleobject.c' line='449' column='1'/> - <parameter type-id='type-id-96' name='functions' filepath='Objects/moduleobject.c' line='449' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyModule_ExecDef' mangled-name='PyModule_ExecDef' filepath='Objects/moduleobject.c' line='384' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyModule_ExecDef'> - <parameter type-id='type-id-14' name='module' filepath='Objects/moduleobject.c' line='384' column='1'/> - <parameter type-id='type-id-539' name='def' filepath='Objects/moduleobject.c' line='384' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyModule_FromDefAndSpec2' mangled-name='PyModule_FromDefAndSpec2' filepath='Objects/moduleobject.c' line='260' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyModule_FromDefAndSpec2'> - <parameter type-id='type-id-539' name='def' filepath='Objects/moduleobject.c' line='260' column='1'/> - <parameter type-id='type-id-14' name='spec' filepath='Objects/moduleobject.c' line='260' column='1'/> - <parameter type-id='type-id-8' name='module_api_version' filepath='Objects/moduleobject.c' line='260' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyModule_CreateInitialized' mangled-name='_PyModule_CreateInitialized' filepath='Objects/moduleobject.c' line='197' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyModule_CreateInitialized'> - <parameter type-id='type-id-539' name='module' filepath='Objects/moduleobject.c' line='197' column='1'/> - <parameter type-id='type-id-8' name='module_api_version' filepath='Objects/moduleobject.c' line='197' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyModule_Create2' mangled-name='PyModule_Create2' filepath='Objects/moduleobject.c' line='186' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyModule_Create2'> - <parameter type-id='type-id-539' name='module' filepath='Objects/moduleobject.c' line='186' column='1'/> - <parameter type-id='type-id-8' name='module_api_version' filepath='Objects/moduleobject.c' line='186' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyModule_New' mangled-name='PyModule_New' filepath='Objects/moduleobject.c' line='126' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyModule_New'> - <parameter type-id='type-id-3' name='str' filepath='Objects/bytesobject.c' line='147' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyModule_NewObject' mangled-name='PyModule_NewObject' filepath='Objects/moduleobject.c' line='110' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyModule_NewObject'> - <parameter type-id='type-id-14' name='name' filepath='Objects/moduleobject.c' line='110' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyModuleDef_Init' mangled-name='PyModuleDef_Init' filepath='Objects/moduleobject.c' line='42' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyModuleDef_Init'> - <parameter type-id='type-id-539' name='def' filepath='Objects/moduleobject.c' line='42' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-type size-in-bits='64' id='type-id-535'> - <return type-id='type-id-14'/> - </function-type> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Objects/namespaceobject.c' comp-dir-path='/src' language='LANG_C99'> - <var-decl name='_PyNamespace_Type' type-id='type-id-112' mangled-name='_PyNamespace_Type' visibility='default' filepath='./Include/internal/pycore_namespace.h' line='13' column='1' elf-symbol-id='_PyNamespace_Type'/> - <function-decl name='_PyNamespace_New' mangled-name='_PyNamespace_New' filepath='Objects/namespaceobject.c' line='248' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyNamespace_New'> - <parameter type-id='type-id-14' name='item' filepath='Objects/abstract.c' line='1408' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Objects/object.c' comp-dir-path='/src' language='LANG_C99'> - - <array-type-def dimensions='1' type-id='type-id-8' size-in-bits='infinite' id='type-id-540'> - <subrange length='infinite' id='type-id-6'/> - - </array-type-def> - <var-decl name='_Py_SwappedOp' type-id='type-id-540' mangled-name='_Py_SwappedOp' visibility='default' filepath='./Include/cpython/object.h' line='352' column='1' elf-symbol-id='_Py_SwappedOp'/> - <var-decl name='_PyNone_Type' type-id='type-id-112' mangled-name='_PyNone_Type' visibility='default' filepath='./Include/cpython/object.h' line='346' column='1' elf-symbol-id='_PyNone_Type'/> - <var-decl name='_Py_NoneStruct' type-id='type-id-108' mangled-name='_Py_NoneStruct' visibility='default' filepath='./Include/object.h' line='646' column='1' elf-symbol-id='_Py_NoneStruct'/> - <var-decl name='_PyNotImplemented_Type' type-id='type-id-112' mangled-name='_PyNotImplemented_Type' visibility='default' filepath='./Include/cpython/object.h' line='347' column='1' elf-symbol-id='_PyNotImplemented_Type'/> - <var-decl name='_Py_NotImplementedStruct' type-id='type-id-108' mangled-name='_Py_NotImplementedStruct' visibility='default' filepath='./Include/object.h' line='660' column='1' elf-symbol-id='_Py_NotImplementedStruct'/> - <function-decl name='Py_IsFalse' mangled-name='Py_IsFalse' filepath='Objects/object.c' line='2455' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_IsFalse'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2303' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='Py_IsTrue' mangled-name='Py_IsTrue' filepath='Objects/object.c' line='2450' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_IsTrue'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2303' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='Py_IsNone' mangled-name='Py_IsNone' filepath='Objects/object.c' line='2445' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_IsNone'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2303' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='Py_Is' mangled-name='Py_Is' filepath='Objects/object.c' line='2440' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_Is'> - <parameter type-id='type-id-14' name='derived' filepath='Objects/abstract.c' line='2784' column='1'/> - <parameter type-id='type-id-14' name='cls' filepath='Objects/abstract.c' line='2784' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='Py_XNewRef' mangled-name='Py_XNewRef' filepath='Objects/object.c' line='2428' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_XNewRef'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2462' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='Py_NewRef' mangled-name='Py_NewRef' filepath='Objects/object.c' line='2422' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_NewRef'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2462' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyObject_GET_WEAKREFS_LISTPTR' mangled-name='PyObject_GET_WEAKREFS_LISTPTR' filepath='Objects/object.c' line='2411' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_GET_WEAKREFS_LISTPTR'> - <parameter type-id='type-id-14' name='op' filepath='Objects/object.c' line='2411' column='1'/> - <return type-id='type-id-22'/> - </function-decl> - <function-decl name='_Py_Dealloc' mangled-name='_Py_Dealloc' filepath='Objects/object.c' line='2366' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_Dealloc'> - <parameter type-id='type-id-14' name='op' filepath='Objects/object.c' line='2366' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_PyObject_AssertFailed' mangled-name='_PyObject_AssertFailed' filepath='Objects/object.c' line='2310' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_AssertFailed'> - <parameter type-id='type-id-14' name='obj' filepath='Objects/object.c' line='2310' column='1'/> - <parameter type-id='type-id-3' name='expr' filepath='Objects/object.c' line='2310' column='1'/> - <parameter type-id='type-id-3' name='msg' filepath='Objects/object.c' line='2310' column='1'/> - <parameter type-id='type-id-3' name='file' filepath='Objects/object.c' line='2311' column='1'/> - <parameter type-id='type-id-8' name='line' filepath='Objects/object.c' line='2311' column='1'/> - <parameter type-id='type-id-3' name='function' filepath='Objects/object.c' line='2311' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_PyTrash_cond' mangled-name='_PyTrash_cond' filepath='Objects/object.c' line='2303' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTrash_cond'> - <parameter type-id='type-id-14' name='op' filepath='Objects/object.c' line='2303' column='1'/> - <parameter type-id='type-id-78' name='dealloc' filepath='Objects/object.c' line='2303' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyTrash_end' mangled-name='_PyTrash_end' filepath='Objects/object.c' line='2291' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTrash_end'> - <parameter type-id='type-id-10' name='tstate' filepath='Objects/object.c' line='2291' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_PyTrash_begin' mangled-name='_PyTrash_begin' filepath='Objects/object.c' line='2277' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTrash_begin'> - <parameter type-id='type-id-10' name='tstate' filepath='Objects/object.c' line='2277' column='1'/> - <parameter type-id='type-id-14' name='op' filepath='Objects/object.c' line='2277' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='Py_ReprLeave' mangled-name='Py_ReprLeave' filepath='Objects/object.c' line='2186' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_ReprLeave'> - <parameter type-id='type-id-14' name='obj' filepath='Objects/object.c' line='2186' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='Py_ReprEnter' mangled-name='Py_ReprEnter' filepath='Objects/object.c' line='2152' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_ReprEnter'> - <parameter type-id='type-id-14' name='dict' filepath='Objects/dictobject.c' line='1091' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyObject_DebugTypeStats' mangled-name='_PyObject_DebugTypeStats' filepath='Objects/object.c' line='2131' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_DebugTypeStats'> - <parameter type-id='type-id-473' name='out' filepath='Objects/object.c' line='2131' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_Py_NewReference' mangled-name='_Py_NewReference' filepath='Objects/object.c' line='2016' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_NewReference'> - <parameter type-id='type-id-14' name='op' filepath='Objects/object.c' line='2016' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyObject_Dir' mangled-name='PyObject_Dir' filepath='Objects/object.c' line='1602' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_Dir'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2462' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyCallable_Check' mangled-name='PyCallable_Check' filepath='Objects/object.c' line='1530' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCallable_Check'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2303' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyObject_Not' mangled-name='PyObject_Not' filepath='Objects/object.c' line='1518' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_Not'> - <parameter type-id='type-id-14' name='obj' filepath='Objects/abstract.c' line='2845' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyObject_IsTrue' mangled-name='PyObject_IsTrue' filepath='Objects/object.c' line='1490' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_IsTrue'> - <parameter type-id='type-id-14' name='obj' filepath='Objects/abstract.c' line='2845' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyObject_GenericSetDict' mangled-name='PyObject_GenericSetDict' filepath='Objects/object.c' line='1454' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_GenericSetDict'> - <parameter type-id='type-id-14' name='obj' filepath='Objects/object.c' line='1454' column='1'/> - <parameter type-id='type-id-14' name='value' filepath='Objects/object.c' line='1454' column='1'/> - <parameter type-id='type-id-18' name='context' filepath='Objects/object.c' line='1454' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyObject_GenericSetAttr' mangled-name='PyObject_GenericSetAttr' filepath='Objects/object.c' line='1448' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_GenericSetAttr'> - <parameter type-id='type-id-14' name='op' filepath='Objects/dictobject.c' line='1896' column='1'/> - <parameter type-id='type-id-14' name='key' filepath='Objects/dictobject.c' line='1896' column='1'/> - <parameter type-id='type-id-14' name='value' filepath='Objects/dictobject.c' line='1896' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyObject_GenericSetAttrWithDict' mangled-name='_PyObject_GenericSetAttrWithDict' filepath='Objects/object.c' line='1365' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_GenericSetAttrWithDict'> - <parameter type-id='type-id-14' name='obj' filepath='Objects/object.c' line='1365' column='1'/> - <parameter type-id='type-id-14' name='name' filepath='Objects/object.c' line='1365' column='1'/> - <parameter type-id='type-id-14' name='value' filepath='Objects/object.c' line='1366' column='1'/> - <parameter type-id='type-id-14' name='dict' filepath='Objects/object.c' line='1366' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyObject_GenericGetAttr' mangled-name='PyObject_GenericGetAttr' filepath='Objects/object.c' line='1359' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_GenericGetAttr'> - <parameter type-id='type-id-14' name='v' filepath='Objects/abstract.c' line='1256' column='1'/> - <parameter type-id='type-id-14' name='w' filepath='Objects/abstract.c' line='1256' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyObject_GenericGetAttrWithDict' mangled-name='_PyObject_GenericGetAttrWithDict' filepath='Objects/object.c' line='1238' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_GenericGetAttrWithDict'> - <parameter type-id='type-id-14' name='obj' filepath='Objects/object.c' line='1238' column='1'/> - <parameter type-id='type-id-14' name='name' filepath='Objects/object.c' line='1238' column='1'/> - <parameter type-id='type-id-14' name='dict' filepath='Objects/object.c' line='1239' column='1'/> - <parameter type-id='type-id-8' name='suppress' filepath='Objects/object.c' line='1239' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyObject_GetMethod' mangled-name='_PyObject_GetMethod' filepath='Objects/object.c' line='1145' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_GetMethod'> - <parameter type-id='type-id-14' name='obj' filepath='Objects/object.c' line='1145' column='1'/> - <parameter type-id='type-id-14' name='name' filepath='Objects/object.c' line='1145' column='1'/> - <parameter type-id='type-id-22' name='method' filepath='Objects/object.c' line='1145' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyObject_NextNotImplemented' mangled-name='_PyObject_NextNotImplemented' filepath='Objects/object.c' line='1125' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_NextNotImplemented'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2462' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyObject_SelfIter' mangled-name='PyObject_SelfIter' filepath='Objects/object.c' line='1113' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_SelfIter'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2462' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyObject_GetDictPtr' mangled-name='_PyObject_GetDictPtr' filepath='Objects/object.c' line='1091' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_GetDictPtr'> - <parameter type-id='type-id-14' name='obj' filepath='Objects/object.c' line='1091' column='1'/> - <return type-id='type-id-22'/> - </function-decl> - <function-decl name='PyObject_SetAttr' mangled-name='PyObject_SetAttr' filepath='Objects/object.c' line='1013' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_SetAttr'> - <parameter type-id='type-id-14' name='v' filepath='Objects/object.c' line='1013' column='1'/> - <parameter type-id='type-id-14' name='name' filepath='Objects/object.c' line='1013' column='1'/> - <parameter type-id='type-id-14' name='value' filepath='Objects/object.c' line='1013' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyObject_HasAttr' mangled-name='PyObject_HasAttr' filepath='Objects/object.c' line='998' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_HasAttr'> - <parameter type-id='type-id-14' name='derived' filepath='Objects/abstract.c' line='2770' column='1'/> - <parameter type-id='type-id-14' name='cls' filepath='Objects/abstract.c' line='2770' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyObject_LookupAttrId' mangled-name='_PyObject_LookupAttrId' filepath='Objects/object.c' line='987' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_LookupAttrId'> - <parameter type-id='type-id-14' name='v' filepath='Objects/object.c' line='987' column='1'/> - <parameter type-id='type-id-499' name='name' filepath='Objects/object.c' line='987' column='1'/> - <parameter type-id='type-id-22' name='result' filepath='Objects/object.c' line='987' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyObject_LookupAttr' mangled-name='_PyObject_LookupAttr' filepath='Objects/object.c' line='938' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_LookupAttr'> - <parameter type-id='type-id-14' name='v' filepath='Objects/object.c' line='938' column='1'/> - <parameter type-id='type-id-14' name='name' filepath='Objects/object.c' line='938' column='1'/> - <parameter type-id='type-id-22' name='result' filepath='Objects/object.c' line='938' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyObject_GetAttr' mangled-name='PyObject_GetAttr' filepath='Objects/object.c' line='904' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_GetAttr'> - <parameter type-id='type-id-14' name='v' filepath='Objects/object.c' line='904' column='1'/> - <parameter type-id='type-id-14' name='name' filepath='Objects/object.c' line='904' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyObject_SetAttrId' mangled-name='_PyObject_SetAttrId' filepath='Objects/object.c' line='863' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_SetAttrId'> - <parameter type-id='type-id-14' name='v' filepath='Objects/object.c' line='863' column='1'/> - <parameter type-id='type-id-499' name='name' filepath='Objects/object.c' line='863' column='1'/> - <parameter type-id='type-id-14' name='w' filepath='Objects/object.c' line='863' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyObject_GetAttrId' mangled-name='_PyObject_GetAttrId' filepath='Objects/object.c' line='852' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_GetAttrId'> - <parameter type-id='type-id-14' name='dp' filepath='Objects/dictobject.c' line='1806' column='1'/> - <parameter type-id='type-id-499' name='key' filepath='Objects/dictobject.c' line='1806' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyObject_IsAbstract' mangled-name='_PyObject_IsAbstract' filepath='Objects/object.c' line='835' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_IsAbstract'> - <parameter type-id='type-id-14' name='obj' filepath='Objects/abstract.c' line='302' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyObject_SetAttrString' mangled-name='PyObject_SetAttrString' filepath='Objects/object.c' line='819' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_SetAttrString'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2359' column='1'/> - <parameter type-id='type-id-3' name='key' filepath='Objects/abstract.c' line='2359' column='1'/> - <parameter type-id='type-id-14' name='value' filepath='Objects/abstract.c' line='2359' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyObject_HasAttrString' mangled-name='PyObject_HasAttrString' filepath='Objects/object.c' line='807' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_HasAttrString'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2378' column='1'/> - <parameter type-id='type-id-3' name='key' filepath='Objects/abstract.c' line='2378' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyObject_GetAttrString' mangled-name='PyObject_GetAttrString' filepath='Objects/object.c' line='792' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_GetAttrString'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2342' column='1'/> - <parameter type-id='type-id-3' name='key' filepath='Objects/abstract.c' line='2342' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyObject_Hash' mangled-name='PyObject_Hash' filepath='Objects/object.c' line='771' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_Hash'> - <parameter type-id='type-id-14' name='v' filepath='Objects/object.c' line='771' column='1'/> - <return type-id='type-id-159'/> - </function-decl> - <function-decl name='PyObject_HashNotImplemented' mangled-name='PyObject_HashNotImplemented' filepath='Objects/object.c' line='763' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_HashNotImplemented'> - <parameter type-id='type-id-14' name='v' filepath='Objects/object.c' line='763' column='1'/> - <return type-id='type-id-159'/> - </function-decl> - <function-decl name='PyObject_RichCompareBool' mangled-name='PyObject_RichCompareBool' filepath='Objects/object.c' line='737' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_RichCompareBool'> - <parameter type-id='type-id-14' name='v' filepath='Objects/object.c' line='737' column='1'/> - <parameter type-id='type-id-14' name='w' filepath='Objects/object.c' line='737' column='1'/> - <parameter type-id='type-id-8' name='op' filepath='Objects/object.c' line='737' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyObject_RichCompare' mangled-name='PyObject_RichCompare' filepath='Objects/object.c' line='715' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_RichCompare'> - <parameter type-id='type-id-14' name='v' filepath='Objects/object.c' line='715' column='1'/> - <parameter type-id='type-id-14' name='w' filepath='Objects/object.c' line='715' column='1'/> - <parameter type-id='type-id-8' name='op' filepath='Objects/object.c' line='715' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyObject_FunctionStr' mangled-name='_PyObject_FunctionStr' filepath='Objects/object.c' line='590' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_FunctionStr'> - <parameter type-id='type-id-14' name='x' filepath='Objects/object.c' line='590' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyObject_Bytes' mangled-name='PyObject_Bytes' filepath='Objects/object.c' line='542' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_Bytes'> - <parameter type-id='type-id-14' name='v' filepath='Objects/abstract.c' line='2122' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyObject_ASCII' mangled-name='PyObject_ASCII' filepath='Objects/object.c' line='515' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_ASCII'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2817' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyObject_Str' mangled-name='PyObject_Str' filepath='Objects/object.c' line='455' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_Str'> - <parameter type-id='type-id-14' name='v' filepath='Objects/abstract.c' line='2122' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyObject_Repr' mangled-name='PyObject_Repr' filepath='Objects/object.c' line='402' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_Repr'> - <parameter type-id='type-id-14' name='v' filepath='Objects/abstract.c' line='2122' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyObject_Dump' mangled-name='_PyObject_Dump' filepath='Objects/object.c' line='361' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_Dump'> - <parameter type-id='type-id-14' name='op' filepath='Objects/object.c' line='361' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_PyObject_IsFreed' mangled-name='_PyObject_IsFreed' filepath='Objects/object.c' line='340' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_IsFreed'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2303' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_Py_BreakPoint' mangled-name='_Py_BreakPoint' filepath='Objects/object.c' line='328' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_BreakPoint'> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyObject_Print' mangled-name='PyObject_Print' filepath='Objects/object.c' line='257' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_Print'> - <parameter type-id='type-id-14' name='op' filepath='Objects/object.c' line='257' column='1'/> - <parameter type-id='type-id-473' name='fp' filepath='Objects/object.c' line='257' column='1'/> - <parameter type-id='type-id-8' name='flags' filepath='Objects/object.c' line='257' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyObject_CallFinalizerFromDealloc' mangled-name='PyObject_CallFinalizerFromDealloc' filepath='Objects/object.c' line='215' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_CallFinalizerFromDealloc'> - <parameter type-id='type-id-14' name='obj' filepath='Objects/abstract.c' line='302' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyObject_CallFinalizer' mangled-name='PyObject_CallFinalizer' filepath='Objects/object.c' line='198' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_CallFinalizer'> - <parameter type-id='type-id-14' name='m' filepath='Objects/moduleobject.c' line='578' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <pointer-type-def type-id='type-id-77' size-in-bits='64' id='type-id-541'/> - <function-decl name='_PyObject_NewVar' mangled-name='_PyObject_NewVar' filepath='Objects/object.c' line='185' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_NewVar'> - <parameter type-id='type-id-74' name='tp' filepath='Objects/object.c' line='185' column='1'/> - <parameter type-id='type-id-36' name='nitems' filepath='Objects/object.c' line='185' column='1'/> - <return type-id='type-id-541'/> - </function-decl> - <function-decl name='_PyObject_New' mangled-name='_PyObject_New' filepath='Objects/object.c' line='174' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_New'> - <parameter type-id='type-id-74' name='tp' filepath='Objects/object.c' line='174' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyObject_InitVar' mangled-name='PyObject_InitVar' filepath='Objects/object.c' line='163' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_InitVar'> - <parameter type-id='type-id-541' name='op' filepath='Objects/object.c' line='163' column='1'/> - <parameter type-id='type-id-74' name='tp' filepath='Objects/object.c' line='163' column='1'/> - <parameter type-id='type-id-36' name='size' filepath='Objects/object.c' line='163' column='1'/> - <return type-id='type-id-541'/> - </function-decl> - <function-decl name='PyObject_Init' mangled-name='PyObject_Init' filepath='Objects/object.c' line='152' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_Init'> - <parameter type-id='type-id-14' name='op' filepath='Objects/object.c' line='152' column='1'/> - <parameter type-id='type-id-74' name='tp' filepath='Objects/object.c' line='152' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_Py_DecRef' mangled-name='_Py_DecRef' filepath='Objects/object.c' line='146' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_DecRef'> - <parameter type-id='type-id-14' name='op' filepath='Objects/object.c' line='2016' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_Py_IncRef' mangled-name='_Py_IncRef' filepath='Objects/object.c' line='140' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_IncRef'> - <parameter type-id='type-id-14' name='op' filepath='Objects/object.c' line='2016' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='Py_DecRef' mangled-name='Py_DecRef' filepath='Objects/object.c' line='134' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_DecRef'> - <parameter type-id='type-id-14' name='op' filepath='Objects/object.c' line='2016' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='Py_IncRef' mangled-name='Py_IncRef' filepath='Objects/object.c' line='128' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_IncRef'> - <parameter type-id='type-id-14' name='op' filepath='Objects/object.c' line='2016' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_PyObject_CheckConsistency' mangled-name='_PyObject_CheckConsistency' filepath='Objects/object.c' line='35' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_CheckConsistency'> - <parameter type-id='type-id-14' name='op' filepath='Objects/object.c' line='35' column='1'/> - <parameter type-id='type-id-8' name='check_content' filepath='Objects/object.c' line='35' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Objects/obmalloc.c' comp-dir-path='/src' language='LANG_C99'> - <class-decl name='_PyTraceMalloc_Config' size-in-bits='96' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_pymem.h' line='72' column='1' id='type-id-542'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='initialized' type-id='type-id-543' visibility='default' filepath='./Include/internal/pycore_pymem.h' line='79' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='32'> - <var-decl name='tracing' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_pymem.h' line='83' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='max_nframe' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_pymem.h' line='87' column='1'/> - </data-member> - </class-decl> - <enum-decl name='__anonymous_enum__' is-anonymous='yes' filepath='./Include/internal/pycore_pymem.h' line='75' column='1' id='type-id-543'> - <underlying-type type-id='type-id-126'/> - <enumerator name='TRACEMALLOC_NOT_INITIALIZED' value='0'/> - <enumerator name='TRACEMALLOC_INITIALIZED' value='1'/> - <enumerator name='TRACEMALLOC_FINALIZED' value='2'/> - </enum-decl> - <var-decl name='_Py_tracemalloc_config' type-id='type-id-542' mangled-name='_Py_tracemalloc_config' visibility='default' filepath='./Include/internal/pycore_pymem.h' line='95' column='1' elf-symbol-id='_Py_tracemalloc_config'/> - <function-decl name='_PyObject_DebugMallocStats' mangled-name='_PyObject_DebugMallocStats' filepath='Objects/obmalloc.c' line='2958' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_DebugMallocStats'> - <parameter type-id='type-id-473' name='out' filepath='Objects/obmalloc.c' line='2958' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyDebugAllocatorStats' mangled-name='_PyDebugAllocatorStats' filepath='Objects/obmalloc.c' line='2913' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyDebugAllocatorStats'> - <parameter type-id='type-id-473' name='out' filepath='Objects/obmalloc.c' line='2913' column='1'/> - <parameter type-id='type-id-3' name='block_name' filepath='Objects/obmalloc.c' line='2914' column='1'/> - <parameter type-id='type-id-8' name='num_blocks' filepath='Objects/obmalloc.c' line='2914' column='1'/> - <parameter type-id='type-id-54' name='sizeof_block' filepath='Objects/obmalloc.c' line='2914' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_Py_GetAllocatedBlocks' mangled-name='_Py_GetAllocatedBlocks' filepath='Objects/obmalloc.c' line='1277' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_GetAllocatedBlocks'> - <return type-id='type-id-36'/> - </function-decl> - <function-decl name='PyObject_Free' mangled-name='PyObject_Free' filepath='Objects/obmalloc.c' line='738' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_Free'> - <parameter type-id='type-id-18' name='ptr' filepath='Objects/obmalloc.c' line='738' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyObject_Realloc' mangled-name='PyObject_Realloc' filepath='Objects/obmalloc.c' line='729' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_Realloc'> - <parameter type-id='type-id-18' name='ptr' filepath='Objects/obmalloc.c' line='729' column='1'/> - <parameter type-id='type-id-54' name='new_size' filepath='Objects/obmalloc.c' line='729' column='1'/> - <return type-id='type-id-18'/> - </function-decl> - <function-decl name='PyObject_Calloc' mangled-name='PyObject_Calloc' filepath='Objects/obmalloc.c' line='716' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_Calloc'> - <parameter type-id='type-id-54' name='nelem' filepath='Objects/obmalloc.c' line='716' column='1'/> - <parameter type-id='type-id-54' name='elsize' filepath='Objects/obmalloc.c' line='716' column='1'/> - <return type-id='type-id-18'/> - </function-decl> - <function-decl name='PyObject_Malloc' mangled-name='PyObject_Malloc' filepath='Objects/obmalloc.c' line='703' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_Malloc'> - <parameter type-id='type-id-54' name='size' filepath='Objects/obmalloc.c' line='703' column='1'/> - <return type-id='type-id-18'/> - </function-decl> - <function-decl name='_PyMem_Strdup' mangled-name='_PyMem_Strdup' filepath='Objects/obmalloc.c' line='690' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyMem_Strdup'> - <parameter type-id='type-id-3' name='str' filepath='Objects/obmalloc.c' line='690' column='1'/> - <return type-id='type-id-115'/> - </function-decl> - <function-decl name='_PyMem_RawStrdup' mangled-name='_PyMem_RawStrdup' filepath='Objects/obmalloc.c' line='677' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyMem_RawStrdup'> - <parameter type-id='type-id-3' name='str' filepath='Objects/obmalloc.c' line='690' column='1'/> - <return type-id='type-id-115'/> - </function-decl> - <qualified-type-def type-id='type-id-282' const='yes' id='type-id-544'/> - <pointer-type-def type-id='type-id-544' size-in-bits='64' id='type-id-545'/> - <function-decl name='_PyMem_RawWcsdup' mangled-name='_PyMem_RawWcsdup' filepath='Objects/obmalloc.c' line='657' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyMem_RawWcsdup'> - <parameter type-id='type-id-545' name='str' filepath='Objects/obmalloc.c' line='657' column='1'/> - <return type-id='type-id-281'/> - </function-decl> - <function-decl name='PyMem_Free' mangled-name='PyMem_Free' filepath='Objects/obmalloc.c' line='649' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMem_Free'> - <parameter type-id='type-id-18' name='ptr' filepath='Objects/obmalloc.c' line='738' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyMem_Realloc' mangled-name='PyMem_Realloc' filepath='Objects/obmalloc.c' line='640' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMem_Realloc'> - <parameter type-id='type-id-18' name='ptr' filepath='Objects/obmalloc.c' line='729' column='1'/> - <parameter type-id='type-id-54' name='new_size' filepath='Objects/obmalloc.c' line='729' column='1'/> - <return type-id='type-id-18'/> - </function-decl> - <function-decl name='PyMem_Calloc' mangled-name='PyMem_Calloc' filepath='Objects/obmalloc.c' line='627' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMem_Calloc'> - <parameter type-id='type-id-54' name='nelem' filepath='Objects/obmalloc.c' line='716' column='1'/> - <parameter type-id='type-id-54' name='elsize' filepath='Objects/obmalloc.c' line='716' column='1'/> - <return type-id='type-id-18'/> - </function-decl> - <function-decl name='PyMem_Malloc' mangled-name='PyMem_Malloc' filepath='Objects/obmalloc.c' line='614' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMem_Malloc'> - <parameter type-id='type-id-54' name='size' filepath='Objects/obmalloc.c' line='703' column='1'/> - <return type-id='type-id-18'/> - </function-decl> - <function-decl name='PyMem_RawFree' mangled-name='PyMem_RawFree' filepath='Objects/obmalloc.c' line='607' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMem_RawFree'> - <parameter type-id='type-id-18' name='ptr' filepath='Objects/obmalloc.c' line='738' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyMem_RawRealloc' mangled-name='PyMem_RawRealloc' filepath='Objects/obmalloc.c' line='599' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMem_RawRealloc'> - <parameter type-id='type-id-18' name='ptr' filepath='Objects/obmalloc.c' line='729' column='1'/> - <parameter type-id='type-id-54' name='new_size' filepath='Objects/obmalloc.c' line='729' column='1'/> - <return type-id='type-id-18'/> - </function-decl> - <function-decl name='PyMem_RawCalloc' mangled-name='PyMem_RawCalloc' filepath='Objects/obmalloc.c' line='590' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMem_RawCalloc'> - <parameter type-id='type-id-54' name='nelem' filepath='Objects/obmalloc.c' line='716' column='1'/> - <parameter type-id='type-id-54' name='elsize' filepath='Objects/obmalloc.c' line='716' column='1'/> - <return type-id='type-id-18'/> - </function-decl> - <function-decl name='PyMem_RawMalloc' mangled-name='PyMem_RawMalloc' filepath='Objects/obmalloc.c' line='576' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMem_RawMalloc'> - <parameter type-id='type-id-54' name='size' filepath='Objects/obmalloc.c' line='703' column='1'/> - <return type-id='type-id-18'/> - </function-decl> - <class-decl name='__anonymous_struct__' size-in-bits='192' is-struct='yes' is-anonymous='yes' naming-typedef-id='type-id-546' visibility='default' filepath='./Include/cpython/objimpl.h' line='56' column='1' id='type-id-547'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='ctx' type-id='type-id-18' visibility='default' filepath='./Include/cpython/objimpl.h' line='58' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='alloc' type-id='type-id-548' visibility='default' filepath='./Include/cpython/objimpl.h' line='61' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='free' type-id='type-id-549' visibility='default' filepath='./Include/cpython/objimpl.h' line='64' column='1'/> - </data-member> - </class-decl> - <pointer-type-def type-id='type-id-550' size-in-bits='64' id='type-id-548'/> - <pointer-type-def type-id='type-id-551' size-in-bits='64' id='type-id-549'/> - <typedef-decl name='PyObjectArenaAllocator' type-id='type-id-547' filepath='./Include/cpython/objimpl.h' line='65' column='1' id='type-id-546'/> - <pointer-type-def type-id='type-id-546' size-in-bits='64' id='type-id-552'/> - <function-decl name='PyObject_SetArenaAllocator' mangled-name='PyObject_SetArenaAllocator' filepath='Objects/obmalloc.c' line='570' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_SetArenaAllocator'> - <parameter type-id='type-id-552' name='allocator' filepath='Objects/obmalloc.c' line='570' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyObject_GetArenaAllocator' mangled-name='PyObject_GetArenaAllocator' filepath='Objects/obmalloc.c' line='552' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_GetArenaAllocator'> - <parameter type-id='type-id-552' name='allocator' filepath='Objects/obmalloc.c' line='570' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <enum-decl name='__anonymous_enum__' is-anonymous='yes' filepath='./Include/cpython/pymem.h' line='23' column='1' id='type-id-553'> - <underlying-type type-id='type-id-126'/> - <enumerator name='PYMEM_DOMAIN_RAW' value='0'/> - <enumerator name='PYMEM_DOMAIN_MEM' value='1'/> - <enumerator name='PYMEM_DOMAIN_OBJ' value='2'/> - </enum-decl> - <typedef-decl name='PyMemAllocatorDomain' type-id='type-id-553' filepath='./Include/cpython/pymem.h' line='32' column='1' id='type-id-554'/> - <class-decl name='__anonymous_struct__' size-in-bits='320' is-struct='yes' is-anonymous='yes' naming-typedef-id='type-id-555' visibility='default' filepath='./Include/cpython/pymem.h' line='47' column='1' id='type-id-556'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='ctx' type-id='type-id-18' visibility='default' filepath='./Include/cpython/pymem.h' line='49' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='malloc' type-id='type-id-548' visibility='default' filepath='./Include/cpython/pymem.h' line='52' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='calloc' type-id='type-id-557' visibility='default' filepath='./Include/cpython/pymem.h' line='55' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='realloc' type-id='type-id-558' visibility='default' filepath='./Include/cpython/pymem.h' line='58' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='256'> - <var-decl name='free' type-id='type-id-559' visibility='default' filepath='./Include/cpython/pymem.h' line='61' column='1'/> - </data-member> - </class-decl> - <pointer-type-def type-id='type-id-560' size-in-bits='64' id='type-id-557'/> - <pointer-type-def type-id='type-id-561' size-in-bits='64' id='type-id-558'/> - <pointer-type-def type-id='type-id-562' size-in-bits='64' id='type-id-559'/> - <typedef-decl name='PyMemAllocatorEx' type-id='type-id-556' filepath='./Include/cpython/pymem.h' line='62' column='1' id='type-id-555'/> - <pointer-type-def type-id='type-id-555' size-in-bits='64' id='type-id-563'/> - <function-decl name='PyMem_SetAllocator' mangled-name='PyMem_SetAllocator' filepath='Objects/obmalloc.c' line='540' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMem_SetAllocator'> - <parameter type-id='type-id-554' name='domain' filepath='Objects/obmalloc.c' line='540' column='1'/> - <parameter type-id='type-id-563' name='allocator' filepath='Objects/obmalloc.c' line='540' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyMem_GetAllocator' mangled-name='PyMem_GetAllocator' filepath='Objects/obmalloc.c' line='522' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMem_GetAllocator'> - <parameter type-id='type-id-554' name='domain' filepath='Objects/obmalloc.c' line='540' column='1'/> - <parameter type-id='type-id-563' name='allocator' filepath='Objects/obmalloc.c' line='540' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyMem_SetupDebugHooks' mangled-name='PyMem_SetupDebugHooks' filepath='Objects/obmalloc.c' line='514' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMem_SetupDebugHooks'> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_PyMem_GetCurrentAllocatorName' mangled-name='_PyMem_GetCurrentAllocatorName' filepath='Objects/obmalloc.c' line='376' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyMem_GetCurrentAllocatorName'> - <return type-id='type-id-3'/> - </function-decl> - <enum-decl name='__anonymous_enum__' is-anonymous='yes' filepath='./Include/cpython/pymem.h' line='34' column='1' id='type-id-564'> - <underlying-type type-id='type-id-126'/> - <enumerator name='PYMEM_ALLOCATOR_NOT_SET' value='0'/> - <enumerator name='PYMEM_ALLOCATOR_DEFAULT' value='1'/> - <enumerator name='PYMEM_ALLOCATOR_DEBUG' value='2'/> - <enumerator name='PYMEM_ALLOCATOR_MALLOC' value='3'/> - <enumerator name='PYMEM_ALLOCATOR_MALLOC_DEBUG' value='4'/> - <enumerator name='PYMEM_ALLOCATOR_PYMALLOC' value='5'/> - <enumerator name='PYMEM_ALLOCATOR_PYMALLOC_DEBUG' value='6'/> - </enum-decl> - <typedef-decl name='PyMemAllocatorName' type-id='type-id-564' filepath='./Include/cpython/pymem.h' line='44' column='1' id='type-id-565'/> - <function-decl name='_PyMem_SetupAllocators' mangled-name='_PyMem_SetupAllocators' filepath='Objects/obmalloc.c' line='309' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyMem_SetupAllocators'> - <parameter type-id='type-id-565' name='allocator' filepath='Objects/obmalloc.c' line='309' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <pointer-type-def type-id='type-id-565' size-in-bits='64' id='type-id-566'/> - <function-decl name='_PyMem_GetAllocatorName' mangled-name='_PyMem_GetAllocatorName' filepath='Objects/obmalloc.c' line='273' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyMem_GetAllocatorName'> - <parameter type-id='type-id-3' name='name' filepath='Objects/obmalloc.c' line='273' column='1'/> - <parameter type-id='type-id-566' name='allocator' filepath='Objects/obmalloc.c' line='273' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyMem_SetDefaultAllocator' mangled-name='_PyMem_SetDefaultAllocator' filepath='Objects/obmalloc.c' line='260' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyMem_SetDefaultAllocator'> - <parameter type-id='type-id-554' name='domain' filepath='Objects/obmalloc.c' line='260' column='1'/> - <parameter type-id='type-id-563' name='old_alloc' filepath='Objects/obmalloc.c' line='261' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-type size-in-bits='64' id='type-id-562'> - <parameter type-id='type-id-18'/> - <parameter type-id='type-id-18'/> - <return type-id='type-id-70'/> - </function-type> - <function-type size-in-bits='64' id='type-id-551'> - <parameter type-id='type-id-18'/> - <parameter type-id='type-id-18'/> - <parameter type-id='type-id-54'/> - <return type-id='type-id-70'/> - </function-type> - <function-type size-in-bits='64' id='type-id-550'> - <parameter type-id='type-id-18'/> - <parameter type-id='type-id-54'/> - <return type-id='type-id-18'/> - </function-type> - <function-type size-in-bits='64' id='type-id-560'> - <parameter type-id='type-id-18'/> - <parameter type-id='type-id-54'/> - <parameter type-id='type-id-54'/> - <return type-id='type-id-18'/> - </function-type> - <function-type size-in-bits='64' id='type-id-561'> - <parameter type-id='type-id-18'/> - <parameter type-id='type-id-18'/> - <parameter type-id='type-id-54'/> - <return type-id='type-id-18'/> - </function-type> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Objects/picklebufobject.c' comp-dir-path='/src' language='LANG_C99'> - <var-decl name='PyPickleBuffer_Type' type-id='type-id-112' mangled-name='PyPickleBuffer_Type' visibility='default' filepath='./Include/cpython/picklebufobject.h' line='13' column='1' elf-symbol-id='PyPickleBuffer_Type'/> - <function-decl name='PyPickleBuffer_Release' mangled-name='PyPickleBuffer_Release' filepath='Objects/picklebufobject.c' line='55' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyPickleBuffer_Release'> - <parameter type-id='type-id-14' name='obj' filepath='Objects/abstract.c' line='2845' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyPickleBuffer_GetBuffer' mangled-name='PyPickleBuffer_GetBuffer' filepath='Objects/picklebufobject.c' line='36' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyPickleBuffer_GetBuffer'> - <parameter type-id='type-id-14' name='obj' filepath='Objects/picklebufobject.c' line='36' column='1'/> - <return type-id='type-id-479'/> - </function-decl> - <function-decl name='PyPickleBuffer_FromObject' mangled-name='PyPickleBuffer_FromObject' filepath='Objects/picklebufobject.c' line='17' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyPickleBuffer_FromObject'> - <parameter type-id='type-id-14' name='v' filepath='Objects/abstract.c' line='2122' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Objects/rangeobject.c' comp-dir-path='/src' language='LANG_C99'> - <var-decl name='PyRange_Type' type-id='type-id-112' mangled-name='PyRange_Type' visibility='default' filepath='./Include/rangeobject.h' line='18' column='1' elf-symbol-id='PyRange_Type'/> - <var-decl name='PyRangeIter_Type' type-id='type-id-112' mangled-name='PyRangeIter_Type' visibility='default' filepath='./Include/rangeobject.h' line='19' column='1' elf-symbol-id='PyRangeIter_Type'/> - <var-decl name='PyLongRangeIter_Type' type-id='type-id-112' mangled-name='PyLongRangeIter_Type' visibility='default' filepath='./Include/rangeobject.h' line='20' column='1' elf-symbol-id='PyLongRangeIter_Type'/> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Objects/setobject.c' comp-dir-path='/src' language='LANG_C99'> - <var-decl name='PySetIter_Type' type-id='type-id-112' mangled-name='PySetIter_Type' visibility='default' filepath='./Include/setobject.h' line='11' column='1' elf-symbol-id='PySetIter_Type'/> - <var-decl name='PySet_Type' type-id='type-id-112' mangled-name='PySet_Type' visibility='default' filepath='./Include/setobject.h' line='9' column='1' elf-symbol-id='PySet_Type'/> - <var-decl name='PyFrozenSet_Type' type-id='type-id-112' mangled-name='PyFrozenSet_Type' visibility='default' filepath='./Include/setobject.h' line='10' column='1' elf-symbol-id='PyFrozenSet_Type'/> - <var-decl name='_PySet_Dummy' type-id='type-id-14' mangled-name='_PySet_Dummy' visibility='default' filepath='./Include/cpython/setobject.h' line='64' column='1' elf-symbol-id='_PySet_Dummy'/> - <function-decl name='_PySet_Update' mangled-name='_PySet_Update' filepath='Objects/setobject.c' line='2367' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PySet_Update'> - <parameter type-id='type-id-14' name='derived' filepath='Objects/abstract.c' line='2784' column='1'/> - <parameter type-id='type-id-14' name='cls' filepath='Objects/abstract.c' line='2784' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PySet_Pop' mangled-name='PySet_Pop' filepath='Objects/setobject.c' line='2357' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySet_Pop'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2462' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PySet_NextEntry' mangled-name='_PySet_NextEntry' filepath='Objects/setobject.c' line='2341' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PySet_NextEntry'> - <parameter type-id='type-id-14' name='set' filepath='Objects/setobject.c' line='2341' column='1'/> - <parameter type-id='type-id-168' name='pos' filepath='Objects/setobject.c' line='2341' column='1'/> - <parameter type-id='type-id-22' name='key' filepath='Objects/setobject.c' line='2341' column='1'/> - <parameter type-id='type-id-529' name='hash' filepath='Objects/setobject.c' line='2341' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PySet_Add' mangled-name='PySet_Add' filepath='Objects/setobject.c' line='2330' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySet_Add'> - <parameter type-id='type-id-14' name='derived' filepath='Objects/abstract.c' line='2784' column='1'/> - <parameter type-id='type-id-14' name='cls' filepath='Objects/abstract.c' line='2784' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PySet_Discard' mangled-name='PySet_Discard' filepath='Objects/setobject.c' line='2320' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySet_Discard'> - <parameter type-id='type-id-14' name='derived' filepath='Objects/abstract.c' line='2784' column='1'/> - <parameter type-id='type-id-14' name='cls' filepath='Objects/abstract.c' line='2784' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PySet_Contains' mangled-name='PySet_Contains' filepath='Objects/setobject.c' line='2310' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySet_Contains'> - <parameter type-id='type-id-14' name='derived' filepath='Objects/abstract.c' line='2784' column='1'/> - <parameter type-id='type-id-14' name='cls' filepath='Objects/abstract.c' line='2784' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PySet_Clear' mangled-name='PySet_Clear' filepath='Objects/setobject.c' line='2300' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySet_Clear'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2303' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PySet_Size' mangled-name='PySet_Size' filepath='Objects/setobject.c' line='2290' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySet_Size'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2335' column='1'/> - <return type-id='type-id-36'/> - </function-decl> - <function-decl name='PyFrozenSet_New' mangled-name='PyFrozenSet_New' filepath='Objects/setobject.c' line='2284' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFrozenSet_New'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2462' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PySet_New' mangled-name='PySet_New' filepath='Objects/setobject.c' line='2278' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySet_New'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2462' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Objects/sliceobject.c' comp-dir-path='/src' language='LANG_C99'> - <var-decl name='PyEllipsis_Type' type-id='type-id-112' mangled-name='PyEllipsis_Type' visibility='default' filepath='./Include/sliceobject.h' line='29' column='1' elf-symbol-id='PyEllipsis_Type'/> - <var-decl name='_Py_EllipsisObject' type-id='type-id-108' mangled-name='_Py_EllipsisObject' visibility='default' filepath='./Include/sliceobject.h' line='9' column='1' elf-symbol-id='_Py_EllipsisObject'/> - <var-decl name='PySlice_Type' type-id='type-id-112' mangled-name='PySlice_Type' visibility='default' filepath='./Include/sliceobject.h' line='28' column='1' elf-symbol-id='PySlice_Type'/> - <function-decl name='_PySlice_GetLongIndices' mangled-name='_PySlice_GetLongIndices' filepath='Objects/sliceobject.c' line='382' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PySlice_GetLongIndices'> - <parameter type-id='type-id-42' name='self' filepath='Objects/sliceobject.c' line='382' column='1'/> - <parameter type-id='type-id-14' name='length' filepath='Objects/sliceobject.c' line='382' column='1'/> - <parameter type-id='type-id-22' name='start_ptr' filepath='Objects/sliceobject.c' line='383' column='1'/> - <parameter type-id='type-id-22' name='stop_ptr' filepath='Objects/sliceobject.c' line='383' column='1'/> - <parameter type-id='type-id-22' name='step_ptr' filepath='Objects/sliceobject.c' line='384' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PySlice_GetIndicesEx' mangled-name='PySlice_GetIndicesEx' filepath='Objects/sliceobject.c' line='293' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySlice_GetIndicesEx'> - <parameter type-id='type-id-14' name='_r' filepath='Objects/sliceobject.c' line='293' column='1'/> - <parameter type-id='type-id-36' name='length' filepath='Objects/sliceobject.c' line='293' column='1'/> - <parameter type-id='type-id-168' name='start' filepath='Objects/sliceobject.c' line='294' column='1'/> - <parameter type-id='type-id-168' name='stop' filepath='Objects/sliceobject.c' line='294' column='1'/> - <parameter type-id='type-id-168' name='step' filepath='Objects/sliceobject.c' line='294' column='1'/> - <parameter type-id='type-id-168' name='slicelength' filepath='Objects/sliceobject.c' line='295' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PySlice_AdjustIndices' mangled-name='PySlice_AdjustIndices' filepath='Objects/sliceobject.c' line='249' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySlice_AdjustIndices'> - <parameter type-id='type-id-36' name='length' filepath='Objects/sliceobject.c' line='249' column='1'/> - <parameter type-id='type-id-168' name='start' filepath='Objects/sliceobject.c' line='250' column='1'/> - <parameter type-id='type-id-168' name='stop' filepath='Objects/sliceobject.c' line='250' column='1'/> - <parameter type-id='type-id-36' name='step' filepath='Objects/sliceobject.c' line='250' column='1'/> - <return type-id='type-id-36'/> - </function-decl> - <function-decl name='PySlice_Unpack' mangled-name='PySlice_Unpack' filepath='Objects/sliceobject.c' line='203' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySlice_Unpack'> - <parameter type-id='type-id-14' name='_r' filepath='Objects/sliceobject.c' line='203' column='1'/> - <parameter type-id='type-id-168' name='start' filepath='Objects/sliceobject.c' line='204' column='1'/> - <parameter type-id='type-id-168' name='stop' filepath='Objects/sliceobject.c' line='204' column='1'/> - <parameter type-id='type-id-168' name='step' filepath='Objects/sliceobject.c' line='204' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PySlice_GetIndices' mangled-name='PySlice_GetIndices' filepath='Objects/sliceobject.c' line='171' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySlice_GetIndices'> - <parameter type-id='type-id-14' name='_r' filepath='Objects/sliceobject.c' line='171' column='1'/> - <parameter type-id='type-id-36' name='length' filepath='Objects/sliceobject.c' line='171' column='1'/> - <parameter type-id='type-id-168' name='start' filepath='Objects/sliceobject.c' line='172' column='1'/> - <parameter type-id='type-id-168' name='stop' filepath='Objects/sliceobject.c' line='172' column='1'/> - <parameter type-id='type-id-168' name='step' filepath='Objects/sliceobject.c' line='172' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PySlice_FromIndices' mangled-name='_PySlice_FromIndices' filepath='Objects/sliceobject.c' line='152' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PySlice_FromIndices'> - <parameter type-id='type-id-36' name='istart' filepath='Objects/sliceobject.c' line='152' column='1'/> - <parameter type-id='type-id-36' name='istop' filepath='Objects/sliceobject.c' line='152' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PySlice_New' mangled-name='PySlice_New' filepath='Objects/sliceobject.c' line='114' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySlice_New'> - <parameter type-id='type-id-14' name='start' filepath='Objects/sliceobject.c' line='114' column='1'/> - <parameter type-id='type-id-14' name='stop' filepath='Objects/sliceobject.c' line='114' column='1'/> - <parameter type-id='type-id-14' name='step' filepath='Objects/sliceobject.c' line='114' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Objects/structseq.c' comp-dir-path='/src' language='LANG_C99'> - <var-decl name='PyStructSequence_UnnamedField' type-id='type-id-4' mangled-name='PyStructSequence_UnnamedField' visibility='default' filepath='./Include/structseq.h' line='22' column='1' elf-symbol-id='PyStructSequence_UnnamedField'/> - <class-decl name='PyStructSequence_Desc' size-in-bits='256' is-struct='yes' visibility='default' filepath='./Include/structseq.h' line='15' column='1' id='type-id-567'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='name' type-id='type-id-3' visibility='default' filepath='./Include/structseq.h' line='16' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='doc' type-id='type-id-3' visibility='default' filepath='./Include/structseq.h' line='17' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='fields' type-id='type-id-568' visibility='default' filepath='./Include/structseq.h' line='18' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='n_in_sequence' type-id='type-id-8' visibility='default' filepath='./Include/structseq.h' line='19' column='1'/> - </data-member> - </class-decl> - <class-decl name='PyStructSequence_Field' size-in-bits='128' is-struct='yes' visibility='default' filepath='./Include/structseq.h' line='10' column='1' id='type-id-569'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='name' type-id='type-id-3' visibility='default' filepath='./Include/structseq.h' line='11' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='doc' type-id='type-id-3' visibility='default' filepath='./Include/structseq.h' line='12' column='1'/> - </data-member> - </class-decl> - <typedef-decl name='PyStructSequence_Field' type-id='type-id-569' filepath='./Include/structseq.h' line='13' column='1' id='type-id-570'/> - <pointer-type-def type-id='type-id-570' size-in-bits='64' id='type-id-568'/> - <typedef-decl name='PyStructSequence_Desc' type-id='type-id-567' filepath='./Include/structseq.h' line='20' column='1' id='type-id-571'/> - <pointer-type-def type-id='type-id-571' size-in-bits='64' id='type-id-572'/> - <function-decl name='PyStructSequence_NewType' mangled-name='PyStructSequence_NewType' filepath='Objects/structseq.c' line='616' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyStructSequence_NewType'> - <parameter type-id='type-id-572' name='desc' filepath='Objects/structseq.c' line='616' column='1'/> - <return type-id='type-id-74'/> - </function-decl> - <function-decl name='_PyStructSequence_NewType' mangled-name='_PyStructSequence_NewType' filepath='Objects/structseq.c' line='563' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyStructSequence_NewType'> - <parameter type-id='type-id-572' name='desc' filepath='Objects/structseq.c' line='563' column='1'/> - <parameter type-id='type-id-16' name='tp_flags' filepath='Objects/structseq.c' line='563' column='1'/> - <return type-id='type-id-74'/> - </function-decl> - <function-decl name='PyStructSequence_InitType' mangled-name='PyStructSequence_InitType' filepath='Objects/structseq.c' line='524' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyStructSequence_InitType'> - <parameter type-id='type-id-74' name='type' filepath='Objects/structseq.c' line='524' column='1'/> - <parameter type-id='type-id-572' name='desc' filepath='Objects/structseq.c' line='524' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyStructSequence_InitType2' mangled-name='PyStructSequence_InitType2' filepath='Objects/structseq.c' line='518' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyStructSequence_InitType2'> - <parameter type-id='type-id-74' name='type' filepath='Objects/structseq.c' line='518' column='1'/> - <parameter type-id='type-id-572' name='desc' filepath='Objects/structseq.c' line='518' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyStructSequence_InitType' mangled-name='_PyStructSequence_InitType' filepath='Objects/structseq.c' line='460' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyStructSequence_InitType'> - <parameter type-id='type-id-74' name='type' filepath='Objects/structseq.c' line='460' column='1'/> - <parameter type-id='type-id-572' name='desc' filepath='Objects/structseq.c' line='460' column='1'/> - <parameter type-id='type-id-16' name='tp_flags' filepath='Objects/structseq.c' line='461' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyStructSequence_GetItem' mangled-name='PyStructSequence_GetItem' filepath='Objects/structseq.c' line='82' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyStructSequence_GetItem'> - <parameter type-id='type-id-14' name='op' filepath='Objects/listobject.c' line='237' column='1'/> - <parameter type-id='type-id-36' name='i' filepath='Objects/listobject.c' line='237' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyStructSequence_SetItem' mangled-name='PyStructSequence_SetItem' filepath='Objects/structseq.c' line='76' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyStructSequence_SetItem'> - <parameter type-id='type-id-14' name='op' filepath='Objects/structseq.c' line='76' column='1'/> - <parameter type-id='type-id-36' name='i' filepath='Objects/structseq.c' line='76' column='1'/> - <parameter type-id='type-id-14' name='v' filepath='Objects/structseq.c' line='76' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyStructSequence_New' mangled-name='PyStructSequence_New' filepath='Objects/structseq.c' line='51' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyStructSequence_New'> - <parameter type-id='type-id-74' name='type' filepath='Objects/structseq.c' line='51' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Objects/tupleobject.c' comp-dir-path='/src' language='LANG_C99'> - <var-decl name='PyTuple_Type' type-id='type-id-112' mangled-name='PyTuple_Type' visibility='default' filepath='./Include/tupleobject.h' line='23' column='1' elf-symbol-id='PyTuple_Type'/> - <var-decl name='PyTupleIter_Type' type-id='type-id-112' mangled-name='PyTupleIter_Type' visibility='default' filepath='./Include/tupleobject.h' line='24' column='1' elf-symbol-id='PyTupleIter_Type'/> - <function-decl name='_PyTuple_DebugMallocStats' mangled-name='_PyTuple_DebugMallocStats' filepath='Objects/tupleobject.c' line='1254' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTuple_DebugMallocStats'> - <parameter type-id='type-id-473' name='out' filepath='Objects/tupleobject.c' line='1254' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_PyTuple_Resize' mangled-name='_PyTuple_Resize' filepath='Objects/tupleobject.c' line='915' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTuple_Resize'> - <parameter type-id='type-id-22' name='pv' filepath='Objects/tupleobject.c' line='915' column='1'/> - <parameter type-id='type-id-36' name='newsize' filepath='Objects/tupleobject.c' line='915' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyTuple_GetSlice' mangled-name='PyTuple_GetSlice' filepath='Objects/tupleobject.c' line='435' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyTuple_GetSlice'> - <parameter type-id='type-id-14' name='a' filepath='Objects/listobject.c' line='488' column='1'/> - <parameter type-id='type-id-36' name='ilow' filepath='Objects/listobject.c' line='488' column='1'/> - <parameter type-id='type-id-36' name='ihigh' filepath='Objects/listobject.c' line='488' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyTuple_Pack' mangled-name='PyTuple_Pack' filepath='Objects/tupleobject.c' line='154' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyTuple_Pack'> - <parameter type-id='type-id-36' name='n' filepath='Objects/tupleobject.c' line='154' column='1'/> - <parameter is-variadic='yes'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyTuple_MaybeUntrack' mangled-name='_PyTuple_MaybeUntrack' filepath='Objects/tupleobject.c' line='132' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTuple_MaybeUntrack'> - <parameter type-id='type-id-14' name='op' filepath='Objects/tupleobject.c' line='132' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyTuple_SetItem' mangled-name='PyTuple_SetItem' filepath='Objects/tupleobject.c' line='112' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyTuple_SetItem'> - <parameter type-id='type-id-14' name='s' filepath='Objects/abstract.c' line='1926' column='1'/> - <parameter type-id='type-id-36' name='i' filepath='Objects/abstract.c' line='1926' column='1'/> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='1926' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyTuple_GetItem' mangled-name='PyTuple_GetItem' filepath='Objects/tupleobject.c' line='98' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyTuple_GetItem'> - <parameter type-id='type-id-14' name='op' filepath='Objects/listobject.c' line='237' column='1'/> - <parameter type-id='type-id-36' name='i' filepath='Objects/listobject.c' line='237' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyTuple_Size' mangled-name='PyTuple_Size' filepath='Objects/tupleobject.c' line='87' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyTuple_Size'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2335' column='1'/> - <return type-id='type-id-36'/> - </function-decl> - <function-decl name='PyTuple_New' mangled-name='PyTuple_New' filepath='Objects/tupleobject.c' line='69' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyTuple_New'> - <parameter type-id='type-id-36' name='size' filepath='Objects/tupleobject.c' line='69' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Objects/typeobject.c' comp-dir-path='/src' language='LANG_C99'> - <var-decl name='PyType_Type' type-id='type-id-112' mangled-name='PyType_Type' visibility='default' filepath='./Include/object.h' line='269' column='1' elf-symbol-id='PyType_Type'/> - <var-decl name='PyBaseObject_Type' type-id='type-id-112' mangled-name='PyBaseObject_Type' visibility='default' filepath='./Include/object.h' line='270' column='1' elf-symbol-id='PyBaseObject_Type'/> - <var-decl name='PySuper_Type' type-id='type-id-112' mangled-name='PySuper_Type' visibility='default' filepath='./Include/object.h' line='271' column='1' elf-symbol-id='PySuper_Type'/> - <function-decl name='PyType_Ready' mangled-name='PyType_Ready' filepath='Objects/typeobject.c' line='6467' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyType_Ready'> - <parameter type-id='type-id-74' name='type' filepath='Objects/typeobject.c' line='6467' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyObject_GetState' mangled-name='_PyObject_GetState' filepath='Objects/typeobject.c' line='5108' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_GetState'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2462' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyType_LookupId' mangled-name='_PyType_LookupId' filepath='Objects/typeobject.c' line='3868' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyType_LookupId'> - <parameter type-id='type-id-74' name='type' filepath='Objects/typeobject.c' line='3868' column='1'/> - <parameter type-id='type-id-499' name='name' filepath='Objects/typeobject.c' line='3868' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyType_Lookup' mangled-name='_PyType_Lookup' filepath='Objects/typeobject.c' line='3810' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyType_Lookup'> - <parameter type-id='type-id-74' name='type' filepath='Objects/typeobject.c' line='3810' column='1'/> - <parameter type-id='type-id-14' name='name' filepath='Objects/typeobject.c' line='3810' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyType_GetModuleByDef' mangled-name='PyType_GetModuleByDef' filepath='Objects/typeobject.c' line='3715' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyType_GetModuleByDef'> - <parameter type-id='type-id-74' name='type' filepath='Objects/typeobject.c' line='3715' column='1'/> - <parameter type-id='type-id-539' name='def' filepath='Objects/typeobject.c' line='3715' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyType_GetModuleState' mangled-name='PyType_GetModuleState' filepath='Objects/typeobject.c' line='3701' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyType_GetModuleState'> - <parameter type-id='type-id-74' name='type' filepath='Objects/typeobject.c' line='3701' column='1'/> - <return type-id='type-id-18'/> - </function-decl> - <function-decl name='PyType_GetModule' mangled-name='PyType_GetModule' filepath='Objects/typeobject.c' line='3677' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyType_GetModule'> - <parameter type-id='type-id-74' name='tp' filepath='Objects/object.c' line='174' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyType_GetSlot' mangled-name='PyType_GetSlot' filepath='Objects/typeobject.c' line='3655' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyType_GetSlot'> - <parameter type-id='type-id-74' name='type' filepath='Objects/typeobject.c' line='3655' column='1'/> - <parameter type-id='type-id-8' name='slot' filepath='Objects/typeobject.c' line='3655' column='1'/> - <return type-id='type-id-18'/> - </function-decl> - <function-decl name='PyType_GetQualName' mangled-name='PyType_GetQualName' filepath='Objects/typeobject.c' line='3649' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyType_GetQualName'> - <parameter type-id='type-id-74' name='type' filepath='Objects/typeobject.c' line='3649' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyType_GetName' mangled-name='PyType_GetName' filepath='Objects/typeobject.c' line='3643' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyType_GetName'> - <parameter type-id='type-id-74' name='type' filepath='Objects/typeobject.c' line='3649' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <class-decl name='__anonymous_struct__' size-in-bits='256' is-struct='yes' is-anonymous='yes' naming-typedef-id='type-id-573' visibility='default' filepath='./Include/object.h' line='234' column='1' id='type-id-574'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='name' type-id='type-id-3' visibility='default' filepath='./Include/object.h' line='235' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='basicsize' type-id='type-id-8' visibility='default' filepath='./Include/object.h' line='236' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='96'> - <var-decl name='itemsize' type-id='type-id-8' visibility='default' filepath='./Include/object.h' line='237' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='flags' type-id='type-id-105' visibility='default' filepath='./Include/object.h' line='238' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='slots' type-id='type-id-575' visibility='default' filepath='./Include/object.h' line='239' column='1'/> - </data-member> - </class-decl> - <class-decl name='__anonymous_struct__' size-in-bits='128' is-struct='yes' is-anonymous='yes' naming-typedef-id='type-id-576' visibility='default' filepath='./Include/object.h' line='229' column='1' id='type-id-577'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='slot' type-id='type-id-8' visibility='default' filepath='./Include/object.h' line='230' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='pfunc' type-id='type-id-18' visibility='default' filepath='./Include/object.h' line='231' column='1'/> - </data-member> - </class-decl> - <typedef-decl name='PyType_Slot' type-id='type-id-577' filepath='./Include/object.h' line='232' column='1' id='type-id-576'/> - <pointer-type-def type-id='type-id-576' size-in-bits='64' id='type-id-575'/> - <typedef-decl name='PyType_Spec' type-id='type-id-574' filepath='./Include/object.h' line='240' column='1' id='type-id-573'/> - <pointer-type-def type-id='type-id-573' size-in-bits='64' id='type-id-578'/> - <function-decl name='PyType_FromSpec' mangled-name='PyType_FromSpec' filepath='Objects/typeobject.c' line='3637' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyType_FromSpec'> - <parameter type-id='type-id-578' name='spec' filepath='Objects/typeobject.c' line='3637' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyType_FromModuleAndSpec' mangled-name='PyType_FromModuleAndSpec' filepath='Objects/typeobject.c' line='3369' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyType_FromModuleAndSpec'> - <parameter type-id='type-id-14' name='module' filepath='Objects/typeobject.c' line='3369' column='1'/> - <parameter type-id='type-id-578' name='spec' filepath='Objects/typeobject.c' line='3369' column='1'/> - <parameter type-id='type-id-14' name='bases' filepath='Objects/typeobject.c' line='3369' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyType_FromSpecWithBases' mangled-name='PyType_FromSpecWithBases' filepath='Objects/typeobject.c' line='3363' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyType_FromSpecWithBases'> - <parameter type-id='type-id-578' name='spec' filepath='Objects/typeobject.c' line='3363' column='1'/> - <parameter type-id='type-id-14' name='bases' filepath='Objects/typeobject.c' line='3363' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyType_CalculateMetaclass' mangled-name='_PyType_CalculateMetaclass' filepath='Objects/typeobject.c' line='2472' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyType_CalculateMetaclass'> - <parameter type-id='type-id-74' name='metatype' filepath='Objects/typeobject.c' line='2472' column='1'/> - <parameter type-id='type-id-14' name='bases' filepath='Objects/typeobject.c' line='2472' column='1'/> - <return type-id='type-id-74'/> - </function-decl> - <function-decl name='PyType_SUPPORTS_WEAKREFS' mangled-name='PyType_SUPPORTS_WEAKREFS' filepath='Objects/typeobject.c' line='2464' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyType_SUPPORTS_WEAKREFS'> - <parameter type-id='type-id-74' name='type' filepath='Objects/typeobject.c' line='6467' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyType_GetFlags' mangled-name='PyType_GetFlags' filepath='Objects/typeobject.c' line='2457' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyType_GetFlags'> - <parameter type-id='type-id-74' name='type' filepath='Objects/typeobject.c' line='2457' column='1'/> - <return type-id='type-id-16'/> - </function-decl> - <function-decl name='_PyObject_LookupSpecialId' mangled-name='_PyObject_LookupSpecialId' filepath='Objects/typeobject.c' line='1594' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_LookupSpecialId'> - <parameter type-id='type-id-14' name='self' filepath='Objects/typeobject.c' line='1594' column='1'/> - <parameter type-id='type-id-499' name='attrid' filepath='Objects/typeobject.c' line='1594' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyObject_LookupSpecial' mangled-name='_PyObject_LookupSpecial' filepath='Objects/typeobject.c' line='1578' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_LookupSpecial'> - <parameter type-id='type-id-14' name='v' filepath='Objects/abstract.c' line='1282' column='1'/> - <parameter type-id='type-id-14' name='w' filepath='Objects/abstract.c' line='1282' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyType_IsSubtype' mangled-name='PyType_IsSubtype' filepath='Objects/typeobject.c' line='1540' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyType_IsSubtype'> - <parameter type-id='type-id-74' name='a' filepath='Objects/typeobject.c' line='1540' column='1'/> - <parameter type-id='type-id-74' name='b' filepath='Objects/typeobject.c' line='1540' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyType_GenericNew' mangled-name='PyType_GenericNew' filepath='Objects/typeobject.c' line='1169' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyType_GenericNew'> - <parameter type-id='type-id-74' name='type' filepath='Objects/typeobject.c' line='1169' column='1'/> - <parameter type-id='type-id-14' name='args' filepath='Objects/typeobject.c' line='1169' column='1'/> - <parameter type-id='type-id-14' name='kwds' filepath='Objects/typeobject.c' line='1169' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyType_GenericAlloc' mangled-name='PyType_GenericAlloc' filepath='Objects/typeobject.c' line='1155' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyType_GenericAlloc'> - <parameter type-id='type-id-74' name='type' filepath='Objects/typeobject.c' line='1155' column='1'/> - <parameter type-id='type-id-36' name='nitems' filepath='Objects/typeobject.c' line='1155' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyType_Name' mangled-name='_PyType_Name' filepath='Objects/typeobject.c' line='450' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyType_Name'> - <parameter type-id='type-id-74' name='type' filepath='Objects/typeobject.c' line='450' column='1'/> - <return type-id='type-id-3'/> - </function-decl> - <function-decl name='PyType_Modified' mangled-name='PyType_Modified' filepath='Objects/typeobject.c' line='284' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyType_Modified'> - <parameter type-id='type-id-74' name='type' filepath='Objects/typeobject.c' line='284' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyType_ClearCache' mangled-name='PyType_ClearCache' filepath='Objects/typeobject.c' line='265' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyType_ClearCache'> - <return type-id='type-id-105'/> - </function-decl> - <function-decl name='_PyType_GetTextSignatureFromInternalDoc' mangled-name='_PyType_GetTextSignatureFromInternalDoc' filepath='Objects/typeobject.c' line='181' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyType_GetTextSignatureFromInternalDoc'> - <parameter type-id='type-id-3' name='name' filepath='Objects/typeobject.c' line='181' column='1'/> - <parameter type-id='type-id-3' name='internal_doc' filepath='Objects/typeobject.c' line='181' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyType_GetDocFromInternalDoc' mangled-name='_PyType_GetDocFromInternalDoc' filepath='Objects/typeobject.c' line='169' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyType_GetDocFromInternalDoc'> - <parameter type-id='type-id-3' name='name' filepath='Objects/typeobject.c' line='169' column='1'/> - <parameter type-id='type-id-3' name='internal_doc' filepath='Objects/typeobject.c' line='169' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyType_CheckConsistency' mangled-name='_PyType_CheckConsistency' filepath='Objects/typeobject.c' line='122' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyType_CheckConsistency'> - <parameter type-id='type-id-74' name='type' filepath='Objects/typeobject.c' line='122' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Objects/unicodeobject.c' comp-dir-path='/src' language='LANG_C99'> - - <array-type-def dimensions='1' type-id='type-id-527' size-in-bits='infinite' id='type-id-579'> - <subrange length='infinite' id='type-id-6'/> - - </array-type-def> - <qualified-type-def type-id='type-id-579' const='yes' id='type-id-580'/> - <var-decl name='_Py_ascii_whitespace' type-id='type-id-580' mangled-name='_Py_ascii_whitespace' visibility='default' filepath='./Include/cpython/unicodeobject.h' line='1029' column='1' elf-symbol-id='_Py_ascii_whitespace'/> - <var-decl name='PyUnicode_Type' type-id='type-id-112' mangled-name='PyUnicode_Type' visibility='default' filepath='./Include/unicodeobject.h' line='111' column='1' elf-symbol-id='PyUnicode_Type'/> - <var-decl name='PyUnicodeIter_Type' type-id='type-id-112' mangled-name='PyUnicodeIter_Type' visibility='default' filepath='./Include/unicodeobject.h' line='112' column='1' elf-symbol-id='PyUnicodeIter_Type'/> - <var-decl name='_PyUnicodeASCIIIter_Type' type-id='type-id-112' visibility='default' filepath='./Include/internal/pycore_unicodeobject.h' line='24' column='1'/> - <function-decl name='PyInit__string' mangled-name='PyInit__string' filepath='Objects/unicodeobject.c' line='16182' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInit__string'> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyUnicode_InternFromString' mangled-name='PyUnicode_InternFromString' filepath='Objects/unicodeobject.c' line='15605' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_InternFromString'> - <parameter type-id='type-id-3' name='cp' filepath='Objects/unicodeobject.c' line='15605' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyUnicode_InternImmortal' mangled-name='PyUnicode_InternImmortal' filepath='Objects/unicodeobject.c' line='15586' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_InternImmortal'> - <parameter type-id='type-id-22' name='p' filepath='Objects/unicodeobject.c' line='15586' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyUnicode_InternInPlace' mangled-name='PyUnicode_InternInPlace' filepath='Objects/unicodeobject.c' line='15531' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_InternInPlace'> - <parameter type-id='type-id-22' name='p' filepath='Objects/unicodeobject.c' line='15531' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyUnicode_Format' mangled-name='PyUnicode_Format' filepath='Objects/unicodeobject.c' line='15187' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_Format'> - <parameter type-id='type-id-14' name='format' filepath='Objects/unicodeobject.c' line='15187' column='1'/> - <parameter type-id='type-id-14' name='args' filepath='Objects/unicodeobject.c' line='15187' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyUnicode_FormatLong' mangled-name='_PyUnicode_FormatLong' filepath='Objects/unicodeobject.c' line='14425' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_FormatLong'> - <parameter type-id='type-id-14' name='val' filepath='Objects/unicodeobject.c' line='14425' column='1'/> - <parameter type-id='type-id-8' name='alt' filepath='Objects/unicodeobject.c' line='14425' column='1'/> - <parameter type-id='type-id-8' name='prec' filepath='Objects/unicodeobject.c' line='14425' column='1'/> - <parameter type-id='type-id-8' name='type' filepath='Objects/unicodeobject.c' line='14425' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyUnicodeWriter_Dealloc' mangled-name='_PyUnicodeWriter_Dealloc' filepath='Objects/unicodeobject.c' line='14066' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicodeWriter_Dealloc'> - <parameter type-id='type-id-525' name='writer' filepath='Objects/unicodeobject.c' line='14066' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_PyUnicodeWriter_Finish' mangled-name='_PyUnicodeWriter_Finish' filepath='Objects/unicodeobject.c' line='14034' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicodeWriter_Finish'> - <parameter type-id='type-id-525' name='writer' filepath='Objects/unicodeobject.c' line='14034' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyUnicodeWriter_WriteLatin1String' mangled-name='_PyUnicodeWriter_WriteLatin1String' filepath='Objects/unicodeobject.c' line='14020' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicodeWriter_WriteLatin1String'> - <parameter type-id='type-id-525' name='writer' filepath='Objects/unicodeobject.c' line='14020' column='1'/> - <parameter type-id='type-id-3' name='str' filepath='Objects/unicodeobject.c' line='14021' column='1'/> - <parameter type-id='type-id-36' name='len' filepath='Objects/unicodeobject.c' line='14021' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyUnicodeWriter_WriteASCIIString' mangled-name='_PyUnicodeWriter_WriteASCIIString' filepath='Objects/unicodeobject.c' line='13960' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicodeWriter_WriteASCIIString'> - <parameter type-id='type-id-525' name='writer' filepath='Objects/unicodeobject.c' line='13960' column='1'/> - <parameter type-id='type-id-3' name='ascii' filepath='Objects/unicodeobject.c' line='13961' column='1'/> - <parameter type-id='type-id-36' name='len' filepath='Objects/unicodeobject.c' line='13961' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyUnicodeWriter_WriteSubstring' mangled-name='_PyUnicodeWriter_WriteSubstring' filepath='Objects/unicodeobject.c' line='13925' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicodeWriter_WriteSubstring'> - <parameter type-id='type-id-525' name='writer' filepath='Objects/unicodeobject.c' line='13925' column='1'/> - <parameter type-id='type-id-14' name='str' filepath='Objects/unicodeobject.c' line='13925' column='1'/> - <parameter type-id='type-id-36' name='start' filepath='Objects/unicodeobject.c' line='13926' column='1'/> - <parameter type-id='type-id-36' name='end' filepath='Objects/unicodeobject.c' line='13926' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyUnicodeWriter_WriteStr' mangled-name='_PyUnicodeWriter_WriteStr' filepath='Objects/unicodeobject.c' line='13894' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicodeWriter_WriteStr'> - <parameter type-id='type-id-525' name='writer' filepath='Objects/unicodeobject.c' line='13894' column='1'/> - <parameter type-id='type-id-14' name='str' filepath='Objects/unicodeobject.c' line='13894' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyUnicodeWriter_WriteChar' mangled-name='_PyUnicodeWriter_WriteChar' filepath='Objects/unicodeobject.c' line='13888' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicodeWriter_WriteChar'> - <parameter type-id='type-id-525' name='writer' filepath='Objects/unicodeobject.c' line='13888' column='1'/> - <parameter type-id='type-id-524' name='ch' filepath='Objects/unicodeobject.c' line='13888' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyUnicodeWriter_PrepareKindInternal' mangled-name='_PyUnicodeWriter_PrepareKindInternal' filepath='Objects/unicodeobject.c' line='13856' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicodeWriter_PrepareKindInternal'> - <parameter type-id='type-id-525' name='writer' filepath='Objects/unicodeobject.c' line='13856' column='1'/> - <parameter type-id='type-id-523' name='kind' filepath='Objects/unicodeobject.c' line='13857' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyUnicodeWriter_PrepareInternal' mangled-name='_PyUnicodeWriter_PrepareInternal' filepath='Objects/unicodeobject.c' line='13779' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicodeWriter_PrepareInternal'> - <parameter type-id='type-id-525' name='writer' filepath='Objects/unicodeobject.c' line='13779' column='1'/> - <parameter type-id='type-id-36' name='length' filepath='Objects/unicodeobject.c' line='13780' column='1'/> - <parameter type-id='type-id-524' name='maxchar' filepath='Objects/unicodeobject.c' line='13780' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyUnicodeWriter_Init' mangled-name='_PyUnicodeWriter_Init' filepath='Objects/unicodeobject.c' line='13755' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicodeWriter_Init'> - <parameter type-id='type-id-525' name='writer' filepath='Objects/unicodeobject.c' line='13755' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyUnicode_RSplit' mangled-name='PyUnicode_RSplit' filepath='Objects/unicodeobject.c' line='13338' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_RSplit'> - <parameter type-id='type-id-14' name='s' filepath='Objects/unicodeobject.c' line='13338' column='1'/> - <parameter type-id='type-id-14' name='sep' filepath='Objects/unicodeobject.c' line='13338' column='1'/> - <parameter type-id='type-id-36' name='maxsplit' filepath='Objects/unicodeobject.c' line='13338' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyUnicode_RPartition' mangled-name='PyUnicode_RPartition' filepath='Objects/unicodeobject.c' line='13244' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_RPartition'> - <parameter type-id='type-id-14' name='str_obj' filepath='Objects/unicodeobject.c' line='13244' column='1'/> - <parameter type-id='type-id-14' name='sep_obj' filepath='Objects/unicodeobject.c' line='13244' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyUnicode_Partition' mangled-name='PyUnicode_Partition' filepath='Objects/unicodeobject.c' line='13192' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_Partition'> - <parameter type-id='type-id-14' name='str_obj' filepath='Objects/unicodeobject.c' line='13244' column='1'/> - <parameter type-id='type-id-14' name='sep_obj' filepath='Objects/unicodeobject.c' line='13244' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyUnicode_Split' mangled-name='PyUnicode_Split' filepath='Objects/unicodeobject.c' line='13147' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_Split'> - <parameter type-id='type-id-14' name='s' filepath='Objects/unicodeobject.c' line='13338' column='1'/> - <parameter type-id='type-id-14' name='sep' filepath='Objects/unicodeobject.c' line='13338' column='1'/> - <parameter type-id='type-id-36' name='maxsplit' filepath='Objects/unicodeobject.c' line='13338' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyUnicode_Replace' mangled-name='PyUnicode_Replace' filepath='Objects/unicodeobject.c' line='12795' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_Replace'> - <parameter type-id='type-id-14' name='str' filepath='Objects/unicodeobject.c' line='12795' column='1'/> - <parameter type-id='type-id-14' name='substr' filepath='Objects/unicodeobject.c' line='12796' column='1'/> - <parameter type-id='type-id-14' name='replstr' filepath='Objects/unicodeobject.c' line='12797' column='1'/> - <parameter type-id='type-id-36' name='maxcount' filepath='Objects/unicodeobject.c' line='12798' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyUnicode_Substring' mangled-name='PyUnicode_Substring' filepath='Objects/unicodeobject.c' line='12560' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_Substring'> - <parameter type-id='type-id-14' name='self' filepath='Objects/unicodeobject.c' line='12560' column='1'/> - <parameter type-id='type-id-36' name='start' filepath='Objects/unicodeobject.c' line='12560' column='1'/> - <parameter type-id='type-id-36' name='end' filepath='Objects/unicodeobject.c' line='12560' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyUnicode_XStrip' mangled-name='_PyUnicode_XStrip' filepath='Objects/unicodeobject.c' line='12510' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_XStrip'> - <parameter type-id='type-id-14' name='self' filepath='Objects/unicodeobject.c' line='12510' column='1'/> - <parameter type-id='type-id-8' name='striptype' filepath='Objects/unicodeobject.c' line='12510' column='1'/> - <parameter type-id='type-id-14' name='sepobj' filepath='Objects/unicodeobject.c' line='12510' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyUnicode_IsIdentifier' mangled-name='PyUnicode_IsIdentifier' filepath='Objects/unicodeobject.c' line='12324' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_IsIdentifier'> - <parameter type-id='type-id-14' name='self' filepath='Objects/unicodeobject.c' line='12324' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyUnicode_ScanIdentifier' mangled-name='_PyUnicode_ScanIdentifier' filepath='Objects/unicodeobject.c' line='12287' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_ScanIdentifier'> - <parameter type-id='type-id-14' name='self' filepath='Objects/unicodeobject.c' line='12287' column='1'/> - <return type-id='type-id-36'/> - </function-decl> - <function-decl name='PyUnicode_AppendAndDel' mangled-name='PyUnicode_AppendAndDel' filepath='Objects/unicodeobject.c' line='11559' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_AppendAndDel'> - <parameter type-id='type-id-22' name='pv' filepath='Objects/bytesobject.c' line='3033' column='1'/> - <parameter type-id='type-id-14' name='w' filepath='Objects/bytesobject.c' line='3033' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyUnicode_Append' mangled-name='PyUnicode_Append' filepath='Objects/unicodeobject.c' line='11476' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_Append'> - <parameter type-id='type-id-22' name='p_left' filepath='Objects/unicodeobject.c' line='11476' column='1'/> - <parameter type-id='type-id-14' name='right' filepath='Objects/unicodeobject.c' line='11476' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyUnicode_Concat' mangled-name='PyUnicode_Concat' filepath='Objects/unicodeobject.c' line='11425' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_Concat'> - <parameter type-id='type-id-14' name='left' filepath='Objects/unicodeobject.c' line='11425' column='1'/> - <parameter type-id='type-id-14' name='right' filepath='Objects/unicodeobject.c' line='11425' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyUnicode_Contains' mangled-name='PyUnicode_Contains' filepath='Objects/unicodeobject.c' line='11362' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_Contains'> - <parameter type-id='type-id-14' name='str' filepath='Objects/unicodeobject.c' line='11362' column='1'/> - <parameter type-id='type-id-14' name='substr' filepath='Objects/unicodeobject.c' line='11362' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyUnicode_EQ' mangled-name='_PyUnicode_EQ' filepath='Objects/unicodeobject.c' line='11356' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_EQ'> - <parameter type-id='type-id-14' name='derived' filepath='Objects/abstract.c' line='2784' column='1'/> - <parameter type-id='type-id-14' name='cls' filepath='Objects/abstract.c' line='2784' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyUnicode_RichCompare' mangled-name='PyUnicode_RichCompare' filepath='Objects/unicodeobject.c' line='11317' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_RichCompare'> - <parameter type-id='type-id-14' name='left' filepath='Objects/unicodeobject.c' line='11317' column='1'/> - <parameter type-id='type-id-14' name='right' filepath='Objects/unicodeobject.c' line='11317' column='1'/> - <parameter type-id='type-id-8' name='op' filepath='Objects/unicodeobject.c' line='11317' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyUnicode_EqualToASCIIId' mangled-name='_PyUnicode_EqualToASCIIId' filepath='Objects/unicodeobject.c' line='11273' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_EqualToASCIIId'> - <parameter type-id='type-id-14' name='left' filepath='Objects/unicodeobject.c' line='11273' column='1'/> - <parameter type-id='type-id-499' name='right' filepath='Objects/unicodeobject.c' line='11273' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyUnicode_EqualToASCIIString' mangled-name='_PyUnicode_EqualToASCIIString' filepath='Objects/unicodeobject.c' line='11250' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_EqualToASCIIString'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2378' column='1'/> - <parameter type-id='type-id-3' name='key' filepath='Objects/abstract.c' line='2378' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyUnicode_CompareWithASCIIString' mangled-name='PyUnicode_CompareWithASCIIString' filepath='Objects/unicodeobject.c' line='11171' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_CompareWithASCIIString'> - <parameter type-id='type-id-14' name='uni' filepath='Objects/unicodeobject.c' line='11171' column='1'/> - <parameter type-id='type-id-3' name='str' filepath='Objects/unicodeobject.c' line='11171' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyUnicode_Compare' mangled-name='PyUnicode_Compare' filepath='Objects/unicodeobject.c' line='11150' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_Compare'> - <parameter type-id='type-id-14' name='derived' filepath='Objects/abstract.c' line='2784' column='1'/> - <parameter type-id='type-id-14' name='cls' filepath='Objects/abstract.c' line='2784' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyUnicode_Equal' mangled-name='_PyUnicode_Equal' filepath='Objects/unicodeobject.c' line='11135' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_Equal'> - <parameter type-id='type-id-14' name='derived' filepath='Objects/abstract.c' line='2784' column='1'/> - <parameter type-id='type-id-14' name='cls' filepath='Objects/abstract.c' line='2784' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyUnicode_Splitlines' mangled-name='PyUnicode_Splitlines' filepath='Objects/unicodeobject.c' line='10325' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_Splitlines'> - <parameter type-id='type-id-14' name='string' filepath='Objects/unicodeobject.c' line='10325' column='1'/> - <parameter type-id='type-id-8' name='keepends' filepath='Objects/unicodeobject.c' line='10325' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyUnicode_Fill' mangled-name='PyUnicode_Fill' filepath='Objects/unicodeobject.c' line='10249' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_Fill'> - <parameter type-id='type-id-14' name='unicode' filepath='Objects/unicodeobject.c' line='10249' column='1'/> - <parameter type-id='type-id-36' name='start' filepath='Objects/unicodeobject.c' line='10249' column='1'/> - <parameter type-id='type-id-36' name='length' filepath='Objects/unicodeobject.c' line='10249' column='1'/> - <parameter type-id='type-id-524' name='fill_char' filepath='Objects/unicodeobject.c' line='10250' column='1'/> - <return type-id='type-id-36'/> - </function-decl> - <function-decl name='_PyUnicode_FastFill' mangled-name='_PyUnicode_FastFill' filepath='Objects/unicodeobject.c' line='10235' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_FastFill'> - <parameter type-id='type-id-14' name='unicode' filepath='Objects/unicodeobject.c' line='10235' column='1'/> - <parameter type-id='type-id-36' name='start' filepath='Objects/unicodeobject.c' line='10235' column='1'/> - <parameter type-id='type-id-36' name='length' filepath='Objects/unicodeobject.c' line='10235' column='1'/> - <parameter type-id='type-id-524' name='fill_char' filepath='Objects/unicodeobject.c' line='10236' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_PyUnicode_JoinArray' mangled-name='_PyUnicode_JoinArray' filepath='Objects/unicodeobject.c' line='10063' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_JoinArray'> - <parameter type-id='type-id-14' name='separator' filepath='Objects/unicodeobject.c' line='10063' column='1'/> - <parameter type-id='type-id-200' name='items' filepath='Objects/unicodeobject.c' line='10063' column='1'/> - <parameter type-id='type-id-36' name='seqlen' filepath='Objects/unicodeobject.c' line='10063' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyUnicode_Join' mangled-name='PyUnicode_Join' filepath='Objects/unicodeobject.c' line='10039' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_Join'> - <parameter type-id='type-id-14' name='func' filepath='Objects/call.c' line='368' column='1'/> - <parameter type-id='type-id-14' name='arg' filepath='Objects/call.c' line='368' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyUnicode_Tailmatch' mangled-name='PyUnicode_Tailmatch' filepath='Objects/unicodeobject.c' line='9792' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_Tailmatch'> - <parameter type-id='type-id-14' name='str' filepath='Objects/unicodeobject.c' line='9792' column='1'/> - <parameter type-id='type-id-14' name='substr' filepath='Objects/unicodeobject.c' line='9793' column='1'/> - <parameter type-id='type-id-36' name='start' filepath='Objects/unicodeobject.c' line='9794' column='1'/> - <parameter type-id='type-id-36' name='end' filepath='Objects/unicodeobject.c' line='9795' column='1'/> - <parameter type-id='type-id-8' name='direction' filepath='Objects/unicodeobject.c' line='9796' column='1'/> - <return type-id='type-id-36'/> - </function-decl> - <function-decl name='PyUnicode_FindChar' mangled-name='PyUnicode_FindChar' filepath='Objects/unicodeobject.c' line='9703' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_FindChar'> - <parameter type-id='type-id-14' name='str' filepath='Objects/unicodeobject.c' line='9703' column='1'/> - <parameter type-id='type-id-524' name='ch' filepath='Objects/unicodeobject.c' line='9703' column='1'/> - <parameter type-id='type-id-36' name='start' filepath='Objects/unicodeobject.c' line='9704' column='1'/> - <parameter type-id='type-id-36' name='end' filepath='Objects/unicodeobject.c' line='9704' column='1'/> - <parameter type-id='type-id-8' name='direction' filepath='Objects/unicodeobject.c' line='9705' column='1'/> - <return type-id='type-id-36'/> - </function-decl> - <function-decl name='PyUnicode_Find' mangled-name='PyUnicode_Find' filepath='Objects/unicodeobject.c' line='9690' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_Find'> - <parameter type-id='type-id-14' name='str' filepath='Objects/unicodeobject.c' line='9792' column='1'/> - <parameter type-id='type-id-14' name='substr' filepath='Objects/unicodeobject.c' line='9793' column='1'/> - <parameter type-id='type-id-36' name='start' filepath='Objects/unicodeobject.c' line='9794' column='1'/> - <parameter type-id='type-id-36' name='end' filepath='Objects/unicodeobject.c' line='9795' column='1'/> - <parameter type-id='type-id-8' name='direction' filepath='Objects/unicodeobject.c' line='9796' column='1'/> - <return type-id='type-id-36'/> - </function-decl> - <function-decl name='PyUnicode_Count' mangled-name='PyUnicode_Count' filepath='Objects/unicodeobject.c' line='9616' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_Count'> - <parameter type-id='type-id-14' name='str' filepath='Objects/unicodeobject.c' line='9616' column='1'/> - <parameter type-id='type-id-14' name='substr' filepath='Objects/unicodeobject.c' line='9617' column='1'/> - <parameter type-id='type-id-36' name='start' filepath='Objects/unicodeobject.c' line='9618' column='1'/> - <parameter type-id='type-id-36' name='end' filepath='Objects/unicodeobject.c' line='9619' column='1'/> - <return type-id='type-id-36'/> - </function-decl> - <pointer-type-def type-id='type-id-524' size-in-bits='64' id='type-id-581'/> - <function-decl name='_PyUnicode_InsertThousandsGrouping' mangled-name='_PyUnicode_InsertThousandsGrouping' filepath='Objects/unicodeobject.c' line='9496' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_InsertThousandsGrouping'> - <parameter type-id='type-id-525' name='writer' filepath='Objects/unicodeobject.c' line='9497' column='1'/> - <parameter type-id='type-id-36' name='n_buffer' filepath='Objects/unicodeobject.c' line='9498' column='1'/> - <parameter type-id='type-id-14' name='digits' filepath='Objects/unicodeobject.c' line='9499' column='1'/> - <parameter type-id='type-id-36' name='d_pos' filepath='Objects/unicodeobject.c' line='9500' column='1'/> - <parameter type-id='type-id-36' name='n_digits' filepath='Objects/unicodeobject.c' line='9501' column='1'/> - <parameter type-id='type-id-36' name='min_width' filepath='Objects/unicodeobject.c' line='9502' column='1'/> - <parameter type-id='type-id-3' name='grouping' filepath='Objects/unicodeobject.c' line='9503' column='1'/> - <parameter type-id='type-id-14' name='thousands_sep' filepath='Objects/unicodeobject.c' line='9504' column='1'/> - <parameter type-id='type-id-581' name='maxchar' filepath='Objects/unicodeobject.c' line='9505' column='1'/> - <return type-id='type-id-36'/> - </function-decl> - <function-decl name='_PyUnicode_TransformDecimalAndSpaceToASCII' mangled-name='_PyUnicode_TransformDecimalAndSpaceToASCII' filepath='Objects/unicodeobject.c' line='9321' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_TransformDecimalAndSpaceToASCII'> - <parameter type-id='type-id-14' name='unicode' filepath='Objects/unicodeobject.c' line='9321' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyUnicode_Translate' mangled-name='PyUnicode_Translate' filepath='Objects/unicodeobject.c' line='9311' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_Translate'> - <parameter type-id='type-id-14' name='str' filepath='Objects/unicodeobject.c' line='9311' column='1'/> - <parameter type-id='type-id-14' name='mapping' filepath='Objects/unicodeobject.c' line='9312' column='1'/> - <parameter type-id='type-id-3' name='errors' filepath='Objects/unicodeobject.c' line='9313' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyUnicode_AsCharmapString' mangled-name='PyUnicode_AsCharmapString' filepath='Objects/unicodeobject.c' line='8887' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_AsCharmapString'> - <parameter type-id='type-id-14' name='v' filepath='Objects/abstract.c' line='1256' column='1'/> - <parameter type-id='type-id-14' name='w' filepath='Objects/abstract.c' line='1256' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyUnicode_EncodeCharmap' mangled-name='_PyUnicode_EncodeCharmap' filepath='Objects/unicodeobject.c' line='8816' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_EncodeCharmap'> - <parameter type-id='type-id-14' name='unicode' filepath='Objects/unicodeobject.c' line='8816' column='1'/> - <parameter type-id='type-id-14' name='mapping' filepath='Objects/unicodeobject.c' line='8817' column='1'/> - <parameter type-id='type-id-3' name='errors' filepath='Objects/unicodeobject.c' line='8818' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyUnicode_BuildEncodingMap' mangled-name='PyUnicode_BuildEncodingMap' filepath='Objects/unicodeobject.c' line='8403' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_BuildEncodingMap'> - <parameter type-id='type-id-14' name='string' filepath='Objects/unicodeobject.c' line='8403' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyUnicode_DecodeCharmap' mangled-name='PyUnicode_DecodeCharmap' filepath='Objects/unicodeobject.c' line='8327' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_DecodeCharmap'> - <parameter type-id='type-id-3' name='s' filepath='Objects/unicodeobject.c' line='8327' column='1'/> - <parameter type-id='type-id-36' name='size' filepath='Objects/unicodeobject.c' line='8328' column='1'/> - <parameter type-id='type-id-14' name='mapping' filepath='Objects/unicodeobject.c' line='8329' column='1'/> - <parameter type-id='type-id-3' name='errors' filepath='Objects/unicodeobject.c' line='8330' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyUnicode_AsASCIIString' mangled-name='PyUnicode_AsASCIIString' filepath='Objects/unicodeobject.c' line='7373' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_AsASCIIString'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2462' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyUnicode_AsASCIIString' mangled-name='_PyUnicode_AsASCIIString' filepath='Objects/unicodeobject.c' line='7356' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_AsASCIIString'> - <parameter type-id='type-id-14' name='unicode' filepath='Objects/unicodeobject.c' line='7356' column='1'/> - <parameter type-id='type-id-3' name='errors' filepath='Objects/unicodeobject.c' line='7356' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyUnicode_DecodeASCII' mangled-name='PyUnicode_DecodeASCII' filepath='Objects/unicodeobject.c' line='7257' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_DecodeASCII'> - <parameter type-id='type-id-3' name='s' filepath='Objects/unicodeobject.c' line='7257' column='1'/> - <parameter type-id='type-id-36' name='size' filepath='Objects/unicodeobject.c' line='7258' column='1'/> - <parameter type-id='type-id-3' name='errors' filepath='Objects/unicodeobject.c' line='7259' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyUnicode_AsLatin1String' mangled-name='PyUnicode_AsLatin1String' filepath='Objects/unicodeobject.c' line='7249' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_AsLatin1String'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2462' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyUnicode_AsLatin1String' mangled-name='_PyUnicode_AsLatin1String' filepath='Objects/unicodeobject.c' line='7230' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_AsLatin1String'> - <parameter type-id='type-id-14' name='unicode' filepath='Objects/unicodeobject.c' line='7356' column='1'/> - <parameter type-id='type-id-3' name='errors' filepath='Objects/unicodeobject.c' line='7356' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyUnicode_DecodeLatin1' mangled-name='PyUnicode_DecodeLatin1' filepath='Objects/unicodeobject.c' line='6937' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_DecodeLatin1'> - <parameter type-id='type-id-3' name='s' filepath='Objects/unicodeobject.c' line='6937' column='1'/> - <parameter type-id='type-id-36' name='size' filepath='Objects/unicodeobject.c' line='6938' column='1'/> - <parameter type-id='type-id-3' name='errors' filepath='Objects/unicodeobject.c' line='6939' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyUnicode_AsRawUnicodeEscapeString' mangled-name='PyUnicode_AsRawUnicodeEscapeString' filepath='Objects/unicodeobject.c' line='6856' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_AsRawUnicodeEscapeString'> - <parameter type-id='type-id-14' name='unicode' filepath='Objects/unicodeobject.c' line='6856' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyUnicode_DecodeRawUnicodeEscape' mangled-name='PyUnicode_DecodeRawUnicodeEscape' filepath='Objects/unicodeobject.c' line='6847' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_DecodeRawUnicodeEscape'> - <parameter type-id='type-id-3' name='s' filepath='Objects/unicodeobject.c' line='6937' column='1'/> - <parameter type-id='type-id-36' name='size' filepath='Objects/unicodeobject.c' line='6938' column='1'/> - <parameter type-id='type-id-3' name='errors' filepath='Objects/unicodeobject.c' line='6939' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyUnicode_DecodeRawUnicodeEscapeStateful' mangled-name='_PyUnicode_DecodeRawUnicodeEscapeStateful' filepath='Objects/unicodeobject.c' line='6711' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_DecodeRawUnicodeEscapeStateful'> - <parameter type-id='type-id-3' name='s' filepath='Objects/unicodeobject.c' line='6711' column='1'/> - <parameter type-id='type-id-36' name='size' filepath='Objects/unicodeobject.c' line='6712' column='1'/> - <parameter type-id='type-id-3' name='errors' filepath='Objects/unicodeobject.c' line='6713' column='1'/> - <parameter type-id='type-id-168' name='consumed' filepath='Objects/unicodeobject.c' line='6714' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyUnicode_AsUnicodeEscapeString' mangled-name='PyUnicode_AsUnicodeEscapeString' filepath='Objects/unicodeobject.c' line='6591' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_AsUnicodeEscapeString'> - <parameter type-id='type-id-14' name='unicode' filepath='Objects/unicodeobject.c' line='6856' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyUnicode_DecodeUnicodeEscape' mangled-name='PyUnicode_DecodeUnicodeEscape' filepath='Objects/unicodeobject.c' line='6581' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_DecodeUnicodeEscape'> - <parameter type-id='type-id-3' name='s' filepath='Objects/unicodeobject.c' line='6937' column='1'/> - <parameter type-id='type-id-36' name='size' filepath='Objects/unicodeobject.c' line='6938' column='1'/> - <parameter type-id='type-id-3' name='errors' filepath='Objects/unicodeobject.c' line='6939' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyUnicode_DecodeUnicodeEscapeStateful' mangled-name='_PyUnicode_DecodeUnicodeEscapeStateful' filepath='Objects/unicodeobject.c' line='6545' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_DecodeUnicodeEscapeStateful'> - <parameter type-id='type-id-3' name='s' filepath='Objects/unicodeobject.c' line='6545' column='1'/> - <parameter type-id='type-id-36' name='size' filepath='Objects/unicodeobject.c' line='6546' column='1'/> - <parameter type-id='type-id-3' name='errors' filepath='Objects/unicodeobject.c' line='6547' column='1'/> - <parameter type-id='type-id-168' name='consumed' filepath='Objects/unicodeobject.c' line='6548' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyUnicode_DecodeUnicodeEscapeInternal' mangled-name='_PyUnicode_DecodeUnicodeEscapeInternal' filepath='Objects/unicodeobject.c' line='6301' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_DecodeUnicodeEscapeInternal'> - <parameter type-id='type-id-3' name='s' filepath='Objects/unicodeobject.c' line='6301' column='1'/> - <parameter type-id='type-id-36' name='size' filepath='Objects/unicodeobject.c' line='6302' column='1'/> - <parameter type-id='type-id-3' name='errors' filepath='Objects/unicodeobject.c' line='6303' column='1'/> - <parameter type-id='type-id-168' name='consumed' filepath='Objects/unicodeobject.c' line='6304' column='1'/> - <parameter type-id='type-id-483' name='first_invalid_escape' filepath='Objects/unicodeobject.c' line='6305' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyUnicode_AsUTF16String' mangled-name='PyUnicode_AsUTF16String' filepath='Objects/unicodeobject.c' line='6291' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_AsUTF16String'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2462' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyUnicode_EncodeUTF16' mangled-name='_PyUnicode_EncodeUTF16' filepath='Objects/unicodeobject.c' line='6123' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_EncodeUTF16'> - <parameter type-id='type-id-14' name='str' filepath='Objects/unicodeobject.c' line='6123' column='1'/> - <parameter type-id='type-id-3' name='errors' filepath='Objects/unicodeobject.c' line='6124' column='1'/> - <parameter type-id='type-id-8' name='byteorder' filepath='Objects/unicodeobject.c' line='6125' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyUnicode_DecodeUTF16Stateful' mangled-name='PyUnicode_DecodeUTF16Stateful' filepath='Objects/unicodeobject.c' line='5968' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_DecodeUTF16Stateful'> - <parameter type-id='type-id-3' name='s' filepath='Objects/unicodeobject.c' line='5968' column='1'/> - <parameter type-id='type-id-36' name='size' filepath='Objects/unicodeobject.c' line='5969' column='1'/> - <parameter type-id='type-id-3' name='errors' filepath='Objects/unicodeobject.c' line='5970' column='1'/> - <parameter type-id='type-id-501' name='byteorder' filepath='Objects/unicodeobject.c' line='5971' column='1'/> - <parameter type-id='type-id-168' name='consumed' filepath='Objects/unicodeobject.c' line='5972' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyUnicode_DecodeUTF16' mangled-name='PyUnicode_DecodeUTF16' filepath='Objects/unicodeobject.c' line='5959' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_DecodeUTF16'> - <parameter type-id='type-id-3' name='s' filepath='Objects/unicodeobject.c' line='5959' column='1'/> - <parameter type-id='type-id-36' name='size' filepath='Objects/unicodeobject.c' line='5960' column='1'/> - <parameter type-id='type-id-3' name='errors' filepath='Objects/unicodeobject.c' line='5961' column='1'/> - <parameter type-id='type-id-501' name='byteorder' filepath='Objects/unicodeobject.c' line='5962' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyUnicode_AsUTF32String' mangled-name='PyUnicode_AsUTF32String' filepath='Objects/unicodeobject.c' line='5951' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_AsUTF32String'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2462' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyUnicode_EncodeUTF32' mangled-name='_PyUnicode_EncodeUTF32' filepath='Objects/unicodeobject.c' line='5802' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_EncodeUTF32'> - <parameter type-id='type-id-14' name='str' filepath='Objects/unicodeobject.c' line='5802' column='1'/> - <parameter type-id='type-id-3' name='errors' filepath='Objects/unicodeobject.c' line='5803' column='1'/> - <parameter type-id='type-id-8' name='byteorder' filepath='Objects/unicodeobject.c' line='5804' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyUnicode_DecodeUTF32Stateful' mangled-name='PyUnicode_DecodeUTF32Stateful' filepath='Objects/unicodeobject.c' line='5657' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_DecodeUTF32Stateful'> - <parameter type-id='type-id-3' name='s' filepath='Objects/unicodeobject.c' line='5657' column='1'/> - <parameter type-id='type-id-36' name='size' filepath='Objects/unicodeobject.c' line='5658' column='1'/> - <parameter type-id='type-id-3' name='errors' filepath='Objects/unicodeobject.c' line='5659' column='1'/> - <parameter type-id='type-id-501' name='byteorder' filepath='Objects/unicodeobject.c' line='5660' column='1'/> - <parameter type-id='type-id-168' name='consumed' filepath='Objects/unicodeobject.c' line='5661' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyUnicode_DecodeUTF32' mangled-name='PyUnicode_DecodeUTF32' filepath='Objects/unicodeobject.c' line='5648' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_DecodeUTF32'> - <parameter type-id='type-id-3' name='s' filepath='Objects/unicodeobject.c' line='5959' column='1'/> - <parameter type-id='type-id-36' name='size' filepath='Objects/unicodeobject.c' line='5960' column='1'/> - <parameter type-id='type-id-3' name='errors' filepath='Objects/unicodeobject.c' line='5961' column='1'/> - <parameter type-id='type-id-501' name='byteorder' filepath='Objects/unicodeobject.c' line='5962' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyUnicode_AsUTF8String' mangled-name='PyUnicode_AsUTF8String' filepath='Objects/unicodeobject.c' line='5640' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_AsUTF8String'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2462' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyUnicode_AsUTF8String' mangled-name='_PyUnicode_AsUTF8String' filepath='Objects/unicodeobject.c' line='5633' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_AsUTF8String'> - <parameter type-id='type-id-14' name='unicode' filepath='Objects/unicodeobject.c' line='7356' column='1'/> - <parameter type-id='type-id-3' name='errors' filepath='Objects/unicodeobject.c' line='7356' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <pointer-type-def type-id='type-id-54' size-in-bits='64' id='type-id-582'/> - <function-decl name='_Py_EncodeUTF8Ex' mangled-name='_Py_EncodeUTF8Ex' filepath='Objects/unicodeobject.c' line='5403' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_EncodeUTF8Ex'> - <parameter type-id='type-id-545' name='text' filepath='Objects/unicodeobject.c' line='5403' column='1'/> - <parameter type-id='type-id-494' name='str' filepath='Objects/unicodeobject.c' line='5403' column='1'/> - <parameter type-id='type-id-582' name='error_pos' filepath='Objects/unicodeobject.c' line='5403' column='1'/> - <parameter type-id='type-id-483' name='reason' filepath='Objects/unicodeobject.c' line='5404' column='1'/> - <parameter type-id='type-id-8' name='raw_malloc' filepath='Objects/unicodeobject.c' line='5404' column='1'/> - <parameter type-id='type-id-386' name='errors' filepath='Objects/unicodeobject.c' line='5404' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_Py_DecodeUTF8_surrogateescape' mangled-name='_Py_DecodeUTF8_surrogateescape' filepath='Objects/unicodeobject.c' line='5373' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_DecodeUTF8_surrogateescape'> - <parameter type-id='type-id-3' name='arg' filepath='Objects/unicodeobject.c' line='5373' column='1'/> - <parameter type-id='type-id-36' name='arglen' filepath='Objects/unicodeobject.c' line='5373' column='1'/> - <parameter type-id='type-id-582' name='wlen' filepath='Objects/unicodeobject.c' line='5374' column='1'/> - <return type-id='type-id-281'/> - </function-decl> - <function-decl name='_Py_DecodeUTF8Ex' mangled-name='_Py_DecodeUTF8Ex' filepath='Objects/unicodeobject.c' line='5264' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_DecodeUTF8Ex'> - <parameter type-id='type-id-3' name='s' filepath='Objects/unicodeobject.c' line='5264' column='1'/> - <parameter type-id='type-id-36' name='size' filepath='Objects/unicodeobject.c' line='5264' column='1'/> - <parameter type-id='type-id-374' name='wstr' filepath='Objects/unicodeobject.c' line='5264' column='1'/> - <parameter type-id='type-id-582' name='wlen' filepath='Objects/unicodeobject.c' line='5264' column='1'/> - <parameter type-id='type-id-483' name='reason' filepath='Objects/unicodeobject.c' line='5265' column='1'/> - <parameter type-id='type-id-386' name='errors' filepath='Objects/unicodeobject.c' line='5265' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyUnicode_DecodeUTF8Stateful' mangled-name='PyUnicode_DecodeUTF8Stateful' filepath='Objects/unicodeobject.c' line='5242' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_DecodeUTF8Stateful'> - <parameter type-id='type-id-3' name='s' filepath='Objects/unicodeobject.c' line='5242' column='1'/> - <parameter type-id='type-id-36' name='size' filepath='Objects/unicodeobject.c' line='5243' column='1'/> - <parameter type-id='type-id-3' name='errors' filepath='Objects/unicodeobject.c' line='5244' column='1'/> - <parameter type-id='type-id-168' name='consumed' filepath='Objects/unicodeobject.c' line='5245' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyUnicode_DecodeUTF8' mangled-name='PyUnicode_DecodeUTF8' filepath='Objects/unicodeobject.c' line='5007' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_DecodeUTF8'> - <parameter type-id='type-id-3' name='s' filepath='Objects/unicodeobject.c' line='6937' column='1'/> - <parameter type-id='type-id-36' name='size' filepath='Objects/unicodeobject.c' line='6938' column='1'/> - <parameter type-id='type-id-3' name='errors' filepath='Objects/unicodeobject.c' line='6939' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyUnicode_EncodeUTF7' mangled-name='_PyUnicode_EncodeUTF7' filepath='Objects/unicodeobject.c' line='4897' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_EncodeUTF7'> - <parameter type-id='type-id-14' name='str' filepath='Objects/unicodeobject.c' line='4897' column='1'/> - <parameter type-id='type-id-8' name='base64SetO' filepath='Objects/unicodeobject.c' line='4898' column='1'/> - <parameter type-id='type-id-8' name='base64WhiteSpace' filepath='Objects/unicodeobject.c' line='4899' column='1'/> - <parameter type-id='type-id-3' name='errors' filepath='Objects/unicodeobject.c' line='4900' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyUnicode_DecodeUTF7Stateful' mangled-name='PyUnicode_DecodeUTF7Stateful' filepath='Objects/unicodeobject.c' line='4699' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_DecodeUTF7Stateful'> - <parameter type-id='type-id-3' name='s' filepath='Objects/unicodeobject.c' line='4699' column='1'/> - <parameter type-id='type-id-36' name='size' filepath='Objects/unicodeobject.c' line='4700' column='1'/> - <parameter type-id='type-id-3' name='errors' filepath='Objects/unicodeobject.c' line='4701' column='1'/> - <parameter type-id='type-id-168' name='consumed' filepath='Objects/unicodeobject.c' line='4702' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyUnicode_DecodeUTF7' mangled-name='PyUnicode_DecodeUTF7' filepath='Objects/unicodeobject.c' line='4684' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_DecodeUTF7'> - <parameter type-id='type-id-3' name='s' filepath='Objects/unicodeobject.c' line='6937' column='1'/> - <parameter type-id='type-id-36' name='size' filepath='Objects/unicodeobject.c' line='6938' column='1'/> - <parameter type-id='type-id-3' name='errors' filepath='Objects/unicodeobject.c' line='6939' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyUnicode_GetDefaultEncoding' mangled-name='PyUnicode_GetDefaultEncoding' filepath='Objects/unicodeobject.c' line='4335' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_GetDefaultEncoding'> - <return type-id='type-id-3'/> - </function-decl> - <function-decl name='PyUnicode_WriteChar' mangled-name='PyUnicode_WriteChar' filepath='Objects/unicodeobject.c' line='4312' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_WriteChar'> - <parameter type-id='type-id-14' name='unicode' filepath='Objects/unicodeobject.c' line='4312' column='1'/> - <parameter type-id='type-id-36' name='index' filepath='Objects/unicodeobject.c' line='4312' column='1'/> - <parameter type-id='type-id-524' name='ch' filepath='Objects/unicodeobject.c' line='4312' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyUnicode_ReadChar' mangled-name='PyUnicode_ReadChar' filepath='Objects/unicodeobject.c' line='4290' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_ReadChar'> - <parameter type-id='type-id-14' name='unicode' filepath='Objects/unicodeobject.c' line='4290' column='1'/> - <parameter type-id='type-id-36' name='index' filepath='Objects/unicodeobject.c' line='4290' column='1'/> - <return type-id='type-id-524'/> - </function-decl> - <function-decl name='PyUnicode_GetLength' mangled-name='PyUnicode_GetLength' filepath='Objects/unicodeobject.c' line='4278' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_GetLength'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2335' column='1'/> - <return type-id='type-id-36'/> - </function-decl> - <function-decl name='PyUnicode_GetSize' mangled-name='PyUnicode_GetSize' filepath='Objects/unicodeobject.c' line='4259' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_GetSize'> - <parameter type-id='type-id-14' name='unicode' filepath='Objects/unicodeobject.c' line='4259' column='1'/> - <return type-id='type-id-36'/> - </function-decl> - <typedef-decl name='Py_UNICODE' type-id='type-id-282' filepath='./Include/cpython/unicodeobject.h' line='10' column='1' id='type-id-583'/> - <qualified-type-def type-id='type-id-583' const='yes' id='type-id-584'/> - <pointer-type-def type-id='type-id-584' size-in-bits='64' id='type-id-585'/> - <function-decl name='_PyUnicode_AsUnicode' mangled-name='_PyUnicode_AsUnicode' filepath='Objects/unicodeobject.c' line='4244' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_AsUnicode'> - <parameter type-id='type-id-14' name='unicode' filepath='Objects/unicodeobject.c' line='4244' column='1'/> - <return type-id='type-id-585'/> - </function-decl> - <pointer-type-def type-id='type-id-583' size-in-bits='64' id='type-id-586'/> - <function-decl name='PyUnicode_AsUnicode' mangled-name='PyUnicode_AsUnicode' filepath='Objects/unicodeobject.c' line='4238' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_AsUnicode'> - <parameter type-id='type-id-14' name='unicode' filepath='Objects/unicodeobject.c' line='4238' column='1'/> - <return type-id='type-id-586'/> - </function-decl> - <function-decl name='PyUnicode_AsUnicodeAndSize' mangled-name='PyUnicode_AsUnicodeAndSize' filepath='Objects/unicodeobject.c' line='4199' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_AsUnicodeAndSize'> - <parameter type-id='type-id-14' name='unicode' filepath='Objects/unicodeobject.c' line='4199' column='1'/> - <parameter type-id='type-id-168' name='size' filepath='Objects/unicodeobject.c' line='4199' column='1'/> - <return type-id='type-id-586'/> - </function-decl> - <function-decl name='PyUnicode_AsUTF8' mangled-name='PyUnicode_AsUTF8' filepath='Objects/unicodeobject.c' line='4193' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_AsUTF8'> - <parameter type-id='type-id-14' name='ob' filepath='Objects/exceptions.c' line='421' column='1'/> - <return type-id='type-id-3'/> - </function-decl> - <function-decl name='PyUnicode_AsUTF8AndSize' mangled-name='PyUnicode_AsUTF8AndSize' filepath='Objects/unicodeobject.c' line='4172' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_AsUTF8AndSize'> - <parameter type-id='type-id-14' name='unicode' filepath='Objects/unicodeobject.c' line='4172' column='1'/> - <parameter type-id='type-id-168' name='psize' filepath='Objects/unicodeobject.c' line='4172' column='1'/> - <return type-id='type-id-3'/> - </function-decl> - <function-decl name='PyUnicode_FSDecoder' mangled-name='PyUnicode_FSDecoder' filepath='Objects/unicodeobject.c' line='4099' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_FSDecoder'> - <parameter type-id='type-id-14' name='arg' filepath='Objects/unicodeobject.c' line='4099' column='1'/> - <parameter type-id='type-id-18' name='addr' filepath='Objects/unicodeobject.c' line='4099' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyUnicode_FSConverter' mangled-name='PyUnicode_FSConverter' filepath='Objects/unicodeobject.c' line='4059' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_FSConverter'> - <parameter type-id='type-id-14' name='arg' filepath='Objects/unicodeobject.c' line='4059' column='1'/> - <parameter type-id='type-id-18' name='addr' filepath='Objects/unicodeobject.c' line='4059' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyUnicode_DecodeFSDefaultAndSize' mangled-name='PyUnicode_DecodeFSDefaultAndSize' filepath='Objects/unicodeobject.c' line='4023' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_DecodeFSDefaultAndSize'> - <parameter type-id='type-id-3' name='s' filepath='Objects/unicodeobject.c' line='4023' column='1'/> - <parameter type-id='type-id-36' name='size' filepath='Objects/unicodeobject.c' line='4023' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyUnicode_DecodeFSDefault' mangled-name='PyUnicode_DecodeFSDefault' filepath='Objects/unicodeobject.c' line='4017' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_DecodeFSDefault'> - <parameter type-id='type-id-3' name='cp' filepath='Objects/unicodeobject.c' line='15605' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyUnicode_DecodeLocale' mangled-name='PyUnicode_DecodeLocale' filepath='Objects/unicodeobject.c' line='4008' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_DecodeLocale'> - <parameter type-id='type-id-3' name='name' filepath='Objects/typeobject.c' line='181' column='1'/> - <parameter type-id='type-id-3' name='internal_doc' filepath='Objects/typeobject.c' line='181' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyUnicode_DecodeLocaleAndSize' mangled-name='PyUnicode_DecodeLocaleAndSize' filepath='Objects/unicodeobject.c' line='4000' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_DecodeLocaleAndSize'> - <parameter type-id='type-id-3' name='str' filepath='Objects/unicodeobject.c' line='4000' column='1'/> - <parameter type-id='type-id-36' name='len' filepath='Objects/unicodeobject.c' line='4000' column='1'/> - <parameter type-id='type-id-3' name='errors' filepath='Objects/unicodeobject.c' line='4001' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyUnicode_AsEncodedUnicode' mangled-name='PyUnicode_AsEncodedUnicode' filepath='Objects/unicodeobject.c' line='3920' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_AsEncodedUnicode'> - <parameter type-id='type-id-14' name='unicode' filepath='Objects/unicodeobject.c' line='3920' column='1'/> - <parameter type-id='type-id-3' name='encoding' filepath='Objects/unicodeobject.c' line='3921' column='1'/> - <parameter type-id='type-id-3' name='errors' filepath='Objects/unicodeobject.c' line='3922' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyUnicode_AsEncodedString' mangled-name='PyUnicode_AsEncodedString' filepath='Objects/unicodeobject.c' line='3820' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_AsEncodedString'> - <parameter type-id='type-id-14' name='unicode' filepath='Objects/unicodeobject.c' line='3820' column='1'/> - <parameter type-id='type-id-3' name='encoding' filepath='Objects/unicodeobject.c' line='3821' column='1'/> - <parameter type-id='type-id-3' name='errors' filepath='Objects/unicodeobject.c' line='3822' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyUnicode_EncodeFSDefault' mangled-name='PyUnicode_EncodeFSDefault' filepath='Objects/unicodeobject.c' line='3786' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_EncodeFSDefault'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2791' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyUnicode_EncodeLocale' mangled-name='PyUnicode_EncodeLocale' filepath='Objects/unicodeobject.c' line='3779' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_EncodeLocale'> - <parameter type-id='type-id-14' name='unicode' filepath='Objects/unicodeobject.c' line='3779' column='1'/> - <parameter type-id='type-id-3' name='errors' filepath='Objects/unicodeobject.c' line='3779' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyUnicode_AsEncodedObject' mangled-name='PyUnicode_AsEncodedObject' filepath='Objects/unicodeobject.c' line='3697' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_AsEncodedObject'> - <parameter type-id='type-id-14' name='unicode' filepath='Objects/unicodeobject.c' line='3920' column='1'/> - <parameter type-id='type-id-3' name='encoding' filepath='Objects/unicodeobject.c' line='3921' column='1'/> - <parameter type-id='type-id-3' name='errors' filepath='Objects/unicodeobject.c' line='3922' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyUnicode_AsDecodedUnicode' mangled-name='PyUnicode_AsDecodedUnicode' filepath='Objects/unicodeobject.c' line='3658' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_AsDecodedUnicode'> - <parameter type-id='type-id-14' name='unicode' filepath='Objects/unicodeobject.c' line='3920' column='1'/> - <parameter type-id='type-id-3' name='encoding' filepath='Objects/unicodeobject.c' line='3921' column='1'/> - <parameter type-id='type-id-3' name='errors' filepath='Objects/unicodeobject.c' line='3922' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyUnicode_AsDecodedObject' mangled-name='PyUnicode_AsDecodedObject' filepath='Objects/unicodeobject.c' line='3636' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_AsDecodedObject'> - <parameter type-id='type-id-14' name='unicode' filepath='Objects/unicodeobject.c' line='3636' column='1'/> - <parameter type-id='type-id-3' name='encoding' filepath='Objects/unicodeobject.c' line='3637' column='1'/> - <parameter type-id='type-id-3' name='errors' filepath='Objects/unicodeobject.c' line='3638' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyUnicode_Decode' mangled-name='PyUnicode_Decode' filepath='Objects/unicodeobject.c' line='3546' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_Decode'> - <parameter type-id='type-id-3' name='s' filepath='Objects/unicodeobject.c' line='3546' column='1'/> - <parameter type-id='type-id-36' name='size' filepath='Objects/unicodeobject.c' line='3547' column='1'/> - <parameter type-id='type-id-3' name='encoding' filepath='Objects/unicodeobject.c' line='3548' column='1'/> - <parameter type-id='type-id-3' name='errors' filepath='Objects/unicodeobject.c' line='3549' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyUnicode_FromEncodedObject' mangled-name='PyUnicode_FromEncodedObject' filepath='Objects/unicodeobject.c' line='3444' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_FromEncodedObject'> - <parameter type-id='type-id-14' name='obj' filepath='Objects/unicodeobject.c' line='3444' column='1'/> - <parameter type-id='type-id-3' name='encoding' filepath='Objects/unicodeobject.c' line='3445' column='1'/> - <parameter type-id='type-id-3' name='errors' filepath='Objects/unicodeobject.c' line='3446' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyUnicode_FromObject' mangled-name='PyUnicode_FromObject' filepath='Objects/unicodeobject.c' line='3422' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_FromObject'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2462' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyUnicode_FromOrdinal' mangled-name='PyUnicode_FromOrdinal' filepath='Objects/unicodeobject.c' line='3410' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_FromOrdinal'> - <parameter type-id='type-id-8' name='ordinal' filepath='Objects/unicodeobject.c' line='3410' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyUnicode_WideCharString_Opt_Converter' mangled-name='_PyUnicode_WideCharString_Opt_Converter' filepath='Objects/unicodeobject.c' line='3374' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_WideCharString_Opt_Converter'> - <parameter type-id='type-id-14' name='o' filepath='Objects/capsule.c' line='181' column='1'/> - <parameter type-id='type-id-18' name='context' filepath='Objects/capsule.c' line='181' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyUnicode_WideCharString_Converter' mangled-name='_PyUnicode_WideCharString_Converter' filepath='Objects/unicodeobject.c' line='3342' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_WideCharString_Converter'> - <parameter type-id='type-id-14' name='o' filepath='Objects/capsule.c' line='181' column='1'/> - <parameter type-id='type-id-18' name='context' filepath='Objects/capsule.c' line='181' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyUnicode_AsWideCharString' mangled-name='PyUnicode_AsWideCharString' filepath='Objects/unicodeobject.c' line='3294' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_AsWideCharString'> - <parameter type-id='type-id-14' name='unicode' filepath='Objects/unicodeobject.c' line='3294' column='1'/> - <parameter type-id='type-id-168' name='size' filepath='Objects/unicodeobject.c' line='3295' column='1'/> - <return type-id='type-id-281'/> - </function-decl> - <function-decl name='PyUnicode_AsWideChar' mangled-name='PyUnicode_AsWideChar' filepath='Objects/unicodeobject.c' line='3252' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_AsWideChar'> - <parameter type-id='type-id-14' name='unicode' filepath='Objects/unicodeobject.c' line='3252' column='1'/> - <parameter type-id='type-id-281' name='w' filepath='Objects/unicodeobject.c' line='3253' column='1'/> - <parameter type-id='type-id-36' name='size' filepath='Objects/unicodeobject.c' line='3254' column='1'/> - <return type-id='type-id-36'/> - </function-decl> - <function-decl name='PyUnicode_FromFormat' mangled-name='PyUnicode_FromFormat' filepath='Objects/unicodeobject.c' line='3142' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_FromFormat'> - <parameter type-id='type-id-3' name='format' filepath='Objects/bytesobject.c' line='375' column='1'/> - <parameter is-variadic='yes'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyUnicode_FromFormatV' mangled-name='PyUnicode_FromFormatV' filepath='Objects/unicodeobject.c' line='3085' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_FromFormatV'> - <parameter type-id='type-id-3' name='format' filepath='Objects/unicodeobject.c' line='3085' column='1'/> - <parameter type-id='type-id-496' name='vargs' filepath='Objects/unicodeobject.c' line='3085' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyUnicode_AsUCS4Copy' mangled-name='PyUnicode_AsUCS4Copy' filepath='Objects/unicodeobject.c' line='2709' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_AsUCS4Copy'> - <parameter type-id='type-id-14' name='string' filepath='Objects/unicodeobject.c' line='2709' column='1'/> - <return type-id='type-id-581'/> - </function-decl> - <function-decl name='PyUnicode_AsUCS4' mangled-name='PyUnicode_AsUCS4' filepath='Objects/unicodeobject.c' line='2698' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_AsUCS4'> - <parameter type-id='type-id-14' name='string' filepath='Objects/unicodeobject.c' line='2698' column='1'/> - <parameter type-id='type-id-581' name='target' filepath='Objects/unicodeobject.c' line='2698' column='1'/> - <parameter type-id='type-id-36' name='targetsize' filepath='Objects/unicodeobject.c' line='2698' column='1'/> - <parameter type-id='type-id-8' name='copy_null' filepath='Objects/unicodeobject.c' line='2699' column='1'/> - <return type-id='type-id-581'/> - </function-decl> - <function-decl name='_PyUnicode_Copy' mangled-name='_PyUnicode_Copy' filepath='Objects/unicodeobject.c' line='2575' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_Copy'> - <parameter type-id='type-id-14' name='v' filepath='Objects/abstract.c' line='2122' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyUnicode_FindMaxChar' mangled-name='_PyUnicode_FindMaxChar' filepath='Objects/unicodeobject.c' line='2492' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_FindMaxChar'> - <parameter type-id='type-id-14' name='unicode' filepath='Objects/unicodeobject.c' line='2492' column='1'/> - <parameter type-id='type-id-36' name='start' filepath='Objects/unicodeobject.c' line='2492' column='1'/> - <parameter type-id='type-id-36' name='end' filepath='Objects/unicodeobject.c' line='2492' column='1'/> - <return type-id='type-id-524'/> - </function-decl> - <function-decl name='PyUnicode_FromKindAndData' mangled-name='PyUnicode_FromKindAndData' filepath='Objects/unicodeobject.c' line='2472' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_FromKindAndData'> - <parameter type-id='type-id-8' name='kind' filepath='Objects/unicodeobject.c' line='2472' column='1'/> - <parameter type-id='type-id-18' name='buffer' filepath='Objects/unicodeobject.c' line='2472' column='1'/> - <parameter type-id='type-id-36' name='size' filepath='Objects/unicodeobject.c' line='2472' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyUnicode_FromASCII' mangled-name='_PyUnicode_FromASCII' filepath='Objects/unicodeobject.c' line='2361' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_FromASCII'> - <parameter type-id='type-id-3' name='bytes' filepath='Objects/bytearrayobject.c' line='108' column='1'/> - <parameter type-id='type-id-36' name='size' filepath='Objects/bytearrayobject.c' line='108' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyUnicode_FromId' mangled-name='_PyUnicode_FromId' filepath='Objects/unicodeobject.c' line='2282' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_FromId'> - <parameter type-id='type-id-499' name='id' filepath='Objects/unicodeobject.c' line='2282' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyUnicode_FromString' mangled-name='PyUnicode_FromString' filepath='Objects/unicodeobject.c' line='2270' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_FromString'> - <parameter type-id='type-id-3' name='cp' filepath='Objects/unicodeobject.c' line='15605' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyUnicode_FromStringAndSize' mangled-name='PyUnicode_FromStringAndSize' filepath='Objects/unicodeobject.c' line='2247' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_FromStringAndSize'> - <parameter type-id='type-id-3' name='u' filepath='Objects/unicodeobject.c' line='2247' column='1'/> - <parameter type-id='type-id-36' name='size' filepath='Objects/unicodeobject.c' line='2247' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyUnicode_FromWideChar' mangled-name='PyUnicode_FromWideChar' filepath='Objects/unicodeobject.c' line='2165' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_FromWideChar'> - <parameter type-id='type-id-545' name='u' filepath='Objects/unicodeobject.c' line='2165' column='1'/> - <parameter type-id='type-id-36' name='size' filepath='Objects/unicodeobject.c' line='2165' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyUnicode_FromUnicode' mangled-name='PyUnicode_FromUnicode' filepath='Objects/unicodeobject.c' line='2143' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_FromUnicode'> - <parameter type-id='type-id-585' name='u' filepath='Objects/unicodeobject.c' line='2143' column='1'/> - <parameter type-id='type-id-36' name='size' filepath='Objects/unicodeobject.c' line='2143' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyUnicode_Resize' mangled-name='PyUnicode_Resize' filepath='Objects/unicodeobject.c' line='2042' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_Resize'> - <parameter type-id='type-id-22' name='p_unicode' filepath='Objects/unicodeobject.c' line='2042' column='1'/> - <parameter type-id='type-id-36' name='length' filepath='Objects/unicodeobject.c' line='2042' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyUnicode_Ready' mangled-name='_PyUnicode_Ready' filepath='Objects/unicodeobject.c' line='1780' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_Ready'> - <parameter type-id='type-id-14' name='unicode' filepath='Objects/unicodeobject.c' line='1780' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyUnicode_CopyCharacters' mangled-name='PyUnicode_CopyCharacters' filepath='Objects/unicodeobject.c' line='1679' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_CopyCharacters'> - <parameter type-id='type-id-14' name='to' filepath='Objects/unicodeobject.c' line='1679' column='1'/> - <parameter type-id='type-id-36' name='to_start' filepath='Objects/unicodeobject.c' line='1679' column='1'/> - <parameter type-id='type-id-14' name='from' filepath='Objects/unicodeobject.c' line='1680' column='1'/> - <parameter type-id='type-id-36' name='from_start' filepath='Objects/unicodeobject.c' line='1680' column='1'/> - <parameter type-id='type-id-36' name='how_many' filepath='Objects/unicodeobject.c' line='1681' column='1'/> - <return type-id='type-id-36'/> - </function-decl> - <function-decl name='_PyUnicode_FastCopyCharacters' mangled-name='_PyUnicode_FastCopyCharacters' filepath='Objects/unicodeobject.c' line='1671' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_FastCopyCharacters'> - <parameter type-id='type-id-14' name='to' filepath='Objects/unicodeobject.c' line='1672' column='1'/> - <parameter type-id='type-id-36' name='to_start' filepath='Objects/unicodeobject.c' line='1672' column='1'/> - <parameter type-id='type-id-14' name='from' filepath='Objects/unicodeobject.c' line='1673' column='1'/> - <parameter type-id='type-id-36' name='from_start' filepath='Objects/unicodeobject.c' line='1673' column='1'/> - <parameter type-id='type-id-36' name='how_many' filepath='Objects/unicodeobject.c' line='1673' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyUnicode_New' mangled-name='PyUnicode_New' filepath='Objects/unicodeobject.c' line='1366' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_New'> - <parameter type-id='type-id-36' name='size' filepath='Objects/unicodeobject.c' line='1366' column='1'/> - <parameter type-id='type-id-524' name='maxchar' filepath='Objects/unicodeobject.c' line='1366' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyUnicode_CheckConsistency' mangled-name='_PyUnicode_CheckConsistency' filepath='Objects/unicodeobject.c' line='501' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_CheckConsistency'> - <parameter type-id='type-id-14' name='op' filepath='Objects/unicodeobject.c' line='501' column='1'/> - <parameter type-id='type-id-8' name='check_content' filepath='Objects/unicodeobject.c' line='501' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_Py_GetErrorHandler' mangled-name='_Py_GetErrorHandler' filepath='Objects/unicodeobject.c' line='397' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_GetErrorHandler'> - <parameter type-id='type-id-3' name='errors' filepath='Objects/unicodeobject.c' line='397' column='1'/> - <return type-id='type-id-386'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Objects/unicodectype.c' comp-dir-path='/src' language='LANG_C99'> - <function-decl name='_PyUnicode_IsAlpha' mangled-name='_PyUnicode_IsAlpha' filepath='Objects/unicodectype.c' line='289' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_IsAlpha'> - <parameter type-id='type-id-524' name='ch' filepath='Objects/unicodectype.c' line='289' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyUnicode_IsCaseIgnorable' mangled-name='_PyUnicode_IsCaseIgnorable' filepath='Objects/unicodectype.c' line='279' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_IsCaseIgnorable'> - <parameter type-id='type-id-524' name='ch' filepath='Objects/unicodectype.c' line='289' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyUnicode_IsCased' mangled-name='_PyUnicode_IsCased' filepath='Objects/unicodectype.c' line='272' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_IsCased'> - <parameter type-id='type-id-524' name='ch' filepath='Objects/unicodectype.c' line='289' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyUnicode_ToFoldedFull' mangled-name='_PyUnicode_ToFoldedFull' filepath='Objects/unicodectype.c' line='257' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_ToFoldedFull'> - <parameter type-id='type-id-524' name='ch' filepath='Objects/unicodectype.c' line='257' column='1'/> - <parameter type-id='type-id-581' name='res' filepath='Objects/unicodectype.c' line='257' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyUnicode_ToUpperFull' mangled-name='_PyUnicode_ToUpperFull' filepath='Objects/unicodectype.c' line='241' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_ToUpperFull'> - <parameter type-id='type-id-524' name='ch' filepath='Objects/unicodectype.c' line='257' column='1'/> - <parameter type-id='type-id-581' name='res' filepath='Objects/unicodectype.c' line='257' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyUnicode_ToTitleFull' mangled-name='_PyUnicode_ToTitleFull' filepath='Objects/unicodectype.c' line='225' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_ToTitleFull'> - <parameter type-id='type-id-524' name='ch' filepath='Objects/unicodectype.c' line='257' column='1'/> - <parameter type-id='type-id-581' name='res' filepath='Objects/unicodectype.c' line='257' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyUnicode_ToLowerFull' mangled-name='_PyUnicode_ToLowerFull' filepath='Objects/unicodectype.c' line='209' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_ToLowerFull'> - <parameter type-id='type-id-524' name='ch' filepath='Objects/unicodectype.c' line='257' column='1'/> - <parameter type-id='type-id-581' name='res' filepath='Objects/unicodectype.c' line='257' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyUnicode_ToLowercase' mangled-name='_PyUnicode_ToLowercase' filepath='Objects/unicodectype.c' line='200' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_ToLowercase'> - <parameter type-id='type-id-524' name='ch' filepath='Objects/unicodectype.c' line='200' column='1'/> - <return type-id='type-id-524'/> - </function-decl> - <function-decl name='_PyUnicode_ToUppercase' mangled-name='_PyUnicode_ToUppercase' filepath='Objects/unicodectype.c' line='188' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_ToUppercase'> - <parameter type-id='type-id-524' name='ch' filepath='Objects/unicodectype.c' line='200' column='1'/> - <return type-id='type-id-524'/> - </function-decl> - <function-decl name='_PyUnicode_IsUppercase' mangled-name='_PyUnicode_IsUppercase' filepath='Objects/unicodectype.c' line='178' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_IsUppercase'> - <parameter type-id='type-id-524' name='ch' filepath='Objects/unicodectype.c' line='289' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyUnicode_IsLowercase' mangled-name='_PyUnicode_IsLowercase' filepath='Objects/unicodectype.c' line='168' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_IsLowercase'> - <parameter type-id='type-id-524' name='ch' filepath='Objects/unicodectype.c' line='289' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyUnicode_IsPrintable' mangled-name='_PyUnicode_IsPrintable' filepath='Objects/unicodectype.c' line='158' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_IsPrintable'> - <parameter type-id='type-id-524' name='ch' filepath='Objects/unicodectype.c' line='289' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyUnicode_IsNumeric' mangled-name='_PyUnicode_IsNumeric' filepath='Objects/unicodectype.c' line='138' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_IsNumeric'> - <parameter type-id='type-id-524' name='ch' filepath='Objects/unicodectype.c' line='289' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyUnicode_IsDigit' mangled-name='_PyUnicode_IsDigit' filepath='Objects/unicodectype.c' line='128' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_IsDigit'> - <parameter type-id='type-id-524' name='ch' filepath='Objects/unicodectype.c' line='128' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyUnicode_ToDigit' mangled-name='_PyUnicode_ToDigit' filepath='Objects/unicodectype.c' line='121' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_ToDigit'> - <parameter type-id='type-id-524' name='ch' filepath='Objects/unicodectype.c' line='289' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyUnicode_IsDecimalDigit' mangled-name='_PyUnicode_IsDecimalDigit' filepath='Objects/unicodectype.c' line='111' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_IsDecimalDigit'> - <parameter type-id='type-id-524' name='ch' filepath='Objects/unicodectype.c' line='128' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyUnicode_ToDecimalDigit' mangled-name='_PyUnicode_ToDecimalDigit' filepath='Objects/unicodectype.c' line='104' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_ToDecimalDigit'> - <parameter type-id='type-id-524' name='ch' filepath='Objects/unicodectype.c' line='289' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyUnicode_IsXidContinue' mangled-name='_PyUnicode_IsXidContinue' filepath='Objects/unicodectype.c' line='94' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_IsXidContinue'> - <parameter type-id='type-id-524' name='ch' filepath='Objects/unicodectype.c' line='289' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyUnicode_IsXidStart' mangled-name='_PyUnicode_IsXidStart' filepath='Objects/unicodectype.c' line='84' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_IsXidStart'> - <parameter type-id='type-id-524' name='ch' filepath='Objects/unicodectype.c' line='289' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyUnicode_IsTitlecase' mangled-name='_PyUnicode_IsTitlecase' filepath='Objects/unicodectype.c' line='74' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_IsTitlecase'> - <parameter type-id='type-id-524' name='ch' filepath='Objects/unicodectype.c' line='289' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyUnicode_ToTitlecase' mangled-name='_PyUnicode_ToTitlecase' filepath='Objects/unicodectype.c' line='62' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_ToTitlecase'> - <parameter type-id='type-id-524' name='ch' filepath='Objects/unicodectype.c' line='200' column='1'/> - <return type-id='type-id-524'/> - </function-decl> - <qualified-type-def type-id='type-id-524' const='yes' id='type-id-587'/> - <function-decl name='_PyUnicode_IsLinebreak' mangled-name='_PyUnicode_IsLinebreak' filepath='Objects/unicodetype_db.h' line='6295' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_IsLinebreak'> - <parameter type-id='type-id-587' name='ch' filepath='Objects/unicodetype_db.h' line='6295' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyUnicode_IsWhitespace' mangled-name='_PyUnicode_IsWhitespace' filepath='Objects/unicodetype_db.h' line='6254' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_IsWhitespace'> - <parameter type-id='type-id-587' name='ch' filepath='Objects/unicodetype_db.h' line='6295' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyUnicode_ToNumeric' mangled-name='_PyUnicode_ToNumeric' filepath='Objects/unicodetype_db.h' line='4223' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_ToNumeric'> - <parameter type-id='type-id-524' name='ch' filepath='Objects/unicodetype_db.h' line='4223' column='1'/> - <return type-id='type-id-391'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Objects/unionobject.c' comp-dir-path='/src' language='LANG_C99'> - <var-decl name='_PyUnion_Type' type-id='type-id-112' visibility='default' filepath='./Include/internal/pycore_unionobject.h' line='11' column='1'/> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Objects/weakrefobject.c' comp-dir-path='/src' language='LANG_C99'> - <var-decl name='_PyWeakref_RefType' type-id='type-id-112' mangled-name='_PyWeakref_RefType' visibility='default' filepath='./Include/weakrefobject.h' line='11' column='1' elf-symbol-id='_PyWeakref_RefType'/> - <var-decl name='_PyWeakref_ProxyType' type-id='type-id-112' mangled-name='_PyWeakref_ProxyType' visibility='default' filepath='./Include/weakrefobject.h' line='12' column='1' elf-symbol-id='_PyWeakref_ProxyType'/> - <var-decl name='_PyWeakref_CallableProxyType' type-id='type-id-112' mangled-name='_PyWeakref_CallableProxyType' visibility='default' filepath='./Include/weakrefobject.h' line='13' column='1' elf-symbol-id='_PyWeakref_CallableProxyType'/> - <function-decl name='PyObject_ClearWeakRefs' mangled-name='PyObject_ClearWeakRefs' filepath='Objects/weakrefobject.c' line='945' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_ClearWeakRefs'> - <parameter type-id='type-id-14' name='object' filepath='Objects/weakrefobject.c' line='945' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyWeakref_GetObject' mangled-name='PyWeakref_GetObject' filepath='Objects/weakrefobject.c' line='915' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyWeakref_GetObject'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2462' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyWeakref_NewProxy' mangled-name='PyWeakref_NewProxy' filepath='Objects/weakrefobject.c' line='848' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyWeakref_NewProxy'> - <parameter type-id='type-id-14' name='ob' filepath='Objects/weakrefobject.c' line='848' column='1'/> - <parameter type-id='type-id-14' name='callback' filepath='Objects/weakrefobject.c' line='848' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyWeakref_NewRef' mangled-name='PyWeakref_NewRef' filepath='Objects/weakrefobject.c' line='789' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyWeakref_NewRef'> - <parameter type-id='type-id-14' name='ob' filepath='Objects/weakrefobject.c' line='789' column='1'/> - <parameter type-id='type-id-14' name='callback' filepath='Objects/weakrefobject.c' line='789' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <class-decl name='_PyWeakReference' size-in-bits='512' is-struct='yes' visibility='default' filepath='./Include/cpython/weakrefobject.h' line='8' column='1' id='type-id-588'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='ob_base' type-id='type-id-108' visibility='default' filepath='./Include/cpython/weakrefobject.h' line='9' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='wr_object' type-id='type-id-14' visibility='default' filepath='./Include/cpython/weakrefobject.h' line='15' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='wr_callback' type-id='type-id-14' visibility='default' filepath='./Include/cpython/weakrefobject.h' line='18' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='256'> - <var-decl name='hash' type-id='type-id-159' visibility='default' filepath='./Include/cpython/weakrefobject.h' line='23' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='320'> - <var-decl name='wr_prev' type-id='type-id-589' visibility='default' filepath='./Include/cpython/weakrefobject.h' line='30' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='384'> - <var-decl name='wr_next' type-id='type-id-589' visibility='default' filepath='./Include/cpython/weakrefobject.h' line='31' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='448'> - <var-decl name='vectorcall' type-id='type-id-106' visibility='default' filepath='./Include/cpython/weakrefobject.h' line='32' column='1'/> - </data-member> - </class-decl> - <typedef-decl name='PyWeakReference' type-id='type-id-588' filepath='./Include/weakrefobject.h' line='9' column='1' id='type-id-590'/> - <pointer-type-def type-id='type-id-590' size-in-bits='64' id='type-id-589'/> - <function-decl name='_PyWeakref_ClearRef' mangled-name='_PyWeakref_ClearRef' filepath='Objects/weakrefobject.c' line='93' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyWeakref_ClearRef'> - <parameter type-id='type-id-589' name='self' filepath='Objects/weakrefobject.c' line='93' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_PyWeakref_GetWeakrefCount' mangled-name='_PyWeakref_GetWeakrefCount' filepath='Objects/weakrefobject.c' line='11' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyWeakref_GetWeakrefCount'> - <parameter type-id='type-id-589' name='head' filepath='Objects/weakrefobject.c' line='11' column='1'/> - <return type-id='type-id-36'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Python/_warnings.c' comp-dir-path='/src' language='LANG_C99'> - <function-decl name='_PyWarnings_Init' mangled-name='_PyWarnings_Init' filepath='Python/_warnings.c' line='1405' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyWarnings_Init'> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyErr_WarnExplicitFormat' mangled-name='PyErr_WarnExplicitFormat' filepath='Python/_warnings.c' line='1257' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_WarnExplicitFormat'> - <parameter type-id='type-id-14' name='category' filepath='Python/_warnings.c' line='1257' column='1'/> - <parameter type-id='type-id-3' name='filename_str' filepath='Python/_warnings.c' line='1258' column='1'/> - <parameter type-id='type-id-8' name='lineno' filepath='Python/_warnings.c' line='1258' column='1'/> - <parameter type-id='type-id-3' name='module_str' filepath='Python/_warnings.c' line='1259' column='1'/> - <parameter type-id='type-id-14' name='registry' filepath='Python/_warnings.c' line='1259' column='1'/> - <parameter type-id='type-id-3' name='format' filepath='Python/_warnings.c' line='1260' column='1'/> - <parameter is-variadic='yes'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyErr_WarnExplicit' mangled-name='PyErr_WarnExplicit' filepath='Python/_warnings.c' line='1229' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_WarnExplicit'> - <parameter type-id='type-id-14' name='category' filepath='Python/_warnings.c' line='1229' column='1'/> - <parameter type-id='type-id-3' name='text' filepath='Python/_warnings.c' line='1229' column='1'/> - <parameter type-id='type-id-3' name='filename_str' filepath='Python/_warnings.c' line='1230' column='1'/> - <parameter type-id='type-id-8' name='lineno' filepath='Python/_warnings.c' line='1230' column='1'/> - <parameter type-id='type-id-3' name='module_str' filepath='Python/_warnings.c' line='1231' column='1'/> - <parameter type-id='type-id-14' name='registry' filepath='Python/_warnings.c' line='1231' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyErr_WarnExplicitObject' mangled-name='PyErr_WarnExplicitObject' filepath='Python/_warnings.c' line='1209' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_WarnExplicitObject'> - <parameter type-id='type-id-14' name='category' filepath='Python/_warnings.c' line='1209' column='1'/> - <parameter type-id='type-id-14' name='message' filepath='Python/_warnings.c' line='1209' column='1'/> - <parameter type-id='type-id-14' name='filename' filepath='Python/_warnings.c' line='1210' column='1'/> - <parameter type-id='type-id-8' name='lineno' filepath='Python/_warnings.c' line='1210' column='1'/> - <parameter type-id='type-id-14' name='module' filepath='Python/_warnings.c' line='1211' column='1'/> - <parameter type-id='type-id-14' name='registry' filepath='Python/_warnings.c' line='1211' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyErr_WarnEx' mangled-name='PyErr_WarnEx' filepath='Python/_warnings.c' line='1185' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_WarnEx'> - <parameter type-id='type-id-14' name='category' filepath='Python/_warnings.c' line='1185' column='1'/> - <parameter type-id='type-id-3' name='text' filepath='Python/_warnings.c' line='1185' column='1'/> - <parameter type-id='type-id-36' name='stack_level' filepath='Python/_warnings.c' line='1185' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyErr_ResourceWarning' mangled-name='PyErr_ResourceWarning' filepath='Python/_warnings.c' line='1166' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_ResourceWarning'> - <parameter type-id='type-id-14' name='source' filepath='Python/_warnings.c' line='1166' column='1'/> - <parameter type-id='type-id-36' name='stack_level' filepath='Python/_warnings.c' line='1166' column='1'/> - <parameter type-id='type-id-3' name='format' filepath='Python/_warnings.c' line='1167' column='1'/> - <parameter is-variadic='yes'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyErr_WarnFormat' mangled-name='PyErr_WarnFormat' filepath='Python/_warnings.c' line='1132' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_WarnFormat'> - <parameter type-id='type-id-14' name='source' filepath='Python/_warnings.c' line='1166' column='1'/> - <parameter type-id='type-id-36' name='stack_level' filepath='Python/_warnings.c' line='1166' column='1'/> - <parameter type-id='type-id-3' name='format' filepath='Python/_warnings.c' line='1167' column='1'/> - <parameter is-variadic='yes'/> - <return type-id='type-id-8'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Python/Python-ast.c' comp-dir-path='/src' language='LANG_C99'> - <function-decl name='PyInit__ast' mangled-name='PyInit__ast' filepath='Python/Python-ast.c' line='12305' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInit__ast'> - <return type-id='type-id-14'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Python/Python-tokenize.c' comp-dir-path='/src' language='LANG_C99'> - <function-decl name='PyInit__tokenize' mangled-name='PyInit__tokenize' filepath='Python/Python-tokenize.c' line='191' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInit__tokenize'> - <return type-id='type-id-14'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Python/bltinmodule.c' comp-dir-path='/src' language='LANG_C99'> - <var-decl name='PyFilter_Type' type-id='type-id-112' mangled-name='PyFilter_Type' visibility='default' filepath='./Include/bltinmodule.h' line='7' column='1' elf-symbol-id='PyFilter_Type'/> - <var-decl name='PyMap_Type' type-id='type-id-112' mangled-name='PyMap_Type' visibility='default' filepath='./Include/bltinmodule.h' line='8' column='1' elf-symbol-id='PyMap_Type'/> - <var-decl name='PyZip_Type' type-id='type-id-112' mangled-name='PyZip_Type' visibility='default' filepath='./Include/bltinmodule.h' line='9' column='1' elf-symbol-id='PyZip_Type'/> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Python/ceval.c' comp-dir-path='/src' language='LANG_C99'> - <function-decl name='Py_LeaveRecursiveCall' mangled-name='Py_LeaveRecursiveCall' filepath='Python/ceval.c' line='7954' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_LeaveRecursiveCall'> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='Py_EnterRecursiveCall' mangled-name='Py_EnterRecursiveCall' filepath='Python/ceval.c' line='7947' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_EnterRecursiveCall'> - <parameter type-id='type-id-3' name='where' filepath='Python/ceval.c' line='7947' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyEval_RequestCodeExtraIndex' mangled-name='_PyEval_RequestCodeExtraIndex' filepath='Python/ceval.c' line='7866' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyEval_RequestCodeExtraIndex'> - <parameter type-id='type-id-104' name='free' filepath='Python/ceval.c' line='7866' column='1'/> - <return type-id='type-id-36'/> - </function-decl> - <function-decl name='_PyEval_SliceIndexNotNone' mangled-name='_PyEval_SliceIndexNotNone' filepath='Python/ceval.c' line='7386' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyEval_SliceIndexNotNone'> - <parameter type-id='type-id-14' name='exc' filepath='Objects/exceptions.c' line='2704' column='1'/> - <parameter type-id='type-id-168' name='end' filepath='Objects/exceptions.c' line='2704' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyEval_SliceIndex' mangled-name='_PyEval_SliceIndex' filepath='Python/ceval.c' line='7364' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyEval_SliceIndex'> - <parameter type-id='type-id-14' name='v' filepath='Python/ceval.c' line='7364' column='1'/> - <parameter type-id='type-id-168' name='pi' filepath='Python/ceval.c' line='7364' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyEval_GetFuncDesc' mangled-name='PyEval_GetFuncDesc' filepath='Python/ceval.c' line='7237' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyEval_GetFuncDesc'> - <parameter type-id='type-id-14' name='ob' filepath='Objects/exceptions.c' line='421' column='1'/> - <return type-id='type-id-3'/> - </function-decl> - <function-decl name='PyEval_GetFuncName' mangled-name='PyEval_GetFuncName' filepath='Python/ceval.c' line='7224' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyEval_GetFuncName'> - <parameter type-id='type-id-14' name='ob' filepath='Objects/exceptions.c' line='421' column='1'/> - <return type-id='type-id-3'/> - </function-decl> - <class-decl name='__anonymous_struct__' size-in-bits='64' is-struct='yes' is-anonymous='yes' naming-typedef-id='type-id-591' visibility='default' filepath='./Include/cpython/compile.h' line='26' column='1' id='type-id-592'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='cf_flags' type-id='type-id-8' visibility='default' filepath='./Include/cpython/compile.h' line='27' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='32'> - <var-decl name='cf_feature_version' type-id='type-id-8' visibility='default' filepath='./Include/cpython/compile.h' line='28' column='1'/> - </data-member> - </class-decl> - <typedef-decl name='PyCompilerFlags' type-id='type-id-592' filepath='./Include/cpython/compile.h' line='29' column='1' id='type-id-591'/> - <pointer-type-def type-id='type-id-591' size-in-bits='64' id='type-id-593'/> - <function-decl name='PyEval_MergeCompilerFlags' mangled-name='PyEval_MergeCompilerFlags' filepath='Python/ceval.c' line='7205' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyEval_MergeCompilerFlags'> - <parameter type-id='type-id-593' name='cf' filepath='Python/ceval.c' line='7205' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyEval_GetGlobals' mangled-name='PyEval_GetGlobals' filepath='Python/ceval.c' line='7194' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyEval_GetGlobals'> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyEval_GetLocals' mangled-name='PyEval_GetLocals' filepath='Python/ceval.c' line='7175' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyEval_GetLocals'> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyEval_GetBuiltinId' mangled-name='_PyEval_GetBuiltinId' filepath='Python/ceval.c' line='7169' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyEval_GetBuiltinId'> - <parameter type-id='type-id-499' name='name' filepath='Python/ceval.c' line='7169' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyEval_GetBuiltin' mangled-name='_PyEval_GetBuiltin' filepath='Python/ceval.c' line='7155' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyEval_GetBuiltin'> - <parameter type-id='type-id-14' name='v' filepath='Objects/abstract.c' line='2122' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyEval_GetBuiltins' mangled-name='PyEval_GetBuiltins' filepath='Python/ceval.c' line='7147' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyEval_GetBuiltins'> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyEval_GetFrame' mangled-name='PyEval_GetFrame' filepath='Python/ceval.c' line='7123' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyEval_GetFrame'> - <return type-id='type-id-438'/> - </function-decl> - <function-decl name='PyEval_SetTrace' mangled-name='PyEval_SetTrace' filepath='Python/ceval.c' line='7043' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyEval_SetTrace'> - <parameter type-id='type-id-13' name='func' filepath='Python/ceval.c' line='7043' column='1'/> - <parameter type-id='type-id-14' name='arg' filepath='Python/ceval.c' line='7043' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <class-decl name='_ts' size-in-bits='2880' is-struct='yes' visibility='default' filepath='./Include/cpython/pystate.h' line='82' column='1' id='type-id-594'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='prev' type-id='type-id-10' visibility='default' filepath='./Include/cpython/pystate.h' line='85' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='next' type-id='type-id-10' visibility='default' filepath='./Include/cpython/pystate.h' line='86' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='interp' type-id='type-id-11' visibility='default' filepath='./Include/cpython/pystate.h' line='87' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='_initialized' type-id='type-id-8' visibility='default' filepath='./Include/cpython/pystate.h' line='93' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='224'> - <var-decl name='_static' type-id='type-id-8' visibility='default' filepath='./Include/cpython/pystate.h' line='96' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='256'> - <var-decl name='recursion_remaining' type-id='type-id-8' visibility='default' filepath='./Include/cpython/pystate.h' line='98' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='288'> - <var-decl name='recursion_limit' type-id='type-id-8' visibility='default' filepath='./Include/cpython/pystate.h' line='99' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='320'> - <var-decl name='recursion_headroom' type-id='type-id-8' visibility='default' filepath='./Include/cpython/pystate.h' line='100' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='352'> - <var-decl name='tracing' type-id='type-id-8' visibility='default' filepath='./Include/cpython/pystate.h' line='105' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='384'> - <var-decl name='tracing_what' type-id='type-id-8' visibility='default' filepath='./Include/cpython/pystate.h' line='106' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='448'> - <var-decl name='cframe' type-id='type-id-595' visibility='default' filepath='./Include/cpython/pystate.h' line='110' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='512'> - <var-decl name='c_profilefunc' type-id='type-id-13' visibility='default' filepath='./Include/cpython/pystate.h' line='112' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='576'> - <var-decl name='c_tracefunc' type-id='type-id-13' visibility='default' filepath='./Include/cpython/pystate.h' line='113' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='640'> - <var-decl name='c_profileobj' type-id='type-id-14' visibility='default' filepath='./Include/cpython/pystate.h' line='114' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='704'> - <var-decl name='c_traceobj' type-id='type-id-14' visibility='default' filepath='./Include/cpython/pystate.h' line='115' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='768'> - <var-decl name='curexc_type' type-id='type-id-14' visibility='default' filepath='./Include/cpython/pystate.h' line='118' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='832'> - <var-decl name='curexc_value' type-id='type-id-14' visibility='default' filepath='./Include/cpython/pystate.h' line='119' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='896'> - <var-decl name='curexc_traceback' type-id='type-id-14' visibility='default' filepath='./Include/cpython/pystate.h' line='120' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='960'> - <var-decl name='exc_info' type-id='type-id-15' visibility='default' filepath='./Include/cpython/pystate.h' line='125' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1024'> - <var-decl name='dict' type-id='type-id-14' visibility='default' filepath='./Include/cpython/pystate.h' line='127' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1088'> - <var-decl name='gilstate_counter' type-id='type-id-8' visibility='default' filepath='./Include/cpython/pystate.h' line='129' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1152'> - <var-decl name='async_exc' type-id='type-id-14' visibility='default' filepath='./Include/cpython/pystate.h' line='131' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1216'> - <var-decl name='thread_id' type-id='type-id-16' visibility='default' filepath='./Include/cpython/pystate.h' line='132' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1280'> - <var-decl name='native_thread_id' type-id='type-id-16' visibility='default' filepath='./Include/cpython/pystate.h' line='138' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1344'> - <var-decl name='trash_delete_nesting' type-id='type-id-8' visibility='default' filepath='./Include/cpython/pystate.h' line='140' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1408'> - <var-decl name='trash_delete_later' type-id='type-id-14' visibility='default' filepath='./Include/cpython/pystate.h' line='141' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1472'> - <var-decl name='on_delete' type-id='type-id-17' visibility='default' filepath='./Include/cpython/pystate.h' line='166' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1536'> - <var-decl name='on_delete_data' type-id='type-id-18' visibility='default' filepath='./Include/cpython/pystate.h' line='167' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1600'> - <var-decl name='coroutine_origin_tracking_depth' type-id='type-id-8' visibility='default' filepath='./Include/cpython/pystate.h' line='169' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1664'> - <var-decl name='async_gen_firstiter' type-id='type-id-14' visibility='default' filepath='./Include/cpython/pystate.h' line='171' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1728'> - <var-decl name='async_gen_finalizer' type-id='type-id-14' visibility='default' filepath='./Include/cpython/pystate.h' line='172' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1792'> - <var-decl name='context' type-id='type-id-14' visibility='default' filepath='./Include/cpython/pystate.h' line='174' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1856'> - <var-decl name='context_ver' type-id='type-id-19' visibility='default' filepath='./Include/cpython/pystate.h' line='175' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1920'> - <var-decl name='id' type-id='type-id-19' visibility='default' filepath='./Include/cpython/pystate.h' line='178' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='1984'> - <var-decl name='trace_info' type-id='type-id-20' visibility='default' filepath='./Include/cpython/pystate.h' line='180' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='2368'> - <var-decl name='datastack_chunk' type-id='type-id-21' visibility='default' filepath='./Include/cpython/pystate.h' line='182' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='2432'> - <var-decl name='datastack_top' type-id='type-id-22' visibility='default' filepath='./Include/cpython/pystate.h' line='183' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='2496'> - <var-decl name='datastack_limit' type-id='type-id-22' visibility='default' filepath='./Include/cpython/pystate.h' line='184' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='2560'> - <var-decl name='exc_state' type-id='type-id-23' visibility='default' filepath='./Include/cpython/pystate.h' line='199' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='2688'> - <var-decl name='root_cframe' type-id='type-id-24' visibility='default' filepath='./Include/cpython/pystate.h' line='202' column='1'/> - </data-member> - </class-decl> - <pointer-type-def type-id='type-id-24' size-in-bits='64' id='type-id-595'/> - <function-decl name='_PyEval_SetTrace' mangled-name='_PyEval_SetTrace' filepath='Python/ceval.c' line='7000' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyEval_SetTrace'> - <parameter type-id='type-id-10' name='tstate' filepath='Python/ceval.c' line='7000' column='1'/> - <parameter type-id='type-id-13' name='func' filepath='Python/ceval.c' line='7000' column='1'/> - <parameter type-id='type-id-14' name='arg' filepath='Python/ceval.c' line='7000' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyEval_SetProfile' mangled-name='PyEval_SetProfile' filepath='Python/ceval.c' line='6990' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyEval_SetProfile'> - <parameter type-id='type-id-13' name='func' filepath='Python/ceval.c' line='7043' column='1'/> - <parameter type-id='type-id-14' name='arg' filepath='Python/ceval.c' line='7043' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_PyEval_SetProfile' mangled-name='_PyEval_SetProfile' filepath='Python/ceval.c' line='6948' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyEval_SetProfile'> - <parameter type-id='type-id-10' name='tstate' filepath='Python/ceval.c' line='7000' column='1'/> - <parameter type-id='type-id-13' name='func' filepath='Python/ceval.c' line='7000' column='1'/> - <parameter type-id='type-id-14' name='arg' filepath='Python/ceval.c' line='7000' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyThreadState_LeaveTracing' mangled-name='PyThreadState_LeaveTracing' filepath='Python/ceval.c' line='6852' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThreadState_LeaveTracing'> - <parameter type-id='type-id-10' name='tstate' filepath='Objects/object.c' line='2291' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyThreadState_EnterTracing' mangled-name='PyThreadState_EnterTracing' filepath='Python/ceval.c' line='6846' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThreadState_EnterTracing'> - <parameter type-id='type-id-10' name='tstate' filepath='Objects/object.c' line='2291' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyEval_EvalCodeEx' mangled-name='PyEval_EvalCodeEx' filepath='Python/ceval.c' line='6449' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyEval_EvalCodeEx'> - <parameter type-id='type-id-14' name='_co' filepath='Python/ceval.c' line='6449' column='1'/> - <parameter type-id='type-id-14' name='globals' filepath='Python/ceval.c' line='6449' column='1'/> - <parameter type-id='type-id-14' name='locals' filepath='Python/ceval.c' line='6449' column='1'/> - <parameter type-id='type-id-200' name='args' filepath='Python/ceval.c' line='6450' column='1'/> - <parameter type-id='type-id-8' name='argcount' filepath='Python/ceval.c' line='6450' column='1'/> - <parameter type-id='type-id-200' name='kws' filepath='Python/ceval.c' line='6451' column='1'/> - <parameter type-id='type-id-8' name='kwcount' filepath='Python/ceval.c' line='6451' column='1'/> - <parameter type-id='type-id-200' name='defs' filepath='Python/ceval.c' line='6452' column='1'/> - <parameter type-id='type-id-8' name='defcount' filepath='Python/ceval.c' line='6452' column='1'/> - <parameter type-id='type-id-14' name='kwdefs' filepath='Python/ceval.c' line='6453' column='1'/> - <parameter type-id='type-id-14' name='closure' filepath='Python/ceval.c' line='6453' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <typedef-decl name='_PyInterpreterFrame' type-id='type-id-375' filepath='./Include/internal/pycore_frame.h' line='67' column='1' id='type-id-596'/> - <pointer-type-def type-id='type-id-596' size-in-bits='64' id='type-id-597'/> - <function-decl name='_PyEval_EvalFrameDefault' mangled-name='_PyEval_EvalFrameDefault' filepath='Python/ceval.c' line='1647' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyEval_EvalFrameDefault'> - <parameter type-id='type-id-10' name='tstate' filepath='Python/ceval.c' line='1647' column='1'/> - <parameter type-id='type-id-597' name='frame' filepath='Python/ceval.c' line='1647' column='1'/> - <parameter type-id='type-id-8' name='throwflag' filepath='Python/ceval.c' line='1647' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyEval_EvalFrameEx' mangled-name='PyEval_EvalFrameEx' filepath='Python/ceval.c' line='1171' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyEval_EvalFrameEx'> - <parameter type-id='type-id-438' name='f' filepath='Python/ceval.c' line='1171' column='1'/> - <parameter type-id='type-id-8' name='throwflag' filepath='Python/ceval.c' line='1171' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyEval_EvalFrame' mangled-name='PyEval_EvalFrame' filepath='Python/ceval.c' line='1163' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyEval_EvalFrame'> - <parameter type-id='type-id-438' name='frame' filepath='Objects/frameobject.c' line='1207' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyEval_EvalCode' mangled-name='PyEval_EvalCode' filepath='Python/ceval.c' line='1130' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyEval_EvalCode'> - <parameter type-id='type-id-14' name='co' filepath='Python/ceval.c' line='1130' column='1'/> - <parameter type-id='type-id-14' name='globals' filepath='Python/ceval.c' line='1130' column='1'/> - <parameter type-id='type-id-14' name='locals' filepath='Python/ceval.c' line='1130' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_Py_CheckRecursiveCall' mangled-name='_Py_CheckRecursiveCall' filepath='Python/ceval.c' line='833' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_CheckRecursiveCall'> - <parameter type-id='type-id-10' name='tstate' filepath='Python/ceval.c' line='833' column='1'/> - <parameter type-id='type-id-3' name='where' filepath='Python/ceval.c' line='833' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='Py_SetRecursionLimit' mangled-name='Py_SetRecursionLimit' filepath='Python/ceval.c' line='819' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_SetRecursionLimit'> - <parameter type-id='type-id-8' name='new_limit' filepath='Python/ceval.c' line='819' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='Py_GetRecursionLimit' mangled-name='Py_GetRecursionLimit' filepath='Python/ceval.c' line='812' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_GetRecursionLimit'> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='Py_MakePendingCalls' mangled-name='Py_MakePendingCalls' filepath='Python/ceval.c' line='762' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_MakePendingCalls'> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='Py_AddPendingCall' mangled-name='Py_AddPendingCall' filepath='Python/ceval.c' line='641' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_AddPendingCall'> - <parameter type-id='type-id-364' name='func' filepath='Python/ceval.c' line='641' column='1'/> - <parameter type-id='type-id-18' name='arg' filepath='Python/ceval.c' line='641' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyEval_AddPendingCall' mangled-name='_PyEval_AddPendingCall' filepath='Python/ceval.c' line='622' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyEval_AddPendingCall'> - <parameter type-id='type-id-11' name='interp' filepath='Python/ceval.c' line='622' column='1'/> - <parameter type-id='type-id-364' name='func' filepath='Python/ceval.c' line='623' column='1'/> - <parameter type-id='type-id-18' name='arg' filepath='Python/ceval.c' line='623' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyEval_SignalReceived' mangled-name='_PyEval_SignalReceived' filepath='Python/ceval.c' line='565' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyEval_SignalReceived'> - <parameter type-id='type-id-11' name='interp' filepath='Python/ceval.c' line='565' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyEval_RestoreThread' mangled-name='PyEval_RestoreThread' filepath='Python/ceval.c' line='531' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyEval_RestoreThread'> - <parameter type-id='type-id-10' name='tstate' filepath='Python/ceval.c' line='531' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyEval_SaveThread' mangled-name='PyEval_SaveThread' filepath='Python/ceval.c' line='517' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyEval_SaveThread'> - <return type-id='type-id-10'/> - </function-decl> - <function-decl name='_PyEval_SignalAsyncExc' mangled-name='_PyEval_SignalAsyncExc' filepath='Python/ceval.c' line='511' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyEval_SignalAsyncExc'> - <parameter type-id='type-id-11' name='interp' filepath='Python/ceval.c' line='511' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyEval_ReleaseThread' mangled-name='PyEval_ReleaseThread' filepath='Python/ceval.c' line='465' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyEval_ReleaseThread'> - <parameter type-id='type-id-10' name='tstate' filepath='Python/ceval.c' line='465' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyEval_AcquireThread' mangled-name='PyEval_AcquireThread' filepath='Python/ceval.c' line='452' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyEval_AcquireThread'> - <parameter type-id='type-id-10' name='tstate' filepath='Python/ceval.c' line='531' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyEval_ReleaseLock' mangled-name='PyEval_ReleaseLock' filepath='Python/ceval.c' line='431' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyEval_ReleaseLock'> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyEval_AcquireLock' mangled-name='PyEval_AcquireLock' filepath='Python/ceval.c' line='421' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyEval_AcquireLock'> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyEval_InitThreads' mangled-name='PyEval_InitThreads' filepath='Python/ceval.c' line='407' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyEval_InitThreads'> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyEval_ThreadsInitialized' mangled-name='PyEval_ThreadsInitialized' filepath='Python/ceval.c' line='357' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyEval_ThreadsInitialized'> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_Py_FatalError_TstateNULL' mangled-name='_Py_FatalError_TstateNULL' filepath='Python/ceval.c' line='342' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_FatalError_TstateNULL'> - <parameter type-id='type-id-3' name='func' filepath='Python/ceval.c' line='342' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_PyEval_GetSwitchInterval' mangled-name='_PyEval_GetSwitchInterval' filepath='Python/ceval_gil.h' line='327' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyEval_GetSwitchInterval'> - <return type-id='type-id-16'/> - </function-decl> - <function-decl name='_PyEval_SetSwitchInterval' mangled-name='_PyEval_SetSwitchInterval' filepath='Python/ceval_gil.h' line='321' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyEval_SetSwitchInterval'> - <parameter type-id='type-id-16' name='microseconds' filepath='Python/ceval_gil.h' line='321' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Python/codecs.c' comp-dir-path='/src' language='LANG_C99'> - <var-decl name='Py_hexdigits' type-id='type-id-3' mangled-name='Py_hexdigits' visibility='default' filepath='./Include/codecs.h' line='242' column='1' elf-symbol-id='Py_hexdigits'/> - <function-decl name='PyCodec_NameReplaceErrors' mangled-name='PyCodec_NameReplaceErrors' filepath='Python/codecs.c' line='959' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCodec_NameReplaceErrors'> - <parameter type-id='type-id-14' name='exc' filepath='Python/codecs.c' line='959' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyCodec_BackslashReplaceErrors' mangled-name='PyCodec_BackslashReplaceErrors' filepath='Python/codecs.c' line='850' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCodec_BackslashReplaceErrors'> - <parameter type-id='type-id-14' name='exc' filepath='Python/codecs.c' line='850' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyCodec_XMLCharRefReplaceErrors' mangled-name='PyCodec_XMLCharRefReplaceErrors' filepath='Python/codecs.c' line='752' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCodec_XMLCharRefReplaceErrors'> - <parameter type-id='type-id-14' name='exc' filepath='Python/codecs.c' line='959' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyCodec_ReplaceErrors' mangled-name='PyCodec_ReplaceErrors' filepath='Python/codecs.c' line='699' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCodec_ReplaceErrors'> - <parameter type-id='type-id-14' name='o' filepath='Objects/dictobject.c' line='3013' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyCodec_IgnoreErrors' mangled-name='PyCodec_IgnoreErrors' filepath='Python/codecs.c' line='675' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCodec_IgnoreErrors'> - <parameter type-id='type-id-14' name='item' filepath='Objects/abstract.c' line='1408' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyCodec_StrictErrors' mangled-name='PyCodec_StrictErrors' filepath='Python/codecs.c' line='665' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCodec_StrictErrors'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2462' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyCodec_LookupError' mangled-name='PyCodec_LookupError' filepath='Python/codecs.c' line='638' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCodec_LookupError'> - <parameter type-id='type-id-3' name='str' filepath='Objects/bytesobject.c' line='147' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyCodec_RegisterError' mangled-name='PyCodec_RegisterError' filepath='Python/codecs.c' line='622' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCodec_RegisterError'> - <parameter type-id='type-id-3' name='name' filepath='Python/codecs.c' line='622' column='1'/> - <parameter type-id='type-id-14' name='error' filepath='Python/codecs.c' line='622' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyCodec_DecodeText' mangled-name='_PyCodec_DecodeText' filepath='Python/codecs.c' line='603' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyCodec_DecodeText'> - <parameter type-id='type-id-14' name='object' filepath='Python/codecs.c' line='603' column='1'/> - <parameter type-id='type-id-3' name='encoding' filepath='Python/codecs.c' line='604' column='1'/> - <parameter type-id='type-id-3' name='errors' filepath='Python/codecs.c' line='605' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyCodec_EncodeText' mangled-name='_PyCodec_EncodeText' filepath='Python/codecs.c' line='590' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyCodec_EncodeText'> - <parameter type-id='type-id-14' name='object' filepath='Python/codecs.c' line='603' column='1'/> - <parameter type-id='type-id-3' name='encoding' filepath='Python/codecs.c' line='604' column='1'/> - <parameter type-id='type-id-3' name='errors' filepath='Python/codecs.c' line='605' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyCodec_LookupTextEncoding' mangled-name='_PyCodec_LookupTextEncoding' filepath='Python/codecs.c' line='522' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyCodec_LookupTextEncoding'> - <parameter type-id='type-id-3' name='encoding' filepath='Python/codecs.c' line='522' column='1'/> - <parameter type-id='type-id-3' name='alternate_command' filepath='Python/codecs.c' line='523' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyCodec_Decode' mangled-name='PyCodec_Decode' filepath='Python/codecs.c' line='508' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCodec_Decode'> - <parameter type-id='type-id-14' name='object' filepath='Python/codecs.c' line='603' column='1'/> - <parameter type-id='type-id-3' name='encoding' filepath='Python/codecs.c' line='604' column='1'/> - <parameter type-id='type-id-3' name='errors' filepath='Python/codecs.c' line='605' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyCodec_Encode' mangled-name='PyCodec_Encode' filepath='Python/codecs.c' line='495' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCodec_Encode'> - <parameter type-id='type-id-14' name='object' filepath='Python/codecs.c' line='603' column='1'/> - <parameter type-id='type-id-3' name='encoding' filepath='Python/codecs.c' line='604' column='1'/> - <parameter type-id='type-id-3' name='errors' filepath='Python/codecs.c' line='605' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyCodec_StreamWriter' mangled-name='PyCodec_StreamWriter' filepath='Python/codecs.c' line='380' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCodec_StreamWriter'> - <parameter type-id='type-id-3' name='encoding' filepath='Python/codecs.c' line='380' column='1'/> - <parameter type-id='type-id-14' name='stream' filepath='Python/codecs.c' line='381' column='1'/> - <parameter type-id='type-id-3' name='errors' filepath='Python/codecs.c' line='382' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyCodec_StreamReader' mangled-name='PyCodec_StreamReader' filepath='Python/codecs.c' line='373' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCodec_StreamReader'> - <parameter type-id='type-id-3' name='encoding' filepath='Python/codecs.c' line='380' column='1'/> - <parameter type-id='type-id-14' name='stream' filepath='Python/codecs.c' line='381' column='1'/> - <parameter type-id='type-id-3' name='errors' filepath='Python/codecs.c' line='382' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyCodec_IncrementalDecoder' mangled-name='PyCodec_IncrementalDecoder' filepath='Python/codecs.c' line='367' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCodec_IncrementalDecoder'> - <parameter type-id='type-id-3' name='encoding' filepath='Python/codecs.c' line='367' column='1'/> - <parameter type-id='type-id-3' name='errors' filepath='Python/codecs.c' line='368' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyCodec_IncrementalEncoder' mangled-name='PyCodec_IncrementalEncoder' filepath='Python/codecs.c' line='361' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCodec_IncrementalEncoder'> - <parameter type-id='type-id-3' name='encoding' filepath='Python/codecs.c' line='367' column='1'/> - <parameter type-id='type-id-3' name='errors' filepath='Python/codecs.c' line='368' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyCodec_Decoder' mangled-name='PyCodec_Decoder' filepath='Python/codecs.c' line='356' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCodec_Decoder'> - <parameter type-id='type-id-3' name='encoding' filepath='Python/codecs.c' line='356' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyCodec_Encoder' mangled-name='PyCodec_Encoder' filepath='Python/codecs.c' line='351' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCodec_Encoder'> - <parameter type-id='type-id-3' name='encoding' filepath='Python/codecs.c' line='356' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyCodecInfo_GetIncrementalEncoder' mangled-name='_PyCodecInfo_GetIncrementalEncoder' filepath='Python/codecs.c' line='337' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyCodecInfo_GetIncrementalEncoder'> - <parameter type-id='type-id-14' name='unicode' filepath='Objects/unicodeobject.c' line='7356' column='1'/> - <parameter type-id='type-id-3' name='errors' filepath='Objects/unicodeobject.c' line='7356' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyCodecInfo_GetIncrementalDecoder' mangled-name='_PyCodecInfo_GetIncrementalDecoder' filepath='Python/codecs.c' line='330' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyCodecInfo_GetIncrementalDecoder'> - <parameter type-id='type-id-14' name='unicode' filepath='Objects/unicodeobject.c' line='7356' column='1'/> - <parameter type-id='type-id-3' name='errors' filepath='Objects/unicodeobject.c' line='7356' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyCodec_KnownEncoding' mangled-name='PyCodec_KnownEncoding' filepath='Python/codecs.c' line='214' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCodec_KnownEncoding'> - <parameter type-id='type-id-3' name='encoding' filepath='Python/codecs.c' line='214' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyCodec_Lookup' mangled-name='_PyCodec_Lookup' filepath='Python/codecs.c' line='127' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyCodec_Lookup'> - <parameter type-id='type-id-3' name='encoding' filepath='Python/codecs.c' line='127' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyCodec_Unregister' mangled-name='PyCodec_Unregister' filepath='Python/codecs.c' line='55' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCodec_Unregister'> - <parameter type-id='type-id-14' name='search_function' filepath='Python/codecs.c' line='55' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyCodec_Register' mangled-name='PyCodec_Register' filepath='Python/codecs.c' line='35' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCodec_Register'> - <parameter type-id='type-id-14' name='search_function' filepath='Python/codecs.c' line='35' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Python/compile.c' comp-dir-path='/src' language='LANG_C99'> - - <array-type-def dimensions='1' type-id='type-id-451' size-in-bits='2048' id='type-id-598'> - <subrange length='256' type-id='type-id-16' id='type-id-264'/> - - </array-type-def> - <qualified-type-def type-id='type-id-598' const='yes' id='type-id-599'/> - <var-decl name='_PyOpcode_Caches' type-id='type-id-599' visibility='default' filepath='./Include/internal/pycore_opcode.h' line='15' column='1'/> - <var-decl name='_PyOpcode_Deopt' type-id='type-id-599' visibility='default' filepath='./Include/internal/pycore_opcode.h' line='17' column='1'/> - <function-decl name='PyCode_Optimize' mangled-name='PyCode_Optimize' filepath='Python/compile.c' line='9389' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCode_Optimize'> - <parameter type-id='type-id-14' name='code' filepath='Python/compile.c' line='9389' column='1'/> - <parameter type-id='type-id-14' name='_unused_consts' filepath='Python/compile.c' line='9389' column='1'/> - <parameter type-id='type-id-14' name='_unused_names' filepath='Python/compile.c' line='9390' column='1'/> - <parameter type-id='type-id-14' name='_unused_lnotab_obj' filepath='Python/compile.c' line='9390' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyCompile_OpcodeStackEffect' mangled-name='PyCompile_OpcodeStackEffect' filepath='Python/compile.c' line='1206' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCompile_OpcodeStackEffect'> - <parameter type-id='type-id-8' name='c1' filepath='Parser/token.c' line='110' column='1'/> - <parameter type-id='type-id-8' name='c2' filepath='Parser/token.c' line='110' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyCompile_OpcodeStackEffectWithJump' mangled-name='PyCompile_OpcodeStackEffectWithJump' filepath='Python/compile.c' line='1200' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCompile_OpcodeStackEffectWithJump'> - <parameter type-id='type-id-8' name='c1' filepath='Parser/token.c' line='194' column='1'/> - <parameter type-id='type-id-8' name='c2' filepath='Parser/token.c' line='194' column='1'/> - <parameter type-id='type-id-8' name='c3' filepath='Parser/token.c' line='194' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <class-decl name='_mod' size-in-bits='192' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='153' column='1' id='type-id-600'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='kind' type-id='type-id-601' visibility='default' filepath='./Include/internal/pycore_ast.h' line='154' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='v' type-id='type-id-602' visibility='default' filepath='./Include/internal/pycore_ast.h' line='174' column='1'/> - </data-member> - </class-decl> - <enum-decl name='_mod_kind' filepath='./Include/internal/pycore_ast.h' line='151' column='1' id='type-id-601'> - <underlying-type type-id='type-id-126'/> - <enumerator name='Module_kind' value='1'/> - <enumerator name='Interactive_kind' value='2'/> - <enumerator name='Expression_kind' value='3'/> - <enumerator name='FunctionType_kind' value='4'/> - </enum-decl> - <union-decl name='__anonymous_union__' size-in-bits='128' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='155' column='1' id='type-id-602'> - <data-member access='private'> - <var-decl name='Module' type-id='type-id-603' visibility='default' filepath='./Include/internal/pycore_ast.h' line='159' column='1'/> - </data-member> - <data-member access='private'> - <var-decl name='Interactive' type-id='type-id-604' visibility='default' filepath='./Include/internal/pycore_ast.h' line='163' column='1'/> - </data-member> - <data-member access='private'> - <var-decl name='Expression' type-id='type-id-605' visibility='default' filepath='./Include/internal/pycore_ast.h' line='167' column='1'/> - </data-member> - <data-member access='private'> - <var-decl name='FunctionType' type-id='type-id-606' visibility='default' filepath='./Include/internal/pycore_ast.h' line='172' column='1'/> - </data-member> - </union-decl> - <class-decl name='__anonymous_struct__' size-in-bits='128' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='156' column='1' id='type-id-603'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='body' type-id='type-id-607' visibility='default' filepath='./Include/internal/pycore_ast.h' line='157' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='type_ignores' type-id='type-id-608' visibility='default' filepath='./Include/internal/pycore_ast.h' line='158' column='1'/> - </data-member> - </class-decl> - <class-decl name='__anonymous_struct__' size-in-bits='192' is-struct='yes' is-anonymous='yes' naming-typedef-id='type-id-609' visibility='default' filepath='./Include/internal/pycore_ast.h' line='62' column='1' id='type-id-610'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='size' type-id='type-id-36' visibility='default' filepath='./Include/internal/pycore_ast.h' line='63' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='elements' type-id='type-id-482' visibility='default' filepath='./Include/internal/pycore_ast.h' line='63' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='typed_elements' type-id='type-id-611' visibility='default' filepath='./Include/internal/pycore_ast.h' line='64' column='1'/> - </data-member> - </class-decl> - <class-decl name='_stmt' size-in-bits='576' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='185' column='1' id='type-id-612'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='kind' type-id='type-id-613' visibility='default' filepath='./Include/internal/pycore_ast.h' line='186' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='v' type-id='type-id-614' visibility='default' filepath='./Include/internal/pycore_ast.h' line='332' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='448'> - <var-decl name='lineno' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='333' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='480'> - <var-decl name='col_offset' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='334' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='512'> - <var-decl name='end_lineno' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='335' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='544'> - <var-decl name='end_col_offset' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='336' column='1'/> - </data-member> - </class-decl> - <enum-decl name='_stmt_kind' filepath='./Include/internal/pycore_ast.h' line='177' column='1' id='type-id-613'> - <underlying-type type-id='type-id-126'/> - <enumerator name='FunctionDef_kind' value='1'/> - <enumerator name='AsyncFunctionDef_kind' value='2'/> - <enumerator name='ClassDef_kind' value='3'/> - <enumerator name='Return_kind' value='4'/> - <enumerator name='Delete_kind' value='5'/> - <enumerator name='Assign_kind' value='6'/> - <enumerator name='AugAssign_kind' value='7'/> - <enumerator name='AnnAssign_kind' value='8'/> - <enumerator name='For_kind' value='9'/> - <enumerator name='AsyncFor_kind' value='10'/> - <enumerator name='While_kind' value='11'/> - <enumerator name='If_kind' value='12'/> - <enumerator name='With_kind' value='13'/> - <enumerator name='AsyncWith_kind' value='14'/> - <enumerator name='Match_kind' value='15'/> - <enumerator name='Raise_kind' value='16'/> - <enumerator name='Try_kind' value='17'/> - <enumerator name='TryStar_kind' value='18'/> - <enumerator name='Assert_kind' value='19'/> - <enumerator name='Import_kind' value='20'/> - <enumerator name='ImportFrom_kind' value='21'/> - <enumerator name='Global_kind' value='22'/> - <enumerator name='Nonlocal_kind' value='23'/> - <enumerator name='Expr_kind' value='24'/> - <enumerator name='Pass_kind' value='25'/> - <enumerator name='Break_kind' value='26'/> - <enumerator name='Continue_kind' value='27'/> - </enum-decl> - <union-decl name='__anonymous_union__' size-in-bits='384' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='187' column='1' id='type-id-614'> - <data-member access='private'> - <var-decl name='FunctionDef' type-id='type-id-615' visibility='default' filepath='./Include/internal/pycore_ast.h' line='195' column='1'/> - </data-member> - <data-member access='private'> - <var-decl name='AsyncFunctionDef' type-id='type-id-615' visibility='default' filepath='./Include/internal/pycore_ast.h' line='204' column='1'/> - </data-member> - <data-member access='private'> - <var-decl name='ClassDef' type-id='type-id-616' visibility='default' filepath='./Include/internal/pycore_ast.h' line='212' column='1'/> - </data-member> - <data-member access='private'> - <var-decl name='Return' type-id='type-id-617' visibility='default' filepath='./Include/internal/pycore_ast.h' line='216' column='1'/> - </data-member> - <data-member access='private'> - <var-decl name='Delete' type-id='type-id-618' visibility='default' filepath='./Include/internal/pycore_ast.h' line='220' column='1'/> - </data-member> - <data-member access='private'> - <var-decl name='Assign' type-id='type-id-619' visibility='default' filepath='./Include/internal/pycore_ast.h' line='226' column='1'/> - </data-member> - <data-member access='private'> - <var-decl name='AugAssign' type-id='type-id-620' visibility='default' filepath='./Include/internal/pycore_ast.h' line='232' column='1'/> - </data-member> - <data-member access='private'> - <var-decl name='AnnAssign' type-id='type-id-621' visibility='default' filepath='./Include/internal/pycore_ast.h' line='239' column='1'/> - </data-member> - <data-member access='private'> - <var-decl name='For' type-id='type-id-622' visibility='default' filepath='./Include/internal/pycore_ast.h' line='247' column='1'/> - </data-member> - <data-member access='private'> - <var-decl name='AsyncFor' type-id='type-id-622' visibility='default' filepath='./Include/internal/pycore_ast.h' line='255' column='1'/> - </data-member> - <data-member access='private'> - <var-decl name='While' type-id='type-id-623' visibility='default' filepath='./Include/internal/pycore_ast.h' line='261' column='1'/> - </data-member> - <data-member access='private'> - <var-decl name='If' type-id='type-id-623' visibility='default' filepath='./Include/internal/pycore_ast.h' line='267' column='1'/> - </data-member> - <data-member access='private'> - <var-decl name='With' type-id='type-id-624' visibility='default' filepath='./Include/internal/pycore_ast.h' line='273' column='1'/> - </data-member> - <data-member access='private'> - <var-decl name='AsyncWith' type-id='type-id-624' visibility='default' filepath='./Include/internal/pycore_ast.h' line='279' column='1'/> - </data-member> - <data-member access='private'> - <var-decl name='Match' type-id='type-id-625' visibility='default' filepath='./Include/internal/pycore_ast.h' line='284' column='1'/> - </data-member> - <data-member access='private'> - <var-decl name='Raise' type-id='type-id-626' visibility='default' filepath='./Include/internal/pycore_ast.h' line='289' column='1'/> - </data-member> - <data-member access='private'> - <var-decl name='Try' type-id='type-id-627' visibility='default' filepath='./Include/internal/pycore_ast.h' line='296' column='1'/> - </data-member> - <data-member access='private'> - <var-decl name='TryStar' type-id='type-id-627' visibility='default' filepath='./Include/internal/pycore_ast.h' line='303' column='1'/> - </data-member> - <data-member access='private'> - <var-decl name='Assert' type-id='type-id-628' visibility='default' filepath='./Include/internal/pycore_ast.h' line='308' column='1'/> - </data-member> - <data-member access='private'> - <var-decl name='Import' type-id='type-id-629' visibility='default' filepath='./Include/internal/pycore_ast.h' line='312' column='1'/> - </data-member> - <data-member access='private'> - <var-decl name='ImportFrom' type-id='type-id-630' visibility='default' filepath='./Include/internal/pycore_ast.h' line='318' column='1'/> - </data-member> - <data-member access='private'> - <var-decl name='Global' type-id='type-id-631' visibility='default' filepath='./Include/internal/pycore_ast.h' line='322' column='1'/> - </data-member> - <data-member access='private'> - <var-decl name='Nonlocal' type-id='type-id-631' visibility='default' filepath='./Include/internal/pycore_ast.h' line='326' column='1'/> - </data-member> - <data-member access='private'> - <var-decl name='Expr' type-id='type-id-617' visibility='default' filepath='./Include/internal/pycore_ast.h' line='330' column='1'/> - </data-member> - </union-decl> - <class-decl name='__anonymous_struct__' size-in-bits='384' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='188' column='1' id='type-id-615'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='name' type-id='type-id-632' visibility='default' filepath='./Include/internal/pycore_ast.h' line='189' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='args' type-id='type-id-633' visibility='default' filepath='./Include/internal/pycore_ast.h' line='190' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='body' type-id='type-id-607' visibility='default' filepath='./Include/internal/pycore_ast.h' line='191' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='decorator_list' type-id='type-id-634' visibility='default' filepath='./Include/internal/pycore_ast.h' line='192' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='256'> - <var-decl name='returns' type-id='type-id-635' visibility='default' filepath='./Include/internal/pycore_ast.h' line='193' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='320'> - <var-decl name='type_comment' type-id='type-id-636' visibility='default' filepath='./Include/internal/pycore_ast.h' line='194' column='1'/> - </data-member> - </class-decl> - <typedef-decl name='identifier' type-id='type-id-14' filepath='./Include/internal/pycore_asdl.h' line='13' column='1' id='type-id-632'/> - <class-decl name='_arguments' size-in-bits='448' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='520' column='1' id='type-id-637'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='posonlyargs' type-id='type-id-638' visibility='default' filepath='./Include/internal/pycore_ast.h' line='521' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='args' type-id='type-id-638' visibility='default' filepath='./Include/internal/pycore_ast.h' line='522' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='vararg' type-id='type-id-639' visibility='default' filepath='./Include/internal/pycore_ast.h' line='523' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='kwonlyargs' type-id='type-id-638' visibility='default' filepath='./Include/internal/pycore_ast.h' line='524' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='256'> - <var-decl name='kw_defaults' type-id='type-id-634' visibility='default' filepath='./Include/internal/pycore_ast.h' line='525' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='320'> - <var-decl name='kwarg' type-id='type-id-639' visibility='default' filepath='./Include/internal/pycore_ast.h' line='526' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='384'> - <var-decl name='defaults' type-id='type-id-634' visibility='default' filepath='./Include/internal/pycore_ast.h' line='527' column='1'/> - </data-member> - </class-decl> - <class-decl name='__anonymous_struct__' size-in-bits='192' is-struct='yes' is-anonymous='yes' naming-typedef-id='type-id-640' visibility='default' filepath='./Include/internal/pycore_ast.h' line='99' column='1' id='type-id-641'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='size' type-id='type-id-36' visibility='default' filepath='./Include/internal/pycore_ast.h' line='100' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='elements' type-id='type-id-482' visibility='default' filepath='./Include/internal/pycore_ast.h' line='100' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='typed_elements' type-id='type-id-642' visibility='default' filepath='./Include/internal/pycore_ast.h' line='101' column='1'/> - </data-member> - </class-decl> - <class-decl name='_arg' size-in-bits='320' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='530' column='1' id='type-id-643'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='arg' type-id='type-id-632' visibility='default' filepath='./Include/internal/pycore_ast.h' line='531' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='annotation' type-id='type-id-635' visibility='default' filepath='./Include/internal/pycore_ast.h' line='532' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='type_comment' type-id='type-id-636' visibility='default' filepath='./Include/internal/pycore_ast.h' line='533' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='lineno' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='534' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='224'> - <var-decl name='col_offset' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='535' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='256'> - <var-decl name='end_lineno' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='536' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='288'> - <var-decl name='end_col_offset' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='537' column='1'/> - </data-member> - </class-decl> - <class-decl name='_expr' size-in-bits='384' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='347' column='1' id='type-id-644'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='kind' type-id='type-id-645' visibility='default' filepath='./Include/internal/pycore_ast.h' line='348' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='v' type-id='type-id-646' visibility='default' filepath='./Include/internal/pycore_ast.h' line='489' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='256'> - <var-decl name='lineno' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='490' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='288'> - <var-decl name='col_offset' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='491' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='320'> - <var-decl name='end_lineno' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='492' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='352'> - <var-decl name='end_col_offset' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='493' column='1'/> - </data-member> - </class-decl> - <enum-decl name='_expr_kind' filepath='./Include/internal/pycore_ast.h' line='339' column='1' id='type-id-645'> - <underlying-type type-id='type-id-126'/> - <enumerator name='BoolOp_kind' value='1'/> - <enumerator name='NamedExpr_kind' value='2'/> - <enumerator name='BinOp_kind' value='3'/> - <enumerator name='UnaryOp_kind' value='4'/> - <enumerator name='Lambda_kind' value='5'/> - <enumerator name='IfExp_kind' value='6'/> - <enumerator name='Dict_kind' value='7'/> - <enumerator name='Set_kind' value='8'/> - <enumerator name='ListComp_kind' value='9'/> - <enumerator name='SetComp_kind' value='10'/> - <enumerator name='DictComp_kind' value='11'/> - <enumerator name='GeneratorExp_kind' value='12'/> - <enumerator name='Await_kind' value='13'/> - <enumerator name='Yield_kind' value='14'/> - <enumerator name='YieldFrom_kind' value='15'/> - <enumerator name='Compare_kind' value='16'/> - <enumerator name='Call_kind' value='17'/> - <enumerator name='FormattedValue_kind' value='18'/> - <enumerator name='JoinedStr_kind' value='19'/> - <enumerator name='Constant_kind' value='20'/> - <enumerator name='Attribute_kind' value='21'/> - <enumerator name='Subscript_kind' value='22'/> - <enumerator name='Starred_kind' value='23'/> - <enumerator name='Name_kind' value='24'/> - <enumerator name='List_kind' value='25'/> - <enumerator name='Tuple_kind' value='26'/> - <enumerator name='Slice_kind' value='27'/> - </enum-decl> - <union-decl name='__anonymous_union__' size-in-bits='192' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='349' column='1' id='type-id-646'> - <data-member access='private'> - <var-decl name='BoolOp' type-id='type-id-647' visibility='default' filepath='./Include/internal/pycore_ast.h' line='353' column='1'/> - </data-member> - <data-member access='private'> - <var-decl name='NamedExpr' type-id='type-id-648' visibility='default' filepath='./Include/internal/pycore_ast.h' line='358' column='1'/> - </data-member> - <data-member access='private'> - <var-decl name='BinOp' type-id='type-id-649' visibility='default' filepath='./Include/internal/pycore_ast.h' line='364' column='1'/> - </data-member> - <data-member access='private'> - <var-decl name='UnaryOp' type-id='type-id-650' visibility='default' filepath='./Include/internal/pycore_ast.h' line='369' column='1'/> - </data-member> - <data-member access='private'> - <var-decl name='Lambda' type-id='type-id-651' visibility='default' filepath='./Include/internal/pycore_ast.h' line='374' column='1'/> - </data-member> - <data-member access='private'> - <var-decl name='IfExp' type-id='type-id-652' visibility='default' filepath='./Include/internal/pycore_ast.h' line='380' column='1'/> - </data-member> - <data-member access='private'> - <var-decl name='Dict' type-id='type-id-653' visibility='default' filepath='./Include/internal/pycore_ast.h' line='385' column='1'/> - </data-member> - <data-member access='private'> - <var-decl name='Set' type-id='type-id-654' visibility='default' filepath='./Include/internal/pycore_ast.h' line='389' column='1'/> - </data-member> - <data-member access='private'> - <var-decl name='ListComp' type-id='type-id-655' visibility='default' filepath='./Include/internal/pycore_ast.h' line='394' column='1'/> - </data-member> - <data-member access='private'> - <var-decl name='SetComp' type-id='type-id-655' visibility='default' filepath='./Include/internal/pycore_ast.h' line='399' column='1'/> - </data-member> - <data-member access='private'> - <var-decl name='DictComp' type-id='type-id-656' visibility='default' filepath='./Include/internal/pycore_ast.h' line='405' column='1'/> - </data-member> - <data-member access='private'> - <var-decl name='GeneratorExp' type-id='type-id-655' visibility='default' filepath='./Include/internal/pycore_ast.h' line='410' column='1'/> - </data-member> - <data-member access='private'> - <var-decl name='Await' type-id='type-id-617' visibility='default' filepath='./Include/internal/pycore_ast.h' line='414' column='1'/> - </data-member> - <data-member access='private'> - <var-decl name='Yield' type-id='type-id-617' visibility='default' filepath='./Include/internal/pycore_ast.h' line='418' column='1'/> - </data-member> - <data-member access='private'> - <var-decl name='YieldFrom' type-id='type-id-617' visibility='default' filepath='./Include/internal/pycore_ast.h' line='422' column='1'/> - </data-member> - <data-member access='private'> - <var-decl name='Compare' type-id='type-id-657' visibility='default' filepath='./Include/internal/pycore_ast.h' line='428' column='1'/> - </data-member> - <data-member access='private'> - <var-decl name='Call' type-id='type-id-658' visibility='default' filepath='./Include/internal/pycore_ast.h' line='434' column='1'/> - </data-member> - <data-member access='private'> - <var-decl name='FormattedValue' type-id='type-id-659' visibility='default' filepath='./Include/internal/pycore_ast.h' line='440' column='1'/> - </data-member> - <data-member access='private'> - <var-decl name='JoinedStr' type-id='type-id-660' visibility='default' filepath='./Include/internal/pycore_ast.h' line='444' column='1'/> - </data-member> - <data-member access='private'> - <var-decl name='Constant' type-id='type-id-661' visibility='default' filepath='./Include/internal/pycore_ast.h' line='449' column='1'/> - </data-member> - <data-member access='private'> - <var-decl name='Attribute' type-id='type-id-662' visibility='default' filepath='./Include/internal/pycore_ast.h' line='455' column='1'/> - </data-member> - <data-member access='private'> - <var-decl name='Subscript' type-id='type-id-663' visibility='default' filepath='./Include/internal/pycore_ast.h' line='461' column='1'/> - </data-member> - <data-member access='private'> - <var-decl name='Starred' type-id='type-id-664' visibility='default' filepath='./Include/internal/pycore_ast.h' line='466' column='1'/> - </data-member> - <data-member access='private'> - <var-decl name='Name' type-id='type-id-665' visibility='default' filepath='./Include/internal/pycore_ast.h' line='471' column='1'/> - </data-member> - <data-member access='private'> - <var-decl name='List' type-id='type-id-666' visibility='default' filepath='./Include/internal/pycore_ast.h' line='476' column='1'/> - </data-member> - <data-member access='private'> - <var-decl name='Tuple' type-id='type-id-666' visibility='default' filepath='./Include/internal/pycore_ast.h' line='481' column='1'/> - </data-member> - <data-member access='private'> - <var-decl name='Slice' type-id='type-id-667' visibility='default' filepath='./Include/internal/pycore_ast.h' line='487' column='1'/> - </data-member> - </union-decl> - <class-decl name='__anonymous_struct__' size-in-bits='128' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='350' column='1' id='type-id-647'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='op' type-id='type-id-668' visibility='default' filepath='./Include/internal/pycore_ast.h' line='351' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='values' type-id='type-id-634' visibility='default' filepath='./Include/internal/pycore_ast.h' line='352' column='1'/> - </data-member> - </class-decl> - <enum-decl name='_boolop' filepath='./Include/internal/pycore_ast.h' line='23' column='1' id='type-id-669'> - <underlying-type type-id='type-id-126'/> - <enumerator name='And' value='1'/> - <enumerator name='Or' value='2'/> - </enum-decl> - <typedef-decl name='boolop_ty' type-id='type-id-669' filepath='./Include/internal/pycore_ast.h' line='23' column='1' id='type-id-668'/> - <class-decl name='__anonymous_struct__' size-in-bits='192' is-struct='yes' is-anonymous='yes' naming-typedef-id='type-id-670' visibility='default' filepath='./Include/internal/pycore_ast.h' line='69' column='1' id='type-id-671'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='size' type-id='type-id-36' visibility='default' filepath='./Include/internal/pycore_ast.h' line='70' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='elements' type-id='type-id-482' visibility='default' filepath='./Include/internal/pycore_ast.h' line='70' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='typed_elements' type-id='type-id-672' visibility='default' filepath='./Include/internal/pycore_ast.h' line='71' column='1'/> - </data-member> - </class-decl> - <pointer-type-def type-id='type-id-644' size-in-bits='64' id='type-id-673'/> - <typedef-decl name='expr_ty' type-id='type-id-673' filepath='./Include/internal/pycore_ast.h' line='19' column='1' id='type-id-635'/> - - <array-type-def dimensions='1' type-id='type-id-635' size-in-bits='64' id='type-id-672'> - <subrange length='1' type-id='type-id-16' id='type-id-258'/> - - </array-type-def> - <typedef-decl name='asdl_expr_seq' type-id='type-id-671' filepath='./Include/internal/pycore_ast.h' line='72' column='1' id='type-id-670'/> - <pointer-type-def type-id='type-id-670' size-in-bits='64' id='type-id-634'/> - <class-decl name='__anonymous_struct__' size-in-bits='128' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='355' column='1' id='type-id-648'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='target' type-id='type-id-635' visibility='default' filepath='./Include/internal/pycore_ast.h' line='356' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='value' type-id='type-id-635' visibility='default' filepath='./Include/internal/pycore_ast.h' line='357' column='1'/> - </data-member> - </class-decl> - <class-decl name='__anonymous_struct__' size-in-bits='192' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='360' column='1' id='type-id-649'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='left' type-id='type-id-635' visibility='default' filepath='./Include/internal/pycore_ast.h' line='361' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='op' type-id='type-id-674' visibility='default' filepath='./Include/internal/pycore_ast.h' line='362' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='right' type-id='type-id-635' visibility='default' filepath='./Include/internal/pycore_ast.h' line='363' column='1'/> - </data-member> - </class-decl> - <enum-decl name='_operator' filepath='./Include/internal/pycore_ast.h' line='25' column='1' id='type-id-675'> - <underlying-type type-id='type-id-126'/> - <enumerator name='Add' value='1'/> - <enumerator name='Sub' value='2'/> - <enumerator name='Mult' value='3'/> - <enumerator name='MatMult' value='4'/> - <enumerator name='Div' value='5'/> - <enumerator name='Mod' value='6'/> - <enumerator name='Pow' value='7'/> - <enumerator name='LShift' value='8'/> - <enumerator name='RShift' value='9'/> - <enumerator name='BitOr' value='10'/> - <enumerator name='BitXor' value='11'/> - <enumerator name='BitAnd' value='12'/> - <enumerator name='FloorDiv' value='13'/> - </enum-decl> - <typedef-decl name='operator_ty' type-id='type-id-675' filepath='./Include/internal/pycore_ast.h' line='27' column='1' id='type-id-674'/> - <class-decl name='__anonymous_struct__' size-in-bits='128' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='366' column='1' id='type-id-650'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='op' type-id='type-id-676' visibility='default' filepath='./Include/internal/pycore_ast.h' line='367' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='operand' type-id='type-id-635' visibility='default' filepath='./Include/internal/pycore_ast.h' line='368' column='1'/> - </data-member> - </class-decl> - <enum-decl name='_unaryop' filepath='./Include/internal/pycore_ast.h' line='29' column='1' id='type-id-677'> - <underlying-type type-id='type-id-126'/> - <enumerator name='Invert' value='1'/> - <enumerator name='Not' value='2'/> - <enumerator name='UAdd' value='3'/> - <enumerator name='USub' value='4'/> - </enum-decl> - <typedef-decl name='unaryop_ty' type-id='type-id-677' filepath='./Include/internal/pycore_ast.h' line='29' column='1' id='type-id-676'/> - <class-decl name='__anonymous_struct__' size-in-bits='128' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='371' column='1' id='type-id-651'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='args' type-id='type-id-633' visibility='default' filepath='./Include/internal/pycore_ast.h' line='372' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='body' type-id='type-id-635' visibility='default' filepath='./Include/internal/pycore_ast.h' line='373' column='1'/> - </data-member> - </class-decl> - <pointer-type-def type-id='type-id-637' size-in-bits='64' id='type-id-678'/> - <typedef-decl name='arguments_ty' type-id='type-id-678' filepath='./Include/internal/pycore_ast.h' line='38' column='1' id='type-id-633'/> - <class-decl name='__anonymous_struct__' size-in-bits='192' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='376' column='1' id='type-id-652'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='test' type-id='type-id-635' visibility='default' filepath='./Include/internal/pycore_ast.h' line='377' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='body' type-id='type-id-635' visibility='default' filepath='./Include/internal/pycore_ast.h' line='378' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='orelse' type-id='type-id-635' visibility='default' filepath='./Include/internal/pycore_ast.h' line='379' column='1'/> - </data-member> - </class-decl> - <class-decl name='__anonymous_struct__' size-in-bits='128' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='382' column='1' id='type-id-653'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='keys' type-id='type-id-634' visibility='default' filepath='./Include/internal/pycore_ast.h' line='383' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='values' type-id='type-id-634' visibility='default' filepath='./Include/internal/pycore_ast.h' line='384' column='1'/> - </data-member> - </class-decl> - <class-decl name='__anonymous_struct__' size-in-bits='64' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='387' column='1' id='type-id-654'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='elts' type-id='type-id-634' visibility='default' filepath='./Include/internal/pycore_ast.h' line='388' column='1'/> - </data-member> - </class-decl> - <class-decl name='__anonymous_struct__' size-in-bits='128' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='391' column='1' id='type-id-655'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='elt' type-id='type-id-635' visibility='default' filepath='./Include/internal/pycore_ast.h' line='392' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='generators' type-id='type-id-679' visibility='default' filepath='./Include/internal/pycore_ast.h' line='393' column='1'/> - </data-member> - </class-decl> - <class-decl name='__anonymous_struct__' size-in-bits='192' is-struct='yes' is-anonymous='yes' naming-typedef-id='type-id-680' visibility='default' filepath='./Include/internal/pycore_ast.h' line='76' column='1' id='type-id-681'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='size' type-id='type-id-36' visibility='default' filepath='./Include/internal/pycore_ast.h' line='77' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='elements' type-id='type-id-482' visibility='default' filepath='./Include/internal/pycore_ast.h' line='77' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='typed_elements' type-id='type-id-682' visibility='default' filepath='./Include/internal/pycore_ast.h' line='78' column='1'/> - </data-member> - </class-decl> - <class-decl name='_comprehension' size-in-bits='256' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='496' column='1' id='type-id-683'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='target' type-id='type-id-635' visibility='default' filepath='./Include/internal/pycore_ast.h' line='497' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='iter' type-id='type-id-635' visibility='default' filepath='./Include/internal/pycore_ast.h' line='498' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='ifs' type-id='type-id-634' visibility='default' filepath='./Include/internal/pycore_ast.h' line='499' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='is_async' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='500' column='1'/> - </data-member> - </class-decl> - <pointer-type-def type-id='type-id-683' size-in-bits='64' id='type-id-684'/> - <typedef-decl name='comprehension_ty' type-id='type-id-684' filepath='./Include/internal/pycore_ast.h' line='34' column='1' id='type-id-685'/> - - <array-type-def dimensions='1' type-id='type-id-685' size-in-bits='64' id='type-id-682'> - <subrange length='1' type-id='type-id-16' id='type-id-258'/> - - </array-type-def> - <typedef-decl name='asdl_comprehension_seq' type-id='type-id-681' filepath='./Include/internal/pycore_ast.h' line='79' column='1' id='type-id-680'/> - <pointer-type-def type-id='type-id-680' size-in-bits='64' id='type-id-679'/> - <class-decl name='__anonymous_struct__' size-in-bits='192' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='401' column='1' id='type-id-656'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='key' type-id='type-id-635' visibility='default' filepath='./Include/internal/pycore_ast.h' line='402' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='value' type-id='type-id-635' visibility='default' filepath='./Include/internal/pycore_ast.h' line='403' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='generators' type-id='type-id-679' visibility='default' filepath='./Include/internal/pycore_ast.h' line='404' column='1'/> - </data-member> - </class-decl> - <class-decl name='__anonymous_struct__' size-in-bits='64' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='412' column='1' id='type-id-617'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='value' type-id='type-id-635' visibility='default' filepath='./Include/internal/pycore_ast.h' line='413' column='1'/> - </data-member> - </class-decl> - <class-decl name='__anonymous_struct__' size-in-bits='192' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='424' column='1' id='type-id-657'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='left' type-id='type-id-635' visibility='default' filepath='./Include/internal/pycore_ast.h' line='425' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='ops' type-id='type-id-686' visibility='default' filepath='./Include/internal/pycore_ast.h' line='426' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='comparators' type-id='type-id-634' visibility='default' filepath='./Include/internal/pycore_ast.h' line='427' column='1'/> - </data-member> - </class-decl> - <class-decl name='__anonymous_struct__' size-in-bits='192' is-struct='yes' is-anonymous='yes' naming-typedef-id='type-id-687' visibility='default' filepath='./Include/internal/pycore_asdl.h' line='42' column='1' id='type-id-688'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='size' type-id='type-id-36' visibility='default' filepath='./Include/internal/pycore_asdl.h' line='43' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='elements' type-id='type-id-482' visibility='default' filepath='./Include/internal/pycore_asdl.h' line='43' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='typed_elements' type-id='type-id-689' visibility='default' filepath='./Include/internal/pycore_asdl.h' line='44' column='1'/> - </data-member> - </class-decl> - - <array-type-def dimensions='1' type-id='type-id-8' size-in-bits='32' id='type-id-689'> - <subrange length='1' type-id='type-id-16' id='type-id-258'/> - - </array-type-def> - <typedef-decl name='asdl_int_seq' type-id='type-id-688' filepath='./Include/internal/pycore_asdl.h' line='45' column='1' id='type-id-687'/> - <pointer-type-def type-id='type-id-687' size-in-bits='64' id='type-id-686'/> - <class-decl name='__anonymous_struct__' size-in-bits='192' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='430' column='1' id='type-id-658'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='func' type-id='type-id-635' visibility='default' filepath='./Include/internal/pycore_ast.h' line='431' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='args' type-id='type-id-634' visibility='default' filepath='./Include/internal/pycore_ast.h' line='432' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='keywords' type-id='type-id-690' visibility='default' filepath='./Include/internal/pycore_ast.h' line='433' column='1'/> - </data-member> - </class-decl> - <class-decl name='__anonymous_struct__' size-in-bits='192' is-struct='yes' is-anonymous='yes' naming-typedef-id='type-id-691' visibility='default' filepath='./Include/internal/pycore_ast.h' line='106' column='1' id='type-id-692'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='size' type-id='type-id-36' visibility='default' filepath='./Include/internal/pycore_ast.h' line='107' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='elements' type-id='type-id-482' visibility='default' filepath='./Include/internal/pycore_ast.h' line='107' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='typed_elements' type-id='type-id-693' visibility='default' filepath='./Include/internal/pycore_ast.h' line='108' column='1'/> - </data-member> - </class-decl> - <class-decl name='_keyword' size-in-bits='256' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='540' column='1' id='type-id-694'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='arg' type-id='type-id-632' visibility='default' filepath='./Include/internal/pycore_ast.h' line='541' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='value' type-id='type-id-635' visibility='default' filepath='./Include/internal/pycore_ast.h' line='542' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='lineno' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='543' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='160'> - <var-decl name='col_offset' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='544' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='end_lineno' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='545' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='224'> - <var-decl name='end_col_offset' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='546' column='1'/> - </data-member> - </class-decl> - <pointer-type-def type-id='type-id-694' size-in-bits='64' id='type-id-695'/> - <typedef-decl name='keyword_ty' type-id='type-id-695' filepath='./Include/internal/pycore_ast.h' line='42' column='1' id='type-id-696'/> - - <array-type-def dimensions='1' type-id='type-id-696' size-in-bits='64' id='type-id-693'> - <subrange length='1' type-id='type-id-16' id='type-id-258'/> - - </array-type-def> - <typedef-decl name='asdl_keyword_seq' type-id='type-id-692' filepath='./Include/internal/pycore_ast.h' line='109' column='1' id='type-id-691'/> - <pointer-type-def type-id='type-id-691' size-in-bits='64' id='type-id-690'/> - <class-decl name='__anonymous_struct__' size-in-bits='192' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='436' column='1' id='type-id-659'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='value' type-id='type-id-635' visibility='default' filepath='./Include/internal/pycore_ast.h' line='437' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='conversion' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='438' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='format_spec' type-id='type-id-635' visibility='default' filepath='./Include/internal/pycore_ast.h' line='439' column='1'/> - </data-member> - </class-decl> - <class-decl name='__anonymous_struct__' size-in-bits='64' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='442' column='1' id='type-id-660'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='values' type-id='type-id-634' visibility='default' filepath='./Include/internal/pycore_ast.h' line='443' column='1'/> - </data-member> - </class-decl> - <class-decl name='__anonymous_struct__' size-in-bits='128' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='446' column='1' id='type-id-661'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='value' type-id='type-id-697' visibility='default' filepath='./Include/internal/pycore_ast.h' line='447' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='kind' type-id='type-id-636' visibility='default' filepath='./Include/internal/pycore_ast.h' line='448' column='1'/> - </data-member> - </class-decl> - <typedef-decl name='constant' type-id='type-id-14' filepath='./Include/internal/pycore_asdl.h' line='16' column='1' id='type-id-697'/> - <typedef-decl name='string' type-id='type-id-14' filepath='./Include/internal/pycore_asdl.h' line='14' column='1' id='type-id-636'/> - <class-decl name='__anonymous_struct__' size-in-bits='192' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='451' column='1' id='type-id-662'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='value' type-id='type-id-635' visibility='default' filepath='./Include/internal/pycore_ast.h' line='452' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='attr' type-id='type-id-632' visibility='default' filepath='./Include/internal/pycore_ast.h' line='453' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='ctx' type-id='type-id-698' visibility='default' filepath='./Include/internal/pycore_ast.h' line='454' column='1'/> - </data-member> - </class-decl> - <enum-decl name='_expr_context' filepath='./Include/internal/pycore_ast.h' line='21' column='1' id='type-id-699'> - <underlying-type type-id='type-id-126'/> - <enumerator name='Load' value='1'/> - <enumerator name='Store' value='2'/> - <enumerator name='Del' value='3'/> - </enum-decl> - <typedef-decl name='expr_context_ty' type-id='type-id-699' filepath='./Include/internal/pycore_ast.h' line='21' column='1' id='type-id-698'/> - <class-decl name='__anonymous_struct__' size-in-bits='192' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='457' column='1' id='type-id-663'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='value' type-id='type-id-635' visibility='default' filepath='./Include/internal/pycore_ast.h' line='458' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='slice' type-id='type-id-635' visibility='default' filepath='./Include/internal/pycore_ast.h' line='459' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='ctx' type-id='type-id-698' visibility='default' filepath='./Include/internal/pycore_ast.h' line='460' column='1'/> - </data-member> - </class-decl> - <class-decl name='__anonymous_struct__' size-in-bits='128' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='463' column='1' id='type-id-664'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='value' type-id='type-id-635' visibility='default' filepath='./Include/internal/pycore_ast.h' line='464' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='ctx' type-id='type-id-698' visibility='default' filepath='./Include/internal/pycore_ast.h' line='465' column='1'/> - </data-member> - </class-decl> - <class-decl name='__anonymous_struct__' size-in-bits='128' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='468' column='1' id='type-id-665'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='id' type-id='type-id-632' visibility='default' filepath='./Include/internal/pycore_ast.h' line='469' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='ctx' type-id='type-id-698' visibility='default' filepath='./Include/internal/pycore_ast.h' line='470' column='1'/> - </data-member> - </class-decl> - <class-decl name='__anonymous_struct__' size-in-bits='128' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='473' column='1' id='type-id-666'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='elts' type-id='type-id-634' visibility='default' filepath='./Include/internal/pycore_ast.h' line='474' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='ctx' type-id='type-id-698' visibility='default' filepath='./Include/internal/pycore_ast.h' line='475' column='1'/> - </data-member> - </class-decl> - <class-decl name='__anonymous_struct__' size-in-bits='192' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='483' column='1' id='type-id-667'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='lower' type-id='type-id-635' visibility='default' filepath='./Include/internal/pycore_ast.h' line='484' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='upper' type-id='type-id-635' visibility='default' filepath='./Include/internal/pycore_ast.h' line='485' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='step' type-id='type-id-635' visibility='default' filepath='./Include/internal/pycore_ast.h' line='486' column='1'/> - </data-member> - </class-decl> - <pointer-type-def type-id='type-id-643' size-in-bits='64' id='type-id-700'/> - <typedef-decl name='arg_ty' type-id='type-id-700' filepath='./Include/internal/pycore_ast.h' line='40' column='1' id='type-id-639'/> - - <array-type-def dimensions='1' type-id='type-id-639' size-in-bits='64' id='type-id-642'> - <subrange length='1' type-id='type-id-16' id='type-id-258'/> - - </array-type-def> - <typedef-decl name='asdl_arg_seq' type-id='type-id-641' filepath='./Include/internal/pycore_ast.h' line='102' column='1' id='type-id-640'/> - <pointer-type-def type-id='type-id-640' size-in-bits='64' id='type-id-638'/> - <typedef-decl name='asdl_stmt_seq' type-id='type-id-610' filepath='./Include/internal/pycore_ast.h' line='65' column='1' id='type-id-609'/> - <pointer-type-def type-id='type-id-609' size-in-bits='64' id='type-id-607'/> - <class-decl name='__anonymous_struct__' size-in-bits='320' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='206' column='1' id='type-id-616'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='name' type-id='type-id-632' visibility='default' filepath='./Include/internal/pycore_ast.h' line='207' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='bases' type-id='type-id-634' visibility='default' filepath='./Include/internal/pycore_ast.h' line='208' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='keywords' type-id='type-id-690' visibility='default' filepath='./Include/internal/pycore_ast.h' line='209' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='body' type-id='type-id-607' visibility='default' filepath='./Include/internal/pycore_ast.h' line='210' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='256'> - <var-decl name='decorator_list' type-id='type-id-634' visibility='default' filepath='./Include/internal/pycore_ast.h' line='211' column='1'/> - </data-member> - </class-decl> - <class-decl name='__anonymous_struct__' size-in-bits='64' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='218' column='1' id='type-id-618'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='targets' type-id='type-id-634' visibility='default' filepath='./Include/internal/pycore_ast.h' line='219' column='1'/> - </data-member> - </class-decl> - <class-decl name='__anonymous_struct__' size-in-bits='192' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='222' column='1' id='type-id-619'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='targets' type-id='type-id-634' visibility='default' filepath='./Include/internal/pycore_ast.h' line='223' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='value' type-id='type-id-635' visibility='default' filepath='./Include/internal/pycore_ast.h' line='224' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='type_comment' type-id='type-id-636' visibility='default' filepath='./Include/internal/pycore_ast.h' line='225' column='1'/> - </data-member> - </class-decl> - <class-decl name='__anonymous_struct__' size-in-bits='192' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='228' column='1' id='type-id-620'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='target' type-id='type-id-635' visibility='default' filepath='./Include/internal/pycore_ast.h' line='229' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='op' type-id='type-id-674' visibility='default' filepath='./Include/internal/pycore_ast.h' line='230' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='value' type-id='type-id-635' visibility='default' filepath='./Include/internal/pycore_ast.h' line='231' column='1'/> - </data-member> - </class-decl> - <class-decl name='__anonymous_struct__' size-in-bits='256' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='234' column='1' id='type-id-621'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='target' type-id='type-id-635' visibility='default' filepath='./Include/internal/pycore_ast.h' line='235' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='annotation' type-id='type-id-635' visibility='default' filepath='./Include/internal/pycore_ast.h' line='236' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='value' type-id='type-id-635' visibility='default' filepath='./Include/internal/pycore_ast.h' line='237' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='simple' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='238' column='1'/> - </data-member> - </class-decl> - <class-decl name='__anonymous_struct__' size-in-bits='320' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='241' column='1' id='type-id-622'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='target' type-id='type-id-635' visibility='default' filepath='./Include/internal/pycore_ast.h' line='242' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='iter' type-id='type-id-635' visibility='default' filepath='./Include/internal/pycore_ast.h' line='243' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='body' type-id='type-id-607' visibility='default' filepath='./Include/internal/pycore_ast.h' line='244' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='orelse' type-id='type-id-607' visibility='default' filepath='./Include/internal/pycore_ast.h' line='245' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='256'> - <var-decl name='type_comment' type-id='type-id-636' visibility='default' filepath='./Include/internal/pycore_ast.h' line='246' column='1'/> - </data-member> - </class-decl> - <class-decl name='__anonymous_struct__' size-in-bits='192' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='257' column='1' id='type-id-623'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='test' type-id='type-id-635' visibility='default' filepath='./Include/internal/pycore_ast.h' line='258' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='body' type-id='type-id-607' visibility='default' filepath='./Include/internal/pycore_ast.h' line='259' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='orelse' type-id='type-id-607' visibility='default' filepath='./Include/internal/pycore_ast.h' line='260' column='1'/> - </data-member> - </class-decl> - <class-decl name='__anonymous_struct__' size-in-bits='192' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='269' column='1' id='type-id-624'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='items' type-id='type-id-701' visibility='default' filepath='./Include/internal/pycore_ast.h' line='270' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='body' type-id='type-id-607' visibility='default' filepath='./Include/internal/pycore_ast.h' line='271' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='type_comment' type-id='type-id-636' visibility='default' filepath='./Include/internal/pycore_ast.h' line='272' column='1'/> - </data-member> - </class-decl> - <class-decl name='__anonymous_struct__' size-in-bits='192' is-struct='yes' is-anonymous='yes' naming-typedef-id='type-id-702' visibility='default' filepath='./Include/internal/pycore_ast.h' line='120' column='1' id='type-id-703'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='size' type-id='type-id-36' visibility='default' filepath='./Include/internal/pycore_ast.h' line='121' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='elements' type-id='type-id-482' visibility='default' filepath='./Include/internal/pycore_ast.h' line='121' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='typed_elements' type-id='type-id-704' visibility='default' filepath='./Include/internal/pycore_ast.h' line='122' column='1'/> - </data-member> - </class-decl> - <class-decl name='_withitem' size-in-bits='128' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='558' column='1' id='type-id-705'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='context_expr' type-id='type-id-635' visibility='default' filepath='./Include/internal/pycore_ast.h' line='559' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='optional_vars' type-id='type-id-635' visibility='default' filepath='./Include/internal/pycore_ast.h' line='560' column='1'/> - </data-member> - </class-decl> - <pointer-type-def type-id='type-id-705' size-in-bits='64' id='type-id-706'/> - <typedef-decl name='withitem_ty' type-id='type-id-706' filepath='./Include/internal/pycore_ast.h' line='46' column='1' id='type-id-707'/> - - <array-type-def dimensions='1' type-id='type-id-707' size-in-bits='64' id='type-id-704'> - <subrange length='1' type-id='type-id-16' id='type-id-258'/> - - </array-type-def> - <typedef-decl name='asdl_withitem_seq' type-id='type-id-703' filepath='./Include/internal/pycore_ast.h' line='123' column='1' id='type-id-702'/> - <pointer-type-def type-id='type-id-702' size-in-bits='64' id='type-id-701'/> - <class-decl name='__anonymous_struct__' size-in-bits='128' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='281' column='1' id='type-id-625'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='subject' type-id='type-id-635' visibility='default' filepath='./Include/internal/pycore_ast.h' line='282' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='cases' type-id='type-id-708' visibility='default' filepath='./Include/internal/pycore_ast.h' line='283' column='1'/> - </data-member> - </class-decl> - <class-decl name='__anonymous_struct__' size-in-bits='192' is-struct='yes' is-anonymous='yes' naming-typedef-id='type-id-709' visibility='default' filepath='./Include/internal/pycore_ast.h' line='127' column='1' id='type-id-710'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='size' type-id='type-id-36' visibility='default' filepath='./Include/internal/pycore_ast.h' line='128' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='elements' type-id='type-id-482' visibility='default' filepath='./Include/internal/pycore_ast.h' line='128' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='typed_elements' type-id='type-id-711' visibility='default' filepath='./Include/internal/pycore_ast.h' line='129' column='1'/> - </data-member> - </class-decl> - <class-decl name='_match_case' size-in-bits='192' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='563' column='1' id='type-id-712'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='pattern' type-id='type-id-713' visibility='default' filepath='./Include/internal/pycore_ast.h' line='564' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='guard' type-id='type-id-635' visibility='default' filepath='./Include/internal/pycore_ast.h' line='565' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='body' type-id='type-id-607' visibility='default' filepath='./Include/internal/pycore_ast.h' line='566' column='1'/> - </data-member> - </class-decl> - <class-decl name='_pattern' size-in-bits='448' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='573' column='1' id='type-id-714'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='kind' type-id='type-id-715' visibility='default' filepath='./Include/internal/pycore_ast.h' line='574' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='v' type-id='type-id-716' visibility='default' filepath='./Include/internal/pycore_ast.h' line='614' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='320'> - <var-decl name='lineno' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='615' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='352'> - <var-decl name='col_offset' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='616' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='384'> - <var-decl name='end_lineno' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='617' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='416'> - <var-decl name='end_col_offset' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='618' column='1'/> - </data-member> - </class-decl> - <enum-decl name='_pattern_kind' filepath='./Include/internal/pycore_ast.h' line='569' column='1' id='type-id-715'> - <underlying-type type-id='type-id-126'/> - <enumerator name='MatchValue_kind' value='1'/> - <enumerator name='MatchSingleton_kind' value='2'/> - <enumerator name='MatchSequence_kind' value='3'/> - <enumerator name='MatchMapping_kind' value='4'/> - <enumerator name='MatchClass_kind' value='5'/> - <enumerator name='MatchStar_kind' value='6'/> - <enumerator name='MatchAs_kind' value='7'/> - <enumerator name='MatchOr_kind' value='8'/> - </enum-decl> - <union-decl name='__anonymous_union__' size-in-bits='256' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='575' column='1' id='type-id-716'> - <data-member access='private'> - <var-decl name='MatchValue' type-id='type-id-617' visibility='default' filepath='./Include/internal/pycore_ast.h' line='578' column='1'/> - </data-member> - <data-member access='private'> - <var-decl name='MatchSingleton' type-id='type-id-717' visibility='default' filepath='./Include/internal/pycore_ast.h' line='582' column='1'/> - </data-member> - <data-member access='private'> - <var-decl name='MatchSequence' type-id='type-id-718' visibility='default' filepath='./Include/internal/pycore_ast.h' line='586' column='1'/> - </data-member> - <data-member access='private'> - <var-decl name='MatchMapping' type-id='type-id-719' visibility='default' filepath='./Include/internal/pycore_ast.h' line='592' column='1'/> - </data-member> - <data-member access='private'> - <var-decl name='MatchClass' type-id='type-id-720' visibility='default' filepath='./Include/internal/pycore_ast.h' line='599' column='1'/> - </data-member> - <data-member access='private'> - <var-decl name='MatchStar' type-id='type-id-721' visibility='default' filepath='./Include/internal/pycore_ast.h' line='603' column='1'/> - </data-member> - <data-member access='private'> - <var-decl name='MatchAs' type-id='type-id-722' visibility='default' filepath='./Include/internal/pycore_ast.h' line='608' column='1'/> - </data-member> - <data-member access='private'> - <var-decl name='MatchOr' type-id='type-id-718' visibility='default' filepath='./Include/internal/pycore_ast.h' line='612' column='1'/> - </data-member> - </union-decl> - <class-decl name='__anonymous_struct__' size-in-bits='64' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='580' column='1' id='type-id-717'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='value' type-id='type-id-697' visibility='default' filepath='./Include/internal/pycore_ast.h' line='581' column='1'/> - </data-member> - </class-decl> - <class-decl name='__anonymous_struct__' size-in-bits='64' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='584' column='1' id='type-id-718'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='patterns' type-id='type-id-723' visibility='default' filepath='./Include/internal/pycore_ast.h' line='585' column='1'/> - </data-member> - </class-decl> - <class-decl name='__anonymous_struct__' size-in-bits='192' is-struct='yes' is-anonymous='yes' naming-typedef-id='type-id-724' visibility='default' filepath='./Include/internal/pycore_ast.h' line='135' column='1' id='type-id-725'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='size' type-id='type-id-36' visibility='default' filepath='./Include/internal/pycore_ast.h' line='136' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='elements' type-id='type-id-482' visibility='default' filepath='./Include/internal/pycore_ast.h' line='136' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='typed_elements' type-id='type-id-726' visibility='default' filepath='./Include/internal/pycore_ast.h' line='137' column='1'/> - </data-member> - </class-decl> - <pointer-type-def type-id='type-id-714' size-in-bits='64' id='type-id-727'/> - <typedef-decl name='pattern_ty' type-id='type-id-727' filepath='./Include/internal/pycore_ast.h' line='50' column='1' id='type-id-713'/> - - <array-type-def dimensions='1' type-id='type-id-713' size-in-bits='64' id='type-id-726'> - <subrange length='1' type-id='type-id-16' id='type-id-258'/> - - </array-type-def> - <typedef-decl name='asdl_pattern_seq' type-id='type-id-725' filepath='./Include/internal/pycore_ast.h' line='138' column='1' id='type-id-724'/> - <pointer-type-def type-id='type-id-724' size-in-bits='64' id='type-id-723'/> - <class-decl name='__anonymous_struct__' size-in-bits='192' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='588' column='1' id='type-id-719'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='keys' type-id='type-id-634' visibility='default' filepath='./Include/internal/pycore_ast.h' line='589' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='patterns' type-id='type-id-723' visibility='default' filepath='./Include/internal/pycore_ast.h' line='590' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='rest' type-id='type-id-632' visibility='default' filepath='./Include/internal/pycore_ast.h' line='591' column='1'/> - </data-member> - </class-decl> - <class-decl name='__anonymous_struct__' size-in-bits='256' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='594' column='1' id='type-id-720'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='cls' type-id='type-id-635' visibility='default' filepath='./Include/internal/pycore_ast.h' line='595' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='patterns' type-id='type-id-723' visibility='default' filepath='./Include/internal/pycore_ast.h' line='596' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='kwd_attrs' type-id='type-id-728' visibility='default' filepath='./Include/internal/pycore_ast.h' line='597' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='kwd_patterns' type-id='type-id-723' visibility='default' filepath='./Include/internal/pycore_ast.h' line='598' column='1'/> - </data-member> - </class-decl> - <class-decl name='__anonymous_struct__' size-in-bits='192' is-struct='yes' is-anonymous='yes' naming-typedef-id='type-id-729' visibility='default' filepath='./Include/internal/pycore_asdl.h' line='37' column='1' id='type-id-730'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='size' type-id='type-id-36' visibility='default' filepath='./Include/internal/pycore_asdl.h' line='38' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='elements' type-id='type-id-482' visibility='default' filepath='./Include/internal/pycore_asdl.h' line='38' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='typed_elements' type-id='type-id-360' visibility='default' filepath='./Include/internal/pycore_asdl.h' line='39' column='1'/> - </data-member> - </class-decl> - <typedef-decl name='asdl_identifier_seq' type-id='type-id-730' filepath='./Include/internal/pycore_asdl.h' line='40' column='1' id='type-id-729'/> - <pointer-type-def type-id='type-id-729' size-in-bits='64' id='type-id-728'/> - <class-decl name='__anonymous_struct__' size-in-bits='64' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='601' column='1' id='type-id-721'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='name' type-id='type-id-632' visibility='default' filepath='./Include/internal/pycore_ast.h' line='602' column='1'/> - </data-member> - </class-decl> - <class-decl name='__anonymous_struct__' size-in-bits='128' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='605' column='1' id='type-id-722'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='pattern' type-id='type-id-713' visibility='default' filepath='./Include/internal/pycore_ast.h' line='606' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='name' type-id='type-id-632' visibility='default' filepath='./Include/internal/pycore_ast.h' line='607' column='1'/> - </data-member> - </class-decl> - <pointer-type-def type-id='type-id-712' size-in-bits='64' id='type-id-731'/> - <typedef-decl name='match_case_ty' type-id='type-id-731' filepath='./Include/internal/pycore_ast.h' line='48' column='1' id='type-id-732'/> - - <array-type-def dimensions='1' type-id='type-id-732' size-in-bits='64' id='type-id-711'> - <subrange length='1' type-id='type-id-16' id='type-id-258'/> - - </array-type-def> - <typedef-decl name='asdl_match_case_seq' type-id='type-id-710' filepath='./Include/internal/pycore_ast.h' line='130' column='1' id='type-id-709'/> - <pointer-type-def type-id='type-id-709' size-in-bits='64' id='type-id-708'/> - <class-decl name='__anonymous_struct__' size-in-bits='128' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='286' column='1' id='type-id-626'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='exc' type-id='type-id-635' visibility='default' filepath='./Include/internal/pycore_ast.h' line='287' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='cause' type-id='type-id-635' visibility='default' filepath='./Include/internal/pycore_ast.h' line='288' column='1'/> - </data-member> - </class-decl> - <class-decl name='__anonymous_struct__' size-in-bits='256' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='291' column='1' id='type-id-627'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='body' type-id='type-id-607' visibility='default' filepath='./Include/internal/pycore_ast.h' line='292' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='handlers' type-id='type-id-733' visibility='default' filepath='./Include/internal/pycore_ast.h' line='293' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='orelse' type-id='type-id-607' visibility='default' filepath='./Include/internal/pycore_ast.h' line='294' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='finalbody' type-id='type-id-607' visibility='default' filepath='./Include/internal/pycore_ast.h' line='295' column='1'/> - </data-member> - </class-decl> - <class-decl name='__anonymous_struct__' size-in-bits='192' is-struct='yes' is-anonymous='yes' naming-typedef-id='type-id-734' visibility='default' filepath='./Include/internal/pycore_ast.h' line='84' column='1' id='type-id-735'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='size' type-id='type-id-36' visibility='default' filepath='./Include/internal/pycore_ast.h' line='85' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='elements' type-id='type-id-482' visibility='default' filepath='./Include/internal/pycore_ast.h' line='85' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='typed_elements' type-id='type-id-736' visibility='default' filepath='./Include/internal/pycore_ast.h' line='86' column='1'/> - </data-member> - </class-decl> - <class-decl name='_excepthandler' size-in-bits='384' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='504' column='1' id='type-id-737'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='kind' type-id='type-id-738' visibility='default' filepath='./Include/internal/pycore_ast.h' line='505' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='v' type-id='type-id-739' visibility='default' filepath='./Include/internal/pycore_ast.h' line='513' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='256'> - <var-decl name='lineno' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='514' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='288'> - <var-decl name='col_offset' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='515' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='320'> - <var-decl name='end_lineno' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='516' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='352'> - <var-decl name='end_col_offset' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='517' column='1'/> - </data-member> - </class-decl> - <enum-decl name='_excepthandler_kind' filepath='./Include/internal/pycore_ast.h' line='503' column='1' id='type-id-738'> - <underlying-type type-id='type-id-126'/> - <enumerator name='ExceptHandler_kind' value='1'/> - </enum-decl> - <union-decl name='__anonymous_union__' size-in-bits='192' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='506' column='1' id='type-id-739'> - <data-member access='private'> - <var-decl name='ExceptHandler' type-id='type-id-740' visibility='default' filepath='./Include/internal/pycore_ast.h' line='511' column='1'/> - </data-member> - </union-decl> - <class-decl name='__anonymous_struct__' size-in-bits='192' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='507' column='1' id='type-id-740'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='type' type-id='type-id-635' visibility='default' filepath='./Include/internal/pycore_ast.h' line='508' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='name' type-id='type-id-632' visibility='default' filepath='./Include/internal/pycore_ast.h' line='509' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='body' type-id='type-id-607' visibility='default' filepath='./Include/internal/pycore_ast.h' line='510' column='1'/> - </data-member> - </class-decl> - <pointer-type-def type-id='type-id-737' size-in-bits='64' id='type-id-741'/> - <typedef-decl name='excepthandler_ty' type-id='type-id-741' filepath='./Include/internal/pycore_ast.h' line='36' column='1' id='type-id-742'/> - - <array-type-def dimensions='1' type-id='type-id-742' size-in-bits='64' id='type-id-736'> - <subrange length='1' type-id='type-id-16' id='type-id-258'/> - - </array-type-def> - <typedef-decl name='asdl_excepthandler_seq' type-id='type-id-735' filepath='./Include/internal/pycore_ast.h' line='87' column='1' id='type-id-734'/> - <pointer-type-def type-id='type-id-734' size-in-bits='64' id='type-id-733'/> - <class-decl name='__anonymous_struct__' size-in-bits='128' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='305' column='1' id='type-id-628'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='test' type-id='type-id-635' visibility='default' filepath='./Include/internal/pycore_ast.h' line='306' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='msg' type-id='type-id-635' visibility='default' filepath='./Include/internal/pycore_ast.h' line='307' column='1'/> - </data-member> - </class-decl> - <class-decl name='__anonymous_struct__' size-in-bits='64' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='310' column='1' id='type-id-629'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='names' type-id='type-id-743' visibility='default' filepath='./Include/internal/pycore_ast.h' line='311' column='1'/> - </data-member> - </class-decl> - <class-decl name='__anonymous_struct__' size-in-bits='192' is-struct='yes' is-anonymous='yes' naming-typedef-id='type-id-744' visibility='default' filepath='./Include/internal/pycore_ast.h' line='113' column='1' id='type-id-745'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='size' type-id='type-id-36' visibility='default' filepath='./Include/internal/pycore_ast.h' line='114' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='elements' type-id='type-id-482' visibility='default' filepath='./Include/internal/pycore_ast.h' line='114' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='typed_elements' type-id='type-id-746' visibility='default' filepath='./Include/internal/pycore_ast.h' line='115' column='1'/> - </data-member> - </class-decl> - <class-decl name='_alias' size-in-bits='256' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='549' column='1' id='type-id-747'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='name' type-id='type-id-632' visibility='default' filepath='./Include/internal/pycore_ast.h' line='550' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='asname' type-id='type-id-632' visibility='default' filepath='./Include/internal/pycore_ast.h' line='551' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='lineno' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='552' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='160'> - <var-decl name='col_offset' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='553' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='end_lineno' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='554' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='224'> - <var-decl name='end_col_offset' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='555' column='1'/> - </data-member> - </class-decl> - <pointer-type-def type-id='type-id-747' size-in-bits='64' id='type-id-748'/> - <typedef-decl name='alias_ty' type-id='type-id-748' filepath='./Include/internal/pycore_ast.h' line='44' column='1' id='type-id-749'/> - - <array-type-def dimensions='1' type-id='type-id-749' size-in-bits='64' id='type-id-746'> - <subrange length='1' type-id='type-id-16' id='type-id-258'/> - - </array-type-def> - <typedef-decl name='asdl_alias_seq' type-id='type-id-745' filepath='./Include/internal/pycore_ast.h' line='116' column='1' id='type-id-744'/> - <pointer-type-def type-id='type-id-744' size-in-bits='64' id='type-id-743'/> - <class-decl name='__anonymous_struct__' size-in-bits='192' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='314' column='1' id='type-id-630'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='module' type-id='type-id-632' visibility='default' filepath='./Include/internal/pycore_ast.h' line='315' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='names' type-id='type-id-743' visibility='default' filepath='./Include/internal/pycore_ast.h' line='316' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='level' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='317' column='1'/> - </data-member> - </class-decl> - <class-decl name='__anonymous_struct__' size-in-bits='64' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='320' column='1' id='type-id-631'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='names' type-id='type-id-728' visibility='default' filepath='./Include/internal/pycore_ast.h' line='321' column='1'/> - </data-member> - </class-decl> - <pointer-type-def type-id='type-id-612' size-in-bits='64' id='type-id-750'/> - <typedef-decl name='stmt_ty' type-id='type-id-750' filepath='./Include/internal/pycore_ast.h' line='17' column='1' id='type-id-751'/> - - <array-type-def dimensions='1' type-id='type-id-751' size-in-bits='64' id='type-id-611'> - <subrange length='1' type-id='type-id-16' id='type-id-258'/> - - </array-type-def> - <class-decl name='__anonymous_struct__' size-in-bits='192' is-struct='yes' is-anonymous='yes' naming-typedef-id='type-id-752' visibility='default' filepath='./Include/internal/pycore_ast.h' line='142' column='1' id='type-id-753'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='size' type-id='type-id-36' visibility='default' filepath='./Include/internal/pycore_ast.h' line='143' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='elements' type-id='type-id-482' visibility='default' filepath='./Include/internal/pycore_ast.h' line='143' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='typed_elements' type-id='type-id-754' visibility='default' filepath='./Include/internal/pycore_ast.h' line='144' column='1'/> - </data-member> - </class-decl> - <class-decl name='_type_ignore' size-in-bits='192' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='622' column='1' id='type-id-755'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='kind' type-id='type-id-756' visibility='default' filepath='./Include/internal/pycore_ast.h' line='623' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='v' type-id='type-id-757' visibility='default' filepath='./Include/internal/pycore_ast.h' line='630' column='1'/> - </data-member> - </class-decl> - <enum-decl name='_type_ignore_kind' filepath='./Include/internal/pycore_ast.h' line='621' column='1' id='type-id-756'> - <underlying-type type-id='type-id-126'/> - <enumerator name='TypeIgnore_kind' value='1'/> - </enum-decl> - <union-decl name='__anonymous_union__' size-in-bits='128' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='624' column='1' id='type-id-757'> - <data-member access='private'> - <var-decl name='TypeIgnore' type-id='type-id-758' visibility='default' filepath='./Include/internal/pycore_ast.h' line='628' column='1'/> - </data-member> - </union-decl> - <class-decl name='__anonymous_struct__' size-in-bits='128' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='625' column='1' id='type-id-758'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='lineno' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='626' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='tag' type-id='type-id-636' visibility='default' filepath='./Include/internal/pycore_ast.h' line='627' column='1'/> - </data-member> - </class-decl> - <pointer-type-def type-id='type-id-755' size-in-bits='64' id='type-id-759'/> - <typedef-decl name='type_ignore_ty' type-id='type-id-759' filepath='./Include/internal/pycore_ast.h' line='52' column='1' id='type-id-760'/> - - <array-type-def dimensions='1' type-id='type-id-760' size-in-bits='64' id='type-id-754'> - <subrange length='1' type-id='type-id-16' id='type-id-258'/> - - </array-type-def> - <typedef-decl name='asdl_type_ignore_seq' type-id='type-id-753' filepath='./Include/internal/pycore_ast.h' line='145' column='1' id='type-id-752'/> - <pointer-type-def type-id='type-id-752' size-in-bits='64' id='type-id-608'/> - <class-decl name='__anonymous_struct__' size-in-bits='64' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='161' column='1' id='type-id-604'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='body' type-id='type-id-607' visibility='default' filepath='./Include/internal/pycore_ast.h' line='162' column='1'/> - </data-member> - </class-decl> - <class-decl name='__anonymous_struct__' size-in-bits='64' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='165' column='1' id='type-id-605'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='body' type-id='type-id-635' visibility='default' filepath='./Include/internal/pycore_ast.h' line='166' column='1'/> - </data-member> - </class-decl> - <class-decl name='__anonymous_struct__' size-in-bits='128' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='169' column='1' id='type-id-606'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='argtypes' type-id='type-id-634' visibility='default' filepath='./Include/internal/pycore_ast.h' line='170' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='returns' type-id='type-id-635' visibility='default' filepath='./Include/internal/pycore_ast.h' line='171' column='1'/> - </data-member> - </class-decl> - <pointer-type-def type-id='type-id-600' size-in-bits='64' id='type-id-761'/> - <typedef-decl name='mod_ty' type-id='type-id-761' filepath='./Include/internal/pycore_ast.h' line='15' column='1' id='type-id-762'/> - <class-decl name='_arena' size-in-bits='192' is-struct='yes' visibility='default' is-declaration-only='yes' id='type-id-763'/> - <typedef-decl name='PyArena' type-id='type-id-763' filepath='./Include/internal/pycore_pyarena.h' line='14' column='1' id='type-id-764'/> - <pointer-type-def type-id='type-id-764' size-in-bits='64' id='type-id-765'/> - <function-decl name='_PyAST_Compile' mangled-name='_PyAST_Compile' filepath='Python/compile.c' line='541' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyAST_Compile'> - <parameter type-id='type-id-762' name='mod' filepath='Python/compile.c' line='541' column='1'/> - <parameter type-id='type-id-14' name='filename' filepath='Python/compile.c' line='541' column='1'/> - <parameter type-id='type-id-593' name='flags' filepath='Python/compile.c' line='541' column='1'/> - <parameter type-id='type-id-8' name='optimize' filepath='Python/compile.c' line='542' column='1'/> - <parameter type-id='type-id-765' name='arena' filepath='Python/compile.c' line='542' column='1'/> - <return type-id='type-id-444'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Python/context.c' comp-dir-path='/src' language='LANG_C99'> - <var-decl name='PyContext_Type' type-id='type-id-112' mangled-name='PyContext_Type' visibility='default' filepath='./Include/cpython/context.h' line='8' column='1' elf-symbol-id='PyContext_Type'/> - <var-decl name='PyContextVar_Type' type-id='type-id-112' mangled-name='PyContextVar_Type' visibility='default' filepath='./Include/cpython/context.h' line='11' column='1' elf-symbol-id='PyContextVar_Type'/> - <var-decl name='PyContextToken_Type' type-id='type-id-112' mangled-name='PyContextToken_Type' visibility='default' filepath='./Include/cpython/context.h' line='14' column='1' elf-symbol-id='PyContextToken_Type'/> - <var-decl name='_PyContextTokenMissing_Type' type-id='type-id-112' visibility='default' filepath='./Include/internal/pycore_context.h' line='11' column='1'/> - <function-decl name='PyContextVar_Reset' mangled-name='PyContextVar_Reset' filepath='Python/context.c' line='295' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyContextVar_Reset'> - <parameter type-id='type-id-14' name='ovar' filepath='Python/context.c' line='295' column='1'/> - <parameter type-id='type-id-14' name='otok' filepath='Python/context.c' line='295' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyContextVar_Set' mangled-name='PyContextVar_Set' filepath='Python/context.c' line='259' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyContextVar_Set'> - <parameter type-id='type-id-14' name='ovar' filepath='Python/context.c' line='259' column='1'/> - <parameter type-id='type-id-14' name='val' filepath='Python/context.c' line='259' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyContextVar_Get' mangled-name='PyContextVar_Get' filepath='Python/context.c' line='196' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyContextVar_Get'> - <parameter type-id='type-id-14' name='ovar' filepath='Python/context.c' line='196' column='1'/> - <parameter type-id='type-id-14' name='def' filepath='Python/context.c' line='196' column='1'/> - <parameter type-id='type-id-22' name='val' filepath='Python/context.c' line='196' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyContextVar_New' mangled-name='PyContextVar_New' filepath='Python/context.c' line='183' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyContextVar_New'> - <parameter type-id='type-id-3' name='name' filepath='Python/context.c' line='183' column='1'/> - <parameter type-id='type-id-14' name='def' filepath='Python/context.c' line='183' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyContext_Exit' mangled-name='PyContext_Exit' filepath='Python/context.c' line='174' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyContext_Exit'> - <parameter type-id='type-id-14' name='obj' filepath='Objects/abstract.c' line='2845' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyContext_Enter' mangled-name='PyContext_Enter' filepath='Python/context.c' line='136' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyContext_Enter'> - <parameter type-id='type-id-14' name='obj' filepath='Objects/abstract.c' line='2845' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyContext_CopyCurrent' mangled-name='PyContext_CopyCurrent' filepath='Python/context.c' line='101' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyContext_CopyCurrent'> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyContext_Copy' mangled-name='PyContext_Copy' filepath='Python/context.c' line='92' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyContext_Copy'> - <parameter type-id='type-id-14' name='item' filepath='Objects/abstract.c' line='1408' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyContext_New' mangled-name='PyContext_New' filepath='Python/context.c' line='85' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyContext_New'> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyContext_NewHamtForTests' mangled-name='_PyContext_NewHamtForTests' filepath='Python/context.c' line='78' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyContext_NewHamtForTests'> - <return type-id='type-id-14'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Python/errors.c' comp-dir-path='/src' language='LANG_C99'> - <function-decl name='PyErr_ProgramTextObject' mangled-name='PyErr_ProgramTextObject' filepath='Python/errors.c' line='1828' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_ProgramTextObject'> - <parameter type-id='type-id-14' name='filename' filepath='Python/errors.c' line='1828' column='1'/> - <parameter type-id='type-id-8' name='lineno' filepath='Python/errors.c' line='1828' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyErr_ProgramDecodedTextObject' mangled-name='_PyErr_ProgramDecodedTextObject' filepath='Python/errors.c' line='1812' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyErr_ProgramDecodedTextObject'> - <parameter type-id='type-id-14' name='filename' filepath='Python/errors.c' line='1812' column='1'/> - <parameter type-id='type-id-8' name='lineno' filepath='Python/errors.c' line='1812' column='1'/> - <parameter type-id='type-id-3' name='encoding' filepath='Python/errors.c' line='1812' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyErr_ProgramText' mangled-name='PyErr_ProgramText' filepath='Python/errors.c' line='1795' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_ProgramText'> - <parameter type-id='type-id-3' name='filename' filepath='Python/errors.c' line='1795' column='1'/> - <parameter type-id='type-id-8' name='lineno' filepath='Python/errors.c' line='1795' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyErr_SyntaxLocationEx' mangled-name='PyErr_SyntaxLocationEx' filepath='Python/errors.c' line='1730' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_SyntaxLocationEx'> - <parameter type-id='type-id-3' name='filename' filepath='Python/errors.c' line='1730' column='1'/> - <parameter type-id='type-id-8' name='lineno' filepath='Python/errors.c' line='1730' column='1'/> - <parameter type-id='type-id-8' name='col_offset' filepath='Python/errors.c' line='1730' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyErr_RangedSyntaxLocationObject' mangled-name='PyErr_RangedSyntaxLocationObject' filepath='Python/errors.c' line='1724' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_RangedSyntaxLocationObject'> - <parameter type-id='type-id-14' name='filename' filepath='Python/errors.c' line='1724' column='1'/> - <parameter type-id='type-id-8' name='lineno' filepath='Python/errors.c' line='1724' column='1'/> - <parameter type-id='type-id-8' name='col_offset' filepath='Python/errors.c' line='1724' column='1'/> - <parameter type-id='type-id-8' name='end_lineno' filepath='Python/errors.c' line='1725' column='1'/> - <parameter type-id='type-id-8' name='end_col_offset' filepath='Python/errors.c' line='1725' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyErr_SyntaxLocationObject' mangled-name='PyErr_SyntaxLocationObject' filepath='Python/errors.c' line='1719' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_SyntaxLocationObject'> - <parameter type-id='type-id-14' name='filename' filepath='Python/errors.c' line='1719' column='1'/> - <parameter type-id='type-id-8' name='lineno' filepath='Python/errors.c' line='1719' column='1'/> - <parameter type-id='type-id-8' name='col_offset' filepath='Python/errors.c' line='1719' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyErr_SyntaxLocation' mangled-name='PyErr_SyntaxLocation' filepath='Python/errors.c' line='1599' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_SyntaxLocation'> - <parameter type-id='type-id-3' name='filename' filepath='Python/errors.c' line='1599' column='1'/> - <parameter type-id='type-id-8' name='lineno' filepath='Python/errors.c' line='1599' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyErr_WriteUnraisable' mangled-name='PyErr_WriteUnraisable' filepath='Python/errors.c' line='1592' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_WriteUnraisable'> - <parameter type-id='type-id-14' name='op' filepath='Objects/object.c' line='2016' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_PyErr_WriteUnraisableMsg' mangled-name='_PyErr_WriteUnraisableMsg' filepath='Python/errors.c' line='1489' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyErr_WriteUnraisableMsg'> - <parameter type-id='type-id-3' name='err_msg_str' filepath='Python/errors.c' line='1489' column='1'/> - <parameter type-id='type-id-14' name='obj' filepath='Python/errors.c' line='1489' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyErr_NewExceptionWithDoc' mangled-name='PyErr_NewExceptionWithDoc' filepath='Python/errors.c' line='1184' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_NewExceptionWithDoc'> - <parameter type-id='type-id-3' name='name' filepath='Python/errors.c' line='1184' column='1'/> - <parameter type-id='type-id-3' name='doc' filepath='Python/errors.c' line='1184' column='1'/> - <parameter type-id='type-id-14' name='base' filepath='Python/errors.c' line='1185' column='1'/> - <parameter type-id='type-id-14' name='dict' filepath='Python/errors.c' line='1185' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyErr_NewException' mangled-name='PyErr_NewException' filepath='Python/errors.c' line='1127' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_NewException'> - <parameter type-id='type-id-3' name='name' filepath='Python/errors.c' line='1127' column='1'/> - <parameter type-id='type-id-14' name='base' filepath='Python/errors.c' line='1127' column='1'/> - <parameter type-id='type-id-14' name='dict' filepath='Python/errors.c' line='1127' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyErr_Format' mangled-name='PyErr_Format' filepath='Python/errors.c' line='1111' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_Format'> - <parameter type-id='type-id-14' name='exception' filepath='Python/errors.c' line='1111' column='1'/> - <parameter type-id='type-id-3' name='format' filepath='Python/errors.c' line='1111' column='1'/> - <parameter is-variadic='yes'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyErr_Format' mangled-name='_PyErr_Format' filepath='Python/errors.c' line='1095' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyErr_Format'> - <parameter type-id='type-id-10' name='tstate' filepath='Python/errors.c' line='1095' column='1'/> - <parameter type-id='type-id-14' name='exception' filepath='Python/errors.c' line='1095' column='1'/> - <parameter type-id='type-id-3' name='format' filepath='Python/errors.c' line='1096' column='1'/> - <parameter is-variadic='yes'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyErr_FormatV' mangled-name='PyErr_FormatV' filepath='Python/errors.c' line='1087' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_FormatV'> - <parameter type-id='type-id-14' name='exception' filepath='Python/errors.c' line='1087' column='1'/> - <parameter type-id='type-id-3' name='format' filepath='Python/errors.c' line='1087' column='1'/> - <parameter type-id='type-id-496' name='vargs' filepath='Python/errors.c' line='1087' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyErr_BadInternalCall' mangled-name='PyErr_BadInternalCall' filepath='Python/errors.c' line='1058' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_BadInternalCall'> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_PyErr_BadInternalCall' mangled-name='_PyErr_BadInternalCall' filepath='Python/errors.c' line='1046' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyErr_BadInternalCall'> - <parameter type-id='type-id-3' name='filename' filepath='Python/errors.c' line='1046' column='1'/> - <parameter type-id='type-id-8' name='lineno' filepath='Python/errors.c' line='1046' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyErr_SetImportError' mangled-name='PyErr_SetImportError' filepath='Python/errors.c' line='1040' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_SetImportError'> - <parameter type-id='type-id-14' name='v' filepath='Objects/abstract.c' line='1311' column='1'/> - <parameter type-id='type-id-14' name='w' filepath='Objects/abstract.c' line='1311' column='1'/> - <parameter type-id='type-id-14' name='z' filepath='Objects/abstract.c' line='1311' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyErr_SetImportErrorSubclass' mangled-name='PyErr_SetImportErrorSubclass' filepath='Python/errors.c' line='987' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_SetImportErrorSubclass'> - <parameter type-id='type-id-14' name='exception' filepath='Python/errors.c' line='987' column='1'/> - <parameter type-id='type-id-14' name='msg' filepath='Python/errors.c' line='987' column='1'/> - <parameter type-id='type-id-14' name='name' filepath='Python/errors.c' line='988' column='1'/> - <parameter type-id='type-id-14' name='path' filepath='Python/errors.c' line='988' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyErr_SetFromErrno' mangled-name='PyErr_SetFromErrno' filepath='Python/errors.c' line='862' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_SetFromErrno'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2462' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyErr_SetFromErrnoWithFilename' mangled-name='PyErr_SetFromErrnoWithFilename' filepath='Python/errors.c' line='853' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_SetFromErrnoWithFilename'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2342' column='1'/> - <parameter type-id='type-id-3' name='key' filepath='Objects/abstract.c' line='2342' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyErr_SetFromErrnoWithFilenameObjects' mangled-name='PyErr_SetFromErrnoWithFilenameObjects' filepath='Python/errors.c' line='754' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_SetFromErrnoWithFilenameObjects'> - <parameter type-id='type-id-14' name='co' filepath='Python/ceval.c' line='1130' column='1'/> - <parameter type-id='type-id-14' name='globals' filepath='Python/ceval.c' line='1130' column='1'/> - <parameter type-id='type-id-14' name='locals' filepath='Python/ceval.c' line='1130' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyErr_SetFromErrnoWithFilenameObject' mangled-name='PyErr_SetFromErrnoWithFilenameObject' filepath='Python/errors.c' line='748' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_SetFromErrnoWithFilenameObject'> - <parameter type-id='type-id-14' name='v' filepath='Objects/abstract.c' line='1256' column='1'/> - <parameter type-id='type-id-14' name='w' filepath='Objects/abstract.c' line='1256' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyErr_NoMemory' mangled-name='PyErr_NoMemory' filepath='Python/errors.c' line='741' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_NoMemory'> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyErr_NoMemory' mangled-name='_PyErr_NoMemory' filepath='Python/errors.c' line='728' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyErr_NoMemory'> - <parameter type-id='type-id-10' name='tstate' filepath='Python/errors.c' line='728' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyErr_BadArgument' mangled-name='PyErr_BadArgument' filepath='Python/errors.c' line='719' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_BadArgument'> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyErr_FormatFromCause' mangled-name='_PyErr_FormatFromCause' filepath='Python/errors.c' line='702' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyErr_FormatFromCause'> - <parameter type-id='type-id-14' name='exception' filepath='Python/errors.c' line='1111' column='1'/> - <parameter type-id='type-id-3' name='format' filepath='Python/errors.c' line='1111' column='1'/> - <parameter is-variadic='yes'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyErr_FormatFromCauseTstate' mangled-name='_PyErr_FormatFromCauseTstate' filepath='Python/errors.c' line='687' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyErr_FormatFromCauseTstate'> - <parameter type-id='type-id-10' name='tstate' filepath='Python/errors.c' line='1095' column='1'/> - <parameter type-id='type-id-14' name='exception' filepath='Python/errors.c' line='1095' column='1'/> - <parameter type-id='type-id-3' name='format' filepath='Python/errors.c' line='1096' column='1'/> - <parameter is-variadic='yes'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyErr_ChainStackItem' mangled-name='_PyErr_ChainStackItem' filepath='Python/errors.c' line='619' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyErr_ChainStackItem'> - <parameter type-id='type-id-15' name='exc_info' filepath='Python/errors.c' line='619' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_PyErr_ChainExceptions' mangled-name='_PyErr_ChainExceptions' filepath='Python/errors.c' line='577' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyErr_ChainExceptions'> - <parameter type-id='type-id-14' name='typ' filepath='Python/errors.c' line='577' column='1'/> - <parameter type-id='type-id-14' name='val' filepath='Python/errors.c' line='577' column='1'/> - <parameter type-id='type-id-14' name='tb' filepath='Python/errors.c' line='577' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_PyErr_StackItemToExcInfoTuple' mangled-name='_PyErr_StackItemToExcInfoTuple' filepath='Python/errors.c' line='552' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyErr_StackItemToExcInfoTuple'> - <parameter type-id='type-id-15' name='err_info' filepath='Python/errors.c' line='552' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyErr_SetExcInfo' mangled-name='PyErr_SetExcInfo' filepath='Python/errors.c' line='541' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_SetExcInfo'> - <parameter type-id='type-id-14' name='type' filepath='Python/errors.c' line='541' column='1'/> - <parameter type-id='type-id-14' name='value' filepath='Python/errors.c' line='541' column='1'/> - <parameter type-id='type-id-14' name='traceback' filepath='Python/errors.c' line='541' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyErr_GetExcInfo' mangled-name='PyErr_GetExcInfo' filepath='Python/errors.c' line='534' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_GetExcInfo'> - <parameter type-id='type-id-22' name='p_type' filepath='Python/errors.c' line='534' column='1'/> - <parameter type-id='type-id-22' name='p_value' filepath='Python/errors.c' line='534' column='1'/> - <parameter type-id='type-id-22' name='p_traceback' filepath='Python/errors.c' line='534' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyErr_SetHandledException' mangled-name='PyErr_SetHandledException' filepath='Python/errors.c' line='527' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_SetHandledException'> - <parameter type-id='type-id-14' name='m' filepath='Objects/moduleobject.c' line='578' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_PyErr_SetHandledException' mangled-name='_PyErr_SetHandledException' filepath='Python/errors.c' line='521' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyErr_SetHandledException'> - <parameter type-id='type-id-10' name='tstate' filepath='Python/errors.c' line='521' column='1'/> - <parameter type-id='type-id-14' name='exc' filepath='Python/errors.c' line='521' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyErr_GetHandledException' mangled-name='PyErr_GetHandledException' filepath='Python/errors.c' line='514' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_GetHandledException'> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyErr_GetHandledException' mangled-name='_PyErr_GetHandledException' filepath='Python/errors.c' line='503' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyErr_GetHandledException'> - <parameter type-id='type-id-10' name='tstate' filepath='Python/errors.c' line='503' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyErr_GetExcInfo' mangled-name='_PyErr_GetExcInfo' filepath='Python/errors.c' line='488' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyErr_GetExcInfo'> - <parameter type-id='type-id-10' name='tstate' filepath='Python/errors.c' line='488' column='1'/> - <parameter type-id='type-id-22' name='p_type' filepath='Python/errors.c' line='489' column='1'/> - <parameter type-id='type-id-22' name='p_value' filepath='Python/errors.c' line='489' column='1'/> - <parameter type-id='type-id-22' name='p_traceback' filepath='Python/errors.c' line='489' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyErr_Clear' mangled-name='PyErr_Clear' filepath='Python/errors.c' line='453' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_Clear'> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_PyErr_Clear' mangled-name='_PyErr_Clear' filepath='Python/errors.c' line='446' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyErr_Clear'> - <parameter type-id='type-id-10' name='tstate' filepath='Objects/object.c' line='2291' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyErr_Fetch' mangled-name='PyErr_Fetch' filepath='Python/errors.c' line='438' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_Fetch'> - <parameter type-id='type-id-22' name='p_type' filepath='Python/errors.c' line='534' column='1'/> - <parameter type-id='type-id-22' name='p_value' filepath='Python/errors.c' line='534' column='1'/> - <parameter type-id='type-id-22' name='p_traceback' filepath='Python/errors.c' line='534' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_PyErr_Fetch' mangled-name='_PyErr_Fetch' filepath='Python/errors.c' line='424' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyErr_Fetch'> - <parameter type-id='type-id-10' name='tstate' filepath='Python/errors.c' line='424' column='1'/> - <parameter type-id='type-id-22' name='p_type' filepath='Python/errors.c' line='424' column='1'/> - <parameter type-id='type-id-22' name='p_value' filepath='Python/errors.c' line='424' column='1'/> - <parameter type-id='type-id-22' name='p_traceback' filepath='Python/errors.c' line='425' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyErr_NormalizeException' mangled-name='PyErr_NormalizeException' filepath='Python/errors.c' line='416' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_NormalizeException'> - <parameter type-id='type-id-22' name='p_type' filepath='Python/errors.c' line='534' column='1'/> - <parameter type-id='type-id-22' name='p_value' filepath='Python/errors.c' line='534' column='1'/> - <parameter type-id='type-id-22' name='p_traceback' filepath='Python/errors.c' line='534' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_PyErr_NormalizeException' mangled-name='_PyErr_NormalizeException' filepath='Python/errors.c' line='309' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyErr_NormalizeException'> - <parameter type-id='type-id-10' name='tstate' filepath='Python/errors.c' line='309' column='1'/> - <parameter type-id='type-id-22' name='exc' filepath='Python/errors.c' line='309' column='1'/> - <parameter type-id='type-id-22' name='val' filepath='Python/errors.c' line='310' column='1'/> - <parameter type-id='type-id-22' name='tb' filepath='Python/errors.c' line='310' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyErr_ExceptionMatches' mangled-name='PyErr_ExceptionMatches' filepath='Python/errors.c' line='291' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_ExceptionMatches'> - <parameter type-id='type-id-14' name='obj' filepath='Objects/abstract.c' line='2845' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyErr_ExceptionMatches' mangled-name='_PyErr_ExceptionMatches' filepath='Python/errors.c' line='284' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyErr_ExceptionMatches'> - <parameter type-id='type-id-10' name='tstate' filepath='Objects/object.c' line='2277' column='1'/> - <parameter type-id='type-id-14' name='op' filepath='Objects/object.c' line='2277' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyErr_GivenExceptionMatches' mangled-name='PyErr_GivenExceptionMatches' filepath='Python/errors.c' line='252' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_GivenExceptionMatches'> - <parameter type-id='type-id-14' name='op' filepath='Objects/funcobject.c' line='319' column='1'/> - <parameter type-id='type-id-14' name='annotations' filepath='Objects/funcobject.c' line='319' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyErr_Occurred' mangled-name='PyErr_Occurred' filepath='Python/errors.c' line='241' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_Occurred'> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyErr_SetString' mangled-name='PyErr_SetString' filepath='Python/errors.c' line='233' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_SetString'> - <parameter type-id='type-id-14' name='exception' filepath='Python/errors.c' line='233' column='1'/> - <parameter type-id='type-id-3' name='string' filepath='Python/errors.c' line='233' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_PyErr_SetString' mangled-name='_PyErr_SetString' filepath='Python/errors.c' line='224' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyErr_SetString'> - <parameter type-id='type-id-10' name='tstate' filepath='Python/errors.c' line='224' column='1'/> - <parameter type-id='type-id-14' name='exception' filepath='Python/errors.c' line='224' column='1'/> - <parameter type-id='type-id-3' name='string' filepath='Python/errors.c' line='225' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyErr_SetNone' mangled-name='PyErr_SetNone' filepath='Python/errors.c' line='216' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_SetNone'> - <parameter type-id='type-id-14' name='m' filepath='Objects/moduleobject.c' line='578' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_PyErr_SetNone' mangled-name='_PyErr_SetNone' filepath='Python/errors.c' line='209' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyErr_SetNone'> - <parameter type-id='type-id-10' name='tstate' filepath='Python/errors.c' line='209' column='1'/> - <parameter type-id='type-id-14' name='exception' filepath='Python/errors.c' line='209' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_PyErr_SetKeyError' mangled-name='_PyErr_SetKeyError' filepath='Python/errors.c' line='196' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyErr_SetKeyError'> - <parameter type-id='type-id-14' name='op' filepath='Objects/object.c' line='2366' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyErr_SetObject' mangled-name='PyErr_SetObject' filepath='Python/errors.c' line='186' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_SetObject'> - <parameter type-id='type-id-14' name='exception' filepath='Python/errors.c' line='186' column='1'/> - <parameter type-id='type-id-14' name='value' filepath='Python/errors.c' line='186' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_PyErr_SetObject' mangled-name='_PyErr_SetObject' filepath='Python/errors.c' line='108' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyErr_SetObject'> - <parameter type-id='type-id-10' name='tstate' filepath='Python/errors.c' line='108' column='1'/> - <parameter type-id='type-id-14' name='exception' filepath='Python/errors.c' line='108' column='1'/> - <parameter type-id='type-id-14' name='value' filepath='Python/errors.c' line='108' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_PyErr_GetTopmostException' mangled-name='_PyErr_GetTopmostException' filepath='Python/errors.c' line='68' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyErr_GetTopmostException'> - <parameter type-id='type-id-10' name='tstate' filepath='Python/errors.c' line='68' column='1'/> - <return type-id='type-id-15'/> - </function-decl> - <function-decl name='PyErr_Restore' mangled-name='PyErr_Restore' filepath='Python/errors.c' line='60' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_Restore'> - <parameter type-id='type-id-14' name='type' filepath='Python/errors.c' line='60' column='1'/> - <parameter type-id='type-id-14' name='value' filepath='Python/errors.c' line='60' column='1'/> - <parameter type-id='type-id-14' name='traceback' filepath='Python/errors.c' line='60' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_PyErr_Restore' mangled-name='_PyErr_Restore' filepath='Python/errors.c' line='32' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyErr_Restore'> - <parameter type-id='type-id-10' name='tstate' filepath='Python/errors.c' line='32' column='1'/> - <parameter type-id='type-id-14' name='type' filepath='Python/errors.c' line='32' column='1'/> - <parameter type-id='type-id-14' name='value' filepath='Python/errors.c' line='32' column='1'/> - <parameter type-id='type-id-14' name='traceback' filepath='Python/errors.c' line='33' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Python/frozenmain.c' comp-dir-path='/src' language='LANG_C99'> - <function-decl name='Py_FrozenMain' mangled-name='Py_FrozenMain' filepath='Python/frozenmain.c' line='16' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_FrozenMain'> - <parameter type-id='type-id-8' name='argc' filepath='Python/frozenmain.c' line='16' column='1'/> - <parameter type-id='type-id-494' name='argv' filepath='Python/frozenmain.c' line='16' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Python/getargs.c' comp-dir-path='/src' language='LANG_C99'> - <function-decl name='_PyArg_NoKwnames' mangled-name='_PyArg_NoKwnames' filepath='Python/getargs.c' line='2921' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyArg_NoKwnames'> - <parameter type-id='type-id-3' name='funcname' filepath='Python/getargs.c' line='2921' column='1'/> - <parameter type-id='type-id-14' name='kwnames' filepath='Python/getargs.c' line='2921' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyArg_NoPositional' mangled-name='_PyArg_NoPositional' filepath='Python/getargs.c' line='2904' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyArg_NoPositional'> - <parameter type-id='type-id-3' name='funcname' filepath='Python/getargs.c' line='2921' column='1'/> - <parameter type-id='type-id-14' name='kwnames' filepath='Python/getargs.c' line='2921' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyArg_NoKeywords' mangled-name='_PyArg_NoKeywords' filepath='Python/getargs.c' line='2885' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyArg_NoKeywords'> - <parameter type-id='type-id-3' name='funcname' filepath='Python/getargs.c' line='2921' column='1'/> - <parameter type-id='type-id-14' name='kwnames' filepath='Python/getargs.c' line='2921' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyArg_UnpackStack' mangled-name='_PyArg_UnpackStack' filepath='Python/getargs.c' line='2858' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyArg_UnpackStack'> - <parameter type-id='type-id-200' name='args' filepath='Python/getargs.c' line='2858' column='1'/> - <parameter type-id='type-id-36' name='nargs' filepath='Python/getargs.c' line='2858' column='1'/> - <parameter type-id='type-id-3' name='name' filepath='Python/getargs.c' line='2858' column='1'/> - <parameter type-id='type-id-36' name='min' filepath='Python/getargs.c' line='2859' column='1'/> - <parameter type-id='type-id-36' name='max' filepath='Python/getargs.c' line='2859' column='1'/> - <parameter is-variadic='yes'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyArg_UnpackTuple' mangled-name='PyArg_UnpackTuple' filepath='Python/getargs.c' line='2832' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyArg_UnpackTuple'> - <parameter type-id='type-id-14' name='args' filepath='Python/getargs.c' line='2832' column='1'/> - <parameter type-id='type-id-3' name='name' filepath='Python/getargs.c' line='2832' column='1'/> - <parameter type-id='type-id-36' name='min' filepath='Python/getargs.c' line='2832' column='1'/> - <parameter type-id='type-id-36' name='max' filepath='Python/getargs.c' line='2832' column='1'/> - <parameter is-variadic='yes'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyArg_CheckPositional' mangled-name='_PyArg_CheckPositional' filepath='Python/getargs.c' line='2770' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyArg_CheckPositional'> - <parameter type-id='type-id-3' name='name' filepath='Python/getargs.c' line='2770' column='1'/> - <parameter type-id='type-id-36' name='nargs' filepath='Python/getargs.c' line='2770' column='1'/> - <parameter type-id='type-id-36' name='min' filepath='Python/getargs.c' line='2771' column='1'/> - <parameter type-id='type-id-36' name='max' filepath='Python/getargs.c' line='2771' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <class-decl name='_PyArg_Parser' size-in-bits='512' is-struct='yes' visibility='default' filepath='./Include/cpython/modsupport.h' line='51' column='1' id='type-id-766'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='format' type-id='type-id-3' visibility='default' filepath='./Include/cpython/modsupport.h' line='52' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='keywords' type-id='type-id-767' visibility='default' filepath='./Include/cpython/modsupport.h' line='53' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='fname' type-id='type-id-3' visibility='default' filepath='./Include/cpython/modsupport.h' line='54' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='custom_msg' type-id='type-id-3' visibility='default' filepath='./Include/cpython/modsupport.h' line='55' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='256'> - <var-decl name='pos' type-id='type-id-8' visibility='default' filepath='./Include/cpython/modsupport.h' line='56' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='288'> - <var-decl name='min' type-id='type-id-8' visibility='default' filepath='./Include/cpython/modsupport.h' line='57' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='320'> - <var-decl name='max' type-id='type-id-8' visibility='default' filepath='./Include/cpython/modsupport.h' line='58' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='384'> - <var-decl name='kwtuple' type-id='type-id-14' visibility='default' filepath='./Include/cpython/modsupport.h' line='59' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='448'> - <var-decl name='next' type-id='type-id-768' visibility='default' filepath='./Include/cpython/modsupport.h' line='60' column='1'/> - </data-member> - </class-decl> - <pointer-type-def type-id='type-id-4' size-in-bits='64' id='type-id-767'/> - <pointer-type-def type-id='type-id-766' size-in-bits='64' id='type-id-768'/> - <function-decl name='_PyArg_UnpackKeywordsWithVararg' mangled-name='_PyArg_UnpackKeywordsWithVararg' filepath='Python/getargs.c' line='2470' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyArg_UnpackKeywordsWithVararg'> - <parameter type-id='type-id-200' name='args' filepath='Python/getargs.c' line='2470' column='1'/> - <parameter type-id='type-id-36' name='nargs' filepath='Python/getargs.c' line='2470' column='1'/> - <parameter type-id='type-id-14' name='kwargs' filepath='Python/getargs.c' line='2471' column='1'/> - <parameter type-id='type-id-14' name='kwnames' filepath='Python/getargs.c' line='2471' column='1'/> - <parameter type-id='type-id-768' name='parser' filepath='Python/getargs.c' line='2472' column='1'/> - <parameter type-id='type-id-8' name='minpos' filepath='Python/getargs.c' line='2473' column='1'/> - <parameter type-id='type-id-8' name='maxpos' filepath='Python/getargs.c' line='2473' column='1'/> - <parameter type-id='type-id-8' name='minkw' filepath='Python/getargs.c' line='2473' column='1'/> - <parameter type-id='type-id-8' name='vararg' filepath='Python/getargs.c' line='2474' column='1'/> - <parameter type-id='type-id-22' name='buf' filepath='Python/getargs.c' line='2474' column='1'/> - <return type-id='type-id-200'/> - </function-decl> - <function-decl name='_PyArg_UnpackKeywords' mangled-name='_PyArg_UnpackKeywords' filepath='Python/getargs.c' line='2269' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyArg_UnpackKeywords'> - <parameter type-id='type-id-200' name='args' filepath='Python/getargs.c' line='2269' column='1'/> - <parameter type-id='type-id-36' name='nargs' filepath='Python/getargs.c' line='2269' column='1'/> - <parameter type-id='type-id-14' name='kwargs' filepath='Python/getargs.c' line='2270' column='1'/> - <parameter type-id='type-id-14' name='kwnames' filepath='Python/getargs.c' line='2270' column='1'/> - <parameter type-id='type-id-768' name='parser' filepath='Python/getargs.c' line='2271' column='1'/> - <parameter type-id='type-id-8' name='minpos' filepath='Python/getargs.c' line='2272' column='1'/> - <parameter type-id='type-id-8' name='maxpos' filepath='Python/getargs.c' line='2272' column='1'/> - <parameter type-id='type-id-8' name='minkw' filepath='Python/getargs.c' line='2272' column='1'/> - <parameter type-id='type-id-22' name='buf' filepath='Python/getargs.c' line='2273' column='1'/> - <return type-id='type-id-200'/> - </function-decl> - <function-decl name='PyArg_ValidateKeywordArguments' mangled-name='PyArg_ValidateKeywordArguments' filepath='Python/getargs.c' line='1558' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyArg_ValidateKeywordArguments'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2303' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyArg_VaParseTupleAndKeywordsFast_SizeT' mangled-name='_PyArg_VaParseTupleAndKeywordsFast_SizeT' filepath='Python/getargs.c' line='1544' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyArg_VaParseTupleAndKeywordsFast_SizeT'> - <parameter type-id='type-id-14' name='args' filepath='Python/getargs.c' line='1544' column='1'/> - <parameter type-id='type-id-14' name='keywords' filepath='Python/getargs.c' line='1544' column='1'/> - <parameter type-id='type-id-768' name='parser' filepath='Python/getargs.c' line='1545' column='1'/> - <parameter type-id='type-id-496' name='va' filepath='Python/getargs.c' line='1545' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyArg_VaParseTupleAndKeywordsFast' mangled-name='_PyArg_VaParseTupleAndKeywordsFast' filepath='Python/getargs.c' line='1530' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyArg_VaParseTupleAndKeywordsFast'> - <parameter type-id='type-id-14' name='args' filepath='Python/getargs.c' line='1544' column='1'/> - <parameter type-id='type-id-14' name='keywords' filepath='Python/getargs.c' line='1544' column='1'/> - <parameter type-id='type-id-768' name='parser' filepath='Python/getargs.c' line='1545' column='1'/> - <parameter type-id='type-id-496' name='va' filepath='Python/getargs.c' line='1545' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyArg_ParseStackAndKeywords_SizeT' mangled-name='_PyArg_ParseStackAndKeywords_SizeT' filepath='Python/getargs.c' line='1516' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyArg_ParseStackAndKeywords_SizeT'> - <parameter type-id='type-id-200' name='args' filepath='Python/getargs.c' line='1516' column='1'/> - <parameter type-id='type-id-36' name='nargs' filepath='Python/getargs.c' line='1516' column='1'/> - <parameter type-id='type-id-14' name='kwnames' filepath='Python/getargs.c' line='1516' column='1'/> - <parameter type-id='type-id-768' name='parser' filepath='Python/getargs.c' line='1517' column='1'/> - <parameter is-variadic='yes'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyArg_ParseStackAndKeywords' mangled-name='_PyArg_ParseStackAndKeywords' filepath='Python/getargs.c' line='1503' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyArg_ParseStackAndKeywords'> - <parameter type-id='type-id-200' name='args' filepath='Python/getargs.c' line='1516' column='1'/> - <parameter type-id='type-id-36' name='nargs' filepath='Python/getargs.c' line='1516' column='1'/> - <parameter type-id='type-id-14' name='kwnames' filepath='Python/getargs.c' line='1516' column='1'/> - <parameter type-id='type-id-768' name='parser' filepath='Python/getargs.c' line='1517' column='1'/> - <parameter is-variadic='yes'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyArg_ParseTupleAndKeywordsFast_SizeT' mangled-name='_PyArg_ParseTupleAndKeywordsFast_SizeT' filepath='Python/getargs.c' line='1490' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyArg_ParseTupleAndKeywordsFast_SizeT'> - <parameter type-id='type-id-14' name='args' filepath='Python/getargs.c' line='1490' column='1'/> - <parameter type-id='type-id-14' name='keywords' filepath='Python/getargs.c' line='1490' column='1'/> - <parameter type-id='type-id-768' name='parser' filepath='Python/getargs.c' line='1491' column='1'/> - <parameter is-variadic='yes'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyArg_ParseTupleAndKeywordsFast' mangled-name='_PyArg_ParseTupleAndKeywordsFast' filepath='Python/getargs.c' line='1477' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyArg_ParseTupleAndKeywordsFast'> - <parameter type-id='type-id-14' name='args' filepath='Python/getargs.c' line='1490' column='1'/> - <parameter type-id='type-id-14' name='keywords' filepath='Python/getargs.c' line='1490' column='1'/> - <parameter type-id='type-id-768' name='parser' filepath='Python/getargs.c' line='1491' column='1'/> - <parameter is-variadic='yes'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyArg_VaParseTupleAndKeywords_SizeT' mangled-name='_PyArg_VaParseTupleAndKeywords_SizeT' filepath='Python/getargs.c' line='1451' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyArg_VaParseTupleAndKeywords_SizeT'> - <parameter type-id='type-id-14' name='args' filepath='Python/getargs.c' line='1451' column='1'/> - <parameter type-id='type-id-14' name='keywords' filepath='Python/getargs.c' line='1452' column='1'/> - <parameter type-id='type-id-3' name='format' filepath='Python/getargs.c' line='1453' column='1'/> - <parameter type-id='type-id-494' name='kwlist' filepath='Python/getargs.c' line='1454' column='1'/> - <parameter type-id='type-id-496' name='va' filepath='Python/getargs.c' line='1454' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyArg_VaParseTupleAndKeywords' mangled-name='PyArg_VaParseTupleAndKeywords' filepath='Python/getargs.c' line='1426' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyArg_VaParseTupleAndKeywords'> - <parameter type-id='type-id-14' name='args' filepath='Python/getargs.c' line='1451' column='1'/> - <parameter type-id='type-id-14' name='keywords' filepath='Python/getargs.c' line='1452' column='1'/> - <parameter type-id='type-id-3' name='format' filepath='Python/getargs.c' line='1453' column='1'/> - <parameter type-id='type-id-494' name='kwlist' filepath='Python/getargs.c' line='1454' column='1'/> - <parameter type-id='type-id-496' name='va' filepath='Python/getargs.c' line='1454' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyArg_ParseTupleAndKeywords_SizeT' mangled-name='_PyArg_ParseTupleAndKeywords_SizeT' filepath='Python/getargs.c' line='1400' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyArg_ParseTupleAndKeywords_SizeT'> - <parameter type-id='type-id-14' name='args' filepath='Python/getargs.c' line='1400' column='1'/> - <parameter type-id='type-id-14' name='keywords' filepath='Python/getargs.c' line='1401' column='1'/> - <parameter type-id='type-id-3' name='format' filepath='Python/getargs.c' line='1402' column='1'/> - <parameter type-id='type-id-494' name='kwlist' filepath='Python/getargs.c' line='1403' column='1'/> - <parameter is-variadic='yes'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyArg_ParseTupleAndKeywords' mangled-name='PyArg_ParseTupleAndKeywords' filepath='Python/getargs.c' line='1376' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyArg_ParseTupleAndKeywords'> - <parameter type-id='type-id-14' name='args' filepath='Python/getargs.c' line='1400' column='1'/> - <parameter type-id='type-id-14' name='keywords' filepath='Python/getargs.c' line='1401' column='1'/> - <parameter type-id='type-id-3' name='format' filepath='Python/getargs.c' line='1402' column='1'/> - <parameter type-id='type-id-494' name='kwlist' filepath='Python/getargs.c' line='1403' column='1'/> - <parameter is-variadic='yes'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyArg_BadArgument' mangled-name='_PyArg_BadArgument' filepath='Python/getargs.c' line='618' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyArg_BadArgument'> - <parameter type-id='type-id-3' name='fname' filepath='Python/getargs.c' line='618' column='1'/> - <parameter type-id='type-id-3' name='displayname' filepath='Python/getargs.c' line='618' column='1'/> - <parameter type-id='type-id-3' name='expected' filepath='Python/getargs.c' line='619' column='1'/> - <parameter type-id='type-id-14' name='arg' filepath='Python/getargs.c' line='619' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_PyArg_VaParse_SizeT' mangled-name='_PyArg_VaParse_SizeT' filepath='Python/getargs.c' line='187' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyArg_VaParse_SizeT'> - <parameter type-id='type-id-14' name='args' filepath='Python/getargs.c' line='187' column='1'/> - <parameter type-id='type-id-3' name='format' filepath='Python/getargs.c' line='187' column='1'/> - <parameter type-id='type-id-496' name='va' filepath='Python/getargs.c' line='187' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyArg_VaParse' mangled-name='PyArg_VaParse' filepath='Python/getargs.c' line='174' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyArg_VaParse'> - <parameter type-id='type-id-14' name='args' filepath='Python/getargs.c' line='187' column='1'/> - <parameter type-id='type-id-3' name='format' filepath='Python/getargs.c' line='187' column='1'/> - <parameter type-id='type-id-496' name='va' filepath='Python/getargs.c' line='187' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyArg_ParseStack_SizeT' mangled-name='_PyArg_ParseStack_SizeT' filepath='Python/getargs.c' line='161' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyArg_ParseStack_SizeT'> - <parameter type-id='type-id-200' name='args' filepath='Python/getargs.c' line='161' column='1'/> - <parameter type-id='type-id-36' name='nargs' filepath='Python/getargs.c' line='161' column='1'/> - <parameter type-id='type-id-3' name='format' filepath='Python/getargs.c' line='161' column='1'/> - <parameter is-variadic='yes'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyArg_ParseStack' mangled-name='_PyArg_ParseStack' filepath='Python/getargs.c' line='149' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyArg_ParseStack'> - <parameter type-id='type-id-200' name='args' filepath='Python/getargs.c' line='161' column='1'/> - <parameter type-id='type-id-36' name='nargs' filepath='Python/getargs.c' line='161' column='1'/> - <parameter type-id='type-id-3' name='format' filepath='Python/getargs.c' line='161' column='1'/> - <parameter is-variadic='yes'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyArg_ParseTuple_SizeT' mangled-name='_PyArg_ParseTuple_SizeT' filepath='Python/getargs.c' line='136' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyArg_ParseTuple_SizeT'> - <parameter type-id='type-id-14' name='args' filepath='Python/getargs.c' line='136' column='1'/> - <parameter type-id='type-id-3' name='format' filepath='Python/getargs.c' line='136' column='1'/> - <parameter is-variadic='yes'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyArg_ParseTuple' mangled-name='PyArg_ParseTuple' filepath='Python/getargs.c' line='124' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyArg_ParseTuple'> - <parameter type-id='type-id-14' name='args' filepath='Python/getargs.c' line='136' column='1'/> - <parameter type-id='type-id-3' name='format' filepath='Python/getargs.c' line='136' column='1'/> - <parameter is-variadic='yes'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyArg_Parse_SizeT' mangled-name='_PyArg_Parse_SizeT' filepath='Python/getargs.c' line='111' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyArg_Parse_SizeT'> - <parameter type-id='type-id-14' name='args' filepath='Python/getargs.c' line='136' column='1'/> - <parameter type-id='type-id-3' name='format' filepath='Python/getargs.c' line='136' column='1'/> - <parameter is-variadic='yes'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyArg_Parse' mangled-name='PyArg_Parse' filepath='Python/getargs.c' line='99' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyArg_Parse'> - <parameter type-id='type-id-14' name='args' filepath='Python/getargs.c' line='136' column='1'/> - <parameter type-id='type-id-3' name='format' filepath='Python/getargs.c' line='136' column='1'/> - <parameter is-variadic='yes'/> - <return type-id='type-id-8'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Python/getcompiler.c' comp-dir-path='/src' language='LANG_C99'> - <function-decl name='Py_GetCompiler' mangled-name='Py_GetCompiler' filepath='Python/getcompiler.c' line='24' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_GetCompiler'> - <return type-id='type-id-3'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Python/getcopyright.c' comp-dir-path='/src' language='LANG_C99'> - <function-decl name='Py_GetCopyright' mangled-name='Py_GetCopyright' filepath='Python/getcopyright.c' line='20' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_GetCopyright'> - <return type-id='type-id-3'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='./Python/getplatform.c' comp-dir-path='/src' language='LANG_C99'> - <function-decl name='Py_GetPlatform' mangled-name='Py_GetPlatform' filepath='./Python/getplatform.c' line='9' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_GetPlatform'> - <return type-id='type-id-3'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Python/getversion.c' comp-dir-path='/src' language='LANG_C99'> - <qualified-type-def type-id='type-id-16' const='yes' id='type-id-769'/> - <var-decl name='Py_Version' type-id='type-id-769' mangled-name='Py_Version' visibility='default' filepath='./Include/pylifecycle.h' line='66' column='1' elf-symbol-id='Py_Version'/> - <function-decl name='Py_GetVersion' mangled-name='Py_GetVersion' filepath='Python/getversion.c' line='9' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_GetVersion'> - <return type-id='type-id-3'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Python/hamt.c' comp-dir-path='/src' language='LANG_C99'> - <var-decl name='_PyHamtItems_Type' type-id='type-id-112' visibility='default' filepath='./Include/internal/pycore_hamt.h' line='29' column='1'/> - <var-decl name='_PyHamtKeys_Type' type-id='type-id-112' visibility='default' filepath='./Include/internal/pycore_hamt.h' line='27' column='1'/> - <var-decl name='_PyHamtValues_Type' type-id='type-id-112' visibility='default' filepath='./Include/internal/pycore_hamt.h' line='28' column='1'/> - <var-decl name='_PyHamt_Type' type-id='type-id-112' visibility='default' filepath='./Include/internal/pycore_hamt.h' line='23' column='1'/> - <var-decl name='_PyHamt_ArrayNode_Type' type-id='type-id-112' visibility='default' filepath='./Include/internal/pycore_hamt.h' line='24' column='1'/> - <var-decl name='_PyHamt_BitmapNode_Type' type-id='type-id-112' visibility='default' filepath='./Include/internal/pycore_hamt.h' line='25' column='1'/> - <var-decl name='_PyHamt_CollisionNode_Type' type-id='type-id-112' visibility='default' filepath='./Include/internal/pycore_hamt.h' line='26' column='1'/> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Python/hashtable.c' comp-dir-path='/src' language='LANG_C99'> - <class-decl name='_Py_hashtable_t' size-in-bits='640' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_hashtable.h' line='60' column='1' id='type-id-770'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='nentries' type-id='type-id-54' visibility='default' filepath='./Include/internal/pycore_hashtable.h' line='61' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='nbuckets' type-id='type-id-54' visibility='default' filepath='./Include/internal/pycore_hashtable.h' line='62' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='buckets' type-id='type-id-771' visibility='default' filepath='./Include/internal/pycore_hashtable.h' line='63' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='get_entry_func' type-id='type-id-772' visibility='default' filepath='./Include/internal/pycore_hashtable.h' line='65' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='256'> - <var-decl name='hash_func' type-id='type-id-773' visibility='default' filepath='./Include/internal/pycore_hashtable.h' line='66' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='320'> - <var-decl name='compare_func' type-id='type-id-774' visibility='default' filepath='./Include/internal/pycore_hashtable.h' line='67' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='384'> - <var-decl name='key_destroy_func' type-id='type-id-775' visibility='default' filepath='./Include/internal/pycore_hashtable.h' line='68' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='448'> - <var-decl name='value_destroy_func' type-id='type-id-775' visibility='default' filepath='./Include/internal/pycore_hashtable.h' line='69' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='512'> - <var-decl name='alloc' type-id='type-id-776' visibility='default' filepath='./Include/internal/pycore_hashtable.h' line='70' column='1'/> - </data-member> - </class-decl> - <class-decl name='__anonymous_struct__' size-in-bits='64' is-struct='yes' is-anonymous='yes' naming-typedef-id='type-id-777' visibility='default' filepath='./Include/internal/pycore_hashtable.h' line='17' column='1' id='type-id-778'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='head' type-id='type-id-779' visibility='default' filepath='./Include/internal/pycore_hashtable.h' line='18' column='1'/> - </data-member> - </class-decl> - <class-decl name='_Py_slist_item_s' size-in-bits='64' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_hashtable.h' line='13' column='1' id='type-id-780'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='next' type-id='type-id-781' visibility='default' filepath='./Include/internal/pycore_hashtable.h' line='14' column='1'/> - </data-member> - </class-decl> - <pointer-type-def type-id='type-id-780' size-in-bits='64' id='type-id-781'/> - <typedef-decl name='_Py_slist_item_t' type-id='type-id-780' filepath='./Include/internal/pycore_hashtable.h' line='15' column='1' id='type-id-782'/> - <pointer-type-def type-id='type-id-782' size-in-bits='64' id='type-id-779'/> - <typedef-decl name='_Py_slist_t' type-id='type-id-778' filepath='./Include/internal/pycore_hashtable.h' line='19' column='1' id='type-id-777'/> - <pointer-type-def type-id='type-id-777' size-in-bits='64' id='type-id-771'/> - <class-decl name='__anonymous_struct__' size-in-bits='256' is-struct='yes' is-anonymous='yes' naming-typedef-id='type-id-783' visibility='default' filepath='./Include/internal/pycore_hashtable.h' line='28' column='1' id='type-id-784'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='_Py_slist_item' type-id='type-id-782' visibility='default' filepath='./Include/internal/pycore_hashtable.h' line='30' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='key_hash' type-id='type-id-785' visibility='default' filepath='./Include/internal/pycore_hashtable.h' line='32' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='key' type-id='type-id-18' visibility='default' filepath='./Include/internal/pycore_hashtable.h' line='33' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='value' type-id='type-id-18' visibility='default' filepath='./Include/internal/pycore_hashtable.h' line='34' column='1'/> - </data-member> - </class-decl> - <typedef-decl name='Py_uhash_t' type-id='type-id-54' filepath='./Include/pyport.h' line='148' column='1' id='type-id-785'/> - <typedef-decl name='_Py_hashtable_entry_t' type-id='type-id-784' filepath='./Include/internal/pycore_hashtable.h' line='35' column='1' id='type-id-783'/> - <pointer-type-def type-id='type-id-783' size-in-bits='64' id='type-id-786'/> - <typedef-decl name='_Py_hashtable_t' type-id='type-id-770' filepath='./Include/internal/pycore_hashtable.h' line='42' column='1' id='type-id-787'/> - <pointer-type-def type-id='type-id-787' size-in-bits='64' id='type-id-788'/> - <pointer-type-def type-id='type-id-789' size-in-bits='64' id='type-id-790'/> - <typedef-decl name='_Py_hashtable_get_entry_func' type-id='type-id-790' filepath='./Include/internal/pycore_hashtable.h' line='47' column='1' id='type-id-772'/> - <pointer-type-def type-id='type-id-791' size-in-bits='64' id='type-id-792'/> - <typedef-decl name='_Py_hashtable_hash_func' type-id='type-id-792' filepath='./Include/internal/pycore_hashtable.h' line='44' column='1' id='type-id-773'/> - <pointer-type-def type-id='type-id-793' size-in-bits='64' id='type-id-794'/> - <typedef-decl name='_Py_hashtable_compare_func' type-id='type-id-794' filepath='./Include/internal/pycore_hashtable.h' line='45' column='1' id='type-id-774'/> - <typedef-decl name='_Py_hashtable_destroy_func' type-id='type-id-17' filepath='./Include/internal/pycore_hashtable.h' line='46' column='1' id='type-id-775'/> - <class-decl name='__anonymous_struct__' size-in-bits='128' is-struct='yes' is-anonymous='yes' naming-typedef-id='type-id-776' visibility='default' filepath='./Include/internal/pycore_hashtable.h' line='50' column='1' id='type-id-795'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='malloc' type-id='type-id-796' visibility='default' filepath='./Include/internal/pycore_hashtable.h' line='52' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='free' type-id='type-id-17' visibility='default' filepath='./Include/internal/pycore_hashtable.h' line='55' column='1'/> - </data-member> - </class-decl> - <pointer-type-def type-id='type-id-797' size-in-bits='64' id='type-id-796'/> - <typedef-decl name='_Py_hashtable_allocator_t' type-id='type-id-795' filepath='./Include/internal/pycore_hashtable.h' line='56' column='1' id='type-id-776'/> - <function-decl name='_Py_hashtable_destroy' mangled-name='_Py_hashtable_destroy' filepath='Python/hashtable.c' line='404' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_hashtable_destroy'> - <parameter type-id='type-id-788' name='ht' filepath='Python/hashtable.c' line='404' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_Py_hashtable_clear' mangled-name='_Py_hashtable_clear' filepath='Python/hashtable.c' line='385' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_hashtable_clear'> - <parameter type-id='type-id-788' name='ht' filepath='Python/hashtable.c' line='404' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_Py_hashtable_new' mangled-name='_Py_hashtable_new' filepath='Python/hashtable.c' line='363' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_hashtable_new'> - <parameter type-id='type-id-773' name='hash_func' filepath='Python/hashtable.c' line='363' column='1'/> - <parameter type-id='type-id-774' name='compare_func' filepath='Python/hashtable.c' line='364' column='1'/> - <return type-id='type-id-788'/> - </function-decl> - <pointer-type-def type-id='type-id-776' size-in-bits='64' id='type-id-798'/> - <function-decl name='_Py_hashtable_new_full' mangled-name='_Py_hashtable_new_full' filepath='Python/hashtable.c' line='316' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_hashtable_new_full'> - <parameter type-id='type-id-773' name='hash_func' filepath='Python/hashtable.c' line='316' column='1'/> - <parameter type-id='type-id-774' name='compare_func' filepath='Python/hashtable.c' line='317' column='1'/> - <parameter type-id='type-id-775' name='key_destroy_func' filepath='Python/hashtable.c' line='318' column='1'/> - <parameter type-id='type-id-775' name='value_destroy_func' filepath='Python/hashtable.c' line='319' column='1'/> - <parameter type-id='type-id-798' name='allocator' filepath='Python/hashtable.c' line='320' column='1'/> - <return type-id='type-id-788'/> - </function-decl> - <pointer-type-def type-id='type-id-799' size-in-bits='64' id='type-id-800'/> - <typedef-decl name='_Py_hashtable_foreach_func' type-id='type-id-800' filepath='./Include/internal/pycore_hashtable.h' line='96' column='1' id='type-id-801'/> - <function-decl name='_Py_hashtable_foreach' mangled-name='_Py_hashtable_foreach' filepath='Python/hashtable.c' line='261' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_hashtable_foreach'> - <parameter type-id='type-id-788' name='ht' filepath='Python/hashtable.c' line='261' column='1'/> - <parameter type-id='type-id-801' name='func' filepath='Python/hashtable.c' line='262' column='1'/> - <parameter type-id='type-id-18' name='user_data' filepath='Python/hashtable.c' line='263' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_Py_hashtable_get' mangled-name='_Py_hashtable_get' filepath='Python/hashtable.c' line='248' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_hashtable_get'> - <parameter type-id='type-id-788' name='ht' filepath='Python/hashtable.c' line='248' column='1'/> - <parameter type-id='type-id-18' name='key' filepath='Python/hashtable.c' line='248' column='1'/> - <return type-id='type-id-18'/> - </function-decl> - <function-decl name='_Py_hashtable_set' mangled-name='_Py_hashtable_set' filepath='Python/hashtable.c' line='209' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_hashtable_set'> - <parameter type-id='type-id-788' name='ht' filepath='Python/hashtable.c' line='209' column='1'/> - <parameter type-id='type-id-18' name='key' filepath='Python/hashtable.c' line='209' column='1'/> - <parameter type-id='type-id-18' name='value' filepath='Python/hashtable.c' line='209' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_Py_hashtable_steal' mangled-name='_Py_hashtable_steal' filepath='Python/hashtable.c' line='174' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_hashtable_steal'> - <parameter type-id='type-id-788' name='ht' filepath='Python/hashtable.c' line='174' column='1'/> - <parameter type-id='type-id-18' name='key' filepath='Python/hashtable.c' line='174' column='1'/> - <return type-id='type-id-18'/> - </function-decl> - <qualified-type-def type-id='type-id-787' const='yes' id='type-id-802'/> - <pointer-type-def type-id='type-id-802' size-in-bits='64' id='type-id-803'/> - <function-decl name='_Py_hashtable_size' mangled-name='_Py_hashtable_size' filepath='Python/hashtable.c' line='120' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_hashtable_size'> - <parameter type-id='type-id-803' name='ht' filepath='Python/hashtable.c' line='120' column='1'/> - <return type-id='type-id-54'/> - </function-decl> - <function-decl name='_Py_hashtable_compare_direct' mangled-name='_Py_hashtable_compare_direct' filepath='Python/hashtable.c' line='99' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_hashtable_compare_direct'> - <parameter type-id='type-id-18' name='key1' filepath='Python/hashtable.c' line='99' column='1'/> - <parameter type-id='type-id-18' name='key2' filepath='Python/hashtable.c' line='99' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_Py_hashtable_hash_ptr' mangled-name='_Py_hashtable_hash_ptr' filepath='Python/hashtable.c' line='92' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_hashtable_hash_ptr'> - <parameter type-id='type-id-18' name='key' filepath='Python/hashtable.c' line='92' column='1'/> - <return type-id='type-id-785'/> - </function-decl> - <function-type size-in-bits='64' id='type-id-789'> - <parameter type-id='type-id-788'/> - <parameter type-id='type-id-18'/> - <return type-id='type-id-786'/> - </function-type> - <function-type size-in-bits='64' id='type-id-799'> - <parameter type-id='type-id-788'/> - <parameter type-id='type-id-18'/> - <parameter type-id='type-id-18'/> - <parameter type-id='type-id-18'/> - <return type-id='type-id-8'/> - </function-type> - <function-type size-in-bits='64' id='type-id-793'> - <parameter type-id='type-id-18'/> - <parameter type-id='type-id-18'/> - <return type-id='type-id-8'/> - </function-type> - <function-type size-in-bits='64' id='type-id-791'> - <parameter type-id='type-id-18'/> - <return type-id='type-id-785'/> - </function-type> - <function-type size-in-bits='64' id='type-id-797'> - <parameter type-id='type-id-54'/> - <return type-id='type-id-18'/> - </function-type> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Python/import.c' comp-dir-path='/src' language='LANG_C99'> - <class-decl name='_inittab' size-in-bits='128' is-struct='yes' visibility='default' filepath='./Include/cpython/import.h' line='24' column='1' id='type-id-804'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='name' type-id='type-id-3' visibility='default' filepath='./Include/cpython/import.h' line='25' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='initfunc' type-id='type-id-534' visibility='default' filepath='./Include/cpython/import.h' line='26' column='1'/> - </data-member> - </class-decl> - <pointer-type-def type-id='type-id-804' size-in-bits='64' id='type-id-805'/> - <var-decl name='PyImport_Inittab' type-id='type-id-805' mangled-name='PyImport_Inittab' visibility='default' filepath='./Include/cpython/import.h' line='28' column='1' elf-symbol-id='PyImport_Inittab'/> - <function-decl name='_PyImport_GetModuleAttrString' mangled-name='_PyImport_GetModuleAttrString' filepath='Python/import.c' line='2649' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyImport_GetModuleAttrString'> - <parameter type-id='type-id-3' name='encoding' filepath='Python/codecs.c' line='522' column='1'/> - <parameter type-id='type-id-3' name='alternate_command' filepath='Python/codecs.c' line='523' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyImport_GetModuleAttr' mangled-name='_PyImport_GetModuleAttr' filepath='Python/import.c' line='2637' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyImport_GetModuleAttr'> - <parameter type-id='type-id-14' name='v' filepath='Objects/abstract.c' line='1071' column='1'/> - <parameter type-id='type-id-14' name='w' filepath='Objects/abstract.c' line='1071' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyImport_AppendInittab' mangled-name='PyImport_AppendInittab' filepath='Python/import.c' line='2623' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyImport_AppendInittab'> - <parameter type-id='type-id-3' name='name' filepath='Python/import.c' line='2623' column='1'/> - <parameter type-id='type-id-534' name='initfunc' filepath='Python/import.c' line='2623' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyImport_ExtendInittab' mangled-name='PyImport_ExtendInittab' filepath='Python/import.c' line='2577' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyImport_ExtendInittab'> - <parameter type-id='type-id-805' name='newtab' filepath='Python/import.c' line='2577' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyInit__imp' mangled-name='PyInit__imp' filepath='Python/import.c' line='2516' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInit__imp'> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyImport_Import' mangled-name='PyImport_Import' filepath='Python/import.c' line='1975' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyImport_Import'> - <parameter type-id='type-id-14' name='module_name' filepath='Python/import.c' line='1975' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyImport_ReloadModule' mangled-name='PyImport_ReloadModule' filepath='Python/import.c' line='1944' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyImport_ReloadModule'> - <parameter type-id='type-id-14' name='v' filepath='Objects/abstract.c' line='2122' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyImport_ImportModuleLevel' mangled-name='PyImport_ImportModuleLevel' filepath='Python/import.c' line='1926' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyImport_ImportModuleLevel'> - <parameter type-id='type-id-3' name='name' filepath='Python/import.c' line='1926' column='1'/> - <parameter type-id='type-id-14' name='globals' filepath='Python/import.c' line='1926' column='1'/> - <parameter type-id='type-id-14' name='locals' filepath='Python/import.c' line='1926' column='1'/> - <parameter type-id='type-id-14' name='fromlist' filepath='Python/import.c' line='1927' column='1'/> - <parameter type-id='type-id-8' name='level' filepath='Python/import.c' line='1927' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyImport_ImportModuleLevelObject' mangled-name='PyImport_ImportModuleLevelObject' filepath='Python/import.c' line='1775' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyImport_ImportModuleLevelObject'> - <parameter type-id='type-id-14' name='name' filepath='Python/import.c' line='1775' column='1'/> - <parameter type-id='type-id-14' name='globals' filepath='Python/import.c' line='1775' column='1'/> - <parameter type-id='type-id-14' name='locals' filepath='Python/import.c' line='1776' column='1'/> - <parameter type-id='type-id-14' name='fromlist' filepath='Python/import.c' line='1776' column='1'/> - <parameter type-id='type-id-8' name='level' filepath='Python/import.c' line='1777' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyImport_GetModule' mangled-name='PyImport_GetModule' filepath='Python/import.c' line='1758' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyImport_GetModule'> - <parameter type-id='type-id-14' name='v' filepath='Objects/abstract.c' line='2122' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyImport_ImportModuleNoBlock' mangled-name='PyImport_ImportModuleNoBlock' filepath='Python/import.c' line='1468' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyImport_ImportModuleNoBlock'> - <parameter type-id='type-id-3' name='encoding' filepath='Python/codecs.c' line='356' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyImport_ImportModule' mangled-name='PyImport_ImportModule' filepath='Python/import.c' line='1444' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyImport_ImportModule'> - <parameter type-id='type-id-3' name='str' filepath='Objects/bytesobject.c' line='147' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyImport_ImportFrozenModule' mangled-name='PyImport_ImportFrozenModule' filepath='Python/import.c' line='1427' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyImport_ImportFrozenModule'> - <parameter type-id='type-id-3' name='name' filepath='Python/import.c' line='1427' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyImport_ImportFrozenModuleObject' mangled-name='PyImport_ImportFrozenModuleObject' filepath='Python/import.c' line='1350' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyImport_ImportFrozenModuleObject'> - <parameter type-id='type-id-14' name='name' filepath='Python/import.c' line='1350' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyImport_GetImporter' mangled-name='PyImport_GetImporter' filepath='Python/import.c' line='950' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyImport_GetImporter'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2817' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyImport_ExecCodeModuleObject' mangled-name='PyImport_ExecCodeModuleObject' filepath='Python/import.c' line='782' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyImport_ExecCodeModuleObject'> - <parameter type-id='type-id-14' name='name' filepath='Python/import.c' line='782' column='1'/> - <parameter type-id='type-id-14' name='co' filepath='Python/import.c' line='782' column='1'/> - <parameter type-id='type-id-14' name='pathname' filepath='Python/import.c' line='782' column='1'/> - <parameter type-id='type-id-14' name='cpathname' filepath='Python/import.c' line='783' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyImport_ExecCodeModuleWithPathnames' mangled-name='PyImport_ExecCodeModuleWithPathnames' filepath='Python/import.c' line='680' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyImport_ExecCodeModuleWithPathnames'> - <parameter type-id='type-id-3' name='name' filepath='Python/import.c' line='680' column='1'/> - <parameter type-id='type-id-14' name='co' filepath='Python/import.c' line='680' column='1'/> - <parameter type-id='type-id-3' name='pathname' filepath='Python/import.c' line='681' column='1'/> - <parameter type-id='type-id-3' name='cpathname' filepath='Python/import.c' line='682' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyImport_ExecCodeModuleEx' mangled-name='PyImport_ExecCodeModuleEx' filepath='Python/import.c' line='673' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyImport_ExecCodeModuleEx'> - <parameter type-id='type-id-3' name='encoding' filepath='Python/codecs.c' line='380' column='1'/> - <parameter type-id='type-id-14' name='stream' filepath='Python/codecs.c' line='381' column='1'/> - <parameter type-id='type-id-3' name='errors' filepath='Python/codecs.c' line='382' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyImport_ExecCodeModule' mangled-name='PyImport_ExecCodeModule' filepath='Python/import.c' line='666' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyImport_ExecCodeModule'> - <parameter type-id='type-id-3' name='name' filepath='Python/import.c' line='666' column='1'/> - <parameter type-id='type-id-14' name='co' filepath='Python/import.c' line='666' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyImport_AddModule' mangled-name='PyImport_AddModule' filepath='Python/import.c' line='617' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyImport_AddModule'> - <parameter type-id='type-id-3' name='str' filepath='Objects/bytesobject.c' line='147' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyImport_AddModuleObject' mangled-name='PyImport_AddModuleObject' filepath='Python/import.c' line='599' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyImport_AddModuleObject'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2791' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyImport_FixupBuiltin' mangled-name='_PyImport_FixupBuiltin' filepath='Python/import.c' line='477' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyImport_FixupBuiltin'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2359' column='1'/> - <parameter type-id='type-id-3' name='key' filepath='Objects/abstract.c' line='2359' column='1'/> - <parameter type-id='type-id-14' name='value' filepath='Objects/abstract.c' line='2359' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyImport_FixupExtensionObject' mangled-name='_PyImport_FixupExtensionObject' filepath='Python/import.c' line='412' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyImport_FixupExtensionObject'> - <parameter type-id='type-id-14' name='mod' filepath='Python/import.c' line='412' column='1'/> - <parameter type-id='type-id-14' name='name' filepath='Python/import.c' line='412' column='1'/> - <parameter type-id='type-id-14' name='filename' filepath='Python/import.c' line='413' column='1'/> - <parameter type-id='type-id-14' name='modules' filepath='Python/import.c' line='413' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyImport_GetMagicTag' mangled-name='PyImport_GetMagicTag' filepath='Python/import.c' line='389' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyImport_GetMagicTag'> - <return type-id='type-id-3'/> - </function-decl> - <function-decl name='PyImport_GetMagicNumber' mangled-name='PyImport_GetMagicNumber' filepath='Python/import.c' line='367' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyImport_GetMagicNumber'> - <return type-id='type-id-53'/> - </function-decl> - <function-decl name='_PyImport_SetModuleString' mangled-name='_PyImport_SetModuleString' filepath='Python/import.c' line='304' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyImport_SetModuleString'> - <parameter type-id='type-id-3' name='name' filepath='Python/import.c' line='304' column='1'/> - <parameter type-id='type-id-14' name='m' filepath='Python/import.c' line='304' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyImport_SetModule' mangled-name='_PyImport_SetModule' filepath='Python/import.c' line='296' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyImport_SetModule'> - <parameter type-id='type-id-14' name='od' filepath='Objects/odictobject.c' line='1624' column='1'/> - <parameter type-id='type-id-14' name='key' filepath='Objects/odictobject.c' line='1624' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyImport_GetModuleId' mangled-name='_PyImport_GetModuleId' filepath='Python/import.c' line='286' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyImport_GetModuleId'> - <parameter type-id='type-id-499' name='nameid' filepath='Python/import.c' line='286' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyImport_IsInitialized' mangled-name='_PyImport_IsInitialized' filepath='Python/import.c' line='278' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyImport_IsInitialized'> - <parameter type-id='type-id-11' name='interp' filepath='Python/import.c' line='278' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyImport_GetModuleDict' mangled-name='PyImport_GetModuleDict' filepath='Python/import.c' line='264' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyImport_GetModuleDict'> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyImport_ReleaseLock' mangled-name='_PyImport_ReleaseLock' filepath='Python/import.c' line='138' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyImport_ReleaseLock'> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyImport_AcquireLock' mangled-name='_PyImport_AcquireLock' filepath='Python/import.c' line='111' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyImport_AcquireLock'> - <return type-id='type-id-70'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Python/initconfig.c' comp-dir-path='/src' language='LANG_C99'> - <var-decl name='Py_UTF8Mode' type-id='type-id-8' mangled-name='Py_UTF8Mode' visibility='default' filepath='./Include/fileobject.h' line='29' column='1' elf-symbol-id='Py_UTF8Mode'/> - <var-decl name='Py_DebugFlag' type-id='type-id-8' mangled-name='Py_DebugFlag' visibility='default' filepath='./Include/cpython/pydebug.h' line='8' column='1' elf-symbol-id='Py_DebugFlag'/> - <var-decl name='Py_VerboseFlag' type-id='type-id-8' mangled-name='Py_VerboseFlag' visibility='default' filepath='./Include/cpython/pydebug.h' line='9' column='1' elf-symbol-id='Py_VerboseFlag'/> - <var-decl name='Py_QuietFlag' type-id='type-id-8' mangled-name='Py_QuietFlag' visibility='default' filepath='./Include/cpython/pydebug.h' line='10' column='1' elf-symbol-id='Py_QuietFlag'/> - <var-decl name='Py_InteractiveFlag' type-id='type-id-8' mangled-name='Py_InteractiveFlag' visibility='default' filepath='./Include/cpython/pydebug.h' line='11' column='1' elf-symbol-id='Py_InteractiveFlag'/> - <var-decl name='Py_InspectFlag' type-id='type-id-8' mangled-name='Py_InspectFlag' visibility='default' filepath='./Include/cpython/pydebug.h' line='12' column='1' elf-symbol-id='Py_InspectFlag'/> - <var-decl name='Py_OptimizeFlag' type-id='type-id-8' mangled-name='Py_OptimizeFlag' visibility='default' filepath='./Include/cpython/pydebug.h' line='13' column='1' elf-symbol-id='Py_OptimizeFlag'/> - <var-decl name='Py_NoSiteFlag' type-id='type-id-8' mangled-name='Py_NoSiteFlag' visibility='default' filepath='./Include/cpython/pydebug.h' line='14' column='1' elf-symbol-id='Py_NoSiteFlag'/> - <var-decl name='Py_BytesWarningFlag' type-id='type-id-8' mangled-name='Py_BytesWarningFlag' visibility='default' filepath='./Include/cpython/pydebug.h' line='15' column='1' elf-symbol-id='Py_BytesWarningFlag'/> - <var-decl name='Py_FrozenFlag' type-id='type-id-8' mangled-name='Py_FrozenFlag' visibility='default' filepath='./Include/cpython/pydebug.h' line='16' column='1' elf-symbol-id='Py_FrozenFlag'/> - <var-decl name='Py_IgnoreEnvironmentFlag' type-id='type-id-8' mangled-name='Py_IgnoreEnvironmentFlag' visibility='default' filepath='./Include/cpython/pydebug.h' line='17' column='1' elf-symbol-id='Py_IgnoreEnvironmentFlag'/> - <var-decl name='Py_DontWriteBytecodeFlag' type-id='type-id-8' mangled-name='Py_DontWriteBytecodeFlag' visibility='default' filepath='./Include/cpython/pydebug.h' line='18' column='1' elf-symbol-id='Py_DontWriteBytecodeFlag'/> - <var-decl name='Py_NoUserSiteDirectory' type-id='type-id-8' mangled-name='Py_NoUserSiteDirectory' visibility='default' filepath='./Include/cpython/pydebug.h' line='19' column='1' elf-symbol-id='Py_NoUserSiteDirectory'/> - <var-decl name='Py_UnbufferedStdioFlag' type-id='type-id-8' mangled-name='Py_UnbufferedStdioFlag' visibility='default' filepath='./Include/cpython/pydebug.h' line='20' column='1' elf-symbol-id='Py_UnbufferedStdioFlag'/> - <var-decl name='Py_HashRandomizationFlag' type-id='type-id-8' mangled-name='Py_HashRandomizationFlag' visibility='default' filepath='./Include/cpython/pydebug.h' line='21' column='1' elf-symbol-id='Py_HashRandomizationFlag'/> - <var-decl name='Py_IsolatedFlag' type-id='type-id-8' mangled-name='Py_IsolatedFlag' visibility='default' filepath='./Include/cpython/pydebug.h' line='22' column='1' elf-symbol-id='Py_IsolatedFlag'/> - <function-decl name='_Py_GetConfigsAsDict' mangled-name='_Py_GetConfigsAsDict' filepath='Python/initconfig.c' line='2967' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_GetConfigsAsDict'> - <return type-id='type-id-14'/> - </function-decl> - <class-decl name='__anonymous_struct__' size-in-bits='256' is-struct='yes' is-anonymous='yes' naming-typedef-id='type-id-806' visibility='default' filepath='./Include/cpython/initconfig.h' line='10' column='1' id='type-id-807'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='_type' type-id='type-id-808' visibility='default' filepath='./Include/cpython/initconfig.h' line='15' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='func' type-id='type-id-3' visibility='default' filepath='./Include/cpython/initconfig.h' line='16' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='err_msg' type-id='type-id-3' visibility='default' filepath='./Include/cpython/initconfig.h' line='17' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='exitcode' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='18' column='1'/> - </data-member> - </class-decl> - <enum-decl name='__anonymous_enum__' is-anonymous='yes' filepath='./Include/cpython/initconfig.h' line='11' column='1' id='type-id-808'> - <underlying-type type-id='type-id-126'/> - <enumerator name='_PyStatus_TYPE_OK' value='0'/> - <enumerator name='_PyStatus_TYPE_ERROR' value='1'/> - <enumerator name='_PyStatus_TYPE_EXIT' value='2'/> - </enum-decl> - <typedef-decl name='PyStatus' type-id='type-id-807' filepath='./Include/cpython/initconfig.h' line='19' column='1' id='type-id-806'/> - <pointer-type-def type-id='type-id-34' size-in-bits='64' id='type-id-809'/> - <function-decl name='PyConfig_Read' mangled-name='PyConfig_Read' filepath='Python/initconfig.c' line='2960' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyConfig_Read'> - <parameter type-id='type-id-809' name='config' filepath='Python/initconfig.c' line='2960' column='1'/> - <return type-id='type-id-806'/> - </function-decl> - <pointer-type-def type-id='type-id-372' size-in-bits='64' id='type-id-810'/> - <function-decl name='PyConfig_SetWideStringList' mangled-name='PyConfig_SetWideStringList' filepath='Python/initconfig.c' line='2876' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyConfig_SetWideStringList'> - <parameter type-id='type-id-809' name='config' filepath='Python/initconfig.c' line='2876' column='1'/> - <parameter type-id='type-id-810' name='list' filepath='Python/initconfig.c' line='2876' column='1'/> - <parameter type-id='type-id-36' name='length' filepath='Python/initconfig.c' line='2877' column='1'/> - <parameter type-id='type-id-374' name='items' filepath='Python/initconfig.c' line='2877' column='1'/> - <return type-id='type-id-806'/> - </function-decl> - <qualified-type-def type-id='type-id-281' const='yes' id='type-id-811'/> - <pointer-type-def type-id='type-id-811' size-in-bits='64' id='type-id-812'/> - <function-decl name='PyConfig_SetArgv' mangled-name='PyConfig_SetArgv' filepath='Python/initconfig.c' line='2864' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyConfig_SetArgv'> - <parameter type-id='type-id-809' name='config' filepath='Python/initconfig.c' line='2864' column='1'/> - <parameter type-id='type-id-36' name='argc' filepath='Python/initconfig.c' line='2864' column='1'/> - <parameter type-id='type-id-812' name='argv' filepath='Python/initconfig.c' line='2864' column='1'/> - <return type-id='type-id-806'/> - </function-decl> - <function-decl name='PyConfig_SetBytesArgv' mangled-name='PyConfig_SetBytesArgv' filepath='Python/initconfig.c' line='2852' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyConfig_SetBytesArgv'> - <parameter type-id='type-id-809' name='config' filepath='Python/initconfig.c' line='2852' column='1'/> - <parameter type-id='type-id-36' name='argc' filepath='Python/initconfig.c' line='2852' column='1'/> - <parameter type-id='type-id-477' name='argv' filepath='Python/initconfig.c' line='2852' column='1'/> - <return type-id='type-id-806'/> - </function-decl> - <function-decl name='_PyConfig_FromDict' mangled-name='_PyConfig_FromDict' filepath='Python/initconfig.c' line='1270' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyConfig_FromDict'> - <parameter type-id='type-id-809' name='config' filepath='Python/initconfig.c' line='1270' column='1'/> - <parameter type-id='type-id-14' name='dict' filepath='Python/initconfig.c' line='1270' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <qualified-type-def type-id='type-id-34' const='yes' id='type-id-813'/> - <pointer-type-def type-id='type-id-813' size-in-bits='64' id='type-id-814'/> - <function-decl name='_PyConfig_AsDict' mangled-name='_PyConfig_AsDict' filepath='Python/initconfig.c' line='1003' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyConfig_AsDict'> - <parameter type-id='type-id-814' name='config' filepath='Python/initconfig.c' line='1003' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyConfig_SetBytesString' mangled-name='PyConfig_SetBytesString' filepath='Python/initconfig.c' line='895' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyConfig_SetBytesString'> - <parameter type-id='type-id-809' name='config' filepath='Python/initconfig.c' line='895' column='1'/> - <parameter type-id='type-id-374' name='config_str' filepath='Python/initconfig.c' line='895' column='1'/> - <parameter type-id='type-id-3' name='str' filepath='Python/initconfig.c' line='896' column='1'/> - <return type-id='type-id-806'/> - </function-decl> - <function-decl name='PyConfig_SetString' mangled-name='PyConfig_SetString' filepath='Python/initconfig.c' line='833' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyConfig_SetString'> - <parameter type-id='type-id-809' name='config' filepath='Python/initconfig.c' line='833' column='1'/> - <parameter type-id='type-id-374' name='config_str' filepath='Python/initconfig.c' line='833' column='1'/> - <parameter type-id='type-id-545' name='str' filepath='Python/initconfig.c' line='833' column='1'/> - <return type-id='type-id-806'/> - </function-decl> - <function-decl name='PyConfig_InitIsolatedConfig' mangled-name='PyConfig_InitIsolatedConfig' filepath='Python/initconfig.c' line='810' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyConfig_InitIsolatedConfig'> - <parameter type-id='type-id-809' name='config' filepath='Python/initconfig.c' line='810' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyConfig_InitPythonConfig' mangled-name='PyConfig_InitPythonConfig' filepath='Python/initconfig.c' line='799' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyConfig_InitPythonConfig'> - <parameter type-id='type-id-809' name='config' filepath='Python/initconfig.c' line='810' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_PyConfig_InitCompatConfig' mangled-name='_PyConfig_InitCompatConfig' filepath='Python/initconfig.c' line='727' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyConfig_InitCompatConfig'> - <parameter type-id='type-id-809' name='config' filepath='Python/initconfig.c' line='810' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyConfig_Clear' mangled-name='PyConfig_Clear' filepath='Python/initconfig.c' line='684' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyConfig_Clear'> - <parameter type-id='type-id-809' name='config' filepath='Python/initconfig.c' line='810' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <pointer-type-def type-id='type-id-374' size-in-bits='64' id='type-id-815'/> - <function-decl name='Py_GetArgcArgv' mangled-name='Py_GetArgcArgv' filepath='Python/initconfig.c' line='609' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_GetArgcArgv'> - <parameter type-id='type-id-501' name='argc' filepath='Python/initconfig.c' line='609' column='1'/> - <parameter type-id='type-id-815' name='argv' filepath='Python/initconfig.c' line='609' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_Py_ClearArgcArgv' mangled-name='_Py_ClearArgcArgv' filepath='Python/initconfig.c' line='580' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_ClearArgcArgv'> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_Py_ClearStandardStreamEncoding' mangled-name='_Py_ClearStandardStreamEncoding' filepath='Python/initconfig.c' line='553' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_ClearStandardStreamEncoding'> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='Py_SetStandardStreamEncoding' mangled-name='Py_SetStandardStreamEncoding' filepath='Python/initconfig.c' line='498' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_SetStandardStreamEncoding'> - <parameter type-id='type-id-3' name='encoding' filepath='Python/initconfig.c' line='498' column='1'/> - <parameter type-id='type-id-3' name='errors' filepath='Python/initconfig.c' line='498' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <qualified-type-def type-id='type-id-372' const='yes' id='type-id-816'/> - <pointer-type-def type-id='type-id-816' size-in-bits='64' id='type-id-817'/> - <function-decl name='_PyWideStringList_AsList' mangled-name='_PyWideStringList_AsList' filepath='Python/initconfig.c' line='467' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyWideStringList_AsList'> - <parameter type-id='type-id-817' name='list' filepath='Python/initconfig.c' line='467' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyWideStringList_Extend' mangled-name='_PyWideStringList_Extend' filepath='Python/initconfig.c' line='442' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyWideStringList_Extend'> - <parameter type-id='type-id-810' name='list' filepath='Python/initconfig.c' line='442' column='1'/> - <parameter type-id='type-id-817' name='list2' filepath='Python/initconfig.c' line='442' column='1'/> - <return type-id='type-id-806'/> - </function-decl> - <function-decl name='PyWideStringList_Append' mangled-name='PyWideStringList_Append' filepath='Python/initconfig.c' line='435' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyWideStringList_Append'> - <parameter type-id='type-id-810' name='list' filepath='Python/initconfig.c' line='435' column='1'/> - <parameter type-id='type-id-545' name='item' filepath='Python/initconfig.c' line='435' column='1'/> - <return type-id='type-id-806'/> - </function-decl> - <function-decl name='PyWideStringList_Insert' mangled-name='PyWideStringList_Insert' filepath='Python/initconfig.c' line='394' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyWideStringList_Insert'> - <parameter type-id='type-id-810' name='list' filepath='Python/initconfig.c' line='394' column='1'/> - <parameter type-id='type-id-36' name='index' filepath='Python/initconfig.c' line='395' column='1'/> - <parameter type-id='type-id-545' name='item' filepath='Python/initconfig.c' line='395' column='1'/> - <return type-id='type-id-806'/> - </function-decl> - <function-decl name='_PyWideStringList_Copy' mangled-name='_PyWideStringList_Copy' filepath='Python/initconfig.c' line='359' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyWideStringList_Copy'> - <parameter type-id='type-id-810' name='list' filepath='Python/initconfig.c' line='359' column='1'/> - <parameter type-id='type-id-817' name='list2' filepath='Python/initconfig.c' line='359' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyWideStringList_Clear' mangled-name='_PyWideStringList_Clear' filepath='Python/initconfig.c' line='346' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyWideStringList_Clear'> - <parameter type-id='type-id-810' name='list' filepath='Python/initconfig.c' line='346' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyStatus_Exception' mangled-name='PyStatus_Exception' filepath='Python/initconfig.c' line='306' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyStatus_Exception'> - <parameter type-id='type-id-806' name='status' filepath='Python/initconfig.c' line='306' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyStatus_IsExit' mangled-name='PyStatus_IsExit' filepath='Python/initconfig.c' line='303' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyStatus_IsExit'> - <parameter type-id='type-id-806' name='status' filepath='Python/initconfig.c' line='306' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyStatus_IsError' mangled-name='PyStatus_IsError' filepath='Python/initconfig.c' line='300' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyStatus_IsError'> - <parameter type-id='type-id-806' name='status' filepath='Python/initconfig.c' line='306' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyStatus_Exit' mangled-name='PyStatus_Exit' filepath='Python/initconfig.c' line='296' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyStatus_Exit'> - <parameter type-id='type-id-8' name='exitcode' filepath='Python/initconfig.c' line='296' column='1'/> - <return type-id='type-id-806'/> - </function-decl> - <function-decl name='PyStatus_NoMemory' mangled-name='PyStatus_NoMemory' filepath='Python/initconfig.c' line='293' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyStatus_NoMemory'> - <return type-id='type-id-806'/> - </function-decl> - <function-decl name='PyStatus_Error' mangled-name='PyStatus_Error' filepath='Python/initconfig.c' line='286' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyStatus_Error'> - <parameter type-id='type-id-3' name='err_msg' filepath='Python/initconfig.c' line='286' column='1'/> - <return type-id='type-id-806'/> - </function-decl> - <function-decl name='PyStatus_Ok' mangled-name='PyStatus_Ok' filepath='Python/initconfig.c' line='283' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyStatus_Ok'> - <return type-id='type-id-806'/> - </function-decl> - <function-decl name='Py_GETENV' mangled-name='Py_GETENV' filepath='Python/initconfig.c' line='273' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_GETENV'> - <parameter type-id='type-id-3' name='name' filepath='Python/initconfig.c' line='273' column='1'/> - <return type-id='type-id-115'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Python/marshal.c' comp-dir-path='/src' language='LANG_C99'> - <function-decl name='PyMarshal_Init' mangled-name='PyMarshal_Init' filepath='Python/marshal.c' line='1893' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMarshal_Init'> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyMarshal_WriteObjectToString' mangled-name='PyMarshal_WriteObjectToString' filepath='Python/marshal.c' line='1644' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMarshal_WriteObjectToString'> - <parameter type-id='type-id-14' name='x' filepath='Python/marshal.c' line='1644' column='1'/> - <parameter type-id='type-id-8' name='version' filepath='Python/marshal.c' line='1644' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyMarshal_ReadObjectFromString' mangled-name='PyMarshal_ReadObjectFromString' filepath='Python/marshal.c' line='1623' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMarshal_ReadObjectFromString'> - <parameter type-id='type-id-3' name='bytes' filepath='Objects/bytearrayobject.c' line='108' column='1'/> - <parameter type-id='type-id-36' name='size' filepath='Objects/bytearrayobject.c' line='108' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyMarshal_ReadObjectFromFile' mangled-name='PyMarshal_ReadObjectFromFile' filepath='Python/marshal.c' line='1603' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMarshal_ReadObjectFromFile'> - <parameter type-id='type-id-473' name='fp' filepath='Python/marshal.c' line='1603' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyMarshal_ReadLastObjectFromFile' mangled-name='PyMarshal_ReadLastObjectFromFile' filepath='Python/marshal.c' line='1578' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMarshal_ReadLastObjectFromFile'> - <parameter type-id='type-id-473' name='fp' filepath='Python/marshal.c' line='1578' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyMarshal_ReadLongFromFile' mangled-name='PyMarshal_ReadLongFromFile' filepath='Python/marshal.c' line='1542' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMarshal_ReadLongFromFile'> - <parameter type-id='type-id-473' name='fp' filepath='Python/marshal.c' line='1542' column='1'/> - <return type-id='type-id-53'/> - </function-decl> - <function-decl name='PyMarshal_ReadShortFromFile' mangled-name='PyMarshal_ReadShortFromFile' filepath='Python/marshal.c' line='1526' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMarshal_ReadShortFromFile'> - <parameter type-id='type-id-473' name='fp' filepath='Python/marshal.c' line='1526' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyMarshal_WriteObjectToFile' mangled-name='PyMarshal_WriteObjectToFile' filepath='Python/marshal.c' line='641' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMarshal_WriteObjectToFile'> - <parameter type-id='type-id-14' name='x' filepath='Python/marshal.c' line='641' column='1'/> - <parameter type-id='type-id-473' name='fp' filepath='Python/marshal.c' line='641' column='1'/> - <parameter type-id='type-id-8' name='version' filepath='Python/marshal.c' line='641' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyMarshal_WriteLongToFile' mangled-name='PyMarshal_WriteLongToFile' filepath='Python/marshal.c' line='626' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMarshal_WriteLongToFile'> - <parameter type-id='type-id-53' name='x' filepath='Python/marshal.c' line='626' column='1'/> - <parameter type-id='type-id-473' name='fp' filepath='Python/marshal.c' line='626' column='1'/> - <parameter type-id='type-id-8' name='version' filepath='Python/marshal.c' line='626' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Python/modsupport.c' comp-dir-path='/src' language='LANG_C99'> - <var-decl name='_Py_PackageContext' type-id='type-id-3' mangled-name='_Py_PackageContext' visibility='default' filepath='./Include/cpython/modsupport.h' line='107' column='1' elf-symbol-id='_Py_PackageContext'/> - <function-decl name='PyModule_AddType' mangled-name='PyModule_AddType' filepath='Python/modsupport.c' line='704' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyModule_AddType'> - <parameter type-id='type-id-14' name='module' filepath='Python/modsupport.c' line='704' column='1'/> - <parameter type-id='type-id-74' name='type' filepath='Python/modsupport.c' line='704' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyModule_AddStringConstant' mangled-name='PyModule_AddStringConstant' filepath='Python/modsupport.c' line='692' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyModule_AddStringConstant'> - <parameter type-id='type-id-14' name='m' filepath='Python/modsupport.c' line='692' column='1'/> - <parameter type-id='type-id-3' name='name' filepath='Python/modsupport.c' line='692' column='1'/> - <parameter type-id='type-id-3' name='value' filepath='Python/modsupport.c' line='692' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyModule_AddIntConstant' mangled-name='PyModule_AddIntConstant' filepath='Python/modsupport.c' line='680' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyModule_AddIntConstant'> - <parameter type-id='type-id-14' name='m' filepath='Python/modsupport.c' line='680' column='1'/> - <parameter type-id='type-id-3' name='name' filepath='Python/modsupport.c' line='680' column='1'/> - <parameter type-id='type-id-53' name='value' filepath='Python/modsupport.c' line='680' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyModule_AddObject' mangled-name='PyModule_AddObject' filepath='Python/modsupport.c' line='670' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyModule_AddObject'> - <parameter type-id='type-id-14' name='mod' filepath='Python/modsupport.c' line='670' column='1'/> - <parameter type-id='type-id-3' name='name' filepath='Python/modsupport.c' line='670' column='1'/> - <parameter type-id='type-id-14' name='value' filepath='Python/modsupport.c' line='670' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyModule_AddObjectRef' mangled-name='PyModule_AddObjectRef' filepath='Python/modsupport.c' line='637' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyModule_AddObjectRef'> - <parameter type-id='type-id-14' name='mod' filepath='Python/modsupport.c' line='670' column='1'/> - <parameter type-id='type-id-3' name='name' filepath='Python/modsupport.c' line='670' column='1'/> - <parameter type-id='type-id-14' name='value' filepath='Python/modsupport.c' line='670' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_Py_VaBuildStack_SizeT' mangled-name='_Py_VaBuildStack_SizeT' filepath='Python/modsupport.c' line='581' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_VaBuildStack_SizeT'> - <parameter type-id='type-id-22' name='small_stack' filepath='Python/modsupport.c' line='581' column='1'/> - <parameter type-id='type-id-36' name='small_stack_len' filepath='Python/modsupport.c' line='581' column='1'/> - <parameter type-id='type-id-3' name='format' filepath='Python/modsupport.c' line='582' column='1'/> - <parameter type-id='type-id-496' name='va' filepath='Python/modsupport.c' line='582' column='1'/> - <parameter type-id='type-id-168' name='p_nargs' filepath='Python/modsupport.c' line='582' column='1'/> - <return type-id='type-id-22'/> - </function-decl> - <function-decl name='_Py_VaBuildStack' mangled-name='_Py_VaBuildStack' filepath='Python/modsupport.c' line='574' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_VaBuildStack'> - <parameter type-id='type-id-22' name='small_stack' filepath='Python/modsupport.c' line='581' column='1'/> - <parameter type-id='type-id-36' name='small_stack_len' filepath='Python/modsupport.c' line='581' column='1'/> - <parameter type-id='type-id-3' name='format' filepath='Python/modsupport.c' line='582' column='1'/> - <parameter type-id='type-id-496' name='va' filepath='Python/modsupport.c' line='582' column='1'/> - <parameter type-id='type-id-168' name='p_nargs' filepath='Python/modsupport.c' line='582' column='1'/> - <return type-id='type-id-22'/> - </function-decl> - <function-decl name='_Py_VaBuildValue_SizeT' mangled-name='_Py_VaBuildValue_SizeT' filepath='Python/modsupport.c' line='545' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_VaBuildValue_SizeT'> - <parameter type-id='type-id-3' name='format' filepath='Python/modsupport.c' line='545' column='1'/> - <parameter type-id='type-id-496' name='va' filepath='Python/modsupport.c' line='545' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='Py_VaBuildValue' mangled-name='Py_VaBuildValue' filepath='Python/modsupport.c' line='539' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_VaBuildValue'> - <parameter type-id='type-id-3' name='format' filepath='Python/modsupport.c' line='545' column='1'/> - <parameter type-id='type-id-496' name='va' filepath='Python/modsupport.c' line='545' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_Py_BuildValue_SizeT' mangled-name='_Py_BuildValue_SizeT' filepath='Python/modsupport.c' line='528' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_BuildValue_SizeT'> - <parameter type-id='type-id-3' name='format' filepath='Objects/bytesobject.c' line='375' column='1'/> - <parameter is-variadic='yes'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='Py_BuildValue' mangled-name='Py_BuildValue' filepath='Python/modsupport.c' line='517' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_BuildValue'> - <parameter type-id='type-id-3' name='format' filepath='Objects/bytesobject.c' line='375' column='1'/> - <parameter is-variadic='yes'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_Py_convert_optional_to_ssize_t' mangled-name='_Py_convert_optional_to_ssize_t' filepath='Python/modsupport.c' line='18' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_convert_optional_to_ssize_t'> - <parameter type-id='type-id-14' name='o' filepath='Objects/capsule.c' line='181' column='1'/> - <parameter type-id='type-id-18' name='context' filepath='Objects/capsule.c' line='181' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Python/mysnprintf.c' comp-dir-path='/src' language='LANG_C99'> - <function-decl name='PyOS_vsnprintf' mangled-name='PyOS_vsnprintf' filepath='Python/mysnprintf.c' line='52' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyOS_vsnprintf'> - <parameter type-id='type-id-115' name='str' filepath='Python/mysnprintf.c' line='52' column='1'/> - <parameter type-id='type-id-54' name='size' filepath='Python/mysnprintf.c' line='52' column='1'/> - <parameter type-id='type-id-3' name='format' filepath='Python/mysnprintf.c' line='52' column='1'/> - <parameter type-id='type-id-496' name='va' filepath='Python/mysnprintf.c' line='52' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyOS_snprintf' mangled-name='PyOS_snprintf' filepath='Python/mysnprintf.c' line='40' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyOS_snprintf'> - <parameter type-id='type-id-115' name='str' filepath='Python/mysnprintf.c' line='40' column='1'/> - <parameter type-id='type-id-54' name='size' filepath='Python/mysnprintf.c' line='40' column='1'/> - <parameter type-id='type-id-3' name='format' filepath='Python/mysnprintf.c' line='40' column='1'/> - <parameter is-variadic='yes'/> - <return type-id='type-id-8'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Python/mystrtoul.c' comp-dir-path='/src' language='LANG_C99'> - <function-decl name='PyOS_strtol' mangled-name='PyOS_strtol' filepath='Python/mystrtoul.c' line='263' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyOS_strtol'> - <parameter type-id='type-id-3' name='str' filepath='Python/mystrtoul.c' line='263' column='1'/> - <parameter type-id='type-id-494' name='ptr' filepath='Python/mystrtoul.c' line='263' column='1'/> - <parameter type-id='type-id-8' name='base' filepath='Python/mystrtoul.c' line='263' column='1'/> - <return type-id='type-id-53'/> - </function-decl> - <function-decl name='PyOS_strtoul' mangled-name='PyOS_strtoul' filepath='Python/mystrtoul.c' line='95' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyOS_strtoul'> - <parameter type-id='type-id-3' name='str' filepath='Python/mystrtoul.c' line='95' column='1'/> - <parameter type-id='type-id-494' name='ptr' filepath='Python/mystrtoul.c' line='95' column='1'/> - <parameter type-id='type-id-8' name='base' filepath='Python/mystrtoul.c' line='95' column='1'/> - <return type-id='type-id-16'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Python/pathconfig.c' comp-dir-path='/src' language='LANG_C99'> - <function-decl name='Py_GetProgramName' mangled-name='Py_GetProgramName' filepath='Python/pathconfig.c' line='369' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_GetProgramName'> - <return type-id='type-id-281'/> - </function-decl> - <function-decl name='Py_GetPythonHome' mangled-name='Py_GetPythonHome' filepath='Python/pathconfig.c' line='362' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_GetPythonHome'> - <return type-id='type-id-281'/> - </function-decl> - <function-decl name='Py_GetProgramFullPath' mangled-name='Py_GetProgramFullPath' filepath='Python/pathconfig.c' line='355' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_GetProgramFullPath'> - <return type-id='type-id-281'/> - </function-decl> - <function-decl name='Py_GetExecPrefix' mangled-name='Py_GetExecPrefix' filepath='Python/pathconfig.c' line='348' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_GetExecPrefix'> - <return type-id='type-id-281'/> - </function-decl> - <function-decl name='Py_GetPrefix' mangled-name='Py_GetPrefix' filepath='Python/pathconfig.c' line='341' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_GetPrefix'> - <return type-id='type-id-281'/> - </function-decl> - <function-decl name='Py_GetPath' mangled-name='Py_GetPath' filepath='Python/pathconfig.c' line='318' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_GetPath'> - <return type-id='type-id-281'/> - </function-decl> - <function-decl name='_Py_SetProgramFullPath' mangled-name='_Py_SetProgramFullPath' filepath='Python/pathconfig.c' line='297' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_SetProgramFullPath'> - <parameter type-id='type-id-545' name='program_full_path' filepath='Python/pathconfig.c' line='297' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='Py_SetProgramName' mangled-name='Py_SetProgramName' filepath='Python/pathconfig.c' line='277' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_SetProgramName'> - <parameter type-id='type-id-545' name='program_full_path' filepath='Python/pathconfig.c' line='297' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='Py_SetPythonHome' mangled-name='Py_SetPythonHome' filepath='Python/pathconfig.c' line='256' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_SetPythonHome'> - <parameter type-id='type-id-545' name='program_full_path' filepath='Python/pathconfig.c' line='297' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='Py_SetPath' mangled-name='Py_SetPath' filepath='Python/pathconfig.c' line='215' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_SetPath'> - <parameter type-id='type-id-545' name='path' filepath='Python/pathconfig.c' line='215' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_PyPathConfig_ClearGlobal' mangled-name='_PyPathConfig_ClearGlobal' filepath='Python/pathconfig.c' line='57' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyPathConfig_ClearGlobal'> - <return type-id='type-id-70'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Python/preconfig.c' comp-dir-path='/src' language='LANG_C99'> - <var-decl name='Py_FileSystemDefaultEncoding' type-id='type-id-3' mangled-name='Py_FileSystemDefaultEncoding' visibility='default' filepath='./Include/fileobject.h' line='22' column='1' elf-symbol-id='Py_FileSystemDefaultEncoding'/> - <var-decl name='Py_HasFileSystemDefaultEncoding' type-id='type-id-8' mangled-name='Py_HasFileSystemDefaultEncoding' visibility='default' filepath='./Include/fileobject.h' line='26' column='1' elf-symbol-id='Py_HasFileSystemDefaultEncoding'/> - <var-decl name='Py_FileSystemDefaultEncodeErrors' type-id='type-id-3' mangled-name='Py_FileSystemDefaultEncodeErrors' visibility='default' filepath='./Include/fileobject.h' line='24' column='1' elf-symbol-id='Py_FileSystemDefaultEncodeErrors'/> - <var-decl name='_Py_HasFileSystemDefaultEncodeErrors' type-id='type-id-8' mangled-name='_Py_HasFileSystemDefaultEncodeErrors' visibility='default' filepath='./Include/internal/pycore_fileutils.h' line='178' column='1' elf-symbol-id='_Py_HasFileSystemDefaultEncodeErrors'/> - <function-decl name='_Py_get_xoption' mangled-name='_Py_get_xoption' filepath='Python/preconfig.c' line='569' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_get_xoption'> - <parameter type-id='type-id-817' name='xoptions' filepath='Python/preconfig.c' line='569' column='1'/> - <parameter type-id='type-id-545' name='name' filepath='Python/preconfig.c' line='569' column='1'/> - <return type-id='type-id-545'/> - </function-decl> - <function-decl name='_Py_get_env_flag' mangled-name='_Py_get_env_flag' filepath='Python/preconfig.c' line='551' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_get_env_flag'> - <parameter type-id='type-id-8' name='use_environment' filepath='Python/preconfig.c' line='551' column='1'/> - <parameter type-id='type-id-501' name='flag' filepath='Python/preconfig.c' line='551' column='1'/> - <parameter type-id='type-id-3' name='name' filepath='Python/preconfig.c' line='551' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_Py_str_to_int' mangled-name='_Py_str_to_int' filepath='Python/preconfig.c' line='533' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_str_to_int'> - <parameter type-id='type-id-3' name='str' filepath='Python/preconfig.c' line='533' column='1'/> - <parameter type-id='type-id-501' name='result' filepath='Python/preconfig.c' line='533' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_Py_GetEnv' mangled-name='_Py_GetEnv' filepath='Python/preconfig.c' line='514' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_GetEnv'> - <parameter type-id='type-id-8' name='use_environment' filepath='Python/preconfig.c' line='514' column='1'/> - <parameter type-id='type-id-3' name='name' filepath='Python/preconfig.c' line='514' column='1'/> - <return type-id='type-id-3'/> - </function-decl> - <pointer-type-def type-id='type-id-63' size-in-bits='64' id='type-id-818'/> - <function-decl name='PyPreConfig_InitIsolatedConfig' mangled-name='PyPreConfig_InitIsolatedConfig' filepath='Python/preconfig.c' line='326' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyPreConfig_InitIsolatedConfig'> - <parameter type-id='type-id-818' name='config' filepath='Python/preconfig.c' line='326' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyPreConfig_InitPythonConfig' mangled-name='PyPreConfig_InitPythonConfig' filepath='Python/preconfig.c' line='305' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyPreConfig_InitPythonConfig'> - <parameter type-id='type-id-818' name='config' filepath='Python/preconfig.c' line='326' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_PyPreConfig_InitCompatConfig' mangled-name='_PyPreConfig_InitCompatConfig' filepath='Python/preconfig.c' line='277' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyPreConfig_InitCompatConfig'> - <parameter type-id='type-id-818' name='config' filepath='Python/preconfig.c' line='326' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <class-decl name='_PyArgv' size-in-bits='256' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_initconfig.h' line='66' column='1' id='type-id-819'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='argc' type-id='type-id-36' visibility='default' filepath='./Include/internal/pycore_initconfig.h' line='67' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='use_bytes_argv' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_initconfig.h' line='68' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='bytes_argv' type-id='type-id-477' visibility='default' filepath='./Include/internal/pycore_initconfig.h' line='69' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='wchar_argv' type-id='type-id-812' visibility='default' filepath='./Include/internal/pycore_initconfig.h' line='70' column='1'/> - </data-member> - </class-decl> - <typedef-decl name='_PyArgv' type-id='type-id-819' filepath='./Include/internal/pycore_initconfig.h' line='71' column='1' id='type-id-820'/> - <qualified-type-def type-id='type-id-820' const='yes' id='type-id-821'/> - <pointer-type-def type-id='type-id-821' size-in-bits='64' id='type-id-822'/> - <function-decl name='_PyArgv_AsWstrList' mangled-name='_PyArgv_AsWstrList' filepath='Python/preconfig.c' line='72' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyArgv_AsWstrList'> - <parameter type-id='type-id-822' name='args' filepath='Python/preconfig.c' line='72' column='1'/> - <parameter type-id='type-id-810' name='list' filepath='Python/preconfig.c' line='72' column='1'/> - <return type-id='type-id-806'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Python/pyarena.c' comp-dir-path='/src' language='LANG_C99'> - <class-decl name='_arena' size-in-bits='192' is-struct='yes' visibility='default' filepath='Python/pyarena.c' line='46' column='1' id='type-id-763'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='a_head' type-id='type-id-823' visibility='default' filepath='Python/pyarena.c' line='51' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='a_cur' type-id='type-id-823' visibility='default' filepath='Python/pyarena.c' line='58' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='a_objects' type-id='type-id-14' visibility='default' filepath='Python/pyarena.c' line='64' column='1'/> - </data-member> - </class-decl> - <class-decl name='_block' size-in-bits='256' is-struct='yes' visibility='default' filepath='Python/pyarena.c' line='17' column='1' id='type-id-824'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='ab_size' type-id='type-id-54' visibility='default' filepath='Python/pyarena.c' line='22' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='ab_offset' type-id='type-id-54' visibility='default' filepath='Python/pyarena.c' line='27' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='ab_next' type-id='type-id-825' visibility='default' filepath='Python/pyarena.c' line='33' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='ab_mem' type-id='type-id-18' visibility='default' filepath='Python/pyarena.c' line='38' column='1'/> - </data-member> - </class-decl> - <pointer-type-def type-id='type-id-824' size-in-bits='64' id='type-id-825'/> - <typedef-decl name='block' type-id='type-id-824' filepath='Python/pyarena.c' line='39' column='1' id='type-id-826'/> - <pointer-type-def type-id='type-id-826' size-in-bits='64' id='type-id-823'/> - <function-decl name='_PyArena_AddPyObject' mangled-name='_PyArena_AddPyObject' filepath='Python/pyarena.c' line='204' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyArena_AddPyObject'> - <parameter type-id='type-id-765' name='arena' filepath='Python/pyarena.c' line='204' column='1'/> - <parameter type-id='type-id-14' name='obj' filepath='Python/pyarena.c' line='204' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyArena_Malloc' mangled-name='_PyArena_Malloc' filepath='Python/pyarena.c' line='181' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyArena_Malloc'> - <parameter type-id='type-id-765' name='arena' filepath='Python/pyarena.c' line='181' column='1'/> - <parameter type-id='type-id-54' name='size' filepath='Python/pyarena.c' line='181' column='1'/> - <return type-id='type-id-18'/> - </function-decl> - <function-decl name='_PyArena_Free' mangled-name='_PyArena_Free' filepath='Python/pyarena.c' line='158' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyArena_Free'> - <parameter type-id='type-id-765' name='arena' filepath='Python/pyarena.c' line='158' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_PyArena_New' mangled-name='_PyArena_New' filepath='Python/pyarena.c' line='129' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyArena_New'> - <return type-id='type-id-765'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Python/pyctype.c' comp-dir-path='/src' language='LANG_C99'> - <qualified-type-def type-id='type-id-105' const='yes' id='type-id-827'/> - - <array-type-def dimensions='1' type-id='type-id-827' size-in-bits='8192' id='type-id-828'> - <subrange length='256' type-id='type-id-16' id='type-id-264'/> - - </array-type-def> - <qualified-type-def type-id='type-id-828' const='yes' id='type-id-829'/> - <var-decl name='_Py_ctype_table' type-id='type-id-829' mangled-name='_Py_ctype_table' visibility='default' filepath='./Include/cpython/pyctype.h' line='16' column='1' elf-symbol-id='_Py_ctype_table'/> - - <array-type-def dimensions='1' type-id='type-id-527' size-in-bits='2048' id='type-id-830'> - <subrange length='256' type-id='type-id-16' id='type-id-264'/> - - </array-type-def> - <qualified-type-def type-id='type-id-830' const='yes' id='type-id-831'/> - <var-decl name='_Py_ctype_tolower' type-id='type-id-831' mangled-name='_Py_ctype_tolower' visibility='default' filepath='./Include/cpython/pyctype.h' line='29' column='1' elf-symbol-id='_Py_ctype_tolower'/> - <var-decl name='_Py_ctype_toupper' type-id='type-id-831' mangled-name='_Py_ctype_toupper' visibility='default' filepath='./Include/cpython/pyctype.h' line='30' column='1' elf-symbol-id='_Py_ctype_toupper'/> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Python/pyhash.c' comp-dir-path='/src' language='LANG_C99'> - <union-decl name='__anonymous_union__' size-in-bits='192' is-anonymous='yes' visibility='default' filepath='./Include/pyhash.h' line='55' column='1' id='type-id-832'> - <data-member access='private'> - <var-decl name='uc' type-id='type-id-833' visibility='default' filepath='./Include/pyhash.h' line='57' column='1'/> - </data-member> - <data-member access='private'> - <var-decl name='fnv' type-id='type-id-834' visibility='default' filepath='./Include/pyhash.h' line='62' column='1'/> - </data-member> - <data-member access='private'> - <var-decl name='siphash' type-id='type-id-835' visibility='default' filepath='./Include/pyhash.h' line='67' column='1'/> - </data-member> - <data-member access='private'> - <var-decl name='djbx33a' type-id='type-id-836' visibility='default' filepath='./Include/pyhash.h' line='72' column='1'/> - </data-member> - <data-member access='private'> - <var-decl name='expat' type-id='type-id-837' visibility='default' filepath='./Include/pyhash.h' line='76' column='1'/> - </data-member> - </union-decl> - - <array-type-def dimensions='1' type-id='type-id-283' size-in-bits='192' id='type-id-833'> - <subrange length='24' type-id='type-id-16' id='type-id-296'/> - - </array-type-def> - <class-decl name='__anonymous_struct__' size-in-bits='128' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/pyhash.h' line='59' column='1' id='type-id-834'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='prefix' type-id='type-id-159' visibility='default' filepath='./Include/pyhash.h' line='60' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='suffix' type-id='type-id-159' visibility='default' filepath='./Include/pyhash.h' line='61' column='1'/> - </data-member> - </class-decl> - <class-decl name='__anonymous_struct__' size-in-bits='128' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/pyhash.h' line='64' column='1' id='type-id-835'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='k0' type-id='type-id-19' visibility='default' filepath='./Include/pyhash.h' line='65' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='k1' type-id='type-id-19' visibility='default' filepath='./Include/pyhash.h' line='66' column='1'/> - </data-member> - </class-decl> - <class-decl name='__anonymous_struct__' size-in-bits='192' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/pyhash.h' line='69' column='1' id='type-id-836'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='padding' type-id='type-id-838' visibility='default' filepath='./Include/pyhash.h' line='70' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='suffix' type-id='type-id-159' visibility='default' filepath='./Include/pyhash.h' line='71' column='1'/> - </data-member> - </class-decl> - - <array-type-def dimensions='1' type-id='type-id-283' size-in-bits='128' id='type-id-838'> - <subrange length='16' type-id='type-id-16' id='type-id-326'/> - - </array-type-def> - <class-decl name='__anonymous_struct__' size-in-bits='192' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/pyhash.h' line='73' column='1' id='type-id-837'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='padding' type-id='type-id-838' visibility='default' filepath='./Include/pyhash.h' line='74' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='hashsalt' type-id='type-id-159' visibility='default' filepath='./Include/pyhash.h' line='75' column='1'/> - </data-member> - </class-decl> - <typedef-decl name='_Py_HashSecret_t' type-id='type-id-832' filepath='./Include/pyhash.h' line='77' column='1' id='type-id-839'/> - <var-decl name='_Py_HashSecret' type-id='type-id-839' mangled-name='_Py_HashSecret' visibility='default' filepath='./Include/pyhash.h' line='78' column='1' elf-symbol-id='_Py_HashSecret'/> - <class-decl name='__anonymous_struct__' size-in-bits='192' is-struct='yes' is-anonymous='yes' naming-typedef-id='type-id-840' visibility='default' filepath='./Include/pyhash.h' line='86' column='1' id='type-id-841'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='hash' type-id='type-id-842' visibility='default' filepath='./Include/pyhash.h' line='87' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='name' type-id='type-id-3' visibility='default' filepath='./Include/pyhash.h' line='88' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='hash_bits' type-id='type-id-843' visibility='default' filepath='./Include/pyhash.h' line='89' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='160'> - <var-decl name='seed_bits' type-id='type-id-843' visibility='default' filepath='./Include/pyhash.h' line='90' column='1'/> - </data-member> - </class-decl> - <pointer-type-def type-id='type-id-844' size-in-bits='64' id='type-id-845'/> - <qualified-type-def type-id='type-id-845' const='yes' id='type-id-842'/> - <qualified-type-def type-id='type-id-8' const='yes' id='type-id-843'/> - <typedef-decl name='PyHash_FuncDef' type-id='type-id-841' filepath='./Include/pyhash.h' line='91' column='1' id='type-id-840'/> - <pointer-type-def type-id='type-id-840' size-in-bits='64' id='type-id-846'/> - <function-decl name='PyHash_GetFuncDef' mangled-name='PyHash_GetFuncDef' filepath='Python/pyhash.c' line='221' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyHash_GetFuncDef'> - <return type-id='type-id-846'/> - </function-decl> - <function-decl name='_Py_HashBytes' mangled-name='_Py_HashBytes' filepath='Python/pyhash.c' line='158' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_HashBytes'> - <parameter type-id='type-id-18' name='src' filepath='Python/pyhash.c' line='158' column='1'/> - <parameter type-id='type-id-36' name='len' filepath='Python/pyhash.c' line='158' column='1'/> - <return type-id='type-id-159'/> - </function-decl> - <function-decl name='_Py_HashPointer' mangled-name='_Py_HashPointer' filepath='Python/pyhash.c' line='148' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_HashPointer'> - <parameter type-id='type-id-18' name='p' filepath='Python/pyhash.c' line='148' column='1'/> - <return type-id='type-id-159'/> - </function-decl> - <function-decl name='_Py_HashPointerRaw' mangled-name='_Py_HashPointerRaw' filepath='Python/pyhash.c' line='138' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_HashPointerRaw'> - <parameter type-id='type-id-18' name='p' filepath='Python/pyhash.c' line='148' column='1'/> - <return type-id='type-id-159'/> - </function-decl> - <function-decl name='_Py_HashDouble' mangled-name='_Py_HashDouble' filepath='Python/pyhash.c' line='92' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_HashDouble'> - <parameter type-id='type-id-14' name='inst' filepath='Python/pyhash.c' line='92' column='1'/> - <parameter type-id='type-id-391' name='v' filepath='Python/pyhash.c' line='92' column='1'/> - <return type-id='type-id-159'/> - </function-decl> - <function-type size-in-bits='64' id='type-id-844'> - <parameter type-id='type-id-18'/> - <parameter type-id='type-id-36'/> - <return type-id='type-id-159'/> - </function-type> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Python/pylifecycle.c' comp-dir-path='/src' language='LANG_C99'> - <var-decl name='_Py_UnhandledKeyboardInterrupt' type-id='type-id-8' mangled-name='_Py_UnhandledKeyboardInterrupt' visibility='default' filepath='./Include/internal/pycore_pylifecycle.h' line='19' column='1' elf-symbol-id='_Py_UnhandledKeyboardInterrupt'/> - <typedef-decl name='_PyRuntimeState' type-id='type-id-56' filepath='./Include/internal/pycore_runtime.h' line='147' column='1' id='type-id-847'/> - <var-decl name='_PyRuntime' type-id='type-id-847' mangled-name='_PyRuntime' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='152' column='1' elf-symbol-id='_PyRuntime'/> - <pointer-type-def type-id='type-id-848' size-in-bits='64' id='type-id-849'/> - <typedef-decl name='PyOS_sighandler_t' type-id='type-id-849' filepath='./Include/pylifecycle.h' line='61' column='1' id='type-id-850'/> - <function-decl name='PyOS_setsig' mangled-name='PyOS_setsig' filepath='Python/pylifecycle.c' line='3022' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyOS_setsig'> - <parameter type-id='type-id-8' name='sig' filepath='Python/pylifecycle.c' line='3022' column='1'/> - <parameter type-id='type-id-850' name='handler' filepath='Python/pylifecycle.c' line='3022' column='1'/> - <return type-id='type-id-850'/> - </function-decl> - <function-decl name='PyOS_getsig' mangled-name='PyOS_getsig' filepath='Python/pylifecycle.c' line='2983' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyOS_getsig'> - <parameter type-id='type-id-8' name='sig' filepath='Python/pylifecycle.c' line='2983' column='1'/> - <return type-id='type-id-850'/> - </function-decl> - <function-decl name='_Py_FdIsInteractive' mangled-name='_Py_FdIsInteractive' filepath='Python/pylifecycle.c' line='2966' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_FdIsInteractive'> - <parameter type-id='type-id-473' name='fp' filepath='Python/pylifecycle.c' line='2966' column='1'/> - <parameter type-id='type-id-14' name='filename' filepath='Python/pylifecycle.c' line='2966' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='Py_FdIsInteractive' mangled-name='Py_FdIsInteractive' filepath='Python/pylifecycle.c' line='2953' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_FdIsInteractive'> - <parameter type-id='type-id-473' name='fp' filepath='Python/pylifecycle.c' line='2953' column='1'/> - <parameter type-id='type-id-3' name='filename' filepath='Python/pylifecycle.c' line='2953' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='Py_Exit' mangled-name='Py_Exit' filepath='Python/pylifecycle.c' line='2936' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_Exit'> - <parameter type-id='type-id-8' name='sts' filepath='Python/pylifecycle.c' line='2936' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='Py_AtExit' mangled-name='Py_AtExit' filepath='Python/pylifecycle.c' line='2911' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_AtExit'> - <parameter type-id='type-id-211' name='func' filepath='Python/pylifecycle.c' line='2911' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='Py_ExitStatusException' mangled-name='Py_ExitStatusException' filepath='Python/pylifecycle.c' line='2870' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_ExitStatusException'> - <parameter type-id='type-id-806' name='status' filepath='Python/pylifecycle.c' line='2870' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_Py_FatalRefcountErrorFunc' mangled-name='_Py_FatalRefcountErrorFunc' filepath='Python/pylifecycle.c' line='2860' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_FatalRefcountErrorFunc'> - <parameter type-id='type-id-3' name='func' filepath='Python/pylifecycle.c' line='2860' column='1'/> - <parameter type-id='type-id-3' name='msg' filepath='Python/pylifecycle.c' line='2860' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_Py_FatalErrorFormat' mangled-name='_Py_FatalErrorFormat' filepath='Python/pylifecycle.c' line='2826' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_FatalErrorFormat'> - <parameter type-id='type-id-3' name='func' filepath='Python/pylifecycle.c' line='2826' column='1'/> - <parameter type-id='type-id-3' name='format' filepath='Python/pylifecycle.c' line='2826' column='1'/> - <parameter is-variadic='yes'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_Py_FatalErrorFunc' mangled-name='_Py_FatalErrorFunc' filepath='Python/pylifecycle.c' line='2819' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_FatalErrorFunc'> - <parameter type-id='type-id-3' name='func' filepath='Python/pylifecycle.c' line='2860' column='1'/> - <parameter type-id='type-id-3' name='msg' filepath='Python/pylifecycle.c' line='2860' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='Py_FatalError' mangled-name='Py_FatalError' filepath='Python/pylifecycle.c' line='2812' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_FatalError'> - <parameter type-id='type-id-3' name='func' filepath='Python/ceval.c' line='342' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_Py_DumpExtensionModules' mangled-name='_Py_DumpExtensionModules' filepath='Python/pylifecycle.c' line='2639' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_DumpExtensionModules'> - <parameter type-id='type-id-8' name='fd' filepath='Python/pylifecycle.c' line='2639' column='1'/> - <parameter type-id='type-id-11' name='interp' filepath='Python/pylifecycle.c' line='2639' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='Py_EndInterpreter' mangled-name='Py_EndInterpreter' filepath='Python/pylifecycle.c' line='2068' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_EndInterpreter'> - <parameter type-id='type-id-10' name='tstate' filepath='Python/ceval.c' line='531' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='Py_NewInterpreter' mangled-name='Py_NewInterpreter' filepath='Python/pylifecycle.c' line='2050' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_NewInterpreter'> - <return type-id='type-id-10'/> - </function-decl> - <function-decl name='_Py_NewInterpreter' mangled-name='_Py_NewInterpreter' filepath='Python/pylifecycle.c' line='2038' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_NewInterpreter'> - <parameter type-id='type-id-8' name='isolated_subinterpreter' filepath='Python/pylifecycle.c' line='2038' column='1'/> - <return type-id='type-id-10'/> - </function-decl> - <function-decl name='Py_Finalize' mangled-name='Py_Finalize' filepath='Python/pylifecycle.c' line='1934' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_Finalize'> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='Py_FinalizeEx' mangled-name='Py_FinalizeEx' filepath='Python/pylifecycle.c' line='1749' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_FinalizeEx'> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_Py_InitializeMain' mangled-name='_Py_InitializeMain' filepath='Python/pylifecycle.c' line='1305' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_InitializeMain'> - <return type-id='type-id-806'/> - </function-decl> - <function-decl name='Py_Initialize' mangled-name='Py_Initialize' filepath='Python/pylifecycle.c' line='1298' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_Initialize'> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='Py_InitializeEx' mangled-name='Py_InitializeEx' filepath='Python/pylifecycle.c' line='1271' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_InitializeEx'> - <parameter type-id='type-id-8' name='install_sigs' filepath='Python/pylifecycle.c' line='1271' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='Py_InitializeFromConfig' mangled-name='Py_InitializeFromConfig' filepath='Python/pylifecycle.c' line='1238' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_InitializeFromConfig'> - <parameter type-id='type-id-814' name='config' filepath='Python/pylifecycle.c' line='1238' column='1'/> - <return type-id='type-id-806'/> - </function-decl> - <function-decl name='_Py_PreInitializeFromConfig' mangled-name='_Py_PreInitializeFromConfig' filepath='Python/pylifecycle.c' line='982' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_PreInitializeFromConfig'> - <parameter type-id='type-id-814' name='config' filepath='Python/pylifecycle.c' line='982' column='1'/> - <parameter type-id='type-id-822' name='args' filepath='Python/pylifecycle.c' line='983' column='1'/> - <return type-id='type-id-806'/> - </function-decl> - <qualified-type-def type-id='type-id-63' const='yes' id='type-id-851'/> - <pointer-type-def type-id='type-id-851' size-in-bits='64' id='type-id-852'/> - <function-decl name='Py_PreInitialize' mangled-name='Py_PreInitialize' filepath='Python/pylifecycle.c' line='975' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_PreInitialize'> - <parameter type-id='type-id-852' name='src_config' filepath='Python/pylifecycle.c' line='975' column='1'/> - <return type-id='type-id-806'/> - </function-decl> - <function-decl name='Py_PreInitializeFromArgs' mangled-name='Py_PreInitializeFromArgs' filepath='Python/pylifecycle.c' line='967' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_PreInitializeFromArgs'> - <parameter type-id='type-id-852' name='src_config' filepath='Python/pylifecycle.c' line='967' column='1'/> - <parameter type-id='type-id-36' name='argc' filepath='Python/pylifecycle.c' line='967' column='1'/> - <parameter type-id='type-id-374' name='argv' filepath='Python/pylifecycle.c' line='967' column='1'/> - <return type-id='type-id-806'/> - </function-decl> - <function-decl name='Py_PreInitializeFromBytesArgs' mangled-name='Py_PreInitializeFromBytesArgs' filepath='Python/pylifecycle.c' line='959' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_PreInitializeFromBytesArgs'> - <parameter type-id='type-id-852' name='src_config' filepath='Python/pylifecycle.c' line='959' column='1'/> - <parameter type-id='type-id-36' name='argc' filepath='Python/pylifecycle.c' line='959' column='1'/> - <parameter type-id='type-id-494' name='argv' filepath='Python/pylifecycle.c' line='959' column='1'/> - <return type-id='type-id-806'/> - </function-decl> - <function-decl name='_Py_PreInitializeFromPyArgv' mangled-name='_Py_PreInitializeFromPyArgv' filepath='Python/pylifecycle.c' line='912' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_PreInitializeFromPyArgv'> - <parameter type-id='type-id-852' name='src_config' filepath='Python/pylifecycle.c' line='912' column='1'/> - <parameter type-id='type-id-822' name='args' filepath='Python/pylifecycle.c' line='912' column='1'/> - <return type-id='type-id-806'/> - </function-decl> - <function-decl name='_PyInterpreterState_SetConfig' mangled-name='_PyInterpreterState_SetConfig' filepath='Python/pylifecycle.c' line='492' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyInterpreterState_SetConfig'> - <parameter type-id='type-id-814' name='src_config' filepath='Python/pylifecycle.c' line='492' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_Py_SetLocaleFromEnv' mangled-name='_Py_SetLocaleFromEnv' filepath='Python/pylifecycle.c' line='404' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_SetLocaleFromEnv'> - <parameter type-id='type-id-8' name='category' filepath='Python/pylifecycle.c' line='404' column='1'/> - <return type-id='type-id-115'/> - </function-decl> - <function-decl name='_Py_CoerceLegacyLocale' mangled-name='_Py_CoerceLegacyLocale' filepath='Python/pylifecycle.c' line='354' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_CoerceLegacyLocale'> - <parameter type-id='type-id-8' name='warn' filepath='Python/pylifecycle.c' line='354' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_Py_IsLocaleCoercionTarget' mangled-name='_Py_IsLocaleCoercionTarget' filepath='Python/pylifecycle.c' line='312' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_IsLocaleCoercionTarget'> - <parameter type-id='type-id-3' name='encoding' filepath='Python/codecs.c' line='214' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_Py_LegacyLocaleDetected' mangled-name='_Py_LegacyLocaleDetected' filepath='Python/pylifecycle.c' line='257' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_LegacyLocaleDetected'> - <parameter type-id='type-id-8' name='warn' filepath='Python/pylifecycle.c' line='257' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='Py_IsInitialized' mangled-name='Py_IsInitialized' filepath='Python/pylifecycle.c' line='157' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_IsInitialized'> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_Py_IsCoreInitialized' mangled-name='_Py_IsCoreInitialized' filepath='Python/pylifecycle.c' line='151' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_IsCoreInitialized'> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_Py_IsFinalizing' mangled-name='_Py_IsFinalizing' filepath='Python/pylifecycle.c' line='135' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_IsFinalizing'> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyRuntime_Finalize' mangled-name='_PyRuntime_Finalize' filepath='Python/pylifecycle.c' line='128' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyRuntime_Finalize'> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_PyRuntime_Initialize' mangled-name='_PyRuntime_Initialize' filepath='Python/pylifecycle.c' line='111' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyRuntime_Initialize'> - <return type-id='type-id-806'/> - </function-decl> - <function-type size-in-bits='64' id='type-id-848'> - <parameter type-id='type-id-8'/> - <return type-id='type-id-70'/> - </function-type> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Python/pystate.c' comp-dir-path='/src' language='LANG_C99'> - <function-decl name='_Py_GetConfig' mangled-name='_Py_GetConfig' filepath='Python/pystate.c' line='2135' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_GetConfig'> - <return type-id='type-id-814'/> - </function-decl> - <function-decl name='_PyInterpreterState_GetConfigCopy' mangled-name='_PyInterpreterState_GetConfigCopy' filepath='Python/pystate.c' line='2121' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyInterpreterState_GetConfigCopy'> - <parameter type-id='type-id-809' name='config' filepath='Python/pystate.c' line='2121' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyInterpreterState_GetConfig' mangled-name='_PyInterpreterState_GetConfig' filepath='Python/pystate.c' line='2114' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyInterpreterState_GetConfig'> - <parameter type-id='type-id-11' name='interp' filepath='Python/pystate.c' line='2114' column='1'/> - <return type-id='type-id-814'/> - </function-decl> - <function-decl name='_PyInterpreterState_SetEvalFrameFunc' mangled-name='_PyInterpreterState_SetEvalFrameFunc' filepath='Python/pystate.c' line='2101' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyInterpreterState_SetEvalFrameFunc'> - <parameter type-id='type-id-11' name='interp' filepath='Python/pystate.c' line='2101' column='1'/> - <parameter type-id='type-id-35' name='eval_frame' filepath='Python/pystate.c' line='2102' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_PyInterpreterState_GetEvalFrameFunc' mangled-name='_PyInterpreterState_GetEvalFrameFunc' filepath='Python/pystate.c' line='2091' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyInterpreterState_GetEvalFrameFunc'> - <parameter type-id='type-id-11' name='interp' filepath='Python/pystate.c' line='2091' column='1'/> - <return type-id='type-id-35'/> - </function-decl> - <function-decl name='_PyCrossInterpreterData_Lookup' mangled-name='_PyCrossInterpreterData_Lookup' filepath='Python/pystate.c' line='1941' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyCrossInterpreterData_Lookup'> - <parameter type-id='type-id-14' name='obj' filepath='Python/pystate.c' line='1941' column='1'/> - <return type-id='type-id-75'/> - </function-decl> - <function-decl name='_PyCrossInterpreterData_RegisterClass' mangled-name='_PyCrossInterpreterData_RegisterClass' filepath='Python/pystate.c' line='1911' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyCrossInterpreterData_RegisterClass'> - <parameter type-id='type-id-74' name='cls' filepath='Python/pystate.c' line='1911' column='1'/> - <parameter type-id='type-id-75' name='getdata' filepath='Python/pystate.c' line='1912' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyCrossInterpreterData_NewObject' mangled-name='_PyCrossInterpreterData_NewObject' filepath='Python/pystate.c' line='1881' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyCrossInterpreterData_NewObject'> - <parameter type-id='type-id-206' name='data' filepath='Python/pystate.c' line='1881' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyCrossInterpreterData_Release' mangled-name='_PyCrossInterpreterData_Release' filepath='Python/pystate.c' line='1858' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyCrossInterpreterData_Release'> - <parameter type-id='type-id-206' name='data' filepath='Python/pystate.c' line='1858' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_PyObject_GetCrossInterpreterData' mangled-name='_PyObject_GetCrossInterpreterData' filepath='Python/pystate.c' line='1786' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_GetCrossInterpreterData'> - <parameter type-id='type-id-14' name='obj' filepath='Python/pystate.c' line='1786' column='1'/> - <parameter type-id='type-id-206' name='data' filepath='Python/pystate.c' line='1786' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyObject_CheckCrossInterpreterData' mangled-name='_PyObject_CheckCrossInterpreterData' filepath='Python/pystate.c' line='1754' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_CheckCrossInterpreterData'> - <parameter type-id='type-id-14' name='obj' filepath='Objects/abstract.c' line='2845' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <enum-decl name='__anonymous_enum__' is-anonymous='yes' filepath='./Include/pystate.h' line='77' column='1' id='type-id-853'> - <underlying-type type-id='type-id-126'/> - <enumerator name='PyGILState_LOCKED' value='0'/> - <enumerator name='PyGILState_UNLOCKED' value='1'/> - </enum-decl> - <typedef-decl name='PyGILState_STATE' type-id='type-id-853' filepath='./Include/pystate.h' line='78' column='1' id='type-id-854'/> - <function-decl name='PyGILState_Release' mangled-name='PyGILState_Release' filepath='Python/pystate.c' line='1689' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyGILState_Release'> - <parameter type-id='type-id-854' name='oldstate' filepath='Python/pystate.c' line='1689' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyGILState_Ensure' mangled-name='PyGILState_Ensure' filepath='Python/pystate.c' line='1641' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyGILState_Ensure'> - <return type-id='type-id-854'/> - </function-decl> - <function-decl name='PyGILState_Check' mangled-name='PyGILState_Check' filepath='Python/pystate.c' line='1621' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyGILState_Check'> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyGILState_GetThisThreadState' mangled-name='PyGILState_GetThisThreadState' filepath='Python/pystate.c' line='1615' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyGILState_GetThisThreadState'> - <return type-id='type-id-10'/> - </function-decl> - <function-decl name='_PyGILState_GetInterpreterStateUnsafe' mangled-name='_PyGILState_GetInterpreterStateUnsafe' filepath='Python/pystate.c' line='1528' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyGILState_GetInterpreterStateUnsafe'> - <return type-id='type-id-11'/> - </function-decl> - <function-decl name='_PyThread_CurrentExceptions' mangled-name='_PyThread_CurrentExceptions' filepath='Python/pystate.c' line='1410' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyThread_CurrentExceptions'> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyThread_CurrentFrames' mangled-name='_PyThread_CurrentFrames' filepath='Python/pystate.c' line='1360' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyThread_CurrentFrames'> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyThreadState_Next' mangled-name='PyThreadState_Next' filepath='Python/pystate.c' line='1350' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThreadState_Next'> - <parameter type-id='type-id-10' name='tstate' filepath='Python/pystate.c' line='1350' column='1'/> - <return type-id='type-id-10'/> - </function-decl> - <function-decl name='PyInterpreterState_ThreadHead' mangled-name='PyInterpreterState_ThreadHead' filepath='Python/pystate.c' line='1345' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInterpreterState_ThreadHead'> - <parameter type-id='type-id-11' name='interp' filepath='Python/pystate.c' line='1345' column='1'/> - <return type-id='type-id-10'/> - </function-decl> - <function-decl name='PyInterpreterState_Next' mangled-name='PyInterpreterState_Next' filepath='Python/pystate.c' line='1340' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInterpreterState_Next'> - <parameter type-id='type-id-11' name='interp' filepath='Python/pystate.c' line='1340' column='1'/> - <return type-id='type-id-11'/> - </function-decl> - <function-decl name='PyInterpreterState_Main' mangled-name='PyInterpreterState_Main' filepath='Python/pystate.c' line='1334' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInterpreterState_Main'> - <return type-id='type-id-11'/> - </function-decl> - <function-decl name='PyInterpreterState_Head' mangled-name='PyInterpreterState_Head' filepath='Python/pystate.c' line='1328' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInterpreterState_Head'> - <return type-id='type-id-11'/> - </function-decl> - <function-decl name='PyThreadState_SetAsyncExc' mangled-name='PyThreadState_SetAsyncExc' filepath='Python/pystate.c' line='1287' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThreadState_SetAsyncExc'> - <parameter type-id='type-id-16' name='id' filepath='Python/pystate.c' line='1287' column='1'/> - <parameter type-id='type-id-14' name='exc' filepath='Python/pystate.c' line='1287' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyThreadState_GetID' mangled-name='PyThreadState_GetID' filepath='Python/pystate.c' line='1271' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThreadState_GetID'> - <parameter type-id='type-id-10' name='tstate' filepath='Python/pystate.c' line='1271' column='1'/> - <return type-id='type-id-19'/> - </function-decl> - <function-decl name='PyThreadState_GetFrame' mangled-name='PyThreadState_GetFrame' filepath='Python/pystate.c' line='1255' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThreadState_GetFrame'> - <parameter type-id='type-id-10' name='tstate' filepath='Python/pystate.c' line='1255' column='1'/> - <return type-id='type-id-438'/> - </function-decl> - <function-decl name='PyThreadState_GetInterpreter' mangled-name='PyThreadState_GetInterpreter' filepath='Python/pystate.c' line='1247' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThreadState_GetInterpreter'> - <parameter type-id='type-id-10' name='tstate' filepath='Python/pystate.c' line='1247' column='1'/> - <return type-id='type-id-11'/> - </function-decl> - <function-decl name='PyThreadState_GetDict' mangled-name='PyThreadState_GetDict' filepath='Python/pystate.c' line='1236' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThreadState_GetDict'> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyThreadState_GetDict' mangled-name='_PyThreadState_GetDict' filepath='Python/pystate.c' line='1222' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyThreadState_GetDict'> - <parameter type-id='type-id-10' name='tstate' filepath='Python/pystate.c' line='1222' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyThreadState_Swap' mangled-name='PyThreadState_Swap' filepath='Python/pystate.c' line='1210' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThreadState_Swap'> - <parameter type-id='type-id-10' name='tstate' filepath='Python/pystate.c' line='1350' column='1'/> - <return type-id='type-id-10'/> - </function-decl> - <pointer-type-def type-id='type-id-62' size-in-bits='64' id='type-id-855'/> - <function-decl name='_PyThreadState_Swap' mangled-name='_PyThreadState_Swap' filepath='Python/pystate.c' line='1185' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyThreadState_Swap'> - <parameter type-id='type-id-855' name='gilstate' filepath='Python/pystate.c' line='1185' column='1'/> - <parameter type-id='type-id-10' name='newts' filepath='Python/pystate.c' line='1185' column='1'/> - <return type-id='type-id-10'/> - </function-decl> - <function-decl name='PyThreadState_Get' mangled-name='PyThreadState_Get' filepath='Python/pystate.c' line='1176' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThreadState_Get'> - <return type-id='type-id-10'/> - </function-decl> - <function-decl name='_PyThreadState_UncheckedGet' mangled-name='_PyThreadState_UncheckedGet' filepath='Python/pystate.c' line='1169' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyThreadState_UncheckedGet'> - <return type-id='type-id-10'/> - </function-decl> - <pointer-type-def type-id='type-id-847' size-in-bits='64' id='type-id-856'/> - <function-decl name='_PyThreadState_DeleteExcept' mangled-name='_PyThreadState_DeleteExcept' filepath='Python/pystate.c' line='1134' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyThreadState_DeleteExcept'> - <parameter type-id='type-id-856' name='runtime' filepath='Python/pystate.c' line='1134' column='1'/> - <parameter type-id='type-id-10' name='tstate' filepath='Python/pystate.c' line='1134' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyThreadState_DeleteCurrent' mangled-name='PyThreadState_DeleteCurrent' filepath='Python/pystate.c' line='1118' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThreadState_DeleteCurrent'> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_PyThreadState_DeleteCurrent' mangled-name='_PyThreadState_DeleteCurrent' filepath='Python/pystate.c' line='1107' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyThreadState_DeleteCurrent'> - <parameter type-id='type-id-10' name='tstate' filepath='Python/pystate.c' line='1107' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyThreadState_Delete' mangled-name='PyThreadState_Delete' filepath='Python/pystate.c' line='1100' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThreadState_Delete'> - <parameter type-id='type-id-10' name='tstate' filepath='Objects/object.c' line='2291' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyThreadState_Clear' mangled-name='PyThreadState_Clear' filepath='Python/pystate.c' line='998' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThreadState_Clear'> - <parameter type-id='type-id-10' name='tstate' filepath='Python/pystate.c' line='998' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyState_RemoveModule' mangled-name='PyState_RemoveModule' filepath='Python/pystate.c' line='941' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyState_RemoveModule'> - <parameter type-id='type-id-539' name='def' filepath='Python/pystate.c' line='941' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyState_AddModule' mangled-name='PyState_AddModule' filepath='Python/pystate.c' line='920' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyState_AddModule'> - <parameter type-id='type-id-14' name='module' filepath='Python/pystate.c' line='920' column='1'/> - <parameter type-id='type-id-539' name='def' filepath='Python/pystate.c' line='920' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyState_AddModule' mangled-name='_PyState_AddModule' filepath='Python/pystate.c' line='887' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyState_AddModule'> - <parameter type-id='type-id-10' name='tstate' filepath='Python/pystate.c' line='887' column='1'/> - <parameter type-id='type-id-14' name='module' filepath='Python/pystate.c' line='887' column='1'/> - <parameter type-id='type-id-539' name='def' filepath='Python/pystate.c' line='887' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyState_FindModule' mangled-name='PyState_FindModule' filepath='Python/pystate.c' line='868' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyState_FindModule'> - <parameter type-id='type-id-539' name='module' filepath='Python/pystate.c' line='868' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyThreadState_SetCurrent' mangled-name='_PyThreadState_SetCurrent' filepath='Python/pystate.c' line='862' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyThreadState_SetCurrent'> - <parameter type-id='type-id-10' name='tstate' filepath='Objects/object.c' line='2291' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_PyThreadState_Init' mangled-name='_PyThreadState_Init' filepath='Python/pystate.c' line='856' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyThreadState_Init'> - <parameter type-id='type-id-10' name='tstate' filepath='Python/pystate.c' line='856' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_PyThreadState_Prealloc' mangled-name='_PyThreadState_Prealloc' filepath='Python/pystate.c' line='848' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyThreadState_Prealloc'> - <parameter type-id='type-id-11' name='interp' filepath='Python/pystate.c' line='1345' column='1'/> - <return type-id='type-id-10'/> - </function-decl> - <function-decl name='PyThreadState_New' mangled-name='PyThreadState_New' filepath='Python/pystate.c' line='840' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThreadState_New'> - <parameter type-id='type-id-11' name='interp' filepath='Python/pystate.c' line='840' column='1'/> - <return type-id='type-id-10'/> - </function-decl> - <function-decl name='PyInterpreterState_GetDict' mangled-name='PyInterpreterState_GetDict' filepath='Python/pystate.c' line='700' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInterpreterState_GetDict'> - <parameter type-id='type-id-11' name='interp' filepath='Python/pystate.c' line='700' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyInterpreterState_GetMainModule' mangled-name='_PyInterpreterState_GetMainModule' filepath='Python/pystate.c' line='690' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyInterpreterState_GetMainModule'> - <parameter type-id='type-id-11' name='interp' filepath='Python/pystate.c' line='700' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyInterpreterState_RequireIDRef' mangled-name='_PyInterpreterState_RequireIDRef' filepath='Python/pystate.c' line='684' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyInterpreterState_RequireIDRef'> - <parameter type-id='type-id-11' name='interp' filepath='Python/pystate.c' line='684' column='1'/> - <parameter type-id='type-id-8' name='required' filepath='Python/pystate.c' line='684' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_PyInterpreterState_RequiresIDRef' mangled-name='_PyInterpreterState_RequiresIDRef' filepath='Python/pystate.c' line='678' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyInterpreterState_RequiresIDRef'> - <parameter type-id='type-id-11' name='interp' filepath='Python/import.c' line='278' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyInterpreterState_IDDecref' mangled-name='_PyInterpreterState_IDDecref' filepath='Python/pystate.c' line='656' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyInterpreterState_IDDecref'> - <parameter type-id='type-id-11' name='interp' filepath='Python/pystate.c' line='656' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_PyInterpreterState_IDIncref' mangled-name='_PyInterpreterState_IDIncref' filepath='Python/pystate.c' line='642' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyInterpreterState_IDIncref'> - <parameter type-id='type-id-11' name='interp' filepath='Python/import.c' line='278' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyInterpreterState_IDInitref' mangled-name='_PyInterpreterState_IDInitref' filepath='Python/pystate.c' line='625' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyInterpreterState_IDInitref'> - <parameter type-id='type-id-11' name='interp' filepath='Python/import.c' line='278' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyInterpreterState_LookUpID' mangled-name='_PyInterpreterState_LookUpID' filepath='Python/pystate.c' line='607' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyInterpreterState_LookUpID'> - <parameter type-id='type-id-29' name='requested_id' filepath='Python/pystate.c' line='607' column='1'/> - <return type-id='type-id-11'/> - </function-decl> - <function-decl name='PyInterpreterState_GetID' mangled-name='PyInterpreterState_GetID' filepath='Python/pystate.c' line='579' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInterpreterState_GetID'> - <parameter type-id='type-id-11' name='interp' filepath='Python/pystate.c' line='579' column='1'/> - <return type-id='type-id-29'/> - </function-decl> - <function-decl name='PyInterpreterState_Get' mangled-name='PyInterpreterState_Get' filepath='Python/pystate.c' line='566' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInterpreterState_Get'> - <return type-id='type-id-11'/> - </function-decl> - <function-decl name='PyInterpreterState_Delete' mangled-name='PyInterpreterState_Delete' filepath='Python/pystate.c' line='477' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInterpreterState_Delete'> - <parameter type-id='type-id-11' name='interp' filepath='Python/pystate.c' line='477' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyInterpreterState_Clear' mangled-name='PyInterpreterState_Clear' filepath='Python/pystate.c' line='446' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInterpreterState_Clear'> - <parameter type-id='type-id-11' name='interp' filepath='Python/ceval.c' line='565' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyInterpreterState_New' mangled-name='PyInterpreterState_New' filepath='Python/pystate.c' line='302' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInterpreterState_New'> - <return type-id='type-id-11'/> - </function-decl> - <function-decl name='_PyInterpreterState_Enable' mangled-name='_PyInterpreterState_Enable' filepath='Python/pystate.c' line='226' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyInterpreterState_Enable'> - <parameter type-id='type-id-856' name='runtime' filepath='Python/pystate.c' line='226' column='1'/> - <return type-id='type-id-806'/> - </function-decl> - <function-decl name='_PyRuntimeState_Fini' mangled-name='_PyRuntimeState_Fini' filepath='Python/pystate.c' line='161' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyRuntimeState_Fini'> - <parameter type-id='type-id-856' name='runtime' filepath='Python/pystate.c' line='161' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_PyRuntimeState_Init' mangled-name='_PyRuntimeState_Init' filepath='Python/pystate.c' line='132' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyRuntimeState_Init'> - <parameter type-id='type-id-856' name='runtime' filepath='Python/pystate.c' line='132' column='1'/> - <return type-id='type-id-806'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Python/pythonrun.c' comp-dir-path='/src' language='LANG_C99'> - <function-decl name='PyRun_InteractiveLoop' mangled-name='PyRun_InteractiveLoop' filepath='Python/pythonrun.c' line='2005' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyRun_InteractiveLoop'> - <parameter type-id='type-id-473' name='fp' filepath='Python/pylifecycle.c' line='2953' column='1'/> - <parameter type-id='type-id-3' name='filename' filepath='Python/pylifecycle.c' line='2953' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyRun_InteractiveOne' mangled-name='PyRun_InteractiveOne' filepath='Python/pythonrun.c' line='1998' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyRun_InteractiveOne'> - <parameter type-id='type-id-473' name='fp' filepath='Python/pylifecycle.c' line='2953' column='1'/> - <parameter type-id='type-id-3' name='filename' filepath='Python/pylifecycle.c' line='2953' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='Py_CompileStringFlags' mangled-name='Py_CompileStringFlags' filepath='Python/pythonrun.c' line='1990' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_CompileStringFlags'> - <parameter type-id='type-id-3' name='str' filepath='Python/pythonrun.c' line='1990' column='1'/> - <parameter type-id='type-id-3' name='p' filepath='Python/pythonrun.c' line='1990' column='1'/> - <parameter type-id='type-id-8' name='s' filepath='Python/pythonrun.c' line='1990' column='1'/> - <parameter type-id='type-id-593' name='flags' filepath='Python/pythonrun.c' line='1991' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='Py_CompileString' mangled-name='Py_CompileString' filepath='Python/pythonrun.c' line='1983' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_CompileString'> - <parameter type-id='type-id-3' name='str' filepath='Python/pythonrun.c' line='1983' column='1'/> - <parameter type-id='type-id-3' name='p' filepath='Python/pythonrun.c' line='1983' column='1'/> - <parameter type-id='type-id-8' name='s' filepath='Python/pythonrun.c' line='1983' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyRun_SimpleString' mangled-name='PyRun_SimpleString' filepath='Python/pythonrun.c' line='1976' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyRun_SimpleString'> - <parameter type-id='type-id-3' name='where' filepath='Python/ceval.c' line='7947' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyRun_String' mangled-name='PyRun_String' filepath='Python/pythonrun.c' line='1969' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyRun_String'> - <parameter type-id='type-id-3' name='str' filepath='Python/pythonrun.c' line='1969' column='1'/> - <parameter type-id='type-id-8' name='s' filepath='Python/pythonrun.c' line='1969' column='1'/> - <parameter type-id='type-id-14' name='g' filepath='Python/pythonrun.c' line='1969' column='1'/> - <parameter type-id='type-id-14' name='l' filepath='Python/pythonrun.c' line='1969' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyRun_SimpleFileEx' mangled-name='PyRun_SimpleFileEx' filepath='Python/pythonrun.c' line='1961' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyRun_SimpleFileEx'> - <parameter type-id='type-id-473' name='f' filepath='Python/pythonrun.c' line='1961' column='1'/> - <parameter type-id='type-id-3' name='p' filepath='Python/pythonrun.c' line='1961' column='1'/> - <parameter type-id='type-id-8' name='c' filepath='Python/pythonrun.c' line='1961' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyRun_SimpleFile' mangled-name='PyRun_SimpleFile' filepath='Python/pythonrun.c' line='1954' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyRun_SimpleFile'> - <parameter type-id='type-id-473' name='fp' filepath='Python/pylifecycle.c' line='2953' column='1'/> - <parameter type-id='type-id-3' name='filename' filepath='Python/pylifecycle.c' line='2953' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyRun_FileFlags' mangled-name='PyRun_FileFlags' filepath='Python/pythonrun.c' line='1946' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyRun_FileFlags'> - <parameter type-id='type-id-473' name='fp' filepath='Python/pythonrun.c' line='1946' column='1'/> - <parameter type-id='type-id-3' name='p' filepath='Python/pythonrun.c' line='1946' column='1'/> - <parameter type-id='type-id-8' name='s' filepath='Python/pythonrun.c' line='1946' column='1'/> - <parameter type-id='type-id-14' name='g' filepath='Python/pythonrun.c' line='1946' column='1'/> - <parameter type-id='type-id-14' name='l' filepath='Python/pythonrun.c' line='1946' column='1'/> - <parameter type-id='type-id-593' name='flags' filepath='Python/pythonrun.c' line='1947' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyRun_FileEx' mangled-name='PyRun_FileEx' filepath='Python/pythonrun.c' line='1939' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyRun_FileEx'> - <parameter type-id='type-id-473' name='fp' filepath='Python/pythonrun.c' line='1939' column='1'/> - <parameter type-id='type-id-3' name='p' filepath='Python/pythonrun.c' line='1939' column='1'/> - <parameter type-id='type-id-8' name='s' filepath='Python/pythonrun.c' line='1939' column='1'/> - <parameter type-id='type-id-14' name='g' filepath='Python/pythonrun.c' line='1939' column='1'/> - <parameter type-id='type-id-14' name='l' filepath='Python/pythonrun.c' line='1939' column='1'/> - <parameter type-id='type-id-8' name='c' filepath='Python/pythonrun.c' line='1939' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyRun_File' mangled-name='PyRun_File' filepath='Python/pythonrun.c' line='1932' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyRun_File'> - <parameter type-id='type-id-473' name='fp' filepath='Python/pythonrun.c' line='1932' column='1'/> - <parameter type-id='type-id-3' name='p' filepath='Python/pythonrun.c' line='1932' column='1'/> - <parameter type-id='type-id-8' name='s' filepath='Python/pythonrun.c' line='1932' column='1'/> - <parameter type-id='type-id-14' name='g' filepath='Python/pythonrun.c' line='1932' column='1'/> - <parameter type-id='type-id-14' name='l' filepath='Python/pythonrun.c' line='1932' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyRun_AnyFileFlags' mangled-name='PyRun_AnyFileFlags' filepath='Python/pythonrun.c' line='1925' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyRun_AnyFileFlags'> - <parameter type-id='type-id-473' name='fp' filepath='Python/pythonrun.c' line='1925' column='1'/> - <parameter type-id='type-id-3' name='name' filepath='Python/pythonrun.c' line='1925' column='1'/> - <parameter type-id='type-id-593' name='flags' filepath='Python/pythonrun.c' line='1925' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyRun_AnyFileEx' mangled-name='PyRun_AnyFileEx' filepath='Python/pythonrun.c' line='1918' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyRun_AnyFileEx'> - <parameter type-id='type-id-473' name='f' filepath='Python/pythonrun.c' line='1961' column='1'/> - <parameter type-id='type-id-3' name='p' filepath='Python/pythonrun.c' line='1961' column='1'/> - <parameter type-id='type-id-8' name='c' filepath='Python/pythonrun.c' line='1961' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyRun_AnyFile' mangled-name='PyRun_AnyFile' filepath='Python/pythonrun.c' line='1911' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyRun_AnyFile'> - <parameter type-id='type-id-473' name='fp' filepath='Python/pylifecycle.c' line='2953' column='1'/> - <parameter type-id='type-id-3' name='filename' filepath='Python/pylifecycle.c' line='2953' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_Py_SourceAsString' mangled-name='_Py_SourceAsString' filepath='Python/pythonrun.c' line='1822' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_SourceAsString'> - <parameter type-id='type-id-14' name='cmd' filepath='Python/pythonrun.c' line='1822' column='1'/> - <parameter type-id='type-id-3' name='funcname' filepath='Python/pythonrun.c' line='1822' column='1'/> - <parameter type-id='type-id-3' name='what' filepath='Python/pythonrun.c' line='1822' column='1'/> - <parameter type-id='type-id-593' name='cf' filepath='Python/pythonrun.c' line='1822' column='1'/> - <parameter type-id='type-id-22' name='cmd_copy' filepath='Python/pythonrun.c' line='1822' column='1'/> - <return type-id='type-id-3'/> - </function-decl> - <function-decl name='Py_CompileStringExFlags' mangled-name='Py_CompileStringExFlags' filepath='Python/pythonrun.c' line='1809' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_CompileStringExFlags'> - <parameter type-id='type-id-3' name='str' filepath='Python/pythonrun.c' line='1809' column='1'/> - <parameter type-id='type-id-3' name='filename_str' filepath='Python/pythonrun.c' line='1809' column='1'/> - <parameter type-id='type-id-8' name='start' filepath='Python/pythonrun.c' line='1809' column='1'/> - <parameter type-id='type-id-593' name='flags' filepath='Python/pythonrun.c' line='1810' column='1'/> - <parameter type-id='type-id-8' name='optimize' filepath='Python/pythonrun.c' line='1810' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='Py_CompileStringObject' mangled-name='Py_CompileStringObject' filepath='Python/pythonrun.c' line='1784' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_CompileStringObject'> - <parameter type-id='type-id-3' name='str' filepath='Python/pythonrun.c' line='1784' column='1'/> - <parameter type-id='type-id-14' name='filename' filepath='Python/pythonrun.c' line='1784' column='1'/> - <parameter type-id='type-id-8' name='start' filepath='Python/pythonrun.c' line='1784' column='1'/> - <parameter type-id='type-id-593' name='flags' filepath='Python/pythonrun.c' line='1785' column='1'/> - <parameter type-id='type-id-8' name='optimize' filepath='Python/pythonrun.c' line='1785' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyRun_FileExFlags' mangled-name='PyRun_FileExFlags' filepath='Python/pythonrun.c' line='1642' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyRun_FileExFlags'> - <parameter type-id='type-id-473' name='fp' filepath='Python/pythonrun.c' line='1642' column='1'/> - <parameter type-id='type-id-3' name='filename' filepath='Python/pythonrun.c' line='1642' column='1'/> - <parameter type-id='type-id-8' name='start' filepath='Python/pythonrun.c' line='1642' column='1'/> - <parameter type-id='type-id-14' name='globals' filepath='Python/pythonrun.c' line='1642' column='1'/> - <parameter type-id='type-id-14' name='locals' filepath='Python/pythonrun.c' line='1643' column='1'/> - <parameter type-id='type-id-8' name='closeit' filepath='Python/pythonrun.c' line='1643' column='1'/> - <parameter type-id='type-id-593' name='flags' filepath='Python/pythonrun.c' line='1643' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyRun_StringFlags' mangled-name='PyRun_StringFlags' filepath='Python/pythonrun.c' line='1589' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyRun_StringFlags'> - <parameter type-id='type-id-3' name='str' filepath='Python/pythonrun.c' line='1589' column='1'/> - <parameter type-id='type-id-8' name='start' filepath='Python/pythonrun.c' line='1589' column='1'/> - <parameter type-id='type-id-14' name='globals' filepath='Python/pythonrun.c' line='1589' column='1'/> - <parameter type-id='type-id-14' name='locals' filepath='Python/pythonrun.c' line='1590' column='1'/> - <parameter type-id='type-id-593' name='flags' filepath='Python/pythonrun.c' line='1590' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyErr_Display' mangled-name='PyErr_Display' filepath='Python/pythonrun.c' line='1571' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_Display'> - <parameter type-id='type-id-14' name='exception' filepath='Python/pythonrun.c' line='1571' column='1'/> - <parameter type-id='type-id-14' name='value' filepath='Python/pythonrun.c' line='1571' column='1'/> - <parameter type-id='type-id-14' name='tb' filepath='Python/pythonrun.c' line='1571' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_PyErr_Display' mangled-name='_PyErr_Display' filepath='Python/pythonrun.c' line='1524' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyErr_Display'> - <parameter type-id='type-id-14' name='file' filepath='Python/pythonrun.c' line='1524' column='1'/> - <parameter type-id='type-id-14' name='exception' filepath='Python/pythonrun.c' line='1524' column='1'/> - <parameter type-id='type-id-14' name='value' filepath='Python/pythonrun.c' line='1524' column='1'/> - <parameter type-id='type-id-14' name='tb' filepath='Python/pythonrun.c' line='1524' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyErr_Print' mangled-name='PyErr_Print' filepath='Python/pythonrun.c' line='880' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_Print'> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyErr_PrintEx' mangled-name='PyErr_PrintEx' filepath='Python/pythonrun.c' line='873' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_PrintEx'> - <parameter type-id='type-id-8' name='set_sys_last_vars' filepath='Python/pythonrun.c' line='873' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_PyErr_Print' mangled-name='_PyErr_Print' filepath='Python/pythonrun.c' line='867' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyErr_Print'> - <parameter type-id='type-id-10' name='tstate' filepath='Objects/object.c' line='2291' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_Py_HandleSystemExit' mangled-name='_Py_HandleSystemExit' filepath='Python/pythonrun.c' line='696' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_HandleSystemExit'> - <parameter type-id='type-id-501' name='exitcode_p' filepath='Python/pythonrun.c' line='696' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyRun_SimpleStringFlags' mangled-name='PyRun_SimpleStringFlags' filepath='Python/pythonrun.c' line='480' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyRun_SimpleStringFlags'> - <parameter type-id='type-id-3' name='command' filepath='Python/pythonrun.c' line='480' column='1'/> - <parameter type-id='type-id-593' name='flags' filepath='Python/pythonrun.c' line='480' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyRun_SimpleFileExFlags' mangled-name='PyRun_SimpleFileExFlags' filepath='Python/pythonrun.c' line='466' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyRun_SimpleFileExFlags'> - <parameter type-id='type-id-473' name='fp' filepath='Python/pythonrun.c' line='466' column='1'/> - <parameter type-id='type-id-3' name='filename' filepath='Python/pythonrun.c' line='466' column='1'/> - <parameter type-id='type-id-8' name='closeit' filepath='Python/pythonrun.c' line='466' column='1'/> - <parameter type-id='type-id-593' name='flags' filepath='Python/pythonrun.c' line='467' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyRun_SimpleFileObject' mangled-name='_PyRun_SimpleFileObject' filepath='Python/pythonrun.c' line='383' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyRun_SimpleFileObject'> - <parameter type-id='type-id-473' name='fp' filepath='Python/pythonrun.c' line='383' column='1'/> - <parameter type-id='type-id-14' name='filename' filepath='Python/pythonrun.c' line='383' column='1'/> - <parameter type-id='type-id-8' name='closeit' filepath='Python/pythonrun.c' line='383' column='1'/> - <parameter type-id='type-id-593' name='flags' filepath='Python/pythonrun.c' line='384' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyRun_InteractiveOneFlags' mangled-name='PyRun_InteractiveOneFlags' filepath='Python/pythonrun.c' line='285' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyRun_InteractiveOneFlags'> - <parameter type-id='type-id-473' name='fp' filepath='Python/pythonrun.c' line='285' column='1'/> - <parameter type-id='type-id-3' name='filename_str' filepath='Python/pythonrun.c' line='285' column='1'/> - <parameter type-id='type-id-593' name='flags' filepath='Python/pythonrun.c' line='285' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyRun_InteractiveOneObject' mangled-name='PyRun_InteractiveOneObject' filepath='Python/pythonrun.c' line='272' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyRun_InteractiveOneObject'> - <parameter type-id='type-id-473' name='fp' filepath='Python/pythonrun.c' line='272' column='1'/> - <parameter type-id='type-id-14' name='filename' filepath='Python/pythonrun.c' line='272' column='1'/> - <parameter type-id='type-id-593' name='flags' filepath='Python/pythonrun.c' line='272' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyRun_InteractiveLoopFlags' mangled-name='PyRun_InteractiveLoopFlags' filepath='Python/pythonrun.c' line='168' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyRun_InteractiveLoopFlags'> - <parameter type-id='type-id-473' name='fp' filepath='Python/pythonrun.c' line='285' column='1'/> - <parameter type-id='type-id-3' name='filename_str' filepath='Python/pythonrun.c' line='285' column='1'/> - <parameter type-id='type-id-593' name='flags' filepath='Python/pythonrun.c' line='285' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyRun_InteractiveLoopObject' mangled-name='_PyRun_InteractiveLoopObject' filepath='Python/pythonrun.c' line='112' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyRun_InteractiveLoopObject'> - <parameter type-id='type-id-473' name='fp' filepath='Python/pythonrun.c' line='112' column='1'/> - <parameter type-id='type-id-14' name='filename' filepath='Python/pythonrun.c' line='112' column='1'/> - <parameter type-id='type-id-593' name='flags' filepath='Python/pythonrun.c' line='112' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyRun_AnyFileExFlags' mangled-name='PyRun_AnyFileExFlags' filepath='Python/pythonrun.c' line='91' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyRun_AnyFileExFlags'> - <parameter type-id='type-id-473' name='fp' filepath='Python/pythonrun.c' line='466' column='1'/> - <parameter type-id='type-id-3' name='filename' filepath='Python/pythonrun.c' line='466' column='1'/> - <parameter type-id='type-id-8' name='closeit' filepath='Python/pythonrun.c' line='466' column='1'/> - <parameter type-id='type-id-593' name='flags' filepath='Python/pythonrun.c' line='467' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyRun_AnyFileObject' mangled-name='_PyRun_AnyFileObject' filepath='Python/pythonrun.c' line='58' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyRun_AnyFileObject'> - <parameter type-id='type-id-473' name='fp' filepath='Python/pythonrun.c' line='58' column='1'/> - <parameter type-id='type-id-14' name='filename' filepath='Python/pythonrun.c' line='58' column='1'/> - <parameter type-id='type-id-8' name='closeit' filepath='Python/pythonrun.c' line='58' column='1'/> - <parameter type-id='type-id-593' name='flags' filepath='Python/pythonrun.c' line='59' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Python/pytime.c' comp-dir-path='/src' language='LANG_C99'> - <typedef-decl name='_PyTime_t' type-id='type-id-29' filepath='./Include/cpython/pytime.h' line='59' column='1' id='type-id-857'/> - <function-decl name='_PyDeadline_Get' mangled-name='_PyDeadline_Get' filepath='Python/pytime.c' line='1347' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyDeadline_Get'> - <parameter type-id='type-id-857' name='deadline' filepath='Python/pytime.c' line='1347' column='1'/> - <return type-id='type-id-857'/> - </function-decl> - <function-decl name='_PyDeadline_Init' mangled-name='_PyDeadline_Init' filepath='Python/pytime.c' line='1339' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyDeadline_Init'> - <parameter type-id='type-id-857' name='deadline' filepath='Python/pytime.c' line='1347' column='1'/> - <return type-id='type-id-857'/> - </function-decl> - <typedef-decl name='__time_t' type-id='type-id-53' filepath='/usr/include/x86_64-linux-gnu/bits/types.h' line='160' column='1' id='type-id-858'/> - <typedef-decl name='time_t' type-id='type-id-858' filepath='/usr/include/x86_64-linux-gnu/bits/types/time_t.h' line='7' column='1' id='type-id-859'/> - <class-decl name='tm' size-in-bits='448' is-struct='yes' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_tm.h' line='7' column='1' id='type-id-860'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='tm_sec' type-id='type-id-8' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_tm.h' line='9' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='32'> - <var-decl name='tm_min' type-id='type-id-8' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_tm.h' line='10' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='tm_hour' type-id='type-id-8' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_tm.h' line='11' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='96'> - <var-decl name='tm_mday' type-id='type-id-8' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_tm.h' line='12' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='tm_mon' type-id='type-id-8' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_tm.h' line='13' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='160'> - <var-decl name='tm_year' type-id='type-id-8' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_tm.h' line='14' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='tm_wday' type-id='type-id-8' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_tm.h' line='15' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='224'> - <var-decl name='tm_yday' type-id='type-id-8' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_tm.h' line='16' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='256'> - <var-decl name='tm_isdst' type-id='type-id-8' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_tm.h' line='17' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='320'> - <var-decl name='tm_gmtoff' type-id='type-id-53' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_tm.h' line='20' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='384'> - <var-decl name='tm_zone' type-id='type-id-3' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_tm.h' line='21' column='1'/> - </data-member> - </class-decl> - <pointer-type-def type-id='type-id-860' size-in-bits='64' id='type-id-861'/> - <function-decl name='_PyTime_gmtime' mangled-name='_PyTime_gmtime' filepath='Python/pytime.c' line='1311' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTime_gmtime'> - <parameter type-id='type-id-859' name='t' filepath='Python/pytime.c' line='1311' column='1'/> - <parameter type-id='type-id-861' name='tm' filepath='Python/pytime.c' line='1311' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyTime_localtime' mangled-name='_PyTime_localtime' filepath='Python/pytime.c' line='1272' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTime_localtime'> - <parameter type-id='type-id-859' name='t' filepath='Python/pytime.c' line='1311' column='1'/> - <parameter type-id='type-id-861' name='tm' filepath='Python/pytime.c' line='1311' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyTime_GetPerfCounter' mangled-name='_PyTime_GetPerfCounter' filepath='Python/pytime.c' line='1253' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTime_GetPerfCounter'> - <return type-id='type-id-857'/> - </function-decl> - <pointer-type-def type-id='type-id-857' size-in-bits='64' id='type-id-862'/> - <class-decl name='__anonymous_struct__' size-in-bits='192' is-struct='yes' is-anonymous='yes' naming-typedef-id='type-id-863' visibility='default' filepath='./Include/cpython/pytime.h' line='232' column='1' id='type-id-864'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='implementation' type-id='type-id-3' visibility='default' filepath='./Include/cpython/pytime.h' line='233' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='monotonic' type-id='type-id-8' visibility='default' filepath='./Include/cpython/pytime.h' line='234' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='96'> - <var-decl name='adjustable' type-id='type-id-8' visibility='default' filepath='./Include/cpython/pytime.h' line='235' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='resolution' type-id='type-id-391' visibility='default' filepath='./Include/cpython/pytime.h' line='236' column='1'/> - </data-member> - </class-decl> - <typedef-decl name='_Py_clock_info_t' type-id='type-id-864' filepath='./Include/cpython/pytime.h' line='237' column='1' id='type-id-863'/> - <pointer-type-def type-id='type-id-863' size-in-bits='64' id='type-id-865'/> - <function-decl name='_PyTime_GetPerfCounterWithInfo' mangled-name='_PyTime_GetPerfCounterWithInfo' filepath='Python/pytime.c' line='1242' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTime_GetPerfCounterWithInfo'> - <parameter type-id='type-id-862' name='t' filepath='Python/pytime.c' line='1242' column='1'/> - <parameter type-id='type-id-865' name='info' filepath='Python/pytime.c' line='1242' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyTime_GetMonotonicClockWithInfo' mangled-name='_PyTime_GetMonotonicClockWithInfo' filepath='Python/pytime.c' line='1161' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTime_GetMonotonicClockWithInfo'> - <parameter type-id='type-id-862' name='t' filepath='Python/pytime.c' line='1242' column='1'/> - <parameter type-id='type-id-865' name='info' filepath='Python/pytime.c' line='1242' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyTime_GetMonotonicClock' mangled-name='_PyTime_GetMonotonicClock' filepath='Python/pytime.c' line='1148' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTime_GetMonotonicClock'> - <return type-id='type-id-857'/> - </function-decl> - <function-decl name='_PyTime_GetSystemClockWithInfo' mangled-name='_PyTime_GetSystemClockWithInfo' filepath='Python/pytime.c' line='964' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTime_GetSystemClockWithInfo'> - <parameter type-id='type-id-862' name='t' filepath='Python/pytime.c' line='1242' column='1'/> - <parameter type-id='type-id-865' name='info' filepath='Python/pytime.c' line='1242' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyTime_GetSystemClock' mangled-name='_PyTime_GetSystemClock' filepath='Python/pytime.c' line='951' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTime_GetSystemClock'> - <return type-id='type-id-857'/> - </function-decl> - <class-decl name='timespec' size-in-bits='128' is-struct='yes' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h' line='10' column='1' id='type-id-866'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='tv_sec' type-id='type-id-858' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h' line='12' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='tv_nsec' type-id='type-id-867' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h' line='16' column='1'/> - </data-member> - </class-decl> - <typedef-decl name='__syscall_slong_t' type-id='type-id-53' filepath='/usr/include/x86_64-linux-gnu/bits/types.h' line='196' column='1' id='type-id-867'/> - <pointer-type-def type-id='type-id-866' size-in-bits='64' id='type-id-868'/> - <function-decl name='_PyTime_AsTimespec' mangled-name='_PyTime_AsTimespec' filepath='Python/pytime.c' line='832' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTime_AsTimespec'> - <parameter type-id='type-id-857' name='t' filepath='Python/pytime.c' line='832' column='1'/> - <parameter type-id='type-id-868' name='ts' filepath='Python/pytime.c' line='832' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyTime_AsTimespec_clamp' mangled-name='_PyTime_AsTimespec_clamp' filepath='Python/pytime.c' line='826' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTime_AsTimespec_clamp'> - <parameter type-id='type-id-857' name='t' filepath='Python/pytime.c' line='826' column='1'/> - <parameter type-id='type-id-868' name='ts' filepath='Python/pytime.c' line='826' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <pointer-type-def type-id='type-id-859' size-in-bits='64' id='type-id-869'/> - <enum-decl name='__anonymous_enum__' is-anonymous='yes' filepath='./Include/cpython/pytime.h' line='66' column='1' id='type-id-870'> - <underlying-type type-id='type-id-126'/> - <enumerator name='_PyTime_ROUND_FLOOR' value='0'/> - <enumerator name='_PyTime_ROUND_CEILING' value='1'/> - <enumerator name='_PyTime_ROUND_HALF_EVEN' value='2'/> - <enumerator name='_PyTime_ROUND_UP' value='3'/> - <enumerator name='_PyTime_ROUND_TIMEOUT' value='3'/> - </enum-decl> - <typedef-decl name='_PyTime_round_t' type-id='type-id-870' filepath='./Include/cpython/pytime.h' line='86' column='1' id='type-id-871'/> - <function-decl name='_PyTime_AsTimevalTime_t' mangled-name='_PyTime_AsTimevalTime_t' filepath='Python/pytime.c' line='787' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTime_AsTimevalTime_t'> - <parameter type-id='type-id-857' name='t' filepath='Python/pytime.c' line='787' column='1'/> - <parameter type-id='type-id-869' name='p_secs' filepath='Python/pytime.c' line='787' column='1'/> - <parameter type-id='type-id-501' name='us' filepath='Python/pytime.c' line='787' column='1'/> - <parameter type-id='type-id-871' name='round' filepath='Python/pytime.c' line='788' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <class-decl name='timeval' size-in-bits='128' is-struct='yes' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h' line='8' column='1' id='type-id-872'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='tv_sec' type-id='type-id-858' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h' line='10' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='tv_usec' type-id='type-id-873' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h' line='11' column='1'/> - </data-member> - </class-decl> - <typedef-decl name='__suseconds_t' type-id='type-id-53' filepath='/usr/include/x86_64-linux-gnu/bits/types.h' line='162' column='1' id='type-id-873'/> - <pointer-type-def type-id='type-id-872' size-in-bits='64' id='type-id-874'/> - <function-decl name='_PyTime_AsTimeval_clamp' mangled-name='_PyTime_AsTimeval_clamp' filepath='Python/pytime.c' line='780' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTime_AsTimeval_clamp'> - <parameter type-id='type-id-857' name='t' filepath='Python/pytime.c' line='780' column='1'/> - <parameter type-id='type-id-874' name='tv' filepath='Python/pytime.c' line='780' column='1'/> - <parameter type-id='type-id-871' name='round' filepath='Python/pytime.c' line='780' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_PyTime_AsTimeval' mangled-name='_PyTime_AsTimeval' filepath='Python/pytime.c' line='773' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTime_AsTimeval'> - <parameter type-id='type-id-857' name='t' filepath='Python/pytime.c' line='773' column='1'/> - <parameter type-id='type-id-874' name='tv' filepath='Python/pytime.c' line='773' column='1'/> - <parameter type-id='type-id-871' name='round' filepath='Python/pytime.c' line='773' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyTime_AsMilliseconds' mangled-name='_PyTime_AsMilliseconds' filepath='Python/pytime.c' line='723' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTime_AsMilliseconds'> - <parameter type-id='type-id-857' name='t' filepath='Python/pytime.c' line='723' column='1'/> - <parameter type-id='type-id-871' name='round' filepath='Python/pytime.c' line='723' column='1'/> - <return type-id='type-id-857'/> - </function-decl> - <function-decl name='_PyTime_AsMicroseconds' mangled-name='_PyTime_AsMicroseconds' filepath='Python/pytime.c' line='715' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTime_AsMicroseconds'> - <parameter type-id='type-id-857' name='t' filepath='Python/pytime.c' line='723' column='1'/> - <parameter type-id='type-id-871' name='round' filepath='Python/pytime.c' line='723' column='1'/> - <return type-id='type-id-857'/> - </function-decl> - <function-decl name='_PyTime_AsNanoseconds' mangled-name='_PyTime_AsNanoseconds' filepath='Python/pytime.c' line='698' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTime_AsNanoseconds'> - <parameter type-id='type-id-857' name='t' filepath='Python/pytime.c' line='698' column='1'/> - <return type-id='type-id-857'/> - </function-decl> - <function-decl name='_PyTime_AsNanosecondsObject' mangled-name='_PyTime_AsNanosecondsObject' filepath='Python/pytime.c' line='593' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTime_AsNanosecondsObject'> - <parameter type-id='type-id-857' name='t' filepath='Python/pytime.c' line='593' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyTime_AsSecondsDouble' mangled-name='_PyTime_AsSecondsDouble' filepath='Python/pytime.c' line='572' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTime_AsSecondsDouble'> - <parameter type-id='type-id-857' name='t' filepath='Python/pytime.c' line='572' column='1'/> - <return type-id='type-id-391'/> - </function-decl> - <function-decl name='_PyTime_FromMillisecondsObject' mangled-name='_PyTime_FromMillisecondsObject' filepath='Python/pytime.c' line='565' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTime_FromMillisecondsObject'> - <parameter type-id='type-id-862' name='tp' filepath='Python/pytime.c' line='565' column='1'/> - <parameter type-id='type-id-14' name='obj' filepath='Python/pytime.c' line='565' column='1'/> - <parameter type-id='type-id-871' name='round' filepath='Python/pytime.c' line='565' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyTime_FromSecondsObject' mangled-name='_PyTime_FromSecondsObject' filepath='Python/pytime.c' line='558' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTime_FromSecondsObject'> - <parameter type-id='type-id-862' name='tp' filepath='Python/pytime.c' line='565' column='1'/> - <parameter type-id='type-id-14' name='obj' filepath='Python/pytime.c' line='565' column='1'/> - <parameter type-id='type-id-871' name='round' filepath='Python/pytime.c' line='565' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyTime_FromTimeval' mangled-name='_PyTime_FromTimeval' filepath='Python/pytime.c' line='491' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTime_FromTimeval'> - <parameter type-id='type-id-862' name='tp' filepath='Python/pytime.c' line='491' column='1'/> - <parameter type-id='type-id-874' name='tv' filepath='Python/pytime.c' line='491' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyTime_FromTimespec' mangled-name='_PyTime_FromTimespec' filepath='Python/pytime.c' line='460' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTime_FromTimespec'> - <parameter type-id='type-id-862' name='tp' filepath='Python/pytime.c' line='460' column='1'/> - <parameter type-id='type-id-868' name='ts' filepath='Python/pytime.c' line='460' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyTime_FromNanosecondsObject' mangled-name='_PyTime_FromNanosecondsObject' filepath='Python/pytime.c' line='410' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTime_FromNanosecondsObject'> - <parameter type-id='type-id-862' name='tp' filepath='Python/pytime.c' line='410' column='1'/> - <parameter type-id='type-id-14' name='obj' filepath='Python/pytime.c' line='410' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyTime_FromNanoseconds' mangled-name='_PyTime_FromNanoseconds' filepath='Python/pytime.c' line='403' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTime_FromNanoseconds'> - <parameter type-id='type-id-857' name='t' filepath='Python/pytime.c' line='698' column='1'/> - <return type-id='type-id-857'/> - </function-decl> - <function-decl name='_PyTime_FromSeconds' mangled-name='_PyTime_FromSeconds' filepath='Python/pytime.c' line='386' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTime_FromSeconds'> - <parameter type-id='type-id-8' name='seconds' filepath='Python/pytime.c' line='386' column='1'/> - <return type-id='type-id-857'/> - </function-decl> - <pointer-type-def type-id='type-id-53' size-in-bits='64' id='type-id-875'/> - <function-decl name='_PyTime_ObjectToTimeval' mangled-name='_PyTime_ObjectToTimeval' filepath='Python/pytime.c' line='378' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTime_ObjectToTimeval'> - <parameter type-id='type-id-14' name='obj' filepath='Python/pytime.c' line='378' column='1'/> - <parameter type-id='type-id-869' name='sec' filepath='Python/pytime.c' line='378' column='1'/> - <parameter type-id='type-id-875' name='usec' filepath='Python/pytime.c' line='378' column='1'/> - <parameter type-id='type-id-871' name='round' filepath='Python/pytime.c' line='379' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyTime_ObjectToTimespec' mangled-name='_PyTime_ObjectToTimespec' filepath='Python/pytime.c' line='370' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTime_ObjectToTimespec'> - <parameter type-id='type-id-14' name='obj' filepath='Python/pytime.c' line='378' column='1'/> - <parameter type-id='type-id-869' name='sec' filepath='Python/pytime.c' line='378' column='1'/> - <parameter type-id='type-id-875' name='usec' filepath='Python/pytime.c' line='378' column='1'/> - <parameter type-id='type-id-871' name='round' filepath='Python/pytime.c' line='379' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyTime_ObjectToTime_t' mangled-name='_PyTime_ObjectToTime_t' filepath='Python/pytime.c' line='336' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTime_ObjectToTime_t'> - <parameter type-id='type-id-14' name='obj' filepath='Python/pytime.c' line='336' column='1'/> - <parameter type-id='type-id-869' name='sec' filepath='Python/pytime.c' line='336' column='1'/> - <parameter type-id='type-id-871' name='round' filepath='Python/pytime.c' line='336' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyLong_FromTime_t' mangled-name='_PyLong_FromTime_t' filepath='Python/pytime.c' line='182' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyLong_FromTime_t'> - <parameter type-id='type-id-859' name='t' filepath='Python/pytime.c' line='182' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyLong_AsTime_t' mangled-name='_PyLong_AsTime_t' filepath='Python/pytime.c' line='162' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyLong_AsTime_t'> - <parameter type-id='type-id-14' name='obj' filepath='Python/pytime.c' line='162' column='1'/> - <return type-id='type-id-859'/> - </function-decl> - <function-decl name='_PyTime_MulDiv' mangled-name='_PyTime_MulDiv' filepath='Python/pytime.c' line='145' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTime_MulDiv'> - <parameter type-id='type-id-857' name='ticks' filepath='Python/pytime.c' line='145' column='1'/> - <parameter type-id='type-id-857' name='mul' filepath='Python/pytime.c' line='145' column='1'/> - <parameter type-id='type-id-857' name='div' filepath='Python/pytime.c' line='145' column='1'/> - <return type-id='type-id-857'/> - </function-decl> - <function-decl name='_PyTime_Add' mangled-name='_PyTime_Add' filepath='Python/pytime.c' line='97' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTime_Add'> - <parameter type-id='type-id-857' name='t1' filepath='Python/pytime.c' line='97' column='1'/> - <parameter type-id='type-id-857' name='t2' filepath='Python/pytime.c' line='97' column='1'/> - <return type-id='type-id-857'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Python/bootstrap_hash.c' comp-dir-path='/src' language='LANG_C99'> - <function-decl name='_PyOS_URandomNonblock' mangled-name='_PyOS_URandomNonblock' filepath='Python/bootstrap_hash.c' line='541' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyOS_URandomNonblock'> - <parameter type-id='type-id-18' name='buffer' filepath='Python/bootstrap_hash.c' line='541' column='1'/> - <parameter type-id='type-id-36' name='size' filepath='Python/bootstrap_hash.c' line='541' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyOS_URandom' mangled-name='_PyOS_URandom' filepath='Python/bootstrap_hash.c' line='527' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyOS_URandom'> - <parameter type-id='type-id-18' name='buffer' filepath='Python/bootstrap_hash.c' line='541' column='1'/> - <parameter type-id='type-id-36' name='size' filepath='Python/bootstrap_hash.c' line='541' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Python/specialize.c' comp-dir-path='/src' language='LANG_C99'> - - <array-type-def dimensions='1' type-id='type-id-285' size-in-bits='2048' id='type-id-876'> - <subrange length='256' type-id='type-id-16' id='type-id-264'/> - - </array-type-def> - <var-decl name='_PyOpcode_Adaptive' type-id='type-id-876' visibility='default' filepath='./Include/internal/pycore_code.h' line='113' column='1'/> - <var-decl name='_Py_QuickenedCount' type-id='type-id-36' visibility='default' filepath='./Include/internal/pycore_code.h' line='115' column='1'/> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Python/structmember.c' comp-dir-path='/src' language='LANG_C99'> - <function-decl name='PyMember_SetOne' mangled-name='PyMember_SetOne' filepath='Python/structmember.c' line='105' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMember_SetOne'> - <parameter type-id='type-id-115' name='addr' filepath='Python/structmember.c' line='105' column='1'/> - <parameter type-id='type-id-97' name='l' filepath='Python/structmember.c' line='105' column='1'/> - <parameter type-id='type-id-14' name='v' filepath='Python/structmember.c' line='105' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyMember_GetOne' mangled-name='PyMember_GetOne' filepath='Python/structmember.c' line='8' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMember_GetOne'> - <parameter type-id='type-id-3' name='obj_addr' filepath='Python/structmember.c' line='8' column='1'/> - <parameter type-id='type-id-97' name='l' filepath='Python/structmember.c' line='8' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Python/symtable.c' comp-dir-path='/src' language='LANG_C99'> - <var-decl name='PySTEntry_Type' type-id='type-id-112' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='78' column='1'/> - <class-decl name='_symtable_entry' size-in-bits='960' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='44' column='1' id='type-id-877'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='ob_base' type-id='type-id-108' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='45' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='ste_id' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='46' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='ste_symbols' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='47' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='256'> - <var-decl name='ste_name' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='48' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='320'> - <var-decl name='ste_varnames' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='49' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='384'> - <var-decl name='ste_children' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='50' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='448'> - <var-decl name='ste_directives' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='51' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='512'> - <var-decl name='ste_type' type-id='type-id-878' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='52' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='544'> - <var-decl name='ste_nested' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='53' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='31'> - <var-decl name='ste_free' type-id='type-id-105' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='54' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='30'> - <var-decl name='ste_child_free' type-id='type-id-105' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='55' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='29'> - <var-decl name='ste_generator' type-id='type-id-105' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='57' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='28'> - <var-decl name='ste_coroutine' type-id='type-id-105' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='58' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='608'> - <var-decl name='ste_comprehension' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='59' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='31'> - <var-decl name='ste_varargs' type-id='type-id-105' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='60' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='30'> - <var-decl name='ste_varkeywords' type-id='type-id-105' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='61' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='29'> - <var-decl name='ste_returns_value' type-id='type-id-105' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='62' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='28'> - <var-decl name='ste_needs_class_closure' type-id='type-id-105' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='64' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='27'> - <var-decl name='ste_comp_iter_target' type-id='type-id-105' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='67' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='672'> - <var-decl name='ste_comp_iter_expr' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='68' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='704'> - <var-decl name='ste_lineno' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='69' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='736'> - <var-decl name='ste_col_offset' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='70' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='768'> - <var-decl name='ste_end_lineno' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='71' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='800'> - <var-decl name='ste_end_col_offset' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='72' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='832'> - <var-decl name='ste_opt_lineno' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='73' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='864'> - <var-decl name='ste_opt_col_offset' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='74' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='896'> - <var-decl name='ste_table' type-id='type-id-880' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='75' column='1'/> - </data-member> - </class-decl> - <enum-decl name='_block_type' filepath='./Include/internal/pycore_symtable.h' line='13' column='1' id='type-id-881'> - <underlying-type type-id='type-id-126'/> - <enumerator name='FunctionBlock' value='0'/> - <enumerator name='ClassBlock' value='1'/> - <enumerator name='ModuleBlock' value='2'/> - <enumerator name='AnnotationBlock' value='3'/> - </enum-decl> - <typedef-decl name='_Py_block_ty' type-id='type-id-881' filepath='./Include/internal/pycore_symtable.h' line='14' column='1' id='type-id-878'/> - <enum-decl name='_comprehension_type' filepath='./Include/internal/pycore_symtable.h' line='16' column='1' id='type-id-882'> - <underlying-type type-id='type-id-126'/> - <enumerator name='NoComprehension' value='0'/> - <enumerator name='ListComprehension' value='1'/> - <enumerator name='DictComprehension' value='2'/> - <enumerator name='SetComprehension' value='3'/> - <enumerator name='GeneratorExpression' value='4'/> - </enum-decl> - <typedef-decl name='_Py_comprehension_ty' type-id='type-id-882' filepath='./Include/internal/pycore_symtable.h' line='21' column='1' id='type-id-879'/> - <class-decl name='symtable' size-in-bits='640' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='25' column='1' id='type-id-883'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='st_filename' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='26' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='st_cur' type-id='type-id-884' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='28' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='st_top' type-id='type-id-884' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='29' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='st_blocks' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='30' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='256'> - <var-decl name='st_stack' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='32' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='320'> - <var-decl name='st_global' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='33' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='384'> - <var-decl name='st_nblocks' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='34' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='448'> - <var-decl name='st_private' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='37' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='512'> - <var-decl name='st_future' type-id='type-id-885' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='38' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='576'> - <var-decl name='recursion_depth' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='40' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='608'> - <var-decl name='recursion_limit' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='41' column='1'/> - </data-member> - </class-decl> - <pointer-type-def type-id='type-id-877' size-in-bits='64' id='type-id-884'/> - <class-decl name='__anonymous_struct__' size-in-bits='64' is-struct='yes' is-anonymous='yes' naming-typedef-id='type-id-886' visibility='default' filepath='./Include/cpython/compile.h' line='36' column='1' id='type-id-887'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='ff_features' type-id='type-id-8' visibility='default' filepath='./Include/cpython/compile.h' line='37' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='32'> - <var-decl name='ff_lineno' type-id='type-id-8' visibility='default' filepath='./Include/cpython/compile.h' line='38' column='1'/> - </data-member> - </class-decl> - <typedef-decl name='PyFutureFeatures' type-id='type-id-887' filepath='./Include/cpython/compile.h' line='39' column='1' id='type-id-886'/> - <pointer-type-def type-id='type-id-886' size-in-bits='64' id='type-id-885'/> - <pointer-type-def type-id='type-id-883' size-in-bits='64' id='type-id-880'/> - <typedef-decl name='PySTEntryObject' type-id='type-id-877' filepath='./Include/internal/pycore_symtable.h' line='76' column='1' id='type-id-888'/> - <pointer-type-def type-id='type-id-888' size-in-bits='64' id='type-id-889'/> - <function-decl name='PySymtable_Lookup' mangled-name='PySymtable_Lookup' filepath='Python/symtable.c' line='373' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySymtable_Lookup'> - <parameter type-id='type-id-880' name='st' filepath='Python/symtable.c' line='373' column='1'/> - <parameter type-id='type-id-18' name='key' filepath='Python/symtable.c' line='373' column='1'/> - <return type-id='type-id-889'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='./Python/sysmodule.c' comp-dir-path='/src' language='LANG_C99'> - <function-decl name='PySys_FormatStderr' mangled-name='PySys_FormatStderr' filepath='./Python/sysmodule.c' line='3462' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySys_FormatStderr'> - <parameter type-id='type-id-3' name='format' filepath='./Python/sysmodule.c' line='3462' column='1'/> - <parameter is-variadic='yes'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PySys_FormatStdout' mangled-name='PySys_FormatStdout' filepath='./Python/sysmodule.c' line='3452' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySys_FormatStdout'> - <parameter type-id='type-id-3' name='format' filepath='./Python/sysmodule.c' line='3462' column='1'/> - <parameter is-variadic='yes'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PySys_WriteStderr' mangled-name='PySys_WriteStderr' filepath='./Python/sysmodule.c' line='3419' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySys_WriteStderr'> - <parameter type-id='type-id-3' name='format' filepath='./Python/sysmodule.c' line='3462' column='1'/> - <parameter is-variadic='yes'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PySys_WriteStdout' mangled-name='PySys_WriteStdout' filepath='./Python/sysmodule.c' line='3409' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySys_WriteStdout'> - <parameter type-id='type-id-3' name='format' filepath='./Python/sysmodule.c' line='3462' column='1'/> - <parameter is-variadic='yes'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PySys_SetArgv' mangled-name='PySys_SetArgv' filepath='./Python/sysmodule.c' line='3313' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySys_SetArgv'> - <parameter type-id='type-id-8' name='argc' filepath='./Python/sysmodule.c' line='3313' column='1'/> - <parameter type-id='type-id-374' name='argv' filepath='./Python/sysmodule.c' line='3313' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PySys_SetArgvEx' mangled-name='PySys_SetArgvEx' filepath='./Python/sysmodule.c' line='3269' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySys_SetArgvEx'> - <parameter type-id='type-id-8' name='argc' filepath='./Python/sysmodule.c' line='3269' column='1'/> - <parameter type-id='type-id-374' name='argv' filepath='./Python/sysmodule.c' line='3269' column='1'/> - <parameter type-id='type-id-8' name='updatepath' filepath='./Python/sysmodule.c' line='3269' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PySys_SetPath' mangled-name='PySys_SetPath' filepath='./Python/sysmodule.c' line='3237' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySys_SetPath'> - <parameter type-id='type-id-545' name='program_full_path' filepath='Python/pathconfig.c' line='297' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PySys_GetXOptions' mangled-name='PySys_GetXOptions' filepath='./Python/sysmodule.c' line='2361' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySys_GetXOptions'> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PySys_AddXOption' mangled-name='PySys_AddXOption' filepath='./Python/sysmodule.c' line='2347' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySys_AddXOption'> - <parameter type-id='type-id-545' name='s' filepath='./Python/sysmodule.c' line='2347' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PySys_HasWarnOptions' mangled-name='PySys_HasWarnOptions' filepath='./Python/sysmodule.c' line='2273' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySys_HasWarnOptions'> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PySys_AddWarnOption' mangled-name='PySys_AddWarnOption' filepath='./Python/sysmodule.c' line='2254' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySys_AddWarnOption'> - <parameter type-id='type-id-545' name='path' filepath='Python/pathconfig.c' line='215' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PySys_AddWarnOptionUnicode' mangled-name='PySys_AddWarnOptionUnicode' filepath='./Python/sysmodule.c' line='2242' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySys_AddWarnOptionUnicode'> - <parameter type-id='type-id-14' name='m' filepath='Objects/moduleobject.c' line='578' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PySys_ResetWarnOptions' mangled-name='PySys_ResetWarnOptions' filepath='./Python/sysmodule.c' line='2214' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySys_ResetWarnOptions'> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_PySys_GetSizeOf' mangled-name='_PySys_GetSizeOf' filepath='./Python/sysmodule.c' line='1624' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PySys_GetSizeOf'> - <parameter type-id='type-id-14' name='vv' filepath='Objects/longobject.c' line='664' column='1'/> - <return type-id='type-id-54'/> - </function-decl> - <function-decl name='PySys_AddAuditHook' mangled-name='PySys_AddAuditHook' filepath='./Python/sysmodule.c' line='360' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySys_AddAuditHook'> - <parameter type-id='type-id-242' name='hook' filepath='./Python/sysmodule.c' line='360' column='1'/> - <parameter type-id='type-id-18' name='userData' filepath='./Python/sysmodule.c' line='360' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PySys_Audit' mangled-name='PySys_Audit' filepath='./Python/sysmodule.c' line='306' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySys_Audit'> - <parameter type-id='type-id-3' name='event' filepath='./Python/sysmodule.c' line='306' column='1'/> - <parameter type-id='type-id-3' name='argFormat' filepath='./Python/sysmodule.c' line='306' column='1'/> - <parameter is-variadic='yes'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PySys_SetObject' mangled-name='PySys_SetObject' filepath='./Python/sysmodule.c' line='140' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySys_SetObject'> - <parameter type-id='type-id-3' name='name' filepath='Python/codecs.c' line='622' column='1'/> - <parameter type-id='type-id-14' name='error' filepath='Python/codecs.c' line='622' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PySys_GetObject' mangled-name='PySys_GetObject' filepath='./Python/sysmodule.c' line='89' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySys_GetObject'> - <parameter type-id='type-id-3' name='name' filepath='./Python/sysmodule.c' line='89' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PySys_GetAttr' mangled-name='_PySys_GetAttr' filepath='./Python/sysmodule.c' line='63' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PySys_GetAttr'> - <parameter type-id='type-id-10' name='tstate' filepath='./Python/sysmodule.c' line='63' column='1'/> - <parameter type-id='type-id-14' name='name' filepath='./Python/sysmodule.c' line='63' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Python/thread.c' comp-dir-path='/src' language='LANG_C99'> - <function-decl name='PyThread_GetInfo' mangled-name='PyThread_GetInfo' filepath='Python/thread.c' line='185' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThread_GetInfo'> - <return type-id='type-id-14'/> - </function-decl> - <pointer-type-def type-id='type-id-237' size-in-bits='64' id='type-id-890'/> - <function-decl name='PyThread_tss_is_created' mangled-name='PyThread_tss_is_created' filepath='Python/thread.c' line='156' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThread_tss_is_created'> - <parameter type-id='type-id-890' name='key' filepath='Python/thread.c' line='156' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyThread_tss_free' mangled-name='PyThread_tss_free' filepath='Python/thread.c' line='147' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThread_tss_free'> - <parameter type-id='type-id-890' name='key' filepath='Python/thread.c' line='147' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyThread_tss_alloc' mangled-name='PyThread_tss_alloc' filepath='Python/thread.c' line='136' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThread_tss_alloc'> - <return type-id='type-id-890'/> - </function-decl> - <function-decl name='PyThread_set_stacksize' mangled-name='PyThread_set_stacksize' filepath='Python/thread.c' line='120' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThread_set_stacksize'> - <parameter type-id='type-id-54' name='size' filepath='Python/thread.c' line='120' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyThread_get_stacksize' mangled-name='PyThread_get_stacksize' filepath='Python/thread.c' line='109' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThread_get_stacksize'> - <return type-id='type-id-54'/> - </function-decl> - <function-decl name='PyThread_tss_get' mangled-name='PyThread_tss_get' filepath='Python/thread_pthread.h' line='922' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThread_tss_get'> - <parameter type-id='type-id-890' name='key' filepath='Python/thread_pthread.h' line='922' column='1'/> - <return type-id='type-id-18'/> - </function-decl> - <function-decl name='PyThread_tss_set' mangled-name='PyThread_tss_set' filepath='Python/thread_pthread.h' line='914' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThread_tss_set'> - <parameter type-id='type-id-890' name='key' filepath='Python/thread_pthread.h' line='914' column='1'/> - <parameter type-id='type-id-18' name='value' filepath='Python/thread_pthread.h' line='914' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyThread_tss_delete' mangled-name='PyThread_tss_delete' filepath='Python/thread_pthread.h' line='900' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThread_tss_delete'> - <parameter type-id='type-id-890' name='key' filepath='Python/thread.c' line='147' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyThread_tss_create' mangled-name='PyThread_tss_create' filepath='Python/thread_pthread.h' line='883' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThread_tss_create'> - <parameter type-id='type-id-890' name='key' filepath='Python/thread_pthread.h' line='883' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyThread_ReInitTLS' mangled-name='PyThread_ReInitTLS' filepath='Python/thread_pthread.h' line='872' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThread_ReInitTLS'> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyThread_get_key_value' mangled-name='PyThread_get_key_value' filepath='Python/thread_pthread.h' line='861' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThread_get_key_value'> - <parameter type-id='type-id-8' name='key' filepath='Python/thread_pthread.h' line='861' column='1'/> - <return type-id='type-id-18'/> - </function-decl> - <function-decl name='PyThread_set_key_value' mangled-name='PyThread_set_key_value' filepath='Python/thread_pthread.h' line='850' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThread_set_key_value'> - <parameter type-id='type-id-8' name='key' filepath='Python/thread_pthread.h' line='850' column='1'/> - <parameter type-id='type-id-18' name='value' filepath='Python/thread_pthread.h' line='850' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyThread_delete_key_value' mangled-name='PyThread_delete_key_value' filepath='Python/thread_pthread.h' line='842' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThread_delete_key_value'> - <parameter type-id='type-id-8' name='sts' filepath='Python/pylifecycle.c' line='2936' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyThread_delete_key' mangled-name='PyThread_delete_key' filepath='Python/thread_pthread.h' line='834' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThread_delete_key'> - <parameter type-id='type-id-8' name='sts' filepath='Python/pylifecycle.c' line='2936' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyThread_create_key' mangled-name='PyThread_create_key' filepath='Python/thread_pthread.h' line='814' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThread_create_key'> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyThread_acquire_lock' mangled-name='PyThread_acquire_lock' filepath='Python/thread_pthread.h' line='747' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThread_acquire_lock'> - <parameter type-id='type-id-30' name='lock' filepath='Python/thread_pthread.h' line='747' column='1'/> - <parameter type-id='type-id-8' name='waitflag' filepath='Python/thread_pthread.h' line='747' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <pointer-type-def type-id='type-id-30' size-in-bits='64' id='type-id-891'/> - <function-decl name='_PyThread_at_fork_reinit' mangled-name='_PyThread_at_fork_reinit' filepath='Python/thread_pthread.h' line='727' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyThread_at_fork_reinit'> - <parameter type-id='type-id-891' name='lock' filepath='Python/thread_pthread.h' line='727' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyThread_release_lock' mangled-name='PyThread_release_lock' filepath='Python/thread_pthread.h' line='553' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThread_release_lock'> - <parameter type-id='type-id-30' name='lock' filepath='Python/thread_pthread.h' line='553' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <enum-decl name='PyLockStatus' filepath='./Include/pythread.h' line='12' column='1' id='type-id-892'> - <underlying-type type-id='type-id-126'/> - <enumerator name='PY_LOCK_FAILURE' value='0'/> - <enumerator name='PY_LOCK_ACQUIRED' value='1'/> - <enumerator name='PY_LOCK_INTR' value='2'/> - </enum-decl> - <typedef-decl name='PyLockStatus' type-id='type-id-892' filepath='./Include/pythread.h' line='16' column='1' id='type-id-893'/> - <function-decl name='PyThread_acquire_lock_timed' mangled-name='PyThread_acquire_lock_timed' filepath='Python/thread_pthread.h' line='430' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThread_acquire_lock_timed'> - <parameter type-id='type-id-30' name='lock' filepath='Python/thread_pthread.h' line='430' column='1'/> - <parameter type-id='type-id-222' name='microseconds' filepath='Python/thread_pthread.h' line='430' column='1'/> - <parameter type-id='type-id-8' name='intr_flag' filepath='Python/thread_pthread.h' line='431' column='1'/> - <return type-id='type-id-893'/> - </function-decl> - <function-decl name='PyThread_free_lock' mangled-name='PyThread_free_lock' filepath='Python/thread_pthread.h' line='400' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThread_free_lock'> - <parameter type-id='type-id-30' name='lock' filepath='Python/thread_pthread.h' line='553' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyThread_allocate_lock' mangled-name='PyThread_allocate_lock' filepath='Python/thread_pthread.h' line='374' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThread_allocate_lock'> - <return type-id='type-id-30'/> - </function-decl> - <function-decl name='PyThread_exit_thread' mangled-name='PyThread_exit_thread' filepath='Python/thread_pthread.h' line='359' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThread_exit_thread'> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyThread_get_thread_native_id' mangled-name='PyThread_get_thread_native_id' filepath='Python/thread_pthread.h' line='331' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThread_get_thread_native_id'> - <return type-id='type-id-16'/> - </function-decl> - <function-decl name='PyThread_get_thread_ident' mangled-name='PyThread_get_thread_ident' filepath='Python/thread_pthread.h' line='320' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThread_get_thread_ident'> - <return type-id='type-id-16'/> - </function-decl> - <function-decl name='PyThread_start_new_thread' mangled-name='PyThread_start_new_thread' filepath='Python/thread_pthread.h' line='244' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThread_start_new_thread'> - <parameter type-id='type-id-17' name='func' filepath='Python/thread_pthread.h' line='244' column='1'/> - <parameter type-id='type-id-18' name='arg' filepath='Python/thread_pthread.h' line='244' column='1'/> - <return type-id='type-id-16'/> - </function-decl> - <function-decl name='PyThread_init_thread' mangled-name='PyThread_init_thread' filepath='Python/thread.c' line='58' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThread_init_thread'> - <return type-id='type-id-70'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Python/traceback.c' comp-dir-path='/src' language='LANG_C99'> - <var-decl name='PyTraceBack_Type' type-id='type-id-112' mangled-name='PyTraceBack_Type' visibility='default' filepath='./Include/traceback.h' line='13' column='1' elf-symbol-id='PyTraceBack_Type'/> - <function-decl name='_Py_DumpTracebackThreads' mangled-name='_Py_DumpTracebackThreads' filepath='Python/traceback.c' line='1283' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_DumpTracebackThreads'> - <parameter type-id='type-id-8' name='fd' filepath='Python/traceback.c' line='1283' column='1'/> - <parameter type-id='type-id-11' name='interp' filepath='Python/traceback.c' line='1283' column='1'/> - <parameter type-id='type-id-10' name='current_tstate' filepath='Python/traceback.c' line='1284' column='1'/> - <return type-id='type-id-3'/> - </function-decl> - <function-decl name='_Py_DumpTraceback' mangled-name='_Py_DumpTraceback' filepath='Python/traceback.c' line='1253' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_DumpTraceback'> - <parameter type-id='type-id-8' name='fd' filepath='Python/traceback.c' line='1253' column='1'/> - <parameter type-id='type-id-10' name='tstate' filepath='Python/traceback.c' line='1253' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_Py_DumpASCII' mangled-name='_Py_DumpASCII' filepath='Python/traceback.c' line='1084' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_DumpASCII'> - <parameter type-id='type-id-8' name='fd' filepath='Python/traceback.c' line='1084' column='1'/> - <parameter type-id='type-id-14' name='text' filepath='Python/traceback.c' line='1084' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_Py_DumpHexadecimal' mangled-name='_Py_DumpHexadecimal' filepath='Python/traceback.c' line='1061' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_DumpHexadecimal'> - <parameter type-id='type-id-8' name='fd' filepath='Python/traceback.c' line='1061' column='1'/> - <parameter type-id='type-id-358' name='value' filepath='Python/traceback.c' line='1061' column='1'/> - <parameter type-id='type-id-36' name='width' filepath='Python/traceback.c' line='1061' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_Py_DumpDecimal' mangled-name='_Py_DumpDecimal' filepath='Python/traceback.c' line='1037' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_DumpDecimal'> - <parameter type-id='type-id-8' name='fd' filepath='Python/traceback.c' line='1037' column='1'/> - <parameter type-id='type-id-54' name='value' filepath='Python/traceback.c' line='1037' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyTraceBack_Print' mangled-name='PyTraceBack_Print' filepath='Python/traceback.c' line='1021' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyTraceBack_Print'> - <parameter type-id='type-id-14' name='op' filepath='Objects/dictobject.c' line='3691' column='1'/> - <parameter type-id='type-id-14' name='key' filepath='Objects/dictobject.c' line='3691' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyTraceBack_Print_Indented' mangled-name='_PyTraceBack_Print_Indented' filepath='Python/traceback.c' line='981' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTraceBack_Print_Indented'> - <parameter type-id='type-id-14' name='v' filepath='Python/traceback.c' line='981' column='1'/> - <parameter type-id='type-id-8' name='indent' filepath='Python/traceback.c' line='981' column='1'/> - <parameter type-id='type-id-3' name='margin' filepath='Python/traceback.c' line='981' column='1'/> - <parameter type-id='type-id-3' name='header_margin' filepath='Python/traceback.c' line='982' column='1'/> - <parameter type-id='type-id-3' name='header' filepath='Python/traceback.c' line='982' column='1'/> - <parameter type-id='type-id-14' name='f' filepath='Python/traceback.c' line='982' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_Py_DisplaySourceLine' mangled-name='_Py_DisplaySourceLine' filepath='Python/traceback.c' line='578' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_DisplaySourceLine'> - <parameter type-id='type-id-14' name='f' filepath='Python/traceback.c' line='578' column='1'/> - <parameter type-id='type-id-14' name='filename' filepath='Python/traceback.c' line='578' column='1'/> - <parameter type-id='type-id-8' name='lineno' filepath='Python/traceback.c' line='578' column='1'/> - <parameter type-id='type-id-8' name='indent' filepath='Python/traceback.c' line='578' column='1'/> - <parameter type-id='type-id-501' name='truncation' filepath='Python/traceback.c' line='579' column='1'/> - <parameter type-id='type-id-22' name='line' filepath='Python/traceback.c' line='579' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_Py_WriteIndentedMargin' mangled-name='_Py_WriteIndentedMargin' filepath='Python/traceback.c' line='406' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_WriteIndentedMargin'> - <parameter type-id='type-id-8' name='indent' filepath='Python/traceback.c' line='406' column='1'/> - <parameter type-id='type-id-3' name='margin' filepath='Python/traceback.c' line='406' column='1'/> - <parameter type-id='type-id-14' name='f' filepath='Python/traceback.c' line='406' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_Py_WriteIndent' mangled-name='_Py_WriteIndent' filepath='Python/traceback.c' line='386' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_WriteIndent'> - <parameter type-id='type-id-8' name='indent' filepath='Python/traceback.c' line='386' column='1'/> - <parameter type-id='type-id-14' name='f' filepath='Python/traceback.c' line='386' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyTraceback_Add' mangled-name='_PyTraceback_Add' filepath='Python/traceback.c' line='264' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTraceback_Add'> - <parameter type-id='type-id-3' name='funcname' filepath='Python/traceback.c' line='264' column='1'/> - <parameter type-id='type-id-3' name='filename' filepath='Python/traceback.c' line='264' column='1'/> - <parameter type-id='type-id-8' name='lineno' filepath='Python/traceback.c' line='264' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyTraceBack_Here' mangled-name='PyTraceBack_Here' filepath='Python/traceback.c' line='249' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyTraceBack_Here'> - <parameter type-id='type-id-438' name='frame' filepath='Python/traceback.c' line='249' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyTraceBack_FromFrame' mangled-name='_PyTraceBack_FromFrame' filepath='Python/traceback.c' line='238' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTraceBack_FromFrame'> - <parameter type-id='type-id-14' name='tb_next' filepath='Python/traceback.c' line='238' column='1'/> - <parameter type-id='type-id-438' name='frame' filepath='Python/traceback.c' line='238' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Python/getopt.c' comp-dir-path='/src' language='LANG_C99'> - <var-decl name='_PyOS_opterr' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_getopt.h' line='8' column='1'/> - <var-decl name='_PyOS_optind' type-id='type-id-36' visibility='default' filepath='./Include/internal/pycore_getopt.h' line='9' column='1'/> - <var-decl name='_PyOS_optarg' type-id='type-id-545' visibility='default' filepath='./Include/internal/pycore_getopt.h' line='10' column='1'/> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Python/pystrcmp.c' comp-dir-path='/src' language='LANG_C99'> - <function-decl name='PyOS_mystricmp' mangled-name='PyOS_mystricmp' filepath='Python/pystrcmp.c' line='22' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyOS_mystricmp'> - <parameter type-id='type-id-3' name='s1' filepath='Python/pystrcmp.c' line='22' column='1'/> - <parameter type-id='type-id-3' name='s2' filepath='Python/pystrcmp.c' line='22' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyOS_mystrnicmp' mangled-name='PyOS_mystrnicmp' filepath='Python/pystrcmp.c' line='7' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyOS_mystrnicmp'> - <parameter type-id='type-id-3' name='s1' filepath='Python/pystrcmp.c' line='7' column='1'/> - <parameter type-id='type-id-3' name='s2' filepath='Python/pystrcmp.c' line='7' column='1'/> - <parameter type-id='type-id-36' name='size' filepath='Python/pystrcmp.c' line='7' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Python/pystrtod.c' comp-dir-path='/src' language='LANG_C99'> - <function-decl name='PyOS_double_to_string' mangled-name='PyOS_double_to_string' filepath='Python/pystrtod.c' line='1259' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyOS_double_to_string'> - <parameter type-id='type-id-391' name='val' filepath='Python/pystrtod.c' line='1259' column='1'/> - <parameter type-id='type-id-1' name='format_code' filepath='Python/pystrtod.c' line='1260' column='1'/> - <parameter type-id='type-id-8' name='precision' filepath='Python/pystrtod.c' line='1261' column='1'/> - <parameter type-id='type-id-8' name='flags' filepath='Python/pystrtod.c' line='1262' column='1'/> - <parameter type-id='type-id-501' name='type' filepath='Python/pystrtod.c' line='1263' column='1'/> - <return type-id='type-id-115'/> - </function-decl> - <pointer-type-def type-id='type-id-894' size-in-bits='64' id='type-id-895'/> - <function-decl name='_Py_string_to_number_with_underscores' mangled-name='_Py_string_to_number_with_underscores' filepath='Python/pystrtod.c' line='383' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_string_to_number_with_underscores'> - <parameter type-id='type-id-3' name='s' filepath='Python/pystrtod.c' line='384' column='1'/> - <parameter type-id='type-id-36' name='orig_len' filepath='Python/pystrtod.c' line='384' column='1'/> - <parameter type-id='type-id-3' name='what' filepath='Python/pystrtod.c' line='384' column='1'/> - <parameter type-id='type-id-14' name='obj' filepath='Python/pystrtod.c' line='384' column='1'/> - <parameter type-id='type-id-18' name='arg' filepath='Python/pystrtod.c' line='384' column='1'/> - <parameter type-id='type-id-895' name='innerfunc' filepath='Python/pystrtod.c' line='385' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyOS_string_to_double' mangled-name='PyOS_string_to_double' filepath='Python/pystrtod.c' line='337' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyOS_string_to_double'> - <parameter type-id='type-id-3' name='s' filepath='Python/pystrtod.c' line='337' column='1'/> - <parameter type-id='type-id-494' name='endptr' filepath='Python/pystrtod.c' line='338' column='1'/> - <parameter type-id='type-id-14' name='overflow_exception' filepath='Python/pystrtod.c' line='339' column='1'/> - <return type-id='type-id-391'/> - </function-decl> - <function-decl name='_Py_parse_inf_or_nan' mangled-name='_Py_parse_inf_or_nan' filepath='Python/pystrtod.c' line='30' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_parse_inf_or_nan'> - <parameter type-id='type-id-3' name='p' filepath='Python/pystrtod.c' line='30' column='1'/> - <parameter type-id='type-id-494' name='endptr' filepath='Python/pystrtod.c' line='30' column='1'/> - <return type-id='type-id-391'/> - </function-decl> - <function-type size-in-bits='64' id='type-id-894'> - <parameter type-id='type-id-3'/> - <parameter type-id='type-id-36'/> - <parameter type-id='type-id-18'/> - <return type-id='type-id-14'/> - </function-type> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Python/pystrhex.c' comp-dir-path='/src' language='LANG_C99'> - <function-decl name='_Py_strhex_bytes_with_sep' mangled-name='_Py_strhex_bytes_with_sep' filepath='Python/pystrhex.c' line='170' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_strhex_bytes_with_sep'> - <parameter type-id='type-id-3' name='argbuf' filepath='Python/pystrhex.c' line='170' column='1'/> - <parameter type-id='type-id-480' name='arglen' filepath='Python/pystrhex.c' line='170' column='1'/> - <parameter type-id='type-id-14' name='sep' filepath='Python/pystrhex.c' line='171' column='1'/> - <parameter type-id='type-id-843' name='bytes_per_group' filepath='Python/pystrhex.c' line='171' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_Py_strhex_with_sep' mangled-name='_Py_strhex_with_sep' filepath='Python/pystrhex.c' line='162' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_strhex_with_sep'> - <parameter type-id='type-id-3' name='argbuf' filepath='Python/pystrhex.c' line='170' column='1'/> - <parameter type-id='type-id-480' name='arglen' filepath='Python/pystrhex.c' line='170' column='1'/> - <parameter type-id='type-id-14' name='sep' filepath='Python/pystrhex.c' line='171' column='1'/> - <parameter type-id='type-id-843' name='bytes_per_group' filepath='Python/pystrhex.c' line='171' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_Py_strhex_bytes' mangled-name='_Py_strhex_bytes' filepath='Python/pystrhex.c' line='155' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_strhex_bytes'> - <parameter type-id='type-id-3' name='argbuf' filepath='Python/pystrhex.c' line='155' column='1'/> - <parameter type-id='type-id-480' name='arglen' filepath='Python/pystrhex.c' line='155' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_Py_strhex' mangled-name='_Py_strhex' filepath='Python/pystrhex.c' line='148' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_strhex'> - <parameter type-id='type-id-3' name='argbuf' filepath='Python/pystrhex.c' line='155' column='1'/> - <parameter type-id='type-id-480' name='arglen' filepath='Python/pystrhex.c' line='155' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Python/dtoa.c' comp-dir-path='/src' language='LANG_C99'> - <function-decl name='_Py_dg_dtoa' mangled-name='_Py_dg_dtoa' filepath='Python/dtoa.c' line='2248' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_dg_dtoa'> - <parameter type-id='type-id-391' name='dd' filepath='Python/dtoa.c' line='2248' column='1'/> - <parameter type-id='type-id-8' name='mode' filepath='Python/dtoa.c' line='2248' column='1'/> - <parameter type-id='type-id-8' name='ndigits' filepath='Python/dtoa.c' line='2248' column='1'/> - <parameter type-id='type-id-501' name='decpt' filepath='Python/dtoa.c' line='2249' column='1'/> - <parameter type-id='type-id-501' name='sign' filepath='Python/dtoa.c' line='2249' column='1'/> - <parameter type-id='type-id-494' name='rve' filepath='Python/dtoa.c' line='2249' column='1'/> - <return type-id='type-id-115'/> - </function-decl> - <function-decl name='_Py_dg_freedtoa' mangled-name='_Py_dg_freedtoa' filepath='Python/dtoa.c' line='2202' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_dg_freedtoa'> - <parameter type-id='type-id-115' name='s' filepath='Python/dtoa.c' line='2202' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_Py_dg_strtod' mangled-name='_Py_dg_strtod' filepath='Python/dtoa.c' line='1439' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_dg_strtod'> - <parameter type-id='type-id-3' name='s00' filepath='Python/dtoa.c' line='1439' column='1'/> - <parameter type-id='type-id-494' name='se' filepath='Python/dtoa.c' line='1439' column='1'/> - <return type-id='type-id-391'/> - </function-decl> - <function-decl name='_Py_dg_infinity' mangled-name='_Py_dg_infinity' filepath='Python/dtoa.c' line='1430' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_dg_infinity'> - <parameter type-id='type-id-8' name='sign' filepath='Python/dtoa.c' line='1430' column='1'/> - <return type-id='type-id-391'/> - </function-decl> - <function-decl name='_Py_dg_stdnan' mangled-name='_Py_dg_stdnan' filepath='Python/dtoa.c' line='1416' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_dg_stdnan'> - <parameter type-id='type-id-8' name='sign' filepath='Python/dtoa.c' line='1430' column='1'/> - <return type-id='type-id-391'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Python/formatter_unicode.c' comp-dir-path='/src' language='LANG_C99'> - <function-decl name='_PyFloat_FormatAdvancedWriter' mangled-name='_PyFloat_FormatAdvancedWriter' filepath='Python/formatter_unicode.c' line='1549' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyFloat_FormatAdvancedWriter'> - <parameter type-id='type-id-525' name='writer' filepath='Python/formatter_unicode.c' line='1549' column='1'/> - <parameter type-id='type-id-14' name='obj' filepath='Python/formatter_unicode.c' line='1550' column='1'/> - <parameter type-id='type-id-14' name='format_spec' filepath='Python/formatter_unicode.c' line='1551' column='1'/> - <parameter type-id='type-id-36' name='start' filepath='Python/formatter_unicode.c' line='1552' column='1'/> - <parameter type-id='type-id-36' name='end' filepath='Python/formatter_unicode.c' line='1552' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyLong_FormatAdvancedWriter' mangled-name='_PyLong_FormatAdvancedWriter' filepath='Python/formatter_unicode.c' line='1487' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyLong_FormatAdvancedWriter'> - <parameter type-id='type-id-525' name='writer' filepath='Python/formatter_unicode.c' line='1487' column='1'/> - <parameter type-id='type-id-14' name='obj' filepath='Python/formatter_unicode.c' line='1488' column='1'/> - <parameter type-id='type-id-14' name='format_spec' filepath='Python/formatter_unicode.c' line='1489' column='1'/> - <parameter type-id='type-id-36' name='start' filepath='Python/formatter_unicode.c' line='1490' column='1'/> - <parameter type-id='type-id-36' name='end' filepath='Python/formatter_unicode.c' line='1490' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyUnicode_FormatAdvancedWriter' mangled-name='_PyUnicode_FormatAdvancedWriter' filepath='Python/formatter_unicode.c' line='1451' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_FormatAdvancedWriter'> - <parameter type-id='type-id-525' name='writer' filepath='Python/formatter_unicode.c' line='1549' column='1'/> - <parameter type-id='type-id-14' name='obj' filepath='Python/formatter_unicode.c' line='1550' column='1'/> - <parameter type-id='type-id-14' name='format_spec' filepath='Python/formatter_unicode.c' line='1551' column='1'/> - <parameter type-id='type-id-36' name='start' filepath='Python/formatter_unicode.c' line='1552' column='1'/> - <parameter type-id='type-id-36' name='end' filepath='Python/formatter_unicode.c' line='1552' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Python/fileutils.c' comp-dir-path='/src' language='LANG_C99'> - <function-decl name='_Py_closerange' mangled-name='_Py_closerange' filepath='Python/fileutils.c' line='2622' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_closerange'> - <parameter type-id='type-id-8' name='first' filepath='Python/fileutils.c' line='2622' column='1'/> - <parameter type-id='type-id-8' name='last' filepath='Python/fileutils.c' line='2622' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <class-decl name='lconv' size-in-bits='768' is-struct='yes' visibility='default' filepath='/usr/include/locale.h' line='51' column='1' id='type-id-896'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='decimal_point' type-id='type-id-115' visibility='default' filepath='/usr/include/locale.h' line='55' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='thousands_sep' type-id='type-id-115' visibility='default' filepath='/usr/include/locale.h' line='56' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='grouping' type-id='type-id-115' visibility='default' filepath='/usr/include/locale.h' line='62' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='int_curr_symbol' type-id='type-id-115' visibility='default' filepath='/usr/include/locale.h' line='68' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='256'> - <var-decl name='currency_symbol' type-id='type-id-115' visibility='default' filepath='/usr/include/locale.h' line='69' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='320'> - <var-decl name='mon_decimal_point' type-id='type-id-115' visibility='default' filepath='/usr/include/locale.h' line='70' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='384'> - <var-decl name='mon_thousands_sep' type-id='type-id-115' visibility='default' filepath='/usr/include/locale.h' line='71' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='448'> - <var-decl name='mon_grouping' type-id='type-id-115' visibility='default' filepath='/usr/include/locale.h' line='72' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='512'> - <var-decl name='positive_sign' type-id='type-id-115' visibility='default' filepath='/usr/include/locale.h' line='73' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='576'> - <var-decl name='negative_sign' type-id='type-id-115' visibility='default' filepath='/usr/include/locale.h' line='74' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='640'> - <var-decl name='int_frac_digits' type-id='type-id-1' visibility='default' filepath='/usr/include/locale.h' line='75' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='648'> - <var-decl name='frac_digits' type-id='type-id-1' visibility='default' filepath='/usr/include/locale.h' line='76' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='656'> - <var-decl name='p_cs_precedes' type-id='type-id-1' visibility='default' filepath='/usr/include/locale.h' line='78' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='664'> - <var-decl name='p_sep_by_space' type-id='type-id-1' visibility='default' filepath='/usr/include/locale.h' line='80' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='672'> - <var-decl name='n_cs_precedes' type-id='type-id-1' visibility='default' filepath='/usr/include/locale.h' line='82' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='680'> - <var-decl name='n_sep_by_space' type-id='type-id-1' visibility='default' filepath='/usr/include/locale.h' line='84' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='688'> - <var-decl name='p_sign_posn' type-id='type-id-1' visibility='default' filepath='/usr/include/locale.h' line='91' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='696'> - <var-decl name='n_sign_posn' type-id='type-id-1' visibility='default' filepath='/usr/include/locale.h' line='92' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='704'> - <var-decl name='int_p_cs_precedes' type-id='type-id-1' visibility='default' filepath='/usr/include/locale.h' line='95' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='712'> - <var-decl name='int_p_sep_by_space' type-id='type-id-1' visibility='default' filepath='/usr/include/locale.h' line='97' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='720'> - <var-decl name='int_n_cs_precedes' type-id='type-id-1' visibility='default' filepath='/usr/include/locale.h' line='99' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='728'> - <var-decl name='int_n_sep_by_space' type-id='type-id-1' visibility='default' filepath='/usr/include/locale.h' line='101' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='736'> - <var-decl name='int_p_sign_posn' type-id='type-id-1' visibility='default' filepath='/usr/include/locale.h' line='108' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='744'> - <var-decl name='int_n_sign_posn' type-id='type-id-1' visibility='default' filepath='/usr/include/locale.h' line='109' column='1'/> - </data-member> - </class-decl> - <pointer-type-def type-id='type-id-896' size-in-bits='64' id='type-id-897'/> - <function-decl name='_Py_GetLocaleconvNumeric' mangled-name='_Py_GetLocaleconvNumeric' filepath='Python/fileutils.c' line='2506' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_GetLocaleconvNumeric'> - <parameter type-id='type-id-897' name='lc' filepath='Python/fileutils.c' line='2506' column='1'/> - <parameter type-id='type-id-22' name='decimal_point' filepath='Python/fileutils.c' line='2507' column='1'/> - <parameter type-id='type-id-22' name='thousands_sep' filepath='Python/fileutils.c' line='2507' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_Py_set_blocking' mangled-name='_Py_set_blocking' filepath='Python/fileutils.c' line='2429' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_set_blocking'> - <parameter type-id='type-id-8' name='fd' filepath='Python/fileutils.c' line='2429' column='1'/> - <parameter type-id='type-id-8' name='blocking' filepath='Python/fileutils.c' line='2429' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_Py_get_blocking' mangled-name='_Py_get_blocking' filepath='Python/fileutils.c' line='2408' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_get_blocking'> - <parameter type-id='type-id-8' name='fd' filepath='Python/fileutils.c' line='2408' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_Py_dup' mangled-name='_Py_dup' filepath='Python/fileutils.c' line='2342' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_dup'> - <parameter type-id='type-id-8' name='fd' filepath='Python/fileutils.c' line='2342' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_Py_wgetcwd' mangled-name='_Py_wgetcwd' filepath='Python/fileutils.c' line='2310' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_wgetcwd'> - <parameter type-id='type-id-281' name='buf' filepath='Python/fileutils.c' line='2310' column='1'/> - <parameter type-id='type-id-54' name='buflen' filepath='Python/fileutils.c' line='2310' column='1'/> - <return type-id='type-id-281'/> - </function-decl> - <function-decl name='_Py_normpath' mangled-name='_Py_normpath' filepath='Python/fileutils.c' line='2181' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_normpath'> - <parameter type-id='type-id-281' name='path' filepath='Python/fileutils.c' line='2181' column='1'/> - <parameter type-id='type-id-36' name='size' filepath='Python/fileutils.c' line='2181' column='1'/> - <return type-id='type-id-281'/> - </function-decl> - <function-decl name='_Py_wrealpath' mangled-name='_Py_wrealpath' filepath='Python/fileutils.c' line='1967' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_wrealpath'> - <parameter type-id='type-id-545' name='path' filepath='Python/fileutils.c' line='1967' column='1'/> - <parameter type-id='type-id-281' name='resolved_path' filepath='Python/fileutils.c' line='1968' column='1'/> - <parameter type-id='type-id-54' name='resolved_path_len' filepath='Python/fileutils.c' line='1968' column='1'/> - <return type-id='type-id-281'/> - </function-decl> - <function-decl name='_Py_wreadlink' mangled-name='_Py_wreadlink' filepath='Python/fileutils.c' line='1918' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_wreadlink'> - <parameter type-id='type-id-545' name='path' filepath='Python/fileutils.c' line='1918' column='1'/> - <parameter type-id='type-id-281' name='buf' filepath='Python/fileutils.c' line='1918' column='1'/> - <parameter type-id='type-id-54' name='buflen' filepath='Python/fileutils.c' line='1918' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_Py_write_noraise' mangled-name='_Py_write_noraise' filepath='Python/fileutils.c' line='1905' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_write_noraise'> - <parameter type-id='type-id-8' name='fd' filepath='Python/fileutils.c' line='1905' column='1'/> - <parameter type-id='type-id-18' name='buf' filepath='Python/fileutils.c' line='1905' column='1'/> - <parameter type-id='type-id-54' name='count' filepath='Python/fileutils.c' line='1905' column='1'/> - <return type-id='type-id-36'/> - </function-decl> - <function-decl name='_Py_write' mangled-name='_Py_write' filepath='Python/fileutils.c' line='1885' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_write'> - <parameter type-id='type-id-8' name='fd' filepath='Python/fileutils.c' line='1905' column='1'/> - <parameter type-id='type-id-18' name='buf' filepath='Python/fileutils.c' line='1905' column='1'/> - <parameter type-id='type-id-54' name='count' filepath='Python/fileutils.c' line='1905' column='1'/> - <return type-id='type-id-36'/> - </function-decl> - <function-decl name='_Py_read' mangled-name='_Py_read' filepath='Python/fileutils.c' line='1746' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_read'> - <parameter type-id='type-id-8' name='fd' filepath='Python/fileutils.c' line='1746' column='1'/> - <parameter type-id='type-id-18' name='buf' filepath='Python/fileutils.c' line='1746' column='1'/> - <parameter type-id='type-id-54' name='count' filepath='Python/fileutils.c' line='1746' column='1'/> - <return type-id='type-id-36'/> - </function-decl> - <function-decl name='_Py_fopen_obj' mangled-name='_Py_fopen_obj' filepath='Python/fileutils.c' line='1647' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_fopen_obj'> - <parameter type-id='type-id-14' name='path' filepath='Python/fileutils.c' line='1647' column='1'/> - <parameter type-id='type-id-3' name='mode' filepath='Python/fileutils.c' line='1647' column='1'/> - <return type-id='type-id-473'/> - </function-decl> - <function-decl name='_Py_wfopen' mangled-name='_Py_wfopen' filepath='Python/fileutils.c' line='1599' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_wfopen'> - <parameter type-id='type-id-545' name='path' filepath='Python/fileutils.c' line='1599' column='1'/> - <parameter type-id='type-id-545' name='mode' filepath='Python/fileutils.c' line='1599' column='1'/> - <return type-id='type-id-473'/> - </function-decl> - <function-decl name='_Py_open_noraise' mangled-name='_Py_open_noraise' filepath='Python/fileutils.c' line='1587' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_open_noraise'> - <parameter type-id='type-id-3' name='pathname' filepath='Python/fileutils.c' line='1587' column='1'/> - <parameter type-id='type-id-8' name='flags' filepath='Python/fileutils.c' line='1587' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_Py_open' mangled-name='_Py_open' filepath='Python/fileutils.c' line='1573' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_open'> - <parameter type-id='type-id-3' name='pathname' filepath='Python/fileutils.c' line='1587' column='1'/> - <parameter type-id='type-id-8' name='flags' filepath='Python/fileutils.c' line='1587' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_Py_set_inheritable_async_safe' mangled-name='_Py_set_inheritable_async_safe' filepath='Python/fileutils.c' line='1496' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_set_inheritable_async_safe'> - <parameter type-id='type-id-8' name='fd' filepath='Python/fileutils.c' line='1496' column='1'/> - <parameter type-id='type-id-8' name='inheritable' filepath='Python/fileutils.c' line='1496' column='1'/> - <parameter type-id='type-id-501' name='atomic_flag_works' filepath='Python/fileutils.c' line='1496' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_Py_set_inheritable' mangled-name='_Py_set_inheritable' filepath='Python/fileutils.c' line='1487' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_set_inheritable'> - <parameter type-id='type-id-8' name='fd' filepath='Python/fileutils.c' line='1496' column='1'/> - <parameter type-id='type-id-8' name='inheritable' filepath='Python/fileutils.c' line='1496' column='1'/> - <parameter type-id='type-id-501' name='atomic_flag_works' filepath='Python/fileutils.c' line='1496' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_Py_get_inheritable' mangled-name='_Py_get_inheritable' filepath='Python/fileutils.c' line='1321' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_get_inheritable'> - <parameter type-id='type-id-8' name='c1' filepath='Parser/token.c' line='79' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <class-decl name='stat' size-in-bits='1152' is-struct='yes' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/stat.h' line='46' column='1' id='type-id-898'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='st_dev' type-id='type-id-899' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/stat.h' line='48' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='st_ino' type-id='type-id-900' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/stat.h' line='53' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='st_nlink' type-id='type-id-901' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/stat.h' line='61' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='st_mode' type-id='type-id-902' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/stat.h' line='62' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='224'> - <var-decl name='st_uid' type-id='type-id-903' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/stat.h' line='64' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='256'> - <var-decl name='st_gid' type-id='type-id-904' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/stat.h' line='65' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='288'> - <var-decl name='__pad0' type-id='type-id-8' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/stat.h' line='67' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='320'> - <var-decl name='st_rdev' type-id='type-id-899' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/stat.h' line='69' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='384'> - <var-decl name='st_size' type-id='type-id-460' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/stat.h' line='74' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='448'> - <var-decl name='st_blksize' type-id='type-id-905' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/stat.h' line='78' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='512'> - <var-decl name='st_blocks' type-id='type-id-906' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/stat.h' line='80' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='576'> - <var-decl name='st_atim' type-id='type-id-866' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/stat.h' line='91' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='704'> - <var-decl name='st_mtim' type-id='type-id-866' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/stat.h' line='92' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='832'> - <var-decl name='st_ctim' type-id='type-id-866' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/stat.h' line='93' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='960'> - <var-decl name='__glibc_reserved' type-id='type-id-907' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/stat.h' line='106' column='1'/> - </data-member> - </class-decl> - <typedef-decl name='__dev_t' type-id='type-id-16' filepath='/usr/include/x86_64-linux-gnu/bits/types.h' line='145' column='1' id='type-id-899'/> - <typedef-decl name='__ino_t' type-id='type-id-16' filepath='/usr/include/x86_64-linux-gnu/bits/types.h' line='148' column='1' id='type-id-900'/> - <typedef-decl name='__nlink_t' type-id='type-id-16' filepath='/usr/include/x86_64-linux-gnu/bits/types.h' line='151' column='1' id='type-id-901'/> - <typedef-decl name='__mode_t' type-id='type-id-105' filepath='/usr/include/x86_64-linux-gnu/bits/types.h' line='150' column='1' id='type-id-902'/> - <typedef-decl name='__uid_t' type-id='type-id-105' filepath='/usr/include/x86_64-linux-gnu/bits/types.h' line='146' column='1' id='type-id-903'/> - <typedef-decl name='__gid_t' type-id='type-id-105' filepath='/usr/include/x86_64-linux-gnu/bits/types.h' line='147' column='1' id='type-id-904'/> - <typedef-decl name='__blksize_t' type-id='type-id-53' filepath='/usr/include/x86_64-linux-gnu/bits/types.h' line='174' column='1' id='type-id-905'/> - <typedef-decl name='__blkcnt_t' type-id='type-id-53' filepath='/usr/include/x86_64-linux-gnu/bits/types.h' line='179' column='1' id='type-id-906'/> - - <array-type-def dimensions='1' type-id='type-id-867' size-in-bits='192' id='type-id-907'> - <subrange length='3' type-id='type-id-16' id='type-id-293'/> - - </array-type-def> - <pointer-type-def type-id='type-id-898' size-in-bits='64' id='type-id-908'/> - <function-decl name='_Py_stat' mangled-name='_Py_stat' filepath='Python/fileutils.c' line='1242' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_stat'> - <parameter type-id='type-id-14' name='path' filepath='Python/fileutils.c' line='1242' column='1'/> - <parameter type-id='type-id-908' name='statbuf' filepath='Python/fileutils.c' line='1242' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_Py_fstat' mangled-name='_Py_fstat' filepath='Python/fileutils.c' line='1189' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_fstat'> - <parameter type-id='type-id-8' name='fd' filepath='Python/fileutils.c' line='1189' column='1'/> - <parameter type-id='type-id-908' name='status' filepath='Python/fileutils.c' line='1189' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_Py_fstat_noraise' mangled-name='_Py_fstat_noraise' filepath='Python/fileutils.c' line='1122' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_fstat_noraise'> - <parameter type-id='type-id-8' name='fd' filepath='Python/fileutils.c' line='1122' column='1'/> - <parameter type-id='type-id-908' name='status' filepath='Python/fileutils.c' line='1122' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_Py_GetLocaleEncodingObject' mangled-name='_Py_GetLocaleEncodingObject' filepath='Python/fileutils.c' line='926' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_GetLocaleEncodingObject'> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_Py_GetLocaleEncoding' mangled-name='_Py_GetLocaleEncoding' filepath='Python/fileutils.c' line='890' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_GetLocaleEncoding'> - <return type-id='type-id-281'/> - </function-decl> - <function-decl name='_Py_EncodeLocaleEx' mangled-name='_Py_EncodeLocaleEx' filepath='Python/fileutils.c' line='869' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_EncodeLocaleEx'> - <parameter type-id='type-id-545' name='text' filepath='Python/fileutils.c' line='869' column='1'/> - <parameter type-id='type-id-494' name='str' filepath='Python/fileutils.c' line='869' column='1'/> - <parameter type-id='type-id-582' name='error_pos' filepath='Python/fileutils.c' line='870' column='1'/> - <parameter type-id='type-id-483' name='reason' filepath='Python/fileutils.c' line='870' column='1'/> - <parameter type-id='type-id-8' name='current_locale' filepath='Python/fileutils.c' line='871' column='1'/> - <parameter type-id='type-id-386' name='errors' filepath='Python/fileutils.c' line='871' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_Py_EncodeLocaleRaw' mangled-name='_Py_EncodeLocaleRaw' filepath='Python/fileutils.c' line='862' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_EncodeLocaleRaw'> - <parameter type-id='type-id-545' name='text' filepath='Python/fileutils.c' line='862' column='1'/> - <parameter type-id='type-id-582' name='error_pos' filepath='Python/fileutils.c' line='862' column='1'/> - <return type-id='type-id-115'/> - </function-decl> - <function-decl name='Py_EncodeLocale' mangled-name='Py_EncodeLocale' filepath='Python/fileutils.c' line='853' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_EncodeLocale'> - <parameter type-id='type-id-545' name='text' filepath='Python/fileutils.c' line='862' column='1'/> - <parameter type-id='type-id-582' name='error_pos' filepath='Python/fileutils.c' line='862' column='1'/> - <return type-id='type-id-115'/> - </function-decl> - <function-decl name='Py_DecodeLocale' mangled-name='Py_DecodeLocale' filepath='Python/fileutils.c' line='651' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_DecodeLocale'> - <parameter type-id='type-id-3' name='arg' filepath='Python/fileutils.c' line='651' column='1'/> - <parameter type-id='type-id-582' name='wlen' filepath='Python/fileutils.c' line='651' column='1'/> - <return type-id='type-id-281'/> - </function-decl> - <function-decl name='_Py_DecodeLocaleEx' mangled-name='_Py_DecodeLocaleEx' filepath='Python/fileutils.c' line='589' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_DecodeLocaleEx'> - <parameter type-id='type-id-3' name='arg' filepath='Python/fileutils.c' line='589' column='1'/> - <parameter type-id='type-id-374' name='wstr' filepath='Python/fileutils.c' line='589' column='1'/> - <parameter type-id='type-id-582' name='wlen' filepath='Python/fileutils.c' line='589' column='1'/> - <parameter type-id='type-id-483' name='reason' filepath='Python/fileutils.c' line='590' column='1'/> - <parameter type-id='type-id-8' name='current_locale' filepath='Python/fileutils.c' line='591' column='1'/> - <parameter type-id='type-id-386' name='errors' filepath='Python/fileutils.c' line='591' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_Py_ResetForceASCII' mangled-name='_Py_ResetForceASCII' filepath='Python/fileutils.c' line='308' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_ResetForceASCII'> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_Py_GetForceASCII' mangled-name='_Py_GetForceASCII' filepath='Python/fileutils.c' line='298' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_GetForceASCII'> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_Py_device_encoding' mangled-name='_Py_device_encoding' filepath='Python/fileutils.c' line='69' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_device_encoding'> - <parameter type-id='type-id-8' name='fd' filepath='Python/fileutils.c' line='69' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Python/suggestions.c' comp-dir-path='/src' language='LANG_C99'> - <function-decl name='_Py_UTF8_Edit_Cost' mangled-name='_Py_UTF8_Edit_Cost' filepath='Python/suggestions.c' line='281' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_UTF8_Edit_Cost'> - <parameter type-id='type-id-14' name='a' filepath='Python/suggestions.c' line='281' column='1'/> - <parameter type-id='type-id-14' name='b' filepath='Python/suggestions.c' line='281' column='1'/> - <parameter type-id='type-id-36' name='max_cost' filepath='Python/suggestions.c' line='281' column='1'/> - <return type-id='type-id-36'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='./Python/dynload_shlib.c' comp-dir-path='/src' language='LANG_C99'> - - <array-type-def dimensions='1' type-id='type-id-3' size-in-bits='infinite' id='type-id-909'> - <subrange length='infinite' id='type-id-6'/> - - </array-type-def> - <var-decl name='_PyImport_DynLoadFiletab' type-id='type-id-909' visibility='default' filepath='./Python/importdl.h' line='9' column='1'/> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Modules/main.c' comp-dir-path='/src' language='LANG_C99'> - <function-decl name='Py_BytesMain' mangled-name='Py_BytesMain' filepath='Modules/main.c' line='727' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_BytesMain'> - <parameter type-id='type-id-8' name='argc' filepath='Modules/main.c' line='727' column='1'/> - <parameter type-id='type-id-494' name='argv' filepath='Modules/main.c' line='727' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='Py_Main' mangled-name='Py_Main' filepath='Modules/main.c' line='715' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_Main'> - <parameter type-id='type-id-8' name='argc' filepath='Modules/main.c' line='715' column='1'/> - <parameter type-id='type-id-374' name='argv' filepath='Modules/main.c' line='715' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='Py_RunMain' mangled-name='Py_RunMain' filepath='Modules/main.c' line='676' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_RunMain'> - <return type-id='type-id-8'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Modules/gcmodule.c' comp-dir-path='/src' language='LANG_C99'> - <function-decl name='PyObject_GC_IsFinalized' mangled-name='PyObject_GC_IsFinalized' filepath='Modules/gcmodule.c' line='2369' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_GC_IsFinalized'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2303' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyObject_GC_IsTracked' mangled-name='PyObject_GC_IsTracked' filepath='Modules/gcmodule.c' line='2360' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_GC_IsTracked'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2303' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyObject_GC_Del' mangled-name='PyObject_GC_Del' filepath='Modules/gcmodule.c' line='2345' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_GC_Del'> - <parameter type-id='type-id-18' name='op' filepath='Modules/gcmodule.c' line='2345' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='_PyObject_GC_Resize' mangled-name='_PyObject_GC_Resize' filepath='Modules/gcmodule.c' line='2327' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_GC_Resize'> - <parameter type-id='type-id-541' name='op' filepath='Modules/gcmodule.c' line='2327' column='1'/> - <parameter type-id='type-id-36' name='nitems' filepath='Modules/gcmodule.c' line='2327' column='1'/> - <return type-id='type-id-541'/> - </function-decl> - <function-decl name='_PyObject_GC_NewVar' mangled-name='_PyObject_GC_NewVar' filepath='Modules/gcmodule.c' line='2307' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_GC_NewVar'> - <parameter type-id='type-id-74' name='tp' filepath='Modules/gcmodule.c' line='2307' column='1'/> - <parameter type-id='type-id-36' name='nitems' filepath='Modules/gcmodule.c' line='2307' column='1'/> - <return type-id='type-id-541'/> - </function-decl> - <function-decl name='_PyObject_GC_New' mangled-name='_PyObject_GC_New' filepath='Modules/gcmodule.c' line='2295' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_GC_New'> - <parameter type-id='type-id-74' name='tp' filepath='Modules/gcmodule.c' line='2295' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyObject_IS_GC' mangled-name='PyObject_IS_GC' filepath='Modules/gcmodule.c' line='2247' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_IS_GC'> - <parameter type-id='type-id-14' name='o' filepath='Objects/abstract.c' line='2303' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyObject_GC_UnTrack' mangled-name='PyObject_GC_UnTrack' filepath='Modules/gcmodule.c' line='2235' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_GC_UnTrack'> - <parameter type-id='type-id-18' name='op_raw' filepath='Modules/gcmodule.c' line='2235' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyObject_GC_Track' mangled-name='PyObject_GC_Track' filepath='Modules/gcmodule.c' line='2216' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_GC_Track'> - <parameter type-id='type-id-18' name='op_raw' filepath='Modules/gcmodule.c' line='2216' column='1'/> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyGC_Collect' mangled-name='PyGC_Collect' filepath='Modules/gcmodule.c' line='2068' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyGC_Collect'> - <return type-id='type-id-36'/> - </function-decl> - <function-decl name='PyGC_IsEnabled' mangled-name='PyGC_IsEnabled' filepath='Modules/gcmodule.c' line='2060' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyGC_IsEnabled'> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyGC_Disable' mangled-name='PyGC_Disable' filepath='Modules/gcmodule.c' line='2051' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyGC_Disable'> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyGC_Enable' mangled-name='PyGC_Enable' filepath='Modules/gcmodule.c' line='2042' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyGC_Enable'> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyInit_gc' mangled-name='PyInit_gc' filepath='Modules/gcmodule.c' line='2035' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInit_gc'> - <return type-id='type-id-14'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='./Modules/atexitmodule.c' comp-dir-path='/src' language='LANG_C99'> - <function-decl name='PyInit_atexit' mangled-name='PyInit_atexit' filepath='./Modules/atexitmodule.c' line='287' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInit_atexit'> - <return type-id='type-id-14'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='./Modules/faulthandler.c' comp-dir-path='/src' language='LANG_C99'> - <function-decl name='PyInit_faulthandler' mangled-name='PyInit_faulthandler' filepath='./Modules/faulthandler.c' line='1333' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInit_faulthandler'> - <return type-id='type-id-14'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='./Modules/posixmodule.c' comp-dir-path='/src' language='LANG_C99'> - <function-decl name='PyInit_posix' mangled-name='PyInit_posix' filepath='./Modules/posixmodule.c' line='15942' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInit_posix'> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyOS_FSPath' mangled-name='PyOS_FSPath' filepath='./Modules/posixmodule.c' line='14469' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyOS_FSPath'> - <parameter type-id='type-id-14' name='v' filepath='Objects/abstract.c' line='2122' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_Py_Sigset_Converter' mangled-name='_Py_Sigset_Converter' filepath='./Modules/posixmodule.c' line='1485' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_Sigset_Converter'> - <parameter type-id='type-id-14' name='obj' filepath='./Modules/posixmodule.c' line='1485' column='1'/> - <parameter type-id='type-id-18' name='addr' filepath='./Modules/posixmodule.c' line='1485' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <typedef-decl name='gid_t' type-id='type-id-904' filepath='/usr/include/x86_64-linux-gnu/sys/types.h' line='64' column='1' id='type-id-910'/> - <pointer-type-def type-id='type-id-910' size-in-bits='64' id='type-id-911'/> - <function-decl name='_Py_Gid_Converter' mangled-name='_Py_Gid_Converter' filepath='./Modules/posixmodule.c' line='773' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_Gid_Converter'> - <parameter type-id='type-id-14' name='obj' filepath='./Modules/posixmodule.c' line='773' column='1'/> - <parameter type-id='type-id-911' name='p' filepath='./Modules/posixmodule.c' line='773' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <typedef-decl name='uid_t' type-id='type-id-903' filepath='/usr/include/x86_64-linux-gnu/sys/types.h' line='79' column='1' id='type-id-912'/> - <pointer-type-def type-id='type-id-912' size-in-bits='64' id='type-id-913'/> - <function-decl name='_Py_Uid_Converter' mangled-name='_Py_Uid_Converter' filepath='./Modules/posixmodule.c' line='667' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_Uid_Converter'> - <parameter type-id='type-id-14' name='obj' filepath='./Modules/posixmodule.c' line='667' column='1'/> - <parameter type-id='type-id-913' name='p' filepath='./Modules/posixmodule.c' line='667' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyLong_FromGid' mangled-name='_PyLong_FromGid' filepath='./Modules/posixmodule.c' line='659' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyLong_FromGid'> - <parameter type-id='type-id-910' name='gid' filepath='./Modules/posixmodule.c' line='659' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='_PyLong_FromUid' mangled-name='_PyLong_FromUid' filepath='./Modules/posixmodule.c' line='651' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyLong_FromUid'> - <parameter type-id='type-id-912' name='uid' filepath='./Modules/posixmodule.c' line='651' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyOS_AfterFork' mangled-name='PyOS_AfterFork' filepath='./Modules/posixmodule.c' line='633' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyOS_AfterFork'> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyOS_AfterFork_Child' mangled-name='PyOS_AfterFork_Child' filepath='./Modules/posixmodule.c' line='573' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyOS_AfterFork_Child'> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyOS_AfterFork_Parent' mangled-name='PyOS_AfterFork_Parent' filepath='./Modules/posixmodule.c' line='564' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyOS_AfterFork_Parent'> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyOS_BeforeFork' mangled-name='PyOS_BeforeFork' filepath='./Modules/posixmodule.c' line='556' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyOS_BeforeFork'> - <return type-id='type-id-70'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='./Modules/signalmodule.c' comp-dir-path='/src' language='LANG_C99'> - <function-decl name='_PyOS_IsMainThread' mangled-name='_PyOS_IsMainThread' filepath='./Modules/signalmodule.c' line='2070' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyOS_IsMainThread'> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyOS_InterruptOccurred' mangled-name='PyOS_InterruptOccurred' filepath='./Modules/signalmodule.c' line='2037' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyOS_InterruptOccurred'> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyOS_InterruptOccurred' mangled-name='_PyOS_InterruptOccurred' filepath='./Modules/signalmodule.c' line='2019' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyOS_InterruptOccurred'> - <parameter type-id='type-id-10' name='tstate' filepath='./Modules/signalmodule.c' line='2019' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_Py_RestoreSignals' mangled-name='_Py_RestoreSignals' filepath='./Modules/signalmodule.c' line='1965' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_RestoreSignals'> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyErr_SetInterrupt' mangled-name='PyErr_SetInterrupt' filepath='./Modules/signalmodule.c' line='1927' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_SetInterrupt'> - <return type-id='type-id-70'/> - </function-decl> - <function-decl name='PyErr_SetInterruptEx' mangled-name='PyErr_SetInterruptEx' filepath='./Modules/signalmodule.c' line='1911' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_SetInterruptEx'> - <parameter type-id='type-id-8' name='signum' filepath='./Modules/signalmodule.c' line='1911' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyErr_CheckSignals' mangled-name='_PyErr_CheckSignals' filepath='./Modules/signalmodule.c' line='1899' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyErr_CheckSignals'> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='_PyErr_CheckSignalsTstate' mangled-name='_PyErr_CheckSignalsTstate' filepath='./Modules/signalmodule.c' line='1811' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyErr_CheckSignalsTstate'> - <parameter type-id='type-id-10' name='tstate' filepath='./Modules/signalmodule.c' line='1811' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyErr_CheckSignals' mangled-name='PyErr_CheckSignals' filepath='./Modules/signalmodule.c' line='1798' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_CheckSignals'> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyInit__signal' mangled-name='PyInit__signal' filepath='./Modules/signalmodule.c' line='1758' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInit__signal'> - <return type-id='type-id-14'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='./Modules/_tracemalloc.c' comp-dir-path='/src' language='LANG_C99'> - <function-decl name='_PyTraceMalloc_GetTraceback' mangled-name='_PyTraceMalloc_GetTraceback' filepath='./Modules/_tracemalloc.c' line='1811' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTraceMalloc_GetTraceback'> - <parameter type-id='type-id-105' name='domain' filepath='./Modules/_tracemalloc.c' line='1811' column='1'/> - <parameter type-id='type-id-358' name='ptr' filepath='./Modules/_tracemalloc.c' line='1811' column='1'/> - <return type-id='type-id-14'/> - </function-decl> - <function-decl name='PyTraceMalloc_Untrack' mangled-name='PyTraceMalloc_Untrack' filepath='./Modules/_tracemalloc.c' line='1752' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyTraceMalloc_Untrack'> - <parameter type-id='type-id-105' name='domain' filepath='./Modules/_tracemalloc.c' line='1752' column='1'/> - <parameter type-id='type-id-358' name='ptr' filepath='./Modules/_tracemalloc.c' line='1752' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyTraceMalloc_Track' mangled-name='PyTraceMalloc_Track' filepath='./Modules/_tracemalloc.c' line='1729' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyTraceMalloc_Track'> - <parameter type-id='type-id-105' name='domain' filepath='./Modules/_tracemalloc.c' line='1729' column='1'/> - <parameter type-id='type-id-358' name='ptr' filepath='./Modules/_tracemalloc.c' line='1729' column='1'/> - <parameter type-id='type-id-54' name='size' filepath='./Modules/_tracemalloc.c' line='1730' column='1'/> - <return type-id='type-id-8'/> - </function-decl> - <function-decl name='PyInit__tracemalloc' mangled-name='PyInit__tracemalloc' filepath='./Modules/_tracemalloc.c' line='1694' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInit__tracemalloc'> - <return type-id='type-id-14'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='./Modules/_codecsmodule.c' comp-dir-path='/src' language='LANG_C99'> - <function-decl name='PyInit__codecs' mangled-name='PyInit__codecs' filepath='./Modules/_codecsmodule.c' line='1067' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInit__codecs'> - <return type-id='type-id-14'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='./Modules/_collectionsmodule.c' comp-dir-path='/src' language='LANG_C99'> - <function-decl name='PyInit__collections' mangled-name='PyInit__collections' filepath='./Modules/_collectionsmodule.c' line='2612' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInit__collections'> - <return type-id='type-id-14'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='./Modules/errnomodule.c' comp-dir-path='/src' language='LANG_C99'> - <function-decl name='PyInit_errno' mangled-name='PyInit_errno' filepath='./Modules/errnomodule.c' line='960' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInit_errno'> - <return type-id='type-id-14'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='./Modules/_io/_iomodule.c' comp-dir-path='/src' language='LANG_C99'> - <var-decl name='_PyIO_Module' type-id='type-id-538' visibility='default' filepath='./Modules/_io/_iomodule.h' line='140' column='1'/> - <function-decl name='PyInit__io' mangled-name='PyInit__io' filepath='./Modules/_io/_iomodule.c' line='681' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInit__io'> - <return type-id='type-id-14'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='./Modules/_io/iobase.c' comp-dir-path='/src' language='LANG_C99'> - <var-decl name='PyIOBase_Type' type-id='type-id-112' visibility='default' filepath='./Modules/_io/_iomodule.h' line='8' column='1'/> - <var-decl name='PyRawIOBase_Type' type-id='type-id-112' visibility='default' filepath='./Modules/_io/_iomodule.h' line='9' column='1'/> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='./Modules/_io/fileio.c' comp-dir-path='/src' language='LANG_C99'> - <var-decl name='PyFileIO_Type' type-id='type-id-112' visibility='default' filepath='./Modules/_io/_iomodule.h' line='14' column='1'/> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='./Modules/_io/bytesio.c' comp-dir-path='/src' language='LANG_C99'> - <var-decl name='PyBytesIO_Type' type-id='type-id-112' visibility='default' filepath='./Modules/_io/_iomodule.h' line='15' column='1'/> - <var-decl name='_PyBytesIOBuffer_Type' type-id='type-id-112' mangled-name='_PyBytesIOBuffer_Type' visibility='default' filepath='./Modules/_io/_iomodule.h' line='158' column='1' elf-symbol-id='_PyBytesIOBuffer_Type'/> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='./Modules/_io/bufferedio.c' comp-dir-path='/src' language='LANG_C99'> - <var-decl name='PyBufferedIOBase_Type' type-id='type-id-112' visibility='default' filepath='./Modules/_io/_iomodule.h' line='10' column='1'/> - <var-decl name='PyBufferedReader_Type' type-id='type-id-112' visibility='default' filepath='./Modules/_io/_iomodule.h' line='17' column='1'/> - <var-decl name='PyBufferedWriter_Type' type-id='type-id-112' visibility='default' filepath='./Modules/_io/_iomodule.h' line='18' column='1'/> - <var-decl name='PyBufferedRWPair_Type' type-id='type-id-112' visibility='default' filepath='./Modules/_io/_iomodule.h' line='19' column='1'/> - <var-decl name='PyBufferedRandom_Type' type-id='type-id-112' visibility='default' filepath='./Modules/_io/_iomodule.h' line='20' column='1'/> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='./Modules/_io/textio.c' comp-dir-path='/src' language='LANG_C99'> - <var-decl name='PyTextIOBase_Type' type-id='type-id-112' visibility='default' filepath='./Modules/_io/_iomodule.h' line='11' column='1'/> - <var-decl name='PyIncrementalNewlineDecoder_Type' type-id='type-id-112' visibility='default' filepath='./Modules/_io/_iomodule.h' line='22' column='1'/> - <var-decl name='PyTextIOWrapper_Type' type-id='type-id-112' visibility='default' filepath='./Modules/_io/_iomodule.h' line='21' column='1'/> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='./Modules/_io/stringio.c' comp-dir-path='/src' language='LANG_C99'> - <var-decl name='PyStringIO_Type' type-id='type-id-112' visibility='default' filepath='./Modules/_io/_iomodule.h' line='16' column='1'/> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='./Modules/itertoolsmodule.c' comp-dir-path='/src' language='LANG_C99'> - <function-decl name='PyInit_itertools' mangled-name='PyInit_itertools' filepath='./Modules/itertoolsmodule.c' line='4901' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInit_itertools'> - <return type-id='type-id-14'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='./Modules/_sre/sre.c' comp-dir-path='/src' language='LANG_C99'> - <function-decl name='PyInit__sre' mangled-name='PyInit__sre' filepath='./Modules/_sre/sre.c' line='3036' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInit__sre'> - <return type-id='type-id-14'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='./Modules/_threadmodule.c' comp-dir-path='/src' language='LANG_C99'> - <function-decl name='PyInit__thread' mangled-name='PyInit__thread' filepath='./Modules/_threadmodule.c' line='1700' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInit__thread'> - <return type-id='type-id-14'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='./Modules/timemodule.c' comp-dir-path='/src' language='LANG_C99'> - <function-decl name='PyInit_time' mangled-name='PyInit_time' filepath='./Modules/timemodule.c' line='2111' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInit_time'> - <return type-id='type-id-14'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='./Modules/_weakref.c' comp-dir-path='/src' language='LANG_C99'> - <function-decl name='PyInit__weakref' mangled-name='PyInit__weakref' filepath='./Modules/_weakref.c' line='193' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInit__weakref'> - <return type-id='type-id-14'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='./Modules/_abc.c' comp-dir-path='/src' language='LANG_C99'> - <function-decl name='PyInit__abc' mangled-name='PyInit__abc' filepath='./Modules/_abc.c' line='967' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInit__abc'> - <return type-id='type-id-14'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='./Modules/_functoolsmodule.c' comp-dir-path='/src' language='LANG_C99'> - <function-decl name='PyInit__functools' mangled-name='PyInit__functools' filepath='./Modules/_functoolsmodule.c' line='1535' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInit__functools'> - <return type-id='type-id-14'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='./Modules/_localemodule.c' comp-dir-path='/src' language='LANG_C99'> - <function-decl name='PyInit__locale' mangled-name='PyInit__locale' filepath='./Modules/_localemodule.c' line='913' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInit__locale'> - <return type-id='type-id-14'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='./Modules/_operator.c' comp-dir-path='/src' language='LANG_C99'> - <function-decl name='PyInit__operator' mangled-name='PyInit__operator' filepath='./Modules/_operator.c' line='1891' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInit__operator'> - <return type-id='type-id-14'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='./Modules/_stat.c' comp-dir-path='/src' language='LANG_C99'> - <function-decl name='PyInit__stat' mangled-name='PyInit__stat' filepath='./Modules/_stat.c' line='630' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInit__stat'> - <return type-id='type-id-14'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='./Modules/symtablemodule.c' comp-dir-path='/src' language='LANG_C99'> - <function-decl name='PyInit__symtable' mangled-name='PyInit__symtable' filepath='./Modules/symtablemodule.c' line='123' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInit__symtable'> - <return type-id='type-id-14'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='./Modules/pwdmodule.c' comp-dir-path='/src' language='LANG_C99'> - <function-decl name='PyInit_pwd' mangled-name='PyInit_pwd' filepath='./Modules/pwdmodule.c' line='368' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInit_pwd'> - <return type-id='type-id-14'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='./Modules/xxsubtype.c' comp-dir-path='/src' language='LANG_C99'> - <function-decl name='PyInit_xxsubtype' mangled-name='PyInit_xxsubtype' filepath='./Modules/xxsubtype.c' line='313' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInit_xxsubtype'> - <return type-id='type-id-14'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='./Modules/getpath.c' comp-dir-path='/src' language='LANG_C99'> - <function-decl name='_Py_Get_Getpath_CodeObject' mangled-name='_Py_Get_Getpath_CodeObject' filepath='./Modules/getpath.c' line='790' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_Get_Getpath_CodeObject'> - <return type-id='type-id-14'/> - </function-decl> - </abi-instr> - <abi-instr version='1.0' address-size='64' path='Python/frozen.c' comp-dir-path='/src' language='LANG_C99'> - <class-decl name='_frozen' size-in-bits='256' is-struct='yes' visibility='default' filepath='./Include/cpython/import.h' line='31' column='1' id='type-id-914'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='name' type-id='type-id-3' visibility='default' filepath='./Include/cpython/import.h' line='32' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='code' type-id='type-id-528' visibility='default' filepath='./Include/cpython/import.h' line='33' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='128'> - <var-decl name='size' type-id='type-id-8' visibility='default' filepath='./Include/cpython/import.h' line='34' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='160'> - <var-decl name='is_package' type-id='type-id-8' visibility='default' filepath='./Include/cpython/import.h' line='35' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='192'> - <var-decl name='get_code' type-id='type-id-534' visibility='default' filepath='./Include/cpython/import.h' line='36' column='1'/> - </data-member> - </class-decl> - <qualified-type-def type-id='type-id-914' const='yes' id='type-id-915'/> - <pointer-type-def type-id='type-id-915' size-in-bits='64' id='type-id-916'/> - <var-decl name='_PyImport_FrozenBootstrap' type-id='type-id-916' mangled-name='_PyImport_FrozenBootstrap' visibility='default' filepath='./Include/internal/pycore_import.h' line='18' column='1' elf-symbol-id='_PyImport_FrozenBootstrap'/> - <var-decl name='_PyImport_FrozenStdlib' type-id='type-id-916' mangled-name='_PyImport_FrozenStdlib' visibility='default' filepath='./Include/internal/pycore_import.h' line='19' column='1' elf-symbol-id='_PyImport_FrozenStdlib'/> - <var-decl name='_PyImport_FrozenTest' type-id='type-id-916' mangled-name='_PyImport_FrozenTest' visibility='default' filepath='./Include/internal/pycore_import.h' line='20' column='1' elf-symbol-id='_PyImport_FrozenTest'/> - <class-decl name='_module_alias' size-in-bits='128' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_import.h' line='13' column='1' id='type-id-917'> - <data-member access='public' layout-offset-in-bits='0'> - <var-decl name='name' type-id='type-id-3' visibility='default' filepath='./Include/internal/pycore_import.h' line='14' column='1'/> - </data-member> - <data-member access='public' layout-offset-in-bits='64'> - <var-decl name='orig' type-id='type-id-3' visibility='default' filepath='./Include/internal/pycore_import.h' line='15' column='1'/> - </data-member> - </class-decl> - <qualified-type-def type-id='type-id-917' const='yes' id='type-id-918'/> - <pointer-type-def type-id='type-id-918' size-in-bits='64' id='type-id-919'/> - <var-decl name='_PyImport_FrozenAliases' type-id='type-id-919' visibility='default' filepath='./Include/internal/pycore_import.h' line='21' column='1'/> - <var-decl name='PyImport_FrozenModules' type-id='type-id-916' mangled-name='PyImport_FrozenModules' visibility='default' filepath='./Include/cpython/import.h' line='42' column='1' elf-symbol-id='PyImport_FrozenModules'/> - </abi-instr> -</abi-corpus> diff --git a/Doc/data/python3.12.abi b/Doc/data/python3.12.abi new file mode 100644 index 00000000..f4138bee --- /dev/null +++ b/Doc/data/python3.12.abi @@ -0,0 +1,26477 @@ +<abi-corpus version='2.0' path='libpython3.12.so' soname='libpython3.12.so.1.0'> + <elf-needed> + <dependency name='libm.so.6'/> + <dependency name='libc.so.6'/> + <dependency name='ld-linux-x86-64.so.2'/> + </elf-needed> + <elf-function-symbols> + <elf-symbol name='PyAIter_Check' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyArg_Parse' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyArg_ParseTuple' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyArg_ParseTupleAndKeywords' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyArg_UnpackTuple' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyArg_VaParse' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyArg_VaParseTupleAndKeywords' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyArg_ValidateKeywordArguments' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyAsyncGen_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyBool_FromLong' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyBuffer_FillContiguousStrides' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyBuffer_FillInfo' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyBuffer_FromContiguous' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyBuffer_GetPointer' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyBuffer_IsContiguous' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyBuffer_Release' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyBuffer_SizeFromFormat' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyBuffer_ToContiguous' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyByteArray_AsString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyByteArray_Concat' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyByteArray_FromObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyByteArray_FromStringAndSize' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyByteArray_Resize' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyByteArray_Size' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyBytes_AsString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyBytes_AsStringAndSize' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyBytes_Concat' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyBytes_ConcatAndDel' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyBytes_DecodeEscape' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyBytes_FromFormat' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyBytes_FromFormatV' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyBytes_FromObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyBytes_FromString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyBytes_FromStringAndSize' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyBytes_Repr' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyBytes_Size' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyCFunction_Call' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyCFunction_GetFlags' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyCFunction_GetFunction' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyCFunction_GetSelf' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyCFunction_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyCFunction_NewEx' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyCMethod_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyCallIter_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyCallable_Check' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyCapsule_GetContext' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyCapsule_GetDestructor' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyCapsule_GetName' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyCapsule_GetPointer' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyCapsule_Import' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyCapsule_IsValid' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyCapsule_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyCapsule_SetContext' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyCapsule_SetDestructor' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyCapsule_SetName' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyCapsule_SetPointer' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyCell_Get' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyCell_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyCell_Set' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyClassMethod_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyCode_AddWatcher' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyCode_Addr2Line' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyCode_Addr2Location' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyCode_ClearWatcher' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyCode_GetCellvars' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyCode_GetCode' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyCode_GetFreevars' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyCode_GetVarnames' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyCode_NewEmpty' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyCode_Optimize' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyCodec_BackslashReplaceErrors' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyCodec_Decode' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyCodec_Decoder' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyCodec_Encode' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyCodec_Encoder' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyCodec_IgnoreErrors' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyCodec_IncrementalDecoder' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyCodec_IncrementalEncoder' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyCodec_KnownEncoding' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyCodec_LookupError' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyCodec_NameReplaceErrors' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyCodec_Register' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyCodec_RegisterError' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyCodec_ReplaceErrors' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyCodec_StreamReader' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyCodec_StreamWriter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyCodec_StrictErrors' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyCodec_Unregister' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyCodec_XMLCharRefReplaceErrors' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyCompile_OpcodeStackEffect' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyCompile_OpcodeStackEffectWithJump' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyComplex_AsCComplex' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyComplex_FromCComplex' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyComplex_FromDoubles' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyComplex_ImagAsDouble' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyComplex_RealAsDouble' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyConfig_Clear' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyConfig_InitIsolatedConfig' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyConfig_InitPythonConfig' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyConfig_Read' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyConfig_SetArgv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyConfig_SetBytesArgv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyConfig_SetBytesString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyConfig_SetString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyConfig_SetWideStringList' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyContextVar_Get' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyContextVar_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyContextVar_Reset' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyContextVar_Set' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyContext_Copy' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyContext_CopyCurrent' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyContext_Enter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyContext_Exit' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyContext_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyCoro_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyDescr_IsData' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyDescr_NewClassMethod' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyDescr_NewGetSet' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyDescr_NewMember' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyDescr_NewMethod' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyDescr_NewWrapper' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyDictProxy_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyDict_AddWatcher' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyDict_Clear' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyDict_ClearWatcher' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyDict_Contains' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyDict_Copy' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyDict_DelItem' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyDict_DelItemString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyDict_GetItem' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyDict_GetItemString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyDict_GetItemWithError' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyDict_Items' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyDict_Keys' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyDict_Merge' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyDict_MergeFromSeq2' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyDict_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyDict_Next' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyDict_SetDefault' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyDict_SetItem' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyDict_SetItemString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyDict_Size' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyDict_Unwatch' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyDict_Update' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyDict_Values' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyDict_Watch' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyErr_BadArgument' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyErr_BadInternalCall' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyErr_CheckSignals' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyErr_Clear' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyErr_Display' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyErr_DisplayException' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyErr_ExceptionMatches' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyErr_Fetch' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyErr_Format' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyErr_FormatV' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyErr_GetExcInfo' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyErr_GetHandledException' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyErr_GetRaisedException' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyErr_GivenExceptionMatches' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyErr_NewException' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyErr_NewExceptionWithDoc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyErr_NoMemory' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyErr_NormalizeException' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyErr_Occurred' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyErr_Print' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyErr_PrintEx' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyErr_ProgramText' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyErr_ProgramTextObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyErr_RangedSyntaxLocationObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyErr_ResourceWarning' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyErr_Restore' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyErr_SetExcInfo' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyErr_SetFromErrno' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyErr_SetFromErrnoWithFilename' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyErr_SetFromErrnoWithFilenameObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyErr_SetFromErrnoWithFilenameObjects' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyErr_SetHandledException' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyErr_SetImportError' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyErr_SetImportErrorSubclass' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyErr_SetInterrupt' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyErr_SetInterruptEx' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyErr_SetNone' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyErr_SetObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyErr_SetRaisedException' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyErr_SetString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyErr_SyntaxLocation' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyErr_SyntaxLocationEx' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyErr_SyntaxLocationObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyErr_WarnEx' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyErr_WarnExplicit' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyErr_WarnExplicitFormat' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyErr_WarnExplicitObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyErr_WarnFormat' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyErr_WriteUnraisable' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyEval_AcquireLock' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyEval_AcquireThread' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyEval_CallFunction' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyEval_CallMethod' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyEval_CallObjectWithKeywords' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyEval_EvalCode' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyEval_EvalCodeEx' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyEval_EvalFrame' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyEval_EvalFrameEx' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyEval_GetBuiltins' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyEval_GetFrame' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyEval_GetFuncDesc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyEval_GetFuncName' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyEval_GetGlobals' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyEval_GetLocals' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyEval_InitThreads' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyEval_MergeCompilerFlags' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyEval_ReleaseLock' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyEval_ReleaseThread' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyEval_RestoreThread' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyEval_SaveThread' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyEval_SetProfile' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyEval_SetProfileAllThreads' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyEval_SetTrace' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyEval_SetTraceAllThreads' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyEval_ThreadsInitialized' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExceptionClass_Name' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyException_GetArgs' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyException_GetCause' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyException_GetContext' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyException_GetTraceback' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyException_SetArgs' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyException_SetCause' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyException_SetContext' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyException_SetTraceback' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyFile_FromFd' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyFile_GetLine' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyFile_NewStdPrinter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyFile_OpenCode' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyFile_OpenCodeObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyFile_SetOpenCodeHook' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyFile_WriteObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyFile_WriteString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyFloat_AsDouble' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyFloat_FromDouble' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyFloat_FromString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyFloat_GetInfo' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyFloat_GetMax' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyFloat_GetMin' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyFloat_Pack2' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyFloat_Pack4' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyFloat_Pack8' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyFloat_Unpack2' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyFloat_Unpack4' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyFloat_Unpack8' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyFrame_FastToLocals' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyFrame_FastToLocalsWithError' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyFrame_GetBack' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyFrame_GetBuiltins' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyFrame_GetCode' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyFrame_GetGenerator' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyFrame_GetGlobals' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyFrame_GetLasti' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyFrame_GetLineNumber' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyFrame_GetLocals' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyFrame_GetVar' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyFrame_GetVarString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyFrame_LocalsToFast' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyFrame_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyFrozenSet_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyFunction_AddWatcher' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyFunction_ClearWatcher' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyFunction_GetAnnotations' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyFunction_GetClosure' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyFunction_GetCode' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyFunction_GetDefaults' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyFunction_GetGlobals' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyFunction_GetKwDefaults' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyFunction_GetModule' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyFunction_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyFunction_NewWithQualName' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyFunction_SetAnnotations' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyFunction_SetClosure' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyFunction_SetDefaults' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyFunction_SetKwDefaults' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyFunction_SetVectorcall' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyGC_Collect' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyGC_Disable' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyGC_Enable' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyGC_IsEnabled' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyGILState_Check' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyGILState_Ensure' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyGILState_GetThisThreadState' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyGILState_Release' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyGen_GetCode' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyGen_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyGen_NewWithQualName' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyHash_GetFuncDef' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyImport_AddModule' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyImport_AddModuleObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyImport_AppendInittab' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyImport_ExecCodeModule' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyImport_ExecCodeModuleEx' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyImport_ExecCodeModuleObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyImport_ExecCodeModuleWithPathnames' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyImport_ExtendInittab' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyImport_GetImporter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyImport_GetMagicNumber' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyImport_GetMagicTag' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyImport_GetModule' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyImport_GetModuleDict' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyImport_Import' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyImport_ImportFrozenModule' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyImport_ImportFrozenModuleObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyImport_ImportModule' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyImport_ImportModuleLevel' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyImport_ImportModuleLevelObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyImport_ImportModuleNoBlock' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyImport_ReloadModule' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyIndex_Check' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyInit__abc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyInit__ast' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyInit__codecs' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyInit__collections' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyInit__functools' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyInit__imp' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyInit__io' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyInit__locale' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyInit__operator' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyInit__signal' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyInit__sre' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyInit__stat' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyInit__string' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyInit__symtable' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyInit__thread' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyInit__tokenize' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyInit__tracemalloc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyInit__typing' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyInit__weakref' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyInit_atexit' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyInit_errno' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyInit_faulthandler' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyInit_gc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyInit_itertools' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyInit_posix' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyInit_pwd' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyInit_time' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyInstanceMethod_Function' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyInstanceMethod_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyInterpreterState_Clear' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyInterpreterState_Delete' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyInterpreterState_Get' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyInterpreterState_GetDict' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyInterpreterState_GetID' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyInterpreterState_Head' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyInterpreterState_Main' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyInterpreterState_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyInterpreterState_Next' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyInterpreterState_ThreadHead' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyIter_Check' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyIter_Next' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyIter_Send' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyList_Append' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyList_AsTuple' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyList_GetItem' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyList_GetSlice' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyList_Insert' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyList_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyList_Reverse' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyList_SetItem' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyList_SetSlice' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyList_Size' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyList_Sort' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyLong_AsDouble' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyLong_AsLong' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyLong_AsLongAndOverflow' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyLong_AsLongLong' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyLong_AsLongLongAndOverflow' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyLong_AsSize_t' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyLong_AsSsize_t' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyLong_AsUnsignedLong' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyLong_AsUnsignedLongLong' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyLong_AsUnsignedLongLongMask' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyLong_AsUnsignedLongMask' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyLong_AsVoidPtr' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyLong_FromDouble' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyLong_FromLong' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyLong_FromLongLong' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyLong_FromSize_t' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyLong_FromSsize_t' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyLong_FromString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyLong_FromUnicodeObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyLong_FromUnsignedLong' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyLong_FromUnsignedLongLong' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyLong_FromVoidPtr' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyLong_GetInfo' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyMapping_Check' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyMapping_GetItemString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyMapping_HasKey' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyMapping_HasKeyString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyMapping_Items' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyMapping_Keys' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyMapping_Length' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyMapping_SetItemString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyMapping_Size' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyMapping_Values' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyMarshal_Init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyMarshal_ReadLastObjectFromFile' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyMarshal_ReadLongFromFile' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyMarshal_ReadObjectFromFile' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyMarshal_ReadObjectFromString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyMarshal_ReadShortFromFile' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyMarshal_WriteLongToFile' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyMarshal_WriteObjectToFile' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyMarshal_WriteObjectToString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyMem_Calloc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyMem_Free' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyMem_GetAllocator' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyMem_Malloc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyMem_RawCalloc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyMem_RawFree' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyMem_RawMalloc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyMem_RawRealloc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyMem_Realloc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyMem_SetAllocator' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyMem_SetupDebugHooks' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyMember_GetOne' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyMember_SetOne' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyMemoryView_FromBuffer' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyMemoryView_FromMemory' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyMemoryView_FromObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyMemoryView_GetContiguous' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyMethod_Function' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyMethod_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyMethod_Self' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyModuleDef_Init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyModule_AddFunctions' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyModule_AddIntConstant' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyModule_AddObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyModule_AddObjectRef' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyModule_AddStringConstant' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyModule_AddType' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyModule_Create2' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyModule_ExecDef' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyModule_FromDefAndSpec2' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyModule_GetDef' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyModule_GetDict' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyModule_GetFilename' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyModule_GetFilenameObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyModule_GetName' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyModule_GetNameObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyModule_GetState' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyModule_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyModule_NewObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyModule_SetDocString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyNumber_Absolute' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyNumber_Add' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyNumber_And' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyNumber_AsSsize_t' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyNumber_Check' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyNumber_Divmod' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyNumber_Float' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyNumber_FloorDivide' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyNumber_InPlaceAdd' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyNumber_InPlaceAnd' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyNumber_InPlaceFloorDivide' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyNumber_InPlaceLshift' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyNumber_InPlaceMatrixMultiply' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyNumber_InPlaceMultiply' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyNumber_InPlaceOr' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyNumber_InPlacePower' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyNumber_InPlaceRemainder' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyNumber_InPlaceRshift' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyNumber_InPlaceSubtract' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyNumber_InPlaceTrueDivide' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyNumber_InPlaceXor' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyNumber_Index' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyNumber_Invert' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyNumber_Long' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyNumber_Lshift' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyNumber_MatrixMultiply' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyNumber_Multiply' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyNumber_Negative' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyNumber_Or' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyNumber_Positive' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyNumber_Power' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyNumber_Remainder' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyNumber_Rshift' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyNumber_Subtract' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyNumber_ToBase' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyNumber_TrueDivide' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyNumber_Xor' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyODict_DelItem' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyODict_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyODict_SetItem' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyOS_AfterFork' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyOS_AfterFork_Child' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyOS_AfterFork_Parent' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyOS_BeforeFork' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyOS_FSPath' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyOS_InterruptOccurred' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyOS_Readline' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyOS_double_to_string' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyOS_getsig' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyOS_mystricmp' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyOS_mystrnicmp' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyOS_setsig' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyOS_snprintf' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyOS_string_to_double' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyOS_strtol' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyOS_strtoul' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyOS_vsnprintf' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_ASCII' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_AsCharBuffer' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_AsFileDescriptor' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_AsReadBuffer' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_AsWriteBuffer' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_Bytes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_Call' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_CallFinalizer' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_CallFinalizerFromDealloc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_CallFunction' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_CallFunctionObjArgs' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_CallMethod' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_CallMethodObjArgs' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_CallNoArgs' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_CallObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_CallOneArg' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_Calloc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_CheckBuffer' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_CheckReadBuffer' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_ClearWeakRefs' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_CopyData' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_DelItem' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_DelItemString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_Dir' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_Format' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_Free' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_GC_Del' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_GC_IsFinalized' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_GC_IsTracked' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_GC_Track' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_GC_UnTrack' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_GET_WEAKREFS_LISTPTR' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_GenericGetAttr' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_GenericGetDict' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_GenericSetAttr' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_GenericSetDict' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_GetAIter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_GetArenaAllocator' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_GetAttr' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_GetAttrString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_GetBuffer' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_GetItem' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_GetItemData' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_GetIter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_GetTypeData' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_HasAttr' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_HasAttrString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_Hash' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_HashNotImplemented' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_IS_GC' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_Init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_InitVar' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_IsInstance' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_IsSubclass' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_IsTrue' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_Length' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_LengthHint' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_Malloc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_Not' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_Print' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_Realloc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_Repr' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_RichCompare' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_RichCompareBool' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_SelfIter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_SetArenaAllocator' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_SetAttr' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_SetAttrString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_SetItem' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_Size' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_Str' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_Type' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_Vectorcall' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_VectorcallDict' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyObject_VectorcallMethod' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyPickleBuffer_FromObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyPickleBuffer_GetBuffer' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyPickleBuffer_Release' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyPreConfig_InitIsolatedConfig' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyPreConfig_InitPythonConfig' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyRun_AnyFile' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyRun_AnyFileEx' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyRun_AnyFileExFlags' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyRun_AnyFileFlags' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyRun_File' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyRun_FileEx' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyRun_FileExFlags' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyRun_FileFlags' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyRun_InteractiveLoop' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyRun_InteractiveLoopFlags' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyRun_InteractiveOne' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyRun_InteractiveOneFlags' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyRun_InteractiveOneObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyRun_SimpleFile' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyRun_SimpleFileEx' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyRun_SimpleFileExFlags' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyRun_SimpleString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyRun_SimpleStringFlags' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyRun_String' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyRun_StringFlags' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PySeqIter_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PySequence_Check' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PySequence_Concat' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PySequence_Contains' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PySequence_Count' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PySequence_DelItem' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PySequence_DelSlice' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PySequence_Fast' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PySequence_GetItem' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PySequence_GetSlice' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PySequence_In' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PySequence_InPlaceConcat' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PySequence_InPlaceRepeat' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PySequence_Index' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PySequence_Length' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PySequence_List' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PySequence_Repeat' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PySequence_SetItem' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PySequence_SetSlice' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PySequence_Size' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PySequence_Tuple' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PySet_Add' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PySet_Clear' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PySet_Contains' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PySet_Discard' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PySet_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PySet_Pop' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PySet_Size' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PySlice_AdjustIndices' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PySlice_GetIndices' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PySlice_GetIndicesEx' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PySlice_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PySlice_Unpack' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyState_AddModule' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyState_FindModule' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyState_RemoveModule' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyStaticMethod_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyStatus_Error' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyStatus_Exception' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyStatus_Exit' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyStatus_IsError' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyStatus_IsExit' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyStatus_NoMemory' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyStatus_Ok' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyStructSequence_GetItem' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyStructSequence_InitType' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyStructSequence_InitType2' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyStructSequence_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyStructSequence_NewType' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyStructSequence_SetItem' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PySymtable_Lookup' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PySys_AddAuditHook' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PySys_AddWarnOption' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PySys_AddWarnOptionUnicode' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PySys_AddXOption' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PySys_Audit' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PySys_FormatStderr' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PySys_FormatStdout' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PySys_GetObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PySys_GetXOptions' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PySys_HasWarnOptions' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PySys_ResetWarnOptions' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PySys_SetArgv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PySys_SetArgvEx' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PySys_SetObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PySys_SetPath' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PySys_WriteStderr' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PySys_WriteStdout' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyThreadState_Clear' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyThreadState_Delete' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyThreadState_DeleteCurrent' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyThreadState_EnterTracing' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyThreadState_Get' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyThreadState_GetDict' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyThreadState_GetFrame' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyThreadState_GetID' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyThreadState_GetInterpreter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyThreadState_LeaveTracing' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyThreadState_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyThreadState_Next' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyThreadState_SetAsyncExc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyThreadState_Swap' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyThread_GetInfo' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyThread_ReInitTLS' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyThread_acquire_lock' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyThread_acquire_lock_timed' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyThread_allocate_lock' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyThread_create_key' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyThread_delete_key' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyThread_delete_key_value' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyThread_exit_thread' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyThread_free_lock' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyThread_get_key_value' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyThread_get_stacksize' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyThread_get_thread_ident' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyThread_get_thread_native_id' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyThread_init_thread' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyThread_release_lock' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyThread_set_key_value' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyThread_set_stacksize' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyThread_start_new_thread' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyThread_tss_alloc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyThread_tss_create' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyThread_tss_delete' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyThread_tss_free' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyThread_tss_get' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyThread_tss_is_created' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyThread_tss_set' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyTraceBack_Here' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyTraceBack_Print' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyTraceMalloc_Track' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyTraceMalloc_Untrack' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyTuple_GetItem' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyTuple_GetSlice' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyTuple_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyTuple_Pack' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyTuple_SetItem' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyTuple_Size' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyType_AddWatcher' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyType_ClearCache' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyType_ClearWatcher' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyType_FromMetaclass' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyType_FromModuleAndSpec' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyType_FromSpec' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyType_FromSpecWithBases' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyType_GenericAlloc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyType_GenericNew' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyType_GetDict' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyType_GetFlags' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyType_GetModule' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyType_GetModuleByDef' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyType_GetModuleState' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyType_GetName' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyType_GetQualName' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyType_GetSlot' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyType_GetTypeDataSize' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyType_IsSubtype' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyType_Modified' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyType_Ready' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyType_SUPPORTS_WEAKREFS' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyType_Unwatch' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyType_Watch' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicodeDecodeError_Create' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicodeDecodeError_GetEncoding' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicodeDecodeError_GetEnd' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicodeDecodeError_GetObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicodeDecodeError_GetReason' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicodeDecodeError_GetStart' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicodeDecodeError_SetEnd' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicodeDecodeError_SetReason' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicodeDecodeError_SetStart' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicodeEncodeError_GetEncoding' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicodeEncodeError_GetEnd' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicodeEncodeError_GetObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicodeEncodeError_GetReason' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicodeEncodeError_GetStart' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicodeEncodeError_SetEnd' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicodeEncodeError_SetReason' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicodeEncodeError_SetStart' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicodeTranslateError_GetEnd' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicodeTranslateError_GetObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicodeTranslateError_GetReason' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicodeTranslateError_GetStart' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicodeTranslateError_SetEnd' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicodeTranslateError_SetReason' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicodeTranslateError_SetStart' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_Append' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_AppendAndDel' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_AsASCIIString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_AsCharmapString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_AsDecodedObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_AsDecodedUnicode' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_AsEncodedObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_AsEncodedString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_AsEncodedUnicode' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_AsLatin1String' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_AsRawUnicodeEscapeString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_AsUCS4' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_AsUCS4Copy' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_AsUTF16String' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_AsUTF32String' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_AsUTF8' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_AsUTF8AndSize' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_AsUTF8String' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_AsUnicodeEscapeString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_AsWideChar' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_AsWideCharString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_BuildEncodingMap' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_Compare' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_CompareWithASCIIString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_Concat' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_Contains' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_CopyCharacters' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_Count' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_Decode' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_DecodeASCII' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_DecodeCharmap' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_DecodeFSDefault' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_DecodeFSDefaultAndSize' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_DecodeLatin1' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_DecodeLocale' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_DecodeLocaleAndSize' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_DecodeRawUnicodeEscape' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_DecodeUTF16' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_DecodeUTF16Stateful' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_DecodeUTF32' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_DecodeUTF32Stateful' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_DecodeUTF7' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_DecodeUTF7Stateful' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_DecodeUTF8' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_DecodeUTF8Stateful' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_DecodeUnicodeEscape' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_EncodeFSDefault' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_EncodeLocale' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_FSConverter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_FSDecoder' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_Fill' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_Find' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_FindChar' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_Format' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_FromEncodedObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_FromFormat' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_FromFormatV' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_FromKindAndData' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_FromObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_FromOrdinal' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_FromString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_FromStringAndSize' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_FromWideChar' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_GetDefaultEncoding' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_GetLength' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_GetSize' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_InternFromString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_InternImmortal' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_InternInPlace' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_IsIdentifier' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_Join' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_Partition' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_RPartition' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_RSplit' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_ReadChar' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_Replace' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_Resize' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_RichCompare' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_Split' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_Splitlines' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_Substring' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_Tailmatch' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_Translate' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_WriteChar' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnstable_Code_GetExtra' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnstable_Code_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnstable_Code_NewWithPosOnlyArgs' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnstable_Code_SetExtra' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnstable_Eval_RequestCodeExtraIndex' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnstable_Exc_PrepReraiseStar' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnstable_GC_VisitObjects' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnstable_InterpreterFrame_GetCode' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnstable_InterpreterFrame_GetLasti' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnstable_InterpreterFrame_GetLine' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnstable_Long_CompactValue' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnstable_Long_IsCompact' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnstable_Object_GC_NewWithExtraData' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnstable_PerfMapState_Fini' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnstable_PerfMapState_Init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnstable_Type_AssignVersionTag' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnstable_WritePerfMapEntry' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyVectorcall_Call' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyVectorcall_Function' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyVectorcall_NARGS' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyWeakref_GetObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyWeakref_NewProxy' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyWeakref_NewRef' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyWideStringList_Append' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyWideStringList_Insert' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyWrapper_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_AddPendingCall' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_AtExit' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_BuildValue' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_BytesMain' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_CompileString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_CompileStringExFlags' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_CompileStringFlags' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_CompileStringObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_DecRef' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_DecodeLocale' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_EncodeLocale' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_EndInterpreter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_EnterRecursiveCall' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_Exit' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_ExitStatusException' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_FatalError' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_FdIsInteractive' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_Finalize' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_FinalizeEx' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_FrozenMain' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_GETENV' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_GenericAlias' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_GetArgcArgv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_GetBuildInfo' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_GetCompiler' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_GetCopyright' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_GetExecPrefix' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_GetPath' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_GetPlatform' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_GetPrefix' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_GetProgramFullPath' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_GetProgramName' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_GetPythonHome' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_GetRecursionLimit' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_GetVersion' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_IncRef' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_Initialize' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_InitializeEx' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_InitializeFromConfig' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_Is' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_IsFalse' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_IsInitialized' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_IsNone' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_IsTrue' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_LeaveRecursiveCall' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_Main' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_MakePendingCalls' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_NewInterpreter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_NewInterpreterFromConfig' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_NewRef' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_PreInitialize' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_PreInitializeFromArgs' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_PreInitializeFromBytesArgs' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_ReprEnter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_ReprLeave' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_RunMain' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_SetPath' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_SetProgramName' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_SetPythonHome' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_SetRecursionLimit' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_SetStandardStreamEncoding' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_UniversalNewlineFgets' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_VaBuildValue' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_XNewRef' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyAST_Compile' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyArena_AddPyObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyArena_Free' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyArena_Malloc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyArena_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyArg_BadArgument' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyArg_CheckPositional' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyArg_NoKeywords' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyArg_NoKwnames' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyArg_NoPositional' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyArg_ParseStack' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyArg_ParseStackAndKeywords' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyArg_ParseStackAndKeywords_SizeT' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyArg_ParseStack_SizeT' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyArg_ParseTupleAndKeywordsFast' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyArg_ParseTupleAndKeywordsFast_SizeT' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyArg_ParseTupleAndKeywords_SizeT' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyArg_ParseTuple_SizeT' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyArg_Parse_SizeT' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyArg_UnpackKeywords' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyArg_UnpackKeywordsWithVararg' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyArg_UnpackStack' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyArg_VaParseTupleAndKeywordsFast' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyArg_VaParseTupleAndKeywordsFast_SizeT' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyArg_VaParseTupleAndKeywords_SizeT' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyArg_VaParse_SizeT' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyArgv_AsWstrList' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyBytesWriter_Alloc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyBytesWriter_Dealloc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyBytesWriter_Finish' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyBytesWriter_Init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyBytesWriter_Prepare' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyBytesWriter_Resize' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyBytesWriter_WriteBytes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyBytes_DecodeEscape' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyBytes_Find' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyBytes_FormatEx' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyBytes_FromHex' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyBytes_Join' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyBytes_Repeat' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyBytes_Resize' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyBytes_ReverseFind' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyCode_CheckLineNumber' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyCode_ConstantKey' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyCode_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyCode_Validate' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyCodecInfo_GetIncrementalDecoder' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyCodecInfo_GetIncrementalEncoder' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyCodec_DecodeText' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyCodec_EncodeText' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyCodec_Lookup' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyCodec_LookupTextEncoding' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyCompile_Assemble' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyCompile_CodeGen' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyCompile_OptimizeCfg' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyConfig_AsDict' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyConfig_FromDict' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyConfig_InitCompatConfig' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyContext_NewHamtForTests' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyCrossInterpreterData_Clear' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyCrossInterpreterData_Init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyCrossInterpreterData_InitWithSize' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyCrossInterpreterData_Lookup' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyCrossInterpreterData_NewObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyCrossInterpreterData_RegisterClass' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyCrossInterpreterData_Release' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyCrossInterpreterData_UnregisterClass' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyDeadline_Get' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyDeadline_Init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyDebugAllocatorStats' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyDictView_Intersect' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyDictView_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyDict_CheckConsistency' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyDict_ContainsId' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyDict_Contains_KnownHash' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyDict_DebugMallocStats' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyDict_DelItemId' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyDict_DelItemIf' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyDict_DelItem_KnownHash' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyDict_GetItemIdWithError' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyDict_GetItemStringWithError' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyDict_GetItemWithError' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyDict_GetItem_KnownHash' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyDict_HasOnlyStringKeys' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyDict_MaybeUntrack' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyDict_MergeEx' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyDict_NewPresized' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyDict_Next' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyDict_Pop' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyDict_SetItemId' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyDict_SetItem_KnownHash' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyDict_SizeOf' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyErr_BadInternalCall' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyErr_ChainExceptions' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyErr_ChainExceptions1' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyErr_ChainStackItem' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyErr_CheckSignals' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyErr_CheckSignalsTstate' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyErr_Clear' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyErr_Display' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyErr_DisplayException' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyErr_ExceptionMatches' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyErr_Fetch' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyErr_Format' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyErr_FormatFromCause' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyErr_FormatFromCauseTstate' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyErr_GetExcInfo' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyErr_GetHandledException' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyErr_GetTopmostException' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyErr_NoMemory' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyErr_NormalizeException' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyErr_Print' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyErr_ProgramDecodedTextObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyErr_Restore' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyErr_SetFromPyStatus' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyErr_SetHandledException' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyErr_SetKeyError' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyErr_SetNone' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyErr_SetObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyErr_SetString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyErr_StackItemToExcInfoTuple' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyErr_WriteUnraisableMsg' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyEval_AddPendingCall' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyEval_EvalFrameDefault' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyEval_GetBuiltin' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyEval_GetBuiltinId' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyEval_GetSwitchInterval' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyEval_MakePendingCalls' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyEval_SetProfile' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyEval_SetSwitchInterval' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyEval_SetTrace' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyEval_SignalAsyncExc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyEval_SignalReceived' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyEval_SliceIndex' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyEval_SliceIndexNotNone' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyExc_CreateExceptionGroup' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyExc_PrepReraiseStar' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyException_AddNote' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyFloat_DebugMallocStats' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyFloat_FormatAdvancedWriter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyFrame_IsEntryFrame' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyFunction_Vectorcall' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyGILState_GetInterpreterStateUnsafe' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyGen_FetchStopIterationValue' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyGen_Finalize' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyGen_SetStopIterationValue' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyImport_AcquireLock' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyImport_CheckSubinterpIncompatibleExtensionAllowed' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyImport_ClearExtension' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyImport_FixupBuiltin' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyImport_FixupExtensionObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyImport_GetModuleAttr' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyImport_GetModuleAttrString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyImport_GetModuleId' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyImport_IsInitialized' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyImport_ReleaseLock' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyImport_SetModule' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyImport_SetModuleString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyInterpreterID_LookUp' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyInterpreterID_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyInterpreterState_Enable' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyInterpreterState_GetConfig' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyInterpreterState_GetConfigCopy' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyInterpreterState_GetEvalFrameFunc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyInterpreterState_GetIDObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyInterpreterState_GetMainModule' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyInterpreterState_HasFeature' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyInterpreterState_IDDecref' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyInterpreterState_IDIncref' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyInterpreterState_IDInitref' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyInterpreterState_LookUpID' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyInterpreterState_RequireIDRef' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyInterpreterState_RequiresIDRef' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyInterpreterState_SetConfig' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyInterpreterState_SetEvalFrameFunc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyList_DebugMallocStats' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyList_Extend' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyLong_AsByteArray' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyLong_AsInt' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyLong_AsTime_t' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyLong_Copy' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyLong_DivmodNear' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyLong_FileDescriptor_Converter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyLong_Format' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyLong_FormatAdvancedWriter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyLong_FormatBytesWriter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyLong_FormatWriter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyLong_Frexp' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyLong_FromByteArray' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyLong_FromBytes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyLong_FromDigits' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyLong_FromGid' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyLong_FromTime_t' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyLong_FromUid' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyLong_GCD' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyLong_Lshift' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyLong_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyLong_NumBits' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyLong_Rshift' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyLong_Sign' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyLong_Size_t_Converter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyLong_UnsignedInt_Converter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyLong_UnsignedLongLong_Converter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyLong_UnsignedLong_Converter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyLong_UnsignedShort_Converter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyMem_GetAllocatorName' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyMem_GetCurrentAllocatorName' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyMem_RawStrdup' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyMem_RawWcsdup' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyMem_SetDefaultAllocator' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyMem_SetupAllocators' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyMem_Strdup' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyModuleSpec_IsInitializing' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyModule_Add' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyModule_Clear' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyModule_ClearDict' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyModule_CreateInitialized' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyNamespace_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyNumber_Index' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyOS_InterruptOccurred' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyOS_IsMainThread' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyOS_URandom' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyOS_URandomNonblock' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyObject_AssertFailed' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyObject_Call' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyObject_CallFunction_SizeT' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyObject_CallMethod' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyObject_CallMethodId' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyObject_CallMethodIdObjArgs' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyObject_CallMethodId_SizeT' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyObject_CallMethod_SizeT' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyObject_Call_Prepend' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyObject_CheckConsistency' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyObject_CheckCrossInterpreterData' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyObject_ClearManagedDict' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyObject_DebugMallocStats' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyObject_DebugTypeStats' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyObject_Dump' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyObject_FastCall' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyObject_FastCallDictTstate' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyObject_FunctionStr' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyObject_GC_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyObject_GC_NewVar' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyObject_GC_Resize' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyObject_GenericGetAttrWithDict' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyObject_GenericSetAttrWithDict' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyObject_GetAttrId' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyObject_GetCrossInterpreterData' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyObject_GetDictPtr' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyObject_GetMethod' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyObject_GetState' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyObject_HasLen' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyObject_IsAbstract' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyObject_IsFreed' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyObject_LookupAttr' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyObject_LookupAttrId' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyObject_LookupSpecial' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyObject_LookupSpecialId' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyObject_MakeTpCall' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyObject_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyObject_NewVar' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyObject_NextNotImplemented' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyObject_RealIsInstance' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyObject_RealIsSubclass' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyObject_SetAttrId' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyObject_VisitManagedDict' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyPathConfig_ClearGlobal' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyPreConfig_InitCompatConfig' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyRun_AnyFileObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyRun_InteractiveLoopObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyRun_SimpleFileObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyRuntimeState_Fini' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyRuntimeState_Init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyRuntime_Finalize' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyRuntime_Initialize' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PySequence_BytesToCharpArray' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PySequence_IterSearch' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PySet_NextEntry' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PySet_Update' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PySlice_FromIndices' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PySlice_GetLongIndices' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyStack_AsDict' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyState_AddModule' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyStructSequence_NewType' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PySys_GetAttr' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PySys_GetSizeOf' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyThreadState_Bind' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyThreadState_DeleteCurrent' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyThreadState_DeleteExcept' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyThreadState_GetCurrent' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyThreadState_GetDict' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyThreadState_Init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyThreadState_New' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyThreadState_Prealloc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyThreadState_Swap' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyThreadState_UncheckedGet' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyThread_CurrentExceptions' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyThread_CurrentFrames' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyThread_at_fork_reinit' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyTime_Add' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyTime_AsMicroseconds' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyTime_AsMilliseconds' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyTime_AsNanoseconds' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyTime_AsNanosecondsObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyTime_AsSecondsDouble' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyTime_AsTimespec' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyTime_AsTimespec_clamp' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyTime_AsTimeval' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyTime_AsTimevalTime_t' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyTime_AsTimeval_clamp' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyTime_FromMicrosecondsClamp' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyTime_FromMillisecondsObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyTime_FromNanoseconds' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyTime_FromNanosecondsObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyTime_FromSeconds' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyTime_FromSecondsObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyTime_FromTimespec' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyTime_FromTimeval' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyTime_GetMonotonicClock' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyTime_GetMonotonicClockWithInfo' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyTime_GetPerfCounter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyTime_GetPerfCounterWithInfo' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyTime_GetSystemClock' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyTime_GetSystemClockWithInfo' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyTime_MulDiv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyTime_ObjectToTime_t' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyTime_ObjectToTimespec' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyTime_ObjectToTimeval' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyTime_gmtime' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyTime_localtime' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyToken_OneChar' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyToken_ThreeChars' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyToken_TwoChars' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyTraceBack_FromFrame' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyTraceBack_Print_Indented' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyTraceMalloc_ClearTraces' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyTraceMalloc_GetMemory' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyTraceMalloc_GetObjectTraceback' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyTraceMalloc_GetTraceback' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyTraceMalloc_GetTracebackLimit' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyTraceMalloc_GetTracedMemory' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyTraceMalloc_GetTraces' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyTraceMalloc_Init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyTraceMalloc_IsTracing' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyTraceMalloc_ResetPeak' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyTraceMalloc_Start' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyTraceMalloc_Stop' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyTraceback_Add' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyTrash_begin' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyTrash_cond' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyTrash_end' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyTuple_DebugMallocStats' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyTuple_MaybeUntrack' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyTuple_Resize' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyType_CalculateMetaclass' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyType_CheckConsistency' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyType_GetDict' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyType_GetDocFromInternalDoc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyType_GetTextSignatureFromInternalDoc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyType_Lookup' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyType_LookupId' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyType_Name' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyUnicodeTranslateError_Create' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyUnicodeWriter_Dealloc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyUnicodeWriter_Finish' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyUnicodeWriter_Init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyUnicodeWriter_PrepareInternal' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyUnicodeWriter_PrepareKindInternal' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyUnicodeWriter_WriteASCIIString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyUnicodeWriter_WriteChar' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyUnicodeWriter_WriteLatin1String' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyUnicodeWriter_WriteStr' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyUnicodeWriter_WriteSubstring' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyUnicode_AsASCIIString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyUnicode_AsLatin1String' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyUnicode_AsUTF8String' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyUnicode_CheckConsistency' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyUnicode_Copy' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyUnicode_DecodeRawUnicodeEscapeStateful' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyUnicode_DecodeUnicodeEscapeInternal' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyUnicode_DecodeUnicodeEscapeStateful' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyUnicode_EQ' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyUnicode_EncodeCharmap' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyUnicode_EncodeUTF16' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyUnicode_EncodeUTF32' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyUnicode_EncodeUTF7' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyUnicode_Equal' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyUnicode_EqualToASCIIId' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyUnicode_EqualToASCIIString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyUnicode_FastCopyCharacters' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyUnicode_FastFill' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyUnicode_FindMaxChar' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyUnicode_FormatAdvancedWriter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyUnicode_FormatLong' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyUnicode_FromASCII' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyUnicode_FromId' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyUnicode_InsertThousandsGrouping' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyUnicode_IsAlpha' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyUnicode_IsCaseIgnorable' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyUnicode_IsCased' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyUnicode_IsDecimalDigit' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyUnicode_IsDigit' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyUnicode_IsLinebreak' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyUnicode_IsLowercase' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyUnicode_IsNumeric' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyUnicode_IsPrintable' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyUnicode_IsTitlecase' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyUnicode_IsUppercase' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyUnicode_IsWhitespace' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyUnicode_IsXidContinue' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyUnicode_IsXidStart' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyUnicode_JoinArray' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyUnicode_ScanIdentifier' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyUnicode_ToDecimalDigit' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyUnicode_ToDigit' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyUnicode_ToFoldedFull' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyUnicode_ToLowerFull' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyUnicode_ToLowercase' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyUnicode_ToNumeric' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyUnicode_ToTitleFull' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyUnicode_ToTitlecase' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyUnicode_ToUpperFull' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyUnicode_ToUppercase' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyUnicode_TransformDecimalAndSpaceToASCII' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyUnicode_WideCharString_Converter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyUnicode_WideCharString_Opt_Converter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyUnicode_XStrip' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyWarnings_Init' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyWeakref_ClearRef' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyWeakref_GetWeakrefCount' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyWideStringList_AsList' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyWideStringList_Clear' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyWideStringList_Copy' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyWideStringList_Extend' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_AtExit' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_BreakPoint' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_BuildValue_SizeT' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_CheckFunctionResult' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_CheckRecursiveCall' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_ClearArgcArgv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_ClearStandardStreamEncoding' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_CoerceLegacyLocale' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_Dealloc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_DecRef' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_DecodeLocaleEx' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_DecodeUTF8Ex' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_DecodeUTF8_surrogateescape' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_DisplaySourceLine' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_DumpASCII' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_DumpDecimal' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_DumpExtensionModules' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_DumpHexadecimal' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_DumpTraceback' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_DumpTracebackThreads' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_EncodeLocaleEx' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_EncodeLocaleRaw' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_EncodeUTF8Ex' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_FatalErrorFormat' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_FatalErrorFunc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_FatalRefcountErrorFunc' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_FdIsInteractive' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_FreeCharPArray' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_GetConfig' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_GetConfigsAsDict' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_GetEnv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_GetErrorHandler' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_GetForceASCII' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_GetLocaleEncoding' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_GetLocaleEncodingObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_GetLocaleconvNumeric' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_Get_Getpath_CodeObject' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_Gid_Converter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_HandleSystemExit' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_HashBytes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_HashDouble' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_HashPointer' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_HashPointerRaw' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_IncRef' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_InitializeMain' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_IsCoreInitialized' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_IsFinalizing' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_IsInterpreterFinalizing' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_IsLocaleCoercionTarget' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_LegacyLocaleDetected' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_NewReference' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_NewReferenceNoTotal' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_PreInitializeFromConfig' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_PreInitializeFromPyArgv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_ResetForceASCII' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_RestoreSignals' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_SetLocaleFromEnv' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_SetProgramFullPath' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_Sigset_Converter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_SourceAsString' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_UTF8_Edit_Cost' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_Uid_Converter' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_UniversalNewlineFgetsWithSize' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_VaBuildStack' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_VaBuildStack_SizeT' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_VaBuildValue_SizeT' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_WriteIndent' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_WriteIndentedMargin' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_add_one_to_index_C' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_add_one_to_index_F' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_c_abs' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_c_diff' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_c_neg' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_c_pow' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_c_prod' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_c_quot' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_c_sum' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_closerange' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_convert_optional_to_ssize_t' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_device_encoding' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_dg_dtoa' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_dg_freedtoa' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_dg_strtod' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_dup' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_fopen_obj' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_fstat' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_fstat_noraise' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_get_blocking' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_get_env_flag' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_get_inheritable' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_get_xoption' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_gitidentifier' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_gitversion' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_hashtable_clear' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_hashtable_compare_direct' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_hashtable_destroy' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_hashtable_foreach' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_hashtable_get' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_hashtable_hash_ptr' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_hashtable_new' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_hashtable_new_full' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_hashtable_set' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_hashtable_size' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_hashtable_steal' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_normpath' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_open' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_open_noraise' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_parse_inf_or_nan' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_read' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_set_blocking' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_set_inheritable' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_set_inheritable_async_safe' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_stat' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_str_to_int' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_strhex' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_strhex_bytes' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_strhex_bytes_with_sep' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_strhex_with_sep' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_string_to_number_with_underscores' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_wfopen' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_wgetcwd' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_wreadlink' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_wrealpath' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_write' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_write_noraise' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + </elf-function-symbols> + <elf-variable-symbols> + <elf-symbol name='PyAsyncGen_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyBaseObject_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyBool_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyByteArrayIter_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyByteArray_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyBytesIter_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyBytes_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyCFunction_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyCMethod_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyCallIter_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyCapsule_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyCell_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyClassMethodDescr_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyClassMethod_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyCode_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyComplex_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyContextToken_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyContextVar_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyContext_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyCoro_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyDictItems_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyDictIterItem_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyDictIterKey_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyDictIterValue_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyDictKeys_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyDictProxy_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyDictRevIterItem_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyDictRevIterKey_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyDictRevIterValue_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyDictValues_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyDict_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyEllipsis_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyEnum_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExc_ArithmeticError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExc_AssertionError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExc_AttributeError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExc_BaseException' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExc_BaseExceptionGroup' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExc_BlockingIOError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExc_BrokenPipeError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExc_BufferError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExc_BytesWarning' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExc_ChildProcessError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExc_ConnectionAbortedError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExc_ConnectionError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExc_ConnectionRefusedError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExc_ConnectionResetError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExc_DeprecationWarning' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExc_EOFError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExc_EncodingWarning' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExc_EnvironmentError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExc_Exception' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExc_FileExistsError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExc_FileNotFoundError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExc_FloatingPointError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExc_FutureWarning' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExc_GeneratorExit' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExc_IOError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExc_ImportError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExc_ImportWarning' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExc_IndentationError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExc_IndexError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExc_InterruptedError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExc_IsADirectoryError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExc_KeyError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExc_KeyboardInterrupt' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExc_LookupError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExc_MemoryError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExc_ModuleNotFoundError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExc_NameError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExc_NotADirectoryError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExc_NotImplementedError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExc_OSError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExc_OverflowError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExc_PendingDeprecationWarning' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExc_PermissionError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExc_ProcessLookupError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExc_RecursionError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExc_ReferenceError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExc_ResourceWarning' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExc_RuntimeError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExc_RuntimeWarning' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExc_StopAsyncIteration' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExc_StopIteration' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExc_SyntaxError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExc_SyntaxWarning' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExc_SystemError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExc_SystemExit' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExc_TabError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExc_TimeoutError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExc_TypeError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExc_UnboundLocalError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExc_UnicodeDecodeError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExc_UnicodeEncodeError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExc_UnicodeError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExc_UnicodeTranslateError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExc_UnicodeWarning' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExc_UserWarning' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExc_ValueError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExc_Warning' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyExc_ZeroDivisionError' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyFilter_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyFloat_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyFrame_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyFrozenSet_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyFunction_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyGen_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyGetSetDescr_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyImport_FrozenModules' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyImport_Inittab' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyInstanceMethod_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyListIter_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyListRevIter_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyList_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyLongRangeIter_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyLong_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyMap_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyMemberDescr_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyMemoryView_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyMethodDescr_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyMethod_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyModuleDef_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyModule_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyODictItems_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyODictIter_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyODictKeys_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyODictValues_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyODict_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyOS_InputHook' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyOS_ReadlineFunctionPointer' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyPickleBuffer_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyProperty_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyRangeIter_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyRange_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyReversed_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PySeqIter_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PySetIter_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PySet_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PySlice_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyStaticMethod_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyStdPrinter_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyStructSequence_UnnamedField' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PySuper_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyTraceBack_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyTupleIter_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyTuple_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyType_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicodeIter_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyUnicode_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyWrapperDescr_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='PyZip_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_BytesWarningFlag' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_DebugFlag' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_DontWriteBytecodeFlag' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_FileSystemDefaultEncodeErrors' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_FileSystemDefaultEncoding' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_FrozenFlag' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_GenericAliasType' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_HasFileSystemDefaultEncoding' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_HashRandomizationFlag' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_IgnoreEnvironmentFlag' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_InspectFlag' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_InteractiveFlag' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_IsolatedFlag' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_NoSiteFlag' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_NoUserSiteDirectory' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_OptimizeFlag' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_QuietFlag' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_UTF8Mode' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_UnbufferedStdioFlag' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_VerboseFlag' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_Version' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='Py_hexdigits' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyAsyncGenASend_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyAsyncGenAThrow_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyAsyncGenWrappedValue_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyBufferWrapper_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyByteArray_empty_string' size='1' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyCoroWrapper_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyImport_FrozenBootstrap' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyImport_FrozenStdlib' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyImport_FrozenTest' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyInterpreterID_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyLong_DigitValue' size='256' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyManagedBuffer_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyMethodWrapper_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyNamespace_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyNone_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyNotImplemented_Type' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyOS_ReadlineTState' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyParser_TokenNames' size='552' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyRuntime' size='459888' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PySet_Dummy' size='8' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyWeakref_CallableProxyType' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyWeakref_ProxyType' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_PyWeakref_RefType' size='416' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_EllipsisObject' size='16' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_FalseStruct' size='32' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_HasFileSystemDefaultEncodeErrors' size='4' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_HashSecret' size='24' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_NoneStruct' size='16' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_NotImplementedStruct' size='16' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_SwappedOp' size='24' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_TrueStruct' size='32' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_ascii_whitespace' size='128' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_ctype_table' size='1024' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_ctype_tolower' size='256' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + <elf-symbol name='_Py_ctype_toupper' size='256' type='object-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/> + </elf-variable-symbols> + <abi-instr address-size='64' path='./Modules/_abc.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <function-decl name='_PyType_GetMRO' filepath='./Include/internal/pycore_typeobject.h' line='119' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyType_GetSubclasses' filepath='./Include/internal/pycore_typeobject.h' line='120' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1'/> + <return type-id='type-id-2'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='./Modules/_io/_iomodule.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <var-decl name='_PyIO_Module' type-id='type-id-3' visibility='default' filepath='./Modules/_io/_iomodule.h' line='143' column='1'/> + </abi-instr> + <abi-instr address-size='64' path='./Modules/_io/bufferedio.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <typedef-decl name='_PyIO_State' type-id='type-id-4' filepath='./Modules/_io/_iomodule.h' line='35' column='1' id='type-id-5'/> + <typedef-decl name='Py_off_t' type-id='type-id-6' filepath='./Modules/_io/_iomodule.h' line='109' column='1' id='type-id-7'/> + <class-decl name='_io_state' size-in-bits='1024' is-struct='yes' visibility='default' filepath='./Modules/_io/_iomodule.h' line='145' column='1' id='type-id-4'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='initialized' type-id='type-id-8' visibility='default' filepath='./Modules/_io/_iomodule.h' line='146' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='unsupported_operation' type-id='type-id-2' visibility='default' filepath='./Modules/_io/_iomodule.h' line='147' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='PyIOBase_Type' type-id='type-id-1' visibility='default' filepath='./Modules/_io/_iomodule.h' line='150' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='PyIncrementalNewlineDecoder_Type' type-id='type-id-1' visibility='default' filepath='./Modules/_io/_iomodule.h' line='151' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='PyRawIOBase_Type' type-id='type-id-1' visibility='default' filepath='./Modules/_io/_iomodule.h' line='152' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='PyBufferedIOBase_Type' type-id='type-id-1' visibility='default' filepath='./Modules/_io/_iomodule.h' line='153' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='384'> + <var-decl name='PyBufferedRWPair_Type' type-id='type-id-1' visibility='default' filepath='./Modules/_io/_iomodule.h' line='154' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='448'> + <var-decl name='PyBufferedRandom_Type' type-id='type-id-1' visibility='default' filepath='./Modules/_io/_iomodule.h' line='155' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='512'> + <var-decl name='PyBufferedReader_Type' type-id='type-id-1' visibility='default' filepath='./Modules/_io/_iomodule.h' line='156' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='576'> + <var-decl name='PyBufferedWriter_Type' type-id='type-id-1' visibility='default' filepath='./Modules/_io/_iomodule.h' line='157' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='640'> + <var-decl name='PyBytesIOBuffer_Type' type-id='type-id-1' visibility='default' filepath='./Modules/_io/_iomodule.h' line='158' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='704'> + <var-decl name='PyBytesIO_Type' type-id='type-id-1' visibility='default' filepath='./Modules/_io/_iomodule.h' line='159' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='768'> + <var-decl name='PyFileIO_Type' type-id='type-id-1' visibility='default' filepath='./Modules/_io/_iomodule.h' line='160' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='832'> + <var-decl name='PyStringIO_Type' type-id='type-id-1' visibility='default' filepath='./Modules/_io/_iomodule.h' line='161' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='896'> + <var-decl name='PyTextIOBase_Type' type-id='type-id-1' visibility='default' filepath='./Modules/_io/_iomodule.h' line='162' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='960'> + <var-decl name='PyTextIOWrapper_Type' type-id='type-id-1' visibility='default' filepath='./Modules/_io/_iomodule.h' line='163' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='off_t' type-id='type-id-9' filepath='/usr/include/x86_64-linux-gnu/sys/types.h' line='87' column='1' id='type-id-6'/> + <pointer-type-def type-id='type-id-5' size-in-bits='64' id='type-id-10'/> + <var-decl name='bufferediobase_spec' type-id='type-id-11' visibility='default' filepath='./Modules/_io/_iomodule.h' line='12' column='1'/> + <var-decl name='bufferedrandom_spec' type-id='type-id-11' visibility='default' filepath='./Modules/_io/_iomodule.h' line='13' column='1'/> + <var-decl name='bufferedreader_spec' type-id='type-id-11' visibility='default' filepath='./Modules/_io/_iomodule.h' line='14' column='1'/> + <var-decl name='bufferedrwpair_spec' type-id='type-id-11' visibility='default' filepath='./Modules/_io/_iomodule.h' line='15' column='1'/> + <var-decl name='bufferedwriter_spec' type-id='type-id-11' visibility='default' filepath='./Modules/_io/_iomodule.h' line='16' column='1'/> + <function-decl name='_PyIOBase_check_readable' filepath='./Modules/_io/_iomodule.h' line='36' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-10'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyIOBase_check_writable' filepath='./Modules/_io/_iomodule.h' line='38' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-10'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyIOBase_check_seekable' filepath='./Modules/_io/_iomodule.h' line='40' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-10'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyFileIO_closed' filepath='./Modules/_io/_iomodule.h' line='52' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyNumber_AsOff_t' filepath='./Modules/_io/_iomodule.h' line='137' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-7'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='./Modules/_io/bytesio.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <var-decl name='bytesio_spec' type-id='type-id-11' visibility='default' filepath='./Modules/_io/_iomodule.h' line='17' column='1'/> + <var-decl name='bytesiobuf_spec' type-id='type-id-11' visibility='default' filepath='./Modules/_io/_iomodule.h' line='18' column='1'/> + </abi-instr> + <abi-instr address-size='64' path='./Modules/_io/fileio.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <var-decl name='fileio_spec' type-id='type-id-11' visibility='default' filepath='./Modules/_io/_iomodule.h' line='19' column='1'/> + <function-decl name='_PyIOBase_finalize' filepath='./Modules/_io/_iomodule.h' line='48' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyIOBase_cannot_pickle' filepath='./Modules/_io/_iomodule.h' line='193' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='./Modules/_io/iobase.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <var-decl name='iobase_spec' type-id='type-id-11' visibility='default' filepath='./Modules/_io/_iomodule.h' line='20' column='1'/> + <var-decl name='rawiobase_spec' type-id='type-id-11' visibility='default' filepath='./Modules/_io/_iomodule.h' line='22' column='1'/> + <function-decl name='_PyIO_trap_eintr' filepath='./Modules/_io/_iomodule.h' line='79' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-8'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='./Modules/_io/stringio.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <var-decl name='stringio_spec' type-id='type-id-11' visibility='default' filepath='./Modules/_io/_iomodule.h' line='23' column='1'/> + <function-decl name='_PyIncrementalNewlineDecoder_decode' filepath='./Modules/_io/_iomodule.h' line='55' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyIO_find_line_ending' filepath='./Modules/_io/_iomodule.h' line='71' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-13'/> + <return type-id='type-id-14'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='./Modules/_io/textio.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <var-decl name='nldecoder_spec' type-id='type-id-11' visibility='default' filepath='./Modules/_io/_iomodule.h' line='21' column='1'/> + <var-decl name='textiobase_spec' type-id='type-id-11' visibility='default' filepath='./Modules/_io/_iomodule.h' line='24' column='1'/> + <var-decl name='textiowrapper_spec' type-id='type-id-11' visibility='default' filepath='./Modules/_io/_iomodule.h' line='25' column='1'/> + <function-decl name='_PyIOBase_check_closed' filepath='./Modules/_io/_iomodule.h' line='42' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='./Modules/_localemodule.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <function-decl name='gettext' filepath='/usr/include/libintl.h' line='39' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <return type-id='type-id-15'/> + </function-decl> + <function-decl name='dgettext' filepath='/usr/include/libintl.h' line='44' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-12'/> + <return type-id='type-id-15'/> + </function-decl> + <function-decl name='dcgettext' filepath='/usr/include/libintl.h' line='51' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-15'/> + </function-decl> + <function-decl name='textdomain' filepath='/usr/include/libintl.h' line='82' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <return type-id='type-id-15'/> + </function-decl> + <function-decl name='bindtextdomain' filepath='/usr/include/libintl.h' line='86' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-12'/> + <return type-id='type-id-15'/> + </function-decl> + <function-decl name='bind_textdomain_codeset' filepath='/usr/include/libintl.h' line='91' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-12'/> + <return type-id='type-id-15'/> + </function-decl> + <function-decl name='wcscoll' filepath='/usr/include/wchar.h' line='131' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-16'/> + <parameter type-id='type-id-16'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='wcsxfrm' filepath='/usr/include/wchar.h' line='135' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-17'/> + <parameter type-id='type-id-18'/> + <parameter type-id='type-id-19'/> + <return type-id='type-id-19'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='./Modules/_sre/sre.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <function-decl name='toupper' filepath='/usr/include/ctype.h' line='125' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <return type-id='type-id-8'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='./Modules/atexitmodule.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <function-decl name='_Py_AtExit' mangled-name='_Py_AtExit' filepath='./Modules/atexitmodule.c' line='27' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_AtExit'> + <parameter type-id='type-id-20' name='interp' filepath='./Modules/atexitmodule.c' line='27' column='1'/> + <parameter type-id='type-id-21' name='func' filepath='./Modules/atexitmodule.c' line='28' column='1'/> + <parameter type-id='type-id-22' name='data' filepath='./Modules/atexitmodule.c' line='28' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='./Modules/faulthandler.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <enum-decl name='__rlimit_resource' filepath='/usr/include/x86_64-linux-gnu/bits/resource.h' line='31' column='1' id='type-id-23'> + <underlying-type type-id='type-id-24'/> + <enumerator name='RLIMIT_CPU' value='0'/> + <enumerator name='RLIMIT_FSIZE' value='1'/> + <enumerator name='RLIMIT_DATA' value='2'/> + <enumerator name='RLIMIT_STACK' value='3'/> + <enumerator name='RLIMIT_CORE' value='4'/> + <enumerator name='__RLIMIT_RSS' value='5'/> + <enumerator name='RLIMIT_NOFILE' value='7'/> + <enumerator name='__RLIMIT_OFILE' value='7'/> + <enumerator name='RLIMIT_AS' value='9'/> + <enumerator name='__RLIMIT_NPROC' value='6'/> + <enumerator name='__RLIMIT_MEMLOCK' value='8'/> + <enumerator name='__RLIMIT_LOCKS' value='10'/> + <enumerator name='__RLIMIT_SIGPENDING' value='11'/> + <enumerator name='__RLIMIT_MSGQUEUE' value='12'/> + <enumerator name='__RLIMIT_NICE' value='13'/> + <enumerator name='__RLIMIT_RTPRIO' value='14'/> + <enumerator name='__RLIMIT_RTTIME' value='15'/> + <enumerator name='__RLIMIT_NLIMITS' value='16'/> + <enumerator name='__RLIM_NLIMITS' value='16'/> + </enum-decl> + <typedef-decl name='rlim_t' type-id='type-id-25' filepath='/usr/include/x86_64-linux-gnu/bits/resource.h' line='133' column='1' id='type-id-26'/> + <class-decl name='rlimit' size-in-bits='128' is-struct='yes' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/resource.h' line='139' column='1' id='type-id-27'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='rlim_cur' type-id='type-id-26' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/resource.h' line='142' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='rlim_max' type-id='type-id-26' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/resource.h' line='144' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='__rlim64_t' type-id='type-id-28' filepath='/usr/include/x86_64-linux-gnu/bits/types.h' line='158' column='1' id='type-id-25'/> + <typedef-decl name='__rlimit_resource_t' type-id='type-id-23' filepath='/usr/include/x86_64-linux-gnu/sys/resource.h' line='38' column='1' id='type-id-29'/> + <pointer-type-def type-id='type-id-30' size-in-bits='64' id='type-id-31'/> + <qualified-type-def type-id='type-id-31' restrict='yes' id='type-id-32'/> + <qualified-type-def type-id='type-id-30' const='yes' id='type-id-33'/> + <pointer-type-def type-id='type-id-33' size-in-bits='64' id='type-id-34'/> + <qualified-type-def type-id='type-id-34' restrict='yes' id='type-id-35'/> + <qualified-type-def type-id='type-id-27' const='yes' id='type-id-36'/> + <pointer-type-def type-id='type-id-36' size-in-bits='64' id='type-id-37'/> + <qualified-type-def type-id='type-id-38' const='yes' id='type-id-39'/> + <pointer-type-def type-id='type-id-39' size-in-bits='64' id='type-id-40'/> + <qualified-type-def type-id='type-id-40' restrict='yes' id='type-id-41'/> + <pointer-type-def type-id='type-id-27' size-in-bits='64' id='type-id-42'/> + <pointer-type-def type-id='type-id-38' size-in-bits='64' id='type-id-43'/> + <qualified-type-def type-id='type-id-43' restrict='yes' id='type-id-44'/> + <function-decl name='raise' filepath='/usr/include/signal.h' line='123' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='sigfillset' filepath='/usr/include/signal.h' line='202' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-45'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='sigaltstack' filepath='/usr/include/signal.h' line='333' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-41'/> + <parameter type-id='type-id-44'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_exit' filepath='/usr/include/unistd.h' line='624' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='sysconf' filepath='/usr/include/unistd.h' line='640' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <return type-id='type-id-47'/> + </function-decl> + <function-decl name='pthread_sigmask' filepath='/usr/include/x86_64-linux-gnu/bits/sigthread.h' line='31' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-35'/> + <parameter type-id='type-id-32'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='getauxval' filepath='/usr/include/x86_64-linux-gnu/sys/auxv.h' line='31' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-28'/> + <return type-id='type-id-28'/> + </function-decl> + <type-decl name='unsigned long int' size-in-bits='64' id='type-id-28'/> + </abi-instr> + <abi-instr address-size='64' path='./Modules/getbuildinfo.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <type-decl name='char' size-in-bits='8' id='type-id-48'/> + <type-decl name='int' size-in-bits='32' id='type-id-8'/> + <type-decl name='unsigned long int' size-in-bits='64' id='type-id-28'/> + <type-decl name='variadic parameter type' id='type-id-49'/> + <typedef-decl name='size_t' type-id='type-id-28' filepath='/usr/lib/gcc/x86_64-linux-gnu/11/include/stddef.h' line='209' column='1' id='type-id-19'/> + <pointer-type-def type-id='type-id-48' size-in-bits='64' id='type-id-15'/> + <qualified-type-def type-id='type-id-48' const='yes' id='type-id-50'/> + <pointer-type-def type-id='type-id-50' size-in-bits='64' id='type-id-12'/> + <function-decl name='PyOS_snprintf' mangled-name='PyOS_snprintf' filepath='./Include/pyerrors.h' line='323' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyOS_snprintf'> + <parameter type-id='type-id-15'/> + <parameter type-id='type-id-19'/> + <parameter type-id='type-id-12'/> + <parameter is-variadic='yes'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='Py_GetBuildInfo' mangled-name='Py_GetBuildInfo' filepath='./Modules/getbuildinfo.c' line='40' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_GetBuildInfo'> + <return type-id='type-id-12'/> + </function-decl> + <function-decl name='_Py_gitversion' mangled-name='_Py_gitversion' filepath='./Modules/getbuildinfo.c' line='59' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_gitversion'> + <return type-id='type-id-12'/> + </function-decl> + <function-decl name='_Py_gitidentifier' mangled-name='_Py_gitidentifier' filepath='./Modules/getbuildinfo.c' line='65' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_gitidentifier'> + <return type-id='type-id-12'/> + </function-decl> + <function-decl name='strcmp' filepath='/usr/include/string.h' line='156' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-12'/> + <return type-id='type-id-8'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='./Modules/getpath.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <function-decl name='_Py_wstat' filepath='./Include/internal/pycore_fileutils.h' line='210' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-16'/> + <parameter type-id='type-id-51'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_Py_join_relfile' filepath='./Include/internal/pycore_fileutils.h' line='249' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-16'/> + <parameter type-id='type-id-16'/> + <return type-id='type-id-52'/> + </function-decl> + <function-decl name='_Py_add_relfile' filepath='./Include/internal/pycore_fileutils.h' line='251' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-52'/> + <parameter type-id='type-id-16'/> + <parameter type-id='type-id-19'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyPathConfig_ReadGlobal' filepath='./Include/internal/pycore_pathconfig.h' line='12' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-53'/> + <return type-id='type-id-54'/> + </function-decl> + <function-decl name='_PyPathConfig_GetGlobalModuleSearchPath' filepath='./Include/internal/pycore_pathconfig.h' line='14' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-16'/> + </function-decl> + <function-decl name='_Py_Get_Getpath_CodeObject' mangled-name='_Py_Get_Getpath_CodeObject' filepath='./Modules/getpath.c' line='791' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_Get_Getpath_CodeObject'> + <return type-id='type-id-2'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='./Modules/posixmodule.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <array-type-def dimensions='1' type-id='type-id-55' size-in-bits='1024' id='type-id-56'> + <subrange length='16' type-id='type-id-28' id='type-id-57'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-58' size-in-bits='256' id='type-id-59'> + <subrange length='32' type-id='type-id-28' id='type-id-60'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-48' size-in-bits='2048' id='type-id-61'> + <subrange length='256' type-id='type-id-28' id='type-id-62'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-48' size-in-bits='520' id='type-id-63'> + <subrange length='65' type-id='type-id-28' id='type-id-64'/> + </array-type-def> + <class-decl name='__dirstream' is-struct='yes' visibility='default' is-declaration-only='yes' id='type-id-65'/> + <class-decl name='__spawn_action' is-struct='yes' visibility='default' is-declaration-only='yes' id='type-id-66'/> + <array-type-def dimensions='1' type-id='type-id-8' size-in-bits='512' id='type-id-67'> + <subrange length='16' type-id='type-id-28' id='type-id-57'/> + </array-type-def> + <typedef-decl name='DIR' type-id='type-id-65' filepath='/usr/include/dirent.h' line='127' column='1' id='type-id-68'/> + <class-decl name='posix_spawnattr_t' size-in-bits='2688' is-struct='yes' naming-typedef-id='type-id-69' visibility='default' filepath='/usr/include/spawn.h' line='29' column='1' id='type-id-70'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='__flags' type-id='type-id-71' visibility='default' filepath='/usr/include/spawn.h' line='31' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='32'> + <var-decl name='__pgrp' type-id='type-id-72' visibility='default' filepath='/usr/include/spawn.h' line='32' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='__sd' type-id='type-id-73' visibility='default' filepath='/usr/include/spawn.h' line='33' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1088'> + <var-decl name='__ss' type-id='type-id-73' visibility='default' filepath='/usr/include/spawn.h' line='34' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2112'> + <var-decl name='__sp' type-id='type-id-74' visibility='default' filepath='/usr/include/spawn.h' line='35' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2144'> + <var-decl name='__policy' type-id='type-id-8' visibility='default' filepath='/usr/include/spawn.h' line='36' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2176'> + <var-decl name='__pad' type-id='type-id-67' visibility='default' filepath='/usr/include/spawn.h' line='37' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='posix_spawnattr_t' type-id='type-id-70' filepath='/usr/include/spawn.h' line='38' column='1' id='type-id-69'/> + <class-decl name='posix_spawn_file_actions_t' size-in-bits='640' is-struct='yes' naming-typedef-id='type-id-75' visibility='default' filepath='/usr/include/spawn.h' line='43' column='1' id='type-id-76'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='__allocated' type-id='type-id-8' visibility='default' filepath='/usr/include/spawn.h' line='45' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='32'> + <var-decl name='__used' type-id='type-id-8' visibility='default' filepath='/usr/include/spawn.h' line='46' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='__actions' type-id='type-id-77' visibility='default' filepath='/usr/include/spawn.h' line='47' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='__pad' type-id='type-id-67' visibility='default' filepath='/usr/include/spawn.h' line='48' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='posix_spawn_file_actions_t' type-id='type-id-76' filepath='/usr/include/spawn.h' line='49' column='1' id='type-id-75'/> + <typedef-decl name='__compar_fn_t' type-id='type-id-78' filepath='/usr/include/stdlib.h' line='816' column='1' id='type-id-79'/> + <typedef-decl name='__cpu_mask' type-id='type-id-28' filepath='/usr/include/x86_64-linux-gnu/bits/cpu-set.h' line='32' column='1' id='type-id-55'/> + <class-decl name='cpu_set_t' size-in-bits='1024' is-struct='yes' naming-typedef-id='type-id-80' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/cpu-set.h' line='39' column='1' id='type-id-81'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='__bits' type-id='type-id-56' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/cpu-set.h' line='41' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='cpu_set_t' type-id='type-id-81' filepath='/usr/include/x86_64-linux-gnu/bits/cpu-set.h' line='42' column='1' id='type-id-80'/> + <class-decl name='dirent' size-in-bits='2240' is-struct='yes' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/dirent.h' line='22' column='1' id='type-id-82'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='d_ino' type-id='type-id-83' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/dirent.h' line='28' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='d_off' type-id='type-id-9' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/dirent.h' line='29' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='d_reclen' type-id='type-id-84' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/dirent.h' line='31' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='144'> + <var-decl name='d_type' type-id='type-id-85' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/dirent.h' line='32' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='152'> + <var-decl name='d_name' type-id='type-id-61' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/dirent.h' line='33' column='1'/> + </data-member> + </class-decl> + <class-decl name='winsize' size-in-bits='64' is-struct='yes' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/ioctl-types.h' line='27' column='1' id='type-id-86'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='ws_row' type-id='type-id-84' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/ioctl-types.h' line='29' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='16'> + <var-decl name='ws_col' type-id='type-id-84' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/ioctl-types.h' line='30' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='32'> + <var-decl name='ws_xpixel' type-id='type-id-84' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/ioctl-types.h' line='31' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='48'> + <var-decl name='ws_ypixel' type-id='type-id-84' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/ioctl-types.h' line='32' column='1'/> + </data-member> + </class-decl> + <enum-decl name='__priority_which' filepath='/usr/include/x86_64-linux-gnu/bits/resource.h' line='187' column='1' id='type-id-87'> + <underlying-type type-id='type-id-24'/> + <enumerator name='PRIO_PROCESS' value='0'/> + <enumerator name='PRIO_PGRP' value='1'/> + <enumerator name='PRIO_USER' value='2'/> + </enum-decl> + <class-decl name='statvfs' size-in-bits='896' is-struct='yes' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/statvfs.h' line='29' column='1' id='type-id-88'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='f_bsize' type-id='type-id-28' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/statvfs.h' line='31' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='f_frsize' type-id='type-id-28' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/statvfs.h' line='32' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='f_blocks' type-id='type-id-89' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/statvfs.h' line='41' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='f_bfree' type-id='type-id-89' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/statvfs.h' line='42' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='f_bavail' type-id='type-id-89' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/statvfs.h' line='43' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='f_files' type-id='type-id-90' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/statvfs.h' line='44' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='384'> + <var-decl name='f_ffree' type-id='type-id-90' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/statvfs.h' line='45' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='448'> + <var-decl name='f_favail' type-id='type-id-90' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/statvfs.h' line='46' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='512'> + <var-decl name='f_fsid' type-id='type-id-28' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/statvfs.h' line='48' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='576'> + <var-decl name='f_flag' type-id='type-id-28' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/statvfs.h' line='52' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='640'> + <var-decl name='f_namemax' type-id='type-id-28' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/statvfs.h' line='53' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='704'> + <var-decl name='__f_spare' type-id='type-id-91' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/statvfs.h' line='54' column='1'/> + </data-member> + </class-decl> + <class-decl name='termios' size-in-bits='480' is-struct='yes' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/termios-struct.h' line='24' column='1' id='type-id-92'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='c_iflag' type-id='type-id-93' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/termios-struct.h' line='26' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='32'> + <var-decl name='c_oflag' type-id='type-id-93' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/termios-struct.h' line='27' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='c_cflag' type-id='type-id-93' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/termios-struct.h' line='28' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='96'> + <var-decl name='c_lflag' type-id='type-id-93' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/termios-struct.h' line='29' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='c_line' type-id='type-id-58' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/termios-struct.h' line='30' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='136'> + <var-decl name='c_cc' type-id='type-id-59' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/termios-struct.h' line='31' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='416'> + <var-decl name='c_ispeed' type-id='type-id-94' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/termios-struct.h' line='32' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='448'> + <var-decl name='c_ospeed' type-id='type-id-94' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/termios-struct.h' line='33' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='cc_t' type-id='type-id-85' filepath='/usr/include/x86_64-linux-gnu/bits/termios.h' line='23' column='1' id='type-id-58'/> + <typedef-decl name='speed_t' type-id='type-id-95' filepath='/usr/include/x86_64-linux-gnu/bits/termios.h' line='24' column='1' id='type-id-94'/> + <typedef-decl name='tcflag_t' type-id='type-id-95' filepath='/usr/include/x86_64-linux-gnu/bits/termios.h' line='25' column='1' id='type-id-93'/> + <typedef-decl name='__id_t' type-id='type-id-95' filepath='/usr/include/x86_64-linux-gnu/bits/types.h' line='159' column='1' id='type-id-96'/> + <typedef-decl name='__fsblkcnt64_t' type-id='type-id-28' filepath='/usr/include/x86_64-linux-gnu/bits/types.h' line='185' column='1' id='type-id-89'/> + <typedef-decl name='__fsfilcnt64_t' type-id='type-id-28' filepath='/usr/include/x86_64-linux-gnu/bits/types.h' line='189' column='1' id='type-id-90'/> + <typedef-decl name='clock_t' type-id='type-id-97' filepath='/usr/include/x86_64-linux-gnu/bits/types/clock_t.h' line='7' column='1' id='type-id-98'/> + <class-decl name='iovec' size-in-bits='128' is-struct='yes' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_iovec.h' line='26' column='1' id='type-id-99'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='iov_base' type-id='type-id-22' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_iovec.h' line='28' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='iov_len' type-id='type-id-19' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_iovec.h' line='29' column='1'/> + </data-member> + </class-decl> + <class-decl name='rusage' size-in-bits='1152' is-struct='yes' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_rusage.h' line='33' column='1' id='type-id-100'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='ru_utime' type-id='type-id-101' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_rusage.h' line='36' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='ru_stime' type-id='type-id-101' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_rusage.h' line='38' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='' type-id='type-id-102' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='' type-id='type-id-103' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='384'> + <var-decl name='' type-id='type-id-104' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='448'> + <var-decl name='' type-id='type-id-105' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='512'> + <var-decl name='' type-id='type-id-106' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='576'> + <var-decl name='' type-id='type-id-107' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='640'> + <var-decl name='' type-id='type-id-108' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='704'> + <var-decl name='' type-id='type-id-109' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='768'> + <var-decl name='' type-id='type-id-110' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='832'> + <var-decl name='' type-id='type-id-111' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='896'> + <var-decl name='' type-id='type-id-112' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='960'> + <var-decl name='' type-id='type-id-113' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1024'> + <var-decl name='' type-id='type-id-114' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1088'> + <var-decl name='' type-id='type-id-115' visibility='default'/> + </data-member> + </class-decl> + <union-decl name='__anonymous_union__' size-in-bits='64' is-anonymous='yes' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_rusage.h' line='40' column='1' id='type-id-102'> + <data-member access='public'> + <var-decl name='ru_maxrss' type-id='type-id-47' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_rusage.h' line='42' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='__ru_maxrss_word' type-id='type-id-116' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_rusage.h' line='43' column='1'/> + </data-member> + </union-decl> + <union-decl name='__anonymous_union__1' size-in-bits='64' is-anonymous='yes' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_rusage.h' line='47' column='1' id='type-id-103'> + <data-member access='public'> + <var-decl name='ru_ixrss' type-id='type-id-47' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_rusage.h' line='49' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='__ru_ixrss_word' type-id='type-id-116' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_rusage.h' line='50' column='1'/> + </data-member> + </union-decl> + <union-decl name='__anonymous_union__2' size-in-bits='64' is-anonymous='yes' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_rusage.h' line='53' column='1' id='type-id-104'> + <data-member access='public'> + <var-decl name='ru_idrss' type-id='type-id-47' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_rusage.h' line='55' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='__ru_idrss_word' type-id='type-id-116' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_rusage.h' line='56' column='1'/> + </data-member> + </union-decl> + <union-decl name='__anonymous_union__3' size-in-bits='64' is-anonymous='yes' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_rusage.h' line='59' column='1' id='type-id-105'> + <data-member access='public'> + <var-decl name='ru_isrss' type-id='type-id-47' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_rusage.h' line='61' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='__ru_isrss_word' type-id='type-id-116' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_rusage.h' line='62' column='1'/> + </data-member> + </union-decl> + <union-decl name='__anonymous_union__4' size-in-bits='64' is-anonymous='yes' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_rusage.h' line='66' column='1' id='type-id-106'> + <data-member access='public'> + <var-decl name='ru_minflt' type-id='type-id-47' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_rusage.h' line='68' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='__ru_minflt_word' type-id='type-id-116' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_rusage.h' line='69' column='1'/> + </data-member> + </union-decl> + <union-decl name='__anonymous_union__5' size-in-bits='64' is-anonymous='yes' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_rusage.h' line='72' column='1' id='type-id-107'> + <data-member access='public'> + <var-decl name='ru_majflt' type-id='type-id-47' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_rusage.h' line='74' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='__ru_majflt_word' type-id='type-id-116' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_rusage.h' line='75' column='1'/> + </data-member> + </union-decl> + <union-decl name='__anonymous_union__6' size-in-bits='64' is-anonymous='yes' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_rusage.h' line='78' column='1' id='type-id-108'> + <data-member access='public'> + <var-decl name='ru_nswap' type-id='type-id-47' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_rusage.h' line='80' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='__ru_nswap_word' type-id='type-id-116' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_rusage.h' line='81' column='1'/> + </data-member> + </union-decl> + <union-decl name='__anonymous_union__7' size-in-bits='64' is-anonymous='yes' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_rusage.h' line='85' column='1' id='type-id-109'> + <data-member access='public'> + <var-decl name='ru_inblock' type-id='type-id-47' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_rusage.h' line='87' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='__ru_inblock_word' type-id='type-id-116' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_rusage.h' line='88' column='1'/> + </data-member> + </union-decl> + <union-decl name='__anonymous_union__8' size-in-bits='64' is-anonymous='yes' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_rusage.h' line='91' column='1' id='type-id-110'> + <data-member access='public'> + <var-decl name='ru_oublock' type-id='type-id-47' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_rusage.h' line='93' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='__ru_oublock_word' type-id='type-id-116' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_rusage.h' line='94' column='1'/> + </data-member> + </union-decl> + <union-decl name='__anonymous_union__9' size-in-bits='64' is-anonymous='yes' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_rusage.h' line='97' column='1' id='type-id-111'> + <data-member access='public'> + <var-decl name='ru_msgsnd' type-id='type-id-47' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_rusage.h' line='99' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='__ru_msgsnd_word' type-id='type-id-116' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_rusage.h' line='100' column='1'/> + </data-member> + </union-decl> + <union-decl name='__anonymous_union__10' size-in-bits='64' is-anonymous='yes' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_rusage.h' line='103' column='1' id='type-id-112'> + <data-member access='public'> + <var-decl name='ru_msgrcv' type-id='type-id-47' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_rusage.h' line='105' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='__ru_msgrcv_word' type-id='type-id-116' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_rusage.h' line='106' column='1'/> + </data-member> + </union-decl> + <union-decl name='__anonymous_union__11' size-in-bits='64' is-anonymous='yes' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_rusage.h' line='109' column='1' id='type-id-113'> + <data-member access='public'> + <var-decl name='ru_nsignals' type-id='type-id-47' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_rusage.h' line='111' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='__ru_nsignals_word' type-id='type-id-116' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_rusage.h' line='112' column='1'/> + </data-member> + </union-decl> + <union-decl name='__anonymous_union__12' size-in-bits='64' is-anonymous='yes' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_rusage.h' line='117' column='1' id='type-id-114'> + <data-member access='public'> + <var-decl name='ru_nvcsw' type-id='type-id-47' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_rusage.h' line='119' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='__ru_nvcsw_word' type-id='type-id-116' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_rusage.h' line='120' column='1'/> + </data-member> + </union-decl> + <union-decl name='__anonymous_union__13' size-in-bits='64' is-anonymous='yes' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_rusage.h' line='124' column='1' id='type-id-115'> + <data-member access='public'> + <var-decl name='ru_nivcsw' type-id='type-id-47' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_rusage.h' line='126' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='__ru_nivcsw_word' type-id='type-id-116' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_rusage.h' line='127' column='1'/> + </data-member> + </union-decl> + <class-decl name='sched_param' size-in-bits='32' is-struct='yes' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_sched_param.h' line='23' column='1' id='type-id-74'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='sched_priority' type-id='type-id-8' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_sched_param.h' line='25' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='eventfd_t' type-id='type-id-117' filepath='/usr/include/x86_64-linux-gnu/sys/eventfd.h' line='27' column='1' id='type-id-118'/> + <typedef-decl name='__priority_which_t' type-id='type-id-87' filepath='/usr/include/x86_64-linux-gnu/sys/resource.h' line='40' column='1' id='type-id-119'/> + <class-decl name='tms' size-in-bits='256' is-struct='yes' visibility='default' filepath='/usr/include/x86_64-linux-gnu/sys/times.h' line='32' column='1' id='type-id-120'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='tms_utime' type-id='type-id-98' visibility='default' filepath='/usr/include/x86_64-linux-gnu/sys/times.h' line='34' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='tms_stime' type-id='type-id-98' visibility='default' filepath='/usr/include/x86_64-linux-gnu/sys/times.h' line='35' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='tms_cutime' type-id='type-id-98' visibility='default' filepath='/usr/include/x86_64-linux-gnu/sys/times.h' line='37' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='tms_cstime' type-id='type-id-98' visibility='default' filepath='/usr/include/x86_64-linux-gnu/sys/times.h' line='38' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='gid_t' type-id='type-id-121' filepath='/usr/include/x86_64-linux-gnu/sys/types.h' line='64' column='1' id='type-id-122'/> + <typedef-decl name='mode_t' type-id='type-id-123' filepath='/usr/include/x86_64-linux-gnu/sys/types.h' line='69' column='1' id='type-id-124'/> + <typedef-decl name='uid_t' type-id='type-id-125' filepath='/usr/include/x86_64-linux-gnu/sys/types.h' line='79' column='1' id='type-id-126'/> + <typedef-decl name='pid_t' type-id='type-id-127' filepath='/usr/include/x86_64-linux-gnu/sys/types.h' line='97' column='1' id='type-id-72'/> + <typedef-decl name='id_t' type-id='type-id-96' filepath='/usr/include/x86_64-linux-gnu/sys/types.h' line='103' column='1' id='type-id-128'/> + <class-decl name='utsname' size-in-bits='3120' is-struct='yes' visibility='default' filepath='/usr/include/x86_64-linux-gnu/sys/utsname.h' line='48' column='1' id='type-id-129'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='sysname' type-id='type-id-63' visibility='default' filepath='/usr/include/x86_64-linux-gnu/sys/utsname.h' line='51' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='520'> + <var-decl name='nodename' type-id='type-id-63' visibility='default' filepath='/usr/include/x86_64-linux-gnu/sys/utsname.h' line='54' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1040'> + <var-decl name='release' type-id='type-id-63' visibility='default' filepath='/usr/include/x86_64-linux-gnu/sys/utsname.h' line='57' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1560'> + <var-decl name='version' type-id='type-id-63' visibility='default' filepath='/usr/include/x86_64-linux-gnu/sys/utsname.h' line='59' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2080'> + <var-decl name='machine' type-id='type-id-63' visibility='default' filepath='/usr/include/x86_64-linux-gnu/sys/utsname.h' line='62' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2600'> + <var-decl name='domainname' type-id='type-id-63' visibility='default' filepath='/usr/include/x86_64-linux-gnu/sys/utsname.h' line='67' column='1'/> + </data-member> + </class-decl> + <enum-decl name='idtype_t' naming-typedef-id='type-id-130' filepath='/usr/include/x86_64-linux-gnu/sys/wait.h' line='75' column='1' id='type-id-131'> + <underlying-type type-id='type-id-24'/> + <enumerator name='P_ALL' value='0'/> + <enumerator name='P_PID' value='1'/> + <enumerator name='P_PGID' value='2'/> + </enum-decl> + <typedef-decl name='idtype_t' type-id='type-id-131' filepath='/usr/include/x86_64-linux-gnu/sys/wait.h' line='79' column='1' id='type-id-130'/> + <pointer-type-def type-id='type-id-68' size-in-bits='64' id='type-id-132'/> + <pointer-type-def type-id='type-id-121' size-in-bits='64' id='type-id-133'/> + <pointer-type-def type-id='type-id-9' size-in-bits='64' id='type-id-134'/> + <pointer-type-def type-id='type-id-66' size-in-bits='64' id='type-id-77'/> + <pointer-type-def type-id='type-id-125' size-in-bits='64' id='type-id-135'/> + <qualified-type-def type-id='type-id-136' restrict='yes' id='type-id-137'/> + <qualified-type-def type-id='type-id-121' const='yes' id='type-id-138'/> + <pointer-type-def type-id='type-id-138' size-in-bits='64' id='type-id-139'/> + <qualified-type-def type-id='type-id-80' const='yes' id='type-id-140'/> + <pointer-type-def type-id='type-id-140' size-in-bits='64' id='type-id-141'/> + <qualified-type-def type-id='type-id-99' const='yes' id='type-id-142'/> + <pointer-type-def type-id='type-id-142' size-in-bits='64' id='type-id-143'/> + <qualified-type-def type-id='type-id-75' const='yes' id='type-id-144'/> + <pointer-type-def type-id='type-id-144' size-in-bits='64' id='type-id-145'/> + <qualified-type-def type-id='type-id-145' restrict='yes' id='type-id-146'/> + <qualified-type-def type-id='type-id-69' const='yes' id='type-id-147'/> + <pointer-type-def type-id='type-id-147' size-in-bits='64' id='type-id-148'/> + <qualified-type-def type-id='type-id-148' restrict='yes' id='type-id-149'/> + <qualified-type-def type-id='type-id-74' const='yes' id='type-id-150'/> + <pointer-type-def type-id='type-id-150' size-in-bits='64' id='type-id-151'/> + <qualified-type-def type-id='type-id-151' restrict='yes' id='type-id-152'/> + <qualified-type-def type-id='type-id-73' const='yes' id='type-id-153'/> + <pointer-type-def type-id='type-id-153' size-in-bits='64' id='type-id-154'/> + <qualified-type-def type-id='type-id-154' restrict='yes' id='type-id-155'/> + <qualified-type-def type-id='type-id-92' const='yes' id='type-id-156'/> + <pointer-type-def type-id='type-id-156' size-in-bits='64' id='type-id-157'/> + <qualified-type-def type-id='type-id-86' const='yes' id='type-id-158'/> + <pointer-type-def type-id='type-id-158' size-in-bits='64' id='type-id-159'/> + <pointer-type-def type-id='type-id-80' size-in-bits='64' id='type-id-160'/> + <pointer-type-def type-id='type-id-82' size-in-bits='64' id='type-id-161'/> + <pointer-type-def type-id='type-id-118' size-in-bits='64' id='type-id-162'/> + <pointer-type-def type-id='type-id-122' size-in-bits='64' id='type-id-163'/> + <pointer-type-def type-id='type-id-72' size-in-bits='64' id='type-id-164'/> + <qualified-type-def type-id='type-id-164' restrict='yes' id='type-id-165'/> + <pointer-type-def type-id='type-id-75' size-in-bits='64' id='type-id-166'/> + <qualified-type-def type-id='type-id-166' restrict='yes' id='type-id-167'/> + <pointer-type-def type-id='type-id-69' size-in-bits='64' id='type-id-168'/> + <qualified-type-def type-id='type-id-168' restrict='yes' id='type-id-169'/> + <pointer-type-def type-id='type-id-100' size-in-bits='64' id='type-id-170'/> + <pointer-type-def type-id='type-id-74' size-in-bits='64' id='type-id-171'/> + <pointer-type-def type-id='type-id-88' size-in-bits='64' id='type-id-172'/> + <qualified-type-def type-id='type-id-172' restrict='yes' id='type-id-173'/> + <pointer-type-def type-id='type-id-120' size-in-bits='64' id='type-id-174'/> + <pointer-type-def type-id='type-id-126' size-in-bits='64' id='type-id-175'/> + <pointer-type-def type-id='type-id-129' size-in-bits='64' id='type-id-176'/> + <class-decl name='__dirstream' is-struct='yes' visibility='default' is-declaration-only='yes' id='type-id-65'/> + <class-decl name='__spawn_action' is-struct='yes' visibility='default' is-declaration-only='yes' id='type-id-66'/> + <function-decl name='_PyEval_ReInitThreads' filepath='./Include/internal/pycore_ceval.h' line='34' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-177'/> + <return type-id='type-id-54'/> + </function-decl> + <function-decl name='_PyPerfTrampoline_AfterFork_Child' filepath='./Include/internal/pycore_ceval.h' line='78' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-54'/> + </function-decl> + <function-decl name='_Py_normpath_and_size' filepath='./Include/internal/pycore_fileutils.h' line='256' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-52'/> + <parameter type-id='type-id-14'/> + <parameter type-id='type-id-13'/> + <return type-id='type-id-52'/> + </function-decl> + <function-decl name='_PyImport_ReInitLock' filepath='./Include/internal/pycore_import.h' line='156' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-54'/> + </function-decl> + <function-decl name='_PyInterpreterState_DeleteExceptMain' filepath='./Include/internal/pycore_pystate.h' line='141' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-178'/> + <return type-id='type-id-54'/> + </function-decl> + <function-decl name='_PySignal_AfterFork' filepath='./Include/internal/pycore_pystate.h' line='142' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyRuntimeState_ReInitThreads' filepath='./Include/internal/pycore_runtime.h' line='192' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-178'/> + <return type-id='type-id-54'/> + </function-decl> + <function-decl name='PyOS_BeforeFork' mangled-name='PyOS_BeforeFork' filepath='./Modules/posixmodule.c' line='585' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyOS_BeforeFork'> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyOS_AfterFork_Parent' mangled-name='PyOS_AfterFork_Parent' filepath='./Modules/posixmodule.c' line='594' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyOS_AfterFork_Parent'> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyOS_AfterFork_Child' mangled-name='PyOS_AfterFork_Child' filepath='./Modules/posixmodule.c' line='605' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyOS_AfterFork_Child'> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyOS_AfterFork' mangled-name='PyOS_AfterFork' filepath='./Modules/posixmodule.c' line='669' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyOS_AfterFork'> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyLong_FromUid' mangled-name='_PyLong_FromUid' filepath='./Modules/posixmodule.c' line='690' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyLong_FromUid'> + <parameter type-id='type-id-126' name='uid' filepath='./Modules/posixmodule.c' line='690' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyLong_FromGid' mangled-name='_PyLong_FromGid' filepath='./Modules/posixmodule.c' line='698' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyLong_FromGid'> + <parameter type-id='type-id-122' name='gid' filepath='./Modules/posixmodule.c' line='698' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_Py_Uid_Converter' mangled-name='_Py_Uid_Converter' filepath='./Modules/posixmodule.c' line='706' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_Uid_Converter'> + <parameter type-id='type-id-2' name='obj' filepath='./Modules/posixmodule.c' line='706' column='1'/> + <parameter type-id='type-id-175' name='p' filepath='./Modules/posixmodule.c' line='706' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_Py_Gid_Converter' mangled-name='_Py_Gid_Converter' filepath='./Modules/posixmodule.c' line='812' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_Gid_Converter'> + <parameter type-id='type-id-2' name='obj' filepath='./Modules/posixmodule.c' line='812' column='1'/> + <parameter type-id='type-id-163' name='p' filepath='./Modules/posixmodule.c' line='812' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_Py_Sigset_Converter' mangled-name='_Py_Sigset_Converter' filepath='./Modules/posixmodule.c' line='1475' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_Sigset_Converter'> + <parameter type-id='type-id-2' name='obj' filepath='./Modules/posixmodule.c' line='1475' column='1'/> + <parameter type-id='type-id-22' name='addr' filepath='./Modules/posixmodule.c' line='1475' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='opendir' filepath='/usr/include/dirent.h' line='134' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <return type-id='type-id-132'/> + </function-decl> + <function-decl name='fdopendir' filepath='/usr/include/dirent.h' line='141' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <return type-id='type-id-132'/> + </function-decl> + <function-decl name='closedir' filepath='/usr/include/dirent.h' line='149' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-132'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='rewinddir' filepath='/usr/include/dirent.h' line='209' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-132'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='setgroups' filepath='/usr/include/grp.h' line='176' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-19'/> + <parameter type-id='type-id-139'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='getgrouplist' filepath='/usr/include/grp.h' line='186' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-121'/> + <parameter type-id='type-id-133'/> + <parameter type-id='type-id-179'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='initgroups' filepath='/usr/include/grp.h' line='197' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-121'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='openpty' filepath='/usr/include/pty.h' line='36' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-179'/> + <parameter type-id='type-id-179'/> + <parameter type-id='type-id-15'/> + <parameter type-id='type-id-157'/> + <parameter type-id='type-id-159'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='forkpty' filepath='/usr/include/pty.h' line='42' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-179'/> + <parameter type-id='type-id-15'/> + <parameter type-id='type-id-157'/> + <parameter type-id='type-id-159'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='sched_setparam' filepath='/usr/include/sched.h' line='54' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-127'/> + <parameter type-id='type-id-151'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='sched_getparam' filepath='/usr/include/sched.h' line='58' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-127'/> + <parameter type-id='type-id-171'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='sched_setscheduler' filepath='/usr/include/sched.h' line='61' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-127'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-151'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='sched_getscheduler' filepath='/usr/include/sched.h' line='65' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-127'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='sched_yield' filepath='/usr/include/sched.h' line='68' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='sched_get_priority_max' filepath='/usr/include/sched.h' line='71' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='sched_get_priority_min' filepath='/usr/include/sched.h' line='74' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='sched_rr_get_interval' filepath='/usr/include/sched.h' line='78' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-127'/> + <parameter type-id='type-id-180'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='sched_setaffinity' filepath='/usr/include/sched.h' line='130' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-127'/> + <parameter type-id='type-id-19'/> + <parameter type-id='type-id-141'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='sched_getaffinity' filepath='/usr/include/sched.h' line='134' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-127'/> + <parameter type-id='type-id-19'/> + <parameter type-id='type-id-160'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='killpg' filepath='/usr/include/signal.h' line='119' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-127'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='sigaddset' filepath='/usr/include/signal.h' line='205' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-45'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='posix_spawn' filepath='/usr/include/spawn.h' line='72' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-165'/> + <parameter type-id='type-id-181'/> + <parameter type-id='type-id-146'/> + <parameter type-id='type-id-149'/> + <parameter type-id='type-id-137'/> + <parameter type-id='type-id-137'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='posix_spawnp' filepath='/usr/include/spawn.h' line='85' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-164'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-145'/> + <parameter type-id='type-id-148'/> + <parameter type-id='type-id-136'/> + <parameter type-id='type-id-136'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='posix_spawnattr_init' filepath='/usr/include/spawn.h' line='93' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-168'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='posix_spawnattr_destroy' filepath='/usr/include/spawn.h' line='97' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-168'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='posix_spawnattr_setsigdefault' filepath='/usr/include/spawn.h' line='108' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-169'/> + <parameter type-id='type-id-155'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='posix_spawnattr_setsigmask' filepath='/usr/include/spawn.h' line='120' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-169'/> + <parameter type-id='type-id-155'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='posix_spawnattr_setflags' filepath='/usr/include/spawn.h' line='131' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-168'/> + <parameter type-id='type-id-71'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='posix_spawnattr_setpgroup' filepath='/usr/include/spawn.h' line='141' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-168'/> + <parameter type-id='type-id-72'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='posix_spawnattr_setschedpolicy' filepath='/usr/include/spawn.h' line='152' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-168'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='posix_spawnattr_setschedparam' filepath='/usr/include/spawn.h' line='164' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-169'/> + <parameter type-id='type-id-152'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='posix_spawn_file_actions_init' filepath='/usr/include/spawn.h' line='170' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-166'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='posix_spawn_file_actions_destroy' filepath='/usr/include/spawn.h' line='175' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-166'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='posix_spawn_file_actions_addopen' filepath='/usr/include/spawn.h' line='181' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-167'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-181'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-124'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='posix_spawn_file_actions_addclose' filepath='/usr/include/spawn.h' line='190' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-166'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='posix_spawn_file_actions_adddup2' filepath='/usr/include/spawn.h' line='196' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-166'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='rename' filepath='/usr/include/stdio.h' line='154' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-12'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='renameat' filepath='/usr/include/stdio.h' line='158' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-12'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='ctermid' filepath='/usr/include/stdio.h' line='837' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-15'/> + <return type-id='type-id-15'/> + </function-decl> + <function-decl name='atoi' filepath='/usr/include/stdlib.h' line='105' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='unsetenv' filepath='/usr/include/stdlib.h' line='664' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='system' filepath='/usr/include/stdlib.h' line='791' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='qsort' filepath='/usr/include/stdlib.h' line='838' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-22'/> + <parameter type-id='type-id-19'/> + <parameter type-id='type-id-19'/> + <parameter type-id='type-id-79'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='getloadavg' filepath='/usr/include/stdlib.h' line='1013' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-182'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='strtok_r' filepath='/usr/include/string.h' line='366' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-183'/> + <parameter type-id='type-id-181'/> + <parameter type-id='type-id-184'/> + <return type-id='type-id-15'/> + </function-decl> + <function-decl name='access' filepath='/usr/include/unistd.h' line='287' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='faccessat' filepath='/usr/include/unistd.h' line='309' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='pipe' filepath='/usr/include/unistd.h' line='437' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-179'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='pipe2' filepath='/usr/include/unistd.h' line='442' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-179'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='chown' filepath='/usr/include/unistd.h' line='493' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-125'/> + <parameter type-id='type-id-121'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='fchown' filepath='/usr/include/unistd.h' line='498' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-125'/> + <parameter type-id='type-id-121'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='lchown' filepath='/usr/include/unistd.h' line='503' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-125'/> + <parameter type-id='type-id-121'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='fchownat' filepath='/usr/include/unistd.h' line='511' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-125'/> + <parameter type-id='type-id-121'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='chdir' filepath='/usr/include/unistd.h' line='517' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='fchdir' filepath='/usr/include/unistd.h' line='521' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='dup2' filepath='/usr/include/unistd.h' line='555' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='dup3' filepath='/usr/include/unistd.h' line='560' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='execve' filepath='/usr/include/unistd.h' line='572' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-136'/> + <parameter type-id='type-id-136'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='fexecve' filepath='/usr/include/unistd.h' line='578' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-136'/> + <parameter type-id='type-id-136'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='execv' filepath='/usr/include/unistd.h' line='584' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-136'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='nice' filepath='/usr/include/unistd.h' line='619' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='pathconf' filepath='/usr/include/unistd.h' line='633' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-47'/> + </function-decl> + <function-decl name='fpathconf' filepath='/usr/include/unistd.h' line='637' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-47'/> + </function-decl> + <function-decl name='getppid' filepath='/usr/include/unistd.h' line='653' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-127'/> + </function-decl> + <function-decl name='getpgrp' filepath='/usr/include/unistd.h' line='656' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-127'/> + </function-decl> + <function-decl name='getpgid' filepath='/usr/include/unistd.h' line='661' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-127'/> + <return type-id='type-id-127'/> + </function-decl> + <function-decl name='setpgid' filepath='/usr/include/unistd.h' line='668' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-127'/> + <parameter type-id='type-id-127'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='setpgrp' filepath='/usr/include/unistd.h' line='682' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='setsid' filepath='/usr/include/unistd.h' line='689' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-127'/> + </function-decl> + <function-decl name='getsid' filepath='/usr/include/unistd.h' line='693' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-127'/> + <return type-id='type-id-127'/> + </function-decl> + <function-decl name='getuid' filepath='/usr/include/unistd.h' line='697' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-125'/> + </function-decl> + <function-decl name='geteuid' filepath='/usr/include/unistd.h' line='700' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-125'/> + </function-decl> + <function-decl name='getgid' filepath='/usr/include/unistd.h' line='703' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-121'/> + </function-decl> + <function-decl name='getegid' filepath='/usr/include/unistd.h' line='706' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-121'/> + </function-decl> + <function-decl name='getgroups' filepath='/usr/include/unistd.h' line='711' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-133'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='setuid' filepath='/usr/include/unistd.h' line='722' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-125'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='setreuid' filepath='/usr/include/unistd.h' line='727' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-125'/> + <parameter type-id='type-id-125'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='seteuid' filepath='/usr/include/unistd.h' line='732' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-125'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='setgid' filepath='/usr/include/unistd.h' line='739' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-121'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='setregid' filepath='/usr/include/unistd.h' line='744' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-121'/> + <parameter type-id='type-id-121'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='setegid' filepath='/usr/include/unistd.h' line='749' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-121'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='getresuid' filepath='/usr/include/unistd.h' line='755' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-135'/> + <parameter type-id='type-id-135'/> + <parameter type-id='type-id-135'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='getresgid' filepath='/usr/include/unistd.h' line='760' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-133'/> + <parameter type-id='type-id-133'/> + <parameter type-id='type-id-133'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='setresuid' filepath='/usr/include/unistd.h' line='765' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-125'/> + <parameter type-id='type-id-125'/> + <parameter type-id='type-id-125'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='setresgid' filepath='/usr/include/unistd.h' line='770' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-121'/> + <parameter type-id='type-id-121'/> + <parameter type-id='type-id-121'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='fork' filepath='/usr/include/unistd.h' line='778' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-127'/> + </function-decl> + <function-decl name='ttyname_r' filepath='/usr/include/unistd.h' line='803' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-15'/> + <parameter type-id='type-id-19'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='link' filepath='/usr/include/unistd.h' line='819' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-12'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='linkat' filepath='/usr/include/unistd.h' line='825' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='symlink' filepath='/usr/include/unistd.h' line='832' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-12'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='symlinkat' filepath='/usr/include/unistd.h' line='847' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-12'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='readlinkat' filepath='/usr/include/unistd.h' line='851' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-181'/> + <parameter type-id='type-id-183'/> + <parameter type-id='type-id-19'/> + <return type-id='type-id-185'/> + </function-decl> + <function-decl name='unlink' filepath='/usr/include/unistd.h' line='858' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='unlinkat' filepath='/usr/include/unistd.h' line='862' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='rmdir' filepath='/usr/include/unistd.h' line='867' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='tcgetpgrp' filepath='/usr/include/unistd.h' line='871' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <return type-id='type-id-127'/> + </function-decl> + <function-decl name='tcsetpgrp' filepath='/usr/include/unistd.h' line='874' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-127'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='getlogin' filepath='/usr/include/unistd.h' line='881' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-15'/> + </function-decl> + <function-decl name='chroot' filepath='/usr/include/unistd.h' line='977' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='fsync' filepath='/usr/include/unistd.h' line='989' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='sync' filepath='/usr/include/unistd.h' line='1005' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='copy_file_range' filepath='/usr/include/unistd.h' line='1142' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-134'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-134'/> + <parameter type-id='type-id-19'/> + <parameter type-id='type-id-95'/> + <return type-id='type-id-185'/> + </function-decl> + <function-decl name='fdatasync' filepath='/usr/include/unistd.h' line='1150' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='login_tty' filepath='/usr/include/utmp.h' line='41' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='__sched_cpucount' filepath='/usr/include/x86_64-linux-gnu/bits/cpu-set.h' line='117' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-19'/> + <parameter type-id='type-id-141'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='__sched_cpualloc' filepath='/usr/include/x86_64-linux-gnu/bits/cpu-set.h' line='119' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-19'/> + <return type-id='type-id-160'/> + </function-decl> + <function-decl name='__sched_cpufree' filepath='/usr/include/x86_64-linux-gnu/bits/cpu-set.h' line='120' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-160'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='splice' filepath='/usr/include/x86_64-linux-gnu/bits/fcntl-linux.h' line='421' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-134'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-134'/> + <parameter type-id='type-id-19'/> + <parameter type-id='type-id-95'/> + <return type-id='type-id-186'/> + </function-decl> + <function-decl name='memfd_create' filepath='/usr/include/x86_64-linux-gnu/bits/mman-shared.h' line='51' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-95'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='unshare' filepath='/usr/include/x86_64-linux-gnu/bits/sched.h' line='86' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='setns' filepath='/usr/include/x86_64-linux-gnu/bits/sched.h' line='95' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='eventfd' filepath='/usr/include/x86_64-linux-gnu/sys/eventfd.h' line='34' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-95'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='eventfd_read' filepath='/usr/include/x86_64-linux-gnu/sys/eventfd.h' line='37' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-162'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='eventfd_write' filepath='/usr/include/x86_64-linux-gnu/sys/eventfd.h' line='40' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-118'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='getpriority' filepath='/usr/include/x86_64-linux-gnu/sys/resource.h' line='105' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-119'/> + <parameter type-id='type-id-128'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='setpriority' filepath='/usr/include/x86_64-linux-gnu/sys/resource.h' line='109' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-119'/> + <parameter type-id='type-id-128'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='chmod' filepath='/usr/include/x86_64-linux-gnu/sys/stat.h' line='352' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-123'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='fchmod' filepath='/usr/include/x86_64-linux-gnu/sys/stat.h' line='365' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-123'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='fchmodat' filepath='/usr/include/x86_64-linux-gnu/sys/stat.h' line='371' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-123'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='umask' filepath='/usr/include/x86_64-linux-gnu/sys/stat.h' line='380' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-123'/> + <return type-id='type-id-123'/> + </function-decl> + <function-decl name='mkdir' filepath='/usr/include/x86_64-linux-gnu/sys/stat.h' line='389' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-123'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='mkdirat' filepath='/usr/include/x86_64-linux-gnu/sys/stat.h' line='396' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-123'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='mknod' filepath='/usr/include/x86_64-linux-gnu/sys/stat.h' line='404' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-123'/> + <parameter type-id='type-id-187'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='mknodat' filepath='/usr/include/x86_64-linux-gnu/sys/stat.h' line='411' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-123'/> + <parameter type-id='type-id-187'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='mkfifo' filepath='/usr/include/x86_64-linux-gnu/sys/stat.h' line='418' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-123'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='mkfifoat' filepath='/usr/include/x86_64-linux-gnu/sys/stat.h' line='425' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-123'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='utimensat' filepath='/usr/include/x86_64-linux-gnu/sys/stat.h' line='433' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-188'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='futimens' filepath='/usr/include/x86_64-linux-gnu/sys/stat.h' line='452' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-188'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='gnu_dev_major' filepath='/usr/include/x86_64-linux-gnu/sys/sysmacros.h' line='35' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-187'/> + <return type-id='type-id-95'/> + </function-decl> + <function-decl name='gnu_dev_minor' filepath='/usr/include/x86_64-linux-gnu/sys/sysmacros.h' line='36' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-187'/> + <return type-id='type-id-95'/> + </function-decl> + <function-decl name='gnu_dev_makedev' filepath='/usr/include/x86_64-linux-gnu/sys/sysmacros.h' line='37' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-95'/> + <parameter type-id='type-id-95'/> + <return type-id='type-id-187'/> + </function-decl> + <function-decl name='times' filepath='/usr/include/x86_64-linux-gnu/sys/times.h' line='46' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-174'/> + <return type-id='type-id-98'/> + </function-decl> + <function-decl name='readv' filepath='/usr/include/x86_64-linux-gnu/sys/uio.h' line='41' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-143'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-185'/> + </function-decl> + <function-decl name='writev' filepath='/usr/include/x86_64-linux-gnu/sys/uio.h' line='52' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-143'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-185'/> + </function-decl> + <function-decl name='uname' filepath='/usr/include/x86_64-linux-gnu/sys/utsname.h' line='81' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-176'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='wait' filepath='/usr/include/x86_64-linux-gnu/sys/wait.h' line='88' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-179'/> + <return type-id='type-id-127'/> + </function-decl> + <function-decl name='waitpid' filepath='/usr/include/x86_64-linux-gnu/sys/wait.h' line='111' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-127'/> + <parameter type-id='type-id-179'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-127'/> + </function-decl> + <function-decl name='waitid' filepath='/usr/include/x86_64-linux-gnu/sys/wait.h' line='132' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-130'/> + <parameter type-id='type-id-96'/> + <parameter type-id='type-id-189'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='wait3' filepath='/usr/include/x86_64-linux-gnu/sys/wait.h' line='148' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-179'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-170'/> + <return type-id='type-id-127'/> + </function-decl> + <function-decl name='wait4' filepath='/usr/include/x86_64-linux-gnu/sys/wait.h' line='164' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-127'/> + <parameter type-id='type-id-179'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-170'/> + <return type-id='type-id-127'/> + </function-decl> + <function-decl name='setxattr' filepath='/usr/include/x86_64-linux-gnu/sys/xattr.h' line='41' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-22'/> + <parameter type-id='type-id-19'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='lsetxattr' filepath='/usr/include/x86_64-linux-gnu/sys/xattr.h' line='48' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-22'/> + <parameter type-id='type-id-19'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='fsetxattr' filepath='/usr/include/x86_64-linux-gnu/sys/xattr.h' line='54' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-22'/> + <parameter type-id='type-id-19'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='getxattr' filepath='/usr/include/x86_64-linux-gnu/sys/xattr.h' line='59' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-22'/> + <parameter type-id='type-id-19'/> + <return type-id='type-id-185'/> + </function-decl> + <function-decl name='lgetxattr' filepath='/usr/include/x86_64-linux-gnu/sys/xattr.h' line='65' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-22'/> + <parameter type-id='type-id-19'/> + <return type-id='type-id-185'/> + </function-decl> + <function-decl name='fgetxattr' filepath='/usr/include/x86_64-linux-gnu/sys/xattr.h' line='70' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-22'/> + <parameter type-id='type-id-19'/> + <return type-id='type-id-185'/> + </function-decl> + <function-decl name='listxattr' filepath='/usr/include/x86_64-linux-gnu/sys/xattr.h' line='76' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-15'/> + <parameter type-id='type-id-19'/> + <return type-id='type-id-185'/> + </function-decl> + <function-decl name='llistxattr' filepath='/usr/include/x86_64-linux-gnu/sys/xattr.h' line='82' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-15'/> + <parameter type-id='type-id-19'/> + <return type-id='type-id-185'/> + </function-decl> + <function-decl name='flistxattr' filepath='/usr/include/x86_64-linux-gnu/sys/xattr.h' line='87' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-15'/> + <parameter type-id='type-id-19'/> + <return type-id='type-id-185'/> + </function-decl> + <function-decl name='removexattr' filepath='/usr/include/x86_64-linux-gnu/sys/xattr.h' line='92' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-12'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='lremovexattr' filepath='/usr/include/x86_64-linux-gnu/sys/xattr.h' line='97' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-12'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='fremovexattr' filepath='/usr/include/x86_64-linux-gnu/sys/xattr.h' line='101' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-12'/> + <return type-id='type-id-8'/> + </function-decl> + <type-decl name='unsigned short int' size-in-bits='16' id='type-id-84'/> + <function-type size-in-bits='64' id='type-id-190'> + <parameter type-id='type-id-22'/> + <parameter type-id='type-id-22'/> + <return type-id='type-id-8'/> + </function-type> + </abi-instr> + <abi-instr address-size='64' path='./Modules/pwdmodule.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <class-decl name='passwd' size-in-bits='384' is-struct='yes' visibility='default' filepath='/usr/include/pwd.h' line='49' column='1' id='type-id-191'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='pw_name' type-id='type-id-15' visibility='default' filepath='/usr/include/pwd.h' line='51' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='pw_passwd' type-id='type-id-15' visibility='default' filepath='/usr/include/pwd.h' line='52' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='pw_uid' type-id='type-id-125' visibility='default' filepath='/usr/include/pwd.h' line='54' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='160'> + <var-decl name='pw_gid' type-id='type-id-121' visibility='default' filepath='/usr/include/pwd.h' line='55' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='pw_gecos' type-id='type-id-15' visibility='default' filepath='/usr/include/pwd.h' line='56' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='pw_dir' type-id='type-id-15' visibility='default' filepath='/usr/include/pwd.h' line='57' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='pw_shell' type-id='type-id-15' visibility='default' filepath='/usr/include/pwd.h' line='58' column='1'/> + </data-member> + </class-decl> + <pointer-type-def type-id='type-id-191' size-in-bits='64' id='type-id-192'/> + <qualified-type-def type-id='type-id-192' restrict='yes' id='type-id-193'/> + <pointer-type-def type-id='type-id-192' size-in-bits='64' id='type-id-194'/> + <qualified-type-def type-id='type-id-194' restrict='yes' id='type-id-195'/> + <function-decl name='setpwent' filepath='/usr/include/pwd.h' line='72' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='endpwent' filepath='/usr/include/pwd.h' line='78' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='getpwent' filepath='/usr/include/pwd.h' line='84' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-192'/> + </function-decl> + <function-decl name='getpwuid_r' filepath='/usr/include/pwd.h' line='146' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-125'/> + <parameter type-id='type-id-193'/> + <parameter type-id='type-id-183'/> + <parameter type-id='type-id-19'/> + <parameter type-id='type-id-195'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='getpwnam_r' filepath='/usr/include/pwd.h' line='153' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-181'/> + <parameter type-id='type-id-193'/> + <parameter type-id='type-id-183'/> + <parameter type-id='type-id-19'/> + <parameter type-id='type-id-195'/> + <return type-id='type-id-8'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='./Modules/signalmodule.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <enum-decl name='__itimer_which' filepath='/usr/include/x86_64-linux-gnu/sys/time.h' line='114' column='1' id='type-id-196'> + <underlying-type type-id='type-id-24'/> + <enumerator name='ITIMER_REAL' value='0'/> + <enumerator name='ITIMER_VIRTUAL' value='1'/> + <enumerator name='ITIMER_PROF' value='2'/> + </enum-decl> + <class-decl name='itimerval' size-in-bits='256' is-struct='yes' visibility='default' filepath='/usr/include/x86_64-linux-gnu/sys/time.h' line='130' column='1' id='type-id-197'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='it_interval' type-id='type-id-101' visibility='default' filepath='/usr/include/x86_64-linux-gnu/sys/time.h' line='133' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='it_value' type-id='type-id-101' visibility='default' filepath='/usr/include/x86_64-linux-gnu/sys/time.h' line='135' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='__itimer_which_t' type-id='type-id-196' filepath='/usr/include/x86_64-linux-gnu/sys/time.h' line='141' column='1' id='type-id-198'/> + <qualified-type-def type-id='type-id-197' const='yes' id='type-id-199'/> + <pointer-type-def type-id='type-id-199' size-in-bits='64' id='type-id-200'/> + <qualified-type-def type-id='type-id-200' restrict='yes' id='type-id-201'/> + <qualified-type-def type-id='type-id-179' restrict='yes' id='type-id-202'/> + <pointer-type-def type-id='type-id-197' size-in-bits='64' id='type-id-203'/> + <qualified-type-def type-id='type-id-203' restrict='yes' id='type-id-204'/> + <qualified-type-def type-id='type-id-189' restrict='yes' id='type-id-205'/> + <function-decl name='_PyErr_CheckSignals' mangled-name='_PyErr_CheckSignals' filepath='./Modules/signalmodule.c' line='1874' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyErr_CheckSignals'> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyErr_SetInterruptEx' mangled-name='PyErr_SetInterruptEx' filepath='./Modules/signalmodule.c' line='1886' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_SetInterruptEx'> + <parameter type-id='type-id-8' name='signum' filepath='./Modules/signalmodule.c' line='1886' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyErr_SetInterrupt' mangled-name='PyErr_SetInterrupt' filepath='./Modules/signalmodule.c' line='1902' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_SetInterrupt'> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_Py_RestoreSignals' mangled-name='_Py_RestoreSignals' filepath='./Modules/signalmodule.c' line='1940' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_RestoreSignals'> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyOS_InterruptOccurred' mangled-name='PyOS_InterruptOccurred' filepath='./Modules/signalmodule.c' line='2012' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyOS_InterruptOccurred'> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyOS_IsMainThread' mangled-name='_PyOS_IsMainThread' filepath='./Modules/signalmodule.c' line='2045' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyOS_IsMainThread'> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='sigismember' filepath='/usr/include/signal.h' line='211' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-154'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='sigpending' filepath='/usr/include/signal.h' line='247' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-45'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='sigwait' filepath='/usr/include/signal.h' line='255' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-155'/> + <parameter type-id='type-id-202'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='sigwaitinfo' filepath='/usr/include/signal.h' line='264' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-155'/> + <parameter type-id='type-id-205'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='sigtimedwait' filepath='/usr/include/signal.h' line='273' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-155'/> + <parameter type-id='type-id-205'/> + <parameter type-id='type-id-206'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='__libc_current_sigrtmin' filepath='/usr/include/signal.h' line='383' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='__libc_current_sigrtmax' filepath='/usr/include/signal.h' line='385' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='strstr' filepath='/usr/include/string.h' line='350' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-12'/> + <return type-id='type-id-15'/> + </function-decl> + <function-decl name='strsignal' filepath='/usr/include/string.h' line='478' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <return type-id='type-id-15'/> + </function-decl> + <function-decl name='alarm' filepath='/usr/include/unistd.h' line='452' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-95'/> + <return type-id='type-id-95'/> + </function-decl> + <function-decl name='pause' filepath='/usr/include/unistd.h' line='489' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='pthread_kill' filepath='/usr/include/x86_64-linux-gnu/bits/sigthread.h' line='36' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-207'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='getitimer' filepath='/usr/include/x86_64-linux-gnu/sys/time.h' line='149' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-198'/> + <parameter type-id='type-id-203'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='setitimer' filepath='/usr/include/x86_64-linux-gnu/sys/time.h' line='155' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-198'/> + <parameter type-id='type-id-201'/> + <parameter type-id='type-id-204'/> + <return type-id='type-id-8'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='./Modules/symtablemodule.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <function-decl name='_Py_SymtableStringObjectFlags' filepath='./Include/internal/pycore_symtable.h' line='144' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-208'/> + <return type-id='type-id-209'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='./Modules/timemodule.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <enum-decl name='__rusage_who' filepath='/usr/include/x86_64-linux-gnu/bits/resource.h' line='158' column='1' id='type-id-210'> + <underlying-type type-id='type-id-24'/> + <enumerator name='RUSAGE_SELF' value='0'/> + <enumerator name='RUSAGE_CHILDREN' value='-1'/> + <enumerator name='RUSAGE_THREAD' value='1'/> + </enum-decl> + <typedef-decl name='__rusage_who_t' type-id='type-id-210' filepath='/usr/include/x86_64-linux-gnu/sys/resource.h' line='39' column='1' id='type-id-211'/> + <pointer-type-def type-id='type-id-212' size-in-bits='64' id='type-id-213'/> + <qualified-type-def type-id='type-id-214' const='yes' id='type-id-215'/> + <pointer-type-def type-id='type-id-215' size-in-bits='64' id='type-id-216'/> + <qualified-type-def type-id='type-id-216' restrict='yes' id='type-id-217'/> + <function-decl name='pthread_getcpuclockid' filepath='/usr/include/pthread.h' line='1315' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-207'/> + <parameter type-id='type-id-213'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='clock' filepath='/usr/include/time.h' line='72' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-98'/> + </function-decl> + <function-decl name='time' filepath='/usr/include/time.h' line='76' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-218'/> + <return type-id='type-id-219'/> + </function-decl> + <function-decl name='mktime' filepath='/usr/include/time.h' line='83' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-220'/> + <return type-id='type-id-219'/> + </function-decl> + <function-decl name='tzset' filepath='/usr/include/time.h' line='228' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='clock_settime' filepath='/usr/include/time.h' line='282' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-221'/> + <parameter type-id='type-id-188'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='clock_nanosleep' filepath='/usr/include/time.h' line='311' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-221'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-188'/> + <parameter type-id='type-id-180'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='wcsftime' filepath='/usr/include/wchar.h' line='852' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-17'/> + <parameter type-id='type-id-19'/> + <parameter type-id='type-id-18'/> + <parameter type-id='type-id-217'/> + <return type-id='type-id-19'/> + </function-decl> + <function-decl name='getrusage' filepath='/usr/include/x86_64-linux-gnu/sys/resource.h' line='89' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-211'/> + <parameter type-id='type-id-170'/> + <return type-id='type-id-8'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='./Python/dynload_shlib.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <array-type-def dimensions='1' type-id='type-id-12' size-in-bits='256' id='type-id-222'> + <subrange length='4' type-id='type-id-28' id='type-id-223'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-12' size-in-bits='infinite' id='type-id-224'> + <subrange length='infinite' id='type-id-225'/> + </array-type-def> + <var-decl name='_PyImport_DynLoadFiletab' type-id='type-id-224' visibility='default' filepath='./Python/importdl.h' line='9' column='1'/> + <function-decl name='dlopen' filepath='/usr/include/dlfcn.h' line='58' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-22'/> + </function-decl> + <function-decl name='dlsym' filepath='/usr/include/dlfcn.h' line='66' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-226'/> + <parameter type-id='type-id-181'/> + <return type-id='type-id-22'/> + </function-decl> + <function-decl name='dlerror' filepath='/usr/include/dlfcn.h' line='84' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-15'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='./Python/getplatform.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <function-decl name='Py_GetPlatform' mangled-name='Py_GetPlatform' filepath='./Python/getplatform.c' line='9' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_GetPlatform'> + <return type-id='type-id-12'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='./Python/importdl.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <typedef-decl name='dl_funcptr' type-id='type-id-227' filepath='./Python/importdl.h' line='28' column='1' id='type-id-228'/> + <function-decl name='_PyImport_SwapPackageContext' filepath='./Include/internal/pycore_import.h' line='112' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <return type-id='type-id-12'/> + </function-decl> + <function-decl name='_PyImport_FindSharedFuncptr' filepath='./Python/importdl.c' line='25' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-229'/> + <return type-id='type-id-228'/> + </function-decl> + <function-type size-in-bits='64' id='type-id-230'> + <return type-id='type-id-46'/> + </function-type> + </abi-instr> + <abi-instr address-size='64' path='./Python/sysmodule.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <function-decl name='_PyEval_CallTracing' filepath='./Include/internal/pycore_ceval.h' line='38' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyEval_GetAsyncGenFirstiter' filepath='./Include/internal/pycore_ceval.h' line='41' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyEval_GetAsyncGenFinalizer' filepath='./Include/internal/pycore_ceval.h' line='42' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyEval_SetAsyncGenFirstiter' filepath='./Include/internal/pycore_ceval.h' line='45' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyEval_SetAsyncGenFinalizer' filepath='./Include/internal/pycore_ceval.h' line='46' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyEval_GetCoroutineOriginTrackingDepth' filepath='./Include/internal/pycore_ceval.h' line='50' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyEval_SetCoroutineOriginTrackingDepth' filepath='./Include/internal/pycore_ceval.h' line='51' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyPerfTrampoline_GetCallbacks' filepath='./Include/internal/pycore_ceval.h' line='74' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-231'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyIsPerfTrampolineActive' filepath='./Include/internal/pycore_ceval.h' line='77' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyImport_GetDLOpenFlags' filepath='./Include/internal/pycore_import.h' line='114' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyImport_SetDLOpenFlags' filepath='./Include/internal/pycore_import.h' line='115' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyImport_InitModules' filepath='./Include/internal/pycore_import.h' line='117' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyImport_GetBuiltinModuleNames' filepath='./Include/internal/pycore_import.h' line='160' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_Py_GetGlobalAllocatedBlocks' filepath='./Include/internal/pycore_obmalloc.h' line='682' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-14'/> + </function-decl> + <function-decl name='_PyPathConfig_ComputeSysPath0' filepath='./Include/internal/pycore_pathconfig.h' line='16' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-232'/> + <parameter type-id='type-id-233'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_Py_GetStdlibDir' filepath='./Include/internal/pycore_pylifecycle.h' line='81' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-52'/> + </function-decl> + <function-decl name='_PyErr_WriteUnraisableDefaultHook' filepath='./Include/internal/pycore_pylifecycle.h' line='85' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyUnicode_InternedSize' filepath='./Include/internal/pycore_unicodeobject.h' line='15' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-14'/> + </function-decl> + <function-decl name='PyThread_GetInfo' mangled-name='PyThread_GetInfo' filepath='./Include/pythread.h' line='87' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThread_GetInfo'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PySys_AddAuditHook' mangled-name='PySys_AddAuditHook' filepath='./Python/sysmodule.c' line='389' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySys_AddAuditHook'> + <parameter type-id='type-id-234' name='hook' filepath='./Python/sysmodule.c' line='389' column='1'/> + <parameter type-id='type-id-22' name='userData' filepath='./Python/sysmodule.c' line='389' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PySys_GetSizeOf' mangled-name='_PySys_GetSizeOf' filepath='./Python/sysmodule.c' line='1776' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PySys_GetSizeOf'> + <parameter type-id='type-id-2' name='o' filepath='./Python/sysmodule.c' line='1776' column='1'/> + <return type-id='type-id-19'/> + </function-decl> + <function-decl name='PyUnstable_PerfMapState_Init' mangled-name='PyUnstable_PerfMapState_Init' filepath='./Python/sysmodule.c' line='2275' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnstable_PerfMapState_Init'> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyUnstable_WritePerfMapEntry' mangled-name='PyUnstable_WritePerfMapEntry' filepath='./Python/sysmodule.c' line='2306' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnstable_WritePerfMapEntry'> + <parameter type-id='type-id-22' name='code_addr' filepath='./Python/sysmodule.c' line='2307' column='1'/> + <parameter type-id='type-id-95' name='code_size' filepath='./Python/sysmodule.c' line='2308' column='1'/> + <parameter type-id='type-id-12' name='entry_name' filepath='./Python/sysmodule.c' line='2309' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PySys_ResetWarnOptions' mangled-name='PySys_ResetWarnOptions' filepath='./Python/sysmodule.c' line='2615' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySys_ResetWarnOptions'> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PySys_AddWarnOptionUnicode' mangled-name='PySys_AddWarnOptionUnicode' filepath='./Python/sysmodule.c' line='2643' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySys_AddWarnOptionUnicode'> + <parameter type-id='type-id-2' name='option' filepath='./Python/sysmodule.c' line='2643' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PySys_AddWarnOption' mangled-name='PySys_AddWarnOption' filepath='./Python/sysmodule.c' line='2655' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySys_AddWarnOption'> + <parameter type-id='type-id-16' name='s' filepath='./Python/sysmodule.c' line='2655' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PySys_HasWarnOptions' mangled-name='PySys_HasWarnOptions' filepath='./Python/sysmodule.c' line='2674' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySys_HasWarnOptions'> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PySys_AddXOption' mangled-name='PySys_AddXOption' filepath='./Python/sysmodule.c' line='2753' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySys_AddXOption'> + <parameter type-id='type-id-16' name='s' filepath='./Python/sysmodule.c' line='2753' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PySys_GetXOptions' mangled-name='PySys_GetXOptions' filepath='./Python/sysmodule.c' line='2767' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySys_GetXOptions'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_Py_CreateMonitoringObject' filepath='./Python/sysmodule.c' line='3540' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PySys_SetPath' mangled-name='PySys_SetPath' filepath='./Python/sysmodule.c' line='3662' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySys_SetPath'> + <parameter type-id='type-id-16' name='path' filepath='./Python/sysmodule.c' line='3662' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PySys_SetArgvEx' mangled-name='PySys_SetArgvEx' filepath='./Python/sysmodule.c' line='3694' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySys_SetArgvEx'> + <parameter type-id='type-id-8' name='argc' filepath='./Python/sysmodule.c' line='3694' column='1'/> + <parameter type-id='type-id-235' name='argv' filepath='./Python/sysmodule.c' line='3694' column='1'/> + <parameter type-id='type-id-8' name='updatepath' filepath='./Python/sysmodule.c' line='3694' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PySys_SetArgv' mangled-name='PySys_SetArgv' filepath='./Python/sysmodule.c' line='3738' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySys_SetArgv'> + <parameter type-id='type-id-8' name='argc' filepath='./Python/sysmodule.c' line='3738' column='1'/> + <parameter type-id='type-id-235' name='argv' filepath='./Python/sysmodule.c' line='3738' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PySys_WriteStdout' mangled-name='PySys_WriteStdout' filepath='./Python/sysmodule.c' line='3833' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySys_WriteStdout'> + <parameter type-id='type-id-12' name='format' filepath='./Python/sysmodule.c' line='3833' column='1'/> + <parameter is-variadic='yes'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PySys_FormatStdout' mangled-name='PySys_FormatStdout' filepath='./Python/sysmodule.c' line='3875' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySys_FormatStdout'> + <parameter type-id='type-id-12' name='format' filepath='./Python/sysmodule.c' line='3875' column='1'/> + <parameter is-variadic='yes'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='getpid' filepath='/usr/include/unistd.h' line='650' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-127'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Modules/config.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <function-decl name='PyInit_atexit' mangled-name='PyInit_atexit' filepath='Modules/config.c' line='26' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInit_atexit'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyInit_faulthandler' mangled-name='PyInit_faulthandler' filepath='Modules/config.c' line='27' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInit_faulthandler'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyInit_posix' mangled-name='PyInit_posix' filepath='Modules/config.c' line='28' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInit_posix'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyInit__signal' mangled-name='PyInit__signal' filepath='Modules/config.c' line='29' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInit__signal'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyInit__tracemalloc' mangled-name='PyInit__tracemalloc' filepath='Modules/config.c' line='30' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInit__tracemalloc'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyInit__codecs' mangled-name='PyInit__codecs' filepath='Modules/config.c' line='31' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInit__codecs'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyInit__collections' mangled-name='PyInit__collections' filepath='Modules/config.c' line='32' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInit__collections'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyInit_errno' mangled-name='PyInit_errno' filepath='Modules/config.c' line='33' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInit_errno'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyInit__io' mangled-name='PyInit__io' filepath='Modules/config.c' line='34' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInit__io'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyInit_itertools' mangled-name='PyInit_itertools' filepath='Modules/config.c' line='35' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInit_itertools'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyInit__sre' mangled-name='PyInit__sre' filepath='Modules/config.c' line='36' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInit__sre'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyInit__thread' mangled-name='PyInit__thread' filepath='Modules/config.c' line='37' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInit__thread'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyInit_time' mangled-name='PyInit_time' filepath='Modules/config.c' line='38' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInit_time'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyInit__typing' mangled-name='PyInit__typing' filepath='Modules/config.c' line='39' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInit__typing'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyInit__weakref' mangled-name='PyInit__weakref' filepath='Modules/config.c' line='40' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInit__weakref'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyInit__abc' mangled-name='PyInit__abc' filepath='Modules/config.c' line='41' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInit__abc'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyInit__functools' mangled-name='PyInit__functools' filepath='Modules/config.c' line='42' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInit__functools'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyInit__locale' mangled-name='PyInit__locale' filepath='Modules/config.c' line='43' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInit__locale'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyInit__operator' mangled-name='PyInit__operator' filepath='Modules/config.c' line='44' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInit__operator'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyInit__stat' mangled-name='PyInit__stat' filepath='Modules/config.c' line='45' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInit__stat'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyInit__symtable' mangled-name='PyInit__symtable' filepath='Modules/config.c' line='46' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInit__symtable'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyInit_pwd' mangled-name='PyInit_pwd' filepath='Modules/config.c' line='47' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInit_pwd'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyInit_gc' mangled-name='PyInit_gc' filepath='Modules/config.c' line='53' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInit_gc'> + <return type-id='type-id-2'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Modules/gcmodule.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <typedef-decl name='gcvisitobjects_t' type-id='type-id-236' filepath='./Include/objimpl.h' line='175' column='1' id='type-id-237'/> + <function-decl name='_PyTuple_ClearFreeList' filepath='./Include/internal/pycore_gc.h' line='199' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyFloat_ClearFreeList' filepath='./Include/internal/pycore_gc.h' line='200' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyList_ClearFreeList' filepath='./Include/internal/pycore_gc.h' line='201' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyDict_ClearFreeList' filepath='./Include/internal/pycore_gc.h' line='202' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyAsyncGen_ClearFreeLists' filepath='./Include/internal/pycore_gc.h' line='203' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyContext_ClearFreeList' filepath='./Include/internal/pycore_gc.h' line='204' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyGC_Enable' mangled-name='PyGC_Enable' filepath='Modules/gcmodule.c' line='2068' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyGC_Enable'> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyGC_Disable' mangled-name='PyGC_Disable' filepath='Modules/gcmodule.c' line='2077' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyGC_Disable'> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyGC_IsEnabled' mangled-name='PyGC_IsEnabled' filepath='Modules/gcmodule.c' line='2086' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyGC_IsEnabled'> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyUnstable_Object_GC_NewWithExtraData' mangled-name='PyUnstable_Object_GC_NewWithExtraData' filepath='Modules/gcmodule.c' line='2347' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnstable_Object_GC_NewWithExtraData'> + <parameter type-id='type-id-1' name='tp' filepath='Modules/gcmodule.c' line='2347' column='1'/> + <parameter type-id='type-id-19' name='extra_size' filepath='Modules/gcmodule.c' line='2347' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyObject_GC_IsTracked' mangled-name='PyObject_GC_IsTracked' filepath='Modules/gcmodule.c' line='2401' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_GC_IsTracked'> + <parameter type-id='type-id-2' name='obj' filepath='Modules/gcmodule.c' line='2401' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyObject_GC_IsFinalized' mangled-name='PyObject_GC_IsFinalized' filepath='Modules/gcmodule.c' line='2410' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_GC_IsFinalized'> + <parameter type-id='type-id-2' name='obj' filepath='Modules/gcmodule.c' line='2410' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyUnstable_GC_VisitObjects' mangled-name='PyUnstable_GC_VisitObjects' filepath='Modules/gcmodule.c' line='2419' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnstable_GC_VisitObjects'> + <parameter type-id='type-id-237' name='callback' filepath='Modules/gcmodule.c' line='2419' column='1'/> + <parameter type-id='type-id-22' name='arg' filepath='Modules/gcmodule.c' line='2419' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-type size-in-bits='64' id='type-id-238'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-22'/> + <return type-id='type-id-8'/> + </function-type> + </abi-instr> + <abi-instr address-size='64' path='Modules/main.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <function-decl name='_PyImport_Fini2' filepath='./Include/internal/pycore_import.h' line='144' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='kill' filepath='/usr/include/signal.h' line='112' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-127'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='Py_RunMain' mangled-name='Py_RunMain' filepath='Modules/main.c' line='685' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_RunMain'> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='Py_Main' mangled-name='Py_Main' filepath='Modules/main.c' line='724' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_Main'> + <parameter type-id='type-id-8' name='argc' filepath='Modules/main.c' line='724' column='1'/> + <parameter type-id='type-id-235' name='argv' filepath='Modules/main.c' line='724' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='Py_BytesMain' mangled-name='Py_BytesMain' filepath='Modules/main.c' line='736' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_BytesMain'> + <parameter type-id='type-id-8' name='argc' filepath='Modules/main.c' line='736' column='1'/> + <parameter type-id='type-id-239' name='argv' filepath='Modules/main.c' line='736' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Objects/abstract.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <pointer-type-def type-id='type-id-240' size-in-bits='64' id='type-id-241'/> + <qualified-type-def type-id='type-id-15' const='yes' id='type-id-242'/> + <pointer-type-def type-id='type-id-242' size-in-bits='64' id='type-id-136'/> + <qualified-type-def type-id='type-id-243' const='yes' id='type-id-244'/> + <pointer-type-def type-id='type-id-244' size-in-bits='64' id='type-id-245'/> + <qualified-type-def type-id='type-id-14' const='yes' id='type-id-246'/> + <pointer-type-def type-id='type-id-246' size-in-bits='64' id='type-id-247'/> + <function-decl name='PyObject_CallFunctionObjArgs' mangled-name='PyObject_CallFunctionObjArgs' filepath='./Include/abstract.h' line='215' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_CallFunctionObjArgs'> + <parameter type-id='type-id-2'/> + <parameter is-variadic='yes'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyObject_VectorcallMethod' mangled-name='PyObject_VectorcallMethod' filepath='./Include/abstract.h' line='253' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_VectorcallMethod'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-248'/> + <parameter type-id='type-id-19'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyObject_CallOneArg' mangled-name='PyObject_CallOneArg' filepath='./Include/cpython/abstract.h' line='88' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_CallOneArg'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyGen_FetchStopIterationValue' mangled-name='_PyGen_FetchStopIterationValue' filepath='./Include/cpython/genobject.h' line='45' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyGen_FetchStopIterationValue'> + <parameter type-id='type-id-233'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyList_Extend' mangled-name='_PyList_Extend' filepath='./Include/cpython/listobject.h' line='24' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyList_Extend'> + <parameter type-id='type-id-249'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyLong_Copy' mangled-name='_PyLong_Copy' filepath='./Include/cpython/longintrepr.h' line='95' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyLong_Copy'> + <parameter type-id='type-id-241'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyLong_FromUnicodeObject' mangled-name='PyLong_FromUnicodeObject' filepath='./Include/cpython/longobject.h' line='21' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyLong_FromUnicodeObject'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyLong_FromBytes' mangled-name='_PyLong_FromBytes' filepath='./Include/cpython/longobject.h' line='22' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyLong_FromBytes'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-14'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyLong_Format' mangled-name='_PyLong_Format' filepath='./Include/cpython/longobject.h' line='89' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyLong_Format'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyObject_LookupAttr' mangled-name='_PyObject_LookupAttr' filepath='./Include/cpython/object.h' line='305' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_LookupAttr'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-233'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyObject_NextNotImplemented' mangled-name='_PyObject_NextNotImplemented' filepath='./Include/cpython/object.h' line='311' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_NextNotImplemented'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyTuple_Resize' mangled-name='_PyTuple_Resize' filepath='./Include/cpython/tupleobject.h' line='13' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTuple_Resize'> + <parameter type-id='type-id-233'/> + <parameter type-id='type-id-14'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyUnicode_New' mangled-name='PyUnicode_New' filepath='./Include/cpython/unicodeobject.h' line='387' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_New'> + <parameter type-id='type-id-14'/> + <parameter type-id='type-id-250'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyDict_Keys' mangled-name='PyDict_Keys' filepath='./Include/dictobject.h' line='29' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyDict_Keys'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyDict_Values' mangled-name='PyDict_Values' filepath='./Include/dictobject.h' line='30' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyDict_Values'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyDict_Items' mangled-name='PyDict_Items' filepath='./Include/dictobject.h' line='31' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyDict_Items'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyFloat_FromString' mangled-name='PyFloat_FromString' filepath='./Include/floatobject.h' line='36' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFloat_FromString'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='Py_GenericAlias' mangled-name='Py_GenericAlias' filepath='./Include/genericaliasobject.h' line='8' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_GenericAlias'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_Py_CheckRecursiveCall' mangled-name='_Py_CheckRecursiveCall' filepath='./Include/internal/pycore_ceval.h' line='125' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_CheckRecursiveCall'> + <parameter type-id='type-id-177'/> + <parameter type-id='type-id-12'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyObject_LookupSpecial' mangled-name='_PyObject_LookupSpecial' filepath='./Include/internal/pycore_object.h' line='411' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_LookupSpecial'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyErr_ExceptionMatches' mangled-name='_PyErr_ExceptionMatches' filepath='./Include/internal/pycore_pyerrors.h' line='46' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyErr_ExceptionMatches'> + <parameter type-id='type-id-177'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyErr_Clear' mangled-name='_PyErr_Clear' filepath='./Include/internal/pycore_pyerrors.h' line='67' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyErr_Clear'> + <parameter type-id='type-id-177'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyErr_SetString' mangled-name='_PyErr_SetString' filepath='./Include/internal/pycore_pyerrors.h' line='73' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyErr_SetString'> + <parameter type-id='type-id-177'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-12'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyErr_Format' mangled-name='_PyErr_Format' filepath='./Include/internal/pycore_pyerrors.h' line='78' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyErr_Format'> + <parameter type-id='type-id-177'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-12'/> + <parameter is-variadic='yes'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_Py_union_args' filepath='./Include/internal/pycore_unionobject.h' line='18' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PySeqIter_New' mangled-name='PySeqIter_New' filepath='./Include/iterobject.h' line='16' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySeqIter_New'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyList_New' mangled-name='PyList_New' filepath='./Include/listobject.h' line='28' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyList_New'> + <parameter type-id='type-id-14'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyList_AsTuple' mangled-name='PyList_AsTuple' filepath='./Include/listobject.h' line='41' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyList_AsTuple'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyLong_FromSsize_t' mangled-name='PyLong_FromSsize_t' filepath='./Include/longobject.h' line='19' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyLong_FromSsize_t'> + <parameter type-id='type-id-14'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyLong_AsSsize_t' mangled-name='PyLong_AsSsize_t' filepath='./Include/longobject.h' line='23' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyLong_AsSsize_t'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-14'/> + </function-decl> + <function-decl name='PyLong_AsDouble' mangled-name='PyLong_AsDouble' filepath='./Include/longobject.h' line='63' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyLong_AsDouble'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-251'/> + </function-decl> + <function-decl name='PyType_IsSubtype' mangled-name='PyType_IsSubtype' filepath='./Include/object.h' line='379' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyType_IsSubtype'> + <parameter type-id='type-id-1'/> + <parameter type-id='type-id-1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyObject_RichCompareBool' mangled-name='PyObject_RichCompareBool' filepath='./Include/object.h' line='407' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_RichCompareBool'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyObject_IsTrue' mangled-name='PyObject_IsTrue' filepath='./Include/object.h' line='422' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_IsTrue'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyErr_GivenExceptionMatches' mangled-name='PyErr_GivenExceptionMatches' filepath='./Include/pyerrors.h' line='40' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_GivenExceptionMatches'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PySlice_FromIndices' mangled-name='_PySlice_FromIndices' filepath='./Include/sliceobject.h' line='36' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PySlice_FromIndices'> + <parameter type-id='type-id-14'/> + <parameter type-id='type-id-14'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyTuple_New' mangled-name='PyTuple_New' filepath='./Include/tupleobject.h' line='30' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyTuple_New'> + <parameter type-id='type-id-14'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyErr_WarnEx' mangled-name='PyErr_WarnEx' filepath='./Include/warnings.h' line='7' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_WarnEx'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-14'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyErr_WarnFormat' mangled-name='PyErr_WarnFormat' filepath='./Include/warnings.h' line='12' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_WarnFormat'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-14'/> + <parameter type-id='type-id-12'/> + <parameter is-variadic='yes'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyObject_Type' mangled-name='PyObject_Type' filepath='Objects/abstract.c' line='40' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_Type'> + <parameter type-id='type-id-2' name='o' filepath='Objects/abstract.c' line='40' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyObject_Size' mangled-name='PyObject_Size' filepath='Objects/abstract.c' line='53' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_Size'> + <parameter type-id='type-id-2' name='o' filepath='Objects/abstract.c' line='53' column='1'/> + <return type-id='type-id-14'/> + </function-decl> + <function-decl name='PyObject_Length' mangled-name='PyObject_Length' filepath='Objects/abstract.c' line='72' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_Length'> + <parameter type-id='type-id-2' name='o' filepath='Objects/abstract.c' line='72' column='1'/> + <return type-id='type-id-14'/> + </function-decl> + <function-decl name='_PyObject_HasLen' mangled-name='_PyObject_HasLen' filepath='Objects/abstract.c' line='79' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_HasLen'> + <parameter type-id='type-id-2' name='o' filepath='Objects/abstract.c' line='79' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyObject_LengthHint' mangled-name='PyObject_LengthHint' filepath='Objects/abstract.c' line='91' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_LengthHint'> + <parameter type-id='type-id-2' name='o' filepath='Objects/abstract.c' line='91' column='1'/> + <parameter type-id='type-id-14' name='defaultvalue' filepath='Objects/abstract.c' line='91' column='1'/> + <return type-id='type-id-14'/> + </function-decl> + <function-decl name='PyObject_GetItem' mangled-name='PyObject_GetItem' filepath='Objects/abstract.c' line='149' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_GetItem'> + <parameter type-id='type-id-2' name='o' filepath='Objects/abstract.c' line='149' column='1'/> + <parameter type-id='type-id-2' name='key' filepath='Objects/abstract.c' line='149' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyObject_SetItem' mangled-name='PyObject_SetItem' filepath='Objects/abstract.c' line='203' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_SetItem'> + <parameter type-id='type-id-2' name='o' filepath='Objects/abstract.c' line='203' column='1'/> + <parameter type-id='type-id-2' name='key' filepath='Objects/abstract.c' line='203' column='1'/> + <parameter type-id='type-id-2' name='value' filepath='Objects/abstract.c' line='203' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyObject_DelItem' mangled-name='PyObject_DelItem' filepath='Objects/abstract.c' line='237' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_DelItem'> + <parameter type-id='type-id-2' name='o' filepath='Objects/abstract.c' line='237' column='1'/> + <parameter type-id='type-id-2' name='key' filepath='Objects/abstract.c' line='237' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyObject_DelItemString' mangled-name='PyObject_DelItemString' filepath='Objects/abstract.c' line='271' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_DelItemString'> + <parameter type-id='type-id-2' name='o' filepath='Objects/abstract.c' line='271' column='1'/> + <parameter type-id='type-id-12' name='key' filepath='Objects/abstract.c' line='271' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyObject_CheckBuffer' mangled-name='PyObject_CheckBuffer' filepath='Objects/abstract.c' line='291' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_CheckBuffer'> + <parameter type-id='type-id-2' name='obj' filepath='Objects/abstract.c' line='291' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyObject_CheckReadBuffer' mangled-name='PyObject_CheckReadBuffer' filepath='Objects/abstract.c' line='302' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_CheckReadBuffer'> + <parameter type-id='type-id-2' name='obj' filepath='Objects/abstract.c' line='302' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyObject_AsCharBuffer' mangled-name='PyObject_AsCharBuffer' filepath='Objects/abstract.c' line='337' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_AsCharBuffer'> + <parameter type-id='type-id-2' name='obj' filepath='Objects/abstract.c' line='337' column='1'/> + <parameter type-id='type-id-252' name='buffer' filepath='Objects/abstract.c' line='338' column='1'/> + <parameter type-id='type-id-13' name='buffer_len' filepath='Objects/abstract.c' line='339' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyObject_AsReadBuffer' mangled-name='PyObject_AsReadBuffer' filepath='Objects/abstract.c' line='344' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_AsReadBuffer'> + <parameter type-id='type-id-2' name='obj' filepath='Objects/abstract.c' line='344' column='1'/> + <parameter type-id='type-id-253' name='buffer' filepath='Objects/abstract.c' line='345' column='1'/> + <parameter type-id='type-id-13' name='buffer_len' filepath='Objects/abstract.c' line='346' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyObject_AsWriteBuffer' mangled-name='PyObject_AsWriteBuffer' filepath='Objects/abstract.c' line='351' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_AsWriteBuffer'> + <parameter type-id='type-id-2' name='obj' filepath='Objects/abstract.c' line='351' column='1'/> + <parameter type-id='type-id-253' name='buffer' filepath='Objects/abstract.c' line='352' column='1'/> + <parameter type-id='type-id-13' name='buffer_len' filepath='Objects/abstract.c' line='353' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyObject_GetBuffer' mangled-name='PyObject_GetBuffer' filepath='Objects/abstract.c' line='380' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_GetBuffer'> + <parameter type-id='type-id-2' name='obj' filepath='Objects/abstract.c' line='380' column='1'/> + <parameter type-id='type-id-254' name='view' filepath='Objects/abstract.c' line='380' column='1'/> + <parameter type-id='type-id-8' name='flags' filepath='Objects/abstract.c' line='380' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyBuffer_IsContiguous' mangled-name='PyBuffer_IsContiguous' filepath='Objects/abstract.c' line='463' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyBuffer_IsContiguous'> + <parameter type-id='type-id-245' name='view' filepath='Objects/abstract.c' line='463' column='1'/> + <parameter type-id='type-id-48' name='order' filepath='Objects/abstract.c' line='463' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyBuffer_GetPointer' mangled-name='PyBuffer_GetPointer' filepath='Objects/abstract.c' line='479' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyBuffer_GetPointer'> + <parameter type-id='type-id-245' name='view' filepath='Objects/abstract.c' line='479' column='1'/> + <parameter type-id='type-id-247' name='indices' filepath='Objects/abstract.c' line='479' column='1'/> + <return type-id='type-id-22'/> + </function-decl> + <function-decl name='_Py_add_one_to_index_F' mangled-name='_Py_add_one_to_index_F' filepath='Objects/abstract.c' line='495' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_add_one_to_index_F'> + <parameter type-id='type-id-8' name='nd' filepath='Objects/abstract.c' line='495' column='1'/> + <parameter type-id='type-id-13' name='index' filepath='Objects/abstract.c' line='495' column='1'/> + <parameter type-id='type-id-247' name='shape' filepath='Objects/abstract.c' line='495' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_Py_add_one_to_index_C' mangled-name='_Py_add_one_to_index_C' filepath='Objects/abstract.c' line='511' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_add_one_to_index_C'> + <parameter type-id='type-id-8' name='nd' filepath='Objects/abstract.c' line='511' column='1'/> + <parameter type-id='type-id-13' name='index' filepath='Objects/abstract.c' line='511' column='1'/> + <parameter type-id='type-id-247' name='shape' filepath='Objects/abstract.c' line='511' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyBuffer_SizeFromFormat' mangled-name='PyBuffer_SizeFromFormat' filepath='Objects/abstract.c' line='527' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyBuffer_SizeFromFormat'> + <parameter type-id='type-id-12' name='format' filepath='Objects/abstract.c' line='527' column='1'/> + <return type-id='type-id-14'/> + </function-decl> + <function-decl name='PyBuffer_FromContiguous' mangled-name='PyBuffer_FromContiguous' filepath='Objects/abstract.c' line='562' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyBuffer_FromContiguous'> + <parameter type-id='type-id-245' name='view' filepath='Objects/abstract.c' line='562' column='1'/> + <parameter type-id='type-id-22' name='buf' filepath='Objects/abstract.c' line='562' column='1'/> + <parameter type-id='type-id-14' name='len' filepath='Objects/abstract.c' line='562' column='1'/> + <parameter type-id='type-id-48' name='fort' filepath='Objects/abstract.c' line='562' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyObject_CopyData' mangled-name='PyObject_CopyData' filepath='Objects/abstract.c' line='614' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_CopyData'> + <parameter type-id='type-id-2' name='dest' filepath='Objects/abstract.c' line='614' column='1'/> + <parameter type-id='type-id-2' name='src' filepath='Objects/abstract.c' line='614' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyBuffer_FillContiguousStrides' mangled-name='PyBuffer_FillContiguousStrides' filepath='Objects/abstract.c' line='685' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyBuffer_FillContiguousStrides'> + <parameter type-id='type-id-8' name='nd' filepath='Objects/abstract.c' line='685' column='1'/> + <parameter type-id='type-id-13' name='shape' filepath='Objects/abstract.c' line='685' column='1'/> + <parameter type-id='type-id-13' name='strides' filepath='Objects/abstract.c' line='686' column='1'/> + <parameter type-id='type-id-8' name='itemsize' filepath='Objects/abstract.c' line='686' column='1'/> + <parameter type-id='type-id-48' name='fort' filepath='Objects/abstract.c' line='687' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyBuffer_FillInfo' mangled-name='PyBuffer_FillInfo' filepath='Objects/abstract.c' line='709' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyBuffer_FillInfo'> + <parameter type-id='type-id-254' name='view' filepath='Objects/abstract.c' line='709' column='1'/> + <parameter type-id='type-id-2' name='obj' filepath='Objects/abstract.c' line='709' column='1'/> + <parameter type-id='type-id-22' name='buf' filepath='Objects/abstract.c' line='709' column='1'/> + <parameter type-id='type-id-14' name='len' filepath='Objects/abstract.c' line='709' column='1'/> + <parameter type-id='type-id-8' name='readonly' filepath='Objects/abstract.c' line='710' column='1'/> + <parameter type-id='type-id-8' name='flags' filepath='Objects/abstract.c' line='710' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyBuffer_Release' mangled-name='PyBuffer_Release' filepath='Objects/abstract.c' line='746' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyBuffer_Release'> + <parameter type-id='type-id-254' name='view' filepath='Objects/abstract.c' line='746' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyObject_Format' mangled-name='PyObject_Format' filepath='Objects/abstract.c' line='761' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_Format'> + <parameter type-id='type-id-2' name='obj' filepath='Objects/abstract.c' line='761' column='1'/> + <parameter type-id='type-id-2' name='format_spec' filepath='Objects/abstract.c' line='761' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyNumber_Check' mangled-name='PyNumber_Check' filepath='Objects/abstract.c' line='821' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_Check'> + <parameter type-id='type-id-2' name='o' filepath='Objects/abstract.c' line='821' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyNumber_Or' mangled-name='PyNumber_Or' filepath='Objects/abstract.c' line='1051' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_Or'> + <parameter type-id='type-id-2' name='v' filepath='Objects/abstract.c' line='1051' column='1'/> + <parameter type-id='type-id-2' name='w' filepath='Objects/abstract.c' line='1051' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyNumber_Xor' mangled-name='PyNumber_Xor' filepath='Objects/abstract.c' line='1052' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_Xor'> + <parameter type-id='type-id-2' name='v' filepath='Objects/abstract.c' line='1052' column='1'/> + <parameter type-id='type-id-2' name='w' filepath='Objects/abstract.c' line='1052' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyNumber_And' mangled-name='PyNumber_And' filepath='Objects/abstract.c' line='1053' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_And'> + <parameter type-id='type-id-2' name='v' filepath='Objects/abstract.c' line='1053' column='1'/> + <parameter type-id='type-id-2' name='w' filepath='Objects/abstract.c' line='1053' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyNumber_Lshift' mangled-name='PyNumber_Lshift' filepath='Objects/abstract.c' line='1054' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_Lshift'> + <parameter type-id='type-id-2' name='v' filepath='Objects/abstract.c' line='1054' column='1'/> + <parameter type-id='type-id-2' name='w' filepath='Objects/abstract.c' line='1054' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyNumber_Rshift' mangled-name='PyNumber_Rshift' filepath='Objects/abstract.c' line='1055' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_Rshift'> + <parameter type-id='type-id-2' name='v' filepath='Objects/abstract.c' line='1055' column='1'/> + <parameter type-id='type-id-2' name='w' filepath='Objects/abstract.c' line='1055' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyNumber_Subtract' mangled-name='PyNumber_Subtract' filepath='Objects/abstract.c' line='1056' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_Subtract'> + <parameter type-id='type-id-2' name='v' filepath='Objects/abstract.c' line='1056' column='1'/> + <parameter type-id='type-id-2' name='w' filepath='Objects/abstract.c' line='1056' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyNumber_Divmod' mangled-name='PyNumber_Divmod' filepath='Objects/abstract.c' line='1057' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_Divmod'> + <parameter type-id='type-id-2' name='v' filepath='Objects/abstract.c' line='1057' column='1'/> + <parameter type-id='type-id-2' name='w' filepath='Objects/abstract.c' line='1057' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyNumber_Add' mangled-name='PyNumber_Add' filepath='Objects/abstract.c' line='1060' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_Add'> + <parameter type-id='type-id-2' name='v' filepath='Objects/abstract.c' line='1060' column='1'/> + <parameter type-id='type-id-2' name='w' filepath='Objects/abstract.c' line='1060' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyNumber_Multiply' mangled-name='PyNumber_Multiply' filepath='Objects/abstract.c' line='1098' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_Multiply'> + <parameter type-id='type-id-2' name='v' filepath='Objects/abstract.c' line='1098' column='1'/> + <parameter type-id='type-id-2' name='w' filepath='Objects/abstract.c' line='1098' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyNumber_MatrixMultiply' mangled-name='PyNumber_MatrixMultiply' filepath='Objects/abstract.c' line='1117' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_MatrixMultiply'> + <parameter type-id='type-id-2' name='v' filepath='Objects/abstract.c' line='1117' column='1'/> + <parameter type-id='type-id-2' name='w' filepath='Objects/abstract.c' line='1117' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyNumber_FloorDivide' mangled-name='PyNumber_FloorDivide' filepath='Objects/abstract.c' line='1123' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_FloorDivide'> + <parameter type-id='type-id-2' name='v' filepath='Objects/abstract.c' line='1123' column='1'/> + <parameter type-id='type-id-2' name='w' filepath='Objects/abstract.c' line='1123' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyNumber_TrueDivide' mangled-name='PyNumber_TrueDivide' filepath='Objects/abstract.c' line='1129' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_TrueDivide'> + <parameter type-id='type-id-2' name='v' filepath='Objects/abstract.c' line='1129' column='1'/> + <parameter type-id='type-id-2' name='w' filepath='Objects/abstract.c' line='1129' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyNumber_Remainder' mangled-name='PyNumber_Remainder' filepath='Objects/abstract.c' line='1135' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_Remainder'> + <parameter type-id='type-id-2' name='v' filepath='Objects/abstract.c' line='1135' column='1'/> + <parameter type-id='type-id-2' name='w' filepath='Objects/abstract.c' line='1135' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyNumber_Power' mangled-name='PyNumber_Power' filepath='Objects/abstract.c' line='1141' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_Power'> + <parameter type-id='type-id-2' name='v' filepath='Objects/abstract.c' line='1141' column='1'/> + <parameter type-id='type-id-2' name='w' filepath='Objects/abstract.c' line='1141' column='1'/> + <parameter type-id='type-id-2' name='z' filepath='Objects/abstract.c' line='1141' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyNumber_InPlaceOr' mangled-name='PyNumber_InPlaceOr' filepath='Objects/abstract.c' line='1236' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_InPlaceOr'> + <parameter type-id='type-id-2' name='v' filepath='Objects/abstract.c' line='1236' column='1'/> + <parameter type-id='type-id-2' name='w' filepath='Objects/abstract.c' line='1236' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyNumber_InPlaceXor' mangled-name='PyNumber_InPlaceXor' filepath='Objects/abstract.c' line='1237' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_InPlaceXor'> + <parameter type-id='type-id-2' name='v' filepath='Objects/abstract.c' line='1237' column='1'/> + <parameter type-id='type-id-2' name='w' filepath='Objects/abstract.c' line='1237' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyNumber_InPlaceAnd' mangled-name='PyNumber_InPlaceAnd' filepath='Objects/abstract.c' line='1238' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_InPlaceAnd'> + <parameter type-id='type-id-2' name='v' filepath='Objects/abstract.c' line='1238' column='1'/> + <parameter type-id='type-id-2' name='w' filepath='Objects/abstract.c' line='1238' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyNumber_InPlaceLshift' mangled-name='PyNumber_InPlaceLshift' filepath='Objects/abstract.c' line='1239' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_InPlaceLshift'> + <parameter type-id='type-id-2' name='v' filepath='Objects/abstract.c' line='1239' column='1'/> + <parameter type-id='type-id-2' name='w' filepath='Objects/abstract.c' line='1239' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyNumber_InPlaceRshift' mangled-name='PyNumber_InPlaceRshift' filepath='Objects/abstract.c' line='1240' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_InPlaceRshift'> + <parameter type-id='type-id-2' name='v' filepath='Objects/abstract.c' line='1240' column='1'/> + <parameter type-id='type-id-2' name='w' filepath='Objects/abstract.c' line='1240' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyNumber_InPlaceSubtract' mangled-name='PyNumber_InPlaceSubtract' filepath='Objects/abstract.c' line='1241' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_InPlaceSubtract'> + <parameter type-id='type-id-2' name='v' filepath='Objects/abstract.c' line='1241' column='1'/> + <parameter type-id='type-id-2' name='w' filepath='Objects/abstract.c' line='1241' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyNumber_InPlaceMatrixMultiply' mangled-name='PyNumber_InPlaceMatrixMultiply' filepath='Objects/abstract.c' line='1242' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_InPlaceMatrixMultiply'> + <parameter type-id='type-id-2' name='v' filepath='Objects/abstract.c' line='1242' column='1'/> + <parameter type-id='type-id-2' name='w' filepath='Objects/abstract.c' line='1242' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyNumber_InPlaceFloorDivide' mangled-name='PyNumber_InPlaceFloorDivide' filepath='Objects/abstract.c' line='1243' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_InPlaceFloorDivide'> + <parameter type-id='type-id-2' name='v' filepath='Objects/abstract.c' line='1243' column='1'/> + <parameter type-id='type-id-2' name='w' filepath='Objects/abstract.c' line='1243' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyNumber_InPlaceTrueDivide' mangled-name='PyNumber_InPlaceTrueDivide' filepath='Objects/abstract.c' line='1244' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_InPlaceTrueDivide'> + <parameter type-id='type-id-2' name='v' filepath='Objects/abstract.c' line='1244' column='1'/> + <parameter type-id='type-id-2' name='w' filepath='Objects/abstract.c' line='1244' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyNumber_InPlaceRemainder' mangled-name='PyNumber_InPlaceRemainder' filepath='Objects/abstract.c' line='1245' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_InPlaceRemainder'> + <parameter type-id='type-id-2' name='v' filepath='Objects/abstract.c' line='1245' column='1'/> + <parameter type-id='type-id-2' name='w' filepath='Objects/abstract.c' line='1245' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyNumber_InPlaceAdd' mangled-name='PyNumber_InPlaceAdd' filepath='Objects/abstract.c' line='1248' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_InPlaceAdd'> + <parameter type-id='type-id-2' name='v' filepath='Objects/abstract.c' line='1248' column='1'/> + <parameter type-id='type-id-2' name='w' filepath='Objects/abstract.c' line='1248' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyNumber_InPlaceMultiply' mangled-name='PyNumber_InPlaceMultiply' filepath='Objects/abstract.c' line='1271' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_InPlaceMultiply'> + <parameter type-id='type-id-2' name='v' filepath='Objects/abstract.c' line='1271' column='1'/> + <parameter type-id='type-id-2' name='w' filepath='Objects/abstract.c' line='1271' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyNumber_InPlacePower' mangled-name='PyNumber_InPlacePower' filepath='Objects/abstract.c' line='1300' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_InPlacePower'> + <parameter type-id='type-id-2' name='v' filepath='Objects/abstract.c' line='1300' column='1'/> + <parameter type-id='type-id-2' name='w' filepath='Objects/abstract.c' line='1300' column='1'/> + <parameter type-id='type-id-2' name='z' filepath='Objects/abstract.c' line='1300' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyNumber_Negative' mangled-name='PyNumber_Negative' filepath='Objects/abstract.c' line='1316' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_Negative'> + <parameter type-id='type-id-2' name='o' filepath='Objects/abstract.c' line='1316' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyNumber_Positive' mangled-name='PyNumber_Positive' filepath='Objects/abstract.c' line='1333' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_Positive'> + <parameter type-id='type-id-2' name='o' filepath='Objects/abstract.c' line='1333' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyNumber_Invert' mangled-name='PyNumber_Invert' filepath='Objects/abstract.c' line='1350' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_Invert'> + <parameter type-id='type-id-2' name='o' filepath='Objects/abstract.c' line='1350' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyNumber_Absolute' mangled-name='PyNumber_Absolute' filepath='Objects/abstract.c' line='1367' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_Absolute'> + <parameter type-id='type-id-2' name='o' filepath='Objects/abstract.c' line='1367' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyIndex_Check' mangled-name='PyIndex_Check' filepath='Objects/abstract.c' line='1385' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyIndex_Check'> + <parameter type-id='type-id-2' name='obj' filepath='Objects/abstract.c' line='1385' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyNumber_Index' mangled-name='_PyNumber_Index' filepath='Objects/abstract.c' line='1397' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyNumber_Index'> + <parameter type-id='type-id-2' name='item' filepath='Objects/abstract.c' line='1397' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyNumber_Index' mangled-name='PyNumber_Index' filepath='Objects/abstract.c' line='1443' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_Index'> + <parameter type-id='type-id-2' name='item' filepath='Objects/abstract.c' line='1443' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyNumber_AsSsize_t' mangled-name='PyNumber_AsSsize_t' filepath='Objects/abstract.c' line='1455' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_AsSsize_t'> + <parameter type-id='type-id-2' name='item' filepath='Objects/abstract.c' line='1455' column='1'/> + <parameter type-id='type-id-2' name='err' filepath='Objects/abstract.c' line='1455' column='1'/> + <return type-id='type-id-14'/> + </function-decl> + <function-decl name='PyNumber_Long' mangled-name='PyNumber_Long' filepath='Objects/abstract.c' line='1506' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_Long'> + <parameter type-id='type-id-2' name='o' filepath='Objects/abstract.c' line='1506' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyNumber_Float' mangled-name='PyNumber_Float' filepath='Objects/abstract.c' line='1621' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_Float'> + <parameter type-id='type-id-2' name='o' filepath='Objects/abstract.c' line='1621' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyNumber_ToBase' mangled-name='PyNumber_ToBase' filepath='Objects/abstract.c' line='1682' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyNumber_ToBase'> + <parameter type-id='type-id-2' name='n' filepath='Objects/abstract.c' line='1682' column='1'/> + <parameter type-id='type-id-8' name='base' filepath='Objects/abstract.c' line='1682' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PySequence_Check' mangled-name='PySequence_Check' filepath='Objects/abstract.c' line='1701' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySequence_Check'> + <parameter type-id='type-id-2' name='s' filepath='Objects/abstract.c' line='1701' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PySequence_Size' mangled-name='PySequence_Size' filepath='Objects/abstract.c' line='1710' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySequence_Size'> + <parameter type-id='type-id-2' name='s' filepath='Objects/abstract.c' line='1710' column='1'/> + <return type-id='type-id-14'/> + </function-decl> + <function-decl name='PySequence_Length' mangled-name='PySequence_Length' filepath='Objects/abstract.c' line='1734' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySequence_Length'> + <parameter type-id='type-id-2' name='s' filepath='Objects/abstract.c' line='1734' column='1'/> + <return type-id='type-id-14'/> + </function-decl> + <function-decl name='PySequence_Concat' mangled-name='PySequence_Concat' filepath='Objects/abstract.c' line='1741' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySequence_Concat'> + <parameter type-id='type-id-2' name='s' filepath='Objects/abstract.c' line='1741' column='1'/> + <parameter type-id='type-id-2' name='o' filepath='Objects/abstract.c' line='1741' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PySequence_Repeat' mangled-name='PySequence_Repeat' filepath='Objects/abstract.c' line='1767' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySequence_Repeat'> + <parameter type-id='type-id-2' name='o' filepath='Objects/abstract.c' line='1767' column='1'/> + <parameter type-id='type-id-14' name='count' filepath='Objects/abstract.c' line='1767' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PySequence_InPlaceConcat' mangled-name='PySequence_InPlaceConcat' filepath='Objects/abstract.c' line='1798' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySequence_InPlaceConcat'> + <parameter type-id='type-id-2' name='s' filepath='Objects/abstract.c' line='1798' column='1'/> + <parameter type-id='type-id-2' name='o' filepath='Objects/abstract.c' line='1798' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PySequence_InPlaceRepeat' mangled-name='PySequence_InPlaceRepeat' filepath='Objects/abstract.c' line='1827' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySequence_InPlaceRepeat'> + <parameter type-id='type-id-2' name='o' filepath='Objects/abstract.c' line='1827' column='1'/> + <parameter type-id='type-id-14' name='count' filepath='Objects/abstract.c' line='1827' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PySequence_GetItem' mangled-name='PySequence_GetItem' filepath='Objects/abstract.c' line='1861' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySequence_GetItem'> + <parameter type-id='type-id-2' name='s' filepath='Objects/abstract.c' line='1861' column='1'/> + <parameter type-id='type-id-14' name='i' filepath='Objects/abstract.c' line='1861' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PySequence_GetSlice' mangled-name='PySequence_GetSlice' filepath='Objects/abstract.c' line='1891' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySequence_GetSlice'> + <parameter type-id='type-id-2' name='s' filepath='Objects/abstract.c' line='1891' column='1'/> + <parameter type-id='type-id-14' name='i1' filepath='Objects/abstract.c' line='1891' column='1'/> + <parameter type-id='type-id-14' name='i2' filepath='Objects/abstract.c' line='1891' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PySequence_SetItem' mangled-name='PySequence_SetItem' filepath='Objects/abstract.c' line='1913' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySequence_SetItem'> + <parameter type-id='type-id-2' name='s' filepath='Objects/abstract.c' line='1913' column='1'/> + <parameter type-id='type-id-14' name='i' filepath='Objects/abstract.c' line='1913' column='1'/> + <parameter type-id='type-id-2' name='o' filepath='Objects/abstract.c' line='1913' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PySequence_DelItem' mangled-name='PySequence_DelItem' filepath='Objects/abstract.c' line='1946' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySequence_DelItem'> + <parameter type-id='type-id-2' name='s' filepath='Objects/abstract.c' line='1946' column='1'/> + <parameter type-id='type-id-14' name='i' filepath='Objects/abstract.c' line='1946' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PySequence_SetSlice' mangled-name='PySequence_SetSlice' filepath='Objects/abstract.c' line='1979' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySequence_SetSlice'> + <parameter type-id='type-id-2' name='s' filepath='Objects/abstract.c' line='1979' column='1'/> + <parameter type-id='type-id-14' name='i1' filepath='Objects/abstract.c' line='1979' column='1'/> + <parameter type-id='type-id-14' name='i2' filepath='Objects/abstract.c' line='1979' column='1'/> + <parameter type-id='type-id-2' name='o' filepath='Objects/abstract.c' line='1979' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PySequence_DelSlice' mangled-name='PySequence_DelSlice' filepath='Objects/abstract.c' line='2002' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySequence_DelSlice'> + <parameter type-id='type-id-2' name='s' filepath='Objects/abstract.c' line='2002' column='1'/> + <parameter type-id='type-id-14' name='i1' filepath='Objects/abstract.c' line='2002' column='1'/> + <parameter type-id='type-id-14' name='i2' filepath='Objects/abstract.c' line='2002' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PySequence_Tuple' mangled-name='PySequence_Tuple' filepath='Objects/abstract.c' line='2025' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySequence_Tuple'> + <parameter type-id='type-id-2' name='v' filepath='Objects/abstract.c' line='2025' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PySequence_List' mangled-name='PySequence_List' filepath='Objects/abstract.c' line='2108' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySequence_List'> + <parameter type-id='type-id-2' name='v' filepath='Objects/abstract.c' line='2108' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PySequence_Fast' mangled-name='PySequence_Fast' filepath='Objects/abstract.c' line='2131' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySequence_Fast'> + <parameter type-id='type-id-2' name='v' filepath='Objects/abstract.c' line='2131' column='1'/> + <parameter type-id='type-id-12' name='m' filepath='Objects/abstract.c' line='2131' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PySequence_IterSearch' mangled-name='_PySequence_IterSearch' filepath='Objects/abstract.c' line='2165' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PySequence_IterSearch'> + <parameter type-id='type-id-2' name='seq' filepath='Objects/abstract.c' line='2165' column='1'/> + <parameter type-id='type-id-2' name='obj' filepath='Objects/abstract.c' line='2165' column='1'/> + <parameter type-id='type-id-8' name='operation' filepath='Objects/abstract.c' line='2165' column='1'/> + <return type-id='type-id-14'/> + </function-decl> + <function-decl name='PySequence_Count' mangled-name='PySequence_Count' filepath='Objects/abstract.c' line='2250' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySequence_Count'> + <parameter type-id='type-id-2' name='s' filepath='Objects/abstract.c' line='2250' column='1'/> + <parameter type-id='type-id-2' name='o' filepath='Objects/abstract.c' line='2250' column='1'/> + <return type-id='type-id-14'/> + </function-decl> + <function-decl name='PySequence_Contains' mangled-name='PySequence_Contains' filepath='Objects/abstract.c' line='2259' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySequence_Contains'> + <parameter type-id='type-id-2' name='seq' filepath='Objects/abstract.c' line='2259' column='1'/> + <parameter type-id='type-id-2' name='ob' filepath='Objects/abstract.c' line='2259' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PySequence_In' mangled-name='PySequence_In' filepath='Objects/abstract.c' line='2274' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySequence_In'> + <parameter type-id='type-id-2' name='w' filepath='Objects/abstract.c' line='2274' column='1'/> + <parameter type-id='type-id-2' name='v' filepath='Objects/abstract.c' line='2274' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PySequence_Index' mangled-name='PySequence_Index' filepath='Objects/abstract.c' line='2280' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySequence_Index'> + <parameter type-id='type-id-2' name='s' filepath='Objects/abstract.c' line='2280' column='1'/> + <parameter type-id='type-id-2' name='o' filepath='Objects/abstract.c' line='2280' column='1'/> + <return type-id='type-id-14'/> + </function-decl> + <function-decl name='PyMapping_Check' mangled-name='PyMapping_Check' filepath='Objects/abstract.c' line='2288' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMapping_Check'> + <parameter type-id='type-id-2' name='o' filepath='Objects/abstract.c' line='2288' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyMapping_Size' mangled-name='PyMapping_Size' filepath='Objects/abstract.c' line='2295' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMapping_Size'> + <parameter type-id='type-id-2' name='o' filepath='Objects/abstract.c' line='2295' column='1'/> + <return type-id='type-id-14'/> + </function-decl> + <function-decl name='PyMapping_Length' mangled-name='PyMapping_Length' filepath='Objects/abstract.c' line='2320' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMapping_Length'> + <parameter type-id='type-id-2' name='o' filepath='Objects/abstract.c' line='2320' column='1'/> + <return type-id='type-id-14'/> + </function-decl> + <function-decl name='PyMapping_GetItemString' mangled-name='PyMapping_GetItemString' filepath='Objects/abstract.c' line='2327' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMapping_GetItemString'> + <parameter type-id='type-id-2' name='o' filepath='Objects/abstract.c' line='2327' column='1'/> + <parameter type-id='type-id-12' name='key' filepath='Objects/abstract.c' line='2327' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyMapping_SetItemString' mangled-name='PyMapping_SetItemString' filepath='Objects/abstract.c' line='2344' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMapping_SetItemString'> + <parameter type-id='type-id-2' name='o' filepath='Objects/abstract.c' line='2344' column='1'/> + <parameter type-id='type-id-12' name='key' filepath='Objects/abstract.c' line='2344' column='1'/> + <parameter type-id='type-id-2' name='value' filepath='Objects/abstract.c' line='2344' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyMapping_HasKeyString' mangled-name='PyMapping_HasKeyString' filepath='Objects/abstract.c' line='2363' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMapping_HasKeyString'> + <parameter type-id='type-id-2' name='o' filepath='Objects/abstract.c' line='2363' column='1'/> + <parameter type-id='type-id-12' name='key' filepath='Objects/abstract.c' line='2363' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyMapping_HasKey' mangled-name='PyMapping_HasKey' filepath='Objects/abstract.c' line='2377' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMapping_HasKey'> + <parameter type-id='type-id-2' name='o' filepath='Objects/abstract.c' line='2377' column='1'/> + <parameter type-id='type-id-2' name='key' filepath='Objects/abstract.c' line='2377' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyMapping_Keys' mangled-name='PyMapping_Keys' filepath='Objects/abstract.c' line='2423' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMapping_Keys'> + <parameter type-id='type-id-2' name='o' filepath='Objects/abstract.c' line='2423' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyMapping_Items' mangled-name='PyMapping_Items' filepath='Objects/abstract.c' line='2435' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMapping_Items'> + <parameter type-id='type-id-2' name='o' filepath='Objects/abstract.c' line='2435' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyMapping_Values' mangled-name='PyMapping_Values' filepath='Objects/abstract.c' line='2447' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMapping_Values'> + <parameter type-id='type-id-2' name='o' filepath='Objects/abstract.c' line='2447' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyObject_IsInstance' mangled-name='PyObject_IsInstance' filepath='Objects/abstract.c' line='2667' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_IsInstance'> + <parameter type-id='type-id-2' name='inst' filepath='Objects/abstract.c' line='2667' column='1'/> + <parameter type-id='type-id-2' name='cls' filepath='Objects/abstract.c' line='2667' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyObject_IsSubclass' mangled-name='PyObject_IsSubclass' filepath='Objects/abstract.c' line='2755' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_IsSubclass'> + <parameter type-id='type-id-2' name='derived' filepath='Objects/abstract.c' line='2755' column='1'/> + <parameter type-id='type-id-2' name='cls' filepath='Objects/abstract.c' line='2755' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyObject_RealIsInstance' mangled-name='_PyObject_RealIsInstance' filepath='Objects/abstract.c' line='2763' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_RealIsInstance'> + <parameter type-id='type-id-2' name='inst' filepath='Objects/abstract.c' line='2763' column='1'/> + <parameter type-id='type-id-2' name='cls' filepath='Objects/abstract.c' line='2763' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyObject_RealIsSubclass' mangled-name='_PyObject_RealIsSubclass' filepath='Objects/abstract.c' line='2769' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_RealIsSubclass'> + <parameter type-id='type-id-2' name='derived' filepath='Objects/abstract.c' line='2769' column='1'/> + <parameter type-id='type-id-2' name='cls' filepath='Objects/abstract.c' line='2769' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyObject_GetIter' mangled-name='PyObject_GetIter' filepath='Objects/abstract.c' line='2776' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_GetIter'> + <parameter type-id='type-id-2' name='o' filepath='Objects/abstract.c' line='2776' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyObject_GetAIter' mangled-name='PyObject_GetAIter' filepath='Objects/abstract.c' line='2801' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_GetAIter'> + <parameter type-id='type-id-2' name='o' filepath='Objects/abstract.c' line='2801' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyIter_Check' mangled-name='PyIter_Check' filepath='Objects/abstract.c' line='2820' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyIter_Check'> + <parameter type-id='type-id-2' name='obj' filepath='Objects/abstract.c' line='2820' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyAIter_Check' mangled-name='PyAIter_Check' filepath='Objects/abstract.c' line='2828' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyAIter_Check'> + <parameter type-id='type-id-2' name='obj' filepath='Objects/abstract.c' line='2828' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyIter_Next' mangled-name='PyIter_Next' filepath='Objects/abstract.c' line='2844' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyIter_Next'> + <parameter type-id='type-id-2' name='iter' filepath='Objects/abstract.c' line='2844' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyIter_Send' mangled-name='PyIter_Send' filepath='Objects/abstract.c' line='2860' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyIter_Send'> + <parameter type-id='type-id-2' name='iter' filepath='Objects/abstract.c' line='2860' column='1'/> + <parameter type-id='type-id-2' name='arg' filepath='Objects/abstract.c' line='2860' column='1'/> + <parameter type-id='type-id-233' name='result' filepath='Objects/abstract.c' line='2860' column='1'/> + <return type-id='type-id-255'/> + </function-decl> + <function-decl name='_PySequence_BytesToCharpArray' mangled-name='_PySequence_BytesToCharpArray' filepath='Objects/abstract.c' line='2893' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PySequence_BytesToCharpArray'> + <parameter type-id='type-id-2' name='self' filepath='Objects/abstract.c' line='2893' column='1'/> + <return type-id='type-id-136'/> + </function-decl> + <function-decl name='_Py_FreeCharPArray' mangled-name='_Py_FreeCharPArray' filepath='Objects/abstract.c' line='2952' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_FreeCharPArray'> + <parameter type-id='type-id-136' name='array' filepath='Objects/abstract.c' line='2952' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <pointer-type-def type-id='type-id-22' size-in-bits='64' id='type-id-253'/> + </abi-instr> + <abi-instr address-size='64' path='Objects/boolobject.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <var-decl name='_Py_FalseStruct' type-id='type-id-240' mangled-name='_Py_FalseStruct' visibility='default' filepath='./Include/boolobject.h' line='17' column='1' elf-symbol-id='_Py_FalseStruct'/> + <var-decl name='_Py_TrueStruct' type-id='type-id-240' mangled-name='_Py_TrueStruct' visibility='default' filepath='./Include/boolobject.h' line='18' column='1' elf-symbol-id='_Py_TrueStruct'/> + <function-decl name='_PyArg_NoKeywords' mangled-name='_PyArg_NoKeywords' filepath='./Include/cpython/modsupport.h' line='27' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyArg_NoKeywords'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyArg_NoKwnames' mangled-name='_PyArg_NoKwnames' filepath='./Include/cpython/modsupport.h' line='28' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyArg_NoKwnames'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyArg_CheckPositional' mangled-name='_PyArg_CheckPositional' filepath='./Include/cpython/modsupport.h' line='40' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyArg_CheckPositional'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-14'/> + <parameter type-id='type-id-14'/> + <parameter type-id='type-id-14'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyArg_UnpackTuple' mangled-name='PyArg_UnpackTuple' filepath='./Include/modsupport.h' line='35' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyArg_UnpackTuple'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-14'/> + <parameter type-id='type-id-14'/> + <parameter is-variadic='yes'/> + <return type-id='type-id-8'/> + </function-decl> + <var-decl name='PyBool_Type' type-id='type-id-256' mangled-name='PyBool_Type' visibility='default' filepath='./Include/object.h' line='227' column='1' elf-symbol-id='PyBool_Type'/> + <function-decl name='PyBool_FromLong' mangled-name='PyBool_FromLong' filepath='Objects/boolobject.c' line='21' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyBool_FromLong'> + <parameter type-id='type-id-47' name='ok' filepath='Objects/boolobject.c' line='21' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Objects/bytearrayobject.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <array-type-def dimensions='1' type-id='type-id-48' size-in-bits='infinite' id='type-id-257'> + <subrange length='infinite' id='type-id-225'/> + </array-type-def> + <qualified-type-def type-id='type-id-258' const='yes' id='type-id-259'/> + <pointer-type-def type-id='type-id-259' size-in-bits='64' id='type-id-260'/> + <qualified-type-def type-id='type-id-8' const='yes' id='type-id-261'/> + <var-decl name='PyByteArray_Type' type-id='type-id-256' mangled-name='PyByteArray_Type' visibility='default' filepath='./Include/bytearrayobject.h' line='20' column='1' elf-symbol-id='PyByteArray_Type'/> + <var-decl name='PyByteArrayIter_Type' type-id='type-id-256' mangled-name='PyByteArrayIter_Type' visibility='default' filepath='./Include/bytearrayobject.h' line='21' column='1' elf-symbol-id='PyByteArrayIter_Type'/> + <var-decl name='_PyByteArray_empty_string' type-id='type-id-257' mangled-name='_PyByteArray_empty_string' visibility='default' filepath='./Include/cpython/bytearrayobject.h' line='14' column='1' elf-symbol-id='_PyByteArray_empty_string'/> + <function-decl name='_PyBytes_FormatEx' mangled-name='_PyBytes_FormatEx' filepath='./Include/cpython/bytesobject.h' line='18' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyBytes_FormatEx'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-14'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyBytes_FromHex' mangled-name='_PyBytes_FromHex' filepath='./Include/cpython/bytesobject.h' line='23' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyBytes_FromHex'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyEval_GetBuiltin' mangled-name='_PyEval_GetBuiltin' filepath='./Include/cpython/ceval.h' line='13' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyEval_GetBuiltin'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyLong_AsInt' mangled-name='_PyLong_AsInt' filepath='./Include/cpython/longobject.h' line='5' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyLong_AsInt'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyArg_BadArgument' mangled-name='_PyArg_BadArgument' filepath='./Include/cpython/modsupport.h' line='39' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyArg_BadArgument'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyArg_UnpackKeywords' mangled-name='_PyArg_UnpackKeywords' filepath='./Include/cpython/modsupport.h' line='88' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyArg_UnpackKeywords'> + <parameter type-id='type-id-248'/> + <parameter type-id='type-id-14'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-262'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-233'/> + <return type-id='type-id-248'/> + </function-decl> + <function-decl name='_Py_GetConfig' mangled-name='_Py_GetConfig' filepath='./Include/cpython/pystate.h' line='368' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_GetConfig'> + <return type-id='type-id-260'/> + </function-decl> + <function-decl name='_Py_bytes_isspace' filepath='./Include/internal/pycore_bytes_methods.h' line='13' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-14'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_Py_bytes_isalpha' filepath='./Include/internal/pycore_bytes_methods.h' line='14' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-14'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_Py_bytes_isalnum' filepath='./Include/internal/pycore_bytes_methods.h' line='15' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-14'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_Py_bytes_isascii' filepath='./Include/internal/pycore_bytes_methods.h' line='16' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-14'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_Py_bytes_isdigit' filepath='./Include/internal/pycore_bytes_methods.h' line='17' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-14'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_Py_bytes_islower' filepath='./Include/internal/pycore_bytes_methods.h' line='18' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-14'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_Py_bytes_isupper' filepath='./Include/internal/pycore_bytes_methods.h' line='19' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-14'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_Py_bytes_istitle' filepath='./Include/internal/pycore_bytes_methods.h' line='20' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-14'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_Py_bytes_lower' filepath='./Include/internal/pycore_bytes_methods.h' line='23' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-15'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-14'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_Py_bytes_upper' filepath='./Include/internal/pycore_bytes_methods.h' line='24' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-15'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-14'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_Py_bytes_title' filepath='./Include/internal/pycore_bytes_methods.h' line='25' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-15'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-14'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_Py_bytes_capitalize' filepath='./Include/internal/pycore_bytes_methods.h' line='26' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-15'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-14'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_Py_bytes_swapcase' filepath='./Include/internal/pycore_bytes_methods.h' line='27' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-15'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-14'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_Py_bytes_find' filepath='./Include/internal/pycore_bytes_methods.h' line='29' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-14'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_Py_bytes_index' filepath='./Include/internal/pycore_bytes_methods.h' line='30' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-14'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_Py_bytes_rfind' filepath='./Include/internal/pycore_bytes_methods.h' line='31' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-14'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_Py_bytes_rindex' filepath='./Include/internal/pycore_bytes_methods.h' line='32' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-14'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_Py_bytes_count' filepath='./Include/internal/pycore_bytes_methods.h' line='33' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-14'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_Py_bytes_contains' filepath='./Include/internal/pycore_bytes_methods.h' line='34' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-14'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_Py_bytes_startswith' filepath='./Include/internal/pycore_bytes_methods.h' line='35' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-14'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_Py_bytes_endswith' filepath='./Include/internal/pycore_bytes_methods.h' line='36' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-14'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_Py_bytes_maketrans' filepath='./Include/internal/pycore_bytes_methods.h' line='39' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-254'/> + <parameter type-id='type-id-254'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyBytes_Repeat' mangled-name='_PyBytes_Repeat' filepath='./Include/internal/pycore_bytesobject.h' line='41' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyBytes_Repeat'> + <parameter type-id='type-id-15'/> + <parameter type-id='type-id-14'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-14'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_Py_strhex_with_sep' mangled-name='_Py_strhex_with_sep' filepath='./Include/internal/pycore_strhex.h' line='22' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_strhex_with_sep'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-246'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-261'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyList_Append' mangled-name='PyList_Append' filepath='./Include/listobject.h' line='34' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyList_Append'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyList_Reverse' mangled-name='PyList_Reverse' filepath='./Include/listobject.h' line='40' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyList_Reverse'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyLong_FromSize_t' mangled-name='PyLong_FromSize_t' filepath='./Include/longobject.h' line='18' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyLong_FromSize_t'> + <parameter type-id='type-id-19'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyLong_AsLongAndOverflow' mangled-name='PyLong_AsLongAndOverflow' filepath='./Include/longobject.h' line='22' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyLong_AsLongAndOverflow'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-179'/> + <return type-id='type-id-47'/> + </function-decl> + <function-decl name='PyType_GenericAlloc' mangled-name='PyType_GenericAlloc' filepath='./Include/object.h' line='395' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyType_GenericAlloc'> + <parameter type-id='type-id-1'/> + <parameter type-id='type-id-14'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyType_GenericNew' mangled-name='PyType_GenericNew' filepath='./Include/object.h' line='396' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyType_GenericNew'> + <parameter type-id='type-id-1'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyObject_SelfIter' mangled-name='PyObject_SelfIter' filepath='./Include/object.h' line='414' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_SelfIter'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyObject_GenericGetAttr' mangled-name='PyObject_GenericGetAttr' filepath='./Include/object.h' line='415' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_GenericGetAttr'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyObject_GetState' mangled-name='_PyObject_GetState' filepath='./Include/object.h' line='436' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_GetState'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyObject_Malloc' mangled-name='PyObject_Malloc' filepath='./Include/objimpl.h' line='97' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_Malloc'> + <parameter type-id='type-id-19'/> + <return type-id='type-id-22'/> + </function-decl> + <function-decl name='PyObject_Realloc' mangled-name='PyObject_Realloc' filepath='./Include/objimpl.h' line='101' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_Realloc'> + <parameter type-id='type-id-22'/> + <parameter type-id='type-id-19'/> + <return type-id='type-id-22'/> + </function-decl> + <function-decl name='PyObject_Free' mangled-name='PyObject_Free' filepath='./Include/objimpl.h' line='102' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_Free'> + <parameter type-id='type-id-22'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyObject_New' mangled-name='_PyObject_New' filepath='./Include/objimpl.h' line='131' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_New'> + <parameter type-id='type-id-1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyObject_GC_New' mangled-name='_PyObject_GC_New' filepath='./Include/objimpl.h' line='188' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_GC_New'> + <parameter type-id='type-id-1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyObject_GC_Del' mangled-name='PyObject_GC_Del' filepath='./Include/objimpl.h' line='201' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_GC_Del'> + <parameter type-id='type-id-22'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyBuffer_ToContiguous' mangled-name='PyBuffer_ToContiguous' filepath='./Include/pybuffer.h' line='58' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyBuffer_ToContiguous'> + <parameter type-id='type-id-22'/> + <parameter type-id='type-id-245'/> + <parameter type-id='type-id-14'/> + <parameter type-id='type-id-48'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyErr_Print' mangled-name='PyErr_Print' filepath='./Include/pythonrun.h' line='12' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_Print'> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PySlice_Unpack' mangled-name='PySlice_Unpack' filepath='./Include/sliceobject.h' line='55' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySlice_Unpack'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-13'/> + <parameter type-id='type-id-13'/> + <parameter type-id='type-id-13'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PySlice_AdjustIndices' mangled-name='PySlice_AdjustIndices' filepath='./Include/sliceobject.h' line='57' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySlice_AdjustIndices'> + <parameter type-id='type-id-14'/> + <parameter type-id='type-id-13'/> + <parameter type-id='type-id-13'/> + <parameter type-id='type-id-14'/> + <return type-id='type-id-14'/> + </function-decl> + <function-decl name='PyUnicode_FromEncodedObject' mangled-name='PyUnicode_FromEncodedObject' filepath='./Include/unicodeobject.h' line='226' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_FromEncodedObject'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-12'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyUnicode_GetDefaultEncoding' mangled-name='PyUnicode_GetDefaultEncoding' filepath='./Include/unicodeobject.h' line='338' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_GetDefaultEncoding'> + <return type-id='type-id-12'/> + </function-decl> + <function-decl name='PyUnicode_AsEncodedString' mangled-name='PyUnicode_AsEncodedString' filepath='./Include/unicodeobject.h' line='395' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_AsEncodedString'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-12'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyUnicode_DecodeLatin1' mangled-name='PyUnicode_DecodeLatin1' filepath='./Include/unicodeobject.h' line='617' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_DecodeLatin1'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-14'/> + <parameter type-id='type-id-12'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='memmove' filepath='/usr/include/string.h' line='47' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-22'/> + <parameter type-id='type-id-22'/> + <parameter type-id='type-id-19'/> + <return type-id='type-id-22'/> + </function-decl> + <function-decl name='memset' filepath='/usr/include/string.h' line='61' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-22'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-19'/> + <return type-id='type-id-22'/> + </function-decl> + <function-decl name='PyByteArray_FromObject' mangled-name='PyByteArray_FromObject' filepath='Objects/bytearrayobject.c' line='83' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyByteArray_FromObject'> + <parameter type-id='type-id-2' name='input' filepath='Objects/bytearrayobject.c' line='83' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyByteArray_FromStringAndSize' mangled-name='PyByteArray_FromStringAndSize' filepath='Objects/bytearrayobject.c' line='109' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyByteArray_FromStringAndSize'> + <parameter type-id='type-id-12' name='bytes' filepath='Objects/bytearrayobject.c' line='109' column='1'/> + <parameter type-id='type-id-14' name='size' filepath='Objects/bytearrayobject.c' line='109' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyByteArray_Size' mangled-name='PyByteArray_Size' filepath='Objects/bytearrayobject.c' line='153' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyByteArray_Size'> + <parameter type-id='type-id-2' name='self' filepath='Objects/bytearrayobject.c' line='153' column='1'/> + <return type-id='type-id-14'/> + </function-decl> + <function-decl name='PyByteArray_AsString' mangled-name='PyByteArray_AsString' filepath='Objects/bytearrayobject.c' line='162' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyByteArray_AsString'> + <parameter type-id='type-id-2' name='self' filepath='Objects/bytearrayobject.c' line='162' column='1'/> + <return type-id='type-id-15'/> + </function-decl> + <function-decl name='PyByteArray_Resize' mangled-name='PyByteArray_Resize' filepath='Objects/bytearrayobject.c' line='171' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyByteArray_Resize'> + <parameter type-id='type-id-2' name='self' filepath='Objects/bytearrayobject.c' line='171' column='1'/> + <parameter type-id='type-id-14' name='requested_size' filepath='Objects/bytearrayobject.c' line='171' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyByteArray_Concat' mangled-name='PyByteArray_Concat' filepath='Objects/bytearrayobject.c' line='250' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyByteArray_Concat'> + <parameter type-id='type-id-2' name='a' filepath='Objects/bytearrayobject.c' line='250' column='1'/> + <parameter type-id='type-id-2' name='b' filepath='Objects/bytearrayobject.c' line='250' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Objects/bytes_methods.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <array-type-def dimensions='1' type-id='type-id-50' size-in-bits='984' id='type-id-263'> + <subrange length='123' type-id='type-id-28' id='type-id-264'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-50' size-in-bits='992' id='type-id-265'> + <subrange length='124' type-id='type-id-28' id='type-id-266'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-50' size-in-bits='1008' id='type-id-267'> + <subrange length='126' type-id='type-id-28' id='type-id-268'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-50' size-in-bits='1040' id='type-id-269'> + <subrange length='130' type-id='type-id-28' id='type-id-270'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-50' size-in-bits='1056' id='type-id-271'> + <subrange length='132' type-id='type-id-28' id='type-id-272'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-50' size-in-bits='1128' id='type-id-273'> + <subrange length='141' type-id='type-id-28' id='type-id-274'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-50' size-in-bits='1240' id='type-id-275'> + <subrange length='155' type-id='type-id-28' id='type-id-276'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-50' size-in-bits='1592' id='type-id-277'> + <subrange length='199' type-id='type-id-28' id='type-id-278'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-50' size-in-bits='1840' id='type-id-279'> + <subrange length='230' type-id='type-id-28' id='type-id-280'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-50' size-in-bits='1912' id='type-id-281'> + <subrange length='239' type-id='type-id-28' id='type-id-282'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-50' size-in-bits='1928' id='type-id-283'> + <subrange length='241' type-id='type-id-28' id='type-id-284'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-50' size-in-bits='2112' id='type-id-285'> + <subrange length='264' type-id='type-id-28' id='type-id-286'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-50' size-in-bits='2144' id='type-id-287'> + <subrange length='268' type-id='type-id-28' id='type-id-288'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-50' size-in-bits='2160' id='type-id-289'> + <subrange length='270' type-id='type-id-28' id='type-id-290'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-50' size-in-bits='2168' id='type-id-291'> + <subrange length='271' type-id='type-id-28' id='type-id-292'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-50' size-in-bits='2328' id='type-id-293'> + <subrange length='291' type-id='type-id-28' id='type-id-294'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-50' size-in-bits='744' id='type-id-295'> + <subrange length='93' type-id='type-id-28' id='type-id-296'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-50' size-in-bits='784' id='type-id-297'> + <subrange length='98' type-id='type-id-28' id='type-id-298'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-50' size-in-bits='infinite' id='type-id-299'> + <subrange length='infinite' id='type-id-225'/> + </array-type-def> + <function-decl name='_PyEval_SliceIndex' mangled-name='_PyEval_SliceIndex' filepath='./Include/cpython/ceval.h' line='34' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyEval_SliceIndex'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-13'/> + <return type-id='type-id-8'/> + </function-decl> + <var-decl name='_Py_isspace__doc__' type-id='type-id-299' visibility='default' filepath='./Include/internal/pycore_bytes_methods.h' line='42' column='1'/> + <var-decl name='_Py_isalpha__doc__' type-id='type-id-299' visibility='default' filepath='./Include/internal/pycore_bytes_methods.h' line='43' column='1'/> + <var-decl name='_Py_isalnum__doc__' type-id='type-id-299' visibility='default' filepath='./Include/internal/pycore_bytes_methods.h' line='44' column='1'/> + <var-decl name='_Py_isascii__doc__' type-id='type-id-299' visibility='default' filepath='./Include/internal/pycore_bytes_methods.h' line='45' column='1'/> + <var-decl name='_Py_isdigit__doc__' type-id='type-id-299' visibility='default' filepath='./Include/internal/pycore_bytes_methods.h' line='46' column='1'/> + <var-decl name='_Py_islower__doc__' type-id='type-id-299' visibility='default' filepath='./Include/internal/pycore_bytes_methods.h' line='47' column='1'/> + <var-decl name='_Py_isupper__doc__' type-id='type-id-299' visibility='default' filepath='./Include/internal/pycore_bytes_methods.h' line='48' column='1'/> + <var-decl name='_Py_istitle__doc__' type-id='type-id-299' visibility='default' filepath='./Include/internal/pycore_bytes_methods.h' line='49' column='1'/> + <var-decl name='_Py_lower__doc__' type-id='type-id-299' visibility='default' filepath='./Include/internal/pycore_bytes_methods.h' line='50' column='1'/> + <var-decl name='_Py_upper__doc__' type-id='type-id-299' visibility='default' filepath='./Include/internal/pycore_bytes_methods.h' line='51' column='1'/> + <var-decl name='_Py_title__doc__' type-id='type-id-299' visibility='default' filepath='./Include/internal/pycore_bytes_methods.h' line='52' column='1'/> + <var-decl name='_Py_capitalize__doc__' type-id='type-id-299' visibility='default' filepath='./Include/internal/pycore_bytes_methods.h' line='53' column='1'/> + <var-decl name='_Py_swapcase__doc__' type-id='type-id-299' visibility='default' filepath='./Include/internal/pycore_bytes_methods.h' line='54' column='1'/> + <var-decl name='_Py_count__doc__' type-id='type-id-299' visibility='default' filepath='./Include/internal/pycore_bytes_methods.h' line='55' column='1'/> + <var-decl name='_Py_find__doc__' type-id='type-id-299' visibility='default' filepath='./Include/internal/pycore_bytes_methods.h' line='56' column='1'/> + <var-decl name='_Py_index__doc__' type-id='type-id-299' visibility='default' filepath='./Include/internal/pycore_bytes_methods.h' line='57' column='1'/> + <var-decl name='_Py_rfind__doc__' type-id='type-id-299' visibility='default' filepath='./Include/internal/pycore_bytes_methods.h' line='58' column='1'/> + <var-decl name='_Py_rindex__doc__' type-id='type-id-299' visibility='default' filepath='./Include/internal/pycore_bytes_methods.h' line='59' column='1'/> + <var-decl name='_Py_startswith__doc__' type-id='type-id-299' visibility='default' filepath='./Include/internal/pycore_bytes_methods.h' line='60' column='1'/> + <var-decl name='_Py_endswith__doc__' type-id='type-id-299' visibility='default' filepath='./Include/internal/pycore_bytes_methods.h' line='61' column='1'/> + <var-decl name='_Py_maketrans__doc__' type-id='type-id-299' visibility='default' filepath='./Include/internal/pycore_bytes_methods.h' line='62' column='1'/> + <function-decl name='_PyArg_ParseTuple_SizeT' mangled-name='_PyArg_ParseTuple_SizeT' filepath='./Include/modsupport.h' line='27' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyArg_ParseTuple_SizeT'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-12'/> + <parameter is-variadic='yes'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='memrchr' filepath='/usr/include/string.h' line='133' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-22'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-19'/> + <return type-id='type-id-22'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Objects/bytesobject.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <array-type-def dimensions='1' type-id='type-id-48' size-in-bits='4096' id='type-id-300'> + <subrange length='512' type-id='type-id-28' id='type-id-301'/> + </array-type-def> + <class-decl name='_PyBytesWriter' size-in-bits='4416' is-struct='yes' naming-typedef-id='type-id-302' visibility='default' filepath='./Include/cpython/bytesobject.h' line='55' column='1' id='type-id-303'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='buffer' type-id='type-id-2' visibility='default' filepath='./Include/cpython/bytesobject.h' line='57' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='allocated' type-id='type-id-14' visibility='default' filepath='./Include/cpython/bytesobject.h' line='60' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='min_size' type-id='type-id-14' visibility='default' filepath='./Include/cpython/bytesobject.h' line='64' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='use_bytearray' type-id='type-id-8' visibility='default' filepath='./Include/cpython/bytesobject.h' line='67' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='224'> + <var-decl name='overallocate' type-id='type-id-8' visibility='default' filepath='./Include/cpython/bytesobject.h' line='71' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='use_small_buffer' type-id='type-id-8' visibility='default' filepath='./Include/cpython/bytesobject.h' line='74' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='288'> + <var-decl name='small_buffer' type-id='type-id-300' visibility='default' filepath='./Include/cpython/bytesobject.h' line='75' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='_PyBytesWriter' type-id='type-id-303' filepath='./Include/cpython/bytesobject.h' line='76' column='1' id='type-id-302'/> + <pointer-type-def type-id='type-id-302' size-in-bits='64' id='type-id-304'/> + <var-decl name='PyBytes_Type' type-id='type-id-256' mangled-name='PyBytes_Type' visibility='default' filepath='./Include/bytesobject.h' line='27' column='1' elf-symbol-id='PyBytes_Type'/> + <var-decl name='PyBytesIter_Type' type-id='type-id-256' mangled-name='PyBytesIter_Type' visibility='default' filepath='./Include/bytesobject.h' line='28' column='1' elf-symbol-id='PyBytesIter_Type'/> + <function-decl name='_Py_NewReference' mangled-name='_Py_NewReference' filepath='./Include/cpython/object.h' line='5' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_NewReference'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_Py_NewReferenceNoTotal' mangled-name='_Py_NewReferenceNoTotal' filepath='./Include/cpython/object.h' line='6' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_NewReferenceNoTotal'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyUnicode_FormatLong' mangled-name='_PyUnicode_FormatLong' filepath='./Include/cpython/unicodeobject.h' line='946' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_FormatLong'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyFloat_AsDouble' mangled-name='PyFloat_AsDouble' filepath='./Include/floatobject.h' line='43' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFloat_AsDouble'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-251'/> + </function-decl> + <function-decl name='_PyLong_FormatBytesWriter' mangled-name='_PyLong_FormatBytesWriter' filepath='./Include/internal/pycore_long.h' line='104' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyLong_FormatBytesWriter'> + <parameter type-id='type-id-304'/> + <parameter type-id='type-id-15'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-15'/> + </function-decl> + <function-decl name='PyObject_ASCII' mangled-name='PyObject_ASCII' filepath='./Include/object.h' line='404' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_ASCII'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyObject_Calloc' mangled-name='PyObject_Calloc' filepath='./Include/objimpl.h' line='99' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_Calloc'> + <parameter type-id='type-id-19'/> + <parameter type-id='type-id-19'/> + <return type-id='type-id-22'/> + </function-decl> + <function-decl name='PyErr_BadArgument' mangled-name='PyErr_BadArgument' filepath='./Include/pyerrors.h' line='168' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_BadArgument'> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_Py_HashBytes' mangled-name='_Py_HashBytes' filepath='./Include/pyhash.h' line='14' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_HashBytes'> + <parameter type-id='type-id-22'/> + <parameter type-id='type-id-14'/> + <return type-id='type-id-305'/> + </function-decl> + <function-decl name='PyOS_double_to_string' mangled-name='PyOS_double_to_string' filepath='./Include/pystrtod.h' line='15' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyOS_double_to_string'> + <parameter type-id='type-id-251'/> + <parameter type-id='type-id-48'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-179'/> + <return type-id='type-id-15'/> + </function-decl> + <function-decl name='PyTuple_GetItem' mangled-name='PyTuple_GetItem' filepath='./Include/tupleobject.h' line='32' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyTuple_GetItem'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-14'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyBytes_FromFormatV' mangled-name='PyBytes_FromFormatV' filepath='Objects/bytesobject.c' line='181' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyBytes_FromFormatV'> + <parameter type-id='type-id-12' name='format' filepath='Objects/bytesobject.c' line='181' column='1'/> + <parameter type-id='type-id-306' name='vargs' filepath='Objects/bytesobject.c' line='181' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyBytes_FromFormat' mangled-name='PyBytes_FromFormat' filepath='Objects/bytesobject.c' line='372' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyBytes_FromFormat'> + <parameter type-id='type-id-12' name='format' filepath='Objects/bytesobject.c' line='372' column='1'/> + <parameter is-variadic='yes'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyBytes_DecodeEscape' mangled-name='PyBytes_DecodeEscape' filepath='Objects/bytesobject.c' line='1165' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyBytes_DecodeEscape'> + <parameter type-id='type-id-12' name='s' filepath='Objects/bytesobject.c' line='1165' column='1'/> + <parameter type-id='type-id-14' name='len' filepath='Objects/bytesobject.c' line='1166' column='1'/> + <parameter type-id='type-id-12' name='errors' filepath='Objects/bytesobject.c' line='1167' column='1'/> + <parameter type-id='type-id-14' name='_unused_unicode' filepath='Objects/bytesobject.c' line='1168' column='1'/> + <parameter type-id='type-id-12' name='_unused_recode_encoding' filepath='Objects/bytesobject.c' line='1169' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyBytes_Size' mangled-name='PyBytes_Size' filepath='Objects/bytesobject.c' line='1204' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyBytes_Size'> + <parameter type-id='type-id-2' name='op' filepath='Objects/bytesobject.c' line='1204' column='1'/> + <return type-id='type-id-14'/> + </function-decl> + <function-decl name='_PyBytes_Find' mangled-name='_PyBytes_Find' filepath='Objects/bytesobject.c' line='1273' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyBytes_Find'> + <parameter type-id='type-id-12' name='haystack' filepath='Objects/bytesobject.c' line='1273' column='1'/> + <parameter type-id='type-id-14' name='len_haystack' filepath='Objects/bytesobject.c' line='1273' column='1'/> + <parameter type-id='type-id-12' name='needle' filepath='Objects/bytesobject.c' line='1274' column='1'/> + <parameter type-id='type-id-14' name='len_needle' filepath='Objects/bytesobject.c' line='1274' column='1'/> + <parameter type-id='type-id-14' name='offset' filepath='Objects/bytesobject.c' line='1275' column='1'/> + <return type-id='type-id-14'/> + </function-decl> + <function-decl name='_PyBytes_ReverseFind' mangled-name='_PyBytes_ReverseFind' filepath='Objects/bytesobject.c' line='1299' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyBytes_ReverseFind'> + <parameter type-id='type-id-12' name='haystack' filepath='Objects/bytesobject.c' line='1299' column='1'/> + <parameter type-id='type-id-14' name='len_haystack' filepath='Objects/bytesobject.c' line='1299' column='1'/> + <parameter type-id='type-id-12' name='needle' filepath='Objects/bytesobject.c' line='1300' column='1'/> + <parameter type-id='type-id-14' name='len_needle' filepath='Objects/bytesobject.c' line='1300' column='1'/> + <parameter type-id='type-id-14' name='offset' filepath='Objects/bytesobject.c' line='1301' column='1'/> + <return type-id='type-id-14'/> + </function-decl> + <function-decl name='PyBytes_Repr' mangled-name='PyBytes_Repr' filepath='Objects/bytesobject.c' line='1308' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyBytes_Repr'> + <parameter type-id='type-id-2' name='obj' filepath='Objects/bytesobject.c' line='1308' column='1'/> + <parameter type-id='type-id-8' name='smartquotes' filepath='Objects/bytesobject.c' line='1308' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyBytes_Join' mangled-name='_PyBytes_Join' filepath='Objects/bytesobject.c' line='1863' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyBytes_Join'> + <parameter type-id='type-id-2' name='sep' filepath='Objects/bytesobject.c' line='1863' column='1'/> + <parameter type-id='type-id-2' name='x' filepath='Objects/bytesobject.c' line='1863' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyBytes_FromObject' mangled-name='PyBytes_FromObject' filepath='Objects/bytesobject.c' line='2835' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyBytes_FromObject'> + <parameter type-id='type-id-2' name='x' filepath='Objects/bytesobject.c' line='2835' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyBytes_ConcatAndDel' mangled-name='PyBytes_ConcatAndDel' filepath='Objects/bytesobject.c' line='3026' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyBytes_ConcatAndDel'> + <parameter type-id='type-id-233' name='pv' filepath='Objects/bytesobject.c' line='3026' column='1'/> + <parameter type-id='type-id-2' name='w' filepath='Objects/bytesobject.c' line='3026' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyBytes_Resize' mangled-name='_PyBytes_Resize' filepath='Objects/bytesobject.c' line='3048' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyBytes_Resize'> + <parameter type-id='type-id-233' name='pv' filepath='Objects/bytesobject.c' line='3048' column='1'/> + <parameter type-id='type-id-14' name='newsize' filepath='Objects/bytesobject.c' line='3048' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyBytesWriter_Init' mangled-name='_PyBytesWriter_Init' filepath='Objects/bytesobject.c' line='3271' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyBytesWriter_Init'> + <parameter type-id='type-id-304' name='writer' filepath='Objects/bytesobject.c' line='3271' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyBytesWriter_Dealloc' mangled-name='_PyBytesWriter_Dealloc' filepath='Objects/bytesobject.c' line='3282' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyBytesWriter_Dealloc'> + <parameter type-id='type-id-304' name='writer' filepath='Objects/bytesobject.c' line='3282' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyBytesWriter_Resize' mangled-name='_PyBytesWriter_Resize' filepath='Objects/bytesobject.c' line='3352' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyBytesWriter_Resize'> + <parameter type-id='type-id-304' name='writer' filepath='Objects/bytesobject.c' line='3352' column='1'/> + <parameter type-id='type-id-22' name='str' filepath='Objects/bytesobject.c' line='3352' column='1'/> + <parameter type-id='type-id-14' name='size' filepath='Objects/bytesobject.c' line='3352' column='1'/> + <return type-id='type-id-22'/> + </function-decl> + <function-decl name='_PyBytesWriter_Prepare' mangled-name='_PyBytesWriter_Prepare' filepath='Objects/bytesobject.c' line='3422' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyBytesWriter_Prepare'> + <parameter type-id='type-id-304' name='writer' filepath='Objects/bytesobject.c' line='3422' column='1'/> + <parameter type-id='type-id-22' name='str' filepath='Objects/bytesobject.c' line='3422' column='1'/> + <parameter type-id='type-id-14' name='size' filepath='Objects/bytesobject.c' line='3422' column='1'/> + <return type-id='type-id-22'/> + </function-decl> + <function-decl name='_PyBytesWriter_Alloc' mangled-name='_PyBytesWriter_Alloc' filepath='Objects/bytesobject.c' line='3452' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyBytesWriter_Alloc'> + <parameter type-id='type-id-304' name='writer' filepath='Objects/bytesobject.c' line='3452' column='1'/> + <parameter type-id='type-id-14' name='size' filepath='Objects/bytesobject.c' line='3452' column='1'/> + <return type-id='type-id-22'/> + </function-decl> + <function-decl name='_PyBytesWriter_Finish' mangled-name='_PyBytesWriter_Finish' filepath='Objects/bytesobject.c' line='3482' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyBytesWriter_Finish'> + <parameter type-id='type-id-304' name='writer' filepath='Objects/bytesobject.c' line='3482' column='1'/> + <parameter type-id='type-id-22' name='str' filepath='Objects/bytesobject.c' line='3482' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyBytesWriter_WriteBytes' mangled-name='_PyBytesWriter_WriteBytes' filepath='Objects/bytesobject.c' line='3526' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyBytesWriter_WriteBytes'> + <parameter type-id='type-id-304' name='writer' filepath='Objects/bytesobject.c' line='3526' column='1'/> + <parameter type-id='type-id-22' name='ptr' filepath='Objects/bytesobject.c' line='3526' column='1'/> + <parameter type-id='type-id-22' name='bytes' filepath='Objects/bytesobject.c' line='3527' column='1'/> + <parameter type-id='type-id-14' name='size' filepath='Objects/bytesobject.c' line='3527' column='1'/> + <return type-id='type-id-22'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Objects/call.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <class-decl name='_Py_Identifier' size-in-bits='128' is-struct='yes' visibility='default' filepath='./Include/cpython/object.h' line='42' column='1' id='type-id-307'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='string' type-id='type-id-12' visibility='default' filepath='./Include/cpython/object.h' line='43' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='index' type-id='type-id-14' visibility='default' filepath='./Include/cpython/object.h' line='46' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='_Py_Identifier' type-id='type-id-307' filepath='./Include/cpython/object.h' line='47' column='1' id='type-id-308'/> + <pointer-type-def type-id='type-id-308' size-in-bits='64' id='type-id-309'/> + <function-decl name='_Py_VaBuildStack_SizeT' mangled-name='_Py_VaBuildStack_SizeT' filepath='./Include/cpython/modsupport.h' line='11' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_VaBuildStack_SizeT'> + <parameter type-id='type-id-233'/> + <parameter type-id='type-id-14'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-306'/> + <parameter type-id='type-id-13'/> + <return type-id='type-id-233'/> + </function-decl> + <function-decl name='_Py_VaBuildStack' mangled-name='_Py_VaBuildStack' filepath='./Include/cpython/modsupport.h' line='46' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_VaBuildStack'> + <parameter type-id='type-id-233'/> + <parameter type-id='type-id-14'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-306'/> + <parameter type-id='type-id-13'/> + <return type-id='type-id-233'/> + </function-decl> + <function-decl name='_PyObject_GetAttrId' mangled-name='_PyObject_GetAttrId' filepath='./Include/cpython/object.h' line='294' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_GetAttrId'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-309'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyObject_GetMethod' mangled-name='_PyObject_GetMethod' filepath='./Include/cpython/object.h' line='308' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_GetMethod'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-233'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_Py_FatalErrorFormat' mangled-name='_Py_FatalErrorFormat' filepath='./Include/cpython/pyerrors.h' line='166' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_FatalErrorFormat'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-12'/> + <parameter is-variadic='yes'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyUnicode_FromId' mangled-name='_PyUnicode_FromId' filepath='./Include/cpython/unicodeobject.h' line='949' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_FromId'> + <parameter type-id='type-id-309'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyDict_Next' mangled-name='PyDict_Next' filepath='./Include/dictobject.h' line='27' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyDict_Next'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-13'/> + <parameter type-id='type-id-233'/> + <parameter type-id='type-id-233'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyEval_Vector' filepath='./Include/internal/pycore_ceval.h' line='94' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-177'/> + <parameter type-id='type-id-310'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-248'/> + <parameter type-id='type-id-19'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyDict_FromItems' filepath='./Include/internal/pycore_dict.h' line='179' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-248'/> + <parameter type-id='type-id-14'/> + <parameter type-id='type-id-248'/> + <parameter type-id='type-id-14'/> + <parameter type-id='type-id-14'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyErr_NoMemory' mangled-name='_PyErr_NoMemory' filepath='./Include/internal/pycore_pyerrors.h' line='71' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyErr_NoMemory'> + <parameter type-id='type-id-177'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyErr_FormatFromCauseTstate' mangled-name='_PyErr_FormatFromCauseTstate' filepath='./Include/internal/pycore_pyerrors.h' line='90' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyErr_FormatFromCauseTstate'> + <parameter type-id='type-id-177'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-12'/> + <parameter is-variadic='yes'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyTuple_FromArray' filepath='./Include/internal/pycore_tuple.h' line='66' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-248'/> + <parameter type-id='type-id-14'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyModule_GetNameObject' mangled-name='PyModule_GetNameObject' filepath='./Include/moduleobject.h' line='25' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyModule_GetNameObject'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyObject_GetAttrString' mangled-name='PyObject_GetAttrString' filepath='./Include/object.h' line='408' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_GetAttrString'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-12'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyCallable_Check' mangled-name='PyCallable_Check' filepath='./Include/object.h' line='424' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCallable_Check'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyObject_FastCallDictTstate' mangled-name='_PyObject_FastCallDictTstate' filepath='Objects/call.c' line='109' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_FastCallDictTstate'> + <parameter type-id='type-id-177' name='tstate' filepath='Objects/call.c' line='109' column='1'/> + <parameter type-id='type-id-2' name='callable' filepath='Objects/call.c' line='109' column='1'/> + <parameter type-id='type-id-248' name='args' filepath='Objects/call.c' line='110' column='1'/> + <parameter type-id='type-id-19' name='nargsf' filepath='Objects/call.c' line='110' column='1'/> + <parameter type-id='type-id-2' name='kwargs' filepath='Objects/call.c' line='111' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyObject_VectorcallDict' mangled-name='PyObject_VectorcallDict' filepath='Objects/call.c' line='153' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_VectorcallDict'> + <parameter type-id='type-id-2' name='callable' filepath='Objects/call.c' line='153' column='1'/> + <parameter type-id='type-id-248' name='args' filepath='Objects/call.c' line='153' column='1'/> + <parameter type-id='type-id-19' name='nargsf' filepath='Objects/call.c' line='154' column='1'/> + <parameter type-id='type-id-2' name='kwargs' filepath='Objects/call.c' line='154' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyVectorcall_Function' mangled-name='PyVectorcall_Function' filepath='Objects/call.c' line='255' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyVectorcall_Function'> + <parameter type-id='type-id-2' name='callable' filepath='Objects/call.c' line='255' column='1'/> + <return type-id='type-id-311'/> + </function-decl> + <function-decl name='PyVectorcall_Call' mangled-name='PyVectorcall_Call' filepath='Objects/call.c' line='292' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyVectorcall_Call'> + <parameter type-id='type-id-2' name='callable' filepath='Objects/call.c' line='292' column='1'/> + <parameter type-id='type-id-2' name='tuple' filepath='Objects/call.c' line='292' column='1'/> + <parameter type-id='type-id-2' name='kwargs' filepath='Objects/call.c' line='292' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyObject_Vectorcall' mangled-name='PyObject_Vectorcall' filepath='Objects/call.c' line='321' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_Vectorcall'> + <parameter type-id='type-id-2' name='callable' filepath='Objects/call.c' line='321' column='1'/> + <parameter type-id='type-id-248' name='args' filepath='Objects/call.c' line='321' column='1'/> + <parameter type-id='type-id-19' name='nargsf' filepath='Objects/call.c' line='322' column='1'/> + <parameter type-id='type-id-2' name='kwnames' filepath='Objects/call.c' line='322' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyObject_Call' mangled-name='_PyObject_Call' filepath='Objects/call.c' line='339' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_Call'> + <parameter type-id='type-id-177' name='tstate' filepath='Objects/call.c' line='339' column='1'/> + <parameter type-id='type-id-2' name='callable' filepath='Objects/call.c' line='339' column='1'/> + <parameter type-id='type-id-2' name='args' filepath='Objects/call.c' line='340' column='1'/> + <parameter type-id='type-id-2' name='kwargs' filepath='Objects/call.c' line='340' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyObject_Call' mangled-name='PyObject_Call' filepath='Objects/call.c' line='376' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_Call'> + <parameter type-id='type-id-2' name='callable' filepath='Objects/call.c' line='376' column='1'/> + <parameter type-id='type-id-2' name='args' filepath='Objects/call.c' line='376' column='1'/> + <parameter type-id='type-id-2' name='kwargs' filepath='Objects/call.c' line='376' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyCFunction_Call' mangled-name='PyCFunction_Call' filepath='Objects/call.c' line='384' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCFunction_Call'> + <parameter type-id='type-id-2' name='callable' filepath='Objects/call.c' line='384' column='1'/> + <parameter type-id='type-id-2' name='args' filepath='Objects/call.c' line='384' column='1'/> + <parameter type-id='type-id-2' name='kwargs' filepath='Objects/call.c' line='384' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyFunction_Vectorcall' mangled-name='_PyFunction_Vectorcall' filepath='Objects/call.c' line='408' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyFunction_Vectorcall'> + <parameter type-id='type-id-2' name='func' filepath='Objects/call.c' line='408' column='1'/> + <parameter type-id='type-id-248' name='stack' filepath='Objects/call.c' line='408' column='1'/> + <parameter type-id='type-id-19' name='nargsf' filepath='Objects/call.c' line='409' column='1'/> + <parameter type-id='type-id-2' name='kwnames' filepath='Objects/call.c' line='409' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyEval_CallObjectWithKeywords' mangled-name='PyEval_CallObjectWithKeywords' filepath='Objects/call.c' line='431' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyEval_CallObjectWithKeywords'> + <parameter type-id='type-id-2' name='callable' filepath='Objects/call.c' line='431' column='1'/> + <parameter type-id='type-id-2' name='args' filepath='Objects/call.c' line='432' column='1'/> + <parameter type-id='type-id-2' name='kwargs' filepath='Objects/call.c' line='432' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyObject_CallObject' mangled-name='PyObject_CallObject' filepath='Objects/call.c' line='464' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_CallObject'> + <parameter type-id='type-id-2' name='callable' filepath='Objects/call.c' line='464' column='1'/> + <parameter type-id='type-id-2' name='args' filepath='Objects/call.c' line='464' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyObject_Call_Prepend' mangled-name='_PyObject_Call_Prepend' filepath='Objects/call.c' line='482' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_Call_Prepend'> + <parameter type-id='type-id-177' name='tstate' filepath='Objects/call.c' line='482' column='1'/> + <parameter type-id='type-id-2' name='callable' filepath='Objects/call.c' line='482' column='1'/> + <parameter type-id='type-id-2' name='obj' filepath='Objects/call.c' line='483' column='1'/> + <parameter type-id='type-id-2' name='args' filepath='Objects/call.c' line='483' column='1'/> + <parameter type-id='type-id-2' name='kwargs' filepath='Objects/call.c' line='483' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyObject_CallFunction' mangled-name='PyObject_CallFunction' filepath='Objects/call.c' line='577' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_CallFunction'> + <parameter type-id='type-id-2' name='callable' filepath='Objects/call.c' line='577' column='1'/> + <parameter type-id='type-id-12' name='format' filepath='Objects/call.c' line='577' column='1'/> + <parameter is-variadic='yes'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyEval_CallFunction' mangled-name='PyEval_CallFunction' filepath='Objects/call.c' line='595' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyEval_CallFunction'> + <parameter type-id='type-id-2' name='callable' filepath='Objects/call.c' line='595' column='1'/> + <parameter type-id='type-id-12' name='format' filepath='Objects/call.c' line='595' column='1'/> + <parameter is-variadic='yes'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyObject_CallMethod' mangled-name='PyObject_CallMethod' filepath='Objects/call.c' line='638' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_CallMethod'> + <parameter type-id='type-id-2' name='obj' filepath='Objects/call.c' line='638' column='1'/> + <parameter type-id='type-id-12' name='name' filepath='Objects/call.c' line='638' column='1'/> + <parameter type-id='type-id-12' name='format' filepath='Objects/call.c' line='638' column='1'/> + <parameter is-variadic='yes'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyEval_CallMethod' mangled-name='PyEval_CallMethod' filepath='Objects/call.c' line='665' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyEval_CallMethod'> + <parameter type-id='type-id-2' name='obj' filepath='Objects/call.c' line='665' column='1'/> + <parameter type-id='type-id-12' name='name' filepath='Objects/call.c' line='665' column='1'/> + <parameter type-id='type-id-12' name='format' filepath='Objects/call.c' line='665' column='1'/> + <parameter is-variadic='yes'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyObject_CallMethod' mangled-name='_PyObject_CallMethod' filepath='Objects/call.c' line='688' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_CallMethod'> + <parameter type-id='type-id-2' name='obj' filepath='Objects/call.c' line='688' column='1'/> + <parameter type-id='type-id-2' name='name' filepath='Objects/call.c' line='688' column='1'/> + <parameter type-id='type-id-12' name='format' filepath='Objects/call.c' line='689' column='1'/> + <parameter is-variadic='yes'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyObject_CallMethodId' mangled-name='_PyObject_CallMethodId' filepath='Objects/call.c' line='712' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_CallMethodId'> + <parameter type-id='type-id-2' name='obj' filepath='Objects/call.c' line='712' column='1'/> + <parameter type-id='type-id-309' name='name' filepath='Objects/call.c' line='712' column='1'/> + <parameter type-id='type-id-12' name='format' filepath='Objects/call.c' line='713' column='1'/> + <parameter is-variadic='yes'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyObject_CallMethod_SizeT' mangled-name='_PyObject_CallMethod_SizeT' filepath='Objects/call.c' line='747' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_CallMethod_SizeT'> + <parameter type-id='type-id-2' name='obj' filepath='Objects/call.c' line='747' column='1'/> + <parameter type-id='type-id-12' name='name' filepath='Objects/call.c' line='747' column='1'/> + <parameter type-id='type-id-12' name='format' filepath='Objects/call.c' line='748' column='1'/> + <parameter is-variadic='yes'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyObject_CallMethodId_SizeT' mangled-name='_PyObject_CallMethodId_SizeT' filepath='Objects/call.c' line='771' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_CallMethodId_SizeT'> + <parameter type-id='type-id-2' name='obj' filepath='Objects/call.c' line='771' column='1'/> + <parameter type-id='type-id-309' name='name' filepath='Objects/call.c' line='771' column='1'/> + <parameter type-id='type-id-12' name='format' filepath='Objects/call.c' line='772' column='1'/> + <parameter is-variadic='yes'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyObject_CallMethodObjArgs' mangled-name='PyObject_CallMethodObjArgs' filepath='Objects/call.c' line='895' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_CallMethodObjArgs'> + <parameter type-id='type-id-2' name='obj' filepath='Objects/call.c' line='895' column='1'/> + <parameter type-id='type-id-2' name='name' filepath='Objects/call.c' line='895' column='1'/> + <parameter is-variadic='yes'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyObject_CallMethodIdObjArgs' mangled-name='_PyObject_CallMethodIdObjArgs' filepath='Objects/call.c' line='920' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_CallMethodIdObjArgs'> + <parameter type-id='type-id-2' name='obj' filepath='Objects/call.c' line='920' column='1'/> + <parameter type-id='type-id-309' name='name' filepath='Objects/call.c' line='920' column='1'/> + <parameter is-variadic='yes'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyStack_AsDict' mangled-name='_PyStack_AsDict' filepath='Objects/call.c' line='967' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyStack_AsDict'> + <parameter type-id='type-id-248' name='values' filepath='Objects/call.c' line='967' column='1'/> + <parameter type-id='type-id-2' name='kwnames' filepath='Objects/call.c' line='967' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyVectorcall_NARGS' mangled-name='PyVectorcall_NARGS' filepath='Objects/call.c' line='1080' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyVectorcall_NARGS'> + <parameter type-id='type-id-19' name='n' filepath='Objects/call.c' line='1080' column='1'/> + <return type-id='type-id-14'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Objects/capsule.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <typedef-decl name='PyCapsule_Destructor' type-id='type-id-312' filepath='./Include/pycapsule.h' line='23' column='1' id='type-id-313'/> + <function-decl name='PyImport_ImportModule' mangled-name='PyImport_ImportModule' filepath='./Include/import.h' line='46' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyImport_ImportModule'> + <parameter type-id='type-id-12'/> + <return type-id='type-id-2'/> + </function-decl> + <var-decl name='PyCapsule_Type' type-id='type-id-256' mangled-name='PyCapsule_Type' visibility='default' filepath='./Include/pycapsule.h' line='21' column='1' elf-symbol-id='PyCapsule_Type'/> + <function-decl name='PyCapsule_New' mangled-name='PyCapsule_New' filepath='Objects/capsule.c' line='44' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCapsule_New'> + <parameter type-id='type-id-22' name='pointer' filepath='Objects/capsule.c' line='44' column='1'/> + <parameter type-id='type-id-12' name='name' filepath='Objects/capsule.c' line='44' column='1'/> + <parameter type-id='type-id-313' name='destructor' filepath='Objects/capsule.c' line='44' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyCapsule_IsValid' mangled-name='PyCapsule_IsValid' filepath='Objects/capsule.c' line='68' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCapsule_IsValid'> + <parameter type-id='type-id-2' name='o' filepath='Objects/capsule.c' line='68' column='1'/> + <parameter type-id='type-id-12' name='name' filepath='Objects/capsule.c' line='68' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyCapsule_GetPointer' mangled-name='PyCapsule_GetPointer' filepath='Objects/capsule.c' line='80' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCapsule_GetPointer'> + <parameter type-id='type-id-2' name='o' filepath='Objects/capsule.c' line='80' column='1'/> + <parameter type-id='type-id-12' name='name' filepath='Objects/capsule.c' line='80' column='1'/> + <return type-id='type-id-22'/> + </function-decl> + <function-decl name='PyCapsule_GetName' mangled-name='PyCapsule_GetName' filepath='Objects/capsule.c' line='98' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCapsule_GetName'> + <parameter type-id='type-id-2' name='o' filepath='Objects/capsule.c' line='98' column='1'/> + <return type-id='type-id-12'/> + </function-decl> + <function-decl name='PyCapsule_GetDestructor' mangled-name='PyCapsule_GetDestructor' filepath='Objects/capsule.c' line='110' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCapsule_GetDestructor'> + <parameter type-id='type-id-2' name='o' filepath='Objects/capsule.c' line='110' column='1'/> + <return type-id='type-id-313'/> + </function-decl> + <function-decl name='PyCapsule_GetContext' mangled-name='PyCapsule_GetContext' filepath='Objects/capsule.c' line='122' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCapsule_GetContext'> + <parameter type-id='type-id-2' name='o' filepath='Objects/capsule.c' line='122' column='1'/> + <return type-id='type-id-22'/> + </function-decl> + <function-decl name='PyCapsule_SetPointer' mangled-name='PyCapsule_SetPointer' filepath='Objects/capsule.c' line='134' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCapsule_SetPointer'> + <parameter type-id='type-id-2' name='o' filepath='Objects/capsule.c' line='134' column='1'/> + <parameter type-id='type-id-22' name='pointer' filepath='Objects/capsule.c' line='134' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyCapsule_SetName' mangled-name='PyCapsule_SetName' filepath='Objects/capsule.c' line='153' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCapsule_SetName'> + <parameter type-id='type-id-2' name='o' filepath='Objects/capsule.c' line='153' column='1'/> + <parameter type-id='type-id-12' name='name' filepath='Objects/capsule.c' line='153' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyCapsule_SetDestructor' mangled-name='PyCapsule_SetDestructor' filepath='Objects/capsule.c' line='167' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCapsule_SetDestructor'> + <parameter type-id='type-id-2' name='o' filepath='Objects/capsule.c' line='167' column='1'/> + <parameter type-id='type-id-313' name='destructor' filepath='Objects/capsule.c' line='167' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyCapsule_SetContext' mangled-name='PyCapsule_SetContext' filepath='Objects/capsule.c' line='181' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCapsule_SetContext'> + <parameter type-id='type-id-2' name='o' filepath='Objects/capsule.c' line='181' column='1'/> + <parameter type-id='type-id-22' name='context' filepath='Objects/capsule.c' line='181' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyCapsule_Import' mangled-name='PyCapsule_Import' filepath='Objects/capsule.c' line='195' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCapsule_Import'> + <parameter type-id='type-id-12' name='name' filepath='Objects/capsule.c' line='195' column='1'/> + <parameter type-id='type-id-8' name='no_block' filepath='Objects/capsule.c' line='195' column='1'/> + <return type-id='type-id-22'/> + </function-decl> + <function-type size-in-bits='64' id='type-id-314'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-46'/> + </function-type> + </abi-instr> + <abi-instr address-size='64' path='Objects/cellobject.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <var-decl name='PyCell_Type' type-id='type-id-256' mangled-name='PyCell_Type' visibility='default' filepath='./Include/cpython/cellobject.h' line='16' column='1' elf-symbol-id='PyCell_Type'/> + <function-decl name='PyObject_RichCompare' mangled-name='PyObject_RichCompare' filepath='./Include/object.h' line='406' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_RichCompare'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyCell_New' mangled-name='PyCell_New' filepath='Objects/cellobject.c' line='7' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCell_New'> + <parameter type-id='type-id-2' name='obj' filepath='Objects/cellobject.c' line='7' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyCell_Get' mangled-name='PyCell_Get' filepath='Objects/cellobject.c' line='52' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCell_Get'> + <parameter type-id='type-id-2' name='op' filepath='Objects/cellobject.c' line='52' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyCell_Set' mangled-name='PyCell_Set' filepath='Objects/cellobject.c' line='63' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCell_Set'> + <parameter type-id='type-id-2' name='op' filepath='Objects/cellobject.c' line='63' column='1'/> + <parameter type-id='type-id-2' name='value' filepath='Objects/cellobject.c' line='63' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Objects/classobject.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <var-decl name='PyMethod_Type' type-id='type-id-256' mangled-name='PyMethod_Type' visibility='default' filepath='./Include/cpython/classobject.h' line='20' column='1' elf-symbol-id='PyMethod_Type'/> + <var-decl name='PyInstanceMethod_Type' type-id='type-id-256' mangled-name='PyInstanceMethod_Type' visibility='default' filepath='./Include/cpython/classobject.h' line='49' column='1' elf-symbol-id='PyInstanceMethod_Type'/> + <function-decl name='_PyType_Lookup' mangled-name='_PyType_Lookup' filepath='./Include/cpython/object.h' line='274' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyType_Lookup'> + <parameter type-id='type-id-1'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyType_GetDict' mangled-name='_PyType_GetDict' filepath='./Include/internal/pycore_typeobject.h' line='117' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyType_GetDict'> + <parameter type-id='type-id-1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyType_Ready' mangled-name='PyType_Ready' filepath='./Include/object.h' line='394' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyType_Ready'> + <parameter type-id='type-id-1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyObject_GenericSetAttr' mangled-name='PyObject_GenericSetAttr' filepath='./Include/object.h' line='416' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_GenericSetAttr'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyObject_Hash' mangled-name='PyObject_Hash' filepath='./Include/object.h' line='420' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_Hash'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-305'/> + </function-decl> + <function-decl name='PyObject_ClearWeakRefs' mangled-name='PyObject_ClearWeakRefs' filepath='./Include/object.h' line='425' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_ClearWeakRefs'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_Py_HashPointer' mangled-name='_Py_HashPointer' filepath='./Include/pyhash.h' line='11' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_HashPointer'> + <parameter type-id='type-id-22'/> + <return type-id='type-id-305'/> + </function-decl> + <function-decl name='PyMethod_Function' mangled-name='PyMethod_Function' filepath='Objects/classobject.c' line='21' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMethod_Function'> + <parameter type-id='type-id-2' name='im' filepath='Objects/classobject.c' line='21' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyMethod_Self' mangled-name='PyMethod_Self' filepath='Objects/classobject.c' line='31' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMethod_Self'> + <parameter type-id='type-id-2' name='im' filepath='Objects/classobject.c' line='31' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyMethod_New' mangled-name='PyMethod_New' filepath='Objects/classobject.c' line='107' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMethod_New'> + <parameter type-id='type-id-2' name='func' filepath='Objects/classobject.c' line='107' column='1'/> + <parameter type-id='type-id-2' name='self' filepath='Objects/classobject.c' line='107' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyInstanceMethod_New' mangled-name='PyInstanceMethod_New' filepath='Objects/classobject.c' line='354' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInstanceMethod_New'> + <parameter type-id='type-id-2' name='func' filepath='Objects/classobject.c' line='354' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyInstanceMethod_Function' mangled-name='PyInstanceMethod_Function' filepath='Objects/classobject.c' line='365' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInstanceMethod_Function'> + <parameter type-id='type-id-2' name='im' filepath='Objects/classobject.c' line='365' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Objects/codeobject.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <class-decl name='_opaque' size-in-bits='192' is-struct='yes' visibility='default' filepath='./Include/cpython/code.h' line='316' column='1' id='type-id-315'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='computed_line' type-id='type-id-8' visibility='default' filepath='./Include/cpython/code.h' line='317' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='lo_next' type-id='type-id-316' visibility='default' filepath='./Include/cpython/code.h' line='318' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='limit' type-id='type-id-316' visibility='default' filepath='./Include/cpython/code.h' line='319' column='1'/> + </data-member> + </class-decl> + <class-decl name='_line_offsets' size-in-bits='320' is-struct='yes' visibility='default' filepath='./Include/cpython/code.h' line='322' column='1' id='type-id-317'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='ar_start' type-id='type-id-8' visibility='default' filepath='./Include/cpython/code.h' line='323' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='32'> + <var-decl name='ar_end' type-id='type-id-8' visibility='default' filepath='./Include/cpython/code.h' line='324' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='ar_line' type-id='type-id-8' visibility='default' filepath='./Include/cpython/code.h' line='325' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='opaque' type-id='type-id-315' visibility='default' filepath='./Include/cpython/code.h' line='326' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='PyCodeAddressRange' type-id='type-id-317' filepath='./Include/cpython/code.h' line='327' column='1' id='type-id-318'/> + <class-decl name='_PyCodeConstructor' size-in-bits='896' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_code.h' line='157' column='1' id='type-id-319'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='filename' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_code.h' line='159' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='name' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_code.h' line='160' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='qualname' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_code.h' line='161' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='flags' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_code.h' line='162' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='code' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_code.h' line='165' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='firstlineno' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_code.h' line='166' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='384'> + <var-decl name='linetable' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_code.h' line='167' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='448'> + <var-decl name='consts' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_code.h' line='170' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='512'> + <var-decl name='names' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_code.h' line='171' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='576'> + <var-decl name='localsplusnames' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_code.h' line='174' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='640'> + <var-decl name='localspluskinds' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_code.h' line='175' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='704'> + <var-decl name='argcount' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_code.h' line='178' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='736'> + <var-decl name='posonlyargcount' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_code.h' line='179' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='768'> + <var-decl name='kwonlyargcount' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_code.h' line='181' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='800'> + <var-decl name='stacksize' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_code.h' line='184' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='832'> + <var-decl name='exceptiontable' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_code.h' line='187' column='1'/> + </data-member> + </class-decl> + <pointer-type-def type-id='type-id-318' size-in-bits='64' id='type-id-320'/> + <pointer-type-def type-id='type-id-321' size-in-bits='64' id='type-id-322'/> + <pointer-type-def type-id='type-id-305' size-in-bits='64' id='type-id-323'/> + <pointer-type-def type-id='type-id-319' size-in-bits='64' id='type-id-324'/> + <qualified-type-def type-id='type-id-325' const='yes' id='type-id-326'/> + <pointer-type-def type-id='type-id-326' size-in-bits='64' id='type-id-316'/> + <var-decl name='PyCode_Type' type-id='type-id-256' mangled-name='PyCode_Type' visibility='default' filepath='./Include/cpython/code.h' line='212' column='1' elf-symbol-id='PyCode_Type'/> + <function-decl name='PyComplex_AsCComplex' mangled-name='PyComplex_AsCComplex' filepath='./Include/cpython/complexobject.h' line='33' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyComplex_AsCComplex'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-327'/> + </function-decl> + <function-decl name='_PySet_NextEntry' mangled-name='_PySet_NextEntry' filepath='./Include/cpython/setobject.h' line='71' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PySet_NextEntry'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-13'/> + <parameter type-id='type-id-233'/> + <parameter type-id='type-id-323'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyUnicode_Copy' mangled-name='_PyUnicode_Copy' filepath='./Include/cpython/unicodeobject.h' line='400' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_Copy'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyUnicode_FromASCII' mangled-name='_PyUnicode_FromASCII' filepath='./Include/cpython/unicodeobject.h' line='474' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_FromASCII'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-14'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_Py_GetBaseOpcode' filepath='./Include/internal/pycore_code.h' line='488' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-328'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyLong_FromVoidPtr' mangled-name='PyLong_FromVoidPtr' filepath='./Include/longobject.h' line='64' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyLong_FromVoidPtr'> + <parameter type-id='type-id-22'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyObject_NewVar' mangled-name='_PyObject_NewVar' filepath='./Include/objimpl.h' line='132' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_NewVar'> + <parameter type-id='type-id-1'/> + <parameter type-id='type-id-14'/> + <return type-id='type-id-322'/> + </function-decl> + <function-decl name='PyErr_WriteUnraisable' mangled-name='PyErr_WriteUnraisable' filepath='./Include/pyerrors.h' line='235' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_WriteUnraisable'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyFrozenSet_New' mangled-name='PyFrozenSet_New' filepath='./Include/setobject.h' line='14' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFrozenSet_New'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyUnicode_DecodeFSDefault' mangled-name='PyUnicode_DecodeFSDefault' filepath='./Include/unicodeobject.h' line='762' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_DecodeFSDefault'> + <parameter type-id='type-id-12'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyUnicode_Compare' mangled-name='PyUnicode_Compare' filepath='./Include/unicodeobject.h' line='952' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_Compare'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='copysign' filepath='/usr/include/x86_64-linux-gnu/bits/mathcalls.h' line='198' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-251'/> + <parameter type-id='type-id-251'/> + <return type-id='type-id-251'/> + </function-decl> + <function-decl name='PyCode_AddWatcher' mangled-name='PyCode_AddWatcher' filepath='Objects/codeobject.c' line='66' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCode_AddWatcher'> + <parameter type-id='type-id-329' name='callback' filepath='Objects/codeobject.c' line='66' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyCode_ClearWatcher' mangled-name='PyCode_ClearWatcher' filepath='Objects/codeobject.c' line='98' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCode_ClearWatcher'> + <parameter type-id='type-id-8' name='watcher_id' filepath='Objects/codeobject.c' line='98' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyCode_Validate' mangled-name='_PyCode_Validate' filepath='Objects/codeobject.c' line='335' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyCode_Validate'> + <parameter type-id='type-id-324' name='con' filepath='Objects/codeobject.c' line='335' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyCode_Quicken' filepath='Objects/codeobject.c' line='392' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-328'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyCode_New' mangled-name='_PyCode_New' filepath='Objects/codeobject.c' line='547' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyCode_New'> + <parameter type-id='type-id-324' name='con' filepath='Objects/codeobject.c' line='547' column='1'/> + <return type-id='type-id-328'/> + </function-decl> + <function-decl name='PyUnstable_Code_NewWithPosOnlyArgs' mangled-name='PyUnstable_Code_NewWithPosOnlyArgs' filepath='Objects/codeobject.c' line='599' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnstable_Code_NewWithPosOnlyArgs'> + <parameter type-id='type-id-8' name='argcount' filepath='Objects/codeobject.c' line='600' column='1'/> + <parameter type-id='type-id-8' name='posonlyargcount' filepath='Objects/codeobject.c' line='600' column='1'/> + <parameter type-id='type-id-8' name='kwonlyargcount' filepath='Objects/codeobject.c' line='600' column='1'/> + <parameter type-id='type-id-8' name='nlocals' filepath='Objects/codeobject.c' line='601' column='1'/> + <parameter type-id='type-id-8' name='stacksize' filepath='Objects/codeobject.c' line='601' column='1'/> + <parameter type-id='type-id-8' name='flags' filepath='Objects/codeobject.c' line='601' column='1'/> + <parameter type-id='type-id-2' name='code' filepath='Objects/codeobject.c' line='602' column='1'/> + <parameter type-id='type-id-2' name='consts' filepath='Objects/codeobject.c' line='602' column='1'/> + <parameter type-id='type-id-2' name='names' filepath='Objects/codeobject.c' line='602' column='1'/> + <parameter type-id='type-id-2' name='varnames' filepath='Objects/codeobject.c' line='603' column='1'/> + <parameter type-id='type-id-2' name='freevars' filepath='Objects/codeobject.c' line='603' column='1'/> + <parameter type-id='type-id-2' name='cellvars' filepath='Objects/codeobject.c' line='603' column='1'/> + <parameter type-id='type-id-2' name='filename' filepath='Objects/codeobject.c' line='604' column='1'/> + <parameter type-id='type-id-2' name='name' filepath='Objects/codeobject.c' line='604' column='1'/> + <parameter type-id='type-id-2' name='qualname' filepath='Objects/codeobject.c' line='605' column='1'/> + <parameter type-id='type-id-8' name='firstlineno' filepath='Objects/codeobject.c' line='605' column='1'/> + <parameter type-id='type-id-2' name='linetable' filepath='Objects/codeobject.c' line='606' column='1'/> + <parameter type-id='type-id-2' name='exceptiontable' filepath='Objects/codeobject.c' line='607' column='1'/> + <return type-id='type-id-328'/> + </function-decl> + <function-decl name='PyUnstable_Code_New' mangled-name='PyUnstable_Code_New' filepath='Objects/codeobject.c' line='724' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnstable_Code_New'> + <parameter type-id='type-id-8' name='argcount' filepath='Objects/codeobject.c' line='724' column='1'/> + <parameter type-id='type-id-8' name='kwonlyargcount' filepath='Objects/codeobject.c' line='724' column='1'/> + <parameter type-id='type-id-8' name='nlocals' filepath='Objects/codeobject.c' line='725' column='1'/> + <parameter type-id='type-id-8' name='stacksize' filepath='Objects/codeobject.c' line='725' column='1'/> + <parameter type-id='type-id-8' name='flags' filepath='Objects/codeobject.c' line='725' column='1'/> + <parameter type-id='type-id-2' name='code' filepath='Objects/codeobject.c' line='726' column='1'/> + <parameter type-id='type-id-2' name='consts' filepath='Objects/codeobject.c' line='726' column='1'/> + <parameter type-id='type-id-2' name='names' filepath='Objects/codeobject.c' line='726' column='1'/> + <parameter type-id='type-id-2' name='varnames' filepath='Objects/codeobject.c' line='727' column='1'/> + <parameter type-id='type-id-2' name='freevars' filepath='Objects/codeobject.c' line='727' column='1'/> + <parameter type-id='type-id-2' name='cellvars' filepath='Objects/codeobject.c' line='727' column='1'/> + <parameter type-id='type-id-2' name='filename' filepath='Objects/codeobject.c' line='728' column='1'/> + <parameter type-id='type-id-2' name='name' filepath='Objects/codeobject.c' line='728' column='1'/> + <parameter type-id='type-id-2' name='qualname' filepath='Objects/codeobject.c' line='728' column='1'/> + <parameter type-id='type-id-8' name='firstlineno' filepath='Objects/codeobject.c' line='729' column='1'/> + <parameter type-id='type-id-2' name='linetable' filepath='Objects/codeobject.c' line='730' column='1'/> + <parameter type-id='type-id-2' name='exceptiontable' filepath='Objects/codeobject.c' line='731' column='1'/> + <return type-id='type-id-328'/> + </function-decl> + <function-decl name='PyCode_NewEmpty' mangled-name='PyCode_NewEmpty' filepath='Objects/codeobject.c' line='758' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCode_NewEmpty'> + <parameter type-id='type-id-12' name='filename' filepath='Objects/codeobject.c' line='758' column='1'/> + <parameter type-id='type-id-12' name='funcname' filepath='Objects/codeobject.c' line='758' column='1'/> + <parameter type-id='type-id-8' name='firstlineno' filepath='Objects/codeobject.c' line='758' column='1'/> + <return type-id='type-id-328'/> + </function-decl> + <function-decl name='PyCode_Addr2Line' mangled-name='PyCode_Addr2Line' filepath='Objects/codeobject.c' line='820' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCode_Addr2Line'> + <parameter type-id='type-id-328' name='co' filepath='Objects/codeobject.c' line='820' column='1'/> + <parameter type-id='type-id-8' name='addrq' filepath='Objects/codeobject.c' line='820' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyCode_CheckLineNumber' mangled-name='_PyCode_CheckLineNumber' filepath='Objects/codeobject.c' line='855' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyCode_CheckLineNumber'> + <parameter type-id='type-id-8' name='lasti' filepath='Objects/codeobject.c' line='855' column='1'/> + <parameter type-id='type-id-320' name='bounds' filepath='Objects/codeobject.c' line='855' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyCode_Addr2Location' mangled-name='PyCode_Addr2Location' filepath='Objects/codeobject.c' line='1032' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCode_Addr2Location'> + <parameter type-id='type-id-328' name='co' filepath='Objects/codeobject.c' line='1032' column='1'/> + <parameter type-id='type-id-8' name='addrq' filepath='Objects/codeobject.c' line='1032' column='1'/> + <parameter type-id='type-id-179' name='start_line' filepath='Objects/codeobject.c' line='1033' column='1'/> + <parameter type-id='type-id-179' name='start_column' filepath='Objects/codeobject.c' line='1033' column='1'/> + <parameter type-id='type-id-179' name='end_line' filepath='Objects/codeobject.c' line='1034' column='1'/> + <parameter type-id='type-id-179' name='end_column' filepath='Objects/codeobject.c' line='1034' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyUnstable_Code_GetExtra' mangled-name='PyUnstable_Code_GetExtra' filepath='Objects/codeobject.c' line='1353' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnstable_Code_GetExtra'> + <parameter type-id='type-id-2' name='code' filepath='Objects/codeobject.c' line='1353' column='1'/> + <parameter type-id='type-id-14' name='index' filepath='Objects/codeobject.c' line='1353' column='1'/> + <parameter type-id='type-id-253' name='extra' filepath='Objects/codeobject.c' line='1353' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyUnstable_Code_SetExtra' mangled-name='PyUnstable_Code_SetExtra' filepath='Objects/codeobject.c' line='1374' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnstable_Code_SetExtra'> + <parameter type-id='type-id-2' name='code' filepath='Objects/codeobject.c' line='1374' column='1'/> + <parameter type-id='type-id-14' name='index' filepath='Objects/codeobject.c' line='1374' column='1'/> + <parameter type-id='type-id-22' name='extra' filepath='Objects/codeobject.c' line='1374' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyCode_GetVarnames' mangled-name='PyCode_GetVarnames' filepath='Objects/codeobject.c' line='1447' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCode_GetVarnames'> + <parameter type-id='type-id-328' name='code' filepath='Objects/codeobject.c' line='1447' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyCode_GetCellvars' mangled-name='PyCode_GetCellvars' filepath='Objects/codeobject.c' line='1462' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCode_GetCellvars'> + <parameter type-id='type-id-328' name='code' filepath='Objects/codeobject.c' line='1462' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyCode_GetFreevars' mangled-name='PyCode_GetFreevars' filepath='Objects/codeobject.c' line='1477' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCode_GetFreevars'> + <parameter type-id='type-id-328' name='code' filepath='Objects/codeobject.c' line='1477' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyCode_GetCode' mangled-name='PyCode_GetCode' filepath='Objects/codeobject.c' line='1518' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCode_GetCode'> + <parameter type-id='type-id-328' name='co' filepath='Objects/codeobject.c' line='1518' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyCode_ConstantKey' mangled-name='_PyCode_ConstantKey' filepath='Objects/codeobject.c' line='2158' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyCode_ConstantKey'> + <parameter type-id='type-id-2' name='op' filepath='Objects/codeobject.c' line='2158' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Objects/complexobject.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <pointer-type-def type-id='type-id-330' size-in-bits='64' id='type-id-331'/> + <var-decl name='PyComplex_Type' type-id='type-id-256' mangled-name='PyComplex_Type' visibility='default' filepath='./Include/complexobject.h' line='11' column='1' elf-symbol-id='PyComplex_Type'/> + <function-decl name='_PyComplex_FormatAdvancedWriter' filepath='./Include/cpython/complexobject.h' line='38' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-332'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-14'/> + <parameter type-id='type-id-14'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyUnicode_TransformDecimalAndSpaceToASCII' mangled-name='_PyUnicode_TransformDecimalAndSpaceToASCII' filepath='./Include/cpython/unicodeobject.h' line='744' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_TransformDecimalAndSpaceToASCII'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_Py_HashDouble' mangled-name='_Py_HashDouble' filepath='./Include/pyhash.h' line='10' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_HashDouble'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-251'/> + <return type-id='type-id-305'/> + </function-decl> + <function-decl name='_Py_string_to_number_with_underscores' mangled-name='_Py_string_to_number_with_underscores' filepath='./Include/pystrtod.h' line='22' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_string_to_number_with_underscores'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-14'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-22'/> + <parameter type-id='type-id-331'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='atan2' filepath='/usr/include/x86_64-linux-gnu/bits/mathcalls.h' line='59' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-251'/> + <parameter type-id='type-id-251'/> + <return type-id='type-id-251'/> + </function-decl> + <function-decl name='cos' filepath='/usr/include/x86_64-linux-gnu/bits/mathcalls.h' line='62' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-251'/> + <return type-id='type-id-251'/> + </function-decl> + <function-decl name='sin' filepath='/usr/include/x86_64-linux-gnu/bits/mathcalls.h' line='64' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-251'/> + <return type-id='type-id-251'/> + </function-decl> + <function-decl name='exp' filepath='/usr/include/x86_64-linux-gnu/bits/mathcalls.h' line='95' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-251'/> + <return type-id='type-id-251'/> + </function-decl> + <function-decl name='log' filepath='/usr/include/x86_64-linux-gnu/bits/mathcalls.h' line='104' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-251'/> + <return type-id='type-id-251'/> + </function-decl> + <function-decl name='pow' filepath='/usr/include/x86_64-linux-gnu/bits/mathcalls.h' line='140' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-251'/> + <parameter type-id='type-id-251'/> + <return type-id='type-id-251'/> + </function-decl> + <function-decl name='hypot' filepath='/usr/include/x86_64-linux-gnu/bits/mathcalls.h' line='147' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-251'/> + <parameter type-id='type-id-251'/> + <return type-id='type-id-251'/> + </function-decl> + <function-decl name='floor' filepath='/usr/include/x86_64-linux-gnu/bits/mathcalls.h' line='165' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-251'/> + <return type-id='type-id-251'/> + </function-decl> + <function-decl name='_Py_c_sum' mangled-name='_Py_c_sum' filepath='Objects/complexobject.c' line='28' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_c_sum'> + <parameter type-id='type-id-327' name='a' filepath='Objects/complexobject.c' line='28' column='1'/> + <parameter type-id='type-id-327' name='b' filepath='Objects/complexobject.c' line='28' column='1'/> + <return type-id='type-id-327'/> + </function-decl> + <function-decl name='_Py_c_diff' mangled-name='_Py_c_diff' filepath='Objects/complexobject.c' line='37' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_c_diff'> + <parameter type-id='type-id-327' name='a' filepath='Objects/complexobject.c' line='37' column='1'/> + <parameter type-id='type-id-327' name='b' filepath='Objects/complexobject.c' line='37' column='1'/> + <return type-id='type-id-327'/> + </function-decl> + <function-decl name='_Py_c_neg' mangled-name='_Py_c_neg' filepath='Objects/complexobject.c' line='46' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_c_neg'> + <parameter type-id='type-id-327' name='a' filepath='Objects/complexobject.c' line='46' column='1'/> + <return type-id='type-id-327'/> + </function-decl> + <function-decl name='_Py_c_prod' mangled-name='_Py_c_prod' filepath='Objects/complexobject.c' line='55' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_c_prod'> + <parameter type-id='type-id-327' name='a' filepath='Objects/complexobject.c' line='55' column='1'/> + <parameter type-id='type-id-327' name='b' filepath='Objects/complexobject.c' line='55' column='1'/> + <return type-id='type-id-327'/> + </function-decl> + <function-decl name='_Py_c_quot' mangled-name='_Py_c_quot' filepath='Objects/complexobject.c' line='68' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_c_quot'> + <parameter type-id='type-id-327' name='a' filepath='Objects/complexobject.c' line='68' column='1'/> + <parameter type-id='type-id-327' name='b' filepath='Objects/complexobject.c' line='68' column='1'/> + <return type-id='type-id-327'/> + </function-decl> + <function-decl name='_Py_c_pow' mangled-name='_Py_c_pow' filepath='Objects/complexobject.c' line='129' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_c_pow'> + <parameter type-id='type-id-327' name='a' filepath='Objects/complexobject.c' line='129' column='1'/> + <parameter type-id='type-id-327' name='b' filepath='Objects/complexobject.c' line='129' column='1'/> + <return type-id='type-id-327'/> + </function-decl> + <function-decl name='_Py_c_abs' mangled-name='_Py_c_abs' filepath='Objects/complexobject.c' line='185' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_c_abs'> + <parameter type-id='type-id-327' name='z' filepath='Objects/complexobject.c' line='185' column='1'/> + <return type-id='type-id-251'/> + </function-decl> + <function-decl name='PyComplex_FromDoubles' mangled-name='PyComplex_FromDoubles' filepath='Objects/complexobject.c' line='250' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyComplex_FromDoubles'> + <parameter type-id='type-id-251' name='real' filepath='Objects/complexobject.c' line='250' column='1'/> + <parameter type-id='type-id-251' name='imag' filepath='Objects/complexobject.c' line='250' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyComplex_RealAsDouble' mangled-name='PyComplex_RealAsDouble' filepath='Objects/complexobject.c' line='259' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyComplex_RealAsDouble'> + <parameter type-id='type-id-2' name='op' filepath='Objects/complexobject.c' line='259' column='1'/> + <return type-id='type-id-251'/> + </function-decl> + <function-decl name='PyComplex_ImagAsDouble' mangled-name='PyComplex_ImagAsDouble' filepath='Objects/complexobject.c' line='270' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyComplex_ImagAsDouble'> + <parameter type-id='type-id-2' name='op' filepath='Objects/complexobject.c' line='270' column='1'/> + <return type-id='type-id-251'/> + </function-decl> + <function-type size-in-bits='64' id='type-id-330'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-14'/> + <parameter type-id='type-id-22'/> + <return type-id='type-id-2'/> + </function-type> + </abi-instr> + <abi-instr address-size='64' path='Objects/descrobject.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <pointer-type-def type-id='type-id-333' size-in-bits='64' id='type-id-334'/> + <var-decl name='_PyMethodWrapper_Type' type-id='type-id-256' mangled-name='_PyMethodWrapper_Type' visibility='default' filepath='./Include/cpython/descrobject.h' line='60' column='1' elf-symbol-id='_PyMethodWrapper_Type'/> + <function-decl name='_PyArg_UnpackStack' mangled-name='_PyArg_UnpackStack' filepath='./Include/cpython/modsupport.h' line='19' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyArg_UnpackStack'> + <parameter type-id='type-id-248'/> + <parameter type-id='type-id-14'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-14'/> + <parameter type-id='type-id-14'/> + <parameter is-variadic='yes'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyType_GetDocFromInternalDoc' mangled-name='_PyType_GetDocFromInternalDoc' filepath='./Include/cpython/object.h' line='283' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyType_GetDocFromInternalDoc'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-12'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyType_GetTextSignatureFromInternalDoc' mangled-name='_PyType_GetTextSignatureFromInternalDoc' filepath='./Include/cpython/object.h' line='284' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyType_GetTextSignatureFromInternalDoc'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-12'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyObject_IsAbstract' mangled-name='_PyObject_IsAbstract' filepath='./Include/cpython/object.h' line='293' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_IsAbstract'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyObject_FunctionStr' mangled-name='_PyObject_FunctionStr' filepath='./Include/cpython/object.h' line='323' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_FunctionStr'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyTrash_begin' mangled-name='_PyTrash_begin' filepath='./Include/cpython/object.h' line='516' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTrash_begin'> + <parameter type-id='type-id-177'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyTrash_end' mangled-name='_PyTrash_end' filepath='./Include/cpython/object.h' line='517' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTrash_end'> + <parameter type-id='type-id-177'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyTrash_cond' mangled-name='_PyTrash_cond' filepath='./Include/cpython/object.h' line='519' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTrash_cond'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-335'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyThreadState_UncheckedGet' mangled-name='_PyThreadState_UncheckedGet' filepath='./Include/cpython/pystate.h' line='274' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyThreadState_UncheckedGet'> + <return type-id='type-id-177'/> + </function-decl> + <var-decl name='PyClassMethodDescr_Type' type-id='type-id-256' mangled-name='PyClassMethodDescr_Type' visibility='default' filepath='./Include/descrobject.h' line='19' column='1' elf-symbol-id='PyClassMethodDescr_Type'/> + <var-decl name='PyGetSetDescr_Type' type-id='type-id-256' mangled-name='PyGetSetDescr_Type' visibility='default' filepath='./Include/descrobject.h' line='20' column='1' elf-symbol-id='PyGetSetDescr_Type'/> + <var-decl name='PyMemberDescr_Type' type-id='type-id-256' mangled-name='PyMemberDescr_Type' visibility='default' filepath='./Include/descrobject.h' line='21' column='1' elf-symbol-id='PyMemberDescr_Type'/> + <var-decl name='PyMethodDescr_Type' type-id='type-id-256' mangled-name='PyMethodDescr_Type' visibility='default' filepath='./Include/descrobject.h' line='22' column='1' elf-symbol-id='PyMethodDescr_Type'/> + <var-decl name='PyWrapperDescr_Type' type-id='type-id-256' mangled-name='PyWrapperDescr_Type' visibility='default' filepath='./Include/descrobject.h' line='23' column='1' elf-symbol-id='PyWrapperDescr_Type'/> + <var-decl name='PyDictProxy_Type' type-id='type-id-256' mangled-name='PyDictProxy_Type' visibility='default' filepath='./Include/descrobject.h' line='24' column='1' elf-symbol-id='PyDictProxy_Type'/> + <var-decl name='PyProperty_Type' type-id='type-id-256' mangled-name='PyProperty_Type' visibility='default' filepath='./Include/descrobject.h' line='25' column='1' elf-symbol-id='PyProperty_Type'/> + <function-decl name='PyMember_GetOne' mangled-name='PyMember_GetOne' filepath='./Include/descrobject.h' line='88' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMember_GetOne'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-336'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyMember_SetOne' mangled-name='PyMember_SetOne' filepath='./Include/descrobject.h' line='89' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMember_SetOne'> + <parameter type-id='type-id-15'/> + <parameter type-id='type-id-336'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyDict_Contains' mangled-name='PyDict_Contains' filepath='./Include/dictobject.h' line='34' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyDict_Contains'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyCMethod_New' mangled-name='PyCMethod_New' filepath='./Include/methodobject.h' line='74' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCMethod_New'> + <parameter type-id='type-id-337'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyType_GetQualName' mangled-name='PyType_GetQualName' filepath='./Include/object.h' line='370' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyType_GetQualName'> + <parameter type-id='type-id-1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyObject_SetAttr' mangled-name='PyObject_SetAttr' filepath='./Include/object.h' line='412' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_SetAttr'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyObject_GC_UnTrack' mangled-name='PyObject_GC_UnTrack' filepath='./Include/objimpl.h' line='199' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_GC_UnTrack'> + <parameter type-id='type-id-22'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyTuple_GetSlice' mangled-name='PyTuple_GetSlice' filepath='./Include/tupleobject.h' line='34' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyTuple_GetSlice'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-14'/> + <parameter type-id='type-id-14'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyDescr_NewMethod' mangled-name='PyDescr_NewMethod' filepath='Objects/descrobject.c' line='919' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyDescr_NewMethod'> + <parameter type-id='type-id-1' name='type' filepath='Objects/descrobject.c' line='919' column='1'/> + <parameter type-id='type-id-337' name='method' filepath='Objects/descrobject.c' line='919' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyDescr_NewClassMethod' mangled-name='PyDescr_NewClassMethod' filepath='Objects/descrobject.c' line='965' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyDescr_NewClassMethod'> + <parameter type-id='type-id-1' name='type' filepath='Objects/descrobject.c' line='965' column='1'/> + <parameter type-id='type-id-337' name='method' filepath='Objects/descrobject.c' line='965' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyDescr_NewMember' mangled-name='PyDescr_NewMember' filepath='Objects/descrobject.c' line='977' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyDescr_NewMember'> + <parameter type-id='type-id-1' name='type' filepath='Objects/descrobject.c' line='977' column='1'/> + <parameter type-id='type-id-336' name='member' filepath='Objects/descrobject.c' line='977' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyDescr_NewGetSet' mangled-name='PyDescr_NewGetSet' filepath='Objects/descrobject.c' line='995' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyDescr_NewGetSet'> + <parameter type-id='type-id-1' name='type' filepath='Objects/descrobject.c' line='995' column='1'/> + <parameter type-id='type-id-338' name='getset' filepath='Objects/descrobject.c' line='995' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyDescr_NewWrapper' mangled-name='PyDescr_NewWrapper' filepath='Objects/descrobject.c' line='1007' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyDescr_NewWrapper'> + <parameter type-id='type-id-1' name='type' filepath='Objects/descrobject.c' line='1007' column='1'/> + <parameter type-id='type-id-334' name='base' filepath='Objects/descrobject.c' line='1007' column='1'/> + <parameter type-id='type-id-22' name='wrapped' filepath='Objects/descrobject.c' line='1007' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyDescr_IsData' mangled-name='PyDescr_IsData' filepath='Objects/descrobject.c' line='1021' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyDescr_IsData'> + <parameter type-id='type-id-2' name='ob' filepath='Objects/descrobject.c' line='1021' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyDictProxy_New' mangled-name='PyDictProxy_New' filepath='Objects/descrobject.c' line='1256' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyDictProxy_New'> + <parameter type-id='type-id-2' name='mapping' filepath='Objects/descrobject.c' line='1256' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyWrapper_New' mangled-name='PyWrapper_New' filepath='Objects/descrobject.c' line='1457' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyWrapper_New'> + <parameter type-id='type-id-2' name='d' filepath='Objects/descrobject.c' line='1457' column='1'/> + <parameter type-id='type-id-2' name='self' filepath='Objects/descrobject.c' line='1457' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Objects/dictobject.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <function-decl name='_PyObject_AssertFailed' mangled-name='_PyObject_AssertFailed' filepath='./Include/cpython/object.h' line='444' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_AssertFailed'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-12'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyObject_IS_GC' mangled-name='PyObject_IS_GC' filepath='./Include/cpython/objimpl.h' line='78' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_IS_GC'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyErr_SetKeyError' mangled-name='_PyErr_SetKeyError' filepath='./Include/cpython/pyerrors.h' line='93' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyErr_SetKeyError'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PySet_Update' mangled-name='_PySet_Update' filepath='./Include/cpython/setobject.h' line='72' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PySet_Update'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-decl> + <var-decl name='PyDict_Type' type-id='type-id-256' mangled-name='PyDict_Type' visibility='default' filepath='./Include/dictobject.h' line='15' column='1' elf-symbol-id='PyDict_Type'/> + <var-decl name='PyDictKeys_Type' type-id='type-id-256' mangled-name='PyDictKeys_Type' visibility='default' filepath='./Include/dictobject.h' line='66' column='1' elf-symbol-id='PyDictKeys_Type'/> + <var-decl name='PyDictValues_Type' type-id='type-id-256' mangled-name='PyDictValues_Type' visibility='default' filepath='./Include/dictobject.h' line='67' column='1' elf-symbol-id='PyDictValues_Type'/> + <var-decl name='PyDictItems_Type' type-id='type-id-256' mangled-name='PyDictItems_Type' visibility='default' filepath='./Include/dictobject.h' line='68' column='1' elf-symbol-id='PyDictItems_Type'/> + <var-decl name='PyDictIterKey_Type' type-id='type-id-256' mangled-name='PyDictIterKey_Type' visibility='default' filepath='./Include/dictobject.h' line='79' column='1' elf-symbol-id='PyDictIterKey_Type'/> + <var-decl name='PyDictIterValue_Type' type-id='type-id-256' mangled-name='PyDictIterValue_Type' visibility='default' filepath='./Include/dictobject.h' line='80' column='1' elf-symbol-id='PyDictIterValue_Type'/> + <var-decl name='PyDictIterItem_Type' type-id='type-id-256' mangled-name='PyDictIterItem_Type' visibility='default' filepath='./Include/dictobject.h' line='81' column='1' elf-symbol-id='PyDictIterItem_Type'/> + <var-decl name='PyDictRevIterKey_Type' type-id='type-id-256' mangled-name='PyDictRevIterKey_Type' visibility='default' filepath='./Include/dictobject.h' line='83' column='1' elf-symbol-id='PyDictRevIterKey_Type'/> + <var-decl name='PyDictRevIterItem_Type' type-id='type-id-256' mangled-name='PyDictRevIterItem_Type' visibility='default' filepath='./Include/dictobject.h' line='84' column='1' elf-symbol-id='PyDictRevIterItem_Type'/> + <var-decl name='PyDictRevIterValue_Type' type-id='type-id-256' mangled-name='PyDictRevIterValue_Type' visibility='default' filepath='./Include/dictobject.h' line='85' column='1' elf-symbol-id='PyDictRevIterValue_Type'/> + <function-decl name='_PyType_AllocNoTrack' filepath='./Include/internal/pycore_object.h' line='358' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1'/> + <parameter type-id='type-id-14'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyObject_ComputedDictPointer' filepath='./Include/internal/pycore_object.h' line='407' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-233'/> + </function-decl> + <function-decl name='_PyErr_GetRaisedException' filepath='./Include/internal/pycore_pyerrors.h' line='44' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-177'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyArg_ValidateKeywordArguments' mangled-name='PyArg_ValidateKeywordArguments' filepath='./Include/modsupport.h' line='34' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyArg_ValidateKeywordArguments'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyDict_DebugMallocStats' mangled-name='_PyDict_DebugMallocStats' filepath='Objects/dictobject.c' line='289' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyDict_DebugMallocStats'> + <parameter type-id='type-id-229' name='out' filepath='Objects/dictobject.c' line='289' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyDict_CheckConsistency' mangled-name='_PyDict_CheckConsistency' filepath='Objects/dictobject.c' line='511' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyDict_CheckConsistency'> + <parameter type-id='type-id-2' name='op' filepath='Objects/dictobject.c' line='511' column='1'/> + <parameter type-id='type-id-8' name='check_content' filepath='Objects/dictobject.c' line='511' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyDict_HasOnlyStringKeys' mangled-name='_PyDict_HasOnlyStringKeys' filepath='Objects/dictobject.c' line='1102' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyDict_HasOnlyStringKeys'> + <parameter type-id='type-id-2' name='dict' filepath='Objects/dictobject.c' line='1102' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyDict_MaybeUntrack' mangled-name='_PyDict_MaybeUntrack' filepath='Objects/dictobject.c' line='1127' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyDict_MaybeUntrack'> + <parameter type-id='type-id-2' name='op' filepath='Objects/dictobject.c' line='1127' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyDict_NewPresized' mangled-name='_PyDict_NewPresized' filepath='Objects/dictobject.c' line='1609' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyDict_NewPresized'> + <parameter type-id='type-id-14' name='minused' filepath='Objects/dictobject.c' line='1609' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyDict_GetItem' mangled-name='PyDict_GetItem' filepath='Objects/dictobject.c' line='1665' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyDict_GetItem'> + <parameter type-id='type-id-2' name='op' filepath='Objects/dictobject.c' line='1665' column='1'/> + <parameter type-id='type-id-2' name='key' filepath='Objects/dictobject.c' line='1665' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyDict_GetItem_KnownHash' mangled-name='_PyDict_GetItem_KnownHash' filepath='Objects/dictobject.c' line='1727' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyDict_GetItem_KnownHash'> + <parameter type-id='type-id-2' name='op' filepath='Objects/dictobject.c' line='1727' column='1'/> + <parameter type-id='type-id-2' name='key' filepath='Objects/dictobject.c' line='1727' column='1'/> + <parameter type-id='type-id-305' name='hash' filepath='Objects/dictobject.c' line='1727' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyDict_GetItemWithError' mangled-name='_PyDict_GetItemWithError' filepath='Objects/dictobject.c' line='1773' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyDict_GetItemWithError'> + <parameter type-id='type-id-2' name='dp' filepath='Objects/dictobject.c' line='1773' column='1'/> + <parameter type-id='type-id-2' name='kv' filepath='Objects/dictobject.c' line='1773' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyDict_GetItemIdWithError' mangled-name='_PyDict_GetItemIdWithError' filepath='Objects/dictobject.c' line='1784' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyDict_GetItemIdWithError'> + <parameter type-id='type-id-2' name='dp' filepath='Objects/dictobject.c' line='1784' column='1'/> + <parameter type-id='type-id-309' name='key' filepath='Objects/dictobject.c' line='1784' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyDict_GetItemStringWithError' mangled-name='_PyDict_GetItemStringWithError' filepath='Objects/dictobject.c' line='1796' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyDict_GetItemStringWithError'> + <parameter type-id='type-id-2' name='v' filepath='Objects/dictobject.c' line='1796' column='1'/> + <parameter type-id='type-id-12' name='key' filepath='Objects/dictobject.c' line='1796' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyDict_SetItem_KnownHash' mangled-name='_PyDict_SetItem_KnownHash' filepath='Objects/dictobject.c' line='1888' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyDict_SetItem_KnownHash'> + <parameter type-id='type-id-2' name='op' filepath='Objects/dictobject.c' line='1888' column='1'/> + <parameter type-id='type-id-2' name='key' filepath='Objects/dictobject.c' line='1888' column='1'/> + <parameter type-id='type-id-2' name='value' filepath='Objects/dictobject.c' line='1888' column='1'/> + <parameter type-id='type-id-305' name='hash' filepath='Objects/dictobject.c' line='1889' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyDict_DelItem' mangled-name='PyDict_DelItem' filepath='Objects/dictobject.c' line='1970' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyDict_DelItem'> + <parameter type-id='type-id-2' name='op' filepath='Objects/dictobject.c' line='1970' column='1'/> + <parameter type-id='type-id-2' name='key' filepath='Objects/dictobject.c' line='1970' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyDict_DelItem_KnownHash' mangled-name='_PyDict_DelItem_KnownHash' filepath='Objects/dictobject.c' line='1984' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyDict_DelItem_KnownHash'> + <parameter type-id='type-id-2' name='op' filepath='Objects/dictobject.c' line='1984' column='1'/> + <parameter type-id='type-id-2' name='key' filepath='Objects/dictobject.c' line='1984' column='1'/> + <parameter type-id='type-id-305' name='hash' filepath='Objects/dictobject.c' line='1984' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyDict_DelItemIf' mangled-name='_PyDict_DelItemIf' filepath='Objects/dictobject.c' line='2016' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyDict_DelItemIf'> + <parameter type-id='type-id-2' name='op' filepath='Objects/dictobject.c' line='2016' column='1'/> + <parameter type-id='type-id-2' name='key' filepath='Objects/dictobject.c' line='2016' column='1'/> + <parameter type-id='type-id-339' name='predicate' filepath='Objects/dictobject.c' line='2017' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyDict_Clear' mangled-name='PyDict_Clear' filepath='Objects/dictobject.c' line='2061' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyDict_Clear'> + <parameter type-id='type-id-2' name='op' filepath='Objects/dictobject.c' line='2061' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyDict_Next' mangled-name='_PyDict_Next' filepath='Objects/dictobject.c' line='2106' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyDict_Next'> + <parameter type-id='type-id-2' name='op' filepath='Objects/dictobject.c' line='2106' column='1'/> + <parameter type-id='type-id-13' name='ppos' filepath='Objects/dictobject.c' line='2106' column='1'/> + <parameter type-id='type-id-233' name='pkey' filepath='Objects/dictobject.c' line='2106' column='1'/> + <parameter type-id='type-id-233' name='pvalue' filepath='Objects/dictobject.c' line='2107' column='1'/> + <parameter type-id='type-id-323' name='phash' filepath='Objects/dictobject.c' line='2107' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyDict_Pop' mangled-name='_PyDict_Pop' filepath='Objects/dictobject.c' line='2231' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyDict_Pop'> + <parameter type-id='type-id-2' name='dict' filepath='Objects/dictobject.c' line='2231' column='1'/> + <parameter type-id='type-id-2' name='key' filepath='Objects/dictobject.c' line='2231' column='1'/> + <parameter type-id='type-id-2' name='deflt' filepath='Objects/dictobject.c' line='2231' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyDict_MergeFromSeq2' mangled-name='PyDict_MergeFromSeq2' filepath='Objects/dictobject.c' line='2722' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyDict_MergeFromSeq2'> + <parameter type-id='type-id-2' name='d' filepath='Objects/dictobject.c' line='2722' column='1'/> + <parameter type-id='type-id-2' name='seq2' filepath='Objects/dictobject.c' line='2722' column='1'/> + <parameter type-id='type-id-8' name='override' filepath='Objects/dictobject.c' line='2722' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyDict_Update' mangled-name='PyDict_Update' filepath='Objects/dictobject.c' line='2981' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyDict_Update'> + <parameter type-id='type-id-2' name='a' filepath='Objects/dictobject.c' line='2981' column='1'/> + <parameter type-id='type-id-2' name='b' filepath='Objects/dictobject.c' line='2981' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyDict_MergeEx' mangled-name='_PyDict_MergeEx' filepath='Objects/dictobject.c' line='2996' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyDict_MergeEx'> + <parameter type-id='type-id-2' name='a' filepath='Objects/dictobject.c' line='2996' column='1'/> + <parameter type-id='type-id-2' name='b' filepath='Objects/dictobject.c' line='2996' column='1'/> + <parameter type-id='type-id-8' name='override' filepath='Objects/dictobject.c' line='2996' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyDict_SetDefault' mangled-name='PyDict_SetDefault' filepath='Objects/dictobject.c' line='3290' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyDict_SetDefault'> + <parameter type-id='type-id-2' name='d' filepath='Objects/dictobject.c' line='3290' column='1'/> + <parameter type-id='type-id-2' name='key' filepath='Objects/dictobject.c' line='3290' column='1'/> + <parameter type-id='type-id-2' name='defaultobj' filepath='Objects/dictobject.c' line='3290' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyDict_SizeOf' mangled-name='_PyDict_SizeOf' filepath='Objects/dictobject.c' line='3571' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyDict_SizeOf'> + <parameter type-id='type-id-340' name='mp' filepath='Objects/dictobject.c' line='3571' column='1'/> + <return type-id='type-id-14'/> + </function-decl> + <function-decl name='_PyDict_Contains_KnownHash' mangled-name='_PyDict_Contains_KnownHash' filepath='Objects/dictobject.c' line='3709' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyDict_Contains_KnownHash'> + <parameter type-id='type-id-2' name='op' filepath='Objects/dictobject.c' line='3709' column='1'/> + <parameter type-id='type-id-2' name='key' filepath='Objects/dictobject.c' line='3709' column='1'/> + <parameter type-id='type-id-305' name='hash' filepath='Objects/dictobject.c' line='3709' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyDict_ContainsId' mangled-name='_PyDict_ContainsId' filepath='Objects/dictobject.c' line='3722' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyDict_ContainsId'> + <parameter type-id='type-id-2' name='op' filepath='Objects/dictobject.c' line='3722' column='1'/> + <parameter type-id='type-id-309' name='key' filepath='Objects/dictobject.c' line='3722' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyDict_GetItemString' mangled-name='PyDict_GetItemString' filepath='Objects/dictobject.c' line='3887' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyDict_GetItemString'> + <parameter type-id='type-id-2' name='v' filepath='Objects/dictobject.c' line='3887' column='1'/> + <parameter type-id='type-id-12' name='key' filepath='Objects/dictobject.c' line='3887' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyDict_SetItemId' mangled-name='_PyDict_SetItemId' filepath='Objects/dictobject.c' line='3901' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyDict_SetItemId'> + <parameter type-id='type-id-2' name='v' filepath='Objects/dictobject.c' line='3901' column='1'/> + <parameter type-id='type-id-309' name='key' filepath='Objects/dictobject.c' line='3901' column='1'/> + <parameter type-id='type-id-2' name='item' filepath='Objects/dictobject.c' line='3901' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyDict_DelItemId' mangled-name='_PyDict_DelItemId' filepath='Objects/dictobject.c' line='3925' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyDict_DelItemId'> + <parameter type-id='type-id-2' name='v' filepath='Objects/dictobject.c' line='3925' column='1'/> + <parameter type-id='type-id-309' name='key' filepath='Objects/dictobject.c' line='3925' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyDict_DelItemString' mangled-name='PyDict_DelItemString' filepath='Objects/dictobject.c' line='3934' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyDict_DelItemString'> + <parameter type-id='type-id-2' name='v' filepath='Objects/dictobject.c' line='3934' column='1'/> + <parameter type-id='type-id-12' name='key' filepath='Objects/dictobject.c' line='3934' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyDictView_New' mangled-name='_PyDictView_New' filepath='Objects/dictobject.c' line='4562' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyDictView_New'> + <parameter type-id='type-id-2' name='dict' filepath='Objects/dictobject.c' line='4562' column='1'/> + <parameter type-id='type-id-1' name='type' filepath='Objects/dictobject.c' line='4562' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyDictView_Intersect' mangled-name='_PyDictView_Intersect' filepath='Objects/dictobject.c' line='4786' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyDictView_Intersect'> + <parameter type-id='type-id-2' name='self' filepath='Objects/dictobject.c' line='4786' column='1'/> + <parameter type-id='type-id-2' name='other' filepath='Objects/dictobject.c' line='4786' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyObject_VisitManagedDict' mangled-name='_PyObject_VisitManagedDict' filepath='Objects/dictobject.c' line='5577' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_VisitManagedDict'> + <parameter type-id='type-id-2' name='obj' filepath='Objects/dictobject.c' line='5577' column='1'/> + <parameter type-id='type-id-341' name='visit' filepath='Objects/dictobject.c' line='5577' column='1'/> + <parameter type-id='type-id-22' name='arg' filepath='Objects/dictobject.c' line='5577' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyObject_ClearManagedDict' mangled-name='_PyObject_ClearManagedDict' filepath='Objects/dictobject.c' line='5600' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_ClearManagedDict'> + <parameter type-id='type-id-2' name='obj' filepath='Objects/dictobject.c' line='5600' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyDict_Watch' mangled-name='PyDict_Watch' filepath='Objects/dictobject.c' line='5754' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyDict_Watch'> + <parameter type-id='type-id-8' name='watcher_id' filepath='Objects/dictobject.c' line='5754' column='1'/> + <parameter type-id='type-id-2' name='dict' filepath='Objects/dictobject.c' line='5754' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyDict_Unwatch' mangled-name='PyDict_Unwatch' filepath='Objects/dictobject.c' line='5769' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyDict_Unwatch'> + <parameter type-id='type-id-8' name='watcher_id' filepath='Objects/dictobject.c' line='5769' column='1'/> + <parameter type-id='type-id-2' name='dict' filepath='Objects/dictobject.c' line='5769' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyDict_AddWatcher' mangled-name='PyDict_AddWatcher' filepath='Objects/dictobject.c' line='5784' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyDict_AddWatcher'> + <parameter type-id='type-id-342' name='callback' filepath='Objects/dictobject.c' line='5784' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyDict_ClearWatcher' mangled-name='PyDict_ClearWatcher' filepath='Objects/dictobject.c' line='5800' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyDict_ClearWatcher'> + <parameter type-id='type-id-8' name='watcher_id' filepath='Objects/dictobject.c' line='5800' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <pointer-type-def type-id='type-id-343' size-in-bits='64' id='type-id-340'/> + <typedef-decl name='PyDictObject' type-id='type-id-344' filepath='./Include/cpython/dictobject.h' line='33' column='1' id='type-id-343'/> + <class-decl name='PyDictObject' size-in-bits='384' is-struct='yes' naming-typedef-id='type-id-343' visibility='default' filepath='./Include/cpython/dictobject.h' line='11' column='1' id='type-id-344'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='ob_base' type-id='type-id-345' visibility='default' filepath='./Include/cpython/dictobject.h' line='12' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='ma_used' type-id='type-id-14' visibility='default' filepath='./Include/cpython/dictobject.h' line='15' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='ma_version_tag' type-id='type-id-117' visibility='default' filepath='./Include/cpython/dictobject.h' line='20' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='ma_keys' type-id='type-id-346' visibility='default' filepath='./Include/cpython/dictobject.h' line='25' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='ma_values' type-id='type-id-347' visibility='default' filepath='./Include/cpython/dictobject.h' line='32' column='1'/> + </data-member> + </class-decl> + <pointer-type-def type-id='type-id-348' size-in-bits='64' id='type-id-346'/> + <pointer-type-def type-id='type-id-349' size-in-bits='64' id='type-id-347'/> + <typedef-decl name='PyDictKeysObject' type-id='type-id-350' filepath='./Include/cpython/dictobject.h' line='5' column='1' id='type-id-348'/> + <typedef-decl name='PyDictValues' type-id='type-id-351' filepath='./Include/cpython/dictobject.h' line='6' column='1' id='type-id-349'/> + <class-decl name='_dictkeysobject' size-in-bits='256' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_dict.h' line='72' column='1' id='type-id-350'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='dk_refcnt' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_dict.h' line='73' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='dk_log2_size' type-id='type-id-325' visibility='default' filepath='./Include/internal/pycore_dict.h' line='76' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='72'> + <var-decl name='dk_log2_index_bytes' type-id='type-id-325' visibility='default' filepath='./Include/internal/pycore_dict.h' line='79' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='80'> + <var-decl name='dk_kind' type-id='type-id-325' visibility='default' filepath='./Include/internal/pycore_dict.h' line='82' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='96'> + <var-decl name='dk_version' type-id='type-id-352' visibility='default' filepath='./Include/internal/pycore_dict.h' line='85' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='dk_usable' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_dict.h' line='88' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='dk_nentries' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_dict.h' line='91' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='dk_indices' type-id='type-id-257' visibility='default' filepath='./Include/internal/pycore_dict.h' line='106' column='1'/> + </data-member> + </class-decl> + <class-decl name='_dictvalues' size-in-bits='64' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_dict.h' line='122' column='1' id='type-id-351'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='values' type-id='type-id-353' visibility='default' filepath='./Include/internal/pycore_dict.h' line='123' column='1'/> + </data-member> + </class-decl> + <function-type size-in-bits='64' id='type-id-354'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-type> + </abi-instr> + <abi-instr address-size='64' path='Objects/enumobject.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <function-decl name='_PyUnicode_EqualToASCIIString' mangled-name='_PyUnicode_EqualToASCIIString' filepath='./Include/cpython/unicodeobject.h' line='767' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_EqualToASCIIString'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-12'/> + <return type-id='type-id-8'/> + </function-decl> + <var-decl name='PyEnum_Type' type-id='type-id-256' mangled-name='PyEnum_Type' visibility='default' filepath='./Include/enumobject.h' line='10' column='1' elf-symbol-id='PyEnum_Type'/> + <var-decl name='PyReversed_Type' type-id='type-id-256' mangled-name='PyReversed_Type' visibility='default' filepath='./Include/enumobject.h' line='11' column='1' elf-symbol-id='PyReversed_Type'/> + </abi-instr> + <abi-instr address-size='64' path='Objects/exceptions.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <function-decl name='PyDict_New' mangled-name='PyDict_New' filepath='./Include/dictobject.h' line='21' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyDict_New'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyDict_GetItemWithError' mangled-name='PyDict_GetItemWithError' filepath='./Include/dictobject.h' line='23' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyDict_GetItemWithError'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyDict_SetItem' mangled-name='PyDict_SetItem' filepath='./Include/dictobject.h' line='24' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyDict_SetItem'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyDict_Copy' mangled-name='PyDict_Copy' filepath='./Include/dictobject.h' line='33' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyDict_Copy'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyDict_SetItemString' mangled-name='PyDict_SetItemString' filepath='./Include/dictobject.h' line='58' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyDict_SetItemString'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyObject_GenericGetDict' mangled-name='PyObject_GenericGetDict' filepath='./Include/dictobject.h' line='61' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_GenericGetDict'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-22'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyErr_SetRaisedException' filepath='./Include/internal/pycore_pyerrors.h' line='51' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-177'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyStaticType_InitBuiltin' filepath='./Include/internal/pycore_typeobject.h' line='112' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <parameter type-id='type-id-1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyStaticType_Dealloc' filepath='./Include/internal/pycore_typeobject.h' line='115' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <parameter type-id='type-id-1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyList_GetItem' mangled-name='PyList_GetItem' filepath='./Include/listobject.h' line='31' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyList_GetItem'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-14'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyArg_ParseTupleAndKeywords_SizeT' mangled-name='_PyArg_ParseTupleAndKeywords_SizeT' filepath='./Include/modsupport.h' line='28' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyArg_ParseTupleAndKeywords_SizeT'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-239'/> + <parameter is-variadic='yes'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyModule_GetDict' mangled-name='PyModule_GetDict' filepath='./Include/moduleobject.h' line='23' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyModule_GetDict'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyObject_Repr' mangled-name='PyObject_Repr' filepath='./Include/object.h' line='402' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_Repr'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyObject_GenericSetDict' mangled-name='PyObject_GenericSetDict' filepath='./Include/object.h' line='418' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_GenericSetDict'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-22'/> + <return type-id='type-id-8'/> + </function-decl> + <var-decl name='PyExc_BaseException' type-id='type-id-2' mangled-name='PyExc_BaseException' visibility='default' filepath='./Include/pyerrors.h' line='78' column='1' elf-symbol-id='PyExc_BaseException'/> + <var-decl name='PyExc_Exception' type-id='type-id-2' mangled-name='PyExc_Exception' visibility='default' filepath='./Include/pyerrors.h' line='79' column='1' elf-symbol-id='PyExc_Exception'/> + <var-decl name='PyExc_BaseExceptionGroup' type-id='type-id-2' mangled-name='PyExc_BaseExceptionGroup' visibility='default' filepath='./Include/pyerrors.h' line='80' column='1' elf-symbol-id='PyExc_BaseExceptionGroup'/> + <var-decl name='PyExc_StopAsyncIteration' type-id='type-id-2' mangled-name='PyExc_StopAsyncIteration' visibility='default' filepath='./Include/pyerrors.h' line='82' column='1' elf-symbol-id='PyExc_StopAsyncIteration'/> + <var-decl name='PyExc_StopIteration' type-id='type-id-2' mangled-name='PyExc_StopIteration' visibility='default' filepath='./Include/pyerrors.h' line='84' column='1' elf-symbol-id='PyExc_StopIteration'/> + <var-decl name='PyExc_GeneratorExit' type-id='type-id-2' mangled-name='PyExc_GeneratorExit' visibility='default' filepath='./Include/pyerrors.h' line='85' column='1' elf-symbol-id='PyExc_GeneratorExit'/> + <var-decl name='PyExc_ArithmeticError' type-id='type-id-2' mangled-name='PyExc_ArithmeticError' visibility='default' filepath='./Include/pyerrors.h' line='86' column='1' elf-symbol-id='PyExc_ArithmeticError'/> + <var-decl name='PyExc_LookupError' type-id='type-id-2' mangled-name='PyExc_LookupError' visibility='default' filepath='./Include/pyerrors.h' line='87' column='1' elf-symbol-id='PyExc_LookupError'/> + <var-decl name='PyExc_AssertionError' type-id='type-id-2' mangled-name='PyExc_AssertionError' visibility='default' filepath='./Include/pyerrors.h' line='89' column='1' elf-symbol-id='PyExc_AssertionError'/> + <var-decl name='PyExc_AttributeError' type-id='type-id-2' mangled-name='PyExc_AttributeError' visibility='default' filepath='./Include/pyerrors.h' line='90' column='1' elf-symbol-id='PyExc_AttributeError'/> + <var-decl name='PyExc_BufferError' type-id='type-id-2' mangled-name='PyExc_BufferError' visibility='default' filepath='./Include/pyerrors.h' line='91' column='1' elf-symbol-id='PyExc_BufferError'/> + <var-decl name='PyExc_EOFError' type-id='type-id-2' mangled-name='PyExc_EOFError' visibility='default' filepath='./Include/pyerrors.h' line='92' column='1' elf-symbol-id='PyExc_EOFError'/> + <var-decl name='PyExc_FloatingPointError' type-id='type-id-2' mangled-name='PyExc_FloatingPointError' visibility='default' filepath='./Include/pyerrors.h' line='93' column='1' elf-symbol-id='PyExc_FloatingPointError'/> + <var-decl name='PyExc_OSError' type-id='type-id-2' mangled-name='PyExc_OSError' visibility='default' filepath='./Include/pyerrors.h' line='94' column='1' elf-symbol-id='PyExc_OSError'/> + <var-decl name='PyExc_ImportError' type-id='type-id-2' mangled-name='PyExc_ImportError' visibility='default' filepath='./Include/pyerrors.h' line='95' column='1' elf-symbol-id='PyExc_ImportError'/> + <var-decl name='PyExc_ModuleNotFoundError' type-id='type-id-2' mangled-name='PyExc_ModuleNotFoundError' visibility='default' filepath='./Include/pyerrors.h' line='97' column='1' elf-symbol-id='PyExc_ModuleNotFoundError'/> + <var-decl name='PyExc_IndexError' type-id='type-id-2' mangled-name='PyExc_IndexError' visibility='default' filepath='./Include/pyerrors.h' line='99' column='1' elf-symbol-id='PyExc_IndexError'/> + <var-decl name='PyExc_KeyError' type-id='type-id-2' mangled-name='PyExc_KeyError' visibility='default' filepath='./Include/pyerrors.h' line='100' column='1' elf-symbol-id='PyExc_KeyError'/> + <var-decl name='PyExc_KeyboardInterrupt' type-id='type-id-2' mangled-name='PyExc_KeyboardInterrupt' visibility='default' filepath='./Include/pyerrors.h' line='101' column='1' elf-symbol-id='PyExc_KeyboardInterrupt'/> + <var-decl name='PyExc_MemoryError' type-id='type-id-2' mangled-name='PyExc_MemoryError' visibility='default' filepath='./Include/pyerrors.h' line='102' column='1' elf-symbol-id='PyExc_MemoryError'/> + <var-decl name='PyExc_NameError' type-id='type-id-2' mangled-name='PyExc_NameError' visibility='default' filepath='./Include/pyerrors.h' line='103' column='1' elf-symbol-id='PyExc_NameError'/> + <var-decl name='PyExc_OverflowError' type-id='type-id-2' mangled-name='PyExc_OverflowError' visibility='default' filepath='./Include/pyerrors.h' line='104' column='1' elf-symbol-id='PyExc_OverflowError'/> + <var-decl name='PyExc_RuntimeError' type-id='type-id-2' mangled-name='PyExc_RuntimeError' visibility='default' filepath='./Include/pyerrors.h' line='105' column='1' elf-symbol-id='PyExc_RuntimeError'/> + <var-decl name='PyExc_RecursionError' type-id='type-id-2' mangled-name='PyExc_RecursionError' visibility='default' filepath='./Include/pyerrors.h' line='107' column='1' elf-symbol-id='PyExc_RecursionError'/> + <var-decl name='PyExc_NotImplementedError' type-id='type-id-2' mangled-name='PyExc_NotImplementedError' visibility='default' filepath='./Include/pyerrors.h' line='109' column='1' elf-symbol-id='PyExc_NotImplementedError'/> + <var-decl name='PyExc_SyntaxError' type-id='type-id-2' mangled-name='PyExc_SyntaxError' visibility='default' filepath='./Include/pyerrors.h' line='110' column='1' elf-symbol-id='PyExc_SyntaxError'/> + <var-decl name='PyExc_IndentationError' type-id='type-id-2' mangled-name='PyExc_IndentationError' visibility='default' filepath='./Include/pyerrors.h' line='111' column='1' elf-symbol-id='PyExc_IndentationError'/> + <var-decl name='PyExc_TabError' type-id='type-id-2' mangled-name='PyExc_TabError' visibility='default' filepath='./Include/pyerrors.h' line='112' column='1' elf-symbol-id='PyExc_TabError'/> + <var-decl name='PyExc_ReferenceError' type-id='type-id-2' mangled-name='PyExc_ReferenceError' visibility='default' filepath='./Include/pyerrors.h' line='113' column='1' elf-symbol-id='PyExc_ReferenceError'/> + <var-decl name='PyExc_SystemError' type-id='type-id-2' mangled-name='PyExc_SystemError' visibility='default' filepath='./Include/pyerrors.h' line='114' column='1' elf-symbol-id='PyExc_SystemError'/> + <var-decl name='PyExc_SystemExit' type-id='type-id-2' mangled-name='PyExc_SystemExit' visibility='default' filepath='./Include/pyerrors.h' line='115' column='1' elf-symbol-id='PyExc_SystemExit'/> + <var-decl name='PyExc_TypeError' type-id='type-id-2' mangled-name='PyExc_TypeError' visibility='default' filepath='./Include/pyerrors.h' line='116' column='1' elf-symbol-id='PyExc_TypeError'/> + <var-decl name='PyExc_UnboundLocalError' type-id='type-id-2' mangled-name='PyExc_UnboundLocalError' visibility='default' filepath='./Include/pyerrors.h' line='117' column='1' elf-symbol-id='PyExc_UnboundLocalError'/> + <var-decl name='PyExc_UnicodeError' type-id='type-id-2' mangled-name='PyExc_UnicodeError' visibility='default' filepath='./Include/pyerrors.h' line='118' column='1' elf-symbol-id='PyExc_UnicodeError'/> + <var-decl name='PyExc_UnicodeEncodeError' type-id='type-id-2' mangled-name='PyExc_UnicodeEncodeError' visibility='default' filepath='./Include/pyerrors.h' line='119' column='1' elf-symbol-id='PyExc_UnicodeEncodeError'/> + <var-decl name='PyExc_UnicodeDecodeError' type-id='type-id-2' mangled-name='PyExc_UnicodeDecodeError' visibility='default' filepath='./Include/pyerrors.h' line='120' column='1' elf-symbol-id='PyExc_UnicodeDecodeError'/> + <var-decl name='PyExc_UnicodeTranslateError' type-id='type-id-2' mangled-name='PyExc_UnicodeTranslateError' visibility='default' filepath='./Include/pyerrors.h' line='121' column='1' elf-symbol-id='PyExc_UnicodeTranslateError'/> + <var-decl name='PyExc_ValueError' type-id='type-id-2' mangled-name='PyExc_ValueError' visibility='default' filepath='./Include/pyerrors.h' line='122' column='1' elf-symbol-id='PyExc_ValueError'/> + <var-decl name='PyExc_ZeroDivisionError' type-id='type-id-2' mangled-name='PyExc_ZeroDivisionError' visibility='default' filepath='./Include/pyerrors.h' line='123' column='1' elf-symbol-id='PyExc_ZeroDivisionError'/> + <var-decl name='PyExc_BlockingIOError' type-id='type-id-2' mangled-name='PyExc_BlockingIOError' visibility='default' filepath='./Include/pyerrors.h' line='126' column='1' elf-symbol-id='PyExc_BlockingIOError'/> + <var-decl name='PyExc_BrokenPipeError' type-id='type-id-2' mangled-name='PyExc_BrokenPipeError' visibility='default' filepath='./Include/pyerrors.h' line='127' column='1' elf-symbol-id='PyExc_BrokenPipeError'/> + <var-decl name='PyExc_ChildProcessError' type-id='type-id-2' mangled-name='PyExc_ChildProcessError' visibility='default' filepath='./Include/pyerrors.h' line='128' column='1' elf-symbol-id='PyExc_ChildProcessError'/> + <var-decl name='PyExc_ConnectionError' type-id='type-id-2' mangled-name='PyExc_ConnectionError' visibility='default' filepath='./Include/pyerrors.h' line='129' column='1' elf-symbol-id='PyExc_ConnectionError'/> + <var-decl name='PyExc_ConnectionAbortedError' type-id='type-id-2' mangled-name='PyExc_ConnectionAbortedError' visibility='default' filepath='./Include/pyerrors.h' line='130' column='1' elf-symbol-id='PyExc_ConnectionAbortedError'/> + <var-decl name='PyExc_ConnectionRefusedError' type-id='type-id-2' mangled-name='PyExc_ConnectionRefusedError' visibility='default' filepath='./Include/pyerrors.h' line='131' column='1' elf-symbol-id='PyExc_ConnectionRefusedError'/> + <var-decl name='PyExc_ConnectionResetError' type-id='type-id-2' mangled-name='PyExc_ConnectionResetError' visibility='default' filepath='./Include/pyerrors.h' line='132' column='1' elf-symbol-id='PyExc_ConnectionResetError'/> + <var-decl name='PyExc_FileExistsError' type-id='type-id-2' mangled-name='PyExc_FileExistsError' visibility='default' filepath='./Include/pyerrors.h' line='133' column='1' elf-symbol-id='PyExc_FileExistsError'/> + <var-decl name='PyExc_FileNotFoundError' type-id='type-id-2' mangled-name='PyExc_FileNotFoundError' visibility='default' filepath='./Include/pyerrors.h' line='134' column='1' elf-symbol-id='PyExc_FileNotFoundError'/> + <var-decl name='PyExc_InterruptedError' type-id='type-id-2' mangled-name='PyExc_InterruptedError' visibility='default' filepath='./Include/pyerrors.h' line='135' column='1' elf-symbol-id='PyExc_InterruptedError'/> + <var-decl name='PyExc_IsADirectoryError' type-id='type-id-2' mangled-name='PyExc_IsADirectoryError' visibility='default' filepath='./Include/pyerrors.h' line='136' column='1' elf-symbol-id='PyExc_IsADirectoryError'/> + <var-decl name='PyExc_NotADirectoryError' type-id='type-id-2' mangled-name='PyExc_NotADirectoryError' visibility='default' filepath='./Include/pyerrors.h' line='137' column='1' elf-symbol-id='PyExc_NotADirectoryError'/> + <var-decl name='PyExc_PermissionError' type-id='type-id-2' mangled-name='PyExc_PermissionError' visibility='default' filepath='./Include/pyerrors.h' line='138' column='1' elf-symbol-id='PyExc_PermissionError'/> + <var-decl name='PyExc_ProcessLookupError' type-id='type-id-2' mangled-name='PyExc_ProcessLookupError' visibility='default' filepath='./Include/pyerrors.h' line='139' column='1' elf-symbol-id='PyExc_ProcessLookupError'/> + <var-decl name='PyExc_TimeoutError' type-id='type-id-2' mangled-name='PyExc_TimeoutError' visibility='default' filepath='./Include/pyerrors.h' line='140' column='1' elf-symbol-id='PyExc_TimeoutError'/> + <var-decl name='PyExc_EnvironmentError' type-id='type-id-2' mangled-name='PyExc_EnvironmentError' visibility='default' filepath='./Include/pyerrors.h' line='145' column='1' elf-symbol-id='PyExc_EnvironmentError'/> + <var-decl name='PyExc_IOError' type-id='type-id-2' mangled-name='PyExc_IOError' visibility='default' filepath='./Include/pyerrors.h' line='146' column='1' elf-symbol-id='PyExc_IOError'/> + <var-decl name='PyExc_Warning' type-id='type-id-2' mangled-name='PyExc_Warning' visibility='default' filepath='./Include/pyerrors.h' line='152' column='1' elf-symbol-id='PyExc_Warning'/> + <var-decl name='PyExc_UserWarning' type-id='type-id-2' mangled-name='PyExc_UserWarning' visibility='default' filepath='./Include/pyerrors.h' line='153' column='1' elf-symbol-id='PyExc_UserWarning'/> + <var-decl name='PyExc_DeprecationWarning' type-id='type-id-2' mangled-name='PyExc_DeprecationWarning' visibility='default' filepath='./Include/pyerrors.h' line='154' column='1' elf-symbol-id='PyExc_DeprecationWarning'/> + <var-decl name='PyExc_PendingDeprecationWarning' type-id='type-id-2' mangled-name='PyExc_PendingDeprecationWarning' visibility='default' filepath='./Include/pyerrors.h' line='155' column='1' elf-symbol-id='PyExc_PendingDeprecationWarning'/> + <var-decl name='PyExc_SyntaxWarning' type-id='type-id-2' mangled-name='PyExc_SyntaxWarning' visibility='default' filepath='./Include/pyerrors.h' line='156' column='1' elf-symbol-id='PyExc_SyntaxWarning'/> + <var-decl name='PyExc_RuntimeWarning' type-id='type-id-2' mangled-name='PyExc_RuntimeWarning' visibility='default' filepath='./Include/pyerrors.h' line='157' column='1' elf-symbol-id='PyExc_RuntimeWarning'/> + <var-decl name='PyExc_FutureWarning' type-id='type-id-2' mangled-name='PyExc_FutureWarning' visibility='default' filepath='./Include/pyerrors.h' line='158' column='1' elf-symbol-id='PyExc_FutureWarning'/> + <var-decl name='PyExc_ImportWarning' type-id='type-id-2' mangled-name='PyExc_ImportWarning' visibility='default' filepath='./Include/pyerrors.h' line='159' column='1' elf-symbol-id='PyExc_ImportWarning'/> + <var-decl name='PyExc_UnicodeWarning' type-id='type-id-2' mangled-name='PyExc_UnicodeWarning' visibility='default' filepath='./Include/pyerrors.h' line='160' column='1' elf-symbol-id='PyExc_UnicodeWarning'/> + <var-decl name='PyExc_BytesWarning' type-id='type-id-2' mangled-name='PyExc_BytesWarning' visibility='default' filepath='./Include/pyerrors.h' line='161' column='1' elf-symbol-id='PyExc_BytesWarning'/> + <var-decl name='PyExc_EncodingWarning' type-id='type-id-2' mangled-name='PyExc_EncodingWarning' visibility='default' filepath='./Include/pyerrors.h' line='162' column='1' elf-symbol-id='PyExc_EncodingWarning'/> + <var-decl name='PyExc_ResourceWarning' type-id='type-id-2' mangled-name='PyExc_ResourceWarning' visibility='default' filepath='./Include/pyerrors.h' line='163' column='1' elf-symbol-id='PyExc_ResourceWarning'/> + <function-decl name='PyErr_NewException' mangled-name='PyErr_NewException' filepath='./Include/pyerrors.h' line='231' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_NewException'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PySet_New' mangled-name='PySet_New' filepath='./Include/setobject.h' line='13' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySet_New'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PySet_Add' mangled-name='PySet_Add' filepath='./Include/setobject.h' line='16' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySet_Add'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PySet_Contains' mangled-name='PySet_Contains' filepath='./Include/setobject.h' line='18' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySet_Contains'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyTuple_Size' mangled-name='PyTuple_Size' filepath='./Include/tupleobject.h' line='31' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyTuple_Size'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-14'/> + </function-decl> + <function-decl name='PyUnicode_ReadChar' mangled-name='PyUnicode_ReadChar' filepath='./Include/unicodeobject.h' line='177' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_ReadChar'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-14'/> + <return type-id='type-id-250'/> + </function-decl> + <function-decl name='PyException_GetTraceback' mangled-name='PyException_GetTraceback' filepath='Objects/exceptions.c' line='377' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyException_GetTraceback'> + <parameter type-id='type-id-2' name='self' filepath='Objects/exceptions.c' line='377' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyException_SetTraceback' mangled-name='PyException_SetTraceback' filepath='Objects/exceptions.c' line='385' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyException_SetTraceback'> + <parameter type-id='type-id-2' name='self' filepath='Objects/exceptions.c' line='385' column='1'/> + <parameter type-id='type-id-2' name='tb' filepath='Objects/exceptions.c' line='385' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyException_GetCause' mangled-name='PyException_GetCause' filepath='Objects/exceptions.c' line='391' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyException_GetCause'> + <parameter type-id='type-id-2' name='self' filepath='Objects/exceptions.c' line='391' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyException_SetCause' mangled-name='PyException_SetCause' filepath='Objects/exceptions.c' line='399' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyException_SetCause'> + <parameter type-id='type-id-2' name='self' filepath='Objects/exceptions.c' line='399' column='1'/> + <parameter type-id='type-id-2' name='cause' filepath='Objects/exceptions.c' line='399' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyException_GetContext' mangled-name='PyException_GetContext' filepath='Objects/exceptions.c' line='407' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyException_GetContext'> + <parameter type-id='type-id-2' name='self' filepath='Objects/exceptions.c' line='407' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyException_SetContext' mangled-name='PyException_SetContext' filepath='Objects/exceptions.c' line='415' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyException_SetContext'> + <parameter type-id='type-id-2' name='self' filepath='Objects/exceptions.c' line='415' column='1'/> + <parameter type-id='type-id-2' name='context' filepath='Objects/exceptions.c' line='415' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyException_GetArgs' mangled-name='PyException_GetArgs' filepath='Objects/exceptions.c' line='421' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyException_GetArgs'> + <parameter type-id='type-id-2' name='self' filepath='Objects/exceptions.c' line='421' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyException_SetArgs' mangled-name='PyException_SetArgs' filepath='Objects/exceptions.c' line='428' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyException_SetArgs'> + <parameter type-id='type-id-2' name='self' filepath='Objects/exceptions.c' line='428' column='1'/> + <parameter type-id='type-id-2' name='args' filepath='Objects/exceptions.c' line='428' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyExceptionClass_Name' mangled-name='PyExceptionClass_Name' filepath='Objects/exceptions.c' line='435' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyExceptionClass_Name'> + <parameter type-id='type-id-2' name='ob' filepath='Objects/exceptions.c' line='435' column='1'/> + <return type-id='type-id-12'/> + </function-decl> + <function-decl name='_PyExc_CreateExceptionGroup' mangled-name='_PyExc_CreateExceptionGroup' filepath='Objects/exceptions.c' line='810' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyExc_CreateExceptionGroup'> + <parameter type-id='type-id-12' name='msg_str' filepath='Objects/exceptions.c' line='810' column='1'/> + <parameter type-id='type-id-2' name='excs' filepath='Objects/exceptions.c' line='810' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyExc_PrepReraiseStar' mangled-name='_PyExc_PrepReraiseStar' filepath='Objects/exceptions.c' line='1351' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyExc_PrepReraiseStar'> + <parameter type-id='type-id-2' name='orig' filepath='Objects/exceptions.c' line='1351' column='1'/> + <parameter type-id='type-id-2' name='excs' filepath='Objects/exceptions.c' line='1351' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyUnstable_Exc_PrepReraiseStar' mangled-name='PyUnstable_Exc_PrepReraiseStar' filepath='Objects/exceptions.c' line='1444' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnstable_Exc_PrepReraiseStar'> + <parameter type-id='type-id-2' name='orig' filepath='Objects/exceptions.c' line='1444' column='1'/> + <parameter type-id='type-id-2' name='excs' filepath='Objects/exceptions.c' line='1444' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyUnicodeEncodeError_GetEncoding' mangled-name='PyUnicodeEncodeError_GetEncoding' filepath='Objects/exceptions.c' line='2679' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicodeEncodeError_GetEncoding'> + <parameter type-id='type-id-2' name='exc' filepath='Objects/exceptions.c' line='2679' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyUnicodeDecodeError_GetEncoding' mangled-name='PyUnicodeDecodeError_GetEncoding' filepath='Objects/exceptions.c' line='2685' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicodeDecodeError_GetEncoding'> + <parameter type-id='type-id-2' name='exc' filepath='Objects/exceptions.c' line='2685' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyUnicodeEncodeError_GetObject' mangled-name='PyUnicodeEncodeError_GetObject' filepath='Objects/exceptions.c' line='2691' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicodeEncodeError_GetObject'> + <parameter type-id='type-id-2' name='exc' filepath='Objects/exceptions.c' line='2691' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyUnicodeDecodeError_GetObject' mangled-name='PyUnicodeDecodeError_GetObject' filepath='Objects/exceptions.c' line='2697' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicodeDecodeError_GetObject'> + <parameter type-id='type-id-2' name='exc' filepath='Objects/exceptions.c' line='2697' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyUnicodeTranslateError_GetObject' mangled-name='PyUnicodeTranslateError_GetObject' filepath='Objects/exceptions.c' line='2703' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicodeTranslateError_GetObject'> + <parameter type-id='type-id-2' name='exc' filepath='Objects/exceptions.c' line='2703' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyUnicodeEncodeError_GetStart' mangled-name='PyUnicodeEncodeError_GetStart' filepath='Objects/exceptions.c' line='2709' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicodeEncodeError_GetStart'> + <parameter type-id='type-id-2' name='exc' filepath='Objects/exceptions.c' line='2709' column='1'/> + <parameter type-id='type-id-13' name='start' filepath='Objects/exceptions.c' line='2709' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyUnicodeDecodeError_GetStart' mangled-name='PyUnicodeDecodeError_GetStart' filepath='Objects/exceptions.c' line='2728' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicodeDecodeError_GetStart'> + <parameter type-id='type-id-2' name='exc' filepath='Objects/exceptions.c' line='2728' column='1'/> + <parameter type-id='type-id-13' name='start' filepath='Objects/exceptions.c' line='2728' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyUnicodeTranslateError_GetStart' mangled-name='PyUnicodeTranslateError_GetStart' filepath='Objects/exceptions.c' line='2746' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicodeTranslateError_GetStart'> + <parameter type-id='type-id-2' name='exc' filepath='Objects/exceptions.c' line='2746' column='1'/> + <parameter type-id='type-id-13' name='start' filepath='Objects/exceptions.c' line='2746' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyUnicodeEncodeError_SetStart' mangled-name='PyUnicodeEncodeError_SetStart' filepath='Objects/exceptions.c' line='2753' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicodeEncodeError_SetStart'> + <parameter type-id='type-id-2' name='exc' filepath='Objects/exceptions.c' line='2753' column='1'/> + <parameter type-id='type-id-14' name='start' filepath='Objects/exceptions.c' line='2753' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyUnicodeDecodeError_SetStart' mangled-name='PyUnicodeDecodeError_SetStart' filepath='Objects/exceptions.c' line='2761' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicodeDecodeError_SetStart'> + <parameter type-id='type-id-2' name='exc' filepath='Objects/exceptions.c' line='2761' column='1'/> + <parameter type-id='type-id-14' name='start' filepath='Objects/exceptions.c' line='2761' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyUnicodeTranslateError_SetStart' mangled-name='PyUnicodeTranslateError_SetStart' filepath='Objects/exceptions.c' line='2769' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicodeTranslateError_SetStart'> + <parameter type-id='type-id-2' name='exc' filepath='Objects/exceptions.c' line='2769' column='1'/> + <parameter type-id='type-id-14' name='start' filepath='Objects/exceptions.c' line='2769' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyUnicodeEncodeError_GetEnd' mangled-name='PyUnicodeEncodeError_GetEnd' filepath='Objects/exceptions.c' line='2777' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicodeEncodeError_GetEnd'> + <parameter type-id='type-id-2' name='exc' filepath='Objects/exceptions.c' line='2777' column='1'/> + <parameter type-id='type-id-13' name='end' filepath='Objects/exceptions.c' line='2777' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyUnicodeDecodeError_GetEnd' mangled-name='PyUnicodeDecodeError_GetEnd' filepath='Objects/exceptions.c' line='2796' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicodeDecodeError_GetEnd'> + <parameter type-id='type-id-2' name='exc' filepath='Objects/exceptions.c' line='2796' column='1'/> + <parameter type-id='type-id-13' name='end' filepath='Objects/exceptions.c' line='2796' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyUnicodeTranslateError_GetEnd' mangled-name='PyUnicodeTranslateError_GetEnd' filepath='Objects/exceptions.c' line='2814' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicodeTranslateError_GetEnd'> + <parameter type-id='type-id-2' name='exc' filepath='Objects/exceptions.c' line='2814' column='1'/> + <parameter type-id='type-id-13' name='end' filepath='Objects/exceptions.c' line='2814' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyUnicodeEncodeError_SetEnd' mangled-name='PyUnicodeEncodeError_SetEnd' filepath='Objects/exceptions.c' line='2821' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicodeEncodeError_SetEnd'> + <parameter type-id='type-id-2' name='exc' filepath='Objects/exceptions.c' line='2821' column='1'/> + <parameter type-id='type-id-14' name='end' filepath='Objects/exceptions.c' line='2821' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyUnicodeDecodeError_SetEnd' mangled-name='PyUnicodeDecodeError_SetEnd' filepath='Objects/exceptions.c' line='2829' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicodeDecodeError_SetEnd'> + <parameter type-id='type-id-2' name='exc' filepath='Objects/exceptions.c' line='2829' column='1'/> + <parameter type-id='type-id-14' name='end' filepath='Objects/exceptions.c' line='2829' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyUnicodeTranslateError_SetEnd' mangled-name='PyUnicodeTranslateError_SetEnd' filepath='Objects/exceptions.c' line='2837' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicodeTranslateError_SetEnd'> + <parameter type-id='type-id-2' name='exc' filepath='Objects/exceptions.c' line='2837' column='1'/> + <parameter type-id='type-id-14' name='end' filepath='Objects/exceptions.c' line='2837' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyUnicodeEncodeError_GetReason' mangled-name='PyUnicodeEncodeError_GetReason' filepath='Objects/exceptions.c' line='2844' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicodeEncodeError_GetReason'> + <parameter type-id='type-id-2' name='exc' filepath='Objects/exceptions.c' line='2844' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyUnicodeDecodeError_GetReason' mangled-name='PyUnicodeDecodeError_GetReason' filepath='Objects/exceptions.c' line='2851' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicodeDecodeError_GetReason'> + <parameter type-id='type-id-2' name='exc' filepath='Objects/exceptions.c' line='2851' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyUnicodeTranslateError_GetReason' mangled-name='PyUnicodeTranslateError_GetReason' filepath='Objects/exceptions.c' line='2858' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicodeTranslateError_GetReason'> + <parameter type-id='type-id-2' name='exc' filepath='Objects/exceptions.c' line='2858' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyUnicodeEncodeError_SetReason' mangled-name='PyUnicodeEncodeError_SetReason' filepath='Objects/exceptions.c' line='2865' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicodeEncodeError_SetReason'> + <parameter type-id='type-id-2' name='exc' filepath='Objects/exceptions.c' line='2865' column='1'/> + <parameter type-id='type-id-12' name='reason' filepath='Objects/exceptions.c' line='2865' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyUnicodeDecodeError_SetReason' mangled-name='PyUnicodeDecodeError_SetReason' filepath='Objects/exceptions.c' line='2873' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicodeDecodeError_SetReason'> + <parameter type-id='type-id-2' name='exc' filepath='Objects/exceptions.c' line='2873' column='1'/> + <parameter type-id='type-id-12' name='reason' filepath='Objects/exceptions.c' line='2873' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyUnicodeTranslateError_SetReason' mangled-name='PyUnicodeTranslateError_SetReason' filepath='Objects/exceptions.c' line='2881' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicodeTranslateError_SetReason'> + <parameter type-id='type-id-2' name='exc' filepath='Objects/exceptions.c' line='2881' column='1'/> + <parameter type-id='type-id-12' name='reason' filepath='Objects/exceptions.c' line='2881' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyUnicodeDecodeError_Create' mangled-name='PyUnicodeDecodeError_Create' filepath='Objects/exceptions.c' line='3134' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicodeDecodeError_Create'> + <parameter type-id='type-id-12' name='encoding' filepath='Objects/exceptions.c' line='3135' column='1'/> + <parameter type-id='type-id-12' name='object' filepath='Objects/exceptions.c' line='3135' column='1'/> + <parameter type-id='type-id-14' name='length' filepath='Objects/exceptions.c' line='3135' column='1'/> + <parameter type-id='type-id-14' name='start' filepath='Objects/exceptions.c' line='3136' column='1'/> + <parameter type-id='type-id-14' name='end' filepath='Objects/exceptions.c' line='3136' column='1'/> + <parameter type-id='type-id-12' name='reason' filepath='Objects/exceptions.c' line='3136' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyUnicodeTranslateError_Create' mangled-name='_PyUnicodeTranslateError_Create' filepath='Objects/exceptions.c' line='3231' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicodeTranslateError_Create'> + <parameter type-id='type-id-2' name='object' filepath='Objects/exceptions.c' line='3232' column='1'/> + <parameter type-id='type-id-14' name='start' filepath='Objects/exceptions.c' line='3233' column='1'/> + <parameter type-id='type-id-14' name='end' filepath='Objects/exceptions.c' line='3233' column='1'/> + <parameter type-id='type-id-12' name='reason' filepath='Objects/exceptions.c' line='3233' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyException_AddNote' mangled-name='_PyException_AddNote' filepath='Objects/exceptions.c' line='3832' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyException_AddNote'> + <parameter type-id='type-id-2' name='exc' filepath='Objects/exceptions.c' line='3832' column='1'/> + <parameter type-id='type-id-2' name='note' filepath='Objects/exceptions.c' line='3832' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Objects/fileobject.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <var-decl name='PyStdPrinter_Type' type-id='type-id-256' mangled-name='PyStdPrinter_Type' visibility='default' filepath='./Include/cpython/fileobject.h' line='11' column='1' elf-symbol-id='PyStdPrinter_Type'/> + <function-decl name='_PyUnicode_AsUTF8String' mangled-name='_PyUnicode_AsUTF8String' filepath='./Include/cpython/unicodeobject.h' line='640' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_AsUTF8String'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-12'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_Py_write' mangled-name='_Py_write' filepath='./Include/internal/pycore_fileutils.h' line='122' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_write'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-22'/> + <parameter type-id='type-id-19'/> + <return type-id='type-id-14'/> + </function-decl> + <function-decl name='Py_IsInitialized' mangled-name='Py_IsInitialized' filepath='./Include/pylifecycle.h' line='18' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_IsInitialized'> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='getc_unlocked' filepath='/usr/include/stdio.h' line='527' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-229'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='flockfile' filepath='/usr/include/stdio.h' line='867' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-229'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='funlockfile' filepath='/usr/include/stdio.h' line='874' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-229'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyFile_FromFd' mangled-name='PyFile_FromFd' filepath='Objects/fileobject.c' line='32' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFile_FromFd'> + <parameter type-id='type-id-8' name='fd' filepath='Objects/fileobject.c' line='32' column='1'/> + <parameter type-id='type-id-12' name='name' filepath='Objects/fileobject.c' line='32' column='1'/> + <parameter type-id='type-id-12' name='mode' filepath='Objects/fileobject.c' line='32' column='1'/> + <parameter type-id='type-id-8' name='buffering' filepath='Objects/fileobject.c' line='32' column='1'/> + <parameter type-id='type-id-12' name='encoding' filepath='Objects/fileobject.c' line='32' column='1'/> + <parameter type-id='type-id-12' name='errors' filepath='Objects/fileobject.c' line='33' column='1'/> + <parameter type-id='type-id-12' name='newline' filepath='Objects/fileobject.c' line='33' column='1'/> + <parameter type-id='type-id-8' name='closefd' filepath='Objects/fileobject.c' line='33' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyFile_GetLine' mangled-name='PyFile_GetLine' filepath='Objects/fileobject.c' line='53' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFile_GetLine'> + <parameter type-id='type-id-2' name='f' filepath='Objects/fileobject.c' line='53' column='1'/> + <parameter type-id='type-id-8' name='n' filepath='Objects/fileobject.c' line='53' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyFile_WriteObject' mangled-name='PyFile_WriteObject' filepath='Objects/fileobject.c' line='112' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFile_WriteObject'> + <parameter type-id='type-id-2' name='v' filepath='Objects/fileobject.c' line='112' column='1'/> + <parameter type-id='type-id-2' name='f' filepath='Objects/fileobject.c' line='112' column='1'/> + <parameter type-id='type-id-8' name='flags' filepath='Objects/fileobject.c' line='112' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyFile_WriteString' mangled-name='PyFile_WriteString' filepath='Objects/fileobject.c' line='142' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFile_WriteString'> + <parameter type-id='type-id-12' name='s' filepath='Objects/fileobject.c' line='142' column='1'/> + <parameter type-id='type-id-2' name='f' filepath='Objects/fileobject.c' line='142' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyObject_AsFileDescriptor' mangled-name='PyObject_AsFileDescriptor' filepath='Objects/fileobject.c' line='172' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_AsFileDescriptor'> + <parameter type-id='type-id-2' name='o' filepath='Objects/fileobject.c' line='172' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyLong_FileDescriptor_Converter' mangled-name='_PyLong_FileDescriptor_Converter' filepath='Objects/fileobject.c' line='218' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyLong_FileDescriptor_Converter'> + <parameter type-id='type-id-2' name='o' filepath='Objects/fileobject.c' line='218' column='1'/> + <parameter type-id='type-id-22' name='ptr' filepath='Objects/fileobject.c' line='218' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='Py_UniversalNewlineFgets' mangled-name='Py_UniversalNewlineFgets' filepath='Objects/fileobject.c' line='272' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_UniversalNewlineFgets'> + <parameter type-id='type-id-15' name='buf' filepath='Objects/fileobject.c' line='272' column='1'/> + <parameter type-id='type-id-8' name='n' filepath='Objects/fileobject.c' line='272' column='1'/> + <parameter type-id='type-id-229' name='stream' filepath='Objects/fileobject.c' line='272' column='1'/> + <parameter type-id='type-id-2' name='fobj' filepath='Objects/fileobject.c' line='272' column='1'/> + <return type-id='type-id-15'/> + </function-decl> + <function-decl name='PyFile_NewStdPrinter' mangled-name='PyFile_NewStdPrinter' filepath='Objects/fileobject.c' line='288' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFile_NewStdPrinter'> + <parameter type-id='type-id-8' name='fd' filepath='Objects/fileobject.c' line='288' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyFile_SetOpenCodeHook' mangled-name='PyFile_SetOpenCodeHook' filepath='Objects/fileobject.c' line='475' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFile_SetOpenCodeHook'> + <parameter type-id='type-id-355' name='hook' filepath='Objects/fileobject.c' line='475' column='1'/> + <parameter type-id='type-id-22' name='userData' filepath='Objects/fileobject.c' line='475' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyFile_OpenCodeObject' mangled-name='PyFile_OpenCodeObject' filepath='Objects/fileobject.c' line='495' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFile_OpenCodeObject'> + <parameter type-id='type-id-2' name='path' filepath='Objects/fileobject.c' line='495' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyFile_OpenCode' mangled-name='PyFile_OpenCode' filepath='Objects/fileobject.c' line='520' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFile_OpenCode'> + <parameter type-id='type-id-12' name='utf8path' filepath='Objects/fileobject.c' line='520' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Objects/floatobject.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <class-decl name='PyStructSequence_Field' size-in-bits='128' is-struct='yes' visibility='default' filepath='./Include/structseq.h' line='10' column='1' id='type-id-356'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='name' type-id='type-id-12' visibility='default' filepath='./Include/structseq.h' line='11' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='doc' type-id='type-id-12' visibility='default' filepath='./Include/structseq.h' line='12' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='PyStructSequence_Field' type-id='type-id-356' filepath='./Include/structseq.h' line='13' column='1' id='type-id-357'/> + <class-decl name='PyStructSequence_Desc' size-in-bits='256' is-struct='yes' visibility='default' filepath='./Include/structseq.h' line='15' column='1' id='type-id-358'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='name' type-id='type-id-12' visibility='default' filepath='./Include/structseq.h' line='16' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='doc' type-id='type-id-12' visibility='default' filepath='./Include/structseq.h' line='17' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='fields' type-id='type-id-359' visibility='default' filepath='./Include/structseq.h' line='18' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='n_in_sequence' type-id='type-id-8' visibility='default' filepath='./Include/structseq.h' line='19' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='PyStructSequence_Desc' type-id='type-id-358' filepath='./Include/structseq.h' line='20' column='1' id='type-id-360'/> + <pointer-type-def type-id='type-id-360' size-in-bits='64' id='type-id-361'/> + <pointer-type-def type-id='type-id-357' size-in-bits='64' id='type-id-359'/> + <qualified-type-def type-id='type-id-239' restrict='yes' id='type-id-184'/> + <qualified-type-def type-id='type-id-12' restrict='yes' id='type-id-181'/> + <function-decl name='_PyLong_Sign' mangled-name='_PyLong_Sign' filepath='./Include/cpython/longobject.h' line='28' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyLong_Sign'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyLong_NumBits' mangled-name='_PyLong_NumBits' filepath='./Include/cpython/longobject.h' line='37' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyLong_NumBits'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-19'/> + </function-decl> + <function-decl name='_PyLong_Lshift' mangled-name='_PyLong_Lshift' filepath='./Include/cpython/longobject.h' line='95' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyLong_Lshift'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-19'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyDebugAllocatorStats' mangled-name='_PyDebugAllocatorStats' filepath='./Include/cpython/object.h' line='399' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyDebugAllocatorStats'> + <parameter type-id='type-id-229'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-19'/> + <return type-id='type-id-46'/> + </function-decl> + <var-decl name='PyFloat_Type' type-id='type-id-256' mangled-name='PyFloat_Type' visibility='default' filepath='./Include/floatobject.h' line='14' column='1' elf-symbol-id='PyFloat_Type'/> + <function-decl name='_Py_dg_strtod' mangled-name='_Py_dg_strtod' filepath='./Include/internal/pycore_dtoa.h' line='63' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_dg_strtod'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-239'/> + <return type-id='type-id-251'/> + </function-decl> + <function-decl name='_Py_dg_dtoa' mangled-name='_Py_dg_dtoa' filepath='./Include/internal/pycore_dtoa.h' line='64' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_dg_dtoa'> + <parameter type-id='type-id-251'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-179'/> + <parameter type-id='type-id-179'/> + <parameter type-id='type-id-239'/> + <return type-id='type-id-15'/> + </function-decl> + <function-decl name='_Py_dg_freedtoa' mangled-name='_Py_dg_freedtoa' filepath='./Include/internal/pycore_dtoa.h' line='66' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_dg_freedtoa'> + <parameter type-id='type-id-15'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyFloat_FormatAdvancedWriter' mangled-name='_PyFloat_FormatAdvancedWriter' filepath='./Include/internal/pycore_floatobject.h' line='61' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyFloat_FormatAdvancedWriter'> + <parameter type-id='type-id-332'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-14'/> + <parameter type-id='type-id-14'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_Py_get_387controlword' filepath='./Include/internal/pycore_pymath.h' line='90' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-84'/> + </function-decl> + <function-decl name='_Py_set_387controlword' filepath='./Include/internal/pycore_pymath.h' line='91' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-84'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyStructSequence_InitBuiltinWithFlags' filepath='./Include/internal/pycore_structseq.h' line='18' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <parameter type-id='type-id-1'/> + <parameter type-id='type-id-361'/> + <parameter type-id='type-id-28'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyStructSequence_FiniBuiltin' filepath='./Include/internal/pycore_structseq.h' line='32' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <parameter type-id='type-id-1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyLong_FromDouble' mangled-name='PyLong_FromDouble' filepath='./Include/longobject.h' line='20' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyLong_FromDouble'> + <parameter type-id='type-id-251'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyErr_SetFromErrno' mangled-name='PyErr_SetFromErrno' filepath='./Include/pyerrors.h' line='170' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_SetFromErrno'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_Py_parse_inf_or_nan' mangled-name='_Py_parse_inf_or_nan' filepath='./Include/pystrtod.h' line='26' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_parse_inf_or_nan'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-239'/> + <return type-id='type-id-251'/> + </function-decl> + <function-decl name='PyStructSequence_New' mangled-name='PyStructSequence_New' filepath='./Include/structseq.h' line='32' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyStructSequence_New'> + <parameter type-id='type-id-1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='strtol' filepath='/usr/include/stdlib.h' line='177' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-181'/> + <parameter type-id='type-id-184'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-47'/> + </function-decl> + <function-decl name='frexp' filepath='/usr/include/x86_64-linux-gnu/bits/mathcalls.h' line='98' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-251'/> + <parameter type-id='type-id-179'/> + <return type-id='type-id-251'/> + </function-decl> + <function-decl name='ldexp' filepath='/usr/include/x86_64-linux-gnu/bits/mathcalls.h' line='101' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-251'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-251'/> + </function-decl> + <function-decl name='modf' filepath='/usr/include/x86_64-linux-gnu/bits/mathcalls.h' line='110' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-251'/> + <parameter type-id='type-id-182'/> + <return type-id='type-id-251'/> + </function-decl> + <function-decl name='ceil' filepath='/usr/include/x86_64-linux-gnu/bits/mathcalls.h' line='159' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-251'/> + <return type-id='type-id-251'/> + </function-decl> + <function-decl name='fmod' filepath='/usr/include/x86_64-linux-gnu/bits/mathcalls.h' line='168' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-251'/> + <parameter type-id='type-id-251'/> + <return type-id='type-id-251'/> + </function-decl> + <function-decl name='round' filepath='/usr/include/x86_64-linux-gnu/bits/mathcalls.h' line='301' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-251'/> + <return type-id='type-id-251'/> + </function-decl> + <function-decl name='PyFloat_GetMax' mangled-name='PyFloat_GetMax' filepath='Objects/floatobject.c' line='44' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFloat_GetMax'> + <return type-id='type-id-251'/> + </function-decl> + <function-decl name='PyFloat_GetMin' mangled-name='PyFloat_GetMin' filepath='Objects/floatobject.c' line='50' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFloat_GetMin'> + <return type-id='type-id-251'/> + </function-decl> + <function-decl name='PyFloat_GetInfo' mangled-name='PyFloat_GetInfo' filepath='Objects/floatobject.c' line='94' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFloat_GetInfo'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyFloat_DebugMallocStats' mangled-name='_PyFloat_DebugMallocStats' filepath='Objects/floatobject.c' line='2037' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyFloat_DebugMallocStats'> + <parameter type-id='type-id-229' name='out' filepath='Objects/floatobject.c' line='2037' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyFloat_Pack2' mangled-name='PyFloat_Pack2' filepath='Objects/floatobject.c' line='2060' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFloat_Pack2'> + <parameter type-id='type-id-251' name='x' filepath='Objects/floatobject.c' line='2060' column='1'/> + <parameter type-id='type-id-15' name='data' filepath='Objects/floatobject.c' line='2060' column='1'/> + <parameter type-id='type-id-8' name='le' filepath='Objects/floatobject.c' line='2060' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyFloat_Pack4' mangled-name='PyFloat_Pack4' filepath='Objects/floatobject.c' line='2165' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFloat_Pack4'> + <parameter type-id='type-id-251' name='x' filepath='Objects/floatobject.c' line='2165' column='1'/> + <parameter type-id='type-id-15' name='data' filepath='Objects/floatobject.c' line='2165' column='1'/> + <parameter type-id='type-id-8' name='le' filepath='Objects/floatobject.c' line='2165' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyFloat_Pack8' mangled-name='PyFloat_Pack8' filepath='Objects/floatobject.c' line='2273' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFloat_Pack8'> + <parameter type-id='type-id-251' name='x' filepath='Objects/floatobject.c' line='2273' column='1'/> + <parameter type-id='type-id-15' name='data' filepath='Objects/floatobject.c' line='2273' column='1'/> + <parameter type-id='type-id-8' name='le' filepath='Objects/floatobject.c' line='2273' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyFloat_Unpack2' mangled-name='PyFloat_Unpack2' filepath='Objects/floatobject.c' line='2403' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFloat_Unpack2'> + <parameter type-id='type-id-12' name='data' filepath='Objects/floatobject.c' line='2403' column='1'/> + <parameter type-id='type-id-8' name='le' filepath='Objects/floatobject.c' line='2403' column='1'/> + <return type-id='type-id-251'/> + </function-decl> + <function-decl name='PyFloat_Unpack4' mangled-name='PyFloat_Unpack4' filepath='Objects/floatobject.c' line='2455' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFloat_Unpack4'> + <parameter type-id='type-id-12' name='data' filepath='Objects/floatobject.c' line='2455' column='1'/> + <parameter type-id='type-id-8' name='le' filepath='Objects/floatobject.c' line='2455' column='1'/> + <return type-id='type-id-251'/> + </function-decl> + <function-decl name='PyFloat_Unpack8' mangled-name='PyFloat_Unpack8' filepath='Objects/floatobject.c' line='2534' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFloat_Unpack8'> + <parameter type-id='type-id-12' name='data' filepath='Objects/floatobject.c' line='2534' column='1'/> + <parameter type-id='type-id-8' name='le' filepath='Objects/floatobject.c' line='2534' column='1'/> + <return type-id='type-id-251'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Objects/frameobject.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <class-decl name='PyFrameConstructor' size-in-bits='512' is-struct='yes' naming-typedef-id='type-id-362' visibility='default' filepath='./Include/cpython/funcobject.h' line='21' column='1' id='type-id-363'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='fc_globals' type-id='type-id-2' visibility='default' filepath='./Include/cpython/funcobject.h' line='22' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='fc_builtins' type-id='type-id-2' visibility='default' filepath='./Include/cpython/funcobject.h' line='22' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='fc_name' type-id='type-id-2' visibility='default' filepath='./Include/cpython/funcobject.h' line='22' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='fc_qualname' type-id='type-id-2' visibility='default' filepath='./Include/cpython/funcobject.h' line='22' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='fc_code' type-id='type-id-2' visibility='default' filepath='./Include/cpython/funcobject.h' line='22' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='fc_defaults' type-id='type-id-2' visibility='default' filepath='./Include/cpython/funcobject.h' line='22' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='384'> + <var-decl name='fc_kwdefaults' type-id='type-id-2' visibility='default' filepath='./Include/cpython/funcobject.h' line='22' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='448'> + <var-decl name='fc_closure' type-id='type-id-2' visibility='default' filepath='./Include/cpython/funcobject.h' line='22' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='PyFrameConstructor' type-id='type-id-363' filepath='./Include/cpython/funcobject.h' line='23' column='1' id='type-id-362'/> + <pointer-type-def type-id='type-id-362' size-in-bits='64' id='type-id-364'/> + <function-decl name='PyCompile_OpcodeStackEffect' mangled-name='PyCompile_OpcodeStackEffect' filepath='./Include/cpython/compile.h' line='68' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCompile_OpcodeStackEffect'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-8'/> + </function-decl> + <var-decl name='PyFrame_Type' type-id='type-id-256' mangled-name='PyFrame_Type' visibility='default' filepath='./Include/cpython/pyframe.h' line='5' column='1' elf-symbol-id='PyFrame_Type'/> + <function-decl name='_PyUnicode_Equal' mangled-name='_PyUnicode_Equal' filepath='./Include/cpython/unicodeobject.h' line='956' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_Equal'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyDict_Size' mangled-name='PyDict_Size' filepath='./Include/dictobject.h' line='32' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyDict_Size'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-14'/> + </function-decl> + <function-decl name='PyDict_Merge' mangled-name='PyDict_Merge' filepath='./Include/dictobject.h' line='44' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyDict_Merge'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyEval_GetBuiltins' filepath='./Include/internal/pycore_ceval.h' line='56' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-177'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyCode_GetCode' filepath='./Include/internal/pycore_code.h' line='209' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-328'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyCode_InitAddressRange' filepath='./Include/internal/pycore_code.h' line='212' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-328'/> + <parameter type-id='type-id-320'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyLineTable_NextAddressRange' filepath='./Include/internal/pycore_code.h' line='222' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-320'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyFunction_FromConstructor' filepath='./Include/internal/pycore_function.h' line='17' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-364'/> + <return type-id='type-id-310'/> + </function-decl> + <function-decl name='PyThreadState_Get' mangled-name='PyThreadState_Get' filepath='./Include/pystate.h' line='60' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThreadState_Get'> + <return type-id='type-id-177'/> + </function-decl> + <function-decl name='PyFrame_GetLineNumber' mangled-name='PyFrame_GetLineNumber' filepath='Objects/frameobject.c' line='34' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFrame_GetLineNumber'> + <parameter type-id='type-id-365' name='f' filepath='Objects/frameobject.c' line='34' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyFrame_New' mangled-name='PyFrame_New' filepath='Objects/frameobject.c' line='1063' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFrame_New'> + <parameter type-id='type-id-177' name='tstate' filepath='Objects/frameobject.c' line='1063' column='1'/> + <parameter type-id='type-id-328' name='code' filepath='Objects/frameobject.c' line='1063' column='1'/> + <parameter type-id='type-id-2' name='globals' filepath='Objects/frameobject.c' line='1064' column='1'/> + <parameter type-id='type-id-2' name='locals' filepath='Objects/frameobject.c' line='1064' column='1'/> + <return type-id='type-id-365'/> + </function-decl> + <function-decl name='PyFrame_GetVar' mangled-name='PyFrame_GetVar' filepath='Objects/frameobject.c' line='1305' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFrame_GetVar'> + <parameter type-id='type-id-365' name='frame_obj' filepath='Objects/frameobject.c' line='1305' column='1'/> + <parameter type-id='type-id-2' name='name' filepath='Objects/frameobject.c' line='1305' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyFrame_GetVarString' mangled-name='PyFrame_GetVarString' filepath='Objects/frameobject.c' line='1339' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFrame_GetVarString'> + <parameter type-id='type-id-365' name='frame' filepath='Objects/frameobject.c' line='1339' column='1'/> + <parameter type-id='type-id-12' name='name' filepath='Objects/frameobject.c' line='1339' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyFrame_FastToLocalsWithError' mangled-name='PyFrame_FastToLocalsWithError' filepath='Objects/frameobject.c' line='1352' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFrame_FastToLocalsWithError'> + <parameter type-id='type-id-365' name='f' filepath='Objects/frameobject.c' line='1352' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyFrame_FastToLocals' mangled-name='PyFrame_FastToLocals' filepath='Objects/frameobject.c' line='1367' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFrame_FastToLocals'> + <parameter type-id='type-id-365' name='f' filepath='Objects/frameobject.c' line='1367' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyFrame_LocalsToFast' mangled-name='PyFrame_LocalsToFast' filepath='Objects/frameobject.c' line='1453' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFrame_LocalsToFast'> + <parameter type-id='type-id-365' name='f' filepath='Objects/frameobject.c' line='1453' column='1'/> + <parameter type-id='type-id-8' name='clear' filepath='Objects/frameobject.c' line='1453' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyFrame_IsEntryFrame' mangled-name='_PyFrame_IsEntryFrame' filepath='Objects/frameobject.c' line='1463' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyFrame_IsEntryFrame'> + <parameter type-id='type-id-365' name='frame' filepath='Objects/frameobject.c' line='1463' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyFrame_GetCode' mangled-name='PyFrame_GetCode' filepath='Objects/frameobject.c' line='1472' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFrame_GetCode'> + <parameter type-id='type-id-365' name='frame' filepath='Objects/frameobject.c' line='1472' column='1'/> + <return type-id='type-id-328'/> + </function-decl> + <function-decl name='PyFrame_GetBack' mangled-name='PyFrame_GetBack' filepath='Objects/frameobject.c' line='1483' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFrame_GetBack'> + <parameter type-id='type-id-365' name='frame' filepath='Objects/frameobject.c' line='1483' column='1'/> + <return type-id='type-id-365'/> + </function-decl> + <function-decl name='PyFrame_GetLocals' mangled-name='PyFrame_GetLocals' filepath='Objects/frameobject.c' line='1499' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFrame_GetLocals'> + <parameter type-id='type-id-365' name='frame' filepath='Objects/frameobject.c' line='1499' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyFrame_GetGlobals' mangled-name='PyFrame_GetGlobals' filepath='Objects/frameobject.c' line='1506' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFrame_GetGlobals'> + <parameter type-id='type-id-365' name='frame' filepath='Objects/frameobject.c' line='1506' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyFrame_GetBuiltins' mangled-name='PyFrame_GetBuiltins' filepath='Objects/frameobject.c' line='1513' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFrame_GetBuiltins'> + <parameter type-id='type-id-365' name='frame' filepath='Objects/frameobject.c' line='1513' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyFrame_GetLasti' mangled-name='PyFrame_GetLasti' filepath='Objects/frameobject.c' line='1520' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFrame_GetLasti'> + <parameter type-id='type-id-365' name='frame' filepath='Objects/frameobject.c' line='1520' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyFrame_GetGenerator' mangled-name='PyFrame_GetGenerator' filepath='Objects/frameobject.c' line='1531' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFrame_GetGenerator'> + <parameter type-id='type-id-365' name='frame' filepath='Objects/frameobject.c' line='1531' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Objects/funcobject.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <var-decl name='PyFunction_Type' type-id='type-id-256' mangled-name='PyFunction_Type' visibility='default' filepath='./Include/cpython/funcobject.h' line='63' column='1' elf-symbol-id='PyFunction_Type'/> + <var-decl name='PyClassMethod_Type' type-id='type-id-256' mangled-name='PyClassMethod_Type' visibility='default' filepath='./Include/cpython/funcobject.h' line='129' column='1' elf-symbol-id='PyClassMethod_Type'/> + <var-decl name='PyStaticMethod_Type' type-id='type-id-256' mangled-name='PyStaticMethod_Type' visibility='default' filepath='./Include/cpython/funcobject.h' line='130' column='1' elf-symbol-id='PyStaticMethod_Type'/> + <function-decl name='_PyEval_BuiltinsFromGlobals' filepath='./Include/internal/pycore_ceval.h' line='57' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-177'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyFunction_AddWatcher' mangled-name='PyFunction_AddWatcher' filepath='Objects/funcobject.c' line='73' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFunction_AddWatcher'> + <parameter type-id='type-id-366' name='callback' filepath='Objects/funcobject.c' line='73' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyFunction_ClearWatcher' mangled-name='PyFunction_ClearWatcher' filepath='Objects/funcobject.c' line='89' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFunction_ClearWatcher'> + <parameter type-id='type-id-8' name='watcher_id' filepath='Objects/funcobject.c' line='89' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyFunction_NewWithQualName' mangled-name='PyFunction_NewWithQualName' filepath='Objects/funcobject.c' line='141' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFunction_NewWithQualName'> + <parameter type-id='type-id-2' name='code' filepath='Objects/funcobject.c' line='141' column='1'/> + <parameter type-id='type-id-2' name='globals' filepath='Objects/funcobject.c' line='141' column='1'/> + <parameter type-id='type-id-2' name='qualname' filepath='Objects/funcobject.c' line='141' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyFunction_New' mangled-name='PyFunction_New' filepath='Objects/funcobject.c' line='244' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFunction_New'> + <parameter type-id='type-id-2' name='code' filepath='Objects/funcobject.c' line='244' column='1'/> + <parameter type-id='type-id-2' name='globals' filepath='Objects/funcobject.c' line='244' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyFunction_GetCode' mangled-name='PyFunction_GetCode' filepath='Objects/funcobject.c' line='250' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFunction_GetCode'> + <parameter type-id='type-id-2' name='op' filepath='Objects/funcobject.c' line='250' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyFunction_GetGlobals' mangled-name='PyFunction_GetGlobals' filepath='Objects/funcobject.c' line='260' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFunction_GetGlobals'> + <parameter type-id='type-id-2' name='op' filepath='Objects/funcobject.c' line='260' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyFunction_GetModule' mangled-name='PyFunction_GetModule' filepath='Objects/funcobject.c' line='270' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFunction_GetModule'> + <parameter type-id='type-id-2' name='op' filepath='Objects/funcobject.c' line='270' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyFunction_GetDefaults' mangled-name='PyFunction_GetDefaults' filepath='Objects/funcobject.c' line='280' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFunction_GetDefaults'> + <parameter type-id='type-id-2' name='op' filepath='Objects/funcobject.c' line='280' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyFunction_SetDefaults' mangled-name='PyFunction_SetDefaults' filepath='Objects/funcobject.c' line='290' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFunction_SetDefaults'> + <parameter type-id='type-id-2' name='op' filepath='Objects/funcobject.c' line='290' column='1'/> + <parameter type-id='type-id-2' name='defaults' filepath='Objects/funcobject.c' line='290' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyFunction_SetVectorcall' mangled-name='PyFunction_SetVectorcall' filepath='Objects/funcobject.c' line='313' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFunction_SetVectorcall'> + <parameter type-id='type-id-310' name='func' filepath='Objects/funcobject.c' line='313' column='1'/> + <parameter type-id='type-id-311' name='vectorcall' filepath='Objects/funcobject.c' line='313' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyFunction_GetKwDefaults' mangled-name='PyFunction_GetKwDefaults' filepath='Objects/funcobject.c' line='321' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFunction_GetKwDefaults'> + <parameter type-id='type-id-2' name='op' filepath='Objects/funcobject.c' line='321' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyFunction_SetKwDefaults' mangled-name='PyFunction_SetKwDefaults' filepath='Objects/funcobject.c' line='331' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFunction_SetKwDefaults'> + <parameter type-id='type-id-2' name='op' filepath='Objects/funcobject.c' line='331' column='1'/> + <parameter type-id='type-id-2' name='defaults' filepath='Objects/funcobject.c' line='331' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyFunction_GetClosure' mangled-name='PyFunction_GetClosure' filepath='Objects/funcobject.c' line='355' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFunction_GetClosure'> + <parameter type-id='type-id-2' name='op' filepath='Objects/funcobject.c' line='355' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyFunction_SetClosure' mangled-name='PyFunction_SetClosure' filepath='Objects/funcobject.c' line='365' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFunction_SetClosure'> + <parameter type-id='type-id-2' name='op' filepath='Objects/funcobject.c' line='365' column='1'/> + <parameter type-id='type-id-2' name='closure' filepath='Objects/funcobject.c' line='365' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyFunction_GetAnnotations' mangled-name='PyFunction_GetAnnotations' filepath='Objects/funcobject.c' line='418' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFunction_GetAnnotations'> + <parameter type-id='type-id-2' name='op' filepath='Objects/funcobject.c' line='418' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyFunction_SetAnnotations' mangled-name='PyFunction_SetAnnotations' filepath='Objects/funcobject.c' line='428' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFunction_SetAnnotations'> + <parameter type-id='type-id-2' name='op' filepath='Objects/funcobject.c' line='428' column='1'/> + <parameter type-id='type-id-2' name='annotations' filepath='Objects/funcobject.c' line='428' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyClassMethod_New' mangled-name='PyClassMethod_New' filepath='Objects/funcobject.c' line='1167' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyClassMethod_New'> + <parameter type-id='type-id-2' name='callable' filepath='Objects/funcobject.c' line='1167' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyStaticMethod_New' mangled-name='PyStaticMethod_New' filepath='Objects/funcobject.c' line='1360' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyStaticMethod_New'> + <parameter type-id='type-id-2' name='callable' filepath='Objects/funcobject.c' line='1360' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Objects/genericaliasobject.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <function-decl name='_PyUnicodeWriter_WriteASCIIString' mangled-name='_PyUnicodeWriter_WriteASCIIString' filepath='./Include/cpython/unicodeobject.h' line='577' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicodeWriter_WriteASCIIString'> + <parameter type-id='type-id-332'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-14'/> + <return type-id='type-id-8'/> + </function-decl> + <var-decl name='Py_GenericAliasType' type-id='type-id-256' mangled-name='Py_GenericAliasType' visibility='default' filepath='./Include/genericaliasobject.h' line='9' column='1' elf-symbol-id='Py_GenericAliasType'/> + <function-decl name='_Py_union_type_or' filepath='./Include/internal/pycore_unionobject.h' line='13' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyList_SetSlice' mangled-name='PyList_SetSlice' filepath='./Include/listobject.h' line='37' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyList_SetSlice'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-14'/> + <parameter type-id='type-id-14'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyObject_Dir' mangled-name='PyObject_Dir' filepath='./Include/object.h' line='432' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_Dir'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyObject_GC_Track' mangled-name='PyObject_GC_Track' filepath='./Include/objimpl.h' line='194' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_GC_Track'> + <parameter type-id='type-id-22'/> + <return type-id='type-id-46'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Objects/genobject.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <class-decl name='PyGenObject' size-in-bits='640' is-struct='yes' naming-typedef-id='type-id-367' visibility='default' filepath='./Include/cpython/genobject.h' line='31' column='1' id='type-id-368'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='ob_base' type-id='type-id-345' visibility='default' filepath='./Include/cpython/genobject.h' line='33' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='gi_weakreflist' type-id='type-id-2' visibility='default' filepath='./Include/cpython/genobject.h' line='33' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='gi_name' type-id='type-id-2' visibility='default' filepath='./Include/cpython/genobject.h' line='33' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='gi_qualname' type-id='type-id-2' visibility='default' filepath='./Include/cpython/genobject.h' line='33' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='gi_exc_state' type-id='type-id-369' visibility='default' filepath='./Include/cpython/genobject.h' line='33' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='448'> + <var-decl name='gi_origin_or_finalizer' type-id='type-id-2' visibility='default' filepath='./Include/cpython/genobject.h' line='33' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='512'> + <var-decl name='gi_hooks_inited' type-id='type-id-48' visibility='default' filepath='./Include/cpython/genobject.h' line='33' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='520'> + <var-decl name='gi_closed' type-id='type-id-48' visibility='default' filepath='./Include/cpython/genobject.h' line='33' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='528'> + <var-decl name='gi_running_async' type-id='type-id-48' visibility='default' filepath='./Include/cpython/genobject.h' line='33' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='536'> + <var-decl name='gi_frame_state' type-id='type-id-370' visibility='default' filepath='./Include/cpython/genobject.h' line='33' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='576'> + <var-decl name='gi_iframe' type-id='type-id-353' visibility='default' filepath='./Include/cpython/genobject.h' line='33' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='PyGenObject' type-id='type-id-368' filepath='./Include/cpython/genobject.h' line='34' column='1' id='type-id-367'/> + <typedef-decl name='_PyInterpreterFrame' type-id='type-id-371' filepath='./Include/internal/pycore_frame.h' line='73' column='1' id='type-id-372'/> + <pointer-type-def type-id='type-id-367' size-in-bits='64' id='type-id-373'/> + <pointer-type-def type-id='type-id-372' size-in-bits='64' id='type-id-374'/> + <function-decl name='_PyEval_EvalFrameDefault' mangled-name='_PyEval_EvalFrameDefault' filepath='./Include/cpython/ceval.h' line='20' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyEval_EvalFrameDefault'> + <parameter type-id='type-id-177'/> + <parameter type-id='type-id-375'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-2'/> + </function-decl> + <var-decl name='PyGen_Type' type-id='type-id-256' mangled-name='PyGen_Type' visibility='default' filepath='./Include/cpython/genobject.h' line='36' column='1' elf-symbol-id='PyGen_Type'/> + <var-decl name='PyCoro_Type' type-id='type-id-256' mangled-name='PyCoro_Type' visibility='default' filepath='./Include/cpython/genobject.h' line='56' column='1' elf-symbol-id='PyCoro_Type'/> + <var-decl name='_PyCoroWrapper_Type' type-id='type-id-256' mangled-name='_PyCoroWrapper_Type' visibility='default' filepath='./Include/cpython/genobject.h' line='57' column='1' elf-symbol-id='_PyCoroWrapper_Type'/> + <var-decl name='PyAsyncGen_Type' type-id='type-id-256' mangled-name='PyAsyncGen_Type' visibility='default' filepath='./Include/cpython/genobject.h' line='70' column='1' elf-symbol-id='PyAsyncGen_Type'/> + <var-decl name='_PyAsyncGenASend_Type' type-id='type-id-256' mangled-name='_PyAsyncGenASend_Type' visibility='default' filepath='./Include/cpython/genobject.h' line='71' column='1' elf-symbol-id='_PyAsyncGenASend_Type'/> + <var-decl name='_PyAsyncGenWrappedValue_Type' type-id='type-id-256' mangled-name='_PyAsyncGenWrappedValue_Type' visibility='default' filepath='./Include/cpython/genobject.h' line='72' column='1' elf-symbol-id='_PyAsyncGenWrappedValue_Type'/> + <var-decl name='_PyAsyncGenAThrow_Type' type-id='type-id-256' mangled-name='_PyAsyncGenAThrow_Type' visibility='default' filepath='./Include/cpython/genobject.h' line='73' column='1' elf-symbol-id='_PyAsyncGenAThrow_Type'/> + <function-decl name='PyObject_CallFinalizerFromDealloc' mangled-name='PyObject_CallFinalizerFromDealloc' filepath='./Include/cpython/object.h' line='313' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_CallFinalizerFromDealloc'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyUnstable_InterpreterFrame_GetLine' mangled-name='PyUnstable_InterpreterFrame_GetLine' filepath='./Include/cpython/pyframe.h' line='35' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnstable_InterpreterFrame_GetLine'> + <parameter type-id='type-id-375'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyEval_GetFrame' filepath='./Include/internal/pycore_ceval.h' line='151' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-375'/> + </function-decl> + <function-decl name='_PyFrame_Copy' filepath='./Include/internal/pycore_frame.h' line='110' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-374'/> + <parameter type-id='type-id-374'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyFrame_MakeAndSetFrameObject' filepath='./Include/internal/pycore_frame.h' line='197' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-374'/> + <return type-id='type-id-365'/> + </function-decl> + <function-decl name='_PyFrame_ClearExceptCode' filepath='./Include/internal/pycore_frame.h' line='224' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-374'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyFrame_Traverse' filepath='./Include/internal/pycore_frame.h' line='227' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-374'/> + <parameter type-id='type-id-341'/> + <parameter type-id='type-id-22'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyErr_ChainStackItem' mangled-name='_PyErr_ChainStackItem' filepath='./Include/internal/pycore_pyerrors.h' line='64' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyErr_ChainStackItem'> + <parameter type-id='type-id-376'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyErr_WarnUnawaitedCoroutine' filepath='./Include/internal/pycore_warnings.h' line='24' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyObject_GC_NewVar' mangled-name='_PyObject_GC_NewVar' filepath='./Include/objimpl.h' line='189' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_GC_NewVar'> + <parameter type-id='type-id-1'/> + <parameter type-id='type-id-14'/> + <return type-id='type-id-322'/> + </function-decl> + <function-decl name='PyErr_SetRaisedException' mangled-name='PyErr_SetRaisedException' filepath='./Include/pyerrors.h' line='22' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_SetRaisedException'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyErr_NormalizeException' mangled-name='PyErr_NormalizeException' filepath='./Include/pyerrors.h' line='42' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_NormalizeException'> + <parameter type-id='type-id-233'/> + <parameter type-id='type-id-233'/> + <parameter type-id='type-id-233'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyGen_GetCode' mangled-name='PyGen_GetCode' filepath='Objects/genobject.c' line='36' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyGen_GetCode'> + <parameter type-id='type-id-373' name='gen' filepath='Objects/genobject.c' line='36' column='1'/> + <return type-id='type-id-328'/> + </function-decl> + <function-decl name='_PyGen_Finalize' mangled-name='_PyGen_Finalize' filepath='Objects/genobject.c' line='70' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyGen_Finalize'> + <parameter type-id='type-id-2' name='self' filepath='Objects/genobject.c' line='70' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyGen_SetStopIterationValue' mangled-name='_PyGen_SetStopIterationValue' filepath='Objects/genobject.c' line='619' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyGen_SetStopIterationValue'> + <parameter type-id='type-id-2' name='value' filepath='Objects/genobject.c' line='619' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyGen_NewWithQualName' mangled-name='PyGen_NewWithQualName' filepath='Objects/genobject.c' line='989' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyGen_NewWithQualName'> + <parameter type-id='type-id-365' name='f' filepath='Objects/genobject.c' line='989' column='1'/> + <parameter type-id='type-id-2' name='name' filepath='Objects/genobject.c' line='989' column='1'/> + <parameter type-id='type-id-2' name='qualname' filepath='Objects/genobject.c' line='989' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyGen_New' mangled-name='PyGen_New' filepath='Objects/genobject.c' line='995' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyGen_New'> + <parameter type-id='type-id-365' name='f' filepath='Objects/genobject.c' line='995' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyCoro_New' mangled-name='PyCoro_New' filepath='Objects/genobject.c' line='1353' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCoro_New'> + <parameter type-id='type-id-365' name='f' filepath='Objects/genobject.c' line='1353' column='1'/> + <parameter type-id='type-id-2' name='name' filepath='Objects/genobject.c' line='1353' column='1'/> + <parameter type-id='type-id-2' name='qualname' filepath='Objects/genobject.c' line='1353' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyAsyncGen_New' mangled-name='PyAsyncGen_New' filepath='Objects/genobject.c' line='1659' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyAsyncGen_New'> + <parameter type-id='type-id-365' name='f' filepath='Objects/genobject.c' line='1659' column='1'/> + <parameter type-id='type-id-2' name='name' filepath='Objects/genobject.c' line='1659' column='1'/> + <parameter type-id='type-id-2' name='qualname' filepath='Objects/genobject.c' line='1659' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Objects/interpreteridobject.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <var-decl name='_PyInterpreterID_Type' type-id='type-id-256' mangled-name='_PyInterpreterID_Type' visibility='default' filepath='./Include/cpython/interpreteridobject.h' line='7' column='1' elf-symbol-id='_PyInterpreterID_Type'/> + <function-decl name='_PyInterpreterState_LookUpID' mangled-name='_PyInterpreterState_LookUpID' filepath='./Include/internal/pycore_interp.h' line='233' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyInterpreterState_LookUpID'> + <parameter type-id='type-id-377'/> + <return type-id='type-id-20'/> + </function-decl> + <function-decl name='_PyInterpreterState_IDInitref' mangled-name='_PyInterpreterState_IDInitref' filepath='./Include/internal/pycore_interp.h' line='235' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyInterpreterState_IDInitref'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyInterpreterState_IDIncref' mangled-name='_PyInterpreterState_IDIncref' filepath='./Include/internal/pycore_interp.h' line='236' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyInterpreterState_IDIncref'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyInterpreterState_IDDecref' mangled-name='_PyInterpreterState_IDDecref' filepath='./Include/internal/pycore_interp.h' line='237' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyInterpreterState_IDDecref'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyLong_FromLongLong' mangled-name='PyLong_FromLongLong' filepath='./Include/longobject.h' line='67' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyLong_FromLongLong'> + <parameter type-id='type-id-378'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyLong_AsLongLong' mangled-name='PyLong_AsLongLong' filepath='./Include/longobject.h' line='69' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyLong_AsLongLong'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-378'/> + </function-decl> + <function-decl name='PyLong_AsLongLongAndOverflow' mangled-name='PyLong_AsLongLongAndOverflow' filepath='./Include/longobject.h' line='72' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyLong_AsLongLongAndOverflow'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-179'/> + <return type-id='type-id-378'/> + </function-decl> + <function-decl name='PyArg_ParseTupleAndKeywords' mangled-name='PyArg_ParseTupleAndKeywords' filepath='./Include/modsupport.h' line='28' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyArg_ParseTupleAndKeywords'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-239'/> + <parameter is-variadic='yes'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyInterpreterState_GetID' mangled-name='PyInterpreterState_GetID' filepath='./Include/pystate.h' line='36' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInterpreterState_GetID'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-377'/> + </function-decl> + <function-decl name='_PyInterpreterID_New' mangled-name='_PyInterpreterID_New' filepath='Objects/interpreteridobject.c' line='268' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyInterpreterID_New'> + <parameter type-id='type-id-377' name='id' filepath='Objects/interpreteridobject.c' line='268' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyInterpreterState_GetIDObject' mangled-name='_PyInterpreterState_GetIDObject' filepath='Objects/interpreteridobject.c' line='274' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyInterpreterState_GetIDObject'> + <parameter type-id='type-id-20' name='interp' filepath='Objects/interpreteridobject.c' line='274' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyInterpreterID_LookUp' mangled-name='_PyInterpreterID_LookUp' filepath='Objects/interpreteridobject.c' line='287' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyInterpreterID_LookUp'> + <parameter type-id='type-id-2' name='requested_id' filepath='Objects/interpreteridobject.c' line='287' column='1'/> + <return type-id='type-id-20'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Objects/iterobject.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <function-decl name='_PyCoro_GetAwaitableIter' filepath='./Include/internal/pycore_genobject.h' line='12' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <var-decl name='PySeqIter_Type' type-id='type-id-256' mangled-name='PySeqIter_Type' visibility='default' filepath='./Include/iterobject.h' line='8' column='1' elf-symbol-id='PySeqIter_Type'/> + <var-decl name='PyCallIter_Type' type-id='type-id-256' mangled-name='PyCallIter_Type' visibility='default' filepath='./Include/iterobject.h' line='9' column='1' elf-symbol-id='PyCallIter_Type'/> + <var-decl name='_PyAnextAwaitable_Type' type-id='type-id-256' visibility='default' filepath='./Include/iterobject.h' line='11' column='1'/> + <function-decl name='PyCallIter_New' mangled-name='PyCallIter_New' filepath='Objects/iterobject.c' line='184' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCallIter_New'> + <parameter type-id='type-id-2' name='callable' filepath='Objects/iterobject.c' line='184' column='1'/> + <parameter type-id='type-id-2' name='sentinel' filepath='Objects/iterobject.c' line='184' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Objects/listobject.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <function-decl name='_PyEval_SliceIndexNotNone' mangled-name='_PyEval_SliceIndexNotNone' filepath='./Include/cpython/ceval.h' line='35' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyEval_SliceIndexNotNone'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-13'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyUnicodeWriter_WriteChar' mangled-name='_PyUnicodeWriter_WriteChar' filepath='./Include/cpython/unicodeobject.h' line='554' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicodeWriter_WriteChar'> + <parameter type-id='type-id-332'/> + <parameter type-id='type-id-250'/> + <return type-id='type-id-8'/> + </function-decl> + <var-decl name='PyList_Type' type-id='type-id-256' mangled-name='PyList_Type' visibility='default' filepath='./Include/listobject.h' line='20' column='1' elf-symbol-id='PyList_Type'/> + <var-decl name='PyListIter_Type' type-id='type-id-256' mangled-name='PyListIter_Type' visibility='default' filepath='./Include/listobject.h' line='21' column='1' elf-symbol-id='PyListIter_Type'/> + <var-decl name='PyListRevIter_Type' type-id='type-id-256' mangled-name='PyListRevIter_Type' visibility='default' filepath='./Include/listobject.h' line='22' column='1' elf-symbol-id='PyListRevIter_Type'/> + <function-decl name='PyObject_HashNotImplemented' mangled-name='PyObject_HashNotImplemented' filepath='./Include/object.h' line='421' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_HashNotImplemented'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-305'/> + </function-decl> + <function-decl name='Py_ReprEnter' mangled-name='Py_ReprEnter' filepath='./Include/object.h' line='441' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_ReprEnter'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='Py_ReprLeave' mangled-name='Py_ReprLeave' filepath='./Include/object.h' line='442' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_ReprLeave'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyList_DebugMallocStats' mangled-name='_PyList_DebugMallocStats' filepath='Objects/listobject.c' line='145' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyList_DebugMallocStats'> + <parameter type-id='type-id-229' name='out' filepath='Objects/listobject.c' line='145' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyList_Size' mangled-name='PyList_Size' filepath='Objects/listobject.c' line='220' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyList_Size'> + <parameter type-id='type-id-2' name='op' filepath='Objects/listobject.c' line='220' column='1'/> + <return type-id='type-id-14'/> + </function-decl> + <function-decl name='PyList_SetItem' mangled-name='PyList_SetItem' filepath='Objects/listobject.c' line='259' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyList_SetItem'> + <parameter type-id='type-id-2' name='op' filepath='Objects/listobject.c' line='259' column='1'/> + <parameter type-id='type-id-14' name='i' filepath='Objects/listobject.c' line='259' column='1'/> + <parameter type-id='type-id-2' name='newitem' filepath='Objects/listobject.c' line='260' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyList_Insert' mangled-name='PyList_Insert' filepath='Objects/listobject.c' line='308' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyList_Insert'> + <parameter type-id='type-id-2' name='op' filepath='Objects/listobject.c' line='308' column='1'/> + <parameter type-id='type-id-14' name='where' filepath='Objects/listobject.c' line='308' column='1'/> + <parameter type-id='type-id-2' name='newitem' filepath='Objects/listobject.c' line='308' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyList_GetSlice' mangled-name='PyList_GetSlice' filepath='Objects/listobject.c' line='491' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyList_GetSlice'> + <parameter type-id='type-id-2' name='a' filepath='Objects/listobject.c' line='491' column='1'/> + <parameter type-id='type-id-14' name='ilow' filepath='Objects/listobject.c' line='491' column='1'/> + <parameter type-id='type-id-14' name='ihigh' filepath='Objects/listobject.c' line='491' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyList_Sort' mangled-name='PyList_Sort' filepath='Objects/listobject.c' line='2514' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyList_Sort'> + <parameter type-id='type-id-2' name='v' filepath='Objects/listobject.c' line='2514' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Objects/longobject.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <array-type-def dimensions='1' type-id='type-id-85' size-in-bits='2048' id='type-id-379'> + <subrange length='256' type-id='type-id-28' id='type-id-62'/> + </array-type-def> + <qualified-type-def type-id='type-id-240' const='yes' id='type-id-380'/> + <pointer-type-def type-id='type-id-380' size-in-bits='64' id='type-id-381'/> + <qualified-type-def type-id='type-id-85' const='yes' id='type-id-382'/> + <pointer-type-def type-id='type-id-382' size-in-bits='64' id='type-id-383'/> + <pointer-type-def type-id='type-id-384' size-in-bits='64' id='type-id-385'/> + <pointer-type-def type-id='type-id-85' size-in-bits='64' id='type-id-386'/> + <function-decl name='_PyUnicodeWriter_PrepareInternal' mangled-name='_PyUnicodeWriter_PrepareInternal' filepath='./Include/cpython/unicodeobject.h' line='532' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicodeWriter_PrepareInternal'> + <parameter type-id='type-id-332'/> + <parameter type-id='type-id-14'/> + <parameter type-id='type-id-250'/> + <return type-id='type-id-8'/> + </function-decl> + <var-decl name='_PyLong_DigitValue' type-id='type-id-379' mangled-name='_PyLong_DigitValue' visibility='default' filepath='./Include/internal/pycore_long.h' line='87' column='1' elf-symbol-id='_PyLong_DigitValue'/> + <function-decl name='_PyLong_FormatAdvancedWriter' mangled-name='_PyLong_FormatAdvancedWriter' filepath='./Include/internal/pycore_long.h' line='91' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyLong_FormatAdvancedWriter'> + <parameter type-id='type-id-332'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-14'/> + <parameter type-id='type-id-14'/> + <return type-id='type-id-8'/> + </function-decl> + <var-decl name='PyLong_Type' type-id='type-id-256' mangled-name='PyLong_Type' visibility='default' filepath='./Include/object.h' line='226' column='1' elf-symbol-id='PyLong_Type'/> + <function-decl name='PyObject_Bytes' mangled-name='PyObject_Bytes' filepath='./Include/object.h' line='405' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_Bytes'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyLong_New' mangled-name='_PyLong_New' filepath='Objects/longobject.c' line='141' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyLong_New'> + <parameter type-id='type-id-14' name='size' filepath='Objects/longobject.c' line='141' column='1'/> + <return type-id='type-id-241'/> + </function-decl> + <function-decl name='_PyLong_FromDigits' mangled-name='_PyLong_FromDigits' filepath='Objects/longobject.c' line='173' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyLong_FromDigits'> + <parameter type-id='type-id-8' name='negative' filepath='Objects/longobject.c' line='173' column='1'/> + <parameter type-id='type-id-14' name='digit_count' filepath='Objects/longobject.c' line='173' column='1'/> + <parameter type-id='type-id-385' name='digits' filepath='Objects/longobject.c' line='173' column='1'/> + <return type-id='type-id-241'/> + </function-decl> + <function-decl name='PyLong_FromUnsignedLong' mangled-name='PyLong_FromUnsignedLong' filepath='Objects/longobject.c' line='360' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyLong_FromUnsignedLong'> + <parameter type-id='type-id-28' name='ival' filepath='Objects/longobject.c' line='360' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyLong_FromUnsignedLongLong' mangled-name='PyLong_FromUnsignedLongLong' filepath='Objects/longobject.c' line='368' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyLong_FromUnsignedLongLong'> + <parameter type-id='type-id-387' name='ival' filepath='Objects/longobject.c' line='368' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyLong_AsLong' mangled-name='PyLong_AsLong' filepath='Objects/longobject.c' line='535' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyLong_AsLong'> + <parameter type-id='type-id-2' name='obj' filepath='Objects/longobject.c' line='535' column='1'/> + <return type-id='type-id-47'/> + </function-decl> + <function-decl name='PyLong_AsUnsignedLong' mangled-name='PyLong_AsUnsignedLong' filepath='Objects/longobject.c' line='619' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyLong_AsUnsignedLong'> + <parameter type-id='type-id-2' name='vv' filepath='Objects/longobject.c' line='619' column='1'/> + <return type-id='type-id-28'/> + </function-decl> + <function-decl name='PyLong_AsSize_t' mangled-name='PyLong_AsSize_t' filepath='Objects/longobject.c' line='672' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyLong_AsSize_t'> + <parameter type-id='type-id-2' name='vv' filepath='Objects/longobject.c' line='672' column='1'/> + <return type-id='type-id-19'/> + </function-decl> + <function-decl name='PyLong_AsUnsignedLongMask' mangled-name='PyLong_AsUnsignedLongMask' filepath='Objects/longobject.c' line='738' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyLong_AsUnsignedLongMask'> + <parameter type-id='type-id-2' name='op' filepath='Objects/longobject.c' line='738' column='1'/> + <return type-id='type-id-28'/> + </function-decl> + <function-decl name='_PyLong_FromByteArray' mangled-name='_PyLong_FromByteArray' filepath='Objects/longobject.c' line='815' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyLong_FromByteArray'> + <parameter type-id='type-id-383' name='bytes' filepath='Objects/longobject.c' line='815' column='1'/> + <parameter type-id='type-id-19' name='n' filepath='Objects/longobject.c' line='815' column='1'/> + <parameter type-id='type-id-8' name='little_endian' filepath='Objects/longobject.c' line='816' column='1'/> + <parameter type-id='type-id-8' name='is_signed' filepath='Objects/longobject.c' line='816' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyLong_AsByteArray' mangled-name='_PyLong_AsByteArray' filepath='Objects/longobject.c' line='930' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyLong_AsByteArray'> + <parameter type-id='type-id-241' name='v' filepath='Objects/longobject.c' line='930' column='1'/> + <parameter type-id='type-id-386' name='bytes' filepath='Objects/longobject.c' line='931' column='1'/> + <parameter type-id='type-id-19' name='n' filepath='Objects/longobject.c' line='931' column='1'/> + <parameter type-id='type-id-8' name='little_endian' filepath='Objects/longobject.c' line='932' column='1'/> + <parameter type-id='type-id-8' name='is_signed' filepath='Objects/longobject.c' line='932' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyLong_AsVoidPtr' mangled-name='PyLong_AsVoidPtr' filepath='Objects/longobject.c' line='1081' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyLong_AsVoidPtr'> + <parameter type-id='type-id-2' name='vv' filepath='Objects/longobject.c' line='1081' column='1'/> + <return type-id='type-id-22'/> + </function-decl> + <function-decl name='PyLong_AsUnsignedLongLong' mangled-name='PyLong_AsUnsignedLongLong' filepath='Objects/longobject.c' line='1252' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyLong_AsUnsignedLongLong'> + <parameter type-id='type-id-2' name='vv' filepath='Objects/longobject.c' line='1252' column='1'/> + <return type-id='type-id-387'/> + </function-decl> + <function-decl name='PyLong_AsUnsignedLongLongMask' mangled-name='PyLong_AsUnsignedLongLongMask' filepath='Objects/longobject.c' line='1313' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyLong_AsUnsignedLongLongMask'> + <parameter type-id='type-id-2' name='op' filepath='Objects/longobject.c' line='1313' column='1'/> + <return type-id='type-id-387'/> + </function-decl> + <function-decl name='_PyLong_UnsignedShort_Converter' mangled-name='_PyLong_UnsignedShort_Converter' filepath='Objects/longobject.c' line='1410' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyLong_UnsignedShort_Converter'> + <parameter type-id='type-id-2' name='obj' filepath='Objects/longobject.c' line='1410' column='1'/> + <parameter type-id='type-id-22' name='ptr' filepath='Objects/longobject.c' line='1410' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyLong_UnsignedInt_Converter' mangled-name='_PyLong_UnsignedInt_Converter' filepath='Objects/longobject.c' line='1432' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyLong_UnsignedInt_Converter'> + <parameter type-id='type-id-2' name='obj' filepath='Objects/longobject.c' line='1432' column='1'/> + <parameter type-id='type-id-22' name='ptr' filepath='Objects/longobject.c' line='1432' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyLong_UnsignedLong_Converter' mangled-name='_PyLong_UnsignedLong_Converter' filepath='Objects/longobject.c' line='1454' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyLong_UnsignedLong_Converter'> + <parameter type-id='type-id-2' name='obj' filepath='Objects/longobject.c' line='1454' column='1'/> + <parameter type-id='type-id-22' name='ptr' filepath='Objects/longobject.c' line='1454' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyLong_UnsignedLongLong_Converter' mangled-name='_PyLong_UnsignedLongLong_Converter' filepath='Objects/longobject.c' line='1471' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyLong_UnsignedLongLong_Converter'> + <parameter type-id='type-id-2' name='obj' filepath='Objects/longobject.c' line='1471' column='1'/> + <parameter type-id='type-id-22' name='ptr' filepath='Objects/longobject.c' line='1471' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyLong_Size_t_Converter' mangled-name='_PyLong_Size_t_Converter' filepath='Objects/longobject.c' line='1488' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyLong_Size_t_Converter'> + <parameter type-id='type-id-2' name='obj' filepath='Objects/longobject.c' line='1488' column='1'/> + <parameter type-id='type-id-22' name='ptr' filepath='Objects/longobject.c' line='1488' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyLong_FormatWriter' mangled-name='_PyLong_FormatWriter' filepath='Objects/longobject.c' line='2166' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyLong_FormatWriter'> + <parameter type-id='type-id-332' name='writer' filepath='Objects/longobject.c' line='2166' column='1'/> + <parameter type-id='type-id-2' name='obj' filepath='Objects/longobject.c' line='2167' column='1'/> + <parameter type-id='type-id-8' name='base' filepath='Objects/longobject.c' line='2168' column='1'/> + <parameter type-id='type-id-8' name='alternate' filepath='Objects/longobject.c' line='2168' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyLong_Frexp' mangled-name='_PyLong_Frexp' filepath='Objects/longobject.c' line='3095' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyLong_Frexp'> + <parameter type-id='type-id-241' name='a' filepath='Objects/longobject.c' line='3095' column='1'/> + <parameter type-id='type-id-13' name='e' filepath='Objects/longobject.c' line='3095' column='1'/> + <return type-id='type-id-251'/> + </function-decl> + <function-decl name='_PyLong_Rshift' mangled-name='_PyLong_Rshift' filepath='Objects/longobject.c' line='5042' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyLong_Rshift'> + <parameter type-id='type-id-2' name='a' filepath='Objects/longobject.c' line='5042' column='1'/> + <parameter type-id='type-id-19' name='shiftby' filepath='Objects/longobject.c' line='5042' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyLong_GCD' mangled-name='_PyLong_GCD' filepath='Objects/longobject.c' line='5321' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyLong_GCD'> + <parameter type-id='type-id-2' name='aarg' filepath='Objects/longobject.c' line='5321' column='1'/> + <parameter type-id='type-id-2' name='barg' filepath='Objects/longobject.c' line='5321' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyLong_DivmodNear' mangled-name='_PyLong_DivmodNear' filepath='Objects/longobject.c' line='5687' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyLong_DivmodNear'> + <parameter type-id='type-id-2' name='a' filepath='Objects/longobject.c' line='5687' column='1'/> + <parameter type-id='type-id-2' name='b' filepath='Objects/longobject.c' line='5687' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyLong_GetInfo' mangled-name='PyLong_GetInfo' filepath='Objects/longobject.c' line='6321' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyLong_GetInfo'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyUnstable_Long_IsCompact' mangled-name='PyUnstable_Long_IsCompact' filepath='Objects/longobject.c' line='6376' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnstable_Long_IsCompact'> + <parameter type-id='type-id-381' name='op' filepath='Objects/longobject.c' line='6376' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyUnstable_Long_CompactValue' mangled-name='PyUnstable_Long_CompactValue' filepath='Objects/longobject.c' line='6383' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnstable_Long_CompactValue'> + <parameter type-id='type-id-381' name='op' filepath='Objects/longobject.c' line='6383' column='1'/> + <return type-id='type-id-14'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Objects/memoryobject.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <var-decl name='_PyManagedBuffer_Type' type-id='type-id-256' mangled-name='_PyManagedBuffer_Type' visibility='default' filepath='./Include/cpython/memoryobject.h' line='5' column='1' elf-symbol-id='_PyManagedBuffer_Type'/> + <var-decl name='PyMemoryView_Type' type-id='type-id-256' mangled-name='PyMemoryView_Type' visibility='default' filepath='./Include/memoryobject.h' line='9' column='1' elf-symbol-id='PyMemoryView_Type'/> + <function-decl name='PyUnicode_AsASCIIString' mangled-name='PyUnicode_AsASCIIString' filepath='./Include/unicodeobject.h' line='639' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_AsASCIIString'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyMemoryView_FromMemory' mangled-name='PyMemoryView_FromMemory' filepath='Objects/memoryobject.c' line='739' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMemoryView_FromMemory'> + <parameter type-id='type-id-15' name='mem' filepath='Objects/memoryobject.c' line='739' column='1'/> + <parameter type-id='type-id-14' name='size' filepath='Objects/memoryobject.c' line='739' column='1'/> + <parameter type-id='type-id-8' name='flags' filepath='Objects/memoryobject.c' line='739' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyMemoryView_FromBuffer' mangled-name='PyMemoryView_FromBuffer' filepath='Objects/memoryobject.c' line='768' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMemoryView_FromBuffer'> + <parameter type-id='type-id-245' name='info' filepath='Objects/memoryobject.c' line='768' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyMemoryView_FromObject' mangled-name='PyMemoryView_FromObject' filepath='Objects/memoryobject.c' line='852' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMemoryView_FromObject'> + <parameter type-id='type-id-2' name='v' filepath='Objects/memoryobject.c' line='852' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyMemoryView_GetContiguous' mangled-name='PyMemoryView_GetContiguous' filepath='Objects/memoryobject.c' line='964' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMemoryView_GetContiguous'> + <parameter type-id='type-id-2' name='obj' filepath='Objects/memoryobject.c' line='964' column='1'/> + <parameter type-id='type-id-8' name='buffertype' filepath='Objects/memoryobject.c' line='964' column='1'/> + <parameter type-id='type-id-48' name='order' filepath='Objects/memoryobject.c' line='964' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Objects/methodobject.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <var-decl name='PyCMethod_Type' type-id='type-id-256' mangled-name='PyCMethod_Type' visibility='default' filepath='./Include/cpython/methodobject.h' line='32' column='1' elf-symbol-id='PyCMethod_Type'/> + <var-decl name='PyCFunction_Type' type-id='type-id-256' mangled-name='PyCFunction_Type' visibility='default' filepath='./Include/methodobject.h' line='14' column='1' elf-symbol-id='PyCFunction_Type'/> + <function-decl name='PyCFunction_New' mangled-name='PyCFunction_New' filepath='Objects/methodobject.c' line='32' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCFunction_New'> + <parameter type-id='type-id-337' name='ml' filepath='Objects/methodobject.c' line='32' column='1'/> + <parameter type-id='type-id-2' name='self' filepath='Objects/methodobject.c' line='32' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyCFunction_NewEx' mangled-name='PyCFunction_NewEx' filepath='Objects/methodobject.c' line='38' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCFunction_NewEx'> + <parameter type-id='type-id-337' name='ml' filepath='Objects/methodobject.c' line='38' column='1'/> + <parameter type-id='type-id-2' name='self' filepath='Objects/methodobject.c' line='38' column='1'/> + <parameter type-id='type-id-2' name='module' filepath='Objects/methodobject.c' line='38' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyCFunction_GetFunction' mangled-name='PyCFunction_GetFunction' filepath='Objects/methodobject.c' line='116' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCFunction_GetFunction'> + <parameter type-id='type-id-2' name='op' filepath='Objects/methodobject.c' line='116' column='1'/> + <return type-id='type-id-388'/> + </function-decl> + <function-decl name='PyCFunction_GetSelf' mangled-name='PyCFunction_GetSelf' filepath='Objects/methodobject.c' line='126' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCFunction_GetSelf'> + <parameter type-id='type-id-2' name='op' filepath='Objects/methodobject.c' line='126' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyCFunction_GetFlags' mangled-name='PyCFunction_GetFlags' filepath='Objects/methodobject.c' line='136' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCFunction_GetFlags'> + <parameter type-id='type-id-2' name='op' filepath='Objects/methodobject.c' line='136' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Objects/moduleobject.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <class-decl name='PyModuleDef_Base' size-in-bits='320' is-struct='yes' visibility='default' filepath='./Include/moduleobject.h' line='44' column='1' id='type-id-389'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='ob_base' type-id='type-id-345' visibility='default' filepath='./Include/moduleobject.h' line='45' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='m_init' type-id='type-id-390' visibility='default' filepath='./Include/moduleobject.h' line='52' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='m_index' type-id='type-id-14' visibility='default' filepath='./Include/moduleobject.h' line='57' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='m_copy' type-id='type-id-2' visibility='default' filepath='./Include/moduleobject.h' line='62' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='PyModuleDef_Base' type-id='type-id-389' filepath='./Include/moduleobject.h' line='63' column='1' id='type-id-391'/> + <class-decl name='PyModuleDef_Slot' size-in-bits='128' is-struct='yes' visibility='default' filepath='./Include/moduleobject.h' line='74' column='1' id='type-id-392'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='slot' type-id='type-id-8' visibility='default' filepath='./Include/moduleobject.h' line='75' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='value' type-id='type-id-22' visibility='default' filepath='./Include/moduleobject.h' line='76' column='1'/> + </data-member> + </class-decl> + <class-decl name='PyModuleDef' size-in-bits='832' is-struct='yes' visibility='default' filepath='./Include/moduleobject.h' line='94' column='1' id='type-id-393'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='m_base' type-id='type-id-391' visibility='default' filepath='./Include/moduleobject.h' line='95' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='m_name' type-id='type-id-12' visibility='default' filepath='./Include/moduleobject.h' line='96' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='384'> + <var-decl name='m_doc' type-id='type-id-12' visibility='default' filepath='./Include/moduleobject.h' line='97' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='448'> + <var-decl name='m_size' type-id='type-id-14' visibility='default' filepath='./Include/moduleobject.h' line='98' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='512'> + <var-decl name='m_methods' type-id='type-id-337' visibility='default' filepath='./Include/moduleobject.h' line='99' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='576'> + <var-decl name='m_slots' type-id='type-id-394' visibility='default' filepath='./Include/moduleobject.h' line='100' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='640'> + <var-decl name='m_traverse' type-id='type-id-395' visibility='default' filepath='./Include/moduleobject.h' line='101' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='704'> + <var-decl name='m_clear' type-id='type-id-396' visibility='default' filepath='./Include/moduleobject.h' line='102' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='768'> + <var-decl name='m_free' type-id='type-id-397' visibility='default' filepath='./Include/moduleobject.h' line='103' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='PyModuleDef' type-id='type-id-393' filepath='./Include/pytypedefs.h' line='12' column='1' id='type-id-3'/> + <typedef-decl name='PyModuleDef_Slot' type-id='type-id-392' filepath='./Include/pytypedefs.h' line='13' column='1' id='type-id-398'/> + <pointer-type-def type-id='type-id-3' size-in-bits='64' id='type-id-399'/> + <pointer-type-def type-id='type-id-398' size-in-bits='64' id='type-id-394'/> + <function-decl name='_PyImport_IsInitialized' mangled-name='_PyImport_IsInitialized' filepath='./Include/cpython/import.h' line='7' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyImport_IsInitialized'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyObject_GenericGetAttrWithDict' mangled-name='_PyObject_GenericGetAttrWithDict' filepath='./Include/cpython/object.h' line='318' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_GenericGetAttrWithDict'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyErr_FormatFromCause' mangled-name='_PyErr_FormatFromCause' filepath='./Include/cpython/pyerrors.h' line='107' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyErr_FormatFromCause'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-12'/> + <parameter is-variadic='yes'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyImport_GetNextModuleIndex' filepath='./Include/internal/pycore_import.h' line='110' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-14'/> + </function-decl> + <function-decl name='_PyImport_ResolveNameWithPackageContext' filepath='./Include/internal/pycore_import.h' line='111' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <return type-id='type-id-12'/> + </function-decl> + <function-decl name='_PyImport_ImportlibModuleRepr' filepath='./Include/internal/pycore_import.h' line='137' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyImport_CheckSubinterpIncompatibleExtensionAllowed' mangled-name='_PyImport_CheckSubinterpIncompatibleExtensionAllowed' filepath='./Include/internal/pycore_import.h' line='172' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyImport_CheckSubinterpIncompatibleExtensionAllowed'> + <parameter type-id='type-id-12'/> + <return type-id='type-id-8'/> + </function-decl> + <var-decl name='PyModule_Type' type-id='type-id-256' mangled-name='PyModule_Type' visibility='default' filepath='./Include/moduleobject.h' line='10' column='1' elf-symbol-id='PyModule_Type'/> + <var-decl name='PyModuleDef_Type' type-id='type-id-256' mangled-name='PyModuleDef_Type' visibility='default' filepath='./Include/moduleobject.h' line='41' column='1' elf-symbol-id='PyModuleDef_Type'/> + <function-decl name='PyObject_SetAttrString' mangled-name='PyObject_SetAttrString' filepath='./Include/object.h' line='409' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_SetAttrString'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PySys_FormatStderr' mangled-name='PySys_FormatStderr' filepath='./Include/sysmodule.h' line='22' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySys_FormatStderr'> + <parameter type-id='type-id-12'/> + <parameter is-variadic='yes'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyModuleDef_Init' mangled-name='PyModuleDef_Init' filepath='Objects/moduleobject.c' line='41' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyModuleDef_Init'> + <parameter type-id='type-id-399' name='def' filepath='Objects/moduleobject.c' line='41' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyModule_NewObject' mangled-name='PyModule_NewObject' filepath='Objects/moduleobject.c' line='107' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyModule_NewObject'> + <parameter type-id='type-id-2' name='name' filepath='Objects/moduleobject.c' line='107' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyModule_New' mangled-name='PyModule_New' filepath='Objects/moduleobject.c' line='123' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyModule_New'> + <parameter type-id='type-id-12' name='name' filepath='Objects/moduleobject.c' line='123' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyModule_Create2' mangled-name='PyModule_Create2' filepath='Objects/moduleobject.c' line='183' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyModule_Create2'> + <parameter type-id='type-id-399' name='module' filepath='Objects/moduleobject.c' line='183' column='1'/> + <parameter type-id='type-id-8' name='module_api_version' filepath='Objects/moduleobject.c' line='183' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyModule_CreateInitialized' mangled-name='_PyModule_CreateInitialized' filepath='Objects/moduleobject.c' line='194' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyModule_CreateInitialized'> + <parameter type-id='type-id-399' name='module' filepath='Objects/moduleobject.c' line='194' column='1'/> + <parameter type-id='type-id-8' name='module_api_version' filepath='Objects/moduleobject.c' line='194' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyModule_FromDefAndSpec2' mangled-name='PyModule_FromDefAndSpec2' filepath='Objects/moduleobject.c' line='242' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyModule_FromDefAndSpec2'> + <parameter type-id='type-id-399' name='def' filepath='Objects/moduleobject.c' line='242' column='1'/> + <parameter type-id='type-id-2' name='spec' filepath='Objects/moduleobject.c' line='242' column='1'/> + <parameter type-id='type-id-8' name='module_api_version' filepath='Objects/moduleobject.c' line='242' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyModule_ExecDef' mangled-name='PyModule_ExecDef' filepath='Objects/moduleobject.c' line='405' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyModule_ExecDef'> + <parameter type-id='type-id-2' name='module' filepath='Objects/moduleobject.c' line='405' column='1'/> + <parameter type-id='type-id-399' name='def' filepath='Objects/moduleobject.c' line='405' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyModule_AddFunctions' mangled-name='PyModule_AddFunctions' filepath='Objects/moduleobject.c' line='473' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyModule_AddFunctions'> + <parameter type-id='type-id-2' name='m' filepath='Objects/moduleobject.c' line='473' column='1'/> + <parameter type-id='type-id-337' name='functions' filepath='Objects/moduleobject.c' line='473' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyModule_SetDocString' mangled-name='PyModule_SetDocString' filepath='Objects/moduleobject.c' line='487' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyModule_SetDocString'> + <parameter type-id='type-id-2' name='m' filepath='Objects/moduleobject.c' line='487' column='1'/> + <parameter type-id='type-id-12' name='doc' filepath='Objects/moduleobject.c' line='487' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyModule_GetName' mangled-name='PyModule_GetName' filepath='Objects/moduleobject.c' line='533' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyModule_GetName'> + <parameter type-id='type-id-2' name='m' filepath='Objects/moduleobject.c' line='533' column='1'/> + <return type-id='type-id-12'/> + </function-decl> + <function-decl name='PyModule_GetFilenameObject' mangled-name='PyModule_GetFilenameObject' filepath='Objects/moduleobject.c' line='545' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyModule_GetFilenameObject'> + <parameter type-id='type-id-2' name='m' filepath='Objects/moduleobject.c' line='545' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyModule_GetFilename' mangled-name='PyModule_GetFilename' filepath='Objects/moduleobject.c' line='567' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyModule_GetFilename'> + <parameter type-id='type-id-2' name='m' filepath='Objects/moduleobject.c' line='567' column='1'/> + <return type-id='type-id-12'/> + </function-decl> + <function-decl name='PyModule_GetDef' mangled-name='PyModule_GetDef' filepath='Objects/moduleobject.c' line='580' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyModule_GetDef'> + <parameter type-id='type-id-2' name='m' filepath='Objects/moduleobject.c' line='580' column='1'/> + <return type-id='type-id-399'/> + </function-decl> + <function-decl name='PyModule_GetState' mangled-name='PyModule_GetState' filepath='Objects/moduleobject.c' line='590' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyModule_GetState'> + <parameter type-id='type-id-2' name='m' filepath='Objects/moduleobject.c' line='590' column='1'/> + <return type-id='type-id-22'/> + </function-decl> + <function-decl name='_PyModule_Clear' mangled-name='_PyModule_Clear' filepath='Objects/moduleobject.c' line='600' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyModule_Clear'> + <parameter type-id='type-id-2' name='m' filepath='Objects/moduleobject.c' line='600' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyModule_ClearDict' mangled-name='_PyModule_ClearDict' filepath='Objects/moduleobject.c' line='608' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyModule_ClearDict'> + <parameter type-id='type-id-2' name='d' filepath='Objects/moduleobject.c' line='608' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyModuleSpec_IsInitializing' mangled-name='_PyModuleSpec_IsInitializing' filepath='Objects/moduleobject.c' line='739' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyModuleSpec_IsInitializing'> + <parameter type-id='type-id-2' name='spec' filepath='Objects/moduleobject.c' line='739' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-type size-in-bits='64' id='type-id-400'> + <return type-id='type-id-2'/> + </function-type> + </abi-instr> + <abi-instr address-size='64' path='Objects/namespaceobject.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <var-decl name='_PyNamespace_Type' type-id='type-id-256' mangled-name='_PyNamespace_Type' visibility='default' filepath='./Include/internal/pycore_namespace.h' line='13' column='1' elf-symbol-id='_PyNamespace_Type'/> + <function-decl name='PyUnicode_Join' mangled-name='PyUnicode_Join' filepath='./Include/unicodeobject.h' line='889' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_Join'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyNamespace_New' mangled-name='_PyNamespace_New' filepath='Objects/namespaceobject.c' line='247' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyNamespace_New'> + <parameter type-id='type-id-2' name='kwds' filepath='Objects/namespaceobject.c' line='247' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Objects/object.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <array-type-def dimensions='1' type-id='type-id-8' size-in-bits='192' id='type-id-91'> + <subrange length='6' type-id='type-id-28' id='type-id-401'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-8' size-in-bits='infinite' id='type-id-402'> + <subrange length='infinite' id='type-id-225'/> + </array-type-def> + <class-decl name='PyModuleObject' size-in-bits='448' is-struct='yes' naming-typedef-id='type-id-403' visibility='default' filepath='./Include/internal/pycore_moduleobject.h' line='11' column='1' id='type-id-404'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='ob_base' type-id='type-id-345' visibility='default' filepath='./Include/internal/pycore_moduleobject.h' line='12' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='md_dict' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_moduleobject.h' line='13' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='md_def' type-id='type-id-399' visibility='default' filepath='./Include/internal/pycore_moduleobject.h' line='14' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='md_state' type-id='type-id-22' visibility='default' filepath='./Include/internal/pycore_moduleobject.h' line='15' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='md_weaklist' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_moduleobject.h' line='16' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='384'> + <var-decl name='md_name' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_moduleobject.h' line='18' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='PyModuleObject' type-id='type-id-404' filepath='./Include/internal/pycore_moduleobject.h' line='19' column='1' id='type-id-403'/> + <enum-decl name='PyGILState_STATE' naming-typedef-id='type-id-405' filepath='./Include/pystate.h' line='77' column='1' id='type-id-406'> + <underlying-type type-id='type-id-24'/> + <enumerator name='PyGILState_LOCKED' value='0'/> + <enumerator name='PyGILState_UNLOCKED' value='1'/> + </enum-decl> + <typedef-decl name='PyGILState_STATE' type-id='type-id-406' filepath='./Include/pystate.h' line='78' column='1' id='type-id-405'/> + <pointer-type-def type-id='type-id-403' size-in-bits='64' id='type-id-407'/> + <pointer-type-def type-id='type-id-408' size-in-bits='64' id='type-id-409'/> + <pointer-type-def type-id='type-id-410' size-in-bits='64' id='type-id-411'/> + <qualified-type-def type-id='type-id-22' restrict='yes' id='type-id-226'/> + <var-decl name='_PyNone_Type' type-id='type-id-256' mangled-name='_PyNone_Type' visibility='default' filepath='./Include/cpython/object.h' line='390' column='1' elf-symbol-id='_PyNone_Type'/> + <var-decl name='_PyNotImplemented_Type' type-id='type-id-256' mangled-name='_PyNotImplemented_Type' visibility='default' filepath='./Include/cpython/object.h' line='391' column='1' elf-symbol-id='_PyNotImplemented_Type'/> + <var-decl name='_Py_SwappedOp' type-id='type-id-402' mangled-name='_Py_SwappedOp' visibility='default' filepath='./Include/cpython/object.h' line='396' column='1' elf-symbol-id='_Py_SwappedOp'/> + <function-decl name='PyMem_RawMalloc' mangled-name='PyMem_RawMalloc' filepath='./Include/cpython/pymem.h' line='5' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMem_RawMalloc'> + <parameter type-id='type-id-19'/> + <return type-id='type-id-22'/> + </function-decl> + <function-decl name='_PyTuple_DebugMallocStats' mangled-name='_PyTuple_DebugMallocStats' filepath='./Include/cpython/tupleobject.h' line='39' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTuple_DebugMallocStats'> + <parameter type-id='type-id-229'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyUnicode_CheckConsistency' mangled-name='_PyUnicode_CheckConsistency' filepath='./Include/cpython/unicodeobject.h' line='170' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_CheckConsistency'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyUnicode_AsASCIIString' mangled-name='_PyUnicode_AsASCIIString' filepath='./Include/cpython/unicodeobject.h' line='713' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_AsASCIIString'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-12'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyEval_GetFrameLocals' filepath='./Include/internal/pycore_ceval.h' line='157' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyObjectDict_SetItem' filepath='./Include/internal/pycore_dict.h' line='56' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1'/> + <parameter type-id='type-id-233'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyObject_MakeDictFromInstanceAttributes' filepath='./Include/internal/pycore_dict.h' line='178' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-347'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_Py_module_getattro_impl' filepath='./Include/internal/pycore_moduleobject.h' line='39' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-407'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_Py_module_getattro' filepath='./Include/internal/pycore_moduleobject.h' line='40' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-407'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyType_CheckConsistency' mangled-name='_PyType_CheckConsistency' filepath='./Include/internal/pycore_object.h' line='138' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyType_CheckConsistency'> + <parameter type-id='type-id-1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyTraceMalloc_NewReference' filepath='./Include/internal/pycore_object.h' line='145' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyObject_StoreInstanceAttribute' filepath='./Include/internal/pycore_object.h' line='361' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-347'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyObject_GetInstanceAttribute' filepath='./Include/internal/pycore_object.h' line='363' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-347'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyStaticType_GetState' filepath='./Include/internal/pycore_typeobject.h' line='113' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <parameter type-id='type-id-1'/> + <return type-id='type-id-411'/> + </function-decl> + <function-decl name='_Py_type_getattro_impl' filepath='./Include/internal/pycore_typeobject.h' line='132' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-179'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_Py_type_getattro' filepath='./Include/internal/pycore_typeobject.h' line='134' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_Py_initialize_generic' filepath='./Include/internal/pycore_typevarobject.h' line='16' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-8'/> + </function-decl> + <var-decl name='_Py_NoneStruct' type-id='type-id-345' mangled-name='_Py_NoneStruct' visibility='default' filepath='./Include/object.h' line='845' column='1' elf-symbol-id='_Py_NoneStruct'/> + <var-decl name='_Py_NotImplementedStruct' type-id='type-id-345' mangled-name='_Py_NotImplementedStruct' visibility='default' filepath='./Include/object.h' line='859' column='1' elf-symbol-id='_Py_NotImplementedStruct'/> + <function-decl name='PyThreadState_GetDict' mangled-name='PyThreadState_GetDict' filepath='./Include/pystate.h' line='66' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThreadState_GetDict'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyGILState_Ensure' mangled-name='PyGILState_Ensure' filepath='./Include/pystate.h' line='102' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyGILState_Ensure'> + <return type-id='type-id-405'/> + </function-decl> + <function-decl name='PyGILState_Release' mangled-name='PyGILState_Release' filepath='./Include/pystate.h' line='112' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyGILState_Release'> + <parameter type-id='type-id-405'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyThread_tss_is_created' mangled-name='PyThread_tss_is_created' filepath='./Include/pythread.h' line='119' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThread_tss_is_created'> + <parameter type-id='type-id-409'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyThread_tss_set' mangled-name='PyThread_tss_set' filepath='./Include/pythread.h' line='122' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThread_tss_set'> + <parameter type-id='type-id-409'/> + <parameter type-id='type-id-22'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyThread_tss_get' mangled-name='PyThread_tss_get' filepath='./Include/pythread.h' line='123' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThread_tss_get'> + <parameter type-id='type-id-409'/> + <return type-id='type-id-22'/> + </function-decl> + <function-decl name='PyUnicode_DecodeASCII' mangled-name='PyUnicode_DecodeASCII' filepath='./Include/unicodeobject.h' line='633' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_DecodeASCII'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-14'/> + <parameter type-id='type-id-12'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='fprintf' filepath='/usr/include/stdio.h' line='350' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-412'/> + <parameter type-id='type-id-181'/> + <parameter is-variadic='yes'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='fwrite' filepath='/usr/include/stdio.h' line='681' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-226'/> + <parameter type-id='type-id-19'/> + <parameter type-id='type-id-19'/> + <parameter type-id='type-id-412'/> + <return type-id='type-id-19'/> + </function-decl> + <function-decl name='ferror' filepath='/usr/include/stdio.h' line='790' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-229'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyMem_DumpTraceback' filepath='Objects/object.c' line='32' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-22'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyObject_CheckConsistency' mangled-name='_PyObject_CheckConsistency' filepath='Objects/object.c' line='36' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_CheckConsistency'> + <parameter type-id='type-id-2' name='op' filepath='Objects/object.c' line='36' column='1'/> + <parameter type-id='type-id-8' name='check_content' filepath='Objects/object.c' line='36' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='Py_IncRef' mangled-name='Py_IncRef' filepath='Objects/object.c' line='268' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_IncRef'> + <parameter type-id='type-id-2' name='o' filepath='Objects/object.c' line='268' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='Py_DecRef' mangled-name='Py_DecRef' filepath='Objects/object.c' line='274' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_DecRef'> + <parameter type-id='type-id-2' name='o' filepath='Objects/object.c' line='274' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_Py_IncRef' mangled-name='_Py_IncRef' filepath='Objects/object.c' line='280' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_IncRef'> + <parameter type-id='type-id-2' name='o' filepath='Objects/object.c' line='280' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_Py_DecRef' mangled-name='_Py_DecRef' filepath='Objects/object.c' line='286' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_DecRef'> + <parameter type-id='type-id-2' name='o' filepath='Objects/object.c' line='286' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyObject_Init' mangled-name='PyObject_Init' filepath='Objects/object.c' line='295' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_Init'> + <parameter type-id='type-id-2' name='op' filepath='Objects/object.c' line='295' column='1'/> + <parameter type-id='type-id-1' name='tp' filepath='Objects/object.c' line='295' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyObject_InitVar' mangled-name='PyObject_InitVar' filepath='Objects/object.c' line='306' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_InitVar'> + <parameter type-id='type-id-322' name='op' filepath='Objects/object.c' line='306' column='1'/> + <parameter type-id='type-id-1' name='tp' filepath='Objects/object.c' line='306' column='1'/> + <parameter type-id='type-id-14' name='size' filepath='Objects/object.c' line='306' column='1'/> + <return type-id='type-id-322'/> + </function-decl> + <function-decl name='PyObject_CallFinalizer' mangled-name='PyObject_CallFinalizer' filepath='Objects/object.c' line='341' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_CallFinalizer'> + <parameter type-id='type-id-2' name='self' filepath='Objects/object.c' line='341' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyObject_Print' mangled-name='PyObject_Print' filepath='Objects/object.c' line='395' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_Print'> + <parameter type-id='type-id-2' name='op' filepath='Objects/object.c' line='395' column='1'/> + <parameter type-id='type-id-229' name='fp' filepath='Objects/object.c' line='395' column='1'/> + <parameter type-id='type-id-8' name='flags' filepath='Objects/object.c' line='395' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_Py_BreakPoint' mangled-name='_Py_BreakPoint' filepath='Objects/object.c' line='454' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_BreakPoint'> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyObject_IsFreed' mangled-name='_PyObject_IsFreed' filepath='Objects/object.c' line='466' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_IsFreed'> + <parameter type-id='type-id-2' name='op' filepath='Objects/object.c' line='466' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyObject_Dump' mangled-name='_PyObject_Dump' filepath='Objects/object.c' line='487' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_Dump'> + <parameter type-id='type-id-2' name='op' filepath='Objects/object.c' line='487' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyObject_HasAttrString' mangled-name='PyObject_HasAttrString' filepath='Objects/object.c' line='927' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_HasAttrString'> + <parameter type-id='type-id-2' name='v' filepath='Objects/object.c' line='927' column='1'/> + <parameter type-id='type-id-12' name='name' filepath='Objects/object.c' line='927' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyObject_SetAttrId' mangled-name='_PyObject_SetAttrId' filepath='Objects/object.c' line='994' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_SetAttrId'> + <parameter type-id='type-id-2' name='v' filepath='Objects/object.c' line='994' column='1'/> + <parameter type-id='type-id-309' name='name' filepath='Objects/object.c' line='994' column='1'/> + <parameter type-id='type-id-2' name='w' filepath='Objects/object.c' line='994' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyObject_LookupAttrId' mangled-name='_PyObject_LookupAttrId' filepath='Objects/object.c' line='1134' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_LookupAttrId'> + <parameter type-id='type-id-2' name='v' filepath='Objects/object.c' line='1134' column='1'/> + <parameter type-id='type-id-309' name='name' filepath='Objects/object.c' line='1134' column='1'/> + <parameter type-id='type-id-233' name='result' filepath='Objects/object.c' line='1134' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyObject_HasAttr' mangled-name='PyObject_HasAttr' filepath='Objects/object.c' line='1145' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_HasAttr'> + <parameter type-id='type-id-2' name='v' filepath='Objects/object.c' line='1145' column='1'/> + <parameter type-id='type-id-2' name='name' filepath='Objects/object.c' line='1145' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyObject_GetDictPtr' mangled-name='_PyObject_GetDictPtr' filepath='Objects/object.c' line='1244' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_GetDictPtr'> + <parameter type-id='type-id-2' name='obj' filepath='Objects/object.c' line='1244' column='1'/> + <return type-id='type-id-233'/> + </function-decl> + <function-decl name='_PyObject_GenericSetAttrWithDict' mangled-name='_PyObject_GenericSetAttrWithDict' filepath='Objects/object.c' line='1525' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_GenericSetAttrWithDict'> + <parameter type-id='type-id-2' name='obj' filepath='Objects/object.c' line='1525' column='1'/> + <parameter type-id='type-id-2' name='name' filepath='Objects/object.c' line='1525' column='1'/> + <parameter type-id='type-id-2' name='value' filepath='Objects/object.c' line='1526' column='1'/> + <parameter type-id='type-id-2' name='dict' filepath='Objects/object.c' line='1526' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyObject_Not' mangled-name='PyObject_Not' filepath='Objects/object.c' line='1686' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_Not'> + <parameter type-id='type-id-2' name='v' filepath='Objects/object.c' line='1686' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyObject_DebugTypeStats' mangled-name='_PyObject_DebugTypeStats' filepath='Objects/object.c' line='2334' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_DebugTypeStats'> + <parameter type-id='type-id-229' name='out' filepath='Objects/object.c' line='2334' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyObject_GET_WEAKREFS_LISTPTR' mangled-name='PyObject_GET_WEAKREFS_LISTPTR' filepath='Objects/object.c' line='2653' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_GET_WEAKREFS_LISTPTR'> + <parameter type-id='type-id-2' name='op' filepath='Objects/object.c' line='2653' column='1'/> + <return type-id='type-id-233'/> + </function-decl> + <function-decl name='Py_NewRef' mangled-name='Py_NewRef' filepath='Objects/object.c' line='2664' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_NewRef'> + <parameter type-id='type-id-2' name='obj' filepath='Objects/object.c' line='2664' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='Py_XNewRef' mangled-name='Py_XNewRef' filepath='Objects/object.c' line='2670' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_XNewRef'> + <parameter type-id='type-id-2' name='obj' filepath='Objects/object.c' line='2670' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='Py_Is' mangled-name='Py_Is' filepath='Objects/object.c' line='2682' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_Is'> + <parameter type-id='type-id-2' name='x' filepath='Objects/object.c' line='2682' column='1'/> + <parameter type-id='type-id-2' name='y' filepath='Objects/object.c' line='2682' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='Py_IsNone' mangled-name='Py_IsNone' filepath='Objects/object.c' line='2687' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_IsNone'> + <parameter type-id='type-id-2' name='x' filepath='Objects/object.c' line='2687' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='Py_IsTrue' mangled-name='Py_IsTrue' filepath='Objects/object.c' line='2692' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_IsTrue'> + <parameter type-id='type-id-2' name='x' filepath='Objects/object.c' line='2692' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='Py_IsFalse' mangled-name='Py_IsFalse' filepath='Objects/object.c' line='2697' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_IsFalse'> + <parameter type-id='type-id-2' name='x' filepath='Objects/object.c' line='2697' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Objects/obmalloc.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <enum-decl name='PyMemAllocatorDomain' naming-typedef-id='type-id-413' filepath='./Include/cpython/pymem.h' line='23' column='1' id='type-id-414'> + <underlying-type type-id='type-id-24'/> + <enumerator name='PYMEM_DOMAIN_RAW' value='0'/> + <enumerator name='PYMEM_DOMAIN_MEM' value='1'/> + <enumerator name='PYMEM_DOMAIN_OBJ' value='2'/> + </enum-decl> + <typedef-decl name='PyMemAllocatorDomain' type-id='type-id-414' filepath='./Include/cpython/pymem.h' line='32' column='1' id='type-id-413'/> + <enum-decl name='PyMemAllocatorName' naming-typedef-id='type-id-415' filepath='./Include/cpython/pymem.h' line='34' column='1' id='type-id-416'> + <underlying-type type-id='type-id-24'/> + <enumerator name='PYMEM_ALLOCATOR_NOT_SET' value='0'/> + <enumerator name='PYMEM_ALLOCATOR_DEFAULT' value='1'/> + <enumerator name='PYMEM_ALLOCATOR_DEBUG' value='2'/> + <enumerator name='PYMEM_ALLOCATOR_MALLOC' value='3'/> + <enumerator name='PYMEM_ALLOCATOR_MALLOC_DEBUG' value='4'/> + <enumerator name='PYMEM_ALLOCATOR_PYMALLOC' value='5'/> + <enumerator name='PYMEM_ALLOCATOR_PYMALLOC_DEBUG' value='6'/> + </enum-decl> + <typedef-decl name='PyMemAllocatorName' type-id='type-id-416' filepath='./Include/cpython/pymem.h' line='44' column='1' id='type-id-415'/> + <pointer-type-def type-id='type-id-417' size-in-bits='64' id='type-id-418'/> + <pointer-type-def type-id='type-id-415' size-in-bits='64' id='type-id-419'/> + <pointer-type-def type-id='type-id-420' size-in-bits='64' id='type-id-421'/> + <qualified-type-def type-id='type-id-422' const='yes' id='type-id-423'/> + <pointer-type-def type-id='type-id-423' size-in-bits='64' id='type-id-16'/> + <function-decl name='Py_GETENV' mangled-name='Py_GETENV' filepath='./Include/cpython/pydebug.h' line='32' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_GETENV'> + <parameter type-id='type-id-12'/> + <return type-id='type-id-15'/> + </function-decl> + <function-decl name='PyGILState_Check' mangled-name='PyGILState_Check' filepath='./Include/cpython/pystate.h' line='291' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyGILState_Check'> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyInterpreterState_Head' mangled-name='PyInterpreterState_Head' filepath='./Include/cpython/pystate.h' line='315' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInterpreterState_Head'> + <return type-id='type-id-20'/> + </function-decl> + <function-decl name='PyInterpreterState_Next' mangled-name='PyInterpreterState_Next' filepath='./Include/cpython/pystate.h' line='316' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInterpreterState_Next'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-20'/> + </function-decl> + <function-decl name='fputc' filepath='/usr/include/stdio.h' line='549' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-229'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='fputs' filepath='/usr/include/stdio.h' line='655' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-181'/> + <parameter type-id='type-id-412'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='malloc' filepath='/usr/include/stdlib.h' line='540' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-19'/> + <return type-id='type-id-22'/> + </function-decl> + <function-decl name='calloc' filepath='/usr/include/stdlib.h' line='543' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-19'/> + <parameter type-id='type-id-19'/> + <return type-id='type-id-22'/> + </function-decl> + <function-decl name='realloc' filepath='/usr/include/stdlib.h' line='551' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-22'/> + <parameter type-id='type-id-19'/> + <return type-id='type-id-22'/> + </function-decl> + <function-decl name='free' filepath='/usr/include/stdlib.h' line='555' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-22'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='wcslen' filepath='/usr/include/wchar.h' line='223' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-16'/> + <return type-id='type-id-19'/> + </function-decl> + <function-decl name='munmap' filepath='/usr/include/x86_64-linux-gnu/sys/mman.h' line='76' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-22'/> + <parameter type-id='type-id-19'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyMem_SetDefaultAllocator' mangled-name='_PyMem_SetDefaultAllocator' filepath='Objects/obmalloc.c' line='258' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyMem_SetDefaultAllocator'> + <parameter type-id='type-id-413' name='domain' filepath='Objects/obmalloc.c' line='258' column='1'/> + <parameter type-id='type-id-418' name='old_alloc' filepath='Objects/obmalloc.c' line='259' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyMem_GetAllocatorName' mangled-name='_PyMem_GetAllocatorName' filepath='Objects/obmalloc.c' line='273' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyMem_GetAllocatorName'> + <parameter type-id='type-id-12' name='name' filepath='Objects/obmalloc.c' line='273' column='1'/> + <parameter type-id='type-id-419' name='allocator' filepath='Objects/obmalloc.c' line='273' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyMem_SetupAllocators' mangled-name='_PyMem_SetupAllocators' filepath='Objects/obmalloc.c' line='369' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyMem_SetupAllocators'> + <parameter type-id='type-id-415' name='allocator' filepath='Objects/obmalloc.c' line='369' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyMem_GetCurrentAllocatorName' mangled-name='_PyMem_GetCurrentAllocatorName' filepath='Objects/obmalloc.c' line='436' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyMem_GetCurrentAllocatorName'> + <return type-id='type-id-12'/> + </function-decl> + <function-decl name='PyMem_SetupDebugHooks' mangled-name='PyMem_SetupDebugHooks' filepath='Objects/obmalloc.c' line='521' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMem_SetupDebugHooks'> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyMem_GetAllocator' mangled-name='PyMem_GetAllocator' filepath='Objects/obmalloc.c' line='564' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMem_GetAllocator'> + <parameter type-id='type-id-413' name='domain' filepath='Objects/obmalloc.c' line='564' column='1'/> + <parameter type-id='type-id-418' name='allocator' filepath='Objects/obmalloc.c' line='564' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyMem_SetAllocator' mangled-name='PyMem_SetAllocator' filepath='Objects/obmalloc.c' line='577' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMem_SetAllocator'> + <parameter type-id='type-id-413' name='domain' filepath='Objects/obmalloc.c' line='577' column='1'/> + <parameter type-id='type-id-418' name='allocator' filepath='Objects/obmalloc.c' line='577' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyObject_GetArenaAllocator' mangled-name='PyObject_GetArenaAllocator' filepath='Objects/obmalloc.c' line='590' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_GetArenaAllocator'> + <parameter type-id='type-id-421' name='allocator' filepath='Objects/obmalloc.c' line='590' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyObject_SetArenaAllocator' mangled-name='PyObject_SetArenaAllocator' filepath='Objects/obmalloc.c' line='603' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_SetArenaAllocator'> + <parameter type-id='type-id-421' name='allocator' filepath='Objects/obmalloc.c' line='603' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyMem_RawCalloc' mangled-name='PyMem_RawCalloc' filepath='Objects/obmalloc.c' line='666' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMem_RawCalloc'> + <parameter type-id='type-id-19' name='nelem' filepath='Objects/obmalloc.c' line='666' column='1'/> + <parameter type-id='type-id-19' name='elsize' filepath='Objects/obmalloc.c' line='666' column='1'/> + <return type-id='type-id-22'/> + </function-decl> + <function-decl name='_PyMem_RawWcsdup' mangled-name='_PyMem_RawWcsdup' filepath='Objects/obmalloc.c' line='741' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyMem_RawWcsdup'> + <parameter type-id='type-id-16' name='str' filepath='Objects/obmalloc.c' line='741' column='1'/> + <return type-id='type-id-52'/> + </function-decl> + <function-decl name='_PyMem_RawStrdup' mangled-name='_PyMem_RawStrdup' filepath='Objects/obmalloc.c' line='761' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyMem_RawStrdup'> + <parameter type-id='type-id-12' name='str' filepath='Objects/obmalloc.c' line='761' column='1'/> + <return type-id='type-id-15'/> + </function-decl> + <function-decl name='_PyMem_Strdup' mangled-name='_PyMem_Strdup' filepath='Objects/obmalloc.c' line='774' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyMem_Strdup'> + <parameter type-id='type-id-12' name='str' filepath='Objects/obmalloc.c' line='774' column='1'/> + <return type-id='type-id-15'/> + </function-decl> + <function-decl name='_PyObject_DebugMallocStats' mangled-name='_PyObject_DebugMallocStats' filepath='Objects/obmalloc.c' line='2546' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_DebugMallocStats'> + <parameter type-id='type-id-229' name='out' filepath='Objects/obmalloc.c' line='2546' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Objects/odictobject.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <var-decl name='PyODict_Type' type-id='type-id-256' mangled-name='PyODict_Type' visibility='default' filepath='./Include/cpython/odictobject.h' line='15' column='1' elf-symbol-id='PyODict_Type'/> + <var-decl name='PyODictIter_Type' type-id='type-id-256' mangled-name='PyODictIter_Type' visibility='default' filepath='./Include/cpython/odictobject.h' line='16' column='1' elf-symbol-id='PyODictIter_Type'/> + <var-decl name='PyODictKeys_Type' type-id='type-id-256' mangled-name='PyODictKeys_Type' visibility='default' filepath='./Include/cpython/odictobject.h' line='17' column='1' elf-symbol-id='PyODictKeys_Type'/> + <var-decl name='PyODictItems_Type' type-id='type-id-256' mangled-name='PyODictItems_Type' visibility='default' filepath='./Include/cpython/odictobject.h' line='18' column='1' elf-symbol-id='PyODictItems_Type'/> + <var-decl name='PyODictValues_Type' type-id='type-id-256' mangled-name='PyODictValues_Type' visibility='default' filepath='./Include/cpython/odictobject.h' line='19' column='1' elf-symbol-id='PyODictValues_Type'/> + <function-decl name='_PyErr_ChainExceptions1' mangled-name='_PyErr_ChainExceptions1' filepath='./Include/cpython/pyerrors.h' line='102' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyErr_ChainExceptions1'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyDict_FromKeys' filepath='./Include/internal/pycore_dict.h' line='36' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_Py_dict_lookup' filepath='./Include/internal/pycore_dict.h' line='48' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-340'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-305'/> + <parameter type-id='type-id-233'/> + <return type-id='type-id-14'/> + </function-decl> + <function-decl name='_PyDict_Pop_KnownHash' filepath='./Include/internal/pycore_dict.h' line='58' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-305'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyODict_New' mangled-name='PyODict_New' filepath='Objects/odictobject.c' line='1545' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyODict_New'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyODict_SetItem' mangled-name='PyODict_SetItem' filepath='Objects/odictobject.c' line='1568' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyODict_SetItem'> + <parameter type-id='type-id-2' name='od' filepath='Objects/odictobject.c' line='1568' column='1'/> + <parameter type-id='type-id-2' name='key' filepath='Objects/odictobject.c' line='1568' column='1'/> + <parameter type-id='type-id-2' name='value' filepath='Objects/odictobject.c' line='1568' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyODict_DelItem' mangled-name='PyODict_DelItem' filepath='Objects/odictobject.c' line='1577' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyODict_DelItem'> + <parameter type-id='type-id-2' name='od' filepath='Objects/odictobject.c' line='1577' column='1'/> + <parameter type-id='type-id-2' name='key' filepath='Objects/odictobject.c' line='1577' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Objects/picklebufobject.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <var-decl name='PyPickleBuffer_Type' type-id='type-id-256' mangled-name='PyPickleBuffer_Type' visibility='default' filepath='./Include/cpython/picklebufobject.h' line='13' column='1' elf-symbol-id='PyPickleBuffer_Type'/> + <function-decl name='PyPickleBuffer_FromObject' mangled-name='PyPickleBuffer_FromObject' filepath='Objects/picklebufobject.c' line='17' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyPickleBuffer_FromObject'> + <parameter type-id='type-id-2' name='base' filepath='Objects/picklebufobject.c' line='17' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyPickleBuffer_GetBuffer' mangled-name='PyPickleBuffer_GetBuffer' filepath='Objects/picklebufobject.c' line='36' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyPickleBuffer_GetBuffer'> + <parameter type-id='type-id-2' name='obj' filepath='Objects/picklebufobject.c' line='36' column='1'/> + <return type-id='type-id-245'/> + </function-decl> + <function-decl name='PyPickleBuffer_Release' mangled-name='PyPickleBuffer_Release' filepath='Objects/picklebufobject.c' line='55' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyPickleBuffer_Release'> + <parameter type-id='type-id-2' name='obj' filepath='Objects/picklebufobject.c' line='55' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Objects/rangeobject.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <var-decl name='PyRange_Type' type-id='type-id-256' mangled-name='PyRange_Type' visibility='default' filepath='./Include/rangeobject.h' line='18' column='1' elf-symbol-id='PyRange_Type'/> + <var-decl name='PyRangeIter_Type' type-id='type-id-256' mangled-name='PyRangeIter_Type' visibility='default' filepath='./Include/rangeobject.h' line='19' column='1' elf-symbol-id='PyRangeIter_Type'/> + <var-decl name='PyLongRangeIter_Type' type-id='type-id-256' mangled-name='PyLongRangeIter_Type' visibility='default' filepath='./Include/rangeobject.h' line='20' column='1' elf-symbol-id='PyLongRangeIter_Type'/> + <function-decl name='_PySlice_GetLongIndices' mangled-name='_PySlice_GetLongIndices' filepath='./Include/sliceobject.h' line='37' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PySlice_GetLongIndices'> + <parameter type-id='type-id-424'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-233'/> + <parameter type-id='type-id-233'/> + <parameter type-id='type-id-233'/> + <return type-id='type-id-8'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Objects/setobject.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <var-decl name='_PySet_Dummy' type-id='type-id-2' mangled-name='_PySet_Dummy' visibility='default' filepath='./Include/cpython/setobject.h' line='69' column='1' elf-symbol-id='_PySet_Dummy'/> + <function-decl name='_PyUnicode_EQ' mangled-name='_PyUnicode_EQ' filepath='./Include/cpython/unicodeobject.h' line='953' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_EQ'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-decl> + <var-decl name='PySet_Type' type-id='type-id-256' mangled-name='PySet_Type' visibility='default' filepath='./Include/setobject.h' line='9' column='1' elf-symbol-id='PySet_Type'/> + <var-decl name='PyFrozenSet_Type' type-id='type-id-256' mangled-name='PyFrozenSet_Type' visibility='default' filepath='./Include/setobject.h' line='10' column='1' elf-symbol-id='PyFrozenSet_Type'/> + <var-decl name='PySetIter_Type' type-id='type-id-256' mangled-name='PySetIter_Type' visibility='default' filepath='./Include/setobject.h' line='11' column='1' elf-symbol-id='PySetIter_Type'/> + <function-decl name='PySet_Size' mangled-name='PySet_Size' filepath='Objects/setobject.c' line='2277' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySet_Size'> + <parameter type-id='type-id-2' name='anyset' filepath='Objects/setobject.c' line='2277' column='1'/> + <return type-id='type-id-14'/> + </function-decl> + <function-decl name='PySet_Clear' mangled-name='PySet_Clear' filepath='Objects/setobject.c' line='2287' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySet_Clear'> + <parameter type-id='type-id-2' name='set' filepath='Objects/setobject.c' line='2287' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PySet_Discard' mangled-name='PySet_Discard' filepath='Objects/setobject.c' line='2307' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySet_Discard'> + <parameter type-id='type-id-2' name='set' filepath='Objects/setobject.c' line='2307' column='1'/> + <parameter type-id='type-id-2' name='key' filepath='Objects/setobject.c' line='2307' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PySet_Pop' mangled-name='PySet_Pop' filepath='Objects/setobject.c' line='2344' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySet_Pop'> + <parameter type-id='type-id-2' name='set' filepath='Objects/setobject.c' line='2344' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Objects/sliceobject.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <var-decl name='_Py_EllipsisObject' type-id='type-id-345' mangled-name='_Py_EllipsisObject' visibility='default' filepath='./Include/sliceobject.h' line='9' column='1' elf-symbol-id='_Py_EllipsisObject'/> + <var-decl name='PySlice_Type' type-id='type-id-256' mangled-name='PySlice_Type' visibility='default' filepath='./Include/sliceobject.h' line='28' column='1' elf-symbol-id='PySlice_Type'/> + <var-decl name='PyEllipsis_Type' type-id='type-id-256' mangled-name='PyEllipsis_Type' visibility='default' filepath='./Include/sliceobject.h' line='29' column='1' elf-symbol-id='PyEllipsis_Type'/> + <function-decl name='PySlice_New' mangled-name='PySlice_New' filepath='Objects/sliceobject.c' line='155' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySlice_New'> + <parameter type-id='type-id-2' name='start' filepath='Objects/sliceobject.c' line='155' column='1'/> + <parameter type-id='type-id-2' name='stop' filepath='Objects/sliceobject.c' line='155' column='1'/> + <parameter type-id='type-id-2' name='step' filepath='Objects/sliceobject.c' line='155' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PySlice_GetIndices' mangled-name='PySlice_GetIndices' filepath='Objects/sliceobject.c' line='197' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySlice_GetIndices'> + <parameter type-id='type-id-2' name='_r' filepath='Objects/sliceobject.c' line='197' column='1'/> + <parameter type-id='type-id-14' name='length' filepath='Objects/sliceobject.c' line='197' column='1'/> + <parameter type-id='type-id-13' name='start' filepath='Objects/sliceobject.c' line='198' column='1'/> + <parameter type-id='type-id-13' name='stop' filepath='Objects/sliceobject.c' line='198' column='1'/> + <parameter type-id='type-id-13' name='step' filepath='Objects/sliceobject.c' line='198' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PySlice_GetIndicesEx' mangled-name='PySlice_GetIndicesEx' filepath='Objects/sliceobject.c' line='319' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySlice_GetIndicesEx'> + <parameter type-id='type-id-2' name='_r' filepath='Objects/sliceobject.c' line='319' column='1'/> + <parameter type-id='type-id-14' name='length' filepath='Objects/sliceobject.c' line='319' column='1'/> + <parameter type-id='type-id-13' name='start' filepath='Objects/sliceobject.c' line='320' column='1'/> + <parameter type-id='type-id-13' name='stop' filepath='Objects/sliceobject.c' line='320' column='1'/> + <parameter type-id='type-id-13' name='step' filepath='Objects/sliceobject.c' line='320' column='1'/> + <parameter type-id='type-id-13' name='slicelength' filepath='Objects/sliceobject.c' line='321' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Objects/structseq.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <class-decl name='PyType_Slot' size-in-bits='128' is-struct='yes' naming-typedef-id='type-id-425' visibility='default' filepath='./Include/object.h' line='343' column='1' id='type-id-426'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='slot' type-id='type-id-8' visibility='default' filepath='./Include/object.h' line='344' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='pfunc' type-id='type-id-22' visibility='default' filepath='./Include/object.h' line='345' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='PyType_Slot' type-id='type-id-426' filepath='./Include/object.h' line='346' column='1' id='type-id-425'/> + <class-decl name='PyType_Spec' size-in-bits='256' is-struct='yes' naming-typedef-id='type-id-11' visibility='default' filepath='./Include/object.h' line='348' column='1' id='type-id-427'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='name' type-id='type-id-12' visibility='default' filepath='./Include/object.h' line='349' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='basicsize' type-id='type-id-8' visibility='default' filepath='./Include/object.h' line='350' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='96'> + <var-decl name='itemsize' type-id='type-id-8' visibility='default' filepath='./Include/object.h' line='351' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='flags' type-id='type-id-95' visibility='default' filepath='./Include/object.h' line='352' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='slots' type-id='type-id-428' visibility='default' filepath='./Include/object.h' line='353' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='PyType_Spec' type-id='type-id-427' filepath='./Include/object.h' line='354' column='1' id='type-id-11'/> + <pointer-type-def type-id='type-id-425' size-in-bits='64' id='type-id-428'/> + <pointer-type-def type-id='type-id-11' size-in-bits='64' id='type-id-429'/> + <function-decl name='_PyType_HasSubclasses' filepath='./Include/internal/pycore_typeobject.h' line='121' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyType_FromSpecWithBases' mangled-name='PyType_FromSpecWithBases' filepath='./Include/object.h' line='358' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyType_FromSpecWithBases'> + <parameter type-id='type-id-429'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <var-decl name='PyStructSequence_UnnamedField' type-id='type-id-430' mangled-name='PyStructSequence_UnnamedField' visibility='default' filepath='./Include/structseq.h' line='22' column='1' elf-symbol-id='PyStructSequence_UnnamedField'/> + <function-decl name='PyStructSequence_SetItem' mangled-name='PyStructSequence_SetItem' filepath='Objects/structseq.c' line='77' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyStructSequence_SetItem'> + <parameter type-id='type-id-2' name='op' filepath='Objects/structseq.c' line='77' column='1'/> + <parameter type-id='type-id-14' name='i' filepath='Objects/structseq.c' line='77' column='1'/> + <parameter type-id='type-id-2' name='v' filepath='Objects/structseq.c' line='77' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyStructSequence_GetItem' mangled-name='PyStructSequence_GetItem' filepath='Objects/structseq.c' line='83' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyStructSequence_GetItem'> + <parameter type-id='type-id-2' name='op' filepath='Objects/structseq.c' line='83' column='1'/> + <parameter type-id='type-id-14' name='i' filepath='Objects/structseq.c' line='83' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyStructSequence_InitType2' mangled-name='PyStructSequence_InitType2' filepath='Objects/structseq.c' line='561' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyStructSequence_InitType2'> + <parameter type-id='type-id-1' name='type' filepath='Objects/structseq.c' line='561' column='1'/> + <parameter type-id='type-id-361' name='desc' filepath='Objects/structseq.c' line='561' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyStructSequence_InitType' mangled-name='PyStructSequence_InitType' filepath='Objects/structseq.c' line='594' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyStructSequence_InitType'> + <parameter type-id='type-id-1' name='type' filepath='Objects/structseq.c' line='594' column='1'/> + <parameter type-id='type-id-361' name='desc' filepath='Objects/structseq.c' line='594' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyStructSequence_NewType' mangled-name='_PyStructSequence_NewType' filepath='Objects/structseq.c' line='632' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyStructSequence_NewType'> + <parameter type-id='type-id-361' name='desc' filepath='Objects/structseq.c' line='632' column='1'/> + <parameter type-id='type-id-28' name='tp_flags' filepath='Objects/structseq.c' line='632' column='1'/> + <return type-id='type-id-1'/> + </function-decl> + <function-decl name='PyStructSequence_NewType' mangled-name='PyStructSequence_NewType' filepath='Objects/structseq.c' line='683' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyStructSequence_NewType'> + <parameter type-id='type-id-361' name='desc' filepath='Objects/structseq.c' line='683' column='1'/> + <return type-id='type-id-1'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Objects/tupleobject.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <function-decl name='_PyObject_GC_Resize' mangled-name='_PyObject_GC_Resize' filepath='./Include/objimpl.h' line='182' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_GC_Resize'> + <parameter type-id='type-id-322'/> + <parameter type-id='type-id-14'/> + <return type-id='type-id-322'/> + </function-decl> + <var-decl name='PyTuple_Type' type-id='type-id-256' mangled-name='PyTuple_Type' visibility='default' filepath='./Include/tupleobject.h' line='23' column='1' elf-symbol-id='PyTuple_Type'/> + <var-decl name='PyTupleIter_Type' type-id='type-id-256' mangled-name='PyTupleIter_Type' visibility='default' filepath='./Include/tupleobject.h' line='24' column='1' elf-symbol-id='PyTupleIter_Type'/> + <function-decl name='PyTuple_SetItem' mangled-name='PyTuple_SetItem' filepath='Objects/tupleobject.c' line='111' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyTuple_SetItem'> + <parameter type-id='type-id-2' name='op' filepath='Objects/tupleobject.c' line='111' column='1'/> + <parameter type-id='type-id-14' name='i' filepath='Objects/tupleobject.c' line='111' column='1'/> + <parameter type-id='type-id-2' name='newitem' filepath='Objects/tupleobject.c' line='111' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyTuple_MaybeUntrack' mangled-name='_PyTuple_MaybeUntrack' filepath='Objects/tupleobject.c' line='131' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTuple_MaybeUntrack'> + <parameter type-id='type-id-2' name='op' filepath='Objects/tupleobject.c' line='131' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Objects/typeobject.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <class-decl name='_PyWeakReference' size-in-bits='512' is-struct='yes' visibility='default' filepath='./Include/cpython/weakrefobject.h' line='8' column='1' id='type-id-431'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='ob_base' type-id='type-id-345' visibility='default' filepath='./Include/cpython/weakrefobject.h' line='9' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='wr_object' type-id='type-id-2' visibility='default' filepath='./Include/cpython/weakrefobject.h' line='15' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='wr_callback' type-id='type-id-2' visibility='default' filepath='./Include/cpython/weakrefobject.h' line='18' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='hash' type-id='type-id-305' visibility='default' filepath='./Include/cpython/weakrefobject.h' line='23' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='wr_prev' type-id='type-id-432' visibility='default' filepath='./Include/cpython/weakrefobject.h' line='30' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='384'> + <var-decl name='wr_next' type-id='type-id-432' visibility='default' filepath='./Include/cpython/weakrefobject.h' line='31' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='448'> + <var-decl name='vectorcall' type-id='type-id-311' visibility='default' filepath='./Include/cpython/weakrefobject.h' line='32' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='PyWeakReference' type-id='type-id-431' filepath='./Include/weakrefobject.h' line='9' column='1' id='type-id-433'/> + <pointer-type-def type-id='type-id-433' size-in-bits='64' id='type-id-432'/> + <function-decl name='PyEval_GetGlobals' mangled-name='PyEval_GetGlobals' filepath='./Include/ceval.h' line='42' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyEval_GetGlobals'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyWeakref_ClearRef' mangled-name='_PyWeakref_ClearRef' filepath='./Include/cpython/weakrefobject.h' line='37' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyWeakref_ClearRef'> + <parameter type-id='type-id-432'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyImport_GetModule' mangled-name='PyImport_GetModule' filepath='./Include/import.h' line='36' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyImport_GetModule'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyImport_Import' mangled-name='PyImport_Import' filepath='./Include/import.h' line='73' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyImport_Import'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyDict_NewKeysForClass' filepath='./Include/internal/pycore_dict.h' line='35' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-346'/> + </function-decl> + <function-decl name='_PyDict_KeysSize' filepath='./Include/internal/pycore_dict.h' line='43' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-346'/> + <return type-id='type-id-19'/> + </function-decl> + <function-decl name='_PyMemoryView_FromBufferProc' filepath='./Include/internal/pycore_memoryobject.h' line='12' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-434'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyObject_GC_Link' filepath='./Include/internal/pycore_object.h' line='345' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyObject_InitializeDict' filepath='./Include/internal/pycore_object.h' line='360' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyObject_FreeInstanceAttributes' filepath='./Include/internal/pycore_object.h' line='408' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyObject_IsInstanceDictEmpty' filepath='./Include/internal/pycore_object.h' line='409' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyErr_FormatNote' filepath='./Include/internal/pycore_pyerrors.h' line='112' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <parameter is-variadic='yes'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_Py_Mangle' filepath='./Include/internal/pycore_symtable.h' line='108' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyStaticType_ClearWeakRefs' filepath='./Include/internal/pycore_typeobject.h' line='114' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <parameter type-id='type-id-1'/> + <return type-id='type-id-46'/> + </function-decl> + <var-decl name='_PyBufferWrapper_Type' type-id='type-id-256' mangled-name='_PyBufferWrapper_Type' visibility='default' filepath='./Include/internal/pycore_typeobject.h' line='139' column='1' elf-symbol-id='_PyBufferWrapper_Type'/> + <function-decl name='PyArg_ParseTuple' mangled-name='PyArg_ParseTuple' filepath='./Include/modsupport.h' line='27' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyArg_ParseTuple'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-12'/> + <parameter is-variadic='yes'/> + <return type-id='type-id-8'/> + </function-decl> + <var-decl name='PyType_Type' type-id='type-id-256' mangled-name='PyType_Type' visibility='default' filepath='./Include/object.h' line='388' column='1' elf-symbol-id='PyType_Type'/> + <var-decl name='PyBaseObject_Type' type-id='type-id-256' mangled-name='PyBaseObject_Type' visibility='default' filepath='./Include/object.h' line='389' column='1' elf-symbol-id='PyBaseObject_Type'/> + <var-decl name='PySuper_Type' type-id='type-id-256' mangled-name='PySuper_Type' visibility='default' filepath='./Include/object.h' line='390' column='1' elf-symbol-id='PySuper_Type'/> + <function-decl name='PyInterpreterState_Get' mangled-name='PyInterpreterState_Get' filepath='./Include/pystate.h' line='26' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInterpreterState_Get'> + <return type-id='type-id-20'/> + </function-decl> + <function-decl name='PyUnicode_IsIdentifier' mangled-name='PyUnicode_IsIdentifier' filepath='./Include/unicodeobject.h' line='1007' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_IsIdentifier'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyWeakref_NewRef' mangled-name='PyWeakref_NewRef' filepath='./Include/weakrefobject.h' line='26' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyWeakref_NewRef'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='strrchr' filepath='/usr/include/string.h' line='273' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-15'/> + </function-decl> + <function-decl name='PyType_GetDict' mangled-name='PyType_GetDict' filepath='Objects/typeobject.c' line='242' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyType_GetDict'> + <parameter type-id='type-id-1' name='self' filepath='Objects/typeobject.c' line='242' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyType_ClearCache' mangled-name='PyType_ClearCache' filepath='Objects/typeobject.c' line='661' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyType_ClearCache'> + <return type-id='type-id-95'/> + </function-decl> + <function-decl name='PyType_AddWatcher' mangled-name='PyType_AddWatcher' filepath='Objects/typeobject.c' line='683' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyType_AddWatcher'> + <parameter type-id='type-id-435' name='callback' filepath='Objects/typeobject.c' line='683' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyType_ClearWatcher' mangled-name='PyType_ClearWatcher' filepath='Objects/typeobject.c' line='713' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyType_ClearWatcher'> + <parameter type-id='type-id-8' name='watcher_id' filepath='Objects/typeobject.c' line='713' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyType_Watch' mangled-name='PyType_Watch' filepath='Objects/typeobject.c' line='726' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyType_Watch'> + <parameter type-id='type-id-8' name='watcher_id' filepath='Objects/typeobject.c' line='726' column='1'/> + <parameter type-id='type-id-2' name='obj' filepath='Objects/typeobject.c' line='726' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyType_Unwatch' mangled-name='PyType_Unwatch' filepath='Objects/typeobject.c' line='744' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyType_Unwatch'> + <parameter type-id='type-id-8' name='watcher_id' filepath='Objects/typeobject.c' line='744' column='1'/> + <parameter type-id='type-id-2' name='obj' filepath='Objects/typeobject.c' line='744' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyType_Modified' mangled-name='PyType_Modified' filepath='Objects/typeobject.c' line='760' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyType_Modified'> + <parameter type-id='type-id-1' name='type' filepath='Objects/typeobject.c' line='760' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyUnstable_Type_AssignVersionTag' mangled-name='PyUnstable_Type_AssignVersionTag' filepath='Objects/typeobject.c' line='928' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnstable_Type_AssignVersionTag'> + <parameter type-id='type-id-1' name='type' filepath='Objects/typeobject.c' line='928' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyObject_LookupSpecialId' mangled-name='_PyObject_LookupSpecialId' filepath='Objects/typeobject.c' line='2173' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_LookupSpecialId'> + <parameter type-id='type-id-2' name='self' filepath='Objects/typeobject.c' line='2173' column='1'/> + <parameter type-id='type-id-309' name='attrid' filepath='Objects/typeobject.c' line='2173' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyType_GetFlags' mangled-name='PyType_GetFlags' filepath='Objects/typeobject.c' line='3036' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyType_GetFlags'> + <parameter type-id='type-id-1' name='type' filepath='Objects/typeobject.c' line='3036' column='1'/> + <return type-id='type-id-28'/> + </function-decl> + <function-decl name='PyType_SUPPORTS_WEAKREFS' mangled-name='PyType_SUPPORTS_WEAKREFS' filepath='Objects/typeobject.c' line='3043' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyType_SUPPORTS_WEAKREFS'> + <parameter type-id='type-id-1' name='type' filepath='Objects/typeobject.c' line='3043' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyType_CalculateMetaclass' mangled-name='_PyType_CalculateMetaclass' filepath='Objects/typeobject.c' line='3051' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyType_CalculateMetaclass'> + <parameter type-id='type-id-1' name='metatype' filepath='Objects/typeobject.c' line='3051' column='1'/> + <parameter type-id='type-id-2' name='bases' filepath='Objects/typeobject.c' line='3051' column='1'/> + <return type-id='type-id-1'/> + </function-decl> + <function-decl name='PyType_FromMetaclass' mangled-name='PyType_FromMetaclass' filepath='Objects/typeobject.c' line='4481' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyType_FromMetaclass'> + <parameter type-id='type-id-1' name='metaclass' filepath='Objects/typeobject.c' line='4481' column='1'/> + <parameter type-id='type-id-2' name='module' filepath='Objects/typeobject.c' line='4481' column='1'/> + <parameter type-id='type-id-429' name='spec' filepath='Objects/typeobject.c' line='4482' column='1'/> + <parameter type-id='type-id-2' name='bases_in' filepath='Objects/typeobject.c' line='4482' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyType_FromModuleAndSpec' mangled-name='PyType_FromModuleAndSpec' filepath='Objects/typeobject.c' line='4488' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyType_FromModuleAndSpec'> + <parameter type-id='type-id-2' name='module' filepath='Objects/typeobject.c' line='4488' column='1'/> + <parameter type-id='type-id-429' name='spec' filepath='Objects/typeobject.c' line='4488' column='1'/> + <parameter type-id='type-id-2' name='bases' filepath='Objects/typeobject.c' line='4488' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyType_FromSpec' mangled-name='PyType_FromSpec' filepath='Objects/typeobject.c' line='4500' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyType_FromSpec'> + <parameter type-id='type-id-429' name='spec' filepath='Objects/typeobject.c' line='4500' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyType_GetName' mangled-name='PyType_GetName' filepath='Objects/typeobject.c' line='4506' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyType_GetName'> + <parameter type-id='type-id-1' name='type' filepath='Objects/typeobject.c' line='4506' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyType_GetSlot' mangled-name='PyType_GetSlot' filepath='Objects/typeobject.c' line='4518' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyType_GetSlot'> + <parameter type-id='type-id-1' name='type' filepath='Objects/typeobject.c' line='4518' column='1'/> + <parameter type-id='type-id-8' name='slot' filepath='Objects/typeobject.c' line='4518' column='1'/> + <return type-id='type-id-22'/> + </function-decl> + <function-decl name='PyType_GetModule' mangled-name='PyType_GetModule' filepath='Objects/typeobject.c' line='4540' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyType_GetModule'> + <parameter type-id='type-id-1' name='type' filepath='Objects/typeobject.c' line='4540' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyType_GetModuleState' mangled-name='PyType_GetModuleState' filepath='Objects/typeobject.c' line='4564' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyType_GetModuleState'> + <parameter type-id='type-id-1' name='type' filepath='Objects/typeobject.c' line='4564' column='1'/> + <return type-id='type-id-22'/> + </function-decl> + <function-decl name='PyType_GetModuleByDef' mangled-name='PyType_GetModuleByDef' filepath='Objects/typeobject.c' line='4578' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyType_GetModuleByDef'> + <parameter type-id='type-id-1' name='type' filepath='Objects/typeobject.c' line='4578' column='1'/> + <parameter type-id='type-id-399' name='def' filepath='Objects/typeobject.c' line='4578' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyObject_GetTypeData' mangled-name='PyObject_GetTypeData' filepath='Objects/typeobject.c' line='4613' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_GetTypeData'> + <parameter type-id='type-id-2' name='obj' filepath='Objects/typeobject.c' line='4613' column='1'/> + <parameter type-id='type-id-1' name='cls' filepath='Objects/typeobject.c' line='4613' column='1'/> + <return type-id='type-id-22'/> + </function-decl> + <function-decl name='PyType_GetTypeDataSize' mangled-name='PyType_GetTypeDataSize' filepath='Objects/typeobject.c' line='4620' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyType_GetTypeDataSize'> + <parameter type-id='type-id-1' name='cls' filepath='Objects/typeobject.c' line='4620' column='1'/> + <return type-id='type-id-14'/> + </function-decl> + <function-decl name='PyObject_GetItemData' mangled-name='PyObject_GetItemData' filepath='Objects/typeobject.c' line='4630' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_GetItemData'> + <parameter type-id='type-id-2' name='obj' filepath='Objects/typeobject.c' line='4630' column='1'/> + <return type-id='type-id-22'/> + </function-decl> + <function-decl name='_PyType_LookupId' mangled-name='_PyType_LookupId' filepath='Objects/typeobject.c' line='4772' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyType_LookupId'> + <parameter type-id='type-id-1' name='type' filepath='Objects/typeobject.c' line='4772' column='1'/> + <parameter type-id='type-id-309' name='name' filepath='Objects/typeobject.c' line='4772' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyDictKeys_DecRef' filepath='Objects/typeobject.c' line='4949' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-346'/> + <return type-id='type-id-46'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Objects/typevarobject.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <function-decl name='_PyArg_UnpackKeywordsWithVararg' mangled-name='_PyArg_UnpackKeywordsWithVararg' filepath='./Include/cpython/modsupport.h' line='95' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyArg_UnpackKeywordsWithVararg'> + <parameter type-id='type-id-248'/> + <parameter type-id='type-id-14'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-262'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-233'/> + <return type-id='type-id-248'/> + </function-decl> + <var-decl name='_PyTypeAlias_Type' type-id='type-id-256' visibility='default' filepath='./Include/internal/pycore_typevarobject.h' line='19' column='1'/> + </abi-instr> + <abi-instr address-size='64' path='Objects/unicodectype.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <function-decl name='_PyUnicode_ToTitlecase' mangled-name='_PyUnicode_ToTitlecase' filepath='Objects/unicodectype.c' line='62' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_ToTitlecase'> + <parameter type-id='type-id-250' name='ch' filepath='Objects/unicodectype.c' line='62' column='1'/> + <return type-id='type-id-250'/> + </function-decl> + <function-decl name='_PyUnicode_ToDigit' mangled-name='_PyUnicode_ToDigit' filepath='Objects/unicodectype.c' line='121' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_ToDigit'> + <parameter type-id='type-id-250' name='ch' filepath='Objects/unicodectype.c' line='121' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyUnicode_ToUppercase' mangled-name='_PyUnicode_ToUppercase' filepath='Objects/unicodectype.c' line='188' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_ToUppercase'> + <parameter type-id='type-id-250' name='ch' filepath='Objects/unicodectype.c' line='188' column='1'/> + <return type-id='type-id-250'/> + </function-decl> + <function-decl name='_PyUnicode_ToLowercase' mangled-name='_PyUnicode_ToLowercase' filepath='Objects/unicodectype.c' line='200' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_ToLowercase'> + <parameter type-id='type-id-250' name='ch' filepath='Objects/unicodectype.c' line='200' column='1'/> + <return type-id='type-id-250'/> + </function-decl> + <function-decl name='_PyUnicode_ToNumeric' mangled-name='_PyUnicode_ToNumeric' filepath='Objects/unicodetype_db.h' line='4243' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_ToNumeric'> + <parameter type-id='type-id-250' name='ch' filepath='Objects/unicodetype_db.h' line='4243' column='1'/> + <return type-id='type-id-251'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Objects/unicodeobject.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <array-type-def dimensions='1' type-id='type-id-382' size-in-bits='1024' id='type-id-436'> + <subrange length='128' type-id='type-id-28' id='type-id-437'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-382' size-in-bits='infinite' id='type-id-438'> + <subrange length='infinite' id='type-id-225'/> + </array-type-def> + <qualified-type-def type-id='type-id-250' const='yes' id='type-id-439'/> + <function-decl name='_PyCodec_Lookup' mangled-name='_PyCodec_Lookup' filepath='./Include/codecs.h' line='57' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyCodec_Lookup'> + <parameter type-id='type-id-12'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyCodec_Encode' mangled-name='PyCodec_Encode' filepath='./Include/codecs.h' line='87' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCodec_Encode'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-12'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyCodec_Decode' mangled-name='PyCodec_Decode' filepath='./Include/codecs.h' line='103' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCodec_Decode'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-12'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyCodec_EncodeText' mangled-name='_PyCodec_EncodeText' filepath='./Include/codecs.h' line='128' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyCodec_EncodeText'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-12'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyCodec_DecodeText' mangled-name='_PyCodec_DecodeText' filepath='./Include/codecs.h' line='134' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyCodec_DecodeText'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-12'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyCodec_LookupError' mangled-name='PyCodec_LookupError' filepath='./Include/codecs.h' line='219' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCodec_LookupError'> + <parameter type-id='type-id-12'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyCodec_StrictErrors' mangled-name='PyCodec_StrictErrors' filepath='./Include/codecs.h' line='222' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCodec_StrictErrors'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyInterpreterState_GetConfig' mangled-name='_PyInterpreterState_GetConfig' filepath='./Include/cpython/pystate.h' line='331' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyInterpreterState_GetConfig'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-260'/> + </function-decl> + <function-decl name='_PyUnicode_FormatAdvancedWriter' mangled-name='_PyUnicode_FormatAdvancedWriter' filepath='./Include/cpython/unicodeobject.h' line='603' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_FormatAdvancedWriter'> + <parameter type-id='type-id-332'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-14'/> + <parameter type-id='type-id-14'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyUnicode_IsLowercase' mangled-name='_PyUnicode_IsLowercase' filepath='./Include/cpython/unicodeobject.h' line='802' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_IsLowercase'> + <parameter type-id='type-id-250'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyUnicode_IsUppercase' mangled-name='_PyUnicode_IsUppercase' filepath='./Include/cpython/unicodeobject.h' line='806' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_IsUppercase'> + <parameter type-id='type-id-250'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyUnicode_IsTitlecase' mangled-name='_PyUnicode_IsTitlecase' filepath='./Include/cpython/unicodeobject.h' line='810' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_IsTitlecase'> + <parameter type-id='type-id-250'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyUnicode_IsXidStart' mangled-name='_PyUnicode_IsXidStart' filepath='./Include/cpython/unicodeobject.h' line='814' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_IsXidStart'> + <parameter type-id='type-id-250'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyUnicode_IsXidContinue' mangled-name='_PyUnicode_IsXidContinue' filepath='./Include/cpython/unicodeobject.h' line='818' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_IsXidContinue'> + <parameter type-id='type-id-250'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyUnicode_IsWhitespace' mangled-name='_PyUnicode_IsWhitespace' filepath='./Include/cpython/unicodeobject.h' line='822' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_IsWhitespace'> + <parameter type-id='type-id-439'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyUnicode_IsLinebreak' mangled-name='_PyUnicode_IsLinebreak' filepath='./Include/cpython/unicodeobject.h' line='826' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_IsLinebreak'> + <parameter type-id='type-id-439'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyUnicode_ToLowerFull' mangled-name='_PyUnicode_ToLowerFull' filepath='./Include/cpython/unicodeobject.h' line='842' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_ToLowerFull'> + <parameter type-id='type-id-250'/> + <parameter type-id='type-id-440'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyUnicode_ToTitleFull' mangled-name='_PyUnicode_ToTitleFull' filepath='./Include/cpython/unicodeobject.h' line='847' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_ToTitleFull'> + <parameter type-id='type-id-250'/> + <parameter type-id='type-id-440'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyUnicode_ToUpperFull' mangled-name='_PyUnicode_ToUpperFull' filepath='./Include/cpython/unicodeobject.h' line='852' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_ToUpperFull'> + <parameter type-id='type-id-250'/> + <parameter type-id='type-id-440'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyUnicode_ToFoldedFull' mangled-name='_PyUnicode_ToFoldedFull' filepath='./Include/cpython/unicodeobject.h' line='857' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_ToFoldedFull'> + <parameter type-id='type-id-250'/> + <parameter type-id='type-id-440'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyUnicode_IsCaseIgnorable' mangled-name='_PyUnicode_IsCaseIgnorable' filepath='./Include/cpython/unicodeobject.h' line='862' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_IsCaseIgnorable'> + <parameter type-id='type-id-250'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyUnicode_IsCased' mangled-name='_PyUnicode_IsCased' filepath='./Include/cpython/unicodeobject.h' line='866' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_IsCased'> + <parameter type-id='type-id-250'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyUnicode_ToDecimalDigit' mangled-name='_PyUnicode_ToDecimalDigit' filepath='./Include/cpython/unicodeobject.h' line='870' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_ToDecimalDigit'> + <parameter type-id='type-id-250'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyUnicode_IsDecimalDigit' mangled-name='_PyUnicode_IsDecimalDigit' filepath='./Include/cpython/unicodeobject.h' line='882' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_IsDecimalDigit'> + <parameter type-id='type-id-250'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyUnicode_IsDigit' mangled-name='_PyUnicode_IsDigit' filepath='./Include/cpython/unicodeobject.h' line='886' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_IsDigit'> + <parameter type-id='type-id-250'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyUnicode_IsNumeric' mangled-name='_PyUnicode_IsNumeric' filepath='./Include/cpython/unicodeobject.h' line='890' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_IsNumeric'> + <parameter type-id='type-id-250'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyUnicode_IsAlpha' mangled-name='_PyUnicode_IsAlpha' filepath='./Include/cpython/unicodeobject.h' line='898' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_IsAlpha'> + <parameter type-id='type-id-250'/> + <return type-id='type-id-8'/> + </function-decl> + <var-decl name='_Py_ascii_whitespace' type-id='type-id-438' mangled-name='_Py_ascii_whitespace' visibility='default' filepath='./Include/cpython/unicodeobject.h' line='903' column='1' elf-symbol-id='_Py_ascii_whitespace'/> + <function-decl name='_Py_DecodeLocaleEx' mangled-name='_Py_DecodeLocaleEx' filepath='./Include/internal/pycore_fileutils.h' line='32' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_DecodeLocaleEx'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-235'/> + <parameter type-id='type-id-441'/> + <parameter type-id='type-id-252'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-442'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_Py_EncodeLocaleEx' mangled-name='_Py_EncodeLocaleEx' filepath='./Include/internal/pycore_fileutils.h' line='40' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_EncodeLocaleEx'> + <parameter type-id='type-id-16'/> + <parameter type-id='type-id-239'/> + <parameter type-id='type-id-441'/> + <parameter type-id='type-id-252'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-442'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_Py_DumpPathConfig' filepath='./Include/internal/pycore_initconfig.h' line='167' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-177'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_Py_SetFileSystemEncoding' filepath='./Include/internal/pycore_pylifecycle.h' line='17' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-12'/> + <return type-id='type-id-8'/> + </function-decl> + <var-decl name='_PyUnicodeASCIIIter_Type' type-id='type-id-256' visibility='default' filepath='./Include/internal/pycore_unicodeobject.h' line='25' column='1'/> + <function-decl name='PyOS_FSPath' mangled-name='PyOS_FSPath' filepath='./Include/osmodule.h' line='11' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyOS_FSPath'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <var-decl name='PyUnicode_Type' type-id='type-id-256' mangled-name='PyUnicode_Type' visibility='default' filepath='./Include/unicodeobject.h' line='111' column='1' elf-symbol-id='PyUnicode_Type'/> + <var-decl name='PyUnicodeIter_Type' type-id='type-id-256' mangled-name='PyUnicodeIter_Type' visibility='default' filepath='./Include/unicodeobject.h' line='112' column='1' elf-symbol-id='PyUnicodeIter_Type'/> + <function-decl name='wcscmp' filepath='/usr/include/wchar.h' line='106' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-16'/> + <parameter type-id='type-id-16'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='wmemchr' filepath='/usr/include/wchar.h' line='254' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-16'/> + <parameter type-id='type-id-422'/> + <parameter type-id='type-id-19'/> + <return type-id='type-id-52'/> + </function-decl> + <function-decl name='wmemcmp' filepath='/usr/include/wchar.h' line='259' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-16'/> + <parameter type-id='type-id-16'/> + <parameter type-id='type-id-19'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_Py_GetErrorHandler' mangled-name='_Py_GetErrorHandler' filepath='Objects/unicodeobject.c' line='396' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_GetErrorHandler'> + <parameter type-id='type-id-12' name='errors' filepath='Objects/unicodeobject.c' line='396' column='1'/> + <return type-id='type-id-442'/> + </function-decl> + <function-decl name='_PyUnicode_FastCopyCharacters' mangled-name='_PyUnicode_FastCopyCharacters' filepath='Objects/unicodeobject.c' line='1440' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_FastCopyCharacters'> + <parameter type-id='type-id-2' name='to' filepath='Objects/unicodeobject.c' line='1441' column='1'/> + <parameter type-id='type-id-14' name='to_start' filepath='Objects/unicodeobject.c' line='1441' column='1'/> + <parameter type-id='type-id-2' name='from' filepath='Objects/unicodeobject.c' line='1442' column='1'/> + <parameter type-id='type-id-14' name='from_start' filepath='Objects/unicodeobject.c' line='1442' column='1'/> + <parameter type-id='type-id-14' name='how_many' filepath='Objects/unicodeobject.c' line='1442' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyUnicode_CopyCharacters' mangled-name='PyUnicode_CopyCharacters' filepath='Objects/unicodeobject.c' line='1448' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_CopyCharacters'> + <parameter type-id='type-id-2' name='to' filepath='Objects/unicodeobject.c' line='1448' column='1'/> + <parameter type-id='type-id-14' name='to_start' filepath='Objects/unicodeobject.c' line='1448' column='1'/> + <parameter type-id='type-id-2' name='from' filepath='Objects/unicodeobject.c' line='1449' column='1'/> + <parameter type-id='type-id-14' name='from_start' filepath='Objects/unicodeobject.c' line='1449' column='1'/> + <parameter type-id='type-id-14' name='how_many' filepath='Objects/unicodeobject.c' line='1450' column='1'/> + <return type-id='type-id-14'/> + </function-decl> + <function-decl name='PyUnicode_Resize' mangled-name='PyUnicode_Resize' filepath='Objects/unicodeobject.c' line='1649' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_Resize'> + <parameter type-id='type-id-233' name='p_unicode' filepath='Objects/unicodeobject.c' line='1649' column='1'/> + <parameter type-id='type-id-14' name='length' filepath='Objects/unicodeobject.c' line='1649' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyUnicode_FromWideChar' mangled-name='PyUnicode_FromWideChar' filepath='Objects/unicodeobject.c' line='1750' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_FromWideChar'> + <parameter type-id='type-id-16' name='u' filepath='Objects/unicodeobject.c' line='1750' column='1'/> + <parameter type-id='type-id-14' name='size' filepath='Objects/unicodeobject.c' line='1750' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyUnicode_FromKindAndData' mangled-name='PyUnicode_FromKindAndData' filepath='Objects/unicodeobject.c' line='2053' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_FromKindAndData'> + <parameter type-id='type-id-8' name='kind' filepath='Objects/unicodeobject.c' line='2053' column='1'/> + <parameter type-id='type-id-22' name='buffer' filepath='Objects/unicodeobject.c' line='2053' column='1'/> + <parameter type-id='type-id-14' name='size' filepath='Objects/unicodeobject.c' line='2053' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyUnicode_FindMaxChar' mangled-name='_PyUnicode_FindMaxChar' filepath='Objects/unicodeobject.c' line='2073' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_FindMaxChar'> + <parameter type-id='type-id-2' name='unicode' filepath='Objects/unicodeobject.c' line='2073' column='1'/> + <parameter type-id='type-id-14' name='start' filepath='Objects/unicodeobject.c' line='2073' column='1'/> + <parameter type-id='type-id-14' name='end' filepath='Objects/unicodeobject.c' line='2073' column='1'/> + <return type-id='type-id-250'/> + </function-decl> + <function-decl name='PyUnicode_AsUCS4' mangled-name='PyUnicode_AsUCS4' filepath='Objects/unicodeobject.c' line='2273' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_AsUCS4'> + <parameter type-id='type-id-2' name='string' filepath='Objects/unicodeobject.c' line='2273' column='1'/> + <parameter type-id='type-id-440' name='target' filepath='Objects/unicodeobject.c' line='2273' column='1'/> + <parameter type-id='type-id-14' name='targetsize' filepath='Objects/unicodeobject.c' line='2273' column='1'/> + <parameter type-id='type-id-8' name='copy_null' filepath='Objects/unicodeobject.c' line='2274' column='1'/> + <return type-id='type-id-440'/> + </function-decl> + <function-decl name='PyUnicode_AsUCS4Copy' mangled-name='PyUnicode_AsUCS4Copy' filepath='Objects/unicodeobject.c' line='2284' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_AsUCS4Copy'> + <parameter type-id='type-id-2' name='string' filepath='Objects/unicodeobject.c' line='2284' column='1'/> + <return type-id='type-id-440'/> + </function-decl> + <function-decl name='PyUnicode_AsWideChar' mangled-name='PyUnicode_AsWideChar' filepath='Objects/unicodeobject.c' line='2913' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_AsWideChar'> + <parameter type-id='type-id-2' name='unicode' filepath='Objects/unicodeobject.c' line='2913' column='1'/> + <parameter type-id='type-id-52' name='w' filepath='Objects/unicodeobject.c' line='2914' column='1'/> + <parameter type-id='type-id-14' name='size' filepath='Objects/unicodeobject.c' line='2915' column='1'/> + <return type-id='type-id-14'/> + </function-decl> + <function-decl name='PyUnicode_AsWideCharString' mangled-name='PyUnicode_AsWideCharString' filepath='Objects/unicodeobject.c' line='2955' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_AsWideCharString'> + <parameter type-id='type-id-2' name='unicode' filepath='Objects/unicodeobject.c' line='2955' column='1'/> + <parameter type-id='type-id-13' name='size' filepath='Objects/unicodeobject.c' line='2956' column='1'/> + <return type-id='type-id-52'/> + </function-decl> + <function-decl name='_PyUnicode_WideCharString_Converter' mangled-name='_PyUnicode_WideCharString_Converter' filepath='Objects/unicodeobject.c' line='3003' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_WideCharString_Converter'> + <parameter type-id='type-id-2' name='obj' filepath='Objects/unicodeobject.c' line='3003' column='1'/> + <parameter type-id='type-id-22' name='ptr' filepath='Objects/unicodeobject.c' line='3003' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyUnicode_WideCharString_Opt_Converter' mangled-name='_PyUnicode_WideCharString_Opt_Converter' filepath='Objects/unicodeobject.c' line='3025' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_WideCharString_Opt_Converter'> + <parameter type-id='type-id-2' name='obj' filepath='Objects/unicodeobject.c' line='3025' column='1'/> + <parameter type-id='type-id-22' name='ptr' filepath='Objects/unicodeobject.c' line='3025' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyUnicode_FromOrdinal' mangled-name='PyUnicode_FromOrdinal' filepath='Objects/unicodeobject.c' line='3051' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_FromOrdinal'> + <parameter type-id='type-id-8' name='ordinal' filepath='Objects/unicodeobject.c' line='3051' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyUnicode_FromObject' mangled-name='PyUnicode_FromObject' filepath='Objects/unicodeobject.c' line='3063' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_FromObject'> + <parameter type-id='type-id-2' name='obj' filepath='Objects/unicodeobject.c' line='3063' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyUnicode_AsDecodedObject' mangled-name='PyUnicode_AsDecodedObject' filepath='Objects/unicodeobject.c' line='3274' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_AsDecodedObject'> + <parameter type-id='type-id-2' name='unicode' filepath='Objects/unicodeobject.c' line='3274' column='1'/> + <parameter type-id='type-id-12' name='encoding' filepath='Objects/unicodeobject.c' line='3275' column='1'/> + <parameter type-id='type-id-12' name='errors' filepath='Objects/unicodeobject.c' line='3276' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyUnicode_AsDecodedUnicode' mangled-name='PyUnicode_AsDecodedUnicode' filepath='Objects/unicodeobject.c' line='3296' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_AsDecodedUnicode'> + <parameter type-id='type-id-2' name='unicode' filepath='Objects/unicodeobject.c' line='3296' column='1'/> + <parameter type-id='type-id-12' name='encoding' filepath='Objects/unicodeobject.c' line='3297' column='1'/> + <parameter type-id='type-id-12' name='errors' filepath='Objects/unicodeobject.c' line='3298' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyUnicode_AsEncodedObject' mangled-name='PyUnicode_AsEncodedObject' filepath='Objects/unicodeobject.c' line='3335' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_AsEncodedObject'> + <parameter type-id='type-id-2' name='unicode' filepath='Objects/unicodeobject.c' line='3335' column='1'/> + <parameter type-id='type-id-12' name='encoding' filepath='Objects/unicodeobject.c' line='3336' column='1'/> + <parameter type-id='type-id-12' name='errors' filepath='Objects/unicodeobject.c' line='3337' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyUnicode_EncodeLocale' mangled-name='PyUnicode_EncodeLocale' filepath='Objects/unicodeobject.c' line='3417' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_EncodeLocale'> + <parameter type-id='type-id-2' name='unicode' filepath='Objects/unicodeobject.c' line='3417' column='1'/> + <parameter type-id='type-id-12' name='errors' filepath='Objects/unicodeobject.c' line='3417' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyUnicode_EncodeFSDefault' mangled-name='PyUnicode_EncodeFSDefault' filepath='Objects/unicodeobject.c' line='3424' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_EncodeFSDefault'> + <parameter type-id='type-id-2' name='unicode' filepath='Objects/unicodeobject.c' line='3424' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyUnicode_AsEncodedUnicode' mangled-name='PyUnicode_AsEncodedUnicode' filepath='Objects/unicodeobject.c' line='3558' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_AsEncodedUnicode'> + <parameter type-id='type-id-2' name='unicode' filepath='Objects/unicodeobject.c' line='3558' column='1'/> + <parameter type-id='type-id-12' name='encoding' filepath='Objects/unicodeobject.c' line='3559' column='1'/> + <parameter type-id='type-id-12' name='errors' filepath='Objects/unicodeobject.c' line='3560' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyUnicode_DecodeLocaleAndSize' mangled-name='PyUnicode_DecodeLocaleAndSize' filepath='Objects/unicodeobject.c' line='3638' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_DecodeLocaleAndSize'> + <parameter type-id='type-id-12' name='str' filepath='Objects/unicodeobject.c' line='3638' column='1'/> + <parameter type-id='type-id-14' name='len' filepath='Objects/unicodeobject.c' line='3638' column='1'/> + <parameter type-id='type-id-12' name='errors' filepath='Objects/unicodeobject.c' line='3639' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyUnicode_DecodeLocale' mangled-name='PyUnicode_DecodeLocale' filepath='Objects/unicodeobject.c' line='3646' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_DecodeLocale'> + <parameter type-id='type-id-12' name='str' filepath='Objects/unicodeobject.c' line='3646' column='1'/> + <parameter type-id='type-id-12' name='errors' filepath='Objects/unicodeobject.c' line='3646' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyUnicode_DecodeFSDefaultAndSize' mangled-name='PyUnicode_DecodeFSDefaultAndSize' filepath='Objects/unicodeobject.c' line='3661' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_DecodeFSDefaultAndSize'> + <parameter type-id='type-id-12' name='s' filepath='Objects/unicodeobject.c' line='3661' column='1'/> + <parameter type-id='type-id-14' name='size' filepath='Objects/unicodeobject.c' line='3661' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyUnicode_FSConverter' mangled-name='PyUnicode_FSConverter' filepath='Objects/unicodeobject.c' line='3697' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_FSConverter'> + <parameter type-id='type-id-2' name='arg' filepath='Objects/unicodeobject.c' line='3697' column='1'/> + <parameter type-id='type-id-22' name='addr' filepath='Objects/unicodeobject.c' line='3697' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyUnicode_FSDecoder' mangled-name='PyUnicode_FSDecoder' filepath='Objects/unicodeobject.c' line='3737' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_FSDecoder'> + <parameter type-id='type-id-2' name='arg' filepath='Objects/unicodeobject.c' line='3737' column='1'/> + <parameter type-id='type-id-22' name='addr' filepath='Objects/unicodeobject.c' line='3737' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyUnicode_GetSize' mangled-name='PyUnicode_GetSize' filepath='Objects/unicodeobject.c' line='3817' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_GetSize'> + <parameter type-id='type-id-2' name='unicode' filepath='Objects/unicodeobject.c' line='3817' column='1'/> + <return type-id='type-id-14'/> + </function-decl> + <function-decl name='PyUnicode_WriteChar' mangled-name='PyUnicode_WriteChar' filepath='Objects/unicodeobject.c' line='3854' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_WriteChar'> + <parameter type-id='type-id-2' name='unicode' filepath='Objects/unicodeobject.c' line='3854' column='1'/> + <parameter type-id='type-id-14' name='index' filepath='Objects/unicodeobject.c' line='3854' column='1'/> + <parameter type-id='type-id-250' name='ch' filepath='Objects/unicodeobject.c' line='3854' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyUnicode_DecodeUTF7' mangled-name='PyUnicode_DecodeUTF7' filepath='Objects/unicodeobject.c' line='4216' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_DecodeUTF7'> + <parameter type-id='type-id-12' name='s' filepath='Objects/unicodeobject.c' line='4216' column='1'/> + <parameter type-id='type-id-14' name='size' filepath='Objects/unicodeobject.c' line='4217' column='1'/> + <parameter type-id='type-id-12' name='errors' filepath='Objects/unicodeobject.c' line='4218' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyUnicode_DecodeUTF7Stateful' mangled-name='PyUnicode_DecodeUTF7Stateful' filepath='Objects/unicodeobject.c' line='4231' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_DecodeUTF7Stateful'> + <parameter type-id='type-id-12' name='s' filepath='Objects/unicodeobject.c' line='4231' column='1'/> + <parameter type-id='type-id-14' name='size' filepath='Objects/unicodeobject.c' line='4232' column='1'/> + <parameter type-id='type-id-12' name='errors' filepath='Objects/unicodeobject.c' line='4233' column='1'/> + <parameter type-id='type-id-13' name='consumed' filepath='Objects/unicodeobject.c' line='4234' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyUnicode_EncodeUTF7' mangled-name='_PyUnicode_EncodeUTF7' filepath='Objects/unicodeobject.c' line='4429' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_EncodeUTF7'> + <parameter type-id='type-id-2' name='str' filepath='Objects/unicodeobject.c' line='4429' column='1'/> + <parameter type-id='type-id-8' name='base64SetO' filepath='Objects/unicodeobject.c' line='4430' column='1'/> + <parameter type-id='type-id-8' name='base64WhiteSpace' filepath='Objects/unicodeobject.c' line='4431' column='1'/> + <parameter type-id='type-id-12' name='errors' filepath='Objects/unicodeobject.c' line='4432' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_Py_DecodeUTF8Ex' mangled-name='_Py_DecodeUTF8Ex' filepath='Objects/unicodeobject.c' line='4797' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_DecodeUTF8Ex'> + <parameter type-id='type-id-12' name='s' filepath='Objects/unicodeobject.c' line='4797' column='1'/> + <parameter type-id='type-id-14' name='size' filepath='Objects/unicodeobject.c' line='4797' column='1'/> + <parameter type-id='type-id-235' name='wstr' filepath='Objects/unicodeobject.c' line='4797' column='1'/> + <parameter type-id='type-id-441' name='wlen' filepath='Objects/unicodeobject.c' line='4797' column='1'/> + <parameter type-id='type-id-252' name='reason' filepath='Objects/unicodeobject.c' line='4798' column='1'/> + <parameter type-id='type-id-442' name='errors' filepath='Objects/unicodeobject.c' line='4798' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_Py_DecodeUTF8_surrogateescape' mangled-name='_Py_DecodeUTF8_surrogateescape' filepath='Objects/unicodeobject.c' line='4906' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_DecodeUTF8_surrogateescape'> + <parameter type-id='type-id-12' name='arg' filepath='Objects/unicodeobject.c' line='4906' column='1'/> + <parameter type-id='type-id-14' name='arglen' filepath='Objects/unicodeobject.c' line='4906' column='1'/> + <parameter type-id='type-id-441' name='wlen' filepath='Objects/unicodeobject.c' line='4907' column='1'/> + <return type-id='type-id-52'/> + </function-decl> + <function-decl name='_Py_EncodeUTF8Ex' mangled-name='_Py_EncodeUTF8Ex' filepath='Objects/unicodeobject.c' line='4936' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_EncodeUTF8Ex'> + <parameter type-id='type-id-16' name='text' filepath='Objects/unicodeobject.c' line='4936' column='1'/> + <parameter type-id='type-id-239' name='str' filepath='Objects/unicodeobject.c' line='4936' column='1'/> + <parameter type-id='type-id-441' name='error_pos' filepath='Objects/unicodeobject.c' line='4936' column='1'/> + <parameter type-id='type-id-252' name='reason' filepath='Objects/unicodeobject.c' line='4937' column='1'/> + <parameter type-id='type-id-8' name='raw_malloc' filepath='Objects/unicodeobject.c' line='4937' column='1'/> + <parameter type-id='type-id-442' name='errors' filepath='Objects/unicodeobject.c' line='4937' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyUnicode_DecodeUTF32' mangled-name='PyUnicode_DecodeUTF32' filepath='Objects/unicodeobject.c' line='5178' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_DecodeUTF32'> + <parameter type-id='type-id-12' name='s' filepath='Objects/unicodeobject.c' line='5178' column='1'/> + <parameter type-id='type-id-14' name='size' filepath='Objects/unicodeobject.c' line='5179' column='1'/> + <parameter type-id='type-id-12' name='errors' filepath='Objects/unicodeobject.c' line='5180' column='1'/> + <parameter type-id='type-id-179' name='byteorder' filepath='Objects/unicodeobject.c' line='5181' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyUnicode_DecodeUTF32Stateful' mangled-name='PyUnicode_DecodeUTF32Stateful' filepath='Objects/unicodeobject.c' line='5187' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_DecodeUTF32Stateful'> + <parameter type-id='type-id-12' name='s' filepath='Objects/unicodeobject.c' line='5187' column='1'/> + <parameter type-id='type-id-14' name='size' filepath='Objects/unicodeobject.c' line='5188' column='1'/> + <parameter type-id='type-id-12' name='errors' filepath='Objects/unicodeobject.c' line='5189' column='1'/> + <parameter type-id='type-id-179' name='byteorder' filepath='Objects/unicodeobject.c' line='5190' column='1'/> + <parameter type-id='type-id-13' name='consumed' filepath='Objects/unicodeobject.c' line='5191' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyUnicode_EncodeUTF32' mangled-name='_PyUnicode_EncodeUTF32' filepath='Objects/unicodeobject.c' line='5332' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_EncodeUTF32'> + <parameter type-id='type-id-2' name='str' filepath='Objects/unicodeobject.c' line='5332' column='1'/> + <parameter type-id='type-id-12' name='errors' filepath='Objects/unicodeobject.c' line='5333' column='1'/> + <parameter type-id='type-id-8' name='byteorder' filepath='Objects/unicodeobject.c' line='5334' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyUnicode_AsUTF32String' mangled-name='PyUnicode_AsUTF32String' filepath='Objects/unicodeobject.c' line='5477' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_AsUTF32String'> + <parameter type-id='type-id-2' name='unicode' filepath='Objects/unicodeobject.c' line='5477' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyUnicode_DecodeUTF16' mangled-name='PyUnicode_DecodeUTF16' filepath='Objects/unicodeobject.c' line='5485' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_DecodeUTF16'> + <parameter type-id='type-id-12' name='s' filepath='Objects/unicodeobject.c' line='5485' column='1'/> + <parameter type-id='type-id-14' name='size' filepath='Objects/unicodeobject.c' line='5486' column='1'/> + <parameter type-id='type-id-12' name='errors' filepath='Objects/unicodeobject.c' line='5487' column='1'/> + <parameter type-id='type-id-179' name='byteorder' filepath='Objects/unicodeobject.c' line='5488' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyUnicode_DecodeUTF16Stateful' mangled-name='PyUnicode_DecodeUTF16Stateful' filepath='Objects/unicodeobject.c' line='5494' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_DecodeUTF16Stateful'> + <parameter type-id='type-id-12' name='s' filepath='Objects/unicodeobject.c' line='5494' column='1'/> + <parameter type-id='type-id-14' name='size' filepath='Objects/unicodeobject.c' line='5495' column='1'/> + <parameter type-id='type-id-12' name='errors' filepath='Objects/unicodeobject.c' line='5496' column='1'/> + <parameter type-id='type-id-179' name='byteorder' filepath='Objects/unicodeobject.c' line='5497' column='1'/> + <parameter type-id='type-id-13' name='consumed' filepath='Objects/unicodeobject.c' line='5498' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyUnicode_EncodeUTF16' mangled-name='_PyUnicode_EncodeUTF16' filepath='Objects/unicodeobject.c' line='5649' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_EncodeUTF16'> + <parameter type-id='type-id-2' name='str' filepath='Objects/unicodeobject.c' line='5649' column='1'/> + <parameter type-id='type-id-12' name='errors' filepath='Objects/unicodeobject.c' line='5650' column='1'/> + <parameter type-id='type-id-8' name='byteorder' filepath='Objects/unicodeobject.c' line='5651' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyUnicode_AsUTF16String' mangled-name='PyUnicode_AsUTF16String' filepath='Objects/unicodeobject.c' line='5813' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_AsUTF16String'> + <parameter type-id='type-id-2' name='unicode' filepath='Objects/unicodeobject.c' line='5813' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyUnicode_DecodeUnicodeEscapeStateful' mangled-name='_PyUnicode_DecodeUnicodeEscapeStateful' filepath='Objects/unicodeobject.c' line='6069' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_DecodeUnicodeEscapeStateful'> + <parameter type-id='type-id-12' name='s' filepath='Objects/unicodeobject.c' line='6069' column='1'/> + <parameter type-id='type-id-14' name='size' filepath='Objects/unicodeobject.c' line='6070' column='1'/> + <parameter type-id='type-id-12' name='errors' filepath='Objects/unicodeobject.c' line='6071' column='1'/> + <parameter type-id='type-id-13' name='consumed' filepath='Objects/unicodeobject.c' line='6072' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyUnicode_DecodeUnicodeEscape' mangled-name='PyUnicode_DecodeUnicodeEscape' filepath='Objects/unicodeobject.c' line='6105' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_DecodeUnicodeEscape'> + <parameter type-id='type-id-12' name='s' filepath='Objects/unicodeobject.c' line='6105' column='1'/> + <parameter type-id='type-id-14' name='size' filepath='Objects/unicodeobject.c' line='6106' column='1'/> + <parameter type-id='type-id-12' name='errors' filepath='Objects/unicodeobject.c' line='6107' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyUnicode_AsUnicodeEscapeString' mangled-name='PyUnicode_AsUnicodeEscapeString' filepath='Objects/unicodeobject.c' line='6115' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_AsUnicodeEscapeString'> + <parameter type-id='type-id-2' name='unicode' filepath='Objects/unicodeobject.c' line='6115' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyUnicode_DecodeRawUnicodeEscapeStateful' mangled-name='_PyUnicode_DecodeRawUnicodeEscapeStateful' filepath='Objects/unicodeobject.c' line='6232' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_DecodeRawUnicodeEscapeStateful'> + <parameter type-id='type-id-12' name='s' filepath='Objects/unicodeobject.c' line='6232' column='1'/> + <parameter type-id='type-id-14' name='size' filepath='Objects/unicodeobject.c' line='6233' column='1'/> + <parameter type-id='type-id-12' name='errors' filepath='Objects/unicodeobject.c' line='6234' column='1'/> + <parameter type-id='type-id-13' name='consumed' filepath='Objects/unicodeobject.c' line='6235' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyUnicode_DecodeRawUnicodeEscape' mangled-name='PyUnicode_DecodeRawUnicodeEscape' filepath='Objects/unicodeobject.c' line='6368' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_DecodeRawUnicodeEscape'> + <parameter type-id='type-id-12' name='s' filepath='Objects/unicodeobject.c' line='6368' column='1'/> + <parameter type-id='type-id-14' name='size' filepath='Objects/unicodeobject.c' line='6369' column='1'/> + <parameter type-id='type-id-12' name='errors' filepath='Objects/unicodeobject.c' line='6370' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyUnicode_AsRawUnicodeEscapeString' mangled-name='PyUnicode_AsRawUnicodeEscapeString' filepath='Objects/unicodeobject.c' line='6377' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_AsRawUnicodeEscapeString'> + <parameter type-id='type-id-2' name='unicode' filepath='Objects/unicodeobject.c' line='6377' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyUnicode_AsLatin1String' mangled-name='_PyUnicode_AsLatin1String' filepath='Objects/unicodeobject.c' line='6741' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_AsLatin1String'> + <parameter type-id='type-id-2' name='unicode' filepath='Objects/unicodeobject.c' line='6741' column='1'/> + <parameter type-id='type-id-12' name='errors' filepath='Objects/unicodeobject.c' line='6741' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyUnicode_AsLatin1String' mangled-name='PyUnicode_AsLatin1String' filepath='Objects/unicodeobject.c' line='6758' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_AsLatin1String'> + <parameter type-id='type-id-2' name='unicode' filepath='Objects/unicodeobject.c' line='6758' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyUnicode_DecodeCharmap' mangled-name='PyUnicode_DecodeCharmap' filepath='Objects/unicodeobject.c' line='7807' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_DecodeCharmap'> + <parameter type-id='type-id-12' name='s' filepath='Objects/unicodeobject.c' line='7807' column='1'/> + <parameter type-id='type-id-14' name='size' filepath='Objects/unicodeobject.c' line='7808' column='1'/> + <parameter type-id='type-id-2' name='mapping' filepath='Objects/unicodeobject.c' line='7809' column='1'/> + <parameter type-id='type-id-12' name='errors' filepath='Objects/unicodeobject.c' line='7810' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyUnicode_BuildEncodingMap' mangled-name='PyUnicode_BuildEncodingMap' filepath='Objects/unicodeobject.c' line='7883' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_BuildEncodingMap'> + <parameter type-id='type-id-2' name='string' filepath='Objects/unicodeobject.c' line='7883' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyUnicode_EncodeCharmap' mangled-name='_PyUnicode_EncodeCharmap' filepath='Objects/unicodeobject.c' line='8295' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_EncodeCharmap'> + <parameter type-id='type-id-2' name='unicode' filepath='Objects/unicodeobject.c' line='8295' column='1'/> + <parameter type-id='type-id-2' name='mapping' filepath='Objects/unicodeobject.c' line='8296' column='1'/> + <parameter type-id='type-id-12' name='errors' filepath='Objects/unicodeobject.c' line='8297' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyUnicode_AsCharmapString' mangled-name='PyUnicode_AsCharmapString' filepath='Objects/unicodeobject.c' line='8364' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_AsCharmapString'> + <parameter type-id='type-id-2' name='unicode' filepath='Objects/unicodeobject.c' line='8364' column='1'/> + <parameter type-id='type-id-2' name='mapping' filepath='Objects/unicodeobject.c' line='8365' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyUnicode_Translate' mangled-name='PyUnicode_Translate' filepath='Objects/unicodeobject.c' line='8780' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_Translate'> + <parameter type-id='type-id-2' name='str' filepath='Objects/unicodeobject.c' line='8780' column='1'/> + <parameter type-id='type-id-2' name='mapping' filepath='Objects/unicodeobject.c' line='8781' column='1'/> + <parameter type-id='type-id-12' name='errors' filepath='Objects/unicodeobject.c' line='8782' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyUnicode_InsertThousandsGrouping' mangled-name='_PyUnicode_InsertThousandsGrouping' filepath='Objects/unicodeobject.c' line='8962' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_InsertThousandsGrouping'> + <parameter type-id='type-id-332' name='writer' filepath='Objects/unicodeobject.c' line='8963' column='1'/> + <parameter type-id='type-id-14' name='n_buffer' filepath='Objects/unicodeobject.c' line='8964' column='1'/> + <parameter type-id='type-id-2' name='digits' filepath='Objects/unicodeobject.c' line='8965' column='1'/> + <parameter type-id='type-id-14' name='d_pos' filepath='Objects/unicodeobject.c' line='8966' column='1'/> + <parameter type-id='type-id-14' name='n_digits' filepath='Objects/unicodeobject.c' line='8967' column='1'/> + <parameter type-id='type-id-14' name='min_width' filepath='Objects/unicodeobject.c' line='8968' column='1'/> + <parameter type-id='type-id-12' name='grouping' filepath='Objects/unicodeobject.c' line='8969' column='1'/> + <parameter type-id='type-id-2' name='thousands_sep' filepath='Objects/unicodeobject.c' line='8970' column='1'/> + <parameter type-id='type-id-440' name='maxchar' filepath='Objects/unicodeobject.c' line='8971' column='1'/> + <return type-id='type-id-14'/> + </function-decl> + <function-decl name='PyUnicode_Count' mangled-name='PyUnicode_Count' filepath='Objects/unicodeobject.c' line='9141' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_Count'> + <parameter type-id='type-id-2' name='str' filepath='Objects/unicodeobject.c' line='9141' column='1'/> + <parameter type-id='type-id-2' name='substr' filepath='Objects/unicodeobject.c' line='9142' column='1'/> + <parameter type-id='type-id-14' name='start' filepath='Objects/unicodeobject.c' line='9143' column='1'/> + <parameter type-id='type-id-14' name='end' filepath='Objects/unicodeobject.c' line='9144' column='1'/> + <return type-id='type-id-14'/> + </function-decl> + <function-decl name='PyUnicode_Find' mangled-name='PyUnicode_Find' filepath='Objects/unicodeobject.c' line='9153' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_Find'> + <parameter type-id='type-id-2' name='str' filepath='Objects/unicodeobject.c' line='9153' column='1'/> + <parameter type-id='type-id-2' name='substr' filepath='Objects/unicodeobject.c' line='9154' column='1'/> + <parameter type-id='type-id-14' name='start' filepath='Objects/unicodeobject.c' line='9155' column='1'/> + <parameter type-id='type-id-14' name='end' filepath='Objects/unicodeobject.c' line='9156' column='1'/> + <parameter type-id='type-id-8' name='direction' filepath='Objects/unicodeobject.c' line='9157' column='1'/> + <return type-id='type-id-14'/> + </function-decl> + <function-decl name='PyUnicode_FindChar' mangled-name='PyUnicode_FindChar' filepath='Objects/unicodeobject.c' line='9166' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_FindChar'> + <parameter type-id='type-id-2' name='str' filepath='Objects/unicodeobject.c' line='9166' column='1'/> + <parameter type-id='type-id-250' name='ch' filepath='Objects/unicodeobject.c' line='9166' column='1'/> + <parameter type-id='type-id-14' name='start' filepath='Objects/unicodeobject.c' line='9167' column='1'/> + <parameter type-id='type-id-14' name='end' filepath='Objects/unicodeobject.c' line='9167' column='1'/> + <parameter type-id='type-id-8' name='direction' filepath='Objects/unicodeobject.c' line='9168' column='1'/> + <return type-id='type-id-14'/> + </function-decl> + <function-decl name='PyUnicode_Tailmatch' mangled-name='PyUnicode_Tailmatch' filepath='Objects/unicodeobject.c' line='9249' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_Tailmatch'> + <parameter type-id='type-id-2' name='str' filepath='Objects/unicodeobject.c' line='9249' column='1'/> + <parameter type-id='type-id-2' name='substr' filepath='Objects/unicodeobject.c' line='9250' column='1'/> + <parameter type-id='type-id-14' name='start' filepath='Objects/unicodeobject.c' line='9251' column='1'/> + <parameter type-id='type-id-14' name='end' filepath='Objects/unicodeobject.c' line='9252' column='1'/> + <parameter type-id='type-id-8' name='direction' filepath='Objects/unicodeobject.c' line='9253' column='1'/> + <return type-id='type-id-14'/> + </function-decl> + <function-decl name='_PyUnicode_JoinArray' mangled-name='_PyUnicode_JoinArray' filepath='Objects/unicodeobject.c' line='9518' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_JoinArray'> + <parameter type-id='type-id-2' name='separator' filepath='Objects/unicodeobject.c' line='9518' column='1'/> + <parameter type-id='type-id-248' name='items' filepath='Objects/unicodeobject.c' line='9518' column='1'/> + <parameter type-id='type-id-14' name='seqlen' filepath='Objects/unicodeobject.c' line='9518' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyUnicode_FastFill' mangled-name='_PyUnicode_FastFill' filepath='Objects/unicodeobject.c' line='9685' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_FastFill'> + <parameter type-id='type-id-2' name='unicode' filepath='Objects/unicodeobject.c' line='9685' column='1'/> + <parameter type-id='type-id-14' name='start' filepath='Objects/unicodeobject.c' line='9685' column='1'/> + <parameter type-id='type-id-14' name='length' filepath='Objects/unicodeobject.c' line='9685' column='1'/> + <parameter type-id='type-id-250' name='fill_char' filepath='Objects/unicodeobject.c' line='9686' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyUnicode_Fill' mangled-name='PyUnicode_Fill' filepath='Objects/unicodeobject.c' line='9698' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_Fill'> + <parameter type-id='type-id-2' name='unicode' filepath='Objects/unicodeobject.c' line='9698' column='1'/> + <parameter type-id='type-id-14' name='start' filepath='Objects/unicodeobject.c' line='9698' column='1'/> + <parameter type-id='type-id-14' name='length' filepath='Objects/unicodeobject.c' line='9698' column='1'/> + <parameter type-id='type-id-250' name='fill_char' filepath='Objects/unicodeobject.c' line='9699' column='1'/> + <return type-id='type-id-14'/> + </function-decl> + <function-decl name='PyUnicode_Splitlines' mangled-name='PyUnicode_Splitlines' filepath='Objects/unicodeobject.c' line='9772' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_Splitlines'> + <parameter type-id='type-id-2' name='string' filepath='Objects/unicodeobject.c' line='9772' column='1'/> + <parameter type-id='type-id-8' name='keepends' filepath='Objects/unicodeobject.c' line='9772' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyUnicode_EqualToASCIIId' mangled-name='_PyUnicode_EqualToASCIIId' filepath='Objects/unicodeobject.c' line='10660' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_EqualToASCIIId'> + <parameter type-id='type-id-2' name='left' filepath='Objects/unicodeobject.c' line='10660' column='1'/> + <parameter type-id='type-id-309' name='right' filepath='Objects/unicodeobject.c' line='10660' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyUnicode_RichCompare' mangled-name='PyUnicode_RichCompare' filepath='Objects/unicodeobject.c' line='10698' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_RichCompare'> + <parameter type-id='type-id-2' name='left' filepath='Objects/unicodeobject.c' line='10698' column='1'/> + <parameter type-id='type-id-2' name='right' filepath='Objects/unicodeobject.c' line='10698' column='1'/> + <parameter type-id='type-id-8' name='op' filepath='Objects/unicodeobject.c' line='10698' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyUnicode_Contains' mangled-name='PyUnicode_Contains' filepath='Objects/unicodeobject.c' line='10739' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_Contains'> + <parameter type-id='type-id-2' name='str' filepath='Objects/unicodeobject.c' line='10739' column='1'/> + <parameter type-id='type-id-2' name='substr' filepath='Objects/unicodeobject.c' line='10739' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyUnicode_Concat' mangled-name='PyUnicode_Concat' filepath='Objects/unicodeobject.c' line='10800' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_Concat'> + <parameter type-id='type-id-2' name='left' filepath='Objects/unicodeobject.c' line='10800' column='1'/> + <parameter type-id='type-id-2' name='right' filepath='Objects/unicodeobject.c' line='10800' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyUnicode_Append' mangled-name='PyUnicode_Append' filepath='Objects/unicodeobject.c' line='10849' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_Append'> + <parameter type-id='type-id-233' name='p_left' filepath='Objects/unicodeobject.c' line='10849' column='1'/> + <parameter type-id='type-id-2' name='right' filepath='Objects/unicodeobject.c' line='10849' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyUnicode_AppendAndDel' mangled-name='PyUnicode_AppendAndDel' filepath='Objects/unicodeobject.c' line='10926' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_AppendAndDel'> + <parameter type-id='type-id-233' name='pleft' filepath='Objects/unicodeobject.c' line='10926' column='1'/> + <parameter type-id='type-id-2' name='right' filepath='Objects/unicodeobject.c' line='10926' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyUnicode_XStrip' mangled-name='_PyUnicode_XStrip' filepath='Objects/unicodeobject.c' line='11738' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_XStrip'> + <parameter type-id='type-id-2' name='self' filepath='Objects/unicodeobject.c' line='11738' column='1'/> + <parameter type-id='type-id-8' name='striptype' filepath='Objects/unicodeobject.c' line='11738' column='1'/> + <parameter type-id='type-id-2' name='sepobj' filepath='Objects/unicodeobject.c' line='11738' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyUnicode_Replace' mangled-name='PyUnicode_Replace' filepath='Objects/unicodeobject.c' line='12011' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_Replace'> + <parameter type-id='type-id-2' name='str' filepath='Objects/unicodeobject.c' line='12011' column='1'/> + <parameter type-id='type-id-2' name='substr' filepath='Objects/unicodeobject.c' line='12012' column='1'/> + <parameter type-id='type-id-2' name='replstr' filepath='Objects/unicodeobject.c' line='12013' column='1'/> + <parameter type-id='type-id-14' name='maxcount' filepath='Objects/unicodeobject.c' line='12014' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyUnicode_Split' mangled-name='PyUnicode_Split' filepath='Objects/unicodeobject.c' line='12349' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_Split'> + <parameter type-id='type-id-2' name='s' filepath='Objects/unicodeobject.c' line='12349' column='1'/> + <parameter type-id='type-id-2' name='sep' filepath='Objects/unicodeobject.c' line='12349' column='1'/> + <parameter type-id='type-id-14' name='maxsplit' filepath='Objects/unicodeobject.c' line='12349' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyUnicode_Partition' mangled-name='PyUnicode_Partition' filepath='Objects/unicodeobject.c' line='12394' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_Partition'> + <parameter type-id='type-id-2' name='str_obj' filepath='Objects/unicodeobject.c' line='12394' column='1'/> + <parameter type-id='type-id-2' name='sep_obj' filepath='Objects/unicodeobject.c' line='12394' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyUnicode_RPartition' mangled-name='PyUnicode_RPartition' filepath='Objects/unicodeobject.c' line='12446' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_RPartition'> + <parameter type-id='type-id-2' name='str_obj' filepath='Objects/unicodeobject.c' line='12446' column='1'/> + <parameter type-id='type-id-2' name='sep_obj' filepath='Objects/unicodeobject.c' line='12446' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyUnicode_RSplit' mangled-name='PyUnicode_RSplit' filepath='Objects/unicodeobject.c' line='12540' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_RSplit'> + <parameter type-id='type-id-2' name='s' filepath='Objects/unicodeobject.c' line='12540' column='1'/> + <parameter type-id='type-id-2' name='sep' filepath='Objects/unicodeobject.c' line='12540' column='1'/> + <parameter type-id='type-id-14' name='maxsplit' filepath='Objects/unicodeobject.c' line='12540' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyUnicodeWriter_PrepareKindInternal' mangled-name='_PyUnicodeWriter_PrepareKindInternal' filepath='Objects/unicodeobject.c' line='13051' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicodeWriter_PrepareKindInternal'> + <parameter type-id='type-id-332' name='writer' filepath='Objects/unicodeobject.c' line='13051' column='1'/> + <parameter type-id='type-id-8' name='kind' filepath='Objects/unicodeobject.c' line='13052' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyUnicodeWriter_WriteSubstring' mangled-name='_PyUnicodeWriter_WriteSubstring' filepath='Objects/unicodeobject.c' line='13117' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicodeWriter_WriteSubstring'> + <parameter type-id='type-id-332' name='writer' filepath='Objects/unicodeobject.c' line='13117' column='1'/> + <parameter type-id='type-id-2' name='str' filepath='Objects/unicodeobject.c' line='13117' column='1'/> + <parameter type-id='type-id-14' name='start' filepath='Objects/unicodeobject.c' line='13118' column='1'/> + <parameter type-id='type-id-14' name='end' filepath='Objects/unicodeobject.c' line='13118' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyUnicodeWriter_WriteLatin1String' mangled-name='_PyUnicodeWriter_WriteLatin1String' filepath='Objects/unicodeobject.c' line='13209' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicodeWriter_WriteLatin1String'> + <parameter type-id='type-id-332' name='writer' filepath='Objects/unicodeobject.c' line='13209' column='1'/> + <parameter type-id='type-id-12' name='str' filepath='Objects/unicodeobject.c' line='13210' column='1'/> + <parameter type-id='type-id-14' name='len' filepath='Objects/unicodeobject.c' line='13210' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyUnicode_Format' mangled-name='PyUnicode_Format' filepath='Objects/unicodeobject.c' line='14359' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_Format'> + <parameter type-id='type-id-2' name='format' filepath='Objects/unicodeobject.c' line='14359' column='1'/> + <parameter type-id='type-id-2' name='args' filepath='Objects/unicodeobject.c' line='14359' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyUnicode_InternImmortal' mangled-name='PyUnicode_InternImmortal' filepath='Objects/unicodeobject.c' line='14769' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_InternImmortal'> + <parameter type-id='type-id-233' name='p' filepath='Objects/unicodeobject.c' line='14769' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyInit__string' mangled-name='PyInit__string' filepath='Objects/unicodeobject.c' line='15337' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInit__string'> + <return type-id='type-id-2'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Objects/unionobject.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <var-decl name='_PyUnion_Type' type-id='type-id-256' visibility='default' filepath='./Include/internal/pycore_unionobject.h' line='11' column='1'/> + <function-decl name='_Py_subs_parameters' filepath='./Include/internal/pycore_unionobject.h' line='16' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_Py_make_parameters' filepath='./Include/internal/pycore_unionobject.h' line='17' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Objects/weakrefobject.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <var-decl name='_PyWeakref_RefType' type-id='type-id-256' mangled-name='_PyWeakref_RefType' visibility='default' filepath='./Include/weakrefobject.h' line='11' column='1' elf-symbol-id='_PyWeakref_RefType'/> + <var-decl name='_PyWeakref_ProxyType' type-id='type-id-256' mangled-name='_PyWeakref_ProxyType' visibility='default' filepath='./Include/weakrefobject.h' line='12' column='1' elf-symbol-id='_PyWeakref_ProxyType'/> + <var-decl name='_PyWeakref_CallableProxyType' type-id='type-id-256' mangled-name='_PyWeakref_CallableProxyType' visibility='default' filepath='./Include/weakrefobject.h' line='13' column='1' elf-symbol-id='_PyWeakref_CallableProxyType'/> + <function-decl name='_PyWeakref_GetWeakrefCount' mangled-name='_PyWeakref_GetWeakrefCount' filepath='Objects/weakrefobject.c' line='11' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyWeakref_GetWeakrefCount'> + <parameter type-id='type-id-432' name='head' filepath='Objects/weakrefobject.c' line='11' column='1'/> + <return type-id='type-id-14'/> + </function-decl> + <function-decl name='PyWeakref_NewProxy' mangled-name='PyWeakref_NewProxy' filepath='Objects/weakrefobject.c' line='843' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyWeakref_NewProxy'> + <parameter type-id='type-id-2' name='ob' filepath='Objects/weakrefobject.c' line='843' column='1'/> + <parameter type-id='type-id-2' name='callback' filepath='Objects/weakrefobject.c' line='843' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyWeakref_GetObject' mangled-name='PyWeakref_GetObject' filepath='Objects/weakrefobject.c' line='908' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyWeakref_GetObject'> + <parameter type-id='type-id-2' name='ref' filepath='Objects/weakrefobject.c' line='908' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Parser/action_helpers.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <array-type-def dimensions='1' type-id='type-id-2' size-in-bits='64' id='type-id-353'> + <subrange length='1' type-id='type-id-28' id='type-id-443'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-444' size-in-bits='64' id='type-id-445'> + <subrange length='1' type-id='type-id-28' id='type-id-443'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-446' size-in-bits='64' id='type-id-447'> + <subrange length='1' type-id='type-id-28' id='type-id-443'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-448' size-in-bits='64' id='type-id-449'> + <subrange length='1' type-id='type-id-28' id='type-id-443'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-450' size-in-bits='64' id='type-id-451'> + <subrange length='1' type-id='type-id-28' id='type-id-443'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-452' size-in-bits='64' id='type-id-453'> + <subrange length='1' type-id='type-id-28' id='type-id-443'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-454' size-in-bits='64' id='type-id-455'> + <subrange length='1' type-id='type-id-28' id='type-id-443'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-456' size-in-bits='64' id='type-id-457'> + <subrange length='1' type-id='type-id-28' id='type-id-443'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-22' size-in-bits='64' id='type-id-458'> + <subrange length='1' type-id='type-id-28' id='type-id-443'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-459' size-in-bits='64' id='type-id-460'> + <subrange length='1' type-id='type-id-28' id='type-id-443'/> + </array-type-def> + <class-decl name='_PyUnicodeWriter' size-in-bits='448' is-struct='yes' naming-typedef-id='type-id-461' visibility='default' filepath='./Include/cpython/unicodeobject.h' line='487' column='1' id='type-id-462'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='buffer' type-id='type-id-2' visibility='default' filepath='./Include/cpython/unicodeobject.h' line='488' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='data' type-id='type-id-22' visibility='default' filepath='./Include/cpython/unicodeobject.h' line='489' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='kind' type-id='type-id-8' visibility='default' filepath='./Include/cpython/unicodeobject.h' line='490' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='160'> + <var-decl name='maxchar' type-id='type-id-250' visibility='default' filepath='./Include/cpython/unicodeobject.h' line='491' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='size' type-id='type-id-14' visibility='default' filepath='./Include/cpython/unicodeobject.h' line='492' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='pos' type-id='type-id-14' visibility='default' filepath='./Include/cpython/unicodeobject.h' line='493' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='min_length' type-id='type-id-14' visibility='default' filepath='./Include/cpython/unicodeobject.h' line='496' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='384'> + <var-decl name='min_char' type-id='type-id-250' visibility='default' filepath='./Include/cpython/unicodeobject.h' line='499' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='416'> + <var-decl name='overallocate' type-id='type-id-85' visibility='default' filepath='./Include/cpython/unicodeobject.h' line='502' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='424'> + <var-decl name='readonly' type-id='type-id-85' visibility='default' filepath='./Include/cpython/unicodeobject.h' line='506' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='_PyUnicodeWriter' type-id='type-id-462' filepath='./Include/cpython/unicodeobject.h' line='507' column='1' id='type-id-461'/> + <class-decl name='asdl_generic_seq' size-in-bits='192' is-struct='yes' naming-typedef-id='type-id-463' visibility='default' filepath='./Include/internal/pycore_asdl.h' line='32' column='1' id='type-id-464'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='size' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_asdl.h' line='33' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='elements' type-id='type-id-253' visibility='default' filepath='./Include/internal/pycore_asdl.h' line='33' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='typed_elements' type-id='type-id-458' visibility='default' filepath='./Include/internal/pycore_asdl.h' line='34' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='asdl_generic_seq' type-id='type-id-464' filepath='./Include/internal/pycore_asdl.h' line='35' column='1' id='type-id-463'/> + <class-decl name='asdl_identifier_seq' size-in-bits='192' is-struct='yes' naming-typedef-id='type-id-465' visibility='default' filepath='./Include/internal/pycore_asdl.h' line='37' column='1' id='type-id-466'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='size' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_asdl.h' line='38' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='elements' type-id='type-id-253' visibility='default' filepath='./Include/internal/pycore_asdl.h' line='38' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='typed_elements' type-id='type-id-353' visibility='default' filepath='./Include/internal/pycore_asdl.h' line='39' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='asdl_identifier_seq' type-id='type-id-466' filepath='./Include/internal/pycore_asdl.h' line='40' column='1' id='type-id-465'/> + <typedef-decl name='mod_ty' type-id='type-id-467' filepath='./Include/internal/pycore_ast.h' line='15' column='1' id='type-id-468'/> + <typedef-decl name='stmt_ty' type-id='type-id-469' filepath='./Include/internal/pycore_ast.h' line='17' column='1' id='type-id-452'/> + <typedef-decl name='excepthandler_ty' type-id='type-id-470' filepath='./Include/internal/pycore_ast.h' line='36' column='1' id='type-id-446'/> + <typedef-decl name='alias_ty' type-id='type-id-471' filepath='./Include/internal/pycore_ast.h' line='44' column='1' id='type-id-444'/> + <typedef-decl name='withitem_ty' type-id='type-id-472' filepath='./Include/internal/pycore_ast.h' line='46' column='1' id='type-id-459'/> + <typedef-decl name='match_case_ty' type-id='type-id-473' filepath='./Include/internal/pycore_ast.h' line='48' column='1' id='type-id-448'/> + <typedef-decl name='pattern_ty' type-id='type-id-474' filepath='./Include/internal/pycore_ast.h' line='50' column='1' id='type-id-450'/> + <typedef-decl name='type_ignore_ty' type-id='type-id-475' filepath='./Include/internal/pycore_ast.h' line='52' column='1' id='type-id-454'/> + <typedef-decl name='type_param_ty' type-id='type-id-476' filepath='./Include/internal/pycore_ast.h' line='54' column='1' id='type-id-456'/> + <class-decl name='asdl_stmt_seq' size-in-bits='192' is-struct='yes' naming-typedef-id='type-id-477' visibility='default' filepath='./Include/internal/pycore_ast.h' line='64' column='1' id='type-id-478'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='size' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast.h' line='65' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='elements' type-id='type-id-253' visibility='default' filepath='./Include/internal/pycore_ast.h' line='65' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='typed_elements' type-id='type-id-453' visibility='default' filepath='./Include/internal/pycore_ast.h' line='66' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='asdl_stmt_seq' type-id='type-id-478' filepath='./Include/internal/pycore_ast.h' line='67' column='1' id='type-id-477'/> + <class-decl name='asdl_excepthandler_seq' size-in-bits='192' is-struct='yes' naming-typedef-id='type-id-479' visibility='default' filepath='./Include/internal/pycore_ast.h' line='86' column='1' id='type-id-480'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='size' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast.h' line='87' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='elements' type-id='type-id-253' visibility='default' filepath='./Include/internal/pycore_ast.h' line='87' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='typed_elements' type-id='type-id-447' visibility='default' filepath='./Include/internal/pycore_ast.h' line='88' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='asdl_excepthandler_seq' type-id='type-id-480' filepath='./Include/internal/pycore_ast.h' line='89' column='1' id='type-id-479'/> + <class-decl name='asdl_alias_seq' size-in-bits='192' is-struct='yes' naming-typedef-id='type-id-481' visibility='default' filepath='./Include/internal/pycore_ast.h' line='115' column='1' id='type-id-482'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='size' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast.h' line='116' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='elements' type-id='type-id-253' visibility='default' filepath='./Include/internal/pycore_ast.h' line='116' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='typed_elements' type-id='type-id-445' visibility='default' filepath='./Include/internal/pycore_ast.h' line='117' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='asdl_alias_seq' type-id='type-id-482' filepath='./Include/internal/pycore_ast.h' line='118' column='1' id='type-id-481'/> + <class-decl name='asdl_withitem_seq' size-in-bits='192' is-struct='yes' naming-typedef-id='type-id-483' visibility='default' filepath='./Include/internal/pycore_ast.h' line='122' column='1' id='type-id-484'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='size' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast.h' line='123' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='elements' type-id='type-id-253' visibility='default' filepath='./Include/internal/pycore_ast.h' line='123' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='typed_elements' type-id='type-id-460' visibility='default' filepath='./Include/internal/pycore_ast.h' line='124' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='asdl_withitem_seq' type-id='type-id-484' filepath='./Include/internal/pycore_ast.h' line='125' column='1' id='type-id-483'/> + <class-decl name='asdl_match_case_seq' size-in-bits='192' is-struct='yes' naming-typedef-id='type-id-485' visibility='default' filepath='./Include/internal/pycore_ast.h' line='129' column='1' id='type-id-486'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='size' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast.h' line='130' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='elements' type-id='type-id-253' visibility='default' filepath='./Include/internal/pycore_ast.h' line='130' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='typed_elements' type-id='type-id-449' visibility='default' filepath='./Include/internal/pycore_ast.h' line='131' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='asdl_match_case_seq' type-id='type-id-486' filepath='./Include/internal/pycore_ast.h' line='132' column='1' id='type-id-485'/> + <class-decl name='asdl_pattern_seq' size-in-bits='192' is-struct='yes' naming-typedef-id='type-id-487' visibility='default' filepath='./Include/internal/pycore_ast.h' line='137' column='1' id='type-id-488'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='size' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast.h' line='138' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='elements' type-id='type-id-253' visibility='default' filepath='./Include/internal/pycore_ast.h' line='138' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='typed_elements' type-id='type-id-451' visibility='default' filepath='./Include/internal/pycore_ast.h' line='139' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='asdl_pattern_seq' type-id='type-id-488' filepath='./Include/internal/pycore_ast.h' line='140' column='1' id='type-id-487'/> + <class-decl name='asdl_type_ignore_seq' size-in-bits='192' is-struct='yes' naming-typedef-id='type-id-489' visibility='default' filepath='./Include/internal/pycore_ast.h' line='144' column='1' id='type-id-490'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='size' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast.h' line='145' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='elements' type-id='type-id-253' visibility='default' filepath='./Include/internal/pycore_ast.h' line='145' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='typed_elements' type-id='type-id-455' visibility='default' filepath='./Include/internal/pycore_ast.h' line='146' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='asdl_type_ignore_seq' type-id='type-id-490' filepath='./Include/internal/pycore_ast.h' line='147' column='1' id='type-id-489'/> + <class-decl name='asdl_type_param_seq' size-in-bits='192' is-struct='yes' naming-typedef-id='type-id-491' visibility='default' filepath='./Include/internal/pycore_ast.h' line='152' column='1' id='type-id-492'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='size' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast.h' line='153' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='elements' type-id='type-id-253' visibility='default' filepath='./Include/internal/pycore_ast.h' line='153' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='typed_elements' type-id='type-id-457' visibility='default' filepath='./Include/internal/pycore_ast.h' line='154' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='asdl_type_param_seq' type-id='type-id-492' filepath='./Include/internal/pycore_ast.h' line='155' column='1' id='type-id-491'/> + <enum-decl name='_mod_kind' filepath='./Include/internal/pycore_ast.h' line='161' column='1' id='type-id-493'> + <underlying-type type-id='type-id-24'/> + <enumerator name='Module_kind' value='1'/> + <enumerator name='Interactive_kind' value='2'/> + <enumerator name='Expression_kind' value='3'/> + <enumerator name='FunctionType_kind' value='4'/> + </enum-decl> + <class-decl name='_mod' size-in-bits='192' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='163' column='1' id='type-id-494'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='kind' type-id='type-id-493' visibility='default' filepath='./Include/internal/pycore_ast.h' line='164' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='v' type-id='type-id-495' visibility='default' filepath='./Include/internal/pycore_ast.h' line='184' column='1'/> + </data-member> + </class-decl> + <union-decl name='__anonymous_union__' size-in-bits='128' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='165' column='1' id='type-id-495'> + <data-member access='public'> + <var-decl name='Module' type-id='type-id-496' visibility='default' filepath='./Include/internal/pycore_ast.h' line='169' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='Interactive' type-id='type-id-497' visibility='default' filepath='./Include/internal/pycore_ast.h' line='173' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='Expression' type-id='type-id-498' visibility='default' filepath='./Include/internal/pycore_ast.h' line='177' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='FunctionType' type-id='type-id-499' visibility='default' filepath='./Include/internal/pycore_ast.h' line='182' column='1'/> + </data-member> + </union-decl> + <class-decl name='__anonymous_struct__' size-in-bits='128' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='166' column='1' id='type-id-496'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='body' type-id='type-id-500' visibility='default' filepath='./Include/internal/pycore_ast.h' line='167' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='type_ignores' type-id='type-id-501' visibility='default' filepath='./Include/internal/pycore_ast.h' line='168' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__39' size-in-bits='64' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='171' column='1' id='type-id-497'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='body' type-id='type-id-500' visibility='default' filepath='./Include/internal/pycore_ast.h' line='172' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__40' size-in-bits='64' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='175' column='1' id='type-id-498'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='body' type-id='type-id-502' visibility='default' filepath='./Include/internal/pycore_ast.h' line='176' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__41' size-in-bits='128' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='179' column='1' id='type-id-499'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='argtypes' type-id='type-id-503' visibility='default' filepath='./Include/internal/pycore_ast.h' line='180' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='returns' type-id='type-id-502' visibility='default' filepath='./Include/internal/pycore_ast.h' line='181' column='1'/> + </data-member> + </class-decl> + <enum-decl name='_stmt_kind' filepath='./Include/internal/pycore_ast.h' line='187' column='1' id='type-id-504'> + <underlying-type type-id='type-id-24'/> + <enumerator name='FunctionDef_kind' value='1'/> + <enumerator name='AsyncFunctionDef_kind' value='2'/> + <enumerator name='ClassDef_kind' value='3'/> + <enumerator name='Return_kind' value='4'/> + <enumerator name='Delete_kind' value='5'/> + <enumerator name='Assign_kind' value='6'/> + <enumerator name='TypeAlias_kind' value='7'/> + <enumerator name='AugAssign_kind' value='8'/> + <enumerator name='AnnAssign_kind' value='9'/> + <enumerator name='For_kind' value='10'/> + <enumerator name='AsyncFor_kind' value='11'/> + <enumerator name='While_kind' value='12'/> + <enumerator name='If_kind' value='13'/> + <enumerator name='With_kind' value='14'/> + <enumerator name='AsyncWith_kind' value='15'/> + <enumerator name='Match_kind' value='16'/> + <enumerator name='Raise_kind' value='17'/> + <enumerator name='Try_kind' value='18'/> + <enumerator name='TryStar_kind' value='19'/> + <enumerator name='Assert_kind' value='20'/> + <enumerator name='Import_kind' value='21'/> + <enumerator name='ImportFrom_kind' value='22'/> + <enumerator name='Global_kind' value='23'/> + <enumerator name='Nonlocal_kind' value='24'/> + <enumerator name='Expr_kind' value='25'/> + <enumerator name='Pass_kind' value='26'/> + <enumerator name='Break_kind' value='27'/> + <enumerator name='Continue_kind' value='28'/> + </enum-decl> + <class-decl name='_stmt' size-in-bits='640' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='196' column='1' id='type-id-505'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='kind' type-id='type-id-504' visibility='default' filepath='./Include/internal/pycore_ast.h' line='197' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='v' type-id='type-id-506' visibility='default' filepath='./Include/internal/pycore_ast.h' line='352' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='512'> + <var-decl name='lineno' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='353' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='544'> + <var-decl name='col_offset' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='354' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='576'> + <var-decl name='end_lineno' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='355' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='608'> + <var-decl name='end_col_offset' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='356' column='1'/> + </data-member> + </class-decl> + <union-decl name='__anonymous_union__1' size-in-bits='448' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='198' column='1' id='type-id-506'> + <data-member access='public'> + <var-decl name='FunctionDef' type-id='type-id-507' visibility='default' filepath='./Include/internal/pycore_ast.h' line='207' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='AsyncFunctionDef' type-id='type-id-507' visibility='default' filepath='./Include/internal/pycore_ast.h' line='217' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='ClassDef' type-id='type-id-508' visibility='default' filepath='./Include/internal/pycore_ast.h' line='226' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='Return' type-id='type-id-509' visibility='default' filepath='./Include/internal/pycore_ast.h' line='230' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='Delete' type-id='type-id-510' visibility='default' filepath='./Include/internal/pycore_ast.h' line='234' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='Assign' type-id='type-id-511' visibility='default' filepath='./Include/internal/pycore_ast.h' line='240' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='TypeAlias' type-id='type-id-512' visibility='default' filepath='./Include/internal/pycore_ast.h' line='246' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='AugAssign' type-id='type-id-513' visibility='default' filepath='./Include/internal/pycore_ast.h' line='252' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='AnnAssign' type-id='type-id-514' visibility='default' filepath='./Include/internal/pycore_ast.h' line='259' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='For' type-id='type-id-515' visibility='default' filepath='./Include/internal/pycore_ast.h' line='267' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='AsyncFor' type-id='type-id-515' visibility='default' filepath='./Include/internal/pycore_ast.h' line='275' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='While' type-id='type-id-516' visibility='default' filepath='./Include/internal/pycore_ast.h' line='281' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='If' type-id='type-id-516' visibility='default' filepath='./Include/internal/pycore_ast.h' line='287' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='With' type-id='type-id-517' visibility='default' filepath='./Include/internal/pycore_ast.h' line='293' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='AsyncWith' type-id='type-id-517' visibility='default' filepath='./Include/internal/pycore_ast.h' line='299' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='Match' type-id='type-id-518' visibility='default' filepath='./Include/internal/pycore_ast.h' line='304' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='Raise' type-id='type-id-519' visibility='default' filepath='./Include/internal/pycore_ast.h' line='309' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='Try' type-id='type-id-520' visibility='default' filepath='./Include/internal/pycore_ast.h' line='316' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='TryStar' type-id='type-id-520' visibility='default' filepath='./Include/internal/pycore_ast.h' line='323' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='Assert' type-id='type-id-521' visibility='default' filepath='./Include/internal/pycore_ast.h' line='328' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='Import' type-id='type-id-522' visibility='default' filepath='./Include/internal/pycore_ast.h' line='332' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='ImportFrom' type-id='type-id-523' visibility='default' filepath='./Include/internal/pycore_ast.h' line='338' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='Global' type-id='type-id-524' visibility='default' filepath='./Include/internal/pycore_ast.h' line='342' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='Nonlocal' type-id='type-id-524' visibility='default' filepath='./Include/internal/pycore_ast.h' line='346' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='Expr' type-id='type-id-509' visibility='default' filepath='./Include/internal/pycore_ast.h' line='350' column='1'/> + </data-member> + </union-decl> + <class-decl name='__anonymous_struct__2' size-in-bits='448' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='199' column='1' id='type-id-507'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='name' type-id='type-id-525' visibility='default' filepath='./Include/internal/pycore_ast.h' line='200' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='args' type-id='type-id-526' visibility='default' filepath='./Include/internal/pycore_ast.h' line='201' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='body' type-id='type-id-500' visibility='default' filepath='./Include/internal/pycore_ast.h' line='202' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='decorator_list' type-id='type-id-503' visibility='default' filepath='./Include/internal/pycore_ast.h' line='203' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='returns' type-id='type-id-502' visibility='default' filepath='./Include/internal/pycore_ast.h' line='204' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='type_comment' type-id='type-id-527' visibility='default' filepath='./Include/internal/pycore_ast.h' line='205' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='384'> + <var-decl name='type_params' type-id='type-id-528' visibility='default' filepath='./Include/internal/pycore_ast.h' line='206' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__6' size-in-bits='384' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='219' column='1' id='type-id-508'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='name' type-id='type-id-525' visibility='default' filepath='./Include/internal/pycore_ast.h' line='220' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='bases' type-id='type-id-503' visibility='default' filepath='./Include/internal/pycore_ast.h' line='221' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='keywords' type-id='type-id-529' visibility='default' filepath='./Include/internal/pycore_ast.h' line='222' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='body' type-id='type-id-500' visibility='default' filepath='./Include/internal/pycore_ast.h' line='223' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='decorator_list' type-id='type-id-503' visibility='default' filepath='./Include/internal/pycore_ast.h' line='224' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='type_params' type-id='type-id-528' visibility='default' filepath='./Include/internal/pycore_ast.h' line='225' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__8' size-in-bits='64' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='232' column='1' id='type-id-510'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='targets' type-id='type-id-503' visibility='default' filepath='./Include/internal/pycore_ast.h' line='233' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__9' size-in-bits='192' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='236' column='1' id='type-id-511'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='targets' type-id='type-id-503' visibility='default' filepath='./Include/internal/pycore_ast.h' line='237' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='value' type-id='type-id-502' visibility='default' filepath='./Include/internal/pycore_ast.h' line='238' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='type_comment' type-id='type-id-527' visibility='default' filepath='./Include/internal/pycore_ast.h' line='239' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__10' size-in-bits='192' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='242' column='1' id='type-id-512'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='name' type-id='type-id-502' visibility='default' filepath='./Include/internal/pycore_ast.h' line='243' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='type_params' type-id='type-id-528' visibility='default' filepath='./Include/internal/pycore_ast.h' line='244' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='value' type-id='type-id-502' visibility='default' filepath='./Include/internal/pycore_ast.h' line='245' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__11' size-in-bits='192' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='248' column='1' id='type-id-513'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='target' type-id='type-id-502' visibility='default' filepath='./Include/internal/pycore_ast.h' line='249' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='op' type-id='type-id-530' visibility='default' filepath='./Include/internal/pycore_ast.h' line='250' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='value' type-id='type-id-502' visibility='default' filepath='./Include/internal/pycore_ast.h' line='251' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__12' size-in-bits='256' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='254' column='1' id='type-id-514'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='target' type-id='type-id-502' visibility='default' filepath='./Include/internal/pycore_ast.h' line='255' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='annotation' type-id='type-id-502' visibility='default' filepath='./Include/internal/pycore_ast.h' line='256' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='value' type-id='type-id-502' visibility='default' filepath='./Include/internal/pycore_ast.h' line='257' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='simple' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='258' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__13' size-in-bits='320' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='261' column='1' id='type-id-515'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='target' type-id='type-id-502' visibility='default' filepath='./Include/internal/pycore_ast.h' line='262' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='iter' type-id='type-id-502' visibility='default' filepath='./Include/internal/pycore_ast.h' line='263' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='body' type-id='type-id-500' visibility='default' filepath='./Include/internal/pycore_ast.h' line='264' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='orelse' type-id='type-id-500' visibility='default' filepath='./Include/internal/pycore_ast.h' line='265' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='type_comment' type-id='type-id-527' visibility='default' filepath='./Include/internal/pycore_ast.h' line='266' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__15' size-in-bits='192' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='277' column='1' id='type-id-516'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='test' type-id='type-id-502' visibility='default' filepath='./Include/internal/pycore_ast.h' line='278' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='body' type-id='type-id-500' visibility='default' filepath='./Include/internal/pycore_ast.h' line='279' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='orelse' type-id='type-id-500' visibility='default' filepath='./Include/internal/pycore_ast.h' line='280' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__17' size-in-bits='192' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='289' column='1' id='type-id-517'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='items' type-id='type-id-531' visibility='default' filepath='./Include/internal/pycore_ast.h' line='290' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='body' type-id='type-id-500' visibility='default' filepath='./Include/internal/pycore_ast.h' line='291' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='type_comment' type-id='type-id-527' visibility='default' filepath='./Include/internal/pycore_ast.h' line='292' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__19' size-in-bits='128' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='301' column='1' id='type-id-518'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='subject' type-id='type-id-502' visibility='default' filepath='./Include/internal/pycore_ast.h' line='302' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='cases' type-id='type-id-532' visibility='default' filepath='./Include/internal/pycore_ast.h' line='303' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__28' size-in-bits='128' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='306' column='1' id='type-id-519'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='exc' type-id='type-id-502' visibility='default' filepath='./Include/internal/pycore_ast.h' line='307' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='cause' type-id='type-id-502' visibility='default' filepath='./Include/internal/pycore_ast.h' line='308' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__29' size-in-bits='256' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='311' column='1' id='type-id-520'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='body' type-id='type-id-500' visibility='default' filepath='./Include/internal/pycore_ast.h' line='312' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='handlers' type-id='type-id-533' visibility='default' filepath='./Include/internal/pycore_ast.h' line='313' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='orelse' type-id='type-id-500' visibility='default' filepath='./Include/internal/pycore_ast.h' line='314' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='finalbody' type-id='type-id-500' visibility='default' filepath='./Include/internal/pycore_ast.h' line='315' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__32' size-in-bits='128' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='325' column='1' id='type-id-521'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='test' type-id='type-id-502' visibility='default' filepath='./Include/internal/pycore_ast.h' line='326' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='msg' type-id='type-id-502' visibility='default' filepath='./Include/internal/pycore_ast.h' line='327' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__33' size-in-bits='64' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='330' column='1' id='type-id-522'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='names' type-id='type-id-534' visibility='default' filepath='./Include/internal/pycore_ast.h' line='331' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__34' size-in-bits='192' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='334' column='1' id='type-id-523'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='module' type-id='type-id-525' visibility='default' filepath='./Include/internal/pycore_ast.h' line='335' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='names' type-id='type-id-534' visibility='default' filepath='./Include/internal/pycore_ast.h' line='336' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='level' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='337' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__35' size-in-bits='64' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='340' column='1' id='type-id-524'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='names' type-id='type-id-535' visibility='default' filepath='./Include/internal/pycore_ast.h' line='341' column='1'/> + </data-member> + </class-decl> + <enum-decl name='_excepthandler_kind' filepath='./Include/internal/pycore_ast.h' line='523' column='1' id='type-id-536'> + <underlying-type type-id='type-id-24'/> + <enumerator name='ExceptHandler_kind' value='1'/> + </enum-decl> + <class-decl name='_excepthandler' size-in-bits='384' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='524' column='1' id='type-id-537'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='kind' type-id='type-id-536' visibility='default' filepath='./Include/internal/pycore_ast.h' line='525' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='v' type-id='type-id-538' visibility='default' filepath='./Include/internal/pycore_ast.h' line='533' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='lineno' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='534' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='288'> + <var-decl name='col_offset' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='535' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='end_lineno' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='536' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='352'> + <var-decl name='end_col_offset' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='537' column='1'/> + </data-member> + </class-decl> + <union-decl name='__anonymous_union__4' size-in-bits='192' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='526' column='1' id='type-id-538'> + <data-member access='public'> + <var-decl name='ExceptHandler' type-id='type-id-539' visibility='default' filepath='./Include/internal/pycore_ast.h' line='531' column='1'/> + </data-member> + </union-decl> + <class-decl name='__anonymous_struct__31' size-in-bits='192' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='527' column='1' id='type-id-539'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='type' type-id='type-id-502' visibility='default' filepath='./Include/internal/pycore_ast.h' line='528' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='name' type-id='type-id-525' visibility='default' filepath='./Include/internal/pycore_ast.h' line='529' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='body' type-id='type-id-500' visibility='default' filepath='./Include/internal/pycore_ast.h' line='530' column='1'/> + </data-member> + </class-decl> + <class-decl name='_alias' size-in-bits='256' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='569' column='1' id='type-id-540'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='name' type-id='type-id-525' visibility='default' filepath='./Include/internal/pycore_ast.h' line='570' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='asname' type-id='type-id-525' visibility='default' filepath='./Include/internal/pycore_ast.h' line='571' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='lineno' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='572' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='160'> + <var-decl name='col_offset' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='573' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='end_lineno' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='574' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='224'> + <var-decl name='end_col_offset' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='575' column='1'/> + </data-member> + </class-decl> + <class-decl name='_withitem' size-in-bits='128' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='578' column='1' id='type-id-541'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='context_expr' type-id='type-id-502' visibility='default' filepath='./Include/internal/pycore_ast.h' line='579' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='optional_vars' type-id='type-id-502' visibility='default' filepath='./Include/internal/pycore_ast.h' line='580' column='1'/> + </data-member> + </class-decl> + <class-decl name='_match_case' size-in-bits='192' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='583' column='1' id='type-id-542'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='pattern' type-id='type-id-450' visibility='default' filepath='./Include/internal/pycore_ast.h' line='584' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='guard' type-id='type-id-502' visibility='default' filepath='./Include/internal/pycore_ast.h' line='585' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='body' type-id='type-id-500' visibility='default' filepath='./Include/internal/pycore_ast.h' line='586' column='1'/> + </data-member> + </class-decl> + <enum-decl name='_pattern_kind' filepath='./Include/internal/pycore_ast.h' line='589' column='1' id='type-id-543'> + <underlying-type type-id='type-id-24'/> + <enumerator name='MatchValue_kind' value='1'/> + <enumerator name='MatchSingleton_kind' value='2'/> + <enumerator name='MatchSequence_kind' value='3'/> + <enumerator name='MatchMapping_kind' value='4'/> + <enumerator name='MatchClass_kind' value='5'/> + <enumerator name='MatchStar_kind' value='6'/> + <enumerator name='MatchAs_kind' value='7'/> + <enumerator name='MatchOr_kind' value='8'/> + </enum-decl> + <class-decl name='_pattern' size-in-bits='448' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='593' column='1' id='type-id-544'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='kind' type-id='type-id-543' visibility='default' filepath='./Include/internal/pycore_ast.h' line='594' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='v' type-id='type-id-545' visibility='default' filepath='./Include/internal/pycore_ast.h' line='634' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='lineno' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='635' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='352'> + <var-decl name='col_offset' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='636' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='384'> + <var-decl name='end_lineno' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='637' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='416'> + <var-decl name='end_col_offset' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='638' column='1'/> + </data-member> + </class-decl> + <union-decl name='__anonymous_union__3' size-in-bits='256' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='595' column='1' id='type-id-545'> + <data-member access='public'> + <var-decl name='MatchValue' type-id='type-id-509' visibility='default' filepath='./Include/internal/pycore_ast.h' line='598' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='MatchSingleton' type-id='type-id-546' visibility='default' filepath='./Include/internal/pycore_ast.h' line='602' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='MatchSequence' type-id='type-id-547' visibility='default' filepath='./Include/internal/pycore_ast.h' line='606' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='MatchMapping' type-id='type-id-548' visibility='default' filepath='./Include/internal/pycore_ast.h' line='612' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='MatchClass' type-id='type-id-549' visibility='default' filepath='./Include/internal/pycore_ast.h' line='619' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='MatchStar' type-id='type-id-550' visibility='default' filepath='./Include/internal/pycore_ast.h' line='623' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='MatchAs' type-id='type-id-551' visibility='default' filepath='./Include/internal/pycore_ast.h' line='628' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='MatchOr' type-id='type-id-547' visibility='default' filepath='./Include/internal/pycore_ast.h' line='632' column='1'/> + </data-member> + </union-decl> + <class-decl name='__anonymous_struct__22' size-in-bits='64' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='600' column='1' id='type-id-546'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='value' type-id='type-id-552' visibility='default' filepath='./Include/internal/pycore_ast.h' line='601' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__23' size-in-bits='64' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='604' column='1' id='type-id-547'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='patterns' type-id='type-id-553' visibility='default' filepath='./Include/internal/pycore_ast.h' line='605' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__24' size-in-bits='192' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='608' column='1' id='type-id-548'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='keys' type-id='type-id-503' visibility='default' filepath='./Include/internal/pycore_ast.h' line='609' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='patterns' type-id='type-id-553' visibility='default' filepath='./Include/internal/pycore_ast.h' line='610' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='rest' type-id='type-id-525' visibility='default' filepath='./Include/internal/pycore_ast.h' line='611' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__25' size-in-bits='256' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='614' column='1' id='type-id-549'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='cls' type-id='type-id-502' visibility='default' filepath='./Include/internal/pycore_ast.h' line='615' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='patterns' type-id='type-id-553' visibility='default' filepath='./Include/internal/pycore_ast.h' line='616' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='kwd_attrs' type-id='type-id-535' visibility='default' filepath='./Include/internal/pycore_ast.h' line='617' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='kwd_patterns' type-id='type-id-553' visibility='default' filepath='./Include/internal/pycore_ast.h' line='618' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__27' size-in-bits='128' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='625' column='1' id='type-id-551'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='pattern' type-id='type-id-450' visibility='default' filepath='./Include/internal/pycore_ast.h' line='626' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='name' type-id='type-id-525' visibility='default' filepath='./Include/internal/pycore_ast.h' line='627' column='1'/> + </data-member> + </class-decl> + <enum-decl name='_type_ignore_kind' filepath='./Include/internal/pycore_ast.h' line='641' column='1' id='type-id-554'> + <underlying-type type-id='type-id-24'/> + <enumerator name='TypeIgnore_kind' value='1'/> + </enum-decl> + <class-decl name='_type_ignore' size-in-bits='192' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='642' column='1' id='type-id-555'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='kind' type-id='type-id-554' visibility='default' filepath='./Include/internal/pycore_ast.h' line='643' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='v' type-id='type-id-556' visibility='default' filepath='./Include/internal/pycore_ast.h' line='650' column='1'/> + </data-member> + </class-decl> + <union-decl name='__anonymous_union__5' size-in-bits='128' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='644' column='1' id='type-id-556'> + <data-member access='public'> + <var-decl name='TypeIgnore' type-id='type-id-557' visibility='default' filepath='./Include/internal/pycore_ast.h' line='648' column='1'/> + </data-member> + </union-decl> + <class-decl name='__anonymous_struct__39' size-in-bits='128' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='645' column='1' id='type-id-557'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='lineno' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='646' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='tag' type-id='type-id-527' visibility='default' filepath='./Include/internal/pycore_ast.h' line='647' column='1'/> + </data-member> + </class-decl> + <enum-decl name='_type_param_kind' filepath='./Include/internal/pycore_ast.h' line='653' column='1' id='type-id-558'> + <underlying-type type-id='type-id-24'/> + <enumerator name='TypeVar_kind' value='1'/> + <enumerator name='ParamSpec_kind' value='2'/> + <enumerator name='TypeVarTuple_kind' value='3'/> + </enum-decl> + <class-decl name='_type_param' size-in-bits='320' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='654' column='1' id='type-id-559'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='kind' type-id='type-id-558' visibility='default' filepath='./Include/internal/pycore_ast.h' line='655' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='v' type-id='type-id-560' visibility='default' filepath='./Include/internal/pycore_ast.h' line='670' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='lineno' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='671' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='224'> + <var-decl name='col_offset' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='672' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='end_lineno' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='673' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='288'> + <var-decl name='end_col_offset' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='674' column='1'/> + </data-member> + </class-decl> + <union-decl name='__anonymous_union__2' size-in-bits='128' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='656' column='1' id='type-id-560'> + <data-member access='public'> + <var-decl name='TypeVar' type-id='type-id-561' visibility='default' filepath='./Include/internal/pycore_ast.h' line='660' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='ParamSpec' type-id='type-id-550' visibility='default' filepath='./Include/internal/pycore_ast.h' line='664' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='TypeVarTuple' type-id='type-id-550' visibility='default' filepath='./Include/internal/pycore_ast.h' line='668' column='1'/> + </data-member> + </union-decl> + <class-decl name='__anonymous_struct__3' size-in-bits='128' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='657' column='1' id='type-id-561'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='name' type-id='type-id-525' visibility='default' filepath='./Include/internal/pycore_ast.h' line='658' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='bound' type-id='type-id-502' visibility='default' filepath='./Include/internal/pycore_ast.h' line='659' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__4' size-in-bits='64' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='662' column='1' id='type-id-550'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='name' type-id='type-id-525' visibility='default' filepath='./Include/internal/pycore_ast.h' line='663' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='Py_UCS4' type-id='type-id-352' filepath='./Include/unicodeobject.h' line='102' column='1' id='type-id-250'/> + <pointer-type-def type-id='type-id-461' size-in-bits='64' id='type-id-332'/> + <pointer-type-def type-id='type-id-540' size-in-bits='64' id='type-id-471'/> + <pointer-type-def type-id='type-id-537' size-in-bits='64' id='type-id-470'/> + <pointer-type-def type-id='type-id-542' size-in-bits='64' id='type-id-473'/> + <pointer-type-def type-id='type-id-494' size-in-bits='64' id='type-id-467'/> + <pointer-type-def type-id='type-id-544' size-in-bits='64' id='type-id-474'/> + <pointer-type-def type-id='type-id-505' size-in-bits='64' id='type-id-469'/> + <pointer-type-def type-id='type-id-555' size-in-bits='64' id='type-id-475'/> + <pointer-type-def type-id='type-id-559' size-in-bits='64' id='type-id-476'/> + <pointer-type-def type-id='type-id-541' size-in-bits='64' id='type-id-472'/> + <pointer-type-def type-id='type-id-481' size-in-bits='64' id='type-id-534'/> + <pointer-type-def type-id='type-id-479' size-in-bits='64' id='type-id-533'/> + <pointer-type-def type-id='type-id-463' size-in-bits='64' id='type-id-562'/> + <pointer-type-def type-id='type-id-465' size-in-bits='64' id='type-id-535'/> + <pointer-type-def type-id='type-id-485' size-in-bits='64' id='type-id-532'/> + <pointer-type-def type-id='type-id-487' size-in-bits='64' id='type-id-553'/> + <pointer-type-def type-id='type-id-477' size-in-bits='64' id='type-id-500'/> + <pointer-type-def type-id='type-id-489' size-in-bits='64' id='type-id-501'/> + <pointer-type-def type-id='type-id-491' size-in-bits='64' id='type-id-528'/> + <pointer-type-def type-id='type-id-483' size-in-bits='64' id='type-id-531'/> + <function-decl name='PyBytes_FromString' mangled-name='PyBytes_FromString' filepath='./Include/bytesobject.h' line='35' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyBytes_FromString'> + <parameter type-id='type-id-12'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyBytes_Concat' mangled-name='PyBytes_Concat' filepath='./Include/bytesobject.h' line='44' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyBytes_Concat'> + <parameter type-id='type-id-233'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyUnicodeWriter_Init' mangled-name='_PyUnicodeWriter_Init' filepath='./Include/cpython/unicodeobject.h' line='515' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicodeWriter_Init'> + <parameter type-id='type-id-332'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyUnicodeWriter_WriteStr' mangled-name='_PyUnicodeWriter_WriteStr' filepath='./Include/cpython/unicodeobject.h' line='561' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicodeWriter_WriteStr'> + <parameter type-id='type-id-332'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyUnicodeWriter_Finish' mangled-name='_PyUnicodeWriter_Finish' filepath='./Include/cpython/unicodeobject.h' line='594' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicodeWriter_Finish'> + <parameter type-id='type-id-332'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyUnicodeWriter_Dealloc' mangled-name='_PyUnicodeWriter_Dealloc' filepath='./Include/cpython/unicodeobject.h' line='598' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicodeWriter_Dealloc'> + <parameter type-id='type-id-332'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_Py_asdl_generic_seq_new' filepath='./Include/internal/pycore_asdl.h' line='47' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-14'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-562'/> + </function-decl> + <function-decl name='_Py_asdl_identifier_seq_new' filepath='./Include/internal/pycore_asdl.h' line='48' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-14'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-535'/> + </function-decl> + <function-decl name='_Py_asdl_int_seq_new' filepath='./Include/internal/pycore_asdl.h' line='49' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-14'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-564'/> + </function-decl> + <function-decl name='_Py_asdl_expr_seq_new' filepath='./Include/internal/pycore_ast.h' line='76' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-14'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-503'/> + </function-decl> + <function-decl name='_Py_asdl_arg_seq_new' filepath='./Include/internal/pycore_ast.h' line='106' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-14'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-565'/> + </function-decl> + <function-decl name='_Py_asdl_keyword_seq_new' filepath='./Include/internal/pycore_ast.h' line='113' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-14'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-529'/> + </function-decl> + <function-decl name='_Py_asdl_pattern_seq_new' filepath='./Include/internal/pycore_ast.h' line='142' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-14'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-553'/> + </function-decl> + <function-decl name='_Py_asdl_type_ignore_seq_new' filepath='./Include/internal/pycore_ast.h' line='149' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-14'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-501'/> + </function-decl> + <function-decl name='_PyAST_Module' filepath='./Include/internal/pycore_ast.h' line='679' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-500'/> + <parameter type-id='type-id-501'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-468'/> + </function-decl> + <function-decl name='_PyAST_FunctionDef' filepath='./Include/internal/pycore_ast.h' line='685' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-525'/> + <parameter type-id='type-id-526'/> + <parameter type-id='type-id-500'/> + <parameter type-id='type-id-503'/> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-527'/> + <parameter type-id='type-id-528'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-452'/> + </function-decl> + <function-decl name='_PyAST_AsyncFunctionDef' filepath='./Include/internal/pycore_ast.h' line='690' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-525'/> + <parameter type-id='type-id-526'/> + <parameter type-id='type-id-500'/> + <parameter type-id='type-id-503'/> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-527'/> + <parameter type-id='type-id-528'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-452'/> + </function-decl> + <function-decl name='_PyAST_ClassDef' filepath='./Include/internal/pycore_ast.h' line='696' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-525'/> + <parameter type-id='type-id-503'/> + <parameter type-id='type-id-529'/> + <parameter type-id='type-id-500'/> + <parameter type-id='type-id-503'/> + <parameter type-id='type-id-528'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-452'/> + </function-decl> + <function-decl name='_PyAST_Call' filepath='./Include/internal/pycore_ast.h' line='814' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-503'/> + <parameter type-id='type-id-529'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-502'/> + </function-decl> + <function-decl name='_PyAST_FormattedValue' filepath='./Include/internal/pycore_ast.h' line='817' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-502'/> + </function-decl> + <function-decl name='_PyAST_JoinedStr' filepath='./Include/internal/pycore_ast.h' line='820' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-503'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-502'/> + </function-decl> + <function-decl name='_PyAST_Attribute' filepath='./Include/internal/pycore_ast.h' line='825' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-525'/> + <parameter type-id='type-id-566'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-502'/> + </function-decl> + <function-decl name='_PyAST_Subscript' filepath='./Include/internal/pycore_ast.h' line='828' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-566'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-502'/> + </function-decl> + <function-decl name='_PyAST_Starred' filepath='./Include/internal/pycore_ast.h' line='831' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-566'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-502'/> + </function-decl> + <function-decl name='_PyAST_List' filepath='./Include/internal/pycore_ast.h' line='837' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-503'/> + <parameter type-id='type-id-566'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-502'/> + </function-decl> + <function-decl name='_PyAST_Tuple' filepath='./Include/internal/pycore_ast.h' line='840' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-503'/> + <parameter type-id='type-id-566'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-502'/> + </function-decl> + <function-decl name='_PyAST_arguments' filepath='./Include/internal/pycore_ast.h' line='853' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-565'/> + <parameter type-id='type-id-565'/> + <parameter type-id='type-id-567'/> + <parameter type-id='type-id-565'/> + <parameter type-id='type-id-503'/> + <parameter type-id='type-id-567'/> + <parameter type-id='type-id-503'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-526'/> + </function-decl> + <function-decl name='_PyAST_arg' filepath='./Include/internal/pycore_ast.h' line='857' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-525'/> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-527'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-567'/> + </function-decl> + <function-decl name='_PyAST_alias' filepath='./Include/internal/pycore_ast.h' line='863' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-525'/> + <parameter type-id='type-id-525'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-444'/> + </function-decl> + <function-decl name='_PyAST_TypeIgnore' filepath='./Include/internal/pycore_ast.h' line='894' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-527'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-454'/> + </function-decl> + <function-decl name='PyUnicode_FromString' mangled-name='PyUnicode_FromString' filepath='./Include/unicodeobject.h' line='137' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_FromString'> + <parameter type-id='type-id-12'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyUnicode_GetLength' mangled-name='PyUnicode_GetLength' filepath='./Include/unicodeobject.h' line='169' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_GetLength'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-14'/> + </function-decl> + <function-decl name='strcpy' filepath='/usr/include/string.h' line='141' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-15'/> + <parameter type-id='type-id-12'/> + <return type-id='type-id-15'/> + </function-decl> + <function-decl name='strpbrk' filepath='/usr/include/string.h' line='323' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-12'/> + <return type-id='type-id-15'/> + </function-decl> + <function-decl name='_PyPegen_new_identifier' filepath='Parser/pegen.h' line='296' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <parameter type-id='type-id-12'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyPegen_parse_string' filepath='Parser/string_parser.h' line='8' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <parameter type-id='type-id-569'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyPegen_decode_string' filepath='Parser/string_parser.h' line='9' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-19'/> + <parameter type-id='type-id-569'/> + <return type-id='type-id-2'/> + </function-decl> + <class-decl name='__anonymous_struct__7' size-in-bits='64' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='228' column='1' id='type-id-509'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='value' type-id='type-id-502' visibility='default' filepath='./Include/internal/pycore_ast.h' line='229' column='1'/> + </data-member> + </class-decl> + </abi-instr> + <abi-instr address-size='64' path='Parser/myreadline.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <array-type-def dimensions='1' type-id='type-id-570' size-in-bits='512' id='type-id-571'> + <subrange length='8' type-id='type-id-28' id='type-id-572'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-573' size-in-bits='5120' id='type-id-574'> + <subrange length='80' type-id='type-id-28' id='type-id-575'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-329' size-in-bits='512' id='type-id-576'> + <subrange length='8' type-id='type-id-28' id='type-id-572'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-346' size-in-bits='5120' id='type-id-577'> + <subrange length='80' type-id='type-id-28' id='type-id-575'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-340' size-in-bits='5120' id='type-id-578'> + <subrange length='80' type-id='type-id-28' id='type-id-575'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-342' size-in-bits='512' id='type-id-579'> + <subrange length='8' type-id='type-id-28' id='type-id-572'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-366' size-in-bits='512' id='type-id-580'> + <subrange length='8' type-id='type-id-28' id='type-id-572'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-249' size-in-bits='5120' id='type-id-581'> + <subrange length='80' type-id='type-id-28' id='type-id-575'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-240' size-in-bits='67072' id='type-id-582'> + <subrange length='262' type-id='type-id-28' id='type-id-583'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-2' size-in-bits='512' id='type-id-584'> + <subrange length='8' type-id='type-id-28' id='type-id-572'/> + </array-type-def> + <array-type-def dimensions='2' type-id='type-id-2' size-in-bits='8704' id='type-id-585'> + <subrange length='8' type-id='type-id-28' id='type-id-572'/> + <subrange length='17' type-id='type-id-28' id='type-id-586'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-587' size-in-bits='1280' id='type-id-588'> + <subrange length='20' type-id='type-id-28' id='type-id-589'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-435' size-in-bits='512' id='type-id-590'> + <subrange length='8' type-id='type-id-28' id='type-id-572'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-591' size-in-bits='32' id='type-id-592'> + <subrange length='1' type-id='type-id-28' id='type-id-443'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-593' size-in-bits='5120' id='type-id-594'> + <subrange length='80' type-id='type-id-28' id='type-id-575'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-595' size-in-bits='49152' id='type-id-596'> + <subrange length='128' type-id='type-id-28' id='type-id-437'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-597' size-in-bits='65536' id='type-id-598'> + <subrange length='128' type-id='type-id-28' id='type-id-437'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-599' size-in-bits='98304' id='type-id-600'> + <subrange length='256' type-id='type-id-28' id='type-id-62'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-601' size-in-bits='4096' id='type-id-602'> + <subrange length='32' type-id='type-id-28' id='type-id-60'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-603' size-in-bits='1048576' id='type-id-604'> + <subrange length='16384' type-id='type-id-28' id='type-id-605'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-606' size-in-bits='2097152' id='type-id-607'> + <subrange length='32768' type-id='type-id-28' id='type-id-608'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-609' size-in-bits='2097152' id='type-id-610'> + <subrange length='32768' type-id='type-id-28' id='type-id-608'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-611' size-in-bits='4160' id='type-id-612'> + <subrange length='65' type-id='type-id-28' id='type-id-64'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-613' size-in-bits='2048' id='type-id-614'> + <subrange length='32' type-id='type-id-28' id='type-id-60'/> + </array-type-def> + <type-decl name='bool' size-in-bits='8' id='type-id-615'/> + <array-type-def dimensions='1' type-id='type-id-48' size-in-bits='320' id='type-id-616'> + <subrange length='40' type-id='type-id-28' id='type-id-617'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-48' size-in-bits='384' id='type-id-618'> + <subrange length='48' type-id='type-id-28' id='type-id-619'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-48' size-in-bits='32' id='type-id-620'> + <subrange length='4' type-id='type-id-28' id='type-id-223'/> + </array-type-def> + <class-decl name='PyAsyncGenASend' is-struct='yes' visibility='default' is-declaration-only='yes' id='type-id-621'/> + <class-decl name='_PyAsyncGenWrappedValue' is-struct='yes' visibility='default' is-declaration-only='yes' id='type-id-622'/> + <class-decl name='_dictkeysobject' size-in-bits='256' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_dict.h' line='72' column='1' id='type-id-350'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='dk_refcnt' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_dict.h' line='73' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='dk_log2_size' type-id='type-id-325' visibility='default' filepath='./Include/internal/pycore_dict.h' line='76' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='72'> + <var-decl name='dk_log2_index_bytes' type-id='type-id-325' visibility='default' filepath='./Include/internal/pycore_dict.h' line='79' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='80'> + <var-decl name='dk_kind' type-id='type-id-325' visibility='default' filepath='./Include/internal/pycore_dict.h' line='82' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='96'> + <var-decl name='dk_version' type-id='type-id-352' visibility='default' filepath='./Include/internal/pycore_dict.h' line='85' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='dk_usable' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_dict.h' line='88' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='dk_nentries' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_dict.h' line='91' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='dk_indices' type-id='type-id-257' visibility='default' filepath='./Include/internal/pycore_dict.h' line='106' column='1'/> + </data-member> + </class-decl> + <class-decl name='_dictvalues' size-in-bits='64' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_dict.h' line='122' column='1' id='type-id-351'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='values' type-id='type-id-353' visibility='default' filepath='./Include/internal/pycore_dict.h' line='123' column='1'/> + </data-member> + </class-decl> + <class-decl name='code_arena_st' is-struct='yes' visibility='default' is-declaration-only='yes' id='type-id-623'/> + <array-type-def dimensions='1' type-id='type-id-384' size-in-bits='32' id='type-id-624'> + <subrange length='1' type-id='type-id-28' id='type-id-443'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-251' size-in-bits='18432' id='type-id-625'> + <subrange length='288' type-id='type-id-28' id='type-id-626'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-397' size-in-bits='16320' id='type-id-627'> + <subrange length='255' type-id='type-id-28' id='type-id-628'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-629' size-in-bits='576' id='type-id-630'> + <subrange length='3' type-id='type-id-28' id='type-id-631'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-632' size-in-bits='576' id='type-id-633'> + <subrange length='3' type-id='type-id-28' id='type-id-631'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-8' size-in-bits='640' id='type-id-634'> + <subrange length='20' type-id='type-id-28' id='type-id-589'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-8' size-in-bits='896' id='type-id-635'> + <subrange length='28' type-id='type-id-28' id='type-id-636'/> + </array-type-def> + <type-decl name='long long int' size-in-bits='64' id='type-id-378'/> + <type-decl name='long long unsigned int' size-in-bits='64' id='type-id-387'/> + <array-type-def dimensions='1' type-id='type-id-637' size-in-bits='4096' id='type-id-638'> + <subrange length='64' type-id='type-id-28' id='type-id-639'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-640' size-in-bits='640' id='type-id-641'> + <subrange length='10' type-id='type-id-28' id='type-id-642'/> + </array-type-def> + <type-decl name='short int' size-in-bits='16' id='type-id-71'/> + <array-type-def dimensions='1' type-id='type-id-410' size-in-bits='64000' id='type-id-643'> + <subrange length='200' type-id='type-id-28' id='type-id-644'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-645' size-in-bits='96' id='type-id-646'> + <subrange length='1' type-id='type-id-28' id='type-id-443'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-647' size-in-bits='786432' id='type-id-648'> + <subrange length='4096' type-id='type-id-28' id='type-id-649'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-325' size-in-bits='80' id='type-id-650'> + <subrange length='10' type-id='type-id-28' id='type-id-642'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-325' size-in-bits='88' id='type-id-651'> + <subrange length='11' type-id='type-id-28' id='type-id-652'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-325' size-in-bits='96' id='type-id-653'> + <subrange length='12' type-id='type-id-28' id='type-id-654'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-325' size-in-bits='104' id='type-id-655'> + <subrange length='13' type-id='type-id-28' id='type-id-656'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-325' size-in-bits='112' id='type-id-657'> + <subrange length='14' type-id='type-id-28' id='type-id-658'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-325' size-in-bits='120' id='type-id-659'> + <subrange length='15' type-id='type-id-28' id='type-id-660'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-325' size-in-bits='128' id='type-id-661'> + <subrange length='16' type-id='type-id-28' id='type-id-57'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-325' size-in-bits='136' id='type-id-662'> + <subrange length='17' type-id='type-id-28' id='type-id-586'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-325' size-in-bits='144' id='type-id-663'> + <subrange length='18' type-id='type-id-28' id='type-id-664'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-325' size-in-bits='152' id='type-id-665'> + <subrange length='19' type-id='type-id-28' id='type-id-666'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-325' size-in-bits='8' id='type-id-667'> + <subrange length='1' type-id='type-id-28' id='type-id-443'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-325' size-in-bits='160' id='type-id-668'> + <subrange length='20' type-id='type-id-28' id='type-id-589'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-325' size-in-bits='168' id='type-id-669'> + <subrange length='21' type-id='type-id-28' id='type-id-670'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-325' size-in-bits='184' id='type-id-671'> + <subrange length='23' type-id='type-id-28' id='type-id-672'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-325' size-in-bits='192' id='type-id-673'> + <subrange length='24' type-id='type-id-28' id='type-id-674'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-325' size-in-bits='200' id='type-id-675'> + <subrange length='25' type-id='type-id-28' id='type-id-676'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-325' size-in-bits='208' id='type-id-677'> + <subrange length='26' type-id='type-id-28' id='type-id-678'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-325' size-in-bits='224' id='type-id-679'> + <subrange length='28' type-id='type-id-28' id='type-id-636'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-325' size-in-bits='16' id='type-id-680'> + <subrange length='2' type-id='type-id-28' id='type-id-681'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-325' size-in-bits='248' id='type-id-682'> + <subrange length='31' type-id='type-id-28' id='type-id-683'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-325' size-in-bits='288' id='type-id-684'> + <subrange length='36' type-id='type-id-28' id='type-id-685'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-325' size-in-bits='24' id='type-id-686'> + <subrange length='3' type-id='type-id-28' id='type-id-631'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-325' size-in-bits='32' id='type-id-687'> + <subrange length='4' type-id='type-id-28' id='type-id-223'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-325' size-in-bits='40' id='type-id-688'> + <subrange length='5' type-id='type-id-28' id='type-id-689'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-325' size-in-bits='48' id='type-id-690'> + <subrange length='6' type-id='type-id-28' id='type-id-401'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-325' size-in-bits='56' id='type-id-691'> + <subrange length='7' type-id='type-id-28' id='type-id-692'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-325' size-in-bits='64' id='type-id-693'> + <subrange length='8' type-id='type-id-28' id='type-id-572'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-325' size-in-bits='72' id='type-id-694'> + <subrange length='9' type-id='type-id-28' id='type-id-695'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-95' size-in-bits='64' id='type-id-696'> + <subrange length='2' type-id='type-id-28' id='type-id-681'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-28' size-in-bits='1024' id='type-id-697'> + <subrange length='16' type-id='type-id-28' id='type-id-57'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-698' size-in-bits='8320' id='type-id-699'> + <subrange length='65' type-id='type-id-28' id='type-id-64'/> + </array-type-def> + <class-decl name='PyBytesObject' size-in-bits='320' is-struct='yes' naming-typedef-id='type-id-700' visibility='default' filepath='./Include/cpython/bytesobject.h' line='5' column='1' id='type-id-701'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='ob_base' type-id='type-id-321' visibility='default' filepath='./Include/cpython/bytesobject.h' line='6' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='ob_shash' type-id='type-id-305' visibility='default' filepath='./Include/cpython/bytesobject.h' line='7' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='ob_sval' type-id='type-id-702' visibility='default' filepath='./Include/cpython/bytesobject.h' line='8' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='PyBytesObject' type-id='type-id-701' filepath='./Include/cpython/bytesobject.h' line='15' column='1' id='type-id-700'/> + <class-decl name='_Py_LocalMonitors' size-in-bits='120' is-struct='yes' visibility='default' filepath='./Include/cpython/code.h' line='20' column='1' id='type-id-703'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='tools' type-id='type-id-659' visibility='default' filepath='./Include/cpython/code.h' line='22' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='_Py_LocalMonitors' type-id='type-id-703' filepath='./Include/cpython/code.h' line='23' column='1' id='type-id-704'/> + <class-decl name='_Py_GlobalMonitors' size-in-bits='120' is-struct='yes' visibility='default' filepath='./Include/cpython/code.h' line='25' column='1' id='type-id-705'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='tools' type-id='type-id-659' visibility='default' filepath='./Include/cpython/code.h' line='26' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='_Py_GlobalMonitors' type-id='type-id-705' filepath='./Include/cpython/code.h' line='27' column='1' id='type-id-706'/> + <union-decl name='_Py_CODEUNIT' size-in-bits='16' naming-typedef-id='type-id-707' visibility='default' filepath='./Include/cpython/code.h' line='38' column='1' id='type-id-708'> + <data-member access='public'> + <var-decl name='cache' type-id='type-id-709' visibility='default' filepath='./Include/cpython/code.h' line='39' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='op' type-id='type-id-710' visibility='default' filepath='./Include/cpython/code.h' line='43' column='1'/> + </data-member> + </union-decl> + <class-decl name='__anonymous_struct__747' size-in-bits='16' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/cpython/code.h' line='40' column='1' id='type-id-710'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='code' type-id='type-id-325' visibility='default' filepath='./Include/cpython/code.h' line='41' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='8'> + <var-decl name='arg' type-id='type-id-325' visibility='default' filepath='./Include/cpython/code.h' line='42' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='_Py_CODEUNIT' type-id='type-id-708' filepath='./Include/cpython/code.h' line='44' column='1' id='type-id-707'/> + <class-decl name='_PyCoCached' size-in-bits='256' is-struct='yes' naming-typedef-id='type-id-711' visibility='default' filepath='./Include/cpython/code.h' line='71' column='1' id='type-id-712'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='_co_code' type-id='type-id-2' visibility='default' filepath='./Include/cpython/code.h' line='72' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='_co_varnames' type-id='type-id-2' visibility='default' filepath='./Include/cpython/code.h' line='73' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='_co_cellvars' type-id='type-id-2' visibility='default' filepath='./Include/cpython/code.h' line='74' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='_co_freevars' type-id='type-id-2' visibility='default' filepath='./Include/cpython/code.h' line='75' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='_PyCoCached' type-id='type-id-712' filepath='./Include/cpython/code.h' line='76' column='1' id='type-id-711'/> + <class-decl name='_PyCoLineInstrumentationData' size-in-bits='16' is-struct='yes' naming-typedef-id='type-id-713' visibility='default' filepath='./Include/cpython/code.h' line='81' column='1' id='type-id-714'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='original_opcode' type-id='type-id-325' visibility='default' filepath='./Include/cpython/code.h' line='82' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='8'> + <var-decl name='line_delta' type-id='type-id-370' visibility='default' filepath='./Include/cpython/code.h' line='83' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='_PyCoLineInstrumentationData' type-id='type-id-714' filepath='./Include/cpython/code.h' line='84' column='1' id='type-id-713'/> + <class-decl name='_PyCoMonitoringData' size-in-bits='576' is-struct='yes' naming-typedef-id='type-id-715' visibility='default' filepath='./Include/cpython/code.h' line='89' column='1' id='type-id-716'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='local_monitors' type-id='type-id-704' visibility='default' filepath='./Include/cpython/code.h' line='91' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='120'> + <var-decl name='active_monitors' type-id='type-id-704' visibility='default' filepath='./Include/cpython/code.h' line='93' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='tools' type-id='type-id-717' visibility='default' filepath='./Include/cpython/code.h' line='95' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='lines' type-id='type-id-718' visibility='default' filepath='./Include/cpython/code.h' line='97' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='384'> + <var-decl name='line_tools' type-id='type-id-717' visibility='default' filepath='./Include/cpython/code.h' line='99' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='448'> + <var-decl name='per_instruction_opcodes' type-id='type-id-717' visibility='default' filepath='./Include/cpython/code.h' line='102' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='512'> + <var-decl name='per_instruction_tools' type-id='type-id-717' visibility='default' filepath='./Include/cpython/code.h' line='104' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='_PyCoMonitoringData' type-id='type-id-716' filepath='./Include/cpython/code.h' line='105' column='1' id='type-id-715'/> + <class-decl name='PyCodeObject' size-in-bits='1600' is-struct='yes' visibility='default' filepath='./Include/cpython/code.h' line='175' column='1' id='type-id-719'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='ob_base' type-id='type-id-321' visibility='default' filepath='./Include/cpython/code.h' line='175' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='co_consts' type-id='type-id-2' visibility='default' filepath='./Include/cpython/code.h' line='175' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='co_names' type-id='type-id-2' visibility='default' filepath='./Include/cpython/code.h' line='175' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='co_exceptiontable' type-id='type-id-2' visibility='default' filepath='./Include/cpython/code.h' line='175' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='384'> + <var-decl name='co_flags' type-id='type-id-8' visibility='default' filepath='./Include/cpython/code.h' line='175' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='416'> + <var-decl name='co_argcount' type-id='type-id-8' visibility='default' filepath='./Include/cpython/code.h' line='175' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='448'> + <var-decl name='co_posonlyargcount' type-id='type-id-8' visibility='default' filepath='./Include/cpython/code.h' line='175' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='480'> + <var-decl name='co_kwonlyargcount' type-id='type-id-8' visibility='default' filepath='./Include/cpython/code.h' line='175' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='512'> + <var-decl name='co_stacksize' type-id='type-id-8' visibility='default' filepath='./Include/cpython/code.h' line='175' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='544'> + <var-decl name='co_firstlineno' type-id='type-id-8' visibility='default' filepath='./Include/cpython/code.h' line='175' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='576'> + <var-decl name='co_nlocalsplus' type-id='type-id-8' visibility='default' filepath='./Include/cpython/code.h' line='175' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='608'> + <var-decl name='co_framesize' type-id='type-id-8' visibility='default' filepath='./Include/cpython/code.h' line='175' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='640'> + <var-decl name='co_nlocals' type-id='type-id-8' visibility='default' filepath='./Include/cpython/code.h' line='175' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='672'> + <var-decl name='co_ncellvars' type-id='type-id-8' visibility='default' filepath='./Include/cpython/code.h' line='175' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='704'> + <var-decl name='co_nfreevars' type-id='type-id-8' visibility='default' filepath='./Include/cpython/code.h' line='175' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='736'> + <var-decl name='co_version' type-id='type-id-352' visibility='default' filepath='./Include/cpython/code.h' line='175' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='768'> + <var-decl name='co_localsplusnames' type-id='type-id-2' visibility='default' filepath='./Include/cpython/code.h' line='175' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='832'> + <var-decl name='co_localspluskinds' type-id='type-id-2' visibility='default' filepath='./Include/cpython/code.h' line='175' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='896'> + <var-decl name='co_filename' type-id='type-id-2' visibility='default' filepath='./Include/cpython/code.h' line='175' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='960'> + <var-decl name='co_name' type-id='type-id-2' visibility='default' filepath='./Include/cpython/code.h' line='175' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1024'> + <var-decl name='co_qualname' type-id='type-id-2' visibility='default' filepath='./Include/cpython/code.h' line='175' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1088'> + <var-decl name='co_linetable' type-id='type-id-2' visibility='default' filepath='./Include/cpython/code.h' line='175' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1152'> + <var-decl name='co_weakreflist' type-id='type-id-2' visibility='default' filepath='./Include/cpython/code.h' line='175' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1216'> + <var-decl name='_co_cached' type-id='type-id-720' visibility='default' filepath='./Include/cpython/code.h' line='175' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1280'> + <var-decl name='_co_instrumentation_version' type-id='type-id-117' visibility='default' filepath='./Include/cpython/code.h' line='175' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1344'> + <var-decl name='_co_monitoring' type-id='type-id-721' visibility='default' filepath='./Include/cpython/code.h' line='175' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1408'> + <var-decl name='_co_firsttraceable' type-id='type-id-8' visibility='default' filepath='./Include/cpython/code.h' line='175' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1472'> + <var-decl name='co_extra' type-id='type-id-22' visibility='default' filepath='./Include/cpython/code.h' line='175' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1536'> + <var-decl name='co_code_adaptive' type-id='type-id-702' visibility='default' filepath='./Include/cpython/code.h' line='175' column='1'/> + </data-member> + </class-decl> + <enum-decl name='PyCodeEvent' naming-typedef-id='type-id-722' filepath='./Include/cpython/code.h' line='279' column='1' id='type-id-723'> + <underlying-type type-id='type-id-24'/> + <enumerator name='PY_CODE_EVENT_CREATE' value='0'/> + <enumerator name='PY_CODE_EVENT_DESTROY' value='1'/> + </enum-decl> + <typedef-decl name='PyCodeEvent' type-id='type-id-723' filepath='./Include/cpython/code.h' line='283' column='1' id='type-id-722'/> + <typedef-decl name='PyCode_WatchCallback' type-id='type-id-724' filepath='./Include/cpython/code.h' line='295' column='1' id='type-id-329'/> + <typedef-decl name='PyContext' type-id='type-id-725' filepath='./Include/cpython/context.h' line='9' column='1' id='type-id-726'/> + <typedef-decl name='wrapperfunc' type-id='type-id-727' filepath='./Include/cpython/descrobject.h' line='5' column='1' id='type-id-728'/> + <class-decl name='wrapperbase' size-in-bits='448' is-struct='yes' visibility='default' filepath='./Include/cpython/descrobject.h' line='11' column='1' id='type-id-333'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='name' type-id='type-id-12' visibility='default' filepath='./Include/cpython/descrobject.h' line='12' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='offset' type-id='type-id-8' visibility='default' filepath='./Include/cpython/descrobject.h' line='13' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='function' type-id='type-id-22' visibility='default' filepath='./Include/cpython/descrobject.h' line='14' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='wrapper' type-id='type-id-728' visibility='default' filepath='./Include/cpython/descrobject.h' line='15' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='doc' type-id='type-id-12' visibility='default' filepath='./Include/cpython/descrobject.h' line='16' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='flags' type-id='type-id-8' visibility='default' filepath='./Include/cpython/descrobject.h' line='17' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='384'> + <var-decl name='name_strobj' type-id='type-id-2' visibility='default' filepath='./Include/cpython/descrobject.h' line='18' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='PyDictKeysObject' type-id='type-id-350' filepath='./Include/cpython/dictobject.h' line='5' column='1' id='type-id-348'/> + <typedef-decl name='PyDictValues' type-id='type-id-351' filepath='./Include/cpython/dictobject.h' line='6' column='1' id='type-id-349'/> + <class-decl name='PyDictObject' size-in-bits='384' is-struct='yes' naming-typedef-id='type-id-343' visibility='default' filepath='./Include/cpython/dictobject.h' line='11' column='1' id='type-id-344'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='ob_base' type-id='type-id-345' visibility='default' filepath='./Include/cpython/dictobject.h' line='12' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='ma_used' type-id='type-id-14' visibility='default' filepath='./Include/cpython/dictobject.h' line='15' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='ma_version_tag' type-id='type-id-117' visibility='default' filepath='./Include/cpython/dictobject.h' line='20' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='ma_keys' type-id='type-id-346' visibility='default' filepath='./Include/cpython/dictobject.h' line='25' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='ma_values' type-id='type-id-347' visibility='default' filepath='./Include/cpython/dictobject.h' line='32' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='PyDictObject' type-id='type-id-344' filepath='./Include/cpython/dictobject.h' line='33' column='1' id='type-id-343'/> + <enum-decl name='PyDict_WatchEvent' naming-typedef-id='type-id-729' filepath='./Include/cpython/dictobject.h' line='101' column='1' id='type-id-730'> + <underlying-type type-id='type-id-24'/> + <enumerator name='PyDict_EVENT_ADDED' value='0'/> + <enumerator name='PyDict_EVENT_MODIFIED' value='1'/> + <enumerator name='PyDict_EVENT_DELETED' value='2'/> + <enumerator name='PyDict_EVENT_CLONED' value='3'/> + <enumerator name='PyDict_EVENT_CLEARED' value='4'/> + <enumerator name='PyDict_EVENT_DEALLOCATED' value='5'/> + </enum-decl> + <typedef-decl name='PyDict_WatchEvent' type-id='type-id-730' filepath='./Include/cpython/dictobject.h' line='105' column='1' id='type-id-729'/> + <typedef-decl name='PyDict_WatchCallback' type-id='type-id-731' filepath='./Include/cpython/dictobject.h' line='110' column='1' id='type-id-342'/> + <typedef-decl name='Py_OpenCodeHookFunction' type-id='type-id-732' filepath='./Include/cpython/fileobject.h' line='13' column='1' id='type-id-355'/> + <class-decl name='PyFloatObject' size-in-bits='192' is-struct='yes' naming-typedef-id='type-id-733' visibility='default' filepath='./Include/cpython/floatobject.h' line='5' column='1' id='type-id-734'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='ob_base' type-id='type-id-345' visibility='default' filepath='./Include/cpython/floatobject.h' line='6' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='ob_fval' type-id='type-id-251' visibility='default' filepath='./Include/cpython/floatobject.h' line='7' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='PyFloatObject' type-id='type-id-734' filepath='./Include/cpython/floatobject.h' line='8' column='1' id='type-id-733'/> + <class-decl name='PyFunctionObject' size-in-bits='1152' is-struct='yes' naming-typedef-id='type-id-735' visibility='default' filepath='./Include/cpython/funcobject.h' line='36' column='1' id='type-id-736'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='ob_base' type-id='type-id-345' visibility='default' filepath='./Include/cpython/funcobject.h' line='37' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='func_globals' type-id='type-id-2' visibility='default' filepath='./Include/cpython/funcobject.h' line='38' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='func_builtins' type-id='type-id-2' visibility='default' filepath='./Include/cpython/funcobject.h' line='38' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='func_name' type-id='type-id-2' visibility='default' filepath='./Include/cpython/funcobject.h' line='38' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='func_qualname' type-id='type-id-2' visibility='default' filepath='./Include/cpython/funcobject.h' line='38' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='384'> + <var-decl name='func_code' type-id='type-id-2' visibility='default' filepath='./Include/cpython/funcobject.h' line='38' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='448'> + <var-decl name='func_defaults' type-id='type-id-2' visibility='default' filepath='./Include/cpython/funcobject.h' line='38' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='512'> + <var-decl name='func_kwdefaults' type-id='type-id-2' visibility='default' filepath='./Include/cpython/funcobject.h' line='38' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='576'> + <var-decl name='func_closure' type-id='type-id-2' visibility='default' filepath='./Include/cpython/funcobject.h' line='38' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='640'> + <var-decl name='func_doc' type-id='type-id-2' visibility='default' filepath='./Include/cpython/funcobject.h' line='39' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='704'> + <var-decl name='func_dict' type-id='type-id-2' visibility='default' filepath='./Include/cpython/funcobject.h' line='40' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='768'> + <var-decl name='func_weakreflist' type-id='type-id-2' visibility='default' filepath='./Include/cpython/funcobject.h' line='41' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='832'> + <var-decl name='func_module' type-id='type-id-2' visibility='default' filepath='./Include/cpython/funcobject.h' line='42' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='896'> + <var-decl name='func_annotations' type-id='type-id-2' visibility='default' filepath='./Include/cpython/funcobject.h' line='43' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='960'> + <var-decl name='func_typeparams' type-id='type-id-2' visibility='default' filepath='./Include/cpython/funcobject.h' line='44' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1024'> + <var-decl name='vectorcall' type-id='type-id-311' visibility='default' filepath='./Include/cpython/funcobject.h' line='45' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1088'> + <var-decl name='func_version' type-id='type-id-352' visibility='default' filepath='./Include/cpython/funcobject.h' line='54' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='PyFunctionObject' type-id='type-id-736' filepath='./Include/cpython/funcobject.h' line='61' column='1' id='type-id-735'/> + <enum-decl name='PyFunction_WatchEvent' naming-typedef-id='type-id-737' filepath='./Include/cpython/funcobject.h' line='142' column='1' id='type-id-738'> + <underlying-type type-id='type-id-24'/> + <enumerator name='PyFunction_EVENT_CREATE' value='0'/> + <enumerator name='PyFunction_EVENT_DESTROY' value='1'/> + <enumerator name='PyFunction_EVENT_MODIFY_CODE' value='2'/> + <enumerator name='PyFunction_EVENT_MODIFY_DEFAULTS' value='3'/> + <enumerator name='PyFunction_EVENT_MODIFY_KWDEFAULTS' value='4'/> + </enum-decl> + <typedef-decl name='PyFunction_WatchEvent' type-id='type-id-738' filepath='./Include/cpython/funcobject.h' line='146' column='1' id='type-id-737'/> + <typedef-decl name='PyFunction_WatchCallback' type-id='type-id-739' filepath='./Include/cpython/funcobject.h' line='163' column='1' id='type-id-366'/> + <class-decl name='_inittab' size-in-bits='128' is-struct='yes' visibility='default' filepath='./Include/cpython/import.h' line='24' column='1' id='type-id-740'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='name' type-id='type-id-12' visibility='default' filepath='./Include/cpython/import.h' line='25' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='initfunc' type-id='type-id-390' visibility='default' filepath='./Include/cpython/import.h' line='26' column='1'/> + </data-member> + </class-decl> + <class-decl name='PyWideStringList' size-in-bits='128' is-struct='yes' naming-typedef-id='type-id-741' visibility='default' filepath='./Include/cpython/initconfig.h' line='32' column='1' id='type-id-742'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='length' type-id='type-id-14' visibility='default' filepath='./Include/cpython/initconfig.h' line='35' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='items' type-id='type-id-235' visibility='default' filepath='./Include/cpython/initconfig.h' line='36' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='PyWideStringList' type-id='type-id-742' filepath='./Include/cpython/initconfig.h' line='37' column='1' id='type-id-741'/> + <class-decl name='PyPreConfig' size-in-bits='320' is-struct='yes' visibility='default' filepath='./Include/cpython/initconfig.h' line='48' column='1' id='type-id-743'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='_config_init' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='49' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='32'> + <var-decl name='parse_argv' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='53' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='isolated' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='60' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='96'> + <var-decl name='use_environment' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='65' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='configure_locale' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='69' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='160'> + <var-decl name='coerce_c_locale' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='82' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='coerce_c_locale_warn' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='90' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='224'> + <var-decl name='utf8_mode' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='115' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='dev_mode' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='121' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='288'> + <var-decl name='allocator' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='125' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='PyPreConfig' type-id='type-id-743' filepath='./Include/cpython/initconfig.h' line='126' column='1' id='type-id-744'/> + <class-decl name='PyConfig' size-in-bits='3456' is-struct='yes' visibility='default' filepath='./Include/cpython/initconfig.h' line='135' column='1' id='type-id-745'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='_config_init' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='136' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='32'> + <var-decl name='isolated' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='138' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='use_environment' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='139' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='96'> + <var-decl name='dev_mode' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='140' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='install_signal_handlers' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='141' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='160'> + <var-decl name='use_hash_seed' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='142' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='hash_seed' type-id='type-id-28' visibility='default' filepath='./Include/cpython/initconfig.h' line='143' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='faulthandler' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='144' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='288'> + <var-decl name='tracemalloc' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='145' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='perf_profiling' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='146' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='352'> + <var-decl name='import_time' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='147' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='384'> + <var-decl name='code_debug_ranges' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='148' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='416'> + <var-decl name='show_ref_count' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='149' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='448'> + <var-decl name='dump_refs' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='150' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='512'> + <var-decl name='dump_refs_file' type-id='type-id-52' visibility='default' filepath='./Include/cpython/initconfig.h' line='151' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='576'> + <var-decl name='malloc_stats' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='152' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='640'> + <var-decl name='filesystem_encoding' type-id='type-id-52' visibility='default' filepath='./Include/cpython/initconfig.h' line='153' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='704'> + <var-decl name='filesystem_errors' type-id='type-id-52' visibility='default' filepath='./Include/cpython/initconfig.h' line='154' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='768'> + <var-decl name='pycache_prefix' type-id='type-id-52' visibility='default' filepath='./Include/cpython/initconfig.h' line='155' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='832'> + <var-decl name='parse_argv' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='156' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='896'> + <var-decl name='orig_argv' type-id='type-id-741' visibility='default' filepath='./Include/cpython/initconfig.h' line='157' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1024'> + <var-decl name='argv' type-id='type-id-741' visibility='default' filepath='./Include/cpython/initconfig.h' line='158' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1152'> + <var-decl name='xoptions' type-id='type-id-741' visibility='default' filepath='./Include/cpython/initconfig.h' line='159' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1280'> + <var-decl name='warnoptions' type-id='type-id-741' visibility='default' filepath='./Include/cpython/initconfig.h' line='160' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1408'> + <var-decl name='site_import' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='161' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1440'> + <var-decl name='bytes_warning' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='162' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1472'> + <var-decl name='warn_default_encoding' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='163' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1504'> + <var-decl name='inspect' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='164' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1536'> + <var-decl name='interactive' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='165' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1568'> + <var-decl name='optimization_level' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='166' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1600'> + <var-decl name='parser_debug' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='167' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1632'> + <var-decl name='write_bytecode' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='168' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1664'> + <var-decl name='verbose' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='169' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1696'> + <var-decl name='quiet' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='170' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1728'> + <var-decl name='user_site_directory' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='171' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1760'> + <var-decl name='configure_c_stdio' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='172' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1792'> + <var-decl name='buffered_stdio' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='173' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1856'> + <var-decl name='stdio_encoding' type-id='type-id-52' visibility='default' filepath='./Include/cpython/initconfig.h' line='174' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1920'> + <var-decl name='stdio_errors' type-id='type-id-52' visibility='default' filepath='./Include/cpython/initconfig.h' line='175' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1984'> + <var-decl name='check_hash_pycs_mode' type-id='type-id-52' visibility='default' filepath='./Include/cpython/initconfig.h' line='179' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2048'> + <var-decl name='use_frozen_modules' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='180' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2080'> + <var-decl name='safe_path' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='181' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2112'> + <var-decl name='int_max_str_digits' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='182' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2144'> + <var-decl name='pathconfig_warnings' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='185' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2176'> + <var-decl name='program_name' type-id='type-id-52' visibility='default' filepath='./Include/cpython/initconfig.h' line='186' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2240'> + <var-decl name='pythonpath_env' type-id='type-id-52' visibility='default' filepath='./Include/cpython/initconfig.h' line='187' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2304'> + <var-decl name='home' type-id='type-id-52' visibility='default' filepath='./Include/cpython/initconfig.h' line='188' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2368'> + <var-decl name='platlibdir' type-id='type-id-52' visibility='default' filepath='./Include/cpython/initconfig.h' line='189' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2432'> + <var-decl name='module_search_paths_set' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='192' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2496'> + <var-decl name='module_search_paths' type-id='type-id-741' visibility='default' filepath='./Include/cpython/initconfig.h' line='193' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2624'> + <var-decl name='stdlib_dir' type-id='type-id-52' visibility='default' filepath='./Include/cpython/initconfig.h' line='194' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2688'> + <var-decl name='executable' type-id='type-id-52' visibility='default' filepath='./Include/cpython/initconfig.h' line='195' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2752'> + <var-decl name='base_executable' type-id='type-id-52' visibility='default' filepath='./Include/cpython/initconfig.h' line='196' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2816'> + <var-decl name='prefix' type-id='type-id-52' visibility='default' filepath='./Include/cpython/initconfig.h' line='197' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2880'> + <var-decl name='base_prefix' type-id='type-id-52' visibility='default' filepath='./Include/cpython/initconfig.h' line='198' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2944'> + <var-decl name='exec_prefix' type-id='type-id-52' visibility='default' filepath='./Include/cpython/initconfig.h' line='199' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='3008'> + <var-decl name='base_exec_prefix' type-id='type-id-52' visibility='default' filepath='./Include/cpython/initconfig.h' line='200' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='3072'> + <var-decl name='skip_source_first_line' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='203' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='3136'> + <var-decl name='run_command' type-id='type-id-52' visibility='default' filepath='./Include/cpython/initconfig.h' line='204' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='3200'> + <var-decl name='run_module' type-id='type-id-52' visibility='default' filepath='./Include/cpython/initconfig.h' line='205' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='3264'> + <var-decl name='run_filename' type-id='type-id-52' visibility='default' filepath='./Include/cpython/initconfig.h' line='206' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='3328'> + <var-decl name='_install_importlib' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='212' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='3360'> + <var-decl name='_init_main' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='215' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='3392'> + <var-decl name='_is_python_build' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='218' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='PyConfig' type-id='type-id-745' filepath='./Include/cpython/initconfig.h' line='219' column='1' id='type-id-258'/> + <class-decl name='PyListObject' size-in-bits='320' is-struct='yes' naming-typedef-id='type-id-746' visibility='default' filepath='./Include/cpython/listobject.h' line='5' column='1' id='type-id-747'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='ob_base' type-id='type-id-321' visibility='default' filepath='./Include/cpython/listobject.h' line='6' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='ob_item' type-id='type-id-233' visibility='default' filepath='./Include/cpython/listobject.h' line='8' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='allocated' type-id='type-id-14' visibility='default' filepath='./Include/cpython/listobject.h' line='21' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='PyListObject' type-id='type-id-747' filepath='./Include/cpython/listobject.h' line='22' column='1' id='type-id-746'/> + <typedef-decl name='digit' type-id='type-id-352' filepath='./Include/cpython/longintrepr.h' line='43' column='1' id='type-id-384'/> + <class-decl name='_PyLongValue' size-in-bits='128' is-struct='yes' visibility='default' filepath='./Include/cpython/longintrepr.h' line='82' column='1' id='type-id-748'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='lv_tag' type-id='type-id-749' visibility='default' filepath='./Include/cpython/longintrepr.h' line='83' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='ob_digit' type-id='type-id-624' visibility='default' filepath='./Include/cpython/longintrepr.h' line='84' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='_PyLongValue' type-id='type-id-748' filepath='./Include/cpython/longintrepr.h' line='85' column='1' id='type-id-750'/> + <class-decl name='_longobject' size-in-bits='256' is-struct='yes' visibility='default' filepath='./Include/cpython/longintrepr.h' line='87' column='1' id='type-id-751'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='ob_base' type-id='type-id-345' visibility='default' filepath='./Include/cpython/longintrepr.h' line='88' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='long_value' type-id='type-id-750' visibility='default' filepath='./Include/cpython/longintrepr.h' line='89' column='1'/> + </data-member> + </class-decl> + <class-decl name='_PyArg_Parser' size-in-bits='576' is-struct='yes' visibility='default' filepath='./Include/cpython/modsupport.h' line='53' column='1' id='type-id-752'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='initialized' type-id='type-id-8' visibility='default' filepath='./Include/cpython/modsupport.h' line='54' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='format' type-id='type-id-12' visibility='default' filepath='./Include/cpython/modsupport.h' line='55' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='keywords' type-id='type-id-753' visibility='default' filepath='./Include/cpython/modsupport.h' line='56' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='fname' type-id='type-id-12' visibility='default' filepath='./Include/cpython/modsupport.h' line='57' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='custom_msg' type-id='type-id-12' visibility='default' filepath='./Include/cpython/modsupport.h' line='58' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='pos' type-id='type-id-8' visibility='default' filepath='./Include/cpython/modsupport.h' line='59' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='352'> + <var-decl name='min' type-id='type-id-8' visibility='default' filepath='./Include/cpython/modsupport.h' line='60' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='384'> + <var-decl name='max' type-id='type-id-8' visibility='default' filepath='./Include/cpython/modsupport.h' line='61' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='448'> + <var-decl name='kwtuple' type-id='type-id-2' visibility='default' filepath='./Include/cpython/modsupport.h' line='62' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='512'> + <var-decl name='next' type-id='type-id-262' visibility='default' filepath='./Include/cpython/modsupport.h' line='63' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='PyType_WatchCallback' type-id='type-id-754' filepath='./Include/cpython/object.h' line='564' column='1' id='type-id-435'/> + <class-decl name='PyObjectArenaAllocator' size-in-bits='192' is-struct='yes' naming-typedef-id='type-id-420' visibility='default' filepath='./Include/cpython/objimpl.h' line='59' column='1' id='type-id-755'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='ctx' type-id='type-id-22' visibility='default' filepath='./Include/cpython/objimpl.h' line='61' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='alloc' type-id='type-id-756' visibility='default' filepath='./Include/cpython/objimpl.h' line='64' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='free' type-id='type-id-757' visibility='default' filepath='./Include/cpython/objimpl.h' line='67' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='PyObjectArenaAllocator' type-id='type-id-755' filepath='./Include/cpython/objimpl.h' line='68' column='1' id='type-id-420'/> + <class-decl name='PyBaseExceptionObject' size-in-bits='576' is-struct='yes' naming-typedef-id='type-id-758' visibility='default' filepath='./Include/cpython/pyerrors.h' line='13' column='1' id='type-id-759'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='ob_base' type-id='type-id-345' visibility='default' filepath='./Include/cpython/pyerrors.h' line='14' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='dict' type-id='type-id-2' visibility='default' filepath='./Include/cpython/pyerrors.h' line='14' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='args' type-id='type-id-2' visibility='default' filepath='./Include/cpython/pyerrors.h' line='14' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='notes' type-id='type-id-2' visibility='default' filepath='./Include/cpython/pyerrors.h' line='14' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='traceback' type-id='type-id-2' visibility='default' filepath='./Include/cpython/pyerrors.h' line='14' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='384'> + <var-decl name='context' type-id='type-id-2' visibility='default' filepath='./Include/cpython/pyerrors.h' line='14' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='448'> + <var-decl name='cause' type-id='type-id-2' visibility='default' filepath='./Include/cpython/pyerrors.h' line='14' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='512'> + <var-decl name='suppress_context' type-id='type-id-48' visibility='default' filepath='./Include/cpython/pyerrors.h' line='14' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='PyBaseExceptionObject' type-id='type-id-759' filepath='./Include/cpython/pyerrors.h' line='15' column='1' id='type-id-758'/> + <typedef-decl name='atexit_datacallbackfunc' type-id='type-id-760' filepath='./Include/cpython/pylifecycle.h' line='109' column='1' id='type-id-21'/> + <class-decl name='PyMemAllocatorEx' size-in-bits='320' is-struct='yes' naming-typedef-id='type-id-417' visibility='default' filepath='./Include/cpython/pymem.h' line='47' column='1' id='type-id-761'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='ctx' type-id='type-id-22' visibility='default' filepath='./Include/cpython/pymem.h' line='49' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='malloc' type-id='type-id-756' visibility='default' filepath='./Include/cpython/pymem.h' line='52' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='calloc' type-id='type-id-762' visibility='default' filepath='./Include/cpython/pymem.h' line='55' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='realloc' type-id='type-id-763' visibility='default' filepath='./Include/cpython/pymem.h' line='58' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='free' type-id='type-id-764' visibility='default' filepath='./Include/cpython/pymem.h' line='61' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='PyMemAllocatorEx' type-id='type-id-761' filepath='./Include/cpython/pymem.h' line='62' column='1' id='type-id-417'/> + <typedef-decl name='Py_tracefunc' type-id='type-id-765' filepath='./Include/cpython/pystate.h' line='49' column='1' id='type-id-766'/> + <class-decl name='_PyCFrame' size-in-bits='128' is-struct='yes' visibility='default' filepath='./Include/cpython/pystate.h' line='67' column='1' id='type-id-767'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='current_frame' type-id='type-id-375' visibility='default' filepath='./Include/cpython/pystate.h' line='79' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='previous' type-id='type-id-768' visibility='default' filepath='./Include/cpython/pystate.h' line='80' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='_PyCFrame' type-id='type-id-767' filepath='./Include/cpython/pystate.h' line='81' column='1' id='type-id-769'/> + <class-decl name='_err_stackitem' size-in-bits='128' is-struct='yes' visibility='default' filepath='./Include/cpython/pystate.h' line='83' column='1' id='type-id-770'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='exc_value' type-id='type-id-2' visibility='default' filepath='./Include/cpython/pystate.h' line='97' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='previous_item' type-id='type-id-771' visibility='default' filepath='./Include/cpython/pystate.h' line='99' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='_PyErr_StackItem' type-id='type-id-770' filepath='./Include/cpython/pystate.h' line='101' column='1' id='type-id-369'/> + <class-decl name='_stack_chunk' size-in-bits='256' is-struct='yes' visibility='default' filepath='./Include/cpython/pystate.h' line='103' column='1' id='type-id-772'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='previous' type-id='type-id-773' visibility='default' filepath='./Include/cpython/pystate.h' line='104' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='size' type-id='type-id-19' visibility='default' filepath='./Include/cpython/pystate.h' line='105' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='top' type-id='type-id-19' visibility='default' filepath='./Include/cpython/pystate.h' line='106' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='data' type-id='type-id-353' visibility='default' filepath='./Include/cpython/pystate.h' line='107' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='_PyStackChunk' type-id='type-id-772' filepath='./Include/cpython/pystate.h' line='108' column='1' id='type-id-774'/> + <class-decl name='_py_trashcan' size-in-bits='128' is-struct='yes' visibility='default' filepath='./Include/cpython/pystate.h' line='110' column='1' id='type-id-775'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='delete_nesting' type-id='type-id-8' visibility='default' filepath='./Include/cpython/pystate.h' line='111' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='delete_later' type-id='type-id-2' visibility='default' filepath='./Include/cpython/pystate.h' line='112' column='1'/> + </data-member> + </class-decl> + <class-decl name='_ts' size-in-bits='2304' is-struct='yes' visibility='default' filepath='./Include/cpython/pystate.h' line='115' column='1' id='type-id-776'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='prev' type-id='type-id-177' visibility='default' filepath='./Include/cpython/pystate.h' line='118' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='next' type-id='type-id-177' visibility='default' filepath='./Include/cpython/pystate.h' line='119' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='interp' type-id='type-id-20' visibility='default' filepath='./Include/cpython/pystate.h' line='120' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='_status' type-id='type-id-777' visibility='default' filepath='./Include/cpython/pystate.h' line='145' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='224'> + <var-decl name='py_recursion_remaining' type-id='type-id-8' visibility='default' filepath='./Include/cpython/pystate.h' line='147' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='py_recursion_limit' type-id='type-id-8' visibility='default' filepath='./Include/cpython/pystate.h' line='148' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='288'> + <var-decl name='c_recursion_remaining' type-id='type-id-8' visibility='default' filepath='./Include/cpython/pystate.h' line='150' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='recursion_headroom' type-id='type-id-8' visibility='default' filepath='./Include/cpython/pystate.h' line='151' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='352'> + <var-decl name='tracing' type-id='type-id-8' visibility='default' filepath='./Include/cpython/pystate.h' line='156' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='384'> + <var-decl name='what_event' type-id='type-id-8' visibility='default' filepath='./Include/cpython/pystate.h' line='157' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='448'> + <var-decl name='cframe' type-id='type-id-768' visibility='default' filepath='./Include/cpython/pystate.h' line='161' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='512'> + <var-decl name='c_profilefunc' type-id='type-id-766' visibility='default' filepath='./Include/cpython/pystate.h' line='163' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='576'> + <var-decl name='c_tracefunc' type-id='type-id-766' visibility='default' filepath='./Include/cpython/pystate.h' line='164' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='640'> + <var-decl name='c_profileobj' type-id='type-id-2' visibility='default' filepath='./Include/cpython/pystate.h' line='165' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='704'> + <var-decl name='c_traceobj' type-id='type-id-2' visibility='default' filepath='./Include/cpython/pystate.h' line='166' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='768'> + <var-decl name='current_exception' type-id='type-id-2' visibility='default' filepath='./Include/cpython/pystate.h' line='169' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='832'> + <var-decl name='exc_info' type-id='type-id-376' visibility='default' filepath='./Include/cpython/pystate.h' line='174' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='896'> + <var-decl name='dict' type-id='type-id-2' visibility='default' filepath='./Include/cpython/pystate.h' line='176' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='960'> + <var-decl name='gilstate_counter' type-id='type-id-8' visibility='default' filepath='./Include/cpython/pystate.h' line='178' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1024'> + <var-decl name='async_exc' type-id='type-id-2' visibility='default' filepath='./Include/cpython/pystate.h' line='180' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1088'> + <var-decl name='thread_id' type-id='type-id-28' visibility='default' filepath='./Include/cpython/pystate.h' line='181' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1152'> + <var-decl name='native_thread_id' type-id='type-id-28' visibility='default' filepath='./Include/cpython/pystate.h' line='187' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1216'> + <var-decl name='trash' type-id='type-id-775' visibility='default' filepath='./Include/cpython/pystate.h' line='189' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1344'> + <var-decl name='on_delete' type-id='type-id-760' visibility='default' filepath='./Include/cpython/pystate.h' line='214' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1408'> + <var-decl name='on_delete_data' type-id='type-id-22' visibility='default' filepath='./Include/cpython/pystate.h' line='215' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1472'> + <var-decl name='coroutine_origin_tracking_depth' type-id='type-id-8' visibility='default' filepath='./Include/cpython/pystate.h' line='217' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1536'> + <var-decl name='async_gen_firstiter' type-id='type-id-2' visibility='default' filepath='./Include/cpython/pystate.h' line='219' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1600'> + <var-decl name='async_gen_finalizer' type-id='type-id-2' visibility='default' filepath='./Include/cpython/pystate.h' line='220' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1664'> + <var-decl name='context' type-id='type-id-2' visibility='default' filepath='./Include/cpython/pystate.h' line='222' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1728'> + <var-decl name='context_ver' type-id='type-id-117' visibility='default' filepath='./Include/cpython/pystate.h' line='223' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1792'> + <var-decl name='id' type-id='type-id-117' visibility='default' filepath='./Include/cpython/pystate.h' line='226' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1856'> + <var-decl name='datastack_chunk' type-id='type-id-778' visibility='default' filepath='./Include/cpython/pystate.h' line='228' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1920'> + <var-decl name='datastack_top' type-id='type-id-233' visibility='default' filepath='./Include/cpython/pystate.h' line='229' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1984'> + <var-decl name='datastack_limit' type-id='type-id-233' visibility='default' filepath='./Include/cpython/pystate.h' line='230' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2048'> + <var-decl name='exc_state' type-id='type-id-369' visibility='default' filepath='./Include/cpython/pystate.h' line='245' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2176'> + <var-decl name='root_cframe' type-id='type-id-769' visibility='default' filepath='./Include/cpython/pystate.h' line='248' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__749' size-in-bits='32' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/cpython/pystate.h' line='122' column='1' id='type-id-777'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='initialized' type-id='type-id-95' visibility='default' filepath='./Include/cpython/pystate.h' line='127' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1'> + <var-decl name='bound' type-id='type-id-95' visibility='default' filepath='./Include/cpython/pystate.h' line='130' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2'> + <var-decl name='unbound' type-id='type-id-95' visibility='default' filepath='./Include/cpython/pystate.h' line='132' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='3'> + <var-decl name='bound_gilstate' type-id='type-id-95' visibility='default' filepath='./Include/cpython/pystate.h' line='134' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='4'> + <var-decl name='active' type-id='type-id-95' visibility='default' filepath='./Include/cpython/pystate.h' line='136' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='5'> + <var-decl name='finalizing' type-id='type-id-95' visibility='default' filepath='./Include/cpython/pystate.h' line='139' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='6'> + <var-decl name='cleared' type-id='type-id-95' visibility='default' filepath='./Include/cpython/pystate.h' line='140' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='7'> + <var-decl name='finalized' type-id='type-id-95' visibility='default' filepath='./Include/cpython/pystate.h' line='141' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='_PyFrameEvalFunction' type-id='type-id-779' filepath='./Include/cpython/pystate.h' line='323' column='1' id='type-id-780'/> + <typedef-decl name='_PyCrossInterpreterData' type-id='type-id-781' filepath='./Include/cpython/pystate.h' line='376' column='1' id='type-id-782'/> + <typedef-decl name='xid_newobjectfunc' type-id='type-id-783' filepath='./Include/cpython/pystate.h' line='378' column='1' id='type-id-784'/> + <typedef-decl name='xid_freefunc' type-id='type-id-760' filepath='./Include/cpython/pystate.h' line='379' column='1' id='type-id-785'/> + <class-decl name='_xid' size-in-bits='320' is-struct='yes' visibility='default' filepath='./Include/cpython/pystate.h' line='381' column='1' id='type-id-781'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='data' type-id='type-id-22' visibility='default' filepath='./Include/cpython/pystate.h' line='385' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='obj' type-id='type-id-2' visibility='default' filepath='./Include/cpython/pystate.h' line='392' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='interp' type-id='type-id-377' visibility='default' filepath='./Include/cpython/pystate.h' line='402' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='new_object' type-id='type-id-784' visibility='default' filepath='./Include/cpython/pystate.h' line='407' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='free' type-id='type-id-785' visibility='default' filepath='./Include/cpython/pystate.h' line='417' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='crossinterpdatafunc' type-id='type-id-786' filepath='./Include/cpython/pystate.h' line='439' column='1' id='type-id-787'/> + <class-decl name='_Py_tss_t' size-in-bits='64' is-struct='yes' visibility='default' filepath='./Include/cpython/pythread.h' line='34' column='1' id='type-id-788'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='_is_initialized' type-id='type-id-8' visibility='default' filepath='./Include/cpython/pythread.h' line='35' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='32'> + <var-decl name='_key' type-id='type-id-789' visibility='default' filepath='./Include/cpython/pythread.h' line='36' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='_PyTime_t' type-id='type-id-377' filepath='./Include/cpython/pytime.h' line='63' column='1' id='type-id-790'/> + <typedef-decl name='Py_AuditHookFunction' type-id='type-id-791' filepath='./Include/cpython/sysmodule.h' line='10' column='1' id='type-id-234'/> + <class-decl name='PyTupleObject' size-in-bits='256' is-struct='yes' naming-typedef-id='type-id-792' visibility='default' filepath='./Include/cpython/tupleobject.h' line='5' column='1' id='type-id-793'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='ob_base' type-id='type-id-321' visibility='default' filepath='./Include/cpython/tupleobject.h' line='6' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='ob_item' type-id='type-id-353' visibility='default' filepath='./Include/cpython/tupleobject.h' line='10' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='PyTupleObject' type-id='type-id-793' filepath='./Include/cpython/tupleobject.h' line='11' column='1' id='type-id-792'/> + <class-decl name='PyASCIIObject' size-in-bits='320' is-struct='yes' naming-typedef-id='type-id-794' visibility='default' filepath='./Include/cpython/unicodeobject.h' line='52' column='1' id='type-id-795'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='ob_base' type-id='type-id-345' visibility='default' filepath='./Include/cpython/unicodeobject.h' line='97' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='length' type-id='type-id-14' visibility='default' filepath='./Include/cpython/unicodeobject.h' line='98' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='hash' type-id='type-id-305' visibility='default' filepath='./Include/cpython/unicodeobject.h' line='99' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='state' type-id='type-id-796' visibility='default' filepath='./Include/cpython/unicodeobject.h' line='146' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__25' size-in-bits='32' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/cpython/unicodeobject.h' line='100' column='1' id='type-id-796'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='interned' type-id='type-id-95' visibility='default' filepath='./Include/cpython/unicodeobject.h' line='110' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2'> + <var-decl name='kind' type-id='type-id-95' visibility='default' filepath='./Include/cpython/unicodeobject.h' line='133' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='5'> + <var-decl name='compact' type-id='type-id-95' visibility='default' filepath='./Include/cpython/unicodeobject.h' line='138' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='6'> + <var-decl name='ascii' type-id='type-id-95' visibility='default' filepath='./Include/cpython/unicodeobject.h' line='142' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='PyASCIIObject' type-id='type-id-795' filepath='./Include/cpython/unicodeobject.h' line='147' column='1' id='type-id-794'/> + <class-decl name='PyCompactUnicodeObject' size-in-bits='448' is-struct='yes' naming-typedef-id='type-id-797' visibility='default' filepath='./Include/cpython/unicodeobject.h' line='152' column='1' id='type-id-798'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='_base' type-id='type-id-794' visibility='default' filepath='./Include/cpython/unicodeobject.h' line='153' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='utf8_length' type-id='type-id-14' visibility='default' filepath='./Include/cpython/unicodeobject.h' line='154' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='384'> + <var-decl name='utf8' type-id='type-id-15' visibility='default' filepath='./Include/cpython/unicodeobject.h' line='156' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='PyCompactUnicodeObject' type-id='type-id-798' filepath='./Include/cpython/unicodeobject.h' line='157' column='1' id='type-id-797'/> + <class-decl name='ast_state' size-in-bits='15616' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='13' column='1' id='type-id-799'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='initialized' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='14' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='32'> + <var-decl name='recursion_depth' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='15' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='recursion_limit' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='16' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='AST_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='17' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='Add_singleton' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='18' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='Add_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='19' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='And_singleton' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='20' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='384'> + <var-decl name='And_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='21' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='448'> + <var-decl name='AnnAssign_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='22' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='512'> + <var-decl name='Assert_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='23' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='576'> + <var-decl name='Assign_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='24' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='640'> + <var-decl name='AsyncFor_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='25' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='704'> + <var-decl name='AsyncFunctionDef_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='26' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='768'> + <var-decl name='AsyncWith_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='27' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='832'> + <var-decl name='Attribute_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='28' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='896'> + <var-decl name='AugAssign_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='29' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='960'> + <var-decl name='Await_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='30' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1024'> + <var-decl name='BinOp_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='31' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1088'> + <var-decl name='BitAnd_singleton' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='32' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1152'> + <var-decl name='BitAnd_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='33' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1216'> + <var-decl name='BitOr_singleton' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='34' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1280'> + <var-decl name='BitOr_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='35' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1344'> + <var-decl name='BitXor_singleton' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='36' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1408'> + <var-decl name='BitXor_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='37' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1472'> + <var-decl name='BoolOp_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='38' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1536'> + <var-decl name='Break_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='39' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1600'> + <var-decl name='Call_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='40' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1664'> + <var-decl name='ClassDef_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='41' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1728'> + <var-decl name='Compare_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='42' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1792'> + <var-decl name='Constant_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='43' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1856'> + <var-decl name='Continue_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='44' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1920'> + <var-decl name='Del_singleton' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='45' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1984'> + <var-decl name='Del_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='46' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2048'> + <var-decl name='Delete_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='47' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2112'> + <var-decl name='DictComp_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='48' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2176'> + <var-decl name='Dict_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='49' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2240'> + <var-decl name='Div_singleton' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='50' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2304'> + <var-decl name='Div_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='51' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2368'> + <var-decl name='Eq_singleton' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='52' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2432'> + <var-decl name='Eq_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='53' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2496'> + <var-decl name='ExceptHandler_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='54' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2560'> + <var-decl name='Expr_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='55' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2624'> + <var-decl name='Expression_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='56' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2688'> + <var-decl name='FloorDiv_singleton' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='57' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2752'> + <var-decl name='FloorDiv_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='58' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2816'> + <var-decl name='For_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='59' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2880'> + <var-decl name='FormattedValue_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='60' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2944'> + <var-decl name='FunctionDef_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='61' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='3008'> + <var-decl name='FunctionType_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='62' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='3072'> + <var-decl name='GeneratorExp_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='63' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='3136'> + <var-decl name='Global_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='64' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='3200'> + <var-decl name='GtE_singleton' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='65' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='3264'> + <var-decl name='GtE_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='66' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='3328'> + <var-decl name='Gt_singleton' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='67' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='3392'> + <var-decl name='Gt_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='68' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='3456'> + <var-decl name='IfExp_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='69' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='3520'> + <var-decl name='If_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='70' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='3584'> + <var-decl name='ImportFrom_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='71' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='3648'> + <var-decl name='Import_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='72' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='3712'> + <var-decl name='In_singleton' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='73' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='3776'> + <var-decl name='In_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='74' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='3840'> + <var-decl name='Interactive_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='75' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='3904'> + <var-decl name='Invert_singleton' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='76' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='3968'> + <var-decl name='Invert_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='77' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='4032'> + <var-decl name='IsNot_singleton' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='78' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='4096'> + <var-decl name='IsNot_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='79' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='4160'> + <var-decl name='Is_singleton' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='80' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='4224'> + <var-decl name='Is_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='81' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='4288'> + <var-decl name='JoinedStr_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='82' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='4352'> + <var-decl name='LShift_singleton' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='83' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='4416'> + <var-decl name='LShift_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='84' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='4480'> + <var-decl name='Lambda_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='85' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='4544'> + <var-decl name='ListComp_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='86' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='4608'> + <var-decl name='List_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='87' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='4672'> + <var-decl name='Load_singleton' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='88' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='4736'> + <var-decl name='Load_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='89' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='4800'> + <var-decl name='LtE_singleton' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='90' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='4864'> + <var-decl name='LtE_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='91' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='4928'> + <var-decl name='Lt_singleton' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='92' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='4992'> + <var-decl name='Lt_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='93' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='5056'> + <var-decl name='MatMult_singleton' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='94' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='5120'> + <var-decl name='MatMult_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='95' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='5184'> + <var-decl name='MatchAs_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='96' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='5248'> + <var-decl name='MatchClass_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='97' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='5312'> + <var-decl name='MatchMapping_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='98' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='5376'> + <var-decl name='MatchOr_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='99' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='5440'> + <var-decl name='MatchSequence_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='100' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='5504'> + <var-decl name='MatchSingleton_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='101' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='5568'> + <var-decl name='MatchStar_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='102' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='5632'> + <var-decl name='MatchValue_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='103' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='5696'> + <var-decl name='Match_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='104' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='5760'> + <var-decl name='Mod_singleton' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='105' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='5824'> + <var-decl name='Mod_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='106' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='5888'> + <var-decl name='Module_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='107' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='5952'> + <var-decl name='Mult_singleton' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='108' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='6016'> + <var-decl name='Mult_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='109' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='6080'> + <var-decl name='Name_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='110' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='6144'> + <var-decl name='NamedExpr_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='111' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='6208'> + <var-decl name='Nonlocal_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='112' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='6272'> + <var-decl name='NotEq_singleton' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='113' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='6336'> + <var-decl name='NotEq_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='114' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='6400'> + <var-decl name='NotIn_singleton' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='115' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='6464'> + <var-decl name='NotIn_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='116' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='6528'> + <var-decl name='Not_singleton' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='117' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='6592'> + <var-decl name='Not_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='118' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='6656'> + <var-decl name='Or_singleton' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='119' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='6720'> + <var-decl name='Or_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='120' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='6784'> + <var-decl name='ParamSpec_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='121' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='6848'> + <var-decl name='Pass_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='122' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='6912'> + <var-decl name='Pow_singleton' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='123' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='6976'> + <var-decl name='Pow_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='124' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='7040'> + <var-decl name='RShift_singleton' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='125' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='7104'> + <var-decl name='RShift_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='126' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='7168'> + <var-decl name='Raise_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='127' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='7232'> + <var-decl name='Return_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='128' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='7296'> + <var-decl name='SetComp_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='129' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='7360'> + <var-decl name='Set_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='130' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='7424'> + <var-decl name='Slice_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='131' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='7488'> + <var-decl name='Starred_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='132' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='7552'> + <var-decl name='Store_singleton' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='133' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='7616'> + <var-decl name='Store_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='134' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='7680'> + <var-decl name='Sub_singleton' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='135' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='7744'> + <var-decl name='Sub_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='136' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='7808'> + <var-decl name='Subscript_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='137' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='7872'> + <var-decl name='TryStar_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='138' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='7936'> + <var-decl name='Try_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='139' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='8000'> + <var-decl name='Tuple_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='140' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='8064'> + <var-decl name='TypeAlias_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='141' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='8128'> + <var-decl name='TypeIgnore_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='142' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='8192'> + <var-decl name='TypeVarTuple_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='143' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='8256'> + <var-decl name='TypeVar_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='144' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='8320'> + <var-decl name='UAdd_singleton' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='145' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='8384'> + <var-decl name='UAdd_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='146' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='8448'> + <var-decl name='USub_singleton' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='147' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='8512'> + <var-decl name='USub_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='148' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='8576'> + <var-decl name='UnaryOp_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='149' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='8640'> + <var-decl name='While_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='150' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='8704'> + <var-decl name='With_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='151' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='8768'> + <var-decl name='YieldFrom_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='152' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='8832'> + <var-decl name='Yield_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='153' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='8896'> + <var-decl name='__dict__' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='154' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='8960'> + <var-decl name='__doc__' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='155' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='9024'> + <var-decl name='__match_args__' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='156' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='9088'> + <var-decl name='__module__' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='157' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='9152'> + <var-decl name='_attributes' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='158' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='9216'> + <var-decl name='_fields' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='159' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='9280'> + <var-decl name='alias_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='160' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='9344'> + <var-decl name='annotation' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='161' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='9408'> + <var-decl name='arg' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='162' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='9472'> + <var-decl name='arg_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='163' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='9536'> + <var-decl name='args' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='164' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='9600'> + <var-decl name='argtypes' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='165' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='9664'> + <var-decl name='arguments_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='166' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='9728'> + <var-decl name='asname' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='167' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='9792'> + <var-decl name='ast' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='168' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='9856'> + <var-decl name='attr' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='169' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='9920'> + <var-decl name='bases' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='170' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='9984'> + <var-decl name='body' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='171' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='10048'> + <var-decl name='boolop_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='172' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='10112'> + <var-decl name='bound' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='173' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='10176'> + <var-decl name='cases' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='174' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='10240'> + <var-decl name='cause' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='175' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='10304'> + <var-decl name='cls' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='176' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='10368'> + <var-decl name='cmpop_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='177' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='10432'> + <var-decl name='col_offset' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='178' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='10496'> + <var-decl name='comparators' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='179' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='10560'> + <var-decl name='comprehension_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='180' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='10624'> + <var-decl name='context_expr' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='181' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='10688'> + <var-decl name='conversion' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='182' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='10752'> + <var-decl name='ctx' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='183' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='10816'> + <var-decl name='decorator_list' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='184' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='10880'> + <var-decl name='defaults' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='185' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='10944'> + <var-decl name='elt' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='186' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='11008'> + <var-decl name='elts' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='187' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='11072'> + <var-decl name='end_col_offset' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='188' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='11136'> + <var-decl name='end_lineno' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='189' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='11200'> + <var-decl name='exc' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='190' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='11264'> + <var-decl name='excepthandler_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='191' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='11328'> + <var-decl name='expr_context_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='192' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='11392'> + <var-decl name='expr_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='193' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='11456'> + <var-decl name='finalbody' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='194' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='11520'> + <var-decl name='format_spec' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='195' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='11584'> + <var-decl name='func' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='196' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='11648'> + <var-decl name='generators' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='197' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='11712'> + <var-decl name='guard' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='198' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='11776'> + <var-decl name='handlers' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='199' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='11840'> + <var-decl name='id' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='200' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='11904'> + <var-decl name='ifs' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='201' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='11968'> + <var-decl name='is_async' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='202' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='12032'> + <var-decl name='items' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='203' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='12096'> + <var-decl name='iter' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='204' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='12160'> + <var-decl name='key' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='205' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='12224'> + <var-decl name='keys' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='206' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='12288'> + <var-decl name='keyword_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='207' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='12352'> + <var-decl name='keywords' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='208' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='12416'> + <var-decl name='kind' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='209' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='12480'> + <var-decl name='kw_defaults' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='210' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='12544'> + <var-decl name='kwarg' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='211' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='12608'> + <var-decl name='kwd_attrs' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='212' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='12672'> + <var-decl name='kwd_patterns' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='213' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='12736'> + <var-decl name='kwonlyargs' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='214' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='12800'> + <var-decl name='left' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='215' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='12864'> + <var-decl name='level' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='216' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='12928'> + <var-decl name='lineno' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='217' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='12992'> + <var-decl name='lower' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='218' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='13056'> + <var-decl name='match_case_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='219' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='13120'> + <var-decl name='mod_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='220' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='13184'> + <var-decl name='module' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='221' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='13248'> + <var-decl name='msg' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='222' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='13312'> + <var-decl name='name' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='223' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='13376'> + <var-decl name='names' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='224' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='13440'> + <var-decl name='op' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='225' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='13504'> + <var-decl name='operand' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='226' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='13568'> + <var-decl name='operator_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='227' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='13632'> + <var-decl name='ops' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='228' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='13696'> + <var-decl name='optional_vars' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='229' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='13760'> + <var-decl name='orelse' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='230' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='13824'> + <var-decl name='pattern' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='231' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='13888'> + <var-decl name='pattern_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='232' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='13952'> + <var-decl name='patterns' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='233' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='14016'> + <var-decl name='posonlyargs' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='234' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='14080'> + <var-decl name='rest' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='235' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='14144'> + <var-decl name='returns' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='236' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='14208'> + <var-decl name='right' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='237' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='14272'> + <var-decl name='simple' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='238' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='14336'> + <var-decl name='slice' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='239' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='14400'> + <var-decl name='step' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='240' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='14464'> + <var-decl name='stmt_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='241' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='14528'> + <var-decl name='subject' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='242' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='14592'> + <var-decl name='tag' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='243' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='14656'> + <var-decl name='target' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='244' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='14720'> + <var-decl name='targets' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='245' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='14784'> + <var-decl name='test' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='246' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='14848'> + <var-decl name='type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='247' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='14912'> + <var-decl name='type_comment' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='248' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='14976'> + <var-decl name='type_ignore_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='249' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='15040'> + <var-decl name='type_ignores' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='250' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='15104'> + <var-decl name='type_param_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='251' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='15168'> + <var-decl name='type_params' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='252' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='15232'> + <var-decl name='unaryop_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='253' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='15296'> + <var-decl name='upper' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='254' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='15360'> + <var-decl name='value' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='255' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='15424'> + <var-decl name='values' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='256' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='15488'> + <var-decl name='vararg' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='257' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='15552'> + <var-decl name='withitem_type' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_ast_state.h' line='258' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='atexit_callbackfunc' type-id='type-id-227' filepath='./Include/internal/pycore_atexit.h' line='15' column='1' id='type-id-613'/> + <class-decl name='_atexit_runtime_state' size-in-bits='2176' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_atexit.h' line='17' column='1' id='type-id-800'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='mutex' type-id='type-id-801' visibility='default' filepath='./Include/internal/pycore_atexit.h' line='18' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='callbacks' type-id='type-id-614' visibility='default' filepath='./Include/internal/pycore_atexit.h' line='20' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2112'> + <var-decl name='ncallbacks' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_atexit.h' line='21' column='1'/> + </data-member> + </class-decl> + <class-decl name='atexit_callback' size-in-bits='192' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_atexit.h' line='29' column='1' id='type-id-802'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='func' type-id='type-id-21' visibility='default' filepath='./Include/internal/pycore_atexit.h' line='30' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='data' type-id='type-id-22' visibility='default' filepath='./Include/internal/pycore_atexit.h' line='31' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='next' type-id='type-id-803' visibility='default' filepath='./Include/internal/pycore_atexit.h' line='32' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='atexit_callback' type-id='type-id-802' filepath='./Include/internal/pycore_atexit.h' line='33' column='1' id='type-id-804'/> + <class-decl name='atexit_py_callback' size-in-bits='192' is-struct='yes' naming-typedef-id='type-id-805' visibility='default' filepath='./Include/internal/pycore_atexit.h' line='35' column='1' id='type-id-806'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='func' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_atexit.h' line='36' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='args' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_atexit.h' line='37' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='kwargs' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_atexit.h' line='38' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='atexit_py_callback' type-id='type-id-806' filepath='./Include/internal/pycore_atexit.h' line='39' column='1' id='type-id-805'/> + <class-decl name='atexit_state' size-in-bits='256' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_atexit.h' line='41' column='1' id='type-id-807'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='ll_callbacks' type-id='type-id-803' visibility='default' filepath='./Include/internal/pycore_atexit.h' line='42' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='last_ll_callback' type-id='type-id-803' visibility='default' filepath='./Include/internal/pycore_atexit.h' line='43' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='callbacks' type-id='type-id-808' visibility='default' filepath='./Include/internal/pycore_atexit.h' line='48' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='ncallbacks' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_atexit.h' line='49' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='224'> + <var-decl name='callback_len' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_atexit.h' line='50' column='1'/> + </data-member> + </class-decl> + <class-decl name='_Py_atomic_address' size-in-bits='64' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_atomic.h' line='45' column='1' id='type-id-809'/> + <typedef-decl name='_Py_atomic_address' type-id='type-id-809' filepath='./Include/internal/pycore_atomic.h' line='47' column='1' id='type-id-810'/> + <class-decl name='_Py_atomic_int' size-in-bits='32' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_atomic.h' line='49' column='1' id='type-id-811'/> + <typedef-decl name='_Py_atomic_int' type-id='type-id-811' filepath='./Include/internal/pycore_atomic.h' line='51' column='1' id='type-id-812'/> + <class-decl name='_pending_calls' size-in-bits='4352' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_ceval_state.h' line='16' column='1' id='type-id-813'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='busy' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ceval_state.h' line='17' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='lock' type-id='type-id-801' visibility='default' filepath='./Include/internal/pycore_ceval_state.h' line='18' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='calls_to_do' type-id='type-id-812' visibility='default' filepath='./Include/internal/pycore_ceval_state.h' line='20' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='160'> + <var-decl name='async_exc' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ceval_state.h' line='24' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='calls' type-id='type-id-602' visibility='default' filepath='./Include/internal/pycore_ceval_state.h' line='29' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='4288'> + <var-decl name='first' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ceval_state.h' line='30' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='4320'> + <var-decl name='last' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ceval_state.h' line='31' column='1'/> + </data-member> + </class-decl> + <class-decl name='_pending_call' size-in-bits='128' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_ceval_state.h' line='26' column='1' id='type-id-601'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='func' type-id='type-id-814' visibility='default' filepath='./Include/internal/pycore_ceval_state.h' line='27' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='arg' type-id='type-id-22' visibility='default' filepath='./Include/internal/pycore_ceval_state.h' line='28' column='1'/> + </data-member> + </class-decl> + <enum-decl name='perf_status_t' naming-typedef-id='type-id-815' filepath='./Include/internal/pycore_ceval_state.h' line='34' column='1' id='type-id-816'> + <underlying-type type-id='type-id-24'/> + <enumerator name='PERF_STATUS_FAILED' value='-1'/> + <enumerator name='PERF_STATUS_NO_INIT' value='0'/> + <enumerator name='PERF_STATUS_OK' value='1'/> + </enum-decl> + <typedef-decl name='perf_status_t' type-id='type-id-816' filepath='./Include/internal/pycore_ceval_state.h' line='38' column='1' id='type-id-815'/> + <class-decl name='trampoline_api_st' size-in-bits='256' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_ceval_state.h' line='44' column='1' id='type-id-817'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='init_state' type-id='type-id-818' visibility='default' filepath='./Include/internal/pycore_ceval_state.h' line='45' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='write_state' type-id='type-id-819' visibility='default' filepath='./Include/internal/pycore_ceval_state.h' line='46' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='free_state' type-id='type-id-814' visibility='default' filepath='./Include/internal/pycore_ceval_state.h' line='48' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='state' type-id='type-id-22' visibility='default' filepath='./Include/internal/pycore_ceval_state.h' line='49' column='1'/> + </data-member> + </class-decl> + <class-decl name='_ceval_runtime_state' size-in-bits='4928' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_ceval_state.h' line='53' column='1' id='type-id-820'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='perf' type-id='type-id-821' visibility='default' filepath='./Include/internal/pycore_ceval_state.h' line='64' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='512'> + <var-decl name='signals_pending' type-id='type-id-812' visibility='default' filepath='./Include/internal/pycore_ceval_state.h' line='69' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='576'> + <var-decl name='pending_mainthread' type-id='type-id-813' visibility='default' filepath='./Include/internal/pycore_ceval_state.h' line='71' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__7' size-in-bits='512' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ceval_state.h' line='54' column='1' id='type-id-821'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='status' type-id='type-id-815' visibility='default' filepath='./Include/internal/pycore_ceval_state.h' line='56' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='extra_code_index' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ceval_state.h' line='57' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='code_arena' type-id='type-id-822' visibility='default' filepath='./Include/internal/pycore_ceval_state.h' line='58' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='trampoline_api' type-id='type-id-817' visibility='default' filepath='./Include/internal/pycore_ceval_state.h' line='59' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='448'> + <var-decl name='map_file' type-id='type-id-229' visibility='default' filepath='./Include/internal/pycore_ceval_state.h' line='60' column='1'/> + </data-member> + </class-decl> + <class-decl name='_ceval_state' size-in-bits='4608' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_ceval_state.h' line='85' column='1' id='type-id-823'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='eval_breaker' type-id='type-id-812' visibility='default' filepath='./Include/internal/pycore_ceval_state.h' line='88' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='32'> + <var-decl name='gil_drop_request' type-id='type-id-812' visibility='default' filepath='./Include/internal/pycore_ceval_state.h' line='90' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='recursion_limit' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ceval_state.h' line='91' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='gil' type-id='type-id-824' visibility='default' filepath='./Include/internal/pycore_ceval_state.h' line='92' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='own_gil' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ceval_state.h' line='93' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='224'> + <var-decl name='gc_scheduled' type-id='type-id-812' visibility='default' filepath='./Include/internal/pycore_ceval_state.h' line='95' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='pending' type-id='type-id-813' visibility='default' filepath='./Include/internal/pycore_ceval_state.h' line='96' column='1'/> + </data-member> + </class-decl> + <class-decl name='callable_cache' size-in-bits='256' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_code.h' line='105' column='1' id='type-id-825'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='isinstance' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_code.h' line='106' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='len' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_code.h' line='107' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='list_append' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_code.h' line='108' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='object__getattribute__' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_code.h' line='109' column='1'/> + </data-member> + </class-decl> + <class-decl name='_PyContextTokenMissing' size-in-bits='128' is-struct='yes' naming-typedef-id='type-id-826' visibility='default' filepath='./Include/internal/pycore_context.h' line='21' column='1' id='type-id-827'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='ob_base' type-id='type-id-345' visibility='default' filepath='./Include/internal/pycore_context.h' line='22' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='_PyContextTokenMissing' type-id='type-id-827' filepath='./Include/internal/pycore_context.h' line='23' column='1' id='type-id-826'/> + <class-decl name='_Py_context_state' size-in-bits='128' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_context.h' line='34' column='1' id='type-id-828'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='freelist' type-id='type-id-829' visibility='default' filepath='./Include/internal/pycore_context.h' line='37' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='numfree' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_context.h' line='38' column='1'/> + </data-member> + </class-decl> + <class-decl name='_pycontextobject' size-in-bits='384' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_context.h' line='42' column='1' id='type-id-725'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='ob_base' type-id='type-id-345' visibility='default' filepath='./Include/internal/pycore_context.h' line='43' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='ctx_prev' type-id='type-id-829' visibility='default' filepath='./Include/internal/pycore_context.h' line='44' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='ctx_vars' type-id='type-id-830' visibility='default' filepath='./Include/internal/pycore_context.h' line='45' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='ctx_weakreflist' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_context.h' line='46' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='ctx_entered' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_context.h' line='47' column='1'/> + </data-member> + </class-decl> + <class-decl name='_Py_dict_state' size-in-bits='10944' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_dict_state.h' line='23' column='1' id='type-id-831'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='global_version' type-id='type-id-117' visibility='default' filepath='./Include/internal/pycore_dict_state.h' line='27' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='next_keys_version' type-id='type-id-352' visibility='default' filepath='./Include/internal/pycore_dict_state.h' line='28' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='free_list' type-id='type-id-578' visibility='default' filepath='./Include/internal/pycore_dict_state.h' line='32' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='5248'> + <var-decl name='keys_free_list' type-id='type-id-577' visibility='default' filepath='./Include/internal/pycore_dict_state.h' line='33' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='10368'> + <var-decl name='numfree' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_dict_state.h' line='34' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='10400'> + <var-decl name='keys_numfree' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_dict_state.h' line='35' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='10432'> + <var-decl name='watchers' type-id='type-id-579' visibility='default' filepath='./Include/internal/pycore_dict_state.h' line='38' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='ULong' type-id='type-id-352' filepath='./Include/internal/pycore_dtoa.h' line='16' column='1' id='type-id-591'/> + <class-decl name='Bigint' size-in-bits='256' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_dtoa.h' line='19' column='1' id='type-id-832'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='next' type-id='type-id-570' visibility='default' filepath='./Include/internal/pycore_dtoa.h' line='20' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='k' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_dtoa.h' line='21' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='96'> + <var-decl name='maxwds' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_dtoa.h' line='21' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='sign' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_dtoa.h' line='21' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='160'> + <var-decl name='wds' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_dtoa.h' line='21' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='x' type-id='type-id-592' visibility='default' filepath='./Include/internal/pycore_dtoa.h' line='22' column='1'/> + </data-member> + </class-decl> + <class-decl name='_dtoa_state' size-in-bits='19072' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_dtoa.h' line='44' column='1' id='type-id-833'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='p5s' type-id='type-id-570' visibility='default' filepath='./Include/internal/pycore_dtoa.h' line='47' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='freelist' type-id='type-id-571' visibility='default' filepath='./Include/internal/pycore_dtoa.h' line='48' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='576'> + <var-decl name='preallocated' type-id='type-id-625' visibility='default' filepath='./Include/internal/pycore_dtoa.h' line='49' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='19008'> + <var-decl name='preallocated_next' type-id='type-id-182' visibility='default' filepath='./Include/internal/pycore_dtoa.h' line='50' column='1'/> + </data-member> + </class-decl> + <class-decl name='_Py_exc_state' size-in-bits='256' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_exceptions.h' line='22' column='1' id='type-id-834'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='errnomap' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_exceptions.h' line='24' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='memerrors_freelist' type-id='type-id-835' visibility='default' filepath='./Include/internal/pycore_exceptions.h' line='25' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='memerrors_numfree' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_exceptions.h' line='26' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='PyExc_ExceptionGroup' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_exceptions.h' line='28' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='_Py_sighandler_t' type-id='type-id-836' filepath='./Include/internal/pycore_faulthandler.h' line='30' column='1' id='type-id-837'/> + <class-decl name='faulthandler_user_signal' size-in-bits='1536' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_faulthandler.h' line='37' column='1' id='type-id-838'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='enabled' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_faulthandler.h' line='38' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='file' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_faulthandler.h' line='39' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='fd' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_faulthandler.h' line='40' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='160'> + <var-decl name='all_threads' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_faulthandler.h' line='41' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='chain' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_faulthandler.h' line='42' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='previous' type-id='type-id-837' visibility='default' filepath='./Include/internal/pycore_faulthandler.h' line='43' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1472'> + <var-decl name='interp' type-id='type-id-20' visibility='default' filepath='./Include/internal/pycore_faulthandler.h' line='44' column='1'/> + </data-member> + </class-decl> + <class-decl name='_faulthandler_runtime_state' size-in-bits='1344' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_faulthandler.h' line='49' column='1' id='type-id-839'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='fatal_error' type-id='type-id-840' visibility='default' filepath='./Include/internal/pycore_faulthandler.h' line='59' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='thread' type-id='type-id-841' visibility='default' filepath='./Include/internal/pycore_faulthandler.h' line='76' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='896'> + <var-decl name='user_signals' type-id='type-id-842' visibility='default' filepath='./Include/internal/pycore_faulthandler.h' line='79' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='960'> + <var-decl name='stack' type-id='type-id-38' visibility='default' filepath='./Include/internal/pycore_faulthandler.h' line='83' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1152'> + <var-decl name='old_stack' type-id='type-id-38' visibility='default' filepath='./Include/internal/pycore_faulthandler.h' line='84' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__8' size-in-bits='256' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_faulthandler.h' line='50' column='1' id='type-id-840'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='enabled' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_faulthandler.h' line='51' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='file' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_faulthandler.h' line='52' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='fd' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_faulthandler.h' line='53' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='160'> + <var-decl name='all_threads' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_faulthandler.h' line='54' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='interp' type-id='type-id-20' visibility='default' filepath='./Include/internal/pycore_faulthandler.h' line='55' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__9' size-in-bits='640' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_faulthandler.h' line='61' column='1' id='type-id-841'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='file' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_faulthandler.h' line='62' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='fd' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_faulthandler.h' line='63' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='timeout_us' type-id='type-id-378' visibility='default' filepath='./Include/internal/pycore_faulthandler.h' line='64' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='repeat' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_faulthandler.h' line='65' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='interp' type-id='type-id-20' visibility='default' filepath='./Include/internal/pycore_faulthandler.h' line='66' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='exit' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_faulthandler.h' line='67' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='384'> + <var-decl name='header' type-id='type-id-15' visibility='default' filepath='./Include/internal/pycore_faulthandler.h' line='68' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='448'> + <var-decl name='header_len' type-id='type-id-19' visibility='default' filepath='./Include/internal/pycore_faulthandler.h' line='69' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='512'> + <var-decl name='cancel_event' type-id='type-id-801' visibility='default' filepath='./Include/internal/pycore_faulthandler.h' line='73' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='576'> + <var-decl name='running' type-id='type-id-801' visibility='default' filepath='./Include/internal/pycore_faulthandler.h' line='75' column='1'/> + </data-member> + </class-decl> + <class-decl name='_fileutils_state' size-in-bits='32' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_fileutils.h' line='14' column='1' id='type-id-843'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='force_ascii' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_fileutils.h' line='15' column='1'/> + </data-member> + </class-decl> + <enum-decl name='_Py_error_handler' naming-typedef-id='type-id-442' filepath='./Include/internal/pycore_fileutils.h' line='18' column='1' id='type-id-844'> + <underlying-type type-id='type-id-24'/> + <enumerator name='_Py_ERROR_UNKNOWN' value='0'/> + <enumerator name='_Py_ERROR_STRICT' value='1'/> + <enumerator name='_Py_ERROR_SURROGATEESCAPE' value='2'/> + <enumerator name='_Py_ERROR_REPLACE' value='3'/> + <enumerator name='_Py_ERROR_IGNORE' value='4'/> + <enumerator name='_Py_ERROR_BACKSLASHREPLACE' value='5'/> + <enumerator name='_Py_ERROR_SURROGATEPASS' value='6'/> + <enumerator name='_Py_ERROR_XMLCHARREFREPLACE' value='7'/> + <enumerator name='_Py_ERROR_OTHER' value='8'/> + </enum-decl> + <typedef-decl name='_Py_error_handler' type-id='type-id-844' filepath='./Include/internal/pycore_fileutils.h' line='28' column='1' id='type-id-442'/> + <enum-decl name='_py_float_format_type' filepath='./Include/internal/pycore_floatobject.h' line='22' column='1' id='type-id-845'> + <underlying-type type-id='type-id-24'/> + <enumerator name='_py_float_format_unknown' value='0'/> + <enumerator name='_py_float_format_ieee_big_endian' value='1'/> + <enumerator name='_py_float_format_ieee_little_endian' value='2'/> + </enum-decl> + <class-decl name='_Py_float_runtime_state' size-in-bits='64' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_floatobject.h' line='28' column='1' id='type-id-846'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='float_format' type-id='type-id-845' visibility='default' filepath='./Include/internal/pycore_floatobject.h' line='29' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='32'> + <var-decl name='double_format' type-id='type-id-845' visibility='default' filepath='./Include/internal/pycore_floatobject.h' line='30' column='1'/> + </data-member> + </class-decl> + <class-decl name='_Py_float_state' size-in-bits='128' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_floatobject.h' line='43' column='1' id='type-id-847'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='numfree' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_floatobject.h' line='48' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='free_list' type-id='type-id-848' visibility='default' filepath='./Include/internal/pycore_floatobject.h' line='49' column='1'/> + </data-member> + </class-decl> + <class-decl name='_frame' size-in-bits='448' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_frame.h' line='16' column='1' id='type-id-849'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='ob_base' type-id='type-id-345' visibility='default' filepath='./Include/internal/pycore_frame.h' line='17' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='f_back' type-id='type-id-365' visibility='default' filepath='./Include/internal/pycore_frame.h' line='18' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='f_frame' type-id='type-id-375' visibility='default' filepath='./Include/internal/pycore_frame.h' line='19' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='f_trace' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_frame.h' line='20' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='f_lineno' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_frame.h' line='21' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='352'> + <var-decl name='f_trace_lines' type-id='type-id-48' visibility='default' filepath='./Include/internal/pycore_frame.h' line='22' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='360'> + <var-decl name='f_trace_opcodes' type-id='type-id-48' visibility='default' filepath='./Include/internal/pycore_frame.h' line='23' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='368'> + <var-decl name='f_fast_as_locals' type-id='type-id-48' visibility='default' filepath='./Include/internal/pycore_frame.h' line='24' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='384'> + <var-decl name='_f_frame_data' type-id='type-id-353' visibility='default' filepath='./Include/internal/pycore_frame.h' line='26' column='1'/> + </data-member> + </class-decl> + <class-decl name='_PyInterpreterFrame' size-in-bits='640' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_frame.h' line='49' column='1' id='type-id-371'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='f_code' type-id='type-id-328' visibility='default' filepath='./Include/internal/pycore_frame.h' line='50' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='previous' type-id='type-id-375' visibility='default' filepath='./Include/internal/pycore_frame.h' line='51' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='f_funcobj' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_frame.h' line='52' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='f_globals' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_frame.h' line='53' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='f_builtins' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_frame.h' line='54' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='f_locals' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_frame.h' line='55' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='384'> + <var-decl name='frame_obj' type-id='type-id-365' visibility='default' filepath='./Include/internal/pycore_frame.h' line='56' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='448'> + <var-decl name='prev_instr' type-id='type-id-850' visibility='default' filepath='./Include/internal/pycore_frame.h' line='61' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='512'> + <var-decl name='stacktop' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_frame.h' line='62' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='544'> + <var-decl name='return_offset' type-id='type-id-709' visibility='default' filepath='./Include/internal/pycore_frame.h' line='69' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='560'> + <var-decl name='owner' type-id='type-id-48' visibility='default' filepath='./Include/internal/pycore_frame.h' line='70' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='576'> + <var-decl name='localsplus' type-id='type-id-353' visibility='default' filepath='./Include/internal/pycore_frame.h' line='72' column='1'/> + </data-member> + </class-decl> + <class-decl name='_py_func_state' size-in-bits='32' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_function.h' line='13' column='1' id='type-id-851'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='next_version' type-id='type-id-352' visibility='default' filepath='./Include/internal/pycore_function.h' line='14' column='1'/> + </data-member> + </class-decl> + <class-decl name='PyGC_Head' size-in-bits='128' is-struct='yes' naming-typedef-id='type-id-852' visibility='default' filepath='./Include/internal/pycore_gc.h' line='12' column='1' id='type-id-853'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='_gc_next' type-id='type-id-749' visibility='default' filepath='./Include/internal/pycore_gc.h' line='15' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='_gc_prev' type-id='type-id-749' visibility='default' filepath='./Include/internal/pycore_gc.h' line='19' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='PyGC_Head' type-id='type-id-853' filepath='./Include/internal/pycore_gc.h' line='20' column='1' id='type-id-852'/> + <class-decl name='gc_generation' size-in-bits='192' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_gc.h' line='140' column='1' id='type-id-629'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='head' type-id='type-id-852' visibility='default' filepath='./Include/internal/pycore_gc.h' line='141' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='threshold' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_gc.h' line='142' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='160'> + <var-decl name='count' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_gc.h' line='143' column='1'/> + </data-member> + </class-decl> + <class-decl name='gc_generation_stats' size-in-bits='192' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_gc.h' line='148' column='1' id='type-id-632'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='collections' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_gc.h' line='150' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='collected' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_gc.h' line='152' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='uncollectable' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_gc.h' line='154' column='1'/> + </data-member> + </class-decl> + <class-decl name='_gc_runtime_state' size-in-bits='1920' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_gc.h' line='157' column='1' id='type-id-854'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='trash_delete_later' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_gc.h' line='160' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='trash_delete_nesting' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_gc.h' line='162' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='96'> + <var-decl name='enabled' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_gc.h' line='165' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='debug' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_gc.h' line='166' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='generations' type-id='type-id-630' visibility='default' filepath='./Include/internal/pycore_gc.h' line='168' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='768'> + <var-decl name='generation0' type-id='type-id-855' visibility='default' filepath='./Include/internal/pycore_gc.h' line='169' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='832'> + <var-decl name='permanent_generation' type-id='type-id-629' visibility='default' filepath='./Include/internal/pycore_gc.h' line='171' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1024'> + <var-decl name='generation_stats' type-id='type-id-633' visibility='default' filepath='./Include/internal/pycore_gc.h' line='172' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1600'> + <var-decl name='collecting' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_gc.h' line='174' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1664'> + <var-decl name='garbage' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_gc.h' line='176' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1728'> + <var-decl name='callbacks' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_gc.h' line='178' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1792'> + <var-decl name='long_lived_total' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_gc.h' line='185' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1856'> + <var-decl name='long_lived_pending' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_gc.h' line='189' column='1'/> + </data-member> + </class-decl> + <class-decl name='_Py_async_gen_state' size-in-bits='10368' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_genobject.h' line='31' column='1' id='type-id-856'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='value_freelist' type-id='type-id-594' visibility='default' filepath='./Include/internal/pycore_genobject.h' line='37' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='5120'> + <var-decl name='value_numfree' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_genobject.h' line='38' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='5184'> + <var-decl name='asend_freelist' type-id='type-id-574' visibility='default' filepath='./Include/internal/pycore_genobject.h' line='40' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='10304'> + <var-decl name='asend_numfree' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_genobject.h' line='41' column='1'/> + </data-member> + </class-decl> + <class-decl name='_gil_runtime_state' size-in-bits='1664' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_gil.h' line='23' column='1' id='type-id-857'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='interval' type-id='type-id-28' visibility='default' filepath='./Include/internal/pycore_gil.h' line='25' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='last_holder' type-id='type-id-810' visibility='default' filepath='./Include/internal/pycore_gil.h' line='28' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='locked' type-id='type-id-812' visibility='default' filepath='./Include/internal/pycore_gil.h' line='31' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='switch_number' type-id='type-id-28' visibility='default' filepath='./Include/internal/pycore_gil.h' line='33' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='cond' type-id='type-id-858' visibility='default' filepath='./Include/internal/pycore_gil.h' line='37' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='640'> + <var-decl name='mutex' type-id='type-id-859' visibility='default' filepath='./Include/internal/pycore_gil.h' line='38' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='960'> + <var-decl name='switch_cond' type-id='type-id-858' visibility='default' filepath='./Include/internal/pycore_gil.h' line='42' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1344'> + <var-decl name='switch_mutex' type-id='type-id-859' visibility='default' filepath='./Include/internal/pycore_gil.h' line='43' column='1'/> + </data-member> + </class-decl> + <class-decl name='_Py_static_objects' size-in-bits='586048' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_global_objects.h' line='31' column='1' id='type-id-860'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='singletons' type-id='type-id-861' visibility='default' filepath='./Include/internal/pycore_global_objects.h' line='54' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__20' size-in-bits='586048' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_global_objects.h' line='32' column='1' id='type-id-861'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='small_ints' type-id='type-id-582' visibility='default' filepath='./Include/internal/pycore_global_objects.h' line='38' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='67072'> + <var-decl name='bytes_empty' type-id='type-id-700' visibility='default' filepath='./Include/internal/pycore_global_objects.h' line='40' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='67392'> + <var-decl name='bytes_characters' type-id='type-id-600' visibility='default' filepath='./Include/internal/pycore_global_objects.h' line='44' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='165696'> + <var-decl name='strings' type-id='type-id-862' visibility='default' filepath='./Include/internal/pycore_global_objects.h' line='46' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='585088'> + <var-decl name='_tuple_empty_gc_not_used' type-id='type-id-852' visibility='default' filepath='./Include/internal/pycore_global_objects.h' line='48' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='585216'> + <var-decl name='tuple_empty' type-id='type-id-792' visibility='default' filepath='./Include/internal/pycore_global_objects.h' line='49' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='585472'> + <var-decl name='_hamt_bitmap_node_empty_gc_not_used' type-id='type-id-852' visibility='default' filepath='./Include/internal/pycore_global_objects.h' line='51' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='585600'> + <var-decl name='hamt_bitmap_node_empty' type-id='type-id-863' visibility='default' filepath='./Include/internal/pycore_global_objects.h' line='52' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='585920'> + <var-decl name='context_token_missing' type-id='type-id-826' visibility='default' filepath='./Include/internal/pycore_global_objects.h' line='53' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__21' size-in-bits='384' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_global_objects.h' line='41' column='1' id='type-id-599'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='ob' type-id='type-id-700' visibility='default' filepath='./Include/internal/pycore_global_objects.h' line='42' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='eos' type-id='type-id-48' visibility='default' filepath='./Include/internal/pycore_global_objects.h' line='43' column='1'/> + </data-member> + </class-decl> + <class-decl name='_Py_interp_cached_objects' size-in-bits='1280' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_global_objects.h' line='60' column='1' id='type-id-864'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='interned_strings' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_global_objects.h' line='61' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='str_replace_inf' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_global_objects.h' line='64' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='objreduce' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_global_objects.h' line='67' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='type_slots_pname' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_global_objects.h' line='68' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='type_slots_ptrs' type-id='type-id-641' visibility='default' filepath='./Include/internal/pycore_global_objects.h' line='69' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='896'> + <var-decl name='generic_type' type-id='type-id-1' visibility='default' filepath='./Include/internal/pycore_global_objects.h' line='72' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='960'> + <var-decl name='typevar_type' type-id='type-id-1' visibility='default' filepath='./Include/internal/pycore_global_objects.h' line='73' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1024'> + <var-decl name='typevartuple_type' type-id='type-id-1' visibility='default' filepath='./Include/internal/pycore_global_objects.h' line='74' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1088'> + <var-decl name='paramspec_type' type-id='type-id-1' visibility='default' filepath='./Include/internal/pycore_global_objects.h' line='75' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1152'> + <var-decl name='paramspecargs_type' type-id='type-id-1' visibility='default' filepath='./Include/internal/pycore_global_objects.h' line='76' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1216'> + <var-decl name='paramspeckwargs_type' type-id='type-id-1' visibility='default' filepath='./Include/internal/pycore_global_objects.h' line='77' column='1'/> + </data-member> + </class-decl> + <class-decl name='_Py_interp_static_objects' size-in-bits='1088' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_global_objects.h' line='85' column='1' id='type-id-865'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='singletons' type-id='type-id-866' visibility='default' filepath='./Include/internal/pycore_global_objects.h' line='92' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__748' size-in-bits='1088' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_global_objects.h' line='86' column='1' id='type-id-866'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='_not_used' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_global_objects.h' line='87' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='_hamt_empty_gc_not_used' type-id='type-id-852' visibility='default' filepath='./Include/internal/pycore_global_objects.h' line='89' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='hamt_empty' type-id='type-id-867' visibility='default' filepath='./Include/internal/pycore_global_objects.h' line='90' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='512'> + <var-decl name='last_resort_memory_error' type-id='type-id-758' visibility='default' filepath='./Include/internal/pycore_global_objects.h' line='91' column='1'/> + </data-member> + </class-decl> + <class-decl name='_Py_global_strings' size-in-bits='419392' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='29' column='1' id='type-id-862'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='literals' type-id='type-id-868' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='57' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='11008'> + <var-decl name='identifiers' type-id='type-id-869' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='751' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='304704'> + <var-decl name='ascii' type-id='type-id-596' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='755' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='353856'> + <var-decl name='latin1' type-id='type-id-598' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='759' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__22' size-in-bits='11008' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='30' column='1' id='type-id-868'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='_py_anon_dictcomp' type-id='type-id-870' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='31' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='448'> + <var-decl name='_py_anon_genexpr' type-id='type-id-871' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='32' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='896'> + <var-decl name='_py_anon_lambda' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='33' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1344'> + <var-decl name='_py_anon_listcomp' type-id='type-id-870' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='34' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1792'> + <var-decl name='_py_anon_module' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='35' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2240'> + <var-decl name='_py_anon_setcomp' type-id='type-id-871' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='36' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2688'> + <var-decl name='_py_anon_string' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='37' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='3136'> + <var-decl name='_py_anon_unknown' type-id='type-id-871' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='38' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='3584'> + <var-decl name='_py_close_br' type-id='type-id-595' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='39' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='3968'> + <var-decl name='_py_dbl_close_br' type-id='type-id-873' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='40' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='4352'> + <var-decl name='_py_dbl_open_br' type-id='type-id-873' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='41' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='4736'> + <var-decl name='_py_dbl_percent' type-id='type-id-873' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='42' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='5120'> + <var-decl name='_py_defaults' type-id='type-id-871' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='43' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='5568'> + <var-decl name='_py_dot' type-id='type-id-595' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='44' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='5952'> + <var-decl name='_py_dot_locals' type-id='type-id-871' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='45' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='6400'> + <var-decl name='_py_empty' type-id='type-id-874' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='46' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='6784'> + <var-decl name='_py_generic_base' type-id='type-id-875' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='47' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='7232'> + <var-decl name='_py_json_decoder' type-id='type-id-876' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='48' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='7680'> + <var-decl name='_py_kwdefaults' type-id='type-id-877' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='49' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='8128'> + <var-decl name='_py_list_err' type-id='type-id-878' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='50' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='8640'> + <var-decl name='_py_newline' type-id='type-id-595' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='51' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='9024'> + <var-decl name='_py_open_br' type-id='type-id-595' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='52' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='9408'> + <var-decl name='_py_percent' type-id='type-id-595' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='53' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='9792'> + <var-decl name='_py_shim_name' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='54' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='10176'> + <var-decl name='_py_type_params' type-id='type-id-876' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='55' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='10624'> + <var-decl name='_py_utf_8' type-id='type-id-880' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='56' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__23' size-in-bits='448' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='31' column='1' id='type-id-870'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='_ascii' type-id='type-id-794' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='31' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='_data' type-id='type-id-651' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='31' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__25' size-in-bits='448' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='32' column='1' id='type-id-871'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='_ascii' type-id='type-id-794' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='32' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='_data' type-id='type-id-650' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='32' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__26' size-in-bits='448' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='33' column='1' id='type-id-872'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='_ascii' type-id='type-id-794' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='33' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='_data' type-id='type-id-694' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='33' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__32' size-in-bits='384' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='39' column='1' id='type-id-595'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='_ascii' type-id='type-id-794' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='39' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='_data' type-id='type-id-680' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='39' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__33' size-in-bits='384' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='40' column='1' id='type-id-873'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='_ascii' type-id='type-id-794' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='40' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='_data' type-id='type-id-686' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='40' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__39' size-in-bits='384' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='46' column='1' id='type-id-874'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='_ascii' type-id='type-id-794' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='46' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='_data' type-id='type-id-667' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='46' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__40' size-in-bits='448' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='47' column='1' id='type-id-875'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='_ascii' type-id='type-id-794' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='47' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='_data' type-id='type-id-657' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='47' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__41' size-in-bits='448' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='48' column='1' id='type-id-876'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='_ascii' type-id='type-id-794' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='48' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='_data' type-id='type-id-655' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='48' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__42' size-in-bits='448' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='49' column='1' id='type-id-877'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='_ascii' type-id='type-id-794' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='49' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='_data' type-id='type-id-653' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='49' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__43' size-in-bits='512' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='50' column='1' id='type-id-878'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='_ascii' type-id='type-id-794' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='50' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='_data' type-id='type-id-673' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='50' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__47' size-in-bits='384' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='54' column='1' id='type-id-879'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='_ascii' type-id='type-id-794' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='54' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='_data' type-id='type-id-691' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='54' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__49' size-in-bits='384' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='56' column='1' id='type-id-880'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='_ascii' type-id='type-id-794' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='56' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='_data' type-id='type-id-690' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='56' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__50' size-in-bits='293696' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='59' column='1' id='type-id-869'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='_py_CANCELLED' type-id='type-id-871' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='60' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='448'> + <var-decl name='_py_FINISHED' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='61' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='896'> + <var-decl name='_py_False' type-id='type-id-880' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='62' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1280'> + <var-decl name='_py_JSONDecodeError' type-id='type-id-881' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='63' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1728'> + <var-decl name='_py_PENDING' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='64' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2112'> + <var-decl name='_py_Py_Repr' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='65' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2496'> + <var-decl name='_py_TextIOWrapper' type-id='type-id-875' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='66' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2944'> + <var-decl name='_py_True' type-id='type-id-883' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='67' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='3328'> + <var-decl name='_py_WarningMessage' type-id='type-id-884' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='68' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='3776'> + <var-decl name='_py__' type-id='type-id-595' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='69' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='4160'> + <var-decl name='_py__WindowsConsoleIO' type-id='type-id-885' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='70' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='4672'> + <var-decl name='_py___IOBase_closed' type-id='type-id-881' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='71' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='5120'> + <var-decl name='_py___abc_tpflags__' type-id='type-id-881' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='72' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='5568'> + <var-decl name='_py___abs__' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='73' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='5952'> + <var-decl name='_py___abstractmethods__' type-id='type-id-886' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='74' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='6464'> + <var-decl name='_py___add__' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='75' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='6848'> + <var-decl name='_py___aenter__' type-id='type-id-870' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='76' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='7296'> + <var-decl name='_py___aexit__' type-id='type-id-871' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='77' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='7744'> + <var-decl name='_py___aiter__' type-id='type-id-871' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='78' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='8192'> + <var-decl name='_py___all__' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='79' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='8576'> + <var-decl name='_py___and__' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='80' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='8960'> + <var-decl name='_py___anext__' type-id='type-id-871' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='81' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='9408'> + <var-decl name='_py___annotations__' type-id='type-id-881' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='82' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='9856'> + <var-decl name='_py___args__' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='83' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='10304'> + <var-decl name='_py___asyncio_running_event_loop__' type-id='type-id-887' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='84' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='10880'> + <var-decl name='_py___await__' type-id='type-id-871' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='85' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='11328'> + <var-decl name='_py___bases__' type-id='type-id-871' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='86' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='11776'> + <var-decl name='_py___bool__' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='87' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='12224'> + <var-decl name='_py___buffer__' type-id='type-id-870' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='88' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='12672'> + <var-decl name='_py___build_class__' type-id='type-id-881' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='89' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='13120'> + <var-decl name='_py___builtins__' type-id='type-id-876' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='90' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='13568'> + <var-decl name='_py___bytes__' type-id='type-id-871' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='91' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='14016'> + <var-decl name='_py___call__' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='92' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='14464'> + <var-decl name='_py___cantrace__' type-id='type-id-876' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='93' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='14912'> + <var-decl name='_py___class__' type-id='type-id-871' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='94' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='15360'> + <var-decl name='_py___class_getitem__' type-id='type-id-885' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='95' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='15872'> + <var-decl name='_py___classcell__' type-id='type-id-875' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='96' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='16320'> + <var-decl name='_py___classdict__' type-id='type-id-875' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='97' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='16768'> + <var-decl name='_py___classdictcell__' type-id='type-id-885' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='98' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='17280'> + <var-decl name='_py___complex__' type-id='type-id-877' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='99' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='17728'> + <var-decl name='_py___contains__' type-id='type-id-876' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='100' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='18176'> + <var-decl name='_py___copy__' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='101' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='18624'> + <var-decl name='_py___ctypes_from_outparam__' type-id='type-id-888' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='102' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='19200'> + <var-decl name='_py___del__' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='103' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='19584'> + <var-decl name='_py___delattr__' type-id='type-id-877' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='104' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='20032'> + <var-decl name='_py___delete__' type-id='type-id-870' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='105' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='20480'> + <var-decl name='_py___delitem__' type-id='type-id-877' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='106' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='20928'> + <var-decl name='_py___dict__' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='107' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='21376'> + <var-decl name='_py___dictoffset__' type-id='type-id-884' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='108' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='21824'> + <var-decl name='_py___dir__' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='109' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='22208'> + <var-decl name='_py___divmod__' type-id='type-id-870' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='110' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='22656'> + <var-decl name='_py___doc__' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='111' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='23040'> + <var-decl name='_py___enter__' type-id='type-id-871' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='112' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='23488'> + <var-decl name='_py___eq__' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='113' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='23872'> + <var-decl name='_py___exit__' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='114' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='24320'> + <var-decl name='_py___file__' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='115' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='24768'> + <var-decl name='_py___float__' type-id='type-id-871' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='116' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='25216'> + <var-decl name='_py___floordiv__' type-id='type-id-876' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='117' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='25664'> + <var-decl name='_py___format__' type-id='type-id-870' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='118' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='26112'> + <var-decl name='_py___fspath__' type-id='type-id-870' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='119' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='26560'> + <var-decl name='_py___ge__' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='120' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='26944'> + <var-decl name='_py___get__' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='121' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='27328'> + <var-decl name='_py___getattr__' type-id='type-id-877' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='122' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='27776'> + <var-decl name='_py___getattribute__' type-id='type-id-889' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='123' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='28288'> + <var-decl name='_py___getinitargs__' type-id='type-id-881' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='124' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='28736'> + <var-decl name='_py___getitem__' type-id='type-id-877' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='125' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='29184'> + <var-decl name='_py___getnewargs__' type-id='type-id-884' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='126' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='29632'> + <var-decl name='_py___getnewargs_ex__' type-id='type-id-885' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='127' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='30144'> + <var-decl name='_py___getstate__' type-id='type-id-876' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='128' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='30592'> + <var-decl name='_py___gt__' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='129' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='30976'> + <var-decl name='_py___hash__' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='130' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='31424'> + <var-decl name='_py___iadd__' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='131' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='31872'> + <var-decl name='_py___iand__' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='132' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='32320'> + <var-decl name='_py___ifloordiv__' type-id='type-id-875' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='133' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='32768'> + <var-decl name='_py___ilshift__' type-id='type-id-877' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='134' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='33216'> + <var-decl name='_py___imatmul__' type-id='type-id-877' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='135' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='33664'> + <var-decl name='_py___imod__' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='136' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='34112'> + <var-decl name='_py___import__' type-id='type-id-870' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='137' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='34560'> + <var-decl name='_py___imul__' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='138' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='35008'> + <var-decl name='_py___index__' type-id='type-id-871' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='139' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='35456'> + <var-decl name='_py___init__' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='140' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='35904'> + <var-decl name='_py___init_subclass__' type-id='type-id-885' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='141' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='36416'> + <var-decl name='_py___instancecheck__' type-id='type-id-885' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='142' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='36928'> + <var-decl name='_py___int__' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='143' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='37312'> + <var-decl name='_py___invert__' type-id='type-id-870' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='144' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='37760'> + <var-decl name='_py___ior__' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='145' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='38144'> + <var-decl name='_py___ipow__' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='146' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='38592'> + <var-decl name='_py___irshift__' type-id='type-id-877' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='147' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='39040'> + <var-decl name='_py___isabstractmethod__' type-id='type-id-890' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='148' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='39552'> + <var-decl name='_py___isub__' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='149' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='40000'> + <var-decl name='_py___iter__' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='150' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='40448'> + <var-decl name='_py___itruediv__' type-id='type-id-876' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='151' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='40896'> + <var-decl name='_py___ixor__' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='152' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='41344'> + <var-decl name='_py___le__' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='153' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='41728'> + <var-decl name='_py___len__' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='154' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='42112'> + <var-decl name='_py___length_hint__' type-id='type-id-881' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='155' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='42560'> + <var-decl name='_py___lltrace__' type-id='type-id-877' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='156' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='43008'> + <var-decl name='_py___loader__' type-id='type-id-870' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='157' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='43456'> + <var-decl name='_py___lshift__' type-id='type-id-870' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='158' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='43904'> + <var-decl name='_py___lt__' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='159' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='44288'> + <var-decl name='_py___main__' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='160' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='44736'> + <var-decl name='_py___matmul__' type-id='type-id-870' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='161' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='45184'> + <var-decl name='_py___missing__' type-id='type-id-877' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='162' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='45632'> + <var-decl name='_py___mod__' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='163' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='46016'> + <var-decl name='_py___module__' type-id='type-id-870' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='164' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='46464'> + <var-decl name='_py___mro_entries__' type-id='type-id-881' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='165' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='46912'> + <var-decl name='_py___mul__' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='166' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='47296'> + <var-decl name='_py___name__' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='167' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='47744'> + <var-decl name='_py___ne__' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='168' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='48128'> + <var-decl name='_py___neg__' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='169' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='48512'> + <var-decl name='_py___new__' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='170' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='48896'> + <var-decl name='_py___newobj__' type-id='type-id-870' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='171' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='49344'> + <var-decl name='_py___newobj_ex__' type-id='type-id-875' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='172' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='49792'> + <var-decl name='_py___next__' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='173' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='50240'> + <var-decl name='_py___notes__' type-id='type-id-871' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='174' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='50688'> + <var-decl name='_py___or__' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='175' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='51072'> + <var-decl name='_py___orig_class__' type-id='type-id-884' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='176' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='51520'> + <var-decl name='_py___origin__' type-id='type-id-870' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='177' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='51968'> + <var-decl name='_py___package__' type-id='type-id-877' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='178' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='52416'> + <var-decl name='_py___parameters__' type-id='type-id-884' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='179' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='52864'> + <var-decl name='_py___path__' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='180' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='53312'> + <var-decl name='_py___pos__' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='181' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='53696'> + <var-decl name='_py___pow__' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='182' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='54080'> + <var-decl name='_py___prepare__' type-id='type-id-877' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='183' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='54528'> + <var-decl name='_py___qualname__' type-id='type-id-876' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='184' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='54976'> + <var-decl name='_py___radd__' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='185' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='55424'> + <var-decl name='_py___rand__' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='186' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='55872'> + <var-decl name='_py___rdivmod__' type-id='type-id-877' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='187' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='56320'> + <var-decl name='_py___reduce__' type-id='type-id-870' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='188' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='56768'> + <var-decl name='_py___reduce_ex__' type-id='type-id-875' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='189' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='57216'> + <var-decl name='_py___release_buffer__' type-id='type-id-891' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='190' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='57728'> + <var-decl name='_py___repr__' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='191' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='58176'> + <var-decl name='_py___reversed__' type-id='type-id-876' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='192' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='58624'> + <var-decl name='_py___rfloordiv__' type-id='type-id-875' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='193' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='59072'> + <var-decl name='_py___rlshift__' type-id='type-id-877' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='194' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='59520'> + <var-decl name='_py___rmatmul__' type-id='type-id-877' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='195' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='59968'> + <var-decl name='_py___rmod__' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='196' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='60416'> + <var-decl name='_py___rmul__' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='197' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='60864'> + <var-decl name='_py___ror__' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='198' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='61248'> + <var-decl name='_py___round__' type-id='type-id-871' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='199' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='61696'> + <var-decl name='_py___rpow__' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='200' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='62144'> + <var-decl name='_py___rrshift__' type-id='type-id-877' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='201' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='62592'> + <var-decl name='_py___rshift__' type-id='type-id-870' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='202' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='63040'> + <var-decl name='_py___rsub__' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='203' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='63488'> + <var-decl name='_py___rtruediv__' type-id='type-id-876' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='204' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='63936'> + <var-decl name='_py___rxor__' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='205' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64384'> + <var-decl name='_py___set__' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='206' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64768'> + <var-decl name='_py___set_name__' type-id='type-id-876' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='207' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='65216'> + <var-decl name='_py___setattr__' type-id='type-id-877' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='208' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='65664'> + <var-decl name='_py___setitem__' type-id='type-id-877' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='209' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='66112'> + <var-decl name='_py___setstate__' type-id='type-id-876' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='210' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='66560'> + <var-decl name='_py___sizeof__' type-id='type-id-870' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='211' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='67008'> + <var-decl name='_py___slotnames__' type-id='type-id-875' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='212' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='67456'> + <var-decl name='_py___slots__' type-id='type-id-871' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='213' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='67904'> + <var-decl name='_py___spec__' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='214' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='68352'> + <var-decl name='_py___str__' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='215' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='68736'> + <var-decl name='_py___sub__' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='216' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='69120'> + <var-decl name='_py___subclasscheck__' type-id='type-id-885' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='217' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='69632'> + <var-decl name='_py___subclasshook__' type-id='type-id-889' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='218' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='70144'> + <var-decl name='_py___truediv__' type-id='type-id-877' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='219' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='70592'> + <var-decl name='_py___trunc__' type-id='type-id-871' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='220' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='71040'> + <var-decl name='_py___type_params__' type-id='type-id-881' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='221' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='71488'> + <var-decl name='_py___typing_is_unpacked_typevartuple__' type-id='type-id-892' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='222' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='72128'> + <var-decl name='_py___typing_prepare_subst__' type-id='type-id-888' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='223' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='72704'> + <var-decl name='_py___typing_subst__' type-id='type-id-889' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='224' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='73216'> + <var-decl name='_py___typing_unpacked_tuple_args__' type-id='type-id-887' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='225' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='73792'> + <var-decl name='_py___warningregistry__' type-id='type-id-886' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='226' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='74304'> + <var-decl name='_py___weaklistoffset__' type-id='type-id-891' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='227' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='74816'> + <var-decl name='_py___weakref__' type-id='type-id-877' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='228' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='75264'> + <var-decl name='_py___xor__' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='229' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='75648'> + <var-decl name='_py__abc_impl' type-id='type-id-871' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='230' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='76096'> + <var-decl name='_py__abstract_' type-id='type-id-870' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='231' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='76544'> + <var-decl name='_py__active' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='232' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='76928'> + <var-decl name='_py__annotation' type-id='type-id-877' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='233' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='77376'> + <var-decl name='_py__anonymous_' type-id='type-id-877' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='234' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='77824'> + <var-decl name='_py__argtypes_' type-id='type-id-870' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='235' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='78272'> + <var-decl name='_py__as_parameter_' type-id='type-id-884' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='236' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='78720'> + <var-decl name='_py__asyncio_future_blocking' type-id='type-id-888' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='237' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='79296'> + <var-decl name='_py__blksize' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='238' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='79744'> + <var-decl name='_py__bootstrap' type-id='type-id-870' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='239' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='80192'> + <var-decl name='_py__check_retval_' type-id='type-id-884' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='240' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='80640'> + <var-decl name='_py__dealloc_warn' type-id='type-id-875' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='241' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='81088'> + <var-decl name='_py__feature_version' type-id='type-id-889' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='242' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='81600'> + <var-decl name='_py__fields_' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='243' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='82048'> + <var-decl name='_py__finalizing' type-id='type-id-877' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='244' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='82496'> + <var-decl name='_py__find_and_load' type-id='type-id-884' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='245' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='82944'> + <var-decl name='_py__fix_up_module' type-id='type-id-884' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='246' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='83392'> + <var-decl name='_py__flags_' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='247' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='83776'> + <var-decl name='_py__get_sourcefile' type-id='type-id-881' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='248' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='84224'> + <var-decl name='_py__handle_fromlist' type-id='type-id-889' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='249' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='84736'> + <var-decl name='_py__initializing' type-id='type-id-875' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='250' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='85184'> + <var-decl name='_py__io' type-id='type-id-893' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='251' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='85568'> + <var-decl name='_py__is_text_encoding' type-id='type-id-885' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='252' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='86080'> + <var-decl name='_py__length_' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='253' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='86528'> + <var-decl name='_py__limbo' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='254' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='86912'> + <var-decl name='_py__lock_unlock_module' type-id='type-id-886' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='255' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='87424'> + <var-decl name='_py__loop' type-id='type-id-880' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='256' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='87808'> + <var-decl name='_py__needs_com_addref_' type-id='type-id-891' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='257' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='88320'> + <var-decl name='_py__pack_' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='258' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='88704'> + <var-decl name='_py__restype_' type-id='type-id-871' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='259' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='89152'> + <var-decl name='_py__showwarnmsg' type-id='type-id-876' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='260' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='89600'> + <var-decl name='_py__shutdown' type-id='type-id-871' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='261' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='90048'> + <var-decl name='_py__slotnames' type-id='type-id-870' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='262' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='90496'> + <var-decl name='_py__strptime_datetime' type-id='type-id-891' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='263' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='91008'> + <var-decl name='_py__swappedbytes_' type-id='type-id-884' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='264' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='91456'> + <var-decl name='_py__type_' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='265' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='91840'> + <var-decl name='_py__uninitialized_submodules' type-id='type-id-894' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='266' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='92416'> + <var-decl name='_py__warn_unawaited_coroutine' type-id='type-id-894' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='267' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='92992'> + <var-decl name='_py__xoptions' type-id='type-id-871' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='268' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='93440'> + <var-decl name='_py_a' type-id='type-id-595' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='269' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='93824'> + <var-decl name='_py_abs_tol' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='270' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='94208'> + <var-decl name='_py_access' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='271' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='94592'> + <var-decl name='_py_add' type-id='type-id-893' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='272' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='94976'> + <var-decl name='_py_add_done_callback' type-id='type-id-885' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='273' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='95488'> + <var-decl name='_py_after_in_child' type-id='type-id-884' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='274' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='95936'> + <var-decl name='_py_after_in_parent' type-id='type-id-881' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='275' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='96384'> + <var-decl name='_py_aggregate_class' type-id='type-id-881' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='276' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='96832'> + <var-decl name='_py_alias' type-id='type-id-880' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='277' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='97216'> + <var-decl name='_py_append' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='278' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='97600'> + <var-decl name='_py_arg' type-id='type-id-893' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='279' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='97984'> + <var-decl name='_py_argdefs' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='280' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='98368'> + <var-decl name='_py_args' type-id='type-id-883' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='281' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='98752'> + <var-decl name='_py_arguments' type-id='type-id-871' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='282' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='99200'> + <var-decl name='_py_argv' type-id='type-id-883' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='283' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='99584'> + <var-decl name='_py_as_integer_ratio' type-id='type-id-889' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='284' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='100096'> + <var-decl name='_py_ast' type-id='type-id-893' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='285' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='100480'> + <var-decl name='_py_attribute' type-id='type-id-871' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='286' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='100928'> + <var-decl name='_py_authorizer_callback' type-id='type-id-886' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='287' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='101440'> + <var-decl name='_py_autocommit' type-id='type-id-870' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='288' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='101888'> + <var-decl name='_py_b' type-id='type-id-595' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='289' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='102272'> + <var-decl name='_py_backtick' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='290' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='102720'> + <var-decl name='_py_base' type-id='type-id-883' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='291' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='103104'> + <var-decl name='_py_before' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='292' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='103488'> + <var-decl name='_py_big' type-id='type-id-893' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='293' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='103872'> + <var-decl name='_py_binary_form' type-id='type-id-877' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='294' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='104320'> + <var-decl name='_py_block' type-id='type-id-880' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='295' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='104704'> + <var-decl name='_py_bound' type-id='type-id-880' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='296' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='105088'> + <var-decl name='_py_buffer' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='297' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='105472'> + <var-decl name='_py_buffer_callback' type-id='type-id-881' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='298' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='105920'> + <var-decl name='_py_buffer_size' type-id='type-id-877' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='299' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='106368'> + <var-decl name='_py_buffering' type-id='type-id-871' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='300' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='106816'> + <var-decl name='_py_buffers' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='301' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='107200'> + <var-decl name='_py_bufsize' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='302' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='107584'> + <var-decl name='_py_builtins' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='303' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='108032'> + <var-decl name='_py_byteorder' type-id='type-id-871' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='304' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='108480'> + <var-decl name='_py_bytes' type-id='type-id-880' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='305' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='108864'> + <var-decl name='_py_bytes_per_sep' type-id='type-id-875' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='306' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='109312'> + <var-decl name='_py_c' type-id='type-id-595' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='307' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='109696'> + <var-decl name='_py_c_call' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='308' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='110080'> + <var-decl name='_py_c_exception' type-id='type-id-877' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='309' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='110528'> + <var-decl name='_py_c_return' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='310' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='110976'> + <var-decl name='_py_cached_statements' type-id='type-id-885' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='311' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='111488'> + <var-decl name='_py_cadata' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='312' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='111872'> + <var-decl name='_py_cafile' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='313' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='112256'> + <var-decl name='_py_call' type-id='type-id-883' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='314' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='112640'> + <var-decl name='_py_call_exception_handler' type-id='type-id-895' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='315' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='113152'> + <var-decl name='_py_call_soon' type-id='type-id-871' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='316' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='113600'> + <var-decl name='_py_cancel' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='317' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='113984'> + <var-decl name='_py_capath' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='318' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='114368'> + <var-decl name='_py_category' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='319' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='114816'> + <var-decl name='_py_cb_type' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='320' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='115200'> + <var-decl name='_py_certfile' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='321' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='115648'> + <var-decl name='_py_check_same_thread' type-id='type-id-885' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='322' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='116160'> + <var-decl name='_py_clear' type-id='type-id-880' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='323' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='116544'> + <var-decl name='_py_close' type-id='type-id-880' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='324' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='116928'> + <var-decl name='_py_closed' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='325' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='117312'> + <var-decl name='_py_closefd' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='326' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='117696'> + <var-decl name='_py_closure' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='327' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='118080'> + <var-decl name='_py_co_argcount' type-id='type-id-877' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='328' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='118528'> + <var-decl name='_py_co_cellvars' type-id='type-id-877' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='329' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='118976'> + <var-decl name='_py_co_code' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='330' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='119360'> + <var-decl name='_py_co_consts' type-id='type-id-871' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='331' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='119808'> + <var-decl name='_py_co_exceptiontable' type-id='type-id-885' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='332' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='120320'> + <var-decl name='_py_co_filename' type-id='type-id-877' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='333' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='120768'> + <var-decl name='_py_co_firstlineno' type-id='type-id-884' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='334' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='121216'> + <var-decl name='_py_co_flags' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='335' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='121664'> + <var-decl name='_py_co_freevars' type-id='type-id-877' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='336' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='122112'> + <var-decl name='_py_co_kwonlyargcount' type-id='type-id-885' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='337' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='122624'> + <var-decl name='_py_co_linetable' type-id='type-id-876' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='338' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='123072'> + <var-decl name='_py_co_name' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='339' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='123456'> + <var-decl name='_py_co_names' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='340' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='123904'> + <var-decl name='_py_co_nlocals' type-id='type-id-870' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='341' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='124352'> + <var-decl name='_py_co_posonlyargcount' type-id='type-id-891' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='342' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='124864'> + <var-decl name='_py_co_qualname' type-id='type-id-877' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='343' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='125312'> + <var-decl name='_py_co_stacksize' type-id='type-id-876' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='344' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='125760'> + <var-decl name='_py_co_varnames' type-id='type-id-877' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='345' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='126208'> + <var-decl name='_py_code' type-id='type-id-883' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='346' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='126592'> + <var-decl name='_py_command' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='347' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='126976'> + <var-decl name='_py_comment_factory' type-id='type-id-881' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='348' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='127424'> + <var-decl name='_py_compile_mode' type-id='type-id-876' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='349' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='127872'> + <var-decl name='_py_consts' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='350' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128256'> + <var-decl name='_py_context' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='351' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128640'> + <var-decl name='_py_contravariant' type-id='type-id-875' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='352' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='129088'> + <var-decl name='_py_cookie' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='353' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='129472'> + <var-decl name='_py_copy' type-id='type-id-883' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='354' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='129856'> + <var-decl name='_py_copyreg' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='355' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='130240'> + <var-decl name='_py_coro' type-id='type-id-883' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='356' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='130624'> + <var-decl name='_py_count' type-id='type-id-880' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='357' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='131008'> + <var-decl name='_py_covariant' type-id='type-id-871' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='358' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='131456'> + <var-decl name='_py_cwd' type-id='type-id-893' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='359' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='131840'> + <var-decl name='_py_d' type-id='type-id-595' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='360' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='132224'> + <var-decl name='_py_data' type-id='type-id-883' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='361' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='132608'> + <var-decl name='_py_database' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='362' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='133056'> + <var-decl name='_py_decode' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='363' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='133440'> + <var-decl name='_py_decoder' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='364' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='133824'> + <var-decl name='_py_default' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='365' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='134208'> + <var-decl name='_py_defaultaction' type-id='type-id-875' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='366' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='134656'> + <var-decl name='_py_delete' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='367' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='135040'> + <var-decl name='_py_depth' type-id='type-id-880' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='368' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='135424'> + <var-decl name='_py_detect_types' type-id='type-id-876' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='369' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='135872'> + <var-decl name='_py_deterministic' type-id='type-id-875' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='370' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='136320'> + <var-decl name='_py_device' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='371' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='136704'> + <var-decl name='_py_dict' type-id='type-id-883' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='372' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='137088'> + <var-decl name='_py_dictcomp' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='373' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='137536'> + <var-decl name='_py_difference_update' type-id='type-id-885' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='374' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='138048'> + <var-decl name='_py_digest' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='375' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='138432'> + <var-decl name='_py_digest_size' type-id='type-id-877' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='376' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='138880'> + <var-decl name='_py_digestmod' type-id='type-id-871' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='377' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='139328'> + <var-decl name='_py_dir_fd' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='378' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='139712'> + <var-decl name='_py_discard' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='379' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='140096'> + <var-decl name='_py_dispatch_table' type-id='type-id-884' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='380' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='140544'> + <var-decl name='_py_displayhook' type-id='type-id-877' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='381' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='140992'> + <var-decl name='_py_dklen' type-id='type-id-880' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='382' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='141376'> + <var-decl name='_py_doc' type-id='type-id-893' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='383' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='141760'> + <var-decl name='_py_dont_inherit' type-id='type-id-876' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='384' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='142208'> + <var-decl name='_py_dst' type-id='type-id-893' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='385' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='142592'> + <var-decl name='_py_dst_dir_fd' type-id='type-id-870' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='386' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='143040'> + <var-decl name='_py_duration' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='387' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='143488'> + <var-decl name='_py_e' type-id='type-id-595' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='388' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='143872'> + <var-decl name='_py_eager_start' type-id='type-id-877' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='389' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='144320'> + <var-decl name='_py_effective_ids' type-id='type-id-875' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='390' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='144768'> + <var-decl name='_py_element_factory' type-id='type-id-881' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='391' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='145216'> + <var-decl name='_py_encode' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='392' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='145600'> + <var-decl name='_py_encoding' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='393' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='146048'> + <var-decl name='_py_end' type-id='type-id-893' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='394' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='146432'> + <var-decl name='_py_end_lineno' type-id='type-id-870' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='395' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='146880'> + <var-decl name='_py_end_offset' type-id='type-id-870' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='396' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='147328'> + <var-decl name='_py_endpos' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='397' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='147712'> + <var-decl name='_py_entrypoint' type-id='type-id-870' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='398' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='148160'> + <var-decl name='_py_env' type-id='type-id-893' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='399' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='148544'> + <var-decl name='_py_errors' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='400' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='148928'> + <var-decl name='_py_event' type-id='type-id-880' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='401' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='149312'> + <var-decl name='_py_eventmask' type-id='type-id-871' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='402' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='149760'> + <var-decl name='_py_exc_type' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='403' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='150208'> + <var-decl name='_py_exc_value' type-id='type-id-871' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='404' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='150656'> + <var-decl name='_py_excepthook' type-id='type-id-870' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='405' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='151104'> + <var-decl name='_py_exception' type-id='type-id-871' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='406' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='151552'> + <var-decl name='_py_existing_file_name' type-id='type-id-891' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='407' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='152064'> + <var-decl name='_py_exp' type-id='type-id-893' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='408' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='152448'> + <var-decl name='_py_extend' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='409' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='152832'> + <var-decl name='_py_extra_tokens' type-id='type-id-876' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='410' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='153280'> + <var-decl name='_py_facility' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='411' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='153728'> + <var-decl name='_py_factory' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='412' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='154112'> + <var-decl name='_py_false' type-id='type-id-880' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='413' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='154496'> + <var-decl name='_py_family' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='414' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='154880'> + <var-decl name='_py_fanout' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='415' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='155264'> + <var-decl name='_py_fd' type-id='type-id-873' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='416' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='155648'> + <var-decl name='_py_fd2' type-id='type-id-893' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='417' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='156032'> + <var-decl name='_py_fdel' type-id='type-id-883' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='418' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='156416'> + <var-decl name='_py_fget' type-id='type-id-883' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='419' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='156800'> + <var-decl name='_py_file' type-id='type-id-883' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='420' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='157184'> + <var-decl name='_py_file_actions' type-id='type-id-876' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='421' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='157632'> + <var-decl name='_py_filename' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='422' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='158080'> + <var-decl name='_py_fileno' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='423' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='158464'> + <var-decl name='_py_filepath' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='424' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='158912'> + <var-decl name='_py_fillvalue' type-id='type-id-871' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='425' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='159360'> + <var-decl name='_py_filters' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='426' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='159744'> + <var-decl name='_py_final' type-id='type-id-880' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='427' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='160128'> + <var-decl name='_py_find_class' type-id='type-id-870' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='428' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='160576'> + <var-decl name='_py_fix_imports' type-id='type-id-877' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='429' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='161024'> + <var-decl name='_py_flags' type-id='type-id-880' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='430' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='161408'> + <var-decl name='_py_flush' type-id='type-id-880' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='431' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='161792'> + <var-decl name='_py_follow_symlinks' type-id='type-id-881' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='432' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='162240'> + <var-decl name='_py_format' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='433' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='162624'> + <var-decl name='_py_frequency' type-id='type-id-871' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='434' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='163072'> + <var-decl name='_py_from_param' type-id='type-id-870' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='435' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='163520'> + <var-decl name='_py_fromlist' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='436' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='163968'> + <var-decl name='_py_fromtimestamp' type-id='type-id-875' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='437' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='164416'> + <var-decl name='_py_fromutc' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='438' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='164800'> + <var-decl name='_py_fset' type-id='type-id-883' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='439' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='165184'> + <var-decl name='_py_func' type-id='type-id-883' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='440' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='165568'> + <var-decl name='_py_future' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='441' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='165952'> + <var-decl name='_py_generation' type-id='type-id-870' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='442' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='166400'> + <var-decl name='_py_genexpr' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='443' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='166784'> + <var-decl name='_py_get' type-id='type-id-893' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='444' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='167168'> + <var-decl name='_py_get_debug' type-id='type-id-871' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='445' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='167616'> + <var-decl name='_py_get_event_loop' type-id='type-id-884' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='446' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='168064'> + <var-decl name='_py_get_loop' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='447' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='168512'> + <var-decl name='_py_get_source' type-id='type-id-870' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='448' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='168960'> + <var-decl name='_py_getattr' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='449' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='169344'> + <var-decl name='_py_getstate' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='450' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='169792'> + <var-decl name='_py_gid' type-id='type-id-893' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='451' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='170176'> + <var-decl name='_py_globals' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='452' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='170560'> + <var-decl name='_py_groupindex' type-id='type-id-870' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='453' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='171008'> + <var-decl name='_py_groups' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='454' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='171392'> + <var-decl name='_py_handle' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='455' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='171776'> + <var-decl name='_py_hash_name' type-id='type-id-871' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='456' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='172224'> + <var-decl name='_py_header' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='457' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='172608'> + <var-decl name='_py_headers' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='458' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='172992'> + <var-decl name='_py_hi' type-id='type-id-873' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='459' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='173376'> + <var-decl name='_py_hook' type-id='type-id-883' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='460' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='173760'> + <var-decl name='_py_id' type-id='type-id-873' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='461' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='174144'> + <var-decl name='_py_ident' type-id='type-id-880' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='462' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='174528'> + <var-decl name='_py_ignore' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='463' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='174912'> + <var-decl name='_py_imag' type-id='type-id-883' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='464' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='175296'> + <var-decl name='_py_importlib' type-id='type-id-871' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='465' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='175744'> + <var-decl name='_py_in_fd' type-id='type-id-880' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='466' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='176128'> + <var-decl name='_py_incoming' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='467' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='176576'> + <var-decl name='_py_indexgroup' type-id='type-id-870' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='468' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='177024'> + <var-decl name='_py_inf' type-id='type-id-893' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='469' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='177408'> + <var-decl name='_py_infer_variance' type-id='type-id-884' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='470' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='177856'> + <var-decl name='_py_inheritable' type-id='type-id-877' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='471' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='178304'> + <var-decl name='_py_initial' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='472' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='178688'> + <var-decl name='_py_initial_bytes' type-id='type-id-875' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='473' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='179136'> + <var-decl name='_py_initial_value' type-id='type-id-875' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='474' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='179584'> + <var-decl name='_py_initval' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='475' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='179968'> + <var-decl name='_py_inner_size' type-id='type-id-870' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='476' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='180416'> + <var-decl name='_py_input' type-id='type-id-880' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='477' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='180800'> + <var-decl name='_py_insert_comments' type-id='type-id-881' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='478' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='181248'> + <var-decl name='_py_insert_pis' type-id='type-id-870' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='479' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='181696'> + <var-decl name='_py_instructions' type-id='type-id-876' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='480' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='182144'> + <var-decl name='_py_intern' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='481' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='182528'> + <var-decl name='_py_intersection' type-id='type-id-876' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='482' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='182976'> + <var-decl name='_py_is_running' type-id='type-id-870' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='483' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='183424'> + <var-decl name='_py_isatty' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='484' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='183808'> + <var-decl name='_py_isinstance' type-id='type-id-870' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='485' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='184256'> + <var-decl name='_py_isoformat' type-id='type-id-871' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='486' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='184704'> + <var-decl name='_py_isolation_level' type-id='type-id-881' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='487' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='185152'> + <var-decl name='_py_istext' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='488' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='185536'> + <var-decl name='_py_item' type-id='type-id-883' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='489' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='185920'> + <var-decl name='_py_items' type-id='type-id-880' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='490' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='186304'> + <var-decl name='_py_iter' type-id='type-id-883' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='491' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='186688'> + <var-decl name='_py_iterable' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='492' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='187136'> + <var-decl name='_py_iterations' type-id='type-id-870' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='493' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='187584'> + <var-decl name='_py_join' type-id='type-id-883' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='494' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='187968'> + <var-decl name='_py_jump' type-id='type-id-883' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='495' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='188352'> + <var-decl name='_py_keepends' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='496' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='188800'> + <var-decl name='_py_key' type-id='type-id-893' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='497' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='189184'> + <var-decl name='_py_keyfile' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='498' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='189568'> + <var-decl name='_py_keys' type-id='type-id-883' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='499' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='189952'> + <var-decl name='_py_kind' type-id='type-id-883' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='500' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='190336'> + <var-decl name='_py_kw' type-id='type-id-873' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='501' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='190720'> + <var-decl name='_py_kw1' type-id='type-id-893' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='502' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='191104'> + <var-decl name='_py_kw2' type-id='type-id-893' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='503' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='191488'> + <var-decl name='_py_lambda' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='504' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='191872'> + <var-decl name='_py_last' type-id='type-id-883' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='505' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192256'> + <var-decl name='_py_last_exc' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='506' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192704'> + <var-decl name='_py_last_node' type-id='type-id-871' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='507' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='193152'> + <var-decl name='_py_last_traceback' type-id='type-id-884' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='508' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='193600'> + <var-decl name='_py_last_type' type-id='type-id-871' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='509' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='194048'> + <var-decl name='_py_last_value' type-id='type-id-870' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='510' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='194496'> + <var-decl name='_py_latin1' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='511' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='194880'> + <var-decl name='_py_leaf_size' type-id='type-id-871' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='512' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='195328'> + <var-decl name='_py_len' type-id='type-id-893' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='513' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='195712'> + <var-decl name='_py_length' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='514' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='196096'> + <var-decl name='_py_level' type-id='type-id-880' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='515' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='196480'> + <var-decl name='_py_limit' type-id='type-id-880' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='516' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='196864'> + <var-decl name='_py_line' type-id='type-id-883' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='517' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='197248'> + <var-decl name='_py_line_buffering' type-id='type-id-884' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='518' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='197696'> + <var-decl name='_py_lineno' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='519' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='198080'> + <var-decl name='_py_listcomp' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='520' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='198528'> + <var-decl name='_py_little' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='521' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='198912'> + <var-decl name='_py_lo' type-id='type-id-873' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='522' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='199296'> + <var-decl name='_py_locale' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='523' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='199680'> + <var-decl name='_py_locals' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='524' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='200064'> + <var-decl name='_py_logoption' type-id='type-id-871' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='525' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='200512'> + <var-decl name='_py_loop' type-id='type-id-883' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='526' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='200896'> + <var-decl name='_py_mapping' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='527' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='201280'> + <var-decl name='_py_match' type-id='type-id-880' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='528' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='201664'> + <var-decl name='_py_max_length' type-id='type-id-870' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='529' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='202112'> + <var-decl name='_py_maxdigits' type-id='type-id-871' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='530' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='202560'> + <var-decl name='_py_maxevents' type-id='type-id-871' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='531' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='203008'> + <var-decl name='_py_maxmem' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='532' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='203392'> + <var-decl name='_py_maxsplit' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='533' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='203840'> + <var-decl name='_py_maxvalue' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='534' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='204288'> + <var-decl name='_py_memLevel' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='535' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='204736'> + <var-decl name='_py_memlimit' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='536' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='205184'> + <var-decl name='_py_message' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='537' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='205568'> + <var-decl name='_py_metaclass' type-id='type-id-871' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='538' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='206016'> + <var-decl name='_py_metadata' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='539' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='206464'> + <var-decl name='_py_method' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='540' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='206848'> + <var-decl name='_py_mod' type-id='type-id-893' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='541' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='207232'> + <var-decl name='_py_mode' type-id='type-id-883' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='542' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='207616'> + <var-decl name='_py_module' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='543' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='208000'> + <var-decl name='_py_module_globals' type-id='type-id-884' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='544' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='208448'> + <var-decl name='_py_modules' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='545' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='208832'> + <var-decl name='_py_mro' type-id='type-id-893' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='546' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='209216'> + <var-decl name='_py_msg' type-id='type-id-893' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='547' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='209600'> + <var-decl name='_py_mycmp' type-id='type-id-880' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='548' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='209984'> + <var-decl name='_py_n' type-id='type-id-595' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='549' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='210368'> + <var-decl name='_py_n_arg' type-id='type-id-880' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='550' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='210752'> + <var-decl name='_py_n_fields' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='551' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='211200'> + <var-decl name='_py_n_sequence_fields' type-id='type-id-885' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='552' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='211712'> + <var-decl name='_py_n_unnamed_fields' type-id='type-id-889' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='553' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='212224'> + <var-decl name='_py_name' type-id='type-id-883' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='554' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='212608'> + <var-decl name='_py_name_from' type-id='type-id-871' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='555' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='213056'> + <var-decl name='_py_namespace_separator' type-id='type-id-886' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='556' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='213568'> + <var-decl name='_py_namespaces' type-id='type-id-870' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='557' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='214016'> + <var-decl name='_py_narg' type-id='type-id-883' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='558' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='214400'> + <var-decl name='_py_ndigits' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='559' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='214784'> + <var-decl name='_py_new_file_name' type-id='type-id-875' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='560' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='215232'> + <var-decl name='_py_new_limit' type-id='type-id-871' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='561' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='215680'> + <var-decl name='_py_newline' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='562' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='216064'> + <var-decl name='_py_newlines' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='563' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='216512'> + <var-decl name='_py_next' type-id='type-id-883' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='564' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='216896'> + <var-decl name='_py_nlocals' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='565' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='217280'> + <var-decl name='_py_node_depth' type-id='type-id-870' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='566' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='217728'> + <var-decl name='_py_node_offset' type-id='type-id-877' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='567' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='218176'> + <var-decl name='_py_ns' type-id='type-id-873' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='568' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='218560'> + <var-decl name='_py_nstype' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='569' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='218944'> + <var-decl name='_py_nt' type-id='type-id-873' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='570' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='219328'> + <var-decl name='_py_null' type-id='type-id-883' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='571' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='219712'> + <var-decl name='_py_number' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='572' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='220096'> + <var-decl name='_py_obj' type-id='type-id-893' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='573' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='220480'> + <var-decl name='_py_object' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='574' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='220864'> + <var-decl name='_py_offset' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='575' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='221248'> + <var-decl name='_py_offset_dst' type-id='type-id-870' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='576' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='221696'> + <var-decl name='_py_offset_src' type-id='type-id-870' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='577' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='222144'> + <var-decl name='_py_on_type_read' type-id='type-id-876' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='578' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='222592'> + <var-decl name='_py_onceregistry' type-id='type-id-876' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='579' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='223040'> + <var-decl name='_py_only_keys' type-id='type-id-871' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='580' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='223488'> + <var-decl name='_py_oparg' type-id='type-id-880' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='581' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='223872'> + <var-decl name='_py_opcode' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='582' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='224256'> + <var-decl name='_py_open' type-id='type-id-883' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='583' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='224640'> + <var-decl name='_py_opener' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='584' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='225024'> + <var-decl name='_py_operation' type-id='type-id-871' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='585' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='225472'> + <var-decl name='_py_optimize' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='586' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='225920'> + <var-decl name='_py_options' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='587' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='226304'> + <var-decl name='_py_order' type-id='type-id-880' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='588' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='226688'> + <var-decl name='_py_origin' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='589' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='227072'> + <var-decl name='_py_out_fd' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='590' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='227456'> + <var-decl name='_py_outgoing' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='591' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='227904'> + <var-decl name='_py_overlapped' type-id='type-id-870' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='592' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='228352'> + <var-decl name='_py_owner' type-id='type-id-880' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='593' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='228736'> + <var-decl name='_py_p' type-id='type-id-595' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='594' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='229120'> + <var-decl name='_py_pages' type-id='type-id-880' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='595' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='229504'> + <var-decl name='_py_parent' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='596' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='229888'> + <var-decl name='_py_password' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='597' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='230336'> + <var-decl name='_py_path' type-id='type-id-883' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='598' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='230720'> + <var-decl name='_py_pattern' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='599' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='231104'> + <var-decl name='_py_peek' type-id='type-id-883' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='600' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='231488'> + <var-decl name='_py_persistent_id' type-id='type-id-875' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='601' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='231936'> + <var-decl name='_py_persistent_load' type-id='type-id-881' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='602' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='232384'> + <var-decl name='_py_person' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='603' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='232768'> + <var-decl name='_py_pi_factory' type-id='type-id-870' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='604' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='233216'> + <var-decl name='_py_pid' type-id='type-id-893' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='605' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='233600'> + <var-decl name='_py_policy' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='606' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='233984'> + <var-decl name='_py_pos' type-id='type-id-893' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='607' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='234368'> + <var-decl name='_py_pos1' type-id='type-id-883' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='608' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='234752'> + <var-decl name='_py_pos2' type-id='type-id-883' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='609' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='235136'> + <var-decl name='_py_posix' type-id='type-id-880' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='610' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='235520'> + <var-decl name='_py_print_file_and_line' type-id='type-id-886' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='611' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='236032'> + <var-decl name='_py_priority' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='612' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='236480'> + <var-decl name='_py_progress' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='613' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='236928'> + <var-decl name='_py_progress_handler' type-id='type-id-889' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='614' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='237440'> + <var-decl name='_py_progress_routine' type-id='type-id-889' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='615' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='237952'> + <var-decl name='_py_proto' type-id='type-id-880' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='616' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='238336'> + <var-decl name='_py_protocol' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='617' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='238784'> + <var-decl name='_py_ps1' type-id='type-id-893' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='618' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='239168'> + <var-decl name='_py_ps2' type-id='type-id-893' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='619' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='239552'> + <var-decl name='_py_query' type-id='type-id-880' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='620' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='239936'> + <var-decl name='_py_quotetabs' type-id='type-id-871' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='621' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='240384'> + <var-decl name='_py_r' type-id='type-id-595' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='622' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='240768'> + <var-decl name='_py_raw' type-id='type-id-893' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='623' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='241152'> + <var-decl name='_py_read' type-id='type-id-883' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='624' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='241536'> + <var-decl name='_py_read1' type-id='type-id-880' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='625' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='241920'> + <var-decl name='_py_readable' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='626' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='242368'> + <var-decl name='_py_readall' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='627' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='242752'> + <var-decl name='_py_readinto' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='628' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='243200'> + <var-decl name='_py_readinto1' type-id='type-id-871' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='629' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='243648'> + <var-decl name='_py_readline' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='630' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='244096'> + <var-decl name='_py_readonly' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='631' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='244544'> + <var-decl name='_py_real' type-id='type-id-883' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='632' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='244928'> + <var-decl name='_py_reducer_override' type-id='type-id-889' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='633' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='245440'> + <var-decl name='_py_registry' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='634' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='245888'> + <var-decl name='_py_rel_tol' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='635' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='246272'> + <var-decl name='_py_release' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='636' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='246656'> + <var-decl name='_py_reload' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='637' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='247040'> + <var-decl name='_py_repl' type-id='type-id-883' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='638' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='247424'> + <var-decl name='_py_replace' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='639' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='247808'> + <var-decl name='_py_reserved' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='640' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='248256'> + <var-decl name='_py_reset' type-id='type-id-880' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='641' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='248640'> + <var-decl name='_py_resetids' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='642' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='249088'> + <var-decl name='_py_return' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='643' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='249472'> + <var-decl name='_py_reverse' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='644' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='249856'> + <var-decl name='_py_reversed' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='645' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='250304'> + <var-decl name='_py_s' type-id='type-id-595' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='646' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='250688'> + <var-decl name='_py_salt' type-id='type-id-883' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='647' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='251072'> + <var-decl name='_py_sched_priority' type-id='type-id-884' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='648' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='251520'> + <var-decl name='_py_scheduler' type-id='type-id-871' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='649' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='251968'> + <var-decl name='_py_seek' type-id='type-id-883' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='650' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='252352'> + <var-decl name='_py_seekable' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='651' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='252800'> + <var-decl name='_py_selectors' type-id='type-id-871' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='652' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='253248'> + <var-decl name='_py_self' type-id='type-id-883' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='653' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='253632'> + <var-decl name='_py_send' type-id='type-id-883' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='654' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='254016'> + <var-decl name='_py_sep' type-id='type-id-893' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='655' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='254400'> + <var-decl name='_py_sequence' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='656' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='254848'> + <var-decl name='_py_server_hostname' type-id='type-id-881' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='657' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='255296'> + <var-decl name='_py_server_side' type-id='type-id-877' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='658' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='255744'> + <var-decl name='_py_session' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='659' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256128'> + <var-decl name='_py_setcomp' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='660' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256512'> + <var-decl name='_py_setpgroup' type-id='type-id-871' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='661' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256960'> + <var-decl name='_py_setsid' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='662' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='257344'> + <var-decl name='_py_setsigdef' type-id='type-id-871' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='663' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='257792'> + <var-decl name='_py_setsigmask' type-id='type-id-870' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='664' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='258240'> + <var-decl name='_py_setstate' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='665' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='258688'> + <var-decl name='_py_shape' type-id='type-id-880' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='666' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='259072'> + <var-decl name='_py_show_cmd' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='667' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='259520'> + <var-decl name='_py_signed' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='668' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='259904'> + <var-decl name='_py_size' type-id='type-id-883' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='669' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='260288'> + <var-decl name='_py_sizehint' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='670' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='260736'> + <var-decl name='_py_skip_file_prefixes' type-id='type-id-891' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='671' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='261248'> + <var-decl name='_py_sleep' type-id='type-id-880' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='672' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='261632'> + <var-decl name='_py_sock' type-id='type-id-883' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='673' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='262016'> + <var-decl name='_py_sort' type-id='type-id-883' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='674' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='262400'> + <var-decl name='_py_sound' type-id='type-id-880' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='675' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='262784'> + <var-decl name='_py_source' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='676' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='263168'> + <var-decl name='_py_source_traceback' type-id='type-id-889' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='677' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='263680'> + <var-decl name='_py_src' type-id='type-id-893' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='678' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='264064'> + <var-decl name='_py_src_dir_fd' type-id='type-id-870' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='679' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='264512'> + <var-decl name='_py_stacklevel' type-id='type-id-870' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='680' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='264960'> + <var-decl name='_py_start' type-id='type-id-880' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='681' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='265344'> + <var-decl name='_py_statement' type-id='type-id-871' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='682' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='265792'> + <var-decl name='_py_status' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='683' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='266176'> + <var-decl name='_py_stderr' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='684' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='266560'> + <var-decl name='_py_stdin' type-id='type-id-880' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='685' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='266944'> + <var-decl name='_py_stdout' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='686' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='267328'> + <var-decl name='_py_step' type-id='type-id-883' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='687' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='267712'> + <var-decl name='_py_steps' type-id='type-id-880' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='688' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='268096'> + <var-decl name='_py_store_name' type-id='type-id-870' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='689' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='268544'> + <var-decl name='_py_strategy' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='690' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='268992'> + <var-decl name='_py_strftime' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='691' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='269440'> + <var-decl name='_py_strict' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='692' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='269824'> + <var-decl name='_py_strict_mode' type-id='type-id-877' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='693' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='270272'> + <var-decl name='_py_string' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='694' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='270656'> + <var-decl name='_py_sub_key' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='695' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='271040'> + <var-decl name='_py_symmetric_difference_update' type-id='type-id-896' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='696' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='271616'> + <var-decl name='_py_tabsize' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='697' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='272000'> + <var-decl name='_py_tag' type-id='type-id-893' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='698' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='272384'> + <var-decl name='_py_target' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='699' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='272768'> + <var-decl name='_py_target_is_directory' type-id='type-id-886' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='700' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='273280'> + <var-decl name='_py_task' type-id='type-id-883' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='701' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='273664'> + <var-decl name='_py_tb_frame' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='702' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='274112'> + <var-decl name='_py_tb_lasti' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='703' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='274560'> + <var-decl name='_py_tb_lineno' type-id='type-id-871' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='704' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='275008'> + <var-decl name='_py_tb_next' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='705' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='275392'> + <var-decl name='_py_tell' type-id='type-id-883' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='706' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='275776'> + <var-decl name='_py_template' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='707' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='276224'> + <var-decl name='_py_term' type-id='type-id-883' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='708' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='276608'> + <var-decl name='_py_text' type-id='type-id-883' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='709' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='276992'> + <var-decl name='_py_threading' type-id='type-id-871' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='710' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='277440'> + <var-decl name='_py_throw' type-id='type-id-880' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='711' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='277824'> + <var-decl name='_py_timeout' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='712' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='278208'> + <var-decl name='_py_times' type-id='type-id-880' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='713' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='278592'> + <var-decl name='_py_timetuple' type-id='type-id-871' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='714' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='279040'> + <var-decl name='_py_top' type-id='type-id-893' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='715' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='279424'> + <var-decl name='_py_trace_callback' type-id='type-id-884' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='716' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='279872'> + <var-decl name='_py_traceback' type-id='type-id-871' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='717' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='280320'> + <var-decl name='_py_trailers' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='718' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='280768'> + <var-decl name='_py_translate' type-id='type-id-871' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='719' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='281216'> + <var-decl name='_py_true' type-id='type-id-883' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='720' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='281600'> + <var-decl name='_py_truncate' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='721' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='282048'> + <var-decl name='_py_twice' type-id='type-id-880' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='722' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='282432'> + <var-decl name='_py_txt' type-id='type-id-893' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='723' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='282816'> + <var-decl name='_py_type' type-id='type-id-883' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='724' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='283200'> + <var-decl name='_py_type_params' type-id='type-id-877' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='725' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='283648'> + <var-decl name='_py_tz' type-id='type-id-873' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='726' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='284032'> + <var-decl name='_py_tzname' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='727' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='284416'> + <var-decl name='_py_uid' type-id='type-id-893' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='728' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='284800'> + <var-decl name='_py_unlink' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='729' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='285184'> + <var-decl name='_py_unraisablehook' type-id='type-id-884' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='730' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='285632'> + <var-decl name='_py_uri' type-id='type-id-893' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='731' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='286016'> + <var-decl name='_py_usedforsecurity' type-id='type-id-881' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='732' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='286464'> + <var-decl name='_py_value' type-id='type-id-880' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='733' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='286848'> + <var-decl name='_py_values' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='734' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='287232'> + <var-decl name='_py_version' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='735' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='287616'> + <var-decl name='_py_volume' type-id='type-id-879' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='736' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='288000'> + <var-decl name='_py_warnings' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='737' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='288448'> + <var-decl name='_py_warnoptions' type-id='type-id-877' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='738' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='288896'> + <var-decl name='_py_wbits' type-id='type-id-880' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='739' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='289280'> + <var-decl name='_py_week' type-id='type-id-883' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='740' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='289664'> + <var-decl name='_py_weekday' type-id='type-id-882' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='741' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='290048'> + <var-decl name='_py_which' type-id='type-id-880' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='742' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='290432'> + <var-decl name='_py_who' type-id='type-id-893' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='743' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='290816'> + <var-decl name='_py_withdata' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='744' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='291264'> + <var-decl name='_py_writable' type-id='type-id-872' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='745' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='291712'> + <var-decl name='_py_write' type-id='type-id-880' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='746' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='292096'> + <var-decl name='_py_write_through' type-id='type-id-875' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='747' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='292544'> + <var-decl name='_py_x' type-id='type-id-595' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='748' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='292928'> + <var-decl name='_py_year' type-id='type-id-883' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='749' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='293312'> + <var-decl name='_py_zdict' type-id='type-id-880' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='750' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__54' size-in-bits='448' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='63' column='1' id='type-id-881'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='_ascii' type-id='type-id-794' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='63' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='_data' type-id='type-id-661' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='63' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__55' size-in-bits='384' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='64' column='1' id='type-id-882'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='_ascii' type-id='type-id-794' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='64' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='_data' type-id='type-id-693' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='64' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__58' size-in-bits='384' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='67' column='1' id='type-id-883'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='_ascii' type-id='type-id-794' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='67' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='_data' type-id='type-id-688' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='67' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__59' size-in-bits='448' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='68' column='1' id='type-id-884'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='_ascii' type-id='type-id-794' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='68' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='_data' type-id='type-id-659' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='68' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__61' size-in-bits='512' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='70' column='1' id='type-id-885'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='_ascii' type-id='type-id-794' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='70' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='_data' type-id='type-id-663' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='70' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__65' size-in-bits='512' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='74' column='1' id='type-id-886'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='_ascii' type-id='type-id-794' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='74' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='_data' type-id='type-id-668' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='74' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__75' size-in-bits='576' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='84' column='1' id='type-id-887'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='_ascii' type-id='type-id-794' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='84' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='_data' type-id='type-id-682' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='84' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__93' size-in-bits='576' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='102' column='1' id='type-id-888'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='_ascii' type-id='type-id-794' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='102' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='_data' type-id='type-id-675' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='102' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__114' size-in-bits='512' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='123' column='1' id='type-id-889'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='_ascii' type-id='type-id-794' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='123' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='_data' type-id='type-id-662' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='123' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__139' size-in-bits='512' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='148' column='1' id='type-id-890'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='_ascii' type-id='type-id-794' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='148' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='_data' type-id='type-id-669' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='148' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__181' size-in-bits='512' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='190' column='1' id='type-id-891'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='_ascii' type-id='type-id-794' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='190' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='_data' type-id='type-id-665' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='190' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__213' size-in-bits='640' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='222' column='1' id='type-id-892'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='_ascii' type-id='type-id-794' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='222' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='_data' type-id='type-id-684' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='222' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__242' size-in-bits='384' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='251' column='1' id='type-id-893'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='_ascii' type-id='type-id-794' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='251' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='_data' type-id='type-id-687' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='251' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__257' size-in-bits='576' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='266' column='1' id='type-id-894'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='_ascii' type-id='type-id-794' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='266' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='_data' type-id='type-id-677' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='266' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__306' size-in-bits='512' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='315' column='1' id='type-id-895'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='_ascii' type-id='type-id-794' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='315' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='_data' type-id='type-id-671' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='315' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__687' size-in-bits='576' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='696' column='1' id='type-id-896'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='_ascii' type-id='type-id-794' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='696' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='_data' type-id='type-id-679' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='696' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__743' size-in-bits='512' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='756' column='1' id='type-id-597'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='_latin1' type-id='type-id-797' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='757' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='448'> + <var-decl name='_data' type-id='type-id-680' visibility='default' filepath='./Include/internal/pycore_global_strings.h' line='758' column='1'/> + </data-member> + </class-decl> + <class-decl name='PyHamtNode' size-in-bits='128' is-struct='yes' naming-typedef-id='type-id-897' visibility='default' filepath='./Include/internal/pycore_hamt.h' line='38' column='1' id='type-id-898'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='ob_base' type-id='type-id-345' visibility='default' filepath='./Include/internal/pycore_hamt.h' line='39' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='PyHamtNode' type-id='type-id-898' filepath='./Include/internal/pycore_hamt.h' line='40' column='1' id='type-id-897'/> + <class-decl name='PyHamtObject' size-in-bits='320' is-struct='yes' naming-typedef-id='type-id-867' visibility='default' filepath='./Include/internal/pycore_hamt.h' line='44' column='1' id='type-id-899'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='ob_base' type-id='type-id-345' visibility='default' filepath='./Include/internal/pycore_hamt.h' line='45' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='h_root' type-id='type-id-900' visibility='default' filepath='./Include/internal/pycore_hamt.h' line='46' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='h_weakreflist' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_hamt.h' line='47' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='h_count' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_hamt.h' line='48' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='PyHamtObject' type-id='type-id-899' filepath='./Include/internal/pycore_hamt.h' line='49' column='1' id='type-id-867'/> + <class-decl name='PyHamtNode_Bitmap' size-in-bits='320' is-struct='yes' naming-typedef-id='type-id-863' visibility='default' filepath='./Include/internal/pycore_hamt.h' line='52' column='1' id='type-id-901'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='ob_base' type-id='type-id-321' visibility='default' filepath='./Include/internal/pycore_hamt.h' line='53' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='b_bitmap' type-id='type-id-352' visibility='default' filepath='./Include/internal/pycore_hamt.h' line='54' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='b_array' type-id='type-id-353' visibility='default' filepath='./Include/internal/pycore_hamt.h' line='55' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='PyHamtNode_Bitmap' type-id='type-id-901' filepath='./Include/internal/pycore_hamt.h' line='56' column='1' id='type-id-863'/> + <class-decl name='_Py_slist_item_s' size-in-bits='64' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_hashtable.h' line='13' column='1' id='type-id-902'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='next' type-id='type-id-903' visibility='default' filepath='./Include/internal/pycore_hashtable.h' line='14' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='_Py_slist_item_t' type-id='type-id-902' filepath='./Include/internal/pycore_hashtable.h' line='15' column='1' id='type-id-904'/> + <class-decl name='_Py_slist_t' size-in-bits='64' is-struct='yes' naming-typedef-id='type-id-905' visibility='default' filepath='./Include/internal/pycore_hashtable.h' line='17' column='1' id='type-id-906'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='head' type-id='type-id-907' visibility='default' filepath='./Include/internal/pycore_hashtable.h' line='18' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='_Py_slist_t' type-id='type-id-906' filepath='./Include/internal/pycore_hashtable.h' line='19' column='1' id='type-id-905'/> + <class-decl name='_Py_hashtable_entry_t' size-in-bits='256' is-struct='yes' naming-typedef-id='type-id-908' visibility='default' filepath='./Include/internal/pycore_hashtable.h' line='28' column='1' id='type-id-909'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='_Py_slist_item' type-id='type-id-904' visibility='default' filepath='./Include/internal/pycore_hashtable.h' line='30' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='key_hash' type-id='type-id-910' visibility='default' filepath='./Include/internal/pycore_hashtable.h' line='32' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='key' type-id='type-id-22' visibility='default' filepath='./Include/internal/pycore_hashtable.h' line='33' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='value' type-id='type-id-22' visibility='default' filepath='./Include/internal/pycore_hashtable.h' line='34' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='_Py_hashtable_entry_t' type-id='type-id-909' filepath='./Include/internal/pycore_hashtable.h' line='35' column='1' id='type-id-908'/> + <typedef-decl name='_Py_hashtable_t' type-id='type-id-911' filepath='./Include/internal/pycore_hashtable.h' line='42' column='1' id='type-id-912'/> + <typedef-decl name='_Py_hashtable_hash_func' type-id='type-id-913' filepath='./Include/internal/pycore_hashtable.h' line='44' column='1' id='type-id-914'/> + <typedef-decl name='_Py_hashtable_compare_func' type-id='type-id-78' filepath='./Include/internal/pycore_hashtable.h' line='45' column='1' id='type-id-915'/> + <typedef-decl name='_Py_hashtable_destroy_func' type-id='type-id-760' filepath='./Include/internal/pycore_hashtable.h' line='46' column='1' id='type-id-916'/> + <typedef-decl name='_Py_hashtable_get_entry_func' type-id='type-id-917' filepath='./Include/internal/pycore_hashtable.h' line='47' column='1' id='type-id-918'/> + <class-decl name='_Py_hashtable_allocator_t' size-in-bits='128' is-struct='yes' naming-typedef-id='type-id-919' visibility='default' filepath='./Include/internal/pycore_hashtable.h' line='50' column='1' id='type-id-920'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='malloc' type-id='type-id-921' visibility='default' filepath='./Include/internal/pycore_hashtable.h' line='52' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='free' type-id='type-id-760' visibility='default' filepath='./Include/internal/pycore_hashtable.h' line='55' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='_Py_hashtable_allocator_t' type-id='type-id-920' filepath='./Include/internal/pycore_hashtable.h' line='56' column='1' id='type-id-919'/> + <class-decl name='_Py_hashtable_t' size-in-bits='640' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_hashtable.h' line='60' column='1' id='type-id-911'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='nentries' type-id='type-id-19' visibility='default' filepath='./Include/internal/pycore_hashtable.h' line='61' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='nbuckets' type-id='type-id-19' visibility='default' filepath='./Include/internal/pycore_hashtable.h' line='62' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='buckets' type-id='type-id-922' visibility='default' filepath='./Include/internal/pycore_hashtable.h' line='63' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='get_entry_func' type-id='type-id-918' visibility='default' filepath='./Include/internal/pycore_hashtable.h' line='65' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='hash_func' type-id='type-id-914' visibility='default' filepath='./Include/internal/pycore_hashtable.h' line='66' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='compare_func' type-id='type-id-915' visibility='default' filepath='./Include/internal/pycore_hashtable.h' line='67' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='384'> + <var-decl name='key_destroy_func' type-id='type-id-916' visibility='default' filepath='./Include/internal/pycore_hashtable.h' line='68' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='448'> + <var-decl name='value_destroy_func' type-id='type-id-916' visibility='default' filepath='./Include/internal/pycore_hashtable.h' line='69' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='512'> + <var-decl name='alloc' type-id='type-id-919' visibility='default' filepath='./Include/internal/pycore_hashtable.h' line='70' column='1'/> + </data-member> + </class-decl> + <class-decl name='_import_runtime_state' size-in-bits='320' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_import.h' line='12' column='1' id='type-id-923'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='inittab' type-id='type-id-924' visibility='default' filepath='./Include/internal/pycore_import.h' line='14' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='last_module_index' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_import.h' line='19' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='extensions' type-id='type-id-925' visibility='default' filepath='./Include/internal/pycore_import.h' line='30' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='pkgcontext' type-id='type-id-12' visibility='default' filepath='./Include/internal/pycore_import.h' line='32' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__6' size-in-bits='128' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_import.h' line='20' column='1' id='type-id-925'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='mutex' type-id='type-id-801' visibility='default' filepath='./Include/internal/pycore_import.h' line='22' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='hashtable' type-id='type-id-926' visibility='default' filepath='./Include/internal/pycore_import.h' line='29' column='1'/> + </data-member> + </class-decl> + <class-decl name='_import_state' size-in-bits='768' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_import.h' line='35' column='1' id='type-id-927'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='modules' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_import.h' line='37' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='modules_by_index' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_import.h' line='57' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='importlib' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_import.h' line='59' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='override_frozen_modules' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_import.h' line='62' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='224'> + <var-decl name='override_multi_interp_extensions_check' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_import.h' line='63' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='dlopenflags' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_import.h' line='65' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='import_func' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_import.h' line='67' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='384'> + <var-decl name='lock' type-id='type-id-928' visibility='default' filepath='./Include/internal/pycore_import.h' line='73' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='576'> + <var-decl name='find_and_load' type-id='type-id-929' visibility='default' filepath='./Include/internal/pycore_import.h' line='79' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__745' size-in-bits='192' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_import.h' line='69' column='1' id='type-id-928'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='mutex' type-id='type-id-801' visibility='default' filepath='./Include/internal/pycore_import.h' line='70' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='thread' type-id='type-id-28' visibility='default' filepath='./Include/internal/pycore_import.h' line='71' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='level' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_import.h' line='72' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__746' size-in-bits='192' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_import.h' line='75' column='1' id='type-id-929'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='import_level' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_import.h' line='76' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='accumulated' type-id='type-id-790' visibility='default' filepath='./Include/internal/pycore_import.h' line='77' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='header' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_import.h' line='78' column='1'/> + </data-member> + </class-decl> + <class-decl name='_Py_long_state' size-in-bits='32' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_interp.h' line='38' column='1' id='type-id-930'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='max_str_digits' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_interp.h' line='39' column='1'/> + </data-member> + </class-decl> + <class-decl name='_is' size-in-bits='3068160' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_interp.h' line='49' column='1' id='type-id-931'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='next' type-id='type-id-20' visibility='default' filepath='./Include/internal/pycore_interp.h' line='51' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='id' type-id='type-id-377' visibility='default' filepath='./Include/internal/pycore_interp.h' line='53' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='id_refcount' type-id='type-id-377' visibility='default' filepath='./Include/internal/pycore_interp.h' line='54' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='requires_idref' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_interp.h' line='55' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='id_mutex' type-id='type-id-801' visibility='default' filepath='./Include/internal/pycore_interp.h' line='56' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='_initialized' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_interp.h' line='62' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='352'> + <var-decl name='finalizing' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_interp.h' line='63' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='384'> + <var-decl name='monitoring_version' type-id='type-id-117' visibility='default' filepath='./Include/internal/pycore_interp.h' line='65' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='448'> + <var-decl name='last_restart_version' type-id='type-id-117' visibility='default' filepath='./Include/internal/pycore_interp.h' line='66' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='512'> + <var-decl name='threads' type-id='type-id-932' visibility='default' filepath='./Include/internal/pycore_interp.h' line='78' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='768'> + <var-decl name='runtime' type-id='type-id-933' visibility='default' filepath='./Include/internal/pycore_interp.h' line='83' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='832'> + <var-decl name='_finalizing' type-id='type-id-810' visibility='default' filepath='./Include/internal/pycore_interp.h' line='90' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='896'> + <var-decl name='gc' type-id='type-id-854' visibility='default' filepath='./Include/internal/pycore_interp.h' line='92' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2816'> + <var-decl name='sysdict' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_interp.h' line='107' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2880'> + <var-decl name='builtins' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_interp.h' line='110' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2944'> + <var-decl name='ceval' type-id='type-id-823' visibility='default' filepath='./Include/internal/pycore_interp.h' line='112' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='7552'> + <var-decl name='imports' type-id='type-id-927' visibility='default' filepath='./Include/internal/pycore_interp.h' line='114' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='8320'> + <var-decl name='_gil' type-id='type-id-857' visibility='default' filepath='./Include/internal/pycore_interp.h' line='117' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='9984'> + <var-decl name='codec_search_path' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_interp.h' line='124' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='10048'> + <var-decl name='codec_search_cache' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_interp.h' line='125' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='10112'> + <var-decl name='codec_error_registry' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_interp.h' line='126' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='10176'> + <var-decl name='codecs_initialized' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_interp.h' line='127' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='10240'> + <var-decl name='config' type-id='type-id-258' visibility='default' filepath='./Include/internal/pycore_interp.h' line='129' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='13696'> + <var-decl name='feature_flags' type-id='type-id-28' visibility='default' filepath='./Include/internal/pycore_interp.h' line='130' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='13760'> + <var-decl name='dict' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_interp.h' line='132' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='13824'> + <var-decl name='sysdict_copy' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_interp.h' line='134' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='13888'> + <var-decl name='builtins_copy' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_interp.h' line='135' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='13952'> + <var-decl name='eval_frame' type-id='type-id-780' visibility='default' filepath='./Include/internal/pycore_interp.h' line='137' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='14016'> + <var-decl name='func_watchers' type-id='type-id-580' visibility='default' filepath='./Include/internal/pycore_interp.h' line='139' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='14528'> + <var-decl name='active_func_watchers' type-id='type-id-325' visibility='default' filepath='./Include/internal/pycore_interp.h' line='141' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='14592'> + <var-decl name='co_extra_user_count' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_interp.h' line='143' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='14656'> + <var-decl name='co_extra_freefuncs' type-id='type-id-627' visibility='default' filepath='./Include/internal/pycore_interp.h' line='144' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='30976'> + <var-decl name='before_forkers' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_interp.h' line='147' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='31040'> + <var-decl name='after_forkers_parent' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_interp.h' line='148' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='31104'> + <var-decl name='after_forkers_child' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_interp.h' line='149' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='31168'> + <var-decl name='warnings' type-id='type-id-934' visibility='default' filepath='./Include/internal/pycore_interp.h' line='152' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='31424'> + <var-decl name='atexit' type-id='type-id-807' visibility='default' filepath='./Include/internal/pycore_interp.h' line='153' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='31680'> + <var-decl name='obmalloc' type-id='type-id-935' visibility='default' filepath='./Include/internal/pycore_interp.h' line='155' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2137664'> + <var-decl name='audit_hooks' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_interp.h' line='157' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2137728'> + <var-decl name='type_watchers' type-id='type-id-590' visibility='default' filepath='./Include/internal/pycore_interp.h' line='158' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2138240'> + <var-decl name='code_watchers' type-id='type-id-576' visibility='default' filepath='./Include/internal/pycore_interp.h' line='159' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2138752'> + <var-decl name='active_code_watchers' type-id='type-id-325' visibility='default' filepath='./Include/internal/pycore_interp.h' line='161' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2138784'> + <var-decl name='object_state' type-id='type-id-936' visibility='default' filepath='./Include/internal/pycore_interp.h' line='163' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2138816'> + <var-decl name='unicode' type-id='type-id-937' visibility='default' filepath='./Include/internal/pycore_interp.h' line='164' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2139264'> + <var-decl name='float_state' type-id='type-id-847' visibility='default' filepath='./Include/internal/pycore_interp.h' line='165' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2139392'> + <var-decl name='long_state' type-id='type-id-930' visibility='default' filepath='./Include/internal/pycore_interp.h' line='166' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2139456'> + <var-decl name='dtoa' type-id='type-id-833' visibility='default' filepath='./Include/internal/pycore_interp.h' line='167' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2158528'> + <var-decl name='func_state' type-id='type-id-851' visibility='default' filepath='./Include/internal/pycore_interp.h' line='168' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2158592'> + <var-decl name='slice_cache' type-id='type-id-424' visibility='default' filepath='./Include/internal/pycore_interp.h' line='171' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2158656'> + <var-decl name='tuple' type-id='type-id-938' visibility='default' filepath='./Include/internal/pycore_interp.h' line='173' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2160576'> + <var-decl name='list' type-id='type-id-939' visibility='default' filepath='./Include/internal/pycore_interp.h' line='174' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2165760'> + <var-decl name='dict_state' type-id='type-id-831' visibility='default' filepath='./Include/internal/pycore_interp.h' line='175' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2176704'> + <var-decl name='async_gen' type-id='type-id-856' visibility='default' filepath='./Include/internal/pycore_interp.h' line='176' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2187072'> + <var-decl name='context' type-id='type-id-828' visibility='default' filepath='./Include/internal/pycore_interp.h' line='177' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2187200'> + <var-decl name='exc_state' type-id='type-id-834' visibility='default' filepath='./Include/internal/pycore_interp.h' line='178' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2187456'> + <var-decl name='ast' type-id='type-id-799' visibility='default' filepath='./Include/internal/pycore_interp.h' line='180' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2203072'> + <var-decl name='types' type-id='type-id-940' visibility='default' filepath='./Include/internal/pycore_interp.h' line='181' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='3053632'> + <var-decl name='callable_cache' type-id='type-id-825' visibility='default' filepath='./Include/internal/pycore_interp.h' line='182' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='3053888'> + <var-decl name='interpreter_trampoline' type-id='type-id-328' visibility='default' filepath='./Include/internal/pycore_interp.h' line='183' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='3053952'> + <var-decl name='monitors' type-id='type-id-706' visibility='default' filepath='./Include/internal/pycore_interp.h' line='185' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='3054072'> + <var-decl name='f_opcode_trace_set' type-id='type-id-615' visibility='default' filepath='./Include/internal/pycore_interp.h' line='186' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='3054080'> + <var-decl name='sys_profile_initialized' type-id='type-id-615' visibility='default' filepath='./Include/internal/pycore_interp.h' line='187' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='3054088'> + <var-decl name='sys_trace_initialized' type-id='type-id-615' visibility='default' filepath='./Include/internal/pycore_interp.h' line='188' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='3054144'> + <var-decl name='sys_profiling_threads' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_interp.h' line='189' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='3054208'> + <var-decl name='sys_tracing_threads' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_interp.h' line='190' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='3054272'> + <var-decl name='monitoring_callables' type-id='type-id-585' visibility='default' filepath='./Include/internal/pycore_interp.h' line='191' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='3062976'> + <var-decl name='monitoring_tool_names' type-id='type-id-584' visibility='default' filepath='./Include/internal/pycore_interp.h' line='192' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='3063488'> + <var-decl name='cached_objects' type-id='type-id-864' visibility='default' filepath='./Include/internal/pycore_interp.h' line='194' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='3064768'> + <var-decl name='static_objects' type-id='type-id-865' visibility='default' filepath='./Include/internal/pycore_interp.h' line='195' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='3065856'> + <var-decl name='_initial_thread' type-id='type-id-941' visibility='default' filepath='./Include/internal/pycore_interp.h' line='198' column='1'/> + </data-member> + </class-decl> + <class-decl name='pythreads' size-in-bits='256' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_interp.h' line='67' column='1' id='type-id-932'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='next_unique_id' type-id='type-id-117' visibility='default' filepath='./Include/internal/pycore_interp.h' line='68' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='head' type-id='type-id-177' visibility='default' filepath='./Include/internal/pycore_interp.h' line='70' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='count' type-id='type-id-47' visibility='default' filepath='./Include/internal/pycore_interp.h' line='72' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='stacksize' type-id='type-id-19' visibility='default' filepath='./Include/internal/pycore_interp.h' line='77' column='1'/> + </data-member> + </class-decl> + <class-decl name='_xidregitem' size-in-bits='256' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_interp.h' line='226' column='1' id='type-id-942'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='prev' type-id='type-id-943' visibility='default' filepath='./Include/internal/pycore_interp.h' line='227' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='next' type-id='type-id-943' visibility='default' filepath='./Include/internal/pycore_interp.h' line='228' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='cls' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_interp.h' line='229' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='getdata' type-id='type-id-787' visibility='default' filepath='./Include/internal/pycore_interp.h' line='230' column='1'/> + </data-member> + </class-decl> + <class-decl name='_Py_list_state' size-in-bits='5184' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_list.h' line='31' column='1' id='type-id-939'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='free_list' type-id='type-id-581' visibility='default' filepath='./Include/internal/pycore_list.h' line='33' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='5120'> + <var-decl name='numfree' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_list.h' line='34' column='1'/> + </data-member> + </class-decl> + <class-decl name='_py_object_runtime_state' size-in-bits='32' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_object_state.h' line='11' column='1' id='type-id-944'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='_not_used' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_object_state.h' line='15' column='1'/> + </data-member> + </class-decl> + <class-decl name='_py_object_state' size-in-bits='32' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_object_state.h' line='18' column='1' id='type-id-936'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='_not_used' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_object_state.h' line='29' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='pymem_uint' type-id='type-id-95' filepath='./Include/internal/pycore_obmalloc.h' line='12' column='1' id='type-id-945'/> + <typedef-decl name='pymem_block' type-id='type-id-325' filepath='./Include/internal/pycore_obmalloc.h' line='251' column='1' id='type-id-946'/> + <class-decl name='pool_header' size-in-bits='384' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_obmalloc.h' line='254' column='1' id='type-id-947'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='ref' type-id='type-id-948' visibility='default' filepath='./Include/internal/pycore_obmalloc.h' line='256' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='freeblock' type-id='type-id-949' visibility='default' filepath='./Include/internal/pycore_obmalloc.h' line='257' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='nextpool' type-id='type-id-950' visibility='default' filepath='./Include/internal/pycore_obmalloc.h' line='258' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='prevpool' type-id='type-id-950' visibility='default' filepath='./Include/internal/pycore_obmalloc.h' line='259' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='arenaindex' type-id='type-id-945' visibility='default' filepath='./Include/internal/pycore_obmalloc.h' line='260' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='288'> + <var-decl name='szidx' type-id='type-id-945' visibility='default' filepath='./Include/internal/pycore_obmalloc.h' line='261' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='nextoffset' type-id='type-id-945' visibility='default' filepath='./Include/internal/pycore_obmalloc.h' line='262' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='352'> + <var-decl name='maxnextoffset' type-id='type-id-945' visibility='default' filepath='./Include/internal/pycore_obmalloc.h' line='263' column='1'/> + </data-member> + </class-decl> + <union-decl name='__anonymous_union__3' size-in-bits='64' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_obmalloc.h' line='255' column='1' id='type-id-948'> + <data-member access='public'> + <var-decl name='_padding' type-id='type-id-949' visibility='default' filepath='./Include/internal/pycore_obmalloc.h' line='255' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='count' type-id='type-id-945' visibility='default' filepath='./Include/internal/pycore_obmalloc.h' line='256' column='1'/> + </data-member> + </union-decl> + <typedef-decl name='poolp' type-id='type-id-950' filepath='./Include/internal/pycore_obmalloc.h' line='266' column='1' id='type-id-637'/> + <class-decl name='arena_object' size-in-bits='384' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_obmalloc.h' line='269' column='1' id='type-id-951'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='address' type-id='type-id-749' visibility='default' filepath='./Include/internal/pycore_obmalloc.h' line='275' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='pool_address' type-id='type-id-949' visibility='default' filepath='./Include/internal/pycore_obmalloc.h' line='278' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='nfreepools' type-id='type-id-945' visibility='default' filepath='./Include/internal/pycore_obmalloc.h' line='283' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='160'> + <var-decl name='ntotalpools' type-id='type-id-945' visibility='default' filepath='./Include/internal/pycore_obmalloc.h' line='286' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='freepools' type-id='type-id-950' visibility='default' filepath='./Include/internal/pycore_obmalloc.h' line='289' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='nextarena' type-id='type-id-611' visibility='default' filepath='./Include/internal/pycore_obmalloc.h' line='305' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='prevarena' type-id='type-id-611' visibility='default' filepath='./Include/internal/pycore_obmalloc.h' line='306' column='1'/> + </data-member> + </class-decl> + <class-decl name='_obmalloc_pools' size-in-bits='4096' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_obmalloc.h' line='419' column='1' id='type-id-952'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='used' type-id='type-id-638' visibility='default' filepath='./Include/internal/pycore_obmalloc.h' line='420' column='1'/> + </data-member> + </class-decl> + <class-decl name='_obmalloc_mgmt' size-in-bits='4672' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_obmalloc.h' line='477' column='1' id='type-id-953'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='arenas' type-id='type-id-611' visibility='default' filepath='./Include/internal/pycore_obmalloc.h' line='479' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='maxarenas' type-id='type-id-945' visibility='default' filepath='./Include/internal/pycore_obmalloc.h' line='481' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='unused_arena_objects' type-id='type-id-611' visibility='default' filepath='./Include/internal/pycore_obmalloc.h' line='486' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='usable_arenas' type-id='type-id-611' visibility='default' filepath='./Include/internal/pycore_obmalloc.h' line='491' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='nfp2lasta' type-id='type-id-612' visibility='default' filepath='./Include/internal/pycore_obmalloc.h' line='494' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='4416'> + <var-decl name='narenas_currently_allocated' type-id='type-id-19' visibility='default' filepath='./Include/internal/pycore_obmalloc.h' line='497' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='4480'> + <var-decl name='ntimes_arena_allocated' type-id='type-id-19' visibility='default' filepath='./Include/internal/pycore_obmalloc.h' line='500' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='4544'> + <var-decl name='narenas_highwater' type-id='type-id-19' visibility='default' filepath='./Include/internal/pycore_obmalloc.h' line='502' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='4608'> + <var-decl name='raw_allocated_blocks' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_obmalloc.h' line='504' column='1'/> + </data-member> + </class-decl> + <class-decl name='arena_coverage_t' size-in-bits='64' is-struct='yes' naming-typedef-id='type-id-603' visibility='default' filepath='./Include/internal/pycore_obmalloc.h' line='619' column='1' id='type-id-954'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='tail_hi' type-id='type-id-955' visibility='default' filepath='./Include/internal/pycore_obmalloc.h' line='620' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='32'> + <var-decl name='tail_lo' type-id='type-id-955' visibility='default' filepath='./Include/internal/pycore_obmalloc.h' line='621' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='arena_coverage_t' type-id='type-id-954' filepath='./Include/internal/pycore_obmalloc.h' line='622' column='1' id='type-id-603'/> + <class-decl name='arena_map_bot' size-in-bits='1048576' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_obmalloc.h' line='624' column='1' id='type-id-956'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='arenas' type-id='type-id-604' visibility='default' filepath='./Include/internal/pycore_obmalloc.h' line='629' column='1'/> + </data-member> + </class-decl> + <class-decl name='arena_map_mid' size-in-bits='2097152' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_obmalloc.h' line='633' column='1' id='type-id-957'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='ptrs' type-id='type-id-607' visibility='default' filepath='./Include/internal/pycore_obmalloc.h' line='634' column='1'/> + </data-member> + </class-decl> + <class-decl name='arena_map_top' size-in-bits='2097152' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_obmalloc.h' line='637' column='1' id='type-id-958'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='ptrs' type-id='type-id-610' visibility='default' filepath='./Include/internal/pycore_obmalloc.h' line='638' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='arena_map_top_t' type-id='type-id-958' filepath='./Include/internal/pycore_obmalloc.h' line='639' column='1' id='type-id-959'/> + <class-decl name='_obmalloc_usage' size-in-bits='2097216' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_obmalloc.h' line='642' column='1' id='type-id-960'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='arena_map_root' type-id='type-id-959' visibility='default' filepath='./Include/internal/pycore_obmalloc.h' line='648' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2097152'> + <var-decl name='arena_map_mid_count' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_obmalloc.h' line='650' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2097184'> + <var-decl name='arena_map_bot_count' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_obmalloc.h' line='651' column='1'/> + </data-member> + </class-decl> + <class-decl name='_obmalloc_global_state' size-in-bits='128' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_obmalloc.h' line='660' column='1' id='type-id-961'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='dump_debug_stats' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_obmalloc.h' line='661' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='interpreter_leaks' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_obmalloc.h' line='662' column='1'/> + </data-member> + </class-decl> + <class-decl name='_obmalloc_state' size-in-bits='2105984' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_obmalloc.h' line='665' column='1' id='type-id-935'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='pools' type-id='type-id-952' visibility='default' filepath='./Include/internal/pycore_obmalloc.h' line='666' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='4096'> + <var-decl name='mgmt' type-id='type-id-953' visibility='default' filepath='./Include/internal/pycore_obmalloc.h' line='667' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='8768'> + <var-decl name='usage' type-id='type-id-960' visibility='default' filepath='./Include/internal/pycore_obmalloc.h' line='668' column='1'/> + </data-member> + </class-decl> + <class-decl name='_parser_runtime_state' size-in-bits='448' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_parser.h' line='21' column='1' id='type-id-962'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='_not_used' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_parser.h' line='25' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='dummy_name' type-id='type-id-963' visibility='default' filepath='./Include/internal/pycore_parser.h' line='27' column='1'/> + </data-member> + </class-decl> + <class-decl name='pyhash_runtime_state' size-in-bits='192' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_pyhash.h' line='9' column='1' id='type-id-964'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='urandom_cache' type-id='type-id-965' visibility='default' filepath='./Include/internal/pycore_pyhash.h' line='19' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__2' size-in-bits='192' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_pyhash.h' line='10' column='1' id='type-id-965'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='fd' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_pyhash.h' line='12' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='st_dev' type-id='type-id-966' visibility='default' filepath='./Include/internal/pycore_pyhash.h' line='13' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='st_ino' type-id='type-id-967' visibility='default' filepath='./Include/internal/pycore_pyhash.h' line='14' column='1'/> + </data-member> + </class-decl> + <class-decl name='debug_alloc_api_t' size-in-bits='384' is-struct='yes' naming-typedef-id='type-id-968' visibility='default' filepath='./Include/internal/pycore_pymem.h' line='14' column='1' id='type-id-969'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='api_id' type-id='type-id-48' visibility='default' filepath='./Include/internal/pycore_pymem.h' line='16' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='alloc' type-id='type-id-417' visibility='default' filepath='./Include/internal/pycore_pymem.h' line='17' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='debug_alloc_api_t' type-id='type-id-969' filepath='./Include/internal/pycore_pymem.h' line='18' column='1' id='type-id-968'/> + <class-decl name='_pymem_allocators' size-in-bits='2368' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_pymem.h' line='20' column='1' id='type-id-970'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='mutex' type-id='type-id-801' visibility='default' filepath='./Include/internal/pycore_pymem.h' line='21' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='standard' type-id='type-id-971' visibility='default' filepath='./Include/internal/pycore_pymem.h' line='26' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1024'> + <var-decl name='debug' type-id='type-id-972' visibility='default' filepath='./Include/internal/pycore_pymem.h' line='31' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2176'> + <var-decl name='obj_arena' type-id='type-id-420' visibility='default' filepath='./Include/internal/pycore_pymem.h' line='32' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__' size-in-bits='960' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_pymem.h' line='22' column='1' id='type-id-971'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='raw' type-id='type-id-417' visibility='default' filepath='./Include/internal/pycore_pymem.h' line='23' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='mem' type-id='type-id-417' visibility='default' filepath='./Include/internal/pycore_pymem.h' line='24' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='640'> + <var-decl name='obj' type-id='type-id-417' visibility='default' filepath='./Include/internal/pycore_pymem.h' line='25' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__1' size-in-bits='1152' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_pymem.h' line='27' column='1' id='type-id-972'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='raw' type-id='type-id-968' visibility='default' filepath='./Include/internal/pycore_pymem.h' line='28' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='384'> + <var-decl name='mem' type-id='type-id-968' visibility='default' filepath='./Include/internal/pycore_pymem.h' line='29' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='768'> + <var-decl name='obj' type-id='type-id-968' visibility='default' filepath='./Include/internal/pycore_pymem.h' line='30' column='1'/> + </data-member> + </class-decl> + <class-decl name='_pythread_runtime_state' size-in-bits='192' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_pythread.h' line='54' column='1' id='type-id-973'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='initialized' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_pythread.h' line='55' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='_condattr_monotonic' type-id='type-id-974' visibility='default' filepath='./Include/internal/pycore_pythread.h' line='66' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__3' size-in-bits='128' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_pythread.h' line='59' column='1' id='type-id-974'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='ptr' type-id='type-id-975' visibility='default' filepath='./Include/internal/pycore_pythread.h' line='61' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='val' type-id='type-id-976' visibility='default' filepath='./Include/internal/pycore_pythread.h' line='64' column='1'/> + </data-member> + </class-decl> + <class-decl name='_getargs_runtime_state' size-in-bits='128' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='30' column='1' id='type-id-977'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='mutex' type-id='type-id-801' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='31' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='static_parsers' type-id='type-id-262' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='32' column='1'/> + </data-member> + </class-decl> + <class-decl name='_gilstate_runtime_state' size-in-bits='128' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='37' column='1' id='type-id-978'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='check_enabled' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='40' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='autoInterpreterState' type-id='type-id-20' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='45' column='1'/> + </data-member> + </class-decl> + <class-decl name='_Py_AuditHookEntry' size-in-bits='192' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='50' column='1' id='type-id-979'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='next' type-id='type-id-980' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='51' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='hookCFunction' type-id='type-id-234' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='52' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='userData' type-id='type-id-22' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='53' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='_Py_AuditHookEntry' type-id='type-id-979' filepath='./Include/internal/pycore_runtime.h' line='54' column='1' id='type-id-981'/> + <class-decl name='pyruntimestate' size-in-bits='3679104' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='61' column='1' id='type-id-982'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='_initialized' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='66' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='32'> + <var-decl name='preinitializing' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='69' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='preinitialized' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='72' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='96'> + <var-decl name='core_initialized' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='75' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='initialized' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='78' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='_finalizing' type-id='type-id-810' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='85' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='interpreters' type-id='type-id-983' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='104' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='512'> + <var-decl name='main_thread' type-id='type-id-28' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='106' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='576'> + <var-decl name='xidregistry' type-id='type-id-984' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='117' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='704'> + <var-decl name='allocators' type-id='type-id-970' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='119' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='3072'> + <var-decl name='obmalloc' type-id='type-id-961' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='120' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='3200'> + <var-decl name='pyhash_state' type-id='type-id-964' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='121' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='3392'> + <var-decl name='time' type-id='type-id-985' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='122' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='3520'> + <var-decl name='threads' type-id='type-id-973' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='123' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='3712'> + <var-decl name='signals' type-id='type-id-986' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='124' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='12352'> + <var-decl name='autoTSSkey' type-id='type-id-408' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='127' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='12416'> + <var-decl name='trashTSSkey' type-id='type-id-408' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='130' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='12480'> + <var-decl name='orig_argv' type-id='type-id-741' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='132' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='12608'> + <var-decl name='parser' type-id='type-id-962' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='134' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='13056'> + <var-decl name='atexit' type-id='type-id-800' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='136' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='15232'> + <var-decl name='imports' type-id='type-id-923' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='138' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='15552'> + <var-decl name='ceval' type-id='type-id-820' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='139' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='20480'> + <var-decl name='gilstate' type-id='type-id-978' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='140' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='20608'> + <var-decl name='getargs' type-id='type-id-977' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='141' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='20736'> + <var-decl name='fileutils' type-id='type-id-843' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='142' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='20800'> + <var-decl name='faulthandler' type-id='type-id-839' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='143' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='22144'> + <var-decl name='tracemalloc' type-id='type-id-987' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='144' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='24000'> + <var-decl name='preconfig' type-id='type-id-744' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='146' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='24320'> + <var-decl name='open_code_hook' type-id='type-id-355' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='150' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='24384'> + <var-decl name='open_code_userdata' type-id='type-id-22' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='151' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='24448'> + <var-decl name='audit_hooks' type-id='type-id-988' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='155' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='24576'> + <var-decl name='object_state' type-id='type-id-944' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='157' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='24608'> + <var-decl name='float_state' type-id='type-id-846' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='158' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='24704'> + <var-decl name='unicode_state' type-id='type-id-989' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='159' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='24832'> + <var-decl name='types' type-id='type-id-990' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='160' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='24896'> + <var-decl name='static_objects' type-id='type-id-860' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='163' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='610944'> + <var-decl name='_main_interpreter' type-id='type-id-991' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='180' column='1'/> + </data-member> + </class-decl> + <class-decl name='pyinterpreters' size-in-bits='256' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='87' column='1' id='type-id-983'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='mutex' type-id='type-id-801' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='88' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='head' type-id='type-id-20' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='90' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='main' type-id='type-id-20' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='94' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='next_id' type-id='type-id-377' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='103' column='1'/> + </data-member> + </class-decl> + <class-decl name='_xidregistry' size-in-bits='128' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='114' column='1' id='type-id-984'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='mutex' type-id='type-id-801' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='115' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='head' type-id='type-id-943' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='116' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__19' size-in-bits='128' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='152' column='1' id='type-id-988'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='mutex' type-id='type-id-801' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='153' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='head' type-id='type-id-980' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='154' column='1'/> + </data-member> + </class-decl> + <class-decl name='_signals_runtime_state' size-in-bits='8640' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_signal.h' line='37' column='1' id='type-id-986'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='handlers' type-id='type-id-699' visibility='default' filepath='./Include/internal/pycore_signal.h' line='44' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='8320'> + <var-decl name='wakeup' type-id='type-id-992' visibility='default' filepath='./Include/internal/pycore_signal.h' line='61' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='8384'> + <var-decl name='is_tripped' type-id='type-id-812' visibility='default' filepath='./Include/internal/pycore_signal.h' line='64' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='8448'> + <var-decl name='default_handler' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_signal.h' line='67' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='8512'> + <var-decl name='ignore_handler' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_signal.h' line='68' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='8576'> + <var-decl name='unhandled_keyboard_interrupt' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_signal.h' line='78' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__4' size-in-bits='128' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_signal.h' line='38' column='1' id='type-id-993'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='tripped' type-id='type-id-812' visibility='default' filepath='./Include/internal/pycore_signal.h' line='39' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='func' type-id='type-id-810' visibility='default' filepath='./Include/internal/pycore_signal.h' line='43' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__5' size-in-bits='64' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_signal.h' line='46' column='1' id='type-id-994'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='fd' type-id='type-id-995' visibility='default' filepath='./Include/internal/pycore_signal.h' line='54' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='32'> + <var-decl name='warn_on_full_buffer' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_signal.h' line='57' column='1'/> + </data-member> + </class-decl> + <class-decl name='_time_runtime_state' size-in-bits='128' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_time.h' line='12' column='1' id='type-id-985'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='ticks_per_second_initialized' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_time.h' line='14' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='ticks_per_second' type-id='type-id-47' visibility='default' filepath='./Include/internal/pycore_time.h' line='15' column='1'/> + </data-member> + </class-decl> + <class-decl name='_PyTraceMalloc_Config' size-in-bits='96' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_tracemalloc.h' line='18' column='1' id='type-id-996'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='initialized' type-id='type-id-997' visibility='default' filepath='./Include/internal/pycore_tracemalloc.h' line='25' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='32'> + <var-decl name='tracing' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_tracemalloc.h' line='29' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='max_nframe' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_tracemalloc.h' line='33' column='1'/> + </data-member> + </class-decl> + <enum-decl name='__anonymous_enum__' is-anonymous='yes' filepath='./Include/internal/pycore_tracemalloc.h' line='21' column='1' id='type-id-997'> + <underlying-type type-id='type-id-24'/> + <enumerator name='TRACEMALLOC_NOT_INITIALIZED' value='0'/> + <enumerator name='TRACEMALLOC_INITIALIZED' value='1'/> + <enumerator name='TRACEMALLOC_FINALIZED' value='2'/> + </enum-decl> + <class-decl name='tracemalloc_frame' size-in-bits='96' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_tracemalloc.h' line='47' column='1' id='type-id-645'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='filename' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_tracemalloc.h' line='50' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='lineno' type-id='type-id-95' visibility='default' filepath='./Include/internal/pycore_tracemalloc.h' line='51' column='1'/> + </data-member> + </class-decl> + <class-decl name='tracemalloc_traceback' size-in-bits='192' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_tracemalloc.h' line='57' column='1' id='type-id-998'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='hash' type-id='type-id-910' visibility='default' filepath='./Include/internal/pycore_tracemalloc.h' line='58' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='nframe' type-id='type-id-709' visibility='default' filepath='./Include/internal/pycore_tracemalloc.h' line='60' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='80'> + <var-decl name='total_nframe' type-id='type-id-709' visibility='default' filepath='./Include/internal/pycore_tracemalloc.h' line='62' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='96'> + <var-decl name='frames' type-id='type-id-646' visibility='default' filepath='./Include/internal/pycore_tracemalloc.h' line='63' column='1'/> + </data-member> + </class-decl> + <class-decl name='_tracemalloc_runtime_state' size-in-bits='1856' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_tracemalloc.h' line='67' column='1' id='type-id-987'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='config' type-id='type-id-996' visibility='default' filepath='./Include/internal/pycore_tracemalloc.h' line='68' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='allocators' type-id='type-id-999' visibility='default' filepath='./Include/internal/pycore_tracemalloc.h' line='75' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1088'> + <var-decl name='tables_lock' type-id='type-id-801' visibility='default' filepath='./Include/internal/pycore_tracemalloc.h' line='78' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1152'> + <var-decl name='traced_memory' type-id='type-id-19' visibility='default' filepath='./Include/internal/pycore_tracemalloc.h' line='82' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1216'> + <var-decl name='peak_traced_memory' type-id='type-id-19' visibility='default' filepath='./Include/internal/pycore_tracemalloc.h' line='85' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1280'> + <var-decl name='filenames' type-id='type-id-926' visibility='default' filepath='./Include/internal/pycore_tracemalloc.h' line='89' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1344'> + <var-decl name='traceback' type-id='type-id-1000' visibility='default' filepath='./Include/internal/pycore_tracemalloc.h' line='92' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1408'> + <var-decl name='tracebacks' type-id='type-id-926' visibility='default' filepath='./Include/internal/pycore_tracemalloc.h' line='96' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1472'> + <var-decl name='traces' type-id='type-id-926' visibility='default' filepath='./Include/internal/pycore_tracemalloc.h' line='99' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1536'> + <var-decl name='domains' type-id='type-id-926' visibility='default' filepath='./Include/internal/pycore_tracemalloc.h' line='102' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1600'> + <var-decl name='empty_traceback' type-id='type-id-998' visibility='default' filepath='./Include/internal/pycore_tracemalloc.h' line='104' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1792'> + <var-decl name='reentrant_key' type-id='type-id-408' visibility='default' filepath='./Include/internal/pycore_tracemalloc.h' line='106' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__18' size-in-bits='960' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_tracemalloc.h' line='71' column='1' id='type-id-999'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='mem' type-id='type-id-417' visibility='default' filepath='./Include/internal/pycore_tracemalloc.h' line='72' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='raw' type-id='type-id-417' visibility='default' filepath='./Include/internal/pycore_tracemalloc.h' line='73' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='640'> + <var-decl name='obj' type-id='type-id-417' visibility='default' filepath='./Include/internal/pycore_tracemalloc.h' line='74' column='1'/> + </data-member> + </class-decl> + <class-decl name='_Py_tuple_state' size-in-bits='1920' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_tuple.h' line='47' column='1' id='type-id-938'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='free_list' type-id='type-id-588' visibility='default' filepath='./Include/internal/pycore_tuple.h' line='57' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1280'> + <var-decl name='numfree' type-id='type-id-634' visibility='default' filepath='./Include/internal/pycore_tuple.h' line='58' column='1'/> + </data-member> + </class-decl> + <class-decl name='_types_runtime_state' size-in-bits='32' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_typeobject.h' line='19' column='1' id='type-id-990'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='next_version_tag' type-id='type-id-95' visibility='default' filepath='./Include/internal/pycore_typeobject.h' line='23' column='1'/> + </data-member> + </class-decl> + <class-decl name='type_cache_entry' size-in-bits='192' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_typeobject.h' line='29' column='1' id='type-id-647'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='version' type-id='type-id-95' visibility='default' filepath='./Include/internal/pycore_typeobject.h' line='30' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='name' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_typeobject.h' line='31' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='value' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_typeobject.h' line='32' column='1'/> + </data-member> + </class-decl> + <class-decl name='type_cache' size-in-bits='786432' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_typeobject.h' line='37' column='1' id='type-id-1001'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='hashtable' type-id='type-id-648' visibility='default' filepath='./Include/internal/pycore_typeobject.h' line='38' column='1'/> + </data-member> + </class-decl> + <class-decl name='static_builtin_state' size-in-bits='320' is-struct='yes' naming-typedef-id='type-id-410' visibility='default' filepath='./Include/internal/pycore_typeobject.h' line='45' column='1' id='type-id-1002'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='type' type-id='type-id-1' visibility='default' filepath='./Include/internal/pycore_typeobject.h' line='46' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='readying' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_typeobject.h' line='47' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='96'> + <var-decl name='ready' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_typeobject.h' line='48' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='tp_dict' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_typeobject.h' line='51' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='tp_subclasses' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_typeobject.h' line='52' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='tp_weaklist' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_typeobject.h' line='57' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='static_builtin_state' type-id='type-id-1002' filepath='./Include/internal/pycore_typeobject.h' line='58' column='1' id='type-id-410'/> + <class-decl name='types_state' size-in-bits='850560' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_typeobject.h' line='60' column='1' id='type-id-940'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='next_version_tag' type-id='type-id-95' visibility='default' filepath='./Include/internal/pycore_typeobject.h' line='64' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='type_cache' type-id='type-id-1001' visibility='default' filepath='./Include/internal/pycore_typeobject.h' line='66' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='786496'> + <var-decl name='num_builtins_initialized' type-id='type-id-19' visibility='default' filepath='./Include/internal/pycore_typeobject.h' line='67' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='786560'> + <var-decl name='builtins' type-id='type-id-643' visibility='default' filepath='./Include/internal/pycore_typeobject.h' line='68' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='pytype_slotdef' type-id='type-id-333' filepath='./Include/internal/pycore_typeobject.h' line='87' column='1' id='type-id-1003'/> + <class-decl name='_PyUnicode_Name_CAPI' size-in-bits='128' is-struct='yes' naming-typedef-id='type-id-1004' visibility='default' filepath='./Include/internal/pycore_ucnhash.h' line='16' column='1' id='type-id-1005'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='getname' type-id='type-id-1006' visibility='default' filepath='./Include/internal/pycore_ucnhash.h' line='21' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='getcode' type-id='type-id-1007' visibility='default' filepath='./Include/internal/pycore_ucnhash.h' line='26' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='_PyUnicode_Name_CAPI' type-id='type-id-1005' filepath='./Include/internal/pycore_ucnhash.h' line='29' column='1' id='type-id-1004'/> + <class-decl name='_Py_unicode_runtime_ids' size-in-bits='128' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_unicodeobject.h' line='29' column='1' id='type-id-1008'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='lock' type-id='type-id-801' visibility='default' filepath='./Include/internal/pycore_unicodeobject.h' line='30' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='next_index' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_unicodeobject.h' line='33' column='1'/> + </data-member> + </class-decl> + <class-decl name='_Py_unicode_runtime_state' size-in-bits='128' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_unicodeobject.h' line='36' column='1' id='type-id-989'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='ids' type-id='type-id-1008' visibility='default' filepath='./Include/internal/pycore_unicodeobject.h' line='37' column='1'/> + </data-member> + </class-decl> + <class-decl name='_Py_unicode_fs_codec' size-in-bits='256' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_unicodeobject.h' line='42' column='1' id='type-id-1009'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='encoding' type-id='type-id-15' visibility='default' filepath='./Include/internal/pycore_unicodeobject.h' line='43' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='utf8' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_unicodeobject.h' line='44' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='errors' type-id='type-id-15' visibility='default' filepath='./Include/internal/pycore_unicodeobject.h' line='45' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='error_handler' type-id='type-id-442' visibility='default' filepath='./Include/internal/pycore_unicodeobject.h' line='46' column='1'/> + </data-member> + </class-decl> + <class-decl name='_Py_unicode_ids' size-in-bits='128' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_unicodeobject.h' line='49' column='1' id='type-id-1010'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='size' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_unicodeobject.h' line='50' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='array' type-id='type-id-233' visibility='default' filepath='./Include/internal/pycore_unicodeobject.h' line='51' column='1'/> + </data-member> + </class-decl> + <class-decl name='_Py_unicode_state' size-in-bits='448' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_unicodeobject.h' line='54' column='1' id='type-id-937'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='fs_codec' type-id='type-id-1009' visibility='default' filepath='./Include/internal/pycore_unicodeobject.h' line='55' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='ucnhash_capi' type-id='type-id-1011' visibility='default' filepath='./Include/internal/pycore_unicodeobject.h' line='57' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='ids' type-id='type-id-1010' visibility='default' filepath='./Include/internal/pycore_unicodeobject.h' line='60' column='1'/> + </data-member> + </class-decl> + <class-decl name='_warnings_runtime_state' size-in-bits='256' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_warnings.h' line='11' column='1' id='type-id-934'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='filters' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_warnings.h' line='14' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='once_registry' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_warnings.h' line='15' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='default_action' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_warnings.h' line='16' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='filters_version' type-id='type-id-47' visibility='default' filepath='./Include/internal/pycore_warnings.h' line='17' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='Py_uhash_t' type-id='type-id-19' filepath='./Include/pyport.h' line='148' column='1' id='type-id-910'/> + <typedef-decl name='PyThread_type_lock' type-id='type-id-22' filepath='./Include/pythread.h' line='4' column='1' id='type-id-801'/> + <typedef-decl name='Py_tss_t' type-id='type-id-788' filepath='./Include/pythread.h' line='113' column='1' id='type-id-408'/> + <typedef-decl name='PyLongObject' type-id='type-id-751' filepath='./Include/pytypedefs.h' line='19' column='1' id='type-id-240'/> + <typedef-decl name='PyCodeObject' type-id='type-id-719' filepath='./Include/pytypedefs.h' line='21' column='1' id='type-id-1012'/> + <typedef-decl name='PyFrameObject' type-id='type-id-849' filepath='./Include/pytypedefs.h' line='22' column='1' id='type-id-1013'/> + <typedef-decl name='PyThreadState' type-id='type-id-776' filepath='./Include/pytypedefs.h' line='24' column='1' id='type-id-941'/> + <typedef-decl name='PyInterpreterState' type-id='type-id-931' filepath='./Include/pytypedefs.h' line='25' column='1' id='type-id-991'/> + <class-decl name='PySliceObject' size-in-bits='320' is-struct='yes' naming-typedef-id='type-id-1014' visibility='default' filepath='./Include/sliceobject.h' line='22' column='1' id='type-id-1015'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='ob_base' type-id='type-id-345' visibility='default' filepath='./Include/sliceobject.h' line='23' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='start' type-id='type-id-2' visibility='default' filepath='./Include/sliceobject.h' line='24' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='stop' type-id='type-id-2' visibility='default' filepath='./Include/sliceobject.h' line='24' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='step' type-id='type-id-2' visibility='default' filepath='./Include/sliceobject.h' line='24' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='PySliceObject' type-id='type-id-1015' filepath='./Include/sliceobject.h' line='25' column='1' id='type-id-1014'/> + <typedef-decl name='__sighandler_t' type-id='type-id-1016' filepath='/usr/include/signal.h' line='72' column='1' id='type-id-1017'/> + <typedef-decl name='uintptr_t' type-id='type-id-28' filepath='/usr/include/stdint.h' line='90' column='1' id='type-id-749'/> + <union-decl name='__atomic_wide_counter' size-in-bits='64' naming-typedef-id='type-id-1018' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/atomic_wide_counter.h' line='25' column='1' id='type-id-1019'> + <data-member access='public'> + <var-decl name='__value64' type-id='type-id-387' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/atomic_wide_counter.h' line='27' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='__value32' type-id='type-id-1020' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/atomic_wide_counter.h' line='32' column='1'/> + </data-member> + </union-decl> + <class-decl name='__anonymous_struct__744' size-in-bits='64' is-struct='yes' is-anonymous='yes' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/atomic_wide_counter.h' line='28' column='1' id='type-id-1020'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='__low' type-id='type-id-95' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/atomic_wide_counter.h' line='30' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='32'> + <var-decl name='__high' type-id='type-id-95' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/atomic_wide_counter.h' line='31' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='__atomic_wide_counter' type-id='type-id-1019' filepath='/usr/include/x86_64-linux-gnu/bits/atomic_wide_counter.h' line='33' column='1' id='type-id-1018'/> + <union-decl name='pthread_condattr_t' size-in-bits='32' naming-typedef-id='type-id-976' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h' line='41' column='1' id='type-id-1021'> + <data-member access='public'> + <var-decl name='__size' type-id='type-id-620' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h' line='43' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='__align' type-id='type-id-8' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h' line='44' column='1'/> + </data-member> + </union-decl> + <typedef-decl name='pthread_condattr_t' type-id='type-id-1021' filepath='/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h' line='45' column='1' id='type-id-976'/> + <typedef-decl name='pthread_key_t' type-id='type-id-95' filepath='/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h' line='49' column='1' id='type-id-789'/> + <union-decl name='pthread_mutex_t' size-in-bits='320' naming-typedef-id='type-id-859' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h' line='67' column='1' id='type-id-1022'> + <data-member access='public'> + <var-decl name='__data' type-id='type-id-1023' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h' line='69' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='__size' type-id='type-id-616' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h' line='70' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='__align' type-id='type-id-47' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h' line='71' column='1'/> + </data-member> + </union-decl> + <typedef-decl name='pthread_mutex_t' type-id='type-id-1022' filepath='/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h' line='72' column='1' id='type-id-859'/> + <union-decl name='pthread_cond_t' size-in-bits='384' naming-typedef-id='type-id-858' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h' line='75' column='1' id='type-id-1024'> + <data-member access='public'> + <var-decl name='__data' type-id='type-id-1025' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h' line='77' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='__size' type-id='type-id-618' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h' line='78' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='__align' type-id='type-id-378' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h' line='79' column='1'/> + </data-member> + </union-decl> + <typedef-decl name='pthread_cond_t' type-id='type-id-1024' filepath='/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h' line='80' column='1' id='type-id-858'/> + <class-decl name='sigaction' size-in-bits='1216' is-struct='yes' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/sigaction.h' line='27' column='1' id='type-id-836'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='__sigaction_handler' type-id='type-id-1026' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/sigaction.h' line='38' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='sa_mask' type-id='type-id-30' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/sigaction.h' line='46' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1088'> + <var-decl name='sa_flags' type-id='type-id-8' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/sigaction.h' line='49' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1152'> + <var-decl name='sa_restorer' type-id='type-id-227' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/sigaction.h' line='52' column='1'/> + </data-member> + </class-decl> + <union-decl name='__anonymous_union__' size-in-bits='64' is-anonymous='yes' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/sigaction.h' line='31' column='1' id='type-id-1026'> + <data-member access='public'> + <var-decl name='sa_handler' type-id='type-id-1017' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/sigaction.h' line='34' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='sa_sigaction' type-id='type-id-1027' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/sigaction.h' line='36' column='1'/> + </data-member> + </union-decl> + <typedef-decl name='int8_t' type-id='type-id-1028' filepath='/usr/include/x86_64-linux-gnu/bits/stdint-intn.h' line='24' column='1' id='type-id-370'/> + <typedef-decl name='int32_t' type-id='type-id-1029' filepath='/usr/include/x86_64-linux-gnu/bits/stdint-intn.h' line='26' column='1' id='type-id-955'/> + <typedef-decl name='int64_t' type-id='type-id-1030' filepath='/usr/include/x86_64-linux-gnu/bits/stdint-intn.h' line='27' column='1' id='type-id-377'/> + <typedef-decl name='uint8_t' type-id='type-id-1031' filepath='/usr/include/x86_64-linux-gnu/bits/stdint-uintn.h' line='24' column='1' id='type-id-325'/> + <typedef-decl name='uint16_t' type-id='type-id-1032' filepath='/usr/include/x86_64-linux-gnu/bits/stdint-uintn.h' line='25' column='1' id='type-id-709'/> + <typedef-decl name='uint64_t' type-id='type-id-1033' filepath='/usr/include/x86_64-linux-gnu/bits/stdint-uintn.h' line='27' column='1' id='type-id-117'/> + <class-decl name='__pthread_mutex_s' size-in-bits='320' is-struct='yes' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/struct_mutex.h' line='22' column='1' id='type-id-1023'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='__lock' type-id='type-id-8' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/struct_mutex.h' line='24' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='32'> + <var-decl name='__count' type-id='type-id-95' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/struct_mutex.h' line='25' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='__owner' type-id='type-id-8' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/struct_mutex.h' line='26' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='96'> + <var-decl name='__nusers' type-id='type-id-95' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/struct_mutex.h' line='28' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='__kind' type-id='type-id-8' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/struct_mutex.h' line='32' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='160'> + <var-decl name='__spins' type-id='type-id-71' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/struct_mutex.h' line='34' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='176'> + <var-decl name='__elision' type-id='type-id-71' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/struct_mutex.h' line='35' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='__list' type-id='type-id-1034' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/struct_mutex.h' line='36' column='1'/> + </data-member> + </class-decl> + <class-decl name='__pthread_internal_list' size-in-bits='128' is-struct='yes' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/thread-shared-types.h' line='51' column='1' id='type-id-1035'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='__prev' type-id='type-id-1036' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/thread-shared-types.h' line='53' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='__next' type-id='type-id-1036' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/thread-shared-types.h' line='54' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='__pthread_list_t' type-id='type-id-1035' filepath='/usr/include/x86_64-linux-gnu/bits/thread-shared-types.h' line='55' column='1' id='type-id-1034'/> + <class-decl name='__pthread_cond_s' size-in-bits='384' is-struct='yes' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/thread-shared-types.h' line='94' column='1' id='type-id-1025'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='__wseq' type-id='type-id-1018' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/thread-shared-types.h' line='96' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='__g1_start' type-id='type-id-1018' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/thread-shared-types.h' line='97' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='__g_refs' type-id='type-id-696' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/thread-shared-types.h' line='98' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='__g_size' type-id='type-id-696' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/thread-shared-types.h' line='99' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='__g1_orig_size' type-id='type-id-95' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/thread-shared-types.h' line='100' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='288'> + <var-decl name='__wrefs' type-id='type-id-95' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/thread-shared-types.h' line='101' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='__g_signals' type-id='type-id-696' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/thread-shared-types.h' line='102' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='__int8_t' type-id='type-id-1037' filepath='/usr/include/x86_64-linux-gnu/bits/types.h' line='37' column='1' id='type-id-1028'/> + <typedef-decl name='__uint8_t' type-id='type-id-85' filepath='/usr/include/x86_64-linux-gnu/bits/types.h' line='38' column='1' id='type-id-1031'/> + <typedef-decl name='__uint16_t' type-id='type-id-84' filepath='/usr/include/x86_64-linux-gnu/bits/types.h' line='40' column='1' id='type-id-1032'/> + <typedef-decl name='__int32_t' type-id='type-id-8' filepath='/usr/include/x86_64-linux-gnu/bits/types.h' line='41' column='1' id='type-id-1029'/> + <typedef-decl name='__int64_t' type-id='type-id-47' filepath='/usr/include/x86_64-linux-gnu/bits/types.h' line='44' column='1' id='type-id-1030'/> + <typedef-decl name='__uint64_t' type-id='type-id-28' filepath='/usr/include/x86_64-linux-gnu/bits/types.h' line='45' column='1' id='type-id-1033'/> + <typedef-decl name='__dev_t' type-id='type-id-28' filepath='/usr/include/x86_64-linux-gnu/bits/types.h' line='145' column='1' id='type-id-187'/> + <typedef-decl name='__uid_t' type-id='type-id-95' filepath='/usr/include/x86_64-linux-gnu/bits/types.h' line='146' column='1' id='type-id-125'/> + <typedef-decl name='__ino64_t' type-id='type-id-28' filepath='/usr/include/x86_64-linux-gnu/bits/types.h' line='149' column='1' id='type-id-83'/> + <typedef-decl name='__pid_t' type-id='type-id-8' filepath='/usr/include/x86_64-linux-gnu/bits/types.h' line='154' column='1' id='type-id-127'/> + <typedef-decl name='__clock_t' type-id='type-id-47' filepath='/usr/include/x86_64-linux-gnu/bits/types.h' line='156' column='1' id='type-id-97'/> + <typedef-decl name='__sig_atomic_t' type-id='type-id-8' filepath='/usr/include/x86_64-linux-gnu/bits/types.h' line='215' column='1' id='type-id-1038'/> + <class-decl name='__sigset_t' size-in-bits='1024' is-struct='yes' naming-typedef-id='type-id-30' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h' line='5' column='1' id='type-id-1039'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='__val' type-id='type-id-697' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h' line='7' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='__sigset_t' type-id='type-id-1039' filepath='/usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h' line='8' column='1' id='type-id-30'/> + <union-decl name='sigval' size-in-bits='64' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/__sigval_t.h' line='24' column='1' id='type-id-1040'> + <data-member access='public'> + <var-decl name='sival_int' type-id='type-id-8' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/__sigval_t.h' line='26' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='sival_ptr' type-id='type-id-22' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/__sigval_t.h' line='27' column='1'/> + </data-member> + </union-decl> + <typedef-decl name='__sigval_t' type-id='type-id-1040' filepath='/usr/include/x86_64-linux-gnu/bits/types/__sigval_t.h' line='30' column='1' id='type-id-1041'/> + <typedef-decl name='sig_atomic_t' type-id='type-id-1038' filepath='/usr/include/x86_64-linux-gnu/bits/types/sig_atomic_t.h' line='8' column='1' id='type-id-995'/> + <class-decl name='siginfo_t' size-in-bits='1024' is-struct='yes' naming-typedef-id='type-id-1042' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/siginfo_t.h' line='36' column='1' id='type-id-1043'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='si_signo' type-id='type-id-8' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/siginfo_t.h' line='38' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='32'> + <var-decl name='si_errno' type-id='type-id-8' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/siginfo_t.h' line='40' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='si_code' type-id='type-id-8' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/siginfo_t.h' line='42' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='96'> + <var-decl name='__pad0' type-id='type-id-8' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/siginfo_t.h' line='48' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='_sifields' type-id='type-id-1044' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/siginfo_t.h' line='123' column='1'/> + </data-member> + </class-decl> + <union-decl name='__anonymous_union__1' size-in-bits='896' is-anonymous='yes' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/siginfo_t.h' line='51' column='1' id='type-id-1044'> + <data-member access='public'> + <var-decl name='_pad' type-id='type-id-635' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/siginfo_t.h' line='53' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='_kill' type-id='type-id-1045' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/siginfo_t.h' line='60' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='_timer' type-id='type-id-1046' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/siginfo_t.h' line='68' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='_rt' type-id='type-id-1047' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/siginfo_t.h' line='76' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='_sigchld' type-id='type-id-1048' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/siginfo_t.h' line='86' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='_sigfault' type-id='type-id-1049' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/siginfo_t.h' line='105' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='_sigpoll' type-id='type-id-1050' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/siginfo_t.h' line='112' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='_sigsys' type-id='type-id-1051' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/siginfo_t.h' line='121' column='1'/> + </data-member> + </union-decl> + <class-decl name='__anonymous_struct__11' size-in-bits='64' is-struct='yes' is-anonymous='yes' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/siginfo_t.h' line='56' column='1' id='type-id-1045'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='si_pid' type-id='type-id-127' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/siginfo_t.h' line='58' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='32'> + <var-decl name='si_uid' type-id='type-id-125' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/siginfo_t.h' line='59' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__12' size-in-bits='128' is-struct='yes' is-anonymous='yes' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/siginfo_t.h' line='63' column='1' id='type-id-1046'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='si_tid' type-id='type-id-8' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/siginfo_t.h' line='65' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='32'> + <var-decl name='si_overrun' type-id='type-id-8' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/siginfo_t.h' line='66' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='si_sigval' type-id='type-id-1041' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/siginfo_t.h' line='67' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__13' size-in-bits='128' is-struct='yes' is-anonymous='yes' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/siginfo_t.h' line='71' column='1' id='type-id-1047'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='si_pid' type-id='type-id-127' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/siginfo_t.h' line='73' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='32'> + <var-decl name='si_uid' type-id='type-id-125' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/siginfo_t.h' line='74' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='si_sigval' type-id='type-id-1041' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/siginfo_t.h' line='75' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__14' size-in-bits='256' is-struct='yes' is-anonymous='yes' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/siginfo_t.h' line='79' column='1' id='type-id-1048'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='si_pid' type-id='type-id-127' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/siginfo_t.h' line='81' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='32'> + <var-decl name='si_uid' type-id='type-id-125' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/siginfo_t.h' line='82' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='si_status' type-id='type-id-8' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/siginfo_t.h' line='83' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='si_utime' type-id='type-id-97' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/siginfo_t.h' line='84' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='si_stime' type-id='type-id-97' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/siginfo_t.h' line='85' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__15' size-in-bits='256' is-struct='yes' is-anonymous='yes' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/siginfo_t.h' line='89' column='1' id='type-id-1049'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='si_addr' type-id='type-id-22' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/siginfo_t.h' line='91' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='si_addr_lsb' type-id='type-id-71' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/siginfo_t.h' line='93' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='_bounds' type-id='type-id-1052' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/siginfo_t.h' line='104' column='1'/> + </data-member> + </class-decl> + <union-decl name='__anonymous_union__2' size-in-bits='128' is-anonymous='yes' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/siginfo_t.h' line='94' column='1' id='type-id-1052'> + <data-member access='public'> + <var-decl name='_addr_bnd' type-id='type-id-1053' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/siginfo_t.h' line='101' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='_pkey' type-id='type-id-1054' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/siginfo_t.h' line='103' column='1'/> + </data-member> + </union-decl> + <class-decl name='__anonymous_struct__16' size-in-bits='128' is-struct='yes' is-anonymous='yes' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/siginfo_t.h' line='97' column='1' id='type-id-1053'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='_lower' type-id='type-id-22' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/siginfo_t.h' line='99' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='_upper' type-id='type-id-22' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/siginfo_t.h' line='100' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__17' size-in-bits='128' is-struct='yes' is-anonymous='yes' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/siginfo_t.h' line='108' column='1' id='type-id-1050'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='si_band' type-id='type-id-47' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/siginfo_t.h' line='110' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='si_fd' type-id='type-id-8' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/siginfo_t.h' line='111' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__18' size-in-bits='128' is-struct='yes' is-anonymous='yes' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/siginfo_t.h' line='116' column='1' id='type-id-1051'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='_call_addr' type-id='type-id-22' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/siginfo_t.h' line='118' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='_syscall' type-id='type-id-8' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/siginfo_t.h' line='119' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='96'> + <var-decl name='_arch' type-id='type-id-95' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/siginfo_t.h' line='120' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='siginfo_t' type-id='type-id-1043' filepath='/usr/include/x86_64-linux-gnu/bits/types/siginfo_t.h' line='124' column='1' id='type-id-1042'/> + <class-decl name='stack_t' size-in-bits='192' is-struct='yes' naming-typedef-id='type-id-38' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/stack_t.h' line='26' column='1' id='type-id-1055'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='ss_sp' type-id='type-id-22' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/stack_t.h' line='28' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='ss_flags' type-id='type-id-8' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/stack_t.h' line='29' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='ss_size' type-id='type-id-19' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/stack_t.h' line='30' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='stack_t' type-id='type-id-1055' filepath='/usr/include/x86_64-linux-gnu/bits/types/stack_t.h' line='31' column='1' id='type-id-38'/> + <typedef-decl name='ino_t' type-id='type-id-83' filepath='/usr/include/x86_64-linux-gnu/sys/types.h' line='49' column='1' id='type-id-967'/> + <typedef-decl name='dev_t' type-id='type-id-187' filepath='/usr/include/x86_64-linux-gnu/sys/types.h' line='59' column='1' id='type-id-966'/> + <typedef-decl name='wchar_t' type-id='type-id-8' filepath='/usr/lib/gcc/x86_64-linux-gnu/11/include/stddef.h' line='321' column='1' id='type-id-422'/> + <pointer-type-def type-id='type-id-832' size-in-bits='64' id='type-id-570'/> + <qualified-type-def type-id='type-id-229' restrict='yes' id='type-id-412'/> + <pointer-type-def type-id='type-id-621' size-in-bits='64' id='type-id-573'/> + <pointer-type-def type-id='type-id-758' size-in-bits='64' id='type-id-835'/> + <pointer-type-def type-id='type-id-1012' size-in-bits='64' id='type-id-328'/> + <pointer-type-def type-id='type-id-726' size-in-bits='64' id='type-id-829'/> + <pointer-type-def type-id='type-id-348' size-in-bits='64' id='type-id-346'/> + <pointer-type-def type-id='type-id-343' size-in-bits='64' id='type-id-340'/> + <pointer-type-def type-id='type-id-349' size-in-bits='64' id='type-id-347'/> + <pointer-type-def type-id='type-id-733' size-in-bits='64' id='type-id-848'/> + <pointer-type-def type-id='type-id-1013' size-in-bits='64' id='type-id-365'/> + <pointer-type-def type-id='type-id-735' size-in-bits='64' id='type-id-310'/> + <pointer-type-def type-id='type-id-852' size-in-bits='64' id='type-id-855'/> + <pointer-type-def type-id='type-id-897' size-in-bits='64' id='type-id-900'/> + <pointer-type-def type-id='type-id-867' size-in-bits='64' id='type-id-830'/> + <pointer-type-def type-id='type-id-991' size-in-bits='64' id='type-id-20'/> + <pointer-type-def type-id='type-id-746' size-in-bits='64' id='type-id-249'/> + <pointer-type-def type-id='type-id-400' size-in-bits='64' id='type-id-390'/> + <pointer-type-def type-id='type-id-1056' size-in-bits='64' id='type-id-727'/> + <pointer-type-def type-id='type-id-1057' size-in-bits='64' id='type-id-779'/> + <pointer-type-def type-id='type-id-1058' size-in-bits='64' id='type-id-783'/> + <pointer-type-def type-id='type-id-1014' size-in-bits='64' id='type-id-424'/> + <pointer-type-def type-id='type-id-941' size-in-bits='64' id='type-id-177'/> + <pointer-type-def type-id='type-id-792' size-in-bits='64' id='type-id-587'/> + <pointer-type-def type-id='type-id-250' size-in-bits='64' id='type-id-440'/> + <pointer-type-def type-id='type-id-752' size-in-bits='64' id='type-id-262'/> + <pointer-type-def type-id='type-id-622' size-in-bits='64' id='type-id-593'/> + <pointer-type-def type-id='type-id-767' size-in-bits='64' id='type-id-768'/> + <pointer-type-def type-id='type-id-711' size-in-bits='64' id='type-id-720'/> + <pointer-type-def type-id='type-id-713' size-in-bits='64' id='type-id-718'/> + <pointer-type-def type-id='type-id-715' size-in-bits='64' id='type-id-721'/> + <pointer-type-def type-id='type-id-782' size-in-bits='64' id='type-id-1059'/> + <pointer-type-def type-id='type-id-369' size-in-bits='64' id='type-id-376'/> + <pointer-type-def type-id='type-id-371' size-in-bits='64' id='type-id-375'/> + <pointer-type-def type-id='type-id-774' size-in-bits='64' id='type-id-778'/> + <pointer-type-def type-id='type-id-1004' size-in-bits='64' id='type-id-1011'/> + <pointer-type-def type-id='type-id-979' size-in-bits='64' id='type-id-980'/> + <pointer-type-def type-id='type-id-707' size-in-bits='64' id='type-id-850'/> + <pointer-type-def type-id='type-id-908' size-in-bits='64' id='type-id-1060'/> + <pointer-type-def type-id='type-id-1061' size-in-bits='64' id='type-id-917'/> + <pointer-type-def type-id='type-id-912' size-in-bits='64' id='type-id-926'/> + <pointer-type-def type-id='type-id-902' size-in-bits='64' id='type-id-903'/> + <pointer-type-def type-id='type-id-904' size-in-bits='64' id='type-id-907'/> + <pointer-type-def type-id='type-id-905' size-in-bits='64' id='type-id-922'/> + <pointer-type-def type-id='type-id-1035' size-in-bits='64' id='type-id-1036'/> + <pointer-type-def type-id='type-id-770' size-in-bits='64' id='type-id-771'/> + <pointer-type-def type-id='type-id-857' size-in-bits='64' id='type-id-824'/> + <pointer-type-def type-id='type-id-740' size-in-bits='64' id='type-id-924'/> + <pointer-type-def type-id='type-id-772' size-in-bits='64' id='type-id-773'/> + <pointer-type-def type-id='type-id-942' size-in-bits='64' id='type-id-943'/> + <pointer-type-def type-id='type-id-956' size-in-bits='64' id='type-id-606'/> + <pointer-type-def type-id='type-id-957' size-in-bits='64' id='type-id-609'/> + <pointer-type-def type-id='type-id-951' size-in-bits='64' id='type-id-611'/> + <pointer-type-def type-id='type-id-802' size-in-bits='64' id='type-id-803'/> + <pointer-type-def type-id='type-id-805' size-in-bits='64' id='type-id-1062'/> + <pointer-type-def type-id='type-id-1062' size-in-bits='64' id='type-id-808'/> + <pointer-type-def type-id='type-id-1063' size-in-bits='64' id='type-id-1064'/> + <qualified-type-def type-id='type-id-15' restrict='yes' id='type-id-183'/> + <pointer-type-def type-id='type-id-623' size-in-bits='64' id='type-id-822'/> + <pointer-type-def type-id='type-id-430' size-in-bits='64' id='type-id-753'/> + <pointer-type-def type-id='type-id-251' size-in-bits='64' id='type-id-182'/> + <pointer-type-def type-id='type-id-838' size-in-bits='64' id='type-id-842'/> + <pointer-type-def type-id='type-id-1065' size-in-bits='64' id='type-id-1066'/> + <pointer-type-def type-id='type-id-1067' size-in-bits='64' id='type-id-765'/> + <pointer-type-def type-id='type-id-1068' size-in-bits='64' id='type-id-786'/> + <pointer-type-def type-id='type-id-1069' size-in-bits='64' id='type-id-754'/> + <pointer-type-def type-id='type-id-1070' size-in-bits='64' id='type-id-791'/> + <pointer-type-def type-id='type-id-1071' size-in-bits='64' id='type-id-1007'/> + <pointer-type-def type-id='type-id-1072' size-in-bits='64' id='type-id-724'/> + <pointer-type-def type-id='type-id-1073' size-in-bits='64' id='type-id-731'/> + <pointer-type-def type-id='type-id-1074' size-in-bits='64' id='type-id-739'/> + <pointer-type-def type-id='type-id-1075' size-in-bits='64' id='type-id-1006'/> + <pointer-type-def type-id='type-id-1076' size-in-bits='64' id='type-id-814'/> + <pointer-type-def type-id='type-id-190' size-in-bits='64' id='type-id-78'/> + <pointer-type-def type-id='type-id-947' size-in-bits='64' id='type-id-950'/> + <pointer-type-def type-id='type-id-976' size-in-bits='64' id='type-id-975'/> + <pointer-type-def type-id='type-id-946' size-in-bits='64' id='type-id-949'/> + <pointer-type-def type-id='type-id-982' size-in-bits='64' id='type-id-933'/> + <pointer-type-def type-id='type-id-1003' size-in-bits='64' id='type-id-640'/> + <pointer-type-def type-id='type-id-1042' size-in-bits='64' id='type-id-189'/> + <pointer-type-def type-id='type-id-998' size-in-bits='64' id='type-id-1000'/> + <pointer-type-def type-id='type-id-1077' size-in-bits='64' id='type-id-913'/> + <pointer-type-def type-id='type-id-325' size-in-bits='64' id='type-id-717'/> + <pointer-type-def type-id='type-id-230' size-in-bits='64' id='type-id-227'/> + <pointer-type-def type-id='type-id-1078' size-in-bits='64' id='type-id-1016'/> + <pointer-type-def type-id='type-id-1079' size-in-bits='64' id='type-id-1027'/> + <pointer-type-def type-id='type-id-1080' size-in-bits='64' id='type-id-764'/> + <pointer-type-def type-id='type-id-1081' size-in-bits='64' id='type-id-757'/> + <pointer-type-def type-id='type-id-1082' size-in-bits='64' id='type-id-819'/> + <pointer-type-def type-id='type-id-1083' size-in-bits='64' id='type-id-818'/> + <pointer-type-def type-id='type-id-1084' size-in-bits='64' id='type-id-921'/> + <pointer-type-def type-id='type-id-1085' size-in-bits='64' id='type-id-756'/> + <pointer-type-def type-id='type-id-1086' size-in-bits='64' id='type-id-762'/> + <pointer-type-def type-id='type-id-1087' size-in-bits='64' id='type-id-763'/> + <qualified-type-def type-id='type-id-993' volatile='yes' id='type-id-698'/> + <qualified-type-def type-id='type-id-994' volatile='yes' id='type-id-992'/> + <pointer-type-def type-id='type-id-422' size-in-bits='64' id='type-id-52'/> + <pointer-type-def type-id='type-id-52' size-in-bits='64' id='type-id-235'/> + <class-decl name='PyAsyncGenASend' is-struct='yes' visibility='default' is-declaration-only='yes' id='type-id-621'/> + <class-decl name='_PyAsyncGenWrappedValue' is-struct='yes' visibility='default' is-declaration-only='yes' id='type-id-622'/> + <class-decl name='code_arena_st' is-struct='yes' visibility='default' is-declaration-only='yes' id='type-id-623'/> + <function-decl name='PyEval_SaveThread' mangled-name='PyEval_SaveThread' filepath='./Include/ceval.h' line='128' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyEval_SaveThread'> + <return type-id='type-id-177'/> + </function-decl> + <function-decl name='PyEval_RestoreThread' mangled-name='PyEval_RestoreThread' filepath='./Include/ceval.h' line='129' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyEval_RestoreThread'> + <parameter type-id='type-id-177'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyMem_RawRealloc' mangled-name='PyMem_RawRealloc' filepath='./Include/cpython/pymem.h' line='7' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMem_RawRealloc'> + <parameter type-id='type-id-22'/> + <parameter type-id='type-id-19'/> + <return type-id='type-id-22'/> + </function-decl> + <function-decl name='PyMem_RawFree' mangled-name='PyMem_RawFree' filepath='./Include/cpython/pymem.h' line='8' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMem_RawFree'> + <parameter type-id='type-id-22'/> + <return type-id='type-id-46'/> + </function-decl> + <var-decl name='_PyOS_ReadlineTState' type-id='type-id-177' mangled-name='_PyOS_ReadlineTState' visibility='default' filepath='./Include/cpython/pythonrun.h' line='120' column='1' elf-symbol-id='_PyOS_ReadlineTState'/> + <var-decl name='PyOS_ReadlineFunctionPointer' type-id='type-id-1064' mangled-name='PyOS_ReadlineFunctionPointer' visibility='default' filepath='./Include/cpython/pythonrun.h' line='121' column='1' elf-symbol-id='PyOS_ReadlineFunctionPointer'/> + <function-decl name='_PyOS_InterruptOccurred' mangled-name='_PyOS_InterruptOccurred' filepath='./Include/internal/pycore_pystate.h' line='152' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyOS_InterruptOccurred'> + <parameter type-id='type-id-177'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyErr_CheckSignals' mangled-name='PyErr_CheckSignals' filepath='./Include/pyerrors.h' line='239' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_CheckSignals'> + <return type-id='type-id-8'/> + </function-decl> + <var-decl name='PyOS_InputHook' type-id='type-id-1066' mangled-name='PyOS_InputHook' visibility='default' filepath='./Include/pythonrun.h' line='22' column='1' elf-symbol-id='PyOS_InputHook'/> + <function-decl name='PyThread_allocate_lock' mangled-name='PyThread_allocate_lock' filepath='./Include/pythread.h' line='30' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThread_allocate_lock'> + <return type-id='type-id-801'/> + </function-decl> + <function-decl name='PyThread_acquire_lock' mangled-name='PyThread_acquire_lock' filepath='./Include/pythread.h' line='32' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThread_acquire_lock'> + <parameter type-id='type-id-801'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyThread_release_lock' mangled-name='PyThread_release_lock' filepath='./Include/pythread.h' line='81' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThread_release_lock'> + <parameter type-id='type-id-801'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='fflush' filepath='/usr/include/stdio.h' line='230' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-229'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='fgets' filepath='/usr/include/stdio.h' line='592' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-183'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-412'/> + <return type-id='type-id-15'/> + </function-decl> + <function-decl name='clearerr' filepath='/usr/include/stdio.h' line='786' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-229'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='feof' filepath='/usr/include/stdio.h' line='788' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-229'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='fileno' filepath='/usr/include/stdio.h' line='809' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-229'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='isatty' filepath='/usr/include/unistd.h' line='809' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyOS_Readline' mangled-name='PyOS_Readline' filepath='Parser/myreadline.c' line='364' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyOS_Readline'> + <parameter type-id='type-id-229' name='sys_stdin' filepath='Parser/myreadline.c' line='364' column='1'/> + <parameter type-id='type-id-229' name='sys_stdout' filepath='Parser/myreadline.c' line='364' column='1'/> + <parameter type-id='type-id-12' name='prompt' filepath='Parser/myreadline.c' line='364' column='1'/> + <return type-id='type-id-15'/> + </function-decl> + <function-type size-in-bits='64' id='type-id-1056'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-22'/> + <return type-id='type-id-2'/> + </function-type> + <function-type size-in-bits='64' id='type-id-1057'> + <parameter type-id='type-id-177'/> + <parameter type-id='type-id-375'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-2'/> + </function-type> + <function-type size-in-bits='64' id='type-id-1058'> + <parameter type-id='type-id-1059'/> + <return type-id='type-id-2'/> + </function-type> + <function-type size-in-bits='64' id='type-id-1061'> + <parameter type-id='type-id-926'/> + <parameter type-id='type-id-22'/> + <return type-id='type-id-1060'/> + </function-type> + <function-type size-in-bits='64' id='type-id-1063'> + <parameter type-id='type-id-229'/> + <parameter type-id='type-id-229'/> + <parameter type-id='type-id-12'/> + <return type-id='type-id-15'/> + </function-type> + <function-type size-in-bits='64' id='type-id-1065'> + <return type-id='type-id-8'/> + </function-type> + <function-type size-in-bits='64' id='type-id-1067'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-365'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-type> + <function-type size-in-bits='64' id='type-id-1068'> + <parameter type-id='type-id-177'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-1059'/> + <return type-id='type-id-8'/> + </function-type> + <function-type size-in-bits='64' id='type-id-1069'> + <parameter type-id='type-id-1'/> + <return type-id='type-id-8'/> + </function-type> + <function-type size-in-bits='64' id='type-id-1070'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-22'/> + <return type-id='type-id-8'/> + </function-type> + <function-type size-in-bits='64' id='type-id-1071'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-440'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-8'/> + </function-type> + <function-type size-in-bits='64' id='type-id-1072'> + <parameter type-id='type-id-722'/> + <parameter type-id='type-id-328'/> + <return type-id='type-id-8'/> + </function-type> + <function-type size-in-bits='64' id='type-id-1073'> + <parameter type-id='type-id-729'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-type> + <function-type size-in-bits='64' id='type-id-1074'> + <parameter type-id='type-id-737'/> + <parameter type-id='type-id-310'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-type> + <function-type size-in-bits='64' id='type-id-1075'> + <parameter type-id='type-id-250'/> + <parameter type-id='type-id-15'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-8'/> + </function-type> + <function-type size-in-bits='64' id='type-id-1076'> + <parameter type-id='type-id-22'/> + <return type-id='type-id-8'/> + </function-type> + <function-type size-in-bits='64' id='type-id-1077'> + <parameter type-id='type-id-22'/> + <return type-id='type-id-910'/> + </function-type> + <function-type size-in-bits='64' id='type-id-1078'> + <parameter type-id='type-id-8'/> + <return type-id='type-id-46'/> + </function-type> + <function-type size-in-bits='64' id='type-id-1079'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-189'/> + <parameter type-id='type-id-22'/> + <return type-id='type-id-46'/> + </function-type> + <function-type size-in-bits='64' id='type-id-1080'> + <parameter type-id='type-id-22'/> + <parameter type-id='type-id-22'/> + <return type-id='type-id-46'/> + </function-type> + <function-type size-in-bits='64' id='type-id-1081'> + <parameter type-id='type-id-22'/> + <parameter type-id='type-id-22'/> + <parameter type-id='type-id-19'/> + <return type-id='type-id-46'/> + </function-type> + <function-type size-in-bits='64' id='type-id-1082'> + <parameter type-id='type-id-22'/> + <parameter type-id='type-id-22'/> + <parameter type-id='type-id-95'/> + <parameter type-id='type-id-328'/> + <return type-id='type-id-46'/> + </function-type> + <function-type size-in-bits='64' id='type-id-1083'> + <return type-id='type-id-22'/> + </function-type> + <function-type size-in-bits='64' id='type-id-1084'> + <parameter type-id='type-id-19'/> + <return type-id='type-id-22'/> + </function-type> + <function-type size-in-bits='64' id='type-id-1085'> + <parameter type-id='type-id-22'/> + <parameter type-id='type-id-19'/> + <return type-id='type-id-22'/> + </function-type> + <function-type size-in-bits='64' id='type-id-1086'> + <parameter type-id='type-id-22'/> + <parameter type-id='type-id-19'/> + <parameter type-id='type-id-19'/> + <return type-id='type-id-22'/> + </function-type> + <function-type size-in-bits='64' id='type-id-1087'> + <parameter type-id='type-id-22'/> + <parameter type-id='type-id-22'/> + <parameter type-id='type-id-19'/> + <return type-id='type-id-22'/> + </function-type> + <function-type size-in-bits='64' id='type-id-1088'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-22'/> + <return type-id='type-id-2'/> + </function-type> + <function-type size-in-bits='64' id='type-id-1089'> + <parameter type-id='type-id-22'/> + <return type-id='type-id-46'/> + </function-type> + </abi-instr> + <abi-instr address-size='64' path='Parser/parser.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <class-decl name='asdl_seq' size-in-bits='128' is-struct='yes' naming-typedef-id='type-id-1090' visibility='default' filepath='./Include/internal/pycore_asdl.h' line='28' column='1' id='type-id-1091'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='size' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_asdl.h' line='29' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='elements' type-id='type-id-253' visibility='default' filepath='./Include/internal/pycore_asdl.h' line='29' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='asdl_seq' type-id='type-id-1091' filepath='./Include/internal/pycore_asdl.h' line='30' column='1' id='type-id-1090'/> + <enum-decl name='_cmpop' filepath='./Include/internal/pycore_ast.h' line='31' column='1' id='type-id-1092'> + <underlying-type type-id='type-id-24'/> + <enumerator name='Eq' value='1'/> + <enumerator name='NotEq' value='2'/> + <enumerator name='Lt' value='3'/> + <enumerator name='LtE' value='4'/> + <enumerator name='Gt' value='5'/> + <enumerator name='GtE' value='6'/> + <enumerator name='Is' value='7'/> + <enumerator name='IsNot' value='8'/> + <enumerator name='In' value='9'/> + <enumerator name='NotIn' value='10'/> + </enum-decl> + <typedef-decl name='cmpop_ty' type-id='type-id-1092' filepath='./Include/internal/pycore_ast.h' line='32' column='1' id='type-id-1093'/> + <class-decl name='CmpopExprPair' size-in-bits='128' is-struct='yes' naming-typedef-id='type-id-1094' visibility='default' filepath='Parser/pegen.h' line='85' column='1' id='type-id-1095'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='cmpop' type-id='type-id-1093' visibility='default' filepath='Parser/pegen.h' line='86' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='expr' type-id='type-id-502' visibility='default' filepath='Parser/pegen.h' line='87' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='CmpopExprPair' type-id='type-id-1095' filepath='Parser/pegen.h' line='88' column='1' id='type-id-1094'/> + <class-decl name='KeyValuePair' size-in-bits='128' is-struct='yes' naming-typedef-id='type-id-1096' visibility='default' filepath='Parser/pegen.h' line='90' column='1' id='type-id-1097'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='key' type-id='type-id-502' visibility='default' filepath='Parser/pegen.h' line='91' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='value' type-id='type-id-502' visibility='default' filepath='Parser/pegen.h' line='92' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='KeyValuePair' type-id='type-id-1097' filepath='Parser/pegen.h' line='93' column='1' id='type-id-1096'/> + <class-decl name='KeyPatternPair' size-in-bits='128' is-struct='yes' naming-typedef-id='type-id-1098' visibility='default' filepath='Parser/pegen.h' line='95' column='1' id='type-id-1099'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='key' type-id='type-id-502' visibility='default' filepath='Parser/pegen.h' line='96' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='pattern' type-id='type-id-450' visibility='default' filepath='Parser/pegen.h' line='97' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='KeyPatternPair' type-id='type-id-1099' filepath='Parser/pegen.h' line='98' column='1' id='type-id-1098'/> + <class-decl name='NameDefaultPair' size-in-bits='128' is-struct='yes' naming-typedef-id='type-id-1100' visibility='default' filepath='Parser/pegen.h' line='100' column='1' id='type-id-1101'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='arg' type-id='type-id-567' visibility='default' filepath='Parser/pegen.h' line='101' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='value' type-id='type-id-502' visibility='default' filepath='Parser/pegen.h' line='102' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='NameDefaultPair' type-id='type-id-1101' filepath='Parser/pegen.h' line='103' column='1' id='type-id-1100'/> + <class-decl name='SlashWithDefault' size-in-bits='128' is-struct='yes' naming-typedef-id='type-id-1102' visibility='default' filepath='Parser/pegen.h' line='105' column='1' id='type-id-1103'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='plain_names' type-id='type-id-565' visibility='default' filepath='Parser/pegen.h' line='106' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='names_with_defaults' type-id='type-id-1104' visibility='default' filepath='Parser/pegen.h' line='107' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='SlashWithDefault' type-id='type-id-1103' filepath='Parser/pegen.h' line='108' column='1' id='type-id-1102'/> + <class-decl name='StarEtc' size-in-bits='192' is-struct='yes' naming-typedef-id='type-id-1105' visibility='default' filepath='Parser/pegen.h' line='110' column='1' id='type-id-1106'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='vararg' type-id='type-id-567' visibility='default' filepath='Parser/pegen.h' line='111' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='kwonlyargs' type-id='type-id-1104' visibility='default' filepath='Parser/pegen.h' line='112' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='kwarg' type-id='type-id-567' visibility='default' filepath='Parser/pegen.h' line='113' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='StarEtc' type-id='type-id-1106' filepath='Parser/pegen.h' line='114' column='1' id='type-id-1105'/> + <class-decl name='AugOperator' size-in-bits='32' is-struct='yes' naming-typedef-id='type-id-1107' visibility='default' filepath='Parser/pegen.h' line='116' column='1' id='type-id-1108'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='kind' type-id='type-id-530' visibility='default' filepath='Parser/pegen.h' line='116' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='AugOperator' type-id='type-id-1108' filepath='Parser/pegen.h' line='116' column='1' id='type-id-1107'/> + <class-decl name='KeywordOrStarred' size-in-bits='128' is-struct='yes' naming-typedef-id='type-id-1109' visibility='default' filepath='Parser/pegen.h' line='117' column='1' id='type-id-1110'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='element' type-id='type-id-22' visibility='default' filepath='Parser/pegen.h' line='118' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='is_keyword' type-id='type-id-8' visibility='default' filepath='Parser/pegen.h' line='119' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='KeywordOrStarred' type-id='type-id-1110' filepath='Parser/pegen.h' line='120' column='1' id='type-id-1109'/> + <class-decl name='ResultTokenWithMetadata' size-in-bits='128' is-struct='yes' naming-typedef-id='type-id-1111' visibility='default' filepath='Parser/pegen.h' line='122' column='1' id='type-id-1112'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='result' type-id='type-id-22' visibility='default' filepath='Parser/pegen.h' line='123' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='metadata' type-id='type-id-2' visibility='default' filepath='Parser/pegen.h' line='124' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='ResultTokenWithMetadata' type-id='type-id-1112' filepath='Parser/pegen.h' line='125' column='1' id='type-id-1111'/> + <enum-decl name='TARGETS_TYPE' naming-typedef-id='type-id-1113' filepath='Parser/pegen.h' line='156' column='1' id='type-id-1114'> + <underlying-type type-id='type-id-24'/> + <enumerator name='STAR_TARGETS' value='0'/> + <enumerator name='DEL_TARGETS' value='1'/> + <enumerator name='FOR_TARGETS' value='2'/> + </enum-decl> + <typedef-decl name='TARGETS_TYPE' type-id='type-id-1114' filepath='Parser/pegen.h' line='160' column='1' id='type-id-1113'/> + <pointer-type-def type-id='type-id-1107' size-in-bits='64' id='type-id-1115'/> + <pointer-type-def type-id='type-id-1094' size-in-bits='64' id='type-id-1116'/> + <pointer-type-def type-id='type-id-1098' size-in-bits='64' id='type-id-1117'/> + <pointer-type-def type-id='type-id-1096' size-in-bits='64' id='type-id-1118'/> + <pointer-type-def type-id='type-id-1109' size-in-bits='64' id='type-id-1119'/> + <pointer-type-def type-id='type-id-1100' size-in-bits='64' id='type-id-1120'/> + <pointer-type-def type-id='type-id-1111' size-in-bits='64' id='type-id-1121'/> + <pointer-type-def type-id='type-id-1102' size-in-bits='64' id='type-id-1122'/> + <pointer-type-def type-id='type-id-1105' size-in-bits='64' id='type-id-1123'/> + <pointer-type-def type-id='type-id-1124' size-in-bits='64' id='type-id-1125'/> + <pointer-type-def type-id='type-id-1090' size-in-bits='64' id='type-id-1104'/> + <pointer-type-def type-id='type-id-1126' size-in-bits='64' id='type-id-1127'/> + <pointer-type-def type-id='type-id-1128' size-in-bits='64' id='type-id-1129'/> + <pointer-type-def type-id='type-id-1130' size-in-bits='64' id='type-id-1131'/> + <class-decl name='tok_state' size-in-bits='138240' is-struct='yes' visibility='default' filepath='Parser/tokenizer.h' line='68' column='1' id='type-id-1132'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='buf' type-id='type-id-15' visibility='default' filepath='Parser/tokenizer.h' line='71' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='cur' type-id='type-id-15' visibility='default' filepath='Parser/tokenizer.h' line='72' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='inp' type-id='type-id-15' visibility='default' filepath='Parser/tokenizer.h' line='73' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='fp_interactive' type-id='type-id-8' visibility='default' filepath='Parser/tokenizer.h' line='74' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='interactive_src_start' type-id='type-id-15' visibility='default' filepath='Parser/tokenizer.h' line='75' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='interactive_src_end' type-id='type-id-15' visibility='default' filepath='Parser/tokenizer.h' line='76' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='384'> + <var-decl name='end' type-id='type-id-12' visibility='default' filepath='Parser/tokenizer.h' line='77' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='448'> + <var-decl name='start' type-id='type-id-12' visibility='default' filepath='Parser/tokenizer.h' line='78' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='512'> + <var-decl name='done' type-id='type-id-8' visibility='default' filepath='Parser/tokenizer.h' line='79' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='576'> + <var-decl name='fp' type-id='type-id-229' visibility='default' filepath='Parser/tokenizer.h' line='81' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='640'> + <var-decl name='tabsize' type-id='type-id-8' visibility='default' filepath='Parser/tokenizer.h' line='82' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='672'> + <var-decl name='indent' type-id='type-id-8' visibility='default' filepath='Parser/tokenizer.h' line='83' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='704'> + <var-decl name='indstack' type-id='type-id-1133' visibility='default' filepath='Parser/tokenizer.h' line='84' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='3904'> + <var-decl name='atbol' type-id='type-id-8' visibility='default' filepath='Parser/tokenizer.h' line='85' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='3936'> + <var-decl name='pendin' type-id='type-id-8' visibility='default' filepath='Parser/tokenizer.h' line='86' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='3968'> + <var-decl name='prompt' type-id='type-id-12' visibility='default' filepath='Parser/tokenizer.h' line='87' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='4032'> + <var-decl name='nextprompt' type-id='type-id-12' visibility='default' filepath='Parser/tokenizer.h' line='87' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='4096'> + <var-decl name='lineno' type-id='type-id-8' visibility='default' filepath='Parser/tokenizer.h' line='88' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='4128'> + <var-decl name='first_lineno' type-id='type-id-8' visibility='default' filepath='Parser/tokenizer.h' line='89' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='4160'> + <var-decl name='starting_col_offset' type-id='type-id-8' visibility='default' filepath='Parser/tokenizer.h' line='91' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='4192'> + <var-decl name='col_offset' type-id='type-id-8' visibility='default' filepath='Parser/tokenizer.h' line='92' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='4224'> + <var-decl name='level' type-id='type-id-8' visibility='default' filepath='Parser/tokenizer.h' line='93' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='4256'> + <var-decl name='parenstack' type-id='type-id-1134' visibility='default' filepath='Parser/tokenizer.h' line='95' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='5856'> + <var-decl name='parenlinenostack' type-id='type-id-1135' visibility='default' filepath='Parser/tokenizer.h' line='96' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='12256'> + <var-decl name='parencolstack' type-id='type-id-1135' visibility='default' filepath='Parser/tokenizer.h' line='97' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='18688'> + <var-decl name='filename' type-id='type-id-2' visibility='default' filepath='Parser/tokenizer.h' line='98' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='18752'> + <var-decl name='altindstack' type-id='type-id-1133' visibility='default' filepath='Parser/tokenizer.h' line='100' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='21952'> + <var-decl name='decoding_state' type-id='type-id-1136' visibility='default' filepath='Parser/tokenizer.h' line='102' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='21984'> + <var-decl name='decoding_erred' type-id='type-id-8' visibility='default' filepath='Parser/tokenizer.h' line='103' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='22016'> + <var-decl name='encoding' type-id='type-id-15' visibility='default' filepath='Parser/tokenizer.h' line='104' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='22080'> + <var-decl name='cont_line' type-id='type-id-8' visibility='default' filepath='Parser/tokenizer.h' line='105' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='22144'> + <var-decl name='line_start' type-id='type-id-12' visibility='default' filepath='Parser/tokenizer.h' line='106' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='22208'> + <var-decl name='multi_line_start' type-id='type-id-12' visibility='default' filepath='Parser/tokenizer.h' line='107' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='22272'> + <var-decl name='decoding_readline' type-id='type-id-2' visibility='default' filepath='Parser/tokenizer.h' line='110' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='22336'> + <var-decl name='decoding_buffer' type-id='type-id-2' visibility='default' filepath='Parser/tokenizer.h' line='111' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='22400'> + <var-decl name='readline' type-id='type-id-2' visibility='default' filepath='Parser/tokenizer.h' line='112' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='22464'> + <var-decl name='enc' type-id='type-id-12' visibility='default' filepath='Parser/tokenizer.h' line='113' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='22528'> + <var-decl name='str' type-id='type-id-15' visibility='default' filepath='Parser/tokenizer.h' line='114' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='22592'> + <var-decl name='input' type-id='type-id-15' visibility='default' filepath='Parser/tokenizer.h' line='115' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='22656'> + <var-decl name='type_comments' type-id='type-id-8' visibility='default' filepath='Parser/tokenizer.h' line='117' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='22688'> + <var-decl name='async_hacks' type-id='type-id-8' visibility='default' filepath='Parser/tokenizer.h' line='120' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='22720'> + <var-decl name='async_def' type-id='type-id-8' visibility='default' filepath='Parser/tokenizer.h' line='121' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='22752'> + <var-decl name='async_def_indent' type-id='type-id-8' visibility='default' filepath='Parser/tokenizer.h' line='122' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='22784'> + <var-decl name='async_def_nl' type-id='type-id-8' visibility='default' filepath='Parser/tokenizer.h' line='123' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='22816'> + <var-decl name='interactive_underflow' type-id='type-id-1137' visibility='default' filepath='Parser/tokenizer.h' line='126' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='22848'> + <var-decl name='report_warnings' type-id='type-id-8' visibility='default' filepath='Parser/tokenizer.h' line='127' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='22912'> + <var-decl name='tok_mode_stack' type-id='type-id-1138' visibility='default' filepath='Parser/tokenizer.h' line='129' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='138112'> + <var-decl name='tok_mode_stack_index' type-id='type-id-8' visibility='default' filepath='Parser/tokenizer.h' line='130' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='138144'> + <var-decl name='tok_extra_tokens' type-id='type-id-8' visibility='default' filepath='Parser/tokenizer.h' line='131' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='138176'> + <var-decl name='comment_newline' type-id='type-id-8' visibility='default' filepath='Parser/tokenizer.h' line='132' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='138208'> + <var-decl name='implicit_newline' type-id='type-id-8' visibility='default' filepath='Parser/tokenizer.h' line='133' column='1'/> + </data-member> + </class-decl> + <function-decl name='_PyAST_Interactive' filepath='./Include/internal/pycore_ast.h' line='681' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-500'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-468'/> + </function-decl> + <function-decl name='_PyAST_Expression' filepath='./Include/internal/pycore_ast.h' line='682' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-468'/> + </function-decl> + <function-decl name='_PyAST_FunctionType' filepath='./Include/internal/pycore_ast.h' line='683' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-503'/> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-468'/> + </function-decl> + <function-decl name='_PyAST_Return' filepath='./Include/internal/pycore_ast.h' line='701' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-452'/> + </function-decl> + <function-decl name='_PyAST_Delete' filepath='./Include/internal/pycore_ast.h' line='703' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-503'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-452'/> + </function-decl> + <function-decl name='_PyAST_Assign' filepath='./Include/internal/pycore_ast.h' line='705' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-503'/> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-527'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-452'/> + </function-decl> + <function-decl name='_PyAST_TypeAlias' filepath='./Include/internal/pycore_ast.h' line='708' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-528'/> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-452'/> + </function-decl> + <function-decl name='_PyAST_AugAssign' filepath='./Include/internal/pycore_ast.h' line='711' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-530'/> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-452'/> + </function-decl> + <function-decl name='_PyAST_AnnAssign' filepath='./Include/internal/pycore_ast.h' line='714' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-452'/> + </function-decl> + <function-decl name='_PyAST_For' filepath='./Include/internal/pycore_ast.h' line='717' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-500'/> + <parameter type-id='type-id-500'/> + <parameter type-id='type-id-527'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-452'/> + </function-decl> + <function-decl name='_PyAST_AsyncFor' filepath='./Include/internal/pycore_ast.h' line='721' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-500'/> + <parameter type-id='type-id-500'/> + <parameter type-id='type-id-527'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-452'/> + </function-decl> + <function-decl name='_PyAST_While' filepath='./Include/internal/pycore_ast.h' line='725' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-500'/> + <parameter type-id='type-id-500'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-452'/> + </function-decl> + <function-decl name='_PyAST_If' filepath='./Include/internal/pycore_ast.h' line='728' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-500'/> + <parameter type-id='type-id-500'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-452'/> + </function-decl> + <function-decl name='_PyAST_With' filepath='./Include/internal/pycore_ast.h' line='731' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-531'/> + <parameter type-id='type-id-500'/> + <parameter type-id='type-id-527'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-452'/> + </function-decl> + <function-decl name='_PyAST_AsyncWith' filepath='./Include/internal/pycore_ast.h' line='734' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-531'/> + <parameter type-id='type-id-500'/> + <parameter type-id='type-id-527'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-452'/> + </function-decl> + <function-decl name='_PyAST_Match' filepath='./Include/internal/pycore_ast.h' line='737' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-532'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-452'/> + </function-decl> + <function-decl name='_PyAST_Raise' filepath='./Include/internal/pycore_ast.h' line='740' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-452'/> + </function-decl> + <function-decl name='_PyAST_Try' filepath='./Include/internal/pycore_ast.h' line='742' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-500'/> + <parameter type-id='type-id-533'/> + <parameter type-id='type-id-500'/> + <parameter type-id='type-id-500'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-452'/> + </function-decl> + <function-decl name='_PyAST_TryStar' filepath='./Include/internal/pycore_ast.h' line='746' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-500'/> + <parameter type-id='type-id-533'/> + <parameter type-id='type-id-500'/> + <parameter type-id='type-id-500'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-452'/> + </function-decl> + <function-decl name='_PyAST_Assert' filepath='./Include/internal/pycore_ast.h' line='750' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-452'/> + </function-decl> + <function-decl name='_PyAST_Import' filepath='./Include/internal/pycore_ast.h' line='752' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-534'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-452'/> + </function-decl> + <function-decl name='_PyAST_ImportFrom' filepath='./Include/internal/pycore_ast.h' line='754' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-525'/> + <parameter type-id='type-id-534'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-452'/> + </function-decl> + <function-decl name='_PyAST_Global' filepath='./Include/internal/pycore_ast.h' line='757' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-535'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-452'/> + </function-decl> + <function-decl name='_PyAST_Nonlocal' filepath='./Include/internal/pycore_ast.h' line='759' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-535'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-452'/> + </function-decl> + <function-decl name='_PyAST_Expr' filepath='./Include/internal/pycore_ast.h' line='762' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-452'/> + </function-decl> + <function-decl name='_PyAST_Pass' filepath='./Include/internal/pycore_ast.h' line='764' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-452'/> + </function-decl> + <function-decl name='_PyAST_Break' filepath='./Include/internal/pycore_ast.h' line='766' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-452'/> + </function-decl> + <function-decl name='_PyAST_Continue' filepath='./Include/internal/pycore_ast.h' line='768' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-452'/> + </function-decl> + <function-decl name='_PyAST_BoolOp' filepath='./Include/internal/pycore_ast.h' line='770' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1139'/> + <parameter type-id='type-id-503'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-502'/> + </function-decl> + <function-decl name='_PyAST_NamedExpr' filepath='./Include/internal/pycore_ast.h' line='773' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-502'/> + </function-decl> + <function-decl name='_PyAST_BinOp' filepath='./Include/internal/pycore_ast.h' line='776' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-530'/> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-502'/> + </function-decl> + <function-decl name='_PyAST_UnaryOp' filepath='./Include/internal/pycore_ast.h' line='779' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1140'/> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-502'/> + </function-decl> + <function-decl name='_PyAST_Lambda' filepath='./Include/internal/pycore_ast.h' line='782' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-526'/> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-502'/> + </function-decl> + <function-decl name='_PyAST_IfExp' filepath='./Include/internal/pycore_ast.h' line='785' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-502'/> + </function-decl> + <function-decl name='_PyAST_Dict' filepath='./Include/internal/pycore_ast.h' line='788' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-503'/> + <parameter type-id='type-id-503'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-502'/> + </function-decl> + <function-decl name='_PyAST_Set' filepath='./Include/internal/pycore_ast.h' line='791' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-503'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-502'/> + </function-decl> + <function-decl name='_PyAST_ListComp' filepath='./Include/internal/pycore_ast.h' line='793' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-1141'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-502'/> + </function-decl> + <function-decl name='_PyAST_SetComp' filepath='./Include/internal/pycore_ast.h' line='796' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-1141'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-502'/> + </function-decl> + <function-decl name='_PyAST_DictComp' filepath='./Include/internal/pycore_ast.h' line='799' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-1141'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-502'/> + </function-decl> + <function-decl name='_PyAST_GeneratorExp' filepath='./Include/internal/pycore_ast.h' line='802' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-1141'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-502'/> + </function-decl> + <function-decl name='_PyAST_Await' filepath='./Include/internal/pycore_ast.h' line='805' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-502'/> + </function-decl> + <function-decl name='_PyAST_Yield' filepath='./Include/internal/pycore_ast.h' line='807' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-502'/> + </function-decl> + <function-decl name='_PyAST_YieldFrom' filepath='./Include/internal/pycore_ast.h' line='809' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-502'/> + </function-decl> + <function-decl name='_PyAST_Compare' filepath='./Include/internal/pycore_ast.h' line='811' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-564'/> + <parameter type-id='type-id-503'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-502'/> + </function-decl> + <function-decl name='_PyAST_Slice' filepath='./Include/internal/pycore_ast.h' line='843' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-502'/> + </function-decl> + <function-decl name='_PyAST_comprehension' filepath='./Include/internal/pycore_ast.h' line='846' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-503'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-1142'/> + </function-decl> + <function-decl name='_PyAST_ExceptHandler' filepath='./Include/internal/pycore_ast.h' line='849' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-525'/> + <parameter type-id='type-id-500'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-446'/> + </function-decl> + <function-decl name='_PyAST_keyword' filepath='./Include/internal/pycore_ast.h' line='860' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-525'/> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-1143'/> + </function-decl> + <function-decl name='_PyAST_withitem' filepath='./Include/internal/pycore_ast.h' line='866' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-459'/> + </function-decl> + <function-decl name='_PyAST_match_case' filepath='./Include/internal/pycore_ast.h' line='868' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-450'/> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-500'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-448'/> + </function-decl> + <function-decl name='_PyAST_MatchValue' filepath='./Include/internal/pycore_ast.h' line='870' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-450'/> + </function-decl> + <function-decl name='_PyAST_MatchSingleton' filepath='./Include/internal/pycore_ast.h' line='872' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-552'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-450'/> + </function-decl> + <function-decl name='_PyAST_MatchSequence' filepath='./Include/internal/pycore_ast.h' line='875' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-553'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-450'/> + </function-decl> + <function-decl name='_PyAST_MatchMapping' filepath='./Include/internal/pycore_ast.h' line='878' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-503'/> + <parameter type-id='type-id-553'/> + <parameter type-id='type-id-525'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-450'/> + </function-decl> + <function-decl name='_PyAST_MatchClass' filepath='./Include/internal/pycore_ast.h' line='882' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-553'/> + <parameter type-id='type-id-535'/> + <parameter type-id='type-id-553'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-450'/> + </function-decl> + <function-decl name='_PyAST_MatchStar' filepath='./Include/internal/pycore_ast.h' line='886' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-525'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-450'/> + </function-decl> + <function-decl name='_PyAST_MatchAs' filepath='./Include/internal/pycore_ast.h' line='888' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-450'/> + <parameter type-id='type-id-525'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-450'/> + </function-decl> + <function-decl name='_PyAST_MatchOr' filepath='./Include/internal/pycore_ast.h' line='891' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-553'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-450'/> + </function-decl> + <function-decl name='_PyAST_TypeVar' filepath='./Include/internal/pycore_ast.h' line='895' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-525'/> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-456'/> + </function-decl> + <function-decl name='_PyAST_ParamSpec' filepath='./Include/internal/pycore_ast.h' line='898' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-525'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-456'/> + </function-decl> + <function-decl name='_PyAST_TypeVarTuple' filepath='./Include/internal/pycore_ast.h' line='900' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-525'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-456'/> + </function-decl> + <function-decl name='_PyPegen_insert_memo' filepath='Parser/pegen.h' line='133' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-22'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyPegen_update_memo' filepath='Parser/pegen.h' line='134' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-22'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyPegen_is_memoized' filepath='Parser/pegen.h' line='135' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-22'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyPegen_lookahead_with_name' filepath='Parser/pegen.h' line='137' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-1127'/> + <parameter type-id='type-id-568'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyPegen_lookahead_with_int' filepath='Parser/pegen.h' line='138' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-1125'/> + <parameter type-id='type-id-568'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyPegen_lookahead_with_string' filepath='Parser/pegen.h' line='139' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-1129'/> + <parameter type-id='type-id-568'/> + <parameter type-id='type-id-12'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyPegen_lookahead' filepath='Parser/pegen.h' line='140' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-1131'/> + <parameter type-id='type-id-568'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyPegen_expect_token' filepath='Parser/pegen.h' line='142' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-569'/> + </function-decl> + <function-decl name='_PyPegen_expect_forced_token' filepath='Parser/pegen.h' line='144' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-12'/> + <return type-id='type-id-569'/> + </function-decl> + <function-decl name='_PyPegen_expect_soft_keyword' filepath='Parser/pegen.h' line='145' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <parameter type-id='type-id-12'/> + <return type-id='type-id-502'/> + </function-decl> + <function-decl name='_PyPegen_soft_keyword_token' filepath='Parser/pegen.h' line='146' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <return type-id='type-id-502'/> + </function-decl> + <function-decl name='_PyPegen_get_last_nonnwhitespace_token' filepath='Parser/pegen.h' line='148' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <return type-id='type-id-569'/> + </function-decl> + <function-decl name='_PyPegen_name_token' filepath='Parser/pegen.h' line='150' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <return type-id='type-id-502'/> + </function-decl> + <function-decl name='_PyPegen_number_token' filepath='Parser/pegen.h' line='151' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <return type-id='type-id-502'/> + </function-decl> + <function-decl name='_PyPegen_string_token' filepath='Parser/pegen.h' line='152' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <return type-id='type-id-22'/> + </function-decl> + <function-decl name='_Pypegen_stack_overflow' filepath='Parser/pegen.h' line='171' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyPegen_get_invalid_target' filepath='Parser/pegen.h' line='222' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-1113'/> + <return type-id='type-id-502'/> + </function-decl> + <function-decl name='_PyPegen_get_expr_name' filepath='Parser/pegen.h' line='223' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-502'/> + <return type-id='type-id-12'/> + </function-decl> + <function-decl name='_PyPegen_dummy_name' filepath='Parser/pegen.h' line='248' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <parameter is-variadic='yes'/> + <return type-id='type-id-22'/> + </function-decl> + <function-decl name='_PyPegen_seq_last_item' filepath='Parser/pegen.h' line='249' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1104'/> + <return type-id='type-id-22'/> + </function-decl> + <function-decl name='_PyPegen_seq_first_item' filepath='Parser/pegen.h' line='251' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1104'/> + <return type-id='type-id-22'/> + </function-decl> + <function-decl name='_PyPegen_new_type_comment' filepath='Parser/pegen.h' line='256' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <parameter type-id='type-id-12'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyPegen_add_type_comment_to_arg' filepath='Parser/pegen.h' line='295' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <parameter type-id='type-id-567'/> + <parameter type-id='type-id-569'/> + <return type-id='type-id-567'/> + </function-decl> + <function-decl name='_PyPegen_singleton_seq' filepath='Parser/pegen.h' line='297' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <parameter type-id='type-id-22'/> + <return type-id='type-id-1104'/> + </function-decl> + <function-decl name='_PyPegen_seq_insert_in_front' filepath='Parser/pegen.h' line='298' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <parameter type-id='type-id-22'/> + <parameter type-id='type-id-1104'/> + <return type-id='type-id-1104'/> + </function-decl> + <function-decl name='_PyPegen_seq_append_to_end' filepath='Parser/pegen.h' line='299' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <parameter type-id='type-id-1104'/> + <parameter type-id='type-id-22'/> + <return type-id='type-id-1104'/> + </function-decl> + <function-decl name='_PyPegen_seq_flatten' filepath='Parser/pegen.h' line='300' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <parameter type-id='type-id-1104'/> + <return type-id='type-id-1104'/> + </function-decl> + <function-decl name='_PyPegen_join_names_with_dot' filepath='Parser/pegen.h' line='301' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-502'/> + <return type-id='type-id-502'/> + </function-decl> + <function-decl name='_PyPegen_seq_count_dots' filepath='Parser/pegen.h' line='302' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1104'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyPegen_alias_for_star' filepath='Parser/pegen.h' line='303' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-444'/> + </function-decl> + <function-decl name='_PyPegen_map_names_to_ids' filepath='Parser/pegen.h' line='304' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <parameter type-id='type-id-503'/> + <return type-id='type-id-535'/> + </function-decl> + <function-decl name='_PyPegen_cmpop_expr_pair' filepath='Parser/pegen.h' line='305' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <parameter type-id='type-id-1093'/> + <parameter type-id='type-id-502'/> + <return type-id='type-id-1116'/> + </function-decl> + <function-decl name='_PyPegen_get_cmpops' filepath='Parser/pegen.h' line='306' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <parameter type-id='type-id-1104'/> + <return type-id='type-id-564'/> + </function-decl> + <function-decl name='_PyPegen_get_exprs' filepath='Parser/pegen.h' line='307' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <parameter type-id='type-id-1104'/> + <return type-id='type-id-503'/> + </function-decl> + <function-decl name='_PyPegen_set_expr_context' filepath='Parser/pegen.h' line='308' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-566'/> + <return type-id='type-id-502'/> + </function-decl> + <function-decl name='_PyPegen_key_value_pair' filepath='Parser/pegen.h' line='309' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-502'/> + <return type-id='type-id-1118'/> + </function-decl> + <function-decl name='_PyPegen_get_keys' filepath='Parser/pegen.h' line='310' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <parameter type-id='type-id-1104'/> + <return type-id='type-id-503'/> + </function-decl> + <function-decl name='_PyPegen_get_values' filepath='Parser/pegen.h' line='311' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <parameter type-id='type-id-1104'/> + <return type-id='type-id-503'/> + </function-decl> + <function-decl name='_PyPegen_key_pattern_pair' filepath='Parser/pegen.h' line='312' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-450'/> + <return type-id='type-id-1117'/> + </function-decl> + <function-decl name='_PyPegen_get_pattern_keys' filepath='Parser/pegen.h' line='313' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <parameter type-id='type-id-1104'/> + <return type-id='type-id-503'/> + </function-decl> + <function-decl name='_PyPegen_get_patterns' filepath='Parser/pegen.h' line='314' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <parameter type-id='type-id-1104'/> + <return type-id='type-id-553'/> + </function-decl> + <function-decl name='_PyPegen_name_default_pair' filepath='Parser/pegen.h' line='315' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <parameter type-id='type-id-567'/> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-569'/> + <return type-id='type-id-1120'/> + </function-decl> + <function-decl name='_PyPegen_slash_with_default' filepath='Parser/pegen.h' line='316' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <parameter type-id='type-id-565'/> + <parameter type-id='type-id-1104'/> + <return type-id='type-id-1122'/> + </function-decl> + <function-decl name='_PyPegen_star_etc' filepath='Parser/pegen.h' line='317' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <parameter type-id='type-id-567'/> + <parameter type-id='type-id-1104'/> + <parameter type-id='type-id-567'/> + <return type-id='type-id-1123'/> + </function-decl> + <function-decl name='_PyPegen_make_arguments' filepath='Parser/pegen.h' line='318' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <parameter type-id='type-id-565'/> + <parameter type-id='type-id-1122'/> + <parameter type-id='type-id-565'/> + <parameter type-id='type-id-1104'/> + <parameter type-id='type-id-1123'/> + <return type-id='type-id-526'/> + </function-decl> + <function-decl name='_PyPegen_empty_arguments' filepath='Parser/pegen.h' line='320' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <return type-id='type-id-526'/> + </function-decl> + <function-decl name='_PyPegen_formatted_value' filepath='Parser/pegen.h' line='321' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-569'/> + <parameter type-id='type-id-1121'/> + <parameter type-id='type-id-1121'/> + <parameter type-id='type-id-569'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-502'/> + </function-decl> + <function-decl name='_PyPegen_augoperator' filepath='Parser/pegen.h' line='323' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <parameter type-id='type-id-530'/> + <return type-id='type-id-1115'/> + </function-decl> + <function-decl name='_PyPegen_function_def_decorators' filepath='Parser/pegen.h' line='324' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <parameter type-id='type-id-503'/> + <parameter type-id='type-id-452'/> + <return type-id='type-id-452'/> + </function-decl> + <function-decl name='_PyPegen_class_def_decorators' filepath='Parser/pegen.h' line='325' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <parameter type-id='type-id-503'/> + <parameter type-id='type-id-452'/> + <return type-id='type-id-452'/> + </function-decl> + <function-decl name='_PyPegen_keyword_or_starred' filepath='Parser/pegen.h' line='326' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <parameter type-id='type-id-22'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-1119'/> + </function-decl> + <function-decl name='_PyPegen_seq_extract_starred_exprs' filepath='Parser/pegen.h' line='327' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <parameter type-id='type-id-1104'/> + <return type-id='type-id-503'/> + </function-decl> + <function-decl name='_PyPegen_seq_delete_starred_exprs' filepath='Parser/pegen.h' line='328' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <parameter type-id='type-id-1104'/> + <return type-id='type-id-529'/> + </function-decl> + <function-decl name='_PyPegen_collect_call_seqs' filepath='Parser/pegen.h' line='329' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <parameter type-id='type-id-503'/> + <parameter type-id='type-id-1104'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-502'/> + </function-decl> + <function-decl name='_PyPegen_constant_from_token' filepath='Parser/pegen.h' line='332' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <parameter type-id='type-id-569'/> + <return type-id='type-id-502'/> + </function-decl> + <function-decl name='_PyPegen_decoded_constant_from_token' filepath='Parser/pegen.h' line='333' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <parameter type-id='type-id-569'/> + <return type-id='type-id-502'/> + </function-decl> + <function-decl name='_PyPegen_constant_from_string' filepath='Parser/pegen.h' line='334' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <parameter type-id='type-id-569'/> + <return type-id='type-id-502'/> + </function-decl> + <function-decl name='_PyPegen_concatenate_strings' filepath='Parser/pegen.h' line='335' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <parameter type-id='type-id-503'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-502'/> + </function-decl> + <function-decl name='_PyPegen_ensure_imaginary' filepath='Parser/pegen.h' line='337' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <parameter type-id='type-id-502'/> + <return type-id='type-id-502'/> + </function-decl> + <function-decl name='_PyPegen_ensure_real' filepath='Parser/pegen.h' line='338' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <parameter type-id='type-id-502'/> + <return type-id='type-id-502'/> + </function-decl> + <function-decl name='_PyPegen_join_sequences' filepath='Parser/pegen.h' line='339' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <parameter type-id='type-id-1104'/> + <parameter type-id='type-id-1104'/> + <return type-id='type-id-1104'/> + </function-decl> + <function-decl name='_PyPegen_check_barry_as_flufl' filepath='Parser/pegen.h' line='340' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <parameter type-id='type-id-569'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyPegen_check_legacy_stmt' filepath='Parser/pegen.h' line='341' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <parameter type-id='type-id-502'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyPegen_check_fstring_conversion' filepath='Parser/pegen.h' line='342' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <parameter type-id='type-id-569'/> + <parameter type-id='type-id-502'/> + <return type-id='type-id-1121'/> + </function-decl> + <function-decl name='_PyPegen_setup_full_format_spec' filepath='Parser/pegen.h' line='343' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <parameter type-id='type-id-569'/> + <parameter type-id='type-id-503'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-1121'/> + </function-decl> + <function-decl name='_PyPegen_make_module' filepath='Parser/pegen.h' line='345' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <parameter type-id='type-id-500'/> + <return type-id='type-id-468'/> + </function-decl> + <function-decl name='_PyPegen_arguments_parsing_error' filepath='Parser/pegen.h' line='346' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <parameter type-id='type-id-502'/> + <return type-id='type-id-22'/> + </function-decl> + <function-decl name='_PyPegen_get_last_comprehension_item' filepath='Parser/pegen.h' line='347' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1142'/> + <return type-id='type-id-502'/> + </function-decl> + <function-decl name='_PyPegen_nonparen_genexp_in_call' filepath='Parser/pegen.h' line='348' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <parameter type-id='type-id-502'/> + <parameter type-id='type-id-1141'/> + <return type-id='type-id-22'/> + </function-decl> + <function-decl name='_PyPegen_interactive_exit' filepath='Parser/pegen.h' line='358' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <return type-id='type-id-500'/> + </function-decl> + <function-decl name='_PyPegen_joined_str' filepath='Parser/pegen.h' line='361' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <parameter type-id='type-id-569'/> + <parameter type-id='type-id-503'/> + <parameter type-id='type-id-569'/> + <return type-id='type-id-502'/> + </function-decl> + <function-type size-in-bits='64' id='type-id-1124'> + <parameter type-id='type-id-568'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-569'/> + </function-type> + <function-type size-in-bits='64' id='type-id-1126'> + <parameter type-id='type-id-568'/> + <return type-id='type-id-502'/> + </function-type> + <function-type size-in-bits='64' id='type-id-1128'> + <parameter type-id='type-id-568'/> + <parameter type-id='type-id-12'/> + <return type-id='type-id-502'/> + </function-type> + <function-type size-in-bits='64' id='type-id-1130'> + <parameter type-id='type-id-568'/> + <return type-id='type-id-22'/> + </function-type> + </abi-instr> + <abi-instr address-size='64' path='Parser/peg_api.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <class-decl name='PyCompilerFlags' size-in-bits='64' is-struct='yes' naming-typedef-id='type-id-1144' visibility='default' filepath='./Include/cpython/compile.h' line='26' column='1' id='type-id-1145'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='cf_flags' type-id='type-id-8' visibility='default' filepath='./Include/cpython/compile.h' line='27' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='32'> + <var-decl name='cf_feature_version' type-id='type-id-8' visibility='default' filepath='./Include/cpython/compile.h' line='28' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='PyCompilerFlags' type-id='type-id-1145' filepath='./Include/cpython/compile.h' line='29' column='1' id='type-id-1144'/> + <pointer-type-def type-id='type-id-1144' size-in-bits='64' id='type-id-208'/> + <function-decl name='PySys_Audit' mangled-name='PySys_Audit' filepath='./Include/cpython/sysmodule.h' line='12' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySys_Audit'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-12'/> + <parameter is-variadic='yes'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyPegen_run_parser_from_file_pointer' filepath='Parser/pegen.h' line='354' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-229'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-208'/> + <parameter type-id='type-id-179'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-468'/> + </function-decl> + <function-decl name='_PyPegen_run_parser_from_string' filepath='Parser/pegen.h' line='357' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-208'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-468'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Parser/pegen.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <array-type-def dimensions='1' type-id='type-id-567' size-in-bits='64' id='type-id-1146'> + <subrange length='1' type-id='type-id-28' id='type-id-443'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-48' size-in-bits='8' id='type-id-702'> + <subrange length='1' type-id='type-id-28' id='type-id-443'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-48' size-in-bits='1600' id='type-id-1134'> + <subrange length='200' type-id='type-id-28' id='type-id-644'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-48' size-in-bits='160' id='type-id-1147'> + <subrange length='20' type-id='type-id-28' id='type-id-589'/> + </array-type-def> + <class-decl name='_IO_codecvt' is-struct='yes' visibility='default' is-declaration-only='yes' id='type-id-1148'/> + <class-decl name='_IO_marker' is-struct='yes' visibility='default' is-declaration-only='yes' id='type-id-1149'/> + <class-decl name='_IO_wide_data' is-struct='yes' visibility='default' is-declaration-only='yes' id='type-id-1150'/> + <class-decl name='__va_list_tag' size-in-bits='192' is-struct='yes' visibility='default' id='type-id-1151'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='gp_offset' type-id='type-id-95' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='32'> + <var-decl name='fp_offset' type-id='type-id-95' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='overflow_arg_area' type-id='type-id-22' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='reg_save_area' type-id='type-id-22' visibility='default'/> + </data-member> + </class-decl> + <class-decl name='_arena' is-struct='yes' visibility='default' is-declaration-only='yes' id='type-id-1152'/> + <array-type-def dimensions='1' type-id='type-id-1142' size-in-bits='64' id='type-id-1153'> + <subrange length='1' type-id='type-id-28' id='type-id-443'/> + </array-type-def> + <type-decl name='double' size-in-bits='64' id='type-id-251'/> + <array-type-def dimensions='1' type-id='type-id-502' size-in-bits='64' id='type-id-1154'> + <subrange length='1' type-id='type-id-28' id='type-id-443'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-8' size-in-bits='3200' id='type-id-1133'> + <subrange length='100' type-id='type-id-28' id='type-id-1155'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-8' size-in-bits='32' id='type-id-1156'> + <subrange length='1' type-id='type-id-28' id='type-id-443'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-8' size-in-bits='6400' id='type-id-1135'> + <subrange length='200' type-id='type-id-28' id='type-id-644'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-1143' size-in-bits='64' id='type-id-1157'> + <subrange length='1' type-id='type-id-28' id='type-id-443'/> + </array-type-def> + <type-decl name='long int' size-in-bits='64' id='type-id-47'/> + <type-decl name='signed char' size-in-bits='8' id='type-id-1037'/> + <array-type-def dimensions='1' type-id='type-id-1158' size-in-bits='115200' id='type-id-1138'> + <subrange length='150' type-id='type-id-28' id='type-id-1159'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-352' size-in-bits='64' id='type-id-1160'> + <subrange length='2' type-id='type-id-28' id='type-id-681'/> + </array-type-def> + <type-decl name='unnamed-enum-underlying-type-32' is-anonymous='yes' size-in-bits='32' alignment-in-bits='32' id='type-id-24'/> + <type-decl name='unsigned char' size-in-bits='8' id='type-id-85'/> + <type-decl name='unsigned int' size-in-bits='32' id='type-id-95'/> + <type-decl name='unsigned short int' size-in-bits='16' id='type-id-84'/> + <type-decl name='void' id='type-id-46'/> + <class-decl name='Py_complex' size-in-bits='128' is-struct='yes' naming-typedef-id='type-id-327' visibility='default' filepath='./Include/cpython/complexobject.h' line='5' column='1' id='type-id-1161'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='real' type-id='type-id-251' visibility='default' filepath='./Include/cpython/complexobject.h' line='6' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='imag' type-id='type-id-251' visibility='default' filepath='./Include/cpython/complexobject.h' line='7' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='Py_complex' type-id='type-id-1161' filepath='./Include/cpython/complexobject.h' line='8' column='1' id='type-id-327'/> + <class-decl name='PyNumberMethods' size-in-bits='2304' is-struct='yes' naming-typedef-id='type-id-1162' visibility='default' filepath='./Include/cpython/object.h' line='59' column='1' id='type-id-1163'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='nb_add' type-id='type-id-1164' visibility='default' filepath='./Include/cpython/object.h' line='64' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='nb_subtract' type-id='type-id-1164' visibility='default' filepath='./Include/cpython/object.h' line='65' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='nb_multiply' type-id='type-id-1164' visibility='default' filepath='./Include/cpython/object.h' line='66' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='nb_remainder' type-id='type-id-1164' visibility='default' filepath='./Include/cpython/object.h' line='67' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='nb_divmod' type-id='type-id-1164' visibility='default' filepath='./Include/cpython/object.h' line='68' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='nb_power' type-id='type-id-1165' visibility='default' filepath='./Include/cpython/object.h' line='69' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='384'> + <var-decl name='nb_negative' type-id='type-id-1166' visibility='default' filepath='./Include/cpython/object.h' line='70' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='448'> + <var-decl name='nb_positive' type-id='type-id-1166' visibility='default' filepath='./Include/cpython/object.h' line='71' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='512'> + <var-decl name='nb_absolute' type-id='type-id-1166' visibility='default' filepath='./Include/cpython/object.h' line='72' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='576'> + <var-decl name='nb_bool' type-id='type-id-396' visibility='default' filepath='./Include/cpython/object.h' line='73' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='640'> + <var-decl name='nb_invert' type-id='type-id-1166' visibility='default' filepath='./Include/cpython/object.h' line='74' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='704'> + <var-decl name='nb_lshift' type-id='type-id-1164' visibility='default' filepath='./Include/cpython/object.h' line='75' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='768'> + <var-decl name='nb_rshift' type-id='type-id-1164' visibility='default' filepath='./Include/cpython/object.h' line='76' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='832'> + <var-decl name='nb_and' type-id='type-id-1164' visibility='default' filepath='./Include/cpython/object.h' line='77' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='896'> + <var-decl name='nb_xor' type-id='type-id-1164' visibility='default' filepath='./Include/cpython/object.h' line='78' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='960'> + <var-decl name='nb_or' type-id='type-id-1164' visibility='default' filepath='./Include/cpython/object.h' line='79' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1024'> + <var-decl name='nb_int' type-id='type-id-1166' visibility='default' filepath='./Include/cpython/object.h' line='80' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1088'> + <var-decl name='nb_reserved' type-id='type-id-22' visibility='default' filepath='./Include/cpython/object.h' line='81' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1152'> + <var-decl name='nb_float' type-id='type-id-1166' visibility='default' filepath='./Include/cpython/object.h' line='82' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1216'> + <var-decl name='nb_inplace_add' type-id='type-id-1164' visibility='default' filepath='./Include/cpython/object.h' line='84' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1280'> + <var-decl name='nb_inplace_subtract' type-id='type-id-1164' visibility='default' filepath='./Include/cpython/object.h' line='85' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1344'> + <var-decl name='nb_inplace_multiply' type-id='type-id-1164' visibility='default' filepath='./Include/cpython/object.h' line='86' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1408'> + <var-decl name='nb_inplace_remainder' type-id='type-id-1164' visibility='default' filepath='./Include/cpython/object.h' line='87' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1472'> + <var-decl name='nb_inplace_power' type-id='type-id-1165' visibility='default' filepath='./Include/cpython/object.h' line='88' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1536'> + <var-decl name='nb_inplace_lshift' type-id='type-id-1164' visibility='default' filepath='./Include/cpython/object.h' line='89' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1600'> + <var-decl name='nb_inplace_rshift' type-id='type-id-1164' visibility='default' filepath='./Include/cpython/object.h' line='90' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1664'> + <var-decl name='nb_inplace_and' type-id='type-id-1164' visibility='default' filepath='./Include/cpython/object.h' line='91' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1728'> + <var-decl name='nb_inplace_xor' type-id='type-id-1164' visibility='default' filepath='./Include/cpython/object.h' line='92' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1792'> + <var-decl name='nb_inplace_or' type-id='type-id-1164' visibility='default' filepath='./Include/cpython/object.h' line='93' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1856'> + <var-decl name='nb_floor_divide' type-id='type-id-1164' visibility='default' filepath='./Include/cpython/object.h' line='95' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1920'> + <var-decl name='nb_true_divide' type-id='type-id-1164' visibility='default' filepath='./Include/cpython/object.h' line='96' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1984'> + <var-decl name='nb_inplace_floor_divide' type-id='type-id-1164' visibility='default' filepath='./Include/cpython/object.h' line='97' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2048'> + <var-decl name='nb_inplace_true_divide' type-id='type-id-1164' visibility='default' filepath='./Include/cpython/object.h' line='98' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2112'> + <var-decl name='nb_index' type-id='type-id-1166' visibility='default' filepath='./Include/cpython/object.h' line='100' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2176'> + <var-decl name='nb_matrix_multiply' type-id='type-id-1164' visibility='default' filepath='./Include/cpython/object.h' line='102' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2240'> + <var-decl name='nb_inplace_matrix_multiply' type-id='type-id-1164' visibility='default' filepath='./Include/cpython/object.h' line='103' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='PyNumberMethods' type-id='type-id-1163' filepath='./Include/cpython/object.h' line='104' column='1' id='type-id-1162'/> + <class-decl name='PySequenceMethods' size-in-bits='640' is-struct='yes' naming-typedef-id='type-id-1167' visibility='default' filepath='./Include/cpython/object.h' line='106' column='1' id='type-id-1168'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='sq_length' type-id='type-id-1169' visibility='default' filepath='./Include/cpython/object.h' line='107' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='sq_concat' type-id='type-id-1164' visibility='default' filepath='./Include/cpython/object.h' line='108' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='sq_repeat' type-id='type-id-1170' visibility='default' filepath='./Include/cpython/object.h' line='109' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='sq_item' type-id='type-id-1170' visibility='default' filepath='./Include/cpython/object.h' line='110' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='was_sq_slice' type-id='type-id-22' visibility='default' filepath='./Include/cpython/object.h' line='111' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='sq_ass_item' type-id='type-id-1171' visibility='default' filepath='./Include/cpython/object.h' line='112' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='384'> + <var-decl name='was_sq_ass_slice' type-id='type-id-22' visibility='default' filepath='./Include/cpython/object.h' line='113' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='448'> + <var-decl name='sq_contains' type-id='type-id-1172' visibility='default' filepath='./Include/cpython/object.h' line='114' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='512'> + <var-decl name='sq_inplace_concat' type-id='type-id-1164' visibility='default' filepath='./Include/cpython/object.h' line='116' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='576'> + <var-decl name='sq_inplace_repeat' type-id='type-id-1170' visibility='default' filepath='./Include/cpython/object.h' line='117' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='PySequenceMethods' type-id='type-id-1168' filepath='./Include/cpython/object.h' line='118' column='1' id='type-id-1167'/> + <class-decl name='PyMappingMethods' size-in-bits='192' is-struct='yes' naming-typedef-id='type-id-1173' visibility='default' filepath='./Include/cpython/object.h' line='120' column='1' id='type-id-1174'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='mp_length' type-id='type-id-1169' visibility='default' filepath='./Include/cpython/object.h' line='121' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='mp_subscript' type-id='type-id-1164' visibility='default' filepath='./Include/cpython/object.h' line='122' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='mp_ass_subscript' type-id='type-id-1175' visibility='default' filepath='./Include/cpython/object.h' line='123' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='PyMappingMethods' type-id='type-id-1174' filepath='./Include/cpython/object.h' line='124' column='1' id='type-id-1173'/> + <typedef-decl name='sendfunc' type-id='type-id-1176' filepath='./Include/cpython/object.h' line='126' column='1' id='type-id-1177'/> + <class-decl name='PyAsyncMethods' size-in-bits='256' is-struct='yes' naming-typedef-id='type-id-1178' visibility='default' filepath='./Include/cpython/object.h' line='128' column='1' id='type-id-1179'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='am_await' type-id='type-id-1166' visibility='default' filepath='./Include/cpython/object.h' line='129' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='am_aiter' type-id='type-id-1166' visibility='default' filepath='./Include/cpython/object.h' line='130' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='am_anext' type-id='type-id-1166' visibility='default' filepath='./Include/cpython/object.h' line='131' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='am_send' type-id='type-id-1177' visibility='default' filepath='./Include/cpython/object.h' line='132' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='PyAsyncMethods' type-id='type-id-1179' filepath='./Include/cpython/object.h' line='133' column='1' id='type-id-1178'/> + <class-decl name='PyBufferProcs' size-in-bits='128' is-struct='yes' naming-typedef-id='type-id-1180' visibility='default' filepath='./Include/cpython/object.h' line='135' column='1' id='type-id-1181'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='bf_getbuffer' type-id='type-id-434' visibility='default' filepath='./Include/cpython/object.h' line='136' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='bf_releasebuffer' type-id='type-id-1182' visibility='default' filepath='./Include/cpython/object.h' line='137' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='PyBufferProcs' type-id='type-id-1181' filepath='./Include/cpython/object.h' line='138' column='1' id='type-id-1180'/> + <class-decl name='_typeobject' size-in-bits='3328' is-struct='yes' visibility='default' filepath='./Include/cpython/object.h' line='146' column='1' id='type-id-1183'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='ob_base' type-id='type-id-321' visibility='default' filepath='./Include/cpython/object.h' line='147' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='tp_name' type-id='type-id-12' visibility='default' filepath='./Include/cpython/object.h' line='148' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='tp_basicsize' type-id='type-id-14' visibility='default' filepath='./Include/cpython/object.h' line='149' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='tp_itemsize' type-id='type-id-14' visibility='default' filepath='./Include/cpython/object.h' line='149' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='384'> + <var-decl name='tp_dealloc' type-id='type-id-335' visibility='default' filepath='./Include/cpython/object.h' line='153' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='448'> + <var-decl name='tp_vectorcall_offset' type-id='type-id-14' visibility='default' filepath='./Include/cpython/object.h' line='154' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='512'> + <var-decl name='tp_getattr' type-id='type-id-1184' visibility='default' filepath='./Include/cpython/object.h' line='155' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='576'> + <var-decl name='tp_setattr' type-id='type-id-1185' visibility='default' filepath='./Include/cpython/object.h' line='156' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='640'> + <var-decl name='tp_as_async' type-id='type-id-1186' visibility='default' filepath='./Include/cpython/object.h' line='157' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='704'> + <var-decl name='tp_repr' type-id='type-id-1187' visibility='default' filepath='./Include/cpython/object.h' line='159' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='768'> + <var-decl name='tp_as_number' type-id='type-id-1188' visibility='default' filepath='./Include/cpython/object.h' line='163' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='832'> + <var-decl name='tp_as_sequence' type-id='type-id-1189' visibility='default' filepath='./Include/cpython/object.h' line='164' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='896'> + <var-decl name='tp_as_mapping' type-id='type-id-1190' visibility='default' filepath='./Include/cpython/object.h' line='165' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='960'> + <var-decl name='tp_hash' type-id='type-id-1191' visibility='default' filepath='./Include/cpython/object.h' line='169' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1024'> + <var-decl name='tp_call' type-id='type-id-1165' visibility='default' filepath='./Include/cpython/object.h' line='170' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1088'> + <var-decl name='tp_str' type-id='type-id-1187' visibility='default' filepath='./Include/cpython/object.h' line='171' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1152'> + <var-decl name='tp_getattro' type-id='type-id-1192' visibility='default' filepath='./Include/cpython/object.h' line='172' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1216'> + <var-decl name='tp_setattro' type-id='type-id-1193' visibility='default' filepath='./Include/cpython/object.h' line='173' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1280'> + <var-decl name='tp_as_buffer' type-id='type-id-1194' visibility='default' filepath='./Include/cpython/object.h' line='176' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1344'> + <var-decl name='tp_flags' type-id='type-id-28' visibility='default' filepath='./Include/cpython/object.h' line='179' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1408'> + <var-decl name='tp_doc' type-id='type-id-12' visibility='default' filepath='./Include/cpython/object.h' line='181' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1472'> + <var-decl name='tp_traverse' type-id='type-id-395' visibility='default' filepath='./Include/cpython/object.h' line='185' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1536'> + <var-decl name='tp_clear' type-id='type-id-396' visibility='default' filepath='./Include/cpython/object.h' line='188' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1600'> + <var-decl name='tp_richcompare' type-id='type-id-1195' visibility='default' filepath='./Include/cpython/object.h' line='192' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1664'> + <var-decl name='tp_weaklistoffset' type-id='type-id-14' visibility='default' filepath='./Include/cpython/object.h' line='195' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1728'> + <var-decl name='tp_iter' type-id='type-id-1196' visibility='default' filepath='./Include/cpython/object.h' line='198' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1792'> + <var-decl name='tp_iternext' type-id='type-id-1197' visibility='default' filepath='./Include/cpython/object.h' line='199' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1856'> + <var-decl name='tp_methods' type-id='type-id-337' visibility='default' filepath='./Include/cpython/object.h' line='202' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1920'> + <var-decl name='tp_members' type-id='type-id-336' visibility='default' filepath='./Include/cpython/object.h' line='203' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1984'> + <var-decl name='tp_getset' type-id='type-id-338' visibility='default' filepath='./Include/cpython/object.h' line='204' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2048'> + <var-decl name='tp_base' type-id='type-id-1' visibility='default' filepath='./Include/cpython/object.h' line='206' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2112'> + <var-decl name='tp_dict' type-id='type-id-2' visibility='default' filepath='./Include/cpython/object.h' line='207' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2176'> + <var-decl name='tp_descr_get' type-id='type-id-1198' visibility='default' filepath='./Include/cpython/object.h' line='208' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2240'> + <var-decl name='tp_descr_set' type-id='type-id-1199' visibility='default' filepath='./Include/cpython/object.h' line='209' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2304'> + <var-decl name='tp_dictoffset' type-id='type-id-14' visibility='default' filepath='./Include/cpython/object.h' line='210' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2368'> + <var-decl name='tp_init' type-id='type-id-1200' visibility='default' filepath='./Include/cpython/object.h' line='211' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2432'> + <var-decl name='tp_alloc' type-id='type-id-1201' visibility='default' filepath='./Include/cpython/object.h' line='212' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2496'> + <var-decl name='tp_new' type-id='type-id-1202' visibility='default' filepath='./Include/cpython/object.h' line='213' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2560'> + <var-decl name='tp_free' type-id='type-id-397' visibility='default' filepath='./Include/cpython/object.h' line='214' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2624'> + <var-decl name='tp_is_gc' type-id='type-id-396' visibility='default' filepath='./Include/cpython/object.h' line='215' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2688'> + <var-decl name='tp_bases' type-id='type-id-2' visibility='default' filepath='./Include/cpython/object.h' line='216' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2752'> + <var-decl name='tp_mro' type-id='type-id-2' visibility='default' filepath='./Include/cpython/object.h' line='217' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2816'> + <var-decl name='tp_cache' type-id='type-id-2' visibility='default' filepath='./Include/cpython/object.h' line='218' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2880'> + <var-decl name='tp_subclasses' type-id='type-id-22' visibility='default' filepath='./Include/cpython/object.h' line='219' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='2944'> + <var-decl name='tp_weaklist' type-id='type-id-2' visibility='default' filepath='./Include/cpython/object.h' line='220' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='3008'> + <var-decl name='tp_del' type-id='type-id-335' visibility='default' filepath='./Include/cpython/object.h' line='221' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='3072'> + <var-decl name='tp_version_tag' type-id='type-id-95' visibility='default' filepath='./Include/cpython/object.h' line='224' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='3136'> + <var-decl name='tp_finalize' type-id='type-id-335' visibility='default' filepath='./Include/cpython/object.h' line='226' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='3200'> + <var-decl name='tp_vectorcall' type-id='type-id-311' visibility='default' filepath='./Include/cpython/object.h' line='227' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='3264'> + <var-decl name='tp_watched' type-id='type-id-85' visibility='default' filepath='./Include/cpython/object.h' line='230' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='getter' type-id='type-id-732' filepath='./Include/descrobject.h' line='8' column='1' id='type-id-1203'/> + <typedef-decl name='setter' type-id='type-id-1204' filepath='./Include/descrobject.h' line='9' column='1' id='type-id-1205'/> + <class-decl name='PyGetSetDef' size-in-bits='320' is-struct='yes' visibility='default' filepath='./Include/descrobject.h' line='11' column='1' id='type-id-1206'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='name' type-id='type-id-12' visibility='default' filepath='./Include/descrobject.h' line='12' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='get' type-id='type-id-1203' visibility='default' filepath='./Include/descrobject.h' line='13' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='set' type-id='type-id-1205' visibility='default' filepath='./Include/descrobject.h' line='14' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='doc' type-id='type-id-12' visibility='default' filepath='./Include/descrobject.h' line='15' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='closure' type-id='type-id-22' visibility='default' filepath='./Include/descrobject.h' line='16' column='1'/> + </data-member> + </class-decl> + <class-decl name='PyMemberDef' size-in-bits='320' is-struct='yes' visibility='default' filepath='./Include/descrobject.h' line='41' column='1' id='type-id-1207'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='name' type-id='type-id-12' visibility='default' filepath='./Include/descrobject.h' line='42' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='type' type-id='type-id-8' visibility='default' filepath='./Include/descrobject.h' line='43' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='offset' type-id='type-id-14' visibility='default' filepath='./Include/descrobject.h' line='44' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='flags' type-id='type-id-8' visibility='default' filepath='./Include/descrobject.h' line='45' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='doc' type-id='type-id-12' visibility='default' filepath='./Include/descrobject.h' line='46' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='identifier' type-id='type-id-2' filepath='./Include/internal/pycore_asdl.h' line='13' column='1' id='type-id-525'/> + <typedef-decl name='string' type-id='type-id-2' filepath='./Include/internal/pycore_asdl.h' line='14' column='1' id='type-id-527'/> + <typedef-decl name='constant' type-id='type-id-2' filepath='./Include/internal/pycore_asdl.h' line='16' column='1' id='type-id-552'/> + <class-decl name='asdl_int_seq' size-in-bits='192' is-struct='yes' naming-typedef-id='type-id-1208' visibility='default' filepath='./Include/internal/pycore_asdl.h' line='42' column='1' id='type-id-1209'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='size' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_asdl.h' line='43' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='elements' type-id='type-id-253' visibility='default' filepath='./Include/internal/pycore_asdl.h' line='43' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='typed_elements' type-id='type-id-1156' visibility='default' filepath='./Include/internal/pycore_asdl.h' line='44' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='asdl_int_seq' type-id='type-id-1209' filepath='./Include/internal/pycore_asdl.h' line='45' column='1' id='type-id-1208'/> + <typedef-decl name='expr_ty' type-id='type-id-1210' filepath='./Include/internal/pycore_ast.h' line='19' column='1' id='type-id-502'/> + <enum-decl name='_expr_context' filepath='./Include/internal/pycore_ast.h' line='21' column='1' id='type-id-1211'> + <underlying-type type-id='type-id-24'/> + <enumerator name='Load' value='1'/> + <enumerator name='Store' value='2'/> + <enumerator name='Del' value='3'/> + </enum-decl> + <typedef-decl name='expr_context_ty' type-id='type-id-1211' filepath='./Include/internal/pycore_ast.h' line='21' column='1' id='type-id-566'/> + <enum-decl name='_boolop' filepath='./Include/internal/pycore_ast.h' line='23' column='1' id='type-id-1212'> + <underlying-type type-id='type-id-24'/> + <enumerator name='And' value='1'/> + <enumerator name='Or' value='2'/> + </enum-decl> + <typedef-decl name='boolop_ty' type-id='type-id-1212' filepath='./Include/internal/pycore_ast.h' line='23' column='1' id='type-id-1139'/> + <enum-decl name='_operator' filepath='./Include/internal/pycore_ast.h' line='25' column='1' id='type-id-1213'> + <underlying-type type-id='type-id-24'/> + <enumerator name='Add' value='1'/> + <enumerator name='Sub' value='2'/> + <enumerator name='Mult' value='3'/> + <enumerator name='MatMult' value='4'/> + <enumerator name='Div' value='5'/> + <enumerator name='Mod' value='6'/> + <enumerator name='Pow' value='7'/> + <enumerator name='LShift' value='8'/> + <enumerator name='RShift' value='9'/> + <enumerator name='BitOr' value='10'/> + <enumerator name='BitXor' value='11'/> + <enumerator name='BitAnd' value='12'/> + <enumerator name='FloorDiv' value='13'/> + </enum-decl> + <typedef-decl name='operator_ty' type-id='type-id-1213' filepath='./Include/internal/pycore_ast.h' line='27' column='1' id='type-id-530'/> + <enum-decl name='_unaryop' filepath='./Include/internal/pycore_ast.h' line='29' column='1' id='type-id-1214'> + <underlying-type type-id='type-id-24'/> + <enumerator name='Invert' value='1'/> + <enumerator name='Not' value='2'/> + <enumerator name='UAdd' value='3'/> + <enumerator name='USub' value='4'/> + </enum-decl> + <typedef-decl name='unaryop_ty' type-id='type-id-1214' filepath='./Include/internal/pycore_ast.h' line='29' column='1' id='type-id-1140'/> + <typedef-decl name='comprehension_ty' type-id='type-id-1215' filepath='./Include/internal/pycore_ast.h' line='34' column='1' id='type-id-1142'/> + <typedef-decl name='arguments_ty' type-id='type-id-1216' filepath='./Include/internal/pycore_ast.h' line='38' column='1' id='type-id-526'/> + <typedef-decl name='arg_ty' type-id='type-id-1217' filepath='./Include/internal/pycore_ast.h' line='40' column='1' id='type-id-567'/> + <typedef-decl name='keyword_ty' type-id='type-id-1218' filepath='./Include/internal/pycore_ast.h' line='42' column='1' id='type-id-1143'/> + <class-decl name='asdl_expr_seq' size-in-bits='192' is-struct='yes' naming-typedef-id='type-id-1219' visibility='default' filepath='./Include/internal/pycore_ast.h' line='71' column='1' id='type-id-1220'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='size' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast.h' line='72' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='elements' type-id='type-id-253' visibility='default' filepath='./Include/internal/pycore_ast.h' line='72' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='typed_elements' type-id='type-id-1154' visibility='default' filepath='./Include/internal/pycore_ast.h' line='73' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='asdl_expr_seq' type-id='type-id-1220' filepath='./Include/internal/pycore_ast.h' line='74' column='1' id='type-id-1219'/> + <class-decl name='asdl_comprehension_seq' size-in-bits='192' is-struct='yes' naming-typedef-id='type-id-1221' visibility='default' filepath='./Include/internal/pycore_ast.h' line='78' column='1' id='type-id-1222'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='size' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast.h' line='79' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='elements' type-id='type-id-253' visibility='default' filepath='./Include/internal/pycore_ast.h' line='79' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='typed_elements' type-id='type-id-1153' visibility='default' filepath='./Include/internal/pycore_ast.h' line='80' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='asdl_comprehension_seq' type-id='type-id-1222' filepath='./Include/internal/pycore_ast.h' line='81' column='1' id='type-id-1221'/> + <class-decl name='asdl_arg_seq' size-in-bits='192' is-struct='yes' naming-typedef-id='type-id-1223' visibility='default' filepath='./Include/internal/pycore_ast.h' line='101' column='1' id='type-id-1224'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='size' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast.h' line='102' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='elements' type-id='type-id-253' visibility='default' filepath='./Include/internal/pycore_ast.h' line='102' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='typed_elements' type-id='type-id-1146' visibility='default' filepath='./Include/internal/pycore_ast.h' line='103' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='asdl_arg_seq' type-id='type-id-1224' filepath='./Include/internal/pycore_ast.h' line='104' column='1' id='type-id-1223'/> + <class-decl name='asdl_keyword_seq' size-in-bits='192' is-struct='yes' naming-typedef-id='type-id-1225' visibility='default' filepath='./Include/internal/pycore_ast.h' line='108' column='1' id='type-id-1226'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='size' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_ast.h' line='109' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='elements' type-id='type-id-253' visibility='default' filepath='./Include/internal/pycore_ast.h' line='109' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='typed_elements' type-id='type-id-1157' visibility='default' filepath='./Include/internal/pycore_ast.h' line='110' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='asdl_keyword_seq' type-id='type-id-1226' filepath='./Include/internal/pycore_ast.h' line='111' column='1' id='type-id-1225'/> + <enum-decl name='_expr_kind' filepath='./Include/internal/pycore_ast.h' line='359' column='1' id='type-id-1227'> + <underlying-type type-id='type-id-24'/> + <enumerator name='BoolOp_kind' value='1'/> + <enumerator name='NamedExpr_kind' value='2'/> + <enumerator name='BinOp_kind' value='3'/> + <enumerator name='UnaryOp_kind' value='4'/> + <enumerator name='Lambda_kind' value='5'/> + <enumerator name='IfExp_kind' value='6'/> + <enumerator name='Dict_kind' value='7'/> + <enumerator name='Set_kind' value='8'/> + <enumerator name='ListComp_kind' value='9'/> + <enumerator name='SetComp_kind' value='10'/> + <enumerator name='DictComp_kind' value='11'/> + <enumerator name='GeneratorExp_kind' value='12'/> + <enumerator name='Await_kind' value='13'/> + <enumerator name='Yield_kind' value='14'/> + <enumerator name='YieldFrom_kind' value='15'/> + <enumerator name='Compare_kind' value='16'/> + <enumerator name='Call_kind' value='17'/> + <enumerator name='FormattedValue_kind' value='18'/> + <enumerator name='JoinedStr_kind' value='19'/> + <enumerator name='Constant_kind' value='20'/> + <enumerator name='Attribute_kind' value='21'/> + <enumerator name='Subscript_kind' value='22'/> + <enumerator name='Starred_kind' value='23'/> + <enumerator name='Name_kind' value='24'/> + <enumerator name='List_kind' value='25'/> + <enumerator name='Tuple_kind' value='26'/> + <enumerator name='Slice_kind' value='27'/> + </enum-decl> + <class-decl name='_expr' size-in-bits='384' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='367' column='1' id='type-id-963'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='kind' type-id='type-id-1227' visibility='default' filepath='./Include/internal/pycore_ast.h' line='368' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='v' type-id='type-id-1228' visibility='default' filepath='./Include/internal/pycore_ast.h' line='509' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='lineno' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='510' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='288'> + <var-decl name='col_offset' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='511' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='end_lineno' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='512' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='352'> + <var-decl name='end_col_offset' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='513' column='1'/> + </data-member> + </class-decl> + <union-decl name='__anonymous_union__1' size-in-bits='192' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='369' column='1' id='type-id-1228'> + <data-member access='public'> + <var-decl name='BoolOp' type-id='type-id-1229' visibility='default' filepath='./Include/internal/pycore_ast.h' line='373' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='NamedExpr' type-id='type-id-1230' visibility='default' filepath='./Include/internal/pycore_ast.h' line='378' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='BinOp' type-id='type-id-1231' visibility='default' filepath='./Include/internal/pycore_ast.h' line='384' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='UnaryOp' type-id='type-id-1232' visibility='default' filepath='./Include/internal/pycore_ast.h' line='389' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='Lambda' type-id='type-id-1233' visibility='default' filepath='./Include/internal/pycore_ast.h' line='394' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='IfExp' type-id='type-id-1234' visibility='default' filepath='./Include/internal/pycore_ast.h' line='400' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='Dict' type-id='type-id-1235' visibility='default' filepath='./Include/internal/pycore_ast.h' line='405' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='Set' type-id='type-id-1236' visibility='default' filepath='./Include/internal/pycore_ast.h' line='409' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='ListComp' type-id='type-id-1237' visibility='default' filepath='./Include/internal/pycore_ast.h' line='414' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='SetComp' type-id='type-id-1237' visibility='default' filepath='./Include/internal/pycore_ast.h' line='419' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='DictComp' type-id='type-id-1238' visibility='default' filepath='./Include/internal/pycore_ast.h' line='425' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='GeneratorExp' type-id='type-id-1237' visibility='default' filepath='./Include/internal/pycore_ast.h' line='430' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='Await' type-id='type-id-509' visibility='default' filepath='./Include/internal/pycore_ast.h' line='434' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='Yield' type-id='type-id-509' visibility='default' filepath='./Include/internal/pycore_ast.h' line='438' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='YieldFrom' type-id='type-id-509' visibility='default' filepath='./Include/internal/pycore_ast.h' line='442' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='Compare' type-id='type-id-1239' visibility='default' filepath='./Include/internal/pycore_ast.h' line='448' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='Call' type-id='type-id-1240' visibility='default' filepath='./Include/internal/pycore_ast.h' line='454' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='FormattedValue' type-id='type-id-1241' visibility='default' filepath='./Include/internal/pycore_ast.h' line='460' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='JoinedStr' type-id='type-id-1242' visibility='default' filepath='./Include/internal/pycore_ast.h' line='464' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='Constant' type-id='type-id-1243' visibility='default' filepath='./Include/internal/pycore_ast.h' line='469' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='Attribute' type-id='type-id-1244' visibility='default' filepath='./Include/internal/pycore_ast.h' line='475' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='Subscript' type-id='type-id-1245' visibility='default' filepath='./Include/internal/pycore_ast.h' line='481' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='Starred' type-id='type-id-1246' visibility='default' filepath='./Include/internal/pycore_ast.h' line='486' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='Name' type-id='type-id-1247' visibility='default' filepath='./Include/internal/pycore_ast.h' line='491' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='List' type-id='type-id-1248' visibility='default' filepath='./Include/internal/pycore_ast.h' line='496' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='Tuple' type-id='type-id-1248' visibility='default' filepath='./Include/internal/pycore_ast.h' line='501' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='Slice' type-id='type-id-1249' visibility='default' filepath='./Include/internal/pycore_ast.h' line='507' column='1'/> + </data-member> + </union-decl> + <class-decl name='__anonymous_struct__1' size-in-bits='128' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='370' column='1' id='type-id-1229'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='op' type-id='type-id-1139' visibility='default' filepath='./Include/internal/pycore_ast.h' line='371' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='values' type-id='type-id-503' visibility='default' filepath='./Include/internal/pycore_ast.h' line='372' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__2' size-in-bits='128' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='375' column='1' id='type-id-1230'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='target' type-id='type-id-502' visibility='default' filepath='./Include/internal/pycore_ast.h' line='376' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='value' type-id='type-id-502' visibility='default' filepath='./Include/internal/pycore_ast.h' line='377' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__3' size-in-bits='192' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='380' column='1' id='type-id-1231'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='left' type-id='type-id-502' visibility='default' filepath='./Include/internal/pycore_ast.h' line='381' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='op' type-id='type-id-530' visibility='default' filepath='./Include/internal/pycore_ast.h' line='382' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='right' type-id='type-id-502' visibility='default' filepath='./Include/internal/pycore_ast.h' line='383' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__4' size-in-bits='128' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='386' column='1' id='type-id-1232'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='op' type-id='type-id-1140' visibility='default' filepath='./Include/internal/pycore_ast.h' line='387' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='operand' type-id='type-id-502' visibility='default' filepath='./Include/internal/pycore_ast.h' line='388' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__5' size-in-bits='128' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='391' column='1' id='type-id-1233'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='args' type-id='type-id-526' visibility='default' filepath='./Include/internal/pycore_ast.h' line='392' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='body' type-id='type-id-502' visibility='default' filepath='./Include/internal/pycore_ast.h' line='393' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__6' size-in-bits='192' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='396' column='1' id='type-id-1234'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='test' type-id='type-id-502' visibility='default' filepath='./Include/internal/pycore_ast.h' line='397' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='body' type-id='type-id-502' visibility='default' filepath='./Include/internal/pycore_ast.h' line='398' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='orelse' type-id='type-id-502' visibility='default' filepath='./Include/internal/pycore_ast.h' line='399' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__7' size-in-bits='128' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='402' column='1' id='type-id-1235'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='keys' type-id='type-id-503' visibility='default' filepath='./Include/internal/pycore_ast.h' line='403' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='values' type-id='type-id-503' visibility='default' filepath='./Include/internal/pycore_ast.h' line='404' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__8' size-in-bits='64' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='407' column='1' id='type-id-1236'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='elts' type-id='type-id-503' visibility='default' filepath='./Include/internal/pycore_ast.h' line='408' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__9' size-in-bits='128' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='411' column='1' id='type-id-1237'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='elt' type-id='type-id-502' visibility='default' filepath='./Include/internal/pycore_ast.h' line='412' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='generators' type-id='type-id-1141' visibility='default' filepath='./Include/internal/pycore_ast.h' line='413' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__11' size-in-bits='192' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='421' column='1' id='type-id-1238'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='key' type-id='type-id-502' visibility='default' filepath='./Include/internal/pycore_ast.h' line='422' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='value' type-id='type-id-502' visibility='default' filepath='./Include/internal/pycore_ast.h' line='423' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='generators' type-id='type-id-1141' visibility='default' filepath='./Include/internal/pycore_ast.h' line='424' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__13' size-in-bits='64' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='432' column='1' id='type-id-509'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='value' type-id='type-id-502' visibility='default' filepath='./Include/internal/pycore_ast.h' line='433' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__16' size-in-bits='192' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='444' column='1' id='type-id-1239'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='left' type-id='type-id-502' visibility='default' filepath='./Include/internal/pycore_ast.h' line='445' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='ops' type-id='type-id-564' visibility='default' filepath='./Include/internal/pycore_ast.h' line='446' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='comparators' type-id='type-id-503' visibility='default' filepath='./Include/internal/pycore_ast.h' line='447' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__17' size-in-bits='192' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='450' column='1' id='type-id-1240'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='func' type-id='type-id-502' visibility='default' filepath='./Include/internal/pycore_ast.h' line='451' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='args' type-id='type-id-503' visibility='default' filepath='./Include/internal/pycore_ast.h' line='452' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='keywords' type-id='type-id-529' visibility='default' filepath='./Include/internal/pycore_ast.h' line='453' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__18' size-in-bits='192' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='456' column='1' id='type-id-1241'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='value' type-id='type-id-502' visibility='default' filepath='./Include/internal/pycore_ast.h' line='457' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='conversion' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='458' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='format_spec' type-id='type-id-502' visibility='default' filepath='./Include/internal/pycore_ast.h' line='459' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__19' size-in-bits='64' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='462' column='1' id='type-id-1242'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='values' type-id='type-id-503' visibility='default' filepath='./Include/internal/pycore_ast.h' line='463' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__20' size-in-bits='128' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='466' column='1' id='type-id-1243'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='value' type-id='type-id-552' visibility='default' filepath='./Include/internal/pycore_ast.h' line='467' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='kind' type-id='type-id-527' visibility='default' filepath='./Include/internal/pycore_ast.h' line='468' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__21' size-in-bits='192' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='471' column='1' id='type-id-1244'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='value' type-id='type-id-502' visibility='default' filepath='./Include/internal/pycore_ast.h' line='472' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='attr' type-id='type-id-525' visibility='default' filepath='./Include/internal/pycore_ast.h' line='473' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='ctx' type-id='type-id-566' visibility='default' filepath='./Include/internal/pycore_ast.h' line='474' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__22' size-in-bits='192' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='477' column='1' id='type-id-1245'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='value' type-id='type-id-502' visibility='default' filepath='./Include/internal/pycore_ast.h' line='478' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='slice' type-id='type-id-502' visibility='default' filepath='./Include/internal/pycore_ast.h' line='479' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='ctx' type-id='type-id-566' visibility='default' filepath='./Include/internal/pycore_ast.h' line='480' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__23' size-in-bits='128' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='483' column='1' id='type-id-1246'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='value' type-id='type-id-502' visibility='default' filepath='./Include/internal/pycore_ast.h' line='484' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='ctx' type-id='type-id-566' visibility='default' filepath='./Include/internal/pycore_ast.h' line='485' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__24' size-in-bits='128' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='488' column='1' id='type-id-1247'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='id' type-id='type-id-525' visibility='default' filepath='./Include/internal/pycore_ast.h' line='489' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='ctx' type-id='type-id-566' visibility='default' filepath='./Include/internal/pycore_ast.h' line='490' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__25' size-in-bits='128' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='493' column='1' id='type-id-1248'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='elts' type-id='type-id-503' visibility='default' filepath='./Include/internal/pycore_ast.h' line='494' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='ctx' type-id='type-id-566' visibility='default' filepath='./Include/internal/pycore_ast.h' line='495' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__27' size-in-bits='192' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='503' column='1' id='type-id-1249'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='lower' type-id='type-id-502' visibility='default' filepath='./Include/internal/pycore_ast.h' line='504' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='upper' type-id='type-id-502' visibility='default' filepath='./Include/internal/pycore_ast.h' line='505' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='step' type-id='type-id-502' visibility='default' filepath='./Include/internal/pycore_ast.h' line='506' column='1'/> + </data-member> + </class-decl> + <class-decl name='_comprehension' size-in-bits='256' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='516' column='1' id='type-id-1250'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='target' type-id='type-id-502' visibility='default' filepath='./Include/internal/pycore_ast.h' line='517' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='iter' type-id='type-id-502' visibility='default' filepath='./Include/internal/pycore_ast.h' line='518' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='ifs' type-id='type-id-503' visibility='default' filepath='./Include/internal/pycore_ast.h' line='519' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='is_async' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='520' column='1'/> + </data-member> + </class-decl> + <class-decl name='_arguments' size-in-bits='448' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='540' column='1' id='type-id-1251'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='posonlyargs' type-id='type-id-565' visibility='default' filepath='./Include/internal/pycore_ast.h' line='541' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='args' type-id='type-id-565' visibility='default' filepath='./Include/internal/pycore_ast.h' line='542' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='vararg' type-id='type-id-567' visibility='default' filepath='./Include/internal/pycore_ast.h' line='543' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='kwonlyargs' type-id='type-id-565' visibility='default' filepath='./Include/internal/pycore_ast.h' line='544' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='kw_defaults' type-id='type-id-503' visibility='default' filepath='./Include/internal/pycore_ast.h' line='545' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='kwarg' type-id='type-id-567' visibility='default' filepath='./Include/internal/pycore_ast.h' line='546' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='384'> + <var-decl name='defaults' type-id='type-id-503' visibility='default' filepath='./Include/internal/pycore_ast.h' line='547' column='1'/> + </data-member> + </class-decl> + <class-decl name='_arg' size-in-bits='320' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='550' column='1' id='type-id-1252'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='arg' type-id='type-id-525' visibility='default' filepath='./Include/internal/pycore_ast.h' line='551' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='annotation' type-id='type-id-502' visibility='default' filepath='./Include/internal/pycore_ast.h' line='552' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='type_comment' type-id='type-id-527' visibility='default' filepath='./Include/internal/pycore_ast.h' line='553' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='lineno' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='554' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='224'> + <var-decl name='col_offset' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='555' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='end_lineno' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='556' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='288'> + <var-decl name='end_col_offset' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='557' column='1'/> + </data-member> + </class-decl> + <class-decl name='_keyword' size-in-bits='256' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_ast.h' line='560' column='1' id='type-id-1253'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='arg' type-id='type-id-525' visibility='default' filepath='./Include/internal/pycore_ast.h' line='561' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='value' type-id='type-id-502' visibility='default' filepath='./Include/internal/pycore_ast.h' line='562' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='lineno' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='563' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='160'> + <var-decl name='col_offset' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='564' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='end_lineno' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='565' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='224'> + <var-decl name='end_col_offset' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_ast.h' line='566' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='PyArena' type-id='type-id-1152' filepath='./Include/internal/pycore_pyarena.h' line='14' column='1' id='type-id-1254'/> + <typedef-decl name='PyCFunction' type-id='type-id-1255' filepath='./Include/methodobject.h' line='19' column='1' id='type-id-388'/> + <class-decl name='PyMethodDef' size-in-bits='256' is-struct='yes' visibility='default' filepath='./Include/methodobject.h' line='54' column='1' id='type-id-1256'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='ml_name' type-id='type-id-12' visibility='default' filepath='./Include/methodobject.h' line='55' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='ml_meth' type-id='type-id-388' visibility='default' filepath='./Include/methodobject.h' line='56' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='ml_flags' type-id='type-id-8' visibility='default' filepath='./Include/methodobject.h' line='57' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='ml_doc' type-id='type-id-12' visibility='default' filepath='./Include/methodobject.h' line='59' column='1'/> + </data-member> + </class-decl> + <class-decl name='_object' size-in-bits='128' is-struct='yes' visibility='default' filepath='./Include/object.h' line='166' column='1' id='type-id-1257'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='' type-id='type-id-1258' visibility='default'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='ob_type' type-id='type-id-1' visibility='default' filepath='./Include/object.h' line='190' column='1'/> + </data-member> + </class-decl> + <union-decl name='__anonymous_union__' size-in-bits='64' is-anonymous='yes' visibility='default' filepath='./Include/object.h' line='180' column='1' id='type-id-1258'> + <data-member access='public'> + <var-decl name='ob_refcnt' type-id='type-id-14' visibility='default' filepath='./Include/object.h' line='181' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='ob_refcnt_split' type-id='type-id-1160' visibility='default' filepath='./Include/object.h' line='183' column='1'/> + </data-member> + </union-decl> + <class-decl name='PyVarObject' size-in-bits='192' is-struct='yes' naming-typedef-id='type-id-321' visibility='default' filepath='./Include/object.h' line='196' column='1' id='type-id-1259'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='ob_base' type-id='type-id-345' visibility='default' filepath='./Include/object.h' line='197' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='ob_size' type-id='type-id-14' visibility='default' filepath='./Include/object.h' line='198' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='PyVarObject' type-id='type-id-1259' filepath='./Include/object.h' line='199' column='1' id='type-id-321'/> + <typedef-decl name='unaryfunc' type-id='type-id-1260' filepath='./Include/object.h' line='305' column='1' id='type-id-1166'/> + <typedef-decl name='binaryfunc' type-id='type-id-1255' filepath='./Include/object.h' line='306' column='1' id='type-id-1164'/> + <typedef-decl name='ternaryfunc' type-id='type-id-1261' filepath='./Include/object.h' line='307' column='1' id='type-id-1165'/> + <typedef-decl name='inquiry' type-id='type-id-339' filepath='./Include/object.h' line='308' column='1' id='type-id-396'/> + <typedef-decl name='lenfunc' type-id='type-id-1262' filepath='./Include/object.h' line='309' column='1' id='type-id-1169'/> + <typedef-decl name='ssizeargfunc' type-id='type-id-1263' filepath='./Include/object.h' line='310' column='1' id='type-id-1170'/> + <typedef-decl name='ssizeobjargproc' type-id='type-id-1264' filepath='./Include/object.h' line='312' column='1' id='type-id-1171'/> + <typedef-decl name='objobjargproc' type-id='type-id-1265' filepath='./Include/object.h' line='314' column='1' id='type-id-1175'/> + <typedef-decl name='objobjproc' type-id='type-id-1266' filepath='./Include/object.h' line='316' column='1' id='type-id-1172'/> + <typedef-decl name='visitproc' type-id='type-id-236' filepath='./Include/object.h' line='317' column='1' id='type-id-341'/> + <typedef-decl name='traverseproc' type-id='type-id-1267' filepath='./Include/object.h' line='318' column='1' id='type-id-395'/> + <typedef-decl name='freefunc' type-id='type-id-760' filepath='./Include/object.h' line='321' column='1' id='type-id-397'/> + <typedef-decl name='destructor' type-id='type-id-312' filepath='./Include/object.h' line='322' column='1' id='type-id-335'/> + <typedef-decl name='getattrfunc' type-id='type-id-1268' filepath='./Include/object.h' line='323' column='1' id='type-id-1184'/> + <typedef-decl name='getattrofunc' type-id='type-id-1255' filepath='./Include/object.h' line='324' column='1' id='type-id-1192'/> + <typedef-decl name='setattrfunc' type-id='type-id-1269' filepath='./Include/object.h' line='325' column='1' id='type-id-1185'/> + <typedef-decl name='setattrofunc' type-id='type-id-1265' filepath='./Include/object.h' line='326' column='1' id='type-id-1193'/> + <typedef-decl name='reprfunc' type-id='type-id-1260' filepath='./Include/object.h' line='327' column='1' id='type-id-1187'/> + <typedef-decl name='hashfunc' type-id='type-id-1270' filepath='./Include/object.h' line='328' column='1' id='type-id-1191'/> + <typedef-decl name='richcmpfunc' type-id='type-id-1271' filepath='./Include/object.h' line='329' column='1' id='type-id-1195'/> + <typedef-decl name='getiterfunc' type-id='type-id-1260' filepath='./Include/object.h' line='330' column='1' id='type-id-1196'/> + <typedef-decl name='iternextfunc' type-id='type-id-1260' filepath='./Include/object.h' line='331' column='1' id='type-id-1197'/> + <typedef-decl name='descrgetfunc' type-id='type-id-1261' filepath='./Include/object.h' line='332' column='1' id='type-id-1198'/> + <typedef-decl name='descrsetfunc' type-id='type-id-1265' filepath='./Include/object.h' line='333' column='1' id='type-id-1199'/> + <typedef-decl name='initproc' type-id='type-id-1265' filepath='./Include/object.h' line='334' column='1' id='type-id-1200'/> + <typedef-decl name='newfunc' type-id='type-id-1272' filepath='./Include/object.h' line='335' column='1' id='type-id-1202'/> + <typedef-decl name='allocfunc' type-id='type-id-1273' filepath='./Include/object.h' line='336' column='1' id='type-id-1201'/> + <typedef-decl name='vectorcallfunc' type-id='type-id-1274' filepath='./Include/object.h' line='339' column='1' id='type-id-311'/> + <enum-decl name='PySendResult' naming-typedef-id='type-id-255' filepath='./Include/object.h' line='875' column='1' id='type-id-1275'> + <underlying-type type-id='type-id-24'/> + <enumerator name='PYGEN_RETURN' value='0'/> + <enumerator name='PYGEN_ERROR' value='-1'/> + <enumerator name='PYGEN_NEXT' value='1'/> + </enum-decl> + <typedef-decl name='PySendResult' type-id='type-id-1275' filepath='./Include/object.h' line='879' column='1' id='type-id-255'/> + <class-decl name='Py_buffer' size-in-bits='640' is-struct='yes' naming-typedef-id='type-id-243' visibility='default' filepath='./Include/pybuffer.h' line='20' column='1' id='type-id-1276'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='buf' type-id='type-id-22' visibility='default' filepath='./Include/pybuffer.h' line='21' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='obj' type-id='type-id-2' visibility='default' filepath='./Include/pybuffer.h' line='22' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='len' type-id='type-id-14' visibility='default' filepath='./Include/pybuffer.h' line='23' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='itemsize' type-id='type-id-14' visibility='default' filepath='./Include/pybuffer.h' line='24' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='readonly' type-id='type-id-8' visibility='default' filepath='./Include/pybuffer.h' line='26' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='288'> + <var-decl name='ndim' type-id='type-id-8' visibility='default' filepath='./Include/pybuffer.h' line='27' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='format' type-id='type-id-15' visibility='default' filepath='./Include/pybuffer.h' line='28' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='384'> + <var-decl name='shape' type-id='type-id-13' visibility='default' filepath='./Include/pybuffer.h' line='29' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='448'> + <var-decl name='strides' type-id='type-id-13' visibility='default' filepath='./Include/pybuffer.h' line='30' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='512'> + <var-decl name='suboffsets' type-id='type-id-13' visibility='default' filepath='./Include/pybuffer.h' line='31' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='576'> + <var-decl name='internal' type-id='type-id-22' visibility='default' filepath='./Include/pybuffer.h' line='32' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='Py_buffer' type-id='type-id-1276' filepath='./Include/pybuffer.h' line='33' column='1' id='type-id-243'/> + <typedef-decl name='getbufferproc' type-id='type-id-1277' filepath='./Include/pybuffer.h' line='35' column='1' id='type-id-434'/> + <typedef-decl name='releasebufferproc' type-id='type-id-1278' filepath='./Include/pybuffer.h' line='36' column='1' id='type-id-1182'/> + <typedef-decl name='Py_ssize_t' type-id='type-id-185' filepath='./Include/pyport.h' line='131' column='1' id='type-id-14'/> + <typedef-decl name='Py_hash_t' type-id='type-id-14' filepath='./Include/pyport.h' line='145' column='1' id='type-id-305'/> + <typedef-decl name='PyMethodDef' type-id='type-id-1256' filepath='./Include/pytypedefs.h' line='14' column='1' id='type-id-1279'/> + <typedef-decl name='PyGetSetDef' type-id='type-id-1206' filepath='./Include/pytypedefs.h' line='15' column='1' id='type-id-1280'/> + <typedef-decl name='PyMemberDef' type-id='type-id-1207' filepath='./Include/pytypedefs.h' line='16' column='1' id='type-id-1281'/> + <typedef-decl name='PyObject' type-id='type-id-1257' filepath='./Include/pytypedefs.h' line='18' column='1' id='type-id-345'/> + <typedef-decl name='PyTypeObject' type-id='type-id-1183' filepath='./Include/pytypedefs.h' line='20' column='1' id='type-id-256'/> + <typedef-decl name='uint32_t' type-id='type-id-1054' filepath='/usr/include/x86_64-linux-gnu/bits/stdint-uintn.h' line='26' column='1' id='type-id-352'/> + <typedef-decl name='__uint32_t' type-id='type-id-95' filepath='/usr/include/x86_64-linux-gnu/bits/types.h' line='42' column='1' id='type-id-1054'/> + <typedef-decl name='__off_t' type-id='type-id-47' filepath='/usr/include/x86_64-linux-gnu/bits/types.h' line='152' column='1' id='type-id-1282'/> + <typedef-decl name='__off64_t' type-id='type-id-47' filepath='/usr/include/x86_64-linux-gnu/bits/types.h' line='153' column='1' id='type-id-9'/> + <typedef-decl name='__ssize_t' type-id='type-id-47' filepath='/usr/include/x86_64-linux-gnu/bits/types.h' line='194' column='1' id='type-id-186'/> + <typedef-decl name='FILE' type-id='type-id-1283' filepath='/usr/include/x86_64-linux-gnu/bits/types/FILE.h' line='7' column='1' id='type-id-1284'/> + <typedef-decl name='_IO_lock_t' type-id='type-id-46' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h' line='43' column='1' id='type-id-1285'/> + <class-decl name='_IO_FILE' size-in-bits='1728' is-struct='yes' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h' line='49' column='1' id='type-id-1283'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='_flags' type-id='type-id-8' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h' line='51' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='_IO_read_ptr' type-id='type-id-15' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h' line='54' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='_IO_read_end' type-id='type-id-15' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h' line='55' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='_IO_read_base' type-id='type-id-15' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h' line='56' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='_IO_write_base' type-id='type-id-15' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h' line='57' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='_IO_write_ptr' type-id='type-id-15' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h' line='58' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='384'> + <var-decl name='_IO_write_end' type-id='type-id-15' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h' line='59' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='448'> + <var-decl name='_IO_buf_base' type-id='type-id-15' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h' line='60' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='512'> + <var-decl name='_IO_buf_end' type-id='type-id-15' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h' line='61' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='576'> + <var-decl name='_IO_save_base' type-id='type-id-15' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h' line='64' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='640'> + <var-decl name='_IO_backup_base' type-id='type-id-15' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h' line='65' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='704'> + <var-decl name='_IO_save_end' type-id='type-id-15' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h' line='66' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='768'> + <var-decl name='_markers' type-id='type-id-1286' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h' line='68' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='832'> + <var-decl name='_chain' type-id='type-id-1287' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h' line='70' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='896'> + <var-decl name='_fileno' type-id='type-id-8' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h' line='72' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='928'> + <var-decl name='_flags2' type-id='type-id-8' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h' line='73' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='960'> + <var-decl name='_old_offset' type-id='type-id-1282' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h' line='74' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1024'> + <var-decl name='_cur_column' type-id='type-id-84' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h' line='77' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1040'> + <var-decl name='_vtable_offset' type-id='type-id-1037' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h' line='78' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1048'> + <var-decl name='_shortbuf' type-id='type-id-702' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h' line='79' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1088'> + <var-decl name='_lock' type-id='type-id-1288' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h' line='81' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1152'> + <var-decl name='_offset' type-id='type-id-9' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h' line='89' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1216'> + <var-decl name='_codecvt' type-id='type-id-1289' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h' line='91' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1280'> + <var-decl name='_wide_data' type-id='type-id-1290' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h' line='92' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1344'> + <var-decl name='_freeres_list' type-id='type-id-1287' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h' line='93' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1408'> + <var-decl name='_freeres_buf' type-id='type-id-22' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h' line='94' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1472'> + <var-decl name='__pad5' type-id='type-id-19' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h' line='95' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1536'> + <var-decl name='_mode' type-id='type-id-8' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h' line='96' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1568'> + <var-decl name='_unused2' type-id='type-id-1147' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h' line='98' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='ssize_t' type-id='type-id-186' filepath='/usr/include/x86_64-linux-gnu/sys/types.h' line='108' column='1' id='type-id-185'/> + <class-decl name='_memo' size-in-bits='256' is-struct='yes' visibility='default' filepath='Parser/pegen.h' line='29' column='1' id='type-id-1291'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='type' type-id='type-id-8' visibility='default' filepath='Parser/pegen.h' line='30' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='node' type-id='type-id-22' visibility='default' filepath='Parser/pegen.h' line='31' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='mark' type-id='type-id-8' visibility='default' filepath='Parser/pegen.h' line='32' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='next' type-id='type-id-1292' visibility='default' filepath='Parser/pegen.h' line='33' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='Memo' type-id='type-id-1291' filepath='Parser/pegen.h' line='34' column='1' id='type-id-1293'/> + <class-decl name='Token' size-in-bits='448' is-struct='yes' naming-typedef-id='type-id-1294' visibility='default' filepath='Parser/pegen.h' line='36' column='1' id='type-id-1295'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='type' type-id='type-id-8' visibility='default' filepath='Parser/pegen.h' line='37' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='bytes' type-id='type-id-2' visibility='default' filepath='Parser/pegen.h' line='38' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='level' type-id='type-id-8' visibility='default' filepath='Parser/pegen.h' line='39' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='160'> + <var-decl name='lineno' type-id='type-id-8' visibility='default' filepath='Parser/pegen.h' line='40' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='col_offset' type-id='type-id-8' visibility='default' filepath='Parser/pegen.h' line='40' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='224'> + <var-decl name='end_lineno' type-id='type-id-8' visibility='default' filepath='Parser/pegen.h' line='40' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='end_col_offset' type-id='type-id-8' visibility='default' filepath='Parser/pegen.h' line='40' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='memo' type-id='type-id-1296' visibility='default' filepath='Parser/pegen.h' line='41' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='384'> + <var-decl name='metadata' type-id='type-id-2' visibility='default' filepath='Parser/pegen.h' line='42' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='Token' type-id='type-id-1295' filepath='Parser/pegen.h' line='43' column='1' id='type-id-1294'/> + <class-decl name='KeywordToken' size-in-bits='128' is-struct='yes' naming-typedef-id='type-id-1297' visibility='default' filepath='Parser/pegen.h' line='45' column='1' id='type-id-1298'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='str' type-id='type-id-12' visibility='default' filepath='Parser/pegen.h' line='46' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='type' type-id='type-id-8' visibility='default' filepath='Parser/pegen.h' line='47' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='KeywordToken' type-id='type-id-1298' filepath='Parser/pegen.h' line='48' column='1' id='type-id-1297'/> + <class-decl name='growable_comment_array' size-in-bits='192' is-struct='yes' naming-typedef-id='type-id-1299' visibility='default' filepath='Parser/pegen.h' line='51' column='1' id='type-id-1300'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='items' type-id='type-id-1301' visibility='default' filepath='Parser/pegen.h' line='55' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='size' type-id='type-id-19' visibility='default' filepath='Parser/pegen.h' line='56' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='num_items' type-id='type-id-19' visibility='default' filepath='Parser/pegen.h' line='57' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__2' size-in-bits='128' is-struct='yes' is-anonymous='yes' visibility='default' filepath='Parser/pegen.h' line='52' column='1' id='type-id-1302'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='lineno' type-id='type-id-8' visibility='default' filepath='Parser/pegen.h' line='53' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='comment' type-id='type-id-15' visibility='default' filepath='Parser/pegen.h' line='54' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='growable_comment_array' type-id='type-id-1300' filepath='Parser/pegen.h' line='58' column='1' id='type-id-1299'/> + <class-decl name='Parser' size-in-bits='1280' is-struct='yes' naming-typedef-id='type-id-1303' visibility='default' filepath='Parser/pegen.h' line='60' column='1' id='type-id-1304'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='tok' type-id='type-id-1305' visibility='default' filepath='Parser/pegen.h' line='61' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='tokens' type-id='type-id-1306' visibility='default' filepath='Parser/pegen.h' line='62' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='mark' type-id='type-id-8' visibility='default' filepath='Parser/pegen.h' line='63' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='160'> + <var-decl name='fill' type-id='type-id-8' visibility='default' filepath='Parser/pegen.h' line='64' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='size' type-id='type-id-8' visibility='default' filepath='Parser/pegen.h' line='64' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='arena' type-id='type-id-563' visibility='default' filepath='Parser/pegen.h' line='65' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='keywords' type-id='type-id-1307' visibility='default' filepath='Parser/pegen.h' line='66' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='384'> + <var-decl name='soft_keywords' type-id='type-id-239' visibility='default' filepath='Parser/pegen.h' line='67' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='448'> + <var-decl name='n_keyword_lists' type-id='type-id-8' visibility='default' filepath='Parser/pegen.h' line='68' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='480'> + <var-decl name='start_rule' type-id='type-id-8' visibility='default' filepath='Parser/pegen.h' line='69' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='512'> + <var-decl name='errcode' type-id='type-id-179' visibility='default' filepath='Parser/pegen.h' line='70' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='576'> + <var-decl name='parsing_started' type-id='type-id-8' visibility='default' filepath='Parser/pegen.h' line='71' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='640'> + <var-decl name='normalize' type-id='type-id-2' visibility='default' filepath='Parser/pegen.h' line='72' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='704'> + <var-decl name='starting_lineno' type-id='type-id-8' visibility='default' filepath='Parser/pegen.h' line='73' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='736'> + <var-decl name='starting_col_offset' type-id='type-id-8' visibility='default' filepath='Parser/pegen.h' line='74' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='768'> + <var-decl name='error_indicator' type-id='type-id-8' visibility='default' filepath='Parser/pegen.h' line='75' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='800'> + <var-decl name='flags' type-id='type-id-8' visibility='default' filepath='Parser/pegen.h' line='76' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='832'> + <var-decl name='feature_version' type-id='type-id-8' visibility='default' filepath='Parser/pegen.h' line='77' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='896'> + <var-decl name='type_ignore_comments' type-id='type-id-1299' visibility='default' filepath='Parser/pegen.h' line='78' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1088'> + <var-decl name='known_err_token' type-id='type-id-569' visibility='default' filepath='Parser/pegen.h' line='79' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1152'> + <var-decl name='level' type-id='type-id-8' visibility='default' filepath='Parser/pegen.h' line='80' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1184'> + <var-decl name='call_invalid_rules' type-id='type-id-8' visibility='default' filepath='Parser/pegen.h' line='81' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1216'> + <var-decl name='debug' type-id='type-id-8' visibility='default' filepath='Parser/pegen.h' line='82' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='Parser' type-id='type-id-1304' filepath='Parser/pegen.h' line='83' column='1' id='type-id-1303'/> + <enum-decl name='decoding_state' filepath='Parser/tokenizer.h' line='17' column='1' id='type-id-1136'> + <underlying-type type-id='type-id-24'/> + <enumerator name='STATE_INIT' value='0'/> + <enumerator name='STATE_SEEK_CODING' value='1'/> + <enumerator name='STATE_NORMAL' value='2'/> + </enum-decl> + <enum-decl name='interactive_underflow_t' filepath='Parser/tokenizer.h' line='23' column='1' id='type-id-1137'> + <underlying-type type-id='type-id-24'/> + <enumerator name='IUNDERFLOW_NORMAL' value='0'/> + <enumerator name='IUNDERFLOW_STOP' value='1'/> + </enum-decl> + <class-decl name='token' size-in-bits='384' is-struct='yes' visibility='default' filepath='Parser/tokenizer.h' line='31' column='1' id='type-id-1308'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='level' type-id='type-id-8' visibility='default' filepath='Parser/tokenizer.h' line='32' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='32'> + <var-decl name='lineno' type-id='type-id-8' visibility='default' filepath='Parser/tokenizer.h' line='33' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='col_offset' type-id='type-id-8' visibility='default' filepath='Parser/tokenizer.h' line='33' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='96'> + <var-decl name='end_lineno' type-id='type-id-8' visibility='default' filepath='Parser/tokenizer.h' line='33' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='end_col_offset' type-id='type-id-8' visibility='default' filepath='Parser/tokenizer.h' line='33' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='start' type-id='type-id-12' visibility='default' filepath='Parser/tokenizer.h' line='34' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='end' type-id='type-id-12' visibility='default' filepath='Parser/tokenizer.h' line='34' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='metadata' type-id='type-id-2' visibility='default' filepath='Parser/tokenizer.h' line='35' column='1'/> + </data-member> + </class-decl> + <enum-decl name='tokenizer_mode_kind_t' filepath='Parser/tokenizer.h' line='38' column='1' id='type-id-1309'> + <underlying-type type-id='type-id-24'/> + <enumerator name='TOK_REGULAR_MODE' value='0'/> + <enumerator name='TOK_FSTRING_MODE' value='1'/> + </enum-decl> + <class-decl name='_tokenizer_mode' size-in-bits='768' is-struct='yes' visibility='default' filepath='Parser/tokenizer.h' line='45' column='1' id='type-id-1310'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='kind' type-id='type-id-1309' visibility='default' filepath='Parser/tokenizer.h' line='46' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='32'> + <var-decl name='curly_bracket_depth' type-id='type-id-8' visibility='default' filepath='Parser/tokenizer.h' line='48' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='curly_bracket_expr_start_depth' type-id='type-id-8' visibility='default' filepath='Parser/tokenizer.h' line='49' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='96'> + <var-decl name='f_string_quote' type-id='type-id-48' visibility='default' filepath='Parser/tokenizer.h' line='51' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='f_string_quote_size' type-id='type-id-8' visibility='default' filepath='Parser/tokenizer.h' line='52' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='160'> + <var-decl name='f_string_raw' type-id='type-id-8' visibility='default' filepath='Parser/tokenizer.h' line='53' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='f_string_start' type-id='type-id-12' visibility='default' filepath='Parser/tokenizer.h' line='54' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='f_string_multi_line_start' type-id='type-id-12' visibility='default' filepath='Parser/tokenizer.h' line='55' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='f_string_line_start' type-id='type-id-8' visibility='default' filepath='Parser/tokenizer.h' line='56' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='384'> + <var-decl name='f_string_start_offset' type-id='type-id-14' visibility='default' filepath='Parser/tokenizer.h' line='58' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='448'> + <var-decl name='f_string_multi_line_start_offset' type-id='type-id-14' visibility='default' filepath='Parser/tokenizer.h' line='59' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='512'> + <var-decl name='last_expr_size' type-id='type-id-14' visibility='default' filepath='Parser/tokenizer.h' line='61' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='576'> + <var-decl name='last_expr_end' type-id='type-id-14' visibility='default' filepath='Parser/tokenizer.h' line='62' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='640'> + <var-decl name='last_expr_buffer' type-id='type-id-15' visibility='default' filepath='Parser/tokenizer.h' line='63' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='704'> + <var-decl name='f_string_debug' type-id='type-id-8' visibility='default' filepath='Parser/tokenizer.h' line='64' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='tokenizer_mode' type-id='type-id-1310' filepath='Parser/tokenizer.h' line='65' column='1' id='type-id-1158'/> + <class-decl name='tok_state' size-in-bits='138240' is-struct='yes' visibility='default' filepath='Parser/tokenizer.h' line='68' column='1' id='type-id-1132'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='buf' type-id='type-id-15' visibility='default' filepath='Parser/tokenizer.h' line='71' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='cur' type-id='type-id-15' visibility='default' filepath='Parser/tokenizer.h' line='72' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='inp' type-id='type-id-15' visibility='default' filepath='Parser/tokenizer.h' line='73' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='fp_interactive' type-id='type-id-8' visibility='default' filepath='Parser/tokenizer.h' line='74' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='interactive_src_start' type-id='type-id-15' visibility='default' filepath='Parser/tokenizer.h' line='75' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='interactive_src_end' type-id='type-id-15' visibility='default' filepath='Parser/tokenizer.h' line='76' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='384'> + <var-decl name='end' type-id='type-id-12' visibility='default' filepath='Parser/tokenizer.h' line='77' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='448'> + <var-decl name='start' type-id='type-id-12' visibility='default' filepath='Parser/tokenizer.h' line='78' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='512'> + <var-decl name='done' type-id='type-id-8' visibility='default' filepath='Parser/tokenizer.h' line='79' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='576'> + <var-decl name='fp' type-id='type-id-229' visibility='default' filepath='Parser/tokenizer.h' line='81' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='640'> + <var-decl name='tabsize' type-id='type-id-8' visibility='default' filepath='Parser/tokenizer.h' line='82' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='672'> + <var-decl name='indent' type-id='type-id-8' visibility='default' filepath='Parser/tokenizer.h' line='83' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='704'> + <var-decl name='indstack' type-id='type-id-1133' visibility='default' filepath='Parser/tokenizer.h' line='84' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='3904'> + <var-decl name='atbol' type-id='type-id-8' visibility='default' filepath='Parser/tokenizer.h' line='85' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='3936'> + <var-decl name='pendin' type-id='type-id-8' visibility='default' filepath='Parser/tokenizer.h' line='86' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='3968'> + <var-decl name='prompt' type-id='type-id-12' visibility='default' filepath='Parser/tokenizer.h' line='87' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='4032'> + <var-decl name='nextprompt' type-id='type-id-12' visibility='default' filepath='Parser/tokenizer.h' line='87' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='4096'> + <var-decl name='lineno' type-id='type-id-8' visibility='default' filepath='Parser/tokenizer.h' line='88' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='4128'> + <var-decl name='first_lineno' type-id='type-id-8' visibility='default' filepath='Parser/tokenizer.h' line='89' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='4160'> + <var-decl name='starting_col_offset' type-id='type-id-8' visibility='default' filepath='Parser/tokenizer.h' line='91' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='4192'> + <var-decl name='col_offset' type-id='type-id-8' visibility='default' filepath='Parser/tokenizer.h' line='92' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='4224'> + <var-decl name='level' type-id='type-id-8' visibility='default' filepath='Parser/tokenizer.h' line='93' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='4256'> + <var-decl name='parenstack' type-id='type-id-1134' visibility='default' filepath='Parser/tokenizer.h' line='95' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='5856'> + <var-decl name='parenlinenostack' type-id='type-id-1135' visibility='default' filepath='Parser/tokenizer.h' line='96' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='12256'> + <var-decl name='parencolstack' type-id='type-id-1135' visibility='default' filepath='Parser/tokenizer.h' line='97' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='18688'> + <var-decl name='filename' type-id='type-id-2' visibility='default' filepath='Parser/tokenizer.h' line='98' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='18752'> + <var-decl name='altindstack' type-id='type-id-1133' visibility='default' filepath='Parser/tokenizer.h' line='100' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='21952'> + <var-decl name='decoding_state' type-id='type-id-1136' visibility='default' filepath='Parser/tokenizer.h' line='102' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='21984'> + <var-decl name='decoding_erred' type-id='type-id-8' visibility='default' filepath='Parser/tokenizer.h' line='103' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='22016'> + <var-decl name='encoding' type-id='type-id-15' visibility='default' filepath='Parser/tokenizer.h' line='104' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='22080'> + <var-decl name='cont_line' type-id='type-id-8' visibility='default' filepath='Parser/tokenizer.h' line='105' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='22144'> + <var-decl name='line_start' type-id='type-id-12' visibility='default' filepath='Parser/tokenizer.h' line='106' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='22208'> + <var-decl name='multi_line_start' type-id='type-id-12' visibility='default' filepath='Parser/tokenizer.h' line='107' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='22272'> + <var-decl name='decoding_readline' type-id='type-id-2' visibility='default' filepath='Parser/tokenizer.h' line='110' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='22336'> + <var-decl name='decoding_buffer' type-id='type-id-2' visibility='default' filepath='Parser/tokenizer.h' line='111' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='22400'> + <var-decl name='readline' type-id='type-id-2' visibility='default' filepath='Parser/tokenizer.h' line='112' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='22464'> + <var-decl name='enc' type-id='type-id-12' visibility='default' filepath='Parser/tokenizer.h' line='113' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='22528'> + <var-decl name='str' type-id='type-id-15' visibility='default' filepath='Parser/tokenizer.h' line='114' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='22592'> + <var-decl name='input' type-id='type-id-15' visibility='default' filepath='Parser/tokenizer.h' line='115' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='22656'> + <var-decl name='type_comments' type-id='type-id-8' visibility='default' filepath='Parser/tokenizer.h' line='117' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='22688'> + <var-decl name='async_hacks' type-id='type-id-8' visibility='default' filepath='Parser/tokenizer.h' line='120' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='22720'> + <var-decl name='async_def' type-id='type-id-8' visibility='default' filepath='Parser/tokenizer.h' line='121' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='22752'> + <var-decl name='async_def_indent' type-id='type-id-8' visibility='default' filepath='Parser/tokenizer.h' line='122' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='22784'> + <var-decl name='async_def_nl' type-id='type-id-8' visibility='default' filepath='Parser/tokenizer.h' line='123' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='22816'> + <var-decl name='interactive_underflow' type-id='type-id-1137' visibility='default' filepath='Parser/tokenizer.h' line='126' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='22848'> + <var-decl name='report_warnings' type-id='type-id-8' visibility='default' filepath='Parser/tokenizer.h' line='127' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='22912'> + <var-decl name='tok_mode_stack' type-id='type-id-1138' visibility='default' filepath='Parser/tokenizer.h' line='129' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='138112'> + <var-decl name='tok_mode_stack_index' type-id='type-id-8' visibility='default' filepath='Parser/tokenizer.h' line='130' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='138144'> + <var-decl name='tok_extra_tokens' type-id='type-id-8' visibility='default' filepath='Parser/tokenizer.h' line='131' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='138176'> + <var-decl name='comment_newline' type-id='type-id-8' visibility='default' filepath='Parser/tokenizer.h' line='132' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='138208'> + <var-decl name='implicit_newline' type-id='type-id-8' visibility='default' filepath='Parser/tokenizer.h' line='133' column='1'/> + </data-member> + </class-decl> + <pointer-type-def type-id='type-id-1284' size-in-bits='64' id='type-id-229'/> + <pointer-type-def type-id='type-id-1297' size-in-bits='64' id='type-id-1311'/> + <pointer-type-def type-id='type-id-1311' size-in-bits='64' id='type-id-1307'/> + <pointer-type-def type-id='type-id-1293' size-in-bits='64' id='type-id-1296'/> + <pointer-type-def type-id='type-id-1303' size-in-bits='64' id='type-id-568'/> + <pointer-type-def type-id='type-id-1254' size-in-bits='64' id='type-id-563'/> + <pointer-type-def type-id='type-id-1178' size-in-bits='64' id='type-id-1186'/> + <pointer-type-def type-id='type-id-1180' size-in-bits='64' id='type-id-1194'/> + <pointer-type-def type-id='type-id-1280' size-in-bits='64' id='type-id-338'/> + <pointer-type-def type-id='type-id-1173' size-in-bits='64' id='type-id-1190'/> + <pointer-type-def type-id='type-id-1281' size-in-bits='64' id='type-id-336'/> + <pointer-type-def type-id='type-id-1279' size-in-bits='64' id='type-id-337'/> + <pointer-type-def type-id='type-id-1162' size-in-bits='64' id='type-id-1188'/> + <pointer-type-def type-id='type-id-345' size-in-bits='64' id='type-id-2'/> + <pointer-type-def type-id='type-id-1312' size-in-bits='64' id='type-id-1260'/> + <pointer-type-def type-id='type-id-1313' size-in-bits='64' id='type-id-1274'/> + <pointer-type-def type-id='type-id-1314' size-in-bits='64' id='type-id-1255'/> + <pointer-type-def type-id='type-id-1315' size-in-bits='64' id='type-id-1261'/> + <pointer-type-def type-id='type-id-1316' size-in-bits='64' id='type-id-1271'/> + <pointer-type-def type-id='type-id-1317' size-in-bits='64' id='type-id-1268'/> + <pointer-type-def type-id='type-id-1318' size-in-bits='64' id='type-id-1263'/> + <pointer-type-def type-id='type-id-1088' size-in-bits='64' id='type-id-732'/> + <pointer-type-def type-id='type-id-1319' size-in-bits='64' id='type-id-1272'/> + <pointer-type-def type-id='type-id-1320' size-in-bits='64' id='type-id-1273'/> + <qualified-type-def type-id='type-id-2' const='yes' id='type-id-1321'/> + <pointer-type-def type-id='type-id-1321' size-in-bits='64' id='type-id-248'/> + <pointer-type-def type-id='type-id-2' size-in-bits='64' id='type-id-233'/> + <pointer-type-def type-id='type-id-1167' size-in-bits='64' id='type-id-1189'/> + <pointer-type-def type-id='type-id-256' size-in-bits='64' id='type-id-1'/> + <pointer-type-def type-id='type-id-243' size-in-bits='64' id='type-id-254'/> + <pointer-type-def type-id='type-id-14' size-in-bits='64' id='type-id-13'/> + <pointer-type-def type-id='type-id-1294' size-in-bits='64' id='type-id-569'/> + <pointer-type-def type-id='type-id-569' size-in-bits='64' id='type-id-1306'/> + <pointer-type-def type-id='type-id-1283' size-in-bits='64' id='type-id-1287'/> + <pointer-type-def type-id='type-id-1148' size-in-bits='64' id='type-id-1289'/> + <pointer-type-def type-id='type-id-1285' size-in-bits='64' id='type-id-1288'/> + <pointer-type-def type-id='type-id-1149' size-in-bits='64' id='type-id-1286'/> + <pointer-type-def type-id='type-id-1150' size-in-bits='64' id='type-id-1290'/> + <pointer-type-def type-id='type-id-1302' size-in-bits='64' id='type-id-1301'/> + <pointer-type-def type-id='type-id-1151' size-in-bits='64' id='type-id-306'/> + <pointer-type-def type-id='type-id-1252' size-in-bits='64' id='type-id-1217'/> + <pointer-type-def type-id='type-id-1251' size-in-bits='64' id='type-id-1216'/> + <pointer-type-def type-id='type-id-1250' size-in-bits='64' id='type-id-1215'/> + <pointer-type-def type-id='type-id-963' size-in-bits='64' id='type-id-1210'/> + <pointer-type-def type-id='type-id-1253' size-in-bits='64' id='type-id-1218'/> + <pointer-type-def type-id='type-id-1291' size-in-bits='64' id='type-id-1292'/> + <pointer-type-def type-id='type-id-1223' size-in-bits='64' id='type-id-565'/> + <pointer-type-def type-id='type-id-1221' size-in-bits='64' id='type-id-1141'/> + <pointer-type-def type-id='type-id-1219' size-in-bits='64' id='type-id-503'/> + <pointer-type-def type-id='type-id-1208' size-in-bits='64' id='type-id-564'/> + <pointer-type-def type-id='type-id-1225' size-in-bits='64' id='type-id-529'/> + <pointer-type-def type-id='type-id-15' size-in-bits='64' id='type-id-239'/> + <pointer-type-def type-id='type-id-354' size-in-bits='64' id='type-id-339'/> + <pointer-type-def type-id='type-id-1322' size-in-bits='64' id='type-id-1266'/> + <pointer-type-def type-id='type-id-1323' size-in-bits='64' id='type-id-1265'/> + <pointer-type-def type-id='type-id-1324' size-in-bits='64' id='type-id-1204'/> + <pointer-type-def type-id='type-id-1325' size-in-bits='64' id='type-id-1277'/> + <pointer-type-def type-id='type-id-1326' size-in-bits='64' id='type-id-1269'/> + <pointer-type-def type-id='type-id-1327' size-in-bits='64' id='type-id-1264'/> + <pointer-type-def type-id='type-id-1328' size-in-bits='64' id='type-id-1267'/> + <pointer-type-def type-id='type-id-238' size-in-bits='64' id='type-id-236'/> + <pointer-type-def type-id='type-id-8' size-in-bits='64' id='type-id-179'/> + <pointer-type-def type-id='type-id-1132' size-in-bits='64' id='type-id-1305'/> + <pointer-type-def type-id='type-id-1308' size-in-bits='64' id='type-id-1329'/> + <pointer-type-def type-id='type-id-1330' size-in-bits='64' id='type-id-1176'/> + <pointer-type-def type-id='type-id-1331' size-in-bits='64' id='type-id-1270'/> + <pointer-type-def type-id='type-id-1332' size-in-bits='64' id='type-id-1262'/> + <pointer-type-def type-id='type-id-314' size-in-bits='64' id='type-id-312'/> + <pointer-type-def type-id='type-id-1333' size-in-bits='64' id='type-id-1278'/> + <pointer-type-def type-id='type-id-1089' size-in-bits='64' id='type-id-760'/> + <pointer-type-def type-id='type-id-46' size-in-bits='64' id='type-id-22'/> + <pointer-type-def type-id='type-id-22' size-in-bits='64' id='type-id-253'/> + <class-decl name='_IO_codecvt' is-struct='yes' visibility='default' is-declaration-only='yes' id='type-id-1148'/> + <class-decl name='_IO_marker' is-struct='yes' visibility='default' is-declaration-only='yes' id='type-id-1149'/> + <class-decl name='_IO_wide_data' is-struct='yes' visibility='default' is-declaration-only='yes' id='type-id-1150'/> + <class-decl name='_arena' is-struct='yes' visibility='default' is-declaration-only='yes' id='type-id-1152'/> + <function-decl name='PyBytes_FromStringAndSize' mangled-name='PyBytes_FromStringAndSize' filepath='./Include/bytesobject.h' line='34' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyBytes_FromStringAndSize'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-14'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyBytes_AsString' mangled-name='PyBytes_AsString' filepath='./Include/bytesobject.h' line='42' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyBytes_AsString'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-15'/> + </function-decl> + <function-decl name='PyBytes_AsStringAndSize' mangled-name='PyBytes_AsStringAndSize' filepath='./Include/bytesobject.h' line='54' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyBytes_AsStringAndSize'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-239'/> + <parameter type-id='type-id-13'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyObject_FastCall' mangled-name='_PyObject_FastCall' filepath='./Include/cpython/abstract.h' line='83' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_FastCall'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-248'/> + <parameter type-id='type-id-14'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyComplex_FromCComplex' mangled-name='PyComplex_FromCComplex' filepath='./Include/cpython/complexobject.h' line='31' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyComplex_FromCComplex'> + <parameter type-id='type-id-327'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyImport_GetModuleAttrString' mangled-name='_PyImport_GetModuleAttrString' filepath='./Include/cpython/import.h' line='46' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyImport_GetModuleAttrString'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-12'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyType_Name' mangled-name='_PyType_Name' filepath='./Include/cpython/object.h' line='273' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyType_Name'> + <parameter type-id='type-id-1'/> + <return type-id='type-id-12'/> + </function-decl> + <function-decl name='PyUnicode_AsUTF8' mangled-name='PyUnicode_AsUTF8' filepath='./Include/cpython/unicodeobject.h' line='625' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_AsUTF8'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-12'/> + </function-decl> + <function-decl name='PyFloat_FromDouble' mangled-name='PyFloat_FromDouble' filepath='./Include/floatobject.h' line='39' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyFloat_FromDouble'> + <parameter type-id='type-id-251'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyAST_Constant' filepath='./Include/internal/pycore_ast.h' line='822' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-552'/> + <parameter type-id='type-id-527'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-502'/> + </function-decl> + <function-decl name='_PyAST_Name' filepath='./Include/internal/pycore_ast.h' line='834' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-525'/> + <parameter type-id='type-id-566'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-502'/> + </function-decl> + <function-decl name='_PyArena_Malloc' mangled-name='_PyArena_Malloc' filepath='./Include/internal/pycore_pyarena.h' line='53' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyArena_Malloc'> + <parameter type-id='type-id-563'/> + <parameter type-id='type-id-19'/> + <return type-id='type-id-22'/> + </function-decl> + <function-decl name='_PyArena_AddPyObject' mangled-name='_PyArena_AddPyObject' filepath='./Include/internal/pycore_pyarena.h' line='59' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyArena_AddPyObject'> + <parameter type-id='type-id-563'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyLong_FromLong' mangled-name='PyLong_FromLong' filepath='./Include/longobject.h' line='16' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyLong_FromLong'> + <parameter type-id='type-id-47'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyLong_FromString' mangled-name='PyLong_FromString' filepath='./Include/longobject.h' line='74' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyLong_FromString'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-239'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyOS_strtoul' mangled-name='PyOS_strtoul' filepath='./Include/longobject.h' line='79' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyOS_strtoul'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-239'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-28'/> + </function-decl> + <function-decl name='PyOS_strtol' mangled-name='PyOS_strtol' filepath='./Include/longobject.h' line='80' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyOS_strtol'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-239'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-47'/> + </function-decl> + <function-decl name='_Py_Dealloc' mangled-name='_Py_Dealloc' filepath='./Include/object.h' line='611' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_Dealloc'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyErr_Occurred' mangled-name='PyErr_Occurred' filepath='./Include/pyerrors.h' line='17' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_Occurred'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyErr_Clear' mangled-name='PyErr_Clear' filepath='./Include/pyerrors.h' line='18' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_Clear'> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyErr_GetRaisedException' mangled-name='PyErr_GetRaisedException' filepath='./Include/pyerrors.h' line='21' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_GetRaisedException'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyErr_ExceptionMatches' mangled-name='PyErr_ExceptionMatches' filepath='./Include/pyerrors.h' line='41' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_ExceptionMatches'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyErr_NoMemory' mangled-name='PyErr_NoMemory' filepath='./Include/pyerrors.h' line='169' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_NoMemory'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyErr_Format' mangled-name='PyErr_Format' filepath='./Include/pyerrors.h' line='182' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_Format'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-12'/> + <parameter is-variadic='yes'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyMem_Malloc' mangled-name='PyMem_Malloc' filepath='./Include/pymem.h' line='52' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMem_Malloc'> + <parameter type-id='type-id-19'/> + <return type-id='type-id-22'/> + </function-decl> + <function-decl name='PyMem_Calloc' mangled-name='PyMem_Calloc' filepath='./Include/pymem.h' line='53' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMem_Calloc'> + <parameter type-id='type-id-19'/> + <parameter type-id='type-id-19'/> + <return type-id='type-id-22'/> + </function-decl> + <function-decl name='PyMem_Realloc' mangled-name='PyMem_Realloc' filepath='./Include/pymem.h' line='54' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMem_Realloc'> + <parameter type-id='type-id-22'/> + <parameter type-id='type-id-19'/> + <return type-id='type-id-22'/> + </function-decl> + <function-decl name='PyMem_Free' mangled-name='PyMem_Free' filepath='./Include/pymem.h' line='55' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMem_Free'> + <parameter type-id='type-id-22'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyOS_string_to_double' mangled-name='PyOS_string_to_double' filepath='./Include/pystrtod.h' line='9' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyOS_string_to_double'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-239'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-251'/> + </function-decl> + <function-decl name='PyUnicode_InternInPlace' mangled-name='PyUnicode_InternInPlace' filepath='./Include/unicodeobject.h' line='254' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_InternInPlace'> + <parameter type-id='type-id-233'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyUnicode_InternFromString' mangled-name='PyUnicode_InternFromString' filepath='./Include/unicodeobject.h' line='255' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_InternFromString'> + <parameter type-id='type-id-12'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyUnicode_DecodeUTF8' mangled-name='PyUnicode_DecodeUTF8' filepath='./Include/unicodeobject.h' line='437' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_DecodeUTF8'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-14'/> + <parameter type-id='type-id-12'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyUnicode_CompareWithASCIIString' mangled-name='PyUnicode_CompareWithASCIIString' filepath='./Include/unicodeobject.h' line='963' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_CompareWithASCIIString'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-12'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='__errno_location' filepath='/usr/include/errno.h' line='37' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-179'/> + </function-decl> + <function-decl name='strncpy' filepath='/usr/include/string.h' line='144' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-15'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-19'/> + <return type-id='type-id-15'/> + </function-decl> + <function-decl name='strncmp' filepath='/usr/include/string.h' line='159' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-19'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='strchr' filepath='/usr/include/string.h' line='246' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-15'/> + </function-decl> + <function-decl name='strlen' filepath='/usr/include/string.h' line='407' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <return type-id='type-id-19'/> + </function-decl> + <function-decl name='_Pypegen_raise_decode_error' filepath='Parser/pegen.h' line='162' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyPegen_raise_tokenizer_init_error' filepath='Parser/pegen.h' line='163' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_Pypegen_tokenizer_error' filepath='Parser/pegen.h' line='164' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyPegen_raise_error' filepath='Parser/pegen.h' line='165' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-12'/> + <parameter is-variadic='yes'/> + <return type-id='type-id-22'/> + </function-decl> + <function-decl name='_PyPegen_raise_error_known_location' filepath='Parser/pegen.h' line='166' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-14'/> + <parameter type-id='type-id-14'/> + <parameter type-id='type-id-14'/> + <parameter type-id='type-id-14'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-306'/> + <return type-id='type-id-22'/> + </function-decl> + <function-decl name='_Pypegen_set_syntax_error' filepath='Parser/pegen.h' line='170' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <parameter type-id='type-id-569'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyPegen_parse' filepath='Parser/pegen.h' line='364' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <return type-id='type-id-22'/> + </function-decl> + <function-decl name='_PyTokenizer_FromString' filepath='Parser/tokenizer.h' line='139' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-1305'/> + </function-decl> + <function-decl name='_PyTokenizer_FromUTF8' filepath='Parser/tokenizer.h' line='140' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-1305'/> + </function-decl> + <function-decl name='_PyTokenizer_FromFile' filepath='Parser/tokenizer.h' line='142' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-229'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-12'/> + <return type-id='type-id-1305'/> + </function-decl> + <function-decl name='_PyTokenizer_Free' filepath='Parser/tokenizer.h' line='144' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1305'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyToken_Free' filepath='Parser/tokenizer.h' line='145' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1329'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyToken_Init' filepath='Parser/tokenizer.h' line='146' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1329'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyTokenizer_Get' filepath='Parser/tokenizer.h' line='147' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1305'/> + <parameter type-id='type-id-1329'/> + <return type-id='type-id-8'/> + </function-decl> + <function-type size-in-bits='64' id='type-id-1312'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-type> + <function-type size-in-bits='64' id='type-id-1313'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-248'/> + <parameter type-id='type-id-19'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-type> + <function-type size-in-bits='64' id='type-id-1314'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-type> + <function-type size-in-bits='64' id='type-id-1315'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-type> + <function-type size-in-bits='64' id='type-id-1316'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-2'/> + </function-type> + <function-type size-in-bits='64' id='type-id-1317'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-15'/> + <return type-id='type-id-2'/> + </function-type> + <function-type size-in-bits='64' id='type-id-1318'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-14'/> + <return type-id='type-id-2'/> + </function-type> + <function-type size-in-bits='64' id='type-id-1319'> + <parameter type-id='type-id-1'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-type> + <function-type size-in-bits='64' id='type-id-1320'> + <parameter type-id='type-id-1'/> + <parameter type-id='type-id-14'/> + <return type-id='type-id-2'/> + </function-type> + <function-type size-in-bits='64' id='type-id-1322'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-type> + <function-type size-in-bits='64' id='type-id-1323'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-type> + <function-type size-in-bits='64' id='type-id-1324'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-22'/> + <return type-id='type-id-8'/> + </function-type> + <function-type size-in-bits='64' id='type-id-1325'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-254'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-8'/> + </function-type> + <function-type size-in-bits='64' id='type-id-1326'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-15'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-type> + <function-type size-in-bits='64' id='type-id-1327'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-14'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-type> + <function-type size-in-bits='64' id='type-id-1328'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-341'/> + <parameter type-id='type-id-22'/> + <return type-id='type-id-8'/> + </function-type> + <function-type size-in-bits='64' id='type-id-1330'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-233'/> + <return type-id='type-id-255'/> + </function-type> + <function-type size-in-bits='64' id='type-id-1331'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-305'/> + </function-type> + <function-type size-in-bits='64' id='type-id-1332'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-14'/> + </function-type> + <function-type size-in-bits='64' id='type-id-1333'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-254'/> + <return type-id='type-id-46'/> + </function-type> + </abi-instr> + <abi-instr address-size='64' path='Parser/pegen_errors.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <function-decl name='_PyErr_ProgramDecodedTextObject' mangled-name='_PyErr_ProgramDecodedTextObject' filepath='./Include/cpython/pyerrors.h' line='146' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyErr_ProgramDecodedTextObject'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-12'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='Py_BuildValue' mangled-name='Py_BuildValue' filepath='./Include/modsupport.h' line='36' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_BuildValue'> + <parameter type-id='type-id-12'/> + <parameter is-variadic='yes'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyObject_Str' mangled-name='PyObject_Str' filepath='./Include/object.h' line='403' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_Str'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyErr_SetNone' mangled-name='PyErr_SetNone' filepath='./Include/pyerrors.h' line='11' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_SetNone'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyErr_SetObject' mangled-name='PyErr_SetObject' filepath='./Include/pyerrors.h' line='12' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_SetObject'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyErr_SetString' mangled-name='PyErr_SetString' filepath='./Include/pyerrors.h' line='13' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_SetString'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-12'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyErr_Fetch' mangled-name='PyErr_Fetch' filepath='./Include/pyerrors.h' line='19' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_Fetch'> + <parameter type-id='type-id-233'/> + <parameter type-id='type-id-233'/> + <parameter type-id='type-id-233'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyErr_Restore' mangled-name='PyErr_Restore' filepath='./Include/pyerrors.h' line='20' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_Restore'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyTuple_Pack' mangled-name='PyTuple_Pack' filepath='./Include/tupleobject.h' line='35' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyTuple_Pack'> + <parameter type-id='type-id-14'/> + <parameter is-variadic='yes'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyUnicode_FromStringAndSize' mangled-name='PyUnicode_FromStringAndSize' filepath='./Include/unicodeobject.h' line='130' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_FromStringAndSize'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-14'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyUnicode_FromFormatV' mangled-name='PyUnicode_FromFormatV' filepath='./Include/unicodeobject.h' line='245' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_FromFormatV'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-306'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='memcpy' filepath='/usr/include/string.h' line='43' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-22'/> + <parameter type-id='type-id-22'/> + <parameter type-id='type-id-19'/> + <return type-id='type-id-22'/> + </function-decl> + <function-decl name='_PyPegen_fill_token' filepath='Parser/pegen.h' line='149' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-568'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyPegen_byte_offset_to_character_offset' filepath='Parser/pegen.h' line='153' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-14'/> + <return type-id='type-id-14'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Parser/string_parser.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <pointer-type-def type-id='type-id-12' size-in-bits='64' id='type-id-252'/> + <function-decl name='_PyBytes_DecodeEscape' mangled-name='_PyBytes_DecodeEscape' filepath='./Include/cpython/bytesobject.h' line='28' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyBytes_DecodeEscape'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-14'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-252'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyUnicode_DecodeUnicodeEscapeInternal' mangled-name='_PyUnicode_DecodeUnicodeEscapeInternal' filepath='./Include/cpython/unicodeobject.h' line='685' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_DecodeUnicodeEscapeInternal'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-14'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-13'/> + <parameter type-id='type-id-252'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyErr_WarnExplicitObject' mangled-name='PyErr_WarnExplicitObject' filepath='./Include/cpython/warnings.h' line='5' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_WarnExplicitObject'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyErr_BadInternalCall' mangled-name='_PyErr_BadInternalCall' filepath='./Include/pyerrors.h' line='225' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyErr_BadInternalCall'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyUnicode_FromFormat' mangled-name='PyUnicode_FromFormat' filepath='./Include/unicodeobject.h' line='249' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_FromFormat'> + <parameter type-id='type-id-12'/> + <parameter is-variadic='yes'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyUnicode_DecodeUTF8Stateful' mangled-name='PyUnicode_DecodeUTF8Stateful' filepath='./Include/unicodeobject.h' line='443' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_DecodeUTF8Stateful'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-14'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-13'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='sprintf' filepath='/usr/include/stdio.h' line='358' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-15'/> + <parameter type-id='type-id-12'/> + <parameter is-variadic='yes'/> + <return type-id='type-id-8'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Parser/token.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <array-type-def dimensions='1' type-id='type-id-430' size-in-bits='4416' id='type-id-1334'> + <subrange length='69' type-id='type-id-28' id='type-id-1335'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-430' size-in-bits='infinite' id='type-id-1336'> + <subrange length='infinite' id='type-id-225'/> + </array-type-def> + <qualified-type-def type-id='type-id-12' const='yes' id='type-id-430'/> + <var-decl name='_PyParser_TokenNames' type-id='type-id-1336' mangled-name='_PyParser_TokenNames' visibility='default' filepath='./Include/internal/pycore_token.h' line='100' column='1' elf-symbol-id='_PyParser_TokenNames'/> + <function-decl name='_PyToken_OneChar' mangled-name='_PyToken_OneChar' filepath='Parser/token.c' line='83' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyToken_OneChar'> + <parameter type-id='type-id-8' name='c1' filepath='Parser/token.c' line='83' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyToken_TwoChars' mangled-name='_PyToken_TwoChars' filepath='Parser/token.c' line='115' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyToken_TwoChars'> + <parameter type-id='type-id-8' name='c1' filepath='Parser/token.c' line='115' column='1'/> + <parameter type-id='type-id-8' name='c2' filepath='Parser/token.c' line='115' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyToken_ThreeChars' mangled-name='_PyToken_ThreeChars' filepath='Parser/token.c' line='199' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyToken_ThreeChars'> + <parameter type-id='type-id-8' name='c1' filepath='Parser/token.c' line='199' column='1'/> + <parameter type-id='type-id-8' name='c2' filepath='Parser/token.c' line='199' column='1'/> + <parameter type-id='type-id-8' name='c3' filepath='Parser/token.c' line='199' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Parser/tokenizer.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <qualified-type-def type-id='type-id-84' const='yes' id='type-id-1337'/> + <pointer-type-def type-id='type-id-1337' size-in-bits='64' id='type-id-1338'/> + <pointer-type-def type-id='type-id-1338' size-in-bits='64' id='type-id-1339'/> + <pointer-type-def type-id='type-id-19' size-in-bits='64' id='type-id-441'/> + <function-decl name='PyObject_CallNoArgs' mangled-name='PyObject_CallNoArgs' filepath='./Include/abstract.h' line='146' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_CallNoArgs'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyObject_CallFunction_SizeT' mangled-name='_PyObject_CallFunction_SizeT' filepath='./Include/abstract.h' line='198' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_CallFunction_SizeT'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-12'/> + <parameter is-variadic='yes'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_Py_CheckFunctionResult' mangled-name='_Py_CheckFunctionResult' filepath='./Include/cpython/abstract.h' line='36' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_CheckFunctionResult'> + <parameter type-id='type-id-177'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-12'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyObject_MakeTpCall' mangled-name='_PyObject_MakeTpCall' filepath='./Include/cpython/abstract.h' line='47' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_MakeTpCall'> + <parameter type-id='type-id-177'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-248'/> + <parameter type-id='type-id-14'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_Py_UniversalNewlineFgetsWithSize' mangled-name='_Py_UniversalNewlineFgetsWithSize' filepath='./Include/cpython/fileobject.h' line='6' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_UniversalNewlineFgetsWithSize'> + <parameter type-id='type-id-15'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-229'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-441'/> + <return type-id='type-id-15'/> + </function-decl> + <function-decl name='_Py_FatalErrorFunc' mangled-name='_Py_FatalErrorFunc' filepath='./Include/cpython/pyerrors.h' line='162' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_FatalErrorFunc'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-12'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyUnicode_IsPrintable' mangled-name='_PyUnicode_IsPrintable' filepath='./Include/cpython/unicodeobject.h' line='894' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_IsPrintable'> + <parameter type-id='type-id-250'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyUnicode_ScanIdentifier' mangled-name='_PyUnicode_ScanIdentifier' filepath='./Include/cpython/unicodeobject.h' line='961' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyUnicode_ScanIdentifier'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-14'/> + </function-decl> + <function-decl name='_Py_dup' mangled-name='_Py_dup' filepath='./Include/internal/pycore_fileutils.h' line='164' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_dup'> + <parameter type-id='type-id-8'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_Py_BuildValue_SizeT' mangled-name='_Py_BuildValue_SizeT' filepath='./Include/modsupport.h' line='37' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_BuildValue_SizeT'> + <parameter type-id='type-id-12'/> + <parameter is-variadic='yes'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyObject_GetAttr' mangled-name='PyObject_GetAttr' filepath='./Include/object.h' line='411' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyObject_GetAttr'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyErr_SetFromErrnoWithFilename' mangled-name='PyErr_SetFromErrnoWithFilename' filepath='./Include/pyerrors.h' line='177' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_SetFromErrnoWithFilename'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-12'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PySys_WriteStderr' mangled-name='PySys_WriteStderr' filepath='./Include/sysmodule.h' line='19' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySys_WriteStderr'> + <parameter type-id='type-id-12'/> + <parameter is-variadic='yes'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyUnicode_Substring' mangled-name='PyUnicode_Substring' filepath='./Include/unicodeobject.h' line='142' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_Substring'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-14'/> + <parameter type-id='type-id-14'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyUnicode_Decode' mangled-name='PyUnicode_Decode' filepath='./Include/unicodeobject.h' line='345' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_Decode'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-14'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-12'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyUnicode_AsUTF8String' mangled-name='PyUnicode_AsUTF8String' filepath='./Include/unicodeobject.h' line='450' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_AsUTF8String'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyUnicode_AsUTF8AndSize' mangled-name='PyUnicode_AsUTF8AndSize' filepath='./Include/unicodeobject.h' line='466' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnicode_AsUTF8AndSize'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-13'/> + <return type-id='type-id-12'/> + </function-decl> + <function-decl name='__ctype_b_loc' filepath='/usr/include/ctype.h' line='79' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-1339'/> + </function-decl> + <function-decl name='tolower' filepath='/usr/include/ctype.h' line='122' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='fclose' filepath='/usr/include/stdio.h' line='178' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-229'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='fdopen' filepath='/usr/include/stdio.h' line='293' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-12'/> + <return type-id='type-id-229'/> + </function-decl> + <function-decl name='getc' filepath='/usr/include/stdio.h' line='514' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-229'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='ungetc' filepath='/usr/include/stdio.h' line='668' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-229'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='ftell' filepath='/usr/include/stdio.h' line='718' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-229'/> + <return type-id='type-id-47'/> + </function-decl> + <function-decl name='memcmp' filepath='/usr/include/string.h' line='64' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-22'/> + <parameter type-id='type-id-22'/> + <parameter type-id='type-id-19'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='memchr' filepath='/usr/include/string.h' line='107' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-22'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-19'/> + <return type-id='type-id-22'/> + </function-decl> + <function-decl name='strcspn' filepath='/usr/include/string.h' line='293' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-12'/> + <return type-id='type-id-19'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Python/Python-ast.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <function-decl name='PyModule_AddIntConstant' mangled-name='PyModule_AddIntConstant' filepath='./Include/modsupport.h' line='53' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyModule_AddIntConstant'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-47'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyInit__ast' mangled-name='PyInit__ast' filepath='Python/Python-ast.c' line='13062' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInit__ast'> + <return type-id='type-id-2'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Python/Python-tokenize.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <function-decl name='PyErr_SyntaxLocationObject' mangled-name='PyErr_SyntaxLocationObject' filepath='./Include/cpython/pyerrors.h' line='130' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_SyntaxLocationObject'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyModule_AddType' mangled-name='PyModule_AddType' filepath='./Include/modsupport.h' line='58' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyModule_AddType'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyTokenizer_FromReadline' filepath='Python/../Parser/tokenizer.h' line='141' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-1305'/> + </function-decl> + <function-decl name='PyInit__tokenize' mangled-name='PyInit__tokenize' filepath='Python/Python-tokenize.c' line='364' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInit__tokenize'> + <return type-id='type-id-2'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Python/_warnings.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <function-decl name='_Py_IsInterpreterFinalizing' mangled-name='_Py_IsInterpreterFinalizing' filepath='./Include/cpython/pylifecycle.h' line='55' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_IsInterpreterFinalizing'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PySys_GetAttr' mangled-name='_PySys_GetAttr' filepath='./Include/cpython/sysmodule.h' line='5' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PySys_GetAttr'> + <parameter type-id='type-id-177'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_Py_DisplaySourceLine' mangled-name='_Py_DisplaySourceLine' filepath='./Include/cpython/traceback.h' line='15' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_DisplaySourceLine'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-179'/> + <parameter type-id='type-id-233'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyImport_GetModules' filepath='./Include/internal/pycore_import.h' line='118' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyImport_BlessMyLoader' filepath='./Include/internal/pycore_import.h' line='134' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyModule_AddObjectRef' mangled-name='PyModule_AddObjectRef' filepath='./Include/modsupport.h' line='46' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyModule_AddObjectRef'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyThreadState_GetFrame' mangled-name='PyThreadState_GetFrame' filepath='./Include/pystate.h' line='72' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThreadState_GetFrame'> + <parameter type-id='type-id-177'/> + <return type-id='type-id-365'/> + </function-decl> + <function-decl name='PyErr_ResourceWarning' mangled-name='PyErr_ResourceWarning' filepath='Python/_warnings.c' line='1240' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_ResourceWarning'> + <parameter type-id='type-id-2' name='source' filepath='Python/_warnings.c' line='1240' column='1'/> + <parameter type-id='type-id-14' name='stack_level' filepath='Python/_warnings.c' line='1240' column='1'/> + <parameter type-id='type-id-12' name='format' filepath='Python/_warnings.c' line='1241' column='1'/> + <parameter is-variadic='yes'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyErr_WarnExplicit' mangled-name='PyErr_WarnExplicit' filepath='Python/_warnings.c' line='1299' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_WarnExplicit'> + <parameter type-id='type-id-2' name='category' filepath='Python/_warnings.c' line='1299' column='1'/> + <parameter type-id='type-id-12' name='text' filepath='Python/_warnings.c' line='1299' column='1'/> + <parameter type-id='type-id-12' name='filename_str' filepath='Python/_warnings.c' line='1300' column='1'/> + <parameter type-id='type-id-8' name='lineno' filepath='Python/_warnings.c' line='1300' column='1'/> + <parameter type-id='type-id-12' name='module_str' filepath='Python/_warnings.c' line='1301' column='1'/> + <parameter type-id='type-id-2' name='registry' filepath='Python/_warnings.c' line='1301' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyErr_WarnExplicitFormat' mangled-name='PyErr_WarnExplicitFormat' filepath='Python/_warnings.c' line='1331' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_WarnExplicitFormat'> + <parameter type-id='type-id-2' name='category' filepath='Python/_warnings.c' line='1331' column='1'/> + <parameter type-id='type-id-12' name='filename_str' filepath='Python/_warnings.c' line='1332' column='1'/> + <parameter type-id='type-id-8' name='lineno' filepath='Python/_warnings.c' line='1332' column='1'/> + <parameter type-id='type-id-12' name='module_str' filepath='Python/_warnings.c' line='1333' column='1'/> + <parameter type-id='type-id-2' name='registry' filepath='Python/_warnings.c' line='1333' column='1'/> + <parameter type-id='type-id-12' name='format' filepath='Python/_warnings.c' line='1334' column='1'/> + <parameter is-variadic='yes'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyWarnings_Init' mangled-name='_PyWarnings_Init' filepath='Python/_warnings.c' line='1471' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyWarnings_Init'> + <return type-id='type-id-2'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Python/assemble.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <function-decl name='_PyCompile_ConstCacheMergeOne' filepath='./Include/internal/pycore_compile.h' line='93' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-233'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyCompile_InstrSize' filepath='./Include/internal/pycore_compile.h' line='95' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_Py_set_localsplus_info' filepath='Python/assemble.c' line='445' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-85'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-46'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Python/ast_opt.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <function-decl name='_PyAST_GetDocString' filepath='./Include/internal/pycore_ast.h' line='917' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-500'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='snprintf' filepath='/usr/include/stdio.h' line='378' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-15'/> + <parameter type-id='type-id-19'/> + <parameter type-id='type-id-12'/> + <parameter is-variadic='yes'/> + <return type-id='type-id-8'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Python/bltinmodule.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <pointer-type-def type-id='type-id-1152' size-in-bits='64' id='type-id-1340'/> + <var-decl name='PyFilter_Type' type-id='type-id-256' mangled-name='PyFilter_Type' visibility='default' filepath='./Include/bltinmodule.h' line='7' column='1' elf-symbol-id='PyFilter_Type'/> + <var-decl name='PyMap_Type' type-id='type-id-256' mangled-name='PyMap_Type' visibility='default' filepath='./Include/bltinmodule.h' line='8' column='1' elf-symbol-id='PyMap_Type'/> + <var-decl name='PyZip_Type' type-id='type-id-256' mangled-name='PyZip_Type' visibility='default' filepath='./Include/bltinmodule.h' line='9' column='1' elf-symbol-id='PyZip_Type'/> + <function-decl name='PyEval_EvalCode' mangled-name='PyEval_EvalCode' filepath='./Include/ceval.h' line='10' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyEval_EvalCode'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyEval_EvalCodeEx' mangled-name='PyEval_EvalCodeEx' filepath='./Include/ceval.h' line='12' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyEval_EvalCodeEx'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-248'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-248'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-248'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyEval_GetBuiltins' mangled-name='PyEval_GetBuiltins' filepath='./Include/ceval.h' line='41' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyEval_GetBuiltins'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyEval_MergeCompilerFlags' mangled-name='PyEval_MergeCompilerFlags' filepath='./Include/cpython/ceval.h' line='18' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyEval_MergeCompilerFlags'> + <parameter type-id='type-id-208'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyRun_StringFlags' mangled-name='PyRun_StringFlags' filepath='./Include/cpython/pythonrun.h' line='44' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyRun_StringFlags'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-208'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='Py_CompileStringObject' mangled-name='Py_CompileStringObject' filepath='./Include/cpython/pythonrun.h' line='63' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_CompileStringObject'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-208'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_Py_SourceAsString' mangled-name='_Py_SourceAsString' filepath='./Include/cpython/pythonrun.h' line='73' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_SourceAsString'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-208'/> + <parameter type-id='type-id-233'/> + <return type-id='type-id-12'/> + </function-decl> + <function-decl name='PyImport_ImportModuleLevelObject' mangled-name='PyImport_ImportModuleLevelObject' filepath='./Include/import.h' line='60' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyImport_ImportModuleLevelObject'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyAST_obj2mod' filepath='./Include/internal/pycore_ast.h' line='906' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-563'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-468'/> + </function-decl> + <function-decl name='PyAST_Check' filepath='./Include/internal/pycore_ast.h' line='907' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyAST_Validate' filepath='./Include/internal/pycore_ast.h' line='909' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-468'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyAST_Compile' mangled-name='_PyAST_Compile' filepath='./Include/internal/pycore_compile.h' line='15' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyAST_Compile'> + <parameter type-id='type-id-467'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-208'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-1340'/> + <return type-id='type-id-328'/> + </function-decl> + <function-decl name='_PyFloat_ExactDealloc' filepath='./Include/internal/pycore_floatobject.h' line='53' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyArena_New' mangled-name='_PyArena_New' filepath='./Include/internal/pycore_pyarena.h' line='38' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyArena_New'> + <return type-id='type-id-563'/> + </function-decl> + <function-decl name='_PyArena_Free' mangled-name='_PyArena_Free' filepath='./Include/internal/pycore_pyarena.h' line='39' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyArena_Free'> + <parameter type-id='type-id-563'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PySys_GetObject' mangled-name='PySys_GetObject' filepath='./Include/sysmodule.h' line='10' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySys_GetObject'> + <parameter type-id='type-id-12'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyAnextAwaitable_New' filepath='Python/bltinmodule.c' line='1664' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Python/bootstrap_hash.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <function-decl name='_Py_fstat' mangled-name='_Py_fstat' filepath='./Include/internal/pycore_fileutils.h' line='93' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_fstat'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-51'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_Py_open' mangled-name='_Py_open' filepath='./Include/internal/pycore_fileutils.h' line='105' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_open'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_Py_open_noraise' mangled-name='_Py_open_noraise' filepath='./Include/internal/pycore_fileutils.h' line='109' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_open_noraise'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_Py_read' mangled-name='_Py_read' filepath='./Include/internal/pycore_fileutils.h' line='117' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_read'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-22'/> + <parameter type-id='type-id-19'/> + <return type-id='type-id-14'/> + </function-decl> + <function-decl name='close' filepath='/usr/include/unistd.h' line='358' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='read' filepath='/usr/include/unistd.h' line='371' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-22'/> + <parameter type-id='type-id-19'/> + <return type-id='type-id-185'/> + </function-decl> + <function-decl name='getrandom' filepath='/usr/include/x86_64-linux-gnu/sys/random.h' line='34' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-22'/> + <parameter type-id='type-id-19'/> + <parameter type-id='type-id-95'/> + <return type-id='type-id-185'/> + </function-decl> + <function-decl name='_PyOS_URandom' mangled-name='_PyOS_URandom' filepath='Python/bootstrap_hash.c' line='527' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyOS_URandom'> + <parameter type-id='type-id-22' name='buffer' filepath='Python/bootstrap_hash.c' line='527' column='1'/> + <parameter type-id='type-id-14' name='size' filepath='Python/bootstrap_hash.c' line='527' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyOS_URandomNonblock' mangled-name='_PyOS_URandomNonblock' filepath='Python/bootstrap_hash.c' line='541' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyOS_URandomNonblock'> + <parameter type-id='type-id-22' name='buffer' filepath='Python/bootstrap_hash.c' line='541' column='1'/> + <parameter type-id='type-id-14' name='size' filepath='Python/bootstrap_hash.c' line='541' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Python/ceval.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <function-decl name='_PyEval_SetProfile' mangled-name='_PyEval_SetProfile' filepath='./Include/cpython/ceval.h' line='7' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyEval_SetProfile'> + <parameter type-id='type-id-177'/> + <parameter type-id='type-id-766'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyEval_SetTrace' mangled-name='_PyEval_SetTrace' filepath='./Include/cpython/ceval.h' line='10' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyEval_SetTrace'> + <parameter type-id='type-id-177'/> + <parameter type-id='type-id-766'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyErr_GetTopmostException' mangled-name='_PyErr_GetTopmostException' filepath='./Include/cpython/pyerrors.h' line='94' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyErr_GetTopmostException'> + <parameter type-id='type-id-177'/> + <return type-id='type-id-376'/> + </function-decl> + <function-decl name='_PyErr_WriteUnraisableMsg' mangled-name='_PyErr_WriteUnraisableMsg' filepath='./Include/cpython/pyerrors.h' line='158' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyErr_WriteUnraisableMsg'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyErr_SetImportErrorWithNameFrom' filepath='./Include/cpython/pyerrors.h' line='171' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyInterpreterState_ThreadHead' mangled-name='PyInterpreterState_ThreadHead' filepath='./Include/cpython/pystate.h' line='317' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInterpreterState_ThreadHead'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-177'/> + </function-decl> + <function-decl name='PyThreadState_Next' mangled-name='PyThreadState_Next' filepath='./Include/cpython/pystate.h' line='318' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThreadState_Next'> + <parameter type-id='type-id-177'/> + <return type-id='type-id-177'/> + </function-decl> + <function-decl name='_PyNumber_PowerNoMod' filepath='./Include/internal/pycore_abstract.h' line='19' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyNumber_InPlacePowerNoMod' filepath='./Include/internal/pycore_abstract.h' line='20' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyStack_UnpackDict' filepath='./Include/internal/pycore_call.h' line='120' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-177'/> + <parameter type-id='type-id-248'/> + <parameter type-id='type-id-14'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-233'/> + <return type-id='type-id-248'/> + </function-decl> + <function-decl name='_PyStack_UnpackDict_FreeNoDecRef' filepath='./Include/internal/pycore_call.h' line='128' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-248'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_Py_MakeCoro' filepath='./Include/internal/pycore_ceval.h' line='153' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-310'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_Py_HandlePending' filepath='./Include/internal/pycore_ceval.h' line='155' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-177'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_Py_Specialize_LoadSuperAttr' filepath='./Include/internal/pycore_code.h' line='227' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-850'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_Py_Specialize_LoadAttr' filepath='./Include/internal/pycore_code.h' line='229' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-850'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_Py_Specialize_StoreAttr' filepath='./Include/internal/pycore_code.h' line='231' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-850'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_Py_Specialize_LoadGlobal' filepath='./Include/internal/pycore_code.h' line='233' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-850'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_Py_Specialize_BinarySubscr' filepath='./Include/internal/pycore_code.h' line='235' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-850'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_Py_Specialize_StoreSubscr' filepath='./Include/internal/pycore_code.h' line='237' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-850'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_Py_Specialize_Call' filepath='./Include/internal/pycore_code.h' line='239' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-850'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_Py_Specialize_BinaryOp' filepath='./Include/internal/pycore_code.h' line='241' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-850'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-233'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_Py_Specialize_CompareOp' filepath='./Include/internal/pycore_code.h' line='243' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-850'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_Py_Specialize_UnpackSequence' filepath='./Include/internal/pycore_code.h' line='245' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-850'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_Py_Specialize_ForIter' filepath='./Include/internal/pycore_code.h' line='247' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-850'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_Py_Specialize_Send' filepath='./Include/internal/pycore_code.h' line='248' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-850'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_Py_Instrument' filepath='./Include/internal/pycore_code.h' line='486' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-328'/> + <parameter type-id='type-id-20'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyDict_LoadGlobal' filepath='./Include/internal/pycore_dict.h' line='52' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-340'/> + <parameter type-id='type-id-340'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyDict_SetItem_Take2' filepath='./Include/internal/pycore_dict.h' line='55' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-340'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyDict_SendEvent' filepath='./Include/internal/pycore_dict.h' line='156' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-729'/> + <parameter type-id='type-id-340'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyFrame_GetLocals' filepath='./Include/internal/pycore_frame.h' line='230' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-374'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyFrame_FastToLocalsWithError' filepath='./Include/internal/pycore_frame.h' line='233' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-374'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyThreadState_PushFrame' filepath='./Include/internal/pycore_frame.h' line='251' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-177'/> + <parameter type-id='type-id-19'/> + <return type-id='type-id-374'/> + </function-decl> + <function-decl name='_PyThreadState_PopFrame' filepath='./Include/internal/pycore_frame.h' line='253' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-177'/> + <parameter type-id='type-id-374'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyGen_yf' filepath='./Include/internal/pycore_genobject.h' line='11' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-373'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyImport_IsDefaultImportFunc' filepath='./Include/internal/pycore_import.h' line='124' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_Py_call_instrumentation' filepath='./Include/internal/pycore_instruments.h' line='69' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-177'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-374'/> + <parameter type-id='type-id-850'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_Py_call_instrumentation_line' filepath='./Include/internal/pycore_instruments.h' line='73' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-177'/> + <parameter type-id='type-id-374'/> + <parameter type-id='type-id-850'/> + <parameter type-id='type-id-850'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_Py_call_instrumentation_instruction' filepath='./Include/internal/pycore_instruments.h' line='77' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-177'/> + <parameter type-id='type-id-374'/> + <parameter type-id='type-id-850'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_Py_call_instrumentation_jump' filepath='./Include/internal/pycore_instruments.h' line='81' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-177'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-374'/> + <parameter type-id='type-id-850'/> + <parameter type-id='type-id-850'/> + <return type-id='type-id-850'/> + </function-decl> + <function-decl name='_Py_call_instrumentation_arg' filepath='./Include/internal/pycore_instruments.h' line='86' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-177'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-374'/> + <parameter type-id='type-id-850'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_Py_call_instrumentation_2args' filepath='./Include/internal/pycore_instruments.h' line='90' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-177'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-374'/> + <parameter type-id='type-id-850'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_Py_call_instrumentation_exc2' filepath='./Include/internal/pycore_instruments.h' line='94' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-177'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-374'/> + <parameter type-id='type-id-850'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyList_AppendTakeRefListResize' filepath='./Include/internal/pycore_list.h' line='41' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-249'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyList_FromArraySteal' filepath='./Include/internal/pycore_list.h' line='78' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-248'/> + <parameter type-id='type-id-14'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyLong_Add' filepath='./Include/internal/pycore_long.h' line='81' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-241'/> + <parameter type-id='type-id-241'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyLong_Multiply' filepath='./Include/internal/pycore_long.h' line='82' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-241'/> + <parameter type-id='type-id-241'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyLong_Subtract' filepath='./Include/internal/pycore_long.h' line='83' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-241'/> + <parameter type-id='type-id-241'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyErr_SetObject' mangled-name='_PyErr_SetObject' filepath='./Include/internal/pycore_pyerrors.h' line='59' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyErr_SetObject'> + <parameter type-id='type-id-177'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyBuildSlice_ConsumeRefs' filepath='./Include/internal/pycore_sliceobject.h' line='17' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PySys_Audit' filepath='./Include/internal/pycore_sysmodule.h' line='11' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-177'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-12'/> + <parameter is-variadic='yes'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyTuple_FromArraySteal' filepath='./Include/internal/pycore_tuple.h' line='67' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-248'/> + <parameter type-id='type-id-14'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PySuper_Lookup' filepath='./Include/internal/pycore_typeobject.h' line='142' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-179'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyUnicode_ExactDealloc' filepath='./Include/internal/pycore_unicodeobject.h' line='14' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyErr_SetHandledException' mangled-name='PyErr_SetHandledException' filepath='./Include/pyerrors.h' line='25' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_SetHandledException'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyTraceBack_Here' mangled-name='PyTraceBack_Here' filepath='./Include/traceback.h' line='9' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyTraceBack_Here'> + <parameter type-id='type-id-365'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='Py_GetRecursionLimit' mangled-name='Py_GetRecursionLimit' filepath='Python/ceval.c' line='236' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_GetRecursionLimit'> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='Py_SetRecursionLimit' mangled-name='Py_SetRecursionLimit' filepath='Python/ceval.c' line='243' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_SetRecursionLimit'> + <parameter type-id='type-id-8' name='new_limit' filepath='Python/ceval.c' line='243' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyEval_EvalFrame' mangled-name='PyEval_EvalFrame' filepath='Python/ceval.c' line='579' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyEval_EvalFrame'> + <parameter type-id='type-id-365' name='f' filepath='Python/ceval.c' line='579' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyEval_EvalFrameEx' mangled-name='PyEval_EvalFrameEx' filepath='Python/ceval.c' line='587' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyEval_EvalFrameEx'> + <parameter type-id='type-id-365' name='f' filepath='Python/ceval.c' line='587' column='1'/> + <parameter type-id='type-id-8' name='throwflag' filepath='Python/ceval.c' line='587' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyThreadState_EnterTracing' mangled-name='PyThreadState_EnterTracing' filepath='Python/ceval.c' line='2108' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThreadState_EnterTracing'> + <parameter type-id='type-id-177' name='tstate' filepath='Python/ceval.c' line='2108' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyThreadState_LeaveTracing' mangled-name='PyThreadState_LeaveTracing' filepath='Python/ceval.c' line='2115' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThreadState_LeaveTracing'> + <parameter type-id='type-id-177' name='tstate' filepath='Python/ceval.c' line='2115' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyEval_SetProfile' mangled-name='PyEval_SetProfile' filepath='Python/ceval.c' line='2139' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyEval_SetProfile'> + <parameter type-id='type-id-766' name='func' filepath='Python/ceval.c' line='2139' column='1'/> + <parameter type-id='type-id-2' name='arg' filepath='Python/ceval.c' line='2139' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyEval_SetProfileAllThreads' mangled-name='PyEval_SetProfileAllThreads' filepath='Python/ceval.c' line='2149' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyEval_SetProfileAllThreads'> + <parameter type-id='type-id-766' name='func' filepath='Python/ceval.c' line='2149' column='1'/> + <parameter type-id='type-id-2' name='arg' filepath='Python/ceval.c' line='2149' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyEval_SetTrace' mangled-name='PyEval_SetTrace' filepath='Python/ceval.c' line='2170' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyEval_SetTrace'> + <parameter type-id='type-id-766' name='func' filepath='Python/ceval.c' line='2170' column='1'/> + <parameter type-id='type-id-2' name='arg' filepath='Python/ceval.c' line='2170' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyEval_SetTraceAllThreads' mangled-name='PyEval_SetTraceAllThreads' filepath='Python/ceval.c' line='2180' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyEval_SetTraceAllThreads'> + <parameter type-id='type-id-766' name='func' filepath='Python/ceval.c' line='2180' column='1'/> + <parameter type-id='type-id-2' name='arg' filepath='Python/ceval.c' line='2180' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyEval_GetFrame' mangled-name='PyEval_GetFrame' filepath='Python/ceval.c' line='2268' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyEval_GetFrame'> + <return type-id='type-id-365'/> + </function-decl> + <function-decl name='_PyEval_GetBuiltinId' mangled-name='_PyEval_GetBuiltinId' filepath='Python/ceval.c' line='2314' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyEval_GetBuiltinId'> + <parameter type-id='type-id-309' name='name' filepath='Python/ceval.c' line='2314' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyEval_GetLocals' mangled-name='PyEval_GetLocals' filepath='Python/ceval.c' line='2320' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyEval_GetLocals'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyEval_GetFuncName' mangled-name='PyEval_GetFuncName' filepath='Python/ceval.c' line='2382' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyEval_GetFuncName'> + <parameter type-id='type-id-2' name='func' filepath='Python/ceval.c' line='2382' column='1'/> + <return type-id='type-id-12'/> + </function-decl> + <function-decl name='PyEval_GetFuncDesc' mangled-name='PyEval_GetFuncDesc' filepath='Python/ceval.c' line='2395' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyEval_GetFuncDesc'> + <parameter type-id='type-id-2' name='func' filepath='Python/ceval.c' line='2395' column='1'/> + <return type-id='type-id-12'/> + </function-decl> + <function-decl name='PyUnstable_Eval_RequestCodeExtraIndex' mangled-name='PyUnstable_Eval_RequestCodeExtraIndex' filepath='Python/ceval.c' line='2767' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnstable_Eval_RequestCodeExtraIndex'> + <parameter type-id='type-id-397' name='free' filepath='Python/ceval.c' line='2767' column='1'/> + <return type-id='type-id-14'/> + </function-decl> + <function-decl name='Py_EnterRecursiveCall' mangled-name='Py_EnterRecursiveCall' filepath='Python/ceval.c' line='2783' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_EnterRecursiveCall'> + <parameter type-id='type-id-12' name='where' filepath='Python/ceval.c' line='2783' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='Py_LeaveRecursiveCall' mangled-name='Py_LeaveRecursiveCall' filepath='Python/ceval.c' line='2788' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_LeaveRecursiveCall'> + <return type-id='type-id-46'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Python/ceval_gil.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <union-decl name='pthread_mutexattr_t' size-in-bits='32' naming-typedef-id='type-id-1341' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h' line='32' column='1' id='type-id-1342'> + <data-member access='public'> + <var-decl name='__size' type-id='type-id-620' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h' line='34' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='__align' type-id='type-id-8' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h' line='35' column='1'/> + </data-member> + </union-decl> + <typedef-decl name='pthread_mutexattr_t' type-id='type-id-1342' filepath='/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h' line='36' column='1' id='type-id-1341'/> + <typedef-decl name='__time_t' type-id='type-id-47' filepath='/usr/include/x86_64-linux-gnu/bits/types.h' line='160' column='1' id='type-id-1343'/> + <typedef-decl name='__syscall_slong_t' type-id='type-id-47' filepath='/usr/include/x86_64-linux-gnu/bits/types.h' line='197' column='1' id='type-id-116'/> + <class-decl name='timespec' size-in-bits='128' is-struct='yes' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h' line='11' column='1' id='type-id-1344'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='tv_sec' type-id='type-id-1343' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h' line='16' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='tv_nsec' type-id='type-id-116' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h' line='21' column='1'/> + </data-member> + </class-decl> + <pointer-type-def type-id='type-id-801' size-in-bits='64' id='type-id-1345'/> + <qualified-type-def type-id='type-id-1341' const='yes' id='type-id-1346'/> + <pointer-type-def type-id='type-id-1346' size-in-bits='64' id='type-id-1347'/> + <qualified-type-def type-id='type-id-1344' const='yes' id='type-id-1348'/> + <pointer-type-def type-id='type-id-1348' size-in-bits='64' id='type-id-188'/> + <qualified-type-def type-id='type-id-188' restrict='yes' id='type-id-206'/> + <pointer-type-def type-id='type-id-858' size-in-bits='64' id='type-id-1349'/> + <qualified-type-def type-id='type-id-1349' restrict='yes' id='type-id-1350'/> + <pointer-type-def type-id='type-id-859' size-in-bits='64' id='type-id-1351'/> + <qualified-type-def type-id='type-id-1351' restrict='yes' id='type-id-1352'/> + <pointer-type-def type-id='type-id-1344' size-in-bits='64' id='type-id-180'/> + <function-decl name='_PyThread_at_fork_reinit' mangled-name='_PyThread_at_fork_reinit' filepath='./Include/cpython/pythread.h' line='11' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyThread_at_fork_reinit'> + <parameter type-id='type-id-1345'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyThreadState_SwapNoGIL' filepath='./Include/internal/pycore_ceval.h' line='105' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-177'/> + <return type-id='type-id-177'/> + </function-decl> + <function-decl name='_Py_RunGC' filepath='./Include/internal/pycore_gc.h' line='206' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-177'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyErr_CheckSignalsTstate' mangled-name='_PyErr_CheckSignalsTstate' filepath='./Include/internal/pycore_pyerrors.h' line='104' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyErr_CheckSignalsTstate'> + <parameter type-id='type-id-177'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyErr_Print' mangled-name='_PyErr_Print' filepath='./Include/internal/pycore_pylifecycle.h' line='87' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyErr_Print'> + <parameter type-id='type-id-177'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyThreadState_DeleteExcept' mangled-name='_PyThreadState_DeleteExcept' filepath='./Include/internal/pycore_pystate.h' line='129' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyThreadState_DeleteExcept'> + <parameter type-id='type-id-177'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyThread_init_thread' mangled-name='PyThread_init_thread' filepath='./Include/pythread.h' line='18' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThread_init_thread'> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyThread_exit_thread' mangled-name='PyThread_exit_thread' filepath='./Include/pythread.h' line='20' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThread_exit_thread'> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyThread_get_thread_ident' mangled-name='PyThread_get_thread_ident' filepath='./Include/pythread.h' line='21' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThread_get_thread_ident'> + <return type-id='type-id-28'/> + </function-decl> + <function-decl name='PyThread_free_lock' mangled-name='PyThread_free_lock' filepath='./Include/pythread.h' line='31' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThread_free_lock'> + <parameter type-id='type-id-801'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='pthread_mutex_init' filepath='/usr/include/pthread.h' line='781' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1351'/> + <parameter type-id='type-id-1347'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='pthread_mutex_destroy' filepath='/usr/include/pthread.h' line='786' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1351'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='pthread_mutex_lock' filepath='/usr/include/pthread.h' line='794' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1351'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='pthread_mutex_unlock' filepath='/usr/include/pthread.h' line='835' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1351'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='pthread_cond_destroy' filepath='/usr/include/pthread.h' line='1117' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1349'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='pthread_cond_signal' filepath='/usr/include/pthread.h' line='1121' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1349'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='pthread_cond_wait' filepath='/usr/include/pthread.h' line='1133' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1350'/> + <parameter type-id='type-id-1352'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='pthread_cond_timedwait' filepath='/usr/include/pthread.h' line='1145' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1350'/> + <parameter type-id='type-id-1352'/> + <parameter type-id='type-id-206'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyEval_SetSwitchInterval' mangled-name='_PyEval_SetSwitchInterval' filepath='Python/ceval_gil.c' line='492' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyEval_SetSwitchInterval'> + <parameter type-id='type-id-28' name='microseconds' filepath='Python/ceval_gil.c' line='492' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyEval_GetSwitchInterval' mangled-name='_PyEval_GetSwitchInterval' filepath='Python/ceval_gil.c' line='500' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyEval_GetSwitchInterval'> + <return type-id='type-id-28'/> + </function-decl> + <function-decl name='PyEval_ThreadsInitialized' mangled-name='PyEval_ThreadsInitialized' filepath='Python/ceval_gil.c' line='524' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyEval_ThreadsInitialized'> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyEval_InitThreads' mangled-name='PyEval_InitThreads' filepath='Python/ceval_gil.c' line='612' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyEval_InitThreads'> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyEval_AcquireLock' mangled-name='PyEval_AcquireLock' filepath='Python/ceval_gil.c' line='625' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyEval_AcquireLock'> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyEval_ReleaseLock' mangled-name='PyEval_ReleaseLock' filepath='Python/ceval_gil.c' line='634' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyEval_ReleaseLock'> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyEval_AcquireThread' mangled-name='PyEval_AcquireThread' filepath='Python/ceval_gil.c' line='662' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyEval_AcquireThread'> + <parameter type-id='type-id-177' name='tstate' filepath='Python/ceval_gil.c' line='662' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyEval_ReleaseThread' mangled-name='PyEval_ReleaseThread' filepath='Python/ceval_gil.c' line='674' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyEval_ReleaseThread'> + <parameter type-id='type-id-177' name='tstate' filepath='Python/ceval_gil.c' line='674' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyEval_SignalAsyncExc' mangled-name='_PyEval_SignalAsyncExc' filepath='Python/ceval_gil.c' line='718' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyEval_SignalAsyncExc'> + <parameter type-id='type-id-20' name='interp' filepath='Python/ceval_gil.c' line='718' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyEval_SignalReceived' mangled-name='_PyEval_SignalReceived' filepath='Python/ceval_gil.c' line='769' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyEval_SignalReceived'> + <parameter type-id='type-id-20' name='interp' filepath='Python/ceval_gil.c' line='769' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyEval_AddPendingCall' mangled-name='_PyEval_AddPendingCall' filepath='Python/ceval_gil.c' line='838' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyEval_AddPendingCall'> + <parameter type-id='type-id-20' name='interp' filepath='Python/ceval_gil.c' line='838' column='1'/> + <parameter type-id='type-id-814' name='func' filepath='Python/ceval_gil.c' line='839' column='1'/> + <parameter type-id='type-id-22' name='arg' filepath='Python/ceval_gil.c' line='839' column='1'/> + <parameter type-id='type-id-8' name='mainthreadonly' filepath='Python/ceval_gil.c' line='840' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='Py_AddPendingCall' mangled-name='Py_AddPendingCall' filepath='Python/ceval_gil.c' line='863' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_AddPendingCall'> + <parameter type-id='type-id-814' name='func' filepath='Python/ceval_gil.c' line='863' column='1'/> + <parameter type-id='type-id-22' name='arg' filepath='Python/ceval_gil.c' line='863' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyEval_MakePendingCalls' mangled-name='_PyEval_MakePendingCalls' filepath='Python/ceval_gil.c' line='991' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyEval_MakePendingCalls'> + <parameter type-id='type-id-177' name='tstate' filepath='Python/ceval_gil.c' line='991' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='Py_MakePendingCalls' mangled-name='Py_MakePendingCalls' filepath='Python/ceval_gil.c' line='1016' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_MakePendingCalls'> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyThread_cond_init' filepath='Python/condvar.h' line='52' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1349'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyThread_cond_after' filepath='Python/condvar.h' line='53' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-378'/> + <parameter type-id='type-id-180'/> + <return type-id='type-id-46'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Python/codecs.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <var-decl name='Py_hexdigits' type-id='type-id-12' mangled-name='Py_hexdigits' visibility='default' filepath='./Include/codecs.h' line='242' column='1' elf-symbol-id='Py_hexdigits'/> + <function-decl name='PyCodec_Register' mangled-name='PyCodec_Register' filepath='Python/codecs.c' line='36' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCodec_Register'> + <parameter type-id='type-id-2' name='search_function' filepath='Python/codecs.c' line='36' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyCodec_Unregister' mangled-name='PyCodec_Unregister' filepath='Python/codecs.c' line='56' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCodec_Unregister'> + <parameter type-id='type-id-2' name='search_function' filepath='Python/codecs.c' line='56' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_Py_normalize_encoding' filepath='Python/codecs.c' line='80' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-15'/> + <parameter type-id='type-id-19'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyCodec_KnownEncoding' mangled-name='PyCodec_KnownEncoding' filepath='Python/codecs.c' line='215' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCodec_KnownEncoding'> + <parameter type-id='type-id-12' name='encoding' filepath='Python/codecs.c' line='215' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyCodecInfo_GetIncrementalDecoder' mangled-name='_PyCodecInfo_GetIncrementalDecoder' filepath='Python/codecs.c' line='329' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyCodecInfo_GetIncrementalDecoder'> + <parameter type-id='type-id-2' name='codec_info' filepath='Python/codecs.c' line='329' column='1'/> + <parameter type-id='type-id-12' name='errors' filepath='Python/codecs.c' line='330' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyCodecInfo_GetIncrementalEncoder' mangled-name='_PyCodecInfo_GetIncrementalEncoder' filepath='Python/codecs.c' line='336' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyCodecInfo_GetIncrementalEncoder'> + <parameter type-id='type-id-2' name='codec_info' filepath='Python/codecs.c' line='336' column='1'/> + <parameter type-id='type-id-12' name='errors' filepath='Python/codecs.c' line='337' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyCodec_Encoder' mangled-name='PyCodec_Encoder' filepath='Python/codecs.c' line='350' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCodec_Encoder'> + <parameter type-id='type-id-12' name='encoding' filepath='Python/codecs.c' line='350' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyCodec_Decoder' mangled-name='PyCodec_Decoder' filepath='Python/codecs.c' line='355' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCodec_Decoder'> + <parameter type-id='type-id-12' name='encoding' filepath='Python/codecs.c' line='355' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyCodec_IncrementalEncoder' mangled-name='PyCodec_IncrementalEncoder' filepath='Python/codecs.c' line='360' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCodec_IncrementalEncoder'> + <parameter type-id='type-id-12' name='encoding' filepath='Python/codecs.c' line='360' column='1'/> + <parameter type-id='type-id-12' name='errors' filepath='Python/codecs.c' line='361' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyCodec_IncrementalDecoder' mangled-name='PyCodec_IncrementalDecoder' filepath='Python/codecs.c' line='366' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCodec_IncrementalDecoder'> + <parameter type-id='type-id-12' name='encoding' filepath='Python/codecs.c' line='366' column='1'/> + <parameter type-id='type-id-12' name='errors' filepath='Python/codecs.c' line='367' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyCodec_StreamReader' mangled-name='PyCodec_StreamReader' filepath='Python/codecs.c' line='372' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCodec_StreamReader'> + <parameter type-id='type-id-12' name='encoding' filepath='Python/codecs.c' line='372' column='1'/> + <parameter type-id='type-id-2' name='stream' filepath='Python/codecs.c' line='373' column='1'/> + <parameter type-id='type-id-12' name='errors' filepath='Python/codecs.c' line='374' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyCodec_StreamWriter' mangled-name='PyCodec_StreamWriter' filepath='Python/codecs.c' line='379' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCodec_StreamWriter'> + <parameter type-id='type-id-12' name='encoding' filepath='Python/codecs.c' line='379' column='1'/> + <parameter type-id='type-id-2' name='stream' filepath='Python/codecs.c' line='380' column='1'/> + <parameter type-id='type-id-12' name='errors' filepath='Python/codecs.c' line='381' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyCodec_LookupTextEncoding' mangled-name='_PyCodec_LookupTextEncoding' filepath='Python/codecs.c' line='503' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyCodec_LookupTextEncoding'> + <parameter type-id='type-id-12' name='encoding' filepath='Python/codecs.c' line='503' column='1'/> + <parameter type-id='type-id-12' name='alternate_command' filepath='Python/codecs.c' line='504' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyCodec_RegisterError' mangled-name='PyCodec_RegisterError' filepath='Python/codecs.c' line='602' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCodec_RegisterError'> + <parameter type-id='type-id-12' name='name' filepath='Python/codecs.c' line='602' column='1'/> + <parameter type-id='type-id-2' name='error' filepath='Python/codecs.c' line='602' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyCodec_IgnoreErrors' mangled-name='PyCodec_IgnoreErrors' filepath='Python/codecs.c' line='655' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCodec_IgnoreErrors'> + <parameter type-id='type-id-2' name='exc' filepath='Python/codecs.c' line='655' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyCodec_ReplaceErrors' mangled-name='PyCodec_ReplaceErrors' filepath='Python/codecs.c' line='679' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCodec_ReplaceErrors'> + <parameter type-id='type-id-2' name='exc' filepath='Python/codecs.c' line='679' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyCodec_XMLCharRefReplaceErrors' mangled-name='PyCodec_XMLCharRefReplaceErrors' filepath='Python/codecs.c' line='732' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCodec_XMLCharRefReplaceErrors'> + <parameter type-id='type-id-2' name='exc' filepath='Python/codecs.c' line='732' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyCodec_BackslashReplaceErrors' mangled-name='PyCodec_BackslashReplaceErrors' filepath='Python/codecs.c' line='830' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCodec_BackslashReplaceErrors'> + <parameter type-id='type-id-2' name='exc' filepath='Python/codecs.c' line='830' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyCodec_NameReplaceErrors' mangled-name='PyCodec_NameReplaceErrors' filepath='Python/codecs.c' line='939' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCodec_NameReplaceErrors'> + <parameter type-id='type-id-2' name='exc' filepath='Python/codecs.c' line='939' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Python/compile.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <array-type-def dimensions='1' type-id='type-id-1353' size-in-bits='1344' id='type-id-1354'> + <subrange length='21' type-id='type-id-28' id='type-id-670'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-1355' size-in-bits='288' id='type-id-1356'> + <subrange length='9' type-id='type-id-28' id='type-id-695'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-326' size-in-bits='2048' id='type-id-1357'> + <subrange length='256' type-id='type-id-28' id='type-id-62'/> + </array-type-def> + <class-decl name='_PyCompilerSrcLocation' size-in-bits='128' is-struct='yes' naming-typedef-id='type-id-1358' visibility='default' filepath='./Include/cpython/compile.h' line='35' column='1' id='type-id-1359'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='lineno' type-id='type-id-8' visibility='default' filepath='./Include/cpython/compile.h' line='36' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='32'> + <var-decl name='end_lineno' type-id='type-id-8' visibility='default' filepath='./Include/cpython/compile.h' line='37' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='col_offset' type-id='type-id-8' visibility='default' filepath='./Include/cpython/compile.h' line='38' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='96'> + <var-decl name='end_col_offset' type-id='type-id-8' visibility='default' filepath='./Include/cpython/compile.h' line='39' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='_PyCompilerSrcLocation' type-id='type-id-1359' filepath='./Include/cpython/compile.h' line='40' column='1' id='type-id-1358'/> + <class-decl name='PyFutureFeatures' size-in-bits='160' is-struct='yes' naming-typedef-id='type-id-1360' visibility='default' filepath='./Include/cpython/compile.h' line='51' column='1' id='type-id-1361'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='ff_features' type-id='type-id-8' visibility='default' filepath='./Include/cpython/compile.h' line='52' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='32'> + <var-decl name='ff_location' type-id='type-id-1358' visibility='default' filepath='./Include/cpython/compile.h' line='53' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='PyFutureFeatures' type-id='type-id-1361' filepath='./Include/cpython/compile.h' line='54' column='1' id='type-id-1360'/> + <class-decl name='_PyASTOptimizeState' size-in-bits='128' is-struct='yes' naming-typedef-id='type-id-1362' visibility='default' filepath='./Include/internal/pycore_compile.h' line='24' column='1' id='type-id-1363'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='optimize' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_compile.h' line='25' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='32'> + <var-decl name='ff_features' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_compile.h' line='26' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='recursion_depth' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_compile.h' line='28' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='96'> + <var-decl name='recursion_limit' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_compile.h' line='29' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='_PyASTOptimizeState' type-id='type-id-1363' filepath='./Include/internal/pycore_compile.h' line='30' column='1' id='type-id-1362'/> + <class-decl name='_PyCompile_ExceptHandlerInfo' size-in-bits='96' is-struct='yes' naming-typedef-id='type-id-1364' visibility='default' filepath='./Include/internal/pycore_compile.h' line='37' column='1' id='type-id-1365'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='h_offset' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_compile.h' line='38' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='32'> + <var-decl name='h_startdepth' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_compile.h' line='39' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='h_preserve_lasti' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_compile.h' line='40' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='_PyCompile_ExceptHandlerInfo' type-id='type-id-1365' filepath='./Include/internal/pycore_compile.h' line='41' column='1' id='type-id-1364'/> + <class-decl name='_PyCompile_Instruction' size-in-bits='288' is-struct='yes' naming-typedef-id='type-id-1366' visibility='default' filepath='./Include/internal/pycore_compile.h' line='43' column='1' id='type-id-1367'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='i_opcode' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_compile.h' line='44' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='32'> + <var-decl name='i_oparg' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_compile.h' line='45' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='i_loc' type-id='type-id-1358' visibility='default' filepath='./Include/internal/pycore_compile.h' line='46' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='i_except_handler_info' type-id='type-id-1364' visibility='default' filepath='./Include/internal/pycore_compile.h' line='47' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='_PyCompile_Instruction' type-id='type-id-1367' filepath='./Include/internal/pycore_compile.h' line='48' column='1' id='type-id-1366'/> + <class-decl name='_PyCompile_InstructionSequence' size-in-bits='256' is-struct='yes' naming-typedef-id='type-id-1368' visibility='default' filepath='./Include/internal/pycore_compile.h' line='50' column='1' id='type-id-1369'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='s_instrs' type-id='type-id-1370' visibility='default' filepath='./Include/internal/pycore_compile.h' line='51' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='s_allocated' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_compile.h' line='52' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='96'> + <var-decl name='s_used' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_compile.h' line='53' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='s_labelmap' type-id='type-id-179' visibility='default' filepath='./Include/internal/pycore_compile.h' line='55' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='s_labelmap_size' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_compile.h' line='56' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='224'> + <var-decl name='s_next_free_label' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_compile.h' line='57' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='_PyCompile_InstructionSequence' type-id='type-id-1369' filepath='./Include/internal/pycore_compile.h' line='58' column='1' id='type-id-1368'/> + <class-decl name='_PyCompile_CodeUnitMetadata' size-in-bits='768' is-struct='yes' naming-typedef-id='type-id-1371' visibility='default' filepath='./Include/internal/pycore_compile.h' line='60' column='1' id='type-id-1372'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='u_name' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_compile.h' line='61' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='u_qualname' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_compile.h' line='62' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='u_consts' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_compile.h' line='68' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='u_names' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_compile.h' line='69' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='u_varnames' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_compile.h' line='70' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='u_cellvars' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_compile.h' line='71' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='384'> + <var-decl name='u_freevars' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_compile.h' line='72' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='448'> + <var-decl name='u_fasthidden' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_compile.h' line='73' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='512'> + <var-decl name='u_argcount' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_compile.h' line='77' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='576'> + <var-decl name='u_posonlyargcount' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_compile.h' line='78' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='640'> + <var-decl name='u_kwonlyargcount' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_compile.h' line='79' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='704'> + <var-decl name='u_firstlineno' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_compile.h' line='81' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='_PyCompile_CodeUnitMetadata' type-id='type-id-1372' filepath='./Include/internal/pycore_compile.h' line='82' column='1' id='type-id-1371'/> + <class-decl name='_PyCfgInstruction' size-in-bits='320' is-struct='yes' naming-typedef-id='type-id-1373' visibility='default' filepath='./Include/internal/pycore_flowgraph.h' line='15' column='1' id='type-id-1374'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='i_opcode' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_flowgraph.h' line='16' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='32'> + <var-decl name='i_oparg' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_flowgraph.h' line='17' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='i_loc' type-id='type-id-1358' visibility='default' filepath='./Include/internal/pycore_flowgraph.h' line='18' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='i_target' type-id='type-id-1353' visibility='default' filepath='./Include/internal/pycore_flowgraph.h' line='19' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='i_except' type-id='type-id-1353' visibility='default' filepath='./Include/internal/pycore_flowgraph.h' line='20' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='_PyCfgInstruction' type-id='type-id-1374' filepath='./Include/internal/pycore_flowgraph.h' line='21' column='1' id='type-id-1373'/> + <class-decl name='_PyCfgJumpTargetLabel' size-in-bits='32' is-struct='yes' naming-typedef-id='type-id-1375' visibility='default' filepath='./Include/internal/pycore_flowgraph.h' line='23' column='1' id='type-id-1376'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='id' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_flowgraph.h' line='24' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='_PyCfgJumpTargetLabel' type-id='type-id-1376' filepath='./Include/internal/pycore_flowgraph.h' line='25' column='1' id='type-id-1375'/> + <class-decl name='_PyCfgExceptStack' size-in-bits='1408' is-struct='yes' naming-typedef-id='type-id-1377' visibility='default' filepath='./Include/internal/pycore_flowgraph.h' line='28' column='1' id='type-id-1378'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='handlers' type-id='type-id-1354' visibility='default' filepath='./Include/internal/pycore_flowgraph.h' line='29' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='1344'> + <var-decl name='depth' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_flowgraph.h' line='30' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='_PyCfgExceptStack' type-id='type-id-1378' filepath='./Include/internal/pycore_flowgraph.h' line='31' column='1' id='type-id-1377'/> + <class-decl name='_PyCfgBasicblock_' size-in-bits='576' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_flowgraph.h' line='33' column='1' id='type-id-1379'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='b_list' type-id='type-id-1353' visibility='default' filepath='./Include/internal/pycore_flowgraph.h' line='38' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='b_label' type-id='type-id-1375' visibility='default' filepath='./Include/internal/pycore_flowgraph.h' line='40' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='b_exceptstack' type-id='type-id-1380' visibility='default' filepath='./Include/internal/pycore_flowgraph.h' line='42' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='b_instr' type-id='type-id-1381' visibility='default' filepath='./Include/internal/pycore_flowgraph.h' line='44' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='b_next' type-id='type-id-1353' visibility='default' filepath='./Include/internal/pycore_flowgraph.h' line='47' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='b_iused' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_flowgraph.h' line='49' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='352'> + <var-decl name='b_ialloc' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_flowgraph.h' line='51' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='384'> + <var-decl name='b_unsafe_locals_mask' type-id='type-id-117' visibility='default' filepath='./Include/internal/pycore_flowgraph.h' line='53' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='448'> + <var-decl name='b_predecessors' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_flowgraph.h' line='55' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='480'> + <var-decl name='b_startdepth' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_flowgraph.h' line='57' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='512'> + <var-decl name='b_offset' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_flowgraph.h' line='59' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='544'> + <var-decl name='b_preserve_lasti' type-id='type-id-95' visibility='default' filepath='./Include/internal/pycore_flowgraph.h' line='61' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='545'> + <var-decl name='b_visited' type-id='type-id-95' visibility='default' filepath='./Include/internal/pycore_flowgraph.h' line='63' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='546'> + <var-decl name='b_except_handler' type-id='type-id-95' visibility='default' filepath='./Include/internal/pycore_flowgraph.h' line='65' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='547'> + <var-decl name='b_cold' type-id='type-id-95' visibility='default' filepath='./Include/internal/pycore_flowgraph.h' line='67' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='548'> + <var-decl name='b_warm' type-id='type-id-95' visibility='default' filepath='./Include/internal/pycore_flowgraph.h' line='69' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='_PyCfgBasicblock' type-id='type-id-1379' filepath='./Include/internal/pycore_flowgraph.h' line='70' column='1' id='type-id-1382'/> + <class-decl name='cfg_builder_' size-in-bits='256' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_flowgraph.h' line='74' column='1' id='type-id-1383'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='g_entryblock' type-id='type-id-1384' visibility='default' filepath='./Include/internal/pycore_flowgraph.h' line='77' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='g_block_list' type-id='type-id-1384' visibility='default' filepath='./Include/internal/pycore_flowgraph.h' line='80' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='g_curblock' type-id='type-id-1384' visibility='default' filepath='./Include/internal/pycore_flowgraph.h' line='82' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='g_current_label' type-id='type-id-1375' visibility='default' filepath='./Include/internal/pycore_flowgraph.h' line='84' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='_PyCfgBuilder' type-id='type-id-1383' filepath='./Include/internal/pycore_flowgraph.h' line='85' column='1' id='type-id-1385'/> + <enum-decl name='_block_type' filepath='./Include/internal/pycore_symtable.h' line='13' column='1' id='type-id-1386'> + <underlying-type type-id='type-id-24'/> + <enumerator name='FunctionBlock' value='0'/> + <enumerator name='ClassBlock' value='1'/> + <enumerator name='ModuleBlock' value='2'/> + <enumerator name='AnnotationBlock' value='3'/> + <enumerator name='TypeVarBoundBlock' value='4'/> + <enumerator name='TypeAliasBlock' value='5'/> + <enumerator name='TypeParamBlock' value='6'/> + </enum-decl> + <typedef-decl name='_Py_block_ty' type-id='type-id-1386' filepath='./Include/internal/pycore_symtable.h' line='23' column='1' id='type-id-1387'/> + <enum-decl name='_comprehension_type' filepath='./Include/internal/pycore_symtable.h' line='25' column='1' id='type-id-1388'> + <underlying-type type-id='type-id-24'/> + <enumerator name='NoComprehension' value='0'/> + <enumerator name='ListComprehension' value='1'/> + <enumerator name='DictComprehension' value='2'/> + <enumerator name='SetComprehension' value='3'/> + <enumerator name='GeneratorExpression' value='4'/> + </enum-decl> + <typedef-decl name='_Py_comprehension_ty' type-id='type-id-1388' filepath='./Include/internal/pycore_symtable.h' line='30' column='1' id='type-id-1389'/> + <class-decl name='symtable' size-in-bits='640' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='34' column='1' id='type-id-1390'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='st_filename' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='35' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='st_cur' type-id='type-id-1391' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='37' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='st_top' type-id='type-id-1391' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='38' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='st_blocks' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='39' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='st_stack' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='41' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='st_global' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='42' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='384'> + <var-decl name='st_nblocks' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='43' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='448'> + <var-decl name='st_private' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='46' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='512'> + <var-decl name='st_future' type-id='type-id-1392' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='47' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='576'> + <var-decl name='recursion_depth' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='49' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='608'> + <var-decl name='recursion_limit' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='50' column='1'/> + </data-member> + </class-decl> + <class-decl name='_symtable_entry' size-in-bits='960' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='53' column='1' id='type-id-1393'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='ob_base' type-id='type-id-345' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='54' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='ste_id' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='55' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='ste_symbols' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='56' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='ste_name' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='57' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='ste_varnames' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='58' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='384'> + <var-decl name='ste_children' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='59' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='448'> + <var-decl name='ste_directives' type-id='type-id-2' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='60' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='512'> + <var-decl name='ste_type' type-id='type-id-1387' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='61' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='544'> + <var-decl name='ste_nested' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='62' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='576'> + <var-decl name='ste_free' type-id='type-id-95' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='63' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='577'> + <var-decl name='ste_child_free' type-id='type-id-95' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='64' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='578'> + <var-decl name='ste_generator' type-id='type-id-95' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='66' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='579'> + <var-decl name='ste_coroutine' type-id='type-id-95' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='67' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='608'> + <var-decl name='ste_comprehension' type-id='type-id-1389' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='68' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='640'> + <var-decl name='ste_varargs' type-id='type-id-95' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='69' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='641'> + <var-decl name='ste_varkeywords' type-id='type-id-95' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='70' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='642'> + <var-decl name='ste_returns_value' type-id='type-id-95' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='71' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='643'> + <var-decl name='ste_needs_class_closure' type-id='type-id-95' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='73' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='644'> + <var-decl name='ste_needs_classdict' type-id='type-id-95' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='76' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='645'> + <var-decl name='ste_comp_inlined' type-id='type-id-95' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='78' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='646'> + <var-decl name='ste_comp_iter_target' type-id='type-id-95' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='79' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='647'> + <var-decl name='ste_can_see_class_scope' type-id='type-id-95' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='80' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='672'> + <var-decl name='ste_comp_iter_expr' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='82' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='704'> + <var-decl name='ste_lineno' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='83' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='736'> + <var-decl name='ste_col_offset' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='84' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='768'> + <var-decl name='ste_end_lineno' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='85' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='800'> + <var-decl name='ste_end_col_offset' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='86' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='832'> + <var-decl name='ste_opt_lineno' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='87' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='864'> + <var-decl name='ste_opt_col_offset' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='88' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='896'> + <var-decl name='ste_table' type-id='type-id-209' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='89' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='PySTEntryObject' type-id='type-id-1393' filepath='./Include/internal/pycore_symtable.h' line='90' column='1' id='type-id-1394'/> + <typedef-decl name='basicblock' type-id='type-id-1382' filepath='Python/compile.c' line='90' column='1' id='type-id-1395'/> + <pointer-type-def type-id='type-id-1360' size-in-bits='64' id='type-id-1392'/> + <pointer-type-def type-id='type-id-1394' size-in-bits='64' id='type-id-1396'/> + <pointer-type-def type-id='type-id-1362' size-in-bits='64' id='type-id-1397'/> + <pointer-type-def type-id='type-id-1382' size-in-bits='64' id='type-id-1384'/> + <pointer-type-def type-id='type-id-1379' size-in-bits='64' id='type-id-1353'/> + <pointer-type-def type-id='type-id-1385' size-in-bits='64' id='type-id-1398'/> + <pointer-type-def type-id='type-id-1377' size-in-bits='64' id='type-id-1380'/> + <pointer-type-def type-id='type-id-1373' size-in-bits='64' id='type-id-1381'/> + <pointer-type-def type-id='type-id-1371' size-in-bits='64' id='type-id-1399'/> + <pointer-type-def type-id='type-id-1366' size-in-bits='64' id='type-id-1370'/> + <pointer-type-def type-id='type-id-1368' size-in-bits='64' id='type-id-1400'/> + <pointer-type-def type-id='type-id-1393' size-in-bits='64' id='type-id-1391'/> + <pointer-type-def type-id='type-id-1395' size-in-bits='64' id='type-id-1401'/> + <qualified-type-def type-id='type-id-352' const='yes' id='type-id-1355'/> + <pointer-type-def type-id='type-id-1390' size-in-bits='64' id='type-id-209'/> + <function-decl name='PyErr_ProgramTextObject' mangled-name='PyErr_ProgramTextObject' filepath='./Include/cpython/pyerrors.h' line='142' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_ProgramTextObject'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyAST_ExprAsUnicode' filepath='./Include/internal/pycore_ast.h' line='912' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-502'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyCode_GetFreevars' filepath='./Include/internal/pycore_code.h' line='208' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-328'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyAST_Optimize' filepath='./Include/internal/pycore_compile.h' line='32' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-467'/> + <parameter type-id='type-id-1340'/> + <parameter type-id='type-id-1397'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyBasicblock_InsertInstruction' filepath='./Include/internal/pycore_flowgraph.h' line='72' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1384'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-1381'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyCfgBuilder_UseLabel' filepath='./Include/internal/pycore_flowgraph.h' line='87' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1398'/> + <parameter type-id='type-id-1375'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyCfgBuilder_Addop' filepath='./Include/internal/pycore_flowgraph.h' line='88' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1398'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-1358'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyCfgBuilder_Init' filepath='./Include/internal/pycore_flowgraph.h' line='90' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1398'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyCfgBuilder_Fini' filepath='./Include/internal/pycore_flowgraph.h' line='91' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1398'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyCfg_OptimizeCodeUnit' filepath='./Include/internal/pycore_flowgraph.h' line='94' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1398'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyCfg_Stackdepth' filepath='./Include/internal/pycore_flowgraph.h' line='96' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1384'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyCfg_ConvertPseudoOps' filepath='./Include/internal/pycore_flowgraph.h' line='97' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1384'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyCfg_ResolveJumps' filepath='./Include/internal/pycore_flowgraph.h' line='98' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1398'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyAssemble_MakeCodeObject' filepath='./Include/internal/pycore_flowgraph.h' line='113' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1399'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-1400'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-328'/> + </function-decl> + <var-decl name='_PyOpcode_Jump' type-id='type-id-1356' visibility='default' filepath='./Include/internal/pycore_opcode.h' line='15' column='1'/> + <var-decl name='_PyOpcode_Caches' type-id='type-id-1357' visibility='default' filepath='./Include/internal/pycore_opcode.h' line='17' column='1'/> + <var-decl name='_PyOpcode_Deopt' type-id='type-id-1357' visibility='default' filepath='./Include/internal/pycore_opcode.h' line='19' column='1'/> + <function-decl name='_PyST_GetSymbol' filepath='./Include/internal/pycore_symtable.h' line='96' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1396'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-47'/> + </function-decl> + <function-decl name='_PyST_GetScope' filepath='./Include/internal/pycore_symtable.h' line='97' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1396'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyST_IsFunctionLike' filepath='./Include/internal/pycore_symtable.h' line='98' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1396'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PySymtable_Build' filepath='./Include/internal/pycore_symtable.h' line='100' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-467'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-1392'/> + <return type-id='type-id-209'/> + </function-decl> + <function-decl name='PySymtable_Lookup' mangled-name='PySymtable_Lookup' filepath='./Include/internal/pycore_symtable.h' line='104' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySymtable_Lookup'> + <parameter type-id='type-id-209'/> + <parameter type-id='type-id-22'/> + <return type-id='type-id-1396'/> + </function-decl> + <function-decl name='_PySymtable_Free' filepath='./Include/internal/pycore_symtable.h' line='106' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-209'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyFuture_FromAST' filepath='./Include/internal/pycore_symtable.h' line='150' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-467'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-1392'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyCompile_OpcodeStackEffectWithJump' mangled-name='PyCompile_OpcodeStackEffectWithJump' filepath='Python/compile.c' line='880' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCompile_OpcodeStackEffectWithJump'> + <parameter type-id='type-id-8' name='opcode' filepath='Python/compile.c' line='880' column='1'/> + <parameter type-id='type-id-8' name='oparg' filepath='Python/compile.c' line='880' column='1'/> + <parameter type-id='type-id-8' name='jump' filepath='Python/compile.c' line='880' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyCompile_CodeGen' mangled-name='_PyCompile_CodeGen' filepath='Python/compile.c' line='7973' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyCompile_CodeGen'> + <parameter type-id='type-id-2' name='ast' filepath='Python/compile.c' line='7973' column='1'/> + <parameter type-id='type-id-2' name='filename' filepath='Python/compile.c' line='7973' column='1'/> + <parameter type-id='type-id-208' name='pflags' filepath='Python/compile.c' line='7973' column='1'/> + <parameter type-id='type-id-8' name='optimize' filepath='Python/compile.c' line='7974' column='1'/> + <parameter type-id='type-id-8' name='compile_mode' filepath='Python/compile.c' line='7974' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyCompile_OptimizeCfg' mangled-name='_PyCompile_OptimizeCfg' filepath='Python/compile.c' line='8058' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyCompile_OptimizeCfg'> + <parameter type-id='type-id-2' name='instructions' filepath='Python/compile.c' line='8058' column='1'/> + <parameter type-id='type-id-2' name='consts' filepath='Python/compile.c' line='8058' column='1'/> + <parameter type-id='type-id-8' name='nlocals' filepath='Python/compile.c' line='8058' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyCfg_JumpLabelsToTargets' filepath='Python/compile.c' line='8082' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1401'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyCompile_Assemble' mangled-name='_PyCompile_Assemble' filepath='Python/compile.c' line='8085' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyCompile_Assemble'> + <parameter type-id='type-id-1399' name='umd' filepath='Python/compile.c' line='8085' column='1'/> + <parameter type-id='type-id-2' name='filename' filepath='Python/compile.c' line='8085' column='1'/> + <parameter type-id='type-id-2' name='instructions' filepath='Python/compile.c' line='8086' column='1'/> + <return type-id='type-id-328'/> + </function-decl> + <function-decl name='PyCode_Optimize' mangled-name='PyCode_Optimize' filepath='Python/compile.c' line='8152' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyCode_Optimize'> + <parameter type-id='type-id-2' name='code' filepath='Python/compile.c' line='8152' column='1'/> + <parameter type-id='type-id-2' name='_unused_consts' filepath='Python/compile.c' line='8152' column='1'/> + <parameter type-id='type-id-2' name='_unused_names' filepath='Python/compile.c' line='8153' column='1'/> + <parameter type-id='type-id-2' name='_unused_lnotab_obj' filepath='Python/compile.c' line='8153' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyOpcode_num_popped' filepath='Python/opcode_metadata.h' line='7' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-615'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyOpcode_num_pushed' filepath='Python/opcode_metadata.h' line='403' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-615'/> + <return type-id='type-id-8'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Python/context.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <var-decl name='PyContext_Type' type-id='type-id-256' mangled-name='PyContext_Type' visibility='default' filepath='./Include/cpython/context.h' line='8' column='1' elf-symbol-id='PyContext_Type'/> + <var-decl name='PyContextVar_Type' type-id='type-id-256' mangled-name='PyContextVar_Type' visibility='default' filepath='./Include/cpython/context.h' line='11' column='1' elf-symbol-id='PyContextVar_Type'/> + <var-decl name='PyContextToken_Type' type-id='type-id-256' mangled-name='PyContextToken_Type' visibility='default' filepath='./Include/cpython/context.h' line='14' column='1' elf-symbol-id='PyContextToken_Type'/> + <var-decl name='_PyContextTokenMissing_Type' type-id='type-id-256' visibility='default' filepath='./Include/internal/pycore_context.h' line='11' column='1'/> + <function-decl name='_PyHamt_New' filepath='./Include/internal/pycore_hamt.h' line='95' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-830'/> + </function-decl> + <function-decl name='_PyHamt_Assoc' filepath='./Include/internal/pycore_hamt.h' line='99' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-830'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-830'/> + </function-decl> + <function-decl name='_PyHamt_Without' filepath='./Include/internal/pycore_hamt.h' line='102' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-830'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-830'/> + </function-decl> + <function-decl name='_PyHamt_Find' filepath='./Include/internal/pycore_hamt.h' line='111' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-830'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-233'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyHamt_Eq' filepath='./Include/internal/pycore_hamt.h' line='120' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-830'/> + <parameter type-id='type-id-830'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyHamt_Len' filepath='./Include/internal/pycore_hamt.h' line='123' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-830'/> + <return type-id='type-id-14'/> + </function-decl> + <function-decl name='_PyHamt_NewIterKeys' filepath='./Include/internal/pycore_hamt.h' line='126' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-830'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyHamt_NewIterValues' filepath='./Include/internal/pycore_hamt.h' line='129' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-830'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyHamt_NewIterItems' filepath='./Include/internal/pycore_hamt.h' line='132' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-830'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyContext_NewHamtForTests' mangled-name='_PyContext_NewHamtForTests' filepath='Python/context.c' line='78' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyContext_NewHamtForTests'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyContext_New' mangled-name='PyContext_New' filepath='Python/context.c' line='85' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyContext_New'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyContext_Copy' mangled-name='PyContext_Copy' filepath='Python/context.c' line='92' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyContext_Copy'> + <parameter type-id='type-id-2' name='octx' filepath='Python/context.c' line='92' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyContext_CopyCurrent' mangled-name='PyContext_CopyCurrent' filepath='Python/context.c' line='101' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyContext_CopyCurrent'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyContext_Enter' mangled-name='PyContext_Enter' filepath='Python/context.c' line='135' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyContext_Enter'> + <parameter type-id='type-id-2' name='octx' filepath='Python/context.c' line='135' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyContext_Exit' mangled-name='PyContext_Exit' filepath='Python/context.c' line='173' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyContext_Exit'> + <parameter type-id='type-id-2' name='octx' filepath='Python/context.c' line='173' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyContextVar_New' mangled-name='PyContextVar_New' filepath='Python/context.c' line='182' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyContextVar_New'> + <parameter type-id='type-id-12' name='name' filepath='Python/context.c' line='182' column='1'/> + <parameter type-id='type-id-2' name='def' filepath='Python/context.c' line='182' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyContextVar_Get' mangled-name='PyContextVar_Get' filepath='Python/context.c' line='195' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyContextVar_Get'> + <parameter type-id='type-id-2' name='ovar' filepath='Python/context.c' line='195' column='1'/> + <parameter type-id='type-id-2' name='def' filepath='Python/context.c' line='195' column='1'/> + <parameter type-id='type-id-233' name='val' filepath='Python/context.c' line='195' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyContextVar_Set' mangled-name='PyContextVar_Set' filepath='Python/context.c' line='258' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyContextVar_Set'> + <parameter type-id='type-id-2' name='ovar' filepath='Python/context.c' line='258' column='1'/> + <parameter type-id='type-id-2' name='val' filepath='Python/context.c' line='258' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyContextVar_Reset' mangled-name='PyContextVar_Reset' filepath='Python/context.c' line='294' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyContextVar_Reset'> + <parameter type-id='type-id-2' name='ovar' filepath='Python/context.c' line='294' column='1'/> + <parameter type-id='type-id-2' name='otok' filepath='Python/context.c' line='294' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Python/deepfreeze/deepfreeze.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <function-decl name='_PyStaticCode_Fini' filepath='./Include/internal/pycore_code.h' line='251' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-328'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyStaticCode_Init' filepath='./Include/internal/pycore_code.h' line='253' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-328'/> + <return type-id='type-id-8'/> + </function-decl> + <var-decl name='_Py_next_func_version' type-id='type-id-352' visibility='default' filepath='./Include/internal/pycore_code.h' line='463' column='1'/> + </abi-instr> + <abi-instr address-size='64' path='Python/errors.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <function-decl name='_Py_fopen_obj' mangled-name='_Py_fopen_obj' filepath='./Include/cpython/fileutils.h' line='6' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_fopen_obj'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-12'/> + <return type-id='type-id-229'/> + </function-decl> + <function-decl name='_PyTraceBack_FromFrame' mangled-name='_PyTraceBack_FromFrame' filepath='./Include/internal/pycore_traceback.h' line='83' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTraceBack_FromFrame'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-365'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyTraceBack_Print' mangled-name='PyTraceBack_Print' filepath='./Include/traceback.h' line='10' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyTraceBack_Print'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='strerror' filepath='/usr/include/string.h' line='419' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <return type-id='type-id-15'/> + </function-decl> + <function-decl name='_PyErr_Restore' mangled-name='_PyErr_Restore' filepath='Python/errors.c' line='65' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyErr_Restore'> + <parameter type-id='type-id-177' name='tstate' filepath='Python/errors.c' line='65' column='1'/> + <parameter type-id='type-id-2' name='type' filepath='Python/errors.c' line='65' column='1'/> + <parameter type-id='type-id-2' name='value' filepath='Python/errors.c' line='65' column='1'/> + <parameter type-id='type-id-2' name='traceback' filepath='Python/errors.c' line='66' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyErr_SetNone' mangled-name='_PyErr_SetNone' filepath='Python/errors.c' line='276' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyErr_SetNone'> + <parameter type-id='type-id-177' name='tstate' filepath='Python/errors.c' line='276' column='1'/> + <parameter type-id='type-id-2' name='exception' filepath='Python/errors.c' line='276' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyErr_NormalizeException' mangled-name='_PyErr_NormalizeException' filepath='Python/errors.c' line='378' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyErr_NormalizeException'> + <parameter type-id='type-id-177' name='tstate' filepath='Python/errors.c' line='378' column='1'/> + <parameter type-id='type-id-233' name='exc' filepath='Python/errors.c' line='378' column='1'/> + <parameter type-id='type-id-233' name='val' filepath='Python/errors.c' line='379' column='1'/> + <parameter type-id='type-id-233' name='tb' filepath='Python/errors.c' line='379' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyErr_Fetch' mangled-name='_PyErr_Fetch' filepath='Python/errors.c' line='503' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyErr_Fetch'> + <parameter type-id='type-id-177' name='tstate' filepath='Python/errors.c' line='503' column='1'/> + <parameter type-id='type-id-233' name='p_type' filepath='Python/errors.c' line='503' column='1'/> + <parameter type-id='type-id-233' name='p_value' filepath='Python/errors.c' line='503' column='1'/> + <parameter type-id='type-id-233' name='p_traceback' filepath='Python/errors.c' line='504' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyErr_GetExcInfo' mangled-name='_PyErr_GetExcInfo' filepath='Python/errors.c' line='570' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyErr_GetExcInfo'> + <parameter type-id='type-id-177' name='tstate' filepath='Python/errors.c' line='570' column='1'/> + <parameter type-id='type-id-233' name='p_type' filepath='Python/errors.c' line='571' column='1'/> + <parameter type-id='type-id-233' name='p_value' filepath='Python/errors.c' line='571' column='1'/> + <parameter type-id='type-id-233' name='p_traceback' filepath='Python/errors.c' line='571' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyErr_GetHandledException' mangled-name='_PyErr_GetHandledException' filepath='Python/errors.c' line='581' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyErr_GetHandledException'> + <parameter type-id='type-id-177' name='tstate' filepath='Python/errors.c' line='581' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyErr_GetHandledException' mangled-name='PyErr_GetHandledException' filepath='Python/errors.c' line='592' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_GetHandledException'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyErr_SetHandledException' mangled-name='_PyErr_SetHandledException' filepath='Python/errors.c' line='599' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyErr_SetHandledException'> + <parameter type-id='type-id-177' name='tstate' filepath='Python/errors.c' line='599' column='1'/> + <parameter type-id='type-id-2' name='exc' filepath='Python/errors.c' line='599' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyErr_GetExcInfo' mangled-name='PyErr_GetExcInfo' filepath='Python/errors.c' line='612' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_GetExcInfo'> + <parameter type-id='type-id-233' name='p_type' filepath='Python/errors.c' line='612' column='1'/> + <parameter type-id='type-id-233' name='p_value' filepath='Python/errors.c' line='612' column='1'/> + <parameter type-id='type-id-233' name='p_traceback' filepath='Python/errors.c' line='612' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyErr_SetExcInfo' mangled-name='PyErr_SetExcInfo' filepath='Python/errors.c' line='619' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_SetExcInfo'> + <parameter type-id='type-id-2' name='type' filepath='Python/errors.c' line='619' column='1'/> + <parameter type-id='type-id-2' name='value' filepath='Python/errors.c' line='619' column='1'/> + <parameter type-id='type-id-2' name='traceback' filepath='Python/errors.c' line='619' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyErr_StackItemToExcInfoTuple' mangled-name='_PyErr_StackItemToExcInfoTuple' filepath='Python/errors.c' line='630' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyErr_StackItemToExcInfoTuple'> + <parameter type-id='type-id-376' name='err_info' filepath='Python/errors.c' line='630' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyErr_ChainExceptions' mangled-name='_PyErr_ChainExceptions' filepath='Python/errors.c' line='655' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyErr_ChainExceptions'> + <parameter type-id='type-id-2' name='typ' filepath='Python/errors.c' line='655' column='1'/> + <parameter type-id='type-id-2' name='val' filepath='Python/errors.c' line='655' column='1'/> + <parameter type-id='type-id-2' name='tb' filepath='Python/errors.c' line='655' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyErr_SetFromErrnoWithFilenameObject' mangled-name='PyErr_SetFromErrnoWithFilenameObject' filepath='Python/errors.c' line='813' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_SetFromErrnoWithFilenameObject'> + <parameter type-id='type-id-2' name='exc' filepath='Python/errors.c' line='813' column='1'/> + <parameter type-id='type-id-2' name='filenameObject' filepath='Python/errors.c' line='813' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyErr_SetFromErrnoWithFilenameObjects' mangled-name='PyErr_SetFromErrnoWithFilenameObjects' filepath='Python/errors.c' line='819' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_SetFromErrnoWithFilenameObjects'> + <parameter type-id='type-id-2' name='exc' filepath='Python/errors.c' line='819' column='1'/> + <parameter type-id='type-id-2' name='filenameObject' filepath='Python/errors.c' line='819' column='1'/> + <parameter type-id='type-id-2' name='filenameObject2' filepath='Python/errors.c' line='819' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyErr_SetImportErrorSubclass' mangled-name='PyErr_SetImportErrorSubclass' filepath='Python/errors.c' line='1140' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_SetImportErrorSubclass'> + <parameter type-id='type-id-2' name='exception' filepath='Python/errors.c' line='1140' column='1'/> + <parameter type-id='type-id-2' name='msg' filepath='Python/errors.c' line='1140' column='1'/> + <parameter type-id='type-id-2' name='name' filepath='Python/errors.c' line='1141' column='1'/> + <parameter type-id='type-id-2' name='path' filepath='Python/errors.c' line='1141' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyErr_SetImportError' mangled-name='PyErr_SetImportError' filepath='Python/errors.c' line='1153' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_SetImportError'> + <parameter type-id='type-id-2' name='msg' filepath='Python/errors.c' line='1153' column='1'/> + <parameter type-id='type-id-2' name='name' filepath='Python/errors.c' line='1153' column='1'/> + <parameter type-id='type-id-2' name='path' filepath='Python/errors.c' line='1153' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyErr_BadInternalCall' mangled-name='PyErr_BadInternalCall' filepath='Python/errors.c' line='1171' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_BadInternalCall'> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyErr_FormatV' mangled-name='PyErr_FormatV' filepath='Python/errors.c' line='1201' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_FormatV'> + <parameter type-id='type-id-2' name='exception' filepath='Python/errors.c' line='1201' column='1'/> + <parameter type-id='type-id-12' name='format' filepath='Python/errors.c' line='1201' column='1'/> + <parameter type-id='type-id-306' name='vargs' filepath='Python/errors.c' line='1201' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyErr_NewExceptionWithDoc' mangled-name='PyErr_NewExceptionWithDoc' filepath='Python/errors.c' line='1315' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_NewExceptionWithDoc'> + <parameter type-id='type-id-12' name='name' filepath='Python/errors.c' line='1315' column='1'/> + <parameter type-id='type-id-12' name='doc' filepath='Python/errors.c' line='1315' column='1'/> + <parameter type-id='type-id-2' name='base' filepath='Python/errors.c' line='1316' column='1'/> + <parameter type-id='type-id-2' name='dict' filepath='Python/errors.c' line='1316' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyErr_SyntaxLocation' mangled-name='PyErr_SyntaxLocation' filepath='Python/errors.c' line='1720' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_SyntaxLocation'> + <parameter type-id='type-id-12' name='filename' filepath='Python/errors.c' line='1720' column='1'/> + <parameter type-id='type-id-8' name='lineno' filepath='Python/errors.c' line='1720' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyErr_RangedSyntaxLocationObject' mangled-name='PyErr_RangedSyntaxLocationObject' filepath='Python/errors.c' line='1844' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_RangedSyntaxLocationObject'> + <parameter type-id='type-id-2' name='filename' filepath='Python/errors.c' line='1844' column='1'/> + <parameter type-id='type-id-8' name='lineno' filepath='Python/errors.c' line='1844' column='1'/> + <parameter type-id='type-id-8' name='col_offset' filepath='Python/errors.c' line='1844' column='1'/> + <parameter type-id='type-id-8' name='end_lineno' filepath='Python/errors.c' line='1845' column='1'/> + <parameter type-id='type-id-8' name='end_col_offset' filepath='Python/errors.c' line='1845' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyErr_SyntaxLocationEx' mangled-name='PyErr_SyntaxLocationEx' filepath='Python/errors.c' line='1850' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_SyntaxLocationEx'> + <parameter type-id='type-id-12' name='filename' filepath='Python/errors.c' line='1850' column='1'/> + <parameter type-id='type-id-8' name='lineno' filepath='Python/errors.c' line='1850' column='1'/> + <parameter type-id='type-id-8' name='col_offset' filepath='Python/errors.c' line='1850' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyErr_ProgramText' mangled-name='PyErr_ProgramText' filepath='Python/errors.c' line='1915' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_ProgramText'> + <parameter type-id='type-id-12' name='filename' filepath='Python/errors.c' line='1915' column='1'/> + <parameter type-id='type-id-8' name='lineno' filepath='Python/errors.c' line='1915' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Python/fileutils.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <class-decl name='__mbstate_t' size-in-bits='64' is-struct='yes' naming-typedef-id='type-id-1402' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h' line='13' column='1' id='type-id-1403'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='__count' type-id='type-id-8' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h' line='15' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='32'> + <var-decl name='__value' type-id='type-id-1404' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h' line='20' column='1'/> + </data-member> + </class-decl> + <union-decl name='__anonymous_union__' size-in-bits='32' is-anonymous='yes' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h' line='16' column='1' id='type-id-1404'> + <data-member access='public'> + <var-decl name='__wch' type-id='type-id-95' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h' line='18' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='__wchb' type-id='type-id-620' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h' line='19' column='1'/> + </data-member> + </union-decl> + <typedef-decl name='__mbstate_t' type-id='type-id-1403' filepath='/usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h' line='21' column='1' id='type-id-1402'/> + <typedef-decl name='mbstate_t' type-id='type-id-1402' filepath='/usr/include/x86_64-linux-gnu/bits/types/mbstate_t.h' line='6' column='1' id='type-id-1405'/> + <pointer-type-def type-id='type-id-1405' size-in-bits='64' id='type-id-1406'/> + <qualified-type-def type-id='type-id-1406' restrict='yes' id='type-id-1407'/> + <qualified-type-def type-id='type-id-51' restrict='yes' id='type-id-1408'/> + <function-decl name='realpath' filepath='/usr/include/stdlib.h' line='808' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-181'/> + <parameter type-id='type-id-183'/> + <return type-id='type-id-15'/> + </function-decl> + <function-decl name='mbstowcs' filepath='/usr/include/stdlib.h' line='941' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-17'/> + <parameter type-id='type-id-181'/> + <parameter type-id='type-id-19'/> + <return type-id='type-id-19'/> + </function-decl> + <function-decl name='wcstombs' filepath='/usr/include/stdlib.h' line='945' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-183'/> + <parameter type-id='type-id-18'/> + <parameter type-id='type-id-19'/> + <return type-id='type-id-19'/> + </function-decl> + <function-decl name='write' filepath='/usr/include/unistd.h' line='378' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-22'/> + <parameter type-id='type-id-19'/> + <return type-id='type-id-185'/> + </function-decl> + <function-decl name='getcwd' filepath='/usr/include/unistd.h' line='531' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-15'/> + <parameter type-id='type-id-19'/> + <return type-id='type-id-15'/> + </function-decl> + <function-decl name='readlink' filepath='/usr/include/unistd.h' line='838' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-181'/> + <parameter type-id='type-id-183'/> + <parameter type-id='type-id-19'/> + <return type-id='type-id-185'/> + </function-decl> + <function-decl name='close_range' filepath='/usr/include/unistd.h' line='1208' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-95'/> + <parameter type-id='type-id-95'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='mbrtowc' filepath='/usr/include/wchar.h' line='297' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-17'/> + <parameter type-id='type-id-181'/> + <parameter type-id='type-id-19'/> + <parameter type-id='type-id-1407'/> + <return type-id='type-id-19'/> + </function-decl> + <function-decl name='ioctl' filepath='/usr/include/x86_64-linux-gnu/sys/ioctl.h' line='42' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-28'/> + <parameter is-variadic='yes'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_Py_device_encoding' mangled-name='_Py_device_encoding' filepath='Python/fileutils.c' line='75' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_device_encoding'> + <parameter type-id='type-id-8' name='fd' filepath='Python/fileutils.c' line='75' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='Py_EncodeLocale' mangled-name='Py_EncodeLocale' filepath='Python/fileutils.c' line='863' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_EncodeLocale'> + <parameter type-id='type-id-16' name='text' filepath='Python/fileutils.c' line='863' column='1'/> + <parameter type-id='type-id-441' name='error_pos' filepath='Python/fileutils.c' line='863' column='1'/> + <return type-id='type-id-15'/> + </function-decl> + <function-decl name='_Py_EncodeLocaleRaw' mangled-name='_Py_EncodeLocaleRaw' filepath='Python/fileutils.c' line='872' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_EncodeLocaleRaw'> + <parameter type-id='type-id-16' name='text' filepath='Python/fileutils.c' line='872' column='1'/> + <parameter type-id='type-id-441' name='error_pos' filepath='Python/fileutils.c' line='872' column='1'/> + <return type-id='type-id-15'/> + </function-decl> + <function-decl name='_Py_GetLocaleEncodingObject' mangled-name='_Py_GetLocaleEncodingObject' filepath='Python/fileutils.c' line='936' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_GetLocaleEncodingObject'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_Py_stat' mangled-name='_Py_stat' filepath='Python/fileutils.c' line='1355' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_stat'> + <parameter type-id='type-id-2' name='path' filepath='Python/fileutils.c' line='1355' column='1'/> + <parameter type-id='type-id-51' name='statbuf' filepath='Python/fileutils.c' line='1355' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_Py_get_inheritable' mangled-name='_Py_get_inheritable' filepath='Python/fileutils.c' line='1435' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_get_inheritable'> + <parameter type-id='type-id-8' name='fd' filepath='Python/fileutils.c' line='1435' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_Py_set_inheritable' mangled-name='_Py_set_inheritable' filepath='Python/fileutils.c' line='1595' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_set_inheritable'> + <parameter type-id='type-id-8' name='fd' filepath='Python/fileutils.c' line='1595' column='1'/> + <parameter type-id='type-id-8' name='inheritable' filepath='Python/fileutils.c' line='1595' column='1'/> + <parameter type-id='type-id-179' name='atomic_flag_works' filepath='Python/fileutils.c' line='1595' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_Py_set_inheritable_async_safe' mangled-name='_Py_set_inheritable_async_safe' filepath='Python/fileutils.c' line='1604' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_set_inheritable_async_safe'> + <parameter type-id='type-id-8' name='fd' filepath='Python/fileutils.c' line='1604' column='1'/> + <parameter type-id='type-id-8' name='inheritable' filepath='Python/fileutils.c' line='1604' column='1'/> + <parameter type-id='type-id-179' name='atomic_flag_works' filepath='Python/fileutils.c' line='1604' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_Py_wfopen' mangled-name='_Py_wfopen' filepath='Python/fileutils.c' line='1707' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_wfopen'> + <parameter type-id='type-id-16' name='path' filepath='Python/fileutils.c' line='1707' column='1'/> + <parameter type-id='type-id-16' name='mode' filepath='Python/fileutils.c' line='1707' column='1'/> + <return type-id='type-id-229'/> + </function-decl> + <function-decl name='_Py_normpath' mangled-name='_Py_normpath' filepath='Python/fileutils.c' line='2514' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_normpath'> + <parameter type-id='type-id-52' name='path' filepath='Python/fileutils.c' line='2514' column='1'/> + <parameter type-id='type-id-14' name='size' filepath='Python/fileutils.c' line='2514' column='1'/> + <return type-id='type-id-52'/> + </function-decl> + <function-decl name='_Py_get_blocking' mangled-name='_Py_get_blocking' filepath='Python/fileutils.c' line='2629' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_get_blocking'> + <parameter type-id='type-id-8' name='fd' filepath='Python/fileutils.c' line='2629' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_Py_set_blocking' mangled-name='_Py_set_blocking' filepath='Python/fileutils.c' line='2650' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_set_blocking'> + <parameter type-id='type-id-8' name='fd' filepath='Python/fileutils.c' line='2650' column='1'/> + <parameter type-id='type-id-8' name='blocking' filepath='Python/fileutils.c' line='2650' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_Py_closerange' mangled-name='_Py_closerange' filepath='Python/fileutils.c' line='2901' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_closerange'> + <parameter type-id='type-id-8' name='first' filepath='Python/fileutils.c' line='2901' column='1'/> + <parameter type-id='type-id-8' name='last' filepath='Python/fileutils.c' line='2901' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Python/flowgraph.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <function-decl name='_PyCompile_EnsureArrayLargeEnough' filepath='./Include/internal/pycore_compile.h' line='86' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-253'/> + <parameter type-id='type-id-179'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-19'/> + <return type-id='type-id-8'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Python/formatter_unicode.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <class-decl name='lconv' size-in-bits='768' is-struct='yes' visibility='default' filepath='/usr/include/locale.h' line='51' column='1' id='type-id-1409'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='decimal_point' type-id='type-id-15' visibility='default' filepath='/usr/include/locale.h' line='55' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='thousands_sep' type-id='type-id-15' visibility='default' filepath='/usr/include/locale.h' line='56' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='grouping' type-id='type-id-15' visibility='default' filepath='/usr/include/locale.h' line='62' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='int_curr_symbol' type-id='type-id-15' visibility='default' filepath='/usr/include/locale.h' line='68' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='currency_symbol' type-id='type-id-15' visibility='default' filepath='/usr/include/locale.h' line='69' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='mon_decimal_point' type-id='type-id-15' visibility='default' filepath='/usr/include/locale.h' line='70' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='384'> + <var-decl name='mon_thousands_sep' type-id='type-id-15' visibility='default' filepath='/usr/include/locale.h' line='71' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='448'> + <var-decl name='mon_grouping' type-id='type-id-15' visibility='default' filepath='/usr/include/locale.h' line='72' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='512'> + <var-decl name='positive_sign' type-id='type-id-15' visibility='default' filepath='/usr/include/locale.h' line='73' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='576'> + <var-decl name='negative_sign' type-id='type-id-15' visibility='default' filepath='/usr/include/locale.h' line='74' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='640'> + <var-decl name='int_frac_digits' type-id='type-id-48' visibility='default' filepath='/usr/include/locale.h' line='75' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='648'> + <var-decl name='frac_digits' type-id='type-id-48' visibility='default' filepath='/usr/include/locale.h' line='76' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='656'> + <var-decl name='p_cs_precedes' type-id='type-id-48' visibility='default' filepath='/usr/include/locale.h' line='78' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='664'> + <var-decl name='p_sep_by_space' type-id='type-id-48' visibility='default' filepath='/usr/include/locale.h' line='80' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='672'> + <var-decl name='n_cs_precedes' type-id='type-id-48' visibility='default' filepath='/usr/include/locale.h' line='82' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='680'> + <var-decl name='n_sep_by_space' type-id='type-id-48' visibility='default' filepath='/usr/include/locale.h' line='84' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='688'> + <var-decl name='p_sign_posn' type-id='type-id-48' visibility='default' filepath='/usr/include/locale.h' line='91' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='696'> + <var-decl name='n_sign_posn' type-id='type-id-48' visibility='default' filepath='/usr/include/locale.h' line='92' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='704'> + <var-decl name='int_p_cs_precedes' type-id='type-id-48' visibility='default' filepath='/usr/include/locale.h' line='95' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='712'> + <var-decl name='int_p_sep_by_space' type-id='type-id-48' visibility='default' filepath='/usr/include/locale.h' line='97' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='720'> + <var-decl name='int_n_cs_precedes' type-id='type-id-48' visibility='default' filepath='/usr/include/locale.h' line='99' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='728'> + <var-decl name='int_n_sep_by_space' type-id='type-id-48' visibility='default' filepath='/usr/include/locale.h' line='101' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='736'> + <var-decl name='int_p_sign_posn' type-id='type-id-48' visibility='default' filepath='/usr/include/locale.h' line='108' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='744'> + <var-decl name='int_n_sign_posn' type-id='type-id-48' visibility='default' filepath='/usr/include/locale.h' line='109' column='1'/> + </data-member> + </class-decl> + <pointer-type-def type-id='type-id-1409' size-in-bits='64' id='type-id-1410'/> + <function-decl name='_Py_GetLocaleconvNumeric' mangled-name='_Py_GetLocaleconvNumeric' filepath='./Include/internal/pycore_fileutils.h' line='222' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_GetLocaleconvNumeric'> + <parameter type-id='type-id-1410'/> + <parameter type-id='type-id-233'/> + <parameter type-id='type-id-233'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='localeconv' filepath='/usr/include/locale.h' line='125' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-1410'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Python/frame.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <function-decl name='_PyFrame_New_NoTrack' filepath='./Include/internal/pycore_frame.h' line='29' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-328'/> + <return type-id='type-id-365'/> + </function-decl> + <function-decl name='PyUnstable_InterpreterFrame_GetCode' mangled-name='PyUnstable_InterpreterFrame_GetCode' filepath='Python/frame.c' line='150' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnstable_InterpreterFrame_GetCode'> + <parameter type-id='type-id-375' name='frame' filepath='Python/frame.c' line='150' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyUnstable_InterpreterFrame_GetLasti' mangled-name='PyUnstable_InterpreterFrame_GetLasti' filepath='Python/frame.c' line='158' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnstable_InterpreterFrame_GetLasti'> + <parameter type-id='type-id-375' name='frame' filepath='Python/frame.c' line='158' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Python/frozen.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <class-decl name='_frozen' size-in-bits='256' is-struct='yes' visibility='default' filepath='./Include/cpython/import.h' line='32' column='1' id='type-id-1411'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='name' type-id='type-id-12' visibility='default' filepath='./Include/cpython/import.h' line='33' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='code' type-id='type-id-383' visibility='default' filepath='./Include/cpython/import.h' line='34' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='size' type-id='type-id-8' visibility='default' filepath='./Include/cpython/import.h' line='35' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='160'> + <var-decl name='is_package' type-id='type-id-8' visibility='default' filepath='./Include/cpython/import.h' line='36' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='get_code' type-id='type-id-390' visibility='default' filepath='./Include/cpython/import.h' line='37' column='1'/> + </data-member> + </class-decl> + <class-decl name='_module_alias' size-in-bits='128' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_import.h' line='162' column='1' id='type-id-1412'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='name' type-id='type-id-12' visibility='default' filepath='./Include/internal/pycore_import.h' line='163' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='orig' type-id='type-id-12' visibility='default' filepath='./Include/internal/pycore_import.h' line='164' column='1'/> + </data-member> + </class-decl> + <qualified-type-def type-id='type-id-1411' const='yes' id='type-id-1413'/> + <pointer-type-def type-id='type-id-1413' size-in-bits='64' id='type-id-1414'/> + <qualified-type-def type-id='type-id-1412' const='yes' id='type-id-1415'/> + <pointer-type-def type-id='type-id-1415' size-in-bits='64' id='type-id-1416'/> + <var-decl name='PyImport_FrozenModules' type-id='type-id-1414' mangled-name='PyImport_FrozenModules' visibility='default' filepath='./Include/cpython/import.h' line='43' column='1' elf-symbol-id='PyImport_FrozenModules'/> + <var-decl name='_PyImport_FrozenBootstrap' type-id='type-id-1414' mangled-name='_PyImport_FrozenBootstrap' visibility='default' filepath='./Include/internal/pycore_import.h' line='167' column='1' elf-symbol-id='_PyImport_FrozenBootstrap'/> + <var-decl name='_PyImport_FrozenStdlib' type-id='type-id-1414' mangled-name='_PyImport_FrozenStdlib' visibility='default' filepath='./Include/internal/pycore_import.h' line='168' column='1' elf-symbol-id='_PyImport_FrozenStdlib'/> + <var-decl name='_PyImport_FrozenTest' type-id='type-id-1414' mangled-name='_PyImport_FrozenTest' visibility='default' filepath='./Include/internal/pycore_import.h' line='169' column='1' elf-symbol-id='_PyImport_FrozenTest'/> + <var-decl name='_PyImport_FrozenAliases' type-id='type-id-1416' visibility='default' filepath='./Include/internal/pycore_import.h' line='170' column='1'/> + <function-decl name='_Py_get_importlib__bootstrap_toplevel' filepath='Python/frozen.c' line='72' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_Py_get_importlib__bootstrap_external_toplevel' filepath='Python/frozen.c' line='73' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_Py_get_zipimport_toplevel' filepath='Python/frozen.c' line='74' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_Py_get_abc_toplevel' filepath='Python/frozen.c' line='75' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_Py_get_codecs_toplevel' filepath='Python/frozen.c' line='76' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_Py_get_io_toplevel' filepath='Python/frozen.c' line='77' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_Py_get__collections_abc_toplevel' filepath='Python/frozen.c' line='78' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_Py_get__sitebuiltins_toplevel' filepath='Python/frozen.c' line='79' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_Py_get_genericpath_toplevel' filepath='Python/frozen.c' line='80' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_Py_get_ntpath_toplevel' filepath='Python/frozen.c' line='81' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_Py_get_posixpath_toplevel' filepath='Python/frozen.c' line='83' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_Py_get_os_toplevel' filepath='Python/frozen.c' line='84' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_Py_get_site_toplevel' filepath='Python/frozen.c' line='85' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_Py_get_stat_toplevel' filepath='Python/frozen.c' line='86' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_Py_get_importlib_util_toplevel' filepath='Python/frozen.c' line='87' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_Py_get_importlib_machinery_toplevel' filepath='Python/frozen.c' line='88' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_Py_get_runpy_toplevel' filepath='Python/frozen.c' line='89' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_Py_get___hello___toplevel' filepath='Python/frozen.c' line='93' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_Py_get___phello___toplevel' filepath='Python/frozen.c' line='95' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_Py_get___phello___ham_toplevel' filepath='Python/frozen.c' line='97' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_Py_get___phello___ham_eggs_toplevel' filepath='Python/frozen.c' line='98' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_Py_get___phello___spam_toplevel' filepath='Python/frozen.c' line='99' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_Py_get_frozen_only_toplevel' filepath='Python/frozen.c' line='100' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-2'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Python/frozenmain.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <class-decl name='PyStatus' size-in-bits='256' is-struct='yes' naming-typedef-id='type-id-54' visibility='default' filepath='./Include/cpython/initconfig.h' line='10' column='1' id='type-id-1417'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='_type' type-id='type-id-997' visibility='default' filepath='./Include/cpython/initconfig.h' line='15' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='func' type-id='type-id-12' visibility='default' filepath='./Include/cpython/initconfig.h' line='16' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='err_msg' type-id='type-id-12' visibility='default' filepath='./Include/cpython/initconfig.h' line='17' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='exitcode' type-id='type-id-8' visibility='default' filepath='./Include/cpython/initconfig.h' line='18' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='PyStatus' type-id='type-id-1417' filepath='./Include/cpython/initconfig.h' line='19' column='1' id='type-id-54'/> + <pointer-type-def type-id='type-id-258' size-in-bits='64' id='type-id-53'/> + <function-decl name='PyStatus_Exception' mangled-name='PyStatus_Exception' filepath='./Include/cpython/initconfig.h' line='27' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyStatus_Exception'> + <parameter type-id='type-id-54'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyConfig_InitPythonConfig' mangled-name='PyConfig_InitPythonConfig' filepath='./Include/cpython/initconfig.h' line='221' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyConfig_InitPythonConfig'> + <parameter type-id='type-id-53'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyConfig_Clear' mangled-name='PyConfig_Clear' filepath='./Include/cpython/initconfig.h' line='223' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyConfig_Clear'> + <parameter type-id='type-id-53'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyConfig_SetBytesArgv' mangled-name='PyConfig_SetBytesArgv' filepath='./Include/cpython/initconfig.h' line='233' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyConfig_SetBytesArgv'> + <parameter type-id='type-id-53'/> + <parameter type-id='type-id-14'/> + <parameter type-id='type-id-136'/> + <return type-id='type-id-54'/> + </function-decl> + <function-decl name='Py_InitializeFromConfig' mangled-name='Py_InitializeFromConfig' filepath='./Include/cpython/pylifecycle.h' line='34' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_InitializeFromConfig'> + <parameter type-id='type-id-260'/> + <return type-id='type-id-54'/> + </function-decl> + <function-decl name='Py_ExitStatusException' mangled-name='Py_ExitStatusException' filepath='./Include/cpython/pylifecycle.h' line='41' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_ExitStatusException'> + <parameter type-id='type-id-54'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyRun_AnyFileExFlags' mangled-name='PyRun_AnyFileExFlags' filepath='./Include/cpython/pythonrun.h' line='11' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyRun_AnyFileExFlags'> + <parameter type-id='type-id-229'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-208'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyImport_ImportFrozenModule' mangled-name='PyImport_ImportFrozenModule' filepath='./Include/import.h' line='80' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyImport_ImportFrozenModule'> + <parameter type-id='type-id-12'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyRuntime_Initialize' mangled-name='_PyRuntime_Initialize' filepath='./Include/internal/pycore_runtime.h' line='197' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyRuntime_Initialize'> + <return type-id='type-id-54'/> + </function-decl> + <function-decl name='Py_FinalizeEx' mangled-name='Py_FinalizeEx' filepath='./Include/pylifecycle.h' line='16' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_FinalizeEx'> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='Py_GetVersion' mangled-name='Py_GetVersion' filepath='./Include/pylifecycle.h' line='54' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_GetVersion'> + <return type-id='type-id-12'/> + </function-decl> + <function-decl name='Py_GetCopyright' mangled-name='Py_GetCopyright' filepath='./Include/pylifecycle.h' line='56' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_GetCopyright'> + <return type-id='type-id-12'/> + </function-decl> + <function-decl name='Py_FrozenMain' mangled-name='Py_FrozenMain' filepath='Python/frozenmain.c' line='16' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_FrozenMain'> + <parameter type-id='type-id-8' name='argc' filepath='Python/frozenmain.c' line='16' column='1'/> + <parameter type-id='type-id-239' name='argv' filepath='Python/frozenmain.c' line='16' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Python/getargs.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <function-decl name='PyArg_Parse' mangled-name='PyArg_Parse' filepath='Python/getargs.c' line='99' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyArg_Parse'> + <parameter type-id='type-id-2' name='args' filepath='Python/getargs.c' line='99' column='1'/> + <parameter type-id='type-id-12' name='format' filepath='Python/getargs.c' line='99' column='1'/> + <parameter is-variadic='yes'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyArg_Parse_SizeT' mangled-name='_PyArg_Parse_SizeT' filepath='Python/getargs.c' line='111' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyArg_Parse_SizeT'> + <parameter type-id='type-id-2' name='args' filepath='Python/getargs.c' line='111' column='1'/> + <parameter type-id='type-id-12' name='format' filepath='Python/getargs.c' line='111' column='1'/> + <parameter is-variadic='yes'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyArg_ParseStack' mangled-name='_PyArg_ParseStack' filepath='Python/getargs.c' line='149' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyArg_ParseStack'> + <parameter type-id='type-id-248' name='args' filepath='Python/getargs.c' line='149' column='1'/> + <parameter type-id='type-id-14' name='nargs' filepath='Python/getargs.c' line='149' column='1'/> + <parameter type-id='type-id-12' name='format' filepath='Python/getargs.c' line='149' column='1'/> + <parameter is-variadic='yes'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyArg_ParseStack_SizeT' mangled-name='_PyArg_ParseStack_SizeT' filepath='Python/getargs.c' line='161' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyArg_ParseStack_SizeT'> + <parameter type-id='type-id-248' name='args' filepath='Python/getargs.c' line='161' column='1'/> + <parameter type-id='type-id-14' name='nargs' filepath='Python/getargs.c' line='161' column='1'/> + <parameter type-id='type-id-12' name='format' filepath='Python/getargs.c' line='161' column='1'/> + <parameter is-variadic='yes'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyArg_VaParse' mangled-name='PyArg_VaParse' filepath='Python/getargs.c' line='174' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyArg_VaParse'> + <parameter type-id='type-id-2' name='args' filepath='Python/getargs.c' line='174' column='1'/> + <parameter type-id='type-id-12' name='format' filepath='Python/getargs.c' line='174' column='1'/> + <parameter type-id='type-id-306' name='va' filepath='Python/getargs.c' line='174' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyArg_VaParse_SizeT' mangled-name='_PyArg_VaParse_SizeT' filepath='Python/getargs.c' line='187' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyArg_VaParse_SizeT'> + <parameter type-id='type-id-2' name='args' filepath='Python/getargs.c' line='187' column='1'/> + <parameter type-id='type-id-12' name='format' filepath='Python/getargs.c' line='187' column='1'/> + <parameter type-id='type-id-306' name='va' filepath='Python/getargs.c' line='187' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyArg_VaParseTupleAndKeywords' mangled-name='PyArg_VaParseTupleAndKeywords' filepath='Python/getargs.c' line='1373' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyArg_VaParseTupleAndKeywords'> + <parameter type-id='type-id-2' name='args' filepath='Python/getargs.c' line='1373' column='1'/> + <parameter type-id='type-id-2' name='keywords' filepath='Python/getargs.c' line='1374' column='1'/> + <parameter type-id='type-id-12' name='format' filepath='Python/getargs.c' line='1375' column='1'/> + <parameter type-id='type-id-239' name='kwlist' filepath='Python/getargs.c' line='1376' column='1'/> + <parameter type-id='type-id-306' name='va' filepath='Python/getargs.c' line='1376' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyArg_VaParseTupleAndKeywords_SizeT' mangled-name='_PyArg_VaParseTupleAndKeywords_SizeT' filepath='Python/getargs.c' line='1398' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyArg_VaParseTupleAndKeywords_SizeT'> + <parameter type-id='type-id-2' name='args' filepath='Python/getargs.c' line='1398' column='1'/> + <parameter type-id='type-id-2' name='keywords' filepath='Python/getargs.c' line='1399' column='1'/> + <parameter type-id='type-id-12' name='format' filepath='Python/getargs.c' line='1400' column='1'/> + <parameter type-id='type-id-239' name='kwlist' filepath='Python/getargs.c' line='1401' column='1'/> + <parameter type-id='type-id-306' name='va' filepath='Python/getargs.c' line='1401' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyArg_ParseTupleAndKeywordsFast' mangled-name='_PyArg_ParseTupleAndKeywordsFast' filepath='Python/getargs.c' line='1424' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyArg_ParseTupleAndKeywordsFast'> + <parameter type-id='type-id-2' name='args' filepath='Python/getargs.c' line='1424' column='1'/> + <parameter type-id='type-id-2' name='keywords' filepath='Python/getargs.c' line='1424' column='1'/> + <parameter type-id='type-id-262' name='parser' filepath='Python/getargs.c' line='1425' column='1'/> + <parameter is-variadic='yes'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyArg_ParseTupleAndKeywordsFast_SizeT' mangled-name='_PyArg_ParseTupleAndKeywordsFast_SizeT' filepath='Python/getargs.c' line='1437' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyArg_ParseTupleAndKeywordsFast_SizeT'> + <parameter type-id='type-id-2' name='args' filepath='Python/getargs.c' line='1437' column='1'/> + <parameter type-id='type-id-2' name='keywords' filepath='Python/getargs.c' line='1437' column='1'/> + <parameter type-id='type-id-262' name='parser' filepath='Python/getargs.c' line='1438' column='1'/> + <parameter is-variadic='yes'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyArg_ParseStackAndKeywords' mangled-name='_PyArg_ParseStackAndKeywords' filepath='Python/getargs.c' line='1450' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyArg_ParseStackAndKeywords'> + <parameter type-id='type-id-248' name='args' filepath='Python/getargs.c' line='1450' column='1'/> + <parameter type-id='type-id-14' name='nargs' filepath='Python/getargs.c' line='1450' column='1'/> + <parameter type-id='type-id-2' name='kwnames' filepath='Python/getargs.c' line='1450' column='1'/> + <parameter type-id='type-id-262' name='parser' filepath='Python/getargs.c' line='1451' column='1'/> + <parameter is-variadic='yes'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyArg_ParseStackAndKeywords_SizeT' mangled-name='_PyArg_ParseStackAndKeywords_SizeT' filepath='Python/getargs.c' line='1463' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyArg_ParseStackAndKeywords_SizeT'> + <parameter type-id='type-id-248' name='args' filepath='Python/getargs.c' line='1463' column='1'/> + <parameter type-id='type-id-14' name='nargs' filepath='Python/getargs.c' line='1463' column='1'/> + <parameter type-id='type-id-2' name='kwnames' filepath='Python/getargs.c' line='1463' column='1'/> + <parameter type-id='type-id-262' name='parser' filepath='Python/getargs.c' line='1464' column='1'/> + <parameter is-variadic='yes'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyArg_VaParseTupleAndKeywordsFast' mangled-name='_PyArg_VaParseTupleAndKeywordsFast' filepath='Python/getargs.c' line='1477' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyArg_VaParseTupleAndKeywordsFast'> + <parameter type-id='type-id-2' name='args' filepath='Python/getargs.c' line='1477' column='1'/> + <parameter type-id='type-id-2' name='keywords' filepath='Python/getargs.c' line='1477' column='1'/> + <parameter type-id='type-id-262' name='parser' filepath='Python/getargs.c' line='1478' column='1'/> + <parameter type-id='type-id-306' name='va' filepath='Python/getargs.c' line='1478' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyArg_VaParseTupleAndKeywordsFast_SizeT' mangled-name='_PyArg_VaParseTupleAndKeywordsFast_SizeT' filepath='Python/getargs.c' line='1491' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyArg_VaParseTupleAndKeywordsFast_SizeT'> + <parameter type-id='type-id-2' name='args' filepath='Python/getargs.c' line='1491' column='1'/> + <parameter type-id='type-id-2' name='keywords' filepath='Python/getargs.c' line='1491' column='1'/> + <parameter type-id='type-id-262' name='parser' filepath='Python/getargs.c' line='1492' column='1'/> + <parameter type-id='type-id-306' name='va' filepath='Python/getargs.c' line='1492' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyArg_NoPositional' mangled-name='_PyArg_NoPositional' filepath='Python/getargs.c' line='2912' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyArg_NoPositional'> + <parameter type-id='type-id-12' name='funcname' filepath='Python/getargs.c' line='2912' column='1'/> + <parameter type-id='type-id-2' name='args' filepath='Python/getargs.c' line='2912' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Python/getcompiler.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <function-decl name='Py_GetCompiler' mangled-name='Py_GetCompiler' filepath='Python/getcompiler.c' line='24' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_GetCompiler'> + <return type-id='type-id-12'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Python/getopt.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <var-decl name='_PyOS_opterr' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_getopt.h' line='8' column='1'/> + <var-decl name='_PyOS_optind' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_getopt.h' line='9' column='1'/> + <var-decl name='_PyOS_optarg' type-id='type-id-16' visibility='default' filepath='./Include/internal/pycore_getopt.h' line='10' column='1'/> + </abi-instr> + <abi-instr address-size='64' path='Python/getversion.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <qualified-type-def type-id='type-id-28' const='yes' id='type-id-1418'/> + <var-decl name='Py_Version' type-id='type-id-1418' mangled-name='Py_Version' visibility='default' filepath='./Include/pylifecycle.h' line='66' column='1' elf-symbol-id='Py_Version'/> + </abi-instr> + <abi-instr address-size='64' path='Python/hamt.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <var-decl name='_PyHamt_Type' type-id='type-id-256' visibility='default' filepath='./Include/internal/pycore_hamt.h' line='23' column='1'/> + <var-decl name='_PyHamt_ArrayNode_Type' type-id='type-id-256' visibility='default' filepath='./Include/internal/pycore_hamt.h' line='24' column='1'/> + <var-decl name='_PyHamt_BitmapNode_Type' type-id='type-id-256' visibility='default' filepath='./Include/internal/pycore_hamt.h' line='25' column='1'/> + <var-decl name='_PyHamt_CollisionNode_Type' type-id='type-id-256' visibility='default' filepath='./Include/internal/pycore_hamt.h' line='26' column='1'/> + <var-decl name='_PyHamtKeys_Type' type-id='type-id-256' visibility='default' filepath='./Include/internal/pycore_hamt.h' line='27' column='1'/> + <var-decl name='_PyHamtValues_Type' type-id='type-id-256' visibility='default' filepath='./Include/internal/pycore_hamt.h' line='28' column='1'/> + <var-decl name='_PyHamtItems_Type' type-id='type-id-256' visibility='default' filepath='./Include/internal/pycore_hamt.h' line='29' column='1'/> + </abi-instr> + <abi-instr address-size='64' path='Python/hashtable.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <typedef-decl name='_Py_hashtable_foreach_func' type-id='type-id-1419' filepath='./Include/internal/pycore_hashtable.h' line='96' column='1' id='type-id-1420'/> + <pointer-type-def type-id='type-id-919' size-in-bits='64' id='type-id-1421'/> + <qualified-type-def type-id='type-id-912' const='yes' id='type-id-1422'/> + <pointer-type-def type-id='type-id-1422' size-in-bits='64' id='type-id-1423'/> + <pointer-type-def type-id='type-id-1424' size-in-bits='64' id='type-id-1419'/> + <function-decl name='_Py_HashPointerRaw' mangled-name='_Py_HashPointerRaw' filepath='./Include/pyhash.h' line='13' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_HashPointerRaw'> + <parameter type-id='type-id-22'/> + <return type-id='type-id-305'/> + </function-decl> + <function-decl name='_Py_hashtable_hash_ptr' mangled-name='_Py_hashtable_hash_ptr' filepath='Python/hashtable.c' line='92' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_hashtable_hash_ptr'> + <parameter type-id='type-id-22' name='key' filepath='Python/hashtable.c' line='92' column='1'/> + <return type-id='type-id-910'/> + </function-decl> + <function-decl name='_Py_hashtable_compare_direct' mangled-name='_Py_hashtable_compare_direct' filepath='Python/hashtable.c' line='99' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_hashtable_compare_direct'> + <parameter type-id='type-id-22' name='key1' filepath='Python/hashtable.c' line='99' column='1'/> + <parameter type-id='type-id-22' name='key2' filepath='Python/hashtable.c' line='99' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_Py_hashtable_size' mangled-name='_Py_hashtable_size' filepath='Python/hashtable.c' line='120' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_hashtable_size'> + <parameter type-id='type-id-1423' name='ht' filepath='Python/hashtable.c' line='120' column='1'/> + <return type-id='type-id-19'/> + </function-decl> + <function-decl name='_Py_hashtable_steal' mangled-name='_Py_hashtable_steal' filepath='Python/hashtable.c' line='174' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_hashtable_steal'> + <parameter type-id='type-id-926' name='ht' filepath='Python/hashtable.c' line='174' column='1'/> + <parameter type-id='type-id-22' name='key' filepath='Python/hashtable.c' line='174' column='1'/> + <return type-id='type-id-22'/> + </function-decl> + <function-decl name='_Py_hashtable_set' mangled-name='_Py_hashtable_set' filepath='Python/hashtable.c' line='209' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_hashtable_set'> + <parameter type-id='type-id-926' name='ht' filepath='Python/hashtable.c' line='209' column='1'/> + <parameter type-id='type-id-22' name='key' filepath='Python/hashtable.c' line='209' column='1'/> + <parameter type-id='type-id-22' name='value' filepath='Python/hashtable.c' line='209' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_Py_hashtable_get' mangled-name='_Py_hashtable_get' filepath='Python/hashtable.c' line='248' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_hashtable_get'> + <parameter type-id='type-id-926' name='ht' filepath='Python/hashtable.c' line='248' column='1'/> + <parameter type-id='type-id-22' name='key' filepath='Python/hashtable.c' line='248' column='1'/> + <return type-id='type-id-22'/> + </function-decl> + <function-decl name='_Py_hashtable_foreach' mangled-name='_Py_hashtable_foreach' filepath='Python/hashtable.c' line='261' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_hashtable_foreach'> + <parameter type-id='type-id-926' name='ht' filepath='Python/hashtable.c' line='261' column='1'/> + <parameter type-id='type-id-1420' name='func' filepath='Python/hashtable.c' line='262' column='1'/> + <parameter type-id='type-id-22' name='user_data' filepath='Python/hashtable.c' line='263' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_Py_hashtable_new_full' mangled-name='_Py_hashtable_new_full' filepath='Python/hashtable.c' line='316' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_hashtable_new_full'> + <parameter type-id='type-id-914' name='hash_func' filepath='Python/hashtable.c' line='316' column='1'/> + <parameter type-id='type-id-915' name='compare_func' filepath='Python/hashtable.c' line='317' column='1'/> + <parameter type-id='type-id-916' name='key_destroy_func' filepath='Python/hashtable.c' line='318' column='1'/> + <parameter type-id='type-id-916' name='value_destroy_func' filepath='Python/hashtable.c' line='319' column='1'/> + <parameter type-id='type-id-1421' name='allocator' filepath='Python/hashtable.c' line='320' column='1'/> + <return type-id='type-id-926'/> + </function-decl> + <function-decl name='_Py_hashtable_new' mangled-name='_Py_hashtable_new' filepath='Python/hashtable.c' line='363' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_hashtable_new'> + <parameter type-id='type-id-914' name='hash_func' filepath='Python/hashtable.c' line='363' column='1'/> + <parameter type-id='type-id-915' name='compare_func' filepath='Python/hashtable.c' line='364' column='1'/> + <return type-id='type-id-926'/> + </function-decl> + <function-decl name='_Py_hashtable_clear' mangled-name='_Py_hashtable_clear' filepath='Python/hashtable.c' line='385' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_hashtable_clear'> + <parameter type-id='type-id-926' name='ht' filepath='Python/hashtable.c' line='385' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_Py_hashtable_destroy' mangled-name='_Py_hashtable_destroy' filepath='Python/hashtable.c' line='404' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_hashtable_destroy'> + <parameter type-id='type-id-926' name='ht' filepath='Python/hashtable.c' line='404' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-type size-in-bits='64' id='type-id-1424'> + <parameter type-id='type-id-926'/> + <parameter type-id='type-id-22'/> + <parameter type-id='type-id-22'/> + <parameter type-id='type-id-22'/> + <return type-id='type-id-8'/> + </function-type> + </abi-instr> + <abi-instr address-size='64' path='Python/import.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <enum-decl name='_PyTime_round_t' naming-typedef-id='type-id-1425' filepath='./Include/cpython/pytime.h' line='70' column='1' id='type-id-1426'> + <underlying-type type-id='type-id-24'/> + <enumerator name='_PyTime_ROUND_FLOOR' value='0'/> + <enumerator name='_PyTime_ROUND_CEILING' value='1'/> + <enumerator name='_PyTime_ROUND_HALF_EVEN' value='2'/> + <enumerator name='_PyTime_ROUND_UP' value='3'/> + <enumerator name='_PyTime_ROUND_TIMEOUT' value='3'/> + </enum-decl> + <typedef-decl name='_PyTime_round_t' type-id='type-id-1426' filepath='./Include/cpython/pytime.h' line='90' column='1' id='type-id-1425'/> + <var-decl name='PyImport_Inittab' type-id='type-id-924' mangled-name='PyImport_Inittab' visibility='default' filepath='./Include/cpython/import.h' line='29' column='1' elf-symbol-id='PyImport_Inittab'/> + <function-decl name='PyStatus_NoMemory' mangled-name='PyStatus_NoMemory' filepath='./Include/cpython/initconfig.h' line='23' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyStatus_NoMemory'> + <return type-id='type-id-54'/> + </function-decl> + <function-decl name='_PyInterpreterState_HasFeature' mangled-name='_PyInterpreterState_HasFeature' filepath='./Include/cpython/pystate.h' line='34' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyInterpreterState_HasFeature'> + <parameter type-id='type-id-20'/> + <parameter type-id='type-id-28'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyTime_AsMicroseconds' mangled-name='_PyTime_AsMicroseconds' filepath='./Include/cpython/pytime.h' line='165' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTime_AsMicroseconds'> + <parameter type-id='type-id-790'/> + <parameter type-id='type-id-1425'/> + <return type-id='type-id-790'/> + </function-decl> + <function-decl name='_PyTime_GetPerfCounter' mangled-name='_PyTime_GetPerfCounter' filepath='./Include/cpython/pytime.h' line='305' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTime_GetPerfCounter'> + <return type-id='type-id-790'/> + </function-decl> + <function-decl name='_Py_KeyedHash' filepath='./Include/internal/pycore_pyhash.h' line='37' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-117'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-14'/> + <return type-id='type-id-117'/> + </function-decl> + <function-decl name='_PySys_ClearAttrString' filepath='./Include/internal/pycore_sysmodule.h' line='23' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyMarshal_ReadObjectFromString' mangled-name='PyMarshal_ReadObjectFromString' filepath='./Include/marshal.h' line='12' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMarshal_ReadObjectFromString'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-14'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyImport_AcquireLock' mangled-name='_PyImport_AcquireLock' filepath='Python/import.c' line='105' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyImport_AcquireLock'> + <parameter type-id='type-id-20' name='interp' filepath='Python/import.c' line='105' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyImport_ReleaseLock' mangled-name='_PyImport_ReleaseLock' filepath='Python/import.c' line='132' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyImport_ReleaseLock'> + <parameter type-id='type-id-20' name='interp' filepath='Python/import.c' line='132' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyImport_GetModuleDict' mangled-name='PyImport_GetModuleDict' filepath='Python/import.c' line='205' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyImport_GetModuleDict'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyImport_GetModuleId' mangled-name='_PyImport_GetModuleId' filepath='Python/import.c' line='216' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyImport_GetModuleId'> + <parameter type-id='type-id-309' name='nameid' filepath='Python/import.c' line='216' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyImport_SetModule' mangled-name='_PyImport_SetModule' filepath='Python/import.c' line='226' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyImport_SetModule'> + <parameter type-id='type-id-2' name='name' filepath='Python/import.c' line='226' column='1'/> + <parameter type-id='type-id-2' name='m' filepath='Python/import.c' line='226' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyImport_SetModuleString' mangled-name='_PyImport_SetModuleString' filepath='Python/import.c' line='234' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyImport_SetModuleString'> + <parameter type-id='type-id-12' name='name' filepath='Python/import.c' line='234' column='1'/> + <parameter type-id='type-id-2' name='m' filepath='Python/import.c' line='234' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyImport_AddModuleObject' mangled-name='PyImport_AddModuleObject' filepath='Python/import.c' line='356' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyImport_AddModuleObject'> + <parameter type-id='type-id-2' name='name' filepath='Python/import.c' line='356' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyImport_AddModule' mangled-name='PyImport_AddModule' filepath='Python/import.c' line='374' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyImport_AddModule'> + <parameter type-id='type-id-12' name='name' filepath='Python/import.c' line='374' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyState_FindModule' mangled-name='PyState_FindModule' filepath='Python/import.c' line='490' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyState_FindModule'> + <parameter type-id='type-id-399' name='module' filepath='Python/import.c' line='490' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyState_AddModule' mangled-name='_PyState_AddModule' filepath='Python/import.c' line='504' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyState_AddModule'> + <parameter type-id='type-id-177' name='tstate' filepath='Python/import.c' line='504' column='1'/> + <parameter type-id='type-id-2' name='module' filepath='Python/import.c' line='504' column='1'/> + <parameter type-id='type-id-399' name='def' filepath='Python/import.c' line='504' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyState_AddModule' mangled-name='PyState_AddModule' filepath='Python/import.c' line='520' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyState_AddModule'> + <parameter type-id='type-id-2' name='module' filepath='Python/import.c' line='520' column='1'/> + <parameter type-id='type-id-399' name='def' filepath='Python/import.c' line='520' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyState_RemoveModule' mangled-name='PyState_RemoveModule' filepath='Python/import.c' line='549' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyState_RemoveModule'> + <parameter type-id='type-id-399' name='def' filepath='Python/import.c' line='549' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyImport_ClearExtension' mangled-name='_PyImport_ClearExtension' filepath='Python/import.c' line='794' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyImport_ClearExtension'> + <parameter type-id='type-id-2' name='name' filepath='Python/import.c' line='794' column='1'/> + <parameter type-id='type-id-2' name='filename' filepath='Python/import.c' line='794' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyImport_FixupExtensionObject' mangled-name='_PyImport_FixupExtensionObject' filepath='Python/import.c' line='1224' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyImport_FixupExtensionObject'> + <parameter type-id='type-id-2' name='mod' filepath='Python/import.c' line='1224' column='1'/> + <parameter type-id='type-id-2' name='name' filepath='Python/import.c' line='1224' column='1'/> + <parameter type-id='type-id-2' name='filename' filepath='Python/import.c' line='1225' column='1'/> + <parameter type-id='type-id-2' name='modules' filepath='Python/import.c' line='1225' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyImport_FixupBuiltin' mangled-name='_PyImport_FixupBuiltin' filepath='Python/import.c' line='1346' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyImport_FixupBuiltin'> + <parameter type-id='type-id-2' name='mod' filepath='Python/import.c' line='1346' column='1'/> + <parameter type-id='type-id-12' name='name' filepath='Python/import.c' line='1346' column='1'/> + <parameter type-id='type-id-2' name='modules' filepath='Python/import.c' line='1346' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyImport_ExtendInittab' mangled-name='PyImport_ExtendInittab' filepath='Python/import.c' line='1444' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyImport_ExtendInittab'> + <parameter type-id='type-id-924' name='newtab' filepath='Python/import.c' line='1444' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyImport_AppendInittab' mangled-name='PyImport_AppendInittab' filepath='Python/import.c' line='1494' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyImport_AppendInittab'> + <parameter type-id='type-id-12' name='name' filepath='Python/import.c' line='1494' column='1'/> + <parameter type-id='type-id-390' name='initfunc' filepath='Python/import.c' line='1494' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyImport_GetMagicNumber' mangled-name='PyImport_GetMagicNumber' filepath='Python/import.c' line='1571' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyImport_GetMagicNumber'> + <return type-id='type-id-47'/> + </function-decl> + <function-decl name='PyImport_GetMagicTag' mangled-name='PyImport_GetMagicTag' filepath='Python/import.c' line='1593' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyImport_GetMagicTag'> + <return type-id='type-id-12'/> + </function-decl> + <function-decl name='PyImport_ExecCodeModule' mangled-name='PyImport_ExecCodeModule' filepath='Python/import.c' line='1614' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyImport_ExecCodeModule'> + <parameter type-id='type-id-12' name='name' filepath='Python/import.c' line='1614' column='1'/> + <parameter type-id='type-id-2' name='co' filepath='Python/import.c' line='1614' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyImport_ExecCodeModuleEx' mangled-name='PyImport_ExecCodeModuleEx' filepath='Python/import.c' line='1621' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyImport_ExecCodeModuleEx'> + <parameter type-id='type-id-12' name='name' filepath='Python/import.c' line='1621' column='1'/> + <parameter type-id='type-id-2' name='co' filepath='Python/import.c' line='1621' column='1'/> + <parameter type-id='type-id-12' name='pathname' filepath='Python/import.c' line='1621' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyImport_ExecCodeModuleWithPathnames' mangled-name='PyImport_ExecCodeModuleWithPathnames' filepath='Python/import.c' line='1628' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyImport_ExecCodeModuleWithPathnames'> + <parameter type-id='type-id-12' name='name' filepath='Python/import.c' line='1628' column='1'/> + <parameter type-id='type-id-2' name='co' filepath='Python/import.c' line='1628' column='1'/> + <parameter type-id='type-id-12' name='pathname' filepath='Python/import.c' line='1629' column='1'/> + <parameter type-id='type-id-12' name='cpathname' filepath='Python/import.c' line='1630' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyImport_ExecCodeModuleObject' mangled-name='PyImport_ExecCodeModuleObject' filepath='Python/import.c' line='1730' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyImport_ExecCodeModuleObject'> + <parameter type-id='type-id-2' name='name' filepath='Python/import.c' line='1730' column='1'/> + <parameter type-id='type-id-2' name='co' filepath='Python/import.c' line='1730' column='1'/> + <parameter type-id='type-id-2' name='pathname' filepath='Python/import.c' line='1730' column='1'/> + <parameter type-id='type-id-2' name='cpathname' filepath='Python/import.c' line='1731' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyImport_ImportFrozenModuleObject' mangled-name='PyImport_ImportFrozenModuleObject' filepath='Python/import.c' line='2110' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyImport_ImportFrozenModuleObject'> + <parameter type-id='type-id-2' name='name' filepath='Python/import.c' line='2110' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyImport_GetImporter' mangled-name='PyImport_GetImporter' filepath='Python/import.c' line='2424' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyImport_GetImporter'> + <parameter type-id='type-id-2' name='path' filepath='Python/import.c' line='2424' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyImport_ImportModuleNoBlock' mangled-name='PyImport_ImportModuleNoBlock' filepath='Python/import.c' line='2488' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyImport_ImportModuleNoBlock'> + <parameter type-id='type-id-12' name='name' filepath='Python/import.c' line='2488' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyImport_ImportModuleLevel' mangled-name='PyImport_ImportModuleLevel' filepath='Python/import.c' line='2935' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyImport_ImportModuleLevel'> + <parameter type-id='type-id-12' name='name' filepath='Python/import.c' line='2935' column='1'/> + <parameter type-id='type-id-2' name='globals' filepath='Python/import.c' line='2935' column='1'/> + <parameter type-id='type-id-2' name='locals' filepath='Python/import.c' line='2935' column='1'/> + <parameter type-id='type-id-2' name='fromlist' filepath='Python/import.c' line='2936' column='1'/> + <parameter type-id='type-id-8' name='level' filepath='Python/import.c' line='2936' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyImport_ReloadModule' mangled-name='PyImport_ReloadModule' filepath='Python/import.c' line='2953' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyImport_ReloadModule'> + <parameter type-id='type-id-2' name='m' filepath='Python/import.c' line='2953' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyImport_GetModuleAttr' mangled-name='_PyImport_GetModuleAttr' filepath='Python/import.c' line='3266' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyImport_GetModuleAttr'> + <parameter type-id='type-id-2' name='modname' filepath='Python/import.c' line='3266' column='1'/> + <parameter type-id='type-id-2' name='attrname' filepath='Python/import.c' line='3266' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyInit__imp' mangled-name='PyInit__imp' filepath='Python/import.c' line='3895' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInit__imp'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyImport_LoadDynamicModuleWithSpec' filepath='Python/importdl.h' line='11' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-229'/> + <return type-id='type-id-2'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Python/initconfig.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <class-decl name='_PyArgv' size-in-bits='256' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_initconfig.h' line='64' column='1' id='type-id-1427'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='argc' type-id='type-id-14' visibility='default' filepath='./Include/internal/pycore_initconfig.h' line='65' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='use_bytes_argv' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_initconfig.h' line='66' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='bytes_argv' type-id='type-id-136' visibility='default' filepath='./Include/internal/pycore_initconfig.h' line='67' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='wchar_argv' type-id='type-id-1428' visibility='default' filepath='./Include/internal/pycore_initconfig.h' line='68' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='_PyArgv' type-id='type-id-1427' filepath='./Include/internal/pycore_initconfig.h' line='69' column='1' id='type-id-1429'/> + <class-decl name='_PyPreCmdline' size-in-bits='384' is-struct='yes' naming-typedef-id='type-id-1430' visibility='default' filepath='./Include/internal/pycore_initconfig.h' line='97' column='1' id='type-id-1431'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='argv' type-id='type-id-741' visibility='default' filepath='./Include/internal/pycore_initconfig.h' line='98' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='xoptions' type-id='type-id-741' visibility='default' filepath='./Include/internal/pycore_initconfig.h' line='99' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='isolated' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_initconfig.h' line='100' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='288'> + <var-decl name='use_environment' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_initconfig.h' line='101' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='dev_mode' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_initconfig.h' line='102' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='352'> + <var-decl name='warn_default_encoding' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_initconfig.h' line='103' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='_PyPreCmdline' type-id='type-id-1431' filepath='./Include/internal/pycore_initconfig.h' line='104' column='1' id='type-id-1430'/> + <pointer-type-def type-id='type-id-744' size-in-bits='64' id='type-id-1432'/> + <pointer-type-def type-id='type-id-741' size-in-bits='64' id='type-id-1433'/> + <pointer-type-def type-id='type-id-1430' size-in-bits='64' id='type-id-1434'/> + <qualified-type-def type-id='type-id-744' const='yes' id='type-id-1435'/> + <pointer-type-def type-id='type-id-1435' size-in-bits='64' id='type-id-1436'/> + <qualified-type-def type-id='type-id-741' const='yes' id='type-id-1437'/> + <pointer-type-def type-id='type-id-1437' size-in-bits='64' id='type-id-232'/> + <qualified-type-def type-id='type-id-1429' const='yes' id='type-id-1438'/> + <pointer-type-def type-id='type-id-1438' size-in-bits='64' id='type-id-1439'/> + <qualified-type-def type-id='type-id-1430' const='yes' id='type-id-1440'/> + <pointer-type-def type-id='type-id-1440' size-in-bits='64' id='type-id-1441'/> + <qualified-type-def type-id='type-id-16' restrict='yes' id='type-id-18'/> + <qualified-type-def type-id='type-id-52' const='yes' id='type-id-1442'/> + <pointer-type-def type-id='type-id-1442' size-in-bits='64' id='type-id-1428'/> + <qualified-type-def type-id='type-id-52' restrict='yes' id='type-id-17'/> + <qualified-type-def type-id='type-id-235' restrict='yes' id='type-id-1443'/> + <pointer-type-def type-id='type-id-235' size-in-bits='64' id='type-id-1444'/> + <var-decl name='Py_DebugFlag' type-id='type-id-8' mangled-name='Py_DebugFlag' visibility='default' filepath='./Include/cpython/pydebug.h' line='8' column='1' elf-symbol-id='Py_DebugFlag'/> + <var-decl name='Py_VerboseFlag' type-id='type-id-8' mangled-name='Py_VerboseFlag' visibility='default' filepath='./Include/cpython/pydebug.h' line='9' column='1' elf-symbol-id='Py_VerboseFlag'/> + <var-decl name='Py_QuietFlag' type-id='type-id-8' mangled-name='Py_QuietFlag' visibility='default' filepath='./Include/cpython/pydebug.h' line='10' column='1' elf-symbol-id='Py_QuietFlag'/> + <var-decl name='Py_InteractiveFlag' type-id='type-id-8' mangled-name='Py_InteractiveFlag' visibility='default' filepath='./Include/cpython/pydebug.h' line='11' column='1' elf-symbol-id='Py_InteractiveFlag'/> + <var-decl name='Py_InspectFlag' type-id='type-id-8' mangled-name='Py_InspectFlag' visibility='default' filepath='./Include/cpython/pydebug.h' line='12' column='1' elf-symbol-id='Py_InspectFlag'/> + <var-decl name='Py_OptimizeFlag' type-id='type-id-8' mangled-name='Py_OptimizeFlag' visibility='default' filepath='./Include/cpython/pydebug.h' line='13' column='1' elf-symbol-id='Py_OptimizeFlag'/> + <var-decl name='Py_NoSiteFlag' type-id='type-id-8' mangled-name='Py_NoSiteFlag' visibility='default' filepath='./Include/cpython/pydebug.h' line='14' column='1' elf-symbol-id='Py_NoSiteFlag'/> + <var-decl name='Py_BytesWarningFlag' type-id='type-id-8' mangled-name='Py_BytesWarningFlag' visibility='default' filepath='./Include/cpython/pydebug.h' line='15' column='1' elf-symbol-id='Py_BytesWarningFlag'/> + <var-decl name='Py_FrozenFlag' type-id='type-id-8' mangled-name='Py_FrozenFlag' visibility='default' filepath='./Include/cpython/pydebug.h' line='16' column='1' elf-symbol-id='Py_FrozenFlag'/> + <var-decl name='Py_IgnoreEnvironmentFlag' type-id='type-id-8' mangled-name='Py_IgnoreEnvironmentFlag' visibility='default' filepath='./Include/cpython/pydebug.h' line='17' column='1' elf-symbol-id='Py_IgnoreEnvironmentFlag'/> + <var-decl name='Py_DontWriteBytecodeFlag' type-id='type-id-8' mangled-name='Py_DontWriteBytecodeFlag' visibility='default' filepath='./Include/cpython/pydebug.h' line='18' column='1' elf-symbol-id='Py_DontWriteBytecodeFlag'/> + <var-decl name='Py_NoUserSiteDirectory' type-id='type-id-8' mangled-name='Py_NoUserSiteDirectory' visibility='default' filepath='./Include/cpython/pydebug.h' line='19' column='1' elf-symbol-id='Py_NoUserSiteDirectory'/> + <var-decl name='Py_UnbufferedStdioFlag' type-id='type-id-8' mangled-name='Py_UnbufferedStdioFlag' visibility='default' filepath='./Include/cpython/pydebug.h' line='20' column='1' elf-symbol-id='Py_UnbufferedStdioFlag'/> + <var-decl name='Py_HashRandomizationFlag' type-id='type-id-8' mangled-name='Py_HashRandomizationFlag' visibility='default' filepath='./Include/cpython/pydebug.h' line='21' column='1' elf-symbol-id='Py_HashRandomizationFlag'/> + <var-decl name='Py_IsolatedFlag' type-id='type-id-8' mangled-name='Py_IsolatedFlag' visibility='default' filepath='./Include/cpython/pydebug.h' line='22' column='1' elf-symbol-id='Py_IsolatedFlag'/> + <var-decl name='Py_UTF8Mode' type-id='type-id-8' mangled-name='Py_UTF8Mode' visibility='default' filepath='./Include/fileobject.h' line='29' column='1' elf-symbol-id='Py_UTF8Mode'/> + <function-decl name='Py_DecodeLocale' mangled-name='Py_DecodeLocale' filepath='./Include/fileutils.h' line='8' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_DecodeLocale'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-441'/> + <return type-id='type-id-52'/> + </function-decl> + <function-decl name='_Py_GetForceASCII' mangled-name='_Py_GetForceASCII' filepath='./Include/internal/pycore_fileutils.h' line='212' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_GetForceASCII'> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_Py_GetLocaleEncoding' mangled-name='_Py_GetLocaleEncoding' filepath='./Include/internal/pycore_fileutils.h' line='229' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_GetLocaleEncoding'> + <return type-id='type-id-52'/> + </function-decl> + <function-decl name='_Py_isabs' filepath='./Include/internal/pycore_fileutils.h' line='244' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-16'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_Py_abspath' filepath='./Include/internal/pycore_fileutils.h' line='245' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-16'/> + <parameter type-id='type-id-235'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyOS_ResetGetOpt' filepath='./Include/internal/pycore_getopt.h' line='12' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyOS_GetOpt' filepath='./Include/internal/pycore_getopt.h' line='20' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-14'/> + <parameter type-id='type-id-1428'/> + <parameter type-id='type-id-179'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyArgv_AsWstrList' mangled-name='_PyArgv_AsWstrList' filepath='./Include/internal/pycore_initconfig.h' line='71' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyArgv_AsWstrList'> + <parameter type-id='type-id-1439'/> + <parameter type-id='type-id-1433'/> + <return type-id='type-id-54'/> + </function-decl> + <function-decl name='_Py_str_to_int' mangled-name='_Py_str_to_int' filepath='./Include/internal/pycore_initconfig.h' line='77' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_str_to_int'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-179'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_Py_get_xoption' mangled-name='_Py_get_xoption' filepath='./Include/internal/pycore_initconfig.h' line='80' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_get_xoption'> + <parameter type-id='type-id-232'/> + <parameter type-id='type-id-16'/> + <return type-id='type-id-16'/> + </function-decl> + <function-decl name='_Py_GetEnv' mangled-name='_Py_GetEnv' filepath='./Include/internal/pycore_initconfig.h' line='83' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_GetEnv'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-12'/> + <return type-id='type-id-12'/> + </function-decl> + <function-decl name='_Py_get_env_flag' mangled-name='_Py_get_env_flag' filepath='./Include/internal/pycore_initconfig.h' line='86' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_get_env_flag'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-179'/> + <parameter type-id='type-id-12'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyPreCmdline_Clear' filepath='./Include/internal/pycore_initconfig.h' line='113' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1434'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyPreCmdline_SetConfig' filepath='./Include/internal/pycore_initconfig.h' line='116' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1441'/> + <parameter type-id='type-id-53'/> + <return type-id='type-id-54'/> + </function-decl> + <function-decl name='_PyPreCmdline_Read' filepath='./Include/internal/pycore_initconfig.h' line='119' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1434'/> + <parameter type-id='type-id-1436'/> + <return type-id='type-id-54'/> + </function-decl> + <function-decl name='_PyPreConfig_InitFromPreConfig' filepath='./Include/internal/pycore_initconfig.h' line='129' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1432'/> + <parameter type-id='type-id-1436'/> + <return type-id='type-id-54'/> + </function-decl> + <function-decl name='_PyPreConfig_AsDict' filepath='./Include/internal/pycore_initconfig.h' line='132' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1436'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyPreConfig_GetConfig' filepath='./Include/internal/pycore_initconfig.h' line='133' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1432'/> + <parameter type-id='type-id-260'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyConfig_InitPathConfig' filepath='./Include/internal/pycore_initconfig.h' line='153' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-53'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-54'/> + </function-decl> + <function-decl name='_Py_IsLocaleCoercionTarget' mangled-name='_Py_IsLocaleCoercionTarget' filepath='./Include/internal/pycore_pylifecycle.h' line='28' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_IsLocaleCoercionTarget'> + <parameter type-id='type-id-12'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PySys_ReadPreinitWarnOptions' filepath='./Include/internal/pycore_pylifecycle.h' line='38' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1433'/> + <return type-id='type-id-54'/> + </function-decl> + <function-decl name='_PySys_ReadPreinitXOptions' filepath='./Include/internal/pycore_pylifecycle.h' line='39' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-53'/> + <return type-id='type-id-54'/> + </function-decl> + <function-decl name='_Py_PreInitializeFromConfig' mangled-name='_Py_PreInitializeFromConfig' filepath='./Include/internal/pycore_pylifecycle.h' line='77' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_PreInitializeFromConfig'> + <parameter type-id='type-id-260'/> + <parameter type-id='type-id-1439'/> + <return type-id='type-id-54'/> + </function-decl> + <function-decl name='setlocale' filepath='/usr/include/locale.h' line='122' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-12'/> + <return type-id='type-id-15'/> + </function-decl> + <function-decl name='setvbuf' filepath='/usr/include/stdio.h' line='332' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-412'/> + <parameter type-id='type-id-183'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-19'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='printf' filepath='/usr/include/stdio.h' line='356' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <parameter is-variadic='yes'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='puts' filepath='/usr/include/stdio.h' line='661' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='strtoul' filepath='/usr/include/stdlib.h' line='181' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-181'/> + <parameter type-id='type-id-184'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-28'/> + </function-decl> + <function-decl name='getenv' filepath='/usr/include/stdlib.h' line='641' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <return type-id='type-id-15'/> + </function-decl> + <function-decl name='wcschr' filepath='/usr/include/wchar.h' line='165' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-16'/> + <parameter type-id='type-id-422'/> + <return type-id='type-id-52'/> + </function-decl> + <function-decl name='wcstok' filepath='/usr/include/wchar.h' line='218' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-17'/> + <parameter type-id='type-id-18'/> + <parameter type-id='type-id-1443'/> + <return type-id='type-id-52'/> + </function-decl> + <function-decl name='wcstol' filepath='/usr/include/wchar.h' line='429' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-18'/> + <parameter type-id='type-id-1443'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-47'/> + </function-decl> + <function-decl name='PyStatus_Ok' mangled-name='PyStatus_Ok' filepath='Python/initconfig.c' line='312' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyStatus_Ok'> + <return type-id='type-id-54'/> + </function-decl> + <function-decl name='PyStatus_Error' mangled-name='PyStatus_Error' filepath='Python/initconfig.c' line='315' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyStatus_Error'> + <parameter type-id='type-id-12' name='err_msg' filepath='Python/initconfig.c' line='315' column='1'/> + <return type-id='type-id-54'/> + </function-decl> + <function-decl name='PyStatus_Exit' mangled-name='PyStatus_Exit' filepath='Python/initconfig.c' line='325' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyStatus_Exit'> + <parameter type-id='type-id-8' name='exitcode' filepath='Python/initconfig.c' line='325' column='1'/> + <return type-id='type-id-54'/> + </function-decl> + <function-decl name='PyStatus_IsError' mangled-name='PyStatus_IsError' filepath='Python/initconfig.c' line='329' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyStatus_IsError'> + <parameter type-id='type-id-54' name='status' filepath='Python/initconfig.c' line='329' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyStatus_IsExit' mangled-name='PyStatus_IsExit' filepath='Python/initconfig.c' line='332' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyStatus_IsExit'> + <parameter type-id='type-id-54' name='status' filepath='Python/initconfig.c' line='332' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyErr_SetFromPyStatus' mangled-name='_PyErr_SetFromPyStatus' filepath='Python/initconfig.c' line='339' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyErr_SetFromPyStatus'> + <parameter type-id='type-id-54' name='status' filepath='Python/initconfig.c' line='339' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyWideStringList_Clear' mangled-name='_PyWideStringList_Clear' filepath='Python/initconfig.c' line='375' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyWideStringList_Clear'> + <parameter type-id='type-id-1433' name='list' filepath='Python/initconfig.c' line='375' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyWideStringList_Copy' mangled-name='_PyWideStringList_Copy' filepath='Python/initconfig.c' line='388' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyWideStringList_Copy'> + <parameter type-id='type-id-1433' name='list' filepath='Python/initconfig.c' line='388' column='1'/> + <parameter type-id='type-id-232' name='list2' filepath='Python/initconfig.c' line='388' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyWideStringList_Insert' mangled-name='PyWideStringList_Insert' filepath='Python/initconfig.c' line='423' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyWideStringList_Insert'> + <parameter type-id='type-id-1433' name='list' filepath='Python/initconfig.c' line='423' column='1'/> + <parameter type-id='type-id-14' name='index' filepath='Python/initconfig.c' line='424' column='1'/> + <parameter type-id='type-id-16' name='item' filepath='Python/initconfig.c' line='424' column='1'/> + <return type-id='type-id-54'/> + </function-decl> + <function-decl name='PyWideStringList_Append' mangled-name='PyWideStringList_Append' filepath='Python/initconfig.c' line='464' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyWideStringList_Append'> + <parameter type-id='type-id-1433' name='list' filepath='Python/initconfig.c' line='464' column='1'/> + <parameter type-id='type-id-16' name='item' filepath='Python/initconfig.c' line='464' column='1'/> + <return type-id='type-id-54'/> + </function-decl> + <function-decl name='_PyWideStringList_Extend' mangled-name='_PyWideStringList_Extend' filepath='Python/initconfig.c' line='471' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyWideStringList_Extend'> + <parameter type-id='type-id-1433' name='list' filepath='Python/initconfig.c' line='471' column='1'/> + <parameter type-id='type-id-232' name='list2' filepath='Python/initconfig.c' line='471' column='1'/> + <return type-id='type-id-54'/> + </function-decl> + <function-decl name='_PyWideStringList_AsList' mangled-name='_PyWideStringList_AsList' filepath='Python/initconfig.c' line='496' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyWideStringList_AsList'> + <parameter type-id='type-id-232' name='list' filepath='Python/initconfig.c' line='496' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='Py_SetStandardStreamEncoding' mangled-name='Py_SetStandardStreamEncoding' filepath='Python/initconfig.c' line='527' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_SetStandardStreamEncoding'> + <parameter type-id='type-id-12' name='encoding' filepath='Python/initconfig.c' line='527' column='1'/> + <parameter type-id='type-id-12' name='errors' filepath='Python/initconfig.c' line='527' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_Py_ClearStandardStreamEncoding' mangled-name='_Py_ClearStandardStreamEncoding' filepath='Python/initconfig.c' line='585' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_ClearStandardStreamEncoding'> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_Py_ClearArgcArgv' mangled-name='_Py_ClearArgcArgv' filepath='Python/initconfig.c' line='608' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_ClearArgcArgv'> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='Py_GetArgcArgv' mangled-name='Py_GetArgcArgv' filepath='Python/initconfig.c' line='639' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_GetArgcArgv'> + <parameter type-id='type-id-179' name='argc' filepath='Python/initconfig.c' line='639' column='1'/> + <parameter type-id='type-id-1444' name='argv' filepath='Python/initconfig.c' line='639' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyConfig_InitCompatConfig' mangled-name='_PyConfig_InitCompatConfig' filepath='Python/initconfig.c' line='758' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyConfig_InitCompatConfig'> + <parameter type-id='type-id-53' name='config' filepath='Python/initconfig.c' line='758' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyConfig_InitIsolatedConfig' mangled-name='PyConfig_InitIsolatedConfig' filepath='Python/initconfig.c' line='842' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyConfig_InitIsolatedConfig'> + <parameter type-id='type-id-53' name='config' filepath='Python/initconfig.c' line='842' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyConfig_SetString' mangled-name='PyConfig_SetString' filepath='Python/initconfig.c' line='867' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyConfig_SetString'> + <parameter type-id='type-id-53' name='config' filepath='Python/initconfig.c' line='867' column='1'/> + <parameter type-id='type-id-235' name='config_str' filepath='Python/initconfig.c' line='867' column='1'/> + <parameter type-id='type-id-16' name='str' filepath='Python/initconfig.c' line='867' column='1'/> + <return type-id='type-id-54'/> + </function-decl> + <function-decl name='PyConfig_SetBytesString' mangled-name='PyConfig_SetBytesString' filepath='Python/initconfig.c' line='929' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyConfig_SetBytesString'> + <parameter type-id='type-id-53' name='config' filepath='Python/initconfig.c' line='929' column='1'/> + <parameter type-id='type-id-235' name='config_str' filepath='Python/initconfig.c' line='929' column='1'/> + <parameter type-id='type-id-12' name='str' filepath='Python/initconfig.c' line='930' column='1'/> + <return type-id='type-id-54'/> + </function-decl> + <function-decl name='_PyConfig_AsDict' mangled-name='_PyConfig_AsDict' filepath='Python/initconfig.c' line='1038' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyConfig_AsDict'> + <parameter type-id='type-id-260' name='config' filepath='Python/initconfig.c' line='1038' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyConfig_FromDict' mangled-name='_PyConfig_FromDict' filepath='Python/initconfig.c' line='1306' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyConfig_FromDict'> + <parameter type-id='type-id-53' name='config' filepath='Python/initconfig.c' line='1306' column='1'/> + <parameter type-id='type-id-2' name='dict' filepath='Python/initconfig.c' line='1306' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyConfig_SetArgv' mangled-name='PyConfig_SetArgv' filepath='Python/initconfig.c' line='2955' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyConfig_SetArgv'> + <parameter type-id='type-id-53' name='config' filepath='Python/initconfig.c' line='2955' column='1'/> + <parameter type-id='type-id-14' name='argc' filepath='Python/initconfig.c' line='2955' column='1'/> + <parameter type-id='type-id-1428' name='argv' filepath='Python/initconfig.c' line='2955' column='1'/> + <return type-id='type-id-54'/> + </function-decl> + <function-decl name='PyConfig_SetWideStringList' mangled-name='PyConfig_SetWideStringList' filepath='Python/initconfig.c' line='2967' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyConfig_SetWideStringList'> + <parameter type-id='type-id-53' name='config' filepath='Python/initconfig.c' line='2967' column='1'/> + <parameter type-id='type-id-1433' name='list' filepath='Python/initconfig.c' line='2967' column='1'/> + <parameter type-id='type-id-14' name='length' filepath='Python/initconfig.c' line='2968' column='1'/> + <parameter type-id='type-id-235' name='items' filepath='Python/initconfig.c' line='2968' column='1'/> + <return type-id='type-id-54'/> + </function-decl> + <function-decl name='PyConfig_Read' mangled-name='PyConfig_Read' filepath='Python/initconfig.c' line='3051' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyConfig_Read'> + <parameter type-id='type-id-53' name='config' filepath='Python/initconfig.c' line='3051' column='1'/> + <return type-id='type-id-54'/> + </function-decl> + <function-decl name='_Py_GetConfigsAsDict' mangled-name='_Py_GetConfigsAsDict' filepath='Python/initconfig.c' line='3058' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_GetConfigsAsDict'> + <return type-id='type-id-2'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Python/instrumentation.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <var-decl name='_PyInstrumentation_MISSING' type-id='type-id-345' visibility='default' filepath='./Include/internal/pycore_instruments.h' line='100' column='1'/> + <var-decl name='_PyInstrumentation_DISABLE' type-id='type-id-345' visibility='default' filepath='./Include/internal/pycore_instruments.h' line='101' column='1'/> + </abi-instr> + <abi-instr address-size='64' path='Python/intrinsics.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <array-type-def dimensions='1' type-id='type-id-1445' size-in-bits='768' id='type-id-1446'> + <subrange length='12' type-id='type-id-28' id='type-id-654'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-1445' size-in-bits='infinite' id='type-id-1447'> + <subrange length='infinite' id='type-id-225'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-1448' size-in-bits='320' id='type-id-1449'> + <subrange length='5' type-id='type-id-28' id='type-id-689'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-1448' size-in-bits='infinite' id='type-id-1450'> + <subrange length='infinite' id='type-id-225'/> + </array-type-def> + <typedef-decl name='instrinsic_func1' type-id='type-id-1451' filepath='./Include/internal/pycore_intrinsics.h' line='29' column='1' id='type-id-1452'/> + <typedef-decl name='instrinsic_func2' type-id='type-id-1453' filepath='./Include/internal/pycore_intrinsics.h' line='30' column='1' id='type-id-1454'/> + <pointer-type-def type-id='type-id-1455' size-in-bits='64' id='type-id-1451'/> + <pointer-type-def type-id='type-id-1456' size-in-bits='64' id='type-id-1453'/> + <qualified-type-def type-id='type-id-1452' const='yes' id='type-id-1445'/> + <qualified-type-def type-id='type-id-1454' const='yes' id='type-id-1448'/> + <function-decl name='_PyFrame_LocalsToFast' filepath='./Include/internal/pycore_frame.h' line='236' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-374'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_Py_set_function_type_params' filepath='./Include/internal/pycore_function.h' line='20' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-177'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyAsyncGenValueWrapperNew' filepath='./Include/internal/pycore_genobject.h' line='13' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-177'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <var-decl name='_PyIntrinsics_UnaryFunctions' type-id='type-id-1447' visibility='default' filepath='./Include/internal/pycore_intrinsics.h' line='31' column='1'/> + <var-decl name='_PyIntrinsics_BinaryFunctions' type-id='type-id-1450' visibility='default' filepath='./Include/internal/pycore_intrinsics.h' line='32' column='1'/> + <function-decl name='_Py_make_typevar' filepath='./Include/internal/pycore_typevarobject.h' line='11' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_Py_make_paramspec' filepath='./Include/internal/pycore_typevarobject.h' line='12' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-177'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_Py_make_typevartuple' filepath='./Include/internal/pycore_typevarobject.h' line='13' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-177'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_Py_make_typealias' filepath='./Include/internal/pycore_typevarobject.h' line='14' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-177'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_Py_subscript_generic' filepath='./Include/internal/pycore_typevarobject.h' line='15' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-177'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-type size-in-bits='64' id='type-id-1455'> + <parameter type-id='type-id-177'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-type> + <function-type size-in-bits='64' id='type-id-1456'> + <parameter type-id='type-id-177'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-type> + </abi-instr> + <abi-instr address-size='64' path='Python/legacy_tracing.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <typedef-decl name='_PyMonitoringEventSet' type-id='type-id-352' filepath='./Include/internal/pycore_instruments.h' line='49' column='1' id='type-id-1457'/> + <function-decl name='_PyMonitoring_RegisterCallback' filepath='./Include/internal/pycore_instruments.h' line='64' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyMonitoring_SetEvents' filepath='./Include/internal/pycore_instruments.h' line='66' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-1457'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_Py_Instrumentation_GetLine' filepath='./Include/internal/pycore_instruments.h' line='98' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-328'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-8'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Python/marshal.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <array-type-def dimensions='1' type-id='type-id-116' size-in-bits='192' id='type-id-1458'> + <subrange length='3' type-id='type-id-28' id='type-id-631'/> + </array-type-def> + <class-decl name='stat' size-in-bits='1152' is-struct='yes' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/struct_stat.h' line='26' column='1' id='type-id-1459'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='st_dev' type-id='type-id-187' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/struct_stat.h' line='31' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='st_ino' type-id='type-id-1460' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/struct_stat.h' line='36' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='st_nlink' type-id='type-id-1461' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/struct_stat.h' line='44' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='st_mode' type-id='type-id-123' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/struct_stat.h' line='45' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='224'> + <var-decl name='st_uid' type-id='type-id-125' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/struct_stat.h' line='47' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='st_gid' type-id='type-id-121' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/struct_stat.h' line='48' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='288'> + <var-decl name='__pad0' type-id='type-id-8' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/struct_stat.h' line='50' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='st_rdev' type-id='type-id-187' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/struct_stat.h' line='52' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='384'> + <var-decl name='st_size' type-id='type-id-1282' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/struct_stat.h' line='57' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='448'> + <var-decl name='st_blksize' type-id='type-id-1462' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/struct_stat.h' line='61' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='512'> + <var-decl name='st_blocks' type-id='type-id-1463' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/struct_stat.h' line='63' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='576'> + <var-decl name='st_atim' type-id='type-id-1344' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/struct_stat.h' line='74' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='704'> + <var-decl name='st_mtim' type-id='type-id-1344' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/struct_stat.h' line='75' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='832'> + <var-decl name='st_ctim' type-id='type-id-1344' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/struct_stat.h' line='76' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='960'> + <var-decl name='__glibc_reserved' type-id='type-id-1458' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/struct_stat.h' line='89' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='__gid_t' type-id='type-id-95' filepath='/usr/include/x86_64-linux-gnu/bits/types.h' line='147' column='1' id='type-id-121'/> + <typedef-decl name='__ino_t' type-id='type-id-28' filepath='/usr/include/x86_64-linux-gnu/bits/types.h' line='148' column='1' id='type-id-1460'/> + <typedef-decl name='__mode_t' type-id='type-id-95' filepath='/usr/include/x86_64-linux-gnu/bits/types.h' line='150' column='1' id='type-id-123'/> + <typedef-decl name='__nlink_t' type-id='type-id-28' filepath='/usr/include/x86_64-linux-gnu/bits/types.h' line='151' column='1' id='type-id-1461'/> + <typedef-decl name='__blksize_t' type-id='type-id-47' filepath='/usr/include/x86_64-linux-gnu/bits/types.h' line='175' column='1' id='type-id-1462'/> + <typedef-decl name='__blkcnt_t' type-id='type-id-47' filepath='/usr/include/x86_64-linux-gnu/bits/types.h' line='180' column='1' id='type-id-1463'/> + <pointer-type-def type-id='type-id-1459' size-in-bits='64' id='type-id-51'/> + <function-decl name='_Py_fstat_noraise' mangled-name='_Py_fstat_noraise' filepath='./Include/internal/pycore_fileutils.h' line='97' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_fstat_noraise'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-51'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='fread' filepath='/usr/include/stdio.h' line='675' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-226'/> + <parameter type-id='type-id-19'/> + <parameter type-id='type-id-19'/> + <parameter type-id='type-id-412'/> + <return type-id='type-id-19'/> + </function-decl> + <function-decl name='PyMarshal_WriteLongToFile' mangled-name='PyMarshal_WriteLongToFile' filepath='Python/marshal.c' line='633' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMarshal_WriteLongToFile'> + <parameter type-id='type-id-47' name='x' filepath='Python/marshal.c' line='633' column='1'/> + <parameter type-id='type-id-229' name='fp' filepath='Python/marshal.c' line='633' column='1'/> + <parameter type-id='type-id-8' name='version' filepath='Python/marshal.c' line='633' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyMarshal_WriteObjectToFile' mangled-name='PyMarshal_WriteObjectToFile' filepath='Python/marshal.c' line='648' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMarshal_WriteObjectToFile'> + <parameter type-id='type-id-2' name='x' filepath='Python/marshal.c' line='648' column='1'/> + <parameter type-id='type-id-229' name='fp' filepath='Python/marshal.c' line='648' column='1'/> + <parameter type-id='type-id-8' name='version' filepath='Python/marshal.c' line='648' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyMarshal_ReadShortFromFile' mangled-name='PyMarshal_ReadShortFromFile' filepath='Python/marshal.c' line='1532' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMarshal_ReadShortFromFile'> + <parameter type-id='type-id-229' name='fp' filepath='Python/marshal.c' line='1532' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyMarshal_ReadLongFromFile' mangled-name='PyMarshal_ReadLongFromFile' filepath='Python/marshal.c' line='1548' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMarshal_ReadLongFromFile'> + <parameter type-id='type-id-229' name='fp' filepath='Python/marshal.c' line='1548' column='1'/> + <return type-id='type-id-47'/> + </function-decl> + <function-decl name='PyMarshal_ReadLastObjectFromFile' mangled-name='PyMarshal_ReadLastObjectFromFile' filepath='Python/marshal.c' line='1584' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMarshal_ReadLastObjectFromFile'> + <parameter type-id='type-id-229' name='fp' filepath='Python/marshal.c' line='1584' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyMarshal_ReadObjectFromFile' mangled-name='PyMarshal_ReadObjectFromFile' filepath='Python/marshal.c' line='1609' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMarshal_ReadObjectFromFile'> + <parameter type-id='type-id-229' name='fp' filepath='Python/marshal.c' line='1609' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyMarshal_WriteObjectToString' mangled-name='PyMarshal_WriteObjectToString' filepath='Python/marshal.c' line='1650' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMarshal_WriteObjectToString'> + <parameter type-id='type-id-2' name='x' filepath='Python/marshal.c' line='1650' column='1'/> + <parameter type-id='type-id-8' name='version' filepath='Python/marshal.c' line='1650' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyMarshal_Init' mangled-name='PyMarshal_Init' filepath='Python/marshal.c' line='1900' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyMarshal_Init'> + <return type-id='type-id-2'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Python/modsupport.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <function-decl name='_Py_convert_optional_to_ssize_t' mangled-name='_Py_convert_optional_to_ssize_t' filepath='Python/modsupport.c' line='16' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_convert_optional_to_ssize_t'> + <parameter type-id='type-id-2' name='obj' filepath='Python/modsupport.c' line='16' column='1'/> + <parameter type-id='type-id-22' name='result' filepath='Python/modsupport.c' line='16' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='Py_VaBuildValue' mangled-name='Py_VaBuildValue' filepath='Python/modsupport.c' line='530' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_VaBuildValue'> + <parameter type-id='type-id-12' name='format' filepath='Python/modsupport.c' line='530' column='1'/> + <parameter type-id='type-id-306' name='va' filepath='Python/modsupport.c' line='530' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_Py_VaBuildValue_SizeT' mangled-name='_Py_VaBuildValue_SizeT' filepath='Python/modsupport.c' line='536' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_VaBuildValue_SizeT'> + <parameter type-id='type-id-12' name='format' filepath='Python/modsupport.c' line='536' column='1'/> + <parameter type-id='type-id-306' name='va' filepath='Python/modsupport.c' line='536' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyModule_Add' mangled-name='_PyModule_Add' filepath='Python/modsupport.c' line='656' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyModule_Add'> + <parameter type-id='type-id-2' name='mod' filepath='Python/modsupport.c' line='656' column='1'/> + <parameter type-id='type-id-12' name='name' filepath='Python/modsupport.c' line='656' column='1'/> + <parameter type-id='type-id-2' name='value' filepath='Python/modsupport.c' line='656' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyModule_AddObject' mangled-name='PyModule_AddObject' filepath='Python/modsupport.c' line='664' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyModule_AddObject'> + <parameter type-id='type-id-2' name='mod' filepath='Python/modsupport.c' line='664' column='1'/> + <parameter type-id='type-id-12' name='name' filepath='Python/modsupport.c' line='664' column='1'/> + <parameter type-id='type-id-2' name='value' filepath='Python/modsupport.c' line='664' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyModule_AddStringConstant' mangled-name='PyModule_AddStringConstant' filepath='Python/modsupport.c' line='680' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyModule_AddStringConstant'> + <parameter type-id='type-id-2' name='m' filepath='Python/modsupport.c' line='680' column='1'/> + <parameter type-id='type-id-12' name='name' filepath='Python/modsupport.c' line='680' column='1'/> + <parameter type-id='type-id-12' name='value' filepath='Python/modsupport.c' line='680' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Python/mysnprintf.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <function-decl name='vsnprintf' filepath='/usr/include/stdio.h' line='382' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-15'/> + <parameter type-id='type-id-19'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-306'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyOS_vsnprintf' mangled-name='PyOS_vsnprintf' filepath='Python/mysnprintf.c' line='53' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyOS_vsnprintf'> + <parameter type-id='type-id-15' name='str' filepath='Python/mysnprintf.c' line='53' column='1'/> + <parameter type-id='type-id-19' name='size' filepath='Python/mysnprintf.c' line='53' column='1'/> + <parameter type-id='type-id-12' name='format' filepath='Python/mysnprintf.c' line='53' column='1'/> + <parameter type-id='type-id-306' name='va' filepath='Python/mysnprintf.c' line='53' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Python/pathconfig.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <function-decl name='_Py_wreadlink' mangled-name='_Py_wreadlink' filepath='./Include/internal/pycore_fileutils.h' line='133' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_wreadlink'> + <parameter type-id='type-id-16'/> + <parameter type-id='type-id-52'/> + <parameter type-id='type-id-19'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_Py_wrealpath' mangled-name='_Py_wrealpath' filepath='./Include/internal/pycore_fileutils.h' line='142' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_wrealpath'> + <parameter type-id='type-id-16'/> + <parameter type-id='type-id-52'/> + <parameter type-id='type-id-19'/> + <return type-id='type-id-52'/> + </function-decl> + <function-decl name='_Py_wgetcwd' mangled-name='_Py_wgetcwd' filepath='./Include/internal/pycore_fileutils.h' line='150' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_wgetcwd'> + <parameter type-id='type-id-52'/> + <parameter type-id='type-id-19'/> + <return type-id='type-id-52'/> + </function-decl> + <function-decl name='wcscpy' filepath='/usr/include/wchar.h' line='87' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-17'/> + <parameter type-id='type-id-18'/> + <return type-id='type-id-52'/> + </function-decl> + <function-decl name='wcsncpy' filepath='/usr/include/wchar.h' line='92' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-17'/> + <parameter type-id='type-id-18'/> + <parameter type-id='type-id-19'/> + <return type-id='type-id-52'/> + </function-decl> + <function-decl name='wcsrchr' filepath='/usr/include/wchar.h' line='175' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-16'/> + <parameter type-id='type-id-422'/> + <return type-id='type-id-52'/> + </function-decl> + <function-decl name='_PyPathConfig_ClearGlobal' mangled-name='_PyPathConfig_ClearGlobal' filepath='Python/pathconfig.c' line='57' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyPathConfig_ClearGlobal'> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='Py_SetPath' mangled-name='Py_SetPath' filepath='Python/pathconfig.c' line='215' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_SetPath'> + <parameter type-id='type-id-16' name='path' filepath='Python/pathconfig.c' line='215' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='Py_SetPythonHome' mangled-name='Py_SetPythonHome' filepath='Python/pathconfig.c' line='256' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_SetPythonHome'> + <parameter type-id='type-id-16' name='home' filepath='Python/pathconfig.c' line='256' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='Py_SetProgramName' mangled-name='Py_SetProgramName' filepath='Python/pathconfig.c' line='279' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_SetProgramName'> + <parameter type-id='type-id-16' name='program_name' filepath='Python/pathconfig.c' line='279' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_Py_SetProgramFullPath' mangled-name='_Py_SetProgramFullPath' filepath='Python/pathconfig.c' line='301' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_SetProgramFullPath'> + <parameter type-id='type-id-16' name='program_full_path' filepath='Python/pathconfig.c' line='301' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='Py_GetPath' mangled-name='Py_GetPath' filepath='Python/pathconfig.c' line='324' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_GetPath'> + <return type-id='type-id-52'/> + </function-decl> + <function-decl name='Py_GetPrefix' mangled-name='Py_GetPrefix' filepath='Python/pathconfig.c' line='347' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_GetPrefix'> + <return type-id='type-id-52'/> + </function-decl> + <function-decl name='Py_GetExecPrefix' mangled-name='Py_GetExecPrefix' filepath='Python/pathconfig.c' line='354' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_GetExecPrefix'> + <return type-id='type-id-52'/> + </function-decl> + <function-decl name='Py_GetProgramFullPath' mangled-name='Py_GetProgramFullPath' filepath='Python/pathconfig.c' line='361' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_GetProgramFullPath'> + <return type-id='type-id-52'/> + </function-decl> + <function-decl name='Py_GetPythonHome' mangled-name='Py_GetPythonHome' filepath='Python/pathconfig.c' line='368' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_GetPythonHome'> + <return type-id='type-id-52'/> + </function-decl> + <function-decl name='Py_GetProgramName' mangled-name='Py_GetProgramName' filepath='Python/pathconfig.c' line='375' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_GetProgramName'> + <return type-id='type-id-52'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Python/perf_trampoline.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <var-decl name='_Py_perfmap_callbacks' type-id='type-id-1464' visibility='default' filepath='./Include/internal/pycore_ceval.h' line='80' column='1'/> + <function-decl name='mprotect' filepath='/usr/include/x86_64-linux-gnu/sys/mman.h' line='81' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-22'/> + <parameter type-id='type-id-19'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-8'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Python/preconfig.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <function-decl name='_Py_CoerceLegacyLocale' mangled-name='_Py_CoerceLegacyLocale' filepath='./Include/cpython/pylifecycle.h' line='62' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_CoerceLegacyLocale'> + <parameter type-id='type-id-8'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_Py_LegacyLocaleDetected' mangled-name='_Py_LegacyLocaleDetected' filepath='./Include/cpython/pylifecycle.h' line='63' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_LegacyLocaleDetected'> + <parameter type-id='type-id-8'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_Py_SetLocaleFromEnv' mangled-name='_Py_SetLocaleFromEnv' filepath='./Include/cpython/pylifecycle.h' line='64' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_SetLocaleFromEnv'> + <parameter type-id='type-id-8'/> + <return type-id='type-id-15'/> + </function-decl> + <var-decl name='Py_FileSystemDefaultEncoding' type-id='type-id-12' mangled-name='Py_FileSystemDefaultEncoding' visibility='default' filepath='./Include/fileobject.h' line='22' column='1' elf-symbol-id='Py_FileSystemDefaultEncoding'/> + <var-decl name='Py_FileSystemDefaultEncodeErrors' type-id='type-id-12' mangled-name='Py_FileSystemDefaultEncodeErrors' visibility='default' filepath='./Include/fileobject.h' line='24' column='1' elf-symbol-id='Py_FileSystemDefaultEncodeErrors'/> + <var-decl name='Py_HasFileSystemDefaultEncoding' type-id='type-id-8' mangled-name='Py_HasFileSystemDefaultEncoding' visibility='default' filepath='./Include/fileobject.h' line='26' column='1' elf-symbol-id='Py_HasFileSystemDefaultEncoding'/> + <var-decl name='_Py_HasFileSystemDefaultEncodeErrors' type-id='type-id-8' mangled-name='_Py_HasFileSystemDefaultEncodeErrors' visibility='default' filepath='./Include/internal/pycore_fileutils.h' line='186' column='1' elf-symbol-id='_Py_HasFileSystemDefaultEncodeErrors'/> + <function-decl name='wcsncmp' filepath='/usr/include/wchar.h' line='109' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-16'/> + <parameter type-id='type-id-16'/> + <parameter type-id='type-id-19'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyPreConfig_InitCompatConfig' mangled-name='_PyPreConfig_InitCompatConfig' filepath='Python/preconfig.c' line='283' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyPreConfig_InitCompatConfig'> + <parameter type-id='type-id-1432' name='config' filepath='Python/preconfig.c' line='283' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyPreConfig_InitPythonConfig' mangled-name='PyPreConfig_InitPythonConfig' filepath='Python/preconfig.c' line='311' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyPreConfig_InitPythonConfig'> + <parameter type-id='type-id-1432' name='config' filepath='Python/preconfig.c' line='311' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyPreConfig_InitIsolatedConfig' mangled-name='PyPreConfig_InitIsolatedConfig' filepath='Python/preconfig.c' line='332' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyPreConfig_InitIsolatedConfig'> + <parameter type-id='type-id-1432' name='config' filepath='Python/preconfig.c' line='332' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Python/pyctype.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <array-type-def dimensions='1' type-id='type-id-382' size-in-bits='2048' id='type-id-1465'> + <subrange length='256' type-id='type-id-28' id='type-id-62'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-1466' size-in-bits='8192' id='type-id-1467'> + <subrange length='256' type-id='type-id-28' id='type-id-62'/> + </array-type-def> + <qualified-type-def type-id='type-id-95' const='yes' id='type-id-1466'/> + <var-decl name='_Py_ctype_table' type-id='type-id-1467' mangled-name='_Py_ctype_table' visibility='default' filepath='./Include/cpython/pyctype.h' line='16' column='1' elf-symbol-id='_Py_ctype_table'/> + <var-decl name='_Py_ctype_tolower' type-id='type-id-1465' mangled-name='_Py_ctype_tolower' visibility='default' filepath='./Include/cpython/pyctype.h' line='29' column='1' elf-symbol-id='_Py_ctype_tolower'/> + <var-decl name='_Py_ctype_toupper' type-id='type-id-1465' mangled-name='_Py_ctype_toupper' visibility='default' filepath='./Include/cpython/pyctype.h' line='30' column='1' elf-symbol-id='_Py_ctype_toupper'/> + </abi-instr> + <abi-instr address-size='64' path='Python/pyhash.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <array-type-def dimensions='1' type-id='type-id-85' size-in-bits='128' id='type-id-1468'> + <subrange length='16' type-id='type-id-28' id='type-id-57'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-85' size-in-bits='192' id='type-id-1469'> + <subrange length='24' type-id='type-id-28' id='type-id-674'/> + </array-type-def> + <union-decl name='_Py_HashSecret_t' size-in-bits='192' naming-typedef-id='type-id-1470' visibility='default' filepath='./Include/pyhash.h' line='55' column='1' id='type-id-1471'> + <data-member access='public'> + <var-decl name='uc' type-id='type-id-1469' visibility='default' filepath='./Include/pyhash.h' line='57' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='fnv' type-id='type-id-1472' visibility='default' filepath='./Include/pyhash.h' line='62' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='siphash' type-id='type-id-1473' visibility='default' filepath='./Include/pyhash.h' line='67' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='djbx33a' type-id='type-id-1474' visibility='default' filepath='./Include/pyhash.h' line='72' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='expat' type-id='type-id-1475' visibility='default' filepath='./Include/pyhash.h' line='76' column='1'/> + </data-member> + </union-decl> + <class-decl name='__anonymous_struct__' size-in-bits='128' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/pyhash.h' line='59' column='1' id='type-id-1472'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='prefix' type-id='type-id-305' visibility='default' filepath='./Include/pyhash.h' line='60' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='suffix' type-id='type-id-305' visibility='default' filepath='./Include/pyhash.h' line='61' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__1' size-in-bits='128' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/pyhash.h' line='64' column='1' id='type-id-1473'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='k0' type-id='type-id-117' visibility='default' filepath='./Include/pyhash.h' line='65' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='k1' type-id='type-id-117' visibility='default' filepath='./Include/pyhash.h' line='66' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__2' size-in-bits='192' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/pyhash.h' line='69' column='1' id='type-id-1474'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='padding' type-id='type-id-1468' visibility='default' filepath='./Include/pyhash.h' line='70' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='suffix' type-id='type-id-305' visibility='default' filepath='./Include/pyhash.h' line='71' column='1'/> + </data-member> + </class-decl> + <class-decl name='__anonymous_struct__3' size-in-bits='192' is-struct='yes' is-anonymous='yes' visibility='default' filepath='./Include/pyhash.h' line='73' column='1' id='type-id-1475'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='padding' type-id='type-id-1468' visibility='default' filepath='./Include/pyhash.h' line='74' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='hashsalt' type-id='type-id-305' visibility='default' filepath='./Include/pyhash.h' line='75' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='_Py_HashSecret_t' type-id='type-id-1471' filepath='./Include/pyhash.h' line='77' column='1' id='type-id-1470'/> + <class-decl name='PyHash_FuncDef' size-in-bits='192' is-struct='yes' naming-typedef-id='type-id-1476' visibility='default' filepath='./Include/pyhash.h' line='86' column='1' id='type-id-1477'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='hash' type-id='type-id-1478' visibility='default' filepath='./Include/pyhash.h' line='87' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='name' type-id='type-id-12' visibility='default' filepath='./Include/pyhash.h' line='88' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='hash_bits' type-id='type-id-261' visibility='default' filepath='./Include/pyhash.h' line='89' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='160'> + <var-decl name='seed_bits' type-id='type-id-261' visibility='default' filepath='./Include/pyhash.h' line='90' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='PyHash_FuncDef' type-id='type-id-1477' filepath='./Include/pyhash.h' line='91' column='1' id='type-id-1476'/> + <pointer-type-def type-id='type-id-1476' size-in-bits='64' id='type-id-1479'/> + <pointer-type-def type-id='type-id-1480' size-in-bits='64' id='type-id-1481'/> + <qualified-type-def type-id='type-id-1481' const='yes' id='type-id-1478'/> + <var-decl name='_Py_HashSecret' type-id='type-id-1470' mangled-name='_Py_HashSecret' visibility='default' filepath='./Include/pyhash.h' line='78' column='1' elf-symbol-id='_Py_HashSecret'/> + <function-decl name='PyHash_GetFuncDef' mangled-name='PyHash_GetFuncDef' filepath='Python/pyhash.c' line='221' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyHash_GetFuncDef'> + <return type-id='type-id-1479'/> + </function-decl> + <function-type size-in-bits='64' id='type-id-1480'> + <parameter type-id='type-id-22'/> + <parameter type-id='type-id-14'/> + <return type-id='type-id-305'/> + </function-type> + </abi-instr> + <abi-instr address-size='64' path='Python/pylifecycle.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <class-decl name='PyInterpreterConfig' size-in-bits='224' is-struct='yes' naming-typedef-id='type-id-1482' visibility='default' filepath='./Include/cpython/pylifecycle.h' line='72' column='1' id='type-id-1483'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='use_main_obmalloc' type-id='type-id-8' visibility='default' filepath='./Include/cpython/pylifecycle.h' line='74' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='32'> + <var-decl name='allow_fork' type-id='type-id-8' visibility='default' filepath='./Include/cpython/pylifecycle.h' line='75' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='allow_exec' type-id='type-id-8' visibility='default' filepath='./Include/cpython/pylifecycle.h' line='76' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='96'> + <var-decl name='allow_threads' type-id='type-id-8' visibility='default' filepath='./Include/cpython/pylifecycle.h' line='77' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='allow_daemon_threads' type-id='type-id-8' visibility='default' filepath='./Include/cpython/pylifecycle.h' line='78' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='160'> + <var-decl name='check_multi_interp_extensions' type-id='type-id-8' visibility='default' filepath='./Include/cpython/pylifecycle.h' line='79' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='gil' type-id='type-id-8' visibility='default' filepath='./Include/cpython/pylifecycle.h' line='80' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='PyInterpreterConfig' type-id='type-id-1483' filepath='./Include/cpython/pylifecycle.h' line='81' column='1' id='type-id-1482'/> + <class-decl name='_PyPerf_Callbacks' size-in-bits='192' is-struct='yes' naming-typedef-id='type-id-1464' visibility='default' filepath='./Include/internal/pycore_ceval.h' line='63' column='1' id='type-id-1484'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='init_state' type-id='type-id-818' visibility='default' filepath='./Include/internal/pycore_ceval.h' line='65' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='write_state' type-id='type-id-819' visibility='default' filepath='./Include/internal/pycore_ceval.h' line='67' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='free_state' type-id='type-id-814' visibility='default' filepath='./Include/internal/pycore_ceval.h' line='70' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='_PyPerf_Callbacks' type-id='type-id-1484' filepath='./Include/internal/pycore_ceval.h' line='71' column='1' id='type-id-1464'/> + <class-decl name='_PyShimCodeDef' size-in-bits='192' is-struct='yes' visibility='default' filepath='./Include/internal/pycore_code.h' line='453' column='1' id='type-id-1485'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='code' type-id='type-id-316' visibility='default' filepath='./Include/internal/pycore_code.h' line='454' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='codelen' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_code.h' line='455' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='96'> + <var-decl name='stacksize' type-id='type-id-8' visibility='default' filepath='./Include/internal/pycore_code.h' line='456' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='cname' type-id='type-id-12' visibility='default' filepath='./Include/internal/pycore_code.h' line='457' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='_PyShimCodeDef' type-id='type-id-1485' filepath='./Include/internal/pycore_code.h' line='458' column='1' id='type-id-1486'/> + <typedef-decl name='_PyRuntimeState' type-id='type-id-982' filepath='./Include/internal/pycore_runtime.h' line='181' column='1' id='type-id-1487'/> + <typedef-decl name='PyOS_sighandler_t' type-id='type-id-1016' filepath='./Include/pylifecycle.h' line='61' column='1' id='type-id-1488'/> + <typedef-decl name='nl_item' type-id='type-id-8' filepath='/usr/include/nl_types.h' line='36' column='1' id='type-id-1489'/> + <typedef-decl name='sigset_t' type-id='type-id-30' filepath='/usr/include/x86_64-linux-gnu/bits/types/sigset_t.h' line='7' column='1' id='type-id-73'/> + <pointer-type-def type-id='type-id-177' size-in-bits='64' id='type-id-1490'/> + <pointer-type-def type-id='type-id-1464' size-in-bits='64' id='type-id-231'/> + <pointer-type-def type-id='type-id-1487' size-in-bits='64' id='type-id-178'/> + <qualified-type-def type-id='type-id-1482' const='yes' id='type-id-1491'/> + <pointer-type-def type-id='type-id-1491' size-in-bits='64' id='type-id-1492'/> + <qualified-type-def type-id='type-id-1486' const='yes' id='type-id-1493'/> + <pointer-type-def type-id='type-id-1493' size-in-bits='64' id='type-id-1494'/> + <qualified-type-def type-id='type-id-836' const='yes' id='type-id-1495'/> + <pointer-type-def type-id='type-id-1495' size-in-bits='64' id='type-id-1496'/> + <qualified-type-def type-id='type-id-1496' restrict='yes' id='type-id-1497'/> + <pointer-type-def type-id='type-id-836' size-in-bits='64' id='type-id-1498'/> + <qualified-type-def type-id='type-id-1498' restrict='yes' id='type-id-1499'/> + <pointer-type-def type-id='type-id-73' size-in-bits='64' id='type-id-45'/> + <function-decl name='_Py_FinishPendingCalls' filepath='./Include/internal/pycore_ceval.h' line='23' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-177'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyEval_Fini' filepath='./Include/internal/pycore_ceval.h' line='53' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyPerfTrampoline_SetCallbacks' filepath='./Include/internal/pycore_ceval.h' line='73' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-231'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyPerfTrampoline_Init' filepath='./Include/internal/pycore_ceval.h' line='75' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyPerfTrampoline_Fini' filepath='./Include/internal/pycore_ceval.h' line='76' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyEval_InitGIL' filepath='./Include/internal/pycore_ceval.h' line='100' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-177'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-54'/> + </function-decl> + <function-decl name='_PyEval_FiniGIL' filepath='./Include/internal/pycore_ceval.h' line='101' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyEval_ReleaseLock' filepath='./Include/internal/pycore_ceval.h' line='104' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <parameter type-id='type-id-177'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_Py_MakeShimCode' filepath='./Include/internal/pycore_code.h' line='461' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1494'/> + <return type-id='type-id-328'/> + </function-decl> + <function-decl name='_PyContext_Init' filepath='./Include/internal/pycore_context.h' line='15' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-54'/> + </function-decl> + <function-decl name='_PyContext_Fini' filepath='./Include/internal/pycore_context.h' line='16' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyDict_Fini' filepath='./Include/internal/pycore_dict.h' line='18' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyExc_InitState' filepath='./Include/internal/pycore_exceptions.h' line='14' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-54'/> + </function-decl> + <function-decl name='_PyExc_InitGlobalObjects' filepath='./Include/internal/pycore_exceptions.h' line='15' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-54'/> + </function-decl> + <function-decl name='_PyExc_InitTypes' filepath='./Include/internal/pycore_exceptions.h' line='16' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyExc_Fini' filepath='./Include/internal/pycore_exceptions.h' line='17' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyExc_ClearExceptionGroupType' filepath='./Include/internal/pycore_exceptions.h' line='31' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_Py_write_noraise' mangled-name='_Py_write_noraise' filepath='./Include/internal/pycore_fileutils.h' line='127' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_write_noraise'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-22'/> + <parameter type-id='type-id-19'/> + <return type-id='type-id-14'/> + </function-decl> + <function-decl name='_Py_ResetForceASCII' mangled-name='_Py_ResetForceASCII' filepath='./Include/internal/pycore_fileutils.h' line='219' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_ResetForceASCII'> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyFloat_InitState' filepath='./Include/internal/pycore_floatobject.h' line='14' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyFloat_InitTypes' filepath='./Include/internal/pycore_floatobject.h' line='15' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-54'/> + </function-decl> + <function-decl name='_PyFloat_Fini' filepath='./Include/internal/pycore_floatobject.h' line='16' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyFloat_FiniType' filepath='./Include/internal/pycore_floatobject.h' line='17' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyGC_CollectNoFail' filepath='./Include/internal/pycore_gc.h' line='195' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-177'/> + <return type-id='type-id-14'/> + </function-decl> + <function-decl name='_PyAsyncGen_Fini' filepath='./Include/internal/pycore_genobject.h' line='17' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyImport_ClearModules' filepath='./Include/internal/pycore_import.h' line='119' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyImport_ClearModulesByIndex' filepath='./Include/internal/pycore_import.h' line='121' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyImport_InitDefaultImportFunc' filepath='./Include/internal/pycore_import.h' line='123' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyImport_GetImportlibLoader' filepath='./Include/internal/pycore_import.h' line='128' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <parameter type-id='type-id-12'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyImport_Init' filepath='./Include/internal/pycore_import.h' line='142' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-54'/> + </function-decl> + <function-decl name='_PyImport_Fini' filepath='./Include/internal/pycore_import.h' line='143' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyImport_InitCore' filepath='./Include/internal/pycore_import.h' line='146' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-177'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-54'/> + </function-decl> + <function-decl name='_PyImport_InitExternal' filepath='./Include/internal/pycore_import.h' line='150' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-177'/> + <return type-id='type-id-54'/> + </function-decl> + <function-decl name='_PyImport_FiniCore' filepath='./Include/internal/pycore_import.h' line='151' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyImport_FiniExternal' filepath='./Include/internal/pycore_import.h' line='152' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyPreConfig_InitFromConfig' filepath='./Include/internal/pycore_initconfig.h' line='126' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1432'/> + <parameter type-id='type-id-260'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyPreConfig_Read' filepath='./Include/internal/pycore_initconfig.h' line='135' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1432'/> + <parameter type-id='type-id-1439'/> + <return type-id='type-id-54'/> + </function-decl> + <function-decl name='_PyPreConfig_Write' filepath='./Include/internal/pycore_initconfig.h' line='137' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1436'/> + <return type-id='type-id-54'/> + </function-decl> + <function-decl name='_PyConfig_Copy' filepath='./Include/internal/pycore_initconfig.h' line='150' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-53'/> + <parameter type-id='type-id-260'/> + <return type-id='type-id-54'/> + </function-decl> + <function-decl name='_PyConfig_InitImportConfig' filepath='./Include/internal/pycore_initconfig.h' line='156' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-53'/> + <return type-id='type-id-54'/> + </function-decl> + <function-decl name='_PyConfig_Read' filepath='./Include/internal/pycore_initconfig.h' line='157' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-53'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-54'/> + </function-decl> + <function-decl name='_PyConfig_Write' filepath='./Include/internal/pycore_initconfig.h' line='158' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-260'/> + <parameter type-id='type-id-933'/> + <return type-id='type-id-54'/> + </function-decl> + <function-decl name='_PyInterpreterState_Clear' filepath='./Include/internal/pycore_interp.h' line='204' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-177'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyList_Fini' filepath='./Include/internal/pycore_list.h' line='16' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyLong_InitTypes' filepath='./Include/internal/pycore_long.h' line='52' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-54'/> + </function-decl> + <function-decl name='_PyLong_FiniTypes' filepath='./Include/internal/pycore_long.h' line='53' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyPathConfig_UpdateGlobal' filepath='./Include/internal/pycore_pathconfig.h' line='13' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-260'/> + <return type-id='type-id-54'/> + </function-decl> + <function-decl name='_PyErr_InitTypes' filepath='./Include/internal/pycore_pyerrors.h' line='14' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-54'/> + </function-decl> + <function-decl name='_PyErr_FiniTypes' filepath='./Include/internal/pycore_pyerrors.h' line='15' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_Py_ClearFileSystemEncoding' filepath='./Include/internal/pycore_pylifecycle.h' line='20' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyUnicode_InitEncodings' filepath='./Include/internal/pycore_pylifecycle.h' line='21' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-177'/> + <return type-id='type-id-54'/> + </function-decl> + <function-decl name='_Py_InitVersion' filepath='./Include/internal/pycore_pylifecycle.h' line='32' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyFaulthandler_Init' filepath='./Include/internal/pycore_pylifecycle.h' line='33' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <return type-id='type-id-54'/> + </function-decl> + <function-decl name='_PyBuiltin_Init' filepath='./Include/internal/pycore_pylifecycle.h' line='34' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PySys_Create' filepath='./Include/internal/pycore_pylifecycle.h' line='35' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-177'/> + <parameter type-id='type-id-233'/> + <return type-id='type-id-54'/> + </function-decl> + <function-decl name='_PySys_UpdateConfig' filepath='./Include/internal/pycore_pylifecycle.h' line='40' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-177'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PySys_FiniTypes' filepath='./Include/internal/pycore_pylifecycle.h' line='41' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyBuiltins_AddExceptions' filepath='./Include/internal/pycore_pylifecycle.h' line='42' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_Py_HashRandomization_Init' filepath='./Include/internal/pycore_pylifecycle.h' line='43' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-260'/> + <return type-id='type-id-54'/> + </function-decl> + <function-decl name='_PyTime_Init' filepath='./Include/internal/pycore_pylifecycle.h' line='45' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-54'/> + </function-decl> + <function-decl name='_PyGC_Init' filepath='./Include/internal/pycore_pylifecycle.h' line='46' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-54'/> + </function-decl> + <function-decl name='_PyAtExit_Init' filepath='./Include/internal/pycore_pylifecycle.h' line='47' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-54'/> + </function-decl> + <function-decl name='_Py_Deepfreeze_Init' filepath='./Include/internal/pycore_pylifecycle.h' line='48' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PySignal_Init' filepath='./Include/internal/pycore_pylifecycle.h' line='52' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PySignal_Fini' filepath='./Include/internal/pycore_pylifecycle.h' line='53' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_Py_HashRandomization_Fini' filepath='./Include/internal/pycore_pylifecycle.h' line='56' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyFaulthandler_Fini' filepath='./Include/internal/pycore_pylifecycle.h' line='57' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyHash_Fini' filepath='./Include/internal/pycore_pylifecycle.h' line='58' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyTraceMalloc_Fini' filepath='./Include/internal/pycore_pylifecycle.h' line='59' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyThread_FiniType' filepath='./Include/internal/pycore_pylifecycle.h' line='63' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_Py_Deepfreeze_Fini' filepath='./Include/internal/pycore_pylifecycle.h' line='64' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyArg_Fini' filepath='./Include/internal/pycore_pylifecycle.h' line='65' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_Py_FinalizeAllocatedBlocks' filepath='./Include/internal/pycore_pylifecycle.h' line='66' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-178'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyGILState_Init' filepath='./Include/internal/pycore_pylifecycle.h' line='68' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-54'/> + </function-decl> + <function-decl name='_PyGILState_SetTstate' filepath='./Include/internal/pycore_pylifecycle.h' line='69' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-177'/> + <return type-id='type-id-54'/> + </function-decl> + <function-decl name='_PyGILState_Fini' filepath='./Include/internal/pycore_pylifecycle.h' line='70' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyGC_DumpShutdownStats' filepath='./Include/internal/pycore_pylifecycle.h' line='72' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyAtExit_Call' filepath='./Include/internal/pycore_pylifecycle.h' line='94' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyMem_RawMalloc' filepath='./Include/internal/pycore_pymem_init.h' line='17' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-22'/> + <parameter type-id='type-id-19'/> + <return type-id='type-id-22'/> + </function-decl> + <function-decl name='_PyMem_RawCalloc' filepath='./Include/internal/pycore_pymem_init.h' line='18' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-22'/> + <parameter type-id='type-id-19'/> + <parameter type-id='type-id-19'/> + <return type-id='type-id-22'/> + </function-decl> + <function-decl name='_PyMem_RawRealloc' filepath='./Include/internal/pycore_pymem_init.h' line='19' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-22'/> + <parameter type-id='type-id-22'/> + <parameter type-id='type-id-19'/> + <return type-id='type-id-22'/> + </function-decl> + <function-decl name='_PyMem_RawFree' filepath='./Include/internal/pycore_pymem_init.h' line='20' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-22'/> + <parameter type-id='type-id-22'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyObject_Malloc' filepath='./Include/internal/pycore_pymem_init.h' line='24' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-22'/> + <parameter type-id='type-id-19'/> + <return type-id='type-id-22'/> + </function-decl> + <function-decl name='_PyObject_Calloc' filepath='./Include/internal/pycore_pymem_init.h' line='25' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-22'/> + <parameter type-id='type-id-19'/> + <parameter type-id='type-id-19'/> + <return type-id='type-id-22'/> + </function-decl> + <function-decl name='_PyObject_Free' filepath='./Include/internal/pycore_pymem_init.h' line='26' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-22'/> + <parameter type-id='type-id-22'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyObject_Realloc' filepath='./Include/internal/pycore_pymem_init.h' line='27' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-22'/> + <parameter type-id='type-id-22'/> + <parameter type-id='type-id-19'/> + <return type-id='type-id-22'/> + </function-decl> + <function-decl name='_PyMem_ArenaAlloc' filepath='./Include/internal/pycore_pymem_init.h' line='52' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-22'/> + <parameter type-id='type-id-19'/> + <return type-id='type-id-22'/> + </function-decl> + <function-decl name='_PyMem_ArenaFree' filepath='./Include/internal/pycore_pymem_init.h' line='53' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-22'/> + <parameter type-id='type-id-22'/> + <parameter type-id='type-id-19'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyThreadState_New' mangled-name='_PyThreadState_New' filepath='./Include/internal/pycore_pystate.h' line='124' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyThreadState_New'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-177'/> + </function-decl> + <function-decl name='_PyThreadState_Bind' mangled-name='_PyThreadState_Bind' filepath='./Include/internal/pycore_pystate.h' line='125' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyThreadState_Bind'> + <parameter type-id='type-id-177'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyInterpreterState_Enable' mangled-name='_PyInterpreterState_Enable' filepath='./Include/internal/pycore_pystate.h' line='138' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyInterpreterState_Enable'> + <parameter type-id='type-id-178'/> + <return type-id='type-id-54'/> + </function-decl> + <var-decl name='_PyRuntime' type-id='type-id-1487' mangled-name='_PyRuntime' visibility='default' filepath='./Include/internal/pycore_runtime.h' line='186' column='1' elf-symbol-id='_PyRuntime'/> + <function-decl name='_PyRuntimeState_Init' mangled-name='_PyRuntimeState_Init' filepath='./Include/internal/pycore_runtime.h' line='188' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyRuntimeState_Init'> + <parameter type-id='type-id-178'/> + <return type-id='type-id-54'/> + </function-decl> + <function-decl name='_PyRuntimeState_Fini' mangled-name='_PyRuntimeState_Fini' filepath='./Include/internal/pycore_runtime.h' line='189' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyRuntimeState_Fini'> + <parameter type-id='type-id-178'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PySlice_Fini' filepath='./Include/internal/pycore_sliceobject.h' line='14' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PySys_ClearAuditHooks' filepath='./Include/internal/pycore_sysmodule.h' line='19' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-177'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PySys_SetAttr' filepath='./Include/internal/pycore_sysmodule.h' line='21' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_Py_DumpTracebackThreads' mangled-name='_Py_DumpTracebackThreads' filepath='./Include/internal/pycore_traceback.h' line='55' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_DumpTracebackThreads'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-20'/> + <parameter type-id='type-id-177'/> + <return type-id='type-id-12'/> + </function-decl> + <function-decl name='_Py_DumpASCII' mangled-name='_Py_DumpASCII' filepath='./Include/internal/pycore_traceback.h' line='67' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_DumpASCII'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_Py_DumpDecimal' mangled-name='_Py_DumpDecimal' filepath='./Include/internal/pycore_traceback.h' line='72' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_DumpDecimal'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-19'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_Py_DumpHexadecimal' mangled-name='_Py_DumpHexadecimal' filepath='./Include/internal/pycore_traceback.h' line='78' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_DumpHexadecimal'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-749'/> + <parameter type-id='type-id-14'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyTuple_Fini' filepath='./Include/internal/pycore_tuple.h' line='17' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyTypes_InitTypes' filepath='./Include/internal/pycore_typeobject.h' line='74' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-54'/> + </function-decl> + <function-decl name='_PyTypes_FiniTypes' filepath='./Include/internal/pycore_typeobject.h' line='75' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyTypes_Fini' filepath='./Include/internal/pycore_typeobject.h' line='76' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_Py_clear_generic_types' filepath='./Include/internal/pycore_typevarobject.h' line='17' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyUnicode_InitState' filepath='./Include/internal/pycore_unicodeobject.h' line='19' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyUnicode_InitGlobalObjects' filepath='./Include/internal/pycore_unicodeobject.h' line='20' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-54'/> + </function-decl> + <function-decl name='_PyUnicode_InitTypes' filepath='./Include/internal/pycore_unicodeobject.h' line='21' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-54'/> + </function-decl> + <function-decl name='_PyUnicode_Fini' filepath='./Include/internal/pycore_unicodeobject.h' line='22' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyUnicode_FiniTypes' filepath='./Include/internal/pycore_unicodeobject.h' line='23' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyUnicode_ClearInterned' filepath='./Include/internal/pycore_unicodeobject.h' line='64' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyWarnings_InitState' filepath='./Include/internal/pycore_warnings.h' line='20' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyModule_IsExtension' filepath='./Include/moduleobject.h' line='109' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyGC_Collect' mangled-name='PyGC_Collect' filepath='./Include/objimpl.h' line='154' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyGC_Collect'> + <return type-id='type-id-14'/> + </function-decl> + <function-decl name='PyInterpreterState_New' mangled-name='PyInterpreterState_New' filepath='./Include/pystate.h' line='14' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInterpreterState_New'> + <return type-id='type-id-20'/> + </function-decl> + <function-decl name='PyInterpreterState_Delete' mangled-name='PyInterpreterState_Delete' filepath='./Include/pystate.h' line='16' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInterpreterState_Delete'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyThreadState_Clear' mangled-name='PyThreadState_Clear' filepath='./Include/pystate.h' line='49' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThreadState_Clear'> + <parameter type-id='type-id-177'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyThreadState_Delete' mangled-name='PyThreadState_Delete' filepath='./Include/pystate.h' line='50' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThreadState_Delete'> + <parameter type-id='type-id-177'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyThreadState_Swap' mangled-name='PyThreadState_Swap' filepath='./Include/pystate.h' line='65' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThreadState_Swap'> + <parameter type-id='type-id-177'/> + <return type-id='type-id-177'/> + </function-decl> + <function-decl name='PyGILState_GetThisThreadState' mangled-name='PyGILState_GetThisThreadState' filepath='./Include/pystate.h' line='120' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyGILState_GetThisThreadState'> + <return type-id='type-id-177'/> + </function-decl> + <function-decl name='PyOS_mystrnicmp' mangled-name='PyOS_mystrnicmp' filepath='./Include/pystrcmp.h' line='8' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyOS_mystrnicmp'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-14'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyErr_PrintEx' mangled-name='PyErr_PrintEx' filepath='./Include/pythonrun.h' line='13' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_PrintEx'> + <parameter type-id='type-id-8'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyErr_DisplayException' mangled-name='PyErr_DisplayException' filepath='./Include/pythonrun.h' line='17' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_DisplayException'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PySys_SetObject' mangled-name='PySys_SetObject' filepath='./Include/sysmodule.h' line='11' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PySys_SetObject'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyUnstable_PerfMapState_Fini' mangled-name='PyUnstable_PerfMapState_Fini' filepath='./Include/sysmodule.h' line='42' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyUnstable_PerfMapState_Fini'> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyTraceMalloc_Start' mangled-name='_PyTraceMalloc_Start' filepath='./Include/tracemalloc.h' line='53' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTraceMalloc_Start'> + <parameter type-id='type-id-8'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='nl_langinfo' filepath='/usr/include/langinfo.h' line='661' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1489'/> + <return type-id='type-id-15'/> + </function-decl> + <function-decl name='sigemptyset' filepath='/usr/include/signal.h' line='199' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-45'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='sigaction' filepath='/usr/include/signal.h' line='243' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-1497'/> + <parameter type-id='type-id-1499'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='vfprintf' filepath='/usr/include/stdio.h' line='365' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-412'/> + <parameter type-id='type-id-181'/> + <parameter type-id='type-id-306'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='abort' filepath='/usr/include/stdlib.h' line='598' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='exit' filepath='/usr/include/stdlib.h' line='624' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='setenv' filepath='/usr/include/stdlib.h' line='660' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyRuntime_Finalize' mangled-name='_PyRuntime_Finalize' filepath='Python/pylifecycle.c' line='121' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyRuntime_Finalize'> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_Py_IsFinalizing' mangled-name='_Py_IsFinalizing' filepath='Python/pylifecycle.c' line='128' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_IsFinalizing'> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_Py_IsCoreInitialized' mangled-name='_Py_IsCoreInitialized' filepath='Python/pylifecycle.c' line='144' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_IsCoreInitialized'> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyInterpreterState_SetConfig' mangled-name='_PyInterpreterState_SetConfig' filepath='Python/pylifecycle.c' line='414' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyInterpreterState_SetConfig'> + <parameter type-id='type-id-260' name='src_config' filepath='Python/pylifecycle.c' line='414' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_Py_PreInitializeFromPyArgv' mangled-name='_Py_PreInitializeFromPyArgv' filepath='Python/pylifecycle.c' line='909' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_PreInitializeFromPyArgv'> + <parameter type-id='type-id-1436' name='src_config' filepath='Python/pylifecycle.c' line='909' column='1'/> + <parameter type-id='type-id-1439' name='args' filepath='Python/pylifecycle.c' line='909' column='1'/> + <return type-id='type-id-54'/> + </function-decl> + <function-decl name='Py_PreInitializeFromBytesArgs' mangled-name='Py_PreInitializeFromBytesArgs' filepath='Python/pylifecycle.c' line='956' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_PreInitializeFromBytesArgs'> + <parameter type-id='type-id-1436' name='src_config' filepath='Python/pylifecycle.c' line='956' column='1'/> + <parameter type-id='type-id-14' name='argc' filepath='Python/pylifecycle.c' line='956' column='1'/> + <parameter type-id='type-id-239' name='argv' filepath='Python/pylifecycle.c' line='956' column='1'/> + <return type-id='type-id-54'/> + </function-decl> + <function-decl name='Py_PreInitializeFromArgs' mangled-name='Py_PreInitializeFromArgs' filepath='Python/pylifecycle.c' line='964' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_PreInitializeFromArgs'> + <parameter type-id='type-id-1436' name='src_config' filepath='Python/pylifecycle.c' line='964' column='1'/> + <parameter type-id='type-id-14' name='argc' filepath='Python/pylifecycle.c' line='964' column='1'/> + <parameter type-id='type-id-235' name='argv' filepath='Python/pylifecycle.c' line='964' column='1'/> + <return type-id='type-id-54'/> + </function-decl> + <function-decl name='Py_PreInitialize' mangled-name='Py_PreInitialize' filepath='Python/pylifecycle.c' line='972' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_PreInitialize'> + <parameter type-id='type-id-1436' name='src_config' filepath='Python/pylifecycle.c' line='972' column='1'/> + <return type-id='type-id-54'/> + </function-decl> + <function-decl name='Py_InitializeEx' mangled-name='Py_InitializeEx' filepath='Python/pylifecycle.c' line='1274' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_InitializeEx'> + <parameter type-id='type-id-8' name='install_sigs' filepath='Python/pylifecycle.c' line='1274' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='Py_Initialize' mangled-name='Py_Initialize' filepath='Python/pylifecycle.c' line='1302' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_Initialize'> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_Py_InitializeMain' mangled-name='_Py_InitializeMain' filepath='Python/pylifecycle.c' line='1309' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_InitializeMain'> + <return type-id='type-id-54'/> + </function-decl> + <function-decl name='Py_Finalize' mangled-name='Py_Finalize' filepath='Python/pylifecycle.c' line='1984' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_Finalize'> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='Py_NewInterpreterFromConfig' mangled-name='Py_NewInterpreterFromConfig' filepath='Python/pylifecycle.c' line='2111' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_NewInterpreterFromConfig'> + <parameter type-id='type-id-1490' name='tstate_p' filepath='Python/pylifecycle.c' line='2111' column='1'/> + <parameter type-id='type-id-1492' name='config' filepath='Python/pylifecycle.c' line='2112' column='1'/> + <return type-id='type-id-54'/> + </function-decl> + <function-decl name='Py_NewInterpreter' mangled-name='Py_NewInterpreter' filepath='Python/pylifecycle.c' line='2118' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_NewInterpreter'> + <return type-id='type-id-177'/> + </function-decl> + <function-decl name='Py_EndInterpreter' mangled-name='Py_EndInterpreter' filepath='Python/pylifecycle.c' line='2142' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_EndInterpreter'> + <parameter type-id='type-id-177' name='tstate' filepath='Python/pylifecycle.c' line='2142' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_Py_DumpExtensionModules' mangled-name='_Py_DumpExtensionModules' filepath='Python/pylifecycle.c' line='2724' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_DumpExtensionModules'> + <parameter type-id='type-id-8' name='fd' filepath='Python/pylifecycle.c' line='2724' column='1'/> + <parameter type-id='type-id-20' name='interp' filepath='Python/pylifecycle.c' line='2724' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='Py_FatalError' mangled-name='Py_FatalError' filepath='Python/pylifecycle.c' line='2897' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_FatalError'> + <parameter type-id='type-id-12' name='msg' filepath='Python/pylifecycle.c' line='2897' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_Py_FatalRefcountErrorFunc' mangled-name='_Py_FatalRefcountErrorFunc' filepath='Python/pylifecycle.c' line='2941' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_FatalRefcountErrorFunc'> + <parameter type-id='type-id-12' name='func' filepath='Python/pylifecycle.c' line='2941' column='1'/> + <parameter type-id='type-id-12' name='msg' filepath='Python/pylifecycle.c' line='2941' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='Py_AtExit' mangled-name='Py_AtExit' filepath='Python/pylifecycle.c' line='2991' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_AtExit'> + <parameter type-id='type-id-227' name='func' filepath='Python/pylifecycle.c' line='2991' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='Py_Exit' mangled-name='Py_Exit' filepath='Python/pylifecycle.c' line='3028' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_Exit'> + <parameter type-id='type-id-8' name='sts' filepath='Python/pylifecycle.c' line='3028' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='Py_FdIsInteractive' mangled-name='Py_FdIsInteractive' filepath='Python/pylifecycle.c' line='3045' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_FdIsInteractive'> + <parameter type-id='type-id-229' name='fp' filepath='Python/pylifecycle.c' line='3045' column='1'/> + <parameter type-id='type-id-12' name='filename' filepath='Python/pylifecycle.c' line='3045' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_Py_FdIsInteractive' mangled-name='_Py_FdIsInteractive' filepath='Python/pylifecycle.c' line='3060' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_FdIsInteractive'> + <parameter type-id='type-id-229' name='fp' filepath='Python/pylifecycle.c' line='3060' column='1'/> + <parameter type-id='type-id-2' name='filename' filepath='Python/pylifecycle.c' line='3060' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyOS_getsig' mangled-name='PyOS_getsig' filepath='Python/pylifecycle.c' line='3077' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyOS_getsig'> + <parameter type-id='type-id-8' name='sig' filepath='Python/pylifecycle.c' line='3077' column='1'/> + <return type-id='type-id-1488'/> + </function-decl> + <function-decl name='PyOS_setsig' mangled-name='PyOS_setsig' filepath='Python/pylifecycle.c' line='3116' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyOS_setsig'> + <parameter type-id='type-id-8' name='sig' filepath='Python/pylifecycle.c' line='3116' column='1'/> + <parameter type-id='type-id-1488' name='handler' filepath='Python/pylifecycle.c' line='3116' column='1'/> + <return type-id='type-id-1488'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Python/pystate.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <pointer-type-def type-id='type-id-823' size-in-bits='64' id='type-id-1500'/> + <pointer-type-def type-id='type-id-854' size-in-bits='64' id='type-id-1501'/> + <qualified-type-def type-id='type-id-19' const='yes' id='type-id-1502'/> + <function-decl name='_PyEval_InitState' filepath='./Include/internal/pycore_ceval.h' line='24' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <parameter type-id='type-id-801'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyEval_FiniState' filepath='./Include/internal/pycore_ceval.h' line='25' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1500'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyEval_AcquireLock' filepath='./Include/internal/pycore_ceval.h' line='103' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-177'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyGC_InitState' filepath='./Include/internal/pycore_gc.h' line='193' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1501'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyImport_ClearCore' filepath='./Include/internal/pycore_import.h' line='108' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyType_InitCache' filepath='./Include/internal/pycore_object.h' line='153' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyObject_InitState' filepath='./Include/internal/pycore_object.h' line='155' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyObject_VirtualAlloc' filepath='./Include/internal/pycore_obmalloc.h' line='677' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-19'/> + <return type-id='type-id-22'/> + </function-decl> + <function-decl name='_PyObject_VirtualFree' filepath='./Include/internal/pycore_obmalloc.h' line='678' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-22'/> + <parameter type-id='type-id-19'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyInterpreterState_FinalizeAllocatedBlocks' filepath='./Include/internal/pycore_obmalloc.h' line='686' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyGC_Fini' filepath='./Include/internal/pycore_pylifecycle.h' line='55' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyWarnings_Fini' filepath='./Include/internal/pycore_pylifecycle.h' line='60' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyAST_Fini' filepath='./Include/internal/pycore_pylifecycle.h' line='61' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyAtExit_Fini' filepath='./Include/internal/pycore_pylifecycle.h' line='62' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <return type-id='type-id-46'/> + </function-decl> + <var-decl name='_Py_tss_tstate' type-id='type-id-177' visibility='default' filepath='./Include/internal/pycore_pystate.h' line='67' column='1'/> + <function-decl name='PyThread_get_thread_native_id' mangled-name='PyThread_get_thread_native_id' filepath='./Include/pythread.h' line='27' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThread_get_thread_native_id'> + <return type-id='type-id-28'/> + </function-decl> + <function-decl name='PyThread_tss_create' mangled-name='PyThread_tss_create' filepath='./Include/pythread.h' line='120' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThread_tss_create'> + <parameter type-id='type-id-409'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyThread_tss_delete' mangled-name='PyThread_tss_delete' filepath='./Include/pythread.h' line='121' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThread_tss_delete'> + <parameter type-id='type-id-409'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyThreadState_GetCurrent' mangled-name='_PyThreadState_GetCurrent' filepath='Python/pystate.c' line='108' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyThreadState_GetCurrent'> + <return type-id='type-id-177'/> + </function-decl> + <function-decl name='PyInterpreterState_Clear' mangled-name='PyInterpreterState_Clear' filepath='Python/pystate.c' line='921' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInterpreterState_Clear'> + <parameter type-id='type-id-20' name='interp' filepath='Python/pystate.c' line='921' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyInterpreterState_RequiresIDRef' mangled-name='_PyInterpreterState_RequiresIDRef' filepath='Python/pystate.c' line='1117' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyInterpreterState_RequiresIDRef'> + <parameter type-id='type-id-20' name='interp' filepath='Python/pystate.c' line='1117' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyInterpreterState_RequireIDRef' mangled-name='_PyInterpreterState_RequireIDRef' filepath='Python/pystate.c' line='1123' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyInterpreterState_RequireIDRef'> + <parameter type-id='type-id-20' name='interp' filepath='Python/pystate.c' line='1123' column='1'/> + <parameter type-id='type-id-8' name='required' filepath='Python/pystate.c' line='1123' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyInterpreterState_GetMainModule' mangled-name='_PyInterpreterState_GetMainModule' filepath='Python/pystate.c' line='1129' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyInterpreterState_GetMainModule'> + <parameter type-id='type-id-20' name='interp' filepath='Python/pystate.c' line='1129' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyInterpreterState_GetDict' mangled-name='PyInterpreterState_GetDict' filepath='Python/pystate.c' line='1140' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInterpreterState_GetDict'> + <parameter type-id='type-id-20' name='interp' filepath='Python/pystate.c' line='1140' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyThreadState_New' mangled-name='PyThreadState_New' filepath='Python/pystate.c' line='1382' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThreadState_New'> + <parameter type-id='type-id-20' name='interp' filepath='Python/pystate.c' line='1382' column='1'/> + <return type-id='type-id-177'/> + </function-decl> + <function-decl name='_PyThreadState_Prealloc' mangled-name='_PyThreadState_Prealloc' filepath='Python/pystate.c' line='1405' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyThreadState_Prealloc'> + <parameter type-id='type-id-20' name='interp' filepath='Python/pystate.c' line='1405' column='1'/> + <return type-id='type-id-177'/> + </function-decl> + <function-decl name='_PyThreadState_Init' mangled-name='_PyThreadState_Init' filepath='Python/pystate.c' line='1413' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyThreadState_Init'> + <parameter type-id='type-id-177' name='tstate' filepath='Python/pystate.c' line='1413' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyThreadState_DeleteCurrent' mangled-name='_PyThreadState_DeleteCurrent' filepath='Python/pystate.c' line='1575' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyThreadState_DeleteCurrent'> + <parameter type-id='type-id-177' name='tstate' filepath='Python/pystate.c' line='1575' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyThreadState_DeleteCurrent' mangled-name='PyThreadState_DeleteCurrent' filepath='Python/pystate.c' line='1585' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThreadState_DeleteCurrent'> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyThreadState_GetDict' mangled-name='_PyThreadState_GetDict' filepath='Python/pystate.c' line='1647' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyThreadState_GetDict'> + <parameter type-id='type-id-177' name='tstate' filepath='Python/pystate.c' line='1647' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyThreadState_GetInterpreter' mangled-name='PyThreadState_GetInterpreter' filepath='Python/pystate.c' line='1672' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThreadState_GetInterpreter'> + <parameter type-id='type-id-177' name='tstate' filepath='Python/pystate.c' line='1672' column='1'/> + <return type-id='type-id-20'/> + </function-decl> + <function-decl name='PyThreadState_GetID' mangled-name='PyThreadState_GetID' filepath='Python/pystate.c' line='1696' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThreadState_GetID'> + <parameter type-id='type-id-177' name='tstate' filepath='Python/pystate.c' line='1696' column='1'/> + <return type-id='type-id-117'/> + </function-decl> + <function-decl name='PyThreadState_SetAsyncExc' mangled-name='PyThreadState_SetAsyncExc' filepath='Python/pystate.c' line='1750' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThreadState_SetAsyncExc'> + <parameter type-id='type-id-28' name='id' filepath='Python/pystate.c' line='1750' column='1'/> + <parameter type-id='type-id-2' name='exc' filepath='Python/pystate.c' line='1750' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyThreadState_Swap' mangled-name='_PyThreadState_Swap' filepath='Python/pystate.c' line='1847' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyThreadState_Swap'> + <parameter type-id='type-id-178' name='runtime' filepath='Python/pystate.c' line='1847' column='1'/> + <parameter type-id='type-id-177' name='newts' filepath='Python/pystate.c' line='1847' column='1'/> + <return type-id='type-id-177'/> + </function-decl> + <function-decl name='PyInterpreterState_Main' mangled-name='PyInterpreterState_Main' filepath='Python/pystate.c' line='1893' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyInterpreterState_Main'> + <return type-id='type-id-20'/> + </function-decl> + <function-decl name='_PyThread_CurrentFrames' mangled-name='_PyThread_CurrentFrames' filepath='Python/pystate.c' line='1924' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyThread_CurrentFrames'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyThread_CurrentExceptions' mangled-name='_PyThread_CurrentExceptions' filepath='Python/pystate.c' line='1985' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyThread_CurrentExceptions'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyGILState_GetInterpreterStateUnsafe' mangled-name='_PyGILState_GetInterpreterStateUnsafe' filepath='Python/pystate.c' line='2103' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyGILState_GetInterpreterStateUnsafe'> + <return type-id='type-id-20'/> + </function-decl> + <function-decl name='_PyCrossInterpreterData_Init' mangled-name='_PyCrossInterpreterData_Init' filepath='Python/pystate.c' line='2266' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyCrossInterpreterData_Init'> + <parameter type-id='type-id-1059' name='data' filepath='Python/pystate.c' line='2266' column='1'/> + <parameter type-id='type-id-20' name='interp' filepath='Python/pystate.c' line='2267' column='1'/> + <parameter type-id='type-id-22' name='shared' filepath='Python/pystate.c' line='2268' column='1'/> + <parameter type-id='type-id-2' name='obj' filepath='Python/pystate.c' line='2268' column='1'/> + <parameter type-id='type-id-784' name='new_object' filepath='Python/pystate.c' line='2269' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyCrossInterpreterData_InitWithSize' mangled-name='_PyCrossInterpreterData_InitWithSize' filepath='Python/pystate.c' line='2288' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyCrossInterpreterData_InitWithSize'> + <parameter type-id='type-id-1059' name='data' filepath='Python/pystate.c' line='2288' column='1'/> + <parameter type-id='type-id-20' name='interp' filepath='Python/pystate.c' line='2289' column='1'/> + <parameter type-id='type-id-1502' name='size' filepath='Python/pystate.c' line='2290' column='1'/> + <parameter type-id='type-id-2' name='obj' filepath='Python/pystate.c' line='2290' column='1'/> + <parameter type-id='type-id-784' name='new_object' filepath='Python/pystate.c' line='2291' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyCrossInterpreterData_Clear' mangled-name='_PyCrossInterpreterData_Clear' filepath='Python/pystate.c' line='2307' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyCrossInterpreterData_Clear'> + <parameter type-id='type-id-20' name='interp' filepath='Python/pystate.c' line='2307' column='1'/> + <parameter type-id='type-id-1059' name='data' filepath='Python/pystate.c' line='2308' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyObject_CheckCrossInterpreterData' mangled-name='_PyObject_CheckCrossInterpreterData' filepath='Python/pystate.c' line='2353' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_CheckCrossInterpreterData'> + <parameter type-id='type-id-2' name='obj' filepath='Python/pystate.c' line='2353' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyObject_GetCrossInterpreterData' mangled-name='_PyObject_GetCrossInterpreterData' filepath='Python/pystate.c' line='2363' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyObject_GetCrossInterpreterData'> + <parameter type-id='type-id-2' name='obj' filepath='Python/pystate.c' line='2363' column='1'/> + <parameter type-id='type-id-1059' name='data' filepath='Python/pystate.c' line='2363' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyCrossInterpreterData_NewObject' mangled-name='_PyCrossInterpreterData_NewObject' filepath='Python/pystate.c' line='2401' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyCrossInterpreterData_NewObject'> + <parameter type-id='type-id-1059' name='data' filepath='Python/pystate.c' line='2401' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyCrossInterpreterData_Release' mangled-name='_PyCrossInterpreterData_Release' filepath='Python/pystate.c' line='2435' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyCrossInterpreterData_Release'> + <parameter type-id='type-id-1059' name='data' filepath='Python/pystate.c' line='2435' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyCrossInterpreterData_RegisterClass' mangled-name='_PyCrossInterpreterData_RegisterClass' filepath='Python/pystate.c' line='2536' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyCrossInterpreterData_RegisterClass'> + <parameter type-id='type-id-1' name='cls' filepath='Python/pystate.c' line='2536' column='1'/> + <parameter type-id='type-id-787' name='getdata' filepath='Python/pystate.c' line='2537' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyCrossInterpreterData_UnregisterClass' mangled-name='_PyCrossInterpreterData_UnregisterClass' filepath='Python/pystate.c' line='2559' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyCrossInterpreterData_UnregisterClass'> + <parameter type-id='type-id-1' name='cls' filepath='Python/pystate.c' line='2559' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyCrossInterpreterData_Lookup' mangled-name='_PyCrossInterpreterData_Lookup' filepath='Python/pystate.c' line='2579' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyCrossInterpreterData_Lookup'> + <parameter type-id='type-id-2' name='obj' filepath='Python/pystate.c' line='2579' column='1'/> + <return type-id='type-id-787'/> + </function-decl> + <function-decl name='_PyInterpreterState_GetEvalFrameFunc' mangled-name='_PyInterpreterState_GetEvalFrameFunc' filepath='Python/pystate.c' line='2728' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyInterpreterState_GetEvalFrameFunc'> + <parameter type-id='type-id-20' name='interp' filepath='Python/pystate.c' line='2728' column='1'/> + <return type-id='type-id-780'/> + </function-decl> + <function-decl name='_PyInterpreterState_SetEvalFrameFunc' mangled-name='_PyInterpreterState_SetEvalFrameFunc' filepath='Python/pystate.c' line='2738' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyInterpreterState_SetEvalFrameFunc'> + <parameter type-id='type-id-20' name='interp' filepath='Python/pystate.c' line='2738' column='1'/> + <parameter type-id='type-id-780' name='eval_frame' filepath='Python/pystate.c' line='2739' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyInterpreterState_GetConfigCopy' mangled-name='_PyInterpreterState_GetConfigCopy' filepath='Python/pystate.c' line='2758' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyInterpreterState_GetConfigCopy'> + <parameter type-id='type-id-53' name='config' filepath='Python/pystate.c' line='2758' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Python/pystrcmp.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <function-decl name='PyOS_mystricmp' mangled-name='PyOS_mystricmp' filepath='Python/pystrcmp.c' line='22' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyOS_mystricmp'> + <parameter type-id='type-id-12' name='s1' filepath='Python/pystrcmp.c' line='22' column='1'/> + <parameter type-id='type-id-12' name='s2' filepath='Python/pystrcmp.c' line='22' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Python/pystrhex.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <function-decl name='_Py_strhex' mangled-name='_Py_strhex' filepath='Python/pystrhex.c' line='148' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_strhex'> + <parameter type-id='type-id-12' name='argbuf' filepath='Python/pystrhex.c' line='148' column='1'/> + <parameter type-id='type-id-246' name='arglen' filepath='Python/pystrhex.c' line='148' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_Py_strhex_bytes' mangled-name='_Py_strhex_bytes' filepath='Python/pystrhex.c' line='155' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_strhex_bytes'> + <parameter type-id='type-id-12' name='argbuf' filepath='Python/pystrhex.c' line='155' column='1'/> + <parameter type-id='type-id-246' name='arglen' filepath='Python/pystrhex.c' line='155' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_Py_strhex_bytes_with_sep' mangled-name='_Py_strhex_bytes_with_sep' filepath='Python/pystrhex.c' line='170' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_strhex_bytes_with_sep'> + <parameter type-id='type-id-12' name='argbuf' filepath='Python/pystrhex.c' line='170' column='1'/> + <parameter type-id='type-id-246' name='arglen' filepath='Python/pystrhex.c' line='170' column='1'/> + <parameter type-id='type-id-2' name='sep' filepath='Python/pystrhex.c' line='171' column='1'/> + <parameter type-id='type-id-261' name='bytes_per_group' filepath='Python/pystrhex.c' line='171' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Python/pythonrun.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <function-decl name='PyAST_mod2obj' filepath='./Include/internal/pycore_ast.h' line='905' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-468'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyImport_GetImportlibExternalLoader' filepath='./Include/internal/pycore_import.h' line='131' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <parameter type-id='type-id-12'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyParser_ASTFromString' filepath='./Include/internal/pycore_parser.h' line='44' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-208'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-467'/> + </function-decl> + <function-decl name='_PyParser_ASTFromFile' filepath='./Include/internal/pycore_parser.h' line='51' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-229'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-208'/> + <parameter type-id='type-id-179'/> + <parameter type-id='type-id-563'/> + <return type-id='type-id-467'/> + </function-decl> + <function-decl name='_Py_Offer_Suggestions' filepath='./Include/internal/pycore_pyerrors.h' line='108' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyTraceBack_Print_Indented' mangled-name='_PyTraceBack_Print_Indented' filepath='./Include/internal/pycore_traceback.h' line='92' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTraceBack_Print_Indented'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_Py_WriteIndentedMargin' mangled-name='_Py_WriteIndentedMargin' filepath='./Include/internal/pycore_traceback.h' line='95' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_WriteIndentedMargin'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-12'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_Py_WriteIndent' mangled-name='_Py_WriteIndent' filepath='./Include/internal/pycore_traceback.h' line='96' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_WriteIndent'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='rewind' filepath='/usr/include/stdio.h' line='723' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-229'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyRun_AnyFileObject' mangled-name='_PyRun_AnyFileObject' filepath='Python/pythonrun.c' line='57' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyRun_AnyFileObject'> + <parameter type-id='type-id-229' name='fp' filepath='Python/pythonrun.c' line='57' column='1'/> + <parameter type-id='type-id-2' name='filename' filepath='Python/pythonrun.c' line='57' column='1'/> + <parameter type-id='type-id-8' name='closeit' filepath='Python/pythonrun.c' line='57' column='1'/> + <parameter type-id='type-id-208' name='flags' filepath='Python/pythonrun.c' line='58' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyRun_InteractiveLoopObject' mangled-name='_PyRun_InteractiveLoopObject' filepath='Python/pythonrun.c' line='111' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyRun_InteractiveLoopObject'> + <parameter type-id='type-id-229' name='fp' filepath='Python/pythonrun.c' line='111' column='1'/> + <parameter type-id='type-id-2' name='filename' filepath='Python/pythonrun.c' line='111' column='1'/> + <parameter type-id='type-id-208' name='flags' filepath='Python/pythonrun.c' line='111' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyRun_InteractiveLoopFlags' mangled-name='PyRun_InteractiveLoopFlags' filepath='Python/pythonrun.c' line='167' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyRun_InteractiveLoopFlags'> + <parameter type-id='type-id-229' name='fp' filepath='Python/pythonrun.c' line='167' column='1'/> + <parameter type-id='type-id-12' name='filename' filepath='Python/pythonrun.c' line='167' column='1'/> + <parameter type-id='type-id-208' name='flags' filepath='Python/pythonrun.c' line='167' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyRun_InteractiveOneObject' mangled-name='PyRun_InteractiveOneObject' filepath='Python/pythonrun.c' line='271' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyRun_InteractiveOneObject'> + <parameter type-id='type-id-229' name='fp' filepath='Python/pythonrun.c' line='271' column='1'/> + <parameter type-id='type-id-2' name='filename' filepath='Python/pythonrun.c' line='271' column='1'/> + <parameter type-id='type-id-208' name='flags' filepath='Python/pythonrun.c' line='271' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyRun_InteractiveOneFlags' mangled-name='PyRun_InteractiveOneFlags' filepath='Python/pythonrun.c' line='284' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyRun_InteractiveOneFlags'> + <parameter type-id='type-id-229' name='fp' filepath='Python/pythonrun.c' line='284' column='1'/> + <parameter type-id='type-id-12' name='filename_str' filepath='Python/pythonrun.c' line='284' column='1'/> + <parameter type-id='type-id-208' name='flags' filepath='Python/pythonrun.c' line='284' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyRun_SimpleFileObject' mangled-name='_PyRun_SimpleFileObject' filepath='Python/pythonrun.c' line='376' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyRun_SimpleFileObject'> + <parameter type-id='type-id-229' name='fp' filepath='Python/pythonrun.c' line='376' column='1'/> + <parameter type-id='type-id-2' name='filename' filepath='Python/pythonrun.c' line='376' column='1'/> + <parameter type-id='type-id-8' name='closeit' filepath='Python/pythonrun.c' line='376' column='1'/> + <parameter type-id='type-id-208' name='flags' filepath='Python/pythonrun.c' line='377' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyRun_SimpleFileExFlags' mangled-name='PyRun_SimpleFileExFlags' filepath='Python/pythonrun.c' line='459' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyRun_SimpleFileExFlags'> + <parameter type-id='type-id-229' name='fp' filepath='Python/pythonrun.c' line='459' column='1'/> + <parameter type-id='type-id-12' name='filename' filepath='Python/pythonrun.c' line='459' column='1'/> + <parameter type-id='type-id-8' name='closeit' filepath='Python/pythonrun.c' line='459' column='1'/> + <parameter type-id='type-id-208' name='flags' filepath='Python/pythonrun.c' line='460' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyRun_SimpleStringFlags' mangled-name='PyRun_SimpleStringFlags' filepath='Python/pythonrun.c' line='473' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyRun_SimpleStringFlags'> + <parameter type-id='type-id-12' name='command' filepath='Python/pythonrun.c' line='473' column='1'/> + <parameter type-id='type-id-208' name='flags' filepath='Python/pythonrun.c' line='473' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_Py_HandleSystemExit' mangled-name='_Py_HandleSystemExit' filepath='Python/pythonrun.c' line='688' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_HandleSystemExit'> + <parameter type-id='type-id-179' name='exitcode_p' filepath='Python/pythonrun.c' line='688' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyErr_Display' mangled-name='_PyErr_Display' filepath='Python/pythonrun.c' line='1496' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyErr_Display'> + <parameter type-id='type-id-2' name='file' filepath='Python/pythonrun.c' line='1496' column='1'/> + <parameter type-id='type-id-2' name='unused' filepath='Python/pythonrun.c' line='1496' column='1'/> + <parameter type-id='type-id-2' name='value' filepath='Python/pythonrun.c' line='1496' column='1'/> + <parameter type-id='type-id-2' name='tb' filepath='Python/pythonrun.c' line='1496' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyErr_Display' mangled-name='PyErr_Display' filepath='Python/pythonrun.c' line='1545' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyErr_Display'> + <parameter type-id='type-id-2' name='unused' filepath='Python/pythonrun.c' line='1545' column='1'/> + <parameter type-id='type-id-2' name='value' filepath='Python/pythonrun.c' line='1545' column='1'/> + <parameter type-id='type-id-2' name='tb' filepath='Python/pythonrun.c' line='1545' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyErr_DisplayException' mangled-name='_PyErr_DisplayException' filepath='Python/pythonrun.c' line='1562' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyErr_DisplayException'> + <parameter type-id='type-id-2' name='file' filepath='Python/pythonrun.c' line='1562' column='1'/> + <parameter type-id='type-id-2' name='exc' filepath='Python/pythonrun.c' line='1562' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyRun_FileExFlags' mangled-name='PyRun_FileExFlags' filepath='Python/pythonrun.c' line='1626' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyRun_FileExFlags'> + <parameter type-id='type-id-229' name='fp' filepath='Python/pythonrun.c' line='1626' column='1'/> + <parameter type-id='type-id-12' name='filename' filepath='Python/pythonrun.c' line='1626' column='1'/> + <parameter type-id='type-id-8' name='start' filepath='Python/pythonrun.c' line='1626' column='1'/> + <parameter type-id='type-id-2' name='globals' filepath='Python/pythonrun.c' line='1626' column='1'/> + <parameter type-id='type-id-2' name='locals' filepath='Python/pythonrun.c' line='1627' column='1'/> + <parameter type-id='type-id-8' name='closeit' filepath='Python/pythonrun.c' line='1627' column='1'/> + <parameter type-id='type-id-208' name='flags' filepath='Python/pythonrun.c' line='1627' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='Py_CompileStringExFlags' mangled-name='Py_CompileStringExFlags' filepath='Python/pythonrun.c' line='1788' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_CompileStringExFlags'> + <parameter type-id='type-id-12' name='str' filepath='Python/pythonrun.c' line='1788' column='1'/> + <parameter type-id='type-id-12' name='filename_str' filepath='Python/pythonrun.c' line='1788' column='1'/> + <parameter type-id='type-id-8' name='start' filepath='Python/pythonrun.c' line='1788' column='1'/> + <parameter type-id='type-id-208' name='flags' filepath='Python/pythonrun.c' line='1789' column='1'/> + <parameter type-id='type-id-8' name='optimize' filepath='Python/pythonrun.c' line='1789' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyRun_AnyFile' mangled-name='PyRun_AnyFile' filepath='Python/pythonrun.c' line='1890' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyRun_AnyFile'> + <parameter type-id='type-id-229' name='fp' filepath='Python/pythonrun.c' line='1890' column='1'/> + <parameter type-id='type-id-12' name='name' filepath='Python/pythonrun.c' line='1890' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyRun_AnyFileEx' mangled-name='PyRun_AnyFileEx' filepath='Python/pythonrun.c' line='1897' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyRun_AnyFileEx'> + <parameter type-id='type-id-229' name='fp' filepath='Python/pythonrun.c' line='1897' column='1'/> + <parameter type-id='type-id-12' name='name' filepath='Python/pythonrun.c' line='1897' column='1'/> + <parameter type-id='type-id-8' name='closeit' filepath='Python/pythonrun.c' line='1897' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyRun_AnyFileFlags' mangled-name='PyRun_AnyFileFlags' filepath='Python/pythonrun.c' line='1904' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyRun_AnyFileFlags'> + <parameter type-id='type-id-229' name='fp' filepath='Python/pythonrun.c' line='1904' column='1'/> + <parameter type-id='type-id-12' name='name' filepath='Python/pythonrun.c' line='1904' column='1'/> + <parameter type-id='type-id-208' name='flags' filepath='Python/pythonrun.c' line='1904' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyRun_File' mangled-name='PyRun_File' filepath='Python/pythonrun.c' line='1911' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyRun_File'> + <parameter type-id='type-id-229' name='fp' filepath='Python/pythonrun.c' line='1911' column='1'/> + <parameter type-id='type-id-12' name='p' filepath='Python/pythonrun.c' line='1911' column='1'/> + <parameter type-id='type-id-8' name='s' filepath='Python/pythonrun.c' line='1911' column='1'/> + <parameter type-id='type-id-2' name='g' filepath='Python/pythonrun.c' line='1911' column='1'/> + <parameter type-id='type-id-2' name='l' filepath='Python/pythonrun.c' line='1911' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyRun_FileEx' mangled-name='PyRun_FileEx' filepath='Python/pythonrun.c' line='1918' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyRun_FileEx'> + <parameter type-id='type-id-229' name='fp' filepath='Python/pythonrun.c' line='1918' column='1'/> + <parameter type-id='type-id-12' name='p' filepath='Python/pythonrun.c' line='1918' column='1'/> + <parameter type-id='type-id-8' name='s' filepath='Python/pythonrun.c' line='1918' column='1'/> + <parameter type-id='type-id-2' name='g' filepath='Python/pythonrun.c' line='1918' column='1'/> + <parameter type-id='type-id-2' name='l' filepath='Python/pythonrun.c' line='1918' column='1'/> + <parameter type-id='type-id-8' name='c' filepath='Python/pythonrun.c' line='1918' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyRun_FileFlags' mangled-name='PyRun_FileFlags' filepath='Python/pythonrun.c' line='1925' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyRun_FileFlags'> + <parameter type-id='type-id-229' name='fp' filepath='Python/pythonrun.c' line='1925' column='1'/> + <parameter type-id='type-id-12' name='p' filepath='Python/pythonrun.c' line='1925' column='1'/> + <parameter type-id='type-id-8' name='s' filepath='Python/pythonrun.c' line='1925' column='1'/> + <parameter type-id='type-id-2' name='g' filepath='Python/pythonrun.c' line='1925' column='1'/> + <parameter type-id='type-id-2' name='l' filepath='Python/pythonrun.c' line='1925' column='1'/> + <parameter type-id='type-id-208' name='flags' filepath='Python/pythonrun.c' line='1926' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyRun_SimpleFile' mangled-name='PyRun_SimpleFile' filepath='Python/pythonrun.c' line='1933' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyRun_SimpleFile'> + <parameter type-id='type-id-229' name='f' filepath='Python/pythonrun.c' line='1933' column='1'/> + <parameter type-id='type-id-12' name='p' filepath='Python/pythonrun.c' line='1933' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyRun_SimpleFileEx' mangled-name='PyRun_SimpleFileEx' filepath='Python/pythonrun.c' line='1940' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyRun_SimpleFileEx'> + <parameter type-id='type-id-229' name='f' filepath='Python/pythonrun.c' line='1940' column='1'/> + <parameter type-id='type-id-12' name='p' filepath='Python/pythonrun.c' line='1940' column='1'/> + <parameter type-id='type-id-8' name='c' filepath='Python/pythonrun.c' line='1940' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyRun_String' mangled-name='PyRun_String' filepath='Python/pythonrun.c' line='1948' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyRun_String'> + <parameter type-id='type-id-12' name='str' filepath='Python/pythonrun.c' line='1948' column='1'/> + <parameter type-id='type-id-8' name='s' filepath='Python/pythonrun.c' line='1948' column='1'/> + <parameter type-id='type-id-2' name='g' filepath='Python/pythonrun.c' line='1948' column='1'/> + <parameter type-id='type-id-2' name='l' filepath='Python/pythonrun.c' line='1948' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyRun_SimpleString' mangled-name='PyRun_SimpleString' filepath='Python/pythonrun.c' line='1955' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyRun_SimpleString'> + <parameter type-id='type-id-12' name='s' filepath='Python/pythonrun.c' line='1955' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='Py_CompileString' mangled-name='Py_CompileString' filepath='Python/pythonrun.c' line='1962' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_CompileString'> + <parameter type-id='type-id-12' name='str' filepath='Python/pythonrun.c' line='1962' column='1'/> + <parameter type-id='type-id-12' name='p' filepath='Python/pythonrun.c' line='1962' column='1'/> + <parameter type-id='type-id-8' name='s' filepath='Python/pythonrun.c' line='1962' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='Py_CompileStringFlags' mangled-name='Py_CompileStringFlags' filepath='Python/pythonrun.c' line='1969' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='Py_CompileStringFlags'> + <parameter type-id='type-id-12' name='str' filepath='Python/pythonrun.c' line='1969' column='1'/> + <parameter type-id='type-id-12' name='p' filepath='Python/pythonrun.c' line='1969' column='1'/> + <parameter type-id='type-id-8' name='s' filepath='Python/pythonrun.c' line='1969' column='1'/> + <parameter type-id='type-id-208' name='flags' filepath='Python/pythonrun.c' line='1970' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='PyRun_InteractiveOne' mangled-name='PyRun_InteractiveOne' filepath='Python/pythonrun.c' line='1977' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyRun_InteractiveOne'> + <parameter type-id='type-id-229' name='f' filepath='Python/pythonrun.c' line='1977' column='1'/> + <parameter type-id='type-id-12' name='p' filepath='Python/pythonrun.c' line='1977' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyRun_InteractiveLoop' mangled-name='PyRun_InteractiveLoop' filepath='Python/pythonrun.c' line='1984' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyRun_InteractiveLoop'> + <parameter type-id='type-id-229' name='f' filepath='Python/pythonrun.c' line='1984' column='1'/> + <parameter type-id='type-id-12' name='p' filepath='Python/pythonrun.c' line='1984' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Python/pytime.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <class-decl name='_Py_clock_info_t' size-in-bits='192' is-struct='yes' naming-typedef-id='type-id-1503' visibility='default' filepath='./Include/cpython/pytime.h' line='240' column='1' id='type-id-1504'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='implementation' type-id='type-id-12' visibility='default' filepath='./Include/cpython/pytime.h' line='241' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='monotonic' type-id='type-id-8' visibility='default' filepath='./Include/cpython/pytime.h' line='242' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='96'> + <var-decl name='adjustable' type-id='type-id-8' visibility='default' filepath='./Include/cpython/pytime.h' line='243' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='resolution' type-id='type-id-251' visibility='default' filepath='./Include/cpython/pytime.h' line='244' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='_Py_clock_info_t' type-id='type-id-1504' filepath='./Include/cpython/pytime.h' line='245' column='1' id='type-id-1503'/> + <typedef-decl name='__suseconds_t' type-id='type-id-47' filepath='/usr/include/x86_64-linux-gnu/bits/types.h' line='162' column='1' id='type-id-1505'/> + <typedef-decl name='__clockid_t' type-id='type-id-8' filepath='/usr/include/x86_64-linux-gnu/bits/types.h' line='169' column='1' id='type-id-212'/> + <typedef-decl name='clockid_t' type-id='type-id-212' filepath='/usr/include/x86_64-linux-gnu/bits/types/clockid_t.h' line='7' column='1' id='type-id-221'/> + <class-decl name='timeval' size-in-bits='128' is-struct='yes' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h' line='8' column='1' id='type-id-101'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='tv_sec' type-id='type-id-1343' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h' line='14' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='tv_usec' type-id='type-id-1505' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h' line='15' column='1'/> + </data-member> + </class-decl> + <class-decl name='tm' size-in-bits='448' is-struct='yes' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_tm.h' line='7' column='1' id='type-id-214'> + <data-member access='public' layout-offset-in-bits='0'> + <var-decl name='tm_sec' type-id='type-id-8' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_tm.h' line='9' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='32'> + <var-decl name='tm_min' type-id='type-id-8' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_tm.h' line='10' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='64'> + <var-decl name='tm_hour' type-id='type-id-8' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_tm.h' line='11' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='96'> + <var-decl name='tm_mday' type-id='type-id-8' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_tm.h' line='12' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='128'> + <var-decl name='tm_mon' type-id='type-id-8' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_tm.h' line='13' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='160'> + <var-decl name='tm_year' type-id='type-id-8' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_tm.h' line='14' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='192'> + <var-decl name='tm_wday' type-id='type-id-8' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_tm.h' line='15' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='224'> + <var-decl name='tm_yday' type-id='type-id-8' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_tm.h' line='16' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='256'> + <var-decl name='tm_isdst' type-id='type-id-8' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_tm.h' line='17' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='320'> + <var-decl name='tm_gmtoff' type-id='type-id-47' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_tm.h' line='20' column='1'/> + </data-member> + <data-member access='public' layout-offset-in-bits='384'> + <var-decl name='tm_zone' type-id='type-id-12' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/types/struct_tm.h' line='21' column='1'/> + </data-member> + </class-decl> + <typedef-decl name='time_t' type-id='type-id-1343' filepath='/usr/include/x86_64-linux-gnu/bits/types/time_t.h' line='10' column='1' id='type-id-219'/> + <pointer-type-def type-id='type-id-790' size-in-bits='64' id='type-id-1506'/> + <pointer-type-def type-id='type-id-1503' size-in-bits='64' id='type-id-1507'/> + <qualified-type-def type-id='type-id-219' const='yes' id='type-id-1508'/> + <pointer-type-def type-id='type-id-1508' size-in-bits='64' id='type-id-1509'/> + <qualified-type-def type-id='type-id-1509' restrict='yes' id='type-id-1510'/> + <pointer-type-def type-id='type-id-47' size-in-bits='64' id='type-id-1511'/> + <pointer-type-def type-id='type-id-219' size-in-bits='64' id='type-id-218'/> + <pointer-type-def type-id='type-id-101' size-in-bits='64' id='type-id-1512'/> + <pointer-type-def type-id='type-id-214' size-in-bits='64' id='type-id-220'/> + <qualified-type-def type-id='type-id-220' restrict='yes' id='type-id-1513'/> + <function-decl name='gmtime_r' filepath='/usr/include/time.h' line='154' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1510'/> + <parameter type-id='type-id-1513'/> + <return type-id='type-id-220'/> + </function-decl> + <function-decl name='localtime_r' filepath='/usr/include/time.h' line='159' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1510'/> + <parameter type-id='type-id-1513'/> + <return type-id='type-id-220'/> + </function-decl> + <function-decl name='clock_getres' filepath='/usr/include/time.h' line='276' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-221'/> + <parameter type-id='type-id-180'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='clock_gettime' filepath='/usr/include/time.h' line='279' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-221'/> + <parameter type-id='type-id-180'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyTime_Add' mangled-name='_PyTime_Add' filepath='Python/pytime.c' line='104' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTime_Add'> + <parameter type-id='type-id-790' name='t1' filepath='Python/pytime.c' line='104' column='1'/> + <parameter type-id='type-id-790' name='t2' filepath='Python/pytime.c' line='104' column='1'/> + <return type-id='type-id-790'/> + </function-decl> + <function-decl name='_PyTime_MulDiv' mangled-name='_PyTime_MulDiv' filepath='Python/pytime.c' line='152' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTime_MulDiv'> + <parameter type-id='type-id-790' name='ticks' filepath='Python/pytime.c' line='152' column='1'/> + <parameter type-id='type-id-790' name='mul' filepath='Python/pytime.c' line='152' column='1'/> + <parameter type-id='type-id-790' name='div' filepath='Python/pytime.c' line='152' column='1'/> + <return type-id='type-id-790'/> + </function-decl> + <function-decl name='_PyLong_AsTime_t' mangled-name='_PyLong_AsTime_t' filepath='Python/pytime.c' line='169' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyLong_AsTime_t'> + <parameter type-id='type-id-2' name='obj' filepath='Python/pytime.c' line='169' column='1'/> + <return type-id='type-id-219'/> + </function-decl> + <function-decl name='_PyLong_FromTime_t' mangled-name='_PyLong_FromTime_t' filepath='Python/pytime.c' line='189' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyLong_FromTime_t'> + <parameter type-id='type-id-219' name='t' filepath='Python/pytime.c' line='189' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyTime_ObjectToTime_t' mangled-name='_PyTime_ObjectToTime_t' filepath='Python/pytime.c' line='357' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTime_ObjectToTime_t'> + <parameter type-id='type-id-2' name='obj' filepath='Python/pytime.c' line='357' column='1'/> + <parameter type-id='type-id-218' name='sec' filepath='Python/pytime.c' line='357' column='1'/> + <parameter type-id='type-id-1425' name='round' filepath='Python/pytime.c' line='357' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyTime_ObjectToTimespec' mangled-name='_PyTime_ObjectToTimespec' filepath='Python/pytime.c' line='392' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTime_ObjectToTimespec'> + <parameter type-id='type-id-2' name='obj' filepath='Python/pytime.c' line='392' column='1'/> + <parameter type-id='type-id-218' name='sec' filepath='Python/pytime.c' line='392' column='1'/> + <parameter type-id='type-id-1511' name='nsec' filepath='Python/pytime.c' line='392' column='1'/> + <parameter type-id='type-id-1425' name='round' filepath='Python/pytime.c' line='393' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyTime_ObjectToTimeval' mangled-name='_PyTime_ObjectToTimeval' filepath='Python/pytime.c' line='400' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTime_ObjectToTimeval'> + <parameter type-id='type-id-2' name='obj' filepath='Python/pytime.c' line='400' column='1'/> + <parameter type-id='type-id-218' name='sec' filepath='Python/pytime.c' line='400' column='1'/> + <parameter type-id='type-id-1511' name='usec' filepath='Python/pytime.c' line='400' column='1'/> + <parameter type-id='type-id-1425' name='round' filepath='Python/pytime.c' line='401' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyTime_FromSeconds' mangled-name='_PyTime_FromSeconds' filepath='Python/pytime.c' line='408' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTime_FromSeconds'> + <parameter type-id='type-id-8' name='seconds' filepath='Python/pytime.c' line='408' column='1'/> + <return type-id='type-id-790'/> + </function-decl> + <function-decl name='_PyTime_FromNanoseconds' mangled-name='_PyTime_FromNanoseconds' filepath='Python/pytime.c' line='425' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTime_FromNanoseconds'> + <parameter type-id='type-id-790' name='ns' filepath='Python/pytime.c' line='425' column='1'/> + <return type-id='type-id-790'/> + </function-decl> + <function-decl name='_PyTime_FromMicrosecondsClamp' mangled-name='_PyTime_FromMicrosecondsClamp' filepath='Python/pytime.c' line='432' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTime_FromMicrosecondsClamp'> + <parameter type-id='type-id-790' name='us' filepath='Python/pytime.c' line='432' column='1'/> + <return type-id='type-id-790'/> + </function-decl> + <function-decl name='_PyTime_FromNanosecondsObject' mangled-name='_PyTime_FromNanosecondsObject' filepath='Python/pytime.c' line='440' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTime_FromNanosecondsObject'> + <parameter type-id='type-id-1506' name='tp' filepath='Python/pytime.c' line='440' column='1'/> + <parameter type-id='type-id-2' name='obj' filepath='Python/pytime.c' line='440' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyTime_FromTimespec' mangled-name='_PyTime_FromTimespec' filepath='Python/pytime.c' line='490' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTime_FromTimespec'> + <parameter type-id='type-id-1506' name='tp' filepath='Python/pytime.c' line='490' column='1'/> + <parameter type-id='type-id-180' name='ts' filepath='Python/pytime.c' line='490' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyTime_FromTimeval' mangled-name='_PyTime_FromTimeval' filepath='Python/pytime.c' line='521' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTime_FromTimeval'> + <parameter type-id='type-id-1506' name='tp' filepath='Python/pytime.c' line='521' column='1'/> + <parameter type-id='type-id-1512' name='tv' filepath='Python/pytime.c' line='521' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyTime_FromSecondsObject' mangled-name='_PyTime_FromSecondsObject' filepath='Python/pytime.c' line='589' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTime_FromSecondsObject'> + <parameter type-id='type-id-1506' name='tp' filepath='Python/pytime.c' line='589' column='1'/> + <parameter type-id='type-id-2' name='obj' filepath='Python/pytime.c' line='589' column='1'/> + <parameter type-id='type-id-1425' name='round' filepath='Python/pytime.c' line='589' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyTime_FromMillisecondsObject' mangled-name='_PyTime_FromMillisecondsObject' filepath='Python/pytime.c' line='596' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTime_FromMillisecondsObject'> + <parameter type-id='type-id-1506' name='tp' filepath='Python/pytime.c' line='596' column='1'/> + <parameter type-id='type-id-2' name='obj' filepath='Python/pytime.c' line='596' column='1'/> + <parameter type-id='type-id-1425' name='round' filepath='Python/pytime.c' line='596' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyTime_AsSecondsDouble' mangled-name='_PyTime_AsSecondsDouble' filepath='Python/pytime.c' line='603' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTime_AsSecondsDouble'> + <parameter type-id='type-id-790' name='t' filepath='Python/pytime.c' line='603' column='1'/> + <return type-id='type-id-251'/> + </function-decl> + <function-decl name='_PyTime_AsNanosecondsObject' mangled-name='_PyTime_AsNanosecondsObject' filepath='Python/pytime.c' line='624' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTime_AsNanosecondsObject'> + <parameter type-id='type-id-790' name='t' filepath='Python/pytime.c' line='624' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyTime_AsNanoseconds' mangled-name='_PyTime_AsNanoseconds' filepath='Python/pytime.c' line='729' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTime_AsNanoseconds'> + <parameter type-id='type-id-790' name='t' filepath='Python/pytime.c' line='729' column='1'/> + <return type-id='type-id-790'/> + </function-decl> + <function-decl name='_PyTime_AsMilliseconds' mangled-name='_PyTime_AsMilliseconds' filepath='Python/pytime.c' line='754' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTime_AsMilliseconds'> + <parameter type-id='type-id-790' name='t' filepath='Python/pytime.c' line='754' column='1'/> + <parameter type-id='type-id-1425' name='round' filepath='Python/pytime.c' line='754' column='1'/> + <return type-id='type-id-790'/> + </function-decl> + <function-decl name='_PyTime_AsTimeval' mangled-name='_PyTime_AsTimeval' filepath='Python/pytime.c' line='804' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTime_AsTimeval'> + <parameter type-id='type-id-790' name='t' filepath='Python/pytime.c' line='804' column='1'/> + <parameter type-id='type-id-1512' name='tv' filepath='Python/pytime.c' line='804' column='1'/> + <parameter type-id='type-id-1425' name='round' filepath='Python/pytime.c' line='804' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyTime_AsTimeval_clamp' mangled-name='_PyTime_AsTimeval_clamp' filepath='Python/pytime.c' line='811' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTime_AsTimeval_clamp'> + <parameter type-id='type-id-790' name='t' filepath='Python/pytime.c' line='811' column='1'/> + <parameter type-id='type-id-1512' name='tv' filepath='Python/pytime.c' line='811' column='1'/> + <parameter type-id='type-id-1425' name='round' filepath='Python/pytime.c' line='811' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyTime_AsTimevalTime_t' mangled-name='_PyTime_AsTimevalTime_t' filepath='Python/pytime.c' line='818' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTime_AsTimevalTime_t'> + <parameter type-id='type-id-790' name='t' filepath='Python/pytime.c' line='818' column='1'/> + <parameter type-id='type-id-218' name='p_secs' filepath='Python/pytime.c' line='818' column='1'/> + <parameter type-id='type-id-179' name='us' filepath='Python/pytime.c' line='818' column='1'/> + <parameter type-id='type-id-1425' name='round' filepath='Python/pytime.c' line='819' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyTime_AsTimespec_clamp' mangled-name='_PyTime_AsTimespec_clamp' filepath='Python/pytime.c' line='857' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTime_AsTimespec_clamp'> + <parameter type-id='type-id-790' name='t' filepath='Python/pytime.c' line='857' column='1'/> + <parameter type-id='type-id-180' name='ts' filepath='Python/pytime.c' line='857' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyTime_AsTimespec' mangled-name='_PyTime_AsTimespec' filepath='Python/pytime.c' line='863' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTime_AsTimespec'> + <parameter type-id='type-id-790' name='t' filepath='Python/pytime.c' line='863' column='1'/> + <parameter type-id='type-id-180' name='ts' filepath='Python/pytime.c' line='863' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyTime_GetSystemClock' mangled-name='_PyTime_GetSystemClock' filepath='Python/pytime.c' line='982' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTime_GetSystemClock'> + <return type-id='type-id-790'/> + </function-decl> + <function-decl name='_PyTime_GetSystemClockWithInfo' mangled-name='_PyTime_GetSystemClockWithInfo' filepath='Python/pytime.c' line='995' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTime_GetSystemClockWithInfo'> + <parameter type-id='type-id-1506' name='t' filepath='Python/pytime.c' line='995' column='1'/> + <parameter type-id='type-id-1507' name='info' filepath='Python/pytime.c' line='995' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyTime_GetMonotonicClock' mangled-name='_PyTime_GetMonotonicClock' filepath='Python/pytime.c' line='1179' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTime_GetMonotonicClock'> + <return type-id='type-id-790'/> + </function-decl> + <function-decl name='_PyTime_GetMonotonicClockWithInfo' mangled-name='_PyTime_GetMonotonicClockWithInfo' filepath='Python/pytime.c' line='1192' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTime_GetMonotonicClockWithInfo'> + <parameter type-id='type-id-1506' name='tp' filepath='Python/pytime.c' line='1192' column='1'/> + <parameter type-id='type-id-1507' name='info' filepath='Python/pytime.c' line='1192' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyTime_GetPerfCounterWithInfo' mangled-name='_PyTime_GetPerfCounterWithInfo' filepath='Python/pytime.c' line='1273' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTime_GetPerfCounterWithInfo'> + <parameter type-id='type-id-1506' name='t' filepath='Python/pytime.c' line='1273' column='1'/> + <parameter type-id='type-id-1507' name='info' filepath='Python/pytime.c' line='1273' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyTime_localtime' mangled-name='_PyTime_localtime' filepath='Python/pytime.c' line='1303' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTime_localtime'> + <parameter type-id='type-id-219' name='t' filepath='Python/pytime.c' line='1303' column='1'/> + <parameter type-id='type-id-220' name='tm' filepath='Python/pytime.c' line='1303' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyTime_gmtime' mangled-name='_PyTime_gmtime' filepath='Python/pytime.c' line='1342' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTime_gmtime'> + <parameter type-id='type-id-219' name='t' filepath='Python/pytime.c' line='1342' column='1'/> + <parameter type-id='type-id-220' name='tm' filepath='Python/pytime.c' line='1342' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyDeadline_Init' mangled-name='_PyDeadline_Init' filepath='Python/pytime.c' line='1370' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyDeadline_Init'> + <parameter type-id='type-id-790' name='timeout' filepath='Python/pytime.c' line='1370' column='1'/> + <return type-id='type-id-790'/> + </function-decl> + <function-decl name='_PyDeadline_Get' mangled-name='_PyDeadline_Get' filepath='Python/pytime.c' line='1378' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyDeadline_Get'> + <parameter type-id='type-id-790' name='deadline' filepath='Python/pytime.c' line='1378' column='1'/> + <return type-id='type-id-790'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Python/specialize.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <function-decl name='_PyDictKeys_GetVersionForCurrentState' filepath='./Include/internal/pycore_dict.h' line='40' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-20'/> + <parameter type-id='type-id-346'/> + <return type-id='type-id-352'/> + </function-decl> + <function-decl name='_PyDict_LookupIndex' filepath='./Include/internal/pycore_dict.h' line='50' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-340'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-14'/> + </function-decl> + <function-decl name='_PyDictKeys_StringLookup' filepath='./Include/internal/pycore_dict.h' line='51' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-346'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-14'/> + </function-decl> + <function-decl name='_PyFunction_GetVersionForCurrentState' filepath='./Include/internal/pycore_function.h' line='19' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-310'/> + <return type-id='type-id-352'/> + </function-decl> + <function-decl name='_Py_slot_tp_getattro' filepath='./Include/internal/pycore_typeobject.h' line='136' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_Py_slot_tp_getattr_hook' filepath='./Include/internal/pycore_typeobject.h' line='137' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-2'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Python/suggestions.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <function-decl name='_PyCode_GetVarnames' filepath='./Include/internal/pycore_code.h' line='206' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-328'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_Py_UTF8_Edit_Cost' mangled-name='_Py_UTF8_Edit_Cost' filepath='Python/suggestions.c' line='404' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_UTF8_Edit_Cost'> + <parameter type-id='type-id-2' name='a' filepath='Python/suggestions.c' line='404' column='1'/> + <parameter type-id='type-id-2' name='b' filepath='Python/suggestions.c' line='404' column='1'/> + <parameter type-id='type-id-14' name='max_cost' filepath='Python/suggestions.c' line='404' column='1'/> + <return type-id='type-id-14'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Python/symtable.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <var-decl name='PySTEntry_Type' type-id='type-id-256' visibility='default' filepath='./Include/internal/pycore_symtable.h' line='92' column='1'/> + </abi-instr> + <abi-instr address-size='64' path='Python/thread.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <array-type-def dimensions='1' type-id='type-id-48' size-in-bits='256' id='type-id-1514'> + <subrange length='32' type-id='type-id-28' id='type-id-60'/> + </array-type-def> + <array-type-def dimensions='1' type-id='type-id-48' size-in-bits='448' id='type-id-1515'> + <subrange length='56' type-id='type-id-28' id='type-id-1516'/> + </array-type-def> + <enum-decl name='PyLockStatus' filepath='./Include/pythread.h' line='12' column='1' id='type-id-1517'> + <underlying-type type-id='type-id-24'/> + <enumerator name='PY_LOCK_FAILURE' value='0'/> + <enumerator name='PY_LOCK_ACQUIRED' value='1'/> + <enumerator name='PY_LOCK_INTR' value='2'/> + </enum-decl> + <typedef-decl name='PyLockStatus' type-id='type-id-1517' filepath='./Include/pythread.h' line='16' column='1' id='type-id-1518'/> + <typedef-decl name='pthread_t' type-id='type-id-28' filepath='/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h' line='27' column='1' id='type-id-207'/> + <union-decl name='pthread_attr_t' size-in-bits='448' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h' line='56' column='1' id='type-id-1519'> + <data-member access='public'> + <var-decl name='__size' type-id='type-id-1515' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h' line='58' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='__align' type-id='type-id-47' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h' line='59' column='1'/> + </data-member> + </union-decl> + <typedef-decl name='pthread_attr_t' type-id='type-id-1519' filepath='/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h' line='62' column='1' id='type-id-1520'/> + <union-decl name='sem_t' size-in-bits='256' naming-typedef-id='type-id-1521' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/semaphore.h' line='35' column='1' id='type-id-1522'> + <data-member access='public'> + <var-decl name='__size' type-id='type-id-1514' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/semaphore.h' line='37' column='1'/> + </data-member> + <data-member access='public'> + <var-decl name='__align' type-id='type-id-47' visibility='default' filepath='/usr/include/x86_64-linux-gnu/bits/semaphore.h' line='38' column='1'/> + </data-member> + </union-decl> + <typedef-decl name='sem_t' type-id='type-id-1522' filepath='/usr/include/x86_64-linux-gnu/bits/semaphore.h' line='39' column='1' id='type-id-1521'/> + <qualified-type-def type-id='type-id-1520' const='yes' id='type-id-1523'/> + <pointer-type-def type-id='type-id-1523' size-in-bits='64' id='type-id-1524'/> + <qualified-type-def type-id='type-id-1524' restrict='yes' id='type-id-1525'/> + <qualified-type-def type-id='type-id-976' const='yes' id='type-id-1526'/> + <pointer-type-def type-id='type-id-1526' size-in-bits='64' id='type-id-1527'/> + <qualified-type-def type-id='type-id-1527' restrict='yes' id='type-id-1528'/> + <pointer-type-def type-id='type-id-1520' size-in-bits='64' id='type-id-1529'/> + <pointer-type-def type-id='type-id-789' size-in-bits='64' id='type-id-1530'/> + <pointer-type-def type-id='type-id-207' size-in-bits='64' id='type-id-1531'/> + <qualified-type-def type-id='type-id-1531' restrict='yes' id='type-id-1532'/> + <pointer-type-def type-id='type-id-1521' size-in-bits='64' id='type-id-1533'/> + <qualified-type-def type-id='type-id-1533' restrict='yes' id='type-id-1534'/> + <pointer-type-def type-id='type-id-1535' size-in-bits='64' id='type-id-1536'/> + <function-decl name='pthread_create' filepath='/usr/include/pthread.h' line='202' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1532'/> + <parameter type-id='type-id-1525'/> + <parameter type-id='type-id-1536'/> + <parameter type-id='type-id-226'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='pthread_exit' filepath='/usr/include/pthread.h' line='211' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-22'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='pthread_detach' filepath='/usr/include/pthread.h' line='269' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-207'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='pthread_self' filepath='/usr/include/pthread.h' line='273' column='1' visibility='default' binding='global' size-in-bits='64'> + <return type-id='type-id-207'/> + </function-decl> + <function-decl name='pthread_attr_init' filepath='/usr/include/pthread.h' line='285' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1529'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='pthread_attr_destroy' filepath='/usr/include/pthread.h' line='288' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1529'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='pthread_attr_setscope' filepath='/usr/include/pthread.h' line='349' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1529'/> + <parameter type-id='type-id-8'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='pthread_attr_setstacksize' filepath='/usr/include/pthread.h' line='373' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1529'/> + <parameter type-id='type-id-19'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='pthread_cond_init' filepath='/usr/include/pthread.h' line='1112' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1350'/> + <parameter type-id='type-id-1528'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='pthread_condattr_init' filepath='/usr/include/pthread.h' line='1194' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-975'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='pthread_condattr_setclock' filepath='/usr/include/pthread.h' line='1219' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-975'/> + <parameter type-id='type-id-212'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='pthread_key_create' filepath='/usr/include/pthread.h' line='1297' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1530'/> + <parameter type-id='type-id-760'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='pthread_key_delete' filepath='/usr/include/pthread.h' line='1302' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-789'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='pthread_getspecific' filepath='/usr/include/pthread.h' line='1305' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-789'/> + <return type-id='type-id-22'/> + </function-decl> + <function-decl name='pthread_setspecific' filepath='/usr/include/pthread.h' line='1308' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-789'/> + <parameter type-id='type-id-22'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='sem_init' filepath='/usr/include/semaphore.h' line='35' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1533'/> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-95'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='sem_destroy' filepath='/usr/include/semaphore.h' line='39' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1533'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='sem_wait' filepath='/usr/include/semaphore.h' line='55' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1533'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='sem_clockwait' filepath='/usr/include/semaphore.h' line='81' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1534'/> + <parameter type-id='type-id-221'/> + <parameter type-id='type-id-206'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='sem_trywait' filepath='/usr/include/semaphore.h' line='100' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1533'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='sem_post' filepath='/usr/include/semaphore.h' line='103' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-1533'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='perror' filepath='/usr/include/stdio.h' line='804' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-12'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='confstr' filepath='/usr/include/unistd.h' line='644' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-15'/> + <parameter type-id='type-id-19'/> + <return type-id='type-id-19'/> + </function-decl> + <function-decl name='syscall' filepath='/usr/include/unistd.h' line='1091' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-47'/> + <parameter is-variadic='yes'/> + <return type-id='type-id-47'/> + </function-decl> + <function-decl name='__sysconf' filepath='/usr/include/x86_64-linux-gnu/bits/pthread_stack_min-dynamic.h' line='24' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <return type-id='type-id-47'/> + </function-decl> + <function-decl name='PyThread_get_stacksize' mangled-name='PyThread_get_stacksize' filepath='Python/thread.c' line='54' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThread_get_stacksize'> + <return type-id='type-id-19'/> + </function-decl> + <function-decl name='PyThread_set_stacksize' mangled-name='PyThread_set_stacksize' filepath='Python/thread.c' line='65' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThread_set_stacksize'> + <parameter type-id='type-id-19' name='size' filepath='Python/thread.c' line='65' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyThread_tss_alloc' mangled-name='PyThread_tss_alloc' filepath='Python/thread.c' line='81' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThread_tss_alloc'> + <return type-id='type-id-409'/> + </function-decl> + <function-decl name='PyThread_tss_free' mangled-name='PyThread_tss_free' filepath='Python/thread.c' line='92' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThread_tss_free'> + <parameter type-id='type-id-409' name='key' filepath='Python/thread.c' line='92' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyThread_start_new_thread' mangled-name='PyThread_start_new_thread' filepath='Python/thread_pthread.h' line='238' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThread_start_new_thread'> + <parameter type-id='type-id-760' name='func' filepath='Python/thread_pthread.h' line='238' column='1'/> + <parameter type-id='type-id-22' name='arg' filepath='Python/thread_pthread.h' line='238' column='1'/> + <return type-id='type-id-28'/> + </function-decl> + <function-decl name='PyThread_acquire_lock_timed' mangled-name='PyThread_acquire_lock_timed' filepath='Python/thread_pthread.h' line='430' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThread_acquire_lock_timed'> + <parameter type-id='type-id-801' name='lock' filepath='Python/thread_pthread.h' line='430' column='1'/> + <parameter type-id='type-id-378' name='microseconds' filepath='Python/thread_pthread.h' line='430' column='1'/> + <parameter type-id='type-id-8' name='intr_flag' filepath='Python/thread_pthread.h' line='431' column='1'/> + <return type-id='type-id-1518'/> + </function-decl> + <function-decl name='PyThread_create_key' mangled-name='PyThread_create_key' filepath='Python/thread_pthread.h' line='809' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThread_create_key'> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyThread_delete_key' mangled-name='PyThread_delete_key' filepath='Python/thread_pthread.h' line='829' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThread_delete_key'> + <parameter type-id='type-id-8' name='key' filepath='Python/thread_pthread.h' line='829' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyThread_delete_key_value' mangled-name='PyThread_delete_key_value' filepath='Python/thread_pthread.h' line='837' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThread_delete_key_value'> + <parameter type-id='type-id-8' name='key' filepath='Python/thread_pthread.h' line='837' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyThread_set_key_value' mangled-name='PyThread_set_key_value' filepath='Python/thread_pthread.h' line='845' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThread_set_key_value'> + <parameter type-id='type-id-8' name='key' filepath='Python/thread_pthread.h' line='845' column='1'/> + <parameter type-id='type-id-22' name='value' filepath='Python/thread_pthread.h' line='845' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyThread_get_key_value' mangled-name='PyThread_get_key_value' filepath='Python/thread_pthread.h' line='856' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThread_get_key_value'> + <parameter type-id='type-id-8' name='key' filepath='Python/thread_pthread.h' line='856' column='1'/> + <return type-id='type-id-22'/> + </function-decl> + <function-decl name='PyThread_ReInitTLS' mangled-name='PyThread_ReInitTLS' filepath='Python/thread_pthread.h' line='867' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyThread_ReInitTLS'> + <return type-id='type-id-46'/> + </function-decl> + <function-type size-in-bits='64' id='type-id-1535'> + <parameter type-id='type-id-22'/> + <return type-id='type-id-22'/> + </function-type> + </abi-instr> + <abi-instr address-size='64' path='Python/traceback.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <function-decl name='_PyObject_CallMethodFormat' filepath='./Include/internal/pycore_call.h' line='33' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-177'/> + <parameter type-id='type-id-2'/> + <parameter type-id='type-id-12'/> + <parameter is-variadic='yes'/> + <return type-id='type-id-2'/> + </function-decl> + <var-decl name='PyTraceBack_Type' type-id='type-id-256' mangled-name='PyTraceBack_Type' visibility='default' filepath='./Include/traceback.h' line='13' column='1' elf-symbol-id='PyTraceBack_Type'/> + <function-decl name='_PyTokenizer_FindEncodingFilename' filepath='Python/traceback.c' line='34' column='1' visibility='default' binding='global' size-in-bits='64'> + <parameter type-id='type-id-8'/> + <parameter type-id='type-id-2'/> + <return type-id='type-id-15'/> + </function-decl> + <function-decl name='_PyTraceback_Add' mangled-name='_PyTraceback_Add' filepath='Python/traceback.c' line='261' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTraceback_Add'> + <parameter type-id='type-id-12' name='funcname' filepath='Python/traceback.c' line='261' column='1'/> + <parameter type-id='type-id-12' name='filename' filepath='Python/traceback.c' line='261' column='1'/> + <parameter type-id='type-id-8' name='lineno' filepath='Python/traceback.c' line='261' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_Py_DumpTraceback' mangled-name='_Py_DumpTraceback' filepath='Python/traceback.c' line='1251' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_Py_DumpTraceback'> + <parameter type-id='type-id-8' name='fd' filepath='Python/traceback.c' line='1251' column='1'/> + <parameter type-id='type-id-177' name='tstate' filepath='Python/traceback.c' line='1251' column='1'/> + <return type-id='type-id-46'/> + </function-decl> + </abi-instr> + <abi-instr address-size='64' path='Python/tracemalloc.c' comp-dir-path='/home/runner/work/cpython/cpython' language='LANG_C11'> + <function-decl name='_PyTraceMalloc_Init' mangled-name='_PyTraceMalloc_Init' filepath='Python/tracemalloc.c' line='799' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTraceMalloc_Init'> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyTraceMalloc_Stop' mangled-name='_PyTraceMalloc_Stop' filepath='Python/tracemalloc.c' line='955' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTraceMalloc_Stop'> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='PyTraceMalloc_Track' mangled-name='PyTraceMalloc_Track' filepath='Python/tracemalloc.c' line='1301' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyTraceMalloc_Track'> + <parameter type-id='type-id-95' name='domain' filepath='Python/tracemalloc.c' line='1301' column='1'/> + <parameter type-id='type-id-749' name='ptr' filepath='Python/tracemalloc.c' line='1301' column='1'/> + <parameter type-id='type-id-19' name='size' filepath='Python/tracemalloc.c' line='1302' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='PyTraceMalloc_Untrack' mangled-name='PyTraceMalloc_Untrack' filepath='Python/tracemalloc.c' line='1324' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='PyTraceMalloc_Untrack'> + <parameter type-id='type-id-95' name='domain' filepath='Python/tracemalloc.c' line='1324' column='1'/> + <parameter type-id='type-id-749' name='ptr' filepath='Python/tracemalloc.c' line='1324' column='1'/> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyTraceMalloc_GetTraceback' mangled-name='_PyTraceMalloc_GetTraceback' filepath='Python/tracemalloc.c' line='1386' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTraceMalloc_GetTraceback'> + <parameter type-id='type-id-95' name='domain' filepath='Python/tracemalloc.c' line='1386' column='1'/> + <parameter type-id='type-id-749' name='ptr' filepath='Python/tracemalloc.c' line='1386' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyTraceMalloc_IsTracing' mangled-name='_PyTraceMalloc_IsTracing' filepath='Python/tracemalloc.c' line='1398' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTraceMalloc_IsTracing'> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyTraceMalloc_ClearTraces' mangled-name='_PyTraceMalloc_ClearTraces' filepath='Python/tracemalloc.c' line='1404' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTraceMalloc_ClearTraces'> + <return type-id='type-id-46'/> + </function-decl> + <function-decl name='_PyTraceMalloc_GetTraces' mangled-name='_PyTraceMalloc_GetTraces' filepath='Python/tracemalloc.c' line='1416' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTraceMalloc_GetTraces'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyTraceMalloc_GetObjectTraceback' mangled-name='_PyTraceMalloc_GetObjectTraceback' filepath='Python/tracemalloc.c' line='1496' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTraceMalloc_GetObjectTraceback'> + <parameter type-id='type-id-2' name='obj' filepath='Python/tracemalloc.c' line='1496' column='1'/> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyTraceMalloc_GetTracebackLimit' mangled-name='_PyTraceMalloc_GetTracebackLimit' filepath='Python/tracemalloc.c' line='1514' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTraceMalloc_GetTracebackLimit'> + <return type-id='type-id-8'/> + </function-decl> + <function-decl name='_PyTraceMalloc_GetMemory' mangled-name='_PyTraceMalloc_GetMemory' filepath='Python/tracemalloc.c' line='1519' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTraceMalloc_GetMemory'> + <return type-id='type-id-19'/> + </function-decl> + <function-decl name='_PyTraceMalloc_GetTracedMemory' mangled-name='_PyTraceMalloc_GetTracedMemory' filepath='Python/tracemalloc.c' line='1536' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTraceMalloc_GetTracedMemory'> + <return type-id='type-id-2'/> + </function-decl> + <function-decl name='_PyTraceMalloc_ResetPeak' mangled-name='_PyTraceMalloc_ResetPeak' filepath='Python/tracemalloc.c' line='1552' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_PyTraceMalloc_ResetPeak'> + <return type-id='type-id-46'/> + </function-decl> + </abi-instr> +</abi-corpus> diff --git a/Doc/data/refcounts.dat b/Doc/data/refcounts.dat index cbd22a3e..ee64ffdc 100644 --- a/Doc/data/refcounts.dat +++ b/Doc/data/refcounts.dat @@ -606,6 +606,9 @@ PyErr_GetExcInfo:PyObject**:ptype:+1: PyErr_GetExcInfo:PyObject**:pvalue:+1: PyErr_GetExcInfo:PyObject**:ptraceback:+1: +PyErr_GetRaisedException:PyObject*::+1: +PyErr_SetRaisedException:::: + PyErr_GivenExceptionMatches:int::: PyErr_GivenExceptionMatches:PyObject*:given:0: PyErr_GivenExceptionMatches:PyObject*:exc:0: @@ -796,10 +799,18 @@ PyEval_SetProfile:void::: PyEval_SetProfile:Py_tracefunc:func:: PyEval_SetProfile:PyObject*:obj:+1: +PyEval_SetProfileAllThreads:void::: +PyEval_SetProfileAllThreads:Py_tracefunc:func:: +PyEval_SetProfileAllThreads:PyObject*:obj:+1: + PyEval_SetTrace:void::: PyEval_SetTrace:Py_tracefunc:func:: PyEval_SetTrace:PyObject*:obj:+1: +PyEval_SetTraceAllThreads:void::: +PyEval_SetTraceAllThreads:Py_tracefunc:func:: +PyEval_SetTraceAllThreads:PyObject*:obj:+1: + PyEval_EvalCode:PyObject*::+1: PyEval_EvalCode:PyObject*:co:0: PyEval_EvalCode:PyObject*:globals:0: @@ -828,6 +839,8 @@ PyEval_EvalFrameEx:int:throwflag:: PyEval_MergeCompilerFlags:int::: PyEval_MergeCompilerFlags:PyCompilerFlags*:cf:: +PyException_GetArgs:PyObject*::+1: + PyException_GetCause:PyObject*::+1: PyException_GetCause:PyObject*:ex:0: diff --git a/Doc/data/stable_abi.dat b/Doc/data/stable_abi.dat index 5387d0bf..f112d268 100644 --- a/Doc/data/stable_abi.dat +++ b/Doc/data/stable_abi.dat @@ -1,4 +1,5 @@ role,name,added,ifdef_note,struct_abi_kind +macro,PY_VECTORCALL_ARGUMENTS_OFFSET,3.12,, function,PyAIter_Check,3.10,, function,PyArg_Parse,3.2,, function,PyArg_ParseTuple,3.2,, @@ -132,12 +133,14 @@ function,PyErr_BadInternalCall,3.2,, function,PyErr_CheckSignals,3.2,, function,PyErr_Clear,3.2,, function,PyErr_Display,3.2,, +function,PyErr_DisplayException,3.12,, function,PyErr_ExceptionMatches,3.2,, function,PyErr_Fetch,3.2,, function,PyErr_Format,3.2,, function,PyErr_FormatV,3.5,, function,PyErr_GetExcInfo,3.7,, function,PyErr_GetHandledException,3.11,, +function,PyErr_GetRaisedException,3.12,, function,PyErr_GivenExceptionMatches,3.2,, function,PyErr_NewException,3.2,, function,PyErr_NewExceptionWithDoc,3.2,, @@ -167,6 +170,7 @@ function,PyErr_SetInterrupt,3.2,, function,PyErr_SetInterruptEx,3.10,, function,PyErr_SetNone,3.2,, function,PyErr_SetObject,3.2,, +function,PyErr_SetRaisedException,3.12,, function,PyErr_SetString,3.2,, function,PyErr_SyntaxLocation,3.2,, function,PyErr_SyntaxLocationEx,3.7,, @@ -265,9 +269,11 @@ var,PyExc_Warning,3.2,, var,PyExc_WindowsError,3.7,on Windows, var,PyExc_ZeroDivisionError,3.2,, function,PyExceptionClass_Name,3.8,, +function,PyException_GetArgs,3.12,, function,PyException_GetCause,3.2,, function,PyException_GetContext,3.2,, function,PyException_GetTraceback,3.2,, +function,PyException_SetArgs,3.12,, function,PyException_SetCause,3.2,, function,PyException_SetContext,3.2,, function,PyException_SetTraceback,3.2,, @@ -385,6 +391,8 @@ function,PyMem_Malloc,3.2,, function,PyMem_Realloc,3.2,, type,PyMemberDef,3.2,,full-abi var,PyMemberDescr_Type,3.2,, +function,PyMember_GetOne,3.2,, +function,PyMember_SetOne,3.2,, function,PyMemoryView_FromBuffer,3.11,, function,PyMemoryView_FromMemory,3.7,, function,PyMemoryView_FromObject,3.2,, @@ -513,6 +521,7 @@ function,PyObject_GetAttrString,3.2,, function,PyObject_GetBuffer,3.11,, function,PyObject_GetItem,3.2,, function,PyObject_GetIter,3.2,, +function,PyObject_GetTypeData,3.12,, function,PyObject_HasAttr,3.2,, function,PyObject_HasAttrString,3.2,, function,PyObject_Hash,3.2,, @@ -536,6 +545,8 @@ function,PyObject_SetItem,3.2,, function,PyObject_Size,3.2,, function,PyObject_Str,3.2,, function,PyObject_Type,3.2,, +function,PyObject_Vectorcall,3.12,, +function,PyObject_VectorcallMethod,3.12,, var,PyProperty_Type,3.2,, var,PyRangeIter_Type,3.2,, var,PyRange_Type,3.2,, @@ -653,6 +664,7 @@ function,PyTuple_Size,3.2,, var,PyTuple_Type,3.2,, type,PyTypeObject,3.2,,opaque function,PyType_ClearCache,3.2,, +function,PyType_FromMetaclass,3.12,, function,PyType_FromModuleAndSpec,3.10,, function,PyType_FromSpec,3.2,, function,PyType_FromSpecWithBases,3.3,, @@ -664,6 +676,7 @@ function,PyType_GetModuleState,3.10,, function,PyType_GetName,3.11,, function,PyType_GetQualName,3.11,, function,PyType_GetSlot,3.4,, +function,PyType_GetTypeDataSize,3.12,, function,PyType_IsSubtype,3.2,, function,PyType_Modified,3.2,, function,PyType_Ready,3.2,, @@ -761,9 +774,7 @@ function,PyUnicode_FromStringAndSize,3.2,, function,PyUnicode_FromWideChar,3.2,, function,PyUnicode_GetDefaultEncoding,3.2,, function,PyUnicode_GetLength,3.7,, -function,PyUnicode_GetSize,3.2,, function,PyUnicode_InternFromString,3.2,, -function,PyUnicode_InternImmortal,3.2,, function,PyUnicode_InternInPlace,3.2,, function,PyUnicode_IsIdentifier,3.2,, function,PyUnicode_Join,3.2,, @@ -784,6 +795,8 @@ function,PyUnicode_WriteChar,3.7,, type,PyVarObject,3.2,,members member,PyVarObject.ob_base,3.2,, member,PyVarObject.ob_size,3.2,, +function,PyVectorcall_Call,3.12,, +function,PyVectorcall_NARGS,3.12,, type,PyWeakReference,3.2,,opaque function,PyWeakref_GetObject,3.2,, function,PyWeakref_NewProxy,3.2,, @@ -861,6 +874,7 @@ type,descrsetfunc,3.2,, type,destructor,3.2,, type,getattrfunc,3.2,, type,getattrofunc,3.2,, +type,getbufferproc,3.12,, type,getiterfunc,3.2,, type,getter,3.2,, type,hashfunc,3.2,, @@ -871,6 +885,7 @@ type,lenfunc,3.2,, type,newfunc,3.2,, type,objobjargproc,3.2,, type,objobjproc,3.2,, +type,releasebufferproc,3.12,, type,reprfunc,3.2,, type,richcmpfunc,3.2,, type,setattrfunc,3.2,, @@ -884,4 +899,5 @@ type,symtable,3.2,,opaque type,ternaryfunc,3.2,, type,traverseproc,3.2,, type,unaryfunc,3.2,, +type,vectorcallfunc,3.12,, type,visitproc,3.2,, diff --git a/Doc/distributing/index.rst b/Doc/distributing/index.rst index 136cf4e7..2430564b 100644 --- a/Doc/distributing/index.rst +++ b/Doc/distributing/index.rst @@ -1,179 +1,19 @@ +:orphan: + +.. This page is retained solely for existing links to /distributing/index.html. + Direct readers to the PPUG instead. + .. _distributing-index: ############################### Distributing Python Modules ############################### -:Email: distutils-sig@python.org - - -As a popular open source development project, Python has an active -supporting community of contributors and users that also make their software -available for other Python developers to use under open source license terms. - -This allows Python users to share and collaborate effectively, benefiting -from the solutions others have already created to common (and sometimes -even rare!) problems, as well as potentially contributing their own -solutions to the common pool. - -This guide covers the distribution part of the process. For a guide to -installing other Python projects, refer to the -:ref:`installation guide <installing-index>`. - .. note:: - For corporate and other institutional users, be aware that many - organisations have their own policies around using and contributing to - open source software. Please take such policies into account when making - use of the distribution and installation tools provided with Python. - - -Key terms -========= - -* the `Python Package Index <https://pypi.org>`__ is a public - repository of open source licensed packages made available for use by - other Python users -* the `Python Packaging Authority - <https://www.pypa.io/>`__ are the group of - developers and documentation authors responsible for the maintenance and - evolution of the standard packaging tools and the associated metadata and - file format standards. They maintain a variety of tools, documentation - and issue trackers on both `GitHub <https://github.com/pypa>`__ and - `Bitbucket <https://bitbucket.org/pypa/>`__. -* :mod:`distutils` is the original build and distribution system first added - to the Python standard library in 1998. While direct use of :mod:`distutils` - is being phased out, it still laid the foundation for the current packaging - and distribution infrastructure, and it not only remains part of the - standard library, but its name lives on in other ways (such as the name - of the mailing list used to coordinate Python packaging standards - development). -* `setuptools`_ is a (largely) drop-in replacement for :mod:`distutils` first - published in 2004. Its most notable addition over the unmodified - :mod:`distutils` tools was the ability to declare dependencies on other - packages. It is currently recommended as a more regularly updated - alternative to :mod:`distutils` that offers consistent support for more - recent packaging standards across a wide range of Python versions. -* `wheel`_ (in this context) is a project that adds the ``bdist_wheel`` - command to :mod:`distutils`/`setuptools`_. This produces a cross platform - binary packaging format (called "wheels" or "wheel files" and defined in - :pep:`427`) that allows Python libraries, even those including binary - extensions, to be installed on a system without needing to be built - locally. - -.. _setuptools: https://setuptools.readthedocs.io/en/latest/ -.. _wheel: https://wheel.readthedocs.io/ - -Open source licensing and collaboration -======================================= - -In most parts of the world, software is automatically covered by copyright. -This means that other developers require explicit permission to copy, use, -modify and redistribute the software. - -Open source licensing is a way of explicitly granting such permission in a -relatively consistent way, allowing developers to share and collaborate -efficiently by making common solutions to various problems freely available. -This leaves many developers free to spend more time focusing on the problems -that are relatively unique to their specific situation. - -The distribution tools provided with Python are designed to make it -reasonably straightforward for developers to make their own contributions -back to that common pool of software if they choose to do so. - -The same distribution tools can also be used to distribute software within -an organisation, regardless of whether that software is published as open -source software or not. - - -Installing the tools -==================== - -The standard library does not include build tools that support modern -Python packaging standards, as the core development team has found that it -is important to have standard tools that work consistently, even on older -versions of Python. - -The currently recommended build and distribution tools can be installed -by invoking the ``pip`` module at the command line:: - - python -m pip install setuptools wheel twine - -.. note:: - - For POSIX users (including macOS and Linux users), these instructions - assume the use of a :term:`virtual environment`. - - For Windows users, these instructions assume that the option to - adjust the system PATH environment variable was selected when installing - Python. - -The Python Packaging User Guide includes more details on the `currently -recommended tools`_. - -.. _currently recommended tools: https://packaging.python.org/guides/tool-recommendations/#packaging-tool-recommendations - -.. index:: - single: Python Package Index (PyPI) - single: PyPI; (see Python Package Index (PyPI)) - -.. _publishing-python-packages: - -Reading the Python Packaging User Guide -======================================= - -The Python Packaging User Guide covers the various key steps and elements -involved in creating and publishing a project: - -* `Project structure`_ -* `Building and packaging the project`_ -* `Uploading the project to the Python Package Index`_ -* `The .pypirc file`_ - -.. _Project structure: \ - https://packaging.python.org/tutorials/packaging-projects/#packaging-python-projects -.. _Building and packaging the project: \ - https://packaging.python.org/tutorials/packaging-projects/#creating-the-package-files -.. _Uploading the project to the Python Package Index: \ - https://packaging.python.org/tutorials/packaging-projects/#uploading-the-distribution-archives -.. _The .pypirc file: \ - https://packaging.python.org/specifications/pypirc/ - - -How do I...? -============ - -These are quick answers or links for some common tasks. - -... choose a name for my project? ---------------------------------- - -This isn't an easy topic, but here are a few tips: - -* check the Python Package Index to see if the name is already in use -* check popular hosting sites like GitHub, Bitbucket, etc to see if there - is already a project with that name -* check what comes up in a web search for the name you're considering -* avoid particularly common words, especially ones with multiple meanings, - as they can make it difficult for users to find your software when - searching for it - - -... create and distribute binary extensions? --------------------------------------------- - -This is actually quite a complex topic, with a variety of alternatives -available depending on exactly what you're aiming to achieve. See the -Python Packaging User Guide for more information and recommendations. - -.. seealso:: - - `Python Packaging User Guide: Binary Extensions - <https://packaging.python.org/guides/packaging-binary-extensions/>`__ - -.. other topics: + Information and guidance on distributing Python modules and packages + has been moved to the `Python Packaging User Guide`_, + and the tutorial on `packaging Python projects`_. - Once the Development & Deployment part of PPUG is fleshed out, some of - those sections should be linked from new questions here (most notably, - we should have a question about avoiding depending on PyPI that links to - https://packaging.python.org/en/latest/mirrors/) + .. _Python Packaging User Guide: https://packaging.python.org/ + .. _packaging Python projects: https://packaging.python.org/en/latest/tutorials/packaging-projects/ diff --git a/Doc/distutils/_setuptools_disclaimer.rst b/Doc/distutils/_setuptools_disclaimer.rst deleted file mode 100644 index cc758583..00000000 --- a/Doc/distutils/_setuptools_disclaimer.rst +++ /dev/null @@ -1,5 +0,0 @@ -.. note:: - - This document is being retained solely until the ``setuptools`` documentation - at https://setuptools.readthedocs.io/en/latest/setuptools.html - independently covers all of the relevant information currently included here. diff --git a/Doc/distutils/apiref.rst b/Doc/distutils/apiref.rst deleted file mode 100644 index 87c92855..00000000 --- a/Doc/distutils/apiref.rst +++ /dev/null @@ -1,2041 +0,0 @@ -.. _api-reference: - -************* -API Reference -************* - -.. seealso:: - - `New and changed setup.py arguments in setuptools`_ - The ``setuptools`` project adds new capabilities to the ``setup`` function - and other APIs, makes the API consistent across different Python versions, - and is hence recommended over using ``distutils`` directly. - -.. _New and changed setup.py arguments in setuptools: https://web.archive.org/web/20210614192516/https://setuptools.pypa.io/en/stable/userguide/keywords.html - -.. include:: ./_setuptools_disclaimer.rst - -:mod:`distutils.core` --- Core Distutils functionality -====================================================== - -.. module:: distutils.core - :synopsis: The core Distutils functionality - - -The :mod:`distutils.core` module is the only module that needs to be installed -to use the Distutils. It provides the :func:`setup` (which is called from the -setup script). Indirectly provides the :class:`distutils.dist.Distribution` and -:class:`distutils.cmd.Command` class. - - -.. function:: setup(arguments) - - The basic do-everything function that does most everything you could ever ask - for from a Distutils method. - - The setup function takes a large number of arguments. These are laid out in the - following table. - - .. tabularcolumns:: |l|L|L| - - +--------------------+--------------------------------+-------------------------------------------------------------+ - | argument name | value | type | - +====================+================================+=============================================================+ - | *name* | The name of the package | a string | - +--------------------+--------------------------------+-------------------------------------------------------------+ - | *version* | The version number of the | a string | - | | package; see | | - | | :mod:`distutils.version` | | - +--------------------+--------------------------------+-------------------------------------------------------------+ - | *description* | A single line describing the | a string | - | | package | | - +--------------------+--------------------------------+-------------------------------------------------------------+ - | *long_description* | Longer description of the | a string | - | | package | | - +--------------------+--------------------------------+-------------------------------------------------------------+ - | *author* | The name of the package author | a string | - +--------------------+--------------------------------+-------------------------------------------------------------+ - | *author_email* | The email address of the | a string | - | | package author | | - +--------------------+--------------------------------+-------------------------------------------------------------+ - | *maintainer* | The name of the current | a string | - | | maintainer, if different from | | - | | the author. Note that if | | - | | the maintainer is provided, | | - | | distutils will use it as the | | - | | author in :file:`PKG-INFO` | | - +--------------------+--------------------------------+-------------------------------------------------------------+ - | *maintainer_email* | The email address of the | a string | - | | current maintainer, if | | - | | different from the author | | - +--------------------+--------------------------------+-------------------------------------------------------------+ - | *url* | A URL for the package | a string | - | | (homepage) | | - +--------------------+--------------------------------+-------------------------------------------------------------+ - | *download_url* | A URL to download the package | a string | - +--------------------+--------------------------------+-------------------------------------------------------------+ - | *packages* | A list of Python packages that | a list of strings | - | | distutils will manipulate | | - +--------------------+--------------------------------+-------------------------------------------------------------+ - | *py_modules* | A list of Python modules that | a list of strings | - | | distutils will manipulate | | - +--------------------+--------------------------------+-------------------------------------------------------------+ - | *scripts* | A list of standalone script | a list of strings | - | | files to be built and | | - | | installed | | - +--------------------+--------------------------------+-------------------------------------------------------------+ - | *ext_modules* | A list of Python extensions to | a list of instances of | - | | be built | :class:`distutils.core.Extension` | - +--------------------+--------------------------------+-------------------------------------------------------------+ - | *classifiers* | A list of categories for the | a list of strings; valid classifiers are listed on `PyPI | - | | package | <https://pypi.org/classifiers>`_. | - +--------------------+--------------------------------+-------------------------------------------------------------+ - | *distclass* | the :class:`Distribution` | a subclass of | - | | class to use | :class:`distutils.core.Distribution` | - +--------------------+--------------------------------+-------------------------------------------------------------+ - | *script_name* | The name of the setup.py | a string | - | | script - defaults to | | - | | ``sys.argv[0]`` | | - +--------------------+--------------------------------+-------------------------------------------------------------+ - | *script_args* | Arguments to supply to the | a list of strings | - | | setup script | | - +--------------------+--------------------------------+-------------------------------------------------------------+ - | *options* | default options for the setup | a dictionary | - | | script | | - +--------------------+--------------------------------+-------------------------------------------------------------+ - | *license* | The license for the package | a string | - +--------------------+--------------------------------+-------------------------------------------------------------+ - | *keywords* | Descriptive meta-data, see | a list of strings or a comma-separated string | - | | :pep:`314` | | - +--------------------+--------------------------------+-------------------------------------------------------------+ - | *platforms* | | a list of strings or a comma-separated string | - +--------------------+--------------------------------+-------------------------------------------------------------+ - | *cmdclass* | A mapping of command names to | a dictionary | - | | :class:`Command` subclasses | | - +--------------------+--------------------------------+-------------------------------------------------------------+ - | *data_files* | A list of data files to | a list | - | | install | | - +--------------------+--------------------------------+-------------------------------------------------------------+ - | *package_dir* | A mapping of package to | a dictionary | - | | directory names | | - +--------------------+--------------------------------+-------------------------------------------------------------+ - - - -.. function:: run_setup(script_name[, script_args=None, stop_after='run']) - - Run a setup script in a somewhat controlled environment, and return the - :class:`distutils.dist.Distribution` instance that drives things. This is - useful if you need to find out the distribution meta-data (passed as keyword - args from *script* to :func:`setup`), or the contents of the config files or - command-line. - - *script_name* is a file that will be read and run with :func:`exec`. ``sys.argv[0]`` - will be replaced with *script* for the duration of the call. *script_args* is a - list of strings; if supplied, ``sys.argv[1:]`` will be replaced by *script_args* - for the duration of the call. - - *stop_after* tells :func:`setup` when to stop processing; possible values: - - .. tabularcolumns:: |l|L| - - +---------------+---------------------------------------------+ - | value | description | - +===============+=============================================+ - | *init* | Stop after the :class:`Distribution` | - | | instance has been created and populated | - | | with the keyword arguments to :func:`setup` | - +---------------+---------------------------------------------+ - | *config* | Stop after config files have been parsed | - | | (and their data stored in the | - | | :class:`Distribution` instance) | - +---------------+---------------------------------------------+ - | *commandline* | Stop after the command-line | - | | (``sys.argv[1:]`` or *script_args*) have | - | | been parsed (and the data stored in the | - | | :class:`Distribution` instance.) | - +---------------+---------------------------------------------+ - | *run* | Stop after all commands have been run (the | - | | same as if :func:`setup` had been called | - | | in the usual way). This is the default | - | | value. | - +---------------+---------------------------------------------+ - -In addition, the :mod:`distutils.core` module exposed a number of classes that -live elsewhere. - -* :class:`~distutils.extension.Extension` from :mod:`distutils.extension` - -* :class:`~distutils.cmd.Command` from :mod:`distutils.cmd` - -* :class:`~distutils.dist.Distribution` from :mod:`distutils.dist` - -A short description of each of these follows, but see the relevant module for -the full reference. - - -.. class:: Extension - - The Extension class describes a single C or C++ extension module in a setup - script. It accepts the following keyword arguments in its constructor: - - .. tabularcolumns:: |l|L|l| - - +------------------------+--------------------------------+---------------------------+ - | argument name | value | type | - +========================+================================+===========================+ - | *name* | the full name of the | a string | - | | extension, including any | | - | | packages --- ie. *not* a | | - | | filename or pathname, but | | - | | Python dotted name | | - +------------------------+--------------------------------+---------------------------+ - | *sources* | list of source filenames, | a list of strings | - | | relative to the distribution | | - | | root (where the setup script | | - | | lives), in Unix form | | - | | (slash-separated) for | | - | | portability. | | - | | Source files may be C, C++, | | - | | SWIG (.i), platform-specific | | - | | resource files, or whatever | | - | | else is recognized by the | | - | | :command:`build_ext` command | | - | | as source for a Python | | - | | extension. | | - +------------------------+--------------------------------+---------------------------+ - | *include_dirs* | list of directories to search | a list of strings | - | | for C/C++ header files (in | | - | | Unix form for portability) | | - +------------------------+--------------------------------+---------------------------+ - | *define_macros* | list of macros to define; each | a list of tuples | - | | macro is defined using a | | - | | 2-tuple ``(name, value)``, | | - | | where *value* is | | - | | either the string to define it | | - | | to or ``None`` to define it | | - | | without a particular value | | - | | (equivalent of ``#define FOO`` | | - | | in source or :option:`!-DFOO` | | - | | on Unix C compiler command | | - | | line) | | - +------------------------+--------------------------------+---------------------------+ - | *undef_macros* | list of macros to undefine | a list of strings | - | | explicitly | | - +------------------------+--------------------------------+---------------------------+ - | *library_dirs* | list of directories to search | a list of strings | - | | for C/C++ libraries at link | | - | | time | | - +------------------------+--------------------------------+---------------------------+ - | *libraries* | list of library names (not | a list of strings | - | | filenames or paths) to link | | - | | against | | - +------------------------+--------------------------------+---------------------------+ - | *runtime_library_dirs* | list of directories to search | a list of strings | - | | for C/C++ libraries at run | | - | | time (for shared extensions, | | - | | this is when the extension is | | - | | loaded) | | - +------------------------+--------------------------------+---------------------------+ - | *extra_objects* | list of extra files to link | a list of strings | - | | with (eg. object files not | | - | | implied by 'sources', static | | - | | library that must be | | - | | explicitly specified, binary | | - | | resource files, etc.) | | - +------------------------+--------------------------------+---------------------------+ - | *extra_compile_args* | any extra platform- and | a list of strings | - | | compiler-specific information | | - | | to use when compiling the | | - | | source files in 'sources'. For | | - | | platforms and compilers where | | - | | a command line makes sense, | | - | | this is typically a list of | | - | | command-line arguments, but | | - | | for other platforms it could | | - | | be anything. | | - +------------------------+--------------------------------+---------------------------+ - | *extra_link_args* | any extra platform- and | a list of strings | - | | compiler-specific information | | - | | to use when linking object | | - | | files together to create the | | - | | extension (or to create a new | | - | | static Python interpreter). | | - | | Similar interpretation as for | | - | | 'extra_compile_args'. | | - +------------------------+--------------------------------+---------------------------+ - | *export_symbols* | list of symbols to be exported | a list of strings | - | | from a shared extension. Not | | - | | used on all platforms, and not | | - | | generally necessary for Python | | - | | extensions, which typically | | - | | export exactly one symbol: | | - | | ``init`` + extension_name. | | - +------------------------+--------------------------------+---------------------------+ - | *depends* | list of files that the | a list of strings | - | | extension depends on | | - +------------------------+--------------------------------+---------------------------+ - | *language* | extension language (i.e. | a string | - | | ``'c'``, ``'c++'``, | | - | | ``'objc'``). Will be detected | | - | | from the source extensions if | | - | | not provided. | | - +------------------------+--------------------------------+---------------------------+ - | *optional* | specifies that a build failure | a boolean | - | | in the extension should not | | - | | abort the build process, but | | - | | simply skip the extension. | | - +------------------------+--------------------------------+---------------------------+ - - .. versionchanged:: 3.8 - - On Unix, C extensions are no longer linked to libpython except on - Android and Cygwin. - - -.. class:: Distribution - - A :class:`Distribution` describes how to build, install and package up a Python - software package. - - See the :func:`setup` function for a list of keyword arguments accepted by the - Distribution constructor. :func:`setup` creates a Distribution instance. - - .. versionchanged:: 3.7 - :class:`~distutils.core.Distribution` now warns if ``classifiers``, - ``keywords`` and ``platforms`` fields are not specified as a list or - a string. - -.. class:: Command - - A :class:`Command` class (or rather, an instance of one of its subclasses) - implement a single distutils command. - - -:mod:`distutils.ccompiler` --- CCompiler base class -=================================================== - -.. module:: distutils.ccompiler - :synopsis: Abstract CCompiler class - - -This module provides the abstract base class for the :class:`CCompiler` -classes. A :class:`CCompiler` instance can be used for all the compile and -link steps needed to build a single project. Methods are provided to set -options for the compiler --- macro definitions, include directories, link path, -libraries and the like. - -This module provides the following functions. - - -.. function:: gen_lib_options(compiler, library_dirs, runtime_library_dirs, libraries) - - Generate linker options for searching library directories and linking with - specific libraries. *libraries* and *library_dirs* are, respectively, lists of - library names (not filenames!) and search directories. Returns a list of - command-line options suitable for use with some compiler (depending on the two - format strings passed in). - - -.. function:: gen_preprocess_options(macros, include_dirs) - - Generate C pre-processor options (:option:`!-D`, :option:`!-U`, :option:`!-I`) as - used by at least two types of compilers: the typical Unix compiler and Visual - C++. *macros* is the usual thing, a list of 1- or 2-tuples, where ``(name,)`` - means undefine (:option:`!-U`) macro *name*, and ``(name, value)`` means define - (:option:`!-D`) macro *name* to *value*. *include_dirs* is just a list of - directory names to be added to the header file search path (:option:`!-I`). - Returns a list of command-line options suitable for either Unix compilers or - Visual C++. - - -.. function:: get_default_compiler(osname, platform) - - Determine the default compiler to use for the given platform. - - *osname* should be one of the standard Python OS names (i.e. the ones returned - by ``os.name``) and *platform* the common value returned by ``sys.platform`` for - the platform in question. - - The default values are ``os.name`` and ``sys.platform`` in case the parameters - are not given. - - -.. function:: new_compiler(plat=None, compiler=None, verbose=0, dry_run=0, force=0) - - Factory function to generate an instance of some CCompiler subclass for the - supplied platform/compiler combination. *plat* defaults to ``os.name`` (eg. - ``'posix'``, ``'nt'``), and *compiler* defaults to the default compiler for - that platform. Currently only ``'posix'`` and ``'nt'`` are supported, and the - default compilers are "traditional Unix interface" (:class:`UnixCCompiler` - class) and Visual C++ (:class:`MSVCCompiler` class). Note that it's perfectly - possible to ask for a Unix compiler object under Windows, and a Microsoft - compiler object under Unix---if you supply a value for *compiler*, *plat* is - ignored. - - .. % Is the posix/nt only thing still true? macOS seems to work, and - .. % returns a UnixCCompiler instance. How to document this... hmm. - - -.. function:: show_compilers() - - Print list of available compilers (used by the :option:`!--help-compiler` options - to :command:`build`, :command:`build_ext`, :command:`build_clib`). - - -.. class:: CCompiler([verbose=0, dry_run=0, force=0]) - - The abstract base class :class:`CCompiler` defines the interface that must be - implemented by real compiler classes. The class also has some utility methods - used by several compiler classes. - - The basic idea behind a compiler abstraction class is that each instance can be - used for all the compile/link steps in building a single project. Thus, - attributes common to all of those compile and link steps --- include - directories, macros to define, libraries to link against, etc. --- are - attributes of the compiler instance. To allow for variability in how individual - files are treated, most of those attributes may be varied on a per-compilation - or per-link basis. - - The constructor for each subclass creates an instance of the Compiler object. - Flags are *verbose* (show verbose output), *dry_run* (don't actually execute the - steps) and *force* (rebuild everything, regardless of dependencies). All of - these flags default to ``0`` (off). Note that you probably don't want to - instantiate :class:`CCompiler` or one of its subclasses directly - use the - :func:`distutils.CCompiler.new_compiler` factory function instead. - - The following methods allow you to manually alter compiler options for the - instance of the Compiler class. - - - .. method:: CCompiler.add_include_dir(dir) - - Add *dir* to the list of directories that will be searched for header files. - The compiler is instructed to search directories in the order in which they are - supplied by successive calls to :meth:`add_include_dir`. - - - .. method:: CCompiler.set_include_dirs(dirs) - - Set the list of directories that will be searched to *dirs* (a list of strings). - Overrides any preceding calls to :meth:`add_include_dir`; subsequent calls to - :meth:`add_include_dir` add to the list passed to :meth:`set_include_dirs`. - This does not affect any list of standard include directories that the compiler - may search by default. - - - .. method:: CCompiler.add_library(libname) - - Add *libname* to the list of libraries that will be included in all links driven - by this compiler object. Note that *libname* should \*not\* be the name of a - file containing a library, but the name of the library itself: the actual - filename will be inferred by the linker, the compiler, or the compiler class - (depending on the platform). - - The linker will be instructed to link against libraries in the order they were - supplied to :meth:`add_library` and/or :meth:`set_libraries`. It is perfectly - valid to duplicate library names; the linker will be instructed to link against - libraries as many times as they are mentioned. - - - .. method:: CCompiler.set_libraries(libnames) - - Set the list of libraries to be included in all links driven by this compiler - object to *libnames* (a list of strings). This does not affect any standard - system libraries that the linker may include by default. - - - .. method:: CCompiler.add_library_dir(dir) - - Add *dir* to the list of directories that will be searched for libraries - specified to :meth:`add_library` and :meth:`set_libraries`. The linker will be - instructed to search for libraries in the order they are supplied to - :meth:`add_library_dir` and/or :meth:`set_library_dirs`. - - - .. method:: CCompiler.set_library_dirs(dirs) - - Set the list of library search directories to *dirs* (a list of strings). This - does not affect any standard library search path that the linker may search by - default. - - - .. method:: CCompiler.add_runtime_library_dir(dir) - - Add *dir* to the list of directories that will be searched for shared libraries - at runtime. - - - .. method:: CCompiler.set_runtime_library_dirs(dirs) - - Set the list of directories to search for shared libraries at runtime to *dirs* - (a list of strings). This does not affect any standard search path that the - runtime linker may search by default. - - - .. method:: CCompiler.define_macro(name[, value=None]) - - Define a preprocessor macro for all compilations driven by this compiler object. - The optional parameter *value* should be a string; if it is not supplied, then - the macro will be defined without an explicit value and the exact outcome - depends on the compiler used. - - .. XXX true? does ANSI say anything about this? - - - .. method:: CCompiler.undefine_macro(name) - - Undefine a preprocessor macro for all compilations driven by this compiler - object. If the same macro is defined by :meth:`define_macro` and - undefined by :meth:`undefine_macro` the last call takes precedence - (including multiple redefinitions or undefinitions). If the macro is - redefined/undefined on a per-compilation basis (ie. in the call to - :meth:`compile`), then that takes precedence. - - - .. method:: CCompiler.add_link_object(object) - - Add *object* to the list of object files (or analogues, such as explicitly named - library files or the output of "resource compilers") to be included in every - link driven by this compiler object. - - - .. method:: CCompiler.set_link_objects(objects) - - Set the list of object files (or analogues) to be included in every link to - *objects*. This does not affect any standard object files that the linker may - include by default (such as system libraries). - - The following methods implement methods for autodetection of compiler options, - providing some functionality similar to GNU :program:`autoconf`. - - - .. method:: CCompiler.detect_language(sources) - - Detect the language of a given file, or list of files. Uses the instance - attributes :attr:`language_map` (a dictionary), and :attr:`language_order` (a - list) to do the job. - - - .. method:: CCompiler.find_library_file(dirs, lib[, debug=0]) - - Search the specified list of directories for a static or shared library file - *lib* and return the full path to that file. If *debug* is true, look for a - debugging version (if that makes sense on the current platform). Return - ``None`` if *lib* wasn't found in any of the specified directories. - - - .. method:: CCompiler.has_function(funcname [, includes=None, include_dirs=None, libraries=None, library_dirs=None]) - - Return a boolean indicating whether *funcname* is supported on the current - platform. The optional arguments can be used to augment the compilation - environment by providing additional include files and paths and libraries and - paths. - - - .. method:: CCompiler.library_dir_option(dir) - - Return the compiler option to add *dir* to the list of directories searched for - libraries. - - - .. method:: CCompiler.library_option(lib) - - Return the compiler option to add *lib* to the list of libraries linked into the - shared library or executable. - - - .. method:: CCompiler.runtime_library_dir_option(dir) - - Return the compiler option to add *dir* to the list of directories searched for - runtime libraries. - - - .. method:: CCompiler.set_executables(**args) - - Define the executables (and options for them) that will be run to perform the - various stages of compilation. The exact set of executables that may be - specified here depends on the compiler class (via the 'executables' class - attribute), but most will have: - - +--------------+------------------------------------------+ - | attribute | description | - +==============+==========================================+ - | *compiler* | the C/C++ compiler | - +--------------+------------------------------------------+ - | *linker_so* | linker used to create shared objects and | - | | libraries | - +--------------+------------------------------------------+ - | *linker_exe* | linker used to create binary executables | - +--------------+------------------------------------------+ - | *archiver* | static library creator | - +--------------+------------------------------------------+ - - On platforms with a command-line (Unix, DOS/Windows), each of these is a string - that will be split into executable name and (optional) list of arguments. - (Splitting the string is done similarly to how Unix shells operate: words are - delimited by spaces, but quotes and backslashes can override this. See - :func:`distutils.util.split_quoted`.) - - The following methods invoke stages in the build process. - - - .. method:: CCompiler.compile(sources[, output_dir=None, macros=None, include_dirs=None, debug=0, extra_preargs=None, extra_postargs=None, depends=None]) - - Compile one or more source files. Generates object files (e.g. transforms a - :file:`.c` file to a :file:`.o` file.) - - *sources* must be a list of filenames, most likely C/C++ files, but in reality - anything that can be handled by a particular compiler and compiler class (eg. - :class:`MSVCCompiler` can handle resource files in *sources*). Return a list of - object filenames, one per source filename in *sources*. Depending on the - implementation, not all source files will necessarily be compiled, but all - corresponding object filenames will be returned. - - If *output_dir* is given, object files will be put under it, while retaining - their original path component. That is, :file:`foo/bar.c` normally compiles to - :file:`foo/bar.o` (for a Unix implementation); if *output_dir* is *build*, then - it would compile to :file:`build/foo/bar.o`. - - *macros*, if given, must be a list of macro definitions. A macro definition is - either a ``(name, value)`` 2-tuple or a ``(name,)`` 1-tuple. The former defines - a macro; if the value is ``None``, the macro is defined without an explicit - value. The 1-tuple case undefines a macro. Later - definitions/redefinitions/undefinitions take precedence. - - *include_dirs*, if given, must be a list of strings, the directories to add to - the default include file search path for this compilation only. - - *debug* is a boolean; if true, the compiler will be instructed to output debug - symbols in (or alongside) the object file(s). - - *extra_preargs* and *extra_postargs* are implementation-dependent. On platforms - that have the notion of a command-line (e.g. Unix, DOS/Windows), they are most - likely lists of strings: extra command-line arguments to prepend/append to the - compiler command line. On other platforms, consult the implementation class - documentation. In any event, they are intended as an escape hatch for those - occasions when the abstract compiler framework doesn't cut the mustard. - - *depends*, if given, is a list of filenames that all targets depend on. If a - source file is older than any file in depends, then the source file will be - recompiled. This supports dependency tracking, but only at a coarse - granularity. - - Raises :exc:`CompileError` on failure. - - - .. method:: CCompiler.create_static_lib(objects, output_libname[, output_dir=None, debug=0, target_lang=None]) - - Link a bunch of stuff together to create a static library file. The "bunch of - stuff" consists of the list of object files supplied as *objects*, the extra - object files supplied to :meth:`add_link_object` and/or - :meth:`set_link_objects`, the libraries supplied to :meth:`add_library` and/or - :meth:`set_libraries`, and the libraries supplied as *libraries* (if any). - - *output_libname* should be a library name, not a filename; the filename will be - inferred from the library name. *output_dir* is the directory where the library - file will be put. - - .. XXX defaults to what? - - *debug* is a boolean; if true, debugging information will be included in the - library (note that on most platforms, it is the compile step where this matters: - the *debug* flag is included here just for consistency). - - *target_lang* is the target language for which the given objects are being - compiled. This allows specific linkage time treatment of certain languages. - - Raises :exc:`LibError` on failure. - - - .. method:: CCompiler.link(target_desc, objects, output_filename[, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, target_lang=None]) - - Link a bunch of stuff together to create an executable or shared library file. - - The "bunch of stuff" consists of the list of object files supplied as *objects*. - *output_filename* should be a filename. If *output_dir* is supplied, - *output_filename* is relative to it (i.e. *output_filename* can provide - directory components if needed). - - *libraries* is a list of libraries to link against. These are library names, - not filenames, since they're translated into filenames in a platform-specific - way (eg. *foo* becomes :file:`libfoo.a` on Unix and :file:`foo.lib` on - DOS/Windows). However, they can include a directory component, which means the - linker will look in that specific directory rather than searching all the normal - locations. - - *library_dirs*, if supplied, should be a list of directories to search for - libraries that were specified as bare library names (ie. no directory - component). These are on top of the system default and those supplied to - :meth:`add_library_dir` and/or :meth:`set_library_dirs`. *runtime_library_dirs* - is a list of directories that will be embedded into the shared library and used - to search for other shared libraries that \*it\* depends on at run-time. (This - may only be relevant on Unix.) - - *export_symbols* is a list of symbols that the shared library will export. - (This appears to be relevant only on Windows.) - - *debug* is as for :meth:`compile` and :meth:`create_static_lib`, with the - slight distinction that it actually matters on most platforms (as opposed to - :meth:`create_static_lib`, which includes a *debug* flag mostly for form's - sake). - - *extra_preargs* and *extra_postargs* are as for :meth:`compile` (except of - course that they supply command-line arguments for the particular linker being - used). - - *target_lang* is the target language for which the given objects are being - compiled. This allows specific linkage time treatment of certain languages. - - Raises :exc:`LinkError` on failure. - - - .. method:: CCompiler.link_executable(objects, output_progname[, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, debug=0, extra_preargs=None, extra_postargs=None, target_lang=None]) - - Link an executable. *output_progname* is the name of the file executable, while - *objects* are a list of object filenames to link in. Other arguments are as for - the :meth:`link` method. - - - .. method:: CCompiler.link_shared_lib(objects, output_libname[, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, target_lang=None]) - - Link a shared library. *output_libname* is the name of the output library, - while *objects* is a list of object filenames to link in. Other arguments are - as for the :meth:`link` method. - - - .. method:: CCompiler.link_shared_object(objects, output_filename[, output_dir=None, libraries=None, library_dirs=None, runtime_library_dirs=None, export_symbols=None, debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, target_lang=None]) - - Link a shared object. *output_filename* is the name of the shared object that - will be created, while *objects* is a list of object filenames to link in. - Other arguments are as for the :meth:`link` method. - - - .. method:: CCompiler.preprocess(source[, output_file=None, macros=None, include_dirs=None, extra_preargs=None, extra_postargs=None]) - - Preprocess a single C/C++ source file, named in *source*. Output will be written - to file named *output_file*, or *stdout* if *output_file* not supplied. - *macros* is a list of macro definitions as for :meth:`compile`, which will - augment the macros set with :meth:`define_macro` and :meth:`undefine_macro`. - *include_dirs* is a list of directory names that will be added to the default - list, in the same way as :meth:`add_include_dir`. - - Raises :exc:`PreprocessError` on failure. - - The following utility methods are defined by the :class:`CCompiler` class, for - use by the various concrete subclasses. - - - .. method:: CCompiler.executable_filename(basename[, strip_dir=0, output_dir='']) - - Returns the filename of the executable for the given *basename*. Typically for - non-Windows platforms this is the same as the basename, while Windows will get - a :file:`.exe` added. - - - .. method:: CCompiler.library_filename(libname[, lib_type='static', strip_dir=0, output_dir='']) - - Returns the filename for the given library name on the current platform. On Unix - a library with *lib_type* of ``'static'`` will typically be of the form - :file:`liblibname.a`, while a *lib_type* of ``'dynamic'`` will be of the form - :file:`liblibname.so`. - - - .. method:: CCompiler.object_filenames(source_filenames[, strip_dir=0, output_dir='']) - - Returns the name of the object files for the given source files. - *source_filenames* should be a list of filenames. - - - .. method:: CCompiler.shared_object_filename(basename[, strip_dir=0, output_dir='']) - - Returns the name of a shared object file for the given file name *basename*. - - - .. method:: CCompiler.execute(func, args[, msg=None, level=1]) - - Invokes :func:`distutils.util.execute`. This method invokes a Python function - *func* with the given arguments *args*, after logging and taking into account - the *dry_run* flag. - - - .. method:: CCompiler.spawn(cmd) - - Invokes :func:`distutils.util.spawn`. This invokes an external process to run - the given command. - - - .. method:: CCompiler.mkpath(name[, mode=511]) - - Invokes :func:`distutils.dir_util.mkpath`. This creates a directory and any - missing ancestor directories. - - - .. method:: CCompiler.move_file(src, dst) - - Invokes :meth:`distutils.file_util.move_file`. Renames *src* to *dst*. - - - .. method:: CCompiler.announce(msg[, level=1]) - - Write a message using :func:`distutils.log.debug`. - - - .. method:: CCompiler.warn(msg) - - Write a warning message *msg* to standard error. - - - .. method:: CCompiler.debug_print(msg) - - If the *debug* flag is set on this :class:`CCompiler` instance, print *msg* to - standard output, otherwise do nothing. - -.. % \subsection{Compiler-specific modules} -.. % -.. % The following modules implement concrete subclasses of the abstract -.. % \class{CCompiler} class. They should not be instantiated directly, but should -.. % be created using \function{distutils.ccompiler.new_compiler()} factory -.. % function. - - -:mod:`distutils.unixccompiler` --- Unix C Compiler -================================================== - -.. module:: distutils.unixccompiler - :synopsis: UNIX C Compiler - - -This module provides the :class:`UnixCCompiler` class, a subclass of -:class:`CCompiler` that handles the typical Unix-style command-line C compiler: - -* macros defined with :option:`!-Dname[=value]` - -* macros undefined with :option:`!-Uname` - -* include search directories specified with :option:`!-Idir` - -* libraries specified with :option:`!-llib` - -* library search directories specified with :option:`!-Ldir` - -* compile handled by :program:`cc` (or similar) executable with :option:`!-c` - option: compiles :file:`.c` to :file:`.o` - -* link static library handled by :program:`ar` command (possibly with - :program:`ranlib`) - -* link shared library handled by :program:`cc` :option:`!-shared` - - -:mod:`distutils.msvccompiler` --- Microsoft Compiler -==================================================== - -.. module:: distutils.msvccompiler - :synopsis: Microsoft Compiler - -.. XXX: This is *waaaaay* out of date! - -This module provides :class:`MSVCCompiler`, an implementation of the abstract -:class:`CCompiler` class for Microsoft Visual Studio. Typically, extension -modules need to be compiled with the same compiler that was used to compile -Python. For Python 2.3 and earlier, the compiler was Visual Studio 6. For Python -2.4 and 2.5, the compiler is Visual Studio .NET 2003. - -:class:`MSVCCompiler` will normally choose the right compiler, linker etc. on -its own. To override this choice, the environment variables *DISTUTILS_USE_SDK* -and *MSSdk* must be both set. *MSSdk* indicates that the current environment has -been setup by the SDK's ``SetEnv.Cmd`` script, or that the environment variables -had been registered when the SDK was installed; *DISTUTILS_USE_SDK* indicates -that the distutils user has made an explicit choice to override the compiler -selection by :class:`MSVCCompiler`. - - -:mod:`distutils.bcppcompiler` --- Borland Compiler -================================================== - -.. module:: distutils.bcppcompiler - - -This module provides :class:`BorlandCCompiler`, a subclass of the abstract -:class:`CCompiler` class for the Borland C++ compiler. - - -:mod:`distutils.cygwincompiler` --- Cygwin Compiler -=================================================== - -.. module:: distutils.cygwinccompiler - - -This module provides the :class:`CygwinCCompiler` class, a subclass of -:class:`UnixCCompiler` that handles the Cygwin port of the GNU C compiler to -Windows. It also contains the Mingw32CCompiler class which handles the mingw32 -port of GCC (same as cygwin in no-cygwin mode). - - -:mod:`distutils.archive_util` --- Archiving utilities -====================================================== - -.. module:: distutils.archive_util - :synopsis: Utility functions for creating archive files (tarballs, zip files, ...) - - -This module provides a few functions for creating archive files, such as -tarballs or zipfiles. - - -.. function:: make_archive(base_name, format[, root_dir=None, base_dir=None, verbose=0, dry_run=0]) - - Create an archive file (eg. ``zip`` or ``tar``). *base_name* is the name of - the file to create, minus any format-specific extension; *format* is the - archive format: one of ``zip``, ``tar``, ``gztar``, ``bztar``, ``xztar``, or - ``ztar``. *root_dir* is a directory that will be the root directory of the - archive; ie. we typically ``chdir`` into *root_dir* before creating the - archive. *base_dir* is the directory where we start archiving from; ie. - *base_dir* will be the common prefix of all files and directories in the - archive. *root_dir* and *base_dir* both default to the current directory. - Returns the name of the archive file. - - .. versionchanged:: 3.5 - Added support for the ``xztar`` format. - - -.. function:: make_tarball(base_name, base_dir[, compress='gzip', verbose=0, dry_run=0]) - - 'Create an (optional compressed) archive as a tar file from all files in and - under *base_dir*. *compress* must be ``'gzip'`` (the default), - ``'bzip2'``, ``'xz'``, ``'compress'``, or ``None``. For the ``'compress'`` - method the compression utility named by :program:`compress` must be on the - default program search path, so this is probably Unix-specific. The output - tar file will be named :file:`base_dir.tar`, possibly plus the appropriate - compression extension (``.gz``, ``.bz2``, ``.xz`` or ``.Z``). Return the - output filename. - - .. versionchanged:: 3.5 - Added support for the ``xz`` compression. - - -.. function:: make_zipfile(base_name, base_dir[, verbose=0, dry_run=0]) - - Create a zip file from all files in and under *base_dir*. The output zip file - will be named *base_name* + :file:`.zip`. Uses either the :mod:`zipfile` Python - module (if available) or the InfoZIP :file:`zip` utility (if installed and - found on the default search path). If neither tool is available, raises - :exc:`DistutilsExecError`. Returns the name of the output zip file. - - -:mod:`distutils.dep_util` --- Dependency checking -================================================= - -.. module:: distutils.dep_util - :synopsis: Utility functions for simple dependency checking - - -This module provides functions for performing simple, timestamp-based -dependency of files and groups of files; also, functions based entirely on such -timestamp dependency analysis. - - -.. function:: newer(source, target) - - Return true if *source* exists and is more recently modified than *target*, or - if *source* exists and *target* doesn't. Return false if both exist and *target* - is the same age or newer than *source*. Raise :exc:`DistutilsFileError` if - *source* does not exist. - - -.. function:: newer_pairwise(sources, targets) - - Walk two filename lists in parallel, testing if each source is newer than its - corresponding target. Return a pair of lists (*sources*, *targets*) where - source is newer than target, according to the semantics of :func:`newer`. - - .. % % equivalent to a listcomp... - - -.. function:: newer_group(sources, target[, missing='error']) - - Return true if *target* is out-of-date with respect to any file listed in - *sources*. In other words, if *target* exists and is newer than every file in - *sources*, return false; otherwise return true. *missing* controls what we do - when a source file is missing; the default (``'error'``) is to blow up with an - :exc:`OSError` from inside :func:`os.stat`; if it is ``'ignore'``, we silently - drop any missing source files; if it is ``'newer'``, any missing source files - make us assume that *target* is out-of-date (this is handy in "dry-run" mode: - it'll make you pretend to carry out commands that wouldn't work because inputs - are missing, but that doesn't matter because you're not actually going to run - the commands). - - -:mod:`distutils.dir_util` --- Directory tree operations -======================================================= - -.. module:: distutils.dir_util - :synopsis: Utility functions for operating on directories and directory trees - - -This module provides functions for operating on directories and trees of -directories. - - -.. function:: mkpath(name[, mode=0o777, verbose=0, dry_run=0]) - - Create a directory and any missing ancestor directories. If the directory - already exists (or if *name* is the empty string, which means the current - directory, which of course exists), then do nothing. Raise - :exc:`DistutilsFileError` if unable to create some directory along the way (eg. - some sub-path exists, but is a file rather than a directory). If *verbose* is - true, print a one-line summary of each mkdir to stdout. Return the list of - directories actually created. - - -.. function:: create_tree(base_dir, files[, mode=0o777, verbose=0, dry_run=0]) - - Create all the empty directories under *base_dir* needed to put *files* there. - *base_dir* is just the name of a directory which doesn't necessarily exist - yet; *files* is a list of filenames to be interpreted relative to *base_dir*. - *base_dir* + the directory portion of every file in *files* will be created if - it doesn't already exist. *mode*, *verbose* and *dry_run* flags are as for - :func:`mkpath`. - - -.. function:: copy_tree(src, dst[, preserve_mode=1, preserve_times=1, preserve_symlinks=0, update=0, verbose=0, dry_run=0]) - - Copy an entire directory tree *src* to a new location *dst*. Both *src* and - *dst* must be directory names. If *src* is not a directory, raise - :exc:`DistutilsFileError`. If *dst* does not exist, it is created with - :func:`mkpath`. The end result of the copy is that every file in *src* is - copied to *dst*, and directories under *src* are recursively copied to *dst*. - Return the list of files that were copied or might have been copied, using their - output name. The return value is unaffected by *update* or *dry_run*: it is - simply the list of all files under *src*, with the names changed to be under - *dst*. - - *preserve_mode* and *preserve_times* are the same as for - :func:`distutils.file_util.copy_file`; note that they only apply to - regular files, not to - directories. If *preserve_symlinks* is true, symlinks will be copied as - symlinks (on platforms that support them!); otherwise (the default), the - destination of the symlink will be copied. *update* and *verbose* are the same - as for :func:`copy_file`. - - Files in *src* that begin with :file:`.nfs` are skipped (more information on - these files is available in answer D2 of the `NFS FAQ page - <http://nfs.sourceforge.net/#section_d>`_). - - .. versionchanged:: 3.3.1 - NFS files are ignored. - -.. function:: remove_tree(directory[, verbose=0, dry_run=0]) - - Recursively remove *directory* and all files and directories underneath it. Any - errors are ignored (apart from being reported to ``sys.stdout`` if *verbose* is - true). - - -:mod:`distutils.file_util` --- Single file operations -===================================================== - -.. module:: distutils.file_util - :synopsis: Utility functions for operating on single files - - -This module contains some utility functions for operating on individual files. - - -.. function:: copy_file(src, dst[, preserve_mode=1, preserve_times=1, update=0, link=None, verbose=0, dry_run=0]) - - Copy file *src* to *dst*. If *dst* is a directory, then *src* is copied there - with the same name; otherwise, it must be a filename. (If the file exists, it - will be ruthlessly clobbered.) If *preserve_mode* is true (the default), the - file's mode (type and permission bits, or whatever is analogous on the - current platform) is copied. If *preserve_times* is true (the default), the - last-modified and last-access times are copied as well. If *update* is true, - *src* will only be copied if *dst* does not exist, or if *dst* does exist but - is older than *src*. - - *link* allows you to make hard links (using :func:`os.link`) or symbolic links - (using :func:`os.symlink`) instead of copying: set it to ``'hard'`` or - ``'sym'``; if it is ``None`` (the default), files are copied. Don't set *link* - on systems that don't support it: :func:`copy_file` doesn't check if hard or - symbolic linking is available. It uses :func:`_copy_file_contents` to copy file - contents. - - Return a tuple ``(dest_name, copied)``: *dest_name* is the actual name of the - output file, and *copied* is true if the file was copied (or would have been - copied, if *dry_run* true). - - .. % XXX if the destination file already exists, we clobber it if - .. % copying, but blow up if linking. Hmmm. And I don't know what - .. % macostools.copyfile() does. Should definitely be consistent, and - .. % should probably blow up if destination exists and we would be - .. % changing it (ie. it's not already a hard/soft link to src OR - .. % (not update) and (src newer than dst)). - - -.. function:: move_file(src, dst[, verbose, dry_run]) - - Move file *src* to *dst*. If *dst* is a directory, the file will be moved into - it with the same name; otherwise, *src* is just renamed to *dst*. Returns the - new full name of the file. - - .. warning:: - - Handles cross-device moves on Unix using :func:`copy_file`. What about - other systems? - - -.. function:: write_file(filename, contents) - - Create a file called *filename* and write *contents* (a sequence of strings - without line terminators) to it. - - -:mod:`distutils.util` --- Miscellaneous other utility functions -=============================================================== - -.. module:: distutils.util - :synopsis: Miscellaneous other utility functions - - -This module contains other assorted bits and pieces that don't fit into any -other utility module. - - -.. function:: get_platform() - - Return a string that identifies the current platform. This is used mainly to - distinguish platform-specific build directories and platform-specific built - distributions. Typically includes the OS name and version and the - architecture (as supplied by 'os.uname()'), although the exact information - included depends on the OS; e.g., on Linux, the kernel version isn't - particularly important. - - Examples of returned values: - - * ``linux-i586`` - * ``linux-alpha`` - * ``solaris-2.6-sun4u`` - - For non-POSIX platforms, currently just returns ``sys.platform``. - - For macOS systems the OS version reflects the minimal version on which - binaries will run (that is, the value of ``MACOSX_DEPLOYMENT_TARGET`` - during the build of Python), not the OS version of the current system. - - For universal binary builds on macOS the architecture value reflects - the universal binary status instead of the architecture of the current - processor. For 32-bit universal binaries the architecture is ``fat``, - for 64-bit universal binaries the architecture is ``fat64``, and - for 4-way universal binaries the architecture is ``universal``. Starting - from Python 2.7 and Python 3.2 the architecture ``fat3`` is used for - a 3-way universal build (ppc, i386, x86_64) and ``intel`` is used for - a universal build with the i386 and x86_64 architectures - - Examples of returned values on macOS: - - * ``macosx-10.3-ppc`` - - * ``macosx-10.3-fat`` - - * ``macosx-10.5-universal`` - - * ``macosx-10.6-intel`` - - For AIX, Python 3.9 and later return a string starting with "aix", followed - by additional fields (separated by ``'-'``) that represent the combined - values of AIX Version, Release and Technology Level (first field), Build Date - (second field), and bit-size (third field). Python 3.8 and earlier returned - only a single additional field with the AIX Version and Release. - - Examples of returned values on AIX: - - * ``aix-5307-0747-32`` # 32-bit build on AIX ``oslevel -s``: 5300-07-00-0000 - - * ``aix-7105-1731-64`` # 64-bit build on AIX ``oslevel -s``: 7100-05-01-1731 - - * ``aix-7.2`` # Legacy form reported in Python 3.8 and earlier - - .. versionchanged:: 3.9 - The AIX platform string format now also includes the technology level, - build date, and ABI bit-size. - - -.. function:: convert_path(pathname) - - Return 'pathname' as a name that will work on the native filesystem, i.e. split - it on '/' and put it back together again using the current directory separator. - Needed because filenames in the setup script are always supplied in Unix style, - and have to be converted to the local convention before we can actually use them - in the filesystem. Raises :exc:`ValueError` on non-Unix-ish systems if - *pathname* either starts or ends with a slash. - - -.. function:: change_root(new_root, pathname) - - Return *pathname* with *new_root* prepended. If *pathname* is relative, this is - equivalent to ``os.path.join(new_root,pathname)`` Otherwise, it requires making - *pathname* relative and then joining the two, which is tricky on DOS/Windows. - - -.. function:: check_environ() - - Ensure that 'os.environ' has all the environment variables we guarantee that - users can use in config files, command-line options, etc. Currently this - includes: - - * :envvar:`HOME` - user's home directory (Unix only) - * :envvar:`PLAT` - description of the current platform, including hardware and - OS (see :func:`get_platform`) - - -.. function:: subst_vars(s, local_vars) - - Perform shell/Perl-style variable substitution on *s*. Every occurrence of - ``$`` followed by a name is considered a variable, and variable is substituted - by the value found in the *local_vars* dictionary, or in ``os.environ`` if it's - not in *local_vars*. *os.environ* is first checked/augmented to guarantee that - it contains certain values: see :func:`check_environ`. Raise :exc:`ValueError` - for any variables not found in either *local_vars* or ``os.environ``. - - Note that this is not a full-fledged string interpolation function. A valid - ``$variable`` can consist only of upper and lower case letters, numbers and an - underscore. No { } or ( ) style quoting is available. - - -.. function:: split_quoted(s) - - Split a string up according to Unix shell-like rules for quotes and backslashes. - In short: words are delimited by spaces, as long as those spaces are not escaped - by a backslash, or inside a quoted string. Single and double quotes are - equivalent, and the quote characters can be backslash-escaped. The backslash is - stripped from any two-character escape sequence, leaving only the escaped - character. The quote characters are stripped from any quoted string. Returns a - list of words. - - .. % Should probably be moved into the standard library. - - -.. function:: execute(func, args[, msg=None, verbose=0, dry_run=0]) - - Perform some action that affects the outside world (for instance, writing to the - filesystem). Such actions are special because they are disabled by the - *dry_run* flag. This method takes care of all that bureaucracy for you; all - you have to do is supply the function to call and an argument tuple for it (to - embody the "external action" being performed), and an optional message to print. - - -.. function:: strtobool(val) - - Convert a string representation of truth to true (1) or false (0). - - True values are ``y``, ``yes``, ``t``, ``true``, ``on`` and ``1``; false values - are ``n``, ``no``, ``f``, ``false``, ``off`` and ``0``. Raises - :exc:`ValueError` if *val* is anything else. - - -.. function:: byte_compile(py_files[, optimize=0, force=0, prefix=None, base_dir=None, verbose=1, dry_run=0, direct=None]) - - Byte-compile a collection of Python source files to :file:`.pyc` files in a - :file:`__pycache__` subdirectory (see :pep:`3147` and :pep:`488`). - *py_files* is a list of files to compile; any files that don't end in - :file:`.py` are silently skipped. *optimize* must be one of the following: - - * ``0`` - don't optimize - * ``1`` - normal optimization (like ``python -O``) - * ``2`` - extra optimization (like ``python -OO``) - - If *force* is true, all files are recompiled regardless of timestamps. - - The source filename encoded in each :term:`bytecode` file defaults to the filenames - listed in *py_files*; you can modify these with *prefix* and *basedir*. - *prefix* is a string that will be stripped off of each source filename, and - *base_dir* is a directory name that will be prepended (after *prefix* is - stripped). You can supply either or both (or neither) of *prefix* and - *base_dir*, as you wish. - - If *dry_run* is true, doesn't actually do anything that would affect the - filesystem. - - Byte-compilation is either done directly in this interpreter process with the - standard :mod:`py_compile` module, or indirectly by writing a temporary script - and executing it. Normally, you should let :func:`byte_compile` figure out to - use direct compilation or not (see the source for details). The *direct* flag - is used by the script generated in indirect mode; unless you know what you're - doing, leave it set to ``None``. - - .. versionchanged:: 3.2.3 - Create ``.pyc`` files with an :func:`import magic tag - <imp.get_tag>` in their name, in a :file:`__pycache__` subdirectory - instead of files without tag in the current directory. - - .. versionchanged:: 3.5 - Create ``.pyc`` files according to :pep:`488`. - - -.. function:: rfc822_escape(header) - - Return a version of *header* escaped for inclusion in an :rfc:`822` header, by - ensuring there are 8 spaces space after each newline. Note that it does no other - modification of the string. - - .. % this _can_ be replaced - -.. % \subsection{Distutils objects} - - -:mod:`distutils.dist` --- The Distribution class -================================================ - -.. module:: distutils.dist - :synopsis: Provides the Distribution class, which represents the module distribution being - built/installed/distributed - - -This module provides the :class:`~distutils.core.Distribution` class, which -represents the module distribution being built/installed/distributed. - - -:mod:`distutils.extension` --- The Extension class -================================================== - -.. module:: distutils.extension - :synopsis: Provides the Extension class, used to describe C/C++ extension modules in setup - scripts - - -This module provides the :class:`Extension` class, used to describe C/C++ -extension modules in setup scripts. - -.. % \subsection{Ungrouped modules} -.. % The following haven't been moved into a more appropriate section yet. - - -:mod:`distutils.debug` --- Distutils debug mode -=============================================== - -.. module:: distutils.debug - :synopsis: Provides the debug flag for distutils - - -This module provides the DEBUG flag. - - -:mod:`distutils.errors` --- Distutils exceptions -================================================ - -.. module:: distutils.errors - :synopsis: Provides standard distutils exceptions - - -Provides exceptions used by the Distutils modules. Note that Distutils modules -may raise standard exceptions; in particular, SystemExit is usually raised for -errors that are obviously the end-user's fault (eg. bad command-line arguments). - -This module is safe to use in ``from ... import *`` mode; it only exports -symbols whose names start with ``Distutils`` and end with ``Error``. - - -:mod:`distutils.fancy_getopt` --- Wrapper around the standard getopt module -=========================================================================== - -.. module:: distutils.fancy_getopt - :synopsis: Additional getopt functionality - - -This module provides a wrapper around the standard :mod:`getopt` module that -provides the following additional features: - -* short and long options are tied together - -* options have help strings, so :func:`fancy_getopt` could potentially create a - complete usage summary - -* options set attributes of a passed-in object - -* boolean options can have "negative aliases" --- eg. if :option:`!--quiet` is - the "negative alias" of :option:`!--verbose`, then :option:`!--quiet` on the - command line sets *verbose* to false. - -.. function:: fancy_getopt(options, negative_opt, object, args) - - Wrapper function. *options* is a list of ``(long_option, short_option, - help_string)`` 3-tuples as described in the constructor for - :class:`FancyGetopt`. *negative_opt* should be a dictionary mapping option names - to option names, both the key and value should be in the *options* list. - *object* is an object which will be used to store values (see the :meth:`getopt` - method of the :class:`FancyGetopt` class). *args* is the argument list. Will use - ``sys.argv[1:]`` if you pass ``None`` as *args*. - - -.. function:: wrap_text(text, width) - - Wraps *text* to less than *width* wide. - - -.. class:: FancyGetopt([option_table=None]) - - The option_table is a list of 3-tuples: ``(long_option, short_option, - help_string)`` - - If an option takes an argument, its *long_option* should have ``'='`` appended; - *short_option* should just be a single character, no ``':'`` in any case. - *short_option* should be ``None`` if a *long_option* doesn't have a - corresponding *short_option*. All option tuples must have long options. - -The :class:`FancyGetopt` class provides the following methods: - - -.. method:: FancyGetopt.getopt([args=None, object=None]) - - Parse command-line options in args. Store as attributes on *object*. - - If *args* is ``None`` or not supplied, uses ``sys.argv[1:]``. If *object* is - ``None`` or not supplied, creates a new :class:`OptionDummy` instance, stores - option values there, and returns a tuple ``(args, object)``. If *object* is - supplied, it is modified in place and :func:`getopt` just returns *args*; in - both cases, the returned *args* is a modified copy of the passed-in *args* list, - which is left untouched. - - .. % and args returned are? - - -.. method:: FancyGetopt.get_option_order() - - Returns the list of ``(option, value)`` tuples processed by the previous run of - :meth:`getopt` Raises :exc:`RuntimeError` if :meth:`getopt` hasn't been called - yet. - - -.. method:: FancyGetopt.generate_help([header=None]) - - Generate help text (a list of strings, one per suggested line of output) from - the option table for this :class:`FancyGetopt` object. - - If supplied, prints the supplied *header* at the top of the help. - - -:mod:`distutils.filelist` --- The FileList class -================================================ - -.. module:: distutils.filelist - :synopsis: The FileList class, used for poking about the file system and - building lists of files. - - -This module provides the :class:`FileList` class, used for poking about the -filesystem and building lists of files. - - -:mod:`distutils.log` --- Simple :pep:`282`-style logging -======================================================== - -.. module:: distutils.log - :synopsis: A simple logging mechanism, :pep:`282`-style - - -:mod:`distutils.spawn` --- Spawn a sub-process -============================================== - -.. module:: distutils.spawn - :synopsis: Provides the spawn() function - - -This module provides the :func:`spawn` function, a front-end to various -platform-specific functions for launching another program in a sub-process. -Also provides :func:`find_executable` to search the path for a given executable -name. - - -:mod:`distutils.sysconfig` --- System configuration information -=============================================================== - -.. module:: distutils.sysconfig - :synopsis: Low-level access to configuration information of the Python interpreter. -.. deprecated:: 3.10 - :mod:`distutils.sysconfig` has been merged into :mod:`sysconfig`. -.. moduleauthor:: Fred L. Drake, Jr. <fdrake@acm.org> -.. moduleauthor:: Greg Ward <gward@python.net> -.. sectionauthor:: Fred L. Drake, Jr. <fdrake@acm.org> - - -The :mod:`distutils.sysconfig` module provides access to Python's low-level -configuration information. The specific configuration variables available -depend heavily on the platform and configuration. The specific variables depend -on the build process for the specific version of Python being run; the variables -are those found in the :file:`Makefile` and configuration header that are -installed with Python on Unix systems. The configuration header is called -:file:`pyconfig.h` for Python versions starting with 2.2, and :file:`config.h` -for earlier versions of Python. - -Some additional functions are provided which perform some useful manipulations -for other parts of the :mod:`distutils` package. - - -.. data:: PREFIX - - The result of ``os.path.normpath(sys.prefix)``. - - -.. data:: EXEC_PREFIX - - The result of ``os.path.normpath(sys.exec_prefix)``. - - -.. function:: get_config_var(name) - - Return the value of a single variable. This is equivalent to - ``get_config_vars().get(name)``. - - -.. function:: get_config_vars(...) - - Return a set of variable definitions. If there are no arguments, this returns a - dictionary mapping names of configuration variables to values. If arguments are - provided, they should be strings, and the return value will be a sequence giving - the associated values. If a given name does not have a corresponding value, - ``None`` will be included for that variable. - - -.. function:: get_config_h_filename() - - Return the full path name of the configuration header. For Unix, this will be - the header generated by the :program:`configure` script; for other platforms the - header will have been supplied directly by the Python source distribution. The - file is a platform-specific text file. - - -.. function:: get_makefile_filename() - - Return the full path name of the :file:`Makefile` used to build Python. For - Unix, this will be a file generated by the :program:`configure` script; the - meaning for other platforms will vary. The file is a platform-specific text - file, if it exists. This function is only useful on POSIX platforms. - -The following functions are deprecated together with this module and they -have no direct replacement. - - -.. function:: get_python_inc([plat_specific[, prefix]]) - - Return the directory for either the general or platform-dependent C include - files. If *plat_specific* is true, the platform-dependent include directory is - returned; if false or omitted, the platform-independent directory is returned. - If *prefix* is given, it is used as either the prefix instead of - :const:`PREFIX`, or as the exec-prefix instead of :const:`EXEC_PREFIX` if - *plat_specific* is true. - - -.. function:: get_python_lib([plat_specific[, standard_lib[, prefix]]]) - - Return the directory for either the general or platform-dependent library - installation. If *plat_specific* is true, the platform-dependent include - directory is returned; if false or omitted, the platform-independent directory - is returned. If *prefix* is given, it is used as either the prefix instead of - :const:`PREFIX`, or as the exec-prefix instead of :const:`EXEC_PREFIX` if - *plat_specific* is true. If *standard_lib* is true, the directory for the - standard library is returned rather than the directory for the installation of - third-party extensions. - -The following function is only intended for use within the :mod:`distutils` -package. - - -.. function:: customize_compiler(compiler) - - Do any platform-specific customization of a - :class:`distutils.ccompiler.CCompiler` instance. - - This function is only needed on Unix at this time, but should be called - consistently to support forward-compatibility. It inserts the information that - varies across Unix flavors and is stored in Python's :file:`Makefile`. This - information includes the selected compiler, compiler and linker options, and the - extension used by the linker for shared objects. - -This function is even more special-purpose, and should only be used from -Python's own build procedures. - - -.. function:: set_python_build() - - Inform the :mod:`distutils.sysconfig` module that it is being used as part of - the build process for Python. This changes a lot of relative locations for - files, allowing them to be located in the build area rather than in an installed - Python. - - -:mod:`distutils.text_file` --- The TextFile class -================================================= - -.. module:: distutils.text_file - :synopsis: Provides the TextFile class, a simple interface to text files - - -This module provides the :class:`TextFile` class, which gives an interface to -text files that (optionally) takes care of stripping comments, ignoring blank -lines, and joining lines with backslashes. - - -.. class:: TextFile([filename=None, file=None, **options]) - - This class provides a file-like object that takes care of all the things you - commonly want to do when processing a text file that has some line-by-line - syntax: strip comments (as long as ``#`` is your comment character), skip blank - lines, join adjacent lines by escaping the newline (ie. backslash at end of - line), strip leading and/or trailing whitespace. All of these are optional and - independently controllable. - - The class provides a :meth:`warn` method so you can generate warning messages - that report physical line number, even if the logical line in question spans - multiple physical lines. Also provides :meth:`unreadline` for implementing - line-at-a-time lookahead. - - :class:`TextFile` instances are create with either *filename*, *file*, or both. - :exc:`RuntimeError` is raised if both are ``None``. *filename* should be a - string, and *file* a file object (or something that provides :meth:`readline` - and :meth:`close` methods). It is recommended that you supply at least - *filename*, so that :class:`TextFile` can include it in warning messages. If - *file* is not supplied, :class:`TextFile` creates its own using the - :func:`open` built-in function. - - The options are all boolean, and affect the values returned by :meth:`readline` - - .. tabularcolumns:: |l|L|l| - - +------------------+--------------------------------+---------+ - | option name | description | default | - +==================+================================+=========+ - | *strip_comments* | strip from ``'#'`` to | true | - | | end-of-line, as well as any | | - | | whitespace leading up to the | | - | | ``'#'``\ ---unless it is | | - | | escaped by a backslash | | - +------------------+--------------------------------+---------+ - | *lstrip_ws* | strip leading whitespace from | false | - | | each line before returning it | | - +------------------+--------------------------------+---------+ - | *rstrip_ws* | strip trailing whitespace | true | - | | (including line terminator!) | | - | | from each line before | | - | | returning it. | | - +------------------+--------------------------------+---------+ - | *skip_blanks* | skip lines that are empty | true | - | | \*after\* stripping comments | | - | | and whitespace. (If both | | - | | lstrip_ws and rstrip_ws are | | - | | false, then some lines may | | - | | consist of solely whitespace: | | - | | these will \*not\* be skipped, | | - | | even if *skip_blanks* is | | - | | true.) | | - +------------------+--------------------------------+---------+ - | *join_lines* | if a backslash is the last | false | - | | non-newline character on a | | - | | line after stripping comments | | - | | and whitespace, join the | | - | | following line to it to form | | - | | one logical line; if N | | - | | consecutive lines end with a | | - | | backslash, then N+1 physical | | - | | lines will be joined to form | | - | | one logical line. | | - +------------------+--------------------------------+---------+ - | *collapse_join* | strip leading whitespace from | false | - | | lines that are joined to their | | - | | predecessor; only matters if | | - | | ``(join_lines and not | | - | | lstrip_ws)`` | | - +------------------+--------------------------------+---------+ - - Note that since *rstrip_ws* can strip the trailing newline, the semantics of - :meth:`readline` must differ from those of the built-in file object's - :meth:`readline` method! In particular, :meth:`readline` returns ``None`` for - end-of-file: an empty string might just be a blank line (or an all-whitespace - line), if *rstrip_ws* is true but *skip_blanks* is not. - - - .. method:: TextFile.open(filename) - - Open a new file *filename*. This overrides any *file* or *filename* - constructor arguments. - - - .. method:: TextFile.close() - - Close the current file and forget everything we know about it (including the - filename and the current line number). - - - .. method:: TextFile.warn(msg[,line=None]) - - Print (to stderr) a warning message tied to the current logical line in the - current file. If the current logical line in the file spans multiple physical - lines, the warning refers to the whole range, such as ``"lines 3-5"``. If - *line* is supplied, it overrides the current line number; it may be a list or - tuple to indicate a range of physical lines, or an integer for a single - physical line. - - - .. method:: TextFile.readline() - - Read and return a single logical line from the current file (or from an internal - buffer if lines have previously been "unread" with :meth:`unreadline`). If the - *join_lines* option is true, this may involve reading multiple physical lines - concatenated into a single string. Updates the current line number, so calling - :meth:`warn` after :meth:`readline` emits a warning about the physical line(s) - just read. Returns ``None`` on end-of-file, since the empty string can occur - if *rstrip_ws* is true but *strip_blanks* is not. - - - .. method:: TextFile.readlines() - - Read and return the list of all logical lines remaining in the current file. - This updates the current line number to the last line of the file. - - - .. method:: TextFile.unreadline(line) - - Push *line* (a string) onto an internal buffer that will be checked by future - :meth:`readline` calls. Handy for implementing a parser with line-at-a-time - lookahead. Note that lines that are "unread" with :meth:`unreadline` are not - subsequently re-cleansed (whitespace stripped, or whatever) when read with - :meth:`readline`. If multiple calls are made to :meth:`unreadline` before a call - to :meth:`readline`, the lines will be returned most in most recent first order. - - -:mod:`distutils.version` --- Version number classes -=================================================== - -.. module:: distutils.version - :synopsis: Implements classes that represent module version numbers. - - -.. % todo -.. % \section{Distutils Commands} -.. % -.. % This part of Distutils implements the various Distutils commands, such -.. % as \code{build}, \code{install} \&c. Each command is implemented as a -.. % separate module, with the command name as the name of the module. - - -:mod:`distutils.cmd` --- Abstract base class for Distutils commands -=================================================================== - -.. module:: distutils.cmd - :synopsis: Provides the abstract base class :class:`~distutils.cmd.Command`. This class - is subclassed by the modules in the distutils.command subpackage. - - -This module supplies the abstract base class :class:`Command`. - - -.. class:: Command(dist) - - Abstract base class for defining command classes, the "worker bees" of the - Distutils. A useful analogy for command classes is to think of them as - subroutines with local variables called *options*. The options are declared - in :meth:`initialize_options` and defined (given their final values) in - :meth:`finalize_options`, both of which must be defined by every command - class. The distinction between the two is necessary because option values - might come from the outside world (command line, config file, ...), and any - options dependent on other options must be computed after these outside - influences have been processed --- hence :meth:`finalize_options`. The body - of the subroutine, where it does all its work based on the values of its - options, is the :meth:`run` method, which must also be implemented by every - command class. - - The class constructor takes a single argument *dist*, a - :class:`~distutils.core.Distribution` instance. - - -Creating a new Distutils command -================================ - -This section outlines the steps to create a new Distutils command. - -A new command lives in a module in the :mod:`distutils.command` package. There -is a sample template in that directory called :file:`command_template`. Copy -this file to a new module with the same name as the new command you're -implementing. This module should implement a class with the same name as the -module (and the command). So, for instance, to create the command -``peel_banana`` (so that users can run ``setup.py peel_banana``), you'd copy -:file:`command_template` to :file:`distutils/command/peel_banana.py`, then edit -it so that it's implementing the class :class:`peel_banana`, a subclass of -:class:`distutils.cmd.Command`. - -Subclasses of :class:`Command` must define the following methods. - -.. method:: Command.initialize_options() - - Set default values for all the options that this command supports. Note that - these defaults may be overridden by other commands, by the setup script, by - config files, or by the command-line. Thus, this is not the place to code - dependencies between options; generally, :meth:`initialize_options` - implementations are just a bunch of ``self.foo = None`` assignments. - - -.. method:: Command.finalize_options() - - Set final values for all the options that this command supports. This is - always called as late as possible, ie. after any option assignments from the - command-line or from other commands have been done. Thus, this is the place - to code option dependencies: if *foo* depends on *bar*, then it is safe to - set *foo* from *bar* as long as *foo* still has the same value it was - assigned in :meth:`initialize_options`. - - -.. method:: Command.run() - - A command's raison d'etre: carry out the action it exists to perform, controlled - by the options initialized in :meth:`initialize_options`, customized by other - commands, the setup script, the command-line, and config files, and finalized in - :meth:`finalize_options`. All terminal output and filesystem interaction should - be done by :meth:`run`. - - -.. attribute:: Command.sub_commands - - *sub_commands* formalizes the notion of a "family" of commands, - e.g. ``install`` as the parent with sub-commands ``install_lib``, - ``install_headers``, etc. The parent of a family of commands defines - *sub_commands* as a class attribute; it's a list of 2-tuples ``(command_name, - predicate)``, with *command_name* a string and *predicate* a function, a - string or ``None``. *predicate* is a method of the parent command that - determines whether the corresponding command is applicable in the current - situation. (E.g. ``install_headers`` is only applicable if we have any C - header files to install.) If *predicate* is ``None``, that command is always - applicable. - - *sub_commands* is usually defined at the *end* of a class, because - predicates can be methods of the class, so they must already have been - defined. The canonical example is the :command:`install` command. - - -:mod:`distutils.command` --- Individual Distutils commands -========================================================== - -.. module:: distutils.command - :synopsis: Contains one module for each standard Distutils command. - - -.. % \subsubsection{Individual Distutils commands} -.. % todo - - -:mod:`distutils.command.bdist` --- Build a binary installer -=========================================================== - -.. module:: distutils.command.bdist - :synopsis: Build a binary installer for a package - - -.. % todo - - -:mod:`distutils.command.bdist_packager` --- Abstract base class for packagers -============================================================================= - -.. module:: distutils.command.bdist_packager - :synopsis: Abstract base class for packagers - - -.. % todo - - -:mod:`distutils.command.bdist_dumb` --- Build a "dumb" installer -================================================================ - -.. module:: distutils.command.bdist_dumb - :synopsis: Build a "dumb" installer - a simple archive of files - - -.. % todo - - -:mod:`distutils.command.bdist_rpm` --- Build a binary distribution as a Redhat RPM and SRPM -=========================================================================================== - -.. module:: distutils.command.bdist_rpm - :synopsis: Build a binary distribution as a Redhat RPM and SRPM - - -.. % todo - - -:mod:`distutils.command.sdist` --- Build a source distribution -============================================================== - -.. module:: distutils.command.sdist - :synopsis: Build a source distribution - - -.. % todo - - -:mod:`distutils.command.build` --- Build all files of a package -=============================================================== - -.. module:: distutils.command.build - :synopsis: Build all files of a package - - -.. % todo - - -:mod:`distutils.command.build_clib` --- Build any C libraries in a package -========================================================================== - -.. module:: distutils.command.build_clib - :synopsis: Build any C libraries in a package - - -.. % todo - - -:mod:`distutils.command.build_ext` --- Build any extensions in a package -======================================================================== - -.. module:: distutils.command.build_ext - :synopsis: Build any extensions in a package - - -.. % todo - - -:mod:`distutils.command.build_py` --- Build the .py/.pyc files of a package -=========================================================================== - -.. module:: distutils.command.build_py - :synopsis: Build the .py/.pyc files of a package - - -.. class:: build_py - -.. class:: build_py_2to3 - - Alternative implementation of build_py which also runs the - 2to3 conversion library on each .py file that is going to be - installed. To use this in a setup.py file for a distribution - that is designed to run with both Python 2.x and 3.x, add:: - - try: - from distutils.command.build_py import build_py_2to3 as build_py - except ImportError: - from distutils.command.build_py import build_py - - to your setup.py, and later:: - - cmdclass = {'build_py': build_py} - - to the invocation of setup(). - - -:mod:`distutils.command.build_scripts` --- Build the scripts of a package -========================================================================= - -.. module:: distutils.command.build_scripts - :synopsis: Build the scripts of a package - - -.. % todo - - -:mod:`distutils.command.clean` --- Clean a package build area -============================================================= - -.. module:: distutils.command.clean - :synopsis: Clean a package build area - -This command removes the temporary files created by :command:`build` -and its subcommands, like intermediary compiled object files. With -the ``--all`` option, the complete build directory will be removed. - -Extension modules built :ref:`in place <distutils-build-ext-inplace>` -will not be cleaned, as they are not in the build directory. - - -:mod:`distutils.command.config` --- Perform package configuration -================================================================= - -.. module:: distutils.command.config - :synopsis: Perform package configuration - - -.. % todo - - -:mod:`distutils.command.install` --- Install a package -====================================================== - -.. module:: distutils.command.install - :synopsis: Install a package - - -.. % todo - - -:mod:`distutils.command.install_data` --- Install data files from a package -=========================================================================== - -.. module:: distutils.command.install_data - :synopsis: Install data files from a package - - -.. % todo - - -:mod:`distutils.command.install_headers` --- Install C/C++ header files from a package -====================================================================================== - -.. module:: distutils.command.install_headers - :synopsis: Install C/C++ header files from a package - - -.. % todo - - -:mod:`distutils.command.install_lib` --- Install library files from a package -============================================================================= - -.. module:: distutils.command.install_lib - :synopsis: Install library files from a package - - -.. % todo - - -:mod:`distutils.command.install_scripts` --- Install script files from a package -================================================================================ - -.. module:: distutils.command.install_scripts - :synopsis: Install script files from a package - - -.. % todo - - -:mod:`distutils.command.register` --- Register a module with the Python Package Index -===================================================================================== - -.. module:: distutils.command.register - :synopsis: Register a module with the Python Package Index - - -The ``register`` command registers the package with the Python Package Index. -This is described in more detail in :pep:`301`. - -.. % todo - - -:mod:`distutils.command.check` --- Check the meta-data of a package -=================================================================== - -.. module:: distutils.command.check - :synopsis: Check the meta-data of a package - - -The ``check`` command performs some tests on the meta-data of a package. -For example, it verifies that all required meta-data are provided as -the arguments passed to the :func:`setup` function. - -.. % todo diff --git a/Doc/distutils/builtdist.rst b/Doc/distutils/builtdist.rst deleted file mode 100644 index c1d9ea53..00000000 --- a/Doc/distutils/builtdist.rst +++ /dev/null @@ -1,392 +0,0 @@ -.. _built-dist: - -**************************** -Creating Built Distributions -**************************** - -.. include:: ./_setuptools_disclaimer.rst - -A "built distribution" is what you're probably used to thinking of either as a -"binary package" or an "installer" (depending on your background). It's not -necessarily binary, though, because it might contain only Python source code -and/or byte-code; and we don't call it a package, because that word is already -spoken for in Python. (And "installer" is a term specific to the world of -mainstream desktop systems.) - -A built distribution is how you make life as easy as possible for installers of -your module distribution: for users of RPM-based Linux systems, it's a binary -RPM; for Windows users, it's an executable installer; for Debian-based Linux -users, it's a Debian package; and so forth. Obviously, no one person will be -able to create built distributions for every platform under the sun, so the -Distutils are designed to enable module developers to concentrate on their -specialty---writing code and creating source distributions---while an -intermediary species called *packagers* springs up to turn source distributions -into built distributions for as many platforms as there are packagers. - -Of course, the module developer could be their own packager; or the packager could -be a volunteer "out there" somewhere who has access to a platform which the -original developer does not; or it could be software periodically grabbing new -source distributions and turning them into built distributions for as many -platforms as the software has access to. Regardless of who they are, a packager -uses the setup script and the :command:`bdist` command family to generate built -distributions. - -As a simple example, if I run the following command in the Distutils source -tree:: - - python setup.py bdist - -then the Distutils builds my module distribution (the Distutils itself in this -case), does a "fake" installation (also in the :file:`build` directory), and -creates the default type of built distribution for my platform. The default -format for built distributions is a "dumb" tar file on Unix, and a simple -executable installer on Windows. (That tar file is considered "dumb" because it -has to be unpacked in a specific location to work.) - -Thus, the above command on a Unix system creates -:file:`Distutils-1.0.{plat}.tar.gz`; unpacking this tarball from the right place -installs the Distutils just as though you had downloaded the source distribution -and run ``python setup.py install``. (The "right place" is either the root of -the filesystem or Python's :file:`{prefix}` directory, depending on the options -given to the :command:`bdist_dumb` command; the default is to make dumb -distributions relative to :file:`{prefix}`.) - -Obviously, for pure Python distributions, this isn't any simpler than just -running ``python setup.py install``\ ---but for non-pure distributions, which -include extensions that would need to be compiled, it can mean the difference -between someone being able to use your extensions or not. And creating "smart" -built distributions, such as an RPM package or an executable installer for -Windows, is far more convenient for users even if your distribution doesn't -include any extensions. - -The :command:`bdist` command has a :option:`!--formats` option, similar to the -:command:`sdist` command, which you can use to select the types of built -distribution to generate: for example, :: - - python setup.py bdist --format=zip - -would, when run on a Unix system, create -:file:`Distutils-1.0.{plat}.zip`\ ---again, this archive would be unpacked -from the root directory to install the Distutils. - -The available formats for built distributions are: - -+-------------+------------------------------+---------+ -| Format | Description | Notes | -+=============+==============================+=========+ -| ``gztar`` | gzipped tar file | \(1) | -| | (:file:`.tar.gz`) | | -+-------------+------------------------------+---------+ -| ``bztar`` | bzipped tar file | | -| | (:file:`.tar.bz2`) | | -+-------------+------------------------------+---------+ -| ``xztar`` | xzipped tar file | | -| | (:file:`.tar.xz`) | | -+-------------+------------------------------+---------+ -| ``ztar`` | compressed tar file | \(3) | -| | (:file:`.tar.Z`) | | -+-------------+------------------------------+---------+ -| ``tar`` | tar file (:file:`.tar`) | | -+-------------+------------------------------+---------+ -| ``zip`` | zip file (:file:`.zip`) | (2),(4) | -+-------------+------------------------------+---------+ -| ``rpm`` | RPM | \(5) | -+-------------+------------------------------+---------+ -| ``pkgtool`` | Solaris :program:`pkgtool` | | -+-------------+------------------------------+---------+ -| ``sdux`` | HP-UX :program:`swinstall` | | -+-------------+------------------------------+---------+ -| ``msi`` | Microsoft Installer. | | -+-------------+------------------------------+---------+ - -.. versionchanged:: 3.5 - Added support for the ``xztar`` format. - - -Notes: - -(1) - default on Unix - -(2) - default on Windows - -(3) - requires external :program:`compress` utility. - -(4) - requires either external :program:`zip` utility or :mod:`zipfile` module (part - of the standard Python library since Python 1.6) - -(5) - requires external :program:`rpm` utility, version 3.0.4 or better (use ``rpm - --version`` to find out which version you have) - -You don't have to use the :command:`bdist` command with the :option:`!--formats` -option; you can also use the command that directly implements the format you're -interested in. Some of these :command:`bdist` "sub-commands" actually generate -several similar formats; for instance, the :command:`bdist_dumb` command -generates all the "dumb" archive formats (``tar``, ``gztar``, ``bztar``, -``xztar``, ``ztar``, and ``zip``), and :command:`bdist_rpm` generates both -binary and source RPMs. The :command:`bdist` sub-commands, and the formats -generated by each, are: - -+--------------------------+-------------------------------------+ -| Command | Formats | -+==========================+=====================================+ -| :command:`bdist_dumb` | tar, gztar, bztar, xztar, ztar, zip | -+--------------------------+-------------------------------------+ -| :command:`bdist_rpm` | rpm, srpm | -+--------------------------+-------------------------------------+ - -The following sections give details on the individual :command:`bdist_\*` -commands. - - -.. .. _creating-dumb: - -.. Creating dumb built distributions -.. ================================= - -.. XXX Need to document absolute vs. prefix-relative packages here, but first - I have to implement it! - - -.. _creating-rpms: - -Creating RPM packages -===================== - -The RPM format is used by many popular Linux distributions, including Red Hat, -SuSE, and Mandrake. If one of these (or any of the other RPM-based Linux -distributions) is your usual environment, creating RPM packages for other users -of that same distribution is trivial. Depending on the complexity of your module -distribution and differences between Linux distributions, you may also be able -to create RPMs that work on different RPM-based distributions. - -The usual way to create an RPM of your module distribution is to run the -:command:`bdist_rpm` command:: - - python setup.py bdist_rpm - -or the :command:`bdist` command with the :option:`!--format` option:: - - python setup.py bdist --formats=rpm - -The former allows you to specify RPM-specific options; the latter allows you to -easily specify multiple formats in one run. If you need to do both, you can -explicitly specify multiple :command:`bdist_\*` commands and their options:: - - python setup.py bdist_rpm --packager="John Doe <jdoe@example.org>" - -Creating RPM packages is driven by a :file:`.spec` file, much as using the -Distutils is driven by the setup script. To make your life easier, the -:command:`bdist_rpm` command normally creates a :file:`.spec` file based on the -information you supply in the setup script, on the command line, and in any -Distutils configuration files. Various options and sections in the -:file:`.spec` file are derived from options in the setup script as follows: - -+------------------------------------------+----------------------------------------------+ -| RPM :file:`.spec` file option or section | Distutils setup script option | -+==========================================+==============================================+ -| Name | ``name`` | -+------------------------------------------+----------------------------------------------+ -| Summary (in preamble) | ``description`` | -+------------------------------------------+----------------------------------------------+ -| Version | ``version`` | -+------------------------------------------+----------------------------------------------+ -| Vendor | ``author`` and ``author_email``, | -| | or --- & ``maintainer`` and | -| | ``maintainer_email`` | -+------------------------------------------+----------------------------------------------+ -| Copyright | ``license`` | -+------------------------------------------+----------------------------------------------+ -| Url | ``url`` | -+------------------------------------------+----------------------------------------------+ -| %description (section) | ``long_description`` | -+------------------------------------------+----------------------------------------------+ - -Additionally, there are many options in :file:`.spec` files that don't have -corresponding options in the setup script. Most of these are handled through -options to the :command:`bdist_rpm` command as follows: - -+-------------------------------+-----------------------------+-------------------------+ -| RPM :file:`.spec` file option | :command:`bdist_rpm` option | default value | -| or section | | | -+===============================+=============================+=========================+ -| Release | ``release`` | "1" | -+-------------------------------+-----------------------------+-------------------------+ -| Group | ``group`` | "Development/Libraries" | -+-------------------------------+-----------------------------+-------------------------+ -| Vendor | ``vendor`` | (see above) | -+-------------------------------+-----------------------------+-------------------------+ -| Packager | ``packager`` | (none) | -+-------------------------------+-----------------------------+-------------------------+ -| Provides | ``provides`` | (none) | -+-------------------------------+-----------------------------+-------------------------+ -| Requires | ``requires`` | (none) | -+-------------------------------+-----------------------------+-------------------------+ -| Conflicts | ``conflicts`` | (none) | -+-------------------------------+-----------------------------+-------------------------+ -| Obsoletes | ``obsoletes`` | (none) | -+-------------------------------+-----------------------------+-------------------------+ -| Distribution | ``distribution_name`` | (none) | -+-------------------------------+-----------------------------+-------------------------+ -| BuildRequires | ``build_requires`` | (none) | -+-------------------------------+-----------------------------+-------------------------+ -| Icon | ``icon`` | (none) | -+-------------------------------+-----------------------------+-------------------------+ - -Obviously, supplying even a few of these options on the command-line would be -tedious and error-prone, so it's usually best to put them in the setup -configuration file, :file:`setup.cfg`\ ---see section :ref:`setup-config`. If -you distribute or package many Python module distributions, you might want to -put options that apply to all of them in your personal Distutils configuration -file (:file:`~/.pydistutils.cfg`). If you want to temporarily disable -this file, you can pass the :option:`!--no-user-cfg` option to :file:`setup.py`. - -There are three steps to building a binary RPM package, all of which are -handled automatically by the Distutils: - -#. create a :file:`.spec` file, which describes the package (analogous to the - Distutils setup script; in fact, much of the information in the setup script - winds up in the :file:`.spec` file) - -#. create the source RPM - -#. create the "binary" RPM (which may or may not contain binary code, depending - on whether your module distribution contains Python extensions) - -Normally, RPM bundles the last two steps together; when you use the Distutils, -all three steps are typically bundled together. - -If you wish, you can separate these three steps. You can use the -:option:`!--spec-only` option to make :command:`bdist_rpm` just create the -:file:`.spec` file and exit; in this case, the :file:`.spec` file will be -written to the "distribution directory"---normally :file:`dist/`, but -customizable with the :option:`!--dist-dir` option. (Normally, the :file:`.spec` -file winds up deep in the "build tree," in a temporary directory created by -:command:`bdist_rpm`.) - -.. % \XXX{this isn't implemented yet---is it needed?!} -.. % You can also specify a custom \file{.spec} file with the -.. % \longprogramopt{spec-file} option; used in conjunction with -.. % \longprogramopt{spec-only}, this gives you an opportunity to customize -.. % the \file{.spec} file manually: -.. % -.. % \ begin{verbatim} -.. % > python setup.py bdist_rpm --spec-only -.. % # ...edit dist/FooBar-1.0.spec -.. % > python setup.py bdist_rpm --spec-file=dist/FooBar-1.0.spec -.. % \ end{verbatim} -.. % -.. % (Although a better way to do this is probably to override the standard -.. % \command{bdist\_rpm} command with one that writes whatever else you want -.. % to the \file{.spec} file.) - - -.. _cross-compile-windows: - -Cross-compiling on Windows -========================== - -Starting with Python 2.6, distutils is capable of cross-compiling between -Windows platforms. In practice, this means that with the correct tools -installed, you can use a 32bit version of Windows to create 64bit extensions -and vice-versa. - -To build for an alternate platform, specify the :option:`!--plat-name` option -to the build command. Valid values are currently 'win32', and 'win-amd64'. -For example, on a 32bit version of Windows, you could execute:: - - python setup.py build --plat-name=win-amd64 - -to build a 64bit version of your extension. - -would create a 64bit installation executable on your 32bit version of Windows. - -To cross-compile, you must download the Python source code and cross-compile -Python itself for the platform you are targeting - it is not possible from a -binary installation of Python (as the .lib etc file for other platforms are -not included.) In practice, this means the user of a 32 bit operating -system will need to use Visual Studio 2008 to open the -:file:`PCbuild/PCbuild.sln` solution in the Python source tree and build the -"x64" configuration of the 'pythoncore' project before cross-compiling -extensions is possible. - -Note that by default, Visual Studio 2008 does not install 64bit compilers or -tools. You may need to reexecute the Visual Studio setup process and select -these tools (using Control Panel->[Add/Remove] Programs is a convenient way to -check or modify your existing install.) - -.. _postinstallation-script: - -The Postinstallation script ---------------------------- - -Starting with Python 2.3, a postinstallation script can be specified with the -:option:`!--install-script` option. The basename of the script must be -specified, and the script filename must also be listed in the scripts argument -to the setup function. - -This script will be run at installation time on the target system after all the -files have been copied, with ``argv[1]`` set to :option:`!-install`, and again at -uninstallation time before the files are removed with ``argv[1]`` set to -:option:`!-remove`. - -The installation script runs embedded in the windows installer, every output -(``sys.stdout``, ``sys.stderr``) is redirected into a buffer and will be -displayed in the GUI after the script has finished. - -Some functions especially useful in this context are available as additional -built-in functions in the installation script. - - -.. function:: directory_created(path) - file_created(path) - - These functions should be called when a directory or file is created by the - postinstall script at installation time. It will register *path* with the - uninstaller, so that it will be removed when the distribution is uninstalled. - To be safe, directories are only removed if they are empty. - - -.. function:: get_special_folder_path(csidl_string) - - This function can be used to retrieve special folder locations on Windows like - the Start Menu or the Desktop. It returns the full path to the folder. - *csidl_string* must be one of the following strings:: - - "CSIDL_APPDATA" - - "CSIDL_COMMON_STARTMENU" - "CSIDL_STARTMENU" - - "CSIDL_COMMON_DESKTOPDIRECTORY" - "CSIDL_DESKTOPDIRECTORY" - - "CSIDL_COMMON_STARTUP" - "CSIDL_STARTUP" - - "CSIDL_COMMON_PROGRAMS" - "CSIDL_PROGRAMS" - - "CSIDL_FONTS" - - If the folder cannot be retrieved, :exc:`OSError` is raised. - - Which folders are available depends on the exact Windows version, and probably - also the configuration. For details refer to Microsoft's documentation of the - :c:func:`SHGetSpecialFolderPath` function. - - -.. function:: create_shortcut(target, description, filename[, arguments[, workdir[, iconpath[, iconindex]]]]) - - This function creates a shortcut. *target* is the path to the program to be - started by the shortcut. *description* is the description of the shortcut. - *filename* is the title of the shortcut that the user will see. *arguments* - specifies the command line arguments, if any. *workdir* is the working directory - for the program. *iconpath* is the file containing the icon for the shortcut, - and *iconindex* is the index of the icon in the file *iconpath*. Again, for - details consult the Microsoft documentation for the :class:`IShellLink` - interface. diff --git a/Doc/distutils/commandref.rst b/Doc/distutils/commandref.rst deleted file mode 100644 index 3e247e68..00000000 --- a/Doc/distutils/commandref.rst +++ /dev/null @@ -1,105 +0,0 @@ -.. _reference: - -***************** -Command Reference -***************** - -.. include:: ./_setuptools_disclaimer.rst - -.. % \section{Building modules: the \protect\command{build} command family} -.. % \label{build-cmds} -.. % \subsubsection{\protect\command{build}} -.. % \label{build-cmd} -.. % \subsubsection{\protect\command{build\_py}} -.. % \label{build-py-cmd} -.. % \subsubsection{\protect\command{build\_ext}} -.. % \label{build-ext-cmd} -.. % \subsubsection{\protect\command{build\_clib}} -.. % \label{build-clib-cmd} - - -.. _install-cmd: - -Installing modules: the :command:`install` command family -========================================================= - -The install command ensures that the build commands have been run and then runs -the subcommands :command:`install_lib`, :command:`install_data` and -:command:`install_scripts`. - -.. % \subsubsection{\protect\command{install\_lib}} -.. % \label{install-lib-cmd} - - -.. _install-data-cmd: - -:command:`install_data` ------------------------ - -This command installs all data files provided with the distribution. - - -.. _install-scripts-cmd: - -:command:`install_scripts` --------------------------- - -This command installs all (Python) scripts in the distribution. - -.. % \subsection{Cleaning up: the \protect\command{clean} command} -.. % \label{clean-cmd} - - -.. _sdist-cmd: - -Creating a source distribution: the :command:`sdist` command -============================================================ - -.. XXX fragment moved down from above: needs context! - -The manifest template commands are: - -+-------------------------------------------+-----------------------------------------------+ -| Command | Description | -+===========================================+===============================================+ -| :command:`include pat1 pat2 ...` | include all files matching any of the listed | -| | patterns | -+-------------------------------------------+-----------------------------------------------+ -| :command:`exclude pat1 pat2 ...` | exclude all files matching any of the listed | -| | patterns | -+-------------------------------------------+-----------------------------------------------+ -| :command:`recursive-include dir pat1 pat2 | include all files under *dir* matching any of | -| ...` | the listed patterns | -+-------------------------------------------+-----------------------------------------------+ -| :command:`recursive-exclude dir pat1 pat2 | exclude all files under *dir* matching any of | -| ...` | the listed patterns | -+-------------------------------------------+-----------------------------------------------+ -| :command:`global-include pat1 pat2 ...` | include all files anywhere in the source tree | -| | matching --- & any of the listed patterns | -+-------------------------------------------+-----------------------------------------------+ -| :command:`global-exclude pat1 pat2 ...` | exclude all files anywhere in the source tree | -| | matching --- & any of the listed patterns | -+-------------------------------------------+-----------------------------------------------+ -| :command:`prune dir` | exclude all files under *dir* | -+-------------------------------------------+-----------------------------------------------+ -| :command:`graft dir` | include all files under *dir* | -+-------------------------------------------+-----------------------------------------------+ - -The patterns here are Unix-style "glob" patterns: ``*`` matches any sequence of -regular filename characters, ``?`` matches any single regular filename -character, and ``[range]`` matches any of the characters in *range* (e.g., -``a-z``, ``a-zA-Z``, ``a-f0-9_.``). The definition of "regular filename -character" is platform-specific: on Unix it is anything except slash; on Windows -anything except backslash or colon. - -.. XXX Windows support not there yet - -.. % \section{Creating a built distribution: the -.. % \protect\command{bdist} command family} -.. % \label{bdist-cmds} - -.. % \subsection{\protect\command{bdist}} -.. % \subsection{\protect\command{bdist\_dumb}} -.. % \subsection{\protect\command{bdist\_rpm}} - - diff --git a/Doc/distutils/configfile.rst b/Doc/distutils/configfile.rst deleted file mode 100644 index 2a5c8329..00000000 --- a/Doc/distutils/configfile.rst +++ /dev/null @@ -1,144 +0,0 @@ -.. _setup-config: - -************************************ -Writing the Setup Configuration File -************************************ - -.. include:: ./_setuptools_disclaimer.rst - -Often, it's not possible to write down everything needed to build a distribution -*a priori*: you may need to get some information from the user, or from the -user's system, in order to proceed. As long as that information is fairly -simple---a list of directories to search for C header files or libraries, for -example---then providing a configuration file, :file:`setup.cfg`, for users to -edit is a cheap and easy way to solicit it. Configuration files also let you -provide default values for any command option, which the installer can then -override either on the command-line or by editing the config file. - -The setup configuration file is a useful middle-ground between the setup -script---which, ideally, would be opaque to installers [#]_---and the command-line to -the setup script, which is outside of your control and entirely up to the -installer. In fact, :file:`setup.cfg` (and any other Distutils configuration -files present on the target system) are processed after the contents of the -setup script, but before the command-line. This has several useful -consequences: - -.. % (If you have more advanced needs, such as determining which extensions -.. % to build based on what capabilities are present on the target system, -.. % then you need the Distutils ``auto-configuration'' facility. This -.. % started to appear in Distutils 0.9 but, as of this writing, isn't mature -.. % or stable enough yet for real-world use.) - -* installers can override some of what you put in :file:`setup.py` by editing - :file:`setup.cfg` - -* you can provide non-standard defaults for options that are not easily set in - :file:`setup.py` - -* installers can override anything in :file:`setup.cfg` using the command-line - options to :file:`setup.py` - -The basic syntax of the configuration file is simple: - -.. code-block:: ini - - [command] - option=value - ... - -where *command* is one of the Distutils commands (e.g. :command:`build_py`, -:command:`install`), and *option* is one of the options that command supports. -Any number of options can be supplied for each command, and any number of -command sections can be included in the file. Blank lines are ignored, as are -comments, which run from a ``'#'`` character until the end of the line. Long -option values can be split across multiple lines simply by indenting the -continuation lines. - -You can find out the list of options supported by a particular command with the -universal :option:`!--help` option, e.g. - -.. code-block:: shell-session - - $ python setup.py --help build_ext - [...] - Options for 'build_ext' command: - --build-lib (-b) directory for compiled extension modules - --build-temp (-t) directory for temporary files (build by-products) - --inplace (-i) ignore build-lib and put compiled extensions into the - source directory alongside your pure Python modules - --include-dirs (-I) list of directories to search for header files - --define (-D) C preprocessor macros to define - --undef (-U) C preprocessor macros to undefine - --swig-opts list of SWIG command line options - [...] - -Note that an option spelled :option:`!--foo-bar` on the command-line is spelled -``foo_bar`` in configuration files. - -.. _distutils-build-ext-inplace: - -For example, say you want your extensions to be built "in-place"---that is, you -have an extension :mod:`pkg.ext`, and you want the compiled extension file -(:file:`ext.so` on Unix, say) to be put in the same source directory as your -pure Python modules :mod:`pkg.mod1` and :mod:`pkg.mod2`. You can always use the -:option:`!--inplace` option on the command-line to ensure this: - -.. code-block:: sh - - python setup.py build_ext --inplace - -But this requires that you always specify the :command:`build_ext` command -explicitly, and remember to provide :option:`!--inplace`. An easier way is to -"set and forget" this option, by encoding it in :file:`setup.cfg`, the -configuration file for this distribution: - -.. code-block:: ini - - [build_ext] - inplace=1 - -This will affect all builds of this module distribution, whether or not you -explicitly specify :command:`build_ext`. If you include :file:`setup.cfg` in -your source distribution, it will also affect end-user builds---which is -probably a bad idea for this option, since always building extensions in-place -would break installation of the module distribution. In certain peculiar cases, -though, modules are built right in their installation directory, so this is -conceivably a useful ability. (Distributing extensions that expect to be built -in their installation directory is almost always a bad idea, though.) - -Another example: certain commands take a lot of options that don't change from -run to run; for example, :command:`bdist_rpm` needs to know everything required -to generate a "spec" file for creating an RPM distribution. Some of this -information comes from the setup script, and some is automatically generated by -the Distutils (such as the list of files installed). But some of it has to be -supplied as options to :command:`bdist_rpm`, which would be very tedious to do -on the command-line for every run. Hence, here is a snippet from the Distutils' -own :file:`setup.cfg`: - -.. code-block:: ini - - [bdist_rpm] - release = 1 - packager = Greg Ward <gward@python.net> - doc_files = CHANGES.txt - README.txt - USAGE.txt - doc/ - examples/ - -Note that the ``doc_files`` option is simply a whitespace-separated string -split across multiple lines for readability. - - -.. seealso:: - - :ref:`inst-config-syntax` in "Installing Python Modules" - More information on the configuration files is available in the manual for - system administrators. - - -.. rubric:: Footnotes - -.. [#] This ideal probably won't be achieved until auto-configuration is fully - supported by the Distutils. - diff --git a/Doc/distutils/examples.rst b/Doc/distutils/examples.rst deleted file mode 100644 index e492b7f6..00000000 --- a/Doc/distutils/examples.rst +++ /dev/null @@ -1,340 +0,0 @@ -.. _distutils_examples: - -****************** -Distutils Examples -****************** - -.. include:: ./_setuptools_disclaimer.rst - -This chapter provides a number of basic examples to help get started with -distutils. Additional information about using distutils can be found in the -Distutils Cookbook. - - -.. seealso:: - - `Distutils Cookbook <https://wiki.python.org/moin/Distutils/Cookbook>`_ - Collection of recipes showing how to achieve more control over distutils. - - -.. _pure-mod: - -Pure Python distribution (by module) -==================================== - -If you're just distributing a couple of modules, especially if they don't live -in a particular package, you can specify them individually using the -``py_modules`` option in the setup script. - -In the simplest case, you'll have two files to worry about: a setup script and -the single module you're distributing, :file:`foo.py` in this example:: - - <root>/ - setup.py - foo.py - -(In all diagrams in this section, *<root>* will refer to the distribution root -directory.) A minimal setup script to describe this situation would be:: - - from distutils.core import setup - setup(name='foo', - version='1.0', - py_modules=['foo'], - ) - -Note that the name of the distribution is specified independently with the -``name`` option, and there's no rule that says it has to be the same as -the name of the sole module in the distribution (although that's probably a good -convention to follow). However, the distribution name is used to generate -filenames, so you should stick to letters, digits, underscores, and hyphens. - -Since ``py_modules`` is a list, you can of course specify multiple -modules, eg. if you're distributing modules :mod:`foo` and :mod:`bar`, your -setup might look like this:: - - <root>/ - setup.py - foo.py - bar.py - -and the setup script might be :: - - from distutils.core import setup - setup(name='foobar', - version='1.0', - py_modules=['foo', 'bar'], - ) - -You can put module source files into another directory, but if you have enough -modules to do that, it's probably easier to specify modules by package rather -than listing them individually. - - -.. _pure-pkg: - -Pure Python distribution (by package) -===================================== - -If you have more than a couple of modules to distribute, especially if they are -in multiple packages, it's probably easier to specify whole packages rather than -individual modules. This works even if your modules are not in a package; you -can just tell the Distutils to process modules from the root package, and that -works the same as any other package (except that you don't have to have an -:file:`__init__.py` file). - -The setup script from the last example could also be written as :: - - from distutils.core import setup - setup(name='foobar', - version='1.0', - packages=[''], - ) - -(The empty string stands for the root package.) - -If those two files are moved into a subdirectory, but remain in the root -package, e.g.:: - - <root>/ - setup.py - src/ foo.py - bar.py - -then you would still specify the root package, but you have to tell the -Distutils where source files in the root package live:: - - from distutils.core import setup - setup(name='foobar', - version='1.0', - package_dir={'': 'src'}, - packages=[''], - ) - -More typically, though, you will want to distribute multiple modules in the same -package (or in sub-packages). For example, if the :mod:`foo` and :mod:`bar` -modules belong in package :mod:`foobar`, one way to layout your source tree is -:: - - <root>/ - setup.py - foobar/ - __init__.py - foo.py - bar.py - -This is in fact the default layout expected by the Distutils, and the one that -requires the least work to describe in your setup script:: - - from distutils.core import setup - setup(name='foobar', - version='1.0', - packages=['foobar'], - ) - -If you want to put modules in directories not named for their package, then you -need to use the ``package_dir`` option again. For example, if the -:file:`src` directory holds modules in the :mod:`foobar` package:: - - <root>/ - setup.py - src/ - __init__.py - foo.py - bar.py - -an appropriate setup script would be :: - - from distutils.core import setup - setup(name='foobar', - version='1.0', - package_dir={'foobar': 'src'}, - packages=['foobar'], - ) - -Or, you might put modules from your main package right in the distribution -root:: - - <root>/ - setup.py - __init__.py - foo.py - bar.py - -in which case your setup script would be :: - - from distutils.core import setup - setup(name='foobar', - version='1.0', - package_dir={'foobar': ''}, - packages=['foobar'], - ) - -(The empty string also stands for the current directory.) - -If you have sub-packages, they must be explicitly listed in ``packages``, -but any entries in ``package_dir`` automatically extend to sub-packages. -(In other words, the Distutils does *not* scan your source tree, trying to -figure out which directories correspond to Python packages by looking for -:file:`__init__.py` files.) Thus, if the default layout grows a sub-package:: - - <root>/ - setup.py - foobar/ - __init__.py - foo.py - bar.py - subfoo/ - __init__.py - blah.py - -then the corresponding setup script would be :: - - from distutils.core import setup - setup(name='foobar', - version='1.0', - packages=['foobar', 'foobar.subfoo'], - ) - - -.. _single-ext: - -Single extension module -======================= - -Extension modules are specified using the ``ext_modules`` option. -``package_dir`` has no effect on where extension source files are found; -it only affects the source for pure Python modules. The simplest case, a -single extension module in a single C source file, is:: - - <root>/ - setup.py - foo.c - -If the :mod:`foo` extension belongs in the root package, the setup script for -this could be :: - - from distutils.core import setup - from distutils.extension import Extension - setup(name='foobar', - version='1.0', - ext_modules=[Extension('foo', ['foo.c'])], - ) - -If the extension actually belongs in a package, say :mod:`foopkg`, then - -With exactly the same source tree layout, this extension can be put in the -:mod:`foopkg` package simply by changing the name of the extension:: - - from distutils.core import setup - from distutils.extension import Extension - setup(name='foobar', - version='1.0', - ext_modules=[Extension('foopkg.foo', ['foo.c'])], - ) - -Checking a package -================== - -The ``check`` command allows you to verify if your package meta-data -meet the minimum requirements to build a distribution. - -To run it, just call it using your :file:`setup.py` script. If something is -missing, ``check`` will display a warning. - -Let's take an example with a simple script:: - - from distutils.core import setup - - setup(name='foobar') - -Running the ``check`` command will display some warnings: - -.. code-block:: shell-session - - $ python setup.py check - running check - warning: check: missing required meta-data: version, url - warning: check: missing meta-data: either (author and author_email) or - (maintainer and maintainer_email) should be supplied - - -If you use the reStructuredText syntax in the ``long_description`` field and -`docutils`_ is installed you can check if the syntax is fine with the -``check`` command, using the ``restructuredtext`` option. - -For example, if the :file:`setup.py` script is changed like this:: - - from distutils.core import setup - - desc = """\ - My description - ============== - - This is the description of the ``foobar`` package. - """ - - setup(name='foobar', version='1', author='tarek', - author_email='tarek@ziade.org', - url='http://example.com', long_description=desc) - -Where the long description is broken, ``check`` will be able to detect it -by using the :mod:`docutils` parser: - -.. code-block:: shell-session - - $ python setup.py check --restructuredtext - running check - warning: check: Title underline too short. (line 2) - warning: check: Could not finish the parsing. - -Reading the metadata -===================== - -The :func:`distutils.core.setup` function provides a command-line interface -that allows you to query the metadata fields of a project through the -``setup.py`` script of a given project: - -.. code-block:: shell-session - - $ python setup.py --name - distribute - -This call reads the ``name`` metadata by running the -:func:`distutils.core.setup` function. Although, when a source or binary -distribution is created with Distutils, the metadata fields are written -in a static file called :file:`PKG-INFO`. When a Distutils-based project is -installed in Python, the :file:`PKG-INFO` file is copied alongside the modules -and packages of the distribution under :file:`NAME-VERSION-pyX.X.egg-info`, -where ``NAME`` is the name of the project, ``VERSION`` its version as defined -in the Metadata, and ``pyX.X`` the major and minor version of Python like -``2.7`` or ``3.2``. - -You can read back this static file, by using the -:class:`distutils.dist.DistributionMetadata` class and its -:func:`read_pkg_file` method:: - - >>> from distutils.dist import DistributionMetadata - >>> metadata = DistributionMetadata() - >>> metadata.read_pkg_file(open('distribute-0.6.8-py2.7.egg-info')) - >>> metadata.name - 'distribute' - >>> metadata.version - '0.6.8' - >>> metadata.description - 'Easily download, build, install, upgrade, and uninstall Python packages' - -Notice that the class can also be instantiated with a metadata file path to -loads its values:: - - >>> pkg_info_path = 'distribute-0.6.8-py2.7.egg-info' - >>> DistributionMetadata(pkg_info_path).name - 'distribute' - - -.. % \section{Multiple extension modules} -.. % \label{multiple-ext} - -.. % \section{Putting it all together} - - -.. _docutils: http://docutils.sourceforge.net diff --git a/Doc/distutils/extending.rst b/Doc/distutils/extending.rst deleted file mode 100644 index 1075e817..00000000 --- a/Doc/distutils/extending.rst +++ /dev/null @@ -1,98 +0,0 @@ -.. _extending-distutils: - -******************* -Extending Distutils -******************* - -.. include:: ./_setuptools_disclaimer.rst - -Distutils can be extended in various ways. Most extensions take the form of new -commands or replacements for existing commands. New commands may be written to -support new types of platform-specific packaging, for example, while -replacements for existing commands may be made to modify details of how the -command operates on a package. - -Most extensions of the distutils are made within :file:`setup.py` scripts that -want to modify existing commands; many simply add a few file extensions that -should be copied into packages in addition to :file:`.py` files as a -convenience. - -Most distutils command implementations are subclasses of the -:class:`distutils.cmd.Command` class. New commands may directly inherit from -:class:`Command`, while replacements often derive from :class:`Command` -indirectly, directly subclassing the command they are replacing. Commands are -required to derive from :class:`Command`. - -.. % \section{Extending existing commands} -.. % \label{extend-existing} - -.. % \section{Writing new commands} -.. % \label{new-commands} -.. % \XXX{Would an uninstall command be a good example here?} - - -Integrating new commands -======================== - -There are different ways to integrate new command implementations into -distutils. The most difficult is to lobby for the inclusion of the new features -in distutils itself, and wait for (and require) a version of Python that -provides that support. This is really hard for many reasons. - -The most common, and possibly the most reasonable for most needs, is to include -the new implementations with your :file:`setup.py` script, and cause the -:func:`distutils.core.setup` function use them:: - - from distutils.command.build_py import build_py as _build_py - from distutils.core import setup - - class build_py(_build_py): - """Specialized Python source builder.""" - - # implement whatever needs to be different... - - setup(cmdclass={'build_py': build_py}, - ...) - -This approach is most valuable if the new implementations must be used to use a -particular package, as everyone interested in the package will need to have the -new command implementation. - -Beginning with Python 2.4, a third option is available, intended to allow new -commands to be added which can support existing :file:`setup.py` scripts without -requiring modifications to the Python installation. This is expected to allow -third-party extensions to provide support for additional packaging systems, but -the commands can be used for anything distutils commands can be used for. A new -configuration option, ``command_packages`` (command-line option -:option:`!--command-packages`), can be used to specify additional packages to be -searched for modules implementing commands. Like all distutils options, this -can be specified on the command line or in a configuration file. This option -can only be set in the ``[global]`` section of a configuration file, or before -any commands on the command line. If set in a configuration file, it can be -overridden from the command line; setting it to an empty string on the command -line causes the default to be used. This should never be set in a configuration -file provided with a package. - -This new option can be used to add any number of packages to the list of -packages searched for command implementations; multiple package names should be -separated by commas. When not specified, the search is only performed in the -:mod:`distutils.command` package. When :file:`setup.py` is run with the option -``--command-packages distcmds,buildcmds``, however, the packages -:mod:`distutils.command`, :mod:`distcmds`, and :mod:`buildcmds` will be searched -in that order. New commands are expected to be implemented in modules of the -same name as the command by classes sharing the same name. Given the example -command line option above, the command :command:`bdist_openpkg` could be -implemented by the class :class:`distcmds.bdist_openpkg.bdist_openpkg` or -:class:`buildcmds.bdist_openpkg.bdist_openpkg`. - - -Adding new distribution types -============================= - -Commands that create distributions (files in the :file:`dist/` directory) need -to add ``(command, filename)`` pairs to ``self.distribution.dist_files`` so that -:command:`upload` can upload it to PyPI. The *filename* in the pair contains no -path information, only the name of the file itself. In dry-run mode, pairs -should still be added to represent what would have been created. - - diff --git a/Doc/distutils/index.rst b/Doc/distutils/index.rst deleted file mode 100644 index 2ccddc38..00000000 --- a/Doc/distutils/index.rst +++ /dev/null @@ -1,49 +0,0 @@ -.. _distutils-index: - -############################################## - Distributing Python Modules (Legacy version) -############################################## - -:Authors: Greg Ward, Anthony Baxter -:Email: distutils-sig@python.org - -.. seealso:: - - :ref:`distributing-index` - The up to date module distribution documentations - -.. note:: - - The entire ``distutils`` package has been deprecated and will be - removed in Python 3.12. This documentation is retained as a - reference only, and will be removed with the package. See the - :ref:`What's New <distutils-deprecated>` entry for more information. - -.. include:: ./_setuptools_disclaimer.rst - -.. note:: - - This guide only covers the basic tools for building and distributing - extensions that are provided as part of this version of Python. Third party - tools offer easier to use and more secure alternatives. Refer to the `quick - recommendations section <https://packaging.python.org/guides/tool-recommendations/>`__ - in the Python Packaging User Guide for more information. - -This document describes the Python Distribution Utilities ("Distutils") from -the module developer's point of view, describing the underlying capabilities -that ``setuptools`` builds on to allow Python developers to make Python modules -and extensions readily available to a wider audience. - -.. toctree:: - :maxdepth: 2 - :numbered: - - introduction.rst - setupscript.rst - configfile.rst - sourcedist.rst - builtdist.rst - examples.rst - extending.rst - commandref.rst - apiref.rst diff --git a/Doc/distutils/introduction.rst b/Doc/distutils/introduction.rst deleted file mode 100644 index 87ed178e..00000000 --- a/Doc/distutils/introduction.rst +++ /dev/null @@ -1,203 +0,0 @@ -.. _distutils-intro: - -**************************** -An Introduction to Distutils -**************************** - -.. include:: ./_setuptools_disclaimer.rst - -This document covers using the Distutils to distribute your Python modules, -concentrating on the role of developer/distributor: if you're looking for -information on installing Python modules, you should refer to the -:ref:`install-index` chapter. - - -.. _distutils-concepts: - -Concepts & Terminology -====================== - -Using the Distutils is quite simple, both for module developers and for -users/administrators installing third-party modules. As a developer, your -responsibilities (apart from writing solid, well-documented and well-tested -code, of course!) are: - -* write a setup script (:file:`setup.py` by convention) - -* (optional) write a setup configuration file - -* create a source distribution - -* (optional) create one or more built (binary) distributions - -Each of these tasks is covered in this document. - -Not all module developers have access to a multitude of platforms, so it's not -always feasible to expect them to create a multitude of built distributions. It -is hoped that a class of intermediaries, called *packagers*, will arise to -address this need. Packagers will take source distributions released by module -developers, build them on one or more platforms, and release the resulting built -distributions. Thus, users on the most popular platforms will be able to -install most popular Python module distributions in the most natural way for -their platform, without having to run a single setup script or compile a line of -code. - - -.. _distutils-simple-example: - -A Simple Example -================ - -The setup script is usually quite simple, although since it's written in Python, -there are no arbitrary limits to what you can do with it, though you should be -careful about putting arbitrarily expensive operations in your setup script. -Unlike, say, Autoconf-style configure scripts, the setup script may be run -multiple times in the course of building and installing your module -distribution. - -If all you want to do is distribute a module called :mod:`foo`, contained in a -file :file:`foo.py`, then your setup script can be as simple as this:: - - from distutils.core import setup - setup(name='foo', - version='1.0', - py_modules=['foo'], - ) - -Some observations: - -* most information that you supply to the Distutils is supplied as keyword - arguments to the :func:`setup` function - -* those keyword arguments fall into two categories: package metadata (name, - version number) and information about what's in the package (a list of pure - Python modules, in this case) - -* modules are specified by module name, not filename (the same will hold true - for packages and extensions) - -* it's recommended that you supply a little more metadata, in particular your - name, email address and a URL for the project (see section :ref:`setup-script` - for an example) - -To create a source distribution for this module, you would create a setup -script, :file:`setup.py`, containing the above code, and run this command from a -terminal:: - - python setup.py sdist - -For Windows, open a command prompt window (:menuselection:`Start --> -Accessories`) and change the command to:: - - setup.py sdist - -:command:`sdist` will create an archive file (e.g., tarball on Unix, ZIP file on Windows) -containing your setup script :file:`setup.py`, and your module :file:`foo.py`. -The archive file will be named :file:`foo-1.0.tar.gz` (or :file:`.zip`), and -will unpack into a directory :file:`foo-1.0`. - -If an end-user wishes to install your :mod:`foo` module, all they have to do is -download :file:`foo-1.0.tar.gz` (or :file:`.zip`), unpack it, and---from the -:file:`foo-1.0` directory---run :: - - python setup.py install - -which will ultimately copy :file:`foo.py` to the appropriate directory for -third-party modules in their Python installation. - -This simple example demonstrates some fundamental concepts of the Distutils. -First, both developers and installers have the same basic user interface, i.e. -the setup script. The difference is which Distutils *commands* they use: the -:command:`sdist` command is almost exclusively for module developers, while -:command:`install` is more often for installers (although most developers will -want to install their own code occasionally). - -Other useful built distribution formats are RPM, implemented by the -:command:`bdist_rpm` command, Solaris :program:`pkgtool` -(:command:`bdist_pkgtool`), and HP-UX :program:`swinstall` -(:command:`bdist_sdux`). For example, the following command will create an RPM -file called :file:`foo-1.0.noarch.rpm`:: - - python setup.py bdist_rpm - -(The :command:`bdist_rpm` command uses the :command:`rpm` executable, therefore -this has to be run on an RPM-based system such as Red Hat Linux, SuSE Linux, or -Mandrake Linux.) - -You can find out what distribution formats are available at any time by running -:: - - python setup.py bdist --help-formats - - -.. _python-terms: - -General Python terminology -========================== - -If you're reading this document, you probably have a good idea of what modules, -extensions, and so forth are. Nevertheless, just to be sure that everyone is -operating from a common starting point, we offer the following glossary of -common Python terms: - -module - the basic unit of code reusability in Python: a block of code imported by some - other code. Three types of modules concern us here: pure Python modules, - extension modules, and packages. - -pure Python module - a module written in Python and contained in a single :file:`.py` file (and - possibly associated :file:`.pyc` files). Sometimes referred to as a - "pure module." - -extension module - a module written in the low-level language of the Python implementation: C/C++ - for Python, Java for Jython. Typically contained in a single dynamically - loadable pre-compiled file, e.g. a shared object (:file:`.so`) file for Python - extensions on Unix, a DLL (given the :file:`.pyd` extension) for Python - extensions on Windows, or a Java class file for Jython extensions. (Note that - currently, the Distutils only handles C/C++ extensions for Python.) - -package - a module that contains other modules; typically contained in a directory in the - filesystem and distinguished from other directories by the presence of a file - :file:`__init__.py`. - -root package - the root of the hierarchy of packages. (This isn't really a package, since it - doesn't have an :file:`__init__.py` file. But we have to call it something.) - The vast majority of the standard library is in the root package, as are many - small, standalone third-party modules that don't belong to a larger module - collection. Unlike regular packages, modules in the root package can be found in - many directories: in fact, every directory listed in ``sys.path`` contributes - modules to the root package. - - -.. _distutils-term: - -Distutils-specific terminology -============================== - -The following terms apply more specifically to the domain of distributing Python -modules using the Distutils: - -module distribution - a collection of Python modules distributed together as a single downloadable - resource and meant to be installed *en masse*. Examples of some well-known - module distributions are NumPy, SciPy, Pillow, - or mxBase. (This would be called a *package*, except that term is - already taken in the Python context: a single module distribution may contain - zero, one, or many Python packages.) - -pure module distribution - a module distribution that contains only pure Python modules and packages. - Sometimes referred to as a "pure distribution." - -non-pure module distribution - a module distribution that contains at least one extension module. Sometimes - referred to as a "non-pure distribution." - -distribution root - the top-level directory of your source tree (or source distribution); the - directory where :file:`setup.py` exists. Generally :file:`setup.py` will be - run from this directory. diff --git a/Doc/distutils/packageindex.rst b/Doc/distutils/packageindex.rst deleted file mode 100644 index ccb9a598..00000000 --- a/Doc/distutils/packageindex.rst +++ /dev/null @@ -1,16 +0,0 @@ -:orphan: - -.. _package-index: - -******************************* -The Python Package Index (PyPI) -******************************* - -The `Python Package Index (PyPI)`_ stores metadata describing distributions -packaged with distutils and other publishing tools, as well the distribution -archives themselves. - -References to up to date PyPI documentation can be found at -:ref:`publishing-python-packages`. - -.. _Python Package Index (PyPI): https://pypi.org diff --git a/Doc/distutils/setupscript.rst b/Doc/distutils/setupscript.rst deleted file mode 100644 index 4386a60b..00000000 --- a/Doc/distutils/setupscript.rst +++ /dev/null @@ -1,713 +0,0 @@ -.. _setup-script: - -************************ -Writing the Setup Script -************************ - -.. include:: ./_setuptools_disclaimer.rst - -The setup script is the centre of all activity in building, distributing, and -installing modules using the Distutils. The main purpose of the setup script is -to describe your module distribution to the Distutils, so that the various -commands that operate on your modules do the right thing. As we saw in section -:ref:`distutils-simple-example` above, the setup script consists mainly of a call to -:func:`setup`, and most information supplied to the Distutils by the module -developer is supplied as keyword arguments to :func:`setup`. - -Here's a slightly more involved example, which we'll follow for the next couple -of sections: the Distutils' own setup script. (Keep in mind that although the -Distutils are included with Python 1.6 and later, they also have an independent -existence so that Python 1.5.2 users can use them to install other module -distributions. The Distutils' own setup script, shown here, is used to install -the package into Python 1.5.2.) :: - - #!/usr/bin/env python - - from distutils.core import setup - - setup(name='Distutils', - version='1.0', - description='Python Distribution Utilities', - author='Greg Ward', - author_email='gward@python.net', - url='https://www.python.org/sigs/distutils-sig/', - packages=['distutils', 'distutils.command'], - ) - -There are only two differences between this and the trivial one-file -distribution presented in section :ref:`distutils-simple-example`: more metadata, and the -specification of pure Python modules by package, rather than by module. This is -important since the Distutils consist of a couple of dozen modules split into -(so far) two packages; an explicit list of every module would be tedious to -generate and difficult to maintain. For more information on the additional -meta-data, see section :ref:`meta-data`. - -Note that any pathnames (files or directories) supplied in the setup script -should be written using the Unix convention, i.e. slash-separated. The -Distutils will take care of converting this platform-neutral representation into -whatever is appropriate on your current platform before actually using the -pathname. This makes your setup script portable across operating systems, which -of course is one of the major goals of the Distutils. In this spirit, all -pathnames in this document are slash-separated. - -This, of course, only applies to pathnames given to Distutils functions. If -you, for example, use standard Python functions such as :func:`glob.glob` or -:func:`os.listdir` to specify files, you should be careful to write portable -code instead of hardcoding path separators:: - - glob.glob(os.path.join('mydir', 'subdir', '*.html')) - os.listdir(os.path.join('mydir', 'subdir')) - - -.. _listing-packages: - -Listing whole packages -====================== - -The ``packages`` option tells the Distutils to process (build, distribute, -install, etc.) all pure Python modules found in each package mentioned in the -``packages`` list. In order to do this, of course, there has to be a -correspondence between package names and directories in the filesystem. The -default correspondence is the most obvious one, i.e. package :mod:`distutils` is -found in the directory :file:`distutils` relative to the distribution root. -Thus, when you say ``packages = ['foo']`` in your setup script, you are -promising that the Distutils will find a file :file:`foo/__init__.py` (which -might be spelled differently on your system, but you get the idea) relative to -the directory where your setup script lives. If you break this promise, the -Distutils will issue a warning but still process the broken package anyway. - -If you use a different convention to lay out your source directory, that's no -problem: you just have to supply the ``package_dir`` option to tell the -Distutils about your convention. For example, say you keep all Python source -under :file:`lib`, so that modules in the "root package" (i.e., not in any -package at all) are in :file:`lib`, modules in the :mod:`foo` package are in -:file:`lib/foo`, and so forth. Then you would put :: - - package_dir = {'': 'lib'} - -in your setup script. The keys to this dictionary are package names, and an -empty package name stands for the root package. The values are directory names -relative to your distribution root. In this case, when you say ``packages = -['foo']``, you are promising that the file :file:`lib/foo/__init__.py` exists. - -Another possible convention is to put the :mod:`foo` package right in -:file:`lib`, the :mod:`foo.bar` package in :file:`lib/bar`, etc. This would be -written in the setup script as :: - - package_dir = {'foo': 'lib'} - -A ``package: dir`` entry in the ``package_dir`` dictionary implicitly -applies to all packages below *package*, so the :mod:`foo.bar` case is -automatically handled here. In this example, having ``packages = ['foo', -'foo.bar']`` tells the Distutils to look for :file:`lib/__init__.py` and -:file:`lib/bar/__init__.py`. (Keep in mind that although ``package_dir`` -applies recursively, you must explicitly list all packages in -``packages``: the Distutils will *not* recursively scan your source tree -looking for any directory with an :file:`__init__.py` file.) - - -.. _listing-modules: - -Listing individual modules -========================== - -For a small module distribution, you might prefer to list all modules rather -than listing packages---especially the case of a single module that goes in the -"root package" (i.e., no package at all). This simplest case was shown in -section :ref:`distutils-simple-example`; here is a slightly more involved example:: - - py_modules = ['mod1', 'pkg.mod2'] - -This describes two modules, one of them in the "root" package, the other in the -:mod:`pkg` package. Again, the default package/directory layout implies that -these two modules can be found in :file:`mod1.py` and :file:`pkg/mod2.py`, and -that :file:`pkg/__init__.py` exists as well. And again, you can override the -package/directory correspondence using the ``package_dir`` option. - - -.. _describing-extensions: - -Describing extension modules -============================ - -Just as writing Python extension modules is a bit more complicated than writing -pure Python modules, describing them to the Distutils is a bit more complicated. -Unlike pure modules, it's not enough just to list modules or packages and expect -the Distutils to go out and find the right files; you have to specify the -extension name, source file(s), and any compile/link requirements (include -directories, libraries to link with, etc.). - -.. XXX read over this section - -All of this is done through another keyword argument to :func:`setup`, the -``ext_modules`` option. ``ext_modules`` is just a list of -:class:`~distutils.core.Extension` instances, each of which describes a -single extension module. -Suppose your distribution includes a single extension, called :mod:`foo` and -implemented by :file:`foo.c`. If no additional instructions to the -compiler/linker are needed, describing this extension is quite simple:: - - Extension('foo', ['foo.c']) - -The :class:`Extension` class can be imported from :mod:`distutils.core` along -with :func:`setup`. Thus, the setup script for a module distribution that -contains only this one extension and nothing else might be:: - - from distutils.core import setup, Extension - setup(name='foo', - version='1.0', - ext_modules=[Extension('foo', ['foo.c'])], - ) - -The :class:`Extension` class (actually, the underlying extension-building -machinery implemented by the :command:`build_ext` command) supports a great deal -of flexibility in describing Python extensions, which is explained in the -following sections. - - -Extension names and packages ----------------------------- - -The first argument to the :class:`~distutils.core.Extension` constructor is -always the name of the extension, including any package names. For example, :: - - Extension('foo', ['src/foo1.c', 'src/foo2.c']) - -describes an extension that lives in the root package, while :: - - Extension('pkg.foo', ['src/foo1.c', 'src/foo2.c']) - -describes the same extension in the :mod:`pkg` package. The source files and -resulting object code are identical in both cases; the only difference is where -in the filesystem (and therefore where in Python's namespace hierarchy) the -resulting extension lives. - -If you have a number of extensions all in the same package (or all under the -same base package), use the ``ext_package`` keyword argument to -:func:`setup`. For example, :: - - setup(..., - ext_package='pkg', - ext_modules=[Extension('foo', ['foo.c']), - Extension('subpkg.bar', ['bar.c'])], - ) - -will compile :file:`foo.c` to the extension :mod:`pkg.foo`, and :file:`bar.c` to -:mod:`pkg.subpkg.bar`. - - -Extension source files ----------------------- - -The second argument to the :class:`~distutils.core.Extension` constructor is -a list of source -files. Since the Distutils currently only support C, C++, and Objective-C -extensions, these are normally C/C++/Objective-C source files. (Be sure to use -appropriate extensions to distinguish C++ source files: :file:`.cc` and -:file:`.cpp` seem to be recognized by both Unix and Windows compilers.) - -However, you can also include SWIG interface (:file:`.i`) files in the list; the -:command:`build_ext` command knows how to deal with SWIG extensions: it will run -SWIG on the interface file and compile the resulting C/C++ file into your -extension. - -.. XXX SWIG support is rough around the edges and largely untested! - -This warning notwithstanding, options to SWIG can be currently passed like -this:: - - setup(..., - ext_modules=[Extension('_foo', ['foo.i'], - swig_opts=['-modern', '-I../include'])], - py_modules=['foo'], - ) - -Or on the commandline like this:: - - > python setup.py build_ext --swig-opts="-modern -I../include" - -On some platforms, you can include non-source files that are processed by the -compiler and included in your extension. Currently, this just means Windows -message text (:file:`.mc`) files and resource definition (:file:`.rc`) files for -Visual C++. These will be compiled to binary resource (:file:`.res`) files and -linked into the executable. - - -Preprocessor options --------------------- - -Three optional arguments to :class:`~distutils.core.Extension` will help if -you need to specify include directories to search or preprocessor macros to -define/undefine: ``include_dirs``, ``define_macros``, and ``undef_macros``. - -For example, if your extension requires header files in the :file:`include` -directory under your distribution root, use the ``include_dirs`` option:: - - Extension('foo', ['foo.c'], include_dirs=['include']) - -You can specify absolute directories there; if you know that your extension will -only be built on Unix systems with X11R6 installed to :file:`/usr`, you can get -away with :: - - Extension('foo', ['foo.c'], include_dirs=['/usr/include/X11']) - -You should avoid this sort of non-portable usage if you plan to distribute your -code: it's probably better to write C code like :: - - #include <X11/Xlib.h> - -If you need to include header files from some other Python extension, you can -take advantage of the fact that header files are installed in a consistent way -by the Distutils :command:`install_headers` command. For example, the Numerical -Python header files are installed (on a standard Unix installation) to -:file:`/usr/local/include/python1.5/Numerical`. (The exact location will differ -according to your platform and Python installation.) Since the Python include -directory---\ :file:`/usr/local/include/python1.5` in this case---is always -included in the search path when building Python extensions, the best approach -is to write C code like :: - - #include <Numerical/arrayobject.h> - -If you must put the :file:`Numerical` include directory right into your header -search path, though, you can find that directory using the Distutils -:mod:`distutils.sysconfig` module:: - - from distutils.sysconfig import get_python_inc - incdir = os.path.join(get_python_inc(plat_specific=1), 'Numerical') - setup(..., - Extension(..., include_dirs=[incdir]), - ) - -Even though this is quite portable---it will work on any Python installation, -regardless of platform---it's probably easier to just write your C code in the -sensible way. - -You can define and undefine pre-processor macros with the ``define_macros`` and -``undef_macros`` options. ``define_macros`` takes a list of ``(name, value)`` -tuples, where ``name`` is the name of the macro to define (a string) and -``value`` is its value: either a string or ``None``. (Defining a macro ``FOO`` -to ``None`` is the equivalent of a bare ``#define FOO`` in your C source: with -most compilers, this sets ``FOO`` to the string ``1``.) ``undef_macros`` is -just a list of macros to undefine. - -For example:: - - Extension(..., - define_macros=[('NDEBUG', '1'), - ('HAVE_STRFTIME', None)], - undef_macros=['HAVE_FOO', 'HAVE_BAR']) - -is the equivalent of having this at the top of every C source file:: - - #define NDEBUG 1 - #define HAVE_STRFTIME - #undef HAVE_FOO - #undef HAVE_BAR - - -Library options ---------------- - -You can also specify the libraries to link against when building your extension, -and the directories to search for those libraries. The ``libraries`` option is -a list of libraries to link against, ``library_dirs`` is a list of directories -to search for libraries at link-time, and ``runtime_library_dirs`` is a list of -directories to search for shared (dynamically loaded) libraries at run-time. - -For example, if you need to link against libraries known to be in the standard -library search path on target systems :: - - Extension(..., - libraries=['gdbm', 'readline']) - -If you need to link with libraries in a non-standard location, you'll have to -include the location in ``library_dirs``:: - - Extension(..., - library_dirs=['/usr/X11R6/lib'], - libraries=['X11', 'Xt']) - -(Again, this sort of non-portable construct should be avoided if you intend to -distribute your code.) - -.. XXX Should mention clib libraries here or somewhere else! - - -Other options -------------- - -There are still some other options which can be used to handle special cases. - -The ``optional`` option is a boolean; if it is true, -a build failure in the extension will not abort the build process, but -instead simply not install the failing extension. - -The ``extra_objects`` option is a list of object files to be passed to the -linker. These files must not have extensions, as the default extension for the -compiler is used. - -``extra_compile_args`` and ``extra_link_args`` can be used to -specify additional command line options for the respective compiler and linker -command lines. - -``export_symbols`` is only useful on Windows. It can contain a list of -symbols (functions or variables) to be exported. This option is not needed when -building compiled extensions: Distutils will automatically add ``initmodule`` -to the list of exported symbols. - -The ``depends`` option is a list of files that the extension depends on -(for example header files). The build command will call the compiler on the -sources to rebuild extension if any on this files has been modified since the -previous build. - -Relationships between Distributions and Packages -================================================ - -A distribution may relate to packages in three specific ways: - -#. It can require packages or modules. - -#. It can provide packages or modules. - -#. It can obsolete packages or modules. - -These relationships can be specified using keyword arguments to the -:func:`distutils.core.setup` function. - -Dependencies on other Python modules and packages can be specified by supplying -the *requires* keyword argument to :func:`setup`. The value must be a list of -strings. Each string specifies a package that is required, and optionally what -versions are sufficient. - -To specify that any version of a module or package is required, the string -should consist entirely of the module or package name. Examples include -``'mymodule'`` and ``'xml.parsers.expat'``. - -If specific versions are required, a sequence of qualifiers can be supplied in -parentheses. Each qualifier may consist of a comparison operator and a version -number. The accepted comparison operators are:: - - < > == - <= >= != - -These can be combined by using multiple qualifiers separated by commas (and -optional whitespace). In this case, all of the qualifiers must be matched; a -logical AND is used to combine the evaluations. - -Let's look at a bunch of examples: - -+-------------------------+----------------------------------------------+ -| Requires Expression | Explanation | -+=========================+==============================================+ -| ``==1.0`` | Only version ``1.0`` is compatible | -+-------------------------+----------------------------------------------+ -| ``>1.0, !=1.5.1, <2.0`` | Any version after ``1.0`` and before ``2.0`` | -| | is compatible, except ``1.5.1`` | -+-------------------------+----------------------------------------------+ - -Now that we can specify dependencies, we also need to be able to specify what we -provide that other distributions can require. This is done using the *provides* -keyword argument to :func:`setup`. The value for this keyword is a list of -strings, each of which names a Python module or package, and optionally -identifies the version. If the version is not specified, it is assumed to match -that of the distribution. - -Some examples: - -+---------------------+----------------------------------------------+ -| Provides Expression | Explanation | -+=====================+==============================================+ -| ``mypkg`` | Provide ``mypkg``, using the distribution | -| | version | -+---------------------+----------------------------------------------+ -| ``mypkg (1.1)`` | Provide ``mypkg`` version 1.1, regardless of | -| | the distribution version | -+---------------------+----------------------------------------------+ - -A package can declare that it obsoletes other packages using the *obsoletes* -keyword argument. The value for this is similar to that of the *requires* -keyword: a list of strings giving module or package specifiers. Each specifier -consists of a module or package name optionally followed by one or more version -qualifiers. Version qualifiers are given in parentheses after the module or -package name. - -The versions identified by the qualifiers are those that are obsoleted by the -distribution being described. If no qualifiers are given, all versions of the -named module or package are understood to be obsoleted. - -.. _distutils-installing-scripts: - -Installing Scripts -================== - -So far we have been dealing with pure and non-pure Python modules, which are -usually not run by themselves but imported by scripts. - -Scripts are files containing Python source code, intended to be started from the -command line. Scripts don't require Distutils to do anything very complicated. -The only clever feature is that if the first line of the script starts with -``#!`` and contains the word "python", the Distutils will adjust the first line -to refer to the current interpreter location. By default, it is replaced with -the current interpreter location. The :option:`!--executable` (or :option:`!-e`) -option will allow the interpreter path to be explicitly overridden. - -The ``scripts`` option simply is a list of files to be handled in this -way. From the PyXML setup script:: - - setup(..., - scripts=['scripts/xmlproc_parse', 'scripts/xmlproc_val'] - ) - -.. versionchanged:: 3.1 - All the scripts will also be added to the ``MANIFEST`` file if no template is - provided. See :ref:`manifest`. - - -.. _distutils-installing-package-data: - -Installing Package Data -======================= - -Often, additional files need to be installed into a package. These files are -often data that's closely related to the package's implementation, or text files -containing documentation that might be of interest to programmers using the -package. These files are called :dfn:`package data`. - -Package data can be added to packages using the ``package_data`` keyword -argument to the :func:`setup` function. The value must be a mapping from -package name to a list of relative path names that should be copied into the -package. The paths are interpreted as relative to the directory containing the -package (information from the ``package_dir`` mapping is used if appropriate); -that is, the files are expected to be part of the package in the source -directories. They may contain glob patterns as well. - -The path names may contain directory portions; any necessary directories will be -created in the installation. - -For example, if a package should contain a subdirectory with several data files, -the files can be arranged like this in the source tree:: - - setup.py - src/ - mypkg/ - __init__.py - module.py - data/ - tables.dat - spoons.dat - forks.dat - -The corresponding call to :func:`setup` might be:: - - setup(..., - packages=['mypkg'], - package_dir={'mypkg': 'src/mypkg'}, - package_data={'mypkg': ['data/*.dat']}, - ) - - -.. versionchanged:: 3.1 - All the files that match ``package_data`` will be added to the ``MANIFEST`` - file if no template is provided. See :ref:`manifest`. - - -.. _distutils-additional-files: - -Installing Additional Files -=========================== - -The ``data_files`` option can be used to specify additional files needed -by the module distribution: configuration files, message catalogs, data files, -anything which doesn't fit in the previous categories. - -``data_files`` specifies a sequence of (*directory*, *files*) pairs in the -following way:: - - setup(..., - data_files=[('bitmaps', ['bm/b1.gif', 'bm/b2.gif']), - ('config', ['cfg/data.cfg'])], - ) - -Each (*directory*, *files*) pair in the sequence specifies the installation -directory and the files to install there. - -Each file name in *files* is interpreted relative to the :file:`setup.py` -script at the top of the package source distribution. Note that you can -specify the directory where the data files will be installed, but you cannot -rename the data files themselves. - -The *directory* should be a relative path. It is interpreted relative to the -installation prefix (Python's ``sys.prefix`` for system installations; -``site.USER_BASE`` for user installations). Distutils allows *directory* to be -an absolute installation path, but this is discouraged since it is -incompatible with the wheel packaging format. No directory information from -*files* is used to determine the final location of the installed file; only -the name of the file is used. - -You can specify the ``data_files`` options as a simple sequence of files -without specifying a target directory, but this is not recommended, and the -:command:`install` command will print a warning in this case. To install data -files directly in the target directory, an empty string should be given as the -directory. - -.. versionchanged:: 3.1 - All the files that match ``data_files`` will be added to the ``MANIFEST`` - file if no template is provided. See :ref:`manifest`. - - -.. _meta-data: - -Additional meta-data -==================== - -The setup script may include additional meta-data beyond the name and version. -This information includes: - -+----------------------+---------------------------+-----------------+--------+ -| Meta-Data | Description | Value | Notes | -+======================+===========================+=================+========+ -| ``name`` | name of the package | short string | \(1) | -+----------------------+---------------------------+-----------------+--------+ -| ``version`` | version of this release | short string | (1)(2) | -+----------------------+---------------------------+-----------------+--------+ -| ``author`` | package author's name | short string | \(3) | -+----------------------+---------------------------+-----------------+--------+ -| ``author_email`` | email address of the | email address | \(3) | -| | package author | | | -+----------------------+---------------------------+-----------------+--------+ -| ``maintainer`` | package maintainer's name | short string | \(3) | -+----------------------+---------------------------+-----------------+--------+ -| ``maintainer_email`` | email address of the | email address | \(3) | -| | package maintainer | | | -+----------------------+---------------------------+-----------------+--------+ -| ``url`` | home page for the package | URL | \(1) | -+----------------------+---------------------------+-----------------+--------+ -| ``description`` | short, summary | short string | | -| | description of the | | | -| | package | | | -+----------------------+---------------------------+-----------------+--------+ -| ``long_description`` | longer description of the | long string | \(4) | -| | package | | | -+----------------------+---------------------------+-----------------+--------+ -| ``download_url`` | location where the | URL | | -| | package may be downloaded | | | -+----------------------+---------------------------+-----------------+--------+ -| ``classifiers`` | a list of classifiers | list of strings | (6)(7) | -+----------------------+---------------------------+-----------------+--------+ -| ``platforms`` | a list of platforms | list of strings | (6)(8) | -+----------------------+---------------------------+-----------------+--------+ -| ``keywords`` | a list of keywords | list of strings | (6)(8) | -+----------------------+---------------------------+-----------------+--------+ -| ``license`` | license for the package | short string | \(5) | -+----------------------+---------------------------+-----------------+--------+ - -Notes: - -(1) - These fields are required. - -(2) - It is recommended that versions take the form *major.minor[.patch[.sub]]*. - -(3) - Either the author or the maintainer must be identified. If maintainer is - provided, distutils lists it as the author in :file:`PKG-INFO`. - -(4) - The ``long_description`` field is used by PyPI when you publish a package, - to build its project page. - -(5) - The ``license`` field is a text indicating the license covering the - package where the license is not a selection from the "License" Trove - classifiers. See the ``Classifier`` field. Notice that - there's a ``licence`` distribution option which is deprecated but still - acts as an alias for ``license``. - -(6) - This field must be a list. - -(7) - The valid classifiers are listed on - `PyPI <https://pypi.org/classifiers>`_. - -(8) - To preserve backward compatibility, this field also accepts a string. If - you pass a comma-separated string ``'foo, bar'``, it will be converted to - ``['foo', 'bar']``, Otherwise, it will be converted to a list of one - string. - -'short string' - A single line of text, not more than 200 characters. - -'long string' - Multiple lines of plain text in reStructuredText format (see - http://docutils.sourceforge.net/). - -'list of strings' - See below. - -Encoding the version information is an art in itself. Python packages generally -adhere to the version format *major.minor[.patch][sub]*. The major number is 0 -for initial, experimental releases of software. It is incremented for releases -that represent major milestones in a package. The minor number is incremented -when important new features are added to the package. The patch number -increments when bug-fix releases are made. Additional trailing version -information is sometimes used to indicate sub-releases. These are -"a1,a2,...,aN" (for alpha releases, where functionality and API may change), -"b1,b2,...,bN" (for beta releases, which only fix bugs) and "pr1,pr2,...,prN" -(for final pre-release release testing). Some examples: - -0.1.0 - the first, experimental release of a package - -1.0.1a2 - the second alpha release of the first patch version of 1.0 - -``classifiers`` must be specified in a list:: - - setup(..., - classifiers=[ - 'Development Status :: 4 - Beta', - 'Environment :: Console', - 'Environment :: Web Environment', - 'Intended Audience :: End Users/Desktop', - 'Intended Audience :: Developers', - 'Intended Audience :: System Administrators', - 'License :: OSI Approved :: Python Software Foundation License', - 'Operating System :: MacOS :: MacOS X', - 'Operating System :: Microsoft :: Windows', - 'Operating System :: POSIX', - 'Programming Language :: Python', - 'Topic :: Communications :: Email', - 'Topic :: Office/Business', - 'Topic :: Software Development :: Bug Tracking', - ], - ) - -.. versionchanged:: 3.7 - :class:`~distutils.core.setup` now warns when ``classifiers``, ``keywords`` - or ``platforms`` fields are not specified as a list or a string. - -.. _debug-setup-script: - -Debugging the setup script -========================== - -Sometimes things go wrong, and the setup script doesn't do what the developer -wants. - -Distutils catches any exceptions when running the setup script, and print a -simple error message before the script is terminated. The motivation for this -behaviour is to not confuse administrators who don't know much about Python and -are trying to install a package. If they get a big long traceback from deep -inside the guts of Distutils, they may think the package or the Python -installation is broken because they don't read all the way down to the bottom -and see that it's a permission problem. - -On the other hand, this doesn't help the developer to find the cause of the -failure. For this purpose, the :envvar:`DISTUTILS_DEBUG` environment variable can be set -to anything except an empty string, and distutils will now print detailed -information about what it is doing, dump the full traceback when an exception -occurs, and print the whole command line when an external program (like a C -compiler) fails. diff --git a/Doc/distutils/sourcedist.rst b/Doc/distutils/sourcedist.rst deleted file mode 100644 index b55d0115..00000000 --- a/Doc/distutils/sourcedist.rst +++ /dev/null @@ -1,245 +0,0 @@ -.. _source-dist: - -****************************** -Creating a Source Distribution -****************************** - -.. include:: ./_setuptools_disclaimer.rst - -As shown in section :ref:`distutils-simple-example`, you use the :command:`sdist` command -to create a source distribution. In the simplest case, :: - - python setup.py sdist - -(assuming you haven't specified any :command:`sdist` options in the setup script -or config file), :command:`sdist` creates the archive of the default format for -the current platform. The default format is a gzip'ed tar file -(:file:`.tar.gz`) on Unix, and ZIP file on Windows. - -You can specify as many formats as you like using the :option:`!--formats` -option, for example:: - - python setup.py sdist --formats=gztar,zip - -to create a gzipped tarball and a zip file. The available formats are: - -+-----------+-------------------------+-------------+ -| Format | Description | Notes | -+===========+=========================+=============+ -| ``zip`` | zip file (:file:`.zip`) | (1),(3) | -+-----------+-------------------------+-------------+ -| ``gztar`` | gzip'ed tar file | \(2) | -| | (:file:`.tar.gz`) | | -+-----------+-------------------------+-------------+ -| ``bztar`` | bzip2'ed tar file | \(5) | -| | (:file:`.tar.bz2`) | | -+-----------+-------------------------+-------------+ -| ``xztar`` | xz'ed tar file | \(5) | -| | (:file:`.tar.xz`) | | -+-----------+-------------------------+-------------+ -| ``ztar`` | compressed tar file | (4),(5) | -| | (:file:`.tar.Z`) | | -+-----------+-------------------------+-------------+ -| ``tar`` | tar file (:file:`.tar`) | \(5) | -+-----------+-------------------------+-------------+ - -.. versionchanged:: 3.5 - Added support for the ``xztar`` format. - -Notes: - -(1) - default on Windows - -(2) - default on Unix - -(3) - requires either external :program:`zip` utility or :mod:`zipfile` module (part - of the standard Python library since Python 1.6) - -(4) - requires the :program:`compress` program. Notice that this format is now - pending for deprecation and will be removed in the future versions of Python. -(5) - deprecated by `PEP 527 <https://peps.python.org/pep-0527/>`_; - `PyPI <https://pypi.org>`_ only accepts ``.zip`` and ``.tar.gz`` files. - -When using any ``tar`` format (``gztar``, ``bztar``, ``xztar``, ``ztar`` or -``tar``), under Unix you can specify the ``owner`` and ``group`` names -that will be set for each member of the archive. - -For example, if you want all files of the archive to be owned by root:: - - python setup.py sdist --owner=root --group=root - - -.. _manifest: - -Specifying the files to distribute -================================== - -If you don't supply an explicit list of files (or instructions on how to -generate one), the :command:`sdist` command puts a minimal default set into the -source distribution: - -* all Python source files implied by the ``py_modules`` and - ``packages`` options - -* all C source files mentioned in the ``ext_modules`` or - ``libraries`` options - - .. XXX getting C library sources currently broken---no - :meth:`get_source_files` method in :file:`build_clib.py`! - -* scripts identified by the ``scripts`` option - See :ref:`distutils-installing-scripts`. - -* anything that looks like a test script: :file:`test/test\*.py` (currently, the - Distutils don't do anything with test scripts except include them in source - distributions, but in the future there will be a standard for testing Python - module distributions) - -* Any of the standard README files (:file:`README`, :file:`README.txt`, - or :file:`README.rst`), :file:`setup.py` (or whatever you called your setup - script), and :file:`setup.cfg`. - -* all files that matches the ``package_data`` metadata. - See :ref:`distutils-installing-package-data`. - -* all files that matches the ``data_files`` metadata. - See :ref:`distutils-additional-files`. - -Sometimes this is enough, but usually you will want to specify additional files -to distribute. The typical way to do this is to write a *manifest template*, -called :file:`MANIFEST.in` by default. The manifest template is just a list of -instructions for how to generate your manifest file, :file:`MANIFEST`, which is -the exact list of files to include in your source distribution. The -:command:`sdist` command processes this template and generates a manifest based -on its instructions and what it finds in the filesystem. - -If you prefer to roll your own manifest file, the format is simple: one filename -per line, regular files (or symlinks to them) only. If you do supply your own -:file:`MANIFEST`, you must specify everything: the default set of files -described above does not apply in this case. - -.. versionchanged:: 3.1 - An existing generated :file:`MANIFEST` will be regenerated without - :command:`sdist` comparing its modification time to the one of - :file:`MANIFEST.in` or :file:`setup.py`. - -.. versionchanged:: 3.1.3 - :file:`MANIFEST` files start with a comment indicating they are generated. - Files without this comment are not overwritten or removed. - -.. versionchanged:: 3.2.2 - :command:`sdist` will read a :file:`MANIFEST` file if no :file:`MANIFEST.in` - exists, like it used to do. - -.. versionchanged:: 3.7 - :file:`README.rst` is now included in the list of distutils standard READMEs. - - -The manifest template has one command per line, where each command specifies a -set of files to include or exclude from the source distribution. For an -example, again we turn to the Distutils' own manifest template: - -.. code-block:: none - - include *.txt - recursive-include examples *.txt *.py - prune examples/sample?/build - -The meanings should be fairly clear: include all files in the distribution root -matching :file:`\*.txt`, all files anywhere under the :file:`examples` directory -matching :file:`\*.txt` or :file:`\*.py`, and exclude all directories matching -:file:`examples/sample?/build`. All of this is done *after* the standard -include set, so you can exclude files from the standard set with explicit -instructions in the manifest template. (Or, you can use the -:option:`!--no-defaults` option to disable the standard set entirely.) There are -several other commands available in the manifest template mini-language; see -section :ref:`sdist-cmd`. - -The order of commands in the manifest template matters: initially, we have the -list of default files as described above, and each command in the template adds -to or removes from that list of files. Once we have fully processed the -manifest template, we remove files that should not be included in the source -distribution: - -* all files in the Distutils "build" tree (default :file:`build/`) - -* all files in directories named :file:`RCS`, :file:`CVS`, :file:`.svn`, - :file:`.hg`, :file:`.git`, :file:`.bzr` or :file:`_darcs` - -Now we have our complete list of files, which is written to the manifest for -future reference, and then used to build the source distribution archive(s). - -You can disable the default set of included files with the -:option:`!--no-defaults` option, and you can disable the standard exclude set -with :option:`!--no-prune`. - -Following the Distutils' own manifest template, let's trace how the -:command:`sdist` command builds the list of files to include in the Distutils -source distribution: - -#. include all Python source files in the :file:`distutils` and - :file:`distutils/command` subdirectories (because packages corresponding to - those two directories were mentioned in the ``packages`` option in the - setup script---see section :ref:`setup-script`) - -#. include :file:`README.txt`, :file:`setup.py`, and :file:`setup.cfg` (standard - files) - -#. include :file:`test/test\*.py` (standard files) - -#. include :file:`\*.txt` in the distribution root (this will find - :file:`README.txt` a second time, but such redundancies are weeded out later) - -#. include anything matching :file:`\*.txt` or :file:`\*.py` in the sub-tree - under :file:`examples`, - -#. exclude all files in the sub-trees starting at directories matching - :file:`examples/sample?/build`\ ---this may exclude files included by the - previous two steps, so it's important that the ``prune`` command in the manifest - template comes after the ``recursive-include`` command - -#. exclude the entire :file:`build` tree, and any :file:`RCS`, :file:`CVS`, - :file:`.svn`, :file:`.hg`, :file:`.git`, :file:`.bzr` and :file:`_darcs` - directories - -Just like in the setup script, file and directory names in the manifest template -should always be slash-separated; the Distutils will take care of converting -them to the standard representation on your platform. That way, the manifest -template is portable across operating systems. - - -.. _manifest-options: - -Manifest-related options -======================== - -The normal course of operations for the :command:`sdist` command is as follows: - -* if the manifest file (:file:`MANIFEST` by default) exists and the first line - does not have a comment indicating it is generated from :file:`MANIFEST.in`, - then it is used as is, unaltered - -* if the manifest file doesn't exist or has been previously automatically - generated, read :file:`MANIFEST.in` and create the manifest - -* if neither :file:`MANIFEST` nor :file:`MANIFEST.in` exist, create a manifest - with just the default file set - -* use the list of files now in :file:`MANIFEST` (either just generated or read - in) to create the source distribution archive(s) - -There are a couple of options that modify this behaviour. First, use the -:option:`!--no-defaults` and :option:`!--no-prune` to disable the standard -"include" and "exclude" sets. - -Second, you might just want to (re)generate the manifest, but not create a source -distribution:: - - python setup.py sdist --manifest-only - -:option:`!-o` is a shortcut for :option:`!--manifest-only`. diff --git a/Doc/distutils/uploading.rst b/Doc/distutils/uploading.rst deleted file mode 100644 index 4c391cab..00000000 --- a/Doc/distutils/uploading.rst +++ /dev/null @@ -1,8 +0,0 @@ -:orphan: - -*************************************** -Uploading Packages to the Package Index -*************************************** - -References to up to date PyPI documentation can be found at -:ref:`publishing-python-packages`. diff --git a/Doc/extending/building.rst b/Doc/extending/building.rst index 53817074..ddde567f 100644 --- a/Doc/extending/building.rst +++ b/Doc/extending/building.rst @@ -11,7 +11,7 @@ A C extension for CPython is a shared library (e.g. a ``.so`` file on Linux, To be importable, the shared library must be available on :envvar:`PYTHONPATH`, and must be named after the module name, with an appropriate extension. -When using distutils, the correct filename is generated automatically. +When using setuptools, the correct filename is generated automatically. The initialization function has the signature: @@ -45,122 +45,13 @@ See the *"Multiple modules in one library"* section in :pep:`489` for details. .. highlight:: c -Building C and C++ Extensions with distutils -============================================ +.. _install-index: +.. _setuptools-index: -.. sectionauthor:: Martin v. Löwis <martin@v.loewis.de> +Building C and C++ Extensions with setuptools +============================================= -Extension modules can be built using distutils, which is included in Python. -Since distutils also supports creation of binary packages, users don't -necessarily need a compiler and distutils to install the extension. - -A distutils package contains a driver script, :file:`setup.py`. This is a plain -Python file, which, in the most simple case, could look like this: - -.. code-block:: python3 - - from distutils.core import setup, Extension - - module1 = Extension('demo', - sources = ['demo.c']) - - setup (name = 'PackageName', - version = '1.0', - description = 'This is a demo package', - ext_modules = [module1]) - - -With this :file:`setup.py`, and a file :file:`demo.c`, running :: - - python setup.py build - -will compile :file:`demo.c`, and produce an extension module named ``demo`` in -the :file:`build` directory. Depending on the system, the module file will end -up in a subdirectory :file:`build/lib.system`, and may have a name like -:file:`demo.so` or :file:`demo.pyd`. - -In the :file:`setup.py`, all execution is performed by calling the ``setup`` -function. This takes a variable number of keyword arguments, of which the -example above uses only a subset. Specifically, the example specifies -meta-information to build packages, and it specifies the contents of the -package. Normally, a package will contain additional modules, like Python -source modules, documentation, subpackages, etc. Please refer to the distutils -documentation in :ref:`distutils-index` to learn more about the features of -distutils; this section explains building extension modules only. - -It is common to pre-compute arguments to :func:`setup`, to better structure the -driver script. In the example above, the ``ext_modules`` argument to -:func:`~distutils.core.setup` is a list of extension modules, each of which is -an instance of -the :class:`~distutils.extension.Extension`. In the example, the instance -defines an extension named ``demo`` which is build by compiling a single source -file, :file:`demo.c`. - -In many cases, building an extension is more complex, since additional -preprocessor defines and libraries may be needed. This is demonstrated in the -example below. - -.. code-block:: python3 - - from distutils.core import setup, Extension - - module1 = Extension('demo', - define_macros = [('MAJOR_VERSION', '1'), - ('MINOR_VERSION', '0')], - include_dirs = ['/usr/local/include'], - libraries = ['tcl83'], - library_dirs = ['/usr/local/lib'], - sources = ['demo.c']) - - setup (name = 'PackageName', - version = '1.0', - description = 'This is a demo package', - author = 'Martin v. Loewis', - author_email = 'martin@v.loewis.de', - url = 'https://docs.python.org/extending/building', - long_description = ''' - This is really just a demo package. - ''', - ext_modules = [module1]) - - -In this example, :func:`~distutils.core.setup` is called with additional -meta-information, which -is recommended when distribution packages have to be built. For the extension -itself, it specifies preprocessor defines, include directories, library -directories, and libraries. Depending on the compiler, distutils passes this -information in different ways to the compiler. For example, on Unix, this may -result in the compilation commands :: - - gcc -DNDEBUG -g -O3 -Wall -Wstrict-prototypes -fPIC -DMAJOR_VERSION=1 -DMINOR_VERSION=0 -I/usr/local/include -I/usr/local/include/python2.2 -c demo.c -o build/temp.linux-i686-2.2/demo.o - - gcc -shared build/temp.linux-i686-2.2/demo.o -L/usr/local/lib -ltcl83 -o build/lib.linux-i686-2.2/demo.so - -These lines are for demonstration purposes only; distutils users should trust -that distutils gets the invocations right. - - -.. _distributing: - -Distributing your extension modules -=================================== - -When an extension has been successfully built, there are three ways to use it. - -End-users will typically want to install the module, they do so by running :: - - python setup.py install - -Module maintainers should produce source packages; to do so, they run :: - - python setup.py sdist - -In some cases, additional files need to be included in a source distribution; -this is done through a :file:`MANIFEST.in` file; see :ref:`manifest` for details. - -If the source distribution has been built successfully, maintainers can also -create binary distributions. Depending on the platform, one of the following -commands can be used to do so. :: - - python setup.py bdist_rpm - python setup.py bdist_dumb +Python 3.12 and newer no longer come with distutils. Please refer to the +``setuptools`` documentation at +https://setuptools.readthedocs.io/en/latest/setuptools.html +to learn more about how build and distribute C/C++ extensions with setuptools. diff --git a/Doc/extending/embedding.rst b/Doc/extending/embedding.rst index e64db373..4c7c7ec9 100644 --- a/Doc/extending/embedding.rst +++ b/Doc/extending/embedding.rst @@ -250,7 +250,7 @@ following two statements before the call to :c:func:`Py_Initialize`:: PyImport_AppendInittab("emb", &PyInit_emb); These two lines initialize the ``numargs`` variable, and make the -:func:`emb.numargs` function accessible to the embedded Python interpreter. +:func:`!emb.numargs` function accessible to the embedded Python interpreter. With these extensions, the Python script can do things like .. code-block:: python diff --git a/Doc/extending/extending.rst b/Doc/extending/extending.rst index d9bf4fd6..68f8e0c6 100644 --- a/Doc/extending/extending.rst +++ b/Doc/extending/extending.rst @@ -195,7 +195,7 @@ The choice of which exception to raise is entirely yours. There are predeclared C objects corresponding to all built-in Python exceptions, such as :c:data:`PyExc_ZeroDivisionError`, which you can use directly. Of course, you should choose exceptions wisely --- don't use :c:data:`PyExc_TypeError` to mean -that a file couldn't be opened (that should probably be :c:data:`PyExc_IOError`). +that a file couldn't be opened (that should probably be :c:data:`PyExc_OSError`). If something's wrong with the argument list, the :c:func:`PyArg_ParseTuple` function usually raises :c:data:`PyExc_TypeError`. If you have an argument whose value must be in a particular range or must satisfy other conditions, @@ -206,7 +206,7 @@ usually declare a static object variable at the beginning of your file:: static PyObject *SpamError; -and initialize it in your module's initialization function (:c:func:`PyInit_spam`) +and initialize it in your module's initialization function (:c:func:`!PyInit_spam`) with an exception object:: PyMODINIT_FUNC @@ -230,22 +230,22 @@ with an exception object:: return m; } -Note that the Python name for the exception object is :exc:`spam.error`. The +Note that the Python name for the exception object is :exc:`!spam.error`. The :c:func:`PyErr_NewException` function may create a class with the base class being :exc:`Exception` (unless another class is passed in instead of ``NULL``), described in :ref:`bltin-exceptions`. -Note also that the :c:data:`SpamError` variable retains a reference to the newly +Note also that the :c:data:`!SpamError` variable retains a reference to the newly created exception class; this is intentional! Since the exception could be removed from the module by external code, an owned reference to the class is -needed to ensure that it will not be discarded, causing :c:data:`SpamError` to +needed to ensure that it will not be discarded, causing :c:data:`!SpamError` to become a dangling pointer. Should it become a dangling pointer, C code which raises the exception could cause a core dump or other unintended side effects. -We discuss the use of ``PyMODINIT_FUNC`` as a function return type later in this +We discuss the use of :c:macro:`PyMODINIT_FUNC` as a function return type later in this sample. -The :exc:`spam.error` exception can be raised in your extension module using a +The :exc:`!spam.error` exception can be raised in your extension module using a call to :c:func:`PyErr_SetString` as shown below:: static PyObject * @@ -279,9 +279,9 @@ statement:: It returns ``NULL`` (the error indicator for functions returning object pointers) if an error is detected in the argument list, relying on the exception set by :c:func:`PyArg_ParseTuple`. Otherwise the string value of the argument has been -copied to the local variable :c:data:`command`. This is a pointer assignment and +copied to the local variable :c:data:`!command`. This is a pointer assignment and you are not supposed to modify the string to which it points (so in Standard C, -the variable :c:data:`command` should properly be declared as ``const char +the variable :c:data:`!command` should properly be declared as ``const char *command``). The next statement is a call to the Unix function :c:func:`system`, passing it @@ -289,7 +289,7 @@ the string we just got from :c:func:`PyArg_ParseTuple`:: sts = system(command); -Our :func:`spam.system` function must return the value of :c:data:`sts` as a +Our :func:`!spam.system` function must return the value of :c:data:`!sts` as a Python object. This is done using the function :c:func:`PyLong_FromLong`. :: return PyLong_FromLong(sts); @@ -315,7 +315,7 @@ contexts, as we have seen. The Module's Method Table and Initialization Function ===================================================== -I promised to show how :c:func:`spam_system` is called from Python programs. +I promised to show how :c:func:`!spam_system` is called from Python programs. First, we need to list its name and address in a "method table":: static PyMethodDef SpamMethods[] = { @@ -335,7 +335,7 @@ When using only ``METH_VARARGS``, the function should expect the Python-level parameters to be passed in as a tuple acceptable for parsing via :c:func:`PyArg_ParseTuple`; more information on this function is provided below. -The :const:`METH_KEYWORDS` bit may be set in the third field if keyword +The :c:macro:`METH_KEYWORDS` bit may be set in the third field if keyword arguments should be passed to the function. In this case, the C function should accept a third ``PyObject *`` parameter which will be a dictionary of keywords. Use :c:func:`PyArg_ParseTupleAndKeywords` to parse the arguments to such a @@ -354,7 +354,7 @@ The method table must be referenced in the module definition structure:: This structure, in turn, must be passed to the interpreter in the module's initialization function. The initialization function must be named -:c:func:`PyInit_name`, where *name* is the name of the module, and should be the +:c:func:`!PyInit_name`, where *name* is the name of the module, and should be the only non-\ ``static`` item defined in the module file:: PyMODINIT_FUNC @@ -363,12 +363,12 @@ only non-\ ``static`` item defined in the module file:: return PyModule_Create(&spammodule); } -Note that PyMODINIT_FUNC declares the function as ``PyObject *`` return type, +Note that :c:macro:`PyMODINIT_FUNC` declares the function as ``PyObject *`` return type, declares any special linkage declarations required by the platform, and for C++ declares the function as ``extern "C"``. -When the Python program imports module :mod:`spam` for the first time, -:c:func:`PyInit_spam` is called. (See below for comments about embedding Python.) +When the Python program imports module :mod:`!spam` for the first time, +:c:func:`!PyInit_spam` is called. (See below for comments about embedding Python.) It calls :c:func:`PyModule_Create`, which returns a module object, and inserts built-in function objects into the newly created module based upon the table (an array of :c:type:`PyMethodDef` structures) found in the module definition. @@ -378,7 +378,7 @@ certain errors, or return ``NULL`` if the module could not be initialized satisfactorily. The init function must return the module object to its caller, so that it then gets inserted into ``sys.modules``. -When embedding Python, the :c:func:`PyInit_spam` function is not called +When embedding Python, the :c:func:`!PyInit_spam` function is not called automatically unless there's an entry in the :c:data:`PyImport_Inittab` table. To add the module to the initialization table, use :c:func:`PyImport_AppendInittab`, optionally followed by an import of the module:: @@ -527,7 +527,7 @@ be part of a module definition:: } This function must be registered with the interpreter using the -:const:`METH_VARARGS` flag; this is described in section :ref:`methodtable`. The +:c:macro:`METH_VARARGS` flag; this is described in section :ref:`methodtable`. The :c:func:`PyArg_ParseTuple` function and its arguments are documented in section :ref:`parsetuple`. @@ -1030,13 +1030,13 @@ Let's follow the control flow into :c:func:`PyList_SetItem`. The list owns references to all its items, so when item 1 is replaced, it has to dispose of the original item 1. Now let's suppose the original item 1 was an instance of a user-defined class, and let's further suppose that the class defined a -:meth:`__del__` method. If this class instance has a reference count of 1, -disposing of it will call its :meth:`__del__` method. +:meth:`!__del__` method. If this class instance has a reference count of 1, +disposing of it will call its :meth:`!__del__` method. -Since it is written in Python, the :meth:`__del__` method can execute arbitrary +Since it is written in Python, the :meth:`!__del__` method can execute arbitrary Python code. Could it perhaps do something to invalidate the reference to -``item`` in :c:func:`bug`? You bet! Assuming that the list passed into -:c:func:`bug` is accessible to the :meth:`__del__` method, it could execute a +``item`` in :c:func:`!bug`? You bet! Assuming that the list passed into +:c:func:`!bug` is accessible to the :meth:`!__del__` method, it could execute a statement to the effect of ``del list[0]``, and assuming this was the last reference to that object, it would free the memory associated with it, thereby invalidating ``item``. @@ -1057,7 +1057,7 @@ increment the reference count. The correct version of the function reads:: This is a true story. An older version of Python contained variants of this bug and someone spent a considerable amount of time in a C debugger to figure out -why his :meth:`__del__` methods would fail... +why his :meth:`!__del__` methods would fail... The second case of problems with a borrowed reference is a variant involving threads. Normally, multiple threads in the Python interpreter can't get in each @@ -1208,14 +1208,14 @@ file corresponding to the module provides a macro that takes care of importing the module and retrieving its C API pointers; client modules only have to call this macro before accessing the C API. -The exporting module is a modification of the :mod:`spam` module from section -:ref:`extending-simpleexample`. The function :func:`spam.system` does not call +The exporting module is a modification of the :mod:`!spam` module from section +:ref:`extending-simpleexample`. The function :func:`!spam.system` does not call the C library function :c:func:`system` directly, but a function -:c:func:`PySpam_System`, which would of course do something more complicated in +:c:func:`!PySpam_System`, which would of course do something more complicated in reality (such as adding "spam" to every command). This function -:c:func:`PySpam_System` is also exported to other extension modules. +:c:func:`!PySpam_System` is also exported to other extension modules. -The function :c:func:`PySpam_System` is a plain C function, declared +The function :c:func:`!PySpam_System` is a plain C function, declared ``static`` like everything else:: static int @@ -1224,7 +1224,7 @@ The function :c:func:`PySpam_System` is a plain C function, declared return system(command); } -The function :c:func:`spam_system` is modified in a trivial way:: +The function :c:func:`!spam_system` is modified in a trivial way:: static PyObject * spam_system(PyObject *self, PyObject *args) @@ -1278,7 +1278,7 @@ function must take care of initializing the C API pointer array:: } Note that ``PySpam_API`` is declared ``static``; otherwise the pointer -array would disappear when :func:`PyInit_spam` terminates! +array would disappear when :c:func:`!PyInit_spam` terminates! The bulk of the work is in the header file :file:`spammodule.h`, which looks like this:: @@ -1332,8 +1332,8 @@ like this:: #endif /* !defined(Py_SPAMMODULE_H) */ All that a client module must do in order to have access to the function -:c:func:`PySpam_System` is to call the function (or rather macro) -:c:func:`import_spam` in its initialization function:: +:c:func:`!PySpam_System` is to call the function (or rather macro) +:c:func:`!import_spam` in its initialization function:: PyMODINIT_FUNC PyInit_client(void) diff --git a/Doc/extending/newtypes.rst b/Doc/extending/newtypes.rst index 5ba63836..9f166eb8 100644 --- a/Doc/extending/newtypes.rst +++ b/Doc/extending/newtypes.rst @@ -149,7 +149,7 @@ done. This can be done using the :c:func:`PyErr_Fetch` and .. index:: single: string; object representation - builtin: repr + pair: built-in function; repr Object Presentation ------------------- @@ -168,7 +168,7 @@ representation of the instance for which it is called. Here is a simple example:: static PyObject * - newdatatype_repr(newdatatypeobject * obj) + newdatatype_repr(newdatatypeobject *obj) { return PyUnicode_FromFormat("Repr-ified_newdatatype{{size:%d}}", obj->obj_UnderlyingDatatypePtr->size); @@ -188,7 +188,7 @@ used instead. Here is a simple example:: static PyObject * - newdatatype_str(newdatatypeobject * obj) + newdatatype_str(newdatatypeobject *obj) { return PyUnicode_FromFormat("Stringified_newdatatype{{size:%d}}", obj->obj_UnderlyingDatatypePtr->size); @@ -270,7 +270,7 @@ structure:: One entry should be defined for each method provided by the type; no entries are needed for methods inherited from a base type. One additional entry is needed at the end; it is a sentinel that marks the end of the array. The -:attr:`ml_name` field of the sentinel must be ``NULL``. +:c:member:`~PyMethodDef.ml_name` field of the sentinel must be ``NULL``. The second table is used to define attributes which map directly to data stored in the instance. A variety of primitive C types are supported, and access may @@ -286,36 +286,11 @@ be read-only or read-write. The structures in the table are defined as:: For each entry in the table, a :term:`descriptor` will be constructed and added to the type which will be able to extract a value from the instance structure. The -:attr:`type` field should contain one of the type codes defined in the -:file:`structmember.h` header; the value will be used to determine how to -convert Python values to and from C values. The :attr:`flags` field is used to -store flags which control how the attribute can be accessed. - -The following flag constants are defined in :file:`structmember.h`; they may be -combined using bitwise-OR. - -+---------------------------+----------------------------------------------+ -| Constant | Meaning | -+===========================+==============================================+ -| :const:`READONLY` | Never writable. | -+---------------------------+----------------------------------------------+ -| :const:`PY_AUDIT_READ` | Emit an ``object.__getattr__`` | -| | :ref:`audit events <audit-events>` before | -| | reading. | -+---------------------------+----------------------------------------------+ - -.. versionchanged:: 3.10 - :const:`RESTRICTED`, :const:`READ_RESTRICTED` and :const:`WRITE_RESTRICTED` - are deprecated. However, :const:`READ_RESTRICTED` is an alias for - :const:`PY_AUDIT_READ`, so fields that specify either :const:`RESTRICTED` - or :const:`READ_RESTRICTED` will also raise an audit event. - -.. index:: - single: READONLY - single: READ_RESTRICTED - single: WRITE_RESTRICTED - single: RESTRICTED - single: PY_AUDIT_READ +:c:member:`~PyMemberDef.type` field should contain a type code like :c:macro:`Py_T_INT` or +:c:macro:`Py_T_DOUBLE`; the value will be used to determine how to +convert Python values to and from C values. The :c:member:`~PyMemberDef.flags` field is used to +store flags which control how the attribute can be accessed: you can set it to +:c:macro:`Py_READONLY` to prevent Python code from setting it. An interesting advantage of using the :c:member:`~PyTypeObject.tp_members` table to build descriptors that are used at runtime is that any attribute defined this way can @@ -323,7 +298,7 @@ have an associated doc string simply by providing the text in the table. An application can use the introspection API to retrieve the descriptor from the class object, and get the doc string using its :attr:`__doc__` attribute. -As with the :c:member:`~PyTypeObject.tp_methods` table, a sentinel entry with a :attr:`name` value +As with the :c:member:`~PyTypeObject.tp_methods` table, a sentinel entry with a :c:member:`~PyMethodDef.ml_name` value of ``NULL`` is required. .. XXX Descriptors need to be explained in more detail somewhere, but not here. @@ -348,7 +323,7 @@ called, so that if you do need to extend their functionality, you'll understand what needs to be done. The :c:member:`~PyTypeObject.tp_getattr` handler is called when the object requires an attribute -look-up. It is called in the same situations where the :meth:`__getattr__` +look-up. It is called in the same situations where the :meth:`~object.__getattr__` method of a class would be called. Here is an example:: @@ -362,13 +337,13 @@ Here is an example:: } PyErr_Format(PyExc_AttributeError, - "'%.50s' object has no attribute '%.400s'", - tp->tp_name, name); + "'%.100s' object has no attribute '%.400s'", + Py_TYPE(obj)->tp_name, name); return NULL; } -The :c:member:`~PyTypeObject.tp_setattr` handler is called when the :meth:`__setattr__` or -:meth:`__delattr__` method of a class instance would be called. When an +The :c:member:`~PyTypeObject.tp_setattr` handler is called when the :meth:`~object.__setattr__` or +:meth:`~object.__delattr__` method of a class instance would be called. When an attribute should be deleted, the third parameter will be ``NULL``. Here is an example that simply raises an exception; if this were really all you wanted, the :c:member:`~PyTypeObject.tp_setattr` handler should be set to ``NULL``. :: @@ -389,7 +364,7 @@ Object Comparison The :c:member:`~PyTypeObject.tp_richcompare` handler is called when comparisons are needed. It is analogous to the :ref:`rich comparison methods <richcmpfuncs>`, like -:meth:`__lt__`, and also called by :c:func:`PyObject_RichCompare` and +:meth:`!__lt__`, and also called by :c:func:`PyObject_RichCompare` and :c:func:`PyObject_RichCompareBool`. This function is called with two Python objects and the operator as arguments, @@ -404,7 +379,7 @@ Here is a sample implementation, for a datatype that is considered equal if the size of an internal pointer is equal:: static PyObject * - newdatatype_richcmp(PyObject *obj1, PyObject *obj2, int op) + newdatatype_richcmp(newdatatypeobject *obj1, newdatatypeobject *obj2, int op) { PyObject *result; int c, size1, size2; @@ -503,7 +478,7 @@ This function takes three arguments: Here is a toy ``tp_call`` implementation:: static PyObject * - newdatatype_call(newdatatypeobject *self, PyObject *args, PyObject *kwds) + newdatatype_call(newdatatypeobject *obj, PyObject *args, PyObject *kwds) { PyObject *result; const char *arg1; @@ -530,7 +505,7 @@ These functions provide support for the iterator protocol. Both handlers take exactly one parameter, the instance for which they are being called, and return a new reference. In the case of an error, they should set an exception and return ``NULL``. :c:member:`~PyTypeObject.tp_iter` corresponds -to the Python :meth:`__iter__` method, while :c:member:`~PyTypeObject.tp_iternext` +to the Python :meth:`~object.__iter__` method, while :c:member:`~PyTypeObject.tp_iternext` corresponds to the Python :meth:`~iterator.__next__` method. Any :term:`iterable` object must implement the :c:member:`~PyTypeObject.tp_iter` @@ -570,43 +545,28 @@ performance-critical objects (such as numbers). .. seealso:: Documentation for the :mod:`weakref` module. -For an object to be weakly referencable, the extension type must do two things: - -#. Include a :c:expr:`PyObject*` field in the C object structure dedicated to - the weak reference mechanism. The object's constructor should leave it - ``NULL`` (which is automatic when using the default - :c:member:`~PyTypeObject.tp_alloc`). - -#. Set the :c:member:`~PyTypeObject.tp_weaklistoffset` type member - to the offset of the aforementioned field in the C object structure, - so that the interpreter knows how to access and modify that field. +For an object to be weakly referencable, the extension type must set the +``Py_TPFLAGS_MANAGED_WEAKREF`` bit of the :c:member:`~PyTypeObject.tp_flags` +field. The legacy :c:member:`~PyTypeObject.tp_weaklistoffset` field should +be left as zero. -Concretely, here is how a trivial object structure would be augmented -with the required field:: - - typedef struct { - PyObject_HEAD - PyObject *weakreflist; /* List of weak references */ - } TrivialObject; - -And the corresponding member in the statically declared type object:: +Concretely, here is how the statically declared type object would look:: static PyTypeObject TrivialType = { PyVarObject_HEAD_INIT(NULL, 0) /* ... other members omitted for brevity ... */ - .tp_weaklistoffset = offsetof(TrivialObject, weakreflist), + .tp_flags = Py_TPFLAGS_MANAGED_WEAKREF | ..., }; + The only further addition is that ``tp_dealloc`` needs to clear any weak -references (by calling :c:func:`PyObject_ClearWeakRefs`) if the field is -non-``NULL``:: +references (by calling :c:func:`PyObject_ClearWeakRefs`):: static void Trivial_dealloc(TrivialObject *self) { /* Clear weakrefs first before calling any destructors */ - if (self->weakreflist != NULL) - PyObject_ClearWeakRefs((PyObject *) self); + PyObject_ClearWeakRefs((PyObject *) self); /* ... remainder of destruction code omitted for brevity ... */ Py_TYPE(self)->tp_free((PyObject *) self); } diff --git a/Doc/extending/newtypes_tutorial.rst b/Doc/extending/newtypes_tutorial.rst index 5d4a3f06..c2bc5f69 100644 --- a/Doc/extending/newtypes_tutorial.rst +++ b/Doc/extending/newtypes_tutorial.rst @@ -36,8 +36,8 @@ So, if you want to define a new extension type, you need to create a new type object. This sort of thing can only be explained by example, so here's a minimal, but -complete, module that defines a new type named :class:`Custom` inside a C -extension module :mod:`custom`: +complete, module that defines a new type named :class:`!Custom` inside a C +extension module :mod:`!custom`: .. note:: What we're showing here is the traditional way of defining *static* @@ -45,17 +45,17 @@ extension module :mod:`custom`: allows defining heap-allocated extension types using the :c:func:`PyType_FromSpec` function, which isn't covered in this tutorial. -.. literalinclude:: ../includes/custom.c +.. literalinclude:: ../includes/newtypes/custom.c Now that's quite a bit to take in at once, but hopefully bits will seem familiar from the previous chapter. This file defines three things: -#. What a :class:`Custom` **object** contains: this is the ``CustomObject`` - struct, which is allocated once for each :class:`Custom` instance. -#. How the :class:`Custom` **type** behaves: this is the ``CustomType`` struct, +#. What a :class:`!Custom` **object** contains: this is the ``CustomObject`` + struct, which is allocated once for each :class:`!Custom` instance. +#. How the :class:`!Custom` **type** behaves: this is the ``CustomType`` struct, which defines a set of flags and function pointers that the interpreter inspects when specific operations are requested. -#. How to initialize the :mod:`custom` module: this is the ``PyInit_custom`` +#. How to initialize the :mod:`!custom` module: this is the ``PyInit_custom`` function and the associated ``custommodule`` struct. The first bit is:: @@ -88,7 +88,7 @@ standard Python floats:: The second bit is the definition of the type object. :: static PyTypeObject CustomType = { - PyVarObject_HEAD_INIT(NULL, 0) + .ob_base = PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "custom.Custom", .tp_doc = PyDoc_STR("Custom objects"), .tp_basicsize = sizeof(CustomObject), @@ -109,7 +109,7 @@ common practice to not specify them explicitly unless you need them. We're going to pick it apart, one field at a time:: - PyVarObject_HEAD_INIT(NULL, 0) + .ob_base = PyVarObject_HEAD_INIT(NULL, 0) This line is mandatory boilerplate to initialize the ``ob_base`` field mentioned above. :: @@ -127,8 +127,8 @@ our objects and in some error messages, for example: TypeError: can only concatenate str (not "custom.Custom") to str Note that the name is a dotted name that includes both the module name and the -name of the type within the module. The module in this case is :mod:`custom` and -the type is :class:`Custom`, so we set the type name to :class:`custom.Custom`. +name of the type within the module. The module in this case is :mod:`!custom` and +the type is :class:`!Custom`, so we set the type name to :class:`!custom.Custom`. Using the real dotted import path is important to make your type compatible with the :mod:`pydoc` and :mod:`pickle` modules. :: @@ -136,7 +136,7 @@ with the :mod:`pydoc` and :mod:`pickle` modules. :: .tp_itemsize = 0, This is so that Python knows how much memory to allocate when creating -new :class:`Custom` instances. :c:member:`~PyTypeObject.tp_itemsize` is +new :class:`!Custom` instances. :c:member:`~PyTypeObject.tp_itemsize` is only used for variable-sized objects and should otherwise be zero. .. note:: @@ -145,13 +145,13 @@ only used for variable-sized objects and should otherwise be zero. :c:member:`~PyTypeObject.tp_basicsize` as its base type, you may have problems with multiple inheritance. A Python subclass of your type will have to list your type first in its :attr:`~class.__bases__`, or else it will not be able to call your type's - :meth:`__new__` method without getting an error. You can avoid this problem by + :meth:`~object.__new__` method without getting an error. You can avoid this problem by ensuring that your type has a larger value for :c:member:`~PyTypeObject.tp_basicsize` than its base type does. Most of the time, this will be true anyway, because either your base type will be :class:`object`, or else you will be adding data members to your base type, and therefore increasing its size. -We set the class flags to :const:`Py_TPFLAGS_DEFAULT`. :: +We set the class flags to :c:macro:`Py_TPFLAGS_DEFAULT`. :: .tp_flags = Py_TPFLAGS_DEFAULT, @@ -164,20 +164,20 @@ We provide a doc string for the type in :c:member:`~PyTypeObject.tp_doc`. :: .tp_doc = PyDoc_STR("Custom objects"), To enable object creation, we have to provide a :c:member:`~PyTypeObject.tp_new` -handler. This is the equivalent of the Python method :meth:`__new__`, but +handler. This is the equivalent of the Python method :meth:`~object.__new__`, but has to be specified explicitly. In this case, we can just use the default implementation provided by the API function :c:func:`PyType_GenericNew`. :: .tp_new = PyType_GenericNew, Everything else in the file should be familiar, except for some code in -:c:func:`PyInit_custom`:: +:c:func:`!PyInit_custom`:: if (PyType_Ready(&CustomType) < 0) return; -This initializes the :class:`Custom` type, filling in a number of members -to the appropriate default values, including :attr:`ob_type` that we initially +This initializes the :class:`!Custom` type, filling in a number of members +to the appropriate default values, including :c:member:`~PyObject.ob_type` that we initially set to ``NULL``. :: Py_INCREF(&CustomType); @@ -188,7 +188,7 @@ set to ``NULL``. :: } This adds the type to the module dictionary. This allows us to create -:class:`Custom` instances by calling the :class:`Custom` class: +:class:`!Custom` instances by calling the :class:`!Custom` class: .. code-block:: pycon @@ -196,57 +196,46 @@ This adds the type to the module dictionary. This allows us to create >>> mycustom = custom.Custom() That's it! All that remains is to build it; put the above code in a file called -:file:`custom.c` and: +:file:`custom.c`, + +.. literalinclude:: ../includes/newtypes/pyproject.toml + +in a file called :file:`pyproject.toml`, and .. code-block:: python - from distutils.core import setup, Extension - setup(name="custom", version="1.0", - ext_modules=[Extension("custom", ["custom.c"])]) + from setuptools import Extension, setup + setup(ext_modules=[Extension("custom", ["custom.c"])]) in a file called :file:`setup.py`; then typing .. code-block:: shell-session - $ python setup.py build + $ python -m pip install . -at a shell should produce a file :file:`custom.so` in a subdirectory; move to -that directory and fire up Python --- you should be able to ``import custom`` and -play around with Custom objects. +in a shell should produce a file :file:`custom.so` in a subdirectory +and install it; now fire up Python --- you should be able to ``import custom`` +and play around with ``Custom`` objects. That wasn't so hard, was it? Of course, the current Custom type is pretty uninteresting. It has no data and doesn't do anything. It can't even be subclassed. -.. note:: - While this documentation showcases the standard :mod:`distutils` module - for building C extensions, it is recommended in real-world use cases to - use the newer and better-maintained ``setuptools`` library. Documentation - on how to do this is out of scope for this document and can be found in - the `Python Packaging User's Guide <https://packaging.python.org/tutorials/distributing-packages/>`_. - Adding data and methods to the Basic example ============================================ Let's extend the basic example to add some data and methods. Let's also make -the type usable as a base class. We'll create a new module, :mod:`custom2` that +the type usable as a base class. We'll create a new module, :mod:`!custom2` that adds these capabilities: -.. literalinclude:: ../includes/custom2.c +.. literalinclude:: ../includes/newtypes/custom2.c This version of the module has a number of changes. -We've added an extra include:: - - #include <structmember.h> - -This include provides declarations that we use to handle attributes, as -described a bit later. - -The :class:`Custom` type now has three data attributes in its C struct, +The :class:`!Custom` type now has three data attributes in its C struct, *first*, *last*, and *number*. The *first* and *last* variables are Python strings containing first and last names. The *number* attribute is a C integer. @@ -279,7 +268,7 @@ This method first clears the reference counts of the two Python attributes. ``NULL`` (which might happen here if ``tp_new`` failed midway). It then calls the :c:member:`~PyTypeObject.tp_free` member of the object's type (computed by ``Py_TYPE(self)``) to free the object's memory. Note that -the object's type might not be :class:`CustomType`, because the object may +the object's type might not be :class:`!CustomType`, because the object may be an instance of a subclass. .. note:: @@ -318,10 +307,10 @@ and install it in the :c:member:`~PyTypeObject.tp_new` member:: .tp_new = Custom_new, The ``tp_new`` handler is responsible for creating (as opposed to initializing) -objects of the type. It is exposed in Python as the :meth:`__new__` method. +objects of the type. It is exposed in Python as the :meth:`~object.__new__` method. It is not required to define a ``tp_new`` member, and indeed many extension types will simply reuse :c:func:`PyType_GenericNew` as done in the first -version of the ``Custom`` type above. In this case, we use the ``tp_new`` +version of the :class:`!Custom` type above. In this case, we use the ``tp_new`` handler to initialize the ``first`` and ``last`` attributes to non-``NULL`` default values. @@ -352,7 +341,7 @@ result against ``NULL`` before proceeding. .. note:: If you are creating a co-operative :c:member:`~PyTypeObject.tp_new` (one - that calls a base type's :c:member:`~PyTypeObject.tp_new` or :meth:`__new__`), + that calls a base type's :c:member:`~PyTypeObject.tp_new` or :meth:`~object.__new__`), you must *not* try to determine what method to call using method resolution order at runtime. Always statically determine what type you are going to call, and call its :c:member:`~PyTypeObject.tp_new` directly, or via @@ -395,14 +384,14 @@ by filling the :c:member:`~PyTypeObject.tp_init` slot. :: .tp_init = (initproc) Custom_init, The :c:member:`~PyTypeObject.tp_init` slot is exposed in Python as the -:meth:`__init__` method. It is used to initialize an object after it's +:meth:`~object.__init__` method. It is used to initialize an object after it's created. Initializers always accept positional and keyword arguments, and they should return either ``0`` on success or ``-1`` on error. Unlike the ``tp_new`` handler, there is no guarantee that ``tp_init`` is called at all (for example, the :mod:`pickle` module by default -doesn't call :meth:`__init__` on unpickled instances). It can also be -called multiple times. Anyone can call the :meth:`__init__` method on +doesn't call :meth:`~object.__init__` on unpickled instances). It can also be +called multiple times. Anyone can call the :meth:`!__init__` method on our objects. For this reason, we have to be extra careful when assigning the new attribute values. We might be tempted, for example to assign the ``first`` member like this:: @@ -436,11 +425,11 @@ We want to expose our instance variables as attributes. There are a number of ways to do that. The simplest way is to define member definitions:: static PyMemberDef Custom_members[] = { - {"first", T_OBJECT_EX, offsetof(CustomObject, first), 0, + {"first", Py_T_OBJECT_EX, offsetof(CustomObject, first), 0, "first name"}, - {"last", T_OBJECT_EX, offsetof(CustomObject, last), 0, + {"last", Py_T_OBJECT_EX, offsetof(CustomObject, last), 0, "last name"}, - {"number", T_INT, offsetof(CustomObject, number), 0, + {"number", Py_T_INT, offsetof(CustomObject, number), 0, "custom number"}, {NULL} /* Sentinel */ }; @@ -460,7 +449,7 @@ Further, the attributes can be deleted, setting the C pointers to ``NULL``. Eve though we can make sure the members are initialized to non-``NULL`` values, the members can be set to ``NULL`` if the attributes are deleted. -We define a single method, :meth:`Custom.name()`, that outputs the objects name as the +We define a single method, :meth:`!Custom.name()`, that outputs the objects name as the concatenation of the first and last names. :: static PyObject * @@ -477,8 +466,8 @@ concatenation of the first and last names. :: return PyUnicode_FromFormat("%S %S", self->first, self->last); } -The method is implemented as a C function that takes a :class:`Custom` (or -:class:`Custom` subclass) instance as the first argument. Methods always take an +The method is implemented as a C function that takes a :class:`!Custom` (or +:class:`!Custom` subclass) instance as the first argument. Methods always take an instance as the first argument. Methods often take positional and keyword arguments as well, but in this case we don't take any and don't need to accept a positional argument tuple or keyword argument dictionary. This method is @@ -489,8 +478,8 @@ equivalent to the Python method: def name(self): return "%s %s" % (self.first, self.last) -Note that we have to check for the possibility that our :attr:`first` and -:attr:`last` members are ``NULL``. This is because they can be deleted, in which +Note that we have to check for the possibility that our :attr:`!first` and +:attr:`!last` members are ``NULL``. This is because they can be deleted, in which case they are set to ``NULL``. It would be better to prevent deletion of these attributes and to restrict the attribute values to be strings. We'll see how to do that in the next section. @@ -505,7 +494,7 @@ definitions:: {NULL} /* Sentinel */ }; -(note that we used the :const:`METH_NOARGS` flag to indicate that the method +(note that we used the :c:macro:`METH_NOARGS` flag to indicate that the method is expecting no arguments other than *self*) and assign it to the :c:member:`~PyTypeObject.tp_methods` slot:: @@ -515,41 +504,45 @@ and assign it to the :c:member:`~PyTypeObject.tp_methods` slot:: Finally, we'll make our type usable as a base class for subclassing. We've written our methods carefully so far so that they don't make any assumptions about the type of the object being created or used, so all we need to do is -to add the :const:`Py_TPFLAGS_BASETYPE` to our class flag definition:: +to add the :c:macro:`Py_TPFLAGS_BASETYPE` to our class flag definition:: .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, -We rename :c:func:`PyInit_custom` to :c:func:`PyInit_custom2`, update the +We rename :c:func:`!PyInit_custom` to :c:func:`!PyInit_custom2`, update the module name in the :c:type:`PyModuleDef` struct, and update the full class name in the :c:type:`PyTypeObject` struct. -Finally, we update our :file:`setup.py` file to build the new module: +Finally, we update our :file:`setup.py` file to include the new module, .. code-block:: python - from distutils.core import setup, Extension - setup(name="custom", version="1.0", - ext_modules=[ - Extension("custom", ["custom.c"]), - Extension("custom2", ["custom2.c"]), - ]) + from setuptools import Extension, setup + setup(ext_modules=[ + Extension("custom", ["custom.c"]), + Extension("custom2", ["custom2.c"]), + ]) + +and then we re-install so that we can ``import custom2``: + +.. code-block:: shell-session + $ python -m pip install . Providing finer control over data attributes ============================================ -In this section, we'll provide finer control over how the :attr:`first` and -:attr:`last` attributes are set in the :class:`Custom` example. In the previous -version of our module, the instance variables :attr:`first` and :attr:`last` +In this section, we'll provide finer control over how the :attr:`!first` and +:attr:`!last` attributes are set in the :class:`!Custom` example. In the previous +version of our module, the instance variables :attr:`!first` and :attr:`!last` could be set to non-string values or even deleted. We want to make sure that these attributes always contain strings. -.. literalinclude:: ../includes/custom3.c +.. literalinclude:: ../includes/newtypes/custom3.c -To provide greater control, over the :attr:`first` and :attr:`last` attributes, +To provide greater control, over the :attr:`!first` and :attr:`!last` attributes, we'll use custom getter and setter functions. Here are the functions for -getting and setting the :attr:`first` attribute:: +getting and setting the :attr:`!first` attribute:: static PyObject * Custom_getfirst(CustomObject *self, void *closure) @@ -578,13 +571,13 @@ getting and setting the :attr:`first` attribute:: return 0; } -The getter function is passed a :class:`Custom` object and a "closure", which is +The getter function is passed a :class:`!Custom` object and a "closure", which is a void pointer. In this case, the closure is ignored. (The closure supports an advanced usage in which definition data is passed to the getter and setter. This could, for example, be used to allow a single set of getter and setter functions that decide the attribute to get or set based on data in the closure.) -The setter function is passed the :class:`Custom` object, the new value, and the +The setter function is passed the :class:`!Custom` object, the new value, and the closure. The new value may be ``NULL``, in which case the attribute is being deleted. In our setter, we raise an error if the attribute is deleted or if its new value is not a string. @@ -609,7 +602,7 @@ above. In this case, we aren't using a closure, so we just pass ``NULL``. We also remove the member definitions for these attributes:: static PyMemberDef Custom_members[] = { - {"number", T_INT, offsetof(CustomObject, number), 0, + {"number", Py_T_INT, offsetof(CustomObject, number), 0, "custom number"}, {NULL} /* Sentinel */ }; @@ -673,11 +666,11 @@ still has a reference from itself. Its reference count doesn't drop to zero. 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:`Custom` example, we allowed any kind of -object to be stored in the :attr:`first` or :attr:`last` attributes [#]_. +In the second version of the :class:`!Custom` example, we allowed any kind of +object to be stored in the :attr:`!first` or :attr:`!last` attributes [#]_. Besides, in the second and third versions, we allowed subclassing -:class:`Custom`, and subclasses may add arbitrary attributes. For any of -those two reasons, :class:`Custom` objects can participate in cycles: +:class:`!Custom`, and subclasses may add arbitrary attributes. For any of +those two reasons, :class:`!Custom` objects can participate in cycles: .. code-block:: pycon @@ -687,11 +680,11 @@ those two reasons, :class:`Custom` objects can participate in cycles: >>> n = Derived() >>> n.some_attribute = n -To allow a :class:`Custom` instance participating in a reference cycle to -be properly detected and collected by the cyclic GC, our :class:`Custom` type +To allow a :class:`!Custom` instance participating in a reference cycle to +be properly detected and collected by the cyclic GC, our :class:`!Custom` type needs to fill two additional slots and to enable a flag that enables these slots: -.. literalinclude:: ../includes/custom4.c +.. literalinclude:: ../includes/newtypes/custom4.c First, the traversal method lets the cyclic GC know about subobjects that could @@ -715,8 +708,8 @@ participate in cycles:: } For each subobject that can participate in cycles, we need to call the -:c:func:`visit` function, which is passed to the traversal method. The -:c:func:`visit` function takes as arguments the subobject and the extra argument +:c:func:`!visit` function, which is passed to the traversal method. The +:c:func:`!visit` function takes as arguments the subobject and the extra argument *arg* passed to the traversal method. It returns an integer value that must be returned if it is non-zero. @@ -781,7 +774,7 @@ and ``Custom_clear``:: Py_TYPE(self)->tp_free((PyObject *) self); } -Finally, we add the :const:`Py_TPFLAGS_HAVE_GC` flag to the class flags:: +Finally, we add the :c:macro:`Py_TPFLAGS_HAVE_GC` flag to the class flags:: .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, @@ -798,9 +791,9 @@ types. It is easiest to inherit from the built in types, since an extension can easily use the :c:type:`PyTypeObject` it needs. It can be difficult to share these :c:type:`PyTypeObject` structures between extension modules. -In this example we will create a :class:`SubList` type that inherits from the +In this example we will create a :class:`!SubList` type that inherits from the built-in :class:`list` type. The new type will be completely compatible with -regular lists, but will have an additional :meth:`increment` method that +regular lists, but will have an additional :meth:`!increment` method that increases an internal counter: .. code-block:: pycon @@ -815,10 +808,10 @@ increases an internal counter: >>> print(s.increment()) 2 -.. literalinclude:: ../includes/sublist.c +.. literalinclude:: ../includes/newtypes/sublist.c -As you can see, the source code closely resembles the :class:`Custom` examples in +As you can see, the source code closely resembles the :class:`!Custom` examples in previous sections. We will break down the main differences between them. :: typedef struct { @@ -830,7 +823,7 @@ The primary difference for derived type objects is that the base type's object structure must be the first value. The base type will already include the :c:func:`PyObject_HEAD` at the beginning of its structure. -When a Python object is a :class:`SubList` instance, its ``PyObject *`` pointer +When a Python object is a :class:`!SubList` instance, its ``PyObject *`` pointer can be safely cast to both ``PyListObject *`` and ``SubListObject *``:: static int @@ -842,7 +835,7 @@ can be safely cast to both ``PyListObject *`` and ``SubListObject *``:: return 0; } -We see above how to call through to the :attr:`__init__` method of the base +We see above how to call through to the :meth:`~object.__init__` method of the base type. This pattern is important when writing a type with custom @@ -886,7 +879,7 @@ slot with :c:func:`PyType_GenericNew` -- the allocation function from the base type will be inherited. After that, calling :c:func:`PyType_Ready` and adding the type object to the -module is the same as with the basic :class:`Custom` examples. +module is the same as with the basic :class:`!Custom` examples. .. rubric:: Footnotes diff --git a/Doc/extending/windows.rst b/Doc/extending/windows.rst index 28d0350f..e366d6cb 100644 --- a/Doc/extending/windows.rst +++ b/Doc/extending/windows.rst @@ -34,10 +34,10 @@ A Cookbook Approach =================== There are two approaches to building extension modules on Windows, just as there -are on Unix: use the :mod:`distutils` package to control the build process, or -do things manually. The distutils approach works well for most extensions; -documentation on using :mod:`distutils` to build and package extension modules -is available in :ref:`distutils-index`. If you find you really need to do +are on Unix: use the ``setuptools`` package to control the build process, or +do things manually. The setuptools approach works well for most extensions; +documentation on using ``setuptools`` to build and package extension modules +is available in :ref:`setuptools-index`. If you find you really need to do things manually, it may be instructive to study the project file for the :source:`winsound <PCbuild/winsound.vcxproj>` standard library module. @@ -132,4 +132,4 @@ modules (including Python) to be able to see your identifiers, you have to say Developer Studio will throw in a lot of import libraries that you do not really need, adding about 100K to your executable. To get rid of them, use the Project Settings dialog, Link tab, to specify *ignore default libraries*. Add the -correct :file:`msvcrtxx.lib` to the list of libraries. +correct :file:`msvcrt{xx}.lib` to the list of libraries. diff --git a/Doc/faq/design.rst b/Doc/faq/design.rst index 9dbfacd7..ae02c443 100644 --- a/Doc/faq/design.rst +++ b/Doc/faq/design.rst @@ -129,7 +129,7 @@ reference or call the method from a particular class. In C++, if you want to use a method from a base class which is overridden in a derived class, you have to use the ``::`` operator -- in Python you can write ``baseclass.methodname(self, <argument list>)``. This is particularly useful -for :meth:`__init__` methods, and in general in cases where a derived class +for :meth:`~object.__init__` methods, and in general in cases where a derived class method wants to extend the base class method of the same name and thus has to call the base class method somehow. @@ -232,7 +232,8 @@ Similar methods exist for bytes and bytearray objects. How fast are exceptions? ------------------------ -A try/except block is extremely efficient if no exceptions are raised. Actually +A :keyword:`try`/:keyword:`except` block is extremely efficient if no exceptions +are raised. Actually catching an exception is expensive. In versions of Python prior to 2.0 it was common to use this idiom:: @@ -352,7 +353,7 @@ will probably run out of file descriptors:: c = f.read(1) Indeed, using CPython's reference counting and destructor scheme, each new -assignment to *f* closes the previous file. With a traditional GC, however, +assignment to ``f`` closes the previous file. With a traditional GC, however, those file objects will only get collected (and closed) at varying and possibly long intervals. @@ -376,10 +377,10 @@ Python to work with it.) Traditional GC also becomes a problem when Python is embedded into other applications. While in a standalone Python it's fine to replace the standard -malloc() and free() with versions provided by the GC library, an application -embedding Python may want to have its *own* substitute for malloc() and free(), +``malloc()`` and ``free()`` with versions provided by the GC library, an application +embedding Python may want to have its *own* substitute for ``malloc()`` and ``free()``, and may not want Python's. Right now, CPython works with anything that -implements malloc() and free() properly. +implements ``malloc()`` and ``free()`` properly. Why isn't all memory freed when CPython exits? @@ -401,14 +402,15 @@ Why are there separate tuple and list data types? Lists and tuples, while similar in many respects, are generally used in fundamentally different ways. Tuples can be thought of as being similar to -Pascal records or C structs; they're small collections of related data which may +Pascal ``records`` or C ``structs``; they're small collections of related data which may be of different types which are operated on as a group. For example, a Cartesian coordinate is appropriately represented as a tuple of two or three numbers. Lists, on the other hand, are more like arrays in other languages. They tend to hold a varying number of objects all of which have the same type and which are -operated on one-by-one. For example, ``os.listdir('.')`` returns a list of +operated on one-by-one. For example, :func:`os.listdir('.') <os.listdir>` +returns a list of strings representing the files in the current directory. Functions which operate on this output would generally not break if you added another file or two to the directory. @@ -444,9 +446,9 @@ far) under most circumstances, and the implementation is simpler. Dictionaries work by computing a hash code for each key stored in the dictionary using the :func:`hash` built-in function. The hash code varies widely depending -on the key and a per-process seed; for example, "Python" could hash to --539294296 while "python", a string that differs by a single bit, could hash -to 1142331976. The hash code is then used to calculate a location in an +on the key and a per-process seed; for example, ``'Python'`` could hash to +``-539294296`` while ``'python'``, a string that differs by a single bit, could hash +to ``1142331976``. The hash code is then used to calculate a location in an internal array where the value will be stored. Assuming that you're storing keys that all have different hash values, this means that dictionaries take constant time -- O(1), in Big-O notation -- to retrieve a key. @@ -497,7 +499,8 @@ Some unacceptable solutions that have been proposed: There is a trick to get around this if you need to, but use it at your own risk: You can wrap a mutable structure inside a class instance which has both a -:meth:`__eq__` and a :meth:`__hash__` method. You must then make sure that the +:meth:`~object.__eq__` and a :meth:`~object.__hash__` method. +You must then make sure that the hash value for all such wrapper objects that reside in a dictionary (or other hash based structure), remain fixed while the object is in the dictionary (or other structure). :: @@ -528,7 +531,7 @@ is True``) then ``hash(o1) == hash(o2)`` (ie, ``o1.__hash__() == o2.__hash__()`` regardless of whether the object is in a dictionary or not. If you fail to meet these restrictions dictionaries and other hash based structures will misbehave. -In the case of ListWrapper, whenever the wrapper object is in a dictionary the +In the case of :class:`!ListWrapper`, whenever the wrapper object is in a dictionary the wrapped list must not change to avoid anomalies. Don't do this unless you are prepared to think hard about the requirements and the consequences of not meeting them correctly. Consider yourself warned. @@ -581,9 +584,9 @@ exhaustive test suites that exercise every line of code in a module. An appropriate testing discipline can help build large complex applications in Python as well as having interface specifications would. In fact, it can be better because an interface specification cannot test certain properties of a -program. For example, the :meth:`append` method is expected to add new elements +program. For example, the :meth:`!list.append` method is expected to add new elements to the end of some internal list; an interface specification cannot test that -your :meth:`append` implementation will actually do this correctly, but it's +your :meth:`!list.append` implementation will actually do this correctly, but it's trivial to check this property in a test suite. Writing test suites is very helpful, and you might want to design your code to @@ -599,14 +602,14 @@ Why is there no goto? In the 1970s people realized that unrestricted goto could lead to messy "spaghetti" code that was hard to understand and revise. In a high-level language, it is also unneeded as long as there -are ways to branch (in Python, with ``if`` statements and ``or``, -``and``, and ``if-else`` expressions) and loop (with ``while`` -and ``for`` statements, possibly containing ``continue`` and ``break``). +are ways to branch (in Python, with :keyword:`if` statements and :keyword:`or`, +:keyword:`and`, and :keyword:`if`/:keyword:`else` expressions) and loop (with :keyword:`while` +and :keyword:`for` statements, possibly containing :keyword:`continue` and :keyword:`break`). One can also use exceptions to provide a "structured goto" that works even across function calls. Many feel that exceptions can conveniently emulate all -reasonable uses of the "go" or "goto" constructs of C, Fortran, and other +reasonable uses of the ``go`` or ``goto`` constructs of C, Fortran, and other languages. For example:: class label(Exception): pass # declare a label @@ -620,7 +623,7 @@ languages. For example:: ... This doesn't allow you to jump into the middle of a loop, but that's usually -considered an abuse of goto anyway. Use sparingly. +considered an abuse of ``goto`` anyway. Use sparingly. Why can't raw strings (r-strings) end with a backslash? @@ -652,7 +655,7 @@ If you're trying to build a pathname for a DOS command, try e.g. one of :: Why doesn't Python have a "with" statement for attribute assignments? --------------------------------------------------------------------- -Python has a 'with' statement that wraps the execution of a block, calling code +Python has a :keyword:`with` statement that wraps the execution of a block, calling code on the entrance and exit from the block. Some languages have a construct that looks like this:: @@ -679,13 +682,13 @@ For instance, take the following incomplete snippet:: with a: print(x) -The snippet assumes that "a" must have a member attribute called "x". However, +The snippet assumes that ``a`` must have a member attribute called ``x``. However, there is nothing in Python that tells the interpreter this. What should happen -if "a" is, let us say, an integer? If there is a global variable named "x", -will it be used inside the with block? As you see, the dynamic nature of Python +if ``a`` is, let us say, an integer? If there is a global variable named ``x``, +will it be used inside the :keyword:`with` block? As you see, the dynamic nature of Python makes such choices much harder. -The primary benefit of "with" and similar language features (reduction of code +The primary benefit of :keyword:`with` and similar language features (reduction of code volume) can, however, easily be achieved in Python by assignment. Instead of:: function(args).mydict[index][index].a = 21 @@ -703,6 +706,10 @@ This also has the side-effect of increasing execution speed because name bindings are resolved at run-time in Python, and the second version only needs to perform the resolution once. +Similar proposals that would introduce syntax to further reduce code volume, +such as using a 'leading dot', have been rejected in favour of explicitness (see +https://mail.python.org/pipermail/python-ideas/2016-May/040070.html). + Why don't generators support the with statement? ------------------------------------------------ @@ -710,7 +717,8 @@ Why don't generators support the with statement? For technical reasons, a generator used directly as a context manager would not work correctly. When, as is most common, a generator is used as an iterator run to completion, no closing is needed. When it is, wrap -it as "contextlib.closing(generator)" in the 'with' statement. +it as :func:`contextlib.closing(generator) <contextlib.closing>` +in the :keyword:`with` statement. Why are colons required for the if/while/def/class statements? diff --git a/Doc/faq/extending.rst b/Doc/faq/extending.rst index 07282639..2a8b9769 100644 --- a/Doc/faq/extending.rst +++ b/Doc/faq/extending.rst @@ -42,7 +42,7 @@ on what you're trying to do. .. XXX make sure these all work `Cython <https://cython.org>`_ and its relative `Pyrex -<https://www.cosc.canterbury.ac.nz/greg.ewing/python/Pyrex/>`_ are compilers +<https://www.csse.canterbury.ac.nz/greg.ewing/python/Pyrex/>`_ are compilers that accept a slightly modified form of Python and generate the corresponding C code. Cython and Pyrex make it possible to write an extension without having to learn Python's C API. @@ -81,13 +81,13 @@ How do I extract C values from a Python object? That depends on the object's type. If it's a tuple, :c:func:`PyTuple_Size` returns its length and :c:func:`PyTuple_GetItem` returns the item at a specified -index. Lists have similar functions, :c:func:`PyListSize` and +index. Lists have similar functions, :c:func:`PyList_Size` and :c:func:`PyList_GetItem`. For bytes, :c:func:`PyBytes_Size` returns its length and :c:func:`PyBytes_AsStringAndSize` provides a pointer to its value and its length. Note that Python bytes objects may contain null bytes so C's -:c:func:`strlen` should not be used. +:c:func:`!strlen` should not be used. To test the type of an object, first make sure it isn't ``NULL``, and then use :c:func:`PyBytes_Check`, :c:func:`PyTuple_Check`, :c:func:`PyList_Check`, etc. diff --git a/Doc/faq/general.rst b/Doc/faq/general.rst index 6256deb5..87273325 100644 --- a/Doc/faq/general.rst +++ b/Doc/faq/general.rst @@ -54,8 +54,8 @@ commercial use, to sell copies of Python in source or binary form (modified or unmodified), or to sell products that incorporate Python in some form. We would still like to know about all commercial use of Python, of course. -See `the PSF license page <https://www.python.org/psf/license/>`_ to find further -explanations and a link to the full text of the license. +See `the license page <https://docs.python.org/3/license.html>`_ to find further +explanations and the full text of the PSF License. The Python logo is trademarked, and in certain cases permission is required to use it. Consult `the Trademark Usage Policy @@ -135,7 +135,7 @@ Python versions are numbered "A.B.C" or "A.B": See :pep:`6` for more information about bugfix releases. -Not all releases are bugfix releases. In the run-up to a new major release, a +Not all releases are bugfix releases. In the run-up to a new feature release, a series of development releases are made, denoted as alpha, beta, or release candidate. Alphas are early releases in which interfaces aren't yet finalized; it's not unexpected to see an interface change between two alpha releases. @@ -215,7 +215,7 @@ every day, and Usenet readers are often more able to cope with this volume. Announcements of new software releases and events can be found in comp.lang.python.announce, a low-traffic moderated list that receives about five postings per day. It's available as `the python-announce mailing list -<https://mail.python.org/mailman/listinfo/python-announce-list>`_. +<https://mail.python.org/mailman3/lists/python-announce-list.python.org/>`_. More info about other mailing lists and newsgroups can be found at https://www.python.org/community/lists/. @@ -297,9 +297,9 @@ How stable is Python? Very stable. New, stable releases have been coming out roughly every 6 to 18 months since 1991, and this seems likely to continue. As of version 3.9, -Python will have a major new release every 12 months (:pep:`602`). +Python will have a new feature release every 12 months (:pep:`602`). -The developers issue "bugfix" releases of older versions, so the stability of +The developers issue bugfix releases of older versions, so the stability of existing releases gradually improves. Bugfix releases, indicated by a third component of the version number (e.g. 3.5.3, 3.6.2), are managed for stability; only fixes for known problems are included in a bugfix release, and it's @@ -352,7 +352,7 @@ titled "Python X.Y Release Schedule", where X.Y is a version that hasn't been publicly released yet. New development is discussed on `the python-dev mailing list -<https://mail.python.org/mailman/listinfo/python-dev/>`_. +<https://mail.python.org/mailman3/lists/python-dev.python.org/>`_. Is it reasonable to propose incompatible changes to Python? diff --git a/Doc/faq/gui.rst b/Doc/faq/gui.rst index 023ffdf0..886833ce 100644 --- a/Doc/faq/gui.rst +++ b/Doc/faq/gui.rst @@ -43,7 +43,7 @@ applications, the applications will not be truly stand-alone, as the application will still need the Tcl and Tk libraries. One solution is to ship the application with the Tcl and Tk libraries, and point -to them at run-time using the :envvar:`TCL_LIBRARY` and :envvar:`TK_LIBRARY` +to them at run-time using the :envvar:`!TCL_LIBRARY` and :envvar:`!TK_LIBRARY` environment variables. To get truly stand-alone applications, the Tcl scripts that form the library @@ -52,7 +52,7 @@ SAM (stand-alone modules), which is part of the Tix distribution (https://tix.sourceforge.net/). Build Tix with SAM enabled, perform the appropriate call to -:c:func:`Tclsam_init`, etc. inside Python's +:c:func:`!Tclsam_init`, etc. inside Python's :file:`Modules/tkappinit.c`, and link with libtclsam and libtksam (you might include the Tix libraries as well). @@ -62,7 +62,7 @@ Can I have Tk events handled while waiting for I/O? On platforms other than Windows, yes, and you don't even need threads! But you'll have to restructure your I/O -code a bit. Tk has the equivalent of Xt's :c:func:`XtAddInput()` call, which allows you +code a bit. Tk has the equivalent of Xt's :c:func:`!XtAddInput` call, which allows you to register a callback function which will be called from the Tk mainloop when I/O is possible on a file descriptor. See :ref:`tkinter-file-handlers`. @@ -70,8 +70,9 @@ I/O is possible on a file descriptor. See :ref:`tkinter-file-handlers`. I can't get key bindings to work in Tkinter: why? ------------------------------------------------- -An often-heard complaint is that event handlers bound to events with the -:meth:`bind` method don't get handled even when the appropriate key is pressed. +An often-heard complaint is that event handlers :ref:`bound <bindings-and-events>` +to events with the :meth:`!bind` method +don't get handled even when the appropriate key is pressed. The most common cause is that the widget to which the binding applies doesn't have "keyboard focus". Check out the Tk documentation for the focus command. diff --git a/Doc/faq/library.rst b/Doc/faq/library.rst index a9cde456..c6991071 100644 --- a/Doc/faq/library.rst +++ b/Doc/faq/library.rst @@ -111,7 +111,7 @@ Is there an equivalent to C's onexit() in Python? ------------------------------------------------- The :mod:`atexit` module provides a register function that is similar to C's -:c:func:`onexit`. +:c:func:`!onexit`. Why don't my signal handlers work? @@ -397,7 +397,7 @@ These aren't:: D[x] = D[x] + 1 Operations that replace other objects may invoke those other objects' -:meth:`__del__` method when their reference count reaches zero, and that can +:meth:`~object.__del__` method when their reference count reaches zero, and that can affect things. This is especially true for the mass updates to dictionaries and lists. When in doubt, use a mutex! @@ -566,7 +566,7 @@ use ``p.read(n)``. Note on a bug in popen2: unless your program calls ``wait()`` or ``waitpid()``, finished child processes are never removed, and eventually calls to popen2 will fail because of a limit on the number of child - processes. Calling :func:`os.waitpid` with the :data:`os.WNOHANG` option can + processes. Calling :func:`os.waitpid` with the :const:`os.WNOHANG` option can prevent this; a good place to insert such a call would be before calling ``popen2`` again. @@ -765,14 +765,17 @@ The :mod:`select` module is commonly used to help with asynchronous I/O on sockets. To prevent the TCP connect from blocking, you can set the socket to non-blocking -mode. Then when you do the :meth:`socket.connect`, you will either connect immediately +mode. Then when you do the :meth:`~socket.socket.connect`, +you will either connect immediately (unlikely) or get an exception that contains the error number as ``.errno``. ``errno.EINPROGRESS`` indicates that the connection is in progress, but hasn't finished yet. Different OSes will return different values, so you're going to have to check what's returned on your system. -You can use the :meth:`socket.connect_ex` method to avoid creating an exception. It will -just return the errno value. To poll, you can call :meth:`socket.connect_ex` again later +You can use the :meth:`~socket.socket.connect_ex` method +to avoid creating an exception. +It will just return the errno value. +To poll, you can call :meth:`~socket.socket.connect_ex` again later -- ``0`` or ``errno.EISCONN`` indicate that you're connected -- or you can pass this socket to :meth:`select.select` to check if it's writable. @@ -780,7 +783,7 @@ socket to :meth:`select.select` to check if it's writable. The :mod:`asyncio` module provides a general purpose single-threaded and concurrent asynchronous library, which can be used for writing non-blocking network code. - The third-party `Twisted <https://twistedmatrix.com/trac/>`_ library is + The third-party `Twisted <https://twisted.org/>`_ library is a popular and feature-rich alternative. diff --git a/Doc/faq/programming.rst b/Doc/faq/programming.rst index ba42289f..f43f69b8 100644 --- a/Doc/faq/programming.rst +++ b/Doc/faq/programming.rst @@ -61,7 +61,7 @@ Yes. `Pyflakes <https://github.com/PyCQA/pyflakes>`_ do basic checking that will help you catch bugs sooner. -Static type checkers such as `Mypy <http://mypy-lang.org/>`_, +Static type checkers such as `Mypy <https://mypy-lang.org/>`_, `Pyre <https://pyre-check.org/>`_, and `Pytype <https://github.com/google/pytype>`_ can check type hints in Python source code. @@ -454,7 +454,7 @@ There are two factors that produce this result: (the list), and both ``x`` and ``y`` refer to it. 2) Lists are :term:`mutable`, which means that you can change their content. -After the call to :meth:`~list.append`, the content of the mutable object has +After the call to :meth:`!append`, the content of the mutable object has changed from ``[]`` to ``[10]``. Since both the variables refer to the same object, using either name accesses the modified value ``[10]``. @@ -1397,7 +1397,7 @@ To see why this happens, you need to know that (a) if an object implements an :meth:`~object.__iadd__` magic method, it gets called when the ``+=`` augmented assignment is executed, and its return value is what gets used in the assignment statement; -and (b) for lists, :meth:`!__iadd__` is equivalent to calling :meth:`~list.extend` on the list +and (b) for lists, :meth:`!__iadd__` is equivalent to calling :meth:`!extend` on the list and returning the list. That's why we say that for lists, ``+=`` is a "shorthand" for :meth:`!list.extend`:: @@ -1903,7 +1903,7 @@ identity tests. This prevents the code from being confused by objects such as ``float('NaN')`` that are not equal to themselves. For example, here is the implementation of -:meth:`collections.abc.Sequence.__contains__`:: +:meth:`!collections.abc.Sequence.__contains__`:: def __contains__(self, value): for v in self: @@ -1979,7 +1979,7 @@ method result will be released right away. The disadvantage is that if instances accumulate, so too will the accumulated method results. They can grow without bound. -The *lru_cache* approach works with methods that have hashable +The *lru_cache* approach works with methods that have :term:`hashable` arguments. It creates a reference to the instance unless special efforts are made to pass in weak references. diff --git a/Doc/glossary.rst b/Doc/glossary.rst index 3d74d550..f3d5c5ee 100644 --- a/Doc/glossary.rst +++ b/Doc/glossary.rst @@ -92,8 +92,8 @@ Glossary asynchronous context manager An object which controls the environment seen in an - :keyword:`async with` statement by defining :meth:`__aenter__` and - :meth:`__aexit__` methods. Introduced by :pep:`492`. + :keyword:`async with` statement by defining :meth:`~object.__aenter__` and + :meth:`~object.__aexit__` methods. Introduced by :pep:`492`. asynchronous generator A function which returns an :term:`asynchronous generator iterator`. It @@ -113,26 +113,26 @@ Glossary An object created by a :term:`asynchronous generator` function. This is an :term:`asynchronous iterator` which when called using the - :meth:`__anext__` method returns an awaitable object which will execute + :meth:`~object.__anext__` method returns an awaitable object which will execute the body of the asynchronous generator function until the next :keyword:`yield` expression. Each :keyword:`yield` temporarily suspends processing, remembering the location execution state (including local variables and pending try-statements). When the *asynchronous generator iterator* effectively - resumes with another awaitable returned by :meth:`__anext__`, it + resumes with another awaitable returned by :meth:`~object.__anext__`, it picks up where it left off. See :pep:`492` and :pep:`525`. asynchronous iterable An object, that can be used in an :keyword:`async for` statement. Must return an :term:`asynchronous iterator` from its - :meth:`__aiter__` method. Introduced by :pep:`492`. + :meth:`~object.__aiter__` method. Introduced by :pep:`492`. asynchronous iterator - An object that implements the :meth:`__aiter__` and :meth:`__anext__` - methods. ``__anext__`` must return an :term:`awaitable` object. + An object that implements the :meth:`~object.__aiter__` and :meth:`~object.__anext__` + methods. :meth:`~object.__anext__` must return an :term:`awaitable` object. :keyword:`async for` resolves the awaitables returned by an asynchronous - iterator's :meth:`__anext__` method until it raises a + iterator's :meth:`~object.__anext__` method until it raises a :exc:`StopAsyncIteration` exception. Introduced by :pep:`492`. attribute @@ -149,7 +149,7 @@ Glossary awaitable An object that can be used in an :keyword:`await` expression. Can be - a :term:`coroutine` or an object with an :meth:`__await__` method. + a :term:`coroutine` or an object with an :meth:`~object.__await__` method. See also :pep:`492`. BDFL @@ -168,8 +168,9 @@ Glossary :class:`str` objects. borrowed reference - In Python's C API, a borrowed reference is a reference to an object. - It does not modify the object reference count. It becomes a dangling + In Python's C API, a borrowed reference is a reference to an object, + where the code using the object does not own the reference. + It becomes a dangling pointer if the object is destroyed. For example, a garbage collection can remove the last :term:`strong reference` to the object and so destroy it. @@ -214,7 +215,7 @@ Glossary A callable is an object that can be called, possibly with a set of arguments (see :term:`argument`), with the following syntax:: - callable(argument1, argument2, ...) + callable(argument1, argument2, argumentN) A :term:`function`, and by extension a :term:`method`, is a callable. An instance of a class that implements the :meth:`~object.__call__` @@ -1063,7 +1064,9 @@ Glossary reference count The number of references to an object. When the reference count of an - object drops to zero, it is deallocated. Reference counting is + object drops to zero, it is deallocated. Some objects are + "immortal" and have reference counts that are never modified, and + therefore the objects are never deallocated. Reference counting is generally not visible to Python code, but it is a key element of the :term:`CPython` implementation. Programmers can call the :func:`sys.getrefcount` function to return the @@ -1131,8 +1134,10 @@ Glossary strong reference In Python's C API, a strong reference is a reference to an object - which increments the object's reference count when it is created and - decrements the object's reference count when it is deleted. + which is owned by the code holding the reference. The strong + reference is taken by calling :c:func:`Py_INCREF` when the + reference is created and released with :c:func:`Py_DECREF` + when the reference is deleted. The :c:func:`Py_NewRef` function can be used to create a strong reference to an object. Usually, the :c:func:`Py_DECREF` function must be called on diff --git a/Doc/howto/annotations.rst b/Doc/howto/annotations.rst index 47206903..1134686c 100644 --- a/Doc/howto/annotations.rst +++ b/Doc/howto/annotations.rst @@ -32,201 +32,201 @@ Annotations Best Practices Accessing The Annotations Dict Of An Object In Python 3.10 And Newer ==================================================================== - Python 3.10 adds a new function to the standard library: - :func:`inspect.get_annotations`. In Python versions 3.10 - and newer, calling this function is the best practice for - accessing the annotations dict of any object that supports - annotations. This function can also "un-stringize" - stringized annotations for you. - - If for some reason :func:`inspect.get_annotations` isn't - viable for your use case, you may access the - ``__annotations__`` data member manually. Best practice - for this changed in Python 3.10 as well: as of Python 3.10, - ``o.__annotations__`` is guaranteed to *always* work - on Python functions, classes, and modules. If you're - certain the object you're examining is one of these three - *specific* objects, you may simply use ``o.__annotations__`` - to get at the object's annotations dict. - - However, other types of callables--for example, - callables created by :func:`functools.partial`--may - not have an ``__annotations__`` attribute defined. When - accessing the ``__annotations__`` of a possibly unknown - object, best practice in Python versions 3.10 and - newer is to call :func:`getattr` with three arguments, - for example ``getattr(o, '__annotations__', None)``. - - Before Python 3.10, accessing ``__annotations__`` on a class that - defines no annotations but that has a parent class with - annotations would return the parent's ``__annotations__``. - In Python 3.10 and newer, the child class's annotations - will be an empty dict instead. +Python 3.10 adds a new function to the standard library: +:func:`inspect.get_annotations`. In Python versions 3.10 +and newer, calling this function is the best practice for +accessing the annotations dict of any object that supports +annotations. This function can also "un-stringize" +stringized annotations for you. + +If for some reason :func:`inspect.get_annotations` isn't +viable for your use case, you may access the +``__annotations__`` data member manually. Best practice +for this changed in Python 3.10 as well: as of Python 3.10, +``o.__annotations__`` is guaranteed to *always* work +on Python functions, classes, and modules. If you're +certain the object you're examining is one of these three +*specific* objects, you may simply use ``o.__annotations__`` +to get at the object's annotations dict. + +However, other types of callables--for example, +callables created by :func:`functools.partial`--may +not have an ``__annotations__`` attribute defined. When +accessing the ``__annotations__`` of a possibly unknown +object, best practice in Python versions 3.10 and +newer is to call :func:`getattr` with three arguments, +for example ``getattr(o, '__annotations__', None)``. + +Before Python 3.10, accessing ``__annotations__`` on a class that +defines no annotations but that has a parent class with +annotations would return the parent's ``__annotations__``. +In Python 3.10 and newer, the child class's annotations +will be an empty dict instead. Accessing The Annotations Dict Of An Object In Python 3.9 And Older =================================================================== - In Python 3.9 and older, accessing the annotations dict - of an object is much more complicated than in newer versions. - The problem is a design flaw in these older versions of Python, - specifically to do with class annotations. +In Python 3.9 and older, accessing the annotations dict +of an object is much more complicated than in newer versions. +The problem is a design flaw in these older versions of Python, +specifically to do with class annotations. - Best practice for accessing the annotations dict of other - objects--functions, other callables, and modules--is the same - as best practice for 3.10, assuming you aren't calling - :func:`inspect.get_annotations`: you should use three-argument - :func:`getattr` to access the object's ``__annotations__`` - attribute. +Best practice for accessing the annotations dict of other +objects--functions, other callables, and modules--is the same +as best practice for 3.10, assuming you aren't calling +:func:`inspect.get_annotations`: you should use three-argument +:func:`getattr` to access the object's ``__annotations__`` +attribute. - Unfortunately, this isn't best practice for classes. The problem - is that, since ``__annotations__`` is optional on classes, and - because classes can inherit attributes from their base classes, - accessing the ``__annotations__`` attribute of a class may - inadvertently return the annotations dict of a *base class.* - As an example:: +Unfortunately, this isn't best practice for classes. The problem +is that, since ``__annotations__`` is optional on classes, and +because classes can inherit attributes from their base classes, +accessing the ``__annotations__`` attribute of a class may +inadvertently return the annotations dict of a *base class.* +As an example:: - class Base: - a: int = 3 - b: str = 'abc' + class Base: + a: int = 3 + b: str = 'abc' - class Derived(Base): - pass + class Derived(Base): + pass - print(Derived.__annotations__) + print(Derived.__annotations__) - This will print the annotations dict from ``Base``, not - ``Derived``. +This will print the annotations dict from ``Base``, not +``Derived``. - Your code will have to have a separate code path if the object - you're examining is a class (``isinstance(o, type)``). - In that case, best practice relies on an implementation detail - of Python 3.9 and before: if a class has annotations defined, - they are stored in the class's ``__dict__`` dictionary. Since - the class may or may not have annotations defined, best practice - is to call the ``get`` method on the class dict. +Your code will have to have a separate code path if the object +you're examining is a class (``isinstance(o, type)``). +In that case, best practice relies on an implementation detail +of Python 3.9 and before: if a class has annotations defined, +they are stored in the class's ``__dict__`` dictionary. Since +the class may or may not have annotations defined, best practice +is to call the ``get`` method on the class dict. - To put it all together, here is some sample code that safely - accesses the ``__annotations__`` attribute on an arbitrary - object in Python 3.9 and before:: +To put it all together, here is some sample code that safely +accesses the ``__annotations__`` attribute on an arbitrary +object in Python 3.9 and before:: - if isinstance(o, type): - ann = o.__dict__.get('__annotations__', None) - else: - ann = getattr(o, '__annotations__', None) + if isinstance(o, type): + ann = o.__dict__.get('__annotations__', None) + else: + ann = getattr(o, '__annotations__', None) - After running this code, ``ann`` should be either a - dictionary or ``None``. You're encouraged to double-check - the type of ``ann`` using :func:`isinstance` before further - examination. +After running this code, ``ann`` should be either a +dictionary or ``None``. You're encouraged to double-check +the type of ``ann`` using :func:`isinstance` before further +examination. - Note that some exotic or malformed type objects may not have - a ``__dict__`` attribute, so for extra safety you may also wish - to use :func:`getattr` to access ``__dict__``. +Note that some exotic or malformed type objects may not have +a ``__dict__`` attribute, so for extra safety you may also wish +to use :func:`getattr` to access ``__dict__``. Manually Un-Stringizing Stringized Annotations ============================================== - In situations where some annotations may be "stringized", - and you wish to evaluate those strings to produce the - Python values they represent, it really is best to - call :func:`inspect.get_annotations` to do this work - for you. - - If you're using Python 3.9 or older, or if for some reason - you can't use :func:`inspect.get_annotations`, you'll need - to duplicate its logic. You're encouraged to examine the - implementation of :func:`inspect.get_annotations` in the - current Python version and follow a similar approach. - - In a nutshell, if you wish to evaluate a stringized annotation - on an arbitrary object ``o``: - - * If ``o`` is a module, use ``o.__dict__`` as the - ``globals`` when calling :func:`eval`. - * If ``o`` is a class, use ``sys.modules[o.__module__].__dict__`` - as the ``globals``, and ``dict(vars(o))`` as the ``locals``, - when calling :func:`eval`. - * If ``o`` is a wrapped callable using :func:`functools.update_wrapper`, - :func:`functools.wraps`, or :func:`functools.partial`, iteratively - unwrap it by accessing either ``o.__wrapped__`` or ``o.func`` as - appropriate, until you have found the root unwrapped function. - * If ``o`` is a callable (but not a class), use - ``o.__globals__`` as the globals when calling :func:`eval`. - - However, not all string values used as annotations can - be successfully turned into Python values by :func:`eval`. - String values could theoretically contain any valid string, - and in practice there are valid use cases for type hints that - require annotating with string values that specifically - *can't* be evaluated. For example: - - * :pep:`604` union types using ``|``, before support for this - was added to Python 3.10. - * Definitions that aren't needed at runtime, only imported - when :const:`typing.TYPE_CHECKING` is true. - - If :func:`eval` attempts to evaluate such values, it will - fail and raise an exception. So, when designing a library - API that works with annotations, it's recommended to only - attempt to evaluate string values when explicitly requested - to by the caller. +In situations where some annotations may be "stringized", +and you wish to evaluate those strings to produce the +Python values they represent, it really is best to +call :func:`inspect.get_annotations` to do this work +for you. + +If you're using Python 3.9 or older, or if for some reason +you can't use :func:`inspect.get_annotations`, you'll need +to duplicate its logic. You're encouraged to examine the +implementation of :func:`inspect.get_annotations` in the +current Python version and follow a similar approach. + +In a nutshell, if you wish to evaluate a stringized annotation +on an arbitrary object ``o``: + +* If ``o`` is a module, use ``o.__dict__`` as the + ``globals`` when calling :func:`eval`. +* If ``o`` is a class, use ``sys.modules[o.__module__].__dict__`` + as the ``globals``, and ``dict(vars(o))`` as the ``locals``, + when calling :func:`eval`. +* If ``o`` is a wrapped callable using :func:`functools.update_wrapper`, + :func:`functools.wraps`, or :func:`functools.partial`, iteratively + unwrap it by accessing either ``o.__wrapped__`` or ``o.func`` as + appropriate, until you have found the root unwrapped function. +* If ``o`` is a callable (but not a class), use + ``o.__globals__`` as the globals when calling :func:`eval`. + +However, not all string values used as annotations can +be successfully turned into Python values by :func:`eval`. +String values could theoretically contain any valid string, +and in practice there are valid use cases for type hints that +require annotating with string values that specifically +*can't* be evaluated. For example: + +* :pep:`604` union types using ``|``, before support for this + was added to Python 3.10. +* Definitions that aren't needed at runtime, only imported + when :const:`typing.TYPE_CHECKING` is true. + +If :func:`eval` attempts to evaluate such values, it will +fail and raise an exception. So, when designing a library +API that works with annotations, it's recommended to only +attempt to evaluate string values when explicitly requested +to by the caller. Best Practices For ``__annotations__`` In Any Python Version ============================================================ - * You should avoid assigning to the ``__annotations__`` member - of objects directly. Let Python manage setting ``__annotations__``. +* You should avoid assigning to the ``__annotations__`` member + of objects directly. Let Python manage setting ``__annotations__``. - * If you do assign directly to the ``__annotations__`` member - of an object, you should always set it to a ``dict`` object. +* If you do assign directly to the ``__annotations__`` member + of an object, you should always set it to a ``dict`` object. - * If you directly access the ``__annotations__`` member - of an object, you should ensure that it's a - dictionary before attempting to examine its contents. +* If you directly access the ``__annotations__`` member + of an object, you should ensure that it's a + dictionary before attempting to examine its contents. - * You should avoid modifying ``__annotations__`` dicts. +* You should avoid modifying ``__annotations__`` dicts. - * You should avoid deleting the ``__annotations__`` attribute - of an object. +* You should avoid deleting the ``__annotations__`` attribute + of an object. ``__annotations__`` Quirks ========================== - In all versions of Python 3, function - objects lazy-create an annotations dict if no annotations - are defined on that object. You can delete the ``__annotations__`` - attribute using ``del fn.__annotations__``, but if you then - access ``fn.__annotations__`` the object will create a new empty dict - that it will store and return as its annotations. Deleting the - annotations on a function before it has lazily created its annotations - dict will throw an ``AttributeError``; using ``del fn.__annotations__`` - twice in a row is guaranteed to always throw an ``AttributeError``. - - Everything in the above paragraph also applies to class and module - objects in Python 3.10 and newer. - - In all versions of Python 3, you can set ``__annotations__`` - on a function object to ``None``. However, subsequently - accessing the annotations on that object using ``fn.__annotations__`` - will lazy-create an empty dictionary as per the first paragraph of - this section. This is *not* true of modules and classes, in any Python - version; those objects permit setting ``__annotations__`` to any - Python value, and will retain whatever value is set. - - If Python stringizes your annotations for you - (using ``from __future__ import annotations``), and you - specify a string as an annotation, the string will - itself be quoted. In effect the annotation is quoted - *twice.* For example:: - - from __future__ import annotations - def foo(a: "str"): pass - - print(foo.__annotations__) - - This prints ``{'a': "'str'"}``. This shouldn't really be considered - a "quirk"; it's mentioned here simply because it might be surprising. +In all versions of Python 3, function +objects lazy-create an annotations dict if no annotations +are defined on that object. You can delete the ``__annotations__`` +attribute using ``del fn.__annotations__``, but if you then +access ``fn.__annotations__`` the object will create a new empty dict +that it will store and return as its annotations. Deleting the +annotations on a function before it has lazily created its annotations +dict will throw an ``AttributeError``; using ``del fn.__annotations__`` +twice in a row is guaranteed to always throw an ``AttributeError``. + +Everything in the above paragraph also applies to class and module +objects in Python 3.10 and newer. + +In all versions of Python 3, you can set ``__annotations__`` +on a function object to ``None``. However, subsequently +accessing the annotations on that object using ``fn.__annotations__`` +will lazy-create an empty dictionary as per the first paragraph of +this section. This is *not* true of modules and classes, in any Python +version; those objects permit setting ``__annotations__`` to any +Python value, and will retain whatever value is set. + +If Python stringizes your annotations for you +(using ``from __future__ import annotations``), and you +specify a string as an annotation, the string will +itself be quoted. In effect the annotation is quoted +*twice.* For example:: + + from __future__ import annotations + def foo(a: "str"): pass + + print(foo.__annotations__) + +This prints ``{'a': "'str'"}``. This shouldn't really be considered +a "quirk"; it's mentioned here simply because it might be surprising. diff --git a/Doc/howto/argparse.rst b/Doc/howto/argparse.rst index adc2f373..ae5bab90 100644 --- a/Doc/howto/argparse.rst +++ b/Doc/howto/argparse.rst @@ -1,10 +1,12 @@ +.. _argparse-tutorial: + ***************** Argparse Tutorial ***************** -:author: Tshepang Lekhonkhobe +:author: Tshepang Mbambo -.. _argparse-tutorial: +.. currentmodule:: argparse This tutorial is intended to be a gentle introduction to :mod:`argparse`, the recommended command-line parsing module in the Python standard library. @@ -12,7 +14,7 @@ recommended command-line parsing module in the Python standard library. .. note:: There are two other modules that fulfill the same task, namely - :mod:`getopt` (an equivalent for :c:func:`getopt` from the C + :mod:`getopt` (an equivalent for ``getopt()`` from the C language) and the deprecated :mod:`optparse`. Note also that :mod:`argparse` is based on :mod:`optparse`, and therefore very similar in terms of usage. @@ -79,16 +81,16 @@ Following is a result of running the code: .. code-block:: shell-session - $ python3 prog.py - $ python3 prog.py --help + $ python prog.py + $ python prog.py --help usage: prog.py [-h] options: -h, --help show this help message and exit - $ python3 prog.py --verbose + $ python prog.py --verbose usage: prog.py [-h] prog.py: error: unrecognized arguments: --verbose - $ python3 prog.py foo + $ python prog.py foo usage: prog.py [-h] prog.py: error: unrecognized arguments: foo @@ -121,10 +123,10 @@ And running the code: .. code-block:: shell-session - $ python3 prog.py + $ python prog.py usage: prog.py [-h] echo prog.py: error: the following arguments are required: echo - $ python3 prog.py --help + $ python prog.py --help usage: prog.py [-h] echo positional arguments: @@ -132,18 +134,18 @@ And running the code: options: -h, --help show this help message and exit - $ python3 prog.py foo + $ python prog.py foo foo Here is what's happening: -* We've added the :meth:`add_argument` method, which is what we use to specify +* We've added the :meth:`~ArgumentParser.add_argument` method, which is what we use to specify which command-line options the program is willing to accept. In this case, I've named it ``echo`` so that it's in line with its function. * Calling our program now requires us to specify an option. -* The :meth:`parse_args` method actually returns some data from the +* The :meth:`~ArgumentParser.parse_args` method actually returns some data from the options specified, in this case, ``echo``. * The variable is some form of 'magic' that :mod:`argparse` performs for free @@ -166,7 +168,7 @@ And we get: .. code-block:: shell-session - $ python3 prog.py -h + $ python prog.py -h usage: prog.py [-h] echo positional arguments: @@ -187,7 +189,7 @@ Following is a result of running the code: .. code-block:: shell-session - $ python3 prog.py 4 + $ python prog.py 4 Traceback (most recent call last): File "prog.py", line 5, in <module> print(args.square**2) @@ -208,9 +210,9 @@ Following is a result of running the code: .. code-block:: shell-session - $ python3 prog.py 4 + $ python prog.py 4 16 - $ python3 prog.py four + $ python prog.py four usage: prog.py [-h] square prog.py: error: argument square: invalid int value: 'four' @@ -235,17 +237,17 @@ And the output: .. code-block:: shell-session - $ python3 prog.py --verbosity 1 + $ python prog.py --verbosity 1 verbosity turned on - $ python3 prog.py - $ python3 prog.py --help + $ python prog.py + $ python prog.py --help usage: prog.py [-h] [--verbosity VERBOSITY] options: -h, --help show this help message and exit --verbosity VERBOSITY increase output verbosity - $ python3 prog.py --verbosity + $ python prog.py --verbosity usage: prog.py [-h] [--verbosity VERBOSITY] prog.py: error: argument --verbosity: expected one argument @@ -256,7 +258,7 @@ Here is what is happening: * To show that the option is actually optional, there is no error when running the program without it. Note that by default, if an optional argument isn't - used, the relevant variable, in this case :attr:`args.verbosity`, is + used, the relevant variable, in this case ``args.verbosity``, is given ``None`` as a value, which is the reason it fails the truth test of the :keyword:`if` statement. @@ -281,12 +283,12 @@ And the output: .. code-block:: shell-session - $ python3 prog.py --verbose + $ python prog.py --verbose verbosity turned on - $ python3 prog.py --verbose 1 + $ python prog.py --verbose 1 usage: prog.py [-h] [--verbose] prog.py: error: unrecognized arguments: 1 - $ python3 prog.py --help + $ python prog.py --help usage: prog.py [-h] [--verbose] options: @@ -299,7 +301,7 @@ Here is what is happening: We even changed the name of the option to match that idea. Note that we now specify a new keyword, ``action``, and give it the value ``"store_true"``. This means that, if the option is specified, - assign the value ``True`` to :data:`args.verbose`. + assign the value ``True`` to ``args.verbose``. Not specifying it implies ``False``. * It complains when you specify a value, in true spirit of what flags @@ -327,9 +329,9 @@ And here goes: .. code-block:: shell-session - $ python3 prog.py -v + $ python prog.py -v verbosity turned on - $ python3 prog.py --help + $ python prog.py --help usage: prog.py [-h] [-v] options: @@ -361,14 +363,14 @@ And now the output: .. code-block:: shell-session - $ python3 prog.py + $ python prog.py usage: prog.py [-h] [-v] square prog.py: error: the following arguments are required: square - $ python3 prog.py 4 + $ python prog.py 4 16 - $ python3 prog.py 4 --verbose + $ python prog.py 4 --verbose the square of 4 equals 16 - $ python3 prog.py --verbose 4 + $ python prog.py --verbose 4 the square of 4 equals 16 * We've brought back a positional argument, hence the complaint. @@ -397,16 +399,16 @@ And the output: .. code-block:: shell-session - $ python3 prog.py 4 + $ python prog.py 4 16 - $ python3 prog.py 4 -v + $ python prog.py 4 -v usage: prog.py [-h] [-v VERBOSITY] square prog.py: error: argument -v/--verbosity: expected one argument - $ python3 prog.py 4 -v 1 + $ python prog.py 4 -v 1 4^2 == 16 - $ python3 prog.py 4 -v 2 + $ python prog.py 4 -v 2 the square of 4 equals 16 - $ python3 prog.py 4 -v 3 + $ python prog.py 4 -v 3 16 These all look good except the last one, which exposes a bug in our program. @@ -431,10 +433,10 @@ And the output: .. code-block:: shell-session - $ python3 prog.py 4 -v 3 + $ python prog.py 4 -v 3 usage: prog.py [-h] [-v {0,1,2}] square prog.py: error: argument -v/--verbosity: invalid choice: 3 (choose from 0, 1, 2) - $ python3 prog.py 4 -h + $ python prog.py 4 -h usage: prog.py [-h] [-v {0,1,2}] square positional arguments: @@ -473,18 +475,18 @@ to count the number of occurrences of specific options. .. code-block:: shell-session - $ python3 prog.py 4 + $ python prog.py 4 16 - $ python3 prog.py 4 -v + $ python prog.py 4 -v 4^2 == 16 - $ python3 prog.py 4 -vv + $ python prog.py 4 -vv the square of 4 equals 16 - $ python3 prog.py 4 --verbosity --verbosity + $ python prog.py 4 --verbosity --verbosity the square of 4 equals 16 - $ python3 prog.py 4 -v 1 + $ python prog.py 4 -v 1 usage: prog.py [-h] [-v] square prog.py: error: unrecognized arguments: 1 - $ python3 prog.py 4 -h + $ python prog.py 4 -h usage: prog.py [-h] [-v] square positional arguments: @@ -493,7 +495,7 @@ to count the number of occurrences of specific options. options: -h, --help show this help message and exit -v, --verbosity increase output verbosity - $ python3 prog.py 4 -vvv + $ python prog.py 4 -vvv 16 * Yes, it's now more of a flag (similar to ``action="store_true"``) in the @@ -540,11 +542,11 @@ And this is what it gives: .. code-block:: shell-session - $ python3 prog.py 4 -vvv + $ python prog.py 4 -vvv the square of 4 equals 16 - $ python3 prog.py 4 -vvvv + $ python prog.py 4 -vvvv the square of 4 equals 16 - $ python3 prog.py 4 + $ python prog.py 4 Traceback (most recent call last): File "prog.py", line 11, in <module> if args.verbosity >= 2: @@ -584,7 +586,7 @@ And: .. code-block:: shell-session - $ python3 prog.py 4 + $ python prog.py 4 16 You can go quite far just with what we've learned so far, @@ -617,10 +619,10 @@ Output: .. code-block:: shell-session - $ python3 prog.py + $ python prog.py usage: prog.py [-h] [-v] x y prog.py: error: the following arguments are required: x, y - $ python3 prog.py -h + $ python prog.py -h usage: prog.py [-h] [-v] x y positional arguments: @@ -630,7 +632,7 @@ Output: options: -h, --help show this help message and exit -v, --verbosity - $ python3 prog.py 4 2 -v + $ python prog.py 4 2 -v 4^2 == 16 @@ -655,21 +657,50 @@ Output: .. code-block:: shell-session - $ python3 prog.py 4 2 + $ python prog.py 4 2 16 - $ python3 prog.py 4 2 -v + $ python prog.py 4 2 -v 4^2 == 16 - $ python3 prog.py 4 2 -vv + $ python prog.py 4 2 -vv Running 'prog.py' 4^2 == 16 +.. _specifying-ambiguous-arguments: + +Specifying ambiguous arguments +------------------------------ + +When there is ambiguity in deciding whether an argument is positional or for an +argument, ``--`` can be used to tell :meth:`~ArgumentParser.parse_args` that +everything after that is a positional argument:: + + >>> parser = argparse.ArgumentParser(prog='PROG') + >>> parser.add_argument('-n', nargs='+') + >>> parser.add_argument('args', nargs='*') + + >>> # ambiguous, so parse_args assumes it's an option + >>> parser.parse_args(['-f']) + usage: PROG [-h] [-n N [N ...]] [args ...] + PROG: error: unrecognized arguments: -f + + >>> parser.parse_args(['--', '-f']) + Namespace(args=['-f'], n=None) + + >>> # ambiguous, so the -n option greedily accepts arguments + >>> parser.parse_args(['-n', '1', '2', '3']) + Namespace(args=[], n=['1', '2', '3']) + + >>> parser.parse_args(['-n', '1', '--', '2', '3']) + Namespace(args=['2', '3'], n=['1']) + + Conflicting options ------------------- So far, we have been working with two methods of an :class:`argparse.ArgumentParser` instance. Let's introduce a third one, -:meth:`add_mutually_exclusive_group`. It allows for us to specify options that +:meth:`~ArgumentParser.add_mutually_exclusive_group`. It allows for us to specify options that conflict with each other. Let's also change the rest of the program so that the new functionality makes more sense: we'll introduce the ``--quiet`` option, @@ -698,16 +729,16 @@ demonstration. Anyways, here's the output: .. code-block:: shell-session - $ python3 prog.py 4 2 + $ python prog.py 4 2 4^2 == 16 - $ python3 prog.py 4 2 -q + $ python prog.py 4 2 -q 16 - $ python3 prog.py 4 2 -v + $ python prog.py 4 2 -v 4 to the power 2 equals 16 - $ python3 prog.py 4 2 -vq + $ python prog.py 4 2 -vq usage: prog.py [-h] [-v | -q] x y prog.py: error: argument -q/--quiet: not allowed with argument -v/--verbose - $ python3 prog.py 4 2 -v --quiet + $ python prog.py 4 2 -v --quiet usage: prog.py [-h] [-v | -q] x y prog.py: error: argument -q/--quiet: not allowed with argument -v/--verbose @@ -742,7 +773,7 @@ but not both at the same time: .. code-block:: shell-session - $ python3 prog.py --help + $ python prog.py --help usage: prog.py [-h] [-v | -q] x y calculate X to the power of Y @@ -757,6 +788,59 @@ but not both at the same time: -q, --quiet +How to translate the argparse output +==================================== + +The output of the :mod:`argparse` module such as its help text and error +messages are all made translatable using the :mod:`gettext` module. This +allows applications to easily localize messages produced by +:mod:`argparse`. See also :ref:`i18n-howto`. + +For instance, in this :mod:`argparse` output: + +.. code-block:: shell-session + + $ python prog.py --help + usage: prog.py [-h] [-v | -q] x y + + calculate X to the power of Y + + positional arguments: + x the base + y the exponent + + options: + -h, --help show this help message and exit + -v, --verbose + -q, --quiet + +The strings ``usage:``, ``positional arguments:``, ``options:`` and +``show this help message and exit`` are all translatable. + +In order to translate these strings, they must first be extracted +into a ``.po`` file. For example, using `Babel <https://babel.pocoo.org/>`__, +run this command: + +.. code-block:: shell-session + + $ pybabel extract -o messages.po /usr/lib/python3.12/argparse.py + +This command will extract all translatable strings from the :mod:`argparse` +module and output them into a file named ``messages.po``. This command assumes +that your Python installation is in ``/usr/lib``. + +You can find out the location of the :mod:`argparse` module on your system +using this script:: + + import argparse + print(argparse.__file__) + +Once the messages in the ``.po`` file are translated and the translations are +installed using :mod:`gettext`, :mod:`argparse` will be able to display the +translated messages. + +To translate your own strings in the :mod:`argparse` output, use :mod:`gettext`. + Conclusion ========== diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index 4e9b3dee..e8e6aace 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -8,17 +8,30 @@ Argument Clinic How-To :author: Larry Hastings +**Source code:** :source:`Tools/clinic/clinic.py`. .. topic:: Abstract Argument Clinic is a preprocessor for CPython C files. - Its purpose is to automate all the boilerplate involved - with writing argument parsing code for "builtins". - This document shows you how to convert your first C - function to work with Argument Clinic, and then introduces - some advanced topics on Argument Clinic usage. + It was introduced in Python 3.4 with :pep:`436`, + in order to provide introspection signatures, + and to generate performant and tailor-made boilerplate code + for argument parsing in CPython builtins, + module level functions, and class methods. + This document is divided in four major sections: - Currently Argument Clinic is considered internal-only + * :ref:`clinic-background` talks about the basic concepts and goals of + Argument Clinic. + * :ref:`clinic-reference` describes the command-line interface and Argument + Clinic terminology. + * :ref:`clinic-tutorial` guides you through all the steps required to + adapt an existing C function to Argument Clinic. + * :ref:`clinic-howtos` details how to handle specific tasks. + + +.. note:: + + Argument Clinic is considered internal-only for CPython. Its use is not supported for files outside CPython, and no guarantees are made regarding backwards compatibility for future versions. In other words: if you @@ -27,89 +40,35 @@ Argument Clinic How-To version of Argument Clinic that ships with the next version of CPython *could* be totally incompatible and break all your code. -The Goals Of Argument Clinic -============================ - -Argument Clinic's primary goal -is to take over responsibility for all argument parsing code -inside CPython. This means that, when you convert a function -to work with Argument Clinic, that function should no longer -do any of its own argument parsing—the code generated by -Argument Clinic should be a "black box" to you, where CPython -calls in at the top, and your code gets called at the bottom, -with ``PyObject *args`` (and maybe ``PyObject *kwargs``) -magically converted into the C variables and types you need. - -In order for Argument Clinic to accomplish its primary goal, -it must be easy to use. Currently, working with CPython's -argument parsing library is a chore, requiring maintaining -redundant information in a surprising number of places. -When you use Argument Clinic, you don't have to repeat yourself. - -Obviously, no one would want to use Argument Clinic unless -it's solving their problem—and without creating new problems of -its own. -So it's paramount that Argument Clinic generate correct code. -It'd be nice if the code was faster, too, but at the very least -it should not introduce a major speed regression. (Eventually Argument -Clinic *should* make a major speedup possible—we could -rewrite its code generator to produce tailor-made argument -parsing code, rather than calling the general-purpose CPython -argument parsing library. That would make for the fastest -argument parsing possible!) - -Additionally, Argument Clinic must be flexible enough to -work with any approach to argument parsing. Python has -some functions with some very strange parsing behaviors; -Argument Clinic's goal is to support all of them. - -Finally, the original motivation for Argument Clinic was -to provide introspection "signatures" for CPython builtins. -It used to be, the introspection query functions would throw -an exception if you passed in a builtin. With Argument -Clinic, that's a thing of the past! - -One idea you should keep in mind, as you work with -Argument Clinic: the more information you give it, the -better job it'll be able to do. -Argument Clinic is admittedly relatively simple right -now. But as it evolves it will get more sophisticated, -and it should be able to do many interesting and smart -things with all the information you give it. - - -Basic Concepts And Usage -======================== - -Argument Clinic ships with CPython; you'll find it in ``Tools/clinic/clinic.py``. -If you run that script, specifying a C file as an argument: -.. code-block:: shell-session +.. _clinic-background: - $ python3 Tools/clinic/clinic.py foo.c +Background +========== -Argument Clinic will scan over the file looking for lines that -look exactly like this: +Basic concepts +-------------- + +When Argument Clinic is run on a file, either via the :ref:`clinic-cli` +or via ``make clinic``, it will scan over the input files looking for +:term:`start lines <start line>`: .. code-block:: none /*[clinic input] -When it finds one, it reads everything up to a line that looks -exactly like this: +When it finds one, it reads everything up to the :term:`end line`: .. code-block:: none [clinic start generated code]*/ -Everything in between these two lines is input for Argument Clinic. -All of these lines, including the beginning and ending comment -lines, are collectively called an Argument Clinic "block". - -When Argument Clinic parses one of these blocks, it -generates output. This output is rewritten into the C file -immediately after the block, followed by a comment containing a checksum. -The Argument Clinic block now looks like this: +Everything in between these two lines is Argument Clinic :term:`input`. +When Argument Clinic parses input, it generates :term:`output`. +The output is rewritten into the C file immediately after the input, +followed by a :term:`checksum line`. +All of these lines, including the :term:`start line` and :term:`checksum line`, +are collectively called an Argument Clinic :term:`block`: .. code-block:: none @@ -117,464 +76,606 @@ The Argument Clinic block now looks like this: ... clinic input goes here ... [clinic start generated code]*/ ... clinic output goes here ... - /*[clinic end generated code: checksum=...]*/ + /*[clinic end generated code: ...]*/ If you run Argument Clinic on the same file a second time, Argument Clinic -will discard the old output and write out the new output with a fresh checksum -line. However, if the input hasn't changed, the output won't change either. +will discard the old :term:`output` and write out the new output with a fresh +:term:`checksum line`. +If the :term:`input` hasn't changed, the output won't change either. -You should never modify the output portion of an Argument Clinic block. Instead, -change the input until it produces the output you want. (That's the purpose of the -checksum—to detect if someone changed the output, as these edits would be lost -the next time Argument Clinic writes out fresh output.) +.. note:: -For the sake of clarity, here's the terminology we'll use with Argument Clinic: + You should never modify the output of an Argument Clinic block, + as any change will be lost in future Argument Clinic runs; + Argument Clinic will detect an output checksum mismatch and regenerate the + correct output. + If you are not happy with the generated output, + you should instead change the input until it produces the output you want. -* The first line of the comment (``/*[clinic input]``) is the *start line*. -* The last line of the initial comment (``[clinic start generated code]*/``) is the *end line*. -* The last line (``/*[clinic end generated code: checksum=...]*/``) is the *checksum line*. -* In between the start line and the end line is the *input*. -* In between the end line and the checksum line is the *output*. -* All the text collectively, from the start line to the checksum line inclusively, - is the *block*. (A block that hasn't been successfully processed by Argument - Clinic yet doesn't have output or a checksum line, but it's still considered - a block.) +.. _clinic-reference: -Converting Your First Function -============================== +Reference +========= -The best way to get a sense of how Argument Clinic works is to -convert a function to work with it. Here, then, are the bare -minimum steps you'd need to follow to convert a function to -work with Argument Clinic. Note that for code you plan to -check in to CPython, you really should take the conversion farther, -using some of the advanced concepts you'll see later on in -the document (like "return converters" and "self converters"). -But we'll keep it simple for this walkthrough so you can learn. -Let's dive in! +.. _clinic-terminology: -0. Make sure you're working with a freshly updated checkout - of the CPython trunk. +Terminology +----------- -1. Find a Python builtin that calls either :c:func:`PyArg_ParseTuple` - or :c:func:`PyArg_ParseTupleAndKeywords`, and hasn't been converted - to work with Argument Clinic yet. - For my example I'm using ``_pickle.Pickler.dump()``. +.. glossary:: -2. If the call to the ``PyArg_Parse`` function uses any of the - following format units: + start line + The line ``/*[clinic input]``. + This line marks the beginning of Argument Clinic input. + Note that the *start line* opens a C block comment. - .. code-block:: none + end line + The line ``[clinic start generated code]*/``. + The *end line* marks the _end_ of Argument Clinic :term:`input`, + but at the same time marks the _start_ of Argument Clinic :term:`output`, + thus the text *"clinic start start generated code"* + Note that the *end line* closes the C block comment opened + by the *start line*. - O& - O! - es - es# - et - et# + checksum + A hash to distinguish unique :term:`inputs <input>` + and :term:`outputs <output>`. - or if it has multiple calls to :c:func:`PyArg_ParseTuple`, - you should choose a different function. Argument Clinic *does* - support all of these scenarios. But these are advanced - topics—let's do something simpler for your first function. + checksum line + A line that looks like ``/*[clinic end generated code: ...]*/``. + The three dots will be replaced by a :term:`checksum` generated from the + :term:`input`, and a :term:`checksum` generated from the :term:`output`. + The checksum line marks the end of Argument Clinic generated code, + and is used by Argument Clinic to determine if it needs to regenerate + output. - Also, if the function has multiple calls to :c:func:`PyArg_ParseTuple` - or :c:func:`PyArg_ParseTupleAndKeywords` where it supports different - types for the same argument, or if the function uses something besides - PyArg_Parse functions to parse its arguments, it probably - isn't suitable for conversion to Argument Clinic. Argument Clinic - doesn't support generic functions or polymorphic parameters. + input + The text between the :term:`start line` and the :term:`end line`. + Note that the start and end lines open and close a C block comment; + the *input* is thus a part of that same C block comment. -3. Add the following boilerplate above the function, creating our block:: + output + The text between the :term:`end line` and the :term:`checksum line`. - /*[clinic input] - [clinic start generated code]*/ + block + All text from the :term:`start line` to the :term:`checksum line` inclusively. -4. Cut the docstring and paste it in between the ``[clinic]`` lines, - removing all the junk that makes it a properly quoted C string. - When you're done you should have just the text, based at the left - margin, with no line wider than 80 characters. - (Argument Clinic will preserve indents inside the docstring.) - If the old docstring had a first line that looked like a function - signature, throw that line away. (The docstring doesn't need it - anymore—when you use ``help()`` on your builtin in the future, - the first line will be built automatically based on the function's - signature.) +.. _clinic-cli: - Sample:: +Command-line interface +---------------------- - /*[clinic input] - Write a pickled representation of obj to the open file. - [clinic start generated code]*/ +The Argument Clinic :abbr:`CLI (Command-Line Interface)` is typically used to +process a single source file, like this: -5. If your docstring doesn't have a "summary" line, Argument Clinic will - complain. So let's make sure it has one. The "summary" line should - be a paragraph consisting of a single 80-column line - at the beginning of the docstring. +.. code-block:: shell-session - (Our example docstring consists solely of a summary line, so the sample - code doesn't have to change for this step.) + $ python3 ./Tools/clinic/clinic.py foo.c -6. Above the docstring, enter the name of the function, followed - by a blank line. This should be the Python name of the function, - and should be the full dotted path - to the function—it should start with the name of the module, - include any sub-modules, and if the function is a method on - a class it should include the class name too. +The CLI supports the following options: - Sample:: +.. program:: ./Tools/clinic/clinic.py [-h] [-f] [-o OUTPUT] [-v] \ + [--converters] [--make] [--srcdir SRCDIR] [FILE ...] - /*[clinic input] - _pickle.Pickler.dump +.. option:: -h, --help - Write a pickled representation of obj to the open file. - [clinic start generated code]*/ + Print CLI usage. -7. If this is the first time that module or class has been used with Argument - Clinic in this C file, - you must declare the module and/or class. Proper Argument Clinic hygiene - prefers declaring these in a separate block somewhere near the - top of the C file, in the same way that include files and statics go at - the top. (In our sample code we'll just show the two blocks next to - each other.) +.. option:: -f, --force - The name of the class and module should be the same as the one - seen by Python. Check the name defined in the :c:type:`PyModuleDef` - or :c:type:`PyTypeObject` as appropriate. + Force output regeneration. - When you declare a class, you must also specify two aspects of its type - in C: the type declaration you'd use for a pointer to an instance of - this class, and a pointer to the :c:type:`PyTypeObject` for this class. +.. option:: -o, --output OUTPUT - Sample:: + Redirect file output to OUTPUT - /*[clinic input] - module _pickle - class _pickle.Pickler "PicklerObject *" "&Pickler_Type" - [clinic start generated code]*/ +.. option:: -v, --verbose - /*[clinic input] - _pickle.Pickler.dump + Enable verbose mode. - Write a pickled representation of obj to the open file. - [clinic start generated code]*/ +.. option:: --converters + Print a list of all supported converters and return converters. +.. option:: --make + Walk :option:`--srcdir` to run over all relevant files. -8. Declare each of the parameters to the function. Each parameter - should get its own line. All the parameter lines should be - indented from the function name and the docstring. +.. option:: --srcdir SRCDIR - The general form of these parameter lines is as follows: + The directory tree to walk in :option:`--make` mode. - .. code-block:: none +.. option:: FILE ... - name_of_parameter: converter + The list of files to process. - If the parameter has a default value, add that after the - converter: - .. code-block:: none +.. _clinic-classes: + +Classes for extending Argument Clinic +------------------------------------- + +.. module:: clinic - name_of_parameter: converter = default_value +.. class:: CConverter - Argument Clinic's support for "default values" is quite sophisticated; - please see :ref:`the section below on default values <default_values>` - for more information. + The base class for all converters. + See :ref:`clinic-howto-custom-converter` for how to subclass this class. - Add a blank line below the parameters. + .. attribute:: type - What's a "converter"? It establishes both the type - of the variable used in C, and the method to convert the Python - value into a C value at runtime. - For now you're going to use what's called a "legacy converter"—a - convenience syntax intended to make porting old code into Argument - Clinic easier. + The C type to use for this variable. + :attr:`!type` should be a Python string specifying the type, + e.g. ``'int'``. + If this is a pointer type, the type string should end with ``' *'``. - For each parameter, copy the "format unit" for that - parameter from the ``PyArg_Parse()`` format argument and - specify *that* as its converter, as a quoted - string. ("format unit" is the formal name for the one-to-three - character substring of the ``format`` parameter that tells - the argument parsing function what the type of the variable - is and how to convert it. For more on format units please - see :ref:`arg-parsing`.) + .. attribute:: default - For multicharacter format units like ``z#``, use the - entire two-or-three character string. + The Python default value for this parameter, as a Python value. + Or the magic value ``unspecified`` if there is no default. - Sample:: + .. attribute:: py_default - /*[clinic input] - module _pickle - class _pickle.Pickler "PicklerObject *" "&Pickler_Type" - [clinic start generated code]*/ + :attr:`!default` as it should appear in Python code, + as a string. + Or ``None`` if there is no default. - /*[clinic input] - _pickle.Pickler.dump + .. attribute:: c_default - obj: 'O' + :attr:`!default` as it should appear in C code, + as a string. + Or ``None`` if there is no default. - Write a pickled representation of obj to the open file. - [clinic start generated code]*/ + .. attribute:: c_ignored_default -9. If your function has ``|`` in the format string, meaning some - parameters have default values, you can ignore it. Argument - Clinic infers which parameters are optional based on whether - or not they have default values. + The default value used to initialize the C variable when + there is no default, but not specifying a default may + result in an "uninitialized variable" warning. This can + easily happen when using option groups—although + properly written code will never actually use this value, + the variable does get passed in to the impl, and the + C compiler will complain about the "use" of the + uninitialized value. This value should always be a + non-empty string. - If your function has ``$`` in the format string, meaning it - takes keyword-only arguments, specify ``*`` on a line by - itself before the first keyword-only argument, indented the - same as the parameter lines. + .. attribute:: converter - (``_pickle.Pickler.dump`` has neither, so our sample is unchanged.) + The name of the C converter function, as a string. + .. attribute:: impl_by_reference -10. If the existing C function calls :c:func:`PyArg_ParseTuple` - (as opposed to :c:func:`PyArg_ParseTupleAndKeywords`), then all its - arguments are positional-only. + A boolean value. If true, + Argument Clinic will add a ``&`` in front of the name of + the variable when passing it into the impl function. - To mark all parameters as positional-only in Argument Clinic, - add a ``/`` on a line by itself after the last parameter, - indented the same as the parameter lines. + .. attribute:: parse_by_reference - Currently this is all-or-nothing; either all parameters are - positional-only, or none of them are. (In the future Argument - Clinic may relax this restriction.) + A boolean value. If true, + Argument Clinic will add a ``&`` in front of the name of + the variable when passing it into :c:func:`PyArg_ParseTuple`. - Sample:: - /*[clinic input] - module _pickle - class _pickle.Pickler "PicklerObject *" "&Pickler_Type" - [clinic start generated code]*/ +.. _clinic-tutorial: - /*[clinic input] - _pickle.Pickler.dump +Tutorial +======== + +The best way to get a sense of how Argument Clinic works is to +convert a function to work with it. Here, then, are the bare +minimum steps you'd need to follow to convert a function to +work with Argument Clinic. Note that for code you plan to +check in to CPython, you really should take the conversion farther, +using some of the :ref:`advanced concepts <clinic-howtos>` +you'll see later on in the document, +like :ref:`clinic-howto-return-converters` +and :ref:`clinic-howto-self-converter`. +But we'll keep it simple for this walkthrough so you can learn. - obj: 'O' - / +First, make sure you're working with a freshly updated checkout +of the CPython trunk. - Write a pickled representation of obj to the open file. - [clinic start generated code]*/ +Next, find a Python builtin that calls either :c:func:`PyArg_ParseTuple` +or :c:func:`PyArg_ParseTupleAndKeywords`, and hasn't been converted +to work with Argument Clinic yet. +For this tutorial, we'll be using +:py:meth:`_pickle.Pickler.dump <pickle.Pickler.dump>`. -11. It's helpful to write a per-parameter docstring for each parameter. - But per-parameter docstrings are optional; you can skip this step - if you prefer. +If the call to the :c:func:`!PyArg_Parse*` function uses any of the +following format units...: - Here's how to add a per-parameter docstring. The first line - of the per-parameter docstring must be indented further than the - parameter definition. The left margin of this first line establishes - the left margin for the whole per-parameter docstring; all the text - you write will be outdented by this amount. You can write as much - text as you like, across multiple lines if you wish. + .. code-block:: none - Sample:: + O& + O! + es + es# + et + et# - /*[clinic input] - module _pickle - class _pickle.Pickler "PicklerObject *" "&Pickler_Type" - [clinic start generated code]*/ +... or if it has multiple calls to :c:func:`PyArg_ParseTuple`, +you should choose a different function. +(See :ref:`clinic-howto-advanced-converters` for those scenarios.) - /*[clinic input] - _pickle.Pickler.dump +Also, if the function has multiple calls to :c:func:`!PyArg_ParseTuple` +or :c:func:`PyArg_ParseTupleAndKeywords` where it supports different +types for the same argument, or if the function uses something besides +:c:func:`!PyArg_Parse*` functions to parse its arguments, it probably +isn't suitable for conversion to Argument Clinic. Argument Clinic +doesn't support generic functions or polymorphic parameters. - obj: 'O' - The object to be pickled. - / +Next, add the following boilerplate above the function, +creating our input block:: - Write a pickled representation of obj to the open file. - [clinic start generated code]*/ + /*[clinic input] + [clinic start generated code]*/ -12. Save and close the file, then run ``Tools/clinic/clinic.py`` on - it. With luck everything worked---your block now has output, and - a ``.c.h`` file has been generated! Reopen the file in your - text editor to see:: +Cut the docstring and paste it in between the ``[clinic]`` lines, +removing all the junk that makes it a properly quoted C string. +When you're done you should have just the text, based at the left +margin, with no line wider than 80 characters. +Argument Clinic will preserve indents inside the docstring. + +If the old docstring had a first line that looked like a function +signature, throw that line away; The docstring doesn't need it anymore --- +when you use :py:func:`help` on your builtin in the future, +the first line will be built automatically based on the function's signature. + +Example docstring summary line:: + + /*[clinic input] + Write a pickled representation of obj to the open file. + [clinic start generated code]*/ + +If your docstring doesn't have a "summary" line, Argument Clinic will +complain, so let's make sure it has one. The "summary" line should +be a paragraph consisting of a single 80-column line +at the beginning of the docstring. +(See :pep:`257` regarding docstring conventions.) + +Our example docstring consists solely of a summary line, so the sample +code doesn't have to change for this step. + +Now, above the docstring, enter the name of the function, followed +by a blank line. This should be the Python name of the function, +and should be the full dotted path to the function --- +it should start with the name of the module, +include any sub-modules, and if the function is a method on +a class it should include the class name too. + +In our example, :mod:`!_pickle` is the module, :py:class:`!Pickler` is the class, +and :py:meth:`!dump` is the method, so the name becomes +:py:meth:`!_pickle.Pickler.dump`:: + + /*[clinic input] + _pickle.Pickler.dump + + Write a pickled representation of obj to the open file. + [clinic start generated code]*/ + +If this is the first time that module or class has been used with Argument +Clinic in this C file, +you must declare the module and/or class. Proper Argument Clinic hygiene +prefers declaring these in a separate block somewhere near the +top of the C file, in the same way that include files and statics go at +the top. +In our sample code we'll just show the two blocks next to each other. + +The name of the class and module should be the same as the one +seen by Python. Check the name defined in the :c:type:`PyModuleDef` +or :c:type:`PyTypeObject` as appropriate. + +When you declare a class, you must also specify two aspects of its type +in C: the type declaration you'd use for a pointer to an instance of +this class, and a pointer to the :c:type:`!PyTypeObject` for this class:: + + /*[clinic input] + module _pickle + class _pickle.Pickler "PicklerObject *" "&Pickler_Type" + [clinic start generated code]*/ + + /*[clinic input] + _pickle.Pickler.dump + + Write a pickled representation of obj to the open file. + [clinic start generated code]*/ + +Declare each of the parameters to the function. Each parameter +should get its own line. All the parameter lines should be +indented from the function name and the docstring. +The general form of these parameter lines is as follows: - /*[clinic input] - _pickle.Pickler.dump +.. code-block:: none - obj: 'O' - The object to be pickled. - / + name_of_parameter: converter - Write a pickled representation of obj to the open file. - [clinic start generated code]*/ +If the parameter has a default value, add that after the +converter: - static PyObject * - _pickle_Pickler_dump(PicklerObject *self, PyObject *obj) - /*[clinic end generated code: output=87ecad1261e02ac7 input=552eb1c0f52260d9]*/ +.. code-block:: none - Obviously, if Argument Clinic didn't produce any output, it's because - it found an error in your input. Keep fixing your errors and retrying - until Argument Clinic processes your file without complaint. + name_of_parameter: converter = default_value - For readability, most of the glue code has been generated to a ``.c.h`` - file. You'll need to include that in your original ``.c`` file, - typically right after the clinic module block:: +Argument Clinic's support for "default values" is quite sophisticated; +see :ref:`clinic-howto-default-values` for more information. - #include "clinic/_pickle.c.h" +Next, add a blank line below the parameters. -13. Double-check that the argument-parsing code Argument Clinic generated - looks basically the same as the existing code. +What's a "converter"? +It establishes both the type of the variable used in C, +and the method to convert the Python value into a C value at runtime. +For now you're going to use what's called a "legacy converter" --- +a convenience syntax intended to make porting old code into Argument +Clinic easier. - First, ensure both places use the same argument-parsing function. - The existing code must call either - :c:func:`PyArg_ParseTuple` or :c:func:`PyArg_ParseTupleAndKeywords`; - ensure that the code generated by Argument Clinic calls the - *exact* same function. +For each parameter, copy the "format unit" for that +parameter from the :c:func:`PyArg_Parse` format argument and +specify *that* as its converter, as a quoted string. +The "format unit" is the formal name for the one-to-three +character substring of the *format* parameter that tells +the argument parsing function what the type of the variable +is and how to convert it. +For more on format units please see :ref:`arg-parsing`. - Second, the format string passed in to :c:func:`PyArg_ParseTuple` or - :c:func:`PyArg_ParseTupleAndKeywords` should be *exactly* the same - as the hand-written one in the existing function, up to the colon - or semi-colon. +For multicharacter format units like ``z#``, +use the entire two-or-three character string. - (Argument Clinic always generates its format strings - with a ``:`` followed by the name of the function. If the - existing code's format string ends with ``;``, to provide - usage help, this change is harmless—don't worry about it.) +Sample:: - Third, for parameters whose format units require two arguments - (like a length variable, or an encoding string, or a pointer - to a conversion function), ensure that the second argument is - *exactly* the same between the two invocations. + /*[clinic input] + module _pickle + class _pickle.Pickler "PicklerObject *" "&Pickler_Type" + [clinic start generated code]*/ - Fourth, inside the output portion of the block you'll find a preprocessor - macro defining the appropriate static :c:type:`PyMethodDef` structure for - this builtin:: + /*[clinic input] + _pickle.Pickler.dump - #define __PICKLE_PICKLER_DUMP_METHODDEF \ - {"dump", (PyCFunction)__pickle_Pickler_dump, METH_O, __pickle_Pickler_dump__doc__}, + obj: 'O' - This static structure should be *exactly* the same as the existing static - :c:type:`PyMethodDef` structure for this builtin. + Write a pickled representation of obj to the open file. + [clinic start generated code]*/ - If any of these items differ in *any way*, - adjust your Argument Clinic function specification and rerun - ``Tools/clinic/clinic.py`` until they *are* the same. +If your function has ``|`` in the format string, +meaning some parameters have default values, you can ignore it. +Argument Clinic infers which parameters are optional +based on whether or not they have default values. +If your function has ``$`` in the format string, +meaning it takes keyword-only arguments, +specify ``*`` on a line by itself before the first keyword-only argument, +indented the same as the parameter lines. -14. Notice that the last line of its output is the declaration - of your "impl" function. This is where the builtin's implementation goes. - Delete the existing prototype of the function you're modifying, but leave - the opening curly brace. Now delete its argument parsing code and the - declarations of all the variables it dumps the arguments into. - Notice how the Python arguments are now arguments to this impl function; - if the implementation used different names for these variables, fix it. +:py:meth:`!_pickle.Pickler.dump` has neither, so our sample is unchanged. - Let's reiterate, just because it's kind of weird. Your code should now - look like this:: +Next, if the existing C function calls :c:func:`PyArg_ParseTuple` +(as opposed to :c:func:`PyArg_ParseTupleAndKeywords`), then all its +arguments are positional-only. - static return_type - your_function_impl(...) - /*[clinic end generated code: checksum=...]*/ - { - ... +To mark parameters as positional-only in Argument Clinic, +add a ``/`` on a line by itself after the last positional-only parameter, +indented the same as the parameter lines. - Argument Clinic generated the checksum line and the function prototype just - above it. You should write the opening (and closing) curly braces for the - function, and the implementation inside. +Sample:: - Sample:: + /*[clinic input] + module _pickle + class _pickle.Pickler "PicklerObject *" "&Pickler_Type" + [clinic start generated code]*/ - /*[clinic input] - module _pickle - class _pickle.Pickler "PicklerObject *" "&Pickler_Type" - [clinic start generated code]*/ - /*[clinic end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ + /*[clinic input] + _pickle.Pickler.dump - /*[clinic input] - _pickle.Pickler.dump + obj: 'O' + / - obj: 'O' - The object to be pickled. - / + Write a pickled representation of obj to the open file. + [clinic start generated code]*/ - Write a pickled representation of obj to the open file. - [clinic start generated code]*/ +It can be helpful to write a per-parameter docstring for each parameter. +Since per-parameter docstrings are optional, +you can skip this step if you prefer. - PyDoc_STRVAR(__pickle_Pickler_dump__doc__, - "Write a pickled representation of obj to the open file.\n" - "\n" - ... - static PyObject * - _pickle_Pickler_dump_impl(PicklerObject *self, PyObject *obj) - /*[clinic end generated code: checksum=3bd30745bf206a48f8b576a1da3d90f55a0a4187]*/ - { - /* Check whether the Pickler was initialized correctly (issue3664). - Developers often forget to call __init__() in their subclasses, which - would trigger a segfault without this check. */ - if (self->write == NULL) { - PyErr_Format(PicklingError, - "Pickler.__init__() was not called by %s.__init__()", - Py_TYPE(self)->tp_name); - return NULL; - } +Nevertheless, here's how to add a per-parameter docstring. +The first line of the per-parameter docstring +must be indented further than the parameter definition. +The left margin of this first line establishes +the left margin for the whole per-parameter docstring; +all the text you write will be outdented by this amount. +You can write as much text as you like, across multiple lines if you wish. - if (_Pickler_ClearBuffer(self) < 0) - return NULL; +Sample:: - ... + /*[clinic input] + module _pickle + class _pickle.Pickler "PicklerObject *" "&Pickler_Type" + [clinic start generated code]*/ -15. Remember the macro with the :c:type:`PyMethodDef` structure for this - function? Find the existing :c:type:`PyMethodDef` structure for this - function and replace it with a reference to the macro. (If the builtin - is at module scope, this will probably be very near the end of the file; - if the builtin is a class method, this will probably be below but relatively - near to the implementation.) + /*[clinic input] + _pickle.Pickler.dump - Note that the body of the macro contains a trailing comma. So when you - replace the existing static :c:type:`PyMethodDef` structure with the macro, - *don't* add a comma to the end. + obj: 'O' + The object to be pickled. + / - Sample:: + Write a pickled representation of obj to the open file. + [clinic start generated code]*/ - static struct PyMethodDef Pickler_methods[] = { - __PICKLE_PICKLER_DUMP_METHODDEF - __PICKLE_PICKLER_CLEAR_MEMO_METHODDEF - {NULL, NULL} /* sentinel */ - }; +Save and close the file, then run ``Tools/clinic/clinic.py`` on it. +With luck everything worked---your block now has output, +and a :file:`.c.h` file has been generated! +Reload the file in your text editor to see the generated code:: + /*[clinic input] + _pickle.Pickler.dump -16. Compile, then run the relevant portions of the regression-test suite. - This change should not introduce any new compile-time warnings or errors, - and there should be no externally visible change to Python's behavior. + obj: 'O' + The object to be pickled. + / - Well, except for one difference: ``inspect.signature()`` run on your function - should now provide a valid signature! + Write a pickled representation of obj to the open file. + [clinic start generated code]*/ - Congratulations, you've ported your first function to work with Argument Clinic! + static PyObject * + _pickle_Pickler_dump(PicklerObject *self, PyObject *obj) + /*[clinic end generated code: output=87ecad1261e02ac7 input=552eb1c0f52260d9]*/ + +Obviously, if Argument Clinic didn't produce any output, +it's because it found an error in your input. +Keep fixing your errors and retrying until Argument Clinic processes your file +without complaint. + +For readability, most of the glue code has been generated to a :file:`.c.h` +file. You'll need to include that in your original :file:`.c` file, +typically right after the clinic module block:: + + #include "clinic/_pickle.c.h" + +Double-check that the argument-parsing code Argument Clinic generated +looks basically the same as the existing code. + +First, ensure both places use the same argument-parsing function. +The existing code must call either +:c:func:`PyArg_ParseTuple` or :c:func:`PyArg_ParseTupleAndKeywords`; +ensure that the code generated by Argument Clinic calls the +*exact* same function. + +Second, the format string passed in to :c:func:`!PyArg_ParseTuple` or +:c:func:`!PyArg_ParseTupleAndKeywords` should be *exactly* the same +as the hand-written one in the existing function, +up to the colon or semi-colon. + +Argument Clinic always generates its format strings +with a ``:`` followed by the name of the function. +If the existing code's format string ends with ``;``, +to provide usage help, this change is harmless --- don't worry about it. + +Third, for parameters whose format units require two arguments, +like a length variable, an encoding string, or a pointer +to a conversion function, ensure that the second argument is +*exactly* the same between the two invocations. + +Fourth, inside the output portion of the block, +you'll find a preprocessor macro defining the appropriate static +:c:type:`PyMethodDef` structure for this builtin:: + + #define __PICKLE_PICKLER_DUMP_METHODDEF \ + {"dump", (PyCFunction)__pickle_Pickler_dump, METH_O, __pickle_Pickler_dump__doc__}, + +This static structure should be *exactly* the same as the existing static +:c:type:`!PyMethodDef` structure for this builtin. + +If any of these items differ in *any way*, +adjust your Argument Clinic function specification and rerun +``Tools/clinic/clinic.py`` until they *are* the same. + +Notice that the last line of its output is the declaration +of your "impl" function. This is where the builtin's implementation goes. +Delete the existing prototype of the function you're modifying, but leave +the opening curly brace. Now delete its argument parsing code and the +declarations of all the variables it dumps the arguments into. +Notice how the Python arguments are now arguments to this impl function; +if the implementation used different names for these variables, fix it. + +Let's reiterate, just because it's kind of weird. +Your code should now look like this:: -Advanced Topics -=============== + static return_type + your_function_impl(...) + /*[clinic end generated code: input=..., output=...]*/ + { + ... -Now that you've had some experience working with Argument Clinic, it's time -for some advanced topics. +Argument Clinic generated the checksum line and the function prototype just +above it. You should write the opening and closing curly braces for the +function, and the implementation inside. +Sample:: -Symbolic default values ------------------------ + /*[clinic input] + module _pickle + class _pickle.Pickler "PicklerObject *" "&Pickler_Type" + [clinic start generated code]*/ + /*[clinic end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ -The default value you provide for a parameter can't be any arbitrary -expression. Currently the following are explicitly supported: + /*[clinic input] + _pickle.Pickler.dump -* Numeric constants (integer and float) -* String constants -* ``True``, ``False``, and ``None`` -* Simple symbolic constants like ``sys.maxsize``, which must - start with the name of the module + obj: 'O' + The object to be pickled. + / -(In the future, this may need to get even more elaborate, -to allow full expressions like ``CONSTANT - 1``.) + Write a pickled representation of obj to the open file. + [clinic start generated code]*/ + PyDoc_STRVAR(__pickle_Pickler_dump__doc__, + "Write a pickled representation of obj to the open file.\n" + "\n" + ... + static PyObject * + _pickle_Pickler_dump_impl(PicklerObject *self, PyObject *obj) + /*[clinic end generated code: checksum=3bd30745bf206a48f8b576a1da3d90f55a0a4187]*/ + { + /* Check whether the Pickler was initialized correctly (issue3664). + Developers often forget to call __init__() in their subclasses, which + would trigger a segfault without this check. */ + if (self->write == NULL) { + PyErr_Format(PicklingError, + "Pickler.__init__() was not called by %s.__init__()", + Py_TYPE(self)->tp_name); + return NULL; + } -Renaming the C functions and variables generated by Argument Clinic -------------------------------------------------------------------- + if (_Pickler_ClearBuffer(self) < 0) { + return NULL; + } + + ... + +Remember the macro with the :c:type:`PyMethodDef` structure for this function? +Find the existing :c:type:`!PyMethodDef` structure for this +function and replace it with a reference to the macro. If the builtin +is at module scope, this will probably be very near the end of the file; +if the builtin is a class method, this will probably be below but relatively +near to the implementation. + +Note that the body of the macro contains a trailing comma; when you +replace the existing static :c:type:`!PyMethodDef` structure with the macro, +*don't* add a comma to the end. + +Sample:: + + static struct PyMethodDef Pickler_methods[] = { + __PICKLE_PICKLER_DUMP_METHODDEF + __PICKLE_PICKLER_CLEAR_MEMO_METHODDEF + {NULL, NULL} /* sentinel */ + }; + +Argument Clinic may generate new instances of ``_Py_ID``. For example:: + + &_Py_ID(new_unique_py_id) + +If it does, you'll have to run ``make regen-global-objects`` +to regenerate the list of precompiled identifiers at this point. + +Finally, compile, then run the relevant portions of the regression-test suite. +This change should not introduce any new compile-time warnings or errors, +and there should be no externally visible change to Python's behavior, +except for one difference: :py:func:`inspect.signature` run on your function +should now provide a valid signature! + +Congratulations, you've ported your first function to work with Argument Clinic! + + +.. _clinic-howtos: + +How-to guides +============= + + +How to rename C functions and variables generated by Argument Clinic +-------------------------------------------------------------------- Argument Clinic automatically names the functions it generates for you. Occasionally this may cause a problem, if the generated name collides with @@ -585,15 +686,15 @@ Argument Clinic will use that function name for the base (generated) function, then add ``"_impl"`` to the end and use that for the name of the impl function. For example, if we wanted to rename the C function names generated for -``pickle.Pickler.dump``, it'd look like this:: +:py:meth:`pickle.Pickler.dump`, it'd look like this:: /*[clinic input] pickle.Pickler.dump as pickler_dumper ... -The base function would now be named ``pickler_dumper()``, -and the impl function would now be named ``pickler_dumper_impl()``. +The base function would now be named :c:func:`!pickler_dumper`, +and the impl function would now be named :c:func:`!pickler_dumper_impl`. Similarly, you may have a problem where you want to give a parameter @@ -611,25 +712,26 @@ using the same ``"as"`` syntax:: fix_imports: bool = True Here, the name used in Python (in the signature and the ``keywords`` -array) would be ``file``, but the C variable would be named ``file_obj``. +array) would be *file*, but the C variable would be named ``file_obj``. -You can use this to rename the ``self`` parameter too! +You can use this to rename the *self* parameter too! -Converting functions using PyArg_UnpackTuple --------------------------------------------- +How to convert functions using ``PyArg_UnpackTuple`` +---------------------------------------------------- To convert a function parsing its arguments with :c:func:`PyArg_UnpackTuple`, simply write out all the arguments, specifying each as an ``object``. You -may specify the ``type`` argument to cast the type as appropriate. All +may specify the *type* argument to cast the type as appropriate. All arguments should be marked positional-only (add a ``/`` on a line by itself after the last argument). Currently the generated code will use :c:func:`PyArg_ParseTuple`, but this will change soon. -Optional Groups ---------------- + +How to use optional groups +-------------------------- Some legacy functions have a tricky approach to parsing their arguments: they count the number of positional arguments, then use a ``switch`` statement @@ -639,16 +741,16 @@ keyword-only arguments.) This approach was used to simulate optional arguments back before :c:func:`PyArg_ParseTupleAndKeywords` was created. While functions using this approach can often be converted to -use :c:func:`PyArg_ParseTupleAndKeywords`, optional arguments, and default values, +use :c:func:`!PyArg_ParseTupleAndKeywords`, optional arguments, and default values, it's not always possible. Some of these legacy functions have -behaviors :c:func:`PyArg_ParseTupleAndKeywords` doesn't directly support. -The most obvious example is the builtin function ``range()``, which has +behaviors :c:func:`!PyArg_ParseTupleAndKeywords` doesn't directly support. +The most obvious example is the builtin function :py:func:`range`, which has an optional argument on the *left* side of its required argument! -Another example is ``curses.window.addch()``, which has a group of two +Another example is :py:meth:`curses.window.addch`, which has a group of two arguments that must always be specified together. (The arguments are -called ``x`` and ``y``; if you call the function passing in ``x``, -you must also pass in ``y``—and if you don't pass in ``x`` you may not -pass in ``y`` either.) +called *x* and *y*; if you call the function passing in *x*, +you must also pass in *y* — and if you don't pass in *x* you may not +pass in *y* either.) In any case, the goal of Argument Clinic is to support argument parsing for all existing CPython builtins without changing their semantics. @@ -669,7 +771,7 @@ can *only* be used with positional-only parameters. To specify an optional group, add a ``[`` on a line by itself before the parameters you wish to group together, and a ``]`` on a line by itself -after these parameters. As an example, here's how ``curses.window.addch`` +after these parameters. As an example, here's how :py:meth:`curses.window.addch` uses optional groups to make the first two parameters and the last parameter optional:: @@ -721,8 +823,8 @@ Notes: use optional groups for new code. -Using real Argument Clinic converters, instead of "legacy converters" ---------------------------------------------------------------------- +How to use real Argument Clinic converters, instead of "legacy converters" +-------------------------------------------------------------------------- To save time, and to minimize how much you need to learn to achieve your first port to Argument Clinic, the walkthrough above tells @@ -755,22 +857,25 @@ the same converters. All arguments to Argument Clinic converters are keyword-only. All Argument Clinic converters accept the following arguments: - ``c_default`` + *c_default* The default value for this parameter when defined in C. Specifically, this will be the initializer for the variable declared in the "parse function". See :ref:`the section on default values <default_values>` for how to use this. Specified as a string. - ``annotation`` + *annotation* The annotation value for this parameter. Not currently supported, because :pep:`8` mandates that the Python library may not use annotations. + *unused* + Wrap the argument with :c:macro:`Py_UNUSED` in the impl function signature. + In addition, some converters accept additional arguments. Here is a list of these arguments, along with their meanings: - ``accept`` + *accept* A set of Python types (and possibly pseudo-types); this restricts the allowable Python argument to values of these types. (This is not a general-purpose facility; as a rule it only supports @@ -778,38 +883,38 @@ of these arguments, along with their meanings: To accept ``None``, add ``NoneType`` to this set. - ``bitwise`` + *bitwise* Only supported for unsigned integers. The native integer value of this Python argument will be written to the parameter without any range checking, even for negative values. - ``converter`` + *converter* Only supported by the ``object`` converter. Specifies the name of a :ref:`C "converter function" <o_ampersand>` to use to convert this object to a native type. - ``encoding`` + *encoding* Only supported for strings. Specifies the encoding to use when converting this string from a Python str (Unicode) value into a C ``char *`` value. - ``subclass_of`` + *subclass_of* Only supported for the ``object`` converter. Requires that the Python value be a subclass of a Python type, as expressed in C. - ``type`` + *type* Only supported for the ``object`` and ``self`` converters. Specifies the C type that will be used to declare the variable. Default value is ``"PyObject *"``. - ``zeroes`` + *zeroes* Only supported for strings. If true, embedded NUL bytes (``'\\0'``) are permitted inside the value. The length of the string will be passed in to the impl function, just after the string parameter, as a parameter named ``<parameter_name>_length``. Please note, not every possible combination of arguments will work. -Usually these arguments are implemented by specific ``PyArg_ParseTuple`` +Usually these arguments are implemented by specific :c:func:`PyArg_ParseTuple` *format units*, with specific behavior. For example, currently you cannot call ``unsigned_short`` without also specifying ``bitwise=True``. Although it's perfectly reasonable to think this would work, these semantics don't @@ -850,15 +955,15 @@ on the right is the text you'd replace it with. ``'s#'`` ``str(zeroes=True)`` ``'s*'`` ``Py_buffer(accept={buffer, str})`` ``'U'`` ``unicode`` -``'u'`` ``Py_UNICODE`` -``'u#'`` ``Py_UNICODE(zeroes=True)`` +``'u'`` ``wchar_t`` +``'u#'`` ``wchar_t(zeroes=True)`` ``'w*'`` ``Py_buffer(accept={rwbuffer})`` ``'Y'`` ``PyByteArrayObject`` ``'y'`` ``str(accept={bytes})`` ``'y#'`` ``str(accept={robuffer}, zeroes=True)`` ``'y*'`` ``Py_buffer`` -``'Z'`` ``Py_UNICODE(accept={str, NoneType})`` -``'Z#'`` ``Py_UNICODE(accept={str, NoneType}, zeroes=True)`` +``'Z'`` ``wchar_t(accept={str, NoneType})`` +``'Z#'`` ``wchar_t(accept={str, NoneType}, zeroes=True)`` ``'z'`` ``str(accept={str, NoneType})`` ``'z#'`` ``str(accept={str, NoneType}, zeroes=True)`` ``'z*'`` ``Py_buffer(accept={buffer, str, NoneType})`` @@ -888,8 +993,9 @@ available. For each converter it'll show you all the parameters it accepts, along with the default value for each parameter. Just run ``Tools/clinic/clinic.py --converters`` to see the full list. -Py_buffer ---------- + +How to use the ``Py_buffer`` converter +-------------------------------------- When using the ``Py_buffer`` converter (or the ``'s*'``, ``'w*'``, ``'*y'``, or ``'z*'`` legacy converters), @@ -897,9 +1003,10 @@ you *must* not call :c:func:`PyBuffer_Release` on the provided buffer. Argument Clinic generates code that does it for you (in the parsing function). +.. _clinic-howto-advanced-converters: -Advanced converters -------------------- +How to use advanced converters +------------------------------ Remember those format units you skipped for your first time because they were advanced? Here's how to handle those too. @@ -909,29 +1016,30 @@ conversion functions, or types, or strings specifying an encoding. (But "legacy converters" don't support arguments. That's why we skipped them for your first function.) The argument you specified to the format unit is now an argument to the converter; this -argument is either ``converter`` (for ``O&``), ``subclass_of`` (for ``O!``), -or ``encoding`` (for all the format units that start with ``e``). +argument is either *converter* (for ``O&``), *subclass_of* (for ``O!``), +or *encoding* (for all the format units that start with ``e``). -When using ``subclass_of``, you may also want to use the other -custom argument for ``object()``: ``type``, which lets you set the type +When using *subclass_of*, you may also want to use the other +custom argument for ``object()``: *type*, which lets you set the type actually used for the parameter. For example, if you want to ensure -that the object is a subclass of ``PyUnicode_Type``, you probably want +that the object is a subclass of :c:var:`PyUnicode_Type`, you probably want to use the converter ``object(type='PyUnicodeObject *', subclass_of='&PyUnicode_Type')``. One possible problem with using Argument Clinic: it takes away some possible flexibility for the format units starting with ``e``. When writing a -``PyArg_Parse`` call by hand, you could theoretically decide at runtime what -encoding string to pass in to :c:func:`PyArg_ParseTuple`. But now this string must +:c:func:`!PyArg_Parse*` call by hand, you could theoretically decide at runtime what +encoding string to pass to that call. But now this string must be hard-coded at Argument-Clinic-preprocessing-time. This limitation is deliberate; it made supporting this format unit much easier, and may allow for future optimizations. This restriction doesn't seem unreasonable; CPython itself always passes in static hard-coded encoding strings for parameters whose format units start with ``e``. +.. _clinic-howto-default-values: .. _default_values: -Parameter default values ------------------------- +How to assign default values to parameter +----------------------------------------- Default values for parameters can be any of a number of values. At their simplest, they can be string, int, or float literals: @@ -955,7 +1063,7 @@ for simple expressions, documented in the following sections. The ``NULL`` default value --------------------------- +^^^^^^^^^^^^^^^^^^^^^^^^^^ For string and object parameters, you can set them to ``None`` to indicate that there's no default. However, that means the C variable will be @@ -964,8 +1072,25 @@ value called ``NULL`` for just this reason: from Python's perspective it behaves like a default value of ``None``, but the C variable is initialized with ``NULL``. -Expressions specified as default values ---------------------------------------- + +Symbolic default values +^^^^^^^^^^^^^^^^^^^^^^^ + +The default value you provide for a parameter can't be any arbitrary +expression. Currently the following are explicitly supported: + +* Numeric constants (integer and float) +* String constants +* ``True``, ``False``, and ``None`` +* Simple symbolic constants like :py:data:`sys.maxsize`, which must + start with the name of the module + +(In the future, this may need to get even more elaborate, +to allow full expressions like ``CONSTANT - 1``.) + + +Expressions as default values +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The default value for a parameter can be more than just a literal value. It can be an entire expression, using math operators and looking up attributes @@ -978,28 +1103,28 @@ Consider the following example: foo: Py_ssize_t = sys.maxsize - 1 -``sys.maxsize`` can have different values on different platforms. Therefore +:py:data:`sys.maxsize` can have different values on different platforms. Therefore Argument Clinic can't simply evaluate that expression locally and hard-code it in C. So it stores the default in such a way that it will get evaluated at runtime, when the user asks for the function's signature. What namespace is available when the expression is evaluated? It's evaluated in the context of the module the builtin came from. So, if your module has an -attribute called "``max_widgets``", you may simply use it: +attribute called :py:attr:`!max_widgets`, you may simply use it: .. code-block:: none foo: Py_ssize_t = max_widgets If the symbol isn't found in the current module, it fails over to looking in -``sys.modules``. That's how it can find ``sys.maxsize`` for example. (Since you -don't know in advance what modules the user will load into their interpreter, +:py:data:`sys.modules`. That's how it can find :py:data:`sys.maxsize` for example. +(Since you don't know in advance what modules the user will load into their interpreter, it's best to restrict yourself to modules that are preloaded by Python itself.) Evaluating default values only at runtime means Argument Clinic can't compute the correct equivalent C default value. So you need to tell it explicitly. When you use an expression, you must also specify the equivalent expression -in C, using the ``c_default`` parameter to the converter: +in C, using the *c_default* parameter to the converter: .. code-block:: none @@ -1021,23 +1146,41 @@ you're not permitted to use: * Tuple/list/set/dict literals. +.. _clinic-howto-return-converters: -Using a return converter ------------------------- +How to use return converters +---------------------------- -By default the impl function Argument Clinic generates for you returns ``PyObject *``. -But your C function often computes some C type, then converts it into the ``PyObject *`` +By default, the impl function Argument Clinic generates for you returns +:c:type:`PyObject * <PyObject>`. +But your C function often computes some C type, +then converts it into the :c:type:`!PyObject *` at the last moment. Argument Clinic handles converting your inputs from Python types into native C types—why not have it convert your return value from a native C type into a Python type too? That's what a "return converter" does. It changes your impl function to return some C type, then adds code to the generated (non-impl) function to handle converting -that value into the appropriate ``PyObject *``. +that value into the appropriate :c:type:`!PyObject *`. The syntax for return converters is similar to that of parameter converters. You specify the return converter like it was a return annotation on the -function itself. Return converters behave much the same as parameter converters; +function itself, using ``->`` notation. + +For example: + +.. code-block:: c + + /*[clinic input] + add -> int + + a: int + b: int + / + + [clinic start generated code]*/ + +Return converters behave much the same as parameter converters; they take arguments, the arguments are all keyword-only, and if you're not changing any of the default arguments you can omit the parentheses. @@ -1049,7 +1192,7 @@ indicate an error has occurred? Normally, a function returns a valid (non-``NUL pointer for success, and ``NULL`` for failure. But if you use an integer return converter, all integers are valid. How can Argument Clinic detect an error? Its solution: each return converter implicitly looks for a special value that indicates an error. If you return -that value, and an error has been set (``PyErr_Occurred()`` returns a true +that value, and an error has been set (c:func:`PyErr_Occurred` returns a true value), then the generated code will propagate the error. Otherwise it will encode the value you return like normal. @@ -1058,32 +1201,25 @@ Currently Argument Clinic supports only a few return converters: .. code-block:: none bool + double + float int - unsigned int long - unsigned int - size_t Py_ssize_t - float - double - DecodeFSDefault - -None of these take parameters. For the first three, return -1 to indicate -error. For ``DecodeFSDefault``, the return type is ``const char *``; return a ``NULL`` -pointer to indicate an error. + size_t + unsigned int + unsigned long -(There's also an experimental ``NoneType`` converter, which lets you -return ``Py_None`` on success or ``NULL`` on failure, without having -to increment the reference count on ``Py_None``. I'm not sure it adds -enough clarity to be worth using.) +None of these take parameters. +For all of these, return ``-1`` to indicate error. To see all the return converters Argument Clinic supports, along with their parameters (if any), just run ``Tools/clinic/clinic.py --converters`` for the full list. -Cloning existing functions --------------------------- +How to clone existing functions +------------------------------- If you have a number of functions that look similar, you may be able to use Clinic's "clone" feature. When you clone an existing function, @@ -1125,8 +1261,9 @@ then modifying it. Cloning is an all-or nothing proposition. Also, the function you are cloning from must have been previously defined in the current file. -Calling Python code -------------------- + +How to call Python code +----------------------- The rest of the advanced topics require you to write Python code which lives inside your C file and modifies Argument Clinic's @@ -1153,17 +1290,19 @@ variable to the C code:: /*[python checksum:...]*/ -Using a "self converter" ------------------------- +.. _clinic-howto-self-converter: + +How to use the "self converter" +------------------------------- Argument Clinic automatically adds a "self" parameter for you using a default converter. It automatically sets the ``type`` of this parameter to the "pointer to an instance" you specified when you declared the type. However, you can override Argument Clinic's converter and specify one yourself. -Just add your own ``self`` parameter as the first parameter in a +Just add your own *self* parameter as the first parameter in a block, and ensure that its converter is an instance of -``self_converter`` or a subclass thereof. +:class:`!self_converter` or a subclass thereof. What's the point? This lets you override the type of ``self``, or give it a different default name. @@ -1171,7 +1310,7 @@ or give it a different default name. How do you specify the custom type you want to cast ``self`` to? If you only have one or two functions with the same type for ``self``, you can directly use Argument Clinic's existing ``self`` converter, -passing in the type you want to use as the ``type`` parameter:: +passing in the type you want to use as the *type* parameter:: /*[clinic input] @@ -1186,7 +1325,7 @@ passing in the type you want to use as the ``type`` parameter:: On the other hand, if you have a lot of functions that will use the same type for ``self``, it's best to create your own converter, subclassing -``self_converter`` but overwriting the ``type`` member:: +:class:`!self_converter` but overwriting the :py:attr:`!type` member:: /*[python input] class PicklerObject_converter(self_converter): @@ -1205,8 +1344,8 @@ type for ``self``, it's best to create your own converter, subclassing [clinic start generated code]*/ -Using a "defining class" converter ----------------------------------- +How to use the "defining class" converter +----------------------------------------- Argument Clinic facilitates gaining access to the defining class of a method. This is useful for :ref:`heap type <heap-types>` methods that need to fetch @@ -1214,8 +1353,8 @@ module level state. Use :c:func:`PyType_FromModuleAndSpec` to associate a new heap type with a module. You can now use :c:func:`PyType_GetModuleState` on the defining class to fetch the module state, for example from a module method. -Example from ``Modules/zlibmodule.c``. First, ``defining_class`` is added to -the clinic input:: +Example from :source:`Modules/zlibmodule.c`. +First, ``defining_class`` is added to the clinic input:: /*[clinic input] zlib.Compress.compress @@ -1245,16 +1384,17 @@ module state:: Each method may only have one argument using this converter, and it must appear after ``self``, or, if ``self`` is not used, as the first argument. The argument will be of type ``PyTypeObject *``. The argument will not appear in the -``__text_signature__``. +:py:attr:`!__text_signature__`. -The ``defining_class`` converter is not compatible with ``__init__`` and ``__new__`` -methods, which cannot use the ``METH_METHOD`` convention. +The ``defining_class`` converter is not compatible with :py:meth:`!__init__` +and :py:meth:`!__new__` methods, which cannot use the :c:macro:`METH_METHOD` +convention. It is not possible to use ``defining_class`` with slot methods. In order to fetch the module state from such methods, use :c:func:`PyType_GetModuleByDef` to look up the module and then :c:func:`PyModule_GetState` to fetch the module state. Example from the ``setattro`` slot method in -``Modules/_threadmodule.c``:: +:source:`Modules/_threadmodule.c`:: static int local_setattro(localobject *self, PyObject *name, PyObject *v) @@ -1268,76 +1408,31 @@ state. Example from the ``setattro`` slot method in See also :pep:`573`. -Writing a custom converter --------------------------- +.. _clinic-howto-custom-converter: + +How to write a custom converter +------------------------------- -As we hinted at in the previous section... you can write your own converters! -A converter is simply a Python class that inherits from ``CConverter``. -The main purpose of a custom converter is if you have a parameter using -the ``O&`` format unit—parsing this parameter means calling +A converter is a Python class that inherits from :py:class:`CConverter`. +The main purpose of a custom converter, is for parameters parsed with +the ``O&`` format unit --- parsing such a parameter means calling a :c:func:`PyArg_ParseTuple` "converter function". -Your converter class should be named ``*something*_converter``. -If the name follows this convention, then your converter class -will be automatically registered with Argument Clinic; its name -will be the name of your class with the ``_converter`` suffix -stripped off. (This is accomplished with a metaclass.) - -You shouldn't subclass ``CConverter.__init__``. Instead, you should -write a ``converter_init()`` function. ``converter_init()`` -always accepts a ``self`` parameter; after that, all additional -parameters *must* be keyword-only. Any arguments passed in to -the converter in Argument Clinic will be passed along to your -``converter_init()``. - -There are some additional members of ``CConverter`` you may wish -to specify in your subclass. Here's the current list: - -``type`` - The C type to use for this variable. - ``type`` should be a Python string specifying the type, e.g. ``int``. - If this is a pointer type, the type string should end with ``' *'``. - -``default`` - The Python default value for this parameter, as a Python value. - Or the magic value ``unspecified`` if there is no default. - -``py_default`` - ``default`` as it should appear in Python code, - as a string. - Or ``None`` if there is no default. - -``c_default`` - ``default`` as it should appear in C code, - as a string. - Or ``None`` if there is no default. - -``c_ignored_default`` - The default value used to initialize the C variable when - there is no default, but not specifying a default may - result in an "uninitialized variable" warning. This can - easily happen when using option groups—although - properly written code will never actually use this value, - the variable does get passed in to the impl, and the - C compiler will complain about the "use" of the - uninitialized value. This value should always be a - non-empty string. - -``converter`` - The name of the C converter function, as a string. - -``impl_by_reference`` - A boolean value. If true, - Argument Clinic will add a ``&`` in front of the name of - the variable when passing it into the impl function. - -``parse_by_reference`` - A boolean value. If true, - Argument Clinic will add a ``&`` in front of the name of - the variable when passing it into :c:func:`PyArg_ParseTuple`. - - -Here's the simplest example of a custom converter, from ``Modules/zlibmodule.c``:: +Your converter class should be named :samp:`{ConverterName}_converter`. +By following this convention, your converter class will be automatically +registered with Argument Clinic, with its *converter name* being the name of +your converter class with the ``_converter`` suffix stripped off. + +Instead of subclassing :py:meth:`!CConverter.__init__`, +write a :py:meth:`!converter_init` method. +:py:meth:`!converter_init` always accepts a *self* parameter. +After *self*, all additional parameters **must** be keyword-only. +Any arguments passed to the converter in Argument Clinic +will be passed along to your :py:meth:`!converter_init` method. +See :py:class:`CConverter` for a list of members you may wish to specify in +your subclass. + +Here's the simplest example of a custom converter, from :source:`Modules/zlibmodule.c`:: /*[python input] @@ -1348,35 +1443,37 @@ Here's the simplest example of a custom converter, from ``Modules/zlibmodule.c`` [python start generated code]*/ /*[python end generated code: output=da39a3ee5e6b4b0d input=35521e4e733823c7]*/ -This block adds a converter to Argument Clinic named ``ssize_t``. Parameters -declared as ``ssize_t`` will be declared as type :c:type:`Py_ssize_t`, and will -be parsed by the ``'O&'`` format unit, which will call the -``ssize_t_converter`` converter function. ``ssize_t`` variables -automatically support default values. +This block adds a converter named ``ssize_t`` to Argument Clinic. +Parameters declared as ``ssize_t`` will be declared with type :c:type:`Py_ssize_t`, +and will be parsed by the ``'O&'`` format unit, +which will call the :c:func:`!ssize_t_converter` converter C function. +``ssize_t`` variables automatically support default values. More sophisticated custom converters can insert custom C code to handle initialization and cleanup. You can see more examples of custom converters in the CPython source tree; grep the C files for the string ``CConverter``. -Writing a custom return converter ---------------------------------- + +How to write a custom return converter +-------------------------------------- Writing a custom return converter is much like writing a custom converter. Except it's somewhat simpler, because return converters are themselves much simpler. -Return converters must subclass ``CReturnConverter``. +Return converters must subclass :py:class:`!CReturnConverter`. There are no examples yet of custom return converters, because they are not widely used yet. If you wish to -write your own return converter, please read ``Tools/clinic/clinic.py``, -specifically the implementation of ``CReturnConverter`` and +write your own return converter, please read :source:`Tools/clinic/clinic.py`, +specifically the implementation of :py:class:`!CReturnConverter` and all its subclasses. -METH_O and METH_NOARGS ----------------------------------------------- -To convert a function using ``METH_O``, make sure the function's +How to convert ``METH_O`` and ``METH_NOARGS`` functions +------------------------------------------------------- + +To convert a function using :c:macro:`METH_O`, make sure the function's single argument is using the ``object`` converter, and mark the arguments as positional-only:: @@ -1388,23 +1485,25 @@ arguments as positional-only:: [clinic start generated code]*/ -To convert a function using ``METH_NOARGS``, just don't specify +To convert a function using :c:macro:`METH_NOARGS`, just don't specify any arguments. You can still use a self converter, a return converter, and specify -a ``type`` argument to the object converter for ``METH_O``. +a *type* argument to the object converter for :c:macro:`METH_O`. -tp_new and tp_init functions ----------------------------------------------- -You can convert ``tp_new`` and ``tp_init`` functions. Just name -them ``__new__`` or ``__init__`` as appropriate. Notes: +How to convert ``tp_new`` and ``tp_init`` functions +--------------------------------------------------- + +You can convert :c:member:`~PyTypeObject.tp_new` and +:c:member:`~PyTypeObject.tp_init` functions. +Just name them ``__new__`` or ``__init__`` as appropriate. Notes: * The function name generated for ``__new__`` doesn't end in ``__new__`` like it would by default. It's just the name of the class, converted into a valid C identifier. -* No ``PyMethodDef`` ``#define`` is generated for these functions. +* No :c:type:`PyMethodDef` ``#define`` is generated for these functions. * ``__init__`` functions return ``int``, not ``PyObject *``. @@ -1416,8 +1515,9 @@ them ``__new__`` or ``__init__`` as appropriate. Notes: (If your function doesn't support keywords, the parsing function generated will throw an exception if it receives any.) -Changing and redirecting Clinic's output ----------------------------------------- + +How to change and redirect Clinic's output +------------------------------------------ It can be inconvenient to have Clinic's output interspersed with your conventional hand-edited C code. Luckily, Clinic is configurable: @@ -1438,7 +1538,7 @@ Let's start with defining some terminology: *field* A field, in this context, is a subsection of Clinic's output. - For example, the ``#define`` for the ``PyMethodDef`` structure + For example, the ``#define`` for the :c:type:`PyMethodDef` structure is a field, called ``methoddef_define``. Clinic has seven different fields it can output per function definition: @@ -1482,8 +1582,8 @@ Let's start with defining some terminology: The filename chosen for the file is ``{basename}.clinic{extension}``, where ``basename`` and ``extension`` were assigned the output from ``os.path.splitext()`` run on the current file. (Example: - the ``file`` destination for ``_pickle.c`` would be written to - ``_pickle.clinic.c``.) + the ``file`` destination for :file:`_pickle.c` would be written to + :file:`_pickle.clinic.c`.) **Important: When using a** ``file`` **destination, you** *must check in* **the generated file!** @@ -1699,8 +1799,8 @@ it in a Clinic block lets Clinic use its existing checksum functionality to ensu the file was not modified by hand before it gets overwritten. -The #ifdef trick ----------------------------------------------- +How to use the ``#ifdef`` trick +------------------------------- If you're converting a function that isn't available on all platforms, there's a trick you can use to make life a little easier. The existing @@ -1736,7 +1836,7 @@ like so:: } #endif /* HAVE_FUNCTIONNAME */ -Then, remove those three lines from the ``PyMethodDef`` structure, +Then, remove those three lines from the :c:type:`PyMethodDef` structure, replacing them with the macro Argument Clinic generated: .. code-block:: none @@ -1777,12 +1877,11 @@ This may mean that you get a complaint from Argument Clinic: When this happens, just open your file, find the ``dump buffer`` block that Argument Clinic added to your file (it'll be at the very bottom), then -move it above the ``PyMethodDef`` structure where that macro is used. +move it above the :c:type:`PyMethodDef` structure where that macro is used. - -Using Argument Clinic in Python files -------------------------------------- +How to use Argument Clinic in Python files +------------------------------------------ It's actually possible to use Argument Clinic to preprocess Python files. There's no point to using Argument Clinic blocks, of course, as the output diff --git a/Doc/howto/curses.rst b/Doc/howto/curses.rst index 83d80471..4828e2fa 100644 --- a/Doc/howto/curses.rst +++ b/Doc/howto/curses.rst @@ -4,6 +4,8 @@ Curses Programming with Python ********************************** +.. currentmodule:: curses + :Author: A.M. Kuchling, Eric S. Raymond :Release: 2.04 @@ -65,7 +67,7 @@ The Python module is a fairly simple wrapper over the C functions provided by curses; if you're already familiar with curses programming in C, it's really easy to transfer that knowledge to Python. The biggest difference is that the Python interface makes things simpler by merging different C functions such as -:c:func:`addstr`, :c:func:`mvaddstr`, and :c:func:`mvwaddstr` into a single +:c:func:`!addstr`, :c:func:`!mvaddstr`, and :c:func:`!mvwaddstr` into a single :meth:`~curses.window.addstr` method. You'll see this covered in more detail later. @@ -82,7 +84,7 @@ Before doing anything, curses must be initialized. This is done by calling the :func:`~curses.initscr` function, which will determine the terminal type, send any required setup codes to the terminal, and create various internal data structures. If successful, -:func:`initscr` returns a window object representing the entire +:func:`!initscr` returns a window object representing the entire screen; this is usually called ``stdscr`` after the name of the corresponding C variable. :: @@ -151,8 +153,8 @@ importing the :func:`curses.wrapper` function and using it like this:: The :func:`~curses.wrapper` function takes a callable object and does the initializations described above, also initializing colors if color -support is present. :func:`wrapper` then runs your provided callable. -Once the callable returns, :func:`wrapper` will restore the original +support is present. :func:`!wrapper` then runs your provided callable. +Once the callable returns, :func:`!wrapper` will restore the original state of the terminal. The callable is called inside a :keyword:`try`...\ :keyword:`except` that catches exceptions, restores the state of the terminal, and then re-raises the exception. Therefore @@ -200,7 +202,7 @@ This is because curses was originally written with slow 300-baud terminal connections in mind; with these terminals, minimizing the time required to redraw the screen was very important. Instead curses accumulates changes to the screen and displays them in the most -efficient manner when you call :meth:`refresh`. For example, if your +efficient manner when you call :meth:`!refresh`. For example, if your program displays some text in a window and then clears the window, there's no need to send the original text because they're never visible. @@ -210,7 +212,7 @@ really complicate programming with curses much. Most programs go into a flurry of activity, and then pause waiting for a keypress or some other action on the part of the user. All you have to do is to be sure that the screen has been redrawn before pausing to wait for user input, by first calling -``stdscr.refresh()`` or the :meth:`refresh` method of some other relevant +:meth:`!stdscr.refresh` or the :meth:`!refresh` method of some other relevant window. A pad is a special case of a window; it can be larger than the actual display @@ -234,7 +236,7 @@ displayed. :: # : filled with pad content. pad.refresh( 0,0, 5,5, 20,75) -The :meth:`refresh` call displays a section of the pad in the rectangle +The :meth:`!refresh` call displays a section of the pad in the rectangle extending from coordinate (5,5) to coordinate (20,75) on the screen; the upper left corner of the displayed section is coordinate (0,0) on the pad. Beyond that difference, pads are exactly like ordinary windows and support the same @@ -242,7 +244,7 @@ methods. If you have multiple windows and pads on screen there is a more efficient way to update the screen and prevent annoying screen flicker -as each part of the screen gets updated. :meth:`refresh` actually +as each part of the screen gets updated. :meth:`!refresh` actually does two things: 1) Calls the :meth:`~curses.window.noutrefresh` method of each window @@ -251,8 +253,8 @@ does two things: 2) Calls the function :func:`~curses.doupdate` function to change the physical screen to match the desired state recorded in the data structure. -Instead you can call :meth:`noutrefresh` on a number of windows to -update the data structure, and then call :func:`doupdate` to update +Instead you can call :meth:`!noutrefresh` on a number of windows to +update the data structure, and then call :func:`!doupdate` to update the screen. @@ -261,11 +263,11 @@ Displaying Text From a C programmer's point of view, curses may sometimes look like a twisty maze of functions, all subtly different. For example, -:c:func:`addstr` displays a string at the current cursor location in -the ``stdscr`` window, while :c:func:`mvaddstr` moves to a given y,x -coordinate first before displaying the string. :c:func:`waddstr` is just -like :c:func:`addstr`, but allows specifying a window to use instead of -using ``stdscr`` by default. :c:func:`mvwaddstr` allows specifying both +:c:func:`!addstr` displays a string at the current cursor location in +the ``stdscr`` window, while :c:func:`!mvaddstr` moves to a given y,x +coordinate first before displaying the string. :c:func:`!waddstr` is just +like :c:func:`!addstr`, but allows specifying a window to use instead of +using ``stdscr`` by default. :c:func:`!mvwaddstr` allows specifying both a window and a coordinate. Fortunately the Python interface hides all these details. ``stdscr`` @@ -298,7 +300,7 @@ the next subsection. The :meth:`~curses.window.addstr` method takes a Python string or bytestring as the value to be displayed. The contents of bytestrings are sent to the terminal as-is. Strings are encoded to bytes using -the value of the window's :attr:`encoding` attribute; this defaults to +the value of the window's :attr:`~window.encoding` attribute; this defaults to the default system encoding as returned by :func:`locale.getencoding`. The :meth:`~curses.window.addch` methods take a character, which can be @@ -444,15 +446,15 @@ There are two methods for getting input from a window: It's possible to not wait for the user using the :meth:`~curses.window.nodelay` window method. After ``nodelay(True)``, -:meth:`getch` and :meth:`getkey` for the window become -non-blocking. To signal that no input is ready, :meth:`getch` returns -``curses.ERR`` (a value of -1) and :meth:`getkey` raises an exception. +:meth:`!getch` and :meth:`!getkey` for the window become +non-blocking. To signal that no input is ready, :meth:`!getch` returns +``curses.ERR`` (a value of -1) and :meth:`!getkey` raises an exception. There's also a :func:`~curses.halfdelay` function, which can be used to (in -effect) set a timer on each :meth:`getch`; if no input becomes +effect) set a timer on each :meth:`!getch`; if no input becomes available within a specified delay (measured in tenths of a second), curses raises an exception. -The :meth:`getch` method returns an integer; if it's between 0 and 255, it +The :meth:`!getch` method returns an integer; if it's between 0 and 255, it represents the ASCII code of the key pressed. Values greater than 255 are special keys such as Page Up, Home, or the cursor keys. You can compare the value returned to constants such as :const:`curses.KEY_PPAGE`, @@ -525,7 +527,7 @@ If you're in doubt about the detailed behavior of the curses functions, consult the manual pages for your curses implementation, whether it's ncurses or a proprietary Unix vendor's. The manual pages will document any quirks, and provide complete lists of all the -functions, attributes, and :const:`ACS_\*` characters available to +functions, attributes, and :ref:`ACS_\* <curses-acs-codes>` characters available to you. Because the curses API is so large, some functions aren't supported in diff --git a/Doc/howto/descriptor.rst b/Doc/howto/descriptor.rst index 74710d9b..1d9424cb 100644 --- a/Doc/howto/descriptor.rst +++ b/Doc/howto/descriptor.rst @@ -779,8 +779,8 @@ by a search through the class's :term:`method resolution order`. If a descriptor is found, it is invoked with ``desc.__get__(None, A)``. -The full C implementation can be found in :c:func:`type_getattro()` and -:c:func:`_PyType_Lookup()` in :source:`Objects/typeobject.c`. +The full C implementation can be found in :c:func:`!type_getattro` and +:c:func:`!_PyType_Lookup` in :source:`Objects/typeobject.c`. Invocation from super @@ -794,7 +794,7 @@ for the base class ``B`` immediately following ``A`` and then returns ``B.__dict__['m'].__get__(obj, A)``. If not a descriptor, ``m`` is returned unchanged. -The full C implementation can be found in :c:func:`super_getattro()` in +The full C implementation can be found in :c:func:`!super_getattro` in :source:`Objects/typeobject.c`. A pure Python equivalent can be found in `Guido's Tutorial <https://www.python.org/download/releases/2.2.3/descrintro/#cooperation>`_. @@ -836,8 +836,8 @@ and if they define :meth:`__set_name__`, that method is called with two arguments. The *owner* is the class where the descriptor is used, and the *name* is the class variable the descriptor was assigned to. -The implementation details are in :c:func:`type_new()` and -:c:func:`set_names()` in :source:`Objects/typeobject.c`. +The implementation details are in :c:func:`!type_new` and +:c:func:`!set_names` in :source:`Objects/typeobject.c`. Since the update logic is in :meth:`type.__new__`, notifications only take place at the time of class creation. If descriptors are added to the class @@ -1273,11 +1273,14 @@ Using the non-data descriptor protocol, a pure Python version of .. testcode:: + import functools + class StaticMethod: "Emulate PyStaticMethod_Type() in Objects/funcobject.c" def __init__(self, f): self.f = f + functools.update_wrapper(self, f) def __get__(self, obj, objtype=None): return self.f @@ -1285,13 +1288,19 @@ Using the non-data descriptor protocol, a pure Python version of def __call__(self, *args, **kwds): return self.f(*args, **kwds) +The :func:`functools.update_wrapper` call adds a ``__wrapped__`` attribute +that refers to the underlying function. Also it carries forward +the attributes necessary to make the wrapper look like the wrapped +function: ``__name__``, ``__qualname__``, ``__doc__``, and ``__annotations__``. + .. testcode:: :hide: class E_sim: @StaticMethod - def f(x): - return x * 10 + def f(x: int) -> str: + "Simple function example" + return "!" * x wrapped_ord = StaticMethod(ord) @@ -1299,11 +1308,51 @@ Using the non-data descriptor protocol, a pure Python version of :hide: >>> E_sim.f(3) - 30 + '!!!' >>> E_sim().f(3) - 30 + '!!!' + + >>> sm = vars(E_sim)['f'] + >>> type(sm).__name__ + 'StaticMethod' + >>> f = E_sim.f + >>> type(f).__name__ + 'function' + >>> sm.__name__ + 'f' + >>> f.__name__ + 'f' + >>> sm.__qualname__ + 'E_sim.f' + >>> f.__qualname__ + 'E_sim.f' + >>> sm.__doc__ + 'Simple function example' + >>> f.__doc__ + 'Simple function example' + >>> sm.__annotations__ + {'x': <class 'int'>, 'return': <class 'str'>} + >>> f.__annotations__ + {'x': <class 'int'>, 'return': <class 'str'>} + >>> sm.__module__ == f.__module__ + True + >>> sm(3) + '!!!' + >>> f(3) + '!!!' + >>> wrapped_ord('A') 65 + >>> wrapped_ord.__module__ == ord.__module__ + True + >>> wrapped_ord.__wrapped__ == ord + True + >>> wrapped_ord.__name__ == ord.__name__ + True + >>> wrapped_ord.__qualname__ == ord.__qualname__ + True + >>> wrapped_ord.__doc__ == ord.__doc__ + True Class methods @@ -1359,11 +1408,14 @@ Using the non-data descriptor protocol, a pure Python version of .. testcode:: + import functools + class ClassMethod: "Emulate PyClassMethod_Type() in Objects/funcobject.c" def __init__(self, f): self.f = f + functools.update_wrapper(self, f) def __get__(self, obj, cls=None): if cls is None: @@ -1380,8 +1432,9 @@ Using the non-data descriptor protocol, a pure Python version of # Verify the emulation works class T: @ClassMethod - def cm(cls, x, y): - return (cls, x, y) + def cm(cls, x: int, y: str) -> tuple[str, int, str]: + "Class method that returns a tuple" + return (cls.__name__, x, y) @ClassMethod @property @@ -1393,17 +1446,40 @@ Using the non-data descriptor protocol, a pure Python version of :hide: >>> T.cm(11, 22) - (<class 'T'>, 11, 22) + ('T', 11, 22) # Also call it from an instance >>> t = T() >>> t.cm(11, 22) - (<class 'T'>, 11, 22) + ('T', 11, 22) # Check the alternate path for chained descriptors >>> T.__doc__ "A doc for 'T'" + # Verify that T uses our emulation + >>> type(vars(T)['cm']).__name__ + 'ClassMethod' + + # Verify that update_wrapper() correctly copied attributes + >>> T.cm.__name__ + 'cm' + >>> T.cm.__qualname__ + 'T.cm' + >>> T.cm.__doc__ + 'Class method that returns a tuple' + >>> T.cm.__annotations__ + {'x': <class 'int'>, 'y': <class 'str'>, 'return': tuple[str, int, str]} + + # Verify that __wrapped__ was added and works correctly + >>> f = vars(T)['cm'].__wrapped__ + >>> type(f).__name__ + 'function' + >>> f.__name__ + 'cm' + >>> f(T, 11, 22) + ('T', 11, 22) + The code path for ``hasattr(type(self.f), '__get__')`` was added in Python 3.9 and makes it possible for :func:`classmethod` to support @@ -1423,6 +1499,12 @@ chained together. In Python 3.11, this functionality was deprecated. >>> G.__doc__ "A doc for 'G'" +The :func:`functools.update_wrapper` call in ``ClassMethod`` adds a +``__wrapped__`` attribute that refers to the underlying function. Also +it carries forward the attributes necessary to make the wrapper look +like the wrapped function: ``__name__``, ``__qualname__``, ``__doc__``, +and ``__annotations__``. + Member objects and __slots__ ---------------------------- diff --git a/Doc/howto/enum.rst b/Doc/howto/enum.rst index 990d006b..28749754 100644 --- a/Doc/howto/enum.rst +++ b/Doc/howto/enum.rst @@ -36,8 +36,10 @@ inherits from :class:`Enum` itself. .. note:: Case of Enum Members - Because Enums are used to represent constants we recommend using - UPPER_CASE names for members, and will be using that style in our examples. + Because Enums are used to represent constants, and to help avoid issues + with name clashes between mixin-class methods/attributes and enum names, + we strongly recommend using UPPER_CASE names for members, and will be using + that style in our examples. Depending on the nature of the enum a member's value may or may not be important, but either way that value can be used to get the corresponding @@ -158,6 +160,7 @@ And a function to display the chores for a given day:: ... for chore, days in chores.items(): ... if day in days: ... print(chore) + ... >>> show_chores(chores_for_ethan, Weekday.SATURDAY) answer SO questions @@ -283,6 +286,7 @@ The values are chosen by :func:`_generate_next_value_`, which can be overridden:: >>> class AutoName(Enum): + ... @staticmethod ... def _generate_next_value_(name, start, count, last_values): ... return name ... @@ -371,6 +375,11 @@ below):: >>> Color.BLUE == 2 False +.. warning:: + + It is possible to reload modules -- if a reloaded module contains + enums, they will be recreated, and the new members may not + compare identical/equal to the original members. Allowed members and attributes of enumerations ---------------------------------------------- @@ -417,10 +426,17 @@ enumeration, with the exception of special methods (:meth:`__str__`, :meth:`__add__`, etc.), descriptors (methods are also descriptors), and variable names listed in :attr:`_ignore_`. -Note: if your enumeration defines :meth:`__new__` and/or :meth:`__init__` then +Note: if your enumeration defines :meth:`__new__` and/or :meth:`__init__`, any value(s) given to the enum member will be passed into those methods. See `Planet`_ for an example. +.. note:: + + The :meth:`__new__` method, if defined, is used during creation of the Enum + members; it is then replaced by Enum's :meth:`__new__` which is used after + class creation for lookup of existing members. See :ref:`new-vs-init` for + more details. + Restricted Enum subclassing --------------------------- @@ -459,6 +475,35 @@ sense to allow sharing some common behavior between a group of enumerations. (See `OrderedEnum`_ for an example.) +.. _enum-dataclass-support: + +Dataclass support +----------------- + +When inheriting from a :class:`~dataclasses.dataclass`, +the :meth:`~Enum.__repr__` omits the inherited class' name. For example:: + + >>> @dataclass + ... class CreatureDataMixin: + ... size: str + ... legs: int + ... tail: bool = field(repr=False, default=True) + ... + >>> class Creature(CreatureDataMixin, Enum): + ... BEETLE = 'small', 6 + ... DOG = 'medium', 4 + ... + >>> Creature.DOG + <Creature.DOG: size='medium', legs=4> + +Use the :func:`!dataclass` argument ``repr=False`` +to use the standard :func:`repr`. + +.. versionchanged:: 3.12 + Only the dataclass fields are shown in the value area, not the dataclass' + name. + + Pickling -------- @@ -479,7 +524,16 @@ from that module. nested in other classes. It is possible to modify how enum members are pickled/unpickled by defining -:meth:`__reduce_ex__` in the enumeration class. +:meth:`__reduce_ex__` in the enumeration class. The default method is by-value, +but enums with complicated values may want to use by-name:: + + >>> class MyEnum(Enum): + ... __reduce_ex__ = enum.pickle_by_enum_name + +.. note:: + + Using by-name for flags is not recommended, as unnamed aliases will + not unpickle. Functional API @@ -687,6 +741,7 @@ It is also possible to name the combinations:: ... W = 2 ... X = 1 ... RWX = 7 + ... >>> Perm.RWX <Perm.RWX: 7> >>> ~Perm.RWX @@ -832,19 +887,23 @@ Some rules: 4. When another data type is mixed in, the :attr:`value` attribute is *not the same* as the enum member itself, although it is equivalent and will compare equal. -5. %-style formatting: ``%s`` and ``%r`` call the :class:`Enum` class's +5. A ``data type`` is a mixin that defines :meth:`__new__`, or a + :class:`~dataclasses.dataclass` +6. %-style formatting: ``%s`` and ``%r`` call the :class:`Enum` class's :meth:`__str__` and :meth:`__repr__` respectively; other codes (such as ``%i`` or ``%h`` for IntEnum) treat the enum member as its mixed-in type. -6. :ref:`Formatted string literals <f-strings>`, :meth:`str.format`, +7. :ref:`Formatted string literals <f-strings>`, :meth:`str.format`, and :func:`format` will use the enum's :meth:`__str__` method. .. note:: Because :class:`IntEnum`, :class:`IntFlag`, and :class:`StrEnum` are designed to be drop-in replacements for existing constants, their - :meth:`__str__` method has been reset to their data types + :meth:`__str__` method has been reset to their data types' :meth:`__str__` method. +.. _new-vs-init: + When to use :meth:`__new__` vs. :meth:`__init__` ------------------------------------------------ @@ -877,6 +936,11 @@ want one of them to be the value:: >>> print(Coordinate(3)) Coordinate.VY +.. warning:: + + *Do not* call ``super().__new__()``, as the lookup-only ``__new__`` is the one + that is found; instead, use the data type directly. + Finer Points ^^^^^^^^^^^^ @@ -955,23 +1019,13 @@ but remain normal attributes. """""""""""""""""""" Enum members are instances of their enum class, and are normally accessed as -``EnumClass.member``. In Python versions ``3.5`` to ``3.10`` you could access -members from other members -- this practice was discouraged, and in ``3.11`` -:class:`Enum` returns to not allowing it:: - - >>> class FieldTypes(Enum): - ... name = 0 - ... value = 1 - ... size = 2 - ... - >>> FieldTypes.value.size - Traceback (most recent call last): - ... - AttributeError: <enum 'FieldTypes'> member has no attribute 'size' - +``EnumClass.member``. In certain situations, such as writing custom enum +behavior, being able to access one member directly from another is useful, +and is supported; however, in order to avoid name clashes between member names +and attributes/methods from mixed-in classes, upper-case names are strongly +recommended. .. versionchanged:: 3.5 -.. versionchanged:: 3.11 Creating members that are mixed with other data types @@ -1313,6 +1367,13 @@ to handle any extra arguments:: members; it is then replaced by Enum's :meth:`__new__` which is used after class creation for lookup of existing members. +.. warning:: + + *Do not* call ``super().__new__()``, as the lookup-only ``__new__`` is the one + that is found; instead, use the data type directly -- e.g.:: + + obj = int.__new__(cls, value) + OrderedEnum ^^^^^^^^^^^ diff --git a/Doc/howto/functional.rst b/Doc/howto/functional.rst index e68bc2eb..b0f9d22d 100644 --- a/Doc/howto/functional.rst +++ b/Doc/howto/functional.rst @@ -1072,8 +1072,8 @@ write the obvious :keyword:`for` loop:: A related function is :func:`itertools.accumulate(iterable, func=operator.add) <itertools.accumulate>`. It performs the same calculation, but instead of -returning only the final result, :func:`accumulate` returns an iterator that -also yields each partial result:: +returning only the final result, :func:`~itertools.accumulate` returns an iterator +that also yields each partial result:: itertools.accumulate([1, 2, 3, 4, 5]) => 1, 3, 6, 10, 15 @@ -1208,8 +1208,8 @@ General ------- **Structure and Interpretation of Computer Programs**, by Harold Abelson and -Gerald Jay Sussman with Julie Sussman. Full text at -https://mitpress.mit.edu/sicp/. In this classic textbook of computer science, +Gerald Jay Sussman with Julie Sussman. The book can be found at +https://mitpress.mit.edu/sicp. In this classic textbook of computer science, chapters 2 and 3 discuss the use of sequences and streams to organize the data flow inside a program. The book uses Scheme for its examples, but many of the design approaches described in these chapters are applicable to functional-style @@ -1223,6 +1223,8 @@ describing functional programming. https://en.wikipedia.org/wiki/Coroutine: Entry for coroutines. +https://en.wikipedia.org/wiki/Partial_application: Entry for the concept of partial function application. + https://en.wikipedia.org/wiki/Currying: Entry for the concept of currying. Python-specific diff --git a/Doc/howto/index.rst b/Doc/howto/index.rst index 8a378e66..f521276a 100644 --- a/Doc/howto/index.rst +++ b/Doc/howto/index.rst @@ -30,6 +30,7 @@ Currently, the HOWTOs are: ipaddress.rst clinic.rst instrumentation.rst + perf_profiling.rst annotations.rst isolating-extensions.rst diff --git a/Doc/howto/instrumentation.rst b/Doc/howto/instrumentation.rst index 4ce15c69..875f846a 100644 --- a/Doc/howto/instrumentation.rst +++ b/Doc/howto/instrumentation.rst @@ -292,11 +292,11 @@ Available static markers .. object:: function__return(str filename, str funcname, int lineno) - This marker is the converse of :c:func:`function__entry`, and indicates that + This marker is the converse of :c:func:`!function__entry`, and indicates that execution of a Python function has ended (either via ``return``, or via an exception). It is only triggered for pure-Python (bytecode) functions. - The arguments are the same as for :c:func:`function__entry` + The arguments are the same as for :c:func:`!function__entry` .. object:: line(str filename, str funcname, int lineno) @@ -304,7 +304,7 @@ Available static markers the equivalent of line-by-line tracing with a Python profiler. It is not triggered within C functions. - The arguments are the same as for :c:func:`function__entry`. + The arguments are the same as for :c:func:`!function__entry`. .. object:: gc__start(int generation) diff --git a/Doc/howto/isolating-extensions.rst b/Doc/howto/isolating-extensions.rst index 2eddb582..8f3787f2 100644 --- a/Doc/howto/isolating-extensions.rst +++ b/Doc/howto/isolating-extensions.rst @@ -1,5 +1,7 @@ .. highlight:: c +.. _isolating-extensions-howto: + *************************** Isolating Extension Modules *************************** @@ -62,7 +64,7 @@ Enter Per-Module State Instead of focusing on per-interpreter state, Python's C API is evolving to better support the more granular *per-module* state. -This means that C-level data is be attached to a *module object*. +This means that C-level data should be attached to a *module object*. Each interpreter creates its own module object, keeping the data separate. For testing the isolation, multiple module objects corresponding to a single extension can even be loaded in a single interpreter. @@ -298,10 +300,10 @@ Watch out for the following two points in particular (but note that this is not a comprehensive list): * Unlike static types, heap type objects are mutable by default. - Use the :c:data:`Py_TPFLAGS_IMMUTABLETYPE` flag to prevent mutability. + Use the :c:macro:`Py_TPFLAGS_IMMUTABLETYPE` flag to prevent mutability. * Heap types inherit :c:member:`~PyTypeObject.tp_new` by default, so it may become possible to instantiate them from Python code. - You can prevent this with the :c:data:`Py_TPFLAGS_DISALLOW_INSTANTIATION` flag. + You can prevent this with the :c:macro:`Py_TPFLAGS_DISALLOW_INSTANTIATION` flag. Defining Heap Types @@ -333,12 +335,12 @@ To avoid memory leaks, instances of heap types must implement the garbage collection protocol. That is, heap types should: -- Have the :c:data:`Py_TPFLAGS_HAVE_GC` flag. +- Have the :c:macro:`Py_TPFLAGS_HAVE_GC` flag. - Define a traverse function using ``Py_tp_traverse``, which visits the type (e.g. using :c:expr:`Py_VISIT(Py_TYPE(self))`). Please refer to the :ref:`the documentation <type-structs>` of -:c:data:`Py_TPFLAGS_HAVE_GC` and :c:member:`~PyTypeObject.tp_traverse` +:c:macro:`Py_TPFLAGS_HAVE_GC` and :c:member:`~PyTypeObject.tp_traverse` for additional considerations. If your traverse function delegates to the ``tp_traverse`` of its base class @@ -372,7 +374,7 @@ To save a some tedious error-handling boilerplate code, you can combine these two steps with :c:func:`PyType_GetModuleState`, resulting in:: my_struct *state = (my_struct*)PyType_GetModuleState(type); - if (state === NULL) { + if (state == NULL) { return NULL; } @@ -411,7 +413,7 @@ that subclass, which may be defined in different module than yours. pass For a method to get its "defining class", it must use the -:data:`METH_METHOD | METH_FASTCALL | METH_KEYWORDS` +:ref:`METH_METHOD | METH_FASTCALL | METH_KEYWORDS <METH_METHOD-METH_FASTCALL-METH_KEYWORDS>` :c:type:`calling convention <PyMethodDef>` and the corresponding :c:type:`PyCMethod` signature:: @@ -435,7 +437,7 @@ For example:: PyObject *kwnames) { my_struct *state = (my_struct*)PyType_GetModuleState(defining_class); - if (state === NULL) { + if (state == NULL) { return NULL; } ... // rest of logic @@ -461,13 +463,13 @@ Module State Access from Slot Methods, Getters and Setters .. After adding to limited API: - If you use the :ref:`limited API <stable>, + If you use the :ref:`limited API <limited-c-api>`, you must update ``Py_LIMITED_API`` to ``0x030b0000``, losing ABI compatibility with earlier versions. Slot methods—the fast C equivalents for special methods, such as :c:member:`~PyNumberMethods.nb_add` for :py:attr:`~object.__add__` or -:c:member:`~PyType.tp_new` for initialization—have a very simple API that +:c:member:`~PyTypeObject.tp_new` for initialization—have a very simple API that doesn't allow passing in the defining class, unlike with :c:type:`PyCMethod`. The same goes for getters and setters defined with :c:type:`PyGetSetDef`. @@ -479,18 +481,18 @@ to get the state:: PyObject *module = PyType_GetModuleByDef(Py_TYPE(self), &module_def); my_struct *state = (my_struct*)PyModule_GetState(module); - if (state === NULL) { + if (state == NULL) { return NULL; } -``PyType_GetModuleByDef`` works by searching the +:c:func:`!PyType_GetModuleByDef` works by searching the :term:`method resolution order` (i.e. all superclasses) for the first superclass that has a corresponding module. .. note:: In very exotic cases (inheritance chains spanning multiple modules - created from the same definition), ``PyType_GetModuleByDef`` might not + created from the same definition), :c:func:`!PyType_GetModuleByDef` might not return the module of the true defining class. However, it will always return a module with the same definition, ensuring a compatible C memory layout. diff --git a/Doc/howto/logging-cookbook.rst b/Doc/howto/logging-cookbook.rst index 97e990d0..588f5a0a 100644 --- a/Doc/howto/logging-cookbook.rst +++ b/Doc/howto/logging-cookbook.rst @@ -340,10 +340,12 @@ adding a ``filters`` section parallel to ``formatters`` and ``handlers``: .. code-block:: json - "filters": { - "warnings_and_below": { - "()" : "__main__.filter_maker", - "level": "WARNING" + { + "filters": { + "warnings_and_below": { + "()" : "__main__.filter_maker", + "level": "WARNING" + } } } @@ -351,12 +353,14 @@ and changing the section on the ``stdout`` handler to add it: .. code-block:: json - "stdout": { - "class": "logging.StreamHandler", - "level": "INFO", - "formatter": "simple", - "stream": "ext://sys.stdout", - "filters": ["warnings_and_below"] + { + "stdout": { + "class": "logging.StreamHandler", + "level": "INFO", + "formatter": "simple", + "stream": "ext://sys.stdout", + "filters": ["warnings_and_below"] + } } A filter is just a function, so we can define the ``filter_maker`` (a factory @@ -757,7 +761,7 @@ printed on the console; on the server side, you should see something like: Note that there are some security issues with pickle in some scenarios. If these affect you, you can use an alternative serialization scheme by overriding -the :meth:`~handlers.SocketHandler.makePickle` method and implementing your +the :meth:`~SocketHandler.makePickle` method and implementing your alternative there, as well as adapting the above script to use your alternative serialization. @@ -831,6 +835,8 @@ To test these files, do the following in a POSIX environment: You may need to tweak the configuration files in the unlikely event that the configured ports clash with something else in your test environment. +.. currentmodule:: logging + .. _context-info: Adding contextual information to your logging output @@ -1542,7 +1548,7 @@ Sometimes you want to let a log file grow to a certain size, then open a new file and log to that. You may want to keep a certain number of these files, and when that many files have been created, rotate the files so that the number of files and the size of the files both remain bounded. For this usage pattern, the -logging package provides a :class:`~handlers.RotatingFileHandler`:: +logging package provides a :class:`RotatingFileHandler`:: import glob import logging @@ -1590,6 +1596,8 @@ and each time it reaches the size limit it is renamed with the suffix Obviously this example sets the log length much too small as an extreme example. You would want to set *maxBytes* to an appropriate value. +.. currentmodule:: logging + .. _format-styles: Use of alternative formatting styles @@ -1720,7 +1728,7 @@ when (and if) the logged message is actually about to be output to a log by a handler. So the only slightly unusual thing which might trip you up is that the parentheses go around the format string and the arguments, not just the format string. That's because the __ notation is just syntax sugar for a constructor -call to one of the XXXMessage classes. +call to one of the :samp:`{XXX}Message` classes. If you prefer, you can use a :class:`LoggerAdapter` to achieve a similar effect to the above, as in the following example:: @@ -1836,6 +1844,7 @@ However, it should be borne in mind that each link in the chain adds run-time overhead to all logging operations, and the technique should only be used when the use of a :class:`Filter` does not provide the desired result. +.. currentmodule:: logging.handlers .. _zeromq-handlers: @@ -1913,6 +1922,8 @@ of queues, for example a ZeroMQ 'subscribe' socket. Here's an example:: :ref:`A more advanced logging tutorial <logging-advanced-tutorial>` +.. currentmodule:: logging + An example dictionary-based configuration ----------------------------------------- @@ -2538,7 +2549,7 @@ should be logged, or the ``extra`` keyword parameter to indicate additional contextual information to be added to the log). So you cannot directly make logging calls using :meth:`str.format` or :class:`string.Template` syntax, because internally the logging package uses %-formatting to merge the format -string and the variable arguments. There would no changing this while preserving +string and the variable arguments. There would be no changing this while preserving backward compatibility, since all logging calls which are out there in existing code will be using %-format strings. @@ -2633,7 +2644,7 @@ when (and if) the logged message is actually about to be output to a log by a handler. So the only slightly unusual thing which might trip you up is that the parentheses go around the format string and the arguments, not just the format string. That’s because the __ notation is just syntax sugar for a constructor -call to one of the ``XXXMessage`` classes shown above. +call to one of the :samp:`{XXX}Message` classes shown above. .. _filters-dictconfig: @@ -3628,7 +3639,7 @@ refer to the comments in the code snippet for more detailed information. Logging to syslog with RFC5424 support -------------------------------------- -Although :rfc:`5424` dates from 2009, most syslog servers are configured by detault to +Although :rfc:`5424` dates from 2009, most syslog servers are configured by default to use the older :rfc:`3164`, which hails from 2001. When ``logging`` was added to Python in 2003, it supported the earlier (and only existing) protocol at the time. Since RFC5424 came out, as there has not been widespread deployment of it in syslog @@ -3819,7 +3830,7 @@ then running the script results in WARNING:demo:division by zero As you can see, this output isn't ideal. That's because the underlying code -which writes to ``sys.stderr`` makes mutiple writes, each of which results in a +which writes to ``sys.stderr`` makes multiple writes, each of which results in a separate logged line (for example, the last three lines above). To get around this problem, you need to buffer things and only output log lines when newlines are seen. Let's use a slghtly better implementation of ``LoggerWriter``: @@ -3914,8 +3925,8 @@ that in other languages such as Java and C#, loggers are often static class attributes. However, this pattern doesn't make sense in Python, where the module (and not the class) is the unit of software decomposition. -Adding handlers other than :class:`NullHandler` to a logger in a library -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Adding handlers other than :class:`~logging.NullHandler` to a logger in a library +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Configuring logging by adding handlers, formatters and filters is the responsibility of the application developer, not the library developer. If you diff --git a/Doc/howto/logging.rst b/Doc/howto/logging.rst index 87065273..7330cf67 100644 --- a/Doc/howto/logging.rst +++ b/Doc/howto/logging.rst @@ -8,6 +8,9 @@ Logging HOWTO .. currentmodule:: logging +This page contains tutorial information. For links to reference information and a +logging cookbook, please see :ref:`tutorial-ref-links`. + Basic Logging Tutorial ---------------------- @@ -336,7 +339,7 @@ favourite beverage and carry on. If your logging needs are simple, then use the above examples to incorporate logging into your own scripts, and if you run into problems or don't understand something, please post a question on the comp.lang.python Usenet -group (available at https://groups.google.com/forum/#!forum/comp.lang.python) and you +group (available at https://groups.google.com/g/comp.lang.python) and you should receive help before too long. Still here? You can carry on reading the next few sections, which provide a @@ -415,6 +418,7 @@ The flow of log event information in loggers and handlers is illustrated in the following diagram. .. image:: logging_flow.png + :class: invert-in-dark-mode Loggers ^^^^^^^ @@ -975,7 +979,7 @@ provided: #. :class:`NullHandler` instances do nothing with error messages. They are used by library developers who want to use logging, but want to avoid the 'No - handlers could be found for logger XXX' message which can be displayed if + handlers could be found for logger *XXX*' message which can be displayed if the library user has not configured logging. See :ref:`library-config` for more information. @@ -1101,11 +1105,19 @@ need: | Current process name when using ``multiprocessing`` | Set ``logging.logMultiprocessing`` to ``False``. | | to manage multiple processes. | | +-----------------------------------------------------+---------------------------------------------------+ +| Current :class:`asyncio.Task` name when using | Set ``logging.logAsyncioTasks`` to ``False``. | +| ``asyncio``. | | ++-----------------------------------------------------+---------------------------------------------------+ Also note that the core logging module only includes the basic handlers. If you don't import :mod:`logging.handlers` and :mod:`logging.config`, they won't take up any memory. +.. _tutorial-ref-links: + +Other resources +--------------- + .. seealso:: Module :mod:`logging` diff --git a/Doc/howto/perf_profiling.rst b/Doc/howto/perf_profiling.rst new file mode 100644 index 00000000..61812c19 --- /dev/null +++ b/Doc/howto/perf_profiling.rst @@ -0,0 +1,208 @@ +.. highlight:: shell-session + +.. _perf_profiling: + +============================================== +Python support for the Linux ``perf`` profiler +============================================== + +:author: Pablo Galindo + +`The Linux perf profiler <https://perf.wiki.kernel.org>`_ +is a very powerful tool that allows you to profile and obtain +information about the performance of your application. +``perf`` also has a very vibrant ecosystem of tools +that aid with the analysis of the data that it produces. + +The main problem with using the ``perf`` profiler with Python applications is that +``perf`` only gets information about native symbols, that is, the names of +functions and procedures written in C. This means that the names and file names +of Python functions in your code will not appear in the output of ``perf``. + +Since Python 3.12, the interpreter can run in a special mode that allows Python +functions to appear in the output of the ``perf`` profiler. When this mode is +enabled, the interpreter will interpose a small piece of code compiled on the +fly before the execution of every Python function and it will teach ``perf`` the +relationship between this piece of code and the associated Python function using +:doc:`perf map files <../c-api/perfmaps>`. + +.. note:: + + Support for the ``perf`` profiler is currently only available for Linux on + select architectures. Check the output of the ``configure`` build step or + check the output of ``python -m sysconfig | grep HAVE_PERF_TRAMPOLINE`` + to see if your system is supported. + +For example, consider the following script: + +.. code-block:: python + + def foo(n): + result = 0 + for _ in range(n): + result += 1 + return result + + def bar(n): + foo(n) + + def baz(n): + bar(n) + + if __name__ == "__main__": + baz(1000000) + +We can run ``perf`` to sample CPU stack traces at 9999 hertz:: + + $ perf record -F 9999 -g -o perf.data python my_script.py + +Then we can use ``perf report`` to analyze the data: + +.. code-block:: shell-session + + $ perf report --stdio -n -g + + # Children Self Samples Command Shared Object Symbol + # ........ ........ ............ .......... .................. .......................................... + # + 91.08% 0.00% 0 python.exe python.exe [.] _start + | + ---_start + | + --90.71%--__libc_start_main + Py_BytesMain + | + |--56.88%--pymain_run_python.constprop.0 + | | + | |--56.13%--_PyRun_AnyFileObject + | | _PyRun_SimpleFileObject + | | | + | | |--55.02%--run_mod + | | | | + | | | --54.65%--PyEval_EvalCode + | | | _PyEval_EvalFrameDefault + | | | PyObject_Vectorcall + | | | _PyEval_Vector + | | | _PyEval_EvalFrameDefault + | | | PyObject_Vectorcall + | | | _PyEval_Vector + | | | _PyEval_EvalFrameDefault + | | | PyObject_Vectorcall + | | | _PyEval_Vector + | | | | + | | | |--51.67%--_PyEval_EvalFrameDefault + | | | | | + | | | | |--11.52%--_PyLong_Add + | | | | | | + | | | | | |--2.97%--_PyObject_Malloc + ... + +As you can see, the Python functions are not shown in the output, only ``_Py_Eval_EvalFrameDefault`` +(the function that evaluates the Python bytecode) shows up. Unfortunately that's not very useful because all Python +functions use the same C function to evaluate bytecode so we cannot know which Python function corresponds to which +bytecode-evaluating function. + +Instead, if we run the same experiment with ``perf`` support enabled we get: + +.. code-block:: shell-session + + $ perf report --stdio -n -g + + # Children Self Samples Command Shared Object Symbol + # ........ ........ ............ .......... .................. ..................................................................... + # + 90.58% 0.36% 1 python.exe python.exe [.] _start + | + ---_start + | + --89.86%--__libc_start_main + Py_BytesMain + | + |--55.43%--pymain_run_python.constprop.0 + | | + | |--54.71%--_PyRun_AnyFileObject + | | _PyRun_SimpleFileObject + | | | + | | |--53.62%--run_mod + | | | | + | | | --53.26%--PyEval_EvalCode + | | | py::<module>:/src/script.py + | | | _PyEval_EvalFrameDefault + | | | PyObject_Vectorcall + | | | _PyEval_Vector + | | | py::baz:/src/script.py + | | | _PyEval_EvalFrameDefault + | | | PyObject_Vectorcall + | | | _PyEval_Vector + | | | py::bar:/src/script.py + | | | _PyEval_EvalFrameDefault + | | | PyObject_Vectorcall + | | | _PyEval_Vector + | | | py::foo:/src/script.py + | | | | + | | | |--51.81%--_PyEval_EvalFrameDefault + | | | | | + | | | | |--13.77%--_PyLong_Add + | | | | | | + | | | | | |--3.26%--_PyObject_Malloc + + + +How to enable ``perf`` profiling support +---------------------------------------- + +``perf`` profiling support can be enabled either from the start using +the environment variable :envvar:`PYTHONPERFSUPPORT` or the +:option:`-X perf <-X>` option, +or dynamically using :func:`sys.activate_stack_trampoline` and +:func:`sys.deactivate_stack_trampoline`. + +The :mod:`!sys` functions take precedence over the :option:`!-X` option, +the :option:`!-X` option takes precedence over the environment variable. + +Example, using the environment variable:: + + $ PYTHONPERFSUPPORT=1 + $ python script.py + $ perf report -g -i perf.data + +Example, using the :option:`!-X` option:: + + $ python -X perf script.py + $ perf report -g -i perf.data + +Example, using the :mod:`sys` APIs in file :file:`example.py`: + +.. code-block:: python + + import sys + + sys.activate_stack_trampoline("perf") + do_profiled_stuff() + sys.deactivate_stack_trampoline() + + non_profiled_stuff() + +...then:: + + $ python ./example.py + $ perf report -g -i perf.data + + +How to obtain the best results +------------------------------ + +For best results, Python should be compiled with +``CFLAGS="-fno-omit-frame-pointer -mno-omit-leaf-frame-pointer"`` as this allows +profilers to unwind using only the frame pointer and not on DWARF debug +information. This is because as the code that is interposed to allow ``perf`` +support is dynamically generated it doesn't have any DWARF debugging information +available. + +You can check if your system has been compiled with this flag by running:: + + $ python -m sysconfig | grep 'no-omit-frame-pointer' + +If you don't see any output it means that your interpreter has not been compiled with +frame pointers and therefore it may not be able to show Python functions in the output +of ``perf``. diff --git a/Doc/howto/pyporting.rst b/Doc/howto/pyporting.rst index add1c11b..6c30a0dd 100644 --- a/Doc/howto/pyporting.rst +++ b/Doc/howto/pyporting.rst @@ -1,49 +1,47 @@ .. _pyporting-howto: -********************************* -Porting Python 2 Code to Python 3 -********************************* +************************************* +How to port Python 2 Code to Python 3 +************************************* :author: Brett Cannon .. topic:: Abstract - With Python 3 being the future of Python while Python 2 is still in active - use, it is good to have your project available for both major releases of - Python. This guide is meant to help you figure out how best to support both - Python 2 & 3 simultaneously. + Python 2 reached its official end-of-life at the start of 2020. This means + that no new bug reports, fixes, or changes will be made to Python 2 - it's + no longer supported. + + This guide is intended to provide you with a path to Python 3 for your + code, that includes compatibility with Python 2 as a first step. If you are looking to port an extension module instead of pure Python code, please see :ref:`cporting-howto`. - If you would like to read one core Python developer's take on why Python 3 - came into existence, you can read Nick Coghlan's `Python 3 Q & A`_ or - Brett Cannon's `Why Python 3 exists`_. - + The archived python-porting_ mailing list may contain some useful guidance. - For help with porting, you can view the archived python-porting_ mailing list. The Short Explanation ===================== -To make your project be single-source Python 2/3 compatible, the basic steps +To achieve Python 2/3 compatibility in a single code base, the basic steps are: #. Only worry about supporting Python 2.7 #. Make sure you have good test coverage (coverage.py_ can help; ``python -m pip install coverage``) -#. Learn the differences between Python 2 & 3 +#. Learn the differences between Python 2 and 3 #. Use Futurize_ (or Modernize_) to update your code (e.g. ``python -m pip install future``) #. Use Pylint_ to help make sure you don't regress on your Python 3 support (``python -m pip install pylint``) #. Use caniusepython3_ to find out which of your dependencies are blocking your use of Python 3 (``python -m pip install caniusepython3``) #. Once your dependencies are no longer blocking you, use continuous integration - to make sure you stay compatible with Python 2 & 3 (tox_ can help test + to make sure you stay compatible with Python 2 and 3 (tox_ can help test against multiple versions of Python; ``python -m pip install tox``) #. Consider using optional static type checking to make sure your type usage - works in both Python 2 & 3 (e.g. use mypy_ to check your typing under both - Python 2 & Python 3; ``python -m pip install mypy``). + works in both Python 2 and 3 (e.g. use mypy_ to check your typing under both + Python 2 and Python 3; ``python -m pip install mypy``). .. note:: @@ -55,43 +53,30 @@ are: Details ======= -A key point about supporting Python 2 & 3 simultaneously is that you can start -**today**! Even if your dependencies are not supporting Python 3 yet that does -not mean you can't modernize your code **now** to support Python 3. Most changes -required to support Python 3 lead to cleaner code using newer practices even in -Python 2 code. +Even if other factors - say, dependencies over which you have no control - +still require you to support Python 2, that does not prevent you taking the +step of including Python 3 support. -Another key point is that modernizing your Python 2 code to also support -Python 3 is largely automated for you. While you might have to make some API -decisions thanks to Python 3 clarifying text data versus binary data, the -lower-level work is now mostly done for you and thus can at least benefit from -the automated changes immediately. +Most changes required to support Python 3 lead to cleaner code using newer +practices even in Python 2 code. -Keep those key points in mind while you read on about the details of porting -your code to support Python 2 & 3 simultaneously. +Different versions of Python 2 +------------------------------ -Drop support for Python 2.6 and older -------------------------------------- +Ideally, your code should be compatible with Python 2.7, which was the +last supported version of Python 2. -While you can make Python 2.5 work with Python 3, it is **much** easier if you -only have to work with Python 2.7. If dropping Python 2.5 is not an -option then the six_ project can help you support Python 2.5 & 3 simultaneously -(``python -m pip install six``). Do realize, though, that nearly all the projects listed -in this HOWTO will not be available to you. +Some of the tools mentioned in this guide will not work with Python 2.6. -If you are able to skip Python 2.5 and older, then the required changes -to your code should continue to look and feel like idiomatic Python code. At -worst you will have to use a function instead of a method in some instances or -have to import a function instead of using a built-in one, but otherwise the -overall transformation should not feel foreign to you. +If absolutely necessary, the six_ project can help you support Python 2.5 and +3 simultaneously. Do realize, though, that nearly all the projects listed in +this guide will not be available to you. -But you should aim for only supporting Python 2.7. Python 2.6 is no longer -freely supported and thus is not receiving bugfixes. This means **you** will have -to work around any issues you come across with Python 2.6. There are also some -tools mentioned in this HOWTO which do not support Python 2.6 (e.g., Pylint_), -and this will become more commonplace as time goes on. It will simply be easier -for you if you only support the versions of Python that you have to support. +If you are able to skip Python 2.5 and older, the required changes to your +code will be minimal. At worst you will have to use a function instead of a +method in some instances or have to import a function instead of using a +built-in one. Make sure you specify the proper version support in your ``setup.py`` file @@ -118,62 +103,57 @@ coverage). If you don't already have a tool to measure test coverage then coverage.py_ is recommended. -Learn the differences between Python 2 & 3 -------------------------------------------- +Be aware of the differences between Python 2 and 3 +-------------------------------------------------- Once you have your code well-tested you are ready to begin porting your code to Python 3! But to fully understand how your code is going to change and what you want to look out for while you code, you will want to learn what changes -Python 3 makes in terms of Python 2. Typically the two best ways of doing that -is reading the :ref:`"What's New" <whatsnew-index>` doc for each release of Python 3 and the -`Porting to Python 3`_ book (which is free online). There is also a handy -`cheat sheet`_ from the Python-Future project. +Python 3 makes in terms of Python 2. + +Some resources for understanding the differences and their implications for you +code: + +* the :ref:`"What's New" <whatsnew-index>` doc for each release of Python 3 +* the `Porting to Python 3`_ book (which is free online) +* the handy `cheat sheet`_ from the Python-Future project. Update your code ---------------- -Once you feel like you know what is different in Python 3 compared to Python 2, -it's time to update your code! You have a choice between two tools in porting -your code automatically: Futurize_ and Modernize_. Which tool you choose will -depend on how much like Python 3 you want your code to be. Futurize_ does its -best to make Python 3 idioms and practices exist in Python 2, e.g. backporting -the ``bytes`` type from Python 3 so that you have semantic parity between the -major versions of Python. Modernize_, -on the other hand, is more conservative and targets a Python 2/3 subset of -Python, directly relying on six_ to help provide compatibility. As Python 3 is -the future, it might be best to consider Futurize to begin adjusting to any new -practices that Python 3 introduces which you are not accustomed to yet. - -Regardless of which tool you choose, they will update your code to run under -Python 3 while staying compatible with the version of Python 2 you started with. -Depending on how conservative you want to be, you may want to run the tool over -your test suite first and visually inspect the diff to make sure the -transformation is accurate. After you have transformed your test suite and -verified that all the tests still pass as expected, then you can transform your -application code knowing that any tests which fail is a translation failure. +There are tools available that can port your code automatically. + +Futurize_ does its best to make Python 3 idioms and practices exist in Python +2, e.g. backporting the ``bytes`` type from Python 3 so that you have +semantic parity between the major versions of Python. This is the better +approach for most cases. + +Modernize_, on the other hand, is more conservative and targets a Python 2/3 +subset of Python, directly relying on six_ to help provide compatibility. + +A good approach is to run the tool over your test suite first and visually +inspect the diff to make sure the transformation is accurate. After you have +transformed your test suite and verified that all the tests still pass as +expected, then you can transform your application code knowing that any tests +which fail is a translation failure. Unfortunately the tools can't automate everything to make your code work under -Python 3 and so there are a handful of things you will need to update manually -to get full Python 3 support (which of these steps are necessary vary between -the tools). Read the documentation for the tool you choose to use to see what it -fixes by default and what it can do optionally to know what will (not) be fixed -for you and what you may have to fix on your own (e.g. using ``io.open()`` over -the built-in ``open()`` function is off by default in Modernize). Luckily, -though, there are only a couple of things to watch out for which can be -considered large issues that may be hard to debug if not watched for. +Python 3, and you will also need to read the tools' documentation in case some +options you need are turned off by default. +Key issues to be aware of and check for: Division ++++++++ -In Python 3, ``5 / 2 == 2.5`` and not ``2``; all division between ``int`` values -result in a ``float``. This change has actually been planned since Python 2.2 -which was released in 2002. Since then users have been encouraged to add -``from __future__ import division`` to any and all files which use the ``/`` and -``//`` operators or to be running the interpreter with the ``-Q`` flag. If you -have not been doing this then you will need to go through your code and do two -things: +In Python 3, ``5 / 2 == 2.5`` and not ``2`` as it was in Python 2; all +division between ``int`` values result in a ``float``. This change has +actually been planned since Python 2.2 which was released in 2002. Since then +users have been encouraged to add ``from __future__ import division`` to any +and all files which use the ``/`` and ``//`` operators or to be running the +interpreter with the ``-Q`` flag. If you have not been doing this then you +will need to go through your code and do two things: #. Add ``from __future__ import division`` to your files #. Update any division operator as necessary to either use ``//`` to use floor @@ -197,30 +177,29 @@ specific type. This complicated the situation especially for anyone supporting multiple languages as APIs wouldn't bother explicitly supporting ``unicode`` when they claimed text data support. -To make the distinction between text and binary data clearer and more -pronounced, Python 3 did what most languages created in the age of the internet -have done and made text and binary data distinct types that cannot blindly be -mixed together (Python predates widespread access to the internet). For any code -that deals only with text or only binary data, this separation doesn't pose an -issue. But for code that has to deal with both, it does mean you might have to -now care about when you are using text compared to binary data, which is why -this cannot be entirely automated. - -To start, you will need to decide which APIs take text and which take binary -(it is **highly** recommended you don't design APIs that can take both due to -the difficulty of keeping the code working; as stated earlier it is difficult to -do well). In Python 2 this means making sure the APIs that take text can work -with ``unicode`` and those that work with binary data work with the -``bytes`` type from Python 3 (which is a subset of ``str`` in Python 2 and acts -as an alias for ``bytes`` type in Python 2). Usually the biggest issue is -realizing which methods exist on which types in Python 2 & 3 simultaneously -(for text that's ``unicode`` in Python 2 and ``str`` in Python 3, for binary -that's ``str``/``bytes`` in Python 2 and ``bytes`` in Python 3). The following -table lists the **unique** methods of each data type across Python 2 & 3 -(e.g., the ``decode()`` method is usable on the equivalent binary data type in -either Python 2 or 3, but it can't be used by the textual data type consistently -between Python 2 and 3 because ``str`` in Python 3 doesn't have the method). Do -note that as of Python 3.5 the ``__mod__`` method was added to the bytes type. +Python 3 made text and binary data distinct types that cannot simply be mixed +together. For any code that deals only with text or only binary data, this +separation doesn't pose an issue. But for code that has to deal with both, it +does mean you might have to now care about when you are using text compared +to binary data, which is why this cannot be entirely automated. + +Decide which APIs take text and which take binary (it is **highly** recommended +you don't design APIs that can take both due to the difficulty of keeping the +code working; as stated earlier it is difficult to do well). In Python 2 this +means making sure the APIs that take text can work with ``unicode`` and those +that work with binary data work with the ``bytes`` type from Python 3 +(which is a subset of ``str`` in Python 2 and acts as an alias for ``bytes`` +type in Python 2). Usually the biggest issue is realizing which methods exist +on which types in Python 2 and 3 simultaneously (for text that's ``unicode`` +in Python 2 and ``str`` in Python 3, for binary that's ``str``/``bytes`` in +Python 2 and ``bytes`` in Python 3). + +The following table lists the **unique** methods of each data type across +Python 2 and 3 (e.g., the ``decode()`` method is usable on the equivalent binary +data type in either Python 2 or 3, but it can't be used by the textual data +type consistently between Python 2 and 3 because ``str`` in Python 3 doesn't +have the method). Do note that as of Python 3.5 the ``__mod__`` method was +added to the bytes type. ======================== ===================== **Text data** **Binary data** @@ -246,12 +225,11 @@ having to keep track of what type of data you are working with. The next issue is making sure you know whether the string literals in your code represent text or binary data. You should add a ``b`` prefix to any literal that presents binary data. For text you should add a ``u`` prefix to -the text literal. (there is a :mod:`__future__` import to force all unspecified +the text literal. (There is a :mod:`__future__` import to force all unspecified literals to be Unicode, but usage has shown it isn't as effective as adding a ``b`` or ``u`` prefix to all literals explicitly) -As part of this dichotomy you also need to be careful about opening files. -Unless you have been working on Windows, there is a chance you have not always +You also need to be careful about opening files. Possibly you have not always bothered to add the ``b`` mode when opening a binary file (e.g., ``rb`` for binary reading). Under Python 3, binary files and text files are clearly distinct and mutually incompatible; see the :mod:`io` module for details. @@ -265,7 +243,7 @@ outdated practice of using :func:`codecs.open` as that's only necessary for keeping compatibility with Python 2.5. The constructors of both ``str`` and ``bytes`` have different semantics for the -same arguments between Python 2 & 3. Passing an integer to ``bytes`` in Python 2 +same arguments between Python 2 and 3. Passing an integer to ``bytes`` in Python 2 will give you the string representation of the integer: ``bytes(3) == '3'``. But in Python 3, an integer argument to ``bytes`` will give you a bytes object as long as the integer specified, filled with null bytes: @@ -400,7 +378,7 @@ Use continuous integration to stay compatible --------------------------------------------- Once you are able to fully run under Python 3 you will want to make sure your -code always works under both Python 2 & 3. Probably the best tool for running +code always works under both Python 2 and 3. Probably the best tool for running your tests under multiple Python interpreters is tox_. You can then integrate tox with your continuous integration system so that you never accidentally break Python 2 or 3 support. @@ -413,11 +391,6 @@ separation of text/binary data handling or indexing on bytes you wouldn't easily find the mistake. This flag will raise an exception when these kinds of comparisons occur, making the mistake much easier to track down. -And that's mostly it! At this point your code base is compatible with both -Python 2 and 3 simultaneously. Your testing will also be set up so that you -don't accidentally break Python 2 or 3 compatibility regardless of which version -you typically run your tests under while developing. - Consider using optional static type checking -------------------------------------------- @@ -438,7 +411,7 @@ to make sure everything functions as expected in both versions of Python. .. _Futurize: https://python-future.org/automatic_conversion.html .. _importlib2: https://pypi.org/project/importlib2 .. _Modernize: https://python-modernize.readthedocs.io/ -.. _mypy: http://mypy-lang.org/ +.. _mypy: https://mypy-lang.org/ .. _Porting to Python 3: http://python3porting.com/ .. _Pylint: https://pypi.org/project/pylint diff --git a/Doc/howto/regex.rst b/Doc/howto/regex.rst index 5cd6140f..c19c4830 100644 --- a/Doc/howto/regex.rst +++ b/Doc/howto/regex.rst @@ -378,11 +378,7 @@ containing information about the match: where it starts and ends, the substring it matched, and more. You can learn about this by interactively experimenting with the :mod:`re` -module. If you have :mod:`tkinter` available, you may also want to look at -:source:`Tools/demo/redemo.py`, a demonstration program included with the -Python distribution. It allows you to enter REs and strings, and displays -whether the RE matches or fails. :file:`redemo.py` can be quite useful when -trying to debug a complicated RE. +module. This HOWTO uses the standard Python interpreter for its examples. First, run the Python interpreter, import the :mod:`re` module, and compile a RE:: @@ -522,6 +518,8 @@ cache. Compilation Flags ----------------- +.. currentmodule:: re + Compilation flags let you modify some aspects of how regular expressions work. Flags are available in the :mod:`re` module under two names, a long name such as :const:`IGNORECASE` and a short, one-letter form such as :const:`I`. (If you're diff --git a/Doc/howto/sorting.rst b/Doc/howto/sorting.rst index decce12b..38dd09f0 100644 --- a/Doc/howto/sorting.rst +++ b/Doc/howto/sorting.rst @@ -273,7 +273,7 @@ Odds and Ends * The sort routines use ``<`` when making comparisons between two objects. So, it is easy to add a standard sort order to a class by - defining an :meth:`__lt__` method: + defining an :meth:`~object.__lt__` method: .. doctest:: @@ -281,8 +281,8 @@ Odds and Ends >>> sorted(student_objects) [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)] - However, note that ``<`` can fall back to using :meth:`__gt__` if - :meth:`__lt__` is not implemented (see :func:`object.__lt__`). + However, note that ``<`` can fall back to using :meth:`~object.__gt__` if + :meth:`~object.__lt__` is not implemented (see :func:`object.__lt__`). * Key functions need not depend directly on the objects being sorted. A key function can also access external resources. For instance, if the student grades diff --git a/Doc/howto/unicode.rst b/Doc/howto/unicode.rst index ca09aee7..254fe729 100644 --- a/Doc/howto/unicode.rst +++ b/Doc/howto/unicode.rst @@ -424,8 +424,8 @@ lowercase letters 'ss'. A second tool is the :mod:`unicodedata` module's :func:`~unicodedata.normalize` function that converts strings to one -of several normal forms, where letters followed by a combining -character are replaced with single characters. :func:`normalize` can +of several normal forms, where letters followed by a combining character are +replaced with single characters. :func:`~unicodedata.normalize` can be used to perform string comparisons that won't falsely report inequality if two strings use combining characters differently: @@ -449,7 +449,7 @@ When run, this outputs: .. code-block:: shell-session - $ python3 compare-strs.py + $ python compare-strs.py length of first string= 1 length of second string= 2 True @@ -474,8 +474,8 @@ The Unicode Standard also specifies how to do caseless comparisons:: print(compare_caseless(single_char, multiple_chars)) -This will print ``True``. (Why is :func:`NFD` invoked twice? Because -there are a few characters that make :meth:`casefold` return a +This will print ``True``. (Why is :func:`!NFD` invoked twice? Because +there are a few characters that make :meth:`~str.casefold` return a non-normalized string, so the result needs to be normalized again. See section 3.13 of the Unicode Standard for a discussion and an example.) diff --git a/Doc/howto/urllib2.rst b/Doc/howto/urllib2.rst index 69af3c3a..570435d4 100644 --- a/Doc/howto/urllib2.rst +++ b/Doc/howto/urllib2.rst @@ -6,13 +6,6 @@ :Author: `Michael Foord <https://agileabstractions.com/>`_ -.. note:: - - There is a French translation of an earlier revision of this - HOWTO, available at `urllib2 - Le Manuel manquant - <https://web.archive.org/web/20200910051922/http://www.voidspace.org.uk/python/articles/urllib2_francais.shtml>`_. - - Introduction ============ @@ -86,7 +79,7 @@ response:: import urllib.request - req = urllib.request.Request('http://www.voidspace.org.uk') + req = urllib.request.Request('http://python.org/') with urllib.request.urlopen(req) as response: the_page = response.read() @@ -201,11 +194,11 @@ which comes after we have a look at what happens when things go wrong. Handling Exceptions =================== -*urlopen* raises :exc:`URLError` when it cannot handle a response (though as +*urlopen* raises :exc:`~urllib.error.URLError` when it cannot handle a response (though as usual with Python APIs, built-in exceptions such as :exc:`ValueError`, :exc:`TypeError` etc. may also be raised). -:exc:`HTTPError` is the subclass of :exc:`URLError` raised in the specific case of +:exc:`~urllib.error.HTTPError` is the subclass of :exc:`~urllib.error.URLError` raised in the specific case of HTTP URLs. The exception classes are exported from the :mod:`urllib.error` module. @@ -236,12 +229,12 @@ the status code indicates that the server is unable to fulfil the request. The default handlers will handle some of these responses for you (for example, if the response is a "redirection" that requests the client fetch the document from a different URL, urllib will handle that for you). For those it can't handle, -urlopen will raise an :exc:`HTTPError`. Typical errors include '404' (page not +urlopen will raise an :exc:`~urllib.error.HTTPError`. Typical errors include '404' (page not found), '403' (request forbidden), and '401' (authentication required). See section 10 of :rfc:`2616` for a reference on all the HTTP error codes. -The :exc:`HTTPError` instance raised will have an integer 'code' attribute, which +The :exc:`~urllib.error.HTTPError` instance raised will have an integer 'code' attribute, which corresponds to the error sent by the server. Error Codes @@ -324,7 +317,7 @@ dictionary is reproduced here for convenience :: } When an error is raised the server responds by returning an HTTP error code -*and* an error page. You can use the :exc:`HTTPError` instance as a response on the +*and* an error page. You can use the :exc:`~urllib.error.HTTPError` instance as a response on the page returned. This means that as well as the code attribute, it also has read, geturl, and info, methods as returned by the ``urllib.response`` module:: @@ -345,7 +338,7 @@ geturl, and info, methods as returned by the ``urllib.response`` module:: Wrapping it Up -------------- -So if you want to be prepared for :exc:`HTTPError` *or* :exc:`URLError` there are two +So if you want to be prepared for :exc:`~urllib.error.HTTPError` *or* :exc:`~urllib.error.URLError` there are two basic approaches. I prefer the second approach. Number 1 @@ -372,7 +365,7 @@ Number 1 .. note:: The ``except HTTPError`` *must* come first, otherwise ``except URLError`` - will *also* catch an :exc:`HTTPError`. + will *also* catch an :exc:`~urllib.error.HTTPError`. Number 2 ~~~~~~~~ @@ -398,7 +391,7 @@ Number 2 info and geturl =============== -The response returned by urlopen (or the :exc:`HTTPError` instance) has two +The response returned by urlopen (or the :exc:`~urllib.error.HTTPError` instance) has two useful methods :meth:`info` and :meth:`geturl` and is defined in the module :mod:`urllib.response`.. @@ -458,7 +451,7 @@ To illustrate creating and installing a handler we will use the ``HTTPBasicAuthHandler``. For a more detailed discussion of this subject -- including an explanation of how Basic Authentication works - see the `Basic Authentication Tutorial -<http://www.voidspace.org.uk/python/articles/authentication.shtml>`_. +<https://web.archive.org/web/20201215133350/http://www.voidspace.org.uk/python/articles/authentication.shtml>`__. When authentication is required, the server sends a header (as well as the 401 error code) requesting authentication. This specifies the authentication scheme diff --git a/Tools/scripts/diff.py b/Doc/includes/diff.py old mode 100755 new mode 100644 similarity index 98% rename from Tools/scripts/diff.py rename to Doc/includes/diff.py index 96199b85..001619f5 --- a/Tools/scripts/diff.py +++ b/Doc/includes/diff.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 """ Command line interface to difflib.py providing diffs in four formats: * ndiff: lists every line and highlights interline changes. diff --git a/Doc/includes/email-headers.py b/Doc/includes/email-headers.py index 2c421451..5def0c90 100644 --- a/Doc/includes/email-headers.py +++ b/Doc/includes/email-headers.py @@ -1,5 +1,6 @@ # Import the email modules we'll need -from email.parser import BytesParser, Parser +#from email.parser import BytesParser +from email.parser import Parser from email.policy import default # If the e-mail headers are in a file, uncomment these two lines: diff --git a/Tools/scripts/ndiff.py b/Doc/includes/ndiff.py old mode 100755 new mode 100644 similarity index 80% rename from Tools/scripts/ndiff.py rename to Doc/includes/ndiff.py index c6d09b8f..32c251bc --- a/Tools/scripts/ndiff.py +++ b/Doc/includes/ndiff.py @@ -1,16 +1,3 @@ -#! /usr/bin/env python3 - -# Module ndiff version 1.7.0 -# Released to the public domain 08-Dec-2000, -# by Tim Peters (tim.one@home.com). - -# Provided as-is; use at your own risk; no warranty; no promises; enjoy! - -# ndiff.py is now simply a front-end to the difflib.ndiff() function. -# Originally, it contained the difflib.SequenceMatcher class as well. -# This completes the raiding of reusable code from this formerly -# self-contained script. - """ndiff [-q] file1 file2 or ndiff (-r1 | -r2) < ndiff_output > file1_or_file2 @@ -121,13 +108,4 @@ def restore(which): sys.stdout.writelines(restored) if __name__ == '__main__': - args = sys.argv[1:] - if "-profile" in args: - import profile, pstats - args.remove("-profile") - statf = "ndiff.pro" - profile.run("main(args)", statf) - stats = pstats.Stats(statf) - stats.strip_dirs().sort_stats('time').print_stats() - else: - main(args) + main(sys.argv[1:]) diff --git a/Doc/includes/custom.c b/Doc/includes/newtypes/custom.c similarity index 91% rename from Doc/includes/custom.c rename to Doc/includes/newtypes/custom.c index 26ca7549..9cfba50a 100644 --- a/Doc/includes/custom.c +++ b/Doc/includes/newtypes/custom.c @@ -7,7 +7,7 @@ typedef struct { } CustomObject; static PyTypeObject CustomType = { - PyVarObject_HEAD_INIT(NULL, 0) + .ob_base = PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "custom.Custom", .tp_doc = PyDoc_STR("Custom objects"), .tp_basicsize = sizeof(CustomObject), @@ -17,7 +17,7 @@ static PyTypeObject CustomType = { }; static PyModuleDef custommodule = { - PyModuleDef_HEAD_INIT, + .m_base = PyModuleDef_HEAD_INIT, .m_name = "custom", .m_doc = "Example module that creates an extension type.", .m_size = -1, diff --git a/Doc/includes/custom2.c b/Doc/includes/newtypes/custom2.c similarity index 81% rename from Doc/includes/custom2.c rename to Doc/includes/newtypes/custom2.c index 2a3c59f8..a0222b17 100644 --- a/Doc/includes/custom2.c +++ b/Doc/includes/newtypes/custom2.c @@ -1,6 +1,6 @@ #define PY_SSIZE_T_CLEAN #include <Python.h> -#include "structmember.h" +#include <stddef.h> /* for offsetof() */ typedef struct { PyObject_HEAD @@ -42,7 +42,7 @@ static int Custom_init(CustomObject *self, PyObject *args, PyObject *kwds) { static char *kwlist[] = {"first", "last", "number", NULL}; - PyObject *first = NULL, *last = NULL, *tmp; + PyObject *first = NULL, *last = NULL; if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOi", kwlist, &first, &last, @@ -50,26 +50,20 @@ Custom_init(CustomObject *self, PyObject *args, PyObject *kwds) return -1; if (first) { - tmp = self->first; - Py_INCREF(first); - self->first = first; - Py_XDECREF(tmp); + Py_XSETREF(self->first, Py_NewRef(first)); } if (last) { - tmp = self->last; - Py_INCREF(last); - self->last = last; - Py_XDECREF(tmp); + Py_XSETREF(self->last, Py_NewRef(last)); } return 0; } static PyMemberDef Custom_members[] = { - {"first", T_OBJECT_EX, offsetof(CustomObject, first), 0, + {"first", Py_T_OBJECT_EX, offsetof(CustomObject, first), 0, "first name"}, - {"last", T_OBJECT_EX, offsetof(CustomObject, last), 0, + {"last", Py_T_OBJECT_EX, offsetof(CustomObject, last), 0, "last name"}, - {"number", T_INT, offsetof(CustomObject, number), 0, + {"number", Py_T_INT, offsetof(CustomObject, number), 0, "custom number"}, {NULL} /* Sentinel */ }; @@ -96,7 +90,7 @@ static PyMethodDef Custom_methods[] = { }; static PyTypeObject CustomType = { - PyVarObject_HEAD_INIT(NULL, 0) + .ob_base = PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "custom2.Custom", .tp_doc = PyDoc_STR("Custom objects"), .tp_basicsize = sizeof(CustomObject), @@ -110,7 +104,7 @@ static PyTypeObject CustomType = { }; static PyModuleDef custommodule = { - PyModuleDef_HEAD_INIT, + .m_base =PyModuleDef_HEAD_INIT, .m_name = "custom2", .m_doc = "Example module that creates an extension type.", .m_size = -1, @@ -127,9 +121,7 @@ PyInit_custom2(void) if (m == NULL) return NULL; - Py_INCREF(&CustomType); - if (PyModule_AddObject(m, "Custom", (PyObject *) &CustomType) < 0) { - Py_DECREF(&CustomType); + if (PyModule_AddObjectRef(m, "Custom", (PyObject *) &CustomType) < 0) { Py_DECREF(m); return NULL; } diff --git a/Doc/includes/custom3.c b/Doc/includes/newtypes/custom3.c similarity index 81% rename from Doc/includes/custom3.c rename to Doc/includes/newtypes/custom3.c index 5a47530f..4aeebe0a 100644 --- a/Doc/includes/custom3.c +++ b/Doc/includes/newtypes/custom3.c @@ -1,6 +1,6 @@ #define PY_SSIZE_T_CLEAN #include <Python.h> -#include "structmember.h" +#include <stddef.h> /* for offsetof() */ typedef struct { PyObject_HEAD @@ -42,7 +42,7 @@ static int Custom_init(CustomObject *self, PyObject *args, PyObject *kwds) { static char *kwlist[] = {"first", "last", "number", NULL}; - PyObject *first = NULL, *last = NULL, *tmp; + PyObject *first = NULL, *last = NULL; if (!PyArg_ParseTupleAndKeywords(args, kwds, "|UUi", kwlist, &first, &last, @@ -50,22 +50,16 @@ Custom_init(CustomObject *self, PyObject *args, PyObject *kwds) return -1; if (first) { - tmp = self->first; - Py_INCREF(first); - self->first = first; - Py_DECREF(tmp); + Py_SETREF(self->first, Py_NewRef(first)); } if (last) { - tmp = self->last; - Py_INCREF(last); - self->last = last; - Py_DECREF(tmp); + Py_SETREF(self->last, Py_NewRef(last)); } return 0; } static PyMemberDef Custom_members[] = { - {"number", T_INT, offsetof(CustomObject, number), 0, + {"number", Py_T_INT, offsetof(CustomObject, number), 0, "custom number"}, {NULL} /* Sentinel */ }; @@ -73,14 +67,12 @@ static PyMemberDef Custom_members[] = { static PyObject * Custom_getfirst(CustomObject *self, void *closure) { - Py_INCREF(self->first); - return self->first; + return Py_NewRef(self->first); } static int Custom_setfirst(CustomObject *self, PyObject *value, void *closure) { - PyObject *tmp; if (value == NULL) { PyErr_SetString(PyExc_TypeError, "Cannot delete the first attribute"); return -1; @@ -90,24 +82,19 @@ Custom_setfirst(CustomObject *self, PyObject *value, void *closure) "The first attribute value must be a string"); return -1; } - tmp = self->first; - Py_INCREF(value); - self->first = value; - Py_DECREF(tmp); + Py_SETREF(self->first, Py_NewRef(value)); return 0; } static PyObject * Custom_getlast(CustomObject *self, void *closure) { - Py_INCREF(self->last); - return self->last; + return Py_NewRef(self->last); } static int Custom_setlast(CustomObject *self, PyObject *value, void *closure) { - PyObject *tmp; if (value == NULL) { PyErr_SetString(PyExc_TypeError, "Cannot delete the last attribute"); return -1; @@ -117,10 +104,7 @@ Custom_setlast(CustomObject *self, PyObject *value, void *closure) "The last attribute value must be a string"); return -1; } - tmp = self->last; - Py_INCREF(value); - self->last = value; - Py_DECREF(tmp); + Py_SETREF(self->last, Py_NewRef(value)); return 0; } @@ -146,7 +130,7 @@ static PyMethodDef Custom_methods[] = { }; static PyTypeObject CustomType = { - PyVarObject_HEAD_INIT(NULL, 0) + .ob_base = PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "custom3.Custom", .tp_doc = PyDoc_STR("Custom objects"), .tp_basicsize = sizeof(CustomObject), @@ -161,7 +145,7 @@ static PyTypeObject CustomType = { }; static PyModuleDef custommodule = { - PyModuleDef_HEAD_INIT, + .m_base = PyModuleDef_HEAD_INIT, .m_name = "custom3", .m_doc = "Example module that creates an extension type.", .m_size = -1, @@ -178,9 +162,7 @@ PyInit_custom3(void) if (m == NULL) return NULL; - Py_INCREF(&CustomType); - if (PyModule_AddObject(m, "Custom", (PyObject *) &CustomType) < 0) { - Py_DECREF(&CustomType); + if (PyModule_AddObjectRef(m, "Custom", (PyObject *) &CustomType) < 0) { Py_DECREF(m); return NULL; } diff --git a/Doc/includes/custom4.c b/Doc/includes/newtypes/custom4.c similarity index 84% rename from Doc/includes/custom4.c rename to Doc/includes/newtypes/custom4.c index c7ee5557..3998918f 100644 --- a/Doc/includes/custom4.c +++ b/Doc/includes/newtypes/custom4.c @@ -1,6 +1,6 @@ #define PY_SSIZE_T_CLEAN #include <Python.h> -#include "structmember.h" +#include <stddef.h> /* for offsetof() */ typedef struct { PyObject_HEAD @@ -58,7 +58,7 @@ static int Custom_init(CustomObject *self, PyObject *args, PyObject *kwds) { static char *kwlist[] = {"first", "last", "number", NULL}; - PyObject *first = NULL, *last = NULL, *tmp; + PyObject *first = NULL, *last = NULL; if (!PyArg_ParseTupleAndKeywords(args, kwds, "|UUi", kwlist, &first, &last, @@ -66,22 +66,16 @@ Custom_init(CustomObject *self, PyObject *args, PyObject *kwds) return -1; if (first) { - tmp = self->first; - Py_INCREF(first); - self->first = first; - Py_DECREF(tmp); + Py_SETREF(self->first, Py_NewRef(first)); } if (last) { - tmp = self->last; - Py_INCREF(last); - self->last = last; - Py_DECREF(tmp); + Py_SETREF(self->last, Py_NewRef(last)); } return 0; } static PyMemberDef Custom_members[] = { - {"number", T_INT, offsetof(CustomObject, number), 0, + {"number", Py_T_INT, offsetof(CustomObject, number), 0, "custom number"}, {NULL} /* Sentinel */ }; @@ -89,8 +83,7 @@ static PyMemberDef Custom_members[] = { static PyObject * Custom_getfirst(CustomObject *self, void *closure) { - Py_INCREF(self->first); - return self->first; + return Py_NewRef(self->first); } static int @@ -105,17 +98,14 @@ Custom_setfirst(CustomObject *self, PyObject *value, void *closure) "The first attribute value must be a string"); return -1; } - Py_INCREF(value); - Py_CLEAR(self->first); - self->first = value; + Py_XSETREF(self->first, Py_NewRef(value)); return 0; } static PyObject * Custom_getlast(CustomObject *self, void *closure) { - Py_INCREF(self->last); - return self->last; + return Py_NewRef(self->last); } static int @@ -130,9 +120,7 @@ Custom_setlast(CustomObject *self, PyObject *value, void *closure) "The last attribute value must be a string"); return -1; } - Py_INCREF(value); - Py_CLEAR(self->last); - self->last = value; + Py_XSETREF(self->last, Py_NewRef(value)); return 0; } @@ -158,7 +146,7 @@ static PyMethodDef Custom_methods[] = { }; static PyTypeObject CustomType = { - PyVarObject_HEAD_INIT(NULL, 0) + .ob_base = PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "custom4.Custom", .tp_doc = PyDoc_STR("Custom objects"), .tp_basicsize = sizeof(CustomObject), @@ -175,7 +163,7 @@ static PyTypeObject CustomType = { }; static PyModuleDef custommodule = { - PyModuleDef_HEAD_INIT, + .m_base = PyModuleDef_HEAD_INIT, .m_name = "custom4", .m_doc = "Example module that creates an extension type.", .m_size = -1, @@ -192,9 +180,7 @@ PyInit_custom4(void) if (m == NULL) return NULL; - Py_INCREF(&CustomType); - if (PyModule_AddObject(m, "Custom", (PyObject *) &CustomType) < 0) { - Py_DECREF(&CustomType); + if (PyModule_AddObjectRef(m, "Custom", (PyObject *) &CustomType) < 0) { Py_DECREF(m); return NULL; } diff --git a/Doc/includes/newtypes/pyproject.toml b/Doc/includes/newtypes/pyproject.toml new file mode 100644 index 00000000..ea7937a3 --- /dev/null +++ b/Doc/includes/newtypes/pyproject.toml @@ -0,0 +1,7 @@ +[build-system] +requires = ["setuptools"] +build-backend = "setuptools.build_meta" + +[project] +name = "custom" +version = "1" diff --git a/Doc/includes/newtypes/setup.py b/Doc/includes/newtypes/setup.py new file mode 100644 index 00000000..67f83673 --- /dev/null +++ b/Doc/includes/newtypes/setup.py @@ -0,0 +1,8 @@ +from setuptools import Extension, setup +setup(ext_modules=[ + Extension("custom", ["custom.c"]), + Extension("custom2", ["custom2.c"]), + Extension("custom3", ["custom3.c"]), + Extension("custom4", ["custom4.c"]), + Extension("sublist", ["sublist.c"]), +]) diff --git a/Doc/includes/sublist.c b/Doc/includes/newtypes/sublist.c similarity index 100% rename from Doc/includes/sublist.c rename to Doc/includes/newtypes/sublist.c diff --git a/Doc/includes/test.py b/Doc/includes/newtypes/test.py similarity index 94% rename from Doc/includes/test.py rename to Doc/includes/newtypes/test.py index 09ebe3fe..55a5cf9f 100644 --- a/Doc/includes/test.py +++ b/Doc/includes/newtypes/test.py @@ -187,13 +187,6 @@ Test cyclic gc(?) >>> gc.enable() """ -import os -import sys -from distutils.util import get_platform -PLAT_SPEC = "%s-%d.%d" % (get_platform(), *sys.version_info[:2]) -src = os.path.join("build", "lib.%s" % PLAT_SPEC) -sys.path.append(src) - if __name__ == "__main__": import doctest, __main__ doctest.testmod(__main__) diff --git a/Doc/includes/setup.py b/Doc/includes/setup.py deleted file mode 100644 index a38a39de..00000000 --- a/Doc/includes/setup.py +++ /dev/null @@ -1,9 +0,0 @@ -from distutils.core import setup, Extension -setup(name="noddy", version="1.0", - ext_modules=[ - Extension("noddy", ["noddy.c"]), - Extension("noddy2", ["noddy2.c"]), - Extension("noddy3", ["noddy3.c"]), - Extension("noddy4", ["noddy4.c"]), - Extension("shoddy", ["shoddy.c"]), - ]) diff --git a/Doc/includes/sqlite3/pysqlite_datetime.py b/Doc/includes/sqlite3/pysqlite_datetime.py deleted file mode 100644 index 5d843f90..00000000 --- a/Doc/includes/sqlite3/pysqlite_datetime.py +++ /dev/null @@ -1,22 +0,0 @@ -import sqlite3 -import datetime - -con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES) -cur = con.cursor() -cur.execute("create table test(d date, ts timestamp)") - -today = datetime.date.today() -now = datetime.datetime.now() - -cur.execute("insert into test(d, ts) values (?, ?)", (today, now)) -cur.execute("select d, ts from test") -row = cur.fetchone() -print(today, "=>", row[0], type(row[0])) -print(now, "=>", row[1], type(row[1])) - -cur.execute('select current_date as "d [date]", current_timestamp as "ts [timestamp]"') -row = cur.fetchone() -print("current_date", row[0], type(row[0])) -print("current_timestamp", row[1], type(row[1])) - -con.close() diff --git a/Doc/includes/turtle-star.py b/Doc/includes/turtle-star.py deleted file mode 100644 index 1a5db761..00000000 --- a/Doc/includes/turtle-star.py +++ /dev/null @@ -1,10 +0,0 @@ -from turtle import * -color('red', 'yellow') -begin_fill() -while True: - forward(200) - left(170) - if abs(pos()) < 1: - break -end_fill() -done() diff --git a/Doc/includes/typestruct.h b/Doc/includes/typestruct.h index 02f8ccfe..ec939c28 100644 --- a/Doc/includes/typestruct.h +++ b/Doc/includes/typestruct.h @@ -80,4 +80,7 @@ typedef struct _typeobject { destructor tp_finalize; vectorcallfunc tp_vectorcall; + + /* bitset of which type-watchers care about this type */ + unsigned char tp_watched; } PyTypeObject; diff --git a/Doc/install/index.rst b/Doc/install/index.rst deleted file mode 100644 index d2d8e567..00000000 --- a/Doc/install/index.rst +++ /dev/null @@ -1,1077 +0,0 @@ -.. highlight:: none - -.. _install-index: - -******************************************** - Installing Python Modules (Legacy version) -******************************************** - -:Author: Greg Ward - -.. TODO: Fill in XXX comments - -.. note:: - - The entire ``distutils`` package has been deprecated and will be - removed in Python 3.12. This documentation is retained as a - reference only, and will be removed with the package. See the - :ref:`What's New <distutils-deprecated>` entry for more information. - -.. seealso:: - - :ref:`installing-index` - The up to date module installation documentation. For regular Python - usage, you almost certainly want that document rather than this one. - -.. include:: ../distutils/_setuptools_disclaimer.rst - -.. note:: - - This guide only covers the basic tools for building and distributing - extensions that are provided as part of this version of Python. Third party - tools offer easier to use and more secure alternatives. Refer to the `quick - recommendations section <https://packaging.python.org/guides/tool-recommendations/>`__ - in the Python Packaging User Guide for more information. - - -.. _inst-intro: - - -Introduction -============ - -In Python 2.0, the ``distutils`` API was first added to the standard library. -This provided Linux distro maintainers with a standard way of converting -Python projects into Linux distro packages, and system administrators with a -standard way of installing them directly onto target systems. - -In the many years since Python 2.0 was released, tightly coupling the build -system and package installer to the language runtime release cycle has turned -out to be problematic, and it is now recommended that projects use the -``pip`` package installer and the ``setuptools`` build system, rather than -using ``distutils`` directly. - -See :ref:`installing-index` and :ref:`distributing-index` for more details. - -This legacy documentation is being retained only until we're confident that the -``setuptools`` documentation covers everything needed. - -.. _inst-new-standard: - -Distutils based source distributions ------------------------------------- - -If you download a module source distribution, you can tell pretty quickly if it -was packaged and distributed in the standard way, i.e. using the Distutils. -First, the distribution's name and version number will be featured prominently -in the name of the downloaded archive, e.g. :file:`foo-1.0.tar.gz` or -:file:`widget-0.9.7.zip`. Next, the archive will unpack into a similarly named -directory: :file:`foo-1.0` or :file:`widget-0.9.7`. Additionally, the -distribution will contain a setup script :file:`setup.py`, and a file named -:file:`README.txt` or possibly just :file:`README`, which should explain that -building and installing the module distribution is a simple matter of running -one command from a terminal:: - - python setup.py install - -For Windows, this command should be run from a command prompt window -(:menuselection:`Start --> Accessories`):: - - setup.py install - -If all these things are true, then you already know how to build and install the -modules you've just downloaded: Run the command above. Unless you need to -install things in a non-standard way or customize the build process, you don't -really need this manual. Or rather, the above command is everything you need to -get out of this manual. - - -.. _inst-standard-install: - -Standard Build and Install -========================== - -As described in section :ref:`inst-new-standard`, building and installing a module -distribution using the Distutils is usually one simple command to run from a -terminal:: - - python setup.py install - - -.. _inst-platform-variations: - -Platform variations -------------------- - -You should always run the setup command from the distribution root directory, -i.e. the top-level subdirectory that the module source distribution unpacks -into. For example, if you've just downloaded a module source distribution -:file:`foo-1.0.tar.gz` onto a Unix system, the normal thing to do is:: - - gunzip -c foo-1.0.tar.gz | tar xf - # unpacks into directory foo-1.0 - cd foo-1.0 - python setup.py install - -On Windows, you'd probably download :file:`foo-1.0.zip`. If you downloaded the -archive file to :file:`C:\\Temp`, then it would unpack into -:file:`C:\\Temp\\foo-1.0`; you can use either an archive manipulator with a -graphical user interface (such as WinZip) or a command-line tool (such as -:program:`unzip` or :program:`pkunzip`) to unpack the archive. Then, open a -command prompt window and run:: - - cd c:\Temp\foo-1.0 - python setup.py install - - -.. _inst-splitting-up: - -Splitting the job up --------------------- - -Running ``setup.py install`` builds and installs all modules in one run. If you -prefer to work incrementally---especially useful if you want to customize the -build process, or if things are going wrong---you can use the setup script to do -one thing at a time. This is particularly helpful when the build and install -will be done by different users---for example, you might want to build a module -distribution and hand it off to a system administrator for installation (or do -it yourself, with super-user privileges). - -For example, you can build everything in one step, and then install everything -in a second step, by invoking the setup script twice:: - - python setup.py build - python setup.py install - -If you do this, you will notice that running the :command:`install` command -first runs the :command:`build` command, which---in this case---quickly notices -that it has nothing to do, since everything in the :file:`build` directory is -up-to-date. - -You may not need this ability to break things down often if all you do is -install modules downloaded off the 'net, but it's very handy for more advanced -tasks. If you get into distributing your own Python modules and extensions, -you'll run lots of individual Distutils commands on their own. - - -.. _inst-how-build-works: - -How building works ------------------- - -As implied above, the :command:`build` command is responsible for putting the -files to install into a *build directory*. By default, this is :file:`build` -under the distribution root; if you're excessively concerned with speed, or want -to keep the source tree pristine, you can change the build directory with the -:option:`!--build-base` option. For example:: - - python setup.py build --build-base=/path/to/pybuild/foo-1.0 - -(Or you could do this permanently with a directive in your system or personal -Distutils configuration file; see section :ref:`inst-config-files`.) Normally, this -isn't necessary. - -The default layout for the build tree is as follows:: - - --- build/ --- lib/ - or - --- build/ --- lib.<plat>/ - temp.<plat>/ - -where ``<plat>`` expands to a brief description of the current OS/hardware -platform and Python version. The first form, with just a :file:`lib` directory, -is used for "pure module distributions"---that is, module distributions that -include only pure Python modules. If a module distribution contains any -extensions (modules written in C/C++), then the second form, with two ``<plat>`` -directories, is used. In that case, the :file:`temp.{plat}` directory holds -temporary files generated by the compile/link process that don't actually get -installed. In either case, the :file:`lib` (or :file:`lib.{plat}`) directory -contains all Python modules (pure Python and extensions) that will be installed. - -In the future, more directories will be added to handle Python scripts, -documentation, binary executables, and whatever else is needed to handle the job -of installing Python modules and applications. - - -.. _inst-how-install-works: - -How installation works ----------------------- - -After the :command:`build` command runs (whether you run it explicitly, or the -:command:`install` command does it for you), the work of the :command:`install` -command is relatively simple: all it has to do is copy everything under -:file:`build/lib` (or :file:`build/lib.{plat}`) to your chosen installation -directory. - -If you don't choose an installation directory---i.e., if you just run ``setup.py -install``\ ---then the :command:`install` command installs to the standard -location for third-party Python modules. This location varies by platform and -by how you built/installed Python itself. On Unix (and macOS, which is also -Unix-based), it also depends on whether the module distribution being installed -is pure Python or contains extensions ("non-pure"): - -.. tabularcolumns:: |l|l|l|l| - -+-----------------+-----------------------------------------------------+--------------------------------------------------+-------+ -| Platform | Standard installation location | Default value | Notes | -+=================+=====================================================+==================================================+=======+ -| Unix (pure) | :file:`{prefix}/lib/python{X.Y}/site-packages` | :file:`/usr/local/lib/python{X.Y}/site-packages` | \(1) | -+-----------------+-----------------------------------------------------+--------------------------------------------------+-------+ -| Unix (non-pure) | :file:`{exec-prefix}/lib/python{X.Y}/site-packages` | :file:`/usr/local/lib/python{X.Y}/site-packages` | \(1) | -+-----------------+-----------------------------------------------------+--------------------------------------------------+-------+ -| Windows | :file:`{prefix}\\Lib\\site-packages` | :file:`C:\\Python{XY}\\Lib\\site-packages` | \(2) | -+-----------------+-----------------------------------------------------+--------------------------------------------------+-------+ - -Notes: - -(1) - Most Linux distributions include Python as a standard part of the system, so - :file:`{prefix}` and :file:`{exec-prefix}` are usually both :file:`/usr` on - Linux. If you build Python yourself on Linux (or any Unix-like system), the - default :file:`{prefix}` and :file:`{exec-prefix}` are :file:`/usr/local`. - -(2) - The default installation directory on Windows was :file:`C:\\Program - Files\\Python` under Python 1.6a1, 1.5.2, and earlier. - -:file:`{prefix}` and :file:`{exec-prefix}` stand for the directories that Python -is installed to, and where it finds its libraries at run-time. They are always -the same under Windows, and very often the same under Unix and macOS. You -can find out what your Python installation uses for :file:`{prefix}` and -:file:`{exec-prefix}` by running Python in interactive mode and typing a few -simple commands. Under Unix, just type ``python`` at the shell prompt. Under -Windows, choose :menuselection:`Start --> Programs --> Python X.Y --> -Python (command line)`. Once the interpreter is started, you type Python code -at the prompt. For example, on my Linux system, I type the three Python -statements shown below, and get the output as shown, to find out my -:file:`{prefix}` and :file:`{exec-prefix}`: - -.. code-block:: pycon - - Python 2.4 (#26, Aug 7 2004, 17:19:02) - Type "help", "copyright", "credits" or "license" for more information. - >>> import sys - >>> sys.prefix - '/usr' - >>> sys.exec_prefix - '/usr' - -A few other placeholders are used in this document: :file:`{X.Y}` stands for the -version of Python, for example ``3.2``; :file:`{abiflags}` will be replaced by -the value of :data:`sys.abiflags` or the empty string for platforms which don't -define ABI flags; :file:`{distname}` will be replaced by the name of the module -distribution being installed. Dots and capitalization are important in the -paths; for example, a value that uses ``python3.2`` on UNIX will typically use -``Python32`` on Windows. - -If you don't want to install modules to the standard location, or if you don't -have permission to write there, then you need to read about alternate -installations in section :ref:`inst-alt-install`. If you want to customize your -installation directories more heavily, see section :ref:`inst-custom-install` on -custom installations. - - -.. _inst-alt-install: - -Alternate Installation -====================== - -Often, it is necessary or desirable to install modules to a location other than -the standard location for third-party Python modules. For example, on a Unix -system you might not have permission to write to the standard third-party module -directory. Or you might wish to try out a module before making it a standard -part of your local Python installation. This is especially true when upgrading -a distribution already present: you want to make sure your existing base of -scripts still works with the new version before actually upgrading. - -The Distutils :command:`install` command is designed to make installing module -distributions to an alternate location simple and painless. The basic idea is -that you supply a base directory for the installation, and the -:command:`install` command picks a set of directories (called an *installation -scheme*) under this base directory in which to install files. The details -differ across platforms, so read whichever of the following sections applies to -you. - -Note that the various alternate installation schemes are mutually exclusive: you -can pass ``--user``, or ``--home``, or ``--prefix`` and ``--exec-prefix``, or -``--install-base`` and ``--install-platbase``, but you can't mix from these -groups. - - -.. _inst-alt-install-user: - -Alternate installation: the user scheme ---------------------------------------- - -This scheme is designed to be the most convenient solution for users that don't -have write permission to the global site-packages directory or don't want to -install into it. It is enabled with a simple option:: - - python setup.py install --user - -Files will be installed into subdirectories of :data:`site.USER_BASE` (written -as :file:`{userbase}` hereafter). This scheme installs pure Python modules and -extension modules in the same location (also known as :data:`site.USER_SITE`). -Here are the values for UNIX, including macOS: - -=============== =========================================================== -Type of file Installation directory -=============== =========================================================== -modules :file:`{userbase}/lib/python{X.Y}/site-packages` -scripts :file:`{userbase}/bin` -data :file:`{userbase}` -C headers :file:`{userbase}/include/python{X.Y}{abiflags}/{distname}` -=============== =========================================================== - -And here are the values used on Windows: - -=============== =========================================================== -Type of file Installation directory -=============== =========================================================== -modules :file:`{userbase}\\Python{XY}\\site-packages` -scripts :file:`{userbase}\\Python{XY}\\Scripts` -data :file:`{userbase}` -C headers :file:`{userbase}\\Python{XY}\\Include\\{distname}` -=============== =========================================================== - -The advantage of using this scheme compared to the other ones described below is -that the user site-packages directory is under normal conditions always included -in :data:`sys.path` (see :mod:`site` for more information), which means that -there is no additional step to perform after running the :file:`setup.py` script -to finalize the installation. - -The :command:`build_ext` command also has a ``--user`` option to add -:file:`{userbase}/include` to the compiler search path for header files and -:file:`{userbase}/lib` to the compiler search path for libraries as well as to -the runtime search path for shared C libraries (rpath). - - -.. _inst-alt-install-home: - -Alternate installation: the home scheme ---------------------------------------- - -The idea behind the "home scheme" is that you build and maintain a personal -stash of Python modules. This scheme's name is derived from the idea of a -"home" directory on Unix, since it's not unusual for a Unix user to make their -home directory have a layout similar to :file:`/usr/` or :file:`/usr/local/`. -This scheme can be used by anyone, regardless of the operating system they -are installing for. - -Installing a new module distribution is as simple as :: - - python setup.py install --home=<dir> - -where you can supply any directory you like for the :option:`!--home` option. On -Unix, lazy typists can just type a tilde (``~``); the :command:`install` command -will expand this to your home directory:: - - python setup.py install --home=~ - -To make Python find the distributions installed with this scheme, you may have -to :ref:`modify Python's search path <inst-search-path>` or edit -:mod:`sitecustomize` (see :mod:`site`) to call :func:`site.addsitedir` or edit -:data:`sys.path`. - -The :option:`!--home` option defines the installation base directory. Files are -installed to the following directories under the installation base as follows: - -=============== =========================================================== -Type of file Installation directory -=============== =========================================================== -modules :file:`{home}/lib/python` -scripts :file:`{home}/bin` -data :file:`{home}` -C headers :file:`{home}/include/python/{distname}` -=============== =========================================================== - -(Mentally replace slashes with backslashes if you're on Windows.) - - -.. _inst-alt-install-prefix-unix: - -Alternate installation: Unix (the prefix scheme) ------------------------------------------------- - -The "prefix scheme" is useful when you wish to use one Python installation to -perform the build/install (i.e., to run the setup script), but install modules -into the third-party module directory of a different Python installation (or -something that looks like a different Python installation). If this sounds a -trifle unusual, it is---that's why the user and home schemes come before. However, -there are at least two known cases where the prefix scheme will be useful. - -First, consider that many Linux distributions put Python in :file:`/usr`, rather -than the more traditional :file:`/usr/local`. This is entirely appropriate, -since in those cases Python is part of "the system" rather than a local add-on. -However, if you are installing Python modules from source, you probably want -them to go in :file:`/usr/local/lib/python2.{X}` rather than -:file:`/usr/lib/python2.{X}`. This can be done with :: - - /usr/bin/python setup.py install --prefix=/usr/local - -Another possibility is a network filesystem where the name used to write to a -remote directory is different from the name used to read it: for example, the -Python interpreter accessed as :file:`/usr/local/bin/python` might search for -modules in :file:`/usr/local/lib/python2.{X}`, but those modules would have to -be installed to, say, :file:`/mnt/{@server}/export/lib/python2.{X}`. This could -be done with :: - - /usr/local/bin/python setup.py install --prefix=/mnt/@server/export - -In either case, the :option:`!--prefix` option defines the installation base, and -the :option:`!--exec-prefix` option defines the platform-specific installation -base, which is used for platform-specific files. (Currently, this just means -non-pure module distributions, but could be expanded to C libraries, binary -executables, etc.) If :option:`!--exec-prefix` is not supplied, it defaults to -:option:`!--prefix`. Files are installed as follows: - -================= ========================================================== -Type of file Installation directory -================= ========================================================== -Python modules :file:`{prefix}/lib/python{X.Y}/site-packages` -extension modules :file:`{exec-prefix}/lib/python{X.Y}/site-packages` -scripts :file:`{prefix}/bin` -data :file:`{prefix}` -C headers :file:`{prefix}/include/python{X.Y}{abiflags}/{distname}` -================= ========================================================== - -There is no requirement that :option:`!--prefix` or :option:`!--exec-prefix` -actually point to an alternate Python installation; if the directories listed -above do not already exist, they are created at installation time. - -Incidentally, the real reason the prefix scheme is important is simply that a -standard Unix installation uses the prefix scheme, but with :option:`!--prefix` -and :option:`!--exec-prefix` supplied by Python itself as ``sys.prefix`` and -``sys.exec_prefix``. Thus, you might think you'll never use the prefix scheme, -but every time you run ``python setup.py install`` without any other options, -you're using it. - -Note that installing extensions to an alternate Python installation has no -effect on how those extensions are built: in particular, the Python header files -(:file:`Python.h` and friends) installed with the Python interpreter used to run -the setup script will be used in compiling extensions. It is your -responsibility to ensure that the interpreter used to run extensions installed -in this way is compatible with the interpreter used to build them. The best way -to do this is to ensure that the two interpreters are the same version of Python -(possibly different builds, or possibly copies of the same build). (Of course, -if your :option:`!--prefix` and :option:`!--exec-prefix` don't even point to an -alternate Python installation, this is immaterial.) - - -.. _inst-alt-install-prefix-windows: - -Alternate installation: Windows (the prefix scheme) ---------------------------------------------------- - -Windows has no concept of a user's home directory, and since the standard Python -installation under Windows is simpler than under Unix, the :option:`!--prefix` -option has traditionally been used to install additional packages in separate -locations on Windows. :: - - python setup.py install --prefix="\Temp\Python" - -to install modules to the :file:`\\Temp\\Python` directory on the current drive. - -The installation base is defined by the :option:`!--prefix` option; the -:option:`!--exec-prefix` option is not supported under Windows, which means that -pure Python modules and extension modules are installed into the same location. -Files are installed as follows: - -=============== ========================================================== -Type of file Installation directory -=============== ========================================================== -modules :file:`{prefix}\\Lib\\site-packages` -scripts :file:`{prefix}\\Scripts` -data :file:`{prefix}` -C headers :file:`{prefix}\\Include\\{distname}` -=============== ========================================================== - - -.. _inst-custom-install: - -Custom Installation -=================== - -Sometimes, the alternate installation schemes described in section -:ref:`inst-alt-install` just don't do what you want. You might want to tweak just -one or two directories while keeping everything under the same base directory, -or you might want to completely redefine the installation scheme. In either -case, you're creating a *custom installation scheme*. - -To create a custom installation scheme, you start with one of the alternate -schemes and override some of the installation directories used for the various -types of files, using these options: - -====================== ======================= -Type of file Override option -====================== ======================= -Python modules ``--install-purelib`` -extension modules ``--install-platlib`` -all modules ``--install-lib`` -scripts ``--install-scripts`` -data ``--install-data`` -C headers ``--install-headers`` -====================== ======================= - -These override options can be relative, absolute, -or explicitly defined in terms of one of the installation base directories. -(There are two installation base directories, and they are normally the -same---they only differ when you use the Unix "prefix scheme" and supply -different ``--prefix`` and ``--exec-prefix`` options; using ``--install-lib`` -will override values computed or given for ``--install-purelib`` and -``--install-platlib``, and is recommended for schemes that don't make a -difference between Python and extension modules.) - -For example, say you're installing a module distribution to your home directory -under Unix---but you want scripts to go in :file:`~/scripts` rather than -:file:`~/bin`. As you might expect, you can override this directory with the -:option:`!--install-scripts` option; in this case, it makes most sense to supply -a relative path, which will be interpreted relative to the installation base -directory (your home directory, in this case):: - - python setup.py install --home=~ --install-scripts=scripts - -Another Unix example: suppose your Python installation was built and installed -with a prefix of :file:`/usr/local/python`, so under a standard installation -scripts will wind up in :file:`/usr/local/python/bin`. If you want them in -:file:`/usr/local/bin` instead, you would supply this absolute directory for the -:option:`!--install-scripts` option:: - - python setup.py install --install-scripts=/usr/local/bin - -(This performs an installation using the "prefix scheme", where the prefix is -whatever your Python interpreter was installed with--- :file:`/usr/local/python` -in this case.) - -If you maintain Python on Windows, you might want third-party modules to live in -a subdirectory of :file:`{prefix}`, rather than right in :file:`{prefix}` -itself. This is almost as easy as customizing the script installation -directory---you just have to remember that there are two types of modules -to worry about, Python and extension modules, which can conveniently be both -controlled by one option:: - - python setup.py install --install-lib=Site - -The specified installation directory is relative to :file:`{prefix}`. Of -course, you also have to ensure that this directory is in Python's module -search path, such as by putting a :file:`.pth` file in a site directory (see -:mod:`site`). See section :ref:`inst-search-path` to find out how to modify -Python's search path. - -If you want to define an entire installation scheme, you just have to supply all -of the installation directory options. The recommended way to do this is to -supply relative paths; for example, if you want to maintain all Python -module-related files under :file:`python` in your home directory, and you want a -separate directory for each platform that you use your home directory from, you -might define the following installation scheme:: - - python setup.py install --home=~ \ - --install-purelib=python/lib \ - --install-platlib=python/lib.$PLAT \ - --install-scripts=python/scripts - --install-data=python/data - -or, equivalently, :: - - python setup.py install --home=~/python \ - --install-purelib=lib \ - --install-platlib='lib.$PLAT' \ - --install-scripts=scripts - --install-data=data - -``$PLAT`` is not (necessarily) an environment variable---it will be expanded by -the Distutils as it parses your command line options, just as it does when -parsing your configuration file(s). - -Obviously, specifying the entire installation scheme every time you install a -new module distribution would be very tedious. Thus, you can put these options -into your Distutils config file (see section :ref:`inst-config-files`): - -.. code-block:: ini - - [install] - install-base=$HOME - install-purelib=python/lib - install-platlib=python/lib.$PLAT - install-scripts=python/scripts - install-data=python/data - -or, equivalently, - -.. code-block:: ini - - [install] - install-base=$HOME/python - install-purelib=lib - install-platlib=lib.$PLAT - install-scripts=scripts - install-data=data - -Note that these two are *not* equivalent if you supply a different installation -base directory when you run the setup script. For example, :: - - python setup.py install --install-base=/tmp - -would install pure modules to :file:`/tmp/python/lib` in the first case, and -to :file:`/tmp/lib` in the second case. (For the second case, you probably -want to supply an installation base of :file:`/tmp/python`.) - -You probably noticed the use of ``$HOME`` and ``$PLAT`` in the sample -configuration file input. These are Distutils configuration variables, which -bear a strong resemblance to environment variables. In fact, you can use -environment variables in config files on platforms that have such a notion but -the Distutils additionally define a few extra variables that may not be in your -environment, such as ``$PLAT``. (And of course, on systems that don't have -environment variables, such as Mac OS 9, the configuration variables supplied by -the Distutils are the only ones you can use.) See section :ref:`inst-config-files` -for details. - -.. note:: When a :ref:`virtual environment <venv-def>` is activated, any options - that change the installation path will be ignored from all distutils configuration - files to prevent inadvertently installing projects outside of the virtual - environment. - -.. XXX need some Windows examples---when would custom installation schemes be - needed on those platforms? - - -.. XXX Move this to Doc/using - -.. _inst-search-path: - -Modifying Python's Search Path ------------------------------- - -When the Python interpreter executes an :keyword:`import` statement, it searches -for both Python code and extension modules along a search path. A default value -for the path is configured into the Python binary when the interpreter is built. -You can determine the path by importing the :mod:`sys` module and printing the -value of ``sys.path``. :: - - $ python - Python 2.2 (#11, Oct 3 2002, 13:31:27) - [GCC 2.96 20000731 (Red Hat Linux 7.3 2.96-112)] on linux2 - Type "help", "copyright", "credits" or "license" for more information. - >>> import sys - >>> sys.path - ['', '/usr/local/lib/python2.3', '/usr/local/lib/python2.3/plat-linux2', - '/usr/local/lib/python2.3/lib-tk', '/usr/local/lib/python2.3/lib-dynload', - '/usr/local/lib/python2.3/site-packages'] - >>> - -The null string in ``sys.path`` represents the current working directory. - -The expected convention for locally installed packages is to put them in the -:file:`{...}/site-packages/` directory, but you may want to install Python -modules into some arbitrary directory. For example, your site may have a -convention of keeping all software related to the web server under :file:`/www`. -Add-on Python modules might then belong in :file:`/www/python`, and in order to -import them, this directory must be added to ``sys.path``. There are several -different ways to add the directory. - -The most convenient way is to add a path configuration file to a directory -that's already on Python's path, usually to the :file:`.../site-packages/` -directory. Path configuration files have an extension of :file:`.pth`, and each -line must contain a single path that will be appended to ``sys.path``. (Because -the new paths are appended to ``sys.path``, modules in the added directories -will not override standard modules. This means you can't use this mechanism for -installing fixed versions of standard modules.) - -Paths can be absolute or relative, in which case they're relative to the -directory containing the :file:`.pth` file. See the documentation of -the :mod:`site` module for more information. - -A slightly less convenient way is to edit the :file:`site.py` file in Python's -standard library, and modify ``sys.path``. :file:`site.py` is automatically -imported when the Python interpreter is executed, unless the :option:`-S` switch -is supplied to suppress this behaviour. So you could simply edit -:file:`site.py` and add two lines to it: - -.. code-block:: python - - import sys - sys.path.append('/www/python/') - -However, if you reinstall the same major version of Python (perhaps when -upgrading from 2.2 to 2.2.2, for example) :file:`site.py` will be overwritten by -the stock version. You'd have to remember that it was modified and save a copy -before doing the installation. - -There are two environment variables that can modify ``sys.path``. -:envvar:`PYTHONHOME` sets an alternate value for the prefix of the Python -installation. For example, if :envvar:`PYTHONHOME` is set to ``/www/python``, -the search path will be set to ``['', '/www/python/lib/pythonX.Y/', -'/www/python/lib/pythonX.Y/plat-linux2', ...]``. - -The :envvar:`PYTHONPATH` variable can be set to a list of paths that will be -added to the beginning of ``sys.path``. For example, if :envvar:`PYTHONPATH` is -set to ``/www/python:/opt/py``, the search path will begin with -``['/www/python', '/opt/py']``. (Note that directories must exist in order to -be added to ``sys.path``; the :mod:`site` module removes paths that don't -exist.) - -Finally, ``sys.path`` is just a regular Python list, so any Python application -can modify it by adding or removing entries. - - -.. _inst-config-files: - -Distutils Configuration Files -============================= - -As mentioned above, you can use Distutils configuration files to record personal -or site preferences for any Distutils options. That is, any option to any -command can be stored in one of two or three (depending on your platform) -configuration files, which will be consulted before the command-line is parsed. -This means that configuration files will override default values, and the -command-line will in turn override configuration files. Furthermore, if -multiple configuration files apply, values from "earlier" files are overridden -by "later" files. - - -.. _inst-config-filenames: - -Location and names of config files ----------------------------------- - -The names and locations of the configuration files vary slightly across -platforms. On Unix and macOS, the three configuration files (in the order -they are processed) are: - -+--------------+----------------------------------------------------------+-------+ -| Type of file | Location and filename | Notes | -+==============+==========================================================+=======+ -| system | :file:`{prefix}/lib/python{ver}/distutils/distutils.cfg` | \(1) | -+--------------+----------------------------------------------------------+-------+ -| personal | :file:`$HOME/.pydistutils.cfg` | \(2) | -+--------------+----------------------------------------------------------+-------+ -| local | :file:`setup.cfg` | \(3) | -+--------------+----------------------------------------------------------+-------+ - -And on Windows, the configuration files are: - -+--------------+-------------------------------------------------+-------+ -| Type of file | Location and filename | Notes | -+==============+=================================================+=======+ -| system | :file:`{prefix}\\Lib\\distutils\\distutils.cfg` | \(4) | -+--------------+-------------------------------------------------+-------+ -| personal | :file:`%HOME%\\pydistutils.cfg` | \(5) | -+--------------+-------------------------------------------------+-------+ -| local | :file:`setup.cfg` | \(3) | -+--------------+-------------------------------------------------+-------+ - -On all platforms, the "personal" file can be temporarily disabled by -passing the ``--no-user-cfg`` option. - -Notes: - -(1) - Strictly speaking, the system-wide configuration file lives in the directory - where the Distutils are installed; under Python 1.6 and later on Unix, this is - as shown. For Python 1.5.2, the Distutils will normally be installed to - :file:`{prefix}/lib/python1.5/site-packages/distutils`, so the system - configuration file should be put there under Python 1.5.2. - -(2) - On Unix, if the :envvar:`HOME` environment variable is not defined, the user's - home directory will be determined with the :func:`getpwuid` function from the - standard :mod:`pwd` module. This is done by the :func:`os.path.expanduser` - function used by Distutils. - -(3) - I.e., in the current directory (usually the location of the setup script). - -(4) - (See also note (1).) Under Python 1.6 and later, Python's default "installation - prefix" is :file:`C:\\Python`, so the system configuration file is normally - :file:`C:\\Python\\Lib\\distutils\\distutils.cfg`. Under Python 1.5.2, the - default prefix was :file:`C:\\Program Files\\Python`, and the Distutils were not - part of the standard library---so the system configuration file would be - :file:`C:\\Program Files\\Python\\distutils\\distutils.cfg` in a standard Python - 1.5.2 installation under Windows. - -(5) - On Windows, if the :envvar:`HOME` environment variable is not defined, - :envvar:`USERPROFILE` then :envvar:`HOMEDRIVE` and :envvar:`HOMEPATH` will - be tried. This is done by the :func:`os.path.expanduser` function used - by Distutils. - - -.. _inst-config-syntax: - -Syntax of config files ----------------------- - -The Distutils configuration files all have the same syntax. The config files -are grouped into sections. There is one section for each Distutils command, -plus a ``global`` section for global options that affect every command. Each -section consists of one option per line, specified as ``option=value``. - -For example, the following is a complete config file that just forces all -commands to run quietly by default: - -.. code-block:: ini - - [global] - verbose=0 - -If this is installed as the system config file, it will affect all processing of -any Python module distribution by any user on the current system. If it is -installed as your personal config file (on systems that support them), it will -affect only module distributions processed by you. And if it is used as the -:file:`setup.cfg` for a particular module distribution, it affects only that -distribution. - -You could override the default "build base" directory and make the -:command:`build\*` commands always forcibly rebuild all files with the -following: - -.. code-block:: ini - - [build] - build-base=blib - force=1 - -which corresponds to the command-line arguments :: - - python setup.py build --build-base=blib --force - -except that including the :command:`build` command on the command-line means -that command will be run. Including a particular command in config files has no -such implication; it only means that if the command is run, the options in the -config file will apply. (Or if other commands that derive values from it are -run, they will use the values in the config file.) - -You can find out the complete list of options for any command using the -:option:`!--help` option, e.g.:: - - python setup.py build --help - -and you can find out the complete list of global options by using -:option:`!--help` without a command:: - - python setup.py --help - -See also the "Reference" section of the "Distributing Python Modules" manual. - - -.. _inst-building-ext: - -Building Extensions: Tips and Tricks -==================================== - -Whenever possible, the Distutils try to use the configuration information made -available by the Python interpreter used to run the :file:`setup.py` script. -For example, the same compiler and linker flags used to compile Python will also -be used for compiling extensions. Usually this will work well, but in -complicated situations this might be inappropriate. This section discusses how -to override the usual Distutils behaviour. - - -.. _inst-tweak-flags: - -Tweaking compiler/linker flags ------------------------------- - -Compiling a Python extension written in C or C++ will sometimes require -specifying custom flags for the compiler and linker in order to use a particular -library or produce a special kind of object code. This is especially true if the -extension hasn't been tested on your platform, or if you're trying to -cross-compile Python. - -In the most general case, the extension author might have foreseen that -compiling the extensions would be complicated, and provided a :file:`Setup` file -for you to edit. This will likely only be done if the module distribution -contains many separate extension modules, or if they often require elaborate -sets of compiler flags in order to work. - -A :file:`Setup` file, if present, is parsed in order to get a list of extensions -to build. Each line in a :file:`Setup` describes a single module. Lines have -the following structure:: - - module ... [sourcefile ...] [cpparg ...] [library ...] - - -Let's examine each of the fields in turn. - -* *module* is the name of the extension module to be built, and should be a - valid Python identifier. You can't just change this in order to rename a module - (edits to the source code would also be needed), so this should be left alone. - -* *sourcefile* is anything that's likely to be a source code file, at least - judging by the filename. Filenames ending in :file:`.c` are assumed to be - written in C, filenames ending in :file:`.C`, :file:`.cc`, and :file:`.c++` are - assumed to be C++, and filenames ending in :file:`.m` or :file:`.mm` are assumed - to be in Objective C. - -* *cpparg* is an argument for the C preprocessor, and is anything starting with - :option:`!-I`, :option:`!-D`, :option:`!-U` or :option:`!-C`. - -* *library* is anything ending in :file:`.a` or beginning with :option:`!-l` or - :option:`!-L`. - -If a particular platform requires a special library on your platform, you can -add it by editing the :file:`Setup` file and running ``python setup.py build``. -For example, if the module defined by the line :: - - foo foomodule.c - -must be linked with the math library :file:`libm.a` on your platform, simply add -:option:`!-lm` to the line:: - - foo foomodule.c -lm - -Arbitrary switches intended for the compiler or the linker can be supplied with -the :option:`!-Xcompiler` *arg* and :option:`!-Xlinker` *arg* options:: - - foo foomodule.c -Xcompiler -o32 -Xlinker -shared -lm - -The next option after :option:`!-Xcompiler` and :option:`!-Xlinker` will be -appended to the proper command line, so in the above example the compiler will -be passed the :option:`!-o32` option, and the linker will be passed -:option:`!-shared`. If a compiler option requires an argument, you'll have to -supply multiple :option:`!-Xcompiler` options; for example, to pass ``-x c++`` -the :file:`Setup` file would have to contain ``-Xcompiler -x -Xcompiler c++``. - -Compiler flags can also be supplied through setting the :envvar:`CFLAGS` -environment variable. If set, the contents of :envvar:`CFLAGS` will be added to -the compiler flags specified in the :file:`Setup` file. - - -.. _inst-non-ms-compilers: - -Using non-Microsoft compilers on Windows ----------------------------------------- - -.. sectionauthor:: Rene Liebscher <R.Liebscher@gmx.de> - - - -Borland/CodeGear C++ -^^^^^^^^^^^^^^^^^^^^ - -This subsection describes the necessary steps to use Distutils with the Borland -C++ compiler version 5.5. First you have to know that Borland's object file -format (OMF) is different from the format used by the Python version you can -download from the Python or ActiveState web site. (Python is built with -Microsoft Visual C++, which uses COFF as the object file format.) For this -reason you have to convert Python's library :file:`python25.lib` into the -Borland format. You can do this as follows: - -.. Should we mention that users have to create cfg-files for the compiler? -.. see also http://community.borland.com/article/0,1410,21205,00.html - -:: - - coff2omf python25.lib python25_bcpp.lib - -The :file:`coff2omf` program comes with the Borland compiler. The file -:file:`python25.lib` is in the :file:`Libs` directory of your Python -installation. If your extension uses other libraries (zlib, ...) you have to -convert them too. - -The converted files have to reside in the same directories as the normal -libraries. - -How does Distutils manage to use these libraries with their changed names? If -the extension needs a library (eg. :file:`foo`) Distutils checks first if it -finds a library with suffix :file:`_bcpp` (eg. :file:`foo_bcpp.lib`) and then -uses this library. In the case it doesn't find such a special library it uses -the default name (:file:`foo.lib`.) [#]_ - -To let Distutils compile your extension with Borland C++ you now have to type:: - - python setup.py build --compiler=bcpp - -If you want to use the Borland C++ compiler as the default, you could specify -this in your personal or system-wide configuration file for Distutils (see -section :ref:`inst-config-files`.) - - -.. seealso:: - - `C++Builder Compiler <https://www.embarcadero.com/products>`_ - Information about the free C++ compiler from Borland, including links to the - download pages. - - `Creating Python Extensions Using Borland's Free Compiler <http://www.cyberus.ca/~g_will/pyExtenDL.shtml>`_ - Document describing how to use Borland's free command-line C++ compiler to build - Python. - - -GNU C / Cygwin / MinGW -^^^^^^^^^^^^^^^^^^^^^^ - -This section describes the necessary steps to use Distutils with the GNU C/C++ -compilers in their Cygwin and MinGW distributions. [#]_ For a Python interpreter -that was built with Cygwin, everything should work without any of these -following steps. - -Not all extensions can be built with MinGW or Cygwin, but many can. Extensions -most likely to not work are those that use C++ or depend on Microsoft Visual C -extensions. - -To let Distutils compile your extension with Cygwin you have to type:: - - python setup.py build --compiler=cygwin - -and for Cygwin in no-cygwin mode [#]_ or for MinGW type:: - - python setup.py build --compiler=mingw32 - -If you want to use any of these options/compilers as default, you should -consider writing it in your personal or system-wide configuration file for -Distutils (see section :ref:`inst-config-files`.) - -Older Versions of Python and MinGW -"""""""""""""""""""""""""""""""""" -The following instructions only apply if you're using a version of Python -inferior to 2.4.1 with a MinGW inferior to 3.0.0 (with -binutils-2.13.90-20030111-1). - -These compilers require some special libraries. This task is more complex than -for Borland's C++, because there is no program to convert the library. First -you have to create a list of symbols which the Python DLL exports. (You can find -a good program for this task at -https://sourceforge.net/projects/mingw/files/MinGW/Extension/pexports/). - -.. I don't understand what the next line means. --amk -.. (inclusive the references on data structures.) - -:: - - pexports python25.dll >python25.def - -The location of an installed :file:`python25.dll` will depend on the -installation options and the version and language of Windows. In a "just for -me" installation, it will appear in the root of the installation directory. In -a shared installation, it will be located in the system directory. - -Then you can create from these information an import library for gcc. :: - - /cygwin/bin/dlltool --dllname python25.dll --def python25.def --output-lib libpython25.a - -The resulting library has to be placed in the same directory as -:file:`python25.lib`. (Should be the :file:`libs` directory under your Python -installation directory.) - -If your extension uses other libraries (zlib,...) you might have to convert -them too. The converted files have to reside in the same directories as the -normal libraries do. - - -.. seealso:: - - `Building Python modules on MS Windows platform with MinGW <https://old.zope.dev/Members/als/tips/win32_mingw_modules>`_ - Information about building the required libraries for the MinGW environment. - - -.. rubric:: Footnotes - -.. [#] This also means you could replace all existing COFF-libraries with OMF-libraries - of the same name. - -.. [#] Check https://www.sourceware.org/cygwin/ for more information - -.. [#] Then you have no POSIX emulation available, but you also don't need - :file:`cygwin1.dll`. diff --git a/Doc/installing/index.rst b/Doc/installing/index.rst index e158bf1c..a46c1cae 100644 --- a/Doc/installing/index.rst +++ b/Doc/installing/index.rst @@ -19,7 +19,9 @@ solutions to the common pool. This guide covers the installation part of the process. For a guide to creating and sharing your own Python projects, refer to the -:ref:`distribution guide <distributing-index>`. +`Python packaging user guide`_. + +.. _Python Packaging User Guide: https://packaging.python.org/en/latest/tutorials/packaging-projects/ .. note:: @@ -52,8 +54,7 @@ Key terms developers and documentation authors responsible for the maintenance and evolution of the standard packaging tools and the associated metadata and file format standards. They maintain a variety of tools, documentation, - and issue trackers on both `GitHub <https://github.com/pypa>`__ and - `Bitbucket <https://bitbucket.org/pypa/>`__. + and issue trackers on `GitHub <https://github.com/pypa>`__. * ``distutils`` is the original build and distribution system first added to the Python standard library in 1998. While direct use of ``distutils`` is being phased out, it still laid the foundation for the current packaging diff --git a/Doc/library/__main__.rst b/Doc/library/__main__.rst index d0a65e76..d378e40b 100644 --- a/Doc/library/__main__.rst +++ b/Doc/library/__main__.rst @@ -61,7 +61,7 @@ The top-level code environment can be: .. code-block:: shell-session - $ python3 helloworld.py + $ python helloworld.py Hello, world! * the Python module or package passed to the Python interpreter with the @@ -69,14 +69,14 @@ The top-level code environment can be: .. code-block:: shell-session - $ python3 -m tarfile + $ python -m tarfile usage: tarfile.py [-h] [-v] (...) * Python code read by the Python interpreter from standard input: .. code-block:: shell-session - $ echo "import this" | python3 + $ echo "import this" | python The Zen of Python, by Tim Peters Beautiful is better than ugly. @@ -87,7 +87,7 @@ The top-level code environment can be: .. code-block:: shell-session - $ python3 -c "import this" + $ python -c "import this" The Zen of Python, by Tim Peters Beautiful is better than ugly. @@ -124,7 +124,7 @@ This is where using the ``if __name__ == '__main__'`` code block comes in handy. Code within this block won't run unless the module is executed in the top-level environment. -Putting as few statements as possible in the block below ``if __name___ == +Putting as few statements as possible in the block below ``if __name__ == '__main__'`` can improve code clarity and correctness. Most often, a function named ``main`` encapsulates the program's primary behavior:: @@ -178,7 +178,7 @@ that your function will return some value acceptable as an input to returned if your function does not have a return statement). By proactively following this convention ourselves, our module will have the -same behavior when run directly (i.e. ``python3 echo.py``) as it will have if +same behavior when run directly (i.e. ``python echo.py``) as it will have if we later package it as a console script entry-point in a pip-installable package. @@ -215,7 +215,7 @@ directly from the command line using the :option:`-m` flag. For example: .. code-block:: shell-session - $ python3 -m bandclass + $ python -m bandclass This command will cause ``__main__.py`` to run. How you utilize this mechanism will depend on the nature of the package you are writing, but in this @@ -238,9 +238,9 @@ package. For more details, see :ref:`intra-package-references` in the Idiomatic Usage ^^^^^^^^^^^^^^^ -The contents of ``__main__.py`` typically isn't fenced with -``if __name__ == '__main__'`` blocks. Instead, those files are kept short, -functions to execute from other modules. Those other modules can then be +The content of ``__main__.py`` typically isn't fenced with an +``if __name__ == '__main__'`` block. Instead, those files are kept +short and import functions to execute from other modules. Those other modules can then be easily unit-tested and are properly reusable. If used, an ``if __name__ == '__main__'`` block will still work as expected @@ -259,7 +259,7 @@ one mentioned below are preferred. See :mod:`venv` for an example of a package with a minimal ``__main__.py`` in the standard library. It doesn't contain a ``if __name__ == '__main__'`` - block. You can invoke it with ``python3 -m venv [directory]``. + block. You can invoke it with ``python -m venv [directory]``. See :mod:`runpy` for more details on the :option:`-m` flag to the interpreter executable. @@ -320,7 +320,7 @@ Now, if we started our program, the result would look like this: .. code-block:: shell-session - $ python3 start.py + $ python start.py Define the variable `my_name`! The exit code of the program would be 1, indicating an error. Uncommenting the @@ -329,19 +329,19 @@ status code 0, indicating success: .. code-block:: shell-session - $ python3 start.py + $ python start.py Dinsdale found in file /path/to/start.py Note that importing ``__main__`` doesn't cause any issues with unintentionally running top-level code meant for script use which is put in the ``if __name__ == "__main__"`` block of the ``start`` module. Why does this work? -Python inserts an empty ``__main__`` module in :attr:`sys.modules` at +Python inserts an empty ``__main__`` module in :data:`sys.modules` at interpreter startup, and populates it by running top-level code. In our example this is the ``start`` module which runs line by line and imports ``namely``. In turn, ``namely`` imports ``__main__`` (which is really ``start``). That's an import cycle! Fortunately, since the partially populated ``__main__`` -module is present in :attr:`sys.modules`, Python passes that to ``namely``. +module is present in :data:`sys.modules`, Python passes that to ``namely``. See :ref:`Special considerations for __main__ <import-dunder-main>` in the import system's reference for details on how this works. diff --git a/Doc/library/_thread.rst b/Doc/library/_thread.rst index ecd7a68e..0442c298 100644 --- a/Doc/library/_thread.rst +++ b/Doc/library/_thread.rst @@ -57,6 +57,8 @@ This module defines the following constants and functions: When the function raises a :exc:`SystemExit` exception, it is silently ignored. + .. audit-event:: _thread.start_new_thread function,args,kwargs start_new_thread + .. versionchanged:: 3.8 :func:`sys.unraisablehook` is now used to handle unhandled exceptions. @@ -68,10 +70,10 @@ This module defines the following constants and functions: there is no guarantee that the interruption will happen immediately. If given, *signum* is the number of the signal to simulate. - If *signum* is not given, :data:`signal.SIGINT` is simulated. + If *signum* is not given, :const:`signal.SIGINT` is simulated. If the given signal isn't handled by Python (it was set to - :data:`signal.SIG_DFL` or :data:`signal.SIG_IGN`), this function does + :const:`signal.SIG_DFL` or :const:`signal.SIG_IGN`), this function does nothing. .. versionchanged:: 3.10 @@ -118,7 +120,7 @@ This module defines the following constants and functions: Its value may be used to uniquely identify this particular thread system-wide (until the thread terminates, after which the value may be recycled by the OS). - .. availability:: Windows, FreeBSD, Linux, macOS, OpenBSD, NetBSD, AIX. + .. availability:: Windows, FreeBSD, Linux, macOS, OpenBSD, NetBSD, AIX, DragonFlyBSD. .. versionadded:: 3.8 @@ -148,8 +150,8 @@ This module defines the following constants and functions: .. data:: TIMEOUT_MAX The maximum value allowed for the *timeout* parameter of - :meth:`Lock.acquire`. Specifying a timeout greater than this value will - raise an :exc:`OverflowError`. + :meth:`Lock.acquire <threading.Lock.acquire>`. Specifying a timeout greater + than this value will raise an :exc:`OverflowError`. .. versionadded:: 3.2 @@ -206,7 +208,7 @@ In addition to these methods, lock objects can also be used via the **Caveats:** - .. index:: module: signal + .. index:: pair: module; signal * Threads interact strangely with interrupts: the :exc:`KeyboardInterrupt` exception will be received by an arbitrary thread. (When the :mod:`signal` @@ -215,8 +217,9 @@ In addition to these methods, lock objects can also be used via the * Calling :func:`sys.exit` or raising the :exc:`SystemExit` exception is equivalent to calling :func:`_thread.exit`. -* It is not possible to interrupt the :meth:`acquire` method on a lock --- the - :exc:`KeyboardInterrupt` exception will happen after the lock has been acquired. +* It is not possible to interrupt the :meth:`~threading.Lock.acquire` method on + a lock --- the :exc:`KeyboardInterrupt` exception will happen after the lock + has been acquired. * When the main thread exits, it is system defined whether the other threads survive. On most systems, they are killed without executing diff --git a/Doc/library/abc.rst b/Doc/library/abc.rst index 3b74622e..274b2d69 100644 --- a/Doc/library/abc.rst +++ b/Doc/library/abc.rst @@ -21,7 +21,7 @@ The :mod:`collections` module has some concrete classes that derive from ABCs; these can, of course, be further derived. In addition, the :mod:`collections.abc` submodule has some ABCs that can be used to test whether a class or instance provides a particular interface, for example, if it is -hashable or if it is a mapping. +:term:`hashable` or if it is a mapping. This module provides the metaclass :class:`ABCMeta` for defining ABCs and diff --git a/Doc/library/argparse.rst b/Doc/library/argparse.rst index eeb65160..fbffa71d 100644 --- a/Doc/library/argparse.rst +++ b/Doc/library/argparse.rst @@ -31,12 +31,12 @@ Core Functionality The :mod:`argparse` module's support for command-line interfaces is built around an instance of :class:`argparse.ArgumentParser`. It is a container for -argument specifications and has options that apply the parser as whole:: +argument specifications and has options that apply to the parser as whole:: parser = argparse.ArgumentParser( - prog = 'ProgramName', - description = 'What the program does', - epilog = 'Text at the bottom of help') + prog='ProgramName', + description='What the program does', + epilog='Text at the bottom of help') The :meth:`ArgumentParser.add_argument` method attaches individual argument specifications to the parser. It supports positional arguments, options that @@ -57,20 +57,20 @@ the extracted data in a :class:`argparse.Namespace` object:: Quick Links for add_argument() ------------------------------ -====================== =========================================================== ========================================================================================================================== -Name Description Values -====================== =========================================================== ========================================================================================================================== -action_ Specify how an argument should be handled ``'store'``, ``'store_const'``, ``'store_true'``, ``'append'``, ``'append_const'``, ``'count'``, ``'help'``, ``'version'`` -choices_ Limit values to a specific set of choices ``['foo', 'bar']``, ``range(1, 10)``, or :class:`~collections.abc.Container` instance -const_ Store a constant value -default_ Default value used when an argument is not provided Defaults to ``None`` -dest_ Specify the attribute name used in the result namespace -help_ Help message for an argument -metavar_ Alternate display name for the argument as shown in help -nargs_ Number of times the argument can be used :class:`int`, ``'?'``, ``'*'``, ``'+'``, or ``argparse.REMAINDER`` -required_ Indicate whether an argument is required or optional ``True`` or ``False`` -type_ Automatically convert an argument to the given type :class:`int`, :class:`float`, ``argparse.FileType('w')``, or callable function -====================== =========================================================== ========================================================================================================================== +============================ =========================================================== ========================================================================================================================== +Name Description Values +============================ =========================================================== ========================================================================================================================== +action_ Specify how an argument should be handled ``'store'``, ``'store_const'``, ``'store_true'``, ``'append'``, ``'append_const'``, ``'count'``, ``'help'``, ``'version'`` +choices_ Limit values to a specific set of choices ``['foo', 'bar']``, ``range(1, 10)``, or :class:`~collections.abc.Container` instance +const_ Store a constant value +default_ Default value used when an argument is not provided Defaults to ``None`` +dest_ Specify the attribute name used in the result namespace +help_ Help message for an argument +metavar_ Alternate display name for the argument as shown in help +nargs_ Number of times the argument can be used :class:`int`, ``'?'``, ``'*'``, or ``'+'`` +required_ Indicate whether an argument is required or optional ``True`` or ``False`` +:ref:`type <argparse-type>` Automatically convert an argument to the given type :class:`int`, :class:`float`, ``argparse.FileType('w')``, or callable function +============================ =========================================================== ========================================================================================================================== Example @@ -563,8 +563,9 @@ at the command line. If the ``fromfile_prefix_chars=`` argument is given to the specified characters will be treated as files, and will be replaced by the arguments they contain. For example:: - >>> with open('args.txt', 'w') as fp: + >>> with open('args.txt', 'w', encoding=sys.getfilesystemencoding()) as fp: ... fp.write('-f\nbar') + ... >>> parser = argparse.ArgumentParser(fromfile_prefix_chars='@') >>> parser.add_argument('-f') >>> parser.parse_args(['-f', 'foo', '@args.txt']) @@ -576,9 +577,18 @@ were in the same place as the original file referencing argument on the command line. So in the example above, the expression ``['-f', 'foo', '@args.txt']`` is considered equivalent to the expression ``['-f', 'foo', '-f', 'bar']``. +:class:`ArgumentParser` uses :term:`filesystem encoding and error handler` +to read the file containing arguments. + The ``fromfile_prefix_chars=`` argument defaults to ``None``, meaning that arguments will never be treated as file references. +.. versionchanged:: 3.12 + :class:`ArgumentParser` changed encoding and errors to read arguments files + from default (e.g. :func:`locale.getpreferredencoding(False) <locale.getpreferredencoding>` and + ``"strict"``) to :term:`filesystem encoding and error handler`. + Arguments file should be encoded in UTF-8 instead of ANSI Codepage on Windows. + argument_default ^^^^^^^^^^^^^^^^ @@ -952,8 +962,8 @@ nargs ArgumentParser objects usually associate a single command-line argument with a single action to be taken. The ``nargs`` keyword argument associates a -different number of command-line arguments with a single action. The supported -values are: +different number of command-line arguments with a single action. +See also :ref:`specifying-ambiguous-arguments`. The supported values are: * ``N`` (an integer). ``N`` arguments from the command line will be gathered together into a list. For example:: @@ -1122,7 +1132,7 @@ command-line argument was not present:: Namespace(foo='1') -.. _type: +.. _argparse-type: type ^^^^ @@ -1181,7 +1191,7 @@ done downstream after the arguments are parsed. For example, JSON or YAML conversions have complex error cases that require better reporting than can be given by the ``type`` keyword. A :exc:`~json.JSONDecodeError` would not be well formatted and a -:exc:`FileNotFound` exception would not be handled at all. +:exc:`FileNotFoundError` exception would not be handled at all. Even :class:`~argparse.FileType` has its limitations for use with the ``type`` keyword. If one argument uses *FileType* and then a subsequent argument fails, @@ -1435,7 +1445,7 @@ Action classes Action classes implement the Action API, a callable which returns a callable which processes arguments from the command-line. Any object which follows this API may be passed as the ``action`` parameter to -:meth:`add_argument`. +:meth:`~ArgumentParser.add_argument`. .. class:: Action(option_strings, dest, nargs=None, const=None, default=None, \ type=None, choices=None, required=False, help=None, \ @@ -1611,6 +1621,9 @@ argument:: >>> parser.parse_args(['--', '-f']) Namespace(foo='-f', one=None) +See also :ref:`the argparse howto on ambiguous arguments <specifying-ambiguous-arguments>` +for more details. + .. _prefix-matching: Argument abbreviations (prefix matching) @@ -1710,7 +1723,7 @@ Sub-commands :class:`ArgumentParser` supports the creation of such sub-commands with the :meth:`add_subparsers` method. The :meth:`add_subparsers` method is normally called with no arguments and returns a special action object. This object - has a single method, :meth:`~ArgumentParser.add_parser`, which takes a + has a single method, :meth:`~_SubParsersAction.add_parser`, which takes a command name and any :class:`ArgumentParser` constructor arguments, and returns an :class:`ArgumentParser` object that can be modified as usual. @@ -1776,7 +1789,7 @@ Sub-commands for that particular parser will be printed. The help message will not include parent parser or sibling parser messages. (A help message for each subparser command, however, can be given by supplying the ``help=`` argument - to :meth:`add_parser` as above.) + to :meth:`~_SubParsersAction.add_parser` as above.) :: @@ -1854,7 +1867,7 @@ Sub-commands ... >>> # create the top-level parser >>> parser = argparse.ArgumentParser() - >>> subparsers = parser.add_subparsers() + >>> subparsers = parser.add_subparsers(required=True) >>> >>> # create the parser for the "foo" command >>> parser_foo = subparsers.add_parser('foo') @@ -2020,7 +2033,26 @@ Mutual exclusion Note that currently mutually exclusive argument groups do not support the *title* and *description* arguments of - :meth:`~ArgumentParser.add_argument_group`. + :meth:`~ArgumentParser.add_argument_group`. However, a mutually exclusive + group can be added to an argument group that has a title and description. + For example:: + + >>> parser = argparse.ArgumentParser(prog='PROG') + >>> group = parser.add_argument_group('Group title', 'Group description') + >>> exclusive_group = group.add_mutually_exclusive_group(required=True) + >>> exclusive_group.add_argument('--foo', help='foo help') + >>> exclusive_group.add_argument('--bar', help='bar help') + >>> parser.print_help() + usage: PROG [-h] (--foo FOO | --bar BAR) + + options: + -h, --help show this help message and exit + + Group title: + Group description + + --foo FOO foo help + --bar BAR bar help .. versionchanged:: 3.11 Calling :meth:`add_argument_group` or :meth:`add_mutually_exclusive_group` @@ -2125,7 +2157,7 @@ the populated namespace and the list of remaining argument strings. .. warning:: :ref:`Prefix matching <prefix-matching>` rules apply to - :meth:`parse_known_args`. The parser may consume an option even if it's just + :meth:`~ArgumentParser.parse_known_args`. The parser may consume an option even if it's just a prefix of one of its known options, instead of leaving it in the remaining arguments list. @@ -2186,7 +2218,7 @@ support this parsing style. These parsers do not support all the argparse features, and will raise exceptions if unsupported features are used. In particular, subparsers, -``argparse.REMAINDER``, and mutually exclusive groups that include both +and mutually exclusive groups that include both optionals and positionals are not supported. The following example shows the difference between @@ -2263,3 +2295,17 @@ A partial upgrade path from :mod:`optparse` to :mod:`argparse`: * Replace the OptionParser constructor ``version`` argument with a call to ``parser.add_argument('--version', action='version', version='<the version>')``. + +Exceptions +---------- + +.. exception:: ArgumentError + + An error from creating or using an argument (optional or positional). + + The string value of this exception is the message, augmented with + information about the argument that caused it. + +.. exception:: ArgumentTypeError + + Raised when something goes wrong converting a command line string to a type. diff --git a/Doc/library/array.rst b/Doc/library/array.rst index 75c49e0f..d6cb8c62 100644 --- a/Doc/library/array.rst +++ b/Doc/library/array.rst @@ -51,9 +51,9 @@ Notes: It can be 16 bits or 32 bits depending on the platform. .. versionchanged:: 3.9 - ``array('u')`` now uses ``wchar_t`` as C type instead of deprecated + ``array('u')`` now uses :c:type:`wchar_t` as C type instead of deprecated ``Py_UNICODE``. This change doesn't affect its behavior because - ``Py_UNICODE`` is alias of ``wchar_t`` since Python 3.3. + ``Py_UNICODE`` is alias of :c:type:`wchar_t` since Python 3.3. .. deprecated-removed:: 3.3 4.0 diff --git a/Doc/library/ast.rst b/Doc/library/ast.rst index 3ed2c4fa..a7fa8074 100644 --- a/Doc/library/ast.rst +++ b/Doc/library/ast.rst @@ -146,6 +146,102 @@ Node classes Snakes <https://greentreesnakes.readthedocs.io/en/latest/>`__ project and all its contributors. + +.. _ast-root-nodes: + +Root nodes +^^^^^^^^^^ + +.. class:: Module(body, type_ignores) + + A Python module, as with :ref:`file input <file-input>`. + Node type generated by :func:`ast.parse` in the default ``"exec"`` *mode*. + + *body* is a :class:`list` of the module's :ref:`ast-statements`. + + *type_ignores* is a :class:`list` of the module's type ignore comments; + see :func:`ast.parse` for more details. + + .. doctest:: + + >>> print(ast.dump(ast.parse('x = 1'), indent=4)) + Module( + body=[ + Assign( + targets=[ + Name(id='x', ctx=Store())], + value=Constant(value=1))], + type_ignores=[]) + + +.. class:: Expression(body) + + A single Python :ref:`expression input <expression-input>`. + Node type generated by :func:`ast.parse` when *mode* is ``"eval"``. + + *body* is a single node, + one of the :ref:`expression types <ast-expressions>`. + + .. doctest:: + + >>> print(ast.dump(ast.parse('123', mode='eval'), indent=4)) + Expression( + body=Constant(value=123)) + + +.. class:: Interactive(body) + + A single :ref:`interactive input <interactive>`, like in :ref:`tut-interac`. + Node type generated by :func:`ast.parse` when *mode* is ``"single"``. + + *body* is a :class:`list` of :ref:`statement nodes <ast-statements>`. + + .. doctest:: + + >>> print(ast.dump(ast.parse('x = 1; y = 2', mode='single'), indent=4)) + Interactive( + body=[ + Assign( + targets=[ + Name(id='x', ctx=Store())], + value=Constant(value=1)), + Assign( + targets=[ + Name(id='y', ctx=Store())], + value=Constant(value=2))]) + + +.. class:: FunctionType(argtypes, returns) + + A representation of an old-style type comments for functions, + as Python versions prior to 3.5 didn't support :pep:`484` annotations. + Node type generated by :func:`ast.parse` when *mode* is ``"func_type"``. + + Such type comments would look like this:: + + def sum_two_number(a, b): + # type: (int, int) -> int + return a + b + + *argtypes* is a :class:`list` of :ref:`expression nodes <ast-expressions>`. + + *returns* is a single :ref:`expression node <ast-expressions>`. + + .. doctest:: + + >>> print(ast.dump(ast.parse('(int, str) -> List[int]', mode='func_type'), indent=4)) + FunctionType( + argtypes=[ + Name(id='int', ctx=Load()), + Name(id='str', ctx=Load())], + returns=Subscript( + value=Name(id='List', ctx=Load()), + slice=Name(id='int', ctx=Load()), + ctx=Load())) + + .. versionadded:: 3.8 + + Literals ^^^^^^^^ @@ -344,6 +440,8 @@ Variables type_ignores=[]) +.. _ast-expressions: + Expressions ^^^^^^^^^^^ @@ -481,17 +579,17 @@ Expressions Comparison operator tokens. -.. class:: Call(func, args, keywords, starargs, kwargs) +.. class:: Call(func, args, keywords) A function call. ``func`` is the function, which will often be a :class:`Name` or :class:`Attribute` object. Of the arguments: * ``args`` holds a list of the arguments passed by position. - * ``keywords`` holds a list of :class:`keyword` objects representing + * ``keywords`` holds a list of :class:`.keyword` objects representing arguments passed by keyword. When creating a ``Call`` node, ``args`` and ``keywords`` are required, but - they can be empty lists. ``starargs`` and ``kwargs`` are optional. + they can be empty lists. .. doctest:: @@ -552,10 +650,10 @@ Expressions .. class:: NamedExpr(target, value) - A named expression. This AST node is produced by the assignment expressions - operator (also known as the walrus operator). As opposed to the :class:`Assign` - node in which the first argument can be multiple nodes, in this case both - ``target`` and ``value`` must be single nodes. + A named expression. This AST node is produced by the assignment expressions + operator (also known as the walrus operator). As opposed to the :class:`Assign` + node in which the first argument can be multiple nodes, in this case both + ``target`` and ``value`` must be single nodes. .. doctest:: @@ -565,6 +663,7 @@ Expressions target=Name(id='x', ctx=Store()), value=Constant(value=4))) + .. versionadded:: 3.8 Subscripting ~~~~~~~~~~~~ @@ -735,6 +834,9 @@ Comprehensions ifs=[], is_async=1)])) + +.. _ast-statements: + Statements ^^^^^^^^^^ @@ -917,6 +1019,26 @@ Statements type_ignores=[]) +.. class:: TypeAlias(name, type_params, value) + + A :ref:`type alias <type-aliases>` created through the :keyword:`type` + statement. ``name`` is the name of the alias, ``type_params`` is a list of + :ref:`type parameters <ast-type-params>`, and ``value`` is the value of the + type alias. + + .. doctest:: + + >>> print(ast.dump(ast.parse('type Alias = int'), indent=4)) + Module( + body=[ + TypeAlias( + name=Name(id='Alias', ctx=Store()), + type_params=[], + value=Name(id='int', ctx=Load()))], + type_ignores=[]) + + .. versionadded:: 3.12 + Other statements which are only applicable inside functions or loops are described in other sections. @@ -1028,10 +1150,11 @@ Control flow .. class:: For(target, iter, body, orelse, type_comment) A ``for`` loop. ``target`` holds the variable(s) the loop assigns to, as a - single :class:`Name`, :class:`Tuple` or :class:`List` node. ``iter`` holds - the item to be looped over, again as a single node. ``body`` and ``orelse`` - contain lists of nodes to execute. Those in ``orelse`` are executed if the - loop finishes normally, rather than via a ``break`` statement. + single :class:`Name`, :class:`Tuple`, :class:`List`, :class:`Attribute` or + :class:`Subscript` node. ``iter`` holds the item to be looped over, again + as a single node. ``body`` and ``orelse`` contain lists of nodes to execute. + Those in ``orelse`` are executed if the loop finishes normally, rather than + via a ``break`` statement. .. attribute:: type_comment @@ -1197,6 +1320,7 @@ Control flow finalbody=[])], type_ignores=[]) + .. versionadded:: 3.11 .. class:: ExceptHandler(type, name, body) @@ -1286,6 +1410,8 @@ Pattern matching that is being matched against the cases) and ``cases`` contains an iterable of :class:`match_case` nodes with the different cases. + .. versionadded:: 3.10 + .. class:: match_case(pattern, guard, body) A single case pattern in a ``match`` statement. ``pattern`` contains the @@ -1337,6 +1463,8 @@ Pattern matching value=Constant(value=Ellipsis))])])], type_ignores=[]) + .. versionadded:: 3.10 + .. class:: MatchValue(value) A match literal or value pattern that compares by equality. ``value`` is @@ -1364,6 +1492,8 @@ Pattern matching value=Constant(value=Ellipsis))])])], type_ignores=[]) + .. versionadded:: 3.10 + .. class:: MatchSingleton(value) A match literal pattern that compares by identity. ``value`` is the @@ -1389,6 +1519,8 @@ Pattern matching value=Constant(value=Ellipsis))])])], type_ignores=[]) + .. versionadded:: 3.10 + .. class:: MatchSequence(patterns) A match sequence pattern. ``patterns`` contains the patterns to be matched @@ -1420,6 +1552,8 @@ Pattern matching value=Constant(value=Ellipsis))])])], type_ignores=[]) + .. versionadded:: 3.10 + .. class:: MatchStar(name) Matches the rest of the sequence in a variable length match sequence pattern. @@ -1460,6 +1594,8 @@ Pattern matching value=Constant(value=Ellipsis))])])], type_ignores=[]) + .. versionadded:: 3.10 + .. class:: MatchMapping(keys, patterns, rest) A match mapping pattern. ``keys`` is a sequence of expression nodes. @@ -1506,6 +1642,8 @@ Pattern matching value=Constant(value=Ellipsis))])])], type_ignores=[]) + .. versionadded:: 3.10 + .. class:: MatchClass(cls, patterns, kwd_attrs, kwd_patterns) A match class pattern. ``cls`` is an expression giving the nominal class to @@ -1570,6 +1708,8 @@ Pattern matching value=Constant(value=Ellipsis))])])], type_ignores=[]) + .. versionadded:: 3.10 + .. class:: MatchAs(pattern, name) A match "as-pattern", capture pattern or wildcard pattern. ``pattern`` @@ -1611,6 +1751,8 @@ Pattern matching value=Constant(value=Ellipsis))])])], type_ignores=[]) + .. versionadded:: 3.10 + .. class:: MatchOr(patterns) A match "or-pattern". An or-pattern matches each of its subpatterns in turn @@ -1643,11 +1785,96 @@ Pattern matching value=Constant(value=Ellipsis))])])], type_ignores=[]) + .. versionadded:: 3.10 + +.. _ast-type-params: + +Type parameters +^^^^^^^^^^^^^^^ + +:ref:`Type parameters <type-params>` can exist on classes, functions, and type +aliases. + +.. class:: TypeVar(name, bound) + + A :class:`typing.TypeVar`. ``name`` is the name of the type variable. + ``bound`` is the bound or constraints, if any. If ``bound`` is a :class:`Tuple`, + it represents constraints; otherwise it represents the bound. + + .. doctest:: + + >>> print(ast.dump(ast.parse("type Alias[T: int] = list[T]"), indent=4)) + Module( + body=[ + TypeAlias( + name=Name(id='Alias', ctx=Store()), + type_params=[ + TypeVar( + name='T', + bound=Name(id='int', ctx=Load()))], + value=Subscript( + value=Name(id='list', ctx=Load()), + slice=Name(id='T', ctx=Load()), + ctx=Load()))], + type_ignores=[]) + + .. versionadded:: 3.12 + +.. class:: ParamSpec(name) + + A :class:`typing.ParamSpec`. ``name`` is the name of the parameter specification. + + .. doctest:: + + >>> print(ast.dump(ast.parse("type Alias[**P] = Callable[P, int]"), indent=4)) + Module( + body=[ + TypeAlias( + name=Name(id='Alias', ctx=Store()), + type_params=[ + ParamSpec(name='P')], + value=Subscript( + value=Name(id='Callable', ctx=Load()), + slice=Tuple( + elts=[ + Name(id='P', ctx=Load()), + Name(id='int', ctx=Load())], + ctx=Load()), + ctx=Load()))], + type_ignores=[]) + + .. versionadded:: 3.12 + +.. class:: TypeVarTuple(name) + + A :class:`typing.TypeVarTuple`. ``name`` is the name of the type variable tuple. + + .. doctest:: + + >>> print(ast.dump(ast.parse("type Alias[*Ts] = tuple[*Ts]"), indent=4)) + Module( + body=[ + TypeAlias( + name=Name(id='Alias', ctx=Store()), + type_params=[ + TypeVarTuple(name='Ts')], + value=Subscript( + value=Name(id='tuple', ctx=Load()), + slice=Tuple( + elts=[ + Starred( + value=Name(id='Ts', ctx=Load()), + ctx=Load())], + ctx=Load()), + ctx=Load()))], + type_ignores=[]) + + .. versionadded:: 3.12 Function and class definitions ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. class:: FunctionDef(name, args, body, decorator_list, returns, type_comment) +.. class:: FunctionDef(name, args, body, decorator_list, returns, type_comment, type_params) A function definition. @@ -1657,11 +1884,15 @@ Function and class definitions * ``decorator_list`` is the list of decorators to be applied, stored outermost first (i.e. the first in the list will be applied last). * ``returns`` is the return annotation. + * ``type_params`` is a list of :ref:`type parameters <ast-type-params>`. .. attribute:: type_comment ``type_comment`` is an optional string with the type annotation as a comment. + .. versionchanged:: 3.12 + Added ``type_params``. + .. class:: Lambda(args, body) @@ -1747,7 +1978,8 @@ Function and class definitions decorator_list=[ Name(id='decorator1', ctx=Load()), Name(id='decorator2', ctx=Load())], - returns=Constant(value='return annotation'))], + returns=Constant(value='return annotation'), + type_params=[])], type_ignores=[]) @@ -1818,21 +2050,19 @@ Function and class definitions type_ignores=[]) -.. class:: ClassDef(name, bases, keywords, starargs, kwargs, body, decorator_list) +.. class:: ClassDef(name, bases, keywords, body, decorator_list, type_params) A class definition. * ``name`` is a raw string for the class name * ``bases`` is a list of nodes for explicitly specified base classes. - * ``keywords`` is a list of :class:`keyword` nodes, principally for 'metaclass'. + * ``keywords`` is a list of :class:`.keyword` nodes, principally for 'metaclass'. Other keywords will be passed to the metaclass, as per `PEP-3115 <https://peps.python.org/pep-3115/>`_. - * ``starargs`` and ``kwargs`` are each a single node, as in a function call. - starargs will be expanded to join the list of base classes, and kwargs will - be passed to the metaclass. * ``body`` is a list of nodes representing the code within the class definition. * ``decorator_list`` is a list of nodes, as in :class:`FunctionDef`. + * ``type_params`` is a list of :ref:`type parameters <ast-type-params>`. .. doctest:: @@ -1857,17 +2087,24 @@ Function and class definitions Pass()], decorator_list=[ Name(id='decorator1', ctx=Load()), - Name(id='decorator2', ctx=Load())])], + Name(id='decorator2', ctx=Load())], + type_params=[])], type_ignores=[]) + .. versionchanged:: 3.12 + Added ``type_params``. + Async and await ^^^^^^^^^^^^^^^ -.. class:: AsyncFunctionDef(name, args, body, decorator_list, returns, type_comment) +.. class:: AsyncFunctionDef(name, args, body, decorator_list, returns, type_comment, type_params) An ``async def`` function definition. Has the same fields as :class:`FunctionDef`. + .. versionchanged:: 3.12 + Added ``type_params``. + .. class:: Await(value) @@ -1897,7 +2134,8 @@ Async and await func=Name(id='other_func', ctx=Load()), args=[], keywords=[])))], - decorator_list=[])], + decorator_list=[], + type_params=[])], type_ignores=[]) diff --git a/Doc/library/asynchat.rst b/Doc/library/asynchat.rst deleted file mode 100644 index 32e04ad6..00000000 --- a/Doc/library/asynchat.rst +++ /dev/null @@ -1,217 +0,0 @@ -:mod:`asynchat` --- Asynchronous socket command/response handler -================================================================ - -.. module:: asynchat - :synopsis: Support for asynchronous command/response protocols. - :deprecated: - -.. moduleauthor:: Sam Rushing <rushing@nightmare.com> -.. sectionauthor:: Steve Holden <sholden@holdenweb.com> - -**Source code:** :source:`Lib/asynchat.py` - -.. deprecated-removed:: 3.6 3.12 - The :mod:`asynchat` module is deprecated - (see :pep:`PEP 594 <594#asynchat>` for details). - Please use :mod:`asyncio` instead. - --------------- - -.. note:: - - This module exists for backwards compatibility only. For new code we - recommend using :mod:`asyncio`. - -This module builds on the :mod:`asyncore` infrastructure, simplifying -asynchronous clients and servers and making it easier to handle protocols -whose elements are terminated by arbitrary strings, or are of variable length. -:mod:`asynchat` defines the abstract class :class:`async_chat` that you -subclass, providing implementations of the :meth:`collect_incoming_data` and -:meth:`found_terminator` methods. It uses the same asynchronous loop as -:mod:`asyncore`, and the two types of channel, :class:`asyncore.dispatcher` -and :class:`asynchat.async_chat`, can freely be mixed in the channel map. -Typically an :class:`asyncore.dispatcher` server channel generates new -:class:`asynchat.async_chat` channel objects as it receives incoming -connection requests. - -.. include:: ../includes/wasm-notavail.rst - -.. class:: async_chat() - - This class is an abstract subclass of :class:`asyncore.dispatcher`. To make - practical use of the code you must subclass :class:`async_chat`, providing - meaningful :meth:`collect_incoming_data` and :meth:`found_terminator` - methods. - The :class:`asyncore.dispatcher` methods can be used, although not all make - sense in a message/response context. - - Like :class:`asyncore.dispatcher`, :class:`async_chat` defines a set of - events that are generated by an analysis of socket conditions after a - :c:func:`select` call. Once the polling loop has been started the - :class:`async_chat` object's methods are called by the event-processing - framework with no action on the part of the programmer. - - Two class attributes can be modified, to improve performance, or possibly - even to conserve memory. - - - .. data:: ac_in_buffer_size - - The asynchronous input buffer size (default ``4096``). - - - .. data:: ac_out_buffer_size - - The asynchronous output buffer size (default ``4096``). - - Unlike :class:`asyncore.dispatcher`, :class:`async_chat` allows you to - define a :abbr:`FIFO (first-in, first-out)` queue of *producers*. A producer need - have only one method, :meth:`more`, which should return data to be - transmitted on the channel. - The producer indicates exhaustion (*i.e.* that it contains no more data) by - having its :meth:`more` method return the empty bytes object. At this point - the :class:`async_chat` object removes the producer from the queue and starts - using the next producer, if any. When the producer queue is empty the - :meth:`handle_write` method does nothing. You use the channel object's - :meth:`set_terminator` method to describe how to recognize the end of, or - an important breakpoint in, an incoming transmission from the remote - endpoint. - - To build a functioning :class:`async_chat` subclass your input methods - :meth:`collect_incoming_data` and :meth:`found_terminator` must handle the - data that the channel receives asynchronously. The methods are described - below. - - -.. method:: async_chat.close_when_done() - - Pushes a ``None`` on to the producer queue. When this producer is popped off - the queue it causes the channel to be closed. - - -.. method:: async_chat.collect_incoming_data(data) - - Called with *data* holding an arbitrary amount of received data. The - default method, which must be overridden, raises a - :exc:`NotImplementedError` exception. - - -.. method:: async_chat.discard_buffers() - - In emergencies this method will discard any data held in the input and/or - output buffers and the producer queue. - - -.. method:: async_chat.found_terminator() - - Called when the incoming data stream matches the termination condition set - by :meth:`set_terminator`. The default method, which must be overridden, - raises a :exc:`NotImplementedError` exception. The buffered input data - should be available via an instance attribute. - - -.. method:: async_chat.get_terminator() - - Returns the current terminator for the channel. - - -.. method:: async_chat.push(data) - - Pushes data on to the channel's queue to ensure its transmission. - This is all you need to do to have the channel write the data out to the - network, although it is possible to use your own producers in more complex - schemes to implement encryption and chunking, for example. - - -.. method:: async_chat.push_with_producer(producer) - - Takes a producer object and adds it to the producer queue associated with - the channel. When all currently pushed producers have been exhausted the - channel will consume this producer's data by calling its :meth:`more` - method and send the data to the remote endpoint. - - -.. method:: async_chat.set_terminator(term) - - Sets the terminating condition to be recognized on the channel. ``term`` - may be any of three types of value, corresponding to three different ways - to handle incoming protocol data. - - +-----------+---------------------------------------------+ - | term | Description | - +===========+=============================================+ - | *string* | Will call :meth:`found_terminator` when the | - | | string is found in the input stream | - +-----------+---------------------------------------------+ - | *integer* | Will call :meth:`found_terminator` when the | - | | indicated number of characters have been | - | | received | - +-----------+---------------------------------------------+ - | ``None`` | The channel continues to collect data | - | | forever | - +-----------+---------------------------------------------+ - - Note that any data following the terminator will be available for reading - by the channel after :meth:`found_terminator` is called. - - -.. _asynchat-example: - -asynchat Example ----------------- - -The following partial example shows how HTTP requests can be read with -:class:`async_chat`. A web server might create an -:class:`http_request_handler` object for each incoming client connection. -Notice that initially the channel terminator is set to match the blank line at -the end of the HTTP headers, and a flag indicates that the headers are being -read. - -Once the headers have been read, if the request is of type POST (indicating -that further data are present in the input stream) then the -``Content-Length:`` header is used to set a numeric terminator to read the -right amount of data from the channel. - -The :meth:`handle_request` method is called once all relevant input has been -marshalled, after setting the channel terminator to ``None`` to ensure that -any extraneous data sent by the web client are ignored. :: - - - import asynchat - - class http_request_handler(asynchat.async_chat): - - def __init__(self, sock, addr, sessions, log): - asynchat.async_chat.__init__(self, sock=sock) - self.addr = addr - self.sessions = sessions - self.ibuffer = [] - self.obuffer = b"" - self.set_terminator(b"\r\n\r\n") - self.reading_headers = True - self.handling = False - self.cgi_data = None - self.log = log - - def collect_incoming_data(self, data): - """Buffer the data""" - self.ibuffer.append(data) - - def found_terminator(self): - if self.reading_headers: - self.reading_headers = False - self.parse_headers(b"".join(self.ibuffer)) - self.ibuffer = [] - if self.op.upper() == b"POST": - clen = self.headers.getheader("content-length") - self.set_terminator(int(clen)) - else: - self.handling = True - self.set_terminator(None) - self.handle_request() - elif not self.handling: - self.set_terminator(None) # browsers sometimes over-send - self.cgi_data = parse(self.headers, b"".join(self.ibuffer)) - self.handling = True - self.ibuffer = [] - self.handle_request() diff --git a/Doc/library/asyncio-dev.rst b/Doc/library/asyncio-dev.rst index 921a394a..a9c3a018 100644 --- a/Doc/library/asyncio-dev.rst +++ b/Doc/library/asyncio-dev.rst @@ -34,7 +34,7 @@ There are several ways to enable asyncio debug mode: In addition to enabling the debug mode, consider also: * setting the log level of the :ref:`asyncio logger <asyncio-logger>` to - :py:data:`logging.DEBUG`, for example the following snippet of code + :py:const:`logging.DEBUG`, for example the following snippet of code can be run at startup of the application:: logging.basicConfig(level=logging.DEBUG) @@ -99,7 +99,7 @@ To schedule a coroutine object from a different OS thread, the # Wait for the result: result = future.result() -To handle signals and to execute subprocesses, the event loop must be +To handle signals the event loop must be run in the main thread. The :meth:`loop.run_in_executor` method can be used with a @@ -142,7 +142,7 @@ Logging asyncio uses the :mod:`logging` module and all logging is performed via the ``"asyncio"`` logger. -The default log level is :py:data:`logging.INFO`, which can be easily +The default log level is :py:const:`logging.INFO`, which can be easily adjusted:: logging.getLogger("asyncio").setLevel(logging.WARNING) diff --git a/Doc/library/asyncio-eventloop.rst b/Doc/library/asyncio-eventloop.rst index c7343826..04af53b9 100644 --- a/Doc/library/asyncio-eventloop.rst +++ b/Doc/library/asyncio-eventloop.rst @@ -59,14 +59,8 @@ an event loop: instead of using these lower level functions to manually create and close an event loop. - .. note:: - In Python versions 3.10.0--3.10.8 and 3.11.0 this function - (and other functions which use it implicitly) emitted a - :exc:`DeprecationWarning` if there was no running event loop, even if - the current loop was set on the policy. - In Python versions 3.10.9, 3.11.1 and 3.12 they emit a - :exc:`DeprecationWarning` if there is no running event loop and no - current loop is set. + .. deprecated:: 3.12 + Deprecation warning is emitted if there is no current event loop. In some future Python release this will become an error. .. function:: set_event_loop(loop) @@ -189,18 +183,32 @@ Running and stopping the loop .. versionadded:: 3.6 -.. coroutinemethod:: loop.shutdown_default_executor() +.. coroutinemethod:: loop.shutdown_default_executor(timeout=None) Schedule the closure of the default executor and wait for it to join all of - the threads in the :class:`ThreadPoolExecutor`. After calling this method, a - :exc:`RuntimeError` will be raised if :meth:`loop.run_in_executor` is called - while using the default executor. + the threads in the :class:`~concurrent.futures.ThreadPoolExecutor`. + Once this method has been called, + using the default executor with :meth:`loop.run_in_executor` + will raise a :exc:`RuntimeError`. - Note that there is no need to call this function when - :func:`asyncio.run` is used. + The *timeout* parameter specifies the amount of time + (in :class:`float` seconds) the executor will be given to finish joining. + With the default, ``None``, + the executor is allowed an unlimited amount of time. + + If the *timeout* is reached, a :exc:`RuntimeWarning` is emitted + and the default executor is terminated + without waiting for its threads to finish joining. + + .. note:: + + Do not call this method when using :func:`asyncio.run`, + as the latter handles default executor shutdown automatically. .. versionadded:: 3.9 + .. versionchanged:: 3.12 + Added the *timeout* parameter. Scheduling callbacks ^^^^^^^^^^^^^^^^^^^^ @@ -210,22 +218,23 @@ Scheduling callbacks Schedule the *callback* :term:`callback` to be called with *args* arguments at the next iteration of the event loop. + Return an instance of :class:`asyncio.Handle`, + which can be used later to cancel the callback. + Callbacks are called in the order in which they are registered. Each callback will be called exactly once. - An optional keyword-only *context* argument allows specifying a + The optional keyword-only *context* argument specifies a custom :class:`contextvars.Context` for the *callback* to run in. - The current context is used when no *context* is provided. - - An instance of :class:`asyncio.Handle` is returned, which can be - used later to cancel the callback. + Callbacks use the current context when no *context* is provided. - This method is not thread-safe. + Unlike :meth:`call_soon_threadsafe`, this method is not thread-safe. .. method:: loop.call_soon_threadsafe(callback, *args, context=None) - A thread-safe variant of :meth:`call_soon`. Must be used to - schedule callbacks *from another thread*. + A thread-safe variant of :meth:`call_soon`. When scheduling callbacks from + another thread, this function *must* be used, since :meth:`call_soon` is not + thread-safe. Raises :exc:`RuntimeError` if called on a loop that's been closed. This can happen on a secondary thread when the main application is @@ -388,16 +397,17 @@ Opening network connections local_addr=None, server_hostname=None, \ ssl_handshake_timeout=None, \ ssl_shutdown_timeout=None, \ - happy_eyeballs_delay=None, interleave=None) + happy_eyeballs_delay=None, interleave=None, \ + all_errors=False) Open a streaming transport connection to a given address specified by *host* and *port*. - The socket family can be either :py:data:`~socket.AF_INET` or - :py:data:`~socket.AF_INET6` depending on *host* (or the *family* + The socket family can be either :py:const:`~socket.AF_INET` or + :py:const:`~socket.AF_INET6` depending on *host* (or the *family* argument, if provided). - The socket type will be :py:data:`~socket.SOCK_STREAM`. + The socket type will be :py:const:`~socket.SOCK_STREAM`. *protocol_factory* must be a callable returning an :ref:`asyncio protocol <asyncio-protocol>` implementation. @@ -485,13 +495,21 @@ Opening network connections to complete before aborting the connection. ``30.0`` seconds if ``None`` (default). + * *all_errors* determines what exceptions are raised when a connection cannot + be created. By default, only a single ``Exception`` is raised: the first + exception if there is only one or all errors have same message, or a single + ``OSError`` with the error messages combined. When ``all_errors`` is ``True``, + an ``ExceptionGroup`` will be raised containing all exceptions (even if there + is only one). + + .. versionchanged:: 3.5 Added support for SSL/TLS in :class:`ProactorEventLoop`. .. versionchanged:: 3.6 - The socket option :py:data:`~socket.TCP_NODELAY` is set by default + The socket option :py:const:`~socket.TCP_NODELAY` is set by default for all TCP connections. .. versionchanged:: 3.7 @@ -506,17 +524,20 @@ Opening network connections When a server's IPv4 path and protocol are working, but the server's IPv6 path and protocol are not working, a dual-stack client application experiences significant connection delay compared to an - IPv4-only client. This is undesirable because it causes the dual- - stack client to have a worse user experience. This document + IPv4-only client. This is undesirable because it causes the + dual-stack client to have a worse user experience. This document specifies requirements for algorithms that reduce this user-visible delay and provides an algorithm. - For more information: https://tools.ietf.org/html/rfc6555 + For more information: https://datatracker.ietf.org/doc/html/rfc6555 .. versionchanged:: 3.11 Added the *ssl_shutdown_timeout* parameter. + .. versionchanged:: 3.12 + *all_errors* was added. + .. seealso:: The :func:`open_connection` function is a high-level alternative @@ -531,11 +552,11 @@ Opening network connections Create a datagram connection. - The socket family can be either :py:data:`~socket.AF_INET`, - :py:data:`~socket.AF_INET6`, or :py:data:`~socket.AF_UNIX`, + The socket family can be either :py:const:`~socket.AF_INET`, + :py:const:`~socket.AF_INET6`, or :py:const:`~socket.AF_UNIX`, depending on *host* (or the *family* argument, if provided). - The socket type will be :py:data:`~socket.SOCK_DGRAM`. + The socket type will be :py:const:`~socket.SOCK_DGRAM`. *protocol_factory* must be a callable returning a :ref:`protocol <asyncio-protocol>` implementation. @@ -560,7 +581,7 @@ Opening network connections * *reuse_port* tells the kernel to allow this endpoint to be bound to the same port as other existing endpoints are bound to, so long as they all set this flag when being created. This option is not supported on Windows - and some Unixes. If the :py:data:`~socket.SO_REUSEPORT` constant is not + and some Unixes. If the :py:const:`~socket.SO_REUSEPORT` constant is not defined then this capability is unsupported. * *allow_broadcast* tells the kernel to allow this endpoint to send @@ -586,7 +607,7 @@ Opening network connections .. versionchanged:: 3.8.1 The *reuse_address* parameter is no longer supported, as using - :py:data:`~sockets.SO_REUSEADDR` poses a significant security concern for + :py:const:`~sockets.SO_REUSEADDR` poses a significant security concern for UDP. Explicitly passing ``reuse_address=True`` will raise an exception. When multiple processes with differing UIDs assign sockets to an @@ -595,7 +616,7 @@ Opening network connections For supported platforms, *reuse_port* can be used as a replacement for similar functionality. With *reuse_port*, - :py:data:`~sockets.SO_REUSEPORT` is used instead, which specifically + :py:const:`~sockets.SO_REUSEPORT` is used instead, which specifically prevents processes with differing UIDs from assigning sockets to the same socket address. @@ -613,8 +634,8 @@ Opening network connections Create a Unix connection. - The socket family will be :py:data:`~socket.AF_UNIX`; socket - type will be :py:data:`~socket.SOCK_STREAM`. + The socket family will be :py:const:`~socket.AF_UNIX`; socket + type will be :py:const:`~socket.SOCK_STREAM`. A tuple of ``(transport, protocol)`` is returned on success. @@ -650,7 +671,7 @@ Creating network servers ssl_shutdown_timeout=None, \ start_serving=True) - Create a TCP server (socket type :data:`~socket.SOCK_STREAM`) listening + Create a TCP server (socket type :const:`~socket.SOCK_STREAM`) listening on *port* of the *host* address. Returns a :class:`Server` object. @@ -678,10 +699,10 @@ Creating network servers be selected (note that if *host* resolves to multiple network interfaces, a different random port will be selected for each interface). - * *family* can be set to either :data:`socket.AF_INET` or - :data:`~socket.AF_INET6` to force the socket to use IPv4 or IPv6. + * *family* can be set to either :const:`socket.AF_INET` or + :const:`~socket.AF_INET6` to force the socket to use IPv4 or IPv6. If not set, the *family* will be determined from host name - (defaults to :data:`~socket.AF_UNSPEC`). + (defaults to :const:`~socket.AF_UNSPEC`). * *flags* is a bitmask for :meth:`getaddrinfo`. @@ -735,7 +756,7 @@ Creating network servers .. versionchanged:: 3.6 Added *ssl_handshake_timeout* and *start_serving* parameters. - The socket option :py:data:`~socket.TCP_NODELAY` is set by default + The socket option :py:const:`~socket.TCP_NODELAY` is set by default for all TCP connections. .. versionchanged:: 3.11 @@ -756,7 +777,7 @@ Creating network servers start_serving=True) Similar to :meth:`loop.create_server` but works with the - :py:data:`~socket.AF_UNIX` socket family. + :py:const:`~socket.AF_UNIX` socket family. *path* is the name of a Unix domain socket, and is required, unless a *sock* argument is provided. Abstract Unix sockets, @@ -874,6 +895,9 @@ TLS Upgrade object only because the coder caches *protocol*-side data and sporadically exchanges extra TLS session packets with *transport*. + In some situations (e.g. when the passed transport is already closing) this + may return ``None``. + Parameters: * *transport* and *protocol* instances that methods like @@ -1296,6 +1320,15 @@ Allows customizing how exceptions are handled in the event loop. (see :meth:`call_exception_handler` documentation for details about context). + If the handler is called on behalf of a :class:`~asyncio.Task` or + :class:`~asyncio.Handle`, it is run in the + :class:`contextvars.Context` of that task or callback handle. + + .. versionchanged:: 3.12 + + The handler may be called in the :class:`~contextvars.Context` + of the task or handle where the exception originated. + .. method:: loop.get_exception_handler() Return the current exception handler, or ``None`` if no custom @@ -1408,9 +1441,8 @@ async/await code consider using the high-level * *stdin* can be any of these: - * a file-like object representing a pipe to be connected to the - subprocess's standard input stream using - :meth:`~loop.connect_write_pipe` + * a file-like object + * an existing file descriptor (a positive integer), for example those created with :meth:`os.pipe()` * the :const:`subprocess.PIPE` constant (default) which will create a new pipe and connect it, * the value ``None`` which will make the subprocess inherit the file @@ -1420,9 +1452,7 @@ async/await code consider using the high-level * *stdout* can be any of these: - * a file-like object representing a pipe to be connected to the - subprocess's standard output stream using - :meth:`~loop.connect_write_pipe` + * a file-like object * the :const:`subprocess.PIPE` constant (default) which will create a new pipe and connect it, * the value ``None`` which will make the subprocess inherit the file @@ -1432,9 +1462,7 @@ async/await code consider using the high-level * *stderr* can be any of these: - * a file-like object representing a pipe to be connected to the - subprocess's standard error stream using - :meth:`~loop.connect_write_pipe` + * a file-like object * the :const:`subprocess.PIPE` constant (default) which will create a new pipe and connect it, * the value ``None`` which will make the subprocess inherit the file @@ -1453,6 +1481,11 @@ async/await code consider using the high-level as text. :func:`bytes.decode` can be used to convert the bytes returned from the stream to text. + If a file-like object passed as *stdin*, *stdout* or *stderr* represents a + pipe, then the other side of this pipe should be registered with + :meth:`~loop.connect_write_pipe` or :meth:`~loop.connect_read_pipe` for use + with the event loop. + See the constructor of the :class:`subprocess.Popen` class for documentation on other arguments. @@ -1499,6 +1532,13 @@ Callback Handles A callback wrapper object returned by :meth:`loop.call_soon`, :meth:`loop.call_soon_threadsafe`. + .. method:: get_context() + + Return the :class:`contextvars.Context` object + associated with the handle. + + .. versionadded:: 3.12 + .. method:: cancel() Cancel the callback. If the callback has already been canceled @@ -1534,7 +1574,7 @@ Server objects are created by :meth:`loop.create_server`, :meth:`loop.create_unix_server`, :func:`start_server`, and :func:`start_unix_server` functions. -Do not instantiate the class directly. +Do not instantiate the :class:`Server` class directly. .. class:: Server @@ -1554,6 +1594,9 @@ Do not instantiate the class directly. .. versionchanged:: 3.7 Server object is an asynchronous context manager since Python 3.7. + .. versionchanged:: 3.11 + This class was exposed publicly as ``asyncio.Server`` in Python 3.9.11, 3.10.3 and 3.11. + .. method:: close() Stop serving: close listening sockets and set the :attr:`sockets` @@ -1625,7 +1668,8 @@ Do not instantiate the class directly. .. attribute:: sockets - List of :class:`socket.socket` objects the server is listening on. + List of socket-like objects, ``asyncio.trsock.TransportSocket``, which + the server is listening on. .. versionchanged:: 3.7 Prior to Python 3.7 ``Server.sockets`` used to return an diff --git a/Doc/library/asyncio-exceptions.rst b/Doc/library/asyncio-exceptions.rst index 9250f01b..7ad9103c 100644 --- a/Doc/library/asyncio-exceptions.rst +++ b/Doc/library/asyncio-exceptions.rst @@ -31,7 +31,7 @@ Exceptions .. versionchanged:: 3.8 - :exc:`CancelledError` is now a subclass of :class:`BaseException`. + :exc:`CancelledError` is now a subclass of :class:`BaseException` rather than :class:`Exception`. .. exception:: InvalidStateError diff --git a/Doc/library/asyncio-extending.rst b/Doc/library/asyncio-extending.rst index 8ffd356f..e7b293f4 100644 --- a/Doc/library/asyncio-extending.rst +++ b/Doc/library/asyncio-extending.rst @@ -69,7 +69,7 @@ Task lifetime support ===================== A third party task implementation should call the following functions to keep a task -visible by :func:`asyncio.get_tasks` and :func:`asyncio.current_task`: +visible by :func:`asyncio.all_tasks` and :func:`asyncio.current_task`: .. function:: _register_task(task) diff --git a/Doc/library/asyncio-future.rst b/Doc/library/asyncio-future.rst index 70cec9b2..893ae551 100644 --- a/Doc/library/asyncio-future.rst +++ b/Doc/library/asyncio-future.rst @@ -276,4 +276,4 @@ the Future has a result:: :func:`concurrent.futures.as_completed` functions. - :meth:`asyncio.Future.cancel` accepts an optional ``msg`` argument, - but :func:`concurrent.futures.cancel` does not. + but :meth:`concurrent.futures.Future.cancel` does not. diff --git a/Doc/library/asyncio-platforms.rst b/Doc/library/asyncio-platforms.rst index 50ad8a2a..19ec726c 100644 --- a/Doc/library/asyncio-platforms.rst +++ b/Doc/library/asyncio-platforms.rst @@ -37,7 +37,7 @@ All event loops on Windows do not support the following methods: * :meth:`loop.create_unix_connection` and :meth:`loop.create_unix_server` are not supported. - The :data:`socket.AF_UNIX` socket family is specific to Unix. + The :const:`socket.AF_UNIX` socket family is specific to Unix. * :meth:`loop.add_signal_handler` and :meth:`loop.remove_signal_handler` are not supported. diff --git a/Doc/library/asyncio-policy.rst b/Doc/library/asyncio-policy.rst index f846f76c..0d7821e6 100644 --- a/Doc/library/asyncio-policy.rst +++ b/Doc/library/asyncio-policy.rst @@ -88,12 +88,16 @@ The abstract event loop policy base class is defined as follows: This function is Unix specific. + .. deprecated:: 3.12 + .. method:: set_child_watcher(watcher) Set the current child process watcher to *watcher*. This function is Unix specific. + .. deprecated:: 3.12 + .. _asyncio-policy-builtin: @@ -112,10 +116,10 @@ asyncio ships with the following built-in policies: On Windows, :class:`ProactorEventLoop` is now used by default. - .. note:: - In Python versions 3.10.9, 3.11.1 and 3.12 the :meth:`get_event_loop` - method of the default asyncio policy emits a :exc:`DeprecationWarning` - if there is no running event loop and no current loop is set. + .. deprecated:: 3.12 + The :meth:`get_event_loop` method of the default asyncio policy now emits + a :exc:`DeprecationWarning` if there is no current event loop set and it + decides to create one. In some future Python release this will become an error. @@ -164,12 +168,16 @@ implementation used by the asyncio event loop: Return the current child watcher for the current policy. + .. deprecated:: 3.12 + .. function:: set_child_watcher(watcher) Set the current child watcher to *watcher* for the current policy. *watcher* must implement methods defined in the :class:`AbstractChildWatcher` base class. + .. deprecated:: 3.12 + .. note:: Third-party event loops implementations might not support custom child watchers. For such event loops, using @@ -220,6 +228,9 @@ implementation used by the asyncio event loop: This method has to be called to ensure that underlying resources are cleaned-up. + .. deprecated:: 3.12 + + .. class:: ThreadedChildWatcher This implementation starts a new waiting thread for every subprocess spawn. @@ -251,6 +262,8 @@ implementation used by the asyncio event loop: .. versionadded:: 3.8 + .. deprecated:: 3.12 + .. class:: SafeChildWatcher This implementation uses active event loop from the main thread to handle @@ -263,6 +276,8 @@ implementation used by the asyncio event loop: This solution is as safe as :class:`MultiLoopChildWatcher` and has the same *O(N)* complexity but requires a running event loop in the main thread to work. + .. deprecated:: 3.12 + .. class:: FastChildWatcher This implementation reaps every terminated processes by calling @@ -275,6 +290,8 @@ implementation used by the asyncio event loop: This solution requires a running event loop in the main thread to work, as :class:`SafeChildWatcher`. + .. deprecated:: 3.12 + .. class:: PidfdChildWatcher This implementation polls process file descriptors (pidfds) to await child diff --git a/Doc/library/asyncio-runner.rst b/Doc/library/asyncio-runner.rst index 4abe7b6e..b68b2570 100644 --- a/Doc/library/asyncio-runner.rst +++ b/Doc/library/asyncio-runner.rst @@ -22,13 +22,13 @@ to simplify async code usage for common wide-spread scenarios. Running an asyncio Program ========================== -.. function:: run(coro, *, debug=None) +.. function:: run(coro, *, debug=None, loop_factory=None) Execute the :term:`coroutine` *coro* and return the result. This function runs the passed coroutine, taking care of managing the asyncio event loop, *finalizing asynchronous - generators*, and closing the threadpool. + generators*, and closing the executor. This function cannot be called when another asyncio event loop is running in the same thread. @@ -37,9 +37,15 @@ Running an asyncio Program debug mode explicitly. ``None`` is used to respect the global :ref:`asyncio-debug-mode` settings. - This function always creates a new event loop and closes it at - the end. It should be used as a main entry point for asyncio - programs, and should ideally only be called once. + If *loop_factory* is not ``None``, it is used to create a new event loop; + otherwise :func:`asyncio.new_event_loop` is used. The loop is closed at the end. + This function should be used as a main entry point for asyncio programs, + and should ideally only be called once. It is recommended to use + *loop_factory* to configure the event loop instead of policies. + + The executor is given a timeout duration of 5 minutes to shutdown. + If the executor hasn't finished within that duration, a warning is + emitted and the executor is closed. Example:: @@ -58,6 +64,10 @@ Running an asyncio Program *debug* is ``None`` by default to respect the global debug mode settings. + .. versionchanged:: 3.12 + + Added *loop_factory* parameter. + Runner context manager ====================== diff --git a/Doc/library/asyncio-stream.rst b/Doc/library/asyncio-stream.rst index 74891306..bbac1c32 100644 --- a/Doc/library/asyncio-stream.rst +++ b/Doc/library/asyncio-stream.rst @@ -206,12 +206,20 @@ StreamReader .. coroutinemethod:: read(n=-1) - Read up to *n* bytes. If *n* is not provided, or set to ``-1``, - read until EOF and return all read bytes. + Read up to *n* bytes from the stream. + If *n* is not provided or set to ``-1``, + read until EOF, then return all read :class:`bytes`. If EOF was received and the internal buffer is empty, return an empty ``bytes`` object. + If *n* is ``0``, return an empty ``bytes`` object immediately. + + If *n* is positive, return at most *n* available ``bytes`` + as soon as at least 1 byte is available in the internal buffer. + If EOF is received before any byte is read, return an empty + ``bytes`` object. + .. coroutinemethod:: readline() Read one line, where "line" is a sequence of bytes @@ -336,7 +344,7 @@ StreamWriter returns immediately. .. coroutinemethod:: start_tls(sslcontext, \*, server_hostname=None, \ - ssl_handshake_timeout=None) + ssl_handshake_timeout=None, ssl_shutdown_timeout=None) Upgrade an existing stream-based connection to TLS. @@ -351,8 +359,16 @@ StreamWriter handshake to complete before aborting the connection. ``60.0`` seconds if ``None`` (default). + * *ssl_shutdown_timeout* is the time in seconds to wait for the SSL shutdown + to complete before aborting the connection. ``30.0`` seconds if ``None`` + (default). + .. versionadded:: 3.11 + .. versionchanged:: 3.12 + Added the *ssl_shutdown_timeout* parameter. + + .. method:: is_closing() Return ``True`` if the stream is closed or in the process of diff --git a/Doc/library/asyncio-subprocess.rst b/Doc/library/asyncio-subprocess.rst index 4274638c..bf35b1cb 100644 --- a/Doc/library/asyncio-subprocess.rst +++ b/Doc/library/asyncio-subprocess.rst @@ -68,7 +68,7 @@ Creating Subprocesses The *limit* argument sets the buffer limit for :class:`StreamReader` wrappers for :attr:`Process.stdout` and :attr:`Process.stderr` - (if :attr:`subprocess.PIPE` is passed to *stdout* and *stderr* arguments). + (if :const:`subprocess.PIPE` is passed to *stdout* and *stderr* arguments). Return a :class:`~asyncio.subprocess.Process` instance. @@ -86,7 +86,7 @@ Creating Subprocesses The *limit* argument sets the buffer limit for :class:`StreamReader` wrappers for :attr:`Process.stdout` and :attr:`Process.stderr` - (if :attr:`subprocess.PIPE` is passed to *stdout* and *stderr* arguments). + (if :const:`subprocess.PIPE` is passed to *stdout* and *stderr* arguments). Return a :class:`~asyncio.subprocess.Process` instance. @@ -207,8 +207,9 @@ their completion. Interact with process: 1. send data to *stdin* (if *input* is not ``None``); - 2. read data from *stdout* and *stderr*, until EOF is reached; - 3. wait for process to terminate. + 2. closes *stdin*; + 3. read data from *stdout* and *stderr*, until EOF is reached; + 4. wait for process to terminate. The optional *input* argument is the data (:class:`bytes` object) that will be sent to the child process. @@ -229,6 +230,10 @@ their completion. Note, that the data read is buffered in memory, so do not use this method if the data size is large or unlimited. + .. versionchanged:: 3.12 + + *stdin* gets closed when `input=None` too. + .. method:: send_signal(signal) Sends the signal *signal* to the child process. @@ -244,7 +249,7 @@ their completion. Stop the child process. - On POSIX systems this method sends :py:data:`signal.SIGTERM` to the + On POSIX systems this method sends :py:const:`signal.SIGTERM` to the child process. On Windows the Win32 API function :c:func:`TerminateProcess` is diff --git a/Doc/library/asyncio-task.rst b/Doc/library/asyncio-task.rst index 1fd7afad..f488aa73 100644 --- a/Doc/library/asyncio-task.rst +++ b/Doc/library/asyncio-task.rst @@ -256,8 +256,9 @@ Creating Tasks .. note:: - :meth:`asyncio.TaskGroup.create_task` is a newer alternative - that allows for convenient waiting for a group of related tasks. + :meth:`asyncio.TaskGroup.create_task` is a new alternative + leveraging structural concurrency; it allows for waiting + for a group of related tasks with strong safety guarantees. .. important:: @@ -300,13 +301,17 @@ in the task at the next opportunity. It is recommended that coroutines use ``try/finally`` blocks to robustly perform clean-up logic. In case :exc:`asyncio.CancelledError` is explicitly caught, it should generally be propagated when -clean-up is complete. Most code can safely ignore :exc:`asyncio.CancelledError`. +clean-up is complete. :exc:`asyncio.CancelledError` directly subclasses +:exc:`BaseException` so most code will not need to be aware of it. The asyncio components that enable structured concurrency, like :class:`asyncio.TaskGroup` and :func:`asyncio.timeout`, are implemented using cancellation internally and might misbehave if a coroutine swallows :exc:`asyncio.CancelledError`. Similarly, user code -should not call :meth:`uncancel <asyncio.Task.uncancel>`. +should not generally call :meth:`uncancel <asyncio.Task.uncancel>`. +However, in cases when suppressing :exc:`asyncio.CancelledError` is +truly desired, it is necessary to also call ``uncancel()`` to completely +remove the cancellation state. .. _taskgroups: @@ -336,7 +341,7 @@ Example:: async with asyncio.TaskGroup() as tg: task1 = tg.create_task(some_coro(...)) task2 = tg.create_task(another_coro(...)) - print("Both tasks have completed now.") + print(f"Both tasks have completed now: {task1.result()}, {task2.result()}") The ``async with`` statement will wait for all tasks in the group to finish. While waiting, new tasks may still be added to the group @@ -455,8 +460,12 @@ Running Tasks Concurrently Tasks/Futures to be cancelled. .. note:: - A more modern way to create and run tasks concurrently and - wait for their completion is :class:`asyncio.TaskGroup`. + A new alternative to create and run tasks concurrently and + wait for their completion is :class:`asyncio.TaskGroup`. *TaskGroup* + provides stronger safety guarantees than *gather* for scheduling a nesting of subtasks: + if a task (or a subtask, a task scheduled by a task) + raises an exception, *TaskGroup* will, while *gather* will not, + cancel the remaining scheduled tasks). .. _asyncio_example_gather: @@ -518,6 +527,51 @@ Running Tasks Concurrently and there is no running event loop. +.. _eager-task-factory: + +Eager Task Factory +================== + +.. function:: eager_task_factory(loop, coro, *, name=None, context=None) + + A task factory for eager task execution. + + When using this factory (via :meth:`loop.set_task_factory(asyncio.eager_task_factory) <loop.set_task_factory>`), + coroutines begin execution synchronously during :class:`Task` construction. + Tasks are only scheduled on the event loop if they block. + This can be a performance improvement as the overhead of loop scheduling + is avoided for coroutines that complete synchronously. + + A common example where this is beneficial is coroutines which employ + caching or memoization to avoid actual I/O when possible. + + .. note:: + + Immediate execution of the coroutine is a semantic change. + If the coroutine returns or raises, the task is never scheduled + to the event loop. If the coroutine execution blocks, the task is + scheduled to the event loop. This change may introduce behavior + changes to existing applications. For example, + the application's task execution order is likely to change. + + .. versionadded:: 3.12 + +.. function:: create_eager_task_factory(custom_task_constructor) + + Create an eager task factory, similar to :func:`eager_task_factory`, + using the provided *custom_task_constructor* when creating a new task instead + of the default :class:`Task`. + + *custom_task_constructor* must be a *callable* with the signature matching + the signature of :class:`Task.__init__ <Task>`. + The callable must return a :class:`asyncio.Task`-compatible object. + + This function returns a *callable* intended to be used as a task factory of an + event loop via :meth:`loop.set_task_factory(factory) <loop.set_task_factory>`). + + .. versionadded:: 3.12 + + Shielding From Cancellation =========================== @@ -574,9 +628,9 @@ Shielding From Cancellation Timeouts ======== -.. coroutinefunction:: timeout(delay) +.. function:: timeout(delay) - An :ref:`asynchronous context manager <async-context-managers>` + Return an :ref:`asynchronous context manager <async-context-managers>` that can be used to limit the amount of time spent waiting on something. @@ -597,16 +651,16 @@ Timeouts If ``long_running_task`` takes more than 10 seconds to complete, the context manager will cancel the current task and handle the resulting :exc:`asyncio.CancelledError` internally, transforming it - into an :exc:`asyncio.TimeoutError` which can be caught and handled. + into a :exc:`TimeoutError` which can be caught and handled. .. note:: The :func:`asyncio.timeout` context manager is what transforms - the :exc:`asyncio.CancelledError` into an :exc:`asyncio.TimeoutError`, - which means the :exc:`asyncio.TimeoutError` can only be caught + the :exc:`asyncio.CancelledError` into a :exc:`TimeoutError`, + which means the :exc:`TimeoutError` can only be caught *outside* of the context manager. - Example of catching :exc:`asyncio.TimeoutError`:: + Example of catching :exc:`TimeoutError`:: async def main(): try: @@ -620,32 +674,26 @@ Timeouts The context manager produced by :func:`asyncio.timeout` can be rescheduled to a different deadline and inspected. - .. class:: Timeout() + .. class:: Timeout(when) An :ref:`asynchronous context manager <async-context-managers>` - that limits time spent inside of it. + for cancelling overdue coroutines. + + ``when`` should be an absolute time at which the context should time out, + as measured by the event loop's clock: - .. versionadded:: 3.11 + - If ``when`` is ``None``, the timeout will never trigger. + - If ``when < loop.time()``, the timeout will trigger on the next + iteration of the event loop. .. method:: when() -> float | None Return the current deadline, or ``None`` if the current deadline is not set. - The deadline is a float, consistent with the time returned by - :meth:`loop.time`. - .. method:: reschedule(when: float | None) - Change the time the timeout will trigger. - - If *when* is ``None``, any current deadline will be removed, and the - context manager will wait indefinitely. - - If *when* is a float, it is set as the new deadline. - - if *when* is in the past, the timeout will trigger on the next - iteration of the event loop. + Reschedule the timeout. .. method:: expired() -> bool @@ -673,7 +721,7 @@ Timeouts .. versionadded:: 3.11 -.. coroutinefunction:: timeout_at(when) +.. function:: timeout_at(when) Similar to :func:`asyncio.timeout`, except *when* is the absolute time to stop waiting, or ``None``. @@ -804,6 +852,10 @@ Waiting Primitives .. versionchanged:: 3.11 Passing coroutine objects to ``wait()`` directly is forbidden. + .. versionchanged:: 3.12 + Added support for generators yielding tasks. + + .. function:: as_completed(aws, *, timeout=None) Run :ref:`awaitable objects <asyncio-awaitables>` in the *aws* @@ -814,9 +866,6 @@ Waiting Primitives Raises :exc:`TimeoutError` if the timeout occurs before all Futures are done. - .. versionchanged:: 3.10 - Removed the *loop* parameter. - Example:: for coro in as_completed(aws): @@ -830,6 +879,9 @@ Waiting Primitives Deprecation warning is emitted if not all awaitable objects in the *aws* iterable are Future-like objects and there is no running event loop. + .. versionchanged:: 3.12 + Added support for generators yielding tasks. + Running in Threads ================== @@ -961,10 +1013,17 @@ Introspection .. versionadded:: 3.7 +.. function:: iscoroutine(obj) + + Return ``True`` if *obj* is a coroutine object. + + .. versionadded:: 3.4 + + Task Object =========== -.. class:: Task(coro, *, loop=None, name=None) +.. class:: Task(coro, *, loop=None, name=None, context=None, eager_start=False) A :class:`Future-like <Future>` object that runs a Python :ref:`coroutine <coroutine>`. Not thread-safe. @@ -999,9 +1058,17 @@ Task Object APIs except :meth:`Future.set_result` and :meth:`Future.set_exception`. - Tasks support the :mod:`contextvars` module. When a Task - is created it copies the current context and later runs its - coroutine in the copied context. + An optional keyword-only *context* argument allows specifying a + custom :class:`contextvars.Context` for the *coro* to run in. + If no *context* is provided, the Task copies the current context + and later runs its coroutine in the copied context. + + An optional keyword-only *eager_start* argument allows eagerly starting + the execution of the :class:`asyncio.Task` at task creation time. + If set to ``True`` and the event loop is running, the task will start + executing the coroutine immediately, until the first time the coroutine + blocks. If the coroutine returns or raises without blocking, the task + will be finished eagerly and will skip scheduling to the event loop. .. versionchanged:: 3.7 Added support for the :mod:`contextvars` module. @@ -1013,6 +1080,12 @@ Task Object Deprecation warning is emitted if *loop* is not specified and there is no running event loop. + .. versionchanged:: 3.11 + Added the *context* parameter. + + .. versionchanged:: 3.12 + Added the *eager_start* parameter. + .. method:: done() Return ``True`` if the Task is *done*. @@ -1097,14 +1170,30 @@ Task Object The *limit* argument is passed to :meth:`get_stack` directly. The *file* argument is an I/O stream to which the output - is written; by default output is written to :data:`sys.stderr`. + is written; by default output is written to :data:`sys.stdout`. .. method:: get_coro() Return the coroutine object wrapped by the :class:`Task`. + .. note:: + + This will return ``None`` for Tasks which have already + completed eagerly. See the :ref:`Eager Task Factory <eager-task-factory>`. + .. versionadded:: 3.8 + .. versionchanged:: 3.12 + + Newly added eager task execution means result may be ``None``. + + .. method:: get_context() + + Return the :class:`contextvars.Context` object + associated with the task. + + .. versionadded:: 3.12 + .. method:: get_name() Return the name of the Task. @@ -1140,7 +1229,9 @@ Task Object Therefore, unlike :meth:`Future.cancel`, :meth:`Task.cancel` does not guarantee that the Task will be cancelled, although suppressing cancellation completely is not common and is actively - discouraged. + discouraged. Should the coroutine nevertheless decide to suppress + the cancellation, it needs to call :meth:`Task.uncancel` in addition + to catching the exception. .. versionchanged:: 3.9 Added the *msg* parameter. @@ -1230,6 +1321,10 @@ Task Object with :meth:`uncancel`. :class:`TaskGroup` context managers use :func:`uncancel` in a similar fashion. + If end-user code is, for some reason, suppresing cancellation by + catching :exc:`CancelledError`, it needs to call this method to remove + the cancellation state. + .. method:: cancelling() Return the number of pending cancellation requests to this Task, i.e., diff --git a/Doc/library/asyncore.rst b/Doc/library/asyncore.rst deleted file mode 100644 index a3a4e90d..00000000 --- a/Doc/library/asyncore.rst +++ /dev/null @@ -1,365 +0,0 @@ -:mod:`asyncore` --- Asynchronous socket handler -=============================================== - -.. module:: asyncore - :synopsis: A base class for developing asynchronous socket handling - services. - :deprecated: - -.. moduleauthor:: Sam Rushing <rushing@nightmare.com> -.. sectionauthor:: Christopher Petrilli <petrilli@amber.org> -.. sectionauthor:: Steve Holden <sholden@holdenweb.com> -.. heavily adapted from original documentation by Sam Rushing - -**Source code:** :source:`Lib/asyncore.py` - -.. deprecated-removed:: 3.6 3.12 - The :mod:`asyncore` module is deprecated - (see :pep:`PEP 594 <594#asyncore>` for details). - Please use :mod:`asyncio` instead. - --------------- - -.. note:: - - This module exists for backwards compatibility only. For new code we - recommend using :mod:`asyncio`. - -This module provides the basic infrastructure for writing asynchronous socket -service clients and servers. - -.. include:: ../includes/wasm-notavail.rst - -There are only two ways to have a program on a single processor do "more than -one thing at a time." Multi-threaded programming is the simplest and most -popular way to do it, but there is another very different technique, that lets -you have nearly all the advantages of multi-threading, without actually using -multiple threads. It's really only practical if your program is largely I/O -bound. If your program is processor bound, then pre-emptive scheduled threads -are probably what you really need. Network servers are rarely processor -bound, however. - -If your operating system supports the :c:func:`select` system call in its I/O -library (and nearly all do), then you can use it to juggle multiple -communication channels at once; doing other work while your I/O is taking -place in the "background." Although this strategy can seem strange and -complex, especially at first, it is in many ways easier to understand and -control than multi-threaded programming. The :mod:`asyncore` module solves -many of the difficult problems for you, making the task of building -sophisticated high-performance network servers and clients a snap. For -"conversational" applications and protocols the companion :mod:`asynchat` -module is invaluable. - -The basic idea behind both modules is to create one or more network -*channels*, instances of class :class:`asyncore.dispatcher` and -:class:`asynchat.async_chat`. Creating the channels adds them to a global -map, used by the :func:`loop` function if you do not provide it with your own -*map*. - -Once the initial channel(s) is(are) created, calling the :func:`loop` function -activates channel service, which continues until the last channel (including -any that have been added to the map during asynchronous service) is closed. - - -.. function:: loop([timeout[, use_poll[, map[,count]]]]) - - Enter a polling loop that terminates after count passes or all open - channels have been closed. All arguments are optional. The *count* - parameter defaults to ``None``, resulting in the loop terminating only when all - channels have been closed. The *timeout* argument sets the timeout - parameter for the appropriate :func:`~select.select` or :func:`~select.poll` - call, measured in seconds; the default is 30 seconds. The *use_poll* - parameter, if true, indicates that :func:`~select.poll` should be used in - preference to :func:`~select.select` (the default is ``False``). - - The *map* parameter is a dictionary whose items are the channels to watch. - As channels are closed they are deleted from their map. If *map* is - omitted, a global map is used. Channels (instances of - :class:`asyncore.dispatcher`, :class:`asynchat.async_chat` and subclasses - thereof) can freely be mixed in the map. - - -.. class:: dispatcher() - - The :class:`dispatcher` class is a thin wrapper around a low-level socket - object. To make it more useful, it has a few methods for event-handling - which are called from the asynchronous loop. Otherwise, it can be treated - as a normal non-blocking socket object. - - The firing of low-level events at certain times or in certain connection - states tells the asynchronous loop that certain higher-level events have - taken place. For example, if we have asked for a socket to connect to - another host, we know that the connection has been made when the socket - becomes writable for the first time (at this point you know that you may - write to it with the expectation of success). The implied higher-level - events are: - - +----------------------+----------------------------------------+ - | Event | Description | - +======================+========================================+ - | ``handle_connect()`` | Implied by the first read or write | - | | event | - +----------------------+----------------------------------------+ - | ``handle_close()`` | Implied by a read event with no data | - | | available | - +----------------------+----------------------------------------+ - | ``handle_accepted()``| Implied by a read event on a listening | - | | socket | - +----------------------+----------------------------------------+ - - During asynchronous processing, each mapped channel's :meth:`readable` and - :meth:`writable` methods are used to determine whether the channel's socket - should be added to the list of channels :c:func:`select`\ ed or - :c:func:`poll`\ ed for read and write events. - - Thus, the set of channel events is larger than the basic socket events. The - full set of methods that can be overridden in your subclass follows: - - - .. method:: handle_read() - - Called when the asynchronous loop detects that a :meth:`read` call on the - channel's socket will succeed. - - - .. method:: handle_write() - - Called when the asynchronous loop detects that a writable socket can be - written. Often this method will implement the necessary buffering for - performance. For example:: - - def handle_write(self): - sent = self.send(self.buffer) - self.buffer = self.buffer[sent:] - - - .. method:: handle_expt() - - Called when there is out of band (OOB) data for a socket connection. This - will almost never happen, as OOB is tenuously supported and rarely used. - - - .. method:: handle_connect() - - Called when the active opener's socket actually makes a connection. Might - send a "welcome" banner, or initiate a protocol negotiation with the - remote endpoint, for example. - - - .. method:: handle_close() - - Called when the socket is closed. - - - .. method:: handle_error() - - Called when an exception is raised and not otherwise handled. The default - version prints a condensed traceback. - - - .. method:: handle_accept() - - Called on listening channels (passive openers) when a connection can be - established with a new remote endpoint that has issued a :meth:`connect` - call for the local endpoint. Deprecated in version 3.2; use - :meth:`handle_accepted` instead. - - .. deprecated:: 3.2 - - - .. method:: handle_accepted(sock, addr) - - Called on listening channels (passive openers) when a connection has been - established with a new remote endpoint that has issued a :meth:`connect` - call for the local endpoint. *sock* is a *new* socket object usable to - send and receive data on the connection, and *addr* is the address - bound to the socket on the other end of the connection. - - .. versionadded:: 3.2 - - - .. method:: readable() - - Called each time around the asynchronous loop to determine whether a - channel's socket should be added to the list on which read events can - occur. The default method simply returns ``True``, indicating that by - default, all channels will be interested in read events. - - - .. method:: writable() - - Called each time around the asynchronous loop to determine whether a - channel's socket should be added to the list on which write events can - occur. The default method simply returns ``True``, indicating that by - default, all channels will be interested in write events. - - - In addition, each channel delegates or extends many of the socket methods. - Most of these are nearly identical to their socket partners. - - - .. method:: create_socket(family=socket.AF_INET, type=socket.SOCK_STREAM) - - This is identical to the creation of a normal socket, and will use the - same options for creation. Refer to the :mod:`socket` documentation for - information on creating sockets. - - .. versionchanged:: 3.3 - *family* and *type* arguments can be omitted. - - - .. method:: connect(address) - - As with the normal socket object, *address* is a tuple with the first - element the host to connect to, and the second the port number. - - - .. method:: send(data) - - Send *data* to the remote end-point of the socket. - - - .. method:: recv(buffer_size) - - Read at most *buffer_size* bytes from the socket's remote end-point. An - empty bytes object implies that the channel has been closed from the - other end. - - Note that :meth:`recv` may raise :exc:`BlockingIOError` , even though - :func:`select.select` or :func:`select.poll` has reported the socket - ready for reading. - - - .. method:: listen(backlog) - - Listen for connections made to the socket. The *backlog* argument - specifies the maximum number of queued connections and should be at least - 1; the maximum value is system-dependent (usually 5). - - - .. method:: bind(address) - - Bind the socket to *address*. The socket must not already be bound. (The - format of *address* depends on the address family --- refer to the - :mod:`socket` documentation for more information.) To mark - the socket as re-usable (setting the :const:`SO_REUSEADDR` option), call - the :class:`dispatcher` object's :meth:`set_reuse_addr` method. - - - .. method:: accept() - - Accept a connection. The socket must be bound to an address and listening - for connections. The return value can be either ``None`` or a pair - ``(conn, address)`` where *conn* is a *new* socket object usable to send - and receive data on the connection, and *address* is the address bound to - the socket on the other end of the connection. - When ``None`` is returned it means the connection didn't take place, in - which case the server should just ignore this event and keep listening - for further incoming connections. - - - .. method:: close() - - Close the socket. All future operations on the socket object will fail. - The remote end-point will receive no more data (after queued data is - flushed). Sockets are automatically closed when they are - garbage-collected. - - -.. class:: dispatcher_with_send() - - A :class:`dispatcher` subclass which adds simple buffered output capability, - useful for simple clients. For more sophisticated usage use - :class:`asynchat.async_chat`. - -.. class:: file_dispatcher() - - A file_dispatcher takes a file descriptor or :term:`file object` along - with an optional map argument and wraps it for use with the :c:func:`poll` - or :c:func:`loop` functions. If provided a file object or anything with a - :c:func:`fileno` method, that method will be called and passed to the - :class:`file_wrapper` constructor. - - .. availability:: Unix. - -.. class:: file_wrapper() - - A file_wrapper takes an integer file descriptor and calls :func:`os.dup` to - duplicate the handle so that the original handle may be closed independently - of the file_wrapper. This class implements sufficient methods to emulate a - socket for use by the :class:`file_dispatcher` class. - - .. availability:: Unix. - - -.. _asyncore-example-1: - -asyncore Example basic HTTP client ----------------------------------- - -Here is a very basic HTTP client that uses the :class:`dispatcher` class to -implement its socket handling:: - - import asyncore - - class HTTPClient(asyncore.dispatcher): - - def __init__(self, host, path): - asyncore.dispatcher.__init__(self) - self.create_socket() - self.connect( (host, 80) ) - self.buffer = bytes('GET %s HTTP/1.0\r\nHost: %s\r\n\r\n' % - (path, host), 'ascii') - - def handle_connect(self): - pass - - def handle_close(self): - self.close() - - def handle_read(self): - print(self.recv(8192)) - - def writable(self): - return (len(self.buffer) > 0) - - def handle_write(self): - sent = self.send(self.buffer) - self.buffer = self.buffer[sent:] - - - client = HTTPClient('www.python.org', '/') - asyncore.loop() - -.. _asyncore-example-2: - -asyncore Example basic echo server ----------------------------------- - -Here is a basic echo server that uses the :class:`dispatcher` class to accept -connections and dispatches the incoming connections to a handler:: - - import asyncore - - class EchoHandler(asyncore.dispatcher_with_send): - - def handle_read(self): - data = self.recv(8192) - if data: - self.send(data) - - class EchoServer(asyncore.dispatcher): - - def __init__(self, host, port): - asyncore.dispatcher.__init__(self) - self.create_socket() - self.set_reuse_addr() - self.bind((host, port)) - self.listen(5) - - def handle_accepted(self, sock, addr): - print('Incoming connection from %s' % repr(addr)) - handler = EchoHandler(sock) - - server = EchoServer('localhost', 8080) - asyncore.loop() diff --git a/Doc/library/atexit.rst b/Doc/library/atexit.rst index f7f03810..3dbef695 100644 --- a/Doc/library/atexit.rst +++ b/Doc/library/atexit.rst @@ -20,6 +20,9 @@ at interpreter termination time they will be run in the order ``C``, ``B``, 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. +**Note:** The effect of registering or unregistering functions from within +a cleanup function is undefined. + .. versionchanged:: 3.7 When used with C-API subinterpreters, registered functions are local to the interpreter they were registered in. @@ -45,6 +48,16 @@ internal error is detected, or when :func:`os._exit` is called. This function returns *func*, which makes it possible to use it as a decorator. + .. warning:: + Starting new threads or calling :func:`os.fork` from a registered + function can lead to race condition between the main Python + runtime thread freeing thread states while internal :mod:`threading` + routines or the new process try to use that state. This can lead to + crashes rather than clean shutdown. + + .. versionchanged:: 3.12 + Attempts to start a new thread or :func:`os.fork` a new process + in a registered function now leads to :exc:`RuntimeError`. .. function:: unregister(func) diff --git a/Doc/library/base64.rst b/Doc/library/base64.rst index 4ca3768f..d5b6af8c 100644 --- a/Doc/library/base64.rst +++ b/Doc/library/base64.rst @@ -58,7 +58,7 @@ The modern interface provides: This allows an application to e.g. generate URL or filesystem safe Base64 strings. The default is ``None``, for which the standard Base64 alphabet is used. - May assert or raise a a :exc:`ValueError` if the length of *altchars* is not 2. Raises a + May assert or raise a :exc:`ValueError` if the length of *altchars* is not 2. Raises a :exc:`TypeError` if *altchars* is not a :term:`bytes-like object`. diff --git a/Doc/library/binascii.rst b/Doc/library/binascii.rst index 5a0815fa..21960cb7 100644 --- a/Doc/library/binascii.rst +++ b/Doc/library/binascii.rst @@ -6,8 +6,8 @@ representations. .. index:: - module: uu - module: base64 + pair: module; uu + pair: module; base64 -------------- diff --git a/Doc/library/bisect.rst b/Doc/library/bisect.rst index 9b40f80f..8022c596 100644 --- a/Doc/library/bisect.rst +++ b/Doc/library/bisect.rst @@ -13,10 +13,18 @@ This module provides support for maintaining a list in sorted order without having to sort the list after each insertion. For long lists of items with -expensive comparison operations, this can be an improvement over the more common -approach. The module is called :mod:`bisect` because it uses a basic bisection -algorithm to do its work. The source code may be most useful as a working -example of the algorithm (the boundary conditions are already right!). +expensive comparison operations, this can be an improvement over +linear searches or frequent resorting. + +The module is called :mod:`bisect` because it uses a basic bisection +algorithm to do its work. Unlike other bisection tools that search for a +specific value, the functions in this module are designed to locate an +insertion point. Accordingly, the functions never call an :meth:`__eq__` +method to determine whether a value has been found. Instead, the +functions only call the :meth:`__lt__` method and will return an insertion +point between values in an array. + +.. _bisect functions: The following functions are provided: @@ -30,16 +38,17 @@ The following functions are provided: any existing entries. The return value is suitable for use as the first parameter to ``list.insert()`` assuming that *a* is already sorted. - The returned insertion point *i* partitions the array *a* into two halves so - that ``all(val < x for val in a[lo : i])`` for the left side and - ``all(val >= x for val in a[i : hi])`` for the right side. + The returned insertion point *ip* partitions the array *a* into two + slices such that ``all(elem < x for elem in a[lo : ip])`` is true for the + left slice and ``all(elem >= x for elem in a[ip : hi])`` is true for the + right slice. *key* specifies a :term:`key function` of one argument that is used to extract a comparison key from each element in the array. To support searching complex records, the key function is not applied to the *x* value. - If *key* is ``None``, the elements are compared directly with no - intervening function call. + If *key* is ``None``, the elements are compared directly and + no key function is called. .. versionchanged:: 3.10 Added the *key* parameter. @@ -48,19 +57,12 @@ The following functions are provided: .. function:: bisect_right(a, x, lo=0, hi=len(a), *, key=None) bisect(a, x, lo=0, hi=len(a), *, key=None) - Similar to :func:`bisect_left`, but returns an insertion point which comes + Similar to :py:func:`~bisect.bisect_left`, but returns an insertion point which comes after (to the right of) any existing entries of *x* in *a*. - The returned insertion point *i* partitions the array *a* into two halves so - that ``all(val <= x for val in a[lo : i])`` for the left side and - ``all(val > x for val in a[i : hi])`` for the right side. - - *key* specifies a :term:`key function` of one argument that is used to - extract a comparison key from each element in the array. To support - searching complex records, the key function is not applied to the *x* value. - - If *key* is ``None``, the elements are compared directly with no - intervening function call. + The returned insertion point *ip* partitions the array *a* into two slices + such that ``all(elem <= x for elem in a[lo : ip])`` is true for the left slice and + ``all(elem > x for elem in a[ip : hi])`` is true for the right slice. .. versionchanged:: 3.10 Added the *key* parameter. @@ -70,7 +72,7 @@ The following functions are provided: Insert *x* in *a* in sorted order. - This function first runs :func:`bisect_left` to locate an insertion point. + This function first runs :py:func:`~bisect.bisect_left` to locate an insertion point. Next, it runs the :meth:`insert` method on *a* to insert *x* at the appropriate position to maintain sort order. @@ -87,10 +89,10 @@ The following functions are provided: .. function:: insort_right(a, x, lo=0, hi=len(a), *, key=None) insort(a, x, lo=0, hi=len(a), *, key=None) - Similar to :func:`insort_left`, but inserting *x* in *a* after any existing + Similar to :py:func:`~bisect.insort_left`, but inserting *x* in *a* after any existing entries of *x*. - This function first runs :func:`bisect_right` to locate an insertion point. + This function first runs :py:func:`~bisect.bisect_right` to locate an insertion point. Next, it runs the :meth:`insert` method on *a* to insert *x* at the appropriate position to maintain sort order. @@ -120,7 +122,7 @@ thoughts in mind: they are used. Consequently, if the search functions are used in a loop, the key function may be called again and again on the same array elements. If the key function isn't fast, consider wrapping it with - :func:`functools.cache` to avoid duplicate computations. Alternatively, + :py:func:`functools.cache` to avoid duplicate computations. Alternatively, consider searching an array of precomputed keys to locate the insertion point (as shown in the examples section below). @@ -140,7 +142,7 @@ thoughts in mind: Searching Sorted Lists ---------------------- -The above :func:`bisect` functions are useful for finding insertion points but +The above `bisect functions`_ are useful for finding insertion points but can be tricky or awkward to use for common searching tasks. The following five functions show how to transform them into the standard lookups for sorted lists:: @@ -186,8 +188,8 @@ Examples .. _bisect-example: -The :func:`bisect` function can be useful for numeric table lookups. This -example uses :func:`bisect` to look up a letter grade for an exam score (say) +The :py:func:`~bisect.bisect` function can be useful for numeric table lookups. This +example uses :py:func:`~bisect.bisect` to look up a letter grade for an exam score (say) based on a set of ordered numeric breakpoints: 90 and up is an 'A', 80 to 89 is a 'B', and so on:: @@ -198,8 +200,8 @@ a 'B', and so on:: >>> [grade(score) for score in [33, 99, 77, 70, 89, 90, 100]] ['F', 'A', 'C', 'C', 'B', 'A', 'A'] -The :func:`bisect` and :func:`insort` functions also work with lists of -tuples. The *key* argument can serve to extract the field used for ordering +The :py:func:`~bisect.bisect` and :py:func:`~bisect.insort` functions also work with +lists of tuples. The *key* argument can serve to extract the field used for ordering records in a table:: >>> from collections import namedtuple @@ -210,10 +212,10 @@ records in a table:: >>> Movie = namedtuple('Movie', ('name', 'released', 'director')) >>> movies = [ - ... Movie('Jaws', 1975, 'Speilberg'), + ... Movie('Jaws', 1975, 'Spielberg'), ... Movie('Titanic', 1997, 'Cameron'), ... Movie('The Birds', 1963, 'Hitchcock'), - ... Movie('Aliens', 1986, 'Scott') + ... Movie('Aliens', 1986, 'Cameron') ... ] >>> # Find the first movie released after 1960 @@ -228,8 +230,8 @@ records in a table:: >>> pprint(movies) [Movie(name='The Birds', released=1963, director='Hitchcock'), Movie(name='Love Story', released=1970, director='Hiller'), - Movie(name='Jaws', released=1975, director='Speilberg'), - Movie(name='Aliens', released=1986, director='Scott'), + Movie(name='Jaws', released=1975, director='Spielberg'), + Movie(name='Aliens', released=1986, director='Cameron'), Movie(name='Titanic', released=1997, director='Cameron')] If the key function is expensive, it is possible to avoid repeated function diff --git a/Doc/library/bz2.rst b/Doc/library/bz2.rst index ae5a1598..ec4aeaa0 100644 --- a/Doc/library/bz2.rst +++ b/Doc/library/bz2.rst @@ -87,7 +87,8 @@ The :mod:`bz2` module contains: compressed streams. :class:`BZ2File` provides all of the members specified by the - :class:`io.BufferedIOBase`, except for :meth:`detach` and :meth:`truncate`. + :class:`io.BufferedIOBase`, except for :meth:`~io.BufferedIOBase.detach` + and :meth:`~io.IOBase.truncate`. Iteration and the :keyword:`with` statement are supported. :class:`BZ2File` also provides the following method: @@ -320,9 +321,11 @@ Writing and reading a bzip2-compressed file in binary mode: >>> with bz2.open("myfile.bz2", "wb") as f: ... # Write compressed data to file ... unused = f.write(data) + ... >>> with bz2.open("myfile.bz2", "rb") as f: ... # Decompress data from file ... content = f.read() + ... >>> content == data # Check equality to original object after round-trip True diff --git a/Doc/library/calendar.rst b/Doc/library/calendar.rst index 66f59f0e..157a7537 100644 --- a/Doc/library/calendar.rst +++ b/Doc/library/calendar.rst @@ -394,6 +394,29 @@ The :mod:`calendar` module exports the following data attributes: An array that represents the abbreviated days of the week in the current locale. +.. data:: MONDAY + TUESDAY + WEDNESDAY + THURSDAY + FRIDAY + SATURDAY + SUNDAY + + Aliases for the days of the week, + where ``MONDAY`` is ``0`` and ``SUNDAY`` is ``6``. + + .. versionadded:: 3.12 + + +.. class:: Day + + Enumeration defining days of the week as integer constants. + The members of this enumeration are exported to the module scope as + :data:`MONDAY` through :data:`SUNDAY`. + + .. versionadded:: 3.12 + + .. data:: month_name An array that represents the months of the year in the current locale. This @@ -407,15 +430,56 @@ The :mod:`calendar` module exports the following data attributes: locale. This follows normal convention of January being month number 1, so it has a length of 13 and ``month_abbr[0]`` is the empty string. -.. data:: MONDAY - TUESDAY - WEDNESDAY - THURSDAY - FRIDAY - SATURDAY - SUNDAY - Aliases for day numbers, where ``MONDAY`` is ``0`` and ``SUNDAY`` is ``6``. +.. data:: JANUARY + FEBRUARY + MARCH + APRIL + MAY + JUNE + JULY + AUGUST + SEPTEMBER + OCTOBER + NOVEMBER + DECEMBER + + Aliases for the months of the year, + where ``JANUARY`` is ``1`` and ``DECEMBER`` is ``12``. + + .. versionadded:: 3.12 + + +.. class:: Month + + Enumeration defining months of the year as integer constants. + The members of this enumeration are exported to the module scope as + :data:`JANUARY` through :data:`DECEMBER`. + + .. versionadded:: 3.12 + + +The :mod:`calendar` module defines the following exceptions: + +.. exception:: IllegalMonthError(month) + + A subclass of :exc:`ValueError`, + raised when the given month number is outside of the range 1-12 (inclusive). + + .. attribute:: month + + The invalid month number. + + +.. exception:: IllegalWeekdayError(weekday) + + A subclass of :exc:`ValueError`, + raised when the given weekday number is outside of the range 0-6 (inclusive). + + .. attribute:: weekday + + The invalid weekday number. + .. seealso:: @@ -425,3 +489,146 @@ The :mod:`calendar` module exports the following data attributes: Module :mod:`time` Low-level time related functions. + + +.. _calendar-cli: + +Command-Line Usage +------------------ + +.. versionadded:: 2.5 + +The :mod:`calendar` module can be executed as a script from the command line +to interactively print a calendar. + +.. code-block:: shell + + python -m calendar [-h] [-L LOCALE] [-e ENCODING] [-t {text,html}] + [-w WIDTH] [-l LINES] [-s SPACING] [-m MONTHS] [-c CSS] + [year] [month] + + +For example, to print a calendar for the year 2000: + +.. code-block:: console + + $ python -m calendar 2000 + 2000 + + January February March + Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su + 1 2 1 2 3 4 5 6 1 2 3 4 5 + 3 4 5 6 7 8 9 7 8 9 10 11 12 13 6 7 8 9 10 11 12 + 10 11 12 13 14 15 16 14 15 16 17 18 19 20 13 14 15 16 17 18 19 + 17 18 19 20 21 22 23 21 22 23 24 25 26 27 20 21 22 23 24 25 26 + 24 25 26 27 28 29 30 28 29 27 28 29 30 31 + 31 + + April May June + Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su + 1 2 1 2 3 4 5 6 7 1 2 3 4 + 3 4 5 6 7 8 9 8 9 10 11 12 13 14 5 6 7 8 9 10 11 + 10 11 12 13 14 15 16 15 16 17 18 19 20 21 12 13 14 15 16 17 18 + 17 18 19 20 21 22 23 22 23 24 25 26 27 28 19 20 21 22 23 24 25 + 24 25 26 27 28 29 30 29 30 31 26 27 28 29 30 + + July August September + Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su + 1 2 1 2 3 4 5 6 1 2 3 + 3 4 5 6 7 8 9 7 8 9 10 11 12 13 4 5 6 7 8 9 10 + 10 11 12 13 14 15 16 14 15 16 17 18 19 20 11 12 13 14 15 16 17 + 17 18 19 20 21 22 23 21 22 23 24 25 26 27 18 19 20 21 22 23 24 + 24 25 26 27 28 29 30 28 29 30 31 25 26 27 28 29 30 + 31 + + October November December + Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su + 1 1 2 3 4 5 1 2 3 + 2 3 4 5 6 7 8 6 7 8 9 10 11 12 4 5 6 7 8 9 10 + 9 10 11 12 13 14 15 13 14 15 16 17 18 19 11 12 13 14 15 16 17 + 16 17 18 19 20 21 22 20 21 22 23 24 25 26 18 19 20 21 22 23 24 + 23 24 25 26 27 28 29 27 28 29 30 25 26 27 28 29 30 31 + 30 31 + + +The following options are accepted: + +.. program:: calendar + + +.. option:: --help, -h + + Show the help message and exit. + + +.. option:: --locale LOCALE, -L LOCALE + + The locale to use for month and weekday names. + Defaults to English. + + +.. option:: --encoding ENCODING, -e ENCODING + + The encoding to use for output. + :option:`--encoding` is required if :option:`--locale` is set. + + +.. option:: --type {text,html}, -t {text,html} + + Print the calendar to the terminal as text, + or as an HTML document. + + +.. option:: year + + The year to print the calendar for. + Must be a number between 1 and 9999. + Defaults to the current year. + + +.. option:: month + + The month of the specified :option:`year` to print the calendar for. + Must be a number between 1 and 12, + and may only be used in text mode. + Defaults to printing a calendar for the full year. + + +*Text-mode options:* + +.. option:: --width WIDTH, -w WIDTH + + The width of the date column in terminal columns. + The date is printed centred in the column. + Any value lower than 2 is ignored. + Defaults to 2. + + +.. option:: --lines LINES, -l LINES + + The number of lines for each week in terminal rows. + The date is printed top-aligned. + Any value lower than 1 is ignored. + Defaults to 1. + + +.. option:: --spacing SPACING, -s SPACING + + The space between months in columns. + Any value lower than 2 is ignored. + Defaults to 6. + + +.. option:: --months MONTHS, -m MONTHS + + The number of months printed per row. + Defaults to 3. + + +*HTML-mode options:* + +.. option:: --css CSS, -c CSS + + The path of a CSS stylesheet to use for the calendar. + This must either be relative to the generated HTML, + or an absolute HTTP or ``file:///`` URL. diff --git a/Doc/library/cmath.rst b/Doc/library/cmath.rst index 28cd96b0..fdac51d9 100644 --- a/Doc/library/cmath.rst +++ b/Doc/library/cmath.rst @@ -9,17 +9,33 @@ This module provides access to mathematical functions for complex numbers. The functions in this module accept integers, floating-point numbers or complex numbers as arguments. They will also accept any Python object that has either a -:meth:`__complex__` or a :meth:`__float__` method: these methods are used to +:meth:`~object.__complex__` or a :meth:`~object.__float__` method: these methods are used to convert the object to a complex or floating-point number, respectively, and the function is then applied to the result of the conversion. .. note:: - On platforms with hardware and system-level support for signed - zeros, functions involving branch cuts are continuous on *both* - sides of the branch cut: the sign of the zero distinguishes one - side of the branch cut from the other. On platforms that do not - support signed zeros the continuity is as specified below. + For functions involving branch cuts, we have the problem of deciding how to + define those functions on the cut itself. Following Kahan's "Branch cuts for + complex elementary functions" paper, as well as Annex G of C99 and later C + standards, we use the sign of zero to distinguish one side of the branch cut + from the other: for a branch cut along (a portion of) the real axis we look + at the sign of the imaginary part, while for a branch cut along the + imaginary axis we look at the sign of the real part. + + For example, the :func:`cmath.sqrt` function has a branch cut along the + negative real axis. An argument of ``complex(-2.0, -0.0)`` is treated as + though it lies *below* the branch cut, and so gives a result on the negative + imaginary axis:: + + >>> cmath.sqrt(complex(-2.0, -0.0)) + -1.4142135623730951j + + But an argument of ``complex(-2.0, 0.0)`` is treated as though it lies above + the branch cut:: + + >>> cmath.sqrt(complex(-2.0, 0.0)) + 1.4142135623730951j Conversions to and from polar coordinates @@ -44,14 +60,11 @@ rectangular coordinates to polar coordinates and back. .. function:: phase(x) - Return the phase of *x* (also known as the *argument* of *x*), as a - float. ``phase(x)`` is equivalent to ``math.atan2(x.imag, - x.real)``. The result lies in the range [-\ *π*, *π*], and the branch - cut for this operation lies along the negative real axis, - continuous from above. On systems with support for signed zeros - (which includes most systems in current use), this means that the - sign of the result is the same as the sign of ``x.imag``, even when - ``x.imag`` is zero:: + Return the phase of *x* (also known as the *argument* of *x*), as a float. + ``phase(x)`` is equivalent to ``math.atan2(x.imag, x.real)``. The result + lies in the range [-\ *π*, *π*], and the branch cut for this operation lies + along the negative real axis. The sign of the result is the same as the + sign of ``x.imag``, even when ``x.imag`` is zero:: >>> phase(complex(-1.0, 0.0)) 3.141592653589793 @@ -92,8 +105,8 @@ Power and logarithmic functions .. function:: log(x[, base]) Returns the logarithm of *x* to the given *base*. If the *base* is not - specified, returns the natural logarithm of *x*. There is one branch cut, from 0 - along the negative real axis to -∞, continuous from above. + specified, returns the natural logarithm of *x*. There is one branch cut, + from 0 along the negative real axis to -∞. .. function:: log10(x) @@ -112,9 +125,9 @@ Trigonometric functions .. function:: acos(x) - Return the arc cosine of *x*. There are two branch cuts: One extends right from - 1 along the real axis to ∞, continuous from below. The other extends left from - -1 along the real axis to -∞, continuous from above. + Return the arc cosine of *x*. There are two branch cuts: One extends right + from 1 along the real axis to ∞. The other extends left from -1 along the + real axis to -∞. .. function:: asin(x) @@ -125,9 +138,8 @@ Trigonometric functions .. function:: atan(x) Return the arc tangent of *x*. There are two branch cuts: One extends from - ``1j`` along the imaginary axis to ``∞j``, continuous from the right. The - other extends from ``-1j`` along the imaginary axis to ``-∞j``, continuous - from the left. + ``1j`` along the imaginary axis to ``∞j``. The other extends from ``-1j`` + along the imaginary axis to ``-∞j``. .. function:: cos(x) @@ -151,23 +163,21 @@ Hyperbolic functions .. function:: acosh(x) Return the inverse hyperbolic cosine of *x*. There is one branch cut, - extending left from 1 along the real axis to -∞, continuous from above. + extending left from 1 along the real axis to -∞. .. function:: asinh(x) Return the inverse hyperbolic sine of *x*. There are two branch cuts: - One extends from ``1j`` along the imaginary axis to ``∞j``, - continuous from the right. The other extends from ``-1j`` along - the imaginary axis to ``-∞j``, continuous from the left. + One extends from ``1j`` along the imaginary axis to ``∞j``. The other + extends from ``-1j`` along the imaginary axis to ``-∞j``. .. function:: atanh(x) Return the inverse hyperbolic tangent of *x*. There are two branch cuts: One - extends from ``1`` along the real axis to ``∞``, continuous from below. The - other extends from ``-1`` along the real axis to ``-∞``, continuous from - above. + extends from ``1`` along the real axis to ``∞``. The other extends from + ``-1`` along the real axis to ``-∞``. .. function:: cosh(x) @@ -291,7 +301,7 @@ Constants .. versionadded:: 3.6 -.. index:: module: math +.. index:: pair: module; math Note that the selection of functions is similar, but not identical, to that in module :mod:`math`. The reason for having two modules is that some users aren't diff --git a/Doc/library/code.rst b/Doc/library/code.rst index 538e5afc..3d7f43c8 100644 --- a/Doc/library/code.rst +++ b/Doc/library/code.rst @@ -163,12 +163,12 @@ interpreter objects as well as the following additions. Push a line of source text to the interpreter. The line should not have a trailing newline; it may have internal newlines. The line is appended to a - buffer and the interpreter's :meth:`runsource` method is called with the + buffer and the interpreter's :meth:`~InteractiveInterpreter.runsource` method is called with the concatenated contents of the buffer as source. If this indicates that the command was executed or invalid, the buffer is reset; otherwise, the command is incomplete, and the buffer is left as it was after the line was appended. The return value is ``True`` if more input is required, ``False`` if the line was - dealt with in some way (this is the same as :meth:`runsource`). + dealt with in some way (this is the same as :meth:`!runsource`). .. method:: InteractiveConsole.resetbuffer() diff --git a/Doc/library/codecs.rst b/Doc/library/codecs.rst index 82252363..2db4a67d 100644 --- a/Doc/library/codecs.rst +++ b/Doc/library/codecs.rst @@ -345,9 +345,10 @@ The following error handlers can be used with all Python +-------------------------+-----------------------------------------------+ | ``'backslashreplace'`` | Replace with backslashed escape sequences. | | | On encoding, use hexadecimal form of Unicode | -| | code point with formats ``\xhh`` ``\uxxxx`` | -| | ``\Uxxxxxxxx``. On decoding, use hexadecimal | -| | form of byte value with format ``\xhh``. | +| | code point with formats :samp:`\\x{hh}` | +| | :samp:`\\u{xxxx}` :samp:`\\U{xxxxxxxx}`. | +| | On decoding, use hexadecimal form of byte | +| | value with format :samp:`\\x{hh}`. | | | Implemented in | | | :func:`backslashreplace_errors`. | +-------------------------+-----------------------------------------------+ @@ -373,8 +374,9 @@ The following error handlers are only applicable to encoding (within +=========================+===============================================+ | ``'xmlcharrefreplace'`` | Replace with XML/HTML numeric character | | | reference, which is a decimal form of Unicode | -| | code point with format ``&#num;`` Implemented | -| | in :func:`xmlcharrefreplace_errors`. | +| | code point with format :samp:`&#{num};`. | +| | Implemented in | +| | :func:`xmlcharrefreplace_errors`. | +-------------------------+-----------------------------------------------+ | ``'namereplace'`` | Replace with ``\N{...}`` escape sequences, | | | what appears in the braces is the Name | @@ -478,8 +480,9 @@ functions: Malformed data is replaced by a backslashed escape sequence. On encoding, use the hexadecimal form of Unicode code point with formats - ``\xhh`` ``\uxxxx`` ``\Uxxxxxxxx``. On decoding, use the hexadecimal form of - byte value with format ``\xhh``. + :samp:`\\x{hh}` :samp:`\\u{xxxx}` :samp:`\\U{xxxxxxxx}`. + On decoding, use the hexadecimal form of + byte value with format :samp:`\\x{hh}`. .. versionchanged:: 3.5 Works with decoding and translating. @@ -492,7 +495,7 @@ functions: The unencodable character is replaced by an appropriate XML/HTML numeric character reference, which is a decimal form of Unicode code point with - format ``&#num;`` . + format :samp:`&#{num};` . .. function:: namereplace_errors(exception) @@ -1346,9 +1349,10 @@ encodings. | | | supported. | +--------------------+---------+---------------------------+ | raw_unicode_escape | | Latin-1 encoding with | -| | | ``\uXXXX`` and | -| | | ``\UXXXXXXXX`` for other | -| | | code points. Existing | +| | | :samp:`\\u{XXXX}` and | +| | | :samp:`\\U{XXXXXXXX}` | +| | | for other code points. | +| | | Existing | | | | backslashes are not | | | | escaped in any way. | | | | It is used in the Python | diff --git a/Doc/library/codeop.rst b/Doc/library/codeop.rst index c66b9d3e..55606e1c 100644 --- a/Doc/library/codeop.rst +++ b/Doc/library/codeop.rst @@ -19,10 +19,10 @@ module instead. There are two parts to this job: -#. Being able to tell if a line of input completes a Python statement: in +#. Being able to tell if a line of input completes a Python statement: in short, telling whether to print '``>>>``' or '``...``' next. -#. Remembering which future statements the user has entered, so subsequent +#. Remembering which future statements the user has entered, so subsequent input can be compiled with these in effect. The :mod:`codeop` module provides a way of doing each of these things, and a way @@ -33,9 +33,9 @@ To do just the former: .. function:: compile_command(source, filename="<input>", symbol="single") Tries to compile *source*, which should be a string of Python code and return a - code object if *source* is valid Python code. In that case, the filename + code object if *source* is valid Python code. In that case, the filename attribute of the code object will be *filename*, which defaults to - ``'<input>'``. Returns ``None`` if *source* is *not* valid Python code, but is a + ``'<input>'``. Returns ``None`` if *source* is *not* valid Python code, but is a prefix of valid Python code. If there is a problem with *source*, an exception will be raised. @@ -43,9 +43,9 @@ To do just the former: :exc:`OverflowError` or :exc:`ValueError` if there is an invalid literal. The *symbol* argument determines whether *source* is compiled as a statement - (``'single'``, the default), as a sequence of statements (``'exec'``) or + (``'single'``, the default), as a sequence of :term:`statement` (``'exec'``) or as an :term:`expression` (``'eval'``). Any other value will - cause :exc:`ValueError` to be raised. + cause :exc:`ValueError` to be raised. .. note:: @@ -58,7 +58,7 @@ To do just the former: .. class:: Compile() - Instances of this class have :meth:`__call__` methods identical in signature to + Instances of this class have :meth:`~object.__call__` methods identical in signature to the built-in function :func:`compile`, but with the difference that if the instance compiles program text containing a :mod:`__future__` statement, the instance 'remembers' and compiles all subsequent program texts with the @@ -67,7 +67,7 @@ To do just the former: .. class:: CommandCompiler() - Instances of this class have :meth:`__call__` methods identical in signature to + Instances of this class have :meth:`~object.__call__` methods identical in signature to :func:`compile_command`; the difference is that if the instance compiles program - text containing a ``__future__`` statement, the instance 'remembers' and + text containing a :mod:`__future__` statement, the instance 'remembers' and compiles all subsequent program texts with the statement in force. diff --git a/Doc/library/collections.abc.rst b/Doc/library/collections.abc.rst index 132b0ce7..43a3286b 100644 --- a/Doc/library/collections.abc.rst +++ b/Doc/library/collections.abc.rst @@ -22,7 +22,7 @@ This module provides :term:`abstract base classes <abstract base class>` that can be used to test whether a class provides a particular interface; for -example, whether it is hashable or whether it is a mapping. +example, whether it is :term:`hashable` or whether it is a mapping. An :func:`issubclass` or :func:`isinstance` test for an interface works in one of three ways. @@ -177,6 +177,7 @@ ABC Inherits from Abstract Methods Mi :class:`AsyncIterable` [1]_ ``__aiter__`` :class:`AsyncIterator` [1]_ :class:`AsyncIterable` ``__anext__`` ``__aiter__`` :class:`AsyncGenerator` [1]_ :class:`AsyncIterator` ``asend``, ``athrow`` ``aclose``, ``__aiter__``, ``__anext__`` +:class:`Buffer` [1]_ ``__buffer__`` ============================== ====================== ======================= ==================================================== @@ -272,6 +273,12 @@ Collections Abstract Base Classes -- Detailed Descriptions The index() method added support for *stop* and *start* arguments. + .. deprecated-removed:: 3.12 3.14 + The :class:`ByteString` ABC has been deprecated. + For use in typing, prefer a union, like ``bytes | bytearray``, or + :class:`collections.abc.Buffer`. + For use as an ABC, prefer :class:`Sequence` or :class:`collections.abc.Buffer`. + .. class:: Set MutableSet @@ -346,6 +353,13 @@ Collections Abstract Base Classes -- Detailed Descriptions .. versionadded:: 3.6 +.. class:: Buffer + + ABC for classes that provide the :meth:`~object.__buffer__` method, + implementing the :ref:`buffer protocol <bufferobjects>`. See :pep:`688`. + + .. versionadded:: 3.12 + Examples and Recipes -------------------- @@ -406,7 +420,7 @@ Notes on using :class:`Set` and :class:`MutableSet` as a mixin: (3) The :class:`Set` mixin provides a :meth:`_hash` method to compute a hash value for the set; however, :meth:`__hash__` is not defined because not all sets - are hashable or immutable. To add set hashability using mixins, + are :term:`hashable` or immutable. To add set hashability using mixins, inherit from both :meth:`Set` and :meth:`Hashable`, then define ``__hash__ = Set._hash``. diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst index 20863837..bb46782c 100644 --- a/Doc/library/collections.rst +++ b/Doc/library/collections.rst @@ -25,7 +25,7 @@ Python's general purpose built-in containers, :class:`dict`, :class:`list`, :func:`namedtuple` factory function for creating tuple subclasses with named fields :class:`deque` list-like container with fast appends and pops on either end :class:`ChainMap` dict-like class for creating a single view of multiple mappings -:class:`Counter` dict subclass for counting hashable objects +:class:`Counter` dict subclass for counting :term:`hashable` objects :class:`OrderedDict` dict subclass that remembers the order entries were added :class:`defaultdict` dict subclass that calls a factory function to supply missing values :class:`UserDict` wrapper around dictionary objects for easier dict subclassing @@ -229,6 +229,7 @@ For example:: >>> cnt = Counter() >>> for word in ['red', 'blue', 'red', 'green', 'blue', 'blue']: ... cnt[word] += 1 + ... >>> cnt Counter({'blue': 3, 'red': 2, 'green': 1}) @@ -241,7 +242,7 @@ For example:: .. class:: Counter([iterable-or-mapping]) - A :class:`Counter` is a :class:`dict` subclass for counting hashable objects. + A :class:`Counter` is a :class:`dict` subclass for counting :term:`hashable` objects. It is a collection where elements are stored as dictionary keys and their counts are stored as dictionary values. Counts are allowed to be any integer value including zero or negative counts. The :class:`Counter` @@ -818,6 +819,7 @@ zero): >>> def constant_factory(value): ... return lambda: value + ... >>> d = defaultdict(constant_factory('<missing>')) >>> d.update(name='John', action='ran') >>> '%(name)s %(action)s to %(object)s' % d @@ -1201,6 +1203,7 @@ variants of :func:`functools.lru_cache`: .. testcode:: + from collections import OrderedDict from time import time class TimeBoundedLRU: diff --git a/Doc/library/compileall.rst b/Doc/library/compileall.rst index 180f5b81..75b97d6f 100644 --- a/Doc/library/compileall.rst +++ b/Doc/library/compileall.rst @@ -29,7 +29,7 @@ compile Python sources. Positional arguments are files to compile or directories that contain source files, traversed recursively. If no argument is given, behave as if - the command line was ``-l <directories from sys.path>``. + the command line was :samp:`-l {<directories from sys.path>}`. .. cmdoption:: -l @@ -141,9 +141,9 @@ There is no command-line option to control the optimization level used by the :func:`compile` function, because the Python interpreter itself already provides the option: :program:`python -O -m compileall`. -Similarly, the :func:`compile` function respects the :attr:`sys.pycache_prefix` +Similarly, the :func:`compile` function respects the :data:`sys.pycache_prefix` setting. The generated bytecode cache will only be useful if :func:`compile` is -run with the same :attr:`sys.pycache_prefix` (if any) that will be used at +run with the same :data:`sys.pycache_prefix` (if any) that will be used at runtime. Public functions diff --git a/Doc/library/concurrent.futures.rst b/Doc/library/concurrent.futures.rst index 8106cc23..6503d1fc 100644 --- a/Doc/library/concurrent.futures.rst +++ b/Doc/library/concurrent.futures.rst @@ -202,7 +202,7 @@ ThreadPoolExecutor Example 'http://www.cnn.com/', 'http://europe.wsj.com/', 'http://www.bbc.co.uk/', - 'http://some-made-up-domain.com/'] + 'http://nonexistant-subdomain.python.org/'] # Retrieve a single page and report the URL and contents def load_url(url, timeout): @@ -250,9 +250,10 @@ to a :class:`ProcessPoolExecutor` will result in deadlock. then :exc:`ValueError` will be raised. If *max_workers* is ``None``, then the default chosen will be at most ``61``, even if more processors are available. - *mp_context* can be a multiprocessing context or None. It will be used to - launch the workers. If *mp_context* is ``None`` or not given, the default - multiprocessing context is used. + *mp_context* can be a :mod:`multiprocessing` context or ``None``. It will be + used to launch the workers. If *mp_context* is ``None`` or not given, the + default :mod:`multiprocessing` context is used. + See :ref:`multiprocessing-start-methods`. *initializer* is an optional callable that is called at the start of each worker process; *initargs* is a tuple of arguments passed to the @@ -280,10 +281,25 @@ to a :class:`ProcessPoolExecutor` will result in deadlock. Added the *initializer* and *initargs* arguments. + .. note:: + The default :mod:`multiprocessing` start method + (see :ref:`multiprocessing-start-methods`) will change away from + *fork* in Python 3.14. Code that requires *fork* be used for their + :class:`ProcessPoolExecutor` should explicitly specify that by + passing a ``mp_context=multiprocessing.get_context("fork")`` + parameter. + .. versionchanged:: 3.11 The *max_tasks_per_child* argument was added to allow users to control the lifetime of workers in the pool. + .. versionchanged:: 3.12 + On POSIX systems, if your application has multiple threads and the + :mod:`multiprocessing` context uses the ``"fork"`` start method: + The :func:`os.fork` function called internally to spawn workers may raise a + :exc:`DeprecationWarning`. Pass a *mp_context* configured to use a + different start method. See the :func:`os.fork` documentation for + further explanation. .. _processpoolexecutor-example: diff --git a/Doc/library/concurrent.rst b/Doc/library/concurrent.rst index 2eba5365..8caea78b 100644 --- a/Doc/library/concurrent.rst +++ b/Doc/library/concurrent.rst @@ -1,5 +1,5 @@ -The :mod:`concurrent` package -============================= +The :mod:`!concurrent` package +============================== Currently, there is only one module in this package: diff --git a/Doc/library/configparser.rst b/Doc/library/configparser.rst index bfd6a7f5..bb282428 100644 --- a/Doc/library/configparser.rst +++ b/Doc/library/configparser.rst @@ -69,10 +69,10 @@ Let's take a very basic configuration file that looks like this: CompressionLevel = 9 ForwardX11 = yes - [bitbucket.org] + [forge.example] User = hg - [topsecret.server.com] + [topsecret.server.example] Port = 50022 ForwardX11 = no @@ -89,10 +89,10 @@ creating the above configuration file programmatically. >>> config['DEFAULT'] = {'ServerAliveInterval': '45', ... 'Compression': 'yes', ... 'CompressionLevel': '9'} - >>> config['bitbucket.org'] = {} - >>> config['bitbucket.org']['User'] = 'hg' - >>> config['topsecret.server.com'] = {} - >>> topsecret = config['topsecret.server.com'] + >>> config['forge.example'] = {} + >>> config['forge.example']['User'] = 'hg' + >>> config['topsecret.server.example'] = {} + >>> topsecret = config['topsecret.server.example'] >>> topsecret['Port'] = '50022' # mutates the parser >>> topsecret['ForwardX11'] = 'no' # same here >>> config['DEFAULT']['ForwardX11'] = 'yes' @@ -115,28 +115,28 @@ back and explore the data it holds. >>> config.read('example.ini') ['example.ini'] >>> config.sections() - ['bitbucket.org', 'topsecret.server.com'] - >>> 'bitbucket.org' in config + ['forge.example', 'topsecret.server.example'] + >>> 'forge.example' in config True - >>> 'bytebong.com' in config + >>> 'python.org' in config False - >>> config['bitbucket.org']['User'] + >>> config['forge.example']['User'] 'hg' >>> config['DEFAULT']['Compression'] 'yes' - >>> topsecret = config['topsecret.server.com'] + >>> topsecret = config['topsecret.server.example'] >>> topsecret['ForwardX11'] 'no' >>> topsecret['Port'] '50022' - >>> for key in config['bitbucket.org']: # doctest: +SKIP + >>> for key in config['forge.example']: # doctest: +SKIP ... print(key) user compressionlevel serveraliveinterval compression forwardx11 - >>> config['bitbucket.org']['ForwardX11'] + >>> config['forge.example']['ForwardX11'] 'yes' As we can see above, the API is pretty straightforward. The only bit of magic @@ -154,15 +154,15 @@ configuration while the previously existing keys are retained. >>> another_config = configparser.ConfigParser() >>> another_config.read('example.ini') ['example.ini'] - >>> another_config['topsecret.server.com']['Port'] + >>> another_config['topsecret.server.example']['Port'] '50022' - >>> another_config.read_string("[topsecret.server.com]\nPort=48484") - >>> another_config['topsecret.server.com']['Port'] + >>> another_config.read_string("[topsecret.server.example]\nPort=48484") + >>> another_config['topsecret.server.example']['Port'] '48484' - >>> another_config.read_dict({"topsecret.server.com": {"Port": 21212}}) - >>> another_config['topsecret.server.com']['Port'] + >>> another_config.read_dict({"topsecret.server.example": {"Port": 21212}}) + >>> another_config['topsecret.server.example']['Port'] '21212' - >>> another_config['topsecret.server.com']['ForwardX11'] + >>> another_config['topsecret.server.example']['ForwardX11'] 'no' This behaviour is equivalent to a :meth:`ConfigParser.read` call with several @@ -195,9 +195,9 @@ recognizes Boolean values from ``'yes'``/``'no'``, ``'on'``/``'off'``, >>> topsecret.getboolean('ForwardX11') False - >>> config['bitbucket.org'].getboolean('ForwardX11') + >>> config['forge.example'].getboolean('ForwardX11') True - >>> config.getboolean('bitbucket.org', 'Compression') + >>> config.getboolean('forge.example', 'Compression') True Apart from :meth:`~ConfigParser.getboolean`, config parsers also @@ -224,7 +224,7 @@ provide fallback values: Please note that default values have precedence over fallback values. For instance, in our example the ``'CompressionLevel'`` key was specified only in the ``'DEFAULT'`` section. If we try to get it from -the section ``'topsecret.server.com'``, we will always get the default, +the section ``'topsecret.server.example'``, we will always get the default, even if we specify a fallback: .. doctest:: @@ -239,7 +239,7 @@ the ``fallback`` keyword-only argument: .. doctest:: - >>> config.get('bitbucket.org', 'monster', + >>> config.get('forge.example', 'monster', ... fallback='No such things as monsters') 'No such things as monsters' @@ -935,8 +935,10 @@ ConfigParser Objects When *default_section* is given, it specifies the name for the special section holding default values for other sections and interpolation purposes - (normally named ``"DEFAULT"``). This value can be retrieved and changed on - runtime using the ``default_section`` instance attribute. + (normally named ``"DEFAULT"``). This value can be retrieved and changed at + runtime using the ``default_section`` instance attribute. This won't + re-evaluate an already parsed config file, but will be used when writing + parsed settings to a new config file. Interpolation behaviour may be customized by providing a custom handler through the *interpolation* argument. ``None`` can be used to turn off @@ -1210,28 +1212,6 @@ ConfigParser Objects names is stripped before :meth:`optionxform` is called. - .. method:: readfp(fp, filename=None) - - .. deprecated:: 3.2 - Use :meth:`read_file` instead. - - .. versionchanged:: 3.2 - :meth:`readfp` now iterates on *fp* instead of calling ``fp.readline()``. - - For existing code calling :meth:`readfp` with arguments which don't - support iteration, the following generator may be used as a wrapper - around the file-like object:: - - def readline_generator(fp): - line = fp.readline() - while line: - yield line - line = fp.readline() - - Instead of ``parser.readfp(fp)`` use - ``parser.read_file(readline_generator(fp))``. - - .. data:: MAX_INTERPOLATION_DEPTH The maximum depth for recursive interpolation for :meth:`get` when the *raw* @@ -1365,10 +1345,9 @@ Exceptions Exception raised when errors occur attempting to parse a file. - .. versionchanged:: 3.2 - The ``filename`` attribute and :meth:`__init__` argument were renamed to - ``source`` for consistency. - +.. versionchanged:: 3.12 + The ``filename`` attribute and :meth:`__init__` constructor argument were + removed. They have been available using the name ``source`` since 3.2. .. rubric:: Footnotes diff --git a/Doc/library/constants.rst b/Doc/library/constants.rst index 38dd552a..401dc9a3 100644 --- a/Doc/library/constants.rst +++ b/Doc/library/constants.rst @@ -22,16 +22,16 @@ A small number of constants live in the built-in namespace. They are: An object frequently used to represent the absence of a value, as when default arguments are not passed to a function. Assignments to ``None`` are illegal and raise a :exc:`SyntaxError`. - ``None`` is the sole instance of the :data:`NoneType` type. + ``None`` is the sole instance of the :data:`~types.NoneType` type. .. data:: NotImplemented A special value which should be returned by the binary special methods - (e.g. :meth:`__eq__`, :meth:`__lt__`, :meth:`__add__`, :meth:`__rsub__`, + (e.g. :meth:`~object.__eq__`, :meth:`~object.__lt__`, :meth:`~object.__add__`, :meth:`~object.__rsub__`, etc.) to indicate that the operation is not implemented with respect to the other type; may be returned by the in-place binary special methods - (e.g. :meth:`__imul__`, :meth:`__iand__`, etc.) for the same purpose. + (e.g. :meth:`~object.__imul__`, :meth:`~object.__iand__`, etc.) for the same purpose. It should not be evaluated in a boolean context. ``NotImplemented`` is the sole instance of the :data:`types.NotImplementedType` type. diff --git a/Doc/library/contextlib.rst b/Doc/library/contextlib.rst index 1b55868c..7cd081d1 100644 --- a/Doc/library/contextlib.rst +++ b/Doc/library/contextlib.rst @@ -304,8 +304,15 @@ Functions and classes provided: This context manager is :ref:`reentrant <reentrant-cms>`. + If the code within the :keyword:`!with` block raises an + :exc:`ExceptionGroup`, suppressed exceptions are removed from the + group. If any exceptions in the group are not suppressed, a group containing them is re-raised. + .. versionadded:: 3.4 + .. versionchanged:: 3.12 + ``suppress`` now supports suppressing exceptions raised as + part of an :exc:`ExceptionGroup`. .. function:: redirect_stdout(new_target) diff --git a/Doc/library/copy.rst b/Doc/library/copy.rst index a8bc2fa5..8f32477e 100644 --- a/Doc/library/copy.rst +++ b/Doc/library/copy.rst @@ -68,7 +68,7 @@ Shallow copies of dictionaries can be made using :meth:`dict.copy`, and of lists by assigning a slice of the entire list, for example, ``copied_list = original_list[:]``. -.. index:: module: pickle +.. index:: pair: module; pickle Classes can use the same interfaces to control copying that they use to control pickling. See the description of module :mod:`pickle` for information on these diff --git a/Doc/library/copyreg.rst b/Doc/library/copyreg.rst index 866b180f..2a28c043 100644 --- a/Doc/library/copyreg.rst +++ b/Doc/library/copyreg.rst @@ -7,8 +7,8 @@ **Source code:** :source:`Lib/copyreg.py` .. index:: - module: pickle - module: copy + pair: module; pickle + pair: module; copy -------------- @@ -28,8 +28,8 @@ Such constructors may be factory functions or class instances. .. function:: pickle(type, function, constructor_ob=None) Declares that *function* should be used as a "reduction" function for objects - of type *type*. *function* should return either a string or a tuple - containing two or three elements. See the :attr:`~pickle.Pickler.dispatch_table` + of type *type*. *function* must return either a string or a tuple + containing between two and six elements. See the :attr:`~pickle.Pickler.dispatch_table` for more details on the interface of *function*. The *constructor_ob* parameter is a legacy feature and is now ignored, but if diff --git a/Doc/library/crypt.rst b/Doc/library/crypt.rst index 740084b4..51f91463 100644 --- a/Doc/library/crypt.rst +++ b/Doc/library/crypt.rst @@ -20,6 +20,7 @@ The :mod:`crypt` module is deprecated (see :pep:`PEP 594 <594#crypt>` for details and alternatives). The :mod:`hashlib` module is a potential replacement for certain use cases. + The `passlib <https://pypi.org/project/passlib/>`_ package can replace all use cases of this module. -------------- diff --git a/Doc/library/csv.rst b/Doc/library/csv.rst index f7e85f2b..64baa69b 100644 --- a/Doc/library/csv.rst +++ b/Doc/library/csv.rst @@ -167,6 +167,8 @@ The :mod:`csv` module defines the following classes: All other optional or keyword arguments are passed to the underlying :class:`reader` instance. + If the argument passed to *fieldnames* is an iterator, it will be coerced to a :class:`list`. + .. versionchanged:: 3.6 Returned rows are now of type :class:`OrderedDict`. @@ -209,6 +211,8 @@ The :mod:`csv` module defines the following classes: Note that unlike the :class:`DictReader` class, the *fieldnames* parameter of the :class:`DictWriter` class is not optional. + If the argument passed to *fieldnames* is an iterator, it will be coerced to a :class:`list`. + A short usage example:: import csv @@ -323,7 +327,7 @@ The :mod:`csv` module defines the following constants: Instructs :class:`writer` objects to quote all non-numeric fields. - Instructs the reader to convert all non-quoted fields to type *float*. + Instructs :class:`reader` objects to convert all non-quoted fields to type *float*. .. data:: QUOTE_NONE @@ -333,7 +337,25 @@ The :mod:`csv` module defines the following constants: character. If *escapechar* is not set, the writer will raise :exc:`Error` if any characters that require escaping are encountered. - Instructs :class:`reader` to perform no special processing of quote characters. + Instructs :class:`reader` objects to perform no special processing of quote characters. + +.. data:: QUOTE_NOTNULL + + Instructs :class:`writer` objects to quote all fields which are not + ``None``. This is similar to :data:`QUOTE_ALL`, except that if a + field value is ``None`` an empty (unquoted) string is written. + + Instructs :class:`reader` objects to interpret an empty (unquoted) field as None and + to otherwise behave as :data:`QUOTE_ALL`. + +.. data:: QUOTE_STRINGS + + Instructs :class:`writer` objects to always place quotes around fields + which are strings. This is similar to :data:`QUOTE_NONNUMERIC`, except that if a + field value is ``None`` an empty (unquoted) string is written. + + Instructs :class:`reader` objects to interpret an empty (unquoted) string as ``None`` and + to otherwise behave as :data:`QUOTE_NONNUMERIC`. The :mod:`csv` module defines the following exception: @@ -454,7 +476,7 @@ Reader objects have the following public attributes: DictReader objects have the following public attribute: -.. attribute:: csvreader.fieldnames +.. attribute:: DictReader.fieldnames If not passed as a parameter when creating the object, this attribute is initialized upon first access or when the first record is read from the diff --git a/Doc/library/ctypes.rst b/Doc/library/ctypes.rst index 282dff38..19cee107 100644 --- a/Doc/library/ctypes.rst +++ b/Doc/library/ctypes.rst @@ -41,7 +41,7 @@ You load libraries by accessing them as attributes of these objects. *cdll* loads libraries which export functions using the standard ``cdecl`` calling convention, while *windll* libraries call functions using the ``stdcall`` calling convention. *oledll* also uses the ``stdcall`` calling convention, and -assumes the functions return a Windows :c:type:`HRESULT` error code. The error +assumes the functions return a Windows :c:type:`!HRESULT` error code. The error code is used to automatically raise an :class:`OSError` exception when the function call fails. @@ -72,8 +72,9 @@ Windows appends the usual ``.dll`` file suffix automatically. On Linux, it is required to specify the filename *including* the extension to load a library, so attribute access can not be used to load libraries. Either the -:meth:`LoadLibrary` method of the dll loaders should be used, or you should load -the library by creating an instance of CDLL by calling the constructor:: +:meth:`~LibraryLoader.LoadLibrary` method of the dll loaders should be used, +or you should load the library by creating an instance of CDLL by calling +the constructor:: >>> cdll.LoadLibrary("libc.so.6") # doctest: +LINUX <CDLL 'libc.so.6', handle ... at ...> @@ -150,15 +151,14 @@ Calling functions ^^^^^^^^^^^^^^^^^ You can call these functions like any other Python callable. This example uses -the ``time()`` function, which returns system time in seconds since the Unix -epoch, and the ``GetModuleHandleA()`` function, which returns a win32 module -handle. +the ``rand()`` function, which takes no arguments and returns a pseudo-random integer:: -This example calls both functions with a ``NULL`` pointer (``None`` should be used -as the ``NULL`` pointer):: + >>> print(libc.rand()) # doctest: +SKIP + 1804289383 + +On Windows, you can call the ``GetModuleHandleA()`` function, which returns a win32 module +handle (passing ``None`` as single argument to call it with a ``NULL`` pointer):: - >>> print(libc.time(None)) # doctest: +SKIP - 1150640792 >>> print(hex(windll.kernel32.GetModuleHandleA(None))) # doctest: +WINDOWS 0x1d000000 >>> @@ -221,7 +221,7 @@ Fundamental data types +----------------------+------------------------------------------+----------------------------+ | :class:`c_char` | :c:expr:`char` | 1-character bytes object | +----------------------+------------------------------------------+----------------------------+ -| :class:`c_wchar` | :c:expr:`wchar_t` | 1-character string | +| :class:`c_wchar` | :c:type:`wchar_t` | 1-character string | +----------------------+------------------------------------------+----------------------------+ | :class:`c_byte` | :c:expr:`char` | int | +----------------------+------------------------------------------+----------------------------+ @@ -244,11 +244,13 @@ Fundamental data types | :class:`c_ulonglong` | :c:expr:`unsigned __int64` or | int | | | :c:expr:`unsigned long long` | | +----------------------+------------------------------------------+----------------------------+ -| :class:`c_size_t` | :c:expr:`size_t` | int | +| :class:`c_size_t` | :c:type:`size_t` | int | +----------------------+------------------------------------------+----------------------------+ -| :class:`c_ssize_t` | :c:expr:`ssize_t` or | int | +| :class:`c_ssize_t` | :c:type:`ssize_t` or | int | | | :c:expr:`Py_ssize_t` | | +----------------------+------------------------------------------+----------------------------+ +| :class:`c_time_t` | :c:type:`time_t` | int | ++----------------------+------------------------------------------+----------------------------+ | :class:`c_float` | :c:expr:`float` | float | +----------------------+------------------------------------------+----------------------------+ | :class:`c_double` | :c:expr:`double` | float | @@ -332,9 +334,9 @@ property:: 10 b'Hi\x00lo\x00\x00\x00\x00\x00' >>> -The :func:`create_string_buffer` function replaces the old :func:`c_buffer` +The :func:`create_string_buffer` function replaces the old :func:`!c_buffer` function (which is still available as an alias). To create a mutable memory -block containing unicode characters of the C type :c:expr:`wchar_t`, use the +block containing unicode characters of the C type :c:type:`wchar_t`, use the :func:`create_unicode_buffer` function. @@ -374,23 +376,23 @@ that they can be converted to the required C data type:: .. _ctypes-calling-variadic-functions: -Calling varadic functions -^^^^^^^^^^^^^^^^^^^^^^^^^ +Calling variadic functions +^^^^^^^^^^^^^^^^^^^^^^^^^^ On a lot of platforms calling variadic functions through ctypes is exactly the same as calling functions with a fixed number of parameters. On some platforms, and in particular ARM64 for Apple Platforms, the calling convention for variadic functions is different than that for regular functions. -On those platforms it is required to specify the *argtypes* attribute for the -regular, non-variadic, function arguments: +On those platforms it is required to specify the :attr:`~_FuncPtr.argtypes` +attribute for the regular, non-variadic, function arguments: .. code-block:: python3 libc.printf.argtypes = [ctypes.c_char_p] -Because specifying the attribute does inhibit portability it is advised to always -specify ``argtypes`` for all variadic functions. +Because specifying the attribute does not inhibit portability it is advised to always +specify :attr:`~_FuncPtr.argtypes` for all variadic functions. .. _ctypes-calling-functions-with-own-custom-data-types: @@ -399,9 +401,10 @@ Calling functions with your own custom data types ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ You can also customize :mod:`ctypes` argument conversion to allow instances of -your own classes be used as function arguments. :mod:`ctypes` looks for an -:attr:`_as_parameter_` attribute and uses this as the function argument. Of -course, it must be one of integer, string, or bytes:: +your own classes be used as function arguments. :mod:`ctypes` looks for an +:attr:`!_as_parameter_` attribute and uses this as the function argument. The +attribute must be an integer, string, bytes, a :mod:`ctypes` instance, or an +object with an :attr:`!_as_parameter_` attribute:: >>> class Bottles: ... def __init__(self, number): @@ -413,7 +416,7 @@ course, it must be one of integer, string, or bytes:: 19 >>> -If you don't want to store the instance's data in the :attr:`_as_parameter_` +If you don't want to store the instance's data in the :attr:`!_as_parameter_` instance variable, you could define a :class:`property` which makes the attribute available on request. @@ -424,9 +427,9 @@ Specifying the required argument types (function prototypes) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ It is possible to specify the required argument types of functions exported from -DLLs by setting the :attr:`argtypes` attribute. +DLLs by setting the :attr:`~_FuncPtr.argtypes` attribute. -:attr:`argtypes` must be a sequence of C data types (the ``printf`` function is +:attr:`~_FuncPtr.argtypes` must be a sequence of C data types (the :func:`!printf` function is probably not a good example here, because it takes a variable number and different types of parameters depending on the format string, on the other hand this is quite handy to experiment with this feature):: @@ -450,14 +453,14 @@ prototype for a C function), and tries to convert the arguments to valid types:: >>> If you have defined your own classes which you pass to function calls, you have -to implement a :meth:`from_param` class method for them to be able to use them -in the :attr:`argtypes` sequence. The :meth:`from_param` class method receives +to implement a :meth:`~_CData.from_param` class method for them to be able to use them +in the :attr:`~_FuncPtr.argtypes` sequence. The :meth:`~_CData.from_param` class method receives the Python object passed to the function call, it should do a typecheck or whatever is needed to make sure this object is acceptable, and then return the -object itself, its :attr:`_as_parameter_` attribute, or whatever you want to +object itself, its :attr:`!_as_parameter_` attribute, or whatever you want to pass as the C function argument in this case. Again, the result should be an integer, string, bytes, a :mod:`ctypes` instance, or an object with an -:attr:`_as_parameter_` attribute. +:attr:`!_as_parameter_` attribute. .. _ctypes-return-types: @@ -465,11 +468,34 @@ integer, string, bytes, a :mod:`ctypes` instance, or an object with an Return types ^^^^^^^^^^^^ +.. testsetup:: + + from ctypes import CDLL, c_char, c_char_p + from ctypes.util import find_library + libc = CDLL(find_library('c')) + strchr = libc.strchr + + By default functions are assumed to return the C :c:expr:`int` type. Other -return types can be specified by setting the :attr:`restype` attribute of the +return types can be specified by setting the :attr:`~_FuncPtr.restype` attribute of the function object. -Here is a more advanced example, it uses the ``strchr`` function, which expects +The C prototype of :c:func:`time` is ``time_t time(time_t *)``. Because :c:type:`time_t` +might be of a different type than the default return type :c:expr:`int`, you should +specify the :attr:`!restype` attribute:: + + >>> libc.time.restype = c_time_t + +The argument types can be specified using :attr:`~_FuncPtr.argtypes`:: + + >>> libc.time.argtypes = (POINTER(c_time_t),) + +To call the function with a ``NULL`` pointer as first argument, use ``None``:: + + >>> print(libc.time(None)) # doctest: +SKIP + 1150640792 + +Here is a more advanced example, it uses the :func:`!strchr` function, which expects a string pointer and a char, and returns a pointer to a string:: >>> strchr = libc.strchr @@ -482,26 +508,27 @@ a string pointer and a char, and returns a pointer to a string:: None >>> -If you want to avoid the ``ord("x")`` calls above, you can set the -:attr:`argtypes` attribute, and the second argument will be converted from a -single character Python bytes object into a C char:: +If you want to avoid the :func:`ord("x") <ord>` calls above, you can set the +:attr:`~_FuncPtr.argtypes` attribute, and the second argument will be converted from a +single character Python bytes object into a C char: + +.. doctest:: >>> strchr.restype = c_char_p >>> strchr.argtypes = [c_char_p, c_char] >>> strchr(b"abcdef", b"d") - 'def' + b'def' >>> strchr(b"abcdef", b"def") Traceback (most recent call last): - File "<stdin>", line 1, in <module> - ArgumentError: argument 2: TypeError: one character string expected + ctypes.ArgumentError: argument 2: TypeError: one character bytes, bytearray or integer expected >>> print(strchr(b"abcdef", b"x")) None >>> strchr(b"abcdef", b"d") - 'def' + b'def' >>> You can also use a callable Python object (a function or a class for example) as -the :attr:`restype` attribute, if the foreign function returns an integer. The +the :attr:`~_FuncPtr.restype` attribute, if the foreign function returns an integer. The callable will be called with the *integer* the C function returns, and the result of this call will be used as the result of your function call. This is useful to check for error return values and automatically raise an exception:: @@ -529,7 +556,8 @@ get the string representation of an error code, and *returns* an exception. :func:`GetLastError` to retrieve it. Please note that a much more powerful error checking mechanism is available -through the :attr:`errcheck` attribute; see the reference manual for details. +through the :attr:`~_FuncPtr.errcheck` attribute; +see the reference manual for details. .. _ctypes-passing-pointers: @@ -567,7 +595,7 @@ Structures and unions Structures and unions must derive from the :class:`Structure` and :class:`Union` base classes which are defined in the :mod:`ctypes` module. Each subclass must -define a :attr:`_fields_` attribute. :attr:`_fields_` must be a list of +define a :attr:`~Structure._fields_` attribute. :attr:`!_fields_` must be a list of *2-tuples*, containing a *field name* and a *field type*. The field type must be a :mod:`ctypes` type like :class:`c_int`, or any other @@ -639,9 +667,9 @@ Structure/union alignment and byte order By default, Structure and Union fields are aligned in the same way the C compiler does it. It is possible to override this behavior by specifying a -:attr:`_pack_` class attribute in the subclass definition. This must be set to a -positive integer and specifies the maximum alignment for the fields. This is -what ``#pragma pack(n)`` also does in MSVC. +:attr:`~Structure._pack_` class attribute in the subclass definition. +This must be set to a positive integer and specifies the maximum alignment for the fields. +This is what ``#pragma pack(n)`` also does in MSVC. :mod:`ctypes` uses the native byte order for Structures and Unions. To build structures with non-native byte order, you can use one of the @@ -657,7 +685,7 @@ Bit fields in structures and unions It is possible to create structures and unions containing bit fields. Bit fields are only possible for integer fields, the bit width is specified as the third -item in the :attr:`_fields_` tuples:: +item in the :attr:`~Structure._fields_` tuples:: >>> class Int(Structure): ... _fields_ = [("first_16", c_int, 16), @@ -828,7 +856,7 @@ Type conversions ^^^^^^^^^^^^^^^^ Usually, ctypes does strict type checking. This means, if you have -``POINTER(c_int)`` in the :attr:`argtypes` list of a function or as the type of +``POINTER(c_int)`` in the :attr:`~_FuncPtr.argtypes` list of a function or as the type of a member field in a structure definition, only instances of exactly the same type are accepted. There are some exceptions to this rule, where ctypes accepts other objects. For example, you can pass compatible array instances instead of @@ -849,7 +877,7 @@ pointer types. So, for ``POINTER(c_int)``, ctypes accepts an array of c_int:: >>> In addition, if a function argument is explicitly declared to be a pointer type -(such as ``POINTER(c_int)``) in :attr:`argtypes`, an object of the pointed +(such as ``POINTER(c_int)``) in :attr:`~_FuncPtr.argtypes`, an object of the pointed type (``c_int`` in this case) can be passed to the function. ctypes will apply the required :func:`byref` conversion in this case automatically. @@ -925,8 +953,8 @@ work:: >>> because the new ``class cell`` is not available in the class statement itself. -In :mod:`ctypes`, we can define the ``cell`` class and set the :attr:`_fields_` -attribute later, after the class statement:: +In :mod:`ctypes`, we can define the ``cell`` class and set the +:attr:`~Structure._fields_` attribute later, after the class statement:: >>> from ctypes import * >>> class cell(Structure): @@ -976,8 +1004,8 @@ argument, and the callback functions expected argument types as the remaining arguments. I will present an example here which uses the standard C library's -:c:func:`qsort` function, that is used to sort items with the help of a callback -function. :c:func:`qsort` will be used to sort an array of integers:: +:c:func:`!qsort` function, that is used to sort items with the help of a callback +function. :c:func:`!qsort` will be used to sort an array of integers:: >>> IntArray5 = c_int * 5 >>> ia = IntArray5(5, 1, 7, 33, 99) @@ -985,7 +1013,7 @@ function. :c:func:`qsort` will be used to sort an array of integers:: >>> qsort.restype = None >>> -:func:`qsort` must be called with a pointer to the data to sort, the number of +:func:`!qsort` must be called with a pointer to the data to sort, the number of items in the data array, the size of one item, and a pointer to the comparison function, the callback. The callback will then be called with two pointers to items, and it must return a negative integer if the first item is smaller than @@ -1074,18 +1102,16 @@ Accessing values exported from dlls ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Some shared libraries not only export functions, they also export variables. An -example in the Python library itself is the :c:data:`Py_OptimizeFlag`, an integer -set to 0, 1, or 2, depending on the :option:`-O` or :option:`-OO` flag given on -startup. +example in the Python library itself is the :c:data:`Py_Version`, Python +runtime version number encoded in a single constant integer. -:mod:`ctypes` can access values like this with the :meth:`in_dll` class methods of +:mod:`ctypes` can access values like this with the :meth:`~_CData.in_dll` class methods of the type. *pythonapi* is a predefined symbol giving access to the Python C api:: - >>> opt_flag = c_int.in_dll(pythonapi, "Py_OptimizeFlag") - >>> print(opt_flag) - c_long(0) - >>> + >>> version = ctypes.c_int.in_dll(ctypes.pythonapi, "Py_Version") + >>> print(hex(version.value)) + 0x30c00a0 If the interpreter would have been started with :option:`-O`, the sample would have printed ``c_long(1)``, or ``c_long(2)`` if :option:`-OO` would have been @@ -1269,13 +1295,13 @@ Finding shared libraries When programming in a compiled language, shared libraries are accessed when compiling/linking a program, and when the program is run. -The purpose of the :func:`find_library` function is to locate a library in a way +The purpose of the :func:`~ctypes.util.find_library` function is to locate a library in a way similar to what the compiler or runtime loader does (on platforms with several versions of a shared library the most recent should be loaded), while the ctypes library loaders act like when a program is run, and call the runtime loader directly. -The :mod:`ctypes.util` module provides a function which can help to determine +The :mod:`!ctypes.util` module provides a function which can help to determine the library to load. @@ -1290,7 +1316,7 @@ the library to load. The exact functionality is system dependent. -On Linux, :func:`find_library` tries to run external programs +On Linux, :func:`~ctypes.util.find_library` tries to run external programs (``/sbin/ldconfig``, ``gcc``, ``objdump`` and ``ld``) to find the library file. It returns the filename of the library file. @@ -1309,7 +1335,7 @@ Here are some examples:: 'libbz2.so.1.0' >>> -On macOS, :func:`find_library` tries several predefined naming schemes and paths +On macOS, :func:`~ctypes.util.find_library` tries several predefined naming schemes and paths to locate the library, and returns a full pathname if successful:: >>> from ctypes.util import find_library @@ -1323,13 +1349,13 @@ to locate the library, and returns a full pathname if successful:: '/System/Library/Frameworks/AGL.framework/AGL' >>> -On Windows, :func:`find_library` searches along the system search path, and +On Windows, :func:`~ctypes.util.find_library` searches along the system search path, and returns the full pathname, but since there is no predefined naming scheme a call like ``find_library("c")`` will fail and return ``None``. If wrapping a shared library with :mod:`ctypes`, it *may* be better to determine the shared library name at development time, and hardcode that into the wrapper -module instead of using :func:`find_library` to locate the library at runtime. +module instead of using :func:`~ctypes.util.find_library` to locate the library at runtime. .. _ctypes-loading-shared-libraries: @@ -1357,6 +1383,10 @@ way is to instantiate one of the following classes: DLLs and determine which one is not found using Windows debugging and tracing tools. + .. versionchanged:: 3.12 + + The *name* parameter can now be a :term:`path-like object`. + .. seealso:: `Microsoft DUMPBIN tool <https://docs.microsoft.com/cpp/build/reference/dependents>`_ @@ -1375,6 +1405,10 @@ way is to instantiate one of the following classes: .. versionchanged:: 3.3 :exc:`WindowsError` used to be raised. + .. versionchanged:: 3.12 + + The *name* parameter can now be a :term:`path-like object`. + .. class:: WinDLL(name, mode=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False, winmode=None) @@ -1382,6 +1416,10 @@ way is to instantiate one of the following classes: functions in these libraries use the ``stdcall`` calling convention, and are assumed to return :c:expr:`int` by default. + .. versionchanged:: 3.12 + + The *name* parameter can now be a :term:`path-like object`. + The Python :term:`global interpreter lock` is released before calling any function exported by these libraries, and reacquired afterwards. @@ -1395,12 +1433,16 @@ function exported by these libraries, and reacquired afterwards. Thus, this is only useful to call Python C api functions directly. + .. versionchanged:: 3.12 + + The *name* parameter can now be a :term:`path-like object`. + All these classes can be instantiated by calling them with at least one argument, the pathname of the shared library. If you have an existing handle to an already loaded shared library, it can be passed as the ``handle`` named -parameter, otherwise the underlying platforms ``dlopen`` or ``LoadLibrary`` -function is used to load the library into the process, and to get a handle to -it. +parameter, otherwise the underlying platforms :c:func:`!dlopen` or +:c:func:`!LoadLibrary` function is used to load the library into +the process, and to get a handle to it. The *mode* parameter can be used to specify how the library is loaded. For details, consult the :manpage:`dlopen(3)` manpage. On Windows, *mode* is @@ -1420,14 +1462,14 @@ to a new value and returns the former value. The *use_last_error* parameter, when set to true, enables the same mechanism for the Windows error code which is managed by the :func:`GetLastError` and -:func:`SetLastError` Windows API functions; :func:`ctypes.get_last_error` and +:func:`!SetLastError` Windows API functions; :func:`ctypes.get_last_error` and :func:`ctypes.set_last_error` are used to request and change the ctypes private copy of the windows error code. The *winmode* parameter is used on Windows to specify how the library is loaded (since *mode* is ignored). It takes any value that is valid for the Win32 API -``LoadLibraryEx`` flags parameter. When omitted, the default is to use the flags -that result in the most secure DLL load to avoiding issues such as DLL +``LoadLibraryEx`` flags parameter. When omitted, the default is to use the +flags that result in the most secure DLL load, which avoids issues such as DLL hijacking. Passing the full path to the DLL is the safest way to ensure the correct library and dependencies are loaded. @@ -1483,8 +1525,8 @@ underscore to not clash with exported function names: Shared libraries can also be loaded by using one of the prefabricated objects, which are instances of the :class:`LibraryLoader` class, either by calling the -:meth:`LoadLibrary` method, or by retrieving the library as attribute of the -loader instance. +:meth:`~LibraryLoader.LoadLibrary` method, or by retrieving the library as +attribute of the loader instance. .. class:: LibraryLoader(dlltype) @@ -1492,7 +1534,7 @@ loader instance. Class which loads shared libraries. *dlltype* should be one of the :class:`CDLL`, :class:`PyDLL`, :class:`WinDLL`, or :class:`OleDLL` types. - :meth:`__getattr__` has special behavior: It allows loading a shared library by + :meth:`!__getattr__` has special behavior: It allows loading a shared library by accessing it as attribute of a library loader instance. The result is cached, so repeated attribute accesses return the same library each time. @@ -1537,7 +1579,7 @@ object is available: An instance of :class:`PyDLL` that exposes Python C API functions as attributes. Note that all these functions are assumed to return C :c:expr:`int`, which is of course not always the truth, so you have to assign - the correct :attr:`restype` attribute to use these functions. + the correct :attr:`!restype` attribute to use these functions. .. audit-event:: ctypes.dlopen name ctypes.LibraryLoader @@ -1589,7 +1631,7 @@ They are instances of a private class: the callable will be called with this integer, allowing further processing or error checking. Using this is deprecated, for more flexible post processing or error checking use a ctypes data type as - :attr:`restype` and assign a callable to the :attr:`errcheck` attribute. + :attr:`!restype` and assign a callable to the :attr:`errcheck` attribute. .. attribute:: argtypes @@ -1600,14 +1642,14 @@ They are instances of a private class: unspecified arguments as well. When a foreign function is called, each actual argument is passed to the - :meth:`from_param` class method of the items in the :attr:`argtypes` + :meth:`~_CData.from_param` class method of the items in the :attr:`argtypes` tuple, this method allows adapting the actual argument to an object that the foreign function accepts. For example, a :class:`c_char_p` item in the :attr:`argtypes` tuple will convert a string passed as argument into a bytes object using ctypes conversion rules. New: It is now possible to put items in argtypes which are not ctypes - types, but each item must have a :meth:`from_param` method which returns a + types, but each item must have a :meth:`~_CData.from_param` method which returns a value usable as argument (integer, string, ctypes instance). This allows defining adapters that can adapt custom objects as function parameters. @@ -1621,7 +1663,7 @@ They are instances of a private class: :module: *result* is what the foreign function returns, as specified by the - :attr:`restype` attribute. + :attr:`!restype` attribute. *func* is the foreign function object itself, this allows reusing the same callable object to check or post process the results of several @@ -1642,12 +1684,12 @@ They are instances of a private class: passed arguments. -.. audit-event:: ctypes.seh_exception code foreign-functions +.. audit-event:: ctypes.set_exception code foreign-functions On Windows, when a foreign function call raises a system exception (for example, due to an access violation), it will be captured and replaced with a suitable Python exception. Further, an auditing event - ``ctypes.seh_exception`` with argument ``code`` will be raised, allowing an + ``ctypes.set_exception`` with argument ``code`` will be raised, allowing an audit hook to replace the exception with its own. .. audit-event:: ctypes.call_function func_pointer,arguments foreign-functions @@ -1731,12 +1773,12 @@ different ways, depending on the type and number of the parameters in the call: COM methods use a special calling convention: They require a pointer to the COM interface as first argument, in addition to those parameters that - are specified in the :attr:`argtypes` tuple. + are specified in the :attr:`!argtypes` tuple. The optional *paramflags* parameter creates foreign function wrappers with much more functionality than the features described above. - *paramflags* must be a tuple of the same length as :attr:`argtypes`. + *paramflags* must be a tuple of the same length as :attr:`~_FuncPtr.argtypes`. Each item in this tuple contains further information about a parameter, it must be a tuple containing one, two, or three items. @@ -1806,7 +1848,7 @@ value if there is a single one, or a tuple containing the output parameter values when there are more than one, so the GetWindowRect function now returns a RECT instance, when called. -Output parameters can be combined with the :attr:`errcheck` protocol to do +Output parameters can be combined with the :attr:`~_FuncPtr.errcheck` protocol to do further output processing and error checking. The win32 ``GetWindowRect`` api function returns a ``BOOL`` to signal success or failure, so this function could do the error checking, and raises an exception when the api call failed:: @@ -1819,7 +1861,7 @@ do the error checking, and raises an exception when the api call failed:: >>> GetWindowRect.errcheck = errcheck >>> -If the :attr:`errcheck` function returns the argument tuple it receives +If the :attr:`~_FuncPtr.errcheck` function returns the argument tuple it receives unchanged, :mod:`ctypes` continues the normal processing it does on the output parameters. If you want to return a tuple of window coordinates instead of a ``RECT`` instance, you can retrieve the fields in the function and return them @@ -1969,7 +2011,7 @@ Utility functions .. function:: get_last_error() Windows only: returns the current value of the ctypes-private copy of the system - :data:`LastError` variable in the calling thread. + :data:`!LastError` variable in the calling thread. .. audit-event:: ctypes.get_last_error "" ctypes.get_last_error @@ -1987,17 +2029,17 @@ Utility functions specifying an address, or a ctypes instance. -.. function:: POINTER(type) +.. function:: POINTER(type, /) - This factory function creates and returns a new ctypes pointer type. Pointer - types are cached and reused internally, so calling this function repeatedly is - cheap. *type* must be a ctypes type. + Create and return a new ctypes pointer type. Pointer types are cached and + reused internally, so calling this function repeatedly is cheap. + *type* must be a ctypes type. -.. function:: pointer(obj) +.. function:: pointer(obj, /) - This function creates a new pointer instance, pointing to *obj*. The returned - object is of the type ``POINTER(type(obj))``. + Create a new pointer instance, pointing to *obj*. + The returned object is of the type ``POINTER(type(obj))``. Note: If you just want to pass a pointer to an object to a foreign function call, you should use ``byref(obj)`` which is much faster. @@ -2022,7 +2064,7 @@ Utility functions .. function:: set_last_error(value) Windows only: set the current value of the ctypes-private copy of the system - :data:`LastError` variable in the calling thread to *value* and return the + :data:`!LastError` variable in the calling thread to *value* and return the previous value. .. audit-event:: ctypes.set_last_error error ctypes.set_last_error @@ -2118,8 +2160,8 @@ Data types This method adapts *obj* to a ctypes type. It is called with the actual object used in a foreign function call when the type is present in the - foreign function's :attr:`argtypes` tuple; it must return an object that - can be used as a function call parameter. + foreign function's :attr:`~_FuncPtr.argtypes` tuple; + it must return an object that can be used as a function call parameter. All ctypes data types have a default implementation of this classmethod that normally returns *obj* if that is an instance of the type. Some @@ -2184,13 +2226,13 @@ Fundamental data types Fundamental data types, when returned as foreign function call results, or, for example, by retrieving structure field members or array items, are transparently converted to native Python types. In other words, if a foreign function has a -:attr:`restype` of :class:`c_char_p`, you will always receive a Python bytes +:attr:`~_FuncPtr.restype` of :class:`c_char_p`, you will always receive a Python bytes object, *not* a :class:`c_char_p` instance. .. XXX above is false, it actually returns a Unicode string Subclasses of fundamental data types do *not* inherit this behavior. So, if a -foreign functions :attr:`restype` is a subclass of :class:`c_void_p`, you will +foreign functions :attr:`!restype` is a subclass of :class:`c_void_p`, you will receive an instance of this subclass from the function call. Of course, you can get the value of the pointer by accessing the ``value`` attribute. @@ -2297,6 +2339,13 @@ These are the fundamental ctypes data types: .. versionadded:: 3.2 +.. class:: c_time_t + + Represents the C :c:type:`time_t` datatype. + + .. versionadded:: 3.12 + + .. class:: c_ubyte Represents the C :c:expr:`unsigned char` datatype, it interprets the value as @@ -2361,7 +2410,7 @@ These are the fundamental ctypes data types: .. class:: c_wchar - Represents the C :c:expr:`wchar_t` datatype, and interprets the value as a + Represents the C :c:type:`wchar_t` datatype, and interprets the value as a single character unicode string. The constructor accepts an optional string initializer, the length of the string must be exactly one character. @@ -2382,7 +2431,7 @@ These are the fundamental ctypes data types: .. class:: HRESULT - Windows only: Represents a :c:type:`HRESULT` value, which contains success or + Windows only: Represents a :c:type:`!HRESULT` value, which contains success or error information for a function or method call. @@ -2391,9 +2440,9 @@ These are the fundamental ctypes data types: Represents the C :c:expr:`PyObject *` datatype. Calling this without an argument creates a ``NULL`` :c:expr:`PyObject *` pointer. -The :mod:`ctypes.wintypes` module provides quite some other Windows specific -data types, for example :c:type:`HWND`, :c:type:`WPARAM`, or :c:type:`DWORD`. Some -useful structures like :c:type:`MSG` or :c:type:`RECT` are also defined. +The :mod:`!ctypes.wintypes` module provides quite some other Windows specific +data types, for example :c:type:`!HWND`, :c:type:`!WPARAM`, or :c:type:`!DWORD`. +Some useful structures like :c:type:`!MSG` or :c:type:`!RECT` are also defined. .. _ctypes-structured-data-types: @@ -2480,6 +2529,7 @@ fields, or any other data types containing pointer type fields. An optional small integer that allows overriding the alignment of structure fields in the instance. :attr:`_pack_` must already be defined when :attr:`_fields_` is assigned, otherwise it will have no effect. + Setting this attribute to 0 is the same as not setting it at all. .. attribute:: _anonymous_ diff --git a/Doc/library/curses.ascii.rst b/Doc/library/curses.ascii.rst index e1d11719..410b76e7 100644 --- a/Doc/library/curses.ascii.rst +++ b/Doc/library/curses.ascii.rst @@ -15,81 +15,81 @@ The :mod:`curses.ascii` module supplies name constants for ASCII characters and functions to test membership in various ASCII character classes. The constants supplied are names for control characters as follows: -+--------------+----------------------------------------------+ -| Name | Meaning | -+==============+==============================================+ -| :const:`NUL` | | -+--------------+----------------------------------------------+ -| :const:`SOH` | Start of heading, console interrupt | -+--------------+----------------------------------------------+ -| :const:`STX` | Start of text | -+--------------+----------------------------------------------+ -| :const:`ETX` | End of text | -+--------------+----------------------------------------------+ -| :const:`EOT` | End of transmission | -+--------------+----------------------------------------------+ -| :const:`ENQ` | Enquiry, goes with :const:`ACK` flow control | -+--------------+----------------------------------------------+ -| :const:`ACK` | Acknowledgement | -+--------------+----------------------------------------------+ -| :const:`BEL` | Bell | -+--------------+----------------------------------------------+ -| :const:`BS` | Backspace | -+--------------+----------------------------------------------+ -| :const:`TAB` | Tab | -+--------------+----------------------------------------------+ -| :const:`HT` | Alias for :const:`TAB`: "Horizontal tab" | -+--------------+----------------------------------------------+ -| :const:`LF` | Line feed | -+--------------+----------------------------------------------+ -| :const:`NL` | Alias for :const:`LF`: "New line" | -+--------------+----------------------------------------------+ -| :const:`VT` | Vertical tab | -+--------------+----------------------------------------------+ -| :const:`FF` | Form feed | -+--------------+----------------------------------------------+ -| :const:`CR` | Carriage return | -+--------------+----------------------------------------------+ -| :const:`SO` | Shift-out, begin alternate character set | -+--------------+----------------------------------------------+ -| :const:`SI` | Shift-in, resume default character set | -+--------------+----------------------------------------------+ -| :const:`DLE` | Data-link escape | -+--------------+----------------------------------------------+ -| :const:`DC1` | XON, for flow control | -+--------------+----------------------------------------------+ -| :const:`DC2` | Device control 2, block-mode flow control | -+--------------+----------------------------------------------+ -| :const:`DC3` | XOFF, for flow control | -+--------------+----------------------------------------------+ -| :const:`DC4` | Device control 4 | -+--------------+----------------------------------------------+ -| :const:`NAK` | Negative acknowledgement | -+--------------+----------------------------------------------+ -| :const:`SYN` | Synchronous idle | -+--------------+----------------------------------------------+ -| :const:`ETB` | End transmission block | -+--------------+----------------------------------------------+ -| :const:`CAN` | Cancel | -+--------------+----------------------------------------------+ -| :const:`EM` | End of medium | -+--------------+----------------------------------------------+ -| :const:`SUB` | Substitute | -+--------------+----------------------------------------------+ -| :const:`ESC` | Escape | -+--------------+----------------------------------------------+ -| :const:`FS` | File separator | -+--------------+----------------------------------------------+ -| :const:`GS` | Group separator | -+--------------+----------------------------------------------+ -| :const:`RS` | Record separator, block-mode terminator | -+--------------+----------------------------------------------+ -| :const:`US` | Unit separator | -+--------------+----------------------------------------------+ -| :const:`SP` | Space | -+--------------+----------------------------------------------+ -| :const:`DEL` | Delete | -+--------------+----------------------------------------------+ ++---------------+----------------------------------------------+ +| Name | Meaning | ++===============+==============================================+ +| .. data:: NUL | | ++---------------+----------------------------------------------+ +| .. data:: SOH | Start of heading, console interrupt | ++---------------+----------------------------------------------+ +| .. data:: STX | Start of text | ++---------------+----------------------------------------------+ +| .. data:: ETX | End of text | ++---------------+----------------------------------------------+ +| .. data:: EOT | End of transmission | ++---------------+----------------------------------------------+ +| .. data:: ENQ | Enquiry, goes with :const:`ACK` flow control | ++---------------+----------------------------------------------+ +| .. data:: ACK | Acknowledgement | ++---------------+----------------------------------------------+ +| .. data:: BEL | Bell | ++---------------+----------------------------------------------+ +| .. data:: BS | Backspace | ++---------------+----------------------------------------------+ +| .. data:: TAB | Tab | ++---------------+----------------------------------------------+ +| .. data:: HT | Alias for :const:`TAB`: "Horizontal tab" | ++---------------+----------------------------------------------+ +| .. data:: LF | Line feed | ++---------------+----------------------------------------------+ +| .. data:: NL | Alias for :const:`LF`: "New line" | ++---------------+----------------------------------------------+ +| .. data:: VT | Vertical tab | ++---------------+----------------------------------------------+ +| .. data:: FF | Form feed | ++---------------+----------------------------------------------+ +| .. data:: CR | Carriage return | ++---------------+----------------------------------------------+ +| .. data:: SO | Shift-out, begin alternate character set | ++---------------+----------------------------------------------+ +| .. data:: SI | Shift-in, resume default character set | ++---------------+----------------------------------------------+ +| .. data:: DLE | Data-link escape | ++---------------+----------------------------------------------+ +| .. data:: DC1 | XON, for flow control | ++---------------+----------------------------------------------+ +| .. data:: DC2 | Device control 2, block-mode flow control | ++---------------+----------------------------------------------+ +| .. data:: DC3 | XOFF, for flow control | ++---------------+----------------------------------------------+ +| .. data:: DC4 | Device control 4 | ++---------------+----------------------------------------------+ +| .. data:: NAK | Negative acknowledgement | ++---------------+----------------------------------------------+ +| .. data:: SYN | Synchronous idle | ++---------------+----------------------------------------------+ +| .. data:: ETB | End transmission block | ++---------------+----------------------------------------------+ +| .. data:: CAN | Cancel | ++---------------+----------------------------------------------+ +| .. data:: EM | End of medium | ++---------------+----------------------------------------------+ +| .. data:: SUB | Substitute | ++---------------+----------------------------------------------+ +| .. data:: ESC | Escape | ++---------------+----------------------------------------------+ +| .. data:: FS | File separator | ++---------------+----------------------------------------------+ +| .. data:: GS | Group separator | ++---------------+----------------------------------------------+ +| .. data:: RS | Record separator, block-mode terminator | ++---------------+----------------------------------------------+ +| .. data:: US | Unit separator | ++---------------+----------------------------------------------+ +| .. data:: SP | Space | ++---------------+----------------------------------------------+ +| .. data:: DEL | Delete | ++---------------+----------------------------------------------+ Note that many of these have little practical significance in modern usage. The mnemonics derive from teleprinter conventions that predate digital computers. diff --git a/Doc/library/curses.rst b/Doc/library/curses.rst index 56311033..9ab67c21 100644 --- a/Doc/library/curses.rst +++ b/Doc/library/curses.rst @@ -44,9 +44,6 @@ Linux and the BSD variants of Unix. Tutorial material on using curses with Python, by Andrew Kuchling and Eric Raymond. - The :source:`Tools/demo/` directory in the Python source distribution contains - some example programs using the curses bindings provided by this module. - .. _curses-functions: @@ -110,7 +107,7 @@ The module :mod:`curses` defines the following functions: Return the attribute value for displaying text in the specified color pair. Only the first 256 color pairs are supported. This attribute value can be combined with :const:`A_STANDOUT`, :const:`A_REVERSE`, - and the other :const:`A_\*` attributes. :func:`pair_number` is the counterpart + and the other :const:`!A_\*` attributes. :func:`pair_number` is the counterpart to this function. @@ -226,7 +223,7 @@ The module :mod:`curses` defines the following functions: .. function:: getwin(file) - Read window related data stored in the file by an earlier :func:`putwin` call. + Read window related data stored in the file by an earlier :func:`window.putwin` call. The routine then creates and initializes a new window using that data, returning the new window object. @@ -644,7 +641,8 @@ The module :mod:`curses` defines the following functions: .. function:: update_lines_cols() - Update :envvar:`LINES` and :envvar:`COLS`. Useful for detecting manual screen resize. + Update the :const:`LINES` and :const:`COLS` module variables. + Useful for detecting manual screen resize. .. versionadded:: 3.5 @@ -1326,9 +1324,9 @@ The :mod:`curses` module defines the following data members: .. data:: version +.. data:: __version__ - A bytes object representing the current version of the module. Also available as - :const:`__version__`. + A bytes object representing the current version of the module. .. data:: ncurses_version @@ -1342,51 +1340,72 @@ The :mod:`curses` module defines the following data members: .. versionadded:: 3.8 +.. data:: COLORS + + The maximum number of colors the terminal can support. + It is defined only after the call to :func:`start_color`. + +.. data:: COLOR_PAIRS + + The maximum number of color pairs the terminal can support. + It is defined only after the call to :func:`start_color`. + +.. data:: COLS + + The width of the screen, i.e., the number of columns. + It is defined only after the call to :func:`initscr`. + Updated by :func:`update_lines_cols`, :func:`resizeterm` and + :func:`resize_term`. + +.. data:: LINES + + The height of the screen, i.e., the number of lines. + It is defined only after the call to :func:`initscr`. + Updated by :func:`update_lines_cols`, :func:`resizeterm` and + :func:`resize_term`. + Some constants are available to specify character cell attributes. The exact constants available are system dependent. -+------------------+-------------------------------+ -| Attribute | Meaning | -+==================+===============================+ -| ``A_ALTCHARSET`` | Alternate character set mode | -+------------------+-------------------------------+ -| ``A_BLINK`` | Blink mode | -+------------------+-------------------------------+ -| ``A_BOLD`` | Bold mode | -+------------------+-------------------------------+ -| ``A_DIM`` | Dim mode | -+------------------+-------------------------------+ -| ``A_INVIS`` | Invisible or blank mode | -+------------------+-------------------------------+ -| ``A_ITALIC`` | Italic mode | -+------------------+-------------------------------+ -| ``A_NORMAL`` | Normal attribute | -+------------------+-------------------------------+ -| ``A_PROTECT`` | Protected mode | -+------------------+-------------------------------+ -| ``A_REVERSE`` | Reverse background and | -| | foreground colors | -+------------------+-------------------------------+ -| ``A_STANDOUT`` | Standout mode | -+------------------+-------------------------------+ -| ``A_UNDERLINE`` | Underline mode | -+------------------+-------------------------------+ -| ``A_HORIZONTAL`` | Horizontal highlight | -+------------------+-------------------------------+ -| ``A_LEFT`` | Left highlight | -+------------------+-------------------------------+ -| ``A_LOW`` | Low highlight | -+------------------+-------------------------------+ -| ``A_RIGHT`` | Right highlight | -+------------------+-------------------------------+ -| ``A_TOP`` | Top highlight | -+------------------+-------------------------------+ -| ``A_VERTICAL`` | Vertical highlight | -+------------------+-------------------------------+ -| ``A_CHARTEXT`` | Bit-mask to extract a | -| | character | -+------------------+-------------------------------+ ++------------------------+-------------------------------+ +| Attribute | Meaning | ++========================+===============================+ +| .. data:: A_ALTCHARSET | Alternate character set mode | ++------------------------+-------------------------------+ +| .. data:: A_BLINK | Blink mode | ++------------------------+-------------------------------+ +| .. data:: A_BOLD | Bold mode | ++------------------------+-------------------------------+ +| .. data:: A_DIM | Dim mode | ++------------------------+-------------------------------+ +| .. data:: A_INVIS | Invisible or blank mode | ++------------------------+-------------------------------+ +| .. data:: A_ITALIC | Italic mode | ++------------------------+-------------------------------+ +| .. data:: A_NORMAL | Normal attribute | ++------------------------+-------------------------------+ +| .. data:: A_PROTECT | Protected mode | ++------------------------+-------------------------------+ +| .. data:: A_REVERSE | Reverse background and | +| | foreground colors | ++------------------------+-------------------------------+ +| .. data:: A_STANDOUT | Standout mode | ++------------------------+-------------------------------+ +| .. data:: A_UNDERLINE | Underline mode | ++------------------------+-------------------------------+ +| .. data:: A_HORIZONTAL | Horizontal highlight | ++------------------------+-------------------------------+ +| .. data:: A_LEFT | Left highlight | ++------------------------+-------------------------------+ +| .. data:: A_LOW | Low highlight | ++------------------------+-------------------------------+ +| .. data:: A_RIGHT | Right highlight | ++------------------------+-------------------------------+ +| .. data:: A_TOP | Top highlight | ++------------------------+-------------------------------+ +| .. data:: A_VERTICAL | Vertical highlight | ++------------------------+-------------------------------+ .. versionadded:: 3.7 ``A_ITALIC`` was added. @@ -1394,220 +1413,220 @@ The exact constants available are system dependent. Several constants are available to extract corresponding attributes returned by some methods. -+------------------+-------------------------------+ -| Bit-mask | Meaning | -+==================+===============================+ -| ``A_ATTRIBUTES`` | Bit-mask to extract | -| | attributes | -+------------------+-------------------------------+ -| ``A_CHARTEXT`` | Bit-mask to extract a | -| | character | -+------------------+-------------------------------+ -| ``A_COLOR`` | Bit-mask to extract | -| | color-pair field information | -+------------------+-------------------------------+ ++-------------------------+-------------------------------+ +| Bit-mask | Meaning | ++=========================+===============================+ +| .. data:: A_ATTRIBUTES | Bit-mask to extract | +| | attributes | ++-------------------------+-------------------------------+ +| .. data:: A_CHARTEXT | Bit-mask to extract a | +| | character | ++-------------------------+-------------------------------+ +| .. data:: A_COLOR | Bit-mask to extract | +| | color-pair field information | ++-------------------------+-------------------------------+ Keys are referred to by integer constants with names starting with ``KEY_``. The exact keycaps available are system dependent. .. XXX this table is far too large! should it be alphabetized? -+-------------------+--------------------------------------------+ -| Key constant | Key | -+===================+============================================+ -| ``KEY_MIN`` | Minimum key value | -+-------------------+--------------------------------------------+ -| ``KEY_BREAK`` | Break key (unreliable) | -+-------------------+--------------------------------------------+ -| ``KEY_DOWN`` | Down-arrow | -+-------------------+--------------------------------------------+ -| ``KEY_UP`` | Up-arrow | -+-------------------+--------------------------------------------+ -| ``KEY_LEFT`` | Left-arrow | -+-------------------+--------------------------------------------+ -| ``KEY_RIGHT`` | Right-arrow | -+-------------------+--------------------------------------------+ -| ``KEY_HOME`` | Home key (upward+left arrow) | -+-------------------+--------------------------------------------+ -| ``KEY_BACKSPACE`` | Backspace (unreliable) | -+-------------------+--------------------------------------------+ -| ``KEY_F0`` | Function keys. Up to 64 function keys are | -| | supported. | -+-------------------+--------------------------------------------+ -| ``KEY_Fn`` | Value of function key *n* | -+-------------------+--------------------------------------------+ -| ``KEY_DL`` | Delete line | -+-------------------+--------------------------------------------+ -| ``KEY_IL`` | Insert line | -+-------------------+--------------------------------------------+ -| ``KEY_DC`` | Delete character | -+-------------------+--------------------------------------------+ -| ``KEY_IC`` | Insert char or enter insert mode | -+-------------------+--------------------------------------------+ -| ``KEY_EIC`` | Exit insert char mode | -+-------------------+--------------------------------------------+ -| ``KEY_CLEAR`` | Clear screen | -+-------------------+--------------------------------------------+ -| ``KEY_EOS`` | Clear to end of screen | -+-------------------+--------------------------------------------+ -| ``KEY_EOL`` | Clear to end of line | -+-------------------+--------------------------------------------+ -| ``KEY_SF`` | Scroll 1 line forward | -+-------------------+--------------------------------------------+ -| ``KEY_SR`` | Scroll 1 line backward (reverse) | -+-------------------+--------------------------------------------+ -| ``KEY_NPAGE`` | Next page | -+-------------------+--------------------------------------------+ -| ``KEY_PPAGE`` | Previous page | -+-------------------+--------------------------------------------+ -| ``KEY_STAB`` | Set tab | -+-------------------+--------------------------------------------+ -| ``KEY_CTAB`` | Clear tab | -+-------------------+--------------------------------------------+ -| ``KEY_CATAB`` | Clear all tabs | -+-------------------+--------------------------------------------+ -| ``KEY_ENTER`` | Enter or send (unreliable) | -+-------------------+--------------------------------------------+ -| ``KEY_SRESET`` | Soft (partial) reset (unreliable) | -+-------------------+--------------------------------------------+ -| ``KEY_RESET`` | Reset or hard reset (unreliable) | -+-------------------+--------------------------------------------+ -| ``KEY_PRINT`` | Print | -+-------------------+--------------------------------------------+ -| ``KEY_LL`` | Home down or bottom (lower left) | -+-------------------+--------------------------------------------+ -| ``KEY_A1`` | Upper left of keypad | -+-------------------+--------------------------------------------+ -| ``KEY_A3`` | Upper right of keypad | -+-------------------+--------------------------------------------+ -| ``KEY_B2`` | Center of keypad | -+-------------------+--------------------------------------------+ -| ``KEY_C1`` | Lower left of keypad | -+-------------------+--------------------------------------------+ -| ``KEY_C3`` | Lower right of keypad | -+-------------------+--------------------------------------------+ -| ``KEY_BTAB`` | Back tab | -+-------------------+--------------------------------------------+ -| ``KEY_BEG`` | Beg (beginning) | -+-------------------+--------------------------------------------+ -| ``KEY_CANCEL`` | Cancel | -+-------------------+--------------------------------------------+ -| ``KEY_CLOSE`` | Close | -+-------------------+--------------------------------------------+ -| ``KEY_COMMAND`` | Cmd (command) | -+-------------------+--------------------------------------------+ -| ``KEY_COPY`` | Copy | -+-------------------+--------------------------------------------+ -| ``KEY_CREATE`` | Create | -+-------------------+--------------------------------------------+ -| ``KEY_END`` | End | -+-------------------+--------------------------------------------+ -| ``KEY_EXIT`` | Exit | -+-------------------+--------------------------------------------+ -| ``KEY_FIND`` | Find | -+-------------------+--------------------------------------------+ -| ``KEY_HELP`` | Help | -+-------------------+--------------------------------------------+ -| ``KEY_MARK`` | Mark | -+-------------------+--------------------------------------------+ -| ``KEY_MESSAGE`` | Message | -+-------------------+--------------------------------------------+ -| ``KEY_MOVE`` | Move | -+-------------------+--------------------------------------------+ -| ``KEY_NEXT`` | Next | -+-------------------+--------------------------------------------+ -| ``KEY_OPEN`` | Open | -+-------------------+--------------------------------------------+ -| ``KEY_OPTIONS`` | Options | -+-------------------+--------------------------------------------+ -| ``KEY_PREVIOUS`` | Prev (previous) | -+-------------------+--------------------------------------------+ -| ``KEY_REDO`` | Redo | -+-------------------+--------------------------------------------+ -| ``KEY_REFERENCE`` | Ref (reference) | -+-------------------+--------------------------------------------+ -| ``KEY_REFRESH`` | Refresh | -+-------------------+--------------------------------------------+ -| ``KEY_REPLACE`` | Replace | -+-------------------+--------------------------------------------+ -| ``KEY_RESTART`` | Restart | -+-------------------+--------------------------------------------+ -| ``KEY_RESUME`` | Resume | -+-------------------+--------------------------------------------+ -| ``KEY_SAVE`` | Save | -+-------------------+--------------------------------------------+ -| ``KEY_SBEG`` | Shifted Beg (beginning) | -+-------------------+--------------------------------------------+ -| ``KEY_SCANCEL`` | Shifted Cancel | -+-------------------+--------------------------------------------+ -| ``KEY_SCOMMAND`` | Shifted Command | -+-------------------+--------------------------------------------+ -| ``KEY_SCOPY`` | Shifted Copy | -+-------------------+--------------------------------------------+ -| ``KEY_SCREATE`` | Shifted Create | -+-------------------+--------------------------------------------+ -| ``KEY_SDC`` | Shifted Delete char | -+-------------------+--------------------------------------------+ -| ``KEY_SDL`` | Shifted Delete line | -+-------------------+--------------------------------------------+ -| ``KEY_SELECT`` | Select | -+-------------------+--------------------------------------------+ -| ``KEY_SEND`` | Shifted End | -+-------------------+--------------------------------------------+ -| ``KEY_SEOL`` | Shifted Clear line | -+-------------------+--------------------------------------------+ -| ``KEY_SEXIT`` | Shifted Exit | -+-------------------+--------------------------------------------+ -| ``KEY_SFIND`` | Shifted Find | -+-------------------+--------------------------------------------+ -| ``KEY_SHELP`` | Shifted Help | -+-------------------+--------------------------------------------+ -| ``KEY_SHOME`` | Shifted Home | -+-------------------+--------------------------------------------+ -| ``KEY_SIC`` | Shifted Input | -+-------------------+--------------------------------------------+ -| ``KEY_SLEFT`` | Shifted Left arrow | -+-------------------+--------------------------------------------+ -| ``KEY_SMESSAGE`` | Shifted Message | -+-------------------+--------------------------------------------+ -| ``KEY_SMOVE`` | Shifted Move | -+-------------------+--------------------------------------------+ -| ``KEY_SNEXT`` | Shifted Next | -+-------------------+--------------------------------------------+ -| ``KEY_SOPTIONS`` | Shifted Options | -+-------------------+--------------------------------------------+ -| ``KEY_SPREVIOUS`` | Shifted Prev | -+-------------------+--------------------------------------------+ -| ``KEY_SPRINT`` | Shifted Print | -+-------------------+--------------------------------------------+ -| ``KEY_SREDO`` | Shifted Redo | -+-------------------+--------------------------------------------+ -| ``KEY_SREPLACE`` | Shifted Replace | -+-------------------+--------------------------------------------+ -| ``KEY_SRIGHT`` | Shifted Right arrow | -+-------------------+--------------------------------------------+ -| ``KEY_SRSUME`` | Shifted Resume | -+-------------------+--------------------------------------------+ -| ``KEY_SSAVE`` | Shifted Save | -+-------------------+--------------------------------------------+ -| ``KEY_SSUSPEND`` | Shifted Suspend | -+-------------------+--------------------------------------------+ -| ``KEY_SUNDO`` | Shifted Undo | -+-------------------+--------------------------------------------+ -| ``KEY_SUSPEND`` | Suspend | -+-------------------+--------------------------------------------+ -| ``KEY_UNDO`` | Undo | -+-------------------+--------------------------------------------+ -| ``KEY_MOUSE`` | Mouse event has occurred | -+-------------------+--------------------------------------------+ -| ``KEY_RESIZE`` | Terminal resize event | -+-------------------+--------------------------------------------+ -| ``KEY_MAX`` | Maximum key value | -+-------------------+--------------------------------------------+ ++-------------------------+--------------------------------------------+ +| Key constant | Key | ++=========================+============================================+ +| .. data:: KEY_MIN | Minimum key value | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_BREAK | Break key (unreliable) | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_DOWN | Down-arrow | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_UP | Up-arrow | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_LEFT | Left-arrow | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_RIGHT | Right-arrow | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_HOME | Home key (upward+left arrow) | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_BACKSPACE | Backspace (unreliable) | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_F0 | Function keys. Up to 64 function keys are | +| | supported. | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_Fn | Value of function key *n* | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_DL | Delete line | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_IL | Insert line | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_DC | Delete character | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_IC | Insert char or enter insert mode | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_EIC | Exit insert char mode | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_CLEAR | Clear screen | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_EOS | Clear to end of screen | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_EOL | Clear to end of line | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_SF | Scroll 1 line forward | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_SR | Scroll 1 line backward (reverse) | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_NPAGE | Next page | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_PPAGE | Previous page | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_STAB | Set tab | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_CTAB | Clear tab | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_CATAB | Clear all tabs | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_ENTER | Enter or send (unreliable) | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_SRESET | Soft (partial) reset (unreliable) | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_RESET | Reset or hard reset (unreliable) | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_PRINT | Print | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_LL | Home down or bottom (lower left) | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_A1 | Upper left of keypad | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_A3 | Upper right of keypad | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_B2 | Center of keypad | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_C1 | Lower left of keypad | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_C3 | Lower right of keypad | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_BTAB | Back tab | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_BEG | Beg (beginning) | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_CANCEL | Cancel | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_CLOSE | Close | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_COMMAND | Cmd (command) | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_COPY | Copy | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_CREATE | Create | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_END | End | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_EXIT | Exit | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_FIND | Find | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_HELP | Help | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_MARK | Mark | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_MESSAGE | Message | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_MOVE | Move | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_NEXT | Next | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_OPEN | Open | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_OPTIONS | Options | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_PREVIOUS | Prev (previous) | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_REDO | Redo | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_REFERENCE | Ref (reference) | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_REFRESH | Refresh | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_REPLACE | Replace | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_RESTART | Restart | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_RESUME | Resume | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_SAVE | Save | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_SBEG | Shifted Beg (beginning) | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_SCANCEL | Shifted Cancel | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_SCOMMAND | Shifted Command | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_SCOPY | Shifted Copy | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_SCREATE | Shifted Create | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_SDC | Shifted Delete char | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_SDL | Shifted Delete line | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_SELECT | Select | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_SEND | Shifted End | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_SEOL | Shifted Clear line | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_SEXIT | Shifted Exit | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_SFIND | Shifted Find | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_SHELP | Shifted Help | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_SHOME | Shifted Home | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_SIC | Shifted Input | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_SLEFT | Shifted Left arrow | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_SMESSAGE | Shifted Message | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_SMOVE | Shifted Move | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_SNEXT | Shifted Next | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_SOPTIONS | Shifted Options | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_SPREVIOUS | Shifted Prev | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_SPRINT | Shifted Print | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_SREDO | Shifted Redo | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_SREPLACE | Shifted Replace | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_SRIGHT | Shifted Right arrow | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_SRSUME | Shifted Resume | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_SSAVE | Shifted Save | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_SSUSPEND | Shifted Suspend | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_SUNDO | Shifted Undo | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_SUSPEND | Suspend | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_UNDO | Undo | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_MOUSE | Mouse event has occurred | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_RESIZE | Terminal resize event | ++-------------------------+--------------------------------------------+ +| .. data:: KEY_MAX | Maximum key value | ++-------------------------+--------------------------------------------+ On VT100s and their software emulations, such as X terminal emulators, there are -normally at least four function keys (:const:`KEY_F1`, :const:`KEY_F2`, -:const:`KEY_F3`, :const:`KEY_F4`) available, and the arrow keys mapped to +normally at least four function keys (:const:`KEY_F1 <KEY_Fn>`, :const:`KEY_F2 <KEY_Fn>`, +:const:`KEY_F3 <KEY_Fn>`, :const:`KEY_F4 <KEY_Fn>`) available, and the arrow keys mapped to :const:`KEY_UP`, :const:`KEY_DOWN`, :const:`KEY_LEFT` and :const:`KEY_RIGHT` in the obvious way. If your machine has a PC keyboard, it is safe to expect arrow keys and twelve function keys (older PC keyboards may have only ten function @@ -1629,6 +1648,8 @@ keys); also, the following keypad mappings are standard: | :kbd:`Page Down` | KEY_NPAGE | +------------------+-----------+ +.. _curses-acs-codes: + The following table lists characters from the alternate character set. These are inherited from the VT100 terminal, and will generally be available on software emulations such as X terminals. When there is no graphic available, curses @@ -1638,117 +1659,143 @@ falls back on a crude printable ASCII approximation. These are available only after :func:`initscr` has been called. -+------------------+------------------------------------------+ -| ACS code | Meaning | -+==================+==========================================+ -| ``ACS_BBSS`` | alternate name for upper right corner | -+------------------+------------------------------------------+ -| ``ACS_BLOCK`` | solid square block | -+------------------+------------------------------------------+ -| ``ACS_BOARD`` | board of squares | -+------------------+------------------------------------------+ -| ``ACS_BSBS`` | alternate name for horizontal line | -+------------------+------------------------------------------+ -| ``ACS_BSSB`` | alternate name for upper left corner | -+------------------+------------------------------------------+ -| ``ACS_BSSS`` | alternate name for top tee | -+------------------+------------------------------------------+ -| ``ACS_BTEE`` | bottom tee | -+------------------+------------------------------------------+ -| ``ACS_BULLET`` | bullet | -+------------------+------------------------------------------+ -| ``ACS_CKBOARD`` | checker board (stipple) | -+------------------+------------------------------------------+ -| ``ACS_DARROW`` | arrow pointing down | -+------------------+------------------------------------------+ -| ``ACS_DEGREE`` | degree symbol | -+------------------+------------------------------------------+ -| ``ACS_DIAMOND`` | diamond | -+------------------+------------------------------------------+ -| ``ACS_GEQUAL`` | greater-than-or-equal-to | -+------------------+------------------------------------------+ -| ``ACS_HLINE`` | horizontal line | -+------------------+------------------------------------------+ -| ``ACS_LANTERN`` | lantern symbol | -+------------------+------------------------------------------+ -| ``ACS_LARROW`` | left arrow | -+------------------+------------------------------------------+ -| ``ACS_LEQUAL`` | less-than-or-equal-to | -+------------------+------------------------------------------+ -| ``ACS_LLCORNER`` | lower left-hand corner | -+------------------+------------------------------------------+ -| ``ACS_LRCORNER`` | lower right-hand corner | -+------------------+------------------------------------------+ -| ``ACS_LTEE`` | left tee | -+------------------+------------------------------------------+ -| ``ACS_NEQUAL`` | not-equal sign | -+------------------+------------------------------------------+ -| ``ACS_PI`` | letter pi | -+------------------+------------------------------------------+ -| ``ACS_PLMINUS`` | plus-or-minus sign | -+------------------+------------------------------------------+ -| ``ACS_PLUS`` | big plus sign | -+------------------+------------------------------------------+ -| ``ACS_RARROW`` | right arrow | -+------------------+------------------------------------------+ -| ``ACS_RTEE`` | right tee | -+------------------+------------------------------------------+ -| ``ACS_S1`` | scan line 1 | -+------------------+------------------------------------------+ -| ``ACS_S3`` | scan line 3 | -+------------------+------------------------------------------+ -| ``ACS_S7`` | scan line 7 | -+------------------+------------------------------------------+ -| ``ACS_S9`` | scan line 9 | -+------------------+------------------------------------------+ -| ``ACS_SBBS`` | alternate name for lower right corner | -+------------------+------------------------------------------+ -| ``ACS_SBSB`` | alternate name for vertical line | -+------------------+------------------------------------------+ -| ``ACS_SBSS`` | alternate name for right tee | -+------------------+------------------------------------------+ -| ``ACS_SSBB`` | alternate name for lower left corner | -+------------------+------------------------------------------+ -| ``ACS_SSBS`` | alternate name for bottom tee | -+------------------+------------------------------------------+ -| ``ACS_SSSB`` | alternate name for left tee | -+------------------+------------------------------------------+ -| ``ACS_SSSS`` | alternate name for crossover or big plus | -+------------------+------------------------------------------+ -| ``ACS_STERLING`` | pound sterling | -+------------------+------------------------------------------+ -| ``ACS_TTEE`` | top tee | -+------------------+------------------------------------------+ -| ``ACS_UARROW`` | up arrow | -+------------------+------------------------------------------+ -| ``ACS_ULCORNER`` | upper left corner | -+------------------+------------------------------------------+ -| ``ACS_URCORNER`` | upper right corner | -+------------------+------------------------------------------+ -| ``ACS_VLINE`` | vertical line | -+------------------+------------------------------------------+ ++------------------------+------------------------------------------+ +| ACS code | Meaning | ++========================+==========================================+ +| .. data:: ACS_BBSS | alternate name for upper right corner | ++------------------------+------------------------------------------+ +| .. data:: ACS_BLOCK | solid square block | ++------------------------+------------------------------------------+ +| .. data:: ACS_BOARD | board of squares | ++------------------------+------------------------------------------+ +| .. data:: ACS_BSBS | alternate name for horizontal line | ++------------------------+------------------------------------------+ +| .. data:: ACS_BSSB | alternate name for upper left corner | ++------------------------+------------------------------------------+ +| .. data:: ACS_BSSS | alternate name for top tee | ++------------------------+------------------------------------------+ +| .. data:: ACS_BTEE | bottom tee | ++------------------------+------------------------------------------+ +| .. data:: ACS_BULLET | bullet | ++------------------------+------------------------------------------+ +| .. data:: ACS_CKBOARD | checker board (stipple) | ++------------------------+------------------------------------------+ +| .. data:: ACS_DARROW | arrow pointing down | ++------------------------+------------------------------------------+ +| .. data:: ACS_DEGREE | degree symbol | ++------------------------+------------------------------------------+ +| .. data:: ACS_DIAMOND | diamond | ++------------------------+------------------------------------------+ +| .. data:: ACS_GEQUAL | greater-than-or-equal-to | ++------------------------+------------------------------------------+ +| .. data:: ACS_HLINE | horizontal line | ++------------------------+------------------------------------------+ +| .. data:: ACS_LANTERN | lantern symbol | ++------------------------+------------------------------------------+ +| .. data:: ACS_LARROW | left arrow | ++------------------------+------------------------------------------+ +| .. data:: ACS_LEQUAL | less-than-or-equal-to | ++------------------------+------------------------------------------+ +| .. data:: ACS_LLCORNER | lower left-hand corner | ++------------------------+------------------------------------------+ +| .. data:: ACS_LRCORNER | lower right-hand corner | ++------------------------+------------------------------------------+ +| .. data:: ACS_LTEE | left tee | ++------------------------+------------------------------------------+ +| .. data:: ACS_NEQUAL | not-equal sign | ++------------------------+------------------------------------------+ +| .. data:: ACS_PI | letter pi | ++------------------------+------------------------------------------+ +| .. data:: ACS_PLMINUS | plus-or-minus sign | ++------------------------+------------------------------------------+ +| .. data:: ACS_PLUS | big plus sign | ++------------------------+------------------------------------------+ +| .. data:: ACS_RARROW | right arrow | ++------------------------+------------------------------------------+ +| .. data:: ACS_RTEE | right tee | ++------------------------+------------------------------------------+ +| .. data:: ACS_S1 | scan line 1 | ++------------------------+------------------------------------------+ +| .. data:: ACS_S3 | scan line 3 | ++------------------------+------------------------------------------+ +| .. data:: ACS_S7 | scan line 7 | ++------------------------+------------------------------------------+ +| .. data:: ACS_S9 | scan line 9 | ++------------------------+------------------------------------------+ +| .. data:: ACS_SBBS | alternate name for lower right corner | ++------------------------+------------------------------------------+ +| .. data:: ACS_SBSB | alternate name for vertical line | ++------------------------+------------------------------------------+ +| .. data:: ACS_SBSS | alternate name for right tee | ++------------------------+------------------------------------------+ +| .. data:: ACS_SSBB | alternate name for lower left corner | ++------------------------+------------------------------------------+ +| .. data:: ACS_SSBS | alternate name for bottom tee | ++------------------------+------------------------------------------+ +| .. data:: ACS_SSSB | alternate name for left tee | ++------------------------+------------------------------------------+ +| .. data:: ACS_SSSS | alternate name for crossover or big plus | ++------------------------+------------------------------------------+ +| .. data:: ACS_STERLING | pound sterling | ++------------------------+------------------------------------------+ +| .. data:: ACS_TTEE | top tee | ++------------------------+------------------------------------------+ +| .. data:: ACS_UARROW | up arrow | ++------------------------+------------------------------------------+ +| .. data:: ACS_ULCORNER | upper left corner | ++------------------------+------------------------------------------+ +| .. data:: ACS_URCORNER | upper right corner | ++------------------------+------------------------------------------+ +| .. data:: ACS_VLINE | vertical line | ++------------------------+------------------------------------------+ + +The following table lists mouse button constants used by :meth:`getmouse`: + ++----------------------------------+---------------------------------------------+ +| Mouse button constant | Meaning | ++==================================+=============================================+ +| .. data:: BUTTONn_PRESSED | Mouse button *n* pressed | ++----------------------------------+---------------------------------------------+ +| .. data:: BUTTONn_RELEASED | Mouse button *n* released | ++----------------------------------+---------------------------------------------+ +| .. data:: BUTTONn_CLICKED | Mouse button *n* clicked | ++----------------------------------+---------------------------------------------+ +| .. data:: BUTTONn_DOUBLE_CLICKED | Mouse button *n* double clicked | ++----------------------------------+---------------------------------------------+ +| .. data:: BUTTONn_TRIPLE_CLICKED | Mouse button *n* triple clicked | ++----------------------------------+---------------------------------------------+ +| .. data:: BUTTON_SHIFT | Shift was down during button state change | ++----------------------------------+---------------------------------------------+ +| .. data:: BUTTON_CTRL | Control was down during button state change | ++----------------------------------+---------------------------------------------+ +| .. data:: BUTTON_ALT | Control was down during button state change | ++----------------------------------+---------------------------------------------+ + + .. versionchanged:: 3.10 + The ``BUTTON5_*`` constants are now exposed if they are provided by the + underlying curses library. The following table lists the predefined colors: -+-------------------+----------------------------+ -| Constant | Color | -+===================+============================+ -| ``COLOR_BLACK`` | Black | -+-------------------+----------------------------+ -| ``COLOR_BLUE`` | Blue | -+-------------------+----------------------------+ -| ``COLOR_CYAN`` | Cyan (light greenish blue) | -+-------------------+----------------------------+ -| ``COLOR_GREEN`` | Green | -+-------------------+----------------------------+ -| ``COLOR_MAGENTA`` | Magenta (purplish red) | -+-------------------+----------------------------+ -| ``COLOR_RED`` | Red | -+-------------------+----------------------------+ -| ``COLOR_WHITE`` | White | -+-------------------+----------------------------+ -| ``COLOR_YELLOW`` | Yellow | -+-------------------+----------------------------+ ++-------------------------+----------------------------+ +| Constant | Color | ++=========================+============================+ +| .. data:: COLOR_BLACK | Black | ++-------------------------+----------------------------+ +| .. data:: COLOR_BLUE | Blue | ++-------------------------+----------------------------+ +| .. data:: COLOR_CYAN | Cyan (light greenish blue) | ++-------------------------+----------------------------+ +| .. data:: COLOR_GREEN | Green | ++-------------------------+----------------------------+ +| .. data:: COLOR_MAGENTA | Magenta (purplish red) | ++-------------------------+----------------------------+ +| .. data:: COLOR_RED | Red | ++-------------------------+----------------------------+ +| .. data:: COLOR_WHITE | White | ++-------------------------+----------------------------+ +| .. data:: COLOR_YELLOW | Yellow | ++-------------------------+----------------------------+ :mod:`curses.textpad` --- Text input widget for curses programs @@ -1854,19 +1901,19 @@ You can instantiate a :class:`Textbox` object as follows: Move operations do nothing if the cursor is at an edge where the movement is not possible. The following synonyms are supported where possible: - +------------------------+------------------+ - | Constant | Keystroke | - +========================+==================+ - | :const:`KEY_LEFT` | :kbd:`Control-B` | - +------------------------+------------------+ - | :const:`KEY_RIGHT` | :kbd:`Control-F` | - +------------------------+------------------+ - | :const:`KEY_UP` | :kbd:`Control-P` | - +------------------------+------------------+ - | :const:`KEY_DOWN` | :kbd:`Control-N` | - +------------------------+------------------+ - | :const:`KEY_BACKSPACE` | :kbd:`Control-h` | - +------------------------+------------------+ + +--------------------------------+------------------+ + | Constant | Keystroke | + +================================+==================+ + | :const:`~curses.KEY_LEFT` | :kbd:`Control-B` | + +--------------------------------+------------------+ + | :const:`~curses.KEY_RIGHT` | :kbd:`Control-F` | + +--------------------------------+------------------+ + | :const:`~curses.KEY_UP` | :kbd:`Control-P` | + +--------------------------------+------------------+ + | :const:`~curses.KEY_DOWN` | :kbd:`Control-N` | + +--------------------------------+------------------+ + | :const:`~curses.KEY_BACKSPACE` | :kbd:`Control-h` | + +--------------------------------+------------------+ All other keystrokes are treated as a command to insert the given character and move right (with line wrapping). diff --git a/Doc/library/dataclasses.rst b/Doc/library/dataclasses.rst index 82faa7b7..d6874876 100644 --- a/Doc/library/dataclasses.rst +++ b/Doc/library/dataclasses.rst @@ -12,8 +12,8 @@ -------------- This module provides a decorator and functions for automatically -adding generated :term:`special method`\s such as :meth:`__init__` and -:meth:`__repr__` to user-defined classes. It was originally described +adding generated :term:`special method`\s such as :meth:`~object.__init__` and +:meth:`~object.__repr__` to user-defined classes. It was originally described in :pep:`557`. The member variables to use in these generated methods are defined @@ -31,7 +31,7 @@ using :pep:`526` type annotations. For example, this code:: def total_cost(self) -> float: return self.unit_price * self.quantity_on_hand -will add, among other things, a :meth:`__init__` that looks like:: +will add, among other things, a :meth:`~object.__init__` that looks like:: def __init__(self, name: str, unit_price: float, quantity_on_hand: int = 0): self.name = name @@ -86,86 +86,86 @@ Module contents The parameters to :func:`dataclass` are: - - ``init``: If true (the default), a :meth:`__init__` method will be + - ``init``: If true (the default), a :meth:`~object.__init__` method will be generated. - If the class already defines :meth:`__init__`, this parameter is + If the class already defines :meth:`~object.__init__`, this parameter is ignored. - - ``repr``: If true (the default), a :meth:`__repr__` method will be + - ``repr``: If true (the default), a :meth:`~object.__repr__` method will be generated. The generated repr string will have the class name and the name and repr of each field, in the order they are defined in the class. Fields that are marked as being excluded from the repr are not included. For example: ``InventoryItem(name='widget', unit_price=3.0, quantity_on_hand=10)``. - If the class already defines :meth:`__repr__`, this parameter is + If the class already defines :meth:`~object.__repr__`, this parameter is ignored. - - ``eq``: If true (the default), an :meth:`__eq__` method will be + - ``eq``: If true (the default), an :meth:`~object.__eq__` method will be generated. This method compares the class as if it were a tuple of its fields, in order. Both instances in the comparison must be of the identical type. - If the class already defines :meth:`__eq__`, this parameter is + If the class already defines :meth:`~object.__eq__`, this parameter is ignored. - - ``order``: If true (the default is ``False``), :meth:`__lt__`, - :meth:`__le__`, :meth:`__gt__`, and :meth:`__ge__` methods will be + - ``order``: If true (the default is ``False``), :meth:`~object.__lt__`, + :meth:`~object.__le__`, :meth:`~object.__gt__`, and :meth:`~object.__ge__` methods will be generated. These compare the class as if it were a tuple of its fields, in order. Both instances in the comparison must be of the identical type. If ``order`` is true and ``eq`` is false, a :exc:`ValueError` is raised. - If the class already defines any of :meth:`__lt__`, - :meth:`__le__`, :meth:`__gt__`, or :meth:`__ge__`, then + If the class already defines any of :meth:`~object.__lt__`, + :meth:`~object.__le__`, :meth:`~object.__gt__`, or :meth:`~object.__ge__`, then :exc:`TypeError` is raised. - - ``unsafe_hash``: If ``False`` (the default), a :meth:`__hash__` method + - ``unsafe_hash``: If ``False`` (the default), a :meth:`~object.__hash__` method is generated according to how ``eq`` and ``frozen`` are set. - :meth:`__hash__` is used by built-in :meth:`hash()`, and when objects are + :meth:`~object.__hash__` is used by built-in :meth:`hash()`, and when objects are added to hashed collections such as dictionaries and sets. Having a - :meth:`__hash__` implies that instances of the class are immutable. + :meth:`~object.__hash__` implies that instances of the class are immutable. Mutability is a complicated property that depends on the programmer's - intent, the existence and behavior of :meth:`__eq__`, and the values of + intent, the existence and behavior of :meth:`~object.__eq__`, and the values of the ``eq`` and ``frozen`` flags in the :func:`dataclass` decorator. - By default, :func:`dataclass` will not implicitly add a :meth:`__hash__` + By default, :func:`dataclass` will not implicitly add a :meth:`~object.__hash__` method unless it is safe to do so. Neither will it add or change an - existing explicitly defined :meth:`__hash__` method. Setting the class + existing explicitly defined :meth:`~object.__hash__` method. Setting the class attribute ``__hash__ = None`` has a specific meaning to Python, as - described in the :meth:`__hash__` documentation. + described in the :meth:`~object.__hash__` documentation. - If :meth:`__hash__` is not explicitly defined, or if it is set to ``None``, - then :func:`dataclass` *may* add an implicit :meth:`__hash__` method. + If :meth:`~object.__hash__` is not explicitly defined, or if it is set to ``None``, + then :func:`dataclass` *may* add an implicit :meth:`~object.__hash__` method. Although not recommended, you can force :func:`dataclass` to create a - :meth:`__hash__` method with ``unsafe_hash=True``. This might be the case + :meth:`~object.__hash__` method with ``unsafe_hash=True``. This might be the case if your class is logically immutable but can nonetheless be mutated. This is a specialized use case and should be considered carefully. - Here are the rules governing implicit creation of a :meth:`__hash__` - method. Note that you cannot both have an explicit :meth:`__hash__` + Here are the rules governing implicit creation of a :meth:`~object.__hash__` + method. Note that you cannot both have an explicit :meth:`~object.__hash__` method in your dataclass and set ``unsafe_hash=True``; this will result in a :exc:`TypeError`. If ``eq`` and ``frozen`` are both true, by default :func:`dataclass` will - generate a :meth:`__hash__` method for you. If ``eq`` is true and - ``frozen`` is false, :meth:`__hash__` will be set to ``None``, marking it + generate a :meth:`~object.__hash__` method for you. If ``eq`` is true and + ``frozen`` is false, :meth:`~object.__hash__` will be set to ``None``, marking it unhashable (which it is, since it is mutable). If ``eq`` is false, - :meth:`__hash__` will be left untouched meaning the :meth:`__hash__` + :meth:`~object.__hash__` will be left untouched meaning the :meth:`~object.__hash__` method of the superclass will be used (if the superclass is :class:`object`, this means it will fall back to id-based hashing). - ``frozen``: If true (the default is ``False``), assigning to fields will generate an exception. This emulates read-only frozen instances. If - :meth:`__setattr__` or :meth:`__delattr__` is defined in the class, then + :meth:`~object.__setattr__` or :meth:`~object.__delattr__` is defined in the class, then :exc:`TypeError` is raised. See the discussion below. - ``match_args``: If true (the default is ``True``), the ``__match_args__`` tuple will be created from the list of - parameters to the generated :meth:`__init__` method (even if - :meth:`__init__` is not generated, see above). If false, or if + parameters to the generated :meth:`~object.__init__` method (even if + :meth:`~object.__init__` is not generated, see above). If false, or if ``__match_args__`` is already defined in the class, then ``__match_args__`` will not be generated. @@ -173,18 +173,18 @@ Module contents - ``kw_only``: If true (the default value is ``False``), then all fields will be marked as keyword-only. If a field is marked as - keyword-only, then the only effect is that the :meth:`__init__` + keyword-only, then the only effect is that the :meth:`~object.__init__` parameter generated from a keyword-only field must be specified - with a keyword when :meth:`__init__` is called. There is no + with a keyword when :meth:`~object.__init__` is called. There is no effect on any other aspect of dataclasses. See the :term:`parameter` glossary entry for details. Also see the :const:`KW_ONLY` section. .. versionadded:: 3.10 - - ``slots``: If true (the default is ``False``), :attr:`__slots__` attribute + - ``slots``: If true (the default is ``False``), :attr:`~object.__slots__` attribute will be generated and new class will be returned instead of the original one. - If :attr:`__slots__` is already defined in the class, then :exc:`TypeError` + If :attr:`~object.__slots__` is already defined in the class, then :exc:`TypeError` is raised. .. versionadded:: 3.10 @@ -215,7 +215,7 @@ Module contents b: int = 0 # assign a default value for 'b' In this example, both ``a`` and ``b`` will be included in the added - :meth:`__init__` method, which will be defined as:: + :meth:`~object.__init__` method, which will be defined as:: def __init__(self, a: int, b: int = 0): @@ -256,13 +256,13 @@ Module contents error to specify both ``default`` and ``default_factory``. - ``init``: If true (the default), this field is included as a - parameter to the generated :meth:`__init__` method. + parameter to the generated :meth:`~object.__init__` method. - ``repr``: If true (the default), this field is included in the - string returned by the generated :meth:`__repr__` method. + string returned by the generated :meth:`~object.__repr__` method. - ``hash``: This can be a bool or ``None``. If true, this field is - included in the generated :meth:`__hash__` method. If ``None`` (the + included in the generated :meth:`~object.__hash__` method. If ``None`` (the default), use the value of ``compare``: this would normally be the expected behavior. A field should be considered in the hash if it's used for comparisons. Setting this value to anything @@ -275,8 +275,8 @@ Module contents is excluded from the hash, it will still be used for comparisons. - ``compare``: If true (the default), this field is included in the - generated equality and comparison methods (:meth:`__eq__`, - :meth:`__gt__`, et al.). + generated equality and comparison methods (:meth:`~object.__eq__`, + :meth:`~object.__gt__`, et al.). - ``metadata``: This can be a mapping or None. None is treated as an empty dict. This value is wrapped in @@ -287,7 +287,7 @@ Module contents namespace in the metadata. - ``kw_only``: If true, this field will be marked as keyword-only. - This is used when the generated :meth:`__init__` method's + This is used when the generated :meth:`~object.__init__` method's parameters are computed. .. versionadded:: 3.10 @@ -389,7 +389,7 @@ Module contents :func:`astuple` raises :exc:`TypeError` if ``obj`` is not a dataclass instance. -.. function:: make_dataclass(cls_name, fields, *, bases=(), namespace=None, init=True, repr=True, eq=True, order=False, unsafe_hash=False, frozen=False, match_args=True, kw_only=False, slots=False, weakref_slot=False) +.. function:: make_dataclass(cls_name, fields, *, bases=(), namespace=None, init=True, repr=True, eq=True, order=False, unsafe_hash=False, frozen=False, match_args=True, kw_only=False, slots=False, weakref_slot=False, module=None) Creates a new dataclass with name ``cls_name``, fields as defined in ``fields``, base classes as given in ``bases``, and initialized @@ -401,6 +401,10 @@ Module contents ``match_args``, ``kw_only``, ``slots``, and ``weakref_slot`` have the same meaning as they do in :func:`dataclass`. + If ``module`` is defined, the ``__module__`` attribute + of the dataclass is set to that value. + By default, it is set to the module name of the caller. + This function is not strictly required, because any Python mechanism for creating a new class with ``__annotations__`` can then apply the :func:`dataclass` function to convert that class to @@ -431,13 +435,13 @@ Module contents Class, raises :exc:`TypeError`. If values in ``changes`` do not specify fields, raises :exc:`TypeError`. - The newly returned object is created by calling the :meth:`__init__` + The newly returned object is created by calling the :meth:`~object.__init__` method of the dataclass. This ensures that :meth:`__post_init__`, if present, is also called. Init-only variables without default values, if any exist, must be specified on the call to :func:`replace` so that they can be passed to - :meth:`__init__` and :meth:`__post_init__`. + :meth:`~object.__init__` and :meth:`__post_init__`. It is an error for ``changes`` to contain any fields that are defined as having ``init=False``. A :exc:`ValueError` will be raised @@ -476,7 +480,7 @@ Module contents :const:`KW_ONLY` is otherwise completely ignored. This includes the name of such a field. By convention, a name of ``_`` is used for a :const:`KW_ONLY` field. Keyword-only fields signify - :meth:`__init__` parameters that must be specified as keywords when + :meth:`~object.__init__` parameters that must be specified as keywords when the class is instantiated. In this example, the fields ``y`` and ``z`` will be marked as keyword-only fields:: @@ -497,35 +501,38 @@ Module contents .. exception:: FrozenInstanceError - Raised when an implicitly defined :meth:`__setattr__` or - :meth:`__delattr__` is called on a dataclass which was defined with + Raised when an implicitly defined :meth:`~object.__setattr__` or + :meth:`~object.__delattr__` is called on a dataclass which was defined with ``frozen=True``. It is a subclass of :exc:`AttributeError`. +.. _post-init-processing: + Post-init processing -------------------- -The generated :meth:`__init__` code will call a method named -:meth:`__post_init__`, if :meth:`__post_init__` is defined on the -class. It will normally be called as ``self.__post_init__()``. -However, if any ``InitVar`` fields are defined, they will also be -passed to :meth:`__post_init__` in the order they were defined in the -class. If no :meth:`__init__` method is generated, then -:meth:`__post_init__` will not automatically be called. +.. function:: __post_init__() -Among other uses, this allows for initializing field values that -depend on one or more other fields. For example:: + When defined on the class, it will be called by the generated + :meth:`~object.__init__`, normally as ``self.__post_init__()``. + However, if any ``InitVar`` fields are defined, they will also be + passed to :meth:`__post_init__` in the order they were defined in the + class. If no :meth:`~object.__init__` method is generated, then + :meth:`__post_init__` will not automatically be called. - @dataclass - class C: - a: float - b: float - c: float = field(init=False) + Among other uses, this allows for initializing field values that + depend on one or more other fields. For example:: - def __post_init__(self): - self.c = self.a + self.b + @dataclass + class C: + a: float + b: float + c: float = field(init=False) + + def __post_init__(self): + self.c = self.a + self.b -The :meth:`__init__` method generated by :func:`dataclass` does not call base -class :meth:`__init__` methods. If the base class has an :meth:`__init__` method +The :meth:`~object.__init__` method generated by :func:`dataclass` does not call base +class :meth:`~object.__init__` methods. If the base class has an :meth:`~object.__init__` method that has to be called, it is common to call this method in a :meth:`__post_init__` method:: @@ -541,7 +548,7 @@ that has to be called, it is common to call this method in a def __post_init__(self): super().__init__(self.side, self.side) -Note, however, that in general the dataclass-generated :meth:`__init__` methods +Note, however, that in general the dataclass-generated :meth:`~object.__init__` methods don't need to be called, since the derived dataclass will take care of initializing all fields of any base class that is a dataclass itself. @@ -569,7 +576,7 @@ if the type of a field is of type ``dataclasses.InitVar``. If a field is an ``InitVar``, it is considered a pseudo-field called an init-only field. As it is not a true field, it is not returned by the module-level :func:`fields` function. Init-only fields are added as -parameters to the generated :meth:`__init__` method, and are passed to +parameters to the generated :meth:`~object.__init__` method, and are passed to the optional :meth:`__post_init__` method. They are not otherwise used by dataclasses. @@ -597,12 +604,12 @@ Frozen instances It is not possible to create truly immutable Python objects. However, by passing ``frozen=True`` to the :meth:`dataclass` decorator you can emulate immutability. In that case, dataclasses will add -:meth:`__setattr__` and :meth:`__delattr__` methods to the class. These +:meth:`~object.__setattr__` and :meth:`~object.__delattr__` methods to the class. These methods will raise a :exc:`FrozenInstanceError` when invoked. There is a tiny performance penalty when using ``frozen=True``: -:meth:`__init__` cannot use simple assignment to initialize fields, and -must use :meth:`object.__setattr__`. +:meth:`~object.__init__` cannot use simple assignment to initialize fields, and +must use :meth:`!object.__setattr__`. Inheritance ----------- @@ -630,14 +637,14 @@ example:: The final list of fields is, in order, ``x``, ``y``, ``z``. The final type of ``x`` is ``int``, as specified in class ``C``. -The generated :meth:`__init__` method for ``C`` will look like:: +The generated :meth:`~object.__init__` method for ``C`` will look like:: def __init__(self, x: int = 15, y: int = 0, z: int = 10): -Re-ordering of keyword-only parameters in :meth:`__init__` ----------------------------------------------------------- +Re-ordering of keyword-only parameters in :meth:`~object.__init__` +------------------------------------------------------------------ -After the parameters needed for :meth:`__init__` are computed, any +After the parameters needed for :meth:`~object.__init__` are computed, any keyword-only parameters are moved to come after all regular (non-keyword-only) parameters. This is a requirement of how keyword-only parameters are implemented in Python: they must come @@ -658,7 +665,7 @@ fields, and ``Base.x`` and ``D.z`` are regular fields:: z: int = 10 t: int = field(kw_only=True, default=0) -The generated :meth:`__init__` method for ``D`` will look like:: +The generated :meth:`~object.__init__` method for ``D`` will look like:: def __init__(self, x: Any = 15.0, z: int = 10, *, y: int = 0, w: int = 1, t: int = 0): @@ -667,7 +674,7 @@ the list of fields: parameters derived from regular fields are followed by parameters derived from keyword-only fields. The relative ordering of keyword-only parameters is maintained in the -re-ordered :meth:`__init__` parameter list. +re-ordered :meth:`~object.__init__` parameter list. Default factory functions @@ -679,10 +686,10 @@ example, to create a new instance of a list, use:: mylist: list = field(default_factory=list) -If a field is excluded from :meth:`__init__` (using ``init=False``) +If a field is excluded from :meth:`~object.__init__` (using ``init=False``) and the field also specifies ``default_factory``, then the default factory function will always be called from the generated -:meth:`__init__` function. This happens because there is no other +:meth:`~object.__init__` function. This happens because there is no other way to give the field an initial value. Mutable default values @@ -710,7 +717,7 @@ Using dataclasses, *if* this code was valid:: @dataclass class D: - x: List = [] + x: list = [] # This code raises ValueError def add(self, element): self.x += element @@ -731,7 +738,7 @@ for ``x`` when creating a class instance will share the same copy of ``x``. Because dataclasses just use normal Python class creation they also share this behavior. There is no general way for Data Classes to detect this condition. Instead, the -:func:`dataclass` decorator will raise a :exc:`TypeError` if it +:func:`dataclass` decorator will raise a :exc:`ValueError` if it detects an unhashable default parameter. The assumption is that if a value is unhashable, it is mutable. This is a partial solution, but it does protect against many common errors. diff --git a/Doc/library/datetime.rst b/Doc/library/datetime.rst index c7b96671..04cc7556 100644 --- a/Doc/library/datetime.rst +++ b/Doc/library/datetime.rst @@ -19,6 +19,10 @@ The :mod:`datetime` module supplies classes for manipulating dates and times. While date and time arithmetic is supported, the focus of the implementation is on efficient attribute extraction for output formatting and manipulation. +.. tip:: + + Skip to :ref:`the format codes <format-codes>`. + .. seealso:: Module :mod:`calendar` @@ -33,6 +37,10 @@ on efficient attribute extraction for output formatting and manipulation. Package `dateutil <https://dateutil.readthedocs.io/en/stable/>`_ Third-party library with expanded time zone and parsing support. + Package `DateType <https://pypi.org/project/datetype/>`_ + Third-party library that introduces distinct static types to e.g. allow static type checkers + to differentiate between naive and aware datetimes. + .. _datetime-naive-aware: Aware and Naive Objects @@ -160,7 +168,7 @@ The :class:`date`, :class:`.datetime`, :class:`.time`, and :class:`timezone` typ share these common features: - Objects of these types are immutable. -- Objects of these types are hashable, meaning that they can be used as +- Objects of these types are :term:`hashable`, meaning that they can be used as dictionary keys. - Objects of these types support efficient pickling via the :mod:`pickle` module. @@ -737,18 +745,16 @@ Instance methods: .. method:: date.strftime(format) Return a string representing the date, controlled by an explicit format string. - Format codes referring to hours, minutes or seconds will see 0 values. For a - complete list of formatting directives, see - :ref:`strftime-strptime-behavior`. + Format codes referring to hours, minutes or seconds will see 0 values. + See also :ref:`strftime-strptime-behavior` and :meth:`date.isoformat`. .. method:: date.__format__(format) Same as :meth:`.date.strftime`. This makes it possible to specify a format string for a :class:`.date` object in :ref:`formatted string - literals <f-strings>` and when using :meth:`str.format`. For a - complete list of formatting directives, see - :ref:`strftime-strptime-behavior`. + literals <f-strings>` and when using :meth:`str.format`. + See also :ref:`strftime-strptime-behavior` and :meth:`date.isoformat`. Examples of Usage: :class:`date` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -765,6 +771,7 @@ Example of counting days to an event:: >>> my_birthday = date(today.year, 6, 24) >>> if my_birthday < today: ... my_birthday = my_birthday.replace(year=today.year + 1) + ... >>> my_birthday datetime.date(2008, 6, 24) >>> time_to_birthday = abs(my_birthday - today) @@ -897,6 +904,10 @@ Other constructors, all class methods: in UTC. As such, the recommended way to create an object representing the current time in UTC is by calling ``datetime.now(timezone.utc)``. + .. deprecated:: 3.12 + + Use :meth:`datetime.now` with :attr:`UTC` instead. + .. classmethod:: datetime.fromtimestamp(timestamp, tz=None) @@ -965,6 +976,10 @@ Other constructors, all class methods: :c:func:`gmtime` function. Raise :exc:`OSError` instead of :exc:`ValueError` on :c:func:`gmtime` failure. + .. deprecated:: 3.12 + + Use :meth:`datetime.fromtimestamp` with :attr:`UTC` instead. + .. classmethod:: datetime.fromordinal(ordinal) @@ -974,19 +989,18 @@ Other constructors, all class methods: microsecond of the result are all 0, and :attr:`.tzinfo` is ``None``. -.. classmethod:: datetime.combine(date, time, tzinfo=self.tzinfo) +.. classmethod:: datetime.combine(date, time, tzinfo=time.tzinfo) Return a new :class:`.datetime` object whose date components are equal to the given :class:`date` object's, and whose time components are equal to the given :class:`.time` object's. If the *tzinfo* argument is provided, its value is used to set the :attr:`.tzinfo` attribute of the result, otherwise the :attr:`~.time.tzinfo` attribute of the *time* argument - is used. + is used. If the *date* argument is a :class:`.datetime` object, its time components + and :attr:`.tzinfo` attributes are ignored. For any :class:`.datetime` object *d*, - ``d == datetime.combine(d.date(), d.time(), d.tzinfo)``. If date is a - :class:`.datetime` object, its time components and :attr:`.tzinfo` attributes - are ignored. + ``d == datetime.combine(d.date(), d.time(), d.tzinfo)``. .. versionchanged:: 3.6 Added the *tzinfo* argument. @@ -1045,14 +1059,14 @@ Other constructors, all class methods: Return a :class:`.datetime` corresponding to *date_string*, parsed according to *format*. - This is equivalent to:: + If *format* does not contain microseconds or timezone information, this is equivalent to:: datetime(*(time.strptime(date_string, format)[0:6])) :exc:`ValueError` is raised if the date_string and format can't be parsed by :func:`time.strptime` or if it returns a value which isn't a - time tuple. For a complete list of formatting directives, see - :ref:`strftime-strptime-behavior`. + time tuple. See also :ref:`strftime-strptime-behavior` and + :meth:`datetime.fromisoformat`. @@ -1370,8 +1384,8 @@ Instance methods: time and this method relies on the platform C :c:func:`mktime` function to perform the conversion. Since :class:`.datetime` supports wider range of values than :c:func:`mktime` on many - platforms, this method may raise :exc:`OverflowError` for times far - in the past or far in the future. + platforms, this method may raise :exc:`OverflowError` or :exc:`OSError` + for times far in the past or far in the future. For aware :class:`.datetime` instances, the return value is computed as:: @@ -1510,20 +1524,21 @@ Instance methods: (which :func:`time.ctime` invokes, but which :meth:`datetime.ctime` does not invoke) conforms to the C standard. + .. method:: datetime.strftime(format) - Return a string representing the date and time, controlled by an explicit format - string. For a complete list of formatting directives, see - :ref:`strftime-strptime-behavior`. + Return a string representing the date and time, + controlled by an explicit format string. + See also :ref:`strftime-strptime-behavior` and :meth:`datetime.isoformat`. .. method:: datetime.__format__(format) Same as :meth:`.datetime.strftime`. This makes it possible to specify a format string for a :class:`.datetime` object in :ref:`formatted string - literals <f-strings>` and when using :meth:`str.format`. For a - complete list of formatting directives, see - :ref:`strftime-strptime-behavior`. + literals <f-strings>` and when using :meth:`str.format`. + See also :ref:`strftime-strptime-behavior` and :meth:`datetime.isoformat`. + Examples of Usage: :class:`.datetime` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -1868,17 +1883,15 @@ Instance methods: .. method:: time.strftime(format) Return a string representing the time, controlled by an explicit format - string. For a complete list of formatting directives, see - :ref:`strftime-strptime-behavior`. + string. See also :ref:`strftime-strptime-behavior` and :meth:`time.isoformat`. .. method:: time.__format__(format) - Same as :meth:`.time.strftime`. This makes it possible to specify a format string - for a :class:`.time` object in :ref:`formatted string - literals <f-strings>` and when using :meth:`str.format`. For a - complete list of formatting directives, see - :ref:`strftime-strptime-behavior`. + Same as :meth:`.time.strftime`. This makes it possible to specify + a format string for a :class:`.time` object in :ref:`formatted string + literals <f-strings>` and when using :meth:`str.format`. + See also :ref:`strftime-strptime-behavior` and :meth:`time.isoformat`. .. method:: time.utcoffset() @@ -2317,9 +2330,19 @@ versus :meth:`strptime`: +----------------+--------------------------------------------------------+------------------------------------------------------------------------------+ + .. _format-codes: + :meth:`strftime` and :meth:`strptime` Format Codes ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +These methods accept format codes that can be used to parse and format dates:: + + >>> datetime.strptime('31/01/22 23:59:59.999999', + ... '%d/%m/%y %H:%M:%S.%f') + datetime.datetime(2022, 1, 31, 23, 59, 59, 999999) + >>> _.strftime('%a %d %b %Y, %I:%M%p') + 'Mon 31 Jan 2022, 11:59PM' + The following is a list of all the format codes that the 1989 C standard requires, and these work on all platforms with a standard C implementation. @@ -2443,6 +2466,11 @@ convenience. These parameters all correspond to ISO 8601 date values. | | Week 01 is the week containing | | | | | Jan 4. | | | +-----------+--------------------------------+------------------------+-------+ +| ``%:z`` | UTC offset in the form | (empty), +00:00, | \(6) | +| | ``±HH:MM[:SS[.ffffff]]`` | -04:00, +10:30, | | +| | (empty string if the object is | +06:34:15, | | +| | naive). | -03:07:12.345216 | | ++-----------+--------------------------------+------------------------+-------+ These may not be available on all platforms when used with the :meth:`strftime` method. The ISO 8601 year and ISO 8601 week directives are not interchangeable @@ -2458,6 +2486,9 @@ differences between platforms in handling of unsupported format specifiers. .. versionadded:: 3.6 ``%G``, ``%u`` and ``%V`` were added. +.. versionadded:: 3.12 + ``%:z`` was added. + Technical Detail ^^^^^^^^^^^^^^^^ @@ -2497,10 +2528,7 @@ Notes: Because the format depends on the current locale, care should be taken when making assumptions about the output value. Field orderings will vary (for example, "month/day/year" versus "day/month/year"), and the output may - contain Unicode characters encoded using the locale's default encoding (for - example, if the current locale is ``ja_JP``, the default encoding could be - any one of ``eucJP``, ``SJIS``, or ``utf-8``; use :meth:`locale.getlocale` - to determine the current locale's encoding). + contain non-ASCII characters. (2) The :meth:`strptime` method can parse years in the full [1, 9999] range, but @@ -2530,8 +2558,8 @@ Notes: available). (6) - For a naive object, the ``%z`` and ``%Z`` format codes are replaced by empty - strings. + For a naive object, the ``%z``, ``%:z`` and ``%Z`` format codes are replaced + by empty strings. For an aware object: @@ -2557,6 +2585,10 @@ Notes: For example, ``'+01:00:00'`` will be parsed as an offset of one hour. In addition, providing ``'Z'`` is identical to ``'+00:00'``. + ``%:z`` + Behaves exactly as ``%z``, but has a colon separator added between + hours, minutes and seconds. + ``%Z`` In :meth:`strftime`, ``%Z`` is replaced by an empty string if :meth:`tzname` returns ``None``; otherwise ``%Z`` is replaced by the diff --git a/Doc/library/decimal.rst b/Doc/library/decimal.rst index 26010813..018ec1ab 100644 --- a/Doc/library/decimal.rst +++ b/Doc/library/decimal.rst @@ -40,23 +40,23 @@ decimal floating point arithmetic. It offers several advantages over the people learn at school." -- excerpt from the decimal arithmetic specification. * Decimal numbers can be represented exactly. In contrast, numbers like - :const:`1.1` and :const:`2.2` do not have exact representations in binary + ``1.1`` and ``2.2`` do not have exact representations in binary floating point. End users typically would not expect ``1.1 + 2.2`` to display - as :const:`3.3000000000000003` as it does with binary floating point. + as ``3.3000000000000003`` as it does with binary floating point. * The exactness carries over into arithmetic. In decimal floating point, ``0.1 + 0.1 + 0.1 - 0.3`` is exactly equal to zero. In binary floating point, the result - is :const:`5.5511151231257827e-017`. While near to zero, the differences + is ``5.5511151231257827e-017``. While near to zero, the differences prevent reliable equality testing and differences can accumulate. For this reason, decimal is preferred in accounting applications which have strict equality invariants. * The decimal module incorporates a notion of significant places so that ``1.30 - + 1.20`` is :const:`2.50`. The trailing zero is kept to indicate significance. + + 1.20`` is ``2.50``. The trailing zero is kept to indicate significance. This is the customary presentation for monetary applications. For multiplication, the "schoolbook" approach uses all the figures in the - multiplicands. For instance, ``1.3 * 1.2`` gives :const:`1.56` while ``1.30 * - 1.20`` gives :const:`1.5600`. + multiplicands. For instance, ``1.3 * 1.2`` gives ``1.56`` while ``1.30 * + 1.20`` gives ``1.5600``. * Unlike hardware based binary floating point, the decimal module has a user alterable precision (defaulting to 28 places) which can be as large as needed for @@ -88,8 +88,8 @@ context for arithmetic, and signals. A decimal number is immutable. It has a sign, coefficient digits, and an exponent. To preserve significance, the coefficient digits do not truncate trailing zeros. Decimals also include special values such as -:const:`Infinity`, :const:`-Infinity`, and :const:`NaN`. The standard also -differentiates :const:`-0` from :const:`+0`. +``Infinity``, ``-Infinity``, and ``NaN``. The standard also +differentiates ``-0`` from ``+0``. The context for arithmetic is an environment specifying precision, rounding rules, limits on exponents, flags indicating the results of operations, and trap @@ -139,8 +139,8 @@ precision, rounding, or enabled traps:: Decimal instances can be constructed from integers, strings, floats, or tuples. Construction from an integer or a float performs an exact conversion of the value of that integer or float. Decimal numbers include special values such as -:const:`NaN` which stands for "Not a number", positive and negative -:const:`Infinity`, and :const:`-0`:: +``NaN`` which stands for "Not a number", positive and negative +``Infinity``, and ``-0``:: >>> getcontext().prec = 28 >>> Decimal(10) @@ -250,7 +250,7 @@ And some mathematical functions are also available to Decimal: >>> Decimal('10').log10() Decimal('1') -The :meth:`quantize` method rounds a number to a fixed exponent. This method is +The :meth:`~Decimal.quantize` method rounds a number to a fixed exponent. This method is useful for monetary applications that often round results to a fixed number of places: @@ -299,7 +299,7 @@ enabled: Contexts also have signal flags for monitoring exceptional conditions encountered during computations. The flags remain set until explicitly cleared, so it is best to clear the flags before each set of monitored computations by -using the :meth:`clear_flags` method. :: +using the :meth:`~Context.clear_flags` method. :: >>> setcontext(ExtendedContext) >>> getcontext().clear_flags() @@ -309,12 +309,12 @@ using the :meth:`clear_flags` method. :: Context(prec=9, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999, capitals=1, clamp=0, flags=[Inexact, Rounded], traps=[]) -The *flags* entry shows that the rational approximation to :const:`Pi` was +The *flags* entry shows that the rational approximation to pi was rounded (digits beyond the context precision were thrown away) and that the result is inexact (some of the discarded digits were non-zero). -Individual traps are set using the dictionary in the :attr:`traps` field of a -context: +Individual traps are set using the dictionary in the :attr:`~Context.traps` +attribute of a context: .. doctest:: newcontext @@ -369,7 +369,7 @@ Decimal objects with the fullwidth digits ``'\uff10'`` through ``'\uff19'``. If *value* is a :class:`tuple`, it should have three components, a sign - (:const:`0` for positive or :const:`1` for negative), a :class:`tuple` of + (``0`` for positive or ``1`` for negative), a :class:`tuple` of digits, and an integer exponent. For example, ``Decimal((0, (1, 4, 1, 4), -3))`` returns ``Decimal('1.414')``. @@ -387,7 +387,7 @@ Decimal objects The purpose of the *context* argument is determining what to do if *value* is a malformed string. If the context traps :const:`InvalidOperation`, an exception is raised; otherwise, the constructor returns a new Decimal with the value of - :const:`NaN`. + ``NaN``. Once constructed, :class:`Decimal` objects are immutable. @@ -701,7 +701,7 @@ Decimal objects .. method:: max(other, context=None) Like ``max(self, other)`` except that the context rounding rule is applied - before returning and that :const:`NaN` values are either signaled or + before returning and that ``NaN`` values are either signaled or ignored (depending on the context and whether they are signaling or quiet). @@ -713,7 +713,7 @@ Decimal objects .. method:: min(other, context=None) Like ``min(self, other)`` except that the context rounding rule is applied - before returning and that :const:`NaN` values are either signaled or + before returning and that ``NaN`` values are either signaled or ignored (depending on the context and whether they are signaling or quiet). @@ -743,12 +743,23 @@ Decimal objects .. method:: normalize(context=None) - Normalize the number by stripping the rightmost trailing zeros and - converting any result equal to :const:`Decimal('0')` to - :const:`Decimal('0e0')`. Used for producing canonical values for attributes - of an equivalence class. For example, ``Decimal('32.100')`` and - ``Decimal('0.321000e+2')`` both normalize to the equivalent value - ``Decimal('32.1')``. + Used for producing canonical values of an equivalence + class within either the current context or the specified context. + + This has the same semantics as the unary plus operation, except that if + the final result is finite it is reduced to its simplest form, with all + trailing zeros removed and its sign preserved. That is, while the + coefficient is non-zero and a multiple of ten the coefficient is divided + by ten and the exponent is incremented by 1. Otherwise (the coefficient is + zero) the exponent is set to 0. In all cases the sign is unchanged. + + For example, ``Decimal('32.100')`` and ``Decimal('0.321000e+2')`` both + normalize to the equivalent value ``Decimal('32.1')``. + + Note that rounding is applied *before* reducing to simplest form. + + In the latest versions of the specification, this operation is also known + as ``reduce``. .. method:: number_class(context=None) @@ -790,7 +801,7 @@ Decimal objects the current thread's context is used. An error is returned whenever the resulting exponent is greater than - :attr:`Emax` or less than :attr:`Etiny`. + :attr:`~Context.Emax` or less than :meth:`~Context.Etiny`. .. method:: radix() @@ -830,7 +841,7 @@ Decimal objects .. method:: same_quantum(other, context=None) Test whether self and other have the same exponent or whether both are - :const:`NaN`. + ``NaN``. This operation is unaffected by context and is quiet: no flags are changed and no rounding is performed. As an exception, the C version may raise @@ -892,11 +903,11 @@ Decimal objects Logical operands ^^^^^^^^^^^^^^^^ -The :meth:`logical_and`, :meth:`logical_invert`, :meth:`logical_or`, -and :meth:`logical_xor` methods expect their arguments to be *logical +The :meth:`~Decimal.logical_and`, :meth:`~Decimal.logical_invert`, :meth:`~Decimal.logical_or`, +and :meth:`~Decimal.logical_xor` methods expect their arguments to be *logical operands*. A *logical operand* is a :class:`Decimal` instance whose exponent and sign are both zero, and whose digits are all either -:const:`0` or :const:`1`. +``0`` or ``1``. .. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -926,7 +937,7 @@ Each thread has its own current context which is accessed or changed using the You can also use the :keyword:`with` statement and the :func:`localcontext` function to temporarily change the active context. -.. function:: localcontext(ctx=None, \*\*kwargs) +.. function:: localcontext(ctx=None, **kwargs) Return a context manager that will set the current context for the active thread to a copy of *ctx* on entry to the with-statement and restore the previous context @@ -982,7 +993,7 @@ described below. In addition, the module provides three pre-made contexts: exceptions are not raised during computations). Because the traps are disabled, this context is useful for applications that - prefer to have result value of :const:`NaN` or :const:`Infinity` instead of + prefer to have result value of ``NaN`` or ``Infinity`` instead of raising exceptions. This allows an application to complete a run in the presence of conditions that would otherwise halt the program. @@ -1001,8 +1012,8 @@ described below. In addition, the module provides three pre-made contexts: In single threaded environments, it is preferable to not use this context at all. Instead, simply create contexts explicitly as described below. - The default values are :attr:`prec`\ =\ :const:`28`, - :attr:`rounding`\ =\ :const:`ROUND_HALF_EVEN`, + The default values are :attr:`Context.prec`\ =\ ``28``, + :attr:`Context.rounding`\ =\ :const:`ROUND_HALF_EVEN`, and enabled traps for :class:`Overflow`, :class:`InvalidOperation`, and :class:`DivisionByZero`. @@ -1016,7 +1027,7 @@ In addition to the three supplied contexts, new contexts can be created with the default values are copied from the :const:`DefaultContext`. If the *flags* field is not specified or is :const:`None`, all flags are cleared. - *prec* is an integer in the range [:const:`1`, :const:`MAX_PREC`] that sets + *prec* is an integer in the range [``1``, :const:`MAX_PREC`] that sets the precision for arithmetic operations in the context. The *rounding* option is one of the constants listed in the section @@ -1026,20 +1037,20 @@ In addition to the three supplied contexts, new contexts can be created with the contexts should only set traps and leave the flags clear. The *Emin* and *Emax* fields are integers specifying the outer limits allowable - for exponents. *Emin* must be in the range [:const:`MIN_EMIN`, :const:`0`], - *Emax* in the range [:const:`0`, :const:`MAX_EMAX`]. + for exponents. *Emin* must be in the range [:const:`MIN_EMIN`, ``0``], + *Emax* in the range [``0``, :const:`MAX_EMAX`]. - The *capitals* field is either :const:`0` or :const:`1` (the default). If set to - :const:`1`, exponents are printed with a capital :const:`E`; otherwise, a - lowercase :const:`e` is used: :const:`Decimal('6.02e+23')`. + The *capitals* field is either ``0`` or ``1`` (the default). If set to + ``1``, exponents are printed with a capital ``E``; otherwise, a + lowercase ``e`` is used: ``Decimal('6.02e+23')``. - The *clamp* field is either :const:`0` (the default) or :const:`1`. - If set to :const:`1`, the exponent ``e`` of a :class:`Decimal` + The *clamp* field is either ``0`` (the default) or ``1``. + If set to ``1``, the exponent ``e`` of a :class:`Decimal` instance representable in this context is strictly limited to the range ``Emin - prec + 1 <= e <= Emax - prec + 1``. If *clamp* is - :const:`0` then a weaker condition holds: the adjusted exponent of - the :class:`Decimal` instance is at most ``Emax``. When *clamp* is - :const:`1`, a large normal number will, where possible, have its + ``0`` then a weaker condition holds: the adjusted exponent of + the :class:`Decimal` instance is at most :attr:`~Context.Emax`. When *clamp* is + ``1``, a large normal number will, where possible, have its exponent reduced and a corresponding number of zeros added to its coefficient, in order to fit the exponent constraints; this preserves the value of the number but loses information about @@ -1048,13 +1059,13 @@ In addition to the three supplied contexts, new contexts can be created with the >>> Context(prec=6, Emax=999, clamp=1).create_decimal('1.23e999') Decimal('1.23000E+999') - A *clamp* value of :const:`1` allows compatibility with the + A *clamp* value of ``1`` allows compatibility with the fixed-width decimal interchange formats specified in IEEE 754. The :class:`Context` class defines several general purpose methods as well as a large number of methods for doing arithmetic directly in a given context. In addition, for each of the :class:`Decimal` methods described above (with - the exception of the :meth:`adjusted` and :meth:`as_tuple` methods) there is + the exception of the :meth:`~Decimal.adjusted` and :meth:`~Decimal.as_tuple` methods) there is a corresponding :class:`Context` method. For example, for a :class:`Context` instance ``C`` and :class:`Decimal` instance ``x``, ``C.exp(x)`` is equivalent to ``x.exp(context=C)``. Each :class:`Context` method accepts a @@ -1064,11 +1075,11 @@ In addition to the three supplied contexts, new contexts can be created with the .. method:: clear_flags() - Resets all of the flags to :const:`0`. + Resets all of the flags to ``0``. .. method:: clear_traps() - Resets all of the traps to :const:`0`. + Resets all of the traps to ``0``. .. versionadded:: 3.3 @@ -1483,13 +1494,13 @@ are also included in the pure Python version for compatibility. +---------------------+---------------------+-------------------------------+ | | 32-bit | 64-bit | +=====================+=====================+===============================+ -| .. data:: MAX_PREC | :const:`425000000` | :const:`999999999999999999` | +| .. data:: MAX_PREC | ``425000000`` | ``999999999999999999`` | +---------------------+---------------------+-------------------------------+ -| .. data:: MAX_EMAX | :const:`425000000` | :const:`999999999999999999` | +| .. data:: MAX_EMAX | ``425000000`` | ``999999999999999999`` | +---------------------+---------------------+-------------------------------+ -| .. data:: MIN_EMIN | :const:`-425000000` | :const:`-999999999999999999` | +| .. data:: MIN_EMIN | ``-425000000`` | ``-999999999999999999`` | +---------------------+---------------------+-------------------------------+ -| .. data:: MIN_ETINY | :const:`-849999999` | :const:`-1999999999999999997` | +| .. data:: MIN_ETINY | ``-849999999`` | ``-1999999999999999997`` | +---------------------+---------------------+-------------------------------+ @@ -1514,7 +1525,7 @@ Rounding modes .. data:: ROUND_CEILING - Round towards :const:`Infinity`. + Round towards ``Infinity``. .. data:: ROUND_DOWN @@ -1522,7 +1533,7 @@ Rounding modes .. data:: ROUND_FLOOR - Round towards :const:`-Infinity`. + Round towards ``-Infinity``. .. data:: ROUND_HALF_DOWN @@ -1570,7 +1581,7 @@ condition. Altered an exponent to fit representation constraints. Typically, clamping occurs when an exponent falls outside the context's - :attr:`Emin` and :attr:`Emax` limits. If possible, the exponent is reduced to + :attr:`~Context.Emin` and :attr:`~Context.Emax` limits. If possible, the exponent is reduced to fit by adding zeros to the coefficient. @@ -1584,8 +1595,8 @@ condition. Signals the division of a non-infinite number by zero. Can occur with division, modulo division, or when raising a number to a negative - power. If this signal is not trapped, returns :const:`Infinity` or - :const:`-Infinity` with the sign determined by the inputs to the calculation. + power. If this signal is not trapped, returns ``Infinity`` or + ``-Infinity`` with the sign determined by the inputs to the calculation. .. class:: Inexact @@ -1602,7 +1613,7 @@ condition. An invalid operation was performed. Indicates that an operation was requested that does not make sense. If not - trapped, returns :const:`NaN`. Possible causes include:: + trapped, returns ``NaN``. Possible causes include:: Infinity - Infinity 0 * Infinity @@ -1619,10 +1630,10 @@ condition. Numerical overflow. - Indicates the exponent is larger than :attr:`Emax` after rounding has + Indicates the exponent is larger than :attr:`Context.Emax` after rounding has occurred. If not trapped, the result depends on the rounding mode, either pulling inward to the largest representable finite number or rounding outward - to :const:`Infinity`. In either case, :class:`Inexact` and :class:`Rounded` + to ``Infinity``. In either case, :class:`Inexact` and :class:`Rounded` are also signaled. @@ -1631,14 +1642,14 @@ condition. Rounding occurred though possibly no information was lost. Signaled whenever rounding discards digits; even if those digits are zero - (such as rounding :const:`5.00` to :const:`5.0`). If not trapped, returns + (such as rounding ``5.00`` to ``5.0``). If not trapped, returns the result unchanged. This signal is used to detect loss of significant digits. .. class:: Subnormal - Exponent was lower than :attr:`Emin` prior to rounding. + Exponent was lower than :attr:`~Context.Emin` prior to rounding. Occurs when an operation result is subnormal (the exponent is too small). If not trapped, returns the result unchanged. @@ -1696,7 +1707,7 @@ Mitigating round-off error with increased precision ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The use of decimal floating point eliminates decimal representation error -(making it possible to represent :const:`0.1` exactly); however, some operations +(making it possible to represent ``0.1`` exactly); however, some operations can still incur round-off error when non-zero digits exceed the fixed precision. The effects of round-off error can be amplified by the addition or subtraction @@ -1746,8 +1757,8 @@ Special values ^^^^^^^^^^^^^^ The number system for the :mod:`decimal` module provides special values -including :const:`NaN`, :const:`sNaN`, :const:`-Infinity`, :const:`Infinity`, -and two zeros, :const:`+0` and :const:`-0`. +including ``NaN``, ``sNaN``, ``-Infinity``, ``Infinity``, +and two zeros, ``+0`` and ``-0``. Infinities can be constructed directly with: ``Decimal('Infinity')``. Also, they can arise from dividing by zero when the :exc:`DivisionByZero` signal is @@ -1758,30 +1769,30 @@ The infinities are signed (affine) and can be used in arithmetic operations where they get treated as very large, indeterminate numbers. For instance, adding a constant to infinity gives another infinite result. -Some operations are indeterminate and return :const:`NaN`, or if the +Some operations are indeterminate and return ``NaN``, or if the :exc:`InvalidOperation` signal is trapped, raise an exception. For example, -``0/0`` returns :const:`NaN` which means "not a number". This variety of -:const:`NaN` is quiet and, once created, will flow through other computations -always resulting in another :const:`NaN`. This behavior can be useful for a +``0/0`` returns ``NaN`` which means "not a number". This variety of +``NaN`` is quiet and, once created, will flow through other computations +always resulting in another ``NaN``. This behavior can be useful for a series of computations that occasionally have missing inputs --- it allows the calculation to proceed while flagging specific results as invalid. -A variant is :const:`sNaN` which signals rather than remaining quiet after every +A variant is ``sNaN`` which signals rather than remaining quiet after every operation. This is a useful return value when an invalid result needs to interrupt a calculation for special handling. The behavior of Python's comparison operators can be a little surprising where a -:const:`NaN` is involved. A test for equality where one of the operands is a -quiet or signaling :const:`NaN` always returns :const:`False` (even when doing +``NaN`` is involved. A test for equality where one of the operands is a +quiet or signaling ``NaN`` always returns :const:`False` (even when doing ``Decimal('NaN')==Decimal('NaN')``), while a test for inequality always returns :const:`True`. An attempt to compare two Decimals using any of the ``<``, ``<=``, ``>`` or ``>=`` operators will raise the :exc:`InvalidOperation` signal -if either operand is a :const:`NaN`, and return :const:`False` if this signal is +if either operand is a ``NaN``, and return :const:`False` if this signal is not trapped. Note that the General Decimal Arithmetic specification does not specify the behavior of direct comparisons; these rules for comparisons -involving a :const:`NaN` were taken from the IEEE 854 standard (see Table 3 in -section 5.7). To ensure strict standards-compliance, use the :meth:`compare` -and :meth:`compare-signal` methods instead. +involving a ``NaN`` were taken from the IEEE 854 standard (see Table 3 in +section 5.7). To ensure strict standards-compliance, use the :meth:`~Decimal.compare` +and :meth:`~Decimal.compare_signal` methods instead. The signed zeros can result from calculations that underflow. They keep the sign that would have resulted if the calculation had been carried out to greater @@ -2013,7 +2024,7 @@ Q. In a fixed-point application with two decimal places, some inputs have many places and need to be rounded. Others are not supposed to have excess digits and need to be validated. What methods should be used? -A. The :meth:`quantize` method rounds to a fixed number of decimal places. If +A. The :meth:`~Decimal.quantize` method rounds to a fixed number of decimal places. If the :const:`Inexact` trap is set, it is also useful for validation: >>> TWOPLACES = Decimal(10) ** -2 # same as Decimal('0.01') @@ -2037,7 +2048,7 @@ throughout an application? A. Some operations like addition, subtraction, and multiplication by an integer will automatically preserve fixed point. Others operations, like division and non-integer multiplication, will change the number of decimal places and need to -be followed-up with a :meth:`quantize` step: +be followed-up with a :meth:`~Decimal.quantize` step: >>> a = Decimal('102.72') # Initial fixed-point values >>> b = Decimal('3.17') @@ -2053,10 +2064,11 @@ be followed-up with a :meth:`quantize` step: Decimal('0.03') In developing fixed-point applications, it is convenient to define functions -to handle the :meth:`quantize` step: +to handle the :meth:`~Decimal.quantize` step: >>> def mul(x, y, fp=TWOPLACES): ... return (x * y).quantize(fp) + ... >>> def div(x, y, fp=TWOPLACES): ... return (x / y).quantize(fp) @@ -2065,24 +2077,44 @@ to handle the :meth:`quantize` step: >>> div(b, a) Decimal('0.03') -Q. There are many ways to express the same value. The numbers :const:`200`, -:const:`200.000`, :const:`2E2`, and :const:`.02E+4` all have the same value at +Q. There are many ways to express the same value. The numbers ``200``, +``200.000``, ``2E2``, and ``.02E+4`` all have the same value at various precisions. Is there a way to transform them to a single recognizable canonical value? -A. The :meth:`normalize` method maps all equivalent values to a single +A. The :meth:`~Decimal.normalize` method maps all equivalent values to a single representative: >>> values = map(Decimal, '200 200.000 2E2 .02E+4'.split()) >>> [v.normalize() for v in values] [Decimal('2E+2'), Decimal('2E+2'), Decimal('2E+2'), Decimal('2E+2')] +Q. When does rounding occur in a computation? + +A. It occurs *after* the computation. The philosophy of the decimal +specification is that numbers are considered exact and are created +independent of the current context. They can even have greater +precision than current context. Computations process with those +exact inputs and then rounding (or other context operations) is +applied to the *result* of the computation:: + + >>> getcontext().prec = 5 + >>> pi = Decimal('3.1415926535') # More than 5 digits + >>> pi # All digits are retained + Decimal('3.1415926535') + >>> pi + 0 # Rounded after an addition + Decimal('3.1416') + >>> pi - Decimal('0.00005') # Subtract unrounded numbers, then round + Decimal('3.1415') + >>> pi + 0 - Decimal('0.00005'). # Intermediate values are rounded + Decimal('3.1416') + Q. Some decimal values always print with exponential notation. Is there a way to get a non-exponential representation? A. For some values, exponential notation is the only way to express the number of significant places in the coefficient. For example, expressing -:const:`5.0E+3` as :const:`5000` keeps the value constant but cannot show the +``5.0E+3`` as ``5000`` keeps the value constant but cannot show the original's two-place significance. If an application does not care about tracking significance, it is easy to @@ -2158,12 +2190,12 @@ for medium-sized numbers and the `Number Theoretic Transform <https://en.wikipedia.org/wiki/Discrete_Fourier_transform_(general)#Number-theoretic_transform>`_ for very large numbers. -The context must be adapted for exact arbitrary precision arithmetic. :attr:`Emin` -and :attr:`Emax` should always be set to the maximum values, :attr:`clamp` -should always be 0 (the default). Setting :attr:`prec` requires some care. +The context must be adapted for exact arbitrary precision arithmetic. :attr:`~Context.Emin` +and :attr:`~Context.Emax` should always be set to the maximum values, :attr:`~Context.clamp` +should always be 0 (the default). Setting :attr:`~Context.prec` requires some care. The easiest approach for trying out bignum arithmetic is to use the maximum -value for :attr:`prec` as well [#]_:: +value for :attr:`~Context.prec` as well [#]_:: >>> setcontext(Context(prec=MAX_PREC, Emax=MAX_EMAX, Emin=MIN_EMIN)) >>> x = Decimal(2) ** 256 @@ -2180,7 +2212,7 @@ the available memory will be insufficient:: MemoryError On systems with overallocation (e.g. Linux), a more sophisticated approach is to -adjust :attr:`prec` to the amount of available RAM. Suppose that you have 8GB of +adjust :attr:`~Context.prec` to the amount of available RAM. Suppose that you have 8GB of RAM and expect 10 simultaneous operands using a maximum of 500MB each:: >>> import sys diff --git a/Doc/library/devmode.rst b/Doc/library/devmode.rst index 44e7d4f5..5b8a9bd1 100644 --- a/Doc/library/devmode.rst +++ b/Doc/library/devmode.rst @@ -16,12 +16,12 @@ setting the :envvar:`PYTHONDEVMODE` environment variable to ``1``. See also :ref:`Python debug build <debug-build>`. Effects of the Python Development Mode -====================================== +-------------------------------------- Enabling the Python Development Mode is similar to the following command, but with additional effects described below:: - PYTHONMALLOC=debug PYTHONASYNCIODEBUG=1 python3 -W default -X faulthandler + PYTHONMALLOC=debug PYTHONASYNCIODEBUG=1 python -W default -X faulthandler Effects of the Python Development Mode: @@ -59,8 +59,9 @@ Effects of the Python Development Mode: ``default``. * Call :func:`faulthandler.enable` at Python startup to install handlers for - the :const:`SIGSEGV`, :const:`SIGFPE`, :const:`SIGABRT`, :const:`SIGBUS` and - :const:`SIGILL` signals to dump the Python traceback on a crash. + the :const:`~signal.SIGSEGV`, :const:`~signal.SIGFPE`, + :const:`~signal.SIGABRT`, :const:`~signal.SIGBUS` and + :const:`~signal.SIGILL` signals to dump the Python traceback on a crash. It behaves as if the :option:`-X faulthandler <-X>` command line option is used or if the :envvar:`PYTHONFAULTHANDLER` environment variable is set to @@ -81,7 +82,7 @@ Effects of the Python Development Mode: ignored for empty strings. * The :class:`io.IOBase` destructor logs ``close()`` exceptions. -* Set the :attr:`~sys.flags.dev_mode` attribute of :attr:`sys.flags` to +* Set the :attr:`~sys.flags.dev_mode` attribute of :data:`sys.flags` to ``True``. The Python Development Mode does not enable the :mod:`tracemalloc` module by @@ -107,7 +108,7 @@ value can be read from :data:`sys.flags.dev_mode <sys.flags>`. ResourceWarning Example -======================= +----------------------- Example of a script counting the number of lines of the text file specified in the command line:: @@ -128,14 +129,14 @@ any warning. Example using README.txt, which has 269 lines: .. code-block:: shell-session - $ python3 script.py README.txt + $ python script.py README.txt 269 Enabling the Python Development Mode displays a :exc:`ResourceWarning` warning: .. code-block:: shell-session - $ python3 -X dev script.py README.txt + $ python -X dev script.py README.txt 269 script.py:10: ResourceWarning: unclosed file <_io.TextIOWrapper name='README.rst' mode='r' encoding='UTF-8'> main() @@ -146,7 +147,7 @@ opened: .. code-block:: shell-session - $ python3 -X dev -X tracemalloc=5 script.py README.rst + $ python -X dev -X tracemalloc=5 script.py README.rst 269 script.py:10: ResourceWarning: unclosed file <_io.TextIOWrapper name='README.rst' mode='r' encoding='UTF-8'> main() @@ -171,7 +172,7 @@ application more deterministic and more reliable. Bad file descriptor error example -================================= +--------------------------------- Script displaying the first line of itself:: @@ -190,7 +191,7 @@ By default, Python does not emit any warning: .. code-block:: shell-session - $ python3 script.py + $ python script.py import os The Python Development Mode shows a :exc:`ResourceWarning` and logs a "Bad file @@ -198,7 +199,7 @@ descriptor" error when finalizing the file object: .. code-block:: shell-session - $ python3 script.py + $ python -X dev script.py import os script.py:10: ResourceWarning: unclosed file <_io.TextIOWrapper name='script.py' mode='r' encoding='UTF-8'> main() diff --git a/Doc/library/difflib.rst b/Doc/library/difflib.rst index feaa7c1a..c5536114 100644 --- a/Doc/library/difflib.rst +++ b/Doc/library/difflib.rst @@ -79,7 +79,7 @@ diffs. For comparing directories and files, see also, the :mod:`filecmp` module. Lines beginning with '``?``' attempt to guide the eye to intraline differences, and were not present in either input sequence. These lines can be confusing if - the sequences contain tab characters. + the sequences contain whitespace characters, such as spaces, tabs or line breaks. .. class:: HtmlDiff @@ -145,8 +145,6 @@ diffs. For comparing directories and files, see also, the :mod:`filecmp` module. The arguments for this method are the same as those for the :meth:`make_file` method. - :file:`Tools/scripts/diff.py` is a command-line front-end to this class and - contains a good example of its use. .. function:: context_diff(a, b, fromfile='', tofile='', fromfiledate='', tofiledate='', n=3, lineterm='\n') @@ -240,8 +238,6 @@ diffs. For comparing directories and files, see also, the :mod:`filecmp` module. function :func:`IS_CHARACTER_JUNK`, which filters out whitespace characters (a blank or tab; it's a bad idea to include newline in this!). - :file:`Tools/scripts/ndiff.py` is a command-line front-end to this function. - >>> diff = ndiff('one\ntwo\nthree\n'.splitlines(keepends=True), ... 'ore\ntree\nemu\n'.splitlines(keepends=True)) >>> print(''.join(diff), end="") @@ -574,8 +570,8 @@ The :class:`SequenceMatcher` class has this constructor: The three methods that return the ratio of matching to total characters can give different results due to differing levels of approximation, although -:meth:`quick_ratio` and :meth:`real_quick_ratio` are always at least as large as -:meth:`ratio`: +:meth:`~SequenceMatcher.quick_ratio` and :meth:`~SequenceMatcher.real_quick_ratio` +are always at least as large as :meth:`~SequenceMatcher.ratio`: >>> s = SequenceMatcher(None, "abcd", "bcde") >>> s.ratio() @@ -597,15 +593,15 @@ This example compares two strings, considering blanks to be "junk": ... "private Thread currentThread;", ... "private volatile Thread currentThread;") -:meth:`ratio` returns a float in [0, 1], measuring the similarity of the -sequences. As a rule of thumb, a :meth:`ratio` value over 0.6 means the +:meth:`~SequenceMatcher.ratio` returns a float in [0, 1], measuring the similarity of the +sequences. As a rule of thumb, a :meth:`~SequenceMatcher.ratio` value over 0.6 means the sequences are close matches: >>> print(round(s.ratio(), 3)) 0.866 If you're only interested in where the sequences match, -:meth:`get_matching_blocks` is handy: +:meth:`~SequenceMatcher.get_matching_blocks` is handy: >>> for block in s.get_matching_blocks(): ... print("a[%d] and b[%d] match for %d elements" % block) @@ -613,12 +609,12 @@ If you're only interested in where the sequences match, a[8] and b[17] match for 21 elements a[29] and b[38] match for 0 elements -Note that the last tuple returned by :meth:`get_matching_blocks` is always a -dummy, ``(len(a), len(b), 0)``, and this is the only case in which the last +Note that the last tuple returned by :meth:`~SequenceMatcher.get_matching_blocks` +is always a dummy, ``(len(a), len(b), 0)``, and this is the only case in which the last tuple element (number of elements matched) is ``0``. If you want to know how to change the first sequence into the second, use -:meth:`get_opcodes`: +:meth:`~SequenceMatcher.get_opcodes`: >>> for opcode in s.get_opcodes(): ... print("%6s a[%d:%d] b[%d:%d]" % opcode) @@ -693,7 +689,7 @@ Differ Example This example compares two texts. First we set up the texts, sequences of individual single-line strings ending with newlines (such sequences can also be -obtained from the :meth:`~io.BaseIO.readlines` method of file-like objects): +obtained from the :meth:`~io.IOBase.readlines` method of file-like objects): >>> text1 = ''' 1. Beautiful is better than ugly. ... 2. Explicit is better than implicit. @@ -759,7 +755,12 @@ A command-line interface to difflib ----------------------------------- This example shows how to use difflib to create a ``diff``-like utility. -It is also contained in the Python source distribution, as -:file:`Tools/scripts/diff.py`. -.. literalinclude:: ../../Tools/scripts/diff.py +.. literalinclude:: ../includes/diff.py + +ndiff example +------------- + +This example shows how to use :func:`difflib.ndiff`. + +.. literalinclude:: ../includes/ndiff.py diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst index a61dd75c..b559b085 100644 --- a/Doc/library/dis.rst +++ b/Doc/library/dis.rst @@ -43,13 +43,13 @@ interpreter. adaptive bytecode can be shown by passing ``adaptive=True``. -Example: Given the function :func:`myfunc`:: +Example: Given the function :func:`!myfunc`:: def myfunc(alist): return len(alist) the following command can be used to display the disassembly of -:func:`myfunc`: +:func:`!myfunc`: .. doctest:: @@ -57,10 +57,9 @@ the following command can be used to display the disassembly of 2 0 RESUME 0 <BLANKLINE> 3 2 LOAD_GLOBAL 1 (NULL + len) - 14 LOAD_FAST 0 (alist) - 16 PRECALL 1 - 20 CALL 1 - 30 RETURN_VALUE + 12 LOAD_FAST 0 (alist) + 14 CALL 1 + 22 RETURN_VALUE (The "2" is a line number). @@ -139,7 +138,6 @@ Example: RESUME LOAD_GLOBAL LOAD_FAST - PRECALL CALL RETURN_VALUE @@ -190,9 +188,9 @@ operation is being performed, so the intermediate analysis object isn't useful: For a module, it disassembles all functions. For a class, it disassembles all methods (including class and static methods). For a code object or sequence of raw bytecode, it prints one line per bytecode instruction. - It also recursively disassembles nested code objects (the code of - comprehensions, generator expressions and nested functions, and the code - used for building nested classes). + It also recursively disassembles nested code objects. These can include + generator expressions, nested functions, the bodies of nested classes, + and the code objects used for :ref:`annotation scopes <annotation-scopes>`. Strings are first compiled to code objects with the :func:`compile` built-in function before being disassembled. If no object is provided, this function disassembles the last traceback. @@ -404,6 +402,10 @@ The Python compiler currently generates the following bytecode instructions. **General instructions** +In the following, We will refer to the interpreter stack as ``STACK`` and describe +operations on it as if it was a Python list. The top of the stack corresponds to +``STACK[-1]`` in this language. + .. opcode:: NOP Do nothing code. Used as a placeholder by the bytecode optimizer, and to @@ -412,20 +414,36 @@ The Python compiler currently generates the following bytecode instructions. .. opcode:: POP_TOP - Removes the top-of-stack (TOS) item. + Removes the top-of-stack item:: + + STACK.pop() + + +.. opcode:: END_FOR + + Removes the top two values from the stack. + Equivalent to ``POP_TOP``; ``POP_TOP``. + Used to clean up at the end of loops, hence the name. + + .. versionadded:: 3.12 .. opcode:: COPY (i) - Push the *i*-th item to the top of the stack. The item is not removed from its - original location. + Push the i-th item to the top of the stack without removing it from its original + location:: + + assert i > 0 + STACK.append(STACK[-i]) .. versionadded:: 3.11 .. opcode:: SWAP (i) - Swap TOS with the item at position *i*. + Swap the top of the stack with the i-th element:: + + STACK[-i], STACK[-1] = stack[-1], STACK[-i] .. versionadded:: 3.11 @@ -453,88 +471,123 @@ The Python compiler currently generates the following bytecode instructions. Unary operations take the top of the stack, apply the operation, and push the result back on the stack. -.. opcode:: UNARY_POSITIVE - - Implements ``TOS = +TOS``. - .. opcode:: UNARY_NEGATIVE - Implements ``TOS = -TOS``. + Implements ``STACK[-1] = -STACK[-1]``. .. opcode:: UNARY_NOT - Implements ``TOS = not TOS``. + Implements ``STACK[-1] = not STACK[-1]``. .. opcode:: UNARY_INVERT - Implements ``TOS = ~TOS``. + Implements ``STACK[-1] = ~STACK[-1]``. .. opcode:: GET_ITER - Implements ``TOS = iter(TOS)``. + Implements ``STACK[-1] = iter(STACK[-1])``. .. opcode:: GET_YIELD_FROM_ITER - If ``TOS`` is a :term:`generator iterator` or :term:`coroutine` object - it is left as is. Otherwise, implements ``TOS = iter(TOS)``. + If ``STACK[-1]`` is a :term:`generator iterator` or :term:`coroutine` object + it is left as is. Otherwise, implements ``STACK[-1] = iter(STACK[-1])``. .. versionadded:: 3.5 **Binary and in-place operations** -Binary operations remove the top of the stack (TOS) and the second top-most -stack item (TOS1) from the stack. They perform the operation, and put the -result back on the stack. +Binary operations remove the top two items from the stack (``STACK[-1]`` and +``STACK[-2]``). They perform the operation, then put the result back on the stack. -In-place operations are like binary operations, in that they remove TOS and -TOS1, and push the result back on the stack, but the operation is done in-place -when TOS1 supports it, and the resulting TOS may be (but does not have to be) -the original TOS1. +In-place operations are like binary operations, but the operation is done in-place +when ``STACK[-2]`` supports it, and the resulting ``STACK[-1]`` may be (but does +not have to be) the original ``STACK[-2]``. .. opcode:: BINARY_OP (op) Implements the binary and in-place operators (depending on the value of - *op*). + *op*):: + + rhs = STACK.pop() + lhs = STACK.pop() + STACK.append(lhs op rhs) .. versionadded:: 3.11 .. opcode:: BINARY_SUBSCR - Implements ``TOS = TOS1[TOS]``. + Implements:: + + key = STACK.pop() + container = STACK.pop() + STACK.append(container[key]) .. opcode:: STORE_SUBSCR - Implements ``TOS1[TOS] = TOS2``. + Implements:: + + key = STACK.pop() + container = STACK.pop() + value = STACK.pop() + container[key] = value .. opcode:: DELETE_SUBSCR - Implements ``del TOS1[TOS]``. + Implements:: + + key = STACK.pop() + container = STACK.pop() + del container[key] + +.. opcode:: BINARY_SLICE + + Implements:: + + end = STACK.pop() + start = STACK.pop() + container = STACK.pop() + STACK.append(container[start:end]) + + .. versionadded:: 3.12 + + +.. opcode:: STORE_SLICE + + Implements:: + + end = STACK.pop() + start = STACK.pop() + container = STACK.pop() + values = STACK.pop() + container[start:end] = value + + .. versionadded:: 3.12 **Coroutine opcodes** .. opcode:: GET_AWAITABLE (where) - Implements ``TOS = get_awaitable(TOS)``, where ``get_awaitable(o)`` + Implements ``STACK[-1] = get_awaitable(STACK[-1])``, where ``get_awaitable(o)`` returns ``o`` if ``o`` is a coroutine object or a generator object with - the CO_ITERABLE_COROUTINE flag, or resolves + the :data:`~inspect.CO_ITERABLE_COROUTINE` flag, or resolves ``o.__await__``. If the ``where`` operand is nonzero, it indicates where the instruction occurs: - * ``1`` After a call to ``__aenter__`` - * ``2`` After a call to ``__aexit__`` + * ``1``: After a call to ``__aenter__`` + * ``2``: After a call to ``__aexit__`` .. versionadded:: 3.5 @@ -544,7 +597,7 @@ the original TOS1. .. opcode:: GET_AITER - Implements ``TOS = TOS.__aiter__()``. + Implements ``STACK[-1] = STACK[-1].__aiter__()``. .. versionadded:: 3.5 .. versionchanged:: 3.7 @@ -554,8 +607,8 @@ the original TOS1. .. opcode:: GET_ANEXT - Pushes ``get_awaitable(TOS.__anext__())`` to the stack. See - ``GET_AWAITABLE`` for details about ``get_awaitable``. + Implement ``STACK.append(get_awaitable(STACK[-1].__anext__()))`` to the stack. + See ``GET_AWAITABLE`` for details about ``get_awaitable``. .. versionadded:: 3.5 @@ -564,18 +617,31 @@ the original TOS1. Terminates an :keyword:`async for` loop. Handles an exception raised when awaiting a next item. The stack contains the async iterable in - TOS1 and the raised exception in TOS. Both are popped. + ``STACK[-2]`` and the raised exception in ``STACK[-1]``. Both are popped. If the exception is not :exc:`StopAsyncIteration`, it is re-raised. .. versionadded:: 3.8 - .. versionchanged:: 3.11 - Exception representation on the stack now consist of one, not three, items. + .. versionchanged:: 3.11 + Exception representation on the stack now consist of one, not three, items. + + +.. opcode:: CLEANUP_THROW + + Handles an exception raised during a :meth:`~generator.throw` or + :meth:`~generator.close` call through the current frame. If ``STACK[-1]`` is an + instance of :exc:`StopIteration`, pop three values from the stack and push + its ``value`` member. Otherwise, re-raise ``STACK[-1]``. + + .. versionadded:: 3.12 + .. opcode:: BEFORE_ASYNC_WITH - Resolves ``__aenter__`` and ``__aexit__`` from the object on top of the - stack. Pushes ``__aexit__`` and result of ``__aenter__()`` to the stack. + Resolves ``__aenter__`` and ``__aexit__`` from ``STACK[-1]``. + Pushes ``__aexit__`` and result of ``__aenter__()`` to the stack:: + + STACK.extend((__aexit__, __aenter__()) .. versionadded:: 3.5 @@ -583,31 +649,40 @@ the original TOS1. **Miscellaneous opcodes** -.. opcode:: PRINT_EXPR +.. opcode:: SET_ADD (i) - Implements the expression statement for the interactive mode. TOS is removed - from the stack and printed. In non-interactive mode, an expression statement - is terminated with :opcode:`POP_TOP`. + Implements:: + item = STACK.pop() + set.add(STACK[-i], item) -.. opcode:: SET_ADD (i) - - Calls ``set.add(TOS1[-i], TOS)``. Used to implement set comprehensions. + Used to implement set comprehensions. .. opcode:: LIST_APPEND (i) - Calls ``list.append(TOS1[-i], TOS)``. Used to implement list comprehensions. + Implements:: + + item = STACK.pop() + list.append(STACK[-i], item) + + Used to implement list comprehensions. .. opcode:: MAP_ADD (i) - Calls ``dict.__setitem__(TOS1[-i], TOS1, TOS)``. Used to implement dict - comprehensions. + Implements:: + + value = STACK.pop() + key = STACK.pop() + dict.__setitem__(STACK[-i], key, value) + + Used to implement dict comprehensions. .. versionadded:: 3.1 .. versionchanged:: 3.8 - Map value is TOS and map key is TOS1. Before, those were reversed. + Map value is ``STACK[-1]`` and map key is ``STACK[-2]``. Before, those + were reversed. For all of the :opcode:`SET_ADD`, :opcode:`LIST_APPEND` and :opcode:`MAP_ADD` instructions, while the added value or key/value pair is popped off, the @@ -617,13 +692,25 @@ iterations of the loop. .. opcode:: RETURN_VALUE - Returns with TOS to the caller of the function. + Returns with ``STACK[-1]`` to the caller of the function. + + +.. opcode:: RETURN_CONST (consti) + + Returns with ``co_consts[consti]`` to the caller of the function. + + .. versionadded:: 3.12 .. opcode:: YIELD_VALUE - Pops TOS and yields it from a :term:`generator`. + Yields ``STACK.pop()`` from a :term:`generator`. + + .. versionchanged:: 3.11 + oparg set to be the stack depth. + .. versionchanged:: 3.12 + oparg set to be the exception block depth, for efficient closing of generators. .. opcode:: SETUP_ANNOTATIONS @@ -636,50 +723,44 @@ iterations of the loop. .. versionadded:: 3.6 -.. opcode:: IMPORT_STAR - - Loads all symbols not starting with ``'_'`` directly from the module TOS to - the local namespace. The module is popped after loading all names. This - opcode implements ``from module import *``. - - .. opcode:: POP_EXCEPT Pops a value from the stack, which is used to restore the exception state. - .. versionchanged:: 3.11 - Exception representation on the stack now consist of one, not three, items. + .. versionchanged:: 3.11 + Exception representation on the stack now consist of one, not three, items. .. opcode:: RERAISE - Re-raises the exception currently on top of the stack. If oparg is non-zero, - pops an additional value from the stack which is used to set ``f_lasti`` - of the current frame. + Re-raises the exception currently on top of the stack. If oparg is non-zero, + pops an additional value from the stack which is used to set ``f_lasti`` + of the current frame. - .. versionadded:: 3.9 + .. versionadded:: 3.9 - .. versionchanged:: 3.11 - Exception representation on the stack now consist of one, not three, items. + .. versionchanged:: 3.11 + Exception representation on the stack now consist of one, not three, items. .. opcode:: PUSH_EXC_INFO - Pops a value from the stack. Pushes the current exception to the top of the stack. - Pushes the value originally popped back to the stack. - Used in exception handlers. + Pops a value from the stack. Pushes the current exception to the top of the stack. + Pushes the value originally popped back to the stack. + Used in exception handlers. - .. versionadded:: 3.11 + .. versionadded:: 3.11 .. opcode:: CHECK_EXC_MATCH - Performs exception matching for ``except``. Tests whether the TOS1 is an exception - matching TOS. Pops TOS and pushes the boolean result of the test. + Performs exception matching for ``except``. Tests whether the ``STACK[-2]`` + is an exception matching ``STACK[-1]``. Pops ``STACK[-1]`` and pushes the boolean + result of the test. .. versionadded:: 3.11 .. opcode:: CHECK_EG_MATCH - Performs exception matching for ``except*``. Applies ``split(TOS)`` on - the exception group representing TOS1. + Performs exception matching for ``except*``. Applies ``split(STACK[-1])`` on + the exception group representing ``STACK[-2]``. In case of a match, pops two items from the stack and pushes the non-matching subgroup (``None`` in case of full match) followed by the @@ -688,28 +769,18 @@ iterations of the loop. .. versionadded:: 3.11 -.. opcode:: PREP_RERAISE_STAR - - Combines the raised and reraised exceptions list from TOS, into an exception - group to propagate from a try-except* block. Uses the original exception - group from TOS1 to reconstruct the structure of reraised exceptions. Pops - two items from the stack and pushes the exception to reraise or ``None`` - if there isn't one. - - .. versionadded:: 3.11 - .. opcode:: WITH_EXCEPT_START - Calls the function in position 4 on the stack with arguments (type, val, tb) - representing the exception at the top of the stack. - Used to implement the call ``context_manager.__exit__(*exc_info())`` when an exception - has occurred in a :keyword:`with` statement. + Calls the function in position 4 on the stack with arguments (type, val, tb) + representing the exception at the top of the stack. + Used to implement the call ``context_manager.__exit__(*exc_info())`` when an exception + has occurred in a :keyword:`with` statement. - .. versionadded:: 3.9 + .. versionadded:: 3.9 - .. versionchanged:: 3.11 - The ``__exit__`` function is in position 4 of the stack rather than 7. - Exception representation on the stack now consist of one, not three, items. + .. versionchanged:: 3.11 + The ``__exit__`` function is in position 4 of the stack rather than 7. + Exception representation on the stack now consist of one, not three, items. .. opcode:: LOAD_ASSERTION_ERROR @@ -722,11 +793,11 @@ iterations of the loop. .. opcode:: LOAD_BUILD_CLASS - Pushes :func:`builtins.__build_class__` onto the stack. It is later called + Pushes :func:`!builtins.__build_class__` onto the stack. It is later called to construct a class. -.. opcode:: BEFORE_WITH (delta) +.. opcode:: BEFORE_WITH This opcode performs several operations before a with block starts. First, it loads :meth:`~object.__exit__` from the context manager and pushes it onto @@ -739,26 +810,26 @@ iterations of the loop. .. opcode:: GET_LEN - Push ``len(TOS)`` onto the stack. + Perform ``STACK.append(len(STACK[-1]))``. .. versionadded:: 3.10 .. opcode:: MATCH_MAPPING - If TOS is an instance of :class:`collections.abc.Mapping` (or, more technically: if - it has the :const:`Py_TPFLAGS_MAPPING` flag set in its - :c:member:`~PyTypeObject.tp_flags`), push ``True`` onto the stack. Otherwise, push - ``False``. + If ``STACK[-1]`` is an instance of :class:`collections.abc.Mapping` (or, more + technically: if it has the :c:macro:`Py_TPFLAGS_MAPPING` flag set in its + :c:member:`~PyTypeObject.tp_flags`), push ``True`` onto the stack. Otherwise, + push ``False``. .. versionadded:: 3.10 .. opcode:: MATCH_SEQUENCE - If TOS is an instance of :class:`collections.abc.Sequence` and is *not* an instance + If ``STACK[-1]`` is an instance of :class:`collections.abc.Sequence` and is *not* an instance of :class:`str`/:class:`bytes`/:class:`bytearray` (or, more technically: if it has - the :const:`Py_TPFLAGS_SEQUENCE` flag set in its :c:member:`~PyTypeObject.tp_flags`), + the :c:macro:`Py_TPFLAGS_SEQUENCE` flag set in its :c:member:`~PyTypeObject.tp_flags`), push ``True`` onto the stack. Otherwise, push ``False``. .. versionadded:: 3.10 @@ -766,9 +837,9 @@ iterations of the loop. .. opcode:: MATCH_KEYS - TOS is a tuple of mapping keys, and TOS1 is the match subject. If TOS1 - contains all of the keys in TOS, push a :class:`tuple` containing the - corresponding values. Otherwise, push ``None``. + ``STACK[-1]`` is a tuple of mapping keys, and ``STACK[-2]`` is the match subject. + If ``STACK[-2]`` contains all of the keys in ``STACK[-1]``, push a :class:`tuple` + containing the corresponding values. Otherwise, push ``None``. .. versionadded:: 3.10 @@ -779,44 +850,65 @@ iterations of the loop. .. opcode:: STORE_NAME (namei) - Implements ``name = TOS``. *namei* is the index of *name* in the attribute - :attr:`co_names` of the code object. The compiler tries to use - :opcode:`STORE_FAST` or :opcode:`STORE_GLOBAL` if possible. + Implements ``name = STACK.pop()``. *namei* is the index of *name* in the attribute + :attr:`!co_names` of the :ref:`code object <code-objects>`. + The compiler tries to use :opcode:`STORE_FAST` or :opcode:`STORE_GLOBAL` if possible. .. opcode:: DELETE_NAME (namei) - Implements ``del name``, where *namei* is the index into :attr:`co_names` - attribute of the code object. + Implements ``del name``, where *namei* is the index into :attr:`!co_names` + attribute of the :ref:`code object <code-objects>`. .. opcode:: UNPACK_SEQUENCE (count) - Unpacks TOS into *count* individual values, which are put onto the stack - right-to-left. + Unpacks ``STACK[-1]`` into *count* individual values, which are put onto the stack + right-to-left. Require there to be exactly *count* values.:: + + assert(len(STACK[-1]) == count) + STACK.extend(STACK.pop()[:-count-1:-1]) .. opcode:: UNPACK_EX (counts) - Implements assignment with a starred target: Unpacks an iterable in TOS into - individual values, where the total number of values can be smaller than the + Implements assignment with a starred target: Unpacks an iterable in ``STACK[-1]`` + into individual values, where the total number of values can be smaller than the number of items in the iterable: one of the new values will be a list of all leftover items. - The low byte of *counts* is the number of values before the list value, the - high byte of *counts* the number of values after it. The resulting values - are put onto the stack right-to-left. + The number of values before and after the list value is limited to 255. + + The number of values before the list value is encoded in the argument of the + opcode. The number of values after the list if any is encoded using an + ``EXTENDED_ARG``. As a consequence, the argument can be seen as a two bytes values + where the low byte of *counts* is the number of values before the list value, the + high byte of *counts* the number of values after it. + + The extracted values are put onto the stack right-to-left, i.e. ``a, *b, c = d`` + will be stored after execution as ``STACK.extend((a, b, c))``. .. opcode:: STORE_ATTR (namei) - Implements ``TOS.name = TOS1``, where *namei* is the index of name in - :attr:`co_names`. + Implements:: + obj = STACK.pop() + value = STACK.pop() + obj.name = value + + where *namei* is the index of name in :attr:`!co_names` of the + :ref:`code object <code-objects>`. .. opcode:: DELETE_ATTR (namei) - Implements ``del TOS.name``, using *namei* as index into :attr:`co_names`. + Implements:: + + obj = STACK.pop() + del obj.name + + where *namei* is the index of name into :attr:`!co_names` of the + :ref:`code object <code-objects>`. .. opcode:: STORE_GLOBAL (namei) @@ -837,12 +929,37 @@ iterations of the loop. .. opcode:: LOAD_NAME (namei) Pushes the value associated with ``co_names[namei]`` onto the stack. + The name is looked up within the locals, then the globals, then the builtins. + + +.. opcode:: LOAD_LOCALS + + Pushes a reference to the locals dictionary onto the stack. This is used + to prepare namespace dictionaries for :opcode:`LOAD_FROM_DICT_OR_DEREF` + and :opcode:`LOAD_FROM_DICT_OR_GLOBALS`. + + .. versionadded:: 3.12 + + +.. opcode:: LOAD_FROM_DICT_OR_GLOBALS (i) + + Pops a mapping off the stack and looks up the value for ``co_names[namei]``. + If the name is not found there, looks it up in the globals and then the builtins, + similar to :opcode:`LOAD_GLOBAL`. + This is used for loading global variables in + :ref:`annotation scopes <annotation-scopes>` within class bodies. + + .. versionadded:: 3.12 .. opcode:: BUILD_TUPLE (count) Creates a tuple consuming *count* items from the stack, and pushes the - resulting tuple onto the stack. + resulting tuple onto the stack.:: + + assert count > 0 + STACK, values = STACK[:-count], STACK[-count:] + STACK.append(tuple(values)) .. opcode:: BUILD_LIST (count) @@ -859,7 +976,7 @@ iterations of the loop. Pushes a new dictionary object onto the stack. Pops ``2 * count`` items so that the dictionary holds *count* entries: - ``{..., TOS3: TOS2, TOS1: TOS}``. + ``{..., STACK[-4]: STACK[-3], STACK[-2]: STACK[-1]}``. .. versionchanged:: 3.5 The dictionary is created from stack items instead of creating an @@ -870,7 +987,7 @@ iterations of the loop. The version of :opcode:`BUILD_MAP` specialized for constant keys. Pops the top element on the stack which contains a tuple of keys, then starting from - ``TOS1``, pops *count* values to form values in the built dictionary. + ``STACK[-2]``, pops *count* values to form values in the built dictionary. .. versionadded:: 3.6 @@ -883,30 +1000,38 @@ iterations of the loop. .. versionadded:: 3.6 -.. opcode:: LIST_TO_TUPLE +.. opcode:: LIST_EXTEND (i) - Pops a list from the stack and pushes a tuple containing the same values. + Implements:: - .. versionadded:: 3.9 + seq = STACK.pop() + list.extend(STACK[-i], seq) - -.. opcode:: LIST_EXTEND (i) - - Calls ``list.extend(TOS1[-i], TOS)``. Used to build lists. + Used to build lists. .. versionadded:: 3.9 .. opcode:: SET_UPDATE (i) - Calls ``set.update(TOS1[-i], TOS)``. Used to build sets. + Implements:: + + seq = STACK.pop() + set.update(STACK[-i], seq) + + Used to build sets. .. versionadded:: 3.9 .. opcode:: DICT_UPDATE (i) - Calls ``dict.update(TOS1[-i], TOS)``. Used to build dicts. + Implements:: + + map = STACK.pop() + dict.update(STACK[-i], map) + + Used to build dicts. .. versionadded:: 3.9 @@ -920,7 +1045,38 @@ iterations of the loop. .. opcode:: LOAD_ATTR (namei) - Replaces TOS with ``getattr(TOS, co_names[namei])``. + If the low bit of ``namei`` is not set, this replaces ``STACK[-1]`` with + ``getattr(STACK[-1], co_names[namei>>1])``. + + If the low bit of ``namei`` is set, this will attempt to load a method named + ``co_names[namei>>1]`` from the ``STACK[-1]`` object. ``STACK[-1]`` is popped. + This bytecode distinguishes two cases: if ``STACK[-1]`` has a method with the + correct name, the bytecode pushes the unbound method and ``STACK[-1]``. + ``STACK[-1]`` will be used as the first argument (``self``) by :opcode:`CALL` + when calling the unbound method. Otherwise, ``NULL`` and the object returned by + the attribute lookup are pushed. + + .. versionchanged:: 3.12 + If the low bit of ``namei`` is set, then a ``NULL`` or ``self`` is + pushed to the stack before the attribute or unbound method respectively. + + +.. opcode:: LOAD_SUPER_ATTR (namei) + + This opcode implements :func:`super` (e.g. ``super().method()`` and + ``super().attr``). It works the same as :opcode:`LOAD_ATTR`, except that + ``namei`` is shifted left by 2 bits instead of 1, and instead of expecting a + single receiver on the stack, it expects three objects (from top of stack + down): ``self`` (the first argument to the current method), ``cls`` (the + class within which the current method was defined), and the global ``super``. + + The low bit of ``namei`` signals to attempt a method load, as with + :opcode:`LOAD_ATTR`. + + The second-low bit of ``namei``, if set, means that this was a two-argument + call to :func:`super` (unset means zero-argument). + + .. versionadded:: 3.12 .. opcode:: COMPARE_OP (opname) @@ -945,17 +1101,16 @@ iterations of the loop. .. opcode:: IMPORT_NAME (namei) - Imports the module ``co_names[namei]``. TOS and TOS1 are popped and provide - the *fromlist* and *level* arguments of :func:`__import__`. The module - object is pushed onto the stack. The current namespace is not affected: for - a proper import statement, a subsequent :opcode:`STORE_FAST` instruction + Imports the module ``co_names[namei]``. ``STACK[-1]`` and ``STACK[-2]`` are + popped and provide the *fromlist* and *level* arguments of :func:`__import__`. + The module object is pushed onto the stack. The current namespace is not affected: for a proper import statement, a subsequent :opcode:`STORE_FAST` instruction modifies the namespace. .. opcode:: IMPORT_FROM (namei) - Loads the attribute ``co_names[namei]`` from the module found in TOS. The - resulting object is pushed onto the stack, to be subsequently stored by a + Loads the attribute ``co_names[namei]`` from the module found in ``STACK[-1]``. + The resulting object is pushed onto the stack, to be subsequently stored by a :opcode:`STORE_FAST` instruction. @@ -978,90 +1133,68 @@ iterations of the loop. .. versionadded:: 3.11 -.. opcode:: POP_JUMP_FORWARD_IF_TRUE (delta) - - If TOS is true, increments the bytecode counter by *delta*. TOS is popped. - - .. versionadded:: 3.11 - - -.. opcode:: POP_JUMP_BACKWARD_IF_TRUE (delta) - - If TOS is true, decrements the bytecode counter by *delta*. TOS is popped. - - .. versionadded:: 3.11 - +.. opcode:: POP_JUMP_IF_TRUE (delta) -.. opcode:: POP_JUMP_FORWARD_IF_FALSE (delta) + If ``STACK[-1]`` is true, increments the bytecode counter by *delta*. + ``STACK[-1]`` is popped. - If TOS is false, increments the bytecode counter by *delta*. TOS is popped. + .. versionchanged:: 3.11 + The oparg is now a relative delta rather than an absolute target. + This opcode is a pseudo-instruction, replaced in final bytecode by + the directed versions (forward/backward). - .. versionadded:: 3.11 + .. versionchanged:: 3.12 + This is no longer a pseudo-instruction. +.. opcode:: POP_JUMP_IF_FALSE (delta) -.. opcode:: POP_JUMP_BACKWARD_IF_FALSE (delta) + If ``STACK[-1]`` is false, increments the bytecode counter by *delta*. + ``STACK[-1]`` is popped. - If TOS is false, decrements the bytecode counter by *delta*. TOS is popped. + .. versionchanged:: 3.11 + The oparg is now a relative delta rather than an absolute target. + This opcode is a pseudo-instruction, replaced in final bytecode by + the directed versions (forward/backward). - .. versionadded:: 3.11 + .. versionchanged:: 3.12 + This is no longer a pseudo-instruction. +.. opcode:: POP_JUMP_IF_NOT_NONE (delta) -.. opcode:: POP_JUMP_FORWARD_IF_NOT_NONE (delta) + If ``STACK[-1]`` is not ``None``, increments the bytecode counter by *delta*. + ``STACK[-1]`` is popped. - If TOS is not ``None``, increments the bytecode counter by *delta*. TOS is popped. + This opcode is a pseudo-instruction, replaced in final bytecode by + the directed versions (forward/backward). .. versionadded:: 3.11 + .. versionchanged:: 3.12 + This is no longer a pseudo-instruction. -.. opcode:: POP_JUMP_BACKWARD_IF_NOT_NONE (delta) - - If TOS is not ``None``, decrements the bytecode counter by *delta*. TOS is popped. - .. versionadded:: 3.11 +.. opcode:: POP_JUMP_IF_NONE (delta) + If ``STACK[-1]`` is ``None``, increments the bytecode counter by *delta*. + ``STACK[-1]`` is popped. -.. opcode:: POP_JUMP_FORWARD_IF_NONE (delta) - - If TOS is ``None``, increments the bytecode counter by *delta*. TOS is popped. + This opcode is a pseudo-instruction, replaced in final bytecode by + the directed versions (forward/backward). .. versionadded:: 3.11 - -.. opcode:: POP_JUMP_BACKWARD_IF_NONE (delta) - - If TOS is ``None``, decrements the bytecode counter by *delta*. TOS is popped. - - .. versionadded:: 3.11 - - -.. opcode:: JUMP_IF_TRUE_OR_POP (delta) - - If TOS is true, increments the bytecode counter by *delta* and leaves TOS on the - stack. Otherwise (TOS is false), TOS is popped. - - .. versionadded:: 3.1 - - .. versionchanged:: 3.11 - The oparg is now a relative delta rather than an absolute target. - -.. opcode:: JUMP_IF_FALSE_OR_POP (delta) - - If TOS is false, increments the bytecode counter by *delta* and leaves TOS on the - stack. Otherwise (TOS is true), TOS is popped. - - .. versionadded:: 3.1 - - .. versionchanged:: 3.11 - The oparg is now a relative delta rather than an absolute target. - + .. versionchanged:: 3.12 + This is no longer a pseudo-instruction. .. opcode:: FOR_ITER (delta) - TOS is an :term:`iterator`. Call its :meth:`~iterator.__next__` method. If - this yields a new value, push it on the stack (leaving the iterator below - it). If the iterator indicates it is exhausted, TOS is popped, and the byte - code counter is incremented by *delta*. + ``STACK[-1]`` is an :term:`iterator`. Call its :meth:`~iterator.__next__` method. + If this yields a new value, push it on the stack (leaving the iterator below + it). If the iterator indicates it is exhausted then the byte code counter is + incremented by *delta*. + .. versionchanged:: 3.12 + Up until 3.11 the iterator was popped when it was exhausted. .. opcode:: LOAD_GLOBAL (namei) @@ -1075,10 +1208,29 @@ iterations of the loop. Pushes a reference to the local ``co_varnames[var_num]`` onto the stack. + .. versionchanged:: 3.12 + This opcode is now only used in situations where the local variable is + guaranteed to be initialized. It cannot raise :exc:`UnboundLocalError`. + +.. opcode:: LOAD_FAST_CHECK (var_num) + + Pushes a reference to the local ``co_varnames[var_num]`` onto the stack, + raising an :exc:`UnboundLocalError` if the local variable has not been + initialized. + + .. versionadded:: 3.12 + +.. opcode:: LOAD_FAST_AND_CLEAR (var_num) + + Pushes a reference to the local ``co_varnames[var_num]`` onto the stack (or + pushes ``NULL`` onto the stack if the local variable has not been + initialized) and sets ``co_varnames[var_num]`` to ``NULL``. + + .. versionadded:: 3.12 .. opcode:: STORE_FAST (var_num) - Stores TOS into the local ``co_varnames[var_num]``. + Stores ``STACK.pop()`` into the local ``co_varnames[var_num]``. .. opcode:: DELETE_FAST (var_num) @@ -1088,7 +1240,7 @@ iterations of the loop. .. opcode:: MAKE_CELL (i) - Creates a new cell in slot ``i``. If that slot is empty then + Creates a new cell in slot ``i``. If that slot is nonempty then that value is stored into the new cell. .. versionadded:: 3.11 @@ -1115,21 +1267,22 @@ iterations of the loop. ``i`` is no longer offset by the length of ``co_varnames``. -.. opcode:: LOAD_CLASSDEREF (i) +.. opcode:: LOAD_FROM_DICT_OR_DEREF (i) - Much like :opcode:`LOAD_DEREF` but first checks the locals dictionary before - consulting the cell. This is used for loading free variables in class - bodies. + Pops a mapping off the stack and looks up the name associated with + slot ``i`` of the "fast locals" storage in this mapping. + If the name is not found there, loads it from the cell contained in + slot ``i``, similar to :opcode:`LOAD_DEREF`. This is used for loading + free variables in class bodies (which previously used + :opcode:`!LOAD_CLASSDEREF`) and in + :ref:`annotation scopes <annotation-scopes>` within class bodies. - .. versionadded:: 3.4 - - .. versionchanged:: 3.11 - ``i`` is no longer offset by the length of ``co_varnames``. + .. versionadded:: 3.12 .. opcode:: STORE_DEREF (i) - Stores TOS into the cell contained in slot ``i`` of the "fast locals" + Stores ``STACK.pop()`` into the cell contained in slot ``i`` of the "fast locals" storage. .. versionchanged:: 3.11 @@ -1162,9 +1315,9 @@ iterations of the loop. depending on the value of *argc*: * 0: ``raise`` (re-raise previous exception) - * 1: ``raise TOS`` (raise exception instance or type at ``TOS``) - * 2: ``raise TOS1 from TOS`` (raise exception instance or type at ``TOS1`` - with ``__cause__`` set to ``TOS``) + * 1: ``raise STACK[-1]`` (raise exception instance or type at ``STACK[-1]``) + * 2: ``raise STACK[-2] from STACK[-1]`` (raise exception instance or type at + ``STACK[-2]`` with ``__cause__`` set to ``STACK[-1]``) .. opcode:: CALL (argc) @@ -1211,39 +1364,18 @@ iterations of the loop. .. versionadded:: 3.6 -.. opcode:: LOAD_METHOD (namei) - - Loads a method named ``co_names[namei]`` from the TOS object. TOS is popped. - This bytecode distinguishes two cases: if TOS has a method with the correct - name, the bytecode pushes the unbound method and TOS. TOS will be used as - the first argument (``self``) by :opcode:`CALL` when calling the - unbound method. Otherwise, ``NULL`` and the object return by the attribute - lookup are pushed. - - .. versionadded:: 3.7 - - -.. opcode:: PRECALL (argc) - - Prefixes :opcode:`CALL`. Logically this is a no op. - It exists to enable effective specialization of calls. - ``argc`` is the number of arguments as described in :opcode:`CALL`. - - .. versionadded:: 3.11 - - .. opcode:: PUSH_NULL - Pushes a ``NULL`` to the stack. - Used in the call sequence to match the ``NULL`` pushed by - :opcode:`LOAD_METHOD` for non-method calls. + Pushes a ``NULL`` to the stack. + Used in the call sequence to match the ``NULL`` pushed by + :opcode:`LOAD_METHOD` for non-method calls. .. versionadded:: 3.11 -.. opcode:: KW_NAMES (i) +.. opcode:: KW_NAMES (consti) - Prefixes :opcode:`PRECALL`. + Prefixes :opcode:`CALL`. Stores a reference to ``co_consts[consti]`` into an internal variable for use by :opcode:`CALL`. ``co_consts[consti]`` must be a tuple of strings. @@ -1260,19 +1392,33 @@ iterations of the loop. * ``0x02`` a dictionary of keyword-only parameters' default values * ``0x04`` a tuple of strings containing parameters' annotations * ``0x08`` a tuple containing cells for free variables, making a closure - * the code associated with the function (at TOS1) - * the :term:`qualified name` of the function (at TOS) + * the code associated with the function (at ``STACK[-1]``) .. versionchanged:: 3.10 Flag value ``0x04`` is a tuple of strings instead of dictionary + .. versionchanged:: 3.11 + Qualified name at ``STACK[-1]`` was removed. + + .. opcode:: BUILD_SLICE (argc) - .. index:: builtin: slice + .. index:: pair: built-in function; slice + + Pushes a slice object on the stack. *argc* must be 2 or 3. If it is 2, implements:: - Pushes a slice object on the stack. *argc* must be 2 or 3. If it is 2, - ``slice(TOS1, TOS)`` is pushed; if it is 3, ``slice(TOS2, TOS1, TOS)`` is - pushed. See the :func:`slice` built-in function for more information. + end = STACK.pop() + start = STACK.pop() + STACK.append(slice(start, stop)) + + if it is 3, implements:: + + step = STACK.pop() + end = STACK.pop() + start = STACK.pop() + STACK.append(slice(start, end, step)) + + See the :func:`slice` built-in function for more information. .. opcode:: EXTENDED_ARG (ext) @@ -1307,13 +1453,14 @@ iterations of the loop. .. opcode:: MATCH_CLASS (count) - TOS is a tuple of keyword attribute names, TOS1 is the class being matched - against, and TOS2 is the match subject. *count* is the number of positional - sub-patterns. + ``STACK[-1]`` is a tuple of keyword attribute names, ``STACK[-2]`` is the class + being matched against, and ``STACK[-3]`` is the match subject. *count* is the + number of positional sub-patterns. - Pop TOS, TOS1, and TOS2. If TOS2 is an instance of TOS1 and has the - positional and keyword attributes required by *count* and TOS, push a tuple - of extracted attributes. Otherwise, push ``None``. + Pop ``STACK[-1]``, ``STACK[-2]``, and ``STACK[-3]``. If ``STACK[-3]`` is an + instance of ``STACK[-2]`` and has the positional and keyword attributes + required by *count* and ``STACK[-1]``, push a tuple of extracted attributes. + Otherwise, push ``None``. .. versionadded:: 3.10 @@ -1324,52 +1471,188 @@ iterations of the loop. .. opcode:: RESUME (where) - A no-op. Performs internal tracing, debugging and optimization checks. + A no-op. Performs internal tracing, debugging and optimization checks. - The ``where`` operand marks where the ``RESUME`` occurs: + The ``where`` operand marks where the ``RESUME`` occurs: - * ``0`` The start of a function - * ``1`` After a ``yield`` expression - * ``2`` After a ``yield from`` expression - * ``3`` After an ``await`` expression + * ``0`` The start of a function, which is neither a generator, coroutine + nor an async generator + * ``1`` After a ``yield`` expression + * ``2`` After a ``yield from`` expression + * ``3`` After an ``await`` expression .. versionadded:: 3.11 .. opcode:: RETURN_GENERATOR - Create a generator, coroutine, or async generator from the current frame. - Clear the current frame and return the newly created generator. - - .. versionadded:: 3.11 - - -.. opcode:: SEND + Create a generator, coroutine, or async generator from the current frame. + Used as first opcode of in code object for the above mentioned callables. + Clear the current frame and return the newly created generator. - Sends ``None`` to the sub-generator of this generator. - Used in ``yield from`` and ``await`` statements. + .. versionadded:: 3.11 - .. versionadded:: 3.11 +.. opcode:: SEND (delta) -.. opcode:: ASYNC_GEN_WRAP + Equivalent to ``STACK[-1] = STACK[-2].send(STACK[-1])``. Used in ``yield from`` + and ``await`` statements. - Wraps the value on top of the stack in an ``async_generator_wrapped_value``. - Used to yield in async generators. + If the call raises :exc:`StopIteration`, pop both items, push the + exception's ``value`` attribute, and increment the bytecode counter by + *delta*. - .. versionadded:: 3.11 + .. versionadded:: 3.11 .. opcode:: HAVE_ARGUMENT This is not really an opcode. It identifies the dividing line between - opcodes which don't use their argument and those that do - (``< HAVE_ARGUMENT`` and ``>= HAVE_ARGUMENT``, respectively). + opcodes in the range [0,255] which don't use their argument and those + that do (``< HAVE_ARGUMENT`` and ``>= HAVE_ARGUMENT``, respectively). + + If your application uses pseudo instructions, use the :data:`hasarg` + collection instead. .. versionchanged:: 3.6 Now every instruction has an argument, but opcodes ``< HAVE_ARGUMENT`` ignore it. Before, only opcodes ``>= HAVE_ARGUMENT`` had an argument. + .. versionchanged:: 3.12 + Pseudo instructions were added to the :mod:`dis` module, and for them + it is not true that comparison with ``HAVE_ARGUMENT`` indicates whether + they use their arg. + + +.. opcode:: CALL_INTRINSIC_1 + + Calls an intrinsic function with one argument. Passes ``STACK[-1]`` as the + argument and sets ``STACK[-1]`` to the result. Used to implement + functionality that is necessary but not performance critical. + + The operand determines which intrinsic function is called: + + +-----------------------------------+-----------------------------------+ + | Operand | Description | + +===================================+===================================+ + | ``INTRINSIC_1_INVALID`` | Not valid | + +-----------------------------------+-----------------------------------+ + | ``INTRINSIC_PRINT`` | Prints the argument to standard | + | | out. Used in the REPL. | + +-----------------------------------+-----------------------------------+ + | ``INTRINSIC_IMPORT_STAR`` | Performs ``import *`` for the | + | | named module. | + +-----------------------------------+-----------------------------------+ + | ``INTRINSIC_STOPITERATION_ERROR`` | Extracts the return value from a | + | | ``StopIteration`` exception. | + +-----------------------------------+-----------------------------------+ + | ``INTRINSIC_ASYNC_GEN_WRAP`` | Wraps an aync generator value | + +-----------------------------------+-----------------------------------+ + | ``INTRINSIC_UNARY_POSITIVE`` | Performs the unary ``+`` | + | | operation | + +-----------------------------------+-----------------------------------+ + | ``INTRINSIC_LIST_TO_TUPLE`` | Converts a list to a tuple | + +-----------------------------------+-----------------------------------+ + | ``INTRINSIC_TYPEVAR`` | Creates a :class:`typing.TypeVar` | + +-----------------------------------+-----------------------------------+ + | ``INTRINSIC_PARAMSPEC`` | Creates a | + | | :class:`typing.ParamSpec` | + +-----------------------------------+-----------------------------------+ + | ``INTRINSIC_TYPEVARTUPLE`` | Creates a | + | | :class:`typing.TypeVarTuple` | + +-----------------------------------+-----------------------------------+ + | ``INTRINSIC_SUBSCRIPT_GENERIC`` | Returns :class:`typing.Generic` | + | | subscripted with the argument | + +-----------------------------------+-----------------------------------+ + | ``INTRINSIC_TYPEALIAS`` | Creates a | + | | :class:`typing.TypeAliasType`; | + | | used in the :keyword:`type` | + | | statement. The argument is a tuple| + | | of the type alias's name, | + | | type parameters, and value. | + +-----------------------------------+-----------------------------------+ + + .. versionadded:: 3.12 + +.. opcode:: CALL_INTRINSIC_2 + + Calls an intrinsic function with two arguments. Passes ``STACK[-2]``, ``STACK[-1]`` as the + arguments and sets ``STACK[-1]`` to the result. Used to implement functionality that is + necessary but not performance critical. + + The operand determines which intrinsic function is called: + + +----------------------------------------+-----------------------------------+ + | Operand | Description | + +========================================+===================================+ + | ``INTRINSIC_2_INVALID`` | Not valid | + +----------------------------------------+-----------------------------------+ + | ``INTRINSIC_PREP_RERAISE_STAR`` | Calculates the | + | | :exc:`ExceptionGroup` to raise | + | | from a ``try-except*``. | + +----------------------------------------+-----------------------------------+ + | ``INTRINSIC_TYPEVAR_WITH_BOUND`` | Creates a :class:`typing.TypeVar` | + | | with a bound. | + +----------------------------------------+-----------------------------------+ + | ``INTRINSIC_TYPEVAR_WITH_CONSTRAINTS`` | Creates a | + | | :class:`typing.TypeVar` with | + | | constraints. | + +----------------------------------------+-----------------------------------+ + | ``INTRINSIC_SET_FUNCTION_TYPE_PARAMS`` | Sets the ``__type_params__`` | + | | attribute of a function. | + +----------------------------------------+-----------------------------------+ + + .. versionadded:: 3.12 + + +**Pseudo-instructions** + +These opcodes do not appear in Python bytecode. They are used by the compiler +but are replaced by real opcodes or removed before bytecode is generated. + +.. opcode:: SETUP_FINALLY (target) + + Set up an exception handler for the following code block. If an exception + occurs, the value stack level is restored to its current state and control + is transferred to the exception handler at ``target``. + + +.. opcode:: SETUP_CLEANUP (target) + + Like ``SETUP_FINALLY``, but in case of an exception also pushes the last + instruction (``lasti``) to the stack so that ``RERAISE`` can restore it. + If an exception occurs, the value stack level and the last instruction on + the frame are restored to their current state, and control is transferred + to the exception handler at ``target``. + + +.. opcode:: SETUP_WITH (target) + + Like ``SETUP_CLEANUP``, but in case of an exception one more item is popped + from the stack before control is transferred to the exception handler at + ``target``. + + This variant is used in :keyword:`with` and :keyword:`async with` + constructs, which push the return value of the context manager's + :meth:`~object.__enter__` or :meth:`~object.__aenter__` to the stack. + + +.. opcode:: POP_BLOCK + + Marks the end of the code block associated with the last ``SETUP_FINALLY``, + ``SETUP_CLEANUP`` or ``SETUP_WITH``. + +.. opcode:: JUMP +.. opcode:: JUMP_NO_INTERRUPT + + Undirected relative jump instructions which are replaced by their + directed (forward/backward) counterparts by the assembler. + +.. opcode:: LOAD_METHOD + + Optimized unbound method lookup. Emitted as a ``LOAD_ATTR`` opcode + with a flag set in the arg. + .. _opcode_collections: @@ -1379,6 +1662,10 @@ Opcode collections These collections are provided for automatic introspection of bytecode instructions: +.. versionchanged:: 3.12 + The collections now contain pseudo instructions as well. These are + opcodes with values ``>= MIN_PSEUDO_OPCODE``. + .. data:: opname Sequence of operation names, indexable using the bytecode. @@ -1394,6 +1681,13 @@ instructions: Sequence of all compare operation names. +.. data:: hasarg + + Sequence of bytecodes that use their argument. + + .. versionadded:: 3.12 + + .. data:: hasconst Sequence of bytecodes that access a constant. @@ -1401,10 +1695,10 @@ instructions: .. data:: hasfree - Sequence of bytecodes that access a free variable (note that 'free' in this + Sequence of bytecodes that access a free variable. 'free' in this context refers to names in the current scope that are referenced by inner scopes or names in outer scopes that are referenced from this scope. It does - *not* include references to global or builtin scopes). + *not* include references to global or builtin scopes. .. data:: hasname @@ -1430,3 +1724,9 @@ instructions: .. data:: hascompare Sequence of bytecodes of Boolean operations. + +.. data:: hasexc + + Sequence of bytecodes that set an exception handler. + + .. versionadded:: 3.12 diff --git a/Doc/library/distribution.rst b/Doc/library/distribution.rst index 8d4befe4..bec1ca3c 100644 --- a/Doc/library/distribution.rst +++ b/Doc/library/distribution.rst @@ -9,7 +9,6 @@ with a local index server, or without any index server at all. .. toctree:: - distutils.rst ensurepip.rst venv.rst zipapp.rst diff --git a/Doc/library/distutils.rst b/Doc/library/distutils.rst deleted file mode 100644 index 31c4ae5b..00000000 --- a/Doc/library/distutils.rst +++ /dev/null @@ -1,49 +0,0 @@ -:mod:`distutils` --- Building and installing Python modules -=========================================================== - -.. module:: distutils - :synopsis: Support for building and installing Python modules into an - existing Python installation. - -.. sectionauthor:: Fred L. Drake, Jr. <fdrake@acm.org> - --------------- - -:mod:`distutils` is deprecated with removal planned for Python 3.12. -See the :ref:`What's New <distutils-deprecated>` entry for more information. - --------------- - -The :mod:`distutils` package provides support for building and installing -additional modules into a Python installation. The new modules may be either -100%-pure Python, or may be extension modules written in C, or may be -collections of Python packages which include modules coded in both Python and C. - -Most Python users will *not* want to use this module directly, but instead -use the cross-version tools maintained by the Python Packaging Authority. In -particular, -`setuptools <https://setuptools.readthedocs.io/en/latest/>`__ is an -enhanced alternative to :mod:`distutils` that provides: - -* support for declaring project dependencies -* additional mechanisms for configuring which files to include in source - releases (including plugins for integration with version control systems) -* the ability to declare project "entry points", which can be used as the - basis for application plugin systems -* the ability to automatically generate Windows command line executables at - installation time rather than needing to prebuild them -* consistent behaviour across all supported Python versions - -The recommended `pip <https://pip.pypa.io/>`__ installer runs all -``setup.py`` scripts with ``setuptools``, even if the script itself only -imports ``distutils``. Refer to the -`Python Packaging User Guide <https://packaging.python.org>`_ for more -information. - -For the benefits of packaging tool authors and users seeking a deeper -understanding of the details of the current packaging and distribution -system, the legacy :mod:`distutils` based user documentation and API -reference remain available: - -* :ref:`install-index` -* :ref:`distutils-index` diff --git a/Doc/library/doctest.rst b/Doc/library/doctest.rst index c106d5a3..d6e4dca0 100644 --- a/Doc/library/doctest.rst +++ b/Doc/library/doctest.rst @@ -351,6 +351,7 @@ The fine print: >>> def f(x): ... r'''Backslashes in a raw docstring: m\n''' + ... >>> print(f.__doc__) Backslashes in a raw docstring: m\n @@ -360,6 +361,7 @@ The fine print: >>> def f(x): ... '''Backslashes in a raw docstring: m\\n''' + ... >>> print(f.__doc__) Backslashes in a raw docstring: m\n @@ -1055,7 +1057,7 @@ from text files and modules with doctests: from a text file using :func:`DocFileSuite`. -.. function:: DocTestSuite(module=None, globs=None, extraglobs=None, test_finder=None, setUp=None, tearDown=None, checker=None) +.. function:: DocTestSuite(module=None, globs=None, extraglobs=None, test_finder=None, setUp=None, tearDown=None, optionflags=0, checker=None) Convert doctest tests for a module to a :class:`unittest.TestSuite`. diff --git a/Doc/library/email.charset.rst b/Doc/library/email.charset.rst index 38fda23b..aa013441 100644 --- a/Doc/library/email.charset.rst +++ b/Doc/library/email.charset.rst @@ -58,9 +58,9 @@ Import this class from the :mod:`email.charset` module. .. attribute:: header_encoding If the character set must be encoded before it can be used in an email - header, this attribute will be set to ``Charset.QP`` (for - quoted-printable), ``Charset.BASE64`` (for base64 encoding), or - ``Charset.SHORTEST`` for the shortest of QP or BASE64 encoding. Otherwise, + header, this attribute will be set to ``charset.QP`` (for + quoted-printable), ``charset.BASE64`` (for base64 encoding), or + ``charset.SHORTEST`` for the shortest of QP or BASE64 encoding. Otherwise, it will be ``None``. @@ -68,7 +68,7 @@ Import this class from the :mod:`email.charset` module. Same as *header_encoding*, but describes the encoding for the mail message's body, which indeed may be different than the header encoding. - ``Charset.SHORTEST`` is not allowed for *body_encoding*. + ``charset.SHORTEST`` is not allowed for *body_encoding*. .. attribute:: output_charset @@ -150,7 +150,7 @@ Import this class from the :mod:`email.charset` module. .. method:: __str__() Returns *input_charset* as a string coerced to lower - case. :meth:`__repr__` is an alias for :meth:`__str__`. + case. :meth:`!__repr__` is an alias for :meth:`!__str__`. .. method:: __eq__(other) @@ -175,9 +175,9 @@ new entries to the global character set, alias, and codec registries: *charset* is the input character set, and must be the canonical name of a character set. - Optional *header_enc* and *body_enc* is either ``Charset.QP`` for - quoted-printable, ``Charset.BASE64`` for base64 encoding, - ``Charset.SHORTEST`` for the shortest of quoted-printable or base64 encoding, + Optional *header_enc* and *body_enc* is either ``charset.QP`` for + quoted-printable, ``charset.BASE64`` for base64 encoding, + ``charset.SHORTEST`` for the shortest of quoted-printable or base64 encoding, or ``None`` for no encoding. ``SHORTEST`` is only valid for *header_enc*. The default is ``None`` for no encoding. diff --git a/Doc/library/email.encoders.rst b/Doc/library/email.encoders.rst index 5d68b104..3bd377e3 100644 --- a/Doc/library/email.encoders.rst +++ b/Doc/library/email.encoders.rst @@ -25,7 +25,7 @@ is especially true for :mimetype:`image/\*` and :mimetype:`text/\*` type message containing binary data. The :mod:`email` package provides some convenient encoders in its -:mod:`encoders` module. These encoders are actually used by the +:mod:`~email.encoders` module. These encoders are actually used by the :class:`~email.mime.audio.MIMEAudio` and :class:`~email.mime.image.MIMEImage` class constructors to provide default encodings. All encoder functions take exactly one argument, the message object to encode. They usually extract the diff --git a/Doc/library/email.generator.rst b/Doc/library/email.generator.rst index 34ad7b7f..91d9d69a 100644 --- a/Doc/library/email.generator.rst +++ b/Doc/library/email.generator.rst @@ -274,9 +274,9 @@ in with information about the part. .. rubric:: Footnotes .. [#] This statement assumes that you use the appropriate setting for - ``unixfrom``, and that there are no :mod:`policy` settings calling for + ``unixfrom``, and that there are no :mod:`email.policy` settings calling for automatic adjustments (for example, - :attr:`~email.policy.Policy.refold_source` must be ``none``, which is + :attr:`~email.policy.EmailPolicy.refold_source` must be ``none``, which is *not* the default). It is also not 100% true, since if the message does not conform to the RFC standards occasionally information about the exact original text is lost during parsing error recovery. It is a goal diff --git a/Doc/library/email.message.rst b/Doc/library/email.message.rst index 5e0509f4..225f4987 100644 --- a/Doc/library/email.message.rst +++ b/Doc/library/email.message.rst @@ -67,7 +67,7 @@ message objects. with the base :class:`~email.message.Message` class *maxheaderlen* is accepted, but defaults to ``None``, which means that by default the line length is controlled by the - :attr:`~email.policy.EmailPolicy.max_line_length` of the policy. The + :attr:`~email.policy.Policy.max_line_length` of the policy. The *policy* argument may be used to override the default policy obtained from the message instance. This can be used to control some of the formatting produced by the method, since the specified *policy* will be @@ -213,7 +213,7 @@ message objects. del msg['subject'] msg['subject'] = 'Python roolz!' - If the :mod:`policy` defines certain headers to be unique (as the standard + If the :mod:`policy <email.policy>` defines certain headers to be unique (as the standard policies do), this method may raise a :exc:`ValueError` when an attempt is made to assign a value to such a header when one already exists. This behavior is intentional for consistency's sake, but do not depend on it @@ -378,7 +378,7 @@ message objects. deprecated. Note that existing parameter values of headers may be accessed through - the :attr:`~email.headerregistry.BaseHeader.params` attribute of the + the :attr:`~email.headerregistry.ParameterizedMIMEHeader.params` attribute of the header value (for example, ``msg['Content-Type'].params['charset']``). .. versionchanged:: 3.4 ``replace`` keyword was added. @@ -691,7 +691,7 @@ message objects. .. method:: clear_content() - Remove the payload and all of the :exc:`Content-` headers, leaving + Remove the payload and all of the :mailheader:`!Content-` headers, leaving all other headers intact and in their original order. diff --git a/Doc/library/email.parser.rst b/Doc/library/email.parser.rst index d9a61616..dda0466a 100644 --- a/Doc/library/email.parser.rst +++ b/Doc/library/email.parser.rst @@ -39,9 +39,9 @@ returns the root object when you close the parser. Note that the parser can be extended in limited ways, and of course you can implement your own parser completely from scratch. All of the logic that connects the :mod:`email` package's bundled parser and the -:class:`~email.message.EmailMessage` class is embodied in the :mod:`policy` +:class:`~email.message.EmailMessage` class is embodied in the :class:`~email.policy.Policy` class, so a custom parser can create message object trees any way it finds -necessary by implementing custom versions of the appropriate :mod:`policy` +necessary by implementing custom versions of the appropriate :class:`!Policy` methods. diff --git a/Doc/library/email.policy.rst b/Doc/library/email.policy.rst index bf53b952..2439dee6 100644 --- a/Doc/library/email.policy.rst +++ b/Doc/library/email.policy.rst @@ -97,6 +97,7 @@ file on disk and pass it to the system ``sendmail`` program on a Unix system: >>> from subprocess import Popen, PIPE >>> with open('mymsg.txt', 'rb') as f: ... msg = message_from_binary_file(f, policy=policy.default) + ... >>> p = Popen(['sendmail', msg['To'].addresses[0]], stdin=PIPE) >>> g = BytesGenerator(p.stdin, policy=msg.policy.clone(linesep='\r\n')) >>> g.flatten(msg) diff --git a/Doc/library/email.rst b/Doc/library/email.rst index 5eebcd9e..816fae99 100644 --- a/Doc/library/email.rst +++ b/Doc/library/email.rst @@ -147,6 +147,3 @@ Legacy API: Module :mod:`mailbox` Tools for creating, reading, and managing collections of messages on disk using a variety standard formats. - - Module :mod:`smtpd` - SMTP server framework (primarily useful for testing) diff --git a/Doc/library/email.utils.rst b/Doc/library/email.utils.rst index 0e266b6a..345b6400 100644 --- a/Doc/library/email.utils.rst +++ b/Doc/library/email.utils.rst @@ -13,19 +13,17 @@ module: .. function:: localtime(dt=None) - Return local time as an aware datetime object. If called without - arguments, return current time. Otherwise *dt* argument should be a - :class:`~datetime.datetime` instance, and it is converted to the local time - zone according to the system time zone database. If *dt* is naive (that - is, ``dt.tzinfo`` is ``None``), it is assumed to be in local time. In this - case, a positive or zero value for *isdst* causes ``localtime`` to presume - initially that summer time (for example, Daylight Saving Time) is or is not - (respectively) in effect for the specified time. A negative value for - *isdst* causes the ``localtime`` to attempt to divine whether summer time - is in effect for the specified time. - - .. versionadded:: 3.3 + Return local time as an aware datetime object. If called without + arguments, return current time. Otherwise *dt* argument should be a + :class:`~datetime.datetime` instance, and it is converted to the local time + zone according to the system time zone database. If *dt* is naive (that + is, ``dt.tzinfo`` is ``None``), it is assumed to be in local time. The + *isdst* parameter is ignored. + .. versionadded:: 3.3 + + .. deprecated-removed:: 3.12 3.14 + The *isdst* parameter. .. function:: make_msgid(idstring=None, domain=None) diff --git a/Doc/library/ensurepip.rst b/Doc/library/ensurepip.rst index d7f89cf9..de3b93f5 100644 --- a/Doc/library/ensurepip.rst +++ b/Doc/library/ensurepip.rst @@ -61,7 +61,7 @@ By default, ``pip`` is installed into the current virtual environment active virtual environment). The installation location can be controlled through two additional command line options: -* ``--root <dir>``: Installs ``pip`` relative to the given root directory +* :samp:`--root {dir}`: Installs ``pip`` relative to the given root directory rather than the root of the currently active virtual environment (if any) or the default root for the current Python installation. * ``--user``: Installs ``pip`` into the user site packages directory rather diff --git a/Doc/library/enum.rst b/Doc/library/enum.rst index 1973578e..7653865f 100644 --- a/Doc/library/enum.rst +++ b/Doc/library/enum.rst @@ -119,7 +119,8 @@ Module Contents :func:`~enum.property` Allows :class:`Enum` members to have attributes without conflicting with - member names. + member names. The ``value`` and ``name`` attributes are implemented this + way. :func:`unique` @@ -141,9 +142,8 @@ Module Contents :func:`global_enum` Modify the :class:`str() <str>` and :func:`repr` of an enum - to show its members as belonging to the module instead of its class. - Should only be used if the enum members will be exported to the - module global namespace. + to show its members as belonging to the module instead of its class, + and export the enum members to the global namespace. :func:`show_flag_values` @@ -170,6 +170,27 @@ Data Types final *enum*, as well as creating the enum members, properly handling duplicates, providing iteration over the enum class, etc. + .. method:: EnumType.__call__(cls, value, names=None, \*, module=None, qualname=None, type=None, start=1, boundary=None) + + This method is called in two different ways: + + * to look up an existing member: + + :cls: The enum class being called. + :value: The value to lookup. + + * to use the ``cls`` enum to create a new enum (only if the existing enum + does not have any members): + + :cls: The enum class being called. + :value: The name of the new Enum to create. + :names: The names/values of the members for the new Enum. + :module: The name of the module the new Enum is created in. + :qualname: The actual location in the module where this Enum can be found. + :type: A mix-in type for the new Enum. + :start: The first integer value for the Enum (used by :class:`auto`). + :boundary: How to handle out-of-range values from bit operations (:class:`Flag` only). + .. method:: EnumType.__contains__(cls, member) Returns ``True`` if member belongs to the ``cls``:: @@ -192,13 +213,6 @@ Data Types >>> dir(Color) ['BLUE', 'GREEN', 'RED', '__class__', '__contains__', '__doc__', '__getitem__', '__init_subclass__', '__iter__', '__len__', '__members__', '__module__', '__name__', '__qualname__'] - .. method:: EnumType.__getattr__(cls, name) - - Returns the Enum member in *cls* matching *name*, or raises an :exc:`AttributeError`:: - - >>> Color.GREEN - <Color.GREEN: 2> - .. method:: EnumType.__getitem__(cls, name) Returns the Enum member in *cls* matching *name*, or raises a :exc:`KeyError`:: @@ -227,6 +241,10 @@ Data Types >>> list(reversed(Color)) [<Color.BLUE: 3>, <Color.GREEN: 2>, <Color.RED: 1>] + .. versionadded:: 3.11 + + Before 3.11 ``enum`` used ``EnumMeta`` type, which is kept as an alias. + .. class:: Enum @@ -262,26 +280,6 @@ Data Types names will also be removed from the completed enumeration. See :ref:`TimePeriod <enum-time-period>` for an example. - .. method:: Enum.__call__(cls, value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None) - - This method is called in two different ways: - - * to look up an existing member: - - :cls: The enum class being called. - :value: The value to lookup. - - * to use the ``cls`` enum to create a new enum: - - :cls: The enum class being called. - :value: The name of the new Enum to create. - :names: The names/values of the members for the new Enum. - :module: The name of the module the new Enum is created in. - :qualname: The actual location in the module where this Enum can be found. - :type: A mix-in type for the new Enum. - :start: The first integer value for the Enum (used by :class:`auto`). - :boundary: How to handle out-of-range values from bit operations (:class:`Flag` only). - .. method:: Enum.__dir__(self) Returns ``['__class__', '__doc__', '__module__', 'name', 'value']`` and @@ -299,6 +297,7 @@ Data Types ... @classmethod ... def today(cls): ... print('today is %s' % cls(date.today().isoweekday()).name) + ... >>> dir(Weekday.SATURDAY) ['__class__', '__doc__', '__eq__', '__hash__', '__module__', 'name', 'today', 'value'] @@ -319,10 +318,11 @@ Data Types ... return 3 ** (count + 1) ... FIRST = auto() ... SECOND = auto() + ... >>> PowersOfThree.SECOND.value 9 - .. method:: Enum.__init_subclass__(cls, **kwds) + .. method:: Enum.__init_subclass__(cls, \**kwds) A *classmethod* that is used to further configure subsequent subclasses. By default, does nothing. @@ -343,6 +343,7 @@ Data Types ... if member.value == value: ... return member ... return None + ... >>> Build.DEBUG.value 'debug' >>> Build('deBUG') @@ -360,6 +361,7 @@ Data Types ... def __repr__(self): ... cls_name = self.__class__.__name__ ... return f'{cls_name}.{self.name}' + ... >>> OtherStyle.ALTERNATE, str(OtherStyle.ALTERNATE), f"{OtherStyle.ALTERNATE}" (OtherStyle.ALTERNATE, 'OtherStyle.ALTERNATE', 'OtherStyle.ALTERNATE') @@ -374,6 +376,7 @@ Data Types ... SOMETHING_ELSE = auto() ... def __str__(self): ... return f'{self.name}' + ... >>> OtherStyle.ALTERNATE, str(OtherStyle.ALTERNATE), f"{OtherStyle.ALTERNATE}" (<OtherStyle.ALTERNATE: 1>, 'ALTERNATE', 'ALTERNATE') @@ -388,6 +391,7 @@ Data Types ... SOMETHING_ELSE = auto() ... def __format__(self, spec): ... return f'{self.name}' + ... >>> OtherStyle.ALTERNATE, str(OtherStyle.ALTERNATE), f"{OtherStyle.ALTERNATE}" (<OtherStyle.ALTERNATE: 1>, 'OtherStyle.ALTERNATE', 'ALTERNATE') @@ -396,6 +400,8 @@ Data Types Using :class:`auto` with :class:`Enum` results in integers of increasing value, starting with ``1``. + .. versionchanged:: 3.12 Added :ref:`enum-dataclass-support` + .. class:: IntEnum @@ -404,17 +410,18 @@ Data Types with an *IntEnum* member, the resulting value loses its enumeration status. >>> from enum import IntEnum - >>> class Numbers(IntEnum): + >>> class Number(IntEnum): ... ONE = 1 ... TWO = 2 ... THREE = 3 - >>> Numbers.THREE - <Numbers.THREE: 3> - >>> Numbers.ONE + Numbers.TWO + ... + >>> Number.THREE + <Number.THREE: 3> + >>> Number.ONE + Number.TWO 3 - >>> Numbers.THREE + 5 + >>> Number.THREE + 5 8 - >>> Numbers.THREE == 3 + >>> Number.THREE == 3 True .. note:: @@ -468,6 +475,7 @@ Data Types ... RED = auto() ... GREEN = auto() ... BLUE = auto() + ... >>> purple = Color.RED | Color.BLUE >>> white = Color.RED | Color.GREEN | Color.BLUE >>> Color.GREEN in purple @@ -575,6 +583,7 @@ Data Types ... RED = auto() ... GREEN = auto() ... BLUE = auto() + ... >>> Color.RED & 2 <Color: 0> >>> Color.RED | 2 @@ -692,14 +701,15 @@ Data Types .. attribute:: STRICT - Out-of-range values cause a :exc:`ValueError` to be raised. This is the + Out-of-range values cause a :exc:`ValueError` to be raised. This is the default for :class:`Flag`:: - >>> from enum import Flag, STRICT + >>> from enum import Flag, STRICT, auto >>> class StrictFlag(Flag, boundary=STRICT): ... RED = auto() ... GREEN = auto() ... BLUE = auto() + ... >>> StrictFlag(2**2 + 2**4) Traceback (most recent call last): ... @@ -712,37 +722,39 @@ Data Types Out-of-range values have invalid values removed, leaving a valid *Flag* value:: - >>> from enum import Flag, CONFORM + >>> from enum import Flag, CONFORM, auto >>> class ConformFlag(Flag, boundary=CONFORM): ... RED = auto() ... GREEN = auto() ... BLUE = auto() + ... >>> ConformFlag(2**2 + 2**4) <ConformFlag.BLUE: 4> .. attribute:: EJECT Out-of-range values lose their *Flag* membership and revert to :class:`int`. - This is the default for :class:`IntFlag`:: - >>> from enum import Flag, EJECT + >>> from enum import Flag, EJECT, auto >>> class EjectFlag(Flag, boundary=EJECT): ... RED = auto() ... GREEN = auto() ... BLUE = auto() + ... >>> EjectFlag(2**2 + 2**4) 20 .. attribute:: KEEP - Out-of-range values are kept, and the *Flag* membership is kept. This is - used for some stdlib flags: + Out-of-range values are kept, and the *Flag* membership is kept. + This is the default for :class:`IntFlag`:: - >>> from enum import Flag, KEEP + >>> from enum import Flag, KEEP, auto >>> class KeepFlag(Flag, boundary=KEEP): ... RED = auto() ... GREEN = auto() ... BLUE = auto() + ... >>> KeepFlag(2**2 + 2**4) <KeepFlag.BLUE|16: 20> diff --git a/Doc/library/errno.rst b/Doc/library/errno.rst index 5122c696..283e8b01 100644 --- a/Doc/library/errno.rst +++ b/Doc/library/errno.rst @@ -511,6 +511,13 @@ defined by the module. The specific list of defined symbols is available as Operation not supported on transport endpoint +.. data:: ENOTSUP + + Operation not supported + + .. versionadded:: 3.2 + + .. data:: EPFNOSUPPORT Protocol family not supported @@ -666,3 +673,24 @@ defined by the module. The specific list of defined symbols is available as .. availability:: WASI, FreeBSD .. versionadded:: 3.11.1 + + +.. data:: ECANCELED + + Operation canceled + + .. versionadded:: 3.2 + + +.. data:: EOWNERDEAD + + Owner died + + .. versionadded:: 3.2 + + +.. data:: ENOTRECOVERABLE + + State not recoverable + + .. versionadded:: 3.2 diff --git a/Doc/library/exceptions.rst b/Doc/library/exceptions.rst index 1217b817..d210f82f 100644 --- a/Doc/library/exceptions.rst +++ b/Doc/library/exceptions.rst @@ -4,8 +4,8 @@ Built-in Exceptions =================== .. index:: - statement: try - statement: except + pair: statement; try + pair: statement; except In Python, all exceptions must be instances of a class that derives from :class:`BaseException`. In a :keyword:`try` statement with an :keyword:`except` @@ -14,7 +14,7 @@ classes derived from that class (but not exception classes from which *it* is derived). Two exception classes that are not related via subclassing are never equivalent, even if they have the same name. -.. index:: statement: raise +.. index:: pair: statement; raise The built-in exceptions listed below can be generated by the interpreter or built-in functions. Except where mentioned, they have an "associated value" @@ -123,7 +123,7 @@ The following exceptions are used mostly as base classes for other exceptions. try: ... except SomeException: - tb = sys.exc_info()[2] + tb = sys.exception().__traceback__ raise OtherException(...).with_traceback(tb) .. method:: add_note(note) @@ -175,7 +175,7 @@ The following exceptions are the exceptions that are usually raised. .. exception:: AssertionError - .. index:: statement: assert + .. index:: pair: statement; assert Raised when an :keyword:`assert` statement fails. @@ -220,10 +220,16 @@ The following exceptions are the exceptions that are usually raised. load a module. Also raised when the "from list" in ``from ... import`` has a name that cannot be found. - The :attr:`name` and :attr:`path` attributes can be set using keyword-only - arguments to the constructor. When set they represent the name of the module - that was attempted to be imported and the path to any file which triggered - the exception, respectively. + The optional *name* and *path* keyword-only arguments + set the corresponding attributes: + + .. attribute:: name + + The name of the module that was attempted to be imported. + + .. attribute:: path + + The path to any file which triggered the exception. .. versionchanged:: 3.3 Added the :attr:`name` and :attr:`path` attributes. @@ -318,7 +324,7 @@ The following exceptions are the exceptions that are usually raised. .. exception:: OSError([arg]) OSError(errno, strerror[, filename[, winerror[, filename2]]]) - .. index:: module: errno + .. index:: pair: module; errno This exception is raised when a system function returns a system-related error, including I/O failures such as "file not found" or "disk full" @@ -450,7 +456,7 @@ The following exceptions are the exceptions that are usually raised. .. exception:: StopAsyncIteration - Must be raised by :meth:`__anext__` method of an + Must be raised by :meth:`~object.__anext__` method of an :term:`asynchronous iterator` object to stop the iteration. .. versionadded:: 3.5 @@ -659,8 +665,8 @@ depending on the system error code. Raised when an operation would block on an object (e.g. socket) set for non-blocking operation. - Corresponds to :c:data:`errno` :py:data:`~errno.EAGAIN`, :py:data:`~errno.EALREADY`, - :py:data:`~errno.EWOULDBLOCK` and :py:data:`~errno.EINPROGRESS`. + Corresponds to :c:data:`errno` :py:const:`~errno.EAGAIN`, :py:const:`~errno.EALREADY`, + :py:const:`~errno.EWOULDBLOCK` and :py:const:`~errno.EINPROGRESS`. In addition to those of :exc:`OSError`, :exc:`BlockingIOError` can have one more attribute: @@ -674,7 +680,7 @@ depending on the system error code. .. exception:: ChildProcessError Raised when an operation on a child process failed. - Corresponds to :c:data:`errno` :py:data:`~errno.ECHILD`. + Corresponds to :c:data:`errno` :py:const:`~errno.ECHILD`. .. exception:: ConnectionError @@ -688,40 +694,40 @@ depending on the system error code. A subclass of :exc:`ConnectionError`, raised when trying to write on a pipe while the other end has been closed, or trying to write on a socket which has been shutdown for writing. - Corresponds to :c:data:`errno` :py:data:`~errno.EPIPE` and :py:data:`~errno.ESHUTDOWN`. + Corresponds to :c:data:`errno` :py:const:`~errno.EPIPE` and :py:const:`~errno.ESHUTDOWN`. .. exception:: ConnectionAbortedError A subclass of :exc:`ConnectionError`, raised when a connection attempt is aborted by the peer. - Corresponds to :c:data:`errno` :py:data:`~errno.ECONNABORTED`. + Corresponds to :c:data:`errno` :py:const:`~errno.ECONNABORTED`. .. exception:: ConnectionRefusedError A subclass of :exc:`ConnectionError`, raised when a connection attempt is refused by the peer. - Corresponds to :c:data:`errno` :py:data:`~errno.ECONNREFUSED`. + Corresponds to :c:data:`errno` :py:const:`~errno.ECONNREFUSED`. .. exception:: ConnectionResetError A subclass of :exc:`ConnectionError`, raised when a connection is reset by the peer. - Corresponds to :c:data:`errno` :py:data:`~errno.ECONNRESET`. + Corresponds to :c:data:`errno` :py:const:`~errno.ECONNRESET`. .. exception:: FileExistsError Raised when trying to create a file or directory which already exists. - Corresponds to :c:data:`errno` :py:data:`~errno.EEXIST`. + Corresponds to :c:data:`errno` :py:const:`~errno.EEXIST`. .. exception:: FileNotFoundError Raised when a file or directory is requested but doesn't exist. - Corresponds to :c:data:`errno` :py:data:`~errno.ENOENT`. + Corresponds to :c:data:`errno` :py:const:`~errno.ENOENT`. .. exception:: InterruptedError Raised when a system call is interrupted by an incoming signal. - Corresponds to :c:data:`errno` :py:data:`~errno.EINTR`. + Corresponds to :c:data:`errno` :py:const:`~errno.EINTR`. .. versionchanged:: 3.5 Python now retries system calls when a syscall is interrupted by a @@ -732,7 +738,7 @@ depending on the system error code. Raised when a file operation (such as :func:`os.remove`) is requested on a directory. - Corresponds to :c:data:`errno` :py:data:`~errno.EISDIR`. + Corresponds to :c:data:`errno` :py:const:`~errno.EISDIR`. .. exception:: NotADirectoryError @@ -740,28 +746,28 @@ depending on the system error code. something which is not a directory. On most POSIX platforms, it may also be raised if an operation attempts to open or traverse a non-directory file as if it were a directory. - Corresponds to :c:data:`errno` :py:data:`~errno.ENOTDIR`. + Corresponds to :c:data:`errno` :py:const:`~errno.ENOTDIR`. .. exception:: PermissionError Raised when trying to run an operation without the adequate access rights - for example filesystem permissions. - Corresponds to :c:data:`errno` :py:data:`~errno.EACCES`, - :py:data:`~errno.EPERM`, and :py:data:`~errno.ENOTCAPABLE`. + Corresponds to :c:data:`errno` :py:const:`~errno.EACCES`, + :py:const:`~errno.EPERM`, and :py:const:`~errno.ENOTCAPABLE`. .. versionchanged:: 3.11.1 - WASI's :py:data:`~errno.ENOTCAPABLE` is now mapped to + WASI's :py:const:`~errno.ENOTCAPABLE` is now mapped to :exc:`PermissionError`. .. exception:: ProcessLookupError Raised when a given process doesn't exist. - Corresponds to :c:data:`errno` :py:data:`~errno.ESRCH`. + Corresponds to :c:data:`errno` :py:const:`~errno.ESRCH`. .. exception:: TimeoutError Raised when a system function timed out at the system level. - Corresponds to :c:data:`errno` :py:data:`~errno.ETIMEDOUT`. + Corresponds to :c:data:`errno` :py:const:`~errno.ETIMEDOUT`. .. versionadded:: 3.3 All the above :exc:`OSError` subclasses were added. @@ -871,6 +877,8 @@ The following exceptions are used as warning categories; see the .. versionadded:: 3.2 +.. _lib-exception-groups: + Exception groups ---------------- @@ -948,8 +956,8 @@ their subgroups based on the types of the contained exceptions. these fields do not need to be updated by :meth:`derive`. :: >>> class MyGroup(ExceptionGroup): - ... def derive(self, exc): - ... return MyGroup(self.message, exc) + ... def derive(self, excs): + ... return MyGroup(self.message, excs) ... >>> e = MyGroup("eg", [ValueError(1), TypeError(2)]) >>> e.add_note("a note") diff --git a/Doc/library/faulthandler.rst b/Doc/library/faulthandler.rst index b80de69a..f64dfeb5 100644 --- a/Doc/library/faulthandler.rst +++ b/Doc/library/faulthandler.rst @@ -175,10 +175,10 @@ handler: .. code-block:: shell-session - $ python3 -c "import ctypes; ctypes.string_at(0)" + $ python -c "import ctypes; ctypes.string_at(0)" Segmentation fault - $ python3 -q -X faulthandler + $ python -q -X faulthandler >>> import ctypes >>> ctypes.string_at(0) Fatal Python error: Segmentation fault diff --git a/Doc/library/fcntl.rst b/Doc/library/fcntl.rst index c5a7ba01..969a79fa 100644 --- a/Doc/library/fcntl.rst +++ b/Doc/library/fcntl.rst @@ -52,6 +52,12 @@ descriptor. constants, which allow to duplicate a file descriptor, the latter setting ``FD_CLOEXEC`` flag in addition. +.. versionchanged:: 3.12 + On Linux >= 4.5, the :mod:`fcntl` module exposes the ``FICLONE`` and + ``FICLONERANGE`` constants, which allow to share some data of one file with + another file by reflinking on some filesystems (e.g., btrfs, OCFS2, and + XFS). This behavior is commonly referred to as "copy-on-write". + The module defines the following functions: @@ -166,9 +172,9 @@ The module defines the following functions: which the lock starts, relative to *whence*, and *whence* is as with :func:`io.IOBase.seek`, specifically: - * :const:`0` -- relative to the start of the file (:data:`os.SEEK_SET`) - * :const:`1` -- relative to the current buffer position (:data:`os.SEEK_CUR`) - * :const:`2` -- relative to the end of the file (:data:`os.SEEK_END`) + * ``0`` -- relative to the start of the file (:const:`os.SEEK_SET`) + * ``1`` -- relative to the current buffer position (:const:`os.SEEK_CUR`) + * ``2`` -- relative to the end of the file (:const:`os.SEEK_END`) The default for *start* is 0, which means to start at the beginning of the file. The default for *len* is 0 which means to lock to the end of the file. The @@ -195,7 +201,7 @@ using the :func:`flock` call may be better. .. seealso:: Module :mod:`os` - If the locking flags :data:`~os.O_SHLOCK` and :data:`~os.O_EXLOCK` are + If the locking flags :const:`~os.O_SHLOCK` and :const:`~os.O_EXLOCK` are present in the :mod:`os` module (on BSD only), the :func:`os.open` function provides an alternative to the :func:`lockf` and :func:`flock` functions. diff --git a/Doc/library/filecmp.rst b/Doc/library/filecmp.rst index 83e9e14d..dfe4b7c5 100644 --- a/Doc/library/filecmp.rst +++ b/Doc/library/filecmp.rst @@ -74,7 +74,7 @@ The :class:`dircmp` class Construct a new directory comparison object, to compare the directories *a* and *b*. *ignore* is a list of names to ignore, and defaults to - :attr:`filecmp.DEFAULT_IGNORES`. *hide* is a list of names to hide, and + :const:`filecmp.DEFAULT_IGNORES`. *hide* is a list of names to hide, and defaults to ``[os.curdir, os.pardir]``. The :class:`dircmp` class compares files by doing *shallow* comparisons @@ -100,7 +100,7 @@ The :class:`dircmp` class used to get various bits of information about the directory trees being compared. - Note that via :meth:`__getattr__` hooks, all attributes are computed lazily, + Note that via :meth:`~object.__getattr__` hooks, all attributes are computed lazily, so there is no speed penalty if only those attributes which are lightweight to compute are used. diff --git a/Doc/library/fileinput.rst b/Doc/library/fileinput.rst index 4bc86875..f93e9a58 100644 --- a/Doc/library/fileinput.rst +++ b/Doc/library/fileinput.rst @@ -177,7 +177,7 @@ available for subclassing as well: The keyword-only parameter *encoding* and *errors* are added. .. versionchanged:: 3.11 - The ``'rU'`` and ``'U'`` modes and the :meth:`__getitem__` method have + The ``'rU'`` and ``'U'`` modes and the :meth:`!__getitem__` method have been removed. diff --git a/Doc/library/fnmatch.rst b/Doc/library/fnmatch.rst index 46bf0fc2..aed8991d 100644 --- a/Doc/library/fnmatch.rst +++ b/Doc/library/fnmatch.rst @@ -8,7 +8,7 @@ .. index:: single: filenames; wildcard expansion -.. index:: module: re +.. index:: pair: module; re -------------- @@ -38,7 +38,7 @@ special characters used in shell-style wildcards are: For a literal match, wrap the meta-characters in brackets. For example, ``'[?]'`` matches the character ``'?'``. -.. index:: module: glob +.. index:: pair: module; glob Note that the filename separator (``'/'`` on Unix) is *not* special to this module. See module :mod:`glob` for pathname expansion (:mod:`glob` uses diff --git a/Doc/library/fractions.rst b/Doc/library/fractions.rst index 5f0ecf1f..509c6368 100644 --- a/Doc/library/fractions.rst +++ b/Doc/library/fractions.rst @@ -25,7 +25,7 @@ another rational number, or from a string. The first version requires that *numerator* and *denominator* are instances of :class:`numbers.Rational` and returns a new :class:`Fraction` instance - with value ``numerator/denominator``. If *denominator* is :const:`0`, it + with value ``numerator/denominator``. If *denominator* is ``0``, it raises a :exc:`ZeroDivisionError`. The second version requires that *other_fraction* is an instance of :class:`numbers.Rational` and returns a :class:`Fraction` instance with the same value. The next two versions accept @@ -77,7 +77,7 @@ another rational number, or from a string. The :class:`Fraction` class inherits from the abstract base class :class:`numbers.Rational`, and implements all of the methods and - operations from that class. :class:`Fraction` instances are hashable, + operations from that class. :class:`Fraction` instances are :term:`hashable`, and should be treated as immutable. In addition, :class:`Fraction` has the following properties and methods: @@ -98,6 +98,14 @@ another rational number, or from a string. :class:`Fraction` implements ``__int__`` now to satisfy ``typing.SupportsInt`` instance checks. + .. versionchanged:: 3.12 + Space is allowed around the slash for string inputs: ``Fraction('2 / 3')``. + + .. versionchanged:: 3.12 + :class:`Fraction` instances now support float-style formatting, with + presentation types ``"e"``, ``"E"``, ``"f"``, ``"F"``, ``"g"``, ``"G"`` + and ``"%""``. + .. attribute:: numerator Numerator of the Fraction in lowest term. @@ -110,10 +118,17 @@ another rational number, or from a string. .. method:: as_integer_ratio() Return a tuple of two integers, whose ratio is equal - to the Fraction and with a positive denominator. + to the original Fraction. The ratio is in lowest terms + and has a positive denominator. .. versionadded:: 3.8 + .. method:: is_integer() + + Return ``True`` if the Fraction is an integer. + + .. versionadded:: 3.12 + .. classmethod:: from_float(flt) Alternative constructor which only accepts instances of @@ -184,6 +199,29 @@ another rational number, or from a string. ``ndigits`` is negative), again rounding half toward even. This method can also be accessed through the :func:`round` function. + .. method:: __format__(format_spec, /) + + Provides support for float-style formatting of :class:`Fraction` + instances via the :meth:`str.format` method, the :func:`format` built-in + function, or :ref:`Formatted string literals <f-strings>`. The + presentation types ``"e"``, ``"E"``, ``"f"``, ``"F"``, ``"g"``, ``"G"`` + and ``"%"`` are supported. For these presentation types, formatting for a + :class:`Fraction` object ``x`` follows the rules outlined for + the :class:`float` type in the :ref:`formatspec` section. + + Here are some examples:: + + >>> from fractions import Fraction + >>> format(Fraction(1, 7), '.40g') + '0.1428571428571428571428571428571428571429' + >>> format(Fraction('1234567.855'), '_.2f') + '1_234_567.86' + >>> f"{Fraction(355, 113):*>20.6e}" + '********3.141593e+00' + >>> old_price, new_price = 499, 672 + >>> "{:.2%} price increase".format(Fraction(new_price, old_price) - 1) + '34.67% price increase' + .. seealso:: diff --git a/Doc/library/ftplib.rst b/Doc/library/ftplib.rst index e5ba9eef..d1fe6414 100644 --- a/Doc/library/ftplib.rst +++ b/Doc/library/ftplib.rst @@ -85,7 +85,8 @@ The module defines the following items: The *encoding* parameter was added, and the default was changed from Latin-1 to UTF-8 to follow :rfc:`2640`. -.. class:: FTP_TLS(host='', user='', passwd='', acct='', keyfile=None, certfile=None, context=None, timeout=None, source_address=None, *, encoding='utf-8') +.. class:: FTP_TLS(host='', user='', passwd='', acct='', *, context=None, + timeout=None, source_address=None, encoding='utf-8') A :class:`FTP` subclass which adds TLS support to FTP as described in :rfc:`4217`. @@ -96,10 +97,6 @@ The module defines the following items: options, certificates and private keys into a single (potentially long-lived) structure. Please read :ref:`ssl-security` for best practices. - *keyfile* and *certfile* are a legacy alternative to *context* -- they - can point to PEM-formatted private key and certificate chain files - (respectively) for the SSL connection. - .. versionadded:: 3.2 .. versionchanged:: 3.3 @@ -108,14 +105,7 @@ The module defines the following items: .. versionchanged:: 3.4 The class now supports hostname check with :attr:`ssl.SSLContext.check_hostname` and *Server Name Indication* (see - :data:`ssl.HAS_SNI`). - - .. deprecated:: 3.6 - - *keyfile* and *certfile* are deprecated in favor of *context*. - Please use :meth:`ssl.SSLContext.load_cert_chain` instead, or let - :func:`ssl.create_default_context` select the system's trusted CA - certificates for you. + :const:`ssl.HAS_SNI`). .. versionchanged:: 3.9 If the *timeout* parameter is set to be zero, it will raise a @@ -123,6 +113,9 @@ The module defines the following items: The *encoding* parameter was added, and the default was changed from Latin-1 to UTF-8 to follow :rfc:`2640`. + .. versionchanged:: 3.12 + The deprecated *keyfile* and *certfile* parameters have been removed. + Here's a sample session using the :class:`FTP_TLS` class:: >>> ftps = FTP_TLS('ftp.pureftpd.org') @@ -438,7 +431,7 @@ FTP_TLS Objects .. attribute:: FTP_TLS.ssl_version - The SSL version to use (defaults to :attr:`ssl.PROTOCOL_SSLv23`). + The SSL version to use (defaults to :data:`ssl.PROTOCOL_SSLv23`). .. method:: FTP_TLS.auth() @@ -448,7 +441,7 @@ FTP_TLS Objects .. versionchanged:: 3.4 The method now supports hostname check with :attr:`ssl.SSLContext.check_hostname` and *Server Name Indication* (see - :data:`ssl.HAS_SNI`). + :const:`ssl.HAS_SNI`). .. method:: FTP_TLS.ccc() diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index d0da05f7..3cb70b7f 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -14,8 +14,8 @@ are always available. They are listed here in alphabetical order. | | :func:`abs` | | :func:`enumerate` | | :func:`len` | | |func-range|_ | | | :func:`aiter` | | :func:`eval` | | |func-list|_ | | :func:`repr` | | | :func:`all` | | :func:`exec` | | :func:`locals` | | :func:`reversed` | -| | :func:`any` | | | | | | :func:`round` | -| | :func:`anext` | | **F** | | **M** | | | +| | :func:`anext` | | | | | | :func:`round` | +| | :func:`any` | | **F** | | **M** | | | | | :func:`ascii` | | :func:`filter` | | :func:`map` | | **S** | | | | | :func:`float` | | :func:`max` | | |func-set|_ | | | **B** | | :func:`format` | | |func-memoryview|_ | | :func:`setattr` | @@ -122,7 +122,7 @@ are always available. They are listed here in alphabetical order. Convert an integer number to a binary string prefixed with "0b". The result is a valid Python expression. If *x* is not a Python :class:`int` object, it - has to define an :meth:`__index__` method that returns an integer. Some + has to define an :meth:`~object.__index__` method that returns an integer. Some examples: >>> bin(3) @@ -147,7 +147,7 @@ are always available. They are listed here in alphabetical order. or omitted, this returns ``False``; otherwise, it returns ``True``. The :class:`bool` class is a subclass of :class:`int` (see :ref:`typesnumeric`). It cannot be subclassed further. Its only instances are ``False`` and - ``True`` (see :ref:`bltin-boolean-values`). + ``True`` (see :ref:`typebool`). .. index:: pair: Boolean; type @@ -168,6 +168,13 @@ are always available. They are listed here in alphabetical order. If :func:`sys.breakpointhook` is not accessible, this function will raise :exc:`RuntimeError`. + By default, the behavior of :func:`breakpoint` can be changed with + the :envvar:`PYTHONBREAKPOINT` environment variable. + See :func:`sys.breakpointhook` for usage details. + + Note that this is not guaranteed if :func:`sys.breakpointhook` + has been replaced. + .. audit-event:: builtins.breakpoint breakpointhook breakpoint .. versionadded:: 3.7 @@ -376,9 +383,9 @@ are always available. They are listed here in alphabetical order. ``0j``. For a general Python object ``x``, ``complex(x)`` delegates to - ``x.__complex__()``. If ``__complex__()`` is not defined then it falls back - to :meth:`__float__`. If ``__float__()`` is not defined then it falls back - to :meth:`__index__`. + ``x.__complex__()``. If :meth:`~object.__complex__` is not defined then it falls back + to :meth:`~object.__float__`. If :meth:`!__float__` is not defined then it falls back + to :meth:`~object.__index__`. .. note:: @@ -393,8 +400,8 @@ are always available. They are listed here in alphabetical order. Grouping digits with underscores as in code literals is allowed. .. versionchanged:: 3.8 - Falls back to :meth:`__index__` if :meth:`__complex__` and - :meth:`__float__` are not defined. + Falls back to :meth:`~object.__index__` if :meth:`~object.__complex__` and + :meth:`~object.__float__` are not defined. .. function:: delattr(object, name) @@ -462,6 +469,7 @@ are always available. They are listed here in alphabetical order. >>> class Shape: ... def __dir__(self): ... return ['area', 'perimeter', 'location'] + ... >>> s = Shape() >>> dir(s) ['area', 'location', 'perimeter'] @@ -561,7 +569,7 @@ are always available. They are listed here in alphabetical order. Raises an :ref:`auditing event <auditing>` ``exec`` with the code object as the argument. Code compilation events may also be raised. -.. index:: builtin: exec +.. index:: pair: built-in function; exec .. function:: exec(object, globals=None, locals=None, /, *, closure=None) @@ -622,7 +630,7 @@ are always available. They are listed here in alphabetical order. .. function:: filter(function, iterable) Construct an iterator from those elements of *iterable* for which *function* - returns true. *iterable* may be either a sequence, a container which + is true. *iterable* may be either a sequence, a container which supports iteration, or an iterator. If *function* is ``None``, the identity function is assumed, that is, all elements of *iterable* that are false are removed. @@ -633,7 +641,7 @@ are always available. They are listed here in alphabetical order. ``None``. See :func:`itertools.filterfalse` for the complementary function that returns - elements of *iterable* for which *function* returns false. + elements of *iterable* for which *function* is false. .. class:: float(x=0.0) @@ -673,8 +681,8 @@ are always available. They are listed here in alphabetical order. float, an :exc:`OverflowError` will be raised. For a general Python object ``x``, ``float(x)`` delegates to - ``x.__float__()``. If ``__float__()`` is not defined then it falls back - to :meth:`__index__`. + ``x.__float__()``. If :meth:`~object.__float__` is not defined then it falls back + to :meth:`~object.__index__`. If no argument is given, ``0.0`` is returned. @@ -700,7 +708,7 @@ are always available. They are listed here in alphabetical order. *x* is now a positional-only parameter. .. versionchanged:: 3.8 - Falls back to :meth:`__index__` if :meth:`__float__` is not defined. + Falls back to :meth:`~object.__index__` if :meth:`~object.__float__` is not defined. .. index:: @@ -786,7 +794,7 @@ are always available. They are listed here in alphabetical order. For objects with custom :meth:`__hash__` methods, note that :func:`hash` truncates the return value based on the bit width of the host machine. - See :meth:`__hash__` for details. + See :meth:`__hash__ <object.__hash__>` for details. .. function:: help() help(request) @@ -814,7 +822,7 @@ are always available. They are listed here in alphabetical order. Convert an integer number to a lowercase hexadecimal string prefixed with "0x". If *x* is not a Python :class:`int` object, it has to define an - :meth:`__index__` method that returns an integer. Some examples: + :meth:`~object.__index__` method that returns an integer. Some examples: >>> hex(255) '0xff' @@ -885,9 +893,9 @@ are always available. They are listed here in alphabetical order. int(x, base=10) Return an integer object constructed from a number or string *x*, or return - ``0`` if no arguments are given. If *x* defines :meth:`__int__`, - ``int(x)`` returns ``x.__int__()``. If *x* defines :meth:`__index__`, - it returns ``x.__index__()``. If *x* defines :meth:`__trunc__`, + ``0`` if no arguments are given. If *x* defines :meth:`~object.__int__`, + ``int(x)`` returns ``x.__int__()``. If *x* defines :meth:`~object.__index__`, + it returns ``x.__index__()``. If *x* defines :meth:`~object.__trunc__`, it returns ``x.__trunc__()``. For floating point numbers, this truncates towards zero. @@ -924,10 +932,10 @@ are always available. They are listed here in alphabetical order. *x* is now a positional-only parameter. .. versionchanged:: 3.8 - Falls back to :meth:`__index__` if :meth:`__int__` is not defined. + Falls back to :meth:`~object.__index__` if :meth:`~object.__int__` is not defined. .. versionchanged:: 3.11 - The delegation to :meth:`__trunc__` is deprecated. + The delegation to :meth:`~object.__trunc__` is deprecated. .. versionchanged:: 3.11 :class:`int` string inputs and string representations can be limited to @@ -1130,7 +1138,7 @@ are always available. They are listed here in alphabetical order. Convert an integer number to an octal string prefixed with "0o". The result is a valid Python expression. If *x* is not a Python :class:`int` object, it - has to define an :meth:`__index__` method that returns an integer. For + has to define an :meth:`~object.__index__` method that returns an integer. For example: >>> oct(8) @@ -1223,7 +1231,7 @@ are always available. They are listed here in alphabetical order. * Binary files are buffered in fixed-size chunks; the size of the buffer is chosen using a heuristic trying to determine the underlying device's "block - size" and falling back on :attr:`io.DEFAULT_BUFFER_SIZE`. On many systems, + size" and falling back on :const:`io.DEFAULT_BUFFER_SIZE`. On many systems, the buffer will typically be 4096 or 8192 bytes long. * "Interactive" text files (files for which :meth:`~io.IOBase.isatty` @@ -1263,7 +1271,7 @@ are always available. They are listed here in alphabetical order. * ``'xmlcharrefreplace'`` is only supported when writing to a file. Characters not supported by the encoding are replaced with the - appropriate XML character reference ``&#nnn;``. + appropriate XML character reference :samp:`&#{nnn};`. * ``'backslashreplace'`` replaces malformed data by Python's backslashed escape sequences. @@ -1339,7 +1347,7 @@ are always available. They are listed here in alphabetical order. single: I/O control; buffering single: binary mode single: text mode - module: sys + pair: module; sys See also the file handling modules, such as :mod:`fileinput`, :mod:`io` (where :func:`open` is declared), :mod:`os`, :mod:`os.path`, :mod:`tempfile`, @@ -1443,8 +1451,9 @@ are always available. They are listed here in alphabetical order. arguments are converted to text strings, :func:`print` cannot be used with binary mode file objects. For these, use ``file.write(...)`` instead. - Whether the output is buffered is usually determined by *file*, but if the - *flush* keyword argument is true, the stream is forcibly flushed. + Output buffering is usually determined by *file*. + However, if *flush* is true, the stream is forcibly flushed. + .. versionchanged:: 3.3 Added the *flush* keyword argument. @@ -1622,7 +1631,7 @@ are always available. They are listed here in alphabetical order. .. class:: slice(stop) - slice(start, stop, step=1) + slice(start, stop, step=None) Return a :term:`slice` object representing the set of indices specified by ``range(start, stop, step)``. The *start* and *step* arguments default to @@ -1634,6 +1643,9 @@ are always available. They are listed here in alphabetical order. example: ``a[start:stop:step]`` or ``a[start:stop, i]``. See :func:`itertools.islice` for an alternate version that returns an iterator. + .. versionchanged:: 3.12 + Slice objects are now :term:`hashable` (provided :attr:`~slice.start`, + :attr:`~slice.stop`, and :attr:`~slice.step` are hashable). .. function:: sorted(iterable, /, *, key=None, reverse=False) @@ -1676,7 +1688,7 @@ are always available. They are listed here in alphabetical order. class C: @staticmethod - def f(arg1, arg2, ...): ... + def f(arg1, arg2, argN): ... The ``@staticmethod`` form is a function :term:`decorator` -- see :ref:`function` for details. @@ -1739,6 +1751,10 @@ are always available. They are listed here in alphabetical order. .. versionchanged:: 3.8 The *start* parameter can be specified as a keyword argument. + .. versionchanged:: 3.12 Summation of floats switched to an algorithm + that gives higher accuracy on most builds. + + .. class:: super() super(type, object_or_type=None) @@ -1821,7 +1837,7 @@ are always available. They are listed here in alphabetical order. .. class:: type(object) type(name, bases, dict, **kwds) - .. index:: object: type + .. index:: pair: object; type With one argument, return the type of an *object*. The return value is a type object and generally the same object as returned by @@ -1977,8 +1993,8 @@ are always available. They are listed here in alphabetical order. .. function:: __import__(name, globals=None, locals=None, fromlist=(), level=0) .. index:: - statement: import - module: imp + pair: statement; import + pair: module; builtins .. note:: diff --git a/Doc/library/functools.rst b/Doc/library/functools.rst index 2f0a9bd8..f736eb0a 100644 --- a/Doc/library/functools.rst +++ b/Doc/library/functools.rst @@ -49,8 +49,13 @@ The :mod:`functools` module defines the following functions: >>> factorial(12) # makes two new recursive calls, the other 10 are cached 479001600 - The cache is threadsafe so the wrapped function can be used in multiple - threads. + The cache is threadsafe so that the wrapped function can be used in + multiple threads. This means that the underlying data structure will + remain coherent during concurrent updates. + + It is possible for the wrapped function to be called more than once if + another thread makes an additional call before the initial call has been + completed and cached. .. versionadded:: 3.9 @@ -86,6 +91,14 @@ The :mod:`functools` module defines the following functions: The cached value can be cleared by deleting the attribute. This allows the *cached_property* method to run again. + The *cached_property* does not prevent a possible race condition in + multi-threaded usage. The getter function could run more than once on the + same instance, with the latest run setting the cached value. If the cached + property is idempotent or otherwise not harmful to run more than once on an + instance, this is fine. If synchronization is needed, implement the necessary + locking inside the decorated getter function or around the cached property + access. + Note, this decorator interferes with the operation of :pep:`412` key-sharing dictionaries. This means that instance dictionaries can take more space than usual. @@ -97,21 +110,20 @@ The :mod:`functools` module defines the following functions: ``__slots__`` without including ``__dict__`` as one of the defined slots (as such classes don't provide a ``__dict__`` attribute at all). - If a mutable mapping is not available or if space-efficient key sharing - is desired, an effect similar to :func:`cached_property` can be achieved - by a stacking :func:`property` on top of :func:`cache`:: - - class DataSet: - def __init__(self, sequence_of_numbers): - self._data = sequence_of_numbers - - @property - @cache - def stdev(self): - return statistics.stdev(self._data) + If a mutable mapping is not available or if space-efficient key sharing is + desired, an effect similar to :func:`cached_property` can also be achieved by + stacking :func:`property` on top of :func:`lru_cache`. See + :ref:`faq-cache-method-calls` for more details on how this differs from :func:`cached_property`. .. versionadded:: 3.8 + .. versionchanged:: 3.12 + Prior to Python 3.12, ``cached_property`` included an undocumented lock to + ensure that in multi-threaded usage the getter function was guaranteed to + run only once per instance. However, the lock was per-property, not + per-instance, which could result in unacceptably high lock contention. In + Python 3.12+ this locking is removed. + .. function:: cmp_to_key(func) @@ -143,11 +155,16 @@ The :mod:`functools` module defines the following functions: *maxsize* most recent calls. It can save time when an expensive or I/O bound function is periodically called with the same arguments. - The cache is threadsafe so the wrapped function can be used in multiple - threads. + The cache is threadsafe so that the wrapped function can be used in + multiple threads. This means that the underlying data structure will + remain coherent during concurrent updates. + + It is possible for the wrapped function to be called more than once if + another thread makes an additional call before the initial call has been + completed and cached. Since a dictionary is used to cache results, the positional and keyword - arguments to the function must be hashable. + arguments to the function must be :term:`hashable`. Distinct argument patterns may be considered to be distinct calls with separate cache entries. For example, ``f(a=1, b=2)`` and ``f(b=2, a=1)`` @@ -209,15 +226,16 @@ The :mod:`functools` module defines the following functions: In general, the LRU cache should only be used when you want to reuse previously computed values. Accordingly, it doesn't make sense to cache - functions with side-effects, functions that need to create distinct mutable - objects on each call, or impure functions such as time() or random(). + functions with side-effects, functions that need to create + distinct mutable objects on each call (such as generators and async functions), + or impure functions such as time() or random(). Example of an LRU cache for static web content:: @lru_cache(maxsize=32) def get_pep(num): 'Retrieve text of a Python Enhancement Proposal' - resource = 'https://peps.python.org/pep-%04d/' % num + resource = f'https://peps.python.org/pep-{num:04d}' try: with urllib.request.urlopen(resource) as s: return s.read() diff --git a/Doc/library/gc.rst b/Doc/library/gc.rst index 69a1a831..331c071c 100644 --- a/Doc/library/gc.rst +++ b/Doc/library/gc.rst @@ -50,6 +50,9 @@ The :mod:`gc` module provides the following functions: is run. Not all items in some free lists may be freed due to the particular implementation, in particular :class:`float`. + The effect of calling ``gc.collect()`` while the interpreter is already + performing a collection is undefined. + .. function:: set_debug(flags) @@ -206,12 +209,17 @@ The :mod:`gc` module provides the following functions: .. function:: freeze() - Freeze all the objects tracked by gc - move them to a permanent generation - and ignore all the future collections. This can be used before a POSIX - fork() call to make the gc copy-on-write friendly or to speed up collection. - Also collection before a POSIX fork() call may free pages for future - allocation which can cause copy-on-write too so it's advised to disable gc - in parent process and freeze before fork and enable gc in child process. + Freeze all the objects tracked by the garbage collector; move them to a + permanent generation and ignore them in all the future collections. + + If a process will ``fork()`` without ``exec()``, avoiding unnecessary + copy-on-write in child processes will maximize memory sharing and reduce + overall memory usage. This requires both avoiding creation of freed "holes" + in memory pages in the parent process and ensuring that GC collections in + child processes won't touch the ``gc_refs`` counter of long-lived objects + originating in the parent process. To accomplish both, call ``gc.disable()`` + early in the parent process, ``gc.freeze()`` right before ``fork()``, and + ``gc.enable()`` early in child processes. .. versionadded:: 3.7 @@ -251,8 +259,8 @@ values but should not rebind them): are printed. .. versionchanged:: 3.4 - Following :pep:`442`, objects with a :meth:`__del__` method don't end - up in :attr:`gc.garbage` anymore. + Following :pep:`442`, objects with a :meth:`~object.__del__` method don't end + up in :data:`gc.garbage` anymore. .. data:: callbacks diff --git a/Doc/library/gettext.rst b/Doc/library/gettext.rst index 747f8703..7ebe91b3 100644 --- a/Doc/library/gettext.rst +++ b/Doc/library/gettext.rst @@ -58,7 +58,7 @@ class-based API instead. Return the localized translation of *message*, based on the current global domain, language, and locale directory. This function is usually aliased as - :func:`_` in the local namespace (see examples below). + :func:`!_` in the local namespace (see examples below). .. function:: dgettext(domain, message) @@ -98,7 +98,7 @@ class-based API instead. .. versionadded:: 3.8 -Note that GNU :program:`gettext` also defines a :func:`dcgettext` method, but +Note that GNU :program:`gettext` also defines a :func:`!dcgettext` method, but this was deemed not useful and so it is currently unimplemented. Here's an example of typical usage for this API:: @@ -119,7 +119,7 @@ greater convenience than the GNU :program:`gettext` API. It is the recommended way of localizing your Python applications and modules. :mod:`!gettext` defines a :class:`GNUTranslations` class which implements the parsing of GNU :file:`.mo` format files, and has methods for returning strings. Instances of this class can also -install themselves in the built-in namespace as the function :func:`_`. +install themselves in the built-in namespace as the function :func:`!_`. .. function:: find(domain, localedir=None, languages=None, all=False) @@ -150,15 +150,12 @@ install themselves in the built-in namespace as the function :func:`_`. .. function:: translation(domain, localedir=None, languages=None, class_=None, fallback=False) - Return a :class:`*Translations` instance based on the *domain*, *localedir*, + Return a ``*Translations`` instance based on the *domain*, *localedir*, and *languages*, which are first passed to :func:`find` to get a list of the associated :file:`.mo` file paths. Instances with identical :file:`.mo` file names are cached. The actual class instantiated is *class_* if provided, otherwise :class:`GNUTranslations`. The class's constructor must - take a single :term:`file object` argument. If provided, *codeset* will change - the charset used to encode translated strings in the - :meth:`~NullTranslations.lgettext` and :meth:`~NullTranslations.lngettext` - methods. + take a single :term:`file object` argument. If multiple files are found, later files are used as fallbacks for earlier ones. To allow setting the fallback, :func:`copy.copy` is used to clone each @@ -177,19 +174,19 @@ install themselves in the built-in namespace as the function :func:`_`. .. function:: install(domain, localedir=None, *, names=None) - This installs the function :func:`_` in Python's builtins namespace, based on + This installs the function :func:`!_` in Python's builtins namespace, based on *domain* and *localedir* which are passed to the function :func:`translation`. For the *names* parameter, please see the description of the translation object's :meth:`~NullTranslations.install` method. As seen below, you usually mark the strings in your application that are - candidates for translation, by wrapping them in a call to the :func:`_` + candidates for translation, by wrapping them in a call to the :func:`!_` function, like this:: print(_('This string will be translated.')) - For convenience, you want the :func:`_` function to be installed in Python's + For convenience, you want the :func:`!_` function to be installed in Python's builtins namespace, so it is easily accessible in all modules of your application. @@ -276,20 +273,20 @@ are the methods of :class:`!NullTranslations`: If the *names* parameter is given, it must be a sequence containing the names of functions you want to install in the builtins namespace in - addition to :func:`_`. Supported names are ``'gettext'``, ``'ngettext'``, - ``'pgettext'``, ``'npgettext'``, ``'lgettext'``, and ``'lngettext'``. + addition to :func:`!_`. Supported names are ``'gettext'``, ``'ngettext'``, + ``'pgettext'``, and ``'npgettext'``. Note that this is only one way, albeit the most convenient way, to make - the :func:`_` function available to your application. Because it affects + the :func:`!_` function available to your application. Because it affects the entire application globally, and specifically the built-in namespace, - localized modules should never install :func:`_`. Instead, they should use - this code to make :func:`_` available to their module:: + localized modules should never install :func:`!_`. Instead, they should use + this code to make :func:`!_` available to their module:: import gettext t = gettext.translation('mymodule', ...) _ = t.gettext - This puts :func:`_` only in the module's global namespace and so only + This puts :func:`!_` only in the module's global namespace and so only affects calls within this module. .. versionchanged:: 3.8 @@ -314,7 +311,7 @@ initialize the "protected" :attr:`_charset` instance variable, defaulting to ids and message strings read from the catalog are converted to Unicode using this encoding, else ASCII is assumed. -Since message ids are read as Unicode strings too, all :meth:`*gettext` methods +Since message ids are read as Unicode strings too, all ``*gettext()`` methods will assume message ids as Unicode strings, not byte strings. The entire set of key/value pairs are placed into a dictionary and set as the @@ -404,13 +401,14 @@ version has a slightly different API. Its documented usage was:: _ = cat.gettext print(_('hello world')) -For compatibility with this older module, the function :func:`Catalog` is an +For compatibility with this older module, the function :func:`!Catalog` is an alias for the :func:`translation` function described above. One difference between this module and Henstridge's: his catalog objects supported access through a mapping API, but this appears to be unused and so is not currently supported. +.. _i18n-howto: Internationalizing your programs and modules -------------------------------------------- @@ -431,7 +429,7 @@ take the following steps: In order to prepare your code for I18N, you need to look at all the strings in your files. Any string that needs to be translated should be marked by wrapping -it in ``_('...')`` --- that is, a call to the function :func:`_`. For example:: +it in ``_('...')`` --- that is, a call to the function :func:`_ <gettext>`. For example:: filename = 'mylog.txt' message = _('writing a log message') @@ -503,7 +501,7 @@ module:: Localizing your application ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -If you are localizing your application, you can install the :func:`_` function +If you are localizing your application, you can install the :func:`!_` function globally into the built-in namespace, usually in the main driver file of your application. This will let all your application-specific files just use ``_('...')`` without having to explicitly install it in each file. @@ -580,13 +578,13 @@ Here is one way you can handle this situation:: for a in animals: print(_(a)) -This works because the dummy definition of :func:`_` simply returns the string +This works because the dummy definition of :func:`!_` simply returns the string unchanged. And this dummy definition will temporarily override any definition -of :func:`_` in the built-in namespace (until the :keyword:`del` command). Take -care, though if you have a previous definition of :func:`_` in the local +of :func:`!_` in the built-in namespace (until the :keyword:`del` command). Take +care, though if you have a previous definition of :func:`!_` in the local namespace. -Note that the second use of :func:`_` will not identify "a" as being +Note that the second use of :func:`!_` will not identify "a" as being translatable to the :program:`gettext` program, because the parameter is not a string literal. @@ -605,13 +603,13 @@ Another way to handle this is with the following example:: print(_(a)) In this case, you are marking translatable strings with the function -:func:`N_`, which won't conflict with any definition of :func:`_`. +:func:`!N_`, which won't conflict with any definition of :func:`!_`. However, you will need to teach your message extraction program to -look for translatable strings marked with :func:`N_`. :program:`xgettext`, +look for translatable strings marked with :func:`!N_`. :program:`xgettext`, :program:`pygettext`, ``pybabel extract``, and :program:`xpot` all support this through the use of the :option:`!-k` command-line switch. -The choice of :func:`N_` here is totally arbitrary; it could have just -as easily been :func:`MarkThisStringForTranslation`. +The choice of :func:`!N_` here is totally arbitrary; it could have just +as easily been :func:`!MarkThisStringForTranslation`. Acknowledgements diff --git a/Doc/library/glob.rst b/Doc/library/glob.rst index 5af15c41..0e4cfe7e 100644 --- a/Doc/library/glob.rst +++ b/Doc/library/glob.rst @@ -49,7 +49,7 @@ For example, ``'[?]'`` matches the character ``'?'``. symlinks are included in the results (as in the shell). Whether or not the results are sorted depends on the file system. If a file that satisfies conditions is removed or added during the call of this function, whether - a path name for that file be included is unspecified. + a path name for that file will be included is unspecified. If *root_dir* is not ``None``, it should be a :term:`path-like object` specifying the root directory for searching. It has the same effect on diff --git a/Doc/library/graphlib.rst b/Doc/library/graphlib.rst index 2bc80da4..fdd8f39e 100644 --- a/Doc/library/graphlib.rst +++ b/Doc/library/graphlib.rst @@ -17,7 +17,7 @@ .. class:: TopologicalSorter(graph=None) - Provides functionality to topologically sort a graph of hashable nodes. + Provides functionality to topologically sort a graph of :term:`hashable` nodes. A topological order is a linear ordering of the vertices in a graph such that for every directed edge u -> v from vertex u to vertex v, vertex u comes @@ -85,7 +85,7 @@ .. method:: add(node, *predecessors) Add a new node and its predecessors to the graph. Both the *node* and all - elements in *predecessors* must be hashable. + elements in *predecessors* must be :term:`hashable`. If called multiple times with the same node argument, the set of dependencies will be the union of all dependencies passed in. @@ -115,7 +115,7 @@ :meth:`TopologicalSorter.done` is less than the number that have been returned by :meth:`TopologicalSorter.get_ready`. - The :meth:`~TopologicalSorter.__bool__` method of this class defers to + The :meth:`~object.__bool__` method of this class defers to this function, so instead of:: if ts.is_active(): @@ -204,7 +204,7 @@ The :mod:`graphlib` module defines the following exception classes: in the working graph. If multiple cycles exist, only one undefined choice among them will be reported and included in the exception. - The detected cycle can be accessed via the second element in the :attr:`~CycleError.args` + The detected cycle can be accessed via the second element in the :attr:`~BaseException.args` attribute of the exception instance and consists in a list of nodes, such that each node is, in the graph, an immediate predecessor of the next node in the list. In the reported list, the first and the last node will be the same, to make it clear that it is cyclic. diff --git a/Doc/library/gzip.rst b/Doc/library/gzip.rst index 8cea2649..60236a11 100644 --- a/Doc/library/gzip.rst +++ b/Doc/library/gzip.rst @@ -70,7 +70,7 @@ The module defines the following items: .. class:: GzipFile(filename=None, mode=None, compresslevel=9, fileobj=None, mtime=None) Constructor for the :class:`GzipFile` class, which simulates most of the - methods of a :term:`file object`, with the exception of the :meth:`truncate` + methods of a :term:`file object`, with the exception of the :meth:`~io.IOBase.truncate` method. At least one of *fileobj* and *filename* must be given a non-trivial value. @@ -113,7 +113,7 @@ The module defines the following items: :class:`GzipFile` supports the :class:`io.BufferedIOBase` interface, including iteration and the :keyword:`with` statement. Only the - :meth:`truncate` method isn't implemented. + :meth:`~io.IOBase.truncate` method isn't implemented. :class:`GzipFile` also provides the following method and attribute: @@ -143,6 +143,12 @@ The module defines the following items: :func:`time.time` and the :attr:`~os.stat_result.st_mtime` attribute of the object returned by :func:`os.stat`. + .. attribute:: name + + The path to the gzip file on disk, as a :class:`str` or :class:`bytes`. + Equivalent to the output of :func:`os.fspath` on the original input path, + with no other normalization, resolution or expansion. + .. versionchanged:: 3.1 Support for the :keyword:`with` statement was added, along with the *mtime* constructor argument and :attr:`mtime` attribute. @@ -165,6 +171,10 @@ The module defines the following items: .. versionchanged:: 3.6 Accepts a :term:`path-like object`. + .. versionchanged:: 3.12 + Remove the ``filename`` attribute, use the :attr:`~GzipFile.name` + attribute instead. + .. deprecated:: 3.9 Opening :class:`GzipFile` for writing without specifying the *mode* argument is deprecated. @@ -258,7 +268,7 @@ Command line options .. cmdoption:: file - If *file* is not specified, read from :attr:`sys.stdin`. + If *file* is not specified, read from :data:`sys.stdin`. .. cmdoption:: --fast diff --git a/Doc/library/hashlib.rst b/Doc/library/hashlib.rst index a96fc8b8..eb650c18 100644 --- a/Doc/library/hashlib.rst +++ b/Doc/library/hashlib.rst @@ -11,7 +11,7 @@ .. index:: single: message digest, MD5 - single: secure hash algorithm, SHA1, SHA224, SHA256, SHA384, SHA512 + single: secure hash algorithm, SHA1, SHA2, SHA224, SHA256, SHA384, SHA512, SHA3, Shake, Blake2 .. testsetup:: @@ -22,7 +22,8 @@ This module implements a common interface to many different secure hash and message digest algorithms. Included are the FIPS secure hash algorithms SHA1, -SHA224, SHA256, SHA384, and SHA512 (defined in FIPS 180-2) as well as RSA's MD5 +SHA224, SHA256, SHA384, SHA512, (defined in `the FIPS 180-4 standard`_), +the SHA-3 series (defined in `the FIPS 202 standard`_) as well as RSA's MD5 algorithm (defined in internet :rfc:`1321`). The terms "secure hash" and "message digest" are interchangeable. Older algorithms were called message digests. The modern term is secure hash. @@ -32,11 +33,6 @@ digests. The modern term is secure hash. If you want the adler32 or crc32 hash functions, they are available in the :mod:`zlib` module. -.. warning:: - - Some algorithms have known hash collision weaknesses, refer to the "See - also" section at the end. - .. _hash-algorithms: @@ -44,38 +40,43 @@ Hash algorithms --------------- There is one constructor method named for each type of :dfn:`hash`. All return -a hash object with the same simple interface. For example: use :func:`sha256` to -create a SHA-256 hash object. You can now feed this object with :term:`bytes-like -objects <bytes-like object>` (normally :class:`bytes`) using the :meth:`update` method. -At any point you can ask it for the :dfn:`digest` of the -concatenation of the data fed to it so far using the :meth:`digest` or -:meth:`hexdigest` methods. +a hash object with the same simple interface. For example: use :func:`sha256` +to create a SHA-256 hash object. You can now feed this object with +:term:`bytes-like objects <bytes-like object>` (normally :class:`bytes`) using +the :meth:`update<hash.update>` method. At any point you can ask it for the +:dfn:`digest` of the concatenation of the data fed to it so far using the +:meth:`digest()<hash.digest>` or :meth:`hexdigest()<hash.hexdigest>` methods. -.. note:: +To allow multithreading, the Python :term:`GIL` is released while computing a +hash supplied more than 2047 bytes of data at once in its constructor or +:meth:`.update<hash.update>` method. - For better multithreading performance, the Python :term:`GIL` is released for - data larger than 2047 bytes at object creation or on update. - -.. note:: - - Feeding string objects into :meth:`update` is not supported, as hashes work - on bytes, not on characters. .. index:: single: OpenSSL; (use in module hashlib) Constructors for hash algorithms that are always present in this module are -:func:`sha1`, :func:`sha224`, :func:`sha256`, :func:`sha384`, -:func:`sha512`, :func:`blake2b`, and :func:`blake2s`. -:func:`md5` is normally available as well, though it -may be missing or blocked if you are using a rare "FIPS compliant" build of Python. -Additional algorithms may also be available depending upon the OpenSSL -library that Python uses on your platform. On most platforms the +:func:`sha1`, :func:`sha224`, :func:`sha256`, :func:`sha384`, :func:`sha512`, :func:`sha3_224`, :func:`sha3_256`, :func:`sha3_384`, :func:`sha3_512`, -:func:`shake_128`, :func:`shake_256` are also available. +:func:`shake_128`, :func:`shake_256`, :func:`blake2b`, and :func:`blake2s`. +:func:`md5` is normally available as well, though it may be missing or blocked +if you are using a rare "FIPS compliant" build of Python. +These correspond to :data:`algorithms_guaranteed`. + +Additional algorithms may also be available if your Python distribution's +:mod:`hashlib` was linked against a build of OpenSSL that provides others. +Others *are not guaranteed available* on all installations and will only be +accessible by name via :func:`new`. See :data:`algorithms_available`. + +.. warning:: + + Some algorithms have known hash collision weaknesses (including MD5 and + SHA1). Refer to `Attacks on cryptographic hash algorithms`_ and the + `hashlib-seealso`_ section at the end of this document. .. versionadded:: 3.6 SHA3 (Keccak) and SHAKE constructors :func:`sha3_224`, :func:`sha3_256`, - :func:`sha3_384`, :func:`sha3_512`, :func:`shake_128`, :func:`shake_256`. + :func:`sha3_384`, :func:`sha3_512`, :func:`shake_128`, :func:`shake_256` + were added. .. versionadded:: 3.6 :func:`blake2b` and :func:`blake2s` were added. @@ -89,10 +90,19 @@ library that Python uses on your platform. On most platforms the that the hashing algorithm is not used in a security context, e.g. as a non-cryptographic one-way compression function. - Hashlib now uses SHA3 and SHAKE from OpenSSL 1.1.1 and newer. +.. versionchanged:: 3.9 + Hashlib now uses SHA3 and SHAKE from OpenSSL if it provides it. + +.. versionchanged:: 3.12 + For any of the MD5, SHA1, SHA2, or SHA3 algorithms that the linked + OpenSSL does not provide we fall back to a verified implementation from + the `HACL\* project`_. + +Usage +----- -For example, to obtain the digest of the byte string ``b"Nobody inspects the -spammish repetition"``:: +To obtain the digest of the byte string ``b"Nobody inspects the spammish +repetition"``:: >>> import hashlib >>> m = hashlib.sha256() @@ -108,22 +118,42 @@ More condensed: >>> hashlib.sha256(b"Nobody inspects the spammish repetition").hexdigest() '031edd7d41651593c5fe5c006fa5752b37fddff7bc4e843aa6af0c950f4b9406' -.. function:: new(name[, data], *, usedforsecurity=True) +Constructors +------------ + +.. function:: new(name[, data], \*, usedforsecurity=True) Is a generic constructor that takes the string *name* of the desired algorithm as its first parameter. It also exists to allow access to the above listed hashes as well as any other algorithms that your OpenSSL - library may offer. The named constructors are much faster than :func:`new` - and should be preferred. + library may offer. -Using :func:`new` with an algorithm provided by OpenSSL: +Using :func:`new` with an algorithm name: >>> h = hashlib.new('sha256') >>> h.update(b"Nobody inspects the spammish repetition") >>> h.hexdigest() '031edd7d41651593c5fe5c006fa5752b37fddff7bc4e843aa6af0c950f4b9406' -Hashlib provides the following constant attributes: + +.. function:: md5([, data], *, usedforsecurity=True) +.. function:: sha1([, data], *, usedforsecurity=True) +.. function:: sha224([, data], *, usedforsecurity=True) +.. function:: sha256([, data], *, usedforsecurity=True) +.. function:: sha384([, data], *, usedforsecurity=True) +.. function:: sha512([, data], *, usedforsecurity=True) +.. function:: sha3_224([, data], *, usedforsecurity=True) +.. function:: sha3_256([, data], *, usedforsecurity=True) +.. function:: sha3_384([, data], *, usedforsecurity=True) +.. function:: sha3_512([, data], *, usedforsecurity=True) + +Named constructors such as these are faster than passing an algorithm name to +:func:`new`. + +Attributes +---------- + +Hashlib provides the following constant module attributes: .. data:: algorithms_guaranteed @@ -144,10 +174,12 @@ Hashlib provides the following constant attributes: .. versionadded:: 3.2 +Hash Objects +------------ + The following values are provided as constant attributes of the hash objects returned by the constructors: - .. data:: hash.digest_size The size of the resulting hash in bytes. @@ -178,11 +210,6 @@ A hash object has the following methods: concatenation of all the arguments: ``m.update(a); m.update(b)`` is equivalent to ``m.update(a+b)``. - .. versionchanged:: 3.1 - The Python GIL is released to allow other threads to run while hash - updates on data larger than 2047 bytes is taking place when using hash - algorithms supplied by OpenSSL. - .. method:: hash.digest() @@ -207,6 +234,9 @@ A hash object has the following methods: SHAKE variable length digests ----------------------------- +.. function:: shake_128([, data], *, usedforsecurity=True) +.. function:: shake_256([, data], *, usedforsecurity=True) + The :func:`shake_128` and :func:`shake_256` algorithms provide variable length digests with length_in_bits//2 up to 128 or 256 bits of security. As such, their digest methods require a length. Maximum length is not limited @@ -214,7 +244,7 @@ by the SHAKE algorithm. .. method:: shake.digest(length) - Return the digest of the data passed to the :meth:`update` method so far. + Return the digest of the data passed to the :meth:`~hash.update` method so far. This is a bytes object of size *length* which may contain bytes in the whole range from 0 to 255. @@ -223,8 +253,13 @@ by the SHAKE algorithm. Like :meth:`digest` except the digest is returned as a string object of double length, containing only hexadecimal digits. This may be used to - exchange the value safely in email or other non-binary environments. + exchange the value in email or other non-binary environments. +Example use: + + >>> h = hashlib.shake_256(b'Nobody inspects the spammish repetition') + >>> h.hexdigest(20) + '44709d6fcb83d92a76dcb0b668c98e1b1d3dafe7' File hashing ------------ @@ -300,23 +335,17 @@ include a `salt <https://en.wikipedia.org/wiki/Salt_%28cryptography%29>`_. >>> from hashlib import pbkdf2_hmac >>> our_app_iters = 500_000 # Application specific, read above. - >>> dk = pbkdf2_hmac('sha256', b'password', b'bad salt'*2, our_app_iters) + >>> dk = pbkdf2_hmac('sha256', b'password', b'bad salt' * 2, our_app_iters) >>> dk.hex() '15530bba69924174860db778f2c6f8104d3aaf9d26241840c8c4a641c8d000a9' - .. versionadded:: 3.4 - - .. note:: + Function only available when Python is compiled with OpenSSL. - A fast implementation of *pbkdf2_hmac* is available with OpenSSL. The - Python implementation uses an inline version of :mod:`hmac`. It is about - three times slower and doesn't release the GIL. - - .. deprecated:: 3.10 + .. versionadded:: 3.4 - Slow Python implementation of *pbkdf2_hmac* is deprecated. In the - future the function will only be available when Python is compiled - with OpenSSL. + .. versionchanged:: 3.12 + Function now only available when Python is built with OpenSSL. The slow + pure Python implementation has been removed. .. function:: scrypt(password, *, salt, n, r, p, maxmem=0, dklen=64) @@ -436,9 +465,10 @@ Constructor functions also accept the following tree hashing parameters: .. figure:: hashlib-blake2-tree.png :alt: Explanation of tree mode parameters. + :class: invert-in-dark-mode See section 2.10 in `BLAKE2 specification -<https://blake2.net/blake2_20130129.pdf>`_ for comprehensive review of tree +<https://www.blake2.net/blake2_20130129.pdf>`_ for comprehensive review of tree hashing. @@ -477,9 +507,9 @@ Simple hashing To calculate hash of some data, you should first construct a hash object by calling the appropriate constructor function (:func:`blake2b` or -:func:`blake2s`), then update it with the data by calling :meth:`update` on the +:func:`blake2s`), then update it with the data by calling :meth:`~hash.update` on the object, and, finally, get the digest out of the object by calling -:meth:`digest` (or :meth:`hexdigest` for hex-encoded string). +:meth:`~hash.digest` (or :meth:`~hash.hexdigest` for hex-encoded string). >>> from hashlib import blake2b >>> h = blake2b() @@ -503,6 +533,7 @@ update the hash: >>> h = blake2b() >>> for item in items: ... h.update(item) + ... >>> h.hexdigest() '6ff843ba685842aa82031d3f53c48b66326df7639a63d128974c5c14f31a0f33343a8c65551134ed1ae0f2b0dd2bb495dc81039e3eeb0aa1bb0388bbeac29183' @@ -624,7 +655,7 @@ on the hash function used in digital signatures. by the signer. (`NIST SP-800-106 "Randomized Hashing for Digital Signatures" - <https://csrc.nist.gov/publications/detail/sp/800-106/final>`_) + <https://csrc.nist.gov/publications/detail/sp/800-106/archive/2009-02-25>`_) In BLAKE2 the salt is processed as a one-time input to the hash function during initialization, rather than as an input to each compression function. @@ -633,7 +664,7 @@ initialization, rather than as an input to each compression function. *Salted hashing* (or just hashing) with BLAKE2 or any other general-purpose cryptographic hash function, such as SHA-256, is not suitable for hashing - passwords. See `BLAKE2 FAQ <https://blake2.net/#qa>`_ for more + passwords. See `BLAKE2 FAQ <https://www.blake2.net/#qa>`_ for more information. .. @@ -769,16 +800,22 @@ Domain Dedication 1.0 Universal: * *Alexandr Sokolovskiy* -.. _BLAKE2: https://blake2.net +.. _BLAKE2: https://www.blake2.net .. _HMAC: https://en.wikipedia.org/wiki/Hash-based_message_authentication_code -.. _BLAKE: https://131002.net/blake/ -.. _SHA-3: https://en.wikipedia.org/wiki/NIST_hash_function_competition +.. _BLAKE: https://web.archive.org/web/20200918190133/https://131002.net/blake/ +.. _SHA-3: https://en.wikipedia.org/wiki/Secure_Hash_Algorithms .. _ChaCha: https://cr.yp.to/chacha.html .. _pyblake2: https://pythonhosted.org/pyblake2/ .. _NIST-SP-800-132: https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-132.pdf .. _stackexchange pbkdf2 iterations question: https://security.stackexchange.com/questions/3959/recommended-of-iterations-when-using-pbkdf2-sha256/ +.. _Attacks on cryptographic hash algorithms: https://en.wikipedia.org/wiki/Cryptographic_hash_function#Attacks_on_cryptographic_hash_algorithms +.. _the FIPS 180-4 standard: https://csrc.nist.gov/publications/detail/fips/180/4/final +.. _the FIPS 202 standard: https://csrc.nist.gov/publications/detail/fips/202/final +.. _HACL\* project: https://github.com/hacl-star/hacl-star +.. _hashlib-seealso: + .. seealso:: Module :mod:`hmac` @@ -787,15 +824,18 @@ Domain Dedication 1.0 Universal: Module :mod:`base64` Another way to encode binary hashes for non-binary environments. - https://blake2.net - Official BLAKE2 website. + https://nvlpubs.nist.gov/nistpubs/fips/nist.fips.180-4.pdf + The FIPS 180-4 publication on Secure Hash Algorithms. - https://csrc.nist.gov/csrc/media/publications/fips/180/2/archive/2002-08-01/documents/fips180-2.pdf - The FIPS 180-2 publication on Secure Hash Algorithms. + https://csrc.nist.gov/publications/detail/fips/202/final + The FIPS 202 publication on the SHA-3 Standard. + + https://www.blake2.net/ + Official BLAKE2 website. - https://en.wikipedia.org/wiki/Cryptographic_hash_function#Cryptographic_hash_algorithms - Wikipedia article with information on which algorithms have known issues and - what that means regarding their use. + https://en.wikipedia.org/wiki/Cryptographic_hash_function + Wikipedia article with information on which algorithms have known issues + and what that means regarding their use. https://www.ietf.org/rfc/rfc8018.txt PKCS #5: Password-Based Cryptography Specification Version 2.1 diff --git a/Doc/library/html.entities.rst b/Doc/library/html.entities.rst index cb8b6237..10529561 100644 --- a/Doc/library/html.entities.rst +++ b/Doc/library/html.entities.rst @@ -34,12 +34,12 @@ This module defines four dictionaries, :data:`html5`, .. data:: name2codepoint - A dictionary that maps HTML entity names to the Unicode code points. + A dictionary that maps HTML4 entity names to the Unicode code points. .. data:: codepoint2name - A dictionary that maps Unicode code points to HTML entity names. + A dictionary that maps Unicode code points to HTML4 entity names. .. rubric:: Footnotes diff --git a/Doc/library/html.parser.rst b/Doc/library/html.parser.rst index 03aff25c..d3509011 100644 --- a/Doc/library/html.parser.rst +++ b/Doc/library/html.parser.rst @@ -173,7 +173,7 @@ implementations do nothing (except for :meth:`~HTMLParser.handle_startendtag`): .. method:: HTMLParser.handle_charref(name) This method is called to process decimal and hexadecimal numeric character - references of the form ``&#NNN;`` and ``&#xNNN;``. For example, the decimal + references of the form :samp:`&#{NNN};` and :samp:`&#x{NNN};`. For example, the decimal equivalent for ``>`` is ``>``, whereas the hexadecimal is ``>``; in this case the method will receive ``'62'`` or ``'x3E'``. This method is never called if *convert_charrefs* is ``True``. diff --git a/Doc/library/http.client.rst b/Doc/library/http.client.rst index 06f92510..c46314fc 100644 --- a/Doc/library/http.client.rst +++ b/Doc/library/http.client.rst @@ -10,7 +10,7 @@ pair: HTTP; protocol single: HTTP; http.client (standard module) -.. index:: module: urllib.request +.. index:: pair: module; urllib.request -------------- @@ -20,7 +20,7 @@ HTTPS protocols. It is normally not used directly --- the module .. seealso:: - The `Requests package <https://requests.readthedocs.io/en/master/>`_ + The `Requests package <https://requests.readthedocs.io/en/latest/>`_ is recommended for a higher-level HTTP client interface. .. note:: @@ -67,10 +67,9 @@ The module provides the following classes: *blocksize* parameter was added. -.. class:: HTTPSConnection(host, port=None, key_file=None, \ - cert_file=None[, timeout], \ - source_address=None, *, context=None, \ - check_hostname=None, blocksize=8192) +.. class:: HTTPSConnection(host, port=None, *[, timeout], \ + source_address=None, context=None, \ + blocksize=8192) A subclass of :class:`HTTPConnection` that uses SSL for communication with secure servers. Default port is ``443``. If *context* is specified, it @@ -84,7 +83,7 @@ The module provides the following classes: .. versionchanged:: 3.2 This class now supports HTTPS virtual hosts if possible (that is, - if :data:`ssl.HAS_SNI` is true). + if :const:`ssl.HAS_SNI` is true). .. versionchanged:: 3.4 The *strict* parameter was removed. HTTP 0.9-style "Simple Responses" are @@ -106,16 +105,9 @@ The module provides the following classes: ``http/1.1`` when no *context* is given. Custom *context* should set ALPN protocols with :meth:`~ssl.SSLContext.set_alpn_protocol`. - .. deprecated:: 3.6 - - *key_file* and *cert_file* are deprecated in favor of *context*. - Please use :meth:`ssl.SSLContext.load_cert_chain` instead, or let - :func:`ssl.create_default_context` select the system's trusted CA - certificates for you. - - The *check_hostname* parameter is also deprecated; the - :attr:`ssl.SSLContext.check_hostname` attribute of *context* should - be used instead. + .. versionchanged:: 3.12 + The deprecated *key_file*, *cert_file* and *check_hostname* parameters + have been removed. .. class:: HTTPResponse(sock, debuglevel=0, method=None, url=None) @@ -262,7 +254,10 @@ HTTPConnection Objects encode_chunked=False) This will send a request to the server using the HTTP request - method *method* and the selector *url*. + method *method* and the request URI *url*. The provided *url* must be + an absolute path to conform with :rfc:`RFC 2616 §5.1.2 <2616#section-5.1.2>` + (unless connecting to an HTTP proxy server or using the ``OPTIONS`` or + ``CONNECT`` methods). If *body* is specified, the specified data is sent after the headers are finished. It may be a :class:`str`, a :term:`bytes-like object`, an @@ -277,7 +272,10 @@ HTTPConnection Objects iterable are sent as is until the iterable is exhausted. The *headers* argument should be a mapping of extra HTTP headers to send - with the request. + with the request. A :rfc:`Host header <2616#section-14.23>` + must be provided to conform with :rfc:`RFC 2616 §5.1.2 <2616#section-5.1.2>` + (unless connecting to an HTTP proxy server or using the ``OPTIONS`` or + ``CONNECT`` methods). If *headers* contains neither Content-Length nor Transfer-Encoding, but there is a request body, one of those @@ -296,6 +294,16 @@ HTTPConnection Objects HTTPConnection object assumes that all encoding is handled by the calling code. If it is ``True``, the body will be chunk-encoded. + For example, to perform a ``GET`` request to ``https://docs.python.org/3/``:: + + >>> import http.client + >>> host = "docs.python.org" + >>> conn = http.client.HTTPSConnection(host) + >>> conn.request("GET", "/3/", headers={"Host": host}) + >>> response = conn.getresponse() + >>> print(response.status, response.reason) + 200 OK + .. note:: Chunked transfer encoding has been added to the HTTP protocol version 1.1. Unless the HTTP server is known to handle HTTP 1.1, @@ -344,13 +352,20 @@ HTTPConnection Objects Set the host and the port for HTTP Connect Tunnelling. This allows running the connection through a proxy server. - The host and port arguments specify the endpoint of the tunneled connection + The *host* and *port* arguments specify the endpoint of the tunneled connection (i.e. the address included in the CONNECT request, *not* the address of the proxy server). - The headers argument should be a mapping of extra HTTP headers to send with + The *headers* argument should be a mapping of extra HTTP headers to send with the CONNECT request. + As HTTP/1.1 is used for HTTP CONNECT tunnelling request, `as per the RFC + <https://datatracker.ietf.org/doc/html/rfc7231#section-4.3.6>`_, a HTTP ``Host:`` + header must be provided, matching the authority-form of the request target + provided as the destination for the CONNECT request. If a HTTP ``Host:`` + header is not provided via the headers argument, one is generated and + transmitted automatically. + For example, to tunnel through a HTTPS proxy server running locally on port 8080, we would pass the address of the proxy to the :class:`HTTPSConnection` constructor, and the address of the host that we eventually want to reach to @@ -363,6 +378,22 @@ HTTPConnection Objects .. versionadded:: 3.2 + .. versionchanged:: 3.12 + HTTP CONNECT tunnelling requests use protocol HTTP/1.1, upgraded from + protocol HTTP/1.0. ``Host:`` HTTP headers are mandatory for HTTP/1.1, so + one will be automatically generated and transmitted if not provided in + the headers argument. + + +.. method:: HTTPConnection.get_proxy_response_headers() + + Returns a dictionary with the headers of the response received from + the proxy server to the CONNECT request. + + If the CONNECT request was not sent, the method returns ``None``. + + .. versionadded:: 3.12 + .. method:: HTTPConnection.connect() @@ -530,7 +561,7 @@ statement. .. deprecated:: 3.9 Deprecated in favor of :attr:`~HTTPResponse.headers`. -.. method:: HTTPResponse.getstatus() +.. method:: HTTPResponse.getcode() .. deprecated:: 3.9 Deprecated in favor of :attr:`~HTTPResponse.status`. diff --git a/Doc/library/http.rst b/Doc/library/http.rst index bd9dcf68..5e191271 100644 --- a/Doc/library/http.rst +++ b/Doc/library/http.rst @@ -137,6 +137,31 @@ equal to the constant name (i.e. ``http.HTTPStatus.OK`` is also available as .. versionadded:: 3.9 Added ``103 EARLY_HINTS``, ``418 IM_A_TEAPOT`` and ``425 TOO_EARLY`` status codes. +HTTP status category +-------------------- + +.. versionadded:: 3.12 + +The enum values have several properties to indicate the HTTP status category: + +==================== ======================== =============================== +Property Indicates that Details +==================== ======================== =============================== +``is_informational`` ``100 <= status <= 199`` HTTP/1.1 :rfc:`7231`, Section 6 +``is_success`` ``200 <= status <= 299`` HTTP/1.1 :rfc:`7231`, Section 6 +``is_redirection`` ``300 <= status <= 399`` HTTP/1.1 :rfc:`7231`, Section 6 +``is_client_error`` ``400 <= status <= 499`` HTTP/1.1 :rfc:`7231`, Section 6 +``is_server_error`` ``500 <= status <= 599`` HTTP/1.1 :rfc:`7231`, Section 6 +==================== ======================== =============================== + + Usage:: + + >>> from http import HTTPStatus + >>> HTTPStatus.OK.is_success + True + >>> HTTPStatus.OK.is_client_error + False + .. class:: HTTPMethod .. versionadded:: 3.11 diff --git a/Doc/library/http.server.rst b/Doc/library/http.server.rst index 6a564400..f9b9425b 100644 --- a/Doc/library/http.server.rst +++ b/Doc/library/http.server.rst @@ -217,7 +217,7 @@ provides three different variants: attribute holds the default values for *message* and *explain* that will be used if no value is provided; for unknown codes the default value for both is the string ``???``. The body will be empty if the method is - HEAD or the response code is one of the following: ``1xx``, + HEAD or the response code is one of the following: :samp:`1{xx}`, ``204 No Content``, ``205 Reset Content``, ``304 Not Modified``. .. versionchanged:: 3.4 @@ -413,6 +413,11 @@ the current directory:: print("serving at port", PORT) httpd.serve_forever() + +:class:`SimpleHTTPRequestHandler` can also be subclassed to enhance behavior, +such as using different index file names by overriding the class attribute +:attr:`index_pages`. + .. _http-server-cli: :mod:`http.server` can also be invoked directly using the :option:`-m` @@ -519,5 +524,5 @@ default :class:`BaseHTTPRequestHandler` ``.log_message`` implementation. This could allow remote clients connecting to your server to send nefarious control codes to your terminal. -.. versionadded:: 3.11.1 +.. versionadded:: 3.12 Control characters are scrubbed in stderr logs. diff --git a/Doc/library/idle.rst b/Doc/library/idle.rst index 3058bcea..3211da50 100644 --- a/Doc/library/idle.rst +++ b/Doc/library/idle.rst @@ -479,7 +479,7 @@ Search and Replace Any selection becomes a search target. However, only selections within a line work because searches are only performed within lines with the -terminal newline removed. If ``[x] Regular expresion`` is checked, the +terminal newline removed. If ``[x] Regular expression`` is checked, the target is interpreted according to the Python re module. .. _completions: diff --git a/Doc/library/imaplib.rst b/Doc/library/imaplib.rst index 0c10e7af..1f774e64 100644 --- a/Doc/library/imaplib.rst +++ b/Doc/library/imaplib.rst @@ -84,8 +84,8 @@ Three exceptions are defined as attributes of the :class:`IMAP4` class: There's also a subclass for secure connections: -.. class:: IMAP4_SSL(host='', port=IMAP4_SSL_PORT, keyfile=None, \ - certfile=None, ssl_context=None, timeout=None) +.. class:: IMAP4_SSL(host='', port=IMAP4_SSL_PORT, *, ssl_context=None, \ + timeout=None) This is a subclass derived from :class:`IMAP4` that connects over an SSL encrypted socket (to use this class you need a socket module that was compiled @@ -96,12 +96,6 @@ There's also a subclass for secure connections: (potentially long-lived) structure. Please read :ref:`ssl-security` for best practices. - *keyfile* and *certfile* are a legacy alternative to *ssl_context* - they - can point to PEM-formatted private key and certificate chain files for - the SSL connection. Note that the *keyfile*/*certfile* parameters are - mutually exclusive with *ssl_context*, a :class:`ValueError` is raised - if *keyfile*/*certfile* is provided along with *ssl_context*. - The optional *timeout* parameter specifies a timeout in seconds for the connection attempt. If timeout is not given or is None, the global default socket timeout is used. @@ -112,18 +106,14 @@ There's also a subclass for secure connections: .. versionchanged:: 3.4 The class now supports hostname check with :attr:`ssl.SSLContext.check_hostname` and *Server Name Indication* (see - :data:`ssl.HAS_SNI`). - - .. deprecated:: 3.6 - - *keyfile* and *certfile* are deprecated in favor of *ssl_context*. - Please use :meth:`ssl.SSLContext.load_cert_chain` instead, or let - :func:`ssl.create_default_context` select the system's trusted CA - certificates for you. + :const:`ssl.HAS_SNI`). .. versionchanged:: 3.9 The optional *timeout* parameter was added. + .. versionchanged:: 3.12 + The deprecated *keyfile* and *certfile* parameters have been removed. + The second subclass allows for connections created by a child process: @@ -187,7 +177,7 @@ IMAP4 Objects ------------- All IMAP4rev1 commands are represented by methods of the same name, either -upper-case or lower-case. +uppercase or lowercase. All arguments to commands are converted to strings, except for ``AUTHENTICATE``, and the last argument to ``APPEND`` which is passed as an IMAP4 literal. If @@ -513,7 +503,7 @@ An :class:`IMAP4` instance has the following methods: .. versionchanged:: 3.4 The method now supports hostname check with :attr:`ssl.SSLContext.check_hostname` and *Server Name Indication* (see - :data:`ssl.HAS_SNI`). + :const:`ssl.HAS_SNI`). .. method:: IMAP4.status(mailbox, names) @@ -564,7 +554,7 @@ An :class:`IMAP4` instance has the following methods: ``search``, the searching *charset* argument is mandatory. There is also a ``uid thread`` command which corresponds to ``thread`` the way that ``uid search`` corresponds to ``search``. The ``thread`` command first searches the - mailbox for messages that match the given searching criteria using the charset + mailbox for messages that match the given searching criteria using the *charset* argument for the interpretation of strings in the searching criteria. It then returns the matching messages threaded according to the specified threading algorithm. diff --git a/Doc/library/imghdr.rst b/Doc/library/imghdr.rst index 318fe650..630fd701 100644 --- a/Doc/library/imghdr.rst +++ b/Doc/library/imghdr.rst @@ -21,8 +21,8 @@ The :mod:`imghdr` module defines the following function: .. function:: what(file, h=None) - Tests the image data contained in the file named by *file*, and returns a - string describing the image type. If optional *h* is provided, the *file* + Test the image data contained in the file named *file* and return a + string describing the image type. If *h* is provided, the *file* argument is ignored and *h* is assumed to contain the byte stream to test. .. versionchanged:: 3.6 diff --git a/Doc/library/imp.rst b/Doc/library/imp.rst deleted file mode 100644 index 000793a7..00000000 --- a/Doc/library/imp.rst +++ /dev/null @@ -1,411 +0,0 @@ -:mod:`imp` --- Access the :ref:`import <importsystem>` internals -================================================================ - -.. module:: imp - :synopsis: Access the implementation of the import statement. - :deprecated: - -**Source code:** :source:`Lib/imp.py` - -.. deprecated-removed:: 3.4 3.12 - The :mod:`imp` module is deprecated in favor of :mod:`importlib`. - -.. index:: statement: import - --------------- - -This module provides an interface to the mechanisms used to implement the -:keyword:`import` statement. It defines the following constants and functions: - - -.. function:: get_magic() - - .. index:: pair: file; byte-code - - Return the magic string value used to recognize byte-compiled code files - (:file:`.pyc` files). (This value may be different for each Python version.) - - .. deprecated:: 3.4 - Use :attr:`importlib.util.MAGIC_NUMBER` instead. - - -.. function:: get_suffixes() - - Return a list of 3-element tuples, each describing a particular type of - module. Each triple has the form ``(suffix, mode, type)``, where *suffix* is - a string to be appended to the module name to form the filename to search - for, *mode* is the mode string to pass to the built-in :func:`open` function - to open the file (this can be ``'r'`` for text files or ``'rb'`` for binary - files), and *type* is the file type, which has one of the values - :const:`PY_SOURCE`, :const:`PY_COMPILED`, or :const:`C_EXTENSION`, described - below. - - .. deprecated:: 3.3 - Use the constants defined on :mod:`importlib.machinery` instead. - - -.. function:: find_module(name[, path]) - - Try to find the module *name*. If *path* is omitted or ``None``, the list of - directory names given by ``sys.path`` is searched, but first a few special - places are searched: the function tries to find a built-in module with the - given name (:const:`C_BUILTIN`), then a frozen module (:const:`PY_FROZEN`), - and on some systems some other places are looked in as well (on Windows, it - looks in the registry which may point to a specific file). - - Otherwise, *path* must be a list of directory names; each directory is - searched for files with any of the suffixes returned by :func:`get_suffixes` - above. Invalid names in the list are silently ignored (but all list items - must be strings). - - If search is successful, the return value is a 3-element tuple ``(file, - pathname, description)``: - - *file* is an open :term:`file object` positioned at the beginning, *pathname* - is the pathname of the file found, and *description* is a 3-element tuple as - contained in the list returned by :func:`get_suffixes` describing the kind of - module found. - - If the module is built-in or frozen then *file* and *pathname* are both ``None`` - and the *description* tuple contains empty strings for its suffix and mode; - the module type is indicated as given in parentheses above. If the search - is unsuccessful, :exc:`ImportError` is raised. Other exceptions indicate - problems with the arguments or environment. - - If the module is a package, *file* is ``None``, *pathname* is the package - path and the last item in the *description* tuple is :const:`PKG_DIRECTORY`. - - This function does not handle hierarchical module names (names containing - dots). In order to find *P.M*, that is, submodule *M* of package *P*, use - :func:`find_module` and :func:`load_module` to find and load package *P*, and - then use :func:`find_module` with the *path* argument set to ``P.__path__``. - When *P* itself has a dotted name, apply this recipe recursively. - - .. deprecated:: 3.3 - Use :func:`importlib.util.find_spec` instead unless Python 3.3 - compatibility is required, in which case use - :func:`importlib.find_loader`. For example usage of the former case, - see the :ref:`importlib-examples` section of the :mod:`importlib` - documentation. - - -.. function:: load_module(name, file, pathname, description) - - Load a module that was previously found by :func:`find_module` (or by an - otherwise conducted search yielding compatible results). This function does - more than importing the module: if the module was already imported, it will - reload the module! The *name* argument indicates the full - module name (including the package name, if this is a submodule of a - package). The *file* argument is an open file, and *pathname* is the - corresponding file name; these can be ``None`` and ``''``, respectively, when - the module is a package or not being loaded from a file. The *description* - argument is a tuple, as would be returned by :func:`get_suffixes`, describing - what kind of module must be loaded. - - If the load is successful, the return value is the module object; otherwise, - an exception (usually :exc:`ImportError`) is raised. - - **Important:** the caller is responsible for closing the *file* argument, if - it was not ``None``, even when an exception is raised. This is best done - using a :keyword:`try` ... :keyword:`finally` statement. - - .. deprecated:: 3.3 - If previously used in conjunction with :func:`imp.find_module` then - consider using :func:`importlib.import_module`, otherwise use the loader - returned by the replacement you chose for :func:`imp.find_module`. If you - called :func:`imp.load_module` and related functions directly with file - path arguments then use a combination of - :func:`importlib.util.spec_from_file_location` and - :func:`importlib.util.module_from_spec`. See the :ref:`importlib-examples` - section of the :mod:`importlib` documentation for details of the various - approaches. - - -.. function:: new_module(name) - - Return a new empty module object called *name*. This object is *not* inserted - in ``sys.modules``. - - .. deprecated:: 3.4 - Use :func:`importlib.util.module_from_spec` instead. - - -.. function:: reload(module) - - Reload a previously imported *module*. The argument must be a module object, so - it must have been successfully imported before. This is useful if you have - edited the module source file using an external editor and want to try out the - new version without leaving the Python interpreter. The return value is the - module object (the same as the *module* argument). - - When ``reload(module)`` is executed: - - * Python modules' code is recompiled and the module-level code reexecuted, - defining a new set of objects which are bound to names in the module's - dictionary. The ``init`` function of extension modules is not called a second - time. - - * As with all other objects in Python the old objects are only reclaimed after - their reference counts drop to zero. - - * The names in the module namespace are updated to point to any new or changed - objects. - - * Other references to the old objects (such as names external to the module) are - not rebound to refer to the new objects and must be updated in each namespace - where they occur if that is desired. - - There are a number of other caveats: - - When a module is reloaded, its dictionary (containing the module's global - variables) is retained. Redefinitions of names will override the old - definitions, so this is generally not a problem. If the new version of a module - does not define a name that was defined by the old version, the old definition - remains. This feature can be used to the module's advantage if it maintains a - global table or cache of objects --- with a :keyword:`try` statement it can test - for the table's presence and skip its initialization if desired:: - - try: - cache - except NameError: - cache = {} - - It is legal though generally not very useful to reload built-in or dynamically - loaded modules, except for :mod:`sys`, :mod:`__main__` and :mod:`builtins`. - In many cases, however, extension modules are not designed to be initialized - more than once, and may fail in arbitrary ways when reloaded. - - If a module imports objects from another module using :keyword:`from` ... - :keyword:`import` ..., calling :func:`reload` for the other module does not - redefine the objects imported from it --- one way around this is to re-execute - the :keyword:`!from` statement, another is to use :keyword:`!import` and qualified - names (*module*.*name*) instead. - - If a module instantiates instances of a class, reloading the module that defines - the class does not affect the method definitions of the instances --- they - continue to use the old class definition. The same is true for derived classes. - - .. versionchanged:: 3.3 - Relies on both ``__name__`` and ``__loader__`` being defined on the module - being reloaded instead of just ``__name__``. - - .. deprecated:: 3.4 - Use :func:`importlib.reload` instead. - - -The following functions are conveniences for handling :pep:`3147` byte-compiled -file paths. - -.. versionadded:: 3.2 - -.. function:: cache_from_source(path, debug_override=None) - - Return the :pep:`3147` path to the byte-compiled file associated with the - source *path*. For example, if *path* is ``/foo/bar/baz.py`` the return - value would be ``/foo/bar/__pycache__/baz.cpython-32.pyc`` for Python 3.2. - The ``cpython-32`` string comes from the current magic tag (see - :func:`get_tag`; if :attr:`sys.implementation.cache_tag` is not defined then - :exc:`NotImplementedError` will be raised). By passing in ``True`` or - ``False`` for *debug_override* you can override the system's value for - ``__debug__``, leading to optimized bytecode. - - *path* need not exist. - - .. versionchanged:: 3.3 - If :attr:`sys.implementation.cache_tag` is ``None``, then - :exc:`NotImplementedError` is raised. - - .. deprecated:: 3.4 - Use :func:`importlib.util.cache_from_source` instead. - - .. versionchanged:: 3.5 - The *debug_override* parameter no longer creates a ``.pyo`` file. - - -.. function:: source_from_cache(path) - - Given the *path* to a :pep:`3147` file name, return the associated source code - file path. For example, if *path* is - ``/foo/bar/__pycache__/baz.cpython-32.pyc`` the returned path would be - ``/foo/bar/baz.py``. *path* need not exist, however if it does not conform - to :pep:`3147` format, a :exc:`ValueError` is raised. If - :attr:`sys.implementation.cache_tag` is not defined, - :exc:`NotImplementedError` is raised. - - .. versionchanged:: 3.3 - Raise :exc:`NotImplementedError` when - :attr:`sys.implementation.cache_tag` is not defined. - - .. deprecated:: 3.4 - Use :func:`importlib.util.source_from_cache` instead. - - -.. function:: get_tag() - - Return the :pep:`3147` magic tag string matching this version of Python's - magic number, as returned by :func:`get_magic`. - - .. deprecated:: 3.4 - Use :attr:`sys.implementation.cache_tag` directly starting - in Python 3.3. - - -The following functions help interact with the import system's internal -locking mechanism. Locking semantics of imports are an implementation -detail which may vary from release to release. However, Python ensures -that circular imports work without any deadlocks. - - -.. function:: lock_held() - - Return ``True`` if the global import lock is currently held, else - ``False``. On platforms without threads, always return ``False``. - - On platforms with threads, a thread executing an import first holds a - global import lock, then sets up a per-module lock for the rest of the - import. This blocks other threads from importing the same module until - the original import completes, preventing other threads from seeing - incomplete module objects constructed by the original thread. An - exception is made for circular imports, which by construction have to - expose an incomplete module object at some point. - - .. versionchanged:: 3.3 - The locking scheme has changed to per-module locks for - the most part. A global import lock is kept for some critical tasks, - such as initializing the per-module locks. - - .. deprecated:: 3.4 - - -.. function:: acquire_lock() - - Acquire the interpreter's global import lock for the current thread. - This lock should be used by import hooks to ensure thread-safety when - importing modules. - - Once a thread has acquired the import lock, the same thread may acquire it - again without blocking; the thread must release it once for each time it has - acquired it. - - On platforms without threads, this function does nothing. - - .. versionchanged:: 3.3 - The locking scheme has changed to per-module locks for - the most part. A global import lock is kept for some critical tasks, - such as initializing the per-module locks. - - .. deprecated:: 3.4 - - -.. function:: release_lock() - - Release the interpreter's global import lock. On platforms without - threads, this function does nothing. - - .. versionchanged:: 3.3 - The locking scheme has changed to per-module locks for - the most part. A global import lock is kept for some critical tasks, - such as initializing the per-module locks. - - .. deprecated:: 3.4 - - -The following constants with integer values, defined in this module, are used -to indicate the search result of :func:`find_module`. - - -.. data:: PY_SOURCE - - The module was found as a source file. - - .. deprecated:: 3.3 - - -.. data:: PY_COMPILED - - The module was found as a compiled code object file. - - .. deprecated:: 3.3 - - -.. data:: C_EXTENSION - - The module was found as dynamically loadable shared library. - - .. deprecated:: 3.3 - - -.. data:: PKG_DIRECTORY - - The module was found as a package directory. - - .. deprecated:: 3.3 - - -.. data:: C_BUILTIN - - The module was found as a built-in module. - - .. deprecated:: 3.3 - - -.. data:: PY_FROZEN - - The module was found as a frozen module. - - .. deprecated:: 3.3 - - -.. class:: NullImporter(path_string) - - The :class:`NullImporter` type is a :pep:`302` import hook that handles - non-directory path strings by failing to find any modules. Calling this type - with an existing directory or empty string raises :exc:`ImportError`. - Otherwise, a :class:`NullImporter` instance is returned. - - Instances have only one method: - - .. method:: NullImporter.find_module(fullname [, path]) - - This method always returns ``None``, indicating that the requested module could - not be found. - - .. versionchanged:: 3.3 - ``None`` is inserted into ``sys.path_importer_cache`` instead of an - instance of :class:`NullImporter`. - - .. deprecated:: 3.4 - Insert ``None`` into ``sys.path_importer_cache`` instead. - - -.. _examples-imp: - -Examples --------- - -The following function emulates what was the standard import statement up to -Python 1.4 (no hierarchical module names). (This *implementation* wouldn't work -in that version, since :func:`find_module` has been extended and -:func:`load_module` has been added in 1.4.) :: - - import imp - import sys - - def __import__(name, globals=None, locals=None, fromlist=None): - # Fast path: see if the module has already been imported. - try: - return sys.modules[name] - except KeyError: - pass - - # If any of the following calls raises an exception, - # there's a problem we can't handle -- let the caller handle it. - - fp, pathname, description = imp.find_module(name) - - try: - return imp.load_module(name, fp, pathname, description) - finally: - # Since we may exit via an exception, close fp explicitly. - if fp: - fp.close() diff --git a/Doc/library/importlib.metadata.rst b/Doc/library/importlib.metadata.rst index 57991779..d2cc769e 100644 --- a/Doc/library/importlib.metadata.rst +++ b/Doc/library/importlib.metadata.rst @@ -1,11 +1,11 @@ .. _using: -================================= - Using :mod:`!importlib.metadata` -================================= +======================================================== +:mod:`!importlib.metadata` -- Accessing package metadata +======================================================== .. module:: importlib.metadata - :synopsis: The implementation of the importlib metadata. + :synopsis: Accessing package metadata .. versionadded:: 3.8 .. versionchanged:: 3.10 @@ -13,7 +13,7 @@ **Source code:** :source:`Lib/importlib/metadata/__init__.py` -``importlib_metadata`` is a library that provides access to +``importlib.metadata`` is a library that provides access to the metadata of an installed `Distribution Package <https://packaging.python.org/en/latest/glossary/#term-Distribution-Package>`_, such as its entry points or its top-level names (`Import Package <https://packaging.python.org/en/latest/glossary/#term-Import-Package>`_\s, modules, if any). @@ -24,7 +24,7 @@ API`_ and `metadata API`_ of ``pkg_resources``. Along with this package can eliminate the need to use the older and less efficient ``pkg_resources`` package. -``importlib_metadata`` operates on third-party *distribution packages* +``importlib.metadata`` operates on third-party *distribution packages* installed into Python's ``site-packages`` directory via tools such as `pip <https://pypi.org/project/pip/>`_. Specifically, it works with distributions with discoverable @@ -73,7 +73,7 @@ something into it: .. code-block:: shell-session - $ python3 -m venv example + $ python -m venv example $ source example/bin/activate (example) $ python -m pip install wheel @@ -176,11 +176,10 @@ for more information on entry points, their definition, and usage. The "selectable" entry points were introduced in ``importlib_metadata`` 3.6 and Python 3.10. Prior to those changes, ``entry_points`` accepted no parameters and always returned a dictionary of entry points, keyed -by group. For compatibility, if no parameters are passed to entry_points, -a ``SelectableGroups`` object is returned, implementing that dict -interface. In the future, calling ``entry_points`` with no parameters -will return an ``EntryPoints`` object. Users should rely on the selection -interface to retrieve entry points by group. +by group. With ``importlib_metadata`` 5.0 and Python 3.12, +``entry_points`` always returns an ``EntryPoints`` object. See +`backports.entry_points_selectable <https://pypi.org/project/backports.entry-points-selectable>`_ +for compatibility options. .. _metadata: @@ -309,6 +308,10 @@ Python module or `Import Package <https://packaging.python.org/en/latest/glossar >>> packages_distributions() {'importlib_metadata': ['importlib-metadata'], 'yaml': ['PyYAML'], 'jaraco': ['jaraco.classes', 'jaraco.functools'], ...} +Some editable installs, `do not supply top-level names +<https://github.com/pypa/packaging-problems/issues/609>`_, and thus this +function is not reliable with such installs. + .. versionadded:: 3.10 .. _distributions: @@ -361,11 +364,11 @@ Because `Distribution Package <https://packaging.python.org/en/latest/glossary/# is not available through :data:`sys.path` searches, or package loaders directly, the metadata for a distribution is found through import -system `finders`_. To find a distribution package's metadata, +system :ref:`finders <finders-and-loaders>`. To find a distribution package's metadata, ``importlib.metadata`` queries the list of :term:`meta path finders <meta path finder>` on :data:`sys.meta_path`. -By default ``importlib_metadata`` installs a finder for distribution packages +By default ``importlib.metadata`` installs a finder for distribution packages found on the file system. This finder doesn't actually find any *distributions*, but it can find their metadata. @@ -397,4 +400,3 @@ a custom finder, return instances of this derived ``Distribution`` in the .. _`entry point API`: https://setuptools.readthedocs.io/en/latest/pkg_resources.html#entry-points .. _`metadata API`: https://setuptools.readthedocs.io/en/latest/pkg_resources.html#metadata-api -.. _`finders`: https://docs.python.org/3/reference/import.html#finders-and-loaders diff --git a/Doc/library/importlib.resources.abc.rst b/Doc/library/importlib.resources.abc.rst index a028537f..c508b6ba 100644 --- a/Doc/library/importlib.resources.abc.rst +++ b/Doc/library/importlib.resources.abc.rst @@ -43,7 +43,8 @@ :const:`None`. An object compatible with this ABC should only be returned when the specified module is a package. - .. versionadded:: 3.7 + .. deprecated-removed:: 3.12 3.14 + Use :class:`importlib.resources.abc.TraversableResources` instead. .. abstractmethod:: open_resource(resource) @@ -86,10 +87,11 @@ .. class:: Traversable - An object with a subset of pathlib.Path methods suitable for + An object with a subset of :class:`pathlib.Path` methods suitable for traversing directories and opening files. - .. versionadded:: 3.9 + For a representation of the object on the file-system, use + :meth:`importlib.resources.as_file`. .. attribute:: name @@ -121,7 +123,7 @@ suitable for reading (same as :attr:`pathlib.Path.open`). When opening as text, accepts encoding parameters such as those - accepted by :attr:`io.TextIOWrapper`. + accepted by :class:`io.TextIOWrapper`. .. method:: read_bytes() @@ -136,16 +138,14 @@ An abstract base class for resource readers capable of serving the :meth:`importlib.resources.files` interface. Subclasses - :class:`importlib.resources.abc.ResourceReader` and provides - concrete implementations of the :class:`importlib.resources.abc.ResourceReader`'s + :class:`ResourceReader` and provides + concrete implementations of the :class:`!ResourceReader`'s abstract methods. Therefore, any loader supplying - :class:`importlib.abc.TraversableResources` also supplies ResourceReader. + :class:`!TraversableResources` also supplies :class:`!ResourceReader`. Loaders that wish to support resource reading are expected to implement this interface. - .. versionadded:: 3.9 - .. abstractmethod:: files() Returns a :class:`importlib.resources.abc.Traversable` object for the loaded diff --git a/Doc/library/importlib.resources.rst b/Doc/library/importlib.resources.rst index 827e7d8d..fecb7ef2 100644 --- a/Doc/library/importlib.resources.rst +++ b/Doc/library/importlib.resources.rst @@ -1,5 +1,5 @@ -:mod:`importlib.resources` -- Resources ---------------------------------------- +:mod:`importlib.resources` -- Package resource reading, opening and access +-------------------------------------------------------------------------- .. module:: importlib.resources :synopsis: Package resource reading, opening, and access @@ -11,9 +11,18 @@ .. versionadded:: 3.7 This module leverages Python's import system to provide access to *resources* -within *packages*. If you can import a package, you can access resources -within that package. Resources can be opened or read, in either binary or -text mode. +within *packages*. + +"Resources" are file-like resources associated with a module or package in +Python. The resources may be contained directly in a package, within a +subdirectory contained in that package, or adjacent to modules outside a +package. Resources may be text or binary. As a result, Python module sources +(.py) of a package and compilation artifacts (pycache) are technically +de-facto resources of that package. In practice, however, resources are +primarily those non-Python artifacts exposed specifically by the package +author. + +Resources can be opened or read in either binary or text mode. Resources are roughly akin to files inside directories, though it's important to keep in mind that this is just a metaphor. Resources and packages **do @@ -41,51 +50,75 @@ for example, a package and its resources can be imported from a zip file using ``get_resource_reader(fullname)`` method as specified by :class:`importlib.resources.abc.ResourceReader`. -.. data:: Package +.. data:: Anchor - Whenever a function accepts a ``Package`` argument, you can pass in - either a :class:`module object <types.ModuleType>` or a module name - as a string. You can only pass module objects whose - ``__spec__.submodule_search_locations`` is not ``None``. + Represents an anchor for resources, either a :class:`module object + <types.ModuleType>` or a module name as a string. Defined as + ``Union[str, ModuleType]``. - The ``Package`` type is defined as ``Union[str, ModuleType]``. - -.. function:: files(package) +.. function:: files(anchor: Optional[Anchor] = None) Returns a :class:`~importlib.resources.abc.Traversable` object - representing the resource container for the package (think directory) - and its resources (think files). A Traversable may contain other - containers (think subdirectories). + representing the resource container (think directory) and its resources + (think files). A Traversable may contain other containers (think + subdirectories). - *package* is either a name or a module object which conforms to the - :data:`Package` requirements. + *anchor* is an optional :data:`Anchor`. If the anchor is a + package, resources are resolved from that package. If a module, + resources are resolved adjacent to that module (in the same package + or the package root). If the anchor is omitted, the caller's module + is used. .. versionadded:: 3.9 + .. versionchanged:: 3.12 + "package" parameter was renamed to "anchor". "anchor" can now + be a non-package module and if omitted will default to the caller's + module. "package" is still accepted for compatibility but will raise + a DeprecationWarning. Consider passing the anchor positionally or + using ``importlib_resources >= 5.10`` for a compatible interface + on older Pythons. + .. function:: as_file(traversable) Given a :class:`~importlib.resources.abc.Traversable` object representing - a file, typically from :func:`importlib.resources.files`, return - a context manager for use in a :keyword:`with` statement. + a file or directory, typically from :func:`importlib.resources.files`, + return a context manager for use in a :keyword:`with` statement. The context manager provides a :class:`pathlib.Path` object. - Exiting the context manager cleans up any temporary file created when the - resource was extracted from e.g. a zip file. + Exiting the context manager cleans up any temporary file or directory + created when the resource was extracted from e.g. a zip file. Use ``as_file`` when the Traversable methods - (``read_text``, etc) are insufficient and an actual file on + (``read_text``, etc) are insufficient and an actual file or directory on the file system is required. .. versionadded:: 3.9 + .. versionchanged:: 3.12 + Added support for ``traversable`` representing a directory. + + Deprecated functions --------------------- +^^^^^^^^^^^^^^^^^^^^ An older, deprecated set of functions is still available, but is scheduled for removal in a future version of Python. The main drawback of these functions is that they do not support directories: they assume all resources are located directly within a *package*. +.. data:: Package + + Whenever a function accepts a ``Package`` argument, you can pass in + either a :class:`module object <types.ModuleType>` or a module name + as a string. You can only pass module objects whose + ``__spec__.submodule_search_locations`` is not ``None``. + + The ``Package`` type is defined as ``Union[str, ModuleType]``. + + .. deprecated:: 3.12 + + .. data:: Resource For *resource* arguments of the functions below, you can pass in @@ -94,6 +127,7 @@ directories: they assume all resources are located directly within a *package*. The ``Resource`` type is defined as ``Union[str, os.PathLike]``. + .. function:: open_binary(package, resource) Open for binary reading the *resource* within *package*. diff --git a/Doc/library/importlib.rst b/Doc/library/importlib.rst index c29d69c1..fc954724 100644 --- a/Doc/library/importlib.rst +++ b/Doc/library/importlib.rst @@ -127,28 +127,6 @@ Functions .. versionchanged:: 3.3 Parent packages are automatically imported. -.. function:: find_loader(name, path=None) - - Find the loader for a module, optionally within the specified *path*. If the - module is in :attr:`sys.modules`, then ``sys.modules[name].__loader__`` is - returned (unless the loader would be ``None`` or is not set, in which case - :exc:`ValueError` is raised). Otherwise a search using :attr:`sys.meta_path` - is done. ``None`` is returned if no loader is found. - - A dotted name does not have its parents implicitly imported as that requires - loading them and that may not be desired. To properly import a submodule you - will need to import all parent packages of the submodule and use the correct - argument to *path*. - - .. versionadded:: 3.3 - - .. versionchanged:: 3.4 - If ``__loader__`` is not set, raise :exc:`ValueError`, just like when the - attribute is set to ``None``. - - .. deprecated:: 3.4 - Use :func:`importlib.util.find_spec` instead. - .. function:: invalidate_caches() Invalidate the internal caches of finders stored at @@ -247,7 +225,6 @@ are also provided to help in implementing the core ABCs. ABC hierarchy:: object - +-- Finder (deprecated) +-- MetaPathFinder +-- PathEntryFinder +-- Loader @@ -258,28 +235,6 @@ ABC hierarchy:: +-- SourceLoader -.. class:: Finder - - An abstract base class representing a :term:`finder`. - - .. deprecated:: 3.3 - Use :class:`MetaPathFinder` or :class:`PathEntryFinder` instead. - - .. abstractmethod:: find_module(fullname, path=None) - - An abstract method for finding a :term:`loader` for the specified - module. Originally specified in :pep:`302`, this method was meant - for use in :data:`sys.meta_path` and in the path-based import subsystem. - - .. versionchanged:: 3.4 - Returns ``None`` when called instead of raising - :exc:`NotImplementedError`. - - .. deprecated:: 3.10 - Implement :meth:`MetaPathFinder.find_spec` or - :meth:`PathEntryFinder.find_spec` instead. - - .. class:: MetaPathFinder An abstract base class representing a :term:`meta path finder`. @@ -287,7 +242,7 @@ ABC hierarchy:: .. versionadded:: 3.3 .. versionchanged:: 3.10 - No longer a subclass of :class:`Finder`. + No longer a subclass of :class:`!Finder`. .. method:: find_spec(fullname, path, target=None) @@ -303,25 +258,6 @@ ABC hierarchy:: .. versionadded:: 3.4 - .. method:: find_module(fullname, path) - - A legacy method for finding a :term:`loader` for the specified - module. If this is a top-level import, *path* will be ``None``. - Otherwise, this is a search for a subpackage or module and *path* - will be the value of :attr:`__path__` from the parent - package. If a loader cannot be found, ``None`` is returned. - - If :meth:`find_spec` is defined, backwards-compatible functionality is - provided. - - .. versionchanged:: 3.4 - Returns ``None`` when called instead of raising - :exc:`NotImplementedError`. Can use :meth:`find_spec` to provide - functionality. - - .. deprecated:: 3.4 - Use :meth:`find_spec` instead. - .. method:: invalidate_caches() An optional method which, when called, should invalidate any internal @@ -342,7 +278,7 @@ ABC hierarchy:: .. versionadded:: 3.3 .. versionchanged:: 3.10 - No longer a subclass of :class:`Finder`. + No longer a subclass of :class:`!Finder`. .. method:: find_spec(fullname, target=None) @@ -356,36 +292,6 @@ ABC hierarchy:: .. versionadded:: 3.4 - .. method:: find_loader(fullname) - - A legacy method for finding a :term:`loader` for the specified - module. Returns a 2-tuple of ``(loader, portion)`` where ``portion`` - is a sequence of file system locations contributing to part of a namespace - package. The loader may be ``None`` while specifying ``portion`` to - signify the contribution of the file system locations to a namespace - package. An empty list can be used for ``portion`` to signify the loader - is not part of a namespace package. If ``loader`` is ``None`` and - ``portion`` is the empty list then no loader or location for a namespace - package were found (i.e. failure to find anything for the module). - - If :meth:`find_spec` is defined then backwards-compatible functionality is - provided. - - .. versionchanged:: 3.4 - Returns ``(None, [])`` instead of raising :exc:`NotImplementedError`. - Uses :meth:`find_spec` when available to provide functionality. - - .. deprecated:: 3.4 - Use :meth:`find_spec` instead. - - .. method:: find_module(fullname) - - A concrete implementation of :meth:`Finder.find_module` which is - equivalent to ``self.find_loader(fullname)[0]``. - - .. deprecated:: 3.4 - Use :meth:`find_spec` instead. - .. method:: invalidate_caches() An optional method which, when called, should invalidate any internal @@ -443,7 +349,7 @@ ABC hierarchy:: from the import. If the loader inserted a module and the load fails, it must be removed by the loader from :data:`sys.modules`; modules already in :data:`sys.modules` before the loader began execution should be left - alone (see :func:`importlib.util.module_for_loader`). + alone. The loader should set several attributes on the module (note that some of these attributes can change when a module is @@ -466,7 +372,7 @@ ABC hierarchy:: The list of locations where the package's submodules will be found. Most of the time this is a single directory. The import system passes this attribute to ``__import__()`` and to finders - in the same way as :attr:`sys.path` but just for the package. + in the same way as :data:`sys.path` but just for the package. It is not set on non-package modules so it can be used as an indicator that the module is a package. @@ -493,20 +399,6 @@ ABC hierarchy:: other responsibilities of :meth:`load_module` when :meth:`exec_module` is implemented. - .. method:: module_repr(module) - - A legacy method which when implemented calculates and returns the given - module's representation, as a string. The module type's default - :meth:`__repr__` will use the result of this method as appropriate. - - .. versionadded:: 3.3 - - .. versionchanged:: 3.4 - Made optional instead of an abstractmethod. - - .. deprecated:: 3.4 - The import machinery now takes care of this automatically. - .. class:: ResourceLoader @@ -717,7 +609,7 @@ ABC hierarchy:: automatically. When writing to the path fails because the path is read-only - (:attr:`errno.EACCES`/:exc:`PermissionError`), do not propagate the + (:const:`errno.EACCES`/:exc:`PermissionError`), do not propagate the exception. .. versionchanged:: 3.4 @@ -753,6 +645,160 @@ ABC hierarchy:: itself does not end in ``__init__``. +.. class:: ResourceReader + + *Superseded by TraversableResources* + + An :term:`abstract base class` to provide the ability to read + *resources*. + + From the perspective of this ABC, a *resource* is a binary + artifact that is shipped within a package. Typically this is + something like a data file that lives next to the ``__init__.py`` + file of the package. The purpose of this class is to help abstract + out the accessing of such data files so that it does not matter if + the package and its data file(s) are stored in a e.g. zip file + versus on the file system. + + For any of methods of this class, a *resource* argument is + expected to be a :term:`path-like object` which represents + conceptually just a file name. This means that no subdirectory + paths should be included in the *resource* argument. This is + because the location of the package the reader is for, acts as the + "directory". Hence the metaphor for directories and file + names is packages and resources, respectively. This is also why + instances of this class are expected to directly correlate to + a specific package (instead of potentially representing multiple + packages or a module). + + Loaders that wish to support resource reading are expected to + provide a method called ``get_resource_reader(fullname)`` which + returns an object implementing this ABC's interface. If the module + specified by fullname is not a package, this method should return + :const:`None`. An object compatible with this ABC should only be + returned when the specified module is a package. + + .. versionadded:: 3.7 + + .. deprecated-removed:: 3.12 3.14 + Use :class:`importlib.resources.abc.TraversableResources` instead. + + .. abstractmethod:: open_resource(resource) + + Returns an opened, :term:`file-like object` for binary reading + of the *resource*. + + If the resource cannot be found, :exc:`FileNotFoundError` is + raised. + + .. abstractmethod:: resource_path(resource) + + Returns the file system path to the *resource*. + + If the resource does not concretely exist on the file system, + raise :exc:`FileNotFoundError`. + + .. abstractmethod:: is_resource(name) + + Returns ``True`` if the named *name* is considered a resource. + :exc:`FileNotFoundError` is raised if *name* does not exist. + + .. abstractmethod:: contents() + + Returns an :term:`iterable` of strings over the contents of + the package. Do note that it is not required that all names + returned by the iterator be actual resources, e.g. it is + acceptable to return names for which :meth:`is_resource` would + be false. + + Allowing non-resource names to be returned is to allow for + situations where how a package and its resources are stored + are known a priori and the non-resource names would be useful. + For instance, returning subdirectory names is allowed so that + when it is known that the package and resources are stored on + the file system then those subdirectory names can be used + directly. + + The abstract method returns an iterable of no items. + + +.. class:: Traversable + + An object with a subset of :class:`pathlib.Path` methods suitable for + traversing directories and opening files. + + For a representation of the object on the file-system, use + :meth:`importlib.resources.as_file`. + + .. versionadded:: 3.9 + + .. deprecated-removed:: 3.12 3.14 + Use :class:`importlib.resources.abc.Traversable` instead. + + .. attribute:: name + + Abstract. The base name of this object without any parent references. + + .. abstractmethod:: iterdir() + + Yield ``Traversable`` objects in ``self``. + + .. abstractmethod:: is_dir() + + Return ``True`` if ``self`` is a directory. + + .. abstractmethod:: is_file() + + Return ``True`` if ``self`` is a file. + + .. abstractmethod:: joinpath(child) + + Return Traversable child in ``self``. + + .. abstractmethod:: __truediv__(child) + + Return ``Traversable`` child in ``self``. + + .. abstractmethod:: open(mode='r', *args, **kwargs) + + *mode* may be 'r' or 'rb' to open as text or binary. Return a handle + suitable for reading (same as :attr:`pathlib.Path.open`). + + When opening as text, accepts encoding parameters such as those + accepted by :attr:`io.TextIOWrapper`. + + .. method:: read_bytes() + + Read contents of ``self`` as bytes. + + .. method:: read_text(encoding=None) + + Read contents of ``self`` as text. + + +.. class:: TraversableResources + + An abstract base class for resource readers capable of serving + the :meth:`importlib.resources.files` interface. Subclasses + :class:`importlib.resources.abc.ResourceReader` and provides + concrete implementations of the :class:`importlib.resources.abc.ResourceReader`'s + abstract methods. Therefore, any loader supplying + :class:`importlib.abc.TraversableResources` also supplies ResourceReader. + + Loaders that wish to support resource reading are expected to + implement this interface. + + .. versionadded:: 3.9 + + .. deprecated-removed:: 3.12 3.14 + Use :class:`importlib.resources.abc.TraversableResources` instead. + + .. abstractmethod:: files() + + Returns a :class:`importlib.resources.abc.Traversable` object for the loaded + package. + + :mod:`importlib.machinery` -- Importers and path hooks ------------------------------------------------------ @@ -895,13 +941,6 @@ find and load modules. is no longer valid then ``None`` is returned but no value is cached in :data:`sys.path_importer_cache`. - .. classmethod:: find_module(fullname, path=None) - - A legacy wrapper around :meth:`find_spec`. - - .. deprecated:: 3.4 - Use :meth:`find_spec` instead. - .. classmethod:: invalidate_caches() Calls :meth:`importlib.abc.PathEntryFinder.invalidate_caches` on all @@ -952,20 +991,13 @@ find and load modules. .. versionadded:: 3.4 - .. method:: find_loader(fullname) - - Attempt to find the loader to handle *fullname* within :attr:`path`. - - .. deprecated:: 3.10 - Use :meth:`find_spec` instead. - .. method:: invalidate_caches() Clear out the internal cache. .. classmethod:: path_hook(*loader_details) - A class method which returns a closure for use on :attr:`sys.path_hooks`. + A class method which returns a closure for use on :data:`sys.path_hooks`. An instance of :class:`FileFinder` is returned by the closure using the path argument given to the closure directly and *loader_details* indirectly. @@ -1063,8 +1095,15 @@ find and load modules. The *fullname* argument specifies the name of the module the loader is to support. The *path* argument is the path to the extension module's file. + Note that, by default, importing an extension module will fail + in subinterpreters if it doesn't implement multi-phase init + (see :pep:`489`), even if it would otherwise import successfully. + .. versionadded:: 3.3 + .. versionchanged:: 3.12 + Multi-phase init is now required for use in subinterpreters. + .. attribute:: name Name of the module the loader supports. @@ -1306,10 +1345,10 @@ an :term:`importer`. .. function:: find_spec(name, package=None) Find the :term:`spec <module spec>` for a module, optionally relative to - the specified **package** name. If the module is in :attr:`sys.modules`, + the specified **package** name. If the module is in :data:`sys.modules`, then ``sys.modules[name].__spec__`` is returned (unless the spec would be ``None`` or is not set, in which case :exc:`ValueError` is raised). - Otherwise a search using :attr:`sys.meta_path` is done. ``None`` is + Otherwise a search using :data:`sys.meta_path` is done. ``None`` is returned if no spec is found. If **name** is for a submodule (contains a dot), the parent module is @@ -1340,67 +1379,6 @@ an :term:`importer`. .. versionadded:: 3.5 -.. decorator:: module_for_loader - - A :term:`decorator` for :meth:`importlib.abc.Loader.load_module` - to handle selecting the proper - module object to load with. The decorated method is expected to have a call - signature taking two positional arguments - (e.g. ``load_module(self, module)``) for which the second argument - will be the module **object** to be used by the loader. - Note that the decorator will not work on static methods because of the - assumption of two arguments. - - The decorated method will take in the **name** of the module to be loaded - as expected for a :term:`loader`. If the module is not found in - :data:`sys.modules` then a new one is constructed. Regardless of where the - module came from, :attr:`__loader__` set to **self** and :attr:`__package__` - is set based on what :meth:`importlib.abc.InspectLoader.is_package` returns - (if available). These attributes are set unconditionally to support - reloading. - - If an exception is raised by the decorated method and a module was added to - :data:`sys.modules`, then the module will be removed to prevent a partially - initialized module from being in left in :data:`sys.modules`. If the module - was already in :data:`sys.modules` then it is left alone. - - .. versionchanged:: 3.3 - :attr:`__loader__` and :attr:`__package__` are automatically set - (when possible). - - .. versionchanged:: 3.4 - Set :attr:`__name__`, :attr:`__loader__` :attr:`__package__` - unconditionally to support reloading. - - .. deprecated:: 3.4 - The import machinery now directly performs all the functionality - provided by this function. - -.. decorator:: set_loader - - A :term:`decorator` for :meth:`importlib.abc.Loader.load_module` - to set the :attr:`__loader__` - attribute on the returned module. If the attribute is already set the - decorator does nothing. It is assumed that the first positional argument to - the wrapped method (i.e. ``self``) is what :attr:`__loader__` should be set - to. - - .. versionchanged:: 3.4 - Set ``__loader__`` if set to ``None``, as if the attribute does not - exist. - - .. deprecated:: 3.4 - The import machinery takes care of this automatically. - -.. decorator:: set_package - - A :term:`decorator` for :meth:`importlib.abc.Loader.load_module` to set the - :attr:`__package__` attribute on the returned module. If :attr:`__package__` - is set and has a value other than ``None`` it will not be changed. - - .. deprecated:: 3.4 - The import machinery takes care of this automatically. - .. function:: spec_from_loader(name, loader, *, origin=None, is_package=None) A factory function for creating a :class:`~importlib.machinery.ModuleSpec` @@ -1431,6 +1409,30 @@ an :term:`importer`. .. versionadded:: 3.7 +.. function:: _incompatible_extension_module_restrictions(*, disable_check) + + A context manager that can temporarily skip the compatibility check + for extension modules. By default the check is enabled and will fail + when a single-phase init module is imported in a subinterpreter. + It will also fail for a multi-phase init module that doesn't + explicitly support a per-interpreter GIL, when imported + in an interpreter with its own GIL. + + Note that this function is meant to accommodate an unusual case; + one which is likely to eventually go away. There's is a pretty good + chance this is not what you were looking for. + + You can get the same effect as this function by implementing the + basic interface of multi-phase init (:pep:`489`) and lying about + support for multiple interpreters (or per-interpreter GIL). + + .. warning:: + Using this function to disable the check can lead to + unexpected behavior and even crashes. It should only be used during + extension module development. + + .. versionadded:: 3.12 + .. class:: LazyLoader(loader) A class which postpones the execution of the loader of a module until the @@ -1442,7 +1444,7 @@ an :term:`importer`. :meth:`~importlib.abc.Loader.create_module` method must return ``None`` or a type for which its ``__class__`` attribute can be mutated along with not using :term:`slots <__slots__>`. Finally, modules which substitute the object - placed into :attr:`sys.modules` will not work as there is no way to properly + placed into :data:`sys.modules` will not work as there is no way to properly replace the module references throughout the interpreter safely; :exc:`ValueError` is raised if such a substitution is detected. @@ -1462,7 +1464,7 @@ an :term:`importer`. .. classmethod:: factory(loader) - A static method which returns a callable that creates a lazy loader. This + A class method which returns a callable that creates a lazy loader. This is meant to be used in situations where the loader is passed by class instead of by instance. :: @@ -1566,9 +1568,9 @@ For deep customizations of import, you typically want to implement an :term:`importer`. This means managing both the :term:`finder` and :term:`loader` side of things. For finders there are two flavours to choose from depending on your needs: a :term:`meta path finder` or a :term:`path entry finder`. The -former is what you would put on :attr:`sys.meta_path` while the latter is what -you create using a :term:`path entry hook` on :attr:`sys.path_hooks` which works -with :attr:`sys.path` entries to potentially create a finder. This example will +former is what you would put on :data:`sys.meta_path` while the latter is what +you create using a :term:`path entry hook` on :data:`sys.path_hooks` which works +with :data:`sys.path` entries to potentially create a finder. This example will show you how to register your own importers so that import will use them (for creating an importer for yourself, read the documentation for the appropriate classes defined within this package):: diff --git a/Doc/library/inspect.rst b/Doc/library/inspect.rst index 9cb7a6f9..603ac326 100644 --- a/Doc/library/inspect.rst +++ b/Doc/library/inspect.rst @@ -343,8 +343,10 @@ attributes (see :ref:`import-mod-attrs` for module attributes): .. function:: iscoroutinefunction(object) - Return ``True`` if the object is a :term:`coroutine function` - (a function defined with an :keyword:`async def` syntax). + Return ``True`` if the object is a :term:`coroutine function` (a function + defined with an :keyword:`async def` syntax), a :func:`functools.partial` + wrapping a :term:`coroutine function`, or a sync function marked with + :func:`markcoroutinefunction`. .. versionadded:: 3.5 @@ -352,6 +354,25 @@ attributes (see :ref:`import-mod-attrs` for module attributes): Functions wrapped in :func:`functools.partial` now return ``True`` if the wrapped function is a :term:`coroutine function`. + .. versionchanged:: 3.12 + Sync functions marked with :func:`markcoroutinefunction` now return + ``True``. + + +.. function:: markcoroutinefunction(func) + + Decorator to mark a callable as a :term:`coroutine function` if it would not + otherwise be detected by :func:`iscoroutinefunction`. + + This may be of use for sync functions that return a :term:`coroutine`, if + the function is passed to an API that requires :func:`iscoroutinefunction`. + + When possible, using an :keyword:`async def` function is preferred. Also + acceptable is calling the function and testing the return with + :func:`iscoroutine`. + + .. versionadded:: 3.12 + .. function:: iscoroutine(object) @@ -553,6 +574,8 @@ Retrieving source code object and the line number indicates where in the original source file the first line of code was found. An :exc:`OSError` is raised if the source code cannot be retrieved. + A :exc:`TypeError` is raised if the object is a built-in module, class, or + function. .. versionchanged:: 3.3 :exc:`OSError` is raised instead of :exc:`IOError`, now an alias of the @@ -565,6 +588,8 @@ Retrieving source code class, method, function, traceback, frame, or code object. The source code is returned as a single string. An :exc:`OSError` is raised if the source code cannot be retrieved. + A :exc:`TypeError` is raised if the object is a built-in module, class, or + function. .. versionchanged:: 3.3 :exc:`OSError` is raised instead of :exc:`IOError`, now an alias of the @@ -668,7 +693,7 @@ function. modified copy. .. versionchanged:: 3.5 - Signature objects are picklable and hashable. + Signature objects are picklable and :term:`hashable`. .. attribute:: Signature.empty @@ -705,7 +730,7 @@ function. .. method:: Signature.replace(*[, parameters][, return_annotation]) - Create a new Signature instance based on the instance replace was invoked + Create a new Signature instance based on the instance :meth:`replace` was invoked on. It is possible to pass different ``parameters`` and/or ``return_annotation`` to override the corresponding properties of the base signature. To remove return_annotation from the copied Signature, pass in @@ -715,6 +740,7 @@ function. >>> def test(a, b): ... pass + ... >>> sig = signature(test) >>> new_sig = sig.replace(return_annotation="new return anno") >>> str(new_sig) @@ -746,7 +772,7 @@ function. you can use :meth:`Parameter.replace` to create a modified copy. .. versionchanged:: 3.5 - Parameter objects are picklable and hashable. + Parameter objects are picklable and :term:`hashable`. .. attribute:: Parameter.empty @@ -780,8 +806,9 @@ function. .. attribute:: Parameter.kind - Describes how argument values are bound to the parameter. Possible values - (accessible via :class:`Parameter`, like ``Parameter.KEYWORD_ONLY``): + Describes how argument values are bound to the parameter. The possible + values are accessible via :class:`Parameter` (like ``Parameter.KEYWORD_ONLY``), + and support comparison and ordering, in the following order: .. tabularcolumns:: |l|L| @@ -1054,6 +1081,7 @@ Classes and functions >>> from inspect import getcallargs >>> def f(a, b=1, *pos, **named): ... pass + ... >>> getcallargs(f, 1, 2, 3) == {'a': 1, 'named': {}, 'b': 2, 'pos': (3,)} True >>> getcallargs(f, a=2, x=4) == {'a': 2, 'named': {'x': 4}, 'b': 1, 'pos': ()} @@ -1416,8 +1444,8 @@ code execution:: pass -Current State of Generators and Coroutines ------------------------------------------- +Current State of Generators, Coroutines, and Asynchronous Generators +-------------------------------------------------------------------- When implementing coroutine schedulers and for other advanced uses of generators, it is useful to determine whether a generator is currently @@ -1452,6 +1480,22 @@ generator to be determined easily. .. versionadded:: 3.5 +.. function:: getasyncgenstate(agen) + + Get current state of an asynchronous generator object. The function is + intended to be used with asynchronous iterator objects created by + :keyword:`async def` functions which use the :keyword:`yield` statement, + but will accept any asynchronous generator-like object that has + ``ag_running`` and ``ag_frame`` attributes. + + Possible states are: + * AGEN_CREATED: Waiting to start execution. + * AGEN_RUNNING: Currently being executed by the interpreter. + * AGEN_SUSPENDED: Currently suspended at a yield expression. + * AGEN_CLOSED: Execution has completed. + + .. versionadded:: 3.12 + The current internal state of the generator can also be queried. This is mostly useful for testing purposes, to ensure that internal state is being updated as expected: @@ -1483,6 +1527,14 @@ updated as expected: .. versionadded:: 3.5 +.. function:: getasyncgenlocals(agen) + + This function is analogous to :func:`~inspect.getgeneratorlocals`, but + works for asynchronous generator objects created by :keyword:`async def` + functions which use the :keyword:`yield` statement. + + .. versionadded:: 3.12 + .. _inspect-module-co-flags: @@ -1551,6 +1603,39 @@ the following flags: for any introspection needs. +Buffer flags +------------ + +.. class:: BufferFlags + + This is an :class:`enum.IntFlag` that represents the flags that + can be passed to the :meth:`~object.__buffer__` method of objects + implementing the :ref:`buffer protocol <bufferobjects>`. + + The meaning of the flags is explained at :ref:`buffer-request-types`. + + .. attribute:: BufferFlags.SIMPLE + .. attribute:: BufferFlags.WRITABLE + .. attribute:: BufferFlags.FORMAT + .. attribute:: BufferFlags.ND + .. attribute:: BufferFlags.STRIDES + .. attribute:: BufferFlags.C_CONTIGUOUS + .. attribute:: BufferFlags.F_CONTIGUOUS + .. attribute:: BufferFlags.ANY_CONTIGUOUS + .. attribute:: BufferFlags.INDIRECT + .. attribute:: BufferFlags.CONTIG + .. attribute:: BufferFlags.CONTIG_RO + .. attribute:: BufferFlags.STRIDED + .. attribute:: BufferFlags.STRIDED_RO + .. attribute:: BufferFlags.RECORDS + .. attribute:: BufferFlags.RECORDS_RO + .. attribute:: BufferFlags.FULL + .. attribute:: BufferFlags.FULL_RO + .. attribute:: BufferFlags.READ + .. attribute:: BufferFlags.WRITE + + .. versionadded:: 3.12 + .. _inspect-module-cli: Command Line Interface diff --git a/Doc/library/internet.rst b/Doc/library/internet.rst index ff58dcf4..681769a4 100644 --- a/Doc/library/internet.rst +++ b/Doc/library/internet.rst @@ -9,7 +9,7 @@ Internet Protocols and Support single: Internet single: World Wide Web -.. index:: module: socket +.. index:: pair: module; socket The modules described in this chapter implement internet protocols and support for related technology. They are all implemented in Python. Most of these diff --git a/Doc/library/intro.rst b/Doc/library/intro.rst index 10209240..5a4c9b8b 100644 --- a/Doc/library/intro.rst +++ b/Doc/library/intro.rst @@ -114,7 +114,7 @@ DOM APIs as well as limited networking capabilities with JavaScript's .. _WebAssembly: https://webassembly.org/ .. _Emscripten: https://emscripten.org/ -.. _Emscripten Networking: https://emscripten.org/docs/porting/networking.html> +.. _Emscripten Networking: https://emscripten.org/docs/porting/networking.html .. _WASI: https://wasi.dev/ .. _wasmtime: https://wasmtime.dev/ .. _Pyodide: https://pyodide.org/ diff --git a/Doc/library/io.rst b/Doc/library/io.rst index c9249da1..01088879 100644 --- a/Doc/library/io.rst +++ b/Doc/library/io.rst @@ -38,9 +38,9 @@ location), or only sequential access (for example in the case of a socket or pipe). All streams are careful about the type of data you give to them. For example -giving a :class:`str` object to the ``write()`` method of a binary stream +giving a :class:`str` object to the :meth:`!write` method of a binary stream will raise a :exc:`TypeError`. So will giving a :class:`bytes` object to the -``write()`` method of a text stream. +:meth:`!write` method of a text stream. .. versionchanged:: 3.3 Operations that used to raise :exc:`IOError` now raise :exc:`OSError`, since @@ -146,7 +146,7 @@ Opt-in EncodingWarning See :pep:`597` for more details. To find where the default locale encoding is used, you can enable -the ``-X warn_default_encoding`` command line option or set the +the :option:`-X warn_default_encoding <-X>` command line option or set the :envvar:`PYTHONWARNDEFAULTENCODING` environment variable, which will emit an :exc:`EncodingWarning` when the default encoding is used. @@ -175,7 +175,7 @@ High-level Module Interface .. audit-event:: open path,mode,flags io.open This function raises an :ref:`auditing event <auditing>` ``open`` with - arguments ``path``, ``mode`` and ``flags``. The ``mode`` and ``flags`` + arguments *path*, *mode* and *flags*. The *mode* and *flags* arguments may have been modified or inferred from the original call. @@ -184,10 +184,10 @@ High-level Module Interface Opens the provided file with mode ``'rb'``. This function should be used when the intent is to treat the contents as executable code. - ``path`` should be a :class:`str` and an absolute path. + *path* should be a :class:`str` and an absolute path. The behavior of this function may be overridden by an earlier call to the - :c:func:`PyFile_SetOpenCodeHook`. However, assuming that ``path`` is a + :c:func:`PyFile_SetOpenCodeHook`. However, assuming that *path* is a :class:`str` and an absolute path, ``open_code(path)`` should always behave the same as ``open(path, 'rb')``. Overriding the behavior is intended for additional validation or preprocessing of the file. @@ -258,7 +258,7 @@ standard stream implementations. The abstract base classes also provide default implementations of some methods in order to help implementation of concrete stream classes. For example, :class:`BufferedIOBase` provides unoptimized implementations of - :meth:`~IOBase.readinto` and :meth:`~IOBase.readline`. + :meth:`!readinto` and :meth:`!readline`. At the top of the I/O hierarchy is the abstract base class :class:`IOBase`. It defines the basic interface to a stream. Note, however, that there is no @@ -320,8 +320,8 @@ I/O Base Classes implementations represent a file that cannot be read, written or seeked. - Even though :class:`IOBase` does not declare :meth:`read` - or :meth:`write` because their signatures will vary, implementations and + Even though :class:`IOBase` does not declare :meth:`!read` + or :meth:`!write` because their signatures will vary, implementations and clients should consider those methods part of the interface. Also, implementations may raise a :exc:`ValueError` (or :exc:`UnsupportedOperation`) when operations they do not support are called. @@ -379,8 +379,8 @@ I/O Base Classes .. method:: readable() - Return ``True`` if the stream can be read from. If ``False``, :meth:`read` - will raise :exc:`OSError`. + Return ``True`` if the stream can be read from. + If ``False``, :meth:`!read` will raise :exc:`OSError`. .. method:: readline(size=-1, /) @@ -401,29 +401,28 @@ I/O Base Classes hint. Note that it's already possible to iterate on file objects using ``for - line in file: ...`` without calling ``file.readlines()``. + line in file: ...`` without calling :meth:`!file.readlines`. - .. method:: seek(offset, whence=SEEK_SET, /) + .. method:: seek(offset, whence=os.SEEK_SET, /) - Change the stream position to the given byte *offset*. *offset* is - interpreted relative to the position indicated by *whence*. The default - value for *whence* is :data:`SEEK_SET`. Values for *whence* are: + Change the stream position to the given byte *offset*, + interpreted relative to the position indicated by *whence*, + and return the new absolute position. + Values for *whence* are: - * :data:`SEEK_SET` or ``0`` -- start of the stream (the default); + * :data:`os.SEEK_SET` or ``0`` -- start of the stream (the default); *offset* should be zero or positive - * :data:`SEEK_CUR` or ``1`` -- current stream position; *offset* may - be negative - * :data:`SEEK_END` or ``2`` -- end of the stream; *offset* is usually - negative - - Return the new absolute position. + * :data:`os.SEEK_CUR` or ``1`` -- current stream position; + *offset* may be negative + * :data:`os.SEEK_END` or ``2`` -- end of the stream; + *offset* is usually negative .. versionadded:: 3.1 - The ``SEEK_*`` constants. + The :data:`!SEEK_*` constants. .. versionadded:: 3.3 Some operating systems could support additional values, like - :data:`os.SEEK_HOLE` or :data:`os.SEEK_DATA`. The valid values + :const:`os.SEEK_HOLE` or :const:`os.SEEK_DATA`. The valid values for a file could depend on it being open in text or binary mode. .. method:: seekable() @@ -450,7 +449,7 @@ I/O Base Classes .. method:: writable() Return ``True`` if the stream supports writing. If ``False``, - :meth:`write` and :meth:`truncate` will raise :exc:`OSError`. + :meth:`!write` and :meth:`truncate` will raise :exc:`OSError`. .. method:: writelines(lines, /) @@ -654,8 +653,9 @@ Raw File I/O implies writing, so this mode behaves in a similar way to ``'w'``. Add a ``'+'`` to the mode to allow simultaneous reading and writing. - The :meth:`read` (when called with a positive argument), :meth:`readinto` - and :meth:`write` methods on this class will only make one system call. + The :meth:`~RawIOBase.read` (when called with a positive argument), + :meth:`~RawIOBase.readinto` and :meth:`~RawIOBase.write` methods on this + class will only make one system call. A custom opener can be used by passing a callable as *opener*. The underlying file descriptor for the file object is then obtained by calling *opener* with @@ -791,8 +791,8 @@ than raw I/O does. object under various conditions, including: * when the buffer gets too small for all pending data; - * when :meth:`flush()` is called; - * when a :meth:`seek()` is requested (for :class:`BufferedRandom` objects); + * when :meth:`flush` is called; + * when a :meth:`~IOBase.seek` is requested (for :class:`BufferedRandom` objects); * when the :class:`BufferedWriter` object is closed or destroyed. The constructor creates a :class:`BufferedWriter` for the given writeable @@ -826,8 +826,8 @@ than raw I/O does. :data:`DEFAULT_BUFFER_SIZE`. :class:`BufferedRandom` is capable of anything :class:`BufferedReader` or - :class:`BufferedWriter` can do. In addition, :meth:`seek` and :meth:`tell` - are guaranteed to be implemented. + :class:`BufferedWriter` can do. In addition, :meth:`~IOBase.seek` and + :meth:`~IOBase.tell` are guaranteed to be implemented. .. class:: BufferedRWPair(reader, writer, buffer_size=DEFAULT_BUFFER_SIZE, /) @@ -904,7 +904,7 @@ Text I/O .. method:: readline(size=-1, /) - Read until newline or EOF and return a single ``str``. If the stream is + Read until newline or EOF and return a single :class:`str`. If the stream is already at EOF, an empty string is returned. If *size* is specified, at most *size* characters will be read. @@ -913,22 +913,22 @@ Text I/O Change the stream position to the given *offset*. Behaviour depends on the *whence* parameter. The default value for *whence* is - :data:`SEEK_SET`. + :data:`!SEEK_SET`. - * :data:`SEEK_SET` or ``0``: seek from the start of the stream + * :data:`!SEEK_SET` or ``0``: seek from the start of the stream (the default); *offset* must either be a number returned by :meth:`TextIOBase.tell`, or zero. Any other *offset* value produces undefined behaviour. - * :data:`SEEK_CUR` or ``1``: "seek" to the current position; + * :data:`!SEEK_CUR` or ``1``: "seek" to the current position; *offset* must be zero, which is a no-operation (all other values are unsupported). - * :data:`SEEK_END` or ``2``: seek to the end of the stream; + * :data:`!SEEK_END` or ``2``: seek to the end of the stream; *offset* must be zero (all other values are unsupported). Return the new absolute position as an opaque number. .. versionadded:: 3.1 - The ``SEEK_*`` constants. + The :data:`!SEEK_*` constants. .. method:: tell() @@ -988,10 +988,10 @@ Text I/O takes place. If *newline* is any of the other legal values, any ``'\n'`` characters written are translated to the given string. - If *line_buffering* is ``True``, :meth:`flush` is implied when a call to + If *line_buffering* is ``True``, :meth:`~IOBase.flush` is implied when a call to write contains a newline character or a carriage return. - If *write_through* is ``True``, calls to :meth:`write` are guaranteed + If *write_through* is ``True``, calls to :meth:`~BufferedIOBase.write` are guaranteed not to be buffered: any data written on the :class:`TextIOWrapper` object is immediately handled to its underlying binary *buffer*. @@ -1043,6 +1043,33 @@ Text I/O .. versionchanged:: 3.11 The method supports ``encoding="locale"`` option. + .. method:: seek(cookie, whence=os.SEEK_SET, /) + + Set the stream position. + Return the new stream position as an :class:`int`. + + Four operations are supported, + given by the following argument combinations: + + * ``seek(0, SEEK_SET)``: Rewind to the start of the stream. + * ``seek(cookie, SEEK_SET)``: Restore a previous position; + *cookie* **must be** a number returned by :meth:`tell`. + * ``seek(0, SEEK_END)``: Fast-forward to the end of the stream. + * ``seek(0, SEEK_CUR)``: Leave the current stream position unchanged. + + Any other argument combinations are invalid, + and may raise exceptions. + + .. seealso:: + + :data:`os.SEEK_SET`, :data:`os.SEEK_CUR`, and :data:`os.SEEK_END`. + + .. method:: tell() + + Return the stream position as an opaque number. + The return value of :meth:`!tell` can be given as input to :meth:`seek`, + to restore a previous stream position. + .. class:: StringIO(initial_value='', newline='\n') @@ -1070,7 +1097,7 @@ Text I/O .. method:: getvalue() - Return a ``str`` containing the entire contents of the buffer. + Return a :class:`str` containing the entire contents of the buffer. Newlines are decoded as if by :meth:`~TextIOBase.read`, although the stream position is not changed. @@ -1125,7 +1152,7 @@ Text I/O over a binary storage (such as a file) is significantly slower than binary I/O over the same storage, because it requires conversions between unicode and binary data using a character codec. This can become noticeable handling huge amounts of text data like large log files. Also, -:meth:`TextIOWrapper.tell` and :meth:`TextIOWrapper.seek` are both quite slow +:meth:`~TextIOBase.tell` and :meth:`~TextIOBase.seek` are both quite slow due to the reconstruction algorithm used. :class:`StringIO`, however, is a native in-memory unicode container and will @@ -1135,7 +1162,7 @@ Multi-threading ^^^^^^^^^^^^^^^ :class:`FileIO` objects are thread-safe to the extent that the operating system -calls (such as ``read(2)`` under Unix) they wrap are thread-safe too. +calls (such as :manpage:`read(2)` under Unix) they wrap are thread-safe too. Binary buffered objects (instances of :class:`BufferedReader`, :class:`BufferedWriter`, :class:`BufferedRandom` and :class:`BufferedRWPair`) diff --git a/Doc/library/itertools.rst b/Doc/library/itertools.rst index 06c73fc2..8a1c83aa 100644 --- a/Doc/library/itertools.rst +++ b/Doc/library/itertools.rst @@ -52,6 +52,7 @@ Iterator Arguments Results Iterator Arguments Results Example ============================ ============================ ================================================= ============================================================= :func:`accumulate` p [,func] p0, p0+p1, p0+p1+p2, ... ``accumulate([1,2,3,4,5]) --> 1 3 6 10 15`` +:func:`batched` p, n (p0, p1, ..., p_n-1), ... ``batched('ABCDEFG', n=3) --> ABC DEF G`` :func:`chain` p, q, ... p0, p1, ... plast, q0, q1, ... ``chain('ABC', 'DEF') --> A B C D E F`` :func:`chain.from_iterable` iterable p0, p1, ... plast, q0, q1, ... ``chain.from_iterable(['ABC', 'DEF']) --> A B C D E F`` :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`` @@ -146,10 +147,10 @@ loops that truncate the stream. >>> list(accumulate(data, max)) # running maximum [3, 4, 6, 6, 6, 9, 9, 9, 9, 9] - # Amortize a 5% loan of 1000 with 4 annual payments of 90 - >>> cashflows = [1000, -90, -90, -90, -90] - >>> list(accumulate(cashflows, lambda bal, pmt: bal*1.05 + pmt)) - [1000, 960.0, 918.0, 873.9000000000001, 827.5950000000001] + # Amortize a 5% loan of 1000 with 10 annual payments of 90 + >>> account_update = lambda bal, pmt: round(bal * 1.05) + pmt + >>> list(accumulate(repeat(-90, 10), account_update, initial=1_000)) + [1000, 960, 918, 874, 828, 779, 728, 674, 618, 559, 497] See :func:`functools.reduce` for a similar function that returns only the final accumulated value. @@ -162,6 +163,44 @@ loops that truncate the stream. .. versionchanged:: 3.8 Added the optional *initial* parameter. + +.. function:: batched(iterable, n) + + Batch data from the *iterable* into tuples of length *n*. The last + batch may be shorter than *n*. + + Loops over the input iterable and accumulates data into tuples up to + size *n*. The input is consumed lazily, just enough to fill a batch. + The result is yielded as soon as the batch is full or when the input + iterable is exhausted: + + .. doctest:: + + >>> flattened_data = ['roses', 'red', 'violets', 'blue', 'sugar', 'sweet'] + >>> unflattened = list(batched(flattened_data, 2)) + >>> unflattened + [('roses', 'red'), ('violets', 'blue'), ('sugar', 'sweet')] + + >>> for batch in batched('ABCDEFG', 3): + ... print(batch) + ... + ('A', 'B', 'C') + ('D', 'E', 'F') + ('G',) + + Roughly equivalent to:: + + def batched(iterable, n): + # batched('ABCDEFG', 3) --> ABC DEF G + if n < 1: + raise ValueError('n must be at least one') + it = iter(iterable) + while batch := tuple(islice(it, n)): + yield batch + + .. versionadded:: 3.12 + + .. function:: chain(*iterables) Make an iterator that returns elements from the first iterable until it is @@ -359,7 +398,7 @@ loops that truncate the stream. .. function:: filterfalse(predicate, iterable) Make an iterator that filters elements from iterable returning only those for - which the predicate is ``False``. If *predicate* is ``None``, return the items + which the predicate is false. If *predicate* is ``None``, return the items that are false. Roughly equivalent to:: def filterfalse(predicate, iterable): @@ -670,7 +709,7 @@ loops that truncate the stream. the tee objects being informed. ``tee`` iterators are not threadsafe. A :exc:`RuntimeError` may be - raised when using simultaneously iterators returned by the same :func:`tee` + raised when simultaneously using iterators returned by the same :func:`tee` call, even if the original *iterable* is threadsafe. This itertool may require significant auxiliary storage (depending on how @@ -730,8 +769,8 @@ well as with the built-in itertools such as ``map()``, ``filter()``, A secondary purpose of the recipes is to serve as an incubator. The ``accumulate()``, ``compress()``, and ``pairwise()`` itertools started out as -recipes. Currently, the ``iter_index()`` recipe is being tested to see -whether it proves its worth. +recipes. Currently, the ``sliding_window()`` and ``iter_index()`` recipes +are being tested to see whether they prove their worth. Substantially all of these recipes and many, many others can be installed from the `more-itertools project <https://pypi.org/project/more-itertools/>`_ found @@ -750,6 +789,7 @@ which incur interpreter overhead. .. testcode:: import collections + import functools import math import operator import random @@ -767,6 +807,23 @@ which incur interpreter overhead. "Return function(0), function(1), ..." return map(function, count(start)) + def repeatfunc(func, times=None, *args): + """Repeat calls to func with specified arguments. + + Example: repeatfunc(random.random) + """ + if times is None: + return starmap(func, repeat(args)) + return starmap(func, repeat(args, times)) + + def flatten(list_of_lists): + "Flatten one level of nesting" + return chain.from_iterable(list_of_lists) + + def ncycles(iterable, n): + "Returns the sequence elements n times" + return chain.from_iterable(repeat(tuple(iterable), n)) + def tail(n, iterable): "Return an iterator over the last n items" # tail(3, 'ABCDEFG') --> E F G @@ -786,158 +843,90 @@ which incur interpreter overhead. "Returns the nth item or a default value" return next(islice(iterable, n, None), default) + def quantify(iterable, pred=bool): + "Given a predicate that returns True or False, count the True results." + return sum(map(pred, iterable)) + def all_equal(iterable): "Returns True if all the elements are equal to each other" g = groupby(iterable) return next(g, True) and not next(g, False) - def quantify(iterable, pred=bool): - "Count how many times the predicate is true" - return sum(map(pred, iterable)) - - def ncycles(iterable, n): - "Returns the sequence elements n times" - return chain.from_iterable(repeat(tuple(iterable), n)) - - def batched(iterable, n): - "Batch data into tuples of length n. The last batch may be shorter." - # batched('ABCDEFG', 3) --> ABC DEF G - if n < 1: - raise ValueError('n must be at least one') - it = iter(iterable) - while (batch := tuple(islice(it, n))): - yield batch - - def grouper(iterable, n, *, incomplete='fill', fillvalue=None): - "Collect data into non-overlapping fixed-length chunks or blocks" - # grouper('ABCDEFG', 3, fillvalue='x') --> ABC DEF Gxx - # grouper('ABCDEFG', 3, incomplete='strict') --> ABC DEF ValueError - # grouper('ABCDEFG', 3, incomplete='ignore') --> ABC DEF - args = [iter(iterable)] * n - if incomplete == 'fill': - return zip_longest(*args, fillvalue=fillvalue) - if incomplete == 'strict': - return zip(*args, strict=True) - if incomplete == 'ignore': - return zip(*args) - else: - raise ValueError('Expected fill, strict, or ignore') - - def sumprod(vec1, vec2): - "Compute a sum of products." - return sum(starmap(operator.mul, zip(vec1, vec2, strict=True))) - - def sum_of_squares(it): - "Add up the squares of the input values." - # sum_of_squares([10, 20, 30]) -> 1400 - return sumprod(*tee(it)) - - def transpose(it): - "Swap the rows and columns of the input." - # transpose([(1, 2, 3), (11, 22, 33)]) --> (1, 11) (2, 22) (3, 33) - return zip(*it, strict=True) - - def matmul(m1, m2): - "Multiply two matrices." - # matmul([(7, 5), (3, 5)], [[2, 5], [7, 9]]) --> (49, 80), (41, 60) - n = len(m2[0]) - return batched(starmap(sumprod, product(m1, transpose(m2))), n) + def first_true(iterable, default=False, pred=None): + """Returns the first true value in the iterable. - def convolve(signal, kernel): - # See: https://betterexplained.com/articles/intuitive-convolution/ - # convolve(data, [0.25, 0.25, 0.25, 0.25]) --> Moving average (blur) - # convolve(data, [1, -1]) --> 1st finite difference (1st derivative) - # convolve(data, [1, -2, 1]) --> 2nd finite difference (2nd derivative) - kernel = tuple(kernel)[::-1] - n = len(kernel) - window = collections.deque([0], maxlen=n) * n - for x in chain(signal, repeat(0, n-1)): - window.append(x) - yield sumprod(kernel, window) + If no true value is found, returns *default* - def polynomial_from_roots(roots): - """Compute a polynomial's coefficients from its roots. + If *pred* is not None, returns the first item + for which pred(item) is true. - (x - 5) (x + 4) (x - 3) expands to: x³ -4x² -17x + 60 """ - # polynomial_from_roots([5, -4, 3]) --> [1, -4, -17, 60] - roots = list(map(operator.neg, roots)) - return [ - sum(map(math.prod, combinations(roots, k))) - for k in range(len(roots) + 1) - ] + # first_true([a,b,c], x) --> a or b or c or x + # first_true([a,b], x, f) --> a if f(a) else b if f(b) else x + return next(filter(pred, iterable), default) - def iter_index(iterable, value, start=0): + def iter_index(iterable, value, start=0, stop=None): "Return indices where a value occurs in a sequence or iterable." # iter_index('AABCADEAF', 'A') --> 0 1 4 7 - try: - seq_index = iterable.index - except AttributeError: + seq_index = getattr(iterable, 'index', None) + if seq_index is None: # Slow path for general iterables - it = islice(iterable, start, None) + it = islice(iterable, start, stop) for i, element in enumerate(it, start): if element is value or element == value: yield i else: # Fast path for sequences + stop = len(iterable) if stop is None else stop i = start - 1 try: while True: - yield (i := seq_index(value, i+1)) + yield (i := seq_index(value, i+1, stop)) except ValueError: pass - def sieve(n): - "Primes less than n" - # sieve(30) --> 2 3 5 7 11 13 17 19 23 29 - data = bytearray((0, 1)) * (n // 2) - data[:3] = 0, 0, 0 - limit = math.isqrt(n) + 1 - for p in compress(range(limit), data): - data[p*p : n : p+p] = bytes(len(range(p*p, n, p+p))) - data[2] = 1 - return iter_index(data, 1) if n > 2 else iter([]) - - def factor(n): - "Prime factors of n." - # factor(99) --> 3 3 11 - for prime in sieve(math.isqrt(n) + 1): - while True: - quotient, remainder = divmod(n, prime) - if remainder: - break - yield prime - n = quotient - if n == 1: - return - if n >= 2: - yield n + def iter_except(func, exception, first=None): + """ Call a function repeatedly until an exception is raised. - def flatten(list_of_lists): - "Flatten one level of nesting" - return chain.from_iterable(list_of_lists) + Converts a call-until-exception interface to an iterator interface. + Like builtins.iter(func, sentinel) but uses an exception instead + of a sentinel to end the loop. - def repeatfunc(func, times=None, *args): - """Repeat calls to func with specified arguments. + Examples: + iter_except(functools.partial(heappop, h), IndexError) # priority queue iterator + iter_except(d.popitem, KeyError) # non-blocking dict iterator + iter_except(d.popleft, IndexError) # non-blocking deque iterator + iter_except(q.get_nowait, Queue.Empty) # loop over a producer Queue + iter_except(s.pop, KeyError) # non-blocking set iterator - Example: repeatfunc(random.random) """ - if times is None: - return starmap(func, repeat(args)) - return starmap(func, repeat(args, times)) + try: + if first is not None: + yield first() # For database APIs needing an initial cast to db.first() + while True: + yield func() + except exception: + pass - def triplewise(iterable): - "Return overlapping triplets from an iterable" - # triplewise('ABCDEFG') --> ABC BCD CDE DEF EFG - for (a, _), (b, c) in pairwise(pairwise(iterable)): - yield a, b, c + def grouper(iterable, n, *, incomplete='fill', fillvalue=None): + "Collect data into non-overlapping fixed-length chunks or blocks" + # grouper('ABCDEFG', 3, fillvalue='x') --> ABC DEF Gxx + # grouper('ABCDEFG', 3, incomplete='strict') --> ABC DEF ValueError + # grouper('ABCDEFG', 3, incomplete='ignore') --> ABC DEF + args = [iter(iterable)] * n + if incomplete == 'fill': + return zip_longest(*args, fillvalue=fillvalue) + if incomplete == 'strict': + return zip(*args, strict=True) + if incomplete == 'ignore': + return zip(*args) + else: + raise ValueError('Expected fill, strict, or ignore') def sliding_window(iterable, n): # sliding_window('ABCDEFG', 4) --> ABCD BCDE CDEF DEFG it = iter(iterable) - window = collections.deque(islice(it, n), maxlen=n) - if len(window) == n: - yield tuple(window) + window = collections.deque(islice(it, n-1), maxlen=n) for x in it: window.append(x) yield tuple(window) @@ -957,11 +946,20 @@ which incur interpreter overhead. nexts = cycle(islice(nexts, num_active)) def partition(pred, iterable): - "Use a predicate to partition entries into false entries and true entries" + """Partition entries into false entries and true entries. + + If *pred* is slow, consider wrapping it with functools.lru_cache(). + """ # partition(is_odd, range(10)) --> 0 2 4 6 8 and 1 3 5 7 9 t1, t2 = tee(iterable) return filterfalse(pred, t1), filter(pred, t2) + def subslices(seq): + "Return all contiguous non-empty subslices of a sequence" + # subslices('ABCD') --> A AB ABC ABCD B BC BCD C CD D + slices = starmap(slice, combinations(range(len(seq) + 1), 2)) + return map(operator.getitem, repeat(seq), slices) + def before_and_after(predicate, it): """ Variant of takewhile() that allows complete access to the remainder of the iterator. @@ -991,17 +989,6 @@ which incur interpreter overhead. yield from it return true_iterator(), remainder_iterator() - def subslices(seq): - "Return all contiguous non-empty subslices of a sequence" - # subslices('ABCD') --> A AB ABC ABCD B BC BCD C CD D - slices = starmap(slice, combinations(range(len(seq) + 1), 2)) - return map(operator.getitem, repeat(seq), slices) - - def powerset(iterable): - "powerset([1,2,3]) --> () (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)" - s = list(iterable) - return chain.from_iterable(combinations(s, r) for r in range(len(s)+1)) - def unique_everseen(iterable, key=None): "List unique elements, preserving order. Remember all elements ever seen." # unique_everseen('AAAABBBCCDAABBB') --> A B C D @@ -1031,41 +1018,116 @@ which incur interpreter overhead. # unique_justseen('ABBcCAD', str.lower) --> A B c A D return map(next, map(operator.itemgetter(1), groupby(iterable, key))) - def iter_except(func, exception, first=None): - """ Call a function repeatedly until an exception is raised. - Converts a call-until-exception interface to an iterator interface. - Like builtins.iter(func, sentinel) but uses an exception instead - of a sentinel to end the loop. +The following recipes have a more mathematical flavor: - Examples: - iter_except(functools.partial(heappop, h), IndexError) # priority queue iterator - iter_except(d.popitem, KeyError) # non-blocking dict iterator - iter_except(d.popleft, IndexError) # non-blocking deque iterator - iter_except(q.get_nowait, Queue.Empty) # loop over a producer Queue - iter_except(s.pop, KeyError) # non-blocking set iterator +.. testcode:: + def powerset(iterable): + "powerset([1,2,3]) --> () (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)" + s = list(iterable) + return chain.from_iterable(combinations(s, r) for r in range(len(s)+1)) + + def sum_of_squares(it): + "Add up the squares of the input values." + # sum_of_squares([10, 20, 30]) -> 1400 + return math.sumprod(*tee(it)) + + def transpose(it): + "Swap the rows and columns of the input." + # transpose([(1, 2, 3), (11, 22, 33)]) --> (1, 11) (2, 22) (3, 33) + return zip(*it, strict=True) + + def matmul(m1, m2): + "Multiply two matrices." + # matmul([(7, 5), (3, 5)], [(2, 5), (7, 9)]) --> (49, 80), (41, 60) + n = len(m2[0]) + return batched(starmap(math.sumprod, product(m1, transpose(m2))), n) + + def convolve(signal, kernel): + """Discrete linear convolution of two iterables. + + The kernel is fully consumed before the calculations begin. + The signal is consumed lazily and can be infinite. + + Convolutions are mathematically commutative. + If the signal and kernel are swapped, + the output will be the same. + + Article: https://betterexplained.com/articles/intuitive-convolution/ + Video: https://www.youtube.com/watch?v=KuXjwB4LzSA """ - try: - if first is not None: - yield first() # For database APIs needing an initial cast to db.first() - while True: - yield func() - except exception: - pass + # convolve(data, [0.25, 0.25, 0.25, 0.25]) --> Moving average (blur) + # convolve(data, [1/2, 0, -1/2]) --> 1st derivative estimate + # convolve(data, [1, -2, 1]) --> 2nd derivative estimate + kernel = tuple(kernel)[::-1] + n = len(kernel) + padded_signal = chain(repeat(0, n-1), signal, repeat(0, n-1)) + windowed_signal = sliding_window(padded_signal, n) + return map(math.sumprod, repeat(kernel), windowed_signal) - def first_true(iterable, default=False, pred=None): - """Returns the first true value in the iterable. + def polynomial_from_roots(roots): + """Compute a polynomial's coefficients from its roots. - If no true value is found, returns *default* + (x - 5) (x + 4) (x - 3) expands to: x³ -4x² -17x + 60 + """ + # polynomial_from_roots([5, -4, 3]) --> [1, -4, -17, 60] + factors = zip(repeat(1), map(operator.neg, roots)) + return list(functools.reduce(convolve, factors, [1])) - If *pred* is not None, returns the first item - for which pred(item) is true. + def polynomial_eval(coefficients, x): + """Evaluate a polynomial at a specific value. + Computes with better numeric stability than Horner's method. """ - # first_true([a,b,c], x) --> a or b or c or x - # first_true([a,b], x, f) --> a if f(a) else b if f(b) else x - return next(filter(pred, iterable), default) + # Evaluate x³ -4x² -17x + 60 at x = 2.5 + # polynomial_eval([1, -4, -17, 60], x=2.5) --> 8.125 + n = len(coefficients) + if not n: + return type(x)(0) + powers = map(pow, repeat(x), reversed(range(n))) + return math.sumprod(coefficients, powers) + + def polynomial_derivative(coefficients): + """Compute the first derivative of a polynomial. + + f(x) = x³ -4x² -17x + 60 + f'(x) = 3x² -8x -17 + """ + # polynomial_derivative([1, -4, -17, 60]) -> [3, -8, -17] + n = len(coefficients) + powers = reversed(range(1, n)) + return list(map(operator.mul, coefficients, powers)) + + def sieve(n): + "Primes less than n." + # sieve(30) --> 2 3 5 7 11 13 17 19 23 29 + if n > 2: + yield 2 + start = 3 + data = bytearray((0, 1)) * (n // 2) + limit = math.isqrt(n) + 1 + for p in iter_index(data, 1, start, limit): + yield from iter_index(data, 1, start, p*p) + data[p*p : n : p+p] = bytes(len(range(p*p, n, p+p))) + start = p*p + yield from iter_index(data, 1, start) + + def factor(n): + "Prime factors of n." + # factor(99) --> 3 3 11 + # factor(1_000_000_000_000_007) --> 47 59 360620266859 + # factor(1_000_000_000_000_403) --> 1000000000000403 + for prime in sieve(math.isqrt(n) + 1): + while True: + if n % prime: + break + yield prime + n //= prime + if n == 1: + return + if n > 1: + yield n def nth_combination(iterable, r, index): "Equivalent to list(combinations(iterable, r))[index]" @@ -1085,6 +1147,7 @@ which incur interpreter overhead. result.append(pool[-1-n]) return tuple(result) + .. doctest:: :hide: @@ -1197,9 +1260,6 @@ which incur interpreter overhead. >>> list(ncycles('abc', 3)) ['a', 'b', 'c', 'a', 'b', 'c', 'a', 'b', 'c'] - >>> sumprod([1,2,3], [4,5,6]) - 32 - >>> sum_of_squares([10, 20, 30]) 1400 @@ -1219,6 +1279,37 @@ which incur interpreter overhead. >>> list(convolve(data, [1, -2, 1])) [20, 0, -36, 24, -20, 20, -20, -4, 16] + >>> from fractions import Fraction + >>> from decimal import Decimal + >>> polynomial_eval([1, -4, -17, 60], x=2) + 18 + >>> x = 2; x**3 - 4*x**2 -17*x + 60 + 18 + >>> polynomial_eval([1, -4, -17, 60], x=2.5) + 8.125 + >>> x = 2.5; x**3 - 4*x**2 -17*x + 60 + 8.125 + >>> polynomial_eval([1, -4, -17, 60], x=Fraction(2, 3)) + Fraction(1274, 27) + >>> x = Fraction(2, 3); x**3 - 4*x**2 -17*x + 60 + Fraction(1274, 27) + >>> polynomial_eval([1, -4, -17, 60], x=Decimal('1.75')) + Decimal('23.359375') + >>> x = Decimal('1.75'); x**3 - 4*x**2 -17*x + 60 + Decimal('23.359375') + >>> polynomial_eval([], 2) + 0 + >>> polynomial_eval([], 2.5) + 0.0 + >>> polynomial_eval([], Fraction(2, 3)) + Fraction(0, 1) + >>> polynomial_eval([], Decimal('1.75')) + Decimal('0') + >>> polynomial_eval([11], 7) == 11 + True + >>> polynomial_eval([11, 2], 7) == 11 * 7 + 2 + True + >>> polynomial_from_roots([5, -4, 3]) [1, -4, -17, 60] >>> factored = lambda x: (x - 5) * (x + 4) * (x - 3) @@ -1226,6 +1317,9 @@ which incur interpreter overhead. >>> all(factored(x) == expanded(x) for x in range(-10, 11)) True + >>> polynomial_derivative([1, -4, -17, 60]) + [3, -8, -17] + >>> list(iter_index('AABCADEAF', 'A')) [0, 1, 4, 7] >>> list(iter_index('AABCADEAF', 'B')) @@ -1246,6 +1340,31 @@ which incur interpreter overhead. [] >>> list(iter_index(iter('AABCADEAF'), 'A', 10)) [] + >>> list(iter_index('AABCADEAF', 'A', 1, 7)) + [1, 4] + >>> list(iter_index(iter('AABCADEAF'), 'A', 1, 7)) + [1, 4] + >>> # Verify that ValueErrors not swallowed (gh-107208) + >>> def assert_no_value(iterable, forbidden_value): + ... for item in iterable: + ... if item == forbidden_value: + ... raise ValueError + ... yield item + ... + >>> list(iter_index(assert_no_value('AABCADEAF', 'B'), 'A')) + Traceback (most recent call last): + ... + ValueError + >>> # Verify that both paths can find identical NaN values + >>> x = float('NaN') + >>> y = float('NaN') + >>> list(iter_index([0, x, x, y, 0], x)) + [1, 2] + >>> list(iter_index(iter([0, x, x, y, 0]), x)) + [1, 2] + >>> # Test list input. Lists do not support None for the stop argument + >>> list(iter_index(list('AABCADEAF'), 'A')) + [0, 1, 4, 7] >>> list(sieve(30)) [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] @@ -1266,6 +1385,12 @@ which incur interpreter overhead. >>> set(sieve(10_000)).isdisjoint(carmichael) True + >>> list(factor(99)) # Code example 1 + [3, 3, 11] + >>> list(factor(1_000_000_000_000_007)) # Code example 2 + [47, 59, 360620266859] + >>> list(factor(1_000_000_000_000_403)) # Code example 3 + [1000000000000403] >>> list(factor(0)) [] >>> list(factor(1)) @@ -1332,35 +1457,34 @@ which incur interpreter overhead. >>> list(grouper('abcdefg', n=3, incomplete='ignore')) [('a', 'b', 'c'), ('d', 'e', 'f')] - >>> list(batched('ABCDEFG', 3)) - [('A', 'B', 'C'), ('D', 'E', 'F'), ('G',)] - >>> list(batched('ABCDEF', 3)) - [('A', 'B', 'C'), ('D', 'E', 'F')] - >>> list(batched('ABCDE', 3)) - [('A', 'B', 'C'), ('D', 'E')] - >>> list(batched('ABCD', 3)) - [('A', 'B', 'C'), ('D',)] - >>> list(batched('ABC', 3)) - [('A', 'B', 'C')] - >>> list(batched('AB', 3)) - [('A', 'B')] - >>> list(batched('A', 3)) - [('A',)] - >>> list(batched('', 3)) - [] - >>> list(batched('ABCDEFG', 2)) - [('A', 'B'), ('C', 'D'), ('E', 'F'), ('G',)] - >>> list(batched('ABCDEFG', 1)) + >>> list(sliding_window('ABCDEFG', 1)) [('A',), ('B',), ('C',), ('D',), ('E',), ('F',), ('G',)] - >>> s = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' - >>> all(list(flatten(batched(s[:n], 5))) == list(s[:n]) for n in range(len(s))) - True - - >>> list(triplewise('ABCDEFG')) + >>> list(sliding_window('ABCDEFG', 2)) + [('A', 'B'), ('B', 'C'), ('C', 'D'), ('D', 'E'), ('E', 'F'), ('F', 'G')] + >>> list(sliding_window('ABCDEFG', 3)) [('A', 'B', 'C'), ('B', 'C', 'D'), ('C', 'D', 'E'), ('D', 'E', 'F'), ('E', 'F', 'G')] - >>> list(sliding_window('ABCDEFG', 4)) [('A', 'B', 'C', 'D'), ('B', 'C', 'D', 'E'), ('C', 'D', 'E', 'F'), ('D', 'E', 'F', 'G')] + >>> list(sliding_window('ABCDEFG', 5)) + [('A', 'B', 'C', 'D', 'E'), ('B', 'C', 'D', 'E', 'F'), ('C', 'D', 'E', 'F', 'G')] + >>> list(sliding_window('ABCDEFG', 6)) + [('A', 'B', 'C', 'D', 'E', 'F'), ('B', 'C', 'D', 'E', 'F', 'G')] + >>> list(sliding_window('ABCDEFG', 7)) + [('A', 'B', 'C', 'D', 'E', 'F', 'G')] + >>> list(sliding_window('ABCDEFG', 8)) + [] + >>> try: + ... list(sliding_window('ABCDEFG', -1)) + ... except ValueError: + ... 'zero or negative n not supported' + ... + 'zero or negative n not supported' + >>> try: + ... list(sliding_window('ABCDEFG', 0)) + ... except ValueError: + ... 'zero or negative n not supported' + ... + 'zero or negative n not supported' >>> list(roundrobin('abc', 'd', 'ef')) ['a', 'd', 'e', 'b', 'f', 'c'] @@ -1440,3 +1564,45 @@ which incur interpreter overhead. >>> combos = list(combinations(iterable, r)) >>> all(nth_combination(iterable, r, i) == comb for i, comb in enumerate(combos)) True + + +.. testcode:: + :hide: + + # Old recipes and their tests which are guaranteed to continue to work. + + def sumprod(vec1, vec2): + "Compute a sum of products." + return sum(starmap(operator.mul, zip(vec1, vec2, strict=True))) + + def dotproduct(vec1, vec2): + return sum(map(operator.mul, vec1, vec2)) + + def pad_none(iterable): + """Returns the sequence elements and then returns None indefinitely. + + Useful for emulating the behavior of the built-in map() function. + """ + return chain(iterable, repeat(None)) + + def triplewise(iterable): + "Return overlapping triplets from an iterable" + # triplewise('ABCDEFG') --> ABC BCD CDE DEF EFG + for (a, _), (b, c) in pairwise(pairwise(iterable)): + yield a, b, c + + +.. doctest:: + :hide: + + >>> dotproduct([1,2,3], [4,5,6]) + 32 + + >>> sumprod([1,2,3], [4,5,6]) + 32 + + >>> list(islice(pad_none('abc'), 0, 6)) + ['a', 'b', 'c', None, None, None] + + >>> list(triplewise('ABCDEFG')) + [('A', 'B', 'C'), ('B', 'C', 'D'), ('C', 'D', 'E'), ('D', 'E', 'F'), ('E', 'F', 'G')] diff --git a/Doc/library/json.rst b/Doc/library/json.rst index 53836145..6c305938 100644 --- a/Doc/library/json.rst +++ b/Doc/library/json.rst @@ -192,7 +192,7 @@ Basic Usage dictionaries will be sorted by key. To use a custom :class:`JSONEncoder` subclass (e.g. one that overrides the - :meth:`default` method to serialize additional types), specify it with the + :meth:`~JSONEncoder.default` method to serialize additional types), specify it with the *cls* kwarg; otherwise :class:`JSONEncoder` is used. .. versionchanged:: 3.6 @@ -422,7 +422,7 @@ Encoders and Decoders Added support for int- and float-derived Enum classes. To extend this to recognize other objects, subclass and implement a - :meth:`default` method with another method that returns a serializable object + :meth:`~JSONEncoder.default` method with another method that returns a serializable object for ``o`` if possible, otherwise it should call the superclass implementation (to raise :exc:`TypeError`). @@ -483,7 +483,7 @@ Encoders and Decoders :exc:`TypeError`). For example, to support arbitrary iterators, you could implement - :meth:`default` like this:: + :meth:`~JSONEncoder.default` like this:: def default(self, o): try: @@ -683,7 +683,7 @@ The :mod:`json.tool` module provides a simple command line interface to validate and pretty-print JSON objects. If the optional ``infile`` and ``outfile`` arguments are not -specified, :attr:`sys.stdin` and :attr:`sys.stdout` will be used respectively: +specified, :data:`sys.stdin` and :data:`sys.stdout` will be used respectively: .. code-block:: shell-session @@ -721,12 +721,12 @@ Command line options } ] - If *infile* is not specified, read from :attr:`sys.stdin`. + If *infile* is not specified, read from :data:`sys.stdin`. .. cmdoption:: outfile Write the output of the *infile* to the given *outfile*. Otherwise, write it - to :attr:`sys.stdout`. + to :data:`sys.stdout`. .. cmdoption:: --sort-keys diff --git a/Doc/library/kde_example.png b/Doc/library/kde_example.png new file mode 100644 index 0000000000000000000000000000000000000000..f45048956999741a6889bdfe85c40e1f25e8863b GIT binary patch literal 332212 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 literal 0 HcmV?d00001 diff --git a/Doc/library/locale.rst b/Doc/library/locale.rst index 0614930c..f2abb363 100644 --- a/Doc/library/locale.rst +++ b/Doc/library/locale.rst @@ -16,7 +16,7 @@ functionality. The POSIX locale mechanism allows programmers to deal with certain cultural issues in an application, without requiring the programmer to know all the specifics of each country where the software is executed. -.. index:: module: _locale +.. index:: pair: module; _locale The :mod:`locale` module is implemented on top of the :mod:`_locale` module, which in turn uses an ANSI C locale implementation if available. @@ -414,18 +414,6 @@ The :mod:`locale` module defines the following exception and functions: The *monetary* keyword parameter was added. -.. function:: format(format, val, grouping=False, monetary=False) - - Please note that this function works like :meth:`format_string` but will - only work for exactly one ``%char`` specifier. For example, ``'%f'`` and - ``'%.0f'`` are both valid specifiers, but ``'%f KiB'`` is not. - - For whole format strings, use :func:`format_string`. - - .. deprecated:: 3.7 - Use :meth:`format_string` instead. - - .. function:: currency(val, symbol=True, grouping=False, international=False) Formats a number *val* according to the current :const:`LC_MONETARY` settings. @@ -476,7 +464,7 @@ The :mod:`locale` module defines the following exception and functions: .. data:: LC_CTYPE - .. index:: module: string + .. index:: pair: module; string Locale category for the character type functions. Depending on the settings of this category, the functions of module :mod:`string` dealing with case change @@ -514,7 +502,7 @@ The :mod:`locale` module defines the following exception and functions: .. data:: LC_NUMERIC - Locale category for formatting numbers. The functions :func:`.format`, + Locale category for formatting numbers. The functions :func:`format_string`, :func:`atoi`, :func:`atof` and :func:`.str` of the :mod:`locale` module are affected by that category. All other numeric formatting operations are not affected. @@ -576,7 +564,7 @@ document that your module is not compatible with non-\ ``C`` locale settings. The only way to perform numeric operations according to the locale is to use the special functions defined by this module: :func:`atof`, :func:`atoi`, -:func:`.format`, :func:`.str`. +:func:`format_string`, :func:`.str`. There is no way to perform case conversions and character classifications according to the locale. For (Unicode) text strings these are done according diff --git a/Doc/library/logging.config.rst b/Doc/library/logging.config.rst index 93e45296..448978f4 100644 --- a/Doc/library/logging.config.rst +++ b/Doc/library/logging.config.rst @@ -87,6 +87,10 @@ in :mod:`logging` itself) and defining handlers which are declared either in provides a mechanism to present the choices and load the chosen configuration). + It will raise :exc:`FileNotFoundError` if the file + doesn't exist and :exc:`RuntimeError` if the file is invalid or + empty. + :param fname: A filename, or a file-like object, or an instance derived from :class:`~configparser.RawConfigParser`. If a ``RawConfigParser``-derived instance is passed, it is used as @@ -111,7 +115,7 @@ in :mod:`logging` itself) and defining handlers which are declared either in they or their ancestors are explicitly named in the logging configuration. - :param encoding: The encoding used to open file when *fname* is filename. + :param encoding: The encoding used to open file when *fname* is filename. .. versionchanged:: 3.4 An instance of a subclass of :class:`~configparser.RawConfigParser` is @@ -126,6 +130,10 @@ in :mod:`logging` itself) and defining handlers which are declared either in .. versionadded:: 3.10 The *encoding* parameter is added. + .. versionchanged:: 3.12 + An exception will be thrown if the provided file + doesn't exist or is invalid or empty. + .. function:: listen(port=DEFAULT_LOGGING_CONFIG_PORT, verify=None) Starts up a socket server on the specified port, and listens for new @@ -253,6 +261,7 @@ otherwise, the context is used to determine what to instantiate. * ``datefmt`` * ``style`` * ``validate`` (since version >=3.8) + * ``defaults`` (since version >=3.12) An optional ``class`` key indicates the name of the formatter's class (as a dotted module and class name). The instantiation @@ -713,6 +722,76 @@ it with :func:`staticmethod`. For example:: You don't need to wrap with :func:`staticmethod` if you're setting the import callable on a configurator *instance*. +.. _configure-queue: + +Configuring QueueHandler and QueueListener +"""""""""""""""""""""""""""""""""""""""""" + +If you want to configure a :class:`~logging.handlers.QueueHandler`, noting that this +is normally used in conjunction with a :class:`~logging.handlers.QueueListener`, you +can configure both together. After the configuration, the ``QueueListener`` instance +will be available as the :attr:`~logging.handlers.QueueHandler.listener` attribute of +the created handler, and that in turn will be available to you using +:func:`~logging.getHandlerByName` and passing the name you have used for the +``QueueHandler`` in your configuration. The dictionary schema for configuring the pair +is shown in the example YAML snippet below. + +.. code-block:: yaml + + handlers: + qhand: + class: logging.handlers.QueueHandler + queue: my.module.queue_factory + listener: my.package.CustomListener + handlers: + - hand_name_1 + - hand_name_2 + ... + +The ``queue`` and ``listener`` keys are optional. + +If the ``queue`` key is present, the corresponding value can be one of the following: + +* An actual instance of :class:`queue.Queue` or a subclass thereof. This is of course + only possible if you are constructing or modifying the configuration dictionary in + code. + +* A string that resolves to a callable which, when called with no arguments, returns + the :class:`queue.Queue` instance to use. That callable could be a + :class:`queue.Queue` subclass or a function which returns a suitable queue instance, + such as ``my.module.queue_factory()``. + +* A dict with a ``'()'`` key which is constructed in the usual way as discussed in + :ref:`logging-config-dict-userdef`. The result of this construction should be a + :class:`queue.Queue` instance. + +If the ``queue`` key is absent, a standard unbounded :class:`queue.Queue` instance is +created and used. + +If the ``listener`` key is present, the corresponding value can be one of the following: + +* A subclass of :class:`logging.handlers.QueueListener`. This is of course only + possible if you are constructing or modifying the configuration dictionary in + code. + +* A string which resolves to a class which is a subclass of ``QueueListener``, such as + ``'my.package.CustomListener'``. + +* A dict with a ``'()'`` key which is constructed in the usual way as discussed in + :ref:`logging-config-dict-userdef`. The result of this construction should be a + callable with the same signature as the ``QueueListener`` initializer. + +If the ``listener`` key is absent, :class:`logging.handlers.QueueListener` is used. + +The values under the ``handlers`` key are the names of other handlers in the +configuration (not shown in the above snippet) which will be passed to the queue +listener. + +Any custom queue handler and listener classes will need to be defined with the same +initialization signatures as :class:`~logging.handlers.QueueHandler` and +:class:`~logging.handlers.QueueListener`. + +.. versionadded:: 3.12 .. _logging-config-fileformat: @@ -883,16 +962,22 @@ Sections which specify formatter configuration are typified by the following. .. code-block:: ini [formatter_form01] - format=F1 %(asctime)s %(levelname)s %(message)s + format=F1 %(asctime)s %(levelname)s %(message)s %(customfield)s datefmt= style=% validate=True + defaults={'customfield': 'defaultvalue'} class=logging.Formatter The arguments for the formatter configuration are the same as the keys in the dictionary schema :ref:`formatters section <logging-config-dictschema-formatters>`. +The ``defaults`` entry, when :ref:`evaluated <func-eval>` in the context of +the ``logging`` package's namespace, is a dictionary of default values for +custom formatting fields. If not provided, it defaults to ``None``. + + .. note:: Due to the use of :func:`eval` as described above, there are diff --git a/Doc/library/logging.handlers.rst b/Doc/library/logging.handlers.rst index b6455298..2a825db5 100644 --- a/Doc/library/logging.handlers.rst +++ b/Doc/library/logging.handlers.rst @@ -97,7 +97,7 @@ sends logging output to a disk file. It inherits the output functionality from Returns a new instance of the :class:`FileHandler` class. The specified file is opened and used as the stream for logging. If *mode* is not specified, - :const:`'a'` is used. If *encoding* is not ``None``, it is used to open the file + ``'a'`` is used. If *encoding* is not ``None``, it is used to open the file with that encoding. If *delay* is true, then file opening is deferred until the first call to :meth:`emit`. By default, the file grows indefinitely. If *errors* is specified, it's used to determine how encoding errors are handled. @@ -182,7 +182,7 @@ for this value. Returns a new instance of the :class:`WatchedFileHandler` class. The specified file is opened and used as the stream for logging. If *mode* is not specified, - :const:`'a'` is used. If *encoding* is not ``None``, it is used to open the file + ``'a'`` is used. If *encoding* is not ``None``, it is used to open the file with that encoding. If *delay* is true, then file opening is deferred until the first call to :meth:`emit`. By default, the file grows indefinitely. If *errors* is provided, it determines how encoding errors are handled. @@ -917,8 +917,9 @@ should, then :meth:`flush` is expected to do the flushing. .. method:: flush() - You can override this to implement custom flushing behavior. This version - just zaps the buffer to empty. + For a :class:`BufferingHandler` instance, flushing means that it sets the + buffer to an empty list. This method can be overwritten to implement more useful + flushing behavior. .. method:: shouldFlush(record) @@ -950,9 +951,9 @@ should, then :meth:`flush` is expected to do the flushing. .. method:: flush() - For a :class:`MemoryHandler`, flushing means just sending the buffered + For a :class:`MemoryHandler` instance, flushing means just sending the buffered records to the target, if there is one. The buffer is also cleared when - this happens. Override if you want different behavior. + buffered records are sent to the target. Override if you want different behavior. .. method:: setTarget(target) @@ -1051,8 +1052,8 @@ possible, while any potentially slow operations (such as sending an email via occur (e.g. because a bounded queue has filled up), the :meth:`~logging.Handler.handleError` method is called to handle the error. This can result in the record silently being dropped (if - :attr:`logging.raiseExceptions` is ``False``) or a message printed to - ``sys.stderr`` (if :attr:`logging.raiseExceptions` is ``True``). + :data:`logging.raiseExceptions` is ``False``) or a message printed to + ``sys.stderr`` (if :data:`logging.raiseExceptions` is ``True``). .. method:: prepare(record) @@ -1091,7 +1092,13 @@ possible, while any potentially slow operations (such as sending an email via want to override this if you want to use blocking behaviour, or a timeout, or a customized queue implementation. + .. attribute:: listener + + When created via configuration using :func:`~logging.config.dictConfig`, this + attribute will contain a :class:`QueueListener` instance for use with this + handler. Otherwise, it will be ``None``. + .. versionadded:: 3.12 .. _queue-listener: diff --git a/Doc/library/logging.rst b/Doc/library/logging.rst index 9390f065..6d1f048d 100644 --- a/Doc/library/logging.rst +++ b/Doc/library/logging.rst @@ -170,6 +170,18 @@ is the module's name in the Python package namespace. .. versionadded:: 3.2 + .. method:: Logger.getChildren() + + Returns a set of loggers which are immediate children of this logger. So for + example ``logging.getLogger().getChildren()`` might return a set containing + loggers named ``foo`` and ``bar``, but a logger named ``foo.bar`` wouldn't be + included in the set. Likewise, ``logging.getLogger('foo').getChildren()`` might + return a set including a logger named ``foo.bar``, but it wouldn't include one + named ``foo.bar.baz``. + + .. versionadded:: 3.12 + + .. method:: Logger.debug(msg, *args, **kwargs) Logs a message with level :const:`DEBUG` on this logger. The *msg* is the @@ -385,21 +397,39 @@ have specific values relative to the predefined levels. If you define a level with the same numeric value, it overwrites the predefined value; the predefined name is lost. -+--------------+---------------+ -| Level | Numeric value | -+==============+===============+ -| ``CRITICAL`` | 50 | -+--------------+---------------+ -| ``ERROR`` | 40 | -+--------------+---------------+ -| ``WARNING`` | 30 | -+--------------+---------------+ -| ``INFO`` | 20 | -+--------------+---------------+ -| ``DEBUG`` | 10 | -+--------------+---------------+ -| ``NOTSET`` | 0 | -+--------------+---------------+ ++-----------------------+---------------+-------------------------------------+ +| Level | Numeric value | What it means / When to use it | ++=======================+===============+=====================================+ +| .. py:data:: NOTSET | 0 | When set on a logger, indicates that| +| | | ancestor loggers are to be consulted| +| | | to determine the effective level. | +| | | If that still resolves to | +| | | :const:`!NOTSET`, then all events | +| | | are logged. When set on a handler, | +| | | all events are handled. | ++-----------------------+---------------+-------------------------------------+ +| .. py:data:: DEBUG | 10 | Detailed information, typically only| +| | | of interest to a developer trying to| +| | | diagnose a problem. | ++-----------------------+---------------+-------------------------------------+ +| .. py:data:: INFO | 20 | Confirmation that things are working| +| | | as expected. | ++-----------------------+---------------+-------------------------------------+ +| .. py:data:: WARNING | 30 | An indication that something | +| | | unexpected happened, or that a | +| | | problem might occur in the near | +| | | future (e.g. 'disk space low'). The | +| | | software is still working as | +| | | expected. | ++-----------------------+---------------+-------------------------------------+ +| .. py:data:: ERROR | 40 | Due to a more serious problem, the | +| | | software has not been able to | +| | | perform some function. | ++-----------------------+---------------+-------------------------------------+ +| .. py:data:: CRITICAL | 50 | A serious error, indicating that the| +| | | program itself may be unable to | +| | | continue running. | ++-----------------------+---------------+-------------------------------------+ .. _handler: @@ -409,7 +439,7 @@ Handler Objects Handlers have the following attributes and methods. Note that :class:`Handler` is never instantiated directly; this class acts as a base for more useful -subclasses. However, the :meth:`__init__` method in subclasses needs to call +subclasses. However, the :meth:`!__init__` method in subclasses needs to call :meth:`Handler.__init__`. .. class:: Handler @@ -547,55 +577,53 @@ Formatter Objects .. currentmodule:: logging -:class:`Formatter` objects have the following attributes and methods. They are -responsible for converting a :class:`LogRecord` to (usually) a string which can -be interpreted by either a human or an external system. The base -:class:`Formatter` allows a formatting string to be specified. If none is -supplied, the default value of ``'%(message)s'`` is used, which just includes -the message in the logging call. To have additional items of information in the -formatted output (such as a timestamp), keep reading. - -A Formatter can be initialized with a format string which makes use of knowledge -of the :class:`LogRecord` attributes - such as the default value mentioned above -making use of the fact that the user's message and arguments are pre-formatted -into a :class:`LogRecord`'s *message* attribute. This format string contains -standard Python %-style mapping keys. See section :ref:`old-string-formatting` -for more information on string formatting. - -The useful mapping keys in a :class:`LogRecord` are given in the section on -:ref:`logrecord-attributes`. - - .. class:: Formatter(fmt=None, datefmt=None, style='%', validate=True, *, defaults=None) - Returns a new instance of the :class:`Formatter` class. The instance is - initialized with a format string for the message as a whole, as well as a - format string for the date/time portion of a message. If no *fmt* is - specified, ``'%(message)s'`` is used. If no *datefmt* is specified, a format - is used which is described in the :meth:`formatTime` documentation. + Responsible for converting a :class:`LogRecord` to an output string + to be interpreted by a human or external system. + + :param fmt: A format string in the given *style* for + the logged output as a whole. + The possible mapping keys are drawn from the :class:`LogRecord` object's + :ref:`logrecord-attributes`. + If not specified, ``'%(message)s'`` is used, + which is just the logged message. + :type fmt: str + + :param datefmt: A format string in the given *style* for + the date/time portion of the logged output. + If not specified, the default described in :meth:`formatTime` is used. + :type datefmt: str + + :param style: Can be one of ``'%'``, ``'{'`` or ``'$'`` and determines + how the format string will be merged with its data: using one of + :ref:`old-string-formatting` (``%``), :meth:`str.format` (``{``) + or :class:`string.Template` (``$``). This only applies to + *fmt* and *datefmt* (e.g. ``'%(message)s'`` versus ``'{message}'``), + not to the actual log messages passed to the logging methods. + However, there are :ref:`other ways <formatting-styles>` + to use ``{``- and ``$``-formatting for log messages. + :type style: str + + :param validate: If ``True`` (the default), incorrect or mismatched + *fmt* and *style* will raise a :exc:`ValueError`; for example, + ``logging.Formatter('%(asctime)s - %(message)s', style='{')``. + :type validate: bool + + :param defaults: A dictionary with default values to use in custom fields. + For example, + ``logging.Formatter('%(ip)s %(message)s', defaults={"ip": None})`` + :type defaults: dict[str, Any] - The *style* parameter can be one of '%', '{' or '$' and determines how - the format string will be merged with its data: using one of %-formatting, - :meth:`str.format` or :class:`string.Template`. This only applies to the - format string *fmt* (e.g. ``'%(message)s'`` or ``{message}``), not to the - actual log messages passed to ``Logger.debug`` etc; see - :ref:`formatting-styles` for more information on using {- and $-formatting - for log messages. + .. versionadded:: 3.2 + The *style* parameter. - The *defaults* parameter can be a dictionary with default values to use in - custom fields. For example: - ``logging.Formatter('%(ip)s %(message)s', defaults={"ip": None})`` + .. versionadded:: 3.8 + The *validate* parameter. - .. versionchanged:: 3.2 - The *style* parameter was added. + .. versionadded:: 3.10 + The *defaults* parameter. - .. versionchanged:: 3.8 - The *validate* parameter was added. Incorrect or mismatched style and fmt - will raise a ``ValueError``. - For example: ``logging.Formatter('%(asctime)s - %(message)s', style='{')``. - - .. versionchanged:: 3.10 - The *defaults* parameter was added. .. method:: format(record) @@ -719,9 +747,10 @@ empty string, all events are passed. .. method:: filter(record) - Is the specified record to be logged? Returns zero for no, nonzero for - yes. If deemed appropriate, the record may be modified in-place by this - method. + Is the specified record to be logged? Returns false for no, true for + yes. Filters can either modify log records in-place or return a completely + different record instance which will replace the original + log record in any future processing of the event. Note that filters attached to handlers are consulted before an event is emitted by the handler, whereas filters attached to loggers are consulted @@ -743,6 +772,12 @@ which has a ``filter`` method with the same semantics. parameter. The returned value should conform to that returned by :meth:`~Filter.filter`. +.. versionchanged:: 3.12 + You can now return a :class:`LogRecord` instance from filters to replace + the log record rather than modifying it in place. This allows filters attached to + a :class:`Handler` to modify the log record before it is emitted, without + having side effects on other handlers. + Although filters are used primarily to filter records based on more sophisticated criteria than levels, they get to see every record which is processed by the handler or logger they're attached to: this can be useful if @@ -796,8 +831,9 @@ wire). :type lineno: int :param msg: The event description message, - which can be a %-format string with placeholders for variable data. - :type msg: str + which can be a %-format string with placeholders for variable data, + or an arbitrary object (see :ref:`arbitrary-object-messages`). + :type msg: typing.Any :param args: Variable data to merge into the *msg* argument to obtain the event description. @@ -871,7 +907,7 @@ you want to use. In the case of {}-formatting, you can specify formatting flags by placing them after the attribute name, separated from it with a colon. For example: a -placeholder of ``{msecs:03d}`` would format a millisecond value of ``4`` as +placeholder of ``{msecs:03.0f}`` would format a millisecond value of ``4`` as ``004``. Refer to the :meth:`str.format` documentation for full details on the options available to you. @@ -948,10 +984,14 @@ the options available to you. +----------------+-------------------------+-----------------------------------------------+ | threadName | ``%(threadName)s`` | Thread name (if available). | +----------------+-------------------------+-----------------------------------------------+ +| taskName | ``%(taskName)s`` | :class:`asyncio.Task` name (if available). | ++----------------+-------------------------+-----------------------------------------------+ .. versionchanged:: 3.1 *processName* was added. +.. versionchanged:: 3.12 + *taskName* was added. .. _logger-adapter: @@ -975,23 +1015,33 @@ information into logging calls. For a usage example, see the section on 'extra'. The return value is a (*msg*, *kwargs*) tuple which has the (possibly modified) versions of the arguments passed in. -In addition to the above, :class:`LoggerAdapter` supports the following -methods of :class:`Logger`: :meth:`~Logger.debug`, :meth:`~Logger.info`, -:meth:`~Logger.warning`, :meth:`~Logger.error`, :meth:`~Logger.exception`, -:meth:`~Logger.critical`, :meth:`~Logger.log`, :meth:`~Logger.isEnabledFor`, -:meth:`~Logger.getEffectiveLevel`, :meth:`~Logger.setLevel` and -:meth:`~Logger.hasHandlers`. These methods have the same signatures as their -counterparts in :class:`Logger`, so you can use the two types of instances -interchangeably. + .. attribute:: manager -.. versionchanged:: 3.2 - The :meth:`~Logger.isEnabledFor`, :meth:`~Logger.getEffectiveLevel`, - :meth:`~Logger.setLevel` and :meth:`~Logger.hasHandlers` methods were added - to :class:`LoggerAdapter`. These methods delegate to the underlying logger. + Delegates to the underlying :attr:`!manager`` on *logger*. + + .. attribute:: _log + + Delegates to the underlying :meth:`!_log`` method on *logger*. + + In addition to the above, :class:`LoggerAdapter` supports the following + methods of :class:`Logger`: :meth:`~Logger.debug`, :meth:`~Logger.info`, + :meth:`~Logger.warning`, :meth:`~Logger.error`, :meth:`~Logger.exception`, + :meth:`~Logger.critical`, :meth:`~Logger.log`, :meth:`~Logger.isEnabledFor`, + :meth:`~Logger.getEffectiveLevel`, :meth:`~Logger.setLevel` and + :meth:`~Logger.hasHandlers`. These methods have the same signatures as their + counterparts in :class:`Logger`, so you can use the two types of instances + interchangeably. + + .. versionchanged:: 3.2 + + The :meth:`~Logger.isEnabledFor`, :meth:`~Logger.getEffectiveLevel`, + :meth:`~Logger.setLevel` and :meth:`~Logger.hasHandlers` methods were added + to :class:`LoggerAdapter`. These methods delegate to the underlying logger. -.. versionchanged:: 3.6 - Attribute :attr:`manager` and method :meth:`_log` were added, which - delegate to the underlying logger and allow adapters to be nested. + .. versionchanged:: 3.6 + + Attribute :attr:`!manager` and method :meth:`!_log` were added, which + delegate to the underlying logger and allow adapters to be nested. Thread Safety @@ -1236,6 +1286,19 @@ functions. This undocumented behaviour was considered a mistake, and was removed in Python 3.4, but reinstated in 3.4.2 due to retain backward compatibility. +.. function:: getHandlerByName(name) + + Returns a handler with the specified *name*, or ``None`` if there is no handler + with that name. + + .. versionadded:: 3.12 + +.. function:: getHandlerNames() + + Returns an immutable set of all known handler names. + + .. versionadded:: 3.12 + .. function:: makeLogRecord(attrdict) Creates and returns a new :class:`LogRecord` instance whose attributes are @@ -1362,8 +1425,8 @@ functions. .. function:: setLoggerClass(klass) Tells the logging system to use the class *klass* when instantiating a logger. - The class should define :meth:`__init__` such that only a name argument is - required, and the :meth:`__init__` should call :meth:`Logger.__init__`. This + The class should define :meth:`!__init__` such that only a name argument is + required, and the :meth:`!__init__` should call :meth:`!Logger.__init__`. This function is typically called before any loggers are instantiated by applications which need to use custom logger behavior. After this call, as at any other time, do not instantiate loggers directly using the subclass: continue to use diff --git a/Doc/library/lzma.rst b/Doc/library/lzma.rst index 868d4dcf..434e7ac9 100644 --- a/Doc/library/lzma.rst +++ b/Doc/library/lzma.rst @@ -100,7 +100,8 @@ Reading and writing compressed files *filters* arguments have the same meanings as for :class:`LZMACompressor`. :class:`LZMAFile` supports all the members specified by - :class:`io.BufferedIOBase`, except for :meth:`detach` and :meth:`truncate`. + :class:`io.BufferedIOBase`, except for :meth:`~io.BufferedIOBase.detach` + and :meth:`~io.IOBase.truncate`. Iteration and the :keyword:`with` statement are supported. The following method is also provided: diff --git a/Doc/library/mailbox.rst b/Doc/library/mailbox.rst index 56908ded..91df07d9 100644 --- a/Doc/library/mailbox.rst +++ b/Doc/library/mailbox.rst @@ -477,7 +477,7 @@ Supported mailbox formats are Maildir, mbox, MH, Babyl, and MMDF. unlock() Three locking mechanisms are used---dot locking and, if available, the - :c:func:`flock` and :c:func:`lockf` system calls. + :c:func:`!flock` and :c:func:`!lockf` system calls. .. seealso:: @@ -588,7 +588,7 @@ Supported mailbox formats are Maildir, mbox, MH, Babyl, and MMDF. unlock() Three locking mechanisms are used---dot locking and, if available, the - :c:func:`flock` and :c:func:`lockf` system calls. For MH mailboxes, locking + :c:func:`!flock` and :c:func:`!lockf` system calls. For MH mailboxes, locking the mailbox means locking the :file:`.mh_sequences` file and, only for the duration of any operations that affect them, locking individual message files. @@ -686,7 +686,7 @@ Supported mailbox formats are Maildir, mbox, MH, Babyl, and MMDF. unlock() Three locking mechanisms are used---dot locking and, if available, the - :c:func:`flock` and :c:func:`lockf` system calls. + :c:func:`!flock` and :c:func:`!lockf` system calls. .. seealso:: @@ -737,7 +737,7 @@ Supported mailbox formats are Maildir, mbox, MH, Babyl, and MMDF. unlock() Three locking mechanisms are used---dot locking and, if available, the - :c:func:`flock` and :c:func:`lockf` system calls. + :c:func:`!flock` and :c:func:`!lockf` system calls. .. seealso:: diff --git a/Doc/library/marshal.rst b/Doc/library/marshal.rst index 24f9dc16..0556f196 100644 --- a/Doc/library/marshal.rst +++ b/Doc/library/marshal.rst @@ -15,8 +15,8 @@ undocumented on purpose; it may change between Python versions (although it rarely does). [#]_ .. index:: - module: pickle - module: shelve + pair: module; pickle + pair: module; shelve This is not a general "persistence" module. For general persistence and transfer of Python objects through RPC calls, see the modules :mod:`pickle` and diff --git a/Doc/library/math.rst b/Doc/library/math.rst index 8d48656d..9e58b552 100644 --- a/Doc/library/math.rst +++ b/Doc/library/math.rst @@ -108,12 +108,7 @@ Number-theoretic and representation functions .. function:: fsum(iterable) Return an accurate floating point sum of values in the iterable. Avoids - loss of precision by tracking multiple intermediate partial sums:: - - >>> sum([.1, .1, .1, .1, .1, .1, .1, .1, .1, .1]) - 0.9999999999999999 - >>> fsum([.1, .1, .1, .1, .1, .1, .1, .1, .1, .1]) - 1.0 + loss of precision by tracking multiple intermediate partial sums. The algorithm's accuracy depends on IEEE-754 arithmetic guarantees and the typical case where the rounding mode is half-even. On some non-Windows @@ -229,11 +224,11 @@ Number-theoretic and representation functions of *x* and are floats. -.. function:: nextafter(x, y) +.. function:: nextafter(x, y, steps=1) - Return the next floating-point value after *x* towards *y*. + Return the floating-point value *steps* steps after *x* towards *y*. - If *x* is equal to *y*, return *y*. + If *x* is equal to *y*, return *y*, unless *steps* is zero. Examples: @@ -244,6 +239,9 @@ Number-theoretic and representation functions See also :func:`math.ulp`. + .. versionchanged:: 3.12 + Added the *steps* argument. + .. versionadded:: 3.9 .. function:: perm(n, k=None) @@ -296,6 +294,22 @@ Number-theoretic and representation functions .. versionadded:: 3.7 +.. function:: sumprod(p, q) + + Return the sum of products of values from two iterables *p* and *q*. + + Raises :exc:`ValueError` if the inputs do not have the same length. + + Roughly equivalent to:: + + sum(itertools.starmap(operator.mul, zip(p, q, strict=True))) + + For float and mixed int/float inputs, the intermediate products + and sums are computed with extended precision. + + .. versionadded:: 3.12 + + .. function:: trunc(x) Return *x* with the fractional part @@ -371,7 +385,7 @@ Power and logarithmic functions logarithms. For small floats *x*, the subtraction in ``exp(x) - 1`` can result in a `significant loss of precision <https://en.wikipedia.org/wiki/Loss_of_significance>`_\; the :func:`expm1` - function provides a way to compute this quantity to full precision:: + function provides a way to compute this quantity to full precision: >>> from math import exp, expm1 >>> exp(1e-5) - 1 # gives result accurate to 11 places @@ -534,7 +548,7 @@ Angular conversion Hyperbolic functions -------------------- -`Hyperbolic functions <https://en.wikipedia.org/wiki/Hyperbolic_function>`_ +`Hyperbolic functions <https://en.wikipedia.org/wiki/Hyperbolic_functions>`_ are analogs of trigonometric functions that are based on hyperbolas instead of circles. @@ -654,7 +668,7 @@ Constants not considered to equal to any other numeric value, including themselves. To check whether a number is a NaN, use the :func:`isnan` function to test for NaNs instead of ``is`` or ``==``. - Example:: + Example: >>> import math >>> math.nan == math.nan diff --git a/Doc/library/mmap.rst b/Doc/library/mmap.rst index c4f8781f..69afadff 100644 --- a/Doc/library/mmap.rst +++ b/Doc/library/mmap.rst @@ -370,11 +370,19 @@ MAP_* Constants MAP_ANONYMOUS MAP_POPULATE MAP_STACK + MAP_ALIGNED_SUPER + MAP_CONCEAL - These are the various flags that can be passed to :meth:`mmap.mmap`. Note that some options might not be present on some systems. + These are the various flags that can be passed to :meth:`mmap.mmap`. :data:`MAP_ALIGNED_SUPER` + is only available at FreeBSD and :data:`MAP_CONCEAL` is only available at OpenBSD. Note + that some options might not be present on some systems. .. versionchanged:: 3.10 - Added MAP_POPULATE constant. + Added :data:`MAP_POPULATE` constant. .. versionadded:: 3.11 - Added MAP_STACK constant. + Added :data:`MAP_STACK` constant. + + .. versionadded:: 3.12 + Added :data:`MAP_ALIGNED_SUPER` constant. + Added :data:`MAP_CONCEAL` constant. diff --git a/Doc/library/msvcrt.rst b/Doc/library/msvcrt.rst index 42fffee6..32693e3d 100644 --- a/Doc/library/msvcrt.rst +++ b/Doc/library/msvcrt.rst @@ -38,7 +38,7 @@ File Operations Lock part of a file based on file descriptor *fd* from the C runtime. Raises :exc:`OSError` on failure. The locked region of the file extends from the current file position for *nbytes* bytes, and may continue beyond the end of the - file. *mode* must be one of the :const:`LK_\*` constants listed below. Multiple + file. *mode* must be one of the :const:`!LK_\*` constants listed below. Multiple regions in a file may be locked at the same time, but may not overlap. Adjacent regions are not merged; they must be unlocked individually. diff --git a/Doc/library/multiprocessing.rst b/Doc/library/multiprocessing.rst index b5ceeb79..2f0f1f80 100644 --- a/Doc/library/multiprocessing.rst +++ b/Doc/library/multiprocessing.rst @@ -19,7 +19,7 @@ offers both local and remote concurrency, effectively side-stepping the :term:`Global Interpreter Lock <global interpreter lock>` by using subprocesses instead of threads. Due to this, the :mod:`multiprocessing` module allows the programmer to fully -leverage multiple processors on a given machine. It runs on both Unix and +leverage multiple processors on a given machine. It runs on both POSIX and Windows. The :mod:`multiprocessing` module also introduces APIs which do not have @@ -99,11 +99,11 @@ necessary, see :ref:`multiprocessing-programming`. +.. _multiprocessing-start-methods: + Contexts and start methods ~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. _multiprocessing-start-methods: - Depending on the platform, :mod:`multiprocessing` supports three ways to start a process. These *start methods* are @@ -115,7 +115,7 @@ to start a process. These *start methods* are will not be inherited. Starting a process using this method is rather slow compared to using *fork* or *forkserver*. - Available on Unix and Windows. The default on Windows and macOS. + Available on POSIX and Windows platforms. The default on Windows and macOS. *fork* The parent process uses :func:`os.fork` to fork the Python @@ -124,32 +124,45 @@ to start a process. These *start methods* are inherited by the child process. Note that safely forking a multithreaded process is problematic. - Available on Unix only. The default on Unix. + Available on POSIX systems. Currently the default on POSIX except macOS. + + .. note:: + The default start method will change away from *fork* in Python 3.14. + Code that requires *fork* should explicitly specify that via + :func:`get_context` or :func:`set_start_method`. + + .. versionchanged:: 3.12 + If Python is able to detect that your process has multiple threads, the + :func:`os.fork` function that this start method calls internally will + raise a :exc:`DeprecationWarning`. Use a different start method. + See the :func:`os.fork` documentation for further explanation. *forkserver* When the program starts and selects the *forkserver* start method, - a server process is started. From then on, whenever a new process + a server process is spawned. From then on, whenever a new process is needed, the parent process connects to the server and requests - that it fork a new process. The fork server process is single - threaded so it is safe for it to use :func:`os.fork`. No - unnecessary resources are inherited. + that it fork a new process. The fork server process is single threaded + unless system libraries or preloaded imports spawn threads as a + side-effect so it is generally safe for it to use :func:`os.fork`. + No unnecessary resources are inherited. + + Available on POSIX platforms which support passing file descriptors + over Unix pipes such as Linux. - Available on Unix platforms which support passing file descriptors - over Unix pipes. .. versionchanged:: 3.8 On macOS, the *spawn* start method is now the default. The *fork* start method should be considered unsafe as it can lead to crashes of the - subprocess. See :issue:`33725`. + subprocess as macOS system libraries may start threads. See :issue:`33725`. .. versionchanged:: 3.4 - *spawn* added on all Unix platforms, and *forkserver* added for - some Unix platforms. + *spawn* added on all POSIX platforms, and *forkserver* added for + some POSIX platforms. Child processes no longer inherit all of the parents inheritable handles on Windows. -On Unix using the *spawn* or *forkserver* start methods will also +On POSIX using the *spawn* or *forkserver* start methods will also start a *resource tracker* process which tracks the unlinked named system resources (such as named semaphores or :class:`~multiprocessing.shared_memory.SharedMemory` objects) created @@ -211,10 +224,10 @@ library user. .. warning:: - The ``'spawn'`` and ``'forkserver'`` start methods cannot currently + The ``'spawn'`` and ``'forkserver'`` start methods generally cannot be used with "frozen" executables (i.e., binaries produced by - packages like **PyInstaller** and **cx_Freeze**) on Unix. - The ``'fork'`` start method does work. + packages like **PyInstaller** and **cx_Freeze**) on POSIX systems. + The ``'fork'`` start method may work if code does not use threads. Exchanging objects between processes @@ -453,16 +466,16 @@ process which created it. ... return x*x ... >>> with p: - ... p.map(f, [1,2,3]) + ... p.map(f, [1,2,3]) Process PoolWorker-1: Process PoolWorker-2: Process PoolWorker-3: Traceback (most recent call last): Traceback (most recent call last): Traceback (most recent call last): - AttributeError: 'module' object has no attribute 'f' - AttributeError: 'module' object has no attribute 'f' - AttributeError: 'module' object has no attribute 'f' + AttributeError: Can't get attribute 'f' on <module '__main__' (<class '_frozen_importlib.BuiltinImporter'>)> + AttributeError: Can't get attribute 'f' on <module '__main__' (<class '_frozen_importlib.BuiltinImporter'>)> + AttributeError: Can't get attribute 'f' on <module '__main__' (<class '_frozen_importlib.BuiltinImporter'>)> (If you try this it will actually output three full tracebacks interleaved in a semi-random fashion, and then you may have to @@ -629,14 +642,14 @@ The :mod:`multiprocessing` package mostly replicates the API of the calling :meth:`join()` is simpler. On Windows, this is an OS handle usable with the ``WaitForSingleObject`` - and ``WaitForMultipleObjects`` family of API calls. On Unix, this is + and ``WaitForMultipleObjects`` family of API calls. On POSIX, this is a file descriptor usable with primitives from the :mod:`select` module. .. versionadded:: 3.3 .. method:: terminate() - Terminate the process. On Unix this is done using the ``SIGTERM`` signal; + Terminate the process. On POSIX this is done using the ``SIGTERM`` signal; on Windows :c:func:`TerminateProcess` is used. Note that exit handlers and finally clauses, etc., will not be executed. @@ -653,7 +666,7 @@ The :mod:`multiprocessing` package mostly replicates the API of the .. method:: kill() - Same as :meth:`terminate()` but using the ``SIGKILL`` signal on Unix. + Same as :meth:`terminate()` but using the ``SIGKILL`` signal on POSIX. .. versionadded:: 3.7 @@ -676,16 +689,17 @@ The :mod:`multiprocessing` package mostly replicates the API of the .. doctest:: >>> import multiprocessing, time, signal - >>> p = multiprocessing.Process(target=time.sleep, args=(1000,)) + >>> mp_context = multiprocessing.get_context('spawn') + >>> p = mp_context.Process(target=time.sleep, args=(1000,)) >>> print(p, p.is_alive()) - <Process ... initial> False + <...Process ... initial> False >>> p.start() >>> print(p, p.is_alive()) - <Process ... started> True + <...Process ... started> True >>> p.terminate() >>> time.sleep(0.1) >>> print(p, p.is_alive()) - <Process ... stopped exitcode=-SIGTERM> False + <...Process ... stopped exitcode=-SIGTERM> False >>> p.exitcode == -signal.SIGTERM True @@ -815,7 +829,7 @@ For an example of the usage of queues for interprocess communication see Return the approximate size of the queue. Because of multithreading/multiprocessing semantics, this number is not reliable. - Note that this may raise :exc:`NotImplementedError` on Unix platforms like + Note that this may raise :exc:`NotImplementedError` on platforms like macOS where ``sem_getvalue()`` is not implemented. .. method:: empty() @@ -1034,9 +1048,8 @@ Miscellaneous Returns a list of the supported start methods, the first of which is the default. The possible start methods are ``'fork'``, - ``'spawn'`` and ``'forkserver'``. On Windows only ``'spawn'`` is - available. On Unix ``'fork'`` and ``'spawn'`` are always - supported, with ``'fork'`` being the default. + ``'spawn'`` and ``'forkserver'``. Not all platforms support all + methods. See :ref:`multiprocessing-start-methods`. .. versionadded:: 3.4 @@ -1048,7 +1061,7 @@ Miscellaneous If *method* is ``None`` then the default context is returned. Otherwise *method* should be ``'fork'``, ``'spawn'``, ``'forkserver'``. :exc:`ValueError` is raised if the specified - start method is not available. + start method is not available. See :ref:`multiprocessing-start-methods`. .. versionadded:: 3.4 @@ -1062,8 +1075,7 @@ Miscellaneous is true then ``None`` is returned. The return value can be ``'fork'``, ``'spawn'``, ``'forkserver'`` - or ``None``. ``'fork'`` is the default on Unix, while ``'spawn'`` is - the default on Windows and macOS. + or ``None``. See :ref:`multiprocessing-start-methods`. .. versionchanged:: 3.8 @@ -1084,11 +1096,27 @@ Miscellaneous before they can create child processes. .. versionchanged:: 3.4 - Now supported on Unix when the ``'spawn'`` start method is used. + Now supported on POSIX when the ``'spawn'`` start method is used. .. versionchanged:: 3.11 Accepts a :term:`path-like object`. +.. function:: set_forkserver_preload(module_names) + + Set a list of module names for the forkserver main process to attempt to + import so that their already imported state is inherited by forked + processes. Any :exc:`ImportError` when doing so is silently ignored. + This can be used as a performance enhancement to avoid repeated work + in every process. + + For this to work, it must be called before the forkserver process has been + launched (before creating a :class:`Pool` or starting a :class:`Process`). + + Only meaningful when using the ``'forkserver'`` start method. + See :ref:`multiprocessing-start-methods`. + + .. versionadded:: 3.4 + .. function:: set_start_method(method, force=False) Set the method which should be used to start child processes. @@ -1102,6 +1130,8 @@ Miscellaneous protected inside the ``if __name__ == '__main__'`` clause of the main module. + See :ref:`multiprocessing-start-methods`. + .. versionadded:: 3.4 .. note:: @@ -1906,7 +1936,8 @@ their parent process exits. The manager classes are defined in the .. doctest:: - >>> manager = multiprocessing.Manager() + >>> mp_context = multiprocessing.get_context('spawn') + >>> manager = mp_context.Manager() >>> Global = manager.Namespace() >>> Global.x = 10 >>> Global.y = 'hello' @@ -2018,8 +2049,8 @@ the proxy). In this way, a proxy can be used just like its referent can: .. doctest:: - >>> from multiprocessing import Manager - >>> manager = Manager() + >>> mp_context = multiprocessing.get_context('spawn') + >>> manager = mp_context.Manager() >>> l = manager.list([i*i for i in range(10)]) >>> print(l) [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] @@ -2520,7 +2551,7 @@ multiple connections at the same time. *timeout* is ``None`` then it will block for an unlimited period. A negative timeout is equivalent to a zero timeout. - For both Unix and Windows, an object can appear in *object_list* if + For both POSIX and Windows, an object can appear in *object_list* if it is * a readable :class:`~multiprocessing.connection.Connection` object; @@ -2531,7 +2562,7 @@ multiple connections at the same time. A connection or socket object is ready when there is data available to be read from it, or the other end has been closed. - **Unix**: ``wait(object_list, timeout)`` almost equivalent + **POSIX**: ``wait(object_list, timeout)`` almost equivalent ``select.select(object_list, [], [], timeout)``. The difference is that, if :func:`select.select` is interrupted by a signal, it can raise :exc:`OSError` with an error number of ``EINTR``, whereas @@ -2682,7 +2713,7 @@ handler type) for messages from different processes to get mixed up. Returns the logger used by :mod:`multiprocessing`. If necessary, a new one will be created. - When first created the logger has level :data:`logging.NOTSET` and no + When first created the logger has level :const:`logging.NOTSET` and no default handler. Messages sent to this logger will not by default propagate to the root logger. @@ -2803,7 +2834,7 @@ Thread safety of proxies Joining zombie processes - On Unix when a process finishes but has not been joined it becomes a zombie. + On POSIX when a process finishes but has not been joined it becomes a zombie. There should never be very many because each time a new process starts (or :func:`~multiprocessing.active_children` is called) all completed processes which have not yet been joined will be joined. Also calling a finished @@ -2866,7 +2897,7 @@ Joining processes that use queues Explicitly pass resources to child processes - On Unix using the *fork* start method, a child process can make + On POSIX using the *fork* start method, a child process can make use of a shared resource created in a parent process using a global resource. However, it is better to pass the object as an argument to the constructor for the child process. @@ -2963,7 +2994,7 @@ Global variables Safe importing of main module Make sure that the main module can be safely imported by a new Python - interpreter without causing unintended side effects (such a starting a new + interpreter without causing unintended side effects (such as starting a new process). For example, using the *spawn* or *forkserver* start method diff --git a/Doc/library/multiprocessing.shared_memory.rst b/Doc/library/multiprocessing.shared_memory.rst index 76046b34..f453e640 100644 --- a/Doc/library/multiprocessing.shared_memory.rst +++ b/Doc/library/multiprocessing.shared_memory.rst @@ -255,16 +255,17 @@ shared memory blocks created using that manager are all released when the :keyword:`with` statement's code block finishes execution. -.. class:: ShareableList(sequence=None, *, name=None) +.. class:: ShareableList(sequence=None, \*, name=None) Provides a mutable list-like object where all values stored within are stored in a shared memory block. This constrains storable values to - only the ``int``, ``float``, ``bool``, ``str`` (less than 10M bytes each), - ``bytes`` (less than 10M bytes each), and ``None`` built-in data types. - It also notably differs from the built-in ``list`` type in that these - lists can not change their overall length (i.e. no append, insert, etc.) - and do not support the dynamic creation of new :class:`ShareableList` - instances via slicing. + only the ``int`` (signed 64-bit), ``float``, ``bool``, ``str`` (less + than 10M bytes each when encoded as utf-8), ``bytes`` (less than 10M + bytes each), and ``None`` built-in data types. It also notably + differs from the built-in ``list`` type in that these lists can not + change their overall length (i.e. no append, insert, etc.) and do not + support the dynamic creation of new :class:`ShareableList` instances + via slicing. *sequence* is used in populating a new ``ShareableList`` full of values. Set to ``None`` to instead attach to an already existing @@ -275,6 +276,35 @@ shared memory blocks created using that manager are all released when the existing ``ShareableList``, specify its shared memory block's unique name while leaving ``sequence`` set to ``None``. + .. note:: + + A known issue exists for :class:`bytes` and :class:`str` values. + If they end with ``\x00`` nul bytes or characters, those may be + *silently stripped* when fetching them by index from the + :class:`ShareableList`. This ``.rstrip(b'\x00')`` behavior is + considered a bug and may go away in the future. See :gh:`106939`. + + For applications where rstripping of trailing nulls is a problem, + work around it by always unconditionally appending an extra non-0 + byte to the end of such values when storing and unconditionally + removing it when fetching: + + .. doctest:: + + >>> from multiprocessing import shared_memory + >>> nul_bug_demo = shared_memory.ShareableList(['?\x00', b'\x03\x02\x01\x00\x00\x00']) + >>> nul_bug_demo[0] + '?' + >>> nul_bug_demo[1] + b'\x03\x02\x01' + >>> nul_bug_demo.shm.unlink() + >>> padded = shared_memory.ShareableList(['?\x00\x07', b'\x03\x02\x01\x00\x00\x00\x07']) + >>> padded[0][:-1] + '?\x00' + >>> padded[1][:-1] + b'\x03\x02\x01\x00\x00\x00' + >>> padded.shm.unlink() + .. method:: count(value) Returns the number of occurrences of ``value``. diff --git a/Doc/library/netrc.rst b/Doc/library/netrc.rst index 88265d9b..c36e5cfe 100644 --- a/Doc/library/netrc.rst +++ b/Doc/library/netrc.rst @@ -51,9 +51,19 @@ the Unix :program:`ftp` program and other FTP clients. Exception raised by the :class:`~netrc.netrc` class when syntactical errors are encountered in source text. Instances of this exception provide three - interesting attributes: :attr:`msg` is a textual explanation of the error, - :attr:`filename` is the name of the source file, and :attr:`lineno` gives the - line number on which the error was found. + interesting attributes: + + .. attribute:: msg + + Textual explanation of the error. + + .. attribute:: filename + + The name of the source file. + + .. attribute:: lineno + + The line number on which the error was found. .. _netrc-objects: diff --git a/Doc/library/nntplib.rst b/Doc/library/nntplib.rst index a36c8a5d..143e4e0c 100644 --- a/Doc/library/nntplib.rst +++ b/Doc/library/nntplib.rst @@ -14,6 +14,23 @@ .. deprecated:: 3.11 The :mod:`nntplib` module is deprecated (see :pep:`594` for details). +.. testsetup:: + + import warnings + with warnings.catch_warnings(): + warnings.simplefilter('ignore', category=DeprecationWarning) + import nntplib + +.. testcleanup:: + + try: + s.quit() + except NameError: + pass + import sys + # Force a warning if any other file imports nntplib + sys.modules.pop('nntplib') + -------------- This module defines the class :class:`NNTP` which implements the client side of diff --git a/Doc/library/operator.rst b/Doc/library/operator.rst index 35e9b49e..57c67bcf 100644 --- a/Doc/library/operator.rst +++ b/Doc/library/operator.rst @@ -59,9 +59,9 @@ truth tests, identity tests, and boolean operations: __not__(obj) Return the outcome of :keyword:`not` *obj*. (Note that there is no - :meth:`__not__` method for object instances; only the interpreter core defines - this operation. The result is affected by the :meth:`__bool__` and - :meth:`__len__` methods.) + :meth:`!__not__` method for object instances; only the interpreter core defines + this operation. The result is affected by the :meth:`~object.__bool__` and + :meth:`~object.__len__` methods.) .. function:: truth(obj) @@ -244,7 +244,7 @@ Operations which work with sequences (some of them with mappings too) include: .. function:: length_hint(obj, default=0) - Return an estimated length for the object *o*. First try to return its + Return an estimated length for the object *obj*. First try to return its actual length, then an estimate using :meth:`object.__length_hint__`, and finally return the default value. @@ -327,7 +327,7 @@ expect a function argument. return g The items can be any type accepted by the operand's :meth:`__getitem__` - method. Dictionaries accept any hashable value. Lists, tuples, and + method. Dictionaries accept any :term:`hashable` value. Lists, tuples, and strings accept an index or a slice: >>> itemgetter(1)('ABCDEFG') diff --git a/Doc/library/optparse.rst b/Doc/library/optparse.rst index 3e29fed0..846b8e03 100644 --- a/Doc/library/optparse.rst +++ b/Doc/library/optparse.rst @@ -42,8 +42,8 @@ on the command-line, for example:: <yourscript> --file=outfile -q As it parses the command line, :mod:`optparse` sets attributes of the -``options`` object returned by :meth:`parse_args` based on user-supplied -command-line values. When :meth:`parse_args` returns from parsing this command +``options`` object returned by :meth:`~OptionParser.parse_args` based on user-supplied +command-line values. When :meth:`~OptionParser.parse_args` returns from parsing this command line, ``options.filename`` will be ``"outfile"`` and ``options.verbose`` will be ``False``. :mod:`optparse` supports both long and short options, allows short options to be merged together, and allows options to be associated with their @@ -285,10 +285,10 @@ program's command line:: (options, args) = parser.parse_args() -(If you like, you can pass a custom argument list to :meth:`parse_args`, but +(If you like, you can pass a custom argument list to :meth:`~OptionParser.parse_args`, but that's rarely necessary: by default it uses ``sys.argv[1:]``.) -:meth:`parse_args` returns two values: +:meth:`~OptionParser.parse_args` returns two values: * ``options``, an object containing values for all of your options---e.g. if ``--file`` takes a single string argument, then ``options.file`` will be the @@ -339,7 +339,7 @@ Now let's make up a fake command line and ask :mod:`optparse` to parse it:: When :mod:`optparse` sees the option string ``-f``, it consumes the next argument, ``foo.txt``, and stores it in ``options.filename``. So, after this -call to :meth:`parse_args`, ``options.filename`` is ``"foo.txt"``. +call to :meth:`~OptionParser.parse_args`, ``options.filename`` is ``"foo.txt"``. Some other option types supported by :mod:`optparse` are ``int`` and ``float``. Here's an option that expects an integer argument:: @@ -453,7 +453,8 @@ Again, the default value for ``verbose`` will be ``True``: the last default value supplied for any particular destination is the one that counts. A clearer way to specify default values is the :meth:`set_defaults` method of -OptionParser, which you can call at any time before calling :meth:`parse_args`:: +OptionParser, which you can call at any time before calling +:meth:`~OptionParser.parse_args`:: parser.set_defaults(verbose=True) parser.add_option(...) @@ -811,7 +812,7 @@ The first step in using :mod:`optparse` is to create an OptionParser instance. help option. When :mod:`optparse` prints the usage string, it expands ``%prog`` to ``os.path.basename(sys.argv[0])`` (or to ``prog`` if you passed that keyword argument). To suppress a usage message, pass the - special value :data:`optparse.SUPPRESS_USAGE`. + special value :const:`optparse.SUPPRESS_USAGE`. ``option_list`` (default: ``[]``) A list of Option objects to populate the parser with. The options in @@ -954,7 +955,16 @@ The canonical way to create an :class:`Option` instance is with the As you can see, most actions involve storing or updating a value somewhere. :mod:`optparse` always creates a special object for this, conventionally called -``options`` (it happens to be an instance of :class:`optparse.Values`). Option +``options``, which is an instance of :class:`optparse.Values`. + +.. class:: Values + + An object holding parsed argument names and values as attributes. + Normally created by calling when calling :meth:`OptionParser.parse_args`, + and can be overridden by a custom subclass passed to the *values* argument of + :meth:`OptionParser.parse_args` (as described in :ref:`optparse-parsing-arguments`). + +Option arguments (and various other values) are stored as attributes of this object, according to the :attr:`~Option.dest` (destination) option attribute. @@ -991,6 +1001,14 @@ one that makes sense for *all* options. Option attributes ^^^^^^^^^^^^^^^^^ +.. class:: Option + + A single command line argument, + with various attributes passed by keyword to the constructor. + Normally created with :meth:`OptionParser.add_option` rather than directly, + and can be overridden by a custom class via the *option_class* argument + to :class:`OptionParser`. + The following option attributes may be passed as keyword arguments to :meth:`OptionParser.add_option`. If you pass an option attribute that is not relevant to a particular option, or fail to pass a required option attribute, @@ -1060,7 +1078,7 @@ relevant to a particular option, or fail to pass a required option attribute, Help text to print for this option when listing all available options after the user supplies a :attr:`~Option.help` option (such as ``--help``). If no help text is supplied, the option will be listed without help text. To - hide this option, use the special value :data:`optparse.SUPPRESS_HELP`. + hide this option, use the special value :const:`optparse.SUPPRESS_HELP`. .. attribute:: Option.metavar @@ -1232,7 +1250,7 @@ must specify for any option using that action. If no :attr:`~Option.help` string is supplied for an option, it will still be listed in the help message. To omit an option entirely, use the special value - :data:`optparse.SUPPRESS_HELP`. + :const:`optparse.SUPPRESS_HELP`. :mod:`optparse` automatically adds a :attr:`~Option.help` option to all OptionParsers, so you do not normally need to create one. @@ -1321,35 +1339,37 @@ Parsing arguments ^^^^^^^^^^^^^^^^^ The whole point of creating and populating an OptionParser is to call its -:meth:`parse_args` method:: +:meth:`~OptionParser.parse_args` method. - (options, args) = parser.parse_args(args=None, values=None) +.. method:: OptionParser.parse_args(args=None, values=None) -where the input parameters are + Parse the command-line options found in *args*. -``args`` - the list of arguments to process (default: ``sys.argv[1:]``) + The input parameters are -``values`` - an :class:`optparse.Values` object to store option arguments in (default: a - new instance of :class:`Values`) -- if you give an existing object, the - option defaults will not be initialized on it + ``args`` + the list of arguments to process (default: ``sys.argv[1:]``) -and the return values are + ``values`` + an :class:`Values` object to store option arguments in (default: a + new instance of :class:`Values`) -- if you give an existing object, the + option defaults will not be initialized on it -``options`` - the same object that was passed in as ``values``, or the optparse.Values - instance created by :mod:`optparse` + and the return value is a pair ``(options, args)`` where -``args`` - the leftover positional arguments after all options have been processed + ``options`` + the same object that was passed in as *values*, or the ``optparse.Values`` + instance created by :mod:`optparse` + + ``args`` + the leftover positional arguments after all options have been processed The most common usage is to supply neither keyword argument. If you supply ``values``, it will be modified with repeated :func:`setattr` calls (roughly one for every option argument stored to an option destination) and returned by -:meth:`parse_args`. +:meth:`~OptionParser.parse_args`. -If :meth:`parse_args` encounters any errors in the argument list, it calls the +If :meth:`~OptionParser.parse_args` encounters any errors in the argument list, it calls the OptionParser's :meth:`error` method with an appropriate end-user error message. This ultimately terminates your process with an exit status of 2 (the traditional Unix exit status for command-line errors). @@ -1501,7 +1521,7 @@ OptionParser supports several other public methods: Set the usage string according to the rules described above for the ``usage`` constructor keyword argument. Passing ``None`` sets the default usage - string; use :data:`optparse.SUPPRESS_USAGE` to suppress a usage message. + string; use :const:`optparse.SUPPRESS_USAGE` to suppress a usage message. .. method:: OptionParser.print_usage(file=None) @@ -1644,7 +1664,7 @@ where the current list of leftover arguments, ie. arguments that have been consumed but are neither options nor option arguments. Feel free to modify ``parser.largs``, e.g. by adding more arguments to it. (This list will - become ``args``, the second return value of :meth:`parse_args`.) + become ``args``, the second return value of :meth:`~OptionParser.parse_args`.) ``parser.rargs`` the current list of remaining arguments, ie. with ``opt_str`` and @@ -2027,7 +2047,7 @@ Features of note: values.ensure_value(attr, value) If the ``attr`` attribute of ``values`` doesn't exist or is ``None``, then - ensure_value() first sets it to ``value``, and then returns 'value. This is + ensure_value() first sets it to ``value``, and then returns ``value``. This is very handy for actions like ``"extend"``, ``"append"``, and ``"count"``, all of which accumulate data in a variable and expect that variable to be of a certain type (a list for the first two, an integer for the latter). Using @@ -2035,3 +2055,27 @@ Features of note: about setting a default value for the option destinations in question; they can just leave the default as ``None`` and :meth:`ensure_value` will take care of getting it right when it's needed. + +Exceptions +---------- + +.. exception:: OptionError + + Raised if an :class:`Option` instance is created with invalid or + inconsistent arguments. + +.. exception:: OptionConflictError + + Raised if conflicting options are added to an :class:`OptionParser`. + +.. exception:: OptionValueError + + Raised if an invalid option value is encountered on the command line. + +.. exception:: BadOptionError + + Raised if an invalid option is passed on the command line. + +.. exception:: AmbiguousOptionError + + Raised if an ambiguous option is passed on the command line. diff --git a/Doc/library/os.path.rst b/Doc/library/os.path.rst index 22d07c47..6f9e0853 100644 --- a/Doc/library/os.path.rst +++ b/Doc/library/os.path.rst @@ -159,7 +159,7 @@ the :mod:`glob` module.) On Unix and Windows, return the argument with an initial component of ``~`` or ``~user`` replaced by that *user*'s home directory. - .. index:: module: pwd + .. index:: pair: module; pwd On Unix, an initial ``~`` is replaced by the environment variable :envvar:`HOME` if it is set; otherwise the current user's home directory is looked up in the @@ -266,6 +266,15 @@ the :mod:`glob` module.) Accepts a :term:`path-like object`. +.. function:: isjunction(path) + + Return ``True`` if *path* refers to an :func:`existing <lexists>` directory + entry that is a junction. Always return ``False`` if junctions are not + supported on the current platform. + + .. versionadded:: 3.12 + + .. function:: islink(path) Return ``True`` if *path* refers to an :func:`existing <exists>` directory @@ -295,6 +304,24 @@ the :mod:`glob` module.) Accepts a :term:`path-like object`. +.. function:: isdevdrive(path) + + Return ``True`` if pathname *path* is located on a Windows Dev Drive. + A Dev Drive is optimized for developer scenarios, and offers faster + performance for reading and writing files. It is recommended for use for + source code, temporary build directories, package caches, and other + IO-intensive operations. + + May raise an error for an invalid path, for example, one without a + recognizable drive, but returns ``False`` on platforms that do not support + Dev Drives. See `the Windows documentation <https://learn.microsoft.com/windows/dev-drive/>`_ + for information on enabling and creating Dev Drives. + + .. availability:: Windows. + + .. versionadded:: 3.12 + + .. function:: join(path, *paths) Join one or more path segments intelligently. The return value is the @@ -383,7 +410,7 @@ the :mod:`glob` module.) *start*. On Windows, :exc:`ValueError` is raised when *path* and *start* are on different drives. - *start* defaults to :attr:`os.curdir`. + *start* defaults to :data:`os.curdir`. .. availability:: Unix, Windows. @@ -470,7 +497,7 @@ the :mod:`glob` module.) ("c:", "/dir") If the path contains a UNC path, drive will contain the host name - and share, up to but not including the fourth separator:: + and share:: >>> splitdrive("//host/computer/dir") ("//host/computer", "/dir") @@ -479,6 +506,39 @@ the :mod:`glob` module.) Accepts a :term:`path-like object`. +.. function:: splitroot(path) + + Split the pathname *path* into a 3-item tuple ``(drive, root, tail)`` where + *drive* is a device name or mount point, *root* is a string of separators + after the drive, and *tail* is everything after the root. Any of these + items may be the empty string. In all cases, ``drive + root + tail`` will + be the same as *path*. + + On POSIX systems, *drive* is always empty. The *root* may be empty (if *path* is + relative), a single forward slash (if *path* is absolute), or two forward slashes + (implementation-defined per `IEEE Std 1003.1-2017; 4.13 Pathname Resolution + <https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13>`_.) + For example:: + + >>> splitroot('/home/sam') + ('', '/', 'home/sam') + >>> splitroot('//home/sam') + ('', '//', 'home/sam') + >>> splitroot('///home/sam') + ('', '/', '//home/sam') + + On Windows, *drive* may be empty, a drive-letter name, a UNC share, or a device + name. The *root* may be empty, a forward slash, or a backward slash. For + example:: + + >>> splitroot('C:/Users/Sam') + ('C:', '/', 'Users/Sam') + >>> splitroot('//Server/Share/Users/Sam') + ('//Server/Share', '/', 'Users/Sam') + + .. versionadded:: 3.12 + + .. function:: splitext(path) Split the pathname *path* into a pair ``(root, ext)`` such that ``root + ext == diff --git a/Doc/library/os.rst b/Doc/library/os.rst index 759064a6..4ffd520f 100644 --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -60,7 +60,7 @@ Notes on the availability of these functions: ``'java'``. .. seealso:: - :attr:`sys.platform` has a finer granularity. :func:`os.uname` gives + :data:`sys.platform` has a finer granularity. :func:`os.uname` gives system-dependent version information. The :mod:`platform` module provides detailed checks for the @@ -88,8 +88,8 @@ startup by the :c:func:`PyConfig_Read` function: see On some systems, conversion using the file system encoding may fail. In this case, Python uses the :ref:`surrogateescape encoding error handler <surrogateescape>`, which means that undecodable bytes are replaced by a - Unicode character U+DCxx on decoding, and these are again translated to the - original byte on encoding. + Unicode character U+DC\ *xx* on decoding, and these are again + translated to the original byte on encoding. The :term:`file system encoding <filesystem encoding and error handler>` must @@ -201,6 +201,11 @@ process and user. ``'surrogateescape'`` error handler. Use :data:`environb` if you would like to use a different encoding. + On Windows, the keys are converted to uppercase. This also applies when + getting, setting, or deleting an item. For example, + ``environ['monty'] = 'python'`` maps the key ``'MONTY'`` to the value + ``'python'``. + .. note:: Calling :func:`putenv` directly does not change :data:`os.environ`, so it's better @@ -210,7 +215,7 @@ process and user. On some platforms, including FreeBSD and macOS, setting ``environ`` may cause memory leaks. Refer to the system documentation for - :c:func:`putenv`. + :c:func:`!putenv`. You can delete items in this mapping to unset environment variables. :func:`unsetenv` will be called automatically when an item is deleted from @@ -228,7 +233,7 @@ process and user. :data:`environ` and :data:`environb` are synchronized (modifying :data:`environb` updates :data:`environ`, and vice versa). - :data:`environb` is only available if :data:`supports_bytes_environ` is + :data:`environb` is only available if :const:`supports_bytes_environ` is ``True``. .. versionadded:: 3.2 @@ -326,7 +331,7 @@ process and user. future environment changes. - :func:`getenvb` is only available if :data:`supports_bytes_environ` + :func:`getenvb` is only available if :const:`supports_bytes_environ` is ``True``. .. availability:: Unix. @@ -396,11 +401,11 @@ process and user. On macOS, :func:`getgroups` behavior differs somewhat from other Unix platforms. If the Python interpreter was built with a - deployment target of :const:`10.5` or earlier, :func:`getgroups` returns + deployment target of ``10.5`` or earlier, :func:`getgroups` returns the list of effective group ids associated with the current user process; this list is limited to a system-defined number of entries, typically 16, and may be modified by calls to :func:`setgroups` if suitably privileged. - If built with a deployment target greater than :const:`10.5`, + If built with a deployment target greater than ``10.5``, :func:`getgroups` returns the current group access list for the user associated with the effective user id of the process; the group access list may change over the lifetime of the process, it is not affected by @@ -488,6 +493,17 @@ process and user. .. versionadded:: 3.3 +.. data:: PRIO_DARWIN_THREAD + PRIO_DARWIN_PROCESS + PRIO_DARWIN_BG + PRIO_DARWIN_NONUI + + Parameters for the :func:`getpriority` and :func:`setpriority` functions. + + .. availability:: macOS + + .. versionadded:: 3.12 + .. function:: getresuid() Return a tuple (ruid, euid, suid) denoting the current process's @@ -548,7 +564,7 @@ process and user. .. note:: On some platforms, including FreeBSD and macOS, setting ``environ`` may - cause memory leaks. Refer to the system documentation for :c:func:`putenv`. + cause memory leaks. Refer to the system documentation for :c:func:`!putenv`. .. audit-event:: os.putenv key,value os.putenv @@ -590,9 +606,47 @@ process and user. See the documentation for :func:`getgroups` for cases where it may not return the same group list set by calling setgroups(). +.. function:: setns(fd, nstype=0) + + Reassociate the current thread with a Linux namespace. + See the :manpage:`setns(2)` and :manpage:`namespaces(7)` man pages for more + details. + + If *fd* refers to a :file:`/proc/{pid}/ns/` link, ``setns()`` reassociates the + calling thread with the namespace associated with that link, + and *nstype* may be set to one of the + :ref:`CLONE_NEW* constants <os-unshare-clone-flags>` + to impose constraints on the operation + (``0`` means no constraints). + + Since Linux 5.8, *fd* may refer to a PID file descriptor obtained from + :func:`~os.pidfd_open`. In this case, ``setns()`` reassociates the calling thread + into one or more of the same namespaces as the thread referred to by *fd*. + This is subject to any constraints imposed by *nstype*, + which is a bit mask combining one or more of the + :ref:`CLONE_NEW* constants <os-unshare-clone-flags>`, + e.g. ``setns(fd, os.CLONE_NEWUTS | os.CLONE_NEWPID)``. + The caller's memberships in unspecified namespaces are left unchanged. + + *fd* can be any object with a :meth:`~io.IOBase.fileno` method, or a raw file descriptor. + + This example reassociates the thread with the ``init`` process's network namespace:: + + fd = os.open("/proc/1/ns/net", os.O_RDONLY) + os.setns(fd, os.CLONE_NEWNET) + os.close(fd) + + .. availability:: Linux >= 3.0 with glibc >= 2.14. + + .. versionadded:: 3.12 + + .. seealso:: + + The :func:`~os.unshare` function. + .. function:: setpgrp() - Call the system call :c:func:`setpgrp` or ``setpgrp(0, 0)`` depending on + Call the system call :c:func:`!setpgrp` or ``setpgrp(0, 0)`` depending on which version is implemented (if any). See the Unix manual for the semantics. .. availability:: Unix, not Emscripten, not WASI. @@ -600,7 +654,7 @@ process and user. .. function:: setpgid(pid, pgrp, /) - Call the system call :c:func:`setpgid` to set the process group id of the + Call the system call :c:func:`!setpgid` to set the process group id of the process with id *pid* to the process group with id *pgrp*. See the Unix manual for the semantics. @@ -660,14 +714,14 @@ process and user. .. function:: getsid(pid, /) - Call the system call :c:func:`getsid`. See the Unix manual for the semantics. + Call the system call :c:func:`!getsid`. See the Unix manual for the semantics. .. availability:: Unix, not Emscripten, not WASI. .. function:: setsid() - Call the system call :c:func:`setsid`. See the Unix manual for the semantics. + Call the system call :c:func:`!setsid`. See the Unix manual for the semantics. .. availability:: Unix, not Emscripten, not WASI. @@ -685,7 +739,7 @@ process and user. .. function:: strerror(code, /) Return the error message corresponding to the error code in *code*. - On platforms where :c:func:`strerror` returns ``NULL`` when given an unknown + On platforms where :c:func:`!strerror` returns ``NULL`` when given an unknown error number, :exc:`ValueError` is raised. @@ -756,6 +810,49 @@ process and user. The function is now always available and is also available on Windows. +.. function:: unshare(flags) + + Disassociate parts of the process execution context, and move them into a + newly created namespace. + See the :manpage:`unshare(2)` + man page for more details. + The *flags* argument is a bit mask, combining zero or more of the + :ref:`CLONE_* constants <os-unshare-clone-flags>`, + that specifies which parts of the execution context should be + unshared from their existing associations and moved to a new namespace. + If the *flags* argument is ``0``, no changes are made to the calling process's + execution context. + + .. availability:: Linux >= 2.6.16. + + .. versionadded:: 3.12 + + .. seealso:: + + The :func:`~os.setns` function. + +.. _os-unshare-clone-flags: + +Flags to the :func:`unshare` function, if the implementation supports them. +See :manpage:`unshare(2)` in the Linux manual +for their exact effect and availability. + +.. data:: CLONE_FILES + CLONE_FS + CLONE_NEWCGROUP + CLONE_NEWIPC + CLONE_NEWNET + CLONE_NEWNS + CLONE_NEWPID + CLONE_NEWTIME + CLONE_NEWUSER + CLONE_NEWUTS + CLONE_SIGHAND + CLONE_SYSVSEM + CLONE_THREAD + CLONE_VM + + .. _os-newstreams: File Object Creation @@ -822,18 +919,32 @@ as internal buffering of data. Copy *count* bytes from file descriptor *src*, starting from offset *offset_src*, to file descriptor *dst*, starting from offset *offset_dst*. If *offset_src* is None, then *src* is read from the current position; - respectively for *offset_dst*. The files pointed by *src* and *dst* + respectively for *offset_dst*. + + In Linux kernel older than 5.3, the files pointed by *src* and *dst* must reside in the same filesystem, otherwise an :exc:`OSError` is - raised with :attr:`~OSError.errno` set to :data:`errno.EXDEV`. + raised with :attr:`~OSError.errno` set to :const:`errno.EXDEV`. This copy is done without the additional cost of transferring data from the kernel to user space and then back into the kernel. Additionally, - some filesystems could implement extra optimizations. The copy is done as if - both files are opened as binary. + some filesystems could implement extra optimizations, such as the use of + reflinks (i.e., two or more inodes that share pointers to the same + copy-on-write disk blocks; supported file systems include btrfs and XFS) + and server-side copy (in the case of NFS). + + The function copies bytes between two file descriptors. Text options, like + the encoding and the line ending, are ignored. The return value is the amount of bytes copied. This could be less than the amount requested. + .. note:: + + On Linux, :func:`os.copy_file_range` should not be used for copying a + range of a pseudo file from a special filesystem like procfs and sysfs. + It will always copy no bytes and return 0 as if the file was empty + because of a known Linux kernel issue. + .. availability:: Linux >= 4.5 with glibc >= 2.27. .. versionadded:: 3.8 @@ -966,7 +1077,7 @@ as internal buffering of data. .. function:: fsync(fd) Force write of file with filedescriptor *fd* to disk. On Unix, this calls the - native :c:func:`fsync` function; on Windows, the MS :c:func:`_commit` function. + native :c:func:`!fsync` function; on Windows, the MS :c:func:`!_commit` function. If you're starting with a buffered Python :term:`file object` *f*, first do ``f.flush()``, and then do ``os.fsync(f.fileno())``, to ensure that all internal @@ -996,13 +1107,17 @@ as internal buffering of data. See also :func:`set_blocking` and :meth:`socket.socket.setblocking`. - .. availability:: Unix. + .. availability:: Unix, Windows. The function is limited on Emscripten and WASI, see :ref:`wasm-availability` for more information. + On Windows, this function is limited to pipes. + .. versionadded:: 3.5 + .. versionchanged:: 3.12 + Added support for pipes on Windows. .. function:: isatty(fd, /) @@ -1048,25 +1163,65 @@ as internal buffering of data. .. versionadded:: 3.11 -.. function:: lseek(fd, pos, how, /) +.. function:: lseek(fd, pos, whence, /) Set the current position of file descriptor *fd* to position *pos*, modified - by *how*: :const:`SEEK_SET` or ``0`` to set the position relative to the - beginning of the file; :const:`SEEK_CUR` or ``1`` to set it relative to the - current position; :const:`SEEK_END` or ``2`` to set it relative to the end of - the file. Return the new cursor position in bytes, starting from the beginning. + by *whence*, and return the new position in bytes relative to + the start of the file. + Valid values for *whence* are: + + * :const:`SEEK_SET` or ``0`` -- set *pos* relative to the beginning of the file + * :const:`SEEK_CUR` or ``1`` -- set *pos* relative to the current file position + * :const:`SEEK_END` or ``2`` -- set *pos* relative to the end of the file + * :const:`SEEK_HOLE` -- set *pos* to the next data location, relative to *pos* + * :const:`SEEK_DATA` -- set *pos* to the next data hole, relative to *pos* + + .. versionchanged:: 3.3 + + Add support for :const:`!SEEK_HOLE` and :const:`!SEEK_DATA`. .. data:: SEEK_SET SEEK_CUR SEEK_END - Parameters to the :func:`lseek` function. Their values are 0, 1, and 2, - respectively. + Parameters to the :func:`lseek` function and the :meth:`~io.IOBase.seek` + method on :term:`file-like objects <file object>`, + for whence to adjust the file position indicator. + + :const:`SEEK_SET` + Adjust the file position relative to the beginning of the file. + :const:`SEEK_CUR` + Adjust the file position relative to the current file position. + :const:`SEEK_END` + Adjust the file position relative to the end of the file. + + Their values are 0, 1, and 2, respectively. + + +.. data:: SEEK_HOLE + SEEK_DATA + + Parameters to the :func:`lseek` function and the :meth:`~io.IOBase.seek` + method on :term:`file-like objects <file object>`, + for seeking file data and holes on sparsely allocated files. + + :data:`!SEEK_DATA` + Adjust the file offset to the next location containing data, + relative to the seek position. + + :data:`!SEEK_HOLE` + Adjust the file offset to the next location containing a hole, + relative to the seek position. + A hole is defined as a sequence of zeros. + + .. note:: + + These operations only make sense for filesystems that support them. + + .. availability:: Linux >= 3.1, macOS, Unix .. versionadded:: 3.3 - Some operating systems could support additional values, like - :data:`os.SEEK_HOLE` or :data:`os.SEEK_DATA`. .. function:: open(path, flags, mode=0o777, *, dir_fd=None) @@ -1180,7 +1335,7 @@ or `the MSDN <https://msdn.microsoft.com/en-us/library/z0kc8e3z.aspx>`_ on Windo .. function:: openpty() - .. index:: module: pty + .. index:: pair: module; pty Open a new pseudo-terminal pair. Return a pair of file descriptors ``(master, slave)`` for the pty and the tty, respectively. The new file @@ -1307,7 +1462,7 @@ or `the MSDN <https://msdn.microsoft.com/en-us/library/z0kc8e3z.aspx>`_ on Windo If some data was successfully read, it will return the number of bytes read. If no bytes were read, it will return ``-1`` and set errno to - :data:`errno.EAGAIN`. + :const:`errno.EAGAIN`. .. availability:: Linux >= 4.14. @@ -1463,21 +1618,6 @@ or `the MSDN <https://msdn.microsoft.com/en-us/library/z0kc8e3z.aspx>`_ on Windo Parameters *out* and *in* was renamed to *out_fd* and *in_fd*. -.. function:: set_blocking(fd, blocking, /) - - Set the blocking mode of the specified file descriptor. Set the - :data:`O_NONBLOCK` flag if blocking is ``False``, clear the flag otherwise. - - See also :func:`get_blocking` and :meth:`socket.socket.setblocking`. - - .. availability:: Unix. - - The function is limited on Emscripten and WASI, see - :ref:`wasm-availability` for more information. - - .. versionadded:: 3.5 - - .. data:: SF_NODISKIO SF_MNOWAIT SF_SYNC @@ -1499,6 +1639,26 @@ or `the MSDN <https://msdn.microsoft.com/en-us/library/z0kc8e3z.aspx>`_ on Windo .. versionadded:: 3.11 +.. function:: set_blocking(fd, blocking, /) + + Set the blocking mode of the specified file descriptor. Set the + :data:`O_NONBLOCK` flag if blocking is ``False``, clear the flag otherwise. + + See also :func:`get_blocking` and :meth:`socket.socket.setblocking`. + + .. availability:: Unix, Windows. + + The function is limited on Emscripten and WASI, see + :ref:`wasm-availability` for more information. + + On Windows, this function is limited to pipes. + + .. versionadded:: 3.5 + + .. versionchanged:: 3.12 + Added support for pipes on Windows. + + .. function:: splice(src, dst, count, offset_src=None, offset_dst=None) Transfer *count* bytes from file descriptor *src*, starting from offset @@ -1508,7 +1668,7 @@ or `the MSDN <https://msdn.microsoft.com/en-us/library/z0kc8e3z.aspx>`_ on Windo *offset_dst*. The offset associated to the file descriptor that refers to a pipe must be ``None``. The files pointed by *src* and *dst* must reside in the same filesystem, otherwise an :exc:`OSError` is raised with - :attr:`~OSError.errno` set to :data:`errno.EXDEV`. + :attr:`~OSError.errno` set to :const:`errno.EXDEV`. This copy is done without the additional cost of transferring data from the kernel to user space and then back into the kernel. Additionally, @@ -1841,18 +2001,18 @@ features: Set the flags of *path* to the numeric *flags*. *flags* may take a combination (bitwise OR) of the following values (as defined in the :mod:`stat` module): - * :data:`stat.UF_NODUMP` - * :data:`stat.UF_IMMUTABLE` - * :data:`stat.UF_APPEND` - * :data:`stat.UF_OPAQUE` - * :data:`stat.UF_NOUNLINK` - * :data:`stat.UF_COMPRESSED` - * :data:`stat.UF_HIDDEN` - * :data:`stat.SF_ARCHIVED` - * :data:`stat.SF_IMMUTABLE` - * :data:`stat.SF_APPEND` - * :data:`stat.SF_NOUNLINK` - * :data:`stat.SF_SNAPSHOT` + * :const:`stat.UF_NODUMP` + * :const:`stat.UF_IMMUTABLE` + * :const:`stat.UF_APPEND` + * :const:`stat.UF_OPAQUE` + * :const:`stat.UF_NOUNLINK` + * :const:`stat.UF_COMPRESSED` + * :const:`stat.UF_HIDDEN` + * :const:`stat.SF_ARCHIVED` + * :const:`stat.SF_IMMUTABLE` + * :const:`stat.SF_APPEND` + * :const:`stat.SF_NOUNLINK` + * :const:`stat.SF_SNAPSHOT` This function can support :ref:`not following symlinks <follow_symlinks>`. @@ -1873,25 +2033,25 @@ features: following values (as defined in the :mod:`stat` module) or bitwise ORed combinations of them: - * :data:`stat.S_ISUID` - * :data:`stat.S_ISGID` - * :data:`stat.S_ENFMT` - * :data:`stat.S_ISVTX` - * :data:`stat.S_IREAD` - * :data:`stat.S_IWRITE` - * :data:`stat.S_IEXEC` - * :data:`stat.S_IRWXU` - * :data:`stat.S_IRUSR` - * :data:`stat.S_IWUSR` - * :data:`stat.S_IXUSR` - * :data:`stat.S_IRWXG` - * :data:`stat.S_IRGRP` - * :data:`stat.S_IWGRP` - * :data:`stat.S_IXGRP` - * :data:`stat.S_IRWXO` - * :data:`stat.S_IROTH` - * :data:`stat.S_IWOTH` - * :data:`stat.S_IXOTH` + * :const:`stat.S_ISUID` + * :const:`stat.S_ISGID` + * :const:`stat.S_ENFMT` + * :const:`stat.S_ISVTX` + * :const:`stat.S_IREAD` + * :const:`stat.S_IWRITE` + * :const:`stat.S_IEXEC` + * :const:`stat.S_IRWXU` + * :const:`stat.S_IRUSR` + * :const:`stat.S_IWUSR` + * :const:`stat.S_IXUSR` + * :const:`stat.S_IRWXG` + * :const:`stat.S_IRGRP` + * :const:`stat.S_IWGRP` + * :const:`stat.S_IXGRP` + * :const:`stat.S_IRWXO` + * :const:`stat.S_IROTH` + * :const:`stat.S_IWOTH` + * :const:`stat.S_IXOTH` This function can support :ref:`specifying a file descriptor <path_fd>`, :ref:`paths relative to directory descriptors <dir_fd>` and :ref:`not @@ -2031,7 +2191,7 @@ features: .. audit-event:: os.link src,dst,src_dir_fd,dst_dir_fd os.link - .. availability:: Unix, Windows. + .. availability:: Unix, Windows, not Emscripten. .. versionchanged:: 3.2 Added Windows support. @@ -2080,9 +2240,72 @@ features: Accepts a :term:`path-like object`. +.. function:: listdrives() + + Return a list containing the names of drives on a Windows system. + + A drive name typically looks like ``'C:\\'``. Not every drive name + will be associated with a volume, and some may be inaccessible for + a variety of reasons, including permissions, network connectivity + or missing media. This function does not test for access. + + May raise :exc:`OSError` if an error occurs collecting the drive + names. + + .. audit-event:: os.listdrives "" os.listdrives + + .. availability:: Windows + + .. versionadded:: 3.12 + + +.. function:: listmounts(volume) + + Return a list containing the mount points for a volume on a Windows + system. + + *volume* must be represented as a GUID path, like those returned by + :func:`os.listvolumes`. Volumes may be mounted in multiple locations + or not at all. In the latter case, the list will be empty. Mount + points that are not associated with a volume will not be returned by + this function. + + The mount points return by this function will be absolute paths, and + may be longer than the drive name. + + Raises :exc:`OSError` if the volume is not recognized or if an error + occurs collecting the paths. + + .. audit-event:: os.listmounts volume os.listmounts + + .. availability:: Windows + + .. versionadded:: 3.12 + + +.. function:: listvolumes() + + Return a list containing the volumes in the system. + + Volumes are typically represented as a GUID path that looks like + ``\\?\Volume{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}\``. Files can + usually be accessed through a GUID path, permissions allowing. + However, users are generally not familiar with them, and so the + recommended use of this function is to retrieve mount points + using :func:`os.listmounts`. + + May raise :exc:`OSError` if an error occurs collecting the volumes. + + .. audit-event:: os.listvolumes "" os.listvolumes + + .. availability:: Windows + + .. versionadded:: 3.12 + + .. function:: lstat(path, *, dir_fd=None) - Perform the equivalent of an :c:func:`lstat` system call on the given path. + Perform the equivalent of an :c:func:`!lstat` system call on the given path. Similar to :func:`~os.stat`, but does not follow symbolic links. Return a :class:`stat_result` object. @@ -2238,13 +2461,13 @@ features: .. function:: major(device, /) Extract the device major number from a raw device number (usually the - :attr:`st_dev` or :attr:`st_rdev` field from :c:type:`stat`). + :attr:`st_dev` or :attr:`st_rdev` field from :c:struct:`stat`). .. function:: minor(device, /) Extract the device minor number from a raw device number (usually the - :attr:`st_dev` or :attr:`st_rdev` field from :c:type:`stat`). + :attr:`st_dev` or :attr:`st_rdev` field from :c:struct:`stat`). .. function:: makedev(major, minor, /) @@ -2645,6 +2868,17 @@ features: This method can raise :exc:`OSError`, such as :exc:`PermissionError`, but :exc:`FileNotFoundError` is caught and not raised. + .. method:: is_junction() + + Return ``True`` if this entry is a junction (even if broken); + return ``False`` if the entry points to a regular directory, any kind + of file, a symlink, or if it doesn't exist anymore. + + The result is cached on the ``os.DirEntry`` object. Call + :func:`os.path.isjunction` to fetch up-to-date information. + + .. versionadded:: 3.12 + .. method:: stat(*, follow_symlinks=True) Return a :class:`stat_result` object for this entry. This method @@ -2667,8 +2901,8 @@ features: Note that there is a nice correspondence between several attributes and methods of ``os.DirEntry`` and of :class:`pathlib.Path`. In particular, the ``name`` attribute has the same - meaning, as do the ``is_dir()``, ``is_file()``, ``is_symlink()`` - and ``stat()`` methods. + meaning, as do the ``is_dir()``, ``is_file()``, ``is_symlink()``, + ``is_junction()``, and ``stat()`` methods. .. versionadded:: 3.5 @@ -2676,6 +2910,12 @@ features: Added support for the :class:`~os.PathLike` interface. Added support for :class:`bytes` paths on Windows. + .. versionchanged:: 3.12 + The ``st_ctime`` attribute of a stat result is deprecated on Windows. + The file creation time is properly available as ``st_birthtime``, and + in the future ``st_ctime`` may be changed to return zero or the + metadata change time, if available. + .. function:: stat(path, *, dir_fd=None, follow_symlinks=True) @@ -2702,7 +2942,7 @@ features: possible and call :func:`lstat` on the result. This does not apply to dangling symlinks or junction points, which will raise the usual exceptions. - .. index:: module: stat + .. index:: pair: module; stat Example:: @@ -2738,7 +2978,7 @@ features: .. class:: stat_result Object whose attributes correspond roughly to the members of the - :c:type:`stat` structure. It is used for the result of :func:`os.stat`, + :c:struct:`stat` structure. It is used for the result of :func:`os.stat`, :func:`os.fstat` and :func:`os.lstat`. Attributes: @@ -2791,10 +3031,12 @@ features: .. attribute:: st_ctime - Platform dependent: + Time of most recent metadata change expressed in seconds. - * the time of most recent metadata change on Unix, - * the time of creation on Windows, expressed in seconds. + .. versionchanged:: 3.12 + ``st_ctime`` is deprecated on Windows. Use ``st_birthtime`` for + the file creation time. In the future, ``st_ctime`` will contain + the time of the most recent metadata change, as for other platforms. .. attribute:: st_atime_ns @@ -2807,29 +3049,48 @@ features: .. attribute:: st_ctime_ns - Platform dependent: + Time of most recent metadata change expressed in nanoseconds as an + integer. - * the time of most recent metadata change on Unix, - * the time of creation on Windows, expressed in nanoseconds as an - integer. + .. versionchanged:: 3.12 + ``st_ctime_ns`` is deprecated on Windows. Use ``st_birthtime_ns`` + for the file creation time. In the future, ``st_ctime`` will contain + the time of the most recent metadata change, as for other platforms. + + .. attribute:: st_birthtime + + Time of file creation expressed in seconds. This attribute is not + always available, and may raise :exc:`AttributeError`. + + .. versionchanged:: 3.12 + ``st_birthtime`` is now available on Windows. + + .. attribute:: st_birthtime_ns + + Time of file creation expressed in nanoseconds as an integer. + This attribute is not always available, and may raise + :exc:`AttributeError`. + + .. versionadded:: 3.12 .. note:: The exact meaning and resolution of the :attr:`st_atime`, - :attr:`st_mtime`, and :attr:`st_ctime` attributes depend on the operating - system and the file system. For example, on Windows systems using the FAT - or FAT32 file systems, :attr:`st_mtime` has 2-second resolution, and - :attr:`st_atime` has only 1-day resolution. See your operating system - documentation for details. + :attr:`st_mtime`, :attr:`st_ctime` and :attr:`st_birthtime` attributes + depend on the operating system and the file system. For example, on + Windows systems using the FAT32 file systems, :attr:`st_mtime` has + 2-second resolution, and :attr:`st_atime` has only 1-day resolution. + See your operating system documentation for details. Similarly, although :attr:`st_atime_ns`, :attr:`st_mtime_ns`, - and :attr:`st_ctime_ns` are always expressed in nanoseconds, many - systems do not provide nanosecond precision. On systems that do - provide nanosecond precision, the floating-point object used to - store :attr:`st_atime`, :attr:`st_mtime`, and :attr:`st_ctime` - cannot preserve all of it, and as such will be slightly inexact. - If you need the exact timestamps you should always use - :attr:`st_atime_ns`, :attr:`st_mtime_ns`, and :attr:`st_ctime_ns`. + :attr:`st_ctime_ns` and :attr:`st_birthtime_ns` are always expressed in + nanoseconds, many systems do not provide nanosecond precision. On + systems that do provide nanosecond precision, the floating-point object + used to store :attr:`st_atime`, :attr:`st_mtime`, :attr:`st_ctime` and + :attr:`st_birthtime` cannot preserve all of it, and as such will be + slightly inexact. If you need the exact timestamps you should always use + :attr:`st_atime_ns`, :attr:`st_mtime_ns`, :attr:`st_ctime_ns` and + :attr:`st_birthtime_ns`. On some Unix systems (such as Linux), the following attributes may also be available: @@ -2859,10 +3120,6 @@ features: File generation number. - .. attribute:: st_birthtime - - Time of file creation. - On Solaris and derivatives, the following attributes may also be available: @@ -2891,22 +3148,24 @@ features: Windows file attributes: ``dwFileAttributes`` member of the ``BY_HANDLE_FILE_INFORMATION`` structure returned by - :c:func:`GetFileInformationByHandle`. See the ``FILE_ATTRIBUTE_*`` + :c:func:`!GetFileInformationByHandle`. + See the :const:`!FILE_ATTRIBUTE_* <stat.FILE_ATTRIBUTE_ARCHIVE>` constants in the :mod:`stat` module. .. attribute:: st_reparse_tag - When :attr:`st_file_attributes` has the ``FILE_ATTRIBUTE_REPARSE_POINT`` + When :attr:`st_file_attributes` has the :const:`~stat.FILE_ATTRIBUTE_REPARSE_POINT` set, this field contains the tag identifying the type of reparse point. - See the ``IO_REPARSE_TAG_*`` constants in the :mod:`stat` module. + See the :const:`IO_REPARSE_TAG_* <stat.IO_REPARSE_TAG_SYMLINK>` + constants in the :mod:`stat` module. The standard module :mod:`stat` defines functions and constants that are - useful for extracting information from a :c:type:`stat` structure. (On + useful for extracting information from a :c:struct:`stat` structure. (On Windows, some items are filled with dummy values.) For backward compatibility, a :class:`stat_result` instance is also accessible as a tuple of at least 10 integers giving the most important (and - portable) members of the :c:type:`stat` structure, in the order + portable) members of the :c:struct:`stat` structure, in the order :attr:`st_mode`, :attr:`st_ino`, :attr:`st_dev`, :attr:`st_nlink`, :attr:`st_uid`, :attr:`st_gid`, :attr:`st_size`, :attr:`st_atime`, :attr:`st_mtime`, :attr:`st_ctime`. More items may be added at the end by @@ -2935,11 +3194,30 @@ features: files as :const:`S_IFCHR`, :const:`S_IFIFO` or :const:`S_IFBLK` as appropriate. + .. versionchanged:: 3.12 + On Windows, :attr:`st_ctime` is deprecated. Eventually, it will + contain the last metadata change time, for consistency with other + platforms, but for now still contains creation time. + Use :attr:`st_birthtime` for the creation time. + + .. versionchanged:: 3.12 + On Windows, :attr:`st_ino` may now be up to 128 bits, depending + on the file system. Previously it would not be above 64 bits, and + larger file identifiers would be arbitrarily packed. + + .. versionchanged:: 3.12 + On Windows, :attr:`st_rdev` no longer returns a value. Previously + it would contain the same as :attr:`st_dev`, which was incorrect. + + .. versionadded:: 3.12 + Added the :attr:`st_birthtime` member on Windows. + + .. function:: statvfs(path) - Perform a :c:func:`statvfs` system call on the given path. The return value is + Perform a :c:func:`!statvfs` system call on the given path. The return value is an object whose attributes describe the filesystem on the given path, and - correspond to the members of the :c:type:`statvfs` structure, namely: + correspond to the members of the :c:struct:`statvfs` structure, namely: :attr:`f_bsize`, :attr:`f_frsize`, :attr:`f_blocks`, :attr:`f_bfree`, :attr:`f_bavail`, :attr:`f_files`, :attr:`f_ffree`, :attr:`f_favail`, :attr:`f_flag`, :attr:`f_namemax`, :attr:`f_fsid`. @@ -3695,7 +3973,8 @@ to be ignored. the :envvar:`PATH` variable. The other variants, :func:`execl`, :func:`execle`, :func:`execv`, and :func:`execve`, will not use the :envvar:`PATH` variable to locate the executable; *path* must contain an appropriate absolute or relative - path. + path. Relative paths must include at least one slash, even on Windows, as + plain names will not be resolved. For :func:`execle`, :func:`execlpe`, :func:`execve`, and :func:`execvpe` (note that these all end in "e"), the *env* parameter must be a mapping which is @@ -3727,7 +4006,7 @@ to be ignored. .. note:: - The standard way to exit is ``sys.exit(n)``. :func:`_exit` should + The standard way to exit is :func:`sys.exit(n) <sys.exit>`. :func:`!_exit` should normally only be used in the child process after a :func:`fork`. The following exit codes are defined and can be used with :func:`_exit`, @@ -3878,15 +4157,38 @@ written in Python, such as a mail server's external command delivery program. .. audit-event:: os.fork "" os.fork + .. warning:: + + If you use TLS sockets in an application calling ``fork()``, see + the warning in the :mod:`ssl` documentation. + .. versionchanged:: 3.8 Calling ``fork()`` in a subinterpreter is no longer supported (:exc:`RuntimeError` is raised). - .. warning:: + .. versionchanged:: 3.12 + If Python is able to detect that your process has multiple + threads, :func:`os.fork` now raises a :exc:`DeprecationWarning`. - See :mod:`ssl` for applications that use the SSL module with fork(). + We chose to surface this as a warning, when detectable, to better + inform developers of a design problem that the POSIX platform + specifically notes as not supported. Even in code that + *appears* to work, it has never been safe to mix threading with + :func:`os.fork` on POSIX platforms. The CPython runtime itself has + always made API calls that are not safe for use in the child + process when threads existed in the parent (such as ``malloc`` and + ``free``). - .. availability:: Unix, not Emscripten, not WASI. + Users of macOS or users of libc or malloc implementations other + than those typically found in glibc to date are among those + already more likely to experience deadlocks running such code. + + See `this discussion on fork being incompatible with threads + <https://discuss.python.org/t/33555>`_ + for technical details of why we're surfacing this longstanding + platform compatibility problem to developers. + + .. availability:: POSIX, not Emscripten, not WASI. .. function:: forkpty() @@ -3899,6 +4201,11 @@ written in Python, such as a mail server's external command delivery program. .. audit-event:: os.forkpty "" os.forkpty + .. versionchanged:: 3.12 + If Python is able to detect that your process has multiple + threads, this now raises a :exc:`DeprecationWarning`. See the + longer explanation on :func:`os.fork`. + .. versionchanged:: 3.8 Calling ``forkpty()`` in a subinterpreter is no longer supported (:exc:`RuntimeError` is raised). @@ -3915,8 +4222,8 @@ written in Python, such as a mail server's external command delivery program. Send signal *sig* to the process *pid*. Constants for the specific signals available on the host platform are defined in the :mod:`signal` module. - Windows: The :data:`signal.CTRL_C_EVENT` and - :data:`signal.CTRL_BREAK_EVENT` signals are special signals which can + Windows: The :const:`signal.CTRL_C_EVENT` and + :const:`signal.CTRL_BREAK_EVENT` signals are special signals which can only be sent to console processes which share a common console window, e.g., some subprocesses. Any other value for *sig* will cause the process to be unconditionally killed by the TerminateProcess API, and the exit code @@ -3955,16 +4262,25 @@ written in Python, such as a mail server's external command delivery program. .. function:: pidfd_open(pid, flags=0) - Return a file descriptor referring to the process *pid*. This descriptor can - be used to perform process management without races and signals. The *flags* - argument is provided for future extensions; no flag values are currently - defined. + Return a file descriptor referring to the process *pid* with *flags* set. + This descriptor can be used to perform process management without races + and signals. See the :manpage:`pidfd_open(2)` man page for more details. .. availability:: Linux >= 5.3 .. versionadded:: 3.9 + .. data:: PIDFD_NONBLOCK + + This flag indicates that the file descriptor will be non-blocking. + If the process referred to by the file descriptor has not yet terminated, + then an attempt to wait on the file descriptor using :manpage:`waitid(2)` + will immediately return the error :const:`~errno.EAGAIN` rather than blocking. + + .. availability:: Linux >= 5.10 + .. versionadded:: 3.12 + .. function:: plock(op, /) @@ -4018,7 +4334,7 @@ written in Python, such as a mail server's external command delivery program. setpgroup=None, resetids=False, setsid=False, setsigmask=(), \ setsigdef=(), scheduler=None) - Wraps the :c:func:`posix_spawn` C library API for use from Python. + Wraps the :c:func:`!posix_spawn` C library API for use from Python. Most users should use :func:`subprocess.run` instead of :func:`posix_spawn`. @@ -4054,16 +4370,16 @@ written in Python, such as a mail server's external command delivery program. Performs ``os.dup2(fd, new_fd)``. These tuples correspond to the C library - :c:func:`posix_spawn_file_actions_addopen`, - :c:func:`posix_spawn_file_actions_addclose`, and - :c:func:`posix_spawn_file_actions_adddup2` API calls used to prepare - for the :c:func:`posix_spawn` call itself. + :c:func:`!posix_spawn_file_actions_addopen`, + :c:func:`!posix_spawn_file_actions_addclose`, and + :c:func:`!posix_spawn_file_actions_adddup2` API calls used to prepare + for the :c:func:`!posix_spawn` call itself. The *setpgroup* argument will set the process group of the child to the value specified. If the value specified is 0, the child's process group ID will be made the same as its process ID. If the value of *setpgroup* is not set, the child will inherit the parent's process group ID. This argument corresponds - to the C library :c:data:`POSIX_SPAWN_SETPGROUP` flag. + to the C library :c:macro:`!POSIX_SPAWN_SETPGROUP` flag. If the *resetids* argument is ``True`` it will reset the effective UID and GID of the child to the real UID and GID of the parent process. If the @@ -4071,27 +4387,27 @@ written in Python, such as a mail server's external command delivery program. the parent. In either case, if the set-user-ID and set-group-ID permission bits are enabled on the executable file, their effect will override the setting of the effective UID and GID. This argument corresponds to the C - library :c:data:`POSIX_SPAWN_RESETIDS` flag. + library :c:macro:`!POSIX_SPAWN_RESETIDS` flag. If the *setsid* argument is ``True``, it will create a new session ID - for ``posix_spawn``. *setsid* requires :c:data:`POSIX_SPAWN_SETSID` - or :c:data:`POSIX_SPAWN_SETSID_NP` flag. Otherwise, :exc:`NotImplementedError` + for ``posix_spawn``. *setsid* requires :c:macro:`!POSIX_SPAWN_SETSID` + or :c:macro:`!POSIX_SPAWN_SETSID_NP` flag. Otherwise, :exc:`NotImplementedError` is raised. The *setsigmask* argument will set the signal mask to the signal set specified. If the parameter is not used, then the child inherits the parent's signal mask. This argument corresponds to the C library - :c:data:`POSIX_SPAWN_SETSIGMASK` flag. + :c:macro:`!POSIX_SPAWN_SETSIGMASK` flag. The *sigdef* argument will reset the disposition of all signals in the set specified. This argument corresponds to the C library - :c:data:`POSIX_SPAWN_SETSIGDEF` flag. + :c:macro:`!POSIX_SPAWN_SETSIGDEF` flag. The *scheduler* argument must be a tuple containing the (optional) scheduler policy and an instance of :class:`sched_param` with the scheduler parameters. A value of ``None`` in the place of the scheduler policy indicates that is not being provided. This argument is a combination of the C library - :c:data:`POSIX_SPAWN_SETSCHEDPARAM` and :c:data:`POSIX_SPAWN_SETSCHEDULER` + :c:macro:`!POSIX_SPAWN_SETSCHEDPARAM` and :c:macro:`!POSIX_SPAWN_SETSCHEDULER` flags. .. audit-event:: os.posix_spawn path,argv,env os.posix_spawn @@ -4104,7 +4420,7 @@ written in Python, such as a mail server's external command delivery program. setpgroup=None, resetids=False, setsid=False, setsigmask=(), \ setsigdef=(), scheduler=None) - Wraps the :c:func:`posix_spawnp` C library API for use from Python. + Wraps the :c:func:`!posix_spawnp` C library API for use from Python. Similar to :func:`posix_spawn` except that the system searches for the *executable* file in the list of directories specified by the @@ -4265,13 +4581,13 @@ written in Python, such as a mail server's external command delivery program. Start a file with its associated application. - When *operation* is not specified or ``'open'``, this acts like double-clicking + When *operation* is not specified, this acts like double-clicking the file in Windows Explorer, or giving the file name as an argument to the :program:`start` command from the interactive command shell: the file is opened with whatever application (if any) its extension is associated. When another *operation* is given, it must be a "command verb" that specifies - what should be done with the file. Common verbs documented by Microsoft are + what should be done with the file. Common verbs documented by Microsoft are ``'open'``, ``'print'`` and ``'edit'`` (to be used on files) as well as ``'explore'`` and ``'find'`` (to be used on directories). @@ -4285,7 +4601,7 @@ written in Python, such as a mail server's external command delivery program. Use *show_cmd* to override the default window style. Whether this has any effect will depend on the application being launched. Values are integers as - supported by the Win32 :c:func:`ShellExecute` function. + supported by the Win32 :c:func:`!ShellExecute` function. :func:`startfile` returns as soon as the associated application is launched. There is no option to wait for the application to close, and no way to retrieve @@ -4295,7 +4611,7 @@ written in Python, such as a mail server's external command delivery program. :func:`os.path.normpath` function to ensure that paths are properly encoded for Win32. - To reduce interpreter startup overhead, the Win32 :c:func:`ShellExecute` + To reduce interpreter startup overhead, the Win32 :c:func:`!ShellExecute` function is not resolved until this function is first called. If the function cannot be resolved, :exc:`NotImplementedError` will be raised. @@ -4359,7 +4675,7 @@ written in Python, such as a mail server's external command delivery program. :attr:`!children_system`, and :attr:`!elapsed` in that order. See the Unix manual page - :manpage:`times(2)` and `times(3) <https://www.freebsd.org/cgi/man.cgi?time(3)>`_ manual page on Unix or `the GetProcessTimes MSDN + :manpage:`times(2)` and `times(3) <https://man.freebsd.org/cgi/man.cgi?time(3)>`_ manual page on Unix or `the GetProcessTimes MSDN <https://docs.microsoft.com/windows/win32/api/processthreadsapi/nf-processthreadsapi-getprocesstimes>`_ on Windows. On Windows, only :attr:`!user` and :attr:`!system` are known; the other attributes are zero. @@ -4405,11 +4721,11 @@ written in Python, such as a mail server's external command delivery program. :data:`WNOHANG` and :data:`WNOWAIT` are additional optional flags. The return value is an object representing the data contained in the - :c:type:`!siginfo_t` structure with the following attributes: + :c:type:`siginfo_t` structure with the following attributes: * :attr:`!si_pid` (process ID) * :attr:`!si_uid` (real user ID of the child) - * :attr:`!si_signo` (always :data:`~signal.SIGCHLD`) + * :attr:`!si_signo` (always :const:`~signal.SIGCHLD`) * :attr:`!si_status` (the exit status or signal number, depending on :attr:`!si_code`) * :attr:`!si_code` (see :data:`CLD_EXITED` for possible values) @@ -4647,7 +4963,7 @@ used to determine the disposition of a process. .. function:: WIFCONTINUED(status) Return ``True`` if a stopped child has been resumed by delivery of - :data:`~signal.SIGCONT` (if the process has been continued from a job + :const:`~signal.SIGCONT` (if the process has been continued from a job control stop), otherwise return ``False``. See :data:`WCONTINUED` option. @@ -5019,7 +5335,7 @@ Random numbers ``/dev/urandom`` devices. The flags argument is a bit mask that can contain zero or more of the - following values ORed together: :py:data:`os.GRND_RANDOM` and + following values ORed together: :py:const:`os.GRND_RANDOM` and :py:data:`GRND_NONBLOCK`. See also the `Linux getrandom() manual page diff --git a/Doc/library/pathlib.rst b/Doc/library/pathlib.rst index e8bb00fc..2fb4dc42 100644 --- a/Doc/library/pathlib.rst +++ b/Doc/library/pathlib.rst @@ -21,6 +21,7 @@ inherit from pure paths but also provide I/O operations. .. image:: pathlib-inheritance.png :align: center + :class: invert-in-dark-mode If you've never used this module before or just aren't sure which class is right for your task, :class:`Path` is most likely what you need. It instantiates @@ -105,8 +106,9 @@ we also call *flavours*: PurePosixPath('setup.py') Each element of *pathsegments* can be either a string representing a - path segment, an object implementing the :class:`os.PathLike` interface - which returns a string, or another path object:: + path segment, or an object implementing the :class:`os.PathLike` interface + where the :meth:`~os.PathLike.__fspath__` method returns a string, + such as another path object:: >>> PurePath('foo', 'some/path', 'bar') PurePosixPath('foo/some/path/bar') @@ -186,7 +188,7 @@ these classes, since they don't provide any operation that does system calls. General properties ^^^^^^^^^^^^^^^^^^ -Paths are immutable and hashable. Paths of a same flavour are comparable +Paths are immutable and :term:`hashable`. Paths of a same flavour are comparable and orderable. These properties respect the flavour's case-folding semantics:: @@ -497,7 +499,7 @@ Pure paths provide the following methods and properties: True -.. method:: PurePath.is_relative_to(*other) +.. method:: PurePath.is_relative_to(other) Return whether or not this path is relative to the *other* path. @@ -509,6 +511,10 @@ Pure paths provide the following methods and properties: .. versionadded:: 3.9 + .. deprecated-removed:: 3.12 3.14 + + Passing additional arguments is deprecated; if supplied, they are joined + with *other*. .. method:: PurePath.is_reserved() @@ -525,10 +531,10 @@ Pure paths provide the following methods and properties: unintended effects. -.. method:: PurePath.joinpath(*other) +.. method:: PurePath.joinpath(*pathsegments) Calling this method is equivalent to combining the path with each of - the *other* arguments in turn:: + the given *pathsegments* in turn:: >>> PurePosixPath('/etc').joinpath('passwd') PurePosixPath('/etc/passwd') @@ -540,7 +546,7 @@ Pure paths provide the following methods and properties: PureWindowsPath('c:/Program Files') -.. method:: PurePath.match(pattern) +.. method:: PurePath.match(pattern, *, case_sensitive=None) Match this path against the provided glob-style pattern. Return ``True`` if matching is successful, ``False`` otherwise. @@ -563,6 +569,13 @@ Pure paths provide the following methods and properties: >>> PurePath('a/b.py').match('/*.py') False + The *pattern* may be another path object; this speeds up matching the same + pattern against multiple files:: + + >>> pattern = PurePath('*.py') + >>> PurePath('a/b.py').match(pattern) + True + As with other methods, case-sensitivity follows platform defaults:: >>> PurePosixPath('b.py').match('*.PY') @@ -570,11 +583,16 @@ Pure paths provide the following methods and properties: >>> PureWindowsPath('b.py').match('*.PY') True + Set *case_sensitive* to ``True`` or ``False`` to override this behaviour. -.. method:: PurePath.relative_to(*other) + .. versionchanged:: 3.12 + The *case_sensitive* parameter was added. + + +.. method:: PurePath.relative_to(other, walk_up=False) Compute a version of this path relative to the path represented by - *other*. If it's impossible, ValueError is raised:: + *other*. If it's impossible, :exc:`ValueError` is raised:: >>> p = PurePosixPath('/etc/passwd') >>> p.relative_to('/') @@ -584,12 +602,38 @@ Pure paths provide the following methods and properties: >>> p.relative_to('/usr') Traceback (most recent call last): File "<stdin>", line 1, in <module> - File "pathlib.py", line 694, in relative_to - .format(str(self), str(formatted))) - ValueError: '/etc/passwd' is not in the subpath of '/usr' OR one path is relative and the other absolute. + File "pathlib.py", line 941, in relative_to + raise ValueError(error_message.format(str(self), str(formatted))) + ValueError: '/etc/passwd' is not in the subpath of '/usr' OR one path is relative and the other is absolute. + + When *walk_up* is False (the default), the path must start with *other*. + When the argument is True, ``..`` entries may be added to form the + relative path. In all other cases, such as the paths referencing + different drives, :exc:`ValueError` is raised.:: + + >>> p.relative_to('/usr', walk_up=True) + PurePosixPath('../etc/passwd') + >>> p.relative_to('foo', walk_up=True) + Traceback (most recent call last): + File "<stdin>", line 1, in <module> + File "pathlib.py", line 941, in relative_to + raise ValueError(error_message.format(str(self), str(formatted))) + ValueError: '/etc/passwd' is not on the same drive as 'foo' OR one path is relative and the other is absolute. + + .. warning:: + This function is part of :class:`PurePath` and works with strings. + It does not check or access the underlying file structure. + This can impact the *walk_up* option as it assumes that no symlinks + are present in the path; call :meth:`~Path.resolve` first if + necessary to resolve symlinks. + + .. versionchanged:: 3.12 + The *walk_up* parameter was added (old behavior is the same as ``walk_up=False``). - NOTE: This function is part of :class:`PurePath` and works with strings. It does not check or access the underlying file structure. + .. deprecated-removed:: 3.12 3.14 + Passing additional positional arguments is deprecated; if supplied, + they are joined with *other*. .. method:: PurePath.with_name(name) @@ -649,6 +693,30 @@ Pure paths provide the following methods and properties: PureWindowsPath('README') +.. method:: PurePath.with_segments(*pathsegments) + + Create a new path object of the same type by combining the given + *pathsegments*. This method is called whenever a derivative path is created, + such as from :attr:`parent` and :meth:`relative_to`. Subclasses may + override this method to pass information to derivative paths, for example:: + + from pathlib import PurePosixPath + + class MyPath(PurePosixPath): + def __init__(self, *pathsegments, session_id): + super().__init__(*pathsegments) + self.session_id = session_id + + def with_segments(self, *pathsegments): + return type(self)(*pathsegments, session_id=self.session_id) + + etc = MyPath('/etc', session_id=42) + hosts = etc / 'hosts' + print(hosts.session_id) # 42 + + .. versionadded:: 3.12 + + .. _concrete-paths: @@ -788,9 +856,14 @@ call fails (for example because the path doesn't exist). .. versionchanged:: 3.10 The *follow_symlinks* parameter was added. -.. method:: Path.exists() +.. method:: Path.exists(*, follow_symlinks=True) + + Return ``True`` if the path points to an existing file or directory. - Whether the path points to an existing file or directory:: + This method normally follows symlinks; to check if a symlink exists, add + the argument ``follow_symlinks=False``. + + :: >>> Path('.').exists() True @@ -801,10 +874,8 @@ call fails (for example because the path doesn't exist). >>> Path('nonexistentfile').exists() False - .. note:: - If the path points to a symlink, :meth:`exists` returns whether the - symlink *points to* an existing file or directory. - + .. versionchanged:: 3.12 + The *follow_symlinks* parameter was added. .. method:: Path.expanduser() @@ -821,7 +892,7 @@ call fails (for example because the path doesn't exist). .. versionadded:: 3.5 -.. method:: Path.glob(pattern) +.. method:: Path.glob(pattern, *, case_sensitive=None) Glob the given relative *pattern* in the directory represented by this path, yielding all matching files (of any kind):: @@ -842,6 +913,11 @@ call fails (for example because the path doesn't exist). PosixPath('setup.py'), PosixPath('test_pathlib.py')] + By default, or when the *case_sensitive* keyword-only argument is set to + ``None``, this method matches paths using platform-specific casing rules: + typically, case-sensitive on POSIX, and case-insensitive on Windows. + Set *case_sensitive* to ``True`` or ``False`` to override this behaviour. + .. note:: Using the "``**``" pattern in large directory trees may consume an inordinate amount of time. @@ -852,6 +928,10 @@ call fails (for example because the path doesn't exist). Return only directories if *pattern* ends with a pathname components separator (:data:`~os.sep` or :data:`~os.altsep`). + .. versionchanged:: 3.12 + The *case_sensitive* parameter was added. + + .. method:: Path.group() Return the name of the group owning the file. :exc:`KeyError` is raised @@ -876,6 +956,14 @@ call fails (for example because the path doesn't exist). other errors (such as permission errors) are propagated. +.. method:: Path.is_junction() + + Return ``True`` if the path points to a junction, and ``False`` for any other + type of file. Currently only Windows supports junctions. + + .. versionadded:: 3.12 + + .. method:: Path.is_mount() Return ``True`` if the path is a :dfn:`mount point`: a point in a @@ -883,10 +971,15 @@ call fails (for example because the path doesn't exist). function checks whether *path*'s parent, :file:`path/..`, is on a different device than *path*, or whether :file:`path/..` and *path* point to the same i-node on the same device --- this should detect mount points for all Unix - and POSIX variants. Not implemented on Windows. + and POSIX variants. On Windows, a mount point is considered to be a drive + letter root (e.g. ``c:\``), a UNC share (e.g. ``\\server\share``), or a + mounted filesystem directory. .. versionadded:: 3.7 + .. versionchanged:: 3.12 + Windows support was added. + .. method:: Path.is_symlink() @@ -953,6 +1046,101 @@ call fails (for example because the path doesn't exist). to the directory after creating the iterator, whether a path object for that file be included is unspecified. +.. method:: Path.walk(top_down=True, on_error=None, follow_symlinks=False) + + Generate the file names in a directory tree by walking the tree + either top-down or bottom-up. + + For each directory in the directory tree rooted at *self* (including + *self* but excluding '.' and '..'), the method yields a 3-tuple of + ``(dirpath, dirnames, filenames)``. + + *dirpath* is a :class:`Path` to the directory currently being walked, + *dirnames* is a list of strings for the names of subdirectories in *dirpath* + (excluding ``'.'`` and ``'..'``), and *filenames* is a list of strings for + the names of the non-directory files in *dirpath*. To get a full path + (which begins with *self*) to a file or directory in *dirpath*, do + ``dirpath / name``. Whether or not the lists are sorted is file + system-dependent. + + If the optional argument *top_down* is true (which is the default), the triple for a + directory is generated before the triples for any of its subdirectories + (directories are walked top-down). If *top_down* is false, the triple + for a directory is generated after the triples for all of its subdirectories + (directories are walked bottom-up). No matter the value of *top_down*, the + list of subdirectories is retrieved before the triples for the directory and + its subdirectories are walked. + + When *top_down* is true, the caller can modify the *dirnames* list in-place + (for example, using :keyword:`del` or slice assignment), and :meth:`Path.walk` + will only recurse into the subdirectories whose names remain in *dirnames*. + This can be used to prune the search, or to impose a specific order of visiting, + or even to inform :meth:`Path.walk` about directories the caller creates or + renames before it resumes :meth:`Path.walk` again. Modifying *dirnames* when + *top_down* is false has no effect on the behavior of :meth:`Path.walk()` since the + directories in *dirnames* have already been generated by the time *dirnames* + is yielded to the caller. + + By default, errors from :func:`os.scandir` are ignored. If the optional + argument *on_error* is specified, it should be a callable; it will be + called with one argument, an :exc:`OSError` instance. The callable can handle the + error to continue the walk or re-raise it to stop the walk. Note that the + filename is available as the ``filename`` attribute of the exception object. + + By default, :meth:`Path.walk` does not follow symbolic links, and instead adds them + to the *filenames* list. Set *follow_symlinks* to true to resolve symlinks + and place them in *dirnames* and *filenames* as appropriate for their targets, and + consequently visit directories pointed to by symlinks (where supported). + + .. note:: + + Be aware that setting *follow_symlinks* to true can lead to infinite + recursion if a link points to a parent directory of itself. :meth:`Path.walk` + does not keep track of the directories it has already visited. + + .. note:: + :meth:`Path.walk` assumes the directories it walks are not modified during + execution. For example, if a directory from *dirnames* has been replaced + with a symlink and *follow_symlinks* is false, :meth:`Path.walk` will + still try to descend into it. To prevent such behavior, remove directories + from *dirnames* as appropriate. + + .. note:: + + Unlike :func:`os.walk`, :meth:`Path.walk` lists symlinks to directories in + *filenames* if *follow_symlinks* is false. + + This example displays the number of bytes used by all files in each directory, + while ignoring ``__pycache__`` directories:: + + from pathlib import Path + for root, dirs, files in Path("cpython/Lib/concurrent").walk(on_error=print): + print( + root, + "consumes", + sum((root / file).stat().st_size for file in files), + "bytes in", + len(files), + "non-directory files" + ) + if '__pycache__' in dirs: + dirs.remove('__pycache__') + + This next example is a simple implementation of :func:`shutil.rmtree`. + Walking the tree bottom-up is essential as :func:`rmdir` doesn't allow + deleting a directory before it is empty:: + + # Delete everything reachable from the directory "top". + # CAUTION: This is dangerous! For example, if top == Path('/'), + # it could delete all of your files. + for root, dirs, files in top.walk(top_down=False): + for name in files: + (root / name).unlink() + for name in dirs: + (root / name).rmdir() + + .. versionadded:: 3.12 + .. method:: Path.lchmod(mode) Like :meth:`Path.chmod` but, if the path points to a symbolic link, the @@ -1126,13 +1314,14 @@ call fails (for example because the path doesn't exist). infinite loop is encountered along the resolution path, :exc:`RuntimeError` is raised. - .. versionadded:: 3.6 - The *strict* argument (pre-3.6 behavior is strict). + .. versionchanged:: 3.6 + The *strict* parameter was added (pre-3.6 behavior is strict). -.. method:: Path.rglob(pattern) +.. method:: Path.rglob(pattern, *, case_sensitive=None) - This is like calling :func:`Path.glob` with "``**/``" added in front of the - given relative *pattern*:: + Glob the given relative *pattern* recursively. This is like calling + :func:`Path.glob` with "``**/``" added in front of the *pattern*, where + *patterns* are the same as for :mod:`fnmatch`:: >>> sorted(Path().rglob("*.py")) [PosixPath('build/lib/pathlib.py'), @@ -1141,12 +1330,21 @@ call fails (for example because the path doesn't exist). PosixPath('setup.py'), PosixPath('test_pathlib.py')] + By default, or when the *case_sensitive* keyword-only argument is set to + ``None``, this method matches paths using platform-specific casing rules: + typically, case-sensitive on POSIX, and case-insensitive on Windows. + Set *case_sensitive* to ``True`` or ``False`` to override this behaviour. + .. audit-event:: pathlib.Path.rglob self,pattern pathlib.Path.rglob .. versionchanged:: 3.11 Return only directories if *pattern* ends with a pathname components separator (:data:`~os.sep` or :data:`~os.altsep`). + .. versionchanged:: 3.12 + The *case_sensitive* parameter was added. + + .. method:: Path.rmdir() Remove this directory. The directory must be empty. @@ -1204,25 +1402,6 @@ call fails (for example because the path doesn't exist). .. versionadded:: 3.10 -.. method:: Path.link_to(target) - - Make *target* a hard link to this path. - - .. warning:: - - This function does not make this path a hard link to *target*, despite - the implication of the function and argument names. The argument order - (target, link) is the reverse of :func:`Path.symlink_to` and - :func:`Path.hardlink_to`, but matches that of :func:`os.link`. - - .. versionadded:: 3.8 - - .. deprecated:: 3.10 - - This method is deprecated in favor of :meth:`Path.hardlink_to`, as the - argument order of :meth:`Path.link_to` does not match that of - :meth:`Path.symlink_to`. - .. method:: Path.touch(mode=0o666, exist_ok=True) @@ -1313,6 +1492,7 @@ Below is a table mapping various :mod:`os` functions to their corresponding :func:`os.path.expanduser` :meth:`Path.expanduser` and :meth:`Path.home` :func:`os.listdir` :meth:`Path.iterdir` +:func:`os.walk` :meth:`Path.walk` :func:`os.path.isdir` :meth:`Path.is_dir` :func:`os.path.isfile` :meth:`Path.is_file` :func:`os.path.islink` :meth:`Path.is_symlink` diff --git a/Doc/library/pdb.rst b/Doc/library/pdb.rst index 4ae12a5d..ef52370b 100644 --- a/Doc/library/pdb.rst +++ b/Doc/library/pdb.rst @@ -20,8 +20,8 @@ supports post-mortem debugging and can be called under program control. .. index:: single: Pdb (class in pdb) - module: bdb - module: cmd + pair: module; bdb + pair: module; cmd The debugger is extensible -- it is actually defined as the class :class:`Pdb`. This is currently undocumented but easily understood by reading the source. The @@ -36,73 +36,91 @@ extension interface uses the modules :mod:`bdb` and :mod:`cmd`. Module :mod:`traceback` Standard interface to extract, format and print stack traces of Python programs. -The debugger's prompt is ``(Pdb)``. Typical usage to run a program under control -of the debugger is:: +The typical usage to break into the debugger is to insert:: - >>> import pdb - >>> import mymodule - >>> pdb.run('mymodule.test()') - > <string>(0)?() - (Pdb) continue - > <string>(1)?() + import pdb; pdb.set_trace() + +Or:: + + breakpoint() + +at the location you want to break into the debugger, and then run the program. +You can then step through the code following this statement, and continue +running without the debugger using the :pdbcmd:`continue` command. + +.. versionadded:: 3.7 + The built-in :func:`breakpoint()`, when called with defaults, can be used + instead of ``import pdb; pdb.set_trace()``. + +:: + + def double(x): + breakpoint() + return x * 2 + val = 3 + print(f"{val} * 2 is {double(val)}") + +The debugger's prompt is ``(Pdb)``, which is the indicator that you are in debug mode:: + + > ...(3)double() + -> return x * 2 + (Pdb) p x + 3 (Pdb) continue - NameError: 'spam' - > <string>(1)?() - (Pdb) + 3 * 2 is 6 .. versionchanged:: 3.3 Tab-completion via the :mod:`readline` module is available for commands and command arguments, e.g. the current global and local names are offered as arguments of the ``p`` command. -:file:`pdb.py` can also be invoked as a script to debug other scripts. For + +You can also invoke :mod:`pdb` from the command line to debug other scripts. For example:: - python3 -m pdb myscript.py + python -m pdb myscript.py -When invoked as a script, pdb will automatically enter post-mortem debugging if +When invoked as a module, pdb will automatically enter post-mortem debugging if the program being debugged exits abnormally. After post-mortem debugging (or after normal exit of the program), pdb will restart the program. Automatic restarting preserves pdb's state (such as breakpoints) and in most cases is more useful than quitting the debugger upon program's exit. .. versionadded:: 3.2 - :file:`pdb.py` now accepts a ``-c`` option that executes commands as if given + ``-c`` option is introduced to execute commands as if given in a :file:`.pdbrc` file, see :ref:`debugger-commands`. .. versionadded:: 3.7 - :file:`pdb.py` now accepts a ``-m`` option that execute modules similar to the way - ``python3 -m`` does. As with a script, the debugger will pause execution just + ``-m`` option is introduced to execute modules similar to the way + ``python -m`` does. As with a script, the debugger will pause execution just before the first line of the module. +Typical usage to execute a statement under control of the debugger is:: -The typical usage to break into the debugger is to insert:: - - import pdb; pdb.set_trace() - -at the location you want to break into the debugger, and then run the program. -You can then step through the code following this statement, and continue -running without the debugger using the :pdbcmd:`continue` command. - -.. versionadded:: 3.7 - The built-in :func:`breakpoint()`, when called with defaults, can be used - instead of ``import pdb; pdb.set_trace()``. + >>> import pdb + >>> def f(x): + ... print(1 / x) + >>> pdb.run("f(2)") + > <string>(1)<module>() + (Pdb) continue + 0.5 + >>> The typical usage to inspect a crashed program is:: >>> import pdb - >>> import mymodule - >>> mymodule.test() + >>> def f(x): + ... print(1 / x) + ... + >>> f(0) Traceback (most recent call last): File "<stdin>", line 1, in <module> - File "./mymodule.py", line 4, in test - test2() - File "./mymodule.py", line 3, in test2 - print(spam) - NameError: spam + File "<stdin>", line 2, in f + ZeroDivisionError: division by zero >>> pdb.pm() - > ./mymodule.py(3)test2() - -> print(spam) + > <stdin>(2)f() + (Pdb) p x + 0 (Pdb) @@ -125,7 +143,7 @@ slightly different way: Evaluate the *expression* (given as a string or a code object) under debugger control. When :func:`runeval` returns, it returns the value of the - expression. Otherwise this function is similar to :func:`run`. + *expression*. Otherwise this function is similar to :func:`run`. .. function:: runcall(function, *args, **kwds) @@ -178,7 +196,7 @@ access further features, you have to do this yourself: that matches one of these patterns. [1]_ By default, Pdb sets a handler for the SIGINT signal (which is sent when the - user presses :kbd:`Ctrl-C` on the console) when you give a ``continue`` command. + user presses :kbd:`Ctrl-C` on the console) when you give a :pdbcmd:`continue` command. This allows you to break into the debugger again by pressing :kbd:`Ctrl-C`. If you want Pdb not to touch the SIGINT handler, set *nosigint* to true. @@ -245,6 +263,21 @@ the commands; the input is split at the first ``;;`` pair, even if it is in the middle of a quoted string. A workaround for strings with double semicolons is to use implicit string concatenation ``';'';'`` or ``";"";"``. +To set a temporary global variable, use a *convenience variable*. A *convenience +variable* is a variable whose name starts with ``$``. For example, ``$foo = 1`` +sets a global variable ``$foo`` which you can use in the debugger session. The +*convenience variables* are cleared when the program resumes execution so it's +less likely to interfere with your program compared to using normal variables +like ``foo = 1``. + +There are three preset *convenience variables*: + +* ``$_frame``: the current frame you are debugging +* ``$_retval``: the return value if the frame is returning +* ``$_exception``: the exception if the frame is raising an exception + +.. versionadded:: 3.12 + .. index:: pair: .pdbrc; file triple: debugger; configuration; file @@ -275,7 +308,7 @@ can be overridden by the local file. .. pdbcommand:: w(here) - Print a stack trace, with the most recent frame at the bottom. An arrow + Print a stack trace, with the most recent frame at the bottom. An arrow (``>``) indicates the current frame, which determines the context of most commands. .. pdbcommand:: d(own) [count] @@ -315,22 +348,22 @@ can be overridden by the local file. With a space separated list of breakpoint numbers, clear those breakpoints. Without argument, clear all breaks (but first ask confirmation). -.. pdbcommand:: disable [bpnumber ...] +.. pdbcommand:: disable bpnumber [bpnumber ...] Disable the breakpoints given as a space separated list of breakpoint numbers. Disabling a breakpoint means it cannot cause the program to stop execution, but unlike clearing a breakpoint, it remains in the list of breakpoints and can be (re-)enabled. -.. pdbcommand:: enable [bpnumber ...] +.. pdbcommand:: enable bpnumber [bpnumber ...] Enable the breakpoints specified. .. pdbcommand:: ignore bpnumber [count] - Set the ignore count for the given breakpoint number. If count is omitted, + Set the ignore count for the given breakpoint number. If *count* is omitted, the ignore count is set to 0. A breakpoint becomes active when the ignore - count is zero. When non-zero, the count is decremented each time the + count is zero. When non-zero, the *count* is decremented each time the breakpoint is reached and the breakpoint is not disabled and any associated condition evaluates to true. @@ -369,7 +402,7 @@ can be overridden by the local file. breakpoint—which could have its own command list, leading to ambiguities about which list to execute. - If you use the 'silent' command in the command list, the usual message about + If you use the ``silent`` command in the command list, the usual message about stopping at a breakpoint is not printed. This may be desirable for breakpoints that are to print a specific message and then continue. If none of the other commands print anything, you see no sign that the breakpoint was reached. @@ -392,8 +425,8 @@ can be overridden by the local file. Without argument, continue execution until the line with a number greater than the current one is reached. - With a line number, continue execution until a line with a number greater or - equal to that is reached. In both cases, also stop when the current frame + With *lineno*, continue execution until a line with a number greater or + equal to *lineno* is reached. In both cases, also stop when the current frame returns. .. versionchanged:: 3.2 @@ -442,11 +475,11 @@ can be overridden by the local file. .. pdbcommand:: a(rgs) - Print the argument list of the current function. + Print the arguments of the current function and their current values. .. pdbcommand:: p expression - Evaluate the *expression* in the current context and print its value. + Evaluate *expression* in the current context and print its value. .. note:: @@ -456,32 +489,76 @@ can be overridden by the local file. .. pdbcommand:: pp expression - Like the :pdbcmd:`p` command, except the value of the expression is + Like the :pdbcmd:`p` command, except the value of *expression* is pretty-printed using the :mod:`pprint` module. .. pdbcommand:: whatis expression - Print the type of the *expression*. + Print the type of *expression*. .. pdbcommand:: source expression - Try to get source code for the given object and display it. + Try to get source code of *expression* and display it. .. versionadded:: 3.2 .. pdbcommand:: display [expression] - Display the value of the expression if it changed, each time execution stops + Display the value of *expression* if it changed, each time execution stops in the current frame. - Without expression, list all display expressions for the current frame. + Without *expression*, list all display expressions for the current frame. + + .. note:: + + Display evaluates *expression* and compares to the result of the previous + evaluation of *expression*, so when the result is mutable, display may not + be able to pick up the changes. + + Example:: + + lst = [] + breakpoint() + pass + lst.append(1) + print(lst) + + Display won't realize ``lst`` has been changed because the result of evaluation + is modified in place by ``lst.append(1)`` before being compared:: + + > example.py(3)<module>() + -> pass + (Pdb) display lst + display lst: [] + (Pdb) n + > example.py(4)<module>() + -> lst.append(1) + (Pdb) n + > example.py(5)<module>() + -> print(lst) + (Pdb) + + You can do some tricks with copy mechanism to make it work:: + + > example.py(3)<module>() + -> pass + (Pdb) display lst[:] + display lst[:]: [] + (Pdb) n + > example.py(4)<module>() + -> lst.append(1) + (Pdb) n + > example.py(5)<module>() + -> print(lst) + display lst[:]: [1] [old: []] + (Pdb) .. versionadded:: 3.2 .. pdbcommand:: undisplay [expression] - Do not display the expression any more in the current frame. Without - expression, clear all display expressions for the current frame. + Do not display *expression* anymore in the current frame. Without + *expression*, clear all display expressions for the current frame. .. versionadded:: 3.2 @@ -497,10 +574,10 @@ can be overridden by the local file. .. pdbcommand:: alias [name [command]] - Create an alias called *name* that executes *command*. The command must + Create an alias called *name* that executes *command*. The *command* must *not* be enclosed in quotes. Replaceable parameters can be indicated by ``%1``, ``%2``, and so on, while ``%*`` is replaced by all the parameters. - If no command is given, the current alias for *name* is shown. If no + If *command* is omitted, the current alias for *name* is shown. If no arguments are given, all aliases are listed. Aliases may be nested and can contain anything that can be legally typed at @@ -513,21 +590,29 @@ can be overridden by the local file. :file:`.pdbrc` file):: # Print instance variables (usage "pi classInst") - alias pi for k in %1.__dict__.keys(): print("%1.",k,"=",%1.__dict__[k]) + alias pi for k in %1.__dict__.keys(): print(f"%1.{k} = {%1.__dict__[k]}") # Print instance variables in self alias ps pi self .. pdbcommand:: unalias name - Delete the specified alias. + Delete the specified alias *name*. .. pdbcommand:: ! statement Execute the (one-line) *statement* in the context of the current stack frame. The exclamation point can be omitted unless the first word of the statement - resembles a debugger command. To set a global variable, you can prefix the - assignment command with a :keyword:`global` statement on the same line, - e.g.:: + resembles a debugger command, e.g.: + + .. code-block:: none + + (Pdb) ! n=42 + (Pdb) + + To set a global variable, you can prefix the assignment command with a + :keyword:`global` statement on the same line, e.g.: + + .. code-block:: none (Pdb) global list_options; list_options = ['-l'] (Pdb) @@ -535,7 +620,7 @@ can be overridden by the local file. .. pdbcommand:: run [args ...] restart [args ...] - Restart the debugged Python program. If an argument is supplied, it is split + Restart the debugged Python program. If *args* is supplied, it is split with :mod:`shlex` and the result is used as the new :data:`sys.argv`. History, breakpoints, actions and debugger options are preserved. :pdbcmd:`restart` is an alias for :pdbcmd:`run`. @@ -546,13 +631,13 @@ can be overridden by the local file. .. pdbcommand:: debug code - Enter a recursive debugger that steps through the code - argument (which is an arbitrary expression or statement to be + Enter a recursive debugger that steps through *code* + (which is an arbitrary expression or statement to be executed in the current environment). .. pdbcommand:: retval - Print the return value for the last return of a function. + Print the return value for the last return of the current function. .. rubric:: Footnotes diff --git a/Doc/library/pickle.rst b/Doc/library/pickle.rst index 79476b04..d6be4ba3 100644 --- a/Doc/library/pickle.rst +++ b/Doc/library/pickle.rst @@ -494,7 +494,8 @@ What can be pickled and unpickled? The following types can be pickled: -* ``None``, ``True``, and ``False``; +* built-in constants (``None``, ``True``, ``False``, ``Ellipsis``, and + ``NotImplemented``); * integers, floating-point numbers, complex numbers; diff --git a/Doc/library/pkgutil.rst b/Doc/library/pkgutil.rst index 788a02dc..891a867d 100644 --- a/Doc/library/pkgutil.rst +++ b/Doc/library/pkgutil.rst @@ -25,9 +25,9 @@ support. from pkgutil import extend_path __path__ = extend_path(__path__, __name__) - This will add to the package's ``__path__`` all subdirectories of directories - on :data:`sys.path` named after the package. This is useful if one wants to - distribute different parts of a single logical package as multiple + For each directory on :data:`sys.path` that has a subdirectory that matches the + package name, add the subdirectory to the package's :attr:`__path__`. This is useful + if one wants to distribute different parts of a single logical package as multiple directories. It also looks for :file:`\*.pkg` files beginning where ``*`` matches the @@ -48,33 +48,6 @@ support. this function to raise an exception (in line with :func:`os.path.isdir` behavior). - -.. class:: ImpImporter(dirname=None) - - :pep:`302` Finder that wraps Python's "classic" import algorithm. - - If *dirname* is a string, a :pep:`302` finder is created that searches that - directory. If *dirname* is ``None``, a :pep:`302` finder is created that - searches the current :data:`sys.path`, plus any modules that are frozen or - built-in. - - Note that :class:`ImpImporter` does not currently support being used by - placement on :data:`sys.meta_path`. - - .. deprecated:: 3.3 - This emulation is no longer needed, as the standard import mechanism - is now fully :pep:`302` compliant and available in :mod:`importlib`. - - -.. class:: ImpLoader(fullname, file, filename, etc) - - :term:`Loader <loader>` that wraps Python's "classic" import algorithm. - - .. deprecated:: 3.3 - This emulation is no longer needed, as the standard import mechanism - is now fully :pep:`302` compliant and available in :mod:`importlib`. - - .. function:: find_loader(fullname) Retrieve a module :term:`loader` for the given *fullname*. @@ -82,7 +55,7 @@ support. This is a backwards compatibility wrapper around :func:`importlib.util.find_spec` that converts most failures to :exc:`ImportError` and only returns the loader rather than the full - :class:`ModuleSpec`. + :class:`importlib.machinery.ModuleSpec`. .. versionchanged:: 3.3 Updated to be based directly on :mod:`importlib` rather than relying @@ -91,6 +64,10 @@ support. .. versionchanged:: 3.4 Updated to be based on :pep:`451` + .. deprecated-removed:: 3.12 3.14 + Use :func:`importlib.util.find_spec` instead. + + .. function:: get_importer(path_item) Retrieve a :term:`finder` for the given *path_item*. @@ -123,6 +100,9 @@ support. .. versionchanged:: 3.4 Updated to be based on :pep:`451` + .. deprecated-removed:: 3.12 3.14 + Use :func:`importlib.util.find_spec` instead. + .. function:: iter_importers(fullname='') diff --git a/Doc/library/platform.rst b/Doc/library/platform.rst index dc2d871b..ec2a7ebd 100644 --- a/Doc/library/platform.rst +++ b/Doc/library/platform.rst @@ -46,7 +46,7 @@ Cross Platform universal files containing multiple architectures. To get at the "64-bitness" of the current interpreter, it is more - reliable to query the :attr:`sys.maxsize` attribute:: + reliable to query the :data:`sys.maxsize` attribute:: is_64bits = sys.maxsize > 2**32 @@ -63,7 +63,7 @@ Cross Platform string is returned if the value cannot be determined. -.. function:: platform(aliased=0, terse=0) +.. function:: platform(aliased=False, terse=False) Returns a single string identifying the underlying platform with as much useful information as possible. @@ -168,16 +168,20 @@ Cross Platform containing six attributes: :attr:`system`, :attr:`node`, :attr:`release`, :attr:`version`, :attr:`machine`, and :attr:`processor`. - Note that this adds a sixth attribute (:attr:`processor`) not present - in the :func:`os.uname` result. Also, the attribute names are different - for the first two attributes; :func:`os.uname` names them - :attr:`sysname` and :attr:`nodename`. + :attr:`processor` is resolved late, on demand. + + Note: the first two attribute names differ from the names presented by + :func:`os.uname`, where they are named :attr:`sysname` and + :attr:`nodename`. Entries which cannot be determined are set to ``''``. .. versionchanged:: 3.3 Result changed from a tuple to a :func:`~collections.namedtuple`. + .. versionchanged:: 3.9 + :attr:`processor` is resolved late instead of immediately. + Java Platform ------------- diff --git a/Doc/library/plistlib.rst b/Doc/library/plistlib.rst index 5ded9661..732ef353 100644 --- a/Doc/library/plistlib.rst +++ b/Doc/library/plistlib.rst @@ -46,7 +46,7 @@ or :class:`datetime.datetime` objects. .. seealso:: - `PList manual page <https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/PropertyLists/>`_ + `PList manual page <https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/PropertyLists/>`_ Apple's documentation of the file format. @@ -159,6 +159,9 @@ Examples Generating a plist:: + import datetime + import plistlib + pl = dict( aString = "Doodah", aList = ["A", "B", 12, 32.1, [1, 2, 3]], @@ -172,13 +175,19 @@ Generating a plist:: ), someData = b"<binary gunk>", someMoreData = b"<lots of binary gunk>" * 10, - aDate = datetime.datetime.fromtimestamp(time.mktime(time.gmtime())), + aDate = datetime.datetime.now() ) - with open(fileName, 'wb') as fp: - dump(pl, fp) + print(plistlib.dumps(pl).decode()) Parsing a plist:: - with open(fileName, 'rb') as fp: - pl = load(fp) - print(pl["aKey"]) + import plistlib + + plist = b"""<plist version="1.0"> + <dict> + <key>foo</key> + <string>bar</string> + </dict> + </plist>""" + pl = plistlib.loads(plist) + print(pl["foo"]) diff --git a/Doc/library/poplib.rst b/Doc/library/poplib.rst index e22a2e14..943eb21f 100644 --- a/Doc/library/poplib.rst +++ b/Doc/library/poplib.rst @@ -53,7 +53,7 @@ The :mod:`poplib` module provides two classes: If the *timeout* parameter is set to be zero, it will raise a :class:`ValueError` to prevent the creation of a non-blocking socket. -.. class:: POP3_SSL(host, port=POP3_SSL_PORT, keyfile=None, certfile=None, timeout=None, context=None) +.. class:: POP3_SSL(host, port=POP3_SSL_PORT, *, timeout=None, context=None) This is a subclass of :class:`POP3` that connects to the server over an SSL encrypted socket. If *port* is not specified, 995, the standard POP3-over-SSL @@ -63,10 +63,6 @@ The :mod:`poplib` module provides two classes: single (potentially long-lived) structure. Please read :ref:`ssl-security` for best practices. - *keyfile* and *certfile* are a legacy alternative to *context* - they can - point to PEM-formatted private key and certificate chain files, - respectively, for the SSL connection. - .. audit-event:: poplib.connect self,host,port poplib.POP3_SSL .. audit-event:: poplib.putline self,line poplib.POP3_SSL @@ -81,19 +77,15 @@ The :mod:`poplib` module provides two classes: .. versionchanged:: 3.4 The class now supports hostname check with :attr:`ssl.SSLContext.check_hostname` and *Server Name Indication* (see - :data:`ssl.HAS_SNI`). - - .. deprecated:: 3.6 - - *keyfile* and *certfile* are deprecated in favor of *context*. - Please use :meth:`ssl.SSLContext.load_cert_chain` instead, or let - :func:`ssl.create_default_context` select the system's trusted CA - certificates for you. + :const:`ssl.HAS_SNI`). .. versionchanged:: 3.9 If the *timeout* parameter is set to be zero, it will raise a :class:`ValueError` to prevent the creation of a non-blocking socket. + .. versionchanged:: 3.12 + The deprecated *keyfile* and *certfile* parameters have been removed. + One exception is defined as an attribute of the :mod:`poplib` module: @@ -156,7 +148,7 @@ A :class:`POP3` instance has the following methods: .. method:: POP3.pass_(password) Send password, response includes message count and mailbox size. Note: the - mailbox on the server is locked until :meth:`~poplib.quit` is called. + mailbox on the server is locked until :meth:`~POP3.quit` is called. .. method:: POP3.apop(user, secret) @@ -248,7 +240,7 @@ A :class:`POP3` instance has the following methods: This method supports hostname checking via :attr:`ssl.SSLContext.check_hostname` and *Server Name Indication* (see - :data:`ssl.HAS_SNI`). + :const:`ssl.HAS_SNI`). .. versionadded:: 3.4 diff --git a/Doc/library/posix.rst b/Doc/library/posix.rst index ec04b0dc..0413f9d0 100644 --- a/Doc/library/posix.rst +++ b/Doc/library/posix.rst @@ -11,7 +11,7 @@ This module provides access to operating system functionality that is standardized by the C Standard and the POSIX standard (a thinly disguised Unix interface). -.. index:: module: os +.. index:: pair: module; os **Do not import this module directly.** Instead, import the module :mod:`os`, which provides a *portable* version of this interface. On Unix, the :mod:`os` diff --git a/Doc/library/pprint.rst b/Doc/library/pprint.rst index 3da5aa93..e883acd6 100644 --- a/Doc/library/pprint.rst +++ b/Doc/library/pprint.rst @@ -45,7 +45,7 @@ The :mod:`pprint` module defines one class: several keyword parameters. *stream* (default ``sys.stdout``) is a :term:`file-like object` to - which the output will be written by calling its :meth:`write` method. + which the output will be written by calling its :meth:`!write` method. If both *stream* and ``sys.stdout`` are ``None``, then :meth:`~PrettyPrinter.pprint` silently returns. @@ -159,7 +159,7 @@ The :mod:`pprint` module defines one class: .. function:: isreadable(object) - .. index:: builtin: eval + .. index:: pair: built-in function; eval Determine if the formatted representation of *object* is "readable", or can be used to reconstruct the value using :func:`eval`. This always returns ``False`` @@ -171,17 +171,21 @@ The :mod:`pprint` module defines one class: .. function:: isrecursive(object) - Determine if *object* requires a recursive representation. + Determine if *object* requires a recursive representation. This function is + subject to the same limitations as noted in :func:`saferepr` below and may raise an + :exc:`RecursionError` if it fails to detect a recursive object. One more support function is also defined: .. function:: saferepr(object) - Return a string representation of *object*, protected against recursive data - structures. If the representation of *object* exposes a recursive entry, the - recursive reference will be represented as ``<Recursion on typename with - id=number>``. The representation is not otherwise formatted. + Return a string representation of *object*, protected against recursion in + some common data structures, namely instances of :class:`dict`, :class:`list` + and :class:`tuple` or subclasses whose ``__repr__`` has not been overridden. If the + representation of object exposes a recursive entry, the recursive reference + will be represented as ``<Recursion on typename with id=number>``. The + representation is not otherwise formatted. >>> pprint.saferepr(stuff) "[<Recursion on list with id=...>, 'spam', 'eggs', 'lumberjack', 'knights', 'ni']" @@ -214,7 +218,7 @@ created. .. method:: PrettyPrinter.isreadable(object) - .. index:: builtin: eval + .. index:: pair: built-in function; eval Determine if the formatted representation of the object is "readable," or can be used to reconstruct the value using :func:`eval`. Note that this returns diff --git a/Doc/library/profile.rst b/Doc/library/profile.rst index c2189e02..723f9271 100644 --- a/Doc/library/profile.rst +++ b/Doc/library/profile.rst @@ -82,7 +82,7 @@ the following:: The first line indicates that 214 calls were monitored. Of those calls, 207 were :dfn:`primitive`, meaning that the call was not induced via recursion. The -next line: ``Ordered by: cumulative name``, indicates that the text string in the +next line: ``Ordered by: cumulative time``, indicates that the text string in the far right column was used to sort the output. The column headings include: ncalls diff --git a/Doc/library/pty.rst b/Doc/library/pty.rst index 7f4da41e..ad4981c9 100644 --- a/Doc/library/pty.rst +++ b/Doc/library/pty.rst @@ -71,7 +71,7 @@ The :mod:`pty` module defines the following functions: Return the exit status value from :func:`os.waitpid` on the child process. - :func:`waitstatus_to_exitcode` can be used to convert the exit status into + :func:`os.waitstatus_to_exitcode` can be used to convert the exit status into an exit code. .. audit-event:: pty.spawn argv pty.spawn diff --git a/Doc/library/pwd.rst b/Doc/library/pwd.rst index 98f3c45e..7cafc66f 100644 --- a/Doc/library/pwd.rst +++ b/Doc/library/pwd.rst @@ -39,7 +39,7 @@ raised if the entry asked for cannot be found. .. note:: - .. index:: module: crypt + .. index:: pair: module; crypt In traditional Unix the field ``pw_passwd`` usually contains a password encrypted with a DES derived algorithm (see module :mod:`crypt`). However most diff --git a/Doc/library/pyexpat.rst b/Doc/library/pyexpat.rst index d6581e21..935e8724 100644 --- a/Doc/library/pyexpat.rst +++ b/Doc/library/pyexpat.rst @@ -33,7 +33,7 @@ can be set to handler functions. When an XML document is then fed to the parser, the handler functions are called for the character data and markup in the XML document. -.. index:: module: pyexpat +.. index:: pair: module; pyexpat This module uses the :mod:`pyexpat` module to provide access to the Expat parser. Direct use of the :mod:`pyexpat` module is deprecated. diff --git a/Doc/library/python.rst b/Doc/library/python.rst index f39613f5..61043599 100644 --- a/Doc/library/python.rst +++ b/Doc/library/python.rst @@ -12,6 +12,7 @@ overview: .. toctree:: sys.rst + sys.monitoring.rst sysconfig.rst builtins.rst __main__.rst diff --git a/Doc/library/queue.rst b/Doc/library/queue.rst index c67f15e9..b2b787c5 100644 --- a/Doc/library/queue.rst +++ b/Doc/library/queue.rst @@ -15,7 +15,7 @@ module implements all the required locking semantics. The module implements three types of queue, which differ only in the order in which the entries are retrieved. In a :abbr:`FIFO (first-in, first-out)` -queue, the first tasks added are the first retrieved. In a +queue, the first tasks added are the first retrieved. In a :abbr:`LIFO (last-in, first-out)` queue, the most recently added entry is the first retrieved (operating like a stack). With a priority queue, the entries are kept sorted (using the :mod:`heapq` module) and the @@ -57,8 +57,8 @@ The :mod:`queue` module defines the following classes and exceptions: *maxsize* is less than or equal to zero, the queue size is infinite. The lowest valued entries are retrieved first (the lowest valued entry is the - one returned by ``sorted(list(entries))[0]``). A typical pattern for entries - is a tuple in the form: ``(priority_number, data)``. + one that would be returned by ``min(entries)``). A typical pattern for + entries is a tuple in the form: ``(priority_number, data)``. If the *data* elements are not comparable, the data can be wrapped in a class that ignores the data item and only compares the priority number:: @@ -127,8 +127,8 @@ provide the public methods described below. .. method:: Queue.put(item, block=True, timeout=None) - Put *item* into the queue. If optional args *block* is true and *timeout* is - ``None`` (the default), block if necessary until a free slot is available. If + Put *item* into the queue. If optional args *block* is true and *timeout* is + ``None`` (the default), block if necessary until a free slot is available. If *timeout* is a positive number, it blocks at most *timeout* seconds and raises the :exc:`Full` exception if no free slot was available within that time. Otherwise (*block* is false), put an item on the queue if a free slot is @@ -143,7 +143,7 @@ provide the public methods described below. .. method:: Queue.get(block=True, timeout=None) - Remove and return an item from the queue. If optional args *block* is true and + Remove and return an item from the queue. If optional args *block* is true and *timeout* is ``None`` (the default), block if necessary until an item is available. If *timeout* is a positive number, it blocks at most *timeout* seconds and raises the :exc:`Empty` exception if no item was available within that time. @@ -152,7 +152,7 @@ provide the public methods described below. Prior to 3.0 on POSIX systems, and for all versions on Windows, if *block* is true and *timeout* is ``None``, this operation goes into - an uninterruptible wait on an underlying lock. This means that no exceptions + an uninterruptible wait on an underlying lock. This means that no exceptions can occur, and in particular a SIGINT will not trigger a :exc:`KeyboardInterrupt`. @@ -184,7 +184,7 @@ fully processed by daemon consumer threads. The count of unfinished tasks goes up whenever an item is added to the queue. The count goes down whenever a consumer thread calls :meth:`task_done` to - indicate that the item was retrieved and all work on it is complete. When the + indicate that the item was retrieved and all work on it is complete. When the count of unfinished tasks drops to zero, :meth:`join` unblocks. @@ -227,7 +227,7 @@ SimpleQueue Objects .. method:: SimpleQueue.empty() - Return ``True`` if the queue is empty, ``False`` otherwise. If empty() + Return ``True`` if the queue is empty, ``False`` otherwise. If empty() returns ``False`` it doesn't guarantee that a subsequent call to get() will not block. diff --git a/Doc/library/random.rst b/Doc/library/random.rst index c7d94e06..76ae97a8 100644 --- a/Doc/library/random.rst +++ b/Doc/library/random.rst @@ -123,27 +123,26 @@ Functions for integers .. function:: randrange(stop) randrange(start, stop[, step]) - Return a randomly selected element from ``range(start, stop, step)``. This is - equivalent to ``choice(range(start, stop, step))``, but doesn't actually build a - range object. + Return a randomly selected element from ``range(start, stop, step)``. - The positional argument pattern matches that of :func:`range`. Keyword arguments - should not be used because the function may use them in unexpected ways. + This is roughly equivalent to ``choice(range(start, stop, step))`` but + supports arbitrarily large ranges and is optimized for common cases. + + The positional argument pattern matches the :func:`range` function. + + Keyword arguments should not be used because they can be interpreted + in unexpected ways. For example ``randrange(start=100)`` is interpreted + as ``randrange(0, 100, 1)``. .. versionchanged:: 3.2 :meth:`randrange` is more sophisticated about producing equally distributed values. Formerly it used a style like ``int(random()*n)`` which could produce slightly uneven distributions. - .. deprecated:: 3.10 - The automatic conversion of non-integer types to equivalent integers is - deprecated. Currently ``randrange(10.0)`` is losslessly converted to - ``randrange(10)``. In the future, this will raise a :exc:`TypeError`. - - .. deprecated:: 3.10 - The exception raised for non-integral values such as ``randrange(10.5)`` - or ``randrange('10')`` will be changed from :exc:`ValueError` to - :exc:`TypeError`. + .. versionchanged:: 3.12 + Automatic conversion of non-integer types is no longer supported. + Calls such as ``randrange(10.0)`` and ``randrange(Fraction(10, 1))`` + now raise a :exc:`TypeError`. .. function:: randint(a, b) @@ -153,7 +152,7 @@ Functions for integers .. function:: getrandbits(k) Returns a non-negative Python integer with *k* random bits. This method - is supplied with the MersenneTwister generator and some other generators + is supplied with the Mersenne Twister generator and some other generators may also provide it as an optional part of the API. When available, :meth:`getrandbits` enables :meth:`randrange` to handle arbitrarily large ranges. @@ -259,6 +258,28 @@ Functions for sequences The *population* must be a sequence. Automatic conversion of sets to lists is no longer supported. +Discrete distributions +---------------------- + +The following function generates a discrete distribution. + +.. function:: binomialvariate(n=1, p=0.5) + + `Binomial distribution + <https://mathworld.wolfram.com/BinomialDistribution.html>`_. + Return the number of successes for *n* independent trials with the + probability of success in each trial being *p*: + + Mathematically equivalent to:: + + sum(random() < p for i in range(n)) + + The number of trials *n* should be a non-negative integer. + The probability of success *p* should be between ``0.0 <= p <= 1.0``. + The result is an integer in the range ``0 <= X <= n``. + + .. versionadded:: 3.12 + .. _real-valued-distributions: @@ -299,7 +320,7 @@ be found in any statistics text. ``beta > 0``. Returned values range between 0 and 1. -.. function:: expovariate(lambd) +.. function:: expovariate(lambd = 1.0) Exponential distribution. *lambd* is 1.0 divided by the desired mean. It should be nonzero. (The parameter would be called @@ -307,11 +328,16 @@ be found in any statistics text. range from 0 to positive infinity if *lambd* is positive, and from negative infinity to 0 if *lambd* is negative. + .. versionchanged:: 3.12 + Added the default value for ``lambd``. + .. function:: gammavariate(alpha, beta) - Gamma distribution. (*Not* the gamma function!) Conditions on the - parameters are ``alpha > 0`` and ``beta > 0``. + Gamma distribution. (*Not* the gamma function!) The shape and + scale parameters, *alpha* and *beta*, must have positive values. + (Calling conventions vary and some sources define 'beta' + as the inverse of the scale). The probability distribution function is:: @@ -322,7 +348,8 @@ be found in any statistics text. .. function:: gauss(mu=0.0, sigma=1.0) - Normal distribution, also called the Gaussian distribution. *mu* is the mean, + Normal distribution, also called the Gaussian distribution. + *mu* is the mean, and *sigma* is the standard deviation. This is slightly faster than the :func:`normalvariate` function defined below. @@ -380,8 +407,8 @@ Alternative Generator Class that implements the default pseudo-random number generator used by the :mod:`random` module. - .. deprecated:: 3.9 - In the future, the *seed* must be one of the following types: + .. deprecated-removed:: 3.9 3.11 + Formerly the *seed* could be any hashable object. Now it is limited to: :class:`NoneType`, :class:`int`, :class:`float`, :class:`str`, :class:`bytes`, or :class:`bytearray`. @@ -399,7 +426,7 @@ Notes on Reproducibility ------------------------ Sometimes it is useful to be able to reproduce the sequences given by a -pseudo-random number generator. By re-using a seed value, the same sequence should be +pseudo-random number generator. By reusing a seed value, the same sequence should be reproducible from run to run as long as multiple threads are not running. Most of the random module's algorithms and seeding functions are subject to @@ -453,16 +480,13 @@ Simulations:: >>> # Deal 20 cards without replacement from a deck >>> # of 52 playing cards, and determine the proportion of cards >>> # with a ten-value: ten, jack, queen, or king. - >>> dealt = sample(['tens', 'low cards'], counts=[16, 36], k=20) - >>> dealt.count('tens') / 20 + >>> deal = sample(['tens', 'low cards'], counts=[16, 36], k=20) + >>> deal.count('tens') / 20 0.15 >>> # Estimate the probability of getting 5 or more heads from 7 spins >>> # of a biased coin that settles on heads 60% of the time. - >>> def trial(): - ... return choices('HT', cum_weights=(0.60, 1.00), k=7).count('H') >= 5 - ... - >>> sum(trial() for i in range(10_000)) / 10_000 + >>> sum(binomialvariate(n=7, p=0.6) >= 5 for i in range(10_000)) / 10_000 0.4169 >>> # Probability of the median of 5 samples being in middle two quartiles @@ -589,7 +613,8 @@ from the combinatoric iterators in the :mod:`itertools` module: return tuple(pool[i] for i in indices) def random_combination_with_replacement(iterable, r): - "Random selection from itertools.combinations_with_replacement(iterable, r)" + "Choose r elements with replacement. Order the result to match the iterable." + # Result will be in set(itertools.combinations_with_replacement(iterable, r)). pool = tuple(iterable) n = len(pool) indices = sorted(random.choices(range(n), k=r)) diff --git a/Doc/library/re.rst b/Doc/library/re.rst index 67056995..92aae100 100644 --- a/Doc/library/re.rst +++ b/Doc/library/re.rst @@ -29,7 +29,7 @@ a literal backslash, one might have to write ``'\\\\'`` as the pattern string, because the regular expression must be ``\\``, and each backslash must be expressed as ``\\`` inside a regular Python string literal. Also, please note that any invalid escape sequences in Python's -usage of the backslash in string literals now generate a :exc:`DeprecationWarning` +usage of the backslash in string literals now generate a :exc:`SyntaxWarning` and in the future this will become a :exc:`SyntaxError`. This behaviour will happen even if it is a valid escape sequence for a regular expression. @@ -271,7 +271,8 @@ The special characters are: * To match a literal ``']'`` inside a set, precede it with a backslash, or place it at the beginning of the set. For example, both ``[()[\]{}]`` and - ``[]()[{}]`` will both match a parenthesis. + ``[]()[{}]`` will match a right bracket, as well as left bracket, braces, + and parentheses. .. .. index:: single: --; in regular expressions .. .. index:: single: &&; in regular expressions @@ -395,8 +396,9 @@ The special characters are: ``(?P<name>...)`` Similar to regular parentheses, but the substring matched by the group is accessible via the symbolic group name *name*. Group names must be valid - Python identifiers, and each group name must be defined only once within a - regular expression. A symbolic group is also a numbered group, just as if + Python identifiers, and in :class:`bytes` patterns they can only contain + bytes in the ASCII range. Each group name must be defined only once within + a regular expression. A symbolic group is also a numbered group, just as if the group were not named. Named groups can be referenced in three contexts. If the pattern is @@ -417,8 +419,9 @@ The special characters are: | | * ``\1`` | +---------------------------------------+----------------------------------+ - .. deprecated:: 3.11 - Group names containing non-ASCII characters in bytes patterns. + .. versionchanged:: 3.12 + In :class:`bytes` patterns, group *name* can only contain bytes + in the ASCII range (``b'\x00'``-``b'\x7f'``). .. index:: single: (?P=; in regular expressions @@ -492,10 +495,14 @@ The special characters are: will match with ``'<user@host.com>'`` as well as ``'user@host.com'``, but not with ``'<user@host.com'`` nor ``'user@host.com>'``. - .. deprecated:: 3.11 - Group *id* containing anything except ASCII digits. + .. versionchanged:: 3.12 + Group *id* can only contain ASCII digits. + In :class:`bytes` patterns, group *name* can only contain bytes + in the ASCII range (``b'\x00'``-``b'\x7f'``). +.. _re-special-sequences: + The special sequences consist of ``'\'`` and a character from the list below. If the ordinary character is not an ASCII digit or an ASCII letter, then the resulting RE will match the second character. For example, ``\$`` matches the @@ -627,8 +634,8 @@ character ``'$'``. single: \x; in regular expressions single: \\; in regular expressions -Most of the standard escapes supported by Python string literals are also -accepted by the regular expression parser:: +Most of the :ref:`escape sequences <escape-sequences>` supported by Python +string literals are also accepted by the regular expression parser:: \a \b \f \n \N \r \t \u @@ -653,7 +660,7 @@ three digits in length. Unknown escapes consisting of ``'\'`` and an ASCII letter now are errors. .. versionchanged:: 3.8 - The ``'\N{name}'`` escape sequence has been added. As in string literals, + The :samp:`'\\N\\{{name}\\}'` escape sequence has been added. As in string literals, it expands to the named Unicode character (e.g. ``'\N{EM DASH}'``). @@ -774,6 +781,17 @@ Flags Corresponds to the inline flag ``(?s)``. +.. data:: U + UNICODE + + In Python 2, this flag made :ref:`special sequences <re-special-sequences>` + include Unicode characters in matches. Since Python 3, Unicode characters + are matched by default. + + See :const:`A` for restricting matching on ASCII characters instead. + + This flag is only kept for backward compatibility. + .. data:: X VERBOSE @@ -838,18 +856,17 @@ Functions .. function:: search(pattern, string, flags=0) Scan through *string* looking for the first location where the regular expression - *pattern* produces a match, and return a corresponding :ref:`match object - <match-objects>`. Return ``None`` if no position in the string matches the - pattern; note that this is different from finding a zero-length match at some - point in the string. + *pattern* produces a match, and return a corresponding :class:`~re.Match`. Return + ``None`` if no position in the string matches the pattern; note that this is + different from finding a zero-length match at some point in the string. .. function:: match(pattern, string, flags=0) If zero or more characters at the beginning of *string* match the regular - expression *pattern*, return a corresponding :ref:`match object - <match-objects>`. Return ``None`` if the string does not match the pattern; - note that this is different from a zero-length match. + expression *pattern*, return a corresponding :class:`~re.Match`. Return + ``None`` if the string does not match the pattern; note that this is + different from a zero-length match. Note that even in :const:`MULTILINE` mode, :func:`re.match` will only match at the beginning of the string and not at the beginning of each line. @@ -861,9 +878,8 @@ Functions .. function:: fullmatch(pattern, string, flags=0) If the whole *string* matches the regular expression *pattern*, return a - corresponding :ref:`match object <match-objects>`. Return ``None`` if the - string does not match the pattern; note that this is different from a - zero-length match. + corresponding :class:`~re.Match`. Return ``None`` if the string does not match + the pattern; note that this is different from a zero-length match. .. versionadded:: 3.4 @@ -936,7 +952,7 @@ Functions .. function:: finditer(pattern, string, flags=0) - Return an :term:`iterator` yielding :ref:`match objects <match-objects>` over + Return an :term:`iterator` yielding :class:`~re.Match` objects over all non-overlapping matches for the RE *pattern* in *string*. The *string* is scanned left-to-right, and matches are returned in the order found. Empty matches are included in the result. @@ -964,18 +980,19 @@ Functions '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 :ref:`match object <match-objects>` - argument, and returns the replacement string. For example:: + *pattern*. The function takes a single :class:`~re.Match` argument, and returns + the replacement string. For example:: >>> def dashrepl(matchobj): ... if matchobj.group(0) == '-': return ' ' ... else: return '-' + ... >>> re.sub('-{1,2}', dashrepl, 'pro----gram-files') 'pro--gram files' >>> re.sub(r'\sAND\s', ' & ', 'Baked Beans And Spam', flags=re.IGNORECASE) 'Baked Beans & Spam' - The pattern may be a string or a :ref:`pattern object <re-objects>`. + The pattern may be a string or a :class:`~re.Pattern`. 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 @@ -1013,9 +1030,10 @@ Functions Empty matches for the pattern are replaced when adjacent to a previous non-empty match. - .. deprecated:: 3.11 - Group *id* containing anything except ASCII digits. - Group names containing non-ASCII characters in bytes replacement strings. + .. versionchanged:: 3.12 + Group *id* can only contain ASCII digits. + In :class:`bytes` replacement strings, group *name* can only contain bytes + in the ASCII range (``b'\x00'``-``b'\x7f'``). .. function:: subn(pattern, repl, string, count=0, flags=0) @@ -1109,16 +1127,20 @@ Exceptions Regular Expression Objects -------------------------- -Compiled regular expression objects support the following methods and -attributes: +.. class:: Pattern + + Compiled regular expression object returned by :func:`re.compile`. + + .. versionchanged:: 3.9 + :py:class:`re.Pattern` supports ``[]`` to indicate a Unicode (str) or bytes pattern. + See :ref:`types-genericalias`. .. method:: Pattern.search(string[, pos[, endpos]]) Scan through *string* looking for the first location where this regular - expression produces a match, and return a corresponding :ref:`match object - <match-objects>`. Return ``None`` if no position in the string matches the - pattern; note that this is different from finding a zero-length match at some - point in the string. + expression produces a match, and return a corresponding :class:`~re.Match`. + Return ``None`` if no position in the string matches the pattern; note that + this is different from finding a zero-length match at some point in the string. The optional second parameter *pos* gives an index in the string where the search is to start; it defaults to ``0``. This is not completely equivalent to @@ -1142,9 +1164,9 @@ attributes: .. method:: Pattern.match(string[, pos[, endpos]]) If zero or more characters at the *beginning* of *string* match this regular - expression, return a corresponding :ref:`match object <match-objects>`. - Return ``None`` if the string does not match the pattern; note that this is - different from a zero-length match. + expression, return a corresponding :class:`~re.Match`. Return ``None`` if the + string does not 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:`~Pattern.search` method. :: @@ -1161,8 +1183,8 @@ attributes: .. method:: Pattern.fullmatch(string[, pos[, endpos]]) If the whole *string* matches this regular expression, return a corresponding - :ref:`match object <match-objects>`. Return ``None`` if the string does not - match the pattern; note that this is different from a zero-length match. + :class:`~re.Match`. Return ``None`` if the string does not 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:`~Pattern.search` method. :: @@ -1248,8 +1270,13 @@ when there is no match, you can test whether there was a match with a simple if match: process(match) -Match objects support the following methods and attributes: +.. class:: Match + Match object returned by successful ``match``\ es and ``search``\ es. + + .. versionchanged:: 3.9 + :py:class:`re.Match` supports ``[]`` to indicate a Unicode (str) or bytes match. + See :ref:`types-genericalias`. .. method:: Match.expand(template) @@ -1513,14 +1540,14 @@ Simulating scanf() .. index:: single: scanf() -Python does not currently have an equivalent to :c:func:`scanf`. Regular +Python does not currently have an equivalent to :c:func:`!scanf`. Regular expressions are generally more powerful, though also more verbose, than -:c:func:`scanf` format strings. The table below offers some more-or-less -equivalent mappings between :c:func:`scanf` format tokens and regular +:c:func:`!scanf` format strings. The table below offers some more-or-less +equivalent mappings between :c:func:`!scanf` format tokens and regular expressions. +--------------------------------+---------------------------------------------+ -| :c:func:`scanf` Token | Regular Expression | +| :c:func:`!scanf` Token | Regular Expression | +================================+=============================================+ | ``%c`` | ``.`` | +--------------------------------+---------------------------------------------+ @@ -1545,7 +1572,7 @@ To extract the filename and numbers from a string like :: /usr/sbin/sendmail - 0 errors, 4 warnings -you would use a :c:func:`scanf` format like :: +you would use a :c:func:`!scanf` format like :: %s - %d errors, %d warnings @@ -1668,6 +1695,7 @@ in each word of a sentence except for the first and last characters:: ... inner_word = list(m.group(2)) ... random.shuffle(inner_word) ... return m.group(1) + "".join(inner_word) + m.group(3) + ... >>> text = "Professor Abdolmalek, please report your absences promptly." >>> re.sub(r"(\w)(\w+)(\w)", repl, text) 'Poefsrosr Aealmlobdk, pslaee reorpt your abnseces plmrptoy.' @@ -1692,10 +1720,10 @@ Finding all Adverbs and their Positions ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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 -a writer wanted to find all of the adverbs *and their positions* in -some text, they would use :func:`finditer` in the following manner:: +text, :func:`finditer` is useful as it provides :class:`~re.Match` objects +instead of strings. Continuing with the previous example, if a writer wanted +to find all of the adverbs *and their positions* in some text, they 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\b", text): diff --git a/Doc/library/readline.rst b/Doc/library/readline.rst index 4d485d25..8fb0eca8 100644 --- a/Doc/library/readline.rst +++ b/Doc/library/readline.rst @@ -19,7 +19,7 @@ function. Readline keybindings may be configured via an initialization file, typically ``.inputrc`` in your home directory. See `Readline Init File -<https://tiswww.cwru.edu/php/chet/readline/rluserman.html#SEC9>`_ +<https://tiswww.cwru.edu/php/chet/readline/rluserman.html#Readline-Init-File>`_ in the GNU Readline manual for information about the format and allowable constructs of that file, and the capabilities of the Readline library in general. diff --git a/Doc/library/reprlib.rst b/Doc/library/reprlib.rst index 4b37c5ba..5ebb0a77 100644 --- a/Doc/library/reprlib.rst +++ b/Doc/library/reprlib.rst @@ -17,12 +17,31 @@ debugger and may be useful in other contexts as well. This module provides a class, an instance, and a function: -.. class:: Repr() +.. class:: Repr(*, maxlevel=6, maxtuple=6, maxlist=6, maxarray=5, maxdict=4, \ + maxset=6, maxfrozenset=6, maxdeque=6, maxstring=30, maxlong=40, \ + maxother=30, fillvalue="...", indent=None) Class which provides formatting services useful in implementing functions similar to the built-in :func:`repr`; size limits for different object types are added to avoid the generation of representations which are excessively long. + The keyword arguments of the constructor can be used as a shortcut to set the + attributes of the :class:`Repr` instance. Which means that the following + initialization:: + + aRepr = reprlib.Repr(maxlevel=3) + + Is equivalent to:: + + aRepr = reprlib.Repr() + aRepr.maxlevel = 3 + + See section `Repr Objects`_ for more information about :class:`Repr` + attributes. + + .. versionchanged:: 3.12 + Allow attributes to be set via keyword arguments. + .. data:: aRepr @@ -123,6 +142,66 @@ which format specific object types. similar manner as :attr:`maxstring`. The default is ``20``. +.. attribute:: Repr.indent + + If this attribute is set to ``None`` (the default), the output is formatted + with no line breaks or indentation, like the standard :func:`repr`. + For example: + + .. code-block:: pycon + + >>> example = [ + 1, 'spam', {'a': 2, 'b': 'spam eggs', 'c': {3: 4.5, 6: []}}, 'ham'] + >>> import reprlib + >>> aRepr = reprlib.Repr() + >>> print(aRepr.repr(example)) + [1, 'spam', {'a': 2, 'b': 'spam eggs', 'c': {3: 4.5, 6: []}}, 'ham'] + + If :attr:`~Repr.indent` is set to a string, each recursion level + is placed on its own line, indented by that string: + + .. code-block:: pycon + + >>> aRepr.indent = '-->' + >>> print(aRepr.repr(example)) + [ + -->1, + -->'spam', + -->{ + -->-->'a': 2, + -->-->'b': 'spam eggs', + -->-->'c': { + -->-->-->3: 4.5, + -->-->-->6: [], + -->-->}, + -->}, + -->'ham', + ] + + Setting :attr:`~Repr.indent` to a positive integer value behaves as if it + was set to a string with that number of spaces: + + .. code-block:: pycon + + >>> aRepr.indent = 4 + >>> print(aRepr.repr(example)) + [ + 1, + 'spam', + { + 'a': 2, + 'b': 'spam eggs', + 'c': { + 3: 4.5, + 6: [], + }, + }, + 'ham', + ] + + .. versionadded:: 3.12 + + .. method:: Repr.repr(obj) The equivalent to the built-in :func:`repr` that uses the formatting imposed by diff --git a/Doc/library/resource.rst b/Doc/library/resource.rst index e7bf45d7..a5324c82 100644 --- a/Doc/library/resource.rst +++ b/Doc/library/resource.rst @@ -244,7 +244,7 @@ platform. used by all of this user id's processes. This limit is enforced only if bit 1 of the vm.overcommit sysctl is set. Please see - `tuning(7) <https://www.freebsd.org/cgi/man.cgi?query=tuning&sektion=7>`__ + `tuning(7) <https://man.freebsd.org/cgi/man.cgi?query=tuning&sektion=7>`__ for a complete description of this sysctl. .. availability:: FreeBSD. diff --git a/Doc/library/runpy.rst b/Doc/library/runpy.rst index 26a4f143..406b080b 100644 --- a/Doc/library/runpy.rst +++ b/Doc/library/runpy.rst @@ -30,7 +30,7 @@ The :mod:`runpy` module provides two functions: .. function:: run_module(mod_name, init_globals=None, run_name=None, alter_sys=False) .. index:: - module: __main__ + pair: module; __main__ Execute the code of the specified module and return the resulting module globals dictionary. The module's code is first located using the standard @@ -39,7 +39,7 @@ The :mod:`runpy` module provides two functions: The *mod_name* argument should be an absolute module name. If the module name refers to a package rather than a normal - module, then that package is imported and the ``__main__`` submodule within + module, then that package is imported and the :mod:`__main__` submodule within that package is then executed and the resulting module globals dictionary returned. @@ -74,7 +74,7 @@ The :mod:`runpy` module provides two functions: Note that this manipulation of :mod:`sys` is not thread-safe. Other threads may see the partially initialised module, as well as the altered list of - arguments. It is recommended that the :mod:`sys` module be left alone when + arguments. It is recommended that the ``sys`` module be left alone when invoking this function from threaded code. .. seealso:: @@ -82,7 +82,7 @@ The :mod:`runpy` module provides two functions: command line. .. versionchanged:: 3.1 - Added ability to execute packages by looking for a ``__main__`` submodule. + Added ability to execute packages by looking for a :mod:`__main__` submodule. .. versionchanged:: 3.2 Added ``__cached__`` global variable (see :pep:`3147`). @@ -93,23 +93,29 @@ The :mod:`runpy` module provides two functions: run this way, as well as ensuring the real module name is always accessible as ``__spec__.name``. + .. versionchanged:: 3.12 + The setting of ``__cached__``, ``__loader__``, and + ``__package__`` are deprecated. See + :class:`~importlib.machinery.ModuleSpec` for alternatives. + .. function:: run_path(path_name, init_globals=None, run_name=None) .. index:: - module: __main__ + pair: module; __main__ Execute the code at the named filesystem location and return the resulting module globals dictionary. As with a script name supplied to the CPython command line, the supplied path may refer to a Python source file, a - compiled bytecode file or a valid sys.path entry containing a ``__main__`` - module (e.g. a zipfile containing a top-level ``__main__.py`` file). + compiled bytecode file or a valid :data:`sys.path` entry containing a + :mod:`__main__` module + (e.g. a zipfile containing a top-level ``__main__.py`` file). For a simple script, the specified code is simply executed in a fresh - module namespace. For a valid sys.path entry (typically a zipfile or + module namespace. For a valid :data:`sys.path` entry (typically a zipfile or directory), the entry is first added to the beginning of ``sys.path``. The function then looks for and executes a :mod:`__main__` module using the updated path. Note that there is no special protection against invoking - an existing :mod:`__main__` entry located elsewhere on ``sys.path`` if + an existing ``__main__`` entry located elsewhere on ``sys.path`` if there is no such module at the specified location. The optional dictionary argument *init_globals* may be used to pre-populate @@ -132,14 +138,14 @@ The :mod:`runpy` module provides two functions: supplied path, and ``__spec__``, ``__cached__``, ``__loader__`` and ``__package__`` will all be set to :const:`None`. - If the supplied path is a reference to a valid sys.path entry, then - ``__spec__`` will be set appropriately for the imported ``__main__`` + If the supplied path is a reference to a valid :data:`sys.path` entry, then + ``__spec__`` will be set appropriately for the imported :mod:`__main__` module (that is, ``__spec__.name`` will always be ``__main__``). ``__file__``, ``__cached__``, ``__loader__`` and ``__package__`` will be :ref:`set as normal <import-mod-attrs>` based on the module spec. A number of alterations are also made to the :mod:`sys` module. Firstly, - ``sys.path`` may be altered as described above. ``sys.argv[0]`` is updated + :data:`sys.path` may be altered as described above. ``sys.argv[0]`` is updated with the value of ``path_name`` and ``sys.modules[__name__]`` is updated with a temporary module object for the module being executed. All modifications to items in :mod:`sys` are reverted before the function @@ -147,7 +153,7 @@ The :mod:`runpy` module provides two functions: Note that, unlike :func:`run_module`, the alterations made to :mod:`sys` are not optional in this function as these adjustments are essential to - allowing the execution of sys.path entries. As the thread-safety + allowing the execution of :data:`sys.path` entries. As the thread-safety limitations still apply, use of this function in threaded code should be either serialised with the import lock or delegated to a separate process. @@ -160,9 +166,13 @@ The :mod:`runpy` module provides two functions: .. versionchanged:: 3.4 Updated to take advantage of the module spec feature added by :pep:`451`. This allows ``__cached__`` to be set correctly in the - case where ``__main__`` is imported from a valid sys.path entry rather + case where ``__main__`` is imported from a valid :data:`sys.path` entry rather than being executed directly. + .. versionchanged:: 3.12 + The setting of ``__cached__``, ``__loader__``, and + ``__package__`` are deprecated. + .. seealso:: :pep:`338` -- Executing modules as scripts diff --git a/Doc/library/sched.rst b/Doc/library/sched.rst index a051c65b..01bac5af 100644 --- a/Doc/library/sched.rst +++ b/Doc/library/sched.rst @@ -36,7 +36,7 @@ scheduler: Example:: >>> import sched, time - >>> s = sched.scheduler(time.time, time.sleep) + >>> s = sched.scheduler(time.monotonic, time.sleep) >>> def print_time(a='default'): ... print("From print_time", time.time(), a) ... @@ -115,7 +115,7 @@ Scheduler Objects .. method:: scheduler.run(blocking=True) - Run all scheduled events. This method will wait (using the :func:`delayfunc` + Run all scheduled events. This method will wait (using the *delayfunc* function passed to the constructor) for the next event, then execute it and so on until there are no more scheduled events. diff --git a/Doc/library/select.rst b/Doc/library/select.rst index 2890706b..c2941e62 100644 --- a/Doc/library/select.rst +++ b/Doc/library/select.rst @@ -6,10 +6,10 @@ -------------- -This module provides access to the :c:func:`select` and :c:func:`poll` functions -available in most operating systems, :c:func:`devpoll` available on -Solaris and derivatives, :c:func:`epoll` available on Linux 2.5+ and -:c:func:`kqueue` available on most BSD. +This module provides access to the :c:func:`!select` and :c:func:`!poll` functions +available in most operating systems, :c:func:`!devpoll` available on +Solaris and derivatives, :c:func:`!epoll` available on Linux 2.5+ and +:c:func:`!kqueue` available on most BSD. Note that on Windows, it only works for sockets; on other operating systems, it also works for other file types (in particular, on Unix, it works on pipes). It cannot be used on regular files to determine whether a file has grown since @@ -41,10 +41,10 @@ The module defines the following: polling object; see section :ref:`devpoll-objects` below for the methods supported by devpoll objects. - :c:func:`devpoll` objects are linked to the number of file + :c:func:`!devpoll` objects are linked to the number of file descriptors allowed at the time of instantiation. If your program - reduces this value, :c:func:`devpoll` will fail. If your program - increases this value, :c:func:`devpoll` may return an + reduces this value, :c:func:`!devpoll` will fail. If your program + increases this value, :c:func:`!devpoll` may return an incomplete list of active file descriptors. The new file descriptor is :ref:`non-inheritable <fd_inheritance>`. @@ -62,7 +62,7 @@ The module defines the following: *sizehint* informs epoll about the expected number of events to be registered. It must be positive, or ``-1`` to use the default. It is only - used on older systems where :c:func:`epoll_create1` is not available; + used on older systems where :c:func:`!epoll_create1` is not available; otherwise it has no effect (though its value is still checked). *flags* is deprecated and completely ignored. However, when supplied, its @@ -117,7 +117,7 @@ The module defines the following: .. function:: select(rlist, wlist, xlist[, timeout]) - This is a straightforward interface to the Unix :c:func:`select` system call. + This is a straightforward interface to the Unix :c:func:`!select` system call. The first three arguments are iterables of 'waitable objects': either integers representing file descriptors or objects with a parameterless method named :meth:`~io.IOBase.fileno` returning such an integer: @@ -154,7 +154,7 @@ The module defines the following: .. index:: single: WinSock File objects on Windows are not acceptable, but sockets are. On Windows, - the underlying :c:func:`select` function is provided by the WinSock + the underlying :c:func:`!select` function is provided by the WinSock library, and does not handle file descriptors that don't originate from WinSock. @@ -169,7 +169,7 @@ The module defines the following: The minimum number of bytes which can be written without blocking to a pipe when the pipe has been reported as ready for writing by :func:`~select.select`, - :func:`poll` or another interface in this module. This doesn't apply + :func:`!poll` or another interface in this module. This doesn't apply to other kind of file-like objects such as sockets. This value is guaranteed by POSIX to be at least 512. @@ -184,11 +184,11 @@ The module defines the following: ``/dev/poll`` Polling Objects ----------------------------- -Solaris and derivatives have ``/dev/poll``. While :c:func:`select` is -O(highest file descriptor) and :c:func:`poll` is O(number of file +Solaris and derivatives have ``/dev/poll``. While :c:func:`!select` is +O(highest file descriptor) and :c:func:`!poll` is O(number of file descriptors), ``/dev/poll`` is O(active file descriptors). -``/dev/poll`` behaviour is very close to the standard :c:func:`poll` +``/dev/poll`` behaviour is very close to the standard :c:func:`!poll` object. @@ -222,7 +222,7 @@ object. implement :meth:`!fileno`, so they can also be used as the argument. *eventmask* is an optional bitmask describing the type of events you want to - check for. The constants are the same that with :c:func:`poll` + check for. The constants are the same that with :c:func:`!poll` object. The default value is a combination of the constants :const:`POLLIN`, :const:`POLLPRI`, and :const:`POLLOUT`. @@ -231,7 +231,7 @@ object. Registering a file descriptor that's already registered is not an error, but the result is undefined. The appropriate action is to unregister or modify it first. This is an important difference - compared with :c:func:`poll`. + compared with :c:func:`!poll`. .. method:: devpoll.modify(fd[, eventmask]) @@ -376,13 +376,13 @@ Edge and Level Trigger Polling (epoll) Objects Polling Objects --------------- -The :c:func:`poll` system call, supported on most Unix systems, provides better +The :c:func:`!poll` system call, supported on most Unix systems, provides better scalability for network servers that service many, many clients at the same -time. :c:func:`poll` scales better because the system call only requires listing -the file descriptors of interest, while :c:func:`select` builds a bitmap, turns +time. :c:func:`!poll` scales better because the system call only requires listing +the file descriptors of interest, while :c:func:`!select` builds a bitmap, turns on bits for the fds of interest, and then afterward the whole bitmap has to be -linearly scanned again. :c:func:`select` is O(highest file descriptor), while -:c:func:`poll` is O(number of file descriptors). +linearly scanned again. :c:func:`!select` is O(highest file descriptor), while +:c:func:`!poll` is O(number of file descriptors). .. method:: poll.register(fd[, eventmask]) @@ -505,7 +505,7 @@ Kqueue Objects Kevent Objects -------------- -https://www.freebsd.org/cgi/man.cgi?query=kqueue&sektion=2 +https://man.freebsd.org/cgi/man.cgi?query=kqueue&sektion=2 .. attribute:: kevent.ident diff --git a/Doc/library/selectors.rst b/Doc/library/selectors.rst index 0deb15cf..dd50bac3 100644 --- a/Doc/library/selectors.rst +++ b/Doc/library/selectors.rst @@ -60,9 +60,9 @@ constants below: +-----------------------+-----------------------------------------------+ | Constant | Meaning | +=======================+===============================================+ - | :const:`EVENT_READ` | Available for read | + | .. data:: EVENT_READ | Available for read | +-----------------------+-----------------------------------------------+ - | :const:`EVENT_WRITE` | Available for write | + | .. data:: EVENT_WRITE | Available for write | +-----------------------+-----------------------------------------------+ @@ -132,8 +132,8 @@ constants below: Change a registered file object's monitored events or attached data. - This is equivalent to :meth:`BaseSelector.unregister(fileobj)` followed - by :meth:`BaseSelector.register(fileobj, events, data)`, except that it + This is equivalent to ``BaseSelector.unregister(fileobj)`` followed + by ``BaseSelector.register(fileobj, events, data)``, except that it can be implemented more efficiently. This returns a new :class:`SelectorKey` instance, or raises a diff --git a/Doc/library/shelve.rst b/Doc/library/shelve.rst index a50fc6f0..01314f49 100644 --- a/Doc/library/shelve.rst +++ b/Doc/library/shelve.rst @@ -6,7 +6,7 @@ **Source code:** :source:`Lib/shelve.py` -.. index:: module: pickle +.. index:: pair: module; pickle -------------- @@ -25,7 +25,7 @@ lots of shared sub-objects. The keys are ordinary strings. database file is opened for reading and writing. The optional *flag* parameter has the same interpretation as the *flag* parameter of :func:`dbm.open`. - By default, pickles created with :data:`pickle.DEFAULT_PROTOCOL` are used + By default, pickles created with :const:`pickle.DEFAULT_PROTOCOL` are used to serialize values. The version of the pickle protocol can be specified with the *protocol* parameter. @@ -42,7 +42,7 @@ lots of shared sub-objects. The keys are ordinary strings. mutated). .. versionchanged:: 3.10 - :data:`pickle.DEFAULT_PROTOCOL` is now used as the default pickle + :const:`pickle.DEFAULT_PROTOCOL` is now used as the default pickle protocol. .. versionchanged:: 3.11 @@ -95,8 +95,8 @@ Restrictions ------------ .. index:: - module: dbm.ndbm - module: dbm.gnu + pair: module; dbm.ndbm + pair: module; dbm.gnu * The choice of which database package will be used (such as :mod:`dbm.ndbm` or :mod:`dbm.gnu`) depends on which interface is available. Therefore it is not @@ -119,7 +119,7 @@ Restrictions A subclass of :class:`collections.abc.MutableMapping` which stores pickled values in the *dict* object. - By default, pickles created with :data:`pickle.DEFAULT_PROTOCOL` are used + By default, pickles created with :const:`pickle.DEFAULT_PROTOCOL` are used to serialize values. The version of the pickle protocol can be specified with the *protocol* parameter. See the :mod:`pickle` documentation for a discussion of the pickle protocols. @@ -143,7 +143,7 @@ Restrictions Added context manager support. .. versionchanged:: 3.10 - :data:`pickle.DEFAULT_PROTOCOL` is now used as the default pickle + :const:`pickle.DEFAULT_PROTOCOL` is now used as the default pickle protocol. diff --git a/Doc/library/shlex.rst b/Doc/library/shlex.rst index aab6a543..f94833ad 100644 --- a/Doc/library/shlex.rst +++ b/Doc/library/shlex.rst @@ -30,15 +30,9 @@ The :mod:`shlex` module defines the following functions: in POSIX mode by default, but uses non-POSIX mode if the *posix* argument is false. - .. note:: - - Since the :func:`split` function instantiates a :class:`~shlex.shlex` - instance, passing ``None`` for *s* will read the string to split from - standard input. - - .. deprecated:: 3.9 - Passing ``None`` for *s* will raise an exception in future Python - versions. + .. versionchanged:: 3.12 + Passing ``None`` for *s* argument now raises an exception, rather than + reading :data:`sys.stdin`. .. function:: join(split_command) diff --git a/Doc/library/shutil.rst b/Doc/library/shutil.rst index 8f1668f7..4390a8e2 100644 --- a/Doc/library/shutil.rst +++ b/Doc/library/shutil.rst @@ -292,15 +292,15 @@ Directory and files operations .. versionadded:: 3.8 The *dirs_exist_ok* parameter. -.. function:: rmtree(path, ignore_errors=False, onerror=None, *, dir_fd=None) +.. function:: rmtree(path, ignore_errors=False, onerror=None, *, onexc=None, dir_fd=None) .. index:: single: directory; deleting Delete an entire directory tree; *path* must point to a directory (but not a symbolic link to a directory). If *ignore_errors* is true, errors resulting from failed removals will be ignored; if false or omitted, such errors are - handled by calling a handler specified by *onerror* or, if that is omitted, - they raise an exception. + handled by calling a handler specified by *onexc* or *onerror* or, if both + are omitted, exceptions are propagated to the caller. This function can support :ref:`paths relative to directory descriptors <dir_fd>`. @@ -315,14 +315,17 @@ Directory and files operations otherwise. Applications can use the :data:`rmtree.avoids_symlink_attacks` function attribute to determine which case applies. - If *onerror* is provided, it must be a callable that accepts three - parameters: *function*, *path*, and *excinfo*. + If *onexc* is provided, it must be a callable that accepts three parameters: + *function*, *path*, and *excinfo*. The first parameter, *function*, is the function which raised the exception; it depends on the platform and implementation. The second parameter, *path*, will be the path name passed to *function*. The third parameter, - *excinfo*, will be the exception information returned by - :func:`sys.exc_info`. Exceptions raised by *onerror* will not be caught. + *excinfo*, is the exception that was raised. Exceptions raised by *onexc* + will not be caught. + + The deprecated *onerror* is similar to *onexc*, except that the third + parameter it receives is the tuple returned from :func:`sys.exc_info`. .. audit-event:: shutil.rmtree path,dir_fd shutil.rmtree @@ -337,6 +340,9 @@ Directory and files operations .. versionchanged:: 3.11 The *dir_fd* parameter. + .. versionchanged:: 3.12 + Added the *onexc* parameter, deprecated *onerror*. + .. attribute:: rmtree.avoids_symlink_attacks Indicates whether the current platform and implementation provides a @@ -363,7 +369,7 @@ Directory and files operations If *copy_function* is given, it must be a callable that takes two arguments *src* and *dst*, and will be used to copy *src* to *dst* if :func:`os.rename` cannot be used. If the source is a directory, - :func:`copytree` is called, passing it the :func:`copy_function`. The + :func:`copytree` is called, passing it the *copy_function*. The default *copy_function* is :func:`copy2`. Using :func:`~shutil.copy` as the *copy_function* allows the move to succeed when it is not possible to also copy the metadata, at the expense of not copying any of the metadata. @@ -393,6 +399,12 @@ Directory and files operations total, used and free space, in bytes. *path* may be a file or a directory. + .. note:: + + On Unix filesystems, *path* must point to a path within a **mounted** + filesystem partition. On those platforms, CPython doesn't attempt to + retrieve disk usage information from non-mounted filesystems. + .. versionadded:: 3.3 .. versionchanged:: 3.8 @@ -425,25 +437,45 @@ Directory and files operations determining if the file exists and executable. When no *path* is specified, the results of :func:`os.environ` are used, - returning either the "PATH" value or a fallback of :attr:`os.defpath`. + returning either the "PATH" value or a fallback of :data:`os.defpath`. + + On Windows, the current directory is prepended to the *path* if *mode* does + not include ``os.X_OK``. When the *mode* does include ``os.X_OK``, the + Windows API ``NeedCurrentDirectoryForExePathW`` will be consulted to + determine if the current directory should be prepended to *path*. To avoid + consulting the current working directory for executables: set the environment + variable ``NoDefaultCurrentDirectoryInExePath``. - On Windows, the current directory is always prepended to the *path* whether - or not you use the default or provide your own, which is the behavior the - command shell uses when finding executables. Additionally, when finding the - *cmd* in the *path*, the ``PATHEXT`` environment variable is checked. For - example, if you call ``shutil.which("python")``, :func:`which` will search - ``PATHEXT`` to know that it should look for ``python.exe`` within the *path* - directories. For example, on Windows:: + Also on Windows, the ``PATHEXT`` variable is used to resolve commands + that may not already include an extension. For example, if you call + ``shutil.which("python")``, :func:`which` will search ``PATHEXT`` + to know that it should look for ``python.exe`` within the *path* + directories. For example, on Windows:: >>> shutil.which("python") 'C:\\Python33\\python.EXE' + This is also applied when *cmd* is a path that contains a directory + component:: + + >> shutil.which("C:\\Python33\\python") + 'C:\\Python33\\python.EXE' + .. versionadded:: 3.3 .. versionchanged:: 3.8 The :class:`bytes` type is now accepted. If *cmd* type is :class:`bytes`, the result type is also :class:`bytes`. + .. versionchanged:: 3.12 + On Windows, the current directory is no longer prepended to the search + path if *mode* includes ``os.X_OK`` and WinAPI + ``NeedCurrentDirectoryForExePathW(cmd)`` is false, else the current + directory is prepended even if it is already in the search path; + ``PATHEXT`` is used now even when *cmd* includes a directory component + or ends with an extension that is in ``PATHEXT``; and filenames that + have no extension can now be found. + .. exception:: Error This exception collects exceptions that are raised during a multi-file @@ -509,7 +541,7 @@ rmtree example ~~~~~~~~~~~~~~ This example shows how to remove a directory tree on Windows where some -of the files have their read-only bit set. It uses the onerror callback +of the files have their read-only bit set. It uses the onexc callback to clear the readonly bit and reattempt the remove. Any subsequent failure will propagate. :: @@ -521,7 +553,7 @@ will propagate. :: os.chmod(path, stat.S_IWRITE) func(path) - shutil.rmtree(directory, onerror=remove_readonly) + shutil.rmtree(directory, onexc=remove_readonly) .. _archiving-operations: @@ -575,9 +607,10 @@ provided. They rely on the :mod:`zipfile` and :mod:`tarfile` modules. .. note:: This function is not thread-safe when custom archivers registered - with :func:`register_archive_format` are used. In this case it + with :func:`register_archive_format` do not support the *root_dir* + argument. In this case it temporarily changes the current working directory of the process - to perform archiving. + to *root_dir* to perform archiving. .. versionchanged:: 3.8 The modern pax (POSIX.1-2001) format is now used instead of @@ -614,19 +647,28 @@ provided. They rely on the :mod:`zipfile` and :mod:`tarfile` modules. Further arguments are passed as keyword arguments: *owner*, *group*, *dry_run* and *logger* (as passed in :func:`make_archive`). + If *function* has the custom attribute ``function.supports_root_dir`` set to ``True``, + the *root_dir* argument is passed as a keyword argument. + Otherwise the current working directory of the process is temporarily + changed to *root_dir* before calling *function*. + In this case :func:`make_archive` is not thread-safe. + If given, *extra_args* is a sequence of ``(name, value)`` pairs that will be used as extra keywords arguments when the archiver callable is used. *description* is used by :func:`get_archive_formats` which returns the list of archivers. Defaults to an empty string. + .. versionchanged:: 3.12 + Added support for functions supporting the *root_dir* argument. + .. function:: unregister_archive_format(name) Remove the archive format *name* from the list of supported formats. -.. function:: unpack_archive(filename[, extract_dir[, format]]) +.. function:: unpack_archive(filename[, extract_dir[, format[, filter]]]) Unpack an archive. *filename* is the full path of the archive. @@ -640,6 +682,14 @@ provided. They rely on the :mod:`zipfile` and :mod:`tarfile` modules. registered for that extension. In case none is found, a :exc:`ValueError` is raised. + The keyword-only *filter* argument is passed to the underlying unpacking + function. For zip files, *filter* is not accepted. + For tar files, it is recommended to set it to ``'data'``, + unless using features specific to tar and UNIX-like filesystems. + (See :ref:`tarfile-extraction-filter` for details.) + The ``'data'`` filter will become the default for tar files + in Python 3.14. + .. audit-event:: shutil.unpack_archive filename,extract_dir,format shutil.unpack_archive .. warning:: @@ -652,6 +702,9 @@ provided. They rely on the :mod:`zipfile` and :mod:`tarfile` modules. .. versionchanged:: 3.7 Accepts a :term:`path-like object` for *filename* and *extract_dir*. + .. versionchanged:: 3.12 + Added the *filter* argument. + .. function:: register_unpack_format(name, extensions, function[, extra_args[, description]]) Registers an unpack format. *name* is the name of the format and @@ -659,11 +712,14 @@ provided. They rely on the :mod:`zipfile` and :mod:`tarfile` modules. ``.zip`` for Zip files. *function* is the callable that will be used to unpack archives. The - callable will receive the path of the archive, followed by the directory - the archive must be extracted to. - - When provided, *extra_args* is a sequence of ``(name, value)`` tuples that - will be passed as keywords arguments to the callable. + callable will receive: + + - the path of the archive, as a positional argument; + - the directory the archive must be extracted to, as a positional argument; + - possibly a *filter* keyword argument, if it was given to + :func:`unpack_archive`; + - additional keyword arguments, specified by *extra_args* as a sequence + of ``(name, value)`` tuples. *description* can be provided to describe the format, and will be returned by the :func:`get_unpack_formats` function. diff --git a/Doc/library/signal.rst b/Doc/library/signal.rst index 523d1ac5..7ee5ece8 100644 --- a/Doc/library/signal.rst +++ b/Doc/library/signal.rst @@ -562,7 +562,7 @@ The :mod:`signal` module defines the following functions: Note that installing a signal handler with :func:`signal` will reset the restart behaviour to interruptible by implicitly calling - :c:func:`siginterrupt` with a true *flag* value for the given signal. + :c:func:`!siginterrupt` with a true *flag* value for the given signal. .. function:: signal(signalnum, handler) @@ -656,7 +656,7 @@ The :mod:`signal` module defines the following functions: .. function:: sigtimedwait(sigset, timeout) Like :func:`sigwaitinfo`, but takes an additional *timeout* argument - specifying a timeout. If *timeout* is specified as :const:`0`, a poll is + specifying a timeout. If *timeout* is specified as ``0``, a poll is performed. Returns :const:`None` if a timeout occurs. .. availability:: Unix. diff --git a/Doc/library/site.rst b/Doc/library/site.rst index 5941739e..02880c56 100644 --- a/Doc/library/site.rst +++ b/Doc/library/site.rst @@ -19,7 +19,7 @@ Importing this module will append site-specific paths to the module search path and add a few builtins, unless :option:`-S` was used. In that case, this module can be safely imported with no automatic modifications to the module search path or additions to the builtins. To explicitly trigger the usual site-specific -additions, call the :func:`site.main` function. +additions, call the :func:`main` function. .. versionchanged:: 3.3 Importing the module used to trigger paths manipulation even when using @@ -51,7 +51,7 @@ searched for site-packages; otherwise they will. .. index:: single: # (hash); comment - statement: import + pair: statement; import A path configuration file is a file whose name has the form :file:`{name}.pth` and exists in one of the four directories mentioned above; its contents are @@ -109,32 +109,40 @@ directory precedes the :file:`foo` directory because :file:`bar.pth` comes alphabetically before :file:`foo.pth`; and :file:`spam` is omitted because it is not mentioned in either path configuration file. -.. index:: module: sitecustomize +:mod:`sitecustomize` +-------------------- + +.. module:: sitecustomize After these path manipulations, an attempt is made to import a module named :mod:`sitecustomize`, which can perform arbitrary site-specific customizations. It is typically created by a system administrator in the site-packages directory. If this import fails with an :exc:`ImportError` or its subclass -exception, and the exception's :attr:`name` attribute equals to ``'sitecustomize'``, +exception, and the exception's :attr:`~ImportError.name` +attribute equals to ``'sitecustomize'``, it is silently ignored. If Python is started without output streams available, as with :file:`pythonw.exe` on Windows (which is used by default to start IDLE), attempted output from :mod:`sitecustomize` is ignored. Any other exception causes a silent and perhaps mysterious failure of the process. -.. index:: module: usercustomize +:mod:`usercustomize` +-------------------- + +.. module:: usercustomize After this, an attempt is made to import a module named :mod:`usercustomize`, which can perform arbitrary user-specific customizations, if -:data:`ENABLE_USER_SITE` is true. This file is intended to be created in the +:data:`~site.ENABLE_USER_SITE` is true. This file is intended to be created in the user site-packages directory (see below), which is part of ``sys.path`` unless disabled by :option:`-s`. If this import fails with an :exc:`ImportError` or -its subclass exception, and the exception's :attr:`name` attribute equals to -``'usercustomize'``, it is silently ignored. +its subclass exception, and the exception's :attr:`~ImportError.name` +attribute equals to ``'usercustomize'``, it is silently ignored. Note that for some non-Unix systems, ``sys.prefix`` and ``sys.exec_prefix`` are empty, and the path manipulations are skipped; however the import of :mod:`sitecustomize` and :mod:`usercustomize` is still attempted. +.. currentmodule:: site .. _rlcompleter-config: @@ -189,9 +197,9 @@ Module contents :func:`getuserbase` hasn't been called yet. Default value is :file:`~/.local` for UNIX and macOS non-framework builds, :file:`~/Library/Python/{X.Y}` for macOS framework builds, and - :file:`{%APPDATA%}\\Python` for Windows. This value is used by Distutils to + :file:`{%APPDATA%}\\Python` for Windows. This value is used to compute the installation directories for scripts, data files, Python modules, - etc. for the :ref:`user installation scheme <inst-alt-install-user>`. + etc. for the :ref:`user installation scheme <sysconfig-user-scheme>`. See also :envvar:`PYTHONUSERBASE`. @@ -250,8 +258,8 @@ command line: .. code-block:: shell-session - $ python3 -m site --user-site - /home/user/.local/lib/python3.3/site-packages + $ python -m site --user-site + /home/user/.local/lib/python3.11/site-packages If it is called without arguments, it will print the contents of :data:`sys.path` on the standard output, followed by the value of diff --git a/Doc/library/smtpd.rst b/Doc/library/smtpd.rst deleted file mode 100644 index ac0c9aeb..00000000 --- a/Doc/library/smtpd.rst +++ /dev/null @@ -1,268 +0,0 @@ -:mod:`smtpd` --- SMTP Server -============================ - -.. module:: smtpd - :synopsis: A SMTP server implementation in Python. - :deprecated: - -.. moduleauthor:: Barry Warsaw <barry@python.org> -.. sectionauthor:: Moshe Zadka <moshez@moshez.org> - -**Source code:** :source:`Lib/smtpd.py` - --------------- - -This module offers several classes to implement SMTP (email) servers. - -.. deprecated-removed:: 3.6 3.12 - The :mod:`smtpd` module is deprecated - (see :pep:`PEP 594 <594#smtpd>` for details). - The `aiosmtpd <https://aiosmtpd.readthedocs.io/>`_ package is a recommended - replacement for this module. It is based on :mod:`asyncio` and provides a - more straightforward API. - -Several server implementations are present; one is a generic -do-nothing implementation, which can be overridden, while the other two offer -specific mail-sending strategies. - -Additionally the SMTPChannel may be extended to implement very specific -interaction behaviour with SMTP clients. - -The code supports :RFC:`5321`, plus the :rfc:`1870` SIZE and :rfc:`6531` -SMTPUTF8 extensions. - -.. include:: ../includes/wasm-notavail.rst - -SMTPServer Objects ------------------- - - -.. class:: SMTPServer(localaddr, remoteaddr, data_size_limit=33554432,\ - map=None, enable_SMTPUTF8=False, decode_data=False) - - Create a new :class:`SMTPServer` object, which binds to local address - *localaddr*. It will treat *remoteaddr* as an upstream SMTP relayer. Both - *localaddr* and *remoteaddr* should be a :ref:`(host, port) <host_port>` - tuple. The object inherits from :class:`asyncore.dispatcher`, and so will - insert itself into :mod:`asyncore`'s event loop on instantiation. - - *data_size_limit* specifies the maximum number of bytes that will be - accepted in a ``DATA`` command. A value of ``None`` or ``0`` means no - limit. - - *map* is the socket map to use for connections (an initially empty - dictionary is a suitable value). If not specified the :mod:`asyncore` - global socket map is used. - - *enable_SMTPUTF8* determines whether the ``SMTPUTF8`` extension (as defined - in :RFC:`6531`) should be enabled. The default is ``False``. - When ``True``, ``SMTPUTF8`` is accepted as a parameter to the ``MAIL`` - command and when present is passed to :meth:`process_message` in the - ``kwargs['mail_options']`` list. *decode_data* and *enable_SMTPUTF8* - cannot be set to ``True`` at the same time. - - *decode_data* specifies whether the data portion of the SMTP transaction - should be decoded using UTF-8. When *decode_data* is ``False`` (the - default), the server advertises the ``8BITMIME`` - extension (:rfc:`6152`), accepts the ``BODY=8BITMIME`` parameter to - the ``MAIL`` command, and when present passes it to :meth:`process_message` - in the ``kwargs['mail_options']`` list. *decode_data* and *enable_SMTPUTF8* - cannot be set to ``True`` at the same time. - - .. method:: process_message(peer, mailfrom, rcpttos, data, **kwargs) - - Raise a :exc:`NotImplementedError` exception. Override this in subclasses to - do something useful with this message. Whatever was passed in the - constructor as *remoteaddr* will be available as the :attr:`_remoteaddr` - attribute. *peer* is the remote host's address, *mailfrom* is the envelope - originator, *rcpttos* are the envelope recipients and *data* is a string - containing the contents of the e-mail (which should be in :rfc:`5321` - format). - - If the *decode_data* constructor keyword is set to ``True``, the *data* - argument will be a unicode string. If it is set to ``False``, it - will be a bytes object. - - *kwargs* is a dictionary containing additional information. It is empty - if ``decode_data=True`` was given as an init argument, otherwise - it contains the following keys: - - *mail_options*: - a list of all received parameters to the ``MAIL`` - command (the elements are uppercase strings; example: - ``['BODY=8BITMIME', 'SMTPUTF8']``). - - *rcpt_options*: - same as *mail_options* but for the ``RCPT`` command. - Currently no ``RCPT TO`` options are supported, so for now - this will always be an empty list. - - Implementations of ``process_message`` should use the ``**kwargs`` - signature to accept arbitrary keyword arguments, since future feature - enhancements may add keys to the kwargs dictionary. - - Return ``None`` to request a normal ``250 Ok`` response; otherwise - return the desired response string in :RFC:`5321` format. - - .. attribute:: channel_class - - Override this in subclasses to use a custom :class:`SMTPChannel` for - managing SMTP clients. - - .. versionadded:: 3.4 - The *map* constructor argument. - - .. versionchanged:: 3.5 - *localaddr* and *remoteaddr* may now contain IPv6 addresses. - - .. versionadded:: 3.5 - The *decode_data* and *enable_SMTPUTF8* constructor parameters, and the - *kwargs* parameter to :meth:`process_message` when *decode_data* is - ``False``. - - .. versionchanged:: 3.6 - *decode_data* is now ``False`` by default. - - -DebuggingServer Objects ------------------------ - - -.. class:: DebuggingServer(localaddr, remoteaddr) - - Create a new debugging server. Arguments are as per :class:`SMTPServer`. - Messages will be discarded, and printed on stdout. - - -PureProxy Objects ------------------ - - -.. class:: PureProxy(localaddr, remoteaddr) - - Create a new pure proxy server. Arguments are as per :class:`SMTPServer`. - Everything will be relayed to *remoteaddr*. Note that running this has a good - chance to make you into an open relay, so please be careful. - - -SMTPChannel Objects -------------------- - -.. class:: SMTPChannel(server, conn, addr, data_size_limit=33554432,\ - map=None, enable_SMTPUTF8=False, decode_data=False) - - Create a new :class:`SMTPChannel` object which manages the communication - between the server and a single SMTP client. - - *conn* and *addr* are as per the instance variables described below. - - *data_size_limit* specifies the maximum number of bytes that will be - accepted in a ``DATA`` command. A value of ``None`` or ``0`` means no - limit. - - *enable_SMTPUTF8* determines whether the ``SMTPUTF8`` extension (as defined - in :RFC:`6531`) should be enabled. The default is ``False``. - *decode_data* and *enable_SMTPUTF8* cannot be set to ``True`` at the same - time. - - A dictionary can be specified in *map* to avoid using a global socket map. - - *decode_data* specifies whether the data portion of the SMTP transaction - should be decoded using UTF-8. The default is ``False``. - *decode_data* and *enable_SMTPUTF8* cannot be set to ``True`` at the same - time. - - To use a custom SMTPChannel implementation you need to override the - :attr:`SMTPServer.channel_class` of your :class:`SMTPServer`. - - .. versionchanged:: 3.5 - The *decode_data* and *enable_SMTPUTF8* parameters were added. - - .. versionchanged:: 3.6 - *decode_data* is now ``False`` by default. - - The :class:`SMTPChannel` has the following instance variables: - - .. attribute:: smtp_server - - Holds the :class:`SMTPServer` that spawned this channel. - - .. attribute:: conn - - Holds the socket object connecting to the client. - - .. attribute:: addr - - Holds the address of the client, the second value returned by - :func:`socket.accept <socket.socket.accept>` - - .. attribute:: received_lines - - Holds a list of the line strings (decoded using UTF-8) received from - the client. The lines have their ``"\r\n"`` line ending translated to - ``"\n"``. - - .. attribute:: smtp_state - - Holds the current state of the channel. This will be either - :attr:`COMMAND` initially and then :attr:`DATA` after the client sends - a "DATA" line. - - .. attribute:: seen_greeting - - Holds a string containing the greeting sent by the client in its "HELO". - - .. attribute:: mailfrom - - Holds a string containing the address identified in the "MAIL FROM:" line - from the client. - - .. attribute:: rcpttos - - Holds a list of strings containing the addresses identified in the - "RCPT TO:" lines from the client. - - .. attribute:: received_data - - Holds a string containing all of the data sent by the client during the - DATA state, up to but not including the terminating ``"\r\n.\r\n"``. - - .. attribute:: fqdn - - Holds the fully qualified domain name of the server as returned by - :func:`socket.getfqdn`. - - .. attribute:: peer - - Holds the name of the client peer as returned by ``conn.getpeername()`` - where ``conn`` is :attr:`conn`. - - The :class:`SMTPChannel` operates by invoking methods named ``smtp_<command>`` - upon reception of a command line from the client. Built into the base - :class:`SMTPChannel` class are methods for handling the following commands - (and responding to them appropriately): - - ======== =================================================================== - Command Action taken - ======== =================================================================== - HELO Accepts the greeting from the client and stores it in - :attr:`seen_greeting`. Sets server to base command mode. - EHLO Accepts the greeting from the client and stores it in - :attr:`seen_greeting`. Sets server to extended command mode. - NOOP Takes no action. - QUIT Closes the connection cleanly. - MAIL Accepts the "MAIL FROM:" syntax and stores the supplied address as - :attr:`mailfrom`. In extended command mode, accepts the - :rfc:`1870` SIZE attribute and responds appropriately based on the - value of *data_size_limit*. - RCPT Accepts the "RCPT TO:" syntax and stores the supplied addresses in - the :attr:`rcpttos` list. - RSET Resets the :attr:`mailfrom`, :attr:`rcpttos`, and - :attr:`received_data`, but not the greeting. - DATA Sets the internal state to :attr:`DATA` and stores remaining lines - from the client in :attr:`received_data` until the terminator - ``"\r\n.\r\n"`` is received. - HELP Returns minimal information on command syntax - VRFY Returns code 252 (the server doesn't know if the address is valid) - EXPN Reports that the command is not implemented. - ======== =================================================================== diff --git a/Doc/library/smtplib.rst b/Doc/library/smtplib.rst index 4e50ad15..aaec2aa1 100644 --- a/Doc/library/smtplib.rst +++ b/Doc/library/smtplib.rst @@ -25,7 +25,7 @@ Protocol) and :rfc:`1869` (SMTP Service Extensions). An :class:`SMTP` instance encapsulates an SMTP connection. It has methods that support a full repertoire of SMTP and ESMTP operations. If the optional - host and port parameters are given, the SMTP :meth:`connect` method is + *host* and *port* parameters are given, the SMTP :meth:`connect` method is called with those parameters during initialization. If specified, *local_hostname* is used as the FQDN of the local host in the HELO/EHLO command. Otherwise, the local hostname is found using @@ -34,12 +34,12 @@ Protocol) and :rfc:`1869` (SMTP Service Extensions). *timeout* parameter specifies a timeout in seconds for blocking operations like the connection attempt (if not specified, the global default timeout setting will be used). If the timeout expires, :exc:`TimeoutError` is - raised. The optional source_address parameter allows binding + raised. The optional *source_address* parameter allows binding to some specific source address in a machine with multiple network interfaces, and/or to some specific source TCP port. It takes a 2-tuple - (host, port), for the socket to bind to as its source address before - connecting. If omitted (or if host or port are ``''`` and/or 0 respectively) - the OS default behavior will be used. + ``(host, port)``, for the socket to bind to as its source address before + connecting. If omitted (or if *host* or *port* are ``''`` and/or ``0`` + respectively) the OS default behavior will be used. For normal use, you should only require the initialization/connect, :meth:`sendmail`, and :meth:`SMTP.quit` methods. @@ -66,18 +66,17 @@ Protocol) and :rfc:`1869` (SMTP Service Extensions). Support for the :keyword:`with` statement was added. .. versionchanged:: 3.3 - source_address argument was added. + *source_address* argument was added. .. versionadded:: 3.5 The SMTPUTF8 extension (:rfc:`6531`) is now supported. .. versionchanged:: 3.9 If the *timeout* parameter is set to be zero, it will raise a - :class:`ValueError` to prevent the creation of a non-blocking socket + :class:`ValueError` to prevent the creation of a non-blocking socket. -.. class:: SMTP_SSL(host='', port=0, local_hostname=None, keyfile=None, \ - certfile=None [, timeout], context=None, \ - source_address=None) +.. class:: SMTP_SSL(host='', port=0, local_hostname=None, * [, timeout], \ + context=None, source_address=None) An :class:`SMTP_SSL` instance behaves exactly the same as instances of :class:`SMTP`. :class:`SMTP_SSL` should be used for situations where SSL is @@ -90,39 +89,31 @@ Protocol) and :rfc:`1869` (SMTP Service Extensions). aspects of the secure connection. Please read :ref:`ssl-security` for best practices. - *keyfile* and *certfile* are a legacy alternative to *context*, and can - point to a PEM formatted private key and certificate chain file for the - SSL connection. - .. versionchanged:: 3.3 *context* was added. .. versionchanged:: 3.3 - source_address argument was added. + The *source_address* argument was added. .. versionchanged:: 3.4 The class now supports hostname check with :attr:`ssl.SSLContext.check_hostname` and *Server Name Indication* (see - :data:`ssl.HAS_SNI`). - - .. deprecated:: 3.6 - - *keyfile* and *certfile* are deprecated in favor of *context*. - Please use :meth:`ssl.SSLContext.load_cert_chain` instead, or let - :func:`ssl.create_default_context` select the system's trusted CA - certificates for you. + :const:`ssl.HAS_SNI`). .. versionchanged:: 3.9 If the *timeout* parameter is set to be zero, it will raise a :class:`ValueError` to prevent the creation of a non-blocking socket + .. versionchanged:: 3.12 + The deprecated *keyfile* and *certfile* parameters have been removed. + .. class:: LMTP(host='', port=LMTP_PORT, local_hostname=None, \ source_address=None[, timeout]) The LMTP protocol, which is very similar to ESMTP, is heavily based on the standard SMTP client. It's common to use Unix sockets for LMTP, so our :meth:`connect` method must support that as well as a regular host:port - server. The optional arguments local_hostname and source_address have the + server. The optional arguments *local_hostname* and *source_address* have the same meaning as they do in the :class:`SMTP` class. To specify a Unix socket, you must use an absolute path for *host*, starting with a '/'. @@ -360,7 +351,7 @@ An :class:`SMTP` instance has the following methods: be used as argument to the ``AUTH`` command; the valid values are those listed in the ``auth`` element of :attr:`esmtp_features`. - *authobject* must be a callable object taking an optional single argument: + *authobject* must be a callable object taking an optional single argument:: data = authobject(challenge=None) @@ -393,7 +384,7 @@ An :class:`SMTP` instance has the following methods: .. versionadded:: 3.5 -.. method:: SMTP.starttls(keyfile=None, certfile=None, context=None) +.. method:: SMTP.starttls(*, context=None) Put the SMTP connection in TLS (Transport Layer Security) mode. All SMTP commands that follow will be encrypted. You should then call :meth:`ehlo` @@ -409,12 +400,8 @@ An :class:`SMTP` instance has the following methods: If there has been no previous ``EHLO`` or ``HELO`` command this session, this method tries ESMTP ``EHLO`` first. - .. deprecated:: 3.6 - - *keyfile* and *certfile* are deprecated in favor of *context*. - Please use :meth:`ssl.SSLContext.load_cert_chain` instead, or let - :func:`ssl.create_default_context` select the system's trusted CA - certificates for you. + .. versionchanged:: 3.12 + The deprecated *keyfile* and *certfile* parameters have been removed. :exc:`SMTPHeloError` The server didn't reply properly to the ``HELO`` greeting. @@ -431,7 +418,7 @@ An :class:`SMTP` instance has the following methods: .. versionchanged:: 3.4 The method now supports hostname check with :attr:`SSLContext.check_hostname` and *Server Name Indicator* (see - :data:`~ssl.HAS_SNI`). + :const:`~ssl.HAS_SNI`). .. versionchanged:: 3.5 The error raised for lack of STARTTLS support is now the diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst index bb689c4d..83957c87 100644 --- a/Doc/library/socket.rst +++ b/Doc/library/socket.rst @@ -19,7 +19,7 @@ all modern Unix systems, Windows, MacOS, and probably additional platforms. .. include:: ../includes/wasm-notavail.rst -.. index:: object: socket +.. index:: pair: object; socket The Python interface is a straightforward transliteration of the Unix system call and library interface for sockets to Python's object-oriented style: the @@ -189,8 +189,11 @@ created. Socket addresses are represented as follows: ``(ifname, proto[, pkttype[, hatype[, addr]]])`` where: - *ifname* - String specifying the device name. - - *proto* - An in network-byte-order integer specifying the Ethernet - protocol number. + - *proto* - The Ethernet protocol number. + May be :data:`ETH_P_ALL` to capture all protocols, + one of the :ref:`ETHERTYPE_* constants <socket-ethernet-types>` + or any other Ethernet protocol number. + Value must be in network-byte-order. - *pkttype* - Optional integer specifying the packet type: - ``PACKET_HOST`` (the default) - Packet addressed to the local host. @@ -232,6 +235,29 @@ created. Socket addresses are represented as follows: .. versionadded:: 3.9 +- :const:`AF_HYPERV` is a Windows-only socket based interface for communicating + with Hyper-V hosts and guests. The address family is represented as a + ``(vm_id, service_id)`` tuple where the ``vm_id`` and ``service_id`` are + UUID strings. + + The ``vm_id`` is the virtual machine identifier or a set of known VMID values + if the target is not a specific virtual machine. Known VMID constants + defined on ``socket`` are: + + - ``HV_GUID_ZERO`` + - ``HV_GUID_BROADCAST`` + - ``HV_GUID_WILDCARD`` - Used to bind on itself and accept connections from + all partitions. + - ``HV_GUID_CHILDREN`` - Used to bind on itself and accept connection from + child partitions. + - ``HV_GUID_LOOPBACK`` - Used as a target to itself. + - ``HV_GUID_PARENT`` - When used as a bind accepts connection from the parent + partition. When used as an address target it will connect to the parent partition. + + The ``service_id`` is the service identifier of the registered service. + + .. versionadded:: 3.12 + If you use a hostname in the *host* portion of IPv4/v6 socket address, the program may show a nondeterministic behavior, as Python uses the first address returned from the DNS resolution. The socket address will be resolved @@ -399,6 +425,20 @@ Constants Added ``TCP_CONNECTION_INFO``. On MacOS this constant can be used in the same way that ``TCP_INFO`` is used on Linux and BSD. + .. versionchanged:: 3.12 + Added ``SO_RTABLE`` and ``SO_USER_COOKIE``. On OpenBSD + and FreeBSD respectively those constants can be used in the same way that + ``SO_MARK`` is used on Linux. Also added missing TCP socket options from + Linux: ``TCP_MD5SIG``, ``TCP_THIN_LINEAR_TIMEOUTS``, ``TCP_THIN_DUPACK``, + ``TCP_REPAIR``, ``TCP_REPAIR_QUEUE``, ``TCP_QUEUE_SEQ``, + ``TCP_REPAIR_OPTIONS``, ``TCP_TIMESTAMP``, ``TCP_CC_INFO``, + ``TCP_SAVE_SYN``, ``TCP_SAVED_SYN``, ``TCP_REPAIR_WINDOW``, + ``TCP_FASTOPEN_CONNECT``, ``TCP_ULP``, ``TCP_MD5SIG_EXT``, + ``TCP_FASTOPEN_KEY``, ``TCP_FASTOPEN_NO_COOKIE``, + ``TCP_ZEROCOPY_RECEIVE``, ``TCP_INQ``, ``TCP_TX_DELAY``. + Added ``IP_PKTINFO``, ``IP_UNBLOCK_SOURCE``, ``IP_BLOCK_SOURCE``, + ``IP_ADD_SOURCE_MEMBERSHIP``, ``IP_DROP_SOURCE_MEMBERSHIP``. + .. data:: AF_CAN PF_CAN SOL_CAN_* @@ -470,6 +510,17 @@ Constants .. versionadded:: 3.9 +.. data:: AF_DIVERT + PF_DIVERT + + These two constants, documented in the FreeBSD divert(4) manual page, are + also defined in the socket module. + + .. availability:: FreeBSD >= 14.0. + + .. versionadded:: 3.12 + + .. data:: AF_PACKET PF_PACKET PACKET_* @@ -480,6 +531,19 @@ Constants .. availability:: Linux >= 2.2. +.. data:: ETH_P_ALL + + :data:`!ETH_P_ALL` can be used in the :class:`~socket.socket` + constructor as *proto* for the :const:`AF_PACKET` family in order to + capture every packet, regardless of protocol. + + For more information, see the :manpage:`packet(7)` manpage. + + .. availability:: Linux. + + .. versionadded:: 3.12 + + .. data:: AF_RDS PF_RDS SOL_RDS @@ -591,6 +655,41 @@ Constants .. availability:: Linux >= 3.9 +.. data:: AF_HYPERV + HV_PROTOCOL_RAW + HVSOCKET_CONNECT_TIMEOUT + HVSOCKET_CONNECT_TIMEOUT_MAX + HVSOCKET_CONNECTED_SUSPEND + HVSOCKET_ADDRESS_FLAG_PASSTHRU + HV_GUID_ZERO + HV_GUID_WILDCARD + HV_GUID_BROADCAST + HV_GUID_CHILDREN + HV_GUID_LOOPBACK + HV_GUID_PARENT + + Constants for Windows Hyper-V sockets for host/guest communications. + + .. availability:: Windows. + + .. versionadded:: 3.12 + +.. _socket-ethernet-types: + +.. data:: ETHERTYPE_ARP + ETHERTYPE_IP + ETHERTYPE_IPV6 + ETHERTYPE_VLAN + + `IEEE 802.3 protocol number + <https://www.iana.org/assignments/ieee-802-numbers/ieee-802-numbers.txt>`_. + constants. + + .. availability:: Linux, FreeBSD, macOS. + + .. versionadded:: 3.12 + + Functions ^^^^^^^^^ @@ -714,7 +813,7 @@ The following functions all create :ref:`socket objects <socket-objects>`. .. function:: create_server(address, *, family=AF_INET, backlog=None, reuse_port=False, dualstack_ipv6=False) Convenience function which creates a TCP socket bound to *address* (a 2-tuple - ``(host, port)``) and return the socket object. + ``(host, port)``) and returns the socket object. *family* should be either :data:`AF_INET` or :data:`AF_INET6`. *backlog* is the queue size passed to :meth:`socket.listen`; if not specified @@ -880,7 +979,7 @@ The :mod:`socket` module also offers various network-related services: .. function:: gethostbyname_ex(hostname) Translate a host name to IPv4 address format, extended interface. Return a - triple ``(hostname, aliaslist, ipaddrlist)`` where *hostname* is the host's + 3-tuple ``(hostname, aliaslist, ipaddrlist)`` where *hostname* is the host's primary host name, *aliaslist* is a (possibly empty) list of alternative host names for the same address, and *ipaddrlist* is a list of IPv4 addresses for the same interface on the same host (often but not @@ -908,7 +1007,7 @@ The :mod:`socket` module also offers various network-related services: .. function:: gethostbyaddr(ip_address) - Return a triple ``(hostname, aliaslist, ipaddrlist)`` where *hostname* is the + Return a 3-tuple ``(hostname, aliaslist, ipaddrlist)`` where *hostname* is the primary host name responding to the given *ip_address*, *aliaslist* is a (possibly empty) list of alternative host names for the same address, and *ipaddrlist* is a list of IPv4/v6 addresses for the same interface on the same @@ -1428,7 +1527,7 @@ to sockets. Return ``True`` if socket is in blocking mode, ``False`` if in non-blocking. - This is equivalent to checking ``socket.gettimeout() == 0``. + This is equivalent to checking ``socket.gettimeout() != 0``. .. versionadded:: 3.7 @@ -1688,7 +1787,7 @@ to sockets. much data, if any, was successfully sent. .. versionchanged:: 3.5 - The socket timeout is no more reset each time data is sent successfully. + The socket timeout is no longer reset each time data is sent successfully. The socket timeout is now the maximum total duration to send all data. .. versionchanged:: 3.5 @@ -1829,7 +1928,7 @@ to sockets. .. method:: socket.setsockopt(level, optname, None, optlen: int) :noindex: - .. index:: module: struct + .. index:: pair: module; struct Set the value of the given socket option (see the Unix manual page :manpage:`setsockopt(2)`). The needed symbolic constants are defined in the @@ -1911,8 +2010,8 @@ can be changed by calling :func:`setdefaulttimeout`. * In *non-blocking mode*, operations fail (with an error that is unfortunately system-dependent) if they cannot be completed immediately: functions from the - :mod:`select` can be used to know when and whether a socket is available for - reading or writing. + :mod:`select` module can be used to know when and whether a socket is available + for reading or writing. * In *timeout mode*, operations fail if they cannot be completed within the timeout specified for the socket (they raise a :exc:`timeout` exception) @@ -2101,7 +2200,7 @@ manager protocol instead, open a socket with:: socket.socket(socket.AF_CAN, socket.SOCK_DGRAM, socket.CAN_BCM) After binding (:const:`CAN_RAW`) or connecting (:const:`CAN_BCM`) the socket, you -can use the :meth:`socket.send`, and the :meth:`socket.recv` operations (and +can use the :meth:`socket.send` and :meth:`socket.recv` operations (and their counterparts) on the socket object as usual. This last example might require special privileges:: @@ -2153,7 +2252,7 @@ This is because the previous execution has left the socket in a ``TIME_WAIT`` state, and can't be immediately reused. There is a :mod:`socket` flag to set, in order to prevent this, -:data:`socket.SO_REUSEADDR`:: +:const:`socket.SO_REUSEADDR`:: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) diff --git a/Doc/library/socketserver.rst b/Doc/library/socketserver.rst index a409c99b..d65e9fe8 100644 --- a/Doc/library/socketserver.rst +++ b/Doc/library/socketserver.rst @@ -140,9 +140,16 @@ server is the address family. ForkingUDPServer ThreadingTCPServer ThreadingUDPServer + ForkingUnixStreamServer + ForkingUnixDatagramServer + ThreadingUnixStreamServer + ThreadingUnixDatagramServer These classes are pre-defined using the mix-in classes. +.. versionadded:: 3.12 + The ``ForkingUnixStreamServer`` and ``ForkingUnixDatagramServer`` classes + were added. To implement a service, you must derive a class from :class:`BaseRequestHandler` and redefine its :meth:`~BaseRequestHandler.handle` method. @@ -176,8 +183,7 @@ expensive or inappropriate for the service) is to maintain an explicit table of partially finished requests and to use :mod:`selectors` to decide which request to work on next (or whether to handle a new incoming request). This is particularly important for stream services where each client can potentially be -connected for a long time (if threads or subprocesses cannot be used). See -:mod:`asyncore` for another way to manage this. +connected for a long time (if threads or subprocesses cannot be used). .. XXX should data and methods be intermingled, or separate? how should the distinction between class and instance variables be drawn? diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 8a0d84d1..d5afaa1c 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -72,7 +72,7 @@ including `cursors`_ and `transactions`_. First, we need to create a new database and open a database connection to allow :mod:`!sqlite3` to work with it. -Call :func:`sqlite3.connect` to to create a connection to +Call :func:`sqlite3.connect` to create a connection to the database :file:`tutorial.db` in the current working directory, implicitly creating it if it does not exist: @@ -259,21 +259,23 @@ Module functions .. function:: connect(database, timeout=5.0, detect_types=0, \ isolation_level="DEFERRED", check_same_thread=True, \ factory=sqlite3.Connection, cached_statements=128, \ - uri=False) + uri=False, *, \ + autocommit=sqlite3.LEGACY_TRANSACTION_CONTROL) Open a connection to an SQLite database. :param database: The path to the database file to be opened. - Pass ``":memory:"`` to open a connection to a database that is - in RAM instead of on disk. + You can pass ``":memory:"`` to create an `SQLite database existing only + in memory <https://sqlite.org/inmemorydb.html>`_, and open a connection + to it. :type database: :term:`path-like object` :param float timeout: How many seconds the connection should wait before raising - an exception, if the database is locked by another connection. - If another connection opens a transaction to modify the database, - it will be locked until that transaction is committed. + an :exc:`OperationalError` when a table is locked. + If another connection opens a transaction to modify a table, + that table will be locked until the transaction is committed. Default five seconds. :param int detect_types: @@ -291,11 +293,13 @@ Module functions By default (``0``), type detection is disabled. :param isolation_level: - The :attr:`~Connection.isolation_level` of the connection, - controlling whether and how transactions are implicitly opened. + Control legacy transaction handling behaviour. + See :attr:`Connection.isolation_level` and + :ref:`sqlite3-transaction-control-isolation-level` for more information. Can be ``"DEFERRED"`` (default), ``"EXCLUSIVE"`` or ``"IMMEDIATE"``; or ``None`` to disable opening transactions implicitly. - See :ref:`sqlite3-controlling-transactions` for more. + Has no effect unless :attr:`Connection.autocommit` is set to + :const:`~sqlite3.LEGACY_TRANSACTION_CONTROL` (the default). :type isolation_level: str | None :param bool check_same_thread: @@ -307,7 +311,7 @@ Module functions to avoid data corruption. See :attr:`threadsafety` for more information. - :param Connection factory: + :param ~sqlite3.Connection factory: A custom subclass of :class:`Connection` to create the connection with, if not the default :class:`Connection` class. @@ -325,7 +329,16 @@ Module functions The query string allows passing parameters to SQLite, enabling various :ref:`sqlite3-uri-tricks`. - :rtype: Connection + :param autocommit: + Control :pep:`249` transaction handling behaviour. + See :attr:`Connection.autocommit` and + :ref:`sqlite3-transaction-control-autocommit` for more information. + *autocommit* currently defaults to + :const:`~sqlite3.LEGACY_TRANSACTION_CONTROL`. + The default will change to ``False`` in a future Python release. + :type autocommit: bool + + :rtype: ~sqlite3.Connection .. audit-event:: sqlite3.connect database sqlite3.connect .. audit-event:: sqlite3.connect/handle connection_handle sqlite3.connect @@ -339,6 +352,9 @@ Module functions .. versionadded:: 3.10 The ``sqlite3.connect/handle`` auditing event. + .. versionadded:: 3.12 + The *autocommit* parameter. + .. function:: complete_statement(statement) Return ``True`` if the string *statement* appears to contain @@ -360,6 +376,9 @@ Module functions to determine if the entered text seems to form a complete SQL statement, or if additional input is needed before calling :meth:`~Cursor.execute`. + See :func:`!runsource` in :source:`Lib/sqlite3/__main__.py` + for real-world use. + .. function:: enable_callback_tracebacks(flag, /) Enable or disable callback tracebacks. @@ -382,6 +401,7 @@ Module functions >>> con = sqlite3.connect(":memory:") >>> def evil_trace(stmt): ... 5/0 + ... >>> con.set_trace_callback(evil_trace) >>> def debug(unraisable): ... print(f"{unraisable.exc_value!r} in callback {unraisable.object.__name__}") @@ -394,15 +414,15 @@ Module functions .. function:: register_adapter(type, adapter, /) - Register an *adapter* callable to adapt the Python type *type* into an - SQLite type. + Register an *adapter* :term:`callable` to adapt the Python type *type* + into an SQLite type. The adapter is called with a Python object of type *type* as its sole argument, and must return a value of a :ref:`type that SQLite natively understands <sqlite3-types>`. .. function:: register_converter(typename, converter, /) - Register the *converter* callable to convert SQLite objects of type + Register the *converter* :term:`callable` to convert SQLite objects of type *typename* into a Python object of a specific type. The converter is invoked for all SQLite values of type *typename*; it is passed a :class:`bytes` object and should return an object of the @@ -419,6 +439,12 @@ Module functions Module constants ^^^^^^^^^^^^^^^^ +.. data:: LEGACY_TRANSACTION_CONTROL + + Set :attr:`~Connection.autocommit` to this constant to select + old style (pre-Python 3.12) transaction control behaviour. + See :ref:`sqlite3-transaction-control-isolation-level` for more information. + .. data:: PARSE_COLNAMES Pass this flag value to the *detect_types* parameter of @@ -459,7 +485,7 @@ Module constants SQLITE_DENY SQLITE_IGNORE - Flags that should be returned by the *authorizer_callback* callable + Flags that should be returned by the *authorizer_callback* :term:`callable` passed to :meth:`Connection.set_authorizer`, to indicate whether: * Access is allowed (:const:`!SQLITE_OK`), @@ -533,11 +559,53 @@ Module constants Version number of this module as a :class:`string <str>`. This is not the version of the SQLite library. + .. deprecated-removed:: 3.12 3.14 + This constant used to reflect the version number of the ``pysqlite`` + package, a third-party library which used to upstream changes to + :mod:`!sqlite3`. Today, it carries no meaning or practical value. + .. data:: version_info Version number of this module as a :class:`tuple` of :class:`integers <int>`. This is not the version of the SQLite library. + .. deprecated-removed:: 3.12 3.14 + This constant used to reflect the version number of the ``pysqlite`` + package, a third-party library which used to upstream changes to + :mod:`!sqlite3`. Today, it carries no meaning or practical value. + +.. _sqlite3-dbconfig-constants: + +.. data:: SQLITE_DBCONFIG_DEFENSIVE + SQLITE_DBCONFIG_DQS_DDL + SQLITE_DBCONFIG_DQS_DML + SQLITE_DBCONFIG_ENABLE_FKEY + SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER + SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION + SQLITE_DBCONFIG_ENABLE_QPSG + SQLITE_DBCONFIG_ENABLE_TRIGGER + SQLITE_DBCONFIG_ENABLE_VIEW + SQLITE_DBCONFIG_LEGACY_ALTER_TABLE + SQLITE_DBCONFIG_LEGACY_FILE_FORMAT + SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE + SQLITE_DBCONFIG_RESET_DATABASE + SQLITE_DBCONFIG_TRIGGER_EQP + SQLITE_DBCONFIG_TRUSTED_SCHEMA + SQLITE_DBCONFIG_WRITABLE_SCHEMA + + These constants are used for the :meth:`Connection.setconfig` + and :meth:`~Connection.getconfig` methods. + + The availability of these constants varies depending on the version of SQLite + Python was compiled with. + + .. versionadded:: 3.12 + + .. seealso:: + + https://www.sqlite.org/c3ref/c_dbconfig_defensive.html + SQLite docs: Database Connection Configuration Options + .. _sqlite3-connection-objects: @@ -562,8 +630,8 @@ Connection objects Create and return a :class:`Cursor` object. The cursor method accepts a single optional parameter *factory*. If - supplied, this must be a callable returning an instance of :class:`Cursor` - or its subclasses. + supplied, this must be a :term:`callable` returning + an instance of :class:`Cursor` or its subclasses. .. method:: blobopen(table, column, row, /, *, readonly=False, name="main") @@ -603,18 +671,27 @@ Connection objects .. method:: commit() Commit any pending transaction to the database. - If there is no open transaction, this method is a no-op. + If :attr:`autocommit` is ``True``, or there is no open transaction, + this method does nothing. + If :attr:`!autocommit` is ``False``, a new transaction is implicitly + opened if a pending transaction was committed by this method. .. method:: rollback() Roll back to the start of any pending transaction. - If there is no open transaction, this method is a no-op. + If :attr:`autocommit` is ``True``, or there is no open transaction, + this method does nothing. + If :attr:`!autocommit` is ``False``, a new transaction is implicitly + opened if a pending transaction was rolled back by this method. .. method:: close() Close the database connection. - Any pending transaction is not committed implicitly; - make sure to :meth:`commit` before closing + If :attr:`autocommit` is ``False``, + any pending transaction is implicitly rolled back. + If :attr:`!autocommit` is ``True`` or :data:`LEGACY_TRANSACTION_CONTROL`, + no implicit transaction control is executed. + Make sure to :meth:`commit` before closing to avoid losing pending changes. .. method:: execute(sql, parameters=(), /) @@ -647,7 +724,7 @@ Connection objects If ``-1``, it may take any number of arguments. :param func: - A callable that is called when the SQL function is invoked. + A :term:`callable` that is called when the SQL function is invoked. The callable must return :ref:`a type natively supported by SQLite <sqlite3-types>`. Set to ``None`` to remove an existing SQL function. @@ -678,7 +755,7 @@ Connection objects ('acbd18db4cc2f85cedef654fccc4a4d8',) - .. method:: create_aggregate(name, /, n_arg, aggregate_class) + .. method:: create_aggregate(name, n_arg, aggregate_class) Create or remove a user-defined SQL aggregate function. @@ -818,7 +895,7 @@ Connection objects [('a', 9), ('b', 12), ('c', 16), ('d', 12), ('e', 9)] - .. method:: create_collation(name, callable) + .. method:: create_collation(name, callable, /) Create a collation named *name* using the collating function *callable*. *callable* is passed two :class:`string <str>` arguments, @@ -867,14 +944,15 @@ Connection objects Call this method from a different thread to abort any queries that might be executing on the connection. - Aborted queries will raise an exception. + Aborted queries will raise an :exc:`OperationalError`. .. method:: set_authorizer(authorizer_callback) - Register callable *authorizer_callback* to be invoked for each attempt to - access a column of a table in the database. The callback should return - one of :const:`SQLITE_OK`, :const:`SQLITE_DENY`, or :const:`SQLITE_IGNORE` + Register :term:`callable` *authorizer_callback* to be invoked + for each attempt to access a column of a table in the database. + The callback should return one of :const:`SQLITE_OK`, + :const:`SQLITE_DENY`, or :const:`SQLITE_IGNORE` to signal how access to the column should be handled by the underlying SQLite library. @@ -897,7 +975,7 @@ Connection objects .. method:: set_progress_handler(progress_handler, n) - Register callable *progress_handler* to be invoked for every *n* + Register :term:`callable` *progress_handler* to be invoked for every *n* instructions of the SQLite virtual machine. This is useful if you want to get called from SQLite during long-running operations, for example to update a GUI. @@ -906,14 +984,14 @@ Connection objects method with ``None`` for *progress_handler*. Returning a non-zero value from the handler function will terminate the - currently executing query and cause it to raise an :exc:`OperationalError` + currently executing query and cause it to raise a :exc:`DatabaseError` exception. .. method:: set_trace_callback(trace_callback) - Register callable *trace_callback* to be invoked for each SQL statement - that is actually executed by the SQLite backend. + Register :term:`callable` *trace_callback* to be invoked + for each SQL statement that is actually executed by the SQLite backend. The only argument passed to the callback is the statement (as :class:`str`) that is being executed. The return value of the callback is @@ -997,12 +1075,25 @@ Connection objects (2, 'broccoli pie', 'broccoli cheese onions flour') (3, 'pumpkin pie', 'pumpkin sugar flour butter') - .. method:: load_extension(path, /) + .. method:: load_extension(path, /, *, entrypoint=None) - Load an SQLite extension from a shared library located at *path*. + Load an SQLite extension from a shared library. Enable extension loading with :meth:`enable_load_extension` before calling this method. + :param str path: + + The path to the SQLite extension. + + :param entrypoint: + + Entry point name. + If ``None`` (the default), + SQLite will come up with an entry point name of its own; + see the SQLite docs `Loading an Extension`_ for details. + + :type entrypoint: str | None + .. audit-event:: sqlite3.load_extension connection,path sqlite3.Connection.load_extension .. versionadded:: 3.2 @@ -1010,6 +1101,11 @@ Connection objects .. versionchanged:: 3.10 Added the ``sqlite3.load_extension`` auditing event. + .. versionadded:: 3.12 + The *entrypoint* parameter. + + .. _Loading an Extension: https://www.sqlite.org/loadext.html#loading_an_extension_ + .. method:: iterdump Return an :term:`iterator` to dump the database as SQL source code. @@ -1035,7 +1131,7 @@ Connection objects Works even if the database is being accessed by other clients or concurrently by the same connection. - :param Connection target: + :param ~sqlite3.Connection target: The database connection to save the backup to. :param int pages: @@ -1045,8 +1141,8 @@ Connection objects Defaults to ``-1``. :param progress: - If set to a callable, it is invoked with three integer arguments for - every backup iteration: + If set to a :term:`callable`, + it is invoked with three integer arguments for every backup iteration: the *status* of the last iteration, the *remaining* number of pages still to be copied, and the *total* number of pages. @@ -1157,6 +1253,30 @@ Connection objects .. _SQLite limit category: https://www.sqlite.org/c3ref/c_limit_attached.html + .. method:: getconfig(op, /) + + Query a boolean connection configuration option. + + :param int op: + A :ref:`SQLITE_DBCONFIG code <sqlite3-dbconfig-constants>`. + + :rtype: bool + + .. versionadded:: 3.12 + + .. method:: setconfig(op, enable=True, /) + + Set a boolean connection configuration option. + + :param int op: + A :ref:`SQLITE_DBCONFIG code <sqlite3-dbconfig-constants>`. + + :param bool enable: + ``True`` if the configuration option should be enabled (default); + ``False`` if it should be disabled. + + .. versionadded:: 3.12 + .. method:: serialize(*, name="main") Serialize a database into a :class:`bytes` object. For an @@ -1211,6 +1331,38 @@ Connection objects .. versionadded:: 3.11 + .. attribute:: autocommit + + This attribute controls :pep:`249`-compliant transaction behaviour. + :attr:`!autocommit` has three allowed values: + + * ``False``: Select :pep:`249`-compliant transaction behaviour, + implying that :mod:`!sqlite3` ensures a transaction is always open. + Use :meth:`commit` and :meth:`rollback` to close transactions. + + This is the recommended value of :attr:`!autocommit`. + + * ``True``: Use SQLite's `autocommit mode`_. + :meth:`commit` and :meth:`rollback` have no effect in this mode. + + * :data:`LEGACY_TRANSACTION_CONTROL`: + Pre-Python 3.12 (non-:pep:`249`-compliant) transaction control. + See :attr:`isolation_level` for more details. + + This is currently the default value of :attr:`!autocommit`. + + Changing :attr:`!autocommit` to ``False`` will open a new transaction, + and changing it to ``True`` will commit any pending transaction. + + See :ref:`sqlite3-transaction-control-autocommit` for more details. + + .. note:: + + The :attr:`isolation_level` attribute has no effect unless + :attr:`autocommit` is :data:`LEGACY_TRANSACTION_CONTROL`. + + .. versionadded:: 3.12 + .. attribute:: in_transaction This read-only attribute corresponds to the low-level SQLite @@ -1223,17 +1375,24 @@ Connection objects .. attribute:: isolation_level - This attribute controls the :ref:`transaction handling - <sqlite3-controlling-transactions>` performed by :mod:`!sqlite3`. + Controls the :ref:`legacy transaction handling mode + <sqlite3-transaction-control-isolation-level>` of :mod:`!sqlite3`. If set to ``None``, transactions are never implicitly opened. If set to one of ``"DEFERRED"``, ``"IMMEDIATE"``, or ``"EXCLUSIVE"``, corresponding to the underlying `SQLite transaction behaviour`_, - implicit :ref:`transaction management - <sqlite3-controlling-transactions>` is performed. + :ref:`implicit transaction management + <sqlite3-transaction-control-isolation-level>` is performed. If not overridden by the *isolation_level* parameter of :func:`connect`, the default is ``""``, which is an alias for ``"DEFERRED"``. + .. note:: + + Using :attr:`autocommit` to control transaction handling is + recommended over using :attr:`!isolation_level`. + :attr:`!isolation_level` has no effect unless :attr:`autocommit` is + set to :data:`LEGACY_TRANSACTION_CONTROL` (the default). + .. attribute:: row_factory The initial :attr:`~Cursor.row_factory` @@ -1247,8 +1406,8 @@ Connection objects .. attribute:: text_factory - A callable that accepts a :class:`bytes` parameter and returns a text - representation of it. + A :term:`callable` that accepts a :class:`bytes` parameter + and returns a text representation of it. The callable is invoked for SQLite values with the ``TEXT`` data type. By default, this attribute is set to :class:`str`. If you want to return ``bytes`` instead, set *text_factory* to ``bytes``. @@ -1335,30 +1494,61 @@ Cursor objects .. method:: execute(sql, parameters=(), /) - Execute SQL statement *sql*. - Bind values to the statement using :ref:`placeholders - <sqlite3-placeholders>` that map to the :term:`sequence` or :class:`dict` - *parameters*. + Execute SQL a single SQL statement, + optionally binding Python values using + :ref:`placeholders <sqlite3-placeholders>`. + + :param str sql: + A single SQL statement. - :meth:`execute` will only execute a single SQL statement. If you try to execute - more than one statement with it, it will raise a :exc:`ProgrammingError`. Use - :meth:`executescript` if you want to execute multiple SQL statements with one - call. + :param parameters: + Python values to bind to placeholders in *sql*. + A :class:`!dict` if named placeholders are used. + A :term:`!sequence` if unnamed placeholders are used. + See :ref:`sqlite3-placeholders`. + :type parameters: :class:`dict` | :term:`sequence` - If :attr:`~Connection.isolation_level` is not ``None``, + :raises ProgrammingError: + If *sql* contains more than one SQL statement. + + If :attr:`~Connection.autocommit` is + :data:`LEGACY_TRANSACTION_CONTROL`, + :attr:`~Connection.isolation_level` is not ``None``, *sql* is an ``INSERT``, ``UPDATE``, ``DELETE``, or ``REPLACE`` statement, and there is no open transaction, a transaction is implicitly opened before executing *sql*. + .. deprecated-removed:: 3.12 3.14 + + :exc:`DeprecationWarning` is emitted if + :ref:`named placeholders <sqlite3-placeholders>` are used + and *parameters* is a sequence instead of a :class:`dict`. + Starting with Python 3.14, :exc:`ProgrammingError` will + be raised instead. + + Use :meth:`executescript` to execute multiple SQL statements. .. method:: executemany(sql, parameters, /) - Execute :ref:`parameterized <sqlite3-placeholders>` SQL statement *sql* - against all parameter sequences or mappings found in the sequence - *parameters*. It is also possible to use an - :term:`iterator` yielding parameters instead of a sequence. + For every item in *parameters*, + repeatedly execute the :ref:`parameterized <sqlite3-placeholders>` + :abbr:`DML (Data Manipulation Language)` SQL statement *sql*. + Uses the same implicit transaction handling as :meth:`~Cursor.execute`. + :param str sql: + A single SQL DML statement. + + :param parameters: + An :term:`!iterable` of parameters to bind with + the placeholders in *sql*. + See :ref:`sqlite3-placeholders`. + :type parameters: :term:`iterable` + + :raises ProgrammingError: + If *sql* contains more than one SQL statement, + or is not a DML statement. + Example: .. testcode:: sqlite3.cursor @@ -1370,10 +1560,28 @@ Cursor objects # cur is an sqlite3.Cursor object cur.executemany("INSERT INTO data VALUES(?)", rows) + .. note:: + + Any resulting rows are discarded, + including DML statements with `RETURNING clauses`_. + + .. _RETURNING clauses: https://www.sqlite.org/lang_returning.html + + .. deprecated-removed:: 3.12 3.14 + + :exc:`DeprecationWarning` is emitted if + :ref:`named placeholders <sqlite3-placeholders>` are used + and the items in *parameters* are sequences + instead of :class:`dict`\s. + Starting with Python 3.14, :exc:`ProgrammingError` will + be raised instead. + .. method:: executescript(sql_script, /) Execute the SQL statements in *sql_script*. - If there is a pending transaction, + If the :attr:`~Connection.autocommit` is + :data:`LEGACY_TRANSACTION_CONTROL` + and there is a pending transaction, an implicit ``COMMIT`` statement is executed first. No other implicit transaction control is performed; any transaction control must be added to *sql_script*. @@ -1488,7 +1696,10 @@ Cursor objects ``INSERT``, ``UPDATE``, ``DELETE``, and ``REPLACE`` statements; is ``-1`` for other statements, including :abbr:`CTE (Common Table Expression)` queries. - It is only updated by the :meth:`execute` and :meth:`executemany` methods. + It is only updated by the :meth:`execute` and :meth:`executemany` methods, + after the statement has run to completion. + This means that any resulting rows must be fetched in order for + :attr:`!rowcount` to be updated. .. attribute:: row_factory @@ -1610,9 +1821,9 @@ Blob objects .. method:: seek(offset, origin=os.SEEK_SET, /) Set the current access position of the blob to *offset*. The *origin* - argument defaults to :data:`os.SEEK_SET` (absolute blob positioning). - Other values for *origin* are :data:`os.SEEK_CUR` (seek relative to the - current position) and :data:`os.SEEK_END` (seek relative to the blob’s + argument defaults to :const:`os.SEEK_SET` (absolute blob positioning). + Other values for *origin* are :const:`os.SEEK_CUR` (seek relative to the + current position) and :const:`os.SEEK_END` (seek relative to the blob’s end). @@ -1770,27 +1981,26 @@ Python types via :ref:`converters <sqlite3-converters>`. .. _sqlite3-default-converters: -Default adapters and converters -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Default adapters and converters (deprecated) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -There are default adapters for the date and datetime types in the datetime -module. They will be sent as ISO dates/ISO timestamps to SQLite. - -The default converters are registered under the name "date" for -:class:`datetime.date` and under the name "timestamp" for -:class:`datetime.datetime`. - -This way, you can use date/timestamps from Python without any additional -fiddling in most cases. The format of the adapters is also compatible with the -experimental SQLite date/time functions. +.. note:: -The following example demonstrates this. + The default adapters and converters are deprecated as of Python 3.12. + Instead, use the :ref:`sqlite3-adapter-converter-recipes` + and tailor them to your needs. -.. literalinclude:: ../includes/sqlite3/pysqlite_datetime.py +The deprecated default adapters and converters consist of: -If a timestamp stored in SQLite has a fractional part longer than 6 -numbers, its value will be truncated to microsecond precision by the -timestamp converter. +* An adapter for :class:`datetime.date` objects to :class:`strings <str>` in + `ISO 8601`_ format. +* An adapter for :class:`datetime.datetime` objects to strings in + ISO 8601 format. +* A converter for :ref:`declared <sqlite3-converters>` "date" types to + :class:`datetime.date` objects. +* A converter for declared "timestamp" types to + :class:`datetime.datetime` objects. + Fractional parts will be truncated to 6 digits (microsecond precision). .. note:: @@ -1799,6 +2009,37 @@ timestamp converter. offsets in timestamps, either leave converters disabled, or register an offset-aware converter with :func:`register_converter`. +.. deprecated:: 3.12 + +.. _ISO 8601: https://en.wikipedia.org/wiki/ISO_8601 + + +.. _sqlite3-cli: + +Command-line interface +^^^^^^^^^^^^^^^^^^^^^^ + +The :mod:`!sqlite3` module can be invoked as a script, +using the interpreter's :option:`-m` switch, +in order to provide a simple SQLite shell. +The argument signature is as follows:: + + python -m sqlite3 [-h] [-v] [filename] [sql] + +Type ``.quit`` or CTRL-D to exit the shell. + +.. program:: python -m sqlite3 [-h] [-v] [filename] [sql] + +.. option:: -h, --help + + Print CLI help. + +.. option:: -v, --version + + Print underlying SQLite library version. + +.. versionadded:: 3.12 + .. _sqlite3-howtos: @@ -1833,7 +2074,7 @@ question marks (qmark style) or named placeholders (named style). For the qmark style, *parameters* must be a :term:`sequence` whose length must match the number of placeholders, or a :exc:`ProgrammingError` is raised. -For the named style, *parameters* should be +For the named style, *parameters* must be an instance of a :class:`dict` (or a subclass), which must contain keys for all named parameters; any extra items are ignored. @@ -2093,7 +2334,7 @@ This section shows recipes for common adapters and converters. assert convert_datetime(b"2019-05-18T15:17:08.123456") == dt # Using current time as fromtimestamp() returns local date/time. - # Droping microseconds as adapt_datetime_epoch truncates fractional second part. + # Dropping microseconds as adapt_datetime_epoch truncates fractional second part. now = datetime.datetime.now().replace(microsecond=0) current_timestamp = int(now.timestamp()) @@ -2157,9 +2398,12 @@ the transaction is committed. If this commit fails, or if the body of the ``with`` statement raises an uncaught exception, the transaction is rolled back. +If :attr:`~Connection.autocommit` is ``False``, +a new transaction is implicitly opened after committing or rolling back. If there is no open transaction upon leaving the body of the ``with`` statement, -the context manager is a no-op. +or if :attr:`~Connection.autocommit` is ``True``, +the context manager does nothing. .. note:: @@ -2279,6 +2523,13 @@ Queries now return :class:`!Row` objects: >>> row["RADIUS"] # Column names are case-insensitive. 6378 +.. note:: + + The ``FROM`` clause can be omitted in the ``SELECT`` statement, as in the + above example. In such cases, SQLite returns a single row with columns + defined by expressions, e.g. literals, with the given aliases + ``expr AS alias``. + You can create a custom :attr:`~Cursor.row_factory` that returns each row as a :class:`dict`, with column names mapped to values: @@ -2334,13 +2585,72 @@ instead of a :class:`~collections.namedtuple`. Explanation ----------- +.. _sqlite3-transaction-control: .. _sqlite3-controlling-transactions: Transaction control ^^^^^^^^^^^^^^^^^^^ -The :mod:`!sqlite3` module does not adhere to the transaction handling recommended -by :pep:`249`. +:mod:`!sqlite3` offers multiple methods of controlling whether, +when and how database transactions are opened and closed. +:ref:`sqlite3-transaction-control-autocommit` is recommended, +while :ref:`sqlite3-transaction-control-isolation-level` +retains the pre-Python 3.12 behaviour. + +.. _sqlite3-transaction-control-autocommit: + +Transaction control via the ``autocommit`` attribute +"""""""""""""""""""""""""""""""""""""""""""""""""""" + +The recommended way of controlling transaction behaviour is through +the :attr:`Connection.autocommit` attribute, +which should preferably be set using the *autocommit* parameter +of :func:`connect`. + +It is suggested to set *autocommit* to ``False``, +which implies :pep:`249`-compliant transaction control. +This means: + +* :mod:`!sqlite3` ensures that a transaction is always open, + so :func:`connect`, :meth:`Connection.commit`, and :meth:`Connection.rollback` + will implicitly open a new transaction + (immediately after closing the pending one, for the latter two). + :mod:`!sqlite3` uses ``BEGIN DEFERRED`` statements when opening transactions. +* Transactions should be committed explicitly using :meth:`!commit`. +* Transactions should be rolled back explicitly using :meth:`!rollback`. +* An implicit rollback is performed if the database is + :meth:`~Connection.close`-ed with pending changes. + +Set *autocommit* to ``True`` to enable SQLite's `autocommit mode`_. +In this mode, :meth:`Connection.commit` and :meth:`Connection.rollback` +have no effect. +Note that SQLite's autocommit mode is distinct from +the :pep:`249`-compliant :attr:`Connection.autocommit` attribute; +use :attr:`Connection.in_transaction` to query +the low-level SQLite autocommit mode. + +Set *autocommit* to :data:`LEGACY_TRANSACTION_CONTROL` +to leave transaction control behaviour to the +:attr:`Connection.isolation_level` attribute. +See :ref:`sqlite3-transaction-control-isolation-level` for more information. + + +.. _sqlite3-transaction-control-isolation-level: + +Transaction control via the ``isolation_level`` attribute +""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +.. note:: + + The recommended way of controlling transactions is via the + :attr:`~Connection.autocommit` attribute. + See :ref:`sqlite3-transaction-control-autocommit`. + +If :attr:`Connection.autocommit` is set to +:data:`LEGACY_TRANSACTION_CONTROL` (the default), +transaction behaviour is controlled using +the :attr:`Connection.isolation_level` attribute. +Otherwise, :attr:`!isolation_level` has no effect. If the connection attribute :attr:`~Connection.isolation_level` is not ``None``, @@ -2371,6 +2681,10 @@ regardless of the value of :attr:`~Connection.isolation_level`. :mod:`!sqlite3` used to implicitly commit an open transaction before DDL statements. This is no longer the case. +.. versionchanged:: 3.12 + The recommended way of controlling transactions is now via the + :attr:`~Connection.autocommit` attribute. + .. _autocommit mode: https://www.sqlite.org/lang_transaction.html#implicit_versus_explicit_transactions diff --git a/Doc/library/ssl.rst b/Doc/library/ssl.rst index 372b1243..5d6bc829 100644 --- a/Doc/library/ssl.rst +++ b/Doc/library/ssl.rst @@ -74,13 +74,10 @@ Functions, Constants, and Exceptions Socket creation ^^^^^^^^^^^^^^^ -Since Python 3.2 and 2.7.9, it is recommended to use the -:meth:`SSLContext.wrap_socket` of an :class:`SSLContext` instance to wrap -sockets as :class:`SSLSocket` objects. The helper functions +Instances of :class:`SSLSocket` must be created using the +:meth:`SSLContext.wrap_socket` method. The helper function :func:`create_default_context` returns a new context with secure default -settings. The old :func:`wrap_socket` function is deprecated since it is -both inefficient and has no support for server name indication (SNI) and -hostname matching. +settings. Client socket example with default context and IPv4/IPv6 dual stack:: @@ -142,7 +139,7 @@ purposes. The settings are: :data:`PROTOCOL_TLS_CLIENT` or :data:`PROTOCOL_TLS_SERVER`, :data:`OP_NO_SSLv2`, and :data:`OP_NO_SSLv3` with high encryption cipher suites without RC4 and - without unauthenticated cipher suites. Passing :data:`~Purpose.SERVER_AUTH` + without unauthenticated cipher suites. Passing :const:`~Purpose.SERVER_AUTH` as *purpose* sets :data:`~SSLContext.verify_mode` to :data:`CERT_REQUIRED` and either loads CA certificates (when at least one of *cafile*, *capath* or *cadata* is given) or uses :meth:`SSLContext.load_default_certs` to load @@ -312,27 +309,6 @@ Random generation .. versionadded:: 3.3 -.. function:: RAND_pseudo_bytes(num) - - Return (bytes, is_cryptographic): bytes are *num* pseudo-random bytes, - is_cryptographic is ``True`` if the bytes generated are cryptographically - strong. Raises an :class:`SSLError` if the operation is not supported by the - current RAND method. - - Generated pseudo-random byte sequences will be unique if they are of - sufficient length, but are not necessarily unpredictable. They can be used - for non-cryptographic purposes and for certain purposes in cryptographic - protocols, but usually not for key generation etc. - - For almost all applications :func:`os.urandom` is preferable. - - .. versionadded:: 3.3 - - .. deprecated:: 3.6 - - OpenSSL has deprecated :func:`ssl.RAND_pseudo_bytes`, use - :func:`ssl.RAND_bytes` instead. - .. function:: RAND_status() Return ``True`` if the SSL pseudo-random number generator has been seeded @@ -344,7 +320,7 @@ Random generation Mix the given *bytes* into the SSL pseudo-random number generator. The parameter *entropy* (a float) is a lower bound on the entropy contained in - string (so you can always use :const:`0.0`). See :rfc:`1750` for more + string (so you can always use ``0.0``). See :rfc:`1750` for more information on sources of entropy. .. versionchanged:: 3.5 @@ -357,49 +333,6 @@ Certificate handling import ssl -.. function:: match_hostname(cert, hostname) - - Verify that *cert* (in decoded format as returned by - :meth:`SSLSocket.getpeercert`) matches the given *hostname*. The rules - applied are those for checking the identity of HTTPS servers as outlined - in :rfc:`2818`, :rfc:`5280` and :rfc:`6125`. In addition to HTTPS, this - function should be suitable for checking the identity of servers in - various SSL-based protocols such as FTPS, IMAPS, POPS and others. - - :exc:`CertificateError` is raised on failure. On success, the function - returns nothing:: - - >>> cert = {'subject': ((('commonName', 'example.com'),),)} - >>> ssl.match_hostname(cert, "example.com") - >>> ssl.match_hostname(cert, "example.org") - Traceback (most recent call last): - File "<stdin>", line 1, in <module> - File "/home/py3k/Lib/ssl.py", line 130, in match_hostname - ssl.CertificateError: hostname 'example.org' doesn't match 'example.com' - - .. versionadded:: 3.2 - - .. versionchanged:: 3.3.3 - The function now follows :rfc:`6125`, section 6.4.3 and does neither - match multiple wildcards (e.g. ``*.*.com`` or ``*a*.example.org``) nor - a wildcard inside an internationalized domain names (IDN) fragment. - IDN A-labels such as ``www*.xn--pthon-kva.org`` are still supported, - but ``x*.python.org`` no longer matches ``xn--tda.python.org``. - - .. versionchanged:: 3.5 - Matching of IP addresses, when present in the subjectAltName field - of the certificate, is now supported. - - .. versionchanged:: 3.7 - The function is no longer used to TLS connections. Hostname matching - is now performed by OpenSSL. - - Allow wildcard when it is the leftmost and the only character - in that segment. Partial wildcards like ``www*.example.com`` are no - longer supported. - - .. deprecated:: 3.7 - .. function:: cert_time_to_seconds(cert_time) Return the time in seconds since the Epoch, given the ``cert_time`` @@ -433,10 +366,10 @@ Certificate handling Given the address ``addr`` of an SSL-protected server, as a (*hostname*, *port-number*) pair, fetches the server's certificate, and returns it as a PEM-encoded string. If ``ssl_version`` is specified, uses that version of - the SSL protocol to attempt to connect to the server. If ``ca_certs`` is + the SSL protocol to attempt to connect to the server. If *ca_certs* is specified, it should be a file containing a list of root certificates, the - same format as used for the same parameter in - :meth:`SSLContext.wrap_socket`. The call will attempt to validate the + same format as used for the *cafile* parameter in + :meth:`SSLContext.load_verify_locations`. The call will attempt to validate the server certificate against that set of root certificates, and will fail if the validation attempt fails. A timeout can be specified with the ``timeout`` parameter. @@ -515,33 +448,6 @@ Certificate handling .. versionadded:: 3.4 -.. function:: wrap_socket(sock, keyfile=None, certfile=None, \ - server_side=False, cert_reqs=CERT_NONE, ssl_version=PROTOCOL_TLS, \ - ca_certs=None, do_handshake_on_connect=True, \ - suppress_ragged_eofs=True, ciphers=None) - - Takes an instance ``sock`` of :class:`socket.socket`, and returns an instance - of :class:`ssl.SSLSocket`, a subtype of :class:`socket.socket`, which wraps - the underlying socket in an SSL context. ``sock`` must be a - :data:`~socket.SOCK_STREAM` socket; other socket types are unsupported. - - Internally, function creates a :class:`SSLContext` with protocol - *ssl_version* and :attr:`SSLContext.options` set to *cert_reqs*. If - parameters *keyfile*, *certfile*, *ca_certs* or *ciphers* are set, then - the values are passed to :meth:`SSLContext.load_cert_chain`, - :meth:`SSLContext.load_verify_locations`, and - :meth:`SSLContext.set_ciphers`. - - The arguments *server_side*, *do_handshake_on_connect*, and - *suppress_ragged_eofs* have the same meaning as - :meth:`SSLContext.wrap_socket`. - - .. deprecated:: 3.7 - - Since Python 3.2 and 2.7.9, it is recommended to use the - :meth:`SSLContext.wrap_socket` instead of :func:`wrap_socket`. The - top-level function is limited and creates an insecure client socket - without server name indication or hostname matching. Constants ^^^^^^^^^ @@ -552,8 +458,8 @@ Constants .. data:: CERT_NONE - Possible value for :attr:`SSLContext.verify_mode`, or the ``cert_reqs`` - parameter to :func:`wrap_socket`. Except for :const:`PROTOCOL_TLS_CLIENT`, + Possible value for :attr:`SSLContext.verify_mode`. + Except for :const:`PROTOCOL_TLS_CLIENT`, it is the default mode. With client-side sockets, just about any cert is accepted. Validation errors, such as untrusted or expired cert, are ignored and do not abort the TLS/SSL handshake. @@ -565,8 +471,8 @@ Constants .. data:: CERT_OPTIONAL - Possible value for :attr:`SSLContext.verify_mode`, or the ``cert_reqs`` - parameter to :func:`wrap_socket`. In client mode, :const:`CERT_OPTIONAL` + Possible value for :attr:`SSLContext.verify_mode`. + In client mode, :const:`CERT_OPTIONAL` has the same meaning as :const:`CERT_REQUIRED`. It is recommended to use :const:`CERT_REQUIRED` for client-side sockets instead. @@ -577,13 +483,12 @@ Constants the TLS handshake. Use of this setting requires a valid set of CA certificates to - be passed, either to :meth:`SSLContext.load_verify_locations` or as a - value of the ``ca_certs`` parameter to :func:`wrap_socket`. + be passed to :meth:`SSLContext.load_verify_locations`. .. data:: CERT_REQUIRED - Possible value for :attr:`SSLContext.verify_mode`, or the ``cert_reqs`` - parameter to :func:`wrap_socket`. In this mode, certificates are + Possible value for :attr:`SSLContext.verify_mode`. + In this mode, certificates are required from the other side of the socket connection; an :class:`SSLError` will be raised if no certificate is provided, or if its validation fails. This mode is **not** sufficient to verify a certificate in client mode as @@ -597,8 +502,7 @@ Constants the client must provide a valid and trusted certificate. Use of this setting requires a valid set of CA certificates to - be passed, either to :meth:`SSLContext.load_verify_locations` or as a - value of the ``ca_certs`` parameter to :func:`wrap_socket`. + be passed to :meth:`SSLContext.load_verify_locations`. .. class:: VerifyMode @@ -707,21 +611,6 @@ Constants Use :data:`PROTOCOL_TLS` instead. -.. data:: PROTOCOL_SSLv2 - - Selects SSL version 2 as the channel encryption protocol. - - This protocol is not available if OpenSSL is compiled with the - ``no-ssl2`` option. - - .. warning:: - - SSL version 2 is insecure. Its use is highly discouraged. - - .. deprecated:: 3.6 - - OpenSSL has removed support for SSLv2. - .. data:: PROTOCOL_SSLv3 Selects SSL version 3 as the channel encryption protocol. @@ -918,6 +807,29 @@ Constants .. versionadded:: 3.10 +.. data:: OP_ENABLE_KTLS + + Enable the use of the kernel TLS. To benefit from the feature, OpenSSL must + have been compiled with support for it, and the negotiated cipher suites and + extensions must be supported by it (a list of supported ones may vary by + platform and kernel version). + + Note that with enabled kernel TLS some cryptographic operations are + performed by the kernel directly and not via any available OpenSSL + Providers. This might be undesirable if, for example, the application + requires all cryptographic operations to be performed by the FIPS provider. + + This option is only available with OpenSSL 3.0.0 and later. + + .. versionadded:: 3.12 + +.. data:: OP_LEGACY_SERVER_CONNECT + + Allow legacy insecure renegotiation between OpenSSL and unpatched servers + only. + + .. versionadded:: 3.12 + .. data:: HAS_ALPN Whether the OpenSSL library has built-in support for the *Application-Layer @@ -1270,11 +1182,6 @@ SSL sockets also have the following additional methods and attributes: 'subjectAltName': (('DNS', '*.eff.org'), ('DNS', 'eff.org')), 'version': 3} - .. note:: - - To validate a certificate for a particular service, you can use the - :func:`match_hostname` function. - If the ``binary_form`` parameter is :const:`True`, and a certificate was provided, this method returns the DER-encoded form of the entire certificate as a sequence of bytes, or :const:`None` if the peer did not provide a @@ -1289,6 +1196,8 @@ SSL sockets also have the following additional methods and attributes: :const:`None` if you used :const:`CERT_NONE` (rather than :const:`CERT_OPTIONAL` or :const:`CERT_REQUIRED`). + See also :attr:`SSLContext.check_hostname`. + .. versionchanged:: 3.2 The returned dictionary includes additional items such as ``issuer`` and ``notBefore``. @@ -1309,7 +1218,7 @@ SSL sockets also have the following additional methods and attributes: .. method:: SSLSocket.shared_ciphers() - Return the list of ciphers shared by the client during the handshake. Each + Return the list of ciphers available in both the client and server. Each entry of the returned list is a three-value tuple containing the name of the cipher, the version of the SSL protocol that defines its use, and the number of secret bits the cipher uses. :meth:`~SSLSocket.shared_ciphers` returns @@ -1409,10 +1318,7 @@ SSL sockets also have the following additional methods and attributes: .. attribute:: SSLSocket.context - The :class:`SSLContext` object this SSL socket is tied to. If the SSL - socket was created using the deprecated :func:`wrap_socket` function - (rather than :meth:`SSLContext.wrap_socket`), this is a custom context - object created for this SSL socket. + The :class:`SSLContext` object this SSL socket is tied to. .. versionadded:: 3.2 @@ -1503,11 +1409,10 @@ to speed up repeated connections from the same clients. The context is created with secure default values. The options :data:`OP_NO_COMPRESSION`, :data:`OP_CIPHER_SERVER_PREFERENCE`, :data:`OP_SINGLE_DH_USE`, :data:`OP_SINGLE_ECDH_USE`, - :data:`OP_NO_SSLv2` (except for :data:`PROTOCOL_SSLv2`), + :data:`OP_NO_SSLv2`, and :data:`OP_NO_SSLv3` (except for :data:`PROTOCOL_SSLv3`) are set by default. The initial cipher suite list contains only ``HIGH`` - ciphers, no ``NULL`` ciphers and no ``MD5`` ciphers (except for - :data:`PROTOCOL_SSLv2`). + ciphers, no ``NULL`` ciphers and no ``MD5`` ciphers. .. deprecated:: 3.10 @@ -1579,9 +1484,9 @@ to speed up repeated connections from the same clients. load CA certificates from other locations, too. The *purpose* flag specifies what kind of CA certificates are loaded. The - default settings :data:`Purpose.SERVER_AUTH` loads certificates, that are + default settings :const:`Purpose.SERVER_AUTH` loads certificates, that are flagged and trusted for TLS web server authentication (client side - sockets). :data:`Purpose.CLIENT_AUTH` loads CA certificates for client + sockets). :const:`Purpose.CLIENT_AUTH` loads CA certificates for client certificate verification on the server side. .. versionadded:: 3.4 @@ -1814,7 +1719,7 @@ to speed up repeated connections from the same clients. .. versionadded:: 3.3 .. seealso:: - `SSL/TLS & Perfect Forward Secrecy <https://vincent.bernat.im/en/blog/2011-ssl-perfect-forward-secrecy>`_ + `SSL/TLS & Perfect Forward Secrecy <https://vincent.bernat.ch/en/blog/2011-ssl-perfect-forward-secrecy>`_ Vincent Bernat. .. method:: SSLContext.wrap_socket(sock, server_side=False, \ @@ -1824,7 +1729,7 @@ to speed up repeated connections from the same clients. Wrap an existing Python socket *sock* and return an instance of :attr:`SSLContext.sslsocket_class` (default :class:`SSLSocket`). The returned SSL socket is tied to the context, its settings and certificates. - *sock* must be a :data:`~socket.SOCK_STREAM` socket; other + *sock* must be a :const:`~socket.SOCK_STREAM` socket; other socket types are unsupported. The parameter ``server_side`` is a boolean which identifies whether @@ -2169,7 +2074,7 @@ Combined key and certificate Often the private key is stored in the same file as the certificate; in this case, only the ``certfile`` parameter to :meth:`SSLContext.load_cert_chain` -and :func:`wrap_socket` needs to be passed. If the private key is stored +needs to be passed. If the private key is stored with the certificate, it should come before the first certificate in the certificate chain:: @@ -2658,10 +2563,9 @@ Therefore, when in client mode, it is highly recommended to use :const:`CERT_REQUIRED`. However, it is in itself not sufficient; you also have to check that the server certificate, which can be obtained by calling :meth:`SSLSocket.getpeercert`, matches the desired service. For many -protocols and applications, the service can be identified by the hostname; -in this case, the :func:`match_hostname` function can be used. This common -check is automatically performed when :attr:`SSLContext.check_hostname` is -enabled. +protocols and applications, the service can be identified by the hostname. +This common check is automatically performed when +:attr:`SSLContext.check_hostname` is enabled. .. versionchanged:: 3.7 Hostname matchings is now performed by OpenSSL. Python no longer uses @@ -2688,7 +2592,7 @@ disabled by default. >>> client_context.maximum_version = ssl.TLSVersion.TLSv1_3 -The SSL context created above will only allow TLSv1.2 and later (if +The SSL context created above will only allow TLSv1.3 and later (if supported by your system) connections to a server. :const:`PROTOCOL_TLS_CLIENT` implies certificate validation and hostname checks by default. You have to load certificates into the context. @@ -2715,8 +2619,8 @@ for example the :mod:`multiprocessing` or :mod:`concurrent.futures` modules), be aware that OpenSSL's internal random number generator does not properly handle forked processes. Applications must change the PRNG state of the parent process if they use any SSL feature with :func:`os.fork`. Any -successful call of :func:`~ssl.RAND_add`, :func:`~ssl.RAND_bytes` or -:func:`~ssl.RAND_pseudo_bytes` is sufficient. +successful call of :func:`~ssl.RAND_add` or :func:`~ssl.RAND_bytes` is +sufficient. .. _ssl-tlsv1_3: diff --git a/Doc/library/stat.rst b/Doc/library/stat.rst index 083dc5e3..77538514 100644 --- a/Doc/library/stat.rst +++ b/Doc/library/stat.rst @@ -13,8 +13,8 @@ The :mod:`stat` module defines constants and functions for interpreting the results of :func:`os.stat`, :func:`os.fstat` and :func:`os.lstat` (if they -exist). For complete details about the :c:func:`stat`, :c:func:`fstat` and -:c:func:`lstat` calls, consult the documentation for your system. +exist). For complete details about the :c:func:`stat`, :c:func:`!fstat` and +:c:func:`!lstat` calls, consult the documentation for your system. .. versionchanged:: 3.4 The stat module is backed by a C implementation. @@ -89,9 +89,9 @@ mode: .. function:: S_IFMT(mode) Return the portion of the file's mode that describes the file type (used by the - :func:`S_IS\*` functions above). + :func:`!S_IS\*` functions above). -Normally, you would use the :func:`os.path.is\*` functions for testing the type +Normally, you would use the :func:`!os.path.is\*` functions for testing the type of a file; the functions here are useful when you are doing multiple tests of the same file and wish to avoid the overhead of the :c:func:`stat` system call for each test. These are also useful when checking for information about a file diff --git a/Doc/library/statistics.rst b/Doc/library/statistics.rst index 78c4bc52..6e6ca7ce 100644 --- a/Doc/library/statistics.rst +++ b/Doc/library/statistics.rst @@ -22,7 +22,7 @@ This module provides functions for calculating mathematical statistics of numeric (:class:`~numbers.Real`-valued) data. The module is not intended to be a competitor to third-party libraries such -as `NumPy <https://numpy.org>`_, `SciPy <https://www.scipy.org/>`_, or +as `NumPy <https://numpy.org>`_, `SciPy <https://scipy.org/>`_, or proprietary full-featured statistics packages aimed at professional statisticians such as Minitab, SAS and Matlab. It is aimed at the level of graphing and scientific calculators. @@ -104,7 +104,7 @@ These functions calculate statistics regarding relations between two inputs. ========================= ===================================================== :func:`covariance` Sample covariance for two variables. -:func:`correlation` Pearson's correlation coefficient for two variables. +:func:`correlation` Pearson and Spearman's correlation coefficients. :func:`linear_regression` Slope and intercept for simple linear regression. ========================= ===================================================== @@ -648,31 +648,57 @@ However, for reading convenience, most of the examples show sorted sequences. .. versionadded:: 3.10 -.. function:: correlation(x, y, /) +.. function:: correlation(x, y, /, *, method='linear') Return the `Pearson's correlation coefficient <https://en.wikipedia.org/wiki/Pearson_correlation_coefficient>`_ for two inputs. Pearson's correlation coefficient *r* takes values - between -1 and +1. It measures the strength and direction of the linear - relationship, where +1 means very strong, positive linear relationship, - -1 very strong, negative linear relationship, and 0 no linear relationship. + between -1 and +1. It measures the strength and direction of a linear + relationship. + + If *method* is "ranked", computes `Spearman's rank correlation coefficient + <https://en.wikipedia.org/wiki/Spearman%27s_rank_correlation_coefficient>`_ + for two inputs. The data is replaced by ranks. Ties are averaged so that + equal values receive the same rank. The resulting coefficient measures the + strength of a monotonic relationship. + + Spearman's correlation coefficient is appropriate for ordinal data or for + continuous data that doesn't meet the linear proportion requirement for + Pearson's correlation coefficient. Both inputs must be of the same length (no less than two), and need not to be constant, otherwise :exc:`StatisticsError` is raised. - Examples: + Example with `Kepler's laws of planetary motion + <https://en.wikipedia.org/wiki/Kepler's_laws_of_planetary_motion>`_: .. doctest:: - >>> x = [1, 2, 3, 4, 5, 6, 7, 8, 9] - >>> y = [9, 8, 7, 6, 5, 4, 3, 2, 1] - >>> correlation(x, x) + >>> # Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, and Neptune + >>> orbital_period = [88, 225, 365, 687, 4331, 10_756, 30_687, 60_190] # days + >>> dist_from_sun = [58, 108, 150, 228, 778, 1_400, 2_900, 4_500] # million km + + >>> # Show that a perfect monotonic relationship exists + >>> correlation(orbital_period, dist_from_sun, method='ranked') + 1.0 + + >>> # Observe that a linear relationship is imperfect + >>> round(correlation(orbital_period, dist_from_sun), 4) + 0.9882 + + >>> # Demonstrate Kepler's third law: There is a linear correlation + >>> # between the square of the orbital period and the cube of the + >>> # distance from the sun. + >>> period_squared = [p * p for p in orbital_period] + >>> dist_cubed = [d * d * d for d in dist_from_sun] + >>> round(correlation(period_squared, dist_cubed), 4) 1.0 - >>> correlation(x, y) - -1.0 .. versionadded:: 3.10 + .. versionchanged:: 3.12 + Added support for Spearman's rank correlation coefficient. + .. function:: linear_regression(x, y, /, *, proportional=False) Return the slope and intercept of `simple linear regression @@ -896,6 +922,10 @@ of applications in statistics. :class:`NormalDist` Examples and Recipes ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Classic probability problems +**************************** + :class:`NormalDist` readily solves classic probability problems. For example, given `historical data for SAT exams @@ -921,6 +951,10 @@ Find the `quartiles <https://en.wikipedia.org/wiki/Quartile>`_ and `deciles >>> list(map(round, sat.quantiles(n=10))) [810, 896, 958, 1011, 1060, 1109, 1162, 1224, 1310] + +Monte Carlo inputs for simulations +********************************** + To estimate the distribution for a model than isn't easy to solve analytically, :class:`NormalDist` can generate input samples for a `Monte Carlo simulation <https://en.wikipedia.org/wiki/Monte_Carlo_method>`_: @@ -937,6 +971,9 @@ Carlo simulation <https://en.wikipedia.org/wiki/Monte_Carlo_method>`_: >>> quantiles(map(model, X, Y, Z)) # doctest: +SKIP [1.4591308524824727, 1.8035946855390597, 2.175091447274739] +Approximating binomial distributions +************************************ + Normal distributions can be used to approximate `Binomial distributions <https://mathworld.wolfram.com/BinomialDistribution.html>`_ when the sample size is large and when the probability of a successful @@ -970,9 +1007,14 @@ probability that the Python room will stay within its capacity limits? >>> seed(8675309) >>> def trial(): ... return choices(('Python', 'Ruby'), (p, q), k=n).count('Python') + ... >>> mean(trial() <= k for i in range(10_000)) 0.8398 + +Naive bayesian classifier +************************* + Normal distributions commonly arise in machine learning problems. Wikipedia has a `nice example of a Naive Bayesian Classifier @@ -1027,6 +1069,48 @@ The final prediction goes to the largest posterior. This is known as the 'female' +Kernel density estimation +************************* + +It is possible to estimate a continuous probability density function +from a fixed number of discrete samples. + +The basic idea is to smooth the data using `a kernel function such as a +normal distribution, triangular distribution, or uniform distribution +<https://en.wikipedia.org/wiki/Kernel_(statistics)#Kernel_functions_in_common_use>`_. +The degree of smoothing is controlled by a single +parameter, ``h``, representing the variance of the kernel function. + +.. testcode:: + + import math + + def kde_normal(sample, h): + "Create a continuous probability density function from a sample." + # Smooth the sample with a normal distribution of variance h. + kernel_h = NormalDist(0.0, math.sqrt(h)).pdf + n = len(sample) + def pdf(x): + return sum(kernel_h(x - x_i) for x_i in sample) / n + return pdf + +`Wikipedia has an example +<https://en.wikipedia.org/wiki/Kernel_density_estimation#Example>`_ +where we can use the ``kde_normal()`` recipe to generate and plot +a probability density function estimated from a small sample: + +.. doctest:: + + >>> sample = [-2.1, -1.3, -0.4, 1.9, 5.1, 6.2] + >>> f_hat = kde_normal(sample, h=2.25) + >>> xarr = [i/100 for i in range(-750, 1100)] + >>> yarr = [f_hat(x) for x in xarr] + +The points in ``xarr`` and ``yarr`` can be used to make a PDF plot: + +.. image:: kde_example.png + :alt: Scatter plot of the estimated probability density function. + .. # This modelines must appear within the last ten lines of the file. kate: indent-width 3; remove-trailing-space on; replace-tabs on; encoding utf-8; diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index 2bc86e97..50f56603 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -32,8 +32,8 @@ Truth Value Testing =================== .. index:: - statement: if - statement: while + pair: statement; if + pair: statement; while pair: truth; value pair: Boolean; operations single: false @@ -44,7 +44,7 @@ Any object can be tested for truth value, for use in an :keyword:`if` or .. index:: single: true By default, an object is considered true unless its class defines either a -:meth:`__bool__` method that returns ``False`` or a :meth:`__len__` method that +:meth:`~object.__bool__` method that returns ``False`` or a :meth:`__len__` method that returns zero, when called with the object. [1]_ Here are most of the built-in objects considered false: @@ -52,7 +52,7 @@ objects considered false: single: None (Built-in object) single: False (Built-in object) -* constants defined to be false: ``None`` and ``False``. +* constants defined to be false: ``None`` and ``False`` * zero of any numeric type: ``0``, ``0.0``, ``0j``, ``Decimal(0)``, ``Fraction(0, 1)`` @@ -61,8 +61,8 @@ objects considered false: ``range(0)`` .. index:: - operator: or - operator: and + pair: operator; or + pair: operator; and single: False single: True @@ -84,8 +84,8 @@ These are the Boolean operations, ordered by ascending priority: +-------------+---------------------------------+-------+ | Operation | Result | Notes | +=============+=================================+=======+ -| ``x or y`` | if *x* is false, then *y*, else | \(1) | -| | *x* | | +| ``x or y`` | if *x* is true, then *x*, else | \(1) | +| | *y* | | +-------------+---------------------------------+-------+ | ``x and y`` | if *x* is false, then *x*, else | \(2) | | | *y* | | @@ -95,9 +95,9 @@ These are the Boolean operations, ordered by ascending priority: +-------------+---------------------------------+-------+ .. index:: - operator: and - operator: or - operator: not + pair: operator; and + pair: operator; or + pair: operator; not Notes: @@ -122,14 +122,14 @@ Comparisons .. index:: pair: chaining; comparisons pair: operator; comparison - operator: == - operator: < (less) - operator: <= - operator: > (greater) - operator: >= - operator: != - operator: is - operator: is not + pair: operator; == + pair: operator; < (less) + pair: operator; <= + pair: operator; > (greater) + pair: operator; >= + pair: operator; != + pair: operator; is + pair: operator; is not There are eight comparison operations in Python. They all have the same priority (which is higher than that of the Boolean operations). Comparisons can @@ -192,8 +192,8 @@ customized; also they can be applied to any two objects and never raise an exception. .. index:: - operator: in - operator: not in + pair: operator; in + pair: operator; not in Two more operations with the same syntactic priority, :keyword:`in` and :keyword:`not in`, are supported by types that are :term:`iterable` or @@ -205,11 +205,11 @@ Numeric Types --- :class:`int`, :class:`float`, :class:`complex` ================================================================ .. index:: - object: numeric - object: Boolean - object: integer - object: floating point - object: complex number + pair: object; numeric + pair: object; Boolean + pair: object; integer + pair: object; floating point + pair: object; complex number pair: C; language There are three distinct numeric types: :dfn:`integers`, :dfn:`floating @@ -244,20 +244,20 @@ and imaginary parts. .. index:: single: arithmetic - builtin: int - builtin: float - builtin: complex + pair: built-in function; int + pair: built-in function; float + pair: built-in function; complex single: operator; + (plus) single: + (plus); unary operator single: + (plus); binary operator single: operator; - (minus) single: - (minus); unary operator single: - (minus); binary operator - operator: * (asterisk) - operator: / (slash) - operator: // - operator: % (percent) - operator: ** + pair: operator; * (asterisk) + pair: operator; / (slash) + pair: operator; // + pair: operator; % (percent) + pair: operator; ** Python fully supports mixed arithmetic: when a binary arithmetic operator has operands of different numeric types, the operand with the "narrower" type is @@ -282,7 +282,7 @@ the operations, see :ref:`operator-summary`): +---------------------+---------------------------------+---------+--------------------+ | ``x / y`` | quotient of *x* and *y* | | | +---------------------+---------------------------------+---------+--------------------+ -| ``x // y`` | floored quotient of *x* and | \(1) | | +| ``x // y`` | floored quotient of *x* and | \(1)\(2)| | | | *y* | | | +---------------------+---------------------------------+---------+--------------------+ | ``x % y`` | remainder of ``x / y`` | \(2) | | @@ -319,8 +319,10 @@ the operations, see :ref:`operator-summary`): Notes: (1) - Also referred to as integer division. The resultant value is a whole - integer, though the result's type is not necessarily int. The result is + Also referred to as integer division. For operands of type :class:`int`, + the result has type :class:`int`. For operands of type :class:`float`, + the result has type :class:`float`. In general, the result is a whole + integer, though the result's type is not necessarily :class:`int`. The result is always rounded towards minus infinity: ``1//2`` is ``0``, ``(-1)//2`` is ``-1``, ``1//(-2)`` is ``-1``, and ``(-1)//(-2)`` is ``0``. @@ -330,16 +332,15 @@ Notes: (3) .. index:: - module: math + pair: module; math single: floor() (in module math) single: ceil() (in module math) single: trunc() (in module math) pair: numeric; conversions - pair: C; language - Conversion from floating point to integer may round or truncate - as in C; see functions :func:`math.floor` and :func:`math.ceil` for - well-defined conversions. + Conversion from :class:`float` to :class:`int` truncates, discarding the + fractional part. See functions :func:`math.floor` and :func:`math.ceil` for + alternative conversions. (4) float also accepts the strings "nan" and "inf" with an optional prefix "+" @@ -353,7 +354,7 @@ Notes: The numeric literals accepted include the digits ``0`` to ``9`` or any Unicode equivalent (code points with the ``Nd`` property). - See https://www.unicode.org/Public/14.0.0/ucd/extracted/DerivedNumericType.txt + See `the Unicode Standard <https://unicode.org/Public/UNIDATA/extracted/DerivedNumericType.txt>`_ for a complete list of code points with the ``Nd`` property. @@ -393,12 +394,12 @@ Bitwise Operations on Integer Types pair: bitwise; operations pair: shifting; operations pair: masking; operations - operator: | (vertical bar) - operator: ^ (caret) - operator: & (ampersand) - operator: << - operator: >> - operator: ~ (tilde) + pair: operator; | (vertical bar) + pair: operator; ^ (caret) + pair: operator; & (ampersand) + pair: operator; << + pair: operator; >> + pair: operator; ~ (tilde) Bitwise operations only make sense for integers. The result of bitwise operations is calculated as though carried out in two's complement with an @@ -530,12 +531,14 @@ class`. In addition, it provides a few more methods: is ``False``. The default values can be used to conveniently turn an integer into a - single byte object. However, when using the default arguments, don't try - to convert a value greater than 255 or you'll get an :exc:`OverflowError`:: + single byte object:: >>> (65).to_bytes() b'A' + However, when using the default arguments, don't try + to convert a value greater than 255 or you'll get an :exc:`OverflowError`. + Equivalent to:: def to_bytes(n, length=1, byteorder='big', signed=False): @@ -602,13 +605,19 @@ class`. In addition, it provides a few more methods: .. method:: int.as_integer_ratio() - Return a pair of integers whose ratio is exactly equal to the original - integer and with a positive denominator. The integer ratio of integers + Return a pair of integers whose ratio is equal to the original + integer and has a positive denominator. The integer ratio of integers (whole numbers) is always the integer as the numerator and ``1`` as the denominator. .. versionadded:: 3.8 +.. method:: int.is_integer() + + Returns ``True``. Exists for duck type compatibility with :meth:`float.is_integer`. + + .. versionadded:: 3.12 + Additional Methods on Float --------------------------- @@ -618,7 +627,7 @@ class`. float also has the following additional methods. .. method:: float.as_integer_ratio() Return a pair of integers whose ratio is exactly equal to the - original float and with a positive denominator. Raises + original float. The ratio is in lowest terms and has a positive denominator. Raises :exc:`OverflowError` on infinities and a :exc:`ValueError` on NaNs. @@ -795,6 +804,39 @@ number, :class:`float`, or :class:`complex`:: hash_value = -2 return hash_value +.. _typebool: + +Boolean Type - :class:`bool` +============================ + +Booleans represent truth values. The :class:`bool` type has exactly two +constant instances: ``True`` and ``False``. + +.. index:: + single: False + single: True + pair: Boolean; values + +The built-in function :func:`bool` converts any value to a boolean, if the +value can be interpreted as a truth value (see section :ref:`truth` above). + +For logical operations, use the :ref:`boolean operators <boolean>` ``and``, +``or`` and ``not``. +When applying the bitwise operators ``&``, ``|``, ``^`` to two booleans, they +return a bool equivalent to the logical operations "and", "or", "xor". However, +the logical operators ``and``, ``or`` and ``!=`` should be preferred +over ``&``, ``|`` and ``^``. + +.. deprecated:: 3.12 + + The use of the bitwise inversion operator ``~`` is deprecated and will + raise an error in Python 3.14. + +:class:`bool` is a subclass of :class:`int` (see :ref:`typesnumeric`). In +many numeric contexts, ``False`` and ``True`` behave like the integers 0 and 1, respectively. +However, relying on this is discouraged; explicitly convert using :func:`int` +instead. + .. _typeiter: Iterator Types @@ -887,7 +929,7 @@ described in dedicated sections. Common Sequence Operations -------------------------- -.. index:: object: sequence +.. index:: pair: object; sequence The operations in the following table are supported by most sequence types, both mutable and immutable. The :class:`collections.abc.Sequence` ABC is @@ -905,15 +947,15 @@ operations have the same priority as the corresponding numeric operations. [3]_ .. index:: triple: operations on; sequence; types - builtin: len - builtin: min - builtin: max + pair: built-in function; len + pair: built-in function; min + pair: built-in function; max pair: concatenation; operation pair: repetition; operation pair: subscript; operation pair: slice; operation - operator: in - operator: not in + pair: operator; in + pair: operator; not in single: count() (sequence method) single: index() (sequence method) @@ -1072,8 +1114,8 @@ Immutable Sequence Types .. index:: triple: immutable; sequence; types - object: tuple - builtin: hash + pair: object; tuple + pair: built-in function; hash The only operation that immutable sequence types generally implement that is not also implemented by mutable sequence types is support for the :func:`hash` @@ -1094,8 +1136,8 @@ Mutable Sequence Types .. index:: triple: mutable; sequence; types - object: list - object: bytearray + pair: object; list + pair: object; bytearray The operations in the following table are defined on mutable sequence types. The :class:`collections.abc.MutableSequence` ABC is provided to make it @@ -1112,7 +1154,7 @@ accepts integers that meet the value restriction ``0 <= x <= 255``). triple: operations on; list; type pair: subscript; assignment pair: slice; assignment - statement: del + pair: statement; del single: append() (sequence method) single: clear() (sequence method) single: copy() (sequence method) @@ -1212,7 +1254,7 @@ Notes: Lists ----- -.. index:: object: list +.. index:: pair: object; list Lists are mutable sequences, typically used to store collections of homogeneous items (where the precise degree of similarity will vary by @@ -1291,7 +1333,7 @@ application). Tuples ------ -.. index:: object: tuple +.. index:: pair: object; tuple Tuples are immutable sequences, typically used to store collections of heterogeneous data (such as the 2-tuples produced by the :func:`enumerate` @@ -1335,7 +1377,7 @@ choice than a simple tuple object. Ranges ------ -.. index:: object: range +.. index:: pair: object; range The :class:`range` type represents an immutable sequence of numbers and is commonly used for looping a specific number of times in :keyword:`for` @@ -1460,7 +1502,7 @@ objects that compare equal might have different :attr:`~range.start`, .. index:: single: string; text sequence type single: str (built-in class); (see also string) - object: string + pair: object; string .. _textseq: @@ -1494,7 +1536,7 @@ Since there is no separate "character" type, indexing a string produces strings of length 1. That is, for a non-empty string *s*, ``s[0] == s[0:1]``. .. index:: - object: io.StringIO + pair: object; io.StringIO There is also no mutable string type, but :meth:`str.join` or :class:`io.StringIO` can be used to efficiently construct strings from @@ -1522,7 +1564,7 @@ multiple fragments. printable string representation of *object*. For string objects, this is the string itself. If *object* does not have a :meth:`~object.__str__` method, then :func:`str` falls back to returning - :meth:`repr(object) <repr>`. + :func:`repr(object) <repr>`. .. index:: single: buffer protocol; str (built-in class) @@ -1560,7 +1602,7 @@ String Methods -------------- .. index:: - module: re + pair: module; re Strings implement all of the :ref:`common <typesseq-common>` sequence operations, along with the additional methods described below. @@ -1597,8 +1639,9 @@ expression support in the :mod:`re` module). lowercase, :meth:`lower` would do nothing to ``'ß'``; :meth:`casefold` converts it to ``"ss"``. - The casefolding algorithm is described in section 3.13 of the Unicode - Standard. + The casefolding algorithm is + `described in section 3.13 'Default Case Folding' of the Unicode Standard + <https://www.unicode.org/versions/Unicode15.0.0/ch03.pdf>`__. .. versionadded:: 3.3 @@ -1760,7 +1803,9 @@ expression support in the :mod:`re` module). one character, ``False`` otherwise. Alphabetic characters are those characters defined in the Unicode character database as "Letter", i.e., those with general category property being one of "Lm", "Lt", "Lu", "Ll", or "Lo". Note that this is different - from the "Alphabetic" property defined in the Unicode Standard. + from the `Alphabetic property defined in the section 4.10 'Letters, Alphabetic, and + Ideographic' of the Unicode Standard + <https://www.unicode.org/versions/Unicode15.0.0/ch04.pdf>`_. .. method:: str.isascii() @@ -1797,7 +1842,7 @@ expression support in the :mod:`re` module). Return ``True`` if the string is a valid identifier according to the language definition, section :ref:`identifiers`. - Call :func:`keyword.iskeyword` to test whether string ``s`` is a reserved + :func:`keyword.iskeyword` can be used to test whether string ``s`` is a reserved identifier, such as :keyword:`def` and :keyword:`class`. Example: @@ -1894,8 +1939,9 @@ expression support in the :mod:`re` module). Return a copy of the string with all the cased characters [4]_ converted to lowercase. - The lowercasing algorithm used is described in section 3.13 of the Unicode - Standard. + The lowercasing algorithm used is + `described in section 3.13 'Default Case Folding' of the Unicode Standard + <https://www.unicode.org/versions/Unicode15.0.0/ch03.pdf>`__. .. method:: str.lstrip([chars]) @@ -2239,8 +2285,9 @@ expression support in the :mod:`re` module). character(s) is not "Lu" (Letter, uppercase), but e.g. "Lt" (Letter, titlecase). - The uppercasing algorithm used is described in section 3.13 of the Unicode - Standard. + The uppercasing algorithm used is + `described in section 3.13 'Default Case Folding' of the Unicode Standard + <https://www.unicode.org/versions/Unicode15.0.0/ch03.pdf>`__. .. method:: str.zfill(width) @@ -2463,10 +2510,10 @@ Binary Sequence Types --- :class:`bytes`, :class:`bytearray`, :class:`memoryview ================================================================================= .. index:: - object: bytes - object: bytearray - object: memoryview - module: array + pair: object; bytes + pair: object; bytearray + pair: object; memoryview + pair: module; array The core built-in types for manipulating binary data are :class:`bytes` and :class:`bytearray`. They are supported by :class:`memoryview` which uses @@ -2481,7 +2528,7 @@ The :mod:`array` module supports efficient storage of basic data types like Bytes Objects ------------- -.. index:: object: bytes +.. index:: pair: object; bytes Bytes objects are immutable sequences of single bytes. Since many major binary protocols are based on the ASCII text encoding, bytes objects offer @@ -2588,7 +2635,7 @@ always convert a bytes object into a list of integers using ``list(b)``. Bytearray Objects ----------------- -.. index:: object: bytearray +.. index:: pair: object; bytearray :class:`bytearray` objects are a mutable counterpart to :class:`bytes` objects. @@ -3703,12 +3750,15 @@ copying. types such as :class:`bytes` and :class:`bytearray`, an element is a single byte, but other types such as :class:`array.array` may have bigger elements. - ``len(view)`` is equal to the length of :class:`~memoryview.tolist`. - If ``view.ndim = 0``, the length is 1. If ``view.ndim = 1``, the length - is equal to the number of elements in the view. For higher dimensions, - the length is equal to the length of the nested list representation of - the view. The :class:`~memoryview.itemsize` attribute will give you the - number of bytes in a single element. + ``len(view)`` is equal to the length of :class:`~memoryview.tolist`, which + is the nested list representation of the view. If ``view.ndim = 1``, + this is equal to the number of elements in the view. + + .. versionchanged:: 3.12 + If ``view.ndim == 0``, ``len(view)`` now raises :exc:`TypeError` instead of returning 1. + + The :class:`~memoryview.itemsize` attribute will give you the number of + bytes in a single element. A :class:`memoryview` supports slicing and indexing to expose its data. One-dimensional slicing will result in a subview:: @@ -3765,7 +3815,7 @@ copying. >>> data bytearray(b'z1spam') - One-dimensional memoryviews of hashable (read-only) types with formats + One-dimensional memoryviews of :term:`hashable` (read-only) types with formats 'B', 'b' or 'c' are also hashable. The hash is defined as ``hash(m) == hash(m.tobytes())``:: @@ -3779,7 +3829,7 @@ copying. .. versionchanged:: 3.3 One-dimensional memoryviews can now be sliced. - One-dimensional memoryviews with formats 'B', 'b' or 'c' are now hashable. + One-dimensional memoryviews with formats 'B', 'b' or 'c' are now :term:`hashable`. .. versionchanged:: 3.4 memoryview is now registered automatically with @@ -3902,7 +3952,7 @@ copying. >>> m = memoryview(bytearray(b'abc')) >>> mm = m.toreadonly() >>> mm.tolist() - [89, 98, 99] + [97, 98, 99] >>> mm[0] = 42 Traceback (most recent call last): File "<stdin>", line 1, in <module> @@ -3958,6 +4008,7 @@ copying. :mod:`struct` syntax. One of the formats must be a byte format ('B', 'b' or 'c'). The byte length of the result must be the same as the original length. + Note that all byte lengths may depend on the operating system. Cast 1D/long to 1D/unsigned bytes:: @@ -3988,8 +4039,8 @@ copying. >>> x = memoryview(b) >>> x[0] = b'a' Traceback (most recent call last): - File "<stdin>", line 1, in <module> - ValueError: memoryview: invalid value for format "B" + ... + TypeError: memoryview: invalid type for format 'B' >>> y = x.cast('c') >>> y[0] = b'a' >>> b @@ -4164,7 +4215,7 @@ copying. Set Types --- :class:`set`, :class:`frozenset` ============================================== -.. index:: object: set +.. index:: pair: object; set A :dfn:`set` object is an unordered collection of distinct :term:`hashable` objects. Common uses include membership testing, removing duplicates from a sequence, and @@ -4366,12 +4417,12 @@ Mapping Types --- :class:`dict` =============================== .. index:: - object: mapping - object: dictionary + pair: object; mapping + pair: object; dictionary triple: operations on; mapping; types triple: operations on; dictionary; type - statement: del - builtin: len + pair: statement; del + pair: built-in function; len A :term:`mapping` object maps :term:`hashable` values to arbitrary objects. Mappings are mutable objects. There is currently only one standard mapping @@ -4461,6 +4512,7 @@ can be used interchangeably to index the same dictionary entry. >>> class Counter(dict): ... def __missing__(self, key): ... return 0 + ... >>> c = Counter() >>> c['red'] 0 @@ -4699,12 +4751,14 @@ support membership tests: .. versionadded:: 3.10 -Keys views are set-like since their entries are unique and hashable. If all +Keys views are set-like since their entries are unique and :term:`hashable`. If all values are hashable, so that ``(key, value)`` pairs are unique and hashable, then the items view is also set-like. (Values views are not treated as set-like since the entries are generally not unique.) For set-like views, all of the operations defined for the abstract base class :class:`collections.abc.Set` are -available (for example, ``==``, ``<``, or ``^``). +available (for example, ``==``, ``<``, or ``^``). While using set operators, +set-like views accept any iterable as the other operand, unlike sets which only +accept sets as the input. An example of dictionary view usage:: @@ -4716,6 +4770,7 @@ An example of dictionary view usage:: >>> n = 0 >>> for val in values: ... n += val + ... >>> print(n) 504 @@ -4734,8 +4789,10 @@ An example of dictionary view usage:: >>> # set operations >>> keys & {'eggs', 'bacon', 'salad'} {'bacon'} - >>> keys ^ {'sausage', 'juice'} - {'juice', 'sausage', 'bacon', 'spam'} + >>> keys ^ {'sausage', 'juice'} == {'juice', 'sausage', 'bacon', 'spam'} + True + >>> keys | ['juice', 'juice', 'juice'] == {'bacon', 'spam', 'juice'} + True >>> # get back a read-only proxy for the original dictionary >>> values.mapping @@ -4835,7 +4892,7 @@ Generic Alias Type ------------------ .. index:: - object: GenericAlias + pair: object; GenericAlias pair: Generic; Alias ``GenericAlias`` objects are generally created by @@ -4942,8 +4999,8 @@ exception to disallow mistakes like ``dict[str][str]``:: >>> dict[str][str] Traceback (most recent call last): - File "<stdin>", line 1, in <module> - TypeError: There are no type variables left in dict[str] + ... + TypeError: dict[str] is not a generic class However, such expressions are valid when :ref:`type variables <generics>` are used. The index must have as many elements as there are type variable items @@ -5090,7 +5147,7 @@ Union Type ---------- .. index:: - object: Union + pair: object; Union pair: union; type A union object holds the value of the ``|`` (bitwise or) operation on @@ -5108,6 +5165,14 @@ enables cleaner type hinting syntax compared to :data:`typing.Union`. def square(number: int | float) -> int | float: return number ** 2 + .. note:: + + The ``|`` operand cannot be used at runtime to define unions where one or + more members is a forward reference. For example, ``int | "Foo"``, where + ``"Foo"`` is a reference to a class not yet defined, will fail at + runtime. For unions which include forward references, present the + whole expression as a string, e.g. ``"int | Foo"``. + .. describe:: union_object == other Union objects can be tested for equality with other union objects. Details: @@ -5141,13 +5206,15 @@ enables cleaner type hinting syntax compared to :data:`typing.Union`. >>> isinstance("", int | str) True - However, union objects containing :ref:`parameterized generics - <types-genericalias>` cannot be used:: + However, :ref:`parameterized generics <types-genericalias>` in + union objects cannot be checked:: - >>> isinstance(1, int | list[int]) + >>> isinstance(1, int | list[int]) # short-circuit evaluation + True + >>> isinstance([1], int | list[int]) Traceback (most recent call last): - File "<stdin>", line 1, in <module> - TypeError: isinstance() argument 2 cannot contain a parameterized generic + ... + TypeError: isinstance() argument 2 cannot be a parameterized generic The user-exposed type for the union object can be accessed from :data:`types.UnionType` and used for :func:`isinstance` checks. An object cannot be @@ -5247,7 +5314,7 @@ See :ref:`function` for more information. Methods ------- -.. index:: object: method +.. index:: pair: object; method Methods are functions that are called using the attribute notation. There are two flavors: built-in methods (such as :meth:`append` on lists) and class @@ -5294,7 +5361,7 @@ Code Objects ------------ .. index:: - builtin: compile + pair: built-in function; compile single: __code__ (function object attribute) Code objects are used by the implementation to represent "pseudo-compiled" @@ -5308,8 +5375,8 @@ Accessing ``__code__`` raises an :ref:`auditing event <auditing>` ``object.__getattr__`` with arguments ``obj`` and ``"__code__"``. .. index:: - builtin: exec - builtin: eval + pair: built-in function; exec + pair: built-in function; eval A code object can be executed or evaluated by passing it (instead of a source string) to the :func:`exec` or :func:`eval` built-in functions. @@ -5323,8 +5390,8 @@ Type Objects ------------ .. index:: - builtin: type - module: types + pair: built-in function; type + pair: module; types Type objects represent the various object types. An object's type is accessed by the built-in function :func:`type`. There are no special operations on @@ -5373,27 +5440,6 @@ information. There is exactly one ``NotImplemented`` object. It is written as ``NotImplemented``. -.. _bltin-boolean-values: - -Boolean Values --------------- - -Boolean values are the two constant objects ``False`` and ``True``. They are -used to represent truth values (although other values can also be considered -false or true). In numeric contexts (for example when used as the argument to -an arithmetic operator), they behave like the integers 0 and 1, respectively. -The built-in function :func:`bool` can be used to convert any value to a -Boolean, if the value can be interpreted as a truth value (see section -:ref:`truth` above). - -.. index:: - single: False - single: True - pair: Boolean; values - -They are written as ``False`` and ``True``, respectively. - - .. _typesinternal: Internal Objects @@ -5443,6 +5489,14 @@ types, where they are relevant. Some of these are not reported by the .. versionadded:: 3.3 +.. attribute:: definition.__type_params__ + + The :ref:`type parameters <type-params>` of generic classes, functions, + and :ref:`type aliases <type-aliases>`. + + .. versionadded:: 3.12 + + .. attribute:: class.__mro__ This attribute is a tuple of classes that are considered when looking for @@ -5463,7 +5517,7 @@ types, where they are relevant. Some of these are not reported by the definition order. Example:: >>> int.__subclasses__() - [<class 'bool'>] + [<class 'bool'>, <enum 'IntEnum'>, <flag 'IntFlag'>, <class 're._constants._NamedIntConstant'>] .. _int_max_str_digits: @@ -5499,7 +5553,7 @@ When an operation would exceed the limit, a :exc:`ValueError` is raised: >>> _ = int('2' * 5432) Traceback (most recent call last): ... - ValueError: Exceeds the limit (4300 digits) for integer string conversion: value has 5432 digits; use sys.set_int_max_str_digits() to increase the limit. + ValueError: Exceeds the limit (4300 digits) for integer string conversion: value has 5432 digits; use sys.set_int_max_str_digits() to increase the limit >>> i = int('2' * 4300) >>> len(str(i)) 4300 @@ -5507,7 +5561,7 @@ When an operation would exceed the limit, a :exc:`ValueError` is raised: >>> len(str(i_squared)) Traceback (most recent call last): ... - ValueError: Exceeds the limit (4300 digits) for integer string conversion: value has 8599 digits; use sys.set_int_max_str_digits() to increase the limit. + ValueError: Exceeds the limit (4300 digits) for integer string conversion; use sys.set_int_max_str_digits() to increase the limit >>> len(hex(i_squared)) 7144 >>> assert int(hex(i_squared), base=16) == i*i # Hexadecimal is unlimited. @@ -5577,7 +5631,7 @@ From code, you can inspect the current limit and set a new one using these a getter and setter for the interpreter-wide limit. Subinterpreters have their own limit. -Information about the default and minimum can be found in :attr:`sys.int_info`: +Information about the default and minimum can be found in :data:`sys.int_info`: * :data:`sys.int_info.default_max_str_digits <sys.int_info>` is the compiled-in default limit. @@ -5608,7 +5662,7 @@ Recommended configuration The default :data:`sys.int_info.default_max_str_digits` is expected to be reasonable for most applications. If your application requires a different limit, set it from your main entry point using Python version agnostic code as -these APIs were added in security patch releases in versions before 3.11. +these APIs were added in security patch releases in versions before 3.12. Example:: diff --git a/Doc/library/string.rst b/Doc/library/string.rst index 3b96813e..9b28f995 100644 --- a/Doc/library/string.rst +++ b/Doc/library/string.rst @@ -227,7 +227,9 @@ See also the :ref:`formatspec` section. The *field_name* itself begins with an *arg_name* that is either a number or a keyword. If it's a number, it refers to a positional argument, and if it's a keyword, -it refers to a named keyword argument. If the numerical arg_names in a format string +it refers to a named keyword argument. An *arg_name* is treated as a number if +a call to :meth:`str.isdecimal` on the string would return true. +If the numerical arg_names in a format string are 0, 1, 2, ... in sequence, they can all be omitted (not just some) and the numbers 0, 1, 2, ... will be automatically inserted in that order. Because *arg_name* is not quote-delimited, it is not possible to specify arbitrary @@ -235,7 +237,7 @@ dictionary keys (e.g., the strings ``'10'`` or ``':-]'``) within a format string The *arg_name* can be followed by any number of index or attribute expressions. An expression of the form ``'.name'`` selects the named attribute using :func:`getattr`, while an expression of the form ``'[index]'`` -does an index lookup using :func:`__getitem__`. +does an index lookup using :meth:`~object.__getitem__`. .. versionchanged:: 3.1 The positional argument specifiers can be omitted for :meth:`str.format`, @@ -254,10 +256,10 @@ Some simple format string examples:: "Units destroyed: {players[0]}" # First element of keyword argument 'players'. The *conversion* field causes a type coercion before formatting. Normally, the -job of formatting a value is done by the :meth:`__format__` method of the value +job of formatting a value is done by the :meth:`~object.__format__` method of the value itself. However, in some cases it is desirable to force a type to be formatted as a string, overriding its own definition of formatting. By converting the -value to a string before calling :meth:`__format__`, the normal formatting logic +value to a string before calling :meth:`~object.__format__`, the normal formatting logic is bypassed. Three conversion flags are currently supported: ``'!s'`` which calls :func:`str` @@ -310,7 +312,7 @@ non-empty format specification typically modifies the result. The general form of a *standard format specifier* is: .. productionlist:: format-spec - format_spec: [[`fill`]`align`][`sign`][z][#][0][`width`][`grouping_option`][.`precision`][`type`] + format_spec: [[`fill`]`align`][`sign`]["z"]["#"]["0"][`width`][`grouping_option`]["." `precision`][`type`] fill: <any character> align: "<" | ">" | "=" | "^" sign: "+" | "-" | " " diff --git a/Doc/library/stringprep.rst b/Doc/library/stringprep.rst index 5cfb533d..c6d78a35 100644 --- a/Doc/library/stringprep.rst +++ b/Doc/library/stringprep.rst @@ -27,7 +27,7 @@ procedure are part of the profile. One example of a ``stringprep`` profile is ``nameprep``, which is used for internationalized domain names. The module :mod:`stringprep` only exposes the tables from :rfc:`3454`. As these -tables would be very large to represent them as dictionaries or lists, the +tables would be very large to represent as dictionaries or lists, the module uses the Unicode character database internally. The module source code itself was generated using the ``mkstringprep.py`` utility. diff --git a/Doc/library/struct.rst b/Doc/library/struct.rst index 50d70731..c94dfde4 100644 --- a/Doc/library/struct.rst +++ b/Doc/library/struct.rst @@ -231,9 +231,9 @@ platform-dependent. | ``Q`` | :c:expr:`unsigned long | integer | 8 | \(2) | | | long` | | | | +--------+--------------------------+--------------------+----------------+------------+ -| ``n`` | :c:expr:`ssize_t` | integer | | \(3) | +| ``n`` | :c:type:`ssize_t` | integer | | \(3) | +--------+--------------------------+--------------------+----------------+------------+ -| ``N`` | :c:expr:`size_t` | integer | | \(3) | +| ``N`` | :c:type:`size_t` | integer | | \(3) | +--------+--------------------------+--------------------+----------------+------------+ | ``e`` | \(6) | float | 2 | \(4) | +--------+--------------------------+--------------------+----------------+------------+ @@ -266,11 +266,11 @@ Notes: (2) When attempting to pack a non-integer using any of the integer conversion - codes, if the non-integer has a :meth:`__index__` method then that method is + codes, if the non-integer has a :meth:`~object.__index__` method then that method is called to convert the argument to an integer before packing. .. versionchanged:: 3.2 - Added use of the :meth:`__index__` method for non-integers. + Added use of the :meth:`~object.__index__` method for non-integers. (3) The ``'n'`` and ``'N'`` conversion codes are only available for the native @@ -371,7 +371,7 @@ ordering:: >>> from struct import * >>> pack(">bhl", 1, 2, 3) b'\x01\x00\x02\x00\x00\x00\x03' - >>> unpack('>bhl', b'\x01\x00\x02\x00\x00\x00\x03' + >>> unpack('>bhl', b'\x01\x00\x02\x00\x00\x00\x03') (1, 2, 3) >>> calcsize('>bhl') 7 @@ -462,7 +462,7 @@ In such cases, the ``@`` format character should be used to specify native byte ordering and data sizes. Internal pad bytes are normally inserted automatically. It is possible that a zero-repeat format code will be needed at the end of a format string to round up to the correct -byte boundary for proper alignment of consective chunks of data. +byte boundary for proper alignment of consecutive chunks of data. Consider these two simple examples (on a 64-bit, little-endian machine):: @@ -548,9 +548,9 @@ The :mod:`struct` module also defines the following type: .. note:: The compiled versions of the most recent format strings passed to - :class:`Struct` and the module-level functions are cached, so programs - that use only a few format strings needn't worry about reusing a single - :class:`Struct` instance. + the module-level functions are cached, so programs that use only a few + format strings needn't worry about reusing a single :class:`Struct` + instance. Compiled Struct objects support the following methods and attributes: @@ -602,4 +602,4 @@ The :mod:`struct` module also defines the following type: .. _ieee 754 standard: https://en.wikipedia.org/wiki/IEEE_754-2008_revision -.. _IETF RFC 1700: https://tools.ietf.org/html/rfc1700 +.. _IETF RFC 1700: https://datatracker.ietf.org/doc/html/rfc1700 diff --git a/Doc/library/subprocess.rst b/Doc/library/subprocess.rst index e4e38e93..04340cca 100644 --- a/Doc/library/subprocess.rst +++ b/Doc/library/subprocess.rst @@ -57,10 +57,13 @@ underlying :class:`Popen` interface can be used directly. and combine both streams into one, use ``stdout=PIPE`` and ``stderr=STDOUT`` instead of *capture_output*. - The *timeout* argument is passed to :meth:`Popen.communicate`. If the timeout - expires, the child process will be killed and waited for. The - :exc:`TimeoutExpired` exception will be re-raised after the child process - has terminated. + A *timeout* may be specified in seconds, it is internally passed on to + :meth:`Popen.communicate`. If the timeout expires, the child process will be + killed and waited for. The :exc:`TimeoutExpired` exception will be + re-raised after the child process has terminated. The initial process + creation itself cannot be interrupted on many platform APIs so you are not + guaranteed to see a timeout exception until at least after however long + process creation takes. The *input* argument is passed to :meth:`Popen.communicate` and thus to the subprocess's stdin. If used it must be a byte sequence, or a string if @@ -111,6 +114,14 @@ underlying :class:`Popen` interface can be used directly. Added the *text* parameter, as a more understandable alias of *universal_newlines*. Added the *capture_output* parameter. + .. versionchanged:: 3.12 + + Changed Windows shell search order for ``shell=True``. The current + directory and ``%PATH%`` are replaced with ``%COMSPEC%`` and + ``%SystemRoot%\System32\cmd.exe``. As a result, dropping a + malicious program named ``cmd.exe`` into a current directory no + longer works. + .. class:: CompletedProcess The return value from :func:`run`, representing a process that has finished. @@ -270,15 +281,14 @@ default values. The arguments that are most commonly needed are: *stdin*, *stdout* and *stderr* specify the executed program's standard input, standard output and standard error file handles, respectively. Valid values - are :data:`PIPE`, :data:`DEVNULL`, an existing file descriptor (a positive - integer), an existing file object with a valid file descriptor, and ``None``. - :data:`PIPE` indicates that a new pipe to the child should be created. - :data:`DEVNULL` indicates that the special file :data:`os.devnull` will - be used. With the default settings of ``None``, no redirection will occur; - the child's file handles will be inherited from the parent. - Additionally, *stderr* can be :data:`STDOUT`, which indicates that the - stderr data from the child process should be captured into the same file - handle as for *stdout*. + are ``None``, :data:`PIPE`, :data:`DEVNULL`, an existing file descriptor (a + positive integer), and an existing :term:`file object` with a valid file + descriptor. With the default settings of ``None``, no redirection will + occur. :data:`PIPE` indicates that a new pipe to the child should be + created. :data:`DEVNULL` indicates that the special file :data:`os.devnull` + will be used. Additionally, *stderr* can be :data:`STDOUT`, which indicates + that the stderr data from the child process should be captured into the same + file handle as for *stdout*. .. index:: single: universal newlines; subprocess module @@ -455,10 +465,10 @@ functions. :func:`open` function when creating the stdin/stdout/stderr pipe file objects: - - :const:`0` means unbuffered (read and write are one + - ``0`` means unbuffered (read and write are one system call and can return short) - - :const:`1` means line buffered - (only usable if ``universal_newlines=True`` i.e., in a text mode) + - ``1`` means line buffered + (only usable if ``text=True`` or ``universal_newlines=True``) - any other positive value means use a buffer of approximately that size - negative bufsize (the default) means the system default of @@ -467,7 +477,7 @@ functions. .. versionchanged:: 3.3.1 *bufsize* now defaults to -1 to enable buffering by default to match the behavior that most code expects. In versions prior to Python 3.2.4 and - 3.3.1 it incorrectly defaulted to :const:`0` which was unbuffered + 3.3.1 it incorrectly defaulted to ``0`` which was unbuffered and allowed short reads. This was unintentional and did not match the behavior of Python 2 as most code expected. @@ -488,17 +498,24 @@ functions. *executable* parameter accepts a bytes and :term:`path-like object` on Windows. + .. versionchanged:: 3.12 + + Changed Windows shell search order for ``shell=True``. The current + directory and ``%PATH%`` are replaced with ``%COMSPEC%`` and + ``%SystemRoot%\System32\cmd.exe``. As a result, dropping a + malicious program named ``cmd.exe`` into a current directory no + longer works. + *stdin*, *stdout* and *stderr* specify the executed program's standard input, standard output and standard error file handles, respectively. Valid values - are :data:`PIPE`, :data:`DEVNULL`, an existing file descriptor (a positive - integer), an existing :term:`file object` with a valid file descriptor, - and ``None``. :data:`PIPE` indicates that a new pipe to the child should - be created. :data:`DEVNULL` indicates that the special file - :data:`os.devnull` will be used. With the default settings of ``None``, - no redirection will occur; the child's file handles will be inherited from - the parent. Additionally, *stderr* can be :data:`STDOUT`, which indicates + are ``None``, :data:`PIPE`, :data:`DEVNULL`, an existing file descriptor (a + positive integer), and an existing :term:`file object` with a valid file + descriptor. With the default settings of ``None``, no redirection will + occur. :data:`PIPE` indicates that a new pipe to the child should be + created. :data:`DEVNULL` indicates that the special file :data:`os.devnull` + will be used. Additionally, *stderr* can be :data:`STDOUT`, which indicates that the stderr data from the applications should be captured into the same - file handle as for stdout. + file handle as for *stdout*. If *preexec_fn* is set to a callable object, this object will be called in the child process just before the child is executed. @@ -524,8 +541,8 @@ functions. :exc:`RuntimeError`. The new restriction may affect applications that are deployed in mod_wsgi, uWSGI, and other embedded environments. - If *close_fds* is true, all file descriptors except :const:`0`, :const:`1` and - :const:`2` will be closed before the child process is executed. Otherwise + If *close_fds* is true, all file descriptors except ``0``, ``1`` and + ``2`` will be closed before the child process is executed. Otherwise when *close_fds* is false, file descriptors obey their inheritable flag as described in :ref:`fd_inheritance`. @@ -720,7 +737,7 @@ arguments. code. All of the functions and methods that accept a *timeout* parameter, such as -:func:`call` and :meth:`Popen.communicate` will raise :exc:`TimeoutExpired` if +:func:`run` and :meth:`Popen.communicate` will raise :exc:`TimeoutExpired` if the timeout expires before the process exits. Exceptions defined in this module all inherit from :exc:`SubprocessError`. @@ -849,7 +866,8 @@ Instances of the :class:`Popen` class have the following methods: On Windows :meth:`kill` is an alias for :meth:`terminate`. -The following attributes are also available: +The following attributes are also set by the class for you to access. +Reassigning them to new values is unsupported: .. attribute:: Popen.args @@ -862,9 +880,9 @@ The following attributes are also available: If the *stdin* argument was :data:`PIPE`, this attribute is a writeable stream object as returned by :func:`open`. If the *encoding* or *errors* - arguments were specified or the *universal_newlines* argument was ``True``, - the stream is a text stream, otherwise it is a byte stream. If the *stdin* - argument was not :data:`PIPE`, this attribute is ``None``. + arguments were specified or the *text* or *universal_newlines* argument + was ``True``, the stream is a text stream, otherwise it is a byte stream. + If the *stdin* argument was not :data:`PIPE`, this attribute is ``None``. .. attribute:: Popen.stdout @@ -872,9 +890,9 @@ The following attributes are also available: If the *stdout* argument was :data:`PIPE`, this attribute is a readable stream object as returned by :func:`open`. Reading from the stream provides output from the child process. If the *encoding* or *errors* arguments were - specified or the *universal_newlines* argument was ``True``, the stream is a - text stream, otherwise it is a byte stream. If the *stdout* argument was not - :data:`PIPE`, this attribute is ``None``. + specified or the *text* or *universal_newlines* argument was ``True``, the + stream is a text stream, otherwise it is a byte stream. If the *stdout* + argument was not :data:`PIPE`, this attribute is ``None``. .. attribute:: Popen.stderr @@ -882,9 +900,9 @@ The following attributes are also available: If the *stderr* argument was :data:`PIPE`, this attribute is a readable stream object as returned by :func:`open`. Reading from the stream provides error output from the child process. If the *encoding* or *errors* arguments - were specified or the *universal_newlines* argument was ``True``, the stream - is a text stream, otherwise it is a byte stream. If the *stderr* argument was - not :data:`PIPE`, this attribute is ``None``. + were specified or the *text* or *universal_newlines* argument was ``True``, the + stream is a text stream, otherwise it is a byte stream. If the *stderr* argument + was not :data:`PIPE`, this attribute is ``None``. .. warning:: @@ -904,9 +922,12 @@ The following attributes are also available: .. attribute:: Popen.returncode - The child return code, set by :meth:`poll` and :meth:`wait` (and indirectly - by :meth:`communicate`). A ``None`` value indicates that the process - hasn't terminated yet. + The child return code. Initially ``None``, :attr:`returncode` is set by + a call to the :meth:`poll`, :meth:`wait`, or :meth:`communicate` methods + if they detect that the process has terminated. + + A ``None`` value indicates that the process hadn't yet terminated at the + time of the last method call. A negative value ``-N`` indicates that the child was terminated by signal ``N`` (POSIX only). @@ -1159,6 +1180,14 @@ calls these functions. .. versionchanged:: 3.3 *timeout* was added. + .. versionchanged:: 3.12 + + Changed Windows shell search order for ``shell=True``. The current + directory and ``%PATH%`` are replaced with ``%COMSPEC%`` and + ``%SystemRoot%\System32\cmd.exe``. As a result, dropping a + malicious program named ``cmd.exe`` into a current directory no + longer works. + .. function:: check_call(args, *, stdin=None, stdout=None, stderr=None, \ shell=False, cwd=None, timeout=None, \ **other_popen_kwargs) @@ -1191,6 +1220,14 @@ calls these functions. .. versionchanged:: 3.3 *timeout* was added. + .. versionchanged:: 3.12 + + Changed Windows shell search order for ``shell=True``. The current + directory and ``%PATH%`` are replaced with ``%COMSPEC%`` and + ``%SystemRoot%\System32\cmd.exe``. As a result, dropping a + malicious program named ``cmd.exe`` into a current directory no + longer works. + .. function:: check_output(args, *, stdin=None, stderr=None, shell=False, \ cwd=None, encoding=None, errors=None, \ @@ -1246,6 +1283,14 @@ calls these functions. .. versionadded:: 3.7 *text* was added as a more readable alias for *universal_newlines*. + .. versionchanged:: 3.12 + + Changed Windows shell search order for ``shell=True``. The current + directory and ``%PATH%`` are replaced with ``%COMSPEC%`` and + ``%SystemRoot%\System32\cmd.exe``. As a result, dropping a + malicious program named ``cmd.exe`` into a current directory no + longer works. + .. _subprocess-replacements: @@ -1565,7 +1610,7 @@ improves performance. If you ever encounter a presumed highly unusual situation where you need to prevent ``vfork()`` from being used by Python, you can set the -:attr:`subprocess._USE_VFORK` attribute to a false value. +:const:`subprocess._USE_VFORK` attribute to a false value. :: @@ -1573,7 +1618,7 @@ prevent ``vfork()`` from being used by Python, you can set the Setting this has no impact on use of ``posix_spawn()`` which could use ``vfork()`` internally within its libc implementation. There is a similar -:attr:`subprocess._USE_POSIX_SPAWN` attribute if you need to prevent use of +:const:`subprocess._USE_POSIX_SPAWN` attribute if you need to prevent use of that. :: @@ -1583,7 +1628,7 @@ that. It is safe to set these to false on any Python version. They will have no effect on older versions when unsupported. Do not assume the attributes are available to read. Despite their names, a true value does not indicate that the -corresponding function will be used, only that that it may be. +corresponding function will be used, only that it may be. Please file issues any time you have to use these private knobs with a way to reproduce the issue you were seeing. Link to that issue from a comment in your diff --git a/Doc/library/superseded.rst b/Doc/library/superseded.rst index b38f1669..910e8991 100644 --- a/Doc/library/superseded.rst +++ b/Doc/library/superseded.rst @@ -9,17 +9,15 @@ backwards compatibility. They have been superseded by other modules. .. toctree:: + :maxdepth: 1 aifc.rst - asynchat.rst - asyncore.rst audioop.rst cgi.rst cgitb.rst chunk.rst crypt.rst imghdr.rst - imp.rst mailcap.rst msilib.rst nis.rst @@ -27,7 +25,6 @@ backwards compatibility. They have been superseded by other modules. optparse.rst ossaudiodev.rst pipes.rst - smtpd.rst sndhdr.rst spwd.rst sunau.rst diff --git a/Doc/library/symtable.rst b/Doc/library/symtable.rst index 65ff5bfe..85eae5f3 100644 --- a/Doc/library/symtable.rst +++ b/Doc/library/symtable.rst @@ -38,7 +38,13 @@ Examining Symbol Tables .. method:: get_type() Return the type of the symbol table. Possible values are ``'class'``, - ``'module'``, and ``'function'``. + ``'module'``, ``'function'``, ``'annotation'``, ``'TypeVar bound'``, + ``'type alias'``, and ``'type parameter'``. The latter four refer to + different flavors of :ref:`annotation scopes <annotation-scopes>`. + + .. versionchanged:: 3.12 + Added ``'annotation'``, ``'TypeVar bound'``, ``'type alias'``, + and ``'type parameter'`` as possible return values. .. method:: get_id() @@ -49,6 +55,10 @@ Examining Symbol Tables Return the table's name. This is the name of the class if the table is for a class, the name of the function if the table is for a function, or ``'top'`` if the table is global (:meth:`get_type` returns ``'module'``). + For type parameter scopes (which are used for generic classes, functions, + and type aliases), it is the name of the underlying class, function, or + type alias. For type alias scopes, it is the name of the type alias. + For :class:`~typing.TypeVar` bound scopes, it is the name of the ``TypeVar``. .. method:: get_lineno() diff --git a/Doc/library/sys.monitoring.rst b/Doc/library/sys.monitoring.rst new file mode 100644 index 00000000..7b02b95f --- /dev/null +++ b/Doc/library/sys.monitoring.rst @@ -0,0 +1,300 @@ +:mod:`sys.monitoring` --- Execution event monitoring +==================================================== + +.. module:: sys.monitoring + :synopsis: Access and control event monitoring + +----------------- + +.. note:: + + ``sys.monitoring`` is a namespace within the ``sys`` module, + not an independent module, so there is no need to + ``import sys.monitoring``, simply ``import sys`` and then use + ``sys.monitoring``. + + +This namespace provides access to the functions and constants necessary to +activate and control event monitoring. + +As programs execute, events occur that might be of interest to tools that +monitor execution. The :mod:`!sys.monitoring` namespace provides means to +receive callbacks when events of interest occur. + +The monitoring API consists of three components: + +* Tool identifiers +* Events +* Callbacks + +Tool identifiers +---------------- + +A tool identifier is an integer and associated name. +Tool identifiers are used to discourage tools from interfering with each +other and to allow multiple tools to operate at the same time. +Currently tools are completely independent and cannot be used to +monitor each other. This restriction may be lifted in the future. + +Before registering or activating events, a tool should choose an identifier. +Identifiers are integers in the range 0 to 5. + +Registering and using tools +''''''''''''''''''''''''''' + +.. function:: use_tool_id(id: int, name: str) -> None + + Must be called before ``id`` can be used. + ``id`` must be in the range 0 to 5 inclusive. + Raises a ``ValueError`` if ``id`` is in use. + +.. function:: free_tool_id(id: int) -> None + + Should be called once a tool no longer requires ``id``. + +.. function:: get_tool(id: int) -> str | None + + Returns the name of the tool if ``id`` is in use, + otherwise it returns ``None``. + ``id`` must be in the range 0 to 5 inclusive. + +All IDs are treated the same by the VM with regard to events, but the +following IDs are pre-defined to make co-operation of tools easier:: + + sys.monitoring.DEBUGGER_ID = 0 + sys.monitoring.COVERAGE_ID = 1 + sys.monitoring.PROFILER_ID = 2 + sys.monitoring.OPTIMIZER_ID = 5 + +There is no obligation to set an ID, nor is there anything preventing a tool +from using an ID even it is already in use. +However, tools are encouraged to use a unique ID and respect other tools. + +Events +------ + +The following events are supported: + +BRANCH + A conditional branch is taken (or not). +CALL + A call in Python code (event occurs before the call). +C_RAISE + Exception raised from any callable, except Python functions (event occurs after the exit). +C_RETURN + Return from any callable, except Python functions (event occurs after the return). +EXCEPTION_HANDLED + An exception is handled. +INSTRUCTION + A VM instruction is about to be executed. +JUMP + An unconditional jump in the control flow graph is made. +LINE + An instruction is about to be executed that has a different line number from the preceding instruction. +PY_RESUME + Resumption of a Python function (for generator and coroutine functions), except for throw() calls. +PY_RETURN + Return from a Python function (occurs immediately before the return, the callee's frame will be on the stack). +PY_START + Start of a Python function (occurs immediately after the call, the callee's frame will be on the stack) +PY_THROW + A Python function is resumed by a throw() call. +PY_UNWIND + Exit from a Python function during exception unwinding. +PY_YIELD + Yield from a Python function (occurs immediately before the yield, the callee's frame will be on the stack). +RAISE + An exception is raised, except those that cause a ``STOP_ITERATION`` event. +RERAISE + An exception is re-raised, for example at the end of a ``finally`` block. +STOP_ITERATION + An artificial ``StopIteration`` is raised; see `the STOP_ITERATION event`_. + +More events may be added in the future. + +These events are attributes of the :mod:`!sys.monitoring.events` namespace. +Each event is represented as a power-of-2 integer constant. +To define a set of events, simply bitwise or the individual events together. +For example, to specify both ``PY_RETURN`` and ``PY_START`` events, use the +expression ``PY_RETURN | PY_START``. + +Events are divided into three groups: + +Local events +'''''''''''' + +Local events are associated with normal execution of the program and happen +at clearly defined locations. All local events can be disabled. +The local events are: + +* PY_START +* PY_RESUME +* PY_RETURN +* PY_YIELD +* CALL +* LINE +* INSTRUCTION +* JUMP +* BRANCH +* STOP_ITERATION + +Ancillary events +'''''''''''''''' + +Ancillary events can be monitored like other events, but are controlled +by another event: + +* C_RAISE +* C_RETURN + +The ``C_RETURN`` and ``C_RAISE`` events are are controlled by the ``CALL`` +event. ``C_RETURN`` and ``C_RAISE`` events will only be seen if the +corresponding ``CALL`` event is being monitored. + +Other events +'''''''''''' + +Other events are not necessarily tied to a specific location in the +program and cannot be individually disabled. + +The other events that can be monitored are: + +* PY_THROW +* PY_UNWIND +* RAISE +* EXCEPTION_HANDLED + + +The STOP_ITERATION event +'''''''''''''''''''''''' + +:pep:`PEP 380 <380#use-of-stopiteration-to-return-values>` +specifies that a ``StopIteration`` exception is raised when returning a value +from a generator or coroutine. However, this is a very inefficient way to +return a value, so some Python implementations, notably CPython 3.12+, do not +raise an exception unless it would be visible to other code. + +To allow tools to monitor for real exceptions without slowing down generators +and coroutines, the ``STOP_ITERATION`` event is provided. +``STOP_ITERATION`` can be locally disabled, unlike ``RAISE``. + + +Turning events on and off +------------------------- + +In order to monitor an event, it must be turned on and a callback registered. +Events can be turned on or off by setting the events either globally or +for a particular code object. + + +Setting events globally +''''''''''''''''''''''' + +Events can be controlled globally by modifying the set of events being monitored. + +.. function:: get_events(tool_id: int) -> int + + Returns the ``int`` representing all the active events. + +.. function:: set_events(tool_id: int, event_set: int) + + Activates all events which are set in ``event_set``. + Raises a ``ValueError`` if ``tool_id`` is not in use. + +No events are active by default. + +Per code object events +'''''''''''''''''''''' + +Events can also be controlled on a per code object basis. + +.. function:: get_local_events(tool_id: int, code: CodeType) -> int + + Returns all the local events for ``code`` + +.. function:: set_local_events(tool_id: int, code: CodeType, event_set: int) + + Activates all the local events for ``code`` which are set in ``event_set``. + Raises a ``ValueError`` if ``tool_id`` is not in use. + +Local events add to global events, but do not mask them. +In other words, all global events will trigger for a code object, +regardless of the local events. + + +Disabling events +'''''''''''''''' + +Local events can be disabled for a specific code location by returning +``sys.monitoring.DISABLE`` from a callback function. This does not change +which events are set, or any other code locations for the same event. + +Disabling events for specific locations is very important for high +performance monitoring. For example, a program can be run under a +debugger with no overhead if the debugger disables all monitoring +except for a few breakpoints. + + +Registering callback functions +------------------------------ + +To register a callable for events call + +.. function:: register_callback(tool_id: int, event: int, func: Callable | None) -> Callable | None + + Registers the callable ``func`` for the ``event`` with the given ``tool_id`` + + If another callback was registered for the given ``tool_id`` and ``event``, + it is unregistered and returned. + Otherwise ``register_callback`` returns ``None``. + + +Functions can be unregistered by calling +``sys.monitoring.register_callback(tool_id, event, None)``. + +Callback functions can be registered and unregistered at any time. + +Registering or unregistering a callback function will generate a ``sys.audit`` event. + + +Callback function arguments +''''''''''''''''''''''''''' + +When an active event occurs, the registered callback function is called. +Different events will provide the callback function with different arguments, as follows: + +* ``PY_START`` and ``PY_RESUME``:: + + func(code: CodeType, instruction_offset: int) -> DISABLE | Any + +* ``PY_RETURN`` and ``PY_YIELD``: + + ``func(code: CodeType, instruction_offset: int, retval: object) -> DISABLE | Any`` + +* ``CALL``, ``C_RAISE`` and ``C_RETURN``: + + ``func(code: CodeType, instruction_offset: int, callable: object, arg0: object | MISSING) -> DISABLE | Any`` + + If there are no arguments, ``arg0`` is set to ``MISSING``. + +* ``RAISE``, ``RERAISE``, ``EXCEPTION_HANDLED``, ``PY_UNWIND``, ``PY_THROW`` and ``STOP_ITERATION``: + + ``func(code: CodeType, instruction_offset: int, exception: BaseException) -> DISABLE | Any`` + +* ``LINE``: + + ``func(code: CodeType, line_number: int) -> DISABLE | Any`` + +* ``BRANCH`` and ``JUMP``: + + ``func(code: CodeType, instruction_offset: int, destination_offset: int) -> DISABLE | Any`` + + Note that the ``destination_offset`` is where the code will next execute. + For an untaken branch this will be the offset of the instruction following + the branch. + +* ``INSTRUCTION``: + + ``func(code: CodeType, instruction_offset: int) -> DISABLE | Any`` + + diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst index b458040c..6fb4c0f1 100644 --- a/Doc/library/sys.rst +++ b/Doc/library/sys.rst @@ -166,7 +166,7 @@ always available. Python interpreter. (This information is not available in any other way --- ``modules.keys()`` only lists the imported modules.) - See also the :attr:`sys.stdlib_module_names` list. + See also the :data:`sys.stdlib_module_names` list. .. function:: call_tracing(func, args) @@ -220,6 +220,10 @@ always available. .. audit-event:: sys._current_exceptions "" sys._current_exceptions + .. versionchanged:: 3.12 + Each value in the dictionary is now a single exception instance, rather + than a 3-tuple as returned from ``sys.exc_info()``. + .. function:: breakpointhook() This hook function is called by built-in :func:`breakpoint`. By default, @@ -329,23 +333,21 @@ always available. *wasm32-emscripten* platform. The named tuple is provisional and may change in the future. - .. tabularcolumns:: |l|L| - - +-----------------------------+----------------------------------------------+ - | Attribute | Explanation | - +=============================+==============================================+ - | :const:`emscripten_version` | Emscripten version as tuple of ints | - | | (major, minor, micro), e.g. ``(3, 1, 8)``. | - +-----------------------------+----------------------------------------------+ - | :const:`runtime` | Runtime string, e.g. browser user agent, | - | | ``'Node.js v14.18.2'``, or ``'UNKNOWN'``. | - +-----------------------------+----------------------------------------------+ - | :const:`pthreads` | ``True`` if Python is compiled with | - | | Emscripten pthreads support. | - +-----------------------------+----------------------------------------------+ - | :const:`shared_memory` | ``True`` if Python is compiled with shared | - | | memory support. | - +-----------------------------+----------------------------------------------+ + .. attribute:: _emscripten_info.emscripten_version + + Emscripten version as tuple of ints (major, minor, micro), e.g. ``(3, 1, 8)``. + + .. attribute:: _emscripten_info.runtime + + Runtime string, e.g. browser user agent, ``'Node.js v14.18.2'``, or ``'UNKNOWN'``. + + .. attribute:: _emscripten_info.pthreads + + ``True`` if Python is compiled with Emscripten pthreads support. + + .. attribute:: _emscripten_info.shared_memory + + ``True`` if Python is compiled with shared memory support. .. availability:: Emscripten. @@ -376,7 +378,7 @@ always available. This function prints out a given traceback and exception to ``sys.stderr``. - When an exception is raised and uncaught, the interpreter calls + When an exception other than :exc:`SystemExit` is raised and uncaught, the interpreter calls ``sys.excepthook`` with three arguments, the exception class, exception instance, and a traceback object. In an interactive session this happens just before control is returned to the prompt; in a Python program this happens just @@ -440,7 +442,7 @@ always available. object <traceback-objects>` which typically encapsulates the call stack at the point where the exception last occurred. - .. index:: object: traceback + .. index:: pair: object; traceback If no exception is being handled anywhere on the stack, this function return a tuple containing three ``None`` values. @@ -511,27 +513,62 @@ always available. The :term:`named tuple` *flags* exposes the status of command line flags. The attributes are read only. - ============================= ============================================================================================================== - attribute flag - ============================= ============================================================================================================== - :const:`debug` :option:`-d` - :const:`inspect` :option:`-i` - :const:`interactive` :option:`-i` - :const:`isolated` :option:`-I` - :const:`optimize` :option:`-O` or :option:`-OO` - :const:`dont_write_bytecode` :option:`-B` - :const:`no_user_site` :option:`-s` - :const:`no_site` :option:`-S` - :const:`ignore_environment` :option:`-E` - :const:`verbose` :option:`-v` - :const:`bytes_warning` :option:`-b` - :const:`quiet` :option:`-q` - :const:`hash_randomization` :option:`-R` - :const:`dev_mode` :option:`-X dev <-X>` (:ref:`Python Development Mode <devmode>`) - :const:`utf8_mode` :option:`-X utf8 <-X>` - :const:`safe_path` :option:`-P` - :const:`int_max_str_digits` :option:`-X int_max_str_digits <-X>` (:ref:`integer string conversion length limitation <int_max_str_digits>`) - ============================= ============================================================================================================== + .. list-table:: + + * - .. attribute:: flags.debug + - :option:`-d` + + * - .. attribute:: flags.inspect + - :option:`-i` + + * - .. attribute:: flags.interactive + - :option:`-i` + + * - .. attribute:: flags.isolated + - :option:`-I` + + * - .. attribute:: flags.optimize + - :option:`-O` or :option:`-OO` + + * - .. attribute:: flags.dont_write_bytecode + - :option:`-B` + + * - .. attribute:: flags.no_user_site + - :option:`-s` + + * - .. attribute:: flags.no_site + - :option:`-S` + + * - .. attribute:: flags.ignore_environment + - :option:`-E` + + * - .. attribute:: flags.verbose + - :option:`-v` + + * - .. attribute:: flags.bytes_warning + - :option:`-b` + + * - .. attribute:: flags.quiet + - :option:`-q` + + * - .. attribute:: flags.hash_randomization + - :option:`-R` + + * - .. attribute:: flags.dev_mode + - :option:`-X dev <-X>` (:ref:`Python Development Mode <devmode>`) + + * - .. attribute:: flags.utf8_mode + - :option:`-X utf8 <-X>` + + * - .. attribute:: flags.safe_path + - :option:`-P` + + * - .. attribute:: flags.int_max_str_digits + - :option:`-X int_max_str_digits <-X>` + (:ref:`integer string conversion length limitation <int_max_str_digits>`) + + * - .. attribute:: flags.warn_default_encoding + - :option:`-X warn_default_encoding <-X>` .. versionchanged:: 3.2 Added ``quiet`` attribute for the new :option:`-q` flag. @@ -550,6 +587,9 @@ always available. Mode <devmode>` and the ``utf8_mode`` attribute for the new :option:`-X` ``utf8`` flag. + .. versionchanged:: 3.10 + Added ``warn_default_encoding`` attribute for :option:`-X` ``warn_default_encoding`` flag. + .. versionchanged:: 3.11 Added the ``safe_path`` attribute for :option:`-P` option. @@ -566,55 +606,82 @@ always available. programming language; see section 5.2.4.2.2 of the 1999 ISO/IEC C standard [C99]_, 'Characteristics of floating types', for details. - .. tabularcolumns:: |l|l|L| - - +---------------------+----------------+--------------------------------------------------+ - | attribute | float.h macro | explanation | - +=====================+================+==================================================+ - | :const:`epsilon` | DBL_EPSILON | difference between 1.0 and the least value | - | | | greater than 1.0 that is representable as a float| - | | | | - | | | See also :func:`math.ulp`. | - +---------------------+----------------+--------------------------------------------------+ - | :const:`dig` | DBL_DIG | maximum number of decimal digits that can be | - | | | faithfully represented in a float; see below | - +---------------------+----------------+--------------------------------------------------+ - | :const:`mant_dig` | DBL_MANT_DIG | float precision: the number of base-``radix`` | - | | | digits in the significand of a float | - +---------------------+----------------+--------------------------------------------------+ - | :const:`max` | DBL_MAX | maximum representable positive finite float | - +---------------------+----------------+--------------------------------------------------+ - | :const:`max_exp` | DBL_MAX_EXP | maximum integer *e* such that ``radix**(e-1)`` is| - | | | a representable finite float | - +---------------------+----------------+--------------------------------------------------+ - | :const:`max_10_exp` | DBL_MAX_10_EXP | maximum integer *e* such that ``10**e`` is in the| - | | | range of representable finite floats | - +---------------------+----------------+--------------------------------------------------+ - | :const:`min` | DBL_MIN | minimum representable positive *normalized* float| - | | | | - | | | Use :func:`math.ulp(0.0) <math.ulp>` to get the | - | | | smallest positive *denormalized* representable | - | | | float. | - +---------------------+----------------+--------------------------------------------------+ - | :const:`min_exp` | DBL_MIN_EXP | minimum integer *e* such that ``radix**(e-1)`` is| - | | | a normalized float | - +---------------------+----------------+--------------------------------------------------+ - | :const:`min_10_exp` | DBL_MIN_10_EXP | minimum integer *e* such that ``10**e`` is a | - | | | normalized float | - +---------------------+----------------+--------------------------------------------------+ - | :const:`radix` | FLT_RADIX | radix of exponent representation | - +---------------------+----------------+--------------------------------------------------+ - | :const:`rounds` | FLT_ROUNDS | integer constant representing the rounding mode | - | | | used for arithmetic operations. This reflects | - | | | the value of the system FLT_ROUNDS macro at | - | | | interpreter startup time. See section 5.2.4.2.2 | - | | | of the C99 standard for an explanation of the | - | | | possible values and their meanings. | - +---------------------+----------------+--------------------------------------------------+ + .. list-table:: Attributes of the :data:`!float_info` :term:`named tuple` + :header-rows: 1 + + * - attribute + - float.h macro + - explanation + + * - .. attribute:: float_info.epsilon + - :c:macro:`!DBL_EPSILON` + - difference between 1.0 and the least value greater than 1.0 that is + representable as a float. + + See also :func:`math.ulp`. + + * - .. attribute:: float_info.dig + - :c:macro:`!DBL_DIG` + - The maximum number of decimal digits that can be faithfully + represented in a float; see below. + + * - .. attribute:: float_info.mant_dig + - :c:macro:`!DBL_MANT_DIG` + - Float precision: the number of base-``radix`` digits in the + significand of a float. + + * - .. attribute:: float_info.max + - :c:macro:`!DBL_MAX` + - The maximum representable positive finite float. + + * - .. attribute:: float_info.max_exp + - :c:macro:`!DBL_MAX_EXP` + - The maximum integer *e* such that ``radix**(e-1)`` is a representable + finite float. + + * - .. attribute:: float_info.max_10_exp + - :c:macro:`!DBL_MAX_10_EXP` + - The maximum integer *e* such that ``10**e`` is in the range of + representable finite floats. + + * - .. attribute:: float_info.min + - :c:macro:`!DBL_MIN` + - The minimum representable positive *normalized* float. + + Use :func:`math.ulp(0.0) <math.ulp>` to get the smallest positive + *denormalized* representable float. + + * - .. attribute:: float_info.min_exp + - :c:macro:`!DBL_MIN_EXP` + - The minimum integer *e* such that ``radix**(e-1)`` is a normalized + float. + + * - .. attribute:: float_info.min_10_exp + - :c:macro:`!DBL_MIN_10_EXP` + - The minimum integer *e* such that ``10**e`` is a normalized float. + + * - .. attribute:: float_info.radix + - :c:macro:`!FLT_RADIX` + - The radix of exponent representation. + + * - .. attribute:: float_info.rounds + - :c:macro:`!FLT_ROUNDS` + - An integer representing the rounding mode for floating-point arithmetic. + This reflects the value of the system :c:macro:`!FLT_ROUNDS` macro + at interpreter startup time: + + * ``-1``: indeterminable + * ``0``: toward zero + * ``1``: to nearest + * ``2``: toward positive infinity + * ``3``: toward negative infinity + + All other values for :c:macro:`!FLT_ROUNDS` characterize + implementation-defined rounding behavior. The attribute :attr:`sys.float_info.dig` needs further explanation. If ``s`` is any string representing a decimal number with at most - :attr:`sys.float_info.dig` significant digits, then converting ``s`` to a + :attr:`!sys.float_info.dig` significant digits, then converting ``s`` to a float and back again will recover a string representing the same decimal value:: @@ -660,6 +727,13 @@ always available. .. versionadded:: 3.4 +.. function:: getunicodeinternedsize() + + Return the number of unicode objects that have been interned. + + .. versionadded:: 3.12 + + .. function:: getandroidapilevel() Return the build time API version of Android as an integer. @@ -679,8 +753,8 @@ always available. Return the current value of the flags that are used for :c:func:`dlopen` calls. Symbolic names for the flag values can be - found in the :mod:`os` module (``RTLD_xxx`` constants, e.g. - :data:`os.RTLD_LAZY`). + found in the :mod:`os` module (:samp:`RTLD_{xxx}` constants, e.g. + :const:`os.RTLD_LAZY`). .. availability:: Unix. @@ -691,7 +765,7 @@ always available. the encoding used with the :term:`filesystem error handler <filesystem encoding and error handler>` to convert between Unicode filenames and bytes filenames. The filesystem error handler is returned from - :func:`getfilesystemencoding`. + :func:`getfilesystemencodeerrors`. For best compatibility, str should be used for filenames in all cases, although representing filenames as bytes is also supported. Functions @@ -749,6 +823,15 @@ always available. higher than you might expect, because it includes the (temporary) reference as an argument to :func:`getrefcount`. + Note that the returned value may not actually reflect how many + references to the object are actually held. For example, some + objects are "immortal" and have a very high refcount that does not + reflect the actual number of references. Consequently, do not rely + on the returned value to be accurate, other than a value of 0 or 1. + + .. versionchanged:: 3.12 + Immortal objects have very large refcounts that do not match + the actual number of references to the object. .. function:: getrecursionlimit() @@ -775,7 +858,7 @@ always available. additional garbage collector overhead if the object is managed by the garbage collector. - See `recursive sizeof recipe <https://code.activestate.com/recipes/577504>`_ + See `recursive sizeof recipe <https://code.activestate.com/recipes/577504/>`_ for an example of using :func:`getsizeof` recursively to find the size of containers and all their contents. @@ -802,6 +885,22 @@ always available. It is not guaranteed to exist in all implementations of Python. +.. function:: _getframemodulename([depth]) + + Return the name of a module from the call stack. If optional integer *depth* + is given, return the module that many calls below the top of the stack. If + that is deeper than the call stack, or if the module is unidentifiable, + ``None`` is returned. The default for *depth* is zero, returning the + module at the top of the call stack. + + .. audit-event:: sys._getframemodulename depth sys._getframemodulename + + .. impl-detail:: + + This function should be used for internal and specialized purposes only. + It is not guaranteed to exist in all implementations of Python. + + .. function:: getprofile() .. index:: @@ -840,24 +939,24 @@ always available. ``sys.getwindowsversion().major``. For compatibility with prior versions, only the first 5 elements are retrievable by indexing. - *platform* will be :const:`2 (VER_PLATFORM_WIN32_NT)`. + *platform* will be ``2`` (VER_PLATFORM_WIN32_NT). *product_type* may be one of the following values: +---------------------------------------+---------------------------------+ | Constant | Meaning | +=======================================+=================================+ - | :const:`1 (VER_NT_WORKSTATION)` | The system is a workstation. | + | ``1`` (VER_NT_WORKSTATION) | The system is a workstation. | +---------------------------------------+---------------------------------+ - | :const:`2 (VER_NT_DOMAIN_CONTROLLER)` | The system is a domain | + | ``2`` (VER_NT_DOMAIN_CONTROLLER) | The system is a domain | | | controller. | +---------------------------------------+---------------------------------+ - | :const:`3 (VER_NT_SERVER)` | The system is a server, but not | + | ``3`` (VER_NT_SERVER) | The system is a server, but not | | | a domain controller. | +---------------------------------------+---------------------------------+ - This function wraps the Win32 :c:func:`GetVersionEx` function; see the - Microsoft documentation on :c:func:`OSVERSIONINFOEX` for more information + This function wraps the Win32 :c:func:`!GetVersionEx` function; see the + Microsoft documentation on :c:func:`!OSVERSIONINFOEX` for more information about these fields. *platform_version* returns the major version, minor version and @@ -915,28 +1014,37 @@ always available. implementation. For more details about hashing of numeric types, see :ref:`numeric-hash`. - +---------------------+--------------------------------------------------+ - | attribute | explanation | - +=====================+==================================================+ - | :const:`width` | width in bits used for hash values | - +---------------------+--------------------------------------------------+ - | :const:`modulus` | prime modulus P used for numeric hash scheme | - +---------------------+--------------------------------------------------+ - | :const:`inf` | hash value returned for a positive infinity | - +---------------------+--------------------------------------------------+ - | :const:`nan` | (this attribute is no longer used) | - +---------------------+--------------------------------------------------+ - | :const:`imag` | multiplier used for the imaginary part of a | - | | complex number | - +---------------------+--------------------------------------------------+ - | :const:`algorithm` | name of the algorithm for hashing of str, bytes, | - | | and memoryview | - +---------------------+--------------------------------------------------+ - | :const:`hash_bits` | internal output size of the hash algorithm | - +---------------------+--------------------------------------------------+ - | :const:`seed_bits` | size of the seed key of the hash algorithm | - +---------------------+--------------------------------------------------+ + .. attribute:: hash_info.width + + The width in bits used for hash values + + .. attribute:: hash_info.modulus + + The prime modulus P used for numeric hash scheme + + .. attribute:: hash_info.inf + + The hash value returned for a positive infinity + + .. attribute:: hash_info.nan + + (This attribute is no longer used) + + .. attribute:: hash_info.imag + + The multiplier used for the imaginary part of a complex number + + .. attribute:: hash_info.algorithm + + The name of the algorithm for hashing of str, bytes, and memoryview + + .. attribute:: hash_info.hash_bits + + The internal output size of the hash algorithm + .. attribute:: hash_info.seed_bits + + The size of the seed key of the hash algorithm .. versionadded:: 3.2 @@ -1014,32 +1122,31 @@ always available. A :term:`named tuple` that holds information about Python's internal representation of integers. The attributes are read only. - .. tabularcolumns:: |l|L| - - +----------------------------------------+-----------------------------------------------+ - | Attribute | Explanation | - +========================================+===============================================+ - | :const:`bits_per_digit` | number of bits held in each digit. Python | - | | integers are stored internally in base | - | | ``2**int_info.bits_per_digit`` | - +----------------------------------------+-----------------------------------------------+ - | :const:`sizeof_digit` | size in bytes of the C type used to | - | | represent a digit | - +----------------------------------------+-----------------------------------------------+ - | :const:`default_max_str_digits` | default value for | - | | :func:`sys.get_int_max_str_digits` when it | - | | is not otherwise explicitly configured. | - +----------------------------------------+-----------------------------------------------+ - | :const:`str_digits_check_threshold` | minimum non-zero value for | - | | :func:`sys.set_int_max_str_digits`, | - | | :envvar:`PYTHONINTMAXSTRDIGITS`, or | - | | :option:`-X int_max_str_digits <-X>`. | - +----------------------------------------+-----------------------------------------------+ + .. attribute:: int_info.bits_per_digit + + The number of bits held in each digit. + Python integers are stored internally in base ``2**int_info.bits_per_digit``. + + .. attribute:: int_info.sizeof_digit + + The size in bytes of the C type used to represent a digit. + + .. attribute:: int_info.default_max_str_digits + + The default value for :func:`sys.get_int_max_str_digits` + when it is not otherwise explicitly configured. + + .. attribute:: int_info.str_digits_check_threshold + + The minimum non-zero value for :func:`sys.set_int_max_str_digits`, + :envvar:`PYTHONINTMAXSTRDIGITS`, or :option:`-X int_max_str_digits <-X>`. .. versionadded:: 3.1 .. versionchanged:: 3.11 - Added ``default_max_str_digits`` and ``str_digits_check_threshold``. + + Added :attr:`~int_info.default_max_str_digits` and + :attr:`~int_info.str_digits_check_threshold`. .. data:: __interactivehook__ @@ -1080,22 +1187,25 @@ always available. .. versionadded:: 3.5 +.. data:: last_exc + + This variable is not always defined; it is set to the exception instance + when an exception is not handled and the interpreter prints an error message + and a stack traceback. Its intended use is to allow an interactive user to + import a debugger module and engage in post-mortem debugging without having + to re-execute the command that caused the error. (Typical use is + ``import pdb; pdb.pm()`` to enter the post-mortem debugger; see :mod:`pdb` + module for more information.) + + .. versionadded:: 3.12 .. data:: last_type last_value last_traceback - These three variables are not always defined; they are set when an exception is - not handled and the interpreter prints an error message and a stack traceback. - Their intended use is to allow an interactive user to import a debugger module - and engage in post-mortem debugging without having to re-execute the command - that caused the error. (Typical use is ``import pdb; pdb.pm()`` to enter the - post-mortem debugger; see :mod:`pdb` module for - more information.) - - The meaning of the variables is the same as that of the return values from - :func:`exc_info` above. - + These three variables are deprecated; use :data:`sys.last_exc` instead. + They hold the legacy representation of ``sys.last_exc``, as returned + from :func:`exc_info` above. .. data:: maxsize @@ -1141,7 +1251,7 @@ always available. :term:`Module specs <module spec>` were introduced in Python 3.4, by :pep:`451`. Earlier versions of Python looked for a method called - :meth:`~importlib.abc.MetaPathFinder.find_module`. + :meth:`!find_module`. This is still called as a fallback if a :data:`meta_path` entry doesn't have a :meth:`~importlib.abc.MetaPathFinder.find_spec` method. @@ -1217,10 +1327,6 @@ always available. Originally specified in :pep:`302`. - .. versionchanged:: 3.3 - ``None`` is stored instead of :class:`imp.NullImporter` when no finder - is found. - .. data:: platform @@ -1255,20 +1361,20 @@ always available. ================ =========================== .. versionchanged:: 3.3 - On Linux, :attr:`sys.platform` doesn't contain the major version anymore. + On Linux, :data:`sys.platform` doesn't contain the major version anymore. It is always ``'linux'``, instead of ``'linux2'`` or ``'linux3'``. Since older Python versions include the version number, it is recommended to always use the ``startswith`` idiom presented above. .. versionchanged:: 3.8 - On AIX, :attr:`sys.platform` doesn't contain the major version anymore. + On AIX, :data:`sys.platform` doesn't contain the major version anymore. It is always ``'aix'``, instead of ``'aix5'`` or ``'aix7'``. Since older Python versions include the version number, it is recommended to always use the ``startswith`` idiom presented above. .. seealso:: - :attr:`os.name` has a coarser granularity. :func:`os.uname` gives + :data:`os.name` has a coarser granularity. :func:`os.uname` gives system-dependent version information. The :mod:`platform` module provides detailed checks for the @@ -1301,7 +1407,7 @@ always available. A string giving the site-specific directory prefix where the platform independent Python files are installed; on Unix, the default is - ``'/usr/local'``. This can be set at build time with the ``--prefix`` + :file:`/usr/local`. This can be set at build time with the :option:`--prefix` argument to the :program:`configure` script. See :ref:`installation_paths` for derived paths. @@ -1335,8 +1441,8 @@ always available. lazy resolving of symbols when importing a module, if called as ``sys.setdlopenflags(0)``. To share symbols across extension modules, call as ``sys.setdlopenflags(os.RTLD_GLOBAL)``. Symbolic names for the flag values - can be found in the :mod:`os` module (``RTLD_xxx`` constants, e.g. - :data:`os.RTLD_LAZY`). + can be found in the :mod:`os` module (:samp:`RTLD_{xxx}` constants, e.g. + :const:`os.RTLD_LAZY`). .. availability:: Unix. @@ -1467,7 +1573,7 @@ always available. :file:`Objects/lnotab_notes.txt` for a detailed explanation of how this works. Per-line events may be disabled for a frame by setting - :attr:`f_trace_lines` to :const:`False` on that frame. + :attr:`!f_trace_lines` to :const:`False` on that :ref:`frame <frame-objects>`. ``'return'`` A function (or other code block) is about to return. The local trace @@ -1485,8 +1591,8 @@ always available. opcode details). The local trace function is called; *arg* is ``None``; the return value specifies the new local trace function. Per-opcode events are not emitted by default: they must be explicitly - requested by setting :attr:`f_trace_opcodes` to :const:`True` on the - frame. + requested by setting :attr:`!f_trace_opcodes` to :const:`True` on the + :ref:`frame <frame-objects>`. Note that as an exception is propagated down the chain of callers, an ``'exception'`` event is generated at each level. @@ -1515,8 +1621,8 @@ always available. .. versionchanged:: 3.7 - ``'opcode'`` event type added; :attr:`f_trace_lines` and - :attr:`f_trace_opcodes` attributes added to frames + ``'opcode'`` event type added; :attr:`!f_trace_lines` and + :attr:`!f_trace_opcodes` attributes added to frames .. function:: set_asyncgen_hooks(firstiter, finalizer) @@ -1564,6 +1670,38 @@ always available. This function has been added on a provisional basis (see :pep:`411` for details.) Use it only for debugging purposes. +.. function:: activate_stack_trampoline(backend, /) + + Activate the stack profiler trampoline *backend*. + The only supported backend is ``"perf"``. + + .. availability:: Linux. + + .. versionadded:: 3.12 + + .. seealso:: + + * :ref:`perf_profiling` + * https://perf.wiki.kernel.org + +.. function:: deactivate_stack_trampoline() + + Deactivate the current stack profiler trampoline backend. + + If no stack profiler is activated, this function has no effect. + + .. availability:: Linux. + + .. versionadded:: 3.12 + +.. function:: is_stack_trampoline_active() + + Return ``True`` if a stack profiler trampoline is active. + + .. availability:: Linux. + + .. versionadded:: 3.12 + .. function:: _enablelegacywindowsfsencoding() Changes the :term:`filesystem encoding and error handler` to 'mbcs' and @@ -1641,7 +1779,7 @@ always available. However, if you are writing a library (and do not control in which context its code will be executed), be aware that the standard streams may be replaced with file-like objects like :class:`io.StringIO` which - do not support the :attr:`~io.BufferedIOBase.buffer` attribute. + do not support the :attr:!buffer` attribute. .. data:: __stdin__ @@ -1679,7 +1817,7 @@ always available. ``email.mime`` sub-package and the ``email.message`` sub-module are not listed. - See also the :attr:`sys.builtin_module_names` list. + See also the :data:`sys.builtin_module_names` list. .. versionadded:: 3.10 @@ -1689,29 +1827,28 @@ always available. A :term:`named tuple` holding information about the thread implementation. - .. tabularcolumns:: |l|p{0.7\linewidth}| - - +------------------+---------------------------------------------------------+ - | Attribute | Explanation | - +==================+=========================================================+ - | :const:`name` | Name of the thread implementation: | - | | | - | | * ``'nt'``: Windows threads | - | | * ``'pthread'``: POSIX threads | - | | * ``'pthread-stubs'``: stub POSIX threads | - | | (on WebAssembly platforms without threading support) | - | | * ``'solaris'``: Solaris threads | - +------------------+---------------------------------------------------------+ - | :const:`lock` | Name of the lock implementation: | - | | | - | | * ``'semaphore'``: a lock uses a semaphore | - | | * ``'mutex+cond'``: a lock uses a mutex | - | | and a condition variable | - | | * ``None`` if this information is unknown | - +------------------+---------------------------------------------------------+ - | :const:`version` | Name and version of the thread library. It is a string, | - | | or ``None`` if this information is unknown. | - +------------------+---------------------------------------------------------+ + .. attribute:: thread_info.name + + The name of the thread implementation: + + * ``"nt"``: Windows threads + * ``"pthread"``: POSIX threads + * ``"pthread-stubs"``: stub POSIX threads + (on WebAssembly platforms without threading support) + * ``"solaris"``: Solaris threads + + .. attribute:: thread_info.lock + + The name of the lock implementation: + + * ``"semaphore"``: a lock uses a semaphore + * ``"mutex+cond"``: a lock uses a mutex and a condition variable + * ``None`` if this information is unknown + + .. attribute:: thread_info.version + + The name and version of the thread library. + It is a string, or ``None`` if this information is unknown. .. versionadded:: 3.3 @@ -1734,35 +1871,39 @@ always available. The *unraisable* argument has the following attributes: - * *exc_type*: Exception type. - * *exc_value*: Exception value, can be ``None``. - * *exc_traceback*: Exception traceback, can be ``None``. - * *err_msg*: Error message, can be ``None``. - * *object*: Object causing the exception, can be ``None``. + * :attr:`!exc_type`: Exception type. + * :attr:`!exc_value`: Exception value, can be ``None``. + * :attr:`!exc_traceback`: Exception traceback, can be ``None``. + * :attr:`!err_msg`: Error message, can be ``None``. + * :attr:`!object`: Object causing the exception, can be ``None``. - The default hook formats *err_msg* and *object* as: + The default hook formats :attr:`!err_msg` and :attr:`!object` as: ``f'{err_msg}: {object!r}'``; use "Exception ignored in" error message - if *err_msg* is ``None``. + if :attr:`!err_msg` is ``None``. :func:`sys.unraisablehook` can be overridden to control how unraisable exceptions are handled. - Storing *exc_value* using a custom hook can create a reference cycle. It - should be cleared explicitly to break the reference cycle when the - exception is no longer needed. + .. seealso:: + + :func:`excepthook` which handles uncaught exceptions. - Storing *object* using a custom hook can resurrect it if it is set to an - object which is being finalized. Avoid storing *object* after the custom - hook completes to avoid resurrecting objects. + .. warning:: - See also :func:`excepthook` which handles uncaught exceptions. + Storing :attr:`!exc_value` using a custom hook can create a reference cycle. + It should be cleared explicitly to break the reference cycle when the + exception is no longer needed. + + Storing :attr:`!object` using a custom hook can resurrect it if it is set to an + object which is being finalized. Avoid storing :attr:`!object` after the custom + hook completes to avoid resurrecting objects. .. audit-event:: sys.unraisablehook hook,unraisable sys.unraisablehook Raise an auditing event ``sys.unraisablehook`` with arguments - ``hook``, ``unraisable`` when an exception that cannot be handled occurs. - The ``unraisable`` object is the same as what will be passed to the hook. - If no hook has been set, ``hook`` may be ``None``. + *hook*, *unraisable* when an exception that cannot be handled occurs. + The *unraisable* object is the same as what will be passed to the hook. + If no hook has been set, *hook* may be ``None``. .. versionadded:: 3.8 @@ -1812,6 +1953,13 @@ always available. .. availability:: Windows. +.. data:: monitoring + :noindex: + + Namespace containing functions and constants for register callbacks + and controlling monitoring events. + See :mod:`sys.monitoring` for details. + .. data:: _xoptions A dictionary of the various implementation-specific flags passed through diff --git a/Doc/library/sysconfig.rst b/Doc/library/sysconfig.rst index 0049b663..e5ed45b8 100644 --- a/Doc/library/sysconfig.rst +++ b/Doc/library/sysconfig.rst @@ -20,12 +20,13 @@ The :mod:`sysconfig` module provides access to Python's configuration information like the list of installation paths and the configuration variables relevant for the current platform. + Configuration variables ----------------------- A Python distribution contains a :file:`Makefile` and a :file:`pyconfig.h` header file that are necessary to build both the Python binary itself and -third-party C extensions compiled using :mod:`distutils`. +third-party C extensions compiled using ``setuptools``. :mod:`sysconfig` puts all variables found in these files in a dictionary that can be accessed using :func:`get_config_vars` or :func:`get_config_var`. @@ -60,6 +61,7 @@ Example of usage:: >>> sysconfig.get_config_vars('AR', 'CXX') ['ar', 'g++'] + .. _installation_paths: Installation paths @@ -68,29 +70,26 @@ Installation paths Python uses an installation scheme that differs depending on the platform and on the installation options. These schemes are stored in :mod:`sysconfig` under unique identifiers based on the value returned by :const:`os.name`. - -Every new component that is installed using :mod:`distutils` or a -Distutils-based system will follow the same scheme to copy its file in the right -places. +The schemes are used by package installers to determine where to copy files to. Python currently supports nine schemes: - *posix_prefix*: scheme for POSIX platforms like Linux or macOS. This is the default scheme used when Python or a component is installed. -- *posix_home*: scheme for POSIX platforms used when a *home* option is used - upon installation. This scheme is used when a component is installed through - Distutils with a specific home prefix. -- *posix_user*: scheme for POSIX platforms used when a component is installed - through Distutils and the *user* option is used. This scheme defines paths - located under the user home directory. +- *posix_home*: scheme for POSIX platforms, when the *home* option is used. + This scheme defines paths located under a specific home prefix. +- *posix_user*: scheme for POSIX platforms, when the *user* option is used. + This scheme defines paths located under the user's home directory + (:const:`site.USER_BASE`). - *posix_venv*: scheme for :mod:`Python virtual environments <venv>` on POSIX - platforms; by default it is the same as *posix_prefix* . -- *nt*: scheme for NT platforms like Windows. -- *nt_user*: scheme for NT platforms, when the *user* option is used. -- *nt_venv*: scheme for :mod:`Python virtual environments <venv>` on NT - platforms; by default it is the same as *nt* . -- *venv*: a scheme with values from ether *posix_venv* or *nt_venv* depending - on the platform Python runs on + platforms; by default it is the same as *posix_prefix*. +- *nt*: scheme for Windows. + This is the default scheme used when Python or a component is installed. +- *nt_user*: scheme for Windows, when the *user* option is used. +- *nt_venv*: scheme for :mod:`Python virtual environments <venv>` on Windows; + by default it is the same as *nt*. +- *venv*: a scheme with values from either *posix_venv* or *nt_venv* depending + on the platform Python runs on. - *osx_framework_user*: scheme for macOS, when the *user* option is used. Each scheme is itself composed of a series of paths and each path has a unique @@ -101,7 +100,7 @@ identifier. Python currently uses eight paths: - *platstdlib*: directory containing the standard Python library files that are platform-specific. - *platlib*: directory for site-specific, platform-specific files. -- *purelib*: directory for site-specific, non-platform-specific files. +- *purelib*: directory for site-specific, non-platform-specific files ('pure' Python). - *include*: directory for non-platform-specific header files for the Python C-API. - *platinclude*: directory for platform-specific header files for @@ -109,7 +108,157 @@ identifier. Python currently uses eight paths: - *scripts*: directory for script files. - *data*: directory for data files. -:mod:`sysconfig` provides some functions to determine these paths. + +.. _sysconfig-user-scheme: + +User scheme +--------------- + +This scheme is designed to be the most convenient solution for users that don't +have write permission to the global site-packages directory or don't want to +install into it. + +Files will be installed into subdirectories of :const:`site.USER_BASE` (written +as :file:`{userbase}` hereafter). This scheme installs pure Python modules and +extension modules in the same location (also known as :const:`site.USER_SITE`). + +``posix_user`` +^^^^^^^^^^^^^^ + +============== =========================================================== +Path Installation directory +============== =========================================================== +*stdlib* :file:`{userbase}/lib/python{X.Y}` +*platstdlib* :file:`{userbase}/lib/python{X.Y}` +*platlib* :file:`{userbase}/lib/python{X.Y}/site-packages` +*purelib* :file:`{userbase}/lib/python{X.Y}/site-packages` +*include* :file:`{userbase}/include/python{X.Y}` +*scripts* :file:`{userbase}/bin` +*data* :file:`{userbase}` +============== =========================================================== + +``nt_user`` +^^^^^^^^^^^ + +============== =========================================================== +Path Installation directory +============== =========================================================== +*stdlib* :file:`{userbase}\\Python{XY}` +*platstdlib* :file:`{userbase}\\Python{XY}` +*platlib* :file:`{userbase}\\Python{XY}\\site-packages` +*purelib* :file:`{userbase}\\Python{XY}\\site-packages` +*include* :file:`{userbase}\\Python{XY}\\Include` +*scripts* :file:`{userbase}\\Python{XY}\\Scripts` +*data* :file:`{userbase}` +============== =========================================================== + +``osx_framework_user`` +^^^^^^^^^^^^^^^^^^^^^^ + +============== =========================================================== +Path Installation directory +============== =========================================================== +*stdlib* :file:`{userbase}/lib/python` +*platstdlib* :file:`{userbase}/lib/python` +*platlib* :file:`{userbase}/lib/python/site-packages` +*purelib* :file:`{userbase}/lib/python/site-packages` +*include* :file:`{userbase}/include/python{X.Y}` +*scripts* :file:`{userbase}/bin` +*data* :file:`{userbase}` +============== =========================================================== + + +.. _sysconfig-home-scheme: + +Home scheme +----------- + +The idea behind the "home scheme" is that you build and maintain a personal +stash of Python modules. This scheme's name is derived from the idea of a +"home" directory on Unix, since it's not unusual for a Unix user to make their +home directory have a layout similar to :file:`/usr/` or :file:`/usr/local/`. +This scheme can be used by anyone, regardless of the operating system they +are installing for. + +``posix_home`` +^^^^^^^^^^^^^^ + +============== =========================================================== +Path Installation directory +============== =========================================================== +*stdlib* :file:`{home}/lib/python` +*platstdlib* :file:`{home}/lib/python` +*platlib* :file:`{home}/lib/python` +*purelib* :file:`{home}/lib/python` +*include* :file:`{home}/include/python` +*platinclude* :file:`{home}/include/python` +*scripts* :file:`{home}/bin` +*data* :file:`{home}` +============== =========================================================== + + +.. _sysconfig-prefix-scheme: + +Prefix scheme +------------- + +The "prefix scheme" is useful when you wish to use one Python installation to +perform the build/install (i.e., to run the setup script), but install modules +into the third-party module directory of a different Python installation (or +something that looks like a different Python installation). If this sounds a +trifle unusual, it is---that's why the user and home schemes come before. However, +there are at least two known cases where the prefix scheme will be useful. + +First, consider that many Linux distributions put Python in :file:`/usr`, rather +than the more traditional :file:`/usr/local`. This is entirely appropriate, +since in those cases Python is part of "the system" rather than a local add-on. +However, if you are installing Python modules from source, you probably want +them to go in :file:`/usr/local/lib/python2.{X}` rather than +:file:`/usr/lib/python2.{X}`. + +Another possibility is a network filesystem where the name used to write to a +remote directory is different from the name used to read it: for example, the +Python interpreter accessed as :file:`/usr/local/bin/python` might search for +modules in :file:`/usr/local/lib/python2.{X}`, but those modules would have to +be installed to, say, :file:`/mnt/{@server}/export/lib/python2.{X}`. + +``posix_prefix`` +^^^^^^^^^^^^^^^^ + +============== ========================================================== +Path Installation directory +============== ========================================================== +*stdlib* :file:`{prefix}/lib/python{X.Y}` +*platstdlib* :file:`{prefix}/lib/python{X.Y}` +*platlib* :file:`{prefix}/lib/python{X.Y}/site-packages` +*purelib* :file:`{prefix}/lib/python{X.Y}/site-packages` +*include* :file:`{prefix}/include/python{X.Y}` +*platinclude* :file:`{prefix}/include/python{X.Y}` +*scripts* :file:`{prefix}/bin` +*data* :file:`{prefix}` +============== ========================================================== + +``nt`` +^^^^^^ + +============== ========================================================== +Path Installation directory +============== ========================================================== +*stdlib* :file:`{prefix}\\Lib` +*platstdlib* :file:`{prefix}\\Lib` +*platlib* :file:`{prefix}\\Lib\\site-packages` +*purelib* :file:`{prefix}\\Lib\\site-packages` +*include* :file:`{prefix}\\Include` +*platinclude* :file:`{prefix}\\Include` +*scripts* :file:`{prefix}\\Scripts` +*data* :file:`{prefix}` +============== ========================================================== + + +Installation path functions +--------------------------- + +:mod:`sysconfig` provides some functions to determine these installation paths. .. function:: get_scheme_names() @@ -187,7 +336,7 @@ identifier. Python currently uses eight paths: platform is used. If *vars* is provided, it must be a dictionary of variables that will update - the dictionary return by :func:`get_config_vars`. + the dictionary returned by :func:`get_config_vars`. If *expand* is set to ``False``, the path will not be expanded using the variables. diff --git a/Doc/library/syslog.rst b/Doc/library/syslog.rst index 766ff57c..f29ef032 100644 --- a/Doc/library/syslog.rst +++ b/Doc/library/syslog.rst @@ -40,6 +40,13 @@ The module defines the following functions: it wasn't called prior to the call to :func:`syslog`, deferring to the syslog implementation to call ``openlog()``. + .. versionchanged:: 3.12 + This function is restricted in subinterpreters. + (Only code that runs in multiple interpreters is affected and + the restriction is not relevant for most users.) + :func:`openlog` must be called in the main interpreter before :func:`syslog` may be used + in a subinterpreter. Otherwise it will raise :exc:`RuntimeError`. + .. function:: openlog([ident[, logoption[, facility]]]) @@ -60,6 +67,13 @@ The module defines the following functions: In previous versions, keyword arguments were not allowed, and *ident* was required. + .. versionchanged:: 3.12 + This function is restricted in subinterpreters. + (Only code that runs in multiple interpreters is affected and + the restriction is not relevant for most users.) + This may only be called in the main interpreter. + It will raise :exc:`RuntimeError` if called in a subinterpreter. + .. function:: closelog() @@ -72,6 +86,13 @@ The module defines the following functions: .. audit-event:: syslog.closelog "" syslog.closelog + .. versionchanged:: 3.12 + This function is restricted in subinterpreters. + (Only code that runs in multiple interpreters is affected and + the restriction is not relevant for most users.) + This may only be called in the main interpreter. + It will raise :exc:`RuntimeError` if called in a subinterpreter. + .. function:: setlogmask(maskpri) diff --git a/Doc/library/tarfile.rst b/Doc/library/tarfile.rst index 96444d4e..574ea337 100644 --- a/Doc/library/tarfile.rst +++ b/Doc/library/tarfile.rst @@ -36,6 +36,13 @@ Some facts and figures: .. versionchanged:: 3.3 Added support for :mod:`lzma` compression. +.. versionchanged:: 3.12 + Archives are extracted using a :ref:`filter <tarfile-extraction-filter>`, + which makes it possible to either limit surprising/dangerous features, + or to acknowledge that they are expected and the archive is fully trusted. + By default, archives are fully trusted, but this default is deprecated + and slated to change in Python 3.14. + .. function:: open(name=None, mode='r', fileobj=None, bufsize=10240, **kwargs) @@ -98,8 +105,8 @@ Some facts and figures: If *fileobj* is specified, it is used as an alternative to a :term:`file object` opened in binary mode for *name*. It is supposed to be at position 0. - For modes ``'w:gz'``, ``'r:gz'``, ``'w:bz2'``, ``'r:bz2'``, ``'x:gz'``, - ``'x:bz2'``, :func:`tarfile.open` accepts the keyword argument + For modes ``'w:gz'``, ``'x:gz'``, ``'w|gz'``, ``'w:bz2'``, ``'x:bz2'``, + ``'w|bz2'``, :func:`tarfile.open` accepts the keyword argument *compresslevel* (default ``9``) to specify the compression level of the file. For modes ``'w:xz'`` and ``'x:xz'``, :func:`tarfile.open` accepts the @@ -152,6 +159,9 @@ Some facts and figures: .. versionchanged:: 3.6 The *name* parameter accepts a :term:`path-like object`. + .. versionchanged:: 3.12 + The *compresslevel* keyword argument also works for streams. + .. class:: TarFile :noindex: @@ -206,6 +216,38 @@ The :mod:`tarfile` module defines the following exceptions: Is raised by :meth:`TarInfo.frombuf` if the buffer it gets is invalid. +.. exception:: FilterError + + Base class for members :ref:`refused <tarfile-extraction-refuse>` by + filters. + + .. attribute:: tarinfo + + Information about the member that the filter refused to extract, + as :ref:`TarInfo <tarinfo-objects>`. + +.. exception:: AbsolutePathError + + Raised to refuse extracting a member with an absolute path. + +.. exception:: OutsideDestinationError + + Raised to refuse extracting a member outside the destination directory. + +.. exception:: SpecialFileError + + Raised to refuse extracting a special file (e.g. a device or pipe). + +.. exception:: AbsoluteLinkError + + Raised to refuse extracting a symbolic link with an absolute path. + +.. exception:: LinkOutsideDestinationError + + Raised to refuse extracting a symbolic link pointing outside the destination + directory. + + The following constants are available at the module level: .. data:: ENCODING @@ -316,11 +358,8 @@ be finalized; only the internally used file object will be closed. See the *debug* can be set from ``0`` (no debug messages) up to ``3`` (all debug messages). The messages are written to ``sys.stderr``. - If *errorlevel* is ``0``, all errors are ignored when using :meth:`TarFile.extract`. - Nevertheless, they appear as error messages in the debug output, when debugging - is enabled. If ``1``, all *fatal* errors are raised as :exc:`OSError` - exceptions. If ``2``, all *non-fatal* errors are raised as :exc:`TarError` - exceptions as well. + *errorlevel* controls how extraction errors are handled, + see :attr:`the corresponding attribute <~TarFile.errorlevel>`. The *encoding* and *errors* arguments define the character encoding to be used for reading or writing the archive and how conversion errors are going @@ -387,7 +426,7 @@ be finalized; only the internally used file object will be closed. See the available. -.. method:: TarFile.extractall(path=".", members=None, *, numeric_owner=False) +.. method:: TarFile.extractall(path=".", members=None, *, numeric_owner=False, filter=None) Extract all members from the archive to the current working directory or directory *path*. If optional *members* is given, it must be a subset of the @@ -401,6 +440,12 @@ be finalized; only the internally used file object will be closed. See the are used to set the owner/group for the extracted files. Otherwise, the named values from the tarfile are used. + The *filter* argument specifies how ``members`` are modified or rejected + before extraction. + See :ref:`tarfile-extraction-filter` for details. + It is recommended to set this explicitly depending on which *tar* features + you need to support. + .. warning:: Never extract archives from untrusted sources without prior inspection. @@ -408,14 +453,20 @@ be finalized; only the internally used file object will be closed. See the that have absolute filenames starting with ``"/"`` or filenames with two dots ``".."``. + Set ``filter='data'`` to prevent the most dangerous security issues, + and read the :ref:`tarfile-extraction-filter` section for details. + .. versionchanged:: 3.5 Added the *numeric_owner* parameter. .. versionchanged:: 3.6 The *path* parameter accepts a :term:`path-like object`. + .. versionchanged:: 3.12 + Added the *filter* parameter. + -.. method:: TarFile.extract(member, path="", set_attrs=True, *, numeric_owner=False) +.. method:: TarFile.extract(member, path="", set_attrs=True, *, numeric_owner=False, filter=None) Extract a member from the archive to the current working directory, using its full name. Its file information is extracted as accurately as possible. *member* @@ -423,9 +474,8 @@ be finalized; only the internally used file object will be closed. See the directory using *path*. *path* may be a :term:`path-like object`. File attributes (owner, mtime, mode) are set unless *set_attrs* is false. - If *numeric_owner* is :const:`True`, the uid and gid numbers from the tarfile - are used to set the owner/group for the extracted files. Otherwise, the named - values from the tarfile are used. + The *numeric_owner* and *filter* arguments are the same as + for :meth:`extractall`. .. note:: @@ -436,6 +486,9 @@ be finalized; only the internally used file object will be closed. See the See the warning for :meth:`extractall`. + Set ``filter='data'`` to prevent the most dangerous security issues, + and read the :ref:`tarfile-extraction-filter` section for details. + .. versionchanged:: 3.2 Added the *set_attrs* parameter. @@ -445,6 +498,9 @@ be finalized; only the internally used file object will be closed. See the .. versionchanged:: 3.6 The *path* parameter accepts a :term:`path-like object`. + .. versionchanged:: 3.12 + Added the *filter* parameter. + .. method:: TarFile.extractfile(member) @@ -457,6 +513,55 @@ be finalized; only the internally used file object will be closed. See the .. versionchanged:: 3.3 Return an :class:`io.BufferedReader` object. +.. attribute:: TarFile.errorlevel + :type: int + + If *errorlevel* is ``0``, errors are ignored when using :meth:`TarFile.extract` + and :meth:`TarFile.extractall`. + Nevertheless, they appear as error messages in the debug output when + *debug* is greater than 0. + If ``1`` (the default), all *fatal* errors are raised as :exc:`OSError` or + :exc:`FilterError` exceptions. If ``2``, all *non-fatal* errors are raised + as :exc:`TarError` exceptions as well. + + Some exceptions, e.g. ones caused by wrong argument types or data + corruption, are always raised. + + Custom :ref:`extraction filters <tarfile-extraction-filter>` + should raise :exc:`FilterError` for *fatal* errors + and :exc:`ExtractError` for *non-fatal* ones. + + Note that when an exception is raised, the archive may be partially + extracted. It is the user’s responsibility to clean up. + +.. attribute:: TarFile.extraction_filter + + .. versionadded:: 3.12 + + The :ref:`extraction filter <tarfile-extraction-filter>` used + as a default for the *filter* argument of :meth:`~TarFile.extract` + and :meth:`~TarFile.extractall`. + + The attribute may be ``None`` or a callable. + String names are not allowed for this attribute, unlike the *filter* + argument to :meth:`~TarFile.extract`. + + If ``extraction_filter`` is ``None`` (the default), + calling an extraction method without a *filter* argument will raise a + ``DeprecationWarning``, + and fall back to the :func:`fully_trusted <fully_trusted_filter>` filter, + whose dangerous behavior matches previous versions of Python. + + In Python 3.14+, leaving ``extraction_filter=None`` will cause + extraction methods to use the :func:`data <data_filter>` filter by default. + + The attribute may be set on instances or overridden in subclasses. + It also is possible to set it on the ``TarFile`` class itself to set a + global default, although, since it affects all uses of *tarfile*, + it is best practice to only do so in top-level applications or + :mod:`site configuration <site>`. + To set a global default this way, a filter function needs to be wrapped in + :func:`staticmethod()` to prevent injection of a ``self`` argument. .. method:: TarFile.add(name, arcname=None, recursive=True, *, filter=None) @@ -532,8 +637,23 @@ permissions, owner etc.), it provides some useful methods to determine its type. It does *not* contain the file's data itself. :class:`TarInfo` objects are returned by :class:`TarFile`'s methods -:meth:`getmember`, :meth:`getmembers` and :meth:`gettarinfo`. +:meth:`~TarFile.getmember`, :meth:`~TarFile.getmembers` and +:meth:`~TarFile.gettarinfo`. + +Modifying the objects returned by :meth:`~!TarFile.getmember` or +:meth:`~!TarFile.getmembers` will affect all subsequent +operations on the archive. +For cases where this is unwanted, you can use :mod:`copy.copy() <copy>` or +call the :meth:`~TarInfo.replace` method to create a modified copy in one step. + +Several attributes can be set to ``None`` to indicate that a piece of metadata +is unused or unknown. +Different :class:`TarInfo` methods handle ``None`` differently: +- The :meth:`~TarFile.extract` or :meth:`~TarFile.extractall` methods will + ignore the corresponding metadata, leaving it set to a default. +- :meth:`~TarFile.addfile` will fail. +- :meth:`~TarFile.list` will print a placeholder string. .. class:: TarInfo(name="") @@ -566,24 +686,39 @@ A ``TarInfo`` object has the following public data attributes: .. attribute:: TarInfo.name + :type: str Name of the archive member. .. attribute:: TarInfo.size + :type: int Size in bytes. .. attribute:: TarInfo.mtime + :type: int | float - Time of last modification. + Time of last modification in seconds since the :ref:`epoch <epoch>`, + as in :attr:`os.stat_result.st_mtime`. + .. versionchanged:: 3.12 + + Can be set to ``None`` for :meth:`~TarFile.extract` and + :meth:`~TarFile.extractall`, causing extraction to skip applying this + attribute. .. attribute:: TarInfo.mode + :type: int + + Permission bits, as for :func:`os.chmod`. - Permission bits. + .. versionchanged:: 3.12 + Can be set to ``None`` for :meth:`~TarFile.extract` and + :meth:`~TarFile.extractall`, causing extraction to skip applying this + attribute. .. attribute:: TarInfo.type @@ -595,35 +730,81 @@ A ``TarInfo`` object has the following public data attributes: .. attribute:: TarInfo.linkname + :type: str Name of the target file name, which is only present in :class:`TarInfo` objects of type :const:`LNKTYPE` and :const:`SYMTYPE`. + For symbolic links (``SYMTYPE``), the *linkname* is relative to the directory + that contains the link. + For hard links (``LNKTYPE``), the *linkname* is relative to the root of + the archive. + .. attribute:: TarInfo.uid + :type: int User ID of the user who originally stored this member. + .. versionchanged:: 3.12 + + Can be set to ``None`` for :meth:`~TarFile.extract` and + :meth:`~TarFile.extractall`, causing extraction to skip applying this + attribute. .. attribute:: TarInfo.gid + :type: int Group ID of the user who originally stored this member. + .. versionchanged:: 3.12 + + Can be set to ``None`` for :meth:`~TarFile.extract` and + :meth:`~TarFile.extractall`, causing extraction to skip applying this + attribute. .. attribute:: TarInfo.uname + :type: str User name. + .. versionchanged:: 3.12 + + Can be set to ``None`` for :meth:`~TarFile.extract` and + :meth:`~TarFile.extractall`, causing extraction to skip applying this + attribute. .. attribute:: TarInfo.gname + :type: str Group name. + .. versionchanged:: 3.12 + + Can be set to ``None`` for :meth:`~TarFile.extract` and + :meth:`~TarFile.extractall`, causing extraction to skip applying this + attribute. .. attribute:: TarInfo.pax_headers + :type: dict A dictionary containing key-value pairs of an associated pax extended header. +.. method:: TarInfo.replace(name=..., mtime=..., mode=..., linkname=..., + uid=..., gid=..., uname=..., gname=..., + deep=True) + + .. versionadded:: 3.12 + + Return a *new* copy of the :class:`!TarInfo` object with the given attributes + changed. For example, to return a ``TarInfo`` with the group name set to + ``'staff'``, use:: + + new_tarinfo = old_tarinfo.replace(gname='staff') + + By default, a deep copy is made. + If *deep* is false, the copy is shallow, i.e. ``pax_headers`` + and any custom attributes are shared with the original ``TarInfo`` object. A :class:`TarInfo` object also provides some convenient query methods: @@ -673,9 +854,258 @@ A :class:`TarInfo` object also provides some convenient query methods: Return :const:`True` if it is one of character device, block device or FIFO. +.. _tarfile-extraction-filter: + +Extraction filters +------------------ + +.. versionadded:: 3.12 + +The *tar* format is designed to capture all details of a UNIX-like filesystem, +which makes it very powerful. +Unfortunately, the features make it easy to create tar files that have +unintended -- and possibly malicious -- effects when extracted. +For example, extracting a tar file can overwrite arbitrary files in various +ways (e.g. by using absolute paths, ``..`` path components, or symlinks that +affect later members). + +In most cases, the full functionality is not needed. +Therefore, *tarfile* supports extraction filters: a mechanism to limit +functionality, and thus mitigate some of the security issues. + +.. seealso:: + + :pep:`706` + Contains further motivation and rationale behind the design. + +The *filter* argument to :meth:`TarFile.extract` or :meth:`~TarFile.extractall` +can be: + +* the string ``'fully_trusted'``: Honor all metadata as specified in the + archive. + Should be used if the user trusts the archive completely, or implements + their own complex verification. + +* the string ``'tar'``: Honor most *tar*-specific features (i.e. features of + UNIX-like filesystems), but block features that are very likely to be + surprising or malicious. See :func:`tar_filter` for details. + +* the string ``'data'``: Ignore or block most features specific to UNIX-like + filesystems. Intended for extracting cross-platform data archives. + See :func:`data_filter` for details. + +* ``None`` (default): Use :attr:`TarFile.extraction_filter`. + + If that is also ``None`` (the default), raise a ``DeprecationWarning``, + and fall back to the ``'fully_trusted'`` filter, whose dangerous behavior + matches previous versions of Python. + + In Python 3.14, the ``'data'`` filter will become the default instead. + It's possible to switch earlier; see :attr:`TarFile.extraction_filter`. + +* A callable which will be called for each extracted member with a + :ref:`TarInfo <tarinfo-objects>` describing the member and the destination + path to where the archive is extracted (i.e. the same path is used for all + members):: + + filter(member: TarInfo, path: str, /) -> TarInfo | None + + The callable is called just before each member is extracted, so it can + take the current state of the disk into account. + It can: + + - return a :class:`TarInfo` object which will be used instead of the metadata + in the archive, or + - return ``None``, in which case the member will be skipped, or + - raise an exception to abort the operation or skip the member, + depending on :attr:`~TarFile.errorlevel`. + Note that when extraction is aborted, :meth:`~TarFile.extractall` may leave + the archive partially extracted. It does not attempt to clean up. + +Default named filters +~~~~~~~~~~~~~~~~~~~~~ + +The pre-defined, named filters are available as functions, so they can be +reused in custom filters: + +.. function:: fully_trusted_filter(member, path) + + Return *member* unchanged. + + This implements the ``'fully_trusted'`` filter. + +.. function:: tar_filter(member, path) + + Implements the ``'tar'`` filter. + + - Strip leading slashes (``/`` and :data:`os.sep`) from filenames. + - :ref:`Refuse <tarfile-extraction-refuse>` to extract files with absolute + paths (in case the name is absolute + even after stripping slashes, e.g. ``C:/foo`` on Windows). + This raises :class:`~tarfile.AbsolutePathError`. + - :ref:`Refuse <tarfile-extraction-refuse>` to extract files whose absolute + path (after following symlinks) would end up outside the destination. + This raises :class:`~tarfile.OutsideDestinationError`. + - Clear high mode bits (setuid, setgid, sticky) and group/other write bits + (:const:`~stat.S_IWGRP`|:const:`~stat.S_IWOTH`). + + Return the modified ``TarInfo`` member. + +.. function:: data_filter(member, path) + + Implements the ``'data'`` filter. + In addition to what ``tar_filter`` does: + + - :ref:`Refuse <tarfile-extraction-refuse>` to extract links (hard or soft) + that link to absolute paths, or ones that link outside the destination. + + This raises :class:`~tarfile.AbsoluteLinkError` or + :class:`~tarfile.LinkOutsideDestinationError`. + + Note that such files are refused even on platforms that do not support + symbolic links. + + - :ref:`Refuse <tarfile-extraction-refuse>` to extract device files + (including pipes). + This raises :class:`~tarfile.SpecialFileError`. + + - For regular files, including hard links: + + - Set the owner read and write permissions + (:const:`~stat.S_IRUSR`|:const:`~stat.S_IWUSR`). + - Remove the group & other executable permission + (:const:`~stat.S_IXGRP`|:const:`~stat.S_IXOTH`) + if the owner doesn’t have it (:const:`~stat.S_IXUSR`). + + - For other files (directories), set ``mode`` to ``None``, so + that extraction methods skip applying permission bits. + - Set user and group info (``uid``, ``gid``, ``uname``, ``gname``) + to ``None``, so that extraction methods skip setting it. + + Return the modified ``TarInfo`` member. + + +.. _tarfile-extraction-refuse: + +Filter errors +~~~~~~~~~~~~~ + +When a filter refuses to extract a file, it will raise an appropriate exception, +a subclass of :class:`~tarfile.FilterError`. +This will abort the extraction if :attr:`TarFile.errorlevel` is 1 or more. +With ``errorlevel=0`` the error will be logged and the member will be skipped, +but extraction will continue. + + +Hints for further verification +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Even with ``filter='data'``, *tarfile* is not suited for extracting untrusted +files without prior inspection. +Among other issues, the pre-defined filters do not prevent denial-of-service +attacks. Users should do additional checks. + +Here is an incomplete list of things to consider: + +* Extract to a :func:`new temporary directory <tempfile.mkdtemp>` + to prevent e.g. exploiting pre-existing links, and to make it easier to + clean up after a failed extraction. +* When working with untrusted data, use external (e.g. OS-level) limits on + disk, memory and CPU usage. +* Check filenames against an allow-list of characters + (to filter out control characters, confusables, foreign path separators, + etc.). +* Check that filenames have expected extensions (discouraging files that + execute when you “click on them”, or extension-less files like Windows special device names). +* Limit the number of extracted files, total size of extracted data, + filename length (including symlink length), and size of individual files. +* Check for files that would be shadowed on case-insensitive filesystems. + +Also note that: + +* Tar files may contain multiple versions of the same file. + Later ones are expected to overwrite any earlier ones. + This feature is crucial to allow updating tape archives, but can be abused + maliciously. +* *tarfile* does not protect against issues with “live” data, + e.g. an attacker tinkering with the destination (or source) directory while + extraction (or archiving) is in progress. + + +Supporting older Python versions +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Extraction filters were added to Python 3.12, but may be backported to older +versions as security updates. +To check whether the feature is available, use e.g. +``hasattr(tarfile, 'data_filter')`` rather than checking the Python version. + +The following examples show how to support Python versions with and without +the feature. +Note that setting ``extraction_filter`` will affect any subsequent operations. + +* Fully trusted archive:: + + my_tarfile.extraction_filter = (lambda member, path: member) + my_tarfile.extractall() + +* Use the ``'data'`` filter if available, but revert to Python 3.11 behavior + (``'fully_trusted'``) if this feature is not available:: + + my_tarfile.extraction_filter = getattr(tarfile, 'data_filter', + (lambda member, path: member)) + my_tarfile.extractall() + +* Use the ``'data'`` filter; *fail* if it is not available:: + + my_tarfile.extractall(filter=tarfile.data_filter) + + or:: + + my_tarfile.extraction_filter = tarfile.data_filter + my_tarfile.extractall() + +* Use the ``'data'`` filter; *warn* if it is not available:: + + if hasattr(tarfile, 'data_filter'): + my_tarfile.extractall(filter='data') + else: + # remove this when no longer needed + warn_the_user('Extracting may be unsafe; consider updating Python') + my_tarfile.extractall() + + +Stateful extraction filter example +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +While *tarfile*'s extraction methods take a simple *filter* callable, +custom filters may be more complex objects with an internal state. +It may be useful to write these as context managers, to be used like this:: + + with StatefulFilter() as filter_func: + tar.extractall(path, filter=filter_func) + +Such a filter can be written as, for example:: + + class StatefulFilter: + def __init__(self): + self.file_count = 0 + + def __enter__(self): + return self + + def __call__(self, member, path): + self.file_count += 1 + return member + + def __exit__(self, *exc_info): + print(f'{self.file_count} files extracted') + + .. _tarfile-commandline: .. program:: tarfile + Command-Line Interface ---------------------- @@ -745,6 +1175,13 @@ Command-line options Verbose output. +.. cmdoption:: --filter <filtername> + + Specifies the *filter* for ``--extract``. + See :ref:`tarfile-extraction-filter` for details. + Only string names are accepted (that is, ``fully_trusted``, ``tar``, + and ``data``). + .. _tar-examples: Examples @@ -754,7 +1191,7 @@ How to extract an entire tar archive to the current working directory:: import tarfile tar = tarfile.open("sample.tar.gz") - tar.extractall() + tar.extractall(filter='data') tar.close() How to extract a subset of a tar archive with :meth:`TarFile.extractall` using diff --git a/Doc/library/tempfile.rst b/Doc/library/tempfile.rst index b7e604c1..097f7087 100644 --- a/Doc/library/tempfile.rst +++ b/Doc/library/tempfile.rst @@ -59,7 +59,7 @@ The module defines the following user-callable items: platforms, it is a file-like object whose :attr:`!file` attribute is the underlying true file object. - The :py:data:`os.O_TMPFILE` flag is used if it is available and works + The :py:const:`os.O_TMPFILE` flag is used if it is available and works (Linux-specific, requires Linux kernel 3.11 or later). On platforms that are neither Posix nor Cygwin, TemporaryFile is an alias @@ -69,26 +69,67 @@ The module defines the following user-callable items: .. versionchanged:: 3.5 - The :py:data:`os.O_TMPFILE` flag is now used if available. + The :py:const:`os.O_TMPFILE` flag is now used if available. .. versionchanged:: 3.8 Added *errors* parameter. -.. function:: NamedTemporaryFile(mode='w+b', buffering=-1, encoding=None, newline=None, suffix=None, prefix=None, dir=None, delete=True, *, errors=None) - - This function operates exactly as :func:`TemporaryFile` does, except that - the file is guaranteed to have a visible name in the file system (on - Unix, the directory entry is not unlinked). That name can be retrieved - from the :attr:`name` attribute of the returned - file-like object. Whether the name can be - used to open the file a second time, while the named temporary file is - still open, varies across platforms (it can be so used on Unix; it cannot - on Windows). If *delete* is true (the default), the file is - deleted as soon as it is closed. - The returned object is always a file-like object whose :attr:`!file` - attribute is the underlying true file object. This file-like object can - be used in a :keyword:`with` statement, just like a normal file. +.. function:: NamedTemporaryFile(mode='w+b', buffering=-1, encoding=None, newline=None, suffix=None, prefix=None, dir=None, delete=True, *, errors=None, delete_on_close=True) + + This function operates exactly as :func:`TemporaryFile` does, except the + following differences: + + * This function returns a file that is guaranteed to have a visible name in + the file system. + * To manage the named file, it extends the parameters of + :func:`TemporaryFile` with *delete* and *delete_on_close* parameters that + determine whether and how the named file should be automatically deleted. + + The returned object is always a :term:`file-like object` whose :attr:`!file` + attribute is the underlying true file object. This :term:`file-like object` + can be used in a :keyword:`with` statement, just like a normal file. The + name of the temporary file can be retrieved from the :attr:`name` attribute + of the returned file-like object. On Unix, unlike with the + :func:`TemporaryFile`, the directory entry does not get unlinked immediately + after the file creation. + + If *delete* is true (the default) and *delete_on_close* is true (the + default), the file is deleted as soon as it is closed. If *delete* is true + and *delete_on_close* is false, the file is deleted on context manager exit + only, or else when the :term:`file-like object` is finalized. Deletion is not + always guaranteed in this case (see :meth:`object.__del__`). If *delete* is + false, the value of *delete_on_close* is ignored. + + Therefore to use the name of the temporary file to reopen the file after + closing it, either make sure not to delete the file upon closure (set the + *delete* parameter to be false) or, in case the temporary file is created in + a :keyword:`with` statement, set the *delete_on_close* parameter to be false. + The latter approach is recommended as it provides assistance in automatic + cleaning of the temporary file upon the context manager exit. + + Opening the temporary file again by its name while it is still open works as + follows: + + * On POSIX the file can always be opened again. + * On Windows, make sure that at least one of the following conditions are + fulfilled: + + * *delete* is false + * additional open shares delete access (e.g. by calling :func:`os.open` + with the flag ``O_TEMPORARY``) + * *delete* is true but *delete_on_close* is false. Note, that in this + case the additional opens that do not share delete access (e.g. + created via builtin :func:`open`) must be closed before exiting the + context manager, else the :func:`os.unlink` call on context manager + exit will fail with a :exc:`PermissionError`. + + On Windows, if *delete_on_close* is false, and the file is created in a + directory for which the user lacks delete access, then the :func:`os.unlink` + call on exit of the context manager will fail with a :exc:`PermissionError`. + This cannot happen when *delete_on_close* is true because delete access is + requested by the open, which fails immediately if the requested access is not + granted. On POSIX (only), a process that is terminated abruptly with SIGKILL cannot automatically delete any NamedTemporaryFiles it created. @@ -98,6 +139,9 @@ The module defines the following user-callable items: .. versionchanged:: 3.8 Added *errors* parameter. + .. versionchanged:: 3.12 + Added *delete_on_close* parameter. + .. class:: SpooledTemporaryFile(max_size=0, mode='w+b', buffering=-1, encoding=None, newline=None, suffix=None, prefix=None, dir=None, *, errors=None) @@ -129,7 +173,7 @@ The module defines the following user-callable items: or text *mode* was specified). -.. class:: TemporaryDirectory(suffix=None, prefix=None, dir=None, ignore_cleanup_errors=False) +.. class:: TemporaryDirectory(suffix=None, prefix=None, dir=None, ignore_cleanup_errors=False, *, delete=True) This class securely creates a temporary directory using the same rules as :func:`mkdtemp`. The resulting object can be used as a context manager (see @@ -151,6 +195,12 @@ The module defines the following user-callable items: (the :func:`cleanup` call, exiting the context manager, when the object is garbage-collected or during interpreter shutdown). + The *delete* parameter can be used to disable cleanup of the directory tree + upon exiting the context. While it may seem unusual for a context manager + to disable the action taken when exiting the context, it can be useful during + debugging or when you need your cleanup behavior to be conditional based on + other logic. + .. audit-event:: tempfile.mkdtemp fullpath tempfile.TemporaryDirectory .. versionadded:: 3.2 @@ -158,6 +208,9 @@ The module defines the following user-callable items: .. versionchanged:: 3.10 Added *ignore_cleanup_errors* parameter. + .. versionchanged:: 3.12 + Added the *delete* parameter. + .. function:: mkstemp(suffix=None, prefix=None, dir=None, text=False) @@ -239,6 +292,9 @@ The module defines the following user-callable items: .. versionchanged:: 3.6 The *dir* parameter now accepts a :term:`path-like object`. + .. versionchanged:: 3.12 + :func:`mkdtemp` now always returns an absolute path, even if *dir* is relative. + .. function:: gettempdir() @@ -346,6 +402,19 @@ Here are some examples of typical usage of the :mod:`tempfile` module:: >>> # file is now closed and removed + # create a temporary file using a context manager + # close the file, use the name to open the file again + >>> with tempfile.TemporaryFile(delete_on_close=False) as fp: + ... fp.write(b'Hello world!') + ... fp.close() + # the file is closed, but not removed + # open the file again by using its name + ... with open(fp.name) as f + ... f.read() + b'Hello world!' + >>> + # file is now removed + # create a temporary directory using the context manager >>> with tempfile.TemporaryDirectory() as tmpdirname: ... print('created temporary directory', tmpdirname) diff --git a/Doc/library/test.rst b/Doc/library/test.rst index 8e05ff39..de60151b 100644 --- a/Doc/library/test.rst +++ b/Doc/library/test.rst @@ -319,6 +319,15 @@ The :mod:`test.support` module defines the following constants: to make writes blocking. +.. data:: Py_DEBUG + + True if Python is built with the :c:macro:`Py_DEBUG` macro defined: if + Python is :ref:`built in debug mode <debug-build>` + (:option:`./configure --with-pydebug <--with-pydebug>`). + + .. versionadded:: 3.12 + + .. data:: SOCK_MAX_SIZE A constant that is likely larger than the underlying OS socket buffer size, @@ -404,6 +413,51 @@ The :mod:`test.support` module defines the following constants: The :mod:`test.support` module defines the following functions: +.. function:: busy_retry(timeout, err_msg=None, /, *, error=True) + + Run the loop body until ``break`` stops the loop. + + After *timeout* seconds, raise an :exc:`AssertionError` if *error* is true, + or just stop the loop if *error* is false. + + Example:: + + for _ in support.busy_retry(support.SHORT_TIMEOUT): + if check(): + break + + Example of error=False usage:: + + for _ in support.busy_retry(support.SHORT_TIMEOUT, error=False): + if check(): + break + else: + raise RuntimeError('my custom error') + +.. function:: sleeping_retry(timeout, err_msg=None, /, *, init_delay=0.010, max_delay=1.0, error=True) + + Wait strategy that applies exponential backoff. + + Run the loop body until ``break`` stops the loop. Sleep at each loop + iteration, but not at the first iteration. The sleep delay is doubled at + each iteration (up to *max_delay* seconds). + + See :func:`busy_retry` documentation for the parameters usage. + + Example raising an exception after SHORT_TIMEOUT seconds:: + + for _ in support.sleeping_retry(support.SHORT_TIMEOUT): + if check(): + break + + Example of error=False usage:: + + for _ in support.sleeping_retry(support.SHORT_TIMEOUT, error=False): + if check(): + break + else: + raise RuntimeError('my custom error') + .. function:: is_resource_enabled(resource) Return ``True`` if *resource* is enabled and available. The list of @@ -418,7 +472,7 @@ The :mod:`test.support` module defines the following functions: .. function:: with_pymalloc() - Return :data:`_testcapi.WITH_PYMALLOC`. + Return :const:`_testcapi.WITH_PYMALLOC`. .. function:: requires(resource, msg=None) @@ -482,6 +536,13 @@ The :mod:`test.support` module defines the following functions: :func:`doctest.testmod`. +.. function:: get_pagesize() + + Get size of a page in bytes. + + .. versionadded:: 3.12 + + .. function:: setswitchinterval(interval) Set the :func:`sys.setswitchinterval` to the given *interval*. Defines @@ -740,6 +801,12 @@ The :mod:`test.support` module defines the following functions: Decorator for only running the test if :data:`HAVE_DOCSTRINGS`. +.. decorator:: requires_limited_api + + Decorator for only running the test if :ref:`Limited C API <limited-c-api>` + is available. + + .. decorator:: cpython_only Decorator for tests only applicable to CPython. @@ -973,7 +1040,7 @@ The :mod:`test.support` module defines the following classes: `SetErrorMode <https://msdn.microsoft.com/en-us/library/windows/desktop/ms680621.aspx>`_. On UNIX, :func:`resource.setrlimit` is used to set - :attr:`resource.RLIMIT_CORE`'s soft limit to 0 to prevent coredump file + :const:`resource.RLIMIT_CORE`'s soft limit to 0 to prevent coredump file creation. On both platforms, the old value is restored by :meth:`__exit__`. @@ -1007,13 +1074,6 @@ The :mod:`test.support` module defines the following classes: Try to match a single stored value (*dv*) with a supplied value (*v*). -.. class:: BasicTestRunner() - - .. method:: run(test) - - Run *test* and return the result. - - :mod:`test.support.socket_helper` --- Utilities for socket tests ================================================================ @@ -1631,6 +1691,21 @@ The :mod:`test.support.warnings_helper` module provides support for warnings tes .. versionadded:: 3.10 +.. function:: ignore_warnings(*, category) + + Suppress warnings that are instances of *category*, + which must be :exc:`Warning` or a subclass. + Roughly equivalent to :func:`warnings.catch_warnings` + with :meth:`warnings.simplefilter('ignore', category=category) <warnings.simplefilter>`. + For example:: + + @warning_helper.ignore_warnings(category=DeprecationWarning) + def test_suppress_warning(): + # do something + + .. versionadded:: 3.8 + + .. function:: check_no_resource_warning(testcase) Context manager to check that no :exc:`ResourceWarning` was raised. You diff --git a/Doc/library/textwrap.rst b/Doc/library/textwrap.rst index 1a9d5f98..e2952ce3 100644 --- a/Doc/library/textwrap.rst +++ b/Doc/library/textwrap.rst @@ -60,7 +60,7 @@ functions should be good enough; otherwise, you should use an instance of First the whitespace in *text* is collapsed (all whitespace is replaced by single spaces). If the result fits in the *width*, it is returned. Otherwise, enough words are dropped from the end so that the remaining words - plus the :attr:`placeholder` fit within :attr:`width`:: + plus the *placeholder* fit within *width*:: >>> textwrap.shorten("Hello world!", width=12) 'Hello world!' @@ -173,7 +173,7 @@ hyphenated words; only then will long words be broken if necessary, unless .. attribute:: expand_tabs (default: ``True``) If true, then all tab characters in *text* will be - expanded to spaces using the :meth:`expandtabs` method of *text*. + expanded to spaces using the :meth:`~str.expandtabs` method of *text*. .. attribute:: tabsize diff --git a/Doc/library/threading.rst b/Doc/library/threading.rst index ef140d75..23d8cd15 100644 --- a/Doc/library/threading.rst +++ b/Doc/library/threading.rst @@ -127,7 +127,7 @@ This module defines the following functions: Its value may be used to uniquely identify this particular thread system-wide (until the thread terminates, after which the value may be recycled by the OS). - .. availability:: Windows, FreeBSD, Linux, macOS, OpenBSD, NetBSD, AIX. + .. availability:: Windows, FreeBSD, Linux, macOS, OpenBSD, NetBSD, AIX, DragonFlyBSD. .. versionadded:: 3.8 @@ -158,6 +158,15 @@ This module defines the following functions: The *func* will be passed to :func:`sys.settrace` for each thread, before its :meth:`~Thread.run` method is called. +.. function:: settrace_all_threads(func) + + Set a trace function for all threads started from the :mod:`threading` module + and all Python threads that are currently executing. + + The *func* will be passed to :func:`sys.settrace` for each thread, before its + :meth:`~Thread.run` method is called. + + .. versionadded:: 3.12 .. function:: gettrace() @@ -178,6 +187,15 @@ This module defines the following functions: The *func* will be passed to :func:`sys.setprofile` for each thread, before its :meth:`~Thread.run` method is called. +.. function:: setprofile_all_threads(func) + + Set a profile function for all threads started from the :mod:`threading` module + and all Python threads that are currently executing. + + The *func* will be passed to :func:`sys.setprofile` for each thread, before its + :meth:`~Thread.run` method is called. + + .. versionadded:: 3.12 .. function:: getprofile() @@ -254,7 +272,7 @@ The instance's values will be different for separate threads. A class that represents thread-local data. For more details and extensive examples, see the documentation string of the - :mod:`_threading_local` module. + :mod:`!_threading_local` module: :source:`Lib/_threading_local.py`. .. _thread-objects: @@ -267,7 +285,7 @@ thread of control. There are two ways to specify the activity: by passing a callable object to the constructor, or by overriding the :meth:`~Thread.run` method in a subclass. No other methods (except for the constructor) should be overridden in a subclass. In other words, *only* override the -:meth:`~Thread.__init__` and :meth:`~Thread.run` methods of this class. +``__init__()`` and :meth:`~Thread.run` methods of this class. Once a thread object is created, its activity must be started by calling the thread's :meth:`~Thread.start` method. This invokes the :meth:`~Thread.run` @@ -319,7 +337,7 @@ since it is impossible to detect the termination of alien threads. are: *group* should be ``None``; reserved for future extension when a - :class:`ThreadGroup` class is implemented. + :class:`!ThreadGroup` class is implemented. *target* is the callable object to be invoked by the :meth:`run` method. Defaults to ``None``, meaning nothing is called. @@ -991,7 +1009,7 @@ This class represents an action that should be run only after a certain amount of time has passed --- a timer. :class:`Timer` is a subclass of :class:`Thread` and as such also functions as an example of creating custom threads. -Timers are started, as with threads, by calling their :meth:`~Timer.start` +Timers are started, as with threads, by calling their :meth:`Timer.start <Thread.start>` method. The timer can be stopped (before its action has begun) by calling the :meth:`~Timer.cancel` method. The interval the timer will wait before executing its action may not be exactly the same as the interval specified by @@ -1129,10 +1147,10 @@ As an example, here is a simple way to synchronize a client and server thread:: Using locks, conditions, and semaphores in the :keyword:`!with` statement ------------------------------------------------------------------------- -All of the objects provided by this module that have :meth:`acquire` and -:meth:`release` methods can be used as context managers for a :keyword:`with` -statement. The :meth:`acquire` method will be called when the block is -entered, and :meth:`release` will be called when the block is exited. Hence, +All of the objects provided by this module that have ``acquire`` and +``release`` methods can be used as context managers for a :keyword:`with` +statement. The ``acquire`` method will be called when the block is +entered, and ``release`` will be called when the block is exited. Hence, the following snippet:: with some_lock: diff --git a/Doc/library/timeit.rst b/Doc/library/timeit.rst index 660a546e..b3d2a1b9 100644 --- a/Doc/library/timeit.rst +++ b/Doc/library/timeit.rst @@ -27,11 +27,11 @@ can be used to compare three different expressions: .. code-block:: shell-session - $ python3 -m timeit '"-".join(str(n) for n in range(100))' + $ python -m timeit "'-'.join(str(n) for n in range(100))" 10000 loops, best of 5: 30.2 usec per loop - $ python3 -m timeit '"-".join([str(n) for n in range(100)])' + $ python -m timeit "'-'.join([str(n) for n in range(100)])" 10000 loops, best of 5: 27.5 usec per loop - $ python3 -m timeit '"-".join(map(str, range(100)))' + $ python -m timeit "'-'.join(map(str, range(100)))" 10000 loops, best of 5: 23.2 usec per loop This can be achieved from the :ref:`python-interface` with:: @@ -86,9 +86,11 @@ The module defines three convenience functions and a public class: .. versionchanged:: 3.7 Default value of *repeat* changed from 3 to 5. + .. function:: default_timer() - The default timer, which is always :func:`time.perf_counter`. + The default timer, which is always time.perf_counter(), returns float seconds. + An alternative, time.perf_counter_ns, returns integer nanoseconds. .. versionchanged:: 3.3 :func:`time.perf_counter` is now the default timer. @@ -124,7 +126,7 @@ The module defines three convenience functions and a public class: Time *number* executions of the main statement. This executes the setup statement once, and then returns the time it takes to execute the main - statement a number of times, measured in seconds as a float. + statement a number of times. The default timer returns seconds as a float. The argument is the number of times through the loop, defaulting to one million. The main statement, the setup statement and the timer function to be used are passed to the constructor. @@ -206,7 +208,7 @@ Command-Line Interface When called as a program from the command line, the following form is used:: - python -m timeit [-n N] [-r N] [-u U] [-s S] [-h] [statement ...] + python -m timeit [-n N] [-r N] [-u U] [-s S] [-p] [-v] [-h] [statement ...] Where the following options are understood: @@ -277,9 +279,9 @@ It is possible to provide a setup statement that is executed only once at the be .. code-block:: shell-session - $ python -m timeit -s 'text = "sample string"; char = "g"' 'char in text' + $ python -m timeit -s "text = 'sample string'; char = 'g'" "char in text" 5000000 loops, best of 5: 0.0877 usec per loop - $ python -m timeit -s 'text = "sample string"; char = "g"' 'text.find(char)' + $ python -m timeit -s "text = 'sample string'; char = 'g'" "text.find(char)" 1000000 loops, best of 5: 0.342 usec per loop In the output, there are three fields. The loop count, which tells you how many @@ -313,14 +315,14 @@ to test for missing and present object attributes: .. code-block:: shell-session - $ python -m timeit 'try:' ' str.__bool__' 'except AttributeError:' ' pass' + $ python -m timeit "try:" " str.__bool__" "except AttributeError:" " pass" 20000 loops, best of 5: 15.7 usec per loop - $ python -m timeit 'if hasattr(str, "__bool__"): pass' + $ python -m timeit "if hasattr(str, '__bool__'): pass" 50000 loops, best of 5: 4.26 usec per loop - $ python -m timeit 'try:' ' int.__bool__' 'except AttributeError:' ' pass' + $ python -m timeit "try:" " int.__bool__" "except AttributeError:" " pass" 200000 loops, best of 5: 1.43 usec per loop - $ python -m timeit 'if hasattr(int, "__bool__"): pass' + $ python -m timeit "if hasattr(int, '__bool__'): pass" 100000 loops, best of 5: 2.23 usec per loop :: diff --git a/Doc/library/tkinter.rst b/Doc/library/tkinter.rst index c8e4317b..246abf37 100644 --- a/Doc/library/tkinter.rst +++ b/Doc/library/tkinter.rst @@ -163,7 +163,7 @@ the modern themed widget set and API:: interpreter and calls :func:`exec` on the contents of :file:`.{className}.py` and :file:`.{baseName}.py`. The path for the profile files is the :envvar:`HOME` environment variable or, if that - isn't defined, then :attr:`os.curdir`. + isn't defined, then :data:`os.curdir`. .. attribute:: tk @@ -352,7 +352,7 @@ Understanding How Tkinter Wraps Tcl/Tk When your application uses Tkinter's classes and methods, internally Tkinter is assembling strings representing Tcl/Tk commands, and executing those -commands in the Tcl interpreter attached to your applicaton's :class:`Tk` +commands in the Tcl interpreter attached to your application's :class:`Tk` instance. Whether it's trying to navigate reference documentation, trying to find diff --git a/Doc/library/tkinter.ttk.rst b/Doc/library/tkinter.ttk.rst index 4ff2b215..9f2f9eb8 100644 --- a/Doc/library/tkinter.ttk.rst +++ b/Doc/library/tkinter.ttk.rst @@ -102,7 +102,7 @@ themed widgets and is not supposed to be directly instantiated. Standard Options ^^^^^^^^^^^^^^^^ -All the :mod:`ttk` Widgets accepts the following options: +All the :mod:`ttk` Widgets accept the following options: .. tabularcolumns:: |l|L| diff --git a/Doc/library/token-list.inc b/Doc/library/token-list.inc index 1a99f051..e885de88 100644 --- a/Doc/library/token-list.inc +++ b/Doc/library/token-list.inc @@ -1,4 +1,4 @@ -.. Auto-generated by Tools/scripts/generate_token.py +.. Auto-generated by Tools/build/generate_token.py .. data:: ENDMARKER .. data:: NAME @@ -201,6 +201,10 @@ Token value for ``":="``. +.. data:: EXCLAMATION + + Token value for ``"!"``. + .. data:: OP .. data:: AWAIT @@ -213,6 +217,16 @@ .. data:: SOFT_KEYWORD +.. data:: FSTRING_START + +.. data:: FSTRING_MIDDLE + +.. data:: FSTRING_END + +.. data:: COMMENT + +.. data:: NL + .. data:: ERRORTOKEN .. data:: N_TOKENS diff --git a/Doc/library/token.rst b/Doc/library/token.rst index a1aceba9..903847bb 100644 --- a/Doc/library/token.rst +++ b/Doc/library/token.rst @@ -50,11 +50,13 @@ The following token type values aren't used by the C tokenizer but are needed fo the :mod:`tokenize` module. .. data:: COMMENT + :noindex: Token value used to indicate a comment. .. data:: NL + :noindex: Token value used to indicate a non-terminating newline. The :data:`NEWLINE` token indicates the end of a logical line of Python code; diff --git a/Doc/library/tokenize.rst b/Doc/library/tokenize.rst index 11f569df..bffe9300 100644 --- a/Doc/library/tokenize.rst +++ b/Doc/library/tokenize.rst @@ -22,6 +22,15 @@ the generic :data:`~token.OP` token type. The exact type can be determined by checking the ``exact_type`` property on the :term:`named tuple` returned from :func:`tokenize.tokenize`. + +.. warning:: + + Note that the functions in this module are only designed to parse + syntactically valid Python code (code that does not raise when parsed + using :func:`ast.parse`). The behavior of the functions in this module is + **undefined** when providing invalid Python code and it can change at any + point. + Tokenizing Input ---------------- @@ -139,11 +148,6 @@ function it uses to do this is available: 2, 3 -Note that unclosed single-quoted strings do not cause an error to be -raised. They are tokenized as :data:`~token.ERRORTOKEN`, followed by the -tokenization of their contents. - - .. _tokenize-cli: Command-Line Usage diff --git a/Doc/library/traceback.rst b/Doc/library/traceback.rst index a7a015f1..55ac361b 100644 --- a/Doc/library/traceback.rst +++ b/Doc/library/traceback.rst @@ -14,11 +14,10 @@ interpreter when it prints a stack trace. This is useful when you want to print stack traces under program control, such as in a "wrapper" around the interpreter. -.. index:: object: traceback +.. index:: pair: object; traceback -The module uses traceback objects --- this is the object type that is stored in -the :data:`sys.last_traceback` variable and returned as the third item from -:func:`sys.exc_info`. +The module uses traceback objects --- these are objects of type :class:`types.TracebackType`, +which are assigned to the ``__traceback__`` field of :class:`BaseException` instances. .. seealso:: @@ -81,16 +80,15 @@ The module defines the following functions: .. function:: print_exc(limit=None, file=None, chain=True) - This is a shorthand for ``print_exception(*sys.exc_info(), limit, file, + This is a shorthand for ``print_exception(sys.exception(), limit, file, chain)``. .. function:: print_last(limit=None, file=None, chain=True) - This is a shorthand for ``print_exception(sys.last_type, sys.last_value, - sys.last_traceback, limit, file, chain)``. In general it will work only - after an exception has reached an interactive prompt (see - :data:`sys.last_type`). + This is a shorthand for ``print_exception(sys.last_exc, limit, file, + chain)``. In general it will work only after an exception has reached + an interactive prompt (see :data:`sys.last_exc`). .. function:: print_stack(f=None, limit=None, file=None) @@ -141,11 +139,11 @@ The module defines the following functions: Format the exception part of a traceback using an exception value such as given by ``sys.last_value``. The return value is a list of strings, each - ending in a newline. Normally, the list contains a single string; however, - for :exc:`SyntaxError` exceptions, it contains several lines that (when - printed) display detailed information about where the syntax error occurred. - The message indicating which exception occurred is the always last string in - the list. + ending in a newline. The list contains the exception's message, which is + normally a single string; however, for :exc:`SyntaxError` exceptions, it + contains several lines that (when printed) display detailed information + about where the syntax error occurred. Following the message, the list + contains the exception's :attr:`notes <BaseException.__notes__>`. Since Python 3.10, instead of passing *value*, an exception object can be passed as the first argument. If *value* is provided, the first @@ -155,6 +153,9 @@ The module defines the following functions: The *etype* parameter has been renamed to *exc* and is now positional-only. + .. versionchanged:: 3.11 + The returned list now includes any notes attached to the exception. + .. function:: format_exception(exc, /[, value, tb], limit=None, chain=True) @@ -219,7 +220,7 @@ The module also defines the following classes: :class:`TracebackException` objects are created from actual exceptions to capture data for later printing in a lightweight fashion. -.. class:: TracebackException(exc_type, exc_value, exc_traceback, *, limit=None, lookup_lines=True, capture_locals=False, compact=False) +.. class:: TracebackException(exc_type, exc_value, exc_traceback, *, limit=None, lookup_lines=True, capture_locals=False, compact=False, max_group_width=15, max_group_depth=10) Capture an exception for later rendering. *limit*, *lookup_lines* and *capture_locals* are as for the :class:`StackSummary` class. @@ -231,6 +232,18 @@ capture data for later printing in a lightweight fashion. Note that when locals are captured, they are also shown in the traceback. + *max_group_width* and *max_group_depth* control the formatting of exception + groups (see :exc:`BaseExceptionGroup`). The depth refers to the nesting + level of the group, and the width refers to the size of a single exception + group's exceptions array. The formatted output is truncated when either + limit is exceeded. + + .. versionchanged:: 3.10 + Added the *compact* parameter. + + .. versionchanged:: 3.11 + Added the *max_group_width* and *max_group_depth* parameters. + .. attribute:: __cause__ A :class:`TracebackException` of the original ``__cause__``. @@ -239,6 +252,14 @@ capture data for later printing in a lightweight fashion. A :class:`TracebackException` of the original ``__context__``. + .. attribute:: exceptions + + If ``self`` represents an :exc:`ExceptionGroup`, this field holds a list of + :class:`TracebackException` instances representing the nested exceptions. + Otherwise it is ``None``. + + .. versionadded:: 3.11 + .. attribute:: __suppress_context__ The ``__suppress_context__`` value from the original exception. @@ -267,6 +288,13 @@ capture data for later printing in a lightweight fashion. For syntax errors - the line number where the error occurred. + .. attribute:: end_lineno + + For syntax errors - the end line number where the error occurred. + Can be ``None`` if not present. + + .. versionadded:: 3.10 + .. attribute:: text For syntax errors - the text where the error occurred. @@ -275,6 +303,13 @@ capture data for later printing in a lightweight fashion. For syntax errors - the offset into the text where the error occurred. + .. attribute:: end_offset + + For syntax errors - the end offset into the text where the error occurred. + Can be ``None`` if not present. + + .. versionadded:: 3.10 + .. attribute:: msg For syntax errors - the compiler error message. @@ -304,25 +339,21 @@ capture data for later printing in a lightweight fashion. some containing internal newlines. :func:`~traceback.print_exception` is a wrapper around this method which just prints the lines to a file. - The message indicating which exception occurred is always the last - string in the output. - .. method:: format_exception_only() Format the exception part of the traceback. The return value is a generator of strings, each ending in a newline. - Normally, the generator emits a single string; however, for - :exc:`SyntaxError` exceptions, it emits several lines that (when - printed) display detailed information about where the syntax - error occurred. + The generator emits the exception's message followed by its notes + (if it has any). The exception message is normally a single string; + however, for :exc:`SyntaxError` exceptions, it consists of several + lines that (when printed) display detailed information about where + the syntax error occurred. - The message indicating which exception occurred is always the last - string in the output. + .. versionchanged:: 3.11 + The exception's notes are now included in the output. - .. versionchanged:: 3.10 - Added the *compact* parameter. :class:`StackSummary` Objects @@ -348,6 +379,10 @@ capture data for later printing in a lightweight fashion. local variables in each :class:`FrameSummary` are captured as object representations. + .. versionchanged:: 3.12 + Exceptions raised from :func:`repr` on a local variable (when + *capture_locals* is ``True``) are no longer propagated to the caller. + .. classmethod:: from_list(a_list) Construct a :class:`StackSummary` object from a supplied list of @@ -440,11 +475,11 @@ exception and traceback: try: lumberjack() except IndexError: - exc_type, exc_value, exc_traceback = sys.exc_info() + exc = sys.exception() print("*** print_tb:") - traceback.print_tb(exc_traceback, limit=1, file=sys.stdout) + traceback.print_tb(exc.__traceback__, limit=1, file=sys.stdout) print("*** print_exception:") - traceback.print_exception(exc_value, limit=2, file=sys.stdout) + traceback.print_exception(exc, limit=2, file=sys.stdout) print("*** print_exc:") traceback.print_exc(limit=2, file=sys.stdout) print("*** format_exc, first and last line:") @@ -452,12 +487,12 @@ exception and traceback: print(formatted_lines[0]) print(formatted_lines[-1]) print("*** format_exception:") - print(repr(traceback.format_exception(exc_value))) + print(repr(traceback.format_exception(exc))) print("*** extract_tb:") - print(repr(traceback.extract_tb(exc_traceback))) + print(repr(traceback.extract_tb(exc.__traceback__))) print("*** format_tb:") - print(repr(traceback.format_tb(exc_traceback))) - print("*** tb_lineno:", exc_traceback.tb_lineno) + print(repr(traceback.format_tb(exc.__traceback__))) + print("*** tb_lineno:", exc.__traceback__.tb_lineno) The output for the example would look similar to this: diff --git a/Doc/library/tty.rst b/Doc/library/tty.rst index b30bc3c7..fc7f98c7 100644 --- a/Doc/library/tty.rst +++ b/Doc/library/tty.rst @@ -20,18 +20,36 @@ Because it requires the :mod:`termios` module, it will work only on Unix. The :mod:`tty` module defines the following functions: +.. function:: cfmakeraw(mode) + + Convert the tty attribute list *mode*, which is a list like the one returned + by :func:`termios.tcgetattr`, to that of a tty in raw mode. + + .. versionadded:: 3.12 + + +.. function:: cfmakecbreak(mode) + + Convert the tty attribute list *mode*, which is a list like the one returned + by :func:`termios.tcgetattr`, to that of a tty in cbreak mode. + + .. versionadded:: 3.12 + + .. function:: setraw(fd, when=termios.TCSAFLUSH) Change the mode of the file descriptor *fd* to raw. If *when* is omitted, it defaults to :const:`termios.TCSAFLUSH`, and is passed to - :func:`termios.tcsetattr`. + :func:`termios.tcsetattr`. The return value of :func:`termios.tcgetattr` + is saved before setting *fd* to raw mode; this value is returned. .. function:: setcbreak(fd, when=termios.TCSAFLUSH) Change the mode of file descriptor *fd* to cbreak. If *when* is omitted, it defaults to :const:`termios.TCSAFLUSH`, and is passed to - :func:`termios.tcsetattr`. + :func:`termios.tcsetattr`. The return value of :func:`termios.tcgetattr` + is saved before setting *fd* to cbreak mode; this value is returned. .. seealso:: diff --git a/Doc/library/turtle.rst b/Doc/library/turtle.rst index 17bf8829..4e1a0948 100644 --- a/Doc/library/turtle.rst +++ b/Doc/library/turtle.rst @@ -19,14 +19,10 @@ Introduction ============ -Turtle graphics is a popular way for introducing programming to kids. It was -part of the original Logo programming language developed by Wally Feurzeig, -Seymour Papert and Cynthia Solomon in 1967. - -Imagine a robotic turtle starting at (0, 0) in the x-y plane. After an ``import turtle``, give it the -command ``turtle.forward(15)``, and it moves (on-screen!) 15 pixels in the -direction it is facing, drawing a line as it moves. Give it the command -``turtle.right(25)``, and it rotates in-place 25 degrees clockwise. +Turtle graphics is an implementation of `the popular geometric drawing tools +introduced in Logo <https://en.wikipedia.org/wiki/Turtle_ +(robot)>`_, developed by Wally Feurzeig, Seymour Papert and Cynthia Solomon +in 1967. .. sidebar:: Turtle star @@ -36,67 +32,261 @@ direction it is facing, drawing a line as it moves. Give it the command .. image:: turtle-star.* :align: center - .. literalinclude:: ../includes/turtle-star.py +In Python, turtle graphics provides a representation of a physical "turtle" +(a little robot with a pen) that draws on a sheet of paper on the floor. + +It's an effective and well-proven way for learners to encounter +programming concepts and interaction with software, as it provides instant, +visible feedback. It also provides convenient access to graphical output +in general. + +Turtle drawing was originally created as an educational tool, to be used by +teachers in the classroom. For the programmer who needs to produce some +graphical output it can be a way to do that without the overhead of +introducing more complex or external libraries into their work. + + +.. _turtle-tutorial: + +Tutorial +======== + +New users should start here. In this tutorial we'll explore some of the +basics of turtle drawing. + + +Starting a turtle environment +----------------------------- + +In a Python shell, import all the objects of the ``turtle`` module:: + + from turtle import * + +If you run into a ``No module named '_tkinter'`` error, you'll have to +install the :mod:`Tk interface package <tkinter>` on your system. + + +Basic drawing +------------- + +Send the turtle forward 100 steps:: + + forward(100) + +You should see (most likely, in a new window on your display) a line +drawn by the turtle, heading East. Change the direction of the turtle, +so that it turns 120 degrees left (anti-clockwise):: + + left(120) + +Let's continue by drawing a triangle:: + + forward(100) + left(120) + forward(100) + +Notice how the turtle, represented by an arrow, points in different +directions as you steer it. + +Experiment with those commands, and also with ``backward()`` and +``right()``. + + +Pen control +~~~~~~~~~~~ + +Try changing the color - for example, ``color('blue')`` - and +width of the line - for example, ``width(3)`` - and then drawing again. + +You can also move the turtle around without drawing, by lifting up the pen: +``up()`` before moving. To start drawing again, use ``down()``. + + +The turtle's position +~~~~~~~~~~~~~~~~~~~~~ + +Send your turtle back to its starting-point (useful if it has disappeared +off-screen):: + + home() + +The home position is at the center of the turtle's screen. If you ever need to +know them, get the turtle's x-y co-ordinates with:: -By combining together these and similar commands, intricate shapes and pictures -can easily be drawn. + pos() -The :mod:`turtle` module is an extended reimplementation of the same-named -module from the Python standard distribution up to version Python 2.5. +Home is at ``(0, 0)``. + +And after a while, it will probably help to clear the window so we can start +anew:: + + clearscreen() + + +Making algorithmic patterns +--------------------------- + +Using loops, it's possible to build up geometric patterns:: + + for steps in range(100): + for c in ('blue', 'red', 'green'): + color(c) + forward(steps) + right(30) + + +\ - which of course, are limited only by the imagination! + +Let's draw the star shape at the top of this page. We want red lines, +filled in with yellow:: + + color('red') + fillcolor('yellow') + +Just as ``up()`` and ``down()`` determine whether lines will be drawn, +filling can be turned on and off:: + + begin_fill() + +Next we'll create a loop:: + + while True: + forward(200) + left(170) + if abs(pos()) < 1: + break + +``abs(pos()) < 1`` is a good way to know when the turtle is back at its +home position. + +Finally, complete the filling:: + + end_fill() + +(Note that filling only actually takes place when you give the +``end_fill()`` command.) + + +.. _turtle-how-to: + +How to... +========= + +This section covers some typical turtle use-cases and approaches. + + +Get started as quickly as possible +---------------------------------- + +One of the joys of turtle graphics is the immediate, visual feedback that's +available from simple commands - it's an excellent way to introduce children +to programming ideas, with a minimum of overhead (not just children, of +course). + +The turtle module makes this possible by exposing all its basic functionality +as functions, available with ``from turtle import *``. The :ref:`turtle +graphics tutorial <turtle-tutorial>` covers this approach. + +It's worth noting that many of the turtle commands also have even more terse +equivalents, such as ``fd()`` for :func:`forward`. These are especially +useful when working with learners for whom typing is not a skill. + +.. _note: + + You'll need to have the :mod:`Tk interface package <tkinter>` installed on + your system for turtle graphics to work. Be warned that this is not + always straightforward, so check this in advance if you're planning to + use turtle graphics with a learner. + + +Use the ``turtle`` module namespace +----------------------------------- -It tries to keep the merits of the old turtle module and to be (nearly) 100% -compatible with it. This means in the first place to enable the learning -programmer to use all the commands, classes and methods interactively when using -the module from within IDLE run with the ``-n`` switch. +Using ``from turtle import *`` is convenient - but be warned that it imports a +rather large collection of objects, and if you're doing anything but turtle +graphics you run the risk of a name conflict (this becomes even more an issue +if you're using turtle graphics in a script where other modules might be +imported). -The turtle module provides turtle graphics primitives, in both object-oriented -and procedure-oriented ways. Because it uses :mod:`tkinter` for the underlying -graphics, it needs a version of Python installed with Tk support. +The solution is to use ``import turtle`` - ``fd()`` becomes +``turtle.fd()``, ``width()`` becomes ``turtle.width()`` and so on. (If typing +"turtle" over and over again becomes tedious, use for example ``import turtle +as t`` instead.) -The object-oriented interface uses essentially two+two classes: -1. The :class:`TurtleScreen` class defines graphics windows as a playground for - the drawing turtles. Its constructor needs a :class:`tkinter.Canvas` or a - :class:`ScrolledCanvas` as argument. It should be used when :mod:`turtle` is - used as part of some application. +Use turtle graphics in a script +------------------------------- - The function :func:`Screen` returns a singleton object of a - :class:`TurtleScreen` subclass. This function should be used when - :mod:`turtle` is used as a standalone tool for doing graphics. - As a singleton object, inheriting from its class is not possible. +It's recommended to use the ``turtle`` module namespace as described +immediately above, for example:: - All methods of TurtleScreen/Screen also exist as functions, i.e. as part of - the procedure-oriented interface. + import turtle as t + from random import random -2. :class:`RawTurtle` (alias: :class:`RawPen`) defines Turtle objects which draw - on a :class:`TurtleScreen`. Its constructor needs a Canvas, ScrolledCanvas - or TurtleScreen as argument, so the RawTurtle objects know where to draw. + for i in range(100): + steps = int(random() * 100) + angle = int(random() * 360) + t.right(angle) + t.fd(steps) - Derived from RawTurtle is the subclass :class:`Turtle` (alias: :class:`Pen`), - which draws on "the" :class:`Screen` instance which is automatically - created, if not already present. +Another step is also required though - as soon as the script ends, Python +will also close the turtle's window. Add:: - All methods of RawTurtle/Turtle also exist as functions, i.e. part of the - procedure-oriented interface. + t.mainloop() -The procedural interface provides functions which are derived from the methods -of the classes :class:`Screen` and :class:`Turtle`. They have the same names as -the corresponding methods. A screen object is automatically created whenever a -function derived from a Screen method is called. An (unnamed) turtle object is -automatically created whenever any of the functions derived from a Turtle method -is called. +to the end of the script. The script will now wait to be dismissed and +will not exit until it is terminated, for example by closing the turtle +graphics window. -To use multiple turtles on a screen one has to use the object-oriented interface. + +Use object-oriented turtle graphics +----------------------------------- + +.. seealso:: :ref:`Explanation of the object-oriented interface <turtle-explanation>` + +Other than for very basic introductory purposes, or for trying things out +as quickly as possible, it's more usual and much more powerful to use the +object-oriented approach to turtle graphics. For example, this allows +multiple turtles on screen at once. + +In this approach, the various turtle commands are methods of objects (mostly of +``Turtle`` objects). You *can* use the object-oriented approach in the shell, +but it would be more typical in a Python script. + +The example above then becomes:: + + from turtle import Turtle + from random import random + + t = Turtle() + for i in range(100): + steps = int(random() * 100) + angle = int(random() * 360) + t.right(angle) + t.fd(steps) + + t.screen.mainloop() + +Note the last line. ``t.screen`` is an instance of the :class:`Screen` +that a Turtle instance exists on; it's created automatically along with +the turtle. + +The turtle's screen can be customised, for example:: + + t.screen.title('Object-oriented turtle demo') + t.screen.bgcolor("orange") + + +Turtle graphics reference +========================= .. note:: + In the following documentation the argument list for functions is given. Methods, of course, have the additional first argument *self* which is omitted here. -Overview of available Turtle and Screen methods -================================================= - Turtle methods -------------- @@ -107,6 +297,7 @@ Turtle motion | :func:`right` | :func:`rt` | :func:`left` | :func:`lt` | :func:`goto` | :func:`setpos` | :func:`setposition` + | :func:`teleport` | :func:`setx` | :func:`sety` | :func:`setheading` | :func:`seth` @@ -358,18 +549,56 @@ Turtle motion .. doctest:: :skipif: _tkinter is None - >>> tp = turtle.pos() - >>> tp - (0.00,0.00) - >>> turtle.setpos(60,30) - >>> turtle.pos() - (60.00,30.00) - >>> turtle.setpos((20,80)) - >>> turtle.pos() - (20.00,80.00) - >>> turtle.setpos(tp) - >>> turtle.pos() - (0.00,0.00) + >>> tp = turtle.pos() + >>> tp + (0.00,0.00) + >>> turtle.setpos(60,30) + >>> turtle.pos() + (60.00,30.00) + >>> turtle.setpos((20,80)) + >>> turtle.pos() + (20.00,80.00) + >>> turtle.setpos(tp) + >>> turtle.pos() + (0.00,0.00) + + +.. function:: teleport(x, y=None, *, fill_gap=False) + + :param x: a number or ``None`` + :param y: a number or ``None`` + :param fill_gap: a boolean + + Move turtle to an absolute position. Unlike goto(x, y), a line will not + be drawn. The turtle's orientation does not change. If currently + filling, the polygon(s) teleported from will be filled after leaving, + and filling will begin again after teleporting. This can be disabled + with fill_gap=True, which makes the imaginary line traveled during + teleporting act as a fill barrier like in goto(x, y). + + .. doctest:: + :skipif: _tkinter is None + :hide: + + >>> turtle.goto(0, 0) + + .. doctest:: + :skipif: _tkinter is None + + >>> tp = turtle.pos() + >>> tp + (0.00,0.00) + >>> turtle.teleport(60) + >>> turtle.pos() + (60.00,0.00) + >>> turtle.teleport(y=10) + >>> turtle.pos() + (60.00,10.00) + >>> turtle.teleport(20, 30) + >>> turtle.pos() + (20.00,30.00) + + .. versionadded: 3.12 .. function:: setx(x) @@ -537,8 +766,7 @@ Turtle motion :skipif: _tkinter is None >>> turtle.color("blue") - >>> turtle.stamp() - 11 + >>> stamp_id = turtle.stamp() >>> turtle.fd(50) @@ -575,15 +803,8 @@ Turtle motion .. doctest:: >>> for i in range(8): - ... turtle.stamp(); turtle.fd(30) - 13 - 14 - 15 - 16 - 17 - 18 - 19 - 20 + ... unused_stamp_id = turtle.stamp() + ... turtle.fd(30) >>> turtle.clearstamps(2) >>> turtle.clearstamps(-2) >>> turtle.clearstamps() @@ -919,23 +1140,23 @@ Color control .. doctest:: :skipif: _tkinter is None - >>> colormode() - 1.0 - >>> turtle.pencolor() - 'red' - >>> turtle.pencolor("brown") - >>> turtle.pencolor() - 'brown' - >>> tup = (0.2, 0.8, 0.55) - >>> turtle.pencolor(tup) - >>> turtle.pencolor() - (0.2, 0.8, 0.5490196078431373) - >>> colormode(255) - >>> turtle.pencolor() - (51.0, 204.0, 140.0) - >>> turtle.pencolor('#32c18f') - >>> turtle.pencolor() - (50.0, 193.0, 143.0) + >>> colormode() + 1.0 + >>> turtle.pencolor() + 'red' + >>> turtle.pencolor("brown") + >>> turtle.pencolor() + 'brown' + >>> tup = (0.2, 0.8, 0.55) + >>> turtle.pencolor(tup) + >>> turtle.pencolor() + (0.2, 0.8, 0.5490196078431373) + >>> colormode(255) + >>> turtle.pencolor() + (51.0, 204.0, 140.0) + >>> turtle.pencolor('#32c18f') + >>> turtle.pencolor() + (50.0, 193.0, 143.0) .. function:: fillcolor(*args) @@ -968,17 +1189,17 @@ Color control .. doctest:: :skipif: _tkinter is None - >>> turtle.fillcolor("violet") - >>> turtle.fillcolor() - 'violet' - >>> turtle.pencolor() - (50.0, 193.0, 143.0) - >>> turtle.fillcolor((50, 193, 143)) # Integers, not floats - >>> turtle.fillcolor() - (50.0, 193.0, 143.0) - >>> turtle.fillcolor('#ffffff') - >>> turtle.fillcolor() - (255.0, 255.0, 255.0) + >>> turtle.fillcolor("violet") + >>> turtle.fillcolor() + 'violet' + >>> turtle.pencolor() + (50.0, 193.0, 143.0) + >>> turtle.fillcolor((50, 193, 143)) # Integers, not floats + >>> turtle.fillcolor() + (50.0, 193.0, 143.0) + >>> turtle.fillcolor('#ffffff') + >>> turtle.fillcolor() + (255.0, 255.0, 255.0) .. function:: color(*args) @@ -1007,12 +1228,12 @@ Color control .. doctest:: :skipif: _tkinter is None - >>> turtle.color("red", "green") - >>> turtle.color() - ('red', 'green') - >>> color("#285078", "#a0c8f0") - >>> color() - ((40.0, 80.0, 120.0), (160.0, 200.0, 240.0)) + >>> turtle.color("red", "green") + >>> turtle.color() + ('red', 'green') + >>> color("#285078", "#a0c8f0") + >>> color() + ((40.0, 80.0, 120.0), (160.0, 200.0, 240.0)) See also: Screen method :func:`colormode`. @@ -1034,11 +1255,11 @@ Filling .. doctest:: :skipif: _tkinter is None - >>> turtle.begin_fill() - >>> if turtle.filling(): - ... turtle.pensize(5) - ... else: - ... turtle.pensize(3) + >>> turtle.begin_fill() + >>> if turtle.filling(): + ... turtle.pensize(5) + ... else: + ... turtle.pensize(3) @@ -1214,7 +1435,7 @@ Appearance will be displayed stretched according to its stretchfactors: *stretch_wid* is stretchfactor perpendicular to its orientation, *stretch_len* is stretchfactor in direction of its orientation, *outline* determines the width - of the shapes's outline. + of the shape's outline. .. doctest:: :skipif: _tkinter is None @@ -1244,11 +1465,11 @@ Appearance .. doctest:: :skipif: _tkinter is None - >>> turtle.shape("circle") - >>> turtle.shapesize(5,2) - >>> turtle.shearfactor(0.5) - >>> turtle.shearfactor() - 0.5 + >>> turtle.shape("circle") + >>> turtle.shapesize(5,2) + >>> turtle.shearfactor(0.5) + >>> turtle.shearfactor() + 0.5 .. function:: tilt(angle) @@ -1279,7 +1500,7 @@ Appearance (direction of movement). .. doctest:: - :skipif: _tkinter is None + :skipif: _tkinter is None or 'always; deprecated method' >>> turtle.reset() >>> turtle.shape("circle") @@ -1545,7 +1766,7 @@ below: 1. Create an empty Shape object of type "compound". 2. Add as many components to this object as desired, using the - :meth:`addcomponent` method. + :meth:`~Shape.addcomponent` method. For example: @@ -1617,11 +1838,11 @@ Window control ``"nopic"``, delete background image, if present. If *picname* is ``None``, return the filename of the current backgroundimage. :: - >>> screen.bgpic() - 'nopic' - >>> screen.bgpic("landscape.gif") - >>> screen.bgpic() - "landscape.gif" + >>> screen.bgpic() + 'nopic' + >>> screen.bgpic("landscape.gif") + >>> screen.bgpic() + "landscape.gif" .. function:: clear() @@ -2028,16 +2249,16 @@ Settings and special methods Return the height of the turtle window. :: - >>> screen.window_height() - 480 + >>> screen.window_height() + 480 .. function:: window_width() Return the width of the turtle window. :: - >>> screen.window_width() - 640 + >>> screen.window_width() + 640 .. _screenspecific: @@ -2108,7 +2329,7 @@ Public classes .. class:: RawTurtle(canvas) RawPen(canvas) - :param canvas: a :class:`tkinter.Canvas`, a :class:`ScrolledCanvas` or a + :param canvas: a :class:`!tkinter.Canvas`, a :class:`ScrolledCanvas` or a :class:`TurtleScreen` Create a turtle. The turtle has all methods described above as "methods of @@ -2123,9 +2344,9 @@ Public classes .. class:: TurtleScreen(cv) - :param cv: a :class:`tkinter.Canvas` + :param cv: a :class:`!tkinter.Canvas` - Provides screen oriented methods like :func:`setbg` etc. that are described + Provides screen oriented methods like :func:`bgcolor` etc. that are described above. .. class:: Screen() @@ -2193,6 +2414,41 @@ Public classes * ``a.rotate(angle)`` rotation +.. _turtle-explanation: + +Explanation +=========== + +A turtle object draws on a screen object, and there a number of key classes in +the turtle object-oriented interface that can be used to create them and relate +them to each other. + +A :class:`Turtle` instance will automatically create a :class:`Screen` +instance if one is not already present. + +``Turtle`` is a subclass of :class:`RawTurtle`, which *doesn't* automatically +create a drawing surface - a *canvas* will need to be provided or created for +it. The *canvas* can be a :class:`!tkinter.Canvas`, :class:`ScrolledCanvas` +or :class:`TurtleScreen`. + + +:class:`TurtleScreen` is the basic drawing surface for a +turtle. :class:`Screen` is a subclass of ``TurtleScreen``, and +includes :ref:`some additional methods <screenspecific>` for managing its +appearance (including size and title) and behaviour. ``TurtleScreen``'s +constructor needs a :class:`!tkinter.Canvas` or a +:class:`ScrolledCanvas` as an argument. + +The functional interface for turtle graphics uses the various methods of +``Turtle`` and ``TurtleScreen``/``Screen``. Behind the scenes, a screen +object is automatically created whenever a function derived from a ``Screen`` +method is called. Similarly, a turtle object is automatically created +whenever any of the functions derived from a Turtle method is called. + +To use multiple turtles on a screen, the object-oriented interface must be +used. + + Help and configuration ====================== @@ -2218,12 +2474,12 @@ facilities: in the range 0..colormode or a 3-tuple of such numbers. - >>> screen.bgcolor("orange") - >>> screen.bgcolor() - "orange" - >>> screen.bgcolor(0.5,0,0.5) - >>> screen.bgcolor() - "#800080" + >>> screen.bgcolor("orange") + >>> screen.bgcolor() + "orange" + >>> screen.bgcolor(0.5,0,0.5) + >>> screen.bgcolor() + "#800080" >>> help(Turtle.penup) Help on method penup in module turtle: @@ -2315,7 +2571,9 @@ of this module or which better fits to your needs, e.g. for use in a classroom, you can prepare a configuration file ``turtle.cfg`` which will be read at import time and modify the configuration according to its settings. -The built in configuration would correspond to the following turtle.cfg:: +The built in configuration would correspond to the following ``turtle.cfg``: + +.. code-block:: ini width = 0.5 height = 0.75 @@ -2340,15 +2598,15 @@ The built in configuration would correspond to the following turtle.cfg:: Short explanation of selected entries: -- The first four lines correspond to the arguments of the :meth:`Screen.setup` +- The first four lines correspond to the arguments of the :func:`Screen.setup <setup>` method. - Line 5 and 6 correspond to the arguments of the method - :meth:`Screen.screensize`. + :func:`Screen.screensize <screensize>`. - *shape* can be any of the built-in shapes, e.g: arrow, turtle, etc. For more info try ``help(shape)``. -- If you want to use no fillcolor (i.e. make the turtle transparent), you have +- If you want to use no fill color (i.e. make the turtle transparent), you have to write ``fillcolor = ""`` (but all nonempty strings must not have quotes in - the cfg-file). + the cfg file). - If you want to reflect the turtle its state, you have to use ``resizemode = auto``. - If you set e.g. ``language = italian`` the docstringdict @@ -2398,6 +2656,8 @@ The :mod:`turtledemo` package directory contains: The demo scripts are: +.. currentmodule:: turtle + .. tabularcolumns:: |l|L|L| +----------------+------------------------------+-----------------------+ @@ -2444,6 +2704,9 @@ The demo scripts are: | planet_and_moon| simulation of | compound shapes, | | | gravitational system | :class:`Vec2D` | +----------------+------------------------------+-----------------------+ +| rosette | a pattern from the wikipedia | :func:`clone`, | +| | article on turtle graphics | :func:`undo` | ++----------------+------------------------------+-----------------------+ | round_dance | dancing turtles rotating | compound shapes, clone| | | pairwise in opposite | shapesize, tilt, | | | direction | get_shapepoly, update | @@ -2457,9 +2720,6 @@ The demo scripts are: | two_canvases | simple design | turtles on two | | | | canvases | +----------------+------------------------------+-----------------------+ -| wikipedia | a pattern from the wikipedia | :func:`clone`, | -| | article on turtle graphics | :func:`undo` | -+----------------+------------------------------+-----------------------+ | yinyang | another elementary example | :func:`circle` | +----------------+------------------------------+-----------------------+ @@ -2469,20 +2729,20 @@ Have fun! Changes since Python 2.6 ======================== -- The methods :meth:`Turtle.tracer`, :meth:`Turtle.window_width` and - :meth:`Turtle.window_height` have been eliminated. +- The methods :func:`Turtle.tracer <tracer>`, :func:`Turtle.window_width <window_width>` and + :func:`Turtle.window_height <window_height>` have been eliminated. Methods with these names and functionality are now available only as methods of :class:`Screen`. The functions derived from these remain available. (In fact already in Python 2.6 these methods were merely duplications of the corresponding - :class:`TurtleScreen`/:class:`Screen`-methods.) + :class:`TurtleScreen`/:class:`Screen` methods.) -- The method :meth:`Turtle.fill` has been eliminated. - The behaviour of :meth:`begin_fill` and :meth:`end_fill` - have changed slightly: now every filling-process must be completed with an +- The method :func:`!Turtle.fill` has been eliminated. + The behaviour of :func:`begin_fill` and :func:`end_fill` + have changed slightly: now every filling process must be completed with an ``end_fill()`` call. -- A method :meth:`Turtle.filling` has been added. It returns a boolean +- A method :func:`Turtle.filling <filling>` has been added. It returns a boolean value: ``True`` if a filling process is under way, ``False`` otherwise. This behaviour corresponds to a ``fill()`` call without arguments in Python 2.6. @@ -2490,23 +2750,23 @@ Changes since Python 2.6 Changes since Python 3.0 ======================== -- The methods :meth:`Turtle.shearfactor`, :meth:`Turtle.shapetransform` and - :meth:`Turtle.get_shapepoly` have been added. Thus the full range of +- The :class:`Turtle` methods :func:`shearfactor`, :func:`shapetransform` and + :func:`get_shapepoly` have been added. Thus the full range of regular linear transforms is now available for transforming turtle shapes. - :meth:`Turtle.tiltangle` has been enhanced in functionality: it now can - be used to get or set the tiltangle. :meth:`Turtle.settiltangle` has been + :func:`tiltangle` has been enhanced in functionality: it now can + be used to get or set the tilt angle. :func:`settiltangle` has been deprecated. -- The method :meth:`Screen.onkeypress` has been added as a complement to - :meth:`Screen.onkey` which in fact binds actions to the keyrelease event. - Accordingly the latter has got an alias: :meth:`Screen.onkeyrelease`. +- The :class:`Screen` method :func:`onkeypress` has been added as a complement to + :func:`onkey`. As the latter binds actions to the key release event, + an alias: :func:`onkeyrelease` was also added for it. -- The method :meth:`Screen.mainloop` has been added. So when working only - with Screen and Turtle objects one must not additionally import - :func:`mainloop` anymore. +- The method :func:`Screen.mainloop <mainloop>` has been added, + so there is no longer a need to use the standalone :func:`mainloop` function + when working with :class:`Screen` and :class:`Turtle` objects. -- Two input methods has been added :meth:`Screen.textinput` and - :meth:`Screen.numinput`. These popup input dialogs and return +- Two input methods have been added: :func:`Screen.textinput <textinput>` and + :func:`Screen.numinput <numinput>`. These pop up input dialogs and return strings and numbers respectively. - Two example scripts :file:`tdemo_nim.py` and :file:`tdemo_round_dance.py` diff --git a/Doc/library/types.rst b/Doc/library/types.rst index e0e77dfb..8cbe17df 100644 --- a/Doc/library/types.rst +++ b/Doc/library/types.rst @@ -75,13 +75,53 @@ Dynamic Type Creation This function looks for items in *bases* that are not instances of :class:`type`, and returns a tuple where each such object that has - an ``__mro_entries__`` method is replaced with an unpacked result of + an :meth:`~object.__mro_entries__` method is replaced with an unpacked result of calling this method. If a *bases* item is an instance of :class:`type`, - or it doesn't have an ``__mro_entries__`` method, then it is included in + or it doesn't have an :meth:`!__mro_entries__` method, then it is included in the return tuple unchanged. .. versionadded:: 3.7 +.. function:: get_original_bases(cls, /) + + Return the tuple of objects originally given as the bases of *cls* before + the :meth:`~object.__mro_entries__` method has been called on any bases + (following the mechanisms laid out in :pep:`560`). This is useful for + introspecting :ref:`Generics <user-defined-generics>`. + + For classes that have an ``__orig_bases__`` attribute, this + function returns the value of ``cls.__orig_bases__``. + For classes without the ``__orig_bases__`` attribute, ``cls.__bases__`` is + returned. + + Examples:: + + from typing import TypeVar, Generic, NamedTuple, TypedDict + + T = TypeVar("T") + class Foo(Generic[T]): ... + class Bar(Foo[int], float): ... + class Baz(list[str]): ... + Eggs = NamedTuple("Eggs", [("a", int), ("b", str)]) + Spam = TypedDict("Spam", {"a": int, "b": str}) + + assert Bar.__bases__ == (Foo, float) + assert get_original_bases(Bar) == (Foo[int], float) + + assert Baz.__bases__ == (list,) + assert get_original_bases(Baz) == (list[str],) + + assert Eggs.__bases__ == (tuple,) + assert get_original_bases(Eggs) == (NamedTuple,) + + assert Spam.__bases__ == (dict,) + assert get_original_bases(Spam) == (TypedDict,) + + assert int.__bases__ == (object,) + assert get_original_bases(int) == (object,) + + .. versionadded:: 3.12 + .. seealso:: :pep:`560` - Core support for typing module and generic types @@ -146,7 +186,7 @@ Standard names are defined for the following types: .. class:: CodeType(**kwargs) - .. index:: builtin: compile + .. index:: pair: built-in function; compile The type for code objects such as returned by :func:`compile`. @@ -311,6 +351,13 @@ Standard names are defined for the following types: .. versionchanged:: 3.9.2 This type can now be subclassed. + .. seealso:: + + :ref:`Generic Alias Types<types-genericalias>` + In-depth documentation on instances of :class:`!types.GenericAlias` + + :pep:`585` - Type Hinting Generics In Standard Collections + Introducing the :class:`!types.GenericAlias` class .. class:: UnionType @@ -320,7 +367,7 @@ Standard names are defined for the following types: .. class:: TracebackType(tb_next, tb_frame, tb_lasti, tb_lineno) - The type of traceback objects such as found in ``sys.exc_info()[2]``. + The type of traceback objects such as found in ``sys.exception().__traceback__``. See :ref:`the language reference <traceback-objects>` for details of the available attributes and operations, and guidance on creating tracebacks @@ -417,6 +464,12 @@ Standard names are defined for the following types: .. versionadded:: 3.9 + .. describe:: hash(proxy) + + Return a hash of the underlying mapping. + + .. versionadded:: 3.12 + Additional Utility Classes and Functions ---------------------------------------- @@ -480,7 +533,7 @@ Coroutine Utility Functions The generator-based coroutine is still a :term:`generator iterator`, but is also considered to be a :term:`coroutine` object and is :term:`awaitable`. However, it may not necessarily implement - the :meth:`__await__` method. + the :meth:`~object.__await__` method. If *gen_func* is a generator function, it will be modified in-place. diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index 7fc0aa3a..f36dc76c 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -2,6 +2,12 @@ :mod:`typing` --- Support for type hints ======================================== +.. testsetup:: * + + import typing + from dataclasses import dataclass + from typing import * + .. module:: typing :synopsis: Support for type hints (see :pep:`484`). @@ -17,10 +23,9 @@ -------------- -This module provides runtime support for type hints. The most fundamental -support consists of the types :data:`Any`, :data:`Union`, :data:`Callable`, -:class:`TypeVar`, and :class:`Generic`. For a full specification, please see -:pep:`484`. For a simplified introduction to type hints, see :pep:`483`. +This module provides runtime support for type hints. For the original +specification of the typing system, see :pep:`484`. For a simplified +introduction to type hints, see :pep:`483`. The function below takes and returns a string and is annotated as follows:: @@ -41,9 +46,18 @@ For a summary of deprecated features and a deprecation timeline, please see .. seealso:: - The documentation at https://typing.readthedocs.io/ serves as useful reference - for type system features, useful typing related tools and typing best practices. + `"Typing cheat sheet" <https://mypy.readthedocs.io/en/stable/cheat_sheet_py3.html>`_ + A quick overview of type hints (hosted at the mypy docs) + "Type System Reference" section of `the mypy docs <https://mypy.readthedocs.io/en/stable/index.html>`_ + The Python typing system is standardised via PEPs, so this reference + should broadly apply to most Python type checkers. (Some parts may still + be specific to mypy.) + + `"Static Typing with Python" <https://typing.readthedocs.io/en/latest/>`_ + Type-checker-agnostic documentation written by the community detailing + type system features, useful typing related tools and typing best + practices. .. _relevant-peps: @@ -52,7 +66,12 @@ Relevant PEPs Since the initial introduction of type hints in :pep:`484` and :pep:`483`, a number of PEPs have modified and enhanced Python's framework for type -annotations. These include: +annotations: + +.. raw:: html + + <details> + <summary><a style="cursor:pointer;">The full list of PEPs</a></summary> * :pep:`526`: Syntax for Variable Annotations *Introducing* syntax for annotating variables outside of function @@ -91,16 +110,30 @@ annotations. These include: *Introducing* :data:`LiteralString` * :pep:`681`: Data Class Transforms *Introducing* the :func:`@dataclass_transform<dataclass_transform>` decorator +* :pep:`692`: Using ``TypedDict`` for more precise ``**kwargs`` typing + *Introducing* a new way of typing ``**kwargs`` with :data:`Unpack` and + :data:`TypedDict` +* :pep:`695`: Type Parameter Syntax + *Introducing* builtin syntax for creating generic functions, classes, and type aliases. +* :pep:`698`: Adding an override decorator to typing + *Introducing* the :func:`@override<override>` decorator + +.. raw:: html + + </details> + <br> .. _type-aliases: Type aliases ============ -A type alias is defined by assigning the type to the alias. In this example, -``Vector`` and ``list[float]`` will be treated as interchangeable synonyms:: +A type alias is defined using the :keyword:`type` statement, which creates +an instance of :class:`TypeAliasType`. In this example, +``Vector`` and ``list[float]`` will be treated equivalently by static type +checkers:: - Vector = list[float] + type Vector = list[float] def scale(scalar: float, vector: Vector) -> Vector: return [scalar * num for num in vector] @@ -112,9 +145,9 @@ Type aliases are useful for simplifying complex type signatures. For example:: from collections.abc import Sequence - ConnectionOptions = dict[str, str] - Address = tuple[str, int] - Server = tuple[Address, ConnectionOptions] + type ConnectionOptions = dict[str, str] + type Address = tuple[str, int] + type Server = tuple[Address, ConnectionOptions] def broadcast_message(message: str, servers: Sequence[Server]) -> None: ... @@ -126,8 +159,17 @@ Type aliases are useful for simplifying complex type signatures. For example:: servers: Sequence[tuple[tuple[str, int], dict[str, str]]]) -> None: ... -Note that ``None`` as a type hint is a special case and is replaced by -``type(None)``. +The :keyword:`type` statement is new in Python 3.12. For backwards +compatibility, type aliases can also be created through simple assignment:: + + Vector = list[float] + +Or marked with :data:`TypeAlias` to make it explicit that this is a type alias, +not a normal variable assignment:: + + from typing import TypeAlias + + Vector: TypeAlias = list[float] .. _distinct: @@ -194,7 +236,7 @@ See :pep:`484` for more details. .. note:: Recall that the use of a type alias declares two types to be *equivalent* to - one another. Doing ``Alias = Original`` will make the static type checker + one another. Doing ``type Alias = Original`` will make the static type checker treat ``Alias`` as being *exactly equivalent* to ``Original`` in all cases. This is useful when you want to simplify complex type signatures. @@ -208,35 +250,85 @@ See :pep:`484` for more details. .. versionadded:: 3.5.2 .. versionchanged:: 3.10 - ``NewType`` is now a class rather than a function. There is some additional - runtime cost when calling ``NewType`` over a regular function. However, this - cost will be reduced in 3.11.0. + ``NewType`` is now a class rather than a function. As a result, there is + some additional runtime cost when calling ``NewType`` over a regular + function. +.. versionchanged:: 3.11 + The performance of calling ``NewType`` has been restored to its level in + Python 3.9. -Callable -======== +.. _annotating-callables: -Frameworks expecting callback functions of specific signatures might be -type hinted using ``Callable[[Arg1Type, Arg2Type], ReturnType]``. +Annotating callable objects +=========================== -For example:: +Functions -- or other :term:`callable` objects -- can be annotated using +:class:`collections.abc.Callable` or :data:`typing.Callable`. +``Callable[[int], str]`` signifies a function that takes a single parameter +of type :class:`int` and returns a :class:`str`. + +For example: - from collections.abc import Callable +.. testcode:: + + from collections.abc import Callable, Awaitable def feeder(get_next_item: Callable[[], str]) -> None: - # Body + ... # Body def async_query(on_success: Callable[[int], None], on_error: Callable[[int, Exception], None]) -> None: - # Body + ... # Body async def on_update(value: str) -> None: - # Body + ... # Body + callback: Callable[[str], Awaitable[None]] = on_update -It is possible to declare the return type of a callable without specifying -the call signature by substituting a literal ellipsis -for the list of arguments in the type hint: ``Callable[..., ReturnType]``. +The subscription syntax must always be used with exactly two values: the +argument list and the return type. The argument list must be a list of types, +a :class:`ParamSpec`, :data:`Concatenate`, or an ellipsis. The return type must +be a single type. + +If a literal ellipsis ``...`` is given as the argument list, it indicates that +a callable with any arbitrary parameter list would be acceptable: + +.. testcode:: + + def concat(x: str, y: str) -> str: + return x + y + + x: Callable[..., str] + x = str # OK + x = concat # Also OK + +``Callable`` cannot express complex signatures such as functions that take a +variadic number of arguments, :func:`overloaded functions <overload>`, or +functions that have keyword-only parameters. However, these signatures can be +expressed by defining a :class:`Protocol` class with a +:meth:`~object.__call__` method: + +.. testcode:: + + from collections.abc import Iterable + from typing import Protocol + + class Combiner(Protocol): + def __call__(self, *vals: bytes, maxlen: int | None = None) -> list[bytes]: ... + + def batch_proc(data: Iterable[bytes], cb_results: Combiner) -> bytes: + for item in data: + ... + + def good_cb(*vals: bytes, maxlen: int | None = None) -> list[bytes]: + ... + def bad_cb(*vals: bytes, maxitems: int | None) -> list[bytes]: + ... + + batch_proc([], good_cb) # OK + batch_proc([], bad_cb) # Error! Argument 2 has incompatible type because of + # different name and kind in the callback Callables which take other callables as arguments may indicate that their parameter types are dependent on each other using :class:`ParamSpec`. @@ -260,28 +352,150 @@ Generics ======== Since type information about objects kept in containers cannot be statically -inferred in a generic way, abstract base classes have been extended to support -subscription to denote expected types for container elements. +inferred in a generic way, many container classes in the standard library support +subscription to denote the expected types of container elements. -:: +.. testcode:: from collections.abc import Mapping, Sequence + class Employee: ... + + # Sequence[Employee] indicates that all elements in the sequence + # must be instances of "Employee". + # Mapping[str, str] indicates that all keys and all values in the mapping + # must be strings. def notify_by_email(employees: Sequence[Employee], overrides: Mapping[str, str]) -> None: ... -Generics can be parameterized by using a factory available in typing -called :class:`TypeVar`. +Generic functions and classes can be parameterized by using +:ref:`type parameter syntax <type-params>`:: -:: + from collections.abc import Sequence + + def first[T](l: Sequence[T]) -> T: # Function is generic over the TypeVar "T" + return l[0] + +Or by using the :class:`TypeVar` factory directly:: from collections.abc import Sequence from typing import TypeVar - T = TypeVar('T') # Declare type variable + U = TypeVar('U') # Declare type variable "U" - def first(l: Sequence[T]) -> T: # Generic function - return l[0] + def second(l: Sequence[U]) -> U: # Function is generic over the TypeVar "U" + return l[1] + +.. versionchanged:: 3.12 + Syntactic support for generics is new in Python 3.12. + +.. _annotating-tuples: + +Annotating tuples +================= + +For most containers in Python, the typing system assumes that all elements in +the container will be of the same type. For example:: + + from collections.abc import Mapping + + # Type checker will infer that all elements in ``x`` are meant to be ints + x: list[int] = [] + + # Type checker error: ``list`` only accepts a single type argument: + y: list[int, str] = [1, 'foo'] + + # Type checker will infer that all keys in ``z`` are meant to be strings, + # and that all values in ``z`` are meant to be either strings or ints + z: Mapping[str, str | int] = {} + +:class:`list` only accepts one type argument, so a type checker would emit an +error on the ``y`` assignment above. Similarly, +:class:`~collections.abc.Mapping` only accepts two type arguments: the first +indicates the type of the keys, and the second indicates the type of the +values. + +Unlike most other Python containers, however, it is common in idiomatic Python +code for tuples to have elements which are not all of the same type. For this +reason, tuples are special-cased in Python's typing system. :class:`tuple` +accepts *any number* of type arguments:: + + # OK: ``x`` is assigned to a tuple of length 1 where the sole element is an int + x: tuple[int] = (5,) + + # OK: ``y`` is assigned to a tuple of length 2; + # element 1 is an int, element 2 is a str + y: tuple[int, str] = (5, "foo") + + # Error: the type annotation indicates a tuple of length 1, + # but ``z`` has been assigned to a tuple of length 3 + z: tuple[int] = (1, 2, 3) + +To denote a tuple which could be of *any* length, and in which all elements are +of the same type ``T``, use ``tuple[T, ...]``. To denote an empty tuple, use +``tuple[()]``. Using plain ``tuple`` as an annotation is equivalent to using +``tuple[Any, ...]``:: + + x: tuple[int, ...] = (1, 2) + # These reassignments are OK: ``tuple[int, ...]`` indicates x can be of any length + x = (1, 2, 3) + x = () + # This reassignment is an error: all elements in ``x`` must be ints + x = ("foo", "bar") + + # ``y`` can only ever be assigned to an empty tuple + y: tuple[()] = () + + z: tuple = ("foo", "bar") + # These reassignments are OK: plain ``tuple`` is equivalent to ``tuple[Any, ...]`` + z = (1, 2, 3) + z = () + +.. _type-of-class-objects: + +The type of class objects +========================= + +A variable annotated with ``C`` may accept a value of type ``C``. In +contrast, a variable annotated with ``type[C]`` (or +:class:`typing.Type[C] <Type>`) may accept values that are classes +themselves -- specifically, it will accept the *class object* of ``C``. For +example:: + + a = 3 # Has type ``int`` + b = int # Has type ``type[int]`` + c = type(a) # Also has type ``type[int]`` + +Note that ``type[C]`` is covariant:: + + class User: ... + class ProUser(User): ... + class TeamUser(User): ... + + def make_new_user(user_class: type[User]) -> User: + # ... + return user_class() + + make_new_user(User) # OK + make_new_user(ProUser) # Also OK: ``type[ProUser]`` is a subtype of ``type[User]`` + make_new_user(TeamUser) # Still fine + make_new_user(User()) # Error: expected ``type[User]`` but got ``User`` + make_new_user(int) # Error: ``type[int]`` is not a subtype of ``type[User]`` + +The only legal parameters for :class:`type` are classes, :data:`Any`, +:ref:`type variables <generics>`, and unions of any of these types. +For example:: + + def new_non_team_user(user_class: type[BasicUser | ProUser]): ... + + new_non_team_user(BasicUser) # OK + new_non_team_user(ProUser) # OK + new_non_team_user(TeamUser) # Error: ``type[TeamUser]`` is not a subtype + # of ``type[BasicUser | ProUser]`` + new_non_team_user(User) # Also an error + +``type[Any]`` is equivalent to :class:`type`, which is the root of Python's +:ref:`metaclass hierarchy <metaclasses>`. .. _user-defined-generics: @@ -292,12 +506,9 @@ A user-defined class can be defined as a generic class. :: - from typing import TypeVar, Generic from logging import Logger - T = TypeVar('T') - - class LoggedVar(Generic[T]): + class LoggedVar[T]: def __init__(self, value: T, name: str, logger: Logger) -> None: self.name = name self.logger = logger @@ -314,12 +525,23 @@ A user-defined class can be defined as a generic class. def log(self, message: str) -> None: self.logger.info('%s: %s', self.name, message) -``Generic[T]`` as a base class defines that the class ``LoggedVar`` takes a -single type parameter ``T`` . This also makes ``T`` valid as a type within the -class body. +This syntax indicates that the class ``LoggedVar`` is parameterised around a +single :class:`type variable <TypeVar>` ``T`` . This also makes ``T`` valid as +a type within the class body. + +Generic classes implicitly inherit from :class:`Generic`. For compatibility +with Python 3.11 and lower, it is also possible to inherit explicitly from +:class:`Generic` to indicate a generic class:: + + from typing import TypeVar, Generic + + T = TypeVar('T') + + class LoggedVar(Generic[T]): + ... -The :class:`Generic` base class defines :meth:`~object.__class_getitem__` so -that ``LoggedVar[T]`` is valid as a type:: +Generic classes have :meth:`~object.__class_getitem__` methods, meaning they +can be parameterised at runtime (e.g. ``LoggedVar[int]`` below):: from collections.abc import Iterable @@ -332,11 +554,14 @@ A generic type can have any number of type variables. All varieties of from typing import TypeVar, Generic, Sequence - T = TypeVar('T', contravariant=True) - B = TypeVar('B', bound=Sequence[bytes], covariant=True) - S = TypeVar('S', int, str) + class WeirdTrio[T, B: Sequence[bytes], S: (int, str)]: + ... + + OldT = TypeVar('OldT', contravariant=True) + OldB = TypeVar('OldB', bound=Sequence[bytes], covariant=True) + OldS = TypeVar('OldS', int, str) - class WeirdTrio(Generic[T, B, S]): + class OldWeirdTrio(Generic[OldT, OldB, OldS]): ... Each type variable argument to :class:`Generic` must be distinct. @@ -345,91 +570,108 @@ This is thus invalid:: from typing import TypeVar, Generic ... + class Pair[M, M]: # SyntaxError + ... + T = TypeVar('T') class Pair(Generic[T, T]): # INVALID ... -You can use multiple inheritance with :class:`Generic`:: +Generic classes can also inherit from other classes:: from collections.abc import Sized - from typing import TypeVar, Generic - T = TypeVar('T') - - class LinkedList(Sized, Generic[T]): + class LinkedList[T](Sized): ... -When inheriting from generic classes, some type variables could be fixed:: +When inheriting from generic classes, some type parameters could be fixed:: from collections.abc import Mapping - from typing import TypeVar - T = TypeVar('T') - - class MyDict(Mapping[str, T]): + class MyDict[T](Mapping[str, T]): ... In this case ``MyDict`` has a single parameter, ``T``. Using a generic class without specifying type parameters assumes :data:`Any` for each position. In the following example, ``MyIterable`` is -not generic but implicitly inherits from ``Iterable[Any]``:: +not generic but implicitly inherits from ``Iterable[Any]``: + +.. testcode:: from collections.abc import Iterable class MyIterable(Iterable): # Same as Iterable[Any] + ... -User defined generic type aliases are also supported. Examples:: +User-defined generic type aliases are also supported. Examples:: from collections.abc import Iterable - from typing import TypeVar - S = TypeVar('S') - Response = Iterable[S] | int + + type Response[S] = Iterable[S] | int # Return type here is same as Iterable[str] | int def response(query: str) -> Response[str]: ... - T = TypeVar('T', int, float, complex) - Vec = Iterable[tuple[T, T]] + type Vec[T] = Iterable[tuple[T, T]] - def inproduct(v: Vec[T]) -> T: # Same as Iterable[tuple[T, T]] + def inproduct[T: (int, float, complex)](v: Vec[T]) -> T: # Same as Iterable[tuple[T, T]] return sum(x*y for x, y in v) +For backward compatibility, generic type aliases can also be created +through a simple assignment:: + + from collections.abc import Iterable + from typing import TypeVar + + S = TypeVar("S") + Response = Iterable[S] | int + .. versionchanged:: 3.7 :class:`Generic` no longer has a custom metaclass. +.. versionchanged:: 3.12 + Syntactic support for generics and type aliases is new in version 3.12. + Previously, generic classes had to explicitly inherit from :class:`Generic` + or contain a type variable in one of their bases. + User-defined generics for parameter expressions are also supported via parameter -specification variables in the form ``Generic[P]``. The behavior is consistent +specification variables in the form ``[**P]``. The behavior is consistent with type variables' described above as parameter specification variables are treated by the typing module as a specialized type variable. The one exception to this is that a list of types can be used to substitute a :class:`ParamSpec`:: - >>> from typing import Generic, ParamSpec, TypeVar - - >>> T = TypeVar('T') - >>> P = ParamSpec('P') - - >>> class Z(Generic[T, P]): ... + >>> class Z[T, **P]: ... # T is a TypeVar; P is a ParamSpec ... >>> Z[int, [dict, float]] - __main__.Z[int, (<class 'dict'>, <class 'float'>)] + __main__.Z[int, [dict, float]] + +Classes generic over a :class:`ParamSpec` can also be created using explicit +inheritance from :class:`Generic`. In this case, ``**`` is not used:: + + from typing import ParamSpec, Generic + + P = ParamSpec('P') + class Z(Generic[P]): + ... -Furthermore, a generic with only one parameter specification variable will accept +Another difference between :class:`TypeVar` and :class:`ParamSpec` is that a +generic with only one parameter specification variable will accept parameter lists in the forms ``X[[Type1, Type2, ...]]`` and also ``X[Type1, Type2, ...]`` for aesthetic reasons. Internally, the latter is converted to the former, so the following are equivalent:: - >>> class X(Generic[P]): ... + >>> class X[**P]: ... ... >>> X[int, str] - __main__.X[(<class 'int'>, <class 'str'>)] + __main__.X[[int, str]] >>> X[[int, str]] - __main__.X[(<class 'int'>, <class 'str'>)] + __main__.X[[int, str]] -Do note that generics with :class:`ParamSpec` may not have correct +Note that generics with :class:`ParamSpec` may not have correct ``__parameters__`` after substitution in some cases because they are intended primarily for static type checking. @@ -439,7 +681,7 @@ are intended primarily for static type checking. A user-defined generic class can have ABCs as base classes without a metaclass conflict. Generic metaclasses are not supported. The outcome of parameterizing -generics is cached, and most types in the typing module are hashable and +generics is cached, and most types in the typing module are :term:`hashable` and comparable for equality. @@ -564,25 +806,7 @@ can define new custom protocols to fully enjoy structural subtyping Module contents =============== -The module defines the following classes, functions and decorators. - -.. note:: - - This module defines several types that are subclasses of pre-existing - standard library classes which also extend :class:`Generic` - to support type variables inside ``[]``. - These types became redundant in Python 3.9 when the - corresponding pre-existing classes were enhanced to support ``[]``. - - The redundant types are deprecated as of Python 3.9 but no - deprecation warnings will be issued by the interpreter. - It is expected that type checkers will flag the deprecated types - when the checked program targets Python 3.9 or newer. - - The deprecated types will be removed from the :mod:`typing` module - in the first Python version released 5 years after the release of Python 3.9.0. - See details in :pep:`585`—*Type Hinting Generics In Standard Collections*. - +The ``typing`` module defines the following classes, functions and decorators. Special typing primitives ------------------------- @@ -590,7 +814,8 @@ Special typing primitives Special types """"""""""""" -These can be used as types in annotations and do not support ``[]``. +These can be used as types in annotations. They do not support subscription +using ``[]``. .. data:: Any @@ -604,29 +829,68 @@ These can be used as types in annotations and do not support ``[]``. avoiding type checker errors with classes that can duck type anywhere or are highly dynamic. +.. data:: AnyStr + + A :ref:`constrained type variable <typing-constrained-typevar>`. + + Definition:: + + AnyStr = TypeVar('AnyStr', str, bytes) + + ``AnyStr`` is meant to be used for functions that may accept :class:`str` or + :class:`bytes` arguments but cannot allow the two to mix. + + For example:: + + def concat(a: AnyStr, b: AnyStr) -> AnyStr: + return a + b + + concat("foo", "bar") # OK, output has type 'str' + concat(b"foo", b"bar") # OK, output has type 'bytes' + concat("foo", b"bar") # Error, cannot mix str and bytes + + Note that, despite its name, ``AnyStr`` has nothing to do with the + :class:`Any` type, nor does it mean "any string". In particular, ``AnyStr`` + and ``str | bytes`` are different from each other and have different use + cases:: + + # Invalid use of AnyStr: + # The type variable is used only once in the function signature, + # so cannot be "solved" by the type checker + def greet_bad(cond: bool) -> AnyStr: + return "hi there!" if cond else b"greetings!" + + # The better way of annotating this function: + def greet_proper(cond: bool) -> str | bytes: + return "hi there!" if cond else b"greetings!" + .. data:: LiteralString - Special type that includes only literal strings. A string + Special type that includes only literal strings. + + Any string literal is compatible with ``LiteralString``, as is another - ``LiteralString``, but an object typed as just ``str`` is not. + ``LiteralString``. However, an object typed as just ``str`` is not. A string created by composing ``LiteralString``-typed objects is also acceptable as a ``LiteralString``. - Example:: + Example: - def run_query(sql: LiteralString) -> ... + .. testcode:: + + def run_query(sql: LiteralString) -> None: ... def caller(arbitrary_string: str, literal_string: LiteralString) -> None: - run_query("SELECT * FROM students") # ok - run_query(literal_string) # ok - run_query("SELECT * FROM " + literal_string) # ok + run_query("SELECT * FROM students") # OK + run_query(literal_string) # OK + run_query("SELECT * FROM " + literal_string) # OK run_query(arbitrary_string) # type checker error run_query( # type checker error f"SELECT * FROM students WHERE name = {arbitrary_string}" ) - This is useful for sensitive APIs where arbitrary user-generated + ``LiteralString`` is useful for sensitive APIs where arbitrary user-generated strings could generate problems. For example, the two cases above that generate type checker errors could be vulnerable to an SQL injection attack. @@ -643,20 +907,20 @@ These can be used as types in annotations and do not support ``[]``. This can be used to define a function that should never be called, or a function that never returns:: - from typing import Never + from typing import Never - def never_call_me(arg: Never) -> None: - pass + def never_call_me(arg: Never) -> None: + pass - def int_or_str(arg: int | str) -> None: - never_call_me(arg) # type checker error - match arg: - case int(): - print("It's an int") - case str(): - print("It's a str") - case _: - never_call_me(arg) # ok, arg is of type Never + def int_or_str(arg: int | str) -> None: + never_call_me(arg) # type checker error + match arg: + case int(): + print("It's an int") + case str(): + print("It's a str") + case _: + never_call_me(arg) # OK, arg is of type Never .. versionadded:: 3.11 @@ -666,6 +930,7 @@ These can be used as types in annotations and do not support ``[]``. .. data:: NoReturn Special type indicating that a function never returns. + For example:: from typing import NoReturn @@ -685,15 +950,20 @@ These can be used as types in annotations and do not support ``[]``. .. data:: Self Special type to represent the current enclosed class. + For example:: - from typing import Self + from typing import Self, reveal_type class Foo: - def return_self(self) -> Self: - ... - return self + def return_self(self) -> Self: + ... + return self + class SubclassOfFoo(Foo): pass + + reveal_type(Foo().return_self()) # Revealed type is "Foo" + reveal_type(SubclassOfFoo().return_self()) # Revealed type is "SubclassOfFoo" This annotation is semantically equivalent to the following, albeit in a more succinct fashion:: @@ -703,19 +973,15 @@ These can be used as types in annotations and do not support ``[]``. Self = TypeVar("Self", bound="Foo") class Foo: - def return_self(self: Self) -> Self: - ... - return self - - In general if something currently follows the pattern of:: - - class Foo: - def return_self(self) -> "Foo": - ... - return self + def return_self(self: Self) -> Self: + ... + return self - You should use :data:`Self` as calls to ``SubclassOfFoo.return_self`` would have - ``Foo`` as the return type and not ``SubclassOfFoo``. + In general, if something returns ``self``, as in the above examples, you + should use ``Self`` as the return annotation. If ``Foo.return_self`` was + annotated as returning ``"Foo"``, then the type checker would infer the + object returned from ``SubclassOfFoo.return_self`` as being of type ``Foo`` + rather than ``SubclassOfFoo``. Other common use cases include: @@ -723,6 +989,17 @@ These can be used as types in annotations and do not support ``[]``. of the ``cls`` parameter. - Annotating an :meth:`~object.__enter__` method which returns self. + You should not use ``Self`` as the return annotation if the method is not + guaranteed to return an instance of a subclass when the class is + subclassed:: + + class Eggs: + # Self would be an incorrect return annotation here, + # as the object returned is always an instance of Eggs, + # even in subclasses + def returns_eggs(self) -> "Eggs": + return Eggs() + See :pep:`673` for more details. .. versionadded:: 3.11 @@ -730,38 +1007,52 @@ These can be used as types in annotations and do not support ``[]``. .. data:: TypeAlias Special annotation for explicitly declaring a :ref:`type alias <type-aliases>`. + For example:: - from typing import TypeAlias + from typing import TypeAlias - Factors: TypeAlias = list[int] + Factors: TypeAlias = list[int] - See :pep:`613` for more details about explicit type aliases. + ``TypeAlias`` is particularly useful on older Python versions for annotating + aliases that make use of forward references, as it can be hard for type + checkers to distinguish these from normal variable assignments: - .. versionadded:: 3.10 + .. testcode:: -Special forms -""""""""""""" + from typing import Generic, TypeAlias, TypeVar -These can be used as types in annotations using ``[]``, each having a unique syntax. + T = TypeVar("T") -.. data:: Tuple + # "Box" does not exist yet, + # so we have to use quotes for the forward reference on Python <3.12. + # Using ``TypeAlias`` tells the type checker that this is a type alias declaration, + # not a variable assignment to a string. + BoxOfStrings: TypeAlias = "Box[str]" - Tuple type; ``Tuple[X, Y]`` is the type of a tuple of two items - with the first item of type X and the second of type Y. The type of - the empty tuple can be written as ``Tuple[()]``. + class Box(Generic[T]): + @classmethod + def make_box_of_strings(cls) -> BoxOfStrings: ... - Example: ``Tuple[T1, T2]`` is a tuple of two elements corresponding - to type variables T1 and T2. ``Tuple[int, float, str]`` is a tuple - of an int, a float and a string. + See :pep:`613` for more details. - To specify a variable-length tuple of homogeneous type, - use literal ellipsis, e.g. ``Tuple[int, ...]``. A plain :data:`Tuple` - is equivalent to ``Tuple[Any, ...]``, and in turn to :class:`tuple`. + .. versionadded:: 3.10 - .. deprecated:: 3.9 - :class:`builtins.tuple <tuple>` now supports subscripting (``[]``). - See :pep:`585` and :ref:`types-genericalias`. + .. deprecated:: 3.12 + :data:`TypeAlias` is deprecated in favor of the :keyword:`type` statement, + which creates instances of :class:`TypeAliasType` + and which natively supports forward references. + Note that while :data:`TypeAlias` and :class:`TypeAliasType` serve + similar purposes and have similar names, they are distinct and the + latter is not the type of the former. + Removal of :data:`TypeAlias` is not currently planned, but users + are encouraged to migrate to :keyword:`type` statements. + +Special forms +""""""""""""" + +These can be used as types in annotations. They all support subscription using +``[]``, but each has a unique syntax. .. data:: Union @@ -800,8 +1091,6 @@ These can be used as types in annotations using ``[]``, each having a unique syn .. data:: Optional - Optional type. - ``Optional[X]`` is equivalent to ``X | None`` (or ``Union[X, None]``). Note that this is not the same concept as an optional argument, @@ -823,50 +1112,16 @@ These can be used as types in annotations using ``[]``, each having a unique syn Optional can now be written as ``X | None``. See :ref:`union type expressions<types-union>`. -.. data:: Callable - - Callable type; ``Callable[[int], str]`` is a function of (int) -> str. - - The subscription syntax must always be used with exactly two - values: the argument list and the return type. The argument list - must be a list of types or an ellipsis; the return type must be - a single type. - - There is no syntax to indicate optional or keyword arguments; - such function types are rarely used as callback types. - ``Callable[..., ReturnType]`` (literal ellipsis) can be used to - type hint a callable taking any number of arguments and returning - ``ReturnType``. A plain :data:`Callable` is equivalent to - ``Callable[..., Any]``, and in turn to - :class:`collections.abc.Callable`. - - Callables which take other callables as arguments may indicate that their - parameter types are dependent on each other using :class:`ParamSpec`. - Additionally, if that callable adds or removes arguments from other - callables, the :data:`Concatenate` operator may be used. They - take the form ``Callable[ParamSpecVariable, ReturnType]`` and - ``Callable[Concatenate[Arg1Type, Arg2Type, ..., ParamSpecVariable], ReturnType]`` - respectively. - - .. deprecated:: 3.9 - :class:`collections.abc.Callable` now supports subscripting (``[]``). - See :pep:`585` and :ref:`types-genericalias`. - - .. versionchanged:: 3.10 - ``Callable`` now supports :class:`ParamSpec` and :data:`Concatenate`. - See :pep:`612` for more details. - - .. seealso:: - The documentation for :class:`ParamSpec` and :class:`Concatenate` provide - examples of usage with ``Callable``. - .. data:: Concatenate - Used with :data:`Callable` and :class:`ParamSpec` to type annotate a higher - order callable which adds, removes, or transforms parameters of another + Special form for annotating higher-order functions. + + ``Concatenate`` can be used in conjunction with :ref:`Callable <annotating-callables>` and + :class:`ParamSpec` to annotate a higher-order callable which adds, removes, + or transforms parameters of another callable. Usage is in the form ``Concatenate[Arg1Type, Arg2Type, ..., ParamSpecVariable]``. ``Concatenate`` - is currently only valid when used as the first argument to a :data:`Callable`. + is currently only valid when used as the first argument to a :ref:`Callable <annotating-callables>`. The last parameter to ``Concatenate`` must be a :class:`ParamSpec` or ellipsis (``...``). @@ -905,75 +1160,33 @@ These can be used as types in annotations using ``[]``, each having a unique syn # We don't need to pass in the lock ourselves thanks to the decorator. sum_threadsafe([1.1, 2.2, 3.3]) -.. versionadded:: 3.10 - -.. seealso:: - - * :pep:`612` -- Parameter Specification Variables (the PEP which introduced - ``ParamSpec`` and ``Concatenate``). - * :class:`ParamSpec` and :class:`Callable`. - - -.. class:: Type(Generic[CT_co]) - - A variable annotated with ``C`` may accept a value of type ``C``. In - contrast, a variable annotated with ``Type[C]`` may accept values that are - classes themselves -- specifically, it will accept the *class object* of - ``C``. For example:: - - a = 3 # Has type 'int' - b = int # Has type 'Type[int]' - c = type(a) # Also has type 'Type[int]' - - Note that ``Type[C]`` is covariant:: - - class User: ... - class BasicUser(User): ... - class ProUser(User): ... - class TeamUser(User): ... - - # Accepts User, BasicUser, ProUser, TeamUser, ... - def make_new_user(user_class: Type[User]) -> User: - # ... - return user_class() - - The fact that ``Type[C]`` is covariant implies that all subclasses of - ``C`` should implement the same constructor signature and class method - signatures as ``C``. The type checker should flag violations of this, - but should also allow constructor calls in subclasses that match the - constructor calls in the indicated base class. How the type checker is - required to handle this particular case may change in future revisions of - :pep:`484`. - - The only legal parameters for :class:`Type` are classes, :data:`Any`, - :ref:`type variables <generics>`, and unions of any of these types. - For example:: + .. versionadded:: 3.10 - def new_non_team_user(user_class: Type[BasicUser | ProUser]): ... + .. seealso:: - ``Type[Any]`` is equivalent to ``Type`` which in turn is equivalent - to ``type``, which is the root of Python's metaclass hierarchy. + * :pep:`612` -- Parameter Specification Variables (the PEP which introduced + ``ParamSpec`` and ``Concatenate``) + * :class:`ParamSpec` + * :ref:`annotating-callables` - .. versionadded:: 3.5.2 +.. data:: Literal - .. deprecated:: 3.9 - :class:`builtins.type <type>` now supports subscripting (``[]``). - See :pep:`585` and :ref:`types-genericalias`. + Special typing form to define "literal types". -.. data:: Literal + ``Literal`` can be used to indicate to type checkers that the + annotated object has a value equivalent to one of the + provided literals. - A type that can be used to indicate to type checkers that the - corresponding variable or function parameter has a value equivalent to - the provided literal (or one of several literals). For example:: + For example:: def validate_simple(data: Any) -> Literal[True]: # always returns True ... - MODE = Literal['r', 'rb', 'w', 'wb'] - def open_helper(file: str, mode: MODE) -> str: + type Mode = Literal['r', 'rb', 'w', 'wb'] + def open_helper(file: str, mode: Mode) -> str: ... - open_helper('/some/path', 'r') # Passes type check + open_helper('/some/path', 'r') # Passes type check open_helper('/other/path', 'typo') # Error in type checker ``Literal[...]`` cannot be subclassed. At runtime, an arbitrary value @@ -1016,8 +1229,12 @@ These can be used as types in annotations using ``[]``, each having a unique syn .. data:: Final - A special typing construct to indicate to type checkers that a name - cannot be re-assigned or overridden in a subclass. For example:: + Special typing construct to indicate final names to type checkers. + + Final names cannot be reassigned in any scope. Final names declared in class + scopes cannot be overridden in subclasses. + + For example:: MAX_SIZE: Final = 9000 MAX_SIZE += 1 # Error reported by type checker @@ -1035,10 +1252,17 @@ These can be used as types in annotations using ``[]``, each having a unique syn .. data:: Required + Special typing construct to mark a :class:`TypedDict` key as required. + + This is mainly useful for ``total=False`` TypedDicts. See :class:`TypedDict` + and :pep:`655` for more details. + + .. versionadded:: 3.11 + .. data:: NotRequired - Special typing constructs that mark individual keys of a :class:`TypedDict` - as either required or non-required respectively. + Special typing construct to mark a :class:`TypedDict` key as potentially + missing. See :class:`TypedDict` and :pep:`655` for more details. @@ -1046,92 +1270,150 @@ These can be used as types in annotations using ``[]``, each having a unique syn .. data:: Annotated - A type, introduced in :pep:`593` (``Flexible function and variable - annotations``), to decorate existing types with context-specific metadata - (possibly multiple pieces of it, as ``Annotated`` is variadic). - Specifically, a type ``T`` can be annotated with metadata ``x`` via the - typehint ``Annotated[T, x]``. This metadata can be used for either static - analysis or at runtime. If a library (or tool) encounters a typehint - ``Annotated[T, x]`` and has no special logic for metadata ``x``, it - should ignore it and simply treat the type as ``T``. Unlike the - ``no_type_check`` functionality that currently exists in the ``typing`` - module which completely disables typechecking annotations on a function - or a class, the ``Annotated`` type allows for both static typechecking - of ``T`` (which can safely ignore ``x``) - together with runtime access to ``x`` within a specific application. - - Ultimately, the responsibility of how to interpret the annotations (if - at all) is the responsibility of the tool or library encountering the - ``Annotated`` type. A tool or library encountering an ``Annotated`` type - can scan through the annotations to determine if they are of interest - (e.g., using ``isinstance()``). - - When a tool or a library does not support annotations or encounters an - unknown annotation it should just ignore it and treat annotated type as - the underlying type. - - It's up to the tool consuming the annotations to decide whether the - client is allowed to have several annotations on one type and how to - merge those annotations. - - Since the ``Annotated`` type allows you to put several annotations of - the same (or different) type(s) on any node, the tools or libraries - consuming those annotations are in charge of dealing with potential - duplicates. For example, if you are doing value range analysis you might - allow this:: - - T1 = Annotated[int, ValueRange(-10, 5)] - T2 = Annotated[T1, ValueRange(-20, 3)] - - Passing ``include_extras=True`` to :func:`get_type_hints` lets one - access the extra annotations at runtime. - - The details of the syntax: + Special typing form to add context-specific metadata to an annotation. + + Add metadata ``x`` to a given type ``T`` by using the annotation + ``Annotated[T, x]``. Metadata added using ``Annotated`` can be used by + static analysis tools or at runtime. At runtime, the metadata is stored + in a :attr:`!__metadata__` attribute. + + If a library or tool encounters an annotation ``Annotated[T, x]`` and has + no special logic for the metadata, it should ignore the metadata and simply + treat the annotation as ``T``. As such, ``Annotated`` can be useful for code + that wants to use annotations for purposes outside Python's static typing + system. + + Using ``Annotated[T, x]`` as an annotation still allows for static + typechecking of ``T``, as type checkers will simply ignore the metadata ``x``. + In this way, ``Annotated`` differs from the + :func:`@no_type_check <no_type_check>` decorator, which can also be used for + adding annotations outside the scope of the typing system, but + completely disables typechecking for a function or class. + + The responsibility of how to interpret the metadata + lies with the the tool or library encountering an + ``Annotated`` annotation. A tool or library encountering an ``Annotated`` type + can scan through the metadata elements to determine if they are of interest + (e.g., using :func:`isinstance`). + + .. describe:: Annotated[<type>, <metadata>] + + Here is an example of how you might use ``Annotated`` to add metadata to + type annotations if you were doing range analysis: + + .. testcode:: + + @dataclass + class ValueRange: + lo: int + hi: int + + T1 = Annotated[int, ValueRange(-10, 5)] + T2 = Annotated[T1, ValueRange(-20, 3)] + + Details of the syntax: * The first argument to ``Annotated`` must be a valid type - * Multiple type annotations are supported (``Annotated`` supports variadic + * Multiple metadata elements can be supplied (``Annotated`` supports variadic arguments):: - Annotated[int, ValueRange(3, 10), ctype("char")] + @dataclass + class ctype: + kind: str + + Annotated[int, ValueRange(3, 10), ctype("char")] - * ``Annotated`` must be called with at least two arguments ( + It is up to the tool consuming the annotations to decide whether the + client is allowed to add multiple metadata elements to one annotation and how to + merge those annotations. + + * ``Annotated`` must be subscripted with at least two arguments ( ``Annotated[int]`` is not valid) - * The order of the annotations is preserved and matters for equality + * The order of the metadata elements is preserved and matters for equality checks:: - Annotated[int, ValueRange(3, 10), ctype("char")] != Annotated[ - int, ctype("char"), ValueRange(3, 10) - ] + assert Annotated[int, ValueRange(3, 10), ctype("char")] != Annotated[ + int, ctype("char"), ValueRange(3, 10) + ] + + * Nested ``Annotated`` types are flattened. The order of the metadata elements + starts with the innermost annotation:: + + assert Annotated[Annotated[int, ValueRange(3, 10)], ctype("char")] == Annotated[ + int, ValueRange(3, 10), ctype("char") + ] + + * Duplicated metadata elements are not removed:: + + assert Annotated[int, ValueRange(3, 10)] != Annotated[ + int, ValueRange(3, 10), ValueRange(3, 10) + ] + + * ``Annotated`` can be used with nested and generic aliases: + + .. testcode:: + + @dataclass + class MaxLen: + value: int + + type Vec[T] = Annotated[list[tuple[T, T]], MaxLen(10)] + + # When used in a type annotation, a type checker will treat "V" the same as + # ``Annotated[list[tuple[int, int]], MaxLen(10)]``: + type V = Vec[int] + + * ``Annotated`` cannot be used with an unpacked :class:`TypeVarTuple`:: + + type Variadic[*Ts] = Annotated[*Ts, Ann1] # NOT valid + + This would be equivalent to:: + + Annotated[T1, T2, T3, ..., Ann1] + + where ``T1``, ``T2``, etc. are :class:`TypeVars <TypeVar>`. This would be + invalid: only one type should be passed to Annotated. + + * By default, :func:`get_type_hints` strips the metadata from annotations. + Pass ``include_extras=True`` to have the metadata preserved: - * Nested ``Annotated`` types are flattened, with metadata ordered - starting with the innermost annotation:: + .. doctest:: - Annotated[Annotated[int, ValueRange(3, 10)], ctype("char")] == Annotated[ - int, ValueRange(3, 10), ctype("char") - ] + >>> from typing import Annotated, get_type_hints + >>> def func(x: Annotated[int, "metadata"]) -> None: pass + ... + >>> get_type_hints(func) + {'x': <class 'int'>, 'return': <class 'NoneType'>} + >>> get_type_hints(func, include_extras=True) + {'x': typing.Annotated[int, 'metadata'], 'return': <class 'NoneType'>} - * Duplicated annotations are not removed:: + * At runtime, the metadata associated with an ``Annotated`` type can be + retrieved via the :attr:`!__metadata__` attribute: - Annotated[int, ValueRange(3, 10)] != Annotated[ - int, ValueRange(3, 10), ValueRange(3, 10) - ] + .. doctest:: - * ``Annotated`` can be used with nested and generic aliases:: + >>> from typing import Annotated + >>> X = Annotated[int, "very", "important", "metadata"] + >>> X + typing.Annotated[int, 'very', 'important', 'metadata'] + >>> X.__metadata__ + ('very', 'important', 'metadata') - T = TypeVar('T') - Vec = Annotated[list[tuple[T, T]], MaxLen(10)] - V = Vec[int] + .. seealso:: - V == Annotated[list[tuple[int, int]], MaxLen(10)] + :pep:`593` - Flexible function and variable annotations + The PEP introducing ``Annotated`` to the standard library. .. versionadded:: 3.9 .. data:: TypeGuard - Special typing form used to annotate the return type of a user-defined + Special typing construct for marking user-defined type guard functions. + + ``TypeGuard`` can be used to annotate the return type of a user-defined type guard function. ``TypeGuard`` only accepts a single type argument. At runtime, functions marked this way should return a boolean. @@ -1196,237 +1478,375 @@ These can be used as types in annotations using ``[]``, each having a unique syn .. versionadded:: 3.10 -Building generic types -"""""""""""""""""""""" +.. data:: Unpack -These are not used in annotations. They are building blocks for creating generic types. + Typing operator to conceptually mark an object as having been unpacked. -.. class:: Generic + For example, using the unpack operator ``*`` on a + :class:`type variable tuple <TypeVarTuple>` is equivalent to using ``Unpack`` + to mark the type variable tuple as having been unpacked:: - Abstract base class for generic types. + Ts = TypeVarTuple('Ts') + tup: tuple[*Ts] + # Effectively does: + tup: tuple[Unpack[Ts]] - A generic type is typically declared by inheriting from an - instantiation of this class with one or more type variables. - For example, a generic mapping type might be defined as:: + In fact, ``Unpack`` can be used interchangeably with ``*`` in the context + of :class:`typing.TypeVarTuple <TypeVarTuple>` and + :class:`builtins.tuple <tuple>` types. You might see ``Unpack`` being used + explicitly in older versions of Python, where ``*`` couldn't be used in + certain places:: - class Mapping(Generic[KT, VT]): - def __getitem__(self, key: KT) -> VT: - ... - # Etc. + # In older versions of Python, TypeVarTuple and Unpack + # are located in the `typing_extensions` backports package. + from typing_extensions import TypeVarTuple, Unpack - This class can then be used as follows:: + Ts = TypeVarTuple('Ts') + tup: tuple[*Ts] # Syntax error on Python <= 3.10! + tup: tuple[Unpack[Ts]] # Semantically equivalent, and backwards-compatible - X = TypeVar('X') - Y = TypeVar('Y') + ``Unpack`` can also be used along with :class:`typing.TypedDict` for typing + ``**kwargs`` in a function signature:: - def lookup_name(mapping: Mapping[X, Y], key: X, default: Y) -> Y: - try: - return mapping[key] - except KeyError: - return default + from typing import TypedDict, Unpack -.. class:: TypeVar + class Movie(TypedDict): + name: str + year: int - Type variable. + # This function expects two keyword arguments - `name` of type `str` + # and `year` of type `int`. + def foo(**kwargs: Unpack[Movie]): ... - Usage:: + See :pep:`692` for more details on using ``Unpack`` for ``**kwargs`` typing. - T = TypeVar('T') # Can be anything - S = TypeVar('S', bound=str) # Can be any subtype of str + .. versionadded:: 3.11 + +Building generic types and type aliases +""""""""""""""""""""""""""""""""""""""" + +The following classes should not be used directly as annotations. +Their intended purpose is to be building blocks +for creating generic types and type aliases. + +These objects can be created through special syntax +(:ref:`type parameter lists <type-params>` and the :keyword:`type` statement). +For compatibility with Python 3.11 and earlier, they can also be created +without the dedicated syntax, as documented below. + +.. class:: Generic + + Abstract base class for generic types. + + A generic type is typically declared by adding a list of type parameters + after the class name:: + + class Mapping[KT, VT]: + def __getitem__(self, key: KT) -> VT: + ... + # Etc. + + Such a class implicitly inherits from ``Generic``. + The runtime semantics of this syntax are discussed in the + :ref:`Language Reference <generic-classes>`. + + This class can then be used as follows:: + + def lookup_name[X, Y](mapping: Mapping[X, Y], key: X, default: Y) -> Y: + try: + return mapping[key] + except KeyError: + return default + + Here the brackets after the function name indicate a + :ref:`generic function <generic-functions>`. + + For backwards compatibility, generic classes can also be + declared by explicitly inheriting from + ``Generic``. In this case, the type parameters must be declared + separately:: + + KT = TypeVar('KT') + VT = TypeVar('VT') + + class Mapping(Generic[KT, VT]): + def __getitem__(self, key: KT) -> VT: + ... + # Etc. + +.. class:: TypeVar(name, *constraints, bound=None, covariant=False, contravariant=False, infer_variance=False) + + Type variable. + + The preferred way to construct a type variable is via the dedicated syntax + for :ref:`generic functions <generic-functions>`, + :ref:`generic classes <generic-classes>`, and + :ref:`generic type aliases <generic-type-aliases>`:: + + class Sequence[T]: # T is a TypeVar + ... + + This syntax can also be used to create bound and constrained type + variables:: + + class StrSequence[S: str]: # S is a TypeVar bound to str + ... + + + class StrOrBytesSequence[A: (str, bytes)]: # A is a TypeVar constrained to str or bytes + ... + + However, if desired, reusable type variables can also be constructed manually, like so:: + + T = TypeVar('T') # Can be anything + S = TypeVar('S', bound=str) # Can be any subtype of str A = TypeVar('A', str, bytes) # Must be exactly str or bytes - Type variables exist primarily for the benefit of static type - checkers. They serve as the parameters for generic types as well - as for generic function definitions. See :class:`Generic` for more - information on generic types. Generic functions work as follows:: + Type variables exist primarily for the benefit of static type + checkers. They serve as the parameters for generic types as well + as for generic function and type alias definitions. + See :class:`Generic` for more + information on generic types. Generic functions work as follows:: - def repeat(x: T, n: int) -> Sequence[T]: - """Return a list containing n references to x.""" - return [x]*n + def repeat[T](x: T, n: int) -> Sequence[T]: + """Return a list containing n references to x.""" + return [x]*n - def print_capitalized(x: S) -> S: - """Print x capitalized, and return x.""" - print(x.capitalize()) - return x + def print_capitalized[S: str](x: S) -> S: + """Print x capitalized, and return x.""" + print(x.capitalize()) + return x - def concatenate(x: A, y: A) -> A: - """Add two strings or bytes objects together.""" - return x + y + def concatenate[A: (str, bytes)](x: A, y: A) -> A: + """Add two strings or bytes objects together.""" + return x + y - Note that type variables can be *bound*, *constrained*, or neither, but - cannot be both bound *and* constrained. + Note that type variables can be *bound*, *constrained*, or neither, but + cannot be both bound *and* constrained. - Bound type variables and constrained type variables have different - semantics in several important ways. Using a *bound* type variable means - that the ``TypeVar`` will be solved using the most specific type possible:: + The variance of type variables is inferred by type checkers when they are created + through the :ref:`type parameter syntax <type-params>` or when + ``infer_variance=True`` is passed. + Manually created type variables may be explicitly marked covariant or contravariant by passing + ``covariant=True`` or ``contravariant=True``. + By default, manually created type variables are invariant. + See :pep:`484` and :pep:`695` for more details. - x = print_capitalized('a string') - reveal_type(x) # revealed type is str + Bound type variables and constrained type variables have different + semantics in several important ways. Using a *bound* type variable means + that the ``TypeVar`` will be solved using the most specific type possible:: - class StringSubclass(str): - pass + x = print_capitalized('a string') + reveal_type(x) # revealed type is str - y = print_capitalized(StringSubclass('another string')) - reveal_type(y) # revealed type is StringSubclass + class StringSubclass(str): + pass - z = print_capitalized(45) # error: int is not a subtype of str + y = print_capitalized(StringSubclass('another string')) + reveal_type(y) # revealed type is StringSubclass - Type variables can be bound to concrete types, abstract types (ABCs or - protocols), and even unions of types:: + z = print_capitalized(45) # error: int is not a subtype of str - U = TypeVar('U', bound=str|bytes) # Can be any subtype of the union str|bytes - V = TypeVar('V', bound=SupportsAbs) # Can be anything with an __abs__ method + Type variables can be bound to concrete types, abstract types (ABCs or + protocols), and even unions of types:: - Using a *constrained* type variable, however, means that the ``TypeVar`` - can only ever be solved as being exactly one of the constraints given:: + # Can be anything with an __abs__ method + def print_abs[T: SupportsAbs](arg: T) -> None: + print("Absolute value:", abs(arg)) - a = concatenate('one', 'two') - reveal_type(a) # revealed type is str + U = TypeVar('U', bound=str|bytes) # Can be any subtype of the union str|bytes + V = TypeVar('V', bound=SupportsAbs) # Can be anything with an __abs__ method - b = concatenate(StringSubclass('one'), StringSubclass('two')) - reveal_type(b) # revealed type is str, despite StringSubclass being passed in + .. _typing-constrained-typevar: - c = concatenate('one', b'two') # error: type variable 'A' can be either str or bytes in a function call, but not both + Using a *constrained* type variable, however, means that the ``TypeVar`` + can only ever be solved as being exactly one of the constraints given:: - At runtime, ``isinstance(x, T)`` will raise :exc:`TypeError`. In general, - :func:`isinstance` and :func:`issubclass` should not be used with types. + a = concatenate('one', 'two') + reveal_type(a) # revealed type is str - Type variables may be marked covariant or contravariant by passing - ``covariant=True`` or ``contravariant=True``. See :pep:`484` for more - details. By default, type variables are invariant. + b = concatenate(StringSubclass('one'), StringSubclass('two')) + reveal_type(b) # revealed type is str, despite StringSubclass being passed in -.. class:: TypeVarTuple + c = concatenate('one', b'two') # error: type variable 'A' can be either str or bytes in a function call, but not both - Type variable tuple. A specialized form of :class:`type variable <TypeVar>` - that enables *variadic* generics. + At runtime, ``isinstance(x, T)`` will raise :exc:`TypeError`. - A normal type variable enables parameterization with a single type. A type - variable tuple, in contrast, allows parameterization with an - *arbitrary* number of types by acting like an *arbitrary* number of type - variables wrapped in a tuple. For example:: + .. attribute:: __name__ - T = TypeVar('T') - Ts = TypeVarTuple('Ts') + The name of the type variable. - def move_first_element_to_last(tup: tuple[T, *Ts]) -> tuple[*Ts, T]: - return (*tup[1:], tup[0]) + .. attribute:: __covariant__ - # T is bound to int, Ts is bound to () - # Return value is (1,), which has type tuple[int] - move_first_element_to_last(tup=(1,)) + Whether the type var has been explicitly marked as covariant. - # T is bound to int, Ts is bound to (str,) - # Return value is ('spam', 1), which has type tuple[str, int] - move_first_element_to_last(tup=(1, 'spam')) + .. attribute:: __contravariant__ - # T is bound to int, Ts is bound to (str, float) - # Return value is ('spam', 3.0, 1), which has type tuple[str, float, int] - move_first_element_to_last(tup=(1, 'spam', 3.0)) + Whether the type var has been explicitly marked as contravariant. - # This fails to type check (and fails at runtime) - # because tuple[()] is not compatible with tuple[T, *Ts] - # (at least one element is required) - move_first_element_to_last(tup=()) + .. attribute:: __infer_variance__ - Note the use of the unpacking operator ``*`` in ``tuple[T, *Ts]``. - Conceptually, you can think of ``Ts`` as a tuple of type variables - ``(T1, T2, ...)``. ``tuple[T, *Ts]`` would then become - ``tuple[T, *(T1, T2, ...)]``, which is equivalent to - ``tuple[T, T1, T2, ...]``. (Note that in older versions of Python, you might - see this written using :data:`Unpack <Unpack>` instead, as - ``Unpack[Ts]``.) + Whether the type variable's variance should be inferred by type checkers. - Type variable tuples must *always* be unpacked. This helps distinguish type - variable tuples from normal type variables:: + .. versionadded:: 3.12 - x: Ts # Not valid - x: tuple[Ts] # Not valid - x: tuple[*Ts] # The correct way to to do it + .. attribute:: __bound__ - Type variable tuples can be used in the same contexts as normal type - variables. For example, in class definitions, arguments, and return types:: + The bound of the type variable, if any. - Shape = TypeVarTuple('Shape') - class Array(Generic[*Shape]): - def __getitem__(self, key: tuple[*Shape]) -> float: ... - def __abs__(self) -> "Array[*Shape]": ... - def get_shape(self) -> tuple[*Shape]: ... + .. versionchanged:: 3.12 - Type variable tuples can be happily combined with normal type variables:: + For type variables created through :ref:`type parameter syntax <type-params>`, + the bound is evaluated only when the attribute is accessed, not when + the type variable is created (see :ref:`lazy-evaluation`). - DType = TypeVar('DType') + .. attribute:: __constraints__ - class Array(Generic[DType, *Shape]): # This is fine - pass + A tuple containing the constraints of the type variable, if any. - class Array2(Generic[*Shape, DType]): # This would also be fine - pass + .. versionchanged:: 3.12 - float_array_1d: Array[float, Height] = Array() # Totally fine - int_array_2d: Array[int, Height, Width] = Array() # Yup, fine too + For type variables created through :ref:`type parameter syntax <type-params>`, + the constraints are evaluated only when the attribute is accessed, not when + the type variable is created (see :ref:`lazy-evaluation`). - However, note that at most one type variable tuple may appear in a single - list of type arguments or type parameters:: + .. versionchanged:: 3.12 - x: tuple[*Ts, *Ts] # Not valid - class Array(Generic[*Shape, *Shape]): # Not valid - pass + Type variables can now be declared using the + :ref:`type parameter <type-params>` syntax introduced by :pep:`695`. + The ``infer_variance`` parameter was added. - Finally, an unpacked type variable tuple can be used as the type annotation - of ``*args``:: +.. class:: TypeVarTuple(name) - def call_soon( - callback: Callable[[*Ts], None], - *args: *Ts - ) -> None: - ... - callback(*args) + Type variable tuple. A specialized form of :class:`type variable <TypeVar>` + that enables *variadic* generics. - In contrast to non-unpacked annotations of ``*args`` - e.g. ``*args: int``, - which would specify that *all* arguments are ``int`` - ``*args: *Ts`` - enables reference to the types of the *individual* arguments in ``*args``. - Here, this allows us to ensure the types of the ``*args`` passed - to ``call_soon`` match the types of the (positional) arguments of - ``callback``. + Type variable tuples can be declared in :ref:`type parameter lists <type-params>` + using a single asterisk (``*``) before the name:: - See :pep:`646` for more details on type variable tuples. + def move_first_element_to_last[T, *Ts](tup: tuple[T, *Ts]) -> tuple[*Ts, T]: + return (*tup[1:], tup[0]) - .. versionadded:: 3.11 + Or by explicitly invoking the ``TypeVarTuple`` constructor:: -.. data:: Unpack + T = TypeVar("T") + Ts = TypeVarTuple("Ts") - A typing operator that conceptually marks an object as having been - unpacked. For example, using the unpack operator ``*`` on a - :class:`type variable tuple <TypeVarTuple>` is equivalent to using ``Unpack`` - to mark the type variable tuple as having been unpacked:: + def move_first_element_to_last(tup: tuple[T, *Ts]) -> tuple[*Ts, T]: + return (*tup[1:], tup[0]) - Ts = TypeVarTuple('Ts') - tup: tuple[*Ts] - # Effectively does: - tup: tuple[Unpack[Ts]] + A normal type variable enables parameterization with a single type. A type + variable tuple, in contrast, allows parameterization with an + *arbitrary* number of types by acting like an *arbitrary* number of type + variables wrapped in a tuple. For example:: - In fact, ``Unpack`` can be used interchangeably with ``*`` in the context - of types. You might see ``Unpack`` being used explicitly in older versions - of Python, where ``*`` couldn't be used in certain places:: + # T is bound to int, Ts is bound to () + # Return value is (1,), which has type tuple[int] + move_first_element_to_last(tup=(1,)) - # In older versions of Python, TypeVarTuple and Unpack - # are located in the `typing_extensions` backports package. - from typing_extensions import TypeVarTuple, Unpack + # T is bound to int, Ts is bound to (str,) + # Return value is ('spam', 1), which has type tuple[str, int] + move_first_element_to_last(tup=(1, 'spam')) - Ts = TypeVarTuple('Ts') - tup: tuple[*Ts] # Syntax error on Python <= 3.10! - tup: tuple[Unpack[Ts]] # Semantically equivalent, and backwards-compatible + # T is bound to int, Ts is bound to (str, float) + # Return value is ('spam', 3.0, 1), which has type tuple[str, float, int] + move_first_element_to_last(tup=(1, 'spam', 3.0)) + + # This fails to type check (and fails at runtime) + # because tuple[()] is not compatible with tuple[T, *Ts] + # (at least one element is required) + move_first_element_to_last(tup=()) + + Note the use of the unpacking operator ``*`` in ``tuple[T, *Ts]``. + Conceptually, you can think of ``Ts`` as a tuple of type variables + ``(T1, T2, ...)``. ``tuple[T, *Ts]`` would then become + ``tuple[T, *(T1, T2, ...)]``, which is equivalent to + ``tuple[T, T1, T2, ...]``. (Note that in older versions of Python, you might + see this written using :data:`Unpack <Unpack>` instead, as + ``Unpack[Ts]``.) + + Type variable tuples must *always* be unpacked. This helps distinguish type + variable tuples from normal type variables:: + + x: Ts # Not valid + x: tuple[Ts] # Not valid + x: tuple[*Ts] # The correct way to do it + + Type variable tuples can be used in the same contexts as normal type + variables. For example, in class definitions, arguments, and return types:: + + class Array[*Shape]: + def __getitem__(self, key: tuple[*Shape]) -> float: ... + def __abs__(self) -> "Array[*Shape]": ... + def get_shape(self) -> tuple[*Shape]: ... + + Type variable tuples can be happily combined with normal type variables: + + .. testcode:: + + class Array[DType, *Shape]: # This is fine + pass + + class Array2[*Shape, DType]: # This would also be fine + pass + + class Height: ... + class Width: ... + + float_array_1d: Array[float, Height] = Array() # Totally fine + int_array_2d: Array[int, Height, Width] = Array() # Yup, fine too + + However, note that at most one type variable tuple may appear in a single + list of type arguments or type parameters:: + + x: tuple[*Ts, *Ts] # Not valid + class Array[*Shape, *Shape]: # Not valid + pass + + Finally, an unpacked type variable tuple can be used as the type annotation + of ``*args``:: + + def call_soon[*Ts]( + callback: Callable[[*Ts], None], + *args: *Ts + ) -> None: + ... + callback(*args) + + In contrast to non-unpacked annotations of ``*args`` - e.g. ``*args: int``, + which would specify that *all* arguments are ``int`` - ``*args: *Ts`` + enables reference to the types of the *individual* arguments in ``*args``. + Here, this allows us to ensure the types of the ``*args`` passed + to ``call_soon`` match the types of the (positional) arguments of + ``callback``. + + See :pep:`646` for more details on type variable tuples. + + .. attribute:: __name__ + + The name of the type variable tuple. .. versionadded:: 3.11 + .. versionchanged:: 3.12 + + Type variable tuples can now be declared using the + :ref:`type parameter <type-params>` syntax introduced by :pep:`695`. + .. class:: ParamSpec(name, *, bound=None, covariant=False, contravariant=False) Parameter specification variable. A specialized version of :class:`type variables <TypeVar>`. - Usage:: + In :ref:`type parameter lists <type-params>`, parameter specifications + can be declared with two asterisks (``**``):: + + type IntFunc[**P] = Callable[P, int] + + For compatibility with Python 3.11 and earlier, ``ParamSpec`` objects + can also be created as follows:: P = ParamSpec('P') @@ -1443,13 +1863,9 @@ These are not used in annotations. They are building blocks for creating generic new callable returned by it have inter-dependent type parameters:: from collections.abc import Callable - from typing import TypeVar, ParamSpec import logging - T = TypeVar('T') - P = ParamSpec('P') - - def add_logging(f: Callable[P, T]) -> Callable[P, T]: + def add_logging[T, **P](f: Callable[P, T]) -> Callable[P, T]: '''A type-safe decorator to add logging to a function.''' def inner(*args: P.args, **kwargs: P.kwargs) -> T: logging.info(f'{f.__name__} was called') @@ -1484,6 +1900,10 @@ These are not used in annotations. They are building blocks for creating generic ``P.args`` and ``P.kwargs`` are instances respectively of :class:`ParamSpecArgs` and :class:`ParamSpecKwargs`. + .. attribute:: __name__ + + The name of the parameter specification. + Parameter specification variables created with ``covariant=True`` or ``contravariant=True`` can be used to declare covariant or contravariant generic types. The ``bound`` argument is also accepted, similar to @@ -1492,14 +1912,20 @@ These are not used in annotations. They are building blocks for creating generic .. versionadded:: 3.10 + .. versionchanged:: 3.12 + + Parameter specifications can now be declared using the + :ref:`type parameter <type-params>` syntax introduced by :pep:`695`. + .. note:: Only parameter specification variables defined in global scope can be pickled. .. seealso:: * :pep:`612` -- Parameter Specification Variables (the PEP which introduced - ``ParamSpec`` and ``Concatenate``). - * :class:`Callable` and :class:`Concatenate`. + ``ParamSpec`` and ``Concatenate``) + * :data:`Concatenate` + * :ref:`annotating-callables` .. data:: ParamSpecArgs .. data:: ParamSpecKwargs @@ -1510,94 +1936,91 @@ These are not used in annotations. They are building blocks for creating generic for runtime introspection and have no special meaning to static type checkers. Calling :func:`get_origin` on either of these objects will return the - original ``ParamSpec``:: + original ``ParamSpec``: - P = ParamSpec("P") - get_origin(P.args) # returns P - get_origin(P.kwargs) # returns P + .. doctest:: - .. versionadded:: 3.10 - - -.. data:: AnyStr + >>> from typing import ParamSpec + >>> P = ParamSpec("P") + >>> get_origin(P.args) is P + True + >>> get_origin(P.kwargs) is P + True - ``AnyStr`` is a :class:`constrained type variable <TypeVar>` defined as - ``AnyStr = TypeVar('AnyStr', str, bytes)``. + .. versionadded:: 3.10 - It is meant to be used for functions that may accept any kind of string - without allowing different kinds of strings to mix. For example:: - def concat(a: AnyStr, b: AnyStr) -> AnyStr: - return a + b +.. class:: TypeAliasType(name, value, *, type_params=()) - concat(u"foo", u"bar") # Ok, output has type 'unicode' - concat(b"foo", b"bar") # Ok, output has type 'bytes' - concat(u"foo", b"bar") # Error, cannot mix unicode and bytes + The type of type aliases created through the :keyword:`type` statement. -.. class:: Protocol(Generic) + Example: - Base class for protocol classes. Protocol classes are defined like this:: + .. doctest:: - class Proto(Protocol): - def meth(self) -> int: - ... + >>> type Alias = int + >>> type(Alias) + <class 'typing.TypeAliasType'> - Such classes are primarily used with static type checkers that recognize - structural subtyping (static duck-typing), for example:: + .. versionadded:: 3.12 - class C: - def meth(self) -> int: - return 0 + .. attribute:: __name__ - def func(x: Proto) -> int: - return x.meth() + The name of the type alias: - func(C()) # Passes static type check + .. doctest:: - See :pep:`544` for more details. Protocol classes decorated with - :func:`runtime_checkable` (described later) act as simple-minded runtime - protocols that check only the presence of given attributes, ignoring their - type signatures. + >>> type Alias = int + >>> Alias.__name__ + 'Alias' - Protocol classes can be generic, for example:: + .. attribute:: __module__ - class GenProto(Protocol[T]): - def meth(self) -> T: - ... + The module in which the type alias was defined:: - .. versionadded:: 3.8 + >>> type Alias = int + >>> Alias.__module__ + '__main__' -.. decorator:: runtime_checkable + .. attribute:: __type_params__ - Mark a protocol class as a runtime protocol. + The type parameters of the type alias, or an empty tuple if the alias is + not generic: - Such a protocol can be used with :func:`isinstance` and :func:`issubclass`. - This raises :exc:`TypeError` when applied to a non-protocol class. This - allows a simple-minded structural check, very similar to "one trick ponies" - in :mod:`collections.abc` such as :class:`~collections.abc.Iterable`. For example:: + .. doctest:: - @runtime_checkable - class Closable(Protocol): - def close(self): ... + >>> type ListOrSet[T] = list[T] | set[T] + >>> ListOrSet.__type_params__ + (T,) + >>> type NotGeneric = int + >>> NotGeneric.__type_params__ + () - assert isinstance(open('/some/file'), Closable) + .. attribute:: __value__ - .. note:: + The type alias's value. This is :ref:`lazily evaluated <lazy-evaluation>`, + so names used in the definition of the alias are not resolved until the + ``__value__`` attribute is accessed: - :func:`runtime_checkable` will check only the presence of the required - methods, not their type signatures. For example, :class:`ssl.SSLObject` - is a class, therefore it passes an :func:`issubclass` - check against :data:`Callable`. However, the - :meth:`ssl.SSLObject.__init__` method exists only to raise a - :exc:`TypeError` with a more informative message, therefore making - it impossible to call (instantiate) :class:`ssl.SSLObject`. + .. doctest:: - .. versionadded:: 3.8 + >>> type Mutually = Recursive + >>> type Recursive = Mutually + >>> Mutually + Mutually + >>> Recursive + Recursive + >>> Mutually.__value__ + Recursive + >>> Recursive.__value__ + Mutually Other special directives """""""""""""""""""""""" -These are not used in annotations. They are building blocks for declaring types. +These functions and classes should not be used directly as annotations. +Their intended purpose is to be building blocks for creating and declaring +types. .. class:: NamedTuple @@ -1642,12 +2065,18 @@ These are not used in annotations. They are building blocks for declaring types. ``NamedTuple`` subclasses can be generic:: - class Group(NamedTuple, Generic[T]): + class Group[T](NamedTuple): key: T group: list[T] Backward-compatible usage:: + # For creating a generic NamedTuple on Python 3.11 or lower + class Group(NamedTuple, Generic[T]): + key: T + group: list[T] + + # A functional syntax is also supported Employee = NamedTuple('Employee', [('name', str), ('id', int)]) .. versionchanged:: 3.6 @@ -1669,19 +2098,138 @@ These are not used in annotations. They are building blocks for declaring types. .. class:: NewType(name, tp) - A helper class to indicate a distinct type to a typechecker, - see :ref:`distinct`. At runtime it returns an object that returns - its argument when called. + Helper class to create low-overhead :ref:`distinct types <distinct>`. + + A ``NewType`` is considered a distinct type by a typechecker. At runtime, + however, calling a ``NewType`` returns its argument unchanged. + Usage:: - UserId = NewType('UserId', int) - first_user = UserId(1) + UserId = NewType('UserId', int) # Declare the NewType "UserId" + first_user = UserId(1) # "UserId" returns the argument unchanged at runtime + + .. attribute:: __module__ + + The module in which the new type is defined. + + .. attribute:: __name__ + + The name of the new type. + + .. attribute:: __supertype__ + + The type that the new type is based on. .. versionadded:: 3.5.2 .. versionchanged:: 3.10 ``NewType`` is now a class rather than a function. +.. class:: Protocol(Generic) + + Base class for protocol classes. + + Protocol classes are defined like this:: + + class Proto(Protocol): + def meth(self) -> int: + ... + + Such classes are primarily used with static type checkers that recognize + structural subtyping (static duck-typing), for example:: + + class C: + def meth(self) -> int: + return 0 + + def func(x: Proto) -> int: + return x.meth() + + func(C()) # Passes static type check + + See :pep:`544` for more details. Protocol classes decorated with + :func:`runtime_checkable` (described later) act as simple-minded runtime + protocols that check only the presence of given attributes, ignoring their + type signatures. + + Protocol classes can be generic, for example:: + + class GenProto[T](Protocol): + def meth(self) -> T: + ... + + In code that needs to be compatible with Python 3.11 or older, generic + Protocols can be written as follows:: + + T = TypeVar("T") + + class GenProto(Protocol[T]): + def meth(self) -> T: + ... + + .. versionadded:: 3.8 + +.. decorator:: runtime_checkable + + Mark a protocol class as a runtime protocol. + + Such a protocol can be used with :func:`isinstance` and :func:`issubclass`. + This raises :exc:`TypeError` when applied to a non-protocol class. This + allows a simple-minded structural check, very similar to "one trick ponies" + in :mod:`collections.abc` such as :class:`~collections.abc.Iterable`. For example:: + + @runtime_checkable + class Closable(Protocol): + def close(self): ... + + assert isinstance(open('/some/file'), Closable) + + @runtime_checkable + class Named(Protocol): + name: str + + import threading + assert isinstance(threading.Thread(name='Bob'), Named) + + .. note:: + + :func:`!runtime_checkable` will check only the presence of the required + methods or attributes, not their type signatures or types. + For example, :class:`ssl.SSLObject` + is a class, therefore it passes an :func:`issubclass` + check against :ref:`Callable <annotating-callables>`. However, the + ``ssl.SSLObject.__init__`` method exists only to raise a + :exc:`TypeError` with a more informative message, therefore making + it impossible to call (instantiate) :class:`ssl.SSLObject`. + + .. note:: + + An :func:`isinstance` check against a runtime-checkable protocol can be + surprisingly slow compared to an ``isinstance()`` check against + a non-protocol class. Consider using alternative idioms such as + :func:`hasattr` calls for structural checks in performance-sensitive + code. + + .. versionadded:: 3.8 + + .. versionchanged:: 3.12 + The internal implementation of :func:`isinstance` checks against + runtime-checkable protocols now uses :func:`inspect.getattr_static` + to look up attributes (previously, :func:`hasattr` was used). + As a result, some objects which used to be considered instances + of a runtime-checkable protocol may no longer be considered instances + of that protocol on Python 3.12+, and vice versa. + Most users are unlikely to be affected by this change. + + .. versionchanged:: 3.12 + The members of a runtime-checkable protocol are now considered "frozen" + at runtime as soon as the class has been created. Monkey-patching + attributes onto a runtime-checkable protocol will still work, but will + have no impact on :func:`isinstance` checks comparing objects to the + protocol. See :ref:`"What's new in Python 3.12" <whatsnew-typing-py312>` + for more details. + + .. class:: TypedDict(dict) Special construct to add type hints to a dictionary. @@ -1805,11 +2353,19 @@ These are not used in annotations. They are building blocks for declaring types. class XZ(X, Z): pass # raises TypeError - T = TypeVar('T') - class XT(X, Generic[T]): pass # raises TypeError - A ``TypedDict`` can be generic:: + class Group[T](TypedDict): + key: T + group: list[T] + + To create a generic ``TypedDict`` that is compatible with Python 3.11 + or lower, inherit from :class:`Generic` explicitly: + + .. testcode:: + + T = TypeVar("T") + class Group(TypedDict, Generic[T]): key: T group: list[T] @@ -1821,7 +2377,9 @@ These are not used in annotations. They are building blocks for declaring types. .. attribute:: __total__ ``Point2D.__total__`` gives the value of the ``total`` argument. - Example:: + Example: + + .. doctest:: >>> from typing import TypedDict >>> class Point2D(TypedDict): pass @@ -1851,7 +2409,9 @@ These are not used in annotations. They are building blocks for declaring types. non-required keys in the same ``TypedDict`` . This is done by declaring a ``TypedDict`` with one value for the ``total`` argument and then inheriting from it in another ``TypedDict`` with a different value for - ``total``:: + ``total``: + + .. doctest:: >>> class Point2D(TypedDict, total=False): ... x: int @@ -1878,980 +2438,1201 @@ These are not used in annotations. They are building blocks for declaring types. .. versionchanged:: 3.11 Added support for generic ``TypedDict``\ s. -Generic concrete collections ----------------------------- +Protocols +--------- -Corresponding to built-in types -""""""""""""""""""""""""""""""" +The following protocols are provided by the typing module. All are decorated +with :func:`@runtime_checkable <runtime_checkable>`. -.. class:: Dict(dict, MutableMapping[KT, VT]) +.. class:: SupportsAbs - A generic version of :class:`dict`. - Useful for annotating return types. To annotate arguments it is preferred - to use an abstract collection type such as :class:`Mapping`. + An ABC with one abstract method ``__abs__`` that is covariant + in its return type. - This type can be used as follows:: +.. class:: SupportsBytes - def count_words(text: str) -> Dict[str, int]: - ... + An ABC with one abstract method ``__bytes__``. - .. deprecated:: 3.9 - :class:`builtins.dict <dict>` now supports subscripting (``[]``). - See :pep:`585` and :ref:`types-genericalias`. +.. class:: SupportsComplex -.. class:: List(list, MutableSequence[T]) + An ABC with one abstract method ``__complex__``. - Generic version of :class:`list`. - Useful for annotating return types. To annotate arguments it is preferred - to use an abstract collection type such as :class:`Sequence` or - :class:`Iterable`. +.. class:: SupportsFloat - This type may be used as follows:: + An ABC with one abstract method ``__float__``. - T = TypeVar('T', int, float) +.. class:: SupportsIndex - def vec2(x: T, y: T) -> List[T]: - return [x, y] + An ABC with one abstract method ``__index__``. - def keep_positives(vector: Sequence[T]) -> List[T]: - return [item for item in vector if item > 0] + .. versionadded:: 3.8 - .. deprecated:: 3.9 - :class:`builtins.list <list>` now supports subscripting (``[]``). - See :pep:`585` and :ref:`types-genericalias`. +.. class:: SupportsInt -.. class:: Set(set, MutableSet[T]) + An ABC with one abstract method ``__int__``. - A generic version of :class:`builtins.set <set>`. - Useful for annotating return types. To annotate arguments it is preferred - to use an abstract collection type such as :class:`AbstractSet`. +.. class:: SupportsRound - .. deprecated:: 3.9 - :class:`builtins.set <set>` now supports subscripting (``[]``). - See :pep:`585` and :ref:`types-genericalias`. + An ABC with one abstract method ``__round__`` + that is covariant in its return type. -.. class:: FrozenSet(frozenset, AbstractSet[T_co]) +ABCs for working with IO +------------------------ - A generic version of :class:`builtins.frozenset <frozenset>`. +.. class:: IO + TextIO + BinaryIO - .. deprecated:: 3.9 - :class:`builtins.frozenset <frozenset>` - now supports subscripting (``[]``). - See :pep:`585` and :ref:`types-genericalias`. + Generic type ``IO[AnyStr]`` and its subclasses ``TextIO(IO[str])`` + and ``BinaryIO(IO[bytes])`` + represent the types of I/O streams such as returned by + :func:`open`. -.. note:: :data:`Tuple` is a special form. +Functions and decorators +------------------------ -Corresponding to types in :mod:`collections` -"""""""""""""""""""""""""""""""""""""""""""" +.. function:: cast(typ, val) -.. class:: DefaultDict(collections.defaultdict, MutableMapping[KT, VT]) + Cast a value to a type. - A generic version of :class:`collections.defaultdict`. + This returns the value unchanged. To the type checker this + signals that the return value has the designated type, but at + runtime we intentionally don't check anything (we want this + to be as fast as possible). - .. versionadded:: 3.5.2 +.. function:: assert_type(val, typ, /) - .. deprecated:: 3.9 - :class:`collections.defaultdict` now supports subscripting (``[]``). - See :pep:`585` and :ref:`types-genericalias`. + Ask a static type checker to confirm that *val* has an inferred type of *typ*. -.. class:: OrderedDict(collections.OrderedDict, MutableMapping[KT, VT]) + At runtime this does nothing: it returns the first argument unchanged with no + checks or side effects, no matter the actual type of the argument. - A generic version of :class:`collections.OrderedDict`. + When a static type checker encounters a call to ``assert_type()``, it + emits an error if the value is not of the specified type:: - .. versionadded:: 3.7.2 + def greet(name: str) -> None: + assert_type(name, str) # OK, inferred type of `name` is `str` + assert_type(name, int) # type checker error - .. deprecated:: 3.9 - :class:`collections.OrderedDict` now supports subscripting (``[]``). - See :pep:`585` and :ref:`types-genericalias`. + This function is useful for ensuring the type checker's understanding of a + script is in line with the developer's intentions:: -.. class:: ChainMap(collections.ChainMap, MutableMapping[KT, VT]) + def complex_function(arg: object): + # Do some complex type-narrowing logic, + # after which we hope the inferred type will be `int` + ... + # Test whether the type checker correctly understands our function + assert_type(arg, int) - A generic version of :class:`collections.ChainMap`. + .. versionadded:: 3.11 - .. versionadded:: 3.5.4 - .. versionadded:: 3.6.1 +.. function:: assert_never(arg, /) - .. deprecated:: 3.9 - :class:`collections.ChainMap` now supports subscripting (``[]``). - See :pep:`585` and :ref:`types-genericalias`. + Ask a static type checker to confirm that a line of code is unreachable. -.. class:: Counter(collections.Counter, Dict[T, int]) + Example:: - A generic version of :class:`collections.Counter`. + def int_or_str(arg: int | str) -> None: + match arg: + case int(): + print("It's an int") + case str(): + print("It's a str") + case _ as unreachable: + assert_never(unreachable) - .. versionadded:: 3.5.4 - .. versionadded:: 3.6.1 + Here, the annotations allow the type checker to infer that the + last case can never execute, because ``arg`` is either + an :class:`int` or a :class:`str`, and both options are covered by + earlier cases. - .. deprecated:: 3.9 - :class:`collections.Counter` now supports subscripting (``[]``). - See :pep:`585` and :ref:`types-genericalias`. + If a type checker finds that a call to ``assert_never()`` is + reachable, it will emit an error. For example, if the type annotation + for ``arg`` was instead ``int | str | float``, the type checker would + emit an error pointing out that ``unreachable`` is of type :class:`float`. + For a call to ``assert_never`` to pass type checking, the inferred type of + the argument passed in must be the bottom type, :data:`Never`, and nothing + else. -.. class:: Deque(deque, MutableSequence[T]) + At runtime, this throws an exception when called. - A generic version of :class:`collections.deque`. + .. seealso:: + `Unreachable Code and Exhaustiveness Checking + <https://typing.readthedocs.io/en/latest/source/unreachable.html>`__ has more + information about exhaustiveness checking with static typing. - .. versionadded:: 3.5.4 - .. versionadded:: 3.6.1 + .. versionadded:: 3.11 - .. deprecated:: 3.9 - :class:`collections.deque` now supports subscripting (``[]``). - See :pep:`585` and :ref:`types-genericalias`. +.. function:: reveal_type(obj, /) -Other concrete types -"""""""""""""""""""" + Reveal the inferred static type of an expression. -.. class:: IO - TextIO - BinaryIO + When a static type checker encounters a call to this function, + it emits a diagnostic with the type of the argument. For example:: - Generic type ``IO[AnyStr]`` and its subclasses ``TextIO(IO[str])`` - and ``BinaryIO(IO[bytes])`` - represent the types of I/O streams such as returned by - :func:`open`. + x: int = 1 + reveal_type(x) # Revealed type is "builtins.int" - .. deprecated-removed:: 3.8 3.13 - The ``typing.io`` namespace is deprecated and will be removed. - These types should be directly imported from ``typing`` instead. + This can be useful when you want to debug how your type checker + handles a particular piece of code. -.. class:: Pattern - Match + The function returns its argument unchanged, which allows using + it within an expression:: - These type aliases - correspond to the return types from :func:`re.compile` and - :func:`re.match`. These types (and the corresponding functions) - are generic in ``AnyStr`` and can be made specific by writing - ``Pattern[str]``, ``Pattern[bytes]``, ``Match[str]``, or - ``Match[bytes]``. + x = reveal_type(1) # Revealed type is "builtins.int" - .. deprecated-removed:: 3.8 3.13 - The ``typing.re`` namespace is deprecated and will be removed. - These types should be directly imported from ``typing`` instead. + Most type checkers support ``reveal_type()`` anywhere, even if the + name is not imported from ``typing``. Importing the name from + ``typing`` allows your code to run without runtime errors and + communicates intent more clearly. - .. deprecated:: 3.9 - Classes ``Pattern`` and ``Match`` from :mod:`re` now support ``[]``. - See :pep:`585` and :ref:`types-genericalias`. + At runtime, this function prints the runtime type of its argument to stderr + and returns it unchanged:: -.. class:: Text + x = reveal_type(1) # prints "Runtime type is int" + print(x) # prints "1" - ``Text`` is an alias for ``str``. It is provided to supply a forward - compatible path for Python 2 code: in Python 2, ``Text`` is an alias for - ``unicode``. + .. versionadded:: 3.11 - Use ``Text`` to indicate that a value must contain a unicode string in - a manner that is compatible with both Python 2 and Python 3:: +.. decorator:: dataclass_transform(*, eq_default=True, order_default=False, \ + kw_only_default=False, frozen_default=False, \ + field_specifiers=(), **kwargs) - def add_unicode_checkmark(text: Text) -> Text: - return text + u' \u2713' + Decorator to mark an object as providing + :func:`dataclass <dataclasses.dataclass>`-like behavior. - .. versionadded:: 3.5.2 + ``dataclass_transform`` may be used to + decorate a class, metaclass, or a function that is itself a decorator. + The presence of ``@dataclass_transform()`` tells a static type checker that the + decorated object performs runtime "magic" that + transforms a class in a similar way to + :func:`@dataclasses.dataclass <dataclasses.dataclass>`. - .. deprecated:: 3.11 - Python 2 is no longer supported, and most type checkers also no longer - support type checking Python 2 code. Removal of the alias is not - currently planned, but users are encouraged to use - :class:`str` instead of ``Text`` wherever possible. + Example usage with a decorator function: -Abstract Base Classes ---------------------- + .. testcode:: -Corresponding to collections in :mod:`collections.abc` -"""""""""""""""""""""""""""""""""""""""""""""""""""""" + @dataclass_transform() + def create_model[T](cls: type[T]) -> type[T]: + ... + return cls -.. class:: AbstractSet(Collection[T_co]) + @create_model + class CustomerModel: + id: int + name: str - A generic version of :class:`collections.abc.Set`. + On a base class:: - .. deprecated:: 3.9 - :class:`collections.abc.Set` now supports subscripting (``[]``). - See :pep:`585` and :ref:`types-genericalias`. + @dataclass_transform() + class ModelBase: ... -.. class:: ByteString(Sequence[int]) + class CustomerModel(ModelBase): + id: int + name: str - A generic version of :class:`collections.abc.ByteString`. + On a metaclass:: - This type represents the types :class:`bytes`, :class:`bytearray`, - and :class:`memoryview` of byte sequences. + @dataclass_transform() + class ModelMeta(type): ... - As a shorthand for this type, :class:`bytes` can be used to - annotate arguments of any of the types mentioned above. + class ModelBase(metaclass=ModelMeta): ... - .. deprecated:: 3.9 - :class:`collections.abc.ByteString` now supports subscripting (``[]``). - See :pep:`585` and :ref:`types-genericalias`. + class CustomerModel(ModelBase): + id: int + name: str -.. class:: Collection(Sized, Iterable[T_co], Container[T_co]) + The ``CustomerModel`` classes defined above will + be treated by type checkers similarly to classes created with + :func:`@dataclasses.dataclass <dataclasses.dataclass>`. + For example, type checkers will assume these classes have + ``__init__`` methods that accept ``id`` and ``name``. - A generic version of :class:`collections.abc.Collection` + The decorated class, metaclass, or function may accept the following bool + arguments which type checkers will assume have the same effect as they + would have on the + :func:`@dataclasses.dataclass<dataclasses.dataclass>` decorator: ``init``, + ``eq``, ``order``, ``unsafe_hash``, ``frozen``, ``match_args``, + ``kw_only``, and ``slots``. It must be possible for the value of these + arguments (``True`` or ``False``) to be statically evaluated. - .. versionadded:: 3.6.0 + The arguments to the ``dataclass_transform`` decorator can be used to + customize the default behaviors of the decorated class, metaclass, or + function: - .. deprecated:: 3.9 - :class:`collections.abc.Collection` now supports subscripting (``[]``). - See :pep:`585` and :ref:`types-genericalias`. + :param bool eq_default: + Indicates whether the ``eq`` parameter is assumed to be + ``True`` or ``False`` if it is omitted by the caller. + Defaults to ``True``. -.. class:: Container(Generic[T_co]) + :param bool order_default: + Indicates whether the ``order`` parameter is + assumed to be ``True`` or ``False`` if it is omitted by the caller. + Defaults to ``False``. - A generic version of :class:`collections.abc.Container`. + :param bool kw_only_default: + Indicates whether the ``kw_only`` parameter is + assumed to be ``True`` or ``False`` if it is omitted by the caller. + Defaults to ``False``. - .. deprecated:: 3.9 - :class:`collections.abc.Container` now supports subscripting (``[]``). - See :pep:`585` and :ref:`types-genericalias`. + :param bool frozen_default: + Indicates whether the ``frozen`` parameter is + assumed to be ``True`` or ``False`` if it is omitted by the caller. + Defaults to ``False``. -.. class:: ItemsView(MappingView, AbstractSet[tuple[KT_co, VT_co]]) + .. versionadded:: 3.12 - A generic version of :class:`collections.abc.ItemsView`. + :param field_specifiers: + Specifies a static list of supported classes + or functions that describe fields, similar to :func:`dataclasses.field`. + Defaults to ``()``. + :type field_specifiers: tuple[Callable[..., Any], ...] - .. deprecated:: 3.9 - :class:`collections.abc.ItemsView` now supports subscripting (``[]``). - See :pep:`585` and :ref:`types-genericalias`. + :param Any \**kwargs: + Arbitrary other keyword arguments are accepted in order to allow for + possible future extensions. -.. class:: KeysView(MappingView, AbstractSet[KT_co]) + Type checkers recognize the following optional parameters on field + specifiers: - A generic version of :class:`collections.abc.KeysView`. + .. list-table:: **Recognised parameters for field specifiers** + :header-rows: 1 + :widths: 20 80 + + * - Parameter name + - Description + * - ``init`` + - Indicates whether the field should be included in the + synthesized ``__init__`` method. If unspecified, ``init`` defaults to + ``True``. + * - ``default`` + - Provides the default value for the field. + * - ``default_factory`` + - Provides a runtime callback that returns the + default value for the field. If neither ``default`` nor + ``default_factory`` are specified, the field is assumed to have no + default value and must be provided a value when the class is + instantiated. + * - ``factory`` + - An alias for the ``default_factory`` parameter on field specifiers. + * - ``kw_only`` + - Indicates whether the field should be marked as + keyword-only. If ``True``, the field will be keyword-only. If + ``False``, it will not be keyword-only. If unspecified, the value of + the ``kw_only`` parameter on the object decorated with + ``dataclass_transform`` will be used, or if that is unspecified, the + value of ``kw_only_default`` on ``dataclass_transform`` will be used. + * - ``alias`` + - Provides an alternative name for the field. This alternative + name is used in the synthesized ``__init__`` method. - .. deprecated:: 3.9 - :class:`collections.abc.KeysView` now supports subscripting (``[]``). - See :pep:`585` and :ref:`types-genericalias`. + At runtime, this decorator records its arguments in the + ``__dataclass_transform__`` attribute on the decorated object. + It has no other runtime effect. -.. class:: Mapping(Collection[KT], Generic[KT, VT_co]) + See :pep:`681` for more details. - A generic version of :class:`collections.abc.Mapping`. - This type can be used as follows:: + .. versionadded:: 3.11 - def get_position_in_index(word_list: Mapping[str, int], word: str) -> int: - return word_list[word] +.. decorator:: overload - .. deprecated:: 3.9 - :class:`collections.abc.Mapping` now supports subscripting (``[]``). - See :pep:`585` and :ref:`types-genericalias`. + Decorator for creating overloaded functions and methods. -.. class:: MappingView(Sized) + The ``@overload`` decorator allows describing functions and methods + that support multiple different combinations of argument types. A series + of ``@overload``-decorated definitions must be followed by exactly one + non-``@overload``-decorated definition (for the same function/method). - A generic version of :class:`collections.abc.MappingView`. + ``@overload``-decorated definitions are for the benefit of the + type checker only, since they will be overwritten by the + non-``@overload``-decorated definition. The non-``@overload``-decorated + definition, meanwhile, will be used at + runtime but should be ignored by a type checker. At runtime, calling + an ``@overload``-decorated function directly will raise + :exc:`NotImplementedError`. - .. deprecated:: 3.9 - :class:`collections.abc.MappingView` now supports subscripting (``[]``). - See :pep:`585` and :ref:`types-genericalias`. + An example of overload that gives a more + precise type than can be expressed using a union or a type variable: -.. class:: MutableMapping(Mapping[KT, VT]) + .. testcode:: - A generic version of :class:`collections.abc.MutableMapping`. + @overload + def process(response: None) -> None: + ... + @overload + def process(response: int) -> tuple[int, str]: + ... + @overload + def process(response: bytes) -> str: + ... + def process(response): + ... # actual implementation goes here - .. deprecated:: 3.9 - :class:`collections.abc.MutableMapping` - now supports subscripting (``[]``). - See :pep:`585` and :ref:`types-genericalias`. + See :pep:`484` for more details and comparison with other typing semantics. -.. class:: MutableSequence(Sequence[T]) + .. versionchanged:: 3.11 + Overloaded functions can now be introspected at runtime using + :func:`get_overloads`. - A generic version of :class:`collections.abc.MutableSequence`. - .. deprecated:: 3.9 - :class:`collections.abc.MutableSequence` - now supports subscripting (``[]``). - See :pep:`585` and :ref:`types-genericalias`. +.. function:: get_overloads(func) -.. class:: MutableSet(AbstractSet[T]) + Return a sequence of :func:`@overload <overload>`-decorated definitions for + *func*. - A generic version of :class:`collections.abc.MutableSet`. + *func* is the function object for the implementation of the + overloaded function. For example, given the definition of ``process`` in + the documentation for :func:`@overload <overload>`, + ``get_overloads(process)`` will return a sequence of three function objects + for the three defined overloads. If called on a function with no overloads, + ``get_overloads()`` returns an empty sequence. - .. deprecated:: 3.9 - :class:`collections.abc.MutableSet` now supports subscripting (``[]``). - See :pep:`585` and :ref:`types-genericalias`. + ``get_overloads()`` can be used for introspecting an overloaded function at + runtime. -.. class:: Sequence(Reversible[T_co], Collection[T_co]) + .. versionadded:: 3.11 - A generic version of :class:`collections.abc.Sequence`. - .. deprecated:: 3.9 - :class:`collections.abc.Sequence` now supports subscripting (``[]``). - See :pep:`585` and :ref:`types-genericalias`. +.. function:: clear_overloads() -.. class:: ValuesView(MappingView, Collection[_VT_co]) + Clear all registered overloads in the internal registry. - A generic version of :class:`collections.abc.ValuesView`. + This can be used to reclaim the memory used by the registry. - .. deprecated:: 3.9 - :class:`collections.abc.ValuesView` now supports subscripting (``[]``). - See :pep:`585` and :ref:`types-genericalias`. + .. versionadded:: 3.11 -Corresponding to other types in :mod:`collections.abc` -"""""""""""""""""""""""""""""""""""""""""""""""""""""" -.. class:: Iterable(Generic[T_co]) +.. decorator:: final - A generic version of :class:`collections.abc.Iterable`. + Decorator to indicate final methods and final classes. - .. deprecated:: 3.9 - :class:`collections.abc.Iterable` now supports subscripting (``[]``). - See :pep:`585` and :ref:`types-genericalias`. + Decorating a method with ``@final`` indicates to a type checker that the + method cannot be overridden in a subclass. Decorating a class with ``@final`` + indicates that it cannot be subclassed. -.. class:: Iterator(Iterable[T_co]) + For example:: - A generic version of :class:`collections.abc.Iterator`. + class Base: + @final + def done(self) -> None: + ... + class Sub(Base): + def done(self) -> None: # Error reported by type checker + ... - .. deprecated:: 3.9 - :class:`collections.abc.Iterator` now supports subscripting (``[]``). - See :pep:`585` and :ref:`types-genericalias`. + @final + class Leaf: + ... + class Other(Leaf): # Error reported by type checker + ... -.. class:: Generator(Iterator[T_co], Generic[T_co, T_contra, V_co]) + There is no runtime checking of these properties. See :pep:`591` for + more details. - A generator can be annotated by the generic type - ``Generator[YieldType, SendType, ReturnType]``. For example:: + .. versionadded:: 3.8 - def echo_round() -> Generator[int, float, str]: - sent = yield 0 - while sent >= 0: - sent = yield round(sent) - return 'Done' + .. versionchanged:: 3.11 + The decorator will now attempt to set a ``__final__`` attribute to ``True`` + on the decorated object. Thus, a check like + ``if getattr(obj, "__final__", False)`` can be used at runtime + to determine whether an object ``obj`` has been marked as final. + If the decorated object does not support setting attributes, + the decorator returns the object unchanged without raising an exception. - Note that unlike many other generics in the typing module, the ``SendType`` - of :class:`Generator` behaves contravariantly, not covariantly or - invariantly. - If your generator will only yield values, set the ``SendType`` and - ``ReturnType`` to ``None``:: +.. decorator:: no_type_check - def infinite_stream(start: int) -> Generator[int, None, None]: - while True: - yield start - start += 1 + Decorator to indicate that annotations are not type hints. - Alternatively, annotate your generator as having a return type of - either ``Iterable[YieldType]`` or ``Iterator[YieldType]``:: + This works as a class or function :term:`decorator`. With a class, it + applies recursively to all methods and classes defined in that class + (but not to methods defined in its superclasses or subclasses). Type + checkers will ignore all annotations in a function or class with this + decorator. - def infinite_stream(start: int) -> Iterator[int]: - while True: - yield start - start += 1 + ``@no_type_check`` mutates the decorated object in place. - .. deprecated:: 3.9 - :class:`collections.abc.Generator` now supports subscripting (``[]``). - See :pep:`585` and :ref:`types-genericalias`. +.. decorator:: no_type_check_decorator -.. class:: Hashable + Decorator to give another decorator the :func:`no_type_check` effect. - An alias to :class:`collections.abc.Hashable`. + This wraps the decorator with something that wraps the decorated + function in :func:`no_type_check`. -.. class:: Reversible(Iterable[T_co]) - A generic version of :class:`collections.abc.Reversible`. +.. decorator:: override - .. deprecated:: 3.9 - :class:`collections.abc.Reversible` now supports subscripting (``[]``). - See :pep:`585` and :ref:`types-genericalias`. + Decorator to indicate that a method in a subclass is intended to override a + method or attribute in a superclass. -.. class:: Sized + Type checkers should emit an error if a method decorated with ``@override`` + does not, in fact, override anything. + This helps prevent bugs that may occur when a base class is changed without + an equivalent change to a child class. - An alias to :class:`collections.abc.Sized`. + For example: -Asynchronous programming -"""""""""""""""""""""""" + .. testcode:: -.. class:: Coroutine(Awaitable[V_co], Generic[T_co, T_contra, V_co]) + class Base: + def log_status(self) -> None: + ... - A generic version of :class:`collections.abc.Coroutine`. - The variance and order of type variables - correspond to those of :class:`Generator`, for example:: + class Sub(Base): + @override + def log_status(self) -> None: # Okay: overrides Base.log_status + ... - from collections.abc import Coroutine - c: Coroutine[list[str], str, int] # Some coroutine defined elsewhere - x = c.send('hi') # Inferred type of 'x' is list[str] - async def bar() -> None: - y = await c # Inferred type of 'y' is int + @override + def done(self) -> None: # Error reported by type checker + ... - .. versionadded:: 3.5.3 + There is no runtime checking of this property. - .. deprecated:: 3.9 - :class:`collections.abc.Coroutine` now supports subscripting (``[]``). - See :pep:`585` and :ref:`types-genericalias`. + The decorator will attempt to set an ``__override__`` attribute to ``True`` on + the decorated object. Thus, a check like + ``if getattr(obj, "__override__", False)`` can be used at runtime to determine + whether an object ``obj`` has been marked as an override. If the decorated object + does not support setting attributes, the decorator returns the object unchanged + without raising an exception. -.. class:: AsyncGenerator(AsyncIterator[T_co], Generic[T_co, T_contra]) + See :pep:`698` for more details. - An async generator can be annotated by the generic type - ``AsyncGenerator[YieldType, SendType]``. For example:: + .. versionadded:: 3.12 - async def echo_round() -> AsyncGenerator[int, float]: - sent = yield 0 - while sent >= 0.0: - rounded = await round(sent) - sent = yield rounded - Unlike normal generators, async generators cannot return a value, so there - is no ``ReturnType`` type parameter. As with :class:`Generator`, the - ``SendType`` behaves contravariantly. +.. decorator:: type_check_only - If your generator will only yield values, set the ``SendType`` to - ``None``:: + Decorator to mark a class or function as unavailable at runtime. - async def infinite_stream(start: int) -> AsyncGenerator[int, None]: - while True: - yield start - start = await increment(start) + This decorator is itself not available at runtime. It is mainly + intended to mark classes that are defined in type stub files if + an implementation returns an instance of a private class:: - Alternatively, annotate your generator as having a return type of - either ``AsyncIterable[YieldType]`` or ``AsyncIterator[YieldType]``:: + @type_check_only + class Response: # private or not available at runtime + code: int + def get_header(self, name: str) -> str: ... - async def infinite_stream(start: int) -> AsyncIterator[int]: - while True: - yield start - start = await increment(start) + def fetch_response() -> Response: ... - .. versionadded:: 3.6.1 + Note that returning instances of private classes is not recommended. + It is usually preferable to make such classes public. - .. deprecated:: 3.9 - :class:`collections.abc.AsyncGenerator` - now supports subscripting (``[]``). - See :pep:`585` and :ref:`types-genericalias`. +Introspection helpers +--------------------- -.. class:: AsyncIterable(Generic[T_co]) +.. function:: get_type_hints(obj, globalns=None, localns=None, include_extras=False) - A generic version of :class:`collections.abc.AsyncIterable`. + Return a dictionary containing type hints for a function, method, module + or class object. - .. versionadded:: 3.5.2 + This is often the same as ``obj.__annotations__``. In addition, + forward references encoded as string literals are handled by evaluating + them in ``globals`` and ``locals`` namespaces. For a class ``C``, return + a dictionary constructed by merging all the ``__annotations__`` along + ``C.__mro__`` in reverse order. - .. deprecated:: 3.9 - :class:`collections.abc.AsyncIterable` now supports subscripting (``[]``). - See :pep:`585` and :ref:`types-genericalias`. + The function recursively replaces all ``Annotated[T, ...]`` with ``T``, + unless ``include_extras`` is set to ``True`` (see :class:`Annotated` for + more information). For example: -.. class:: AsyncIterator(AsyncIterable[T_co]) + .. testcode:: - A generic version of :class:`collections.abc.AsyncIterator`. + class Student(NamedTuple): + name: Annotated[str, 'some marker'] - .. versionadded:: 3.5.2 + assert get_type_hints(Student) == {'name': str} + assert get_type_hints(Student, include_extras=False) == {'name': str} + assert get_type_hints(Student, include_extras=True) == { + 'name': Annotated[str, 'some marker'] + } - .. deprecated:: 3.9 - :class:`collections.abc.AsyncIterator` now supports subscripting (``[]``). - See :pep:`585` and :ref:`types-genericalias`. + .. note:: -.. class:: Awaitable(Generic[T_co]) + :func:`get_type_hints` does not work with imported + :ref:`type aliases <type-aliases>` that include forward references. + Enabling postponed evaluation of annotations (:pep:`563`) may remove + the need for most forward references. - A generic version of :class:`collections.abc.Awaitable`. + .. versionchanged:: 3.9 + Added ``include_extras`` parameter as part of :pep:`593`. + See the documentation on :data:`Annotated` for more information. - .. versionadded:: 3.5.2 + .. versionchanged:: 3.11 + Previously, ``Optional[t]`` was added for function and method annotations + if a default value equal to ``None`` was set. + Now the annotation is returned unchanged. - .. deprecated:: 3.9 - :class:`collections.abc.Awaitable` now supports subscripting (``[]``). - See :pep:`585` and :ref:`types-genericalias`. +.. function:: get_origin(tp) + Get the unsubscripted version of a type: for a typing object of the form + ``X[Y, Z, ...]`` return ``X``. -Context manager types -""""""""""""""""""""" + If ``X`` is a typing-module alias for a builtin or + :mod:`collections` class, it will be normalized to the original class. + If ``X`` is an instance of :class:`ParamSpecArgs` or :class:`ParamSpecKwargs`, + return the underlying :class:`ParamSpec`. + Return ``None`` for unsupported objects. -.. class:: ContextManager(Generic[T_co]) + Examples: - A generic version of :class:`contextlib.AbstractContextManager`. + .. testcode:: - .. versionadded:: 3.5.4 - .. versionadded:: 3.6.0 + assert get_origin(str) is None + assert get_origin(Dict[str, int]) is dict + assert get_origin(Union[int, str]) is Union + P = ParamSpec('P') + assert get_origin(P.args) is P + assert get_origin(P.kwargs) is P - .. deprecated:: 3.9 - :class:`contextlib.AbstractContextManager` - now supports subscripting (``[]``). - See :pep:`585` and :ref:`types-genericalias`. + .. versionadded:: 3.8 -.. class:: AsyncContextManager(Generic[T_co]) +.. function:: get_args(tp) - A generic version of :class:`contextlib.AbstractAsyncContextManager`. + Get type arguments with all substitutions performed: for a typing object + of the form ``X[Y, Z, ...]`` return ``(Y, Z, ...)``. - .. versionadded:: 3.5.4 - .. versionadded:: 3.6.2 + If ``X`` is a union or :class:`Literal` contained in another + generic type, the order of ``(Y, Z, ...)`` may be different from the order + of the original arguments ``[Y, Z, ...]`` due to type caching. + Return ``()`` for unsupported objects. - .. deprecated:: 3.9 - :class:`contextlib.AbstractAsyncContextManager` - now supports subscripting (``[]``). - See :pep:`585` and :ref:`types-genericalias`. + Examples: -Protocols ---------- + .. testcode:: -These protocols are decorated with :func:`runtime_checkable`. + assert get_args(int) == () + assert get_args(Dict[int, str]) == (int, str) + assert get_args(Union[int, str]) == (int, str) -.. class:: SupportsAbs + .. versionadded:: 3.8 - An ABC with one abstract method ``__abs__`` that is covariant - in its return type. +.. function:: is_typeddict(tp) -.. class:: SupportsBytes + Check if a type is a :class:`TypedDict`. - An ABC with one abstract method ``__bytes__``. + For example: -.. class:: SupportsComplex + .. testcode:: - An ABC with one abstract method ``__complex__``. + class Film(TypedDict): + title: str + year: int -.. class:: SupportsFloat + assert is_typeddict(Film) + assert not is_typeddict(list | str) - An ABC with one abstract method ``__float__``. + # TypedDict is a factory for creating typed dicts, + # not a typed dict itself + assert not is_typeddict(TypedDict) -.. class:: SupportsIndex + .. versionadded:: 3.10 - An ABC with one abstract method ``__index__``. +.. class:: ForwardRef - .. versionadded:: 3.8 + Class used for internal typing representation of string forward references. -.. class:: SupportsInt + For example, ``List["SomeClass"]`` is implicitly transformed into + ``List[ForwardRef("SomeClass")]``. ``ForwardRef`` should not be instantiated by + a user, but may be used by introspection tools. - An ABC with one abstract method ``__int__``. + .. note:: + :pep:`585` generic types such as ``list["SomeClass"]`` will not be + implicitly transformed into ``list[ForwardRef("SomeClass")]`` and thus + will not automatically resolve to ``list[SomeClass]``. -.. class:: SupportsRound + .. versionadded:: 3.7.4 - An ABC with one abstract method ``__round__`` - that is covariant in its return type. +Constant +-------- -Functions and decorators ------------------------- +.. data:: TYPE_CHECKING -.. function:: cast(typ, val) + A special constant that is assumed to be ``True`` by 3rd party static + type checkers. It is ``False`` at runtime. - Cast a value to a type. + Usage:: - This returns the value unchanged. To the type checker this - signals that the return value has the designated type, but at - runtime we intentionally don't check anything (we want this - to be as fast as possible). + if TYPE_CHECKING: + import expensive_mod -.. function:: assert_type(val, typ, /) + def fun(arg: 'expensive_mod.SomeType') -> None: + local_var: expensive_mod.AnotherType = other_fun() - Ask a static type checker to confirm that *val* has an inferred type of *typ*. + The first type annotation must be enclosed in quotes, making it a + "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. - When the type checker encounters a call to ``assert_type()``, it - emits an error if the value is not of the specified type:: + .. note:: - def greet(name: str) -> None: - assert_type(name, str) # OK, inferred type of `name` is `str` - assert_type(name, int) # type checker error + If ``from __future__ import annotations`` is used, + annotations are not evaluated at function definition time. + Instead, they are stored as strings in ``__annotations__``. + This makes it unnecessary to use quotes around the annotation + (see :pep:`563`). - At runtime this returns the first argument unchanged with no side effects. + .. versionadded:: 3.5.2 - This function is useful for ensuring the type checker's understanding of a - script is in line with the developer's intentions:: +.. _generic-concrete-collections: +.. _deprecated-aliases: - def complex_function(arg: object): - # Do some complex type-narrowing logic, - # after which we hope the inferred type will be `int` - ... - # Test whether the type checker correctly understands our function - assert_type(arg, int) +Deprecated aliases +------------------ - .. versionadded:: 3.11 +This module defines several deprecated aliases to pre-existing +standard library classes. These were originally included in the typing +module in order to support parameterizing these generic classes using ``[]``. +However, the aliases became redundant in Python 3.9 when the +corresponding pre-existing classes were enhanced to support ``[]`` (see +:pep:`585`). -.. function:: assert_never(arg, /) +The redundant types are deprecated as of Python 3.9. However, while the aliases +may be removed at some point, removal of these aliases is not currently +planned. As such, no deprecation warnings are currently issued by the +interpreter for these aliases. - Ask a static type checker to confirm that a line of code is unreachable. +If at some point it is decided to remove these deprecated aliases, a +deprecation warning will be issued by the interpreter for at least two releases +prior to removal. The aliases are guaranteed to remain in the typing module +without deprecation warnings until at least Python 3.14. - Example:: +Type checkers are encouraged to flag uses of the deprecated types if the +program they are checking targets a minimum Python version of 3.9 or newer. - def int_or_str(arg: int | str) -> None: - match arg: - case int(): - print("It's an int") - case str(): - print("It's a str") - case _ as unreachable: - assert_never(unreachable) +.. _corresponding-to-built-in-types: - Here, the annotations allow the type checker to infer that the - last case can never execute, because ``arg`` is either - an :class:`int` or a :class:`str`, and both options are covered by - earlier cases. - If a type checker finds that a call to ``assert_never()`` is - reachable, it will emit an error. For example, if the type annotation - for ``arg`` was instead ``int | str | float``, the type checker would - emit an error pointing out that ``unreachable`` is of type :class:`float`. - For a call to ``assert_never`` to pass type checking, the inferred type of - the argument passed in must be the bottom type, :data:`Never`, and nothing - else. +Aliases to built-in types +""""""""""""""""""""""""" - At runtime, this throws an exception when called. +.. class:: Dict(dict, MutableMapping[KT, VT]) - .. seealso:: - `Unreachable Code and Exhaustiveness Checking - <https://typing.readthedocs.io/en/latest/source/unreachable.html>`__ has more - information about exhaustiveness checking with static typing. + Deprecated alias to :class:`dict`. - .. versionadded:: 3.11 + Note that to annotate arguments, it is preferred + to use an abstract collection type such as :class:`Mapping` + rather than to use :class:`dict` or :class:`!typing.Dict`. -.. function:: reveal_type(obj, /) + This type can be used as follows:: - Reveal the inferred static type of an expression. + def count_words(text: str) -> Dict[str, int]: + ... - When a static type checker encounters a call to this function, - it emits a diagnostic with the type of the argument. For example:: + .. deprecated:: 3.9 + :class:`builtins.dict <dict>` now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. - x: int = 1 - reveal_type(x) # Revealed type is "builtins.int" +.. class:: List(list, MutableSequence[T]) - This can be useful when you want to debug how your type checker - handles a particular piece of code. + Deprecated alias to :class:`list`. - The function returns its argument unchanged, which allows using - it within an expression:: + Note that to annotate arguments, it is preferred + to use an abstract collection type such as :class:`Sequence` or + :class:`Iterable` rather than to use :class:`list` or :class:`!typing.List`. - x = reveal_type(1) # Revealed type is "builtins.int" + This type may be used as follows:: - Most type checkers support ``reveal_type()`` anywhere, even if the - name is not imported from ``typing``. Importing the name from - ``typing`` allows your code to run without runtime errors and - communicates intent more clearly. + def vec2[T: (int, float)](x: T, y: T) -> List[T]: + return [x, y] - At runtime, this function prints the runtime type of its argument to stderr - and returns it unchanged:: + def keep_positives[T: (int, float)](vector: Sequence[T]) -> List[T]: + return [item for item in vector if item > 0] - x = reveal_type(1) # prints "Runtime type is int" - print(x) # prints "1" + .. deprecated:: 3.9 + :class:`builtins.list <list>` now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. - .. versionadded:: 3.11 +.. class:: Set(set, MutableSet[T]) -.. decorator:: dataclass_transform + Deprecated alias to :class:`builtins.set <set>`. - :data:`~typing.dataclass_transform` may be used to - decorate a class, metaclass, or a function that is itself a decorator. - The presence of ``@dataclass_transform()`` tells a static type checker that the - decorated object performs runtime "magic" that - transforms a class, giving it :func:`dataclasses.dataclass`-like behaviors. + Note that to annotate arguments, it is preferred + to use an abstract collection type such as :class:`AbstractSet` + rather than to use :class:`set` or :class:`!typing.Set`. - Example usage with a decorator function:: + .. deprecated:: 3.9 + :class:`builtins.set <set>` now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. - T = TypeVar("T") +.. class:: FrozenSet(frozenset, AbstractSet[T_co]) - @dataclass_transform() - def create_model(cls: type[T]) -> type[T]: - ... - return cls + Deprecated alias to :class:`builtins.frozenset <frozenset>`. - @create_model - class CustomerModel: - id: int - name: str + .. deprecated:: 3.9 + :class:`builtins.frozenset <frozenset>` + now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. - On a base class:: +.. data:: Tuple - @dataclass_transform() - class ModelBase: ... + Deprecated alias for :class:`tuple`. - class CustomerModel(ModelBase): - id: int - name: str + :class:`tuple` and ``Tuple`` are special-cased in the type system; see + :ref:`annotating-tuples` for more details. - On a metaclass:: + .. deprecated:: 3.9 + :class:`builtins.tuple <tuple>` now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. - @dataclass_transform() - class ModelMeta(type): ... +.. class:: Type(Generic[CT_co]) - class ModelBase(metaclass=ModelMeta): ... + Deprecated alias to :class:`type`. - class CustomerModel(ModelBase): - id: int - name: str + See :ref:`type-of-class-objects` for details on using :class:`type` or + ``typing.Type`` in type annotations. - The ``CustomerModel`` classes defined above will - be treated by type checkers similarly to classes created with - :func:`@dataclasses.dataclass <dataclasses.dataclass>`. - For example, type checkers will assume these classes have - ``__init__`` methods that accept ``id`` and ``name``. + .. versionadded:: 3.5.2 - The decorated class, metaclass, or function may accept the following bool - arguments which type checkers will assume have the same effect as they - would have on the - :func:`@dataclasses.dataclass<dataclasses.dataclass>` decorator: ``init``, - ``eq``, ``order``, ``unsafe_hash``, ``frozen``, ``match_args``, - ``kw_only``, and ``slots``. It must be possible for the value of these - arguments (``True`` or ``False``) to be statically evaluated. + .. deprecated:: 3.9 + :class:`builtins.type <type>` now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. - The arguments to the ``dataclass_transform`` decorator can be used to - customize the default behaviors of the decorated class, metaclass, or - function: +.. _corresponding-to-types-in-collections: - * ``eq_default`` indicates whether the ``eq`` parameter is assumed to be - ``True`` or ``False`` if it is omitted by the caller. - * ``order_default`` indicates whether the ``order`` parameter is - assumed to be True or False if it is omitted by the caller. - * ``kw_only_default`` indicates whether the ``kw_only`` parameter is - assumed to be True or False if it is omitted by the caller. - * ``field_specifiers`` specifies a static list of supported classes - or functions that describe fields, similar to ``dataclasses.field()``. - * Arbitrary other keyword arguments are accepted in order to allow for - possible future extensions. - - Type checkers recognize the following optional arguments on field - specifiers: +Aliases to types in :mod:`collections` +"""""""""""""""""""""""""""""""""""""" - * ``init`` indicates whether the field should be included in the - synthesized ``__init__`` method. If unspecified, ``init`` defaults to - ``True``. - * ``default`` provides the default value for the field. - * ``default_factory`` provides a runtime callback that returns the - default value for the field. If neither ``default`` nor - ``default_factory`` are specified, the field is assumed to have no - default value and must be provided a value when the class is - instantiated. - * ``factory`` is an alias for ``default_factory``. - * ``kw_only`` indicates whether the field should be marked as - keyword-only. If ``True``, the field will be keyword-only. If - ``False``, it will not be keyword-only. If unspecified, the value of - the ``kw_only`` parameter on the object decorated with - ``dataclass_transform`` will be used, or if that is unspecified, the - value of ``kw_only_default`` on ``dataclass_transform`` will be used. - * ``alias`` provides an alternative name for the field. This alternative - name is used in the synthesized ``__init__`` method. +.. class:: DefaultDict(collections.defaultdict, MutableMapping[KT, VT]) - At runtime, this decorator records its arguments in the - ``__dataclass_transform__`` attribute on the decorated object. - It has no other runtime effect. + Deprecated alias to :class:`collections.defaultdict`. - See :pep:`681` for more details. + .. versionadded:: 3.5.2 - .. versionadded:: 3.11 + .. deprecated:: 3.9 + :class:`collections.defaultdict` now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. -.. decorator:: overload +.. class:: OrderedDict(collections.OrderedDict, MutableMapping[KT, VT]) - The ``@overload`` decorator allows describing functions and methods - that support multiple different combinations of argument types. A series - of ``@overload``-decorated definitions must be followed by exactly one - non-``@overload``-decorated definition (for the same function/method). - The ``@overload``-decorated definitions are for the benefit of the - type checker only, since they will be overwritten by the - non-``@overload``-decorated definition, while the latter is used at - runtime but should be ignored by a type checker. At runtime, calling - a ``@overload``-decorated function directly will raise - :exc:`NotImplementedError`. An example of overload that gives a more - precise type than can be expressed using a union or a type variable:: + Deprecated alias to :class:`collections.OrderedDict`. - @overload - def process(response: None) -> None: - ... - @overload - def process(response: int) -> tuple[int, str]: - ... - @overload - def process(response: bytes) -> str: - ... - def process(response): - <actual implementation> + .. versionadded:: 3.7.2 - See :pep:`484` for more details and comparison with other typing semantics. + .. deprecated:: 3.9 + :class:`collections.OrderedDict` now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. - .. versionchanged:: 3.11 - Overloaded functions can now be introspected at runtime using - :func:`get_overloads`. +.. class:: ChainMap(collections.ChainMap, MutableMapping[KT, VT]) + Deprecated alias to :class:`collections.ChainMap`. -.. function:: get_overloads(func) + .. versionadded:: 3.5.4 + .. versionadded:: 3.6.1 - Return a sequence of :func:`@overload <overload>`-decorated definitions for - *func*. *func* is the function object for the implementation of the - overloaded function. For example, given the definition of ``process`` in - the documentation for :func:`@overload <overload>`, - ``get_overloads(process)`` will return a sequence of three function objects - for the three defined overloads. If called on a function with no overloads, - ``get_overloads()`` returns an empty sequence. + .. deprecated:: 3.9 + :class:`collections.ChainMap` now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. - ``get_overloads()`` can be used for introspecting an overloaded function at - runtime. +.. class:: Counter(collections.Counter, Dict[T, int]) - .. versionadded:: 3.11 + Deprecated alias to :class:`collections.Counter`. + .. versionadded:: 3.5.4 + .. versionadded:: 3.6.1 -.. function:: clear_overloads() + .. deprecated:: 3.9 + :class:`collections.Counter` now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. - Clear all registered overloads in the internal registry. This can be used - to reclaim the memory used by the registry. +.. class:: Deque(deque, MutableSequence[T]) - .. versionadded:: 3.11 + Deprecated alias to :class:`collections.deque`. + .. versionadded:: 3.5.4 + .. versionadded:: 3.6.1 -.. decorator:: final + .. deprecated:: 3.9 + :class:`collections.deque` now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. - A decorator to indicate to type checkers that the decorated method - cannot be overridden, and the decorated class cannot be subclassed. - For example:: +.. _other-concrete-types: - class Base: - @final - def done(self) -> None: - ... - class Sub(Base): - def done(self) -> None: # Error reported by type checker - ... +Aliases to other concrete types +""""""""""""""""""""""""""""""" - @final - class Leaf: - ... - class Other(Leaf): # Error reported by type checker - ... + .. deprecated-removed:: 3.8 3.13 + The ``typing.io`` namespace is deprecated and will be removed. + These types should be directly imported from ``typing`` instead. - There is no runtime checking of these properties. See :pep:`591` for - more details. +.. class:: Pattern + Match - .. versionadded:: 3.8 + Deprecated aliases corresponding to the return types from + :func:`re.compile` and :func:`re.match`. - .. versionchanged:: 3.11 - The decorator will now set the ``__final__`` attribute to ``True`` - on the decorated object. Thus, a check like - ``if getattr(obj, "__final__", False)`` can be used at runtime - to determine whether an object ``obj`` has been marked as final. - If the decorated object does not support setting attributes, - the decorator returns the object unchanged without raising an exception. + These types (and the corresponding functions) are generic over + :data:`AnyStr`. ``Pattern`` can be specialised as ``Pattern[str]`` or + ``Pattern[bytes]``; ``Match`` can be specialised as ``Match[str]`` or + ``Match[bytes]``. + .. deprecated-removed:: 3.8 3.13 + The ``typing.re`` namespace is deprecated and will be removed. + These types should be directly imported from ``typing`` instead. -.. decorator:: no_type_check + .. deprecated:: 3.9 + Classes ``Pattern`` and ``Match`` from :mod:`re` now support ``[]``. + See :pep:`585` and :ref:`types-genericalias`. - Decorator to indicate that annotations are not type hints. +.. class:: Text - This works as class or function :term:`decorator`. With a class, it - applies recursively to all methods and classes defined in that class - (but not to methods defined in its superclasses or subclasses). + Deprecated alias for :class:`str`. - This mutates the function(s) in place. + ``Text`` is provided to supply a forward + compatible path for Python 2 code: in Python 2, ``Text`` is an alias for + ``unicode``. -.. decorator:: no_type_check_decorator + Use ``Text`` to indicate that a value must contain a unicode string in + a manner that is compatible with both Python 2 and Python 3:: - Decorator to give another decorator the :func:`no_type_check` effect. + def add_unicode_checkmark(text: Text) -> Text: + return text + u' \u2713' - This wraps the decorator with something that wraps the decorated - function in :func:`no_type_check`. + .. versionadded:: 3.5.2 -.. decorator:: type_check_only + .. deprecated:: 3.11 + Python 2 is no longer supported, and most type checkers also no longer + support type checking Python 2 code. Removal of the alias is not + currently planned, but users are encouraged to use + :class:`str` instead of ``Text``. - Decorator to mark a class or function to be unavailable at runtime. +.. _abstract-base-classes: +.. _corresponding-to-collections-in-collections-abc: - This decorator is itself not available at runtime. It is mainly - intended to mark classes that are defined in type stub files if - an implementation returns an instance of a private class:: +Aliases to container ABCs in :mod:`collections.abc` +""""""""""""""""""""""""""""""""""""""""""""""""""" - @type_check_only - class Response: # private or not available at runtime - code: int - def get_header(self, name: str) -> str: ... +.. class:: AbstractSet(Collection[T_co]) - def fetch_response() -> Response: ... + Deprecated alias to :class:`collections.abc.Set`. - Note that returning instances of private classes is not recommended. - It is usually preferable to make such classes public. + .. deprecated:: 3.9 + :class:`collections.abc.Set` now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. -Introspection helpers ---------------------- +.. class:: ByteString(Sequence[int]) -.. function:: get_type_hints(obj, globalns=None, localns=None, include_extras=False) + This type represents the types :class:`bytes`, :class:`bytearray`, + and :class:`memoryview` of byte sequences. - Return a dictionary containing type hints for a function, method, module - or class object. + .. deprecated-removed:: 3.9 3.14 + Prefer :class:`collections.abc.Buffer`, or a union like ``bytes | bytearray | memoryview``. - This is often the same as ``obj.__annotations__``. In addition, - forward references encoded as string literals are handled by evaluating - them in ``globals`` and ``locals`` namespaces. For a class ``C``, return - a dictionary constructed by merging all the ``__annotations__`` along - ``C.__mro__`` in reverse order. +.. class:: Collection(Sized, Iterable[T_co], Container[T_co]) - The function recursively replaces all ``Annotated[T, ...]`` with ``T``, - unless ``include_extras`` is set to ``True`` (see :class:`Annotated` for - more information). For example:: + Deprecated alias to :class:`collections.abc.Collection`. - class Student(NamedTuple): - name: Annotated[str, 'some marker'] + .. versionadded:: 3.6.0 - get_type_hints(Student) == {'name': str} - get_type_hints(Student, include_extras=False) == {'name': str} - get_type_hints(Student, include_extras=True) == { - 'name': Annotated[str, 'some marker'] - } + .. deprecated:: 3.9 + :class:`collections.abc.Collection` now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. - .. note:: +.. class:: Container(Generic[T_co]) - :func:`get_type_hints` does not work with imported - :ref:`type aliases <type-aliases>` that include forward references. - Enabling postponed evaluation of annotations (:pep:`563`) may remove - the need for most forward references. + Deprecated alias to :class:`collections.abc.Container`. - .. versionchanged:: 3.9 - Added ``include_extras`` parameter as part of :pep:`593`. + .. deprecated:: 3.9 + :class:`collections.abc.Container` now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. - .. versionchanged:: 3.11 - Previously, ``Optional[t]`` was added for function and method annotations - if a default value equal to ``None`` was set. - Now the annotation is returned unchanged. +.. class:: ItemsView(MappingView, AbstractSet[tuple[KT_co, VT_co]]) -.. function:: get_args(tp) -.. function:: get_origin(tp) + Deprecated alias to :class:`collections.abc.ItemsView`. - Provide basic introspection for generic types and special typing forms. + .. deprecated:: 3.9 + :class:`collections.abc.ItemsView` now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. - For a typing object of the form ``X[Y, Z, ...]`` these functions return - ``X`` and ``(Y, Z, ...)``. If ``X`` is a generic alias for a builtin or - :mod:`collections` class, it gets normalized to the original class. - If ``X`` is a union or :class:`Literal` contained in another - generic type, the order of ``(Y, Z, ...)`` may be different from the order - of the original arguments ``[Y, Z, ...]`` due to type caching. - For unsupported objects return ``None`` and ``()`` correspondingly. - Examples:: +.. class:: KeysView(MappingView, AbstractSet[KT_co]) - assert get_origin(Dict[str, int]) is dict - assert get_args(Dict[int, str]) == (int, str) + Deprecated alias to :class:`collections.abc.KeysView`. - assert get_origin(Union[int, str]) is Union - assert get_args(Union[int, str]) == (int, str) + .. deprecated:: 3.9 + :class:`collections.abc.KeysView` now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. - .. versionadded:: 3.8 +.. class:: Mapping(Collection[KT], Generic[KT, VT_co]) -.. function:: is_typeddict(tp) + Deprecated alias to :class:`collections.abc.Mapping`. - Check if a type is a :class:`TypedDict`. + This type can be used as follows:: - For example:: + def get_position_in_index(word_list: Mapping[str, int], word: str) -> int: + return word_list[word] - class Film(TypedDict): - title: str - year: int + .. deprecated:: 3.9 + :class:`collections.abc.Mapping` now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. - is_typeddict(Film) # => True - is_typeddict(list | str) # => False +.. class:: MappingView(Sized) - .. versionadded:: 3.10 + Deprecated alias to :class:`collections.abc.MappingView`. -.. class:: ForwardRef + .. deprecated:: 3.9 + :class:`collections.abc.MappingView` now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. - A class used for internal typing representation of string forward references. - For example, ``List["SomeClass"]`` is implicitly transformed into - ``List[ForwardRef("SomeClass")]``. This class should not be instantiated by - a user, but may be used by introspection tools. +.. class:: MutableMapping(Mapping[KT, VT]) - .. note:: - :pep:`585` generic types such as ``list["SomeClass"]`` will not be - implicitly transformed into ``list[ForwardRef("SomeClass")]`` and thus - will not automatically resolve to ``list[SomeClass]``. + Deprecated alias to :class:`collections.abc.MutableMapping`. - .. versionadded:: 3.7.4 + .. deprecated:: 3.9 + :class:`collections.abc.MutableMapping` + now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. -Constant --------- +.. class:: MutableSequence(Sequence[T]) -.. data:: TYPE_CHECKING + Deprecated alias to :class:`collections.abc.MutableSequence`. - A special constant that is assumed to be ``True`` by 3rd party static - type checkers. It is ``False`` at runtime. Usage:: + .. deprecated:: 3.9 + :class:`collections.abc.MutableSequence` + now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. - if TYPE_CHECKING: - import expensive_mod +.. class:: MutableSet(AbstractSet[T]) - def fun(arg: 'expensive_mod.SomeType') -> None: - local_var: expensive_mod.AnotherType = other_fun() + Deprecated alias to :class:`collections.abc.MutableSet`. - The first type annotation must be enclosed in quotes, making it a - "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. + .. deprecated:: 3.9 + :class:`collections.abc.MutableSet` now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. - .. note:: +.. class:: Sequence(Reversible[T_co], Collection[T_co]) - If ``from __future__ import annotations`` is used, - annotations are not evaluated at function definition time. - Instead, they are stored as strings in ``__annotations__``. - This makes it unnecessary to use quotes around the annotation - (see :pep:`563`). + Deprecated alias to :class:`collections.abc.Sequence`. + + .. deprecated:: 3.9 + :class:`collections.abc.Sequence` now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. + +.. class:: ValuesView(MappingView, Collection[_VT_co]) + + Deprecated alias to :class:`collections.abc.ValuesView`. + + .. deprecated:: 3.9 + :class:`collections.abc.ValuesView` now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. + +.. _asynchronous-programming: + +Aliases to asynchronous ABCs in :mod:`collections.abc` +"""""""""""""""""""""""""""""""""""""""""""""""""""""" + +.. class:: Coroutine(Awaitable[ReturnType], Generic[YieldType, SendType, ReturnType]) + + Deprecated alias to :class:`collections.abc.Coroutine`. + + The variance and order of type variables + correspond to those of :class:`Generator`, for example:: + + from collections.abc import Coroutine + c: Coroutine[list[str], str, int] # Some coroutine defined elsewhere + x = c.send('hi') # Inferred type of 'x' is list[str] + async def bar() -> None: + y = await c # Inferred type of 'y' is int + + .. versionadded:: 3.5.3 + + .. deprecated:: 3.9 + :class:`collections.abc.Coroutine` now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. + +.. class:: AsyncGenerator(AsyncIterator[YieldType], Generic[YieldType, SendType]) + + Deprecated alias to :class:`collections.abc.AsyncGenerator`. + + An async generator can be annotated by the generic type + ``AsyncGenerator[YieldType, SendType]``. For example:: + + async def echo_round() -> AsyncGenerator[int, float]: + sent = yield 0 + while sent >= 0.0: + rounded = await round(sent) + sent = yield rounded + + Unlike normal generators, async generators cannot return a value, so there + is no ``ReturnType`` type parameter. As with :class:`Generator`, the + ``SendType`` behaves contravariantly. + + If your generator will only yield values, set the ``SendType`` to + ``None``:: + + async def infinite_stream(start: int) -> AsyncGenerator[int, None]: + while True: + yield start + start = await increment(start) + + Alternatively, annotate your generator as having a return type of + either ``AsyncIterable[YieldType]`` or ``AsyncIterator[YieldType]``:: + + async def infinite_stream(start: int) -> AsyncIterator[int]: + while True: + yield start + start = await increment(start) + + .. versionadded:: 3.6.1 + + .. deprecated:: 3.9 + :class:`collections.abc.AsyncGenerator` + now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. + +.. class:: AsyncIterable(Generic[T_co]) + + Deprecated alias to :class:`collections.abc.AsyncIterable`. .. versionadded:: 3.5.2 + .. deprecated:: 3.9 + :class:`collections.abc.AsyncIterable` now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. + +.. class:: AsyncIterator(AsyncIterable[T_co]) + + Deprecated alias to :class:`collections.abc.AsyncIterator`. + + .. versionadded:: 3.5.2 + + .. deprecated:: 3.9 + :class:`collections.abc.AsyncIterator` now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. + +.. class:: Awaitable(Generic[T_co]) + + Deprecated alias to :class:`collections.abc.Awaitable`. + + .. versionadded:: 3.5.2 + + .. deprecated:: 3.9 + :class:`collections.abc.Awaitable` now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. + +.. _corresponding-to-other-types-in-collections-abc: + +Aliases to other ABCs in :mod:`collections.abc` +""""""""""""""""""""""""""""""""""""""""""""""" + +.. class:: Iterable(Generic[T_co]) + + Deprecated alias to :class:`collections.abc.Iterable`. + + .. deprecated:: 3.9 + :class:`collections.abc.Iterable` now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. + +.. class:: Iterator(Iterable[T_co]) + + Deprecated alias to :class:`collections.abc.Iterator`. + + .. deprecated:: 3.9 + :class:`collections.abc.Iterator` now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. + +.. data:: Callable + + Deprecated alias to :class:`collections.abc.Callable`. + + See :ref:`annotating-callables` for details on how to use + :class:`collections.abc.Callable` and ``typing.Callable`` in type annotations. + + .. deprecated:: 3.9 + :class:`collections.abc.Callable` now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. + + .. versionchanged:: 3.10 + ``Callable`` now supports :class:`ParamSpec` and :data:`Concatenate`. + See :pep:`612` for more details. + +.. class:: Generator(Iterator[YieldType], Generic[YieldType, SendType, ReturnType]) + + Deprecated alias to :class:`collections.abc.Generator`. + + A generator can be annotated by the generic type + ``Generator[YieldType, SendType, ReturnType]``. For example:: + + def echo_round() -> Generator[int, float, str]: + sent = yield 0 + while sent >= 0: + sent = yield round(sent) + return 'Done' + + Note that unlike many other generics in the typing module, the ``SendType`` + of :class:`Generator` behaves contravariantly, not covariantly or + invariantly. + + If your generator will only yield values, set the ``SendType`` and + ``ReturnType`` to ``None``:: + + def infinite_stream(start: int) -> Generator[int, None, None]: + while True: + yield start + start += 1 + + Alternatively, annotate your generator as having a return type of + either ``Iterable[YieldType]`` or ``Iterator[YieldType]``:: + + def infinite_stream(start: int) -> Iterator[int]: + while True: + yield start + start += 1 + + .. deprecated:: 3.9 + :class:`collections.abc.Generator` now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. + +.. class:: Hashable + + Deprecated alias to :class:`collections.abc.Hashable`. + + .. deprecated:: 3.12 + Use :class:`collections.abc.Hashable` directly instead. + +.. class:: Reversible(Iterable[T_co]) + + Deprecated alias to :class:`collections.abc.Reversible`. + + .. deprecated:: 3.9 + :class:`collections.abc.Reversible` now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. + +.. class:: Sized + + Deprecated alias to :class:`collections.abc.Sized`. + + .. deprecated:: 3.12 + Use :class:`collections.abc.Sized` directly instead. + +.. _context-manager-types: + +Aliases to :mod:`contextlib` ABCs +""""""""""""""""""""""""""""""""" + +.. class:: ContextManager(Generic[T_co]) + + Deprecated alias to :class:`contextlib.AbstractContextManager`. + + .. versionadded:: 3.5.4 + .. versionadded:: 3.6.0 + + .. deprecated:: 3.9 + :class:`contextlib.AbstractContextManager` + now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. + +.. class:: AsyncContextManager(Generic[T_co]) + + Deprecated alias to :class:`contextlib.AbstractAsyncContextManager`. + + .. versionadded:: 3.5.4 + .. versionadded:: 3.6.2 + + .. deprecated:: 3.9 + :class:`contextlib.AbstractAsyncContextManager` + now supports subscripting (``[]``). + See :pep:`585` and :ref:`types-genericalias`. + Deprecation Timeline of Major Features ====================================== @@ -2859,14 +3640,34 @@ Certain features in ``typing`` are deprecated and may be removed in a future version of Python. The following table summarizes major deprecations for your convenience. This is subject to change, and not all deprecations are listed. -+----------------------------------+---------------+-------------------+----------------+ -| Feature | Deprecated in | Projected removal | PEP/issue | -+==================================+===============+===================+================+ -| ``typing.io`` and ``typing.re`` | 3.8 | 3.13 | :issue:`38291` | -| submodules | | | | -+----------------------------------+---------------+-------------------+----------------+ -| ``typing`` versions of standard | 3.9 | Undecided | :pep:`585` | -| collections | | | | -+----------------------------------+---------------+-------------------+----------------+ -| ``typing.Text`` | 3.11 | Undecided | :gh:`92332` | -+----------------------------------+---------------+-------------------+----------------+ +.. list-table:: + :header-rows: 1 + + * - Feature + - Deprecated in + - Projected removal + - PEP/issue + * - ``typing.io`` and ``typing.re`` submodules + - 3.8 + - 3.13 + - :issue:`38291` + * - ``typing`` versions of standard collections + - 3.9 + - Undecided (see :ref:`deprecated-aliases` for more information) + - :pep:`585` + * - :class:`typing.ByteString` + - 3.9 + - 3.14 + - :gh:`91896` + * - :data:`typing.Text` + - 3.11 + - Undecided + - :gh:`92332` + * - :class:`typing.Hashable` and :class:`typing.Sized` + - 3.12 + - Undecided + - :gh:`94309` + * - :data:`typing.TypeAlias` + - 3.12 + - Undecided + - :pep:`695` diff --git a/Doc/library/unicodedata.rst b/Doc/library/unicodedata.rst index 6276f638..3a094f9c 100644 --- a/Doc/library/unicodedata.rst +++ b/Doc/library/unicodedata.rst @@ -17,8 +17,8 @@ This module provides access to the Unicode Character Database (UCD) which defines character properties for all Unicode characters. The data contained in -this database is compiled from the `UCD version 14.0.0 -<https://www.unicode.org/Public/14.0.0/ucd>`_. +this database is compiled from the `UCD version 15.0.0 +<https://www.unicode.org/Public/15.0.0/ucd>`_. The module uses the same names and symbols as defined by Unicode Standard Annex #44, `"Unicode Character Database" @@ -175,6 +175,6 @@ Examples: .. rubric:: Footnotes -.. [#] https://www.unicode.org/Public/14.0.0/ucd/NameAliases.txt +.. [#] https://www.unicode.org/Public/15.0.0/ucd/NameAliases.txt -.. [#] https://www.unicode.org/Public/14.0.0/ucd/NamedSequences.txt +.. [#] https://www.unicode.org/Public/15.0.0/ucd/NamedSequences.txt diff --git a/Doc/library/unittest.mock-examples.rst b/Doc/library/unittest.mock-examples.rst index f9a207ba..34f343eb 100644 --- a/Doc/library/unittest.mock-examples.rst +++ b/Doc/library/unittest.mock-examples.rst @@ -360,6 +360,30 @@ of arbitrary attributes as well as the getting of them then you can use *spec_set* instead of *spec*. +Using side_effect to return per file content +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:func:`mock_open` is used to patch :func:`open` method. :attr:`~Mock.side_effect` +can be used to return a new Mock object per call. This can be used to return different +contents per file stored in a dictionary:: + + DEFAULT = "default" + data_dict = {"file1": "data1", + "file2": "data2"} + + def open_side_effect(name): + return mock_open(read_data=data_dict.get(name, DEFAULT))() + + with patch("builtins.open", side_effect=open_side_effect): + with open("file1") as file1: + assert file1.read() == "data1" + + with open("file2") as file2: + assert file2.read() == "data2" + + with open("file3") as file2: + assert file2.read() == "default" + Patch Decorators ---------------- @@ -579,14 +603,14 @@ Partial mocking In some tests I wanted to mock out a call to :meth:`datetime.date.today` to return a known date, but I didn't want to prevent the code under test from creating new date objects. Unfortunately :class:`datetime.date` is written in C, and -so I couldn't just monkey-patch out the static :meth:`date.today` method. +so I couldn't just monkey-patch out the static :meth:`datetime.date.today` method. I found a simple way of doing this that involved effectively wrapping the date class with a mock, but passing through calls to the constructor to the real class (and returning real instances). The :func:`patch decorator <patch>` is used here to -mock out the ``date`` class in the module under test. The :attr:`side_effect` +mock out the ``date`` class in the module under test. The :attr:`~Mock.side_effect` attribute on the mock date class is then set to a lambda function that returns a real date. When the mock date class is called a real date will be constructed and returned by ``side_effect``. :: @@ -766,8 +790,8 @@ mock has a nice API for making assertions about how your mock objects are used. >>> mock.foo_bar.assert_called_with('baz', spam='eggs') If your mock is only being called once you can use the -:meth:`assert_called_once_with` method that also asserts that the -:attr:`call_count` is one. +:meth:`~Mock.assert_called_once_with` method that also asserts that the +:attr:`~Mock.call_count` is one. >>> mock.foo_bar.assert_called_once_with('baz', spam='eggs') >>> mock.foo_bar() @@ -835,7 +859,7 @@ One possibility would be for mock to copy the arguments you pass in. This could then cause problems if you do assertions that rely on object identity for equality. -Here's one solution that uses the :attr:`side_effect` +Here's one solution that uses the :attr:`~Mock.side_effect` functionality. If you provide a ``side_effect`` function for a mock then ``side_effect`` will be called with the same args as the mock. This gives us an opportunity to copy the arguments and store them for later assertions. In this @@ -971,7 +995,8 @@ We can do this with :class:`MagicMock`, which will behave like a dictionary, and using :data:`~Mock.side_effect` to delegate dictionary access to a real underlying dictionary that is under our control. -When the :meth:`__getitem__` and :meth:`__setitem__` methods of our ``MagicMock`` are called +When the :meth:`~object.__getitem__` and :meth:`~object.__setitem__` methods +of our ``MagicMock`` are called (normal dictionary access) then ``side_effect`` is called with the key (and in the case of ``__setitem__`` the value too). We can also control what is returned. @@ -1074,7 +1099,7 @@ subclass. Sometimes this is inconvenient. For example, `one user <https://code.google.com/archive/p/mock/issues/105>`_ is subclassing mock to created a `Twisted adaptor -<https://twistedmatrix.com/documents/11.0.0/api/twisted.python.components.html>`_. +<https://twisted.org/documents/11.0.0/api/twisted.python.components.html>`_. Having this applied to attributes too actually causes errors. ``Mock`` (in all its flavours) uses a method called ``_get_child_mock`` to create diff --git a/Doc/library/unittest.mock.rst b/Doc/library/unittest.mock.rst index b768557e..13cd593f 100644 --- a/Doc/library/unittest.mock.rst +++ b/Doc/library/unittest.mock.rst @@ -72,6 +72,7 @@ available, and then make assertions about how they have been used: :attr:`side_effect` allows you to perform side effects, including raising an exception when a mock is called: + >>> from unittest.mock import Mock >>> mock = Mock(side_effect=KeyError('foo')) >>> mock() Traceback (most recent call last): @@ -406,7 +407,7 @@ the *new_callable* argument to :func:`patch`. False .. versionchanged:: 3.6 - Added two keyword only argument to the reset_mock function. + Added two keyword-only arguments to the reset_mock function. This can be useful where you want to make a series of assertions that reuse the same object. Note that :meth:`reset_mock` *doesn't* clear the @@ -416,8 +417,8 @@ the *new_callable* argument to :func:`patch`. parameter as ``True``. Child mocks and the return value mock (if any) are reset as well. - .. note:: *return_value*, and :attr:`side_effect` are keyword only - argument. + .. note:: *return_value*, and :attr:`side_effect` are keyword-only + arguments. .. method:: mock_add_spec(spec, spec_set=False) @@ -1604,6 +1605,7 @@ decorator: >>> @patch.dict(foo, {'newkey': 'newvalue'}) ... def test(): ... assert foo == {'newkey': 'newvalue'} + ... >>> test() >>> assert foo == {} @@ -2436,7 +2438,7 @@ behaviour you can switch it off by setting the module level switch Alternatively you can just use ``vars(my_mock)`` (instance members) and ``dir(type(my_mock))`` (type members) to bypass the filtering irrespective of -:data:`mock.FILTER_DIR`. +:const:`mock.FILTER_DIR`. mock_open diff --git a/Doc/library/unittest.rst b/Doc/library/unittest.rst index 82fded4a..4c28e8fa 100644 --- a/Doc/library/unittest.rst +++ b/Doc/library/unittest.rst @@ -72,7 +72,7 @@ test runner a GUI tool for test discovery and execution. This is intended largely for ease of use for those new to unit testing. For production environments it is recommended that tests be driven by a continuous integration system such as - `Buildbot <https://buildbot.net/>`_, `Jenkins <https://jenkins.io/>`_, + `Buildbot <https://buildbot.net/>`_, `Jenkins <https://www.jenkins.io/>`_, `GitHub Actions <https://github.com/features/actions>`_, or `AppVeyor <https://www.appveyor.com/>`_. @@ -244,6 +244,10 @@ Command-line options Show local variables in tracebacks. +.. cmdoption:: --durations N + + Show the N slowest test cases (N=0 for all). + .. versionadded:: 3.2 The command-line options ``-b``, ``-c`` and ``-f`` were added. @@ -253,10 +257,12 @@ Command-line options .. versionadded:: 3.7 The command-line option ``-k``. +.. versionadded:: 3.12 + The command-line option ``--durations``. + The command line can also be used for test discovery, for running all of the tests in a project or just a subset. - .. _unittest-test-discovery: Test Discovery @@ -1128,7 +1134,7 @@ Test cases If given, *level* should be either a numeric logging level or its string equivalent (for example either ``"ERROR"`` or - :attr:`logging.ERROR`). The default is :attr:`logging.INFO`. + :const:`logging.ERROR`). The default is :const:`logging.INFO`. The test passes if at least one message emitted inside the ``with`` block matches the *logger* and *level* conditions, otherwise it fails. @@ -1169,7 +1175,7 @@ Test cases If given, *level* should be either a numeric logging level or its string equivalent (for example either ``"ERROR"`` or - :attr:`logging.ERROR`). The default is :attr:`logging.INFO`. + :const:`logging.ERROR`). The default is :const:`logging.INFO`. Unlike :meth:`assertLogs`, nothing will be returned by the context manager. @@ -1261,9 +1267,6 @@ Test cases :meth:`.assertRegex`. .. versionadded:: 3.2 :meth:`.assertNotRegex`. - .. versionadded:: 3.5 - The name ``assertNotRegexpMatches`` is a deprecated alias - for :meth:`.assertNotRegex`. .. method:: assertCountEqual(first, second, msg=None) @@ -1660,40 +1663,6 @@ Test cases :mod:`unittest`-based test framework. -.. _deprecated-aliases: - -Deprecated aliases -################## - -For historical reasons, some of the :class:`TestCase` methods had one or more -aliases that are now deprecated. The following table lists the correct names -along with their deprecated aliases: - - ============================== ====================== ======================= - Method Name Deprecated alias Deprecated alias - ============================== ====================== ======================= - :meth:`.assertEqual` failUnlessEqual assertEquals - :meth:`.assertNotEqual` failIfEqual assertNotEquals - :meth:`.assertTrue` failUnless assert\_ - :meth:`.assertFalse` failIf - :meth:`.assertRaises` failUnlessRaises - :meth:`.assertAlmostEqual` failUnlessAlmostEqual assertAlmostEquals - :meth:`.assertNotAlmostEqual` failIfAlmostEqual assertNotAlmostEquals - :meth:`.assertRegex` assertRegexpMatches - :meth:`.assertNotRegex` assertNotRegexpMatches - :meth:`.assertRaisesRegex` assertRaisesRegexp - ============================== ====================== ======================= - - .. deprecated:: 3.1 - The fail* aliases listed in the second column have been deprecated. - .. deprecated:: 3.2 - The assert* aliases listed in the third column have been deprecated. - .. deprecated:: 3.2 - ``assertRegexpMatches`` and ``assertRaisesRegexp`` have been renamed to - :meth:`.assertRegex` and :meth:`.assertRaisesRegex`. - .. deprecated:: 3.5 - The ``assertNotRegexpMatches`` name is deprecated in favor of :meth:`.assertNotRegex`. - .. _testsuite-objects: Grouping tests @@ -1819,7 +1788,7 @@ Loading and running tests case is created for that method instead. - .. method:: loadTestsFromModule(module, pattern=None) + .. method:: loadTestsFromModule(module, *, pattern=None) Return a suite of all test cases contained in the given module. This method searches *module* for classes derived from :class:`TestCase` and @@ -1843,10 +1812,11 @@ Loading and running tests Support for ``load_tests`` added. .. versionchanged:: 3.5 - The undocumented and unofficial *use_load_tests* default argument is - deprecated and ignored, although it is still accepted for backward - compatibility. The method also now accepts a keyword-only argument - *pattern* which is passed to ``load_tests`` as the third argument. + Support for a keyword-only argument *pattern* has been added. + + .. versionchanged:: 3.12 + The undocumented and unofficial *use_load_tests* parameter has been + removed. .. method:: loadTestsFromName(name, module=None) @@ -2045,6 +2015,13 @@ Loading and running tests A list containing :class:`TestCase` instances that were marked as expected failures, but succeeded. + .. attribute:: collectedDurations + + A list containing 2-tuples of test case names and floats + representing the elapsed time of each test which was run. + + .. versionadded:: 3.12 + .. attribute:: shouldStop Set to ``True`` when the execution of tests should stop by :meth:`stop`. @@ -2196,16 +2173,23 @@ Loading and running tests .. versionadded:: 3.4 + .. method:: addDuration(test, elapsed) -.. class:: TextTestResult(stream, descriptions, verbosity) + Called when the test case finishes. *elapsed* is the time represented in + seconds, and it includes the execution of cleanup functions. + + .. versionadded:: 3.12 + +.. class:: TextTestResult(stream, descriptions, verbosity, *, durations=None) A concrete implementation of :class:`TestResult` used by the - :class:`TextTestRunner`. + :class:`TextTestRunner`. Subclasses should accept ``**kwargs`` to ensure + compatibility as the interface changes. .. versionadded:: 3.2 - This class was previously named ``_TextTestResult``. The old name still - exists as an alias but is deprecated. + .. versionadded:: 3.12 + Added *durations* keyword argument. .. data:: defaultTestLoader @@ -2215,7 +2199,8 @@ Loading and running tests .. class:: TextTestRunner(stream=None, descriptions=True, verbosity=1, failfast=False, \ - buffer=False, resultclass=None, warnings=None, *, tb_locals=False) + buffer=False, resultclass=None, warnings=None, *, \ + tb_locals=False, durations=None) A basic test runner implementation that outputs results to a stream. If *stream* is ``None``, the default, :data:`sys.stderr` is used as the output stream. This class @@ -2227,23 +2212,23 @@ Loading and running tests By default this runner shows :exc:`DeprecationWarning`, :exc:`PendingDeprecationWarning`, :exc:`ResourceWarning` and :exc:`ImportWarning` even if they are :ref:`ignored by default - <warning-ignored>`. Deprecation warnings caused by :ref:`deprecated unittest - methods <deprecated-aliases>` are also special-cased and, when the warning - filters are ``'default'`` or ``'always'``, they will appear only once - per-module, in order to avoid too many warning messages. This behavior can + <warning-ignored>`. This behavior can be overridden using Python's :option:`!-Wd` or :option:`!-Wa` options (see :ref:`Warning control <using-on-warnings>`) and leaving *warnings* to ``None``. .. versionchanged:: 3.2 - Added the ``warnings`` argument. + Added the *warnings* parameter. .. versionchanged:: 3.2 The default stream is set to :data:`sys.stderr` at instantiation time rather than import time. .. versionchanged:: 3.5 - Added the tb_locals parameter. + Added the *tb_locals* parameter. + + .. versionchanged:: 3.12 + Added the *durations* parameter. .. method:: _makeResult() @@ -2296,7 +2281,8 @@ Loading and running tests The *testRunner* argument can either be a test runner class or an already created instance of it. By default ``main`` calls :func:`sys.exit` with - an exit code indicating success or failure of the tests run. + an exit code indicating success (0) or failure (1) of the tests run. + An exit code of 5 indicates that no tests were run. The *testLoader* argument has to be a :class:`TestLoader` instance, and defaults to :data:`defaultTestLoader`. diff --git a/Doc/library/urllib.error.rst b/Doc/library/urllib.error.rst index f7d47ed7..a5bcb5b1 100644 --- a/Doc/library/urllib.error.rst +++ b/Doc/library/urllib.error.rst @@ -31,7 +31,7 @@ The following exceptions are raised by :mod:`urllib.error` as appropriate: of :exc:`IOError`. -.. exception:: HTTPError +.. exception:: HTTPError(url, code, msg, hdrs, fp) Though being an exception (a subclass of :exc:`URLError`), an :exc:`HTTPError` can also function as a non-exceptional file-like return @@ -39,6 +39,11 @@ The following exceptions are raised by :mod:`urllib.error` as appropriate: is useful when handling exotic HTTP errors, such as requests for authentication. + .. attribute:: url + + Contains the request URL. + An alias for *filename* attribute. + .. attribute:: code An HTTP status code as defined in :rfc:`2616`. This numeric value corresponds @@ -48,19 +53,27 @@ The following exceptions are raised by :mod:`urllib.error` as appropriate: .. attribute:: reason This is usually a string explaining the reason for this error. + An alias for *msg* attribute. .. attribute:: headers The HTTP response headers for the HTTP request that caused the :exc:`HTTPError`. + An alias for *hdrs* attribute. .. versionadded:: 3.4 + .. attribute:: fp + + A file-like object where the HTTP error body can be read from. + .. exception:: ContentTooShortError(msg, content) This exception is raised when the :func:`~urllib.request.urlretrieve` function detects that the amount of the downloaded data is less than the expected amount (given by - the *Content-Length* header). The :attr:`content` attribute stores the - downloaded (and supposedly truncated) data. + the *Content-Length* header). + + .. attribute:: content + The downloaded (and supposedly truncated) data. diff --git a/Doc/library/urllib.parse.rst b/Doc/library/urllib.parse.rst index 96b39651..53e5f039 100644 --- a/Doc/library/urllib.parse.rst +++ b/Doc/library/urllib.parse.rst @@ -23,9 +23,9 @@ to an absolute URL given a "base URL." The module has been designed to match the internet RFC on Relative Uniform Resource Locators. It supports the following URL schemes: ``file``, ``ftp``, ``gopher``, ``hdl``, ``http``, ``https``, ``imap``, ``mailto``, ``mms``, -``news``, ``nntp``, ``prospero``, ``rsync``, ``rtsp``, ``rtspu``, ``sftp``, -``shttp``, ``sip``, ``sips``, ``snews``, ``svn``, ``svn+ssh``, ``telnet``, -``wais``, ``ws``, ``wss``. +``news``, ``nntp``, ``prospero``, ``rsync``, ``rtsp``, ``rtsps``, ``rtspu``, +``sftp``, ``shttp``, ``sip``, ``sips``, ``snews``, ``svn``, ``svn+ssh``, +``telnet``, ``wais``, ``ws``, ``wss``. The :mod:`urllib.parse` module defines functions that fall into two broad categories: URL parsing and URL quoting. These are covered in detail in @@ -159,6 +159,10 @@ or on combining URL components into a URL string. ParseResult(scheme='http', netloc='www.cwi.nl:80', path='/%7Eguido/Python.html', params='', query='', fragment='') + .. warning:: + + :func:`urlparse` does not perform validation. See :ref:`URL parsing + security <url-parsing-security>` for details. .. versionchanged:: 3.2 Added IPv6 URL parsing capabilities. @@ -324,8 +328,14 @@ or on combining URL components into a URL string. ``#``, ``@``, or ``:`` will raise a :exc:`ValueError`. If the URL is decomposed before parsing, no error will be raised. - Following the `WHATWG spec`_ that updates RFC 3986, ASCII newline - ``\n``, ``\r`` and tab ``\t`` characters are stripped from the URL. + Following some of the `WHATWG spec`_ that updates RFC 3986, leading C0 + control and space characters are stripped from the URL. ``\n``, + ``\r`` and tab ``\t`` characters are removed from the URL at any position. + + .. warning:: + + :func:`urlsplit` does not perform validation. See :ref:`URL parsing + security <url-parsing-security>` for details. .. versionchanged:: 3.6 Out-of-range port numbers now raise :exc:`ValueError`, instead of @@ -338,6 +348,9 @@ or on combining URL components into a URL string. .. versionchanged:: 3.10 ASCII newline and tab characters are stripped from the URL. + .. versionchanged:: 3.12 + Leading WHATWG C0 control and space characters are stripped from the URL. + .. _WHATWG spec: https://url.spec.whatwg.org/#concept-basic-url-parser .. function:: urlunsplit(parts) @@ -414,6 +427,35 @@ or on combining URL components into a URL string. or ``scheme://host/path``). If *url* is not a wrapped URL, it is returned without changes. +.. _url-parsing-security: + +URL parsing security +-------------------- + +The :func:`urlsplit` and :func:`urlparse` APIs do not perform **validation** of +inputs. They may not raise errors on inputs that other applications consider +invalid. They may also succeed on some inputs that might not be considered +URLs elsewhere. Their purpose is for practical functionality rather than +purity. + +Instead of raising an exception on unusual input, they may instead return some +component parts as empty strings. Or components may contain more than perhaps +they should. + +We recommend that users of these APIs where the values may be used anywhere +with security implications code defensively. Do some verification within your +code before trusting a returned component part. Does that ``scheme`` make +sense? Is that a sensible ``path``? Is there anything strange about that +``hostname``? etc. + +What constitutes a URL is not universally well defined. Different applications +have different needs and desired constraints. For instance the living `WHATWG +spec`_ describes what user facing web clients such as a web browser require. +While :rfc:`3986` is more general. These functions incorporate some aspects of +both, but cannot be claimed compliant with either. The APIs and existing user +code with expectations on specific behaviors predate both standards leading us +to be very cautious about making API behavior changes. + .. _parsing-ascii-encoded-bytes: Parsing ASCII Encoded Bytes @@ -556,7 +598,7 @@ task isn't already covered by the URL parsing functions above. .. function:: quote(string, safe='/', encoding=None, errors=None) - Replace special characters in *string* using the ``%xx`` escape. Letters, + Replace special characters in *string* using the :samp:`%{xx}` escape. Letters, digits, and the characters ``'_.-~'`` are never quoted. By default, this function is intended for quoting the path section of a URL. The optional *safe* parameter specifies additional ASCII characters that should not be @@ -603,7 +645,7 @@ task isn't already covered by the URL parsing functions above. .. function:: unquote(string, encoding='utf-8', errors='replace') - Replace ``%xx`` escapes with their single-character equivalent. + Replace :samp:`%{xx}` escapes with their single-character equivalent. The optional *encoding* and *errors* parameters specify how to decode percent-encoded sequences into Unicode characters, as accepted by the :meth:`bytes.decode` method. @@ -634,7 +676,7 @@ task isn't already covered by the URL parsing functions above. .. function:: unquote_to_bytes(string) - Replace ``%xx`` escapes with their single-octet equivalent, and return a + Replace :samp:`%{xx}` escapes with their single-octet equivalent, and return a :class:`bytes` object. *string* may be either a :class:`str` or a :class:`bytes` object. diff --git a/Doc/library/urllib.request.rst b/Doc/library/urllib.request.rst index 59e1f2da..35b8f5b4 100644 --- a/Doc/library/urllib.request.rst +++ b/Doc/library/urllib.request.rst @@ -28,8 +28,8 @@ The :mod:`urllib.request` module defines the following functions: .. function:: urlopen(url, data=None[, timeout], *, cafile=None, capath=None, cadefault=False, context=None) - Open the URL *url*, which can be either a string or a - :class:`Request` object. + Open *url*, which can be either a string containing a valid, properly + encoded URL, or a :class:`Request` object. *data* must be an object specifying additional data to be sent to the server, or ``None`` if no such data is needed. See :class:`Request` @@ -99,7 +99,7 @@ The :mod:`urllib.request` module defines the following functions: .. versionchanged:: 3.2 HTTPS virtual hosts are now supported if possible (that is, if - :data:`ssl.HAS_SNI` is true). + :const:`ssl.HAS_SNI` is true). .. versionadded:: 3.2 *data* can be an iterable object. @@ -192,7 +192,7 @@ The following classes are provided: This class is an abstraction of a URL request. - *url* should be a string containing a valid URL. + *url* should be a string containing a valid, properly encoded URL. *data* must be an object specifying additional data to send to the server, or ``None`` if no such data is needed. Currently HTTP @@ -1630,7 +1630,7 @@ The typical response object is a :class:`urllib.response.addinfourl` instance: .. deprecated:: 3.9 Deprecated in favor of :attr:`~addinfourl.status`. - .. method:: getstatus() + .. method:: getcode() .. deprecated:: 3.9 Deprecated in favor of :attr:`~addinfourl.status`. diff --git a/Doc/library/uuid.rst b/Doc/library/uuid.rst index a71fe7ab..adf01770 100644 --- a/Doc/library/uuid.rst +++ b/Doc/library/uuid.rst @@ -22,7 +22,7 @@ random UUID. Depending on support from the underlying platform, :func:`uuid1` may or may not return a "safe" UUID. A safe UUID is one which is generated using synchronization methods that ensure no two processes can obtain the same -UUID. All instances of :class:`UUID` have an :attr:`is_safe` attribute +UUID. All instances of :class:`UUID` have an :attr:`~UUID.is_safe` attribute which relays any information about the UUID's safety, using this enumeration: .. class:: SafeUUID @@ -95,25 +95,34 @@ which relays any information about the UUID's safety, using this enumeration: A tuple of the six integer fields of the UUID, which are also available as six individual attributes and two derived attributes: - +------------------------------+-------------------------------+ - | Field | Meaning | - +==============================+===============================+ - | :attr:`time_low` | the first 32 bits of the UUID | - +------------------------------+-------------------------------+ - | :attr:`time_mid` | the next 16 bits of the UUID | - +------------------------------+-------------------------------+ - | :attr:`time_hi_version` | the next 16 bits of the UUID | - +------------------------------+-------------------------------+ - | :attr:`clock_seq_hi_variant` | the next 8 bits of the UUID | - +------------------------------+-------------------------------+ - | :attr:`clock_seq_low` | the next 8 bits of the UUID | - +------------------------------+-------------------------------+ - | :attr:`node` | the last 48 bits of the UUID | - +------------------------------+-------------------------------+ - | :attr:`time` | the 60-bit timestamp | - +------------------------------+-------------------------------+ - | :attr:`clock_seq` | the 14-bit sequence number | - +------------------------------+-------------------------------+ +.. list-table:: + + * - Field + - Meaning + + * - .. attribute:: UUID.time_low + - The first 32 bits of the UUID. + + * - .. attribute:: UUID.time_mid + - The next 16 bits of the UUID. + + * - .. attribute:: UUID.time_hi_version + - The next 16 bits of the UUID. + + * - .. attribute:: UUID.clock_seq_hi_variant + - The next 8 bits of the UUID. + + * - .. attribute:: UUID.clock_seq_low + - The next 8 bits of the UUID. + + * - .. attribute:: UUID.node + - The last 48 bits of the UUID. + + * - .. attribute:: UUID.time + - The 60-bit timestamp. + + * - .. attribute:: UUID.clock_seq + - The 14-bit sequence number. .. attribute:: UUID.hex @@ -186,7 +195,8 @@ The :mod:`uuid` module defines the following functions: .. function:: uuid3(namespace, name) Generate a UUID based on the MD5 hash of a namespace identifier (which is a - UUID) and a name (which is a string). + UUID) and a name (which is a :class:`bytes` object or a string + that will be encoded using UTF-8). .. index:: single: uuid3 @@ -201,7 +211,8 @@ The :mod:`uuid` module defines the following functions: .. function:: uuid5(namespace, name) Generate a UUID based on the SHA-1 hash of a namespace identifier (which is a - UUID) and a name (which is a string). + UUID) and a name (which is a :class:`bytes` object or a string + that will be encoded using UTF-8). .. index:: single: uuid5 @@ -231,7 +242,7 @@ The :mod:`uuid` module defines the following namespace identifiers for use with text output format. The :mod:`uuid` module defines the following constants for the possible values -of the :attr:`variant` attribute: +of the :attr:`~UUID.variant` attribute: .. data:: RESERVED_NCS @@ -261,6 +272,47 @@ of the :attr:`variant` attribute: internal format of UUIDs, and methods of generating UUIDs. +.. _uuid-cli: + +Command-Line Usage +------------------ + +.. versionadded:: 3.12 + +The :mod:`uuid` module can be executed as a script from the command line. + +.. code-block:: sh + + python -m uuid [-h] [-u {uuid1,uuid3,uuid4,uuid5}] [-n NAMESPACE] [-N NAME] + +The following options are accepted: + +.. program:: uuid + +.. cmdoption:: -h, --help + + Show the help message and exit. + +.. cmdoption:: -u <uuid> + --uuid <uuid> + + Specify the function name to use to generate the uuid. By default :func:`uuid4` + is used. + +.. cmdoption:: -n <namespace> + --namespace <namespace> + + The namespace is a ``UUID``, or ``@ns`` where ``ns`` is a well-known predefined UUID + addressed by namespace name. Such as ``@dns``, ``@url``, ``@oid``, and ``@x500``. + Only required for :func:`uuid3` / :func:`uuid5` functions. + +.. cmdoption:: -N <name> + --name <name> + + The name used as part of generating the uuid. Only required for + :func:`uuid3` / :func:`uuid5` functions. + + .. _uuid-example: Example @@ -301,3 +353,22 @@ Here are some examples of typical usage of the :mod:`uuid` module:: >>> uuid.UUID(bytes=x.bytes) UUID('00010203-0405-0607-0809-0a0b0c0d0e0f') + +.. _uuid-cli-example: + +Command-Line Example +-------------------- + +Here are some examples of typical usage of the :mod:`uuid` command line interface: + +.. code-block:: shell + + # generate a random uuid - by default uuid4() is used + $ python -m uuid + + # generate a uuid using uuid1() + $ python -m uuid -u uuid1 + + # generate a uuid using uuid5 + $ python -m uuid -u uuid5 -n @url -N example.com + diff --git a/Doc/library/venv.rst b/Doc/library/venv.rst index adc6cd33..18af1d41 100644 --- a/Doc/library/venv.rst +++ b/Doc/library/venv.rst @@ -30,6 +30,25 @@ When used from within a virtual environment, common installation tools such as `pip`_ will install Python packages into a virtual environment without needing to be told to do so explicitly. +A virtual environment is (amongst other things): + +* Used to contain a specific Python interpreter and software libraries and + binaries which are needed to support a project (library or application). These + are by default isolated from software in other virtual environments and Python + interpreters and libraries installed in the operating system. + +* Contained in a directory, conventionally either named ``venv`` or ``.venv`` in + the project directory, or under a container directory for lots of virtual + environments, such as ``~/.virtualenvs``. + +* Not checked into source control systems such as Git. + +* Considered as disposable -- it should be simple to delete and recreate it from + scratch. You don't place any project code in the environment + +* Not considered as movable or copyable -- you just recreate the same + environment in the target location. + See :pep:`405` for more background on Python virtual environments. .. seealso:: @@ -55,13 +74,13 @@ point to the directories of the virtual environment, whereas :data:`sys.base_prefix` and :data:`sys.base_exec_prefix` point to those of the base Python used to create the environment. It is sufficient to check -``sys.prefix == sys.base_prefix`` to determine if the current interpreter is +``sys.prefix != sys.base_prefix`` to determine if the current interpreter is running from a virtual environment. A virtual environment may be "activated" using a script in its binary directory (``bin`` on POSIX; ``Scripts`` on Windows). -This will prepend that directory to your :envvar:`!PATH`, so that running -:program:`!python` will invoke the environment's Python interpreter +This will prepend that directory to your :envvar:`PATH`, so that running +:program:`python` will invoke the environment's Python interpreter and you can run installed scripts without having to use their full path. The invocation of the activation script is platform-specific (:samp:`{<venv>}` must be replaced by the path to the directory @@ -84,7 +103,7 @@ containing the virtual environment): +-------------+------------+--------------------------------------------------+ .. versionadded:: 3.4 - :program:`!fish` and :program:`!csh` activation scripts. + :program:`fish` and :program:`csh` activation scripts. .. versionadded:: 3.8 PowerShell activation scripts installed under POSIX for PowerShell Core @@ -100,10 +119,10 @@ In order to achieve this, scripts installed into virtual environments have a "shebang" line which points to the environment's Python interpreter, i.e. :samp:`#!/{<path-to-venv>}/bin/python`. This means that the script will run with that interpreter regardless of the -value of :envvar:`!PATH`. On Windows, "shebang" line processing is supported if +value of :envvar:`PATH`. On Windows, "shebang" line processing is supported if you have the :ref:`launcher` installed. Thus, double-clicking an installed script in a Windows Explorer window should run it with the correct interpreter -without the environment needing to be activated or on the :envvar:`!PATH`. +without the environment needing to be activated or on the :envvar:`PATH`. When a virtual environment has been activated, the :envvar:`!VIRTUAL_ENV` environment variable is set to the path of the environment. @@ -284,11 +303,14 @@ creation according to their needs, the :class:`EnvBuilder` class. .. method:: upgrade_dependencies(context) - Upgrades the core venv dependency packages (currently ``pip`` and - ``setuptools``) in the environment. This is done by shelling out to the + Upgrades the core venv dependency packages (currently ``pip``) + in the environment. This is done by shelling out to the ``pip`` executable in the environment. .. versionadded:: 3.9 + .. versionchanged:: 3.12 + + ``setuptools`` is no longer a core venv dependency. .. method:: post_setup(context) @@ -478,7 +500,7 @@ subclass which installs setuptools and pip into a created virtual environment:: :param context: The information for the virtual environment creation request being processed. """ - url = 'https://bitbucket.org/pypa/setuptools/downloads/ez_setup.py' + url = "https://bootstrap.pypa.io/ez_setup.py" self.install_script(context, 'setuptools', url) # clear up the setuptools archive which gets downloaded pred = lambda o: o.startswith('setuptools-') and o.endswith('.tar.gz') @@ -497,76 +519,68 @@ subclass which installs setuptools and pip into a created virtual environment:: url = 'https://bootstrap.pypa.io/get-pip.py' self.install_script(context, 'pip', url) + def main(args=None): - compatible = True - if sys.version_info < (3, 3): - compatible = False - elif not hasattr(sys, 'base_prefix'): - compatible = False - if not compatible: - raise ValueError('This script is only for use with ' - 'Python 3.3 or later') + import argparse + + parser = argparse.ArgumentParser(prog=__name__, + description='Creates virtual Python ' + 'environments in one or ' + 'more target ' + 'directories.') + parser.add_argument('dirs', metavar='ENV_DIR', nargs='+', + help='A directory in which to create the ' + 'virtual environment.') + parser.add_argument('--no-setuptools', default=False, + action='store_true', dest='nodist', + help="Don't install setuptools or pip in the " + "virtual environment.") + parser.add_argument('--no-pip', default=False, + action='store_true', dest='nopip', + help="Don't install pip in the virtual " + "environment.") + parser.add_argument('--system-site-packages', default=False, + action='store_true', dest='system_site', + help='Give the virtual environment access to the ' + 'system site-packages dir.') + if os.name == 'nt': + use_symlinks = False else: - import argparse - - parser = argparse.ArgumentParser(prog=__name__, - description='Creates virtual Python ' - 'environments in one or ' - 'more target ' - 'directories.') - parser.add_argument('dirs', metavar='ENV_DIR', nargs='+', - help='A directory in which to create the ' - 'virtual environment.') - parser.add_argument('--no-setuptools', default=False, - action='store_true', dest='nodist', - help="Don't install setuptools or pip in the " - "virtual environment.") - parser.add_argument('--no-pip', default=False, - action='store_true', dest='nopip', - help="Don't install pip in the virtual " - "environment.") - parser.add_argument('--system-site-packages', default=False, - action='store_true', dest='system_site', - help='Give the virtual environment access to the ' - 'system site-packages dir.') - if os.name == 'nt': - use_symlinks = False - else: - use_symlinks = True - parser.add_argument('--symlinks', default=use_symlinks, - action='store_true', dest='symlinks', - help='Try to use symlinks rather than copies, ' - 'when symlinks are not the default for ' - 'the platform.') - parser.add_argument('--clear', default=False, action='store_true', - dest='clear', help='Delete the contents of the ' - 'virtual environment ' - 'directory if it already ' - 'exists, before virtual ' - 'environment creation.') - parser.add_argument('--upgrade', default=False, action='store_true', - dest='upgrade', help='Upgrade the virtual ' - 'environment directory to ' - 'use this version of ' - 'Python, assuming Python ' - 'has been upgraded ' - 'in-place.') - parser.add_argument('--verbose', default=False, action='store_true', - dest='verbose', help='Display the output ' - 'from the scripts which ' - 'install setuptools and pip.') - options = parser.parse_args(args) - if options.upgrade and options.clear: - raise ValueError('you cannot supply --upgrade and --clear together.') - builder = ExtendedEnvBuilder(system_site_packages=options.system_site, - clear=options.clear, - symlinks=options.symlinks, - upgrade=options.upgrade, - nodist=options.nodist, - nopip=options.nopip, - verbose=options.verbose) - for d in options.dirs: - builder.create(d) + use_symlinks = True + parser.add_argument('--symlinks', default=use_symlinks, + action='store_true', dest='symlinks', + help='Try to use symlinks rather than copies, ' + 'when symlinks are not the default for ' + 'the platform.') + parser.add_argument('--clear', default=False, action='store_true', + dest='clear', help='Delete the contents of the ' + 'virtual environment ' + 'directory if it already ' + 'exists, before virtual ' + 'environment creation.') + parser.add_argument('--upgrade', default=False, action='store_true', + dest='upgrade', help='Upgrade the virtual ' + 'environment directory to ' + 'use this version of ' + 'Python, assuming Python ' + 'has been upgraded ' + 'in-place.') + parser.add_argument('--verbose', default=False, action='store_true', + dest='verbose', help='Display the output ' + 'from the scripts which ' + 'install setuptools and pip.') + options = parser.parse_args(args) + if options.upgrade and options.clear: + raise ValueError('you cannot supply --upgrade and --clear together.') + builder = ExtendedEnvBuilder(system_site_packages=options.system_site, + clear=options.clear, + symlinks=options.symlinks, + upgrade=options.upgrade, + nodist=options.nodist, + nopip=options.nopip, + verbose=options.verbose) + for d in options.dirs: + builder.create(d) if __name__ == '__main__': rc = 1 diff --git a/Doc/library/warnings.rst b/Doc/library/warnings.rst index 28579ce8..884de08e 100644 --- a/Doc/library/warnings.rst +++ b/Doc/library/warnings.rst @@ -396,7 +396,7 @@ Available Functions ------------------- -.. function:: warn(message, category=None, stacklevel=1, source=None) +.. function:: warn(message, category=None, stacklevel=1, source=None, \*, skip_file_prefixes=None) Issue a warning, or maybe ignore it or raise an exception. The *category* argument, if given, must be a :ref:`warning category class <warning-categories>`; it @@ -407,12 +407,39 @@ Available Functions :ref:`warnings filter <warning-filter>`. The *stacklevel* argument can be used by wrapper functions written in Python, like this:: - def deprecation(message): + def deprecated_api(message): warnings.warn(message, DeprecationWarning, stacklevel=2) - This makes the warning refer to :func:`deprecation`'s caller, rather than to the - source of :func:`deprecation` itself (since the latter would defeat the purpose - of the warning message). + This makes the warning refer to ``deprecated_api``'s caller, rather than to + the source of ``deprecated_api`` itself (since the latter would defeat the + purpose of the warning message). + + The *skip_file_prefixes* keyword argument can be used to indicate which + stack frames are ignored when counting stack levels. This can be useful when + you want the warning to always appear at call sites outside of a package + when a constant *stacklevel* does not fit all call paths or is otherwise + challenging to maintain. If supplied, it must be a tuple of strings. When + prefixes are supplied, stacklevel is implicitly overridden to be ``max(2, + stacklevel)``. To cause a warning to be attributed to the caller from + outside of the current package you might write:: + + # example/lower.py + _warn_skips = (os.path.dirname(__file__),) + + def one_way(r_luxury_yacht=None, t_wobbler_mangrove=None): + if r_luxury_yacht: + warnings.warn("Please migrate to t_wobbler_mangrove=.", + skip_file_prefixes=_warn_skips) + + # example/higher.py + from . import lower + + def another_way(**kw): + lower.one_way(**kw) + + This makes the warning refer to both the ``example.lower.one_way()`` and + ``package.higher.another_way()`` call sites only from calling code living + outside of ``example`` package. *source*, if supplied, is the destroyed object which emitted a :exc:`ResourceWarning`. @@ -420,6 +447,9 @@ Available Functions .. versionchanged:: 3.6 Added *source* parameter. + .. versionchanged:: 3.12 + Added *skip_file_prefixes*. + .. function:: warn_explicit(message, category, filename, lineno, module=None, registry=None, module_globals=None, source=None) diff --git a/Doc/library/wave.rst b/Doc/library/wave.rst index d50aabd5..bb85dbe3 100644 --- a/Doc/library/wave.rst +++ b/Doc/library/wave.rst @@ -11,9 +11,14 @@ -------------- -The :mod:`wave` module provides a convenient interface to the WAV sound format. -Only files using ``WAVE_FORMAT_PCM`` are supported. Note that this does not -include files using ``WAVE_FORMAT_EXTENSIBLE`` even if the subformat is PCM. +The :mod:`wave` module provides a convenient interface to the Waveform Audio +"WAVE" (or "WAV") file format. Only uncompressed PCM encoded wave files are +supported. + +.. versionchanged:: 3.12 + + Support for ``WAVE_FORMAT_EXTENSIBLE`` headers was added, provided that the + extended format is ``KSDATAFORMAT_SUBTYPE_PCM``. The :mod:`wave` module defines the following function and exception: @@ -37,13 +42,12 @@ The :mod:`wave` module defines the following function and exception: value for *mode*. If you pass in a file-like object, the wave object will not close it when its - :meth:`close` method is called; it is the caller's responsibility to close + ``close()`` method is called; it is the caller's responsibility to close the file object. The :func:`.open` function may be used in a :keyword:`with` statement. When - the :keyword:`!with` block completes, the :meth:`Wave_read.close() - <wave.Wave_read.close>` or :meth:`Wave_write.close() - <wave.Wave_write.close()>` method is called. + the :keyword:`!with` block completes, the :meth:`Wave_read.close()` or + :meth:`Wave_write.close()` method is called. .. versionchanged:: 3.4 Added support for unseekable files. @@ -59,87 +63,91 @@ The :mod:`wave` module defines the following function and exception: Wave_read Objects ----------------- -Wave_read objects, as returned by :func:`.open`, have the following methods: +.. class:: Wave_read + + Read a WAV file. + + Wave_read objects, as returned by :func:`.open`, have the following methods: -.. method:: Wave_read.close() + .. method:: close() - Close the stream if it was opened by :mod:`wave`, and make the instance - unusable. This is called automatically on object collection. + Close the stream if it was opened by :mod:`wave`, and make the instance + unusable. This is called automatically on object collection. -.. method:: Wave_read.getnchannels() + .. method:: getnchannels() - Returns number of audio channels (``1`` for mono, ``2`` for stereo). + Returns number of audio channels (``1`` for mono, ``2`` for stereo). -.. method:: Wave_read.getsampwidth() + .. method:: getsampwidth() - Returns sample width in bytes. + Returns sample width in bytes. -.. method:: Wave_read.getframerate() + .. method:: getframerate() - Returns sampling frequency. + Returns sampling frequency. -.. method:: Wave_read.getnframes() + .. method:: getnframes() - Returns number of audio frames. + Returns number of audio frames. -.. method:: Wave_read.getcomptype() + .. method:: getcomptype() - Returns compression type (``'NONE'`` is the only supported type). + Returns compression type (``'NONE'`` is the only supported type). -.. method:: Wave_read.getcompname() + .. method:: getcompname() - Human-readable version of :meth:`getcomptype`. Usually ``'not compressed'`` - parallels ``'NONE'``. + Human-readable version of :meth:`getcomptype`. Usually ``'not compressed'`` + parallels ``'NONE'``. -.. method:: Wave_read.getparams() + .. method:: getparams() - Returns a :func:`~collections.namedtuple` ``(nchannels, sampwidth, - framerate, nframes, comptype, compname)``, equivalent to output of the - :meth:`get\*` methods. + Returns a :func:`~collections.namedtuple` ``(nchannels, sampwidth, + framerate, nframes, comptype, compname)``, equivalent to output of the + ``get*()`` methods. -.. method:: Wave_read.readframes(n) + .. method:: readframes(n) - Reads and returns at most *n* frames of audio, as a :class:`bytes` object. + Reads and returns at most *n* frames of audio, as a :class:`bytes` object. -.. method:: Wave_read.rewind() + .. method:: rewind() - Rewind the file pointer to the beginning of the audio stream. + Rewind the file pointer to the beginning of the audio stream. -The following two methods are defined for compatibility with the :mod:`aifc` -module, and don't do anything interesting. + The following two methods are defined for compatibility with the :mod:`aifc` + module, and don't do anything interesting. -.. method:: Wave_read.getmarkers() + .. method:: getmarkers() - Returns ``None``. + Returns ``None``. -.. method:: Wave_read.getmark(id) + .. method:: getmark(id) - Raise an error. + Raise an error. -The following two methods define a term "position" which is compatible between -them, and is otherwise implementation dependent. + The following two methods define a term "position" which is compatible between + them, and is otherwise implementation dependent. -.. method:: Wave_read.setpos(pos) + .. method:: setpos(pos) - Set the file pointer to the specified position. + Set the file pointer to the specified position. -.. method:: Wave_read.tell() + .. method:: tell() - Return current file pointer position. + Return current file pointer position. .. _wave-write-objects: @@ -147,97 +155,100 @@ them, and is otherwise implementation dependent. Wave_write Objects ------------------ -For seekable output streams, the ``wave`` header will automatically be updated -to reflect the number of frames actually written. For unseekable streams, the -*nframes* value must be accurate when the first frame data is written. An -accurate *nframes* value can be achieved either by calling -:meth:`~Wave_write.setnframes` or :meth:`~Wave_write.setparams` with the number -of frames that will be written before :meth:`~Wave_write.close` is called and -then using :meth:`~Wave_write.writeframesraw` to write the frame data, or by -calling :meth:`~Wave_write.writeframes` with all of the frame data to be -written. In the latter case :meth:`~Wave_write.writeframes` will calculate -the number of frames in the data and set *nframes* accordingly before writing -the frame data. +.. class:: Wave_write -Wave_write objects, as returned by :func:`.open`, have the following methods: + Write a WAV file. -.. versionchanged:: 3.4 - Added support for unseekable files. + Wave_write objects, as returned by :func:`.open`. + For seekable output streams, the ``wave`` header will automatically be updated + to reflect the number of frames actually written. For unseekable streams, the + *nframes* value must be accurate when the first frame data is written. An + accurate *nframes* value can be achieved either by calling + :meth:`setnframes` or :meth:`setparams` with the number + of frames that will be written before :meth:`close` is called and + then using :meth:`writeframesraw` to write the frame data, or by + calling :meth:`writeframes` with all of the frame data to be + written. In the latter case :meth:`writeframes` will calculate + the number of frames in the data and set *nframes* accordingly before writing + the frame data. -.. method:: Wave_write.close() + .. versionchanged:: 3.4 + Added support for unseekable files. - Make sure *nframes* is correct, and close the file if it was opened by - :mod:`wave`. This method is called upon object collection. It will raise - an exception if the output stream is not seekable and *nframes* does not - match the number of frames actually written. + Wave_write objects have the following methods: + .. method:: close() -.. method:: Wave_write.setnchannels(n) + Make sure *nframes* is correct, and close the file if it was opened by + :mod:`wave`. This method is called upon object collection. It will raise + an exception if the output stream is not seekable and *nframes* does not + match the number of frames actually written. - Set the number of channels. + .. method:: setnchannels(n) -.. method:: Wave_write.setsampwidth(n) + Set the number of channels. - Set the sample width to *n* bytes. + .. method:: setsampwidth(n) -.. method:: Wave_write.setframerate(n) + Set the sample width to *n* bytes. - Set the frame rate to *n*. - .. versionchanged:: 3.2 - A non-integral input to this method is rounded to the nearest - integer. + .. method:: setframerate(n) + Set the frame rate to *n*. -.. method:: Wave_write.setnframes(n) + .. versionchanged:: 3.2 + A non-integral input to this method is rounded to the nearest + integer. - Set the number of frames to *n*. This will be changed later if the number - of frames actually written is different (this update attempt will - raise an error if the output stream is not seekable). + .. method:: setnframes(n) -.. method:: Wave_write.setcomptype(type, name) + Set the number of frames to *n*. This will be changed later if the number + of frames actually written is different (this update attempt will + raise an error if the output stream is not seekable). - Set the compression type and description. At the moment, only compression type - ``NONE`` is supported, meaning no compression. + .. method:: setcomptype(type, name) -.. method:: Wave_write.setparams(tuple) + Set the compression type and description. At the moment, only compression type + ``NONE`` is supported, meaning no compression. - The *tuple* should be ``(nchannels, sampwidth, framerate, nframes, comptype, - compname)``, with values valid for the :meth:`set\*` methods. Sets all - parameters. + .. method:: setparams(tuple) -.. method:: Wave_write.tell() + The *tuple* should be ``(nchannels, sampwidth, framerate, nframes, comptype, + compname)``, with values valid for the ``set*()`` methods. Sets all + parameters. - Return current position in the file, with the same disclaimer for the - :meth:`Wave_read.tell` and :meth:`Wave_read.setpos` methods. + .. method:: tell() -.. method:: Wave_write.writeframesraw(data) + Return current position in the file, with the same disclaimer for the + :meth:`Wave_read.tell` and :meth:`Wave_read.setpos` methods. - Write audio frames, without correcting *nframes*. - .. versionchanged:: 3.4 - Any :term:`bytes-like object` is now accepted. + .. method:: writeframesraw(data) + Write audio frames, without correcting *nframes*. -.. method:: Wave_write.writeframes(data) + .. versionchanged:: 3.4 + Any :term:`bytes-like object` is now accepted. - Write audio frames and make sure *nframes* is correct. It will raise an - error if the output stream is not seekable and the total number of frames - that have been written after *data* has been written does not match the - previously set value for *nframes*. - .. versionchanged:: 3.4 - Any :term:`bytes-like object` is now accepted. + .. method:: writeframes(data) + Write audio frames and make sure *nframes* is correct. It will raise an + error if the output stream is not seekable and the total number of frames + that have been written after *data* has been written does not match the + previously set value for *nframes*. -Note that it is invalid to set any parameters after calling :meth:`writeframes` -or :meth:`writeframesraw`, and any attempt to do so will raise -:exc:`wave.Error`. + .. versionchanged:: 3.4 + Any :term:`bytes-like object` is now accepted. + Note that it is invalid to set any parameters after calling :meth:`writeframes` + or :meth:`writeframesraw`, and any attempt to do so will raise + :exc:`wave.Error`. diff --git a/Doc/library/weakref.rst b/Doc/library/weakref.rst index 1406b663..d6e062df 100644 --- a/Doc/library/weakref.rst +++ b/Doc/library/weakref.rst @@ -111,7 +111,7 @@ See :ref:`__slots__ documentation <slots>` for details. Exceptions raised by the callback will be noted on the standard error output, but cannot be propagated; they are handled in exactly the same way as exceptions - raised from an object's :meth:`__del__` method. + raised from an object's :meth:`~object.__del__` method. Weak references are :term:`hashable` if the *object* is hashable. They will maintain their hash value even after the *object* was deleted. If @@ -221,8 +221,7 @@ than needed. Added support for ``|`` and ``|=`` operators, as specified in :pep:`584`. :class:`WeakValueDictionary` objects have an additional method that has the -same issues as the :meth:`keyrefs` method of :class:`WeakKeyDictionary` -objects. +same issues as the :meth:`WeakKeyDictionary.keyrefs` method. .. method:: WeakValueDictionary.valuerefs() @@ -281,7 +280,7 @@ objects. Exceptions raised by finalizer callbacks during garbage collection will be shown on the standard error output, but cannot be propagated. They are handled in the same way as exceptions raised - from an object's :meth:`__del__` method or a weak reference's + from an object's :meth:`~object.__del__` method or a weak reference's callback. When the program exits, each remaining live finalizer is called @@ -523,18 +522,18 @@ is still alive. For instance obj dead or exiting -Comparing finalizers with :meth:`__del__` methods -------------------------------------------------- +Comparing finalizers with :meth:`~object.__del__` methods +--------------------------------------------------------- Suppose we want to create a class whose instances represent temporary directories. The directories should be deleted with their contents when the first of the following events occurs: * the object is garbage collected, -* the object's :meth:`remove` method is called, or +* the object's :meth:`!remove` method is called, or * the program exits. -We might try to implement the class using a :meth:`__del__` method as +We might try to implement the class using a :meth:`~object.__del__` method as follows:: class TempDir: @@ -553,12 +552,12 @@ follows:: def __del__(self): self.remove() -Starting with Python 3.4, :meth:`__del__` methods no longer prevent +Starting with Python 3.4, :meth:`~object.__del__` methods no longer prevent reference cycles from being garbage collected, and module globals are no longer forced to :const:`None` during :term:`interpreter shutdown`. So this code should work without any issues on CPython. -However, handling of :meth:`__del__` methods is notoriously implementation +However, handling of :meth:`~object.__del__` methods is notoriously implementation specific, since it depends on internal details of the interpreter's garbage collector implementation. diff --git a/Doc/library/webbrowser.rst b/Doc/library/webbrowser.rst index 734b6321..61db8042 100644 --- a/Doc/library/webbrowser.rst +++ b/Doc/library/webbrowser.rst @@ -115,13 +115,7 @@ for the controller classes, all defined in this module. +------------------------+-----------------------------------------+-------+ | ``'firefox'`` | :class:`Mozilla('mozilla')` | | +------------------------+-----------------------------------------+-------+ -| ``'netscape'`` | :class:`Mozilla('netscape')` | | -+------------------------+-----------------------------------------+-------+ -| ``'galeon'`` | :class:`Galeon('galeon')` | | -+------------------------+-----------------------------------------+-------+ -| ``'epiphany'`` | :class:`Galeon('epiphany')` | | -+------------------------+-----------------------------------------+-------+ -| ``'skipstone'`` | :class:`BackgroundBrowser('skipstone')` | | +| ``'epiphany'`` | :class:`Epiphany('epiphany')` | | +------------------------+-----------------------------------------+-------+ | ``'kfmclient'`` | :class:`Konqueror()` | \(1) | +------------------------+-----------------------------------------+-------+ @@ -129,12 +123,8 @@ for the controller classes, all defined in this module. +------------------------+-----------------------------------------+-------+ | ``'kfm'`` | :class:`Konqueror()` | \(1) | +------------------------+-----------------------------------------+-------+ -| ``'mosaic'`` | :class:`BackgroundBrowser('mosaic')` | | -+------------------------+-----------------------------------------+-------+ | ``'opera'`` | :class:`Opera()` | | +------------------------+-----------------------------------------+-------+ -| ``'grail'`` | :class:`Grail()` | | -+------------------------+-----------------------------------------+-------+ | ``'links'`` | :class:`GenericBrowser('links')` | | +------------------------+-----------------------------------------+-------+ | ``'elinks'`` | :class:`Elinks('elinks')` | | @@ -176,6 +166,11 @@ Notes: .. versionadded:: 3.3 Support for Chrome/Chromium has been added. +.. versionchanged:: 3.12 + Support for several obsolete browsers has been removed. + Removed browsers include Grail, Mosaic, Netscape, Galeon, + Skipstone, Iceape, and Firefox versions 35 and below. + .. deprecated-removed:: 3.11 3.13 :class:`MacOSX` is deprecated, use :class:`MacOSXOSAScript` instead. diff --git a/Doc/library/winreg.rst b/Doc/library/winreg.rst index 4ab67181..06bd4d87 100644 --- a/Doc/library/winreg.rst +++ b/Doc/library/winreg.rst @@ -288,7 +288,7 @@ This module offers the following functions: table (FAT) file system, the filename may not have an extension. A call to :func:`LoadKey` fails if the calling process does not have the - :const:`SE_RESTORE_PRIVILEGE` privilege. Note that privileges are different + :c:data:`!SE_RESTORE_PRIVILEGE` privilege. Note that privileges are different from permissions -- see the `RegLoadKey documentation <https://msdn.microsoft.com/en-us/library/ms724889%28v=VS.85%29.aspx>`__ for more details. @@ -414,7 +414,7 @@ This module offers the following functions: If *key* represents a key on a remote computer, the path described by *file_name* is relative to the remote computer. The caller of this method must - possess the :const:`SeBackupPrivilege` security privilege. Note that + possess the **SeBackupPrivilege** security privilege. Note that privileges are different than permissions -- see the `Conflicts Between User Rights and Permissions documentation <https://msdn.microsoft.com/en-us/library/ms724878%28v=VS.85%29.aspx>`__ @@ -536,7 +536,7 @@ This module offers the following functions: Constants ------------------ -The following constants are defined for use in many :mod:`_winreg` functions. +The following constants are defined for use in many :mod:`winreg` functions. .. _hkey-constants: @@ -745,7 +745,7 @@ All registry functions in this module return one of these objects. All registry functions in this module which accept a handle object also accept an integer, however, use of the handle object is encouraged. -Handle objects provide semantics for :meth:`__bool__` -- thus :: +Handle objects provide semantics for :meth:`~object.__bool__` -- thus :: if handle: print("Yes") diff --git a/Doc/library/winsound.rst b/Doc/library/winsound.rst index 372f792a..370c5216 100644 --- a/Doc/library/winsound.rst +++ b/Doc/library/winsound.rst @@ -24,7 +24,7 @@ provided by Windows platforms. It includes functions and several constants. .. function:: PlaySound(sound, flags) - Call the underlying :c:func:`PlaySound` function from the Platform API. The + Call the underlying :c:func:`!PlaySound` function from the Platform API. The *sound* parameter may be a filename, a system sound alias, audio data as a :term:`bytes-like object`, or ``None``. Its interpretation depends on the value of *flags*, which can be a bitwise ORed @@ -35,7 +35,7 @@ provided by Windows platforms. It includes functions and several constants. .. function:: MessageBeep(type=MB_OK) - Call the underlying :c:func:`MessageBeep` function from the Platform API. This + Call the underlying :c:func:`!MessageBeep` function from the Platform API. This plays a sound as specified in the registry. The *type* argument specifies which sound to play; possible values are ``-1``, ``MB_ICONASTERISK``, ``MB_ICONEXCLAMATION``, ``MB_ICONHAND``, ``MB_ICONQUESTION``, and ``MB_OK``, all diff --git a/Doc/library/wsgiref.rst b/Doc/library/wsgiref.rst index 75dea466..39a4c1ba 100644 --- a/Doc/library/wsgiref.rst +++ b/Doc/library/wsgiref.rst @@ -674,7 +674,7 @@ input, output, and error streams. This method is a WSGI application to generate an error page for the user. It is only invoked if an error occurs before headers are sent to the client. - This method can access the current error information using ``sys.exc_info()``, + This method can access the current error using ``sys.exception()``, and should pass that information to *start_response* when calling it (as described in the "Error Handling" section of :pep:`3333`). diff --git a/Doc/library/xml.etree.elementtree.rst b/Doc/library/xml.etree.elementtree.rst index 2fe0d2e0..54c93008 100644 --- a/Doc/library/xml.etree.elementtree.rst +++ b/Doc/library/xml.etree.elementtree.rst @@ -17,7 +17,7 @@ for parsing and creating XML data. This module will use a fast implementation whenever available. .. deprecated:: 3.3 - The :mod:`xml.etree.cElementTree` module is deprecated. + The :mod:`!xml.etree.cElementTree` module is deprecated. .. warning:: @@ -825,6 +825,8 @@ Reference Functions ^^^^^^^^^ +.. module:: xml.etree.ElementInclude + .. function:: xml.etree.ElementInclude.default_loader( href, parse, encoding=None) :module: @@ -862,6 +864,9 @@ Functions Element Objects ^^^^^^^^^^^^^^^ +.. module:: xml.etree.ElementTree + :noindex: + .. class:: Element(tag, attrib={}, **extra) Element class. This class defines the Element interface, and provides a @@ -1045,9 +1050,9 @@ Element Objects :meth:`~object.__getitem__`, :meth:`~object.__setitem__`, :meth:`~object.__len__`. - Caution: Elements with no subelements will test as ``False``. This behavior - will change in future versions. Use specific ``len(elem)`` or ``elem is - None`` test instead. :: + Caution: Elements with no subelements will test as ``False``. Testing the + truth value of an Element is deprecated and will raise an exception in + Python 3.14. Use specific ``len(elem)`` or ``elem is None`` test instead.:: element = root.find('foo') @@ -1057,6 +1062,9 @@ Element Objects if element is None: print("element not found") + .. versionchanged:: 3.12 + Testing the truth value of an Element emits :exc:`DeprecationWarning`. + Prior to Python 3.8, the serialisation order of the XML attributes of elements was artificially made predictable by sorting the attributes by their name. Based on the now guaranteed ordering of dicts, this arbitrary @@ -1212,6 +1220,7 @@ Example of changing the attribute "target" of every link in first paragraph:: [<Element 'a' at 0xb77ec2ac>, <Element 'a' at 0xb77ec1cc>] >>> for i in links: # Iterates through all found links ... i.attrib["target"] = "blank" + ... >>> tree.write("output.xhtml") .. _elementtree-qname-objects: diff --git a/Doc/library/xml.rst b/Doc/library/xml.rst index 20b0905b..1e49b656 100644 --- a/Doc/library/xml.rst +++ b/Doc/library/xml.rst @@ -73,12 +73,12 @@ decompression bomb Safe Safe Safe 1. Expat 2.4.1 and newer is not vulnerable to the "billion laughs" and "quadratic blowup" vulnerabilities. Items still listed as vulnerable due to potential reliance on system-provided libraries. Check - :data:`pyexpat.EXPAT_VERSION`. + :const:`pyexpat.EXPAT_VERSION`. 2. :mod:`xml.etree.ElementTree` doesn't expand external entities and raises a - :exc:`ParserError` when an entity occurs. + :exc:`~xml.etree.ElementTree.ParseError` when an entity occurs. 3. :mod:`xml.dom.minidom` doesn't expand external entities and simply returns the unexpanded entity verbatim. -4. :mod:`xmlrpclib` doesn't expand external entities and omits them. +4. :mod:`xmlrpc.client` doesn't expand external entities and omits them. 5. Since Python 3.7.1, external general entities are no longer processed by default. @@ -119,8 +119,8 @@ all known attack vectors with examples and references. .. _defusedxml-package: -The :mod:`defusedxml` Package ------------------------------------------------------- +The :mod:`!defusedxml` Package +------------------------------ `defusedxml`_ is a pure Python package with modified subclasses of all stdlib XML parsers that prevent any potentially malicious operation. Use of this diff --git a/Doc/library/xml.sax.handler.rst b/Doc/library/xml.sax.handler.rst index 719ce5ab..e2f28e32 100644 --- a/Doc/library/xml.sax.handler.rst +++ b/Doc/library/xml.sax.handler.rst @@ -393,7 +393,7 @@ implements this interface, then register the object with your :class:`~xml.sax.xmlreader.XMLReader`, the parser will call the methods in your object to report all warnings and errors. There are three levels of errors available: warnings, (possibly) recoverable errors, -and unrecoverable errors. All methods take a :exc:`SAXParseException` as the +and unrecoverable errors. All methods take a :exc:`~xml.sax.SAXParseException` as the only parameter. Errors and warnings may be converted to an exception by raising the passed-in exception object. diff --git a/Doc/library/xml.sax.utils.rst b/Doc/library/xml.sax.utils.rst index e46fefdf..e57e76dc 100644 --- a/Doc/library/xml.sax.utils.rst +++ b/Doc/library/xml.sax.utils.rst @@ -25,6 +25,11 @@ or as base classes. replaced with its corresponding value. The characters ``'&'``, ``'<'`` and ``'>'`` are always escaped, even if *entities* is provided. + .. note:: + + This function should only be used to escape characters that + can't be used directly in XML. Do not use this function as a general + string translation function. .. function:: unescape(data, entities={}) @@ -87,5 +92,5 @@ or as base classes. reading. The input source can be given as a string, a file-like object, or an :class:`~xml.sax.xmlreader.InputSource` object; parsers will use this function to implement the polymorphic *source* argument to their - :meth:`parse` method. + :meth:`~xml.sax.xmlreader.XMLReader.parse` method. diff --git a/Doc/library/xmlrpc.client.rst b/Doc/library/xmlrpc.client.rst index bd2c49a6..146c4fd7 100644 --- a/Doc/library/xmlrpc.client.rst +++ b/Doc/library/xmlrpc.client.rst @@ -161,7 +161,7 @@ between conformable Python objects and XML on the wire. .. seealso:: - `XML-RPC HOWTO <https://www.tldp.org/HOWTO/XML-RPC-HOWTO/index.html>`_ + `XML-RPC HOWTO <https://tldp.org/HOWTO/XML-RPC-HOWTO/index.html>`_ A good description of XML-RPC operation and client software in several languages. Contains pretty much everything an XML-RPC client developer needs to know. diff --git a/Doc/library/xmlrpc.rst b/Doc/library/xmlrpc.rst index ae68157b..5f0a2cf6 100644 --- a/Doc/library/xmlrpc.rst +++ b/Doc/library/xmlrpc.rst @@ -1,5 +1,5 @@ -:mod:`xmlrpc` --- XMLRPC server and client modules -================================================== +:mod:`!xmlrpc` --- XMLRPC server and client modules +=================================================== XML-RPC is a Remote Procedure Call method that uses XML passed via HTTP as a transport. With it, a client can call methods with parameters on a remote diff --git a/Doc/library/zipapp.rst b/Doc/library/zipapp.rst index fb40a2b3..7c01fc10 100644 --- a/Doc/library/zipapp.rst +++ b/Doc/library/zipapp.rst @@ -215,7 +215,7 @@ using the :func:`create_archive` function:: >>> import zipapp >>> zipapp.create_archive('old_archive.pyz', 'new_archive.pyz', '/usr/bin/python3') -To update the file in place, do the replacement in memory using a :class:`BytesIO` +To update the file in place, do the replacement in memory using a :class:`~io.BytesIO` object, and then overwrite the source afterwards. Note that there is a risk when overwriting a file in place that an error will result in the loss of the original file. This code does not protect against such errors, but @@ -281,12 +281,7 @@ The steps to create a standalone archive are as follows: file - if not, you can just list the dependencies manually on the pip command line). -3. Optionally, delete the ``.dist-info`` directories created by pip in the - ``myapp`` directory. These hold metadata for pip to manage the packages, and - as you won't be making any further use of pip they aren't required - - although it won't do any harm if you leave them. - -4. Package the application using: +3. Package the application using: .. code-block:: shell-session @@ -303,115 +298,18 @@ the Python interpreter registers the ``.pyz`` and ``.pyzw`` file extensions when installed. -Making a Windows executable -~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -On Windows, registration of the ``.pyz`` extension is optional, and -furthermore, there are certain places that don't recognise registered -extensions "transparently" (the simplest example is that -``subprocess.run(['myapp'])`` won't find your application - you need to -explicitly specify the extension). - -On Windows, therefore, it is often preferable to create an executable from the -zipapp. This is relatively easy, although it does require a C compiler. The -basic approach relies on the fact that zipfiles can have arbitrary data -prepended, and Windows exe files can have arbitrary data appended. So by -creating a suitable launcher and tacking the ``.pyz`` file onto the end of it, -you end up with a single-file executable that runs your application. - -A suitable launcher can be as simple as the following:: - - #define Py_LIMITED_API 1 - #include "Python.h" - - #define WIN32_LEAN_AND_MEAN - #include <windows.h> - - #ifdef WINDOWS - int WINAPI wWinMain( - HINSTANCE hInstance, /* handle to current instance */ - HINSTANCE hPrevInstance, /* handle to previous instance */ - LPWSTR lpCmdLine, /* pointer to command line */ - int nCmdShow /* show state of window */ - ) - #else - int wmain() - #endif - { - wchar_t **myargv = _alloca((__argc + 1) * sizeof(wchar_t*)); - myargv[0] = __wargv[0]; - memcpy(myargv + 1, __wargv, __argc * sizeof(wchar_t *)); - return Py_Main(__argc+1, myargv); - } - -If you define the ``WINDOWS`` preprocessor symbol, this will generate a -GUI executable, and without it, a console executable. - -To compile the executable, you can either just use the standard MSVC -command line tools, or you can take advantage of the fact that distutils -knows how to compile Python source:: - - >>> from distutils.ccompiler import new_compiler - >>> import distutils.sysconfig - >>> import sys - >>> import os - >>> from pathlib import Path - - >>> def compile(src): - >>> src = Path(src) - >>> cc = new_compiler() - >>> exe = src.stem - >>> cc.add_include_dir(distutils.sysconfig.get_python_inc()) - >>> cc.add_library_dir(os.path.join(sys.base_exec_prefix, 'libs')) - >>> # First the CLI executable - >>> objs = cc.compile([str(src)]) - >>> cc.link_executable(objs, exe) - >>> # Now the GUI executable - >>> cc.define_macro('WINDOWS') - >>> objs = cc.compile([str(src)]) - >>> cc.link_executable(objs, exe + 'w') - - >>> if __name__ == "__main__": - >>> compile("zastub.c") - -The resulting launcher uses the "Limited ABI", so it will run unchanged with -any version of Python 3.x. All it needs is for Python (``python3.dll``) to be -on the user's ``PATH``. - -For a fully standalone distribution, you can distribute the launcher with your -application appended, bundled with the Python "embedded" distribution. This -will run on any PC with the appropriate architecture (32 bit or 64 bit). - - Caveats ~~~~~~~ -There are some limitations to the process of bundling your application into -a single file. In most, if not all, cases they can be addressed without -needing major changes to your application. - -1. If your application depends on a package that includes a C extension, that - package cannot be run from a zip file (this is an OS limitation, as executable - code must be present in the filesystem for the OS loader to load it). In this - case, you can exclude that dependency from the zipfile, and either require - your users to have it installed, or ship it alongside your zipfile and add code - to your ``__main__.py`` to include the directory containing the unzipped - module in ``sys.path``. In this case, you will need to make sure to ship - appropriate binaries for your target architecture(s) (and potentially pick the - correct version to add to ``sys.path`` at runtime, based on the user's machine). - -2. If you are shipping a Windows executable as described above, you either need to - ensure that your users have ``python3.dll`` on their PATH (which is not the - default behaviour of the installer) or you should bundle your application with - the embedded distribution. - -3. The suggested launcher above uses the Python embedding API. This means that in - your application, ``sys.executable`` will be your application, and *not* a - conventional Python interpreter. Your code and its dependencies need to be - prepared for this possibility. For example, if your application uses the - :mod:`multiprocessing` module, it will need to call - :func:`multiprocessing.set_executable` to let the module know where to find the - standard Python interpreter. +If your application depends on a package that includes a C extension, that +package cannot be run from a zip file (this is an OS limitation, as executable +code must be present in the filesystem for the OS loader to load it). In this +case, you can exclude that dependency from the zipfile, and either require +your users to have it installed, or ship it alongside your zipfile and add code +to your ``__main__.py`` to include the directory containing the unzipped +module in ``sys.path``. In this case, you will need to make sure to ship +appropriate binaries for your target architecture(s) (and potentially pick the +correct version to add to ``sys.path`` at runtime, based on the user's machine). The Python Zip Application Archive Format diff --git a/Doc/library/zipfile.rst b/Doc/library/zipfile.rst index af1f2638..45f3d340 100644 --- a/Doc/library/zipfile.rst +++ b/Doc/library/zipfile.rst @@ -7,7 +7,7 @@ .. moduleauthor:: James C. Ahlstrom <jim@interet.com> .. sectionauthor:: James C. Ahlstrom <jim@interet.com> -**Source code:** :source:`Lib/zipfile.py` +**Source code:** :source:`Lib/zipfile/` -------------- @@ -55,8 +55,9 @@ The module defines the following items: .. class:: Path :noindex: - A pathlib-compatible wrapper for zip files. See section - :ref:`path-objects` for details. + Class that implements a subset of the interface provided by + :class:`pathlib.Path`, including the full + :class:`importlib.resources.abc.Traversable` interface. .. versionadded:: 3.8 @@ -127,7 +128,7 @@ The module defines the following items: Documentation on the ZIP file format by Phil Katz, the creator of the format and algorithms used. - `Info-ZIP Home Page <http://www.info-zip.org/>`_ + `Info-ZIP Home Page <https://infozip.sourceforge.net/>`_ Information about the Info-ZIP project's ZIP archive programs and development libraries. @@ -287,7 +288,7 @@ ZipFile Objects (``ZipExtFile``) is read-only and provides the following methods: :meth:`~io.BufferedIOBase.read`, :meth:`~io.IOBase.readline`, :meth:`~io.IOBase.readlines`, :meth:`~io.IOBase.seek`, - :meth:`~io.IOBase.tell`, :meth:`__iter__`, :meth:`~iterator.__next__`. + :meth:`~io.IOBase.tell`, :meth:`~container.__iter__`, :meth:`~iterator.__next__`. These objects can operate independently of the ZipFile. With ``mode='w'``, a writable file handle is returned, which supports the @@ -685,6 +686,7 @@ The :class:`PyZipFile` constructor takes the same parameters as the >>> def notests(s): ... fn = os.path.basename(s) ... return (not (fn == 'test' or fn.startswith('test_'))) + ... >>> zf.writepy('myprog', filterfunc=notests) The :meth:`writepy` method makes archives with file names like diff --git a/Doc/library/zipimport.rst b/Doc/library/zipimport.rst index fe1adcae..11d19e8c 100644 --- a/Doc/library/zipimport.rst +++ b/Doc/library/zipimport.rst @@ -74,6 +74,11 @@ zipimporter Objects :exc:`ZipImportError` is raised if *archivepath* doesn't point to a valid ZIP archive. + .. versionchanged:: 3.12 + + Methods ``find_loader()`` and ``find_module()``, deprecated in 3.10 are + now removed. Use :meth:`find_spec` instead. + .. method:: create_module(spec) Implementation of :meth:`importlib.abc.Loader.create_module` that returns @@ -89,28 +94,6 @@ zipimporter Objects .. versionadded:: 3.10 - .. method:: find_loader(fullname, path=None) - - An implementation of :meth:`importlib.abc.PathEntryFinder.find_loader`. - - .. deprecated:: 3.10 - - Use :meth:`find_spec` instead. - - - .. method:: find_module(fullname, path=None) - - Search for a module specified by *fullname*. *fullname* must be the fully - qualified (dotted) module name. It returns the zipimporter instance itself - if the module was found, or :const:`None` if it wasn't. The optional - *path* argument is ignored---it's there for compatibility with the - importer protocol. - - .. deprecated:: 3.10 - - Use :meth:`find_spec` instead. - - .. method:: find_spec(fullname, target=None) An implementation of :meth:`importlib.abc.PathEntryFinder.find_spec`. diff --git a/Doc/library/zoneinfo.rst b/Doc/library/zoneinfo.rst index d2e5619e..f8624da6 100644 --- a/Doc/library/zoneinfo.rst +++ b/Doc/library/zoneinfo.rst @@ -241,7 +241,7 @@ The following class methods are also available: .. warning:: Invoking this function may change the semantics of datetimes using - ``ZoneInfo`` in surprising ways; this modifies process-wide global state + ``ZoneInfo`` in surprising ways; this modifies module state and thus may have wide-ranging effects. Only use it if you know that you need to. diff --git a/Doc/license.rst b/Doc/license.rst index 37a3d4fa..1b209922 100644 --- a/Doc/license.rst +++ b/Doc/license.rst @@ -302,7 +302,8 @@ for third-party software incorporated in the Python distribution. Mersenne Twister ---------------- -The :mod:`_random` module includes code based on a download from +The :mod:`!_random` C extension underlying the :mod:`random` module +includes code based on a download from http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/emt19937ar.html. The following are the verbatim comments from the original code:: @@ -351,8 +352,8 @@ the verbatim comments from the original code:: Sockets ------- -The :mod:`socket` module uses the functions, :func:`getaddrinfo`, and -:func:`getnameinfo`, which are coded in separate source files from the WIDE +The :mod:`socket` module uses the functions, :c:func:`!getaddrinfo`, and +:c:func:`!getnameinfo`, which are coded in separate source files from the WIDE Project, https://www.wide.ad.jp/. :: Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -386,7 +387,8 @@ Project, https://www.wide.ad.jp/. :: Asynchronous socket services ---------------------------- -The :mod:`asynchat` and :mod:`asyncore` modules contain the following notice:: +The :mod:`!test.support.asynchat` and :mod:`!test.support.asyncore` +modules contain the following notice:: Copyright 1996 by Sam Rushing @@ -537,7 +539,7 @@ The :mod:`xmlrpc.client` module contains the following notice:: test_epoll ---------- -The :mod:`test_epoll` module contains the following notice:: +The :mod:`!test.test_epoll` module contains the following notice:: Copyright (c) 2001-2006 Twisted Matrix Laboratories. @@ -657,140 +659,192 @@ The modules :mod:`hashlib`, :mod:`posix`, :mod:`ssl`, :mod:`crypt` use the OpenSSL library for added performance if made available by the operating system. Additionally, the Windows and macOS installers for Python may include a copy of the OpenSSL libraries, so we include a copy -of the OpenSSL license here:: - - - LICENSE ISSUES - ============== - - The OpenSSL toolkit stays under a dual license, i.e. both the conditions of - the OpenSSL License and the original SSLeay license apply to the toolkit. - See below for the actual license texts. Actually both licenses are BSD-style - Open Source licenses. In case of any license issues related to OpenSSL - please contact openssl-core@openssl.org. - - OpenSSL License - --------------- - - /* ==================================================================== - * Copyright (c) 1998-2008 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - - Original SSLeay License - ----------------------- - - /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ +of the OpenSSL license here. For the OpenSSL 3.0 release, +and later releases derived from that, the Apache License v2 applies:: + + + Apache License + Version 2.0, January 2004 + https://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS expat ----- -The :mod:`pyexpat` extension is built using an included copy of the expat +The :mod:`pyexpat <xml.parsers.expat>` extension is built using an included copy of the expat sources unless the build is configured ``--with-system-expat``:: Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd @@ -819,7 +873,8 @@ sources unless the build is configured ``--with-system-expat``:: libffi ------ -The :mod:`_ctypes` extension is built using an included copy of the libffi +The :mod:`!_ctypes` C extension underlying the :mod:`ctypes` module +is built using an included copy of the libffi sources unless the build is configured ``--with-system-libffi``:: Copyright (c) 1996-2008 Red Hat, Inc and others. @@ -920,7 +975,8 @@ on the cfuhash project:: libmpdec -------- -The :mod:`_decimal` module is built using an included copy of the libmpdec +The :mod:`!_decimal` C extension underlying the :mod:`decimal` module +is built using an included copy of the libmpdec library unless the build is configured ``--with-system-libmpdec``:: Copyright (c) 2008-2020 Stefan Krah. All rights reserved. diff --git a/Doc/make.bat b/Doc/make.bat index 7ced8f92..87d8359e 100644 --- a/Doc/make.bat +++ b/Doc/make.bat @@ -1,194 +1,194 @@ -@echo off -setlocal - -pushd %~dp0 - -set this=%~n0 - -call ..\PCbuild\find_python.bat %PYTHON% - -if not defined PYTHON set PYTHON=py - -if not defined SPHINXBUILD ( - %PYTHON% -c "import sphinx" > nul 2> nul - if errorlevel 1 ( - echo Installing sphinx with %PYTHON% - %PYTHON% -m pip install -r requirements.txt - if errorlevel 1 exit /B - ) - set SPHINXBUILD=%PYTHON% -c "import sphinx.cmd.build, sys; sys.exit(sphinx.cmd.build.main())" -) - -%PYTHON% -c "import python_docs_theme" > nul 2> nul -if errorlevel 1 ( - echo Installing python-docs-theme with %PYTHON% - %PYTHON% -m pip install python-docs-theme - if errorlevel 1 exit /B -) - -if not defined BLURB ( - %PYTHON% -c "import blurb" > nul 2> nul - if errorlevel 1 ( - echo Installing blurb with %PYTHON% - rem Should have been installed with Sphinx earlier - %PYTHON% -m pip install blurb - if errorlevel 1 exit /B - ) - set BLURB=%PYTHON% -m blurb -) - -if not defined SPHINXLINT ( - %PYTHON% -c "import sphinxlint" > nul 2> nul - if errorlevel 1 ( - echo Installing sphinx-lint with %PYTHON% - rem Should have been installed with Sphinx earlier - %PYTHON% -m pip install sphinx-lint - if errorlevel 1 exit /B - ) - set SPHINXLINT=%PYTHON% -m sphinxlint -) - -if "%1" NEQ "htmlhelp" goto :skiphhcsearch -if exist "%HTMLHELP%" goto :skiphhcsearch - -rem Search for HHC in likely places -set HTMLHELP= -where hhc /q && set "HTMLHELP=hhc" && goto :skiphhcsearch -where /R ..\externals hhc > "%TEMP%\hhc.loc" 2> nul && set /P HTMLHELP= < "%TEMP%\hhc.loc" & del "%TEMP%\hhc.loc" -if not exist "%HTMLHELP%" where /R "%ProgramFiles(x86)%" hhc > "%TEMP%\hhc.loc" 2> nul && set /P HTMLHELP= < "%TEMP%\hhc.loc" & del "%TEMP%\hhc.loc" -if not exist "%HTMLHELP%" where /R "%ProgramFiles%" hhc > "%TEMP%\hhc.loc" 2> nul && set /P HTMLHELP= < "%TEMP%\hhc.loc" & del "%TEMP%\hhc.loc" -if not exist "%HTMLHELP%" ( - echo. - echo.The HTML Help Workshop was not found. Set the HTMLHELP variable - echo.to the path to hhc.exe or download and install it from - echo.http://msdn.microsoft.com/en-us/library/ms669985 - exit /B 1 -) -:skiphhcsearch - -if not defined DISTVERSION for /f "usebackq" %%v in (`%PYTHON% tools/extensions/patchlevel.py`) do set DISTVERSION=%%v - -if not defined BUILDDIR set BUILDDIR=build - -rem Targets that don't require sphinx-build -if "%1" EQU "" goto help -if "%1" EQU "help" goto help -if "%1" EQU "check" goto check -if "%1" EQU "serve" goto serve -if "%1" == "clean" ( - rmdir /q /s "%BUILDDIR%" - goto end -) - -%SPHINXBUILD% >nul 2> nul -if errorlevel 9009 ( - echo. - echo.The 'sphinx-build' command was not found. Make sure you have Sphinx - echo.installed, then set the SPHINXBUILD environment variable to point - echo.to the full path of the 'sphinx-build' executable. Alternatively you - echo.may add the Sphinx directory to PATH. - echo. - echo.If you don't have Sphinx installed, grab it from - echo.http://sphinx-doc.org/ - popd - exit /B 1 -) - -rem Targets that do require sphinx-build and have their own label -if "%1" EQU "htmlview" goto htmlview - -rem Everything else -goto build - -:help -echo.usage: %this% BUILDER [filename ...] -echo. -echo.Call %this% with the desired Sphinx builder as the first argument, e.g. -echo.``%this% html`` or ``%this% doctest``. Interesting targets that are -echo.always available include: -echo. -echo. Provided by Sphinx: -echo. html, htmlhelp, latex, text -echo. suspicious, linkcheck, changes, doctest -echo. Provided by this script: -echo. clean, check, htmlview -echo. -echo.All arguments past the first one are passed through to sphinx-build as -echo.filenames to build or are ignored. See README.rst in this directory or -echo.the documentation for your version of Sphinx for more exhaustive lists -echo.of available targets and descriptions of each. -echo. -echo.This script assumes that the SPHINXBUILD environment variable contains -echo.a legitimate command for calling sphinx-build, or that sphinx-build is -echo.on your PATH if SPHINXBUILD is not set. Options for sphinx-build can -echo.be passed by setting the SPHINXOPTS environment variable. -goto end - -:build -if not exist "%BUILDDIR%" mkdir "%BUILDDIR%" - -rem PY_MISC_NEWS_DIR is also used by our Sphinx extension in tools/extensions/pyspecific.py -if not defined PY_MISC_NEWS_DIR set PY_MISC_NEWS_DIR=%BUILDDIR%\%1 -if not exist "%PY_MISC_NEWS_DIR%" mkdir "%PY_MISC_NEWS_DIR%" -if exist ..\Misc\NEWS ( - echo.Copying Misc\NEWS to %PY_MISC_NEWS_DIR%\NEWS - copy ..\Misc\NEWS "%PY_MISC_NEWS_DIR%\NEWS" > nul -) else if exist ..\Misc\NEWS.D ( - if defined BLURB ( - echo.Merging Misc/NEWS with %BLURB% - %BLURB% merge -f "%PY_MISC_NEWS_DIR%\NEWS" - ) else ( - echo.No Misc/NEWS file and Blurb is not available. - exit /B 1 - ) -) - -if defined PAPER ( - set SPHINXOPTS=-D latex_elements.papersize=%PAPER% %SPHINXOPTS% -) -if "%1" EQU "htmlhelp" ( - set SPHINXOPTS=-D html_theme_options.body_max_width=none %SPHINXOPTS% -) -cmd /S /C "%SPHINXBUILD% %SPHINXOPTS% -b%1 -dbuild\doctrees . "%BUILDDIR%\%1" %2 %3 %4 %5 %6 %7 %8 %9" - -if "%1" EQU "htmlhelp" ( - "%HTMLHELP%" "%BUILDDIR%\htmlhelp\python%DISTVERSION:.=%.hhp" - rem hhc.exe seems to always exit with code 1, reset to 0 for less than 2 - if not errorlevel 2 cmd /C exit /b 0 -) - -echo. -if errorlevel 1 ( - echo.Build failed (exit code %ERRORLEVEL%^), check for error messages - echo.above. Any output will be found in %BUILDDIR%\%1 -) else ( - echo.Build succeeded. All output should be in %BUILDDIR%\%1 -) -goto end - -:htmlview -if NOT "%2" EQU "" ( - echo.Can't specify filenames to build with htmlview target, ignoring. -) -cmd /C %this% html - -if EXIST "%BUILDDIR%\html\index.html" ( - echo.Opening "%BUILDDIR%\html\index.html" in the default web browser... - start "" "%BUILDDIR%\html\index.html" -) - -goto end - -:check -rem Check the docs and NEWS files with sphinx-lint. -rem Ignore the tools dir and check that the default role is not used. -cmd /S /C "%SPHINXLINT% -i tools --enable default-role" -cmd /S /C "%SPHINXLINT% --enable default-role ..\Misc\NEWS.d\next\ " -goto end - -:serve -echo.The serve target was removed, use htmlview instead (see bpo-36329) -goto end - -:end -popd +@echo off +setlocal + +pushd %~dp0 + +set this=%~n0 + +call ..\PCbuild\find_python.bat %PYTHON% + +if not defined PYTHON set PYTHON=py + +if not defined SPHINXBUILD ( + %PYTHON% -c "import sphinx" > nul 2> nul + if errorlevel 1 ( + echo Installing sphinx with %PYTHON% + %PYTHON% -m pip install -r requirements.txt + if errorlevel 1 exit /B + ) + set SPHINXBUILD=%PYTHON% -c "import sphinx.cmd.build, sys; sys.exit(sphinx.cmd.build.main())" +) + +%PYTHON% -c "import python_docs_theme" > nul 2> nul +if errorlevel 1 ( + echo Installing python-docs-theme with %PYTHON% + %PYTHON% -m pip install python-docs-theme + if errorlevel 1 exit /B +) + +if not defined BLURB ( + %PYTHON% -c "import blurb" > nul 2> nul + if errorlevel 1 ( + echo Installing blurb with %PYTHON% + rem Should have been installed with Sphinx earlier + %PYTHON% -m pip install blurb + if errorlevel 1 exit /B + ) + set BLURB=%PYTHON% -m blurb +) + +if not defined SPHINXLINT ( + %PYTHON% -c "import sphinxlint" > nul 2> nul + if errorlevel 1 ( + echo Installing sphinx-lint with %PYTHON% + rem Should have been installed with Sphinx earlier + %PYTHON% -m pip install sphinx-lint + if errorlevel 1 exit /B + ) + set SPHINXLINT=%PYTHON% -m sphinxlint +) + +if "%1" NEQ "htmlhelp" goto :skiphhcsearch +if exist "%HTMLHELP%" goto :skiphhcsearch + +rem Search for HHC in likely places +set HTMLHELP= +where hhc /q && set "HTMLHELP=hhc" && goto :skiphhcsearch +where /R ..\externals hhc > "%TEMP%\hhc.loc" 2> nul && set /P HTMLHELP= < "%TEMP%\hhc.loc" & del "%TEMP%\hhc.loc" +if not exist "%HTMLHELP%" where /R "%ProgramFiles(x86)%" hhc > "%TEMP%\hhc.loc" 2> nul && set /P HTMLHELP= < "%TEMP%\hhc.loc" & del "%TEMP%\hhc.loc" +if not exist "%HTMLHELP%" where /R "%ProgramFiles%" hhc > "%TEMP%\hhc.loc" 2> nul && set /P HTMLHELP= < "%TEMP%\hhc.loc" & del "%TEMP%\hhc.loc" +if not exist "%HTMLHELP%" ( + echo. + echo.The HTML Help Workshop was not found. Set the HTMLHELP variable + echo.to the path to hhc.exe or download and install it from + echo.http://msdn.microsoft.com/en-us/library/ms669985 + exit /B 1 +) +:skiphhcsearch + +if not defined DISTVERSION for /f "usebackq" %%v in (`%PYTHON% tools/extensions/patchlevel.py`) do set DISTVERSION=%%v + +if not defined BUILDDIR set BUILDDIR=build + +rem Targets that don't require sphinx-build +if "%1" EQU "" goto help +if "%1" EQU "help" goto help +if "%1" EQU "check" goto check +if "%1" EQU "serve" goto serve +if "%1" == "clean" ( + rmdir /q /s "%BUILDDIR%" + goto end +) + +%SPHINXBUILD% >nul 2> nul +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + popd + exit /B 1 +) + +rem Targets that do require sphinx-build and have their own label +if "%1" EQU "htmlview" goto htmlview + +rem Everything else +goto build + +:help +echo.usage: %this% BUILDER [filename ...] +echo. +echo.Call %this% with the desired Sphinx builder as the first argument, e.g. +echo.``%this% html`` or ``%this% doctest``. Interesting targets that are +echo.always available include: +echo. +echo. Provided by Sphinx: +echo. html, htmlhelp, latex, text +echo. linkcheck, changes, doctest +echo. Provided by this script: +echo. clean, check, htmlview +echo. +echo.All arguments past the first one are passed through to sphinx-build as +echo.filenames to build or are ignored. See README.rst in this directory or +echo.the documentation for your version of Sphinx for more exhaustive lists +echo.of available targets and descriptions of each. +echo. +echo.This script assumes that the SPHINXBUILD environment variable contains +echo.a legitimate command for calling sphinx-build, or that sphinx-build is +echo.on your PATH if SPHINXBUILD is not set. Options for sphinx-build can +echo.be passed by setting the SPHINXOPTS environment variable. +goto end + +:build +if not exist "%BUILDDIR%" mkdir "%BUILDDIR%" + +rem PY_MISC_NEWS_DIR is also used by our Sphinx extension in tools/extensions/pyspecific.py +if not defined PY_MISC_NEWS_DIR set PY_MISC_NEWS_DIR=%BUILDDIR%\%1 +if not exist "%PY_MISC_NEWS_DIR%" mkdir "%PY_MISC_NEWS_DIR%" +if exist ..\Misc\NEWS ( + echo.Copying Misc\NEWS to %PY_MISC_NEWS_DIR%\NEWS + copy ..\Misc\NEWS "%PY_MISC_NEWS_DIR%\NEWS" > nul +) else if exist ..\Misc\NEWS.D ( + if defined BLURB ( + echo.Merging Misc/NEWS with %BLURB% + %BLURB% merge -f "%PY_MISC_NEWS_DIR%\NEWS" + ) else ( + echo.No Misc/NEWS file and Blurb is not available. + exit /B 1 + ) +) + +if defined PAPER ( + set SPHINXOPTS=-D latex_elements.papersize=%PAPER% %SPHINXOPTS% +) +if "%1" EQU "htmlhelp" ( + set SPHINXOPTS=-D html_theme_options.body_max_width=none %SPHINXOPTS% +) +cmd /S /C "%SPHINXBUILD% %SPHINXOPTS% -b%1 -dbuild\doctrees . "%BUILDDIR%\%1" %2 %3 %4 %5 %6 %7 %8 %9" + +if "%1" EQU "htmlhelp" ( + "%HTMLHELP%" "%BUILDDIR%\htmlhelp\python%DISTVERSION:.=%.hhp" + rem hhc.exe seems to always exit with code 1, reset to 0 for less than 2 + if not errorlevel 2 cmd /C exit /b 0 +) + +echo. +if errorlevel 1 ( + echo.Build failed (exit code %ERRORLEVEL%^), check for error messages + echo.above. Any output will be found in %BUILDDIR%\%1 +) else ( + echo.Build succeeded. All output should be in %BUILDDIR%\%1 +) +goto end + +:htmlview +if NOT "%2" EQU "" ( + echo.Can't specify filenames to build with htmlview target, ignoring. +) +cmd /C %this% html + +if EXIST "%BUILDDIR%\html\index.html" ( + echo.Opening "%BUILDDIR%\html\index.html" in the default web browser... + start "" "%BUILDDIR%\html\index.html" +) + +goto end + +:check +rem Check the docs and NEWS files with sphinx-lint. +rem Ignore the tools dir and check that the default role is not used. +cmd /S /C "%SPHINXLINT% -i tools --enable default-role" +cmd /S /C "%SPHINXLINT% --enable default-role ..\Misc\NEWS.d\next\ " +goto end + +:serve +echo.The serve target was removed, use htmlview instead (see bpo-36329) +goto end + +:end +popd diff --git a/Doc/reference/compound_stmts.rst b/Doc/reference/compound_stmts.rst index d5cb2899..12ad18d4 100644 --- a/Doc/reference/compound_stmts.rst +++ b/Doc/reference/compound_stmts.rst @@ -84,9 +84,9 @@ The :keyword:`!if` statement ============================ .. index:: - ! statement: if - keyword: elif - keyword: else + ! pair: statement; if + pair: keyword; elif + pair: keyword; else single: : (colon); compound statement The :keyword:`if` statement is used for conditional execution: @@ -109,8 +109,8 @@ The :keyword:`!while` statement =============================== .. index:: - ! statement: while - keyword: else + ! pair: statement; while + pair: keyword; else pair: loop; statement single: : (colon); compound statement @@ -127,8 +127,8 @@ suite of the :keyword:`!else` clause, if present, is executed and the loop terminates. .. index:: - statement: break - statement: continue + pair: statement; break + pair: statement; continue A :keyword:`break` statement executed in the first suite terminates the loop without executing the :keyword:`!else` clause's suite. A :keyword:`continue` @@ -142,12 +142,12 @@ The :keyword:`!for` statement ============================= .. index:: - ! statement: for - keyword: in - keyword: else + ! pair: statement; for + pair: keyword; in + pair: keyword; else pair: target; list pair: loop; statement - object: sequence + pair: object; sequence single: : (colon); compound statement The :keyword:`for` statement is used to iterate over the elements of a sequence @@ -167,8 +167,8 @@ the suite in the :keyword:`!else` clause, if present, is executed, and the loop terminates. .. index:: - statement: break - statement: continue + pair: statement; break + pair: statement; continue A :keyword:`break` statement executed in the first suite terminates the loop without executing the :keyword:`!else` clause's suite. A :keyword:`continue` @@ -188,7 +188,7 @@ those made in the suite of the for-loop:: .. index:: - builtin: range + pair: built-in function; range Names in the target list are not deleted when the loop is finished, but if the sequence is empty, they will not have been assigned to at all by the loop. Hint: @@ -205,11 +205,11 @@ The :keyword:`!try` statement ============================= .. index:: - ! statement: try - keyword: except - keyword: finally - keyword: else - keyword: as + ! pair: statement; try + pair: keyword; except + pair: keyword; finally + pair: keyword; else + pair: keyword; as single: : (colon); compound statement The :keyword:`!try` statement specifies exception handlers and/or cleanup code @@ -297,39 +297,36 @@ traceback attached to them, they form a reference cycle with the stack frame, keeping all locals in that frame alive until the next garbage collection occurs. .. index:: - module: sys - object: traceback + pair: module; sys + pair: object; traceback Before an :keyword:`!except` clause's suite is executed, -details about the exception are -stored in the :mod:`sys` module and can be accessed via :func:`sys.exc_info`. -:func:`sys.exc_info` returns a 3-tuple consisting of the exception class, the -exception instance and a traceback object (see section :ref:`types`) identifying -the point in the program where the exception occurred. The details about the -exception accessed via :func:`sys.exc_info` are restored to their previous values -when leaving an exception handler:: - - >>> print(sys.exc_info()) - (None, None, None) +the exception is stored in the :mod:`sys` module, where it can be accessed +from within the body of the :keyword:`!except` clause by calling +:func:`sys.exception`. When leaving an exception handler, the exception +stored in the :mod:`sys` module is reset to its previous value:: + + >>> print(sys.exception()) + None >>> try: ... raise TypeError ... except: - ... print(sys.exc_info()) + ... print(repr(sys.exception())) ... try: ... raise ValueError ... except: - ... print(sys.exc_info()) - ... print(sys.exc_info()) + ... print(repr(sys.exception())) + ... print(repr(sys.exception())) ... - (<class 'TypeError'>, TypeError(), <traceback object at 0x10efad080>) - (<class 'ValueError'>, ValueError(), <traceback object at 0x10efad040>) - (<class 'TypeError'>, TypeError(), <traceback object at 0x10efad080>) - >>> print(sys.exc_info()) - (None, None, None) + TypeError() + ValueError() + TypeError() + >>> print(sys.exception()) + None .. index:: - keyword: except_star + pair: keyword; except_star .. _except_star: @@ -365,8 +362,10 @@ one :keyword:`!except*` clause, the first that matches it. :: Any remaining exceptions that were not handled by any :keyword:`!except*` -clause are re-raised at the end, combined into an exception group along with -all exceptions that were raised from within :keyword:`!except*` clauses. +clause are re-raised at the end, along with all exceptions that were +raised from within the :keyword:`!except*` clauses. If this list contains +more than one exception to reraise, they are combined into an exception +group. If the raised exception is not an exception group and its type matches one of the :keyword:`!except*` clauses, it is caught and wrapped by an @@ -388,10 +387,10 @@ cannot appear in an :keyword:`!except*` clause. .. index:: - keyword: else - statement: return - statement: break - statement: continue + pair: keyword; else + pair: statement; return + pair: statement; break + pair: statement; continue .. _except_else: @@ -405,7 +404,7 @@ the :keyword:`!else` clause are not handled by the preceding :keyword:`except` clauses. -.. index:: keyword: finally +.. index:: pair: keyword; finally .. _finally: @@ -435,9 +434,9 @@ The exception information is not available to the program during execution of the :keyword:`!finally` clause. .. index:: - statement: return - statement: break - statement: continue + pair: statement; return + pair: statement; break + pair: statement; continue When a :keyword:`return`, :keyword:`break` or :keyword:`continue` statement is executed in the :keyword:`try` suite of a :keyword:`!try`...\ :keyword:`!finally` @@ -469,8 +468,8 @@ The :keyword:`!with` statement ============================== .. index:: - ! statement: with - keyword: as + ! pair: statement; with + pair: keyword; as single: as; with statement single: , (comma); with statement single: : (colon); compound statement @@ -586,11 +585,11 @@ The :keyword:`!match` statement =============================== .. index:: - ! statement: match - ! keyword: case + ! pair: statement; match + ! pair: keyword; case ! single: pattern matching - keyword: if - keyword: as + pair: keyword; if + pair: keyword; as pair: match; case single: as; match statement single: : (colon); compound statement @@ -819,7 +818,7 @@ keyword against a subject. Syntax: If the OR pattern fails, the AS pattern fails. Otherwise, the AS pattern binds the subject to the name on the right of the as keyword and succeeds. -``capture_pattern`` cannot be a a ``_``. +``capture_pattern`` cannot be a ``_``. In simple terms ``P as NAME`` will match with ``P``, and on success it will set ``NAME = <subject>``. @@ -1191,12 +1190,12 @@ Function definitions ==================== .. index:: - statement: def + pair: statement; def pair: function; definition pair: function; name pair: name; binding - object: user-defined function - object: function + pair: object; user-defined function + pair: object; function pair: function; name pair: name; binding single: () (parentheses); function definition @@ -1207,7 +1206,7 @@ A function definition defines a user-defined function object (see section :ref:`types`): .. productionlist:: python-grammar - funcdef: [`decorators`] "def" `funcname` "(" [`parameter_list`] ")" + funcdef: [`decorators`] "def" `funcname` [`type_params`] "(" [`parameter_list`] ")" : ["->" `expression`] ":" `suite` decorators: `decorator`+ decorator: "@" `assignment_expression` NEWLINE @@ -1257,6 +1256,15 @@ except that the original function is not temporarily bound to the name ``func``. :token:`~python-grammar:assignment_expression`. Previously, the grammar was much more restrictive; see :pep:`614` for details. +A list of :ref:`type parameters <type-params>` may be given in square brackets +between the function's name and the opening parenthesis for its parameter list. +This indicates to static type checkers that the function is generic. At runtime, +the type parameters can be retrieved from the function's ``__type_params__`` +attribute. See :ref:`generic-functions` for more. + +.. versionchanged:: 3.12 + Type parameter lists are new in Python 3.12. + .. index:: triple: default; parameter; value single: argument; function definition @@ -1364,8 +1372,8 @@ Class definitions ================= .. index:: - object: class - statement: class + pair: object; class + pair: statement; class pair: class; definition pair: class; name pair: name; binding @@ -1379,7 +1387,7 @@ Class definitions A class definition defines a class object (see section :ref:`types`): .. productionlist:: python-grammar - classdef: [`decorators`] "class" `classname` [`inheritance`] ":" `suite` + classdef: [`decorators`] "class" `classname` [`type_params`] [`inheritance`] ":" `suite` inheritance: "(" [`argument_list`] ")" classname: `identifier` @@ -1435,6 +1443,15 @@ decorators. The result is then bound to the class name. :token:`~python-grammar:assignment_expression`. Previously, the grammar was much more restrictive; see :pep:`614` for details. +A list of :ref:`type parameters <type-params>` may be given in square brackets +immediately after the class's name. +This indicates to static type checkers that the class is generic. At runtime, +the type parameters can be retrieved from the class's ``__type_params__`` +attribute. See :ref:`generic-classes` for more. + +.. versionchanged:: 3.12 + Type parameter lists are new in Python 3.12. + **Programmer's note:** Variables defined in the class definition are class attributes; they are shared by instances. Instance attributes can be set in a method with ``self.name = value``. Both class and instance attributes are @@ -1464,7 +1481,7 @@ Coroutines .. versionadded:: 3.5 -.. index:: statement: async def +.. index:: pair: statement; async def .. _`async def`: Coroutine function definition @@ -1475,8 +1492,8 @@ Coroutine function definition : ["->" `expression`] ":" `suite` .. index:: - keyword: async - keyword: await + pair: keyword; async + pair: keyword; await Execution of Python coroutines can be suspended and resumed at many points (see :term:`coroutine`). :keyword:`await` expressions, :keyword:`async for` and @@ -1498,7 +1515,7 @@ An example of a coroutine function:: ``await`` and ``async`` are now keywords; previously they were only treated as such inside the body of a coroutine function. -.. index:: statement: async for +.. index:: pair: statement; async for .. _`async for`: The :keyword:`!async for` statement @@ -1543,7 +1560,7 @@ It is a :exc:`SyntaxError` to use an ``async for`` statement outside the body of a coroutine function. -.. index:: statement: async with +.. index:: pair: statement; async with .. _`async with`: The :keyword:`!async with` statement @@ -1590,6 +1607,228 @@ body of a coroutine function. The proposal that made coroutines a proper standalone concept in Python, and added supporting syntax. +.. _type-params: + +Type parameter lists +==================== + +.. versionadded:: 3.12 + +.. index:: + single: type parameters + +.. productionlist:: python-grammar + type_params: "[" `type_param` ("," `type_param`)* "]" + type_param: `typevar` | `typevartuple` | `paramspec` + typevar: `identifier` (":" `expression`)? + typevartuple: "*" `identifier` + paramspec: "**" `identifier` + +:ref:`Functions <def>` (including :ref:`coroutines <async def>`), +:ref:`classes <class>` and :ref:`type aliases <type>` may +contain a type parameter list:: + + def max[T](args: list[T]) -> T: + ... + + async def amax[T](args: list[T]) -> T: + ... + + class Bag[T]: + def __iter__(self) -> Iterator[T]: + ... + + def add(self, arg: T) -> None: + ... + + type ListOrSet[T] = list[T] | set[T] + +Semantically, this indicates that the function, class, or type alias is +generic over a type variable. This information is primarily used by static +type checkers, and at runtime, generic objects behave much like their +non-generic counterparts. + +Type parameters are declared in square brackets (``[]``) immediately +after the name of the function, class, or type alias. The type parameters +are accessible within the scope of the generic object, but not elsewhere. +Thus, after a declaration ``def func[T](): pass``, the name ``T`` is not available in +the module scope. Below, the semantics of generic objects are described +with more precision. The scope of type parameters is modeled with a special +function (technically, an :ref:`annotation scope <annotation-scopes>`) that +wraps the creation of the generic object. + +Generic functions, classes, and type aliases have a :attr:`!__type_params__` +attribute listing their type parameters. + +Type parameters come in three kinds: + +* :data:`typing.TypeVar`, introduced by a plain name (e.g., ``T``). Semantically, this + represents a single type to a type checker. +* :data:`typing.TypeVarTuple`, introduced by a name prefixed with a single + asterisk (e.g., ``*Ts``). Semantically, this stands for a tuple of any + number of types. +* :data:`typing.ParamSpec`, introduced by a name prefixed with two asterisks + (e.g., ``**P``). Semantically, this stands for the parameters of a callable. + +:data:`typing.TypeVar` declarations can define *bounds* and *constraints* with +a colon (``:``) followed by an expression. A single expression after the colon +indicates a bound (e.g. ``T: int``). Semantically, this means +that the :data:`!typing.TypeVar` can only represent types that are a subtype of +this bound. A parenthesized tuple of expressions after the colon indicates a +set of constraints (e.g. ``T: (str, bytes)``). Each member of the tuple should be a +type (again, this is not enforced at runtime). Constrained type variables can only +take on one of the types in the list of constraints. + +For :data:`!typing.TypeVar`\ s declared using the type parameter list syntax, +the bound and constraints are not evaluated when the generic object is created, +but only when the value is explicitly accessed through the attributes ``__bound__`` +and ``__constraints__``. To accomplish this, the bounds or constraints are +evaluated in a separate :ref:`annotation scope <annotation-scopes>`. + +:data:`typing.TypeVarTuple`\ s and :data:`typing.ParamSpec`\ s cannot have bounds +or constraints. + +The following example indicates the full set of allowed type parameter declarations:: + + def overly_generic[ + SimpleTypeVar, + TypeVarWithBound: int, + TypeVarWithConstraints: (str, bytes), + *SimpleTypeVarTuple, + **SimpleParamSpec, + ]( + a: SimpleTypeVar, + b: TypeVarWithBound, + c: Callable[SimpleParamSpec, TypeVarWithConstraints], + *d: SimpleTypeVarTuple, + ): ... + +.. _generic-functions: + +Generic functions +----------------- + +Generic functions are declared as follows:: + + def func[T](arg: T): ... + +This syntax is equivalent to:: + + annotation-def TYPE_PARAMS_OF_func(): + T = typing.TypeVar("T") + def func(arg: T): ... + func.__type_params__ = (T,) + return func + func = TYPE_PARAMS_OF_func() + +Here ``annotation-def`` indicates an :ref:`annotation scope <annotation-scopes>`, +which is not actually bound to any name at runtime. (One +other liberty is taken in the translation: the syntax does not go through +attribute access on the :mod:`typing` module, but creates an instance of +:data:`typing.TypeVar` directly.) + +The annotations of generic functions are evaluated within the annotation scope +used for declaring the type parameters, but the function's defaults and +decorators are not. + +The following example illustrates the scoping rules for these cases, +as well as for additional flavors of type parameters:: + + @decorator + def func[T: int, *Ts, **P](*args: *Ts, arg: Callable[P, T] = some_default): + ... + +Except for the :ref:`lazy evaluation <lazy-evaluation>` of the +:class:`~typing.TypeVar` bound, this is equivalent to:: + + DEFAULT_OF_arg = some_default + + annotation-def TYPE_PARAMS_OF_func(): + + annotation-def BOUND_OF_T(): + return int + # In reality, BOUND_OF_T() is evaluated only on demand. + T = typing.TypeVar("T", bound=BOUND_OF_T()) + + Ts = typing.TypeVarTuple("Ts") + P = typing.ParamSpec("P") + + def func(*args: *Ts, arg: Callable[P, T] = DEFAULT_OF_arg): + ... + + func.__type_params__ = (T, Ts, P) + return func + func = decorator(TYPE_PARAMS_OF_func()) + +The capitalized names like ``DEFAULT_OF_arg`` are not actually +bound at runtime. + +.. _generic-classes: + +Generic classes +--------------- + +Generic classes are declared as follows:: + + class Bag[T]: ... + +This syntax is equivalent to:: + + annotation-def TYPE_PARAMS_OF_Bag(): + T = typing.TypeVar("T") + class Bag(typing.Generic[T]): + __type_params__ = (T,) + ... + return Bag + Bag = TYPE_PARAMS_OF_Bag() + +Here again ``annotation-def`` (not a real keyword) indicates an +:ref:`annotation scope <annotation-scopes>`, and the name +``TYPE_PARAMS_OF_Bag`` is not actually bound at runtime. + +Generic classes implicitly inherit from :data:`typing.Generic`. +The base classes and keyword arguments of generic classes are +evaluated within the type scope for the type parameters, +and decorators are evaluated outside that scope. This is illustrated +by this example:: + + @decorator + class Bag(Base[T], arg=T): ... + +This is equivalent to:: + + annotation-def TYPE_PARAMS_OF_Bag(): + T = typing.TypeVar("T") + class Bag(Base[T], typing.Generic[T], arg=T): + __type_params__ = (T,) + ... + return Bag + Bag = decorator(TYPE_PARAMS_OF_Bag()) + +.. _generic-type-aliases: + +Generic type aliases +-------------------- + +The :keyword:`type` statement can also be used to create a generic type alias:: + + type ListOrSet[T] = list[T] | set[T] + +Except for the :ref:`lazy evaluation <lazy-evaluation>` of the value, +this is equivalent to:: + + annotation-def TYPE_PARAMS_OF_ListOrSet(): + T = typing.TypeVar("T") + + annotation-def VALUE_OF_ListOrSet(): + return list[T] | set[T] + # In reality, the value is lazily evaluated + return typing.TypeAliasType("ListOrSet", VALUE_OF_ListOrSet(), type_params=(T,)) + ListOrSet = TYPE_PARAMS_OF_ListOrSet() + +Here, ``annotation-def`` (not a real keyword) indicates an +:ref:`annotation scope <annotation-scopes>`. The capitalized names +like ``TYPE_PARAMS_OF_ListOrSet`` are not actually bound at runtime. .. rubric:: Footnotes @@ -1601,7 +1840,7 @@ body of a coroutine function. * a class that inherits from :class:`collections.abc.Sequence` * a Python class that has been registered as :class:`collections.abc.Sequence` - * a builtin class that has its (CPython) :data:`Py_TPFLAGS_SEQUENCE` bit set + * a builtin class that has its (CPython) :c:macro:`Py_TPFLAGS_SEQUENCE` bit set * a class that inherits from any of the above The following standard library classes are sequences: @@ -1620,7 +1859,7 @@ body of a coroutine function. * a class that inherits from :class:`collections.abc.Mapping` * a Python class that has been registered as :class:`collections.abc.Mapping` - * a builtin class that has its (CPython) :data:`Py_TPFLAGS_MAPPING` bit set + * a builtin class that has its (CPython) :c:macro:`Py_TPFLAGS_MAPPING` bit set * a class that inherits from any of the above The standard library classes :class:`dict` and :class:`types.MappingProxyType` diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst index afd4a547..362ac752 100644 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -21,8 +21,8 @@ conformance to Von Neumann's model of a "stored program computer", code is also represented by objects.) .. index:: - builtin: id - builtin: type + pair: built-in function; id + pair: built-in function; type single: identity of an object single: value of an object single: type of an object @@ -141,1081 +141,1201 @@ Some of the type descriptions below contain a paragraph listing 'special attributes.' These are attributes that provide access to the implementation and are not intended for general use. Their definition may change in the future. + None - .. index:: object: None +---- + +.. index:: pair: object; None + +This type has a single value. There is a single object with this value. This +object is accessed through the built-in name ``None``. It is used to signify the +absence of a value in many situations, e.g., it is returned from functions that +don't explicitly return anything. Its truth value is false. - This type has a single value. There is a single object with this value. This - object is accessed through the built-in name ``None``. It is used to signify the - absence of a value in many situations, e.g., it is returned from functions that - don't explicitly return anything. Its truth value is false. NotImplemented - .. index:: object: NotImplemented +-------------- + +.. index:: pair: object; NotImplemented - This type has a single value. There is a single object with this value. This - object is accessed through the built-in name ``NotImplemented``. Numeric methods - and rich comparison methods should return this value if they do not implement the - operation for the operands provided. (The interpreter will then try the - reflected operation, or some other fallback, depending on the operator.) It - should not be evaluated in a boolean context. +This type has a single value. There is a single object with this value. This +object is accessed through the built-in name ``NotImplemented``. Numeric methods +and rich comparison methods should return this value if they do not implement the +operation for the operands provided. (The interpreter will then try the +reflected operation, or some other fallback, depending on the operator.) It +should not be evaluated in a boolean context. - See - :ref:`implementing-the-arithmetic-operations` - for more details. +See +:ref:`implementing-the-arithmetic-operations` +for more details. - .. versionchanged:: 3.9 - Evaluating ``NotImplemented`` in a boolean context is deprecated. While - it currently evaluates as true, it will emit a :exc:`DeprecationWarning`. - It will raise a :exc:`TypeError` in a future version of Python. +.. versionchanged:: 3.9 + Evaluating ``NotImplemented`` in a boolean context is deprecated. While + it currently evaluates as true, it will emit a :exc:`DeprecationWarning`. + It will raise a :exc:`TypeError` in a future version of Python. Ellipsis - .. index:: - object: Ellipsis - single: ...; ellipsis literal +-------- +.. index:: + pair: object; Ellipsis + single: ...; ellipsis literal + +This type has a single value. There is a single object with this value. This +object is accessed through the literal ``...`` or the built-in name +``Ellipsis``. Its truth value is true. - This type has a single value. There is a single object with this value. This - object is accessed through the literal ``...`` or the built-in name - ``Ellipsis``. Its truth value is true. :class:`numbers.Number` - .. index:: object: numeric +----------------------- + +.. index:: pair: object; numeric + +These are created by numeric literals and returned as results by arithmetic +operators and arithmetic built-in functions. Numeric objects are immutable; +once created their value never changes. Python numbers are of course strongly +related to mathematical numbers, but subject to the limitations of numerical +representation in computers. + +The string representations of the numeric classes, computed by +:meth:`~object.__repr__` and :meth:`~object.__str__`, have the following +properties: + +* They are valid numeric literals which, when passed to their + class constructor, produce an object having the value of the + original numeric. + +* The representation is in base 10, when possible. + +* Leading zeros, possibly excepting a single zero before a + decimal point, are not shown. + +* Trailing zeros, possibly excepting a single zero after a + decimal point, are not shown. - These are created by numeric literals and returned as results by arithmetic - operators and arithmetic built-in functions. Numeric objects are immutable; - once created their value never changes. Python numbers are of course strongly - related to mathematical numbers, but subject to the limitations of numerical - representation in computers. +* A sign is shown only when the number is negative. - The string representations of the numeric classes, computed by - :meth:`~object.__repr__` and :meth:`~object.__str__`, have the following - properties: +Python distinguishes between integers, floating point numbers, and complex +numbers: - * They are valid numeric literals which, when passed to their - class constructor, produce an object having the value of the - original numeric. - * The representation is in base 10, when possible. +:class:`numbers.Integral` +^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. index:: pair: object; integer - * Leading zeros, possibly excepting a single zero before a - decimal point, are not shown. +These represent elements from the mathematical set of integers (positive and +negative). - * Trailing zeros, possibly excepting a single zero after a - decimal point, are not shown. +.. note:: + .. index:: pair: integer; representation - * A sign is shown only when the number is negative. + The rules for integer representation are intended to give the most meaningful + interpretation of shift and mask operations involving negative integers. - Python distinguishes between integers, floating point numbers, and complex - numbers: +There are two types of integers: - :class:`numbers.Integral` - .. index:: object: integer +Integers (:class:`int`) + These represent numbers in an unlimited range, subject to available (virtual) + memory only. For the purpose of shift and mask operations, a binary + representation is assumed, and negative numbers are represented in a variant of + 2's complement which gives the illusion of an infinite string of sign bits + extending to the left. - These represent elements from the mathematical set of integers (positive and - negative). +Booleans (:class:`bool`) + .. index:: + pair: object; Boolean + single: False + single: True - There are two types of integers: + These represent the truth values False and True. The two objects representing + the values ``False`` and ``True`` are the only Boolean objects. The Boolean type is a + subtype of the integer type, and Boolean values behave like the values 0 and 1, + respectively, in almost all contexts, the exception being that when converted to + a string, the strings ``"False"`` or ``"True"`` are returned, respectively. - Integers (:class:`int`) - These represent numbers in an unlimited range, subject to available (virtual) - memory only. For the purpose of shift and mask operations, a binary - representation is assumed, and negative numbers are represented in a variant of - 2's complement which gives the illusion of an infinite string of sign bits - extending to the left. - Booleans (:class:`bool`) - .. index:: - object: Boolean - single: False - single: True +:class:`numbers.Real` (:class:`float`) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - These represent the truth values False and True. The two objects representing - the values ``False`` and ``True`` are the only Boolean objects. The Boolean type is a - subtype of the integer type, and Boolean values behave like the values 0 and 1, - respectively, in almost all contexts, the exception being that when converted to - a string, the strings ``"False"`` or ``"True"`` are returned, respectively. +.. index:: + pair: object; floating point + pair: floating point; number + pair: C; language + pair: Java; language - .. index:: pair: integer; representation +These represent machine-level double precision floating point numbers. You are +at the mercy of the underlying machine architecture (and C or Java +implementation) for the accepted range and handling of overflow. Python does not +support single-precision floating point numbers; the savings in processor and +memory usage that are usually the reason for using these are dwarfed by the +overhead of using objects in Python, so there is no reason to complicate the +language with two kinds of floating point numbers. - The rules for integer representation are intended to give the most meaningful - interpretation of shift and mask operations involving negative integers. - :class:`numbers.Real` (:class:`float`) - .. index:: - object: floating point - pair: floating point; number - pair: C; language - pair: Java; language +:class:`numbers.Complex` (:class:`complex`) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - These represent machine-level double precision floating point numbers. You are - at the mercy of the underlying machine architecture (and C or Java - implementation) for the accepted range and handling of overflow. Python does not - support single-precision floating point numbers; the savings in processor and - memory usage that are usually the reason for using these are dwarfed by the - overhead of using objects in Python, so there is no reason to complicate the - language with two kinds of floating point numbers. +.. index:: + pair: object; complex + pair: complex; number - :class:`numbers.Complex` (:class:`complex`) - .. index:: - object: complex - pair: complex; number +These represent complex numbers as a pair of machine-level double precision +floating point numbers. The same caveats apply as for floating point numbers. +The real and imaginary parts of a complex number ``z`` can be retrieved through +the read-only attributes ``z.real`` and ``z.imag``. - These represent complex numbers as a pair of machine-level double precision - floating point numbers. The same caveats apply as for floating point numbers. - The real and imaginary parts of a complex number ``z`` can be retrieved through - the read-only attributes ``z.real`` and ``z.imag``. Sequences +--------- + +.. index:: + pair: built-in function; len + pair: object; sequence + single: index operation + single: item selection + single: subscription + +These represent finite ordered sets indexed by non-negative numbers. The +built-in function :func:`len` returns the number of items of a sequence. When +the length of a sequence is *n*, the index set contains the numbers 0, 1, +..., *n*-1. Item *i* of sequence *a* is selected by ``a[i]``. + +.. index:: single: slicing + +Sequences also support slicing: ``a[i:j]`` selects all items with index *k* such +that *i* ``<=`` *k* ``<`` *j*. When used as an expression, a slice is a +sequence of the same type. This implies that the index set is renumbered so +that it starts at 0. + +Some sequences also support "extended slicing" with a third "step" parameter: +``a[i:j:k]`` selects all items of *a* with index *x* where ``x = i + n*k``, *n* +``>=`` ``0`` and *i* ``<=`` *x* ``<`` *j*. + +Sequences are distinguished according to their mutability: + + +Immutable sequences +^^^^^^^^^^^^^^^^^^^ + +.. index:: + pair: object; immutable sequence + pair: object; immutable + +An object of an immutable sequence type cannot change once it is created. (If +the object contains references to other objects, these other objects may be +mutable and may be changed; however, the collection of objects directly +referenced by an immutable object cannot change.) + +The following types are immutable sequences: + +.. index:: + single: string; immutable sequences + +Strings .. index:: - builtin: len - object: sequence - single: index operation - single: item selection - single: subscription - - These represent finite ordered sets indexed by non-negative numbers. The - built-in function :func:`len` returns the number of items of a sequence. When - the length of a sequence is *n*, the index set contains the numbers 0, 1, - ..., *n*-1. Item *i* of sequence *a* is selected by ``a[i]``. - - .. index:: single: slicing - - Sequences also support slicing: ``a[i:j]`` selects all items with index *k* such - that *i* ``<=`` *k* ``<`` *j*. When used as an expression, a slice is a - sequence of the same type. This implies that the index set is renumbered so - that it starts at 0. - - Some sequences also support "extended slicing" with a third "step" parameter: - ``a[i:j:k]`` selects all items of *a* with index *x* where ``x = i + n*k``, *n* - ``>=`` ``0`` and *i* ``<=`` *x* ``<`` *j*. - - Sequences are distinguished according to their mutability: - - Immutable sequences - .. index:: - object: immutable sequence - object: immutable - - An object of an immutable sequence type cannot change once it is created. (If - the object contains references to other objects, these other objects may be - mutable and may be changed; however, the collection of objects directly - referenced by an immutable object cannot change.) - - The following types are immutable sequences: - - .. index:: - single: string; immutable sequences - - Strings - .. index:: - builtin: chr - builtin: ord - single: character - single: integer - single: Unicode - - A string is a sequence of values that represent Unicode code points. - All the code points in the range ``U+0000 - U+10FFFF`` can be - represented in a string. Python doesn't have a :c:expr:`char` type; - instead, every code point in the string is represented as a string - object with length ``1``. The built-in function :func:`ord` - converts a code point from its string form to an integer in the - range ``0 - 10FFFF``; :func:`chr` converts an integer in the range - ``0 - 10FFFF`` to the corresponding length ``1`` string object. - :meth:`str.encode` can be used to convert a :class:`str` to - :class:`bytes` using the given text encoding, and - :meth:`bytes.decode` can be used to achieve the opposite. - - Tuples - .. index:: - object: tuple - pair: singleton; tuple - pair: empty; tuple - - The items of a tuple are arbitrary Python objects. Tuples of two or - more items are formed by comma-separated lists of expressions. A tuple - of one item (a 'singleton') can be formed by affixing a comma to an - expression (an expression by itself does not create a tuple, since - parentheses must be usable for grouping of expressions). An empty - tuple can be formed by an empty pair of parentheses. - - Bytes - .. index:: bytes, byte - - A bytes object is an immutable array. The items are 8-bit bytes, - represented by integers in the range 0 <= x < 256. Bytes literals - (like ``b'abc'``) and the built-in :func:`bytes()` constructor - can be used to create bytes objects. Also, bytes objects can be - decoded to strings via the :meth:`~bytes.decode` method. - - Mutable sequences - .. index:: - object: mutable sequence - object: mutable - pair: assignment; statement - single: subscription - single: slicing - - Mutable sequences can be changed after they are created. The subscription and - slicing notations can be used as the target of assignment and :keyword:`del` - (delete) statements. - - There are currently two intrinsic mutable sequence types: - - Lists - .. index:: object: list - - The items of a list are arbitrary Python objects. Lists are formed by - placing a comma-separated list of expressions in square brackets. (Note - that there are no special cases needed to form lists of length 0 or 1.) - - Byte Arrays - .. index:: bytearray - - A bytearray object is a mutable array. They are created by the built-in - :func:`bytearray` constructor. Aside from being mutable - (and hence unhashable), byte arrays otherwise provide the same interface - and functionality as immutable :class:`bytes` objects. - - .. index:: module: array - - The extension module :mod:`array` provides an additional example of a - mutable sequence type, as does the :mod:`collections` module. + pair: built-in function; chr + pair: built-in function; ord + single: character + single: integer + single: Unicode + + A string is a sequence of values that represent Unicode code points. + All the code points in the range ``U+0000 - U+10FFFF`` can be + represented in a string. Python doesn't have a :c:expr:`char` type; + instead, every code point in the string is represented as a string + object with length ``1``. The built-in function :func:`ord` + converts a code point from its string form to an integer in the + range ``0 - 10FFFF``; :func:`chr` converts an integer in the range + ``0 - 10FFFF`` to the corresponding length ``1`` string object. + :meth:`str.encode` can be used to convert a :class:`str` to + :class:`bytes` using the given text encoding, and + :meth:`bytes.decode` can be used to achieve the opposite. + +Tuples + .. index:: + pair: object; tuple + pair: singleton; tuple + pair: empty; tuple + + The items of a tuple are arbitrary Python objects. Tuples of two or + more items are formed by comma-separated lists of expressions. A tuple + of one item (a 'singleton') can be formed by affixing a comma to an + expression (an expression by itself does not create a tuple, since + parentheses must be usable for grouping of expressions). An empty + tuple can be formed by an empty pair of parentheses. + +Bytes + .. index:: bytes, byte + + A bytes object is an immutable array. The items are 8-bit bytes, + represented by integers in the range 0 <= x < 256. Bytes literals + (like ``b'abc'``) and the built-in :func:`bytes()` constructor + can be used to create bytes objects. Also, bytes objects can be + decoded to strings via the :meth:`~bytes.decode` method. + + +Mutable sequences +^^^^^^^^^^^^^^^^^ + +.. index:: + pair: object; mutable sequence + pair: object; mutable + pair: assignment; statement + single: subscription + single: slicing + +Mutable sequences can be changed after they are created. The subscription and +slicing notations can be used as the target of assignment and :keyword:`del` +(delete) statements. + +.. note:: + .. index:: pair: module; array + .. index:: pair: module; collections + + The :mod:`collections` and :mod:`array` module provide + additional examples of mutable sequence types. + +There are currently two intrinsic mutable sequence types: + +Lists + .. index:: pair: object; list + + The items of a list are arbitrary Python objects. Lists are formed by + placing a comma-separated list of expressions in square brackets. (Note + that there are no special cases needed to form lists of length 0 or 1.) + +Byte Arrays + .. index:: bytearray + + A bytearray object is a mutable array. They are created by the built-in + :func:`bytearray` constructor. Aside from being mutable + (and hence unhashable), byte arrays otherwise provide the same interface + and functionality as immutable :class:`bytes` objects. + Set types - .. index:: - builtin: len - object: set type +--------- + +.. index:: + pair: built-in function; len + pair: object; set type - These represent unordered, finite sets of unique, immutable objects. As such, - they cannot be indexed by any subscript. However, they can be iterated over, and - the built-in function :func:`len` returns the number of items in a set. Common - uses for sets are fast membership testing, removing duplicates from a sequence, - and computing mathematical operations such as intersection, union, difference, - and symmetric difference. +These represent unordered, finite sets of unique, immutable objects. As such, +they cannot be indexed by any subscript. However, they can be iterated over, and +the built-in function :func:`len` returns the number of items in a set. Common +uses for sets are fast membership testing, removing duplicates from a sequence, +and computing mathematical operations such as intersection, union, difference, +and symmetric difference. - For set elements, the same immutability rules apply as for dictionary keys. Note - that numeric types obey the normal rules for numeric comparison: if two numbers - compare equal (e.g., ``1`` and ``1.0``), only one of them can be contained in a - set. +For set elements, the same immutability rules apply as for dictionary keys. Note +that numeric types obey the normal rules for numeric comparison: if two numbers +compare equal (e.g., ``1`` and ``1.0``), only one of them can be contained in a +set. - There are currently two intrinsic set types: +There are currently two intrinsic set types: - Sets - .. index:: object: set - These represent a mutable set. They are created by the built-in :func:`set` - constructor and can be modified afterwards by several methods, such as - :meth:`~set.add`. +Sets + .. index:: pair: object; set - Frozen sets - .. index:: object: frozenset + These represent a mutable set. They are created by the built-in :func:`set` + constructor and can be modified afterwards by several methods, such as + :meth:`~set.add`. + + +Frozen sets + .. index:: pair: object; frozenset + + These represent an immutable set. They are created by the built-in + :func:`frozenset` constructor. As a frozenset is immutable and + :term:`hashable`, it can be used again as an element of another set, or as + a dictionary key. - These represent an immutable set. They are created by the built-in - :func:`frozenset` constructor. As a frozenset is immutable and - :term:`hashable`, it can be used again as an element of another set, or as - a dictionary key. Mappings - .. index:: - builtin: len - single: subscription - object: mapping - - These represent finite sets of objects indexed by arbitrary index sets. The - subscript notation ``a[k]`` selects the item indexed by ``k`` from the mapping - ``a``; this can be used in expressions and as the target of assignments or - :keyword:`del` statements. The built-in function :func:`len` returns the number - of items in a mapping. - - There is currently a single intrinsic mapping type: - - Dictionaries - .. index:: object: dictionary - - These represent finite sets of objects indexed by nearly arbitrary values. The - only types of values not acceptable as keys are values containing lists or - dictionaries or other mutable types that are compared by value rather than by - object identity, the reason being that the efficient implementation of - dictionaries requires a key's hash value to remain constant. Numeric types used - for keys obey the normal rules for numeric comparison: if two numbers compare - equal (e.g., ``1`` and ``1.0``) then they can be used interchangeably to index - the same dictionary entry. - - Dictionaries preserve insertion order, meaning that keys will be produced - in the same order they were added sequentially over the dictionary. - Replacing an existing key does not change the order, however removing a key - and re-inserting it will add it to the end instead of keeping its old place. - - Dictionaries are mutable; they can be created by the ``{...}`` notation (see - section :ref:`dict`). - - .. index:: - module: dbm.ndbm - module: dbm.gnu - - The extension modules :mod:`dbm.ndbm` and :mod:`dbm.gnu` provide - additional examples of mapping types, as does the :mod:`collections` - module. - - .. versionchanged:: 3.7 - Dictionaries did not preserve insertion order in versions of Python before 3.6. - In CPython 3.6, insertion order was preserved, but it was considered - an implementation detail at that time rather than a language guarantee. +-------- + +.. index:: + pair: built-in function; len + single: subscription + pair: object; mapping + +These represent finite sets of objects indexed by arbitrary index sets. The +subscript notation ``a[k]`` selects the item indexed by ``k`` from the mapping +``a``; this can be used in expressions and as the target of assignments or +:keyword:`del` statements. The built-in function :func:`len` returns the number +of items in a mapping. + +There is currently a single intrinsic mapping type: + + +Dictionaries +^^^^^^^^^^^^ + +.. index:: pair: object; dictionary + +These represent finite sets of objects indexed by nearly arbitrary values. The +only types of values not acceptable as keys are values containing lists or +dictionaries or other mutable types that are compared by value rather than by +object identity, the reason being that the efficient implementation of +dictionaries requires a key's hash value to remain constant. Numeric types used +for keys obey the normal rules for numeric comparison: if two numbers compare +equal (e.g., ``1`` and ``1.0``) then they can be used interchangeably to index +the same dictionary entry. + +Dictionaries preserve insertion order, meaning that keys will be produced +in the same order they were added sequentially over the dictionary. +Replacing an existing key does not change the order, however removing a key +and re-inserting it will add it to the end instead of keeping its old place. + +Dictionaries are mutable; they can be created by the ``{...}`` notation (see +section :ref:`dict`). + +.. index:: + pair: module; dbm.ndbm + pair: module; dbm.gnu + +The extension modules :mod:`dbm.ndbm` and :mod:`dbm.gnu` provide +additional examples of mapping types, as does the :mod:`collections` +module. + +.. versionchanged:: 3.7 + Dictionaries did not preserve insertion order in versions of Python before 3.6. + In CPython 3.6, insertion order was preserved, but it was considered + an implementation detail at that time rather than a language guarantee. + Callable types - .. index:: - object: callable - pair: function; call - single: invocation - pair: function; argument - - These are the types to which the function call operation (see section - :ref:`calls`) can be applied: - - User-defined functions - .. index:: - pair: user-defined; function - object: function - object: user-defined function - - A user-defined function object is created by a function definition (see - section :ref:`function`). It should be called with an argument list - containing the same number of items as the function's formal parameter - list. - - Special attributes: - - .. tabularcolumns:: |l|L|l| - - .. index:: - single: __doc__ (function attribute) - single: __name__ (function attribute) - single: __module__ (function attribute) - single: __dict__ (function attribute) - single: __defaults__ (function attribute) - single: __closure__ (function attribute) - single: __code__ (function attribute) - single: __globals__ (function attribute) - single: __annotations__ (function attribute) - single: __kwdefaults__ (function attribute) - pair: global; namespace - - +-------------------------+-------------------------------+-----------+ - | Attribute | Meaning | | - +=========================+===============================+===========+ - | :attr:`__doc__` | The function's documentation | Writable | - | | string, or ``None`` if | | - | | unavailable; not inherited by | | - | | subclasses. | | - +-------------------------+-------------------------------+-----------+ - | :attr:`~definition.\ | The function's name. | Writable | - | __name__` | | | - +-------------------------+-------------------------------+-----------+ - | :attr:`~definition.\ | The function's | Writable | - | __qualname__` | :term:`qualified name`. | | - | | | | - | | .. versionadded:: 3.3 | | - +-------------------------+-------------------------------+-----------+ - | :attr:`__module__` | The name of the module the | Writable | - | | function was defined in, or | | - | | ``None`` if unavailable. | | - +-------------------------+-------------------------------+-----------+ - | :attr:`__defaults__` | A tuple containing default | Writable | - | | argument values for those | | - | | arguments that have defaults, | | - | | or ``None`` if no arguments | | - | | have a default value. | | - +-------------------------+-------------------------------+-----------+ - | :attr:`__code__` | The code object representing | Writable | - | | the compiled function body. | | - +-------------------------+-------------------------------+-----------+ - | :attr:`__globals__` | A reference to the dictionary | Read-only | - | | that holds the function's | | - | | global variables --- the | | - | | global namespace of the | | - | | module in which the function | | - | | was defined. | | - +-------------------------+-------------------------------+-----------+ - | :attr:`~object.__dict__`| The namespace supporting | Writable | - | | arbitrary function | | - | | attributes. | | - +-------------------------+-------------------------------+-----------+ - | :attr:`__closure__` | ``None`` or a tuple of cells | Read-only | - | | that contain bindings for the | | - | | function's free variables. | | - | | See below for information on | | - | | the ``cell_contents`` | | - | | attribute. | | - +-------------------------+-------------------------------+-----------+ - | :attr:`__annotations__` | A dict containing annotations | Writable | - | | of parameters. The keys of | | - | | the dict are the parameter | | - | | names, and ``'return'`` for | | - | | the return annotation, if | | - | | provided. For more | | - | | information on working with | | - | | this attribute, see | | - | | :ref:`annotations-howto`. | | - +-------------------------+-------------------------------+-----------+ - | :attr:`__kwdefaults__` | A dict containing defaults | Writable | - | | for keyword-only parameters. | | - +-------------------------+-------------------------------+-----------+ - - Most of the attributes labelled "Writable" check the type of the assigned value. - - Function objects also support getting and setting arbitrary attributes, which - can be used, for example, to attach metadata to functions. Regular attribute - dot-notation is used to get and set such attributes. *Note that the current - implementation only supports function attributes on user-defined functions. - Function attributes on built-in functions may be supported in the future.* - - A cell object has the attribute ``cell_contents``. This can be used to get - the value of the cell, as well as set the value. - - Additional information about a function's definition can be retrieved from its - code object; see the description of internal types below. The - :data:`cell <types.CellType>` type can be accessed in the :mod:`types` - module. - - Instance methods - .. index:: - object: method - object: user-defined method - pair: user-defined; method - - An instance method object combines a class, a class instance and any - callable object (normally a user-defined function). - - .. index:: - single: __func__ (method attribute) - single: __self__ (method attribute) - single: __doc__ (method attribute) - single: __name__ (method attribute) - single: __module__ (method attribute) - - Special read-only attributes: :attr:`__self__` is the class instance object, - :attr:`__func__` is the function object; :attr:`__doc__` is the method's - documentation (same as ``__func__.__doc__``); :attr:`~definition.__name__` is the - method name (same as ``__func__.__name__``); :attr:`__module__` is the - name of the module the method was defined in, or ``None`` if unavailable. - - Methods also support accessing (but not setting) the arbitrary function - attributes on the underlying function object. - - User-defined method objects may be created when getting an attribute of a - class (perhaps via an instance of that class), if that attribute is a - user-defined function object or a class method object. - - When an instance method object is created by retrieving a user-defined - function object from a class via one of its instances, its - :attr:`__self__` attribute is the instance, and the method object is said - to be bound. The new method's :attr:`__func__` attribute is the original - function object. - - When an instance method object is created by retrieving a class method - object from a class or instance, its :attr:`__self__` attribute is the - class itself, and its :attr:`__func__` attribute is the function object - underlying the class method. - - When an instance method object is called, the underlying function - (:attr:`__func__`) is called, inserting the class instance - (:attr:`__self__`) in front of the argument list. For instance, when - :class:`C` is a class which contains a definition for a function - :meth:`f`, and ``x`` is an instance of :class:`C`, calling ``x.f(1)`` is - equivalent to calling ``C.f(x, 1)``. - - When an instance method object is derived from a class method object, the - "class instance" stored in :attr:`__self__` will actually be the class - itself, so that calling either ``x.f(1)`` or ``C.f(1)`` is equivalent to - calling ``f(C,1)`` where ``f`` is the underlying function. - - Note that the transformation from function object to instance method - object happens each time the attribute is retrieved from the instance. In - some cases, a fruitful optimization is to assign the attribute to a local - variable and call that local variable. Also notice that this - transformation only happens for user-defined functions; other callable - objects (and all non-callable objects) are retrieved without - transformation. It is also important to note that user-defined functions - which are attributes of a class instance are not converted to bound - methods; this *only* happens when the function is an attribute of the - class. - - Generator functions - .. index:: - single: generator; function - single: generator; iterator - - A function or method which uses the :keyword:`yield` statement (see section - :ref:`yield`) is called a :dfn:`generator function`. Such a function, when - called, always returns an :term:`iterator` object which can be used to - execute the body of the function: calling the iterator's - :meth:`iterator.__next__` method will cause the function to execute until - it provides a value using the :keyword:`!yield` statement. When the - function executes a :keyword:`return` statement or falls off the end, a - :exc:`StopIteration` exception is raised and the iterator will have - reached the end of the set of values to be returned. - - Coroutine functions - .. index:: - single: coroutine; function - - A function or method which is defined using :keyword:`async def` is called - a :dfn:`coroutine function`. Such a function, when called, returns a - :term:`coroutine` object. It may contain :keyword:`await` expressions, - as well as :keyword:`async with` and :keyword:`async for` statements. See - also the :ref:`coroutine-objects` section. - - Asynchronous generator functions - .. index:: - single: asynchronous generator; function - single: asynchronous generator; asynchronous iterator - - A function or method which is defined using :keyword:`async def` and - which uses the :keyword:`yield` statement is called a - :dfn:`asynchronous generator function`. Such a function, when called, - returns an :term:`asynchronous iterator` object which can be used in an - :keyword:`async for` statement to execute the body of the function. - - Calling the asynchronous iterator's - :meth:`aiterator.__anext__ <object.__anext__>` method - will return an :term:`awaitable` which when awaited - will execute until it provides a value using the :keyword:`yield` - expression. When the function executes an empty :keyword:`return` - statement or falls off the end, a :exc:`StopAsyncIteration` exception - is raised and the asynchronous iterator will have reached the end of - the set of values to be yielded. - - Built-in functions - .. index:: - object: built-in function - object: function - pair: C; language - - A built-in function object is a wrapper around a C function. Examples of - built-in functions are :func:`len` and :func:`math.sin` (:mod:`math` is a - standard built-in module). The number and type of the arguments are - determined by the C function. Special read-only attributes: - :attr:`__doc__` is the function's documentation string, or ``None`` if - unavailable; :attr:`~definition.__name__` is the function's name; :attr:`__self__` is - set to ``None`` (but see the next item); :attr:`__module__` is the name of - the module the function was defined in or ``None`` if unavailable. - - Built-in methods - .. index:: - object: built-in method - object: method - pair: built-in; method - - This is really a different disguise of a built-in function, this time containing - an object passed to the C function as an implicit extra argument. An example of - a built-in method is ``alist.append()``, assuming *alist* is a list object. In - this case, the special read-only attribute :attr:`__self__` is set to the object - denoted by *alist*. - - Classes - Classes are callable. These objects normally act as factories for new - instances of themselves, but variations are possible for class types that - override :meth:`~object.__new__`. The arguments of the call are passed to - :meth:`__new__` and, in the typical case, to :meth:`~object.__init__` to - initialize the new instance. - - Class Instances - Instances of arbitrary classes can be made callable by defining a - :meth:`~object.__call__` method in their class. +-------------- + +.. index:: + pair: object; callable + pair: function; call + single: invocation + pair: function; argument + +These are the types to which the function call operation (see section +:ref:`calls`) can be applied: + + +User-defined functions +^^^^^^^^^^^^^^^^^^^^^^ + +.. index:: + pair: user-defined; function + pair: object; function + pair: object; user-defined function + +A user-defined function object is created by a function definition (see +section :ref:`function`). It should be called with an argument list +containing the same number of items as the function's formal parameter +list. + +Special attributes: + +.. tabularcolumns:: |l|L|l| + +.. index:: + single: __doc__ (function attribute) + single: __name__ (function attribute) + single: __module__ (function attribute) + single: __dict__ (function attribute) + single: __defaults__ (function attribute) + single: __closure__ (function attribute) + single: __code__ (function attribute) + single: __globals__ (function attribute) + single: __annotations__ (function attribute) + single: __kwdefaults__ (function attribute) + single: __type_params__ (function attribute) + pair: global; namespace + ++-------------------------+-------------------------------+-----------+ +| Attribute | Meaning | | ++=========================+===============================+===========+ +| :attr:`__doc__` | The function's documentation | Writable | +| | string, or ``None`` if | | +| | unavailable; not inherited by | | +| | subclasses. | | ++-------------------------+-------------------------------+-----------+ +| :attr:`~definition.\ | The function's name. | Writable | +| __name__` | | | ++-------------------------+-------------------------------+-----------+ +| :attr:`~definition.\ | The function's | Writable | +| __qualname__` | :term:`qualified name`. | | +| | | | +| | .. versionadded:: 3.3 | | ++-------------------------+-------------------------------+-----------+ +| :attr:`__module__` | The name of the module the | Writable | +| | function was defined in, or | | +| | ``None`` if unavailable. | | ++-------------------------+-------------------------------+-----------+ +| :attr:`__defaults__` | A tuple containing default | Writable | +| | argument values for those | | +| | arguments that have defaults, | | +| | or ``None`` if no arguments | | +| | have a default value. | | ++-------------------------+-------------------------------+-----------+ +| :attr:`__code__` | The code object representing | Writable | +| | the compiled function body. | | ++-------------------------+-------------------------------+-----------+ +| :attr:`__globals__` | A reference to the dictionary | Read-only | +| | that holds the function's | | +| | global variables --- the | | +| | global namespace of the | | +| | module in which the function | | +| | was defined. | | ++-------------------------+-------------------------------+-----------+ +| :attr:`~object.__dict__`| The namespace supporting | Writable | +| | arbitrary function | | +| | attributes. | | ++-------------------------+-------------------------------+-----------+ +| :attr:`__closure__` | ``None`` or a tuple of cells | Read-only | +| | that contain bindings for the | | +| | function's free variables. | | +| | See below for information on | | +| | the ``cell_contents`` | | +| | attribute. | | ++-------------------------+-------------------------------+-----------+ +| :attr:`__annotations__` | A dict containing annotations | Writable | +| | of parameters. The keys of | | +| | the dict are the parameter | | +| | names, and ``'return'`` for | | +| | the return annotation, if | | +| | provided. For more | | +| | information on working with | | +| | this attribute, see | | +| | :ref:`annotations-howto`. | | ++-------------------------+-------------------------------+-----------+ +| :attr:`__kwdefaults__` | A dict containing defaults | Writable | +| | for keyword-only parameters. | | ++-------------------------+-------------------------------+-----------+ +| :attr:`__type_params__` | A tuple containing the | Writable | +| | :ref:`type parameters | | +| | <type-params>` of a | | +| | :ref:`generic function | | +| | <generic-functions>`. | | ++-------------------------+-------------------------------+-----------+ + +Most of the attributes labelled "Writable" check the type of the assigned value. + +Function objects also support getting and setting arbitrary attributes, which +can be used, for example, to attach metadata to functions. Regular attribute +dot-notation is used to get and set such attributes. *Note that the current +implementation only supports function attributes on user-defined functions. +Function attributes on built-in functions may be supported in the future.* + +A cell object has the attribute ``cell_contents``. This can be used to get +the value of the cell, as well as set the value. + +Additional information about a function's definition can be retrieved from its +code object; see the description of internal types below. The +:data:`cell <types.CellType>` type can be accessed in the :mod:`types` +module. + + +Instance methods +^^^^^^^^^^^^^^^^ + +.. index:: + pair: object; method + pair: object; user-defined method + pair: user-defined; method + +An instance method object combines a class, a class instance and any +callable object (normally a user-defined function). + +.. index:: + single: __func__ (method attribute) + single: __self__ (method attribute) + single: __doc__ (method attribute) + single: __name__ (method attribute) + single: __module__ (method attribute) + +Special read-only attributes: :attr:`__self__` is the class instance object, +:attr:`__func__` is the function object; :attr:`__doc__` is the method's +documentation (same as ``__func__.__doc__``); :attr:`~definition.__name__` is the +method name (same as ``__func__.__name__``); :attr:`__module__` is the +name of the module the method was defined in, or ``None`` if unavailable. + +Methods also support accessing (but not setting) the arbitrary function +attributes on the underlying function object. + +User-defined method objects may be created when getting an attribute of a +class (perhaps via an instance of that class), if that attribute is a +user-defined function object or a class method object. + +When an instance method object is created by retrieving a user-defined +function object from a class via one of its instances, its +:attr:`__self__` attribute is the instance, and the method object is said +to be bound. The new method's :attr:`__func__` attribute is the original +function object. + +When an instance method object is created by retrieving a class method +object from a class or instance, its :attr:`__self__` attribute is the +class itself, and its :attr:`__func__` attribute is the function object +underlying the class method. + +When an instance method object is called, the underlying function +(:attr:`__func__`) is called, inserting the class instance +(:attr:`__self__`) in front of the argument list. For instance, when +:class:`C` is a class which contains a definition for a function +:meth:`f`, and ``x`` is an instance of :class:`C`, calling ``x.f(1)`` is +equivalent to calling ``C.f(x, 1)``. + +When an instance method object is derived from a class method object, the +"class instance" stored in :attr:`__self__` will actually be the class +itself, so that calling either ``x.f(1)`` or ``C.f(1)`` is equivalent to +calling ``f(C,1)`` where ``f`` is the underlying function. + +Note that the transformation from function object to instance method +object happens each time the attribute is retrieved from the instance. In +some cases, a fruitful optimization is to assign the attribute to a local +variable and call that local variable. Also notice that this +transformation only happens for user-defined functions; other callable +objects (and all non-callable objects) are retrieved without +transformation. It is also important to note that user-defined functions +which are attributes of a class instance are not converted to bound +methods; this *only* happens when the function is an attribute of the +class. + + +Generator functions +^^^^^^^^^^^^^^^^^^^ + +.. index:: + single: generator; function + single: generator; iterator + +A function or method which uses the :keyword:`yield` statement (see section +:ref:`yield`) is called a :dfn:`generator function`. Such a function, when +called, always returns an :term:`iterator` object which can be used to +execute the body of the function: calling the iterator's +:meth:`iterator.__next__` method will cause the function to execute until +it provides a value using the :keyword:`!yield` statement. When the +function executes a :keyword:`return` statement or falls off the end, a +:exc:`StopIteration` exception is raised and the iterator will have +reached the end of the set of values to be returned. + + +Coroutine functions +^^^^^^^^^^^^^^^^^^^ + +.. index:: + single: coroutine; function + +A function or method which is defined using :keyword:`async def` is called +a :dfn:`coroutine function`. Such a function, when called, returns a +:term:`coroutine` object. It may contain :keyword:`await` expressions, +as well as :keyword:`async with` and :keyword:`async for` statements. See +also the :ref:`coroutine-objects` section. + + +Asynchronous generator functions +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. index:: + single: asynchronous generator; function + single: asynchronous generator; asynchronous iterator + +A function or method which is defined using :keyword:`async def` and +which uses the :keyword:`yield` statement is called a +:dfn:`asynchronous generator function`. Such a function, when called, +returns an :term:`asynchronous iterator` object which can be used in an +:keyword:`async for` statement to execute the body of the function. + +Calling the asynchronous iterator's +:meth:`aiterator.__anext__ <object.__anext__>` method +will return an :term:`awaitable` which when awaited +will execute until it provides a value using the :keyword:`yield` +expression. When the function executes an empty :keyword:`return` +statement or falls off the end, a :exc:`StopAsyncIteration` exception +is raised and the asynchronous iterator will have reached the end of +the set of values to be yielded. + + +Built-in functions +^^^^^^^^^^^^^^^^^^ + +.. index:: + pair: object; built-in function + pair: object; function + pair: C; language + +A built-in function object is a wrapper around a C function. Examples of +built-in functions are :func:`len` and :func:`math.sin` (:mod:`math` is a +standard built-in module). The number and type of the arguments are +determined by the C function. Special read-only attributes: +:attr:`__doc__` is the function's documentation string, or ``None`` if +unavailable; :attr:`~definition.__name__` is the function's name; :attr:`__self__` is +set to ``None`` (but see the next item); :attr:`__module__` is the name of +the module the function was defined in or ``None`` if unavailable. + + +Built-in methods +^^^^^^^^^^^^^^^^ + +.. index:: + pair: object; built-in method + pair: object; method + pair: built-in; method + +This is really a different disguise of a built-in function, this time containing +an object passed to the C function as an implicit extra argument. An example of +a built-in method is ``alist.append()``, assuming *alist* is a list object. In +this case, the special read-only attribute :attr:`__self__` is set to the object +denoted by *alist*. + + +Classes +^^^^^^^ + +Classes are callable. These objects normally act as factories for new +instances of themselves, but variations are possible for class types that +override :meth:`~object.__new__`. The arguments of the call are passed to +:meth:`__new__` and, in the typical case, to :meth:`~object.__init__` to +initialize the new instance. + + +Class Instances +^^^^^^^^^^^^^^^ + +Instances of arbitrary classes can be made callable by defining a +:meth:`~object.__call__` method in their class. Modules - .. index:: - statement: import - object: module - - Modules are a basic organizational unit of Python code, and are created by - the :ref:`import system <importsystem>` as invoked either by the - :keyword:`import` statement, or by calling - functions such as :func:`importlib.import_module` and built-in - :func:`__import__`. A module object has a namespace implemented by a - dictionary object (this is the dictionary referenced by the ``__globals__`` - attribute of functions defined in the module). Attribute references are - translated to lookups in this dictionary, e.g., ``m.x`` is equivalent to - ``m.__dict__["x"]``. A module object does not contain the code object used - to initialize the module (since it isn't needed once the initialization is - done). - - Attribute assignment updates the module's namespace dictionary, e.g., - ``m.x = 1`` is equivalent to ``m.__dict__["x"] = 1``. +------- - .. index:: - single: __name__ (module attribute) - single: __doc__ (module attribute) - single: __file__ (module attribute) - single: __annotations__ (module attribute) - pair: module; namespace +.. index:: + pair: statement; import + pair: object; module + +Modules are a basic organizational unit of Python code, and are created by +the :ref:`import system <importsystem>` as invoked either by the +:keyword:`import` statement, or by calling +functions such as :func:`importlib.import_module` and built-in +:func:`__import__`. A module object has a namespace implemented by a +dictionary object (this is the dictionary referenced by the ``__globals__`` +attribute of functions defined in the module). Attribute references are +translated to lookups in this dictionary, e.g., ``m.x`` is equivalent to +``m.__dict__["x"]``. A module object does not contain the code object used +to initialize the module (since it isn't needed once the initialization is +done). + +Attribute assignment updates the module's namespace dictionary, e.g., +``m.x = 1`` is equivalent to ``m.__dict__["x"] = 1``. - Predefined (writable) attributes: +.. index:: + single: __name__ (module attribute) + single: __doc__ (module attribute) + single: __file__ (module attribute) + single: __annotations__ (module attribute) + pair: module; namespace - :attr:`__name__` - The module's name. +Predefined (writable) attributes: - :attr:`__doc__` - The module's documentation string, or ``None`` if - unavailable. + :attr:`__name__` + The module's name. - :attr:`__file__` - The pathname of the file from which the - module was loaded, if it was loaded from a file. - The :attr:`__file__` - attribute may be missing for certain types of modules, such as C modules - that are statically linked into the interpreter. For extension modules - loaded dynamically from a shared library, it's the pathname of the shared - library file. + :attr:`__doc__` + The module's documentation string, or ``None`` if + unavailable. - :attr:`__annotations__` - A dictionary containing - :term:`variable annotations <variable annotation>` collected during - module body execution. For best practices on working - with :attr:`__annotations__`, please see :ref:`annotations-howto`. + :attr:`__file__` + The pathname of the file from which the + module was loaded, if it was loaded from a file. + The :attr:`__file__` + attribute may be missing for certain types of modules, such as C modules + that are statically linked into the interpreter. For extension modules + loaded dynamically from a shared library, it's the pathname of the shared + library file. - .. index:: single: __dict__ (module attribute) + :attr:`__annotations__` + A dictionary containing + :term:`variable annotations <variable annotation>` collected during + module body execution. For best practices on working + with :attr:`__annotations__`, please see :ref:`annotations-howto`. - Special read-only attribute: :attr:`~object.__dict__` is the module's - namespace as a dictionary object. +.. index:: single: __dict__ (module attribute) - .. impl-detail:: +Special read-only attribute: :attr:`~object.__dict__` is the module's +namespace as a dictionary object. + +.. impl-detail:: + + Because of the way CPython clears module dictionaries, the module + dictionary will be cleared when the module falls out of scope even if the + dictionary still has live references. To avoid this, copy the dictionary + or keep the module around while using its dictionary directly. - Because of the way CPython clears module dictionaries, the module - dictionary will be cleared when the module falls out of scope even if the - dictionary still has live references. To avoid this, copy the dictionary - or keep the module around while using its dictionary directly. Custom classes - Custom class types are typically created by class definitions (see section - :ref:`class`). A class has a namespace implemented by a dictionary object. - Class attribute references are translated to lookups in this dictionary, e.g., - ``C.x`` is translated to ``C.__dict__["x"]`` (although there are a number of - hooks which allow for other means of locating attributes). When the attribute - name is not found there, the attribute search continues in the base classes. - This search of the base classes uses the C3 method resolution order which - behaves correctly even in the presence of 'diamond' inheritance structures - where there are multiple inheritance paths leading back to a common ancestor. - Additional details on the C3 MRO used by Python can be found in the - documentation accompanying the 2.3 release at - https://www.python.org/download/releases/2.3/mro/. - - .. XXX: Could we add that MRO doc as an appendix to the language ref? +-------------- + +Custom class types are typically created by class definitions (see section +:ref:`class`). A class has a namespace implemented by a dictionary object. +Class attribute references are translated to lookups in this dictionary, e.g., +``C.x`` is translated to ``C.__dict__["x"]`` (although there are a number of +hooks which allow for other means of locating attributes). When the attribute +name is not found there, the attribute search continues in the base classes. +This search of the base classes uses the C3 method resolution order which +behaves correctly even in the presence of 'diamond' inheritance structures +where there are multiple inheritance paths leading back to a common ancestor. +Additional details on the C3 MRO used by Python can be found in the +documentation accompanying the 2.3 release at +https://www.python.org/download/releases/2.3/mro/. + +.. XXX: Could we add that MRO doc as an appendix to the language ref? - .. index:: - object: class - object: class instance - object: instance - pair: class object; call - single: container - object: dictionary - pair: class; attribute +.. index:: + pair: object; class + pair: object; class instance + pair: object; instance + pair: class object; call + single: container + pair: object; dictionary + pair: class; attribute - When a class attribute reference (for class :class:`C`, say) would yield a - class method object, it is transformed into an instance method object whose - :attr:`__self__` attribute is :class:`C`. When it would yield a static - method object, it is transformed into the object wrapped by the static method - object. See section :ref:`descriptors` for another way in which attributes - retrieved from a class may differ from those actually contained in its - :attr:`~object.__dict__`. +When a class attribute reference (for class :class:`C`, say) would yield a +class method object, it is transformed into an instance method object whose +:attr:`__self__` attribute is :class:`C`. When it would yield a static +method object, it is transformed into the object wrapped by the static method +object. See section :ref:`descriptors` for another way in which attributes +retrieved from a class may differ from those actually contained in its +:attr:`~object.__dict__`. - .. index:: triple: class; attribute; assignment +.. index:: triple: class; attribute; assignment - Class attribute assignments update the class's dictionary, never the dictionary - of a base class. +Class attribute assignments update the class's dictionary, never the dictionary +of a base class. - .. index:: pair: class object; call +.. index:: pair: class object; call - A class object can be called (see above) to yield a class instance (see below). +A class object can be called (see above) to yield a class instance (see below). - .. index:: - single: __name__ (class attribute) - single: __module__ (class attribute) - single: __dict__ (class attribute) - single: __bases__ (class attribute) - single: __doc__ (class attribute) - single: __annotations__ (class attribute) +.. index:: + single: __name__ (class attribute) + single: __module__ (class attribute) + single: __dict__ (class attribute) + single: __bases__ (class attribute) + single: __doc__ (class attribute) + single: __annotations__ (class attribute) + single: __type_params__ (class attribute) - Special attributes: +Special attributes: - :attr:`~definition.__name__` - The class name. + :attr:`~definition.__name__` + The class name. - :attr:`__module__` - The name of the module in which the class was defined. + :attr:`__module__` + The name of the module in which the class was defined. - :attr:`~object.__dict__` - The dictionary containing the class's namespace. + :attr:`~object.__dict__` + The dictionary containing the class's namespace. - :attr:`~class.__bases__` - A tuple containing the base classes, in the order of - their occurrence in the base class list. + :attr:`~class.__bases__` + A tuple containing the base classes, in the order of + their occurrence in the base class list. - :attr:`__doc__` - The class's documentation string, or ``None`` if undefined. + :attr:`__doc__` + The class's documentation string, or ``None`` if undefined. + + :attr:`__annotations__` + A dictionary containing + :term:`variable annotations <variable annotation>` + collected during class body execution. For best practices on + working with :attr:`__annotations__`, please see + :ref:`annotations-howto`. + + :attr:`__type_params__` + A tuple containing the :ref:`type parameters <type-params>` of + a :ref:`generic class <generic-classes>`. - :attr:`__annotations__` - A dictionary containing - :term:`variable annotations <variable annotation>` - collected during class body execution. For best practices on - working with :attr:`__annotations__`, please see - :ref:`annotations-howto`. Class instances - .. index:: - object: class instance - object: instance - pair: class; instance - pair: class instance; attribute - - A class instance is created by calling a class object (see above). A class - instance has a namespace implemented as a dictionary which is the first place - in which attribute references are searched. When an attribute is not found - there, and the instance's class has an attribute by that name, the search - continues with the class attributes. If a class attribute is found that is a - user-defined function object, it is transformed into an instance method - object whose :attr:`__self__` attribute is the instance. Static method and - class method objects are also transformed; see above under "Classes". See - section :ref:`descriptors` for another way in which attributes of a class - retrieved via its instances may differ from the objects actually stored in - the class's :attr:`~object.__dict__`. If no class attribute is found, and the - object's class has a :meth:`~object.__getattr__` method, that is called to satisfy - the lookup. - - .. index:: triple: class instance; attribute; assignment - - Attribute assignments and deletions update the instance's dictionary, never a - class's dictionary. If the class has a :meth:`~object.__setattr__` or - :meth:`~object.__delattr__` method, this is called instead of updating the instance - dictionary directly. +--------------- - .. index:: - object: numeric - object: sequence - object: mapping +.. index:: + pair: object; class instance + pair: object; instance + pair: class; instance + pair: class instance; attribute + +A class instance is created by calling a class object (see above). A class +instance has a namespace implemented as a dictionary which is the first place +in which attribute references are searched. When an attribute is not found +there, and the instance's class has an attribute by that name, the search +continues with the class attributes. If a class attribute is found that is a +user-defined function object, it is transformed into an instance method +object whose :attr:`__self__` attribute is the instance. Static method and +class method objects are also transformed; see above under "Classes". See +section :ref:`descriptors` for another way in which attributes of a class +retrieved via its instances may differ from the objects actually stored in +the class's :attr:`~object.__dict__`. If no class attribute is found, and the +object's class has a :meth:`~object.__getattr__` method, that is called to satisfy +the lookup. + +.. index:: triple: class instance; attribute; assignment + +Attribute assignments and deletions update the instance's dictionary, never a +class's dictionary. If the class has a :meth:`~object.__setattr__` or +:meth:`~object.__delattr__` method, this is called instead of updating the instance +dictionary directly. - Class instances can pretend to be numbers, sequences, or mappings if they have - methods with certain special names. See section :ref:`specialnames`. +.. index:: + pair: object; numeric + pair: object; sequence + pair: object; mapping - .. index:: - single: __dict__ (instance attribute) - single: __class__ (instance attribute) +Class instances can pretend to be numbers, sequences, or mappings if they have +methods with certain special names. See section :ref:`specialnames`. + +.. index:: + single: __dict__ (instance attribute) + single: __class__ (instance attribute) + +Special attributes: :attr:`~object.__dict__` is the attribute dictionary; +:attr:`~instance.__class__` is the instance's class. - Special attributes: :attr:`~object.__dict__` is the attribute dictionary; - :attr:`~instance.__class__` is the instance's class. I/O objects (also known as file objects) - .. index:: - builtin: open - module: io - single: popen() (in module os) - single: makefile() (socket method) - single: sys.stdin - single: sys.stdout - single: sys.stderr - single: stdio - single: stdin (in module sys) - single: stdout (in module sys) - single: stderr (in module sys) - - A :term:`file object` represents an open file. Various shortcuts are - available to create file objects: the :func:`open` built-in function, and - also :func:`os.popen`, :func:`os.fdopen`, and the - :meth:`~socket.socket.makefile` method of socket objects (and perhaps by - other functions or methods provided by extension modules). - - The objects ``sys.stdin``, ``sys.stdout`` and ``sys.stderr`` are - initialized to file objects corresponding to the interpreter's standard - input, output and error streams; they are all open in text mode and - therefore follow the interface defined by the :class:`io.TextIOBase` - abstract class. +---------------------------------------- + +.. index:: + pair: built-in function; open + pair: module; io + single: popen() (in module os) + single: makefile() (socket method) + single: sys.stdin + single: sys.stdout + single: sys.stderr + single: stdio + single: stdin (in module sys) + single: stdout (in module sys) + single: stderr (in module sys) + +A :term:`file object` represents an open file. Various shortcuts are +available to create file objects: the :func:`open` built-in function, and +also :func:`os.popen`, :func:`os.fdopen`, and the +:meth:`~socket.socket.makefile` method of socket objects (and perhaps by +other functions or methods provided by extension modules). + +The objects ``sys.stdin``, ``sys.stdout`` and ``sys.stderr`` are +initialized to file objects corresponding to the interpreter's standard +input, output and error streams; they are all open in text mode and +therefore follow the interface defined by the :class:`io.TextIOBase` +abstract class. + Internal types - .. index:: - single: internal type - single: types, internal - - A few types used internally by the interpreter are exposed to the user. Their - definitions may change with future versions of the interpreter, but they are - mentioned here for completeness. - - .. index:: bytecode, object; code, code object - - Code objects - Code objects represent *byte-compiled* executable Python code, or :term:`bytecode`. - The difference between a code object and a function object is that the function - object contains an explicit reference to the function's globals (the module in - which it was defined), while a code object contains no context; also the default - argument values are stored in the function object, not in the code object - (because they represent values calculated at run-time). Unlike function - objects, code objects are immutable and contain no references (directly or - indirectly) to mutable objects. - - .. index:: - single: co_argcount (code object attribute) - single: co_posonlyargcount (code object attribute) - single: co_kwonlyargcount (code object attribute) - single: co_code (code object attribute) - single: co_consts (code object attribute) - single: co_filename (code object attribute) - single: co_firstlineno (code object attribute) - single: co_flags (code object attribute) - single: co_lnotab (code object attribute) - single: co_name (code object attribute) - single: co_names (code object attribute) - single: co_nlocals (code object attribute) - single: co_stacksize (code object attribute) - single: co_varnames (code object attribute) - single: co_cellvars (code object attribute) - single: co_freevars (code object attribute) - single: co_qualname (code object attribute) - - Special read-only attributes: :attr:`co_name` gives the function name; - :attr:`co_qualname` gives the fully qualified function name; - :attr:`co_argcount` is the total number of positional arguments - (including positional-only arguments and arguments with default values); - :attr:`co_posonlyargcount` is the number of positional-only arguments - (including arguments with default values); :attr:`co_kwonlyargcount` is - the number of keyword-only arguments (including arguments with default - values); :attr:`co_nlocals` is the number of local variables used by the - function (including arguments); :attr:`co_varnames` is a tuple containing - the names of the local variables (starting with the argument names); - :attr:`co_cellvars` is a tuple containing the names of local variables - that are referenced by nested functions; :attr:`co_freevars` is a tuple - containing the names of free variables; :attr:`co_code` is a string - representing the sequence of bytecode instructions; :attr:`co_consts` is - a tuple containing the literals used by the bytecode; :attr:`co_names` is - a tuple containing the names used by the bytecode; :attr:`co_filename` is - the filename from which the code was compiled; :attr:`co_firstlineno` is - the first line number of the function; :attr:`co_lnotab` is a string - encoding the mapping from bytecode offsets to line numbers (for details - see the source code of the interpreter); :attr:`co_stacksize` is the - required stack size; :attr:`co_flags` is an integer encoding a number - of flags for the interpreter. - - .. index:: object: generator - - The following flag bits are defined for :attr:`co_flags`: bit ``0x04`` is set if - the function uses the ``*arguments`` syntax to accept an arbitrary number of - positional arguments; bit ``0x08`` is set if the function uses the - ``**keywords`` syntax to accept arbitrary keyword arguments; bit ``0x20`` is set - if the function is a generator. - - Future feature declarations (``from __future__ import division``) also use bits - in :attr:`co_flags` to indicate whether a code object was compiled with a - particular feature enabled: bit ``0x2000`` is set if the function was compiled - with future division enabled; bits ``0x10`` and ``0x1000`` were used in earlier - versions of Python. - - Other bits in :attr:`co_flags` are reserved for internal use. - - .. index:: single: documentation string - - If a code object represents a function, the first item in :attr:`co_consts` is - the documentation string of the function, or ``None`` if undefined. - - .. method:: codeobject.co_positions() - - Returns an iterable over the source code positions of each bytecode - instruction in the code object. - - The iterator returns tuples containing the ``(start_line, end_line, - start_column, end_column)``. The *i-th* tuple corresponds to the - position of the source code that compiled to the *i-th* instruction. - Column information is 0-indexed utf-8 byte offsets on the given source - line. - - This positional information can be missing. A non-exhaustive lists of - cases where this may happen: - - - Running the interpreter with :option:`-X` ``no_debug_ranges``. - - Loading a pyc file compiled while using :option:`-X` ``no_debug_ranges``. - - Position tuples corresponding to artificial instructions. - - Line and column numbers that can't be represented due to - implementation specific limitations. - - When this occurs, some or all of the tuple elements can be - :const:`None`. - - .. versionadded:: 3.11 - - .. note:: - This feature requires storing column positions in code objects which may - result in a small increase of disk usage of compiled Python files or - interpreter memory usage. To avoid storing the extra information and/or - deactivate printing the extra traceback information, the - :option:`-X` ``no_debug_ranges`` command line flag or the :envvar:`PYTHONNODEBUGRANGES` - environment variable can be used. - - .. _frame-objects: - - Frame objects - .. index:: object: frame - - Frame objects represent execution frames. They may occur in traceback objects - (see below), and are also passed to registered trace functions. - - .. index:: - single: f_back (frame attribute) - single: f_code (frame attribute) - single: f_globals (frame attribute) - single: f_locals (frame attribute) - single: f_lasti (frame attribute) - single: f_builtins (frame attribute) - - Special read-only attributes: :attr:`f_back` is to the previous stack frame - (towards the caller), or ``None`` if this is the bottom stack frame; - :attr:`f_code` is the code object being executed in this frame; :attr:`f_locals` - is the dictionary used to look up local variables; :attr:`f_globals` is used for - global variables; :attr:`f_builtins` is used for built-in (intrinsic) names; - :attr:`f_lasti` gives the precise instruction (this is an index into the - bytecode string of the code object). - - Accessing ``f_code`` raises an :ref:`auditing event <auditing>` - ``object.__getattr__`` with arguments ``obj`` and ``"f_code"``. - - .. index:: - single: f_trace (frame attribute) - single: f_trace_lines (frame attribute) - single: f_trace_opcodes (frame attribute) - single: f_lineno (frame attribute) - - Special writable attributes: :attr:`f_trace`, if not ``None``, is a function - called for various events during code execution (this is used by the debugger). - Normally an event is triggered for each new source line - this can be - disabled by setting :attr:`f_trace_lines` to :const:`False`. - - Implementations *may* allow per-opcode events to be requested by setting - :attr:`f_trace_opcodes` to :const:`True`. Note that this may lead to - undefined interpreter behaviour if exceptions raised by the trace - function escape to the function being traced. - - :attr:`f_lineno` is the current line number of the frame --- writing to this - from within a trace function jumps to the given line (only for the bottom-most - frame). A debugger can implement a Jump command (aka Set Next Statement) - by writing to f_lineno. - - Frame objects support one method: - - .. method:: frame.clear() - - This method clears all references to local variables held by the - frame. Also, if the frame belonged to a generator, the generator - is finalized. This helps break reference cycles involving frame - objects (for example when catching an exception and storing its - traceback for later use). - - :exc:`RuntimeError` is raised if the frame is currently executing. - - .. versionadded:: 3.4 - - .. _traceback-objects: - - Traceback objects - .. index:: - object: traceback - pair: stack; trace - pair: exception; handler - pair: execution; stack - single: exc_info (in module sys) - single: last_traceback (in module sys) - single: sys.exc_info - single: sys.last_traceback - - Traceback objects represent a stack trace of an exception. A traceback object - is implicitly created when an exception occurs, and may also be explicitly - created by calling :class:`types.TracebackType`. - - For implicitly created tracebacks, when the search for an exception handler - unwinds the execution stack, at each unwound level a traceback object is - inserted in front of the current traceback. When an exception handler is - entered, the stack trace is made available to the program. (See section - :ref:`try`.) It is accessible as the third item of the - tuple returned by ``sys.exc_info()``, and as the ``__traceback__`` attribute - of the caught exception. - - When the program contains no suitable - handler, the stack trace is written (nicely formatted) to the standard error - stream; if the interpreter is interactive, it is also made available to the user - as ``sys.last_traceback``. - - For explicitly created tracebacks, it is up to the creator of the traceback - to determine how the ``tb_next`` attributes should be linked to form a - full stack trace. - - .. index:: - single: tb_frame (traceback attribute) - single: tb_lineno (traceback attribute) - single: tb_lasti (traceback attribute) - statement: try - - Special read-only attributes: - :attr:`tb_frame` points to the execution frame of the current level; - :attr:`tb_lineno` gives the line number where the exception occurred; - :attr:`tb_lasti` indicates the precise instruction. - The line number and last instruction in the traceback may differ from the - line number of its frame object if the exception occurred in a - :keyword:`try` statement with no matching except clause or with a - finally clause. - - Accessing ``tb_frame`` raises an :ref:`auditing event <auditing>` - ``object.__getattr__`` with arguments ``obj`` and ``"tb_frame"``. - - .. index:: - single: tb_next (traceback attribute) - - Special writable attribute: :attr:`tb_next` is the next level in the stack - trace (towards the frame where the exception occurred), or ``None`` if - there is no next level. - - .. versionchanged:: 3.7 - Traceback objects can now be explicitly instantiated from Python code, - and the ``tb_next`` attribute of existing instances can be updated. - - Slice objects - .. index:: builtin: slice - - Slice objects are used to represent slices for - :meth:`~object.__getitem__` - methods. They are also created by the built-in :func:`slice` function. - - .. index:: - single: start (slice object attribute) - single: stop (slice object attribute) - single: step (slice object attribute) - - Special read-only attributes: :attr:`~slice.start` is the lower bound; - :attr:`~slice.stop` is the upper bound; :attr:`~slice.step` is the step - value; each is ``None`` if omitted. These attributes can have any type. - - Slice objects support one method: - - .. method:: slice.indices(self, length) - - This method takes a single integer argument *length* and computes - information about the slice that the slice object would describe if - applied to a sequence of *length* items. It returns a tuple of three - integers; respectively these are the *start* and *stop* indices and the - *step* or stride length of the slice. Missing or out-of-bounds indices - are handled in a manner consistent with regular slices. - - Static method objects - Static method objects provide a way of defeating the transformation of function - objects to method objects described above. A static method object is a wrapper - around any other object, usually a user-defined method object. When a static - method object is retrieved from a class or a class instance, the object actually - returned is the wrapped object, which is not subject to any further - transformation. Static method objects are also callable. Static method - objects are created by the built-in :func:`staticmethod` constructor. - - Class method objects - A class method object, like a static method object, is a wrapper around another - object that alters the way in which that object is retrieved from classes and - class instances. The behaviour of class method objects upon such retrieval is - described above, under "User-defined methods". Class method objects are created - by the built-in :func:`classmethod` constructor. +-------------- + +.. index:: + single: internal type + single: types, internal + +A few types used internally by the interpreter are exposed to the user. Their +definitions may change with future versions of the interpreter, but they are +mentioned here for completeness. + + +.. _code-objects: + +Code objects +^^^^^^^^^^^^ + +.. index:: bytecode, object; code, code object + +Code objects represent *byte-compiled* executable Python code, or :term:`bytecode`. +The difference between a code object and a function object is that the function +object contains an explicit reference to the function's globals (the module in +which it was defined), while a code object contains no context; also the default +argument values are stored in the function object, not in the code object +(because they represent values calculated at run-time). Unlike function +objects, code objects are immutable and contain no references (directly or +indirectly) to mutable objects. + +.. index:: + single: co_argcount (code object attribute) + single: co_posonlyargcount (code object attribute) + single: co_kwonlyargcount (code object attribute) + single: co_code (code object attribute) + single: co_consts (code object attribute) + single: co_filename (code object attribute) + single: co_firstlineno (code object attribute) + single: co_flags (code object attribute) + single: co_lnotab (code object attribute) + single: co_name (code object attribute) + single: co_names (code object attribute) + single: co_nlocals (code object attribute) + single: co_stacksize (code object attribute) + single: co_varnames (code object attribute) + single: co_cellvars (code object attribute) + single: co_freevars (code object attribute) + single: co_qualname (code object attribute) + +Special read-only attributes: :attr:`co_name` gives the function name; +:attr:`co_qualname` gives the fully qualified function name; +:attr:`co_argcount` is the total number of positional arguments +(including positional-only arguments and arguments with default values); +:attr:`co_posonlyargcount` is the number of positional-only arguments +(including arguments with default values); :attr:`co_kwonlyargcount` is +the number of keyword-only arguments (including arguments with default +values); :attr:`co_nlocals` is the number of local variables used by the +function (including arguments); :attr:`co_varnames` is a tuple containing +the names of the local variables (starting with the argument names); +:attr:`co_cellvars` is a tuple containing the names of local variables +that are referenced by nested functions; :attr:`co_freevars` is a tuple +containing the names of free variables; :attr:`co_code` is a string +representing the sequence of bytecode instructions; :attr:`co_consts` is +a tuple containing the literals used by the bytecode; :attr:`co_names` is +a tuple containing the names used by the bytecode; :attr:`co_filename` is +the filename from which the code was compiled; :attr:`co_firstlineno` is +the first line number of the function; :attr:`co_lnotab` is a string +encoding the mapping from bytecode offsets to line numbers (for details +see the source code of the interpreter, is deprecated since 3.12 +and may be removed in 3.14); :attr:`co_stacksize` is the +required stack size; :attr:`co_flags` is an integer encoding a number +of flags for the interpreter. + +.. index:: pair: object; generator + +The following flag bits are defined for :attr:`co_flags`: bit ``0x04`` is set if +the function uses the ``*arguments`` syntax to accept an arbitrary number of +positional arguments; bit ``0x08`` is set if the function uses the +``**keywords`` syntax to accept arbitrary keyword arguments; bit ``0x20`` is set +if the function is a generator. + +Future feature declarations (``from __future__ import division``) also use bits +in :attr:`co_flags` to indicate whether a code object was compiled with a +particular feature enabled: bit ``0x2000`` is set if the function was compiled +with future division enabled; bits ``0x10`` and ``0x1000`` were used in earlier +versions of Python. + +Other bits in :attr:`co_flags` are reserved for internal use. + +.. index:: single: documentation string + +If a code object represents a function, the first item in :attr:`co_consts` is +the documentation string of the function, or ``None`` if undefined. + +.. method:: codeobject.co_positions() + + Returns an iterable over the source code positions of each bytecode + instruction in the code object. + + The iterator returns tuples containing the ``(start_line, end_line, + start_column, end_column)``. The *i-th* tuple corresponds to the + position of the source code that compiled to the *i-th* instruction. + Column information is 0-indexed utf-8 byte offsets on the given source + line. + + This positional information can be missing. A non-exhaustive lists of + cases where this may happen: + + - Running the interpreter with :option:`-X` ``no_debug_ranges``. + - Loading a pyc file compiled while using :option:`-X` ``no_debug_ranges``. + - Position tuples corresponding to artificial instructions. + - Line and column numbers that can't be represented due to + implementation specific limitations. + + When this occurs, some or all of the tuple elements can be + :const:`None`. + + .. versionadded:: 3.11 + + .. note:: + This feature requires storing column positions in code objects which may + result in a small increase of disk usage of compiled Python files or + interpreter memory usage. To avoid storing the extra information and/or + deactivate printing the extra traceback information, the + :option:`-X` ``no_debug_ranges`` command line flag or the :envvar:`PYTHONNODEBUGRANGES` + environment variable can be used. + + +.. _frame-objects: + +Frame objects +^^^^^^^^^^^^^ + +.. index:: pair: object; frame + +Frame objects represent execution frames. They may occur in traceback objects +(see below), and are also passed to registered trace functions. + +.. index:: + single: f_back (frame attribute) + single: f_code (frame attribute) + single: f_globals (frame attribute) + single: f_locals (frame attribute) + single: f_lasti (frame attribute) + single: f_builtins (frame attribute) + +Special read-only attributes: :attr:`f_back` is to the previous stack frame +(towards the caller), or ``None`` if this is the bottom stack frame; +:attr:`f_code` is the code object being executed in this frame; :attr:`f_locals` +is the dictionary used to look up local variables; :attr:`f_globals` is used for +global variables; :attr:`f_builtins` is used for built-in (intrinsic) names; +:attr:`f_lasti` gives the precise instruction (this is an index into the +bytecode string of the code object). + +Accessing ``f_code`` raises an :ref:`auditing event <auditing>` +``object.__getattr__`` with arguments ``obj`` and ``"f_code"``. + +.. index:: + single: f_trace (frame attribute) + single: f_trace_lines (frame attribute) + single: f_trace_opcodes (frame attribute) + single: f_lineno (frame attribute) + +Special writable attributes: :attr:`f_trace`, if not ``None``, is a function +called for various events during code execution (this is used by the debugger). +Normally an event is triggered for each new source line - this can be +disabled by setting :attr:`f_trace_lines` to :const:`False`. + +Implementations *may* allow per-opcode events to be requested by setting +:attr:`f_trace_opcodes` to :const:`True`. Note that this may lead to +undefined interpreter behaviour if exceptions raised by the trace +function escape to the function being traced. + +:attr:`f_lineno` is the current line number of the frame --- writing to this +from within a trace function jumps to the given line (only for the bottom-most +frame). A debugger can implement a Jump command (aka Set Next Statement) +by writing to f_lineno. + +Frame objects support one method: + +.. method:: frame.clear() + + This method clears all references to local variables held by the + frame. Also, if the frame belonged to a generator, the generator + is finalized. This helps break reference cycles involving frame + objects (for example when catching an exception and storing its + traceback for later use). + + :exc:`RuntimeError` is raised if the frame is currently executing. + + .. versionadded:: 3.4 + + +.. _traceback-objects: + +Traceback objects +^^^^^^^^^^^^^^^^^ + +.. index:: + pair: object; traceback + pair: stack; trace + pair: exception; handler + pair: execution; stack + single: exc_info (in module sys) + single: last_traceback (in module sys) + single: sys.exc_info + single: sys.exception + single: sys.last_traceback + +Traceback objects represent a stack trace of an exception. A traceback object +is implicitly created when an exception occurs, and may also be explicitly +created by calling :class:`types.TracebackType`. + +For implicitly created tracebacks, when the search for an exception handler +unwinds the execution stack, at each unwound level a traceback object is +inserted in front of the current traceback. When an exception handler is +entered, the stack trace is made available to the program. (See section +:ref:`try`.) It is accessible as the third item of the +tuple returned by ``sys.exc_info()``, and as the ``__traceback__`` attribute +of the caught exception. + +When the program contains no suitable +handler, the stack trace is written (nicely formatted) to the standard error +stream; if the interpreter is interactive, it is also made available to the user +as ``sys.last_traceback``. + +For explicitly created tracebacks, it is up to the creator of the traceback +to determine how the ``tb_next`` attributes should be linked to form a +full stack trace. + +.. index:: + single: tb_frame (traceback attribute) + single: tb_lineno (traceback attribute) + single: tb_lasti (traceback attribute) + pair: statement; try + +Special read-only attributes: +:attr:`tb_frame` points to the execution frame of the current level; +:attr:`tb_lineno` gives the line number where the exception occurred; +:attr:`tb_lasti` indicates the precise instruction. +The line number and last instruction in the traceback may differ from the +line number of its frame object if the exception occurred in a +:keyword:`try` statement with no matching except clause or with a +finally clause. + +Accessing ``tb_frame`` raises an :ref:`auditing event <auditing>` +``object.__getattr__`` with arguments ``obj`` and ``"tb_frame"``. + +.. index:: + single: tb_next (traceback attribute) + +Special writable attribute: :attr:`tb_next` is the next level in the stack +trace (towards the frame where the exception occurred), or ``None`` if +there is no next level. + +.. versionchanged:: 3.7 + Traceback objects can now be explicitly instantiated from Python code, + and the ``tb_next`` attribute of existing instances can be updated. + + +Slice objects +^^^^^^^^^^^^^ + +.. index:: pair: built-in function; slice + +Slice objects are used to represent slices for +:meth:`~object.__getitem__` +methods. They are also created by the built-in :func:`slice` function. + +.. index:: + single: start (slice object attribute) + single: stop (slice object attribute) + single: step (slice object attribute) + +Special read-only attributes: :attr:`~slice.start` is the lower bound; +:attr:`~slice.stop` is the upper bound; :attr:`~slice.step` is the step +value; each is ``None`` if omitted. These attributes can have any type. + +Slice objects support one method: + +.. method:: slice.indices(self, length) + + This method takes a single integer argument *length* and computes + information about the slice that the slice object would describe if + applied to a sequence of *length* items. It returns a tuple of three + integers; respectively these are the *start* and *stop* indices and the + *step* or stride length of the slice. Missing or out-of-bounds indices + are handled in a manner consistent with regular slices. + + +Static method objects +^^^^^^^^^^^^^^^^^^^^^ + +Static method objects provide a way of defeating the transformation of function +objects to method objects described above. A static method object is a wrapper +around any other object, usually a user-defined method object. When a static +method object is retrieved from a class or a class instance, the object actually +returned is the wrapped object, which is not subject to any further +transformation. Static method objects are also callable. Static method +objects are created by the built-in :func:`staticmethod` constructor. + + +Class method objects +^^^^^^^^^^^^^^^^^^^^ + +A class method object, like a static method object, is a wrapper around another +object that alters the way in which that object is retrieved from classes and +class instances. The behaviour of class method objects upon such retrieval is +described above, under "User-defined methods". Class method objects are created +by the built-in :func:`classmethod` constructor. .. _specialnames: @@ -1308,7 +1428,7 @@ Basic customization .. index:: single: destructor single: finalizer - statement: del + pair: statement; del Called when the instance is about to be destroyed. This is also called a finalizer or (improperly) a destructor. If a base class has a @@ -1409,7 +1529,7 @@ Basic customization .. method:: object.__bytes__(self) - .. index:: builtin: bytes + .. index:: pair: built-in function; bytes Called by :ref:`bytes <func-bytes>` to compute a byte-string representation of an object. This should return a :class:`bytes` object. @@ -1417,7 +1537,7 @@ Basic customization .. index:: single: string; __format__() (object method) pair: string; conversion - builtin: print + pair: built-in function; print .. method:: object.__format__(self, format_spec) @@ -1496,8 +1616,8 @@ Basic customization .. method:: object.__hash__(self) .. index:: - object: dictionary - builtin: hash + pair: object; dictionary + pair: built-in function; hash Called by built-in function :func:`hash` and for operations on members of hashed collections including :class:`set`, :class:`frozenset`, and @@ -1525,7 +1645,7 @@ Basic customization :meth:`__hash__`, its instances will not be usable as items in hashable collections. If a class defines mutable objects and implements an :meth:`__eq__` method, it should not implement :meth:`__hash__`, since the - implementation of hashable collections requires that a key's hash value is + implementation of :term:`hashable` collections requires that a key's hash value is immutable (if the object's hash value changes, it will be in the wrong hash bucket). @@ -1562,7 +1682,7 @@ Basic customization This is intended to provide protection against a denial-of-service caused by carefully chosen inputs that exploit the worst case performance of a dict insertion, O(n\ :sup:`2`) complexity. See - http://www.ocert.org/advisories/ocert-2011-003.html for details. + http://ocert.org/advisories/ocert-2011-003.html for details. Changing hash values affects the iteration order of sets. Python has never made guarantees about this ordering @@ -1580,9 +1700,9 @@ Basic customization Called to implement truth value testing and the built-in operation ``bool()``; should return ``False`` or ``True``. When this method is not - defined, :meth:`__len__` is called, if it is defined, and the object is + defined, :meth:`~object.__len__` is called, if it is defined, and the object is considered true if its result is nonzero. If a class defines neither - :meth:`__len__` nor :meth:`__bool__`, all its instances are considered + :meth:`!__len__` nor :meth:`!__bool__`, all its instances are considered true. @@ -1906,8 +2026,7 @@ Attribute lookup speed can be significantly improved as well. .. _datamodel-note-slots: -Notes on using *__slots__* -"""""""""""""""""""""""""" +Notes on using *__slots__*: * When inheriting from a class without *__slots__*, the :attr:`~object.__dict__` and @@ -1943,8 +2062,10 @@ Notes on using *__slots__* descriptor directly from the base class). This renders the meaning of the program undefined. In the future, a check may be added to prevent this. -* Nonempty *__slots__* does not work for classes derived from "variable-length" - built-in types such as :class:`int`, :class:`bytes` and :class:`tuple`. +* :exc:`TypeError` will be raised if nonempty *__slots__* are defined for a + class derived from a + :c:member:`"variable-length" built-in type <PyTypeObject.tp_itemsize>` such as + :class:`int`, :class:`bytes`, and :class:`tuple`. * Any non-string :term:`iterable` may be assigned to *__slots__*. @@ -2046,7 +2167,7 @@ Metaclasses .. index:: single: metaclass - builtin: type + pair: built-in function; type single: = (equals); class definition By default, classes are constructed using :func:`type`. The class body is @@ -2082,15 +2203,28 @@ When a class definition is executed, the following steps occur: Resolving MRO entries ^^^^^^^^^^^^^^^^^^^^^ -If a base that appears in class definition is not an instance of :class:`type`, -then an ``__mro_entries__`` method is searched on it. If found, it is called -with the original bases tuple. This method must return a tuple of classes that -will be used instead of this base. The tuple may be empty, in such case -the original base is ignored. +.. method:: object.__mro_entries__(self, bases) + + If a base that appears in a class definition is not an instance of + :class:`type`, then an :meth:`!__mro_entries__` method is searched on the base. + If an :meth:`!__mro_entries__` method is found, the base is substituted with the + result of a call to :meth:`!__mro_entries__` when creating the class. + The method is called with the original bases tuple + passed to the *bases* parameter, and must return a tuple + of classes that will be used instead of the base. The returned tuple may be + empty: in these cases, the original base is ignored. .. seealso:: - :pep:`560` - Core support for typing module and generic types + :func:`types.resolve_bases` + Dynamically resolve bases that are not instances of :class:`type`. + + :func:`types.get_original_bases` + Retrieve a class's "original bases" prior to modifications by + :meth:`~object.__mro_entries__`. + + :pep:`560` + Core support for typing module and generic types. Determining the appropriate metaclass @@ -2460,21 +2594,21 @@ through the object's keys; for sequences, it should iterate through the values. .. method:: object.__len__(self) .. index:: - builtin: len + pair: built-in function; len single: __bool__() (object method) Called to implement the built-in function :func:`len`. Should return the length of the object, an integer ``>=`` 0. Also, an object that doesn't define a - :meth:`__bool__` method and whose :meth:`__len__` method returns zero is + :meth:`~object.__bool__` method and whose :meth:`!__len__` method returns zero is considered to be false in a Boolean context. .. impl-detail:: - In CPython, the length is required to be at most :attr:`sys.maxsize`. - If the length is larger than :attr:`!sys.maxsize` some features (such as + In CPython, the length is required to be at most :data:`sys.maxsize`. + If the length is larger than :data:`!sys.maxsize` some features (such as :func:`len`) may raise :exc:`OverflowError`. To prevent raising :exc:`!OverflowError` by truth value testing, an object must define a - :meth:`__bool__` method. + :meth:`~object.__bool__` method. .. method:: object.__length_hint__(self) @@ -2489,7 +2623,7 @@ through the object's keys; for sequences, it should iterate through the values. .. versionadded:: 3.4 -.. index:: object: slice +.. index:: pair: object; slice .. note:: @@ -2618,9 +2752,9 @@ left undefined. object.__or__(self, other) .. index:: - builtin: divmod - builtin: pow - builtin: pow + pair: built-in function; divmod + pair: built-in function; pow + pair: built-in function; pow These methods are called to implement the binary arithmetic operations (``+``, ``-``, ``*``, ``@``, ``/``, ``//``, ``%``, :func:`divmod`, @@ -2653,8 +2787,8 @@ left undefined. object.__ror__(self, other) .. index:: - builtin: divmod - builtin: pow + pair: built-in function; divmod + pair: built-in function; pow These methods are called to implement the binary arithmetic operations (``+``, ``-``, ``*``, ``@``, ``/``, ``//``, ``%``, :func:`divmod`, @@ -2666,7 +2800,7 @@ left undefined. ``type(y).__rsub__(y, x)`` is called if ``type(x).__sub__(x, y)`` returns *NotImplemented*. - .. index:: builtin: pow + .. index:: pair: built-in function; pow Note that ternary :func:`pow` will not try calling :meth:`__rpow__` (the coercion rules would become too complicated). @@ -2713,7 +2847,7 @@ left undefined. object.__abs__(self) object.__invert__(self) - .. index:: builtin: abs + .. index:: pair: built-in function; abs Called to implement the unary arithmetic operations (``-``, ``+``, :func:`abs` and ``~``). @@ -2724,9 +2858,9 @@ left undefined. object.__float__(self) .. index:: - builtin: complex - builtin: int - builtin: float + pair: built-in function; complex + pair: built-in function; int + pair: built-in function; float Called to implement the built-in functions :func:`complex`, :func:`int` and :func:`float`. Should return a value @@ -2751,7 +2885,7 @@ left undefined. object.__floor__(self) object.__ceil__(self) - .. index:: builtin: round + .. index:: pair: built-in function; round Called to implement the built-in function :func:`round` and :mod:`math` functions :func:`~math.trunc`, :func:`~math.floor` and :func:`~math.ceil`. @@ -2779,7 +2913,7 @@ execution of the block of code. Context managers are normally invoked using the used by directly invoking their methods. .. index:: - statement: with + pair: statement; with single: context manager Typical uses of context managers include saving and restoring various kinds of @@ -2848,6 +2982,47 @@ a :exc:`TypeError`. The specification for the Python ``match`` statement. +.. _python-buffer-protocol: + +Emulating buffer types +---------------------- + +The :ref:`buffer protocol <bufferobjects>` provides a way for Python +objects to expose efficient access to a low-level memory array. This protocol +is implemented by builtin types such as :class:`bytes` and :class:`memoryview`, +and third-party libraries may define additional buffer types. + +While buffer types are usually implemented in C, it is also possible to +implement the protocol in Python. + +.. method:: object.__buffer__(self, flags) + + Called when a buffer is requested from *self* (for example, by the + :class:`memoryview` constructor). The *flags* argument is an integer + representing the kind of buffer requested, affecting for example whether + the returned buffer is read-only or writable. :class:`inspect.BufferFlags` + provides a convenient way to interpret the flags. The method must return + a :class:`memoryview` object. + +.. method:: object.__release_buffer__(self, buffer) + + Called when a buffer is no longer needed. The *buffer* argument is a + :class:`memoryview` object that was previously returned by + :meth:`~object.__buffer__`. The method must release any resources associated + with the buffer. This method should return ``None``. + Buffer objects that do not need to perform any cleanup are not required + to implement this method. + +.. versionadded:: 3.12 + +.. seealso:: + + :pep:`688` - Making the buffer protocol accessible in Python + Introduces the Python ``__buffer__`` and ``__release_buffer__`` methods. + + :class:`collections.abc.Buffer` + ABC for buffer types. + .. _special-lookup: Special method lookup @@ -3006,6 +3181,11 @@ generators, coroutines do not directly support iteration. above. If the exception is not caught in the coroutine, it propagates back to the caller. + .. versionchanged:: 3.12 + + The second signature \(type\[, value\[, traceback\]\]\) is deprecated and + may be removed in a future version of Python. + .. method:: coroutine.close() Causes the coroutine to clean itself up and exit. If the coroutine diff --git a/Doc/reference/executionmodel.rst b/Doc/reference/executionmodel.rst index a264015c..cea3a56b 100644 --- a/Doc/reference/executionmodel.rst +++ b/Doc/reference/executionmodel.rst @@ -71,6 +71,8 @@ The following constructs bind names: + in a capture pattern in structural pattern matching * :keyword:`import` statements. +* :keyword:`type` statements. +* :ref:`type parameter lists <type-params>`. The :keyword:`!import` statement of the form ``from ... import *`` binds all names defined in the imported module, except those beginning with an underscore. @@ -149,9 +151,10 @@ a global statement, the free variable is treated as a global. The :keyword:`nonlocal` statement causes corresponding names to refer to previously bound variables in the nearest enclosing function scope. :exc:`SyntaxError` is raised at compile time if the given name does not -exist in any enclosing function scope. +exist in any enclosing function scope. :ref:`Type parameters <type-params>` +cannot be rebound with the :keyword:`!nonlocal` statement. -.. index:: module: __main__ +.. index:: pair: module; __main__ The namespace for a module is automatically created the first time a module is imported. The main module for a script is always called :mod:`__main__`. @@ -163,14 +166,119 @@ These references follow the normal rules for name resolution with an exception that unbound local variables are looked up in the global namespace. The namespace of the class definition becomes the attribute dictionary of the class. The scope of names defined in a class block is limited to the -class block; it does not extend to the code blocks of methods -- this includes -comprehensions and generator expressions since they are implemented using a -function scope. This means that the following will fail:: +class block; it does not extend to the code blocks of methods. This includes +comprehensions and generator expressions, but it does not include +:ref:`annotation scopes <annotation-scopes>`, +which have access to their enclosing class scopes. +This means that the following will fail:: class A: a = 42 b = list(a + i for i in range(10)) +However, the following will succeed:: + + class A: + type Alias = Nested + class Nested: pass + + print(A.Alias.__value__) # <type 'A.Nested'> + +.. _annotation-scopes: + +Annotation scopes +----------------- + +:ref:`Type parameter lists <type-params>` and :keyword:`type` statements +introduce *annotation scopes*, which behave mostly like function scopes, +but with some exceptions discussed below. :term:`Annotations <annotation>` +currently do not use annotation scopes, but they are expected to use +annotation scopes in Python 3.13 when :pep:`649` is implemented. + +Annotation scopes are used in the following contexts: + +* Type parameter lists for :ref:`generic type aliases <generic-type-aliases>`. +* Type parameter lists for :ref:`generic functions <generic-functions>`. + A generic function's annotations are + executed within the annotation scope, but its defaults and decorators are not. +* Type parameter lists for :ref:`generic classes <generic-classes>`. + A generic class's base classes and + keyword arguments are executed within the annotation scope, but its decorators are not. +* The bounds and constraints for type variables + (:ref:`lazily evaluated <lazy-evaluation>`). +* The value of type aliases (:ref:`lazily evaluated <lazy-evaluation>`). + +Annotation scopes differ from function scopes in the following ways: + +* Annotation scopes have access to their enclosing class namespace. + If an annotation scope is immediately within a class scope, or within another + annotation scope that is immediately within a class scope, the code in the + annotation scope can use names defined in the class scope as if it were + executed directly within the class body. This contrasts with regular + functions defined within classes, which cannot access names defined in the class scope. +* Expressions in annotation scopes cannot contain :keyword:`yield`, ``yield from``, + :keyword:`await`, or :token:`:= <python-grammar:assignment_expression>` + expressions. (These expressions are allowed in other scopes contained within the + annotation scope.) +* Names defined in annotation scopes cannot be rebound with :keyword:`nonlocal` + statements in inner scopes. This includes only type parameters, as no other + syntactic elements that can appear within annotation scopes can introduce new names. +* While annotation scopes have an internal name, that name is not reflected in the + :term:`__qualname__ <qualified name>` of objects defined within the scope. + Instead, the :attr:`!__qualname__` + of such objects is as if the object were defined in the enclosing scope. + +.. versionadded:: 3.12 + Annotation scopes were introduced in Python 3.12 as part of :pep:`695`. + +.. _lazy-evaluation: + +Lazy evaluation +--------------- + +The values of type aliases created through the :keyword:`type` statement are +*lazily evaluated*. The same applies to the bounds and constraints of type +variables created through the :ref:`type parameter syntax <type-params>`. +This means that they are not evaluated when the type alias or type variable is +created. Instead, they are only evaluated when doing so is necessary to resolve +an attribute access. + +Example: + +.. doctest:: + + >>> type Alias = 1/0 + >>> Alias.__value__ + Traceback (most recent call last): + ... + ZeroDivisionError: division by zero + >>> def func[T: 1/0](): pass + >>> T = func.__type_params__[0] + >>> T.__bound__ + Traceback (most recent call last): + ... + ZeroDivisionError: division by zero + +Here the exception is raised only when the ``__value__`` attribute +of the type alias or the ``__bound__`` attribute of the type variable +is accessed. + +This behavior is primarily useful for references to types that have not +yet been defined when the type alias or type variable is created. For example, +lazy evaluation enables creation of mutually recursive type aliases:: + + from typing import Literal + + type SimpleExpr = int | Parenthesized + type Parenthesized = tuple[Literal["("], Expr, Literal[")"]] + type Expr = SimpleExpr | tuple[SimpleExpr, Literal["+", "-"], Expr] + +Lazily evaluated values are evaluated in :ref:`annotation scope <annotation-scopes>`, +which means that names that appear inside the lazily evaluated value are looked up +as if they were used in the immediately enclosing scope. + +.. versionadded:: 3.12 + .. _restrict_exec: Builtins and restricted execution diff --git a/Doc/reference/expressions.rst b/Doc/reference/expressions.rst index ea9db182..5d7a36aa 100644 --- a/Doc/reference/expressions.rst +++ b/Doc/reference/expressions.rst @@ -71,7 +71,7 @@ An identifier occurring as an atom is a name. See section :ref:`identifiers` for lexical definition and section :ref:`naming` for documentation of naming and binding. -.. index:: exception: NameError +.. index:: pair: exception; NameError When the name is bound to an object, evaluation of the atom yields that object. When a name is not bound, an attempt to evaluate it raises a :exc:`NameError` @@ -245,7 +245,7 @@ List displays pair: list; display pair: list; comprehensions pair: empty; list - object: list + pair: object; list single: [] (square brackets); list expression single: , (comma); expression list @@ -270,7 +270,7 @@ Set displays .. index:: pair: set; display pair: set; comprehensions - object: set + pair: object; set single: {} (curly brackets); set expression single: , (comma); expression list @@ -298,27 +298,27 @@ Dictionary displays .. index:: pair: dictionary; display pair: dictionary; comprehensions - key, datum, key/datum pair - object: dictionary + key, value, key/value pair + pair: object; dictionary single: {} (curly brackets); dictionary expression single: : (colon); in dictionary expressions single: , (comma); in dictionary displays -A dictionary display is a possibly empty series of key/datum pairs enclosed in -curly braces: +A dictionary display is a possibly empty series of dict items (key/value pairs) +enclosed in curly braces: .. productionlist:: python-grammar - dict_display: "{" [`key_datum_list` | `dict_comprehension`] "}" - key_datum_list: `key_datum` ("," `key_datum`)* [","] - key_datum: `expression` ":" `expression` | "**" `or_expr` + dict_display: "{" [`dict_item_list` | `dict_comprehension`] "}" + dict_item_list: `dict_item` ("," `dict_item`)* [","] + dict_item: `expression` ":" `expression` | "**" `or_expr` dict_comprehension: `expression` ":" `expression` `comp_for` A dictionary display yields a new dictionary object. -If a comma-separated sequence of key/datum pairs is given, they are evaluated +If a comma-separated sequence of dict items is given, they are evaluated from left to right to define the entries of the dictionary: each key object is -used as a key into the dictionary to store the corresponding datum. This means -that you can specify the same key multiple times in the key/datum list, and the +used as a key into the dictionary to store the corresponding value. This means +that you can specify the same key multiple times in the dict item list, and the final dictionary's value for that key will be the last one given. .. index:: @@ -328,7 +328,7 @@ final dictionary's value for that key will be the last one given. A double asterisk ``**`` denotes :dfn:`dictionary unpacking`. Its operand must be a :term:`mapping`. Each mapping item is added to the new dictionary. Later values replace values already set by -earlier key/datum pairs and earlier dictionary unpackings. +earlier dict items and earlier dictionary unpackings. .. versionadded:: 3.5 Unpacking into dictionary displays, originally proposed by :pep:`448`. @@ -344,7 +344,7 @@ in the new dictionary in the order they are produced. Restrictions on the types of the key values are listed earlier in section :ref:`types`. (To summarize, the key type should be :term:`hashable`, which excludes all mutable objects.) Clashes between duplicate keys are not detected; the last -datum (textually rightmost in the display) stored for a given key value +value (textually rightmost in the display) stored for a given key value prevails. .. versionchanged:: 3.8 @@ -361,7 +361,7 @@ Generator expressions .. index:: pair: generator; expression - object: generator + pair: object; generator single: () (parentheses); generator expression A generator expression is a compact generator notation in parentheses: @@ -415,8 +415,8 @@ Yield expressions ----------------- .. index:: - keyword: yield - keyword: from + pair: keyword; yield + pair: keyword; from pair: yield; expression pair: generator; function @@ -522,7 +522,7 @@ on the right hand side of an assignment statement. The proposal that expanded on :pep:`492` by adding generator capabilities to coroutine functions. -.. index:: object: generator +.. index:: pair: object; generator .. _generator-methods: Generator-iterator methods @@ -534,7 +534,7 @@ be used to control the execution of a generator function. Note that calling any of the generator methods below when the generator is already executing raises a :exc:`ValueError` exception. -.. index:: exception: StopIteration +.. index:: pair: exception; StopIteration .. method:: generator.__next__() @@ -584,7 +584,12 @@ is already executing raises a :exc:`ValueError` exception. :attr:`~BaseException.__traceback__` attribute stored in *value* may be cleared. -.. index:: exception: GeneratorExit + .. versionchanged:: 3.12 + + The second signature \(type\[, value\[, traceback\]\]\) is deprecated and + may be removed in a future version of Python. + +.. index:: pair: exception; GeneratorExit .. method:: generator.close() @@ -696,7 +701,7 @@ of a *finalizer* method see the implementation of The expression ``yield from <expr>`` is a syntax error when used in an asynchronous generator function. -.. index:: object: asynchronous-generator +.. index:: pair: object; asynchronous-generator .. _asynchronous-generator-methods: Asynchronous generator-iterator methods @@ -706,7 +711,7 @@ This subsection describes the methods of an asynchronous generator iterator, which are used to control the execution of a generator function. -.. index:: exception: StopAsyncIteration +.. index:: pair: exception; StopAsyncIteration .. coroutinemethod:: agen.__anext__() @@ -740,7 +745,8 @@ which are used to control the execution of a generator function. because there is no yield expression that could receive the value. -.. coroutinemethod:: agen.athrow(type[, value[, traceback]]) +.. coroutinemethod:: agen.athrow(value) + agen.athrow(type[, value[, traceback]]) Returns an awaitable that raises an exception of type ``type`` at the point where the asynchronous generator was paused, and returns the next value @@ -752,7 +758,12 @@ which are used to control the execution of a generator function. raises a different exception, then when the awaitable is run that exception propagates to the caller of the awaitable. -.. index:: exception: GeneratorExit + .. versionchanged:: 3.12 + + The second signature \(type\[, value\[, traceback\]\]\) is deprecated and + may be removed in a future version of Python. + +.. index:: pair: exception; GeneratorExit .. coroutinemethod:: agen.aclose() @@ -799,9 +810,9 @@ An attribute reference is a primary followed by a period and a name: attributeref: `primary` "." `identifier` .. index:: - exception: AttributeError - object: module - object: list + pair: exception; AttributeError + pair: object; module + pair: object; list The primary must evaluate to an object of a type that supports attribute references, which most objects do. This object is then asked to produce the @@ -822,12 +833,12 @@ Subscriptions single: [] (square brackets); subscription .. index:: - object: sequence - object: mapping - object: string - object: tuple - object: list - object: dictionary + pair: object; sequence + pair: object; mapping + pair: object; string + pair: object; tuple + pair: object; list + pair: object; dictionary pair: sequence; item The subscription of an instance of a :ref:`container class <sequence-types>` @@ -895,10 +906,10 @@ Slicings single: , (comma); slicing .. index:: - object: sequence - object: string - object: tuple - object: list + pair: object; sequence + pair: object; string + pair: object; tuple + pair: object; list A slicing selects a range of items in a sequence object (e.g., a string, tuple or list). Slicings may be used as expressions or as targets in assignment or @@ -939,7 +950,7 @@ substituting ``None`` for missing expressions. .. index:: - object: callable + pair: object; callable single: call single: argument; call semantics single: () (parentheses); call @@ -1089,8 +1100,8 @@ a user-defined function: .. index:: pair: function; call triple: user-defined; function; call - object: user-defined function - object: function + pair: object; user-defined function + pair: object; function The code block for the function is executed, passing it the argument list. The first thing the code block will do is bind the formal parameters to the @@ -1104,25 +1115,25 @@ a built-in function or method: pair: built-in function; call pair: method; call pair: built-in method; call - object: built-in method - object: built-in function - object: method - object: function + pair: object; built-in method + pair: object; built-in function + pair: object; method + pair: object; function The result is up to the interpreter; see :ref:`built-in-funcs` for the descriptions of built-in functions and methods. a class object: .. index:: - object: class + pair: object; class pair: class object; call A new instance of that class is returned. a class instance method: .. index:: - object: class instance - object: instance + pair: object; class instance + pair: object; instance pair: class instance; call The corresponding user-defined function is called, with an argument list that is @@ -1138,7 +1149,7 @@ a class instance: if that method was called. -.. index:: keyword: await +.. index:: pair: keyword; await .. _await: Await expression @@ -1160,7 +1171,7 @@ The power operator .. index:: pair: power; operation - operator: ** + pair: operator; ** The power operator binds more tightly than unary operators on its left; it binds less tightly than unary operators on its right. The syntax is: @@ -1221,7 +1232,7 @@ operation can be overridden with the :meth:`__pos__` special method. .. index:: single: inversion - operator: ~ (tilde) + pair: operator; ~ (tilde) The unary ``~`` (invert) operator yields the bitwise inversion of its integer argument. The bitwise inversion of ``x`` is defined as ``-(x+1)``. It only @@ -1230,7 +1241,7 @@ applies to integral numbers or to custom objects that override the -.. index:: exception: TypeError +.. index:: pair: exception; TypeError In all three cases, if the argument does not have the proper type, a :exc:`TypeError` exception is raised. @@ -1256,7 +1267,7 @@ operators and one for additive operators: .. index:: single: multiplication - operator: * (asterisk) + pair: operator; * (asterisk) The ``*`` (multiplication) operator yields the product of its arguments. The arguments must either both be numbers, or one argument must be an integer and @@ -1269,7 +1280,7 @@ This operation can be customized using the special :meth:`__mul__` and .. index:: single: matrix multiplication - operator: @ (at) + pair: operator; @ (at) The ``@`` (at) operator is intended to be used for matrix multiplication. No builtin Python types implement this operator. @@ -1277,10 +1288,10 @@ builtin Python types implement this operator. .. versionadded:: 3.5 .. index:: - exception: ZeroDivisionError + pair: exception; ZeroDivisionError single: division - operator: / (slash) - operator: // + pair: operator; / (slash) + pair: operator; // The ``/`` (division) and ``//`` (floor division) operators yield the quotient of their arguments. The numeric arguments are first converted to a common type. @@ -1294,7 +1305,7 @@ This operation can be customized using the special :meth:`__truediv__` and .. index:: single: modulo - operator: % (percent) + pair: operator; % (percent) The ``%`` (modulo) operator yields the remainder from the division of the first argument by the second. The numeric arguments are first converted to a common @@ -1352,8 +1363,8 @@ Shifting operations .. index:: pair: shifting; operation - operator: << - operator: >> + pair: operator; << + pair: operator; >> The shifting operations have lower priority than the arithmetic operations: @@ -1366,7 +1377,7 @@ the left or right by the number of bits given by the second argument. This operation can be customized using the special :meth:`__lshift__` and :meth:`__rshift__` methods. -.. index:: exception: ValueError +.. index:: pair: exception; ValueError A right shift by *n* bits is defined as floor division by ``pow(2,n)``. A left shift by *n* bits is defined as multiplication with ``pow(2,n)``. @@ -1388,7 +1399,7 @@ Each of the three bitwise operations has a different priority level: .. index:: pair: bitwise; and - operator: & (ampersand) + pair: operator; & (ampersand) The ``&`` operator yields the bitwise AND of its arguments, which must be integers or one of them must be a custom object overriding :meth:`__and__` or @@ -1397,7 +1408,7 @@ integers or one of them must be a custom object overriding :meth:`__and__` or .. index:: pair: bitwise; xor pair: exclusive; or - operator: ^ (caret) + pair: operator; ^ (caret) The ``^`` operator yields the bitwise XOR (exclusive OR) of its arguments, which must be integers or one of them must be a custom object overriding :meth:`__xor__` or @@ -1406,7 +1417,7 @@ must be integers or one of them must be a custom object overriding :meth:`__xor_ .. index:: pair: bitwise; or pair: inclusive; or - operator: | (vertical bar) + pair: operator; | (vertical bar) The ``|`` operator yields the bitwise (inclusive) OR of its arguments, which must be integers or one of them must be a custom object overriding :meth:`__or__` or @@ -1421,12 +1432,12 @@ Comparisons .. index:: single: comparison pair: C; language - operator: < (less) - operator: > (greater) - operator: <= - operator: >= - operator: == - operator: != + pair: operator; < (less) + pair: operator; > (greater) + pair: operator; <= + pair: operator; >= + pair: operator; == + pair: operator; != Unlike C, all comparison operations in Python have the same priority, which is lower than that of any arithmetic, shifting or bitwise operation. Also unlike @@ -1658,17 +1669,17 @@ raises the :exc:`IndexError` exception. (If any other exception is raised, it i if :keyword:`in` raised that exception). .. index:: - operator: in - operator: not in + pair: operator; in + pair: operator; not in pair: membership; test - object: sequence + pair: object; sequence The operator :keyword:`not in` is defined to have the inverse truth value of :keyword:`in`. .. index:: - operator: is - operator: is not + pair: operator; is + pair: operator; is not pair: identity; test @@ -1706,19 +1717,19 @@ control flow statements, the following values are interpreted as false: ``False``, ``None``, numeric zero of all types, and empty strings and containers (including strings, tuples, lists, dictionaries, sets and frozensets). All other values are interpreted as true. User-defined objects can customize their -truth value by providing a :meth:`__bool__` method. +truth value by providing a :meth:`~object.__bool__` method. -.. index:: operator: not +.. index:: pair: operator; not The operator :keyword:`not` yields ``True`` if its argument is false, ``False`` otherwise. -.. index:: operator: and +.. index:: pair: operator; and The expression ``x and y`` first evaluates *x*; if *x* is false, its value is returned; otherwise, *y* is evaluated and the resulting value is returned. -.. index:: operator: or +.. index:: pair: operator; or The expression ``x or y`` first evaluates *x*; if *x* is true, its value is returned; otherwise, *y* is evaluated and the resulting value is returned. @@ -1843,7 +1854,7 @@ Expression lists starred_expression: `expression` | (`starred_item` ",")* [`starred_item`] starred_item: `assignment_expression` | "*" `or_expr` -.. index:: object: tuple +.. index:: pair: object; tuple Except when part of a list or set display, an expression list containing at least one comma yields a tuple. The length of diff --git a/Doc/reference/import.rst b/Doc/reference/import.rst index 70d946ab..0f416a5c 100644 --- a/Doc/reference/import.rst +++ b/Doc/reference/import.rst @@ -324,15 +324,18 @@ modules, and one that knows how to import modules from an :term:`import path` .. versionchanged:: 3.4 The :meth:`~importlib.abc.MetaPathFinder.find_spec` method of meta path - finders replaced :meth:`~importlib.abc.MetaPathFinder.find_module`, which + finders replaced :meth:`!find_module`, which is now deprecated. While it will continue to work without change, the import machinery will try it only if the finder does not implement ``find_spec()``. .. versionchanged:: 3.10 - Use of :meth:`~importlib.abc.MetaPathFinder.find_module` by the import system + Use of :meth:`!find_module` by the import system now raises :exc:`ImportWarning`. +.. versionchanged:: 3.12 + ``find_module()`` has been removed. Use :meth:`find_spec` instead. + Loading ======= @@ -358,7 +361,6 @@ of what happens during the loading portion of import:: sys.modules[spec.name] = module elif not hasattr(spec.loader, 'exec_module'): module = spec.loader.load_module(spec.name) - # Set __loader__ and __package__ if missing. else: sys.modules[spec.name] = module try: @@ -539,6 +541,10 @@ The import machinery fills in these attributes on each module object during loading, based on the module's spec, before the loader executes the module. +It is **strongly** recommended that you rely on :attr:`__spec__` and +its attributes instead of any of the other individual attributes +listed below. + .. attribute:: __name__ The ``__name__`` attribute must be set to the fully qualified name of @@ -552,9 +558,17 @@ the module. for introspection, but can be used for additional loader-specific functionality, for example getting data associated with a loader. + It is **strongly** recommended that you rely on :attr:`__spec__` + instead instead of this attribute. + + .. versionchanged:: 3.12 + The value of ``__loader__`` is expected to be the same as + ``__spec__.loader``. The use of ``__loader__`` is deprecated and slated + for removal in Python 3.14. + .. attribute:: __package__ - The module's ``__package__`` attribute must be set. Its value must + The module's ``__package__`` attribute may be set. Its value must be a string, but it can be the same value as its ``__name__``. When the module is a package, its ``__package__`` value should be set to its ``__name__``. When the module is not a package, ``__package__`` @@ -563,13 +577,25 @@ the module. details. This attribute is used instead of ``__name__`` to calculate explicit - relative imports for main modules, as defined in :pep:`366`. It is - expected to have the same value as ``__spec__.parent``. + relative imports for main modules, as defined in :pep:`366`. + + It is **strongly** recommended that you rely on :attr:`__spec__` + instead instead of this attribute. .. versionchanged:: 3.6 The value of ``__package__`` is expected to be the same as ``__spec__.parent``. + .. versionchanged:: 3.10 + :exc:`ImportWarning` is raised if import falls back to + ``__package__`` instead of + :attr:`~importlib.machinery.ModuleSpec.parent`. + + .. versionchanged:: 3.12 + Raise :exc:`DeprecationWarning` instead of :exc:`ImportWarning` + when falling back to ``__package__``. + + .. attribute:: __spec__ The ``__spec__`` attribute must be set to the module spec that was @@ -578,7 +604,7 @@ the module. interpreter startup <programs>`. The one exception is ``__main__``, where ``__spec__`` is :ref:`set to None in some cases <main_spec>`. - When ``__package__`` is not defined, ``__spec__.parent`` is used as + When ``__spec__.parent`` is not set, ``__package__`` is used as a fallback. .. versionadded:: 3.4 @@ -623,6 +649,9 @@ the module. if a loader can load from a cached module but otherwise does not load from a file, that atypical scenario may be appropriate. + It is **strongly** recommended that you rely on :attr:`__spec__` + instead instead of ``__cached__``. + .. _package-path-rules: module.__path__ @@ -676,22 +705,10 @@ Here are the exact rules used: * Otherwise, just use the module's ``__name__`` in the repr. -.. versionchanged:: 3.4 - Use of :meth:`loader.module_repr() <importlib.abc.Loader.module_repr>` - has been deprecated and the module spec is now used by the import - machinery to generate a module repr. - - For backward compatibility with Python 3.3, the module repr will be - generated by calling the loader's - :meth:`~importlib.abc.Loader.module_repr` method, if defined, before - trying either approach described above. However, the method is deprecated. - -.. versionchanged:: 3.10 - - Calling :meth:`~importlib.abc.Loader.module_repr` now occurs after trying to - use a module's ``__spec__`` attribute but before falling back on - ``__file__``. Use of :meth:`~importlib.abc.Loader.module_repr` is slated to - stop in Python 3.12. +.. versionchanged:: 3.12 + Use of :meth:`!module_repr`, having been deprecated since Python 3.4, was + removed in Python 3.12 and is no longer called during the resolution of a + module's repr. .. _pyc-invalidation: @@ -823,7 +840,7 @@ stores finder objects rather than being limited to :term:`importer` objects). In this way, the expensive search for a particular :term:`path entry` location's :term:`path entry finder` need only be done once. User code is free to remove cache entries from :data:`sys.path_importer_cache` forcing -the path based finder to perform the path entry search again [#fnpic]_. +the path based finder to perform the path entry search again. If the path entry is not present in the cache, the path based finder iterates over every callable in :data:`sys.path_hooks`. Each of the :term:`path entry @@ -873,13 +890,13 @@ module. ``find_spec()`` returns a fully populated spec for the module. This spec will always have "loader" set (with one exception). To indicate to the import machinery that the spec represents a namespace -:term:`portion`, the path entry finder sets "submodule_search_locations" to +:term:`portion`, the path entry finder sets ``submodule_search_locations`` to a list containing the portion. .. versionchanged:: 3.4 :meth:`~importlib.abc.PathEntryFinder.find_spec` replaced - :meth:`~importlib.abc.PathEntryFinder.find_loader` and - :meth:`~importlib.abc.PathEntryFinder.find_module`, both of which + :meth:`!find_loader` and + :meth:`!find_module`, both of which are now deprecated, but will be used if ``find_spec()`` is not defined. Older path entry finders may implement one of these two deprecated methods @@ -887,7 +904,7 @@ a list containing the portion. sake of backward compatibility. However, if ``find_spec()`` is implemented on the path entry finder, the legacy methods are ignored. - :meth:`~importlib.abc.PathEntryFinder.find_loader` takes one argument, the + :meth:`!find_loader` takes one argument, the fully qualified name of the module being imported. ``find_loader()`` returns a 2-tuple where the first item is the loader and the second item is a namespace :term:`portion`. @@ -906,10 +923,13 @@ a list containing the portion. ``find_loader()`` in preference to ``find_module()``. .. versionchanged:: 3.10 - Calls to :meth:`~importlib.abc.PathEntryFinder.find_module` and - :meth:`~importlib.abc.PathEntryFinder.find_loader` by the import + Calls to :meth:`!find_module` and + :meth:`!find_loader` by the import system will raise :exc:`ImportWarning`. +.. versionchanged:: 3.12 + ``find_module()`` and ``find_loader()`` have been removed. + Replacing the standard import system ==================================== @@ -1031,8 +1051,8 @@ The original specification for :data:`sys.meta_path` was :pep:`302`, with subsequent extension in :pep:`420`. :pep:`420` introduced :term:`namespace packages <namespace package>` for -Python 3.3. :pep:`420` also introduced the :meth:`find_loader` protocol as an -alternative to :meth:`find_module`. +Python 3.3. :pep:`420` also introduced the :meth:`!find_loader` protocol as an +alternative to :meth:`!find_module`. :pep:`366` describes the addition of the ``__package__`` attribute for explicit relative imports in main modules. @@ -1059,8 +1079,3 @@ methods to finders and loaders. module may replace itself in :data:`sys.modules`. This is implementation-specific behavior that is not guaranteed to work in other Python implementations. - -.. [#fnpic] In legacy code, it is possible to find instances of - :class:`imp.NullImporter` in the :data:`sys.path_importer_cache`. It - is recommended that code be changed to use ``None`` instead. See - :ref:`portingpythoncode` for more details. diff --git a/Doc/reference/introduction.rst b/Doc/reference/introduction.rst index 914a1155..81f0a5c5 100644 --- a/Doc/reference/introduction.rst +++ b/Doc/reference/introduction.rst @@ -74,7 +74,7 @@ PyPy and a Just in Time compiler. One of the goals of the project is to encourage experimentation with the language itself by making it easier to modify the interpreter (since it is written in Python). Additional information is - available on `the PyPy project's home page <https://pypy.org/>`_. + available on `the PyPy project's home page <https://www.pypy.org/>`_. Each of these implementations varies in some way from the language as documented in this manual, or introduces specific information beyond what's covered in the diff --git a/Doc/reference/lexical_analysis.rst b/Doc/reference/lexical_analysis.rst index 44726de3..816de9b5 100644 --- a/Doc/reference/lexical_analysis.rst +++ b/Doc/reference/lexical_analysis.rst @@ -315,7 +315,7 @@ The Unicode category codes mentioned above stand for: * *Nd* - decimal numbers * *Pc* - connector punctuations * *Other_ID_Start* - explicit list of characters in `PropList.txt - <https://www.unicode.org/Public/14.0.0/ucd/PropList.txt>`_ to support backwards + <https://www.unicode.org/Public/15.0.0/ucd/PropList.txt>`_ to support backwards compatibility * *Other_ID_Continue* - likewise @@ -323,8 +323,8 @@ All identifiers are converted into the normal form NFKC while parsing; compariso of identifiers is based on NFKC. A non-normative HTML file listing all valid identifier characters for Unicode -14.0.0 can be found at -https://www.unicode.org/Public/14.0.0/ucd/DerivedCoreProperties.txt +15.0.0 can be found at +https://www.unicode.org/Public/15.0.0/ucd/DerivedCoreProperties.txt .. _keywords: @@ -361,15 +361,19 @@ Soft Keywords .. versionadded:: 3.10 Some identifiers are only reserved under specific contexts. These are known as -*soft keywords*. The identifiers ``match``, ``case`` and ``_`` can -syntactically act as keywords in contexts related to the pattern matching -statement, but this distinction is done at the parser level, not when -tokenizing. +*soft keywords*. The identifiers ``match``, ``case``, ``type`` and ``_`` can +syntactically act as keywords in certain contexts, +but this distinction is done at the parser level, not when tokenizing. -As soft keywords, their use with pattern matching is possible while still -preserving compatibility with existing code that uses ``match``, ``case`` and ``_`` as +As soft keywords, their use in the grammar is possible while still +preserving compatibility with existing code that uses these names as identifier names. +``match``, ``case``, and ``_`` are used in the :keyword:`match` statement. +``type`` is used in the :keyword:`type` statement. + +.. versionchanged:: 3.12 + ``type`` is now a soft keyword. .. index:: single: _, identifiers @@ -480,9 +484,11 @@ declaration is given in the source file; see section :ref:`encodings`. In plain English: Both types of literals can be enclosed in matching single quotes (``'``) or double quotes (``"``). They can also be enclosed in matching groups of three single or double quotes (these are generally referred to as -*triple-quoted strings*). The backslash (``\``) character is used to escape -characters that otherwise have a special meaning, such as newline, backslash -itself, or the quote character. +*triple-quoted strings*). The backslash (``\``) character is used to give special +meaning to otherwise ordinary characters like ``n``, which means 'newline' when +escaped (``\n``). It can also be used to escape characters that otherwise have a +special meaning, such as newline, backslash itself, or the quote character. +See :ref:`escape sequences <escape-sequences>` below for examples. .. index:: single: b'; bytes literal @@ -541,55 +547,61 @@ retained), except that three unescaped quotes in a row terminate the literal. ( single: \u; escape sequence single: \U; escape sequence +.. _escape-sequences: + + +Escape sequences +^^^^^^^^^^^^^^^^ + Unless an ``'r'`` or ``'R'`` prefix is present, escape sequences in string and bytes literals are interpreted according to rules similar to those used by Standard C. The recognized escape sequences are: -+-----------------+---------------------------------+-------+ -| Escape Sequence | Meaning | Notes | -+=================+=================================+=======+ -| ``\``\ <newline>| Backslash and newline ignored | \(1) | -+-----------------+---------------------------------+-------+ -| ``\\`` | Backslash (``\``) | | -+-----------------+---------------------------------+-------+ -| ``\'`` | Single quote (``'``) | | -+-----------------+---------------------------------+-------+ -| ``\"`` | Double quote (``"``) | | -+-----------------+---------------------------------+-------+ -| ``\a`` | ASCII Bell (BEL) | | -+-----------------+---------------------------------+-------+ -| ``\b`` | ASCII Backspace (BS) | | -+-----------------+---------------------------------+-------+ -| ``\f`` | ASCII Formfeed (FF) | | -+-----------------+---------------------------------+-------+ -| ``\n`` | ASCII Linefeed (LF) | | -+-----------------+---------------------------------+-------+ -| ``\r`` | ASCII Carriage Return (CR) | | -+-----------------+---------------------------------+-------+ -| ``\t`` | ASCII Horizontal Tab (TAB) | | -+-----------------+---------------------------------+-------+ -| ``\v`` | ASCII Vertical Tab (VT) | | -+-----------------+---------------------------------+-------+ -| ``\ooo`` | Character with octal value | (2,4) | -| | *ooo* | | -+-----------------+---------------------------------+-------+ -| ``\xhh`` | Character with hex value *hh* | (3,4) | -+-----------------+---------------------------------+-------+ ++-------------------------+---------------------------------+-------+ +| Escape Sequence | Meaning | Notes | ++=========================+=================================+=======+ +| ``\``\ <newline> | Backslash and newline ignored | \(1) | ++-------------------------+---------------------------------+-------+ +| ``\\`` | Backslash (``\``) | | ++-------------------------+---------------------------------+-------+ +| ``\'`` | Single quote (``'``) | | ++-------------------------+---------------------------------+-------+ +| ``\"`` | Double quote (``"``) | | ++-------------------------+---------------------------------+-------+ +| ``\a`` | ASCII Bell (BEL) | | ++-------------------------+---------------------------------+-------+ +| ``\b`` | ASCII Backspace (BS) | | ++-------------------------+---------------------------------+-------+ +| ``\f`` | ASCII Formfeed (FF) | | ++-------------------------+---------------------------------+-------+ +| ``\n`` | ASCII Linefeed (LF) | | ++-------------------------+---------------------------------+-------+ +| ``\r`` | ASCII Carriage Return (CR) | | ++-------------------------+---------------------------------+-------+ +| ``\t`` | ASCII Horizontal Tab (TAB) | | ++-------------------------+---------------------------------+-------+ +| ``\v`` | ASCII Vertical Tab (VT) | | ++-------------------------+---------------------------------+-------+ +| :samp:`\\\\{ooo}` | Character with octal value | (2,4) | +| | *ooo* | | ++-------------------------+---------------------------------+-------+ +| :samp:`\\x{hh}` | Character with hex value *hh* | (3,4) | ++-------------------------+---------------------------------+-------+ Escape sequences only recognized in string literals are: -+-----------------+---------------------------------+-------+ -| Escape Sequence | Meaning | Notes | -+=================+=================================+=======+ -| ``\N{name}`` | Character named *name* in the | \(5) | -| | Unicode database | | -+-----------------+---------------------------------+-------+ -| ``\uxxxx`` | Character with 16-bit hex value | \(6) | -| | *xxxx* | | -+-----------------+---------------------------------+-------+ -| ``\Uxxxxxxxx`` | Character with 32-bit hex value | \(7) | -| | *xxxxxxxx* | | -+-----------------+---------------------------------+-------+ ++-------------------------+---------------------------------+-------+ +| Escape Sequence | Meaning | Notes | ++=========================+=================================+=======+ +| :samp:`\\N\\{{name}\\}` | Character named *name* in the | \(5) | +| | Unicode database | | ++-------------------------+---------------------------------+-------+ +| :samp:`\\u{xxxx}` | Character with 16-bit hex value | \(6) | +| | *xxxx* | | ++-------------------------+---------------------------------+-------+ +| :samp:`\\U{xxxxxxxx}` | Character with 32-bit hex value | \(7) | +| | *xxxxxxxx* | | ++-------------------------+---------------------------------+-------+ Notes: @@ -608,9 +620,13 @@ Notes: As in Standard C, up to three octal digits are accepted. .. versionchanged:: 3.11 - Octal escapes with value larger than ``0o377`` produce a :exc:`DeprecationWarning`. - In a future Python version they will be a :exc:`SyntaxWarning` and - eventually a :exc:`SyntaxError`. + Octal escapes with value larger than ``0o377`` produce a + :exc:`DeprecationWarning`. + + .. versionchanged:: 3.12 + Octal escapes with value larger than ``0o377`` produce a + :exc:`SyntaxWarning`. In a future Python version they will be eventually + a :exc:`SyntaxError`. (3) Unlike in Standard C, exactly two hex digits are required. @@ -642,9 +658,11 @@ escape sequences only recognized in string literals fall into the category of unrecognized escapes for bytes literals. .. versionchanged:: 3.6 - Unrecognized escape sequences produce a :exc:`DeprecationWarning`. In - a future Python version they will be a :exc:`SyntaxWarning` and - eventually a :exc:`SyntaxError`. + Unrecognized escape sequences produce a :exc:`DeprecationWarning`. + + .. versionchanged:: 3.12 + Unrecognized escape sequences produce a :exc:`SyntaxWarning`. In a future + Python version they will be eventually a :exc:`SyntaxError`. Even in a raw literal, quotes can be escaped with a backslash, but the backslash remains in the result; for example, ``r"\""`` is a valid string @@ -731,16 +749,28 @@ Expressions in formatted string literals are treated like regular Python expressions surrounded by parentheses, with a few exceptions. An empty expression is not allowed, and both :keyword:`lambda` and assignment expressions ``:=`` must be surrounded by explicit parentheses. -Replacement expressions can contain line breaks (e.g. in triple-quoted -strings), but they cannot contain comments. Each expression is evaluated -in the context where the formatted string literal appears, in order from -left to right. +Each expression is evaluated in the context where the formatted string literal +appears, in order from left to right. Replacement expressions can contain +newlines in both single-quoted and triple-quoted f-strings and they can contain +comments. Everything that comes after a ``#`` inside a replacement field +is a comment (even closing braces and quotes). In that case, replacement fields +must be closed in a different line. + +.. code-block:: text + + >>> f"abc{a # This is a comment }" + ... + 3}" + 'abc5' .. versionchanged:: 3.7 Prior to Python 3.7, an :keyword:`await` expression and comprehensions containing an :keyword:`async for` clause were illegal in the expressions in formatted string literals due to a problem with the implementation. +.. versionchanged:: 3.12 + Prior to Python 3.12, comments were not allowed inside f-string replacement + fields. + When the equal sign ``'='`` is provided, the output will have the expression text, the ``'='`` and the evaluated value. Spaces after the opening brace ``'{'``, within the expression and after the ``'='`` are all retained in the @@ -757,7 +787,7 @@ is converted before formatting. Conversion ``'!s'`` calls :func:`str` on the result, ``'!r'`` calls :func:`repr`, and ``'!a'`` calls :func:`ascii`. The result is then formatted using the :func:`format` protocol. The -format specifier is passed to the :meth:`__format__` method of the +format specifier is passed to the :meth:`~object.__format__` method of the expression or conversion result. An empty string is passed when the format specifier is omitted. The formatted result is then included in the final value of the whole string. @@ -803,24 +833,30 @@ Some examples of formatted string literals:: 'line = "The mill\'s closed" ' -A consequence of sharing the same syntax as regular string literals is -that characters in the replacement fields must not conflict with the -quoting used in the outer formatted string literal:: +Reusing the outer f-string quoting type inside a replacement field is +permitted:: - f"abc {a["x"]} def" # error: outer string literal ended prematurely - f"abc {a['x']} def" # workaround: use different quoting + >>> a = dict(x=2) + >>> f"abc {a["x"]} def" + 'abc 2 def' -Backslashes are not allowed in format expressions and will raise -an error:: +.. versionchanged:: 3.12 + Prior to Python 3.12, reuse of the same quoting type of the outer f-string + inside a replacement field was not possible. - f"newline: {ord('\n')}" # raises SyntaxError +Backslashes are also allowed in replacement fields and are evaluated the same +way as in any other context:: -To include a value in which a backslash escape is required, create -a temporary variable. + >>> a = ["a", "b", "c"] + >>> print(f"List a contains:\n{"\n".join(a)}") + List a contains: + a + b + c - >>> newline = ord('\n') - >>> f"newline: {newline}" - 'newline: 10' +.. versionchanged:: 3.12 + Prior to Python 3.12, backslashes were not permitted inside an f-string + replacement field. Formatted string literals cannot be used as docstrings, even if they do not include expressions. @@ -1009,4 +1045,4 @@ occurrence outside string literals and comments is an unconditional error: .. rubric:: Footnotes -.. [#] https://www.unicode.org/Public/11.0.0/ucd/NameAliases.txt +.. [#] https://www.unicode.org/Public/15.0.0/ucd/NameAliases.txt diff --git a/Doc/reference/simple_stmts.rst b/Doc/reference/simple_stmts.rst index c98ac81e..a9e65be1 100644 --- a/Doc/reference/simple_stmts.rst +++ b/Doc/reference/simple_stmts.rst @@ -28,6 +28,7 @@ simple statements is: : | `future_stmt` : | `global_stmt` : | `nonlocal_stmt` + : | `type_stmt` .. _exprstmts: @@ -53,8 +54,8 @@ An expression statement evaluates the expression list (which may be a single expression). .. index:: - builtin: repr - object: None + pair: built-in function; repr + pair: object; None pair: string; conversion single: output pair: standard; output @@ -76,7 +77,7 @@ Assignment statements pair: assignment; statement pair: binding; name pair: rebinding; name - object: mutable + pair: object; mutable pair: attribute; assignment Assignment statements are used to (re)bind names to values and to modify @@ -185,7 +186,7 @@ Assignment of an object to a single target is recursively defined as follows. .. index:: pair: subscription; assignment - object: mutable + pair: object; mutable * If the target is a subscription: The primary expression in the reference is evaluated. It should yield either a mutable sequence object (such as a list) @@ -193,8 +194,8 @@ Assignment of an object to a single target is recursively defined as follows. evaluated. .. index:: - object: sequence - object: list + pair: object; sequence + pair: object; list If the primary is a mutable sequence object (such as a list), the subscript must yield an integer. If it is negative, the sequence's length is added to @@ -204,12 +205,12 @@ Assignment of an object to a single target is recursively defined as follows. raised (assignment to a subscripted sequence cannot add new items to a list). .. index:: - object: mapping - object: dictionary + pair: object; mapping + pair: object; dictionary If the primary is a mapping object (such as a dictionary), the subscript must have a type compatible with the mapping's key type, and the mapping is then - asked to create a key/datum pair which maps the subscript to the assigned + asked to create a key/value pair which maps the subscript to the assigned object. This can either replace an existing key/value pair with the same key value, or insert a new key/value pair (if no key with the same value existed). @@ -376,7 +377,7 @@ The :keyword:`!assert` statement ================================ .. index:: - ! statement: assert + ! pair: statement; assert pair: debugging; assertions single: , (comma); expression list @@ -398,7 +399,7 @@ The extended form, ``assert expression1, expression2``, is equivalent to :: .. index:: single: __debug__ - exception: AssertionError + pair: exception; AssertionError These equivalences assume that :const:`__debug__` and :exc:`AssertionError` refer to the built-in variables with those names. In the current implementation, the @@ -419,7 +420,7 @@ The :keyword:`!pass` statement ============================== .. index:: - statement: pass + pair: statement; pass pair: null; operation pair: null; operation @@ -441,7 +442,7 @@ The :keyword:`!del` statement ============================= .. index:: - ! statement: del + ! pair: statement; del pair: deletion; target triple: deletion; target; list @@ -454,7 +455,7 @@ Rather than spelling it out in full details, here are some hints. Deletion of a target list recursively deletes each target, from left to right. .. index:: - statement: global + pair: statement; global pair: unbinding; name Deletion of a name removes the binding of that name from the local or global @@ -480,7 +481,7 @@ The :keyword:`!return` statement ================================ .. index:: - ! statement: return + ! pair: statement; return pair: function; definition pair: class; definition @@ -495,7 +496,7 @@ If an expression list is present, it is evaluated, else ``None`` is substituted. :keyword:`return` leaves the current function call with the expression list (or ``None``) as return value. -.. index:: keyword: finally +.. index:: pair: keyword; finally When :keyword:`return` passes control out of a :keyword:`try` statement with a :keyword:`finally` clause, that :keyword:`!finally` clause is executed before @@ -517,11 +518,11 @@ The :keyword:`!yield` statement =============================== .. index:: - statement: yield + pair: statement; yield single: generator; function single: generator; iterator single: function; generator - exception: StopIteration + pair: exception; StopIteration .. productionlist:: python-grammar yield_stmt: `yield_expression` @@ -553,7 +554,7 @@ The :keyword:`!raise` statement =============================== .. index:: - ! statement: raise + ! pair: statement; raise single: exception pair: raising; exception single: __traceback__ (exception attribute) @@ -574,7 +575,7 @@ instantiating the class with no arguments. The :dfn:`type` of the exception is the exception instance's class, the :dfn:`value` is the instance itself. -.. index:: object: traceback +.. index:: pair: object; traceback A traceback object is normally created automatically when an exception is raised and attached to it as the :attr:`__traceback__` attribute, which is writable. @@ -667,9 +668,9 @@ The :keyword:`!break` statement =============================== .. index:: - ! statement: break - statement: for - statement: while + ! pair: statement; break + pair: statement; for + pair: statement; while pair: loop; statement .. productionlist:: python-grammar @@ -679,7 +680,7 @@ The :keyword:`!break` statement :keyword:`while` loop, but not nested in a function or class definition within that loop. -.. index:: keyword: else +.. index:: pair: keyword; else pair: loop control; target It terminates the nearest enclosing loop, skipping the optional :keyword:`!else` @@ -688,7 +689,7 @@ clause if the loop has one. If a :keyword:`for` loop is terminated by :keyword:`break`, the loop control target keeps its current value. -.. index:: keyword: finally +.. index:: pair: keyword; finally When :keyword:`break` passes control out of a :keyword:`try` statement with a :keyword:`finally` clause, that :keyword:`!finally` clause is executed before @@ -701,11 +702,11 @@ The :keyword:`!continue` statement ================================== .. index:: - ! statement: continue - statement: for - statement: while + ! pair: statement; continue + pair: statement; for + pair: statement; while pair: loop; statement - keyword: finally + pair: keyword; finally .. productionlist:: python-grammar continue_stmt: "continue" @@ -726,12 +727,12 @@ The :keyword:`!import` statement ================================ .. index:: - ! statement: import + ! pair: statement; import single: module; importing pair: name; binding - keyword: from - keyword: as - exception: ImportError + pair: keyword; from + pair: keyword; as + pair: exception; ImportError single: , (comma); import statement .. productionlist:: python-grammar @@ -942,7 +943,7 @@ The :keyword:`!global` statement ================================ .. index:: - ! statement: global + ! pair: statement; global triple: global; name; binding single: , (comma); identifier list @@ -970,9 +971,9 @@ annotation. them or silently change the meaning of the program. .. index:: - builtin: exec - builtin: eval - builtin: compile + pair: built-in function; exec + pair: built-in function; eval + pair: built-in function; compile **Programmer's note:** :keyword:`global` is a directive to the parser. It applies only to code parsed at the same time as the :keyword:`!global` statement. @@ -988,7 +989,7 @@ call. The same applies to the :func:`eval` and :func:`compile` functions. The :keyword:`!nonlocal` statement ================================== -.. index:: statement: nonlocal +.. index:: pair: statement; nonlocal single: , (comma); identifier list .. productionlist:: python-grammar @@ -1012,3 +1013,48 @@ pre-existing bindings in the local scope. :pep:`3104` - Access to Names in Outer Scopes The specification for the :keyword:`nonlocal` statement. + +.. _type: + +The :keyword:`!type` statement +============================== + +.. index:: pair: statement; type + +.. productionlist:: python-grammar + type_stmt: 'type' `identifier` [`type_params`] "=" `expression` + +The :keyword:`!type` statement declares a type alias, which is an instance +of :class:`typing.TypeAliasType`. + +For example, the following statement creates a type alias:: + + type Point = tuple[float, float] + +This code is roughly equivalent to:: + + annotation-def VALUE_OF_Point(): + return tuple[float, float] + Point = typing.TypeAliasType("Point", VALUE_OF_Point()) + +``annotation-def`` indicates an :ref:`annotation scope <annotation-scopes>`, which behaves +mostly like a function, but with several small differences. + +The value of the +type alias is evaluated in the annotation scope. It is not evaluated when the +type alias is created, but only when the value is accessed through the type alias's +:attr:`!__value__` attribute (see :ref:`lazy-evaluation`). +This allows the type alias to refer to names that are not yet defined. + +Type aliases may be made generic by adding a :ref:`type parameter list <type-params>` +after the name. See :ref:`generic-type-aliases` for more. + +:keyword:`!type` is a :ref:`soft keyword <soft-keywords>`. + +.. versionadded:: 3.12 + +.. seealso:: + + :pep:`695` - Type Parameter Syntax + Introduced the :keyword:`!type` statement and syntax for + generic classes and functions. diff --git a/Doc/reference/toplevel_components.rst b/Doc/reference/toplevel_components.rst index 319c9de4..dd3d3d68 100644 --- a/Doc/reference/toplevel_components.rst +++ b/Doc/reference/toplevel_components.rst @@ -21,9 +21,9 @@ Complete Python programs .. index:: single: program .. index:: - module: sys - module: __main__ - module: builtins + pair: module; sys + pair: module; __main__ + pair: module; builtins While a language specification need not prescribe how the language interpreter is invoked, it is useful to have a notion of a complete Python program. A @@ -38,7 +38,7 @@ the next section. .. index:: single: interactive mode - module: __main__ + pair: module; __main__ The interpreter may also be invoked in interactive mode; in this case, it does not read and execute a complete program but reads and executes one statement @@ -98,7 +98,7 @@ Expression input ================ .. index:: single: input -.. index:: builtin: eval +.. index:: pair: built-in function; eval :func:`eval` is used for expression input. It ignores leading whitespace. The string argument to :func:`eval` must have the following form: diff --git a/Doc/requirements-oldest-sphinx.txt b/Doc/requirements-oldest-sphinx.txt new file mode 100644 index 00000000..d3ef5bc1 --- /dev/null +++ b/Doc/requirements-oldest-sphinx.txt @@ -0,0 +1,36 @@ +# Requirements to build the Python documentation, for the oldest supported +# Sphinx version. +# +# We pin Sphinx and all of its dependencies to ensure a consistent environment. + +blurb +python-docs-theme>=2022.1 + +# Generated from: +# pip install "Sphinx~=4.2.0" +# pip freeze +# +# Sphinx 4.2 comes from ``needs_sphinx = '4.2'`` in ``Doc/conf.py``. + +alabaster==0.7.13 +Babel==2.12.1 +certifi==2023.7.22 +charset-normalizer==3.2.0 +colorama==0.4.6 +docutils==0.16 +idna==3.4 +imagesize==1.4.1 +Jinja2==2.11.3 +MarkupSafe==1.1.1 +packaging==23.1 +Pygments==2.16.1 +requests==2.31.0 +snowballstemmer==2.2.0 +Sphinx==4.2.0 +sphinxcontrib-applehelp==1.0.4 +sphinxcontrib-devhelp==1.0.2 +sphinxcontrib-htmlhelp==2.0.1 +sphinxcontrib-jsmath==1.0.1 +sphinxcontrib-qthelp==1.0.3 +sphinxcontrib-serializinghtml==1.1.5 +urllib3==2.0.4 diff --git a/Doc/requirements.txt b/Doc/requirements.txt index 134f39d6..4741265a 100644 --- a/Doc/requirements.txt +++ b/Doc/requirements.txt @@ -1,4 +1,7 @@ # Requirements to build the Python documentation +# +# Note that when updating this file, you will likely also have to update +# the Doc/constraints.txt file. # Sphinx version is pinned so that new versions that introduce new warnings # won't suddenly cause build failures. Updating the version is fine as long @@ -7,9 +10,10 @@ sphinx==4.5.0 blurb -sphinx-lint==0.6.7 -sphinxext-opengraph>=0.7.1 +sphinxext-opengraph==0.7.5 # The theme used by the documentation is stored separately, so we need # to install that as well. -python-docs-theme>=2022.1 +python-docs-theme>=2023.3.1,!=2023.7 + +-c constraints.txt diff --git a/Doc/tools/.nitignore b/Doc/tools/.nitignore new file mode 100644 index 00000000..90a66ac8 --- /dev/null +++ b/Doc/tools/.nitignore @@ -0,0 +1,187 @@ +# All RST files under Doc/ -- except these -- must pass Sphinx nit-picky mode, +# as tested on the CI via check-warnings.py in reusable-docs.yml. +# Keep lines sorted lexicographically to help avoid merge conflicts. + +Doc/c-api/arg.rst +Doc/c-api/descriptor.rst +Doc/c-api/exceptions.rst +Doc/c-api/file.rst +Doc/c-api/float.rst +Doc/c-api/gcsupport.rst +Doc/c-api/init.rst +Doc/c-api/init_config.rst +Doc/c-api/intro.rst +Doc/c-api/memory.rst +Doc/c-api/memoryview.rst +Doc/c-api/module.rst +Doc/c-api/object.rst +Doc/c-api/set.rst +Doc/c-api/stable.rst +Doc/c-api/structures.rst +Doc/c-api/sys.rst +Doc/c-api/type.rst +Doc/c-api/typeobj.rst +Doc/extending/extending.rst +Doc/extending/newtypes.rst +Doc/glossary.rst +Doc/howto/descriptor.rst +Doc/howto/enum.rst +Doc/howto/isolating-extensions.rst +Doc/howto/logging.rst +Doc/howto/urllib2.rst +Doc/library/2to3.rst +Doc/library/__future__.rst +Doc/library/abc.rst +Doc/library/aifc.rst +Doc/library/ast.rst +Doc/library/asyncio-dev.rst +Doc/library/asyncio-eventloop.rst +Doc/library/asyncio-extending.rst +Doc/library/asyncio-policy.rst +Doc/library/asyncio-stream.rst +Doc/library/asyncio-subprocess.rst +Doc/library/asyncio-task.rst +Doc/library/audioop.rst +Doc/library/bdb.rst +Doc/library/bisect.rst +Doc/library/bz2.rst +Doc/library/calendar.rst +Doc/library/cgi.rst +Doc/library/chunk.rst +Doc/library/cmd.rst +Doc/library/codecs.rst +Doc/library/collections.abc.rst +Doc/library/collections.rst +Doc/library/concurrent.futures.rst +Doc/library/configparser.rst +Doc/library/contextlib.rst +Doc/library/copy.rst +Doc/library/csv.rst +Doc/library/datetime.rst +Doc/library/dbm.rst +Doc/library/decimal.rst +Doc/library/doctest.rst +Doc/library/email.charset.rst +Doc/library/email.compat32-message.rst +Doc/library/email.errors.rst +Doc/library/email.headerregistry.rst +Doc/library/email.mime.rst +Doc/library/email.parser.rst +Doc/library/email.policy.rst +Doc/library/enum.rst +Doc/library/exceptions.rst +Doc/library/faulthandler.rst +Doc/library/fcntl.rst +Doc/library/ftplib.rst +Doc/library/functions.rst +Doc/library/functools.rst +Doc/library/getopt.rst +Doc/library/getpass.rst +Doc/library/gettext.rst +Doc/library/gzip.rst +Doc/library/http.client.rst +Doc/library/http.cookiejar.rst +Doc/library/http.cookies.rst +Doc/library/http.server.rst +Doc/library/importlib.resources.rst +Doc/library/importlib.rst +Doc/library/inspect.rst +Doc/library/locale.rst +Doc/library/logging.config.rst +Doc/library/logging.handlers.rst +Doc/library/lzma.rst +Doc/library/mailbox.rst +Doc/library/mmap.rst +Doc/library/msilib.rst +Doc/library/multiprocessing.rst +Doc/library/multiprocessing.shared_memory.rst +Doc/library/nntplib.rst +Doc/library/numbers.rst +Doc/library/optparse.rst +Doc/library/os.path.rst +Doc/library/os.rst +Doc/library/ossaudiodev.rst +Doc/library/pickle.rst +Doc/library/pickletools.rst +Doc/library/platform.rst +Doc/library/plistlib.rst +Doc/library/profile.rst +Doc/library/pyclbr.rst +Doc/library/pydoc.rst +Doc/library/pyexpat.rst +Doc/library/random.rst +Doc/library/readline.rst +Doc/library/reprlib.rst +Doc/library/resource.rst +Doc/library/rlcompleter.rst +Doc/library/select.rst +Doc/library/selectors.rst +Doc/library/shelve.rst +Doc/library/signal.rst +Doc/library/smtplib.rst +Doc/library/socket.rst +Doc/library/socketserver.rst +Doc/library/ssl.rst +Doc/library/stdtypes.rst +Doc/library/string.rst +Doc/library/subprocess.rst +Doc/library/sunau.rst +Doc/library/syslog.rst +Doc/library/tarfile.rst +Doc/library/telnetlib.rst +Doc/library/tempfile.rst +Doc/library/termios.rst +Doc/library/test.rst +Doc/library/time.rst +Doc/library/tkinter.rst +Doc/library/tkinter.scrolledtext.rst +Doc/library/tkinter.tix.rst +Doc/library/tkinter.ttk.rst +Doc/library/traceback.rst +Doc/library/tty.rst +Doc/library/unittest.mock.rst +Doc/library/unittest.rst +Doc/library/urllib.parse.rst +Doc/library/urllib.request.rst +Doc/library/webbrowser.rst +Doc/library/wsgiref.rst +Doc/library/xdrlib.rst +Doc/library/xml.dom.minidom.rst +Doc/library/xml.dom.pulldom.rst +Doc/library/xml.dom.rst +Doc/library/xml.rst +Doc/library/xml.sax.handler.rst +Doc/library/xml.sax.reader.rst +Doc/library/xml.sax.rst +Doc/library/xmlrpc.client.rst +Doc/library/xmlrpc.server.rst +Doc/library/zlib.rst +Doc/reference/compound_stmts.rst +Doc/reference/datamodel.rst +Doc/reference/expressions.rst +Doc/reference/import.rst +Doc/reference/simple_stmts.rst +Doc/tutorial/datastructures.rst +Doc/tutorial/introduction.rst +Doc/using/cmdline.rst +Doc/using/windows.rst +Doc/whatsnew/2.0.rst +Doc/whatsnew/2.1.rst +Doc/whatsnew/2.2.rst +Doc/whatsnew/2.3.rst +Doc/whatsnew/2.4.rst +Doc/whatsnew/2.5.rst +Doc/whatsnew/2.6.rst +Doc/whatsnew/2.7.rst +Doc/whatsnew/3.0.rst +Doc/whatsnew/3.1.rst +Doc/whatsnew/3.2.rst +Doc/whatsnew/3.3.rst +Doc/whatsnew/3.4.rst +Doc/whatsnew/3.5.rst +Doc/whatsnew/3.6.rst +Doc/whatsnew/3.7.rst +Doc/whatsnew/3.8.rst +Doc/whatsnew/3.9.rst +Doc/whatsnew/3.10.rst +Doc/whatsnew/3.11.rst diff --git a/Doc/tools/check-warnings.py b/Doc/tools/check-warnings.py new file mode 100644 index 00000000..809a8d63 --- /dev/null +++ b/Doc/tools/check-warnings.py @@ -0,0 +1,311 @@ +#!/usr/bin/env python3 +""" +Check the output of running Sphinx in nit-picky mode (missing references). +""" +from __future__ import annotations + +import argparse +import itertools +import os +import re +import subprocess +import sys +from pathlib import Path +from typing import TextIO + +# Exclude these whether they're dirty or clean, +# because they trigger a rebuild of dirty files. +EXCLUDE_FILES = { + "Doc/whatsnew/changelog.rst", +} + +# Subdirectories of Doc/ to exclude. +EXCLUDE_SUBDIRS = { + ".env", + ".venv", + "env", + "includes", + "venv", +} + +# Regex pattern to match the parts of a Sphinx warning +WARNING_PATTERN = re.compile( + r"(?P<file>([A-Za-z]:[\\/])?[^:]+):(?P<line>\d+): WARNING: (?P<msg>.+)" +) + +# Regex pattern to match the line numbers in a Git unified diff +DIFF_PATTERN = re.compile( + r"^@@ -(?P<linea>\d+)(?:,(?P<removed>\d+))? \+(?P<lineb>\d+)(?:,(?P<added>\d+))? @@", + flags=re.MULTILINE, +) + + +def get_diff_files(ref_a: str, ref_b: str, filter_mode: str = "") -> set[Path]: + """List the files changed between two Git refs, filtered by change type.""" + added_files_result = subprocess.run( + [ + "git", + "diff", + f"--diff-filter={filter_mode}", + "--name-only", + f"{ref_a}...{ref_b}", + "--", + ], + stdout=subprocess.PIPE, + check=True, + text=True, + encoding="UTF-8", + ) + + added_files = added_files_result.stdout.strip().split("\n") + return {Path(file.strip()) for file in added_files if file.strip()} + + +def get_diff_lines(ref_a: str, ref_b: str, file: Path) -> list[int]: + """List the lines changed between two Git refs for a specific file.""" + diff_output = subprocess.run( + [ + "git", + "diff", + "--unified=0", + f"{ref_a}...{ref_b}", + "--", + str(file), + ], + stdout=subprocess.PIPE, + check=True, + text=True, + encoding="UTF-8", + ) + + # Scrape line offsets + lengths from diff and convert to line numbers + line_matches = DIFF_PATTERN.finditer(diff_output.stdout) + # Removed and added line counts are 1 if not printed + line_match_values = [ + line_match.groupdict(default=1) for line_match in line_matches + ] + line_ints = [ + (int(match_value["lineb"]), int(match_value["added"])) + for match_value in line_match_values + ] + line_ranges = [ + range(line_b, line_b + added) for line_b, added in line_ints + ] + line_numbers = list(itertools.chain(*line_ranges)) + + return line_numbers + + +def get_para_line_numbers(file_obj: TextIO) -> list[list[int]]: + """Get the line numbers of text in a file object, grouped by paragraph.""" + paragraphs = [] + prev_line = None + for lineno, line in enumerate(file_obj): + lineno = lineno + 1 + if prev_line is None or (line.strip() and not prev_line.strip()): + paragraph = [lineno - 1] + paragraphs.append(paragraph) + paragraph.append(lineno) + prev_line = line + return paragraphs + + +def filter_and_parse_warnings( + warnings: list[str], files: set[Path] +) -> list[re.Match[str]]: + """Get the warnings matching passed files and parse them with regex.""" + filtered_warnings = [ + warning + for warning in warnings + if any(str(file) in warning for file in files) + ] + warning_matches = [ + WARNING_PATTERN.fullmatch(warning.strip()) + for warning in filtered_warnings + ] + non_null_matches = [warning for warning in warning_matches if warning] + return non_null_matches + + +def filter_warnings_by_diff( + warnings: list[re.Match[str]], ref_a: str, ref_b: str, file: Path +) -> list[re.Match[str]]: + """Filter the passed per-file warnings to just those on changed lines.""" + diff_lines = get_diff_lines(ref_a, ref_b, file) + with file.open(encoding="UTF-8") as file_obj: + paragraphs = get_para_line_numbers(file_obj) + touched_paras = [ + para_lines + for para_lines in paragraphs + if set(diff_lines) & set(para_lines) + ] + touched_para_lines = set(itertools.chain(*touched_paras)) + warnings_infile = [ + warning for warning in warnings if str(file) in warning["file"] + ] + warnings_touched = [ + warning + for warning in warnings_infile + if int(warning["line"]) in touched_para_lines + ] + return warnings_touched + + +def process_touched_warnings( + warnings: list[str], ref_a: str, ref_b: str +) -> list[re.Match[str]]: + """Filter a list of Sphinx warnings to those affecting touched lines.""" + added_files, modified_files = tuple( + get_diff_files(ref_a, ref_b, filter_mode=mode) for mode in ("A", "M") + ) + + warnings_added = filter_and_parse_warnings(warnings, added_files) + warnings_modified = filter_and_parse_warnings(warnings, modified_files) + + modified_files_warned = { + file + for file in modified_files + if any(str(file) in warning["file"] for warning in warnings_modified) + } + + warnings_modified_touched = [ + filter_warnings_by_diff(warnings_modified, ref_a, ref_b, file) + for file in modified_files_warned + ] + warnings_touched = warnings_added + list( + itertools.chain(*warnings_modified_touched) + ) + + return warnings_touched + + +def annotate_diff( + warnings: list[str], ref_a: str = "main", ref_b: str = "HEAD" +) -> None: + """ + Convert Sphinx warning messages to GitHub Actions for changed paragraphs. + + Converts lines like: + .../Doc/library/cgi.rst:98: WARNING: reference target not found + to: + ::warning file=.../Doc/library/cgi.rst,line=98::reference target not found + + See: + https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#setting-a-warning-message + """ + warnings_touched = process_touched_warnings(warnings, ref_a, ref_b) + print("Emitting doc warnings matching modified lines:") + for warning in warnings_touched: + print("::warning file={file},line={line}::{msg}".format_map(warning)) + print(warning[0]) + if not warnings_touched: + print("None") + + +def fail_if_regression( + warnings: list[str], files_with_expected_nits: set[str], files_with_nits: set[str] +) -> int: + """ + Ensure some files always pass Sphinx nit-picky mode (no missing references). + These are files which are *not* in .nitignore. + """ + all_rst = { + str(rst) + for rst in Path("Doc/").rglob("*.rst") + if rst.parts[1] not in EXCLUDE_SUBDIRS + } + should_be_clean = all_rst - files_with_expected_nits - EXCLUDE_FILES + problem_files = sorted(should_be_clean & files_with_nits) + if problem_files: + print("\nError: must not contain warnings:\n") + for filename in problem_files: + print(filename) + for warning in warnings: + if filename in warning: + if match := WARNING_PATTERN.fullmatch(warning): + print(" {line}: {msg}".format_map(match)) + return -1 + return 0 + + +def fail_if_improved( + files_with_expected_nits: set[str], files_with_nits: set[str] +) -> int: + """ + We may have fixed warnings in some files so that the files are now completely clean. + Good news! Let's add them to .nitignore to prevent regression. + """ + files_with_no_nits = files_with_expected_nits - files_with_nits + if files_with_no_nits: + print("\nCongratulations! You improved:\n") + for filename in sorted(files_with_no_nits): + print(filename) + print("\nPlease remove from Doc/tools/.nitignore\n") + return -1 + return 0 + + +def main(argv: list[str] | None = None) -> int: + parser = argparse.ArgumentParser() + parser.add_argument( + "--annotate-diff", + nargs="*", + metavar=("BASE_REF", "HEAD_REF"), + help="Add GitHub Actions annotations on the diff for warnings on " + "lines changed between the given refs (main and HEAD, by default)", + ) + parser.add_argument( + "--fail-if-regression", + action="store_true", + help="Fail if known-good files have warnings", + ) + parser.add_argument( + "--fail-if-improved", + action="store_true", + help="Fail if new files with no nits are found", + ) + + args = parser.parse_args(argv) + if args.annotate_diff is not None and len(args.annotate_diff) > 2: + parser.error( + "--annotate-diff takes between 0 and 2 ref args, not " + f"{len(args.annotate_diff)} {tuple(args.annotate_diff)}" + ) + exit_code = 0 + + wrong_directory_msg = "Must run this script from the repo root" + assert Path("Doc").exists() and Path("Doc").is_dir(), wrong_directory_msg + + with Path("Doc/sphinx-warnings.txt").open(encoding="UTF-8") as f: + warnings = f.read().splitlines() + + cwd = str(Path.cwd()) + os.path.sep + files_with_nits = { + warning.removeprefix(cwd).split(":")[0] + for warning in warnings + if "Doc/" in warning + } + + with Path("Doc/tools/.nitignore").open(encoding="UTF-8") as clean_files: + files_with_expected_nits = { + filename.strip() + for filename in clean_files + if filename.strip() and not filename.startswith("#") + } + + if args.annotate_diff is not None: + annotate_diff(warnings, *args.annotate_diff) + + if args.fail_if_regression: + exit_code += fail_if_regression( + warnings, files_with_expected_nits, files_with_nits + ) + + if args.fail_if_improved: + exit_code += fail_if_improved(files_with_expected_nits, files_with_nits) + + return exit_code + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/Doc/tools/extensions/asdl_highlight.py b/Doc/tools/extensions/asdl_highlight.py index b1989e53..42863a4b 100644 --- a/Doc/tools/extensions/asdl_highlight.py +++ b/Doc/tools/extensions/asdl_highlight.py @@ -1,4 +1,3 @@ -import os import sys from pathlib import Path @@ -6,7 +5,7 @@ CPYTHON_ROOT = Path(__file__).resolve().parent.parent.parent.parent sys.path.append(str(CPYTHON_ROOT / "Parser")) from pygments.lexer import RegexLexer, bygroups, include, words -from pygments.token import (Comment, Generic, Keyword, Name, Operator, +from pygments.token import (Comment, Keyword, Name, Operator, Punctuation, Text) from asdl import builtin_types diff --git a/Doc/tools/extensions/c_annotations.py b/Doc/tools/extensions/c_annotations.py index 9defb24a..3551bfa4 100644 --- a/Doc/tools/extensions/c_annotations.py +++ b/Doc/tools/extensions/c_annotations.py @@ -20,10 +20,12 @@ """ from os import path +import docutils from docutils import nodes from docutils.parsers.rst import directives from docutils.parsers.rst import Directive from docutils.statemachine import StringList +from sphinx.locale import _ as sphinx_gettext import csv from sphinx import addnodes @@ -40,6 +42,16 @@ REST_ROLE_MAP = { } +# Monkeypatch nodes.Node.findall for forwards compatability +# This patch can be dropped when the minimum Sphinx version is 4.4.0 +# or the minimum Docutils version is 0.18.1. +if docutils.__version_info__ < (0, 18, 1): + def findall(self, *args, **kwargs): + return iter(self.traverse(*args, **kwargs)) + + nodes.Node.findall = findall + + class RCEntry: def __init__(self, name): self.name = name @@ -86,7 +98,7 @@ class Annotations: self.stable_abi_data[name] = record def add_annotations(self, app, doctree): - for node in doctree.traverse(addnodes.desc_content): + for node in doctree.findall(addnodes.desc_content): par = node.parent if par['domain'] != 'c': continue @@ -143,6 +155,22 @@ class Annotations: ' (Only some members are part of the stable ABI.)') node.insert(0, emph_node) + # Unstable API annotation. + if name.startswith('PyUnstable'): + warn_node = nodes.admonition( + classes=['unstable-c-api', 'warning']) + message = 'This is ' + emph_node = nodes.emphasis(message, message) + ref_node = addnodes.pending_xref( + 'Unstable API', refdomain="std", + reftarget='unstable-c-api', + reftype='ref', refexplicit="False") + ref_node += nodes.Text('Unstable API') + emph_node += ref_node + emph_node += nodes.Text('. It may change without warning in minor releases.') + warn_node += emph_node + node.insert(0, warn_node) + # Return value annotation if objtype != 'function': continue @@ -152,11 +180,11 @@ class Annotations: elif not entry.result_type.endswith("Object*"): continue if entry.result_refs is None: - rc = 'Return value: Always NULL.' + rc = sphinx_gettext('Return value: Always NULL.') elif entry.result_refs: - rc = 'Return value: New reference.' + rc = sphinx_gettext('Return value: New reference.') else: - rc = 'Return value: Borrowed reference.' + rc = sphinx_gettext('Return value: Borrowed reference.') node.insert(0, nodes.emphasis(rc, rc, classes=['refcount'])) diff --git a/Doc/tools/extensions/peg_highlight.py b/Doc/tools/extensions/peg_highlight.py index 27f54cdf..4bdc2ee1 100644 --- a/Doc/tools/extensions/peg_highlight.py +++ b/Doc/tools/extensions/peg_highlight.py @@ -1,5 +1,5 @@ from pygments.lexer import RegexLexer, bygroups, include -from pygments.token import Comment, Generic, Keyword, Name, Operator, Punctuation, Text +from pygments.token import Comment, Keyword, Name, Operator, Punctuation, Text from sphinx.highlighting import lexers diff --git a/Doc/tools/extensions/pyspecific.py b/Doc/tools/extensions/pyspecific.py index 6c383ea5..c286bcf3 100644 --- a/Doc/tools/extensions/pyspecific.py +++ b/Doc/tools/extensions/pyspecific.py @@ -14,38 +14,32 @@ import io from os import getenv, path from time import asctime from pprint import pformat + +from docutils import nodes, utils from docutils.io import StringOutput from docutils.parsers.rst import Directive from docutils.utils import new_document - -from docutils import nodes, utils - from sphinx import addnodes from sphinx.builders import Builder -try: - from sphinx.errors import NoUri -except ImportError: - from sphinx.environment import NoUri +from sphinx.domains.python import PyFunction, PyMethod +from sphinx.errors import NoUri from sphinx.locale import _ as sphinx_gettext -from sphinx.util import status_iterator, logging +from sphinx.util import logging +from sphinx.util.docutils import SphinxDirective from sphinx.util.nodes import split_explicit_title from sphinx.writers.text import TextWriter, TextTranslator -from sphinx.writers.latex import LaTeXTranslator try: - from sphinx.domains.python import PyFunction, PyMethod + # Sphinx 6+ + from sphinx.util.display import status_iterator except ImportError: - from sphinx.domains.python import PyClassmember as PyMethod - from sphinx.domains.python import PyModulelevel as PyFunction - -# Support for checking for suspicious markup - -import suspicious + # Deprecated in Sphinx 6.1, will be removed in Sphinx 8 + from sphinx.util import status_iterator ISSUE_URI = 'https://bugs.python.org/issue?@action=redirect&bpo=%s' GH_ISSUE_URI = 'https://github.com/python/cpython/issues/%s' -SOURCE_URI = 'https://github.com/python/cpython/tree/3.11/%s' +SOURCE_URI = 'https://github.com/python/cpython/tree/3.12/%s' # monkey-patch reST parser to disable alphabetic and roman enumerated lists from docutils.parsers.rst.states import Body @@ -104,14 +98,13 @@ class ImplementationDetail(Directive): final_argument_whitespace = True # This text is copied to templates/dummy.html - label_text = 'CPython implementation detail:' + label_text = sphinx_gettext('CPython implementation detail:') def run(self): self.assert_has_content() pnode = nodes.compound(classes=['impl-detail']) - label = sphinx_gettext(self.label_text) content = self.content - add_text = nodes.strong(label, label) + add_text = nodes.strong(self.label_text, self.label_text) self.state.nested_parse(content, self.content_offset, pnode) content = nodes.inline(pnode[0].rawsource, translatable=True) content.source = pnode[0].source @@ -124,7 +117,7 @@ class ImplementationDetail(Directive): # Support for documenting platform availability -class Availability(Directive): +class Availability(SphinxDirective): has_content = True required_arguments = 1 @@ -144,18 +137,19 @@ class Availability(Directive): def run(self): availability_ref = ':ref:`Availability <availability>`: ' + avail_nodes, avail_msgs = self.state.inline_text( + availability_ref + self.arguments[0], + self.lineno) pnode = nodes.paragraph(availability_ref + self.arguments[0], - classes=["availability"],) - n, m = self.state.inline_text(availability_ref, self.lineno) - pnode.extend(n + m) - n, m = self.state.inline_text(self.arguments[0], self.lineno) - pnode.extend(n + m) + '', *avail_nodes, *avail_msgs) + self.set_source_info(pnode) + cnode = nodes.container("", pnode, classes=["availability"]) + self.set_source_info(cnode) if self.content: - self.state.nested_parse(self.content, self.content_offset, pnode) - + self.state.nested_parse(self.content, self.content_offset, cnode) self.parse_platforms() - return [pnode] + return [cnode] def parse_platforms(self): """Parse platform information from arguments @@ -185,7 +179,7 @@ class Availability(Directive): if unknown: cls = type(self) logger = logging.getLogger(cls.__qualname__) - logger.warn( + logger.warning( f"Unknown platform(s) or syntax '{' '.join(sorted(unknown))}' " f"in '.. availability:: {self.arguments[0]}', see " f"{__file__}:{cls.__qualname__}.known_platforms for a set " @@ -239,9 +233,9 @@ class AuditEvent(Directive): final_argument_whitespace = True _label = [ - "Raises an :ref:`auditing event <auditing>` {name} with no arguments.", - "Raises an :ref:`auditing event <auditing>` {name} with argument {args}.", - "Raises an :ref:`auditing event <auditing>` {name} with arguments {args}.", + sphinx_gettext("Raises an :ref:`auditing event <auditing>` {name} with no arguments."), + sphinx_gettext("Raises an :ref:`auditing event <auditing>` {name} with argument {args}."), + sphinx_gettext("Raises an :ref:`auditing event <auditing>` {name} with arguments {args}."), ] @property @@ -257,7 +251,7 @@ class AuditEvent(Directive): else: args = [] - label = sphinx_gettext(self._label[min(2, len(args))]) + label = self._label[min(2, len(args))] text = label.format(name="``{}``".format(name), args=", ".join("``{}``".format(a) for a in args if a)) @@ -272,7 +266,7 @@ class AuditEvent(Directive): info = env.all_audit_events.setdefault(name, new_info) if info is not new_info: if not self._do_args_match(info['args'], new_info['args']): - self.logger.warn( + self.logger.warning( "Mismatched arguments for audit-event {}: {!r} != {!r}" .format(name, info['args'], new_info['args']) ) @@ -419,8 +413,8 @@ class DeprecatedRemoved(Directive): final_argument_whitespace = True option_spec = {} - _deprecated_label = 'Deprecated since version {deprecated}, will be removed in version {removed}' - _removed_label = 'Deprecated since version {deprecated}, removed in version {removed}' + _deprecated_label = sphinx_gettext('Deprecated since version {deprecated}, will be removed in version {removed}') + _removed_label = sphinx_gettext('Deprecated since version {deprecated}, removed in version {removed}') def run(self): node = addnodes.versionmodified() @@ -436,7 +430,6 @@ class DeprecatedRemoved(Directive): else: label = self._removed_label - label = sphinx_gettext(label) text = label.format(deprecated=self.arguments[0], removed=self.arguments[1]) if len(self.arguments) == 3: inodes, messages = self.state.inline_text(self.arguments[2], @@ -549,7 +542,7 @@ class PydocTopicsBuilder(Builder): 'building topics... ', length=len(pydoc_topic_labels)): if label not in self.env.domaindata['std']['labels']: - self.env.logger.warn('label %r not in documentation' % label) + self.env.logger.warning(f'label {label!r} not in documentation') continue docname, labelid, sectname = self.env.domaindata['std']['labels'][label] doctree = self.env.get_and_resolve_doctree(docname, self) @@ -564,6 +557,7 @@ class PydocTopicsBuilder(Builder): try: f.write('# -*- coding: utf-8 -*-\n'.encode('utf-8')) f.write(('# Autogenerated by Sphinx on %s\n' % asctime()).encode('utf-8')) + f.write('# as part of the release process.\n'.encode('utf-8')) f.write(('topics = ' + pformat(self.topics) + '\n').encode('utf-8')) finally: f.close() @@ -677,6 +671,30 @@ def process_audit_events(app, doctree, fromdocname): node.replace_self(table) +def patch_pairindextypes(app, _env) -> None: + """Remove all entries from ``pairindextypes`` before writing POT files. + + We want to run this just before writing output files, as the check to + circumvent is in ``I18nBuilder.write_doc()``. + As such, we link this to ``env-check-consistency``, even though it has + nothing to do with the environment consistency check. + """ + if app.builder.name != 'gettext': + return + + # allow translating deprecated index entries + try: + from sphinx.domains.python import pairindextypes + except ImportError: + pass + else: + # Sphinx checks if a 'pair' type entry on an index directive is one of + # the Sphinx-translated pairindextypes values. As we intend to move + # away from this, we need Sphinx to believe that these values don't + # exist, by deleting them when using the gettext builder. + pairindextypes.clear() + + def setup(app): app.add_role('issue', issue_role) app.add_role('gh', gh_issue_role) @@ -687,7 +705,6 @@ def setup(app): app.add_directive('audit-event-table', AuditEventListDirective) app.add_directive('deprecated-removed', DeprecatedRemoved) app.add_builder(PydocTopicsBuilder) - app.add_builder(suspicious.CheckSuspiciousMarkupBuilder) app.add_object_type('opcode', 'opcode', '%s (opcode)', parse_opcode_signature) app.add_object_type('pdbcommand', 'pdbcmd', '%s (pdb command)', parse_pdb_command) app.add_object_type('2to3fixer', '2to3fixer', '%s (2to3 fixer)') @@ -699,6 +716,7 @@ def setup(app): app.add_directive_to_domain('py', 'awaitablemethod', PyAwaitableMethod) app.add_directive_to_domain('py', 'abstractmethod', PyAbstractMethod) app.add_directive('miscnews', MiscNews) + app.connect('env-check-consistency', patch_pairindextypes) app.connect('doctree-resolved', process_audit_events) app.connect('env-merge-info', audit_events_merge) app.connect('env-purge-doc', audit_events_purge) diff --git a/Doc/tools/extensions/suspicious.py b/Doc/tools/extensions/suspicious.py deleted file mode 100644 index 2d581a8a..00000000 --- a/Doc/tools/extensions/suspicious.py +++ /dev/null @@ -1,251 +0,0 @@ -""" -Try to detect suspicious constructs, resembling markup -that has leaked into the final output. - -Suspicious lines are reported in a comma-separated-file, -``suspicious.csv``, located in the output directory. - -The file is utf-8 encoded, and each line contains four fields: - - * document name (normalized) - * line number in the source document - * problematic text - * complete line showing the problematic text in context - -It is common to find many false positives. To avoid reporting them -again and again, they may be added to the ``ignored.csv`` file -(located in the configuration directory). The file has the same -format as ``suspicious.csv`` with a few differences: - - - each line defines a rule; if the rule matches, the issue - is ignored. - - line number may be empty (that is, nothing between the - commas: ",,"). In this case, line numbers are ignored (the - rule matches anywhere in the file). - - the last field does not have to be a complete line; some - surrounding text (never more than a line) is enough for - context. - -Rules are processed sequentially. A rule matches when: - - * document names are the same - * problematic texts are the same - * line numbers are close to each other (5 lines up or down) - * the rule text is completely contained into the source line - -The simplest way to create the ignored.csv file is by copying -undesired entries from suspicious.csv (possibly trimming the last -field.) - -Copyright 2009 Gabriel A. Genellina - -""" - -import os -import re -import csv - -from docutils import nodes -from sphinx.builders import Builder -import sphinx.util - -detect_all = re.compile(r''' - ::(?=[^=])| # two :: (but NOT ::=) - :[a-zA-Z][a-zA-Z0-9]+| # :foo - `| # ` (seldom used by itself) - (?<!\.)\.\.[ \t]*\w+: # .. foo: (but NOT ... else:) - ''', re.VERBOSE).finditer - - -class Rule: - def __init__(self, docname, lineno, issue, line): - """A rule for ignoring issues""" - self.docname = docname # document to which this rule applies - self.lineno = lineno # line number in the original source; - # this rule matches only near that. - # None -> don't care - self.issue = issue # the markup fragment that triggered this rule - self.line = line # text of the container element (single line only) - self.used = False - - def __repr__(self): - return '{0.docname},,{0.issue},{0.line}'.format(self) - - - -class dialect(csv.excel): - """Our dialect: uses only linefeed as newline.""" - lineterminator = '\n' - - -class CheckSuspiciousMarkupBuilder(Builder): - """ - Checks for possibly invalid markup that may leak into the output. - """ - name = 'suspicious' - logger = sphinx.util.logging.getLogger("CheckSuspiciousMarkupBuilder") - - def init(self): - # create output file - self.log_file_name = os.path.join(self.outdir, 'suspicious.csv') - open(self.log_file_name, 'w').close() - # load database of previously ignored issues - self.load_rules(os.path.join(os.path.dirname(__file__), '..', - 'susp-ignored.csv')) - - def get_outdated_docs(self): - return self.env.found_docs - - def get_target_uri(self, docname, typ=None): - return '' - - def prepare_writing(self, docnames): - pass - - def write_doc(self, docname, doctree): - # set when any issue is encountered in this document - self.any_issue = False - self.docname = docname - visitor = SuspiciousVisitor(doctree, self) - doctree.walk(visitor) - - def finish(self): - unused_rules = [rule for rule in self.rules if not rule.used] - if unused_rules: - self.logger.warning( - 'Found %s/%s unused rules: %s' % ( - len(unused_rules), len(self.rules), - '\n'.join(repr(rule) for rule in unused_rules), - ) - ) - return - - def check_issue(self, line, lineno, issue): - if not self.is_ignored(line, lineno, issue): - self.report_issue(line, lineno, issue) - - def is_ignored(self, line, lineno, issue): - """Determine whether this issue should be ignored.""" - docname = self.docname - for rule in self.rules: - if rule.docname != docname: continue - if rule.issue != issue: continue - # Both lines must match *exactly*. This is rather strict, - # and probably should be improved. - # Doing fuzzy matches with levenshtein distance could work, - # but that means bringing other libraries... - # Ok, relax that requirement: just check if the rule fragment - # is contained in the document line - if rule.line not in line: continue - # Check both line numbers. If they're "near" - # this rule matches. (lineno=None means "don't care") - if (rule.lineno is not None) and \ - abs(rule.lineno - lineno) > 5: continue - # if it came this far, the rule matched - rule.used = True - return True - return False - - def report_issue(self, text, lineno, issue): - self.any_issue = True - self.write_log_entry(lineno, issue, text) - self.logger.warning('[%s:%d] "%s" found in "%-.120s"' % - (self.docname, lineno, issue, text)) - self.app.statuscode = 1 - - def write_log_entry(self, lineno, issue, text): - f = open(self.log_file_name, 'a') - writer = csv.writer(f, dialect) - writer.writerow([self.docname, lineno, issue, text.strip()]) - f.close() - - def load_rules(self, filename): - """Load database of previously ignored issues. - - A csv file, with exactly the same format as suspicious.csv - Fields: document name (normalized), line number, issue, surrounding text - """ - self.logger.info("loading ignore rules... ", nonl=1) - self.rules = rules = [] - try: - f = open(filename, 'r') - except IOError: - return - for i, row in enumerate(csv.reader(f)): - if len(row) != 4: - raise ValueError( - "wrong format in %s, line %d: %s" % (filename, i+1, row)) - docname, lineno, issue, text = row - if lineno: - lineno = int(lineno) - else: - lineno = None - rule = Rule(docname, lineno, issue, text) - rules.append(rule) - f.close() - self.logger.info('done, %d rules loaded' % len(self.rules)) - - -def get_lineno(node): - """Obtain line number information for a node.""" - lineno = None - while lineno is None and node: - node = node.parent - lineno = node.line - return lineno - - -def extract_line(text, index): - """text may be a multiline string; extract - only the line containing the given character index. - - >>> extract_line("abc\ndefgh\ni", 6) - >>> 'defgh' - >>> for i in (0, 2, 3, 4, 10): - ... print extract_line("abc\ndefgh\ni", i) - abc - abc - abc - defgh - defgh - i - """ - p = text.rfind('\n', 0, index) + 1 - q = text.find('\n', index) - if q < 0: - q = len(text) - return text[p:q] - - -class SuspiciousVisitor(nodes.GenericNodeVisitor): - - lastlineno = 0 - - def __init__(self, document, builder): - nodes.GenericNodeVisitor.__init__(self, document) - self.builder = builder - - def default_visit(self, node): - if isinstance(node, (nodes.Text, nodes.image)): # direct text containers - text = node.astext() - # lineno seems to go backwards sometimes (?) - self.lastlineno = lineno = max(get_lineno(node) or 0, self.lastlineno) - seen = set() # don't report the same issue more than only once per line - for match in detect_all(text): - issue = match.group() - line = extract_line(text, match.start()) - if (issue, line) not in seen: - self.builder.check_issue(line, lineno, issue) - seen.add((issue, line)) - - unknown_visit = default_visit - - def visit_document(self, node): - self.lastlineno = 0 - - def visit_comment(self, node): - # ignore comments -- too much false positives. - # (although doing this could miss some errors; - # there were two sections "commented-out" by mistake - # in the Python docs that would not be caught) - raise nodes.SkipNode diff --git a/Doc/tools/rstlint.py b/Doc/tools/rstlint.py deleted file mode 100644 index 4ea68ef3..00000000 --- a/Doc/tools/rstlint.py +++ /dev/null @@ -1,408 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - -# Check for stylistic and formal issues in .rst and .py -# files included in the documentation. -# -# 01/2009, Georg Brandl - -# TODO: - wrong versions in versionadded/changed -# - wrong markup after versionchanged directive - -import os -import re -import sys -import getopt -from string import ascii_letters -from os.path import join, splitext, abspath, exists -from collections import defaultdict - -directives = [ - # standard docutils ones - 'admonition', 'attention', 'caution', 'class', 'compound', 'container', - 'contents', 'csv-table', 'danger', 'date', 'default-role', 'epigraph', - 'error', 'figure', 'footer', 'header', 'highlights', 'hint', 'image', - 'important', 'include', 'line-block', 'list-table', 'meta', 'note', - 'parsed-literal', 'pull-quote', 'raw', 'replace', - 'restructuredtext-test-directive', 'role', 'rubric', 'sectnum', 'sidebar', - 'table', 'target-notes', 'tip', 'title', 'topic', 'unicode', 'warning', - # Sphinx and Python docs custom ones - 'acks', 'attribute', 'autoattribute', 'autoclass', 'autodata', - 'autoexception', 'autofunction', 'automethod', 'automodule', - 'availability', 'centered', 'cfunction', 'class', 'classmethod', 'cmacro', - 'cmdoption', 'cmember', 'code-block', 'confval', 'cssclass', 'ctype', - 'currentmodule', 'cvar', 'data', 'decorator', 'decoratormethod', - 'deprecated-removed', 'deprecated(?!-removed)', 'describe', 'directive', - 'doctest', 'envvar', 'event', 'exception', 'function', 'glossary', - 'highlight', 'highlightlang', 'impl-detail', 'index', 'literalinclude', - 'method', 'miscnews', 'module', 'moduleauthor', 'opcode', 'pdbcommand', - 'productionlist', 'program', 'role', 'sectionauthor', 'seealso', - 'sourcecode', 'staticmethod', 'tabularcolumns', 'testcode', 'testoutput', - 'testsetup', 'toctree', 'todo', 'todolist', 'versionadded', - 'versionchanged' -] - -roles = [ - "(?<!py):class:", - "(?<!:c|py):func:", - "(?<!py):meth:", - "(?<!:py):mod:", - ":exc:", - ":issue:", - ":attr:", - ":c:func:", - ":ref:", - ":const:", - ":term:", - "(?<!:c|py):data:", - ":keyword:", - ":file:", - ":pep:", - ":c:type:", - ":c:member:", - ":option:", - ":rfc:", - ":envvar:", - ":c:data:", - ":source:", - ":mailheader:", - ":program:", - ":c:macro:", - ":dfn:", - ":kbd:", - ":command:", - ":mimetype:", - ":opcode:", - ":manpage:", - ":py:data:", - ":RFC:", - ":pdbcmd:", - ":abbr:", - ":samp:", - ":token:", - ":PEP:", - ":sup:", - ":py:class:", - ":menuselection:", - ":doc:", - ":sub:", - ":py:meth:", - ":newsgroup:", - ":code:", - ":py:func:", - ":makevar:", - ":guilabel:", - ":title-reference:", - ":py:mod:", - ":download:", - ":2to3fixer:", -] - -all_directives = "(" + "|".join(directives) + ")" -all_roles = "(" + "|".join(roles) + ")" - -# Find comments that looks like a directive, like: -# .. versionchanged 3.6 -# or -# .. versionchanged: 3.6 -# as it should be: -# .. versionchanged:: 3.6 -seems_directive_re = re.compile(r"(?<!\.)\.\. %s([^a-z:]|:(?!:))" % all_directives) - -# Find directive prefixed with three dots instead of two, like: -# ... versionchanged:: 3.6 -# instead of: -# .. versionchanged:: 3.6 -three_dot_directive_re = re.compile(r"\.\.\. %s::" % all_directives) - -# Find role used with double backticks instead of simple backticks like: -# :const:``None`` -# instead of: -# :const:`None` -double_backtick_role = re.compile(r"(?<!``)%s``" % all_roles) - - -# Find role used with no backticks instead of simple backticks like: -# :const:None -# instead of: -# :const:`None` -role_with_no_backticks = re.compile(r"%s[^` ]" % all_roles) - -# Find role glued with another word like: -# the:c:func:`PyThreadState_LeaveTracing` function. -# instead of: -# the :c:func:`PyThreadState_LeaveTracing` function. -role_glued_with_word = re.compile(r"[a-zA-Z]%s" % all_roles) - -default_role_re = re.compile(r"(^| )`\w([^`]*?\w)?`($| )") -leaked_markup_re = re.compile(r"[a-z]::\s|`|\.\.\s*\w+:") - - -checkers = {} - -checker_props = {'severity': 1, 'falsepositives': False} - - -def checker(*suffixes, **kwds): - """Decorator to register a function as a checker.""" - def deco(func): - for suffix in suffixes: - checkers.setdefault(suffix, []).append(func) - for prop in checker_props: - setattr(func, prop, kwds.get(prop, checker_props[prop])) - return func - return deco - - -@checker('.py', severity=4) -def check_syntax(fn, lines): - """Check Python examples for valid syntax.""" - code = ''.join(lines) - if '\r' in code: - if os.name != 'nt': - yield 0, '\\r in code file' - code = code.replace('\r', '') - try: - compile(code, fn, 'exec') - except SyntaxError as err: - yield err.lineno, 'not compilable: %s' % err - - -@checker('.rst', severity=2) -def check_suspicious_constructs(fn, lines): - """Check for suspicious reST constructs.""" - inprod = False - for lno, line in enumerate(lines, start=1): - if seems_directive_re.search(line): - yield lno, "comment seems to be intended as a directive" - if three_dot_directive_re.search(line): - yield lno, "directive should start with two dots, not three." - if double_backtick_role.search(line): - yield lno, "role use a single backtick, double backtick found." - if role_with_no_backticks.search(line): - yield lno, "role use a single backtick, no backtick found." - if role_glued_with_word.search(line): - yield lno, "missing space before role" - if ".. productionlist::" in line: - inprod = True - elif not inprod and default_role_re.search(line): - yield lno, "default role used" - elif inprod and not line.strip(): - inprod = False - - -@checker('.py', '.rst') -def check_whitespace(fn, lines): - """Check for whitespace and line length issues.""" - for lno, line in enumerate(lines): - if '\r' in line: - yield lno+1, '\\r in line' - if '\t' in line: - yield lno+1, 'OMG TABS!!!1' - if line[:-1].rstrip(' \t') != line[:-1]: - yield lno+1, 'trailing whitespace' - - -@checker('.rst', severity=0) -def check_line_length(fn, lines): - """Check for line length; this checker is not run by default.""" - for lno, line in enumerate(lines): - if len(line) > 81: - # don't complain about tables, links and function signatures - if line.lstrip()[0] not in '+|' and \ - 'http://' not in line and \ - not line.lstrip().startswith(('.. function', - '.. method', - '.. cfunction')): - yield lno+1, "line too long" - - -@checker('.html', severity=2, falsepositives=True) -def check_leaked_markup(fn, lines): - """Check HTML files for leaked reST markup; this only works if - the HTML files have been built. - """ - for lno, line in enumerate(lines): - if leaked_markup_re.search(line): - yield lno+1, 'possibly leaked markup: %r' % line - - -def hide_literal_blocks(lines): - """Tool to remove literal blocks from given lines. - - It yields empty lines in place of blocks, so line numbers are - still meaningful. - """ - in_block = False - for line in lines: - if line.endswith("::\n"): - in_block = True - elif in_block: - if line == "\n" or line.startswith(" "): - line = "\n" - else: - in_block = False - yield line - - -def type_of_explicit_markup(line): - if re.match(fr'\.\. {all_directives}::', line): - return 'directive' - if re.match(r'\.\. \[[0-9]+\] ', line): - return 'footnote' - if re.match(r'\.\. \[[^\]]+\] ', line): - return 'citation' - if re.match(r'\.\. _.*[^_]: ', line): - return 'target' - if re.match(r'\.\. \|[^\|]*\| ', line): - return 'substitution_definition' - return 'comment' - - -def hide_comments(lines): - """Tool to remove comments from given lines. - - It yields empty lines in place of comments, so line numbers are - still meaningful. - """ - in_multiline_comment = False - for line in lines: - if line == "..\n": - in_multiline_comment = True - elif in_multiline_comment: - if line == "\n" or line.startswith(" "): - line = "\n" - else: - in_multiline_comment = False - if line.startswith(".. ") and type_of_explicit_markup(line) == 'comment': - line = "\n" - yield line - - - -@checker(".rst", severity=2) -def check_missing_surrogate_space_on_plural(fn, lines): - r"""Check for missing 'backslash-space' between a code sample a letter. - - Good: ``Point``\ s - Bad: ``Point``s - """ - in_code_sample = False - check_next_one = False - for lno, line in enumerate(hide_comments(hide_literal_blocks(lines))): - tokens = line.split("``") - for token_no, token in enumerate(tokens): - if check_next_one: - if token[0] in ascii_letters: - yield lno + 1, f"Missing backslash-space between code sample and {token!r}." - check_next_one = False - if token_no == len(tokens) - 1: - continue - if in_code_sample: - check_next_one = True - in_code_sample = not in_code_sample - -def main(argv): - usage = '''\ -Usage: %s [-v] [-f] [-s sev] [-i path]* [path] - -Options: -v verbose (print all checked file names) - -f enable checkers that yield many false positives - -s sev only show problems with severity >= sev - -i path ignore subdir or file path -''' % argv[0] - try: - gopts, args = getopt.getopt(argv[1:], 'vfs:i:') - except getopt.GetoptError: - print(usage) - return 2 - - verbose = False - severity = 1 - ignore = [] - falsepos = False - for opt, val in gopts: - if opt == '-v': - verbose = True - elif opt == '-f': - falsepos = True - elif opt == '-s': - severity = int(val) - elif opt == '-i': - ignore.append(abspath(val)) - - if len(args) == 0: - path = '.' - elif len(args) == 1: - path = args[0] - else: - print(usage) - return 2 - - if not exists(path): - print('Error: path %s does not exist' % path) - return 2 - - count = defaultdict(int) - - print("""⚠ rstlint.py is no longer maintained here and will be removed -⚠ in a future release. -⚠ Please use https://pypi.org/p/sphinx-lint instead. -""") - - for root, dirs, files in os.walk(path): - # ignore subdirs in ignore list - if abspath(root) in ignore: - del dirs[:] - continue - - for fn in files: - fn = join(root, fn) - if fn[:2] == './': - fn = fn[2:] - - # ignore files in ignore list - if abspath(fn) in ignore: - continue - - ext = splitext(fn)[1] - checkerlist = checkers.get(ext, None) - if not checkerlist: - continue - - if verbose: - print('Checking %s...' % fn) - - try: - with open(fn, 'r', encoding='utf-8') as f: - lines = list(f) - except (IOError, OSError) as err: - print('%s: cannot open: %s' % (fn, err)) - count[4] += 1 - continue - - for checker in checkerlist: - if checker.falsepositives and not falsepos: - continue - csev = checker.severity - if csev >= severity: - for lno, msg in checker(fn, lines): - print('[%d] %s:%d: %s' % (csev, fn, lno, msg)) - count[csev] += 1 - if verbose: - print() - if not count: - if severity > 1: - print('No problems with severity >= %d found.' % severity) - else: - print('No problems found.') - else: - for severity in sorted(count): - number = count[severity] - print('%d problem%s with severity %d found.' % - (number, number > 1 and 's' or '', severity)) - return int(bool(count)) - - -if __name__ == '__main__': - sys.exit(main(sys.argv)) diff --git a/Doc/tools/susp-ignored.csv b/Doc/tools/susp-ignored.csv deleted file mode 100644 index 29d65cd7..00000000 --- a/Doc/tools/susp-ignored.csv +++ /dev/null @@ -1,398 +0,0 @@ -c-api/arg,,:ref,"PyArg_ParseTuple(args, ""O|O:ref"", &object, &callback)" -c-api/list,,:high,list[low:high] -c-api/sequence,,:i2,del o[i1:i2] -c-api/sequence,,:i2,o[i1:i2] -c-api/tuple,,:high,p[low:high] -c-api/unicode,,:end,str[start:end] -c-api/unicode,,:start,unicode[start:start+length] -distutils/examples,,`,This is the description of the ``foobar`` package. -distutils/setupscript,,::, -extending/embedding,,:numargs,"if(!PyArg_ParseTuple(args, "":numargs""))" -extending/extending,,:myfunction,"PyArg_ParseTuple(args, ""D:myfunction"", &c);" -extending/extending,,:set,"if (PyArg_ParseTuple(args, ""O:set_callback"", &temp)) {" -extending/newtypes,,:call,"if (!PyArg_ParseTuple(args, ""sss:call"", &arg1, &arg2, &arg3)) {" -faq/programming,,:chr,">=4.0) or 1+f(xc,yc,x*x-y*y+xc,2.0*x*y+yc,k-1,f):f(xc,yc,x,y,k,f):chr(" -faq/programming,,:reduce,"print((lambda Ru,Ro,Iu,Io,IM,Sx,Sy:reduce(lambda x,y:x+y,map(lambda y," -faq/programming,,:reduce,"Sx=Sx,Sy=Sy:reduce(lambda x,y:x+y,map(lambda x,xc=Ru,yc=yc,Ru=Ru,Ro=Ro," -faq/windows,,:d48eceb,"Python 3.6.4 (v3.6.4:d48eceb, Dec 19 2017, 06:04:45) [MSC v.1900 32 bit (Intel)] on win32" -howto/curses,,:black,"colors when it activates color mode. They are: 0:black, 1:red," -howto/curses,,:red,"colors when it activates color mode. They are: 0:black, 1:red," -howto/curses,,:green,"2:green, 3:yellow, 4:blue, 5:magenta, 6:cyan, and 7:white. The" -howto/curses,,:yellow,"2:green, 3:yellow, 4:blue, 5:magenta, 6:cyan, and 7:white. The" -howto/curses,,:blue,"2:green, 3:yellow, 4:blue, 5:magenta, 6:cyan, and 7:white. The" -howto/curses,,:magenta,"2:green, 3:yellow, 4:blue, 5:magenta, 6:cyan, and 7:white. The" -howto/curses,,:cyan,"2:green, 3:yellow, 4:blue, 5:magenta, 6:cyan, and 7:white. The" -howto/curses,,:white,"2:green, 3:yellow, 4:blue, 5:magenta, 6:cyan, and 7:white. The" -howto/descriptor,,:root,"INFO:root" -howto/descriptor,,:Updating,"root:Updating" -howto/descriptor,,:Accessing,"root:Accessing" -howto/instrumentation,,::,python$target:::function-entry -howto/instrumentation,,:function,python$target:::function-entry -howto/instrumentation,,::,python$target:::function-return -howto/instrumentation,,:function,python$target:::function-return -howto/instrumentation,,:call,156641360502280 function-entry:call_stack.py:start:23 -howto/instrumentation,,:start,156641360502280 function-entry:call_stack.py:start:23 -howto/instrumentation,,:function,156641360518804 function-entry: call_stack.py:function_1:1 -howto/instrumentation,,:function,156641360532797 function-entry: call_stack.py:function_3:9 -howto/instrumentation,,:function,156641360546807 function-return: call_stack.py:function_3:10 -howto/instrumentation,,:function,156641360563367 function-return: call_stack.py:function_1:2 -howto/instrumentation,,:function,156641360578365 function-entry: call_stack.py:function_2:5 -howto/instrumentation,,:function,156641360591757 function-entry: call_stack.py:function_1:1 -howto/instrumentation,,:function,156641360605556 function-entry: call_stack.py:function_3:9 -howto/instrumentation,,:function,156641360617482 function-return: call_stack.py:function_3:10 -howto/instrumentation,,:function,156641360629814 function-return: call_stack.py:function_1:2 -howto/instrumentation,,:function,156641360642285 function-return: call_stack.py:function_2:6 -howto/instrumentation,,:function,156641360656770 function-entry: call_stack.py:function_3:9 -howto/instrumentation,,:function,156641360669707 function-return: call_stack.py:function_3:10 -howto/instrumentation,,:function,156641360687853 function-entry: call_stack.py:function_4:13 -howto/instrumentation,,:function,156641360700719 function-return: call_stack.py:function_4:14 -howto/instrumentation,,:function,156641360719640 function-entry: call_stack.py:function_5:18 -howto/instrumentation,,:function,156641360732567 function-return: call_stack.py:function_5:21 -howto/instrumentation,,:call,156641360747370 function-return:call_stack.py:start:28 -howto/instrumentation,,:start,156641360747370 function-return:call_stack.py:start:28 -howto/ipaddress,,:DB8,>>> ipaddress.ip_address('2001:DB8::1') -howto/ipaddress,,::,>>> ipaddress.ip_address('2001:DB8::1') -howto/ipaddress,,:db8,IPv6Address('2001:db8::1') -howto/ipaddress,,::,IPv6Address('2001:db8::1') -howto/ipaddress,,::,IPv6Address('::1') -howto/ipaddress,,:db8,>>> ipaddress.ip_network('2001:db8::0/96') -howto/ipaddress,,::,>>> ipaddress.ip_network('2001:db8::0/96') -howto/ipaddress,,:db8,IPv6Network('2001:db8::/96') -howto/ipaddress,,::,IPv6Network('2001:db8::/96') -howto/ipaddress,,:db8,IPv6Network('2001:db8::/128') -howto/ipaddress,,::,IPv6Network('2001:db8::/128') -howto/ipaddress,,:db8,IPv6Interface('2001:db8::1/96') -howto/ipaddress,,::,IPv6Interface('2001:db8::1/96') -howto/ipaddress,,:db8,>>> addr6 = ipaddress.ip_address('2001:db8::1') -howto/ipaddress,,::,>>> addr6 = ipaddress.ip_address('2001:db8::1') -howto/ipaddress,,:db8,>>> host6 = ipaddress.ip_interface('2001:db8::1/96') -howto/ipaddress,,::,>>> host6 = ipaddress.ip_interface('2001:db8::1/96') -howto/ipaddress,,:db8,>>> net6 = ipaddress.ip_network('2001:db8::0/96') -howto/ipaddress,,::,>>> net6 = ipaddress.ip_network('2001:db8::0/96') -howto/ipaddress,,:ffff,IPv6Address('ffff:ffff:ffff:ffff:ffff:ffff::') -howto/ipaddress,,::,IPv6Address('ffff:ffff:ffff:ffff:ffff:ffff::') -howto/ipaddress,,::,IPv6Address('::ffff:ffff') -howto/ipaddress,,:ffff,IPv6Address('::ffff:ffff') -howto/ipaddress,,:db8,'2001:db8::/96' -howto/ipaddress,,::,'2001:db8::/96' -howto/ipaddress,,:db8,>>> ipaddress.ip_interface('2001:db8::1/96') -howto/ipaddress,,::,>>> ipaddress.ip_interface('2001:db8::1/96') -howto/ipaddress,,:db8,'2001:db8::1' -howto/ipaddress,,::,'2001:db8::1' -howto/ipaddress,,:db8,IPv6Address('2001:db8::ffff:ffff') -howto/ipaddress,,::,IPv6Address('2001:db8::ffff:ffff') -howto/ipaddress,,:ffff,IPv6Address('2001:db8::ffff:ffff') -howto/logging,,:And,"WARNING:And this, too" -howto/logging,,:And,"WARNING:root:And this, too" -howto/logging,,:And,"ERROR:root:And non-ASCII stuff, too, like " -howto/logging,,:Doing,INFO:root:Doing something -howto/logging,,:Finished,INFO:root:Finished -howto/logging,,:logger,severity:logger name:message -howto/logging,,:Look,WARNING:root:Look before you leap! -howto/logging,,:message,severity:logger name:message -howto/logging,,:root,DEBUG:root:This message should go to the log file -howto/logging,,:root,INFO:root:Doing something -howto/logging,,:root,INFO:root:Finished -howto/logging,,:root,INFO:root:So should this -howto/logging,,:root,"ERROR:root:And non-ASCII stuff, too, like " -howto/logging,,:root,INFO:root:Started -howto/logging,,:root,"WARNING:root:And this, too" -howto/logging,,:root,WARNING:root:Look before you leap! -howto/logging,,:root,WARNING:root:Watch out! -howto/logging,,:So,INFO:root:So should this -howto/logging,,:So,INFO:So should this -howto/logging,,:Started,INFO:root:Started -howto/logging,,:This,DEBUG:root:This message should go to the log file -howto/logging,,:This,DEBUG:This message should appear on the console -howto/logging,,:Watch,WARNING:root:Watch out! -howto/pyporting,,::,Programming Language :: Python :: 2 -howto/pyporting,,::,Programming Language :: Python :: 3 -howto/regex,,::, -howto/regex,,:foo,(?:foo) -howto/urllib2,,:password,"""joe:password@example.com""" -library/__main__,,`, -library/ast,,:upper,lower:upper -library/ast,,:step,lower:upper:step -library/audioop,,:ipos,"# factor = audioop.findfactor(in_test[ipos*2:ipos*2+len(out_test)]," -library/configparser,,:home,my_dir: ${Common:home_dir}/twosheds -library/configparser,,:option,${section:option} -library/configparser,,:path,python_dir: ${Frameworks:path}/Python/Versions/${Frameworks:Python} -library/configparser,,:Python,python_dir: ${Frameworks:path}/Python/Versions/${Frameworks:Python} -library/configparser,,:system,path: ${Common:system_dir}/Library/Frameworks/ -library/datetime,,:MM, -library/datetime,,:SS, -library/decimal,,:optional,"trailneg:optional trailing minus indicator" -library/difflib,,:ahi,a[alo:ahi] -library/difflib,,:bhi,b[blo:bhi] -library/difflib,,:i1, -library/difflib,,:i2, -library/difflib,,:j2, -library/doctest,,`,``factorial`` from the ``example`` module: -library/doctest,,`,The ``example`` module -library/doctest,,`,Using ``factorial`` -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,,:LEAF,"h00 = blake2b(buf[0:LEAF_SIZE], fanout=FANOUT, depth=DEPTH," -library/http.client,,:port,host:port -library/http.cookies,,`,!#$%&'*+-.^_`|~: -library/imaplib,,:MM,"""DD-Mmm-YYYY HH:MM:SS" -library/imaplib,,:SS,"""DD-Mmm-YYYY HH:MM:SS" -library/inspect,,:int,">>> def foo(a, *, b:int, **kwargs):" -library/inspect,,:int,"'(a, *, b:int, **kwargs)'" -library/inspect,,:int,'b:int' -library/ipaddress,,:db8,>>> ipaddress.ip_address('2001:db8::') -library/ipaddress,,::,>>> ipaddress.ip_address('2001:db8::') -library/ipaddress,,:db8,IPv6Address('2001:db8::') -library/ipaddress,,::,IPv6Address('2001:db8::') -library/ipaddress,,:db8,>>> ipaddress.IPv6Address('2001:db8::1000') -library/ipaddress,,::,>>> ipaddress.IPv6Address('2001:db8::1000') -library/ipaddress,,:db8,'2001:db8::1000' -library/ipaddress,,::,'2001:db8::1000' -library/ipaddress,,:db8,">>> f'{ipaddress.IPv6Address(""2001:db8::1000""):s}'" -library/ipaddress,,::,">>> f'{ipaddress.IPv6Address(""2001:db8::1000""):s}'" -library/ipaddress,,::,IPv6Address('ff02::5678%1') -library/ipaddress,,::,fe80::1234 -library/ipaddress,,:db8,">>> ipaddress.ip_address(""2001:db8::1"").reverse_pointer" -library/ipaddress,,::,">>> ipaddress.ip_address(""2001:db8::1"").reverse_pointer" -library/ipaddress,,::,"""::abc:7:def""" -library/ipaddress,,:def,"""::abc:7:def""" -library/ipaddress,,::,::FFFF/96 -library/ipaddress,,::,2002::/16 -library/ipaddress,,::,2001::/32 -library/ipaddress,,::,>>> str(ipaddress.IPv6Address('::1')) -library/ipaddress,,::,'::1' -library/ipaddress,,:ff00,ffff:ff00:: -library/ipaddress,,:db00,2001:db00::0/24 -library/ipaddress,,::,2001:db00::0/24 -library/ipaddress,,:db00,2001:db00::0/ffff:ff00:: -library/ipaddress,,::,2001:db00::0/ffff:ff00:: -library/itertools,,:step,elements from seq[start:stop:step] -library/itertools,,::,kernel = tuple(kernel)[::-1] -library/itertools,,:stop,elements from seq[start:stop:step] -library/logging.handlers,,:port,host:port -library/logging,,:root,WARNING:root:Watch out! -library/logging,,:Watch,WARNING:root:Watch out! -library/mmap,,:i2,obj[i1:i2] -library/multiprocessing,,`,# Add more tasks using `put()` -library/multiprocessing,,:queue,">>> QueueManager.register('get_queue', callable=lambda:queue)" -library/multiprocessing,,`,# register the Foo class; make `f()` and `g()` accessible via proxy -library/multiprocessing,,`,# register the Foo class; make `g()` and `_h()` accessible via proxy -library/multiprocessing,,`,# register the generator function baz; use `GeneratorProxy` to make proxies -library/nntplib,,:bytes,:bytes -library/nntplib,,:lines,:lines -library/optparse,,:len,"del parser.rargs[:len(value)]" -library/os.path,,:foo,c:foo -library/pathlib,,:bar,">>> PureWindowsPath('c:/Windows', 'd:bar')" -library/pathlib,,:bar,PureWindowsPath('d:bar') -library/pathlib,,:Program,>>> PureWindowsPath('c:Program Files/').root -library/pathlib,,:Program,>>> PureWindowsPath('c:Program Files/').anchor -library/pdb,,:lineno,filename:lineno -library/pickle,,:memory,"conn = sqlite3.connect("":memory:"")" -library/posix,,`,"CFLAGS=""`getconf LFS_CFLAGS`"" OPT=""-g -O2 $CFLAGS""" -library/pprint,,::,"'Programming Language :: Python :: 2.6'," -library/pprint,,::,"'Programming Language :: Python :: 2.7'," -library/pprint,,::,"'classifiers': ['Development Status :: 3 - Alpha'," -library/pprint,,::,"'Intended Audience :: Developers'," -library/pprint,,::,"'License :: OSI Approved :: MIT License'," -library/pprint,,::,"'Programming Language :: Python :: 2'," -library/pprint,,::,"'Programming Language :: Python :: 3'," -library/pprint,,::,"'Programming Language :: Python :: 3.2'," -library/pprint,,::,"'Programming Language :: Python :: 3.3'," -library/pprint,,::,"'Programming Language :: Python :: 3.4'," -library/pprint,,::,"'Topic :: Software Development :: Build Tools']," -library/profile,,:lineno,filename:lineno(function) -library/pyexpat,,:elem1,<py:elem1 /> -library/pyexpat,,:py,"xmlns:py = ""http://www.python.org/ns/"">" -library/random,,:len,new_diff = mean(combined[:len(drug)]) - mean(combined[len(drug):]) -library/readline,,:bind,"python:bind -v" -library/readline,,:bind,"python:bind ^I rl_complete" -library/smtplib,,:port,method must support that as well as a regular host:port -library/socket,,::,'5aef:2b::8' -library/socket,,:can,"return (can_id, can_dlc, data[:can_dlc])" -library/socket,,:len,fds.frombytes(cmsg_data[:len(cmsg_data) - (len(cmsg_data) % fds.itemsize)]) -library/sqlite3,,:year,"cur.execute(""select * from lang where first_appeared=:year"", {""year"": 1972})" -library/sqlite3,,:memory, -library/sqlite3,,:template,"con = sqlite3.connect(""file:template.db?mode=ro"", uri=True)" -library/sqlite3,,:nosuchdb,"con = sqlite3.connect(""file:nosuchdb.db?mode=rw"", uri=True)" -library/sqlite3,,:mem1,"con1 = sqlite3.connect(""file:mem1?mode=memory&cache=shared"", uri=True)" -library/sqlite3,,:mem1,"con2 = sqlite3.connect(""file:mem1?mode=memory&cache=shared"", uri=True)" -library/ssl,,:My,"Organizational Unit Name (eg, section) []:My Group" -library/ssl,,:My,"Organization Name (eg, company) [Internet Widgits Pty Ltd]:My Organization, Inc." -library/ssl,,:myserver,"Common Name (eg, YOUR name) []:myserver.mygroup.myorganization.com" -library/ssl,,:MyState,State or Province Name (full name) [Some-State]:MyState -library/ssl,,:ops,Email Address []:ops@myserver.mygroup.myorganization.com -library/ssl,,:Some,"Locality Name (eg, city) []:Some City" -library/ssl,,:US,Country Name (2 letter code) [AU]:US -library/stdtypes,,:end,s[start:end] -library/stdtypes,,::,>>> hash(v[::-2]) == hash(b'abcefg'[::-2]) -library/stdtypes,,:len,s[len(s):len(s)] -library/stdtypes,,::,>>> y = m[::2] -library/stdtypes,,::,>>> z = y[::-2] -library/string,,`,"!""#$%&'()*+,-./:;<=>?@[\]^_`{|}~" -library/tarfile,,:bz2, -library/tarfile,,:compression,filemode[:compression] -library/tarfile,,:gz, -library/tarfile,,:xz,'a:xz' -library/tarfile,,:xz,'r:xz' -library/tarfile,,:xz,'w:xz' -library/time,,:mm, -library/time,,:ss, -library/tracemalloc,,:limit,"for index, stat in enumerate(top_stats[:limit], 1):" -library/turtle,,::,Example:: -library/unittest,,:foo,"self.assertEqual(cm.output, ['INFO:foo:first message'," -library/unittest,,:first,"self.assertEqual(cm.output, ['INFO:foo:first message'," -library/unittest,,:foo,'ERROR:foo.bar:second message']) -library/unittest,,:second,'ERROR:foo.bar:second message']) -library/urllib.request,,:close,Connection:close -library/urllib.request,,:port,:port -library/urllib.request,,:lang,"xmlns=""http://www.w3.org/1999/xhtml"" xml:lang=""en"" lang=""en"">\n\n<head>\n" -library/urllib.request,,:password,"""joe:password@python.org""" -library/urllib.parse,,:scheme,<URL:scheme://host/path> -library/urllib.parse,,:scheme,URL:scheme://host/path -library/uuid,,:uuid,urn:uuid:12345678-1234-5678-1234-567812345678 -library/venv,,:param,":param nodist: If true, setuptools and pip are not installed into the" -library/venv,,:param,":param progress: If setuptools or pip are installed, the progress of the" -library/venv,,:param,":param nopip: If true, pip is not installed into the created" -library/venv,,:param,:param context: The information for the virtual environment -library/xmlrpc.client,,:nil,ex:nil -library/xmlrpc.client,,:pass,http://user:pass@host:port/path -library/xmlrpc.client,,:pass,user:pass -library/xmlrpc.client,,:port,http://user:pass@host:port/path -license,,`,"``Software''), to deal in the Software without restriction, including" -license,,`,"THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND," -license,,`,* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND -license,,`,THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -license,,`,* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY -license,,`,THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND -license,,:zooko,mailto:zooko@zooko.com -reference/expressions,,:index,x[index:index] -reference/lexical_analysis,,`,$ ? ` -reference/lexical_analysis,,:fileencoding,# vim:fileencoding=<encoding-name> -tutorial/datastructures,,:value,It is also possible to delete a key:value -tutorial/datastructures,,:value,key:value pairs within the braces adds initial key:value pairs -tutorial/stdlib2,,:config,"logging.warning('Warning:config file %s not found', 'server.conf')" -tutorial/stdlib2,,:config,WARNING:root:Warning:config file server.conf not found -tutorial/stdlib2,,:Critical,CRITICAL:root:Critical error -- shutting down -tutorial/stdlib2,,:Error,ERROR:root:Error occurred -tutorial/stdlib2,,:root,CRITICAL:root:Critical error -- shutting down -tutorial/stdlib2,,:root,ERROR:root:Error occurred -tutorial/stdlib2,,:root,WARNING:root:Warning:config file server.conf not found -tutorial/stdlib2,,:start,extra = data[start:start+extra_size] -tutorial/stdlib2,,:start,"fields = struct.unpack('<IIIHH', data[start:start+16])" -tutorial/stdlib2,,:start,filename = data[start:start+filenamesize] -tutorial/stdlib2,,:Warning,WARNING:root:Warning:config file server.conf not found -using/cmdline,,:errorhandler,:errorhandler -using/cmdline,,:message,action:message:category:module:lineno -using/cmdline,,:category,action:message:category:module:lineno -using/cmdline,,:module,action:message:category:module:lineno -using/cmdline,,:lineno,action:message:category:module:lineno -using/cmdline,,::,-W ignore::DeprecationWarning -using/unix,,:Packaging,https://en.opensuse.org/Portal:Packaging -whatsnew/2.0,,:len, -whatsnew/2.3,,::, -whatsnew/2.3,,:config, -whatsnew/2.3,,:Critical, -whatsnew/2.3,,:Error, -whatsnew/2.3,,:Problem, -whatsnew/2.3,,:root, -whatsnew/2.3,,:Warning, -whatsnew/2.4,,::, -whatsnew/2.4,,:System, -whatsnew/2.5,,:memory,:memory: -whatsnew/2.5,,:step,[start:stop:step] -whatsnew/2.5,,:stop,[start:stop:step] -whatsnew/2.7,,::,"ParseResult(scheme='http', netloc='[1080::8:800:200C:417A]'," -whatsnew/2.7,,::,>>> urlparse.urlparse('http://[1080::8:800:200C:417A]/foo') -whatsnew/2.7,,:Sunday,'2009:4:Sunday' -whatsnew/2.7,,:Cookie,"export PYTHONWARNINGS=all,error:::Cookie:0" -whatsnew/2.7,,::,"export PYTHONWARNINGS=all,error:::Cookie:0" -whatsnew/3.2,,:affe,"netloc='[dead:beef:cafe:5417:affe:8FA3:deaf:feed]'," -whatsnew/3.2,,:affe,>>> urllib.parse.urlparse('http://[dead:beef:cafe:5417:affe:8FA3:deaf:feed]/foo/') -whatsnew/3.2,,:beef,"netloc='[dead:beef:cafe:5417:affe:8FA3:deaf:feed]'," -whatsnew/3.2,,:beef,>>> urllib.parse.urlparse('http://[dead:beef:cafe:5417:affe:8FA3:deaf:feed]/foo/') -whatsnew/3.2,,:cafe,"netloc='[dead:beef:cafe:5417:affe:8FA3:deaf:feed]'," -whatsnew/3.2,,:cafe,>>> urllib.parse.urlparse('http://[dead:beef:cafe:5417:affe:8FA3:deaf:feed]/foo/') -whatsnew/3.2,,:deaf,"netloc='[dead:beef:cafe:5417:affe:8FA3:deaf:feed]'," -whatsnew/3.2,,:deaf,>>> urllib.parse.urlparse('http://[dead:beef:cafe:5417:affe:8FA3:deaf:feed]/foo/') -whatsnew/3.2,,:directory,${buildout:directory}/downloads/dist -whatsnew/3.2,,::,"$ export PYTHONWARNINGS='ignore::RuntimeWarning::,once::UnicodeWarning::'" -whatsnew/3.2,,:feed,"netloc='[dead:beef:cafe:5417:affe:8FA3:deaf:feed]'," -whatsnew/3.2,,:feed,>>> urllib.parse.urlparse('http://[dead:beef:cafe:5417:affe:8FA3:deaf:feed]/foo/') -whatsnew/3.2,,:gz,">>> with tarfile.open(name='myarchive.tar.gz', mode='w:gz') as tf:" -whatsnew/3.2,,:location,zope9-location = ${zope9:location} -whatsnew/3.2,,:prefix,zope-conf = ${custom:prefix}/etc/zope.conf -library/re,,`,!#$%&'*+-.^_`|~: -library/re,,`,!\#\$%\&'\*\+\-\.\^_`\|\~: -library/tarfile,,:xz,'x:xz' -library/warnings,,:message,action:message:category:module:line -library/warnings,,:category,action:message:category:module:line -library/warnings,,:module,action:message:category:module:line -library/warnings,,:line,action:message:category:module:line -library/warnings,,::,error::ResourceWarning -library/warnings,,::,default::DeprecationWarning -library/warnings,,::,default:::mymodule -library/warnings,,:mymodule,default:::mymodule -library/warnings,,::,error:::mymodule -library/warnings,,:mymodule,error:::mymodule -library/warnings,,::,ignore::DeprecationWarning -library/warnings,,::,ignore::PendingDeprecationWarning -library/warnings,,::,ignore::ImportWarning -library/warnings,,::,ignore::ResourceWarning -library/xml.etree.elementtree,,:sometag,prefix:sometag -library/xml.etree.elementtree,,:fictional,"<actors xmlns:fictional=""http://characters.example.com""" -library/xml.etree.elementtree,,:character,<fictional:character>Lancelot</fictional:character> -library/xml.etree.elementtree,,:character,<fictional:character>Archie Leach</fictional:character> -library/xml.etree.elementtree,,:character,<fictional:character>Sir Robin</fictional:character> -library/xml.etree.elementtree,,:character,<fictional:character>Gunther</fictional:character> -library/xml.etree.elementtree,,:character,<fictional:character>Commander Clement</fictional:character> -library/xml.etree.elementtree,,:actor,"for actor in root.findall('real_person:actor', ns):" -library/xml.etree.elementtree,,:name,"name = actor.find('real_person:name', ns)" -library/xml.etree.elementtree,,:character,"for char in actor.findall('role:character', ns):" -library/xml.etree.elementtree,,:xi,<document xmlns:xi="http://www.w3.org/2001/XInclude"> -library/xml.etree.elementtree,,:include, <xi:include href="source.xml" parse="xml" /> -library/xml.etree.elementtree,,:include, Copyright (c) <xi:include href="year.txt" parse="text" />. -library/zipapp,,:main,"$ python -m zipapp myapp -m ""myapp:main""" -library/zipapp,,:fn,"pkg.mod:fn" -library/zipapp,,:callable,"pkg.module:callable" -library/stdtypes,,::,>>> m[::2].tolist() -whatsnew/3.5,,:root,'WARNING:root:warning\n' -whatsnew/3.5,,:warning,'WARNING:root:warning\n' -whatsnew/3.5,,::,>>> addr6 = ipaddress.IPv6Address('::1') -whatsnew/3.5,,:root,ERROR:root:exception -whatsnew/3.5,,:exception,ERROR:root:exception -whatsnew/changelog,,`,'`' -whatsnew/changelog,,:end,str[start:end] -library/binascii,,`,'`' -library/uu,,`,'`' -whatsnew/3.7,,`,'`' -whatsnew/3.7,,::,error::BytesWarning -whatsnew/changelog,,::,error::BytesWarning -whatsnew/changelog,,::,default::BytesWarning -whatsnew/changelog,,::,default::DeprecationWarning -library/importlib.metadata,,:main,"EntryPoint(name='wheel', value='wheel.cli:main', group='console_scripts')" -library/importlib.metadata,,`,loading the metadata for packages for the indicated ``context``. -library/re,,`,"`" -library/typing,,`,# Type of ``val`` is narrowed to ``str`` -library/typing,,`,"# Else, type of ``val`` is narrowed to ``float``." -library/typing,,`,# Type of ``val`` is narrowed to ``list[str]``. -library/typing,,`,# Type of ``val`` remains as ``list[object]``. -library/tkinter,,::,ttk::frame .frm -padding 10 -library/tkinter,,::,"grid [ttk::label .frm.lbl -text ""Hello World!""] -column 0 -row 0" -library/tkinter,,::,"grid [ttk::button .frm.btn -text ""Quit"" -command ""destroy .""] -column 1 -row 0" -library/tkinter,,::,ttk::frame -library/tkinter,,::,ttk::button -library/tkinter,,::,ttk::widget -reference/compound_stmts,,:exc,subclass of :exc:`BaseExceptionGroup`. It is not possible to mix except -reference/compound_stmts,,`,subclass of :exc:`BaseExceptionGroup`. It is not possible to mix except -reference/compound_stmts,,:keyword,"and except* in the same :keyword:`try`. :keyword:`break`," -reference/compound_stmts,,`,"and except* in the same :keyword:`try`. :keyword:`break`," -reference/compound_stmts,,:keyword,:keyword:`continue` and :keyword:`return` cannot appear in an except* -reference/compound_stmts,,`,:keyword:`continue` and :keyword:`return` cannot appear in an except* -whatsnew/changelog,,:CON,": os.path.abspath(“C:CON”) is now fixed to return “\.CON”, not" -whatsnew/changelog,,::,Lib/email/mime/nonmultipart.py::MIMENonMultipart -library/typing,,`,"assert_type(name, str) # OK, inferred type of `name` is `str`" -library/typing,,`,# after which we hope the inferred type will be `int` -whatsnew/changelog,,:company,-V:company/tag -library/typing,,`,# are located in the `typing_extensions` backports package. diff --git a/Doc/tools/templates/customsourcelink.html b/Doc/tools/templates/customsourcelink.html index 21af621e..eb9db9e3 100644 --- a/Doc/tools/templates/customsourcelink.html +++ b/Doc/tools/templates/customsourcelink.html @@ -4,7 +4,7 @@ <ul class="this-page-menu"> <li><a href="{{ pathto('bugs') }}">{% trans %}Report a Bug{% endtrans %}</a></li> <li> - <a href="https://github.com/python/cpython/blob/{{ version }}/Doc/{{ sourcename|replace('.rst.txt', '.rst') }}" + <a href="https://github.com/python/cpython/blob/main/Doc/{{ sourcename|replace('.rst.txt', '.rst') }}" rel="nofollow">{{ _('Show Source') }} </a> </li> diff --git a/Doc/tools/templates/dummy.html b/Doc/tools/templates/dummy.html index 3438b443..bab4aaeb 100644 --- a/Doc/tools/templates/dummy.html +++ b/Doc/tools/templates/dummy.html @@ -7,6 +7,11 @@ In extensions/pyspecific.py: {% trans %}Deprecated since version {deprecated}, will be removed in version {removed}{% endtrans %} {% trans %}Deprecated since version {deprecated}, removed in version {removed}{% endtrans %} +In extensions/c_annotations.py: + +{% trans %}Return value: Always NULL.{% endtrans %} +{% trans %}Return value: New reference.{% endtrans %} +{% trans %}Return value: Borrowed reference.{% endtrans %} In docsbuild-scripts, when rewriting indexsidebar.html with actual versions: diff --git a/Doc/tools/templates/indexcontent.html b/Doc/tools/templates/indexcontent.html index a96746b6..1e3ab7cf 100644 --- a/Doc/tools/templates/indexcontent.html +++ b/Doc/tools/templates/indexcontent.html @@ -62,6 +62,7 @@ </td><td width="50%"> <p class="biglink"><a class="biglink" href="{{ pathto("license") }}">{% trans %}History and License of Python{% endtrans %}</a></p> <p class="biglink"><a class="biglink" href="{{ pathto("copyright") }}">{% trans %}Copyright{% endtrans %}</a></p> + <p class="biglink"><a class="biglink" href="{{ pathto("download") }}">{% trans %}Download the documentation{% endtrans %}</a></p> </td></tr> </table> {% endblock %} diff --git a/Doc/tools/templates/layout.html b/Doc/tools/templates/layout.html index 98ccf422..9498b2cc 100644 --- a/Doc/tools/templates/layout.html +++ b/Doc/tools/templates/layout.html @@ -4,8 +4,16 @@ {%- if outdated %} <div id="outdated-warning" style="padding: .5em; text-align: center; background-color: #FFBABA; color: #6A0E0E;"> {% trans %}This document is for an old version of Python that is no longer supported. - You should upgrade, and read the {% endtrans %} - <a href="/3/{{ pagename }}{{ file_suffix }}">{% trans %} Python documentation for the current stable release{% endtrans %}</a>. + You should upgrade, and read the{% endtrans %} + <a href="/3/{{ pagename }}{{ file_suffix }}">{% trans %}Python documentation for the current stable release{% endtrans %}</a>. +</div> +{%- endif %} + +{%- if is_deployment_preview %} +<div id="deployment-preview-warning" style="padding: .5em; text-align: center; background-color: #fff2ba; color: #6a580e;"> + {% trans %}This is a deploy preview created from a <a href="{{ repository_url }}/pull/{{ pr_id }}">pull request</a>. + For authoritative documentation, see{% endtrans %} + <a href="https://docs.python.org/3/{{ pagename }}{{ file_suffix }}">{% trans %}the current stable release{% endtrans %}</a>. </div> {%- endif %} {% endblock %} diff --git a/Doc/tools/templates/search.html b/Doc/tools/templates/search.html index f2ac2ea0..85297446 100644 --- a/Doc/tools/templates/search.html +++ b/Doc/tools/templates/search.html @@ -1,48 +1,62 @@ {% extends "!search.html" %} {% block extrahead %} {{ super() }} + <meta name="robots" content="noindex"> <script type="text/javascript"> - var GLOSSARY_PAGE = 'glossary.html'; + const GLOSSARY_PAGE = 'glossary.html'; - jQuery(function() { - $.getJSON("_static/glossary.json", function(glossary) { - var RESULT_TEMPLATE = '<div style="display: none" class="admonition seealso" id="glossary-result">' + + document.addEventListener('DOMContentLoaded', function() { + fetch('_static/glossary.json') + .then(function(response) { + if (response.ok) { + return response.json(); + } else { + throw new Error('Failed to fetch glossary.json'); + } + }) + .then(function(glossary) { + const RESULT_TEMPLATE = '<div style="display: none" class="admonition seealso" id="glossary-result">' + ' <p class="topic-title">' + ' <a class="glossary-title" href="#"></a>' + ' </p>' + ' <div class="glossary-body"></div>' + '</div>'; - $("#search-results").prepend(RESULT_TEMPLATE); + let searchResults = document.getElementById('search-results'); + searchResults.insertAdjacentHTML('afterbegin', RESULT_TEMPLATE); - var params = $.getQueryParameters(); - if (params.q) { - var search_param = params.q[0].toLowerCase(); - var glossary_item = glossary[search_param]; - if (glossary_item) { - var resultDiv = $("#glossary-result"); + const params = new URLSearchParams(document.location.search).get("q"); + if (params) { + const searchParam = params.toLowerCase(); + const glossaryItem = glossary[searchParam]; + if (glossaryItem) { + let resultDiv = document.getElementById('glossary-result'); - // set up the title text with a link to the glossary page - resultDiv.find(".glossary-title").text('Glossary: ' + glossary_item.title); - var link_target = search_param.replace(/ /g, '-'); - resultDiv.find(".glossary-title").attr( - 'href', GLOSSARY_PAGE + '#term-' + link_target - ); + // set up the title text with a link to the glossary page + let glossaryTitle = resultDiv.querySelector('.glossary-title'); + glossaryTitle.textContent = 'Glossary: ' + glossaryItem.title; + const linkTarget = searchParam.replace(/ /g, '-'); + glossaryTitle.href = GLOSSARY_PAGE + '#term-' + linkTarget; - // rewrite any anchor links (to other glossary terms) - // to have a full reference to the glossary page - var body = $(glossary_item.body).children(); - body.find("a[href^='#']").each(function() { - var current_url = $(this).attr('href'); - $(this).attr('href', GLOSSARY_PAGE + current_url); - }); - resultDiv.find(".glossary-body").html(body); + // rewrite any anchor links (to other glossary terms) + // to have a full reference to the glossary page + let body = document.createElement('div'); + body.innerHTML = glossaryItem.body; + const anchorLinks = body.querySelectorAll('a[href^="#"]'); + anchorLinks.forEach(function(link) { + const currentUrl = link.getAttribute('href'); + link.href = GLOSSARY_PAGE + currentUrl; + }); + resultDiv.querySelector('.glossary-body').appendChild(body); - resultDiv.show(); - } else { - $("#glossary-result").hide(''); - } + resultDiv.style.display = ''; + } else { + document.getElementById('glossary-result').style.display = 'none'; } + } + }) + .catch(function(error) { + console.error(error); }); }); </script> -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/Doc/tutorial/appendix.rst b/Doc/tutorial/appendix.rst index 241a8120..588591fc 100644 --- a/Doc/tutorial/appendix.rst +++ b/Doc/tutorial/appendix.rst @@ -101,8 +101,8 @@ in the script:: The Customization Modules ------------------------- -Python provides two hooks to let you customize it: :mod:`sitecustomize` and -:mod:`usercustomize`. To see how it works, you need first to find the location +Python provides two hooks to let you customize it: :index:`sitecustomize` and +:index:`usercustomize`. To see how it works, you need first to find the location of your user site-packages directory. Start Python and run this code:: >>> import site @@ -113,9 +113,9 @@ Now you can create a file named :file:`usercustomize.py` in that directory and put anything you want in it. It will affect every invocation of Python, unless it is started with the :option:`-s` option to disable the automatic import. -:mod:`sitecustomize` works in the same way, but is typically created by an +:index:`sitecustomize` works in the same way, but is typically created by an administrator of the computer in the global site-packages directory, and is -imported before :mod:`usercustomize`. See the documentation of the :mod:`site` +imported before :index:`usercustomize`. See the documentation of the :mod:`site` module for more details. diff --git a/Doc/tutorial/classes.rst b/Doc/tutorial/classes.rst index 30450c70..7b92e1a5 100644 --- a/Doc/tutorial/classes.rst +++ b/Doc/tutorial/classes.rst @@ -91,7 +91,7 @@ Attributes may be read-only or writable. In the latter case, assignment to attributes is possible. Module attributes are writable: you can write ``modname.the_answer = 42``. Writable attributes may also be deleted with the :keyword:`del` statement. For example, ``del modname.the_answer`` will remove -the attribute :attr:`the_answer` from the object named by ``modname``. +the attribute :attr:`!the_answer` from the object named by ``modname``. Namespaces are created at different moments and have different lifetimes. The namespace containing the built-in names is created when the Python interpreter @@ -249,7 +249,7 @@ created. This is basically a wrapper around the contents of the namespace created by the class definition; we'll learn more about class objects in the next section. The original local scope (the one in effect just before the class definition was entered) is reinstated, and the class object is bound here to the -class name given in the class definition header (:class:`ClassName` in the +class name given in the class definition header (:class:`!ClassName` in the example). @@ -276,7 +276,7 @@ definition looked like this:: then ``MyClass.i`` and ``MyClass.f`` are valid attribute references, returning an integer and a function object, respectively. Class attributes can also be assigned to, so you can change the value of ``MyClass.i`` by assignment. -:attr:`__doc__` is also a valid attribute, returning the docstring belonging to +:attr:`!__doc__` is also a valid attribute, returning the docstring belonging to the class: ``"A simple example class"``. Class *instantiation* uses function notation. Just pretend that the class @@ -291,20 +291,20 @@ variable ``x``. The instantiation operation ("calling" a class object) creates an empty object. Many classes like to create objects with instances customized to a specific initial state. Therefore a class may define a special method named -:meth:`__init__`, like this:: +:meth:`~object.__init__`, like this:: def __init__(self): self.data = [] -When a class defines an :meth:`__init__` method, class instantiation -automatically invokes :meth:`__init__` for the newly created class instance. So +When a class defines an :meth:`~object.__init__` method, class instantiation +automatically invokes :meth:`!__init__` for the newly created class instance. So in this example, a new, initialized instance can be obtained by:: x = MyClass() -Of course, the :meth:`__init__` method may have arguments for greater +Of course, the :meth:`~object.__init__` method may have arguments for greater flexibility. In that case, arguments given to the class instantiation operator -are passed on to :meth:`__init__`. For example, :: +are passed on to :meth:`!__init__`. For example, :: >>> class Complex: ... def __init__(self, realpart, imagpart): @@ -328,7 +328,7 @@ attribute names: data attributes and methods. *data attributes* correspond to "instance variables" in Smalltalk, and to "data members" in C++. Data attributes need not be declared; like local variables, they spring into existence when they are first assigned to. For example, if -``x`` is the instance of :class:`MyClass` created above, the following piece of +``x`` is the instance of :class:`!MyClass` created above, the following piece of code will print the value ``16``, without leaving a trace:: x.counter = 1 @@ -344,7 +344,7 @@ list objects have methods called append, insert, remove, sort, and so on. However, in the following discussion, we'll use the term method exclusively to mean methods of class instance objects, unless explicitly stated otherwise.) -.. index:: object: method +.. index:: pair: object; method Valid method names of an instance object depend on its class. By definition, all attributes of a class that are function objects define corresponding @@ -363,7 +363,7 @@ Usually, a method is called right after it is bound:: x.f() -In the :class:`MyClass` example, this will return the string ``'hello world'``. +In the :class:`!MyClass` example, this will return the string ``'hello world'``. However, it is not necessary to call a method right away: ``x.f`` is a method object, and can be stored away and called at a later time. For example:: @@ -375,7 +375,7 @@ will continue to print ``hello world`` until the end of time. What exactly happens when a method is called? You may have noticed that ``x.f()`` was called without an argument above, even though the function -definition for :meth:`f` specified an argument. What happened to the argument? +definition for :meth:`!f` specified an argument. What happened to the argument? Surely Python raises an exception when a function that requires an argument is called without any --- even if the argument isn't actually used... @@ -532,9 +532,9 @@ variable in the class is also ok. For example:: h = g -Now ``f``, ``g`` and ``h`` are all attributes of class :class:`C` that refer to +Now ``f``, ``g`` and ``h`` are all attributes of class :class:`!C` that refer to function objects, and consequently they are all methods of instances of -:class:`C` --- ``h`` being exactly equivalent to ``g``. Note that this practice +:class:`!C` --- ``h`` being exactly equivalent to ``g``. Note that this practice usually only serves to confuse the reader of a program. Methods may call other methods by using method attributes of the ``self`` @@ -581,7 +581,8 @@ this:: . <statement-N> -The name :class:`BaseClassName` must be defined in a scope containing the +The name :class:`!BaseClassName` must be defined in a +namespace accessible from the scope containing the derived class definition. In place of a base class name, other arbitrary expressions are also allowed. This can be useful, for example, when the base class is defined in another module:: @@ -644,9 +645,9 @@ multiple base classes looks like this:: For most purposes, in the simplest cases, you can think of the search for attributes inherited from a parent class as depth-first, left-to-right, not searching twice in the same class where there is an overlap in the hierarchy. -Thus, if an attribute is not found in :class:`DerivedClassName`, it is searched -for in :class:`Base1`, then (recursively) in the base classes of :class:`Base1`, -and if it was not found there, it was searched for in :class:`Base2`, and so on. +Thus, if an attribute is not found in :class:`!DerivedClassName`, it is searched +for in :class:`!Base1`, then (recursively) in the base classes of :class:`!Base1`, +and if it was not found there, it was searched for in :class:`!Base2`, and so on. In fact, it is slightly more complex than that; the method resolution order changes dynamically to support cooperative calls to :func:`super`. This @@ -759,7 +760,8 @@ is to use :mod:`dataclasses` for this purpose:: A piece of Python code that expects a particular abstract data type can often be passed a class that emulates the methods of that data type instead. For instance, if you have a function that formats some data from a file object, you -can define a class with methods :meth:`read` and :meth:`!readline` that get the +can define a class with methods :meth:`~io.TextIOBase.read` and +:meth:`~io.TextIOBase.readline` that get the data from a string buffer instead, and pass it as an argument. .. (Unfortunately, this technique has its limitations: a class can't define @@ -768,7 +770,7 @@ data from a string buffer instead, and pass it as an argument. not cause the interpreter to read further input from it.) Instance method objects have attributes, too: ``m.__self__`` is the instance -object with the method :meth:`m`, and ``m.__func__`` is the function object +object with the method :meth:`!m`, and ``m.__func__`` is the function object corresponding to the method. @@ -817,9 +819,9 @@ using the :func:`next` built-in function; this example shows how it all works:: StopIteration Having seen the mechanics behind the iterator protocol, it is easy to add -iterator behavior to your classes. Define an :meth:`__iter__` method which +iterator behavior to your classes. Define an :meth:`~container.__iter__` method which returns an object with a :meth:`~iterator.__next__` method. If the class -defines :meth:`__next__`, then :meth:`__iter__` can just return ``self``:: +defines :meth:`!__next__`, then :meth:`!__iter__` can just return ``self``:: class Reverse: """Iterator for looping over a sequence backwards.""" @@ -878,7 +880,7 @@ easy to create:: Anything that can be done with generators can also be done with class-based iterators as described in the previous section. What makes generators so -compact is that the :meth:`__iter__` and :meth:`~generator.__next__` methods +compact is that the :meth:`~iterator.__iter__` and :meth:`~generator.__next__` methods are created automatically. Another key feature is that the local variables and execution state are diff --git a/Doc/tutorial/controlflow.rst b/Doc/tutorial/controlflow.rst index 52db51e8..aa9caa10 100644 --- a/Doc/tutorial/controlflow.rst +++ b/Doc/tutorial/controlflow.rst @@ -4,8 +4,8 @@ More Control Flow Tools *********************** -Besides the :keyword:`while` statement just introduced, Python uses the usual -flow control statements known from other languages, with some twists. +As well as the :keyword:`while` statement just introduced, Python uses a few more +that we will encounter in this chapter. .. _tut-if: @@ -46,7 +46,7 @@ details see :ref:`tut-match`. ========================== .. index:: - statement: for + pair: statement; for The :keyword:`for` statement in Python differs a bit from what you may be used to in C or Pascal. Rather than always iterating over an arithmetic progression @@ -163,14 +163,21 @@ arguments. In chapter :ref:`tut-structures`, we will discuss in more detail abo :keyword:`!break` and :keyword:`!continue` Statements, and :keyword:`!else` Clauses on Loops ============================================================================================ -The :keyword:`break` statement, like in C, breaks out of the innermost enclosing +The :keyword:`break` statement breaks out of the innermost enclosing :keyword:`for` or :keyword:`while` loop. -Loop statements may have an :keyword:`!else` clause; it is executed when the loop -terminates through exhaustion of the iterable (with :keyword:`for`) or when the -condition becomes false (with :keyword:`while`), but not when the loop is -terminated by a :keyword:`break` statement. This is exemplified by the -following loop, which searches for prime numbers:: +A :keyword:`!for` or :keyword:`!while` loop can include an :keyword:`!else` clause. + +In a :keyword:`for` loop, the :keyword:`!else` clause is executed +after the loop reaches its final iteration. + +In a :keyword:`while` loop, it's executed after the loop's condition becomes false. + +In either kind of loop, the :keyword:`!else` clause is **not** executed +if the loop was terminated by a :keyword:`break`. + +This is exemplified in the following :keyword:`!for` loop, +which searches for prime numbers:: >>> for n in range(2, 10): ... for x in range(2, n): @@ -307,8 +314,9 @@ you can use the class name followed by an argument list resembling a constructor, but with the ability to capture attributes into variables:: class Point: - x: int - y: int + def __init__(self, x, y): + self.x = x + self.y = y def where_is(point): match point: @@ -342,7 +350,13 @@ Dotted names (like ``foo.bar``), attribute names (the ``x=`` and ``y=`` above) o (recognized by the "(...)" next to them like ``Point`` above) are never assigned to. Patterns can be arbitrarily nested. For example, if we have a short -list of points, we could match it like this:: +list of Points, with ``__match_args__`` added, we could match it like this:: + + class Point: + __match_args__ = ('x', 'y') + def __init__(self, x, y): + self.x = x + self.y = y match points: case []: @@ -520,7 +534,7 @@ This example, as usual, demonstrates some new Python features: Different types define different methods. Methods of different types may have the same name without causing ambiguity. (It is possible to define your own object types and methods, using *classes*, see :ref:`tut-classes`) - The method :meth:`append` shown in the example is defined for list objects; it + The method :meth:`!append` shown in the example is defined for list objects; it adds a new element at the end of the list. In this example it is equivalent to ``result = result + [a]``, but more efficient. @@ -1032,7 +1046,7 @@ Function Annotations information about the types used by user-defined functions (see :pep:`3107` and :pep:`484` for more information). -:term:`Annotations <function annotation>` are stored in the :attr:`__annotations__` +:term:`Annotations <function annotation>` are stored in the :attr:`!__annotations__` attribute of the function as a dictionary and have no effect on any other part of the function. Parameter annotations are defined by a colon after the parameter name, followed by an expression evaluating to the value of the annotation. Return annotations are diff --git a/Doc/tutorial/datastructures.rst b/Doc/tutorial/datastructures.rst index c8e89d9b..87614d08 100644 --- a/Doc/tutorial/datastructures.rst +++ b/Doc/tutorial/datastructures.rst @@ -143,8 +143,8 @@ Using Lists as Stacks The list methods make it very easy to use a list as a stack, where the last element added is the first element retrieved ("last-in, first-out"). To add an -item to the top of the stack, use :meth:`append`. To retrieve an item from the -top of the stack, use :meth:`pop` without an explicit index. For example:: +item to the top of the stack, use :meth:`~list.append`. To retrieve an item from the +top of the stack, use :meth:`~list.pop` without an explicit index. For example:: >>> stack = [3, 4, 5] >>> stack.append(6) @@ -341,7 +341,7 @@ The :keyword:`!del` statement ============================= There is a way to remove an item from a list given its index instead of its -value: the :keyword:`del` statement. This differs from the :meth:`pop` method +value: the :keyword:`del` statement. This differs from the :meth:`~list.pop` method which returns a value. The :keyword:`!del` statement can also be used to remove slices from a list or clear the entire list (which we did earlier by assignment of an empty list to the slice). For example:: @@ -501,8 +501,8 @@ any immutable type; strings and numbers can always be keys. Tuples can be used as keys if they contain only strings, numbers, or tuples; if a tuple contains any mutable object either directly or indirectly, it cannot be used as a key. You can't use lists as keys, since lists can be modified in place using index -assignments, slice assignments, or methods like :meth:`append` and -:meth:`extend`. +assignments, slice assignments, or methods like :meth:`~list.append` and +:meth:`~list.extend`. It is best to think of a dictionary as a set of *key: value* pairs, with the requirement that the keys are unique (within one dictionary). A pair of @@ -567,7 +567,7 @@ Looping Techniques ================== When looping through dictionaries, the key and corresponding value can be -retrieved at the same time using the :meth:`items` method. :: +retrieved at the same time using the :meth:`~dict.items` method. :: >>> knights = {'gallahad': 'the pure', 'robin': 'the brave'} >>> for k, v in knights.items(): diff --git a/Doc/tutorial/errors.rst b/Doc/tutorial/errors.rst index e09c829b..1ec59767 100644 --- a/Doc/tutorial/errors.rst +++ b/Doc/tutorial/errors.rst @@ -154,13 +154,13 @@ exception type. The *except clause* may specify a variable after the exception name. The variable is bound to the exception instance which typically has an ``args`` attribute that stores the arguments. For convenience, builtin exception -types define :meth:`__str__` to print all the arguments without explicitly +types define :meth:`~object.__str__` to print all the arguments without explicitly accessing ``.args``. :: >>> try: ... raise Exception('spam', 'eggs') ... except Exception as inst: - ... print(type(inst)) # the exception instance + ... print(type(inst)) # the exception type ... print(inst.args) # arguments stored in .args ... print(inst) # __str__ allows args to be printed directly, ... # but may be overridden in exception subclasses @@ -174,7 +174,7 @@ accessing ``.args``. :: x = spam y = eggs -The exception's :meth:`__str__` output is printed as the last part ('detail') +The exception's :meth:`~object.__str__` output is printed as the last part ('detail') of the message for unhandled exceptions. :exc:`BaseException` is the common base class of all exceptions. One of its @@ -535,11 +535,20 @@ of a certain type while letting all other exceptions propagate to other clauses and eventually to be reraised. :: >>> def f(): - ... raise ExceptionGroup("group1", - ... [OSError(1), - ... SystemError(2), - ... ExceptionGroup("group2", - ... [OSError(3), RecursionError(4)])]) + ... raise ExceptionGroup( + ... "group1", + ... [ + ... OSError(1), + ... SystemError(2), + ... ExceptionGroup( + ... "group2", + ... [ + ... OSError(3), + ... RecursionError(4) + ... ] + ... ) + ... ] + ... ) ... >>> try: ... f() @@ -578,6 +587,8 @@ the following pattern:: ... +.. _tut-exception-notes: + Enriching Exceptions with Notes =============================== diff --git a/Doc/tutorial/floatingpoint.rst b/Doc/tutorial/floatingpoint.rst index e1cd7f9e..b88055a4 100644 --- a/Doc/tutorial/floatingpoint.rst +++ b/Doc/tutorial/floatingpoint.rst @@ -1,6 +1,7 @@ .. testsetup:: import math + from fractions import Fraction .. _tut-fp-issues: @@ -9,12 +10,13 @@ Floating Point Arithmetic: Issues and Limitations ************************************************** .. sectionauthor:: Tim Peters <tim_one@users.sourceforge.net> +.. sectionauthor:: Raymond Hettinger <python at rcn dot com> Floating-point numbers are represented in computer hardware as base 2 (binary) -fractions. For example, the **decimal** fraction ``0.125`` -has value 1/10 + 2/100 + 5/1000, and in the same way the **binary** fraction ``0.001`` -has value 0/2 + 0/4 + 1/8. These two fractions have identical values, the only +fractions. For example, the **decimal** fraction ``0.625`` +has value 6/10 + 2/100 + 5/1000, and in the same way the **binary** fraction ``0.101`` +has value 1/2 + 0/4 + 1/8. These two fractions have identical values, the only real difference being that the first is written in base 10 fractional notation, and the second in base 2. @@ -57,13 +59,15 @@ Many users are not aware of the approximation because of the way values are displayed. Python only prints a decimal approximation to the true decimal value of the binary approximation stored by the machine. On most machines, if Python were to print the true decimal value of the binary approximation stored -for 0.1, it would have to display :: +for 0.1, it would have to display:: >>> 0.1 0.1000000000000000055511151231257827021181583404541015625 That is more digits than most people find useful, so Python keeps the number -of digits manageable by displaying a rounded value instead :: +of digits manageable by displaying a rounded value instead: + +.. doctest:: >>> 1 / 10 0.1 @@ -90,7 +94,10 @@ thing in all languages that support your hardware's floating-point arithmetic (although some languages may not *display* the difference by default, or in all output modes). -For more pleasant output, you may wish to use string formatting to produce a limited number of significant digits:: +For more pleasant output, you may wish to use string formatting to produce a +limited number of significant digits: + +.. doctest:: >>> format(math.pi, '.12g') # give 12 significant digits '3.14159265359' @@ -101,33 +108,49 @@ For more pleasant output, you may wish to use string formatting to produce a lim >>> repr(math.pi) '3.141592653589793' - It's important to realize that this is, in a real sense, an illusion: you're simply rounding the *display* of the true machine value. One illusion may beget another. For example, since 0.1 is not exactly 1/10, -summing three values of 0.1 may not yield exactly 0.3, either:: +summing three values of 0.1 may not yield exactly 0.3, either: + +.. doctest:: - >>> .1 + .1 + .1 == .3 + >>> 0.1 + 0.1 + 0.1 == 0.3 False Also, since the 0.1 cannot get any closer to the exact value of 1/10 and 0.3 cannot get any closer to the exact value of 3/10, then pre-rounding with -:func:`round` function cannot help:: +:func:`round` function cannot help: - >>> round(.1, 1) + round(.1, 1) + round(.1, 1) == round(.3, 1) +.. doctest:: + + >>> round(0.1, 1) + round(0.1, 1) + round(0.1, 1) == round(0.3, 1) False Though the numbers cannot be made closer to their intended exact values, -the :func:`round` function can be useful for post-rounding so that results -with inexact values become comparable to one another:: +the :func:`math.isclose` function can be useful for comparing inexact values: - >>> round(.1 + .1 + .1, 10) == round(.3, 10) - True +.. doctest:: + + >>> math.isclose(0.1 + 0.1 + 0.1, 0.3) + True + +Alternatively, the :func:`round` function can be used to compare rough +approximations:: + +.. doctest:: + + >>> round(math.pi, ndigits=2) == round(22 / 7, ndigits=2) + True Binary floating-point arithmetic holds many surprises like this. The problem with "0.1" is explained in precise detail below, in the "Representation Error" -section. See `The Perils of Floating Point <https://www.lahey.com/float.htm>`_ +section. See `Examples of Floating Point Problems +<https://jvns.ca/blog/2023/01/13/examples-of-floating-point-problems/>`_ for +a pleasant summary of how binary floating-point works and the kinds of +problems commonly encountered in practice. Also see +`The Perils of Floating Point <https://www.lahey.com/float.htm>`_ for a more complete account of other common surprises. As that says near the end, "there are no easy answers." Still, don't be unduly @@ -151,33 +174,41 @@ Another form of exact arithmetic is supported by the :mod:`fractions` module which implements arithmetic based on rational numbers (so the numbers like 1/3 can be represented exactly). -If you are a heavy user of floating point operations you should take a look +If you are a heavy user of floating-point operations you should take a look at the NumPy package and many other packages for mathematical and statistical operations supplied by the SciPy project. See <https://scipy.org>. Python provides tools that may help on those rare occasions when you really *do* want to know the exact value of a float. The :meth:`float.as_integer_ratio` method expresses the value of a float as a -fraction:: +fraction: + +.. doctest:: >>> x = 3.14159 >>> x.as_integer_ratio() (3537115888337719, 1125899906842624) Since the ratio is exact, it can be used to losslessly recreate the -original value:: +original value: + +.. doctest:: >>> x == 3537115888337719 / 1125899906842624 True The :meth:`float.hex` method expresses a float in hexadecimal (base -16), again giving the exact value stored by your computer:: +16), again giving the exact value stored by your computer: + +.. doctest:: >>> x.hex() '0x1.921f9f01b866ep+1' This precise hexadecimal representation can be used to reconstruct -the float value exactly:: +the float value exactly: + +.. doctest:: >>> x == float.fromhex('0x1.921f9f01b866ep+1') True @@ -186,17 +217,43 @@ Since the representation is exact, it is useful for reliably porting values across different versions of Python (platform independence) and exchanging data with other languages that support the same format (such as Java and C99). -Another helpful tool is the :func:`math.fsum` function which helps mitigate -loss-of-precision during summation. It tracks "lost digits" as values are -added onto a running total. That can make a difference in overall accuracy -so that the errors do not accumulate to the point where they affect the -final total: +Another helpful tool is the :func:`sum` function which helps mitigate +loss-of-precision during summation. It uses extended precision for +intermediate rounding steps as values are added onto a running total. +That can make a difference in overall accuracy so that the errors do not +accumulate to the point where they affect the final total: - >>> sum([0.1] * 10) == 1.0 +.. doctest:: + + >>> 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 == 1.0 False - >>> math.fsum([0.1] * 10) == 1.0 + >>> sum([0.1] * 10) == 1.0 True +The :func:`math.fsum()` goes further and tracks all of the "lost digits" +as values are added onto a running total so that the result has only a +single rounding. This is slower than :func:`sum` but will be more +accurate in uncommon cases where large magnitude inputs mostly cancel +each other out leaving a final sum near zero: + +.. doctest:: + + >>> arr = [-0.10430216751806065, -266310978.67179024, 143401161448607.16, + ... -143401161400469.7, 266262841.31058735, -0.003244936839808227] + >>> float(sum(map(Fraction, arr))) # Exact summation with single rounding + 8.042173697819788e-13 + >>> math.fsum(arr) # Single rounding + 8.042173697819788e-13 + >>> sum(arr) # Multiple roundings in extended precision + 8.042178034628478e-13 + >>> total = 0.0 + >>> for x in arr: + ... total += x # Multiple roundings in standard precision + ... + >>> total # Straight addition has no correct digits! + -0.0051575902860057365 + + .. _tut-fp-error: Representation Error @@ -211,12 +268,14 @@ decimal fractions cannot be represented exactly as binary (base 2) fractions. This is the chief reason why Python (or Perl, C, C++, Java, Fortran, and many others) often won't display the exact decimal number you expect. -Why is that? 1/10 is not exactly representable as a binary fraction. Almost all -machines today (November 2000) use IEEE-754 floating point arithmetic, and -almost all platforms map Python floats to IEEE-754 "double precision". 754 -doubles contain 53 bits of precision, so on input the computer strives to -convert 0.1 to the closest fraction it can of the form *J*/2**\ *N* where *J* is -an integer containing exactly 53 bits. Rewriting :: +Why is that? 1/10 is not exactly representable as a binary fraction. Since at +least 2000, almost all machines use IEEE 754 binary floating-point arithmetic, +and almost all platforms map Python floats to IEEE 754 binary64 "double +precision" values. IEEE 754 binary64 values contain 53 bits of precision, so +on input the computer strives to convert 0.1 to the closest fraction it can of +the form *J*/2**\ *N* where *J* is an integer containing exactly 53 bits. +Rewriting +:: 1 / 10 ~= J / (2**N) @@ -225,25 +284,34 @@ as :: J ~= 2**N / 10 and recalling that *J* has exactly 53 bits (is ``>= 2**52`` but ``< 2**53``), -the best value for *N* is 56:: +the best value for *N* is 56: + +.. doctest:: >>> 2**52 <= 2**56 // 10 < 2**53 True That is, 56 is the only value for *N* that leaves *J* with exactly 53 bits. The -best possible value for *J* is then that quotient rounded:: +best possible value for *J* is then that quotient rounded: + +.. doctest:: >>> q, r = divmod(2**56, 10) >>> r 6 Since the remainder is more than half of 10, the best approximation is obtained -by rounding up:: +by rounding up: + +.. doctest:: + + >>> q+1 7205759403792794 -Therefore the best possible approximation to 1/10 in 754 double precision is:: +Therefore the best possible approximation to 1/10 in IEEE 754 double precision +is:: 7205759403792794 / 2 ** 56 @@ -256,13 +324,17 @@ if we had not rounded up, the quotient would have been a little bit smaller than 1/10. But in no case can it be *exactly* 1/10! So the computer never "sees" 1/10: what it sees is the exact fraction given -above, the best 754 double approximation it can get:: +above, the best IEEE 754 double approximation it can get: + +.. doctest:: >>> 0.1 * 2 ** 55 3602879701896397.0 If we multiply that fraction by 10\*\*55, we can see the value out to -55 decimal digits:: +55 decimal digits: + +.. doctest:: >>> 3602879701896397 * 10 ** 55 // 2 ** 55 1000000000000000055511151231257827021181583404541015625 @@ -270,13 +342,17 @@ If we multiply that fraction by 10\*\*55, we can see the value out to meaning that the exact number stored in the computer is equal to the decimal value 0.1000000000000000055511151231257827021181583404541015625. Instead of displaying the full decimal value, many languages (including -older versions of Python), round the result to 17 significant digits:: +older versions of Python), round the result to 17 significant digits: + +.. doctest:: >>> format(0.1, '.17f') '0.10000000000000001' The :mod:`fractions` and :mod:`decimal` modules make these calculations -easy:: +easy: + +.. doctest:: >>> from decimal import Decimal >>> from fractions import Fraction diff --git a/Doc/tutorial/inputoutput.rst b/Doc/tutorial/inputoutput.rst index 3581b372..fe9ca9cc 100644 --- a/Doc/tutorial/inputoutput.rst +++ b/Doc/tutorial/inputoutput.rst @@ -15,7 +15,7 @@ Fancier Output Formatting ========================= So far we've encountered two ways of writing values: *expression statements* and -the :func:`print` function. (A third way is using the :meth:`write` method +the :func:`print` function. (A third way is using the :meth:`~io.TextIOBase.write` method of file objects; the standard output file can be referenced as ``sys.stdout``. See the Library Reference for more information on this.) @@ -285,8 +285,8 @@ Reading and Writing Files ========================= .. index:: - builtin: open - object: file + pair: built-in function; open + pair: object; file :func:`open` returns a :term:`file object`, and is most commonly used with two positional arguments and one keyword argument: @@ -456,8 +456,8 @@ to the very file end with ``seek(0, 2)``) and the only valid *offset* values are those returned from the ``f.tell()``, or zero. Any other *offset* value produces undefined behaviour. -File objects have some additional methods, such as :meth:`~file.isatty` and -:meth:`~file.truncate` which are less frequently used; consult the Library +File objects have some additional methods, such as :meth:`~io.IOBase.isatty` and +:meth:`~io.IOBase.truncate` which are less frequently used; consult the Library Reference for a complete guide to file objects. @@ -466,10 +466,10 @@ Reference for a complete guide to file objects. Saving structured data with :mod:`json` --------------------------------------- -.. index:: module: json +.. index:: pair: module; json Strings can easily be written to and read from a file. Numbers take a bit more -effort, since the :meth:`read` method only returns strings, which will have to +effort, since the :meth:`~io.TextIOBase.read` method only returns strings, which will have to be passed to a function like :func:`int`, which takes a string like ``'123'`` and returns its numeric value 123. When you want to save more complex data types like nested lists and dictionaries, parsing and serializing by hand diff --git a/Doc/tutorial/interactive.rst b/Doc/tutorial/interactive.rst index c0eb1fee..0d3896a4 100644 --- a/Doc/tutorial/interactive.rst +++ b/Doc/tutorial/interactive.rst @@ -23,7 +23,7 @@ Python statement names, the current local variables, and the available module names. For dotted expressions such as ``string.a``, it will evaluate the expression up to the final ``'.'`` and then suggest completions from the attributes of the resulting object. Note that this may execute -application-defined code if an object with a :meth:`__getattr__` method +application-defined code if an object with a :meth:`~object.__getattr__` method is part of the expression. The default configuration also saves your history into a file named :file:`.python_history` in your user directory. The history will be available again during the next interactive interpreter diff --git a/Doc/tutorial/interpreter.rst b/Doc/tutorial/interpreter.rst index 08851cb8..b71c6108 100644 --- a/Doc/tutorial/interpreter.rst +++ b/Doc/tutorial/interpreter.rst @@ -10,13 +10,13 @@ Using the Python Interpreter Invoking the Interpreter ======================== -The Python interpreter is usually installed as :file:`/usr/local/bin/python3.11` +The Python interpreter is usually installed as :file:`/usr/local/bin/python3.12` on those machines where it is available; putting :file:`/usr/local/bin` in your Unix shell's search path makes it possible to start it by typing the command: .. code-block:: text - python3.11 + python3.12 to the shell. [#]_ Since the choice of the directory where the interpreter lives is an installation option, other places are possible; check with your local @@ -24,7 +24,7 @@ Python guru or system administrator. (E.g., :file:`/usr/local/python` is a popular alternative location.) On Windows machines where you have installed Python from the :ref:`Microsoft Store -<windows-store>`, the :file:`python3.11` command will be available. If you have +<windows-store>`, the :file:`python3.12` command will be available. If you have the :ref:`py.exe launcher <launcher>` installed, you can use the :file:`py` command. See :ref:`setting-envvars` for other ways to launch Python. @@ -97,8 +97,8 @@ before printing the first prompt: .. code-block:: shell-session - $ python3.11 - Python 3.11 (default, April 4 2021, 09:25:04) + $ python3.12 + Python 3.12 (default, April 4 2022, 09:25:04) [GCC 10.2.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> diff --git a/Doc/tutorial/introduction.rst b/Doc/tutorial/introduction.rst index b7a89905..0fc75c7d 100644 --- a/Doc/tutorial/introduction.rst +++ b/Doc/tutorial/introduction.rst @@ -52,8 +52,8 @@ Numbers The interpreter acts as a simple calculator: you can type an expression at it and it will write the value. Expression syntax is straightforward: the -operators ``+``, ``-``, ``*`` and ``/`` work just like in most other languages -(for example, Pascal or C); parentheses (``()``) can be used for grouping. +operators ``+``, ``-``, ``*`` and ``/`` can be used to perform +arithmetic; parentheses (``()``) can be used for grouping. For example:: >>> 2 + 2 @@ -138,16 +138,25 @@ and uses the ``j`` or ``J`` suffix to indicate the imaginary part .. _tut-strings: -Strings -------- +Text +---- -Besides numbers, Python can also manipulate strings, which can be expressed -in several ways. They can be enclosed in single quotes (``'...'``) or -double quotes (``"..."``) with the same result [#]_. ``\`` can be used -to escape quotes:: +Python can manipulate text (represented by type :class:`str`, so-called +"strings") as well as numbers. This includes characters "``!``", words +"``rabbit``", names "``Paris``", sentences "``Got your back.``", etc. +"``Yay! :)``". They can be enclosed in single quotes (``'...'``) or double +quotes (``"..."``) with the same result [#]_. >>> 'spam eggs' # single quotes 'spam eggs' + >>> "Paris rabbit got your back :)! Yay!" # double quotes + 'Paris rabbit got your back :)! Yay!' + >>> '1975' # digits and numerals enclosed in quotes are also strings + '1975' + +To quote a quote, we need to "escape" it, by preceding it with ``\``. +Alternatively, we can use the other type of quotation marks:: + >>> 'doesn\'t' # use \' to escape the single quote... "doesn't" >>> "doesn't" # ...or use double quotes instead @@ -159,23 +168,14 @@ to escape quotes:: >>> '"Isn\'t," they said.' '"Isn\'t," they said.' -In the interactive interpreter, the output string is enclosed in quotes and -special characters are escaped with backslashes. While this might sometimes -look different from the input (the enclosing quotes could change), the two -strings are equivalent. The string is enclosed in double quotes if -the string contains a single quote and no double quotes, otherwise it is -enclosed in single quotes. The :func:`print` function produces a more -readable output, by omitting the enclosing quotes and by printing escaped -and special characters:: +In the Python shell, the string definition and output string can look +different. The :func:`print` function produces a more readable output, by +omitting the enclosing quotes and by printing escaped and special characters:: - >>> '"Isn\'t," they said.' - '"Isn\'t," they said.' - >>> print('"Isn\'t," they said.') - "Isn't," they said. >>> s = 'First line.\nSecond line.' # \n means newline - >>> s # without print(), \n is included in the output + >>> s # without print(), special characters are included in the string 'First line.\nSecond line.' - >>> print(s) # with print(), \n produces a new line + >>> print(s) # with print(), special characters are interpreted, so \n produces new line First line. Second line. @@ -274,7 +274,7 @@ Indices may also be negative numbers, to start counting from the right:: Note that since -0 is the same as 0, negative indices start from -1. In addition to indexing, *slicing* is also supported. While indexing is used -to obtain individual characters, *slicing* allows you to obtain substring:: +to obtain individual characters, *slicing* allows you to obtain a substring:: >>> word[0:2] # characters from position 0 (included) to 2 (excluded) 'Py' diff --git a/Doc/tutorial/modules.rst b/Doc/tutorial/modules.rst index ad70d929..bf9e8e0b 100644 --- a/Doc/tutorial/modules.rst +++ b/Doc/tutorial/modules.rst @@ -183,7 +183,7 @@ The Module Search Path .. index:: triple: module; search; path -When a module named :mod:`spam` is imported, the interpreter first searches for +When a module named :mod:`!spam` is imported, the interpreter first searches for a built-in module with that name. These module names are listed in :data:`sys.builtin_module_names`. If not found, it then searches for a file named :file:`spam.py` in a list of directories given by the variable @@ -264,7 +264,7 @@ Some tips for experts: Standard Modules ================ -.. index:: module: sys +.. index:: pair: module; sys Python comes with a library of standard modules, described in a separate document, the Python Library Reference ("Library Reference" hereafter). Some @@ -345,7 +345,7 @@ Without arguments, :func:`dir` lists the names you have defined currently:: Note that it lists all types of names: variables, modules, functions, etc. -.. index:: module: builtins +.. index:: pair: module; builtins :func:`dir` does not list the names of built-in functions and variables. If you want a list of those, they are defined in the standard module @@ -389,7 +389,7 @@ Packages ======== Packages are a way of structuring Python's module namespace by using "dotted -module names". For example, the module name :mod:`A.B` designates a submodule +module names". For example, the module name :mod:`!A.B` designates a submodule named ``B`` in a package named ``A``. Just like the use of modules saves the authors of different modules from having to worry about each other's global variable names, the use of dotted module names saves the authors of multi-module @@ -438,7 +438,7 @@ When importing the package, Python searches through the directories on The :file:`__init__.py` files are required to make Python treat directories containing the file as packages. This prevents directories with a common name, -such as ``string``, unintentionally hiding valid modules that occur later +such as ``string``, from unintentionally hiding valid modules that occur later on the module search path. In the simplest case, :file:`__init__.py` can just be an empty file, but it can also execute initialization code for the package or set the ``__all__`` variable, described later. @@ -448,7 +448,7 @@ example:: import sound.effects.echo -This loads the submodule :mod:`sound.effects.echo`. It must be referenced with +This loads the submodule :mod:`!sound.effects.echo`. It must be referenced with its full name. :: sound.effects.echo.echofilter(input, output, delay=0.7, atten=4) @@ -457,7 +457,7 @@ An alternative way of importing the submodule is:: from sound.effects import echo -This also loads the submodule :mod:`echo`, and makes it available without its +This also loads the submodule :mod:`!echo`, and makes it available without its package prefix, so it can be used as follows:: echo.echofilter(input, output, delay=0.7, atten=4) @@ -466,8 +466,8 @@ Yet another variation is to import the desired function or variable directly:: from sound.effects.echo import echofilter -Again, this loads the submodule :mod:`echo`, but this makes its function -:func:`echofilter` directly available:: +Again, this loads the submodule :mod:`!echo`, but this makes its function +:func:`!echofilter` directly available:: echofilter(input, output, delay=0.7, atten=4) @@ -510,11 +510,27 @@ code:: __all__ = ["echo", "surround", "reverse"] This would mean that ``from sound.effects import *`` would import the three -named submodules of the :mod:`sound.effects` package. +named submodules of the :mod:`!sound.effects` package. + +Be aware that submodules might become shadowed by locally defined names. For +example, if you added a ``reverse`` function to the +:file:`sound/effects/__init__.py` file, the ``from sound.effects import *`` +would only import the two submodules ``echo`` and ``surround``, but *not* the +``reverse`` submodule, because it is shadowed by the locally defined +``reverse`` function:: + + __all__ = [ + "echo", # refers to the 'echo.py' file + "surround", # refers to the 'surround.py' file + "reverse", # !!! refers to the 'reverse' function now !!! + ] + + def reverse(msg: str): # <-- this name shadows the 'reverse.py' submodule + return msg[::-1] # in the case of a 'from sound.effects import *' If ``__all__`` is not defined, the statement ``from sound.effects import *`` -does *not* import all submodules from the package :mod:`sound.effects` into the -current namespace; it only ensures that the package :mod:`sound.effects` has +does *not* import all submodules from the package :mod:`!sound.effects` into the +current namespace; it only ensures that the package :mod:`!sound.effects` has been imported (possibly running any initialization code in :file:`__init__.py`) and then imports whatever names are defined in the package. This includes any names defined (and submodules explicitly loaded) by :file:`__init__.py`. It @@ -525,8 +541,8 @@ previous :keyword:`import` statements. Consider this code:: import sound.effects.surround from sound.effects import * -In this example, the :mod:`echo` and :mod:`surround` modules are imported in the -current namespace because they are defined in the :mod:`sound.effects` package +In this example, the :mod:`!echo` and :mod:`!surround` modules are imported in the +current namespace because they are defined in the :mod:`!sound.effects` package when the ``from...import`` statement is executed. (This also works when ``__all__`` is defined.) @@ -545,15 +561,15 @@ packages. Intra-package References ------------------------ -When packages are structured into subpackages (as with the :mod:`sound` package +When packages are structured into subpackages (as with the :mod:`!sound` package in the example), you can use absolute imports to refer to submodules of siblings -packages. For example, if the module :mod:`sound.filters.vocoder` needs to use -the :mod:`echo` module in the :mod:`sound.effects` package, it can use ``from +packages. For example, if the module :mod:`!sound.filters.vocoder` needs to use +the :mod:`!echo` module in the :mod:`!sound.effects` package, it can use ``from sound.effects import echo``. You can also write relative imports, with the ``from module import name`` form of import statement. These imports use leading dots to indicate the current and -parent packages involved in the relative import. From the :mod:`surround` +parent packages involved in the relative import. From the :mod:`!surround` module for example, you might use:: from . import echo diff --git a/Doc/tutorial/stdlib.rst b/Doc/tutorial/stdlib.rst index a94a7f45..6bae279c 100644 --- a/Doc/tutorial/stdlib.rst +++ b/Doc/tutorial/stdlib.rst @@ -15,7 +15,7 @@ operating system:: >>> import os >>> os.getcwd() # Return the current working directory - 'C:\\Python311' + 'C:\\Python312' >>> os.chdir('/server/accesslogs') # Change current working directory >>> os.system('mkdir today') # Run the command mkdir in the system shell 0 @@ -24,7 +24,7 @@ Be sure to use the ``import os`` style instead of ``from os import *``. This will keep :func:`os.open` from shadowing the built-in :func:`open` function which operates much differently. -.. index:: builtin: help +.. index:: pair: built-in function; help The built-in :func:`dir` and :func:`help` functions are useful as interactive aids for working with large modules like :mod:`os`:: @@ -65,11 +65,15 @@ Command Line Arguments Common utility scripts often need to process command line arguments. These arguments are stored in the :mod:`sys` module's *argv* attribute as a list. For -instance the following output results from running ``python demo.py one two -three`` at the command line:: +instance, let's take the following :file:`demo.py` file:: + + # File demo.py + import sys + print(sys.argv) + +Here is the output from running ``python demo.py one two three`` at the command +line:: - >>> import sys - >>> print(sys.argv) ['demo.py', 'one', 'two', 'three'] The :mod:`argparse` module provides a more sophisticated mechanism to process diff --git a/Doc/tutorial/stdlib2.rst b/Doc/tutorial/stdlib2.rst index 24cf0970..33f311db 100644 --- a/Doc/tutorial/stdlib2.rst +++ b/Doc/tutorial/stdlib2.rst @@ -59,7 +59,7 @@ formatting numbers with group separators:: 'English_United States.1252' >>> conv = locale.localeconv() # get a mapping of conventions >>> x = 1234567.8 - >>> locale.format("%d", x, grouping=True) + >>> locale.format_string("%d", x, grouping=True) '1,234,567' >>> locale.format_string("%s%.*f", (conv['currency_symbol'], ... conv['frac_digits'], x), grouping=True) @@ -279,7 +279,7 @@ applications include caching objects that are expensive to create:: Traceback (most recent call last): File "<stdin>", line 1, in <module> d['primary'] # entry was automatically removed - File "C:/python311/lib/weakref.py", line 46, in __getitem__ + File "C:/python312/lib/weakref.py", line 46, in __getitem__ o = self.data[key]() KeyError: 'primary' @@ -394,7 +394,7 @@ point:: >>> sum([Decimal('0.1')]*10) == Decimal('1.0') True - >>> sum([0.1]*10) == 1.0 + >>> 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 == 1.0 False The :mod:`decimal` module provides arithmetic with as much precision as needed:: diff --git a/Doc/tutorial/venv.rst b/Doc/tutorial/venv.rst index 8312c587..a6dead2e 100644 --- a/Doc/tutorial/venv.rst +++ b/Doc/tutorial/venv.rst @@ -44,7 +44,7 @@ whichever version you want. To create a virtual environment, decide upon a directory where you want to place it, and run the :mod:`venv` module as a script with the directory path:: - python3 -m venv tutorial-env + python -m venv tutorial-env This will create the ``tutorial-env`` directory if it doesn't exist, and also create directories inside it containing a copy of the Python @@ -60,7 +60,7 @@ Once you've created a virtual environment, you may activate it. On Windows, run:: - tutorial-env\Scripts\activate.bat + tutorial-env\Scripts\activate On Unix or MacOS, run:: @@ -207,4 +207,6 @@ necessary packages with ``install -r``: ``pip`` has many more options. Consult the :ref:`installing-index` guide for complete documentation for ``pip``. When you've written a package and want to make it available on the Python Package Index, -consult the :ref:`distributing-index` guide. +consult the `Python packaging user guide`_. + +.. _Python Packaging User Guide: https://packaging.python.org/en/latest/tutorials/packaging-projects/ diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst index 2a69ef8f..bade3ca6 100644 --- a/Doc/using/cmdline.rst +++ b/Doc/using/cmdline.rst @@ -109,7 +109,7 @@ source. Many standard library modules contain code that is invoked on their execution as a script. An example is the :mod:`timeit` module:: - python -m timeit -s 'setup here' 'benchmarked code here' + python -m timeit -s "setup here" "benchmarked code here" python -m timeit -h # for details .. audit-event:: cpython.run_module module-name cmdoption-m @@ -271,8 +271,11 @@ Miscellaneous options .. cmdoption:: -d - Turn on parser debugging output (for expert only, depending on compilation - options). See also :envvar:`PYTHONDEBUG`. + Turn on parser debugging output (for expert only). + See also the :envvar:`PYTHONDEBUG` environment variable. + + This option requires a :ref:`debug build of Python <debug-build>`, otherwise + it's ignored. .. cmdoption:: -E @@ -367,7 +370,7 @@ Miscellaneous options Hash randomization is intended to provide protection against a denial-of-service caused by carefully chosen inputs that exploit the worst case performance of a dict construction, O(n\ :sup:`2`) complexity. See - http://www.ocert.org/advisories/ocert-2011-003.html for details. + http://ocert.org/advisories/ocert-2011-003.html for details. :envvar:`PYTHONHASHSEED` allows you to set a fixed value for the hash seed secret. @@ -492,7 +495,8 @@ Miscellaneous options Reserved for various implementation-specific options. CPython currently defines the following possible values: - * ``-X faulthandler`` to enable :mod:`faulthandler`; + * ``-X faulthandler`` to enable :mod:`faulthandler`. + See also :envvar:`PYTHONFAULTHANDLER`. * ``-X showrefcount`` to output the total reference count and number of used memory blocks when the program finishes or after each statement in the interactive interpreter. This only works on :ref:`debug builds @@ -500,8 +504,9 @@ Miscellaneous options * ``-X tracemalloc`` to start tracing Python memory allocations using the :mod:`tracemalloc` module. By default, only the most recent frame is stored in a traceback of a trace. Use ``-X tracemalloc=NFRAME`` to start - tracing with a traceback limit of *NFRAME* frames. See the - :func:`tracemalloc.start` for more information. + tracing with a traceback limit of *NFRAME* frames. + See :func:`tracemalloc.start` and :envvar:`PYTHONTRACEMALLOC` + for more information. * ``-X int_max_str_digits`` configures the :ref:`integer string conversion length limitation <int_max_str_digits>`. See also :envvar:`PYTHONINTMAXSTRDIGITS`. @@ -516,6 +521,7 @@ Miscellaneous options * ``-X utf8`` enables the :ref:`Python UTF-8 Mode <utf8-mode>`. ``-X utf8=0`` explicitly disables :ref:`Python UTF-8 Mode <utf8-mode>` (even when it would otherwise activate automatically). + See also :envvar:`PYTHONUTF8`. * ``-X pycache_prefix=PATH`` enables writing ``.pyc`` files to a parallel tree rooted at the given directory instead of to the code tree. See also :envvar:`PYTHONPYCACHEPREFIX`. @@ -535,6 +541,11 @@ Miscellaneous options development (running from the source tree) then the default is "off". Note that the "importlib_bootstrap" and "importlib_bootstrap_external" frozen modules are always used, even if this flag is set to "off". + * ``-X perf`` enables support for the Linux ``perf`` profiler. + When this option is provided, the ``perf`` profiler will be able to + report Python calls. This option is only available on some platforms and + will do nothing if is not supported on the current system. The default value + is "off". See also :envvar:`PYTHONPERFSUPPORT` and :ref:`perf_profiling`. It also allows passing arbitrary values and retrieving them through the :data:`sys._xoptions` dictionary. @@ -579,6 +590,9 @@ Miscellaneous options .. versionadded:: 3.11 The ``-X int_max_str_digits`` option. + .. versionadded:: 3.12 + The ``-X perf`` option. + Options you shouldn't use ~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -690,6 +704,9 @@ conflict. :option:`-d` option. If set to an integer, it is equivalent to specifying :option:`-d` multiple times. + This environment variable requires a :ref:`debug build of Python + <debug-build>`, otherwise it's ignored. + .. envvar:: PYTHONINSPECT @@ -794,8 +811,8 @@ conflict. Defines the :data:`user base directory <site.USER_BASE>`, which is used to compute the path of the :data:`user site-packages directory <site.USER_SITE>` - and :ref:`Distutils installation paths <inst-alt-install-user>` for - ``python setup.py install --user``. + and :ref:`installation paths <sysconfig-user-scheme>` for + ``python -m pip install --user``. .. seealso:: @@ -847,7 +864,9 @@ conflict. Python memory allocations using the :mod:`tracemalloc` module. The value of the variable is the maximum number of frames stored in a traceback of a trace. For example, ``PYTHONTRACEMALLOC=1`` stores only the most recent - frame. See the :func:`tracemalloc.start` for more information. + frame. + See the :func:`tracemalloc.start` function for more information. + This is equivalent to setting the :option:`-X` ``tracemalloc`` option. .. versionadded:: 3.4 @@ -855,8 +874,8 @@ conflict. .. envvar:: PYTHONPROFILEIMPORTTIME If this environment variable is set to a non-empty string, Python will - show how long each import takes. This is exactly equivalent to setting - ``-X importtime`` on the command line. + show how long each import takes. + This is equivalent to setting the :option:`-X` ``importtime`` option. .. versionadded:: 3.7 @@ -878,11 +897,11 @@ conflict. * ``default``: use the :ref:`default memory allocators <default-memory-allocators>`. * ``malloc``: use the :c:func:`malloc` function of the C library - for all domains (:c:data:`PYMEM_DOMAIN_RAW`, :c:data:`PYMEM_DOMAIN_MEM`, - :c:data:`PYMEM_DOMAIN_OBJ`). + for all domains (:c:macro:`PYMEM_DOMAIN_RAW`, :c:macro:`PYMEM_DOMAIN_MEM`, + :c:macro:`PYMEM_DOMAIN_OBJ`). * ``pymalloc``: use the :ref:`pymalloc allocator <pymalloc>` for - :c:data:`PYMEM_DOMAIN_MEM` and :c:data:`PYMEM_DOMAIN_OBJ` domains and use - the :c:func:`malloc` function for the :c:data:`PYMEM_DOMAIN_RAW` domain. + :c:macro:`PYMEM_DOMAIN_MEM` and :c:macro:`PYMEM_DOMAIN_OBJ` domains and use + the :c:func:`malloc` function for the :c:macro:`PYMEM_DOMAIN_RAW` domain. Install :ref:`debug hooks <pymem-debug-hooks>`: @@ -998,6 +1017,7 @@ conflict. If this environment variable is set to a non-empty string, enable :ref:`Python Development Mode <devmode>`, introducing additional runtime checks that are too expensive to be enabled by default. + This is equivalent to setting the :option:`-X` ``dev`` option. .. versionadded:: 3.7 @@ -1031,19 +1051,21 @@ conflict. .. versionadded:: 3.11 +.. envvar:: PYTHONPERFSUPPORT + If this variable is set to a nonzero value, it enables support for + the Linux ``perf`` profiler so Python calls can be detected by it. -Debug-mode variables -~~~~~~~~~~~~~~~~~~~~ - -.. envvar:: PYTHONTHREADDEBUG + If set to ``0``, disable Linux ``perf`` profiler support. - If set, Python will print threading debug info into stdout. + See also the :option:`-X perf <-X>` command-line option + and :ref:`perf_profiling`. - Need a :ref:`debug build of Python <debug-build>`. + .. versionadded:: 3.12 - .. deprecated-removed:: 3.10 3.12 +Debug-mode variables +~~~~~~~~~~~~~~~~~~~~ .. envvar:: PYTHONDUMPREFS diff --git a/Doc/using/configure.rst b/Doc/using/configure.rst index c387528d..3fe2a635 100644 --- a/Doc/using/configure.rst +++ b/Doc/using/configure.rst @@ -2,6 +2,70 @@ Configure Python **************** +Build Requirements +================== + +Features required to build CPython: + +* A `C11 <https://en.cppreference.com/w/c/11>`_ compiler. `Optional C11 + features + <https://en.wikipedia.org/wiki/C11_(C_standard_revision)#Optional_features>`_ + are not required. + +* Support for `IEEE 754 <https://en.wikipedia.org/wiki/IEEE_754>`_ floating + point numbers and `floating point Not-a-Number (NaN) + <https://en.wikipedia.org/wiki/NaN#Floating_point>`_. + +* Support for threads. + +* OpenSSL 1.1.1 or newer for the :mod:`ssl` and :mod:`hashlib` modules. + +* On Windows, Microsoft Visual Studio 2017 or later is required. + +.. versionchanged:: 3.11 + C11 compiler, IEEE 754 and NaN support are now required. + On Windows, Visual Studio 2017 or later is required. + +.. versionchanged:: 3.10 + OpenSSL 1.1.1 is now required. + +.. versionchanged:: 3.7 + Thread support and OpenSSL 1.0.2 are now required. + +.. versionchanged:: 3.6 + Selected C99 features are now required, like ``<stdint.h>`` and ``static + inline`` functions. + +.. versionchanged:: 3.5 + On Windows, Visual Studio 2015 or later is required. + +See also :pep:`7` "Style Guide for C Code" and :pep:`11` "CPython platform +support". + + +Generated files +=============== + +To reduce build dependencies, Python source code contains multiple generated +files. Commands to regenerate all generated files:: + + make regen-all + make regen-stdlib-module-names + make regen-limited-abi + make regen-configure + +The ``Makefile.pre.in`` file documents generated files, their inputs, and tools used +to regenerate them. Search for ``regen-*`` make targets. + +The ``make regen-configure`` command runs `tiran/cpython_autoconf +<https://github.com/tiran/cpython_autoconf>`_ container for reproducible build; +see container ``entry.sh`` script. The container is optional, the following +command can be run locally, the generated files depend on autoconf and aclocal +versions:: + + autoreconf -ivf -Werror + + .. _configure-options: Configure Options @@ -18,8 +82,8 @@ General Options .. cmdoption:: --enable-loadable-sqlite-extensions - Support loadable extensions in the :mod:`_sqlite` extension module (default - is no). + Support loadable extensions in the :mod:`!_sqlite` extension module (default + is no) of the :mod:`sqlite3` module. See the :meth:`sqlite3.Connection.enable_load_extension` method of the :mod:`sqlite3` module. @@ -41,12 +105,6 @@ General Options See :data:`sys.int_info.bits_per_digit <sys.int_info>`. -.. cmdoption:: --with-cxx-main -.. cmdoption:: --with-cxx-main=COMPILER - - Compile the Python ``main()`` function and link Python executable with C++ - compiler: ``$CXX``, or *COMPILER* if specified. - .. cmdoption:: --with-suffix=SUFFIX Set the Python executable suffix to *SUFFIX*. @@ -62,7 +120,7 @@ General Options .. cmdoption:: --with-tzpath=<list of absolute paths separated by pathsep> - Select the default time zone search path for :data:`zoneinfo.TZPATH`. + Select the default time zone search path for :const:`zoneinfo.TZPATH`. See the :ref:`Compile-time configuration <zoneinfo_data_compile_time_config>` of the :mod:`zoneinfo` module. @@ -77,7 +135,7 @@ General Options Build the ``_decimal`` extension module using a thread-local context rather than a coroutine-local context (default), see the :mod:`decimal` module. - See :data:`decimal.HAVE_CONTEXTVAR` and the :mod:`contextvars` module. + See :const:`decimal.HAVE_CONTEXTVAR` and the :mod:`contextvars` module. .. versionadded:: 3.9 @@ -99,6 +157,12 @@ General Options See :envvar:`PYTHONCOERCECLOCALE` and the :pep:`538`. +.. cmdoption:: --without-freelists + + Disable all freelists except the empty tuple singleton. + + .. versionadded:: 3.11 + .. cmdoption:: --with-platlibdir=DIRNAME Python library directory name (default is ``lib``). @@ -117,7 +181,7 @@ General Options Some Linux distribution packaging policies recommend against bundling dependencies. For example, Fedora installs wheel packages in the ``/usr/share/python-wheels/`` directory and don't install the - :mod:`ensurepip._bundled` package. + :mod:`!ensurepip._bundled` package. .. versionadded:: 3.10 @@ -137,7 +201,8 @@ General Options Turn on internal statistics gathering. The statistics will be dumped to a arbitrary (probably unique) file in - ``/tmp/py_stats/``, or ``C:\temp\py_stats\`` on Windows. + ``/tmp/py_stats/``, or ``C:\temp\py_stats\`` on Windows. If that directory + does not exist, results will be printed on stdout. Use ``Tools/scripts/summarize_stats.py`` to read the stats. @@ -174,10 +239,26 @@ WebAssembly Options Install Options --------------- +.. cmdoption:: --prefix=PREFIX + + Install architecture-independent files in PREFIX. On Unix, it + defaults to :file:`/usr/local`. + + This value can be retrieved at runtime using :data:`sys.prefix`. + + As an example, one can use ``--prefix="$HOME/.local/"`` to install + a Python in its home directory. + +.. cmdoption:: --exec-prefix=EPREFIX + + Install architecture-dependent files in EPREFIX, defaults to :option:`--prefix`. + + This value can be retrieved at runtime using :data:`sys.exec_prefix`. + .. cmdoption:: --disable-test-modules Don't build nor install test modules, like the :mod:`test` package or the - :mod:`_testcapi` extension module (built and installed by default). + :mod:`!_testcapi` extension module (built and installed by default). .. versionadded:: 3.10 @@ -197,7 +278,8 @@ Performance options ------------------- Configuring Python using ``--enable-optimizations --with-lto`` (PGO + LTO) is -recommended for best performance. +recommended for best performance. The experimental ``--enable-bolt`` flag can +also be used to improve performance. .. cmdoption:: --enable-optimizations @@ -237,6 +319,34 @@ recommended for best performance. .. versionadded:: 3.11 To use ThinLTO feature, use ``--with-lto=thin`` on Clang. + .. versionchanged:: 3.12 + Use ThinLTO as the default optimization policy on Clang if the compiler accepts the flag. + +.. cmdoption:: --enable-bolt + + Enable usage of the `BOLT post-link binary optimizer + <https://github.com/llvm/llvm-project/tree/main/bolt>`_ (disabled by + default). + + BOLT is part of the LLVM project but is not always included in their binary + distributions. This flag requires that ``llvm-bolt`` and ``merge-fdata`` + are available. + + BOLT is still a fairly new project so this flag should be considered + experimental for now. Because this tool operates on machine code its success + is dependent on a combination of the build environment + the other + optimization configure args + the CPU architecture, and not all combinations + are supported. + BOLT versions before LLVM 16 are known to crash BOLT under some scenarios. + Use of LLVM 16 or newer for BOLT optimization is strongly encouraged. + + The :envvar:`!BOLT_INSTRUMENT_FLAGS` and :envvar:`!BOLT_APPLY_FLAGS` + :program:`configure` variables can be defined to override the default set of + arguments for :program:`llvm-bolt` to instrument and apply BOLT data to + binaries, respectively. + + .. versionadded:: 3.12 + .. cmdoption:: --with-computed-gotos Enable computed gotos in evaluation loop (enabled by default on supported @@ -262,6 +372,11 @@ recommended for best performance. Enable C-level code profiling with ``gprof`` (disabled by default). +.. cmdoption:: --with-strict-overflow + + Add ``-fstrict-overflow`` to the C compiler flags (by default we add + ``-fno-strict-overflow`` instead). + .. _debug-build: @@ -276,9 +391,10 @@ Effects of a debug build: * Display all warnings by default: the list of default warning filters is empty in the :mod:`warnings` module. * Add ``d`` to :data:`sys.abiflags`. -* Add :func:`sys.gettotalrefcount` function. +* Add :func:`!sys.gettotalrefcount` function. * Add :option:`-X showrefcount <-X>` command line option. -* Add :envvar:`PYTHONTHREADDEBUG` environment variable. +* Add :option:`-d` command line option and :envvar:`PYTHONDEBUG` environment + variable to debug the parser. * Add support for the ``__lltrace__`` variable: enable low-level tracing in the bytecode evaluation loop if the variable is defined. * Install :ref:`debug hooks on memory allocators <default-memory-allocators>` @@ -297,7 +413,7 @@ Effects of a debug build: * Check that deallocator functions don't change the current exception. * The garbage collector (:func:`gc.collect` function) runs some basic checks on objects consistency. - * The :c:macro:`Py_SAFE_DOWNCAST()` macro checks for integer underflow and + * The :c:macro:`!Py_SAFE_DOWNCAST()` macro checks for integer underflow and overflow when downcasting from wide types to narrow types. See also the :ref:`Python Development Mode <devmode>` and the @@ -325,7 +441,7 @@ Debug options Effects: * Define the ``Py_TRACE_REFS`` macro. - * Add :func:`sys.getobjects` function. + * Add :func:`!sys.getobjects` function. * Add :envvar:`PYTHONDUMPREFS` environment variable. This build is not ABI compatible with release build (default build) or debug @@ -403,14 +519,9 @@ Libraries options .. cmdoption:: --with-system-expat - Build the :mod:`pyexpat` module using an installed ``expat`` library + Build the :mod:`!pyexpat` module using an installed ``expat`` library (default is no). -.. cmdoption:: --with-system-ffi - - Build the :mod:`_ctypes` extension module using an installed ``ffi`` - library, see the :mod:`ctypes` module (default is system-dependent). - .. cmdoption:: --with-system-libmpdec Build the ``_decimal`` extension module using an installed ``mpdec`` @@ -598,7 +709,6 @@ Main files of the build system * :file:`pyconfig.h` (created by :file:`configure`); * :file:`Modules/Setup`: C extensions built by the Makefile using :file:`Module/makesetup` shell script; -* :file:`setup.py`: C extensions built using the :mod:`distutils` module. Main build steps ---------------- @@ -607,8 +717,7 @@ Main build steps * A static ``libpython`` library (``.a``) is created from objects files. * ``python.o`` and the static ``libpython`` library are linked into the final ``python`` program. -* C extensions are built by the Makefile (see :file:`Modules/Setup`) - and ``python setup.py build``. +* C extensions are built by the Makefile (see :file:`Modules/Setup`). Main Makefile targets --------------------- @@ -660,18 +769,15 @@ Example on Linux x86-64:: At the beginning of the files, C extensions are built as built-in modules. Extensions defined after the ``*shared*`` marker are built as dynamic libraries. -The :file:`setup.py` script only builds C extensions as shared libraries using -the :mod:`distutils` module. - -The :c:macro:`PyAPI_FUNC()`, :c:macro:`PyAPI_API()` and -:c:macro:`PyMODINIT_FUNC()` macros of :file:`Include/pyport.h` are defined +The :c:macro:`!PyAPI_FUNC()`, :c:macro:`!PyAPI_DATA()` and +:c:macro:`PyMODINIT_FUNC` macros of :file:`Include/exports.h` are defined differently depending if the ``Py_BUILD_CORE_MODULE`` macro is defined: * Use ``Py_EXPORTED_SYMBOL`` if the ``Py_BUILD_CORE_MODULE`` is defined * Use ``Py_IMPORTED_SYMBOL`` otherwise. If the ``Py_BUILD_CORE_BUILTIN`` macro is used by mistake on a C extension -built as a shared library, its ``PyInit_xxx()`` function is not exported, +built as a shared library, its :samp:`PyInit_{xxx}()` function is not exported, causing an :exc:`ImportError` on import. @@ -692,11 +798,11 @@ Preprocessor flags .. envvar:: CPPFLAGS - (Objective) C/C++ preprocessor flags, e.g. ``-I<include dir>`` if you have - headers in a nonstandard directory ``<include dir>``. + (Objective) C/C++ preprocessor flags, e.g. :samp:`-I{include_dir}` if you have + headers in a nonstandard directory *include_dir*. Both :envvar:`CPPFLAGS` and :envvar:`LDFLAGS` need to contain the shell's - value for setup.py to be able to build extension modules using the + value to be able to build extension modules using the directories specified in the environment variables. .. envvar:: BASECPPFLAGS @@ -720,22 +826,10 @@ Compiler flags Example: ``gcc -pthread``. -.. envvar:: MAINCC - - C compiler command used to build the ``main()`` function of programs like - ``python``. - - Variable set by the :option:`--with-cxx-main` option of the configure - script. - - Default: ``$(CC)``. - .. envvar:: CXX C++ compiler command. - Used if the :option:`--with-cxx-main` option is used. - Example: ``g++ -pthread``. .. envvar:: CFLAGS @@ -745,8 +839,8 @@ Compiler flags .. envvar:: CFLAGS_NODIST :envvar:`CFLAGS_NODIST` is used for building the interpreter and stdlib C - extensions. Use it when a compiler flag should *not* be part of the - distutils :envvar:`CFLAGS` once Python is installed (:issue:`21121`). + extensions. Use it when a compiler flag should *not* be part of + :envvar:`CFLAGS` once Python is installed (:gh:`65320`). In particular, :envvar:`CFLAGS` should not contain: @@ -761,6 +855,13 @@ Compiler flags .. versionadded:: 3.5 +.. envvar:: COMPILEALL_OPTS + + Options passed to the :mod:`compileall` command line when building PYC files + in ``make install``. Default: ``-j0``. + + .. versionadded:: 3.12 + .. envvar:: EXTRA_CFLAGS Extra C compiler flags. @@ -853,7 +954,7 @@ Linker flags Linker command used to build programs like ``python`` and ``_testembed``. - Default: ``$(PURIFY) $(MAINCC)``. + Default: ``$(PURIFY) $(CC)``. .. envvar:: CONFIGURE_LDFLAGS @@ -869,7 +970,7 @@ Linker flags :envvar:`LDFLAGS_NODIST` is used in the same manner as :envvar:`CFLAGS_NODIST`. Use it when a linker flag should *not* be part of - the distutils :envvar:`LDFLAGS` once Python is installed (:issue:`35257`). + :envvar:`LDFLAGS` once Python is installed (:gh:`65320`). In particular, :envvar:`LDFLAGS` should not contain: @@ -887,11 +988,11 @@ Linker flags .. envvar:: LDFLAGS - Linker flags, e.g. ``-L<lib dir>`` if you have libraries in a nonstandard - directory ``<lib dir>``. + Linker flags, e.g. :samp:`-L{lib_dir}` if you have libraries in a nonstandard + directory *lib_dir*. Both :envvar:`CPPFLAGS` and :envvar:`LDFLAGS` need to contain the shell's - value for setup.py to be able to build extension modules using the + value to be able to build extension modules using the directories specified in the environment variables. .. envvar:: LIBS diff --git a/Doc/using/mac.rst b/Doc/using/mac.rst index 9ae0270e..eb1413af 100644 --- a/Doc/using/mac.rst +++ b/Doc/using/mac.rst @@ -66,7 +66,7 @@ number of standard Unix command line editors, :program:`vim` and :program:`BBEdit` or :program:`TextWrangler` from Bare Bones Software (see http://www.barebones.com/products/bbedit/index.html) are good choices, as is :program:`TextMate` (see https://macromates.com/). Other editors include -:program:`Gvim` (https://macvim-dev.github.io/macvim/) and :program:`Aquamacs` +:program:`Gvim` (https://macvim.org/macvim/) and :program:`Aquamacs` (http://aquamacs.org/). To run your script from the Terminal window you must make sure that @@ -125,13 +125,9 @@ http://www.hashcollision.org/hkn/python/idle_intro/index.html. Installing Additional Python Packages ===================================== -There are several methods to install additional Python packages: +This section has moved to the `Python Packaging User Guide`_. -* Packages can be installed via the standard Python distutils mode (``python - setup.py install``). - -* Many packages can also be installed via the :program:`setuptools` extension - or :program:`pip` wrapper, see https://pip.pypa.io/. +.. _Python Packaging User Guide: https://packaging.python.org/en/latest/tutorials/installing-packages/ GUI Programming on the Mac @@ -144,8 +140,8 @@ the foundation of most modern Mac development. Information on PyObjC is available from https://pypi.org/project/pyobjc/. The standard Python GUI toolkit is :mod:`tkinter`, based on the cross-platform -Tk toolkit (https://www.tcl.tk). An Aqua-native version of Tk is bundled with OS -X by Apple, and the latest version can be downloaded and installed from +Tk toolkit (https://www.tcl.tk). An Aqua-native version of Tk is bundled with +macOS by Apple, and the latest version can be downloaded and installed from https://www.activestate.com; it can also be built from source. *wxPython* is another popular cross-platform GUI toolkit that runs natively on diff --git a/Doc/using/unix.rst b/Doc/using/unix.rst index 24c02c99..58838c28 100644 --- a/Doc/using/unix.rst +++ b/Doc/using/unix.rst @@ -30,9 +30,9 @@ following links: for Debian users https://en.opensuse.org/Portal:Packaging for OpenSuse users - https://docs-old.fedoraproject.org/en-US/Fedora_Draft_Documentation/0.1/html/RPM_Guide/ch-creating-rpms.html + https://docs.fedoraproject.org/en-US/package-maintainers/Packaging_Tutorial_GNU_Hello/ for Fedora users - http://www.slackbook.org/html/package-management-making-packages.html + https://slackbook.org/html/package-management-making-packages.html for Slackware users @@ -54,13 +54,6 @@ On FreeBSD and OpenBSD pkg_add ftp://ftp.openbsd.org/pub/OpenBSD/4.2/packages/i386/python-2.5.1p2.tgz -On OpenSolaris --------------- - -You can get Python from `OpenCSW <https://www.opencsw.org/>`_. Various versions -of Python are available and can be installed with e.g. ``pkgutil -i python27``. - - .. _building-python-on-unix: Building Python @@ -93,7 +86,7 @@ Python-related paths and files ============================== These are subject to difference depending on local installation conventions; -:envvar:`prefix` (``${prefix}``) and :envvar:`exec_prefix` (``${exec_prefix}``) +:option:`prefix <--prefix>` and :option:`exec_prefix <--exec-prefix>` are installation-dependent and should be interpreted as for GNU software; they may be the same. diff --git a/Doc/using/venv-create.inc b/Doc/using/venv-create.inc index 0422cd2e..2fc90126 100644 --- a/Doc/using/venv-create.inc +++ b/Doc/using/venv-create.inc @@ -1,7 +1,7 @@ Creation of :ref:`virtual environments <venv-def>` is done by executing the command ``venv``:: - python3 -m venv /path/to/new/virtual/environment + python -m venv /path/to/new/virtual/environment Running this command creates the target directory (creating any parent directories that don't exist already) and places a ``pyvenv.cfg`` file in it @@ -26,7 +26,7 @@ re-used. On Windows, invoke the ``venv`` command as follows:: - c:\>c:\Python35\python -m venv c:\path\to\myenv + c:\>Python35\python -m venv c:\path\to\myenv Alternatively, if you configured the ``PATH`` and ``PATHEXT`` variables for your :ref:`Python installation <using-on-windows>`:: @@ -61,12 +61,16 @@ The command, if run with ``-h``, will show the available options:: environment (pip is bootstrapped by default) --prompt PROMPT Provides an alternative prompt prefix for this environment. - --upgrade-deps Upgrade core dependencies: pip setuptools to the + --upgrade-deps Upgrade core dependencies (pip) to the latest version in PyPI Once an environment has been created, you may wish to activate it, e.g. by sourcing an activate script in its bin directory. +.. versionchanged:: 3.12 + + ``setuptools`` is no longer a core venv dependency. + .. versionchanged:: 3.9 Add ``--upgrade-deps`` option to upgrade pip + setuptools to the latest on PyPI @@ -104,4 +108,3 @@ invoked to bootstrap ``pip`` into the virtual environment. Multiple paths can be given to ``venv``, in which case an identical virtual environment will be created, according to the given options, at each provided path. - diff --git a/Doc/using/windows.rst b/Doc/using/windows.rst index 50c220d7..919b76f2 100644 --- a/Doc/using/windows.rst +++ b/Doc/using/windows.rst @@ -126,11 +126,24 @@ command line, allowing scripted installers to replicate an installation on many machines without user interaction. These options may also be set without suppressing the UI in order to change some of the defaults. -To completely hide the installer UI and install Python silently, pass the -``/quiet`` option. To skip past the user interaction but still display -progress and errors, pass the ``/passive`` option. The ``/uninstall`` -option may be passed to immediately begin removing Python - no confirmation -prompt will be displayed. +The following options (found by executing the installer with ``/?``) can be +passed into the installer: + ++---------------------+--------------------------------------------------------+ +| Name | Description | ++=====================+========================================================+ +| /passive | to display progress without requiring user interaction | ++---------------------+--------------------------------------------------------+ +| /quiet | to install/uninstall without displaying any UI | ++---------------------+--------------------------------------------------------+ +| /simple | to prevent user customization | ++---------------------+--------------------------------------------------------+ +| /uninstall | to remove Python (without confirmation) | ++---------------------+--------------------------------------------------------+ +| /layout [directory] | to pre-download all components | ++---------------------+--------------------------------------------------------+ +| /log [filename] | to specify log files location | ++---------------------+--------------------------------------------------------+ All other options are passed as ``name=value``, where the value is usually ``0`` to disable a feature, ``1`` to enable a feature, or a path. The full list @@ -457,7 +470,7 @@ user's system, including environment variables, system registry settings, and installed packages. The standard library is included as pre-compiled and optimized ``.pyc`` files in a ZIP, and ``python3.dll``, ``python37.dll``, ``python.exe`` and ``pythonw.exe`` are all provided. Tcl/tk (including all -dependants, such as Idle), pip and the Python documentation are not included. +dependents, such as Idle), pip and the Python documentation are not included. .. note:: @@ -528,7 +541,7 @@ Besides the standard CPython distribution, there are modified packages including additional functionality. The following is a list of popular versions and their key features: -`ActivePython <https://www.activestate.com/activepython/>`_ +`ActivePython <https://www.activestate.com/products/python/>`_ Installer with multi-platform compatibility, documentation, PyWin32 `Anaconda <https://www.anaconda.com/download/>`_ @@ -876,7 +889,7 @@ minor version. I.e. ``/usr/bin/python3.7-32`` will request usage of the The "-64" suffix is deprecated, and now implies "any architecture that is not provably i386/32-bit". To request a specific environment, use the new - ``-V:<TAG>`` argument with the complete tag. + :samp:`-V:{TAG}` argument with the complete tag. The ``/usr/bin/env`` form of shebang line has one further special property. Before looking for installed Python interpreters, this form will search the @@ -1179,7 +1192,7 @@ non-standard paths in the registry and user site-packages. * Adds ``._pth`` file support and removes ``applocal`` option from ``pyvenv.cfg``. - * Adds ``pythonXX.zip`` as a potential landmark when directly adjacent + * Adds :file:`python{XX}.zip` as a potential landmark when directly adjacent to the executable. .. deprecated:: @@ -1188,7 +1201,7 @@ non-standard paths in the registry and user site-packages. Modules specified in the registry under ``Modules`` (not ``PythonPath``) may be imported by :class:`importlib.machinery.WindowsRegistryFinder`. This finder is enabled on Windows in 3.6.0 and earlier, but may need to - be explicitly added to :attr:`sys.meta_path` in the future. + be explicitly added to :data:`sys.meta_path` in the future. Additional modules ================== @@ -1233,11 +1246,10 @@ shipped with PyWin32. It is an embeddable IDE with a built-in debugger. cx_Freeze --------- -`cx_Freeze <https://cx-freeze.readthedocs.io/en/latest/>`_ is a :mod:`distutils` -extension (see :ref:`extending-distutils`) which wraps Python scripts into -executable Windows programs (:file:`{*}.exe` files). When you have done this, -you can distribute your application without requiring your users to install -Python. +`cx_Freeze <https://cx-freeze.readthedocs.io/en/latest/>`_ +wraps Python scripts into executable Windows programs +(:file:`{*}.exe` files). When you have done this, you can distribute your +application without requiring your users to install Python. Compiling Python on Windows diff --git a/Doc/whatsnew/2.0.rst b/Doc/whatsnew/2.0.rst index 6b16dfd4..a5fc847d 100644 --- a/Doc/whatsnew/2.0.rst +++ b/Doc/whatsnew/2.0.rst @@ -153,9 +153,9 @@ Lundh. A detailed explanation of the interface was written up as :pep:`100`, significant points about the Unicode interfaces. In Python source code, Unicode strings are written as ``u"string"``. Arbitrary -Unicode characters can be written using a new escape sequence, ``\uHHHH``, where +Unicode characters can be written using a new escape sequence, :samp:`\\u{HHHH}`, where *HHHH* is a 4-digit hexadecimal number from 0000 to FFFF. The existing -``\xHHHH`` escape sequence can also be used, and octal escapes can be used for +:samp:`\\x{HH}` escape sequence can also be used, and octal escapes can be used for characters up to U+01FF, which is represented by ``\777``. Unicode strings, just like regular strings, are an immutable sequence type. @@ -664,7 +664,7 @@ extra set of parentheses to pass both values as a tuple: ``L.append( (1,2) )``. The earlier versions of these methods were more forgiving because they used an old function in Python's C interface to parse their arguments; 2.0 modernizes -them to use :func:`PyArg_ParseTuple`, the current argument parsing function, +them to use :c:func:`PyArg_ParseTuple`, the current argument parsing function, which provides more helpful error messages and treats multi-argument calls as errors. If you absolutely must use 2.0 but can't fix your code, you can edit :file:`Objects/listobject.c` and define the preprocessor symbol @@ -766,7 +766,7 @@ file, :file:`Include/pyport.h`. Vladimir Marangozov's long-awaited malloc restructuring was completed, to make it easy to have the Python interpreter use a custom allocator instead of C's -standard :func:`malloc`. For documentation, read the comments in +standard :c:func:`malloc`. For documentation, read the comments in :file:`Include/pymem.h` and :file:`Include/objimpl.h`. For the lengthy discussions during which the interface was hammered out, see the web archives of the 'patches' and 'python-dev' lists at python.org. @@ -794,15 +794,15 @@ are generating Python code would run into this limit. A patch by Charles G. Waldman raises the limit from ``2**16`` to ``2**32``. Three new convenience functions intended for adding constants to a module's -dictionary at module initialization time were added: :func:`PyModule_AddObject`, -:func:`PyModule_AddIntConstant`, and :func:`PyModule_AddStringConstant`. Each +dictionary at module initialization time were added: :c:func:`PyModule_AddObject`, +:c:func:`PyModule_AddIntConstant`, and :c:func:`PyModule_AddStringConstant`. Each of these functions takes a module object, a null-terminated C string containing the name to be added, and a third argument for the value to be assigned to the name. This third argument is, respectively, a Python object, a C long, or a C string. -A wrapper API was added for Unix-style signal handlers. :func:`PyOS_getsig` gets -a signal handler and :func:`PyOS_setsig` will set a new handler. +A wrapper API was added for Unix-style signal handlers. :c:func:`PyOS_getsig` gets +a signal handler and :c:func:`PyOS_setsig` will set a new handler. .. ====================================================================== @@ -820,7 +820,7 @@ packages, which made administering a Python installation something of a chore. The SIG for distribution utilities, shepherded by Greg Ward, has created the Distutils, a system to make package installation much easier. They form the -:mod:`distutils` package, a new part of Python's standard library. In the best +``distutils`` package, a new part of Python's standard library. In the best case, installing a Python module from source will require the same steps: first you simply mean unpack the tarball or zip archive, and the run "``python setup.py install``". The platform will be automatically detected, the compiler @@ -933,7 +933,7 @@ using it:: parser.parse( 'hamlet.xml' ) For more information, consult the Python documentation, or the XML HOWTO at -http://pyxml.sourceforge.net/topics/howto/xml-howto.html. +https://pyxml.sourceforge.net/topics/howto/xml-howto.html. DOM Support diff --git a/Doc/whatsnew/2.1.rst b/Doc/whatsnew/2.1.rst index 0136de58..f0e1ded7 100644 --- a/Doc/whatsnew/2.1.rst +++ b/Doc/whatsnew/2.1.rst @@ -613,7 +613,7 @@ New and Improved Modules framework based on running embedded examples in docstrings and comparing the results against the expected output. PyUnit, contributed by Steve Purcell, is a unit testing framework inspired by JUnit, which was in turn an adaptation of - Kent Beck's Smalltalk testing framework. See http://pyunit.sourceforge.net/ for + Kent Beck's Smalltalk testing framework. See https://pyunit.sourceforge.net/ for more information about PyUnit. * The :mod:`difflib` module contains a class, :class:`SequenceMatcher`, which @@ -692,8 +692,8 @@ applied, and 136 bugs fixed; both figures are likely to be underestimates. Some of the more notable changes are: * A specialized object allocator is now optionally available, that should be - faster than the system :func:`malloc` and have less memory overhead. The - allocator uses C's :func:`malloc` function to get large pools of memory, and + faster than the system :c:func:`malloc` and have less memory overhead. The + allocator uses C's :c:func:`!malloc` function to get large pools of memory, and then fulfills smaller memory requests from these pools. It can be enabled by providing the :option:`!--with-pymalloc` option to the :program:`configure` script; see :file:`Objects/obmalloc.c` for the implementation details. @@ -701,13 +701,13 @@ of the more notable changes are: Authors of C extension modules should test their code with the object allocator enabled, because some incorrect code may break, causing core dumps at runtime. There are a bunch of memory allocation functions in Python's C API that have - previously been just aliases for the C library's :func:`malloc` and - :func:`free`, meaning that if you accidentally called mismatched functions, the + previously been just aliases for the C library's :c:func:`malloc` and + :c:func:`free`, meaning that if you accidentally called mismatched functions, the error wouldn't be noticeable. When the object allocator is enabled, these - functions aren't aliases of :func:`malloc` and :func:`free` any more, and + functions aren't aliases of :c:func:`!malloc` and :c:func:`!free` any more, and calling the wrong function to free memory will get you a core dump. For - example, if memory was allocated using :func:`PyMem_New`, it has to be freed - using :func:`PyMem_Del`, not :func:`free`. A few modules included with Python + example, if memory was allocated using :c:macro:`PyMem_New`, it has to be freed + using :c:func:`PyMem_Del`, not :c:func:`!free`. A few modules included with Python fell afoul of this and had to be fixed; doubtless there are more third-party modules that will have the same problem. @@ -717,7 +717,7 @@ of the more notable changes are: complain about its lack of speed, and because it's often been used as a naïve benchmark. The :meth:`readline` method of file objects has therefore been rewritten to be much faster. The exact amount of the speedup will vary from - platform to platform depending on how slow the C library's :func:`getc` was, but + platform to platform depending on how slow the C library's :c:func:`!getc` was, but is around 66%, and potentially much faster on some particular operating systems. Tim Peters did much of the benchmarking and coding for this change, motivated by a discussion in comp.lang.python. @@ -770,7 +770,7 @@ of the more notable changes are: reorganization done by Jeremy Hylton. * C extensions which import other modules have been changed to use - :func:`PyImport_ImportModule`, which means that they will use any import hooks + :c:func:`PyImport_ImportModule`, which means that they will use any import hooks that have been installed. This is also encouraged for third-party extensions that need to import some other module from C code. diff --git a/Doc/whatsnew/2.2.rst b/Doc/whatsnew/2.2.rst index 0c3bfda1..d9ead574 100644 --- a/Doc/whatsnew/2.2.rst +++ b/Doc/whatsnew/2.2.rst @@ -632,10 +632,10 @@ queen threatens another) and the Knight's Tour (a route that takes a knight to every square of an $NxN$ chessboard without visiting any square twice). The idea of generators comes from other programming languages, especially Icon -(https://www.cs.arizona.edu/icon/), where the idea of generators is central. In +(https://www2.cs.arizona.edu/icon/), where the idea of generators is central. In Icon, every expression and function call behaves like a generator. One example from "An Overview of the Icon Programming Language" at -https://www.cs.arizona.edu/icon/docs/ipd266.htm gives an idea of what this looks +https://www2.cs.arizona.edu/icon/docs/ipd266.htm gives an idea of what this looks like:: sentence := "Store it in the neighboring harbor" @@ -1078,17 +1078,17 @@ code, none of the changes described here will affect you very much. To upgrade an extension module to the new API, perform the following steps: -* Rename :c:func:`Py_TPFLAGS_GC` to :c:func:`PyTPFLAGS_HAVE_GC`. +* Rename :c:macro:`!Py_TPFLAGS_GC` to :c:macro:`Py_TPFLAGS_HAVE_GC`. * Use :c:func:`PyObject_GC_New` or :c:func:`PyObject_GC_NewVar` to allocate objects, and :c:func:`PyObject_GC_Del` to deallocate them. -* Rename :c:func:`PyObject_GC_Init` to :c:func:`PyObject_GC_Track` and - :c:func:`PyObject_GC_Fini` to :c:func:`PyObject_GC_UnTrack`. +* Rename :c:func:`!PyObject_GC_Init` to :c:func:`PyObject_GC_Track` and + :c:func:`!PyObject_GC_Fini` to :c:func:`PyObject_GC_UnTrack`. -* Remove :c:func:`PyGC_HEAD_SIZE` from object size calculations. +* Remove :c:macro:`!PyGC_HEAD_SIZE` from object size calculations. -* Remove calls to :c:func:`PyObject_AS_GC` and :c:func:`PyObject_FROM_GC`. +* Remove calls to :c:func:`!PyObject_AS_GC` and :c:func:`!PyObject_FROM_GC`. * A new ``et`` format sequence was added to :c:func:`PyArg_ParseTuple`; ``et`` takes both a parameter and an encoding name, and converts the parameter to the @@ -1105,11 +1105,11 @@ code, none of the changes described here will affect you very much. expected, and a set of pointers to :c:expr:`PyObject*` variables that will be filled in with argument values. -* Two new flags :const:`METH_NOARGS` and :const:`METH_O` are available in method +* Two new flags :c:macro:`METH_NOARGS` and :c:macro:`METH_O` are available in method definition tables to simplify implementation of methods with no arguments or a single untyped argument. Calling such methods is more efficient than calling a - corresponding method that uses :const:`METH_VARARGS`. Also, the old - :const:`METH_OLDARGS` style of writing C methods is now officially deprecated. + corresponding method that uses :c:macro:`METH_VARARGS`. Also, the old + :c:macro:`!METH_OLDARGS` style of writing C methods is now officially deprecated. * Two new wrapper functions, :c:func:`PyOS_snprintf` and :c:func:`PyOS_vsnprintf` were added to provide cross-platform implementations for the relatively new @@ -1219,7 +1219,7 @@ Some of the more notable changes are: operator, but these features were rarely used and therefore buggy. The :meth:`tolist` method and the :attr:`start`, :attr:`stop`, and :attr:`step` attributes are also being deprecated. At the C level, the fourth argument to - the :c:func:`PyRange_New` function, ``repeat``, has also been deprecated. + the :c:func:`!PyRange_New` function, ``repeat``, has also been deprecated. * There were a bunch of patches to the dictionary implementation, mostly to fix potential core dumps if a dictionary contains objects that sneakily changed diff --git a/Doc/whatsnew/2.3.rst b/Doc/whatsnew/2.3.rst index c6e2003e..0442c9fd 100644 --- a/Doc/whatsnew/2.3.rst +++ b/Doc/whatsnew/2.3.rst @@ -218,10 +218,10 @@ queen threatens another) and the Knight's Tour (a route that takes a knight to every square of an $NxN$ chessboard without visiting any square twice). The idea of generators comes from other programming languages, especially Icon -(https://www.cs.arizona.edu/icon/), where the idea of generators is central. In +(https://www2.cs.arizona.edu/icon/), where the idea of generators is central. In Icon, every expression and function call behaves like a generator. One example from "An Overview of the Icon Programming Language" at -https://www.cs.arizona.edu/icon/docs/ipd266.htm gives an idea of what this looks +https://www2.cs.arizona.edu/icon/docs/ipd266.htm gives an idea of what this looks like:: sentence := "Store it in the neighboring harbor" @@ -728,7 +728,7 @@ module: Importer objects must have a single method, ``find_module(fullname, path=None)``. *fullname* will be a module or package name, e.g. ``string`` or -``distutils.core``. :meth:`find_module` must return a loader object that has a +``distutils.core``. :meth:`!find_module` must return a loader object that has a single method, ``load_module(fullname)``, that creates and returns the corresponding module object. @@ -1332,7 +1332,7 @@ complete list of changes, or look through the CVS logs for all the details. (Contributed by Kevin O'Connor.) * The IDLE integrated development environment has been updated using the code - from the IDLEfork project (http://idlefork.sourceforge.net). The most notable feature is + from the IDLEfork project (https://idlefork.sourceforge.net). The most notable feature is that the code being developed is now executed in a subprocess, meaning that there's no longer any need for manual ``reload()`` operations. IDLE's core code has been incorporated into the standard library as the :mod:`idlelib` package. @@ -1474,7 +1474,7 @@ complete list of changes, or look through the CVS logs for all the details. * On Windows, the :mod:`socket` module now ships with Secure Sockets Layer (SSL) support. -* The value of the C :const:`PYTHON_API_VERSION` macro is now exposed at the +* The value of the C :c:macro:`PYTHON_API_VERSION` macro is now exposed at the Python level as ``sys.api_version``. The current exception can be cleared by calling the new :func:`sys.exc_clear` function. @@ -1847,7 +1847,7 @@ specifically for allocating Python objects. :c:func:`PyObject_Malloc`, :c:func:`PyObject_Realloc`, and :c:func:`PyObject_Free`. * To allocate and free Python objects, use the "object" family - :c:func:`PyObject_New`, :c:func:`PyObject_NewVar`, and :c:func:`PyObject_Del`. + :c:macro:`PyObject_New`, :c:macro:`PyObject_NewVar`, and :c:func:`PyObject_Del`. Thanks to lots of work by Tim Peters, pymalloc in 2.3 also provides debugging features to catch memory overwrites and doubled frees in both extension modules @@ -1886,10 +1886,10 @@ Changes to Python's build process and to the C API include: (:file:`libpython2.3.so`) by supplying :option:`!--enable-shared` when running Python's :program:`configure` script. (Contributed by Ondrej Palkovsky.) -* The :c:macro:`DL_EXPORT` and :c:macro:`DL_IMPORT` macros are now deprecated. +* The :c:macro:`!DL_EXPORT` and :c:macro:`!DL_IMPORT` macros are now deprecated. Initialization functions for Python extension modules should now be declared using the new macro :c:macro:`PyMODINIT_FUNC`, while the Python core will - generally use the :c:macro:`PyAPI_FUNC` and :c:macro:`PyAPI_DATA` macros. + generally use the :c:macro:`!PyAPI_FUNC` and :c:macro:`!PyAPI_DATA` macros. * The interpreter can be compiled without any docstrings for the built-in functions and modules by supplying :option:`!--without-doc-strings` to the @@ -1897,12 +1897,12 @@ Changes to Python's build process and to the C API include: but will also mean that you can't get help for Python's built-ins. (Contributed by Gustavo Niemeyer.) -* The :c:func:`PyArg_NoArgs` macro is now deprecated, and code that uses it +* The :c:func:`!PyArg_NoArgs` macro is now deprecated, and code that uses it should be changed. For Python 2.2 and later, the method definition table can - specify the :const:`METH_NOARGS` flag, signalling that there are no arguments, + specify the :c:macro:`METH_NOARGS` flag, signalling that there are no arguments, and the argument checking can then be removed. If compatibility with pre-2.2 versions of Python is important, the code could use ``PyArg_ParseTuple(args, - "")`` instead, but this will be slower than using :const:`METH_NOARGS`. + "")`` instead, but this will be slower than using :c:macro:`METH_NOARGS`. * :c:func:`PyArg_ParseTuple` accepts new format characters for various sizes of unsigned integers: ``B`` for :c:expr:`unsigned char`, ``H`` for :c:expr:`unsigned @@ -1918,7 +1918,7 @@ Changes to Python's build process and to the C API include: seconds, according to one measurement). * It's now possible to define class and static methods for a C extension type by - setting either the :const:`METH_CLASS` or :const:`METH_STATIC` flags in a + setting either the :c:macro:`METH_CLASS` or :c:macro:`METH_STATIC` flags in a method's :c:type:`PyMethodDef` structure. * Python now includes a copy of the Expat XML parser's source code, removing any diff --git a/Doc/whatsnew/2.4.rst b/Doc/whatsnew/2.4.rst index 63e81987..ceda03af 100644 --- a/Doc/whatsnew/2.4.rst +++ b/Doc/whatsnew/2.4.rst @@ -756,7 +756,7 @@ API that perform ASCII-only conversions, ignoring the locale setting: :c:expr:`double` to an ASCII string. The code for these functions came from the GLib library -(https://developer.gnome.org/glib/stable/), whose developers kindly +(https://developer-old.gnome.org/glib/2.26/), whose developers kindly relicensed the relevant functions and donated them to the Python Software Foundation. The :mod:`locale` module can now change the numeric locale, letting extensions such as GTK+ produce the correct results. @@ -1468,7 +1468,7 @@ Some of the changes to Python's build process and to the C API are: *X* is a NaN. (Contributed by Tim Peters.) * C code can avoid unnecessary locking by using the new - :c:func:`PyEval_ThreadsInitialized` function to tell if any thread operations + :c:func:`!PyEval_ThreadsInitialized` function to tell if any thread operations have been performed. If this function returns false, no lock operations are needed. (Contributed by Nick Coghlan.) @@ -1476,7 +1476,7 @@ Some of the changes to Python's build process and to the C API are: :c:func:`PyArg_ParseTupleAndKeywords` but takes a :c:type:`va_list` instead of a number of arguments. (Contributed by Greg Chapman.) -* A new method flag, :const:`METH_COEXISTS`, allows a function defined in slots +* A new method flag, :c:macro:`METH_COEXIST`, allows a function defined in slots to co-exist with a :c:type:`PyCFunction` having the same name. This can halve the access time for a method such as :meth:`set.__contains__`. (Contributed by Raymond Hettinger.) @@ -1491,7 +1491,7 @@ Some of the changes to Python's build process and to the C API are: though that processor architecture doesn't call that register "the TSC register". (Contributed by Jeremy Hylton.) -* The :c:type:`tracebackobject` type has been renamed to +* The :c:type:`!tracebackobject` type has been renamed to :c:type:`PyTracebackObject`. .. ====================================================================== diff --git a/Doc/whatsnew/2.5.rst b/Doc/whatsnew/2.5.rst index dcfaef6e..f58b3ede 100644 --- a/Doc/whatsnew/2.5.rst +++ b/Doc/whatsnew/2.5.rst @@ -954,7 +954,7 @@ The return value must be either a Python integer or long integer. The interpreter will check that the type returned is correct, and raises a :exc:`TypeError` if this requirement isn't met. -A corresponding :attr:`nb_index` slot was added to the C-level +A corresponding :c:member:`~PyNumberMethods.nb_index` slot was added to the C-level :c:type:`PyNumberMethods` structure to let C extensions implement this protocol. ``PyNumber_Index(obj)`` can be used in extension code to call the :meth:`__index__` function and retrieve its result. @@ -1448,10 +1448,10 @@ complete list of changes, or look through the SVN logs for all the details. return times that are precise to fractions of a second; not all systems support such precision.) - Constants named :attr:`os.SEEK_SET`, :attr:`os.SEEK_CUR`, and - :attr:`os.SEEK_END` have been added; these are the parameters to the + Constants named :const:`os.SEEK_SET`, :const:`os.SEEK_CUR`, and + :const:`os.SEEK_END` have been added; these are the parameters to the :func:`os.lseek` function. Two new constants for locking are - :attr:`os.O_SHLOCK` and :attr:`os.O_EXLOCK`. + :const:`os.O_SHLOCK` and :const:`os.O_EXLOCK`. Two new functions, :func:`wait3` and :func:`wait4`, were added. They're similar the :func:`waitpid` function which waits for a child process to exit and returns @@ -1602,7 +1602,7 @@ complete list of changes, or look through the SVN logs for all the details. * The :mod:`unicodedata` module has been updated to use version 4.1.0 of the Unicode character database. Version 3.2.0 is required by some specifications, - so it's still available as :attr:`unicodedata.ucd_3_2_0`. + so it's still available as :data:`unicodedata.ucd_3_2_0`. * New module: the :mod:`uuid` module generates universally unique identifiers (UUIDs) according to :rfc:`4122`. The RFC defines several different UUID @@ -2119,9 +2119,9 @@ Changes to Python's build process and to the C API include: the various AST nodes in :file:`Parser/Python.asdl`. A Python script reads this file and generates a set of C structure definitions in :file:`Include/Python-ast.h`. The :c:func:`PyParser_ASTFromString` and - :c:func:`PyParser_ASTFromFile`, defined in :file:`Include/pythonrun.h`, take + :c:func:`!PyParser_ASTFromFile`, defined in :file:`Include/pythonrun.h`, take Python source as input and return the root of an AST representing the contents. - This AST can then be turned into a code object by :c:func:`PyAST_Compile`. For + This AST can then be turned into a code object by :c:func:`!PyAST_Compile`. For more information, read the source code, and then ask questions on python-dev. The AST code was developed under Jeremy Hylton's management, and implemented by @@ -2151,8 +2151,8 @@ Changes to Python's build process and to the C API include: Previously these different families all reduced to the platform's :c:func:`malloc` and :c:func:`free` functions. This meant it didn't matter if - you got things wrong and allocated memory with the :c:func:`PyMem` function but - freed it with the :c:func:`PyObject` function. With 2.5's changes to obmalloc, + you got things wrong and allocated memory with the ``PyMem`` function but + freed it with the ``PyObject`` function. With 2.5's changes to obmalloc, these families now do different things and mismatches will probably result in a segfault. You should carefully test your C extension modules with Python 2.5. @@ -2172,7 +2172,7 @@ Changes to Python's build process and to the C API include: ``Py_LOCAL(type)`` declares the function as returning a value of the specified *type* and uses a fast-calling qualifier. ``Py_LOCAL_INLINE(type)`` does the same thing and also requests the - function be inlined. If :c:func:`PY_LOCAL_AGGRESSIVE` is defined before + function be inlined. If macro :c:macro:`!PY_LOCAL_AGGRESSIVE` is defined before :file:`python.h` is included, a set of more aggressive optimizations are enabled for the module; you should benchmark the results to find out if these optimizations actually make the code faster. (Contributed by Fredrik Lundh at @@ -2181,7 +2181,7 @@ Changes to Python's build process and to the C API include: * ``PyErr_NewException(name, base, dict)`` can now accept a tuple of base classes as its *base* argument. (Contributed by Georg Brandl.) -* The :c:func:`PyErr_Warn` function for issuing warnings is now deprecated in +* The :c:func:`!PyErr_Warn` function for issuing warnings is now deprecated in favour of ``PyErr_WarnEx(category, message, stacklevel)`` which lets you specify the number of stack frames separating this function and the caller. A *stacklevel* of 1 is the function calling :c:func:`PyErr_WarnEx`, 2 is the @@ -2191,7 +2191,7 @@ Changes to Python's build process and to the C API include: compiled with a C++ compiler without errors. (Implemented by Anthony Baxter, Martin von Löwis, Skip Montanaro.) -* The :c:func:`PyRange_New` function was removed. It was never documented, never +* The :c:func:`!PyRange_New` function was removed. It was never documented, never used in the core code, and had dangerously lax error checking. In the unlikely case that your extensions were using it, you can replace it by something like the following:: diff --git a/Doc/whatsnew/2.6.rst b/Doc/whatsnew/2.6.rst index 34f2656f..96d9b792 100644 --- a/Doc/whatsnew/2.6.rst +++ b/Doc/whatsnew/2.6.rst @@ -125,7 +125,7 @@ and to C extension code as :c:data:`Py_Py3kWarningFlag`. .. seealso:: - The 3xxx series of PEPs, which contains proposals for Python 3.0. + The 3\ *xxx* series of PEPs, which contains proposals for Python 3.0. :pep:`3000` describes the development process for Python 3.0. Start with :pep:`3100` that describes the general goals for Python 3.0, and then explore the higher-numbered PEPS that propose @@ -172,7 +172,7 @@ this edition of "What's New in Python" links to the bug/patch item for each change. Hosting of the Python bug tracker is kindly provided by -`Upfront Systems <http://www.upfrontsoftware.co.za>`__ +`Upfront Systems <https://upfrontsoftware.co.za>`__ of Stellenbosch, South Africa. Martin von Löwis put a lot of effort into importing existing bugs and patches from SourceForge; his scripts for this import operation are at @@ -977,7 +977,7 @@ can be used to include Unicode characters:: print len(s) # 12 Unicode characters At the C level, Python 3.0 will rename the existing 8-bit -string type, called :c:type:`PyStringObject` in Python 2.x, +string type, called :c:type:`!PyStringObject` in Python 2.x, to :c:type:`PyBytesObject`. Python 2.6 uses ``#define`` to support using the names :c:func:`PyBytesObject`, :c:func:`PyBytes_Check`, :c:func:`PyBytes_FromStringAndSize`, @@ -1138,11 +1138,11 @@ indicate that the external caller is done. The *flags* argument to :c:func:`PyObject_GetBuffer` specifies constraints upon the memory returned. Some examples are: - * :const:`PyBUF_WRITABLE` indicates that the memory must be writable. + * :c:macro:`PyBUF_WRITABLE` indicates that the memory must be writable. - * :const:`PyBUF_LOCK` requests a read-only or exclusive lock on the memory. + * :c:macro:`PyBUF_LOCK` requests a read-only or exclusive lock on the memory. - * :const:`PyBUF_C_CONTIGUOUS` and :const:`PyBUF_F_CONTIGUOUS` + * :c:macro:`PyBUF_C_CONTIGUOUS` and :c:macro:`PyBUF_F_CONTIGUOUS` requests a C-contiguous (last dimension varies the fastest) or Fortran-contiguous (first dimension varies the fastest) array layout. @@ -1433,7 +1433,7 @@ one, :func:`math.trunc`, that's been backported to Python 2.6. `Scheme's numerical tower <https://www.gnu.org/software/guile/manual/html_node/Numerical-Tower.html#Numerical-Tower>`__, from the Guile manual. - `Scheme's number datatypes <https://schemers.org/Documents/Standards/R5RS/HTML/r5rs-Z-H-9.html#%_sec_6.2>`__ from the R5RS Scheme specification. + `Scheme's number datatypes <https://conservatory.scheme.org/schemers/Documents/Standards/R5RS/HTML/r5rs-Z-H-9.html#%_sec_6.2>`__ from the R5RS Scheme specification. The :mod:`fractions` Module @@ -1850,8 +1850,8 @@ changes, or look through the Subversion logs for all the details. special values and floating-point exceptions in a manner consistent with Annex 'G' of the C99 standard. -* A new data type in the :mod:`collections` module: :class:`namedtuple(typename, - fieldnames)` is a factory function that creates subclasses of the standard tuple +* A new data type in the :mod:`collections` module: ``namedtuple(typename, fieldnames)`` + is a factory function that creates subclasses of the standard tuple whose fields are accessible by name as well as index. For example:: >>> var_type = collections.namedtuple('variable', @@ -1873,7 +1873,7 @@ changes, or look through the Subversion logs for all the details. variable(id=1, name='amplitude', type='int', size=4) Several places in the standard library that returned tuples have - been modified to return :class:`namedtuple` instances. For example, + been modified to return :func:`namedtuple` instances. For example, the :meth:`Decimal.as_tuple` method now returns a named tuple with :attr:`sign`, :attr:`digits`, and :attr:`exponent` fields. @@ -2289,7 +2289,7 @@ changes, or look through the Subversion logs for all the details. (Contributed by Raymond Hettinger; :issue:`1861`.) * The :mod:`select` module now has wrapper functions - for the Linux :c:func:`epoll` and BSD :c:func:`kqueue` system calls. + for the Linux :c:func:`!epoll` and BSD :c:func:`!kqueue` system calls. :meth:`modify` method was added to the existing :class:`poll` objects; ``pollobj.modify(fd, eventmask)`` takes a file descriptor or file object and an event mask, modifying the recorded event mask @@ -2328,7 +2328,7 @@ changes, or look through the Subversion logs for all the details. one for reading and one for writing. The writable descriptor will be passed to :func:`set_wakeup_fd`, and the readable descriptor will be added to the list of descriptors monitored by the event loop via - :c:func:`select` or :c:func:`poll`. + :c:func:`!select` or :c:func:`!poll`. On receiving a signal, a byte will be written and the main event loop will be woken up, avoiding the need to poll. @@ -2363,7 +2363,7 @@ changes, or look through the Subversion logs for all the details. negotiation itself. (Patch contributed by Bill Fenner; :issue:`829951`.) -* The :mod:`socket` module now supports TIPC (http://tipc.sourceforge.net/), +* The :mod:`socket` module now supports TIPC (https://tipc.sourceforge.net/), a high-performance non-IP-based protocol designed for use in clustered environments. TIPC addresses are 4- or 5-tuples. (Contributed by Alberto Bertogli; :issue:`1646`.) @@ -2982,7 +2982,7 @@ Changes to Python's build process and to the C API include: * Python now must be compiled with C89 compilers (after 19 years!). This means that the Python source tree has dropped its - own implementations of :c:func:`memmove` and :c:func:`strerror`, which + own implementations of :c:func:`!memmove` and :c:func:`!strerror`, which are in the C89 standard library. * Python 2.6 can be built with Microsoft Visual Studio 2008 (version @@ -3012,11 +3012,11 @@ Changes to Python's build process and to the C API include: bug occurred if one thread closed a file object while another thread was reading from or writing to the object. In 2.6 file objects have a reference count, manipulated by the - :c:func:`PyFile_IncUseCount` and :c:func:`PyFile_DecUseCount` + :c:func:`!PyFile_IncUseCount` and :c:func:`!PyFile_DecUseCount` functions. File objects can't be closed unless the reference count - is zero. :c:func:`PyFile_IncUseCount` should be called while the GIL + is zero. :c:func:`!PyFile_IncUseCount` should be called while the GIL is still held, before carrying out an I/O operation using the - ``FILE *`` pointer, and :c:func:`PyFile_DecUseCount` should be called + ``FILE *`` pointer, and :c:func:`!PyFile_DecUseCount` should be called immediately after the GIL is re-acquired. (Contributed by Antoine Pitrou and Gregory P. Smith.) @@ -3060,9 +3060,9 @@ Changes to Python's build process and to the C API include: * Some macros were renamed in both 3.0 and 2.6 to make it clearer that they are macros, - not functions. :c:macro:`Py_Size()` became :c:macro:`Py_SIZE()`, - :c:macro:`Py_Type()` became :c:macro:`Py_TYPE()`, and - :c:macro:`Py_Refcnt()` became :c:macro:`Py_REFCNT()`. + not functions. :c:macro:`!Py_Size()` became :c:macro:`Py_SIZE()`, + :c:macro:`!Py_Type()` became :c:macro:`Py_TYPE()`, and + :c:macro:`!Py_Refcnt()` became :c:macro:`Py_REFCNT()`. The mixed-case macros are still available in Python 2.6 for backward compatibility. (:issue:`1629`) diff --git a/Doc/whatsnew/2.7.rst b/Doc/whatsnew/2.7.rst index 82f5ea3b..eda6c8be 100644 --- a/Doc/whatsnew/2.7.rst +++ b/Doc/whatsnew/2.7.rst @@ -355,7 +355,7 @@ added as a more powerful replacement for the This means Python now supports three different modules for parsing command-line arguments: :mod:`getopt`, :mod:`optparse`, and :mod:`argparse`. The :mod:`getopt` module closely resembles the C -library's :c:func:`getopt` function, so it remains useful if you're writing a +library's :c:func:`!getopt` function, so it remains useful if you're writing a Python prototype that will eventually be rewritten in C. :mod:`optparse` becomes redundant, but there are no plans to remove it because there are many scripts still using it, and there's no @@ -1331,6 +1331,7 @@ changes, or look through the Subversion logs for all the details. >>> from inspect import getcallargs >>> def f(a, b=1, *pos, **named): ... pass + ... >>> getcallargs(f, 1, 2, 3) {'a': 1, 'b': 2, 'pos': (3,), 'named': {}} >>> getcallargs(f, a=2, x=4) @@ -1555,9 +1556,9 @@ changes, or look through the Subversion logs for all the details. :issue:`8484`.) The version of OpenSSL being used is now available as the module - attributes :data:`ssl.OPENSSL_VERSION` (a string), - :data:`ssl.OPENSSL_VERSION_INFO` (a 5-tuple), and - :data:`ssl.OPENSSL_VERSION_NUMBER` (an integer). (Added by Antoine + attributes :const:`ssl.OPENSSL_VERSION` (a string), + :const:`ssl.OPENSSL_VERSION_INFO` (a 5-tuple), and + :const:`ssl.OPENSSL_VERSION_NUMBER` (an integer). (Added by Antoine Pitrou; :issue:`8321`.) * The :mod:`struct` module will no longer silently ignore overflow @@ -2103,7 +2104,7 @@ Changes to Python's build process and to the C API include: * The latest release of the GNU Debugger, GDB 7, can be `scripted using Python - <https://sourceware.org/gdb/current/onlinedocs/gdb/Python.html>`__. + <https://web.archive.org/web/20110715084810/http://sourceware.org/gdb/current/onlinedocs/gdb/Python.html>`__. When you begin debugging an executable program P, GDB will look for a file named ``P-gdb.py`` and automatically read it. Dave Malcolm contributed a :file:`python-gdb.py` that adds a number of @@ -2151,7 +2152,7 @@ Changes to Python's build process and to the C API include: * New function: stemming from the rewrite of string-to-float conversion, a new :c:func:`PyOS_string_to_double` function was added. The old - :c:func:`PyOS_ascii_strtod` and :c:func:`PyOS_ascii_atof` functions + :c:func:`!PyOS_ascii_strtod` and :c:func:`!PyOS_ascii_atof` functions are now deprecated. * New function: :c:func:`PySys_SetArgvEx` sets the value of @@ -2194,13 +2195,13 @@ Changes to Python's build process and to the C API include: .. XXX these macros don't seem to be described in the c-api docs. -* Removed function: :c:macro:`PyEval_CallObject` is now only available +* Removed function: :c:func:`!PyEval_CallObject` is now only available as a macro. A function version was being kept around to preserve ABI linking compatibility, but that was in 1997; it can certainly be deleted by now. (Removed by Antoine Pitrou; :issue:`8276`.) -* New format codes: the :c:func:`PyFormat_FromString`, - :c:func:`PyFormat_FromStringV`, and :c:func:`PyErr_Format` functions now +* New format codes: the :c:func:`!PyString_FromFormat`, + :c:func:`!PyString_FromFormatV`, and :c:func:`PyErr_Format` functions now accept ``%lld`` and ``%llu`` format codes for displaying C's :c:expr:`long long` types. (Contributed by Mark Dickinson; :issue:`7228`.) @@ -2230,7 +2231,7 @@ Changes to Python's build process and to the C API include: * When using the :c:type:`PyMemberDef` structure to define attributes of a type, Python will no longer let you try to delete or set a - :const:`T_STRING_INPLACE` attribute. + :c:macro:`T_STRING_INPLACE` attribute. .. rev 79644 @@ -2286,10 +2287,10 @@ object, and then get the ``void *`` pointer, which will usually point to an array of pointers to the module's various API functions. There is an existing data type already used for this, -:c:type:`PyCObject`, but it doesn't provide type safety. Evil code +:c:type:`!PyCObject`, but it doesn't provide type safety. Evil code written in pure Python could cause a segmentation fault by taking a -:c:type:`PyCObject` from module A and somehow substituting it for the -:c:type:`PyCObject` in module B. Capsules know their own name, +:c:type:`!PyCObject` from module A and somehow substituting it for the +:c:type:`!PyCObject` in module B. Capsules know their own name, and getting the pointer requires providing the name: .. code-block:: c @@ -2309,10 +2310,10 @@ detect the mismatched name and return false. Refer to :ref:`using-capsules` for more information on using these objects. Python 2.7 now uses capsules internally to provide various -extension-module APIs, but the :c:func:`PyCObject_AsVoidPtr` was +extension-module APIs, but the :c:func:`!PyCObject_AsVoidPtr` was modified to handle capsules, preserving compile-time compatibility -with the :c:type:`CObject` interface. Use of -:c:func:`PyCObject_AsVoidPtr` will signal a +with the :c:type:`!PyCObject` interface. Use of +:c:func:`!PyCObject_AsVoidPtr` will signal a :exc:`PendingDeprecationWarning`, which is silent by default. Implemented in Python 3.1 and backported to 2.7 by Larry Hastings; @@ -2539,7 +2540,7 @@ For C extensions: instead of triggering a :exc:`DeprecationWarning` (:issue:`5080`). * Use the new :c:func:`PyOS_string_to_double` function instead of the old - :c:func:`PyOS_ascii_strtod` and :c:func:`PyOS_ascii_atof` functions, + :c:func:`!PyOS_ascii_strtod` and :c:func:`!PyOS_ascii_atof` functions, which are now deprecated. For applications that embed Python: @@ -2697,7 +2698,7 @@ projects. However, as this migration is currently still incomplete, the legacy versions of those guides remaining available as :ref:`install-index` -and :ref:`distutils-index`. +and :ref:`setuptools-index`. .. seealso:: diff --git a/Doc/whatsnew/3.0.rst b/Doc/whatsnew/3.0.rst index 63b24748..4bd53fb1 100644 --- a/Doc/whatsnew/3.0.rst +++ b/Doc/whatsnew/3.0.rst @@ -789,7 +789,7 @@ Operators And Special Methods :attr:`__doc__`, :attr:`__globals__`, :attr:`~definition.__name__`, respectively. -* :meth:`__nonzero__` is now :meth:`__bool__`. +* :meth:`!__nonzero__` is now :meth:`~object.__bool__`. Builtins -------- @@ -840,7 +840,7 @@ Builtins need it; however, 99 percent of the time an explicit :keyword:`for` loop is more readable. -* Removed :func:`reload`. Use :func:`imp.reload`. +* Removed :func:`reload`. Use :func:`!imp.reload`. * Removed. :meth:`dict.has_key` -- use the :keyword:`in` operator instead. @@ -865,8 +865,8 @@ to the C API. * No more C API support for restricted execution. -* :c:func:`PyNumber_Coerce`, :c:func:`PyNumber_CoerceEx`, - :c:func:`PyMember_Get`, and :c:func:`PyMember_Set` C APIs are removed. +* :c:func:`!PyNumber_Coerce`, :c:func:`!PyNumber_CoerceEx`, + :c:func:`!PyMember_Get`, and :c:func:`!PyMember_Set` C APIs are removed. * New C API :c:func:`PyImport_ImportModuleNoBlock`, works like :c:func:`PyImport_ImportModule` but won't block on the import lock @@ -875,7 +875,7 @@ to the C API. * Renamed the boolean conversion C-level slot and method: ``nb_nonzero`` is now ``nb_bool``. -* Removed :c:macro:`METH_OLDARGS` and :c:macro:`WITH_CYCLE_GC` from the C API. +* Removed :c:macro:`!METH_OLDARGS` and :c:macro:`!WITH_CYCLE_GC` from the C API. .. ====================================================================== diff --git a/Doc/whatsnew/3.1.rst b/Doc/whatsnew/3.1.rst index fba8816b..cc6619c5 100644 --- a/Doc/whatsnew/3.1.rst +++ b/Doc/whatsnew/3.1.rst @@ -370,7 +370,7 @@ New, Improved, and Deprecated Modules * The :mod:`io` module has three new constants for the :meth:`seek` method :data:`SEEK_SET`, :data:`SEEK_CUR`, and :data:`SEEK_END`. -* The :attr:`sys.version_info` tuple is now a named tuple:: +* The :data:`sys.version_info` tuple is now a named tuple:: >>> sys.version_info sys.version_info(major=3, minor=1, micro=0, releaselevel='alpha', serial=2) @@ -486,7 +486,7 @@ Changes to Python's build process and to the C API include: Apart from the performance improvements this change should be invisible to end users, with one exception: for testing and debugging purposes there's a - new :attr:`sys.int_info` that provides information about the + new :data:`sys.int_info` that provides information about the internal format, giving the number of bits per digit and the size in bytes of the C type used to store each digit:: @@ -501,16 +501,16 @@ Changes to Python's build process and to the C API include: (Contributed by Mark Dickinson and Lisandro Dalcrin; :issue:`5175`.) -* Deprecated :c:func:`PyNumber_Int`. Use :c:func:`PyNumber_Long` instead. +* Deprecated :c:func:`!PyNumber_Int`. Use :c:func:`PyNumber_Long` instead. (Contributed by Mark Dickinson; :issue:`4910`.) * Added a new :c:func:`PyOS_string_to_double` function to replace the - deprecated functions :c:func:`PyOS_ascii_strtod` and :c:func:`PyOS_ascii_atof`. + deprecated functions :c:func:`!PyOS_ascii_strtod` and :c:func:`!PyOS_ascii_atof`. (Contributed by Mark Dickinson; :issue:`5914`.) -* Added :c:type:`PyCapsule` as a replacement for the :c:type:`PyCObject` API. +* Added :c:type:`PyCapsule` as a replacement for the :c:type:`!PyCObject` API. The principal difference is that the new type has a well defined interface for passing typing safety information and a less complicated signature for calling a destructor. The old type had a problematic API and is now diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst index ed72af71..42e54fba 100644 --- a/Doc/whatsnew/3.10.rst +++ b/Doc/whatsnew/3.10.rst @@ -668,6 +668,7 @@ Several other key features: GREEN = 1 BLUE = 2 + color = Color.GREEN match color: case Color.RED: print("I see red!") @@ -877,7 +878,7 @@ Other Language Changes (Contributed by Raymond Hettinger in :issue:`43475`.) * A :exc:`SyntaxError` (instead of a :exc:`NameError`) will be raised when deleting - the :const:`__debug__` constant. (Contributed by Dong-hee Na in :issue:`45000`.) + the :const:`__debug__` constant. (Contributed by Donghee Na in :issue:`45000`.) * :exc:`SyntaxError` exceptions now have ``end_lineno`` and ``end_offset`` attributes. They will be ``None`` if not determined. @@ -886,7 +887,7 @@ Other Language Changes New Modules =========== -* None yet. +* None. Improved Modules @@ -1252,9 +1253,9 @@ descriptors without copying between kernel address space and user address space, where one of the file descriptors must refer to a pipe. (Contributed by Pablo Galindo in :issue:`41625`.) -Add :data:`~os.O_EVTONLY`, :data:`~os.O_FSYNC`, :data:`~os.O_SYMLINK` -and :data:`~os.O_NOFOLLOW_ANY` for macOS. -(Contributed by Dong-hee Na in :issue:`43106`.) +Add :const:`~os.O_EVTONLY`, :const:`~os.O_FSYNC`, :const:`~os.O_SYMLINK` +and :const:`~os.O_NOFOLLOW_ANY` for macOS. +(Contributed by Donghee Na in :issue:`43106`.) os.path ------- @@ -1318,7 +1319,7 @@ objects in the tree returned by :func:`pyclbr.readline` and shelve ------ -The :mod:`shelve` module now uses :data:`pickle.DEFAULT_PROTOCOL` by default +The :mod:`shelve` module now uses :const:`pickle.DEFAULT_PROTOCOL` by default instead of :mod:`pickle` protocol ``3`` when creating shelves. (Contributed by Zackery Spytz in :issue:`34204`.) @@ -1355,7 +1356,7 @@ The ssl module requires OpenSSL 1.1.1 or newer. (Contributed by Christian Heimes in :pep:`644` and :issue:`43669`.) The ssl module has preliminary support for OpenSSL 3.0.0 and new option -:data:`~ssl.OP_IGNORE_UNEXPECTED_EOF`. +:const:`~ssl.OP_IGNORE_UNEXPECTED_EOF`. (Contributed by Christian Heimes in :issue:`38820`, :issue:`43794`, :issue:`43788`, :issue:`43791`, :issue:`43799`, :issue:`43920`, :issue:`43789`, and :issue:`43811`.) @@ -1386,7 +1387,7 @@ Add a *timeout* parameter to the :func:`ssl.get_server_certificate` function. The ssl module uses heap-types and multi-phase initialization. (Contributed by Christian Heimes in :issue:`42333`.) -A new verify flag :data:`~ssl.VERIFY_X509_PARTIAL_CHAIN` has been added. +A new verify flag :const:`~ssl.VERIFY_X509_PARTIAL_CHAIN` has been added. (Contributed by l0x in :issue:`40849`.) sqlite3 @@ -1412,7 +1413,7 @@ _thread ------- :func:`_thread.interrupt_main` now takes an optional signal number to -simulate (the default is still :data:`signal.SIGINT`). +simulate (the default is still :const:`signal.SIGINT`). (Contributed by Antoine Pitrou in :issue:`43356`.) threading @@ -1581,7 +1582,7 @@ Optimizations * The following built-in functions now support the faster :pep:`590` vectorcall calling convention: :func:`map`, :func:`filter`, :func:`reversed`, :func:`bool` and :func:`float`. - (Contributed by Dong-hee Na and Jeroen Demeyer in :issue:`43575`, :issue:`43287`, :issue:`41922`, :issue:`41873` and :issue:`41870`.) + (Contributed by Donghee Na and Jeroen Demeyer in :issue:`43575`, :issue:`43287`, :issue:`41922`, :issue:`41873` and :issue:`41870`.) * :class:`BZ2File` performance is improved by removing internal ``RLock``. This makes :class:`BZ2File` thread unsafe in the face of multiple simultaneous @@ -1607,11 +1608,11 @@ Deprecated * Starting in this release, there will be a concerted effort to begin cleaning up old import semantics that were kept for Python 2.7 compatibility. Specifically, - :meth:`~importlib.abc.PathEntryFinder.find_loader`/:meth:`~importlib.abc.Finder.find_module` + :meth:`!find_loader`/:meth:`!find_module` (superseded by :meth:`~importlib.abc.Finder.find_spec`), :meth:`~importlib.abc.Loader.load_module` (superseded by :meth:`~importlib.abc.Loader.exec_module`), - :meth:`~importlib.abc.Loader.module_repr` (which the import system + :meth:`!module_repr` (which the import system takes care of for you), the ``__package__`` attribute (superseded by ``__spec__.parent``), the ``__loader__`` attribute (superseded by ``__spec__.loader``), and the ``__cached__`` attribute @@ -1644,8 +1645,8 @@ Deprecated :meth:`~importlib.abc.Loader.exec_module` is preferred. (Contributed by Brett Cannon in :issue:`26131`.) -* The use of :meth:`importlib.abc.MetaPathFinder.find_module` and - :meth:`importlib.abc.PathEntryFinder.find_module` by the import system now +* The use of :meth:`!importlib.abc.MetaPathFinder.find_module` and + :meth:`!importlib.abc.PathEntryFinder.find_module` by the import system now trigger an :exc:`ImportWarning` as :meth:`importlib.abc.MetaPathFinder.find_spec` and :meth:`importlib.abc.PathEntryFinder.find_spec` @@ -1653,53 +1654,53 @@ Deprecated :func:`importlib.util.spec_from_loader` to help in porting. (Contributed by Brett Cannon in :issue:`42134`.) -* The use of :meth:`importlib.abc.PathEntryFinder.find_loader` by the import +* The use of :meth:`!importlib.abc.PathEntryFinder.find_loader` by the import system now triggers an :exc:`ImportWarning` as :meth:`importlib.abc.PathEntryFinder.find_spec` is preferred. You can use :func:`importlib.util.spec_from_loader` to help in porting. (Contributed by Brett Cannon in :issue:`43672`.) * The various implementations of - :meth:`importlib.abc.MetaPathFinder.find_module` ( - :meth:`importlib.machinery.BuiltinImporter.find_module`, - :meth:`importlib.machinery.FrozenImporter.find_module`, - :meth:`importlib.machinery.WindowsRegistryFinder.find_module`, - :meth:`importlib.machinery.PathFinder.find_module`, - :meth:`importlib.abc.MetaPathFinder.find_module` ), - :meth:`importlib.abc.PathEntryFinder.find_module` ( - :meth:`importlib.machinery.FileFinder.find_module` ), and - :meth:`importlib.abc.PathEntryFinder.find_loader` ( - :meth:`importlib.machinery.FileFinder.find_loader` ) + :meth:`!importlib.abc.MetaPathFinder.find_module` ( + :meth:`!importlib.machinery.BuiltinImporter.find_module`, + :meth:`!importlib.machinery.FrozenImporter.find_module`, + :meth:`!importlib.machinery.WindowsRegistryFinder.find_module`, + :meth:`!importlib.machinery.PathFinder.find_module`, + :meth:`!importlib.abc.MetaPathFinder.find_module` ), + :meth:`!importlib.abc.PathEntryFinder.find_module` ( + :meth:`!importlib.machinery.FileFinder.find_module` ), and + :meth:`!importlib.abc.PathEntryFinder.find_loader` ( + :meth:`!importlib.machinery.FileFinder.find_loader` ) now raise :exc:`DeprecationWarning` and are slated for removal in Python 3.12 (previously they were documented as deprecated in Python 3.4). (Contributed by Brett Cannon in :issue:`42135`.) -* :class:`importlib.abc.Finder` is deprecated (including its sole method, - :meth:`~importlib.abc.Finder.find_module`). Both +* :class:`!importlib.abc.Finder` is deprecated (including its sole method, + :meth:`!find_module`). Both :class:`importlib.abc.MetaPathFinder` and :class:`importlib.abc.PathEntryFinder` no longer inherit from the class. Users should inherit from one of these two classes as appropriate instead. (Contributed by Brett Cannon in :issue:`42135`.) -* The deprecations of :mod:`imp`, :func:`importlib.find_loader`, - :func:`importlib.util.set_package_wrapper`, - :func:`importlib.util.set_loader_wrapper`, - :func:`importlib.util.module_for_loader`, - :class:`pkgutil.ImpImporter`, and - :class:`pkgutil.ImpLoader` have all been updated to list Python 3.12 as the +* The deprecations of :mod:`!imp`, :func:`!importlib.find_loader`, + :func:`!importlib.util.set_package_wrapper`, + :func:`!importlib.util.set_loader_wrapper`, + :func:`!importlib.util.module_for_loader`, + :class:`!pkgutil.ImpImporter`, and + :class:`!pkgutil.ImpLoader` have all been updated to list Python 3.12 as the slated version of removal (they began raising :exc:`DeprecationWarning` in previous versions of Python). (Contributed by Brett Cannon in :issue:`43720`.) * The import system now uses the ``__spec__`` attribute on modules before - falling back on :meth:`~importlib.abc.Loader.module_repr` for a module's + falling back on :meth:`!module_repr` for a module's ``__repr__()`` method. Removal of the use of ``module_repr()`` is scheduled for Python 3.12. (Contributed by Brett Cannon in :issue:`42137`.) -* :meth:`importlib.abc.Loader.module_repr`, - :meth:`importlib.machinery.FrozenLoader.module_repr`, and - :meth:`importlib.machinery.BuiltinLoader.module_repr` are deprecated and +* :meth:`!importlib.abc.Loader.module_repr`, + :meth:`!importlib.machinery.FrozenLoader.module_repr`, and + :meth:`!importlib.machinery.BuiltinLoader.module_repr` are deprecated and slated for removal in Python 3.12. (Contributed by Brett Cannon in :issue:`42136`.) @@ -1756,8 +1757,8 @@ Deprecated * :data:`~ssl.PROTOCOL_SSLv2`, :data:`~ssl.PROTOCOL_SSLv3`, :data:`~ssl.PROTOCOL_SSLv23`, :data:`~ssl.PROTOCOL_TLSv1`, :data:`~ssl.PROTOCOL_TLSv1_1`, :data:`~ssl.PROTOCOL_TLSv1_2`, and - :data:`~ssl.PROTOCOL_TLS` are deprecated in favor of - :data:`~ssl.PROTOCOL_TLS_CLIENT` and :data:`~ssl.PROTOCOL_TLS_SERVER` + :const:`~ssl.PROTOCOL_TLS` are deprecated in favor of + :const:`~ssl.PROTOCOL_TLS_CLIENT` and :const:`~ssl.PROTOCOL_TLS_SERVER` * :func:`~ssl.wrap_socket` is replaced by :meth:`ssl.SSLContext.wrap_socket` @@ -1816,10 +1817,10 @@ Removed scheduled to be removed in Python 3.6, but such removals were delayed until after Python 2.7 EOL. Existing users should copy whatever classes they use into their code. - (Contributed by Dong-hee Na and Terry J. Reedy in :issue:`42299`.) + (Contributed by Donghee Na and Terry J. Reedy in :issue:`42299`.) -* Removed the :c:func:`PyModule_GetWarningsModule` function that was useless - now due to the _warnings module was converted to a builtin module in 2.6. +* Removed the :c:func:`!PyModule_GetWarningsModule` function that was useless + now due to the :mod:`!_warnings` module was converted to a builtin module in 2.6. (Contributed by Hai Shi in :issue:`42599`.) * Remove deprecated aliases to :ref:`collections-abstract-base-classes` from @@ -2123,11 +2124,11 @@ New Features These functions allow to activate, deactivate and query the state of the garbage collector from C code without having to import the :mod:`gc` module. -* Add a new :c:data:`Py_TPFLAGS_DISALLOW_INSTANTIATION` type flag to disallow +* Add a new :c:macro:`Py_TPFLAGS_DISALLOW_INSTANTIATION` type flag to disallow creating type instances. (Contributed by Victor Stinner in :issue:`43916`.) -* Add a new :c:data:`Py_TPFLAGS_IMMUTABLETYPE` type flag for creating immutable +* Add a new :c:macro:`Py_TPFLAGS_IMMUTABLETYPE` type flag for creating immutable type objects: type attributes cannot be set nor deleted. (Contributed by Victor Stinner and Erlend E. Aasland in :issue:`43908`.) @@ -2186,9 +2187,9 @@ Porting to Python 3.10 been included directly, consider including ``Python.h`` instead. (Contributed by Nicholas Sim in :issue:`35134`.) -* Use the :c:data:`Py_TPFLAGS_IMMUTABLETYPE` type flag to create immutable type - objects. Do not rely on :c:data:`Py_TPFLAGS_HEAPTYPE` to decide if a type - object is mutable or not; check if :c:data:`Py_TPFLAGS_IMMUTABLETYPE` is set +* Use the :c:macro:`Py_TPFLAGS_IMMUTABLETYPE` type flag to create immutable type + objects. Do not rely on :c:macro:`Py_TPFLAGS_HEAPTYPE` to decide if a type + object is mutable or not; check if :c:macro:`Py_TPFLAGS_IMMUTABLETYPE` is set instead. (Contributed by Victor Stinner and Erlend E. Aasland in :issue:`43908`.) diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index 4244875f..88eaee97 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -2,8 +2,6 @@ What's New In Python 3.11 **************************** -:Release: |release| -:Date: |today| :Editor: Pablo Galindo Salgado .. Rules for maintenance: @@ -47,7 +45,7 @@ when researching a change. This article explains the new features in Python 3.11, compared to 3.10. - +Python 3.11 was released on October 24, 2022. For full details, see the :ref:`changelog <changelog>`. @@ -220,17 +218,17 @@ Windows ``py.exe`` launcher improvements The copy of the :ref:`launcher` included with Python 3.11 has been significantly updated. It now supports company/tag syntax as defined in :pep:`514` using the -``-V:<company>/<tag>`` argument instead of the limited ``-<major>.<minor>``. +:samp:`-V:{<company>}/{<tag>}` argument instead of the limited :samp:`-{<major>}.{<minor>}`. This allows launching distributions other than ``PythonCore``, -the one hosted on `python.org <https://python.org>`_. +the one hosted on `python.org <https://www.python.org>`_. When using ``-V:`` selectors, either company or tag can be omitted, but all installs will be searched. For example, ``-V:OtherPython/`` will select the "best" tag registered for ``OtherPython``, while ``-V:3.11`` or ``-V:/3.11`` will select the "best" distribution with tag ``3.11``. -When using the legacy ``-<major>``, ``-<major>.<minor>``, -``-<major>-<bitness>`` or ``-<major>.<minor>-<bitness>`` arguments, +When using the legacy :samp:`-{<major>}`, :samp:`-{<major>}.{<minor>}`, +:samp:`-{<major>}-{<bitness>}` or :samp:`-{<major>}.{<minor>}-{<bitness>}` arguments, all existing behaviour should be preserved from past versions, and only releases from ``PythonCore`` will be selected. However, the ``-64`` suffix now implies "not 32-bit" (not necessarily x86-64), @@ -461,6 +459,10 @@ Other Language Changes :class:`collections.OrderedDict`, :class:`collections.deque`, :class:`weakref.WeakSet`, and :class:`datetime.tzinfo` now copies and pickles instance attributes implemented as :term:`slots <__slots__>`. + This change has an unintended side effect: It trips up a small minority + of existing Python projects not expecting :meth:`object.__getstate__` to + exist. See the later comments on :gh:`70766` for discussions of what + workarounds such code may need. (Contributed by Serhiy Storchaka in :issue:`26579`.) .. _whatsnew311-pythonsafepath: @@ -497,7 +499,7 @@ Other CPython Implementation Changes * The special methods :meth:`~object.__complex__` for :class:`complex` and :meth:`~object.__bytes__` for :class:`bytes` are implemented to support the :class:`typing.SupportsComplex` and :class:`typing.SupportsBytes` protocols. - (Contributed by Mark Dickinson and Dong-hee Na in :issue:`24234`.) + (Contributed by Mark Dickinson and Donghee Na in :issue:`24234`.) * ``siphash13`` is added as a new internal hashing algorithm. It has similar security properties as ``siphash24``, @@ -642,7 +644,7 @@ dataclasses datetime -------- -* Add :attr:`datetime.UTC`, a convenience alias for +* Add :const:`datetime.UTC`, a convenience alias for :attr:`datetime.timezone.utc`. (Contributed by Kabir Kwatra in :gh:`91973`.) * :meth:`datetime.date.fromisoformat`, :meth:`datetime.time.fromisoformat` and @@ -668,19 +670,11 @@ enum for :meth:`~object.__str__` and :meth:`~object.__format__` (used by :func:`str`, :func:`format` and :term:`f-string`\s). -* Changed :class:`~enum.IntEnum`, :class:`~enum.IntFlag` and :class:`~enum.StrEnum` - to now inherit from :class:`~enum.ReprEnum`, - so their :func:`str` output now matches :func:`format` - (both ``str(AnIntEnum.ONE)`` and ``format(AnIntEnum.ONE)`` return ``'1'``, - whereas before ``str(AnIntEnum.ONE)`` returned ``'AnIntEnum.ONE'``. - -* Changed :meth:`Enum.__format__() <enum.Enum.__format__>` - (the default for :func:`format`, :meth:`str.format` and :term:`f-string`\s) - of enums with mixed-in types (e.g. :class:`int`, :class:`str`) - to also include the class name in the output, not just the member's key. - This matches the existing behavior of :meth:`enum.Enum.__str__`, - returning e.g. ``'AnEnum.MEMBER'`` for an enum ``AnEnum(str, Enum)`` - instead of just ``'MEMBER'``. +* Changed :meth:`Enum.__format__() <enum.Enum.__format__>` (the default for + :func:`format`, :meth:`str.format` and :term:`f-string`\s) to always produce + the same result as :meth:`Enum.__str__()`: for enums inheriting from + :class:`~enum.ReprEnum` it will be the member's value; for all other enums + it will be the enum and member name (e.g. ``Color.RED``). * Added a new *boundary* class parameter to :class:`~enum.Flag` enums and the :class:`~enum.FlagBoundary` enum with its options, @@ -700,7 +694,7 @@ enum * Added the :func:`~enum.global_enum` enum decorator, which adjusts :meth:`~object.__repr__` and :meth:`~object.__str__` to show values as members of their module rather than the enum class. - For example, ``'re.ASCII'`` for the :data:`~re.ASCII` member + For example, ``'re.ASCII'`` for the :const:`~re.ASCII` member of :class:`re.RegexFlag` rather than ``'RegexFlag.ASCII'``. * Enhanced :class:`~enum.Flag` to support @@ -903,7 +897,7 @@ os * On Windows, :func:`os.urandom` now uses ``BCryptGenRandom()``, instead of ``CryptGenRandom()`` which is deprecated. - (Contributed by Dong-hee Na in :issue:`44611`.) + (Contributed by Donghee Na in :issue:`44611`.) .. _whatsnew311-pathlib: @@ -1073,8 +1067,8 @@ threading * On Unix, if the ``sem_clockwait()`` function is available in the C library (glibc 2.30 and newer), the :meth:`threading.Lock.acquire` method now uses - the monotonic clock (:data:`time.CLOCK_MONOTONIC`) for the timeout, rather - than using the system clock (:data:`time.CLOCK_REALTIME`), to not be affected + the monotonic clock (:const:`time.CLOCK_MONOTONIC`) for the timeout, rather + than using the system clock (:const:`time.CLOCK_REALTIME`), to not be affected by system clock changes. (Contributed by Victor Stinner in :issue:`41710`.) @@ -1095,7 +1089,7 @@ time <https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/high-resolution-timers>`_ which has a resolution of 100 nanoseconds (10\ :sup:`-7` seconds). Previously, it had a resolution of 1 millisecond (10\ :sup:`-3` seconds). - (Contributed by Benjamin Szőke, Dong-hee Na, Eryk Sun and Victor Stinner in :issue:`21302` and :issue:`45429`.) + (Contributed by Benjamin Szőke, Donghee Na, Eryk Sun and Victor Stinner in :issue:`21302` and :issue:`45429`.) .. _whatsnew311-tkinter: @@ -1311,7 +1305,7 @@ This section covers specific optimizations independent of the * :func:`unicodedata.normalize` now normalizes pure-ASCII strings in constant time. - (Contributed by Dong-hee Na in :issue:`44987`.) + (Contributed by Donghee Na in :issue:`44987`.) .. _whatsnew311-faster-cpython: @@ -1319,14 +1313,17 @@ This section covers specific optimizations independent of the Faster CPython ============== -CPython 3.11 is on average `25% faster <https://github.com/faster-cpython/ideas#published-results>`_ -than CPython 3.10 when measured with the +CPython 3.11 is an average of +`25% faster <https://github.com/faster-cpython/ideas#published-results>`_ +than CPython 3.10 as measured with the `pyperformance <https://github.com/python/pyperformance>`_ benchmark suite, -and compiled with GCC on Ubuntu Linux. Depending on your workload, the speedup -could be up to 10-60% faster. +when compiled with GCC on Ubuntu Linux. +Depending on your workload, the overall speedup could be 10-60%. -This project focuses on two major areas in Python: faster startup and faster -runtime. Other optimizations not under this project are listed in `Optimizations`_. +This project focuses on two major areas in Python: +:ref:`whatsnew311-faster-startup` and :ref:`whatsnew311-faster-runtime`. +Optimizations not covered by this project are listed separately under +:ref:`whatsnew311-optimizations`. .. _whatsnew311-faster-startup: @@ -1339,8 +1336,8 @@ Faster Startup Frozen imports / Static code objects ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Python caches bytecode in the :ref:`__pycache__<tut-pycache>` directory to -speed up module loading. +Python caches :term:`bytecode` in the :ref:`__pycache__ <tut-pycache>` +directory to speed up module loading. Previously in 3.10, Python module execution looked like this: @@ -1349,8 +1346,9 @@ Previously in 3.10, Python module execution looked like this: Read __pycache__ -> Unmarshal -> Heap allocated code object -> Evaluate In Python 3.11, the core modules essential for Python startup are "frozen". -This means that their code objects (and bytecode) are statically allocated -by the interpreter. This reduces the steps in module execution process to this: +This means that their :ref:`codeobjects` (and bytecode) +are statically allocated by the interpreter. +This reduces the steps in module execution process to: .. code-block:: text @@ -1359,7 +1357,7 @@ by the interpreter. This reduces the steps in module execution process to this: Interpreter startup is now 10-15% faster in Python 3.11. This has a big impact for short-running programs using Python. -(Contributed by Eric Snow, Guido van Rossum and Kumar Aditya in numerous issues.) +(Contributed by Eric Snow, Guido van Rossum and Kumar Aditya in many issues.) .. _whatsnew311-faster-runtime: @@ -1372,17 +1370,19 @@ Faster Runtime Cheaper, lazy Python frames ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Python frames are created whenever Python calls a Python function. This frame -holds execution information. The following are new frame optimizations: +Python frames, holding execution information, +are created whenever Python calls a Python function. +The following are new frame optimizations: - Streamlined the frame creation process. - Avoided memory allocation by generously re-using frame space on the C stack. - Streamlined the internal frame struct to contain only essential information. Frames previously held extra debugging and memory management information. -Old-style frame objects are now created only when requested by debuggers or -by Python introspection functions such as ``sys._getframe`` or -``inspect.currentframe``. For most user code, no frame objects are +Old-style :ref:`frame objects <frame-objects>` +are now created only when requested by debuggers +or by Python introspection functions such as :func:`sys._getframe` and +:func:`inspect.currentframe`. For most user code, no frame objects are created at all. As a result, nearly all Python functions calls have sped up significantly. We measured a 3-7% speedup in pyperformance. @@ -1403,10 +1403,11 @@ In 3.11, when CPython detects Python code calling another Python function, it sets up a new frame, and "jumps" to the new code inside the new frame. This avoids calling the C interpreting function altogether. -Most Python function calls now consume no C stack space. This speeds up -most of such calls. In simple recursive functions like fibonacci or -factorial, a 1.7x speedup was observed. This also means recursive functions -can recurse significantly deeper (if the user increases the recursion limit). +Most Python function calls now consume no C stack space, speeding them up. +In simple recursive functions like fibonacci or +factorial, we observed a 1.7x speedup. This also means recursive functions +can recurse significantly deeper +(if the user increases the recursion limit with :func:`sys.setrecursionlimit`). We measured a 1-3% improvement in pyperformance. (Contributed by Pablo Galindo and Mark Shannon in :issue:`45256`.) @@ -1417,7 +1418,7 @@ We measured a 1-3% improvement in pyperformance. PEP 659: Specializing Adaptive Interpreter ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -:pep:`659` is one of the key parts of the faster CPython project. The general +:pep:`659` is one of the key parts of the Faster CPython project. The general idea is that while Python is a dynamic language, most code has regions where objects and types rarely change. This concept is known as *type stability*. @@ -1426,17 +1427,18 @@ in the executing code. Python will then replace the current operation with a more specialized one. This specialized operation uses fast paths available only to those use cases/types, which generally outperform their generic counterparts. This also brings in another concept called *inline caching*, where -Python caches the results of expensive operations directly in the bytecode. +Python caches the results of expensive operations directly in the +:term:`bytecode`. The specializer will also combine certain common instruction pairs into one -superinstruction. This reduces the overhead during execution. +superinstruction, reducing the overhead during execution. Python will only specialize when it sees code that is "hot" (executed multiple times). This prevents Python -from wasting time for run-once code. Python can also de-specialize when code is +from wasting time on run-once code. Python can also de-specialize when code is too dynamic or when the use changes. Specialization is attempted periodically, -and specialization attempts are not too expensive. This allows specialization -to adapt to new circumstances. +and specialization attempts are not too expensive, +allowing specialization to adapt to new circumstances. (PEP written by Mark Shannon, with ideas inspired by Stefan Brunthaler. See :pep:`659` for more information. Implementation by Mark Shannon and Brandt @@ -1449,32 +1451,32 @@ Bucher, with additional help from Irit Katriel and Dennis Sweeney.) | Operation | Form | Specialization | Operation speedup | Contributor(s) | | | | | (up to) | | +===============+====================+=======================================================+===================+===================+ -| Binary | ``x+x; x*x; x-x;`` | Binary add, multiply and subtract for common types | 10% | Mark Shannon, | -| operations | | such as ``int``, ``float``, and ``str`` take custom | | Dong-hee Na, | -| | | fast paths for their underlying types. | | Brandt Bucher, | +| Binary | ``x + x`` | Binary add, multiply and subtract for common types | 10% | Mark Shannon, | +| operations | | such as :class:`int`, :class:`float` and :class:`str` | | Donghee Na, | +| | ``x - x`` | take custom fast paths for their underlying types. | | Brandt Bucher, | | | | | | Dennis Sweeney | +| | ``x * x`` | | | | +---------------+--------------------+-------------------------------------------------------+-------------------+-------------------+ -| Subscript | ``a[i]`` | Subscripting container types such as ``list``, | 10-25% | Irit Katriel, | -| | | ``tuple`` and ``dict`` directly index the underlying | | Mark Shannon | -| | | data structures. | | | +| Subscript | ``a[i]`` | Subscripting container types such as :class:`list`, | 10-25% | Irit Katriel, | +| | | :class:`tuple` and :class:`dict` directly index | | Mark Shannon | +| | | the underlying data structures. | | | | | | | | | -| | | Subscripting custom ``__getitem__`` | | | +| | | Subscripting custom :meth:`~object.__getitem__` | | | | | | is also inlined similar to :ref:`inline-calls`. | | | +---------------+--------------------+-------------------------------------------------------+-------------------+-------------------+ | Store | ``a[i] = z`` | Similar to subscripting specialization above. | 10-25% | Dennis Sweeney | | subscript | | | | | +---------------+--------------------+-------------------------------------------------------+-------------------+-------------------+ | Calls | ``f(arg)`` | Calls to common builtin (C) functions and types such | 20% | Mark Shannon, | -| | ``C(arg)`` | as ``len`` and ``str`` directly call their underlying | | Ken Jin | -| | | C version. This avoids going through the internal | | | -| | | calling convention. | | | -| | | | | | +| | | as :func:`len` and :class:`str` directly call their | | Ken Jin | +| | ``C(arg)`` | underlying C version. This avoids going through the | | | +| | | internal calling convention. | | | +---------------+--------------------+-------------------------------------------------------+-------------------+-------------------+ -| Load | ``print`` | The object's index in the globals/builtins namespace | [1]_ | Mark Shannon | -| global | ``len`` | is cached. Loading globals and builtins require | | | -| variable | | zero namespace lookups. | | | +| Load | ``print`` | The object's index in the globals/builtins namespace | [#load-global]_ | Mark Shannon | +| global | | is cached. Loading globals and builtins require | | | +| variable | ``len`` | zero namespace lookups. | | | +---------------+--------------------+-------------------------------------------------------+-------------------+-------------------+ -| Load | ``o.attr`` | Similar to loading global variables. The attribute's | [2]_ | Mark Shannon | +| Load | ``o.attr`` | Similar to loading global variables. The attribute's | [#load-attr]_ | Mark Shannon | | attribute | | index inside the class/object's namespace is cached. | | | | | | In most cases, attribute loading will require zero | | | | | | namespace lookups. | | | @@ -1486,14 +1488,15 @@ Bucher, with additional help from Irit Katriel and Dennis Sweeney.) | Store | ``o.attr = z`` | Similar to load attribute optimization. | 2% | Mark Shannon | | attribute | | | in pyperformance | | +---------------+--------------------+-------------------------------------------------------+-------------------+-------------------+ -| Unpack | ``*seq`` | Specialized for common containers such as ``list`` | 8% | Brandt Bucher | -| Sequence | | and ``tuple``. Avoids internal calling convention. | | | +| Unpack | ``*seq`` | Specialized for common containers such as | 8% | Brandt Bucher | +| Sequence | | :class:`list` and :class:`tuple`. | | | +| | | Avoids internal calling convention. | | | +---------------+--------------------+-------------------------------------------------------+-------------------+-------------------+ -.. [1] A similar optimization already existed since Python 3.8. 3.11 - specializes for more forms and reduces some overhead. +.. [#load-global] A similar optimization already existed since Python 3.8. + 3.11 specializes for more forms and reduces some overhead. -.. [2] A similar optimization already existed since Python 3.10. +.. [#load-attr] A similar optimization already existed since Python 3.10. 3.11 specializes for more forms. Furthermore, all attribute loads should be sped up by :issue:`45947`. @@ -1503,49 +1506,72 @@ Bucher, with additional help from Irit Katriel and Dennis Sweeney.) Misc ---- -* Objects now require less memory due to lazily created object namespaces. Their - namespace dictionaries now also share keys more freely. +* Objects now require less memory due to lazily created object namespaces. + Their namespace dictionaries now also share keys more freely. (Contributed Mark Shannon in :issue:`45340` and :issue:`40116`.) +* "Zero-cost" exceptions are implemented, eliminating the cost + of :keyword:`try` statements when no exception is raised. + (Contributed by Mark Shannon in :issue:`40222`.) + * A more concise representation of exceptions in the interpreter reduced the time required for catching an exception by about 10%. (Contributed by Irit Katriel in :issue:`45711`.) +* :mod:`re`'s regular expression matching engine has been partially refactored, + and now uses computed gotos (or "threaded code") on supported platforms. As a + result, Python 3.11 executes the `pyperformance regular expression benchmarks + <https://pyperformance.readthedocs.io/benchmarks.html#regex-dna>`_ up to 10% + faster than Python 3.10. + (Contributed by Brandt Bucher in :gh:`91404`.) + .. _whatsnew311-faster-cpython-faq: FAQ --- -| Q: How should I write my code to utilize these speedups? -| -| A: You don't have to change your code. Write Pythonic code that follows common - best practices. The Faster CPython project optimizes for common code - patterns we observe. -| -| -| Q: Will CPython 3.11 use more memory? -| -| A: Maybe not. We don't expect memory use to exceed 20% more than 3.10. - This is offset by memory optimizations for frame objects and object - dictionaries as mentioned above. -| -| -| Q: I don't see any speedups in my workload. Why? -| -| A: Certain code won't have noticeable benefits. If your code spends most of - its time on I/O operations, or already does most of its - computation in a C extension library like numpy, there won't be significant - speedup. This project currently benefits pure-Python workloads the most. -| -| Furthermore, the pyperformance figures are a geometric mean. Even within the - pyperformance benchmarks, certain benchmarks have slowed down slightly, while - others have sped up by nearly 2x! -| -| -| Q: Is there a JIT compiler? -| -| A: No. We're still exploring other optimizations. +.. _faster-cpython-faq-my-code: + +How should I write my code to utilize these speedups? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Write Pythonic code that follows common best practices; +you don't have to change your code. +The Faster CPython project optimizes for common code patterns we observe. + + +.. _faster-cpython-faq-memory: + +Will CPython 3.11 use more memory? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Maybe not; we don't expect memory use to exceed 20% higher than 3.10. +This is offset by memory optimizations for frame objects and object +dictionaries as mentioned above. + + +.. _faster-cpython-ymmv: + +I don't see any speedups in my workload. Why? +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Certain code won't have noticeable benefits. If your code spends most of +its time on I/O operations, or already does most of its +computation in a C extension library like NumPy, there won't be significant +speedups. This project currently benefits pure-Python workloads the most. + +Furthermore, the pyperformance figures are a geometric mean. Even within the +pyperformance benchmarks, certain benchmarks have slowed down slightly, while +others have sped up by nearly 2x! + + +.. _faster-cpython-jit: + +Is there a JIT compiler? +^^^^^^^^^^^^^^^^^^^^^^^^ + +No. We're still exploring other optimizations. .. _whatsnew311-faster-cpython-about: @@ -1790,7 +1816,7 @@ Standard Library (Contributed by Serhiy Storchaka in :gh:`91760`.) * In the :mod:`re` module, the :func:`!re.template` function - and the corresponding :data:`!re.TEMPLATE` and :data:`!re.T` flags + and the corresponding :const:`!re.TEMPLATE` and :const:`!re.T` flags are deprecated, as they were undocumented and lacked an obvious purpose. They will be removed in Python 3.13. (Contributed by Serhiy Storchaka and Miro Hrončok in :gh:`92728`.) @@ -1813,7 +1839,7 @@ Standard Library * :class:`!webbrowser.MacOSX` is deprecated and will be removed in Python 3.13. It is untested, undocumented, and not used by :mod:`webbrowser` itself. - (Contributed by Dong-hee Na in :issue:`42255`.) + (Contributed by Donghee Na in :issue:`42255`.) * The behavior of returning a value from a :class:`~unittest.TestCase` and :class:`~unittest.IsolatedAsyncioTestCase` test methods (other than the @@ -1834,6 +1860,10 @@ Standard Library (Contributed by Erlend E. Aasland in :issue:`5846`.) +* :meth:`~!unittest.TestProgram.usageExit` is marked deprecated, to be removed + in 3.13. + (Contributed by Carlos Damázio in :gh:`67048`.) + .. _whatsnew311-pending-removal: .. _whatsnew311-python-api-pending-removal: @@ -1850,28 +1880,28 @@ C APIs pending removal are * The :mod:`asynchat` module * The :mod:`asyncore` module * The :ref:`entire distutils package <distutils-deprecated>` -* The :mod:`imp` module +* The :mod:`!imp` module * The :class:`typing.io <typing.IO>` namespace * The :class:`typing.re <typing.Pattern>` namespace * :func:`!cgi.log` -* :func:`importlib.find_loader` -* :meth:`importlib.abc.Loader.module_repr` -* :meth:`importlib.abc.MetaPathFinder.find_module` -* :meth:`importlib.abc.PathEntryFinder.find_loader` -* :meth:`importlib.abc.PathEntryFinder.find_module` +* :func:`!importlib.find_loader` +* :meth:`!importlib.abc.Loader.module_repr` +* :meth:`!importlib.abc.MetaPathFinder.find_module` +* :meth:`!importlib.abc.PathEntryFinder.find_loader` +* :meth:`!importlib.abc.PathEntryFinder.find_module` * :meth:`!importlib.machinery.BuiltinImporter.find_module` * :meth:`!importlib.machinery.BuiltinLoader.module_repr` * :meth:`!importlib.machinery.FileFinder.find_loader` * :meth:`!importlib.machinery.FileFinder.find_module` * :meth:`!importlib.machinery.FrozenImporter.find_module` * :meth:`!importlib.machinery.FrozenLoader.module_repr` -* :meth:`importlib.machinery.PathFinder.find_module` +* :meth:`!importlib.machinery.PathFinder.find_module` * :meth:`!importlib.machinery.WindowsRegistryFinder.find_module` -* :func:`importlib.util.module_for_loader` +* :func:`!importlib.util.module_for_loader` * :func:`!importlib.util.set_loader_wrapper` * :func:`!importlib.util.set_package_wrapper` -* :class:`pkgutil.ImpImporter` -* :class:`pkgutil.ImpLoader` +* :class:`!pkgutil.ImpImporter` +* :class:`!pkgutil.ImpLoader` * :meth:`pathlib.Path.link_to` * :func:`!sqlite3.enable_shared_cache` * :func:`!sqlite3.OptimizedUnicode` @@ -1954,7 +1984,7 @@ Removed C APIs are :ref:`listed separately <whatsnew311-c-api-removed>`. :meth:`!NullTranslations.set_output_charset` methods, and the *codeset* parameter of :func:`!translation` and :func:`!install`, since they are only used for the :func:`!l*gettext` functions. - (Contributed by Dong-hee Na and Serhiy Storchaka in :issue:`44235`.) + (Contributed by Donghee Na and Serhiy Storchaka in :issue:`44235`.) * Removed from the :mod:`inspect` module: @@ -1979,7 +2009,7 @@ Removed C APIs are :ref:`listed separately <whatsnew311-c-api-removed>`. * Removed the :class:`!MailmanProxy` class in the :mod:`smtpd` module, as it is unusable without the external :mod:`!mailman` package. - (Contributed by Dong-hee Na in :issue:`35800`.) + (Contributed by Donghee Na in :issue:`35800`.) * Removed the deprecated :meth:`!split` method of :class:`!_tkinter.TkappType`. (Contributed by Erlend E. Aasland in :issue:`38371`.) @@ -2084,30 +2114,22 @@ Build Changes and WASI contributed by Christian Heimes in :gh:`90473`; platforms promoted in :gh:`95085`) -* Building Python now requires: +* Building CPython now requires: - * A `C11 <https://en.cppreference.com/w/c/11>`_ compiler. + * A `C11 <https://en.cppreference.com/w/c/11>`_ compiler and standard library. `Optional C11 features <https://en.wikipedia.org/wiki/C11_(C_standard_revision)#Optional_features>`_ are not required. - (Contributed by Victor Stinner in :issue:`46656`.) + (Contributed by Victor Stinner in :issue:`46656`, + :issue:`45440` and :issue:`46640`.) * Support for `IEEE 754 <https://en.wikipedia.org/wiki/IEEE_754>`_ floating point numbers. (Contributed by Victor Stinner in :issue:`46917`.) - * Support for `floating point Not-a-Number (NaN) - <https://en.wikipedia.org/wiki/NaN#Floating_point>`_, - as the :c:macro:`!Py_NO_NAN` macro has been removed. - (Contributed by Victor Stinner in :issue:`46656`.) - - * A `C99 <https://en.cppreference.com/w/c/99>`_ - ``<math.h>`` header file providing the - :c:func:`!copysign`, :c:func:`!hypot`, :c:func:`!isfinite`, - :c:func:`!isinf`, :c:func:`!isnan`, and :c:func:`!round` functions - (contributed by Victor Stinner in :issue:`45440`); - and a :c:data:`!NAN` constant or the :c:func:`!__builtin_nan` function - (Contributed by Victor Stinner in :issue:`46640`). +* The :c:macro:`!Py_NO_NAN` macro has been removed. + Since CPython now requires IEEE 754 floats, NaN values are always available. + (Contributed by Victor Stinner in :issue:`46656`.) * The :mod:`tkinter` package now requires `Tcl/Tk <https://www.tcl.tk>`_ version 8.5.12 or newer. @@ -2129,10 +2151,10 @@ Build Changes * CPython can now be built with the `ThinLTO <https://clang.llvm.org/docs/ThinLTO.html>`_ option via passing ``thin`` to :option:`--with-lto`, i.e. ``--with-lto=thin``. - (Contributed by Dong-hee Na and Brett Holman in :issue:`44340`.) + (Contributed by Donghee Na and Brett Holman in :issue:`44340`.) * Freelists for object structs can now be disabled. A new :program:`configure` - option :option:`!--without-freelists` can be used to disable all freelists + option :option:`--without-freelists` can be used to disable all freelists except empty tuple singleton. (Contributed by Christian Heimes in :issue:`45522`.) @@ -2198,7 +2220,7 @@ New Features * :c:func:`PyBuffer_SizeFromFormat` * :c:func:`PyBuffer_ToContiguous` * :c:func:`PyBuffer_FromContiguous` - * :c:func:`PyBuffer_CopyData` + * :c:func:`PyObject_CopyData` * :c:func:`PyBuffer_IsContiguous` * :c:func:`PyBuffer_FillContiguousStrides` * :c:func:`PyBuffer_FillInfo` @@ -2209,7 +2231,7 @@ New Features (Contributed by Christian Heimes in :issue:`45459`.) -* Added the :c:data:`PyType_GetModuleByDef` function, used to get the module +* Added the :c:func:`PyType_GetModuleByDef` function, used to get the module in which a method was defined, in cases where this information is not available directly (via :c:type:`PyCMethod`). (Contributed by Petr Viktorin in :issue:`46613`.) @@ -2329,11 +2351,11 @@ Porting to Python 3.11 #endif * The :c:func:`PyType_Ready` function now raises an error if a type is defined - with the :const:`Py_TPFLAGS_HAVE_GC` flag set but has no traverse function + with the :c:macro:`Py_TPFLAGS_HAVE_GC` flag set but has no traverse function (:c:member:`PyTypeObject.tp_traverse`). (Contributed by Victor Stinner in :issue:`44263`.) -* Heap types with the :const:`Py_TPFLAGS_IMMUTABLETYPE` flag can now inherit +* Heap types with the :c:macro:`Py_TPFLAGS_IMMUTABLETYPE` flag can now inherit the :pep:`590` vectorcall protocol. Previously, this was only possible for :ref:`static types <static-types>`. (Contributed by Erlend E. Aasland in :issue:`43908`) @@ -2467,7 +2489,7 @@ Porting to Python 3.11 #endif Or use the `pythoncapi_compat project - <https://github.com/python/pythoncapi_compat>`__ to get these two + <https://github.com/python/pythoncapi-compat>`__ to get these two functions on older Python versions. * Changes of the :c:type:`PyThreadState` structure members: @@ -2519,8 +2541,8 @@ Porting to Python 3.11 } #endif - Or use `the pythoncapi_compat project - <https://github.com/python/pythoncapi_compat>`__ to get these functions + Or use `the pythoncapi-compat project + <https://github.com/python/pythoncapi-compat>`__ to get these functions on old Python functions. * Distributors are encouraged to build Python with the optimized Blake2 @@ -2544,18 +2566,18 @@ Deprecated * Deprecate the following functions to configure the Python initialization: - * :c:func:`PySys_AddWarnOptionUnicode` - * :c:func:`PySys_AddWarnOption` - * :c:func:`PySys_AddXOption` - * :c:func:`PySys_HasWarnOptions` - * :c:func:`PySys_SetArgvEx` - * :c:func:`PySys_SetArgv` - * :c:func:`PySys_SetPath` - * :c:func:`Py_SetPath` - * :c:func:`Py_SetProgramName` - * :c:func:`Py_SetPythonHome` - * :c:func:`Py_SetStandardStreamEncoding` - * :c:func:`_Py_SetProgramFullPath` + * :c:func:`!PySys_AddWarnOptionUnicode` + * :c:func:`!PySys_AddWarnOption` + * :c:func:`!PySys_AddXOption` + * :c:func:`!PySys_HasWarnOptions` + * :c:func:`!PySys_SetArgvEx` + * :c:func:`!PySys_SetArgv` + * :c:func:`!PySys_SetPath` + * :c:func:`!Py_SetPath` + * :c:func:`!Py_SetProgramName` + * :c:func:`!Py_SetPythonHome` + * :c:func:`!Py_SetStandardStreamEncoding` + * :c:func:`!_Py_SetProgramFullPath` Use the new :c:type:`PyConfig` API of the :ref:`Python Initialization Configuration <init-config>` instead (:pep:`587`). @@ -2573,22 +2595,22 @@ Pending Removal in Python 3.12 The following C APIs have been deprecated in earlier Python releases, and will be removed in Python 3.12. -* :c:func:`PyUnicode_AS_DATA` -* :c:func:`PyUnicode_AS_UNICODE` -* :c:func:`PyUnicode_AsUnicodeAndSize` -* :c:func:`PyUnicode_AsUnicode` -* :c:func:`PyUnicode_FromUnicode` -* :c:func:`PyUnicode_GET_DATA_SIZE` -* :c:func:`PyUnicode_GET_SIZE` -* :c:func:`PyUnicode_GetSize` +* :c:func:`!PyUnicode_AS_DATA` +* :c:func:`!PyUnicode_AS_UNICODE` +* :c:func:`!PyUnicode_AsUnicodeAndSize` +* :c:func:`!PyUnicode_AsUnicode` +* :c:func:`!PyUnicode_FromUnicode` +* :c:func:`!PyUnicode_GET_DATA_SIZE` +* :c:func:`!PyUnicode_GET_SIZE` +* :c:func:`!PyUnicode_GetSize` * :c:func:`PyUnicode_IS_COMPACT` * :c:func:`PyUnicode_IS_READY` * :c:func:`PyUnicode_READY` -* :c:func:`Py_UNICODE_WSTR_LENGTH` -* :c:func:`_PyUnicode_AsUnicode` -* :c:macro:`PyUnicode_WCHAR_KIND` +* :c:func:`!PyUnicode_WSTR_LENGTH` +* :c:func:`!_PyUnicode_AsUnicode` +* :c:macro:`!PyUnicode_WCHAR_KIND` * :c:type:`PyUnicodeObject` -* :c:func:`PyUnicode_InternImmortal()` +* :c:func:`!PyUnicode_InternImmortal` .. _whatsnew311-c-api-removed: @@ -2596,7 +2618,7 @@ and will be removed in Python 3.12. Removed ------- -* :c:func:`PyFrame_BlockSetup` and :c:func:`PyFrame_BlockPop` have been +* :c:func:`!PyFrame_BlockSetup` and :c:func:`!PyFrame_BlockPop` have been removed. (Contributed by Mark Shannon in :issue:`40222`.) @@ -2632,7 +2654,7 @@ Removed * :c:func:`PyMarshal_WriteObjectToString` * the ``Py_MARSHAL_VERSION`` macro - These are not part of the :ref:`limited API <stable-abi-list>`. + These are not part of the :ref:`limited API <limited-api-list>`. (Contributed by Victor Stinner in :issue:`45474`.) diff --git a/Doc/whatsnew/3.12.rst b/Doc/whatsnew/3.12.rst new file mode 100644 index 00000000..fad94d6d --- /dev/null +++ b/Doc/whatsnew/3.12.rst @@ -0,0 +1,2420 @@ + +**************************** + What's New In Python 3.12 +**************************** + +:Editor: Adam Turner + +.. Rules for maintenance: + + * Anyone can add text to this document. Do not spend very much time + on the wording of your changes, because your text will probably + get rewritten to some degree. + + * The maintainer will go through Misc/NEWS periodically and add + changes; it's therefore more important to add your changes to + Misc/NEWS than to this file. + + * This is not a complete list of every single change; completeness + is the purpose of Misc/NEWS. Some changes I consider too small + or esoteric to include. If such a change is added to the text, + I'll just remove it. (This is another reason you shouldn't spend + too much time on writing your addition.) + + * If you want to draw your new text to the attention of the + maintainer, add 'XXX' to the beginning of the paragraph or + section. + + * It's OK to just add a fragmentary note about a change. For + example: "XXX Describe the transmogrify() function added to the + socket module." The maintainer will research the change and + write the necessary text. + + * You can comment out your additions if you like, but it's not + necessary (especially when a final release is some months away). + + * Credit the author of a patch or bugfix. Just the name is + sufficient; the e-mail address isn't necessary. + + * It's helpful to add the issue number as a comment: + + XXX Describe the transmogrify() function added to the socket + module. + (Contributed by P.Y. Developer in :gh:`12345`.) + + This saves the maintainer the effort of going through the VCS log when + researching a change. + +This article explains the new features in Python 3.12, compared to 3.11. +Python 3.12 was released on October 2, 2023. +For full details, see the :ref:`changelog <changelog>`. + +.. seealso:: + + :pep:`693` -- Python 3.12 Release Schedule + +Summary -- Release highlights +============================= + +.. This section singles out the most important changes in Python 3.12. + Brevity is key. + +Python 3.12 is the latest stable release of the Python programming language, +with a mix of changes to the language and the standard library. +The library changes focus on cleaning up deprecated APIs, usability, and correctness. +Of note, the :mod:`!distutils` package has been removed from the standard library. +Filesystem support in :mod:`os` and :mod:`pathlib` has seen a number of improvements, +and several modules have better performance. + +The language changes focus on usability, +as :term:`f-strings <f-string>` have had many limitations removed +and 'Did you mean ...' suggestions continue to improve. +The new :ref:`type parameter syntax <whatsnew312-pep695>` +and :keyword:`type` statement improve ergonomics for using :term:`generic types +<generic type>` and :term:`type aliases <type alias>` with static type checkers. + +This article doesn't attempt to provide a complete specification of all new features, +but instead gives a convenient overview. +For full details, you should refer to the documentation, +such as the :ref:`Library Reference <library-index>` +and :ref:`Language Reference <reference-index>`. +If you want to understand the complete implementation and design rationale for a change, +refer to the PEP for a particular new feature; +but note that PEPs usually are not kept up-to-date +once a feature has been fully implemented. + +-------------- + +.. PEP-sized items next. + +New syntax features: + +* :ref:`PEP 695 <whatsnew312-pep695>`, type parameter syntax and the :keyword:`type` statement + +New grammar features: + +* :ref:`PEP 701 <whatsnew312-pep701>`, :term:`f-strings <f-string>` in the grammar + +Interpreter improvements: + +* :ref:`PEP 684 <whatsnew312-pep684>`, a unique per-interpreter :term:`GIL + <global interpreter lock>` +* :ref:`PEP 669 <whatsnew312-pep669>`, low impact monitoring +* `Improved 'Did you mean ...' suggestions <improved error messages_>`_ + for :exc:`NameError`, :exc:`ImportError`, and :exc:`SyntaxError` exceptions + +Python data model improvements: + +* :ref:`PEP 688 <whatsnew312-pep688>`, using the :ref:`buffer protocol + <bufferobjects>` from Python + +Significant improvements in the standard library: + +* The :class:`pathlib.Path` class now supports subclassing +* The :mod:`os` module received several improvements for Windows support +* A :ref:`command-line interface <sqlite3-cli>` has been added to the + :mod:`sqlite3` module +* :func:`isinstance` checks against :func:`runtime-checkable protocols + <typing.runtime_checkable>` enjoy a speed up of between two and 20 times +* The :mod:`asyncio` package has had a number of performance improvements, + with some benchmarks showing a 75% speed up. +* A :ref:`command-line interface <uuid-cli>` has been added to the + :mod:`uuid` module +* Due to the changes in :ref:`PEP 701 <whatsnew312-pep701>`, + producing tokens via the :mod:`tokenize` module is up to up to 64% faster. + +Security improvements: + +* Replace the builtin :mod:`hashlib` implementations of + SHA1, SHA3, SHA2-384, SHA2-512, and MD5 with formally verified code from the + `HACL* <https://github.com/hacl-star/hacl-star/>`__ project. + These builtin implementations remain as fallbacks that are only used when + OpenSSL does not provide them. + +C API improvements: + +* :ref:`PEP 697 <whatsnew312-pep697>`, unstable C API tier +* :ref:`PEP 683 <whatsnew312-pep683>`, immortal objects + +CPython implementation improvements: + +* :ref:`PEP 709 <whatsnew312-pep709>`, comprehension inlining +* :ref:`CPython support <perf_profiling>` for the Linux ``perf`` profiler +* Implement stack overflow protection on supported platforms + +New typing features: + +* :ref:`PEP 692 <whatsnew312-pep692>`, using :class:`~typing.TypedDict` to + annotate :term:`**kwargs <argument>` +* :ref:`PEP 698 <whatsnew312-pep698>`, :func:`typing.override` decorator + +Important deprecations, removals or restrictions: + +* :pep:`623`: Remove ``wstr`` from Unicode objects in Python's C API, + reducing the size of every :class:`str` object by at least 8 bytes. + +* :pep:`632`: Remove the :mod:`!distutils` package. + See `the migration guide <https://peps.python.org/pep-0632/#migration-advice>`_ + for advice replacing the APIs it provided. + The third-party `Setuptools <https://setuptools.pypa.io/en/latest/deprecated/distutils-legacy.html>`__ + package continues to provide :mod:`!distutils`, + if you still require it in Python 3.12 and beyond. + +* :gh:`95299`: Do not pre-install ``setuptools`` in virtual environments + created with :mod:`venv`. + This means that ``distutils``, ``setuptools``, ``pkg_resources``, + and ``easy_install`` will no longer available by default; to access these + run ``pip install setuptools`` in the :ref:`activated <venv-explanation>` + virtual environment. + +* The :mod:`!asynchat`, :mod:`!asyncore`, and :mod:`!imp` modules have been + removed, along with several :class:`unittest.TestCase` + `method aliases <unittest-TestCase-removed-aliases_>`_. + + +New Features +============ + +.. _whatsnew312-pep695: + +PEP 695: Type Parameter Syntax +------------------------------ + +Generic classes and functions under :pep:`484` were declared using a verbose syntax +that left the scope of type parameters unclear and required explicit declarations of +variance. + +:pep:`695` introduces a new, more compact and explicit way to create +:ref:`generic classes <generic-classes>` and :ref:`functions <generic-functions>`:: + + def max[T](args: Iterable[T]) -> T: + ... + + class list[T]: + def __getitem__(self, index: int, /) -> T: + ... + + def append(self, element: T) -> None: + ... + +In addition, the PEP introduces a new way to declare :ref:`type aliases <type-aliases>` +using the :keyword:`type` statement, which creates an instance of +:class:`~typing.TypeAliasType`:: + + type Point = tuple[float, float] + +Type aliases can also be :ref:`generic <generic-type-aliases>`:: + + type Point[T] = tuple[T, T] + +The new syntax allows declaring :class:`~typing.TypeVarTuple` +and :class:`~typing.ParamSpec` parameters, as well as :class:`~typing.TypeVar` +parameters with bounds or constraints:: + + type IntFunc[**P] = Callable[P, int] # ParamSpec + type LabeledTuple[*Ts] = tuple[str, *Ts] # TypeVarTuple + type HashableSequence[T: Hashable] = Sequence[T] # TypeVar with bound + type IntOrStrSequence[T: (int, str)] = Sequence[T] # TypeVar with constraints + +The value of type aliases and the bound and constraints of type variables +created through this syntax are evaluated only on demand (see +:ref:`lazy evaluation <lazy-evaluation>`). This means type aliases are able to +refer to other types defined later in the file. + +Type parameters declared through a type parameter list are visible within the +scope of the declaration and any nested scopes, but not in the outer scope. For +example, they can be used in the type annotations for the methods of a generic +class or in the class body. However, they cannot be used in the module scope after +the class is defined. See :ref:`type-params` for a detailed description of the +runtime semantics of type parameters. + +In order to support these scoping semantics, a new kind of scope is introduced, +the :ref:`annotation scope <annotation-scopes>`. Annotation scopes behave for the +most part like function scopes, but interact differently with enclosing class scopes. +In Python 3.13, :term:`annotations <annotation>` will also be evaluated in +annotation scopes. + +See :pep:`695` for more details. + +(PEP written by Eric Traut. Implementation by Jelle Zijlstra, Eric Traut, +and others in :gh:`103764`.) + +.. _whatsnew312-pep701: + +PEP 701: Syntactic formalization of f-strings +--------------------------------------------- + +:pep:`701` lifts some restrictions on the usage of :term:`f-strings <f-string>`. +Expression components inside f-strings can now be any valid Python expression, +including strings reusing the same quote as the containing f-string, +multi-line expressions, comments, backslashes, and unicode escape sequences. +Let's cover these in detail: + +* Quote reuse: in Python 3.11, reusing the same quotes as the enclosing f-string + raises a :exc:`SyntaxError`, forcing the user to either use other available + quotes (like using double quotes or triple quotes if the f-string uses single + quotes). In Python 3.12, you can now do things like this: + + >>> songs = ['Take me back to Eden', 'Alkaline', 'Ascensionism'] + >>> f"This is the playlist: {", ".join(songs)}" + 'This is the playlist: Take me back to Eden, Alkaline, Ascensionism' + + Note that before this change there was no explicit limit in how f-strings can + be nested, but the fact that string quotes cannot be reused inside the + expression component of f-strings made it impossible to nest f-strings + arbitrarily. In fact, this is the most nested f-string that could be written: + + >>> f"""{f'''{f'{f"{1+1}"}'}'''}""" + '2' + + As now f-strings can contain any valid Python expression inside expression + components, it is now possible to nest f-strings arbitrarily: + + >>> f"{f"{f"{f"{f"{f"{1+1}"}"}"}"}"}" + '2' + +* Multi-line expressions and comments: In Python 3.11, f-string expressions + must be defined in a single line, even if the expression within the f-string + could normally span multiple lines + (like literal lists being defined over multiple lines), + making them harder to read. In Python 3.12 you can now define f-strings + spanning multiple lines, and add inline comments: + + >>> f"This is the playlist: {", ".join([ + ... 'Take me back to Eden', # My, my, those eyes like fire + ... 'Alkaline', # Not acid nor alkaline + ... 'Ascensionism' # Take to the broken skies at last + ... ])}" + 'This is the playlist: Take me back to Eden, Alkaline, Ascensionism' + +* Backslashes and unicode characters: before Python 3.12 f-string expressions + couldn't contain any ``\`` character. This also affected unicode :ref:`escape + sequences <escape-sequences>` (such as ``\N{snowman}``) as these contain + the ``\N`` part that previously could not be part of expression components of + f-strings. Now, you can define expressions like this: + + >>> print(f"This is the playlist: {"\n".join(songs)}") + This is the playlist: Take me back to Eden + Alkaline + Ascensionism + >>> print(f"This is the playlist: {"\N{BLACK HEART SUIT}".join(songs)}") + This is the playlist: Take me back to Eden♥Alkaline♥Ascensionism + +See :pep:`701` for more details. + +As a positive side-effect of how this feature has been implemented (by parsing f-strings +with :pep:`the PEG parser <617>`, now error messages for f-strings are more precise +and include the exact location of the error. For example, in Python 3.11, the following +f-string raises a :exc:`SyntaxError`: + +.. code-block:: python + + >>> my_string = f"{x z y}" + f"{1 + 1}" + File "<stdin>", line 1 + (x z y) + ^^^ + SyntaxError: f-string: invalid syntax. Perhaps you forgot a comma? + +but the error message doesn't include the exact location of the error within the line and +also has the expression artificially surrounded by parentheses. In Python 3.12, as f-strings +are parsed with the PEG parser, error messages can be more precise and show the entire line: + +.. code-block:: python + + >>> my_string = f"{x z y}" + f"{1 + 1}" + File "<stdin>", line 1 + my_string = f"{x z y}" + f"{1 + 1}" + ^^^ + SyntaxError: invalid syntax. Perhaps you forgot a comma? + +(Contributed by Pablo Galindo, Batuhan Taskaya, Lysandros Nikolaou, Cristián +Maureira-Fredes and Marta Gómez in :gh:`102856`. PEP written by Pablo Galindo, +Batuhan Taskaya, Lysandros Nikolaou and Marta Gómez). + +.. _whatsnew312-pep684: + +PEP 684: A Per-Interpreter GIL +------------------------------ + +:pep:`684` introduces a per-interpreter :term:`GIL <global interpreter lock>`, +so that sub-interpreters may now be created with a unique GIL per interpreter. +This allows Python programs to take full advantage of multiple CPU +cores. This is currently only available through the C-API, +though a Python API is :pep:`anticipated for 3.13 <554>`. + +Use the new :c:func:`Py_NewInterpreterFromConfig` function to +create an interpreter with its own GIL:: + + PyInterpreterConfig config = { + .check_multi_interp_extensions = 1, + .gil = PyInterpreterConfig_OWN_GIL, + }; + PyThreadState *tstate = NULL; + PyStatus status = Py_NewInterpreterFromConfig(&tstate, &config); + if (PyStatus_Exception(status)) { + return -1; + } + /* The new interpeter is now active in the current thread. */ + +For further examples how to use the C-API for sub-interpreters with a +per-interpreter GIL, see :source:`Modules/_xxsubinterpretersmodule.c`. + +(Contributed by Eric Snow in :gh:`104210`, etc.) + +.. _whatsnew312-pep669: + +PEP 669: Low impact monitoring for CPython +------------------------------------------ + +:pep:`669` defines a new :mod:`API <sys.monitoring>` for profilers, +debuggers, and other tools to monitor events in CPython. +It covers a wide range of events, including calls, +returns, lines, exceptions, jumps, and more. +This means that you only pay for what you use, providing support +for near-zero overhead debuggers and coverage tools. +See :mod:`sys.monitoring` for details. + +(Contributed by Mark Shannon in :gh:`103082`.) + +.. _whatsnew312-pep688: + +PEP 688: Making the buffer protocol accessible in Python +-------------------------------------------------------- + +:pep:`688` introduces a way to use the :ref:`buffer protocol <bufferobjects>` +from Python code. Classes that implement the :meth:`~object.__buffer__` method +are now usable as buffer types. + +The new :class:`collections.abc.Buffer` ABC provides a standard +way to represent buffer objects, for example in type annotations. +The new :class:`inspect.BufferFlags` enum represents the flags that +can be used to customize buffer creation. +(Contributed by Jelle Zijlstra in :gh:`102500`.) + +.. _whatsnew312-pep709: + +PEP 709: Comprehension inlining +------------------------------- + +Dictionary, list, and set comprehensions are now inlined, rather than creating a +new single-use function object for each execution of the comprehension. This +speeds up execution of a comprehension by up to two times. +See :pep:`709` for further details. + +Comprehension iteration variables remain isolated and don't overwrite a +variable of the same name in the outer scope, nor are they visible after the +comprehension. Inlining does result in a few visible behavior changes: + +* There is no longer a separate frame for the comprehension in tracebacks, + and tracing/profiling no longer shows the comprehension as a function call. +* The :mod:`symtable` module will no longer produce child symbol tables for each + comprehension; instead, the comprehension's locals will be included in the + parent function's symbol table. +* Calling :func:`locals` inside a comprehension now includes variables + from outside the comprehension, and no longer includes the synthetic ``.0`` + variable for the comprehension "argument". +* A comprehension iterating directly over ``locals()`` (e.g. ``[k for k in + locals()]``) may see "RuntimeError: dictionary changed size during iteration" + when run under tracing (e.g. code coverage measurement). This is the same + behavior already seen in e.g. ``for k in locals():``. To avoid the error, first + create a list of keys to iterate over: ``keys = list(locals()); [k for k in + keys]``. + +(Contributed by Carl Meyer and Vladimir Matveev in :pep:`709`.) + +Improved Error Messages +----------------------- + +* Modules from the standard library are now potentially suggested as part of + the error messages displayed by the interpreter when a :exc:`NameError` is + raised to the top level. (Contributed by Pablo Galindo in :gh:`98254`.) + + >>> sys.version_info + Traceback (most recent call last): + File "<stdin>", line 1, in <module> + NameError: name 'sys' is not defined. Did you forget to import 'sys'? + +* Improve the error suggestion for :exc:`NameError` exceptions for instances. + Now if a :exc:`NameError` is raised in a method and the instance has an + attribute that's exactly equal to the name in the exception, the suggestion + will include ``self.<NAME>`` instead of the closest match in the method + scope. (Contributed by Pablo Galindo in :gh:`99139`.) + + >>> class A: + ... def __init__(self): + ... self.blech = 1 + ... + ... def foo(self): + ... somethin = blech + ... + >>> A().foo() + Traceback (most recent call last): + File "<stdin>", line 1 + somethin = blech + ^^^^^ + NameError: name 'blech' is not defined. Did you mean: 'self.blech'? + +* Improve the :exc:`SyntaxError` error message when the user types ``import x + from y`` instead of ``from y import x``. (Contributed by Pablo Galindo in :gh:`98931`.) + + >>> import a.y.z from b.y.z + Traceback (most recent call last): + File "<stdin>", line 1 + import a.y.z from b.y.z + ^^^^^^^^^^^^^^^^^^^^^^^ + SyntaxError: Did you mean to use 'from ... import ...' instead? + +* :exc:`ImportError` exceptions raised from failed ``from <module> import + <name>`` statements now include suggestions for the value of ``<name>`` based on the + available names in ``<module>``. (Contributed by Pablo Galindo in :gh:`91058`.) + + >>> from collections import chainmap + Traceback (most recent call last): + File "<stdin>", line 1, in <module> + ImportError: cannot import name 'chainmap' from 'collections'. Did you mean: 'ChainMap'? + + +New Features Related to Type Hints +================================== + +This section covers major changes affecting :pep:`type hints <484>` and +the :mod:`typing` module. + +.. _whatsnew312-pep692: + +PEP 692: Using ``TypedDict`` for more precise ``**kwargs`` typing +----------------------------------------------------------------- + +Typing ``**kwargs`` in a function signature as introduced by :pep:`484` allowed +for valid annotations only in cases where all of the ``**kwargs`` were of the +same type. + +:pep:`692` specifies a more precise way of typing ``**kwargs`` by relying on +typed dictionaries:: + + from typing import TypedDict, Unpack + + class Movie(TypedDict): + name: str + year: int + + def foo(**kwargs: Unpack[Movie]): ... + +See :pep:`692` for more details. + +(Contributed by Franek Magiera in :gh:`103629`.) + +.. _whatsnew312-pep698: + +PEP 698: Override Decorator for Static Typing +--------------------------------------------- + +A new decorator :func:`typing.override` has been added to the :mod:`typing` +module. It indicates to type checkers that the method is intended to override +a method in a superclass. This allows type checkers to catch mistakes where +a method that is intended to override something in a base class +does not in fact do so. + +Example:: + + from typing import override + + class Base: + def get_color(self) -> str: + return "blue" + + class GoodChild(Base): + @override # ok: overrides Base.get_color + def get_color(self) -> str: + return "yellow" + + class BadChild(Base): + @override # type checker error: does not override Base.get_color + def get_colour(self) -> str: + return "red" + +See :pep:`698` for more details. + +(Contributed by Steven Troxler in :gh:`101561`.) + +Other Language Changes +====================== + +* The parser now raises :exc:`SyntaxError` when parsing source code containing + null bytes. (Contributed by Pablo Galindo in :gh:`96670`.) + +* A backslash-character pair that is not a valid escape sequence now generates + a :exc:`SyntaxWarning`, instead of :exc:`DeprecationWarning`. + For example, ``re.compile("\d+\.\d+")`` now emits a :exc:`SyntaxWarning` + (``"\d"`` is an invalid escape sequence, use raw strings for regular + expression: ``re.compile(r"\d+\.\d+")``). + In a future Python version, :exc:`SyntaxError` will eventually be raised, + instead of :exc:`SyntaxWarning`. + (Contributed by Victor Stinner in :gh:`98401`.) + +* Octal escapes with value larger than ``0o377`` (ex: ``"\477"``), deprecated + in Python 3.11, now produce a :exc:`SyntaxWarning`, instead of + :exc:`DeprecationWarning`. + In a future Python version they will be eventually a :exc:`SyntaxError`. + (Contributed by Victor Stinner in :gh:`98401`.) + +* Variables used in the target part of comprehensions that are not stored to + can now be used in assignment expressions (``:=``). + For example, in ``[(b := 1) for a, b.prop in some_iter]``, the assignment to + ``b`` is now allowed. Note that assigning to variables stored to in the target + part of comprehensions (like ``a``) is still disallowed, as per :pep:`572`. + (Contributed by Nikita Sobolev in :gh:`100581`.) + +* Exceptions raised in a class or type's ``__set_name__`` method are no longer + wrapped by a :exc:`RuntimeError`. Context information is added to the + exception as a :pep:`678` note. (Contributed by Irit Katriel in :gh:`77757`.) + +* When a ``try-except*`` construct handles the entire :exc:`ExceptionGroup` + and raises one other exception, that exception is no longer wrapped in an + :exc:`ExceptionGroup`. Also changed in version 3.11.4. (Contributed by Irit + Katriel in :gh:`103590`.) + +* The Garbage Collector now runs only on the eval breaker mechanism of the + Python bytecode evaluation loop instead of object allocations. The GC can + also run when :c:func:`PyErr_CheckSignals` is called so C extensions that + need to run for a long time without executing any Python code also have a + chance to execute the GC periodically. (Contributed by Pablo Galindo in + :gh:`97922`.) + +* All builtin and extension callables expecting boolean parameters now accept + arguments of any type instead of just :class:`bool` and :class:`int`. + (Contributed by Serhiy Storchaka in :gh:`60203`.) + +* :class:`memoryview` now supports the half-float type (the "e" format code). + (Contributed by Donghee Na and Antoine Pitrou in :gh:`90751`.) + +* :class:`slice` objects are now hashable, allowing them to be used as dict keys and + set items. (Contributed by Will Bradshaw, Furkan Onder, and Raymond Hettinger in :gh:`101264`.) + +* :func:`sum` now uses Neumaier summation to improve accuracy and commutativity + when summing floats or mixed ints and floats. + (Contributed by Raymond Hettinger in :gh:`100425`.) + +* :func:`ast.parse` now raises :exc:`SyntaxError` instead of :exc:`ValueError` + when parsing source code containing null bytes. (Contributed by Pablo Galindo + in :gh:`96670`.) + +* The extraction methods in :mod:`tarfile`, and :func:`shutil.unpack_archive`, + have a new a *filter* argument that allows limiting tar features than may be + surprising or dangerous, such as creating files outside the destination + directory. + See :ref:`tarfile extraction filters <tarfile-extraction-filter>` for details. + In Python 3.14, the default will switch to ``'data'``. + (Contributed by Petr Viktorin in :pep:`706`.) + +* :class:`types.MappingProxyType` instances are now hashable if the underlying + mapping is hashable. + (Contributed by Serhiy Storchaka in :gh:`87995`.) + +* Add :ref:`support for the perf profiler <perf_profiling>` through the new + environment variable :envvar:`PYTHONPERFSUPPORT` + and command-line option :option:`-X perf <-X>`, + as well as the new :func:`sys.activate_stack_trampoline`, + :func:`sys.deactivate_stack_trampoline`, + and :func:`sys.is_stack_trampoline_active` functions. + (Design by Pablo Galindo. Contributed by Pablo Galindo and Christian Heimes + with contributions from Gregory P. Smith [Google] and Mark Shannon + in :gh:`96123`.) + + +New Modules +=========== + +* None. + + +Improved Modules +================ + +array +----- + +* The :class:`array.array` class now supports subscripting, making it a + :term:`generic type`. (Contributed by Jelle Zijlstra in :gh:`98658`.) + +asyncio +------- + +* The performance of writing to sockets in :mod:`asyncio` has been + significantly improved. ``asyncio`` now avoids unnecessary copying when + writing to sockets and uses :meth:`~socket.socket.sendmsg` if the platform + supports it. (Contributed by Kumar Aditya in :gh:`91166`.) + +* Add :func:`asyncio.eager_task_factory` and :func:`asyncio.create_eager_task_factory` + functions to allow opting an event loop in to eager task execution, + making some use-cases 2x to 5x faster. + (Contributed by Jacob Bower & Itamar Oren in :gh:`102853`, :gh:`104140`, and :gh:`104138`) + +* On Linux, :mod:`asyncio` uses :class:`asyncio.PidfdChildWatcher` by default + if :func:`os.pidfd_open` is available and functional instead of + :class:`asyncio.ThreadedChildWatcher`. + (Contributed by Kumar Aditya in :gh:`98024`.) + +* The event loop now uses the best available child watcher for each platform + (:class:`asyncio.PidfdChildWatcher` if supported and + :class:`asyncio.ThreadedChildWatcher` otherwise), so manually + configuring a child watcher is not recommended. + (Contributed by Kumar Aditya in :gh:`94597`.) + +* Add *loop_factory* parameter to :func:`asyncio.run` to allow specifying + a custom event loop factory. + (Contributed by Kumar Aditya in :gh:`99388`.) + +* Add C implementation of :func:`asyncio.current_task` for 4x-6x speedup. + (Contributed by Itamar Oren and Pranav Thulasiram Bhat in :gh:`100344`.) + +* :func:`asyncio.iscoroutine` now returns ``False`` for generators as + :mod:`asyncio` does not support legacy generator-based coroutines. + (Contributed by Kumar Aditya in :gh:`102748`.) + +* :func:`asyncio.wait` and :func:`asyncio.as_completed` now accepts generators + yielding tasks. + (Contributed by Kumar Aditya in :gh:`78530`.) + +calendar +-------- + +* Add enums :data:`calendar.Month` and :data:`calendar.Day` + defining months of the year and days of the week. + (Contributed by Prince Roshan in :gh:`103636`.) + +csv +--- + +* Add :const:`csv.QUOTE_NOTNULL` and :const:`csv.QUOTE_STRINGS` flags to + provide finer grained control of ``None`` and empty strings by + :class:`csv.writer` objects. + +dis +--- + +* Pseudo instruction opcodes (which are used by the compiler but + do not appear in executable bytecode) are now exposed in the + :mod:`dis` module. + :opcode:`HAVE_ARGUMENT` is still relevant to real opcodes, + but it is not useful for pseudo instructions. Use the new + :data:`dis.hasarg` collection instead. + (Contributed by Irit Katriel in :gh:`94216`.) + +* Add the :data:`dis.hasexc` collection to signify instructions that set + an exception handler. (Contributed by Irit Katriel in :gh:`94216`.) + +fractions +--------- + +* Objects of type :class:`fractions.Fraction` now support float-style + formatting. (Contributed by Mark Dickinson in :gh:`100161`.) + +importlib.resources +------------------- + +* :func:`importlib.resources.as_file` now supports resource directories. + (Contributed by Jason R. Coombs in :gh:`97930`.) + +inspect +------- + +* Add :func:`inspect.markcoroutinefunction` to mark sync functions that return + a :term:`coroutine` for use with :func:`inspect.iscoroutinefunction`. + (Contributed Carlton Gibson in :gh:`99247`.) + +* Add :func:`inspect.getasyncgenstate` and :func:`inspect.getasyncgenlocals` + for determining the current state of asynchronous generators. + (Contributed by Thomas Krennwallner in :gh:`79940`.) + +* The performance of :func:`inspect.getattr_static` has been considerably + improved. Most calls to the function should be at least 2x faster than they + were in Python 3.11, and some may be 6x faster or more. (Contributed by Alex + Waygood in :gh:`103193`.) + +itertools +--------- + +* Add :class:`itertools.batched()` for collecting into even-sized + tuples where the last batch may be shorter than the rest. + (Contributed by Raymond Hettinger in :gh:`98363`.) + +math +---- + +* Add :func:`math.sumprod` for computing a sum of products. + (Contributed by Raymond Hettinger in :gh:`100485`.) + +* Extend :func:`math.nextafter` to include a *steps* argument + for moving up or down multiple steps at a time. + (By Matthias Goergens, Mark Dickinson, and Raymond Hettinger in :gh:`94906`.) + +os +-- + +* Add :const:`os.PIDFD_NONBLOCK` to open a file descriptor + for a process with :func:`os.pidfd_open` in non-blocking mode. + (Contributed by Kumar Aditya in :gh:`93312`.) + +* :class:`os.DirEntry` now includes an :meth:`os.DirEntry.is_junction` + method to check if the entry is a junction. + (Contributed by Charles Machalow in :gh:`99547`.) + +* Add :func:`os.listdrives`, :func:`os.listvolumes` and :func:`os.listmounts` + functions on Windows for enumerating drives, volumes and mount points. + (Contributed by Steve Dower in :gh:`102519`.) + +* :func:`os.stat` and :func:`os.lstat` are now more accurate on Windows. + The ``st_birthtime`` field will now be filled with the creation time + of the file, and ``st_ctime`` is deprecated but still contains the + creation time (but in the future will return the last metadata change, + for consistency with other platforms). ``st_dev`` may be up to 64 bits + and ``st_ino`` up to 128 bits depending on your file system, and + ``st_rdev`` is always set to zero rather than incorrect values. + Both functions may be significantly faster on newer releases of + Windows. (Contributed by Steve Dower in :gh:`99726`.) + +os.path +------- + +* Add :func:`os.path.isjunction` to check if a given path is a junction. + (Contributed by Charles Machalow in :gh:`99547`.) + +* Add :func:`os.path.splitroot` to split a path into a triad + ``(drive, root, tail)``. (Contributed by Barney Gale in :gh:`101000`.) + +pathlib +------- + +* Add support for subclassing :class:`pathlib.PurePath` and + :class:`pathlib.Path`, plus their Posix- and Windows-specific variants. + Subclasses may override the :meth:`pathlib.PurePath.with_segments` method + to pass information between path instances. + +* Add :meth:`pathlib.Path.walk` for walking the directory trees and generating + all file or directory names within them, similar to :func:`os.walk`. + (Contributed by Stanislav Zmiev in :gh:`90385`.) + +* Add *walk_up* optional parameter to :meth:`pathlib.PurePath.relative_to` + to allow the insertion of ``..`` entries in the result; this behavior is + more consistent with :func:`os.path.relpath`. + (Contributed by Domenico Ragusa in :gh:`84538`.) + +* Add :meth:`pathlib.Path.is_junction` as a proxy to :func:`os.path.isjunction`. + (Contributed by Charles Machalow in :gh:`99547`.) + +* Add *case_sensitive* optional parameter to :meth:`pathlib.Path.glob`, + :meth:`pathlib.Path.rglob` and :meth:`pathlib.PurePath.match` for matching + the path's case sensitivity, allowing for more precise control over the matching process. + +pdb +--- + +* Add convenience variables to hold values temporarily for debug session + and provide quick access to values like the current frame or the return + value. + (Contributed by Tian Gao in :gh:`103693`.) + +random +------ + +* Add :func:`random.binomialvariate`. + (Contributed by Raymond Hettinger in :gh:`81620`.) + +* Add a default of ``lambd=1.0`` to :func:`random.expovariate`. + (Contributed by Raymond Hettinger in :gh:`100234`.) + +shutil +------ + +* :func:`shutil.make_archive` now passes the *root_dir* argument to custom + archivers which support it. + In this case it no longer temporarily changes the current working directory + of the process to *root_dir* to perform archiving. + (Contributed by Serhiy Storchaka in :gh:`74696`.) + +* :func:`shutil.rmtree` now accepts a new argument *onexc* which is an + error handler like *onerror* but which expects an exception instance + rather than a *(typ, val, tb)* triplet. *onerror* is deprecated and + will be removed in Python 3.14. + (Contributed by Irit Katriel in :gh:`102828`.) + +* :func:`shutil.which` now consults the *PATHEXT* environment variable to + find matches within *PATH* on Windows even when the given *cmd* includes + a directory component. + (Contributed by Charles Machalow in :gh:`103179`.) + + :func:`shutil.which` will call ``NeedCurrentDirectoryForExePathW`` when + querying for executables on Windows to determine if the current working + directory should be prepended to the search path. + (Contributed by Charles Machalow in :gh:`103179`.) + + :func:`shutil.which` will return a path matching the *cmd* with a component + from ``PATHEXT`` prior to a direct match elsewhere in the search path on + Windows. + (Contributed by Charles Machalow in :gh:`103179`.) + +sqlite3 +------- + +* Add a :ref:`command-line interface <sqlite3-cli>`. + (Contributed by Erlend E. Aasland in :gh:`77617`.) + +* Add the :attr:`sqlite3.Connection.autocommit` attribute + to :class:`sqlite3.Connection` + and the *autocommit* parameter to :func:`sqlite3.connect` + to control :pep:`249`-compliant + :ref:`transaction handling <sqlite3-transaction-control-autocommit>`. + (Contributed by Erlend E. Aasland in :gh:`83638`.) + +* Add *entrypoint* keyword-only parameter to + :meth:`sqlite3.Connection.load_extension`, + for overriding the SQLite extension entry point. + (Contributed by Erlend E. Aasland in :gh:`103015`.) + +* Add :meth:`sqlite3.Connection.getconfig` and + :meth:`sqlite3.Connection.setconfig` to :class:`sqlite3.Connection` + to make configuration changes to a database connection. + (Contributed by Erlend E. Aasland in :gh:`103489`.) + +statistics +---------- + +* Extend :func:`statistics.correlation` to include as a ``ranked`` method + for computing the Spearman correlation of ranked data. + (Contributed by Raymond Hettinger in :gh:`95861`.) + +sys +--- + +* Add the :mod:`sys.monitoring` namespace to expose the new :ref:`PEP 669 + <whatsnew312-pep669>` monitoring API. + (Contributed by Mark Shannon in :gh:`103082`.) + +* Add :func:`sys.activate_stack_trampoline` and + :func:`sys.deactivate_stack_trampoline` for activating and deactivating + stack profiler trampolines, + and :func:`sys.is_stack_trampoline_active` for querying if stack profiler + trampolines are active. + (Contributed by Pablo Galindo and Christian Heimes + with contributions from Gregory P. Smith [Google] and Mark Shannon + in :gh:`96123`.) + +* Add :data:`sys.last_exc` which holds the last unhandled exception that + was raised (for post-mortem debugging use cases). Deprecate the + three fields that have the same information in its legacy form: + :data:`sys.last_type`, :data:`sys.last_value` and :data:`sys.last_traceback`. + (Contributed by Irit Katriel in :gh:`102778`.) + +* :func:`sys._current_exceptions` now returns a mapping from thread-id to an + exception instance, rather than to a ``(typ, exc, tb)`` tuple. + (Contributed by Irit Katriel in :gh:`103176`.) + +* :func:`sys.setrecursionlimit` and :func:`sys.getrecursionlimit`. + The recursion limit now applies only to Python code. Builtin functions do + not use the recursion limit, but are protected by a different mechanism + that prevents recursion from causing a virtual machine crash. + +tempfile +-------- + +* The :class:`tempfile.NamedTemporaryFile` function has a new optional parameter + *delete_on_close* (Contributed by Evgeny Zorin in :gh:`58451`.) +* :func:`tempfile.mkdtemp` now always returns an absolute path, even if the + argument provided to the *dir* parameter is a relative path. + +.. _whatsnew-typing-py312: + +threading +--------- + +* Add :func:`threading.settrace_all_threads` and + :func:`threading.setprofile_all_threads` that allow to set tracing and + profiling functions in all running threads in addition to the calling one. + (Contributed by Pablo Galindo in :gh:`93503`.) + +tkinter +------- + +* ``tkinter.Canvas.coords()`` now flattens its arguments. + It now accepts not only coordinates as separate arguments + (``x1, y1, x2, y2, ...``) and a sequence of coordinates + (``[x1, y1, x2, y2, ...]``), but also coordinates grouped in pairs + (``(x1, y1), (x2, y2), ...`` and ``[(x1, y1), (x2, y2), ...]``), + like ``create_*()`` methods. + (Contributed by Serhiy Storchaka in :gh:`94473`.) + +tokenize +-------- + +* The :mod:`tokenize` module includes the changes introduced in :pep:`701`. + (Contributed by Marta Gómez Macías and Pablo Galindo in :gh:`102856`.) + See :ref:`whatsnew312-porting-to-python312` for more information on the + changes to the :mod:`tokenize` module. + +types +----- + +* Add :func:`types.get_original_bases` to allow for further introspection of + :ref:`user-defined-generics` when subclassed. (Contributed by + James Hilton-Balfe and Alex Waygood in :gh:`101827`.) + +typing +------ + +* :func:`isinstance` checks against + :func:`runtime-checkable protocols <typing.runtime_checkable>` now use + :func:`inspect.getattr_static` rather than :func:`hasattr` to lookup whether + attributes exist. This means that descriptors and :meth:`~object.__getattr__` + methods are no longer unexpectedly evaluated during ``isinstance()`` checks + against runtime-checkable protocols. However, it may also mean that some + objects which used to be considered instances of a runtime-checkable protocol + may no longer be considered instances of that protocol on Python 3.12+, and + vice versa. Most users are unlikely to be affected by this change. + (Contributed by Alex Waygood in :gh:`102433`.) + +* The members of a runtime-checkable protocol are now considered "frozen" at + runtime as soon as the class has been created. Monkey-patching attributes + onto a runtime-checkable protocol will still work, but will have no impact on + :func:`isinstance` checks comparing objects to the protocol. For example:: + + >>> from typing import Protocol, runtime_checkable + >>> @runtime_checkable + ... class HasX(Protocol): + ... x = 1 + ... + >>> class Foo: ... + ... + >>> f = Foo() + >>> isinstance(f, HasX) + False + >>> f.x = 1 + >>> isinstance(f, HasX) + True + >>> HasX.y = 2 + >>> isinstance(f, HasX) # unchanged, even though HasX now also has a "y" attribute + True + + This change was made in order to speed up ``isinstance()`` checks against + runtime-checkable protocols. + +* The performance profile of :func:`isinstance` checks against + :func:`runtime-checkable protocols <typing.runtime_checkable>` has changed + significantly. Most ``isinstance()`` checks against protocols with only a few + members should be at least 2x faster than in 3.11, and some may be 20x + faster or more. However, ``isinstance()`` checks against protocols with fourteen + or more members may be slower than in Python 3.11. (Contributed by Alex + Waygood in :gh:`74690` and :gh:`103193`.) + +* All :data:`typing.TypedDict` and :data:`typing.NamedTuple` classes now have the + ``__orig_bases__`` attribute. (Contributed by Adrian Garcia Badaracco in + :gh:`103699`.) + +* Add ``frozen_default`` parameter to :func:`typing.dataclass_transform`. + (Contributed by Erik De Bonte in :gh:`99957`.) + +unicodedata +----------- + +* The Unicode database has been updated to version 15.0.0. (Contributed by + Benjamin Peterson in :gh:`96734`). + +unittest +-------- + +Add a ``--durations`` command line option, showing the N slowest test cases:: + + python3 -m unittest --durations=3 lib.tests.test_threading + ..... + Slowest test durations + ---------------------------------------------------------------------- + 1.210s test_timeout (Lib.test.test_threading.BarrierTests) + 1.003s test_default_timeout (Lib.test.test_threading.BarrierTests) + 0.518s test_timeout (Lib.test.test_threading.EventTests) + + (0.000 durations hidden. Use -v to show these durations.) + ---------------------------------------------------------------------- + Ran 158 tests in 9.869s + + OK (skipped=3) + +(Contributed by Giampaolo Rodola in :gh:`48330`) + +uuid +---- + +* Add a :ref:`command-line interface <uuid-cli>`. + (Contributed by Adam Chhina in :gh:`88597`.) + + +Optimizations +============= + +* Remove ``wstr`` and ``wstr_length`` members from Unicode objects. + It reduces object size by 8 or 16 bytes on 64bit platform. (:pep:`623`) + (Contributed by Inada Naoki in :gh:`92536`.) + +* Add experimental support for using the BOLT binary optimizer in the build + process, which improves performance by 1-5%. + (Contributed by Kevin Modzelewski in :gh:`90536` and tuned by Donghee Na in :gh:`101525`) + +* Speed up the regular expression substitution (functions :func:`re.sub` and + :func:`re.subn` and corresponding :class:`!re.Pattern` methods) for + replacement strings containing group references by 2--3 times. + (Contributed by Serhiy Storchaka in :gh:`91524`.) + +* Speed up :class:`asyncio.Task` creation by deferring expensive string formatting. + (Contributed by Itamar Oren in :gh:`103793`.) + +* The :func:`tokenize.tokenize` and :func:`tokenize.generate_tokens` functions are + up to 64% faster as a side effect of the changes required to cover :pep:`701` in + the :mod:`tokenize` module. (Contributed by Marta Gómez Macías and Pablo Galindo + in :gh:`102856`.) + +* Speed up :func:`super` method calls and attribute loads via the + new :opcode:`LOAD_SUPER_ATTR` instruction. (Contributed by Carl Meyer and + Vladimir Matveev in :gh:`103497`.) + + +CPython bytecode changes +======================== + +* Remove the :opcode:`!LOAD_METHOD` instruction. It has been merged into + :opcode:`LOAD_ATTR`. :opcode:`LOAD_ATTR` will now behave like the old + :opcode:`!LOAD_METHOD` instruction if the low bit of its oparg is set. + (Contributed by Ken Jin in :gh:`93429`.) + +* Remove the :opcode:`!JUMP_IF_FALSE_OR_POP` and :opcode:`!JUMP_IF_TRUE_OR_POP` + instructions. (Contributed by Irit Katriel in :gh:`102859`.) + +* Remove the :opcode:`!PRECALL` instruction. (Contributed by Mark Shannon in + :gh:`92925`.) + +* Add the :opcode:`BINARY_SLICE` and :opcode:`STORE_SLICE` instructions. + (Contributed by Mark Shannon in :gh:`94163`.) + +* Add the :opcode:`CALL_INTRINSIC_1` instructions. + (Contributed by Mark Shannon in :gh:`99005`.) + +* Add the :opcode:`CALL_INTRINSIC_2` instruction. + (Contributed by Irit Katriel in :gh:`101799`.) + +* Add the :opcode:`CLEANUP_THROW` instruction. + (Contributed by Brandt Bucher in :gh:`90997`.) + +* Add the :opcode:`!END_SEND` instruction. + (Contributed by Mark Shannon in :gh:`103082`.) + +* Add the :opcode:`LOAD_FAST_AND_CLEAR` instruction as part of the + implementation of :pep:`709`. (Contributed by Carl Meyer in :gh:`101441`.) + +* Add the :opcode:`LOAD_FAST_CHECK` instruction. + (Contributed by Dennis Sweeney in :gh:`93143`.) + +* Add the :opcode:`LOAD_FROM_DICT_OR_DEREF`, :opcode:`LOAD_FROM_DICT_OR_GLOBALS`, + and :opcode:`LOAD_LOCALS` opcodes as part of the implementation of :pep:`695`. + Remove the :opcode:`!LOAD_CLASSDEREF` opcode, which can be replaced with + :opcode:`LOAD_LOCALS` plus :opcode:`LOAD_FROM_DICT_OR_DEREF`. (Contributed + by Jelle Zijlstra in :gh:`103764`.) + +* Add the :opcode:`LOAD_SUPER_ATTR` instruction. (Contributed by Carl Meyer and + Vladimir Matveev in :gh:`103497`.) + +* Add the :opcode:`RETURN_CONST` instruction. (Contributed by Wenyang Wang in :gh:`101632`.) + +Demos and Tools +=============== + +* Remove the ``Tools/demo/`` directory which contained old demo scripts. A copy + can be found in the `old-demos project + <https://github.com/gvanrossum/old-demos>`_. + (Contributed by Victor Stinner in :gh:`97681`.) + +* Remove outdated example scripts of the ``Tools/scripts/`` directory. + A copy can be found in the `old-demos project + <https://github.com/gvanrossum/old-demos>`_. + (Contributed by Victor Stinner in :gh:`97669`.) + + +Deprecated +========== + +* :mod:`argparse`: The *type*, *choices*, and *metavar* parameters + of :class:`!argparse.BooleanOptionalAction` are deprecated + and will be removed in 3.14. + (Contributed by Nikita Sobolev in :gh:`92248`.) + +* :mod:`ast`: The following :mod:`ast` features have been deprecated in documentation since + Python 3.8, now cause a :exc:`DeprecationWarning` to be emitted at runtime + when they are accessed or used, and will be removed in Python 3.14: + + * :class:`!ast.Num` + * :class:`!ast.Str` + * :class:`!ast.Bytes` + * :class:`!ast.NameConstant` + * :class:`!ast.Ellipsis` + + Use :class:`ast.Constant` instead. + (Contributed by Serhiy Storchaka in :gh:`90953`.) + +* :mod:`asyncio`: + + * The child watcher classes :class:`asyncio.MultiLoopChildWatcher`, + :class:`asyncio.FastChildWatcher`, :class:`asyncio.AbstractChildWatcher` + and :class:`asyncio.SafeChildWatcher` are deprecated and + will be removed in Python 3.14. + (Contributed by Kumar Aditya in :gh:`94597`.) + + * :func:`asyncio.set_child_watcher`, :func:`asyncio.get_child_watcher`, + :meth:`asyncio.AbstractEventLoopPolicy.set_child_watcher` and + :meth:`asyncio.AbstractEventLoopPolicy.get_child_watcher` are deprecated + and will be removed in Python 3.14. + (Contributed by Kumar Aditya in :gh:`94597`.) + + * The :meth:`~asyncio.get_event_loop` method of the + default event loop policy now emits a :exc:`DeprecationWarning` if there + is no current event loop set and it decides to create one. + (Contributed by Serhiy Storchaka and Guido van Rossum in :gh:`100160`.) + +* :mod:`calendar`: ``calendar.January`` and ``calendar.February`` constants are deprecated and + replaced by :data:`calendar.JANUARY` and :data:`calendar.FEBRUARY`. + (Contributed by Prince Roshan in :gh:`103636`.) + +* :mod:`collections.abc`: Deprecated :class:`collections.abc.ByteString`. + Prefer :class:`Sequence` or :class:`collections.abc.Buffer`. + For use in typing, prefer a union, like ``bytes | bytearray``, or :class:`collections.abc.Buffer`. + (Contributed by Shantanu Jain in :gh:`91896`.) + +* :mod:`datetime`: :class:`datetime.datetime`'s :meth:`~datetime.datetime.utcnow` and + :meth:`~datetime.datetime.utcfromtimestamp` are deprecated and will be + removed in a future version. Instead, use timezone-aware objects to represent + datetimes in UTC: respectively, call :meth:`~datetime.datetime.now` and + :meth:`~datetime.datetime.fromtimestamp` with the *tz* parameter set to + :const:`datetime.UTC`. + (Contributed by Paul Ganssle in :gh:`103857`.) + +* :mod:`email`: Deprecate the *isdst* parameter in :func:`email.utils.localtime`. + (Contributed by Alan Williams in :gh:`72346`.) + +* :mod:`importlib.abc`: Deprecated the following classes, scheduled for removal in + Python 3.14: + + * :class:`!importlib.abc.ResourceReader` + * :class:`!importlib.abc.Traversable` + * :class:`!importlib.abc.TraversableResources` + + Use :mod:`importlib.resources.abc` classes instead: + + * :class:`importlib.resources.abc.Traversable` + * :class:`importlib.resources.abc.TraversableResources` + + (Contributed by Jason R. Coombs and Hugo van Kemenade in :gh:`93963`.) + +* :mod:`itertools`: Deprecate the support for copy, deepcopy, and pickle operations, + which is undocumented, inefficient, historically buggy, and inconsistent. + This will be removed in 3.14 for a significant reduction in code + volume and maintenance burden. + (Contributed by Raymond Hettinger in :gh:`101588`.) + +* :mod:`multiprocessing`: In Python 3.14, the default :mod:`multiprocessing` + start method will change to a safer one on Linux, BSDs, + and other non-macOS POSIX platforms where ``'fork'`` is currently + the default (:gh:`84559`). Adding a runtime warning about this was deemed too + disruptive as the majority of code is not expected to care. Use the + :func:`~multiprocessing.get_context` or + :func:`~multiprocessing.set_start_method` APIs to explicitly specify when + your code *requires* ``'fork'``. See :ref:`contexts and start methods + <multiprocessing-start-methods>`. + +* :mod:`pkgutil`: :func:`pkgutil.find_loader` and :func:`pkgutil.get_loader` + are deprecated and will be removed in Python 3.14; + use :func:`importlib.util.find_spec` instead. + (Contributed by Nikita Sobolev in :gh:`97850`.) + +* :mod:`pty`: The module has two undocumented ``master_open()`` and ``slave_open()`` + functions that have been deprecated since Python 2 but only gained a + proper :exc:`DeprecationWarning` in 3.12. Remove them in 3.14. + (Contributed by Soumendra Ganguly and Gregory P. Smith in :gh:`85984`.) + +* :mod:`os`: + + * The ``st_ctime`` fields return by :func:`os.stat` and :func:`os.lstat` on + Windows are deprecated. In a future release, they will contain the last + metadata change time, consistent with other platforms. For now, they still + contain the creation time, which is also available in the new ``st_birthtime`` + field. (Contributed by Steve Dower in :gh:`99726`.) + + * On POSIX platforms, :func:`os.fork` can now raise a + :exc:`DeprecationWarning` when it can detect being called from a + multithreaded process. There has always been a fundamental incompatibility + with the POSIX platform when doing so. Even if such code *appeared* to work. + We added the warning to to raise awareness as issues encounted by code doing + this are becoming more frequent. See the :func:`os.fork` documentation for + more details along with `this discussion on fork being incompatible with threads + <https://discuss.python.org/t/33555>`_ for *why* we're now surfacing this + longstanding platform compatibility problem to developers. + + When this warning appears due to usage of :mod:`multiprocessing` or + :mod:`concurrent.futures` the fix is to use a different + :mod:`multiprocessing` start method such as ``"spawn"`` or ``"forkserver"``. + +* :mod:`shutil`: The *onerror* argument of :func:`shutil.rmtree` is deprecated and will be removed + in Python 3.14. Use *onexc* instead. (Contributed by Irit Katriel in :gh:`102828`.) + +* :mod:`sqlite3`: + + * :ref:`default adapters and converters + <sqlite3-default-converters>` are now deprecated. + Instead, use the :ref:`sqlite3-adapter-converter-recipes` + and tailor them to your needs. + (Contributed by Erlend E. Aasland in :gh:`90016`.) + + * In :meth:`~sqlite3.Cursor.execute`, :exc:`DeprecationWarning` is now emitted + when :ref:`named placeholders <sqlite3-placeholders>` are used together with + parameters supplied as a :term:`sequence` instead of as a :class:`dict`. + Starting from Python 3.14, using named placeholders with parameters supplied + as a sequence will raise a :exc:`~sqlite3.ProgrammingError`. + (Contributed by Erlend E. Aasland in :gh:`101698`.) + +* :mod:`sys`: The :data:`sys.last_type`, :data:`sys.last_value` and :data:`sys.last_traceback` + fields are deprecated. Use :data:`sys.last_exc` instead. + (Contributed by Irit Katriel in :gh:`102778`.) + +* :mod:`tarfile`: Extracting tar archives without specifying *filter* is deprecated until + Python 3.14, when ``'data'`` filter will become the default. + See :ref:`tarfile-extraction-filter` for details. + +* :mod:`typing`: + + * :class:`typing.Hashable` and :class:`typing.Sized` aliases for :class:`collections.abc.Hashable` + and :class:`collections.abc.Sized`. (:gh:`94309`.) + + * :class:`typing.ByteString`, deprecated since Python 3.9, now causes a + :exc:`DeprecationWarning` to be emitted when it is used. + (Contributed by Alex Waygood in :gh:`91896`.) + +* :mod:`xml.etree.ElementTree`: The module now emits :exc:`DeprecationWarning` + when testing the truth value of an :class:`xml.etree.ElementTree.Element`. + Before, the Python implementation emitted :exc:`FutureWarning`, and the C + implementation emitted nothing. + (Contributed by Jacob Walls in :gh:`83122`.) + +* The 3-arg signatures (type, value, traceback) of :meth:`coroutine throw() + <coroutine.throw>`, :meth:`generator throw() <generator.throw>` and + :meth:`async generator throw() <agen.athrow>` are deprecated and + may be removed in a future version of Python. Use the single-arg versions + of these functions instead. (Contributed by Ofey Chan in :gh:`89874`.) + +* :exc:`DeprecationWarning` is now raised when ``__package__`` on a + module differs from ``__spec__.parent`` (previously it was + :exc:`ImportWarning`). + (Contributed by Brett Cannon in :gh:`65961`.) + +* Setting ``__package__`` or ``__cached__`` on a module is deprecated, + and will cease to be set or taken into consideration by the import system in Python 3.14. + (Contributed by Brett Cannon in :gh:`65961`.) + +* The bitwise inversion operator (``~``) on bool is deprecated. It will throw an + error in Python 3.14. Use ``not`` for logical negation of bools instead. + In the rare case that you really need the bitwise inversion of the underlying + ``int``, convert to int explicitly: ``~int(x)``. (Contributed by Tim Hoffmann + in :gh:`103487`.) + +* Accessing ``co_lnotab`` on code objects was deprecated in Python 3.10 via :pep:`626`, + but it only got a proper :exc:`DeprecationWarning` in 3.12, + therefore it will be removed in 3.14. + (Contributed by Nikita Sobolev in :gh:`101866`.) + +Pending Removal in Python 3.13 +------------------------------ + +The following modules and APIs have been deprecated in earlier Python releases, +and will be removed in Python 3.13. + +Modules (see :pep:`594`): + +* :mod:`aifc` +* :mod:`audioop` +* :mod:`cgi` +* :mod:`cgitb` +* :mod:`chunk` +* :mod:`crypt` +* :mod:`imghdr` +* :mod:`mailcap` +* :mod:`msilib` +* :mod:`nis` +* :mod:`nntplib` +* :mod:`ossaudiodev` +* :mod:`pipes` +* :mod:`sndhdr` +* :mod:`spwd` +* :mod:`sunau` +* :mod:`telnetlib` +* :mod:`uu` +* :mod:`xdrlib` + +Other modules: + +* :mod:`!lib2to3`, and the :program:`2to3` program (:gh:`84540`) + +APIs: + +* :class:`!configparser.LegacyInterpolation` (:gh:`90765`) +* :func:`locale.getdefaultlocale` (:gh:`90817`) +* :meth:`!turtle.RawTurtle.settiltangle` (:gh:`50096`) +* :func:`!unittest.findTestCases` (:gh:`50096`) +* :func:`!unittest.getTestCaseNames` (:gh:`50096`) +* :func:`!unittest.makeSuite` (:gh:`50096`) +* :meth:`!unittest.TestProgram.usageExit` (:gh:`67048`) +* :class:`!webbrowser.MacOSX` (:gh:`86421`) +* :class:`classmethod` descriptor chaining (:gh:`89519`) + +Pending Removal in Python 3.14 +------------------------------ + +The following APIs have been deprecated +and will be removed in Python 3.14. + +* :mod:`argparse`: The *type*, *choices*, and *metavar* parameters + of :class:`!argparse.BooleanOptionalAction` + +* :mod:`ast`: + + * :class:`!ast.Num` + * :class:`!ast.Str` + * :class:`!ast.Bytes` + * :class:`!ast.NameConstant` + * :class:`!ast.Ellipsis` + +* :mod:`asyncio`: + + * :class:`!asyncio.MultiLoopChildWatcher` + * :class:`!asyncio.FastChildWatcher` + * :class:`!asyncio.AbstractChildWatcher` + * :class:`!asyncio.SafeChildWatcher` + * :func:`!asyncio.set_child_watcher` + * :func:`!asyncio.get_child_watcher`, + * :meth:`!asyncio.AbstractEventLoopPolicy.set_child_watcher` + * :meth:`!asyncio.AbstractEventLoopPolicy.get_child_watcher` + +* :mod:`collections.abc`: :class:`!collections.abc.ByteString`. + +* :mod:`email`: the *isdst* parameter in :func:`email.utils.localtime`. + +* :mod:`importlib.abc`: + + * :class:`!importlib.abc.ResourceReader` + * :class:`!importlib.abc.Traversable` + * :class:`!importlib.abc.TraversableResources` + +* :mod:`itertools`: Support for copy, deepcopy, and pickle operations. + +* :mod:`pkgutil`: + + * :func:`!pkgutil.find_loader` + * :func:`!pkgutil.get_loader`. + +* :mod:`pty`: + + * :func:`!pty.master_open` + * :func:`!pty.slave_open` + +* :mod:`shutil`: The *onerror* argument of :func:`shutil.rmtree` + +* :mod:`typing`: :class:`!typing.ByteString` + +* :mod:`xml.etree.ElementTree`: Testing the truth value of an :class:`xml.etree.ElementTree.Element`. + +* The ``__package__`` and ``__cached__`` attributes on module objects. + +* The ``co_lnotab`` attribute of code objects. + +Pending Removal in Future Versions +---------------------------------- + +The following APIs were deprecated in earlier Python versions and will be removed, +although there is currently no date scheduled for their removal. + +* :mod:`array`'s ``'u'`` format code (:gh:`57281`) + +* :class:`typing.Text` (:gh:`92332`) + +* Currently Python accepts numeric literals immediately followed by keywords, + for example ``0in x``, ``1or x``, ``0if 1else 2``. It allows confusing + and ambiguous expressions like ``[0x1for x in y]`` (which can be + interpreted as ``[0x1 for x in y]`` or ``[0x1f or x in y]``). + A syntax warning is raised if the numeric literal is + immediately followed by one of keywords :keyword:`and`, :keyword:`else`, + :keyword:`for`, :keyword:`if`, :keyword:`in`, :keyword:`is` and :keyword:`or`. + In a future release it will be changed to a syntax error. (:gh:`87999`) + + +Removed +======= + +asynchat and asyncore +--------------------- + +* These two modules have been removed + according to the schedule in :pep:`594`, + having been deprecated in Python 3.6. + Use :mod:`asyncio` instead. + (Contributed by Nikita Sobolev in :gh:`96580`.) + +configparser +------------ + +* Several names deprecated in the :mod:`configparser` way back in 3.2 have + been removed per :gh:`89336`: + + * :class:`configparser.ParsingError` no longer has a ``filename`` attribute + or argument. Use the ``source`` attribute and argument instead. + * :mod:`configparser` no longer has a ``SafeConfigParser`` class. Use the + shorter :class:`~configparser.ConfigParser` name instead. + * :class:`configparser.ConfigParser` no longer has a ``readfp`` method. + Use :meth:`~configparser.ConfigParser.read_file` instead. + +distutils +--------- + +* Remove the :py:mod:`!distutils` package. It was deprecated in Python 3.10 by + :pep:`632` "Deprecate distutils module". For projects still using + ``distutils`` and cannot be updated to something else, the ``setuptools`` + project can be installed: it still provides ``distutils``. + (Contributed by Victor Stinner in :gh:`92584`.) + +ensurepip +--------- + +* Remove the bundled setuptools wheel from :mod:`ensurepip`, + and stop installing setuptools in environments created by :mod:`venv`. + + ``pip (>= 22.1)`` does not require setuptools to be installed in the + environment. ``setuptools``-based (and ``distutils``-based) packages + can still be used with ``pip install``, since pip will provide + ``setuptools`` in the build environment it uses for building a + package. + + ``easy_install``, ``pkg_resources``, ``setuptools`` and ``distutils`` + are no longer provided by default in environments created with + ``venv`` or bootstrapped with ``ensurepip``, since they are part of + the ``setuptools`` package. For projects relying on these at runtime, + the ``setuptools`` project should be declared as a dependency and + installed separately (typically, using pip). + + (Contributed by Pradyun Gedam in :gh:`95299`.) + +enum +---- + +* Remove :mod:`enum`'s ``EnumMeta.__getattr__``, which is no longer needed for + enum attribute access. + (Contributed by Ethan Furman in :gh:`95083`.) + +ftplib +------ + +* Remove :mod:`ftplib`'s ``FTP_TLS.ssl_version`` class attribute: use the + *context* parameter instead. + (Contributed by Victor Stinner in :gh:`94172`.) + +gzip +---- + +* Remove the ``filename`` attribute of :mod:`gzip`'s :class:`gzip.GzipFile`, + deprecated since Python 2.6, use the :attr:`~gzip.GzipFile.name` attribute + instead. In write mode, the ``filename`` attribute added ``'.gz'`` file + extension if it was not present. + (Contributed by Victor Stinner in :gh:`94196`.) + +hashlib +------- + +* Remove the pure Python implementation of :mod:`hashlib`'s + :func:`hashlib.pbkdf2_hmac()`, deprecated in Python 3.10. Python 3.10 and + newer requires OpenSSL 1.1.1 (:pep:`644`): this OpenSSL version provides + a C implementation of :func:`~hashlib.pbkdf2_hmac()` which is faster. + (Contributed by Victor Stinner in :gh:`94199`.) + +importlib +--------- + +* Many previously deprecated cleanups in :mod:`importlib` have now been + completed: + + * References to, and support for :meth:`!module_repr()` has been removed. + (Contributed by Barry Warsaw in :gh:`97850`.) + + * ``importlib.util.set_package``, ``importlib.util.set_loader`` and + ``importlib.util.module_for_loader`` have all been removed. (Contributed by + Brett Cannon and Nikita Sobolev in :gh:`65961` and :gh:`97850`.) + + * Support for ``find_loader()`` and ``find_module()`` APIs have been + removed. (Contributed by Barry Warsaw in :gh:`98040`.) + + * ``importlib.abc.Finder``, ``pkgutil.ImpImporter``, and ``pkgutil.ImpLoader`` + have been removed. (Contributed by Barry Warsaw in :gh:`98040`.) + +imp +--- + +* The :mod:`!imp` module has been removed. (Contributed by Barry Warsaw in + :gh:`98040`.) + + To migrate, consult the following correspondence table: + + ================================= ======================================= + imp importlib + ================================= ======================================= + ``imp.NullImporter`` Insert ``None`` into ``sys.path_importer_cache`` + ``imp.cache_from_source()`` :func:`importlib.util.cache_from_source` + ``imp.find_module()`` :func:`importlib.util.find_spec` + ``imp.get_magic()`` :attr:`importlib.util.MAGIC_NUMBER` + ``imp.get_suffixes()`` :attr:`importlib.machinery.SOURCE_SUFFIXES`, :attr:`importlib.machinery.EXTENSION_SUFFIXES`, and :attr:`importlib.machinery.BYTECODE_SUFFIXES` + ``imp.get_tag()`` :attr:`sys.implementation.cache_tag <sys.implementation>` + ``imp.load_module()`` :func:`importlib.import_module` + ``imp.new_module(name)`` ``types.ModuleType(name)`` + ``imp.reload()`` :func:`importlib.reload` + ``imp.source_from_cache()`` :func:`importlib.util.source_from_cache` + ``imp.load_source()`` *See below* + ================================= ======================================= + + Replace ``imp.load_source()`` with:: + + import importlib.util + import importlib.machinery + + def load_source(modname, filename): + loader = importlib.machinery.SourceFileLoader(modname, filename) + spec = importlib.util.spec_from_file_location(modname, filename, loader=loader) + module = importlib.util.module_from_spec(spec) + # The module is always executed and not cached in sys.modules. + # Uncomment the following line to cache the module. + # sys.modules[module.__name__] = module + loader.exec_module(module) + return module + +* Remove :mod:`!imp` functions and attributes with no replacements: + + * Undocumented functions: + + * ``imp.init_builtin()`` + * ``imp.load_compiled()`` + * ``imp.load_dynamic()`` + * ``imp.load_package()`` + + * ``imp.lock_held()``, ``imp.acquire_lock()``, ``imp.release_lock()``: + the locking scheme has changed in Python 3.3 to per-module locks. + * ``imp.find_module()`` constants: ``SEARCH_ERROR``, ``PY_SOURCE``, + ``PY_COMPILED``, ``C_EXTENSION``, ``PY_RESOURCE``, ``PKG_DIRECTORY``, + ``C_BUILTIN``, ``PY_FROZEN``, ``PY_CODERESOURCE``, ``IMP_HOOK``. + +io +-- + +* Remove :mod:`io`'s ``io.OpenWrapper`` and ``_pyio.OpenWrapper``, deprecated in Python + 3.10: just use :func:`open` instead. The :func:`open` (:func:`io.open`) + function is a built-in function. Since Python 3.10, :func:`!_pyio.open` is + also a static method. + (Contributed by Victor Stinner in :gh:`94169`.) + +locale +------ + +* Remove :mod:`locale`'s :func:`!locale.format` function, deprecated in Python 3.7: + use :func:`locale.format_string` instead. + (Contributed by Victor Stinner in :gh:`94226`.) + +* ``smtpd``: The module has been removed according to the schedule in :pep:`594`, + having been deprecated in Python 3.4.7 and 3.5.4. + Use aiosmtpd_ PyPI module or any other + :mod:`asyncio`-based server instead. + (Contributed by Oleg Iarygin in :gh:`93243`.) + +.. _aiosmtpd: https://pypi.org/project/aiosmtpd/ + +sqlite3 +------- + +* The following undocumented :mod:`sqlite3` features, deprecated in Python + 3.10, are now removed: + + * ``sqlite3.enable_shared_cache()`` + * ``sqlite3.OptimizedUnicode`` + + If a shared cache must be used, open the database in URI mode using the + ``cache=shared`` query parameter. + + The ``sqlite3.OptimizedUnicode`` text factory has been an alias for + :class:`str` since Python 3.3. Code that previously set the text factory to + ``OptimizedUnicode`` can either use ``str`` explicitly, or rely on the + default value which is also ``str``. + + (Contributed by Erlend E. Aasland in :gh:`92548`.) + +ssl +--- + +* Remove :mod:`ssl`'s :func:`!ssl.RAND_pseudo_bytes` function, deprecated in Python 3.6: + use :func:`os.urandom` or :func:`ssl.RAND_bytes` instead. + (Contributed by Victor Stinner in :gh:`94199`.) + +* Remove the :func:`!ssl.match_hostname` function. + It was deprecated in Python 3.7. OpenSSL performs + hostname matching since Python 3.7, Python no longer uses the + :func:`!ssl.match_hostname` function. + (Contributed by Victor Stinner in :gh:`94199`.) + +* Remove the :func:`!ssl.wrap_socket` function, deprecated in Python 3.7: + instead, create a :class:`ssl.SSLContext` object and call its + :class:`ssl.SSLContext.wrap_socket` method. Any package that still uses + :func:`!ssl.wrap_socket` is broken and insecure. The function neither sends a + SNI TLS extension nor validates server hostname. Code is subject to `CWE-295 + <https://cwe.mitre.org/data/definitions/295.html>`_: Improper Certificate + Validation. + (Contributed by Victor Stinner in :gh:`94199`.) + +unittest +-------- + +* Remove many long-deprecated :mod:`unittest` features: + + .. _unittest-TestCase-removed-aliases: + + * A number of :class:`~unittest.TestCase` method aliases: + + ============================ =============================== =============== + Deprecated alias Method Name Deprecated in + ============================ =============================== =============== + ``failUnless`` :meth:`.assertTrue` 3.1 + ``failIf`` :meth:`.assertFalse` 3.1 + ``failUnlessEqual`` :meth:`.assertEqual` 3.1 + ``failIfEqual`` :meth:`.assertNotEqual` 3.1 + ``failUnlessAlmostEqual`` :meth:`.assertAlmostEqual` 3.1 + ``failIfAlmostEqual`` :meth:`.assertNotAlmostEqual` 3.1 + ``failUnlessRaises`` :meth:`.assertRaises` 3.1 + ``assert_`` :meth:`.assertTrue` 3.2 + ``assertEquals`` :meth:`.assertEqual` 3.2 + ``assertNotEquals`` :meth:`.assertNotEqual` 3.2 + ``assertAlmostEquals`` :meth:`.assertAlmostEqual` 3.2 + ``assertNotAlmostEquals`` :meth:`.assertNotAlmostEqual` 3.2 + ``assertRegexpMatches`` :meth:`.assertRegex` 3.2 + ``assertRaisesRegexp`` :meth:`.assertRaisesRegex` 3.2 + ``assertNotRegexpMatches`` :meth:`.assertNotRegex` 3.5 + ============================ =============================== =============== + + You can use https://github.com/isidentical/teyit to automatically modernise + your unit tests. + + * Undocumented and broken :class:`~unittest.TestCase` method + ``assertDictContainsSubset`` (deprecated in Python 3.2). + + * Undocumented :meth:`TestLoader.loadTestsFromModule + <unittest.TestLoader.loadTestsFromModule>` parameter *use_load_tests* + (deprecated and ignored since Python 3.2). + + * An alias of the :class:`~unittest.TextTestResult` class: + ``_TextTestResult`` (deprecated in Python 3.2). + + (Contributed by Serhiy Storchaka in :gh:`89325`.) + +webbrowser +---------- + +* Remove support for obsolete browsers from :mod:`webbrowser`. + The removed browsers include: Grail, Mosaic, Netscape, Galeon, Skipstone, + Iceape, Firebird, and Firefox versions 35 and below (:gh:`102871`). + +xml.etree.ElementTree +--------------------- + +* Remove the ``ElementTree.Element.copy()`` method of the + pure Python implementation, deprecated in Python 3.10, use the + :func:`copy.copy` function instead. The C implementation of :mod:`xml.etree.ElementTree` + has no ``copy()`` method, only a ``__copy__()`` method. + (Contributed by Victor Stinner in :gh:`94383`.) + +zipimport +--------- + +* Remove :mod:`zipimport`'s ``find_loader()`` and ``find_module()`` methods, + deprecated in Python 3.10: use the ``find_spec()`` method instead. See + :pep:`451` for the rationale. + (Contributed by Victor Stinner in :gh:`94379`.) + +Others +------ + +* Remove the ``suspicious`` rule from the documentation :file:`Makefile` and + :file:`Doc/tools/rstlint.py`, both in favor of `sphinx-lint + <https://github.com/sphinx-contrib/sphinx-lint>`_. + (Contributed by Julien Palard in :gh:`98179`.) + +* Remove the *keyfile* and *certfile* parameters from the + :mod:`ftplib`, :mod:`imaplib`, :mod:`poplib` and :mod:`smtplib` modules, + and the *key_file*, *cert_file* and *check_hostname* parameters from the + :mod:`http.client` module, + all deprecated since Python 3.6. Use the *context* parameter + (*ssl_context* in :mod:`imaplib`) instead. + (Contributed by Victor Stinner in :gh:`94172`.) + +.. _whatsnew312-porting-to-python312: + +Porting to Python 3.12 +====================== + +This section lists previously described changes and other bugfixes +that may require changes to your code. + +Changes in the Python API +------------------------- + +* More strict rules are now applied for numerical group references and + group names in regular expressions. + Only sequence of ASCII digits is now accepted as a numerical reference. + The group name in bytes patterns and replacement strings can now only + contain ASCII letters and digits and underscore. + (Contributed by Serhiy Storchaka in :gh:`91760`.) + +* Remove ``randrange()`` functionality deprecated since Python 3.10. Formerly, + ``randrange(10.0)`` losslessly converted to ``randrange(10)``. Now, it raises a + :exc:`TypeError`. Also, the exception raised for non-integer values such as + ``randrange(10.5)`` or ``randrange('10')`` has been changed from :exc:`ValueError` to + :exc:`TypeError`. This also prevents bugs where ``randrange(1e25)`` would silently + select from a larger range than ``randrange(10**25)``. + (Originally suggested by Serhiy Storchaka :gh:`86388`.) + +* :class:`argparse.ArgumentParser` changed encoding and error handler + for reading arguments from file (e.g. ``fromfile_prefix_chars`` option) + from default text encoding (e.g. :func:`locale.getpreferredencoding(False) <locale.getpreferredencoding>`) + to :term:`filesystem encoding and error handler`. + Argument files should be encoded in UTF-8 instead of ANSI Codepage on Windows. + +* Remove the ``asyncore``-based ``smtpd`` module deprecated in Python 3.4.7 + and 3.5.4. A recommended replacement is the + :mod:`asyncio`-based aiosmtpd_ PyPI module. + +* :func:`shlex.split`: Passing ``None`` for *s* argument now raises an + exception, rather than reading :data:`sys.stdin`. The feature was deprecated + in Python 3.9. + (Contributed by Victor Stinner in :gh:`94352`.) + +* The :mod:`os` module no longer accepts bytes-like paths, like + :class:`bytearray` and :class:`memoryview` types: only the exact + :class:`bytes` type is accepted for bytes strings. + (Contributed by Victor Stinner in :gh:`98393`.) + +* :func:`syslog.openlog` and :func:`syslog.closelog` now fail if used in subinterpreters. + :func:`syslog.syslog` may still be used in subinterpreters, + but now only if :func:`syslog.openlog` has already been called in the main interpreter. + These new restrictions do not apply to the main interpreter, + so only a very small set of users might be affected. + This change helps with interpreter isolation. Furthermore, :mod:`syslog` is a wrapper + around process-global resources, which are best managed from the main interpreter. + (Contributed by Donghee Na in :gh:`99127`.) + +* The undocumented locking behavior of :func:`~functools.cached_property` + is removed, because it locked across all instances of the class, leading to high + lock contention. This means that a cached property getter function could now run + more than once for a single instance, if two threads race. For most simple + cached properties (e.g. those that are idempotent and simply calculate a value + based on other attributes of the instance) this will be fine. If + synchronization is needed, implement locking within the cached property getter + function or around multi-threaded access points. + +* :func:`sys._current_exceptions` now returns a mapping from thread-id to an + exception instance, rather than to a ``(typ, exc, tb)`` tuple. + (Contributed by Irit Katriel in :gh:`103176`.) + +* When extracting tar files using :mod:`tarfile` or + :func:`shutil.unpack_archive`, pass the *filter* argument to limit features + that may be surprising or dangerous. + See :ref:`tarfile-extraction-filter` for details. + +* The output of the :func:`tokenize.tokenize` and :func:`tokenize.generate_tokens` + functions is now changed due to the changes introduced in :pep:`701`. This + means that ``STRING`` tokens are not emitted any more for f-strings and the + tokens described in :pep:`701` are now produced instead: ``FSTRING_START``, + ``FSTRING_MIDDLE`` and ``FSTRING_END`` are now emitted for f-string "string" + parts in addition to the appropriate tokens for the tokenization in the + expression components. For example for the f-string ``f"start {1+1} end"`` + the old version of the tokenizer emitted:: + + 1,0-1,18: STRING 'f"start {1+1} end"' + + while the new version emits:: + + 1,0-1,2: FSTRING_START 'f"' + 1,2-1,8: FSTRING_MIDDLE 'start ' + 1,8-1,9: OP '{' + 1,9-1,10: NUMBER '1' + 1,10-1,11: OP '+' + 1,11-1,12: NUMBER '1' + 1,12-1,13: OP '}' + 1,13-1,17: FSTRING_MIDDLE ' end' + 1,17-1,18: FSTRING_END '"' + + Additionally, there may be some minor behavioral changes as a consequence of the + changes required to support :pep:`701`. Some of these changes include: + + * The ``type`` attribute of the tokens emitted when tokenizing some invalid Python + characters such as ``!`` has changed from ``ERRORTOKEN`` to ``OP``. + + * Incomplete single-line strings now also raise :exc:`tokenize.TokenError` as incomplete + multiline strings do. + + * Some incomplete or invalid Python code now raises :exc:`tokenize.TokenError` instead of + returning arbitrary ``ERRORTOKEN`` tokens when tokenizing it. + + * Mixing tabs and spaces as indentation in the same file is not supported anymore and will + raise a :exc:`TabError`. + +Build Changes +============= + +* Python no longer uses :file:`setup.py` to build shared C extension modules. + Build parameters like headers and libraries are detected in ``configure`` + script. Extensions are built by :file:`Makefile`. Most extensions use + ``pkg-config`` and fall back to manual detection. + (Contributed by Christian Heimes in :gh:`93939`.) + +* ``va_start()`` with two parameters, like ``va_start(args, format),`` + is now required to build Python. + ``va_start()`` is no longer called with a single parameter. + (Contributed by Kumar Aditya in :gh:`93207`.) + +* CPython now uses the ThinLTO option as the default link time optimization policy + if the Clang compiler accepts the flag. + (Contributed by Donghee Na in :gh:`89536`.) + +* Add ``COMPILEALL_OPTS`` variable in :file:`Makefile` to override :mod:`compileall` + options (default: ``-j0``) in ``make install``. Also merged the 3 + ``compileall`` commands into a single command to build .pyc files for all + optimization levels (0, 1, 2) at once. + (Contributed by Victor Stinner in :gh:`99289`.) + +* Add platform triplets for 64-bit LoongArch: + + * loongarch64-linux-gnusf + * loongarch64-linux-gnuf32 + * loongarch64-linux-gnu + + (Contributed by Zhang Na in :gh:`90656`.) + +* ``PYTHON_FOR_REGEN`` now require Python 3.10 or newer. + +* Autoconf 2.71 and aclocal 1.16.4 is now required to regenerate + :file:`!configure`. + (Contributed by Christian Heimes in :gh:`89886`.) + +* Windows builds and macOS installers from python.org now use OpenSSL 3.0. + + +C API Changes +============= + +New Features +------------ + +.. _whatsnew312-pep697: + +* :pep:`697`: Introduce the :ref:`Unstable C API tier <unstable-c-api>`, + intended for low-level tools like debuggers and JIT compilers. + This API may change in each minor release of CPython without deprecation + warnings. + Its contents are marked by the ``PyUnstable_`` prefix in names. + + Code object constructors: + + - ``PyUnstable_Code_New()`` (renamed from ``PyCode_New``) + - ``PyUnstable_Code_NewWithPosOnlyArgs()`` (renamed from ``PyCode_NewWithPosOnlyArgs``) + + Extra storage for code objects (:pep:`523`): + + - ``PyUnstable_Eval_RequestCodeExtraIndex()`` (renamed from ``_PyEval_RequestCodeExtraIndex``) + - ``PyUnstable_Code_GetExtra()`` (renamed from ``_PyCode_GetExtra``) + - ``PyUnstable_Code_SetExtra()`` (renamed from ``_PyCode_SetExtra``) + + The original names will continue to be available until the respective + API changes. + + (Contributed by Petr Viktorin in :gh:`101101`.) + +* :pep:`697`: Add an API for extending types whose instance memory layout is + opaque: + + - :c:member:`PyType_Spec.basicsize` can be zero or negative to specify + inheriting or extending the base class size. + - :c:func:`PyObject_GetTypeData` and :c:func:`PyType_GetTypeDataSize` + added to allow access to subclass-specific instance data. + - :c:macro:`Py_TPFLAGS_ITEMS_AT_END` and :c:func:`PyObject_GetItemData` + added to allow safely extending certain variable-sized types, including + :c:var:`PyType_Type`. + - :c:macro:`Py_RELATIVE_OFFSET` added to allow defining + :c:type:`members <PyMemberDef>` in terms of a subclass-specific struct. + + (Contributed by Petr Viktorin in :gh:`103509`.) + +* Add the new :ref:`limited C API <limited-c-api>` function :c:func:`PyType_FromMetaclass`, + which generalizes the existing :c:func:`PyType_FromModuleAndSpec` using + an additional metaclass argument. + (Contributed by Wenzel Jakob in :gh:`93012`.) + +* API for creating objects that can be called using + :ref:`the vectorcall protocol <vectorcall>` was added to the + :ref:`Limited API <stable>`: + + * :c:macro:`Py_TPFLAGS_HAVE_VECTORCALL` + * :c:func:`PyVectorcall_NARGS` + * :c:func:`PyVectorcall_Call` + * :c:type:`vectorcallfunc` + + The :c:macro:`Py_TPFLAGS_HAVE_VECTORCALL` flag is now removed from a class + when the class's :py:meth:`~object.__call__` method is reassigned. + This makes vectorcall safe to use with mutable types (i.e. heap types + without the immutable flag, :c:macro:`Py_TPFLAGS_IMMUTABLETYPE`). + Mutable types that do not override :c:member:`~PyTypeObject.tp_call` now + inherit the ``Py_TPFLAGS_HAVE_VECTORCALL`` flag. + (Contributed by Petr Viktorin in :gh:`93274`.) + + The :c:macro:`Py_TPFLAGS_MANAGED_DICT` and :c:macro:`Py_TPFLAGS_MANAGED_WEAKREF` + flags have been added. This allows extensions classes to support object + ``__dict__`` and weakrefs with less bookkeeping, + using less memory and with faster access. + +* API for performing calls using + :ref:`the vectorcall protocol <vectorcall>` was added to the + :ref:`Limited API <stable>`: + + * :c:func:`PyObject_Vectorcall` + * :c:func:`PyObject_VectorcallMethod` + * :c:macro:`PY_VECTORCALL_ARGUMENTS_OFFSET` + + This means that both the incoming and outgoing ends of the vector call + protocol are now available in the :ref:`Limited API <stable>`. (Contributed + by Wenzel Jakob in :gh:`98586`.) + +* Add two new public functions, + :c:func:`PyEval_SetProfileAllThreads` and + :c:func:`PyEval_SetTraceAllThreads`, that allow to set tracing and profiling + functions in all running threads in addition to the calling one. (Contributed + by Pablo Galindo in :gh:`93503`.) + +* Add new function :c:func:`PyFunction_SetVectorcall` to the C API + which sets the vectorcall field of a given :c:type:`PyFunctionObject`. + (Contributed by Andrew Frost in :gh:`92257`.) + +* The C API now permits registering callbacks via :c:func:`PyDict_AddWatcher`, + :c:func:`PyDict_Watch` and related APIs to be called whenever a dictionary + is modified. This is intended for use by optimizing interpreters, JIT + compilers, or debuggers. + (Contributed by Carl Meyer in :gh:`91052`.) + +* Add :c:func:`PyType_AddWatcher` and :c:func:`PyType_Watch` API to register + callbacks to receive notification on changes to a type. + (Contributed by Carl Meyer in :gh:`91051`.) + +* Add :c:func:`PyCode_AddWatcher` and :c:func:`PyCode_ClearWatcher` + APIs to register callbacks to receive notification on creation and + destruction of code objects. + (Contributed by Itamar Oren in :gh:`91054`.) + +* Add :c:func:`PyFrame_GetVar` and :c:func:`PyFrame_GetVarString` functions to + get a frame variable by its name. + (Contributed by Victor Stinner in :gh:`91248`.) + +* Add :c:func:`PyErr_GetRaisedException` and :c:func:`PyErr_SetRaisedException` + for saving and restoring the current exception. + These functions return and accept a single exception object, + rather than the triple arguments of the now-deprecated + :c:func:`PyErr_Fetch` and :c:func:`PyErr_Restore`. + This is less error prone and a bit more efficient. + (Contributed by Mark Shannon in :gh:`101578`.) + +* Add ``_PyErr_ChainExceptions1``, which takes an exception instance, + to replace the legacy-API ``_PyErr_ChainExceptions``, which is now + deprecated. (Contributed by Mark Shannon in :gh:`101578`.) + +* Add :c:func:`PyException_GetArgs` and :c:func:`PyException_SetArgs` + as convenience functions for retrieving and modifying + the :attr:`~BaseException.args` passed to the exception's constructor. + (Contributed by Mark Shannon in :gh:`101578`.) + +* Add :c:func:`PyErr_DisplayException`, which takes an exception instance, + to replace the legacy-api :c:func:`!PyErr_Display`. (Contributed by + Irit Katriel in :gh:`102755`). + +.. _whatsnew312-pep683: + +* :pep:`683`: Introduce *Immortal Objects*, which allows objects + to bypass reference counts, and related changes to the C-API: + + - ``_Py_IMMORTAL_REFCNT``: The reference count that defines an object + as immortal. + - ``_Py_IsImmortal`` Checks if an object has the immortal reference count. + - ``PyObject_HEAD_INIT`` This will now initialize reference count to + ``_Py_IMMORTAL_REFCNT`` when used with ``Py_BUILD_CORE``. + - ``SSTATE_INTERNED_IMMORTAL`` An identifier for interned unicode objects + that are immortal. + - ``SSTATE_INTERNED_IMMORTAL_STATIC`` An identifier for interned unicode + objects that are immortal and static + - ``sys.getunicodeinternedsize`` This returns the total number of unicode + objects that have been interned. This is now needed for :file:`refleak.py` to + correctly track reference counts and allocated blocks + + (Contributed by Eddie Elizondo in :gh:`84436`.) + +* :pep:`684`: Add the new :c:func:`Py_NewInterpreterFromConfig` + function and :c:type:`PyInterpreterConfig`, which may be used + to create sub-interpreters with their own GILs. + (See :ref:`whatsnew312-pep684` for more info.) + (Contributed by Eric Snow in :gh:`104110`.) + +* In the limited C API version 3.12, :c:func:`Py_INCREF` and + :c:func:`Py_DECREF` functions are now implemented as opaque function calls to + hide implementation details. + (Contributed by Victor Stinner in :gh:`105387`.) + +Porting to Python 3.12 +---------------------- + +* Legacy Unicode APIs based on ``Py_UNICODE*`` representation has been removed. + Please migrate to APIs based on UTF-8 or ``wchar_t*``. + +* Argument parsing functions like :c:func:`PyArg_ParseTuple` doesn't support + ``Py_UNICODE*`` based format (e.g. ``u``, ``Z``) anymore. Please migrate + to other formats for Unicode like ``s``, ``z``, ``es``, and ``U``. + +* ``tp_weaklist`` for all static builtin types is always ``NULL``. + This is an internal-only field on ``PyTypeObject`` + but we're pointing out the change in case someone happens to be + accessing the field directly anyway. To avoid breakage, consider + using the existing public C-API instead, or, if necessary, the + (internal-only) ``_PyObject_GET_WEAKREFS_LISTPTR()`` macro. + +* This internal-only :c:member:`PyTypeObject.tp_subclasses` may now not be + a valid object pointer. Its type was changed to :c:expr:`void *` to + reflect this. We mention this in case someone happens to be accessing the + internal-only field directly. + + To get a list of subclasses, call the Python method + :py:meth:`~class.__subclasses__` (using :c:func:`PyObject_CallMethod`, + for example). + +* Add support of more formatting options (left aligning, octals, uppercase + hexadecimals, :c:type:`intmax_t`, :c:type:`ptrdiff_t`, :c:type:`wchar_t` C + strings, variable width and precision) in :c:func:`PyUnicode_FromFormat` and + :c:func:`PyUnicode_FromFormatV`. + (Contributed by Serhiy Storchaka in :gh:`98836`.) + +* An unrecognized format character in :c:func:`PyUnicode_FromFormat` and + :c:func:`PyUnicode_FromFormatV` now sets a :exc:`SystemError`. + In previous versions it caused all the rest of the format string to be + copied as-is to the result string, and any extra arguments discarded. + (Contributed by Serhiy Storchaka in :gh:`95781`.) + +* Fix wrong sign placement in :c:func:`PyUnicode_FromFormat` and + :c:func:`PyUnicode_FromFormatV`. + (Contributed by Philip Georgi in :gh:`95504`.) + +* Extension classes wanting to add a ``__dict__`` or weak reference slot + should use :c:macro:`Py_TPFLAGS_MANAGED_DICT` and + :c:macro:`Py_TPFLAGS_MANAGED_WEAKREF` instead of ``tp_dictoffset`` and + ``tp_weaklistoffset``, respectively. + The use of ``tp_dictoffset`` and ``tp_weaklistoffset`` is still + supported, but does not fully support multiple inheritance + (:gh:`95589`), and performance may be worse. + Classes declaring :c:macro:`Py_TPFLAGS_MANAGED_DICT` should call + :c:func:`!_PyObject_VisitManagedDict` and :c:func:`!_PyObject_ClearManagedDict` + to traverse and clear their instance's dictionaries. + To clear weakrefs, call :c:func:`PyObject_ClearWeakRefs`, as before. + +* The :c:func:`PyUnicode_FSDecoder` function no longer accepts bytes-like + paths, like :class:`bytearray` and :class:`memoryview` types: only the exact + :class:`bytes` type is accepted for bytes strings. + (Contributed by Victor Stinner in :gh:`98393`.) + +* The :c:macro:`Py_CLEAR`, :c:macro:`Py_SETREF` and :c:macro:`Py_XSETREF` + macros now only evaluate their arguments once. If an argument has side + effects, these side effects are no longer duplicated. + (Contributed by Victor Stinner in :gh:`98724`.) + +* The interpreter's error indicator is now always normalized. This means + that :c:func:`PyErr_SetObject`, :c:func:`PyErr_SetString` and the other + functions that set the error indicator now normalize the exception + before storing it. (Contributed by Mark Shannon in :gh:`101578`.) + +* ``_Py_RefTotal`` is no longer authoritative and only kept around + for ABI compatibility. Note that it is an internal global and only + available on debug builds. If you happen to be using it then you'll + need to start using ``_Py_GetGlobalRefTotal()``. + +* The following functions now select an appropriate metaclass for the newly + created type: + + * :c:func:`PyType_FromSpec` + * :c:func:`PyType_FromSpecWithBases` + * :c:func:`PyType_FromModuleAndSpec` + + Creating classes whose metaclass overrides :c:member:`~PyTypeObject.tp_new` + is deprecated, and in Python 3.14+ it will be disallowed. + Note that these functions ignore ``tp_new`` of the metaclass, possibly + allowing incomplete initialization. + + Note that :c:func:`PyType_FromMetaclass` (added in Python 3.12) + already disallows creating classes whose metaclass overrides ``tp_new`` + (:meth:`~object.__new__` in Python). + + Since ``tp_new`` overrides almost everything ``PyType_From*`` functions do, + the two are incompatible with each other. + The existing behavior -- ignoring the metaclass for several steps + of type creation -- is unsafe in general, since (meta)classes assume that + ``tp_new`` was called. + There is no simple general workaround. One of the following may work for you: + + - If you control the metaclass, avoid using ``tp_new`` in it: + + - If initialization can be skipped, it can be done in + :c:member:`~PyTypeObject.tp_init` instead. + - If the metaclass doesn't need to be instantiated from Python, + set its ``tp_new`` to ``NULL`` using + the :c:macro:`Py_TPFLAGS_DISALLOW_INSTANTIATION` flag. + This makes it acceptable for ``PyType_From*`` functions. + + - Avoid ``PyType_From*`` functions: if you don't need C-specific features + (slots or setting the instance size), create types by :ref:`calling <call>` + the metaclass. + + - If you *know* the ``tp_new`` can be skipped safely, filter the deprecation + warning out using :func:`warnings.catch_warnings` from Python. + +* :c:var:`PyOS_InputHook` and :c:var:`PyOS_ReadlineFunctionPointer` are no + longer called in :ref:`subinterpreters <sub-interpreter-support>`. This is + because clients generally rely on process-wide global state (since these + callbacks have no way of recovering extension module state). + + This also avoids situations where extensions may find themselves running in a + subinterpreter that they don't support (or haven't yet been loaded in). See + :gh:`104668` for more info. + +* :c:struct:`PyLongObject` has had its internals changed for better performance. + Although the internals of :c:struct:`PyLongObject` are private, they are used + by some extension modules. + The internal fields should no longer be accessed directly, instead the API + functions beginning ``PyLong_...`` should be used instead. + Two new *unstable* API functions are provided for efficient access to the + value of :c:struct:`PyLongObject`\s which fit into a single machine word: + + * :c:func:`PyUnstable_Long_IsCompact` + * :c:func:`PyUnstable_Long_CompactValue` + +* Custom allocators, set via :c:func:`PyMem_SetAllocator`, are now + required to be thread-safe, regardless of memory domain. Allocators + that don't have their own state, including "hooks", are not affected. + If your custom allocator is not already thread-safe and you need + guidance then please create a new GitHub issue + and CC ``@ericsnowcurrently``. + +Deprecated +---------- + +* In accordance with :pep:`699`, the ``ma_version_tag`` field in :c:type:`PyDictObject` + is deprecated for extension modules. Accessing this field will generate a compiler + warning at compile time. This field will be removed in Python 3.14. + (Contributed by Ramvikrams and Kumar Aditya in :gh:`101193`. PEP by Ken Jin.) + +* Deprecate global configuration variable: + + * :c:var:`Py_DebugFlag`: use :c:member:`PyConfig.parser_debug` + * :c:var:`Py_VerboseFlag`: use :c:member:`PyConfig.verbose` + * :c:var:`Py_QuietFlag`: use :c:member:`PyConfig.quiet` + * :c:var:`Py_InteractiveFlag`: use :c:member:`PyConfig.interactive` + * :c:var:`Py_InspectFlag`: use :c:member:`PyConfig.inspect` + * :c:var:`Py_OptimizeFlag`: use :c:member:`PyConfig.optimization_level` + * :c:var:`Py_NoSiteFlag`: use :c:member:`PyConfig.site_import` + * :c:var:`Py_BytesWarningFlag`: use :c:member:`PyConfig.bytes_warning` + * :c:var:`Py_FrozenFlag`: use :c:member:`PyConfig.pathconfig_warnings` + * :c:var:`Py_IgnoreEnvironmentFlag`: use :c:member:`PyConfig.use_environment` + * :c:var:`Py_DontWriteBytecodeFlag`: use :c:member:`PyConfig.write_bytecode` + * :c:var:`Py_NoUserSiteDirectory`: use :c:member:`PyConfig.user_site_directory` + * :c:var:`Py_UnbufferedStdioFlag`: use :c:member:`PyConfig.buffered_stdio` + * :c:var:`Py_HashRandomizationFlag`: use :c:member:`PyConfig.use_hash_seed` + and :c:member:`PyConfig.hash_seed` + * :c:var:`Py_IsolatedFlag`: use :c:member:`PyConfig.isolated` + * :c:var:`Py_LegacyWindowsFSEncodingFlag`: use :c:member:`PyPreConfig.legacy_windows_fs_encoding` + * :c:var:`Py_LegacyWindowsStdioFlag`: use :c:member:`PyConfig.legacy_windows_stdio` + * :c:var:`!Py_FileSystemDefaultEncoding`: use :c:member:`PyConfig.filesystem_encoding` + * :c:var:`!Py_HasFileSystemDefaultEncoding`: use :c:member:`PyConfig.filesystem_encoding` + * :c:var:`!Py_FileSystemDefaultEncodeErrors`: use :c:member:`PyConfig.filesystem_errors` + * :c:var:`!Py_UTF8Mode`: use :c:member:`PyPreConfig.utf8_mode` (see :c:func:`Py_PreInitialize`) + + The :c:func:`Py_InitializeFromConfig` API should be used with + :c:type:`PyConfig` instead. + (Contributed by Victor Stinner in :gh:`77782`.) + +* Creating :c:data:`immutable types <Py_TPFLAGS_IMMUTABLETYPE>` with mutable + bases is deprecated and will be disabled in Python 3.14. (:gh:`95388`) + +* The :file:`structmember.h` header is deprecated, though it continues to be + available and there are no plans to remove it. + + Its contents are now available just by including :file:`Python.h`, + with a ``Py`` prefix added if it was missing: + + - :c:struct:`PyMemberDef`, :c:func:`PyMember_GetOne` and + :c:func:`PyMember_SetOne` + - Type macros like :c:macro:`Py_T_INT`, :c:macro:`Py_T_DOUBLE`, etc. + (previously ``T_INT``, ``T_DOUBLE``, etc.) + - The flags :c:macro:`Py_READONLY` (previously ``READONLY``) and + :c:macro:`Py_AUDIT_READ` (previously all uppercase) + + Several items are not exposed from :file:`Python.h`: + + - :c:macro:`T_OBJECT` (use :c:macro:`Py_T_OBJECT_EX`) + - :c:macro:`T_NONE` (previously undocumented, and pretty quirky) + - The macro ``WRITE_RESTRICTED`` which does nothing. + - The macros ``RESTRICTED`` and ``READ_RESTRICTED``, equivalents of + :c:macro:`Py_AUDIT_READ`. + - In some configurations, ``<stddef.h>`` is not included from :file:`Python.h`. + It should be included manually when using ``offsetof()``. + + The deprecated header continues to provide its original + contents under the original names. + Your old code can stay unchanged, unless the extra include and non-namespaced + macros bother you greatly. + + (Contributed in :gh:`47146` by Petr Viktorin, based on + earlier work by Alexander Belopolsky and Matthias Braun.) + +* :c:func:`PyErr_Fetch` and :c:func:`PyErr_Restore` are deprecated. + Use :c:func:`PyErr_GetRaisedException` and + :c:func:`PyErr_SetRaisedException` instead. + (Contributed by Mark Shannon in :gh:`101578`.) + +* :c:func:`!PyErr_Display` is deprecated. Use :c:func:`PyErr_DisplayException` + instead. (Contributed by Irit Katriel in :gh:`102755`). + +* ``_PyErr_ChainExceptions`` is deprecated. Use ``_PyErr_ChainExceptions1`` + instead. (Contributed by Irit Katriel in :gh:`102192`.) + +* Using :c:func:`PyType_FromSpec`, :c:func:`PyType_FromSpecWithBases` + or :c:func:`PyType_FromModuleAndSpec` to create a class whose metaclass + overrides :c:member:`~PyTypeObject.tp_new` is deprecated. + Call the metaclass instead. + +Pending Removal in Python 3.14 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +* The ``ma_version_tag`` field in :c:type:`PyDictObject` for extension modules + (:pep:`699`; :gh:`101193`). + +* Global configuration variables: + + * :c:var:`Py_DebugFlag`: use :c:member:`PyConfig.parser_debug` + * :c:var:`Py_VerboseFlag`: use :c:member:`PyConfig.verbose` + * :c:var:`Py_QuietFlag`: use :c:member:`PyConfig.quiet` + * :c:var:`Py_InteractiveFlag`: use :c:member:`PyConfig.interactive` + * :c:var:`Py_InspectFlag`: use :c:member:`PyConfig.inspect` + * :c:var:`Py_OptimizeFlag`: use :c:member:`PyConfig.optimization_level` + * :c:var:`Py_NoSiteFlag`: use :c:member:`PyConfig.site_import` + * :c:var:`Py_BytesWarningFlag`: use :c:member:`PyConfig.bytes_warning` + * :c:var:`Py_FrozenFlag`: use :c:member:`PyConfig.pathconfig_warnings` + * :c:var:`Py_IgnoreEnvironmentFlag`: use :c:member:`PyConfig.use_environment` + * :c:var:`Py_DontWriteBytecodeFlag`: use :c:member:`PyConfig.write_bytecode` + * :c:var:`Py_NoUserSiteDirectory`: use :c:member:`PyConfig.user_site_directory` + * :c:var:`Py_UnbufferedStdioFlag`: use :c:member:`PyConfig.buffered_stdio` + * :c:var:`Py_HashRandomizationFlag`: use :c:member:`PyConfig.use_hash_seed` + and :c:member:`PyConfig.hash_seed` + * :c:var:`Py_IsolatedFlag`: use :c:member:`PyConfig.isolated` + * :c:var:`Py_LegacyWindowsFSEncodingFlag`: use :c:member:`PyPreConfig.legacy_windows_fs_encoding` + * :c:var:`Py_LegacyWindowsStdioFlag`: use :c:member:`PyConfig.legacy_windows_stdio` + * :c:var:`!Py_FileSystemDefaultEncoding`: use :c:member:`PyConfig.filesystem_encoding` + * :c:var:`!Py_HasFileSystemDefaultEncoding`: use :c:member:`PyConfig.filesystem_encoding` + * :c:var:`!Py_FileSystemDefaultEncodeErrors`: use :c:member:`PyConfig.filesystem_errors` + * :c:var:`!Py_UTF8Mode`: use :c:member:`PyPreConfig.utf8_mode` (see :c:func:`Py_PreInitialize`) + + The :c:func:`Py_InitializeFromConfig` API should be used with + :c:type:`PyConfig` instead. + +* Creating :c:data:`immutable types <Py_TPFLAGS_IMMUTABLETYPE>` with mutable + bases (:gh:`95388`). + +Pending Removal in Python 3.15 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +* :c:func:`PyImport_ImportModuleNoBlock`: use :c:func:`PyImport_ImportModule` +* :c:type:`!Py_UNICODE_WIDE` type: use :c:type:`wchar_t` +* :c:type:`Py_UNICODE` type: use :c:type:`wchar_t` +* Python initialization functions: + + * :c:func:`PySys_ResetWarnOptions`: clear :data:`sys.warnoptions` and + :data:`!warnings.filters` + * :c:func:`Py_GetExecPrefix`: get :data:`sys.exec_prefix` + * :c:func:`Py_GetPath`: get :data:`sys.path` + * :c:func:`Py_GetPrefix`: get :data:`sys.prefix` + * :c:func:`Py_GetProgramFullPath`: get :data:`sys.executable` + * :c:func:`Py_GetProgramName`: get :data:`sys.executable` + * :c:func:`Py_GetPythonHome`: get :c:member:`PyConfig.home` or + the :envvar:`PYTHONHOME` environment variable + +Pending Removal in Future Versions +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The following APIs are deprecated and will be removed, +although there is currently no date scheduled for their removal. + +* :c:macro:`Py_TPFLAGS_HAVE_FINALIZE`: unneeded since Python 3.8 +* :c:func:`PyErr_Fetch`: use :c:func:`PyErr_GetRaisedException` +* :c:func:`PyErr_NormalizeException`: use :c:func:`PyErr_GetRaisedException` +* :c:func:`PyErr_Restore`: use :c:func:`PyErr_SetRaisedException` +* :c:func:`PyModule_GetFilename`: use :c:func:`PyModule_GetFilenameObject` +* :c:func:`PyOS_AfterFork`: use :c:func:`PyOS_AfterFork_Child` +* :c:func:`PySlice_GetIndicesEx`: use :c:func:`PySlice_Unpack` and :c:func:`PySlice_AdjustIndices` +* :c:func:`!PyUnicode_AsDecodedObject`: use :c:func:`PyCodec_Decode` +* :c:func:`!PyUnicode_AsDecodedUnicode`: use :c:func:`PyCodec_Decode` +* :c:func:`!PyUnicode_AsEncodedObject`: use :c:func:`PyCodec_Encode` +* :c:func:`!PyUnicode_AsEncodedUnicode`: use :c:func:`PyCodec_Encode` +* :c:func:`PyUnicode_READY`: unneeded since Python 3.12 +* :c:func:`!PyErr_Display`: use :c:func:`PyErr_DisplayException` +* :c:func:`!_PyErr_ChainExceptions`: use ``_PyErr_ChainExceptions1`` +* :c:member:`!PyBytesObject.ob_shash` member: + call :c:func:`PyObject_Hash` instead +* :c:member:`!PyDictObject.ma_version_tag` member +* Thread Local Storage (TLS) API: + + * :c:func:`PyThread_create_key`: use :c:func:`PyThread_tss_alloc` + * :c:func:`PyThread_delete_key`: use :c:func:`PyThread_tss_free` + * :c:func:`PyThread_set_key_value`: use :c:func:`PyThread_tss_set` + * :c:func:`PyThread_get_key_value`: use :c:func:`PyThread_tss_get` + * :c:func:`PyThread_delete_key_value`: use :c:func:`PyThread_tss_delete` + * :c:func:`PyThread_ReInitTLS`: unneeded since Python 3.7 + +Removed +------- + +* Remove the :file:`token.h` header file. There was never any public tokenizer C + API. The :file:`token.h` header file was only designed to be used by Python + internals. + (Contributed by Victor Stinner in :gh:`92651`.) + +* Legacy Unicode APIs have been removed. See :pep:`623` for detail. + + * :c:macro:`!PyUnicode_WCHAR_KIND` + * :c:func:`!PyUnicode_AS_UNICODE` + * :c:func:`!PyUnicode_AsUnicode` + * :c:func:`!PyUnicode_AsUnicodeAndSize` + * :c:func:`!PyUnicode_AS_DATA` + * :c:func:`!PyUnicode_FromUnicode` + * :c:func:`!PyUnicode_GET_SIZE` + * :c:func:`!PyUnicode_GetSize` + * :c:func:`!PyUnicode_GET_DATA_SIZE` + +* Remove the ``PyUnicode_InternImmortal()`` function macro. + (Contributed by Victor Stinner in :gh:`85858`.) + +* Remove ``Jython`` compatibility hacks from several stdlib modules and tests. + (Contributed by Nikita Sobolev in :gh:`99482`.) + +* Remove ``_use_broken_old_ctypes_structure_semantics_`` flag + from :mod:`ctypes` module. + (Contributed by Nikita Sobolev in :gh:`99285`.) diff --git a/Doc/whatsnew/3.2.rst b/Doc/whatsnew/3.2.rst index 3becd3f7..ba1cb4ae 100644 --- a/Doc/whatsnew/3.2.rst +++ b/Doc/whatsnew/3.2.rst @@ -319,18 +319,18 @@ aspects that are visible to the programmer: >>> collections.__cached__ # doctest: +SKIP 'c:/py32/lib/__pycache__/collections.cpython-32.pyc' -* The tag that is unique to each interpreter is accessible from the :mod:`imp` +* The tag that is unique to each interpreter is accessible from the :mod:`!imp` module: - >>> import imp + >>> import imp # doctest: +SKIP >>> imp.get_tag() # doctest: +SKIP 'cpython-32' * Scripts that try to deduce source filename from the imported file now need to be smarter. It is no longer sufficient to simply strip the "c" from a ".pyc" - filename. Instead, use the new functions in the :mod:`imp` module: + filename. Instead, use the new functions in the :mod:`!imp` module: - >>> imp.source_from_cache('c:/py32/lib/__pycache__/collections.cpython-32.pyc') + >>> imp.source_from_cache('c:/py32/lib/__pycache__/collections.cpython-32.pyc') # doctest: +SKIP 'c:/py32/lib/collections.py' >>> imp.cache_from_source('c:/py32/lib/collections.py') # doctest: +SKIP 'c:/py32/lib/__pycache__/collections.cpython-32.pyc' @@ -424,7 +424,7 @@ protocols, the users must to be able access the environment using native strings even though the underlying platform may have a different convention. To bridge this gap, the :mod:`wsgiref` module has a new function, :func:`wsgiref.handlers.read_environ` for transcoding CGI variables from -:attr:`os.environ` into native strings and returning a new dictionary. +:data:`os.environ` into native strings and returning a new dictionary. .. seealso:: @@ -468,6 +468,7 @@ Some smaller changes made to the core Python language are: >>> class LowerCasedDict(dict): ... def __getitem__(self, key): ... return dict.__getitem__(self, key.lower()) + ... >>> lcd = LowerCasedDict(part='widgets', quantity=10) >>> 'There are {QUANTITY} {Part} in stock'.format_map(lcd) 'There are 10 widgets in stock' @@ -475,6 +476,7 @@ Some smaller changes made to the core Python language are: >>> class PlaceholderDict(dict): ... def __missing__(self, key): ... return '<{}>'.format(key) + ... >>> 'Hello {name}, welcome to {location}'.format_map(PlaceholderDict()) 'Hello <name>, welcome to <location>' @@ -483,7 +485,7 @@ Some smaller changes made to the core Python language are: * The interpreter can now be started with a quiet option, ``-q``, to prevent the copyright and version information from being displayed in the interactive - mode. The option can be introspected using the :attr:`sys.flags` attribute: + mode. The option can be introspected using the :data:`sys.flags` attribute: .. code-block:: shell-session @@ -564,9 +566,9 @@ Some smaller changes made to the core Python language are: (See :issue:`4617`.) -* The internal :c:type:`structsequence` tool now creates subclasses of tuple. +* :ref:`Struct sequence types <struct-sequence-objects>` are now subclasses of tuple. This means that C structures like those returned by :func:`os.stat`, - :func:`time.gmtime`, and :attr:`sys.version_info` now work like a + :func:`time.gmtime`, and :data:`sys.version_info` now work like a :term:`named tuple` and now work with functions and methods that expect a tuple as an argument. This is a big step forward in making the C structures as flexible as their pure Python counterparts: @@ -596,7 +598,7 @@ Some smaller changes made to the core Python language are: module, or on the command line. A :exc:`ResourceWarning` is issued at interpreter shutdown if the - :data:`gc.garbage` list isn't empty, and if :attr:`gc.DEBUG_UNCOLLECTABLE` is + :data:`gc.garbage` list isn't empty, and if :const:`gc.DEBUG_UNCOLLECTABLE` is set, all uncollectable objects are printed. This is meant to make the programmer aware that their code contains object finalization issues. @@ -621,7 +623,7 @@ Some smaller changes made to the core Python language are: :class:`collections.Sequence` :term:`abstract base class`. As a result, the language will have a more uniform API. In addition, :class:`range` objects now support slicing and negative indices, even with values larger than - :attr:`sys.maxsize`. This makes *range* more interoperable with lists:: + :data:`sys.maxsize`. This makes *range* more interoperable with lists:: >>> range(0, 100, 2).count(10) 1 @@ -783,8 +785,8 @@ functools (Contributed by Raymond Hettinger and incorporating design ideas from Jim Baker, Miki Tebeka, and Nick Coghlan; see `recipe 498245 - <https://code.activestate.com/recipes/498245>`_\, `recipe 577479 - <https://code.activestate.com/recipes/577479>`_\, :issue:`10586`, and + <https://code.activestate.com/recipes/498245/>`_\, `recipe 577479 + <https://code.activestate.com/recipes/577479/>`_\, :issue:`10586`, and :issue:`10593`.) * The :func:`functools.wraps` decorator now adds a :attr:`__wrapped__` attribute @@ -1005,13 +1007,13 @@ datetime and time after 1900. The new supported year range is from 1000 to 9999 inclusive. * Whenever a two-digit year is used in a time tuple, the interpretation has been - governed by :attr:`time.accept2dyear`. The default is ``True`` which means that + governed by :data:`time.accept2dyear`. The default is ``True`` which means that for a two-digit year, the century is guessed according to the POSIX rules governing the ``%y`` strptime format. Starting with Py3.2, use of the century guessing heuristic will emit a :exc:`DeprecationWarning`. Instead, it is recommended that - :attr:`time.accept2dyear` be set to ``False`` so that large date ranges + :data:`time.accept2dyear` be set to ``False`` so that large date ranges can be used without guesswork:: >>> import time, warnings @@ -1029,7 +1031,7 @@ datetime and time 'Fri Jan 1 12:34:56 11' Several functions now have significantly expanded date ranges. When - :attr:`time.accept2dyear` is false, the :func:`time.asctime` function will + :data:`time.accept2dyear` is false, the :func:`time.asctime` function will accept any year that fits in a C int, while the :func:`time.mktime` and :func:`time.strftime` functions will accept the full range supported by the corresponding operating system functions. @@ -1192,11 +1194,11 @@ can be set to "$" for the shell-style formatting provided by If no configuration is set-up before a logging event occurs, there is now a default configuration using a :class:`~logging.StreamHandler` directed to -:attr:`sys.stderr` for events of ``WARNING`` level or higher. Formerly, an +:data:`sys.stderr` for events of ``WARNING`` level or higher. Formerly, an event occurring before a configuration was set-up would either raise an exception or silently drop the event depending on the value of -:attr:`logging.raiseExceptions`. The new default handler is stored in -:attr:`logging.lastResort`. +:data:`logging.raiseExceptions`. The new default handler is stored in +:data:`logging.lastResort`. The use of filters has been simplified. Instead of creating a :class:`~logging.Filter` object, the predicate can be any Python callable that @@ -1298,7 +1300,7 @@ values are equal (:issue:`8188`):: hash(Decimal("1.5")) == hash(complex(1.5, 0)) Some of the hashing details are exposed through a new attribute, -:attr:`sys.hash_info`, which describes the bit width of the hash value, the +:data:`sys.hash_info`, which describes the bit width of the hash value, the prime modulus, the hash values for *infinity* and *nan*, and the multiplier used for the imaginary part of a number: @@ -1386,7 +1388,7 @@ select ------ The :mod:`select` module now exposes a new, constant attribute, -:attr:`~select.PIPE_BUF`, which gives the minimum number of bytes which are +:const:`~select.PIPE_BUF`, which gives the minimum number of bytes which are guaranteed not to block when :func:`select.select` says a pipe is ready for writing. @@ -1527,7 +1529,7 @@ filenames: b'Sehensw\xc3\xbcrdigkeiten' Some operating systems allow direct access to encoded bytes in the -environment. If so, the :attr:`os.supports_bytes_environ` constant will be +environment. If so, the :const:`os.supports_bytes_environ` constant will be true. For direct access to encoded environment variables (if available), @@ -1664,9 +1666,9 @@ for secure (encrypted, authenticated) internet connections: algorithm" error. * The version of OpenSSL being used is now accessible using the module - attributes :data:`ssl.OPENSSL_VERSION` (a string), - :data:`ssl.OPENSSL_VERSION_INFO` (a 5-tuple), and - :data:`ssl.OPENSSL_VERSION_NUMBER` (an integer). + attributes :const:`ssl.OPENSSL_VERSION` (a string), + :const:`ssl.OPENSSL_VERSION_INFO` (a 5-tuple), and + :const:`ssl.OPENSSL_VERSION_NUMBER` (an integer). (Contributed by Antoine Pitrou in :issue:`8850`, :issue:`1589`, :issue:`8322`, :issue:`5639`, :issue:`4870`, :issue:`8484`, and :issue:`8321`.) @@ -1817,8 +1819,7 @@ names. =============================== ============================== Likewise, the ``TestCase.fail*`` methods deprecated in Python 3.1 are expected - to be removed in Python 3.3. Also see the :ref:`deprecated-aliases` section in - the :mod:`unittest` documentation. + to be removed in Python 3.3. (Contributed by Ezio Melotti; :issue:`9424`.) @@ -1887,6 +1888,7 @@ inspect >>> from inspect import getgeneratorstate >>> def gen(): ... yield 'demo' + ... >>> g = gen() >>> getgeneratorstate(g) 'GEN_CREATED' @@ -2057,7 +2059,7 @@ information: such as "3.2". It also provides access to the paths and variables corresponding to one of -seven named schemes used by :mod:`distutils`. Those include *posix_prefix*, +seven named schemes used by ``distutils``. Those include *posix_prefix*, *posix_home*, *posix_user*, *nt*, *nt_user*, *os2*, *os2_home*: * :func:`~sysconfig.get_paths` makes a dictionary containing installation paths @@ -2300,7 +2302,7 @@ turtledemo The demonstration code for the :mod:`turtle` module was moved from the *Demo* directory to main library. It includes over a dozen sample scripts with -lively displays. Being on :attr:`sys.path`, it can now be run directly +lively displays. Being on :data:`sys.path`, it can now be run directly from the command-line: .. code-block:: shell-session @@ -2564,10 +2566,10 @@ Changes to Python's build process and to the C API include: (:issue:`2443`). * A new C API function :c:func:`PySys_SetArgvEx` allows an embedded interpreter - to set :attr:`sys.argv` without also modifying :attr:`sys.path` + to set :data:`sys.argv` without also modifying :data:`sys.path` (:issue:`5753`). -* :c:macro:`PyEval_CallObject` is now only available in macro form. The +* :c:func:`!PyEval_CallObject` is now only available in macro form. The function declaration, which was kept for backwards compatibility reasons, is now removed -- the macro was introduced in 1997 (:issue:`8276`). @@ -2601,7 +2603,7 @@ Also, there were a number of updates to the Mac OS X build, see for details. For users running a 32/64-bit build, there is a known problem with the default Tcl/Tk on Mac OS X 10.6. Accordingly, we recommend installing an updated alternative such as -`ActiveState Tcl/Tk 8.5.9 <https://www.activestate.com/activetcl/downloads>`_\. +`ActiveState Tcl/Tk 8.5.9 <https://web.archive.org/web/20101208191259/https://www.activestate.com/activetcl/downloads>`_\. See https://www.python.org/download/mac/tcltk/ for additional details. Porting to Python 3.2 @@ -2656,7 +2658,7 @@ require changes to your code: * "t#" format has been removed: use "s#" or "s*" instead * "w" and "w#" formats has been removed: use "w*" instead -* The :c:type:`PyCObject` type, deprecated in 3.1, has been removed. To wrap +* The :c:type:`!PyCObject` type, deprecated in 3.1, has been removed. To wrap opaque C pointers in Python objects, the :c:type:`PyCapsule` API should be used instead; the new type has a well-defined interface for passing typing safety information and a less complicated signature for calling a destructor. @@ -2729,15 +2731,15 @@ require changes to your code: (Contributed by Antoine Pitrou, :issue:`10272`.) -* The misleading functions :c:func:`PyEval_AcquireLock()` and - :c:func:`PyEval_ReleaseLock()` have been officially deprecated. The - thread-state aware APIs (such as :c:func:`PyEval_SaveThread()` - and :c:func:`PyEval_RestoreThread()`) should be used instead. +* The misleading functions :c:func:`!PyEval_AcquireLock` and + :c:func:`!PyEval_ReleaseLock` have been officially deprecated. The + thread-state aware APIs (such as :c:func:`PyEval_SaveThread` + and :c:func:`PyEval_RestoreThread`) should be used instead. * Due to security risks, :func:`asyncore.handle_accept` has been deprecated, and a new function, :func:`asyncore.handle_accepted`, was added to replace it. (Contributed by Giampaolo Rodola in :issue:`6706`.) -* Due to the new :term:`GIL` implementation, :c:func:`PyEval_InitThreads()` - cannot be called before :c:func:`Py_Initialize()` anymore. +* Due to the new :term:`GIL` implementation, :c:func:`!PyEval_InitThreads` + cannot be called before :c:func:`Py_Initialize` anymore. diff --git a/Doc/whatsnew/3.3.rst b/Doc/whatsnew/3.3.rst index 96a63257..3361789f 100644 --- a/Doc/whatsnew/3.3.rst +++ b/Doc/whatsnew/3.3.rst @@ -249,7 +249,7 @@ Changes introduced by :pep:`393` are the following: non-BMP code points. * The value of :data:`sys.maxunicode` is now always ``1114111`` (``0x10FFFF`` - in hexadecimal). The :c:func:`PyUnicode_GetMax` function still returns + in hexadecimal). The :c:func:`!PyUnicode_GetMax` function still returns either ``0xFFFF`` or ``0x10FFFF`` for backward compatibility, and it should not be used with the new Unicode API (see :issue:`13054`). @@ -560,6 +560,7 @@ Example with (non-bound) methods:: >>> class C: ... def meth(self): ... pass + ... >>> C.meth.__name__ 'meth' >>> C.meth.__qualname__ @@ -647,7 +648,7 @@ PEP 421: Adding sys.implementation A new attribute on the :mod:`sys` module exposes details specific to the implementation of the currently running interpreter. The initial set of -attributes on :attr:`sys.implementation` are ``name``, ``version``, +attributes on :data:`sys.implementation` are ``name``, ``version``, ``hexversion``, and ``cache_tag``. The intention of ``sys.implementation`` is to consolidate into one namespace @@ -684,7 +685,7 @@ through normal attribute access. Using importlib as the Implementation of Import =============================================== :issue:`2377` - Replace __import__ w/ importlib.__import__ -:issue:`13959` - Re-implement parts of :mod:`imp` in pure Python +:issue:`13959` - Re-implement parts of :mod:`!imp` in pure Python :issue:`14605` - Make import machinery explicit :issue:`14646` - Require loaders set __loader__ and __package__ @@ -713,12 +714,12 @@ to properly delineate between :term:`meta path finders <meta path finder>` and :term:`path entry finders <path entry finder>` by introducing :class:`importlib.abc.MetaPathFinder` and :class:`importlib.abc.PathEntryFinder`, respectively. The old ABC of -:class:`importlib.abc.Finder` is now only provided for backwards-compatibility +:class:`!importlib.abc.Finder` is now only provided for backwards-compatibility and does not enforce any method requirements. In terms of finders, :class:`importlib.machinery.FileFinder` exposes the mechanism used to search for source and bytecode files of a module. Previously -this class was an implicit member of :attr:`sys.path_hooks`. +this class was an implicit member of :data:`sys.path_hooks`. For loaders, the new abstract base class :class:`importlib.abc.FileLoader` helps write a loader that uses the file system as the storage mechanism for a module's @@ -734,7 +735,7 @@ provide the full name of the module now instead of just the tail end of the module's name. The :func:`importlib.invalidate_caches` function will now call the method with -the same name on all finders cached in :attr:`sys.path_importer_cache` to help +the same name on all finders cached in :data:`sys.path_importer_cache` to help clean up any stored state as necessary. Visible Changes @@ -744,8 +745,8 @@ For potential required changes to code, see the `Porting Python code`_ section. Beyond the expanse of what :mod:`importlib` now exposes, there are other -visible changes to import. The biggest is that :attr:`sys.meta_path` and -:attr:`sys.path_hooks` now store all of the meta path finders and path entry +visible changes to import. The biggest is that :data:`sys.meta_path` and +:data:`sys.path_hooks` now store all of the meta path finders and path entry hooks used by import. Previously the finders were implicit and hidden within the C code of import instead of being directly exposed. This means that one can now easily remove or change the order of the various finders to fit one's needs. @@ -760,9 +761,9 @@ Loaders are also now expected to set the ``__package__`` attribute from :pep:`366`. Once again, import itself is already setting this on all loaders from :mod:`importlib` and import itself is setting the attribute post-load. -``None`` is now inserted into :attr:`sys.path_importer_cache` when no finder -can be found on :attr:`sys.path_hooks`. Since :class:`imp.NullImporter` is not -directly exposed on :attr:`sys.path_hooks` it could no longer be relied upon to +``None`` is now inserted into :data:`sys.path_importer_cache` when no finder +can be found on :data:`sys.path_hooks`. Since :class:`!imp.NullImporter` is not +directly exposed on :data:`sys.path_hooks` it could no longer be relied upon to always be available to use as a value representing no finder found. All other changes relate to semantic changes which should be taken into @@ -841,7 +842,7 @@ Builtin functions and types * :func:`open` gets a new *opener* parameter: the underlying file descriptor for the file object is then obtained by calling *opener* with (*file*, - *flags*). It can be used to use custom flags like :data:`os.O_CLOEXEC` for + *flags*). It can be used to use custom flags like :const:`os.O_CLOEXEC` for example. The ``'x'`` mode was added: open for exclusive creation, failing if the file already exists. * :func:`print`: added the *flush* keyword argument. If the *flush* keyword @@ -1126,7 +1127,7 @@ Features * If Python is compiled without threads, the C version automatically disables the expensive thread local context machinery. In this case, - the variable :data:`~decimal.HAVE_THREADS` is set to ``False``. + the variable :const:`~decimal.HAVE_THREADS` is set to ``False``. API changes ~~~~~~~~~~~ @@ -1134,20 +1135,20 @@ API changes * The C module has the following context limits, depending on the machine architecture: - +-------------------+---------------------+------------------------------+ - | | 32-bit | 64-bit | - +===================+=====================+==============================+ - | :const:`MAX_PREC` | :const:`425000000` | :const:`999999999999999999` | - +-------------------+---------------------+------------------------------+ - | :const:`MAX_EMAX` | :const:`425000000` | :const:`999999999999999999` | - +-------------------+---------------------+------------------------------+ - | :const:`MIN_EMIN` | :const:`-425000000` | :const:`-999999999999999999` | - +-------------------+---------------------+------------------------------+ + +-------------------+----------------+-------------------------+ + | | 32-bit | 64-bit | + +===================+================+=========================+ + | :const:`MAX_PREC` | ``425000000`` | ``999999999999999999`` | + +-------------------+----------------+-------------------------+ + | :const:`MAX_EMAX` | ``425000000`` | ``999999999999999999`` | + +-------------------+----------------+-------------------------+ + | :const:`MIN_EMIN` | ``-425000000`` | ``-999999999999999999`` | + +-------------------+----------------+-------------------------+ * In the context templates (:class:`~decimal.DefaultContext`, :class:`~decimal.BasicContext` and :class:`~decimal.ExtendedContext`) the magnitude of :attr:`~decimal.Context.Emax` and - :attr:`~decimal.Context.Emin` has changed to :const:`999999`. + :attr:`~decimal.Context.Emin` has changed to ``999999``. * The :class:`~decimal.Decimal` constructor in decimal.py does not observe the context limits and converts values with arbitrary exponents or precision @@ -1575,8 +1576,8 @@ os -- * The :mod:`os` module has a new :func:`~os.pipe2` function that makes it - possible to create a pipe with :data:`~os.O_CLOEXEC` or - :data:`~os.O_NONBLOCK` flags set atomically. This is especially useful to + possible to create a pipe with :const:`~os.O_CLOEXEC` or + :const:`~os.O_NONBLOCK` flags set atomically. This is especially useful to avoid race conditions in multi-threaded programs. * The :mod:`os` module has a new :func:`~os.sendfile` function which provides @@ -1690,9 +1691,9 @@ os * Some platforms now support additional constants for the :func:`~os.lseek` function, such as ``os.SEEK_HOLE`` and ``os.SEEK_DATA``. -* New constants :data:`~os.RTLD_LAZY`, :data:`~os.RTLD_NOW`, - :data:`~os.RTLD_GLOBAL`, :data:`~os.RTLD_LOCAL`, :data:`~os.RTLD_NODELETE`, - :data:`~os.RTLD_NOLOAD`, and :data:`~os.RTLD_DEEPBIND` are available on +* New constants :const:`~os.RTLD_LAZY`, :const:`~os.RTLD_NOW`, + :const:`~os.RTLD_GLOBAL`, :const:`~os.RTLD_LOCAL`, :const:`~os.RTLD_NODELETE`, + :const:`~os.RTLD_NOLOAD`, and :const:`~os.RTLD_DEEPBIND` are available on platforms that support them. These are for use with the :func:`sys.setdlopenflags` function, and supersede the similar constants defined in :mod:`ctypes` and :mod:`DLFCN`. (Contributed by Victor Stinner @@ -1892,7 +1893,7 @@ socket * The :class:`~socket.socket` class now supports the PF_RDS protocol family (https://en.wikipedia.org/wiki/Reliable_Datagram_Sockets and - https://oss.oracle.com/projects/rds/). + `https://oss.oracle.com/projects/rds <https://web.archive.org/web/20130115155505/https://oss.oracle.com/projects/rds/>`__). * The :class:`~socket.socket` class now supports the ``PF_SYSTEM`` protocol family on OS X. (Contributed by Michael Goderbauer in :issue:`13777`.) @@ -1951,7 +1952,7 @@ ssl * You can query the SSL compression algorithm used by an SSL socket, thanks to its new :meth:`~ssl.SSLSocket.compression` method. The new attribute - :attr:`~ssl.OP_NO_COMPRESSION` can be used to disable compression. + :const:`~ssl.OP_NO_COMPRESSION` can be used to disable compression. (Contributed by Antoine Pitrou in :issue:`13634`.) * Support has been added for the Next Protocol Negotiation extension using @@ -1965,7 +1966,7 @@ ssl * The :func:`~ssl.get_server_certificate` function now supports IPv6. (Contributed by Charles-François Natali in :issue:`11811`.) -* New attribute :attr:`~ssl.OP_CIPHER_SERVER_PREFERENCE` allows setting +* New attribute :const:`~ssl.OP_CIPHER_SERVER_PREFERENCE` allows setting SSLv3 server sockets to use the server's cipher ordering preference rather than the client's (:issue:`13635`). @@ -1983,7 +1984,7 @@ the form '-rwxrwxrwx'. struct ------ -The :mod:`struct` module now supports ``ssize_t`` and ``size_t`` via the +The :mod:`struct` module now supports :c:type:`ssize_t` and :c:type:`size_t` via the new codes ``n`` and ``N``, respectively. (Contributed by Antoine Pitrou in :issue:`3163`.) @@ -1994,7 +1995,7 @@ subprocess Command strings can now be bytes objects on posix platforms. (Contributed by Victor Stinner in :issue:`8513`.) -A new constant :data:`~subprocess.DEVNULL` allows suppressing output in a +A new constant :const:`~subprocess.DEVNULL` allows suppressing output in a platform-independent fashion. (Contributed by Ross Lagerwall in :issue:`5870`.) @@ -2066,7 +2067,7 @@ The :pep:`418` added new functions to the :mod:`time` module: Other new functions: * :func:`~time.clock_getres`, :func:`~time.clock_gettime` and - :func:`~time.clock_settime` functions with ``CLOCK_xxx`` constants. + :func:`~time.clock_settime` functions with :samp:`CLOCK_{xxx}` constants. (Contributed by Victor Stinner in :issue:`10278`.) To improve cross platform consistency, :func:`~time.sleep` now raises a @@ -2140,7 +2141,7 @@ New attribute :attr:`zlib.Decompress.eof` makes it possible to distinguish between a properly formed compressed stream and an incomplete or truncated one. (Contributed by Nadeem Vawda in :issue:`12646`.) -New attribute :attr:`zlib.ZLIB_RUNTIME_VERSION` reports the version string of +New attribute :const:`zlib.ZLIB_RUNTIME_VERSION` reports the version string of the underlying ``zlib`` library that is loaded at runtime. (Contributed by Torsten Landschoff in :issue:`12306`.) @@ -2194,8 +2195,8 @@ Changes to Python's build process and to the C API include: * :c:func:`PyUnicode_AsUCS4`, :c:func:`PyUnicode_AsUCS4Copy` * :c:macro:`PyUnicode_DATA`, :c:macro:`PyUnicode_1BYTE_DATA`, :c:macro:`PyUnicode_2BYTE_DATA`, :c:macro:`PyUnicode_4BYTE_DATA` - * :c:macro:`PyUnicode_KIND` with :c:type:`PyUnicode_Kind` enum: - :c:data:`PyUnicode_WCHAR_KIND`, :c:data:`PyUnicode_1BYTE_KIND`, + * :c:macro:`PyUnicode_KIND` with :c:enum:`PyUnicode_Kind` enum: + :c:data:`!PyUnicode_WCHAR_KIND`, :c:data:`PyUnicode_1BYTE_KIND`, :c:data:`PyUnicode_2BYTE_KIND`, :c:data:`PyUnicode_4BYTE_KIND` * :c:macro:`PyUnicode_READ`, :c:macro:`PyUnicode_READ_CHAR`, :c:macro:`PyUnicode_WRITE` * :c:macro:`PyUnicode_MAX_CHAR_VALUE` @@ -2269,58 +2270,58 @@ removed in Python 4. All functions using this type are deprecated: Unicode functions and methods using :c:type:`Py_UNICODE` and :c:expr:`Py_UNICODE*` types: -* :c:macro:`PyUnicode_FromUnicode`: use :c:func:`PyUnicode_FromWideChar` or +* :c:macro:`!PyUnicode_FromUnicode`: use :c:func:`PyUnicode_FromWideChar` or :c:func:`PyUnicode_FromKindAndData` -* :c:macro:`PyUnicode_AS_UNICODE`, :c:func:`PyUnicode_AsUnicode`, - :c:func:`PyUnicode_AsUnicodeAndSize`: use :c:func:`PyUnicode_AsWideCharString` -* :c:macro:`PyUnicode_AS_DATA`: use :c:macro:`PyUnicode_DATA` with +* :c:macro:`!PyUnicode_AS_UNICODE`, :c:func:`!PyUnicode_AsUnicode`, + :c:func:`!PyUnicode_AsUnicodeAndSize`: use :c:func:`PyUnicode_AsWideCharString` +* :c:macro:`!PyUnicode_AS_DATA`: use :c:macro:`PyUnicode_DATA` with :c:macro:`PyUnicode_READ` and :c:macro:`PyUnicode_WRITE` -* :c:macro:`PyUnicode_GET_SIZE`, :c:func:`PyUnicode_GetSize`: use +* :c:macro:`!PyUnicode_GET_SIZE`, :c:func:`!PyUnicode_GetSize`: use :c:macro:`PyUnicode_GET_LENGTH` or :c:func:`PyUnicode_GetLength` -* :c:macro:`PyUnicode_GET_DATA_SIZE`: use +* :c:macro:`!PyUnicode_GET_DATA_SIZE`: use ``PyUnicode_GET_LENGTH(str) * PyUnicode_KIND(str)`` (only work on ready strings) -* :c:func:`PyUnicode_AsUnicodeCopy`: use :c:func:`PyUnicode_AsUCS4Copy` or +* :c:func:`!PyUnicode_AsUnicodeCopy`: use :c:func:`PyUnicode_AsUCS4Copy` or :c:func:`PyUnicode_AsWideCharString` -* :c:func:`PyUnicode_GetMax` +* :c:func:`!PyUnicode_GetMax` Functions and macros manipulating Py_UNICODE* strings: -* :c:macro:`Py_UNICODE_strlen`: use :c:func:`PyUnicode_GetLength` or +* :c:macro:`!Py_UNICODE_strlen()`: use :c:func:`PyUnicode_GetLength` or :c:macro:`PyUnicode_GET_LENGTH` -* :c:macro:`Py_UNICODE_strcat`: use :c:func:`PyUnicode_CopyCharacters` or +* :c:macro:`!Py_UNICODE_strcat()`: use :c:func:`PyUnicode_CopyCharacters` or :c:func:`PyUnicode_FromFormat` -* :c:macro:`Py_UNICODE_strcpy`, :c:macro:`Py_UNICODE_strncpy`, - :c:macro:`Py_UNICODE_COPY`: use :c:func:`PyUnicode_CopyCharacters` or +* :c:macro:`!Py_UNICODE_strcpy()`, :c:macro:`!Py_UNICODE_strncpy()`, + :c:macro:`!Py_UNICODE_COPY()`: use :c:func:`PyUnicode_CopyCharacters` or :c:func:`PyUnicode_Substring` -* :c:macro:`Py_UNICODE_strcmp`: use :c:func:`PyUnicode_Compare` -* :c:macro:`Py_UNICODE_strncmp`: use :c:func:`PyUnicode_Tailmatch` -* :c:macro:`Py_UNICODE_strchr`, :c:macro:`Py_UNICODE_strrchr`: use +* :c:macro:`!Py_UNICODE_strcmp()`: use :c:func:`PyUnicode_Compare` +* :c:macro:`!Py_UNICODE_strncmp()`: use :c:func:`PyUnicode_Tailmatch` +* :c:macro:`!Py_UNICODE_strchr()`, :c:macro:`!Py_UNICODE_strrchr()`: use :c:func:`PyUnicode_FindChar` -* :c:macro:`Py_UNICODE_FILL`: use :c:func:`PyUnicode_Fill` -* :c:macro:`Py_UNICODE_MATCH` +* :c:macro:`!Py_UNICODE_FILL()`: use :c:func:`PyUnicode_Fill` +* :c:macro:`!Py_UNICODE_MATCH` Encoders: -* :c:func:`PyUnicode_Encode`: use :c:func:`PyUnicode_AsEncodedObject` -* :c:func:`PyUnicode_EncodeUTF7` -* :c:func:`PyUnicode_EncodeUTF8`: use :c:func:`PyUnicode_AsUTF8` or +* :c:func:`!PyUnicode_Encode`: use :c:func:`!PyUnicode_AsEncodedObject` +* :c:func:`!PyUnicode_EncodeUTF7` +* :c:func:`!PyUnicode_EncodeUTF8`: use :c:func:`PyUnicode_AsUTF8` or :c:func:`PyUnicode_AsUTF8String` -* :c:func:`PyUnicode_EncodeUTF32` -* :c:func:`PyUnicode_EncodeUTF16` -* :c:func:`PyUnicode_EncodeUnicodeEscape` use +* :c:func:`!PyUnicode_EncodeUTF32` +* :c:func:`!PyUnicode_EncodeUTF16` +* :c:func:`!PyUnicode_EncodeUnicodeEscape` use :c:func:`PyUnicode_AsUnicodeEscapeString` -* :c:func:`PyUnicode_EncodeRawUnicodeEscape` use +* :c:func:`!PyUnicode_EncodeRawUnicodeEscape` use :c:func:`PyUnicode_AsRawUnicodeEscapeString` -* :c:func:`PyUnicode_EncodeLatin1`: use :c:func:`PyUnicode_AsLatin1String` -* :c:func:`PyUnicode_EncodeASCII`: use :c:func:`PyUnicode_AsASCIIString` -* :c:func:`PyUnicode_EncodeCharmap` -* :c:func:`PyUnicode_TranslateCharmap` -* :c:func:`PyUnicode_EncodeMBCS`: use :c:func:`PyUnicode_AsMBCSString` or +* :c:func:`!PyUnicode_EncodeLatin1`: use :c:func:`PyUnicode_AsLatin1String` +* :c:func:`!PyUnicode_EncodeASCII`: use :c:func:`PyUnicode_AsASCIIString` +* :c:func:`!PyUnicode_EncodeCharmap` +* :c:func:`!PyUnicode_TranslateCharmap` +* :c:func:`!PyUnicode_EncodeMBCS`: use :c:func:`PyUnicode_AsMBCSString` or :c:func:`PyUnicode_EncodeCodePage` (with ``CP_ACP`` code_page) -* :c:func:`PyUnicode_EncodeDecimal`, - :c:func:`PyUnicode_TransformDecimalToASCII` +* :c:func:`!PyUnicode_EncodeDecimal`, + :c:func:`!PyUnicode_TransformDecimalToASCII` Deprecated features @@ -2377,19 +2378,19 @@ Porting Python code * :func:`__import__` no longer allows one to use an index value other than 0 for top-level modules. E.g. ``__import__('sys', level=1)`` is now an error. -* Because :attr:`sys.meta_path` and :attr:`sys.path_hooks` now have finders on +* Because :data:`sys.meta_path` and :data:`sys.path_hooks` now have finders on them by default, you will most likely want to use :meth:`list.insert` instead of :meth:`list.append` to add to those lists. -* Because ``None`` is now inserted into :attr:`sys.path_importer_cache`, if you +* Because ``None`` is now inserted into :data:`sys.path_importer_cache`, if you are clearing out entries in the dictionary of paths that do not have a finder, you will need to remove keys paired with values of ``None`` **and** - :class:`imp.NullImporter` to be backwards-compatible. This will lead to extra + :class:`!imp.NullImporter` to be backwards-compatible. This will lead to extra overhead on older versions of Python that re-insert ``None`` into - :attr:`sys.path_importer_cache` where it represents the use of implicit + :data:`sys.path_importer_cache` where it represents the use of implicit finders, but semantically it should not change anything. -* :class:`importlib.abc.Finder` no longer specifies a ``find_module()`` abstract +* :class:`!importlib.abc.Finder` no longer specifies a ``find_module()`` abstract method that must be implemented. If you were relying on subclasses to implement that method, make sure to check for the method's existence first. You will probably want to check for ``find_loader()`` first, though, in the @@ -2444,7 +2445,7 @@ Porting Python code error instead of sleeping forever. It has always raised an error on posix. * The ``ast.__version__`` constant has been removed. If you need to - make decisions affected by the AST version, use :attr:`sys.version_info` + make decisions affected by the AST version, use :data:`sys.version_info` to make the decision. * Code that used to work around the fact that the :mod:`threading` module used @@ -2461,7 +2462,7 @@ Porting C code -------------- * In the course of changes to the buffer API the undocumented - :c:member:`~Py_buffer.smalltable` member of the + :c:member:`!smalltable` member of the :c:type:`Py_buffer` structure has been removed and the layout of the :c:type:`PyMemoryViewObject` has changed. diff --git a/Doc/whatsnew/3.4.rst b/Doc/whatsnew/3.4.rst index 9f894b40..8e2d0427 100644 --- a/Doc/whatsnew/3.4.rst +++ b/Doc/whatsnew/3.4.rst @@ -247,7 +247,7 @@ projects. However, as this migration is currently still incomplete, the legacy versions of those guides remaining available as :ref:`install-index` -and :ref:`distutils-index`. +and :ref:`setuptools-index`. .. seealso:: @@ -775,7 +775,7 @@ of a given opcode and argument, information that is not otherwise available. doctest ------- -A new :ref:`option flag <doctest-options>`, :data:`~doctest.FAIL_FAST`, halts +A new :ref:`option flag <doctest-options>`, :const:`~doctest.FAIL_FAST`, halts test running as soon as the first failure is detected. (Contributed by R. David Murray and Daniel Urban in :issue:`16522`.) @@ -841,7 +841,7 @@ for example, if the file might have been changed and re-checked in less time than the resolution of a particular filesystem's file modification time field. (Contributed by Mark Levitt in :issue:`18149`.) -New module attribute :data:`~filecmp.DEFAULT_IGNORES` provides the list of +New module attribute :const:`~filecmp.DEFAULT_IGNORES` provides the list of directories that are used as the default value for the *ignore* parameter of the :func:`~filecmp.dircmp` function. (Contributed by Eli Bendersky in :issue:`15442`.) @@ -991,18 +991,18 @@ for the :meth:`~importlib.abc.InspectLoader.get_code` method. However, it will normally be desirable to override the default implementation for performance reasons. (Contributed by Brett Cannon in :issue:`18072`.) -The :func:`~importlib.reload` function has been moved from :mod:`imp` to -:mod:`importlib` as part of the :mod:`imp` module deprecation. (Contributed by +The :func:`~importlib.reload` function has been moved from :mod:`!imp` to +:mod:`importlib` as part of the :mod:`!imp` module deprecation. (Contributed by Berker Peksag in :issue:`18193`.) :mod:`importlib.util` now has a :data:`~importlib.util.MAGIC_NUMBER` attribute providing access to the bytecode version number. This replaces the -:func:`~imp.get_magic` function in the deprecated :mod:`imp` module. +:func:`!get_magic` function in the deprecated :mod:`!imp` module. (Contributed by Brett Cannon in :issue:`18192`.) New :mod:`importlib.util` functions :func:`~importlib.util.cache_from_source` and :func:`~importlib.util.source_from_cache` replace the same-named functions -in the deprecated :mod:`imp` module. (Contributed by Brett Cannon in +in the deprecated :mod:`!imp` module. (Contributed by Brett Cannon in :issue:`18194`.) The :mod:`importlib` bootstrap :class:`.NamespaceLoader` now conforms to @@ -1189,7 +1189,7 @@ Windows). (Contributed by Brian Curtin in :issue:`11939`.) root on Windows. (Contributed by Tim Golden in :issue:`9035`.) :func:`os.open` supports two new flags on platforms that provide them, -:data:`~os.O_PATH` (un-opened file descriptor), and :data:`~os.O_TMPFILE` +:const:`~os.O_PATH` (un-opened file descriptor), and :const:`~os.O_TMPFILE` (unnamed temporary file; as of 3.4.0 release available only on Linux systems with a kernel version of 3.11 or newer that have uapi headers). (Contributed by Christian Heimes in :issue:`18673` and Benjamin Peterson, respectively.) @@ -1238,8 +1238,8 @@ plistlib stdlib serialization protocols, with new :func:`~plistlib.load`, :func:`~plistlib.dump`, :func:`~plistlib.loads`, and :func:`~plistlib.dumps` functions. (The older API is now deprecated.) In addition to the already -supported XML plist format (:data:`~plistlib.FMT_XML`), it also now supports -the binary plist format (:data:`~plistlib.FMT_BINARY`). (Contributed by Ronald +supported XML plist format (:const:`~plistlib.FMT_XML`), it also now supports +the binary plist format (:const:`~plistlib.FMT_BINARY`). (Contributed by Ronald Oussoren and others in :issue:`14455`.) @@ -1323,14 +1323,14 @@ ability to query or set the resource limits for processes other than the one making the call. (Contributed by Christian Heimes in :issue:`16595`.) On Linux kernel version 2.6.36 or later, there are also some new -Linux specific constants: :attr:`~resource.RLIMIT_MSGQUEUE`, -:attr:`~resource.RLIMIT_NICE`, :attr:`~resource.RLIMIT_RTPRIO`, -:attr:`~resource.RLIMIT_RTTIME`, and :attr:`~resource.RLIMIT_SIGPENDING`. +Linux specific constants: :const:`~resource.RLIMIT_MSGQUEUE`, +:const:`~resource.RLIMIT_NICE`, :const:`~resource.RLIMIT_RTPRIO`, +:const:`~resource.RLIMIT_RTTIME`, and :const:`~resource.RLIMIT_SIGPENDING`. (Contributed by Christian Heimes in :issue:`19324`.) On FreeBSD version 9 and later, there some new FreeBSD specific constants: -:attr:`~resource.RLIMIT_SBSIZE`, :attr:`~resource.RLIMIT_SWAP`, and -:attr:`~resource.RLIMIT_NPTS`. (Contributed by Claudiu Popa in +:const:`~resource.RLIMIT_SBSIZE`, :const:`~resource.RLIMIT_SWAP`, and +:const:`~resource.RLIMIT_NPTS`. (Contributed by Claudiu Popa in :issue:`19343`.) @@ -1388,7 +1388,7 @@ try/except statement by code that only cares whether or not an error occurred. socket ------ -The socket module now supports the :data:`~socket.CAN_BCM` protocol on +The socket module now supports the :const:`~socket.CAN_BCM` protocol on platforms that support it. (Contributed by Brian Thorne in :issue:`15359`.) Socket objects have new methods to get or set their :ref:`inheritable flag @@ -1399,7 +1399,7 @@ The ``socket.AF_*`` and ``socket.SOCK_*`` constants are now enumeration values using the new :mod:`enum` module. This allows meaningful names to be printed during debugging, instead of integer "magic numbers". -The :data:`~socket.AF_LINK` constant is now available on BSD and OSX. +The :const:`~socket.AF_LINK` constant is now available on BSD and OSX. :func:`~socket.inet_pton` and :func:`~socket.inet_ntop` are now supported on Windows. (Contributed by Atsuo Ishimoto in :issue:`7171`.) @@ -1460,8 +1460,8 @@ Heimes in :issue:`18147`.) If OpenSSL 0.9.8 or later is available, :class:`~ssl.SSLContext` has a new attribute :attr:`~ssl.SSLContext.verify_flags` that can be used to control the certificate verification process by setting it to some combination of the new -constants :data:`~ssl.VERIFY_DEFAULT`, :data:`~ssl.VERIFY_CRL_CHECK_LEAF`, -:data:`~ssl.VERIFY_CRL_CHECK_CHAIN`, or :data:`~ssl.VERIFY_X509_STRICT`. +constants :const:`~ssl.VERIFY_DEFAULT`, :const:`~ssl.VERIFY_CRL_CHECK_LEAF`, +:const:`~ssl.VERIFY_CRL_CHECK_CHAIN`, or :const:`~ssl.VERIFY_X509_STRICT`. OpenSSL does not do any CRL verification by default. (Contributed by Christien Heimes in :issue:`8813`.) @@ -1500,7 +1500,7 @@ implementation is required as most of the values aren't standardized and are platform-dependent. (Contributed by Christian Heimes in :issue:`11016`.) The module supports new :mod:`~stat.ST_MODE` flags, :mod:`~stat.S_IFDOOR`, -:attr:`~stat.S_IFPORT`, and :attr:`~stat.S_IFWHT`. (Contributed by +:const:`~stat.S_IFPORT`, and :const:`~stat.S_IFWHT`. (Contributed by Christian Hiemes in :issue:`11016`.) @@ -1849,7 +1849,7 @@ Python's default implementation to a SipHash implementation on platforms that have a 64 bit data type. Any performance differences in comparison with the older FNV algorithm are trivial. -The PEP adds additional fields to the :attr:`sys.hash_info` named tuple to +The PEP adds additional fields to the :data:`sys.hash_info` named tuple to describe the hash algorithm in use by the currently executing binary. Otherwise, the PEP does not alter any existing CPython APIs. @@ -2077,31 +2077,31 @@ Deprecations in the Python API ------------------------------ * As mentioned in :ref:`whatsnew-pep-451`, a number of :mod:`importlib` - methods and functions are deprecated: :meth:`importlib.find_loader` is + methods and functions are deprecated: :meth:`!importlib.find_loader` is replaced by :func:`importlib.util.find_spec`; - :meth:`importlib.machinery.PathFinder.find_module` is replaced by + :meth:`!importlib.machinery.PathFinder.find_module` is replaced by :meth:`importlib.machinery.PathFinder.find_spec`; - :meth:`importlib.abc.MetaPathFinder.find_module` is replaced by + :meth:`!importlib.abc.MetaPathFinder.find_module` is replaced by :meth:`importlib.abc.MetaPathFinder.find_spec`; - :meth:`importlib.abc.PathEntryFinder.find_loader` and - :meth:`~importlib.abc.PathEntryFinder.find_module` are replaced by - :meth:`importlib.abc.PathEntryFinder.find_spec`; all of the ``xxxLoader`` ABC - ``load_module`` methods (:meth:`importlib.abc.Loader.load_module`, - :meth:`importlib.abc.InspectLoader.load_module`, - :meth:`importlib.abc.FileLoader.load_module`, - :meth:`importlib.abc.SourceLoader.load_module`) should no longer be + :meth:`!importlib.abc.PathEntryFinder.find_loader` and + :meth:`!find_module` are replaced by + :meth:`importlib.abc.PathEntryFinder.find_spec`; all of the :samp:`{xxx}Loader` ABC + ``load_module`` methods (:meth:`!importlib.abc.Loader.load_module`, + :meth:`!importlib.abc.InspectLoader.load_module`, + :meth:`!importlib.abc.FileLoader.load_module`, + :meth:`!importlib.abc.SourceLoader.load_module`) should no longer be implemented, instead loaders should implement an ``exec_module`` method (:meth:`importlib.abc.Loader.exec_module`, :meth:`importlib.abc.InspectLoader.exec_module` :meth:`importlib.abc.SourceLoader.exec_module`) and let the import system take care of the rest; and - :meth:`importlib.abc.Loader.module_repr`, - :meth:`importlib.util.module_for_loader`, :meth:`importlib.util.set_loader`, - and :meth:`importlib.util.set_package` are no longer needed because their + :meth:`!importlib.abc.Loader.module_repr`, + :meth:`!importlib.util.module_for_loader`, :meth:`!importlib.util.set_loader`, + and :meth:`!importlib.util.set_package` are no longer needed because their functions are now handled automatically by the import system. -* The :mod:`imp` module is pending deprecation. To keep compatibility with +* The :mod:`!imp` module is pending deprecation. To keep compatibility with Python 2/3 code bases, the module's removal is currently not scheduled. * The :mod:`formatter` module is pending deprecation and is slated for removal @@ -2277,7 +2277,7 @@ Changes in the Python API in a backwards-compatible fashion, use e.g. ``getattr(module, '__loader__', None) is not None``. (:issue:`17115`.) -* :meth:`importlib.util.module_for_loader` now sets ``__loader__`` and +* :meth:`!importlib.util.module_for_loader` now sets ``__loader__`` and ``__package__`` unconditionally to properly support reloading. If this is not desired then you will need to set these attributes manually. You can use :func:`importlib.util.module_to_load` for module management. @@ -2300,7 +2300,7 @@ Changes in the Python API then you can see if the module's ``__spec__.location`` is set to ``'frozen'``, check if the loader is a subclass of :class:`importlib.machinery.FrozenImporter`, - or if Python 2 compatibility is necessary you can use :func:`imp.is_frozen`. + or if Python 2 compatibility is necessary you can use :func:`!imp.is_frozen`. * :func:`py_compile.compile` now raises :exc:`FileExistsError` if the file path it would write to is a symlink or a non-regular file. This is to act as a diff --git a/Doc/whatsnew/3.5.rst b/Doc/whatsnew/3.5.rst index f9cceecb..3c0d8d66 100644 --- a/Doc/whatsnew/3.5.rst +++ b/Doc/whatsnew/3.5.rst @@ -425,7 +425,7 @@ are declared in the annotations:: While these annotations are available at runtime through the usual :attr:`__annotations__` attribute, *no automatic type checking happens at runtime*. Instead, it is assumed that a separate off-line type checker -(e.g. `mypy <http://mypy-lang.org>`_) will be used for on-demand +(e.g. `mypy <https://mypy-lang.org>`_) will be used for on-demand source code analysis. The type system supports unions, generic types, and a special type @@ -478,7 +478,7 @@ not make an additional system call:: PEP 475: Retry system calls failing with EINTR ---------------------------------------------- -An :py:data:`errno.EINTR` error code is returned whenever a system call, that +An :py:const:`errno.EINTR` error code is returned whenever a system call, that is waiting for I/O, is interrupted by a signal. Previously, Python would raise :exc:`InterruptedError` in such cases. This meant that, when writing a Python application, the developer had two choices: @@ -527,7 +527,7 @@ by a signal: :func:`~os.writev`; * special cases: :func:`os.close` and :func:`os.dup2` now ignore - :py:data:`~errno.EINTR` errors; the syscall is not retried (see the PEP + :py:const:`~errno.EINTR` errors; the syscall is not retried (see the PEP for the rationale); * :mod:`select` functions: :func:`devpoll.poll() <select.devpoll.poll>`, @@ -1045,8 +1045,8 @@ not just sequences. (Contributed by Serhiy Storchaka in :issue:`23171`.) curses ------ -The new :func:`~curses.update_lines_cols` function updates the :envvar:`LINES` -and :envvar:`COLS` environment variables. This is useful for detecting +The new :func:`~curses.update_lines_cols` function updates the :data:`LINES` +and :data:`COLS` module variables. This is useful for detecting manual screen resizing. (Contributed by Arnon Yaari in :issue:`4254`.) @@ -1079,7 +1079,7 @@ Both the ``build`` and ``build_ext`` commands now accept a ``-j`` option to enable parallel building of extension modules. (Contributed by Antoine Pitrou in :issue:`5309`.) -The :mod:`distutils` module now supports ``xz`` compression, and can be +The ``distutils`` module now supports ``xz`` compression, and can be enabled by passing ``xztar`` as an argument to ``bdist --format``. (Contributed by Serhiy Storchaka in :issue:`16314`.) @@ -1498,7 +1498,7 @@ use ``/dev/urandom`` and avoiding failures due to potential file descriptor exhaustion. (Contributed by Victor Stinner in :issue:`22181`.) New :func:`~os.get_blocking` and :func:`~os.set_blocking` functions allow -getting and setting a file descriptor's blocking mode (:data:`~os.O_NONBLOCK`.) +getting and setting a file descriptor's blocking mode (:const:`~os.O_NONBLOCK`.) (Contributed by Victor Stinner in :issue:`22054`.) The :func:`~os.truncate` and :func:`~os.ftruncate` functions are now supported @@ -1783,7 +1783,7 @@ the TLS handshake. The new :meth:`SSLSocket.selected_alpn_protocol() <ssl.SSLSocket.selected_alpn_protocol>` returns the protocol that was selected during the TLS handshake. -The :data:`~ssl.HAS_ALPN` flag indicates whether ALPN support is present. +The :const:`~ssl.HAS_ALPN` flag indicates whether ALPN support is present. Other Changes @@ -2192,7 +2192,7 @@ encode error with ``\N{...}`` escapes. (Contributed by Serhiy Storchaka in :issue:`19676`.) A new :c:func:`PyErr_FormatV` function similar to :c:func:`PyErr_Format`, -but accepts a ``va_list`` argument. +but accepts a :c:type:`va_list` argument. (Contributed by Antoine Pitrou in :issue:`18711`.) A new :c:data:`PyExc_RecursionError` exception. @@ -2212,7 +2212,7 @@ for details.) The :c:member:`PyTypeObject.tp_finalize` slot is now part of the stable ABI. Windows builds now require Microsoft Visual C++ 14.0, which -is available as part of `Visual Studio 2015 <https://www.visualstudio.com/>`_. +is available as part of `Visual Studio 2015 <https://visualstudio.microsoft.com/en/vs/older-downloads/#visual-studio-2015-and-other-products>`_. Extension modules now include a platform information tag in their filename on some platforms (the tag is optional, and CPython will import extensions without @@ -2476,7 +2476,7 @@ Changes in the Python API in Python 3.5, all old ``.pyo`` files from previous versions of Python are invalid regardless of this PEP. -* The :mod:`socket` module now exports the :data:`~socket.CAN_RAW_FD_FRAMES` +* The :mod:`socket` module now exports the :const:`~socket.CAN_RAW_FD_FRAMES` constant on linux 3.6 and greater. * The :func:`ssl.cert_time_to_seconds` function now interprets the input time @@ -2512,7 +2512,7 @@ Changes in the Python API Changes in the C API -------------------- -* The undocumented :c:member:`~PyMemoryViewObject.format` member of the +* The undocumented :c:member:`!format` member of the (non-public) :c:type:`PyMemoryViewObject` structure has been removed. All extensions relying on the relevant parts in ``memoryobject.h`` must be rebuilt. @@ -2520,7 +2520,7 @@ Changes in the C API * The :c:type:`PyMemAllocator` structure was renamed to :c:type:`PyMemAllocatorEx` and a new ``calloc`` field was added. -* Removed non-documented macro :c:macro:`PyObject_REPR` which leaked references. +* Removed non-documented macro :c:macro:`!PyObject_REPR()` which leaked references. Use format character ``%R`` in :c:func:`PyUnicode_FromFormat`-like functions to format the :func:`repr` of the object. (Contributed by Serhiy Storchaka in :issue:`22453`.) @@ -2533,7 +2533,7 @@ Changes in the C API * As part of the :pep:`492` implementation, the ``tp_reserved`` slot of :c:type:`PyTypeObject` was replaced with a - :c:member:`tp_as_async` slot. Refer to :ref:`coro-objects` for + :c:member:`~PyTypeObject.tp_as_async` slot. Refer to :ref:`coro-objects` for new types, structures and functions. diff --git a/Doc/whatsnew/3.6.rst b/Doc/whatsnew/3.6.rst index f138fa5c..be20ee1a 100644 --- a/Doc/whatsnew/3.6.rst +++ b/Doc/whatsnew/3.6.rst @@ -238,7 +238,7 @@ and the ``__annotations__`` attribute. and Guido van Rossum. Implemented by Ivan Levkivskyi. Tools that use or will use the new syntax: - `mypy <http://www.mypy-lang.org/>`_, + `mypy <https://www.mypy-lang.org/>`_, `pytype <https://github.com/google/pytype>`_, PyCharm, etc. @@ -650,8 +650,8 @@ compiled in release mode using ``PYTHONMALLOC=debug``. Effects of debug hooks: * Detect writes before the start of a buffer (buffer underflows) * Detect writes after the end of a buffer (buffer overflows) * Check that the :term:`GIL <global interpreter lock>` is held when allocator - functions of :c:data:`PYMEM_DOMAIN_OBJ` (ex: :c:func:`PyObject_Malloc`) and - :c:data:`PYMEM_DOMAIN_MEM` (ex: :c:func:`PyMem_Malloc`) domains are called. + functions of :c:macro:`PYMEM_DOMAIN_OBJ` (ex: :c:func:`PyObject_Malloc`) and + :c:macro:`PYMEM_DOMAIN_MEM` (ex: :c:func:`PyMem_Malloc`) domains are called. Checking if the GIL is held is also a new feature of Python 3.6. @@ -1012,7 +1012,7 @@ distutils --------- The ``default_format`` attribute has been removed from -:class:`distutils.command.sdist.sdist` and the ``formats`` +``distutils.command.sdist.sdist`` and the ``formats`` attribute defaults to ``['gztar']``. Although not anticipated, any code relying on the presence of ``default_format`` may need to be adapted. See :issue:`27819` for more details. @@ -1388,7 +1388,7 @@ are treated as punctuation. site ---- -When specifying paths to add to :attr:`sys.path` in a ``.pth`` file, +When specifying paths to add to :data:`sys.path` in a ``.pth`` file, you may now specify file paths on top of directories (e.g. zip files). (Contributed by Wolfgang Langner in :issue:`26587`). @@ -1404,7 +1404,7 @@ socket ------ The :func:`~socket.socket.ioctl` function now supports the -:data:`~socket.SIO_LOOPBACK_FAST_PATH` control code. +:const:`~socket.SIO_LOOPBACK_FAST_PATH` control code. (Contributed by Daniel Stokes in :issue:`26536`.) The :meth:`~socket.socket.getsockopt` constants ``SO_DOMAIN``, @@ -1416,7 +1416,7 @@ The :meth:`~socket.socket.setsockopt` now supports the (Contributed by Christian Heimes in :issue:`27744`.) The socket module now supports the address family -:data:`~socket.AF_ALG` to interface with Linux Kernel crypto API. ``ALG_*``, +:const:`~socket.AF_ALG` to interface with Linux Kernel crypto API. ``ALG_*``, ``SOL_ALG`` and :meth:`~socket.socket.sendmsg_afalg` were added. (Contributed by Christian Heimes in :issue:`27744` with support from Victor Stinner.) @@ -1822,7 +1822,7 @@ Optimizations up to 80% faster. (Contributed by Josh Snider in :issue:`26574`). * Allocator functions of the :c:func:`PyMem_Malloc` domain - (:c:data:`PYMEM_DOMAIN_MEM`) now use the :ref:`pymalloc memory allocator + (:c:macro:`PYMEM_DOMAIN_MEM`) now use the :ref:`pymalloc memory allocator <pymalloc>` instead of :c:func:`malloc` function of the C library. The pymalloc allocator is optimized for objects smaller or equal to 512 bytes with a short lifetime, and use :c:func:`malloc` for larger memory blocks. @@ -1874,8 +1874,8 @@ Build and C API Changes (Original patch by Alecsandru Patrascu of Intel in :issue:`26359`.) * The :term:`GIL <global interpreter lock>` must now be held when allocator - functions of :c:data:`PYMEM_DOMAIN_OBJ` (ex: :c:func:`PyObject_Malloc`) and - :c:data:`PYMEM_DOMAIN_MEM` (ex: :c:func:`PyMem_Malloc`) domains are called. + functions of :c:macro:`PYMEM_DOMAIN_OBJ` (ex: :c:func:`PyObject_Malloc`) and + :c:macro:`PYMEM_DOMAIN_MEM` (ex: :c:func:`PyMem_Malloc`) domains are called. * New :c:func:`Py_FinalizeEx` API which indicates if flushing buffered data failed. @@ -1986,7 +1986,7 @@ distutils ~~~~~~~~~ The undocumented ``extra_path`` argument to the -:class:`~distutils.Distribution` constructor is now considered deprecated +``distutils.Distribution`` constructor is now considered deprecated and will raise a warning if set. Support for this parameter will be removed in a future Python release. See :issue:`27919` for details. @@ -2010,7 +2010,7 @@ been deprecated in previous versions of Python in favour of :meth:`importlib.abc.Loader.exec_module`. The :class:`importlib.machinery.WindowsRegistryFinder` class is now -deprecated. As of 3.6.0, it is still added to :attr:`sys.meta_path` by +deprecated. As of 3.6.0, it is still added to :data:`sys.meta_path` by default (on Windows), but this may change in future releases. os @@ -2066,9 +2066,9 @@ environment. (Contributed by Brett Cannon in :issue:`25154`.) Deprecated functions and types of the C API ------------------------------------------- -Undocumented functions :c:func:`PyUnicode_AsEncodedObject`, -:c:func:`PyUnicode_AsDecodedObject`, :c:func:`PyUnicode_AsEncodedUnicode` -and :c:func:`PyUnicode_AsDecodedUnicode` are deprecated now. +Undocumented functions :c:func:`!PyUnicode_AsEncodedObject`, +:c:func:`!PyUnicode_AsDecodedObject`, :c:func:`!PyUnicode_AsEncodedUnicode` +and :c:func:`!PyUnicode_AsDecodedUnicode` are deprecated now. Use the :ref:`generic codec based API <codec-registry>` instead. @@ -2180,7 +2180,7 @@ Changes in the Python API now raises :exc:`ValueError` for out-of-range values, rather than returning :const:`None`. See :issue:`20059`. -* The :mod:`imp` module now raises a :exc:`DeprecationWarning` instead of +* The :mod:`!imp` module now raises a :exc:`DeprecationWarning` instead of :exc:`PendingDeprecationWarning`. * The following modules have had missing APIs added to their :attr:`__all__` @@ -2245,7 +2245,7 @@ Changes in the Python API accepting additional keyword arguments will need to adjust their calls to :meth:`type.__new__` (whether direct or via :class:`super`) accordingly. -* In :class:`distutils.command.sdist.sdist`, the ``default_format`` +* In ``distutils.command.sdist.sdist``, the ``default_format`` attribute has been removed and is no longer honored. Instead, the gzipped tarfile format is the default on all platforms and no platform-specific selection is made. diff --git a/Doc/whatsnew/3.7.rst b/Doc/whatsnew/3.7.rst index de03e5be..e82bb756 100644 --- a/Doc/whatsnew/3.7.rst +++ b/Doc/whatsnew/3.7.rst @@ -1280,13 +1280,13 @@ This function should be used instead of :func:`os.close` for better compatibility across platforms. (Contributed by Christian Heimes in :issue:`32454`.) -The :mod:`socket` module now exposes the :data:`socket.TCP_CONGESTION` -(Linux 2.6.13), :data:`socket.TCP_USER_TIMEOUT` (Linux 2.6.37), and -:data:`socket.TCP_NOTSENT_LOWAT` (Linux 3.12) constants. +The :mod:`socket` module now exposes the :const:`socket.TCP_CONGESTION` +(Linux 2.6.13), :const:`socket.TCP_USER_TIMEOUT` (Linux 2.6.37), and +:const:`socket.TCP_NOTSENT_LOWAT` (Linux 3.12) constants. (Contributed by Omar Sandoval in :issue:`26273` and Nathaniel J. Smith in :issue:`29728`.) -Support for :data:`socket.AF_VSOCK` sockets has been added to allow +Support for :const:`socket.AF_VSOCK` sockets has been added to allow communication between virtual machines and their hosts. (Contributed by Cathy Avery in :issue:`27584`.) @@ -1394,7 +1394,7 @@ subprocess The :func:`subprocess.run` function accepts the new *capture_output* keyword argument. When true, stdout and stderr will be captured. -This is equivalent to passing :data:`subprocess.PIPE` as *stdout* and +This is equivalent to passing :const:`subprocess.PIPE` as *stdout* and *stderr* arguments. (Contributed by Bo Bayles in :issue:`32102`.) @@ -1453,12 +1453,12 @@ time New clock identifiers have been added: -* :data:`time.CLOCK_BOOTTIME` (Linux): Identical to - :data:`time.CLOCK_MONOTONIC`, except it also includes any time that the +* :const:`time.CLOCK_BOOTTIME` (Linux): Identical to + :const:`time.CLOCK_MONOTONIC`, except it also includes any time that the system is suspended. -* :data:`time.CLOCK_PROF` (FreeBSD, NetBSD and OpenBSD): High-resolution +* :const:`time.CLOCK_PROF` (FreeBSD, NetBSD and OpenBSD): High-resolution per-process CPU timer. -* :data:`time.CLOCK_UPTIME` (FreeBSD, OpenBSD): Time whose absolute value is +* :const:`time.CLOCK_UPTIME` (FreeBSD, OpenBSD): Time whose absolute value is the time the system has been running and not suspended, providing accurate uptime measurement. @@ -1674,10 +1674,10 @@ The new :c:func:`import__find__load__start` and module imports. (Contributed by Christian Heimes in :issue:`31574`.) -The fields :c:member:`name` and :c:member:`doc` of structures +The fields :c:member:`!name` and :c:member:`!doc` of structures :c:type:`PyMemberDef`, :c:type:`PyGetSetDef`, :c:type:`PyStructSequence_Field`, :c:type:`PyStructSequence_Desc`, -and :c:type:`wrapperbase` are now of type ``const char *`` rather of +and :c:struct:`wrapperbase` are now of type ``const char *`` rather of ``char *``. (Contributed by Serhiy Storchaka in :issue:`28761`.) The result of :c:func:`PyUnicode_AsUTF8AndSize` and :c:func:`PyUnicode_AsUTF8` @@ -1906,7 +1906,7 @@ Other CPython Implementation Changes variables were defined. Previously, the order was undefined. (Contributed by Raymond Hettinger in :issue:`32690`.) -* The :mod:`distutils` ``upload`` command no longer tries to change CR +* The ``distutils`` ``upload`` command no longer tries to change CR end-of-line characters to CRLF. This fixes a corruption issue with sdists that ended with a byte equivalent to CR. (Contributed by Bo Bayles in :issue:`32304`.) @@ -2004,11 +2004,11 @@ importlib --------- Methods -:meth:`MetaPathFinder.find_module() <importlib.abc.MetaPathFinder.find_module>` +:meth:`MetaPathFinder.find_module() <!importlib.abc.MetaPathFinder.find_module>` (replaced by :meth:`MetaPathFinder.find_spec() <importlib.abc.MetaPathFinder.find_spec>`) and -:meth:`PathEntryFinder.find_loader() <importlib.abc.PathEntryFinder.find_loader>` +:meth:`PathEntryFinder.find_loader() <!importlib.abc.PathEntryFinder.find_loader>` (replaced by :meth:`PathEntryFinder.find_spec() <importlib.abc.PathEntryFinder.find_spec>`) both deprecated in Python 3.4 now emit :exc:`DeprecationWarning`. @@ -2181,7 +2181,7 @@ The following features and APIs have been removed from Python 3.7: :func:`ssl.wrap_socket` or :class:`ssl.SSLContext`. (Contributed by Christian Heimes in :issue:`32951`.) -* The unused :mod:`distutils` ``install_misc`` command has been removed. +* The unused ``distutils`` ``install_misc`` command has been removed. (Contributed by Eric N. Vander Weele in :issue:`29218`.) diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index 4e2dbe3b..68fd4d77 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -404,7 +404,7 @@ Other Language Changes or :meth:`~object.__complex__` is not available. (Contributed by Serhiy Storchaka in :issue:`20092`.) -* Added support of ``\N{name}`` escapes in :mod:`regular expressions <re>`:: +* Added support of :samp:`\\N\\{{name}\\}` escapes in :mod:`regular expressions <re>`:: >>> notice = 'Copyright © 2019' >>> copyright_year_pattern = re.compile(r'\N{copyright sign}\s*(\d{4})') @@ -947,7 +947,7 @@ This made it difficult to update, experiment with, or teach the various logging configuration options using the interactive prompt or a Jupyter notebook. -(Suggested by Raymond Hettinger, implemented by Dong-hee Na, and +(Suggested by Raymond Hettinger, implemented by Donghee Na, and reviewed by Vinay Sajip in :issue:`33897`.) @@ -1089,6 +1089,9 @@ contain characters unrepresentable at the OS level. Added :meth:`pathlib.Path.link_to()` which creates a hard link pointing to a path. (Contributed by Joannah Nanjekye in :issue:`26978`) +Note that ``link_to`` was deprecated in 3.10 and removed in 3.12 in +favor of a ``hardlink_to`` method added in 3.10 which matches the +semantics of the existing ``symlink_to`` method. pickle @@ -1302,7 +1305,7 @@ Zackery Spytz in :issue:`25451`.) time ---- -Added new clock :data:`~time.CLOCK_UPTIME_RAW` for macOS 10.12. +Added new clock :const:`~time.CLOCK_UPTIME_RAW` for macOS 10.12. (Contributed by Joannah Nanjekye in :issue:`35702`.) @@ -1571,12 +1574,12 @@ Build and C API Changes * :c:func:`Py_INCREF`, :c:func:`Py_DECREF` * :c:func:`Py_XINCREF`, :c:func:`Py_XDECREF` * :c:func:`PyObject_INIT`, :c:func:`PyObject_INIT_VAR` - * Private functions: :c:func:`_PyObject_GC_TRACK`, - :c:func:`_PyObject_GC_UNTRACK`, :c:func:`_Py_Dealloc` + * Private functions: :c:func:`!_PyObject_GC_TRACK`, + :c:func:`!_PyObject_GC_UNTRACK`, :c:func:`!_Py_Dealloc` (Contributed by Victor Stinner in :issue:`35059`.) -* The :c:func:`PyByteArray_Init` and :c:func:`PyByteArray_Fini` functions have +* The :c:func:`!PyByteArray_Init` and :c:func:`!PyByteArray_Fini` functions have been removed. They did nothing since Python 2.7.4 and Python 3.2.0, were excluded from the limited API (stable ABI), and were not documented. (Contributed by Victor Stinner in :issue:`35713`.) @@ -1625,7 +1628,7 @@ Build and C API Changes parameter for indicating the number of positional-only arguments. (Contributed by Pablo Galindo in :issue:`37221`.) -* :c:func:`Py_SetPath` now sets :data:`sys.executable` to the program full +* :c:func:`!Py_SetPath` now sets :data:`sys.executable` to the program full path (:c:func:`Py_GetProgramFullPath`) rather than to the program name (:c:func:`Py_GetProgramName`). (Contributed by Victor Stinner in :issue:`38234`.) @@ -1711,7 +1714,7 @@ Deprecated * The :meth:`~threading.Thread.isAlive()` method of :class:`threading.Thread` has been deprecated. - (Contributed by Dong-hee Na in :issue:`35283`.) + (Contributed by Donghee Na in :issue:`35283`.) * Many builtin and extension functions that take integer arguments will now emit a deprecation warning for :class:`~decimal.Decimal`\ s, @@ -1836,18 +1839,18 @@ Changes in Python behavior classes will affect their string representation. (Contributed by Serhiy Storchaka in :issue:`36793`.) -* On AIX, :attr:`sys.platform` doesn't contain the major version anymore. +* On AIX, :data:`sys.platform` doesn't contain the major version anymore. It is always ``'aix'``, instead of ``'aix3'`` .. ``'aix7'``. Since older Python versions include the version number, so it is recommended to always use ``sys.platform.startswith('aix')``. (Contributed by M. Felt in :issue:`36588`.) -* :c:func:`PyEval_AcquireLock` and :c:func:`PyEval_AcquireThread` now +* :c:func:`!PyEval_AcquireLock` and :c:func:`!PyEval_AcquireThread` now terminate the current thread if called while the interpreter is finalizing, making them consistent with :c:func:`PyEval_RestoreThread`, :c:func:`Py_END_ALLOW_THREADS`, and :c:func:`PyGILState_Ensure`. If this - behavior is not desired, guard the call by checking :c:func:`_Py_IsFinalizing` - or :c:func:`sys.is_finalizing`. + behavior is not desired, guard the call by checking :c:func:`!_Py_IsFinalizing` + or :func:`sys.is_finalizing`. (Contributed by Joannah Nanjekye in :issue:`36475`.) @@ -2018,7 +2021,7 @@ Changes in the C API *cf_flags*. (Contributed by Guido van Rossum in :issue:`35766`.) -* The :c:func:`PyEval_ReInitThreads` function has been removed from the C API. +* The :c:func:`!PyEval_ReInitThreads` function has been removed from the C API. It should not be called explicitly: use :c:func:`PyOS_AfterFork_Child` instead. (Contributed by Victor Stinner in :issue:`36728`.) @@ -2058,8 +2061,8 @@ Changes in the C API * Remove :c:macro:`Py_INCREF` on the type object after allocating an instance - if any. - This may happen after calling :c:func:`PyObject_New`, - :c:func:`PyObject_NewVar`, :c:func:`PyObject_GC_New`, + This may happen after calling :c:macro:`PyObject_New`, + :c:macro:`PyObject_NewVar`, :c:func:`PyObject_GC_New`, :c:func:`PyObject_GC_NewVar`, or any other custom allocator that uses :c:func:`PyObject_Init` or :c:func:`PyObject_INIT`. @@ -2113,12 +2116,12 @@ Changes in the C API extension types across feature releases, anymore. A :c:type:`PyTypeObject` exported by a third-party extension module is supposed to have all the slots expected in the current Python version, including - :c:member:`~PyTypeObject.tp_finalize` (:const:`Py_TPFLAGS_HAVE_FINALIZE` + :c:member:`~PyTypeObject.tp_finalize` (:c:macro:`Py_TPFLAGS_HAVE_FINALIZE` is not checked anymore before reading :c:member:`~PyTypeObject.tp_finalize`). (Contributed by Antoine Pitrou in :issue:`32388`.) -* The functions :c:func:`PyNode_AddChild` and :c:func:`PyParser_AddToken` now accept +* The functions :c:func:`!PyNode_AddChild` and :c:func:`!PyParser_AddToken` now accept two additional ``int`` arguments *end_lineno* and *end_col_offset*. * The :file:`libpython38.a` file to allow MinGW tools to link directly against @@ -2226,7 +2229,7 @@ The benchmarks were measured on an `Intel® Core™ i7-4960HQ processor <https://ark.intel.com/content/www/us/en/ark/products/76088/intel-core-i7-4960hq-processor-6m-cache-up-to-3-80-ghz.html>`_ running the macOS 64-bit builds found at -`python.org <https://www.python.org/downloads/mac-osx/>`_. +`python.org <https://www.python.org/downloads/macos/>`_. The benchmark script displays timings in nanoseconds. diff --git a/Doc/whatsnew/3.9.rst b/Doc/whatsnew/3.9.rst index e974ee3a..6e6961e4 100644 --- a/Doc/whatsnew/3.9.rst +++ b/Doc/whatsnew/3.9.rst @@ -44,7 +44,6 @@ This article explains the new features in Python 3.9, compared to 3.8. Python 3.9 was released on October 5, 2020. - For full details, see the :ref:`changelog <changelog>`. .. seealso:: @@ -415,7 +414,7 @@ datetime The :meth:`~datetime.date.isocalendar()` of :class:`datetime.date` and :meth:`~datetime.datetime.isocalendar()` of :class:`datetime.datetime` methods now returns a :func:`~collections.namedtuple` instead of a :class:`tuple`. -(Contributed by Dong-hee Na in :issue:`24416`.) +(Contributed by Donghee Na in :issue:`24416`.) distutils --------- @@ -427,16 +426,16 @@ digests. It skips MD5 on platforms that block MD5 digest. fcntl ----- -Added constants :data:`~fcntl.F_OFD_GETLK`, :data:`~fcntl.F_OFD_SETLK` -and :data:`~fcntl.F_OFD_SETLKW`. -(Contributed by Dong-hee Na in :issue:`38602`.) +Added constants :const:`~fcntl.F_OFD_GETLK`, :const:`~fcntl.F_OFD_SETLK` +and :const:`~fcntl.F_OFD_SETLKW`. +(Contributed by Donghee Na in :issue:`38602`.) ftplib ------- :class:`~ftplib.FTP` and :class:`~ftplib.FTP_TLS` now raise a :class:`ValueError` if the given timeout for their constructor is zero to prevent the creation of -a non-blocking socket. (Contributed by Dong-hee Na in :issue:`39259`.) +a non-blocking socket. (Contributed by Donghee Na in :issue:`39259`.) gc -- @@ -468,7 +467,7 @@ http ---- HTTP status codes ``103 EARLY_HINTS``, ``418 IM_A_TEAPOT`` and ``425 TOO_EARLY`` are added to -:class:`http.HTTPStatus`. (Contributed by Dong-hee Na in :issue:`39509` and Ross Rhodes in :issue:`39507`.) +:class:`http.HTTPStatus`. (Contributed by Donghee Na in :issue:`39509` and Ross Rhodes in :issue:`39507`.) IDLE and idlelib ---------------- @@ -509,14 +508,14 @@ an optional *timeout* parameter for their constructors. Also, the :meth:`~imaplib.IMAP4.open` method now has an optional *timeout* parameter with this change. The overridden methods of :class:`~imaplib.IMAP4_SSL` and :class:`~imaplib.IMAP4_stream` were applied to this change. -(Contributed by Dong-hee Na in :issue:`38615`.) +(Contributed by Donghee Na in :issue:`38615`.) :meth:`imaplib.IMAP4.unselect` is added. :meth:`imaplib.IMAP4.unselect` frees server's resources associated with the selected mailbox and returns the server to the authenticated state. This command performs the same actions as :meth:`imaplib.IMAP4.close`, except that no messages are permanently removed from the currently -selected mailbox. (Contributed by Dong-hee Na in :issue:`40375`.) +selected mailbox. (Contributed by Donghee Na in :issue:`40375`.) importlib --------- @@ -588,16 +587,16 @@ nntplib :class:`~nntplib.NNTP` and :class:`~nntplib.NNTP_SSL` now raise a :class:`ValueError` if the given timeout for their constructor is zero to prevent the creation of -a non-blocking socket. (Contributed by Dong-hee Na in :issue:`39259`.) +a non-blocking socket. (Contributed by Donghee Na in :issue:`39259`.) os -- -Added :data:`~os.CLD_KILLED` and :data:`~os.CLD_STOPPED` for :attr:`si_code`. -(Contributed by Dong-hee Na in :issue:`38493`.) +Added :const:`~os.CLD_KILLED` and :const:`~os.CLD_STOPPED` for :attr:`si_code`. +(Contributed by Donghee Na in :issue:`38493`.) Exposed the Linux-specific :func:`os.pidfd_open` (:issue:`38692`) and -:data:`os.P_PIDFD` (:issue:`38713`) for process management with file +:const:`os.P_PIDFD` (:issue:`38713`) for process management with file descriptors. The :func:`os.unsetenv` function is now also available on Windows. @@ -629,7 +628,7 @@ poplib :class:`~poplib.POP3` and :class:`~poplib.POP3_SSL` now raise a :class:`ValueError` if the given timeout for their constructor is zero to prevent the creation of -a non-blocking socket. (Contributed by Dong-hee Na in :issue:`39259`.) +a non-blocking socket. (Contributed by Donghee Na in :issue:`39259`.) pprint ------ @@ -661,19 +660,19 @@ smtplib :class:`~smtplib.SMTP` and :class:`~smtplib.SMTP_SSL` now raise a :class:`ValueError` if the given timeout for their constructor is zero to prevent the creation of -a non-blocking socket. (Contributed by Dong-hee Na in :issue:`39259`.) +a non-blocking socket. (Contributed by Donghee Na in :issue:`39259`.) :class:`~smtplib.LMTP` constructor now has an optional *timeout* parameter. -(Contributed by Dong-hee Na in :issue:`39329`.) +(Contributed by Donghee Na in :issue:`39329`.) socket ------ -The :mod:`socket` module now exports the :data:`~socket.CAN_RAW_JOIN_FILTERS` +The :mod:`socket` module now exports the :const:`~socket.CAN_RAW_JOIN_FILTERS` constant on Linux 4.1 and greater. (Contributed by Stefan Tatschner and Zackery Spytz in :issue:`25780`.) -The socket module now supports the :data:`~socket.CAN_J1939` protocol on +The socket module now supports the :const:`~socket.CAN_J1939` protocol on platforms that support it. (Contributed by Karl Ding in :issue:`40291`.) The socket module now has the :func:`socket.send_fds` and @@ -692,13 +691,13 @@ which has nanosecond resolution, rather than sys --- -Added a new :attr:`sys.platlibdir` attribute: name of the platform-specific +Added a new :data:`sys.platlibdir` attribute: name of the platform-specific library directory. It is used to build the path of standard library and the paths of installed extension modules. It is equal to ``"lib"`` on most platforms. On Fedora and SuSE, it is equal to ``"lib64"`` on 64-bit platforms. (Contributed by Jan Matějek, Matěj Cepl, Charalampos Stratakis and Victor Stinner in :issue:`1294959`.) -Previously, :attr:`sys.stderr` was block-buffered when non-interactive. Now +Previously, :data:`sys.stderr` was block-buffered when non-interactive. Now ``stderr`` defaults to always being line-buffered. (Contributed by Jendrik Seipp in :issue:`13601`.) @@ -777,7 +776,7 @@ Optimizations * A number of Python builtins (:class:`range`, :class:`tuple`, :class:`set`, :class:`frozenset`, :class:`list`, :class:`dict`) are now sped up by using :pep:`590` vectorcall protocol. - (Contributed by Dong-hee Na, Mark Shannon, Jeroen Demeyer and Petr Viktorin in :issue:`37207`.) + (Contributed by Donghee Na, Mark Shannon, Jeroen Demeyer and Petr Viktorin in :issue:`37207`.) * Optimized :func:`~set.difference_update` for the case when the other set is much larger than the base set. @@ -791,7 +790,7 @@ Optimizations * :term:`floor division` of float operation now has a better performance. Also the message of :exc:`ZeroDivisionError` for this operation is updated. - (Contributed by Dong-hee Na in :issue:`39434`.) + (Contributed by Donghee Na in :issue:`39434`.) * Decoding short ASCII strings with UTF-8 and ascii codecs is now about 15% faster. (Contributed by Inada Naoki in :issue:`37348`.) @@ -849,7 +848,7 @@ in nanoseconds. The benchmarks were measured on an `Intel® Core™ i7-4960HQ processor <https://ark.intel.com/content/www/us/en/ark/products/76088/intel-core-i7-4960hq-processor-6m-cache-up-to-3-80-ghz.html>`_ running the macOS 64-bit builds found at -`python.org <https://www.python.org/downloads/mac-osx/>`_. +`python.org <https://www.python.org/downloads/macos/>`_. Deprecated @@ -870,9 +869,9 @@ Deprecated users can leverage the Abstract Syntax Tree (AST) generation and compilation stage, using the :mod:`ast` module. -* The Public C API functions :c:func:`PyParser_SimpleParseStringFlags`, - :c:func:`PyParser_SimpleParseStringFlagsFilename`, - :c:func:`PyParser_SimpleParseFileFlags` and :c:func:`PyNode_Compile` +* The Public C API functions :c:func:`!PyParser_SimpleParseStringFlags`, + :c:func:`!PyParser_SimpleParseStringFlagsFilename`, + :c:func:`!PyParser_SimpleParseFileFlags` and :c:func:`!PyNode_Compile` are deprecated and will be removed in Python 3.10 together with the old parser. * Using :data:`NotImplemented` in a boolean context has been deprecated, @@ -923,10 +922,10 @@ Deprecated (Contributed by Batuhan Taskaya in :issue:`39639` and :issue:`39969` and Serhiy Storchaka in :issue:`39988`.) -* The :c:func:`PyEval_InitThreads` and :c:func:`PyEval_ThreadsInitialized` +* The :c:func:`!PyEval_InitThreads` and :c:func:`!PyEval_ThreadsInitialized` functions are now deprecated and will be removed in Python 3.11. Calling - :c:func:`PyEval_InitThreads` now does nothing. The :term:`GIL` is initialized - by :c:func:`Py_Initialize()` since Python 3.7. + :c:func:`!PyEval_InitThreads` now does nothing. The :term:`GIL` is initialized + by :c:func:`Py_Initialize` since Python 3.7. (Contributed by Victor Stinner in :issue:`39877`.) * Passing ``None`` as the first argument to the :func:`shlex.split` function @@ -961,7 +960,7 @@ Removed are not supported or not enabled by NNTP server administrators. For ``xgtitle()``, please use :meth:`nntplib.NNTP.descriptions` or :meth:`nntplib.NNTP.description` instead. - (Contributed by Dong-hee Na in :issue:`39366`.) + (Contributed by Donghee Na in :issue:`39366`.) * :class:`array.array`: ``tostring()`` and ``fromstring()`` methods have been removed. They were aliases to ``tobytes()`` and ``frombytes()``, deprecated @@ -994,7 +993,7 @@ Removed * The :meth:`~threading.Thread.isAlive()` method of :class:`threading.Thread` has been removed. It was deprecated since Python 3.8. Use :meth:`~threading.Thread.is_alive()` instead. - (Contributed by Dong-hee Na in :issue:`37804`.) + (Contributed by Donghee Na in :issue:`37804`.) * Methods ``getchildren()`` and ``getiterator()`` of classes :class:`~xml.etree.ElementTree.ElementTree` and @@ -1084,7 +1083,7 @@ Changes in the Python API ``__VENV_PROMPT__`` is set to ``""``. * The :meth:`select.epoll.unregister` method no longer ignores the - :data:`~errno.EBADF` error. + :const:`~errno.EBADF` error. (Contributed by Victor Stinner in :issue:`39239`.) * The *compresslevel* parameter of :class:`bz2.BZ2File` became keyword-only, @@ -1115,9 +1114,9 @@ Changes in the Python API ``PyCF_ALLOW_TOP_LEVEL_AWAIT`` was clashing with ``CO_FUTURE_DIVISION``. (Contributed by Batuhan Taskaya in :issue:`39562`) -* ``array('u')`` now uses ``wchar_t`` as C type instead of ``Py_UNICODE``. +* ``array('u')`` now uses :c:type:`wchar_t` as C type instead of ``Py_UNICODE``. This change doesn't affect to its behavior because ``Py_UNICODE`` is alias - of ``wchar_t`` since Python 3.3. + of :c:type:`wchar_t` since Python 3.3. (Contributed by Inada Naoki in :issue:`34538`.) * The :func:`logging.getLogger` API now returns the root logger when passed @@ -1226,8 +1225,8 @@ Build Changes ============= * Added ``--with-platlibdir`` option to the ``configure`` script: name of the - platform-specific library directory, stored in the new :attr:`sys.platlibdir` - attribute. See :attr:`sys.platlibdir` attribute for more information. + platform-specific library directory, stored in the new :data:`sys.platlibdir` + attribute. See :data:`sys.platlibdir` attribute for more information. (Contributed by Jan Matějek, Matěj Cepl, Charalampos Stratakis and Victor Stinner in :issue:`1294959`.) @@ -1276,7 +1275,7 @@ New Features * :pep:`573`: Added :c:func:`PyType_FromModuleAndSpec` to associate a module with a class; :c:func:`PyType_GetModule` and :c:func:`PyType_GetModuleState` to retrieve the module and its state; and - :c:data:`PyCMethod` and :c:data:`METH_METHOD` to allow a method to + :c:type:`PyCMethod` and :c:macro:`METH_METHOD` to allow a method to access the class it was defined in. (Contributed by Marcel Plch and Petr Viktorin in :issue:`38787`.) @@ -1315,7 +1314,7 @@ New Features * The :c:func:`PyModule_AddType` function is added to help adding a type to a module. - (Contributed by Dong-hee Na in :issue:`40024`.) + (Contributed by Donghee Na in :issue:`40024`.) * Added the functions :c:func:`PyObject_GC_IsTracked` and :c:func:`PyObject_GC_IsFinalized` to the public API to allow to query if @@ -1370,8 +1369,8 @@ Porting to Python 3.9 (Contributed by Victor Stinner in :issue:`40241`.) * The ``Py_UNICODE_COPY``, ``Py_UNICODE_FILL``, ``PyUnicode_WSTR_LENGTH``, - :c:func:`PyUnicode_FromUnicode`, :c:func:`PyUnicode_AsUnicode`, - ``_PyUnicode_AsUnicode``, and :c:func:`PyUnicode_AsUnicodeAndSize` are + :c:func:`!PyUnicode_FromUnicode`, :c:func:`!PyUnicode_AsUnicode`, + ``_PyUnicode_AsUnicode``, and :c:func:`!PyUnicode_AsUnicodeAndSize` are marked as deprecated in C. They have been deprecated by :pep:`393` since Python 3.3. (Contributed by Inada Naoki in :issue:`36346`.) @@ -1389,8 +1388,8 @@ Porting to Python 3.9 * :c:func:`PyObject_IS_GC` macro was converted to a function. * The :c:func:`PyObject_NEW` macro becomes an alias to the - :c:func:`PyObject_New` macro, and the :c:func:`PyObject_NEW_VAR` macro - becomes an alias to the :c:func:`PyObject_NewVar` macro. They no longer + :c:macro:`PyObject_New` macro, and the :c:func:`PyObject_NEW_VAR` macro + becomes an alias to the :c:macro:`PyObject_NewVar` macro. They no longer access directly the :c:member:`PyTypeObject.tp_basicsize` member. * :c:func:`PyObject_GET_WEAKREFS_LISTPTR` macro was converted to a function: diff --git a/Doc/whatsnew/index.rst b/Doc/whatsnew/index.rst index c787cdb0..bfee2257 100644 --- a/Doc/whatsnew/index.rst +++ b/Doc/whatsnew/index.rst @@ -11,6 +11,7 @@ anyone wishing to stay up-to-date after a new release. .. toctree:: :maxdepth: 2 + 3.12.rst 3.11.rst 3.10.rst 3.9.rst diff --git a/Grammar/Tokens b/Grammar/Tokens index 1f3e3b09..618ae811 100644 --- a/Grammar/Tokens +++ b/Grammar/Tokens @@ -53,6 +53,7 @@ ATEQUAL '@=' RARROW '->' ELLIPSIS '...' COLONEQUAL ':=' +EXCLAMATION '!' OP AWAIT @@ -60,9 +61,12 @@ ASYNC TYPE_IGNORE TYPE_COMMENT SOFT_KEYWORD +FSTRING_START +FSTRING_MIDDLE +FSTRING_END +COMMENT +NL ERRORTOKEN # These aren't used by the C tokenizer but are needed for tokenize.py -COMMENT -NL ENCODING diff --git a/Grammar/python.gram b/Grammar/python.gram index bae8bc32..f88dc2bd 100644 --- a/Grammar/python.gram +++ b/Grammar/python.gram @@ -112,6 +112,7 @@ simple_stmts[asdl_stmt_seq*]: # will throw a SyntaxError. simple_stmt[stmt_ty] (memo): | assignment + | &"type" type_alias | e=star_expressions { _PyAST_Expr(e, EXTRA) } | &'return' return_stmt | &('import' | 'from') import_stmt @@ -194,7 +195,10 @@ yield_stmt[stmt_ty]: y=yield_expr { _PyAST_Expr(y, EXTRA) } assert_stmt[stmt_ty]: 'assert' a=expression b=[',' z=expression { z }] { _PyAST_Assert(a, b, EXTRA) } -import_stmt[stmt_ty]: import_name | import_from +import_stmt[stmt_ty]: + | invalid_import + | import_name + | import_from # Import statements # ----------------- @@ -249,11 +253,11 @@ class_def[stmt_ty]: class_def_raw[stmt_ty]: | invalid_class_def_raw - | 'class' a=NAME b=['(' z=[arguments] ')' { z }] ':' c=block { + | 'class' a=NAME t=[type_params] b=['(' z=[arguments] ')' { z }] ':' c=block { _PyAST_ClassDef(a->v.Name.id, (b) ? ((expr_ty) b)->v.Call.args : NULL, (b) ? ((expr_ty) b)->v.Call.keywords : NULL, - c, NULL, EXTRA) } + c, NULL, t, EXTRA) } # Function definitions # -------------------- @@ -264,18 +268,18 @@ function_def[stmt_ty]: function_def_raw[stmt_ty]: | invalid_def_raw - | 'def' n=NAME &&'(' params=[params] ')' a=['->' z=expression { z }] &&':' tc=[func_type_comment] b=block { + | 'def' n=NAME t=[type_params] &&'(' params=[params] ')' a=['->' z=expression { z }] &&':' tc=[func_type_comment] b=block { _PyAST_FunctionDef(n->v.Name.id, (params) ? params : CHECK(arguments_ty, _PyPegen_empty_arguments(p)), - b, NULL, a, NEW_TYPE_COMMENT(p, tc), EXTRA) } - | ASYNC 'def' n=NAME &&'(' params=[params] ')' a=['->' z=expression { z }] &&':' tc=[func_type_comment] b=block { + b, NULL, a, NEW_TYPE_COMMENT(p, tc), t, EXTRA) } + | ASYNC 'def' n=NAME t=[type_params] &&'(' params=[params] ')' a=['->' z=expression { z }] &&':' tc=[func_type_comment] b=block { CHECK_VERSION( stmt_ty, 5, "Async functions are", _PyAST_AsyncFunctionDef(n->v.Name.id, (params) ? params : CHECK(arguments_ty, _PyPegen_empty_arguments(p)), - b, NULL, a, NEW_TYPE_COMMENT(p, tc), EXTRA) + b, NULL, a, NEW_TYPE_COMMENT(p, tc), t, EXTRA) ) } # Function parameters @@ -412,8 +416,8 @@ try_stmt[stmt_ty]: | invalid_try_stmt | 'try' &&':' b=block f=finally_block { _PyAST_Try(b, NULL, NULL, f, EXTRA) } | 'try' &&':' b=block ex[asdl_excepthandler_seq*]=except_block+ el=[else_block] f=[finally_block] { _PyAST_Try(b, ex, el, f, EXTRA) } - | 'try' &&':' b=block ex[asdl_excepthandler_seq*]=except_star_block+ el=[else_block] f=[finally_block] { - CHECK_VERSION(stmt_ty, 11, "Exception groups are", + | 'try' &&':' b=block ex[asdl_excepthandler_seq*]=except_star_block+ el=[else_block] f=[finally_block] { + CHECK_VERSION(stmt_ty, 11, "Exception groups are", _PyAST_TryStar(b, ex, el, f, EXTRA)) } @@ -625,6 +629,39 @@ keyword_patterns[asdl_seq*]: keyword_pattern[KeyPatternPair*]: | arg=NAME '=' value=pattern { _PyPegen_key_pattern_pair(p, arg, value) } +# Type statement +# --------------- + +type_alias[stmt_ty]: + | "type" n=NAME t=[type_params] '=' b=expression { + CHECK_VERSION(stmt_ty, 12, "Type statement is", + _PyAST_TypeAlias(CHECK(expr_ty, _PyPegen_set_expr_context(p, n, Store)), t, b, EXTRA)) } + +# Type parameter declaration +# -------------------------- + +type_params[asdl_type_param_seq*]: '[' t=type_param_seq ']' { + CHECK_VERSION(asdl_type_param_seq *, 12, "Type parameter lists are", t) } + +type_param_seq[asdl_type_param_seq*]: a[asdl_type_param_seq*]=','.type_param+ [','] { a } + +type_param[type_param_ty] (memo): + | a=NAME b=[type_param_bound] { _PyAST_TypeVar(a->v.Name.id, b, EXTRA) } + | '*' a=NAME colon=":" e=expression { + RAISE_SYNTAX_ERROR_STARTING_FROM(colon, e->kind == Tuple_kind + ? "cannot use constraints with TypeVarTuple" + : "cannot use bound with TypeVarTuple") + } + | '*' a=NAME { _PyAST_TypeVarTuple(a->v.Name.id, EXTRA) } + | '**' a=NAME colon=":" e=expression { + RAISE_SYNTAX_ERROR_STARTING_FROM(colon, e->kind == Tuple_kind + ? "cannot use constraints with ParamSpec" + : "cannot use bound with ParamSpec") + } + | '**' a=NAME { _PyAST_ParamSpec(a->v.Name.id, EXTRA) } + +type_param_bound[expr_ty]: ":" e=expression { e } + # EXPRESSIONS # ----------- @@ -804,7 +841,7 @@ atom[expr_ty]: | 'True' { _PyAST_Constant(Py_True, NULL, EXTRA) } | 'False' { _PyAST_Constant(Py_False, NULL, EXTRA) } | 'None' { _PyAST_Constant(Py_None, NULL, EXTRA) } - | &STRING strings + | &(STRING|FSTRING_START) strings | NUMBER | &'(' (tuple | group | genexp) | &'[' (list | listcomp) @@ -874,7 +911,25 @@ lambda_param[arg_ty]: a=NAME { _PyAST_arg(a->v.Name.id, NULL, NULL, EXTRA) } # LITERALS # ======== -strings[expr_ty] (memo): a=STRING+ { _PyPegen_concatenate_strings(p, a) } +fstring_middle[expr_ty]: + | fstring_replacement_field + | t=FSTRING_MIDDLE { _PyPegen_constant_from_token(p, t) } +fstring_replacement_field[expr_ty]: + | '{' a=(yield_expr | star_expressions) debug_expr="="? conversion=[fstring_conversion] format=[fstring_full_format_spec] rbrace='}' { + _PyPegen_formatted_value(p, a, debug_expr, conversion, format, rbrace, EXTRA) } + | invalid_replacement_field +fstring_conversion[ResultTokenWithMetadata*]: + | conv_token="!" conv=NAME { _PyPegen_check_fstring_conversion(p, conv_token, conv) } +fstring_full_format_spec[ResultTokenWithMetadata*]: + | colon=':' spec=fstring_format_spec* { _PyPegen_setup_full_format_spec(p, colon, (asdl_expr_seq *) spec, EXTRA) } +fstring_format_spec[expr_ty]: + | t=FSTRING_MIDDLE { _PyPegen_decoded_constant_from_token(p, t) } + | fstring_replacement_field +fstring[expr_ty]: + | a=FSTRING_START b=fstring_middle* c=FSTRING_END { _PyPegen_joined_str(p, a, (asdl_expr_seq*)b, c) } + +string[expr_ty]: s[Token*]=STRING { _PyPegen_constant_from_string(p, s) } +strings[expr_ty] (memo): a[asdl_expr_seq*]=(fstring|string)+ { _PyPegen_concatenate_strings(p, a, EXTRA) } list[expr_ty]: | '[' a=[star_named_expressions] ']' { _PyAST_List(a, Load, EXTRA) } @@ -954,6 +1009,7 @@ kwargs[asdl_seq*]: | ','.kwarg_or_double_starred+ starred_expression[expr_ty]: + | invalid_starred_expression | '*' a=expression { _PyAST_Starred(a, Load, EXTRA) } kwarg_or_starred[KeywordOrStarred*]: @@ -1080,6 +1136,8 @@ invalid_arguments: RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, _PyPegen_get_last_comprehension_item(PyPegen_last_item(b, comprehension_ty)), "Generator expression must be parenthesized") } | a=NAME b='=' expression for_if_clauses { RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "invalid syntax. Maybe you meant '==' or ':=' instead of '='?")} + | (args ',')? a=NAME b='=' &(',' | ')') { + RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "expected argument value expression")} | a=args b=for_if_clauses { _PyPegen_nonparen_genexp_in_call(p, a, b) } | args ',' a=expression b=for_if_clauses { RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, _PyPegen_get_last_comprehension_item(PyPegen_last_item(b, comprehension_ty)), "Generator expression must be parenthesized") } @@ -1092,6 +1150,8 @@ invalid_kwarg: | !(NAME '=') a=expression b='=' { RAISE_SYNTAX_ERROR_KNOWN_RANGE( a, b, "expression cannot contain assignment, perhaps you meant \"==\"?") } + | a='**' expression '=' b=expression { + RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "cannot assign to keyword argument unpacking") } # IMPORTANT: Note that the "_without_invalid" suffix causes the rule to not call invalid rules under it expression_without_invalid[expr_ty]: @@ -1110,6 +1170,8 @@ invalid_expression: _PyPegen_check_legacy_stmt(p, a) ? NULL : p->tokens[p->mark-1]->level == 0 ? NULL : RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "invalid syntax. Perhaps you forgot a comma?") } | a=disjunction 'if' b=disjunction !('else'|':') { RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "expected 'else' after 'if' expression") } + | a='lambda' [lambda_params] b=':' &FSTRING_MIDDLE { + RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "f-string: lambda expressions are not allowed without parentheses") } invalid_named_expression(memo): | a=expression ':=' expression { @@ -1162,14 +1224,14 @@ invalid_dict_comprehension: | '{' a='**' bitwise_or for_if_clauses '}' { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "dict unpacking cannot be used in dict comprehension") } invalid_parameters: - | param_no_default* invalid_parameters_helper a=param_no_default { - RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "non-default argument follows default argument") } - | param_no_default* a='(' param_no_default+ ','? b=')' { - RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "Function parameters cannot be parenthesized") } | a="/" ',' { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "at least one argument must precede /") } | (slash_no_default | slash_with_default) param_maybe_default* a='/' { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "/ may appear only once") } + | slash_no_default? param_no_default* invalid_parameters_helper a=param_no_default { + RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "parameter without a default follows parameter with a default") } + | param_no_default* a='(' param_no_default+ ','? b=')' { + RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "Function parameters cannot be parenthesized") } | (slash_no_default | slash_with_default)? param_maybe_default* '*' (',' | param_no_default) param_maybe_default* a='/' { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "/ must be ahead of *") } | param_maybe_default+ '/' a='*' { @@ -1190,14 +1252,14 @@ invalid_parameters_helper: # This is only there to avoid type errors | a=slash_with_default { _PyPegen_singleton_seq(p, a) } | param_with_default+ invalid_lambda_parameters: - | lambda_param_no_default* invalid_lambda_parameters_helper a=lambda_param_no_default { - RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "non-default argument follows default argument") } - | lambda_param_no_default* a='(' ','.lambda_param+ ','? b=')' { - RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "Lambda expression parameters cannot be parenthesized") } | a="/" ',' { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "at least one argument must precede /") } | (lambda_slash_no_default | lambda_slash_with_default) lambda_param_maybe_default* a='/' { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "/ may appear only once") } + | lambda_slash_no_default? lambda_param_no_default* invalid_lambda_parameters_helper a=lambda_param_no_default { + RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "parameter without a default follows parameter with a default") } + | lambda_param_no_default* a='(' ','.lambda_param+ ','? b=')' { + RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "Lambda expression parameters cannot be parenthesized") } | (lambda_slash_no_default | lambda_slash_with_default)? lambda_param_maybe_default* '*' (',' | lambda_param_no_default) lambda_param_maybe_default* a='/' { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "/ must be ahead of *") } | lambda_param_maybe_default+ '/' a='*' { @@ -1230,6 +1292,10 @@ invalid_group: RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "cannot use starred expression here") } | '(' a='**' expression ')' { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "cannot use double starred expression here") } +invalid_import: + | a='import' ','.dotted_name+ 'from' dotted_name { + RAISE_SYNTAX_ERROR_STARTING_FROM(a, "Did you mean to use 'from ... import ...' instead?") } + invalid_import_from_targets: | import_from_as_names ',' NEWLINE { RAISE_SYNTAX_ERROR("trailing comma not allowed without surrounding parentheses") } @@ -1321,3 +1387,26 @@ invalid_kvpair: RAISE_ERROR_KNOWN_LOCATION(p, PyExc_SyntaxError, a->lineno, a->end_col_offset - 1, a->end_lineno, -1, "':' expected after dictionary key") } | expression ':' a='*' bitwise_or { RAISE_SYNTAX_ERROR_STARTING_FROM(a, "cannot use a starred expression in a dictionary value") } | expression a=':' &('}'|',') {RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "expression expected after dictionary key and ':'") } +invalid_starred_expression: + | a='*' expression '=' b=expression { RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, "cannot assign to iterable argument unpacking") } +invalid_replacement_field: + | '{' a='=' { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "f-string: valid expression required before '='") } + | '{' a='!' { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "f-string: valid expression required before '!'") } + | '{' a=':' { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "f-string: valid expression required before ':'") } + | '{' a='}' { RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, "f-string: valid expression required before '}'") } + | '{' !(yield_expr | star_expressions) { RAISE_SYNTAX_ERROR_ON_NEXT_TOKEN("f-string: expecting a valid expression after '{'")} + | '{' (yield_expr | star_expressions) !('=' | '!' | ':' | '}') { + PyErr_Occurred() ? NULL : RAISE_SYNTAX_ERROR_ON_NEXT_TOKEN("f-string: expecting '=', or '!', or ':', or '}'") } + | '{' (yield_expr | star_expressions) '=' !('!' | ':' | '}') { + PyErr_Occurred() ? NULL : RAISE_SYNTAX_ERROR_ON_NEXT_TOKEN("f-string: expecting '!', or ':', or '}'") } + | '{' (yield_expr | star_expressions) '='? invalid_conversion_character + | '{' (yield_expr | star_expressions) '='? ['!' NAME] !(':' | '}') { + PyErr_Occurred() ? NULL : RAISE_SYNTAX_ERROR_ON_NEXT_TOKEN("f-string: expecting ':' or '}'") } + | '{' (yield_expr | star_expressions) '='? ['!' NAME] ':' fstring_format_spec* !'}' { + PyErr_Occurred() ? NULL : RAISE_SYNTAX_ERROR_ON_NEXT_TOKEN("f-string: expecting '}', or format specs") } + | '{' (yield_expr | star_expressions) '='? ['!' NAME] !'}' { + PyErr_Occurred() ? NULL : RAISE_SYNTAX_ERROR_ON_NEXT_TOKEN("f-string: expecting '}'") } + +invalid_conversion_character: + | '!' &(':' | '}') { RAISE_SYNTAX_ERROR_ON_NEXT_TOKEN("f-string: missing conversion character") } + | '!' !NAME { RAISE_SYNTAX_ERROR_ON_NEXT_TOKEN("f-string: invalid conversion character") } diff --git a/Include/README.rst b/Include/README.rst index f52e690e..531f0969 100644 --- a/Include/README.rst +++ b/Include/README.rst @@ -1,11 +1,13 @@ The Python C API ================ -The C API is divided into three sections: +The C API is divided into these sections: 1. ``Include/``: Limited API 2. ``Include/cpython/``: CPython implementation details -3. ``Include/internal/``: The internal API +3. ``Include/cpython/``, names with the ``PyUnstable_`` prefix: API that can + change between minor releases +4. ``Include/internal/``, and any name with ``_`` prefix: The internal API Information on changing the C API is available `in the developer guide`_ diff --git a/Include/abstract.h b/Include/abstract.h index 9e06fbbb..064b0300 100644 --- a/Include/abstract.h +++ b/Include/abstract.h @@ -14,9 +14,9 @@ extern "C" { Print an object 'o' on file 'fp'. Returns -1 on error. The flags argument is used to enable certain printing options. The only option currently - supported is Py_Print_RAW. - - (What should be said about Py_Print_RAW?). */ + supported is Py_PRINT_RAW. By default (flags=0), PyObject_Print() formats + the object by calling PyObject_Repr(). If flags equals to Py_PRINT_RAW, it + formats the object by calling PyObject_Str(). */ /* Implemented elsewhere: @@ -88,7 +88,7 @@ extern "C" { -1 on failure. This is the equivalent of the Python statement: del o.attr_name. */ -#define PyObject_DelAttrString(O,A) PyObject_SetAttrString((O),(A), NULL) +#define PyObject_DelAttrString(O, A) PyObject_SetAttrString((O), (A), NULL) /* Implemented as a macro: @@ -98,7 +98,7 @@ extern "C" { Delete attribute named attr_name, for object o. Returns -1 on failure. This is the equivalent of the Python statement: del o.attr_name. */ -#define PyObject_DelAttr(O,A) PyObject_SetAttr((O),(A), NULL) +#define PyObject_DelAttr(O, A) PyObject_SetAttr((O), (A), NULL) /* Implemented elsewhere: @@ -228,6 +228,32 @@ PyAPI_FUNC(PyObject *) PyObject_CallMethodObjArgs( PyObject *name, ...); +/* Given a vectorcall nargsf argument, return the actual number of arguments. + * (For use outside the limited API, this is re-defined as a static inline + * function in cpython/abstract.h) + */ +PyAPI_FUNC(Py_ssize_t) PyVectorcall_NARGS(size_t nargsf); + +/* Call "callable" (which must support vectorcall) with positional arguments + "tuple" and keyword arguments "dict". "dict" may also be NULL */ +PyAPI_FUNC(PyObject *) PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *dict); + +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030C0000 +#define PY_VECTORCALL_ARGUMENTS_OFFSET \ + (_Py_STATIC_CAST(size_t, 1) << (8 * sizeof(size_t) - 1)) + +/* Perform a PEP 590-style vector call on 'callable' */ +PyAPI_FUNC(PyObject *) PyObject_Vectorcall( + PyObject *callable, + PyObject *const *args, + size_t nargsf, + PyObject *kwnames); + +/* Call the method 'name' on args[0] with arguments in args[1..nargsf-1]. */ +PyAPI_FUNC(PyObject *) PyObject_VectorcallMethod( + PyObject *name, PyObject *const *args, + size_t nargsf, PyObject *kwnames); +#endif /* Implemented elsewhere: @@ -722,7 +748,7 @@ PyAPI_FUNC(PyObject *) PySequence_Fast(PyObject *o, const char* m); /* Return the 'i'-th element of the sequence 'o', assuming that o was returned by PySequence_Fast, and that i is within bounds. */ #define PySequence_Fast_GET_ITEM(o, i)\ - (PyList_Check(o) ? PyList_GET_ITEM(o, i) : PyTuple_GET_ITEM(o, i)) + (PyList_Check(o) ? PyList_GET_ITEM((o), (i)) : PyTuple_GET_ITEM((o), (i))) /* Return a pointer to the underlying item array for an object returned by PySequence_Fast */ @@ -802,7 +828,7 @@ PyAPI_FUNC(Py_ssize_t) PyMapping_Length(PyObject *o); failure. This is equivalent to the Python statement: del o[key]. */ -#define PyMapping_DelItemString(O,K) PyObject_DelItemString((O),(K)) +#define PyMapping_DelItemString(O, K) PyObject_DelItemString((O), (K)) /* Implemented as a macro: @@ -812,7 +838,7 @@ PyAPI_FUNC(Py_ssize_t) PyMapping_Length(PyObject *o); Returns -1 on failure. This is equivalent to the Python statement: del o[key]. */ -#define PyMapping_DelItem(O,K) PyObject_DelItem((O),(K)) +#define PyMapping_DelItem(O, K) PyObject_DelItem((O), (K)) /* On success, return 1 if the mapping object 'o' has the key 'key', and 0 otherwise. diff --git a/Include/boolobject.h b/Include/boolobject.h index 28068d1c..976fa352 100644 --- a/Include/boolobject.h +++ b/Include/boolobject.h @@ -9,18 +9,17 @@ extern "C" { PyAPI_DATA(PyTypeObject) PyBool_Type; -#define PyBool_Check(x) Py_IS_TYPE(x, &PyBool_Type) +#define PyBool_Check(x) Py_IS_TYPE((x), &PyBool_Type) -/* Py_False and Py_True are the only two bools in existence. -Don't forget to apply Py_INCREF() when returning either!!! */ +/* Py_False and Py_True are the only two bools in existence. */ /* Don't use these directly */ PyAPI_DATA(PyLongObject) _Py_FalseStruct; PyAPI_DATA(PyLongObject) _Py_TrueStruct; /* Use these macros */ -#define Py_False ((PyObject *) &_Py_FalseStruct) -#define Py_True ((PyObject *) &_Py_TrueStruct) +#define Py_False _PyObject_CAST(&_Py_FalseStruct) +#define Py_True _PyObject_CAST(&_Py_TrueStruct) // Test if an object is the True singleton, the same as "x is True" in Python. PyAPI_FUNC(int) Py_IsTrue(PyObject *x); @@ -31,8 +30,8 @@ PyAPI_FUNC(int) Py_IsFalse(PyObject *x); #define Py_IsFalse(x) Py_Is((x), Py_False) /* Macros for returning Py_True or Py_False, respectively */ -#define Py_RETURN_TRUE return Py_NewRef(Py_True) -#define Py_RETURN_FALSE return Py_NewRef(Py_False) +#define Py_RETURN_TRUE return Py_True +#define Py_RETURN_FALSE return Py_False /* Function to return a bool from a C long */ PyAPI_FUNC(PyObject *) PyBool_FromLong(long); diff --git a/Include/bytearrayobject.h b/Include/bytearrayobject.h index ae2bde1c..3d53fdba 100644 --- a/Include/bytearrayobject.h +++ b/Include/bytearrayobject.h @@ -21,8 +21,8 @@ PyAPI_DATA(PyTypeObject) PyByteArray_Type; PyAPI_DATA(PyTypeObject) PyByteArrayIter_Type; /* Type check macros */ -#define PyByteArray_Check(self) PyObject_TypeCheck(self, &PyByteArray_Type) -#define PyByteArray_CheckExact(self) Py_IS_TYPE(self, &PyByteArray_Type) +#define PyByteArray_Check(self) PyObject_TypeCheck((self), &PyByteArray_Type) +#define PyByteArray_CheckExact(self) Py_IS_TYPE((self), &PyByteArray_Type) /* Direct API functions */ PyAPI_FUNC(PyObject *) PyByteArray_FromObject(PyObject *); diff --git a/Include/bytesobject.h b/Include/bytesobject.h index 4c4dc40d..ee448cd0 100644 --- a/Include/bytesobject.h +++ b/Include/bytesobject.h @@ -29,7 +29,7 @@ PyAPI_DATA(PyTypeObject) PyBytesIter_Type; #define PyBytes_Check(op) \ PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_BYTES_SUBCLASS) -#define PyBytes_CheckExact(op) Py_IS_TYPE(op, &PyBytes_Type) +#define PyBytes_CheckExact(op) Py_IS_TYPE((op), &PyBytes_Type) PyAPI_FUNC(PyObject *) PyBytes_FromStringAndSize(const char *, Py_ssize_t); PyAPI_FUNC(PyObject *) PyBytes_FromString(const char *); diff --git a/Include/ceval.h b/Include/ceval.h index 1b57f6ea..ad4d909d 100644 --- a/Include/ceval.h +++ b/Include/ceval.h @@ -31,7 +31,7 @@ Py_DEPRECATED(3.9) PyAPI_FUNC(PyObject *) PyEval_CallObjectWithKeywords( /* Deprecated since PyEval_CallObjectWithKeywords is deprecated */ #define PyEval_CallObject(callable, arg) \ - PyEval_CallObjectWithKeywords(callable, arg, (PyObject *)NULL) + PyEval_CallObjectWithKeywords((callable), (arg), _PyObject_CAST(_Py_NULL)) Py_DEPRECATED(3.9) PyAPI_FUNC(PyObject *) PyEval_CallFunction( PyObject *callable, const char *format, ...); diff --git a/Include/complexobject.h b/Include/complexobject.h index c7764e43..ebe49a83 100644 --- a/Include/complexobject.h +++ b/Include/complexobject.h @@ -10,8 +10,8 @@ extern "C" { PyAPI_DATA(PyTypeObject) PyComplex_Type; -#define PyComplex_Check(op) PyObject_TypeCheck(op, &PyComplex_Type) -#define PyComplex_CheckExact(op) Py_IS_TYPE(op, &PyComplex_Type) +#define PyComplex_Check(op) PyObject_TypeCheck((op), &PyComplex_Type) +#define PyComplex_CheckExact(op) Py_IS_TYPE((op), &PyComplex_Type) PyAPI_FUNC(PyObject *) PyComplex_FromDoubles(double real, double imag); diff --git a/Include/cpython/abstract.h b/Include/cpython/abstract.h index d2766693..3b27aab2 100644 --- a/Include/cpython/abstract.h +++ b/Include/cpython/abstract.h @@ -50,23 +50,18 @@ PyAPI_FUNC(PyObject *) _PyObject_MakeTpCall( PyObject *const *args, Py_ssize_t nargs, PyObject *keywords); -#define PY_VECTORCALL_ARGUMENTS_OFFSET \ - (_Py_STATIC_CAST(size_t, 1) << (8 * sizeof(size_t) - 1)) - +// PyVectorcall_NARGS() is exported as a function for the stable ABI. +// Here (when we are not using the stable ABI), the name is overridden to +// call a static inline function for best performance. +#define PyVectorcall_NARGS(n) _PyVectorcall_NARGS(n) static inline Py_ssize_t -PyVectorcall_NARGS(size_t n) +_PyVectorcall_NARGS(size_t n) { return n & ~PY_VECTORCALL_ARGUMENTS_OFFSET; } PyAPI_FUNC(vectorcallfunc) PyVectorcall_Function(PyObject *callable); -PyAPI_FUNC(PyObject *) PyObject_Vectorcall( - PyObject *callable, - PyObject *const *args, - size_t nargsf, - PyObject *kwnames); - // Backwards compatibility aliases for API that was provisional in Python 3.8 #define _PyObject_Vectorcall PyObject_Vectorcall #define _PyObject_VectorcallMethod PyObject_VectorcallMethod @@ -84,10 +79,6 @@ PyAPI_FUNC(PyObject *) PyObject_VectorcallDict( size_t nargsf, PyObject *kwargs); -/* Call "callable" (which must support vectorcall) with positional arguments - "tuple" and keyword arguments "dict". "dict" may also be NULL */ -PyAPI_FUNC(PyObject *) PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *dict); - // Same as PyObject_Vectorcall(), except without keyword arguments PyAPI_FUNC(PyObject *) _PyObject_FastCall( PyObject *func, @@ -96,10 +87,6 @@ PyAPI_FUNC(PyObject *) _PyObject_FastCall( PyAPI_FUNC(PyObject *) PyObject_CallOneArg(PyObject *func, PyObject *arg); -PyAPI_FUNC(PyObject *) PyObject_VectorcallMethod( - PyObject *name, PyObject *const *args, - size_t nargsf, PyObject *kwnames); - static inline PyObject * PyObject_CallMethodNoArgs(PyObject *self, PyObject *name) { @@ -176,7 +163,7 @@ PyAPI_FUNC(Py_ssize_t) PyObject_LengthHint(PyObject *o, Py_ssize_t); /* Assume tp_as_sequence and sq_item exist and that 'i' does not need to be corrected for a negative index. */ #define PySequence_ITEM(o, i)\ - ( Py_TYPE(o)->tp_as_sequence->sq_item(o, i) ) + ( Py_TYPE(o)->tp_as_sequence->sq_item((o), (i)) ) #define PY_ITERSEARCH_COUNT 1 #define PY_ITERSEARCH_INDEX 2 diff --git a/Include/cpython/bytearrayobject.h b/Include/cpython/bytearrayobject.h index 5114169c..9ba176eb 100644 --- a/Include/cpython/bytearrayobject.h +++ b/Include/cpython/bytearrayobject.h @@ -25,14 +25,10 @@ static inline char* PyByteArray_AS_STRING(PyObject *op) } return _PyByteArray_empty_string; } -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define PyByteArray_AS_STRING(self) PyByteArray_AS_STRING(_PyObject_CAST(self)) -#endif +#define PyByteArray_AS_STRING(self) PyByteArray_AS_STRING(_PyObject_CAST(self)) static inline Py_ssize_t PyByteArray_GET_SIZE(PyObject *op) { PyByteArrayObject *self = _PyByteArray_CAST(op); return Py_SIZE(self); } -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define PyByteArray_GET_SIZE(self) PyByteArray_GET_SIZE(_PyObject_CAST(self)) -#endif +#define PyByteArray_GET_SIZE(self) PyByteArray_GET_SIZE(_PyObject_CAST(self)) diff --git a/Include/cpython/bytesobject.h b/Include/cpython/bytesobject.h index 53343661..e982031c 100644 --- a/Include/cpython/bytesobject.h +++ b/Include/cpython/bytesobject.h @@ -36,17 +36,13 @@ static inline char* PyBytes_AS_STRING(PyObject *op) { return _PyBytes_CAST(op)->ob_sval; } -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define PyBytes_AS_STRING(op) PyBytes_AS_STRING(_PyObject_CAST(op)) -#endif +#define PyBytes_AS_STRING(op) PyBytes_AS_STRING(_PyObject_CAST(op)) static inline Py_ssize_t PyBytes_GET_SIZE(PyObject *op) { PyBytesObject *self = _PyBytes_CAST(op); return Py_SIZE(self); } -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define PyBytes_GET_SIZE(self) PyBytes_GET_SIZE(_PyObject_CAST(self)) -#endif +#define PyBytes_GET_SIZE(self) PyBytes_GET_SIZE(_PyObject_CAST(self)) /* _PyBytes_Join(sep, x) is like sep.join(x). sep must be PyBytesObject*, x must be an iterable object. */ diff --git a/Include/cpython/cellobject.h b/Include/cpython/cellobject.h index e07f9d1d..47a6a491 100644 --- a/Include/cpython/cellobject.h +++ b/Include/cpython/cellobject.h @@ -15,14 +15,27 @@ typedef struct { PyAPI_DATA(PyTypeObject) PyCell_Type; -#define PyCell_Check(op) Py_IS_TYPE(op, &PyCell_Type) +#define PyCell_Check(op) Py_IS_TYPE((op), &PyCell_Type) PyAPI_FUNC(PyObject *) PyCell_New(PyObject *); PyAPI_FUNC(PyObject *) PyCell_Get(PyObject *); PyAPI_FUNC(int) PyCell_Set(PyObject *, PyObject *); -#define PyCell_GET(op) (((PyCellObject *)(op))->ob_ref) -#define PyCell_SET(op, v) _Py_RVALUE(((PyCellObject *)(op))->ob_ref = (v)) +static inline PyObject* PyCell_GET(PyObject *op) { + PyCellObject *cell; + assert(PyCell_Check(op)); + cell = _Py_CAST(PyCellObject*, op); + return cell->ob_ref; +} +#define PyCell_GET(op) PyCell_GET(_PyObject_CAST(op)) + +static inline void PyCell_SET(PyObject *op, PyObject *value) { + PyCellObject *cell; + assert(PyCell_Check(op)); + cell = _Py_CAST(PyCellObject*, op); + cell->ob_ref = value; +} +#define PyCell_SET(op, value) PyCell_SET(_PyObject_CAST(op), (value)) #ifdef __cplusplus } diff --git a/Include/cpython/ceval.h b/Include/cpython/ceval.h index 9d4eeafb..a9616bd6 100644 --- a/Include/cpython/ceval.h +++ b/Include/cpython/ceval.h @@ -3,8 +3,10 @@ #endif PyAPI_FUNC(void) PyEval_SetProfile(Py_tracefunc, PyObject *); +PyAPI_FUNC(void) PyEval_SetProfileAllThreads(Py_tracefunc, PyObject *); PyAPI_DATA(int) _PyEval_SetProfile(PyThreadState *tstate, Py_tracefunc func, PyObject *arg); PyAPI_FUNC(void) PyEval_SetTrace(Py_tracefunc, PyObject *); +PyAPI_FUNC(void) PyEval_SetTraceAllThreads(Py_tracefunc, PyObject *); PyAPI_FUNC(int) _PyEval_SetTrace(PyThreadState *tstate, Py_tracefunc func, PyObject *arg); /* Helper to look up a builtin object */ @@ -20,7 +22,14 @@ PyAPI_FUNC(PyObject *) _PyEval_EvalFrameDefault(PyThreadState *tstate, struct _P PyAPI_FUNC(void) _PyEval_SetSwitchInterval(unsigned long microseconds); PyAPI_FUNC(unsigned long) _PyEval_GetSwitchInterval(void); -PyAPI_FUNC(Py_ssize_t) _PyEval_RequestCodeExtraIndex(freefunc); +PyAPI_FUNC(int) _PyEval_MakePendingCalls(PyThreadState *); + +PyAPI_FUNC(Py_ssize_t) PyUnstable_Eval_RequestCodeExtraIndex(freefunc); +// Old name -- remove when this API changes: +_Py_DEPRECATED_EXTERNALLY(3.12) static inline Py_ssize_t +_PyEval_RequestCodeExtraIndex(freefunc f) { + return PyUnstable_Eval_RequestCodeExtraIndex(f); +} PyAPI_FUNC(int) _PyEval_SliceIndex(PyObject *, Py_ssize_t *); PyAPI_FUNC(int) _PyEval_SliceIndexNotNone(PyObject *, Py_ssize_t *); diff --git a/Include/cpython/classobject.h b/Include/cpython/classobject.h index 80df8842..d7c9ddd1 100644 --- a/Include/cpython/classobject.h +++ b/Include/cpython/classobject.h @@ -19,19 +19,27 @@ typedef struct { PyAPI_DATA(PyTypeObject) PyMethod_Type; -#define PyMethod_Check(op) Py_IS_TYPE(op, &PyMethod_Type) +#define PyMethod_Check(op) Py_IS_TYPE((op), &PyMethod_Type) PyAPI_FUNC(PyObject *) PyMethod_New(PyObject *, PyObject *); PyAPI_FUNC(PyObject *) PyMethod_Function(PyObject *); PyAPI_FUNC(PyObject *) PyMethod_Self(PyObject *); -/* Macros for direct access to these values. Type checks are *not* - done, so use with care. */ -#define PyMethod_GET_FUNCTION(meth) \ - (((PyMethodObject *)meth) -> im_func) -#define PyMethod_GET_SELF(meth) \ - (((PyMethodObject *)meth) -> im_self) +#define _PyMethod_CAST(meth) \ + (assert(PyMethod_Check(meth)), _Py_CAST(PyMethodObject*, meth)) + +/* Static inline functions for direct access to these values. + Type checks are *not* done, so use with care. */ +static inline PyObject* PyMethod_GET_FUNCTION(PyObject *meth) { + return _PyMethod_CAST(meth)->im_func; +} +#define PyMethod_GET_FUNCTION(meth) PyMethod_GET_FUNCTION(_PyObject_CAST(meth)) + +static inline PyObject* PyMethod_GET_SELF(PyObject *meth) { + return _PyMethod_CAST(meth)->im_self; +} +#define PyMethod_GET_SELF(meth) PyMethod_GET_SELF(_PyObject_CAST(meth)) typedef struct { PyObject_HEAD @@ -40,15 +48,21 @@ typedef struct { PyAPI_DATA(PyTypeObject) PyInstanceMethod_Type; -#define PyInstanceMethod_Check(op) Py_IS_TYPE(op, &PyInstanceMethod_Type) +#define PyInstanceMethod_Check(op) Py_IS_TYPE((op), &PyInstanceMethod_Type) PyAPI_FUNC(PyObject *) PyInstanceMethod_New(PyObject *); PyAPI_FUNC(PyObject *) PyInstanceMethod_Function(PyObject *); -/* Macros for direct access to these values. Type checks are *not* - done, so use with care. */ -#define PyInstanceMethod_GET_FUNCTION(meth) \ - (((PyInstanceMethodObject *)meth) -> func) +#define _PyInstanceMethod_CAST(meth) \ + (assert(PyInstanceMethod_Check(meth)), \ + _Py_CAST(PyInstanceMethodObject*, meth)) + +/* Static inline function for direct access to these values. + Type checks are *not* done, so use with care. */ +static inline PyObject* PyInstanceMethod_GET_FUNCTION(PyObject *meth) { + return _PyInstanceMethod_CAST(meth)->func; +} +#define PyInstanceMethod_GET_FUNCTION(meth) PyInstanceMethod_GET_FUNCTION(_PyObject_CAST(meth)) #ifdef __cplusplus } diff --git a/Include/cpython/code.h b/Include/cpython/code.h index 7006060c..03834b20 100644 --- a/Include/cpython/code.h +++ b/Include/cpython/code.h @@ -3,10 +3,29 @@ #ifndef Py_LIMITED_API #ifndef Py_CODE_H #define Py_CODE_H + #ifdef __cplusplus extern "C" { #endif +/* Count of all local monitoring events */ +#define _PY_MONITORING_LOCAL_EVENTS 10 +/* Count of all "real" monitoring events (not derived from other events) */ +#define _PY_MONITORING_UNGROUPED_EVENTS 15 +/* Count of all monitoring events */ +#define _PY_MONITORING_EVENTS 17 + +/* Tables of which tools are active for each monitored event. */ +/* For 3.12 ABI compatibility this is over sized */ +typedef struct _Py_LocalMonitors { + /* Only _PY_MONITORING_LOCAL_EVENTS of these are used */ + uint8_t tools[_PY_MONITORING_UNGROUPED_EVENTS]; +} _Py_LocalMonitors; + +typedef struct _Py_GlobalMonitors { + uint8_t tools[_PY_MONITORING_UNGROUPED_EVENTS]; +} _Py_GlobalMonitors; + /* Each instruction in a code object is a fixed-width value, * currently 2 bytes: 1-byte opcode + 1-byte oparg. The EXTENDED_ARG * opcode allows for larger values but the current limit is 3 uses @@ -16,20 +35,74 @@ extern "C" { * 2**32 - 1, rather than INT_MAX. */ -typedef uint16_t _Py_CODEUNIT; +typedef union { + uint16_t cache; + struct { + uint8_t code; + uint8_t arg; + } op; +} _Py_CODEUNIT; -#ifdef WORDS_BIGENDIAN -# define _Py_OPCODE(word) ((word) >> 8) -# define _Py_OPARG(word) ((word) & 255) -# define _Py_MAKECODEUNIT(opcode, oparg) (((opcode)<<8)|(oparg)) -#else -# define _Py_OPCODE(word) ((word) & 255) -# define _Py_OPARG(word) ((word) >> 8) -# define _Py_MAKECODEUNIT(opcode, oparg) ((opcode)|((oparg)<<8)) -#endif -// Use "unsigned char" instead of "uint8_t" here to avoid illegal aliasing: -#define _Py_SET_OPCODE(word, opcode) (((unsigned char *)&(word))[0] = (opcode)) +/* These macros only remain defined for compatibility. */ +#define _Py_OPCODE(word) ((word).op.code) +#define _Py_OPARG(word) ((word).op.arg) + +static inline _Py_CODEUNIT +_py_make_codeunit(uint8_t opcode, uint8_t oparg) +{ + // No designated initialisers because of C++ compat + _Py_CODEUNIT word; + word.op.code = opcode; + word.op.arg = oparg; + return word; +} + +static inline void +_py_set_opcode(_Py_CODEUNIT *word, uint8_t opcode) +{ + word->op.code = opcode; +} + +#define _Py_MAKE_CODEUNIT(opcode, oparg) _py_make_codeunit((opcode), (oparg)) +#define _Py_SET_OPCODE(word, opcode) _py_set_opcode(&(word), (opcode)) + + +typedef struct { + PyObject *_co_code; + PyObject *_co_varnames; + PyObject *_co_cellvars; + PyObject *_co_freevars; +} _PyCoCached; + +/* Ancilliary data structure used for instrumentation. + Line instrumentation creates an array of + these. One entry per code unit.*/ +typedef struct { + uint8_t original_opcode; + int8_t line_delta; +} _PyCoLineInstrumentationData; + +/* Main data structure used for instrumentation. + * This is allocated when needed for instrumentation + */ +typedef struct { + /* Monitoring specific to this code object */ + _Py_LocalMonitors local_monitors; + /* Monitoring that is active on this code object */ + _Py_LocalMonitors active_monitors; + /* The tools that are to be notified for events for the matching code unit */ + uint8_t *tools; + /* Information to support line events */ + _PyCoLineInstrumentationData *lines; + /* The tools that are to be notified for line events for the matching code unit */ + uint8_t *line_tools; + /* Information to support instruction events */ + /* The underlying instructions, which can themselves be instrumented */ + uint8_t *per_instruction_opcodes; + /* The tools that are to be notified for instruction events for the matching code unit */ + uint8_t *per_instruction_tools; +} _PyCoMonitoringData; // To avoid repeating ourselves in deepfreeze.py, all PyCodeObject members are // defined in this macro: @@ -62,8 +135,6 @@ typedef uint16_t _Py_CODEUNIT; PyObject *co_exceptiontable; /* Byte string encoding exception handling \ table */ \ int co_flags; /* CO_..., see below */ \ - short co_warmup; /* Warmup counter for quickening */ \ - short _co_linearray_entry_size; /* Size of each entry in _co_linearray */ \ \ /* The rest are not so impactful on performance. */ \ int co_argcount; /* #arguments, except *args */ \ @@ -74,12 +145,12 @@ typedef uint16_t _Py_CODEUNIT; \ /* redundant values (derived from co_localsplusnames and \ co_localspluskinds) */ \ - int co_nlocalsplus; /* number of local + cell + free variables \ - */ \ + int co_nlocalsplus; /* number of local + cell + free variables */ \ + int co_framesize; /* Size of frame in words */ \ int co_nlocals; /* number of local variables */ \ - int co_nplaincellvars; /* number of non-arg cell variables */ \ int co_ncellvars; /* total number of cell variables */ \ int co_nfreevars; /* number of free variables */ \ + uint32_t co_version; /* version number */ \ \ PyObject *co_localsplusnames; /* tuple mapping offsets to names */ \ PyObject *co_localspluskinds; /* Bytes mapping to local kinds (one byte \ @@ -89,8 +160,9 @@ typedef uint16_t _Py_CODEUNIT; PyObject *co_qualname; /* unicode (qualname, for reference) */ \ PyObject *co_linetable; /* bytes object that holds location info */ \ PyObject *co_weakreflist; /* to support weakrefs to code objects */ \ - PyObject *_co_code; /* cached co_code object/attribute */ \ - char *_co_linearray; /* array of line offsets */ \ + _PyCoCached *_co_cached; /* cached co_* attributes */ \ + uint64_t _co_instrumentation_version; /* current instrumentation version */ \ + _PyCoMonitoringData *_co_monitoring; /* Monitoring data */ \ int _co_firsttraceable; /* index of first traceable instruction */ \ /* Scratch space for extra data relating to the code object. \ Type is a void* to keep the format private in codeobject.c to force \ @@ -139,24 +211,55 @@ struct PyCodeObject _PyCode_DEF(1); PyAPI_DATA(PyTypeObject) PyCode_Type; -#define PyCode_Check(op) Py_IS_TYPE(op, &PyCode_Type) -#define PyCode_GetNumFree(op) ((op)->co_nfreevars) -#define _PyCode_CODE(CO) ((_Py_CODEUNIT *)(CO)->co_code_adaptive) +#define PyCode_Check(op) Py_IS_TYPE((op), &PyCode_Type) + +static inline Py_ssize_t PyCode_GetNumFree(PyCodeObject *op) { + assert(PyCode_Check(op)); + return op->co_nfreevars; +} + +static inline int PyCode_GetFirstFree(PyCodeObject *op) { + assert(PyCode_Check(op)); + return op->co_nlocalsplus - op->co_nfreevars; +} + +#define _PyCode_CODE(CO) _Py_RVALUE((_Py_CODEUNIT *)(CO)->co_code_adaptive) #define _PyCode_NBYTES(CO) (Py_SIZE(CO) * (Py_ssize_t)sizeof(_Py_CODEUNIT)) -/* Public interface */ -PyAPI_FUNC(PyCodeObject *) PyCode_New( +/* Unstable public interface */ +PyAPI_FUNC(PyCodeObject *) PyUnstable_Code_New( int, int, int, int, int, PyObject *, PyObject *, PyObject *, PyObject *, PyObject *, PyObject *, PyObject *, PyObject *, PyObject *, int, PyObject *, PyObject *); -PyAPI_FUNC(PyCodeObject *) PyCode_NewWithPosOnlyArgs( +PyAPI_FUNC(PyCodeObject *) PyUnstable_Code_NewWithPosOnlyArgs( int, int, int, int, int, int, PyObject *, PyObject *, PyObject *, PyObject *, PyObject *, PyObject *, PyObject *, PyObject *, PyObject *, int, PyObject *, PyObject *); /* same as struct above */ +// Old names -- remove when this API changes: +_Py_DEPRECATED_EXTERNALLY(3.12) static inline PyCodeObject * +PyCode_New( + int a, int b, int c, int d, int e, PyObject *f, PyObject *g, + PyObject *h, PyObject *i, PyObject *j, PyObject *k, + PyObject *l, PyObject *m, PyObject *n, int o, PyObject *p, + PyObject *q) +{ + return PyUnstable_Code_New( + a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q); +} +_Py_DEPRECATED_EXTERNALLY(3.12) static inline PyCodeObject * +PyCode_NewWithPosOnlyArgs( + int a, int poac, int b, int c, int d, int e, PyObject *f, PyObject *g, + PyObject *h, PyObject *i, PyObject *j, PyObject *k, + PyObject *l, PyObject *m, PyObject *n, int o, PyObject *p, + PyObject *q) +{ + return PyUnstable_Code_NewWithPosOnlyArgs( + a, poac, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q); +} /* Creates a new empty code object with the specified source location. */ PyAPI_FUNC(PyCodeObject *) @@ -169,6 +272,46 @@ PyAPI_FUNC(int) PyCode_Addr2Line(PyCodeObject *, int); PyAPI_FUNC(int) PyCode_Addr2Location(PyCodeObject *, int, int *, int *, int *, int *); +#define PY_FOREACH_CODE_EVENT(V) \ + V(CREATE) \ + V(DESTROY) + +typedef enum { + #define PY_DEF_EVENT(op) PY_CODE_EVENT_##op, + PY_FOREACH_CODE_EVENT(PY_DEF_EVENT) + #undef PY_DEF_EVENT +} PyCodeEvent; + + +/* + * A callback that is invoked for different events in a code object's lifecycle. + * + * The callback is invoked with a borrowed reference to co, after it is + * created and before it is destroyed. + * + * If the callback sets an exception, it must return -1. Otherwise + * it should return 0. + */ +typedef int (*PyCode_WatchCallback)( + PyCodeEvent event, + PyCodeObject* co); + +/* + * Register a per-interpreter callback that will be invoked for code object + * lifecycle events. + * + * Returns a handle that may be passed to PyCode_ClearWatcher on success, + * or -1 and sets an error if no more handles are available. + */ +PyAPI_FUNC(int) PyCode_AddWatcher(PyCode_WatchCallback callback); + +/* + * Clear the watcher associated with the watcher_id handle. + * + * Returns 0 on success or -1 if no watcher exists for the provided id. + */ +PyAPI_FUNC(int) PyCode_ClearWatcher(int watcher_id); + /* for internal use only */ struct _opaque { int computed_line; @@ -200,11 +343,21 @@ PyAPI_FUNC(PyObject*) _PyCode_ConstantKey(PyObject *obj); PyAPI_FUNC(PyObject*) PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names, PyObject *lnotab); - -PyAPI_FUNC(int) _PyCode_GetExtra(PyObject *code, Py_ssize_t index, - void **extra); -PyAPI_FUNC(int) _PyCode_SetExtra(PyObject *code, Py_ssize_t index, - void *extra); +PyAPI_FUNC(int) PyUnstable_Code_GetExtra( + PyObject *code, Py_ssize_t index, void **extra); +PyAPI_FUNC(int) PyUnstable_Code_SetExtra( + PyObject *code, Py_ssize_t index, void *extra); +// Old names -- remove when this API changes: +_Py_DEPRECATED_EXTERNALLY(3.12) static inline int +_PyCode_GetExtra(PyObject *code, Py_ssize_t index, void **extra) +{ + return PyUnstable_Code_GetExtra(code, index, extra); +} +_Py_DEPRECATED_EXTERNALLY(3.12) static inline int +_PyCode_SetExtra(PyObject *code, Py_ssize_t index, void *extra) +{ + return PyUnstable_Code_SetExtra(code, index, extra); +} /* Equivalent to getattr(code, 'co_code') in Python. Returns a strong reference to a bytes object. */ diff --git a/Include/cpython/compile.h b/Include/cpython/compile.h index 518a3764..f5a62a8e 100644 --- a/Include/cpython/compile.h +++ b/Include/cpython/compile.h @@ -31,11 +31,26 @@ typedef struct { #define _PyCompilerFlags_INIT \ (PyCompilerFlags){.cf_flags = 0, .cf_feature_version = PY_MINOR_VERSION} +/* source location information */ +typedef struct { + int lineno; + int end_lineno; + int col_offset; + int end_col_offset; +} _PyCompilerSrcLocation; + +#define SRC_LOCATION_FROM_AST(n) \ + (_PyCompilerSrcLocation){ \ + .lineno = (n)->lineno, \ + .end_lineno = (n)->end_lineno, \ + .col_offset = (n)->col_offset, \ + .end_col_offset = (n)->end_col_offset } + /* Future feature support */ typedef struct { - int ff_features; /* flags set by future statements */ - int ff_lineno; /* line number of last future statement */ + int ff_features; /* flags set by future statements */ + _PyCompilerSrcLocation ff_location; /* location of last future statement */ } PyFutureFeatures; #define FUTURE_NESTED_SCOPES "nested_scopes" diff --git a/Include/cpython/context.h b/Include/cpython/context.h index 4db079f7..9879fc71 100644 --- a/Include/cpython/context.h +++ b/Include/cpython/context.h @@ -15,9 +15,9 @@ PyAPI_DATA(PyTypeObject) PyContextToken_Type; typedef struct _pycontexttokenobject PyContextToken; -#define PyContext_CheckExact(o) Py_IS_TYPE(o, &PyContext_Type) -#define PyContextVar_CheckExact(o) Py_IS_TYPE(o, &PyContextVar_Type) -#define PyContextToken_CheckExact(o) Py_IS_TYPE(o, &PyContextToken_Type) +#define PyContext_CheckExact(o) Py_IS_TYPE((o), &PyContext_Type) +#define PyContextVar_CheckExact(o) Py_IS_TYPE((o), &PyContextVar_Type) +#define PyContextToken_CheckExact(o) Py_IS_TYPE((o), &PyContextToken_Type) PyAPI_FUNC(PyObject *) PyContext_New(void); diff --git a/Include/cpython/dictobject.h b/Include/cpython/dictobject.h index 033eaeb4..ddada922 100644 --- a/Include/cpython/dictobject.h +++ b/Include/cpython/dictobject.h @@ -16,7 +16,11 @@ typedef struct { /* Dictionary version: globally unique, value change each time the dictionary is modified */ +#ifdef Py_BUILD_CORE uint64_t ma_version_tag; +#else + Py_DEPRECATED(3.12) uint64_t ma_version_tag; +#endif PyDictKeysObject *ma_keys; @@ -46,7 +50,14 @@ PyAPI_FUNC(int) _PyDict_Next( PyObject *mp, Py_ssize_t *pos, PyObject **key, PyObject **value, Py_hash_t *hash); /* Get the number of items of a dictionary. */ -#define PyDict_GET_SIZE(mp) (assert(PyDict_Check(mp)),((PyDictObject *)mp)->ma_used) +static inline Py_ssize_t PyDict_GET_SIZE(PyObject *op) { + PyDictObject *mp; + assert(PyDict_Check(op)); + mp = _Py_CAST(PyDictObject*, op); + return mp->ma_used; +} +#define PyDict_GET_SIZE(op) PyDict_GET_SIZE(_PyObject_CAST(op)) + PyAPI_FUNC(int) _PyDict_Contains_KnownHash(PyObject *, PyObject *, Py_hash_t); PyAPI_FUNC(int) _PyDict_ContainsId(PyObject *, _Py_Identifier *); PyAPI_FUNC(PyObject *) _PyDict_NewPresized(Py_ssize_t minused); @@ -76,3 +87,32 @@ typedef struct { PyAPI_FUNC(PyObject *) _PyDictView_New(PyObject *, PyTypeObject *); PyAPI_FUNC(PyObject *) _PyDictView_Intersect(PyObject* self, PyObject *other); + +/* Dictionary watchers */ + +#define PY_FOREACH_DICT_EVENT(V) \ + V(ADDED) \ + V(MODIFIED) \ + V(DELETED) \ + V(CLONED) \ + V(CLEARED) \ + V(DEALLOCATED) + +typedef enum { + #define PY_DEF_EVENT(EVENT) PyDict_EVENT_##EVENT, + PY_FOREACH_DICT_EVENT(PY_DEF_EVENT) + #undef PY_DEF_EVENT +} PyDict_WatchEvent; + +// Callback to be invoked when a watched dict is cleared, dealloced, or modified. +// In clear/dealloc case, key and new_value will be NULL. Otherwise, new_value will be the +// new value for key, NULL if key is being deleted. +typedef int(*PyDict_WatchCallback)(PyDict_WatchEvent event, PyObject* dict, PyObject* key, PyObject* new_value); + +// Register/unregister a dict-watcher callback +PyAPI_FUNC(int) PyDict_AddWatcher(PyDict_WatchCallback callback); +PyAPI_FUNC(int) PyDict_ClearWatcher(int watcher_id); + +// Mark given dictionary as "watched" (callback will be called if it is modified) +PyAPI_FUNC(int) PyDict_Watch(int watcher_id, PyObject* dict); +PyAPI_FUNC(int) PyDict_Unwatch(int watcher_id, PyObject* dict); diff --git a/Include/cpython/fileobject.h b/Include/cpython/fileobject.h index cff2243d..b70ec318 100644 --- a/Include/cpython/fileobject.h +++ b/Include/cpython/fileobject.h @@ -3,6 +3,7 @@ #endif PyAPI_FUNC(char *) Py_UniversalNewlineFgets(char *, int, FILE*, PyObject *); +PyAPI_FUNC(char *) _Py_UniversalNewlineFgetsWithSize(char *, int, FILE*, PyObject *, size_t*); /* The std printer acts as a preliminary sys.stderr until the new io infrastructure is in place. */ diff --git a/Include/cpython/floatobject.h b/Include/cpython/floatobject.h index 7795d9f8..12709309 100644 --- a/Include/cpython/floatobject.h +++ b/Include/cpython/floatobject.h @@ -7,9 +7,15 @@ typedef struct { double ob_fval; } PyFloatObject; -// Macro version of PyFloat_AsDouble() trading safety for speed. +#define _PyFloat_CAST(op) \ + (assert(PyFloat_Check(op)), _Py_CAST(PyFloatObject*, op)) + +// Static inline version of PyFloat_AsDouble() trading safety for speed. // It doesn't check if op is a double object. -#define PyFloat_AS_DOUBLE(op) (((PyFloatObject *)(op))->ob_fval) +static inline double PyFloat_AS_DOUBLE(PyObject *op) { + return _PyFloat_CAST(op)->ob_fval; +} +#define PyFloat_AS_DOUBLE(op) PyFloat_AS_DOUBLE(_PyObject_CAST(op)) PyAPI_FUNC(int) PyFloat_Pack2(double x, char *p, int le); diff --git a/Include/cpython/funcobject.h b/Include/cpython/funcobject.h index 99ac6008..6f78f586 100644 --- a/Include/cpython/funcobject.h +++ b/Include/cpython/funcobject.h @@ -41,6 +41,7 @@ typedef struct { PyObject *func_weakreflist; /* List of weak references */ PyObject *func_module; /* The __module__ attribute, can be anything */ PyObject *func_annotations; /* Annotations, a dict or NULL */ + PyObject *func_typeparams; /* Tuple of active type variables or NULL */ vectorcallfunc vectorcall; /* Version number for use by specializer. * Can set to non-zero when we want to specialize. @@ -48,7 +49,8 @@ typedef struct { * defaults * kwdefaults (only if the object changes, not the contents of the dict) * code - * annotations */ + * annotations + * vectorcall function pointer */ uint32_t func_version; /* Invariant: @@ -60,7 +62,7 @@ typedef struct { PyAPI_DATA(PyTypeObject) PyFunction_Type; -#define PyFunction_Check(op) Py_IS_TYPE(op, &PyFunction_Type) +#define PyFunction_Check(op) Py_IS_TYPE((op), &PyFunction_Type) PyAPI_FUNC(PyObject *) PyFunction_New(PyObject *, PyObject *); PyAPI_FUNC(PyObject *) PyFunction_NewWithQualName(PyObject *, PyObject *, PyObject *); @@ -69,6 +71,7 @@ PyAPI_FUNC(PyObject *) PyFunction_GetGlobals(PyObject *); PyAPI_FUNC(PyObject *) PyFunction_GetModule(PyObject *); PyAPI_FUNC(PyObject *) PyFunction_GetDefaults(PyObject *); PyAPI_FUNC(int) PyFunction_SetDefaults(PyObject *, PyObject *); +PyAPI_FUNC(void) PyFunction_SetVectorcall(PyFunctionObject *, vectorcallfunc); PyAPI_FUNC(PyObject *) PyFunction_GetKwDefaults(PyObject *); PyAPI_FUNC(int) PyFunction_SetKwDefaults(PyObject *, PyObject *); PyAPI_FUNC(PyObject *) PyFunction_GetClosure(PyObject *); @@ -82,22 +85,45 @@ PyAPI_FUNC(PyObject *) _PyFunction_Vectorcall( size_t nargsf, PyObject *kwnames); -/* Macros for direct access to these values. Type checks are *not* - done, so use with care. */ -#define PyFunction_GET_CODE(func) \ - (((PyFunctionObject *)func) -> func_code) -#define PyFunction_GET_GLOBALS(func) \ - (((PyFunctionObject *)func) -> func_globals) -#define PyFunction_GET_MODULE(func) \ - (((PyFunctionObject *)func) -> func_module) -#define PyFunction_GET_DEFAULTS(func) \ - (((PyFunctionObject *)func) -> func_defaults) -#define PyFunction_GET_KW_DEFAULTS(func) \ - (((PyFunctionObject *)func) -> func_kwdefaults) -#define PyFunction_GET_CLOSURE(func) \ - (((PyFunctionObject *)func) -> func_closure) -#define PyFunction_GET_ANNOTATIONS(func) \ - (((PyFunctionObject *)func) -> func_annotations) +#define _PyFunction_CAST(func) \ + (assert(PyFunction_Check(func)), _Py_CAST(PyFunctionObject*, func)) + +/* Static inline functions for direct access to these values. + Type checks are *not* done, so use with care. */ +static inline PyObject* PyFunction_GET_CODE(PyObject *func) { + return _PyFunction_CAST(func)->func_code; +} +#define PyFunction_GET_CODE(func) PyFunction_GET_CODE(_PyObject_CAST(func)) + +static inline PyObject* PyFunction_GET_GLOBALS(PyObject *func) { + return _PyFunction_CAST(func)->func_globals; +} +#define PyFunction_GET_GLOBALS(func) PyFunction_GET_GLOBALS(_PyObject_CAST(func)) + +static inline PyObject* PyFunction_GET_MODULE(PyObject *func) { + return _PyFunction_CAST(func)->func_module; +} +#define PyFunction_GET_MODULE(func) PyFunction_GET_MODULE(_PyObject_CAST(func)) + +static inline PyObject* PyFunction_GET_DEFAULTS(PyObject *func) { + return _PyFunction_CAST(func)->func_defaults; +} +#define PyFunction_GET_DEFAULTS(func) PyFunction_GET_DEFAULTS(_PyObject_CAST(func)) + +static inline PyObject* PyFunction_GET_KW_DEFAULTS(PyObject *func) { + return _PyFunction_CAST(func)->func_kwdefaults; +} +#define PyFunction_GET_KW_DEFAULTS(func) PyFunction_GET_KW_DEFAULTS(_PyObject_CAST(func)) + +static inline PyObject* PyFunction_GET_CLOSURE(PyObject *func) { + return _PyFunction_CAST(func)->func_closure; +} +#define PyFunction_GET_CLOSURE(func) PyFunction_GET_CLOSURE(_PyObject_CAST(func)) + +static inline PyObject* PyFunction_GET_ANNOTATIONS(PyObject *func) { + return _PyFunction_CAST(func)->func_annotations; +} +#define PyFunction_GET_ANNOTATIONS(func) PyFunction_GET_ANNOTATIONS(_PyObject_CAST(func)) /* The classmethod and staticmethod types lives here, too */ PyAPI_DATA(PyTypeObject) PyClassMethod_Type; @@ -106,6 +132,55 @@ PyAPI_DATA(PyTypeObject) PyStaticMethod_Type; PyAPI_FUNC(PyObject *) PyClassMethod_New(PyObject *); PyAPI_FUNC(PyObject *) PyStaticMethod_New(PyObject *); +#define PY_FOREACH_FUNC_EVENT(V) \ + V(CREATE) \ + V(DESTROY) \ + V(MODIFY_CODE) \ + V(MODIFY_DEFAULTS) \ + V(MODIFY_KWDEFAULTS) + +typedef enum { + #define PY_DEF_EVENT(EVENT) PyFunction_EVENT_##EVENT, + PY_FOREACH_FUNC_EVENT(PY_DEF_EVENT) + #undef PY_DEF_EVENT +} PyFunction_WatchEvent; + +/* + * A callback that is invoked for different events in a function's lifecycle. + * + * The callback is invoked with a borrowed reference to func, after it is + * created and before it is modified or destroyed. The callback should not + * modify func. + * + * When a function's code object, defaults, or kwdefaults are modified the + * callback will be invoked with the respective event and new_value will + * contain a borrowed reference to the new value that is about to be stored in + * the function. Otherwise the third argument is NULL. + * + * If the callback returns with an exception set, it must return -1. Otherwise + * it should return 0. + */ +typedef int (*PyFunction_WatchCallback)( + PyFunction_WatchEvent event, + PyFunctionObject *func, + PyObject *new_value); + +/* + * Register a per-interpreter callback that will be invoked for function lifecycle + * events. + * + * Returns a handle that may be passed to PyFunction_ClearWatcher on success, + * or -1 and sets an error if no more handles are available. + */ +PyAPI_FUNC(int) PyFunction_AddWatcher(PyFunction_WatchCallback callback); + +/* + * Clear the watcher associated with the watcher_id handle. + * + * Returns 0 on success or -1 if no watcher exists for the supplied id. + */ +PyAPI_FUNC(int) PyFunction_ClearWatcher(int watcher_id); + #ifdef __cplusplus } #endif diff --git a/Include/cpython/genobject.h b/Include/cpython/genobject.h index 40eaa19d..7856481b 100644 --- a/Include/cpython/genobject.h +++ b/Include/cpython/genobject.h @@ -13,8 +13,6 @@ extern "C" { and coroutine objects. */ #define _PyGenObject_HEAD(prefix) \ PyObject_HEAD \ - /* The code object backing the generator */ \ - PyCodeObject *prefix##_code; \ /* List of weak reference. */ \ PyObject *prefix##_weakreflist; \ /* Name of the generator. */ \ @@ -28,7 +26,7 @@ extern "C" { char prefix##_running_async; \ /* The frame */ \ int8_t prefix##_frame_state; \ - PyObject *prefix##_iframe[1]; + PyObject *prefix##_iframe[1]; \ typedef struct { /* The gi_ prefix is intended to remind of generator-iterator. */ @@ -37,8 +35,8 @@ typedef struct { PyAPI_DATA(PyTypeObject) PyGen_Type; -#define PyGen_Check(op) PyObject_TypeCheck(op, &PyGen_Type) -#define PyGen_CheckExact(op) Py_IS_TYPE(op, &PyGen_Type) +#define PyGen_Check(op) PyObject_TypeCheck((op), &PyGen_Type) +#define PyGen_CheckExact(op) Py_IS_TYPE((op), &PyGen_Type) PyAPI_FUNC(PyObject *) PyGen_New(PyFrameObject *); PyAPI_FUNC(PyObject *) PyGen_NewWithQualName(PyFrameObject *, @@ -46,6 +44,7 @@ PyAPI_FUNC(PyObject *) PyGen_NewWithQualName(PyFrameObject *, PyAPI_FUNC(int) _PyGen_SetStopIterationValue(PyObject *); PyAPI_FUNC(int) _PyGen_FetchStopIterationValue(PyObject **); PyAPI_FUNC(void) _PyGen_Finalize(PyObject *self); +PyAPI_FUNC(PyCodeObject *) PyGen_GetCode(PyGenObject *gen); /* --- PyCoroObject ------------------------------------------------------- */ @@ -57,7 +56,7 @@ typedef struct { PyAPI_DATA(PyTypeObject) PyCoro_Type; PyAPI_DATA(PyTypeObject) _PyCoroWrapper_Type; -#define PyCoro_CheckExact(op) Py_IS_TYPE(op, &PyCoro_Type) +#define PyCoro_CheckExact(op) Py_IS_TYPE((op), &PyCoro_Type) PyAPI_FUNC(PyObject *) PyCoro_New(PyFrameObject *, PyObject *name, PyObject *qualname); @@ -76,7 +75,9 @@ PyAPI_DATA(PyTypeObject) _PyAsyncGenAThrow_Type; PyAPI_FUNC(PyObject *) PyAsyncGen_New(PyFrameObject *, PyObject *name, PyObject *qualname); -#define PyAsyncGen_CheckExact(op) Py_IS_TYPE(op, &PyAsyncGen_Type) +#define PyAsyncGen_CheckExact(op) Py_IS_TYPE((op), &PyAsyncGen_Type) + +#define PyAsyncGenASend_CheckExact(op) Py_IS_TYPE((op), &_PyAsyncGenASend_Type) #undef _PyGenObject_HEAD diff --git a/Include/cpython/import.h b/Include/cpython/import.h index a69b4f34..2bca4ade 100644 --- a/Include/cpython/import.h +++ b/Include/cpython/import.h @@ -10,8 +10,8 @@ PyAPI_FUNC(PyObject *) _PyImport_GetModuleId(_Py_Identifier *name); PyAPI_FUNC(int) _PyImport_SetModule(PyObject *name, PyObject *module); PyAPI_FUNC(int) _PyImport_SetModuleString(const char *name, PyObject* module); -PyAPI_FUNC(void) _PyImport_AcquireLock(void); -PyAPI_FUNC(int) _PyImport_ReleaseLock(void); +PyAPI_FUNC(void) _PyImport_AcquireLock(PyInterpreterState *interp); +PyAPI_FUNC(int) _PyImport_ReleaseLock(PyInterpreterState *interp); PyAPI_FUNC(int) _PyImport_FixupBuiltin( PyObject *mod, @@ -25,6 +25,7 @@ struct _inittab { const char *name; /* ASCII encoded string */ PyObject* (*initfunc)(void); }; +// This is not used after Py_Initialize() is called. PyAPI_DATA(struct _inittab *) PyImport_Inittab; PyAPI_FUNC(int) PyImport_ExtendInittab(struct _inittab *newtab); diff --git a/Include/cpython/initconfig.h b/Include/cpython/initconfig.h index 3b6d5938..cbae97f1 100644 --- a/Include/cpython/initconfig.h +++ b/Include/cpython/initconfig.h @@ -25,6 +25,7 @@ PyAPI_FUNC(PyStatus) PyStatus_Exit(int exitcode); PyAPI_FUNC(int) PyStatus_IsError(PyStatus err); PyAPI_FUNC(int) PyStatus_IsExit(PyStatus err); PyAPI_FUNC(int) PyStatus_Exception(PyStatus err); +PyAPI_FUNC(PyObject *) _PyErr_SetFromPyStatus(PyStatus status); /* --- PyWideStringList ------------------------------------------------ */ @@ -142,6 +143,7 @@ typedef struct PyConfig { unsigned long hash_seed; int faulthandler; int tracemalloc; + int perf_profiling; int import_time; int code_debug_ranges; int show_ref_count; @@ -177,6 +179,7 @@ typedef struct PyConfig { wchar_t *check_hash_pycs_mode; int use_frozen_modules; int safe_path; + int int_max_str_digits; /* --- Path configuration inputs ------------ */ int pathconfig_warnings; @@ -211,10 +214,6 @@ typedef struct PyConfig { // If equal to 0, stop Python initialization before the "main" phase. int _init_main; - // If non-zero, disallow threads, subprocesses, and fork. - // Default: 0. - int _isolated_interpreter; - // If non-zero, we believe we're running from a source tree. int _is_python_build; } PyConfig; diff --git a/Include/internal/pycore_interpreteridobject.h b/Include/cpython/interpreteridobject.h similarity index 51% rename from Include/internal/pycore_interpreteridobject.h rename to Include/cpython/interpreteridobject.h index 804831e7..50765842 100644 --- a/Include/internal/pycore_interpreteridobject.h +++ b/Include/cpython/interpreteridobject.h @@ -1,22 +1,11 @@ -/* Interpreter ID Object */ - -#ifndef Py_INTERNAL_INTERPRETERIDOBJECT_H -#define Py_INTERNAL_INTERPRETERIDOBJECT_H -#ifdef __cplusplus -extern "C" { +#ifndef Py_CPYTHON_INTERPRETERIDOBJECT_H +# error "this header file must not be included directly" #endif -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif +/* Interpreter ID Object */ PyAPI_DATA(PyTypeObject) _PyInterpreterID_Type; PyAPI_FUNC(PyObject *) _PyInterpreterID_New(int64_t); PyAPI_FUNC(PyObject *) _PyInterpreterState_GetIDObject(PyInterpreterState *); PyAPI_FUNC(PyInterpreterState *) _PyInterpreterID_LookUp(PyObject *); - -#ifdef __cplusplus -} -#endif -#endif // !Py_INTERNAL_INTERPRETERIDOBJECT_H diff --git a/Include/cpython/listobject.h b/Include/cpython/listobject.h index 1add8213..8fa82122 100644 --- a/Include/cpython/listobject.h +++ b/Include/cpython/listobject.h @@ -34,18 +34,14 @@ static inline Py_ssize_t PyList_GET_SIZE(PyObject *op) { PyListObject *list = _PyList_CAST(op); return Py_SIZE(list); } -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define PyList_GET_SIZE(op) PyList_GET_SIZE(_PyObject_CAST(op)) -#endif +#define PyList_GET_SIZE(op) PyList_GET_SIZE(_PyObject_CAST(op)) -#define PyList_GET_ITEM(op, index) (_PyList_CAST(op)->ob_item[index]) +#define PyList_GET_ITEM(op, index) (_PyList_CAST(op)->ob_item[(index)]) static inline void PyList_SET_ITEM(PyObject *op, Py_ssize_t index, PyObject *value) { PyListObject *list = _PyList_CAST(op); list->ob_item[index] = value; } -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 #define PyList_SET_ITEM(op, index, value) \ - PyList_SET_ITEM(_PyObject_CAST(op), index, _PyObject_CAST(value)) -#endif + PyList_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value)) diff --git a/Include/cpython/longintrepr.h b/Include/cpython/longintrepr.h index 6d524275..692c69ba 100644 --- a/Include/cpython/longintrepr.h +++ b/Include/cpython/longintrepr.h @@ -79,9 +79,14 @@ typedef long stwodigits; /* signed variant of twodigits */ aware that ints abuse ob_size's sign bit. */ -struct _longobject { - PyObject_VAR_HEAD +typedef struct _PyLongValue { + uintptr_t lv_tag; /* Number of digits, sign and flags */ digit ob_digit[1]; +} _PyLongValue; + +struct _longobject { + PyObject_HEAD + _PyLongValue long_value; }; PyAPI_FUNC(PyLongObject *) _PyLong_New(Py_ssize_t); @@ -89,6 +94,37 @@ PyAPI_FUNC(PyLongObject *) _PyLong_New(Py_ssize_t); /* Return a copy of src. */ PyAPI_FUNC(PyObject *) _PyLong_Copy(PyLongObject *src); +PyAPI_FUNC(PyLongObject *) +_PyLong_FromDigits(int negative, Py_ssize_t digit_count, digit *digits); + + +/* Inline some internals for speed. These should be in pycore_long.h + * if user code didn't need them inlined. */ + +#define _PyLong_SIGN_MASK 3 +#define _PyLong_NON_SIZE_BITS 3 + + +static inline int +_PyLong_IsCompact(const PyLongObject* op) { + assert(PyType_HasFeature((op)->ob_base.ob_type, Py_TPFLAGS_LONG_SUBCLASS)); + return op->long_value.lv_tag < (2 << _PyLong_NON_SIZE_BITS); +} + +#define PyUnstable_Long_IsCompact _PyLong_IsCompact + +static inline Py_ssize_t +_PyLong_CompactValue(const PyLongObject *op) +{ + assert(PyType_HasFeature((op)->ob_base.ob_type, Py_TPFLAGS_LONG_SUBCLASS)); + assert(PyUnstable_Long_IsCompact(op)); + Py_ssize_t sign = 1 - (op->long_value.lv_tag & _PyLong_SIGN_MASK); + return sign * (Py_ssize_t)op->long_value.ob_digit[0]; +} + +#define PyUnstable_Long_CompactValue _PyLong_CompactValue + + #ifdef __cplusplus } #endif diff --git a/Include/cpython/longobject.h b/Include/cpython/longobject.h index 1a73799d..90cc0f26 100644 --- a/Include/cpython/longobject.h +++ b/Include/cpython/longobject.h @@ -93,3 +93,8 @@ PyAPI_FUNC(PyObject *) _PyLong_GCD(PyObject *, PyObject *); PyAPI_FUNC(PyObject *) _PyLong_Rshift(PyObject *, size_t); PyAPI_FUNC(PyObject *) _PyLong_Lshift(PyObject *, size_t); + + +PyAPI_FUNC(int) PyUnstable_Long_IsCompact(const PyLongObject* op); +PyAPI_FUNC(Py_ssize_t) PyUnstable_Long_CompactValue(const PyLongObject* op); + diff --git a/Include/cpython/memoryobject.h b/Include/cpython/memoryobject.h new file mode 100644 index 00000000..3837fa8c --- /dev/null +++ b/Include/cpython/memoryobject.h @@ -0,0 +1,52 @@ +#ifndef Py_CPYTHON_MEMORYOBJECT_H +# error "this header file must not be included directly" +#endif + +PyAPI_DATA(PyTypeObject) _PyManagedBuffer_Type; + +/* The structs are declared here so that macros can work, but they shouldn't + be considered public. Don't access their fields directly, use the macros + and functions instead! */ +#define _Py_MANAGED_BUFFER_RELEASED 0x001 /* access to exporter blocked */ +#define _Py_MANAGED_BUFFER_FREE_FORMAT 0x002 /* free format */ + +typedef struct { + PyObject_HEAD + int flags; /* state flags */ + Py_ssize_t exports; /* number of direct memoryview exports */ + Py_buffer master; /* snapshot buffer obtained from the original exporter */ +} _PyManagedBufferObject; + + +/* memoryview state flags */ +#define _Py_MEMORYVIEW_RELEASED 0x001 /* access to master buffer blocked */ +#define _Py_MEMORYVIEW_C 0x002 /* C-contiguous layout */ +#define _Py_MEMORYVIEW_FORTRAN 0x004 /* Fortran contiguous layout */ +#define _Py_MEMORYVIEW_SCALAR 0x008 /* scalar: ndim = 0 */ +#define _Py_MEMORYVIEW_PIL 0x010 /* PIL-style layout */ +#define _Py_MEMORYVIEW_RESTRICTED 0x020 /* Disallow new references to the memoryview's buffer */ + +typedef struct { + PyObject_VAR_HEAD + _PyManagedBufferObject *mbuf; /* managed buffer */ + Py_hash_t hash; /* hash value for read-only views */ + int flags; /* state flags */ + Py_ssize_t exports; /* number of buffer re-exports */ + Py_buffer view; /* private copy of the exporter's view */ + PyObject *weakreflist; + Py_ssize_t ob_array[1]; /* shape, strides, suboffsets */ +} PyMemoryViewObject; + +#define _PyMemoryView_CAST(op) _Py_CAST(PyMemoryViewObject*, op) + +/* Get a pointer to the memoryview's private copy of the exporter's buffer. */ +static inline Py_buffer* PyMemoryView_GET_BUFFER(PyObject *op) { + return (&_PyMemoryView_CAST(op)->view); +} +#define PyMemoryView_GET_BUFFER(op) PyMemoryView_GET_BUFFER(_PyObject_CAST(op)) + +/* Get a pointer to the exporting object (this may be NULL!). */ +static inline PyObject* PyMemoryView_GET_BASE(PyObject *op) { + return _PyMemoryView_CAST(op)->view.obj; +} +#define PyMemoryView_GET_BASE(op) PyMemoryView_GET_BASE(_PyObject_CAST(op)) diff --git a/Include/cpython/methodobject.h b/Include/cpython/methodobject.h index 54a61cfd..d541e154 100644 --- a/Include/cpython/methodobject.h +++ b/Include/cpython/methodobject.h @@ -31,8 +31,8 @@ typedef struct { PyAPI_DATA(PyTypeObject) PyCMethod_Type; -#define PyCMethod_CheckExact(op) Py_IS_TYPE(op, &PyCMethod_Type) -#define PyCMethod_Check(op) PyObject_TypeCheck(op, &PyCMethod_Type) +#define PyCMethod_CheckExact(op) Py_IS_TYPE((op), &PyCMethod_Type) +#define PyCMethod_Check(op) PyObject_TypeCheck((op), &PyCMethod_Type) /* Static inline functions for direct access to these values. @@ -40,9 +40,7 @@ PyAPI_DATA(PyTypeObject) PyCMethod_Type; static inline PyCFunction PyCFunction_GET_FUNCTION(PyObject *func) { return _PyCFunctionObject_CAST(func)->m_ml->ml_meth; } -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define PyCFunction_GET_FUNCTION(func) PyCFunction_GET_FUNCTION(_PyObject_CAST(func)) -#endif +#define PyCFunction_GET_FUNCTION(func) PyCFunction_GET_FUNCTION(_PyObject_CAST(func)) static inline PyObject* PyCFunction_GET_SELF(PyObject *func_obj) { PyCFunctionObject *func = _PyCFunctionObject_CAST(func_obj); @@ -51,16 +49,12 @@ static inline PyObject* PyCFunction_GET_SELF(PyObject *func_obj) { } return func->m_self; } -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define PyCFunction_GET_SELF(func) PyCFunction_GET_SELF(_PyObject_CAST(func)) -#endif +#define PyCFunction_GET_SELF(func) PyCFunction_GET_SELF(_PyObject_CAST(func)) static inline int PyCFunction_GET_FLAGS(PyObject *func) { return _PyCFunctionObject_CAST(func)->m_ml->ml_flags; } -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define PyCFunction_GET_FLAGS(func) PyCFunction_GET_FLAGS(_PyObject_CAST(func)) -#endif +#define PyCFunction_GET_FLAGS(func) PyCFunction_GET_FLAGS(_PyObject_CAST(func)) static inline PyTypeObject* PyCFunction_GET_CLASS(PyObject *func_obj) { PyCFunctionObject *func = _PyCFunctionObject_CAST(func_obj); @@ -69,6 +63,4 @@ static inline PyTypeObject* PyCFunction_GET_CLASS(PyObject *func_obj) { } return _Py_NULL; } -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define PyCFunction_GET_CLASS(func) PyCFunction_GET_CLASS(_PyObject_CAST(func)) -#endif +#define PyCFunction_GET_CLASS(func) PyCFunction_GET_CLASS(_PyObject_CAST(func)) diff --git a/Include/cpython/modsupport.h b/Include/cpython/modsupport.h index 769eb52b..2259291a 100644 --- a/Include/cpython/modsupport.h +++ b/Include/cpython/modsupport.h @@ -34,11 +34,13 @@ PyAPI_FUNC(int) _PyArg_NoPositional(const char *funcname, PyObject *args); #define _PyArg_NoPositional(funcname, args) \ ((args) == NULL || _PyArg_NoPositional((funcname), (args))) +#define _Py_ANY_VARARGS(n) ((n) == PY_SSIZE_T_MAX) + PyAPI_FUNC(void) _PyArg_BadArgument(const char *, const char *, const char *, PyObject *); PyAPI_FUNC(int) _PyArg_CheckPositional(const char *, Py_ssize_t, Py_ssize_t, Py_ssize_t); #define _PyArg_CheckPositional(funcname, nargs, min, max) \ - ((!ANY_VARARGS(max) && (min) <= (nargs) && (nargs) <= (max)) \ + ((!_Py_ANY_VARARGS(max) && (min) <= (nargs) && (nargs) <= (max)) \ || _PyArg_CheckPositional((funcname), (nargs), (min), (max))) PyAPI_FUNC(PyObject **) _Py_VaBuildStack( @@ -49,6 +51,7 @@ PyAPI_FUNC(PyObject **) _Py_VaBuildStack( Py_ssize_t *p_nargs); typedef struct _PyArg_Parser { + int initialized; const char *format; const char * const *keywords; const char *fname; @@ -98,10 +101,9 @@ PyAPI_FUNC(PyObject * const *) _PyArg_UnpackKeywordsWithVararg( #define _PyArg_UnpackKeywords(args, nargs, kwargs, kwnames, parser, minpos, maxpos, minkw, buf) \ (((minkw) == 0 && (kwargs) == NULL && (kwnames) == NULL && \ - (minpos) <= (nargs) && (nargs) <= (maxpos) && args != NULL) ? (args) : \ + (minpos) <= (nargs) && (nargs) <= (maxpos) && (args) != NULL) ? (args) : \ _PyArg_UnpackKeywords((args), (nargs), (kwargs), (kwnames), (parser), \ (minpos), (maxpos), (minkw), (buf))) PyAPI_FUNC(PyObject *) _PyModule_CreateInitialized(PyModuleDef*, int apiver); - -PyAPI_DATA(const char *) _Py_PackageContext; +PyAPI_FUNC(int) _PyModule_Add(PyObject *, const char *, PyObject *); diff --git a/Include/cpython/object.h b/Include/cpython/object.h index b018dabf..ae7f780a 100644 --- a/Include/cpython/object.h +++ b/Include/cpython/object.h @@ -3,6 +3,7 @@ #endif PyAPI_FUNC(void) _Py_NewReference(PyObject *op); +PyAPI_FUNC(void) _Py_NewReferenceNoTotal(PyObject *op); #ifdef Py_TRACE_REFS /* Py_TRACE_REFS is such major surgery that we call external routines. */ @@ -10,7 +11,11 @@ PyAPI_FUNC(void) _Py_ForgetReference(PyObject *); #endif #ifdef Py_REF_DEBUG -PyAPI_FUNC(Py_ssize_t) _Py_GetRefTotal(void); +/* These are useful as debugging aids when chasing down refleaks. */ +PyAPI_FUNC(Py_ssize_t) _Py_GetGlobalRefTotal(void); +# define _Py_GetRefTotal() _Py_GetGlobalRefTotal() +PyAPI_FUNC(Py_ssize_t) _Py_GetLegacyRefTotal(void); +PyAPI_FUNC(Py_ssize_t) _PyInterpreterState_GetRefTotal(PyInterpreterState *); #endif @@ -41,22 +46,15 @@ typedef struct _Py_Identifier { Py_ssize_t index; } _Py_Identifier; -#if defined(NEEDS_PY_IDENTIFIER) || !defined(Py_BUILD_CORE) +#ifndef Py_BUILD_CORE // For now we are keeping _Py_IDENTIFIER for continued use // in non-builtin extensions (and naughty PyPI modules). -#define _Py_static_string_init(value) { .string = value, .index = -1 } +#define _Py_static_string_init(value) { .string = (value), .index = -1 } #define _Py_static_string(varname, value) static _Py_Identifier varname = _Py_static_string_init(value) #define _Py_IDENTIFIER(varname) _Py_static_string(PyId_##varname, #varname) -#endif /* NEEDS_PY_IDENTIFIER */ - -typedef int (*getbufferproc)(PyObject *, Py_buffer *, int); -typedef void (*releasebufferproc)(PyObject *, Py_buffer *); - -typedef PyObject *(*vectorcallfunc)(PyObject *callable, PyObject *const *args, - size_t nargsf, PyObject *kwnames); - +#endif /* !Py_BUILD_CORE */ typedef struct { /* Number implementations must check *both* @@ -217,9 +215,9 @@ struct _typeobject { inquiry tp_is_gc; /* For PyObject_IS_GC */ PyObject *tp_bases; PyObject *tp_mro; /* method resolution order */ - PyObject *tp_cache; - PyObject *tp_subclasses; - PyObject *tp_weaklist; + PyObject *tp_cache; /* no longer used */ + void *tp_subclasses; /* for static builtin types this is an index */ + PyObject *tp_weaklist; /* not used for static builtin types */ destructor tp_del; /* Type attribute cache version tag. Added in version 2.6 */ @@ -227,13 +225,27 @@ struct _typeobject { destructor tp_finalize; vectorcallfunc tp_vectorcall; + + /* bitset of which type-watchers care about this type */ + unsigned char tp_watched; }; /* This struct is used by the specializer * It should should be treated as an opaque blob * by code other than the specializer and interpreter. */ struct _specialization_cache { + // In order to avoid bloating the bytecode with lots of inline caches, the + // members of this structure have a somewhat unique contract. They are set + // by the specialization machinery, and are invalidated by PyType_Modified. + // The rules for using them are as follows: + // - If getitem is non-NULL, then it is the same Python function that + // PyType_Lookup(cls, "__getitem__") would return. + // - If getitem is NULL, then getitem_version is meaningless. + // - If getitem->func_version == getitem_version, then getitem can be called + // with two positional arguments and no keyword arguments, and has neither + // *args nor **kwargs (as required by BINARY_SUBSCR_GETITEM): PyObject *getitem; + uint32_t getitem_version; }; /* The *real* layout of a type object when allocated on the heap */ @@ -271,6 +283,7 @@ PyAPI_FUNC(PyTypeObject *) _PyType_CalculateMetaclass(PyTypeObject *, PyObject * PyAPI_FUNC(PyObject *) _PyType_GetDocFromInternalDoc(const char *, const char *); PyAPI_FUNC(PyObject *) _PyType_GetTextSignatureFromInternalDoc(const char *, const char *); PyAPI_FUNC(PyObject *) PyType_GetModuleByDef(PyTypeObject *, PyModuleDef *); +PyAPI_FUNC(PyObject *) PyType_GetDict(PyTypeObject *); PyAPI_FUNC(int) PyObject_Print(PyObject *, FILE *, int); PyAPI_FUNC(void) _Py_BreakPoint(void); @@ -309,38 +322,69 @@ _PyObject_GenericSetAttrWithDict(PyObject *, PyObject *, PyAPI_FUNC(PyObject *) _PyObject_FunctionStr(PyObject *); -/* Safely decref `op` and set `op` to `op2`. +/* Safely decref `dst` and set `dst` to `src`. * * As in case of Py_CLEAR "the obvious" code can be deadly: * - * Py_DECREF(op); - * op = op2; + * Py_DECREF(dst); + * dst = src; * * The safe way is: * - * Py_SETREF(op, op2); + * Py_SETREF(dst, src); + * + * That arranges to set `dst` to `src` _before_ decref'ing, so that any code + * triggered as a side-effect of `dst` getting torn down no longer believes + * `dst` points to a valid object. * - * That arranges to set `op` to `op2` _before_ decref'ing, so that any code - * triggered as a side-effect of `op` getting torn down no longer believes - * `op` points to a valid object. + * Temporary variables are used to only evalutate macro arguments once and so + * avoid the duplication of side effects. _Py_TYPEOF() or memcpy() is used to + * avoid a miscompilation caused by type punning. See Py_CLEAR() comment for + * implementation details about type punning. * - * Py_XSETREF is a variant of Py_SETREF that uses Py_XDECREF instead of - * Py_DECREF. + * The memcpy() implementation does not emit a compiler warning if 'src' has + * not the same type than 'src': any pointer type is accepted for 'src'. */ - -#define Py_SETREF(op, op2) \ - do { \ - PyObject *_py_tmp = _PyObject_CAST(op); \ - (op) = (op2); \ - Py_DECREF(_py_tmp); \ +#ifdef _Py_TYPEOF +#define Py_SETREF(dst, src) \ + do { \ + _Py_TYPEOF(dst)* _tmp_dst_ptr = &(dst); \ + _Py_TYPEOF(dst) _tmp_old_dst = (*_tmp_dst_ptr); \ + *_tmp_dst_ptr = (src); \ + Py_DECREF(_tmp_old_dst); \ + } while (0) +#else +#define Py_SETREF(dst, src) \ + do { \ + PyObject **_tmp_dst_ptr = _Py_CAST(PyObject**, &(dst)); \ + PyObject *_tmp_old_dst = (*_tmp_dst_ptr); \ + PyObject *_tmp_src = _PyObject_CAST(src); \ + memcpy(_tmp_dst_ptr, &_tmp_src, sizeof(PyObject*)); \ + Py_DECREF(_tmp_old_dst); \ } while (0) +#endif -#define Py_XSETREF(op, op2) \ - do { \ - PyObject *_py_tmp = _PyObject_CAST(op); \ - (op) = (op2); \ - Py_XDECREF(_py_tmp); \ +/* Py_XSETREF() is a variant of Py_SETREF() that uses Py_XDECREF() instead of + * Py_DECREF(). + */ +#ifdef _Py_TYPEOF +#define Py_XSETREF(dst, src) \ + do { \ + _Py_TYPEOF(dst)* _tmp_dst_ptr = &(dst); \ + _Py_TYPEOF(dst) _tmp_old_dst = (*_tmp_dst_ptr); \ + *_tmp_dst_ptr = (src); \ + Py_XDECREF(_tmp_old_dst); \ + } while (0) +#else +#define Py_XSETREF(dst, src) \ + do { \ + PyObject **_tmp_dst_ptr = _Py_CAST(PyObject**, &(dst)); \ + PyObject *_tmp_old_dst = (*_tmp_dst_ptr); \ + PyObject *_tmp_src = _PyObject_CAST(src); \ + memcpy(_tmp_dst_ptr, &_tmp_src, sizeof(PyObject*)); \ + Py_XDECREF(_tmp_old_dst); \ } while (0) +#endif PyAPI_DATA(PyTypeObject) _PyNone_Type; @@ -385,9 +429,9 @@ _PyObject_DebugTypeStats(FILE *out); #endif #define _PyObject_ASSERT_WITH_MSG(obj, expr, msg) \ - _PyObject_ASSERT_FROM(obj, expr, msg, __FILE__, __LINE__, __func__) + _PyObject_ASSERT_FROM((obj), expr, (msg), __FILE__, __LINE__, __func__) #define _PyObject_ASSERT(obj, expr) \ - _PyObject_ASSERT_WITH_MSG(obj, expr, NULL) + _PyObject_ASSERT_WITH_MSG((obj), expr, NULL) #define _PyObject_ASSERT_FAILED_MSG(obj, msg) \ _PyObject_AssertFailed((obj), NULL, (msg), __FILE__, __LINE__, __func__) @@ -480,7 +524,7 @@ PyAPI_FUNC(int) _PyTrash_cond(PyObject *op, destructor dealloc); /* If "cond" is false, then _tstate remains NULL and the deallocator \ * is run normally without involving the trashcan */ \ if (cond) { \ - _tstate = PyThreadState_Get(); \ + _tstate = _PyThreadState_UncheckedGet(); \ if (_PyTrash_begin(_tstate, _PyObject_CAST(op))) { \ break; \ } \ @@ -493,8 +537,8 @@ PyAPI_FUNC(int) _PyTrash_cond(PyObject *op, destructor dealloc); } while (0); #define Py_TRASHCAN_BEGIN(op, dealloc) \ - Py_TRASHCAN_BEGIN_CONDITION(op, \ - _PyTrash_cond(_PyObject_CAST(op), (destructor)dealloc)) + Py_TRASHCAN_BEGIN_CONDITION((op), \ + _PyTrash_cond(_PyObject_CAST(op), (destructor)(dealloc))) /* The following two macros, Py_TRASHCAN_SAFE_BEGIN and * Py_TRASHCAN_SAFE_END, are deprecated since version 3.11 and @@ -505,7 +549,27 @@ Py_DEPRECATED(3.11) typedef int UsingDeprecatedTrashcanMacro; #define Py_TRASHCAN_SAFE_BEGIN(op) \ do { \ UsingDeprecatedTrashcanMacro cond=1; \ - Py_TRASHCAN_BEGIN_CONDITION(op, cond); + Py_TRASHCAN_BEGIN_CONDITION((op), cond); #define Py_TRASHCAN_SAFE_END(op) \ Py_TRASHCAN_END; \ } while(0); + +PyAPI_FUNC(void *) PyObject_GetItemData(PyObject *obj); + +PyAPI_FUNC(int) _PyObject_VisitManagedDict(PyObject *obj, visitproc visit, void *arg); +PyAPI_FUNC(void) _PyObject_ClearManagedDict(PyObject *obj); + +#define TYPE_MAX_WATCHERS 8 + +typedef int(*PyType_WatchCallback)(PyTypeObject *); +PyAPI_FUNC(int) PyType_AddWatcher(PyType_WatchCallback callback); +PyAPI_FUNC(int) PyType_ClearWatcher(int watcher_id); +PyAPI_FUNC(int) PyType_Watch(int watcher_id, PyObject *type); +PyAPI_FUNC(int) PyType_Unwatch(int watcher_id, PyObject *type); + +/* Attempt to assign a version tag to the given type. + * + * Returns 1 if the type already had a valid version tag or a new one was + * assigned, or 0 if a new tag could not be assigned. + */ +PyAPI_FUNC(int) PyUnstable_Type_AssignVersionTag(PyTypeObject *type); diff --git a/Include/cpython/objimpl.h b/Include/cpython/objimpl.h index d7c76eab..5a8cdd57 100644 --- a/Include/cpython/objimpl.h +++ b/Include/cpython/objimpl.h @@ -2,7 +2,9 @@ # error "this header file must not be included directly" #endif -#define _PyObject_SIZE(typeobj) ( (typeobj)->tp_basicsize ) +static inline size_t _PyObject_SIZE(PyTypeObject *type) { + return _Py_STATIC_CAST(size_t, type->tp_basicsize); +} /* _PyObject_VAR_SIZE returns the number of bytes (as size_t) allocated for a vrbl-size object with nitems items, exclusive of gc overhead (if any). The @@ -18,10 +20,11 @@ # error "_PyObject_VAR_SIZE requires SIZEOF_VOID_P be a power of 2" #endif -#define _PyObject_VAR_SIZE(typeobj, nitems) \ - _Py_SIZE_ROUND_UP((typeobj)->tp_basicsize + \ - (nitems)*(typeobj)->tp_itemsize, \ - SIZEOF_VOID_P) +static inline size_t _PyObject_VAR_SIZE(PyTypeObject *type, Py_ssize_t nitems) { + size_t size = _Py_STATIC_CAST(size_t, type->tp_basicsize); + size += _Py_STATIC_CAST(size_t, nitems) * _Py_STATIC_CAST(size_t, type->tp_itemsize); + return _Py_SIZE_ROUND_UP(size, SIZEOF_VOID_P); +} /* This example code implements an object constructor with a custom @@ -87,3 +90,6 @@ PyAPI_FUNC(int) PyObject_IS_GC(PyObject *obj); PyAPI_FUNC(int) PyType_SUPPORTS_WEAKREFS(PyTypeObject *type); PyAPI_FUNC(PyObject **) PyObject_GET_WEAKREFS_LISTPTR(PyObject *op); + +PyAPI_FUNC(PyObject *) PyUnstable_Object_GC_NewWithExtraData(PyTypeObject *, + size_t); diff --git a/Include/cpython/odictobject.h b/Include/cpython/odictobject.h index e0704130..3822d554 100644 --- a/Include/cpython/odictobject.h +++ b/Include/cpython/odictobject.h @@ -18,8 +18,8 @@ PyAPI_DATA(PyTypeObject) PyODictKeys_Type; PyAPI_DATA(PyTypeObject) PyODictItems_Type; PyAPI_DATA(PyTypeObject) PyODictValues_Type; -#define PyODict_Check(op) PyObject_TypeCheck(op, &PyODict_Type) -#define PyODict_CheckExact(op) Py_IS_TYPE(op, &PyODict_Type) +#define PyODict_Check(op) PyObject_TypeCheck((op), &PyODict_Type) +#define PyODict_CheckExact(op) Py_IS_TYPE((op), &PyODict_Type) #define PyODict_SIZE(op) PyDict_GET_SIZE((op)) PyAPI_FUNC(PyObject *) PyODict_New(void); @@ -27,13 +27,13 @@ PyAPI_FUNC(int) PyODict_SetItem(PyObject *od, PyObject *key, PyObject *item); PyAPI_FUNC(int) PyODict_DelItem(PyObject *od, PyObject *key); /* wrappers around PyDict* functions */ -#define PyODict_GetItem(od, key) PyDict_GetItem(_PyObject_CAST(od), key) +#define PyODict_GetItem(od, key) PyDict_GetItem(_PyObject_CAST(od), (key)) #define PyODict_GetItemWithError(od, key) \ - PyDict_GetItemWithError(_PyObject_CAST(od), key) -#define PyODict_Contains(od, key) PyDict_Contains(_PyObject_CAST(od), key) + PyDict_GetItemWithError(_PyObject_CAST(od), (key)) +#define PyODict_Contains(od, key) PyDict_Contains(_PyObject_CAST(od), (key)) #define PyODict_Size(od) PyDict_Size(_PyObject_CAST(od)) #define PyODict_GetItemString(od, key) \ - PyDict_GetItemString(_PyObject_CAST(od), key) + PyDict_GetItemString(_PyObject_CAST(od), (key)) #endif diff --git a/Include/cpython/picklebufobject.h b/Include/cpython/picklebufobject.h index 0df2561d..f3cbaeef 100644 --- a/Include/cpython/picklebufobject.h +++ b/Include/cpython/picklebufobject.h @@ -12,7 +12,7 @@ extern "C" { PyAPI_DATA(PyTypeObject) PyPickleBuffer_Type; -#define PyPickleBuffer_Check(op) Py_IS_TYPE(op, &PyPickleBuffer_Type) +#define PyPickleBuffer_Check(op) Py_IS_TYPE((op), &PyPickleBuffer_Type) /* Create a PickleBuffer redirecting to the given buffer-enabled object */ PyAPI_FUNC(PyObject *) PyPickleBuffer_FromObject(PyObject *); diff --git a/Include/cpython/pydebug.h b/Include/cpython/pydebug.h index cab799f0..f6ebd99e 100644 --- a/Include/cpython/pydebug.h +++ b/Include/cpython/pydebug.h @@ -5,31 +5,31 @@ extern "C" { #endif -PyAPI_DATA(int) Py_DebugFlag; -PyAPI_DATA(int) Py_VerboseFlag; -PyAPI_DATA(int) Py_QuietFlag; -PyAPI_DATA(int) Py_InteractiveFlag; -PyAPI_DATA(int) Py_InspectFlag; -PyAPI_DATA(int) Py_OptimizeFlag; -PyAPI_DATA(int) Py_NoSiteFlag; -PyAPI_DATA(int) Py_BytesWarningFlag; -PyAPI_DATA(int) Py_FrozenFlag; -PyAPI_DATA(int) Py_IgnoreEnvironmentFlag; -PyAPI_DATA(int) Py_DontWriteBytecodeFlag; -PyAPI_DATA(int) Py_NoUserSiteDirectory; -PyAPI_DATA(int) Py_UnbufferedStdioFlag; -PyAPI_DATA(int) Py_HashRandomizationFlag; -PyAPI_DATA(int) Py_IsolatedFlag; +Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_DebugFlag; +Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_VerboseFlag; +Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_QuietFlag; +Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_InteractiveFlag; +Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_InspectFlag; +Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_OptimizeFlag; +Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_NoSiteFlag; +Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_BytesWarningFlag; +Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_FrozenFlag; +Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_IgnoreEnvironmentFlag; +Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_DontWriteBytecodeFlag; +Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_NoUserSiteDirectory; +Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_UnbufferedStdioFlag; +Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_HashRandomizationFlag; +Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_IsolatedFlag; #ifdef MS_WINDOWS -PyAPI_DATA(int) Py_LegacyWindowsFSEncodingFlag; -PyAPI_DATA(int) Py_LegacyWindowsStdioFlag; +Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_LegacyWindowsFSEncodingFlag; +Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_LegacyWindowsStdioFlag; #endif /* this is a wrapper around getenv() that pays attention to Py_IgnoreEnvironmentFlag. It should be used for getting variables like PYTHONPATH and PYTHONHOME from the environment */ -PyAPI_DATA(char*) Py_GETENV(const char *name); +PyAPI_FUNC(char*) Py_GETENV(const char *name); #ifdef __cplusplus } diff --git a/Include/cpython/pyerrors.h b/Include/cpython/pyerrors.h index 47d80e32..156665cb 100644 --- a/Include/cpython/pyerrors.h +++ b/Include/cpython/pyerrors.h @@ -37,6 +37,7 @@ typedef struct { PyObject *msg; PyObject *name; PyObject *path; + PyObject *name_from; } PyImportErrorObject; typedef struct { @@ -97,7 +98,8 @@ PyAPI_FUNC(void) _PyErr_GetExcInfo(PyThreadState *, PyObject **, PyObject **, Py /* Context manipulation (PEP 3134) */ -PyAPI_FUNC(void) _PyErr_ChainExceptions(PyObject *, PyObject *, PyObject *); +Py_DEPRECATED(3.12) PyAPI_FUNC(void) _PyErr_ChainExceptions(PyObject *, PyObject *, PyObject *); +PyAPI_FUNC(void) _PyErr_ChainExceptions1(PyObject *); /* Like PyErr_Format(), but saves current exception as __context__ and __cause__. @@ -110,23 +112,13 @@ PyAPI_FUNC(PyObject *) _PyErr_FormatFromCause( /* In exceptions.c */ -/* Helper that attempts to replace the current exception with one of the - * same type but with a prefix added to the exception text. The resulting - * exception description looks like: - * - * prefix (exc_type: original_exc_str) - * - * Only some exceptions can be safely replaced. If the function determines - * it isn't safe to perform the replacement, it will leave the original - * unmodified exception in place. - * - * Returns a borrowed reference to the new exception (if any), NULL if the - * existing exception was left in place. - */ -PyAPI_FUNC(PyObject *) _PyErr_TrySetFromCause( - const char *prefix_format, /* ASCII-encoded string */ - ... - ); +PyAPI_FUNC(int) _PyException_AddNote( + PyObject *exc, + PyObject *note); + +PyAPI_FUNC(PyObject*) PyUnstable_Exc_PrepReraiseStar( + PyObject *orig, + PyObject *excs); /* In signalmodule.c */ @@ -176,4 +168,11 @@ PyAPI_FUNC(void) _Py_NO_RETURN _Py_FatalErrorFormat( const char *format, ...); -#define Py_FatalError(message) _Py_FatalErrorFunc(__func__, message) +extern PyObject *_PyErr_SetImportErrorWithNameFrom( + PyObject *, + PyObject *, + PyObject *, + PyObject *); + + +#define Py_FatalError(message) _Py_FatalErrorFunc(__func__, (message)) diff --git a/Include/cpython/pyframe.h b/Include/cpython/pyframe.h index 1dc634cc..0e2afff9 100644 --- a/Include/cpython/pyframe.h +++ b/Include/cpython/pyframe.h @@ -14,4 +14,22 @@ PyAPI_FUNC(PyObject *) PyFrame_GetBuiltins(PyFrameObject *frame); PyAPI_FUNC(PyObject *) PyFrame_GetGenerator(PyFrameObject *frame); PyAPI_FUNC(int) PyFrame_GetLasti(PyFrameObject *frame); +PyAPI_FUNC(PyObject*) PyFrame_GetVar(PyFrameObject *frame, PyObject *name); +PyAPI_FUNC(PyObject*) PyFrame_GetVarString(PyFrameObject *frame, const char *name); +/* The following functions are for use by debuggers and other tools + * implementing custom frame evaluators with PEP 523. */ + +struct _PyInterpreterFrame; + +/* Returns the code object of the frame (strong reference). + * Does not raise an exception. */ +PyAPI_FUNC(PyObject *) PyUnstable_InterpreterFrame_GetCode(struct _PyInterpreterFrame *frame); + +/* Returns a byte ofsset into the last executed instruction. + * Does not raise an exception. */ +PyAPI_FUNC(int) PyUnstable_InterpreterFrame_GetLasti(struct _PyInterpreterFrame *frame); + +/* Returns the currently executing line number, or -1 if there is no line number. + * Does not raise an exception. */ +PyAPI_FUNC(int) PyUnstable_InterpreterFrame_GetLine(struct _PyInterpreterFrame *frame); diff --git a/Include/cpython/pylifecycle.h b/Include/cpython/pylifecycle.h index bb5b07ef..4daea33b 100644 --- a/Include/cpython/pylifecycle.h +++ b/Include/cpython/pylifecycle.h @@ -52,6 +52,7 @@ PyAPI_FUNC(const char *) _Py_gitidentifier(void); PyAPI_FUNC(const char *) _Py_gitversion(void); PyAPI_FUNC(int) _Py_IsFinalizing(void); +PyAPI_FUNC(int) _Py_IsInterpreterFinalizing(PyInterpreterState *interp); /* Random */ PyAPI_FUNC(int) _PyOS_URandom(void *buffer, Py_ssize_t size); @@ -62,4 +63,49 @@ PyAPI_FUNC(int) _Py_CoerceLegacyLocale(int warn); PyAPI_FUNC(int) _Py_LegacyLocaleDetected(int warn); PyAPI_FUNC(char *) _Py_SetLocaleFromEnv(int category); -PyAPI_FUNC(PyThreadState *) _Py_NewInterpreter(int isolated_subinterpreter); +/* --- PyInterpreterConfig ------------------------------------ */ + +#define PyInterpreterConfig_DEFAULT_GIL (0) +#define PyInterpreterConfig_SHARED_GIL (1) +#define PyInterpreterConfig_OWN_GIL (2) + +typedef struct { + // XXX "allow_object_sharing"? "own_objects"? + int use_main_obmalloc; + int allow_fork; + int allow_exec; + int allow_threads; + int allow_daemon_threads; + int check_multi_interp_extensions; + int gil; +} PyInterpreterConfig; + +#define _PyInterpreterConfig_INIT \ + { \ + .use_main_obmalloc = 0, \ + .allow_fork = 0, \ + .allow_exec = 0, \ + .allow_threads = 1, \ + .allow_daemon_threads = 0, \ + .check_multi_interp_extensions = 1, \ + .gil = PyInterpreterConfig_OWN_GIL, \ + } + +#define _PyInterpreterConfig_LEGACY_INIT \ + { \ + .use_main_obmalloc = 1, \ + .allow_fork = 1, \ + .allow_exec = 1, \ + .allow_threads = 1, \ + .allow_daemon_threads = 1, \ + .check_multi_interp_extensions = 0, \ + .gil = PyInterpreterConfig_SHARED_GIL, \ + } + +PyAPI_FUNC(PyStatus) Py_NewInterpreterFromConfig( + PyThreadState **tstate_p, + const PyInterpreterConfig *config); + +typedef void (*atexit_datacallbackfunc)(void *); +PyAPI_FUNC(int) _Py_AtExit( + PyInterpreterState *, atexit_datacallbackfunc, void *); diff --git a/Include/cpython/pystate.h b/Include/cpython/pystate.h index 2bd46067..628f2e09 100644 --- a/Include/cpython/pystate.h +++ b/Include/cpython/pystate.h @@ -3,11 +3,46 @@ #endif +/* +Runtime Feature Flags + +Each flag indicate whether or not a specific runtime feature +is available in a given context. For example, forking the process +might not be allowed in the current interpreter (i.e. os.fork() would fail). +*/ + +/* Set if the interpreter share obmalloc runtime state + with the main interpreter. */ +#define Py_RTFLAGS_USE_MAIN_OBMALLOC (1UL << 5) + +/* Set if import should check a module for subinterpreter support. */ +#define Py_RTFLAGS_MULTI_INTERP_EXTENSIONS (1UL << 8) + +/* Set if threads are allowed. */ +#define Py_RTFLAGS_THREADS (1UL << 10) + +/* Set if daemon threads are allowed. */ +#define Py_RTFLAGS_DAEMON_THREADS (1UL << 11) + +/* Set if os.fork() is allowed. */ +#define Py_RTFLAGS_FORK (1UL << 15) + +/* Set if os.exec*() is allowed. */ +#define Py_RTFLAGS_EXEC (1UL << 16) + + +PyAPI_FUNC(int) _PyInterpreterState_HasFeature(PyInterpreterState *interp, + unsigned long feature); + + +/* private interpreter helpers */ + PyAPI_FUNC(int) _PyInterpreterState_RequiresIDRef(PyInterpreterState *); PyAPI_FUNC(void) _PyInterpreterState_RequireIDRef(PyInterpreterState *, int); PyAPI_FUNC(PyObject *) _PyInterpreterState_GetMainModule(PyInterpreterState *); + /* State unique per thread */ /* Py_tracefunc return -1 when raising an exception, or 0 for success. */ @@ -27,12 +62,6 @@ typedef int (*Py_tracefunc)(PyObject *, PyFrameObject *, int, PyObject *); #define PyTrace_C_RETURN 6 #define PyTrace_OPCODE 7 - -typedef struct { - PyCodeObject *code; // The code object for the bounds. May be NULL. - PyCodeAddressRange bounds; // Only valid if code != NULL. -} PyTraceInfo; - // Internal structure: you should not use it directly, but use public functions // like PyThreadState_EnterTracing() and PyThreadState_LeaveTracing(). typedef struct _PyCFrame { @@ -46,7 +75,6 @@ typedef struct _PyCFrame { * discipline and make sure that instances of this struct cannot * accessed outside of their lifetime. */ - uint8_t use_tracing; // 0 or 255 (or'ed into opcode, hence 8-bit type) /* Pointer to the currently executing frame (it can be NULL) */ struct _PyInterpreterFrame *current_frame; struct _PyCFrame *previous; @@ -79,6 +107,11 @@ typedef struct _stack_chunk { PyObject * data[1]; /* Variable sized */ } _PyStackChunk; +struct _py_trashcan { + int delete_nesting; + PyObject *delete_later; +}; + struct _ts { /* See Python/ceval.c for comments explaining most fields */ @@ -86,24 +119,42 @@ struct _ts { PyThreadState *next; PyInterpreterState *interp; - /* Has been initialized to a safe state. + struct { + /* Has been initialized to a safe state. + + In order to be effective, this must be set to 0 during or right + after allocation. */ + unsigned int initialized:1; + + /* Has been bound to an OS thread. */ + unsigned int bound:1; + /* Has been unbound from its OS thread. */ + unsigned int unbound:1; + /* Has been bound aa current for the GILState API. */ + unsigned int bound_gilstate:1; + /* Currently in use (maybe holds the GIL). */ + unsigned int active:1; - In order to be effective, this must be set to 0 during or right - after allocation. */ - int _initialized; + /* various stages of finalization */ + unsigned int finalizing:1; + unsigned int cleared:1; + unsigned int finalized:1; - /* Was this thread state statically allocated? */ - int _static; + /* padding to align to 4 bytes */ + unsigned int :24; + } _status; - int recursion_remaining; - int recursion_limit; + int py_recursion_remaining; + int py_recursion_limit; + + int c_recursion_remaining; int recursion_headroom; /* Allow 50 more calls to handle any errors. */ /* 'tracing' keeps track of the execution depth when tracing/profiling. This is to prevent the actual trace/profile code from being recorded in the trace/profile. */ int tracing; - int tracing_what; /* The event currently being traced, if any. */ + int what_event; /* The event currently being monitored, if any. */ /* Pointer to current _PyCFrame in the C stack frame of the currently, * or most recently, executing _PyEval_EvalFrameDefault. */ @@ -115,9 +166,7 @@ struct _ts { PyObject *c_traceobj; /* The exception currently being raised */ - PyObject *curexc_type; - PyObject *curexc_value; - PyObject *curexc_traceback; + PyObject *current_exception; /* Pointer to the top of the exception stack for the exceptions * we may be currently handling. (See _PyErr_StackItem above.) @@ -137,8 +186,7 @@ struct _ts { */ unsigned long native_thread_id; - int trash_delete_nesting; - PyObject *trash_delete_later; + struct _py_trashcan trash; /* Called when a thread state is deleted normally, but not when it * is destroyed after fork(). @@ -177,8 +225,6 @@ struct _ts { /* Unique thread state id. */ uint64_t id; - PyTraceInfo trace_info; - _PyStackChunk *datastack_chunk; PyObject **datastack_top; PyObject **datastack_limit; @@ -202,12 +248,25 @@ struct _ts { _PyCFrame root_cframe; }; +/* WASI has limited call stack. Python's recursion limit depends on code + layout, optimization, and WASI runtime. Wasmtime can handle about 700 + recursions, sometimes less. 500 is a more conservative limit. */ +#ifndef C_RECURSION_LIMIT +# ifdef __wasi__ +# define C_RECURSION_LIMIT 500 +# else + // This value is duplicated in Lib/test/support/__init__.py +# define C_RECURSION_LIMIT 1500 +# endif +#endif /* other API */ // Alias for backward compatibility with Python 3.8 #define _PyInterpreterState_Get PyInterpreterState_Get +/* An alias for the internal _PyThreadState_New(), + kept for stable ABI compatibility. */ PyAPI_FUNC(PyThreadState *) _PyThreadState_Prealloc(PyInterpreterState *); /* Similar to PyThreadState_Get(), but don't issue a fatal error @@ -279,7 +338,10 @@ PyAPI_FUNC(const PyConfig*) _PyInterpreterState_GetConfig(PyInterpreterState *in for example. Python must be preinitialized to call this method. - The caller must hold the GIL. */ + The caller must hold the GIL. + + Once done with the configuration, PyConfig_Clear() must be called to clear + it. */ PyAPI_FUNC(int) _PyInterpreterState_GetConfigCopy( struct PyConfig *config); @@ -313,6 +375,9 @@ PyAPI_FUNC(const PyConfig*) _Py_GetConfig(void); // is necessary to pass safely between interpreters in the same process. typedef struct _xid _PyCrossInterpreterData; +typedef PyObject *(*xid_newobjectfunc)(_PyCrossInterpreterData *); +typedef void (*xid_freefunc)(void *); + struct _xid { // data is the cross-interpreter-safe derivation of a Python object // (see _PyObject_GetCrossInterpreterData). It will be NULL if the @@ -339,7 +404,7 @@ struct _xid { // interpreter given the data. The resulting object (a new // reference) will be equivalent to the original object. This field // is required. - PyObject *(*new_object)(_PyCrossInterpreterData *); + xid_newobjectfunc new_object; // free is called when the data is released. If it is NULL then // nothing will be done to free the data. For some types this is // okay (e.g. bytes) and for those types this field should be set @@ -349,18 +414,31 @@ struct _xid { // leak. In that case, at the very least this field should be set // to PyMem_RawFree (the default if not explicitly set to NULL). // The call will happen with the original interpreter activated. - void (*free)(void *); + xid_freefunc free; }; +PyAPI_FUNC(void) _PyCrossInterpreterData_Init( + _PyCrossInterpreterData *data, + PyInterpreterState *interp, void *shared, PyObject *obj, + xid_newobjectfunc new_object); +PyAPI_FUNC(int) _PyCrossInterpreterData_InitWithSize( + _PyCrossInterpreterData *, + PyInterpreterState *interp, const size_t, PyObject *, + xid_newobjectfunc); +PyAPI_FUNC(void) _PyCrossInterpreterData_Clear( + PyInterpreterState *, _PyCrossInterpreterData *); + PyAPI_FUNC(int) _PyObject_GetCrossInterpreterData(PyObject *, _PyCrossInterpreterData *); PyAPI_FUNC(PyObject *) _PyCrossInterpreterData_NewObject(_PyCrossInterpreterData *); -PyAPI_FUNC(void) _PyCrossInterpreterData_Release(_PyCrossInterpreterData *); +PyAPI_FUNC(int) _PyCrossInterpreterData_Release(_PyCrossInterpreterData *); PyAPI_FUNC(int) _PyObject_CheckCrossInterpreterData(PyObject *); /* cross-interpreter data registry */ -typedef int (*crossinterpdatafunc)(PyObject *, _PyCrossInterpreterData *); +typedef int (*crossinterpdatafunc)(PyThreadState *tstate, PyObject *, + _PyCrossInterpreterData *); PyAPI_FUNC(int) _PyCrossInterpreterData_RegisterClass(PyTypeObject *, crossinterpdatafunc); +PyAPI_FUNC(int) _PyCrossInterpreterData_UnregisterClass(PyTypeObject *); PyAPI_FUNC(crossinterpdatafunc) _PyCrossInterpreterData_Lookup(PyObject *); diff --git a/Include/cpython/pythonrun.h b/Include/cpython/pythonrun.h index 2e72d082..fb617655 100644 --- a/Include/cpython/pythonrun.h +++ b/Include/cpython/pythonrun.h @@ -66,8 +66,8 @@ PyAPI_FUNC(PyObject *) Py_CompileStringObject( PyCompilerFlags *flags, int optimize); -#define Py_CompileString(str, p, s) Py_CompileStringExFlags(str, p, s, NULL, -1) -#define Py_CompileStringFlags(str, p, s, f) Py_CompileStringExFlags(str, p, s, f, -1) +#define Py_CompileString(str, p, s) Py_CompileStringExFlags((str), (p), (s), NULL, -1) +#define Py_CompileStringFlags(str, p, s, f) Py_CompileStringExFlags((str), (p), (s), (f), -1) PyAPI_FUNC(const char *) _Py_SourceAsString( @@ -96,23 +96,23 @@ PyAPI_FUNC(PyObject *) PyRun_FileEx(FILE *fp, const char *p, int s, PyObject *g, PyAPI_FUNC(PyObject *) PyRun_FileFlags(FILE *fp, const char *p, int s, PyObject *g, PyObject *l, PyCompilerFlags *flags); /* Use macros for a bunch of old variants */ -#define PyRun_String(str, s, g, l) PyRun_StringFlags(str, s, g, l, NULL) -#define PyRun_AnyFile(fp, name) PyRun_AnyFileExFlags(fp, name, 0, NULL) +#define PyRun_String(str, s, g, l) PyRun_StringFlags((str), (s), (g), (l), NULL) +#define PyRun_AnyFile(fp, name) PyRun_AnyFileExFlags((fp), (name), 0, NULL) #define PyRun_AnyFileEx(fp, name, closeit) \ - PyRun_AnyFileExFlags(fp, name, closeit, NULL) + PyRun_AnyFileExFlags((fp), (name), (closeit), NULL) #define PyRun_AnyFileFlags(fp, name, flags) \ - PyRun_AnyFileExFlags(fp, name, 0, flags) -#define PyRun_SimpleString(s) PyRun_SimpleStringFlags(s, NULL) -#define PyRun_SimpleFile(f, p) PyRun_SimpleFileExFlags(f, p, 0, NULL) -#define PyRun_SimpleFileEx(f, p, c) PyRun_SimpleFileExFlags(f, p, c, NULL) -#define PyRun_InteractiveOne(f, p) PyRun_InteractiveOneFlags(f, p, NULL) -#define PyRun_InteractiveLoop(f, p) PyRun_InteractiveLoopFlags(f, p, NULL) + PyRun_AnyFileExFlags((fp), (name), 0, (flags)) +#define PyRun_SimpleString(s) PyRun_SimpleStringFlags((s), NULL) +#define PyRun_SimpleFile(f, p) PyRun_SimpleFileExFlags((f), (p), 0, NULL) +#define PyRun_SimpleFileEx(f, p, c) PyRun_SimpleFileExFlags((f), (p), (c), NULL) +#define PyRun_InteractiveOne(f, p) PyRun_InteractiveOneFlags((f), (p), NULL) +#define PyRun_InteractiveLoop(f, p) PyRun_InteractiveLoopFlags((f), (p), NULL) #define PyRun_File(fp, p, s, g, l) \ - PyRun_FileExFlags(fp, p, s, g, l, 0, NULL) + PyRun_FileExFlags((fp), (p), (s), (g), (l), 0, NULL) #define PyRun_FileEx(fp, p, s, g, l, c) \ - PyRun_FileExFlags(fp, p, s, g, l, c, NULL) + PyRun_FileExFlags((fp), (p), (s), (g), (l), (c), NULL) #define PyRun_FileFlags(fp, p, s, g, l, flags) \ - PyRun_FileExFlags(fp, p, s, g, l, 0, flags) + PyRun_FileExFlags((fp), (p), (s), (g), (l), 0, (flags)) /* Stuff with no proper home (yet) */ diff --git a/Include/cpython/pytime.h b/Include/cpython/pytime.h index 23d4f16a..16d88d19 100644 --- a/Include/cpython/pytime.h +++ b/Include/cpython/pytime.h @@ -53,6 +53,10 @@ functions and constants extern "C" { #endif +#ifdef __clang__ +struct timeval; +#endif + /* _PyTime_t: Python timestamp with subsecond precision. It can be used to store a duration, and so indirectly a date (related to another date, like UNIX epoch). */ @@ -130,6 +134,10 @@ PyAPI_FUNC(_PyTime_t) _PyTime_FromSeconds(int seconds); /* Create a timestamp from a number of nanoseconds. */ PyAPI_FUNC(_PyTime_t) _PyTime_FromNanoseconds(_PyTime_t ns); +/* Create a timestamp from a number of microseconds. + * Clamp to [_PyTime_MIN; _PyTime_MAX] on overflow. */ +PyAPI_FUNC(_PyTime_t) _PyTime_FromMicrosecondsClamp(_PyTime_t us); + /* Create a timestamp from nanoseconds (Python int). */ PyAPI_FUNC(int) _PyTime_FromNanosecondsObject(_PyTime_t *t, PyObject *obj); diff --git a/Include/cpython/setobject.h b/Include/cpython/setobject.h index b4443a67..20fd63ea 100644 --- a/Include/cpython/setobject.h +++ b/Include/cpython/setobject.h @@ -58,8 +58,13 @@ typedef struct { PyObject *weakreflist; /* List of weak references */ } PySetObject; -#define PySet_GET_SIZE(so) \ - (assert(PyAnySet_Check(so)), (((PySetObject *)(so))->used)) +#define _PySet_CAST(so) \ + (assert(PyAnySet_Check(so)), _Py_CAST(PySetObject*, so)) + +static inline Py_ssize_t PySet_GET_SIZE(PyObject *so) { + return _PySet_CAST(so)->used; +} +#define PySet_GET_SIZE(so) PySet_GET_SIZE(_PyObject_CAST(so)) PyAPI_DATA(PyObject *) _PySet_Dummy; diff --git a/Include/cpython/tupleobject.h b/Include/cpython/tupleobject.h index 3d9c1aff..f6a1f076 100644 --- a/Include/cpython/tupleobject.h +++ b/Include/cpython/tupleobject.h @@ -23,11 +23,9 @@ static inline Py_ssize_t PyTuple_GET_SIZE(PyObject *op) { PyTupleObject *tuple = _PyTuple_CAST(op); return Py_SIZE(tuple); } -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define PyTuple_GET_SIZE(op) PyTuple_GET_SIZE(_PyObject_CAST(op)) -#endif +#define PyTuple_GET_SIZE(op) PyTuple_GET_SIZE(_PyObject_CAST(op)) -#define PyTuple_GET_ITEM(op, index) (_PyTuple_CAST(op)->ob_item[index]) +#define PyTuple_GET_ITEM(op, index) (_PyTuple_CAST(op)->ob_item[(index)]) /* Function *only* to be used to fill in brand new tuples */ static inline void @@ -35,9 +33,7 @@ PyTuple_SET_ITEM(PyObject *op, Py_ssize_t index, PyObject *value) { PyTupleObject *tuple = _PyTuple_CAST(op); tuple->ob_item[index] = value; } -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 #define PyTuple_SET_ITEM(op, index, value) \ - PyTuple_SET_ITEM(_PyObject_CAST(op), index, _PyObject_CAST(value)) -#endif + PyTuple_SET_ITEM(_PyObject_CAST(op), (index), _PyObject_CAST(value)) PyAPI_FUNC(void) _PyTuple_DebugMallocStats(FILE *out); diff --git a/Include/cpython/unicodeobject.h b/Include/cpython/unicodeobject.h index 84307d18..3394726d 100644 --- a/Include/cpython/unicodeobject.h +++ b/Include/cpython/unicodeobject.h @@ -11,63 +11,43 @@ /* --- Internal Unicode Operations ---------------------------------------- */ -#ifndef USE_UNICODE_WCHAR_CACHE -# define USE_UNICODE_WCHAR_CACHE 1 -#endif /* USE_UNICODE_WCHAR_CACHE */ - -/* Since splitting on whitespace is an important use case, and - whitespace in most situations is solely ASCII whitespace, we - optimize for the common case by using a quick look-up table - _Py_ascii_whitespace (see below) with an inlined check. - - */ -#define Py_UNICODE_ISSPACE(ch) \ - ((Py_UCS4)(ch) < 128U ? _Py_ascii_whitespace[(ch)] : _PyUnicode_IsWhitespace(ch)) - -#define Py_UNICODE_ISLOWER(ch) _PyUnicode_IsLowercase(ch) -#define Py_UNICODE_ISUPPER(ch) _PyUnicode_IsUppercase(ch) -#define Py_UNICODE_ISTITLE(ch) _PyUnicode_IsTitlecase(ch) -#define Py_UNICODE_ISLINEBREAK(ch) _PyUnicode_IsLinebreak(ch) - -#define Py_UNICODE_TOLOWER(ch) _PyUnicode_ToLowercase(ch) -#define Py_UNICODE_TOUPPER(ch) _PyUnicode_ToUppercase(ch) -#define Py_UNICODE_TOTITLE(ch) _PyUnicode_ToTitlecase(ch) - -#define Py_UNICODE_ISDECIMAL(ch) _PyUnicode_IsDecimalDigit(ch) -#define Py_UNICODE_ISDIGIT(ch) _PyUnicode_IsDigit(ch) -#define Py_UNICODE_ISNUMERIC(ch) _PyUnicode_IsNumeric(ch) -#define Py_UNICODE_ISPRINTABLE(ch) _PyUnicode_IsPrintable(ch) +// Static inline functions to work with surrogates +static inline int Py_UNICODE_IS_SURROGATE(Py_UCS4 ch) { + return (0xD800 <= ch && ch <= 0xDFFF); +} +static inline int Py_UNICODE_IS_HIGH_SURROGATE(Py_UCS4 ch) { + return (0xD800 <= ch && ch <= 0xDBFF); +} +static inline int Py_UNICODE_IS_LOW_SURROGATE(Py_UCS4 ch) { + return (0xDC00 <= ch && ch <= 0xDFFF); +} -#define Py_UNICODE_TODECIMAL(ch) _PyUnicode_ToDecimalDigit(ch) -#define Py_UNICODE_TODIGIT(ch) _PyUnicode_ToDigit(ch) -#define Py_UNICODE_TONUMERIC(ch) _PyUnicode_ToNumeric(ch) +// Join two surrogate characters and return a single Py_UCS4 value. +static inline Py_UCS4 Py_UNICODE_JOIN_SURROGATES(Py_UCS4 high, Py_UCS4 low) { + assert(Py_UNICODE_IS_HIGH_SURROGATE(high)); + assert(Py_UNICODE_IS_LOW_SURROGATE(low)); + return 0x10000 + (((high & 0x03FF) << 10) | (low & 0x03FF)); +} -#define Py_UNICODE_ISALPHA(ch) _PyUnicode_IsAlpha(ch) +// High surrogate = top 10 bits added to 0xD800. +// The character must be in the range [U+10000; U+10ffff]. +static inline Py_UCS4 Py_UNICODE_HIGH_SURROGATE(Py_UCS4 ch) { + assert(0x10000 <= ch && ch <= 0x10ffff); + return (0xD800 - (0x10000 >> 10) + (ch >> 10)); +} -#define Py_UNICODE_ISALNUM(ch) \ - (Py_UNICODE_ISALPHA(ch) || \ - Py_UNICODE_ISDECIMAL(ch) || \ - Py_UNICODE_ISDIGIT(ch) || \ - Py_UNICODE_ISNUMERIC(ch)) - -/* macros to work with surrogates */ -#define Py_UNICODE_IS_SURROGATE(ch) (0xD800 <= (ch) && (ch) <= 0xDFFF) -#define Py_UNICODE_IS_HIGH_SURROGATE(ch) (0xD800 <= (ch) && (ch) <= 0xDBFF) -#define Py_UNICODE_IS_LOW_SURROGATE(ch) (0xDC00 <= (ch) && (ch) <= 0xDFFF) -/* Join two surrogate characters and return a single Py_UCS4 value. */ -#define Py_UNICODE_JOIN_SURROGATES(high, low) \ - (((((Py_UCS4)(high) & 0x03FF) << 10) | \ - ((Py_UCS4)(low) & 0x03FF)) + 0x10000) -/* high surrogate = top 10 bits added to D800 */ -#define Py_UNICODE_HIGH_SURROGATE(ch) (0xD800 - (0x10000 >> 10) + ((ch) >> 10)) -/* low surrogate = bottom 10 bits added to DC00 */ -#define Py_UNICODE_LOW_SURROGATE(ch) (0xDC00 + ((ch) & 0x3FF)) +// Low surrogate = bottom 10 bits added to 0xDC00. +// The character must be in the range [U+10000; U+10ffff]. +static inline Py_UCS4 Py_UNICODE_LOW_SURROGATE(Py_UCS4 ch) { + assert(0x10000 <= ch && ch <= 0x10ffff); + return (0xDC00 + (ch & 0x3FF)); +} /* --- Unicode Type ------------------------------------------------------- */ /* ASCII-only strings created through PyUnicode_New use the PyASCIIObject structure. state.ascii and state.compact are set, and the data - immediately follow the structure. utf8_length and wstr_length can be found + immediately follow the structure. utf8_length can be found in the length field; the utf8 pointer is equal to the data pointer. */ typedef struct { /* There are 4 forms of Unicode strings: @@ -79,8 +59,7 @@ typedef struct { * kind = PyUnicode_1BYTE_KIND * compact = 1 * ascii = 1 - * ready = 1 - * (length is the length of the utf8 and wstr strings) + * (length is the length of the utf8) * (data starts just after the structure) * (since ASCII is decoded from UTF-8, the utf8 string are the data) @@ -91,55 +70,27 @@ typedef struct { * kind = PyUnicode_1BYTE_KIND, PyUnicode_2BYTE_KIND or PyUnicode_4BYTE_KIND * compact = 1 - * ready = 1 * ascii = 0 * utf8 is not shared with data * utf8_length = 0 if utf8 is NULL - * wstr is shared with data and wstr_length=length - if kind=PyUnicode_2BYTE_KIND and sizeof(wchar_t)=2 - or if kind=PyUnicode_4BYTE_KIND and sizeof(wchar_t)=4 - * wstr_length = 0 if wstr is NULL * (data starts just after the structure) - - legacy string, not ready: - - * structure = PyUnicodeObject - * test: kind == PyUnicode_WCHAR_KIND - * length = 0 (use wstr_length) - * hash = -1 - * kind = PyUnicode_WCHAR_KIND - * compact = 0 - * ascii = 0 - * ready = 0 - * interned = SSTATE_NOT_INTERNED - * wstr is not NULL - * data.any is NULL - * utf8 is NULL - * utf8_length = 0 - - - legacy string, ready: + - legacy string: * structure = PyUnicodeObject structure - * test: !PyUnicode_IS_COMPACT(op) && kind != PyUnicode_WCHAR_KIND + * test: !PyUnicode_IS_COMPACT(op) * kind = PyUnicode_1BYTE_KIND, PyUnicode_2BYTE_KIND or PyUnicode_4BYTE_KIND * compact = 0 - * ready = 1 * data.any is not NULL * utf8 is shared and utf8_length = length with data.any if ascii = 1 * utf8_length = 0 if utf8 is NULL - * wstr is shared with data.any and wstr_length = length - if kind=PyUnicode_2BYTE_KIND and sizeof(wchar_t)=2 - or if kind=PyUnicode_4BYTE_KIND and sizeof(wchar_4)=4 - * wstr_length = 0 if wstr is NULL Compact strings use only one memory block (structure + characters), whereas legacy strings use one block for the structure and one block for characters. - Legacy strings are created by PyUnicode_FromUnicode() and - PyUnicode_FromStringAndSize(NULL, size) functions. They become ready - when PyUnicode_READY() is called. + Legacy strings are created by subclasses of Unicode. See also _PyUnicode_CheckConsistency(). */ @@ -147,22 +98,18 @@ typedef struct { Py_ssize_t length; /* Number of code points in the string */ Py_hash_t hash; /* Hash value; -1 if not set */ struct { - /* - SSTATE_NOT_INTERNED (0) - SSTATE_INTERNED_MORTAL (1) - SSTATE_INTERNED_IMMORTAL (2) - - If interned != SSTATE_NOT_INTERNED, the two references from the + /* If interned is non-zero, the two references from the dictionary to this object are *not* counted in ob_refcnt. - */ + The possible values here are: + 0: Not Interned + 1: Interned + 2: Interned and Immortal + 3: Interned, Immortal, and Static + This categorization allows the runtime to determine the right + cleanup mechanism at runtime shutdown. */ unsigned int interned:2; /* Character size: - - PyUnicode_WCHAR_KIND (0): - - * character type = wchar_t (16 or 32 bits, depending on the - platform) - - PyUnicode_1BYTE_KIND (1): * character type = Py_UCS1 (8 bits, unsigned) @@ -193,16 +140,10 @@ typedef struct { and the kind is PyUnicode_1BYTE_KIND. If ascii is set and compact is set, use the PyASCIIObject structure. */ unsigned int ascii:1; - /* The ready flag indicates whether the object layout is initialized - completely. This means that this is either a compact object, or - the data pointer is filled out. The bit is redundant, and helps - to minimize the test in PyUnicode_IS_READY(). */ - unsigned int ready:1; /* Padding to ensure that PyUnicode_DATA() is always aligned to 4 bytes (see issue #19537 on m68k). */ - unsigned int :24; + unsigned int :25; } state; - wchar_t *wstr; /* wchar_t representation (null-terminated) */ } PyASCIIObject; /* Non-ASCII strings allocated through PyUnicode_New use the @@ -213,13 +154,9 @@ typedef struct { Py_ssize_t utf8_length; /* Number of bytes in utf8, excluding the * terminating \0. */ char *utf8; /* UTF-8 representation (null-terminated) */ - Py_ssize_t wstr_length; /* Number of code points in wstr, possible - * surrogates count as two code points. */ } PyCompactUnicodeObject; -/* Strings allocated through PyUnicode_FromUnicode(NULL, len) use the - PyUnicodeObject structure. The actual string data is initially in the wstr - block, and copied into the data block using _PyUnicode_Ready. */ +/* Object format for Unicode subclasses. */ typedef struct { PyCompactUnicodeObject _base; union { @@ -254,68 +191,56 @@ PyAPI_FUNC(int) _PyUnicode_CheckConsistency( #define SSTATE_NOT_INTERNED 0 #define SSTATE_INTERNED_MORTAL 1 #define SSTATE_INTERNED_IMMORTAL 2 +#define SSTATE_INTERNED_IMMORTAL_STATIC 3 /* Use only if you know it's a string */ static inline unsigned int PyUnicode_CHECK_INTERNED(PyObject *op) { return _PyASCIIObject_CAST(op)->state.interned; } -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define PyUnicode_CHECK_INTERNED(op) PyUnicode_CHECK_INTERNED(_PyObject_CAST(op)) -#endif +#define PyUnicode_CHECK_INTERNED(op) PyUnicode_CHECK_INTERNED(_PyObject_CAST(op)) -/* Fast check to determine whether an object is ready. Equivalent to: - PyUnicode_IS_COMPACT(op) || _PyUnicodeObject_CAST(op)->data.any */ -static inline unsigned int PyUnicode_IS_READY(PyObject *op) { - return _PyASCIIObject_CAST(op)->state.ready; +/* For backward compatibility */ +static inline unsigned int PyUnicode_IS_READY(PyObject* Py_UNUSED(op)) { + return 1; } -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define PyUnicode_IS_READY(op) PyUnicode_IS_READY(_PyObject_CAST(op)) -#endif +#define PyUnicode_IS_READY(op) PyUnicode_IS_READY(_PyObject_CAST(op)) /* Return true if the string contains only ASCII characters, or 0 if not. The string may be compact (PyUnicode_IS_COMPACT_ASCII) or not, but must be ready. */ static inline unsigned int PyUnicode_IS_ASCII(PyObject *op) { - assert(PyUnicode_IS_READY(op)); return _PyASCIIObject_CAST(op)->state.ascii; } -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define PyUnicode_IS_ASCII(op) PyUnicode_IS_ASCII(_PyObject_CAST(op)) -#endif +#define PyUnicode_IS_ASCII(op) PyUnicode_IS_ASCII(_PyObject_CAST(op)) /* Return true if the string is compact or 0 if not. No type checks or Ready calls are performed. */ static inline unsigned int PyUnicode_IS_COMPACT(PyObject *op) { return _PyASCIIObject_CAST(op)->state.compact; } -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define PyUnicode_IS_COMPACT(op) PyUnicode_IS_COMPACT(_PyObject_CAST(op)) -#endif +#define PyUnicode_IS_COMPACT(op) PyUnicode_IS_COMPACT(_PyObject_CAST(op)) /* Return true if the string is a compact ASCII string (use PyASCIIObject structure), or 0 if not. No type checks or Ready calls are performed. */ static inline int PyUnicode_IS_COMPACT_ASCII(PyObject *op) { return (_PyASCIIObject_CAST(op)->state.ascii && PyUnicode_IS_COMPACT(op)); } -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define PyUnicode_IS_COMPACT_ASCII(op) PyUnicode_IS_COMPACT_ASCII(_PyObject_CAST(op)) -#endif +#define PyUnicode_IS_COMPACT_ASCII(op) PyUnicode_IS_COMPACT_ASCII(_PyObject_CAST(op)) enum PyUnicode_Kind { -/* String contains only wstr byte characters. This is only possible - when the string was created with a legacy API and _PyUnicode_Ready() - has not been called yet. */ - PyUnicode_WCHAR_KIND = 0, /* Return values of the PyUnicode_KIND() function: */ PyUnicode_1BYTE_KIND = 1, PyUnicode_2BYTE_KIND = 2, PyUnicode_4BYTE_KIND = 4 }; -/* Return one of the PyUnicode_*_KIND values defined above. */ -#define PyUnicode_KIND(op) \ - (assert(PyUnicode_IS_READY(op)), \ - _PyASCIIObject_CAST(op)->state.kind) +// PyUnicode_KIND(): Return one of the PyUnicode_*_KIND values defined above. +// +// gh-89653: Converting this macro to a static inline function would introduce +// new compiler warnings on "kind < PyUnicode_KIND(str)" (compare signed and +// unsigned numbers) where kind type is an int or on +// "unsigned int kind = PyUnicode_KIND(str)" (cast signed to unsigned). +#define PyUnicode_KIND(op) _Py_RVALUE(_PyASCIIObject_CAST(op)->state.kind) /* Return a void pointer to the raw unicode buffer. */ static inline void* _PyUnicode_COMPACT_DATA(PyObject *op) { @@ -339,9 +264,7 @@ static inline void* PyUnicode_DATA(PyObject *op) { } return _PyUnicode_NONCOMPACT_DATA(op); } -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define PyUnicode_DATA(op) PyUnicode_DATA(_PyObject_CAST(op)) -#endif +#define PyUnicode_DATA(op) PyUnicode_DATA(_PyObject_CAST(op)) /* Return pointers to the canonical representation cast to unsigned char, Py_UCS2, or Py_UCS4 for direct character access. @@ -352,16 +275,11 @@ static inline void* PyUnicode_DATA(PyObject *op) { #define PyUnicode_2BYTE_DATA(op) _Py_STATIC_CAST(Py_UCS2*, PyUnicode_DATA(op)) #define PyUnicode_4BYTE_DATA(op) _Py_STATIC_CAST(Py_UCS4*, PyUnicode_DATA(op)) -/* Returns the length of the unicode string. The caller has to make sure that - the string has it's canonical representation set before calling - this function. Call PyUnicode_(FAST_)Ready to ensure that. */ +/* Returns the length of the unicode string. */ static inline Py_ssize_t PyUnicode_GET_LENGTH(PyObject *op) { - assert(PyUnicode_IS_READY(op)); return _PyASCIIObject_CAST(op)->length; } -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define PyUnicode_GET_LENGTH(op) PyUnicode_GET_LENGTH(_PyObject_CAST(op)) -#endif +#define PyUnicode_GET_LENGTH(op) PyUnicode_GET_LENGTH(_PyObject_CAST(op)) /* Write into the canonical representation, this function does not do any sanity checks and is intended for usage in loops. The caller should cache the @@ -371,6 +289,7 @@ static inline Py_ssize_t PyUnicode_GET_LENGTH(PyObject *op) { static inline void PyUnicode_WRITE(int kind, void *data, Py_ssize_t index, Py_UCS4 value) { + assert(index >= 0); if (kind == PyUnicode_1BYTE_KIND) { assert(value <= 0xffU); _Py_STATIC_CAST(Py_UCS1*, data)[index] = _Py_STATIC_CAST(Py_UCS1, value); @@ -385,17 +304,16 @@ static inline void PyUnicode_WRITE(int kind, void *data, _Py_STATIC_CAST(Py_UCS4*, data)[index] = value; } } -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 #define PyUnicode_WRITE(kind, data, index, value) \ PyUnicode_WRITE(_Py_STATIC_CAST(int, kind), _Py_CAST(void*, data), \ (index), _Py_STATIC_CAST(Py_UCS4, value)) -#endif /* Read a code point from the string's canonical representation. No checks or ready calls are performed. */ static inline Py_UCS4 PyUnicode_READ(int kind, const void *data, Py_ssize_t index) { + assert(index >= 0); if (kind == PyUnicode_1BYTE_KIND) { return _Py_STATIC_CAST(const Py_UCS1*, data)[index]; } @@ -405,12 +323,10 @@ static inline Py_UCS4 PyUnicode_READ(int kind, assert(kind == PyUnicode_4BYTE_KIND); return _Py_STATIC_CAST(const Py_UCS4*, data)[index]; } -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 #define PyUnicode_READ(kind, data, index) \ PyUnicode_READ(_Py_STATIC_CAST(int, kind), \ _Py_STATIC_CAST(const void*, data), \ (index)) -#endif /* PyUnicode_READ_CHAR() is less efficient than PyUnicode_READ() because it calls PyUnicode_KIND() and might call it twice. For single reads, use @@ -419,7 +335,11 @@ static inline Py_UCS4 PyUnicode_READ(int kind, static inline Py_UCS4 PyUnicode_READ_CHAR(PyObject *unicode, Py_ssize_t index) { int kind; - assert(PyUnicode_IS_READY(unicode)); + + assert(index >= 0); + // Tolerate reading the NUL character at str[len(str)] + assert(index <= PyUnicode_GET_LENGTH(unicode)); + kind = PyUnicode_KIND(unicode); if (kind == PyUnicode_1BYTE_KIND) { return PyUnicode_1BYTE_DATA(unicode)[index]; @@ -430,10 +350,8 @@ static inline Py_UCS4 PyUnicode_READ_CHAR(PyObject *unicode, Py_ssize_t index) assert(kind == PyUnicode_4BYTE_KIND); return PyUnicode_4BYTE_DATA(unicode)[index]; } -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define PyUnicode_READ_CHAR(unicode, index) \ - PyUnicode_READ_CHAR(_PyObject_CAST(unicode), (index)) -#endif +#define PyUnicode_READ_CHAR(unicode, index) \ + PyUnicode_READ_CHAR(_PyObject_CAST(unicode), (index)) /* Return a maximum character value which is suitable for creating another string based on op. This is always an approximation but more efficient @@ -442,7 +360,6 @@ static inline Py_UCS4 PyUnicode_MAX_CHAR_VALUE(PyObject *op) { int kind; - assert(PyUnicode_IS_READY(op)); if (PyUnicode_IS_ASCII(op)) { return 0x7fU; } @@ -457,10 +374,8 @@ static inline Py_UCS4 PyUnicode_MAX_CHAR_VALUE(PyObject *op) assert(kind == PyUnicode_4BYTE_KIND); return 0x10ffffU; } -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define PyUnicode_MAX_CHAR_VALUE(op) \ - PyUnicode_MAX_CHAR_VALUE(_PyObject_CAST(op)) -#endif +#define PyUnicode_MAX_CHAR_VALUE(op) \ + PyUnicode_MAX_CHAR_VALUE(_PyObject_CAST(op)) /* === Public API ========================================================= */ @@ -474,31 +389,12 @@ PyAPI_FUNC(PyObject*) PyUnicode_New( Py_UCS4 maxchar /* maximum code point value in the string */ ); -/* Initializes the canonical string representation from the deprecated - wstr/Py_UNICODE representation. This function is used to convert Unicode - objects which were created using the old API to the new flexible format - introduced with PEP 393. - - Don't call this function directly, use the public PyUnicode_READY() function - instead. */ -PyAPI_FUNC(int) _PyUnicode_Ready( - PyObject *unicode /* Unicode object */ - ); - -/* PyUnicode_READY() does less work than _PyUnicode_Ready() in the best - case. If the canonical representation is not yet set, it will still call - _PyUnicode_Ready(). - Returns 0 on success and -1 on errors. */ -static inline int PyUnicode_READY(PyObject *op) +/* For backward compatibility */ +static inline int PyUnicode_READY(PyObject* Py_UNUSED(op)) { - if (PyUnicode_IS_READY(op)) { - return 0; - } - return _PyUnicode_Ready(op); + return 0; } -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define PyUnicode_READY(op) PyUnicode_READY(_PyObject_CAST(op)) -#endif +#define PyUnicode_READY(op) PyUnicode_READY(_PyObject_CAST(op)) /* Get a copy of a Unicode string. */ PyAPI_FUNC(PyObject*) _PyUnicode_Copy( @@ -586,139 +482,12 @@ PyAPI_FUNC(Py_UCS4) _PyUnicode_FindMaxChar ( Py_ssize_t start, Py_ssize_t end); -/* --- Legacy deprecated API ---------------------------------------------- */ - -/* Create a Unicode Object from the Py_UNICODE buffer u of the given - size. - - u may be NULL which causes the contents to be undefined. It is the - user's responsibility to fill in the needed data afterwards. Note - that modifying the Unicode object contents after construction is - only allowed if u was set to NULL. - - The buffer is copied into the new object. */ -Py_DEPRECATED(3.3) PyAPI_FUNC(PyObject*) PyUnicode_FromUnicode( - const Py_UNICODE *u, /* Unicode buffer */ - Py_ssize_t size /* size of buffer */ - ); - -/* Return a read-only pointer to the Unicode object's internal - Py_UNICODE buffer. - If the wchar_t/Py_UNICODE representation is not yet available, this - function will calculate it. */ -Py_DEPRECATED(3.3) PyAPI_FUNC(Py_UNICODE *) PyUnicode_AsUnicode( - PyObject *unicode /* Unicode object */ - ); - -/* Similar to PyUnicode_AsUnicode(), but raises a ValueError if the string - contains null characters. */ -PyAPI_FUNC(const Py_UNICODE *) _PyUnicode_AsUnicode( - PyObject *unicode /* Unicode object */ - ); - -/* Return a read-only pointer to the Unicode object's internal - Py_UNICODE buffer and save the length at size. - If the wchar_t/Py_UNICODE representation is not yet available, this - function will calculate it. */ - -Py_DEPRECATED(3.3) PyAPI_FUNC(Py_UNICODE *) PyUnicode_AsUnicodeAndSize( - PyObject *unicode, /* Unicode object */ - Py_ssize_t *size /* location where to save the length */ - ); - - -/* Fast access macros */ - -Py_DEPRECATED(3.3) -static inline Py_ssize_t PyUnicode_WSTR_LENGTH(PyObject *op) -{ - if (PyUnicode_IS_COMPACT_ASCII(op)) { - return _PyASCIIObject_CAST(op)->length; - } - else { - return _PyCompactUnicodeObject_CAST(op)->wstr_length; - } -} -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define PyUnicode_WSTR_LENGTH(op) PyUnicode_WSTR_LENGTH(_PyObject_CAST(op)) -#endif - -/* Returns the deprecated Py_UNICODE representation's size in code units - (this includes surrogate pairs as 2 units). - If the Py_UNICODE representation is not available, it will be computed - on request. Use PyUnicode_GET_LENGTH() for the length in code points. */ - -Py_DEPRECATED(3.3) -static inline Py_ssize_t PyUnicode_GET_SIZE(PyObject *op) -{ - _Py_COMP_DIAG_PUSH - _Py_COMP_DIAG_IGNORE_DEPR_DECLS - if (_PyASCIIObject_CAST(op)->wstr == _Py_NULL) { - (void)PyUnicode_AsUnicode(op); - assert(_PyASCIIObject_CAST(op)->wstr != _Py_NULL); - } - return PyUnicode_WSTR_LENGTH(op); - _Py_COMP_DIAG_POP -} -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define PyUnicode_GET_SIZE(op) PyUnicode_GET_SIZE(_PyObject_CAST(op)) -#endif - -Py_DEPRECATED(3.3) -static inline Py_ssize_t PyUnicode_GET_DATA_SIZE(PyObject *op) -{ - _Py_COMP_DIAG_PUSH - _Py_COMP_DIAG_IGNORE_DEPR_DECLS - return PyUnicode_GET_SIZE(op) * Py_UNICODE_SIZE; - _Py_COMP_DIAG_POP -} -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define PyUnicode_GET_DATA_SIZE(op) PyUnicode_GET_DATA_SIZE(_PyObject_CAST(op)) -#endif - -/* Alias for PyUnicode_AsUnicode(). This will create a wchar_t/Py_UNICODE - representation on demand. Using this macro is very inefficient now, - try to port your code to use the new PyUnicode_*BYTE_DATA() macros or - use PyUnicode_WRITE() and PyUnicode_READ(). */ - -Py_DEPRECATED(3.3) -static inline Py_UNICODE* PyUnicode_AS_UNICODE(PyObject *op) -{ - wchar_t *wstr = _PyASCIIObject_CAST(op)->wstr; - if (wstr != _Py_NULL) { - return wstr; - } - - _Py_COMP_DIAG_PUSH - _Py_COMP_DIAG_IGNORE_DEPR_DECLS - return PyUnicode_AsUnicode(op); - _Py_COMP_DIAG_POP -} -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define PyUnicode_AS_UNICODE(op) PyUnicode_AS_UNICODE(_PyObject_CAST(op)) -#endif - -Py_DEPRECATED(3.3) -static inline const char* PyUnicode_AS_DATA(PyObject *op) -{ - _Py_COMP_DIAG_PUSH - _Py_COMP_DIAG_IGNORE_DEPR_DECLS - Py_UNICODE *data = PyUnicode_AS_UNICODE(op); - // In C++, casting directly PyUnicode* to const char* is not valid - return _Py_STATIC_CAST(const char*, _Py_STATIC_CAST(const void*, data)); - _Py_COMP_DIAG_POP -} -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define PyUnicode_AS_DATA(op) PyUnicode_AS_DATA(_PyObject_CAST(op)) -#endif - - /* --- _PyUnicodeWriter API ----------------------------------------------- */ typedef struct { PyObject *buffer; void *data; - enum PyUnicode_Kind kind; + int kind; Py_UCS4 maxchar; Py_ssize_t size; Py_ssize_t pos; @@ -769,8 +538,7 @@ _PyUnicodeWriter_PrepareInternal(_PyUnicodeWriter *writer, Return 0 on success, raise an exception and return -1 on error. */ #define _PyUnicodeWriter_PrepareKind(WRITER, KIND) \ - (assert((KIND) != PyUnicode_WCHAR_KIND), \ - (KIND) <= (WRITER)->kind \ + ((KIND) <= (WRITER)->kind \ ? 0 \ : _PyUnicodeWriter_PrepareKindInternal((WRITER), (KIND))) @@ -778,7 +546,7 @@ _PyUnicodeWriter_PrepareInternal(_PyUnicodeWriter *writer, macro instead. */ PyAPI_FUNC(int) _PyUnicodeWriter_PrepareKindInternal(_PyUnicodeWriter *writer, - enum PyUnicode_Kind kind); + int kind); /* Append a Unicode character. Return 0 on success, raise an exception and return -1 on error. */ @@ -1024,10 +792,6 @@ PyAPI_FUNC(Py_ssize_t) _PyUnicode_InsertThousandsGrouping( /* === Characters Type APIs =============================================== */ -/* Helper array used by Py_UNICODE_ISSPACE(). */ - -PyAPI_DATA(const unsigned char) _Py_ascii_whitespace[]; - /* These should not be used directly. Use the Py_UNICODE_IS* and Py_UNICODE_TO* macros instead. @@ -1135,6 +899,50 @@ PyAPI_FUNC(int) _PyUnicode_IsAlpha( Py_UCS4 ch /* Unicode character */ ); +// Helper array used by Py_UNICODE_ISSPACE(). +PyAPI_DATA(const unsigned char) _Py_ascii_whitespace[]; + +// Since splitting on whitespace is an important use case, and +// whitespace in most situations is solely ASCII whitespace, we +// optimize for the common case by using a quick look-up table +// _Py_ascii_whitespace (see below) with an inlined check. +static inline int Py_UNICODE_ISSPACE(Py_UCS4 ch) { + if (ch < 128) { + return _Py_ascii_whitespace[ch]; + } + return _PyUnicode_IsWhitespace(ch); +} + +#define Py_UNICODE_ISLOWER(ch) _PyUnicode_IsLowercase(ch) +#define Py_UNICODE_ISUPPER(ch) _PyUnicode_IsUppercase(ch) +#define Py_UNICODE_ISTITLE(ch) _PyUnicode_IsTitlecase(ch) +#define Py_UNICODE_ISLINEBREAK(ch) _PyUnicode_IsLinebreak(ch) + +#define Py_UNICODE_TOLOWER(ch) _PyUnicode_ToLowercase(ch) +#define Py_UNICODE_TOUPPER(ch) _PyUnicode_ToUppercase(ch) +#define Py_UNICODE_TOTITLE(ch) _PyUnicode_ToTitlecase(ch) + +#define Py_UNICODE_ISDECIMAL(ch) _PyUnicode_IsDecimalDigit(ch) +#define Py_UNICODE_ISDIGIT(ch) _PyUnicode_IsDigit(ch) +#define Py_UNICODE_ISNUMERIC(ch) _PyUnicode_IsNumeric(ch) +#define Py_UNICODE_ISPRINTABLE(ch) _PyUnicode_IsPrintable(ch) + +#define Py_UNICODE_TODECIMAL(ch) _PyUnicode_ToDecimalDigit(ch) +#define Py_UNICODE_TODIGIT(ch) _PyUnicode_ToDigit(ch) +#define Py_UNICODE_TONUMERIC(ch) _PyUnicode_ToNumeric(ch) + +#define Py_UNICODE_ISALPHA(ch) _PyUnicode_IsAlpha(ch) + +static inline int Py_UNICODE_ISALNUM(Py_UCS4 ch) { + return (Py_UNICODE_ISALPHA(ch) + || Py_UNICODE_ISDECIMAL(ch) + || Py_UNICODE_ISDIGIT(ch) + || Py_UNICODE_ISNUMERIC(ch)); +} + + +/* === Misc functions ===================================================== */ + PyAPI_FUNC(PyObject*) _PyUnicode_FormatLong(PyObject *, int, int, int); /* Return an interned Unicode object for an Identifier; may fail if there is no memory.*/ @@ -1144,7 +952,7 @@ PyAPI_FUNC(PyObject*) _PyUnicode_FromId(_Py_Identifier*); and where the hash values are equal (i.e. a very probable match) */ PyAPI_FUNC(int) _PyUnicode_EQ(PyObject *, PyObject *); -/* Equality check. Returns -1 on failure. */ +/* Equality check. */ PyAPI_FUNC(int) _PyUnicode_Equal(PyObject *, PyObject *); PyAPI_FUNC(int) _PyUnicode_WideCharString_Converter(PyObject *, void *); diff --git a/Include/cpython/warnings.h b/Include/cpython/warnings.h index 2ef8e3ce..4e3eb88e 100644 --- a/Include/cpython/warnings.h +++ b/Include/cpython/warnings.h @@ -17,4 +17,4 @@ PyAPI_FUNC(int) PyErr_WarnExplicitFormat( const char *format, ...); // DEPRECATED: Use PyErr_WarnEx() instead. -#define PyErr_Warn(category, msg) PyErr_WarnEx(category, msg, 1) +#define PyErr_Warn(category, msg) PyErr_WarnEx((category), (msg), 1) diff --git a/Include/cpython/weakrefobject.h b/Include/cpython/weakrefobject.h index 26b364f4..fd79fdc2 100644 --- a/Include/cpython/weakrefobject.h +++ b/Include/cpython/weakrefobject.h @@ -53,6 +53,4 @@ static inline PyObject* PyWeakref_GET_OBJECT(PyObject *ref_obj) { } return Py_None; } -#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define PyWeakref_GET_OBJECT(ref) PyWeakref_GET_OBJECT(_PyObject_CAST(ref)) -#endif +#define PyWeakref_GET_OBJECT(ref) PyWeakref_GET_OBJECT(_PyObject_CAST(ref)) diff --git a/Include/datetime.h b/Include/datetime.h index bb565201..b78cc0e8 100644 --- a/Include/datetime.h +++ b/Include/datetime.h @@ -119,39 +119,39 @@ typedef struct // o is a pointer to a time or a datetime object. #define _PyDateTime_HAS_TZINFO(o) (((_PyDateTime_BaseTZInfo *)(o))->hastzinfo) -#define PyDateTime_GET_YEAR(o) ((((PyDateTime_Date*)o)->data[0] << 8) | \ - ((PyDateTime_Date*)o)->data[1]) -#define PyDateTime_GET_MONTH(o) (((PyDateTime_Date*)o)->data[2]) -#define PyDateTime_GET_DAY(o) (((PyDateTime_Date*)o)->data[3]) - -#define PyDateTime_DATE_GET_HOUR(o) (((PyDateTime_DateTime*)o)->data[4]) -#define PyDateTime_DATE_GET_MINUTE(o) (((PyDateTime_DateTime*)o)->data[5]) -#define PyDateTime_DATE_GET_SECOND(o) (((PyDateTime_DateTime*)o)->data[6]) +#define PyDateTime_GET_YEAR(o) ((((PyDateTime_Date*)(o))->data[0] << 8) | \ + ((PyDateTime_Date*)(o))->data[1]) +#define PyDateTime_GET_MONTH(o) (((PyDateTime_Date*)(o))->data[2]) +#define PyDateTime_GET_DAY(o) (((PyDateTime_Date*)(o))->data[3]) + +#define PyDateTime_DATE_GET_HOUR(o) (((PyDateTime_DateTime*)(o))->data[4]) +#define PyDateTime_DATE_GET_MINUTE(o) (((PyDateTime_DateTime*)(o))->data[5]) +#define PyDateTime_DATE_GET_SECOND(o) (((PyDateTime_DateTime*)(o))->data[6]) #define PyDateTime_DATE_GET_MICROSECOND(o) \ - ((((PyDateTime_DateTime*)o)->data[7] << 16) | \ - (((PyDateTime_DateTime*)o)->data[8] << 8) | \ - ((PyDateTime_DateTime*)o)->data[9]) -#define PyDateTime_DATE_GET_FOLD(o) (((PyDateTime_DateTime*)o)->fold) -#define PyDateTime_DATE_GET_TZINFO(o) (_PyDateTime_HAS_TZINFO(o) ? \ + ((((PyDateTime_DateTime*)(o))->data[7] << 16) | \ + (((PyDateTime_DateTime*)(o))->data[8] << 8) | \ + ((PyDateTime_DateTime*)(o))->data[9]) +#define PyDateTime_DATE_GET_FOLD(o) (((PyDateTime_DateTime*)(o))->fold) +#define PyDateTime_DATE_GET_TZINFO(o) (_PyDateTime_HAS_TZINFO((o)) ? \ ((PyDateTime_DateTime *)(o))->tzinfo : Py_None) /* Apply for time instances. */ -#define PyDateTime_TIME_GET_HOUR(o) (((PyDateTime_Time*)o)->data[0]) -#define PyDateTime_TIME_GET_MINUTE(o) (((PyDateTime_Time*)o)->data[1]) -#define PyDateTime_TIME_GET_SECOND(o) (((PyDateTime_Time*)o)->data[2]) +#define PyDateTime_TIME_GET_HOUR(o) (((PyDateTime_Time*)(o))->data[0]) +#define PyDateTime_TIME_GET_MINUTE(o) (((PyDateTime_Time*)(o))->data[1]) +#define PyDateTime_TIME_GET_SECOND(o) (((PyDateTime_Time*)(o))->data[2]) #define PyDateTime_TIME_GET_MICROSECOND(o) \ - ((((PyDateTime_Time*)o)->data[3] << 16) | \ - (((PyDateTime_Time*)o)->data[4] << 8) | \ - ((PyDateTime_Time*)o)->data[5]) -#define PyDateTime_TIME_GET_FOLD(o) (((PyDateTime_Time*)o)->fold) + ((((PyDateTime_Time*)(o))->data[3] << 16) | \ + (((PyDateTime_Time*)(o))->data[4] << 8) | \ + ((PyDateTime_Time*)(o))->data[5]) +#define PyDateTime_TIME_GET_FOLD(o) (((PyDateTime_Time*)(o))->fold) #define PyDateTime_TIME_GET_TZINFO(o) (_PyDateTime_HAS_TZINFO(o) ? \ ((PyDateTime_Time *)(o))->tzinfo : Py_None) /* Apply for time delta instances */ -#define PyDateTime_DELTA_GET_DAYS(o) (((PyDateTime_Delta*)o)->days) -#define PyDateTime_DELTA_GET_SECONDS(o) (((PyDateTime_Delta*)o)->seconds) +#define PyDateTime_DELTA_GET_DAYS(o) (((PyDateTime_Delta*)(o))->days) +#define PyDateTime_DELTA_GET_SECONDS(o) (((PyDateTime_Delta*)(o))->seconds) #define PyDateTime_DELTA_GET_MICROSECONDS(o) \ - (((PyDateTime_Delta*)o)->microseconds) + (((PyDateTime_Delta*)(o))->microseconds) /* Define structure for C API. */ @@ -203,60 +203,60 @@ static PyDateTime_CAPI *PyDateTimeAPI = NULL; #define PyDateTime_TimeZone_UTC PyDateTimeAPI->TimeZone_UTC /* Macros for type checking when not building the Python core. */ -#define PyDate_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->DateType) -#define PyDate_CheckExact(op) Py_IS_TYPE(op, PyDateTimeAPI->DateType) +#define PyDate_Check(op) PyObject_TypeCheck((op), PyDateTimeAPI->DateType) +#define PyDate_CheckExact(op) Py_IS_TYPE((op), PyDateTimeAPI->DateType) -#define PyDateTime_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->DateTimeType) -#define PyDateTime_CheckExact(op) Py_IS_TYPE(op, PyDateTimeAPI->DateTimeType) +#define PyDateTime_Check(op) PyObject_TypeCheck((op), PyDateTimeAPI->DateTimeType) +#define PyDateTime_CheckExact(op) Py_IS_TYPE((op), PyDateTimeAPI->DateTimeType) -#define PyTime_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->TimeType) -#define PyTime_CheckExact(op) Py_IS_TYPE(op, PyDateTimeAPI->TimeType) +#define PyTime_Check(op) PyObject_TypeCheck((op), PyDateTimeAPI->TimeType) +#define PyTime_CheckExact(op) Py_IS_TYPE((op), PyDateTimeAPI->TimeType) -#define PyDelta_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->DeltaType) -#define PyDelta_CheckExact(op) Py_IS_TYPE(op, PyDateTimeAPI->DeltaType) +#define PyDelta_Check(op) PyObject_TypeCheck((op), PyDateTimeAPI->DeltaType) +#define PyDelta_CheckExact(op) Py_IS_TYPE((op), PyDateTimeAPI->DeltaType) -#define PyTZInfo_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->TZInfoType) -#define PyTZInfo_CheckExact(op) Py_IS_TYPE(op, PyDateTimeAPI->TZInfoType) +#define PyTZInfo_Check(op) PyObject_TypeCheck((op), PyDateTimeAPI->TZInfoType) +#define PyTZInfo_CheckExact(op) Py_IS_TYPE((op), PyDateTimeAPI->TZInfoType) /* Macros for accessing constructors in a simplified fashion. */ #define PyDate_FromDate(year, month, day) \ - PyDateTimeAPI->Date_FromDate(year, month, day, PyDateTimeAPI->DateType) + PyDateTimeAPI->Date_FromDate((year), (month), (day), PyDateTimeAPI->DateType) #define PyDateTime_FromDateAndTime(year, month, day, hour, min, sec, usec) \ - PyDateTimeAPI->DateTime_FromDateAndTime(year, month, day, hour, \ - min, sec, usec, Py_None, PyDateTimeAPI->DateTimeType) + PyDateTimeAPI->DateTime_FromDateAndTime((year), (month), (day), (hour), \ + (min), (sec), (usec), Py_None, PyDateTimeAPI->DateTimeType) #define PyDateTime_FromDateAndTimeAndFold(year, month, day, hour, min, sec, usec, fold) \ - PyDateTimeAPI->DateTime_FromDateAndTimeAndFold(year, month, day, hour, \ - min, sec, usec, Py_None, fold, PyDateTimeAPI->DateTimeType) + PyDateTimeAPI->DateTime_FromDateAndTimeAndFold((year), (month), (day), (hour), \ + (min), (sec), (usec), Py_None, (fold), PyDateTimeAPI->DateTimeType) #define PyTime_FromTime(hour, minute, second, usecond) \ - PyDateTimeAPI->Time_FromTime(hour, minute, second, usecond, \ + PyDateTimeAPI->Time_FromTime((hour), (minute), (second), (usecond), \ Py_None, PyDateTimeAPI->TimeType) #define PyTime_FromTimeAndFold(hour, minute, second, usecond, fold) \ - PyDateTimeAPI->Time_FromTimeAndFold(hour, minute, second, usecond, \ - Py_None, fold, PyDateTimeAPI->TimeType) + PyDateTimeAPI->Time_FromTimeAndFold((hour), (minute), (second), (usecond), \ + Py_None, (fold), PyDateTimeAPI->TimeType) #define PyDelta_FromDSU(days, seconds, useconds) \ - PyDateTimeAPI->Delta_FromDelta(days, seconds, useconds, 1, \ + PyDateTimeAPI->Delta_FromDelta((days), (seconds), (useconds), 1, \ PyDateTimeAPI->DeltaType) #define PyTimeZone_FromOffset(offset) \ - PyDateTimeAPI->TimeZone_FromTimeZone(offset, NULL) + PyDateTimeAPI->TimeZone_FromTimeZone((offset), NULL) #define PyTimeZone_FromOffsetAndName(offset, name) \ - PyDateTimeAPI->TimeZone_FromTimeZone(offset, name) + PyDateTimeAPI->TimeZone_FromTimeZone((offset), (name)) /* Macros supporting the DB API. */ #define PyDateTime_FromTimestamp(args) \ PyDateTimeAPI->DateTime_FromTimestamp( \ - (PyObject*) (PyDateTimeAPI->DateTimeType), args, NULL) + (PyObject*) (PyDateTimeAPI->DateTimeType), (args), NULL) #define PyDate_FromTimestamp(args) \ PyDateTimeAPI->Date_FromTimestamp( \ - (PyObject*) (PyDateTimeAPI->DateType), args) + (PyObject*) (PyDateTimeAPI->DateType), (args)) #endif /* !defined(_PY_DATETIME_IMPL) */ diff --git a/Include/descrobject.h b/Include/descrobject.h index 77f221df..fd66d17b 100644 --- a/Include/descrobject.h +++ b/Include/descrobject.h @@ -32,6 +32,62 @@ PyAPI_FUNC(PyObject *) PyDescr_NewGetSet(PyTypeObject *, PyGetSetDef *); PyAPI_FUNC(PyObject *) PyDictProxy_New(PyObject *); PyAPI_FUNC(PyObject *) PyWrapper_New(PyObject *, PyObject *); + +/* An array of PyMemberDef structures defines the name, type and offset + of selected members of a C structure. These can be read by + PyMember_GetOne() and set by PyMember_SetOne() (except if their READONLY + flag is set). The array must be terminated with an entry whose name + pointer is NULL. */ +struct PyMemberDef { + const char *name; + int type; + Py_ssize_t offset; + int flags; + const char *doc; +}; + +// These constants used to be in structmember.h, not prefixed by Py_. +// (structmember.h now has aliases to the new names.) + +/* Types */ +#define Py_T_SHORT 0 +#define Py_T_INT 1 +#define Py_T_LONG 2 +#define Py_T_FLOAT 3 +#define Py_T_DOUBLE 4 +#define Py_T_STRING 5 +#define _Py_T_OBJECT 6 // Deprecated, use Py_T_OBJECT_EX instead +/* the ordering here is weird for binary compatibility */ +#define Py_T_CHAR 7 /* 1-character string */ +#define Py_T_BYTE 8 /* 8-bit signed int */ +/* unsigned variants: */ +#define Py_T_UBYTE 9 +#define Py_T_USHORT 10 +#define Py_T_UINT 11 +#define Py_T_ULONG 12 + +/* Added by Jack: strings contained in the structure */ +#define Py_T_STRING_INPLACE 13 + +/* Added by Lillo: bools contained in the structure (assumed char) */ +#define Py_T_BOOL 14 + +#define Py_T_OBJECT_EX 16 +#define Py_T_LONGLONG 17 +#define Py_T_ULONGLONG 18 + +#define Py_T_PYSSIZET 19 /* Py_ssize_t */ +#define _Py_T_NONE 20 // Deprecated. Value is always None. + +/* Flags */ +#define Py_READONLY 1 +#define Py_AUDIT_READ 2 // Added in 3.10, harmless no-op before that +#define _Py_WRITE_RESTRICTED 4 // Deprecated, no-op. Do not reuse the value. +#define Py_RELATIVE_OFFSET 8 + +PyAPI_FUNC(PyObject *) PyMember_GetOne(const char *, PyMemberDef *); +PyAPI_FUNC(int) PyMember_SetOne(char *, PyMemberDef *, PyObject *); + #ifndef Py_LIMITED_API # define Py_CPYTHON_DESCROBJECT_H # include "cpython/descrobject.h" diff --git a/Include/dictobject.h b/Include/dictobject.h index a6233d8a..e7fcb44d 100644 --- a/Include/dictobject.h +++ b/Include/dictobject.h @@ -16,7 +16,7 @@ PyAPI_DATA(PyTypeObject) PyDict_Type; #define PyDict_Check(op) \ PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_DICT_SUBCLASS) -#define PyDict_CheckExact(op) Py_IS_TYPE(op, &PyDict_Type) +#define PyDict_CheckExact(op) Py_IS_TYPE((op), &PyDict_Type) PyAPI_FUNC(PyObject *) PyDict_New(void); PyAPI_FUNC(PyObject *) PyDict_GetItem(PyObject *mp, PyObject *key); @@ -67,9 +67,9 @@ PyAPI_DATA(PyTypeObject) PyDictKeys_Type; PyAPI_DATA(PyTypeObject) PyDictValues_Type; PyAPI_DATA(PyTypeObject) PyDictItems_Type; -#define PyDictKeys_Check(op) PyObject_TypeCheck(op, &PyDictKeys_Type) -#define PyDictValues_Check(op) PyObject_TypeCheck(op, &PyDictValues_Type) -#define PyDictItems_Check(op) PyObject_TypeCheck(op, &PyDictItems_Type) +#define PyDictKeys_Check(op) PyObject_TypeCheck((op), &PyDictKeys_Type) +#define PyDictValues_Check(op) PyObject_TypeCheck((op), &PyDictValues_Type) +#define PyDictItems_Check(op) PyObject_TypeCheck((op), &PyDictItems_Type) /* This excludes Values, since they are not sets. */ # define PyDictViewSet_Check(op) \ (PyDictKeys_Check(op) || PyDictItems_Check(op)) diff --git a/Include/exports.h b/Include/exports.h index fc1a5c5e..59373c39 100644 --- a/Include/exports.h +++ b/Include/exports.h @@ -2,9 +2,15 @@ #define Py_EXPORTS_H #if defined(_WIN32) || defined(__CYGWIN__) - #define Py_IMPORTED_SYMBOL __declspec(dllimport) - #define Py_EXPORTED_SYMBOL __declspec(dllexport) - #define Py_LOCAL_SYMBOL + #if defined(Py_ENABLE_SHARED) + #define Py_IMPORTED_SYMBOL __declspec(dllimport) + #define Py_EXPORTED_SYMBOL __declspec(dllexport) + #define Py_LOCAL_SYMBOL + #else + #define Py_IMPORTED_SYMBOL + #define Py_EXPORTED_SYMBOL + #define Py_LOCAL_SYMBOL + #endif #else /* * If we only ever used gcc >= 5, we could use __has_attribute(visibility) diff --git a/Include/fileobject.h b/Include/fileobject.h index 4c983e7b..2deef544 100644 --- a/Include/fileobject.h +++ b/Include/fileobject.h @@ -19,14 +19,14 @@ PyAPI_FUNC(int) PyObject_AsFileDescriptor(PyObject *); /* The default encoding used by the platform file system APIs If non-NULL, this is different than the default encoding for strings */ -PyAPI_DATA(const char *) Py_FileSystemDefaultEncoding; +Py_DEPRECATED(3.12) PyAPI_DATA(const char *) Py_FileSystemDefaultEncoding; #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03060000 -PyAPI_DATA(const char *) Py_FileSystemDefaultEncodeErrors; +Py_DEPRECATED(3.12) PyAPI_DATA(const char *) Py_FileSystemDefaultEncodeErrors; #endif -PyAPI_DATA(int) Py_HasFileSystemDefaultEncoding; +Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_HasFileSystemDefaultEncoding; #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03070000 -PyAPI_DATA(int) Py_UTF8Mode; +Py_DEPRECATED(3.12) PyAPI_DATA(int) Py_UTF8Mode; #endif /* A routine to check if a file descriptor can be select()-ed. */ diff --git a/Include/floatobject.h b/Include/floatobject.h index 9d2fff30..999441ac 100644 --- a/Include/floatobject.h +++ b/Include/floatobject.h @@ -14,7 +14,7 @@ extern "C" { PyAPI_DATA(PyTypeObject) PyFloat_Type; #define PyFloat_Check(op) PyObject_TypeCheck(op, &PyFloat_Type) -#define PyFloat_CheckExact(op) Py_IS_TYPE(op, &PyFloat_Type) +#define PyFloat_CheckExact(op) Py_IS_TYPE((op), &PyFloat_Type) #define Py_RETURN_NAN return PyFloat_FromDouble(Py_NAN) diff --git a/Include/import.h b/Include/import.h index a87677bb..5d5f3425 100644 --- a/Include/import.h +++ b/Include/import.h @@ -67,7 +67,7 @@ PyAPI_FUNC(PyObject *) PyImport_ImportModuleLevelObject( #endif #define PyImport_ImportModuleEx(n, g, l, f) \ - PyImport_ImportModuleLevel(n, g, l, f, 0) + PyImport_ImportModuleLevel((n), (g), (l), (f), 0) PyAPI_FUNC(PyObject *) PyImport_GetImporter(PyObject *path); PyAPI_FUNC(PyObject *) PyImport_Import(PyObject *name); diff --git a/Include/internal/pycore_accu.h b/Include/internal/pycore_accu.h deleted file mode 100644 index d346222e..00000000 --- a/Include/internal/pycore_accu.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef Py_LIMITED_API -#ifndef Py_INTERNAL_ACCU_H -#define Py_INTERNAL_ACCU_H -#ifdef __cplusplus -extern "C" { -#endif - -/*** This is a private API for use by the interpreter and the stdlib. - *** Its definition may be changed or removed at any moment. - ***/ - -#ifndef Py_BUILD_CORE -# error "this header requires Py_BUILD_CORE define" -#endif - -/* - * A two-level accumulator of unicode objects that avoids both the overhead - * of keeping a huge number of small separate objects, and the quadratic - * behaviour of using a naive repeated concatenation scheme. - */ - -#undef small /* defined by some Windows headers */ - -typedef struct { - PyObject *large; /* A list of previously accumulated large strings */ - PyObject *small; /* Pending small strings */ -} _PyAccu; - -PyAPI_FUNC(int) _PyAccu_Init(_PyAccu *acc); -PyAPI_FUNC(int) _PyAccu_Accumulate(_PyAccu *acc, PyObject *unicode); -PyAPI_FUNC(PyObject *) _PyAccu_FinishAsList(_PyAccu *acc); -PyAPI_FUNC(PyObject *) _PyAccu_Finish(_PyAccu *acc); -PyAPI_FUNC(void) _PyAccu_Destroy(_PyAccu *acc); - -#ifdef __cplusplus -} -#endif -#endif /* !Py_INTERNAL_ACCU_H */ -#endif /* !Py_LIMITED_API */ diff --git a/Include/internal/pycore_asdl.h b/Include/internal/pycore_asdl.h index 5b01c7a6..afeada88 100644 --- a/Include/internal/pycore_asdl.h +++ b/Include/internal/pycore_asdl.h @@ -91,7 +91,7 @@ asdl_ ## NAME ## _seq *_Py_asdl_ ## NAME ## _seq_new(Py_ssize_t size, PyArena *a (S)->typed_elements[_asdl_i] = (V); \ } while (0) #else -# define asdl_seq_SET(S, I, V) _Py_RVALUE((S)->typed_elements[I] = (V)) +# define asdl_seq_SET(S, I, V) _Py_RVALUE((S)->typed_elements[(I)] = (V)) #endif #ifdef Py_DEBUG @@ -103,7 +103,7 @@ asdl_ ## NAME ## _seq *_Py_asdl_ ## NAME ## _seq_new(Py_ssize_t size, PyArena *a (S)->elements[_asdl_i] = (V); \ } while (0) #else -# define asdl_seq_SET_UNTYPED(S, I, V) _Py_RVALUE((S)->elements[I] = (V)) +# define asdl_seq_SET_UNTYPED(S, I, V) _Py_RVALUE((S)->elements[(I)] = (V)) #endif #ifdef __cplusplus diff --git a/Include/internal/pycore_ast.h b/Include/internal/pycore_ast.h index 36277efe..b568902b 100644 --- a/Include/internal/pycore_ast.h +++ b/Include/internal/pycore_ast.h @@ -51,6 +51,8 @@ typedef struct _pattern *pattern_ty; typedef struct _type_ignore *type_ignore_ty; +typedef struct _type_param *type_param_ty; + typedef struct { _ASDL_SEQ_HEAD @@ -147,6 +149,14 @@ typedef struct { asdl_type_ignore_seq *_Py_asdl_type_ignore_seq_new(Py_ssize_t size, PyArena *arena); +typedef struct { + _ASDL_SEQ_HEAD + type_param_ty typed_elements[1]; +} asdl_type_param_seq; + +asdl_type_param_seq *_Py_asdl_type_param_seq_new(Py_ssize_t size, PyArena + *arena); + enum _mod_kind {Module_kind=1, Interactive_kind=2, Expression_kind=3, FunctionType_kind=4}; @@ -176,12 +186,13 @@ struct _mod { enum _stmt_kind {FunctionDef_kind=1, AsyncFunctionDef_kind=2, ClassDef_kind=3, Return_kind=4, Delete_kind=5, Assign_kind=6, - AugAssign_kind=7, AnnAssign_kind=8, For_kind=9, - AsyncFor_kind=10, While_kind=11, If_kind=12, With_kind=13, - AsyncWith_kind=14, Match_kind=15, Raise_kind=16, Try_kind=17, - TryStar_kind=18, Assert_kind=19, Import_kind=20, - ImportFrom_kind=21, Global_kind=22, Nonlocal_kind=23, - Expr_kind=24, Pass_kind=25, Break_kind=26, Continue_kind=27}; + TypeAlias_kind=7, AugAssign_kind=8, AnnAssign_kind=9, + For_kind=10, AsyncFor_kind=11, While_kind=12, If_kind=13, + With_kind=14, AsyncWith_kind=15, Match_kind=16, + Raise_kind=17, Try_kind=18, TryStar_kind=19, Assert_kind=20, + Import_kind=21, ImportFrom_kind=22, Global_kind=23, + Nonlocal_kind=24, Expr_kind=25, Pass_kind=26, Break_kind=27, + Continue_kind=28}; struct _stmt { enum _stmt_kind kind; union { @@ -192,6 +203,7 @@ struct _stmt { asdl_expr_seq *decorator_list; expr_ty returns; string type_comment; + asdl_type_param_seq *type_params; } FunctionDef; struct { @@ -201,6 +213,7 @@ struct _stmt { asdl_expr_seq *decorator_list; expr_ty returns; string type_comment; + asdl_type_param_seq *type_params; } AsyncFunctionDef; struct { @@ -209,6 +222,7 @@ struct _stmt { asdl_keyword_seq *keywords; asdl_stmt_seq *body; asdl_expr_seq *decorator_list; + asdl_type_param_seq *type_params; } ClassDef; struct { @@ -225,6 +239,12 @@ struct _stmt { string type_comment; } Assign; + struct { + expr_ty name; + asdl_type_param_seq *type_params; + expr_ty value; + } TypeAlias; + struct { expr_ty target; operator_ty op; @@ -630,6 +650,30 @@ struct _type_ignore { } v; }; +enum _type_param_kind {TypeVar_kind=1, ParamSpec_kind=2, TypeVarTuple_kind=3}; +struct _type_param { + enum _type_param_kind kind; + union { + struct { + identifier name; + expr_ty bound; + } TypeVar; + + struct { + identifier name; + } ParamSpec; + + struct { + identifier name; + } TypeVarTuple; + + } v; + int lineno; + int col_offset; + int end_lineno; + int end_col_offset; +}; + // Note: these macros affect function definitions, not only call sites. mod_ty _PyAST_Module(asdl_stmt_seq * body, asdl_type_ignore_seq * type_ignores, @@ -640,19 +684,20 @@ mod_ty _PyAST_FunctionType(asdl_expr_seq * argtypes, expr_ty returns, PyArena *arena); stmt_ty _PyAST_FunctionDef(identifier name, arguments_ty args, asdl_stmt_seq * body, asdl_expr_seq * decorator_list, expr_ty - returns, string type_comment, int lineno, int - col_offset, int end_lineno, int end_col_offset, - PyArena *arena); + returns, string type_comment, asdl_type_param_seq * + type_params, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena); stmt_ty _PyAST_AsyncFunctionDef(identifier name, arguments_ty args, asdl_stmt_seq * body, asdl_expr_seq * decorator_list, expr_ty returns, string - type_comment, int lineno, int col_offset, int + type_comment, asdl_type_param_seq * + type_params, int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena); stmt_ty _PyAST_ClassDef(identifier name, asdl_expr_seq * bases, asdl_keyword_seq * keywords, asdl_stmt_seq * body, - asdl_expr_seq * decorator_list, int lineno, int - col_offset, int end_lineno, int end_col_offset, PyArena - *arena); + asdl_expr_seq * decorator_list, asdl_type_param_seq * + type_params, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena); stmt_ty _PyAST_Return(expr_ty value, int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena); stmt_ty _PyAST_Delete(asdl_expr_seq * targets, int lineno, int col_offset, int @@ -660,6 +705,9 @@ stmt_ty _PyAST_Delete(asdl_expr_seq * targets, int lineno, int col_offset, int stmt_ty _PyAST_Assign(asdl_expr_seq * targets, expr_ty value, string type_comment, int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena); +stmt_ty _PyAST_TypeAlias(expr_ty name, asdl_type_param_seq * type_params, + expr_ty value, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena); stmt_ty _PyAST_AugAssign(expr_ty target, operator_ty op, expr_ty value, int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena); @@ -844,6 +892,14 @@ pattern_ty _PyAST_MatchOr(asdl_pattern_seq * patterns, int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena); type_ignore_ty _PyAST_TypeIgnore(int lineno, string tag, PyArena *arena); +type_param_ty _PyAST_TypeVar(identifier name, expr_ty bound, int lineno, int + col_offset, int end_lineno, int end_col_offset, + PyArena *arena); +type_param_ty _PyAST_ParamSpec(identifier name, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena); +type_param_ty _PyAST_TypeVarTuple(identifier name, int lineno, int col_offset, + int end_lineno, int end_col_offset, PyArena + *arena); PyObject* PyAST_mod2obj(mod_ty t); diff --git a/Include/internal/pycore_ast_state.h b/Include/internal/pycore_ast_state.h index f15b4905..0c0d53f3 100644 --- a/Include/internal/pycore_ast_state.h +++ b/Include/internal/pycore_ast_state.h @@ -118,6 +118,7 @@ struct ast_state { PyObject *Not_type; PyObject *Or_singleton; PyObject *Or_type; + PyObject *ParamSpec_type; PyObject *Pass_type; PyObject *Pow_singleton; PyObject *Pow_type; @@ -137,7 +138,10 @@ struct ast_state { PyObject *TryStar_type; PyObject *Try_type; PyObject *Tuple_type; + PyObject *TypeAlias_type; PyObject *TypeIgnore_type; + PyObject *TypeVarTuple_type; + PyObject *TypeVar_type; PyObject *UAdd_singleton; PyObject *UAdd_type; PyObject *USub_singleton; @@ -166,6 +170,7 @@ struct ast_state { PyObject *bases; PyObject *body; PyObject *boolop_type; + PyObject *bound; PyObject *cases; PyObject *cause; PyObject *cls; @@ -243,6 +248,8 @@ struct ast_state { PyObject *type_comment; PyObject *type_ignore_type; PyObject *type_ignores; + PyObject *type_param_type; + PyObject *type_params; PyObject *unaryop_type; PyObject *upper; PyObject *value; diff --git a/Include/internal/pycore_atexit.h b/Include/internal/pycore_atexit.h new file mode 100644 index 00000000..63a2cd5d --- /dev/null +++ b/Include/internal/pycore_atexit.h @@ -0,0 +1,57 @@ +#ifndef Py_INTERNAL_ATEXIT_H +#define Py_INTERNAL_ATEXIT_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + + +//############### +// runtime atexit + +typedef void (*atexit_callbackfunc)(void); + +struct _atexit_runtime_state { + PyThread_type_lock mutex; +#define NEXITFUNCS 32 + atexit_callbackfunc callbacks[NEXITFUNCS]; + int ncallbacks; +}; + + +//################### +// interpreter atexit + +struct atexit_callback; +typedef struct atexit_callback { + atexit_datacallbackfunc func; + void *data; + struct atexit_callback *next; +} atexit_callback; + +typedef struct { + PyObject *func; + PyObject *args; + PyObject *kwargs; +} atexit_py_callback; + +struct atexit_state { + atexit_callback *ll_callbacks; + atexit_callback *last_ll_callback; + + // XXX The rest of the state could be moved to the atexit module state + // and a low-level callback added for it during module exec. + // For the moment we leave it here. + atexit_py_callback **callbacks; + int ncallbacks; + int callback_len; +}; + + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_ATEXIT_H */ diff --git a/Include/internal/pycore_bytesobject.h b/Include/internal/pycore_bytesobject.h index 9173a4f1..d36fa956 100644 --- a/Include/internal/pycore_bytesobject.h +++ b/Include/internal/pycore_bytesobject.h @@ -9,11 +9,6 @@ extern "C" { #endif -/* runtime lifecycle */ - -extern PyStatus _PyBytes_InitTypes(PyInterpreterState *); - - /* Substring Search. Returns the index of the first occurrence of diff --git a/Include/internal/pycore_call.h b/Include/internal/pycore_call.h index 3ccacfa0..5d9342b5 100644 --- a/Include/internal/pycore_call.h +++ b/Include/internal/pycore_call.h @@ -103,6 +103,7 @@ _PyObject_CallNoArgsTstate(PyThreadState *tstate, PyObject *func) { // Private static inline function variant of public PyObject_CallNoArgs() static inline PyObject * _PyObject_CallNoArgs(PyObject *func) { + EVAL_CALL_STAT_INC_IF_FUNCTION(EVAL_CALL_API, func); PyThreadState *tstate = _PyThreadState_GET(); return _PyObject_VectorcallTstate(tstate, func, NULL, 0, NULL); } @@ -111,9 +112,20 @@ _PyObject_CallNoArgs(PyObject *func) { static inline PyObject * _PyObject_FastCallTstate(PyThreadState *tstate, PyObject *func, PyObject *const *args, Py_ssize_t nargs) { + EVAL_CALL_STAT_INC_IF_FUNCTION(EVAL_CALL_API, func); return _PyObject_VectorcallTstate(tstate, func, args, (size_t)nargs, NULL); } +PyObject *const * +_PyStack_UnpackDict(PyThreadState *tstate, + PyObject *const *args, Py_ssize_t nargs, + PyObject *kwargs, PyObject **p_kwnames); + +void +_PyStack_UnpackDict_Free(PyObject *const *stack, Py_ssize_t nargs, + PyObject *kwnames); + +void _PyStack_UnpackDict_FreeNoDecRef(PyObject *const *stack, PyObject *kwnames); #ifdef __cplusplus } diff --git a/Include/internal/pycore_ceval.h b/Include/internal/pycore_ceval.h index 8d18d200..fc0f72ef 100644 --- a/Include/internal/pycore_ceval.h +++ b/Include/internal/pycore_ceval.h @@ -12,15 +12,8 @@ extern "C" { struct pyruntimestate; struct _ceval_runtime_state; -/* WASI has limited call stack. Python's recursion limit depends on code - layout, optimization, and WASI runtime. Wasmtime can handle about 700-750 - recursions, sometimes less. 600 is a more conservative limit. */ #ifndef Py_DEFAULT_RECURSION_LIMIT -# ifdef __wasi__ -# define Py_DEFAULT_RECURSION_LIMIT 600 -# else -# define Py_DEFAULT_RECURSION_LIMIT 1000 -# endif +# define Py_DEFAULT_RECURSION_LIMIT 1000 #endif #include "pycore_interp.h" // PyInterpreterState.eval_frame @@ -28,14 +21,14 @@ struct _ceval_runtime_state; extern void _Py_FinishPendingCalls(PyThreadState *tstate); -extern void _PyEval_InitRuntimeState(struct _ceval_runtime_state *); -extern void _PyEval_InitState(struct _ceval_state *, PyThread_type_lock); +extern void _PyEval_InitState(PyInterpreterState *, PyThread_type_lock); extern void _PyEval_FiniState(struct _ceval_state *ceval); PyAPI_FUNC(void) _PyEval_SignalReceived(PyInterpreterState *interp); PyAPI_FUNC(int) _PyEval_AddPendingCall( PyInterpreterState *interp, int (*func)(void *), - void *arg); + void *arg, + int mainthreadonly); PyAPI_FUNC(void) _PyEval_SignalAsyncExc(PyInterpreterState *interp); #ifdef HAVE_FORK extern PyStatus _PyEval_ReInitThreads(PyThreadState *tstate); @@ -65,10 +58,32 @@ extern PyObject* _PyEval_BuiltinsFromGlobals( PyThreadState *tstate, PyObject *globals); +// Trampoline API + +typedef struct { + // Callback to initialize the trampoline state + void* (*init_state)(void); + // Callback to register every trampoline being created + void (*write_state)(void* state, const void *code_addr, + unsigned int code_size, PyCodeObject* code); + // Callback to free the trampoline state + int (*free_state)(void* state); +} _PyPerf_Callbacks; + +extern int _PyPerfTrampoline_SetCallbacks(_PyPerf_Callbacks *); +extern void _PyPerfTrampoline_GetCallbacks(_PyPerf_Callbacks *); +extern int _PyPerfTrampoline_Init(int activate); +extern int _PyPerfTrampoline_Fini(void); +extern int _PyIsPerfTrampolineActive(void); +extern PyStatus _PyPerfTrampoline_AfterFork_Child(void); +#ifdef PY_HAVE_PERF_TRAMPOLINE +extern _PyPerf_Callbacks _Py_perfmap_callbacks; +#endif static inline PyObject* _PyEval_EvalFrame(PyThreadState *tstate, struct _PyInterpreterFrame *frame, int throwflag) { + EVAL_CALL_STAT_INC(EVAL_CALL_TOTAL); if (tstate->interp->eval_frame == NULL) { return _PyEval_EvalFrameDefault(tstate, frame, throwflag); } @@ -81,11 +96,13 @@ _PyEval_Vector(PyThreadState *tstate, PyObject* const* args, size_t argcount, PyObject *kwnames); -extern int _PyEval_ThreadsInitialized(struct pyruntimestate *runtime); -extern PyStatus _PyEval_InitGIL(PyThreadState *tstate); +extern int _PyEval_ThreadsInitialized(void); +extern PyStatus _PyEval_InitGIL(PyThreadState *tstate, int own_gil); extern void _PyEval_FiniGIL(PyInterpreterState *interp); -extern void _PyEval_ReleaseLock(PyThreadState *tstate); +extern void _PyEval_AcquireLock(PyThreadState *tstate); +extern void _PyEval_ReleaseLock(PyInterpreterState *, PyThreadState *); +extern PyThreadState * _PyThreadState_SwapNoGIL(PyThreadState *); extern void _PyEval_DeactivateOpCache(void); @@ -96,12 +113,12 @@ extern void _PyEval_DeactivateOpCache(void); /* With USE_STACKCHECK macro defined, trigger stack checks in _Py_CheckRecursiveCall() on every 64th call to _Py_EnterRecursiveCall. */ static inline int _Py_MakeRecCheck(PyThreadState *tstate) { - return (tstate->recursion_remaining-- <= 0 - || (tstate->recursion_remaining & 63) == 0); + return (tstate->c_recursion_remaining-- <= 0 + || (tstate->c_recursion_remaining & 63) == 0); } #else static inline int _Py_MakeRecCheck(PyThreadState *tstate) { - return tstate->recursion_remaining-- <= 0; + return tstate->c_recursion_remaining-- <= 0; } #endif @@ -109,6 +126,9 @@ PyAPI_FUNC(int) _Py_CheckRecursiveCall( PyThreadState *tstate, const char *where); +int _Py_CheckRecursiveCallPy( + PyThreadState *tstate); + static inline int _Py_EnterRecursiveCallTstate(PyThreadState *tstate, const char *where) { return (_Py_MakeRecCheck(tstate) && _Py_CheckRecursiveCall(tstate, where)); @@ -120,7 +140,7 @@ static inline int _Py_EnterRecursiveCall(const char *where) { } static inline void _Py_LeaveRecursiveCallTstate(PyThreadState *tstate) { - tstate->recursion_remaining++; + tstate->c_recursion_remaining++; } static inline void _Py_LeaveRecursiveCall(void) { @@ -132,6 +152,11 @@ extern struct _PyInterpreterFrame* _PyEval_GetFrame(void); extern PyObject* _Py_MakeCoro(PyFunctionObject *func); +extern int _Py_HandlePending(PyThreadState *tstate); + +extern PyObject * _PyEval_GetFrameLocals(void); + + #ifdef __cplusplus } #endif diff --git a/Include/internal/pycore_ceval_state.h b/Include/internal/pycore_ceval_state.h new file mode 100644 index 00000000..e56e43c6 --- /dev/null +++ b/Include/internal/pycore_ceval_state.h @@ -0,0 +1,103 @@ +#ifndef Py_INTERNAL_CEVAL_STATE_H +#define Py_INTERNAL_CEVAL_STATE_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + + +#include "pycore_atomic.h" /* _Py_atomic_address */ +#include "pycore_gil.h" // struct _gil_runtime_state + + +struct _pending_calls { + int busy; + PyThread_type_lock lock; + /* Request for running pending calls. */ + _Py_atomic_int calls_to_do; + /* Request for looking at the `async_exc` field of the current + thread state. + Guarded by the GIL. */ + int async_exc; +#define NPENDINGCALLS 32 + struct _pending_call { + int (*func)(void *); + void *arg; + } calls[NPENDINGCALLS]; + int first; + int last; +}; + +typedef enum { + PERF_STATUS_FAILED = -1, // Perf trampoline is in an invalid state + PERF_STATUS_NO_INIT = 0, // Perf trampoline is not initialized + PERF_STATUS_OK = 1, // Perf trampoline is ready to be executed +} perf_status_t; + + +#ifdef PY_HAVE_PERF_TRAMPOLINE +struct code_arena_st; + +struct trampoline_api_st { + void* (*init_state)(void); + void (*write_state)(void* state, const void *code_addr, + unsigned int code_size, PyCodeObject* code); + int (*free_state)(void* state); + void *state; +}; +#endif + +struct _ceval_runtime_state { + struct { +#ifdef PY_HAVE_PERF_TRAMPOLINE + perf_status_t status; + Py_ssize_t extra_code_index; + struct code_arena_st *code_arena; + struct trampoline_api_st trampoline_api; + FILE *map_file; +#else + int _not_used; +#endif + } perf; + /* Request for checking signals. It is shared by all interpreters (see + bpo-40513). Any thread of any interpreter can receive a signal, but only + the main thread of the main interpreter can handle signals: see + _Py_ThreadCanHandleSignals(). */ + _Py_atomic_int signals_pending; + /* Pending calls to be made only on the main thread. */ + struct _pending_calls pending_mainthread; +}; + +#ifdef PY_HAVE_PERF_TRAMPOLINE +# define _PyEval_RUNTIME_PERF_INIT \ + { \ + .status = PERF_STATUS_NO_INIT, \ + .extra_code_index = -1, \ + } +#else +# define _PyEval_RUNTIME_PERF_INIT {0} +#endif + + +struct _ceval_state { + /* This single variable consolidates all requests to break out of + the fast path in the eval loop. */ + _Py_atomic_int eval_breaker; + /* Request for dropping the GIL */ + _Py_atomic_int gil_drop_request; + int recursion_limit; + struct _gil_runtime_state *gil; + int own_gil; + /* The GC is ready to be executed */ + _Py_atomic_int gc_scheduled; + struct _pending_calls pending; +}; + + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_CEVAL_STATE_H */ diff --git a/Include/internal/pycore_code.h b/Include/internal/pycore_code.h index 3a24a654..75a23f3f 100644 --- a/Include/internal/pycore_code.h +++ b/Include/internal/pycore_code.h @@ -4,6 +4,8 @@ extern "C" { #endif +#define CODE_MAX_WATCHERS 8 + /* PEP 659 * Specialization and quickening structs and helper functions */ @@ -16,109 +18,95 @@ extern "C" { #define CACHE_ENTRIES(cache) (sizeof(cache)/sizeof(_Py_CODEUNIT)) typedef struct { - _Py_CODEUNIT counter; - _Py_CODEUNIT index; - _Py_CODEUNIT module_keys_version[2]; - _Py_CODEUNIT builtin_keys_version; + uint16_t counter; + uint16_t index; + uint16_t module_keys_version; + uint16_t builtin_keys_version; } _PyLoadGlobalCache; #define INLINE_CACHE_ENTRIES_LOAD_GLOBAL CACHE_ENTRIES(_PyLoadGlobalCache) typedef struct { - _Py_CODEUNIT counter; + uint16_t counter; } _PyBinaryOpCache; #define INLINE_CACHE_ENTRIES_BINARY_OP CACHE_ENTRIES(_PyBinaryOpCache) typedef struct { - _Py_CODEUNIT counter; + uint16_t counter; } _PyUnpackSequenceCache; #define INLINE_CACHE_ENTRIES_UNPACK_SEQUENCE \ CACHE_ENTRIES(_PyUnpackSequenceCache) typedef struct { - _Py_CODEUNIT counter; - _Py_CODEUNIT mask; + uint16_t counter; } _PyCompareOpCache; #define INLINE_CACHE_ENTRIES_COMPARE_OP CACHE_ENTRIES(_PyCompareOpCache) typedef struct { - _Py_CODEUNIT counter; - _Py_CODEUNIT type_version[2]; - _Py_CODEUNIT func_version; + uint16_t counter; } _PyBinarySubscrCache; #define INLINE_CACHE_ENTRIES_BINARY_SUBSCR CACHE_ENTRIES(_PyBinarySubscrCache) typedef struct { - _Py_CODEUNIT counter; - _Py_CODEUNIT version[2]; - _Py_CODEUNIT index; -} _PyAttrCache; + uint16_t counter; +} _PySuperAttrCache; -#define INLINE_CACHE_ENTRIES_LOAD_ATTR CACHE_ENTRIES(_PyAttrCache) +#define INLINE_CACHE_ENTRIES_LOAD_SUPER_ATTR CACHE_ENTRIES(_PySuperAttrCache) -#define INLINE_CACHE_ENTRIES_STORE_ATTR CACHE_ENTRIES(_PyAttrCache) +typedef struct { + uint16_t counter; + uint16_t version[2]; + uint16_t index; +} _PyAttrCache; typedef struct { - _Py_CODEUNIT counter; - _Py_CODEUNIT type_version[2]; - _Py_CODEUNIT dict_offset; - _Py_CODEUNIT keys_version[2]; - _Py_CODEUNIT descr[4]; + uint16_t counter; + uint16_t type_version[2]; + uint16_t keys_version[2]; + uint16_t descr[4]; } _PyLoadMethodCache; -#define INLINE_CACHE_ENTRIES_LOAD_METHOD CACHE_ENTRIES(_PyLoadMethodCache) -typedef struct { - _Py_CODEUNIT counter; - _Py_CODEUNIT func_version[2]; - _Py_CODEUNIT min_args; -} _PyCallCache; +// MUST be the max(_PyAttrCache, _PyLoadMethodCache) +#define INLINE_CACHE_ENTRIES_LOAD_ATTR CACHE_ENTRIES(_PyLoadMethodCache) -#define INLINE_CACHE_ENTRIES_CALL CACHE_ENTRIES(_PyCallCache) +#define INLINE_CACHE_ENTRIES_STORE_ATTR CACHE_ENTRIES(_PyAttrCache) typedef struct { - _Py_CODEUNIT counter; -} _PyPrecallCache; + uint16_t counter; + uint16_t func_version[2]; +} _PyCallCache; -#define INLINE_CACHE_ENTRIES_PRECALL CACHE_ENTRIES(_PyPrecallCache) +#define INLINE_CACHE_ENTRIES_CALL CACHE_ENTRIES(_PyCallCache) typedef struct { - _Py_CODEUNIT counter; + uint16_t counter; } _PyStoreSubscrCache; #define INLINE_CACHE_ENTRIES_STORE_SUBSCR CACHE_ENTRIES(_PyStoreSubscrCache) -#define QUICKENING_WARMUP_DELAY 8 - -/* We want to compare to zero for efficiency, so we offset values accordingly */ -#define QUICKENING_INITIAL_WARMUP_VALUE (-QUICKENING_WARMUP_DELAY) +typedef struct { + uint16_t counter; +} _PyForIterCache; -void _PyCode_Quicken(PyCodeObject *code); +#define INLINE_CACHE_ENTRIES_FOR_ITER CACHE_ENTRIES(_PyForIterCache) -static inline void -_PyCode_Warmup(PyCodeObject *code) -{ - if (code->co_warmup != 0) { - code->co_warmup++; - if (code->co_warmup == 0) { - _PyCode_Quicken(code); - } - } -} - -extern uint8_t _PyOpcode_Adaptive[256]; +typedef struct { + uint16_t counter; +} _PySendCache; -extern Py_ssize_t _Py_QuickenedCount; +#define INLINE_CACHE_ENTRIES_SEND CACHE_ENTRIES(_PySendCache) // Borrowed references to common callables: struct callable_cache { PyObject *isinstance; PyObject *len; PyObject *list_append; + PyObject *object__getattribute__; }; /* "Locals plus" for a code object is the set of locals + cell vars + @@ -140,6 +128,7 @@ struct callable_cache { // Note that these all fit within a byte, as do combinations. // Later, we will use the smaller numbers to differentiate the different // kinds of locals (e.g. pos-only arg, varkwargs, local-only). +#define CO_FAST_HIDDEN 0x10 #define CO_FAST_LOCAL 0x20 #define CO_FAST_CELL 0x40 #define CO_FAST_FREE 0x80 @@ -235,90 +224,47 @@ extern int _PyLineTable_PreviousAddressRange(PyCodeAddressRange *range); /* Specialization functions */ -extern int _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, - PyObject *name); -extern int _Py_Specialize_StoreAttr(PyObject *owner, _Py_CODEUNIT *instr, +extern void _Py_Specialize_LoadSuperAttr(PyObject *global_super, PyObject *cls, + _Py_CODEUNIT *instr, int load_method); +extern void _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name); -extern int _Py_Specialize_LoadGlobal(PyObject *globals, PyObject *builtins, _Py_CODEUNIT *instr, PyObject *name); -extern int _Py_Specialize_LoadMethod(PyObject *owner, _Py_CODEUNIT *instr, +extern void _Py_Specialize_StoreAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name); -extern int _Py_Specialize_BinarySubscr(PyObject *sub, PyObject *container, _Py_CODEUNIT *instr); -extern int _Py_Specialize_StoreSubscr(PyObject *container, PyObject *sub, _Py_CODEUNIT *instr); -extern int _Py_Specialize_Call(PyObject *callable, _Py_CODEUNIT *instr, - int nargs, PyObject *kwnames); -extern int _Py_Specialize_Precall(PyObject *callable, _Py_CODEUNIT *instr, - int nargs, PyObject *kwnames, int oparg); +extern void _Py_Specialize_LoadGlobal(PyObject *globals, PyObject *builtins, + _Py_CODEUNIT *instr, PyObject *name); +extern void _Py_Specialize_BinarySubscr(PyObject *sub, PyObject *container, + _Py_CODEUNIT *instr); +extern void _Py_Specialize_StoreSubscr(PyObject *container, PyObject *sub, + _Py_CODEUNIT *instr); +extern void _Py_Specialize_Call(PyObject *callable, _Py_CODEUNIT *instr, + int nargs, PyObject *kwnames); extern void _Py_Specialize_BinaryOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr, int oparg, PyObject **locals); extern void _Py_Specialize_CompareOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr, int oparg); extern void _Py_Specialize_UnpackSequence(PyObject *seq, _Py_CODEUNIT *instr, int oparg); +extern void _Py_Specialize_ForIter(PyObject *iter, _Py_CODEUNIT *instr, int oparg); +extern void _Py_Specialize_Send(PyObject *receiver, _Py_CODEUNIT *instr); -/* Deallocator function for static codeobjects used in deepfreeze.py */ -extern void _PyStaticCode_Dealloc(PyCodeObject *co); -/* Function to intern strings of codeobjects */ -extern int _PyStaticCode_InternStrings(PyCodeObject *co); +/* Finalizer function for static codeobjects used in deepfreeze.py */ +extern void _PyStaticCode_Fini(PyCodeObject *co); +/* Function to intern strings of codeobjects and quicken the bytecode */ +extern int _PyStaticCode_Init(PyCodeObject *co); #ifdef Py_STATS -#define SPECIALIZATION_FAILURE_KINDS 30 - -typedef struct _specialization_stats { - uint64_t success; - uint64_t failure; - uint64_t hit; - uint64_t deferred; - uint64_t miss; - uint64_t deopt; - uint64_t failure_kinds[SPECIALIZATION_FAILURE_KINDS]; -} SpecializationStats; - -typedef struct _opcode_stats { - SpecializationStats specialization; - uint64_t execution_count; - uint64_t pair_count[256]; -} OpcodeStats; - -typedef struct _call_stats { - uint64_t inlined_py_calls; - uint64_t pyeval_calls; - uint64_t frames_pushed; - uint64_t frame_objects_created; -} CallStats; - -typedef struct _object_stats { - uint64_t allocations; - uint64_t allocations512; - uint64_t allocations4k; - uint64_t allocations_big; - uint64_t frees; - uint64_t to_freelist; - uint64_t from_freelist; - uint64_t new_values; - uint64_t dict_materialized_on_request; - uint64_t dict_materialized_new_key; - uint64_t dict_materialized_too_big; - uint64_t dict_materialized_str_subclass; -} ObjectStats; - -typedef struct _stats { - OpcodeStats opcode_stats[256]; - CallStats call_stats; - ObjectStats object_stats; -} PyStats; - -extern PyStats _py_stats; - -#define STAT_INC(opname, name) _py_stats.opcode_stats[opname].specialization.name++ -#define STAT_DEC(opname, name) _py_stats.opcode_stats[opname].specialization.name-- -#define OPCODE_EXE_INC(opname) _py_stats.opcode_stats[opname].execution_count++ -#define CALL_STAT_INC(name) _py_stats.call_stats.name++ -#define OBJECT_STAT_INC(name) _py_stats.object_stats.name++ -#define OBJECT_STAT_INC_COND(name, cond) \ - do { if (cond) _py_stats.object_stats.name++; } while (0) -extern void _Py_PrintSpecializationStats(int to_file); +#define STAT_INC(opname, name) do { if (_py_stats) _py_stats->opcode_stats[opname].specialization.name++; } while (0) +#define STAT_DEC(opname, name) do { if (_py_stats) _py_stats->opcode_stats[opname].specialization.name--; } while (0) +#define OPCODE_EXE_INC(opname) do { if (_py_stats) _py_stats->opcode_stats[opname].execution_count++; } while (0) +#define CALL_STAT_INC(name) do { if (_py_stats) _py_stats->call_stats.name++; } while (0) +#define OBJECT_STAT_INC(name) do { if (_py_stats) _py_stats->object_stats.name++; } while (0) +#define OBJECT_STAT_INC_COND(name, cond) \ + do { if (_py_stats && cond) _py_stats->object_stats.name++; } while (0) +#define EVAL_CALL_STAT_INC(name) do { if (_py_stats) _py_stats->call_stats.eval_calls[name]++; } while (0) +#define EVAL_CALL_STAT_INC_IF_FUNCTION(name, callable) \ + do { if (_py_stats && PyFunction_Check(callable)) _py_stats->call_stats.eval_calls[name]++; } while (0) // Used by the _opcode extension which is built as a shared library PyAPI_FUNC(PyObject*) _Py_GetSpecializationStats(void); @@ -330,112 +276,65 @@ PyAPI_FUNC(PyObject*) _Py_GetSpecializationStats(void); #define CALL_STAT_INC(name) ((void)0) #define OBJECT_STAT_INC(name) ((void)0) #define OBJECT_STAT_INC_COND(name, cond) ((void)0) +#define EVAL_CALL_STAT_INC(name) ((void)0) +#define EVAL_CALL_STAT_INC_IF_FUNCTION(name, callable) ((void)0) #endif // !Py_STATS -// Cache values are only valid in memory, so use native endianness. -#ifdef WORDS_BIGENDIAN +// Utility functions for reading/writing 32/64-bit values in the inline caches. +// Great care should be taken to ensure that these functions remain correct and +// performant! They should compile to just "move" instructions on all supported +// compilers and platforms. + +// We use memcpy to let the C compiler handle unaligned accesses and endianness +// issues for us. It also seems to produce better code than manual copying for +// most compilers (see https://blog.regehr.org/archives/959 for more info). static inline void write_u32(uint16_t *p, uint32_t val) { - p[0] = (uint16_t)(val >> 16); - p[1] = (uint16_t)(val >> 0); + memcpy(p, &val, sizeof(val)); } static inline void write_u64(uint16_t *p, uint64_t val) { - p[0] = (uint16_t)(val >> 48); - p[1] = (uint16_t)(val >> 32); - p[2] = (uint16_t)(val >> 16); - p[3] = (uint16_t)(val >> 0); -} - -static inline uint32_t -read_u32(uint16_t *p) -{ - uint32_t val = 0; - val |= (uint32_t)p[0] << 16; - val |= (uint32_t)p[1] << 0; - return val; + memcpy(p, &val, sizeof(val)); } -static inline uint64_t -read_u64(uint16_t *p) -{ - uint64_t val = 0; - val |= (uint64_t)p[0] << 48; - val |= (uint64_t)p[1] << 32; - val |= (uint64_t)p[2] << 16; - val |= (uint64_t)p[3] << 0; - return val; -} - -#else - static inline void -write_u32(uint16_t *p, uint32_t val) +write_obj(uint16_t *p, PyObject *val) { - p[0] = (uint16_t)(val >> 0); - p[1] = (uint16_t)(val >> 16); + memcpy(p, &val, sizeof(val)); } -static inline void -write_u64(uint16_t *p, uint64_t val) +static inline uint16_t +read_u16(uint16_t *p) { - p[0] = (uint16_t)(val >> 0); - p[1] = (uint16_t)(val >> 16); - p[2] = (uint16_t)(val >> 32); - p[3] = (uint16_t)(val >> 48); + return *p; } static inline uint32_t read_u32(uint16_t *p) { - uint32_t val = 0; - val |= (uint32_t)p[0] << 0; - val |= (uint32_t)p[1] << 16; + uint32_t val; + memcpy(&val, p, sizeof(val)); return val; } static inline uint64_t read_u64(uint16_t *p) { - uint64_t val = 0; - val |= (uint64_t)p[0] << 0; - val |= (uint64_t)p[1] << 16; - val |= (uint64_t)p[2] << 32; - val |= (uint64_t)p[3] << 48; + uint64_t val; + memcpy(&val, p, sizeof(val)); return val; } -#endif - -static inline void -write_obj(uint16_t *p, PyObject *obj) -{ - uintptr_t val = (uintptr_t)obj; -#if SIZEOF_VOID_P == 8 - write_u64(p, val); -#elif SIZEOF_VOID_P == 4 - write_u32(p, val); -#else - #error "SIZEOF_VOID_P must be 4 or 8" -#endif -} - static inline PyObject * read_obj(uint16_t *p) { - uintptr_t val; -#if SIZEOF_VOID_P == 8 - val = read_u64(p); -#elif SIZEOF_VOID_P == 4 - val = read_u32(p); -#else - #error "SIZEOF_VOID_P must be 4 or 8" -#endif - return (PyObject *)val; + PyObject *val; + memcpy(&val, p, sizeof(val)); + return val; } /* See Objects/exception_handling_notes.txt for details. @@ -499,8 +398,22 @@ write_location_entry_start(uint8_t *ptr, int code, int length) /* With a 16-bit counter, we have 12 bits for the counter value, and 4 bits for the backoff */ #define ADAPTIVE_BACKOFF_BITS 4 -/* The initial counter value is 31 == 2**ADAPTIVE_BACKOFF_START - 1 */ -#define ADAPTIVE_BACKOFF_START 5 + +// A value of 1 means that we attempt to specialize the *second* time each +// instruction is executed. Executing twice is a much better indicator of +// "hotness" than executing once, but additional warmup delays only prevent +// specialization. Most types stabilize by the second execution, too: +#define ADAPTIVE_WARMUP_VALUE 1 +#define ADAPTIVE_WARMUP_BACKOFF 1 + +// A value of 52 means that we attempt to re-specialize after 53 misses (a prime +// number, useful for avoiding artifacts if every nth value is a different type +// or something). Setting the backoff to 0 means that the counter is reset to +// the same state as a warming-up instruction (value == 1, backoff == 1) after +// deoptimization. This isn't strictly necessary, but it is bit easier to reason +// about when thinking about the opcode transitions as a state machine: +#define ADAPTIVE_COOLDOWN_VALUE 52 +#define ADAPTIVE_COOLDOWN_BACKOFF 0 #define MAX_BACKOFF_VALUE (16 - ADAPTIVE_BACKOFF_BITS) @@ -508,13 +421,19 @@ write_location_entry_start(uint8_t *ptr, int code, int length) static inline uint16_t adaptive_counter_bits(int value, int backoff) { return (value << ADAPTIVE_BACKOFF_BITS) | - (backoff & ((1<<ADAPTIVE_BACKOFF_BITS)-1)); + (backoff & ((1<<ADAPTIVE_BACKOFF_BITS)-1)); } static inline uint16_t -adaptive_counter_start(void) { - unsigned int value = (1 << ADAPTIVE_BACKOFF_START) - 1; - return adaptive_counter_bits(value, ADAPTIVE_BACKOFF_START); +adaptive_counter_warmup(void) { + return adaptive_counter_bits(ADAPTIVE_WARMUP_VALUE, + ADAPTIVE_WARMUP_BACKOFF); +} + +static inline uint16_t +adaptive_counter_cooldown(void) { + return adaptive_counter_bits(ADAPTIVE_COOLDOWN_VALUE, + ADAPTIVE_COOLDOWN_BACKOFF); } static inline uint16_t @@ -531,31 +450,42 @@ adaptive_counter_backoff(uint16_t counter) { /* Line array cache for tracing */ -extern int _PyCode_CreateLineArray(PyCodeObject *co); +typedef struct _PyShimCodeDef { + const uint8_t *code; + int codelen; + int stacksize; + const char *cname; +} _PyShimCodeDef; -static inline int -_PyCode_InitLineArray(PyCodeObject *co) -{ - if (co->_co_linearray) { - return 0; - } - return _PyCode_CreateLineArray(co); -} +extern PyCodeObject * +_Py_MakeShimCode(const _PyShimCodeDef *code); -static inline int -_PyCode_LineNumberFromArray(PyCodeObject *co, int index) -{ - assert(co->_co_linearray != NULL); - assert(index >= 0); - assert(index < Py_SIZE(co)); - if (co->_co_linearray_entry_size == 2) { - return ((int16_t *)co->_co_linearray)[index]; - } - else { - assert(co->_co_linearray_entry_size == 4); - return ((int32_t *)co->_co_linearray)[index]; - } -} +extern uint32_t _Py_next_func_version; + + +/* Comparison bit masks. */ + +/* Note this evaluates its arguments twice each */ +#define COMPARISON_BIT(x, y) (1 << (2 * ((x) >= (y)) + ((x) <= (y)))) + +/* + * The following bits are chosen so that the value of + * COMPARSION_BIT(left, right) + * masked by the values below will be non-zero if the + * comparison is true, and zero if it is false */ + +/* This is for values that are unordered, ie. NaN, not types that are unordered, e.g. sets */ +#define COMPARISON_UNORDERED 1 + +#define COMPARISON_LESS_THAN 2 +#define COMPARISON_GREATER_THAN 4 +#define COMPARISON_EQUALS 8 + +#define COMPARISON_NOT_EQUALS (COMPARISON_UNORDERED | COMPARISON_LESS_THAN | COMPARISON_GREATER_THAN) + +extern int _Py_Instrument(PyCodeObject *co, PyInterpreterState *interp); + +extern int _Py_GetBaseOpcode(PyCodeObject *code, int offset); #ifdef __cplusplus diff --git a/Include/internal/pycore_compile.h b/Include/internal/pycore_compile.h index 06a6082c..80a637e5 100644 --- a/Include/internal/pycore_compile.h +++ b/Include/internal/pycore_compile.h @@ -18,12 +18,8 @@ PyAPI_FUNC(PyCodeObject*) _PyAST_Compile( PyCompilerFlags *flags, int optimize, struct _arena *arena); -extern PyFutureFeatures* _PyFuture_FromAST( - struct _mod * mod, - PyObject *filename - ); -extern PyObject* _Py_Mangle(PyObject *p, PyObject *name); +static const _PyCompilerSrcLocation NO_LOCATION = {-1, -1, -1, -1}; typedef struct { int optimize; @@ -38,6 +34,84 @@ extern int _PyAST_Optimize( struct _arena *arena, _PyASTOptimizeState *state); +typedef struct { + int h_offset; + int h_startdepth; + int h_preserve_lasti; +} _PyCompile_ExceptHandlerInfo; + +typedef struct { + int i_opcode; + int i_oparg; + _PyCompilerSrcLocation i_loc; + _PyCompile_ExceptHandlerInfo i_except_handler_info; +} _PyCompile_Instruction; + +typedef struct { + _PyCompile_Instruction *s_instrs; + int s_allocated; + int s_used; + + int *s_labelmap; /* label id --> instr offset */ + int s_labelmap_size; + int s_next_free_label; /* next free label id */ +} _PyCompile_InstructionSequence; + +typedef struct { + PyObject *u_name; + PyObject *u_qualname; /* dot-separated qualified name (lazy) */ + + /* The following fields are dicts that map objects to + the index of them in co_XXX. The index is used as + the argument for opcodes that refer to those collections. + */ + PyObject *u_consts; /* all constants */ + PyObject *u_names; /* all names */ + PyObject *u_varnames; /* local variables */ + PyObject *u_cellvars; /* cell variables */ + PyObject *u_freevars; /* free variables */ + PyObject *u_fasthidden; /* dict; keys are names that are fast-locals only + temporarily within an inlined comprehension. When + value is True, treat as fast-local. */ + + Py_ssize_t u_argcount; /* number of arguments for block */ + Py_ssize_t u_posonlyargcount; /* number of positional only arguments for block */ + Py_ssize_t u_kwonlyargcount; /* number of keyword only arguments for block */ + + int u_firstlineno; /* the first lineno of the block */ +} _PyCompile_CodeUnitMetadata; + + +/* Utility for a number of growing arrays used in the compiler */ +int _PyCompile_EnsureArrayLargeEnough( + int idx, + void **array, + int *alloc, + int default_alloc, + size_t item_size); + +int _PyCompile_ConstCacheMergeOne(PyObject *const_cache, PyObject **obj); + +int _PyCompile_InstrSize(int opcode, int oparg); + +/* Access compiler internals for unit testing */ + +PyAPI_FUNC(PyObject*) _PyCompile_CodeGen( + PyObject *ast, + PyObject *filename, + PyCompilerFlags *flags, + int optimize, + int compile_mode); + +PyAPI_FUNC(PyObject*) _PyCompile_OptimizeCfg( + PyObject *instructions, + PyObject *consts, + int nlocals); + +PyAPI_FUNC(PyCodeObject*) +_PyCompile_Assemble(_PyCompile_CodeUnitMetadata *umd, PyObject *filename, + PyObject *instructions); + #ifdef __cplusplus } #endif diff --git a/Include/internal/pycore_context.h b/Include/internal/pycore_context.h index 1bf4e8f3..52dfe3ef 100644 --- a/Include/internal/pycore_context.h +++ b/Include/internal/pycore_context.h @@ -18,6 +18,10 @@ void _PyContext_Fini(PyInterpreterState *); /* other API */ +typedef struct { + PyObject_HEAD +} _PyContextTokenMissing; + #ifndef WITH_FREELISTS // without freelists # define PyContext_MAXFREELIST 0 diff --git a/Include/internal/pycore_descrobject.h b/Include/internal/pycore_descrobject.h new file mode 100644 index 00000000..76378569 --- /dev/null +++ b/Include/internal/pycore_descrobject.h @@ -0,0 +1,26 @@ +#ifndef Py_INTERNAL_DESCROBJECT_H +#define Py_INTERNAL_DESCROBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +typedef struct { + PyObject_HEAD + PyObject *prop_get; + PyObject *prop_set; + PyObject *prop_del; + PyObject *prop_doc; + PyObject *prop_name; + int getter_doc; +} propertyobject; + +typedef propertyobject _PyPropertyObject; + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_DESCROBJECT_H */ diff --git a/Include/internal/pycore_dict.h b/Include/internal/pycore_dict.h index dc308fe5..6253e084 100644 --- a/Include/internal/pycore_dict.h +++ b/Include/internal/pycore_dict.h @@ -9,6 +9,9 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif +#include "pycore_dict_state.h" +#include "pycore_runtime.h" // _PyRuntime + /* runtime lifecycle */ @@ -17,25 +20,6 @@ extern void _PyDict_Fini(PyInterpreterState *interp); /* other API */ -#ifndef WITH_FREELISTS -// without freelists -# define PyDict_MAXFREELIST 0 -#endif - -#ifndef PyDict_MAXFREELIST -# define PyDict_MAXFREELIST 80 -#endif - -struct _Py_dict_state { -#if PyDict_MAXFREELIST > 0 - /* Dictionary reuse scheme to save calls to malloc and free */ - PyDictObject *free_list[PyDict_MAXFREELIST]; - int numfree; - PyDictKeysObject *keys_free_list[PyDict_MAXFREELIST]; - int keys_numfree; -#endif -}; - typedef struct { /* Cached hash code of me_key. */ Py_hash_t me_hash; @@ -53,16 +37,17 @@ extern PyObject *_PyDict_FromKeys(PyObject *, PyObject *, PyObject *); /* Gets a version number unique to the current state of the keys of dict, if possible. * Returns the version number, or zero if it was not possible to get a version number. */ -extern uint32_t _PyDictKeys_GetVersionForCurrentState(PyDictKeysObject *dictkeys); +extern uint32_t _PyDictKeys_GetVersionForCurrentState( + PyInterpreterState *interp, PyDictKeysObject *dictkeys); -extern Py_ssize_t _PyDict_KeysSize(PyDictKeysObject *keys); +extern size_t _PyDict_KeysSize(PyDictKeysObject *keys); /* _Py_dict_lookup() returns index of entry which can be used like DK_ENTRIES(dk)[index]. * -1 when no entry found, -3 when compare raises error. */ extern Py_ssize_t _Py_dict_lookup(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject **value_addr); -extern Py_ssize_t _PyDict_GetItemHint(PyDictObject *, PyObject *, Py_ssize_t, PyObject **); +extern Py_ssize_t _PyDict_LookupIndex(PyDictObject *, PyObject *); extern Py_ssize_t _PyDictKeys_StringLookup(PyDictKeysObject* dictkeys, PyObject *key); extern PyObject *_PyDict_LoadGlobal(PyDictObject *, PyDictObject *, PyObject *); @@ -138,21 +123,57 @@ struct _dictvalues { PyObject *values[1]; }; -#define DK_LOG_SIZE(dk) ((dk)->dk_log2_size) +#define DK_LOG_SIZE(dk) _Py_RVALUE((dk)->dk_log2_size) #if SIZEOF_VOID_P > 4 #define DK_SIZE(dk) (((int64_t)1)<<DK_LOG_SIZE(dk)) #else #define DK_SIZE(dk) (1<<DK_LOG_SIZE(dk)) #endif -#define DK_ENTRIES(dk) \ - (assert(dk->dk_kind == DICT_KEYS_GENERAL), (PyDictKeyEntry*)(&((int8_t*)((dk)->dk_indices))[(size_t)1 << (dk)->dk_log2_index_bytes])) -#define DK_UNICODE_ENTRIES(dk) \ - (assert(dk->dk_kind != DICT_KEYS_GENERAL), (PyDictUnicodeEntry*)(&((int8_t*)((dk)->dk_indices))[(size_t)1 << (dk)->dk_log2_index_bytes])) -#define DK_IS_UNICODE(dk) ((dk)->dk_kind != DICT_KEYS_GENERAL) -extern uint64_t _pydict_global_version; +static inline void* _DK_ENTRIES(PyDictKeysObject *dk) { + int8_t *indices = (int8_t*)(dk->dk_indices); + size_t index = (size_t)1 << dk->dk_log2_index_bytes; + return (&indices[index]); +} +static inline PyDictKeyEntry* DK_ENTRIES(PyDictKeysObject *dk) { + assert(dk->dk_kind == DICT_KEYS_GENERAL); + return (PyDictKeyEntry*)_DK_ENTRIES(dk); +} +static inline PyDictUnicodeEntry* DK_UNICODE_ENTRIES(PyDictKeysObject *dk) { + assert(dk->dk_kind != DICT_KEYS_GENERAL); + return (PyDictUnicodeEntry*)_DK_ENTRIES(dk); +} + +#define DK_IS_UNICODE(dk) ((dk)->dk_kind != DICT_KEYS_GENERAL) -#define DICT_NEXT_VERSION() (++_pydict_global_version) +#define DICT_VERSION_INCREMENT (1 << DICT_MAX_WATCHERS) +#define DICT_VERSION_MASK (DICT_VERSION_INCREMENT - 1) + +#define DICT_NEXT_VERSION(INTERP) \ + ((INTERP)->dict_state.global_version += DICT_VERSION_INCREMENT) + +void +_PyDict_SendEvent(int watcher_bits, + PyDict_WatchEvent event, + PyDictObject *mp, + PyObject *key, + PyObject *value); + +static inline uint64_t +_PyDict_NotifyEvent(PyInterpreterState *interp, + PyDict_WatchEvent event, + PyDictObject *mp, + PyObject *key, + PyObject *value) +{ + assert(Py_REFCNT((PyObject*)mp) > 0); + int watcher_bits = mp->ma_version_tag & DICT_VERSION_MASK; + if (watcher_bits) { + _PyDict_SendEvent(watcher_bits, event, mp, key, value); + return DICT_NEXT_VERSION(interp) | watcher_bits; + } + return DICT_NEXT_VERSION(interp); +} extern PyObject *_PyObject_MakeDictFromInstanceAttributes(PyObject *obj, PyDictValues *values); extern PyObject *_PyDict_FromItems( diff --git a/Include/internal/pycore_dict_state.h b/Include/internal/pycore_dict_state.h new file mode 100644 index 00000000..ece0f10c --- /dev/null +++ b/Include/internal/pycore_dict_state.h @@ -0,0 +1,50 @@ +#ifndef Py_INTERNAL_DICT_STATE_H +#define Py_INTERNAL_DICT_STATE_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + + +#ifndef WITH_FREELISTS +// without freelists +# define PyDict_MAXFREELIST 0 +#endif + +#ifndef PyDict_MAXFREELIST +# define PyDict_MAXFREELIST 80 +#endif + +#define DICT_MAX_WATCHERS 8 + +struct _Py_dict_state { + /*Global counter used to set ma_version_tag field of dictionary. + * It is incremented each time that a dictionary is created and each + * time that a dictionary is modified. */ + uint64_t global_version; + uint32_t next_keys_version; + +#if PyDict_MAXFREELIST > 0 + /* Dictionary reuse scheme to save calls to malloc and free */ + PyDictObject *free_list[PyDict_MAXFREELIST]; + PyDictKeysObject *keys_free_list[PyDict_MAXFREELIST]; + int numfree; + int keys_numfree; +#endif + + PyDict_WatchCallback watchers[DICT_MAX_WATCHERS]; +}; + +#define _dict_state_INIT \ + { \ + .next_keys_version = 2, \ + } + + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_DICT_STATE_H */ diff --git a/Include/internal/pycore_dtoa.h b/Include/internal/pycore_dtoa.h index c77cf6e4..4d9681d5 100644 --- a/Include/internal/pycore_dtoa.h +++ b/Include/internal/pycore_dtoa.h @@ -1,3 +1,5 @@ +#ifndef Py_INTERNAL_DTOA_H +#define Py_INTERNAL_DTOA_H #ifdef __cplusplus extern "C" { #endif @@ -11,6 +13,50 @@ extern "C" { #if _PY_SHORT_FLOAT_REPR == 1 +typedef uint32_t ULong; + +struct +Bigint { + struct Bigint *next; + int k, maxwds, sign, wds; + ULong x[1]; +}; + +#ifdef Py_USING_MEMORY_DEBUGGER + +struct _dtoa_state { + int _not_used; +}; +#define _dtoa_interp_state_INIT(INTERP) \ + {0} + +#else // !Py_USING_MEMORY_DEBUGGER + +/* The size of the Bigint freelist */ +#define Bigint_Kmax 7 + +#ifndef PRIVATE_MEM +#define PRIVATE_MEM 2304 +#endif +#define Bigint_PREALLOC_SIZE \ + ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double)) + +struct _dtoa_state { + /* p5s is a linked list of powers of 5 of the form 5**(2**i), i >= 2 */ + // XXX This should be freed during runtime fini. + struct Bigint *p5s; + struct Bigint *freelist[Bigint_Kmax+1]; + double preallocated[Bigint_PREALLOC_SIZE]; + double *preallocated_next; +}; +#define _dtoa_state_INIT(INTERP) \ + { \ + .preallocated_next = (INTERP)->dtoa.preallocated, \ + } + +#endif // !Py_USING_MEMORY_DEBUGGER + + /* These functions are used by modules compiled as C extension like math: they must be exported. */ @@ -18,11 +64,10 @@ PyAPI_FUNC(double) _Py_dg_strtod(const char *str, char **ptr); PyAPI_FUNC(char *) _Py_dg_dtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve); PyAPI_FUNC(void) _Py_dg_freedtoa(char *s); -PyAPI_FUNC(double) _Py_dg_stdnan(int sign); -PyAPI_FUNC(double) _Py_dg_infinity(int sign); #endif // _PY_SHORT_FLOAT_REPR == 1 #ifdef __cplusplus } #endif +#endif /* !Py_INTERNAL_DTOA_H */ diff --git a/Include/internal/pycore_faulthandler.h b/Include/internal/pycore_faulthandler.h new file mode 100644 index 00000000..e6aec774 --- /dev/null +++ b/Include/internal/pycore_faulthandler.h @@ -0,0 +1,99 @@ +#ifndef Py_INTERNAL_FAULTHANDLER_H +#define Py_INTERNAL_FAULTHANDLER_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +#ifdef HAVE_SIGACTION +# include <signal.h> +#endif + + +#ifndef MS_WINDOWS + /* register() is useless on Windows, because only SIGSEGV, SIGABRT and + SIGILL can be handled by the process, and these signals can only be used + with enable(), not using register() */ +# define FAULTHANDLER_USER +#endif + + +#ifdef HAVE_SIGACTION +/* Using an alternative stack requires sigaltstack() + and sigaction() SA_ONSTACK */ +# ifdef HAVE_SIGALTSTACK +# define FAULTHANDLER_USE_ALT_STACK +# endif +typedef struct sigaction _Py_sighandler_t; +#else +typedef PyOS_sighandler_t _Py_sighandler_t; +#endif // HAVE_SIGACTION + + +#ifdef FAULTHANDLER_USER +struct faulthandler_user_signal { + int enabled; + PyObject *file; + int fd; + int all_threads; + int chain; + _Py_sighandler_t previous; + PyInterpreterState *interp; +}; +#endif /* FAULTHANDLER_USER */ + + +struct _faulthandler_runtime_state { + struct { + int enabled; + PyObject *file; + int fd; + int all_threads; + PyInterpreterState *interp; +#ifdef MS_WINDOWS + void *exc_handler; +#endif + } fatal_error; + + struct { + PyObject *file; + int fd; + PY_TIMEOUT_T timeout_us; /* timeout in microseconds */ + int repeat; + PyInterpreterState *interp; + int exit; + char *header; + size_t header_len; + /* The main thread always holds this lock. It is only released when + faulthandler_thread() is interrupted before this thread exits, or at + Python exit. */ + PyThread_type_lock cancel_event; + /* released by child thread when joined */ + PyThread_type_lock running; + } thread; + +#ifdef FAULTHANDLER_USER + struct faulthandler_user_signal *user_signals; +#endif + +#ifdef FAULTHANDLER_USE_ALT_STACK + stack_t stack; + stack_t old_stack; +#endif +}; + +#define _faulthandler_runtime_state_INIT \ + { \ + .fatal_error = { \ + .fd = -1, \ + }, \ + } + + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_FAULTHANDLER_H */ diff --git a/Include/internal/pycore_fileutils.h b/Include/internal/pycore_fileutils.h index 3ce8108e..7c2b6ec0 100644 --- a/Include/internal/pycore_fileutils.h +++ b/Include/internal/pycore_fileutils.h @@ -10,6 +10,11 @@ extern "C" { #include <locale.h> /* struct lconv */ + +struct _fileutils_state { + int force_ascii; +}; + typedef enum { _Py_ERROR_UNKNOWN=0, _Py_ERROR_STRICT, @@ -61,7 +66,7 @@ PyAPI_FUNC(PyObject *) _Py_device_encoding(int); #ifdef MS_WINDOWS struct _Py_stat_struct { - unsigned long st_dev; + uint64_t st_dev; uint64_t st_ino; unsigned short st_mode; int st_nlink; @@ -75,8 +80,11 @@ struct _Py_stat_struct { int st_mtime_nsec; time_t st_ctime; int st_ctime_nsec; + time_t st_birthtime; + int st_birthtime_nsec; unsigned long st_file_attributes; unsigned long st_reparse_tag; + uint64_t st_ino_high; }; #else # define _Py_stat_struct stat @@ -155,11 +163,11 @@ PyAPI_FUNC(int) _Py_set_inheritable_async_safe(int fd, int inheritable, PyAPI_FUNC(int) _Py_dup(int fd); -#ifndef MS_WINDOWS PyAPI_FUNC(int) _Py_get_blocking(int fd); PyAPI_FUNC(int) _Py_set_blocking(int fd, int blocking); -#else /* MS_WINDOWS */ + +#ifdef MS_WINDOWS PyAPI_FUNC(void*) _Py_get_osfhandle_noraise(int fd); PyAPI_FUNC(void*) _Py_get_osfhandle(int fd); @@ -244,8 +252,17 @@ extern int _Py_add_relfile(wchar_t *dirname, const wchar_t *relfile, size_t bufsize); extern size_t _Py_find_basename(const wchar_t *filename); -PyAPI_FUNC(wchar_t *) _Py_normpath(wchar_t *path, Py_ssize_t size); +PyAPI_FUNC(wchar_t*) _Py_normpath(wchar_t *path, Py_ssize_t size); +extern wchar_t *_Py_normpath_and_size(wchar_t *path, Py_ssize_t size, Py_ssize_t *length); + +// The Windows Games API family does not provide these functions +// so provide our own implementations. Remove them in case they get added +// to the Games API family +#if defined(MS_WINDOWS_GAMES) && !defined(MS_WINDOWS_DESKTOP) +#include <winerror.h> +extern HRESULT PathCchSkipRoot(const wchar_t *pszPath, const wchar_t **ppszRootEnd); +#endif /* defined(MS_WINDOWS_GAMES) && !defined(MS_WINDOWS_DESKTOP) */ // Macros to protect CRT calls against instant termination when passed an // invalid parameter (bpo-23524). IPH stands for Invalid Parameter Handler. diff --git a/Include/internal/pycore_fileutils_windows.h b/Include/internal/pycore_fileutils_windows.h new file mode 100644 index 00000000..e804d385 --- /dev/null +++ b/Include/internal/pycore_fileutils_windows.h @@ -0,0 +1,98 @@ +#ifndef Py_INTERNAL_FILEUTILS_WINDOWS_H +#define Py_INTERNAL_FILEUTILS_WINDOWS_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "Py_BUILD_CORE must be defined to include this header" +#endif + +#ifdef MS_WINDOWS + +#if !defined(NTDDI_WIN10_NI) || !(NTDDI_VERSION >= NTDDI_WIN10_NI) +typedef struct _FILE_STAT_BASIC_INFORMATION { + LARGE_INTEGER FileId; + LARGE_INTEGER CreationTime; + LARGE_INTEGER LastAccessTime; + LARGE_INTEGER LastWriteTime; + LARGE_INTEGER ChangeTime; + LARGE_INTEGER AllocationSize; + LARGE_INTEGER EndOfFile; + ULONG FileAttributes; + ULONG ReparseTag; + ULONG NumberOfLinks; + ULONG DeviceType; + ULONG DeviceCharacteristics; + ULONG Reserved; + LARGE_INTEGER VolumeSerialNumber; + FILE_ID_128 FileId128; +} FILE_STAT_BASIC_INFORMATION; + +typedef enum _FILE_INFO_BY_NAME_CLASS { + FileStatByNameInfo, + FileStatLxByNameInfo, + FileCaseSensitiveByNameInfo, + FileStatBasicByNameInfo, + MaximumFileInfoByNameClass +} FILE_INFO_BY_NAME_CLASS; +#endif + +typedef BOOL (WINAPI *PGetFileInformationByName)( + PCWSTR FileName, + FILE_INFO_BY_NAME_CLASS FileInformationClass, + PVOID FileInfoBuffer, + ULONG FileInfoBufferSize +); + +static inline BOOL _Py_GetFileInformationByName( + PCWSTR FileName, + FILE_INFO_BY_NAME_CLASS FileInformationClass, + PVOID FileInfoBuffer, + ULONG FileInfoBufferSize +) { + static PGetFileInformationByName GetFileInformationByName = NULL; + static int GetFileInformationByName_init = -1; + + if (GetFileInformationByName_init < 0) { + HMODULE hMod = LoadLibraryW(L"api-ms-win-core-file-l2-1-4"); + GetFileInformationByName_init = 0; + if (hMod) { + GetFileInformationByName = (PGetFileInformationByName)GetProcAddress( + hMod, "GetFileInformationByName"); + if (GetFileInformationByName) { + GetFileInformationByName_init = 1; + } else { + FreeLibrary(hMod); + } + } + } + + if (GetFileInformationByName_init <= 0) { + SetLastError(ERROR_NOT_SUPPORTED); + return FALSE; + } + return GetFileInformationByName(FileName, FileInformationClass, FileInfoBuffer, FileInfoBufferSize); +} + +static inline BOOL _Py_GetFileInformationByName_ErrorIsTrustworthy(int error) +{ + switch(error) { + case ERROR_FILE_NOT_FOUND: + case ERROR_PATH_NOT_FOUND: + case ERROR_NOT_READY: + case ERROR_BAD_NET_NAME: + case ERROR_BAD_NETPATH: + case ERROR_BAD_PATHNAME: + case ERROR_INVALID_NAME: + case ERROR_FILENAME_EXCED_RANGE: + return TRUE; + case ERROR_NOT_SUPPORTED: + return FALSE; + } + return FALSE; +} + +#endif + +#endif diff --git a/Include/internal/pycore_floatobject.h b/Include/internal/pycore_floatobject.h index 8a655543..27c63bc8 100644 --- a/Include/internal/pycore_floatobject.h +++ b/Include/internal/pycore_floatobject.h @@ -19,6 +19,18 @@ extern void _PyFloat_FiniType(PyInterpreterState *); /* other API */ +enum _py_float_format_type { + _py_float_format_unknown, + _py_float_format_ieee_big_endian, + _py_float_format_ieee_little_endian, +}; + +struct _Py_float_runtime_state { + enum _py_float_format_type float_format; + enum _py_float_format_type double_format; +}; + + #ifndef WITH_FREELISTS // without freelists # define PyFloat_MAXFREELIST 0 diff --git a/Include/internal/pycore_flowgraph.h b/Include/internal/pycore_flowgraph.h new file mode 100644 index 00000000..720feb18 --- /dev/null +++ b/Include/internal/pycore_flowgraph.h @@ -0,0 +1,120 @@ +#ifndef Py_INTERNAL_CFG_H +#define Py_INTERNAL_CFG_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +#include "pycore_opcode_utils.h" +#include "pycore_compile.h" + + +typedef struct { + int i_opcode; + int i_oparg; + _PyCompilerSrcLocation i_loc; + struct _PyCfgBasicblock_ *i_target; /* target block (if jump instruction) */ + struct _PyCfgBasicblock_ *i_except; /* target block when exception is raised */ +} _PyCfgInstruction; + +typedef struct { + int id; +} _PyCfgJumpTargetLabel; + + +typedef struct { + struct _PyCfgBasicblock_ *handlers[CO_MAXBLOCKS+1]; + int depth; +} _PyCfgExceptStack; + +typedef struct _PyCfgBasicblock_ { + /* Each basicblock in a compilation unit is linked via b_list in the + reverse order that the block are allocated. b_list points to the next + block in this list, not to be confused with b_next, which is next by + control flow. */ + struct _PyCfgBasicblock_ *b_list; + /* The label of this block if it is a jump target, -1 otherwise */ + _PyCfgJumpTargetLabel b_label; + /* Exception stack at start of block, used by assembler to create the exception handling table */ + _PyCfgExceptStack *b_exceptstack; + /* pointer to an array of instructions, initially NULL */ + _PyCfgInstruction *b_instr; + /* If b_next is non-NULL, it is a pointer to the next + block reached by normal control flow. */ + struct _PyCfgBasicblock_ *b_next; + /* number of instructions used */ + int b_iused; + /* length of instruction array (b_instr) */ + int b_ialloc; + /* Used by add_checks_for_loads_of_unknown_variables */ + uint64_t b_unsafe_locals_mask; + /* Number of predecessors that a block has. */ + int b_predecessors; + /* depth of stack upon entry of block, computed by stackdepth() */ + int b_startdepth; + /* instruction offset for block, computed by assemble_jump_offsets() */ + int b_offset; + /* Basic block is an exception handler that preserves lasti */ + unsigned b_preserve_lasti : 1; + /* Used by compiler passes to mark whether they have visited a basic block. */ + unsigned b_visited : 1; + /* b_except_handler is used by the cold-detection algorithm to mark exception targets */ + unsigned b_except_handler : 1; + /* b_cold is true if this block is not perf critical (like an exception handler) */ + unsigned b_cold : 1; + /* b_warm is used by the cold-detection algorithm to mark blocks which are definitely not cold */ + unsigned b_warm : 1; +} _PyCfgBasicblock; + +int _PyBasicblock_InsertInstruction(_PyCfgBasicblock *block, int pos, _PyCfgInstruction *instr); + +typedef struct cfg_builder_ { + /* The entryblock, at which control flow begins. All blocks of the + CFG are reachable through the b_next links */ + _PyCfgBasicblock *g_entryblock; + /* Pointer to the most recently allocated block. By following + b_list links, you can reach all allocated blocks. */ + _PyCfgBasicblock *g_block_list; + /* pointer to the block currently being constructed */ + _PyCfgBasicblock *g_curblock; + /* label for the next instruction to be placed */ + _PyCfgJumpTargetLabel g_current_label; +} _PyCfgBuilder; + +int _PyCfgBuilder_UseLabel(_PyCfgBuilder *g, _PyCfgJumpTargetLabel lbl); +int _PyCfgBuilder_Addop(_PyCfgBuilder *g, int opcode, int oparg, _PyCompilerSrcLocation loc); + +int _PyCfgBuilder_Init(_PyCfgBuilder *g); +void _PyCfgBuilder_Fini(_PyCfgBuilder *g); + +_PyCfgInstruction* _PyCfg_BasicblockLastInstr(const _PyCfgBasicblock *b); +int _PyCfg_OptimizeCodeUnit(_PyCfgBuilder *g, PyObject *consts, PyObject *const_cache, + int code_flags, int nlocals, int nparams, int firstlineno); +int _PyCfg_Stackdepth(_PyCfgBasicblock *entryblock, int code_flags); +void _PyCfg_ConvertPseudoOps(_PyCfgBasicblock *entryblock); +int _PyCfg_ResolveJumps(_PyCfgBuilder *g); + + +static inline int +basicblock_nofallthrough(const _PyCfgBasicblock *b) { + _PyCfgInstruction *last = _PyCfg_BasicblockLastInstr(b); + return (last && + (IS_SCOPE_EXIT_OPCODE(last->i_opcode) || + IS_UNCONDITIONAL_JUMP_OPCODE(last->i_opcode))); +} + +#define BB_NO_FALLTHROUGH(B) (basicblock_nofallthrough(B)) +#define BB_HAS_FALLTHROUGH(B) (!basicblock_nofallthrough(B)) + +PyCodeObject * +_PyAssemble_MakeCodeObject(_PyCompile_CodeUnitMetadata *u, PyObject *const_cache, + PyObject *consts, int maxdepth, _PyCompile_InstructionSequence *instrs, + int nlocalsplus, int code_flags, PyObject *filename); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_CFG_H */ diff --git a/Include/internal/pycore_format.h b/Include/internal/pycore_format.h index 1899609e..1b8d5753 100644 --- a/Include/internal/pycore_format.h +++ b/Include/internal/pycore_format.h @@ -14,14 +14,12 @@ extern "C" { * F_BLANK ' ' * F_ALT '#' * F_ZERO '0' - * F_NO_NEG_0 'z' */ #define F_LJUST (1<<0) #define F_SIGN (1<<1) #define F_BLANK (1<<2) #define F_ALT (1<<3) #define F_ZERO (1<<4) -#define F_NO_NEG_0 (1<<5) #ifdef __cplusplus } diff --git a/Include/internal/pycore_frame.h b/Include/internal/pycore_frame.h index 4866ea21..158db2cf 100644 --- a/Include/internal/pycore_frame.h +++ b/Include/internal/pycore_frame.h @@ -6,6 +6,7 @@ extern "C" { #include <stdbool.h> #include <stddef.h> +#include "pycore_code.h" // STATS /* See Objects/frame_layout.md for an explanation of the frame stack * including explanation of the PyFrameObject and _PyInterpreterFrame @@ -41,26 +42,31 @@ typedef enum _framestate { enum _frameowner { FRAME_OWNED_BY_THREAD = 0, FRAME_OWNED_BY_GENERATOR = 1, - FRAME_OWNED_BY_FRAME_OBJECT = 2 + FRAME_OWNED_BY_FRAME_OBJECT = 2, + FRAME_OWNED_BY_CSTACK = 3, }; typedef struct _PyInterpreterFrame { - /* "Specials" section */ - PyFunctionObject *f_func; /* Strong reference */ - PyObject *f_globals; /* Borrowed reference */ - PyObject *f_builtins; /* Borrowed reference */ - PyObject *f_locals; /* Strong reference, may be NULL */ PyCodeObject *f_code; /* Strong reference */ - PyFrameObject *frame_obj; /* Strong reference, may be NULL */ - /* Linkage section */ struct _PyInterpreterFrame *previous; + PyObject *f_funcobj; /* Strong reference. Only valid if not on C stack */ + PyObject *f_globals; /* Borrowed reference. Only valid if not on C stack */ + PyObject *f_builtins; /* Borrowed reference. Only valid if not on C stack */ + PyObject *f_locals; /* Strong reference, may be NULL. Only valid if not on C stack */ + PyFrameObject *frame_obj; /* Strong reference, may be NULL. Only valid if not on C stack */ // NOTE: This is not necessarily the last instruction started in the given // frame. Rather, it is the code unit *prior to* the *next* instruction. For // example, it may be an inline CACHE entry, an instruction we just jumped // over, or (in the case of a newly-created frame) a totally invalid value: _Py_CODEUNIT *prev_instr; - int stacktop; /* Offset of TOS from localsplus */ - bool is_entry; // Whether this is the "root" frame for the current _PyCFrame. + int stacktop; /* Offset of TOS from localsplus */ + /* The return_offset determines where a `RETURN` should go in the caller, + * relative to `prev_instr`. + * It is only meaningful to the callee, + * so it needs to be set in any CALL (to a Python function) + * or SEND (to a coroutine or generator). + * If there is no callee, then it is meaningless. */ + uint16_t return_offset; char owner; /* Locals and stack */ PyObject *localsplus[1]; @@ -90,7 +96,16 @@ static inline void _PyFrame_StackPush(_PyInterpreterFrame *f, PyObject *value) { f->stacktop++; } -#define FRAME_SPECIALS_SIZE ((sizeof(_PyInterpreterFrame)-1)/sizeof(PyObject *)) +#define FRAME_SPECIALS_SIZE ((int)((sizeof(_PyInterpreterFrame)-1)/sizeof(PyObject *))) + +static inline int +_PyFrame_NumSlotsForCodeObject(PyCodeObject *code) +{ + /* This function needs to remain in sync with the calculation of + * co_framesize in Tools/build/deepfreeze.py */ + assert(code->co_framesize >= FRAME_SPECIALS_SIZE); + return code->co_framesize - FRAME_SPECIALS_SIZE; +} void _PyFrame_Copy(_PyInterpreterFrame *src, _PyInterpreterFrame *dest); @@ -99,20 +114,24 @@ void _PyFrame_Copy(_PyInterpreterFrame *src, _PyInterpreterFrame *dest); when frame is linked into the frame stack. */ static inline void -_PyFrame_InitializeSpecials( +_PyFrame_Initialize( _PyInterpreterFrame *frame, PyFunctionObject *func, - PyObject *locals, int nlocalsplus) + PyObject *locals, PyCodeObject *code, int null_locals_from) { - frame->f_func = func; - frame->f_code = (PyCodeObject *)Py_NewRef(func->func_code); + frame->f_funcobj = (PyObject *)func; + frame->f_code = (PyCodeObject *)Py_NewRef(code); frame->f_builtins = func->func_builtins; frame->f_globals = func->func_globals; - frame->f_locals = Py_XNewRef(locals); - frame->stacktop = nlocalsplus; + frame->f_locals = locals; + frame->stacktop = code->co_nlocalsplus; frame->frame_obj = NULL; - frame->prev_instr = _PyCode_CODE(frame->f_code) - 1; - frame->is_entry = false; + frame->prev_instr = _PyCode_CODE(code) - 1; + frame->return_offset = 0; frame->owner = FRAME_OWNED_BY_THREAD; + + for (int i = null_locals_from; i < code->co_nlocalsplus; i++) { + frame->localsplus[i] = NULL; + } } /* Gets the pointer to the locals array @@ -124,10 +143,16 @@ _PyFrame_GetLocalsArray(_PyInterpreterFrame *frame) return frame->localsplus; } +/* Fetches the stack pointer, and sets stacktop to -1. + Having stacktop <= 0 ensures that invalid + values are not visible to the cycle GC. + We choose -1 rather than 0 to assist debugging. */ static inline PyObject** _PyFrame_GetStackPointer(_PyInterpreterFrame *frame) { - return frame->localsplus+frame->stacktop; + PyObject **sp = frame->localsplus + frame->stacktop; + frame->stacktop = -1; + return sp; } static inline void @@ -151,6 +176,21 @@ _PyFrame_IsIncomplete(_PyInterpreterFrame *frame) frame->prev_instr < _PyCode_CODE(frame->f_code) + frame->f_code->_co_firsttraceable; } +static inline _PyInterpreterFrame * +_PyFrame_GetFirstComplete(_PyInterpreterFrame *frame) +{ + while (frame && _PyFrame_IsIncomplete(frame)) { + frame = frame->previous; + } + return frame; +} + +static inline _PyInterpreterFrame * +_PyThreadState_GetFrame(PyThreadState *tstate) +{ + return _PyFrame_GetFirstComplete(tstate->cframe->current_frame); +} + /* For use by _PyFrame_GetFrameObject Do not call directly. */ PyFrameObject * @@ -181,22 +221,22 @@ _PyFrame_GetFrameObject(_PyInterpreterFrame *frame) * frames like the ones in generators and coroutines. */ void -_PyFrame_Clear(_PyInterpreterFrame * frame); +_PyFrame_ClearExceptCode(_PyInterpreterFrame * frame); int _PyFrame_Traverse(_PyInterpreterFrame *frame, visitproc visit, void *arg); +PyObject * +_PyFrame_GetLocals(_PyInterpreterFrame *frame, int include_hidden); + int _PyFrame_FastToLocalsWithError(_PyInterpreterFrame *frame); void _PyFrame_LocalsToFast(_PyInterpreterFrame *frame, int clear); -extern _PyInterpreterFrame * -_PyThreadState_BumpFramePointerSlow(PyThreadState *tstate, size_t size); - static inline bool -_PyThreadState_HasStackSpace(PyThreadState *tstate, size_t size) +_PyThreadState_HasStackSpace(PyThreadState *tstate, int size) { assert( (tstate->datastack_top == NULL && tstate->datastack_limit == NULL) @@ -204,27 +244,28 @@ _PyThreadState_HasStackSpace(PyThreadState *tstate, size_t size) (tstate->datastack_top != NULL && tstate->datastack_limit != NULL) ); return tstate->datastack_top != NULL && - size < (size_t)(tstate->datastack_limit - tstate->datastack_top); + size < tstate->datastack_limit - tstate->datastack_top; } -static inline _PyInterpreterFrame * -_PyThreadState_BumpFramePointer(PyThreadState *tstate, size_t size) -{ - if (_PyThreadState_HasStackSpace(tstate, size)) { - _PyInterpreterFrame *res = (_PyInterpreterFrame *)tstate->datastack_top; - tstate->datastack_top += size; - return res; - } - return _PyThreadState_BumpFramePointerSlow(tstate, size); -} +extern _PyInterpreterFrame * +_PyThreadState_PushFrame(PyThreadState *tstate, size_t size); void _PyThreadState_PopFrame(PyThreadState *tstate, _PyInterpreterFrame *frame); -/* Consume reference to func */ -_PyInterpreterFrame * -_PyFrame_Push(PyThreadState *tstate, PyFunctionObject *func); - -int _PyInterpreterFrame_GetLine(_PyInterpreterFrame *frame); +/* Pushes a frame without checking for space. + * Must be guarded by _PyThreadState_HasStackSpace() + * Consumes reference to func. */ +static inline _PyInterpreterFrame * +_PyFrame_PushUnchecked(PyThreadState *tstate, PyFunctionObject *func, int null_locals_from) +{ + CALL_STAT_INC(frames_pushed); + PyCodeObject *code = (PyCodeObject *)func->func_code; + _PyInterpreterFrame *new_frame = (_PyInterpreterFrame *)tstate->datastack_top; + tstate->datastack_top += code->co_framesize; + assert(tstate->datastack_top < tstate->datastack_limit); + _PyFrame_Initialize(new_frame, func, NULL, code, null_locals_from); + return new_frame; +} static inline PyGenObject *_PyFrame_GetGenerator(_PyInterpreterFrame *frame) diff --git a/Include/internal/pycore_function.h b/Include/internal/pycore_function.h index 1c87aa31..ecbb7001 100644 --- a/Include/internal/pycore_function.h +++ b/Include/internal/pycore_function.h @@ -8,9 +8,17 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif +#define FUNC_MAX_WATCHERS 8 + +struct _py_func_state { + uint32_t next_version; +}; + extern PyFunctionObject* _PyFunction_FromConstructor(PyFrameConstructor *constr); extern uint32_t _PyFunction_GetVersionForCurrentState(PyFunctionObject *func); +extern PyObject *_Py_set_function_type_params( + PyThreadState* unused, PyObject *func, PyObject *type_params); #ifdef __cplusplus } diff --git a/Include/internal/pycore_gc.h b/Include/internal/pycore_gc.h index 16c18936..b3abe203 100644 --- a/Include/internal/pycore_gc.h +++ b/Include/internal/pycore_gc.h @@ -19,17 +19,29 @@ typedef struct { uintptr_t _gc_prev; } PyGC_Head; -#define _Py_AS_GC(o) ((PyGC_Head *)(o)-1) +static inline PyGC_Head* _Py_AS_GC(PyObject *op) { + return (_Py_CAST(PyGC_Head*, op) - 1); +} #define _PyGC_Head_UNUSED PyGC_Head /* True if the object is currently tracked by the GC. */ -#define _PyObject_GC_IS_TRACKED(o) (_Py_AS_GC(o)->_gc_next != 0) +static inline int _PyObject_GC_IS_TRACKED(PyObject *op) { + PyGC_Head *gc = _Py_AS_GC(op); + return (gc->_gc_next != 0); +} +#define _PyObject_GC_IS_TRACKED(op) _PyObject_GC_IS_TRACKED(_Py_CAST(PyObject*, op)) /* True if the object may be tracked by the GC in the future, or already is. This can be useful to implement some optimizations. */ -#define _PyObject_GC_MAY_BE_TRACKED(obj) \ - (PyObject_IS_GC(obj) && \ - (!PyTuple_CheckExact(obj) || _PyObject_GC_IS_TRACKED(obj))) +static inline int _PyObject_GC_MAY_BE_TRACKED(PyObject *obj) { + if (!PyObject_IS_GC(obj)) { + return 0; + } + if (PyTuple_CheckExact(obj)) { + return _PyObject_GC_IS_TRACKED(obj); + } + return 1; +} /* Bit flags for _gc_prev */ @@ -43,26 +55,40 @@ typedef struct { // Lowest bit of _gc_next is used for flags only in GC. // But it is always 0 for normal code. -#define _PyGCHead_NEXT(g) ((PyGC_Head*)(g)->_gc_next) -#define _PyGCHead_SET_NEXT(g, p) _Py_RVALUE((g)->_gc_next = (uintptr_t)(p)) +static inline PyGC_Head* _PyGCHead_NEXT(PyGC_Head *gc) { + uintptr_t next = gc->_gc_next; + return _Py_CAST(PyGC_Head*, next); +} +static inline void _PyGCHead_SET_NEXT(PyGC_Head *gc, PyGC_Head *next) { + gc->_gc_next = _Py_CAST(uintptr_t, next); +} // Lowest two bits of _gc_prev is used for _PyGC_PREV_MASK_* flags. -#define _PyGCHead_PREV(g) ((PyGC_Head*)((g)->_gc_prev & _PyGC_PREV_MASK)) -#define _PyGCHead_SET_PREV(g, p) do { \ - assert(((uintptr_t)p & ~_PyGC_PREV_MASK) == 0); \ - (g)->_gc_prev = ((g)->_gc_prev & ~_PyGC_PREV_MASK) \ - | ((uintptr_t)(p)); \ - } while (0) +static inline PyGC_Head* _PyGCHead_PREV(PyGC_Head *gc) { + uintptr_t prev = (gc->_gc_prev & _PyGC_PREV_MASK); + return _Py_CAST(PyGC_Head*, prev); +} +static inline void _PyGCHead_SET_PREV(PyGC_Head *gc, PyGC_Head *prev) { + uintptr_t uprev = _Py_CAST(uintptr_t, prev); + assert((uprev & ~_PyGC_PREV_MASK) == 0); + gc->_gc_prev = ((gc->_gc_prev & ~_PyGC_PREV_MASK) | uprev); +} -#define _PyGCHead_FINALIZED(g) \ - (((g)->_gc_prev & _PyGC_PREV_MASK_FINALIZED) != 0) -#define _PyGCHead_SET_FINALIZED(g) \ - _Py_RVALUE((g)->_gc_prev |= _PyGC_PREV_MASK_FINALIZED) +static inline int _PyGCHead_FINALIZED(PyGC_Head *gc) { + return ((gc->_gc_prev & _PyGC_PREV_MASK_FINALIZED) != 0); +} +static inline void _PyGCHead_SET_FINALIZED(PyGC_Head *gc) { + gc->_gc_prev |= _PyGC_PREV_MASK_FINALIZED; +} -#define _PyGC_FINALIZED(o) \ - _PyGCHead_FINALIZED(_Py_AS_GC(o)) -#define _PyGC_SET_FINALIZED(o) \ - _PyGCHead_SET_FINALIZED(_Py_AS_GC(o)) +static inline int _PyGC_FINALIZED(PyObject *op) { + PyGC_Head *gc = _Py_AS_GC(op); + return _PyGCHead_FINALIZED(gc); +} +static inline void _PyGC_SET_FINALIZED(PyObject *op) { + PyGC_Head *gc = _Py_AS_GC(op); + _PyGCHead_SET_FINALIZED(gc); +} /* GC runtime state */ @@ -176,6 +202,8 @@ extern void _PyList_ClearFreeList(PyInterpreterState *interp); extern void _PyDict_ClearFreeList(PyInterpreterState *interp); extern void _PyAsyncGen_ClearFreeLists(PyInterpreterState *interp); extern void _PyContext_ClearFreeList(PyInterpreterState *interp); +extern void _Py_ScheduleGC(PyInterpreterState *interp); +extern void _Py_RunGC(PyThreadState *tstate); #ifdef __cplusplus } diff --git a/Include/internal/pycore_genobject.h b/Include/internal/pycore_genobject.h index 42db0d87..dc60b4ca 100644 --- a/Include/internal/pycore_genobject.h +++ b/Include/internal/pycore_genobject.h @@ -10,7 +10,7 @@ extern "C" { extern PyObject *_PyGen_yf(PyGenObject *); extern PyObject *_PyCoro_GetAwaitableIter(PyObject *o); -extern PyObject *_PyAsyncGenValueWrapperNew(PyObject *); +extern PyObject *_PyAsyncGenValueWrapperNew(PyThreadState *state, PyObject *); /* runtime lifecycle */ diff --git a/Include/internal/pycore_global_objects.h b/Include/internal/pycore_global_objects.h index 98673d4e..5a3fb132 100644 --- a/Include/internal/pycore_global_objects.h +++ b/Include/internal/pycore_global_objects.h @@ -10,6 +10,9 @@ extern "C" { #include "pycore_gc.h" // PyGC_Head #include "pycore_global_strings.h" // struct _Py_global_strings +#include "pycore_hamt.h" // PyHamtNode_Bitmap +#include "pycore_context.h" // _PyContextTokenMissing +#include "pycore_typeobject.h" // pytype_slotdef // These would be in pycore_long.h if it weren't for an include cycle. @@ -21,11 +24,11 @@ extern "C" { // All others must be per-interpreter. #define _Py_GLOBAL_OBJECT(NAME) \ - _PyRuntime.global_objects.NAME + _PyRuntime.static_objects.NAME #define _Py_SINGLETON(NAME) \ _Py_GLOBAL_OBJECT(singletons.NAME) -struct _Py_global_objects { +struct _Py_static_objects { struct { /* Small integers are preallocated in this array so that they * can be shared. @@ -44,6 +47,48 @@ struct _Py_global_objects { _PyGC_Head_UNUSED _tuple_empty_gc_not_used; PyTupleObject tuple_empty; + + _PyGC_Head_UNUSED _hamt_bitmap_node_empty_gc_not_used; + PyHamtNode_Bitmap hamt_bitmap_node_empty; + _PyContextTokenMissing context_token_missing; + } singletons; +}; + +#define _Py_INTERP_CACHED_OBJECT(interp, NAME) \ + (interp)->cached_objects.NAME + +struct _Py_interp_cached_objects { + PyObject *interned_strings; + + /* AST */ + PyObject *str_replace_inf; + + /* object.__reduce__ */ + PyObject *objreduce; + PyObject *type_slots_pname; + pytype_slotdef *type_slots_ptrs[MAX_EQUIV]; + + /* TypeVar and related types */ + PyTypeObject *generic_type; + PyTypeObject *typevar_type; + PyTypeObject *typevartuple_type; + PyTypeObject *paramspec_type; + PyTypeObject *paramspecargs_type; + PyTypeObject *paramspeckwargs_type; +}; + +#define _Py_INTERP_STATIC_OBJECT(interp, NAME) \ + (interp)->static_objects.NAME +#define _Py_INTERP_SINGLETON(interp, NAME) \ + _Py_INTERP_STATIC_OBJECT(interp, singletons.NAME) + +struct _Py_interp_static_objects { + struct { + int _not_used; + // hamt_empty is here instead of global because of its weakreflist. + _PyGC_Head_UNUSED _hamt_empty_gc_not_used; + PyHamtObject hamt_empty; + PyBaseExceptionObject last_resort_memory_error; } singletons; }; diff --git a/Include/internal/pycore_global_objects_fini_generated.h b/Include/internal/pycore_global_objects_fini_generated.h new file mode 100644 index 00000000..439f47a2 --- /dev/null +++ b/Include/internal/pycore_global_objects_fini_generated.h @@ -0,0 +1,1531 @@ +#ifndef Py_INTERNAL_GLOBAL_OBJECTS_FINI_GENERATED_INIT_H +#define Py_INTERNAL_GLOBAL_OBJECTS_FINI_GENERATED_INIT_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +#ifdef Py_DEBUG +static inline void +_PyStaticObject_CheckRefcnt(PyObject *obj) { + if (Py_REFCNT(obj) < _Py_IMMORTAL_REFCNT) { + fprintf(stderr, "Immortal Object has less refcnt than expected.\n"); + _PyObject_Dump(obj); + } +} +#endif + +/* The following is auto-generated by Tools/build/generate_global_objects.py. */ +#ifdef Py_DEBUG +static inline void +_PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) { + /* generated runtime-global */ + // (see pycore_runtime_init_generated.h) + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + -5]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + -4]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + -3]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + -2]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + -1]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 0]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 1]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 2]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 3]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 4]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 5]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 6]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 7]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 8]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 9]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 10]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 11]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 12]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 13]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 14]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 15]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 16]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 17]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 18]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 19]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 20]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 21]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 22]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 23]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 24]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 25]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 26]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 27]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 28]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 29]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 30]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 31]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 32]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 33]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 34]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 35]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 36]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 37]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 38]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 39]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 40]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 41]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 42]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 43]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 44]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 45]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 46]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 47]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 48]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 49]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 50]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 51]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 52]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 53]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 54]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 55]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 56]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 57]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 58]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 59]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 60]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 61]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 62]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 63]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 64]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 65]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 66]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 67]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 68]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 69]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 70]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 71]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 72]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 73]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 74]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 75]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 76]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 77]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 78]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 79]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 80]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 81]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 82]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 83]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 84]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 85]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 86]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 87]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 88]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 89]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 90]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 91]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 92]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 93]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 94]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 95]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 96]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 97]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 98]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 99]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 100]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 101]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 102]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 103]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 104]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 105]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 106]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 107]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 108]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 109]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 110]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 111]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 112]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 113]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 114]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 115]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 116]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 117]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 118]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 119]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 120]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 121]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 122]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 123]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 124]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 125]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 126]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 127]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 129]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 130]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 131]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 132]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 133]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 134]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 135]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 136]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 137]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 138]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 139]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 140]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 141]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 142]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 143]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 144]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 145]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 146]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 147]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 148]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 149]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 150]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 151]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 152]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 153]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 154]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 155]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 156]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 157]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 158]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 159]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 160]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 161]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 162]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 163]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 164]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 165]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 166]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 167]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 168]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 169]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 170]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 171]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 172]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 173]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 174]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 175]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 176]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 177]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 178]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 179]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 180]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 181]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 182]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 183]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 184]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 185]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 186]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 187]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 188]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 189]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 190]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 191]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 192]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 193]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 194]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 195]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 196]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 197]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 198]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 199]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 200]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 201]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 202]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 203]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 204]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 205]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 206]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 207]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 208]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 209]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 210]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 211]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 212]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 213]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 214]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 215]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 216]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 217]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 218]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 219]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 220]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 221]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 222]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 223]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 224]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 225]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 226]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 227]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 228]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 229]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 230]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 231]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 232]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 233]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 234]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 235]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 236]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 237]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 238]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 239]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 240]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 241]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 242]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 243]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 244]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 245]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 246]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 247]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 248]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 249]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 250]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 251]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 252]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 253]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 254]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 255]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + 256]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[0]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[1]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[2]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[3]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[4]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[5]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[6]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[7]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[8]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[9]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[10]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[11]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[12]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[13]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[14]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[15]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[16]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[17]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[18]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[19]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[20]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[21]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[22]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[23]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[24]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[25]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[26]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[27]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[28]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[29]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[30]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[31]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[32]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[33]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[34]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[35]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[36]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[37]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[38]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[39]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[40]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[41]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[42]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[43]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[44]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[45]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[46]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[47]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[48]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[49]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[50]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[51]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[52]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[53]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[54]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[55]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[56]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[57]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[58]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[59]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[60]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[61]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[62]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[63]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[64]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[65]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[66]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[67]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[68]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[69]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[70]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[71]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[72]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[73]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[74]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[75]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[76]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[77]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[78]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[79]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[80]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[81]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[82]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[83]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[84]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[85]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[86]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[87]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[88]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[89]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[90]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[91]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[92]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[93]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[94]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[95]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[96]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[97]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[98]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[99]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[100]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[101]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[102]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[103]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[104]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[105]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[106]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[107]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[108]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[109]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[110]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[111]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[112]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[113]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[114]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[115]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[116]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[117]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[118]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[119]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[120]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[121]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[122]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[123]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[124]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[125]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[126]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[127]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[129]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[130]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[131]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[132]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[133]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[134]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[135]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[136]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[137]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[138]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[139]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[140]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[141]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[142]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[143]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[144]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[145]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[146]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[147]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[148]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[149]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[150]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[151]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[152]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[153]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[154]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[155]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[156]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[157]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[158]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[159]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[160]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[161]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[162]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[163]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[164]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[165]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[166]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[167]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[168]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[169]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[170]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[171]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[172]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[173]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[174]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[175]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[176]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[177]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[178]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[179]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[180]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[181]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[182]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[183]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[184]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[185]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[186]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[187]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[188]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[189]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[190]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[191]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[192]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[193]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[194]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[195]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[196]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[197]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[198]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[199]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[200]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[201]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[202]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[203]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[204]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[205]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[206]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[207]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[208]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[209]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[210]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[211]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[212]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[213]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[214]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[215]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[216]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[217]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[218]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[219]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[220]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[221]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[222]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[223]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[224]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[225]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[226]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[227]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[228]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[229]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[230]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[231]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[232]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[233]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[234]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[235]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[236]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[237]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[238]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[239]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[240]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[241]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[242]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[243]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[244]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[245]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[246]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[247]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[248]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[249]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[250]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[251]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[252]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[253]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[254]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_characters)[255]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(anon_dictcomp)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(anon_genexpr)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(anon_lambda)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(anon_listcomp)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(anon_module)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(anon_setcomp)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(anon_string)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(anon_unknown)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(close_br)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(dbl_close_br)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(dbl_open_br)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(dbl_percent)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(defaults)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(dot)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(dot_locals)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(empty)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(generic_base)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(json_decoder)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(kwdefaults)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(list_err)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(newline)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(open_br)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(percent)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(shim_name)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(type_params)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(utf_8)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(CANCELLED)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(FINISHED)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(False)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(JSONDecodeError)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(PENDING)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(Py_Repr)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(TextIOWrapper)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(True)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(WarningMessage)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_WindowsConsoleIO)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__IOBase_closed)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__abc_tpflags__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__abs__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__abstractmethods__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__add__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__aenter__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__aexit__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__aiter__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__all__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__and__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__anext__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__annotations__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__args__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__asyncio_running_event_loop__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__await__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__bases__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__bool__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__buffer__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__build_class__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__builtins__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__bytes__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__call__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__cantrace__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__class__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__class_getitem__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__classcell__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__classdict__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__classdictcell__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__complex__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__contains__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__copy__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__ctypes_from_outparam__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__del__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__delattr__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__delete__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__delitem__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__dict__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__dictoffset__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__dir__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__divmod__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__doc__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__enter__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__eq__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__exit__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__file__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__float__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__floordiv__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__format__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__fspath__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__ge__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__get__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__getattr__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__getattribute__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__getinitargs__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__getitem__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__getnewargs__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__getnewargs_ex__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__getstate__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__gt__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__hash__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__iadd__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__iand__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__ifloordiv__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__ilshift__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__imatmul__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__imod__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__import__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__imul__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__index__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__init__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__init_subclass__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__instancecheck__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__int__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__invert__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__ior__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__ipow__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__irshift__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__isabstractmethod__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__isub__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__iter__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__itruediv__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__ixor__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__le__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__len__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__length_hint__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__lltrace__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__loader__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__lshift__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__lt__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__main__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__matmul__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__missing__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__mod__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__module__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__mro_entries__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__mul__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__name__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__ne__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__neg__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__new__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__newobj__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__newobj_ex__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__next__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__notes__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__or__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__orig_class__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__origin__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__package__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__parameters__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__path__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__pos__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__pow__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__prepare__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__qualname__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__radd__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__rand__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__rdivmod__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__reduce__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__reduce_ex__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__release_buffer__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__repr__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__reversed__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__rfloordiv__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__rlshift__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__rmatmul__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__rmod__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__rmul__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__ror__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__round__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__rpow__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__rrshift__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__rshift__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__rsub__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__rtruediv__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__rxor__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__set__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__set_name__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__setattr__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__setitem__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__setstate__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__sizeof__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__slotnames__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__slots__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__spec__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__str__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__sub__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__subclasscheck__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__subclasshook__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__truediv__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__trunc__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__type_params__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__typing_is_unpacked_typevartuple__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__typing_prepare_subst__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__typing_subst__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__typing_unpacked_tuple_args__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__warningregistry__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__weaklistoffset__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__weakref__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__xor__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_abc_impl)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_abstract_)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_active)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_annotation)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_anonymous_)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_argtypes_)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_as_parameter_)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_asyncio_future_blocking)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_blksize)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_bootstrap)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_check_retval_)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_dealloc_warn)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_feature_version)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_fields_)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_finalizing)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_find_and_load)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_fix_up_module)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_flags_)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_get_sourcefile)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_handle_fromlist)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_initializing)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_io)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_is_text_encoding)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_length_)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_limbo)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_lock_unlock_module)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_loop)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_needs_com_addref_)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_pack_)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_restype_)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_showwarnmsg)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_shutdown)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_slotnames)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_strptime_datetime)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_swappedbytes_)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_type_)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_uninitialized_submodules)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_warn_unawaited_coroutine)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(_xoptions)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(a)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(abs_tol)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(access)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(add)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(add_done_callback)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(after_in_child)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(after_in_parent)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(aggregate_class)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(alias)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(append)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(arg)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(argdefs)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(args)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(arguments)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(argv)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(as_integer_ratio)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(ast)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(attribute)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(authorizer_callback)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(autocommit)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(b)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(backtick)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(base)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(before)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(big)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(binary_form)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(block)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(bound)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(buffer)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(buffer_callback)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(buffer_size)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(buffering)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(buffers)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(bufsize)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(builtins)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(byteorder)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(bytes)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(bytes_per_sep)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(c)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(c_call)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(c_exception)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(c_return)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(cached_statements)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(cadata)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(cafile)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(call)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(call_exception_handler)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(call_soon)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(cancel)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(capath)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(category)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(cb_type)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(certfile)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(check_same_thread)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(clear)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(close)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(closed)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(closefd)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(closure)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(co_argcount)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(co_cellvars)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(co_code)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(co_consts)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(co_exceptiontable)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(co_filename)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(co_firstlineno)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(co_flags)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(co_freevars)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(co_kwonlyargcount)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(co_linetable)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(co_name)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(co_names)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(co_nlocals)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(co_posonlyargcount)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(co_qualname)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(co_stacksize)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(co_varnames)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(code)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(command)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(comment_factory)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(compile_mode)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(consts)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(context)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(contravariant)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(cookie)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(copy)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(copyreg)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(coro)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(count)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(covariant)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(cwd)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(d)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(data)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(database)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(decode)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(decoder)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(default)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(defaultaction)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(delete)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(depth)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(detect_types)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(deterministic)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(device)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(dict)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(dictcomp)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(difference_update)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(digest)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(digest_size)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(digestmod)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(dir_fd)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(discard)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(dispatch_table)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(displayhook)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(dklen)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(doc)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(dont_inherit)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(dst)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(dst_dir_fd)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(duration)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(e)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(eager_start)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(effective_ids)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(element_factory)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(encode)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(encoding)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(end)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(end_lineno)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(end_offset)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(endpos)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(entrypoint)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(env)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(errors)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(event)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(eventmask)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(exc_type)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(exc_value)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(excepthook)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(exception)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(existing_file_name)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(exp)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(extend)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(extra_tokens)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(facility)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(factory)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(false)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(family)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(fanout)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(fd)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(fd2)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(fdel)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(fget)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(file)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(file_actions)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(filename)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(fileno)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(filepath)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(fillvalue)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(filters)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(final)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(find_class)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(fix_imports)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(flags)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(flush)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(follow_symlinks)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(format)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(frequency)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(from_param)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(fromlist)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(fromtimestamp)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(fromutc)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(fset)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(func)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(future)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(generation)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(genexpr)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(get)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(get_debug)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(get_event_loop)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(get_loop)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(get_source)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(getattr)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(getstate)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(gid)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(globals)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(groupindex)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(groups)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(handle)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(hash_name)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(header)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(headers)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(hi)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(hook)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(id)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(ident)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(ignore)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(imag)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(importlib)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(in_fd)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(incoming)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(indexgroup)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(inf)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(infer_variance)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(inheritable)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(initial)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(initial_bytes)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(initial_value)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(initval)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(inner_size)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(input)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(insert_comments)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(insert_pis)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(instructions)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(intern)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(intersection)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(is_running)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(isatty)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(isinstance)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(isoformat)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(isolation_level)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(istext)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(item)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(items)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(iter)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(iterable)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(iterations)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(join)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(jump)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(keepends)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(key)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(keyfile)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(keys)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(kind)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(kw)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(kw1)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(kw2)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(lambda)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(last)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(last_exc)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(last_node)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(last_traceback)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(last_type)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(last_value)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(latin1)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(leaf_size)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(len)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(length)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(level)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(limit)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(line)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(line_buffering)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(lineno)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(listcomp)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(little)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(lo)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(locale)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(locals)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(logoption)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(loop)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(mapping)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(match)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(max_length)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(maxdigits)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(maxevents)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(maxmem)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(maxsplit)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(maxvalue)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(memLevel)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(memlimit)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(message)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(metaclass)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(metadata)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(method)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(mod)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(mode)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(module)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(module_globals)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(modules)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(mro)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(msg)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(mycmp)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(n)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(n_arg)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(n_fields)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(n_sequence_fields)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(n_unnamed_fields)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(name)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(name_from)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(namespace_separator)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(namespaces)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(narg)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(ndigits)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(new_file_name)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(new_limit)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(newline)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(newlines)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(next)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(nlocals)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(node_depth)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(node_offset)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(ns)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(nstype)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(nt)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(null)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(number)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(obj)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(object)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(offset)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(offset_dst)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(offset_src)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(on_type_read)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(onceregistry)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(only_keys)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(oparg)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(opcode)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(open)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(opener)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(operation)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(optimize)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(options)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(order)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(origin)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(out_fd)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(outgoing)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(overlapped)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(owner)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(p)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(pages)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(parent)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(password)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(path)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(pattern)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(peek)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(persistent_id)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(persistent_load)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(person)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(pi_factory)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(pid)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(policy)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(pos)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(pos1)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(pos2)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(posix)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(print_file_and_line)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(priority)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(progress)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(progress_handler)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(progress_routine)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(proto)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(protocol)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(ps1)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(ps2)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(query)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(quotetabs)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(r)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(raw)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(read)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(read1)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(readable)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(readall)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(readinto)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(readinto1)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(readline)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(readonly)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(real)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(reducer_override)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(registry)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(rel_tol)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(release)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(reload)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(repl)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(replace)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(reserved)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(reset)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(resetids)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(return)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(reverse)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(reversed)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(s)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(salt)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(sched_priority)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(scheduler)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(seek)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(seekable)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(selectors)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(self)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(send)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(sep)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(sequence)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(server_hostname)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(server_side)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(session)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(setcomp)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(setpgroup)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(setsid)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(setsigdef)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(setsigmask)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(setstate)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(shape)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(show_cmd)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(signed)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(size)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(sizehint)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(skip_file_prefixes)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(sleep)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(sock)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(sort)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(sound)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(source)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(source_traceback)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(src)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(src_dir_fd)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(stacklevel)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(start)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(statement)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(status)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(stderr)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(stdin)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(stdout)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(step)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(steps)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(store_name)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(strategy)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(strftime)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(strict)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(strict_mode)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(string)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(sub_key)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(symmetric_difference_update)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(tabsize)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(tag)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(target)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(target_is_directory)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(task)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(tb_frame)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(tb_lasti)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(tb_lineno)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(tb_next)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(tell)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(template)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(term)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(text)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(threading)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(throw)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(timeout)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(times)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(timetuple)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(top)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(trace_callback)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(traceback)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(trailers)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(translate)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(true)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(truncate)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(twice)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(txt)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(type)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(type_params)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(tz)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(tzname)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(uid)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(unlink)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(unraisablehook)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(uri)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(usedforsecurity)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(value)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(values)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(version)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(volume)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(warnings)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(warnoptions)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(wbits)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(week)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(weekday)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(which)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(who)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(withdata)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(writable)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(write)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(write_through)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(x)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(year)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(zdict)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[0]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[1]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[2]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[3]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[4]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[5]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[6]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[7]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[8]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[9]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[10]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[11]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[12]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[13]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[14]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[15]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[16]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[17]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[18]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[19]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[20]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[21]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[22]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[23]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[24]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[25]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[26]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[27]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[28]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[29]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[30]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[31]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[32]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[33]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[34]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[35]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[36]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[37]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[38]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[39]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[40]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[41]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[42]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[43]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[44]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[45]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[46]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[47]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[48]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[49]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[50]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[51]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[52]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[53]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[54]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[55]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[56]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[57]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[58]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[59]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[60]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[61]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[62]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[63]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[64]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[65]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[66]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[67]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[68]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[69]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[70]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[71]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[72]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[73]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[74]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[75]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[76]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[77]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[78]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[79]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[80]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[81]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[82]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[83]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[84]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[85]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[86]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[87]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[88]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[89]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[90]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[91]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[92]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[93]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[94]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[95]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[96]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[97]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[98]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[99]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[100]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[101]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[102]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[103]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[104]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[105]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[106]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[107]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[108]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[109]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[110]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[111]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[112]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[113]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[114]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[115]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[116]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[117]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[118]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[119]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[120]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[121]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[122]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[123]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[124]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[125]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[126]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).ascii[127]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[128 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[129 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[130 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[131 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[132 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[133 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[134 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[135 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[136 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[137 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[138 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[139 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[140 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[141 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[142 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[143 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[144 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[145 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[146 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[147 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[148 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[149 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[150 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[151 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[152 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[153 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[154 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[155 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[156 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[157 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[158 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[159 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[160 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[161 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[162 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[163 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[164 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[165 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[166 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[167 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[168 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[169 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[170 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[171 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[172 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[173 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[174 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[175 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[176 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[177 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[178 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[179 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[180 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[181 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[182 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[183 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[184 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[185 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[186 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[187 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[188 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[189 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[190 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[191 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[192 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[193 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[194 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[195 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[196 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[197 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[198 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[199 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[200 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[201 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[202 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[203 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[204 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[205 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[206 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[207 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[208 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[209 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[210 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[211 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[212 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[213 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[214 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[215 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[216 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[217 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[218 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[219 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[220 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[221 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[222 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[223 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[224 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[225 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[226 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[227 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[228 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[229 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[230 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[231 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[232 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[233 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[234 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[235 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[236 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[237 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[238 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[239 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[240 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[241 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[242 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[243 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[244 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[245 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[246 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[247 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[248 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[249 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[250 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[251 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[252 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[253 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[254 - 128]); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(strings).latin1[255 - 128]); + /* non-generated */ + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(bytes_empty)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(tuple_empty)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(hamt_bitmap_node_empty)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_INTERP_SINGLETON(interp, hamt_empty)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_SINGLETON(context_token_missing)); +} +#endif // Py_DEBUG +/* End auto-generated code */ + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_GLOBAL_OBJECTS_FINI_GENERATED_INIT_H */ diff --git a/Include/internal/pycore_global_strings.h b/Include/internal/pycore_global_strings.h index ca970627..0c84999c 100644 --- a/Include/internal/pycore_global_strings.h +++ b/Include/internal/pycore_global_strings.h @@ -8,10 +8,10 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif -// The data structure & init here are inspired by Tools/scripts/deepfreeze.py. +// The data structure & init here are inspired by Tools/build/deepfreeze.py. // All field names generated by ASCII_STR() have a common prefix, -// to help avoid collisions with keywords, etc. +// to help avoid collisions with keywords, macros, etc. #define STRUCT_FOR_ASCII_STR(LITERAL) \ struct { \ @@ -19,13 +19,13 @@ extern "C" { uint8_t _data[sizeof(LITERAL)]; \ } #define STRUCT_FOR_STR(NAME, LITERAL) \ - STRUCT_FOR_ASCII_STR(LITERAL) _ ## NAME; + STRUCT_FOR_ASCII_STR(LITERAL) _py_ ## NAME; #define STRUCT_FOR_ID(NAME) \ - STRUCT_FOR_ASCII_STR(#NAME) _ ## NAME; + STRUCT_FOR_ASCII_STR(#NAME) _py_ ## NAME; // XXX Order by frequency of use? -/* The following is auto-generated by Tools/scripts/generate_global_objects.py. */ +/* The following is auto-generated by Tools/build/generate_global_objects.py. */ struct _Py_global_strings { struct { STRUCT_FOR_STR(anon_dictcomp, "<dictcomp>") @@ -37,27 +37,37 @@ struct _Py_global_strings { STRUCT_FOR_STR(anon_string, "<string>") STRUCT_FOR_STR(anon_unknown, "<unknown>") STRUCT_FOR_STR(close_br, "}") - STRUCT_FOR_STR(comma_sep, ", ") STRUCT_FOR_STR(dbl_close_br, "}}") STRUCT_FOR_STR(dbl_open_br, "{{") STRUCT_FOR_STR(dbl_percent, "%%") + STRUCT_FOR_STR(defaults, ".defaults") STRUCT_FOR_STR(dot, ".") STRUCT_FOR_STR(dot_locals, ".<locals>") STRUCT_FOR_STR(empty, "") + STRUCT_FOR_STR(generic_base, ".generic_base") + STRUCT_FOR_STR(json_decoder, "json.decoder") + STRUCT_FOR_STR(kwdefaults, ".kwdefaults") STRUCT_FOR_STR(list_err, "list index out of range") STRUCT_FOR_STR(newline, "\n") STRUCT_FOR_STR(open_br, "{") STRUCT_FOR_STR(percent, "%") + STRUCT_FOR_STR(shim_name, "<shim>") + STRUCT_FOR_STR(type_params, ".type_params") STRUCT_FOR_STR(utf_8, "utf-8") } literals; struct { + STRUCT_FOR_ID(CANCELLED) + STRUCT_FOR_ID(FINISHED) STRUCT_FOR_ID(False) + STRUCT_FOR_ID(JSONDecodeError) + STRUCT_FOR_ID(PENDING) STRUCT_FOR_ID(Py_Repr) STRUCT_FOR_ID(TextIOWrapper) STRUCT_FOR_ID(True) STRUCT_FOR_ID(WarningMessage) STRUCT_FOR_ID(_) + STRUCT_FOR_ID(_WindowsConsoleIO) STRUCT_FOR_ID(__IOBase_closed) STRUCT_FOR_ID(__abc_tpflags__) STRUCT_FOR_ID(__abs__) @@ -71,9 +81,11 @@ struct _Py_global_strings { STRUCT_FOR_ID(__anext__) STRUCT_FOR_ID(__annotations__) STRUCT_FOR_ID(__args__) + STRUCT_FOR_ID(__asyncio_running_event_loop__) STRUCT_FOR_ID(__await__) STRUCT_FOR_ID(__bases__) STRUCT_FOR_ID(__bool__) + STRUCT_FOR_ID(__buffer__) STRUCT_FOR_ID(__build_class__) STRUCT_FOR_ID(__builtins__) STRUCT_FOR_ID(__bytes__) @@ -82,14 +94,18 @@ struct _Py_global_strings { STRUCT_FOR_ID(__class__) STRUCT_FOR_ID(__class_getitem__) STRUCT_FOR_ID(__classcell__) + STRUCT_FOR_ID(__classdict__) + STRUCT_FOR_ID(__classdictcell__) STRUCT_FOR_ID(__complex__) STRUCT_FOR_ID(__contains__) STRUCT_FOR_ID(__copy__) + STRUCT_FOR_ID(__ctypes_from_outparam__) STRUCT_FOR_ID(__del__) STRUCT_FOR_ID(__delattr__) STRUCT_FOR_ID(__delete__) STRUCT_FOR_ID(__delitem__) STRUCT_FOR_ID(__dict__) + STRUCT_FOR_ID(__dictoffset__) STRUCT_FOR_ID(__dir__) STRUCT_FOR_ID(__divmod__) STRUCT_FOR_ID(__doc__) @@ -171,6 +187,7 @@ struct _Py_global_strings { STRUCT_FOR_ID(__rdivmod__) STRUCT_FOR_ID(__reduce__) STRUCT_FOR_ID(__reduce_ex__) + STRUCT_FOR_ID(__release_buffer__) STRUCT_FOR_ID(__repr__) STRUCT_FOR_ID(__reversed__) STRUCT_FOR_ID(__rfloordiv__) @@ -201,122 +218,408 @@ struct _Py_global_strings { STRUCT_FOR_ID(__subclasshook__) STRUCT_FOR_ID(__truediv__) STRUCT_FOR_ID(__trunc__) + STRUCT_FOR_ID(__type_params__) STRUCT_FOR_ID(__typing_is_unpacked_typevartuple__) STRUCT_FOR_ID(__typing_prepare_subst__) STRUCT_FOR_ID(__typing_subst__) STRUCT_FOR_ID(__typing_unpacked_tuple_args__) STRUCT_FOR_ID(__warningregistry__) + STRUCT_FOR_ID(__weaklistoffset__) STRUCT_FOR_ID(__weakref__) STRUCT_FOR_ID(__xor__) STRUCT_FOR_ID(_abc_impl) + STRUCT_FOR_ID(_abstract_) + STRUCT_FOR_ID(_active) STRUCT_FOR_ID(_annotation) + STRUCT_FOR_ID(_anonymous_) + STRUCT_FOR_ID(_argtypes_) + STRUCT_FOR_ID(_as_parameter_) + STRUCT_FOR_ID(_asyncio_future_blocking) STRUCT_FOR_ID(_blksize) STRUCT_FOR_ID(_bootstrap) + STRUCT_FOR_ID(_check_retval_) STRUCT_FOR_ID(_dealloc_warn) + STRUCT_FOR_ID(_feature_version) + STRUCT_FOR_ID(_fields_) STRUCT_FOR_ID(_finalizing) STRUCT_FOR_ID(_find_and_load) STRUCT_FOR_ID(_fix_up_module) + STRUCT_FOR_ID(_flags_) STRUCT_FOR_ID(_get_sourcefile) STRUCT_FOR_ID(_handle_fromlist) STRUCT_FOR_ID(_initializing) + STRUCT_FOR_ID(_io) STRUCT_FOR_ID(_is_text_encoding) + STRUCT_FOR_ID(_length_) + STRUCT_FOR_ID(_limbo) STRUCT_FOR_ID(_lock_unlock_module) + STRUCT_FOR_ID(_loop) + STRUCT_FOR_ID(_needs_com_addref_) + STRUCT_FOR_ID(_pack_) + STRUCT_FOR_ID(_restype_) STRUCT_FOR_ID(_showwarnmsg) STRUCT_FOR_ID(_shutdown) STRUCT_FOR_ID(_slotnames) - STRUCT_FOR_ID(_strptime_time) + STRUCT_FOR_ID(_strptime_datetime) + STRUCT_FOR_ID(_swappedbytes_) + STRUCT_FOR_ID(_type_) STRUCT_FOR_ID(_uninitialized_submodules) STRUCT_FOR_ID(_warn_unawaited_coroutine) STRUCT_FOR_ID(_xoptions) + STRUCT_FOR_ID(a) + STRUCT_FOR_ID(abs_tol) + STRUCT_FOR_ID(access) STRUCT_FOR_ID(add) + STRUCT_FOR_ID(add_done_callback) + STRUCT_FOR_ID(after_in_child) + STRUCT_FOR_ID(after_in_parent) + STRUCT_FOR_ID(aggregate_class) + STRUCT_FOR_ID(alias) STRUCT_FOR_ID(append) + STRUCT_FOR_ID(arg) + STRUCT_FOR_ID(argdefs) + STRUCT_FOR_ID(args) + STRUCT_FOR_ID(arguments) + STRUCT_FOR_ID(argv) + STRUCT_FOR_ID(as_integer_ratio) + STRUCT_FOR_ID(ast) + STRUCT_FOR_ID(attribute) + STRUCT_FOR_ID(authorizer_callback) + STRUCT_FOR_ID(autocommit) + STRUCT_FOR_ID(b) + STRUCT_FOR_ID(backtick) + STRUCT_FOR_ID(base) + STRUCT_FOR_ID(before) STRUCT_FOR_ID(big) + STRUCT_FOR_ID(binary_form) + STRUCT_FOR_ID(block) + STRUCT_FOR_ID(bound) STRUCT_FOR_ID(buffer) + STRUCT_FOR_ID(buffer_callback) + STRUCT_FOR_ID(buffer_size) + STRUCT_FOR_ID(buffering) + STRUCT_FOR_ID(buffers) + STRUCT_FOR_ID(bufsize) STRUCT_FOR_ID(builtins) + STRUCT_FOR_ID(byteorder) + STRUCT_FOR_ID(bytes) + STRUCT_FOR_ID(bytes_per_sep) + STRUCT_FOR_ID(c) STRUCT_FOR_ID(c_call) STRUCT_FOR_ID(c_exception) STRUCT_FOR_ID(c_return) + STRUCT_FOR_ID(cached_statements) + STRUCT_FOR_ID(cadata) + STRUCT_FOR_ID(cafile) STRUCT_FOR_ID(call) + STRUCT_FOR_ID(call_exception_handler) + STRUCT_FOR_ID(call_soon) + STRUCT_FOR_ID(cancel) + STRUCT_FOR_ID(capath) + STRUCT_FOR_ID(category) + STRUCT_FOR_ID(cb_type) + STRUCT_FOR_ID(certfile) + STRUCT_FOR_ID(check_same_thread) STRUCT_FOR_ID(clear) STRUCT_FOR_ID(close) STRUCT_FOR_ID(closed) + STRUCT_FOR_ID(closefd) + STRUCT_FOR_ID(closure) + STRUCT_FOR_ID(co_argcount) + STRUCT_FOR_ID(co_cellvars) + STRUCT_FOR_ID(co_code) + STRUCT_FOR_ID(co_consts) + STRUCT_FOR_ID(co_exceptiontable) + STRUCT_FOR_ID(co_filename) + STRUCT_FOR_ID(co_firstlineno) + STRUCT_FOR_ID(co_flags) + STRUCT_FOR_ID(co_freevars) + STRUCT_FOR_ID(co_kwonlyargcount) + STRUCT_FOR_ID(co_linetable) + STRUCT_FOR_ID(co_name) + STRUCT_FOR_ID(co_names) + STRUCT_FOR_ID(co_nlocals) + STRUCT_FOR_ID(co_posonlyargcount) + STRUCT_FOR_ID(co_qualname) + STRUCT_FOR_ID(co_stacksize) + STRUCT_FOR_ID(co_varnames) STRUCT_FOR_ID(code) + STRUCT_FOR_ID(command) + STRUCT_FOR_ID(comment_factory) + STRUCT_FOR_ID(compile_mode) + STRUCT_FOR_ID(consts) + STRUCT_FOR_ID(context) + STRUCT_FOR_ID(contravariant) + STRUCT_FOR_ID(cookie) STRUCT_FOR_ID(copy) STRUCT_FOR_ID(copyreg) + STRUCT_FOR_ID(coro) + STRUCT_FOR_ID(count) + STRUCT_FOR_ID(covariant) + STRUCT_FOR_ID(cwd) + STRUCT_FOR_ID(d) + STRUCT_FOR_ID(data) + STRUCT_FOR_ID(database) STRUCT_FOR_ID(decode) + STRUCT_FOR_ID(decoder) STRUCT_FOR_ID(default) STRUCT_FOR_ID(defaultaction) + STRUCT_FOR_ID(delete) + STRUCT_FOR_ID(depth) + STRUCT_FOR_ID(detect_types) + STRUCT_FOR_ID(deterministic) + STRUCT_FOR_ID(device) + STRUCT_FOR_ID(dict) STRUCT_FOR_ID(dictcomp) STRUCT_FOR_ID(difference_update) + STRUCT_FOR_ID(digest) + STRUCT_FOR_ID(digest_size) + STRUCT_FOR_ID(digestmod) + STRUCT_FOR_ID(dir_fd) + STRUCT_FOR_ID(discard) STRUCT_FOR_ID(dispatch_table) STRUCT_FOR_ID(displayhook) - STRUCT_FOR_ID(enable) + STRUCT_FOR_ID(dklen) + STRUCT_FOR_ID(doc) + STRUCT_FOR_ID(dont_inherit) + STRUCT_FOR_ID(dst) + STRUCT_FOR_ID(dst_dir_fd) + STRUCT_FOR_ID(duration) + STRUCT_FOR_ID(e) + STRUCT_FOR_ID(eager_start) + STRUCT_FOR_ID(effective_ids) + STRUCT_FOR_ID(element_factory) STRUCT_FOR_ID(encode) STRUCT_FOR_ID(encoding) + STRUCT_FOR_ID(end) STRUCT_FOR_ID(end_lineno) STRUCT_FOR_ID(end_offset) + STRUCT_FOR_ID(endpos) + STRUCT_FOR_ID(entrypoint) + STRUCT_FOR_ID(env) STRUCT_FOR_ID(errors) + STRUCT_FOR_ID(event) + STRUCT_FOR_ID(eventmask) + STRUCT_FOR_ID(exc_type) + STRUCT_FOR_ID(exc_value) STRUCT_FOR_ID(excepthook) STRUCT_FOR_ID(exception) + STRUCT_FOR_ID(existing_file_name) + STRUCT_FOR_ID(exp) STRUCT_FOR_ID(extend) + STRUCT_FOR_ID(extra_tokens) + STRUCT_FOR_ID(facility) + STRUCT_FOR_ID(factory) + STRUCT_FOR_ID(false) + STRUCT_FOR_ID(family) + STRUCT_FOR_ID(fanout) + STRUCT_FOR_ID(fd) + STRUCT_FOR_ID(fd2) + STRUCT_FOR_ID(fdel) + STRUCT_FOR_ID(fget) + STRUCT_FOR_ID(file) + STRUCT_FOR_ID(file_actions) STRUCT_FOR_ID(filename) STRUCT_FOR_ID(fileno) + STRUCT_FOR_ID(filepath) STRUCT_FOR_ID(fillvalue) STRUCT_FOR_ID(filters) + STRUCT_FOR_ID(final) STRUCT_FOR_ID(find_class) + STRUCT_FOR_ID(fix_imports) + STRUCT_FOR_ID(flags) STRUCT_FOR_ID(flush) + STRUCT_FOR_ID(follow_symlinks) + STRUCT_FOR_ID(format) + STRUCT_FOR_ID(frequency) + STRUCT_FOR_ID(from_param) + STRUCT_FOR_ID(fromlist) + STRUCT_FOR_ID(fromtimestamp) + STRUCT_FOR_ID(fromutc) + STRUCT_FOR_ID(fset) + STRUCT_FOR_ID(func) + STRUCT_FOR_ID(future) + STRUCT_FOR_ID(generation) STRUCT_FOR_ID(genexpr) STRUCT_FOR_ID(get) + STRUCT_FOR_ID(get_debug) + STRUCT_FOR_ID(get_event_loop) + STRUCT_FOR_ID(get_loop) STRUCT_FOR_ID(get_source) STRUCT_FOR_ID(getattr) STRUCT_FOR_ID(getstate) + STRUCT_FOR_ID(gid) + STRUCT_FOR_ID(globals) + STRUCT_FOR_ID(groupindex) + STRUCT_FOR_ID(groups) + STRUCT_FOR_ID(handle) + STRUCT_FOR_ID(hash_name) + STRUCT_FOR_ID(header) + STRUCT_FOR_ID(headers) + STRUCT_FOR_ID(hi) + STRUCT_FOR_ID(hook) + STRUCT_FOR_ID(id) + STRUCT_FOR_ID(ident) STRUCT_FOR_ID(ignore) + STRUCT_FOR_ID(imag) STRUCT_FOR_ID(importlib) + STRUCT_FOR_ID(in_fd) + STRUCT_FOR_ID(incoming) + STRUCT_FOR_ID(indexgroup) STRUCT_FOR_ID(inf) + STRUCT_FOR_ID(infer_variance) + STRUCT_FOR_ID(inheritable) + STRUCT_FOR_ID(initial) + STRUCT_FOR_ID(initial_bytes) + STRUCT_FOR_ID(initial_value) + STRUCT_FOR_ID(initval) + STRUCT_FOR_ID(inner_size) + STRUCT_FOR_ID(input) + STRUCT_FOR_ID(insert_comments) + STRUCT_FOR_ID(insert_pis) + STRUCT_FOR_ID(instructions) + STRUCT_FOR_ID(intern) STRUCT_FOR_ID(intersection) + STRUCT_FOR_ID(is_running) STRUCT_FOR_ID(isatty) STRUCT_FOR_ID(isinstance) + STRUCT_FOR_ID(isoformat) + STRUCT_FOR_ID(isolation_level) + STRUCT_FOR_ID(istext) + STRUCT_FOR_ID(item) STRUCT_FOR_ID(items) STRUCT_FOR_ID(iter) + STRUCT_FOR_ID(iterable) + STRUCT_FOR_ID(iterations) STRUCT_FOR_ID(join) + STRUCT_FOR_ID(jump) + STRUCT_FOR_ID(keepends) + STRUCT_FOR_ID(key) + STRUCT_FOR_ID(keyfile) STRUCT_FOR_ID(keys) + STRUCT_FOR_ID(kind) + STRUCT_FOR_ID(kw) + STRUCT_FOR_ID(kw1) + STRUCT_FOR_ID(kw2) STRUCT_FOR_ID(lambda) + STRUCT_FOR_ID(last) + STRUCT_FOR_ID(last_exc) + STRUCT_FOR_ID(last_node) STRUCT_FOR_ID(last_traceback) STRUCT_FOR_ID(last_type) STRUCT_FOR_ID(last_value) STRUCT_FOR_ID(latin1) + STRUCT_FOR_ID(leaf_size) STRUCT_FOR_ID(len) + STRUCT_FOR_ID(length) + STRUCT_FOR_ID(level) + STRUCT_FOR_ID(limit) STRUCT_FOR_ID(line) + STRUCT_FOR_ID(line_buffering) STRUCT_FOR_ID(lineno) STRUCT_FOR_ID(listcomp) STRUCT_FOR_ID(little) + STRUCT_FOR_ID(lo) STRUCT_FOR_ID(locale) + STRUCT_FOR_ID(locals) + STRUCT_FOR_ID(logoption) + STRUCT_FOR_ID(loop) + STRUCT_FOR_ID(mapping) STRUCT_FOR_ID(match) + STRUCT_FOR_ID(max_length) + STRUCT_FOR_ID(maxdigits) + STRUCT_FOR_ID(maxevents) + STRUCT_FOR_ID(maxmem) + STRUCT_FOR_ID(maxsplit) + STRUCT_FOR_ID(maxvalue) + STRUCT_FOR_ID(memLevel) + STRUCT_FOR_ID(memlimit) + STRUCT_FOR_ID(message) STRUCT_FOR_ID(metaclass) + STRUCT_FOR_ID(metadata) + STRUCT_FOR_ID(method) + STRUCT_FOR_ID(mod) STRUCT_FOR_ID(mode) + STRUCT_FOR_ID(module) + STRUCT_FOR_ID(module_globals) STRUCT_FOR_ID(modules) STRUCT_FOR_ID(mro) STRUCT_FOR_ID(msg) + STRUCT_FOR_ID(mycmp) + STRUCT_FOR_ID(n) + STRUCT_FOR_ID(n_arg) STRUCT_FOR_ID(n_fields) STRUCT_FOR_ID(n_sequence_fields) STRUCT_FOR_ID(n_unnamed_fields) STRUCT_FOR_ID(name) + STRUCT_FOR_ID(name_from) + STRUCT_FOR_ID(namespace_separator) + STRUCT_FOR_ID(namespaces) + STRUCT_FOR_ID(narg) + STRUCT_FOR_ID(ndigits) + STRUCT_FOR_ID(new_file_name) + STRUCT_FOR_ID(new_limit) + STRUCT_FOR_ID(newline) STRUCT_FOR_ID(newlines) STRUCT_FOR_ID(next) + STRUCT_FOR_ID(nlocals) + STRUCT_FOR_ID(node_depth) + STRUCT_FOR_ID(node_offset) + STRUCT_FOR_ID(ns) + STRUCT_FOR_ID(nstype) + STRUCT_FOR_ID(nt) + STRUCT_FOR_ID(null) + STRUCT_FOR_ID(number) STRUCT_FOR_ID(obj) + STRUCT_FOR_ID(object) STRUCT_FOR_ID(offset) + STRUCT_FOR_ID(offset_dst) + STRUCT_FOR_ID(offset_src) + STRUCT_FOR_ID(on_type_read) STRUCT_FOR_ID(onceregistry) + STRUCT_FOR_ID(only_keys) + STRUCT_FOR_ID(oparg) STRUCT_FOR_ID(opcode) STRUCT_FOR_ID(open) + STRUCT_FOR_ID(opener) + STRUCT_FOR_ID(operation) + STRUCT_FOR_ID(optimize) + STRUCT_FOR_ID(options) + STRUCT_FOR_ID(order) + STRUCT_FOR_ID(origin) + STRUCT_FOR_ID(out_fd) + STRUCT_FOR_ID(outgoing) + STRUCT_FOR_ID(overlapped) + STRUCT_FOR_ID(owner) + STRUCT_FOR_ID(p) + STRUCT_FOR_ID(pages) STRUCT_FOR_ID(parent) - STRUCT_FOR_ID(partial) + STRUCT_FOR_ID(password) STRUCT_FOR_ID(path) + STRUCT_FOR_ID(pattern) STRUCT_FOR_ID(peek) STRUCT_FOR_ID(persistent_id) STRUCT_FOR_ID(persistent_load) + STRUCT_FOR_ID(person) + STRUCT_FOR_ID(pi_factory) + STRUCT_FOR_ID(pid) + STRUCT_FOR_ID(policy) + STRUCT_FOR_ID(pos) + STRUCT_FOR_ID(pos1) + STRUCT_FOR_ID(pos2) + STRUCT_FOR_ID(posix) STRUCT_FOR_ID(print_file_and_line) + STRUCT_FOR_ID(priority) + STRUCT_FOR_ID(progress) + STRUCT_FOR_ID(progress_handler) + STRUCT_FOR_ID(progress_routine) + STRUCT_FOR_ID(proto) + STRUCT_FOR_ID(protocol) STRUCT_FOR_ID(ps1) STRUCT_FOR_ID(ps2) + STRUCT_FOR_ID(query) + STRUCT_FOR_ID(quotetabs) + STRUCT_FOR_ID(r) STRUCT_FOR_ID(raw) STRUCT_FOR_ID(read) STRUCT_FOR_ID(read1) @@ -325,37 +628,126 @@ struct _Py_global_strings { STRUCT_FOR_ID(readinto) STRUCT_FOR_ID(readinto1) STRUCT_FOR_ID(readline) + STRUCT_FOR_ID(readonly) + STRUCT_FOR_ID(real) STRUCT_FOR_ID(reducer_override) + STRUCT_FOR_ID(registry) + STRUCT_FOR_ID(rel_tol) + STRUCT_FOR_ID(release) STRUCT_FOR_ID(reload) + STRUCT_FOR_ID(repl) STRUCT_FOR_ID(replace) + STRUCT_FOR_ID(reserved) STRUCT_FOR_ID(reset) + STRUCT_FOR_ID(resetids) STRUCT_FOR_ID(return) + STRUCT_FOR_ID(reverse) STRUCT_FOR_ID(reversed) + STRUCT_FOR_ID(s) + STRUCT_FOR_ID(salt) + STRUCT_FOR_ID(sched_priority) + STRUCT_FOR_ID(scheduler) STRUCT_FOR_ID(seek) STRUCT_FOR_ID(seekable) + STRUCT_FOR_ID(selectors) + STRUCT_FOR_ID(self) STRUCT_FOR_ID(send) + STRUCT_FOR_ID(sep) + STRUCT_FOR_ID(sequence) + STRUCT_FOR_ID(server_hostname) + STRUCT_FOR_ID(server_side) + STRUCT_FOR_ID(session) STRUCT_FOR_ID(setcomp) + STRUCT_FOR_ID(setpgroup) + STRUCT_FOR_ID(setsid) + STRUCT_FOR_ID(setsigdef) + STRUCT_FOR_ID(setsigmask) STRUCT_FOR_ID(setstate) + STRUCT_FOR_ID(shape) + STRUCT_FOR_ID(show_cmd) + STRUCT_FOR_ID(signed) + STRUCT_FOR_ID(size) + STRUCT_FOR_ID(sizehint) + STRUCT_FOR_ID(skip_file_prefixes) + STRUCT_FOR_ID(sleep) + STRUCT_FOR_ID(sock) STRUCT_FOR_ID(sort) + STRUCT_FOR_ID(sound) + STRUCT_FOR_ID(source) + STRUCT_FOR_ID(source_traceback) + STRUCT_FOR_ID(src) + STRUCT_FOR_ID(src_dir_fd) + STRUCT_FOR_ID(stacklevel) + STRUCT_FOR_ID(start) + STRUCT_FOR_ID(statement) + STRUCT_FOR_ID(status) STRUCT_FOR_ID(stderr) STRUCT_FOR_ID(stdin) STRUCT_FOR_ID(stdout) + STRUCT_FOR_ID(step) + STRUCT_FOR_ID(steps) + STRUCT_FOR_ID(store_name) + STRUCT_FOR_ID(strategy) + STRUCT_FOR_ID(strftime) STRUCT_FOR_ID(strict) + STRUCT_FOR_ID(strict_mode) + STRUCT_FOR_ID(string) + STRUCT_FOR_ID(sub_key) STRUCT_FOR_ID(symmetric_difference_update) + STRUCT_FOR_ID(tabsize) + STRUCT_FOR_ID(tag) + STRUCT_FOR_ID(target) + STRUCT_FOR_ID(target_is_directory) + STRUCT_FOR_ID(task) + STRUCT_FOR_ID(tb_frame) + STRUCT_FOR_ID(tb_lasti) + STRUCT_FOR_ID(tb_lineno) + STRUCT_FOR_ID(tb_next) STRUCT_FOR_ID(tell) + STRUCT_FOR_ID(template) + STRUCT_FOR_ID(term) STRUCT_FOR_ID(text) STRUCT_FOR_ID(threading) STRUCT_FOR_ID(throw) + STRUCT_FOR_ID(timeout) + STRUCT_FOR_ID(times) + STRUCT_FOR_ID(timetuple) STRUCT_FOR_ID(top) + STRUCT_FOR_ID(trace_callback) + STRUCT_FOR_ID(traceback) + STRUCT_FOR_ID(trailers) + STRUCT_FOR_ID(translate) + STRUCT_FOR_ID(true) STRUCT_FOR_ID(truncate) + STRUCT_FOR_ID(twice) + STRUCT_FOR_ID(txt) + STRUCT_FOR_ID(type) + STRUCT_FOR_ID(type_params) + STRUCT_FOR_ID(tz) + STRUCT_FOR_ID(tzname) + STRUCT_FOR_ID(uid) + STRUCT_FOR_ID(unlink) STRUCT_FOR_ID(unraisablehook) + STRUCT_FOR_ID(uri) + STRUCT_FOR_ID(usedforsecurity) + STRUCT_FOR_ID(value) STRUCT_FOR_ID(values) STRUCT_FOR_ID(version) + STRUCT_FOR_ID(volume) STRUCT_FOR_ID(warnings) STRUCT_FOR_ID(warnoptions) + STRUCT_FOR_ID(wbits) + STRUCT_FOR_ID(week) + STRUCT_FOR_ID(weekday) + STRUCT_FOR_ID(which) + STRUCT_FOR_ID(who) + STRUCT_FOR_ID(withdata) STRUCT_FOR_ID(writable) STRUCT_FOR_ID(write) - STRUCT_FOR_ID(zipimporter) + STRUCT_FOR_ID(write_through) + STRUCT_FOR_ID(x) + STRUCT_FOR_ID(year) + STRUCT_FOR_ID(zdict) } identifiers; struct { PyASCIIObject _ascii; @@ -373,9 +765,9 @@ struct _Py_global_strings { #define _Py_ID(NAME) \ - (_Py_SINGLETON(strings.identifiers._ ## NAME._ascii.ob_base)) + (_Py_SINGLETON(strings.identifiers._py_ ## NAME._ascii.ob_base)) #define _Py_STR(NAME) \ - (_Py_SINGLETON(strings.literals._ ## NAME._ascii.ob_base)) + (_Py_SINGLETON(strings.literals._py_ ## NAME._ascii.ob_base)) /* _Py_DECLARE_STR() should precede all uses of _Py_STR() in a function. diff --git a/Include/internal/pycore_hamt.h b/Include/internal/pycore_hamt.h index 4d64288b..d8742c7c 100644 --- a/Include/internal/pycore_hamt.h +++ b/Include/internal/pycore_hamt.h @@ -28,14 +28,10 @@ extern PyTypeObject _PyHamtKeys_Type; extern PyTypeObject _PyHamtValues_Type; extern PyTypeObject _PyHamtItems_Type; -/* runtime lifecycle */ - -void _PyHamt_Fini(PyInterpreterState *); - /* other API */ -#define PyHamt_Check(o) Py_IS_TYPE(o, &_PyHamt_Type) +#define PyHamt_Check(o) Py_IS_TYPE((o), &_PyHamt_Type) /* Abstract tree node. */ @@ -53,6 +49,13 @@ typedef struct { } PyHamtObject; +typedef struct { + PyObject_VAR_HEAD + uint32_t b_bitmap; + PyObject *b_array[1]; +} PyHamtNode_Bitmap; + + /* A struct to hold the state of depth-first traverse of the tree. HAMT is an immutable collection. Iterators will hold a strong reference diff --git a/Include/internal/pycore_hashtable.h b/Include/internal/pycore_hashtable.h index 18757abc..6501ab14 100644 --- a/Include/internal/pycore_hashtable.h +++ b/Include/internal/pycore_hashtable.h @@ -18,9 +18,9 @@ typedef struct { _Py_slist_item_t *head; } _Py_slist_t; -#define _Py_SLIST_ITEM_NEXT(ITEM) (((_Py_slist_item_t *)ITEM)->next) +#define _Py_SLIST_ITEM_NEXT(ITEM) _Py_RVALUE(((_Py_slist_item_t *)(ITEM))->next) -#define _Py_SLIST_HEAD(SLIST) (((_Py_slist_t *)SLIST)->head) +#define _Py_SLIST_HEAD(SLIST) _Py_RVALUE(((_Py_slist_t *)(SLIST))->head) /* _Py_hashtable: table entry */ diff --git a/Include/internal/pycore_import.h b/Include/internal/pycore_import.h index aee1f66a..376957bd 100644 --- a/Include/internal/pycore_import.h +++ b/Include/internal/pycore_import.h @@ -5,10 +5,159 @@ extern "C" { #endif +#include "pycore_hashtable.h" // _Py_hashtable_t +#include "pycore_time.h" // _PyTime_t + + +struct _import_runtime_state { + /* The builtin modules (defined in config.c). */ + struct _inittab *inittab; + /* The most recent value assigned to a PyModuleDef.m_base.m_index. + This is incremented each time PyModuleDef_Init() is called, + which is just about every time an extension module is imported. + See PyInterpreterState.modules_by_index for more info. */ + Py_ssize_t last_module_index; + struct { + /* A lock to guard the cache. */ + PyThread_type_lock mutex; + /* The actual cache of (filename, name, PyModuleDef) for modules. + Only legacy (single-phase init) extension modules are added + and only if they support multiple initialization (m_size >- 0) + or are imported in the main interpreter. + This is initialized lazily in _PyImport_FixupExtensionObject(). + Modules are added there and looked up in _imp.find_extension(). */ + _Py_hashtable_t *hashtable; + } extensions; + /* Package context -- the full module name for package imports */ + const char * pkgcontext; +}; + +struct _import_state { + /* cached sys.modules dictionary */ + PyObject *modules; + /* This is the list of module objects for all legacy (single-phase init) + extension modules ever loaded in this process (i.e. imported + in this interpreter or in any other). Py_None stands in for + modules that haven't actually been imported in this interpreter. + + A module's index (PyModuleDef.m_base.m_index) is used to look up + the corresponding module object for this interpreter, if any. + (See PyState_FindModule().) When any extension module + is initialized during import, its moduledef gets initialized by + PyModuleDef_Init(), and the first time that happens for each + PyModuleDef, its index gets set to the current value of + a global counter (see _PyRuntimeState.imports.last_module_index). + The entry for that index in this interpreter remains unset until + the module is actually imported here. (Py_None is used as + a placeholder.) Note that multi-phase init modules always get + an index for which there will never be a module set. + + This is initialized lazily in PyState_AddModule(), which is also + where modules get added. */ + PyObject *modules_by_index; + /* importlib module._bootstrap */ + PyObject *importlib; + /* override for config->use_frozen_modules (for tests) + (-1: "off", 1: "on", 0: no override) */ + int override_frozen_modules; + int override_multi_interp_extensions_check; +#ifdef HAVE_DLOPEN + int dlopenflags; +#endif + PyObject *import_func; + /* The global import lock. */ + struct { + PyThread_type_lock mutex; + unsigned long thread; + int level; + } lock; + /* diagnostic info in PyImport_ImportModuleLevelObject() */ + struct { + int import_level; + _PyTime_t accumulated; + int header; + } find_and_load; +}; + +#ifdef HAVE_DLOPEN +# include <dlfcn.h> +# if HAVE_DECL_RTLD_NOW +# define _Py_DLOPEN_FLAGS RTLD_NOW +# else +# define _Py_DLOPEN_FLAGS RTLD_LAZY +# endif +# define DLOPENFLAGS_INIT .dlopenflags = _Py_DLOPEN_FLAGS, +#else +# define _Py_DLOPEN_FLAGS 0 +# define DLOPENFLAGS_INIT +#endif + +#define IMPORTS_INIT \ + { \ + DLOPENFLAGS_INIT \ + .lock = { \ + .mutex = NULL, \ + .thread = PYTHREAD_INVALID_THREAD_ID, \ + .level = 0, \ + }, \ + .find_and_load = { \ + .header = 1, \ + }, \ + } + +extern void _PyImport_ClearCore(PyInterpreterState *interp); + +extern Py_ssize_t _PyImport_GetNextModuleIndex(void); +extern const char * _PyImport_ResolveNameWithPackageContext(const char *name); +extern const char * _PyImport_SwapPackageContext(const char *newcontext); + +extern int _PyImport_GetDLOpenFlags(PyInterpreterState *interp); +extern void _PyImport_SetDLOpenFlags(PyInterpreterState *interp, int new_val); + +extern PyObject * _PyImport_InitModules(PyInterpreterState *interp); +extern PyObject * _PyImport_GetModules(PyInterpreterState *interp); +extern void _PyImport_ClearModules(PyInterpreterState *interp); + +extern void _PyImport_ClearModulesByIndex(PyInterpreterState *interp); + +extern int _PyImport_InitDefaultImportFunc(PyInterpreterState *interp); +extern int _PyImport_IsDefaultImportFunc( + PyInterpreterState *interp, + PyObject *func); + +extern PyObject * _PyImport_GetImportlibLoader( + PyInterpreterState *interp, + const char *loader_name); +extern PyObject * _PyImport_GetImportlibExternalLoader( + PyInterpreterState *interp, + const char *loader_name); +extern PyObject * _PyImport_BlessMyLoader( + PyInterpreterState *interp, + PyObject *module_globals); +extern PyObject * _PyImport_ImportlibModuleRepr( + PyInterpreterState *interp, + PyObject *module); + + +extern PyStatus _PyImport_Init(void); +extern void _PyImport_Fini(void); +extern void _PyImport_Fini2(void); + +extern PyStatus _PyImport_InitCore( + PyThreadState *tstate, + PyObject *sysmod, + int importlib); +extern PyStatus _PyImport_InitExternal(PyThreadState *tstate); +extern void _PyImport_FiniCore(PyInterpreterState *interp); +extern void _PyImport_FiniExternal(PyInterpreterState *interp); + + #ifdef HAVE_FORK -extern PyStatus _PyImport_ReInitLock(void); +extern PyStatus _PyImport_ReInitLock(PyInterpreterState *interp); #endif -extern PyObject* _PyImport_BootstrapImp(PyThreadState *tstate); + + +extern PyObject* _PyImport_GetBuiltinModuleNames(void); struct _module_alias { const char *name; /* ASCII encoded string */ @@ -20,6 +169,13 @@ PyAPI_DATA(const struct _frozen *) _PyImport_FrozenStdlib; PyAPI_DATA(const struct _frozen *) _PyImport_FrozenTest; extern const struct _module_alias * _PyImport_FrozenAliases; +PyAPI_FUNC(int) _PyImport_CheckSubinterpIncompatibleExtensionAllowed( + const char *name); + + +// for testing +PyAPI_FUNC(int) _PyImport_ClearExtension(PyObject *name, PyObject *filename); + #ifdef __cplusplus } #endif diff --git a/Include/internal/pycore_initconfig.h b/Include/internal/pycore_initconfig.h index d765600f..4cbd14a6 100644 --- a/Include/internal/pycore_initconfig.h +++ b/Include/internal/pycore_initconfig.h @@ -36,15 +36,13 @@ struct pyruntimestate; ._type = _PyStatus_TYPE_EXIT, \ .exitcode = (EXITCODE)} #define _PyStatus_IS_ERROR(err) \ - (err._type == _PyStatus_TYPE_ERROR) + ((err)._type == _PyStatus_TYPE_ERROR) #define _PyStatus_IS_EXIT(err) \ - (err._type == _PyStatus_TYPE_EXIT) + ((err)._type == _PyStatus_TYPE_EXIT) #define _PyStatus_EXCEPTION(err) \ - (err._type != _PyStatus_TYPE_OK) + ((err)._type != _PyStatus_TYPE_OK) #define _PyStatus_UPDATE_FUNC(err) \ - do { err.func = _PyStatus_GET_FUNC(); } while (0) - -PyObject* _PyErr_SetFromPyStatus(PyStatus status); + do { (err).func = _PyStatus_GET_FUNC(); } while (0) /* --- PyWideStringList ------------------------------------------------ */ @@ -170,8 +168,6 @@ extern void _Py_DumpPathConfig(PyThreadState *tstate); PyAPI_FUNC(PyObject*) _Py_Get_Getpath_CodeObject(void); -extern int _Py_global_config_int_max_str_digits; - /* --- Function used for testing ---------------------------------- */ diff --git a/Include/internal/pycore_instruments.h b/Include/internal/pycore_instruments.h new file mode 100644 index 00000000..87f70d2d --- /dev/null +++ b/Include/internal/pycore_instruments.h @@ -0,0 +1,106 @@ + +#ifndef Py_INTERNAL_INSTRUMENT_H +#define Py_INTERNAL_INSTRUMENT_H + + +#include "pycore_bitutils.h" // _Py_popcount32 +#include "pycore_frame.h" + +#include "cpython/code.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define PY_MONITORING_TOOL_IDS 8 + +/* Local events. + * These require bytecode instrumentation */ + +#define PY_MONITORING_EVENT_PY_START 0 +#define PY_MONITORING_EVENT_PY_RESUME 1 +#define PY_MONITORING_EVENT_PY_RETURN 2 +#define PY_MONITORING_EVENT_PY_YIELD 3 +#define PY_MONITORING_EVENT_CALL 4 +#define PY_MONITORING_EVENT_LINE 5 +#define PY_MONITORING_EVENT_INSTRUCTION 6 +#define PY_MONITORING_EVENT_JUMP 7 +#define PY_MONITORING_EVENT_BRANCH 8 +#define PY_MONITORING_EVENT_STOP_ITERATION 9 + +#define PY_MONITORING_IS_INSTRUMENTED_EVENT(ev) \ + ((ev) < _PY_MONITORING_LOCAL_EVENTS) + +/* Other events, mainly exceptions */ + +#define PY_MONITORING_EVENT_RAISE 10 +#define PY_MONITORING_EVENT_EXCEPTION_HANDLED 11 +#define PY_MONITORING_EVENT_PY_UNWIND 12 +#define PY_MONITORING_EVENT_PY_THROW 13 +#define PY_MONITORING_EVENT_RERAISE 14 + + +/* Ancilliary events */ + +#define PY_MONITORING_EVENT_C_RETURN 15 +#define PY_MONITORING_EVENT_C_RAISE 16 + + +typedef uint32_t _PyMonitoringEventSet; + +/* Tool IDs */ + +/* These are defined in PEP 669 for convenience to avoid clashes */ +#define PY_MONITORING_DEBUGGER_ID 0 +#define PY_MONITORING_COVERAGE_ID 1 +#define PY_MONITORING_PROFILER_ID 2 +#define PY_MONITORING_OPTIMIZER_ID 5 + +/* Internal IDs used to suuport sys.setprofile() and sys.settrace() */ +#define PY_MONITORING_SYS_PROFILE_ID 6 +#define PY_MONITORING_SYS_TRACE_ID 7 + + +PyObject *_PyMonitoring_RegisterCallback(int tool_id, int event_id, PyObject *obj); + +int _PyMonitoring_SetEvents(int tool_id, _PyMonitoringEventSet events); + +extern int +_Py_call_instrumentation(PyThreadState *tstate, int event, + _PyInterpreterFrame *frame, _Py_CODEUNIT *instr); + +extern int +_Py_call_instrumentation_line(PyThreadState *tstate, _PyInterpreterFrame* frame, + _Py_CODEUNIT *instr, _Py_CODEUNIT *prev); + +extern int +_Py_call_instrumentation_instruction( + PyThreadState *tstate, _PyInterpreterFrame* frame, _Py_CODEUNIT *instr); + +_Py_CODEUNIT * +_Py_call_instrumentation_jump( + PyThreadState *tstate, int event, + _PyInterpreterFrame *frame, _Py_CODEUNIT *instr, _Py_CODEUNIT *target); + +extern int +_Py_call_instrumentation_arg(PyThreadState *tstate, int event, + _PyInterpreterFrame *frame, _Py_CODEUNIT *instr, PyObject *arg); + +extern int +_Py_call_instrumentation_2args(PyThreadState *tstate, int event, + _PyInterpreterFrame *frame, _Py_CODEUNIT *instr, PyObject *arg0, PyObject *arg1); + +extern void +_Py_call_instrumentation_exc2(PyThreadState *tstate, int event, + _PyInterpreterFrame *frame, _Py_CODEUNIT *instr, PyObject *arg0, PyObject *arg1); + +extern int +_Py_Instrumentation_GetLine(PyCodeObject *code, int index); + +extern PyObject _PyInstrumentation_MISSING; +extern PyObject _PyInstrumentation_DISABLE; + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_INSTRUMENT_H */ diff --git a/Include/internal/pycore_interp.h b/Include/internal/pycore_interp.h index 02d25d67..1db23145 100644 --- a/Include/internal/pycore_interp.h +++ b/Include/internal/pycore_interp.h @@ -10,75 +10,60 @@ extern "C" { #include <stdbool.h> -#include "pycore_atomic.h" // _Py_atomic_address #include "pycore_ast_state.h" // struct ast_state +#include "pycore_atexit.h" // struct atexit_state +#include "pycore_atomic.h" // _Py_atomic_address +#include "pycore_ceval_state.h" // struct _ceval_state #include "pycore_code.h" // struct callable_cache #include "pycore_context.h" // struct _Py_context_state -#include "pycore_dict.h" // struct _Py_dict_state +#include "pycore_dict_state.h" // struct _Py_dict_state +#include "pycore_dtoa.h" // struct _dtoa_state #include "pycore_exceptions.h" // struct _Py_exc_state #include "pycore_floatobject.h" // struct _Py_float_state +#include "pycore_function.h" // FUNC_MAX_WATCHERS #include "pycore_genobject.h" // struct _Py_async_gen_state -#include "pycore_gil.h" // struct _gil_runtime_state #include "pycore_gc.h" // struct _gc_runtime_state +#include "pycore_global_objects.h" // struct _Py_interp_static_objects +#include "pycore_import.h" // struct _import_state +#include "pycore_instruments.h" // _PY_MONITORING_EVENTS #include "pycore_list.h" // struct _Py_list_state +#include "pycore_object_state.h" // struct _py_object_state +#include "pycore_obmalloc.h" // struct obmalloc_state #include "pycore_tuple.h" // struct _Py_tuple_state #include "pycore_typeobject.h" // struct type_cache #include "pycore_unicodeobject.h" // struct _Py_unicode_state #include "pycore_warnings.h" // struct _warnings_runtime_state -struct _pending_calls { - PyThread_type_lock lock; - /* Request for running pending calls. */ - _Py_atomic_int calls_to_do; - /* Request for looking at the `async_exc` field of the current - thread state. - Guarded by the GIL. */ - int async_exc; -#define NPENDINGCALLS 32 - struct { - int (*func)(void *); - void *arg; - } calls[NPENDINGCALLS]; - int first; - int last; -}; -struct _ceval_state { - int recursion_limit; - /* This single variable consolidates all requests to break out of - the fast path in the eval loop. */ - _Py_atomic_int eval_breaker; - /* Request for dropping the GIL */ - _Py_atomic_int gil_drop_request; - struct _pending_calls pending; +struct _Py_long_state { + int max_str_digits; }; - -// atexit state -typedef struct { - PyObject *func; - PyObject *args; - PyObject *kwargs; -} atexit_callback; - -struct atexit_state { - atexit_callback **callbacks; - int ncallbacks; - int callback_len; -}; - - /* interpreter state */ /* PyInterpreterState holds the global state for one of the runtime's interpreters. Typically the initial (main) interpreter is the only one. - The PyInterpreterState typedef is in Include/pystate.h. + The PyInterpreterState typedef is in Include/pytypedefs.h. */ struct _is { PyInterpreterState *next; + int64_t id; + int64_t id_refcount; + int requires_idref; + PyThread_type_lock id_mutex; + + /* Has been initialized to a safe state. + + In order to be effective, this must be set to 0 during or right + after allocation. */ + int _initialized; + int finalizing; + + uint64_t monitoring_version; + uint64_t last_restart_version; struct pythreads { uint64_t next_unique_id; /* The linked list of threads, newest first. */ @@ -97,36 +82,44 @@ struct _is { Get runtime from tstate: tstate->interp->runtime. */ struct pyruntimestate *runtime; - int64_t id; - int64_t id_refcount; - int requires_idref; - PyThread_type_lock id_mutex; + /* Set by Py_EndInterpreter(). - /* Has been initialized to a safe state. + Use _PyInterpreterState_GetFinalizing() + and _PyInterpreterState_SetFinalizing() + to access it, don't access it directly. */ + _Py_atomic_address _finalizing; - In order to be effective, this must be set to 0 during or right - after allocation. */ - int _initialized; - int finalizing; + struct _gc_runtime_state gc; - /* Was this interpreter statically allocated? */ - bool _static; + /* The following fields are here to avoid allocation during init. + The data is exposed through PyInterpreterState pointer fields. + These fields should not be accessed directly outside of init. - struct _ceval_state ceval; - struct _gc_runtime_state gc; + All other PyInterpreterState pointer fields are populated when + needed and default to NULL. + + For now there are some exceptions to that rule, which require + allocation during init. These will be addressed on a case-by-case + basis. Also see _PyRuntimeState regarding the various mutex fields. + */ - // sys.modules dictionary - PyObject *modules; - PyObject *modules_by_index; // Dictionary of the sys module PyObject *sysdict; + // Dictionary of the builtins module PyObject *builtins; - // importlib module - PyObject *importlib; - // override for config->use_frozen_modules (for tests) - // (-1: "off", 1: "on", 0: no override) - int override_frozen_modules; + + struct _ceval_state ceval; + + struct _import_state imports; + + /* The per-interpreter GIL, which might not be used. */ + struct _gil_runtime_state _gil; + + /* ---------- IMPORTANT --------------------------- + The fields above this line are declared as early as + possible to facilitate out-of-process observability + tools. */ PyObject *codec_search_path; PyObject *codec_search_cache; @@ -134,17 +127,19 @@ struct _is { int codecs_initialized; PyConfig config; -#ifdef HAVE_DLOPEN - int dlopenflags; -#endif + unsigned long feature_flags; PyObject *dict; /* Stores per-interpreter state */ + PyObject *sysdict_copy; PyObject *builtins_copy; - PyObject *import_func; // Initialized to _PyEval_EvalFrameDefault(). _PyFrameEvalFunction eval_frame; + PyFunction_WatchCallback func_watchers[FUNC_MAX_WATCHERS]; + // One bit is set for each non-NULL entry in func_watchers + uint8_t active_func_watchers; + Py_ssize_t co_extra_user_count; freefunc co_extra_freefuncs[MAX_CO_EXTRA_USERS]; @@ -157,10 +152,20 @@ struct _is { struct _warnings_runtime_state warnings; struct atexit_state atexit; + struct _obmalloc_state obmalloc; + PyObject *audit_hooks; + PyType_WatchCallback type_watchers[TYPE_MAX_WATCHERS]; + PyCode_WatchCallback code_watchers[CODE_MAX_WATCHERS]; + // One bit is set for each non-NULL entry in code_watchers + uint8_t active_code_watchers; + struct _py_object_state object_state; struct _Py_unicode_state unicode; struct _Py_float_state float_state; + struct _Py_long_state long_state; + struct _dtoa_state dtoa; + struct _py_func_state func_state; /* Using a cache is very effective since typically only a single slice is created and then deleted again. */ PySliceObject *slice_cache; @@ -173,34 +178,43 @@ struct _is { struct _Py_exc_state exc_state; struct ast_state ast; - struct type_cache type_cache; + struct types_state types; struct callable_cache callable_cache; + PyCodeObject *interpreter_trampoline; - int int_max_str_digits; - - /* The following fields are here to avoid allocation during init. - The data is exposed through PyInterpreterState pointer fields. - These fields should not be accessed directly outside of init. + _Py_GlobalMonitors monitors; + bool f_opcode_trace_set; + bool sys_profile_initialized; + bool sys_trace_initialized; + Py_ssize_t sys_profiling_threads; /* Count of threads with c_profilefunc set */ + Py_ssize_t sys_tracing_threads; /* Count of threads with c_tracefunc set */ + PyObject *monitoring_callables[PY_MONITORING_TOOL_IDS][_PY_MONITORING_EVENTS]; + PyObject *monitoring_tool_names[PY_MONITORING_TOOL_IDS]; - All other PyInterpreterState pointer fields are populated when - needed and default to NULL. + struct _Py_interp_cached_objects cached_objects; + struct _Py_interp_static_objects static_objects; - For now there are some exceptions to that rule, which require - allocation during init. These will be addressed on a case-by-case - basis. Also see _PyRuntimeState regarding the various mutex fields. - */ - - /* the initial PyInterpreterState.threads.head */ + /* the initial PyInterpreterState.threads.head */ PyThreadState _initial_thread; }; /* other API */ -extern void _PyInterpreterState_ClearModules(PyInterpreterState *interp); extern void _PyInterpreterState_Clear(PyThreadState *tstate); +static inline PyThreadState* +_PyInterpreterState_GetFinalizing(PyInterpreterState *interp) { + return (PyThreadState*)_Py_atomic_load_relaxed(&interp->_finalizing); +} + +static inline void +_PyInterpreterState_SetFinalizing(PyInterpreterState *interp, PyThreadState *tstate) { + _Py_atomic_store_relaxed(&interp->_finalizing, (uintptr_t)tstate); +} + + /* cross-interpreter data registry */ /* For now we use a global registry of shareable classes. An @@ -210,9 +224,10 @@ extern void _PyInterpreterState_Clear(PyThreadState *tstate); struct _xidregitem; struct _xidregitem { - PyTypeObject *cls; - crossinterpdatafunc getdata; + struct _xidregitem *prev; struct _xidregitem *next; + PyObject *cls; // weakref to a PyTypeObject + crossinterpdatafunc getdata; }; PyAPI_FUNC(PyInterpreterState*) _PyInterpreterState_LookUpID(int64_t); diff --git a/Include/internal/pycore_intrinsics.h b/Include/internal/pycore_intrinsics.h new file mode 100644 index 00000000..39f15681 --- /dev/null +++ b/Include/internal/pycore_intrinsics.h @@ -0,0 +1,32 @@ +// Auto-generated by Tools/build/generate_opcode_h.py from Lib/opcode.py + +/* Unary Functions: */ +#define INTRINSIC_1_INVALID 0 +#define INTRINSIC_PRINT 1 +#define INTRINSIC_IMPORT_STAR 2 +#define INTRINSIC_STOPITERATION_ERROR 3 +#define INTRINSIC_ASYNC_GEN_WRAP 4 +#define INTRINSIC_UNARY_POSITIVE 5 +#define INTRINSIC_LIST_TO_TUPLE 6 +#define INTRINSIC_TYPEVAR 7 +#define INTRINSIC_PARAMSPEC 8 +#define INTRINSIC_TYPEVARTUPLE 9 +#define INTRINSIC_SUBSCRIPT_GENERIC 10 +#define INTRINSIC_TYPEALIAS 11 + +#define MAX_INTRINSIC_1 11 + + +/* Binary Functions: */ +#define INTRINSIC_2_INVALID 0 +#define INTRINSIC_PREP_RERAISE_STAR 1 +#define INTRINSIC_TYPEVAR_WITH_BOUND 2 +#define INTRINSIC_TYPEVAR_WITH_CONSTRAINTS 3 +#define INTRINSIC_SET_FUNCTION_TYPE_PARAMS 4 + +#define MAX_INTRINSIC_2 4 + +typedef PyObject *(*instrinsic_func1)(PyThreadState* tstate, PyObject *value); +typedef PyObject *(*instrinsic_func2)(PyThreadState* tstate, PyObject *value1, PyObject *value2); +extern const instrinsic_func1 _PyIntrinsics_UnaryFunctions[]; +extern const instrinsic_func2 _PyIntrinsics_BinaryFunctions[]; diff --git a/Include/internal/pycore_list.h b/Include/internal/pycore_list.h index 860dce1f..2fcbe12c 100644 --- a/Include/internal/pycore_list.h +++ b/Include/internal/pycore_list.h @@ -35,7 +35,7 @@ struct _Py_list_state { #endif }; -#define _PyList_ITEMS(op) (_PyList_CAST(op)->ob_item) +#define _PyList_ITEMS(op) _Py_RVALUE(_PyList_CAST(op)->ob_item) extern int _PyList_AppendTakeRefListResize(PyListObject *self, PyObject *newitem); @@ -56,6 +56,27 @@ _PyList_AppendTakeRef(PyListObject *self, PyObject *newitem) return _PyList_AppendTakeRefListResize(self, newitem); } +// Repeat the bytes of a buffer in place +static inline void +_Py_memory_repeat(char* dest, Py_ssize_t len_dest, Py_ssize_t len_src) +{ + assert(len_src > 0); + Py_ssize_t copied = len_src; + while (copied < len_dest) { + Py_ssize_t bytes_to_copy = Py_MIN(copied, len_dest - copied); + memcpy(dest + copied, dest, bytes_to_copy); + copied += bytes_to_copy; + } +} + +typedef struct { + PyObject_HEAD + Py_ssize_t it_index; + PyListObject *it_seq; /* Set to NULL when iterator is exhausted */ +} _PyListIterObject; + +extern PyObject *_PyList_FromArraySteal(PyObject *const *src, Py_ssize_t n); + #ifdef __cplusplus } #endif diff --git a/Include/internal/pycore_long.h b/Include/internal/pycore_long.h index 0f466eb6..64c00cb1 100644 --- a/Include/internal/pycore_long.h +++ b/Include/internal/pycore_long.h @@ -108,6 +108,150 @@ PyAPI_FUNC(char*) _PyLong_FormatBytesWriter( int base, int alternate); +/* Long value tag bits: + * 0-1: Sign bits value = (1-sign), ie. negative=2, positive=0, zero=1. + * 2: Reserved for immortality bit + * 3+ Unsigned digit count + */ +#define SIGN_MASK 3 +#define SIGN_ZERO 1 +#define SIGN_NEGATIVE 2 +#define NON_SIZE_BITS 3 + +/* The functions _PyLong_IsCompact and _PyLong_CompactValue are defined + * in Include/cpython/longobject.h, since they need to be inline. + * + * "Compact" values have at least one bit to spare, + * so that addition and subtraction can be performed on the values + * without risk of overflow. + * + * The inline functions need tag bits. + * For readability, rather than do `#define SIGN_MASK _PyLong_SIGN_MASK` + * we define them to the numbers in both places and then assert that + * they're the same. + */ +static_assert(SIGN_MASK == _PyLong_SIGN_MASK, "SIGN_MASK does not match _PyLong_SIGN_MASK"); +static_assert(NON_SIZE_BITS == _PyLong_NON_SIZE_BITS, "NON_SIZE_BITS does not match _PyLong_NON_SIZE_BITS"); + +/* All *compact" values are guaranteed to fit into + * a Py_ssize_t with at least one bit to spare. + * In other words, for 64 bit machines, compact + * will be signed 63 (or fewer) bit values + */ + +/* Return 1 if the argument is compact int */ +static inline int +_PyLong_IsNonNegativeCompact(const PyLongObject* op) { + assert(PyLong_Check(op)); + return op->long_value.lv_tag <= (1 << NON_SIZE_BITS); +} + + +static inline int +_PyLong_BothAreCompact(const PyLongObject* a, const PyLongObject* b) { + assert(PyLong_Check(a)); + assert(PyLong_Check(b)); + return (a->long_value.lv_tag | b->long_value.lv_tag) < (2 << NON_SIZE_BITS); +} + +static inline bool +_PyLong_IsZero(const PyLongObject *op) +{ + return (op->long_value.lv_tag & SIGN_MASK) == SIGN_ZERO; +} + +static inline bool +_PyLong_IsNegative(const PyLongObject *op) +{ + return (op->long_value.lv_tag & SIGN_MASK) == SIGN_NEGATIVE; +} + +static inline bool +_PyLong_IsPositive(const PyLongObject *op) +{ + return (op->long_value.lv_tag & SIGN_MASK) == 0; +} + +static inline Py_ssize_t +_PyLong_DigitCount(const PyLongObject *op) +{ + assert(PyLong_Check(op)); + return op->long_value.lv_tag >> NON_SIZE_BITS; +} + +/* Equivalent to _PyLong_DigitCount(op) * _PyLong_NonCompactSign(op) */ +static inline Py_ssize_t +_PyLong_SignedDigitCount(const PyLongObject *op) +{ + assert(PyLong_Check(op)); + Py_ssize_t sign = 1 - (op->long_value.lv_tag & SIGN_MASK); + return sign * (Py_ssize_t)(op->long_value.lv_tag >> NON_SIZE_BITS); +} + +static inline int +_PyLong_CompactSign(const PyLongObject *op) +{ + assert(PyLong_Check(op)); + assert(_PyLong_IsCompact(op)); + return 1 - (op->long_value.lv_tag & SIGN_MASK); +} + +static inline int +_PyLong_NonCompactSign(const PyLongObject *op) +{ + assert(PyLong_Check(op)); + assert(!_PyLong_IsCompact(op)); + return 1 - (op->long_value.lv_tag & SIGN_MASK); +} + +/* Do a and b have the same sign? */ +static inline int +_PyLong_SameSign(const PyLongObject *a, const PyLongObject *b) +{ + return (a->long_value.lv_tag & SIGN_MASK) == (b->long_value.lv_tag & SIGN_MASK); +} + +#define TAG_FROM_SIGN_AND_SIZE(sign, size) ((1 - (sign)) | ((size) << NON_SIZE_BITS)) + +static inline void +_PyLong_SetSignAndDigitCount(PyLongObject *op, int sign, Py_ssize_t size) +{ + assert(size >= 0); + assert(-1 <= sign && sign <= 1); + assert(sign != 0 || size == 0); + op->long_value.lv_tag = TAG_FROM_SIGN_AND_SIZE(sign, (size_t)size); +} + +static inline void +_PyLong_SetDigitCount(PyLongObject *op, Py_ssize_t size) +{ + assert(size >= 0); + op->long_value.lv_tag = (((size_t)size) << NON_SIZE_BITS) | (op->long_value.lv_tag & SIGN_MASK); +} + +#define NON_SIZE_MASK ~((1 << NON_SIZE_BITS) - 1) + +static inline void +_PyLong_FlipSign(PyLongObject *op) { + unsigned int flipped_sign = 2 - (op->long_value.lv_tag & SIGN_MASK); + op->long_value.lv_tag &= NON_SIZE_MASK; + op->long_value.lv_tag |= flipped_sign; +} + +#define _PyLong_DIGIT_INIT(val) \ + { \ + .ob_base = _PyObject_HEAD_INIT(&PyLong_Type) \ + .long_value = { \ + .lv_tag = TAG_FROM_SIGN_AND_SIZE( \ + (val) == 0 ? 0 : ((val) < 0 ? -1 : 1), \ + (val) == 0 ? 0 : 1), \ + { ((val) >= 0 ? (val) : -(val)) }, \ + } \ + } + +#define _PyLong_FALSE_TAG TAG_FROM_SIGN_AND_SIZE(0, 0) +#define _PyLong_TRUE_TAG TAG_FROM_SIGN_AND_SIZE(1, 1) + #ifdef __cplusplus } #endif diff --git a/Include/internal/pycore_memoryobject.h b/Include/internal/pycore_memoryobject.h new file mode 100644 index 00000000..fe19e3f9 --- /dev/null +++ b/Include/internal/pycore_memoryobject.h @@ -0,0 +1,18 @@ +#ifndef Py_INTERNAL_MEMORYOBJECT_H +#define Py_INTERNAL_MEMORYOBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +PyObject * +_PyMemoryView_FromBufferProc(PyObject *v, int flags, + getbufferproc bufferproc); + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_MEMORYOBJECT_H */ diff --git a/Include/internal/pycore_moduleobject.h b/Include/internal/pycore_moduleobject.h index 76361b8d..15a1bcb6 100644 --- a/Include/internal/pycore_moduleobject.h +++ b/Include/internal/pycore_moduleobject.h @@ -36,6 +36,9 @@ static inline PyObject* _PyModule_GetDict(PyObject *mod) { return dict; } +PyObject* _Py_module_getattro_impl(PyModuleObject *m, PyObject *name, int suppress); +PyObject* _Py_module_getattro(PyModuleObject *m, PyObject *name); + #ifdef __cplusplus } #endif diff --git a/Include/internal/pycore_object.h b/Include/internal/pycore_object.h index f022f824..7a2f13a2 100644 --- a/Include/internal/pycore_object.h +++ b/Include/internal/pycore_object.h @@ -14,28 +14,92 @@ extern "C" { #include "pycore_pystate.h" // _PyInterpreterState_GET() #include "pycore_runtime.h" // _PyRuntime -#define _PyObject_IMMORTAL_INIT(type) \ - { \ - .ob_refcnt = 999999999, \ - .ob_type = type, \ - } -#define _PyVarObject_IMMORTAL_INIT(type, size) \ - { \ - .ob_base = _PyObject_IMMORTAL_INIT(type), \ - .ob_size = size, \ - } +/* We need to maintain an internal copy of Py{Var}Object_HEAD_INIT to avoid + designated initializer conflicts in C++20. If we use the deinition in + object.h, we will be mixing designated and non-designated initializers in + pycore objects which is forbiddent in C++20. However, if we then use + designated initializers in object.h then Extensions without designated break. + Furthermore, we can't use designated initializers in Extensions since these + are not supported pre-C++20. Thus, keeping an internal copy here is the most + backwards compatible solution */ +#define _PyObject_HEAD_INIT(type) \ + { \ + _PyObject_EXTRA_INIT \ + .ob_refcnt = _Py_IMMORTAL_REFCNT, \ + .ob_type = (type) \ + }, +#define _PyVarObject_HEAD_INIT(type, size) \ + { \ + .ob_base = _PyObject_HEAD_INIT(type) \ + .ob_size = size \ + }, PyAPI_FUNC(void) _Py_NO_RETURN _Py_FatalRefcountErrorFunc( const char *func, const char *message); -#define _Py_FatalRefcountError(message) _Py_FatalRefcountErrorFunc(__func__, message) +#define _Py_FatalRefcountError(message) \ + _Py_FatalRefcountErrorFunc(__func__, (message)) + + +#ifdef Py_REF_DEBUG +/* The symbol is only exposed in the API for the sake of extensions + built against the pre-3.12 stable ABI. */ +PyAPI_DATA(Py_ssize_t) _Py_RefTotal; + +extern void _Py_AddRefTotal(PyInterpreterState *, Py_ssize_t); +extern void _Py_IncRefTotal(PyInterpreterState *); +extern void _Py_DecRefTotal(PyInterpreterState *); + +# define _Py_DEC_REFTOTAL(interp) \ + interp->object_state.reftotal-- +#endif + +// Increment reference count by n +static inline void _Py_RefcntAdd(PyObject* op, Py_ssize_t n) +{ + if (_Py_IsImmortal(op)) { + return; + } +#ifdef Py_REF_DEBUG + _Py_AddRefTotal(_PyInterpreterState_GET(), n); +#endif + op->ob_refcnt += n; +} +#define _Py_RefcntAdd(op, n) _Py_RefcntAdd(_PyObject_CAST(op), n) + +static inline void _Py_SetImmortal(PyObject *op) +{ + if (op) { + op->ob_refcnt = _Py_IMMORTAL_REFCNT; + } +} +#define _Py_SetImmortal(op) _Py_SetImmortal(_PyObject_CAST(op)) + +/* _Py_ClearImmortal() should only be used during runtime finalization. */ +static inline void _Py_ClearImmortal(PyObject *op) +{ + if (op) { + assert(op->ob_refcnt == _Py_IMMORTAL_REFCNT); + op->ob_refcnt = 1; + Py_DECREF(op); + } +} +#define _Py_ClearImmortal(op) \ + do { \ + _Py_ClearImmortal(_PyObject_CAST(op)); \ + op = NULL; \ + } while (0) static inline void _Py_DECREF_SPECIALIZED(PyObject *op, const destructor destruct) { + if (_Py_IsImmortal(op)) { + return; + } + _Py_DECREF_STAT_INC(); #ifdef Py_REF_DEBUG - _Py_RefTotal--; + _Py_DEC_REFTOTAL(_PyInterpreterState_GET()); #endif if (--op->ob_refcnt != 0) { assert(op->ob_refcnt > 0); @@ -51,8 +115,12 @@ _Py_DECREF_SPECIALIZED(PyObject *op, const destructor destruct) static inline void _Py_DECREF_NO_DEALLOC(PyObject *op) { + if (_Py_IsImmortal(op)) { + return; + } + _Py_DECREF_STAT_INC(); #ifdef Py_REF_DEBUG - _Py_RefTotal--; + _Py_DEC_REFTOTAL(_PyInterpreterState_GET()); #endif op->ob_refcnt--; #ifdef Py_DEBUG @@ -62,6 +130,11 @@ _Py_DECREF_NO_DEALLOC(PyObject *op) #endif } +#ifdef Py_REF_DEBUG +# undef _Py_DEC_REFTOTAL +#endif + + PyAPI_FUNC(int) _PyType_CheckConsistency(PyTypeObject *type); PyAPI_FUNC(int) _PyDict_CheckConsistency(PyObject *mp, int check_content); @@ -79,6 +152,7 @@ _PyType_HasFeature(PyTypeObject *type, unsigned long feature) { extern void _PyType_InitCache(PyInterpreterState *interp); +extern void _PyObject_InitState(PyInterpreterState *interp); /* Inline functions trading binary compatibility for speed: _PyObject_Init() is the fast version of PyObject_Init(), and @@ -100,8 +174,9 @@ static inline void _PyObject_InitVar(PyVarObject *op, PyTypeObject *typeobj, Py_ssize_t size) { assert(op != NULL); - Py_SET_SIZE(op, size); + assert(typeobj != &PyLong_Type); _PyObject_Init((PyObject *)op, typeobj); + Py_SET_SIZE(op, size); } @@ -190,22 +265,64 @@ static inline void _PyObject_GC_UNTRACK( #endif #ifdef Py_REF_DEBUG +extern void _PyInterpreterState_FinalizeRefTotal(PyInterpreterState *); +extern void _Py_FinalizeRefTotal(_PyRuntimeState *); extern void _PyDebug_PrintTotalRefs(void); #endif #ifdef Py_TRACE_REFS extern void _Py_AddToAllObjects(PyObject *op, int force); -extern void _Py_PrintReferences(FILE *); -extern void _Py_PrintReferenceAddresses(FILE *); +extern void _Py_PrintReferences(PyInterpreterState *, FILE *); +extern void _Py_PrintReferenceAddresses(PyInterpreterState *, FILE *); #endif + +/* Return the *address* of the object's weaklist. The address may be + * dereferenced to get the current head of the weaklist. This is useful + * for iterating over the linked list of weakrefs, especially when the + * list is being modified externally (e.g. refs getting removed). + * + * The returned pointer should not be used to change the head of the list + * nor should it be used to add, remove, or swap any refs in the list. + * That is the sole responsibility of the code in weakrefobject.c. + */ static inline PyObject ** _PyObject_GET_WEAKREFS_LISTPTR(PyObject *op) { + if (PyType_Check(op) && + ((PyTypeObject *)op)->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) { + PyInterpreterState *interp = _PyInterpreterState_GET(); + static_builtin_state *state = _PyStaticType_GetState( + interp, (PyTypeObject *)op); + return _PyStaticType_GET_WEAKREFS_LISTPTR(state); + } + // Essentially _PyObject_GET_WEAKREFS_LISTPTR_FROM_OFFSET(): Py_ssize_t offset = Py_TYPE(op)->tp_weaklistoffset; return (PyObject **)((char *)op + offset); } +/* This is a special case of _PyObject_GET_WEAKREFS_LISTPTR(). + * Only the most fundamental lookup path is used. + * Consequently, static types should not be used. + * + * For static builtin types the returned pointer will always point + * to a NULL tp_weaklist. This is fine for any deallocation cases, + * since static types are never deallocated and static builtin types + * are only finalized at the end of runtime finalization. + * + * If the weaklist for static types is actually needed then use + * _PyObject_GET_WEAKREFS_LISTPTR(). + */ +static inline PyWeakReference ** +_PyObject_GET_WEAKREFS_LISTPTR_FROM_OFFSET(PyObject *op) +{ + assert(!PyType_Check(op) || + ((PyTypeObject *)op)->tp_flags & Py_TPFLAGS_HEAPTYPE); + Py_ssize_t offset = Py_TYPE(op)->tp_weaklistoffset; + return (PyWeakReference **)((char *)op + offset); +} + + // Fast inlined version of PyObject_IS_GC() static inline int _PyObject_IS_GC(PyObject *obj) @@ -222,7 +339,7 @@ static inline size_t _PyType_PreHeaderSize(PyTypeObject *tp) { return _PyType_IS_GC(tp) * sizeof(PyGC_Head) + - _PyType_HasFeature(tp, Py_TPFLAGS_MANAGED_DICT) * 2 * sizeof(PyObject *); + _PyType_HasFeature(tp, Py_TPFLAGS_PREHEADER) * 2 * sizeof(PyObject *); } void _PyObject_GC_Link(PyObject *op); @@ -233,13 +350,9 @@ extern int _Py_CheckSlotResult( const char *slot_name, int success); -// PyType_Ready() must be called if _PyType_IsReady() is false. -// See also the Py_TPFLAGS_READY flag. -#define _PyType_IsReady(type) ((type)->tp_dict != NULL) - // Test if a type supports weak references static inline int _PyType_SUPPORTS_WEAKREFS(PyTypeObject *type) { - return (type->tp_weaklistoffset > 0); + return (type->tp_weaklistoffset != 0); } extern PyObject* _PyType_AllocNoTrack(PyTypeObject *type, Py_ssize_t nitems); @@ -250,30 +363,50 @@ extern int _PyObject_StoreInstanceAttribute(PyObject *obj, PyDictValues *values, PyObject * _PyObject_GetInstanceAttribute(PyObject *obj, PyDictValues *values, PyObject *name); -static inline PyDictValues **_PyObject_ValuesPointer(PyObject *obj) +typedef union { + PyObject *dict; + /* Use a char* to generate a warning if directly assigning a PyDictValues */ + char *values; +} PyDictOrValues; + +static inline PyDictOrValues * +_PyObject_DictOrValuesPointer(PyObject *obj) { assert(Py_TYPE(obj)->tp_flags & Py_TPFLAGS_MANAGED_DICT); - return ((PyDictValues **)obj)-4; + return ((PyDictOrValues *)obj)-3; } -static inline PyObject **_PyObject_ManagedDictPointer(PyObject *obj) +static inline int +_PyDictOrValues_IsValues(PyDictOrValues dorv) { - assert(Py_TYPE(obj)->tp_flags & Py_TPFLAGS_MANAGED_DICT); - return ((PyObject **)obj)-3; + return ((uintptr_t)dorv.values) & 1; } -#define MANAGED_DICT_OFFSET (((int)sizeof(PyObject *))*-3) +static inline PyDictValues * +_PyDictOrValues_GetValues(PyDictOrValues dorv) +{ + assert(_PyDictOrValues_IsValues(dorv)); + return (PyDictValues *)(dorv.values + 1); +} -extern PyObject ** _PyObject_DictPointer(PyObject *); -extern int _PyObject_VisitInstanceAttributes(PyObject *self, visitproc visit, void *arg); -extern void _PyObject_ClearInstanceAttributes(PyObject *self); -extern void _PyObject_FreeInstanceAttributes(PyObject *self); -extern int _PyObject_IsInstanceDictEmpty(PyObject *); -extern PyObject* _PyType_GetSubclasses(PyTypeObject *); +static inline PyObject * +_PyDictOrValues_GetDict(PyDictOrValues dorv) +{ + assert(!_PyDictOrValues_IsValues(dorv)); + return dorv.dict; +} -// Access macro to the members which are floating "behind" the object -#define _PyHeapType_GET_MEMBERS(etype) \ - ((PyMemberDef *)(((char *)etype) + Py_TYPE(etype)->tp_basicsize)) +static inline void +_PyDictOrValues_SetValues(PyDictOrValues *ptr, PyDictValues *values) +{ + ptr->values = ((char *)values) - 1; +} + +#define MANAGED_WEAKREF_OFFSET (((Py_ssize_t)sizeof(PyObject *))*-4) + +extern PyObject ** _PyObject_ComputedDictPointer(PyObject *); +extern void _PyObject_FreeInstanceAttributes(PyObject *obj); +extern int _PyObject_IsInstanceDictEmpty(PyObject *); PyAPI_FUNC(PyObject *) _PyObject_LookupSpecial(PyObject *, PyObject *); @@ -289,12 +422,12 @@ PyAPI_FUNC(PyObject *) _PyObject_LookupSpecial(PyObject *, PyObject *); * match. * * Third party code unintentionally rely on problematic fpcasts. The call - * trampoline mitigates common occurences of bad fpcasts on Emscripten. + * trampoline mitigates common occurrences of bad fpcasts on Emscripten. */ #if defined(__EMSCRIPTEN__) && defined(PY_CALL_TRAMPOLINE) #define _PyCFunction_TrampolineCall(meth, self, args) \ _PyCFunctionWithKeywords_TrampolineCall( \ - (*(PyCFunctionWithKeywords)(void(*)(void))meth), self, args, NULL) + (*(PyCFunctionWithKeywords)(void(*)(void))(meth)), (self), (args), NULL) extern PyObject* _PyCFunctionWithKeywords_TrampolineCall( PyCFunctionWithKeywords meth, PyObject *, PyObject *, PyObject *); #else diff --git a/Include/internal/pycore_object_state.h b/Include/internal/pycore_object_state.h new file mode 100644 index 00000000..65feb5af --- /dev/null +++ b/Include/internal/pycore_object_state.h @@ -0,0 +1,36 @@ +#ifndef Py_INTERNAL_OBJECT_STATE_H +#define Py_INTERNAL_OBJECT_STATE_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +struct _py_object_runtime_state { +#ifdef Py_REF_DEBUG + Py_ssize_t interpreter_leaks; +#endif + int _not_used; +}; + +struct _py_object_state { +#ifdef Py_REF_DEBUG + Py_ssize_t reftotal; +#endif +#ifdef Py_TRACE_REFS + /* Head of circular doubly-linked list of all objects. These are linked + * together via the _ob_prev and _ob_next members of a PyObject, which + * exist only in a Py_TRACE_REFS build. + */ + PyObject refchain; +#endif + int _not_used; +}; + + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_OBJECT_STATE_H */ diff --git a/Include/internal/pycore_obmalloc.h b/Include/internal/pycore_obmalloc.h new file mode 100644 index 00000000..ca2a0419 --- /dev/null +++ b/Include/internal/pycore_obmalloc.h @@ -0,0 +1,698 @@ +#ifndef Py_INTERNAL_OBMALLOC_H +#define Py_INTERNAL_OBMALLOC_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + + +typedef unsigned int pymem_uint; /* assuming >= 16 bits */ + +#undef uint +#define uint pymem_uint + + +/* An object allocator for Python. + + Here is an introduction to the layers of the Python memory architecture, + showing where the object allocator is actually used (layer +2), It is + called for every object allocation and deallocation (PyObject_New/Del), + unless the object-specific allocators implement a proprietary allocation + scheme (ex.: ints use a simple free list). This is also the place where + the cyclic garbage collector operates selectively on container objects. + + + Object-specific allocators + _____ ______ ______ ________ + [ int ] [ dict ] [ list ] ... [ string ] Python core | ++3 | <----- Object-specific memory -----> | <-- Non-object memory --> | + _______________________________ | | + [ Python's object allocator ] | | ++2 | ####### Object memory ####### | <------ Internal buffers ------> | + ______________________________________________________________ | + [ Python's raw memory allocator (PyMem_ API) ] | ++1 | <----- Python memory (under PyMem manager's control) ------> | | + __________________________________________________________________ + [ Underlying general-purpose allocator (ex: C library malloc) ] + 0 | <------ Virtual memory allocated for the python process -------> | + + ========================================================================= + _______________________________________________________________________ + [ OS-specific Virtual Memory Manager (VMM) ] +-1 | <--- Kernel dynamic storage allocation & management (page-based) ---> | + __________________________________ __________________________________ + [ ] [ ] +-2 | <-- Physical memory: ROM/RAM --> | | <-- Secondary storage (swap) --> | + +*/ +/*==========================================================================*/ + +/* A fast, special-purpose memory allocator for small blocks, to be used + on top of a general-purpose malloc -- heavily based on previous art. */ + +/* Vladimir Marangozov -- August 2000 */ + +/* + * "Memory management is where the rubber meets the road -- if we do the wrong + * thing at any level, the results will not be good. And if we don't make the + * levels work well together, we are in serious trouble." (1) + * + * (1) Paul R. Wilson, Mark S. Johnstone, Michael Neely, and David Boles, + * "Dynamic Storage Allocation: A Survey and Critical Review", + * in Proc. 1995 Int'l. Workshop on Memory Management, September 1995. + */ + +/* #undef WITH_MEMORY_LIMITS */ /* disable mem limit checks */ + +/*==========================================================================*/ + +/* + * Allocation strategy abstract: + * + * For small requests, the allocator sub-allocates <Big> blocks of memory. + * Requests greater than SMALL_REQUEST_THRESHOLD bytes are routed to the + * system's allocator. + * + * Small requests are grouped in size classes spaced 8 bytes apart, due + * to the required valid alignment of the returned address. Requests of + * a particular size are serviced from memory pools of 4K (one VMM page). + * Pools are fragmented on demand and contain free lists of blocks of one + * particular size class. In other words, there is a fixed-size allocator + * for each size class. Free pools are shared by the different allocators + * thus minimizing the space reserved for a particular size class. + * + * This allocation strategy is a variant of what is known as "simple + * segregated storage based on array of free lists". The main drawback of + * simple segregated storage is that we might end up with lot of reserved + * memory for the different free lists, which degenerate in time. To avoid + * this, we partition each free list in pools and we share dynamically the + * reserved space between all free lists. This technique is quite efficient + * for memory intensive programs which allocate mainly small-sized blocks. + * + * For small requests we have the following table: + * + * Request in bytes Size of allocated block Size class idx + * ---------------------------------------------------------------- + * 1-8 8 0 + * 9-16 16 1 + * 17-24 24 2 + * 25-32 32 3 + * 33-40 40 4 + * 41-48 48 5 + * 49-56 56 6 + * 57-64 64 7 + * 65-72 72 8 + * ... ... ... + * 497-504 504 62 + * 505-512 512 63 + * + * 0, SMALL_REQUEST_THRESHOLD + 1 and up: routed to the underlying + * allocator. + */ + +/*==========================================================================*/ + +/* + * -- Main tunable settings section -- + */ + +/* + * Alignment of addresses returned to the user. 8-bytes alignment works + * on most current architectures (with 32-bit or 64-bit address buses). + * The alignment value is also used for grouping small requests in size + * classes spaced ALIGNMENT bytes apart. + * + * You shouldn't change this unless you know what you are doing. + */ + +#if SIZEOF_VOID_P > 4 +#define ALIGNMENT 16 /* must be 2^N */ +#define ALIGNMENT_SHIFT 4 +#else +#define ALIGNMENT 8 /* must be 2^N */ +#define ALIGNMENT_SHIFT 3 +#endif + +/* Return the number of bytes in size class I, as a uint. */ +#define INDEX2SIZE(I) (((pymem_uint)(I) + 1) << ALIGNMENT_SHIFT) + +/* + * Max size threshold below which malloc requests are considered to be + * small enough in order to use preallocated memory pools. You can tune + * this value according to your application behaviour and memory needs. + * + * Note: a size threshold of 512 guarantees that newly created dictionaries + * will be allocated from preallocated memory pools on 64-bit. + * + * The following invariants must hold: + * 1) ALIGNMENT <= SMALL_REQUEST_THRESHOLD <= 512 + * 2) SMALL_REQUEST_THRESHOLD is evenly divisible by ALIGNMENT + * + * Although not required, for better performance and space efficiency, + * it is recommended that SMALL_REQUEST_THRESHOLD is set to a power of 2. + */ +#define SMALL_REQUEST_THRESHOLD 512 +#define NB_SMALL_SIZE_CLASSES (SMALL_REQUEST_THRESHOLD / ALIGNMENT) + +/* + * The system's VMM page size can be obtained on most unices with a + * getpagesize() call or deduced from various header files. To make + * things simpler, we assume that it is 4K, which is OK for most systems. + * It is probably better if this is the native page size, but it doesn't + * have to be. In theory, if SYSTEM_PAGE_SIZE is larger than the native page + * size, then `POOL_ADDR(p)->arenaindex' could rarely cause a segmentation + * violation fault. 4K is apparently OK for all the platforms that python + * currently targets. + */ +#define SYSTEM_PAGE_SIZE (4 * 1024) + +/* + * Maximum amount of memory managed by the allocator for small requests. + */ +#ifdef WITH_MEMORY_LIMITS +#ifndef SMALL_MEMORY_LIMIT +#define SMALL_MEMORY_LIMIT (64 * 1024 * 1024) /* 64 MB -- more? */ +#endif +#endif + +#if !defined(WITH_PYMALLOC_RADIX_TREE) +/* Use radix-tree to track arena memory regions, for address_in_range(). + * Enable by default since it allows larger pool sizes. Can be disabled + * using -DWITH_PYMALLOC_RADIX_TREE=0 */ +#define WITH_PYMALLOC_RADIX_TREE 1 +#endif + +#if SIZEOF_VOID_P > 4 +/* on 64-bit platforms use larger pools and arenas if we can */ +#define USE_LARGE_ARENAS +#if WITH_PYMALLOC_RADIX_TREE +/* large pools only supported if radix-tree is enabled */ +#define USE_LARGE_POOLS +#endif +#endif + +/* + * The allocator sub-allocates <Big> blocks of memory (called arenas) aligned + * on a page boundary. This is a reserved virtual address space for the + * current process (obtained through a malloc()/mmap() call). In no way this + * means that the memory arenas will be used entirely. A malloc(<Big>) is + * usually an address range reservation for <Big> bytes, unless all pages within + * this space are referenced subsequently. So malloc'ing big blocks and not + * using them does not mean "wasting memory". It's an addressable range + * wastage... + * + * Arenas are allocated with mmap() on systems supporting anonymous memory + * mappings to reduce heap fragmentation. + */ +#ifdef USE_LARGE_ARENAS +#define ARENA_BITS 20 /* 1 MiB */ +#else +#define ARENA_BITS 18 /* 256 KiB */ +#endif +#define ARENA_SIZE (1 << ARENA_BITS) +#define ARENA_SIZE_MASK (ARENA_SIZE - 1) + +#ifdef WITH_MEMORY_LIMITS +#define MAX_ARENAS (SMALL_MEMORY_LIMIT / ARENA_SIZE) +#endif + +/* + * Size of the pools used for small blocks. Must be a power of 2. + */ +#ifdef USE_LARGE_POOLS +#define POOL_BITS 14 /* 16 KiB */ +#else +#define POOL_BITS 12 /* 4 KiB */ +#endif +#define POOL_SIZE (1 << POOL_BITS) +#define POOL_SIZE_MASK (POOL_SIZE - 1) + +#if !WITH_PYMALLOC_RADIX_TREE +#if POOL_SIZE != SYSTEM_PAGE_SIZE +# error "pool size must be equal to system page size" +#endif +#endif + +#define MAX_POOLS_IN_ARENA (ARENA_SIZE / POOL_SIZE) +#if MAX_POOLS_IN_ARENA * POOL_SIZE != ARENA_SIZE +# error "arena size not an exact multiple of pool size" +#endif + +/* + * -- End of tunable settings section -- + */ + +/*==========================================================================*/ + +/* When you say memory, my mind reasons in terms of (pointers to) blocks */ +typedef uint8_t pymem_block; + +/* Pool for small blocks. */ +struct pool_header { + union { pymem_block *_padding; + uint count; } ref; /* number of allocated blocks */ + pymem_block *freeblock; /* pool's free list head */ + struct pool_header *nextpool; /* next pool of this size class */ + struct pool_header *prevpool; /* previous pool "" */ + uint arenaindex; /* index into arenas of base adr */ + uint szidx; /* block size class index */ + uint nextoffset; /* bytes to virgin block */ + uint maxnextoffset; /* largest valid nextoffset */ +}; + +typedef struct pool_header *poolp; + +/* Record keeping for arenas. */ +struct arena_object { + /* The address of the arena, as returned by malloc. Note that 0 + * will never be returned by a successful malloc, and is used + * here to mark an arena_object that doesn't correspond to an + * allocated arena. + */ + uintptr_t address; + + /* Pool-aligned pointer to the next pool to be carved off. */ + pymem_block* pool_address; + + /* The number of available pools in the arena: free pools + never- + * allocated pools. + */ + uint nfreepools; + + /* The total number of pools in the arena, whether or not available. */ + uint ntotalpools; + + /* Singly-linked list of available pools. */ + struct pool_header* freepools; + + /* Whenever this arena_object is not associated with an allocated + * arena, the nextarena member is used to link all unassociated + * arena_objects in the singly-linked `unused_arena_objects` list. + * The prevarena member is unused in this case. + * + * When this arena_object is associated with an allocated arena + * with at least one available pool, both members are used in the + * doubly-linked `usable_arenas` list, which is maintained in + * increasing order of `nfreepools` values. + * + * Else this arena_object is associated with an allocated arena + * all of whose pools are in use. `nextarena` and `prevarena` + * are both meaningless in this case. + */ + struct arena_object* nextarena; + struct arena_object* prevarena; +}; + +#define POOL_OVERHEAD _Py_SIZE_ROUND_UP(sizeof(struct pool_header), ALIGNMENT) + +#define DUMMY_SIZE_IDX 0xffff /* size class of newly cached pools */ + +/* Round pointer P down to the closest pool-aligned address <= P, as a poolp */ +#define POOL_ADDR(P) ((poolp)_Py_ALIGN_DOWN((P), POOL_SIZE)) + +/* Return total number of blocks in pool of size index I, as a uint. */ +#define NUMBLOCKS(I) ((pymem_uint)(POOL_SIZE - POOL_OVERHEAD) / INDEX2SIZE(I)) + +/*==========================================================================*/ + +/* + * Pool table -- headed, circular, doubly-linked lists of partially used pools. + +This is involved. For an index i, usedpools[i+i] is the header for a list of +all partially used pools holding small blocks with "size class idx" i. So +usedpools[0] corresponds to blocks of size 8, usedpools[2] to blocks of size +16, and so on: index 2*i <-> blocks of size (i+1)<<ALIGNMENT_SHIFT. + +Pools are carved off an arena's highwater mark (an arena_object's pool_address +member) as needed. Once carved off, a pool is in one of three states forever +after: + +used == partially used, neither empty nor full + At least one block in the pool is currently allocated, and at least one + block in the pool is not currently allocated (note this implies a pool + has room for at least two blocks). + This is a pool's initial state, as a pool is created only when malloc + needs space. + The pool holds blocks of a fixed size, and is in the circular list headed + at usedpools[i] (see above). It's linked to the other used pools of the + same size class via the pool_header's nextpool and prevpool members. + If all but one block is currently allocated, a malloc can cause a + transition to the full state. If all but one block is not currently + allocated, a free can cause a transition to the empty state. + +full == all the pool's blocks are currently allocated + On transition to full, a pool is unlinked from its usedpools[] list. + It's not linked to from anything then anymore, and its nextpool and + prevpool members are meaningless until it transitions back to used. + A free of a block in a full pool puts the pool back in the used state. + Then it's linked in at the front of the appropriate usedpools[] list, so + that the next allocation for its size class will reuse the freed block. + +empty == all the pool's blocks are currently available for allocation + On transition to empty, a pool is unlinked from its usedpools[] list, + and linked to the front of its arena_object's singly-linked freepools list, + via its nextpool member. The prevpool member has no meaning in this case. + Empty pools have no inherent size class: the next time a malloc finds + an empty list in usedpools[], it takes the first pool off of freepools. + If the size class needed happens to be the same as the size class the pool + last had, some pool initialization can be skipped. + + +Block Management + +Blocks within pools are again carved out as needed. pool->freeblock points to +the start of a singly-linked list of free blocks within the pool. When a +block is freed, it's inserted at the front of its pool's freeblock list. Note +that the available blocks in a pool are *not* linked all together when a pool +is initialized. Instead only "the first two" (lowest addresses) blocks are +set up, returning the first such block, and setting pool->freeblock to a +one-block list holding the second such block. This is consistent with that +pymalloc strives at all levels (arena, pool, and block) never to touch a piece +of memory until it's actually needed. + +So long as a pool is in the used state, we're certain there *is* a block +available for allocating, and pool->freeblock is not NULL. If pool->freeblock +points to the end of the free list before we've carved the entire pool into +blocks, that means we simply haven't yet gotten to one of the higher-address +blocks. The offset from the pool_header to the start of "the next" virgin +block is stored in the pool_header nextoffset member, and the largest value +of nextoffset that makes sense is stored in the maxnextoffset member when a +pool is initialized. All the blocks in a pool have been passed out at least +once when and only when nextoffset > maxnextoffset. + + +Major obscurity: While the usedpools vector is declared to have poolp +entries, it doesn't really. It really contains two pointers per (conceptual) +poolp entry, the nextpool and prevpool members of a pool_header. The +excruciating initialization code below fools C so that + + usedpool[i+i] + +"acts like" a genuine poolp, but only so long as you only reference its +nextpool and prevpool members. The "- 2*sizeof(pymem_block *)" gibberish is +compensating for that a pool_header's nextpool and prevpool members +immediately follow a pool_header's first two members: + + union { pymem_block *_padding; + uint count; } ref; + pymem_block *freeblock; + +each of which consume sizeof(pymem_block *) bytes. So what usedpools[i+i] really +contains is a fudged-up pointer p such that *if* C believes it's a poolp +pointer, then p->nextpool and p->prevpool are both p (meaning that the headed +circular list is empty). + +It's unclear why the usedpools setup is so convoluted. It could be to +minimize the amount of cache required to hold this heavily-referenced table +(which only *needs* the two interpool pointer members of a pool_header). OTOH, +referencing code has to remember to "double the index" and doing so isn't +free, usedpools[0] isn't a strictly legal pointer, and we're crucially relying +on that C doesn't insert any padding anywhere in a pool_header at or before +the prevpool member. +**************************************************************************** */ + +#define OBMALLOC_USED_POOLS_SIZE (2 * ((NB_SMALL_SIZE_CLASSES + 7) / 8) * 8) + +struct _obmalloc_pools { + poolp used[OBMALLOC_USED_POOLS_SIZE]; +}; + + +/*========================================================================== +Arena management. + +`arenas` is a vector of arena_objects. It contains maxarenas entries, some of +which may not be currently used (== they're arena_objects that aren't +currently associated with an allocated arena). Note that arenas proper are +separately malloc'ed. + +Prior to Python 2.5, arenas were never free()'ed. Starting with Python 2.5, +we do try to free() arenas, and use some mild heuristic strategies to increase +the likelihood that arenas eventually can be freed. + +unused_arena_objects + + This is a singly-linked list of the arena_objects that are currently not + being used (no arena is associated with them). Objects are taken off the + head of the list in new_arena(), and are pushed on the head of the list in + PyObject_Free() when the arena is empty. Key invariant: an arena_object + is on this list if and only if its .address member is 0. + +usable_arenas + + This is a doubly-linked list of the arena_objects associated with arenas + that have pools available. These pools are either waiting to be reused, + or have not been used before. The list is sorted to have the most- + allocated arenas first (ascending order based on the nfreepools member). + This means that the next allocation will come from a heavily used arena, + which gives the nearly empty arenas a chance to be returned to the system. + In my unscientific tests this dramatically improved the number of arenas + that could be freed. + +Note that an arena_object associated with an arena all of whose pools are +currently in use isn't on either list. + +Changed in Python 3.8: keeping usable_arenas sorted by number of free pools +used to be done by one-at-a-time linear search when an arena's number of +free pools changed. That could, overall, consume time quadratic in the +number of arenas. That didn't really matter when there were only a few +hundred arenas (typical!), but could be a timing disaster when there were +hundreds of thousands. See bpo-37029. + +Now we have a vector of "search fingers" to eliminate the need to search: +nfp2lasta[nfp] returns the last ("rightmost") arena in usable_arenas +with nfp free pools. This is NULL if and only if there is no arena with +nfp free pools in usable_arenas. +*/ + +/* How many arena_objects do we initially allocate? + * 16 = can allocate 16 arenas = 16 * ARENA_SIZE = 4MB before growing the + * `arenas` vector. + */ +#define INITIAL_ARENA_OBJECTS 16 + +struct _obmalloc_mgmt { + /* Array of objects used to track chunks of memory (arenas). */ + struct arena_object* arenas; + /* Number of slots currently allocated in the `arenas` vector. */ + uint maxarenas; + + /* The head of the singly-linked, NULL-terminated list of available + * arena_objects. + */ + struct arena_object* unused_arena_objects; + + /* The head of the doubly-linked, NULL-terminated at each end, list of + * arena_objects associated with arenas that have pools available. + */ + struct arena_object* usable_arenas; + + /* nfp2lasta[nfp] is the last arena in usable_arenas with nfp free pools */ + struct arena_object* nfp2lasta[MAX_POOLS_IN_ARENA + 1]; + + /* Number of arenas allocated that haven't been free()'d. */ + size_t narenas_currently_allocated; + + /* Total number of times malloc() called to allocate an arena. */ + size_t ntimes_arena_allocated; + /* High water mark (max value ever seen) for narenas_currently_allocated. */ + size_t narenas_highwater; + + Py_ssize_t raw_allocated_blocks; +}; + + +#if WITH_PYMALLOC_RADIX_TREE +/*==========================================================================*/ +/* radix tree for tracking arena usage. If enabled, used to implement + address_in_range(). + + memory address bit allocation for keys + + 64-bit pointers, IGNORE_BITS=0 and 2^20 arena size: + 15 -> MAP_TOP_BITS + 15 -> MAP_MID_BITS + 14 -> MAP_BOT_BITS + 20 -> ideal aligned arena + ---- + 64 + + 64-bit pointers, IGNORE_BITS=16, and 2^20 arena size: + 16 -> IGNORE_BITS + 10 -> MAP_TOP_BITS + 10 -> MAP_MID_BITS + 8 -> MAP_BOT_BITS + 20 -> ideal aligned arena + ---- + 64 + + 32-bit pointers and 2^18 arena size: + 14 -> MAP_BOT_BITS + 18 -> ideal aligned arena + ---- + 32 + +*/ + +#if SIZEOF_VOID_P == 8 + +/* number of bits in a pointer */ +#define POINTER_BITS 64 + +/* High bits of memory addresses that will be ignored when indexing into the + * radix tree. Setting this to zero is the safe default. For most 64-bit + * machines, setting this to 16 would be safe. The kernel would not give + * user-space virtual memory addresses that have significant information in + * those high bits. The main advantage to setting IGNORE_BITS > 0 is that less + * virtual memory will be used for the top and middle radix tree arrays. Those + * arrays are allocated in the BSS segment and so will typically consume real + * memory only if actually accessed. + */ +#define IGNORE_BITS 0 + +/* use the top and mid layers of the radix tree */ +#define USE_INTERIOR_NODES + +#elif SIZEOF_VOID_P == 4 + +#define POINTER_BITS 32 +#define IGNORE_BITS 0 + +#else + + /* Currently this code works for 64-bit or 32-bit pointers only. */ +#error "obmalloc radix tree requires 64-bit or 32-bit pointers." + +#endif /* SIZEOF_VOID_P */ + +/* arena_coverage_t members require this to be true */ +#if ARENA_BITS >= 32 +# error "arena size must be < 2^32" +#endif + +/* the lower bits of the address that are not ignored */ +#define ADDRESS_BITS (POINTER_BITS - IGNORE_BITS) + +#ifdef USE_INTERIOR_NODES +/* number of bits used for MAP_TOP and MAP_MID nodes */ +#define INTERIOR_BITS ((ADDRESS_BITS - ARENA_BITS + 2) / 3) +#else +#define INTERIOR_BITS 0 +#endif + +#define MAP_TOP_BITS INTERIOR_BITS +#define MAP_TOP_LENGTH (1 << MAP_TOP_BITS) +#define MAP_TOP_MASK (MAP_TOP_LENGTH - 1) + +#define MAP_MID_BITS INTERIOR_BITS +#define MAP_MID_LENGTH (1 << MAP_MID_BITS) +#define MAP_MID_MASK (MAP_MID_LENGTH - 1) + +#define MAP_BOT_BITS (ADDRESS_BITS - ARENA_BITS - 2*INTERIOR_BITS) +#define MAP_BOT_LENGTH (1 << MAP_BOT_BITS) +#define MAP_BOT_MASK (MAP_BOT_LENGTH - 1) + +#define MAP_BOT_SHIFT ARENA_BITS +#define MAP_MID_SHIFT (MAP_BOT_BITS + MAP_BOT_SHIFT) +#define MAP_TOP_SHIFT (MAP_MID_BITS + MAP_MID_SHIFT) + +#define AS_UINT(p) ((uintptr_t)(p)) +#define MAP_BOT_INDEX(p) ((AS_UINT(p) >> MAP_BOT_SHIFT) & MAP_BOT_MASK) +#define MAP_MID_INDEX(p) ((AS_UINT(p) >> MAP_MID_SHIFT) & MAP_MID_MASK) +#define MAP_TOP_INDEX(p) ((AS_UINT(p) >> MAP_TOP_SHIFT) & MAP_TOP_MASK) + +#if IGNORE_BITS > 0 +/* Return the ignored part of the pointer address. Those bits should be same + * for all valid pointers if IGNORE_BITS is set correctly. + */ +#define HIGH_BITS(p) (AS_UINT(p) >> ADDRESS_BITS) +#else +#define HIGH_BITS(p) 0 +#endif + + +/* This is the leaf of the radix tree. See arena_map_mark_used() for the + * meaning of these members. */ +typedef struct { + int32_t tail_hi; + int32_t tail_lo; +} arena_coverage_t; + +typedef struct arena_map_bot { + /* The members tail_hi and tail_lo are accessed together. So, it + * better to have them as an array of structs, rather than two + * arrays. + */ + arena_coverage_t arenas[MAP_BOT_LENGTH]; +} arena_map_bot_t; + +#ifdef USE_INTERIOR_NODES +typedef struct arena_map_mid { + struct arena_map_bot *ptrs[MAP_MID_LENGTH]; +} arena_map_mid_t; + +typedef struct arena_map_top { + struct arena_map_mid *ptrs[MAP_TOP_LENGTH]; +} arena_map_top_t; +#endif + +struct _obmalloc_usage { + /* The root of radix tree. Note that by initializing like this, the memory + * should be in the BSS. The OS will only memory map pages as the MAP_MID + * nodes get used (OS pages are demand loaded as needed). + */ +#ifdef USE_INTERIOR_NODES + arena_map_top_t arena_map_root; + /* accounting for number of used interior nodes */ + int arena_map_mid_count; + int arena_map_bot_count; +#else + arena_map_bot_t arena_map_root; +#endif +}; + +#endif /* WITH_PYMALLOC_RADIX_TREE */ + + +struct _obmalloc_global_state { + int dump_debug_stats; + Py_ssize_t interpreter_leaks; +}; + +struct _obmalloc_state { + struct _obmalloc_pools pools; + struct _obmalloc_mgmt mgmt; + struct _obmalloc_usage usage; +}; + + +#undef uint + + +/* Allocate memory directly from the O/S virtual memory system, + * where supported. Otherwise fallback on malloc */ +void *_PyObject_VirtualAlloc(size_t size); +void _PyObject_VirtualFree(void *, size_t size); + + +/* This function returns the number of allocated memory blocks, regardless of size */ +extern Py_ssize_t _Py_GetGlobalAllocatedBlocks(void); +#define _Py_GetAllocatedBlocks() \ + _Py_GetGlobalAllocatedBlocks() +extern Py_ssize_t _PyInterpreterState_GetAllocatedBlocks(PyInterpreterState *); +extern void _PyInterpreterState_FinalizeAllocatedBlocks(PyInterpreterState *); + + +#ifdef WITH_PYMALLOC +// Export the symbol for the 3rd party guppy3 project +PyAPI_FUNC(int) _PyObject_DebugMallocStats(FILE *out); +#endif + + +#ifdef __cplusplus +} +#endif +#endif // !Py_INTERNAL_OBMALLOC_H diff --git a/Include/internal/pycore_obmalloc_init.h b/Include/internal/pycore_obmalloc_init.h new file mode 100644 index 00000000..8ee72ff2 --- /dev/null +++ b/Include/internal/pycore_obmalloc_init.h @@ -0,0 +1,73 @@ +#ifndef Py_INTERNAL_OBMALLOC_INIT_H +#define Py_INTERNAL_OBMALLOC_INIT_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + + +/****************************************************/ +/* the default object allocator's state initializer */ + +#define PTA(pools, x) \ + ((poolp )((uint8_t *)&(pools.used[2*(x)]) - 2*sizeof(pymem_block *))) +#define PT(p, x) PTA(p, x), PTA(p, x) + +#define PT_8(p, start) \ + PT(p, start), \ + PT(p, start+1), \ + PT(p, start+2), \ + PT(p, start+3), \ + PT(p, start+4), \ + PT(p, start+5), \ + PT(p, start+6), \ + PT(p, start+7) + +#if NB_SMALL_SIZE_CLASSES <= 8 +# define _obmalloc_pools_INIT(p) \ + { PT_8(p, 0) } +#elif NB_SMALL_SIZE_CLASSES <= 16 +# define _obmalloc_pools_INIT(p) \ + { PT_8(p, 0), PT_8(p, 8) } +#elif NB_SMALL_SIZE_CLASSES <= 24 +# define _obmalloc_pools_INIT(p) \ + { PT_8(p, 0), PT_8(p, 8), PT_8(p, 16) } +#elif NB_SMALL_SIZE_CLASSES <= 32 +# define _obmalloc_pools_INIT(p) \ + { PT_8(p, 0), PT_8(p, 8), PT_8(p, 16), PT_8(p, 24) } +#elif NB_SMALL_SIZE_CLASSES <= 40 +# define _obmalloc_pools_INIT(p) \ + { PT_8(p, 0), PT_8(p, 8), PT_8(p, 16), PT_8(p, 24), PT_8(p, 32) } +#elif NB_SMALL_SIZE_CLASSES <= 48 +# define _obmalloc_pools_INIT(p) \ + { PT_8(p, 0), PT_8(p, 8), PT_8(p, 16), PT_8(p, 24), PT_8(p, 32), PT_8(p, 40) } +#elif NB_SMALL_SIZE_CLASSES <= 56 +# define _obmalloc_pools_INIT(p) \ + { PT_8(p, 0), PT_8(p, 8), PT_8(p, 16), PT_8(p, 24), PT_8(p, 32), PT_8(p, 40), PT_8(p, 48) } +#elif NB_SMALL_SIZE_CLASSES <= 64 +# define _obmalloc_pools_INIT(p) \ + { PT_8(p, 0), PT_8(p, 8), PT_8(p, 16), PT_8(p, 24), PT_8(p, 32), PT_8(p, 40), PT_8(p, 48), PT_8(p, 56) } +#else +# error "NB_SMALL_SIZE_CLASSES should be less than 64" +#endif + +#define _obmalloc_global_state_INIT \ + { \ + .dump_debug_stats = -1, \ + } + +#define _obmalloc_state_INIT(obmalloc) \ + { \ + .pools = { \ + .used = _obmalloc_pools_INIT(obmalloc.pools), \ + }, \ + } + + +#ifdef __cplusplus +} +#endif +#endif // !Py_INTERNAL_OBMALLOC_INIT_H diff --git a/Include/internal/pycore_opcode.h b/Include/internal/pycore_opcode.h index eadcba1a..15d96503 100644 --- a/Include/internal/pycore_opcode.h +++ b/Include/internal/pycore_opcode.h @@ -1,4 +1,4 @@ -// Auto-generated by Tools/scripts/generate_opcode_h.py from Lib/opcode.py +// Auto-generated by Tools/build/generate_opcode_h.py from Lib/opcode.py #ifndef Py_INTERNAL_OPCODE_H #define Py_INTERNAL_OPCODE_H @@ -12,52 +12,44 @@ extern "C" { #include "opcode.h" +extern const uint32_t _PyOpcode_Jump[9]; + extern const uint8_t _PyOpcode_Caches[256]; extern const uint8_t _PyOpcode_Deopt[256]; #ifdef NEED_OPCODE_TABLES -static const uint32_t _PyOpcode_RelativeJump[8] = { +const uint32_t _PyOpcode_Jump[9] = { 0U, 0U, 536870912U, - 135118848U, + 135020544U, 4163U, - 122880U, - 0U, - 0U, -}; -static const uint32_t _PyOpcode_Jump[8] = { 0U, 0U, - 536870912U, - 135118848U, - 4163U, - 122880U, - 0U, 0U, + 48U, }; const uint8_t _PyOpcode_Caches[256] = { - [BINARY_SUBSCR] = 4, + [BINARY_SUBSCR] = 1, [STORE_SUBSCR] = 1, [UNPACK_SEQUENCE] = 1, + [FOR_ITER] = 1, [STORE_ATTR] = 4, - [LOAD_ATTR] = 4, - [COMPARE_OP] = 2, - [LOAD_GLOBAL] = 5, + [LOAD_ATTR] = 9, + [COMPARE_OP] = 1, + [LOAD_GLOBAL] = 4, [BINARY_OP] = 1, - [LOAD_METHOD] = 10, - [PRECALL] = 1, - [CALL] = 4, + [SEND] = 1, + [LOAD_SUPER_ATTR] = 1, + [CALL] = 3, }; const uint8_t _PyOpcode_Deopt[256] = { - [ASYNC_GEN_WRAP] = ASYNC_GEN_WRAP, [BEFORE_ASYNC_WITH] = BEFORE_ASYNC_WITH, [BEFORE_WITH] = BEFORE_WITH, [BINARY_OP] = BINARY_OP, - [BINARY_OP_ADAPTIVE] = BINARY_OP, [BINARY_OP_ADD_FLOAT] = BINARY_OP, [BINARY_OP_ADD_INT] = BINARY_OP, [BINARY_OP_ADD_UNICODE] = BINARY_OP, @@ -66,8 +58,8 @@ const uint8_t _PyOpcode_Deopt[256] = { [BINARY_OP_MULTIPLY_INT] = BINARY_OP, [BINARY_OP_SUBTRACT_FLOAT] = BINARY_OP, [BINARY_OP_SUBTRACT_INT] = BINARY_OP, + [BINARY_SLICE] = BINARY_SLICE, [BINARY_SUBSCR] = BINARY_SUBSCR, - [BINARY_SUBSCR_ADAPTIVE] = BINARY_SUBSCR, [BINARY_SUBSCR_DICT] = BINARY_SUBSCR, [BINARY_SUBSCR_GETITEM] = BINARY_SUBSCR, [BINARY_SUBSCR_LIST_INT] = BINARY_SUBSCR, @@ -81,17 +73,33 @@ const uint8_t _PyOpcode_Deopt[256] = { [BUILD_TUPLE] = BUILD_TUPLE, [CACHE] = CACHE, [CALL] = CALL, - [CALL_ADAPTIVE] = CALL, + [CALL_BOUND_METHOD_EXACT_ARGS] = CALL, + [CALL_BUILTIN_CLASS] = CALL, + [CALL_BUILTIN_FAST_WITH_KEYWORDS] = CALL, [CALL_FUNCTION_EX] = CALL_FUNCTION_EX, + [CALL_INTRINSIC_1] = CALL_INTRINSIC_1, + [CALL_INTRINSIC_2] = CALL_INTRINSIC_2, + [CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = CALL, + [CALL_NO_KW_BUILTIN_FAST] = CALL, + [CALL_NO_KW_BUILTIN_O] = CALL, + [CALL_NO_KW_ISINSTANCE] = CALL, + [CALL_NO_KW_LEN] = CALL, + [CALL_NO_KW_LIST_APPEND] = CALL, + [CALL_NO_KW_METHOD_DESCRIPTOR_FAST] = CALL, + [CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS] = CALL, + [CALL_NO_KW_METHOD_DESCRIPTOR_O] = CALL, + [CALL_NO_KW_STR_1] = CALL, + [CALL_NO_KW_TUPLE_1] = CALL, + [CALL_NO_KW_TYPE_1] = CALL, [CALL_PY_EXACT_ARGS] = CALL, [CALL_PY_WITH_DEFAULTS] = CALL, [CHECK_EG_MATCH] = CHECK_EG_MATCH, [CHECK_EXC_MATCH] = CHECK_EXC_MATCH, + [CLEANUP_THROW] = CLEANUP_THROW, [COMPARE_OP] = COMPARE_OP, - [COMPARE_OP_ADAPTIVE] = COMPARE_OP, - [COMPARE_OP_FLOAT_JUMP] = COMPARE_OP, - [COMPARE_OP_INT_JUMP] = COMPARE_OP, - [COMPARE_OP_STR_JUMP] = COMPARE_OP, + [COMPARE_OP_FLOAT] = COMPARE_OP, + [COMPARE_OP_INT] = COMPARE_OP, + [COMPARE_OP_STR] = COMPARE_OP, [CONTAINS_OP] = CONTAINS_OP, [COPY] = COPY, [COPY_FREE_VARS] = COPY_FREE_VARS, @@ -104,10 +112,15 @@ const uint8_t _PyOpcode_Deopt[256] = { [DICT_MERGE] = DICT_MERGE, [DICT_UPDATE] = DICT_UPDATE, [END_ASYNC_FOR] = END_ASYNC_FOR, + [END_FOR] = END_FOR, + [END_SEND] = END_SEND, [EXTENDED_ARG] = EXTENDED_ARG, - [EXTENDED_ARG_QUICK] = EXTENDED_ARG, [FORMAT_VALUE] = FORMAT_VALUE, [FOR_ITER] = FOR_ITER, + [FOR_ITER_GEN] = FOR_ITER, + [FOR_ITER_LIST] = FOR_ITER, + [FOR_ITER_RANGE] = FOR_ITER, + [FOR_ITER_TUPLE] = FOR_ITER, [GET_AITER] = GET_AITER, [GET_ANEXT] = GET_ANEXT, [GET_AWAITABLE] = GET_AWAITABLE, @@ -116,46 +129,64 @@ const uint8_t _PyOpcode_Deopt[256] = { [GET_YIELD_FROM_ITER] = GET_YIELD_FROM_ITER, [IMPORT_FROM] = IMPORT_FROM, [IMPORT_NAME] = IMPORT_NAME, - [IMPORT_STAR] = IMPORT_STAR, + [INSTRUMENTED_CALL] = INSTRUMENTED_CALL, + [INSTRUMENTED_CALL_FUNCTION_EX] = INSTRUMENTED_CALL_FUNCTION_EX, + [INSTRUMENTED_END_FOR] = INSTRUMENTED_END_FOR, + [INSTRUMENTED_END_SEND] = INSTRUMENTED_END_SEND, + [INSTRUMENTED_FOR_ITER] = INSTRUMENTED_FOR_ITER, + [INSTRUMENTED_INSTRUCTION] = INSTRUMENTED_INSTRUCTION, + [INSTRUMENTED_JUMP_BACKWARD] = INSTRUMENTED_JUMP_BACKWARD, + [INSTRUMENTED_JUMP_FORWARD] = INSTRUMENTED_JUMP_FORWARD, + [INSTRUMENTED_LINE] = INSTRUMENTED_LINE, + [INSTRUMENTED_LOAD_SUPER_ATTR] = INSTRUMENTED_LOAD_SUPER_ATTR, + [INSTRUMENTED_POP_JUMP_IF_FALSE] = INSTRUMENTED_POP_JUMP_IF_FALSE, + [INSTRUMENTED_POP_JUMP_IF_NONE] = INSTRUMENTED_POP_JUMP_IF_NONE, + [INSTRUMENTED_POP_JUMP_IF_NOT_NONE] = INSTRUMENTED_POP_JUMP_IF_NOT_NONE, + [INSTRUMENTED_POP_JUMP_IF_TRUE] = INSTRUMENTED_POP_JUMP_IF_TRUE, + [INSTRUMENTED_RESUME] = INSTRUMENTED_RESUME, + [INSTRUMENTED_RETURN_CONST] = INSTRUMENTED_RETURN_CONST, + [INSTRUMENTED_RETURN_VALUE] = INSTRUMENTED_RETURN_VALUE, + [INSTRUMENTED_YIELD_VALUE] = INSTRUMENTED_YIELD_VALUE, + [INTERPRETER_EXIT] = INTERPRETER_EXIT, [IS_OP] = IS_OP, [JUMP_BACKWARD] = JUMP_BACKWARD, [JUMP_BACKWARD_NO_INTERRUPT] = JUMP_BACKWARD_NO_INTERRUPT, - [JUMP_BACKWARD_QUICK] = JUMP_BACKWARD, [JUMP_FORWARD] = JUMP_FORWARD, - [JUMP_IF_FALSE_OR_POP] = JUMP_IF_FALSE_OR_POP, - [JUMP_IF_TRUE_OR_POP] = JUMP_IF_TRUE_OR_POP, [KW_NAMES] = KW_NAMES, [LIST_APPEND] = LIST_APPEND, [LIST_EXTEND] = LIST_EXTEND, - [LIST_TO_TUPLE] = LIST_TO_TUPLE, [LOAD_ASSERTION_ERROR] = LOAD_ASSERTION_ERROR, [LOAD_ATTR] = LOAD_ATTR, - [LOAD_ATTR_ADAPTIVE] = LOAD_ATTR, + [LOAD_ATTR_CLASS] = LOAD_ATTR, + [LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN] = LOAD_ATTR, [LOAD_ATTR_INSTANCE_VALUE] = LOAD_ATTR, + [LOAD_ATTR_METHOD_LAZY_DICT] = LOAD_ATTR, + [LOAD_ATTR_METHOD_NO_DICT] = LOAD_ATTR, + [LOAD_ATTR_METHOD_WITH_VALUES] = LOAD_ATTR, [LOAD_ATTR_MODULE] = LOAD_ATTR, + [LOAD_ATTR_PROPERTY] = LOAD_ATTR, [LOAD_ATTR_SLOT] = LOAD_ATTR, [LOAD_ATTR_WITH_HINT] = LOAD_ATTR, [LOAD_BUILD_CLASS] = LOAD_BUILD_CLASS, - [LOAD_CLASSDEREF] = LOAD_CLASSDEREF, [LOAD_CLOSURE] = LOAD_CLOSURE, [LOAD_CONST] = LOAD_CONST, [LOAD_CONST__LOAD_FAST] = LOAD_CONST, [LOAD_DEREF] = LOAD_DEREF, [LOAD_FAST] = LOAD_FAST, + [LOAD_FAST_AND_CLEAR] = LOAD_FAST_AND_CLEAR, + [LOAD_FAST_CHECK] = LOAD_FAST_CHECK, [LOAD_FAST__LOAD_CONST] = LOAD_FAST, [LOAD_FAST__LOAD_FAST] = LOAD_FAST, + [LOAD_FROM_DICT_OR_DEREF] = LOAD_FROM_DICT_OR_DEREF, + [LOAD_FROM_DICT_OR_GLOBALS] = LOAD_FROM_DICT_OR_GLOBALS, [LOAD_GLOBAL] = LOAD_GLOBAL, - [LOAD_GLOBAL_ADAPTIVE] = LOAD_GLOBAL, [LOAD_GLOBAL_BUILTIN] = LOAD_GLOBAL, [LOAD_GLOBAL_MODULE] = LOAD_GLOBAL, - [LOAD_METHOD] = LOAD_METHOD, - [LOAD_METHOD_ADAPTIVE] = LOAD_METHOD, - [LOAD_METHOD_CLASS] = LOAD_METHOD, - [LOAD_METHOD_MODULE] = LOAD_METHOD, - [LOAD_METHOD_NO_DICT] = LOAD_METHOD, - [LOAD_METHOD_WITH_DICT] = LOAD_METHOD, - [LOAD_METHOD_WITH_VALUES] = LOAD_METHOD, + [LOAD_LOCALS] = LOAD_LOCALS, [LOAD_NAME] = LOAD_NAME, + [LOAD_SUPER_ATTR] = LOAD_SUPER_ATTR, + [LOAD_SUPER_ATTR_ATTR] = LOAD_SUPER_ATTR, + [LOAD_SUPER_ATTR_METHOD] = LOAD_SUPER_ATTR, [MAKE_CELL] = MAKE_CELL, [MAKE_FUNCTION] = MAKE_FUNCTION, [MAP_ADD] = MAP_ADD, @@ -165,49 +196,26 @@ const uint8_t _PyOpcode_Deopt[256] = { [MATCH_SEQUENCE] = MATCH_SEQUENCE, [NOP] = NOP, [POP_EXCEPT] = POP_EXCEPT, - [POP_JUMP_BACKWARD_IF_FALSE] = POP_JUMP_BACKWARD_IF_FALSE, - [POP_JUMP_BACKWARD_IF_NONE] = POP_JUMP_BACKWARD_IF_NONE, - [POP_JUMP_BACKWARD_IF_NOT_NONE] = POP_JUMP_BACKWARD_IF_NOT_NONE, - [POP_JUMP_BACKWARD_IF_TRUE] = POP_JUMP_BACKWARD_IF_TRUE, - [POP_JUMP_FORWARD_IF_FALSE] = POP_JUMP_FORWARD_IF_FALSE, - [POP_JUMP_FORWARD_IF_NONE] = POP_JUMP_FORWARD_IF_NONE, - [POP_JUMP_FORWARD_IF_NOT_NONE] = POP_JUMP_FORWARD_IF_NOT_NONE, - [POP_JUMP_FORWARD_IF_TRUE] = POP_JUMP_FORWARD_IF_TRUE, + [POP_JUMP_IF_FALSE] = POP_JUMP_IF_FALSE, + [POP_JUMP_IF_NONE] = POP_JUMP_IF_NONE, + [POP_JUMP_IF_NOT_NONE] = POP_JUMP_IF_NOT_NONE, + [POP_JUMP_IF_TRUE] = POP_JUMP_IF_TRUE, [POP_TOP] = POP_TOP, - [PRECALL] = PRECALL, - [PRECALL_ADAPTIVE] = PRECALL, - [PRECALL_BOUND_METHOD] = PRECALL, - [PRECALL_BUILTIN_CLASS] = PRECALL, - [PRECALL_BUILTIN_FAST_WITH_KEYWORDS] = PRECALL, - [PRECALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = PRECALL, - [PRECALL_NO_KW_BUILTIN_FAST] = PRECALL, - [PRECALL_NO_KW_BUILTIN_O] = PRECALL, - [PRECALL_NO_KW_ISINSTANCE] = PRECALL, - [PRECALL_NO_KW_LEN] = PRECALL, - [PRECALL_NO_KW_LIST_APPEND] = PRECALL, - [PRECALL_NO_KW_METHOD_DESCRIPTOR_FAST] = PRECALL, - [PRECALL_NO_KW_METHOD_DESCRIPTOR_NOARGS] = PRECALL, - [PRECALL_NO_KW_METHOD_DESCRIPTOR_O] = PRECALL, - [PRECALL_NO_KW_STR_1] = PRECALL, - [PRECALL_NO_KW_TUPLE_1] = PRECALL, - [PRECALL_NO_KW_TYPE_1] = PRECALL, - [PRECALL_PYFUNC] = PRECALL, - [PREP_RERAISE_STAR] = PREP_RERAISE_STAR, - [PRINT_EXPR] = PRINT_EXPR, [PUSH_EXC_INFO] = PUSH_EXC_INFO, [PUSH_NULL] = PUSH_NULL, [RAISE_VARARGS] = RAISE_VARARGS, [RERAISE] = RERAISE, + [RESERVED] = RESERVED, [RESUME] = RESUME, - [RESUME_QUICK] = RESUME, + [RETURN_CONST] = RETURN_CONST, [RETURN_GENERATOR] = RETURN_GENERATOR, [RETURN_VALUE] = RETURN_VALUE, [SEND] = SEND, + [SEND_GEN] = SEND, [SETUP_ANNOTATIONS] = SETUP_ANNOTATIONS, [SET_ADD] = SET_ADD, [SET_UPDATE] = SET_UPDATE, [STORE_ATTR] = STORE_ATTR, - [STORE_ATTR_ADAPTIVE] = STORE_ATTR, [STORE_ATTR_INSTANCE_VALUE] = STORE_ATTR, [STORE_ATTR_SLOT] = STORE_ATTR, [STORE_ATTR_WITH_HINT] = STORE_ATTR, @@ -217,18 +225,16 @@ const uint8_t _PyOpcode_Deopt[256] = { [STORE_FAST__STORE_FAST] = STORE_FAST, [STORE_GLOBAL] = STORE_GLOBAL, [STORE_NAME] = STORE_NAME, + [STORE_SLICE] = STORE_SLICE, [STORE_SUBSCR] = STORE_SUBSCR, - [STORE_SUBSCR_ADAPTIVE] = STORE_SUBSCR, [STORE_SUBSCR_DICT] = STORE_SUBSCR, [STORE_SUBSCR_LIST_INT] = STORE_SUBSCR, [SWAP] = SWAP, [UNARY_INVERT] = UNARY_INVERT, [UNARY_NEGATIVE] = UNARY_NEGATIVE, [UNARY_NOT] = UNARY_NOT, - [UNARY_POSITIVE] = UNARY_POSITIVE, [UNPACK_EX] = UNPACK_EX, [UNPACK_SEQUENCE] = UNPACK_SEQUENCE, - [UNPACK_SEQUENCE_ADAPTIVE] = UNPACK_SEQUENCE, [UNPACK_SEQUENCE_LIST] = UNPACK_SEQUENCE, [UNPACK_SEQUENCE_TUPLE] = UNPACK_SEQUENCE, [UNPACK_SEQUENCE_TWO_TUPLE] = UNPACK_SEQUENCE, @@ -238,96 +244,96 @@ const uint8_t _PyOpcode_Deopt[256] = { #endif // NEED_OPCODE_TABLES #ifdef Py_DEBUG -static const char *const _PyOpcode_OpName[256] = { +static const char *const _PyOpcode_OpName[267] = { [CACHE] = "CACHE", [POP_TOP] = "POP_TOP", [PUSH_NULL] = "PUSH_NULL", - [BINARY_OP_ADAPTIVE] = "BINARY_OP_ADAPTIVE", + [INTERPRETER_EXIT] = "INTERPRETER_EXIT", + [END_FOR] = "END_FOR", + [END_SEND] = "END_SEND", [BINARY_OP_ADD_FLOAT] = "BINARY_OP_ADD_FLOAT", [BINARY_OP_ADD_INT] = "BINARY_OP_ADD_INT", [BINARY_OP_ADD_UNICODE] = "BINARY_OP_ADD_UNICODE", - [BINARY_OP_INPLACE_ADD_UNICODE] = "BINARY_OP_INPLACE_ADD_UNICODE", - [BINARY_OP_MULTIPLY_FLOAT] = "BINARY_OP_MULTIPLY_FLOAT", [NOP] = "NOP", - [UNARY_POSITIVE] = "UNARY_POSITIVE", + [BINARY_OP_INPLACE_ADD_UNICODE] = "BINARY_OP_INPLACE_ADD_UNICODE", [UNARY_NEGATIVE] = "UNARY_NEGATIVE", [UNARY_NOT] = "UNARY_NOT", + [BINARY_OP_MULTIPLY_FLOAT] = "BINARY_OP_MULTIPLY_FLOAT", [BINARY_OP_MULTIPLY_INT] = "BINARY_OP_MULTIPLY_INT", - [BINARY_OP_SUBTRACT_FLOAT] = "BINARY_OP_SUBTRACT_FLOAT", [UNARY_INVERT] = "UNARY_INVERT", + [BINARY_OP_SUBTRACT_FLOAT] = "BINARY_OP_SUBTRACT_FLOAT", + [RESERVED] = "RESERVED", [BINARY_OP_SUBTRACT_INT] = "BINARY_OP_SUBTRACT_INT", - [BINARY_SUBSCR_ADAPTIVE] = "BINARY_SUBSCR_ADAPTIVE", [BINARY_SUBSCR_DICT] = "BINARY_SUBSCR_DICT", [BINARY_SUBSCR_GETITEM] = "BINARY_SUBSCR_GETITEM", [BINARY_SUBSCR_LIST_INT] = "BINARY_SUBSCR_LIST_INT", [BINARY_SUBSCR_TUPLE_INT] = "BINARY_SUBSCR_TUPLE_INT", - [CALL_ADAPTIVE] = "CALL_ADAPTIVE", [CALL_PY_EXACT_ARGS] = "CALL_PY_EXACT_ARGS", [CALL_PY_WITH_DEFAULTS] = "CALL_PY_WITH_DEFAULTS", [BINARY_SUBSCR] = "BINARY_SUBSCR", - [COMPARE_OP_ADAPTIVE] = "COMPARE_OP_ADAPTIVE", - [COMPARE_OP_FLOAT_JUMP] = "COMPARE_OP_FLOAT_JUMP", - [COMPARE_OP_INT_JUMP] = "COMPARE_OP_INT_JUMP", - [COMPARE_OP_STR_JUMP] = "COMPARE_OP_STR_JUMP", + [BINARY_SLICE] = "BINARY_SLICE", + [STORE_SLICE] = "STORE_SLICE", + [CALL_BOUND_METHOD_EXACT_ARGS] = "CALL_BOUND_METHOD_EXACT_ARGS", + [CALL_BUILTIN_CLASS] = "CALL_BUILTIN_CLASS", [GET_LEN] = "GET_LEN", [MATCH_MAPPING] = "MATCH_MAPPING", [MATCH_SEQUENCE] = "MATCH_SEQUENCE", [MATCH_KEYS] = "MATCH_KEYS", - [EXTENDED_ARG_QUICK] = "EXTENDED_ARG_QUICK", + [CALL_BUILTIN_FAST_WITH_KEYWORDS] = "CALL_BUILTIN_FAST_WITH_KEYWORDS", [PUSH_EXC_INFO] = "PUSH_EXC_INFO", [CHECK_EXC_MATCH] = "CHECK_EXC_MATCH", [CHECK_EG_MATCH] = "CHECK_EG_MATCH", - [JUMP_BACKWARD_QUICK] = "JUMP_BACKWARD_QUICK", - [LOAD_ATTR_ADAPTIVE] = "LOAD_ATTR_ADAPTIVE", - [LOAD_ATTR_INSTANCE_VALUE] = "LOAD_ATTR_INSTANCE_VALUE", - [LOAD_ATTR_MODULE] = "LOAD_ATTR_MODULE", - [LOAD_ATTR_SLOT] = "LOAD_ATTR_SLOT", - [LOAD_ATTR_WITH_HINT] = "LOAD_ATTR_WITH_HINT", - [LOAD_CONST__LOAD_FAST] = "LOAD_CONST__LOAD_FAST", - [LOAD_FAST__LOAD_CONST] = "LOAD_FAST__LOAD_CONST", - [LOAD_FAST__LOAD_FAST] = "LOAD_FAST__LOAD_FAST", - [LOAD_GLOBAL_ADAPTIVE] = "LOAD_GLOBAL_ADAPTIVE", - [LOAD_GLOBAL_BUILTIN] = "LOAD_GLOBAL_BUILTIN", + [CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = "CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS", + [CALL_NO_KW_BUILTIN_FAST] = "CALL_NO_KW_BUILTIN_FAST", + [CALL_NO_KW_BUILTIN_O] = "CALL_NO_KW_BUILTIN_O", + [CALL_NO_KW_ISINSTANCE] = "CALL_NO_KW_ISINSTANCE", + [CALL_NO_KW_LEN] = "CALL_NO_KW_LEN", + [CALL_NO_KW_LIST_APPEND] = "CALL_NO_KW_LIST_APPEND", + [CALL_NO_KW_METHOD_DESCRIPTOR_FAST] = "CALL_NO_KW_METHOD_DESCRIPTOR_FAST", + [CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS] = "CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS", + [CALL_NO_KW_METHOD_DESCRIPTOR_O] = "CALL_NO_KW_METHOD_DESCRIPTOR_O", + [CALL_NO_KW_STR_1] = "CALL_NO_KW_STR_1", + [CALL_NO_KW_TUPLE_1] = "CALL_NO_KW_TUPLE_1", [WITH_EXCEPT_START] = "WITH_EXCEPT_START", [GET_AITER] = "GET_AITER", [GET_ANEXT] = "GET_ANEXT", [BEFORE_ASYNC_WITH] = "BEFORE_ASYNC_WITH", [BEFORE_WITH] = "BEFORE_WITH", [END_ASYNC_FOR] = "END_ASYNC_FOR", - [LOAD_GLOBAL_MODULE] = "LOAD_GLOBAL_MODULE", - [LOAD_METHOD_ADAPTIVE] = "LOAD_METHOD_ADAPTIVE", - [LOAD_METHOD_CLASS] = "LOAD_METHOD_CLASS", - [LOAD_METHOD_MODULE] = "LOAD_METHOD_MODULE", - [LOAD_METHOD_NO_DICT] = "LOAD_METHOD_NO_DICT", + [CLEANUP_THROW] = "CLEANUP_THROW", + [CALL_NO_KW_TYPE_1] = "CALL_NO_KW_TYPE_1", + [COMPARE_OP_FLOAT] = "COMPARE_OP_FLOAT", + [COMPARE_OP_INT] = "COMPARE_OP_INT", + [COMPARE_OP_STR] = "COMPARE_OP_STR", [STORE_SUBSCR] = "STORE_SUBSCR", [DELETE_SUBSCR] = "DELETE_SUBSCR", - [LOAD_METHOD_WITH_DICT] = "LOAD_METHOD_WITH_DICT", - [LOAD_METHOD_WITH_VALUES] = "LOAD_METHOD_WITH_VALUES", - [PRECALL_ADAPTIVE] = "PRECALL_ADAPTIVE", - [PRECALL_BOUND_METHOD] = "PRECALL_BOUND_METHOD", - [PRECALL_BUILTIN_CLASS] = "PRECALL_BUILTIN_CLASS", - [PRECALL_BUILTIN_FAST_WITH_KEYWORDS] = "PRECALL_BUILTIN_FAST_WITH_KEYWORDS", + [FOR_ITER_LIST] = "FOR_ITER_LIST", + [FOR_ITER_TUPLE] = "FOR_ITER_TUPLE", + [FOR_ITER_RANGE] = "FOR_ITER_RANGE", + [FOR_ITER_GEN] = "FOR_ITER_GEN", + [LOAD_SUPER_ATTR_ATTR] = "LOAD_SUPER_ATTR_ATTR", + [LOAD_SUPER_ATTR_METHOD] = "LOAD_SUPER_ATTR_METHOD", [GET_ITER] = "GET_ITER", [GET_YIELD_FROM_ITER] = "GET_YIELD_FROM_ITER", - [PRINT_EXPR] = "PRINT_EXPR", + [LOAD_ATTR_CLASS] = "LOAD_ATTR_CLASS", [LOAD_BUILD_CLASS] = "LOAD_BUILD_CLASS", - [PRECALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = "PRECALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS", - [PRECALL_NO_KW_BUILTIN_FAST] = "PRECALL_NO_KW_BUILTIN_FAST", + [LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN] = "LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN", + [LOAD_ATTR_INSTANCE_VALUE] = "LOAD_ATTR_INSTANCE_VALUE", [LOAD_ASSERTION_ERROR] = "LOAD_ASSERTION_ERROR", [RETURN_GENERATOR] = "RETURN_GENERATOR", - [PRECALL_NO_KW_BUILTIN_O] = "PRECALL_NO_KW_BUILTIN_O", - [PRECALL_NO_KW_ISINSTANCE] = "PRECALL_NO_KW_ISINSTANCE", - [PRECALL_NO_KW_LEN] = "PRECALL_NO_KW_LEN", - [PRECALL_NO_KW_LIST_APPEND] = "PRECALL_NO_KW_LIST_APPEND", - [PRECALL_NO_KW_METHOD_DESCRIPTOR_FAST] = "PRECALL_NO_KW_METHOD_DESCRIPTOR_FAST", - [PRECALL_NO_KW_METHOD_DESCRIPTOR_NOARGS] = "PRECALL_NO_KW_METHOD_DESCRIPTOR_NOARGS", - [LIST_TO_TUPLE] = "LIST_TO_TUPLE", + [LOAD_ATTR_MODULE] = "LOAD_ATTR_MODULE", + [LOAD_ATTR_PROPERTY] = "LOAD_ATTR_PROPERTY", + [LOAD_ATTR_SLOT] = "LOAD_ATTR_SLOT", + [LOAD_ATTR_WITH_HINT] = "LOAD_ATTR_WITH_HINT", + [LOAD_ATTR_METHOD_LAZY_DICT] = "LOAD_ATTR_METHOD_LAZY_DICT", + [LOAD_ATTR_METHOD_NO_DICT] = "LOAD_ATTR_METHOD_NO_DICT", + [LOAD_ATTR_METHOD_WITH_VALUES] = "LOAD_ATTR_METHOD_WITH_VALUES", [RETURN_VALUE] = "RETURN_VALUE", - [IMPORT_STAR] = "IMPORT_STAR", + [LOAD_CONST__LOAD_FAST] = "LOAD_CONST__LOAD_FAST", [SETUP_ANNOTATIONS] = "SETUP_ANNOTATIONS", - [YIELD_VALUE] = "YIELD_VALUE", - [ASYNC_GEN_WRAP] = "ASYNC_GEN_WRAP", - [PREP_RERAISE_STAR] = "PREP_RERAISE_STAR", + [LOAD_FAST__LOAD_CONST] = "LOAD_FAST__LOAD_CONST", + [LOAD_LOCALS] = "LOAD_LOCALS", + [LOAD_FAST__LOAD_FAST] = "LOAD_FAST__LOAD_FAST", [POP_EXCEPT] = "POP_EXCEPT", [STORE_NAME] = "STORE_NAME", [DELETE_NAME] = "DELETE_NAME", @@ -350,25 +356,25 @@ static const char *const _PyOpcode_OpName[256] = { [IMPORT_NAME] = "IMPORT_NAME", [IMPORT_FROM] = "IMPORT_FROM", [JUMP_FORWARD] = "JUMP_FORWARD", - [JUMP_IF_FALSE_OR_POP] = "JUMP_IF_FALSE_OR_POP", - [JUMP_IF_TRUE_OR_POP] = "JUMP_IF_TRUE_OR_POP", - [PRECALL_NO_KW_METHOD_DESCRIPTOR_O] = "PRECALL_NO_KW_METHOD_DESCRIPTOR_O", - [POP_JUMP_FORWARD_IF_FALSE] = "POP_JUMP_FORWARD_IF_FALSE", - [POP_JUMP_FORWARD_IF_TRUE] = "POP_JUMP_FORWARD_IF_TRUE", + [LOAD_GLOBAL_BUILTIN] = "LOAD_GLOBAL_BUILTIN", + [LOAD_GLOBAL_MODULE] = "LOAD_GLOBAL_MODULE", + [STORE_ATTR_INSTANCE_VALUE] = "STORE_ATTR_INSTANCE_VALUE", + [POP_JUMP_IF_FALSE] = "POP_JUMP_IF_FALSE", + [POP_JUMP_IF_TRUE] = "POP_JUMP_IF_TRUE", [LOAD_GLOBAL] = "LOAD_GLOBAL", [IS_OP] = "IS_OP", [CONTAINS_OP] = "CONTAINS_OP", [RERAISE] = "RERAISE", [COPY] = "COPY", - [PRECALL_NO_KW_STR_1] = "PRECALL_NO_KW_STR_1", + [RETURN_CONST] = "RETURN_CONST", [BINARY_OP] = "BINARY_OP", [SEND] = "SEND", [LOAD_FAST] = "LOAD_FAST", [STORE_FAST] = "STORE_FAST", [DELETE_FAST] = "DELETE_FAST", - [PRECALL_NO_KW_TUPLE_1] = "PRECALL_NO_KW_TUPLE_1", - [POP_JUMP_FORWARD_IF_NOT_NONE] = "POP_JUMP_FORWARD_IF_NOT_NONE", - [POP_JUMP_FORWARD_IF_NONE] = "POP_JUMP_FORWARD_IF_NONE", + [LOAD_FAST_CHECK] = "LOAD_FAST_CHECK", + [POP_JUMP_IF_NOT_NONE] = "POP_JUMP_IF_NOT_NONE", + [POP_JUMP_IF_NONE] = "POP_JUMP_IF_NONE", [RAISE_VARARGS] = "RAISE_VARARGS", [GET_AWAITABLE] = "GET_AWAITABLE", [MAKE_FUNCTION] = "MAKE_FUNCTION", @@ -380,46 +386,46 @@ static const char *const _PyOpcode_OpName[256] = { [STORE_DEREF] = "STORE_DEREF", [DELETE_DEREF] = "DELETE_DEREF", [JUMP_BACKWARD] = "JUMP_BACKWARD", - [PRECALL_NO_KW_TYPE_1] = "PRECALL_NO_KW_TYPE_1", + [LOAD_SUPER_ATTR] = "LOAD_SUPER_ATTR", [CALL_FUNCTION_EX] = "CALL_FUNCTION_EX", - [PRECALL_PYFUNC] = "PRECALL_PYFUNC", + [LOAD_FAST_AND_CLEAR] = "LOAD_FAST_AND_CLEAR", [EXTENDED_ARG] = "EXTENDED_ARG", [LIST_APPEND] = "LIST_APPEND", [SET_ADD] = "SET_ADD", [MAP_ADD] = "MAP_ADD", - [LOAD_CLASSDEREF] = "LOAD_CLASSDEREF", + [STORE_ATTR_SLOT] = "STORE_ATTR_SLOT", [COPY_FREE_VARS] = "COPY_FREE_VARS", - [RESUME_QUICK] = "RESUME_QUICK", + [YIELD_VALUE] = "YIELD_VALUE", [RESUME] = "RESUME", [MATCH_CLASS] = "MATCH_CLASS", - [STORE_ATTR_ADAPTIVE] = "STORE_ATTR_ADAPTIVE", - [STORE_ATTR_INSTANCE_VALUE] = "STORE_ATTR_INSTANCE_VALUE", + [STORE_ATTR_WITH_HINT] = "STORE_ATTR_WITH_HINT", + [STORE_FAST__LOAD_FAST] = "STORE_FAST__LOAD_FAST", [FORMAT_VALUE] = "FORMAT_VALUE", [BUILD_CONST_KEY_MAP] = "BUILD_CONST_KEY_MAP", [BUILD_STRING] = "BUILD_STRING", - [STORE_ATTR_SLOT] = "STORE_ATTR_SLOT", - [STORE_ATTR_WITH_HINT] = "STORE_ATTR_WITH_HINT", - [LOAD_METHOD] = "LOAD_METHOD", - [STORE_FAST__LOAD_FAST] = "STORE_FAST__LOAD_FAST", - [LIST_EXTEND] = "LIST_EXTEND", - [SET_UPDATE] = "SET_UPDATE", - [DICT_MERGE] = "DICT_MERGE", - [DICT_UPDATE] = "DICT_UPDATE", - [PRECALL] = "PRECALL", [STORE_FAST__STORE_FAST] = "STORE_FAST__STORE_FAST", - [STORE_SUBSCR_ADAPTIVE] = "STORE_SUBSCR_ADAPTIVE", [STORE_SUBSCR_DICT] = "STORE_SUBSCR_DICT", [STORE_SUBSCR_LIST_INT] = "STORE_SUBSCR_LIST_INT", - [CALL] = "CALL", - [KW_NAMES] = "KW_NAMES", - [POP_JUMP_BACKWARD_IF_NOT_NONE] = "POP_JUMP_BACKWARD_IF_NOT_NONE", - [POP_JUMP_BACKWARD_IF_NONE] = "POP_JUMP_BACKWARD_IF_NONE", - [POP_JUMP_BACKWARD_IF_FALSE] = "POP_JUMP_BACKWARD_IF_FALSE", - [POP_JUMP_BACKWARD_IF_TRUE] = "POP_JUMP_BACKWARD_IF_TRUE", - [UNPACK_SEQUENCE_ADAPTIVE] = "UNPACK_SEQUENCE_ADAPTIVE", [UNPACK_SEQUENCE_LIST] = "UNPACK_SEQUENCE_LIST", + [LIST_EXTEND] = "LIST_EXTEND", + [SET_UPDATE] = "SET_UPDATE", + [DICT_MERGE] = "DICT_MERGE", + [DICT_UPDATE] = "DICT_UPDATE", [UNPACK_SEQUENCE_TUPLE] = "UNPACK_SEQUENCE_TUPLE", [UNPACK_SEQUENCE_TWO_TUPLE] = "UNPACK_SEQUENCE_TWO_TUPLE", + [SEND_GEN] = "SEND_GEN", + [169] = "<169>", + [170] = "<170>", + [CALL] = "CALL", + [KW_NAMES] = "KW_NAMES", + [CALL_INTRINSIC_1] = "CALL_INTRINSIC_1", + [CALL_INTRINSIC_2] = "CALL_INTRINSIC_2", + [LOAD_FROM_DICT_OR_GLOBALS] = "LOAD_FROM_DICT_OR_GLOBALS", + [LOAD_FROM_DICT_OR_DEREF] = "LOAD_FROM_DICT_OR_DEREF", + [177] = "<177>", + [178] = "<178>", + [179] = "<179>", + [180] = "<180>", [181] = "<181>", [182] = "<182>", [183] = "<183>", @@ -476,29 +482,46 @@ static const char *const _PyOpcode_OpName[256] = { [234] = "<234>", [235] = "<235>", [236] = "<236>", - [237] = "<237>", - [238] = "<238>", - [239] = "<239>", - [240] = "<240>", - [241] = "<241>", - [242] = "<242>", - [243] = "<243>", - [244] = "<244>", - [245] = "<245>", - [246] = "<246>", - [247] = "<247>", - [248] = "<248>", - [249] = "<249>", - [250] = "<250>", - [251] = "<251>", - [252] = "<252>", - [253] = "<253>", - [254] = "<254>", - [DO_TRACING] = "DO_TRACING", + [INSTRUMENTED_LOAD_SUPER_ATTR] = "INSTRUMENTED_LOAD_SUPER_ATTR", + [INSTRUMENTED_POP_JUMP_IF_NONE] = "INSTRUMENTED_POP_JUMP_IF_NONE", + [INSTRUMENTED_POP_JUMP_IF_NOT_NONE] = "INSTRUMENTED_POP_JUMP_IF_NOT_NONE", + [INSTRUMENTED_RESUME] = "INSTRUMENTED_RESUME", + [INSTRUMENTED_CALL] = "INSTRUMENTED_CALL", + [INSTRUMENTED_RETURN_VALUE] = "INSTRUMENTED_RETURN_VALUE", + [INSTRUMENTED_YIELD_VALUE] = "INSTRUMENTED_YIELD_VALUE", + [INSTRUMENTED_CALL_FUNCTION_EX] = "INSTRUMENTED_CALL_FUNCTION_EX", + [INSTRUMENTED_JUMP_FORWARD] = "INSTRUMENTED_JUMP_FORWARD", + [INSTRUMENTED_JUMP_BACKWARD] = "INSTRUMENTED_JUMP_BACKWARD", + [INSTRUMENTED_RETURN_CONST] = "INSTRUMENTED_RETURN_CONST", + [INSTRUMENTED_FOR_ITER] = "INSTRUMENTED_FOR_ITER", + [INSTRUMENTED_POP_JUMP_IF_FALSE] = "INSTRUMENTED_POP_JUMP_IF_FALSE", + [INSTRUMENTED_POP_JUMP_IF_TRUE] = "INSTRUMENTED_POP_JUMP_IF_TRUE", + [INSTRUMENTED_END_FOR] = "INSTRUMENTED_END_FOR", + [INSTRUMENTED_END_SEND] = "INSTRUMENTED_END_SEND", + [INSTRUMENTED_INSTRUCTION] = "INSTRUMENTED_INSTRUCTION", + [INSTRUMENTED_LINE] = "INSTRUMENTED_LINE", + [255] = "<255>", + [SETUP_FINALLY] = "SETUP_FINALLY", + [SETUP_CLEANUP] = "SETUP_CLEANUP", + [SETUP_WITH] = "SETUP_WITH", + [POP_BLOCK] = "POP_BLOCK", + [JUMP] = "JUMP", + [JUMP_NO_INTERRUPT] = "JUMP_NO_INTERRUPT", + [LOAD_METHOD] = "LOAD_METHOD", + [LOAD_SUPER_METHOD] = "LOAD_SUPER_METHOD", + [LOAD_ZERO_SUPER_METHOD] = "LOAD_ZERO_SUPER_METHOD", + [LOAD_ZERO_SUPER_ATTR] = "LOAD_ZERO_SUPER_ATTR", + [STORE_FAST_MAYBE_NULL] = "STORE_FAST_MAYBE_NULL", }; #endif #define EXTRA_CASES \ + case 169: \ + case 170: \ + case 177: \ + case 178: \ + case 179: \ + case 180: \ case 181: \ case 182: \ case 183: \ @@ -555,24 +578,7 @@ static const char *const _PyOpcode_OpName[256] = { case 234: \ case 235: \ case 236: \ - case 237: \ - case 238: \ - case 239: \ - case 240: \ - case 241: \ - case 242: \ - case 243: \ - case 244: \ - case 245: \ - case 246: \ - case 247: \ - case 248: \ - case 249: \ - case 250: \ - case 251: \ - case 252: \ - case 253: \ - case 254: \ + case 255: \ ; #ifdef __cplusplus diff --git a/Include/internal/pycore_opcode_utils.h b/Include/internal/pycore_opcode_utils.h new file mode 100644 index 00000000..1d5ff988 --- /dev/null +++ b/Include/internal/pycore_opcode_utils.h @@ -0,0 +1,92 @@ +#ifndef Py_INTERNAL_OPCODE_UTILS_H +#define Py_INTERNAL_OPCODE_UTILS_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +#include "pycore_opcode.h" // _PyOpcode_Jump + + +#define MAX_REAL_OPCODE 254 + +#define IS_WITHIN_OPCODE_RANGE(opcode) \ + (((opcode) >= 0 && (opcode) <= MAX_REAL_OPCODE) || \ + IS_PSEUDO_OPCODE(opcode)) + +#define IS_JUMP_OPCODE(opcode) \ + is_bit_set_in_table(_PyOpcode_Jump, opcode) + +#define IS_BLOCK_PUSH_OPCODE(opcode) \ + ((opcode) == SETUP_FINALLY || \ + (opcode) == SETUP_WITH || \ + (opcode) == SETUP_CLEANUP) + +#define HAS_TARGET(opcode) \ + (IS_JUMP_OPCODE(opcode) || IS_BLOCK_PUSH_OPCODE(opcode)) + +/* opcodes that must be last in the basicblock */ +#define IS_TERMINATOR_OPCODE(opcode) \ + (IS_JUMP_OPCODE(opcode) || IS_SCOPE_EXIT_OPCODE(opcode)) + +/* opcodes which are not emitted in codegen stage, only by the assembler */ +#define IS_ASSEMBLER_OPCODE(opcode) \ + ((opcode) == JUMP_FORWARD || \ + (opcode) == JUMP_BACKWARD || \ + (opcode) == JUMP_BACKWARD_NO_INTERRUPT) + +#define IS_BACKWARDS_JUMP_OPCODE(opcode) \ + ((opcode) == JUMP_BACKWARD || \ + (opcode) == JUMP_BACKWARD_NO_INTERRUPT) + +#define IS_UNCONDITIONAL_JUMP_OPCODE(opcode) \ + ((opcode) == JUMP || \ + (opcode) == JUMP_NO_INTERRUPT || \ + (opcode) == JUMP_FORWARD || \ + (opcode) == JUMP_BACKWARD || \ + (opcode) == JUMP_BACKWARD_NO_INTERRUPT) + +#define IS_SCOPE_EXIT_OPCODE(opcode) \ + ((opcode) == RETURN_VALUE || \ + (opcode) == RETURN_CONST || \ + (opcode) == RAISE_VARARGS || \ + (opcode) == RERAISE) + +#define IS_SUPERINSTRUCTION_OPCODE(opcode) \ + ((opcode) == LOAD_FAST__LOAD_FAST || \ + (opcode) == LOAD_FAST__LOAD_CONST || \ + (opcode) == LOAD_CONST__LOAD_FAST || \ + (opcode) == STORE_FAST__LOAD_FAST || \ + (opcode) == STORE_FAST__STORE_FAST) + + +#define LOG_BITS_PER_INT 5 +#define MASK_LOW_LOG_BITS 31 + +static inline int +is_bit_set_in_table(const uint32_t *table, int bitindex) { + /* Is the relevant bit set in the relevant word? */ + /* 512 bits fit into 9 32-bits words. + * Word is indexed by (bitindex>>ln(size of int in bits)). + * Bit within word is the low bits of bitindex. + */ + if (bitindex >= 0 && bitindex < 512) { + uint32_t word = table[bitindex >> LOG_BITS_PER_INT]; + return (word >> (bitindex & MASK_LOW_LOG_BITS)) & 1; + } + else { + return 0; + } +} + +#undef LOG_BITS_PER_INT +#undef MASK_LOW_LOG_BITS + + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_OPCODE_UTILS_H */ diff --git a/Include/internal/pycore_parser.h b/Include/internal/pycore_parser.h index e2de24e2..dd51b928 100644 --- a/Include/internal/pycore_parser.h +++ b/Include/internal/pycore_parser.h @@ -8,12 +8,46 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif + +#include "pycore_ast.h" // struct _expr +#include "pycore_global_strings.h" // _Py_DECLARE_STR() +#include "pycore_pyarena.h" // PyArena + + +#ifdef Py_DEBUG +#define _PYPEGEN_NSTATISTICS 2000 +#endif + +struct _parser_runtime_state { +#ifdef Py_DEBUG + long memo_statistics[_PYPEGEN_NSTATISTICS]; +#else + int _not_used; +#endif + struct _expr dummy_name; +}; + +_Py_DECLARE_STR(empty, "") +#define _parser_runtime_state_INIT \ + { \ + .dummy_name = { \ + .kind = Name_kind, \ + .v.Name.id = &_Py_STR(empty), \ + .v.Name.ctx = Load, \ + .lineno = 1, \ + .col_offset = 0, \ + .end_lineno = 1, \ + .end_col_offset = 0, \ + }, \ + } + extern struct _mod* _PyParser_ASTFromString( const char *str, PyObject* filename, int mode, PyCompilerFlags *flags, PyArena *arena); + extern struct _mod* _PyParser_ASTFromFile( FILE *fp, PyObject *filename_ob, @@ -25,6 +59,7 @@ extern struct _mod* _PyParser_ASTFromFile( int *errcode, PyArena *arena); + #ifdef __cplusplus } #endif diff --git a/Include/internal/pycore_pyerrors.h b/Include/internal/pycore_pyerrors.h index 66f37942..4620a269 100644 --- a/Include/internal/pycore_pyerrors.h +++ b/Include/internal/pycore_pyerrors.h @@ -20,7 +20,10 @@ extern void _PyErr_FiniTypes(PyInterpreterState *); static inline PyObject* _PyErr_Occurred(PyThreadState *tstate) { assert(tstate != NULL); - return tstate->curexc_type; + if (tstate->current_exception == NULL) { + return NULL; + } + return (PyObject *)Py_TYPE(tstate->current_exception); } static inline void _PyErr_ClearExcState(_PyErr_StackItem *exc_state) @@ -37,10 +40,16 @@ PyAPI_FUNC(void) _PyErr_Fetch( PyObject **value, PyObject **traceback); +extern PyObject * +_PyErr_GetRaisedException(PyThreadState *tstate); + PyAPI_FUNC(int) _PyErr_ExceptionMatches( PyThreadState *tstate, PyObject *exc); +void +_PyErr_SetRaisedException(PyThreadState *tstate, PyObject *exc); + PyAPI_FUNC(void) _PyErr_Restore( PyThreadState *tstate, PyObject *type, @@ -100,6 +109,8 @@ extern PyObject* _Py_Offer_Suggestions(PyObject* exception); PyAPI_FUNC(Py_ssize_t) _Py_UTF8_Edit_Cost(PyObject *str_a, PyObject *str_b, Py_ssize_t max_cost); +void _PyErr_FormatNote(const char *format, ...); + #ifdef __cplusplus } #endif diff --git a/Include/internal/pycore_pyhash.h b/Include/internal/pycore_pyhash.h index a229f8d8..34dfa537 100644 --- a/Include/internal/pycore_pyhash.h +++ b/Include/internal/pycore_pyhash.h @@ -5,6 +5,36 @@ # error "this header requires Py_BUILD_CORE define" #endif -uint64_t _Py_KeyedHash(uint64_t, const char *, Py_ssize_t); +struct pyhash_runtime_state { + struct { +#ifndef MS_WINDOWS + int fd; + dev_t st_dev; + ino_t st_ino; +#else + // This is a placeholder so the struct isn't empty on Windows. + int _not_used; +#endif + } urandom_cache; +}; + +#ifndef MS_WINDOWS +# define _py_urandom_cache_INIT \ + { \ + .fd = -1, \ + } +#else +# define _py_urandom_cache_INIT {0} #endif + +#define pyhash_state_INIT \ + { \ + .urandom_cache = _py_urandom_cache_INIT, \ + } + + +uint64_t _Py_KeyedHash(uint64_t, const char *, Py_ssize_t); + + +#endif // Py_INTERNAL_HASH_H diff --git a/Include/internal/pycore_pylifecycle.h b/Include/internal/pycore_pylifecycle.h index b4718b8a..7cd998a7 100644 --- a/Include/internal/pycore_pylifecycle.h +++ b/Include/internal/pycore_pylifecycle.h @@ -14,10 +14,6 @@ extern "C" { struct _PyArgv; struct pyruntimestate; -/* True if the main interpreter thread exited due to an unhandled - * KeyboardInterrupt exception, suggesting the user pressed ^C. */ -PyAPI_DATA(int) _Py_UnhandledKeyboardInterrupt; - extern int _Py_SetFileSystemEncoding( const char *encoding, const char *errors); @@ -33,8 +29,8 @@ PyAPI_FUNC(int) _Py_IsLocaleCoercionTarget(const char *ctype_loc); /* Various one-time initializers */ +extern void _Py_InitVersion(void); extern PyStatus _PyFaulthandler_Init(int enable); -extern int _PyTraceMalloc_Init(int enable); extern PyObject * _PyBuiltin_Init(PyInterpreterState *interp); extern PyStatus _PySys_Create( PyThreadState *tstate, @@ -42,11 +38,11 @@ extern PyStatus _PySys_Create( extern PyStatus _PySys_ReadPreinitWarnOptions(PyWideStringList *options); extern PyStatus _PySys_ReadPreinitXOptions(PyConfig *config); extern int _PySys_UpdateConfig(PyThreadState *tstate); -extern void _PySys_Fini(PyInterpreterState *interp); +extern void _PySys_FiniTypes(PyInterpreterState *interp); extern int _PyBuiltins_AddExceptions(PyObject * bltinmod); extern PyStatus _Py_HashRandomization_Init(const PyConfig *); -extern PyStatus _PyImportZip_Init(PyThreadState *tstate); +extern PyStatus _PyTime_Init(void); extern PyStatus _PyGC_Init(PyInterpreterState *interp); extern PyStatus _PyAtExit_Init(PyInterpreterState *interp); extern int _Py_Deepfreeze_Init(void); @@ -56,8 +52,6 @@ extern int _Py_Deepfreeze_Init(void); extern int _PySignal_Init(int install_signal_handlers); extern void _PySignal_Fini(void); -extern void _PyImport_Fini(void); -extern void _PyImport_Fini2(void); extern void _PyGC_Fini(PyInterpreterState *interp); extern void _Py_HashRandomization_Fini(void); extern void _PyFaulthandler_Fini(void); @@ -69,8 +63,9 @@ extern void _PyAtExit_Fini(PyInterpreterState *interp); extern void _PyThread_FiniType(PyInterpreterState *interp); extern void _Py_Deepfreeze_Fini(void); extern void _PyArg_Fini(void); +extern void _Py_FinalizeAllocatedBlocks(_PyRuntimeState *); -extern PyStatus _PyGILState_Init(_PyRuntimeState *runtime); +extern PyStatus _PyGILState_Init(PyInterpreterState *interp); extern PyStatus _PyGILState_SetTstate(PyThreadState *tstate); extern void _PyGILState_Fini(PyInterpreterState *interp); @@ -92,6 +87,7 @@ PyAPI_FUNC(PyObject*) _PyErr_WriteUnraisableDefaultHook(PyObject *unraisable); PyAPI_FUNC(void) _PyErr_Print(PyThreadState *tstate); PyAPI_FUNC(void) _PyErr_Display(PyObject *file, PyObject *exception, PyObject *value, PyObject *tb); +PyAPI_FUNC(void) _PyErr_DisplayException(PyObject *file, PyObject *exc); PyAPI_FUNC(void) _PyThreadState_DeleteCurrent(PyThreadState *tstate); diff --git a/Include/internal/pycore_pymath.h b/Include/internal/pycore_pymath.h index 5c6aee2a..7a4e1c1e 100644 --- a/Include/internal/pycore_pymath.h +++ b/Include/internal/pycore_pymath.h @@ -56,25 +56,6 @@ static inline void _Py_ADJUST_ERANGE2(double x, double y) } } -// Return whether integral type *type* is signed or not. -#define _Py_IntegralTypeSigned(type) \ - ((type)(-1) < 0) - -// Return the maximum value of integral type *type*. -#define _Py_IntegralTypeMax(type) \ - ((_Py_IntegralTypeSigned(type)) ? (((((type)1 << (sizeof(type)*CHAR_BIT - 2)) - 1) << 1) + 1) : ~(type)0) - -// Return the minimum value of integral type *type*. -#define _Py_IntegralTypeMin(type) \ - ((_Py_IntegralTypeSigned(type)) ? -_Py_IntegralTypeMax(type) - 1 : 0) - -// Check whether *v* is in the range of integral type *type*. This is most -// useful if *v* is floating-point, since demoting a floating-point *v* to an -// integral type that cannot represent *v*'s integral part is undefined -// behavior. -#define _Py_InIntegralTypeRange(type, v) \ - (_Py_IntegralTypeMin(type) <= v && v <= _Py_IntegralTypeMax(type)) - //--- HAVE_PY_SET_53BIT_PRECISION macro ------------------------------------ // diff --git a/Include/internal/pycore_pymem.h b/Include/internal/pycore_pymem.h index b9eea9d4..81a707a0 100644 --- a/Include/internal/pycore_pymem.h +++ b/Include/internal/pycore_pymem.h @@ -11,6 +11,28 @@ extern "C" { #include "pymem.h" // PyMemAllocatorName +typedef struct { + /* We tag each block with an API ID in order to tag API violations */ + char api_id; + PyMemAllocatorEx alloc; +} debug_alloc_api_t; + +struct _pymem_allocators { + PyThread_type_lock mutex; + struct { + PyMemAllocatorEx raw; + PyMemAllocatorEx mem; + PyMemAllocatorEx obj; + } standard; + struct { + debug_alloc_api_t raw; + debug_alloc_api_t mem; + debug_alloc_api_t obj; + } debug; + PyObjectArenaAllocator obj_arena; +}; + + /* Set the memory allocator of the specified domain to the default. Save the old allocator into *old_alloc if it's non-NULL. Return on success, or return -1 if the domain is unknown. */ @@ -69,46 +91,8 @@ PyAPI_FUNC(int) _PyMem_GetAllocatorName( PYMEM_ALLOCATOR_NOT_SET does nothing. */ PyAPI_FUNC(int) _PyMem_SetupAllocators(PyMemAllocatorName allocator); -struct _PyTraceMalloc_Config { - /* Module initialized? - Variable protected by the GIL */ - enum { - TRACEMALLOC_NOT_INITIALIZED, - TRACEMALLOC_INITIALIZED, - TRACEMALLOC_FINALIZED - } initialized; - - /* Is tracemalloc tracing memory allocations? - Variable protected by the GIL */ - int tracing; - - /* limit of the number of frames in a traceback, 1 by default. - Variable protected by the GIL. */ - int max_nframe; -}; - -#define _PyTraceMalloc_Config_INIT \ - {.initialized = TRACEMALLOC_NOT_INITIALIZED, \ - .tracing = 0, \ - .max_nframe = 1} - -PyAPI_DATA(struct _PyTraceMalloc_Config) _Py_tracemalloc_config; - -/* Allocate memory directly from the O/S virtual memory system, - * where supported. Otherwise fallback on malloc */ -void *_PyObject_VirtualAlloc(size_t size); -void _PyObject_VirtualFree(void *, size_t size); - -/* This function returns the number of allocated memory blocks, regardless of size */ -PyAPI_FUNC(Py_ssize_t) _Py_GetAllocatedBlocks(void); - -/* Macros */ -#ifdef WITH_PYMALLOC -// Export the symbol for the 3rd party guppy3 project -PyAPI_FUNC(int) _PyObject_DebugMallocStats(FILE *out); -#endif #ifdef __cplusplus } #endif -#endif // !Py_INTERNAL_PYMEM_H +#endif /* !Py_INTERNAL_PYMEM_H */ diff --git a/Include/internal/pycore_pymem_init.h b/Include/internal/pycore_pymem_init.h new file mode 100644 index 00000000..78232738 --- /dev/null +++ b/Include/internal/pycore_pymem_init.h @@ -0,0 +1,85 @@ +#ifndef Py_INTERNAL_PYMEM_INIT_H +#define Py_INTERNAL_PYMEM_INIT_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +#include "pycore_pymem.h" + + +/********************************/ +/* the allocators' initializers */ + +extern void * _PyMem_RawMalloc(void *, size_t); +extern void * _PyMem_RawCalloc(void *, size_t, size_t); +extern void * _PyMem_RawRealloc(void *, void *, size_t); +extern void _PyMem_RawFree(void *, void *); +#define PYRAW_ALLOC {NULL, _PyMem_RawMalloc, _PyMem_RawCalloc, _PyMem_RawRealloc, _PyMem_RawFree} + +#ifdef WITH_PYMALLOC +extern void* _PyObject_Malloc(void *, size_t); +extern void* _PyObject_Calloc(void *, size_t, size_t); +extern void _PyObject_Free(void *, void *); +extern void* _PyObject_Realloc(void *, void *, size_t); +# define PYOBJ_ALLOC {NULL, _PyObject_Malloc, _PyObject_Calloc, _PyObject_Realloc, _PyObject_Free} +#else +# define PYOBJ_ALLOC PYRAW_ALLOC +#endif // WITH_PYMALLOC + +#define PYMEM_ALLOC PYOBJ_ALLOC + +extern void* _PyMem_DebugRawMalloc(void *, size_t); +extern void* _PyMem_DebugRawCalloc(void *, size_t, size_t); +extern void* _PyMem_DebugRawRealloc(void *, void *, size_t); +extern void _PyMem_DebugRawFree(void *, void *); + +extern void* _PyMem_DebugMalloc(void *, size_t); +extern void* _PyMem_DebugCalloc(void *, size_t, size_t); +extern void* _PyMem_DebugRealloc(void *, void *, size_t); +extern void _PyMem_DebugFree(void *, void *); + +#define PYDBGRAW_ALLOC(runtime) \ + {&(runtime).allocators.debug.raw, _PyMem_DebugRawMalloc, _PyMem_DebugRawCalloc, _PyMem_DebugRawRealloc, _PyMem_DebugRawFree} +#define PYDBGMEM_ALLOC(runtime) \ + {&(runtime).allocators.debug.mem, _PyMem_DebugMalloc, _PyMem_DebugCalloc, _PyMem_DebugRealloc, _PyMem_DebugFree} +#define PYDBGOBJ_ALLOC(runtime) \ + {&(runtime).allocators.debug.obj, _PyMem_DebugMalloc, _PyMem_DebugCalloc, _PyMem_DebugRealloc, _PyMem_DebugFree} + +extern void * _PyMem_ArenaAlloc(void *, size_t); +extern void _PyMem_ArenaFree(void *, void *, size_t); + +#ifdef Py_DEBUG +# define _pymem_allocators_standard_INIT(runtime) \ + { \ + PYDBGRAW_ALLOC(runtime), \ + PYDBGMEM_ALLOC(runtime), \ + PYDBGOBJ_ALLOC(runtime), \ + } +#else +# define _pymem_allocators_standard_INIT(runtime) \ + { \ + PYRAW_ALLOC, \ + PYMEM_ALLOC, \ + PYOBJ_ALLOC, \ + } +#endif + +#define _pymem_allocators_debug_INIT \ + { \ + {'r', PYRAW_ALLOC}, \ + {'m', PYMEM_ALLOC}, \ + {'o', PYOBJ_ALLOC}, \ + } + +# define _pymem_allocators_obj_arena_INIT \ + { NULL, _PyMem_ArenaAlloc, _PyMem_ArenaFree } + + +#ifdef __cplusplus +} +#endif +#endif // !Py_INTERNAL_PYMEM_INIT_H diff --git a/Include/internal/pycore_pystate.h b/Include/internal/pycore_pystate.h index cb8f1157..ccfc2586 100644 --- a/Include/internal/pycore_pystate.h +++ b/Include/internal/pycore_pystate.h @@ -33,6 +33,13 @@ _Py_IsMainInterpreter(PyInterpreterState *interp) return (interp == _PyInterpreterState_Main()); } +static inline int +_Py_IsMainInterpreterFinalizing(PyInterpreterState *interp) +{ + return (_PyRuntimeState_GetFinalizing(interp->runtime) != NULL && + interp == &interp->runtime->_main_interpreter); +} + static inline const PyConfig * _Py_GetMainConfig(void) @@ -53,28 +60,17 @@ _Py_ThreadCanHandleSignals(PyInterpreterState *interp) } -/* Only execute pending calls on the main thread. */ -static inline int -_Py_ThreadCanHandlePendingCalls(void) -{ - return _Py_IsMainThread(); -} - - -/* Variable and macro for in-line access to current thread +/* Variable and static inline functions for in-line access to current thread and interpreter state */ -static inline PyThreadState* -_PyRuntimeState_GetThreadState(_PyRuntimeState *runtime) -{ - return (PyThreadState*)_Py_atomic_load_relaxed(&runtime->gilstate.tstate_current); -} +#if defined(HAVE_THREAD_LOCAL) && !defined(Py_BUILD_CORE_MODULE) +extern _Py_thread_local PyThreadState *_Py_tss_tstate; +#endif +PyAPI_DATA(PyThreadState *) _PyThreadState_GetCurrent(void); /* Get the current Python thread state. - Efficient macro reading directly the 'gilstate.tstate_current' atomic - variable. The macro is unsafe: it does not check for error and it can - return NULL. + This function is unsafe: it does not check for error and it can return NULL. The caller must hold the GIL. @@ -82,27 +78,33 @@ _PyRuntimeState_GetThreadState(_PyRuntimeState *runtime) static inline PyThreadState* _PyThreadState_GET(void) { - return _PyRuntimeState_GetThreadState(&_PyRuntime); +#if defined(HAVE_THREAD_LOCAL) && !defined(Py_BUILD_CORE_MODULE) + return _Py_tss_tstate; +#else + return _PyThreadState_GetCurrent(); +#endif } -PyAPI_FUNC(void) _Py_NO_RETURN _Py_FatalError_TstateNULL(const char *func); static inline void _Py_EnsureFuncTstateNotNULL(const char *func, PyThreadState *tstate) { if (tstate == NULL) { - _Py_FatalError_TstateNULL(func); + _Py_FatalErrorFunc(func, + "the function must be called with the GIL held, " + "after Python initialization and before Python finalization, " + "but the GIL is released (the current Python thread state is NULL)"); } } // Call Py_FatalError() if tstate is NULL #define _Py_EnsureTstateNotNULL(tstate) \ - _Py_EnsureFuncTstateNotNULL(__func__, tstate) + _Py_EnsureFuncTstateNotNULL(__func__, (tstate)) /* Get the current interpreter state. - The macro is unsafe: it does not check for error and it can return NULL. + The function is unsafe: it does not check for error and it can return NULL. The caller must hold the GIL. @@ -119,36 +121,24 @@ static inline PyInterpreterState* _PyInterpreterState_GET(void) { // PyThreadState functions -PyAPI_FUNC(void) _PyThreadState_SetCurrent(PyThreadState *tstate); +PyAPI_FUNC(PyThreadState *) _PyThreadState_New(PyInterpreterState *interp); +PyAPI_FUNC(void) _PyThreadState_Bind(PyThreadState *tstate); // We keep this around exclusively for stable ABI compatibility. PyAPI_FUNC(void) _PyThreadState_Init( PyThreadState *tstate); -PyAPI_FUNC(void) _PyThreadState_DeleteExcept( - _PyRuntimeState *runtime, - PyThreadState *tstate); - - -static inline void -_PyThreadState_UpdateTracingState(PyThreadState *tstate) -{ - bool use_tracing = - (tstate->tracing == 0) && - (tstate->c_tracefunc != NULL || tstate->c_profilefunc != NULL); - tstate->cframe->use_tracing = (use_tracing ? 255 : 0); -} +PyAPI_FUNC(void) _PyThreadState_DeleteExcept(PyThreadState *tstate); /* Other */ PyAPI_FUNC(PyThreadState *) _PyThreadState_Swap( - struct _gilstate_runtime_state *gilstate, + _PyRuntimeState *runtime, PyThreadState *newts); PyAPI_FUNC(PyStatus) _PyInterpreterState_Enable(_PyRuntimeState *runtime); #ifdef HAVE_FORK extern PyStatus _PyInterpreterState_DeleteExceptMain(_PyRuntimeState *runtime); -extern PyStatus _PyGILState_Reinit(_PyRuntimeState *runtime); extern void _PySignal_AfterFork(void); #endif @@ -161,6 +151,12 @@ PyAPI_FUNC(int) _PyState_AddModule( PyAPI_FUNC(int) _PyOS_InterruptOccurred(PyThreadState *tstate); +#define HEAD_LOCK(runtime) \ + PyThread_acquire_lock((runtime)->interpreters.mutex, WAIT_LOCK) +#define HEAD_UNLOCK(runtime) \ + PyThread_release_lock((runtime)->interpreters.mutex) + + #ifdef __cplusplus } #endif diff --git a/Include/internal/pycore_pythread.h b/Include/internal/pycore_pythread.h new file mode 100644 index 00000000..f5392149 --- /dev/null +++ b/Include/internal/pycore_pythread.h @@ -0,0 +1,81 @@ +#ifndef Py_INTERNAL_PYTHREAD_H +#define Py_INTERNAL_PYTHREAD_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + + +#ifndef _POSIX_THREADS +/* This means pthreads are not implemented in libc headers, hence the macro + not present in unistd.h. But they still can be implemented as an external + library (e.g. gnu pth in pthread emulation) */ +# ifdef HAVE_PTHREAD_H +# include <pthread.h> /* _POSIX_THREADS */ +# endif +# ifndef _POSIX_THREADS +/* Check if we're running on HP-UX and _SC_THREADS is defined. If so, then + enough of the Posix threads package is implemented to support python + threads. + + This is valid for HP-UX 11.23 running on an ia64 system. If needed, add + a check of __ia64 to verify that we're running on an ia64 system instead + of a pa-risc system. +*/ +# ifdef __hpux +# ifdef _SC_THREADS +# define _POSIX_THREADS +# endif +# endif +# endif /* _POSIX_THREADS */ +#endif /* _POSIX_THREADS */ + +#if defined(_POSIX_THREADS) || defined(HAVE_PTHREAD_STUBS) +# define _USE_PTHREADS +#endif + +#if defined(_USE_PTHREADS) && defined(HAVE_PTHREAD_CONDATTR_SETCLOCK) && defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC) +// monotonic is supported statically. It doesn't mean it works on runtime. +# define CONDATTR_MONOTONIC +#endif + + +#if defined(HAVE_PTHREAD_STUBS) +// pthread_key +struct py_stub_tls_entry { + bool in_use; + void *value; +}; +#endif + +struct _pythread_runtime_state { + int initialized; + +#ifdef _USE_PTHREADS + // This matches when thread_pthread.h is used. + struct { + /* NULL when pthread_condattr_setclock(CLOCK_MONOTONIC) is not supported. */ + pthread_condattr_t *ptr; +# ifdef CONDATTR_MONOTONIC + /* The value to which condattr_monotonic is set. */ + pthread_condattr_t val; +# endif + } _condattr_monotonic; + +#endif // USE_PTHREADS + +#if defined(HAVE_PTHREAD_STUBS) + struct { + struct py_stub_tls_entry tls_entries[PTHREAD_KEYS_MAX]; + } stubs; +#endif +}; + + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_PYTHREAD_H */ diff --git a/Include/internal/pycore_range.h b/Include/internal/pycore_range.h new file mode 100644 index 00000000..bf045ec4 --- /dev/null +++ b/Include/internal/pycore_range.h @@ -0,0 +1,21 @@ +#ifndef Py_INTERNAL_RANGE_H +#define Py_INTERNAL_RANGE_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +typedef struct { + PyObject_HEAD + long start; + long step; + long len; +} _PyRangeIterObject; + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_RANGE_H */ diff --git a/Include/internal/pycore_runtime.h b/Include/internal/pycore_runtime.h index ae63ae74..5ed97e97 100644 --- a/Include/internal/pycore_runtime.h +++ b/Include/internal/pycore_runtime.h @@ -8,22 +8,28 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif +#include "pycore_atexit.h" // struct atexit_runtime_state #include "pycore_atomic.h" /* _Py_atomic_address */ -#include "pycore_gil.h" // struct _gil_runtime_state +#include "pycore_ceval_state.h" // struct _ceval_runtime_state +#include "pycore_floatobject.h" // struct _Py_float_runtime_state +#include "pycore_faulthandler.h" // struct _faulthandler_runtime_state #include "pycore_global_objects.h" // struct _Py_global_objects +#include "pycore_import.h" // struct _import_runtime_state #include "pycore_interp.h" // PyInterpreterState +#include "pycore_object_state.h" // struct _py_object_runtime_state +#include "pycore_parser.h" // struct _parser_runtime_state +#include "pycore_pymem.h" // struct _pymem_allocators +#include "pycore_pyhash.h" // struct pyhash_runtime_state +#include "pycore_pythread.h" // struct _pythread_runtime_state +#include "pycore_signal.h" // struct _signals_runtime_state +#include "pycore_time.h" // struct _time_runtime_state +#include "pycore_tracemalloc.h" // struct _tracemalloc_runtime_state +#include "pycore_typeobject.h" // struct types_runtime_state #include "pycore_unicodeobject.h" // struct _Py_unicode_runtime_ids - -/* ceval state */ - -struct _ceval_runtime_state { - /* Request for checking signals. It is shared by all interpreters (see - bpo-40513). Any thread of any interpreter can receive a signal, but only - the main thread of the main interpreter can handle signals: see - _Py_ThreadCanHandleSignals(). */ - _Py_atomic_int signals_pending; - struct _gil_runtime_state gil; +struct _getargs_runtime_state { + PyThread_type_lock mutex; + struct _PyArg_Parser *static_parsers; }; /* GIL state */ @@ -32,15 +38,11 @@ struct _gilstate_runtime_state { /* bpo-26558: Flag to disable PyGILState_Check(). If set to non-zero, PyGILState_Check() always return 1. */ int check_enabled; - /* Assuming the current thread holds the GIL, this is the - PyThreadState for the current thread. */ - _Py_atomic_address tstate_current; /* The single PyInterpreterState used by this process' GILState implementation */ /* TODO: Given interp_main, it may be possible to kill this ref */ PyInterpreterState *autoInterpreterState; - Py_tss_t autoTSSkey; }; /* Runtime audit hook state */ @@ -90,8 +92,8 @@ typedef struct pyruntimestate { in the operation of the runtime. It is also often the only interpreter. */ PyInterpreterState *main; - /* _next_interp_id is an auto-numbered sequence of small - integers. It gets initialized in _PyInterpreterState_Init(), + /* next_id is an auto-numbered sequence of small + integers. It gets initialized in _PyInterpreterState_Enable(), which is called in Py_Initialize(), and used in PyInterpreterState_New(). A negative interpreter ID indicates an error occurred. The main interpreter will @@ -100,20 +102,46 @@ typedef struct pyruntimestate { using a Python int. */ int64_t next_id; } interpreters; + + unsigned long main_thread; + + /* ---------- IMPORTANT --------------------------- + The fields above this line are declared as early as + possible to facilitate out-of-process observability + tools. */ + // XXX Remove this field once we have a tp_* slot. struct _xidregistry { PyThread_type_lock mutex; struct _xidregitem *head; } xidregistry; - unsigned long main_thread; + struct _pymem_allocators allocators; + struct _obmalloc_global_state obmalloc; + struct pyhash_runtime_state pyhash_state; + struct _time_runtime_state time; + struct _pythread_runtime_state threads; + struct _signals_runtime_state signals; + + /* Used for the thread state bound to the current thread. */ + Py_tss_t autoTSSkey; + + /* Used instead of PyThreadState.trash when there is not current tstate. */ + Py_tss_t trashTSSkey; -#define NEXITFUNCS 32 - void (*exitfuncs[NEXITFUNCS])(void); - int nexitfuncs; + PyWideStringList orig_argv; + struct _parser_runtime_state parser; + + struct _atexit_runtime_state atexit; + + struct _import_runtime_state imports; struct _ceval_runtime_state ceval; struct _gilstate_runtime_state gilstate; + struct _getargs_runtime_state getargs; + struct _fileutils_state fileutils; + struct _faulthandler_runtime_state faulthandler; + struct _tracemalloc_runtime_state tracemalloc; PyPreConfig preconfig; @@ -121,12 +149,18 @@ typedef struct pyruntimestate { // is called multiple times. Py_OpenCodeHookFunction open_code_hook; void *open_code_userdata; - _Py_AuditHookEntry *audit_hook_head; + struct { + PyThread_type_lock mutex; + _Py_AuditHookEntry *head; + } audit_hooks; - struct _Py_unicode_runtime_ids unicode_ids; + struct _py_object_runtime_state object_state; + struct _Py_float_runtime_state float_state; + struct _Py_unicode_runtime_state unicode_state; + struct _types_runtime_state types; /* All the objects that are shared by the runtime's interpreters. */ - struct _Py_global_objects global_objects; + struct _Py_static_objects static_objects; /* The following fields are here to avoid allocation during init. The data is exposed through _PyRuntimeState pointer fields. diff --git a/Include/internal/pycore_runtime_init.h b/Include/internal/pycore_runtime_init.h index 13eae1e4..7aace9f8 100644 --- a/Include/internal/pycore_runtime_init.h +++ b/Include/internal/pycore_runtime_init.h @@ -8,48 +8,87 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif +#include "pycore_long.h" #include "pycore_object.h" +#include "pycore_parser.h" +#include "pycore_pymem_init.h" +#include "pycore_obmalloc_init.h" + + +extern PyTypeObject _PyExc_MemoryError; /* The static initializers defined here should only be used in the runtime init code (in pystate.c and pylifecycle.c). */ -#define _PyRuntimeState_INIT \ +#define _PyRuntimeState_INIT(runtime) \ { \ - .gilstate = { \ - .check_enabled = 1, \ - /* A TSS key must be initialized with Py_tss_NEEDS_INIT \ - in accordance with the specification. */ \ - .autoTSSkey = Py_tss_NEEDS_INIT, \ + .allocators = { \ + .standard = _pymem_allocators_standard_INIT(runtime), \ + .debug = _pymem_allocators_debug_INIT, \ + .obj_arena = _pymem_allocators_obj_arena_INIT, \ }, \ + .obmalloc = _obmalloc_global_state_INIT, \ + .pyhash_state = pyhash_state_INIT, \ + .signals = _signals_RUNTIME_INIT, \ .interpreters = { \ /* This prevents interpreters from getting created \ until _PyInterpreterState_Enable() is called. */ \ .next_id = -1, \ }, \ - .global_objects = _Py_global_objects_INIT, \ - ._main_interpreter = _PyInterpreterState_INIT, \ + /* A TSS key must be initialized with Py_tss_NEEDS_INIT \ + in accordance with the specification. */ \ + .autoTSSkey = Py_tss_NEEDS_INIT, \ + .parser = _parser_runtime_state_INIT, \ + .ceval = { \ + .perf = _PyEval_RUNTIME_PERF_INIT, \ + }, \ + .gilstate = { \ + .check_enabled = 1, \ + }, \ + .fileutils = { \ + .force_ascii = -1, \ + }, \ + .faulthandler = _faulthandler_runtime_state_INIT, \ + .tracemalloc = _tracemalloc_runtime_state_INIT, \ + .float_state = { \ + .float_format = _py_float_format_unknown, \ + .double_format = _py_float_format_unknown, \ + }, \ + .types = { \ + .next_version_tag = 1, \ + }, \ + .static_objects = { \ + .singletons = { \ + .small_ints = _Py_small_ints_INIT, \ + .bytes_empty = _PyBytes_SIMPLE_INIT(0, 0), \ + .bytes_characters = _Py_bytes_characters_INIT, \ + .strings = { \ + .literals = _Py_str_literals_INIT, \ + .identifiers = _Py_str_identifiers_INIT, \ + .ascii = _Py_str_ascii_INIT, \ + .latin1 = _Py_str_latin1_INIT, \ + }, \ + .tuple_empty = { \ + .ob_base = _PyVarObject_HEAD_INIT(&PyTuple_Type, 0) \ + }, \ + .hamt_bitmap_node_empty = { \ + .ob_base = _PyVarObject_HEAD_INIT(&_PyHamt_BitmapNode_Type, 0) \ + }, \ + .context_token_missing = { \ + .ob_base = _PyObject_HEAD_INIT(&_PyContextTokenMissing_Type) \ + }, \ + }, \ + }, \ + ._main_interpreter = _PyInterpreterState_INIT(runtime._main_interpreter), \ } -#ifdef HAVE_DLOPEN -# include <dlfcn.h> -# if HAVE_DECL_RTLD_NOW -# define _Py_DLOPEN_FLAGS RTLD_NOW -# else -# define _Py_DLOPEN_FLAGS RTLD_LAZY -# endif -# define DLOPENFLAGS_INIT .dlopenflags = _Py_DLOPEN_FLAGS, -#else -# define _Py_DLOPEN_FLAGS 0 -# define DLOPENFLAGS_INIT -#endif - -#define _PyInterpreterState_INIT \ +#define _PyInterpreterState_INIT(INTERP) \ { \ - ._static = 1, \ .id_refcount = -1, \ - DLOPENFLAGS_INIT \ + .imports = IMPORTS_INIT, \ + .obmalloc = _obmalloc_state_INIT(INTERP.obmalloc), \ .ceval = { \ .recursion_limit = Py_DEFAULT_RECURSION_LIMIT, \ }, \ @@ -62,1193 +101,91 @@ extern "C" { { .threshold = 10, }, \ }, \ }, \ + .object_state = _py_object_state_INIT(INTERP), \ + .dtoa = _dtoa_state_INIT(&(INTERP)), \ + .dict_state = _dict_state_INIT, \ + .func_state = { \ + .next_version = 1, \ + }, \ + .types = { \ + .next_version_tag = _Py_TYPE_BASE_VERSION_TAG, \ + }, \ + .static_objects = { \ + .singletons = { \ + ._not_used = 1, \ + .hamt_empty = { \ + .ob_base = _PyObject_HEAD_INIT(&_PyHamt_Type) \ + .h_root = (PyHamtNode*)&_Py_SINGLETON(hamt_bitmap_node_empty), \ + }, \ + .last_resort_memory_error = { \ + _PyObject_HEAD_INIT(&_PyExc_MemoryError) \ + }, \ + }, \ + }, \ ._initial_thread = _PyThreadState_INIT, \ } #define _PyThreadState_INIT \ { \ - ._static = 1, \ - .recursion_limit = Py_DEFAULT_RECURSION_LIMIT, \ + .py_recursion_limit = Py_DEFAULT_RECURSION_LIMIT, \ .context_ver = 1, \ } - -// global objects - -#define _PyLong_DIGIT_INIT(val) \ +#ifdef Py_TRACE_REFS +# define _py_object_state_INIT(INTERP) \ { \ - _PyVarObject_IMMORTAL_INIT(&PyLong_Type, \ - ((val) == 0 ? 0 : ((val) > 0 ? 1 : -1))), \ - .ob_digit = { ((val) >= 0 ? (val) : -(val)) }, \ + .refchain = {&INTERP.object_state.refchain, &INTERP.object_state.refchain}, \ } +#else +# define _py_object_state_INIT(INTERP) \ + { 0 } +#endif + + +// global objects #define _PyBytes_SIMPLE_INIT(CH, LEN) \ { \ - _PyVarObject_IMMORTAL_INIT(&PyBytes_Type, LEN), \ + _PyVarObject_HEAD_INIT(&PyBytes_Type, (LEN)) \ .ob_shash = -1, \ - .ob_sval = { CH }, \ + .ob_sval = { (CH) }, \ } #define _PyBytes_CHAR_INIT(CH) \ { \ - _PyBytes_SIMPLE_INIT(CH, 1) \ + _PyBytes_SIMPLE_INIT((CH), 1) \ } #define _PyUnicode_ASCII_BASE_INIT(LITERAL, ASCII) \ { \ - .ob_base = _PyObject_IMMORTAL_INIT(&PyUnicode_Type), \ + .ob_base = _PyObject_HEAD_INIT(&PyUnicode_Type) \ .length = sizeof(LITERAL) - 1, \ .hash = -1, \ .state = { \ .kind = 1, \ .compact = 1, \ - .ascii = ASCII, \ - .ready = 1, \ + .ascii = (ASCII), \ }, \ } #define _PyASCIIObject_INIT(LITERAL) \ { \ - ._ascii = _PyUnicode_ASCII_BASE_INIT(LITERAL, 1), \ - ._data = LITERAL \ + ._ascii = _PyUnicode_ASCII_BASE_INIT((LITERAL), 1), \ + ._data = (LITERAL) \ } #define INIT_STR(NAME, LITERAL) \ - ._ ## NAME = _PyASCIIObject_INIT(LITERAL) + ._py_ ## NAME = _PyASCIIObject_INIT(LITERAL) #define INIT_ID(NAME) \ - ._ ## NAME = _PyASCIIObject_INIT(#NAME) -#define _PyUnicode_LATIN1_INIT(LITERAL) \ + ._py_ ## NAME = _PyASCIIObject_INIT(#NAME) +#define _PyUnicode_LATIN1_INIT(LITERAL, UTF8) \ { \ ._latin1 = { \ - ._base = _PyUnicode_ASCII_BASE_INIT(LITERAL, 0), \ + ._base = _PyUnicode_ASCII_BASE_INIT((LITERAL), 0), \ + .utf8 = (UTF8), \ + .utf8_length = sizeof(UTF8) - 1, \ }, \ - ._data = LITERAL, \ + ._data = (LITERAL), \ } -/* The following is auto-generated by Tools/scripts/generate_global_objects.py. */ -#define _Py_global_objects_INIT { \ - .singletons = { \ - .small_ints = { \ - _PyLong_DIGIT_INIT(-5), \ - _PyLong_DIGIT_INIT(-4), \ - _PyLong_DIGIT_INIT(-3), \ - _PyLong_DIGIT_INIT(-2), \ - _PyLong_DIGIT_INIT(-1), \ - _PyLong_DIGIT_INIT(0), \ - _PyLong_DIGIT_INIT(1), \ - _PyLong_DIGIT_INIT(2), \ - _PyLong_DIGIT_INIT(3), \ - _PyLong_DIGIT_INIT(4), \ - _PyLong_DIGIT_INIT(5), \ - _PyLong_DIGIT_INIT(6), \ - _PyLong_DIGIT_INIT(7), \ - _PyLong_DIGIT_INIT(8), \ - _PyLong_DIGIT_INIT(9), \ - _PyLong_DIGIT_INIT(10), \ - _PyLong_DIGIT_INIT(11), \ - _PyLong_DIGIT_INIT(12), \ - _PyLong_DIGIT_INIT(13), \ - _PyLong_DIGIT_INIT(14), \ - _PyLong_DIGIT_INIT(15), \ - _PyLong_DIGIT_INIT(16), \ - _PyLong_DIGIT_INIT(17), \ - _PyLong_DIGIT_INIT(18), \ - _PyLong_DIGIT_INIT(19), \ - _PyLong_DIGIT_INIT(20), \ - _PyLong_DIGIT_INIT(21), \ - _PyLong_DIGIT_INIT(22), \ - _PyLong_DIGIT_INIT(23), \ - _PyLong_DIGIT_INIT(24), \ - _PyLong_DIGIT_INIT(25), \ - _PyLong_DIGIT_INIT(26), \ - _PyLong_DIGIT_INIT(27), \ - _PyLong_DIGIT_INIT(28), \ - _PyLong_DIGIT_INIT(29), \ - _PyLong_DIGIT_INIT(30), \ - _PyLong_DIGIT_INIT(31), \ - _PyLong_DIGIT_INIT(32), \ - _PyLong_DIGIT_INIT(33), \ - _PyLong_DIGIT_INIT(34), \ - _PyLong_DIGIT_INIT(35), \ - _PyLong_DIGIT_INIT(36), \ - _PyLong_DIGIT_INIT(37), \ - _PyLong_DIGIT_INIT(38), \ - _PyLong_DIGIT_INIT(39), \ - _PyLong_DIGIT_INIT(40), \ - _PyLong_DIGIT_INIT(41), \ - _PyLong_DIGIT_INIT(42), \ - _PyLong_DIGIT_INIT(43), \ - _PyLong_DIGIT_INIT(44), \ - _PyLong_DIGIT_INIT(45), \ - _PyLong_DIGIT_INIT(46), \ - _PyLong_DIGIT_INIT(47), \ - _PyLong_DIGIT_INIT(48), \ - _PyLong_DIGIT_INIT(49), \ - _PyLong_DIGIT_INIT(50), \ - _PyLong_DIGIT_INIT(51), \ - _PyLong_DIGIT_INIT(52), \ - _PyLong_DIGIT_INIT(53), \ - _PyLong_DIGIT_INIT(54), \ - _PyLong_DIGIT_INIT(55), \ - _PyLong_DIGIT_INIT(56), \ - _PyLong_DIGIT_INIT(57), \ - _PyLong_DIGIT_INIT(58), \ - _PyLong_DIGIT_INIT(59), \ - _PyLong_DIGIT_INIT(60), \ - _PyLong_DIGIT_INIT(61), \ - _PyLong_DIGIT_INIT(62), \ - _PyLong_DIGIT_INIT(63), \ - _PyLong_DIGIT_INIT(64), \ - _PyLong_DIGIT_INIT(65), \ - _PyLong_DIGIT_INIT(66), \ - _PyLong_DIGIT_INIT(67), \ - _PyLong_DIGIT_INIT(68), \ - _PyLong_DIGIT_INIT(69), \ - _PyLong_DIGIT_INIT(70), \ - _PyLong_DIGIT_INIT(71), \ - _PyLong_DIGIT_INIT(72), \ - _PyLong_DIGIT_INIT(73), \ - _PyLong_DIGIT_INIT(74), \ - _PyLong_DIGIT_INIT(75), \ - _PyLong_DIGIT_INIT(76), \ - _PyLong_DIGIT_INIT(77), \ - _PyLong_DIGIT_INIT(78), \ - _PyLong_DIGIT_INIT(79), \ - _PyLong_DIGIT_INIT(80), \ - _PyLong_DIGIT_INIT(81), \ - _PyLong_DIGIT_INIT(82), \ - _PyLong_DIGIT_INIT(83), \ - _PyLong_DIGIT_INIT(84), \ - _PyLong_DIGIT_INIT(85), \ - _PyLong_DIGIT_INIT(86), \ - _PyLong_DIGIT_INIT(87), \ - _PyLong_DIGIT_INIT(88), \ - _PyLong_DIGIT_INIT(89), \ - _PyLong_DIGIT_INIT(90), \ - _PyLong_DIGIT_INIT(91), \ - _PyLong_DIGIT_INIT(92), \ - _PyLong_DIGIT_INIT(93), \ - _PyLong_DIGIT_INIT(94), \ - _PyLong_DIGIT_INIT(95), \ - _PyLong_DIGIT_INIT(96), \ - _PyLong_DIGIT_INIT(97), \ - _PyLong_DIGIT_INIT(98), \ - _PyLong_DIGIT_INIT(99), \ - _PyLong_DIGIT_INIT(100), \ - _PyLong_DIGIT_INIT(101), \ - _PyLong_DIGIT_INIT(102), \ - _PyLong_DIGIT_INIT(103), \ - _PyLong_DIGIT_INIT(104), \ - _PyLong_DIGIT_INIT(105), \ - _PyLong_DIGIT_INIT(106), \ - _PyLong_DIGIT_INIT(107), \ - _PyLong_DIGIT_INIT(108), \ - _PyLong_DIGIT_INIT(109), \ - _PyLong_DIGIT_INIT(110), \ - _PyLong_DIGIT_INIT(111), \ - _PyLong_DIGIT_INIT(112), \ - _PyLong_DIGIT_INIT(113), \ - _PyLong_DIGIT_INIT(114), \ - _PyLong_DIGIT_INIT(115), \ - _PyLong_DIGIT_INIT(116), \ - _PyLong_DIGIT_INIT(117), \ - _PyLong_DIGIT_INIT(118), \ - _PyLong_DIGIT_INIT(119), \ - _PyLong_DIGIT_INIT(120), \ - _PyLong_DIGIT_INIT(121), \ - _PyLong_DIGIT_INIT(122), \ - _PyLong_DIGIT_INIT(123), \ - _PyLong_DIGIT_INIT(124), \ - _PyLong_DIGIT_INIT(125), \ - _PyLong_DIGIT_INIT(126), \ - _PyLong_DIGIT_INIT(127), \ - _PyLong_DIGIT_INIT(128), \ - _PyLong_DIGIT_INIT(129), \ - _PyLong_DIGIT_INIT(130), \ - _PyLong_DIGIT_INIT(131), \ - _PyLong_DIGIT_INIT(132), \ - _PyLong_DIGIT_INIT(133), \ - _PyLong_DIGIT_INIT(134), \ - _PyLong_DIGIT_INIT(135), \ - _PyLong_DIGIT_INIT(136), \ - _PyLong_DIGIT_INIT(137), \ - _PyLong_DIGIT_INIT(138), \ - _PyLong_DIGIT_INIT(139), \ - _PyLong_DIGIT_INIT(140), \ - _PyLong_DIGIT_INIT(141), \ - _PyLong_DIGIT_INIT(142), \ - _PyLong_DIGIT_INIT(143), \ - _PyLong_DIGIT_INIT(144), \ - _PyLong_DIGIT_INIT(145), \ - _PyLong_DIGIT_INIT(146), \ - _PyLong_DIGIT_INIT(147), \ - _PyLong_DIGIT_INIT(148), \ - _PyLong_DIGIT_INIT(149), \ - _PyLong_DIGIT_INIT(150), \ - _PyLong_DIGIT_INIT(151), \ - _PyLong_DIGIT_INIT(152), \ - _PyLong_DIGIT_INIT(153), \ - _PyLong_DIGIT_INIT(154), \ - _PyLong_DIGIT_INIT(155), \ - _PyLong_DIGIT_INIT(156), \ - _PyLong_DIGIT_INIT(157), \ - _PyLong_DIGIT_INIT(158), \ - _PyLong_DIGIT_INIT(159), \ - _PyLong_DIGIT_INIT(160), \ - _PyLong_DIGIT_INIT(161), \ - _PyLong_DIGIT_INIT(162), \ - _PyLong_DIGIT_INIT(163), \ - _PyLong_DIGIT_INIT(164), \ - _PyLong_DIGIT_INIT(165), \ - _PyLong_DIGIT_INIT(166), \ - _PyLong_DIGIT_INIT(167), \ - _PyLong_DIGIT_INIT(168), \ - _PyLong_DIGIT_INIT(169), \ - _PyLong_DIGIT_INIT(170), \ - _PyLong_DIGIT_INIT(171), \ - _PyLong_DIGIT_INIT(172), \ - _PyLong_DIGIT_INIT(173), \ - _PyLong_DIGIT_INIT(174), \ - _PyLong_DIGIT_INIT(175), \ - _PyLong_DIGIT_INIT(176), \ - _PyLong_DIGIT_INIT(177), \ - _PyLong_DIGIT_INIT(178), \ - _PyLong_DIGIT_INIT(179), \ - _PyLong_DIGIT_INIT(180), \ - _PyLong_DIGIT_INIT(181), \ - _PyLong_DIGIT_INIT(182), \ - _PyLong_DIGIT_INIT(183), \ - _PyLong_DIGIT_INIT(184), \ - _PyLong_DIGIT_INIT(185), \ - _PyLong_DIGIT_INIT(186), \ - _PyLong_DIGIT_INIT(187), \ - _PyLong_DIGIT_INIT(188), \ - _PyLong_DIGIT_INIT(189), \ - _PyLong_DIGIT_INIT(190), \ - _PyLong_DIGIT_INIT(191), \ - _PyLong_DIGIT_INIT(192), \ - _PyLong_DIGIT_INIT(193), \ - _PyLong_DIGIT_INIT(194), \ - _PyLong_DIGIT_INIT(195), \ - _PyLong_DIGIT_INIT(196), \ - _PyLong_DIGIT_INIT(197), \ - _PyLong_DIGIT_INIT(198), \ - _PyLong_DIGIT_INIT(199), \ - _PyLong_DIGIT_INIT(200), \ - _PyLong_DIGIT_INIT(201), \ - _PyLong_DIGIT_INIT(202), \ - _PyLong_DIGIT_INIT(203), \ - _PyLong_DIGIT_INIT(204), \ - _PyLong_DIGIT_INIT(205), \ - _PyLong_DIGIT_INIT(206), \ - _PyLong_DIGIT_INIT(207), \ - _PyLong_DIGIT_INIT(208), \ - _PyLong_DIGIT_INIT(209), \ - _PyLong_DIGIT_INIT(210), \ - _PyLong_DIGIT_INIT(211), \ - _PyLong_DIGIT_INIT(212), \ - _PyLong_DIGIT_INIT(213), \ - _PyLong_DIGIT_INIT(214), \ - _PyLong_DIGIT_INIT(215), \ - _PyLong_DIGIT_INIT(216), \ - _PyLong_DIGIT_INIT(217), \ - _PyLong_DIGIT_INIT(218), \ - _PyLong_DIGIT_INIT(219), \ - _PyLong_DIGIT_INIT(220), \ - _PyLong_DIGIT_INIT(221), \ - _PyLong_DIGIT_INIT(222), \ - _PyLong_DIGIT_INIT(223), \ - _PyLong_DIGIT_INIT(224), \ - _PyLong_DIGIT_INIT(225), \ - _PyLong_DIGIT_INIT(226), \ - _PyLong_DIGIT_INIT(227), \ - _PyLong_DIGIT_INIT(228), \ - _PyLong_DIGIT_INIT(229), \ - _PyLong_DIGIT_INIT(230), \ - _PyLong_DIGIT_INIT(231), \ - _PyLong_DIGIT_INIT(232), \ - _PyLong_DIGIT_INIT(233), \ - _PyLong_DIGIT_INIT(234), \ - _PyLong_DIGIT_INIT(235), \ - _PyLong_DIGIT_INIT(236), \ - _PyLong_DIGIT_INIT(237), \ - _PyLong_DIGIT_INIT(238), \ - _PyLong_DIGIT_INIT(239), \ - _PyLong_DIGIT_INIT(240), \ - _PyLong_DIGIT_INIT(241), \ - _PyLong_DIGIT_INIT(242), \ - _PyLong_DIGIT_INIT(243), \ - _PyLong_DIGIT_INIT(244), \ - _PyLong_DIGIT_INIT(245), \ - _PyLong_DIGIT_INIT(246), \ - _PyLong_DIGIT_INIT(247), \ - _PyLong_DIGIT_INIT(248), \ - _PyLong_DIGIT_INIT(249), \ - _PyLong_DIGIT_INIT(250), \ - _PyLong_DIGIT_INIT(251), \ - _PyLong_DIGIT_INIT(252), \ - _PyLong_DIGIT_INIT(253), \ - _PyLong_DIGIT_INIT(254), \ - _PyLong_DIGIT_INIT(255), \ - _PyLong_DIGIT_INIT(256), \ - }, \ - \ - .bytes_empty = _PyBytes_SIMPLE_INIT(0, 0), \ - .bytes_characters = { \ - _PyBytes_CHAR_INIT(0), \ - _PyBytes_CHAR_INIT(1), \ - _PyBytes_CHAR_INIT(2), \ - _PyBytes_CHAR_INIT(3), \ - _PyBytes_CHAR_INIT(4), \ - _PyBytes_CHAR_INIT(5), \ - _PyBytes_CHAR_INIT(6), \ - _PyBytes_CHAR_INIT(7), \ - _PyBytes_CHAR_INIT(8), \ - _PyBytes_CHAR_INIT(9), \ - _PyBytes_CHAR_INIT(10), \ - _PyBytes_CHAR_INIT(11), \ - _PyBytes_CHAR_INIT(12), \ - _PyBytes_CHAR_INIT(13), \ - _PyBytes_CHAR_INIT(14), \ - _PyBytes_CHAR_INIT(15), \ - _PyBytes_CHAR_INIT(16), \ - _PyBytes_CHAR_INIT(17), \ - _PyBytes_CHAR_INIT(18), \ - _PyBytes_CHAR_INIT(19), \ - _PyBytes_CHAR_INIT(20), \ - _PyBytes_CHAR_INIT(21), \ - _PyBytes_CHAR_INIT(22), \ - _PyBytes_CHAR_INIT(23), \ - _PyBytes_CHAR_INIT(24), \ - _PyBytes_CHAR_INIT(25), \ - _PyBytes_CHAR_INIT(26), \ - _PyBytes_CHAR_INIT(27), \ - _PyBytes_CHAR_INIT(28), \ - _PyBytes_CHAR_INIT(29), \ - _PyBytes_CHAR_INIT(30), \ - _PyBytes_CHAR_INIT(31), \ - _PyBytes_CHAR_INIT(32), \ - _PyBytes_CHAR_INIT(33), \ - _PyBytes_CHAR_INIT(34), \ - _PyBytes_CHAR_INIT(35), \ - _PyBytes_CHAR_INIT(36), \ - _PyBytes_CHAR_INIT(37), \ - _PyBytes_CHAR_INIT(38), \ - _PyBytes_CHAR_INIT(39), \ - _PyBytes_CHAR_INIT(40), \ - _PyBytes_CHAR_INIT(41), \ - _PyBytes_CHAR_INIT(42), \ - _PyBytes_CHAR_INIT(43), \ - _PyBytes_CHAR_INIT(44), \ - _PyBytes_CHAR_INIT(45), \ - _PyBytes_CHAR_INIT(46), \ - _PyBytes_CHAR_INIT(47), \ - _PyBytes_CHAR_INIT(48), \ - _PyBytes_CHAR_INIT(49), \ - _PyBytes_CHAR_INIT(50), \ - _PyBytes_CHAR_INIT(51), \ - _PyBytes_CHAR_INIT(52), \ - _PyBytes_CHAR_INIT(53), \ - _PyBytes_CHAR_INIT(54), \ - _PyBytes_CHAR_INIT(55), \ - _PyBytes_CHAR_INIT(56), \ - _PyBytes_CHAR_INIT(57), \ - _PyBytes_CHAR_INIT(58), \ - _PyBytes_CHAR_INIT(59), \ - _PyBytes_CHAR_INIT(60), \ - _PyBytes_CHAR_INIT(61), \ - _PyBytes_CHAR_INIT(62), \ - _PyBytes_CHAR_INIT(63), \ - _PyBytes_CHAR_INIT(64), \ - _PyBytes_CHAR_INIT(65), \ - _PyBytes_CHAR_INIT(66), \ - _PyBytes_CHAR_INIT(67), \ - _PyBytes_CHAR_INIT(68), \ - _PyBytes_CHAR_INIT(69), \ - _PyBytes_CHAR_INIT(70), \ - _PyBytes_CHAR_INIT(71), \ - _PyBytes_CHAR_INIT(72), \ - _PyBytes_CHAR_INIT(73), \ - _PyBytes_CHAR_INIT(74), \ - _PyBytes_CHAR_INIT(75), \ - _PyBytes_CHAR_INIT(76), \ - _PyBytes_CHAR_INIT(77), \ - _PyBytes_CHAR_INIT(78), \ - _PyBytes_CHAR_INIT(79), \ - _PyBytes_CHAR_INIT(80), \ - _PyBytes_CHAR_INIT(81), \ - _PyBytes_CHAR_INIT(82), \ - _PyBytes_CHAR_INIT(83), \ - _PyBytes_CHAR_INIT(84), \ - _PyBytes_CHAR_INIT(85), \ - _PyBytes_CHAR_INIT(86), \ - _PyBytes_CHAR_INIT(87), \ - _PyBytes_CHAR_INIT(88), \ - _PyBytes_CHAR_INIT(89), \ - _PyBytes_CHAR_INIT(90), \ - _PyBytes_CHAR_INIT(91), \ - _PyBytes_CHAR_INIT(92), \ - _PyBytes_CHAR_INIT(93), \ - _PyBytes_CHAR_INIT(94), \ - _PyBytes_CHAR_INIT(95), \ - _PyBytes_CHAR_INIT(96), \ - _PyBytes_CHAR_INIT(97), \ - _PyBytes_CHAR_INIT(98), \ - _PyBytes_CHAR_INIT(99), \ - _PyBytes_CHAR_INIT(100), \ - _PyBytes_CHAR_INIT(101), \ - _PyBytes_CHAR_INIT(102), \ - _PyBytes_CHAR_INIT(103), \ - _PyBytes_CHAR_INIT(104), \ - _PyBytes_CHAR_INIT(105), \ - _PyBytes_CHAR_INIT(106), \ - _PyBytes_CHAR_INIT(107), \ - _PyBytes_CHAR_INIT(108), \ - _PyBytes_CHAR_INIT(109), \ - _PyBytes_CHAR_INIT(110), \ - _PyBytes_CHAR_INIT(111), \ - _PyBytes_CHAR_INIT(112), \ - _PyBytes_CHAR_INIT(113), \ - _PyBytes_CHAR_INIT(114), \ - _PyBytes_CHAR_INIT(115), \ - _PyBytes_CHAR_INIT(116), \ - _PyBytes_CHAR_INIT(117), \ - _PyBytes_CHAR_INIT(118), \ - _PyBytes_CHAR_INIT(119), \ - _PyBytes_CHAR_INIT(120), \ - _PyBytes_CHAR_INIT(121), \ - _PyBytes_CHAR_INIT(122), \ - _PyBytes_CHAR_INIT(123), \ - _PyBytes_CHAR_INIT(124), \ - _PyBytes_CHAR_INIT(125), \ - _PyBytes_CHAR_INIT(126), \ - _PyBytes_CHAR_INIT(127), \ - _PyBytes_CHAR_INIT(128), \ - _PyBytes_CHAR_INIT(129), \ - _PyBytes_CHAR_INIT(130), \ - _PyBytes_CHAR_INIT(131), \ - _PyBytes_CHAR_INIT(132), \ - _PyBytes_CHAR_INIT(133), \ - _PyBytes_CHAR_INIT(134), \ - _PyBytes_CHAR_INIT(135), \ - _PyBytes_CHAR_INIT(136), \ - _PyBytes_CHAR_INIT(137), \ - _PyBytes_CHAR_INIT(138), \ - _PyBytes_CHAR_INIT(139), \ - _PyBytes_CHAR_INIT(140), \ - _PyBytes_CHAR_INIT(141), \ - _PyBytes_CHAR_INIT(142), \ - _PyBytes_CHAR_INIT(143), \ - _PyBytes_CHAR_INIT(144), \ - _PyBytes_CHAR_INIT(145), \ - _PyBytes_CHAR_INIT(146), \ - _PyBytes_CHAR_INIT(147), \ - _PyBytes_CHAR_INIT(148), \ - _PyBytes_CHAR_INIT(149), \ - _PyBytes_CHAR_INIT(150), \ - _PyBytes_CHAR_INIT(151), \ - _PyBytes_CHAR_INIT(152), \ - _PyBytes_CHAR_INIT(153), \ - _PyBytes_CHAR_INIT(154), \ - _PyBytes_CHAR_INIT(155), \ - _PyBytes_CHAR_INIT(156), \ - _PyBytes_CHAR_INIT(157), \ - _PyBytes_CHAR_INIT(158), \ - _PyBytes_CHAR_INIT(159), \ - _PyBytes_CHAR_INIT(160), \ - _PyBytes_CHAR_INIT(161), \ - _PyBytes_CHAR_INIT(162), \ - _PyBytes_CHAR_INIT(163), \ - _PyBytes_CHAR_INIT(164), \ - _PyBytes_CHAR_INIT(165), \ - _PyBytes_CHAR_INIT(166), \ - _PyBytes_CHAR_INIT(167), \ - _PyBytes_CHAR_INIT(168), \ - _PyBytes_CHAR_INIT(169), \ - _PyBytes_CHAR_INIT(170), \ - _PyBytes_CHAR_INIT(171), \ - _PyBytes_CHAR_INIT(172), \ - _PyBytes_CHAR_INIT(173), \ - _PyBytes_CHAR_INIT(174), \ - _PyBytes_CHAR_INIT(175), \ - _PyBytes_CHAR_INIT(176), \ - _PyBytes_CHAR_INIT(177), \ - _PyBytes_CHAR_INIT(178), \ - _PyBytes_CHAR_INIT(179), \ - _PyBytes_CHAR_INIT(180), \ - _PyBytes_CHAR_INIT(181), \ - _PyBytes_CHAR_INIT(182), \ - _PyBytes_CHAR_INIT(183), \ - _PyBytes_CHAR_INIT(184), \ - _PyBytes_CHAR_INIT(185), \ - _PyBytes_CHAR_INIT(186), \ - _PyBytes_CHAR_INIT(187), \ - _PyBytes_CHAR_INIT(188), \ - _PyBytes_CHAR_INIT(189), \ - _PyBytes_CHAR_INIT(190), \ - _PyBytes_CHAR_INIT(191), \ - _PyBytes_CHAR_INIT(192), \ - _PyBytes_CHAR_INIT(193), \ - _PyBytes_CHAR_INIT(194), \ - _PyBytes_CHAR_INIT(195), \ - _PyBytes_CHAR_INIT(196), \ - _PyBytes_CHAR_INIT(197), \ - _PyBytes_CHAR_INIT(198), \ - _PyBytes_CHAR_INIT(199), \ - _PyBytes_CHAR_INIT(200), \ - _PyBytes_CHAR_INIT(201), \ - _PyBytes_CHAR_INIT(202), \ - _PyBytes_CHAR_INIT(203), \ - _PyBytes_CHAR_INIT(204), \ - _PyBytes_CHAR_INIT(205), \ - _PyBytes_CHAR_INIT(206), \ - _PyBytes_CHAR_INIT(207), \ - _PyBytes_CHAR_INIT(208), \ - _PyBytes_CHAR_INIT(209), \ - _PyBytes_CHAR_INIT(210), \ - _PyBytes_CHAR_INIT(211), \ - _PyBytes_CHAR_INIT(212), \ - _PyBytes_CHAR_INIT(213), \ - _PyBytes_CHAR_INIT(214), \ - _PyBytes_CHAR_INIT(215), \ - _PyBytes_CHAR_INIT(216), \ - _PyBytes_CHAR_INIT(217), \ - _PyBytes_CHAR_INIT(218), \ - _PyBytes_CHAR_INIT(219), \ - _PyBytes_CHAR_INIT(220), \ - _PyBytes_CHAR_INIT(221), \ - _PyBytes_CHAR_INIT(222), \ - _PyBytes_CHAR_INIT(223), \ - _PyBytes_CHAR_INIT(224), \ - _PyBytes_CHAR_INIT(225), \ - _PyBytes_CHAR_INIT(226), \ - _PyBytes_CHAR_INIT(227), \ - _PyBytes_CHAR_INIT(228), \ - _PyBytes_CHAR_INIT(229), \ - _PyBytes_CHAR_INIT(230), \ - _PyBytes_CHAR_INIT(231), \ - _PyBytes_CHAR_INIT(232), \ - _PyBytes_CHAR_INIT(233), \ - _PyBytes_CHAR_INIT(234), \ - _PyBytes_CHAR_INIT(235), \ - _PyBytes_CHAR_INIT(236), \ - _PyBytes_CHAR_INIT(237), \ - _PyBytes_CHAR_INIT(238), \ - _PyBytes_CHAR_INIT(239), \ - _PyBytes_CHAR_INIT(240), \ - _PyBytes_CHAR_INIT(241), \ - _PyBytes_CHAR_INIT(242), \ - _PyBytes_CHAR_INIT(243), \ - _PyBytes_CHAR_INIT(244), \ - _PyBytes_CHAR_INIT(245), \ - _PyBytes_CHAR_INIT(246), \ - _PyBytes_CHAR_INIT(247), \ - _PyBytes_CHAR_INIT(248), \ - _PyBytes_CHAR_INIT(249), \ - _PyBytes_CHAR_INIT(250), \ - _PyBytes_CHAR_INIT(251), \ - _PyBytes_CHAR_INIT(252), \ - _PyBytes_CHAR_INIT(253), \ - _PyBytes_CHAR_INIT(254), \ - _PyBytes_CHAR_INIT(255), \ - }, \ - \ - .strings = { \ - .literals = { \ - INIT_STR(anon_dictcomp, "<dictcomp>"), \ - INIT_STR(anon_genexpr, "<genexpr>"), \ - INIT_STR(anon_lambda, "<lambda>"), \ - INIT_STR(anon_listcomp, "<listcomp>"), \ - INIT_STR(anon_module, "<module>"), \ - INIT_STR(anon_setcomp, "<setcomp>"), \ - INIT_STR(anon_string, "<string>"), \ - INIT_STR(anon_unknown, "<unknown>"), \ - INIT_STR(close_br, "}"), \ - INIT_STR(comma_sep, ", "), \ - INIT_STR(dbl_close_br, "}}"), \ - INIT_STR(dbl_open_br, "{{"), \ - INIT_STR(dbl_percent, "%%"), \ - INIT_STR(dot, "."), \ - INIT_STR(dot_locals, ".<locals>"), \ - INIT_STR(empty, ""), \ - INIT_STR(list_err, "list index out of range"), \ - INIT_STR(newline, "\n"), \ - INIT_STR(open_br, "{"), \ - INIT_STR(percent, "%"), \ - INIT_STR(utf_8, "utf-8"), \ - }, \ - .identifiers = { \ - INIT_ID(False), \ - INIT_ID(Py_Repr), \ - INIT_ID(TextIOWrapper), \ - INIT_ID(True), \ - INIT_ID(WarningMessage), \ - INIT_ID(_), \ - INIT_ID(__IOBase_closed), \ - INIT_ID(__abc_tpflags__), \ - INIT_ID(__abs__), \ - INIT_ID(__abstractmethods__), \ - INIT_ID(__add__), \ - INIT_ID(__aenter__), \ - INIT_ID(__aexit__), \ - INIT_ID(__aiter__), \ - INIT_ID(__all__), \ - INIT_ID(__and__), \ - INIT_ID(__anext__), \ - INIT_ID(__annotations__), \ - INIT_ID(__args__), \ - INIT_ID(__await__), \ - INIT_ID(__bases__), \ - INIT_ID(__bool__), \ - INIT_ID(__build_class__), \ - INIT_ID(__builtins__), \ - INIT_ID(__bytes__), \ - INIT_ID(__call__), \ - INIT_ID(__cantrace__), \ - INIT_ID(__class__), \ - INIT_ID(__class_getitem__), \ - INIT_ID(__classcell__), \ - INIT_ID(__complex__), \ - INIT_ID(__contains__), \ - INIT_ID(__copy__), \ - INIT_ID(__del__), \ - INIT_ID(__delattr__), \ - INIT_ID(__delete__), \ - INIT_ID(__delitem__), \ - INIT_ID(__dict__), \ - INIT_ID(__dir__), \ - INIT_ID(__divmod__), \ - INIT_ID(__doc__), \ - INIT_ID(__enter__), \ - INIT_ID(__eq__), \ - INIT_ID(__exit__), \ - INIT_ID(__file__), \ - INIT_ID(__float__), \ - INIT_ID(__floordiv__), \ - INIT_ID(__format__), \ - INIT_ID(__fspath__), \ - INIT_ID(__ge__), \ - INIT_ID(__get__), \ - INIT_ID(__getattr__), \ - INIT_ID(__getattribute__), \ - INIT_ID(__getinitargs__), \ - INIT_ID(__getitem__), \ - INIT_ID(__getnewargs__), \ - INIT_ID(__getnewargs_ex__), \ - INIT_ID(__getstate__), \ - INIT_ID(__gt__), \ - INIT_ID(__hash__), \ - INIT_ID(__iadd__), \ - INIT_ID(__iand__), \ - INIT_ID(__ifloordiv__), \ - INIT_ID(__ilshift__), \ - INIT_ID(__imatmul__), \ - INIT_ID(__imod__), \ - INIT_ID(__import__), \ - INIT_ID(__imul__), \ - INIT_ID(__index__), \ - INIT_ID(__init__), \ - INIT_ID(__init_subclass__), \ - INIT_ID(__instancecheck__), \ - INIT_ID(__int__), \ - INIT_ID(__invert__), \ - INIT_ID(__ior__), \ - INIT_ID(__ipow__), \ - INIT_ID(__irshift__), \ - INIT_ID(__isabstractmethod__), \ - INIT_ID(__isub__), \ - INIT_ID(__iter__), \ - INIT_ID(__itruediv__), \ - INIT_ID(__ixor__), \ - INIT_ID(__le__), \ - INIT_ID(__len__), \ - INIT_ID(__length_hint__), \ - INIT_ID(__lltrace__), \ - INIT_ID(__loader__), \ - INIT_ID(__lshift__), \ - INIT_ID(__lt__), \ - INIT_ID(__main__), \ - INIT_ID(__matmul__), \ - INIT_ID(__missing__), \ - INIT_ID(__mod__), \ - INIT_ID(__module__), \ - INIT_ID(__mro_entries__), \ - INIT_ID(__mul__), \ - INIT_ID(__name__), \ - INIT_ID(__ne__), \ - INIT_ID(__neg__), \ - INIT_ID(__new__), \ - INIT_ID(__newobj__), \ - INIT_ID(__newobj_ex__), \ - INIT_ID(__next__), \ - INIT_ID(__notes__), \ - INIT_ID(__or__), \ - INIT_ID(__orig_class__), \ - INIT_ID(__origin__), \ - INIT_ID(__package__), \ - INIT_ID(__parameters__), \ - INIT_ID(__path__), \ - INIT_ID(__pos__), \ - INIT_ID(__pow__), \ - INIT_ID(__prepare__), \ - INIT_ID(__qualname__), \ - INIT_ID(__radd__), \ - INIT_ID(__rand__), \ - INIT_ID(__rdivmod__), \ - INIT_ID(__reduce__), \ - INIT_ID(__reduce_ex__), \ - INIT_ID(__repr__), \ - INIT_ID(__reversed__), \ - INIT_ID(__rfloordiv__), \ - INIT_ID(__rlshift__), \ - INIT_ID(__rmatmul__), \ - INIT_ID(__rmod__), \ - INIT_ID(__rmul__), \ - INIT_ID(__ror__), \ - INIT_ID(__round__), \ - INIT_ID(__rpow__), \ - INIT_ID(__rrshift__), \ - INIT_ID(__rshift__), \ - INIT_ID(__rsub__), \ - INIT_ID(__rtruediv__), \ - INIT_ID(__rxor__), \ - INIT_ID(__set__), \ - INIT_ID(__set_name__), \ - INIT_ID(__setattr__), \ - INIT_ID(__setitem__), \ - INIT_ID(__setstate__), \ - INIT_ID(__sizeof__), \ - INIT_ID(__slotnames__), \ - INIT_ID(__slots__), \ - INIT_ID(__spec__), \ - INIT_ID(__str__), \ - INIT_ID(__sub__), \ - INIT_ID(__subclasscheck__), \ - INIT_ID(__subclasshook__), \ - INIT_ID(__truediv__), \ - INIT_ID(__trunc__), \ - INIT_ID(__typing_is_unpacked_typevartuple__), \ - INIT_ID(__typing_prepare_subst__), \ - INIT_ID(__typing_subst__), \ - INIT_ID(__typing_unpacked_tuple_args__), \ - INIT_ID(__warningregistry__), \ - INIT_ID(__weakref__), \ - INIT_ID(__xor__), \ - INIT_ID(_abc_impl), \ - INIT_ID(_annotation), \ - INIT_ID(_blksize), \ - INIT_ID(_bootstrap), \ - INIT_ID(_dealloc_warn), \ - INIT_ID(_finalizing), \ - INIT_ID(_find_and_load), \ - INIT_ID(_fix_up_module), \ - INIT_ID(_get_sourcefile), \ - INIT_ID(_handle_fromlist), \ - INIT_ID(_initializing), \ - INIT_ID(_is_text_encoding), \ - INIT_ID(_lock_unlock_module), \ - INIT_ID(_showwarnmsg), \ - INIT_ID(_shutdown), \ - INIT_ID(_slotnames), \ - INIT_ID(_strptime_time), \ - INIT_ID(_uninitialized_submodules), \ - INIT_ID(_warn_unawaited_coroutine), \ - INIT_ID(_xoptions), \ - INIT_ID(add), \ - INIT_ID(append), \ - INIT_ID(big), \ - INIT_ID(buffer), \ - INIT_ID(builtins), \ - INIT_ID(c_call), \ - INIT_ID(c_exception), \ - INIT_ID(c_return), \ - INIT_ID(call), \ - INIT_ID(clear), \ - INIT_ID(close), \ - INIT_ID(closed), \ - INIT_ID(code), \ - INIT_ID(copy), \ - INIT_ID(copyreg), \ - INIT_ID(decode), \ - INIT_ID(default), \ - INIT_ID(defaultaction), \ - INIT_ID(dictcomp), \ - INIT_ID(difference_update), \ - INIT_ID(dispatch_table), \ - INIT_ID(displayhook), \ - INIT_ID(enable), \ - INIT_ID(encode), \ - INIT_ID(encoding), \ - INIT_ID(end_lineno), \ - INIT_ID(end_offset), \ - INIT_ID(errors), \ - INIT_ID(excepthook), \ - INIT_ID(exception), \ - INIT_ID(extend), \ - INIT_ID(filename), \ - INIT_ID(fileno), \ - INIT_ID(fillvalue), \ - INIT_ID(filters), \ - INIT_ID(find_class), \ - INIT_ID(flush), \ - INIT_ID(genexpr), \ - INIT_ID(get), \ - INIT_ID(get_source), \ - INIT_ID(getattr), \ - INIT_ID(getstate), \ - INIT_ID(ignore), \ - INIT_ID(importlib), \ - INIT_ID(inf), \ - INIT_ID(intersection), \ - INIT_ID(isatty), \ - INIT_ID(isinstance), \ - INIT_ID(items), \ - INIT_ID(iter), \ - INIT_ID(join), \ - INIT_ID(keys), \ - INIT_ID(lambda), \ - INIT_ID(last_traceback), \ - INIT_ID(last_type), \ - INIT_ID(last_value), \ - INIT_ID(latin1), \ - INIT_ID(len), \ - INIT_ID(line), \ - INIT_ID(lineno), \ - INIT_ID(listcomp), \ - INIT_ID(little), \ - INIT_ID(locale), \ - INIT_ID(match), \ - INIT_ID(metaclass), \ - INIT_ID(mode), \ - INIT_ID(modules), \ - INIT_ID(mro), \ - INIT_ID(msg), \ - INIT_ID(n_fields), \ - INIT_ID(n_sequence_fields), \ - INIT_ID(n_unnamed_fields), \ - INIT_ID(name), \ - INIT_ID(newlines), \ - INIT_ID(next), \ - INIT_ID(obj), \ - INIT_ID(offset), \ - INIT_ID(onceregistry), \ - INIT_ID(opcode), \ - INIT_ID(open), \ - INIT_ID(parent), \ - INIT_ID(partial), \ - INIT_ID(path), \ - INIT_ID(peek), \ - INIT_ID(persistent_id), \ - INIT_ID(persistent_load), \ - INIT_ID(print_file_and_line), \ - INIT_ID(ps1), \ - INIT_ID(ps2), \ - INIT_ID(raw), \ - INIT_ID(read), \ - INIT_ID(read1), \ - INIT_ID(readable), \ - INIT_ID(readall), \ - INIT_ID(readinto), \ - INIT_ID(readinto1), \ - INIT_ID(readline), \ - INIT_ID(reducer_override), \ - INIT_ID(reload), \ - INIT_ID(replace), \ - INIT_ID(reset), \ - INIT_ID(return), \ - INIT_ID(reversed), \ - INIT_ID(seek), \ - INIT_ID(seekable), \ - INIT_ID(send), \ - INIT_ID(setcomp), \ - INIT_ID(setstate), \ - INIT_ID(sort), \ - INIT_ID(stderr), \ - INIT_ID(stdin), \ - INIT_ID(stdout), \ - INIT_ID(strict), \ - INIT_ID(symmetric_difference_update), \ - INIT_ID(tell), \ - INIT_ID(text), \ - INIT_ID(threading), \ - INIT_ID(throw), \ - INIT_ID(top), \ - INIT_ID(truncate), \ - INIT_ID(unraisablehook), \ - INIT_ID(values), \ - INIT_ID(version), \ - INIT_ID(warnings), \ - INIT_ID(warnoptions), \ - INIT_ID(writable), \ - INIT_ID(write), \ - INIT_ID(zipimporter), \ - }, \ - .ascii = { \ - _PyASCIIObject_INIT("\x00"), \ - _PyASCIIObject_INIT("\x01"), \ - _PyASCIIObject_INIT("\x02"), \ - _PyASCIIObject_INIT("\x03"), \ - _PyASCIIObject_INIT("\x04"), \ - _PyASCIIObject_INIT("\x05"), \ - _PyASCIIObject_INIT("\x06"), \ - _PyASCIIObject_INIT("\x07"), \ - _PyASCIIObject_INIT("\x08"), \ - _PyASCIIObject_INIT("\x09"), \ - _PyASCIIObject_INIT("\x0a"), \ - _PyASCIIObject_INIT("\x0b"), \ - _PyASCIIObject_INIT("\x0c"), \ - _PyASCIIObject_INIT("\x0d"), \ - _PyASCIIObject_INIT("\x0e"), \ - _PyASCIIObject_INIT("\x0f"), \ - _PyASCIIObject_INIT("\x10"), \ - _PyASCIIObject_INIT("\x11"), \ - _PyASCIIObject_INIT("\x12"), \ - _PyASCIIObject_INIT("\x13"), \ - _PyASCIIObject_INIT("\x14"), \ - _PyASCIIObject_INIT("\x15"), \ - _PyASCIIObject_INIT("\x16"), \ - _PyASCIIObject_INIT("\x17"), \ - _PyASCIIObject_INIT("\x18"), \ - _PyASCIIObject_INIT("\x19"), \ - _PyASCIIObject_INIT("\x1a"), \ - _PyASCIIObject_INIT("\x1b"), \ - _PyASCIIObject_INIT("\x1c"), \ - _PyASCIIObject_INIT("\x1d"), \ - _PyASCIIObject_INIT("\x1e"), \ - _PyASCIIObject_INIT("\x1f"), \ - _PyASCIIObject_INIT("\x20"), \ - _PyASCIIObject_INIT("\x21"), \ - _PyASCIIObject_INIT("\x22"), \ - _PyASCIIObject_INIT("\x23"), \ - _PyASCIIObject_INIT("\x24"), \ - _PyASCIIObject_INIT("\x25"), \ - _PyASCIIObject_INIT("\x26"), \ - _PyASCIIObject_INIT("\x27"), \ - _PyASCIIObject_INIT("\x28"), \ - _PyASCIIObject_INIT("\x29"), \ - _PyASCIIObject_INIT("\x2a"), \ - _PyASCIIObject_INIT("\x2b"), \ - _PyASCIIObject_INIT("\x2c"), \ - _PyASCIIObject_INIT("\x2d"), \ - _PyASCIIObject_INIT("\x2e"), \ - _PyASCIIObject_INIT("\x2f"), \ - _PyASCIIObject_INIT("\x30"), \ - _PyASCIIObject_INIT("\x31"), \ - _PyASCIIObject_INIT("\x32"), \ - _PyASCIIObject_INIT("\x33"), \ - _PyASCIIObject_INIT("\x34"), \ - _PyASCIIObject_INIT("\x35"), \ - _PyASCIIObject_INIT("\x36"), \ - _PyASCIIObject_INIT("\x37"), \ - _PyASCIIObject_INIT("\x38"), \ - _PyASCIIObject_INIT("\x39"), \ - _PyASCIIObject_INIT("\x3a"), \ - _PyASCIIObject_INIT("\x3b"), \ - _PyASCIIObject_INIT("\x3c"), \ - _PyASCIIObject_INIT("\x3d"), \ - _PyASCIIObject_INIT("\x3e"), \ - _PyASCIIObject_INIT("\x3f"), \ - _PyASCIIObject_INIT("\x40"), \ - _PyASCIIObject_INIT("\x41"), \ - _PyASCIIObject_INIT("\x42"), \ - _PyASCIIObject_INIT("\x43"), \ - _PyASCIIObject_INIT("\x44"), \ - _PyASCIIObject_INIT("\x45"), \ - _PyASCIIObject_INIT("\x46"), \ - _PyASCIIObject_INIT("\x47"), \ - _PyASCIIObject_INIT("\x48"), \ - _PyASCIIObject_INIT("\x49"), \ - _PyASCIIObject_INIT("\x4a"), \ - _PyASCIIObject_INIT("\x4b"), \ - _PyASCIIObject_INIT("\x4c"), \ - _PyASCIIObject_INIT("\x4d"), \ - _PyASCIIObject_INIT("\x4e"), \ - _PyASCIIObject_INIT("\x4f"), \ - _PyASCIIObject_INIT("\x50"), \ - _PyASCIIObject_INIT("\x51"), \ - _PyASCIIObject_INIT("\x52"), \ - _PyASCIIObject_INIT("\x53"), \ - _PyASCIIObject_INIT("\x54"), \ - _PyASCIIObject_INIT("\x55"), \ - _PyASCIIObject_INIT("\x56"), \ - _PyASCIIObject_INIT("\x57"), \ - _PyASCIIObject_INIT("\x58"), \ - _PyASCIIObject_INIT("\x59"), \ - _PyASCIIObject_INIT("\x5a"), \ - _PyASCIIObject_INIT("\x5b"), \ - _PyASCIIObject_INIT("\x5c"), \ - _PyASCIIObject_INIT("\x5d"), \ - _PyASCIIObject_INIT("\x5e"), \ - _PyASCIIObject_INIT("\x5f"), \ - _PyASCIIObject_INIT("\x60"), \ - _PyASCIIObject_INIT("\x61"), \ - _PyASCIIObject_INIT("\x62"), \ - _PyASCIIObject_INIT("\x63"), \ - _PyASCIIObject_INIT("\x64"), \ - _PyASCIIObject_INIT("\x65"), \ - _PyASCIIObject_INIT("\x66"), \ - _PyASCIIObject_INIT("\x67"), \ - _PyASCIIObject_INIT("\x68"), \ - _PyASCIIObject_INIT("\x69"), \ - _PyASCIIObject_INIT("\x6a"), \ - _PyASCIIObject_INIT("\x6b"), \ - _PyASCIIObject_INIT("\x6c"), \ - _PyASCIIObject_INIT("\x6d"), \ - _PyASCIIObject_INIT("\x6e"), \ - _PyASCIIObject_INIT("\x6f"), \ - _PyASCIIObject_INIT("\x70"), \ - _PyASCIIObject_INIT("\x71"), \ - _PyASCIIObject_INIT("\x72"), \ - _PyASCIIObject_INIT("\x73"), \ - _PyASCIIObject_INIT("\x74"), \ - _PyASCIIObject_INIT("\x75"), \ - _PyASCIIObject_INIT("\x76"), \ - _PyASCIIObject_INIT("\x77"), \ - _PyASCIIObject_INIT("\x78"), \ - _PyASCIIObject_INIT("\x79"), \ - _PyASCIIObject_INIT("\x7a"), \ - _PyASCIIObject_INIT("\x7b"), \ - _PyASCIIObject_INIT("\x7c"), \ - _PyASCIIObject_INIT("\x7d"), \ - _PyASCIIObject_INIT("\x7e"), \ - _PyASCIIObject_INIT("\x7f"), \ - }, \ - .latin1 = { \ - _PyUnicode_LATIN1_INIT("\x80"), \ - _PyUnicode_LATIN1_INIT("\x81"), \ - _PyUnicode_LATIN1_INIT("\x82"), \ - _PyUnicode_LATIN1_INIT("\x83"), \ - _PyUnicode_LATIN1_INIT("\x84"), \ - _PyUnicode_LATIN1_INIT("\x85"), \ - _PyUnicode_LATIN1_INIT("\x86"), \ - _PyUnicode_LATIN1_INIT("\x87"), \ - _PyUnicode_LATIN1_INIT("\x88"), \ - _PyUnicode_LATIN1_INIT("\x89"), \ - _PyUnicode_LATIN1_INIT("\x8a"), \ - _PyUnicode_LATIN1_INIT("\x8b"), \ - _PyUnicode_LATIN1_INIT("\x8c"), \ - _PyUnicode_LATIN1_INIT("\x8d"), \ - _PyUnicode_LATIN1_INIT("\x8e"), \ - _PyUnicode_LATIN1_INIT("\x8f"), \ - _PyUnicode_LATIN1_INIT("\x90"), \ - _PyUnicode_LATIN1_INIT("\x91"), \ - _PyUnicode_LATIN1_INIT("\x92"), \ - _PyUnicode_LATIN1_INIT("\x93"), \ - _PyUnicode_LATIN1_INIT("\x94"), \ - _PyUnicode_LATIN1_INIT("\x95"), \ - _PyUnicode_LATIN1_INIT("\x96"), \ - _PyUnicode_LATIN1_INIT("\x97"), \ - _PyUnicode_LATIN1_INIT("\x98"), \ - _PyUnicode_LATIN1_INIT("\x99"), \ - _PyUnicode_LATIN1_INIT("\x9a"), \ - _PyUnicode_LATIN1_INIT("\x9b"), \ - _PyUnicode_LATIN1_INIT("\x9c"), \ - _PyUnicode_LATIN1_INIT("\x9d"), \ - _PyUnicode_LATIN1_INIT("\x9e"), \ - _PyUnicode_LATIN1_INIT("\x9f"), \ - _PyUnicode_LATIN1_INIT("\xa0"), \ - _PyUnicode_LATIN1_INIT("\xa1"), \ - _PyUnicode_LATIN1_INIT("\xa2"), \ - _PyUnicode_LATIN1_INIT("\xa3"), \ - _PyUnicode_LATIN1_INIT("\xa4"), \ - _PyUnicode_LATIN1_INIT("\xa5"), \ - _PyUnicode_LATIN1_INIT("\xa6"), \ - _PyUnicode_LATIN1_INIT("\xa7"), \ - _PyUnicode_LATIN1_INIT("\xa8"), \ - _PyUnicode_LATIN1_INIT("\xa9"), \ - _PyUnicode_LATIN1_INIT("\xaa"), \ - _PyUnicode_LATIN1_INIT("\xab"), \ - _PyUnicode_LATIN1_INIT("\xac"), \ - _PyUnicode_LATIN1_INIT("\xad"), \ - _PyUnicode_LATIN1_INIT("\xae"), \ - _PyUnicode_LATIN1_INIT("\xaf"), \ - _PyUnicode_LATIN1_INIT("\xb0"), \ - _PyUnicode_LATIN1_INIT("\xb1"), \ - _PyUnicode_LATIN1_INIT("\xb2"), \ - _PyUnicode_LATIN1_INIT("\xb3"), \ - _PyUnicode_LATIN1_INIT("\xb4"), \ - _PyUnicode_LATIN1_INIT("\xb5"), \ - _PyUnicode_LATIN1_INIT("\xb6"), \ - _PyUnicode_LATIN1_INIT("\xb7"), \ - _PyUnicode_LATIN1_INIT("\xb8"), \ - _PyUnicode_LATIN1_INIT("\xb9"), \ - _PyUnicode_LATIN1_INIT("\xba"), \ - _PyUnicode_LATIN1_INIT("\xbb"), \ - _PyUnicode_LATIN1_INIT("\xbc"), \ - _PyUnicode_LATIN1_INIT("\xbd"), \ - _PyUnicode_LATIN1_INIT("\xbe"), \ - _PyUnicode_LATIN1_INIT("\xbf"), \ - _PyUnicode_LATIN1_INIT("\xc0"), \ - _PyUnicode_LATIN1_INIT("\xc1"), \ - _PyUnicode_LATIN1_INIT("\xc2"), \ - _PyUnicode_LATIN1_INIT("\xc3"), \ - _PyUnicode_LATIN1_INIT("\xc4"), \ - _PyUnicode_LATIN1_INIT("\xc5"), \ - _PyUnicode_LATIN1_INIT("\xc6"), \ - _PyUnicode_LATIN1_INIT("\xc7"), \ - _PyUnicode_LATIN1_INIT("\xc8"), \ - _PyUnicode_LATIN1_INIT("\xc9"), \ - _PyUnicode_LATIN1_INIT("\xca"), \ - _PyUnicode_LATIN1_INIT("\xcb"), \ - _PyUnicode_LATIN1_INIT("\xcc"), \ - _PyUnicode_LATIN1_INIT("\xcd"), \ - _PyUnicode_LATIN1_INIT("\xce"), \ - _PyUnicode_LATIN1_INIT("\xcf"), \ - _PyUnicode_LATIN1_INIT("\xd0"), \ - _PyUnicode_LATIN1_INIT("\xd1"), \ - _PyUnicode_LATIN1_INIT("\xd2"), \ - _PyUnicode_LATIN1_INIT("\xd3"), \ - _PyUnicode_LATIN1_INIT("\xd4"), \ - _PyUnicode_LATIN1_INIT("\xd5"), \ - _PyUnicode_LATIN1_INIT("\xd6"), \ - _PyUnicode_LATIN1_INIT("\xd7"), \ - _PyUnicode_LATIN1_INIT("\xd8"), \ - _PyUnicode_LATIN1_INIT("\xd9"), \ - _PyUnicode_LATIN1_INIT("\xda"), \ - _PyUnicode_LATIN1_INIT("\xdb"), \ - _PyUnicode_LATIN1_INIT("\xdc"), \ - _PyUnicode_LATIN1_INIT("\xdd"), \ - _PyUnicode_LATIN1_INIT("\xde"), \ - _PyUnicode_LATIN1_INIT("\xdf"), \ - _PyUnicode_LATIN1_INIT("\xe0"), \ - _PyUnicode_LATIN1_INIT("\xe1"), \ - _PyUnicode_LATIN1_INIT("\xe2"), \ - _PyUnicode_LATIN1_INIT("\xe3"), \ - _PyUnicode_LATIN1_INIT("\xe4"), \ - _PyUnicode_LATIN1_INIT("\xe5"), \ - _PyUnicode_LATIN1_INIT("\xe6"), \ - _PyUnicode_LATIN1_INIT("\xe7"), \ - _PyUnicode_LATIN1_INIT("\xe8"), \ - _PyUnicode_LATIN1_INIT("\xe9"), \ - _PyUnicode_LATIN1_INIT("\xea"), \ - _PyUnicode_LATIN1_INIT("\xeb"), \ - _PyUnicode_LATIN1_INIT("\xec"), \ - _PyUnicode_LATIN1_INIT("\xed"), \ - _PyUnicode_LATIN1_INIT("\xee"), \ - _PyUnicode_LATIN1_INIT("\xef"), \ - _PyUnicode_LATIN1_INIT("\xf0"), \ - _PyUnicode_LATIN1_INIT("\xf1"), \ - _PyUnicode_LATIN1_INIT("\xf2"), \ - _PyUnicode_LATIN1_INIT("\xf3"), \ - _PyUnicode_LATIN1_INIT("\xf4"), \ - _PyUnicode_LATIN1_INIT("\xf5"), \ - _PyUnicode_LATIN1_INIT("\xf6"), \ - _PyUnicode_LATIN1_INIT("\xf7"), \ - _PyUnicode_LATIN1_INIT("\xf8"), \ - _PyUnicode_LATIN1_INIT("\xf9"), \ - _PyUnicode_LATIN1_INIT("\xfa"), \ - _PyUnicode_LATIN1_INIT("\xfb"), \ - _PyUnicode_LATIN1_INIT("\xfc"), \ - _PyUnicode_LATIN1_INIT("\xfd"), \ - _PyUnicode_LATIN1_INIT("\xfe"), \ - _PyUnicode_LATIN1_INIT("\xff"), \ - }, \ - }, \ - \ - .tuple_empty = { \ - .ob_base = _PyVarObject_IMMORTAL_INIT(&PyTuple_Type, 0) \ - }, \ - }, \ -} -/* End auto-generated code */ - +#include "pycore_runtime_init_generated.h" #ifdef __cplusplus } diff --git a/Include/internal/pycore_runtime_init_generated.h b/Include/internal/pycore_runtime_init_generated.h new file mode 100644 index 00000000..07f237b2 --- /dev/null +++ b/Include/internal/pycore_runtime_init_generated.h @@ -0,0 +1,1525 @@ +#ifndef Py_INTERNAL_RUNTIME_INIT_GENERATED_H +#define Py_INTERNAL_RUNTIME_INIT_GENERATED_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +/* The following is auto-generated by Tools/build/generate_global_objects.py. */ +#define _Py_small_ints_INIT { \ + _PyLong_DIGIT_INIT(-5), \ + _PyLong_DIGIT_INIT(-4), \ + _PyLong_DIGIT_INIT(-3), \ + _PyLong_DIGIT_INIT(-2), \ + _PyLong_DIGIT_INIT(-1), \ + _PyLong_DIGIT_INIT(0), \ + _PyLong_DIGIT_INIT(1), \ + _PyLong_DIGIT_INIT(2), \ + _PyLong_DIGIT_INIT(3), \ + _PyLong_DIGIT_INIT(4), \ + _PyLong_DIGIT_INIT(5), \ + _PyLong_DIGIT_INIT(6), \ + _PyLong_DIGIT_INIT(7), \ + _PyLong_DIGIT_INIT(8), \ + _PyLong_DIGIT_INIT(9), \ + _PyLong_DIGIT_INIT(10), \ + _PyLong_DIGIT_INIT(11), \ + _PyLong_DIGIT_INIT(12), \ + _PyLong_DIGIT_INIT(13), \ + _PyLong_DIGIT_INIT(14), \ + _PyLong_DIGIT_INIT(15), \ + _PyLong_DIGIT_INIT(16), \ + _PyLong_DIGIT_INIT(17), \ + _PyLong_DIGIT_INIT(18), \ + _PyLong_DIGIT_INIT(19), \ + _PyLong_DIGIT_INIT(20), \ + _PyLong_DIGIT_INIT(21), \ + _PyLong_DIGIT_INIT(22), \ + _PyLong_DIGIT_INIT(23), \ + _PyLong_DIGIT_INIT(24), \ + _PyLong_DIGIT_INIT(25), \ + _PyLong_DIGIT_INIT(26), \ + _PyLong_DIGIT_INIT(27), \ + _PyLong_DIGIT_INIT(28), \ + _PyLong_DIGIT_INIT(29), \ + _PyLong_DIGIT_INIT(30), \ + _PyLong_DIGIT_INIT(31), \ + _PyLong_DIGIT_INIT(32), \ + _PyLong_DIGIT_INIT(33), \ + _PyLong_DIGIT_INIT(34), \ + _PyLong_DIGIT_INIT(35), \ + _PyLong_DIGIT_INIT(36), \ + _PyLong_DIGIT_INIT(37), \ + _PyLong_DIGIT_INIT(38), \ + _PyLong_DIGIT_INIT(39), \ + _PyLong_DIGIT_INIT(40), \ + _PyLong_DIGIT_INIT(41), \ + _PyLong_DIGIT_INIT(42), \ + _PyLong_DIGIT_INIT(43), \ + _PyLong_DIGIT_INIT(44), \ + _PyLong_DIGIT_INIT(45), \ + _PyLong_DIGIT_INIT(46), \ + _PyLong_DIGIT_INIT(47), \ + _PyLong_DIGIT_INIT(48), \ + _PyLong_DIGIT_INIT(49), \ + _PyLong_DIGIT_INIT(50), \ + _PyLong_DIGIT_INIT(51), \ + _PyLong_DIGIT_INIT(52), \ + _PyLong_DIGIT_INIT(53), \ + _PyLong_DIGIT_INIT(54), \ + _PyLong_DIGIT_INIT(55), \ + _PyLong_DIGIT_INIT(56), \ + _PyLong_DIGIT_INIT(57), \ + _PyLong_DIGIT_INIT(58), \ + _PyLong_DIGIT_INIT(59), \ + _PyLong_DIGIT_INIT(60), \ + _PyLong_DIGIT_INIT(61), \ + _PyLong_DIGIT_INIT(62), \ + _PyLong_DIGIT_INIT(63), \ + _PyLong_DIGIT_INIT(64), \ + _PyLong_DIGIT_INIT(65), \ + _PyLong_DIGIT_INIT(66), \ + _PyLong_DIGIT_INIT(67), \ + _PyLong_DIGIT_INIT(68), \ + _PyLong_DIGIT_INIT(69), \ + _PyLong_DIGIT_INIT(70), \ + _PyLong_DIGIT_INIT(71), \ + _PyLong_DIGIT_INIT(72), \ + _PyLong_DIGIT_INIT(73), \ + _PyLong_DIGIT_INIT(74), \ + _PyLong_DIGIT_INIT(75), \ + _PyLong_DIGIT_INIT(76), \ + _PyLong_DIGIT_INIT(77), \ + _PyLong_DIGIT_INIT(78), \ + _PyLong_DIGIT_INIT(79), \ + _PyLong_DIGIT_INIT(80), \ + _PyLong_DIGIT_INIT(81), \ + _PyLong_DIGIT_INIT(82), \ + _PyLong_DIGIT_INIT(83), \ + _PyLong_DIGIT_INIT(84), \ + _PyLong_DIGIT_INIT(85), \ + _PyLong_DIGIT_INIT(86), \ + _PyLong_DIGIT_INIT(87), \ + _PyLong_DIGIT_INIT(88), \ + _PyLong_DIGIT_INIT(89), \ + _PyLong_DIGIT_INIT(90), \ + _PyLong_DIGIT_INIT(91), \ + _PyLong_DIGIT_INIT(92), \ + _PyLong_DIGIT_INIT(93), \ + _PyLong_DIGIT_INIT(94), \ + _PyLong_DIGIT_INIT(95), \ + _PyLong_DIGIT_INIT(96), \ + _PyLong_DIGIT_INIT(97), \ + _PyLong_DIGIT_INIT(98), \ + _PyLong_DIGIT_INIT(99), \ + _PyLong_DIGIT_INIT(100), \ + _PyLong_DIGIT_INIT(101), \ + _PyLong_DIGIT_INIT(102), \ + _PyLong_DIGIT_INIT(103), \ + _PyLong_DIGIT_INIT(104), \ + _PyLong_DIGIT_INIT(105), \ + _PyLong_DIGIT_INIT(106), \ + _PyLong_DIGIT_INIT(107), \ + _PyLong_DIGIT_INIT(108), \ + _PyLong_DIGIT_INIT(109), \ + _PyLong_DIGIT_INIT(110), \ + _PyLong_DIGIT_INIT(111), \ + _PyLong_DIGIT_INIT(112), \ + _PyLong_DIGIT_INIT(113), \ + _PyLong_DIGIT_INIT(114), \ + _PyLong_DIGIT_INIT(115), \ + _PyLong_DIGIT_INIT(116), \ + _PyLong_DIGIT_INIT(117), \ + _PyLong_DIGIT_INIT(118), \ + _PyLong_DIGIT_INIT(119), \ + _PyLong_DIGIT_INIT(120), \ + _PyLong_DIGIT_INIT(121), \ + _PyLong_DIGIT_INIT(122), \ + _PyLong_DIGIT_INIT(123), \ + _PyLong_DIGIT_INIT(124), \ + _PyLong_DIGIT_INIT(125), \ + _PyLong_DIGIT_INIT(126), \ + _PyLong_DIGIT_INIT(127), \ + _PyLong_DIGIT_INIT(128), \ + _PyLong_DIGIT_INIT(129), \ + _PyLong_DIGIT_INIT(130), \ + _PyLong_DIGIT_INIT(131), \ + _PyLong_DIGIT_INIT(132), \ + _PyLong_DIGIT_INIT(133), \ + _PyLong_DIGIT_INIT(134), \ + _PyLong_DIGIT_INIT(135), \ + _PyLong_DIGIT_INIT(136), \ + _PyLong_DIGIT_INIT(137), \ + _PyLong_DIGIT_INIT(138), \ + _PyLong_DIGIT_INIT(139), \ + _PyLong_DIGIT_INIT(140), \ + _PyLong_DIGIT_INIT(141), \ + _PyLong_DIGIT_INIT(142), \ + _PyLong_DIGIT_INIT(143), \ + _PyLong_DIGIT_INIT(144), \ + _PyLong_DIGIT_INIT(145), \ + _PyLong_DIGIT_INIT(146), \ + _PyLong_DIGIT_INIT(147), \ + _PyLong_DIGIT_INIT(148), \ + _PyLong_DIGIT_INIT(149), \ + _PyLong_DIGIT_INIT(150), \ + _PyLong_DIGIT_INIT(151), \ + _PyLong_DIGIT_INIT(152), \ + _PyLong_DIGIT_INIT(153), \ + _PyLong_DIGIT_INIT(154), \ + _PyLong_DIGIT_INIT(155), \ + _PyLong_DIGIT_INIT(156), \ + _PyLong_DIGIT_INIT(157), \ + _PyLong_DIGIT_INIT(158), \ + _PyLong_DIGIT_INIT(159), \ + _PyLong_DIGIT_INIT(160), \ + _PyLong_DIGIT_INIT(161), \ + _PyLong_DIGIT_INIT(162), \ + _PyLong_DIGIT_INIT(163), \ + _PyLong_DIGIT_INIT(164), \ + _PyLong_DIGIT_INIT(165), \ + _PyLong_DIGIT_INIT(166), \ + _PyLong_DIGIT_INIT(167), \ + _PyLong_DIGIT_INIT(168), \ + _PyLong_DIGIT_INIT(169), \ + _PyLong_DIGIT_INIT(170), \ + _PyLong_DIGIT_INIT(171), \ + _PyLong_DIGIT_INIT(172), \ + _PyLong_DIGIT_INIT(173), \ + _PyLong_DIGIT_INIT(174), \ + _PyLong_DIGIT_INIT(175), \ + _PyLong_DIGIT_INIT(176), \ + _PyLong_DIGIT_INIT(177), \ + _PyLong_DIGIT_INIT(178), \ + _PyLong_DIGIT_INIT(179), \ + _PyLong_DIGIT_INIT(180), \ + _PyLong_DIGIT_INIT(181), \ + _PyLong_DIGIT_INIT(182), \ + _PyLong_DIGIT_INIT(183), \ + _PyLong_DIGIT_INIT(184), \ + _PyLong_DIGIT_INIT(185), \ + _PyLong_DIGIT_INIT(186), \ + _PyLong_DIGIT_INIT(187), \ + _PyLong_DIGIT_INIT(188), \ + _PyLong_DIGIT_INIT(189), \ + _PyLong_DIGIT_INIT(190), \ + _PyLong_DIGIT_INIT(191), \ + _PyLong_DIGIT_INIT(192), \ + _PyLong_DIGIT_INIT(193), \ + _PyLong_DIGIT_INIT(194), \ + _PyLong_DIGIT_INIT(195), \ + _PyLong_DIGIT_INIT(196), \ + _PyLong_DIGIT_INIT(197), \ + _PyLong_DIGIT_INIT(198), \ + _PyLong_DIGIT_INIT(199), \ + _PyLong_DIGIT_INIT(200), \ + _PyLong_DIGIT_INIT(201), \ + _PyLong_DIGIT_INIT(202), \ + _PyLong_DIGIT_INIT(203), \ + _PyLong_DIGIT_INIT(204), \ + _PyLong_DIGIT_INIT(205), \ + _PyLong_DIGIT_INIT(206), \ + _PyLong_DIGIT_INIT(207), \ + _PyLong_DIGIT_INIT(208), \ + _PyLong_DIGIT_INIT(209), \ + _PyLong_DIGIT_INIT(210), \ + _PyLong_DIGIT_INIT(211), \ + _PyLong_DIGIT_INIT(212), \ + _PyLong_DIGIT_INIT(213), \ + _PyLong_DIGIT_INIT(214), \ + _PyLong_DIGIT_INIT(215), \ + _PyLong_DIGIT_INIT(216), \ + _PyLong_DIGIT_INIT(217), \ + _PyLong_DIGIT_INIT(218), \ + _PyLong_DIGIT_INIT(219), \ + _PyLong_DIGIT_INIT(220), \ + _PyLong_DIGIT_INIT(221), \ + _PyLong_DIGIT_INIT(222), \ + _PyLong_DIGIT_INIT(223), \ + _PyLong_DIGIT_INIT(224), \ + _PyLong_DIGIT_INIT(225), \ + _PyLong_DIGIT_INIT(226), \ + _PyLong_DIGIT_INIT(227), \ + _PyLong_DIGIT_INIT(228), \ + _PyLong_DIGIT_INIT(229), \ + _PyLong_DIGIT_INIT(230), \ + _PyLong_DIGIT_INIT(231), \ + _PyLong_DIGIT_INIT(232), \ + _PyLong_DIGIT_INIT(233), \ + _PyLong_DIGIT_INIT(234), \ + _PyLong_DIGIT_INIT(235), \ + _PyLong_DIGIT_INIT(236), \ + _PyLong_DIGIT_INIT(237), \ + _PyLong_DIGIT_INIT(238), \ + _PyLong_DIGIT_INIT(239), \ + _PyLong_DIGIT_INIT(240), \ + _PyLong_DIGIT_INIT(241), \ + _PyLong_DIGIT_INIT(242), \ + _PyLong_DIGIT_INIT(243), \ + _PyLong_DIGIT_INIT(244), \ + _PyLong_DIGIT_INIT(245), \ + _PyLong_DIGIT_INIT(246), \ + _PyLong_DIGIT_INIT(247), \ + _PyLong_DIGIT_INIT(248), \ + _PyLong_DIGIT_INIT(249), \ + _PyLong_DIGIT_INIT(250), \ + _PyLong_DIGIT_INIT(251), \ + _PyLong_DIGIT_INIT(252), \ + _PyLong_DIGIT_INIT(253), \ + _PyLong_DIGIT_INIT(254), \ + _PyLong_DIGIT_INIT(255), \ + _PyLong_DIGIT_INIT(256), \ +} + +#define _Py_bytes_characters_INIT { \ + _PyBytes_CHAR_INIT(0), \ + _PyBytes_CHAR_INIT(1), \ + _PyBytes_CHAR_INIT(2), \ + _PyBytes_CHAR_INIT(3), \ + _PyBytes_CHAR_INIT(4), \ + _PyBytes_CHAR_INIT(5), \ + _PyBytes_CHAR_INIT(6), \ + _PyBytes_CHAR_INIT(7), \ + _PyBytes_CHAR_INIT(8), \ + _PyBytes_CHAR_INIT(9), \ + _PyBytes_CHAR_INIT(10), \ + _PyBytes_CHAR_INIT(11), \ + _PyBytes_CHAR_INIT(12), \ + _PyBytes_CHAR_INIT(13), \ + _PyBytes_CHAR_INIT(14), \ + _PyBytes_CHAR_INIT(15), \ + _PyBytes_CHAR_INIT(16), \ + _PyBytes_CHAR_INIT(17), \ + _PyBytes_CHAR_INIT(18), \ + _PyBytes_CHAR_INIT(19), \ + _PyBytes_CHAR_INIT(20), \ + _PyBytes_CHAR_INIT(21), \ + _PyBytes_CHAR_INIT(22), \ + _PyBytes_CHAR_INIT(23), \ + _PyBytes_CHAR_INIT(24), \ + _PyBytes_CHAR_INIT(25), \ + _PyBytes_CHAR_INIT(26), \ + _PyBytes_CHAR_INIT(27), \ + _PyBytes_CHAR_INIT(28), \ + _PyBytes_CHAR_INIT(29), \ + _PyBytes_CHAR_INIT(30), \ + _PyBytes_CHAR_INIT(31), \ + _PyBytes_CHAR_INIT(32), \ + _PyBytes_CHAR_INIT(33), \ + _PyBytes_CHAR_INIT(34), \ + _PyBytes_CHAR_INIT(35), \ + _PyBytes_CHAR_INIT(36), \ + _PyBytes_CHAR_INIT(37), \ + _PyBytes_CHAR_INIT(38), \ + _PyBytes_CHAR_INIT(39), \ + _PyBytes_CHAR_INIT(40), \ + _PyBytes_CHAR_INIT(41), \ + _PyBytes_CHAR_INIT(42), \ + _PyBytes_CHAR_INIT(43), \ + _PyBytes_CHAR_INIT(44), \ + _PyBytes_CHAR_INIT(45), \ + _PyBytes_CHAR_INIT(46), \ + _PyBytes_CHAR_INIT(47), \ + _PyBytes_CHAR_INIT(48), \ + _PyBytes_CHAR_INIT(49), \ + _PyBytes_CHAR_INIT(50), \ + _PyBytes_CHAR_INIT(51), \ + _PyBytes_CHAR_INIT(52), \ + _PyBytes_CHAR_INIT(53), \ + _PyBytes_CHAR_INIT(54), \ + _PyBytes_CHAR_INIT(55), \ + _PyBytes_CHAR_INIT(56), \ + _PyBytes_CHAR_INIT(57), \ + _PyBytes_CHAR_INIT(58), \ + _PyBytes_CHAR_INIT(59), \ + _PyBytes_CHAR_INIT(60), \ + _PyBytes_CHAR_INIT(61), \ + _PyBytes_CHAR_INIT(62), \ + _PyBytes_CHAR_INIT(63), \ + _PyBytes_CHAR_INIT(64), \ + _PyBytes_CHAR_INIT(65), \ + _PyBytes_CHAR_INIT(66), \ + _PyBytes_CHAR_INIT(67), \ + _PyBytes_CHAR_INIT(68), \ + _PyBytes_CHAR_INIT(69), \ + _PyBytes_CHAR_INIT(70), \ + _PyBytes_CHAR_INIT(71), \ + _PyBytes_CHAR_INIT(72), \ + _PyBytes_CHAR_INIT(73), \ + _PyBytes_CHAR_INIT(74), \ + _PyBytes_CHAR_INIT(75), \ + _PyBytes_CHAR_INIT(76), \ + _PyBytes_CHAR_INIT(77), \ + _PyBytes_CHAR_INIT(78), \ + _PyBytes_CHAR_INIT(79), \ + _PyBytes_CHAR_INIT(80), \ + _PyBytes_CHAR_INIT(81), \ + _PyBytes_CHAR_INIT(82), \ + _PyBytes_CHAR_INIT(83), \ + _PyBytes_CHAR_INIT(84), \ + _PyBytes_CHAR_INIT(85), \ + _PyBytes_CHAR_INIT(86), \ + _PyBytes_CHAR_INIT(87), \ + _PyBytes_CHAR_INIT(88), \ + _PyBytes_CHAR_INIT(89), \ + _PyBytes_CHAR_INIT(90), \ + _PyBytes_CHAR_INIT(91), \ + _PyBytes_CHAR_INIT(92), \ + _PyBytes_CHAR_INIT(93), \ + _PyBytes_CHAR_INIT(94), \ + _PyBytes_CHAR_INIT(95), \ + _PyBytes_CHAR_INIT(96), \ + _PyBytes_CHAR_INIT(97), \ + _PyBytes_CHAR_INIT(98), \ + _PyBytes_CHAR_INIT(99), \ + _PyBytes_CHAR_INIT(100), \ + _PyBytes_CHAR_INIT(101), \ + _PyBytes_CHAR_INIT(102), \ + _PyBytes_CHAR_INIT(103), \ + _PyBytes_CHAR_INIT(104), \ + _PyBytes_CHAR_INIT(105), \ + _PyBytes_CHAR_INIT(106), \ + _PyBytes_CHAR_INIT(107), \ + _PyBytes_CHAR_INIT(108), \ + _PyBytes_CHAR_INIT(109), \ + _PyBytes_CHAR_INIT(110), \ + _PyBytes_CHAR_INIT(111), \ + _PyBytes_CHAR_INIT(112), \ + _PyBytes_CHAR_INIT(113), \ + _PyBytes_CHAR_INIT(114), \ + _PyBytes_CHAR_INIT(115), \ + _PyBytes_CHAR_INIT(116), \ + _PyBytes_CHAR_INIT(117), \ + _PyBytes_CHAR_INIT(118), \ + _PyBytes_CHAR_INIT(119), \ + _PyBytes_CHAR_INIT(120), \ + _PyBytes_CHAR_INIT(121), \ + _PyBytes_CHAR_INIT(122), \ + _PyBytes_CHAR_INIT(123), \ + _PyBytes_CHAR_INIT(124), \ + _PyBytes_CHAR_INIT(125), \ + _PyBytes_CHAR_INIT(126), \ + _PyBytes_CHAR_INIT(127), \ + _PyBytes_CHAR_INIT(128), \ + _PyBytes_CHAR_INIT(129), \ + _PyBytes_CHAR_INIT(130), \ + _PyBytes_CHAR_INIT(131), \ + _PyBytes_CHAR_INIT(132), \ + _PyBytes_CHAR_INIT(133), \ + _PyBytes_CHAR_INIT(134), \ + _PyBytes_CHAR_INIT(135), \ + _PyBytes_CHAR_INIT(136), \ + _PyBytes_CHAR_INIT(137), \ + _PyBytes_CHAR_INIT(138), \ + _PyBytes_CHAR_INIT(139), \ + _PyBytes_CHAR_INIT(140), \ + _PyBytes_CHAR_INIT(141), \ + _PyBytes_CHAR_INIT(142), \ + _PyBytes_CHAR_INIT(143), \ + _PyBytes_CHAR_INIT(144), \ + _PyBytes_CHAR_INIT(145), \ + _PyBytes_CHAR_INIT(146), \ + _PyBytes_CHAR_INIT(147), \ + _PyBytes_CHAR_INIT(148), \ + _PyBytes_CHAR_INIT(149), \ + _PyBytes_CHAR_INIT(150), \ + _PyBytes_CHAR_INIT(151), \ + _PyBytes_CHAR_INIT(152), \ + _PyBytes_CHAR_INIT(153), \ + _PyBytes_CHAR_INIT(154), \ + _PyBytes_CHAR_INIT(155), \ + _PyBytes_CHAR_INIT(156), \ + _PyBytes_CHAR_INIT(157), \ + _PyBytes_CHAR_INIT(158), \ + _PyBytes_CHAR_INIT(159), \ + _PyBytes_CHAR_INIT(160), \ + _PyBytes_CHAR_INIT(161), \ + _PyBytes_CHAR_INIT(162), \ + _PyBytes_CHAR_INIT(163), \ + _PyBytes_CHAR_INIT(164), \ + _PyBytes_CHAR_INIT(165), \ + _PyBytes_CHAR_INIT(166), \ + _PyBytes_CHAR_INIT(167), \ + _PyBytes_CHAR_INIT(168), \ + _PyBytes_CHAR_INIT(169), \ + _PyBytes_CHAR_INIT(170), \ + _PyBytes_CHAR_INIT(171), \ + _PyBytes_CHAR_INIT(172), \ + _PyBytes_CHAR_INIT(173), \ + _PyBytes_CHAR_INIT(174), \ + _PyBytes_CHAR_INIT(175), \ + _PyBytes_CHAR_INIT(176), \ + _PyBytes_CHAR_INIT(177), \ + _PyBytes_CHAR_INIT(178), \ + _PyBytes_CHAR_INIT(179), \ + _PyBytes_CHAR_INIT(180), \ + _PyBytes_CHAR_INIT(181), \ + _PyBytes_CHAR_INIT(182), \ + _PyBytes_CHAR_INIT(183), \ + _PyBytes_CHAR_INIT(184), \ + _PyBytes_CHAR_INIT(185), \ + _PyBytes_CHAR_INIT(186), \ + _PyBytes_CHAR_INIT(187), \ + _PyBytes_CHAR_INIT(188), \ + _PyBytes_CHAR_INIT(189), \ + _PyBytes_CHAR_INIT(190), \ + _PyBytes_CHAR_INIT(191), \ + _PyBytes_CHAR_INIT(192), \ + _PyBytes_CHAR_INIT(193), \ + _PyBytes_CHAR_INIT(194), \ + _PyBytes_CHAR_INIT(195), \ + _PyBytes_CHAR_INIT(196), \ + _PyBytes_CHAR_INIT(197), \ + _PyBytes_CHAR_INIT(198), \ + _PyBytes_CHAR_INIT(199), \ + _PyBytes_CHAR_INIT(200), \ + _PyBytes_CHAR_INIT(201), \ + _PyBytes_CHAR_INIT(202), \ + _PyBytes_CHAR_INIT(203), \ + _PyBytes_CHAR_INIT(204), \ + _PyBytes_CHAR_INIT(205), \ + _PyBytes_CHAR_INIT(206), \ + _PyBytes_CHAR_INIT(207), \ + _PyBytes_CHAR_INIT(208), \ + _PyBytes_CHAR_INIT(209), \ + _PyBytes_CHAR_INIT(210), \ + _PyBytes_CHAR_INIT(211), \ + _PyBytes_CHAR_INIT(212), \ + _PyBytes_CHAR_INIT(213), \ + _PyBytes_CHAR_INIT(214), \ + _PyBytes_CHAR_INIT(215), \ + _PyBytes_CHAR_INIT(216), \ + _PyBytes_CHAR_INIT(217), \ + _PyBytes_CHAR_INIT(218), \ + _PyBytes_CHAR_INIT(219), \ + _PyBytes_CHAR_INIT(220), \ + _PyBytes_CHAR_INIT(221), \ + _PyBytes_CHAR_INIT(222), \ + _PyBytes_CHAR_INIT(223), \ + _PyBytes_CHAR_INIT(224), \ + _PyBytes_CHAR_INIT(225), \ + _PyBytes_CHAR_INIT(226), \ + _PyBytes_CHAR_INIT(227), \ + _PyBytes_CHAR_INIT(228), \ + _PyBytes_CHAR_INIT(229), \ + _PyBytes_CHAR_INIT(230), \ + _PyBytes_CHAR_INIT(231), \ + _PyBytes_CHAR_INIT(232), \ + _PyBytes_CHAR_INIT(233), \ + _PyBytes_CHAR_INIT(234), \ + _PyBytes_CHAR_INIT(235), \ + _PyBytes_CHAR_INIT(236), \ + _PyBytes_CHAR_INIT(237), \ + _PyBytes_CHAR_INIT(238), \ + _PyBytes_CHAR_INIT(239), \ + _PyBytes_CHAR_INIT(240), \ + _PyBytes_CHAR_INIT(241), \ + _PyBytes_CHAR_INIT(242), \ + _PyBytes_CHAR_INIT(243), \ + _PyBytes_CHAR_INIT(244), \ + _PyBytes_CHAR_INIT(245), \ + _PyBytes_CHAR_INIT(246), \ + _PyBytes_CHAR_INIT(247), \ + _PyBytes_CHAR_INIT(248), \ + _PyBytes_CHAR_INIT(249), \ + _PyBytes_CHAR_INIT(250), \ + _PyBytes_CHAR_INIT(251), \ + _PyBytes_CHAR_INIT(252), \ + _PyBytes_CHAR_INIT(253), \ + _PyBytes_CHAR_INIT(254), \ + _PyBytes_CHAR_INIT(255), \ +} + +#define _Py_str_literals_INIT { \ + INIT_STR(anon_dictcomp, "<dictcomp>"), \ + INIT_STR(anon_genexpr, "<genexpr>"), \ + INIT_STR(anon_lambda, "<lambda>"), \ + INIT_STR(anon_listcomp, "<listcomp>"), \ + INIT_STR(anon_module, "<module>"), \ + INIT_STR(anon_setcomp, "<setcomp>"), \ + INIT_STR(anon_string, "<string>"), \ + INIT_STR(anon_unknown, "<unknown>"), \ + INIT_STR(close_br, "}"), \ + INIT_STR(dbl_close_br, "}}"), \ + INIT_STR(dbl_open_br, "{{"), \ + INIT_STR(dbl_percent, "%%"), \ + INIT_STR(defaults, ".defaults"), \ + INIT_STR(dot, "."), \ + INIT_STR(dot_locals, ".<locals>"), \ + INIT_STR(empty, ""), \ + INIT_STR(generic_base, ".generic_base"), \ + INIT_STR(json_decoder, "json.decoder"), \ + INIT_STR(kwdefaults, ".kwdefaults"), \ + INIT_STR(list_err, "list index out of range"), \ + INIT_STR(newline, "\n"), \ + INIT_STR(open_br, "{"), \ + INIT_STR(percent, "%"), \ + INIT_STR(shim_name, "<shim>"), \ + INIT_STR(type_params, ".type_params"), \ + INIT_STR(utf_8, "utf-8"), \ +} + +#define _Py_str_identifiers_INIT { \ + INIT_ID(CANCELLED), \ + INIT_ID(FINISHED), \ + INIT_ID(False), \ + INIT_ID(JSONDecodeError), \ + INIT_ID(PENDING), \ + INIT_ID(Py_Repr), \ + INIT_ID(TextIOWrapper), \ + INIT_ID(True), \ + INIT_ID(WarningMessage), \ + INIT_ID(_), \ + INIT_ID(_WindowsConsoleIO), \ + INIT_ID(__IOBase_closed), \ + INIT_ID(__abc_tpflags__), \ + INIT_ID(__abs__), \ + INIT_ID(__abstractmethods__), \ + INIT_ID(__add__), \ + INIT_ID(__aenter__), \ + INIT_ID(__aexit__), \ + INIT_ID(__aiter__), \ + INIT_ID(__all__), \ + INIT_ID(__and__), \ + INIT_ID(__anext__), \ + INIT_ID(__annotations__), \ + INIT_ID(__args__), \ + INIT_ID(__asyncio_running_event_loop__), \ + INIT_ID(__await__), \ + INIT_ID(__bases__), \ + INIT_ID(__bool__), \ + INIT_ID(__buffer__), \ + INIT_ID(__build_class__), \ + INIT_ID(__builtins__), \ + INIT_ID(__bytes__), \ + INIT_ID(__call__), \ + INIT_ID(__cantrace__), \ + INIT_ID(__class__), \ + INIT_ID(__class_getitem__), \ + INIT_ID(__classcell__), \ + INIT_ID(__classdict__), \ + INIT_ID(__classdictcell__), \ + INIT_ID(__complex__), \ + INIT_ID(__contains__), \ + INIT_ID(__copy__), \ + INIT_ID(__ctypes_from_outparam__), \ + INIT_ID(__del__), \ + INIT_ID(__delattr__), \ + INIT_ID(__delete__), \ + INIT_ID(__delitem__), \ + INIT_ID(__dict__), \ + INIT_ID(__dictoffset__), \ + INIT_ID(__dir__), \ + INIT_ID(__divmod__), \ + INIT_ID(__doc__), \ + INIT_ID(__enter__), \ + INIT_ID(__eq__), \ + INIT_ID(__exit__), \ + INIT_ID(__file__), \ + INIT_ID(__float__), \ + INIT_ID(__floordiv__), \ + INIT_ID(__format__), \ + INIT_ID(__fspath__), \ + INIT_ID(__ge__), \ + INIT_ID(__get__), \ + INIT_ID(__getattr__), \ + INIT_ID(__getattribute__), \ + INIT_ID(__getinitargs__), \ + INIT_ID(__getitem__), \ + INIT_ID(__getnewargs__), \ + INIT_ID(__getnewargs_ex__), \ + INIT_ID(__getstate__), \ + INIT_ID(__gt__), \ + INIT_ID(__hash__), \ + INIT_ID(__iadd__), \ + INIT_ID(__iand__), \ + INIT_ID(__ifloordiv__), \ + INIT_ID(__ilshift__), \ + INIT_ID(__imatmul__), \ + INIT_ID(__imod__), \ + INIT_ID(__import__), \ + INIT_ID(__imul__), \ + INIT_ID(__index__), \ + INIT_ID(__init__), \ + INIT_ID(__init_subclass__), \ + INIT_ID(__instancecheck__), \ + INIT_ID(__int__), \ + INIT_ID(__invert__), \ + INIT_ID(__ior__), \ + INIT_ID(__ipow__), \ + INIT_ID(__irshift__), \ + INIT_ID(__isabstractmethod__), \ + INIT_ID(__isub__), \ + INIT_ID(__iter__), \ + INIT_ID(__itruediv__), \ + INIT_ID(__ixor__), \ + INIT_ID(__le__), \ + INIT_ID(__len__), \ + INIT_ID(__length_hint__), \ + INIT_ID(__lltrace__), \ + INIT_ID(__loader__), \ + INIT_ID(__lshift__), \ + INIT_ID(__lt__), \ + INIT_ID(__main__), \ + INIT_ID(__matmul__), \ + INIT_ID(__missing__), \ + INIT_ID(__mod__), \ + INIT_ID(__module__), \ + INIT_ID(__mro_entries__), \ + INIT_ID(__mul__), \ + INIT_ID(__name__), \ + INIT_ID(__ne__), \ + INIT_ID(__neg__), \ + INIT_ID(__new__), \ + INIT_ID(__newobj__), \ + INIT_ID(__newobj_ex__), \ + INIT_ID(__next__), \ + INIT_ID(__notes__), \ + INIT_ID(__or__), \ + INIT_ID(__orig_class__), \ + INIT_ID(__origin__), \ + INIT_ID(__package__), \ + INIT_ID(__parameters__), \ + INIT_ID(__path__), \ + INIT_ID(__pos__), \ + INIT_ID(__pow__), \ + INIT_ID(__prepare__), \ + INIT_ID(__qualname__), \ + INIT_ID(__radd__), \ + INIT_ID(__rand__), \ + INIT_ID(__rdivmod__), \ + INIT_ID(__reduce__), \ + INIT_ID(__reduce_ex__), \ + INIT_ID(__release_buffer__), \ + INIT_ID(__repr__), \ + INIT_ID(__reversed__), \ + INIT_ID(__rfloordiv__), \ + INIT_ID(__rlshift__), \ + INIT_ID(__rmatmul__), \ + INIT_ID(__rmod__), \ + INIT_ID(__rmul__), \ + INIT_ID(__ror__), \ + INIT_ID(__round__), \ + INIT_ID(__rpow__), \ + INIT_ID(__rrshift__), \ + INIT_ID(__rshift__), \ + INIT_ID(__rsub__), \ + INIT_ID(__rtruediv__), \ + INIT_ID(__rxor__), \ + INIT_ID(__set__), \ + INIT_ID(__set_name__), \ + INIT_ID(__setattr__), \ + INIT_ID(__setitem__), \ + INIT_ID(__setstate__), \ + INIT_ID(__sizeof__), \ + INIT_ID(__slotnames__), \ + INIT_ID(__slots__), \ + INIT_ID(__spec__), \ + INIT_ID(__str__), \ + INIT_ID(__sub__), \ + INIT_ID(__subclasscheck__), \ + INIT_ID(__subclasshook__), \ + INIT_ID(__truediv__), \ + INIT_ID(__trunc__), \ + INIT_ID(__type_params__), \ + INIT_ID(__typing_is_unpacked_typevartuple__), \ + INIT_ID(__typing_prepare_subst__), \ + INIT_ID(__typing_subst__), \ + INIT_ID(__typing_unpacked_tuple_args__), \ + INIT_ID(__warningregistry__), \ + INIT_ID(__weaklistoffset__), \ + INIT_ID(__weakref__), \ + INIT_ID(__xor__), \ + INIT_ID(_abc_impl), \ + INIT_ID(_abstract_), \ + INIT_ID(_active), \ + INIT_ID(_annotation), \ + INIT_ID(_anonymous_), \ + INIT_ID(_argtypes_), \ + INIT_ID(_as_parameter_), \ + INIT_ID(_asyncio_future_blocking), \ + INIT_ID(_blksize), \ + INIT_ID(_bootstrap), \ + INIT_ID(_check_retval_), \ + INIT_ID(_dealloc_warn), \ + INIT_ID(_feature_version), \ + INIT_ID(_fields_), \ + INIT_ID(_finalizing), \ + INIT_ID(_find_and_load), \ + INIT_ID(_fix_up_module), \ + INIT_ID(_flags_), \ + INIT_ID(_get_sourcefile), \ + INIT_ID(_handle_fromlist), \ + INIT_ID(_initializing), \ + INIT_ID(_io), \ + INIT_ID(_is_text_encoding), \ + INIT_ID(_length_), \ + INIT_ID(_limbo), \ + INIT_ID(_lock_unlock_module), \ + INIT_ID(_loop), \ + INIT_ID(_needs_com_addref_), \ + INIT_ID(_pack_), \ + INIT_ID(_restype_), \ + INIT_ID(_showwarnmsg), \ + INIT_ID(_shutdown), \ + INIT_ID(_slotnames), \ + INIT_ID(_strptime_datetime), \ + INIT_ID(_swappedbytes_), \ + INIT_ID(_type_), \ + INIT_ID(_uninitialized_submodules), \ + INIT_ID(_warn_unawaited_coroutine), \ + INIT_ID(_xoptions), \ + INIT_ID(a), \ + INIT_ID(abs_tol), \ + INIT_ID(access), \ + INIT_ID(add), \ + INIT_ID(add_done_callback), \ + INIT_ID(after_in_child), \ + INIT_ID(after_in_parent), \ + INIT_ID(aggregate_class), \ + INIT_ID(alias), \ + INIT_ID(append), \ + INIT_ID(arg), \ + INIT_ID(argdefs), \ + INIT_ID(args), \ + INIT_ID(arguments), \ + INIT_ID(argv), \ + INIT_ID(as_integer_ratio), \ + INIT_ID(ast), \ + INIT_ID(attribute), \ + INIT_ID(authorizer_callback), \ + INIT_ID(autocommit), \ + INIT_ID(b), \ + INIT_ID(backtick), \ + INIT_ID(base), \ + INIT_ID(before), \ + INIT_ID(big), \ + INIT_ID(binary_form), \ + INIT_ID(block), \ + INIT_ID(bound), \ + INIT_ID(buffer), \ + INIT_ID(buffer_callback), \ + INIT_ID(buffer_size), \ + INIT_ID(buffering), \ + INIT_ID(buffers), \ + INIT_ID(bufsize), \ + INIT_ID(builtins), \ + INIT_ID(byteorder), \ + INIT_ID(bytes), \ + INIT_ID(bytes_per_sep), \ + INIT_ID(c), \ + INIT_ID(c_call), \ + INIT_ID(c_exception), \ + INIT_ID(c_return), \ + INIT_ID(cached_statements), \ + INIT_ID(cadata), \ + INIT_ID(cafile), \ + INIT_ID(call), \ + INIT_ID(call_exception_handler), \ + INIT_ID(call_soon), \ + INIT_ID(cancel), \ + INIT_ID(capath), \ + INIT_ID(category), \ + INIT_ID(cb_type), \ + INIT_ID(certfile), \ + INIT_ID(check_same_thread), \ + INIT_ID(clear), \ + INIT_ID(close), \ + INIT_ID(closed), \ + INIT_ID(closefd), \ + INIT_ID(closure), \ + INIT_ID(co_argcount), \ + INIT_ID(co_cellvars), \ + INIT_ID(co_code), \ + INIT_ID(co_consts), \ + INIT_ID(co_exceptiontable), \ + INIT_ID(co_filename), \ + INIT_ID(co_firstlineno), \ + INIT_ID(co_flags), \ + INIT_ID(co_freevars), \ + INIT_ID(co_kwonlyargcount), \ + INIT_ID(co_linetable), \ + INIT_ID(co_name), \ + INIT_ID(co_names), \ + INIT_ID(co_nlocals), \ + INIT_ID(co_posonlyargcount), \ + INIT_ID(co_qualname), \ + INIT_ID(co_stacksize), \ + INIT_ID(co_varnames), \ + INIT_ID(code), \ + INIT_ID(command), \ + INIT_ID(comment_factory), \ + INIT_ID(compile_mode), \ + INIT_ID(consts), \ + INIT_ID(context), \ + INIT_ID(contravariant), \ + INIT_ID(cookie), \ + INIT_ID(copy), \ + INIT_ID(copyreg), \ + INIT_ID(coro), \ + INIT_ID(count), \ + INIT_ID(covariant), \ + INIT_ID(cwd), \ + INIT_ID(d), \ + INIT_ID(data), \ + INIT_ID(database), \ + INIT_ID(decode), \ + INIT_ID(decoder), \ + INIT_ID(default), \ + INIT_ID(defaultaction), \ + INIT_ID(delete), \ + INIT_ID(depth), \ + INIT_ID(detect_types), \ + INIT_ID(deterministic), \ + INIT_ID(device), \ + INIT_ID(dict), \ + INIT_ID(dictcomp), \ + INIT_ID(difference_update), \ + INIT_ID(digest), \ + INIT_ID(digest_size), \ + INIT_ID(digestmod), \ + INIT_ID(dir_fd), \ + INIT_ID(discard), \ + INIT_ID(dispatch_table), \ + INIT_ID(displayhook), \ + INIT_ID(dklen), \ + INIT_ID(doc), \ + INIT_ID(dont_inherit), \ + INIT_ID(dst), \ + INIT_ID(dst_dir_fd), \ + INIT_ID(duration), \ + INIT_ID(e), \ + INIT_ID(eager_start), \ + INIT_ID(effective_ids), \ + INIT_ID(element_factory), \ + INIT_ID(encode), \ + INIT_ID(encoding), \ + INIT_ID(end), \ + INIT_ID(end_lineno), \ + INIT_ID(end_offset), \ + INIT_ID(endpos), \ + INIT_ID(entrypoint), \ + INIT_ID(env), \ + INIT_ID(errors), \ + INIT_ID(event), \ + INIT_ID(eventmask), \ + INIT_ID(exc_type), \ + INIT_ID(exc_value), \ + INIT_ID(excepthook), \ + INIT_ID(exception), \ + INIT_ID(existing_file_name), \ + INIT_ID(exp), \ + INIT_ID(extend), \ + INIT_ID(extra_tokens), \ + INIT_ID(facility), \ + INIT_ID(factory), \ + INIT_ID(false), \ + INIT_ID(family), \ + INIT_ID(fanout), \ + INIT_ID(fd), \ + INIT_ID(fd2), \ + INIT_ID(fdel), \ + INIT_ID(fget), \ + INIT_ID(file), \ + INIT_ID(file_actions), \ + INIT_ID(filename), \ + INIT_ID(fileno), \ + INIT_ID(filepath), \ + INIT_ID(fillvalue), \ + INIT_ID(filters), \ + INIT_ID(final), \ + INIT_ID(find_class), \ + INIT_ID(fix_imports), \ + INIT_ID(flags), \ + INIT_ID(flush), \ + INIT_ID(follow_symlinks), \ + INIT_ID(format), \ + INIT_ID(frequency), \ + INIT_ID(from_param), \ + INIT_ID(fromlist), \ + INIT_ID(fromtimestamp), \ + INIT_ID(fromutc), \ + INIT_ID(fset), \ + INIT_ID(func), \ + INIT_ID(future), \ + INIT_ID(generation), \ + INIT_ID(genexpr), \ + INIT_ID(get), \ + INIT_ID(get_debug), \ + INIT_ID(get_event_loop), \ + INIT_ID(get_loop), \ + INIT_ID(get_source), \ + INIT_ID(getattr), \ + INIT_ID(getstate), \ + INIT_ID(gid), \ + INIT_ID(globals), \ + INIT_ID(groupindex), \ + INIT_ID(groups), \ + INIT_ID(handle), \ + INIT_ID(hash_name), \ + INIT_ID(header), \ + INIT_ID(headers), \ + INIT_ID(hi), \ + INIT_ID(hook), \ + INIT_ID(id), \ + INIT_ID(ident), \ + INIT_ID(ignore), \ + INIT_ID(imag), \ + INIT_ID(importlib), \ + INIT_ID(in_fd), \ + INIT_ID(incoming), \ + INIT_ID(indexgroup), \ + INIT_ID(inf), \ + INIT_ID(infer_variance), \ + INIT_ID(inheritable), \ + INIT_ID(initial), \ + INIT_ID(initial_bytes), \ + INIT_ID(initial_value), \ + INIT_ID(initval), \ + INIT_ID(inner_size), \ + INIT_ID(input), \ + INIT_ID(insert_comments), \ + INIT_ID(insert_pis), \ + INIT_ID(instructions), \ + INIT_ID(intern), \ + INIT_ID(intersection), \ + INIT_ID(is_running), \ + INIT_ID(isatty), \ + INIT_ID(isinstance), \ + INIT_ID(isoformat), \ + INIT_ID(isolation_level), \ + INIT_ID(istext), \ + INIT_ID(item), \ + INIT_ID(items), \ + INIT_ID(iter), \ + INIT_ID(iterable), \ + INIT_ID(iterations), \ + INIT_ID(join), \ + INIT_ID(jump), \ + INIT_ID(keepends), \ + INIT_ID(key), \ + INIT_ID(keyfile), \ + INIT_ID(keys), \ + INIT_ID(kind), \ + INIT_ID(kw), \ + INIT_ID(kw1), \ + INIT_ID(kw2), \ + INIT_ID(lambda), \ + INIT_ID(last), \ + INIT_ID(last_exc), \ + INIT_ID(last_node), \ + INIT_ID(last_traceback), \ + INIT_ID(last_type), \ + INIT_ID(last_value), \ + INIT_ID(latin1), \ + INIT_ID(leaf_size), \ + INIT_ID(len), \ + INIT_ID(length), \ + INIT_ID(level), \ + INIT_ID(limit), \ + INIT_ID(line), \ + INIT_ID(line_buffering), \ + INIT_ID(lineno), \ + INIT_ID(listcomp), \ + INIT_ID(little), \ + INIT_ID(lo), \ + INIT_ID(locale), \ + INIT_ID(locals), \ + INIT_ID(logoption), \ + INIT_ID(loop), \ + INIT_ID(mapping), \ + INIT_ID(match), \ + INIT_ID(max_length), \ + INIT_ID(maxdigits), \ + INIT_ID(maxevents), \ + INIT_ID(maxmem), \ + INIT_ID(maxsplit), \ + INIT_ID(maxvalue), \ + INIT_ID(memLevel), \ + INIT_ID(memlimit), \ + INIT_ID(message), \ + INIT_ID(metaclass), \ + INIT_ID(metadata), \ + INIT_ID(method), \ + INIT_ID(mod), \ + INIT_ID(mode), \ + INIT_ID(module), \ + INIT_ID(module_globals), \ + INIT_ID(modules), \ + INIT_ID(mro), \ + INIT_ID(msg), \ + INIT_ID(mycmp), \ + INIT_ID(n), \ + INIT_ID(n_arg), \ + INIT_ID(n_fields), \ + INIT_ID(n_sequence_fields), \ + INIT_ID(n_unnamed_fields), \ + INIT_ID(name), \ + INIT_ID(name_from), \ + INIT_ID(namespace_separator), \ + INIT_ID(namespaces), \ + INIT_ID(narg), \ + INIT_ID(ndigits), \ + INIT_ID(new_file_name), \ + INIT_ID(new_limit), \ + INIT_ID(newline), \ + INIT_ID(newlines), \ + INIT_ID(next), \ + INIT_ID(nlocals), \ + INIT_ID(node_depth), \ + INIT_ID(node_offset), \ + INIT_ID(ns), \ + INIT_ID(nstype), \ + INIT_ID(nt), \ + INIT_ID(null), \ + INIT_ID(number), \ + INIT_ID(obj), \ + INIT_ID(object), \ + INIT_ID(offset), \ + INIT_ID(offset_dst), \ + INIT_ID(offset_src), \ + INIT_ID(on_type_read), \ + INIT_ID(onceregistry), \ + INIT_ID(only_keys), \ + INIT_ID(oparg), \ + INIT_ID(opcode), \ + INIT_ID(open), \ + INIT_ID(opener), \ + INIT_ID(operation), \ + INIT_ID(optimize), \ + INIT_ID(options), \ + INIT_ID(order), \ + INIT_ID(origin), \ + INIT_ID(out_fd), \ + INIT_ID(outgoing), \ + INIT_ID(overlapped), \ + INIT_ID(owner), \ + INIT_ID(p), \ + INIT_ID(pages), \ + INIT_ID(parent), \ + INIT_ID(password), \ + INIT_ID(path), \ + INIT_ID(pattern), \ + INIT_ID(peek), \ + INIT_ID(persistent_id), \ + INIT_ID(persistent_load), \ + INIT_ID(person), \ + INIT_ID(pi_factory), \ + INIT_ID(pid), \ + INIT_ID(policy), \ + INIT_ID(pos), \ + INIT_ID(pos1), \ + INIT_ID(pos2), \ + INIT_ID(posix), \ + INIT_ID(print_file_and_line), \ + INIT_ID(priority), \ + INIT_ID(progress), \ + INIT_ID(progress_handler), \ + INIT_ID(progress_routine), \ + INIT_ID(proto), \ + INIT_ID(protocol), \ + INIT_ID(ps1), \ + INIT_ID(ps2), \ + INIT_ID(query), \ + INIT_ID(quotetabs), \ + INIT_ID(r), \ + INIT_ID(raw), \ + INIT_ID(read), \ + INIT_ID(read1), \ + INIT_ID(readable), \ + INIT_ID(readall), \ + INIT_ID(readinto), \ + INIT_ID(readinto1), \ + INIT_ID(readline), \ + INIT_ID(readonly), \ + INIT_ID(real), \ + INIT_ID(reducer_override), \ + INIT_ID(registry), \ + INIT_ID(rel_tol), \ + INIT_ID(release), \ + INIT_ID(reload), \ + INIT_ID(repl), \ + INIT_ID(replace), \ + INIT_ID(reserved), \ + INIT_ID(reset), \ + INIT_ID(resetids), \ + INIT_ID(return), \ + INIT_ID(reverse), \ + INIT_ID(reversed), \ + INIT_ID(s), \ + INIT_ID(salt), \ + INIT_ID(sched_priority), \ + INIT_ID(scheduler), \ + INIT_ID(seek), \ + INIT_ID(seekable), \ + INIT_ID(selectors), \ + INIT_ID(self), \ + INIT_ID(send), \ + INIT_ID(sep), \ + INIT_ID(sequence), \ + INIT_ID(server_hostname), \ + INIT_ID(server_side), \ + INIT_ID(session), \ + INIT_ID(setcomp), \ + INIT_ID(setpgroup), \ + INIT_ID(setsid), \ + INIT_ID(setsigdef), \ + INIT_ID(setsigmask), \ + INIT_ID(setstate), \ + INIT_ID(shape), \ + INIT_ID(show_cmd), \ + INIT_ID(signed), \ + INIT_ID(size), \ + INIT_ID(sizehint), \ + INIT_ID(skip_file_prefixes), \ + INIT_ID(sleep), \ + INIT_ID(sock), \ + INIT_ID(sort), \ + INIT_ID(sound), \ + INIT_ID(source), \ + INIT_ID(source_traceback), \ + INIT_ID(src), \ + INIT_ID(src_dir_fd), \ + INIT_ID(stacklevel), \ + INIT_ID(start), \ + INIT_ID(statement), \ + INIT_ID(status), \ + INIT_ID(stderr), \ + INIT_ID(stdin), \ + INIT_ID(stdout), \ + INIT_ID(step), \ + INIT_ID(steps), \ + INIT_ID(store_name), \ + INIT_ID(strategy), \ + INIT_ID(strftime), \ + INIT_ID(strict), \ + INIT_ID(strict_mode), \ + INIT_ID(string), \ + INIT_ID(sub_key), \ + INIT_ID(symmetric_difference_update), \ + INIT_ID(tabsize), \ + INIT_ID(tag), \ + INIT_ID(target), \ + INIT_ID(target_is_directory), \ + INIT_ID(task), \ + INIT_ID(tb_frame), \ + INIT_ID(tb_lasti), \ + INIT_ID(tb_lineno), \ + INIT_ID(tb_next), \ + INIT_ID(tell), \ + INIT_ID(template), \ + INIT_ID(term), \ + INIT_ID(text), \ + INIT_ID(threading), \ + INIT_ID(throw), \ + INIT_ID(timeout), \ + INIT_ID(times), \ + INIT_ID(timetuple), \ + INIT_ID(top), \ + INIT_ID(trace_callback), \ + INIT_ID(traceback), \ + INIT_ID(trailers), \ + INIT_ID(translate), \ + INIT_ID(true), \ + INIT_ID(truncate), \ + INIT_ID(twice), \ + INIT_ID(txt), \ + INIT_ID(type), \ + INIT_ID(type_params), \ + INIT_ID(tz), \ + INIT_ID(tzname), \ + INIT_ID(uid), \ + INIT_ID(unlink), \ + INIT_ID(unraisablehook), \ + INIT_ID(uri), \ + INIT_ID(usedforsecurity), \ + INIT_ID(value), \ + INIT_ID(values), \ + INIT_ID(version), \ + INIT_ID(volume), \ + INIT_ID(warnings), \ + INIT_ID(warnoptions), \ + INIT_ID(wbits), \ + INIT_ID(week), \ + INIT_ID(weekday), \ + INIT_ID(which), \ + INIT_ID(who), \ + INIT_ID(withdata), \ + INIT_ID(writable), \ + INIT_ID(write), \ + INIT_ID(write_through), \ + INIT_ID(x), \ + INIT_ID(year), \ + INIT_ID(zdict), \ +} + +#define _Py_str_ascii_INIT { \ + _PyASCIIObject_INIT("\x00"), \ + _PyASCIIObject_INIT("\x01"), \ + _PyASCIIObject_INIT("\x02"), \ + _PyASCIIObject_INIT("\x03"), \ + _PyASCIIObject_INIT("\x04"), \ + _PyASCIIObject_INIT("\x05"), \ + _PyASCIIObject_INIT("\x06"), \ + _PyASCIIObject_INIT("\x07"), \ + _PyASCIIObject_INIT("\x08"), \ + _PyASCIIObject_INIT("\x09"), \ + _PyASCIIObject_INIT("\x0a"), \ + _PyASCIIObject_INIT("\x0b"), \ + _PyASCIIObject_INIT("\x0c"), \ + _PyASCIIObject_INIT("\x0d"), \ + _PyASCIIObject_INIT("\x0e"), \ + _PyASCIIObject_INIT("\x0f"), \ + _PyASCIIObject_INIT("\x10"), \ + _PyASCIIObject_INIT("\x11"), \ + _PyASCIIObject_INIT("\x12"), \ + _PyASCIIObject_INIT("\x13"), \ + _PyASCIIObject_INIT("\x14"), \ + _PyASCIIObject_INIT("\x15"), \ + _PyASCIIObject_INIT("\x16"), \ + _PyASCIIObject_INIT("\x17"), \ + _PyASCIIObject_INIT("\x18"), \ + _PyASCIIObject_INIT("\x19"), \ + _PyASCIIObject_INIT("\x1a"), \ + _PyASCIIObject_INIT("\x1b"), \ + _PyASCIIObject_INIT("\x1c"), \ + _PyASCIIObject_INIT("\x1d"), \ + _PyASCIIObject_INIT("\x1e"), \ + _PyASCIIObject_INIT("\x1f"), \ + _PyASCIIObject_INIT("\x20"), \ + _PyASCIIObject_INIT("\x21"), \ + _PyASCIIObject_INIT("\x22"), \ + _PyASCIIObject_INIT("\x23"), \ + _PyASCIIObject_INIT("\x24"), \ + _PyASCIIObject_INIT("\x25"), \ + _PyASCIIObject_INIT("\x26"), \ + _PyASCIIObject_INIT("\x27"), \ + _PyASCIIObject_INIT("\x28"), \ + _PyASCIIObject_INIT("\x29"), \ + _PyASCIIObject_INIT("\x2a"), \ + _PyASCIIObject_INIT("\x2b"), \ + _PyASCIIObject_INIT("\x2c"), \ + _PyASCIIObject_INIT("\x2d"), \ + _PyASCIIObject_INIT("\x2e"), \ + _PyASCIIObject_INIT("\x2f"), \ + _PyASCIIObject_INIT("\x30"), \ + _PyASCIIObject_INIT("\x31"), \ + _PyASCIIObject_INIT("\x32"), \ + _PyASCIIObject_INIT("\x33"), \ + _PyASCIIObject_INIT("\x34"), \ + _PyASCIIObject_INIT("\x35"), \ + _PyASCIIObject_INIT("\x36"), \ + _PyASCIIObject_INIT("\x37"), \ + _PyASCIIObject_INIT("\x38"), \ + _PyASCIIObject_INIT("\x39"), \ + _PyASCIIObject_INIT("\x3a"), \ + _PyASCIIObject_INIT("\x3b"), \ + _PyASCIIObject_INIT("\x3c"), \ + _PyASCIIObject_INIT("\x3d"), \ + _PyASCIIObject_INIT("\x3e"), \ + _PyASCIIObject_INIT("\x3f"), \ + _PyASCIIObject_INIT("\x40"), \ + _PyASCIIObject_INIT("\x41"), \ + _PyASCIIObject_INIT("\x42"), \ + _PyASCIIObject_INIT("\x43"), \ + _PyASCIIObject_INIT("\x44"), \ + _PyASCIIObject_INIT("\x45"), \ + _PyASCIIObject_INIT("\x46"), \ + _PyASCIIObject_INIT("\x47"), \ + _PyASCIIObject_INIT("\x48"), \ + _PyASCIIObject_INIT("\x49"), \ + _PyASCIIObject_INIT("\x4a"), \ + _PyASCIIObject_INIT("\x4b"), \ + _PyASCIIObject_INIT("\x4c"), \ + _PyASCIIObject_INIT("\x4d"), \ + _PyASCIIObject_INIT("\x4e"), \ + _PyASCIIObject_INIT("\x4f"), \ + _PyASCIIObject_INIT("\x50"), \ + _PyASCIIObject_INIT("\x51"), \ + _PyASCIIObject_INIT("\x52"), \ + _PyASCIIObject_INIT("\x53"), \ + _PyASCIIObject_INIT("\x54"), \ + _PyASCIIObject_INIT("\x55"), \ + _PyASCIIObject_INIT("\x56"), \ + _PyASCIIObject_INIT("\x57"), \ + _PyASCIIObject_INIT("\x58"), \ + _PyASCIIObject_INIT("\x59"), \ + _PyASCIIObject_INIT("\x5a"), \ + _PyASCIIObject_INIT("\x5b"), \ + _PyASCIIObject_INIT("\x5c"), \ + _PyASCIIObject_INIT("\x5d"), \ + _PyASCIIObject_INIT("\x5e"), \ + _PyASCIIObject_INIT("\x5f"), \ + _PyASCIIObject_INIT("\x60"), \ + _PyASCIIObject_INIT("\x61"), \ + _PyASCIIObject_INIT("\x62"), \ + _PyASCIIObject_INIT("\x63"), \ + _PyASCIIObject_INIT("\x64"), \ + _PyASCIIObject_INIT("\x65"), \ + _PyASCIIObject_INIT("\x66"), \ + _PyASCIIObject_INIT("\x67"), \ + _PyASCIIObject_INIT("\x68"), \ + _PyASCIIObject_INIT("\x69"), \ + _PyASCIIObject_INIT("\x6a"), \ + _PyASCIIObject_INIT("\x6b"), \ + _PyASCIIObject_INIT("\x6c"), \ + _PyASCIIObject_INIT("\x6d"), \ + _PyASCIIObject_INIT("\x6e"), \ + _PyASCIIObject_INIT("\x6f"), \ + _PyASCIIObject_INIT("\x70"), \ + _PyASCIIObject_INIT("\x71"), \ + _PyASCIIObject_INIT("\x72"), \ + _PyASCIIObject_INIT("\x73"), \ + _PyASCIIObject_INIT("\x74"), \ + _PyASCIIObject_INIT("\x75"), \ + _PyASCIIObject_INIT("\x76"), \ + _PyASCIIObject_INIT("\x77"), \ + _PyASCIIObject_INIT("\x78"), \ + _PyASCIIObject_INIT("\x79"), \ + _PyASCIIObject_INIT("\x7a"), \ + _PyASCIIObject_INIT("\x7b"), \ + _PyASCIIObject_INIT("\x7c"), \ + _PyASCIIObject_INIT("\x7d"), \ + _PyASCIIObject_INIT("\x7e"), \ + _PyASCIIObject_INIT("\x7f"), \ +} + +#define _Py_str_latin1_INIT { \ + _PyUnicode_LATIN1_INIT("\x80", "\xc2\x80"), \ + _PyUnicode_LATIN1_INIT("\x81", "\xc2\x81"), \ + _PyUnicode_LATIN1_INIT("\x82", "\xc2\x82"), \ + _PyUnicode_LATIN1_INIT("\x83", "\xc2\x83"), \ + _PyUnicode_LATIN1_INIT("\x84", "\xc2\x84"), \ + _PyUnicode_LATIN1_INIT("\x85", "\xc2\x85"), \ + _PyUnicode_LATIN1_INIT("\x86", "\xc2\x86"), \ + _PyUnicode_LATIN1_INIT("\x87", "\xc2\x87"), \ + _PyUnicode_LATIN1_INIT("\x88", "\xc2\x88"), \ + _PyUnicode_LATIN1_INIT("\x89", "\xc2\x89"), \ + _PyUnicode_LATIN1_INIT("\x8a", "\xc2\x8a"), \ + _PyUnicode_LATIN1_INIT("\x8b", "\xc2\x8b"), \ + _PyUnicode_LATIN1_INIT("\x8c", "\xc2\x8c"), \ + _PyUnicode_LATIN1_INIT("\x8d", "\xc2\x8d"), \ + _PyUnicode_LATIN1_INIT("\x8e", "\xc2\x8e"), \ + _PyUnicode_LATIN1_INIT("\x8f", "\xc2\x8f"), \ + _PyUnicode_LATIN1_INIT("\x90", "\xc2\x90"), \ + _PyUnicode_LATIN1_INIT("\x91", "\xc2\x91"), \ + _PyUnicode_LATIN1_INIT("\x92", "\xc2\x92"), \ + _PyUnicode_LATIN1_INIT("\x93", "\xc2\x93"), \ + _PyUnicode_LATIN1_INIT("\x94", "\xc2\x94"), \ + _PyUnicode_LATIN1_INIT("\x95", "\xc2\x95"), \ + _PyUnicode_LATIN1_INIT("\x96", "\xc2\x96"), \ + _PyUnicode_LATIN1_INIT("\x97", "\xc2\x97"), \ + _PyUnicode_LATIN1_INIT("\x98", "\xc2\x98"), \ + _PyUnicode_LATIN1_INIT("\x99", "\xc2\x99"), \ + _PyUnicode_LATIN1_INIT("\x9a", "\xc2\x9a"), \ + _PyUnicode_LATIN1_INIT("\x9b", "\xc2\x9b"), \ + _PyUnicode_LATIN1_INIT("\x9c", "\xc2\x9c"), \ + _PyUnicode_LATIN1_INIT("\x9d", "\xc2\x9d"), \ + _PyUnicode_LATIN1_INIT("\x9e", "\xc2\x9e"), \ + _PyUnicode_LATIN1_INIT("\x9f", "\xc2\x9f"), \ + _PyUnicode_LATIN1_INIT("\xa0", "\xc2\xa0"), \ + _PyUnicode_LATIN1_INIT("\xa1", "\xc2\xa1"), \ + _PyUnicode_LATIN1_INIT("\xa2", "\xc2\xa2"), \ + _PyUnicode_LATIN1_INIT("\xa3", "\xc2\xa3"), \ + _PyUnicode_LATIN1_INIT("\xa4", "\xc2\xa4"), \ + _PyUnicode_LATIN1_INIT("\xa5", "\xc2\xa5"), \ + _PyUnicode_LATIN1_INIT("\xa6", "\xc2\xa6"), \ + _PyUnicode_LATIN1_INIT("\xa7", "\xc2\xa7"), \ + _PyUnicode_LATIN1_INIT("\xa8", "\xc2\xa8"), \ + _PyUnicode_LATIN1_INIT("\xa9", "\xc2\xa9"), \ + _PyUnicode_LATIN1_INIT("\xaa", "\xc2\xaa"), \ + _PyUnicode_LATIN1_INIT("\xab", "\xc2\xab"), \ + _PyUnicode_LATIN1_INIT("\xac", "\xc2\xac"), \ + _PyUnicode_LATIN1_INIT("\xad", "\xc2\xad"), \ + _PyUnicode_LATIN1_INIT("\xae", "\xc2\xae"), \ + _PyUnicode_LATIN1_INIT("\xaf", "\xc2\xaf"), \ + _PyUnicode_LATIN1_INIT("\xb0", "\xc2\xb0"), \ + _PyUnicode_LATIN1_INIT("\xb1", "\xc2\xb1"), \ + _PyUnicode_LATIN1_INIT("\xb2", "\xc2\xb2"), \ + _PyUnicode_LATIN1_INIT("\xb3", "\xc2\xb3"), \ + _PyUnicode_LATIN1_INIT("\xb4", "\xc2\xb4"), \ + _PyUnicode_LATIN1_INIT("\xb5", "\xc2\xb5"), \ + _PyUnicode_LATIN1_INIT("\xb6", "\xc2\xb6"), \ + _PyUnicode_LATIN1_INIT("\xb7", "\xc2\xb7"), \ + _PyUnicode_LATIN1_INIT("\xb8", "\xc2\xb8"), \ + _PyUnicode_LATIN1_INIT("\xb9", "\xc2\xb9"), \ + _PyUnicode_LATIN1_INIT("\xba", "\xc2\xba"), \ + _PyUnicode_LATIN1_INIT("\xbb", "\xc2\xbb"), \ + _PyUnicode_LATIN1_INIT("\xbc", "\xc2\xbc"), \ + _PyUnicode_LATIN1_INIT("\xbd", "\xc2\xbd"), \ + _PyUnicode_LATIN1_INIT("\xbe", "\xc2\xbe"), \ + _PyUnicode_LATIN1_INIT("\xbf", "\xc2\xbf"), \ + _PyUnicode_LATIN1_INIT("\xc0", "\xc3\x80"), \ + _PyUnicode_LATIN1_INIT("\xc1", "\xc3\x81"), \ + _PyUnicode_LATIN1_INIT("\xc2", "\xc3\x82"), \ + _PyUnicode_LATIN1_INIT("\xc3", "\xc3\x83"), \ + _PyUnicode_LATIN1_INIT("\xc4", "\xc3\x84"), \ + _PyUnicode_LATIN1_INIT("\xc5", "\xc3\x85"), \ + _PyUnicode_LATIN1_INIT("\xc6", "\xc3\x86"), \ + _PyUnicode_LATIN1_INIT("\xc7", "\xc3\x87"), \ + _PyUnicode_LATIN1_INIT("\xc8", "\xc3\x88"), \ + _PyUnicode_LATIN1_INIT("\xc9", "\xc3\x89"), \ + _PyUnicode_LATIN1_INIT("\xca", "\xc3\x8a"), \ + _PyUnicode_LATIN1_INIT("\xcb", "\xc3\x8b"), \ + _PyUnicode_LATIN1_INIT("\xcc", "\xc3\x8c"), \ + _PyUnicode_LATIN1_INIT("\xcd", "\xc3\x8d"), \ + _PyUnicode_LATIN1_INIT("\xce", "\xc3\x8e"), \ + _PyUnicode_LATIN1_INIT("\xcf", "\xc3\x8f"), \ + _PyUnicode_LATIN1_INIT("\xd0", "\xc3\x90"), \ + _PyUnicode_LATIN1_INIT("\xd1", "\xc3\x91"), \ + _PyUnicode_LATIN1_INIT("\xd2", "\xc3\x92"), \ + _PyUnicode_LATIN1_INIT("\xd3", "\xc3\x93"), \ + _PyUnicode_LATIN1_INIT("\xd4", "\xc3\x94"), \ + _PyUnicode_LATIN1_INIT("\xd5", "\xc3\x95"), \ + _PyUnicode_LATIN1_INIT("\xd6", "\xc3\x96"), \ + _PyUnicode_LATIN1_INIT("\xd7", "\xc3\x97"), \ + _PyUnicode_LATIN1_INIT("\xd8", "\xc3\x98"), \ + _PyUnicode_LATIN1_INIT("\xd9", "\xc3\x99"), \ + _PyUnicode_LATIN1_INIT("\xda", "\xc3\x9a"), \ + _PyUnicode_LATIN1_INIT("\xdb", "\xc3\x9b"), \ + _PyUnicode_LATIN1_INIT("\xdc", "\xc3\x9c"), \ + _PyUnicode_LATIN1_INIT("\xdd", "\xc3\x9d"), \ + _PyUnicode_LATIN1_INIT("\xde", "\xc3\x9e"), \ + _PyUnicode_LATIN1_INIT("\xdf", "\xc3\x9f"), \ + _PyUnicode_LATIN1_INIT("\xe0", "\xc3\xa0"), \ + _PyUnicode_LATIN1_INIT("\xe1", "\xc3\xa1"), \ + _PyUnicode_LATIN1_INIT("\xe2", "\xc3\xa2"), \ + _PyUnicode_LATIN1_INIT("\xe3", "\xc3\xa3"), \ + _PyUnicode_LATIN1_INIT("\xe4", "\xc3\xa4"), \ + _PyUnicode_LATIN1_INIT("\xe5", "\xc3\xa5"), \ + _PyUnicode_LATIN1_INIT("\xe6", "\xc3\xa6"), \ + _PyUnicode_LATIN1_INIT("\xe7", "\xc3\xa7"), \ + _PyUnicode_LATIN1_INIT("\xe8", "\xc3\xa8"), \ + _PyUnicode_LATIN1_INIT("\xe9", "\xc3\xa9"), \ + _PyUnicode_LATIN1_INIT("\xea", "\xc3\xaa"), \ + _PyUnicode_LATIN1_INIT("\xeb", "\xc3\xab"), \ + _PyUnicode_LATIN1_INIT("\xec", "\xc3\xac"), \ + _PyUnicode_LATIN1_INIT("\xed", "\xc3\xad"), \ + _PyUnicode_LATIN1_INIT("\xee", "\xc3\xae"), \ + _PyUnicode_LATIN1_INIT("\xef", "\xc3\xaf"), \ + _PyUnicode_LATIN1_INIT("\xf0", "\xc3\xb0"), \ + _PyUnicode_LATIN1_INIT("\xf1", "\xc3\xb1"), \ + _PyUnicode_LATIN1_INIT("\xf2", "\xc3\xb2"), \ + _PyUnicode_LATIN1_INIT("\xf3", "\xc3\xb3"), \ + _PyUnicode_LATIN1_INIT("\xf4", "\xc3\xb4"), \ + _PyUnicode_LATIN1_INIT("\xf5", "\xc3\xb5"), \ + _PyUnicode_LATIN1_INIT("\xf6", "\xc3\xb6"), \ + _PyUnicode_LATIN1_INIT("\xf7", "\xc3\xb7"), \ + _PyUnicode_LATIN1_INIT("\xf8", "\xc3\xb8"), \ + _PyUnicode_LATIN1_INIT("\xf9", "\xc3\xb9"), \ + _PyUnicode_LATIN1_INIT("\xfa", "\xc3\xba"), \ + _PyUnicode_LATIN1_INIT("\xfb", "\xc3\xbb"), \ + _PyUnicode_LATIN1_INIT("\xfc", "\xc3\xbc"), \ + _PyUnicode_LATIN1_INIT("\xfd", "\xc3\xbd"), \ + _PyUnicode_LATIN1_INIT("\xfe", "\xc3\xbe"), \ + _PyUnicode_LATIN1_INIT("\xff", "\xc3\xbf"), \ +} +/* End auto-generated code */ + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_RUNTIME_INIT_GENERATED_H */ diff --git a/Include/internal/pycore_signal.h b/Include/internal/pycore_signal.h index b921dd17..ca3f69d0 100644 --- a/Include/internal/pycore_signal.h +++ b/Include/internal/pycore_signal.h @@ -10,8 +10,11 @@ extern "C" { # error "this header requires Py_BUILD_CORE define" #endif +#include "pycore_atomic.h" // _Py_atomic_address + #include <signal.h> // NSIG + #ifdef _SIG_MAXSIG // gh-91145: On FreeBSD, <signal.h> defines NSIG as 32: it doesn't include // realtime signals: [SIGRTMIN,SIGRTMAX]. Use _SIG_MAXSIG instead. For @@ -29,6 +32,66 @@ extern "C" { # define Py_NSIG 64 // Use a reasonable default value #endif +#define INVALID_FD (-1) + +struct _signals_runtime_state { + volatile struct { + _Py_atomic_int tripped; + /* func is atomic to ensure that PyErr_SetInterrupt is async-signal-safe + * (even though it would probably be otherwise, anyway). + */ + _Py_atomic_address func; + } handlers[Py_NSIG]; + + volatile struct { +#ifdef MS_WINDOWS + /* This would be "SOCKET fd" if <winsock2.h> were always included. + It isn't so we must cast to SOCKET where appropriate. */ + volatile int fd; +#elif defined(__VXWORKS__) + int fd; +#else + sig_atomic_t fd; +#endif + + int warn_on_full_buffer; +#ifdef MS_WINDOWS + int use_send; +#endif + } wakeup; + + /* Speed up sigcheck() when none tripped */ + _Py_atomic_int is_tripped; + + /* These objects necessarily belong to the main interpreter. */ + PyObject *default_handler; + PyObject *ignore_handler; + +#ifdef MS_WINDOWS + /* This would be "HANDLE sigint_event" if <windows.h> were always included. + It isn't so we must cast to HANDLE everywhere "sigint_event" is used. */ + void *sigint_event; +#endif + + /* True if the main interpreter thread exited due to an unhandled + * KeyboardInterrupt exception, suggesting the user pressed ^C. */ + int unhandled_keyboard_interrupt; +}; + +#ifdef MS_WINDOWS +# define _signals_WAKEUP_INIT \ + {.fd = INVALID_FD, .warn_on_full_buffer = 1, .use_send = 0} +#else +# define _signals_WAKEUP_INIT \ + {.fd = INVALID_FD, .warn_on_full_buffer = 1} +#endif + +#define _signals_RUNTIME_INIT \ + { \ + .wakeup = _signals_WAKEUP_INIT, \ + } + + #ifdef __cplusplus } #endif diff --git a/Include/internal/pycore_sliceobject.h b/Include/internal/pycore_sliceobject.h index e81834c0..98665c38 100644 --- a/Include/internal/pycore_sliceobject.h +++ b/Include/internal/pycore_sliceobject.h @@ -13,6 +13,8 @@ extern "C" { extern void _PySlice_Fini(PyInterpreterState *); +extern PyObject * +_PyBuildSlice_ConsumeRefs(PyObject *start, PyObject *stop); #ifdef __cplusplus } diff --git a/Include/internal/pycore_structseq.h b/Include/internal/pycore_structseq.h index 0199c790..6f5dfc12 100644 --- a/Include/internal/pycore_structseq.h +++ b/Include/internal/pycore_structseq.h @@ -15,12 +15,23 @@ PyAPI_FUNC(PyTypeObject *) _PyStructSequence_NewType( PyStructSequence_Desc *desc, unsigned long tp_flags); -PyAPI_FUNC(int) _PyStructSequence_InitType( +extern int _PyStructSequence_InitBuiltinWithFlags( + PyInterpreterState *interp, PyTypeObject *type, PyStructSequence_Desc *desc, unsigned long tp_flags); -extern void _PyStructSequence_FiniType(PyTypeObject *type); +static inline int +_PyStructSequence_InitBuiltin(PyInterpreterState *interp, + PyTypeObject *type, + PyStructSequence_Desc *desc) +{ + return _PyStructSequence_InitBuiltinWithFlags(interp, type, desc, 0); +} + +extern void _PyStructSequence_FiniBuiltin( + PyInterpreterState *interp, + PyTypeObject *type); #ifdef __cplusplus } diff --git a/Include/internal/pycore_symtable.h b/Include/internal/pycore_symtable.h index 28935f4e..c8e0578a 100644 --- a/Include/internal/pycore_symtable.h +++ b/Include/internal/pycore_symtable.h @@ -10,8 +10,17 @@ extern "C" { struct _mod; // Type defined in pycore_ast.h -typedef enum _block_type { FunctionBlock, ClassBlock, ModuleBlock, AnnotationBlock } - _Py_block_ty; +typedef enum _block_type { + FunctionBlock, ClassBlock, ModuleBlock, + // Used for annotations if 'from __future__ import annotations' is active. + // Annotation blocks cannot bind names and are not evaluated. + AnnotationBlock, + // Used for generics and type aliases. These work mostly like functions + // (see PEP 695 for details). The three different blocks function identically; + // they are different enum entries only so that error messages can be more + // precise. + TypeVarBoundBlock, TypeAliasBlock, TypeParamBlock +} _Py_block_ty; typedef enum _comprehension_type { NoComprehension = 0, @@ -49,7 +58,7 @@ typedef struct _symtable_entry { PyObject *ste_varnames; /* list of function parameters */ PyObject *ste_children; /* list of child blocks */ PyObject *ste_directives;/* locations of global and nonlocal statements */ - _Py_block_ty ste_type; /* module, class or function */ + _Py_block_ty ste_type; int ste_nested; /* true if block is nested */ unsigned ste_free : 1; /* true if block has free variables */ unsigned ste_child_free : 1; /* true if a child block has free vars, @@ -64,7 +73,12 @@ typedef struct _symtable_entry { unsigned ste_needs_class_closure : 1; /* for class scopes, true if a closure over __class__ should be created */ + unsigned ste_needs_classdict : 1; /* for class scopes, true if a closure + over the class dict should be created */ + unsigned ste_comp_inlined : 1; /* true if this comprehension is inlined */ unsigned ste_comp_iter_target : 1; /* true if visiting comprehension target */ + unsigned ste_can_see_class_scope : 1; /* true if this block can see names bound in an + enclosing class scope */ int ste_comp_iter_expr; /* non-zero if visiting a comprehension range expression */ int ste_lineno; /* first line of block */ int ste_col_offset; /* offset of first line of block */ @@ -77,10 +91,11 @@ typedef struct _symtable_entry { extern PyTypeObject PySTEntry_Type; -#define PySTEntry_Check(op) Py_IS_TYPE(op, &PySTEntry_Type) +#define PySTEntry_Check(op) Py_IS_TYPE((op), &PySTEntry_Type) extern long _PyST_GetSymbol(PySTEntryObject *, PyObject *); extern int _PyST_GetScope(PySTEntryObject *, PyObject *); +extern int _PyST_IsFunctionLike(PySTEntryObject *); extern struct symtable* _PySymtable_Build( struct _mod *mod, @@ -90,6 +105,8 @@ PyAPI_FUNC(PySTEntryObject *) PySymtable_Lookup(struct symtable *, void *); extern void _PySymtable_Free(struct symtable *); +extern PyObject* _Py_Mangle(PyObject *p, PyObject *name); + /* Flags for def-use information */ #define DEF_GLOBAL 1 /* global stmt */ @@ -102,14 +119,16 @@ extern void _PySymtable_Free(struct symtable *); #define DEF_IMPORT 2<<6 /* assignment occurred via import */ #define DEF_ANNOT 2<<7 /* this name is annotated */ #define DEF_COMP_ITER 2<<8 /* this name is a comprehension iteration variable */ +#define DEF_TYPE_PARAM 2<<9 /* this name is a type parameter */ +#define DEF_COMP_CELL 2<<10 /* this name is a cell in an inlined comprehension */ #define DEF_BOUND (DEF_LOCAL | DEF_PARAM | DEF_IMPORT) /* GLOBAL_EXPLICIT and GLOBAL_IMPLICIT are used internally by the symbol table. GLOBAL is returned from PyST_GetScope() for either of them. - It is stored in ste_symbols at bits 12-15. + It is stored in ste_symbols at bits 13-16. */ -#define SCOPE_OFFSET 11 +#define SCOPE_OFFSET 12 #define SCOPE_MASK (DEF_GLOBAL | DEF_LOCAL | DEF_PARAM | DEF_NONLOCAL) #define LOCAL 1 @@ -128,6 +147,11 @@ extern struct symtable* _Py_SymtableStringObjectFlags( int start, PyCompilerFlags *flags); +int _PyFuture_FromAST( + struct _mod * mod, + PyObject *filename, + PyFutureFeatures* futures); + #ifdef __cplusplus } #endif diff --git a/Include/internal/pycore_sysmodule.h b/Include/internal/pycore_sysmodule.h index 10d092cd..b4b1feba 100644 --- a/Include/internal/pycore_sysmodule.h +++ b/Include/internal/pycore_sysmodule.h @@ -20,6 +20,9 @@ extern void _PySys_ClearAuditHooks(PyThreadState *tstate); PyAPI_FUNC(int) _PySys_SetAttr(PyObject *, PyObject *); +extern int _PySys_ClearAttrString(PyInterpreterState *interp, + const char *name, int verbose); + #ifdef __cplusplus } #endif diff --git a/Include/internal/pycore_time.h b/Include/internal/pycore_time.h new file mode 100644 index 00000000..949170c4 --- /dev/null +++ b/Include/internal/pycore_time.h @@ -0,0 +1,25 @@ +#ifndef Py_INTERNAL_TIME_H +#define Py_INTERNAL_TIME_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + + +struct _time_runtime_state { +#ifdef HAVE_TIMES + int ticks_per_second_initialized; + long ticks_per_second; +#else + int _not_used; +#endif +}; + + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_TIME_H */ diff --git a/Include/token.h b/Include/internal/pycore_token.h similarity index 70% rename from Include/token.h rename to Include/internal/pycore_token.h index eb1b9ea4..c02e637f 100644 --- a/Include/token.h +++ b/Include/internal/pycore_token.h @@ -1,13 +1,16 @@ -/* Auto-generated by Tools/scripts/generate_token.py */ +/* Auto-generated by Tools/build/generate_token.py */ /* Token types */ -#ifndef Py_LIMITED_API -#ifndef Py_TOKEN_H -#define Py_TOKEN_H +#ifndef Py_INTERNAL_TOKEN_H +#define Py_INTERNAL_TOKEN_H #ifdef __cplusplus extern "C" { #endif +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + #undef TILDE /* Prevent clash of our definition with system macro. Ex AIX, ioctl.h */ #define ENDMARKER 0 @@ -64,14 +67,20 @@ extern "C" { #define RARROW 51 #define ELLIPSIS 52 #define COLONEQUAL 53 -#define OP 54 -#define AWAIT 55 -#define ASYNC 56 -#define TYPE_IGNORE 57 -#define TYPE_COMMENT 58 -#define SOFT_KEYWORD 59 -#define ERRORTOKEN 60 -#define N_TOKENS 64 +#define EXCLAMATION 54 +#define OP 55 +#define AWAIT 56 +#define ASYNC 57 +#define TYPE_IGNORE 58 +#define TYPE_COMMENT 59 +#define SOFT_KEYWORD 60 +#define FSTRING_START 61 +#define FSTRING_MIDDLE 62 +#define FSTRING_END 63 +#define COMMENT 64 +#define NL 65 +#define ERRORTOKEN 66 +#define N_TOKENS 68 #define NT_OFFSET 256 /* Special definitions for cooperation with parser */ @@ -83,15 +92,17 @@ extern "C" { (x) == NEWLINE || \ (x) == INDENT || \ (x) == DEDENT) +#define ISSTRINGLIT(x) ((x) == STRING || \ + (x) == FSTRING_MIDDLE) +// Symbols exported for test_peg_generator PyAPI_DATA(const char * const) _PyParser_TokenNames[]; /* Token names */ -PyAPI_FUNC(int) PyToken_OneChar(int); -PyAPI_FUNC(int) PyToken_TwoChars(int, int); -PyAPI_FUNC(int) PyToken_ThreeChars(int, int, int); +PyAPI_FUNC(int) _PyToken_OneChar(int); +PyAPI_FUNC(int) _PyToken_TwoChars(int, int); +PyAPI_FUNC(int) _PyToken_ThreeChars(int, int, int); #ifdef __cplusplus } #endif -#endif /* !Py_TOKEN_H */ -#endif /* Py_LIMITED_API */ +#endif // !Py_INTERNAL_TOKEN_H diff --git a/Include/internal/pycore_tracemalloc.h b/Include/internal/pycore_tracemalloc.h new file mode 100644 index 00000000..d086adc6 --- /dev/null +++ b/Include/internal/pycore_tracemalloc.h @@ -0,0 +1,123 @@ +#ifndef Py_INTERNAL_TRACEMALLOC_H +#define Py_INTERNAL_TRACEMALLOC_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +#include "pycore_hashtable.h" // _Py_hashtable_t + + +/* Trace memory blocks allocated by PyMem_RawMalloc() */ +#define TRACE_RAW_MALLOC + + +struct _PyTraceMalloc_Config { + /* Module initialized? + Variable protected by the GIL */ + enum { + TRACEMALLOC_NOT_INITIALIZED, + TRACEMALLOC_INITIALIZED, + TRACEMALLOC_FINALIZED + } initialized; + + /* Is tracemalloc tracing memory allocations? + Variable protected by the GIL */ + int tracing; + + /* limit of the number of frames in a traceback, 1 by default. + Variable protected by the GIL. */ + int max_nframe; +}; + + +/* Pack the frame_t structure to reduce the memory footprint on 64-bit + architectures: 12 bytes instead of 16. */ +#if defined(_MSC_VER) +#pragma pack(push, 4) +#endif + +struct +#ifdef __GNUC__ +__attribute__((packed)) +#endif +tracemalloc_frame { + /* filename cannot be NULL: "<unknown>" is used if the Python frame + filename is NULL */ + PyObject *filename; + unsigned int lineno; +}; +#ifdef _MSC_VER +#pragma pack(pop) +#endif + +struct tracemalloc_traceback { + Py_uhash_t hash; + /* Number of frames stored */ + uint16_t nframe; + /* Total number of frames the traceback had */ + uint16_t total_nframe; + struct tracemalloc_frame frames[1]; +}; + + +struct _tracemalloc_runtime_state { + struct _PyTraceMalloc_Config config; + + /* Protected by the GIL */ + struct { + PyMemAllocatorEx mem; + PyMemAllocatorEx raw; + PyMemAllocatorEx obj; + } allocators; + +#if defined(TRACE_RAW_MALLOC) + PyThread_type_lock tables_lock; +#endif + /* Size in bytes of currently traced memory. + Protected by TABLES_LOCK(). */ + size_t traced_memory; + /* Peak size in bytes of traced memory. + Protected by TABLES_LOCK(). */ + size_t peak_traced_memory; + /* Hash table used as a set to intern filenames: + PyObject* => PyObject*. + Protected by the GIL */ + _Py_hashtable_t *filenames; + /* Buffer to store a new traceback in traceback_new(). + Protected by the GIL. */ + struct tracemalloc_traceback *traceback; + /* Hash table used as a set to intern tracebacks: + traceback_t* => traceback_t* + Protected by the GIL */ + _Py_hashtable_t *tracebacks; + /* pointer (void*) => trace (trace_t*). + Protected by TABLES_LOCK(). */ + _Py_hashtable_t *traces; + /* domain (unsigned int) => traces (_Py_hashtable_t). + Protected by TABLES_LOCK(). */ + _Py_hashtable_t *domains; + + struct tracemalloc_traceback empty_traceback; + + Py_tss_t reentrant_key; +}; + +#define _tracemalloc_runtime_state_INIT \ + { \ + .config = { \ + .initialized = TRACEMALLOC_NOT_INITIALIZED, \ + .tracing = 0, \ + .max_nframe = 1, \ + }, \ + .reentrant_key = Py_tss_NEEDS_INIT, \ + } + + +#ifdef __cplusplus +} +#endif +#endif // !Py_INTERNAL_TRACEMALLOC_H diff --git a/Include/internal/pycore_tuple.h b/Include/internal/pycore_tuple.h index 1efe4fa2..335edad8 100644 --- a/Include/internal/pycore_tuple.h +++ b/Include/internal/pycore_tuple.h @@ -14,7 +14,6 @@ extern "C" { /* runtime lifecycle */ extern PyStatus _PyTuple_InitGlobalObjects(PyInterpreterState *); -extern PyStatus _PyTuple_InitTypes(PyInterpreterState *); extern void _PyTuple_Fini(PyInterpreterState *); @@ -62,11 +61,18 @@ struct _Py_tuple_state { #endif }; -#define _PyTuple_ITEMS(op) (_PyTuple_CAST(op)->ob_item) +#define _PyTuple_ITEMS(op) _Py_RVALUE(_PyTuple_CAST(op)->ob_item) extern PyObject *_PyTuple_FromArray(PyObject *const *, Py_ssize_t); extern PyObject *_PyTuple_FromArraySteal(PyObject *const *, Py_ssize_t); + +typedef struct { + PyObject_HEAD + Py_ssize_t it_index; + PyTupleObject *it_seq; /* Set to NULL when iterator is exhausted */ +} _PyTupleIterObject; + #ifdef __cplusplus } #endif diff --git a/Include/internal/pycore_typeobject.h b/Include/internal/pycore_typeobject.h index c480a3a5..8f3fbbcd 100644 --- a/Include/internal/pycore_typeobject.h +++ b/Include/internal/pycore_typeobject.h @@ -4,20 +4,25 @@ extern "C" { #endif +#include "pycore_moduleobject.h" + #ifndef Py_BUILD_CORE # error "this header requires Py_BUILD_CORE define" #endif -/* runtime lifecycle */ +/* state */ -extern PyStatus _PyTypes_InitState(PyInterpreterState *); -extern PyStatus _PyTypes_InitTypes(PyInterpreterState *); -extern void _PyTypes_FiniTypes(PyInterpreterState *); -extern void _PyTypes_Fini(PyInterpreterState *); +#define _Py_TYPE_BASE_VERSION_TAG (2<<16) +#define _Py_MAX_GLOBAL_TYPE_VERSION_TAG (_Py_TYPE_BASE_VERSION_TAG - 1) +struct _types_runtime_state { + /* Used to set PyTypeObject.tp_version_tag for core static types. */ + // bpo-42745: next_version_tag remains shared by all interpreters + // because of static types. + unsigned int next_version_tag; +}; -/* other API */ // Type attribute lookup cache: speed up attribute and method lookups, // see _PyType_Lookup(). @@ -28,21 +33,113 @@ struct type_cache_entry { }; #define MCACHE_SIZE_EXP 12 -#define MCACHE_STATS 0 struct type_cache { struct type_cache_entry hashtable[1 << MCACHE_SIZE_EXP]; -#if MCACHE_STATS - size_t hits; - size_t misses; - size_t collisions; -#endif }; -extern PyStatus _PyTypes_InitSlotDefs(void); +/* For now we hard-code this to a value for which we are confident + all the static builtin types will fit (for all builds). */ +#define _Py_MAX_STATIC_BUILTIN_TYPES 200 + +typedef struct { + PyTypeObject *type; + int readying; + int ready; + // XXX tp_dict can probably be statically allocated, + // instead of dynamically and stored on the interpreter. + PyObject *tp_dict; + PyObject *tp_subclasses; + /* We never clean up weakrefs for static builtin types since + they will effectively never get triggered. However, there + are also some diagnostic uses for the list of weakrefs, + so we still keep it. */ + PyObject *tp_weaklist; +} static_builtin_state; + +struct types_state { + /* Used to set PyTypeObject.tp_version_tag. + It starts at _Py_MAX_GLOBAL_TYPE_VERSION_TAG + 1, + where all those lower numbers are used for core static types. */ + unsigned int next_version_tag; + + struct type_cache type_cache; + size_t num_builtins_initialized; + static_builtin_state builtins[_Py_MAX_STATIC_BUILTIN_TYPES]; +}; + + +/* runtime lifecycle */ + +extern PyStatus _PyTypes_InitTypes(PyInterpreterState *); +extern void _PyTypes_FiniTypes(PyInterpreterState *); +extern void _PyTypes_Fini(PyInterpreterState *); + + +/* other API */ + +/* Length of array of slotdef pointers used to store slots with the + same __name__. There should be at most MAX_EQUIV-1 slotdef entries with + the same __name__, for any __name__. Since that's a static property, it is + appropriate to declare fixed-size arrays for this. */ +#define MAX_EQUIV 10 + +typedef struct wrapperbase pytype_slotdef; + + +static inline PyObject ** +_PyStaticType_GET_WEAKREFS_LISTPTR(static_builtin_state *state) +{ + assert(state != NULL); + return &state->tp_weaklist; +} + +/* Like PyType_GetModuleState, but skips verification + * that type is a heap type with an associated module */ +static inline void * +_PyType_GetModuleState(PyTypeObject *type) +{ + assert(PyType_Check(type)); + assert(type->tp_flags & Py_TPFLAGS_HEAPTYPE); + PyHeapTypeObject *et = (PyHeapTypeObject *)type; + assert(et->ht_module); + PyModuleObject *mod = (PyModuleObject *)(et->ht_module); + assert(mod != NULL); + return mod->md_state; +} + + +extern int _PyStaticType_InitBuiltin(PyInterpreterState *, PyTypeObject *type); +extern static_builtin_state * _PyStaticType_GetState(PyInterpreterState *, PyTypeObject *); +extern void _PyStaticType_ClearWeakRefs(PyInterpreterState *, PyTypeObject *type); +extern void _PyStaticType_Dealloc(PyInterpreterState *, PyTypeObject *); + +PyAPI_FUNC(PyObject *) _PyType_GetDict(PyTypeObject *); +extern PyObject * _PyType_GetBases(PyTypeObject *type); +extern PyObject * _PyType_GetMRO(PyTypeObject *type); +extern PyObject* _PyType_GetSubclasses(PyTypeObject *); +extern int _PyType_HasSubclasses(PyTypeObject *); + +// PyType_Ready() must be called if _PyType_IsReady() is false. +// See also the Py_TPFLAGS_READY flag. +static inline int +_PyType_IsReady(PyTypeObject *type) +{ + return _PyType_GetDict(type) != NULL; +} + +PyObject * +_Py_type_getattro_impl(PyTypeObject *type, PyObject *name, int *suppress_missing_attribute); +PyObject * +_Py_type_getattro(PyTypeObject *type, PyObject *name); + +PyObject *_Py_slot_tp_getattro(PyObject *self, PyObject *name); +PyObject *_Py_slot_tp_getattr_hook(PyObject *self, PyObject *name); -extern void _PyStaticType_Dealloc(PyTypeObject *type); +PyAPI_DATA(PyTypeObject) _PyBufferWrapper_Type; +PyObject * +_PySuper_Lookup(PyTypeObject *su_type, PyObject *su_obj, PyObject *name, int *meth_found); #ifdef __cplusplus } diff --git a/Include/internal/pycore_typevarobject.h b/Include/internal/pycore_typevarobject.h new file mode 100644 index 00000000..c9fa97d6 --- /dev/null +++ b/Include/internal/pycore_typevarobject.h @@ -0,0 +1,24 @@ +#ifndef Py_INTERNAL_TYPEVAROBJECT_H +#define Py_INTERNAL_TYPEVAROBJECT_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +extern PyObject *_Py_make_typevar(PyObject *, PyObject *, PyObject *); +extern PyObject *_Py_make_paramspec(PyThreadState *, PyObject *); +extern PyObject *_Py_make_typevartuple(PyThreadState *, PyObject *); +extern PyObject *_Py_make_typealias(PyThreadState *, PyObject *); +extern PyObject *_Py_subscript_generic(PyThreadState *, PyObject *); +extern int _Py_initialize_generic(PyInterpreterState *); +extern void _Py_clear_generic_types(PyInterpreterState *); + +extern PyTypeObject _PyTypeAlias_Type; + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_TYPEVAROBJECT_H */ diff --git a/Include/internal/pycore_unicodeobject.h b/Include/internal/pycore_unicodeobject.h index 4bee2419..1bb0f366 100644 --- a/Include/internal/pycore_unicodeobject.h +++ b/Include/internal/pycore_unicodeobject.h @@ -9,8 +9,10 @@ extern "C" { #endif #include "pycore_fileutils.h" // _Py_error_handler +#include "pycore_ucnhash.h" // _PyUnicode_Name_CAPI void _PyUnicode_ExactDealloc(PyObject *op); +Py_ssize_t _PyUnicode_InternedSize(void); /* runtime lifecycle */ @@ -19,7 +21,6 @@ extern PyStatus _PyUnicode_InitGlobalObjects(PyInterpreterState *); extern PyStatus _PyUnicode_InitTypes(PyInterpreterState *); extern void _PyUnicode_Fini(PyInterpreterState *); extern void _PyUnicode_FiniTypes(PyInterpreterState *); -extern void _PyStaticUnicode_Dealloc(PyObject *); extern PyTypeObject _PyUnicodeASCIIIter_Type; @@ -32,6 +33,10 @@ struct _Py_unicode_runtime_ids { Py_ssize_t next_index; }; +struct _Py_unicode_runtime_state { + struct _Py_unicode_runtime_ids ids; +}; + /* fs_codec.encoding is initialized to NULL. Later, it is set to a non-NULL string by _PyUnicode_InitEncodings(). */ struct _Py_unicode_fs_codec { @@ -49,10 +54,13 @@ struct _Py_unicode_ids { struct _Py_unicode_state { struct _Py_unicode_fs_codec fs_codec; + _PyUnicode_Name_CAPI *ucnhash_capi; + // Unicode identifiers (_Py_Identifier): see _PyUnicode_FromId() struct _Py_unicode_ids ids; }; +extern void _PyUnicode_InternInPlace(PyInterpreterState *interp, PyObject **p); extern void _PyUnicode_ClearInterned(PyInterpreterState *interp); diff --git a/Include/internal/pycore_unicodeobject_generated.h b/Include/internal/pycore_unicodeobject_generated.h new file mode 100644 index 00000000..9b470094 --- /dev/null +++ b/Include/internal/pycore_unicodeobject_generated.h @@ -0,0 +1,2093 @@ +#ifndef Py_INTERNAL_UNICODEOBJECT_GENERATED_H +#define Py_INTERNAL_UNICODEOBJECT_GENERATED_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +/* The following is auto-generated by Tools/build/generate_global_objects.py. */ +static inline void +_PyUnicode_InitStaticStrings(PyInterpreterState *interp) { + PyObject *string; + string = &_Py_ID(CANCELLED); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(FINISHED); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(False); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(JSONDecodeError); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(PENDING); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(Py_Repr); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(TextIOWrapper); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(True); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(WarningMessage); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(_); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(_WindowsConsoleIO); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__IOBase_closed); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__abc_tpflags__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__abs__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__abstractmethods__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__add__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__aenter__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__aexit__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__aiter__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__all__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__and__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__anext__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__annotations__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__args__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__asyncio_running_event_loop__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__await__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__bases__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__bool__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__buffer__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__build_class__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__builtins__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__bytes__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__call__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__cantrace__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__class__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__class_getitem__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__classcell__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__classdict__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__classdictcell__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__complex__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__contains__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__copy__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__ctypes_from_outparam__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__del__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__delattr__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__delete__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__delitem__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__dict__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__dictoffset__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__dir__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__divmod__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__doc__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__enter__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__eq__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__exit__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__file__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__float__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__floordiv__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__format__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__fspath__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__ge__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__get__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__getattr__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__getattribute__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__getinitargs__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__getitem__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__getnewargs__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__getnewargs_ex__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__getstate__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__gt__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__hash__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__iadd__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__iand__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__ifloordiv__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__ilshift__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__imatmul__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__imod__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__import__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__imul__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__index__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__init__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__init_subclass__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__instancecheck__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__int__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__invert__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__ior__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__ipow__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__irshift__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__isabstractmethod__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__isub__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__iter__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__itruediv__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__ixor__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__le__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__len__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__length_hint__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__lltrace__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__loader__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__lshift__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__lt__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__main__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__matmul__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__missing__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__mod__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__module__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__mro_entries__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__mul__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__name__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__ne__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__neg__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__new__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__newobj__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__newobj_ex__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__next__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__notes__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__or__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__orig_class__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__origin__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__package__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__parameters__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__path__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__pos__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__pow__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__prepare__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__qualname__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__radd__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__rand__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__rdivmod__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__reduce__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__reduce_ex__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__release_buffer__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__repr__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__reversed__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__rfloordiv__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__rlshift__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__rmatmul__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__rmod__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__rmul__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__ror__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__round__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__rpow__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__rrshift__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__rshift__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__rsub__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__rtruediv__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__rxor__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__set__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__set_name__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__setattr__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__setitem__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__setstate__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__sizeof__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__slotnames__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__slots__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__spec__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__str__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__sub__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__subclasscheck__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__subclasshook__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__truediv__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__trunc__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__type_params__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__typing_is_unpacked_typevartuple__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__typing_prepare_subst__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__typing_subst__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__typing_unpacked_tuple_args__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__warningregistry__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__weaklistoffset__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__weakref__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__xor__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(_abc_impl); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(_abstract_); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(_active); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(_annotation); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(_anonymous_); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(_argtypes_); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(_as_parameter_); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(_asyncio_future_blocking); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(_blksize); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(_bootstrap); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(_check_retval_); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(_dealloc_warn); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(_feature_version); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(_fields_); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(_finalizing); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(_find_and_load); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(_fix_up_module); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(_flags_); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(_get_sourcefile); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(_handle_fromlist); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(_initializing); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(_io); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(_is_text_encoding); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(_length_); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(_limbo); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(_lock_unlock_module); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(_loop); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(_needs_com_addref_); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(_pack_); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(_restype_); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(_showwarnmsg); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(_shutdown); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(_slotnames); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(_strptime_datetime); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(_swappedbytes_); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(_type_); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(_uninitialized_submodules); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(_warn_unawaited_coroutine); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(_xoptions); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(a); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(abs_tol); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(access); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(add); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(add_done_callback); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(after_in_child); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(after_in_parent); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(aggregate_class); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(alias); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(append); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(arg); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(argdefs); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(args); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(arguments); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(argv); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(as_integer_ratio); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(ast); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(attribute); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(authorizer_callback); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(autocommit); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(b); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(backtick); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(base); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(before); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(big); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(binary_form); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(block); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(bound); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(buffer); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(buffer_callback); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(buffer_size); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(buffering); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(buffers); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(bufsize); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(builtins); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(byteorder); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(bytes); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(bytes_per_sep); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(c); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(c_call); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(c_exception); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(c_return); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(cached_statements); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(cadata); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(cafile); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(call); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(call_exception_handler); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(call_soon); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(cancel); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(capath); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(category); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(cb_type); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(certfile); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(check_same_thread); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(clear); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(close); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(closed); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(closefd); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(closure); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(co_argcount); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(co_cellvars); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(co_code); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(co_consts); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(co_exceptiontable); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(co_filename); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(co_firstlineno); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(co_flags); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(co_freevars); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(co_kwonlyargcount); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(co_linetable); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(co_name); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(co_names); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(co_nlocals); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(co_posonlyargcount); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(co_qualname); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(co_stacksize); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(co_varnames); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(code); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(command); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(comment_factory); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(compile_mode); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(consts); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(context); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(contravariant); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(cookie); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(copy); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(copyreg); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(coro); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(count); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(covariant); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(cwd); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(d); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(data); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(database); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(decode); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(decoder); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(default); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(defaultaction); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(delete); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(depth); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(detect_types); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(deterministic); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(device); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(dict); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(dictcomp); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(difference_update); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(digest); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(digest_size); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(digestmod); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(dir_fd); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(discard); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(dispatch_table); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(displayhook); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(dklen); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(doc); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(dont_inherit); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(dst); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(dst_dir_fd); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(duration); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(e); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(eager_start); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(effective_ids); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(element_factory); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(encode); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(encoding); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(end); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(end_lineno); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(end_offset); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(endpos); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(entrypoint); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(env); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(errors); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(event); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(eventmask); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(exc_type); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(exc_value); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(excepthook); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(exception); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(existing_file_name); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(exp); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(extend); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(extra_tokens); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(facility); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(factory); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(false); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(family); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(fanout); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(fd); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(fd2); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(fdel); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(fget); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(file); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(file_actions); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(filename); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(fileno); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(filepath); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(fillvalue); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(filters); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(final); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(find_class); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(fix_imports); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(flags); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(flush); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(follow_symlinks); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(format); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(frequency); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(from_param); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(fromlist); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(fromtimestamp); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(fromutc); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(fset); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(func); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(future); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(generation); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(genexpr); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(get); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(get_debug); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(get_event_loop); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(get_loop); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(get_source); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(getattr); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(getstate); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(gid); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(globals); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(groupindex); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(groups); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(handle); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(hash_name); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(header); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(headers); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(hi); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(hook); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(id); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(ident); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(ignore); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(imag); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(importlib); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(in_fd); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(incoming); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(indexgroup); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(inf); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(infer_variance); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(inheritable); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(initial); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(initial_bytes); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(initial_value); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(initval); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(inner_size); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(input); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(insert_comments); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(insert_pis); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(instructions); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(intern); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(intersection); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(is_running); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(isatty); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(isinstance); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(isoformat); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(isolation_level); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(istext); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(item); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(items); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(iter); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(iterable); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(iterations); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(join); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(jump); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(keepends); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(key); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(keyfile); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(keys); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(kind); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(kw); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(kw1); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(kw2); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(lambda); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(last); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(last_exc); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(last_node); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(last_traceback); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(last_type); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(last_value); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(latin1); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(leaf_size); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(len); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(length); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(level); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(limit); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(line); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(line_buffering); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(lineno); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(listcomp); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(little); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(lo); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(locale); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(locals); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(logoption); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(loop); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(mapping); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(match); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(max_length); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(maxdigits); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(maxevents); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(maxmem); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(maxsplit); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(maxvalue); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(memLevel); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(memlimit); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(message); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(metaclass); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(metadata); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(method); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(mod); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(mode); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(module); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(module_globals); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(modules); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(mro); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(msg); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(mycmp); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(n); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(n_arg); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(n_fields); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(n_sequence_fields); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(n_unnamed_fields); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(name); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(name_from); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(namespace_separator); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(namespaces); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(narg); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(ndigits); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(new_file_name); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(new_limit); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(newline); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(newlines); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(next); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(nlocals); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(node_depth); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(node_offset); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(ns); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(nstype); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(nt); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(null); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(number); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(obj); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(object); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(offset); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(offset_dst); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(offset_src); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(on_type_read); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(onceregistry); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(only_keys); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(oparg); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(opcode); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(open); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(opener); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(operation); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(optimize); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(options); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(order); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(origin); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(out_fd); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(outgoing); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(overlapped); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(owner); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(p); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(pages); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(parent); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(password); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(path); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(pattern); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(peek); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(persistent_id); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(persistent_load); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(person); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(pi_factory); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(pid); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(policy); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(pos); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(pos1); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(pos2); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(posix); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(print_file_and_line); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(priority); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(progress); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(progress_handler); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(progress_routine); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(proto); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(protocol); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(ps1); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(ps2); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(query); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(quotetabs); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(r); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(raw); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(read); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(read1); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(readable); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(readall); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(readinto); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(readinto1); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(readline); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(readonly); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(real); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(reducer_override); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(registry); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(rel_tol); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(release); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(reload); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(repl); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(replace); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(reserved); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(reset); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(resetids); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(return); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(reverse); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(reversed); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(s); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(salt); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(sched_priority); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(scheduler); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(seek); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(seekable); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(selectors); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(self); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(send); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(sep); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(sequence); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(server_hostname); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(server_side); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(session); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(setcomp); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(setpgroup); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(setsid); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(setsigdef); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(setsigmask); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(setstate); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(shape); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(show_cmd); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(signed); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(size); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(sizehint); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(skip_file_prefixes); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(sleep); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(sock); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(sort); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(sound); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(source); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(source_traceback); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(src); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(src_dir_fd); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(stacklevel); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(start); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(statement); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(status); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(stderr); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(stdin); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(stdout); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(step); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(steps); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(store_name); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(strategy); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(strftime); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(strict); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(strict_mode); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(string); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(sub_key); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(symmetric_difference_update); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(tabsize); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(tag); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(target); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(target_is_directory); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(task); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(tb_frame); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(tb_lasti); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(tb_lineno); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(tb_next); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(tell); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(template); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(term); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(text); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(threading); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(throw); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(timeout); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(times); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(timetuple); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(top); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(trace_callback); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(traceback); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(trailers); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(translate); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(true); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(truncate); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(twice); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(txt); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(type); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(type_params); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(tz); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(tzname); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(uid); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(unlink); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(unraisablehook); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(uri); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(usedforsecurity); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(value); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(values); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(version); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(volume); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(warnings); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(warnoptions); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(wbits); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(week); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(weekday); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(which); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(who); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(withdata); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(writable); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(write); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(write_through); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(x); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(year); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(zdict); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); +} +/* End auto-generated code */ +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_UNICODEOBJECT_GENERATED_H */ diff --git a/Include/internal/pycore_unionobject.h b/Include/internal/pycore_unionobject.h index a9ed5651..87264635 100644 --- a/Include/internal/pycore_unionobject.h +++ b/Include/internal/pycore_unionobject.h @@ -9,10 +9,10 @@ extern "C" { #endif extern PyTypeObject _PyUnion_Type; -#define _PyUnion_Check(op) Py_IS_TYPE(op, &_PyUnion_Type) +#define _PyUnion_Check(op) Py_IS_TYPE((op), &_PyUnion_Type) extern PyObject *_Py_union_type_or(PyObject *, PyObject *); -#define _PyGenericAlias_Check(op) PyObject_TypeCheck(op, &Py_GenericAliasType) +#define _PyGenericAlias_Check(op) PyObject_TypeCheck((op), &Py_GenericAliasType) extern PyObject *_Py_subs_parameters(PyObject *, PyObject *, PyObject *, PyObject *); extern PyObject *_Py_make_parameters(PyObject *); extern PyObject *_Py_union_args(PyObject *self); diff --git a/Include/interpreteridobject.h b/Include/interpreteridobject.h new file mode 100644 index 00000000..8432632f --- /dev/null +++ b/Include/interpreteridobject.h @@ -0,0 +1,17 @@ +#ifndef Py_INTERPRETERIDOBJECT_H +#define Py_INTERPRETERIDOBJECT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_LIMITED_API +# define Py_CPYTHON_INTERPRETERIDOBJECT_H +# include "cpython/interpreteridobject.h" +# undef Py_CPYTHON_INTERPRETERIDOBJECT_H +#endif + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERPRETERIDOBJECT_H */ diff --git a/Include/iterobject.h b/Include/iterobject.h index 6454611a..fff30f71 100644 --- a/Include/iterobject.h +++ b/Include/iterobject.h @@ -11,12 +11,12 @@ PyAPI_DATA(PyTypeObject) PyCallIter_Type; extern PyTypeObject _PyAnextAwaitable_Type; #endif -#define PySeqIter_Check(op) Py_IS_TYPE(op, &PySeqIter_Type) +#define PySeqIter_Check(op) Py_IS_TYPE((op), &PySeqIter_Type) PyAPI_FUNC(PyObject *) PySeqIter_New(PyObject *); -#define PyCallIter_Check(op) Py_IS_TYPE(op, &PyCallIter_Type) +#define PyCallIter_Check(op) Py_IS_TYPE((op), &PyCallIter_Type) PyAPI_FUNC(PyObject *) PyCallIter_New(PyObject *, PyObject *); diff --git a/Include/listobject.h b/Include/listobject.h index eff42c18..6b7041ba 100644 --- a/Include/listobject.h +++ b/Include/listobject.h @@ -23,7 +23,7 @@ PyAPI_DATA(PyTypeObject) PyListRevIter_Type; #define PyList_Check(op) \ PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_LIST_SUBCLASS) -#define PyList_CheckExact(op) Py_IS_TYPE(op, &PyList_Type) +#define PyList_CheckExact(op) Py_IS_TYPE((op), &PyList_Type) PyAPI_FUNC(PyObject *) PyList_New(Py_ssize_t size); PyAPI_FUNC(Py_ssize_t) PyList_Size(PyObject *); diff --git a/Include/longobject.h b/Include/longobject.h index 81ba1239..e559e238 100644 --- a/Include/longobject.h +++ b/Include/longobject.h @@ -11,7 +11,7 @@ PyAPI_DATA(PyTypeObject) PyLong_Type; #define PyLong_Check(op) \ PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_LONG_SUBCLASS) -#define PyLong_CheckExact(op) Py_IS_TYPE(op, &PyLong_Type) +#define PyLong_CheckExact(op) Py_IS_TYPE((op), &PyLong_Type) PyAPI_FUNC(PyObject *) PyLong_FromLong(long); PyAPI_FUNC(PyObject *) PyLong_FromUnsignedLong(unsigned long); diff --git a/Include/memoryobject.h b/Include/memoryobject.h index 154397ce..2c9146aa 100644 --- a/Include/memoryobject.h +++ b/Include/memoryobject.h @@ -6,19 +6,9 @@ extern "C" { #endif -#ifndef Py_LIMITED_API -PyAPI_DATA(PyTypeObject) _PyManagedBuffer_Type; -#endif PyAPI_DATA(PyTypeObject) PyMemoryView_Type; -#define PyMemoryView_Check(op) Py_IS_TYPE(op, &PyMemoryView_Type) - -#ifndef Py_LIMITED_API -/* Get a pointer to the memoryview's private copy of the exporter's buffer. */ -#define PyMemoryView_GET_BUFFER(op) (&((PyMemoryViewObject *)(op))->view) -/* Get a pointer to the exporting object (this may be NULL!). */ -#define PyMemoryView_GET_BASE(op) (((PyMemoryViewObject *)(op))->view.obj) -#endif +#define PyMemoryView_Check(op) Py_IS_TYPE((op), &PyMemoryView_Type) PyAPI_FUNC(PyObject *) PyMemoryView_FromObject(PyObject *base); #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 @@ -32,38 +22,10 @@ PyAPI_FUNC(PyObject *) PyMemoryView_GetContiguous(PyObject *base, int buffertype, char order); - -/* The structs are declared here so that macros can work, but they shouldn't - be considered public. Don't access their fields directly, use the macros - and functions instead! */ #ifndef Py_LIMITED_API -#define _Py_MANAGED_BUFFER_RELEASED 0x001 /* access to exporter blocked */ -#define _Py_MANAGED_BUFFER_FREE_FORMAT 0x002 /* free format */ -typedef struct { - PyObject_HEAD - int flags; /* state flags */ - Py_ssize_t exports; /* number of direct memoryview exports */ - Py_buffer master; /* snapshot buffer obtained from the original exporter */ -} _PyManagedBufferObject; - - -/* memoryview state flags */ -#define _Py_MEMORYVIEW_RELEASED 0x001 /* access to master buffer blocked */ -#define _Py_MEMORYVIEW_C 0x002 /* C-contiguous layout */ -#define _Py_MEMORYVIEW_FORTRAN 0x004 /* Fortran contiguous layout */ -#define _Py_MEMORYVIEW_SCALAR 0x008 /* scalar: ndim = 0 */ -#define _Py_MEMORYVIEW_PIL 0x010 /* PIL-style layout */ - -typedef struct { - PyObject_VAR_HEAD - _PyManagedBufferObject *mbuf; /* managed buffer */ - Py_hash_t hash; /* hash value for read-only views */ - int flags; /* state flags */ - Py_ssize_t exports; /* number of buffer re-exports */ - Py_buffer view; /* private copy of the exporter's view */ - PyObject *weakreflist; - Py_ssize_t ob_array[1]; /* shape, strides, suboffsets */ -} PyMemoryViewObject; +# define Py_CPYTHON_MEMORYOBJECT_H +# include "cpython/memoryobject.h" +# undef Py_CPYTHON_MEMORYOBJECT_H #endif #ifdef __cplusplus diff --git a/Include/methodobject.h b/Include/methodobject.h index c971d78a..72af5ad9 100644 --- a/Include/methodobject.h +++ b/Include/methodobject.h @@ -13,8 +13,8 @@ extern "C" { PyAPI_DATA(PyTypeObject) PyCFunction_Type; -#define PyCFunction_CheckExact(op) Py_IS_TYPE(op, &PyCFunction_Type) -#define PyCFunction_Check(op) PyObject_TypeCheck(op, &PyCFunction_Type) +#define PyCFunction_CheckExact(op) Py_IS_TYPE((op), &PyCFunction_Type) +#define PyCFunction_Check(op) PyObject_TypeCheck((op), &PyCFunction_Type) typedef PyObject *(*PyCFunction)(PyObject *, PyObject *); typedef PyObject *(*_PyCFunctionFast) (PyObject *, PyObject *const *, Py_ssize_t); diff --git a/Include/modsupport.h b/Include/modsupport.h index 0e96a5c9..1592bd0d 100644 --- a/Include/modsupport.h +++ b/Include/modsupport.h @@ -37,14 +37,14 @@ PyAPI_FUNC(PyObject *) Py_BuildValue(const char *, ...); PyAPI_FUNC(PyObject *) _Py_BuildValue_SizeT(const char *, ...); -#define ANY_VARARGS(n) (n == PY_SSIZE_T_MAX) - PyAPI_FUNC(PyObject *) Py_VaBuildValue(const char *, va_list); +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030a0000 // Add an attribute with name 'name' and value 'obj' to the module 'mod. // On success, return 0 on success. // On error, raise an exception and return -1. PyAPI_FUNC(int) PyModule_AddObjectRef(PyObject *mod, const char *name, PyObject *value); +#endif /* Py_LIMITED_API */ // Similar to PyModule_AddObjectRef() but steal a reference to 'obj' // (Py_DECREF(obj)) on success (if it returns 0). @@ -58,8 +58,8 @@ PyAPI_FUNC(int) PyModule_AddStringConstant(PyObject *, const char *, const char PyAPI_FUNC(int) PyModule_AddType(PyObject *module, PyTypeObject *type); #endif /* Py_LIMITED_API */ -#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant(m, #c, c) -#define PyModule_AddStringMacro(m, c) PyModule_AddStringConstant(m, #c, c) +#define PyModule_AddIntMacro(m, c) PyModule_AddIntConstant((m), #c, (c)) +#define PyModule_AddStringMacro(m, c) PyModule_AddStringConstant((m), #c, (c)) #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000 /* New in 3.5 */ @@ -134,10 +134,10 @@ PyAPI_FUNC(PyObject *) PyModule_Create2(PyModuleDef*, int apiver); #ifdef Py_LIMITED_API #define PyModule_Create(module) \ - PyModule_Create2(module, PYTHON_ABI_VERSION) + PyModule_Create2((module), PYTHON_ABI_VERSION) #else #define PyModule_Create(module) \ - PyModule_Create2(module, PYTHON_API_VERSION) + PyModule_Create2((module), PYTHON_API_VERSION) #endif #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000 @@ -148,10 +148,10 @@ PyAPI_FUNC(PyObject *) PyModule_FromDefAndSpec2(PyModuleDef *def, #ifdef Py_LIMITED_API #define PyModule_FromDefAndSpec(module, spec) \ - PyModule_FromDefAndSpec2(module, spec, PYTHON_ABI_VERSION) + PyModule_FromDefAndSpec2((module), (spec), PYTHON_ABI_VERSION) #else #define PyModule_FromDefAndSpec(module, spec) \ - PyModule_FromDefAndSpec2(module, spec, PYTHON_API_VERSION) + PyModule_FromDefAndSpec2((module), (spec), PYTHON_API_VERSION) #endif /* Py_LIMITED_API */ #endif /* New in 3.5 */ diff --git a/Include/moduleobject.h b/Include/moduleobject.h index 75abd2cf..b8bdfe29 100644 --- a/Include/moduleobject.h +++ b/Include/moduleobject.h @@ -9,8 +9,8 @@ extern "C" { PyAPI_DATA(PyTypeObject) PyModule_Type; -#define PyModule_Check(op) PyObject_TypeCheck(op, &PyModule_Type) -#define PyModule_CheckExact(op) Py_IS_TYPE(op, &PyModule_Type) +#define PyModule_Check(op) PyObject_TypeCheck((op), &PyModule_Type) +#define PyModule_CheckExact(op) Py_IS_TYPE((op), &PyModule_Type) #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 PyAPI_FUNC(PyObject *) PyModule_NewObject( @@ -43,8 +43,22 @@ PyAPI_DATA(PyTypeObject) PyModuleDef_Type; typedef struct PyModuleDef_Base { PyObject_HEAD + /* The function used to re-initialize the module. + This is only set for legacy (single-phase init) extension modules + and only used for those that support multiple initializations + (m_size >= 0). + It is set by _PyImport_LoadDynamicModuleWithSpec() + and _imp.create_builtin(). */ PyObject* (*m_init)(void); + /* The module's index into its interpreter's modules_by_index cache. + This is set for all extension modules but only used for legacy ones. + (See PyInterpreterState.modules_by_index for more info.) + It is set by PyModuleDef_Init(). */ Py_ssize_t m_index; + /* A copy of the module's __dict__ after the first time it was loaded. + This is only set/used for legacy modules that do not support + multiple initializations. + It is set by _PyImport_FixupExtensionObject(). */ PyObject* m_copy; } PyModuleDef_Base; @@ -64,11 +78,17 @@ struct PyModuleDef_Slot { #define Py_mod_create 1 #define Py_mod_exec 2 +#define Py_mod_multiple_interpreters 3 #ifndef Py_LIMITED_API -#define _Py_mod_LAST_SLOT 2 +#define _Py_mod_LAST_SLOT 3 #endif +/* for Py_mod_multiple_interpreters: */ +#define Py_MOD_MULTIPLE_INTERPRETERS_NOT_SUPPORTED ((void *)0) +#define Py_MOD_MULTIPLE_INTERPRETERS_SUPPORTED ((void *)1) +#define Py_MOD_PER_INTERPRETER_GIL_SUPPORTED ((void *)2) + #endif /* New in 3.5 */ struct PyModuleDef { diff --git a/Include/object.h b/Include/object.h index f2af428e..5c30c77b 100644 --- a/Include/object.h +++ b/Include/object.h @@ -51,6 +51,8 @@ A standard interface exists for objects that contain an array of items whose size is determined when the object is allocated. */ +#include "pystats.h" + /* Py_DEBUG implies Py_REF_DEBUG. */ #if defined(Py_DEBUG) && !defined(Py_REF_DEBUG) # define Py_REF_DEBUG @@ -76,12 +78,76 @@ whose size is determined when the object is allocated. /* PyObject_HEAD defines the initial segment of every PyObject. */ #define PyObject_HEAD PyObject ob_base; -#define PyObject_HEAD_INIT(type) \ - { _PyObject_EXTRA_INIT \ - 1, type }, +/* +Immortalization: + +The following indicates the immortalization strategy depending on the amount +of available bits in the reference count field. All strategies are backwards +compatible but the specific reference count value or immortalization check +might change depending on the specializations for the underlying system. + +Proper deallocation of immortal instances requires distinguishing between +statically allocated immortal instances vs those promoted by the runtime to be +immortal. The latter should be the only instances that require +cleanup during runtime finalization. +*/ + +#if SIZEOF_VOID_P > 4 +/* +In 64+ bit systems, an object will be marked as immortal by setting all of the +lower 32 bits of the reference count field, which is equal to: 0xFFFFFFFF + +Using the lower 32 bits makes the value backwards compatible by allowing +C-Extensions without the updated checks in Py_INCREF and Py_DECREF to safely +increase and decrease the objects reference count. The object would lose its +immortality, but the execution would still be correct. + +Reference count increases will use saturated arithmetic, taking advantage of +having all the lower 32 bits set, which will avoid the reference count to go +beyond the refcount limit. Immortality checks for reference count decreases will +be done by checking the bit sign flag in the lower 32 bits. +*/ +#define _Py_IMMORTAL_REFCNT UINT_MAX + +#else +/* +In 32 bit systems, an object will be marked as immortal by setting all of the +lower 30 bits of the reference count field, which is equal to: 0x3FFFFFFF -#define PyVarObject_HEAD_INIT(type, size) \ - { PyObject_HEAD_INIT(type) size }, +Using the lower 30 bits makes the value backwards compatible by allowing +C-Extensions without the updated checks in Py_INCREF and Py_DECREF to safely +increase and decrease the objects reference count. The object would lose its +immortality, but the execution would still be correct. + +Reference count increases and decreases will first go through an immortality +check by comparing the reference count field to the immortality reference count. +*/ +#define _Py_IMMORTAL_REFCNT (UINT_MAX >> 2) +#endif + +// Make all internal uses of PyObject_HEAD_INIT immortal while preserving the +// C-API expectation that the refcnt will be set to 1. +#ifdef Py_BUILD_CORE +#define PyObject_HEAD_INIT(type) \ + { \ + _PyObject_EXTRA_INIT \ + { _Py_IMMORTAL_REFCNT }, \ + (type) \ + }, +#else +#define PyObject_HEAD_INIT(type) \ + { \ + _PyObject_EXTRA_INIT \ + { 1 }, \ + (type) \ + }, +#endif /* Py_BUILD_CORE */ + +#define PyVarObject_HEAD_INIT(type, size) \ + { \ + PyObject_HEAD_INIT(type) \ + (size) \ + }, /* PyObject_VAR_HEAD defines the initial segment of all variable-size * container objects. These end with a declaration of an array with 1 @@ -99,7 +165,28 @@ whose size is determined when the object is allocated. */ struct _object { _PyObject_HEAD_EXTRA - Py_ssize_t ob_refcnt; + +#if (defined(__GNUC__) || defined(__clang__)) \ + && !(defined __STDC_VERSION__ && __STDC_VERSION__ >= 201112L) + // On C99 and older, anonymous union is a GCC and clang extension + __extension__ +#endif +#ifdef _MSC_VER + // Ignore MSC warning C4201: "nonstandard extension used: + // nameless struct/union" + __pragma(warning(push)) + __pragma(warning(disable: 4201)) +#endif + union { + Py_ssize_t ob_refcnt; +#if SIZEOF_VOID_P > 4 + PY_UINT32_T ob_refcnt_split[2]; +#endif + }; +#ifdef _MSC_VER + __pragma(warning(pop)) +#endif + PyTypeObject *ob_type; }; @@ -136,8 +223,13 @@ static inline PyTypeObject* Py_TYPE(PyObject *ob) { # define Py_TYPE(ob) Py_TYPE(_PyObject_CAST(ob)) #endif +PyAPI_DATA(PyTypeObject) PyLong_Type; +PyAPI_DATA(PyTypeObject) PyBool_Type; + // bpo-39573: The Py_SET_SIZE() function must be used to set an object size. static inline Py_ssize_t Py_SIZE(PyObject *ob) { + assert(ob->ob_type != &PyLong_Type); + assert(ob->ob_type != &PyBool_Type); PyVarObject *var_ob = _PyVarObject_CAST(ob); return var_ob->ob_size; } @@ -145,20 +237,36 @@ static inline Py_ssize_t Py_SIZE(PyObject *ob) { # define Py_SIZE(ob) Py_SIZE(_PyObject_CAST(ob)) #endif +static inline Py_ALWAYS_INLINE int _Py_IsImmortal(PyObject *op) +{ +#if SIZEOF_VOID_P > 4 + return _Py_CAST(PY_INT32_T, op->ob_refcnt) < 0; +#else + return op->ob_refcnt == _Py_IMMORTAL_REFCNT; +#endif +} +#define _Py_IsImmortal(op) _Py_IsImmortal(_PyObject_CAST(op)) static inline int Py_IS_TYPE(PyObject *ob, PyTypeObject *type) { return Py_TYPE(ob) == type; } #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define Py_IS_TYPE(ob, type) Py_IS_TYPE(_PyObject_CAST(ob), type) +# define Py_IS_TYPE(ob, type) Py_IS_TYPE(_PyObject_CAST(ob), (type)) #endif static inline void Py_SET_REFCNT(PyObject *ob, Py_ssize_t refcnt) { + // This immortal check is for code that is unaware of immortal objects. + // The runtime tracks these objects and we should avoid as much + // as possible having extensions inadvertently change the refcnt + // of an immortalized object. + if (_Py_IsImmortal(ob)) { + return; + } ob->ob_refcnt = refcnt; } #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define Py_SET_REFCNT(ob, refcnt) Py_SET_REFCNT(_PyObject_CAST(ob), refcnt) +# define Py_SET_REFCNT(ob, refcnt) Py_SET_REFCNT(_PyObject_CAST(ob), (refcnt)) #endif @@ -169,12 +277,13 @@ static inline void Py_SET_TYPE(PyObject *ob, PyTypeObject *type) { # define Py_SET_TYPE(ob, type) Py_SET_TYPE(_PyObject_CAST(ob), type) #endif - static inline void Py_SET_SIZE(PyVarObject *ob, Py_ssize_t size) { + assert(ob->ob_base.ob_type != &PyLong_Type); + assert(ob->ob_base.ob_type != &PyBool_Type); ob->ob_size = size; } #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define Py_SET_SIZE(ob, size) Py_SET_SIZE(_PyVarObject_CAST(ob), size) +# define Py_SET_SIZE(ob, size) Py_SET_SIZE(_PyVarObject_CAST(ob), (size)) #endif @@ -226,6 +335,11 @@ typedef int (*initproc)(PyObject *, PyObject *, PyObject *); typedef PyObject *(*newfunc)(PyTypeObject *, PyObject *, PyObject *); typedef PyObject *(*allocfunc)(PyTypeObject *, Py_ssize_t); +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030c0000 // 3.12 +typedef PyObject *(*vectorcallfunc)(PyObject *callable, PyObject *const *args, + size_t nargsf, PyObject *kwnames); +#endif + typedef struct{ int slot; /* slot id, see below */ void *pfunc; /* function pointer */ @@ -255,6 +369,11 @@ PyAPI_FUNC(void *) PyType_GetModuleState(PyTypeObject *); PyAPI_FUNC(PyObject *) PyType_GetName(PyTypeObject *); PyAPI_FUNC(PyObject *) PyType_GetQualName(PyTypeObject *); #endif +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030C0000 +PyAPI_FUNC(PyObject *) PyType_FromMetaclass(PyTypeObject*, PyObject*, PyType_Spec*, PyObject*); +PyAPI_FUNC(void *) PyObject_GetTypeData(PyObject *obj, PyTypeObject *cls); +PyAPI_FUNC(Py_ssize_t) PyType_GetTypeDataSize(PyTypeObject *cls); +#endif /* Generic type check */ PyAPI_FUNC(int) PyType_IsSubtype(PyTypeObject *, PyTypeObject *); @@ -263,7 +382,7 @@ static inline int PyObject_TypeCheck(PyObject *ob, PyTypeObject *type) { return Py_IS_TYPE(ob, type) || PyType_IsSubtype(Py_TYPE(ob), type); } #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 -# define PyObject_TypeCheck(ob, type) PyObject_TypeCheck(_PyObject_CAST(ob), type) +# define PyObject_TypeCheck(ob, type) PyObject_TypeCheck(_PyObject_CAST(ob), (type)) #endif PyAPI_DATA(PyTypeObject) PyType_Type; /* built-in 'type' */ @@ -347,12 +466,21 @@ given type object has a specified feature. #ifndef Py_LIMITED_API +/* Track types initialized using _PyStaticType_InitBuiltin(). */ +#define _Py_TPFLAGS_STATIC_BUILTIN (1 << 1) + +/* Placement of weakref pointers are managed by the VM, not by the type. + * The VM will automatically set tp_weaklistoffset. + */ +#define Py_TPFLAGS_MANAGED_WEAKREF (1 << 3) + /* Placement of dict (and values) pointers are managed by the VM, not by the type. - * The VM will automatically set tp_dictoffset. Should not be used for variable sized - * classes, such as classes that extend tuple. + * The VM will automatically set tp_dictoffset. */ #define Py_TPFLAGS_MANAGED_DICT (1 << 4) +#define Py_TPFLAGS_PREHEADER (Py_TPFLAGS_MANAGED_WEAKREF | Py_TPFLAGS_MANAGED_DICT) + /* Set if instances of the type object are treated as sequences for pattern matching */ #define Py_TPFLAGS_SEQUENCE (1 << 5) /* Set if instances of the type object are treated as mappings for pattern matching */ @@ -373,11 +501,13 @@ given type object has a specified feature. #define Py_TPFLAGS_BASETYPE (1UL << 10) /* Set if the type implements the vectorcall protocol (PEP 590) */ -#ifndef Py_LIMITED_API +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030C0000 #define Py_TPFLAGS_HAVE_VECTORCALL (1UL << 11) +#ifndef Py_LIMITED_API // Backwards compatibility alias for API that was provisional in Python 3.8 #define _Py_TPFLAGS_HAVE_VECTORCALL Py_TPFLAGS_HAVE_VECTORCALL #endif +#endif /* Set if the type is 'ready' -- fully initialized */ #define Py_TPFLAGS_READY (1UL << 12) @@ -409,6 +539,9 @@ given type object has a specified feature. // subject itself (rather than a mapped attribute on it): #define _Py_TPFLAGS_MATCH_SELF (1UL << 22) +/* Items (ob_size*tp_itemsize) are found at the end of an instance's memory */ +#define Py_TPFLAGS_ITEMS_AT_END (1UL << 23) + /* These flags are used to determine if a type is a subclass. */ #define Py_TPFLAGS_LONG_SUBCLASS (1UL << 24) #define Py_TPFLAGS_LIST_SUBCLASS (1UL << 25) @@ -468,11 +601,12 @@ decision that's up to the implementer of each new type so if you want, you can count such references to the type object.) */ -#ifdef Py_REF_DEBUG -PyAPI_DATA(Py_ssize_t) _Py_RefTotal; +#if defined(Py_REF_DEBUG) && !defined(Py_LIMITED_API) PyAPI_FUNC(void) _Py_NegativeRefcount(const char *filename, int lineno, PyObject *op); -#endif /* Py_REF_DEBUG */ +PyAPI_FUNC(void) _Py_INCREF_IncRefTotal(void); +PyAPI_FUNC(void) _Py_DECREF_DecRefTotal(void); +#endif // Py_REF_DEBUG && !Py_LIMITED_API PyAPI_FUNC(void) _Py_Dealloc(PyObject *); @@ -488,52 +622,86 @@ PyAPI_FUNC(void) Py_DecRef(PyObject *); PyAPI_FUNC(void) _Py_IncRef(PyObject *); PyAPI_FUNC(void) _Py_DecRef(PyObject *); -static inline void Py_INCREF(PyObject *op) +static inline Py_ALWAYS_INLINE void Py_INCREF(PyObject *op) { -#if defined(Py_REF_DEBUG) && defined(Py_LIMITED_API) && Py_LIMITED_API+0 >= 0x030A0000 - // Stable ABI for Python 3.10 built in debug mode. +#if defined(Py_LIMITED_API) && (Py_LIMITED_API+0 >= 0x030c0000 || defined(Py_REF_DEBUG)) + // Stable ABI implements Py_INCREF() as a function call on limited C API + // version 3.12 and newer, and on Python built in debug mode. _Py_IncRef() + // was added to Python 3.10.0a7, use Py_IncRef() on older Python versions. + // Py_IncRef() accepts NULL whereas _Py_IncRef() doesn't. +# if Py_LIMITED_API+0 >= 0x030a00A7 _Py_IncRef(op); +# else + Py_IncRef(op); +# endif #else // Non-limited C API and limited C API for Python 3.9 and older access // directly PyObject.ob_refcnt. +#if SIZEOF_VOID_P > 4 + // Portable saturated add, branching on the carry flag and set low bits + PY_UINT32_T cur_refcnt = op->ob_refcnt_split[PY_BIG_ENDIAN]; + PY_UINT32_T new_refcnt = cur_refcnt + 1; + if (new_refcnt == 0) { + return; + } + op->ob_refcnt_split[PY_BIG_ENDIAN] = new_refcnt; +#else + // Explicitly check immortality against the immortal value + if (_Py_IsImmortal(op)) { + return; + } + op->ob_refcnt++; +#endif + _Py_INCREF_STAT_INC(); #ifdef Py_REF_DEBUG - _Py_RefTotal++; + _Py_INCREF_IncRefTotal(); #endif - op->ob_refcnt++; #endif } #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 # define Py_INCREF(op) Py_INCREF(_PyObject_CAST(op)) #endif - -#if defined(Py_REF_DEBUG) && defined(Py_LIMITED_API) && Py_LIMITED_API+0 >= 0x030A0000 -// Stable ABI for limited C API version 3.10 of Python debug build +#if defined(Py_LIMITED_API) && (Py_LIMITED_API+0 >= 0x030c0000 || defined(Py_REF_DEBUG)) +// Stable ABI implements Py_DECREF() as a function call on limited C API +// version 3.12 and newer, and on Python built in debug mode. _Py_DecRef() was +// added to Python 3.10.0a7, use Py_DecRef() on older Python versions. +// Py_DecRef() accepts NULL whereas _Py_IncRef() doesn't. static inline void Py_DECREF(PyObject *op) { +# if Py_LIMITED_API+0 >= 0x030a00A7 _Py_DecRef(op); +# else + Py_DecRef(op); +# endif } #define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op)) #elif defined(Py_REF_DEBUG) static inline void Py_DECREF(const char *filename, int lineno, PyObject *op) { - _Py_RefTotal--; - if (--op->ob_refcnt != 0) { - if (op->ob_refcnt < 0) { - _Py_NegativeRefcount(filename, lineno, op); - } + if (op->ob_refcnt <= 0) { + _Py_NegativeRefcount(filename, lineno, op); } - else { + if (_Py_IsImmortal(op)) { + return; + } + _Py_DECREF_STAT_INC(); + _Py_DECREF_DecRefTotal(); + if (--op->ob_refcnt == 0) { _Py_Dealloc(op); } } #define Py_DECREF(op) Py_DECREF(__FILE__, __LINE__, _PyObject_CAST(op)) #else -static inline void Py_DECREF(PyObject *op) +static inline Py_ALWAYS_INLINE void Py_DECREF(PyObject *op) { // Non-limited C API and limited C API for Python 3.9 and older access // directly PyObject.ob_refcnt. + if (_Py_IsImmortal(op)) { + return; + } + _Py_DECREF_STAT_INC(); if (--op->ob_refcnt == 0) { _Py_Dealloc(op); } @@ -575,15 +743,44 @@ static inline void Py_DECREF(PyObject *op) * one of those can't cause problems -- but in part that relies on that * Python integers aren't currently weakly referencable. Best practice is * to use Py_CLEAR() even if you can't think of a reason for why you need to. + * + * gh-98724: Use a temporary variable to only evaluate the macro argument once, + * to avoid the duplication of side effects if the argument has side effects. + * + * gh-99701: If the PyObject* type is used with casting arguments to PyObject*, + * the code can be miscompiled with strict aliasing because of type punning. + * With strict aliasing, a compiler considers that two pointers of different + * types cannot read or write the same memory which enables optimization + * opportunities. + * + * If available, use _Py_TYPEOF() to use the 'op' type for temporary variables, + * and so avoid type punning. Otherwise, use memcpy() which causes type erasure + * and so prevents the compiler to reuse an old cached 'op' value after + * Py_CLEAR(). */ -#define Py_CLEAR(op) \ - do { \ - PyObject *_py_tmp = _PyObject_CAST(op); \ - if (_py_tmp != NULL) { \ - (op) = NULL; \ - Py_DECREF(_py_tmp); \ - } \ +#ifdef _Py_TYPEOF +#define Py_CLEAR(op) \ + do { \ + _Py_TYPEOF(op)* _tmp_op_ptr = &(op); \ + _Py_TYPEOF(op) _tmp_old_op = (*_tmp_op_ptr); \ + if (_tmp_old_op != NULL) { \ + *_tmp_op_ptr = _Py_NULL; \ + Py_DECREF(_tmp_old_op); \ + } \ } while (0) +#else +#define Py_CLEAR(op) \ + do { \ + PyObject **_tmp_op_ptr = _Py_CAST(PyObject**, &(op)); \ + PyObject *_tmp_old_op = (*_tmp_op_ptr); \ + if (_tmp_old_op != NULL) { \ + PyObject *_null_ptr = _Py_NULL; \ + memcpy(_tmp_op_ptr, &_null_ptr, sizeof(PyObject*)); \ + Py_DECREF(_tmp_old_op); \ + } \ + } while (0) +#endif + /* Function to use in case the object pointer can be NULL: */ static inline void Py_XINCREF(PyObject *op) @@ -651,7 +848,7 @@ PyAPI_FUNC(int) Py_IsNone(PyObject *x); #define Py_IsNone(x) Py_Is((x), Py_None) /* Macro for returning Py_None from a function */ -#define Py_RETURN_NONE return Py_NewRef(Py_None) +#define Py_RETURN_NONE return Py_None /* Py_NotImplemented is a singleton used to signal that an operation is @@ -661,7 +858,7 @@ PyAPI_DATA(PyObject) _Py_NotImplementedStruct; /* Don't use this directly */ #define Py_NotImplemented (&_Py_NotImplementedStruct) /* Macro for returning Py_NotImplemented from a function */ -#define Py_RETURN_NOTIMPLEMENTED return Py_NewRef(Py_NotImplemented) +#define Py_RETURN_NOTIMPLEMENTED return Py_NotImplemented /* Rich comparison opcodes */ #define Py_LT 0 @@ -772,7 +969,7 @@ PyType_HasFeature(PyTypeObject *type, unsigned long feature) return ((flags & feature) != 0); } -#define PyType_FastSubclass(type, flag) PyType_HasFeature(type, flag) +#define PyType_FastSubclass(type, flag) PyType_HasFeature((type), (flag)) static inline int PyType_Check(PyObject *op) { return PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_TYPE_SUBCLASS); diff --git a/Include/objimpl.h b/Include/objimpl.h index 4fa670e7..ef871c5e 100644 --- a/Include/objimpl.h +++ b/Include/objimpl.h @@ -135,14 +135,14 @@ PyAPI_FUNC(PyVarObject *) _PyObject_NewVar(PyTypeObject *, Py_ssize_t); // Alias to PyObject_New(). In Python 3.8, PyObject_NEW() called directly // PyObject_MALLOC() with _PyObject_SIZE(). -#define PyObject_NEW(type, typeobj) PyObject_New(type, typeobj) +#define PyObject_NEW(type, typeobj) PyObject_New(type, (typeobj)) #define PyObject_NewVar(type, typeobj, n) \ ( (type *) _PyObject_NewVar((typeobj), (n)) ) // Alias to PyObject_NewVar(). In Python 3.8, PyObject_NEW_VAR() called // directly PyObject_MALLOC() with _PyObject_VAR_SIZE(). -#define PyObject_NEW_VAR(type, typeobj, n) PyObject_NewVar(type, typeobj, n) +#define PyObject_NEW_VAR(type, typeobj, n) PyObject_NewVar(type, (typeobj), (n)) /* @@ -157,6 +157,25 @@ PyAPI_FUNC(int) PyGC_Enable(void); PyAPI_FUNC(int) PyGC_Disable(void); PyAPI_FUNC(int) PyGC_IsEnabled(void); + +#if !defined(Py_LIMITED_API) +/* Visit all live GC-capable objects, similar to gc.get_objects(None). The + * supplied callback is called on every such object with the void* arg set + * to the supplied arg. Returning 0 from the callback ends iteration, returning + * 1 allows iteration to continue. Returning any other value may result in + * undefined behaviour. + * + * If new objects are (de)allocated by the callback it is undefined if they + * will be visited. + + * Garbage collection is disabled during operation. Explicitly running a + * collection in the callback may lead to undefined behaviour e.g. visiting the + * same objects multiple times or not at all. + */ +typedef int (*gcvisitobjects_t)(PyObject*, void*); +PyAPI_FUNC(void) PyUnstable_GC_VisitObjects(gcvisitobjects_t callback, void* arg); +#endif + /* Test if a type has a GC head */ #define PyType_IS_GC(t) PyType_HasFeature((t), Py_TPFLAGS_HAVE_GC) diff --git a/Include/opcode.h b/Include/opcode.h index 084d34b8..9806511b 100644 --- a/Include/opcode.h +++ b/Include/opcode.h @@ -1,4 +1,4 @@ -// Auto-generated by Tools/scripts/generate_opcode_h.py from Lib/opcode.py +// Auto-generated by Tools/build/generate_opcode_h.py from Lib/opcode.py #ifndef Py_OPCODE_H #define Py_OPCODE_H @@ -11,12 +11,17 @@ extern "C" { #define CACHE 0 #define POP_TOP 1 #define PUSH_NULL 2 +#define INTERPRETER_EXIT 3 +#define END_FOR 4 +#define END_SEND 5 #define NOP 9 -#define UNARY_POSITIVE 10 #define UNARY_NEGATIVE 11 #define UNARY_NOT 12 #define UNARY_INVERT 15 +#define RESERVED 17 #define BINARY_SUBSCR 25 +#define BINARY_SLICE 26 +#define STORE_SLICE 27 #define GET_LEN 30 #define MATCH_MAPPING 31 #define MATCH_SEQUENCE 32 @@ -30,21 +35,17 @@ extern "C" { #define BEFORE_ASYNC_WITH 52 #define BEFORE_WITH 53 #define END_ASYNC_FOR 54 +#define CLEANUP_THROW 55 #define STORE_SUBSCR 60 #define DELETE_SUBSCR 61 #define GET_ITER 68 #define GET_YIELD_FROM_ITER 69 -#define PRINT_EXPR 70 #define LOAD_BUILD_CLASS 71 #define LOAD_ASSERTION_ERROR 74 #define RETURN_GENERATOR 75 -#define LIST_TO_TUPLE 82 #define RETURN_VALUE 83 -#define IMPORT_STAR 84 #define SETUP_ANNOTATIONS 85 -#define YIELD_VALUE 86 -#define ASYNC_GEN_WRAP 87 -#define PREP_RERAISE_STAR 88 +#define LOAD_LOCALS 87 #define POP_EXCEPT 89 #define HAVE_ARGUMENT 90 #define STORE_NAME 90 @@ -68,22 +69,22 @@ extern "C" { #define IMPORT_NAME 108 #define IMPORT_FROM 109 #define JUMP_FORWARD 110 -#define JUMP_IF_FALSE_OR_POP 111 -#define JUMP_IF_TRUE_OR_POP 112 -#define POP_JUMP_FORWARD_IF_FALSE 114 -#define POP_JUMP_FORWARD_IF_TRUE 115 +#define POP_JUMP_IF_FALSE 114 +#define POP_JUMP_IF_TRUE 115 #define LOAD_GLOBAL 116 #define IS_OP 117 #define CONTAINS_OP 118 #define RERAISE 119 #define COPY 120 +#define RETURN_CONST 121 #define BINARY_OP 122 #define SEND 123 #define LOAD_FAST 124 #define STORE_FAST 125 #define DELETE_FAST 126 -#define POP_JUMP_FORWARD_IF_NOT_NONE 128 -#define POP_JUMP_FORWARD_IF_NONE 129 +#define LOAD_FAST_CHECK 127 +#define POP_JUMP_IF_NOT_NONE 128 +#define POP_JUMP_IF_NONE 129 #define RAISE_VARARGS 130 #define GET_AWAITABLE 131 #define MAKE_FUNCTION 132 @@ -95,106 +96,141 @@ extern "C" { #define STORE_DEREF 138 #define DELETE_DEREF 139 #define JUMP_BACKWARD 140 +#define LOAD_SUPER_ATTR 141 #define CALL_FUNCTION_EX 142 +#define LOAD_FAST_AND_CLEAR 143 #define EXTENDED_ARG 144 #define LIST_APPEND 145 #define SET_ADD 146 #define MAP_ADD 147 -#define LOAD_CLASSDEREF 148 #define COPY_FREE_VARS 149 +#define YIELD_VALUE 150 #define RESUME 151 #define MATCH_CLASS 152 #define FORMAT_VALUE 155 #define BUILD_CONST_KEY_MAP 156 #define BUILD_STRING 157 -#define LOAD_METHOD 160 #define LIST_EXTEND 162 #define SET_UPDATE 163 #define DICT_MERGE 164 #define DICT_UPDATE 165 -#define PRECALL 166 #define CALL 171 #define KW_NAMES 172 -#define POP_JUMP_BACKWARD_IF_NOT_NONE 173 -#define POP_JUMP_BACKWARD_IF_NONE 174 -#define POP_JUMP_BACKWARD_IF_FALSE 175 -#define POP_JUMP_BACKWARD_IF_TRUE 176 -#define BINARY_OP_ADAPTIVE 3 -#define BINARY_OP_ADD_FLOAT 4 -#define BINARY_OP_ADD_INT 5 -#define BINARY_OP_ADD_UNICODE 6 -#define BINARY_OP_INPLACE_ADD_UNICODE 7 -#define BINARY_OP_MULTIPLY_FLOAT 8 -#define BINARY_OP_MULTIPLY_INT 13 -#define BINARY_OP_SUBTRACT_FLOAT 14 -#define BINARY_OP_SUBTRACT_INT 16 -#define BINARY_SUBSCR_ADAPTIVE 17 -#define BINARY_SUBSCR_DICT 18 -#define BINARY_SUBSCR_GETITEM 19 -#define BINARY_SUBSCR_LIST_INT 20 -#define BINARY_SUBSCR_TUPLE_INT 21 -#define CALL_ADAPTIVE 22 +#define CALL_INTRINSIC_1 173 +#define CALL_INTRINSIC_2 174 +#define LOAD_FROM_DICT_OR_GLOBALS 175 +#define LOAD_FROM_DICT_OR_DEREF 176 +#define MIN_INSTRUMENTED_OPCODE 237 +#define INSTRUMENTED_LOAD_SUPER_ATTR 237 +#define INSTRUMENTED_POP_JUMP_IF_NONE 238 +#define INSTRUMENTED_POP_JUMP_IF_NOT_NONE 239 +#define INSTRUMENTED_RESUME 240 +#define INSTRUMENTED_CALL 241 +#define INSTRUMENTED_RETURN_VALUE 242 +#define INSTRUMENTED_YIELD_VALUE 243 +#define INSTRUMENTED_CALL_FUNCTION_EX 244 +#define INSTRUMENTED_JUMP_FORWARD 245 +#define INSTRUMENTED_JUMP_BACKWARD 246 +#define INSTRUMENTED_RETURN_CONST 247 +#define INSTRUMENTED_FOR_ITER 248 +#define INSTRUMENTED_POP_JUMP_IF_FALSE 249 +#define INSTRUMENTED_POP_JUMP_IF_TRUE 250 +#define INSTRUMENTED_END_FOR 251 +#define INSTRUMENTED_END_SEND 252 +#define INSTRUMENTED_INSTRUCTION 253 +#define INSTRUMENTED_LINE 254 +#define MIN_PSEUDO_OPCODE 256 +#define SETUP_FINALLY 256 +#define SETUP_CLEANUP 257 +#define SETUP_WITH 258 +#define POP_BLOCK 259 +#define JUMP 260 +#define JUMP_NO_INTERRUPT 261 +#define LOAD_METHOD 262 +#define LOAD_SUPER_METHOD 263 +#define LOAD_ZERO_SUPER_METHOD 264 +#define LOAD_ZERO_SUPER_ATTR 265 +#define STORE_FAST_MAYBE_NULL 266 +#define MAX_PSEUDO_OPCODE 266 +#define BINARY_OP_ADD_FLOAT 6 +#define BINARY_OP_ADD_INT 7 +#define BINARY_OP_ADD_UNICODE 8 +#define BINARY_OP_INPLACE_ADD_UNICODE 10 +#define BINARY_OP_MULTIPLY_FLOAT 13 +#define BINARY_OP_MULTIPLY_INT 14 +#define BINARY_OP_SUBTRACT_FLOAT 16 +#define BINARY_OP_SUBTRACT_INT 18 +#define BINARY_SUBSCR_DICT 19 +#define BINARY_SUBSCR_GETITEM 20 +#define BINARY_SUBSCR_LIST_INT 21 +#define BINARY_SUBSCR_TUPLE_INT 22 #define CALL_PY_EXACT_ARGS 23 #define CALL_PY_WITH_DEFAULTS 24 -#define COMPARE_OP_ADAPTIVE 26 -#define COMPARE_OP_FLOAT_JUMP 27 -#define COMPARE_OP_INT_JUMP 28 -#define COMPARE_OP_STR_JUMP 29 -#define EXTENDED_ARG_QUICK 34 -#define JUMP_BACKWARD_QUICK 38 -#define LOAD_ATTR_ADAPTIVE 39 -#define LOAD_ATTR_INSTANCE_VALUE 40 -#define LOAD_ATTR_MODULE 41 -#define LOAD_ATTR_SLOT 42 -#define LOAD_ATTR_WITH_HINT 43 -#define LOAD_CONST__LOAD_FAST 44 -#define LOAD_FAST__LOAD_CONST 45 -#define LOAD_FAST__LOAD_FAST 46 -#define LOAD_GLOBAL_ADAPTIVE 47 -#define LOAD_GLOBAL_BUILTIN 48 -#define LOAD_GLOBAL_MODULE 55 -#define LOAD_METHOD_ADAPTIVE 56 -#define LOAD_METHOD_CLASS 57 -#define LOAD_METHOD_MODULE 58 -#define LOAD_METHOD_NO_DICT 59 -#define LOAD_METHOD_WITH_DICT 62 -#define LOAD_METHOD_WITH_VALUES 63 -#define PRECALL_ADAPTIVE 64 -#define PRECALL_BOUND_METHOD 65 -#define PRECALL_BUILTIN_CLASS 66 -#define PRECALL_BUILTIN_FAST_WITH_KEYWORDS 67 -#define PRECALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS 72 -#define PRECALL_NO_KW_BUILTIN_FAST 73 -#define PRECALL_NO_KW_BUILTIN_O 76 -#define PRECALL_NO_KW_ISINSTANCE 77 -#define PRECALL_NO_KW_LEN 78 -#define PRECALL_NO_KW_LIST_APPEND 79 -#define PRECALL_NO_KW_METHOD_DESCRIPTOR_FAST 80 -#define PRECALL_NO_KW_METHOD_DESCRIPTOR_NOARGS 81 -#define PRECALL_NO_KW_METHOD_DESCRIPTOR_O 113 -#define PRECALL_NO_KW_STR_1 121 -#define PRECALL_NO_KW_TUPLE_1 127 -#define PRECALL_NO_KW_TYPE_1 141 -#define PRECALL_PYFUNC 143 -#define RESUME_QUICK 150 -#define STORE_ATTR_ADAPTIVE 153 -#define STORE_ATTR_INSTANCE_VALUE 154 -#define STORE_ATTR_SLOT 158 -#define STORE_ATTR_WITH_HINT 159 -#define STORE_FAST__LOAD_FAST 161 -#define STORE_FAST__STORE_FAST 167 -#define STORE_SUBSCR_ADAPTIVE 168 -#define STORE_SUBSCR_DICT 169 -#define STORE_SUBSCR_LIST_INT 170 -#define UNPACK_SEQUENCE_ADAPTIVE 177 -#define UNPACK_SEQUENCE_LIST 178 -#define UNPACK_SEQUENCE_TUPLE 179 -#define UNPACK_SEQUENCE_TWO_TUPLE 180 -#define DO_TRACING 255 +#define CALL_BOUND_METHOD_EXACT_ARGS 28 +#define CALL_BUILTIN_CLASS 29 +#define CALL_BUILTIN_FAST_WITH_KEYWORDS 34 +#define CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS 38 +#define CALL_NO_KW_BUILTIN_FAST 39 +#define CALL_NO_KW_BUILTIN_O 40 +#define CALL_NO_KW_ISINSTANCE 41 +#define CALL_NO_KW_LEN 42 +#define CALL_NO_KW_LIST_APPEND 43 +#define CALL_NO_KW_METHOD_DESCRIPTOR_FAST 44 +#define CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS 45 +#define CALL_NO_KW_METHOD_DESCRIPTOR_O 46 +#define CALL_NO_KW_STR_1 47 +#define CALL_NO_KW_TUPLE_1 48 +#define CALL_NO_KW_TYPE_1 56 +#define COMPARE_OP_FLOAT 57 +#define COMPARE_OP_INT 58 +#define COMPARE_OP_STR 59 +#define FOR_ITER_LIST 62 +#define FOR_ITER_TUPLE 63 +#define FOR_ITER_RANGE 64 +#define FOR_ITER_GEN 65 +#define LOAD_SUPER_ATTR_ATTR 66 +#define LOAD_SUPER_ATTR_METHOD 67 +#define LOAD_ATTR_CLASS 70 +#define LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN 72 +#define LOAD_ATTR_INSTANCE_VALUE 73 +#define LOAD_ATTR_MODULE 76 +#define LOAD_ATTR_PROPERTY 77 +#define LOAD_ATTR_SLOT 78 +#define LOAD_ATTR_WITH_HINT 79 +#define LOAD_ATTR_METHOD_LAZY_DICT 80 +#define LOAD_ATTR_METHOD_NO_DICT 81 +#define LOAD_ATTR_METHOD_WITH_VALUES 82 +#define LOAD_CONST__LOAD_FAST 84 +#define LOAD_FAST__LOAD_CONST 86 +#define LOAD_FAST__LOAD_FAST 88 +#define LOAD_GLOBAL_BUILTIN 111 +#define LOAD_GLOBAL_MODULE 112 +#define STORE_ATTR_INSTANCE_VALUE 113 +#define STORE_ATTR_SLOT 148 +#define STORE_ATTR_WITH_HINT 153 +#define STORE_FAST__LOAD_FAST 154 +#define STORE_FAST__STORE_FAST 158 +#define STORE_SUBSCR_DICT 159 +#define STORE_SUBSCR_LIST_INT 160 +#define UNPACK_SEQUENCE_LIST 161 +#define UNPACK_SEQUENCE_TUPLE 166 +#define UNPACK_SEQUENCE_TWO_TUPLE 167 +#define SEND_GEN 168 + +#define HAS_ARG(op) ((((op) >= HAVE_ARGUMENT) && (!IS_PSEUDO_OPCODE(op)))\ + || ((op) == JUMP) \ + || ((op) == JUMP_NO_INTERRUPT) \ + || ((op) == LOAD_METHOD) \ + || ((op) == LOAD_SUPER_METHOD) \ + || ((op) == LOAD_ZERO_SUPER_METHOD) \ + || ((op) == LOAD_ZERO_SUPER_ATTR) \ + || ((op) == STORE_FAST_MAYBE_NULL) \ + ) #define HAS_CONST(op) (false\ - || ((op) == 100) \ - || ((op) == 172) \ + || ((op) == LOAD_CONST) \ + || ((op) == RETURN_CONST) \ + || ((op) == KW_NAMES) \ ) #define NB_ADD 0 @@ -224,11 +260,10 @@ extern "C" { #define NB_INPLACE_TRUE_DIVIDE 24 #define NB_INPLACE_XOR 25 -#define HAS_ARG(op) ((op) >= HAVE_ARGUMENT) +/* Defined in Lib/opcode.py */ +#define ENABLE_SPECIALIZATION 1 -/* Reserve some bytecodes for internal use in the compiler. - * The value of 240 is arbitrary. */ -#define IS_ARTIFICIAL(op) ((op) > 240) +#define IS_PSEUDO_OPCODE(op) (((op) >= MIN_PSEUDO_OPCODE) && ((op) <= MAX_PSEUDO_OPCODE)) #ifdef __cplusplus } diff --git a/Include/patchlevel.h b/Include/patchlevel.h index 806e0441..bb459864 100644 --- a/Include/patchlevel.h +++ b/Include/patchlevel.h @@ -17,13 +17,13 @@ /* Version parsed out into numeric values */ /*--start constants--*/ #define PY_MAJOR_VERSION 3 -#define PY_MINOR_VERSION 11 -#define PY_MICRO_VERSION 2 +#define PY_MINOR_VERSION 12 +#define PY_MICRO_VERSION 0 #define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_FINAL #define PY_RELEASE_SERIAL 0 /* Version as a string */ -#define PY_VERSION "3.11.2" +#define PY_VERSION "3.12.0" /*--end constants--*/ /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. diff --git a/Include/py_curses.h b/Include/py_curses.h index b2c7f1bb..e46b08e9 100644 --- a/Include/py_curses.h +++ b/Include/py_curses.h @@ -64,7 +64,7 @@ typedef struct { char *encoding; } PyCursesWindowObject; -#define PyCursesWindow_Check(v) Py_IS_TYPE(v, &PyCursesWindow_Type) +#define PyCursesWindow_Check(v) Py_IS_TYPE((v), &PyCursesWindow_Type) #define PyCurses_CAPSULE_NAME "_curses._C_API" diff --git a/Include/pybuffer.h b/Include/pybuffer.h index 6893505e..ca1c6058 100644 --- a/Include/pybuffer.h +++ b/Include/pybuffer.h @@ -32,6 +32,9 @@ typedef struct { void *internal; } Py_buffer; +typedef int (*getbufferproc)(PyObject *, Py_buffer *, int); +typedef void (*releasebufferproc)(PyObject *, Py_buffer *); + /* Return 1 if the getbuffer function is available, otherwise return 0. */ PyAPI_FUNC(int) PyObject_CheckBuffer(PyObject *obj); @@ -101,7 +104,7 @@ PyAPI_FUNC(void) PyBuffer_Release(Py_buffer *view); /* Maximum number of dimensions */ #define PyBUF_MAX_NDIM 64 -/* Flags for getting buffers */ +/* Flags for getting buffers. Keep these in sync with inspect.BufferFlags. */ #define PyBUF_SIMPLE 0 #define PyBUF_WRITABLE 0x0001 diff --git a/Include/pycapsule.h b/Include/pycapsule.h index fb5d503f..929a9a68 100644 --- a/Include/pycapsule.h +++ b/Include/pycapsule.h @@ -22,7 +22,7 @@ PyAPI_DATA(PyTypeObject) PyCapsule_Type; typedef void (*PyCapsule_Destructor)(PyObject *); -#define PyCapsule_CheckExact(op) Py_IS_TYPE(op, &PyCapsule_Type) +#define PyCapsule_CheckExact(op) Py_IS_TYPE((op), &PyCapsule_Type) PyAPI_FUNC(PyObject *) PyCapsule_New( diff --git a/Include/pydtrace.h b/Include/pydtrace.h index 75f8e7f7..e197d366 100644 --- a/Include/pydtrace.h +++ b/Include/pydtrace.h @@ -12,7 +12,7 @@ extern "C" { /* pydtrace_probes.h, on systems with DTrace, is auto-generated to include `PyDTrace_{PROBE}` and `PyDTrace_{PROBE}_ENABLED()` macros for every probe - defined in pydtrace_provider.d. + defined in pydtrace.d. Calling these functions must be guarded by a `PyDTrace_{PROBE}_ENABLED()` check to minimize performance impact when probing is off. For example: diff --git a/Include/pyerrors.h b/Include/pyerrors.h index 34e3de33..d089fa71 100644 --- a/Include/pyerrors.h +++ b/Include/pyerrors.h @@ -18,6 +18,8 @@ PyAPI_FUNC(PyObject *) PyErr_Occurred(void); PyAPI_FUNC(void) PyErr_Clear(void); PyAPI_FUNC(void) PyErr_Fetch(PyObject **, PyObject **, PyObject **); PyAPI_FUNC(void) PyErr_Restore(PyObject *, PyObject *, PyObject *); +PyAPI_FUNC(PyObject *) PyErr_GetRaisedException(void); +PyAPI_FUNC(void) PyErr_SetRaisedException(PyObject *); #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030b0000 PyAPI_FUNC(PyObject*) PyErr_GetHandledException(void); PyAPI_FUNC(void) PyErr_SetHandledException(PyObject *); @@ -51,6 +53,10 @@ PyAPI_FUNC(void) PyException_SetCause(PyObject *, PyObject *); PyAPI_FUNC(PyObject *) PyException_GetContext(PyObject *); PyAPI_FUNC(void) PyException_SetContext(PyObject *, PyObject *); + +PyAPI_FUNC(PyObject *) PyException_GetArgs(PyObject *); +PyAPI_FUNC(void) PyException_SetArgs(PyObject *, PyObject *); + /* */ #define PyExceptionClass_Check(x) \ @@ -62,10 +68,10 @@ PyAPI_FUNC(void) PyException_SetContext(PyObject *, PyObject *); PyAPI_FUNC(const char *) PyExceptionClass_Name(PyObject *); -#define PyExceptionInstance_Class(x) ((PyObject*)Py_TYPE(x)) +#define PyExceptionInstance_Class(x) _PyObject_CAST(Py_TYPE(x)) #define _PyBaseExceptionGroup_Check(x) \ - PyObject_TypeCheck(x, (PyTypeObject *)PyExc_BaseExceptionGroup) + PyObject_TypeCheck((x), (PyTypeObject *)PyExc_BaseExceptionGroup) /* Predefined exceptions */ diff --git a/Include/pymacconfig.h b/Include/pymacconfig.h index 9dde11bd..00459a03 100644 --- a/Include/pymacconfig.h +++ b/Include/pymacconfig.h @@ -84,18 +84,6 @@ # define HAVE_GCC_ASM_FOR_X87 #endif - /* - * The definition in pyconfig.h is only valid on the OS release - * where configure ran on and not necessarily for all systems where - * the executable can be used on. - * - * Specifically: OSX 10.4 has limited supported for '%zd', while - * 10.5 has full support for '%zd'. A binary built on 10.5 won't - * work properly on 10.4 unless we suppress the definition - * of PY_FORMAT_SIZE_T - */ -#undef PY_FORMAT_SIZE_T - #endif /* defined(_APPLE__) */ diff --git a/Include/pymacro.h b/Include/pymacro.h index 90ad8f07..342d2a7b 100644 --- a/Include/pymacro.h +++ b/Include/pymacro.h @@ -3,20 +3,23 @@ // gh-91782: On FreeBSD 12, if the _POSIX_C_SOURCE and _XOPEN_SOURCE macros are // defined, <sys/cdefs.h> disables C11 support and <assert.h> does not define -// the static_assert() macro. Define the static_assert() macro in Python until -// <sys/cdefs.h> suports C11: +// the static_assert() macro. // https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=255290 -#if defined(__FreeBSD__) && !defined(static_assert) -# define static_assert _Static_assert -#endif - -// static_assert is defined in glibc from version 2.16. Before it requires -// compiler support (gcc >= 4.6) and is called _Static_assert. -// In C++ 11 static_assert is a keyword, redefining is undefined behaviour. -#if (defined(__GLIBC__) \ - && (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ <= 16)) \ - && !(defined(__cplusplus) && __cplusplus >= 201103L) \ - && !defined(static_assert)) +// +// macOS <= 10.10 doesn't define static_assert in assert.h at all despite +// having C11 compiler support. +// +// static_assert is defined in glibc from version 2.16. Compiler support for +// the C11 _Static_assert keyword is in gcc >= 4.6. +// +// MSVC makes static_assert a keyword in C11-17, contrary to the standards. +// +// In C++11 and C2x, static_assert is a keyword, redefining is undefined +// behaviour. So only define if building as C (if __STDC_VERSION__ is defined), +// not C++, and only for C11-17. +#if !defined(static_assert) && (defined(__GNUC__) || defined(__clang__)) \ + && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L \ + && __STDC_VERSION__ <= 201710L # define static_assert _Static_assert #endif @@ -152,4 +155,9 @@ // For example, "int x; _Py_RVALUE(x) = 1;" fails with a compiler error. #define _Py_RVALUE(EXPR) ((void)0, (EXPR)) +// Return non-zero if the type is signed, return zero if it's unsigned. +// Use "<= 0" rather than "< 0" to prevent the compiler warning: +// "comparison of unsigned expression in '< 0' is always false". +#define _Py_IS_TYPE_SIGNED(type) ((type)(-1) <= 0) + #endif /* Py_PYMACRO_H */ diff --git a/Include/pymath.h b/Include/pymath.h index 772b67e4..4c1e3d99 100644 --- a/Include/pymath.h +++ b/Include/pymath.h @@ -39,27 +39,24 @@ // Return 1 if float or double arg is neither infinite nor NAN, else 0. #define Py_IS_FINITE(X) isfinite(X) -/* HUGE_VAL is supposed to expand to a positive double infinity. Python - * uses Py_HUGE_VAL instead because some platforms are broken in this - * respect. We used to embed code in pyport.h to try to worm around that, - * but different platforms are broken in conflicting ways. If you're on - * a platform where HUGE_VAL is defined incorrectly, fiddle your Python - * config to #define Py_HUGE_VAL to something that works on your platform. +// Py_INFINITY: Value that evaluates to a positive double infinity. +#ifndef Py_INFINITY +# define Py_INFINITY ((double)INFINITY) +#endif + +/* Py_HUGE_VAL should always be the same as Py_INFINITY. But historically + * this was not reliable and Python did not require IEEE floats and C99 + * conformity. Prefer Py_INFINITY for new code. */ #ifndef Py_HUGE_VAL # define Py_HUGE_VAL HUGE_VAL #endif -// Py_NAN: Value that evaluates to a quiet Not-a-Number (NaN). +/* Py_NAN: Value that evaluates to a quiet Not-a-Number (NaN). The sign is + * undefined and normally not relevant, but e.g. fixed for float("nan"). + */ #if !defined(Py_NAN) -# if _Py__has_builtin(__builtin_nan) - // Built-in implementation of the ISO C99 function nan(): quiet NaN. -# define Py_NAN (__builtin_nan("")) -#else - // Use C99 NAN constant: quiet Not-A-Number. - // NAN is a float, Py_NAN is a double: cast to double. # define Py_NAN ((double)NAN) -# endif #endif #endif /* Py_PYMATH_H */ diff --git a/Include/pymem.h b/Include/pymem.h index c15ad10d..e8826457 100644 --- a/Include/pymem.h +++ b/Include/pymem.h @@ -82,13 +82,13 @@ PyAPI_FUNC(void) PyMem_Free(void *ptr); // Deprecated aliases only kept for backward compatibility. // PyMem_Del and PyMem_DEL are defined with no parameter to be able to use // them as function pointers (ex: dealloc = PyMem_Del). -#define PyMem_MALLOC(n) PyMem_Malloc(n) -#define PyMem_NEW(type, n) PyMem_New(type, n) -#define PyMem_REALLOC(p, n) PyMem_Realloc(p, n) -#define PyMem_RESIZE(p, type, n) PyMem_Resize(p, type, n) -#define PyMem_FREE(p) PyMem_Free(p) -#define PyMem_Del PyMem_Free -#define PyMem_DEL PyMem_Free +#define PyMem_MALLOC(n) PyMem_Malloc((n)) +#define PyMem_NEW(type, n) PyMem_New(type, (n)) +#define PyMem_REALLOC(p, n) PyMem_Realloc((p), (n)) +#define PyMem_RESIZE(p, type, n) PyMem_Resize((p), type, (n)) +#define PyMem_FREE(p) PyMem_Free((p)) +#define PyMem_Del(p) PyMem_Free((p)) +#define PyMem_DEL(p) PyMem_Free((p)) #ifndef Py_LIMITED_API diff --git a/Include/pyport.h b/Include/pyport.h index 93250f4e..35eca723 100644 --- a/Include/pyport.h +++ b/Include/pyport.h @@ -153,32 +153,10 @@ typedef Py_ssize_t Py_ssize_clean_t; /* Largest possible value of size_t. */ #define PY_SIZE_MAX SIZE_MAX -/* Macro kept for backward compatibility: use "z" in new code. +/* Macro kept for backward compatibility: use directly "z" in new code. * - * PY_FORMAT_SIZE_T is a platform-specific modifier for use in a printf - * format to convert an argument with the width of a size_t or Py_ssize_t. - * C99 introduced "z" for this purpose, but old MSVCs had not supported it. - * Since MSVC supports "z" since (at least) 2015, we can just use "z" - * for new code. - * - * These "high level" Python format functions interpret "z" correctly on - * all platforms (Python interprets the format string itself, and does whatever - * the platform C requires to convert a size_t/Py_ssize_t argument): - * - * PyBytes_FromFormat - * PyErr_Format - * PyBytes_FromFormatV - * PyUnicode_FromFormatV - * - * Lower-level uses require that you interpolate the correct format modifier - * yourself (e.g., calling printf, fprintf, sprintf, PyOS_snprintf); for - * example, - * - * Py_ssize_t index; - * fprintf(stderr, "index %" PY_FORMAT_SIZE_T "d sucks\n", index); - * - * That will expand to %zd or to something else correct for a Py_ssize_t on - * the platform. + * PY_FORMAT_SIZE_T is a modifier for use in a printf format to convert an + * argument with the width of a size_t or Py_ssize_t: "z" (C99). */ #ifndef PY_FORMAT_SIZE_T # define PY_FORMAT_SIZE_T "z" @@ -206,7 +184,6 @@ typedef Py_ssize_t Py_ssize_clean_t; # define Py_LOCAL_INLINE(type) static inline type #endif -// bpo-28126: Py_MEMCPY is kept for backwards compatibility, #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000 # define Py_MEMCPY memcpy #endif @@ -269,6 +246,10 @@ typedef Py_ssize_t Py_ssize_clean_t; #define S_ISCHR(x) (((x) & S_IFMT) == S_IFCHR) #endif +#ifndef S_ISLNK +#define S_ISLNK(x) (((x) & S_IFMT) == S_IFLNK) +#endif + #ifdef __cplusplus /* Move this down here since some C++ #include's don't like to be included inside an extern "C" */ @@ -341,6 +322,15 @@ extern "C" { #define Py_DEPRECATED(VERSION_UNUSED) #endif +// _Py_DEPRECATED_EXTERNALLY(version) +// Deprecated outside CPython core. +#ifdef Py_BUILD_CORE +#define _Py_DEPRECATED_EXTERNALLY(VERSION_UNUSED) +#else +#define _Py_DEPRECATED_EXTERNALLY(version) Py_DEPRECATED(version) +#endif + + #if defined(__clang__) #define _Py_COMP_DIAG_PUSH _Pragma("clang diagnostic push") #define _Py_COMP_DIAG_IGNORE_DEPR_DECLS \ @@ -439,11 +429,6 @@ Please be conservative with adding new ones, document them and enclose them in platform-specific #ifdefs. **************************************************************************/ -#ifdef SOLARIS -/* Unchecked */ -extern int gethostname(char *, int); -#endif - #ifdef HAVE__GETPTY #include <sys/types.h> /* we need to import mode_t */ extern char * _getpty(int *, int, mode_t, int); @@ -672,6 +657,27 @@ extern char * _getpty(int *, int, mode_t, int); # define WITH_THREAD #endif +#ifdef WITH_THREAD +# ifdef Py_BUILD_CORE +# ifdef HAVE_THREAD_LOCAL +# error "HAVE_THREAD_LOCAL is already defined" +# endif +# define HAVE_THREAD_LOCAL 1 +# ifdef thread_local +# define _Py_thread_local thread_local +# elif __STDC_VERSION__ >= 201112L && !defined(__STDC_NO_THREADS__) +# define _Py_thread_local _Thread_local +# elif defined(_MSC_VER) /* AKA NT_THREADS */ +# define _Py_thread_local __declspec(thread) +# elif defined(__GNUC__) /* includes clang */ +# define _Py_thread_local __thread +# else + // fall back to the PyThread_tss_*() API, or ignore. +# undef HAVE_THREAD_LOCAL +# endif +# endif +#endif + /* Check that ALT_SOABI is consistent with Py_TRACE_REFS: ./configure --with-trace-refs should must be used to define Py_TRACE_REFS */ #if defined(ALT_SOABI) && defined(Py_TRACE_REFS) @@ -720,6 +726,15 @@ extern char * _getpty(int *, int, mode_t, int); # define _Py__has_builtin(x) 0 #endif +// _Py_TYPEOF(expr) gets the type of an expression. +// +// Example: _Py_TYPEOF(x) x_copy = (x); +// +// The macro is only defined if GCC or clang compiler is used. +#if defined(__GNUC__) || defined(__clang__) +# define _Py_TYPEOF(expr) __typeof__(expr) +#endif + /* A convenient way for code to know if sanitizers are enabled. */ #if defined(__has_feature) @@ -739,4 +754,21 @@ extern char * _getpty(int *, int, mode_t, int); # endif #endif + +/* AIX has __bool__ redefined in it's system header file. */ +#if defined(_AIX) && defined(__bool__) +#undef __bool__ +#endif + +// Make sure we have maximum alignment, even if the current compiler +// does not support max_align_t. Note that: +// - Autoconf reports alignment of unknown types to 0. +// - 'long double' has maximum alignment on *most* platforms, +// looks like the best we can do for pre-C11 compilers. +// - The value is tested, see test_alignof_max_align_t +#if !defined(ALIGNOF_MAX_ALIGN_T) || ALIGNOF_MAX_ALIGN_T == 0 +# undef ALIGNOF_MAX_ALIGN_T +# define ALIGNOF_MAX_ALIGN_T _Alignof(long double) +#endif + #endif /* Py_PYPORT_H */ diff --git a/Include/pystats.h b/Include/pystats.h new file mode 100644 index 00000000..4b961bad --- /dev/null +++ b/Include/pystats.h @@ -0,0 +1,110 @@ + + +#ifndef Py_PYSTATS_H +#define Py_PYSTATS_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef Py_STATS + +#define SPECIALIZATION_FAILURE_KINDS 36 + +/* Stats for determining who is calling PyEval_EvalFrame */ +#define EVAL_CALL_TOTAL 0 +#define EVAL_CALL_VECTOR 1 +#define EVAL_CALL_GENERATOR 2 +#define EVAL_CALL_LEGACY 3 +#define EVAL_CALL_FUNCTION_VECTORCALL 4 +#define EVAL_CALL_BUILD_CLASS 5 +#define EVAL_CALL_SLOT 6 +#define EVAL_CALL_FUNCTION_EX 7 +#define EVAL_CALL_API 8 +#define EVAL_CALL_METHOD 9 + +#define EVAL_CALL_KINDS 10 + +typedef struct _specialization_stats { + uint64_t success; + uint64_t failure; + uint64_t hit; + uint64_t deferred; + uint64_t miss; + uint64_t deopt; + uint64_t failure_kinds[SPECIALIZATION_FAILURE_KINDS]; +} SpecializationStats; + +typedef struct _opcode_stats { + SpecializationStats specialization; + uint64_t execution_count; + uint64_t pair_count[256]; +} OpcodeStats; + +typedef struct _call_stats { + uint64_t inlined_py_calls; + uint64_t pyeval_calls; + uint64_t frames_pushed; + uint64_t frame_objects_created; + uint64_t eval_calls[EVAL_CALL_KINDS]; +} CallStats; + +typedef struct _object_stats { + uint64_t increfs; + uint64_t decrefs; + uint64_t interpreter_increfs; + uint64_t interpreter_decrefs; + uint64_t allocations; + uint64_t allocations512; + uint64_t allocations4k; + uint64_t allocations_big; + uint64_t frees; + uint64_t to_freelist; + uint64_t from_freelist; + uint64_t new_values; + uint64_t dict_materialized_on_request; + uint64_t dict_materialized_new_key; + uint64_t dict_materialized_too_big; + uint64_t dict_materialized_str_subclass; + uint64_t type_cache_hits; + uint64_t type_cache_misses; + uint64_t type_cache_dunder_hits; + uint64_t type_cache_dunder_misses; + uint64_t type_cache_collisions; +} ObjectStats; + +typedef struct _stats { + OpcodeStats opcode_stats[256]; + CallStats call_stats; + ObjectStats object_stats; +} PyStats; + + +PyAPI_DATA(PyStats) _py_stats_struct; +PyAPI_DATA(PyStats *) _py_stats; + +extern void _Py_StatsClear(void); +extern void _Py_PrintSpecializationStats(int to_file); + +#ifdef _PY_INTERPRETER + +#define _Py_INCREF_STAT_INC() do { if (_py_stats) _py_stats->object_stats.interpreter_increfs++; } while (0) +#define _Py_DECREF_STAT_INC() do { if (_py_stats) _py_stats->object_stats.interpreter_decrefs++; } while (0) + +#else + +#define _Py_INCREF_STAT_INC() do { if (_py_stats) _py_stats->object_stats.increfs++; } while (0) +#define _Py_DECREF_STAT_INC() do { if (_py_stats) _py_stats->object_stats.decrefs++; } while (0) + +#endif + +#else + +#define _Py_INCREF_STAT_INC() ((void)0) +#define _Py_DECREF_STAT_INC() ((void)0) + +#endif // !Py_STATS + +#ifdef __cplusplus +} +#endif +#endif /* !Py_PYSTATs_H */ diff --git a/Include/pythonrun.h b/Include/pythonrun.h index 1b208b73..154c7450 100644 --- a/Include/pythonrun.h +++ b/Include/pythonrun.h @@ -13,6 +13,10 @@ PyAPI_FUNC(void) PyErr_Print(void); PyAPI_FUNC(void) PyErr_PrintEx(int); PyAPI_FUNC(void) PyErr_Display(PyObject *, PyObject *, PyObject *); +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030C0000 +PyAPI_FUNC(void) PyErr_DisplayException(PyObject *); +#endif + /* Stuff with no proper home (yet) */ PyAPI_DATA(int) (*PyOS_InputHook)(void); diff --git a/Include/pythread.h b/Include/pythread.h index a4832908..63714437 100644 --- a/Include/pythread.h +++ b/Include/pythread.h @@ -20,7 +20,9 @@ PyAPI_FUNC(unsigned long) PyThread_start_new_thread(void (*)(void *), void *); PyAPI_FUNC(void) _Py_NO_RETURN PyThread_exit_thread(void); PyAPI_FUNC(unsigned long) PyThread_get_thread_ident(void); -#if defined(__APPLE__) || defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(_WIN32) || defined(_AIX) +#if (defined(__APPLE__) || defined(__linux__) || defined(_WIN32) \ + || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) \ + || defined(__DragonFly__) || defined(_AIX)) #define PY_HAVE_THREAD_NATIVE_ID PyAPI_FUNC(unsigned long) PyThread_get_thread_native_id(void); #endif diff --git a/Include/rangeobject.h b/Include/rangeobject.h index d6af8473..d46ce7cd 100644 --- a/Include/rangeobject.h +++ b/Include/rangeobject.h @@ -19,7 +19,7 @@ PyAPI_DATA(PyTypeObject) PyRange_Type; PyAPI_DATA(PyTypeObject) PyRangeIter_Type; PyAPI_DATA(PyTypeObject) PyLongRangeIter_Type; -#define PyRange_Check(op) Py_IS_TYPE(op, &PyRange_Type) +#define PyRange_Check(op) Py_IS_TYPE((op), &PyRange_Type) #ifdef __cplusplus } diff --git a/Include/setobject.h b/Include/setobject.h index fdad7064..62c9e6b1 100644 --- a/Include/setobject.h +++ b/Include/setobject.h @@ -20,21 +20,21 @@ PyAPI_FUNC(int) PySet_Discard(PyObject *set, PyObject *key); PyAPI_FUNC(PyObject *) PySet_Pop(PyObject *set); PyAPI_FUNC(Py_ssize_t) PySet_Size(PyObject *anyset); -#define PyFrozenSet_CheckExact(ob) Py_IS_TYPE(ob, &PyFrozenSet_Type) +#define PyFrozenSet_CheckExact(ob) Py_IS_TYPE((ob), &PyFrozenSet_Type) #define PyFrozenSet_Check(ob) \ - (Py_IS_TYPE(ob, &PyFrozenSet_Type) || \ + (Py_IS_TYPE((ob), &PyFrozenSet_Type) || \ PyType_IsSubtype(Py_TYPE(ob), &PyFrozenSet_Type)) #define PyAnySet_CheckExact(ob) \ - (Py_IS_TYPE(ob, &PySet_Type) || Py_IS_TYPE(ob, &PyFrozenSet_Type)) + (Py_IS_TYPE((ob), &PySet_Type) || Py_IS_TYPE((ob), &PyFrozenSet_Type)) #define PyAnySet_Check(ob) \ - (Py_IS_TYPE(ob, &PySet_Type) || Py_IS_TYPE(ob, &PyFrozenSet_Type) || \ + (Py_IS_TYPE((ob), &PySet_Type) || Py_IS_TYPE((ob), &PyFrozenSet_Type) || \ PyType_IsSubtype(Py_TYPE(ob), &PySet_Type) || \ PyType_IsSubtype(Py_TYPE(ob), &PyFrozenSet_Type)) #define PySet_CheckExact(op) Py_IS_TYPE(op, &PySet_Type) #define PySet_Check(ob) \ - (Py_IS_TYPE(ob, &PySet_Type) || \ + (Py_IS_TYPE((ob), &PySet_Type) || \ PyType_IsSubtype(Py_TYPE(ob), &PySet_Type)) #ifndef Py_LIMITED_API diff --git a/Include/sliceobject.h b/Include/sliceobject.h index 2c889508..c13863f2 100644 --- a/Include/sliceobject.h +++ b/Include/sliceobject.h @@ -28,7 +28,7 @@ typedef struct { PyAPI_DATA(PyTypeObject) PySlice_Type; PyAPI_DATA(PyTypeObject) PyEllipsis_Type; -#define PySlice_Check(op) Py_IS_TYPE(op, &PySlice_Type) +#define PySlice_Check(op) Py_IS_TYPE((op), &PySlice_Type) PyAPI_FUNC(PyObject *) PySlice_New(PyObject* start, PyObject* stop, PyObject* step); diff --git a/Include/structmember.h b/Include/structmember.h index 65a777d5..f6e8fd82 100644 --- a/Include/structmember.h +++ b/Include/structmember.h @@ -5,69 +5,50 @@ extern "C" { #endif -/* Interface to map C struct members to Python object attributes */ - -#include <stddef.h> /* For offsetof */ - -/* An array of PyMemberDef structures defines the name, type and offset - of selected members of a C structure. These can be read by - PyMember_GetOne() and set by PyMember_SetOne() (except if their READONLY - flag is set). The array must be terminated with an entry whose name - pointer is NULL. */ - -struct PyMemberDef { - const char *name; - int type; - Py_ssize_t offset; - int flags; - const char *doc; -}; +/* Interface to map C struct members to Python object attributes + * + * This header is deprecated: new code should not use stuff from here. + * New definitions are in descrobject.h. + * + * However, there's nothing wrong with old code continuing to use it, + * and there's not much mainenance overhead in maintaining a few aliases. + * So, don't be too eager to convert old code. + * + * It uses names not prefixed with Py_. + * It is also *not* included from Python.h and must be included individually. + */ + +#include <stddef.h> /* For offsetof (not always provided by Python.h) */ /* Types */ -#define T_SHORT 0 -#define T_INT 1 -#define T_LONG 2 -#define T_FLOAT 3 -#define T_DOUBLE 4 -#define T_STRING 5 -#define T_OBJECT 6 -/* XXX the ordering here is weird for binary compatibility */ -#define T_CHAR 7 /* 1-character string */ -#define T_BYTE 8 /* 8-bit signed int */ -/* unsigned variants: */ -#define T_UBYTE 9 -#define T_USHORT 10 -#define T_UINT 11 -#define T_ULONG 12 - -/* Added by Jack: strings contained in the structure */ -#define T_STRING_INPLACE 13 - -/* Added by Lillo: bools contained in the structure (assumed char) */ -#define T_BOOL 14 - -#define T_OBJECT_EX 16 /* Like T_OBJECT, but raises AttributeError - when the value is NULL, instead of - converting to None. */ -#define T_LONGLONG 17 -#define T_ULONGLONG 18 - -#define T_PYSSIZET 19 /* Py_ssize_t */ -#define T_NONE 20 /* Value is always None */ - +#define T_SHORT Py_T_SHORT +#define T_INT Py_T_INT +#define T_LONG Py_T_LONG +#define T_FLOAT Py_T_FLOAT +#define T_DOUBLE Py_T_DOUBLE +#define T_STRING Py_T_STRING +#define T_OBJECT _Py_T_OBJECT +#define T_CHAR Py_T_CHAR +#define T_BYTE Py_T_BYTE +#define T_UBYTE Py_T_UBYTE +#define T_USHORT Py_T_USHORT +#define T_UINT Py_T_UINT +#define T_ULONG Py_T_ULONG +#define T_STRING_INPLACE Py_T_STRING_INPLACE +#define T_BOOL Py_T_BOOL +#define T_OBJECT_EX Py_T_OBJECT_EX +#define T_LONGLONG Py_T_LONGLONG +#define T_ULONGLONG Py_T_ULONGLONG +#define T_PYSSIZET Py_T_PYSSIZET +#define T_NONE _Py_T_NONE /* Flags */ -#define READONLY 1 -#define READ_RESTRICTED 2 -#define PY_WRITE_RESTRICTED 4 +#define READONLY Py_READONLY +#define PY_AUDIT_READ Py_AUDIT_READ +#define READ_RESTRICTED Py_AUDIT_READ +#define PY_WRITE_RESTRICTED _Py_WRITE_RESTRICTED #define RESTRICTED (READ_RESTRICTED | PY_WRITE_RESTRICTED) -#define PY_AUDIT_READ READ_RESTRICTED - -/* Current API, use this */ -PyAPI_FUNC(PyObject *) PyMember_GetOne(const char *, PyMemberDef *); -PyAPI_FUNC(int) PyMember_SetOne(char *, PyMemberDef *, PyObject *); - #ifdef __cplusplus } diff --git a/Include/structseq.h b/Include/structseq.h index 4f5c09f7..96871155 100644 --- a/Include/structseq.h +++ b/Include/structseq.h @@ -35,9 +35,9 @@ PyAPI_FUNC(PyObject *) PyStructSequence_New(PyTypeObject* type); typedef PyTupleObject PyStructSequence; /* Macro, *only* to be used to fill in brand new objects */ -#define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM(op, i, v) +#define PyStructSequence_SET_ITEM(op, i, v) PyTuple_SET_ITEM((op), (i), (v)) -#define PyStructSequence_GET_ITEM(op, i) PyTuple_GET_ITEM(op, i) +#define PyStructSequence_GET_ITEM(op, i) PyTuple_GET_ITEM((op), (i)) #endif PyAPI_FUNC(void) PyStructSequence_SetItem(PyObject*, Py_ssize_t, PyObject*); diff --git a/Include/sysmodule.h b/Include/sysmodule.h index b5087119..96f88387 100644 --- a/Include/sysmodule.h +++ b/Include/sysmodule.h @@ -29,6 +29,19 @@ Py_DEPRECATED(3.11) PyAPI_FUNC(int) PySys_HasWarnOptions(void); Py_DEPRECATED(3.11) PyAPI_FUNC(void) PySys_AddXOption(const wchar_t *); PyAPI_FUNC(PyObject *) PySys_GetXOptions(void); +#if !defined(Py_LIMITED_API) +typedef struct { + FILE* perf_map; + PyThread_type_lock map_lock; +} PerfMapState; + +PyAPI_FUNC(int) PyUnstable_PerfMapState_Init(void); + +PyAPI_FUNC(int) PyUnstable_WritePerfMapEntry(const void *code_addr, unsigned int code_size, const char *entry_name); + +PyAPI_FUNC(void) PyUnstable_PerfMapState_Fini(void); +#endif + #ifndef Py_LIMITED_API # define Py_CPYTHON_SYSMODULE_H # include "cpython/sysmodule.h" diff --git a/Include/traceback.h b/Include/traceback.h index 2dfa2ada..2b40cc9f 100644 --- a/Include/traceback.h +++ b/Include/traceback.h @@ -11,7 +11,7 @@ PyAPI_FUNC(int) PyTraceBack_Print(PyObject *, PyObject *); /* Reveal traceback type so we can typecheck traceback objects */ PyAPI_DATA(PyTypeObject) PyTraceBack_Type; -#define PyTraceBack_Check(v) Py_IS_TYPE(v, &PyTraceBack_Type) +#define PyTraceBack_Check(v) Py_IS_TYPE((v), &PyTraceBack_Type) #ifndef Py_LIMITED_API diff --git a/Include/tracemalloc.h b/Include/tracemalloc.h index bd14217c..580027a8 100644 --- a/Include/tracemalloc.h +++ b/Include/tracemalloc.h @@ -33,6 +33,40 @@ PyAPI_FUNC(int) PyTraceMalloc_Untrack( PyAPI_FUNC(PyObject*) _PyTraceMalloc_GetTraceback( unsigned int domain, uintptr_t ptr); + +/* Return non-zero if tracemalloc is tracing */ +PyAPI_FUNC(int) _PyTraceMalloc_IsTracing(void); + +/* Clear the tracemalloc traces */ +PyAPI_FUNC(void) _PyTraceMalloc_ClearTraces(void); + +/* Clear the tracemalloc traces */ +PyAPI_FUNC(PyObject *) _PyTraceMalloc_GetTraces(void); + +/* Clear tracemalloc traceback for an object */ +PyAPI_FUNC(PyObject *) _PyTraceMalloc_GetObjectTraceback(PyObject *obj); + +/* Initialize tracemalloc */ +PyAPI_FUNC(int) _PyTraceMalloc_Init(void); + +/* Start tracemalloc */ +PyAPI_FUNC(int) _PyTraceMalloc_Start(int max_nframe); + +/* Stop tracemalloc */ +PyAPI_FUNC(void) _PyTraceMalloc_Stop(void); + +/* Get the tracemalloc traceback limit */ +PyAPI_FUNC(int) _PyTraceMalloc_GetTracebackLimit(void); + +/* Get the memory usage of tracemalloc in bytes */ +PyAPI_FUNC(size_t) _PyTraceMalloc_GetMemory(void); + +/* Get the current size and peak size of traced memory blocks as a 2-tuple */ +PyAPI_FUNC(PyObject *) _PyTraceMalloc_GetTracedMemory(void); + +/* Set the peak size of traced memory blocks to the current size */ +PyAPI_FUNC(void) _PyTraceMalloc_ResetPeak(void); + #endif #endif /* !Py_TRACEMALLOC_H */ diff --git a/Include/tupleobject.h b/Include/tupleobject.h index dc68e3fc..1f9ab54b 100644 --- a/Include/tupleobject.h +++ b/Include/tupleobject.h @@ -25,7 +25,7 @@ PyAPI_DATA(PyTypeObject) PyTupleIter_Type; #define PyTuple_Check(op) \ PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_TUPLE_SUBCLASS) -#define PyTuple_CheckExact(op) Py_IS_TYPE(op, &PyTuple_Type) +#define PyTuple_CheckExact(op) Py_IS_TYPE((op), &PyTuple_Type) PyAPI_FUNC(PyObject *) PyTuple_New(Py_ssize_t size); PyAPI_FUNC(Py_ssize_t) PyTuple_Size(PyObject *); diff --git a/Include/unicodeobject.h b/Include/unicodeobject.h index 1d2f5460..5839c747 100644 --- a/Include/unicodeobject.h +++ b/Include/unicodeobject.h @@ -113,7 +113,7 @@ PyAPI_DATA(PyTypeObject) PyUnicodeIter_Type; #define PyUnicode_Check(op) \ PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_UNICODE_SUBCLASS) -#define PyUnicode_CheckExact(op) Py_IS_TYPE(op, &PyUnicode_Type) +#define PyUnicode_CheckExact(op) Py_IS_TYPE((op), &PyUnicode_Type) /* --- Constants ---------------------------------------------------------- */ @@ -171,13 +171,6 @@ PyAPI_FUNC(Py_ssize_t) PyUnicode_GetLength( ); #endif -/* Get the number of Py_UNICODE units in the - string representation. */ - -Py_DEPRECATED(3.3) PyAPI_FUNC(Py_ssize_t) PyUnicode_GetSize( - PyObject *unicode /* Unicode object */ - ); - #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000 /* Read a character from the string. */ @@ -198,9 +191,7 @@ PyAPI_FUNC(int) PyUnicode_WriteChar( ); #endif -/* Resize a Unicode object. The length is the number of characters, except - if the kind of the string is PyUnicode_WCHAR_KIND: in this case, the length - is the number of Py_UNICODE characters. +/* Resize a Unicode object. The length is the number of codepoints. *unicode is modified to point to the new (resized) object and 0 returned on success. @@ -265,10 +256,6 @@ PyAPI_FUNC(PyObject *) PyUnicode_InternFromString( const char *u /* UTF-8 encoded string */ ); -// PyUnicode_InternImmortal() is deprecated since Python 3.10 -// and will be removed in Python 3.12. Use PyUnicode_InternInPlace() instead. -Py_DEPRECATED(3.10) PyAPI_FUNC(void) PyUnicode_InternImmortal(PyObject **); - /* --- wchar_t support for platforms which support it --------------------- */ #ifdef HAVE_WCHAR_H @@ -639,7 +626,7 @@ PyAPI_FUNC(PyObject*) PyUnicode_AsLatin1String( /* --- ASCII Codecs ------------------------------------------------------- - Only 7-bit ASCII data is excepted. All other codes generate errors. + Only 7-bit ASCII data is expected. All other codes generate errors. */ @@ -768,38 +755,22 @@ PyAPI_FUNC(int) PyUnicode_FSConverter(PyObject*, void*); PyAPI_FUNC(int) PyUnicode_FSDecoder(PyObject*, void*); -/* Decode a null-terminated string using Py_FileSystemDefaultEncoding - and the "surrogateescape" error handler. - - If Py_FileSystemDefaultEncoding is not set, fall back to the locale - encoding. - - Use PyUnicode_DecodeFSDefaultAndSize() if the string length is known. -*/ +/* Decode a null-terminated string from the Python filesystem encoding + and error handler. + If the string length is known, use PyUnicode_DecodeFSDefaultAndSize(). */ PyAPI_FUNC(PyObject*) PyUnicode_DecodeFSDefault( const char *s /* encoded string */ ); -/* Decode a string using Py_FileSystemDefaultEncoding - and the "surrogateescape" error handler. - - If Py_FileSystemDefaultEncoding is not set, fall back to the locale - encoding. -*/ - +/* Decode a string from the Python filesystem encoding and error handler. */ PyAPI_FUNC(PyObject*) PyUnicode_DecodeFSDefaultAndSize( const char *s, /* encoded string */ Py_ssize_t size /* size */ ); -/* Encode a Unicode object to Py_FileSystemDefaultEncoding with the - "surrogateescape" error handler, and return bytes. - - If Py_FileSystemDefaultEncoding is not set, fall back to the locale - encoding. -*/ - +/* Encode a Unicode object to the Python filesystem encoding and error handler. + Return bytes. */ PyAPI_FUNC(PyObject*) PyUnicode_EncodeFSDefault( PyObject *unicode ); diff --git a/Include/weakrefobject.h b/Include/weakrefobject.h index f071e9c7..8e1fa1b9 100644 --- a/Include/weakrefobject.h +++ b/Include/weakrefobject.h @@ -12,12 +12,12 @@ PyAPI_DATA(PyTypeObject) _PyWeakref_RefType; PyAPI_DATA(PyTypeObject) _PyWeakref_ProxyType; PyAPI_DATA(PyTypeObject) _PyWeakref_CallableProxyType; -#define PyWeakref_CheckRef(op) PyObject_TypeCheck(op, &_PyWeakref_RefType) +#define PyWeakref_CheckRef(op) PyObject_TypeCheck((op), &_PyWeakref_RefType) #define PyWeakref_CheckRefExact(op) \ - Py_IS_TYPE(op, &_PyWeakref_RefType) + Py_IS_TYPE((op), &_PyWeakref_RefType) #define PyWeakref_CheckProxy(op) \ - (Py_IS_TYPE(op, &_PyWeakref_ProxyType) || \ - Py_IS_TYPE(op, &_PyWeakref_CallableProxyType)) + (Py_IS_TYPE((op), &_PyWeakref_ProxyType) \ + || Py_IS_TYPE((op), &_PyWeakref_CallableProxyType)) #define PyWeakref_Check(op) \ (PyWeakref_CheckRef(op) || PyWeakref_CheckProxy(op)) diff --git a/Lib/_aix_support.py b/Lib/_aix_support.py index 1d8482ff..dadc75c2 100644 --- a/Lib/_aix_support.py +++ b/Lib/_aix_support.py @@ -3,12 +3,24 @@ import sys import sysconfig -try: - import subprocess -except ImportError: # pragma: no cover - # _aix_support is used in distutils by setup.py to build C extensions, - # before subprocess dependencies like _posixsubprocess are available. - import _bootsubprocess as subprocess + +# Taken from _osx_support _read_output function +def _read_cmd_output(commandstring, capture_stderr=False): + """Output from successful command execution or None""" + # Similar to os.popen(commandstring, "r").read(), + # but without actually using os.popen because that + # function is not usable during python bootstrap. + import os + import contextlib + fp = open("/tmp/_aix_support.%s"%( + os.getpid(),), "w+b") + + with contextlib.closing(fp) as fp: + if capture_stderr: + cmd = "%s >'%s' 2>&1" % (commandstring, fp.name) + else: + cmd = "%s 2>/dev/null >'%s'" % (commandstring, fp.name) + return fp.read() if not os.system(cmd) else None def _aix_tag(vrtl, bd): @@ -36,7 +48,12 @@ def _aix_bos_rte(): If no builddate is found give a value that will satisfy pep425 related queries """ # All AIX systems to have lslpp installed in this location - out = subprocess.check_output(["/usr/bin/lslpp", "-Lqc", "bos.rte"]) + # subprocess may not be available during python bootstrap + try: + import subprocess + out = subprocess.check_output(["/usr/bin/lslpp", "-Lqc", "bos.rte"]) + except ImportError: + out = _read_cmd_output("/usr/bin/lslpp -Lqc bos.rte") out = out.decode("utf-8") out = out.strip().split(":") # type: ignore _bd = int(out[-1]) if out[-1] != '' else 9988 diff --git a/Lib/_bootsubprocess.py b/Lib/_bootsubprocess.py deleted file mode 100644 index 014782f6..00000000 --- a/Lib/_bootsubprocess.py +++ /dev/null @@ -1,97 +0,0 @@ -""" -Basic subprocess implementation for POSIX which only uses os functions. Only -implement features required by setup.py to build C extension modules when -subprocess is unavailable. setup.py is not used on Windows. -""" -import os - - -# distutils.spawn used by distutils.command.build_ext -# calls subprocess.Popen().wait() -class Popen: - def __init__(self, cmd, env=None): - self._cmd = cmd - self._env = env - self.returncode = None - - def wait(self): - pid = os.fork() - if pid == 0: - # Child process - try: - if self._env is not None: - os.execve(self._cmd[0], self._cmd, self._env) - else: - os.execv(self._cmd[0], self._cmd) - finally: - os._exit(1) - else: - # Parent process - _, status = os.waitpid(pid, 0) - self.returncode = os.waitstatus_to_exitcode(status) - - return self.returncode - - -def _check_cmd(cmd): - # Use regex [a-zA-Z0-9./-]+: reject empty string, space, etc. - safe_chars = [] - for first, last in (("a", "z"), ("A", "Z"), ("0", "9")): - for ch in range(ord(first), ord(last) + 1): - safe_chars.append(chr(ch)) - safe_chars.append("./-") - safe_chars = ''.join(safe_chars) - - if isinstance(cmd, (tuple, list)): - check_strs = cmd - elif isinstance(cmd, str): - check_strs = [cmd] - else: - return False - - for arg in check_strs: - if not isinstance(arg, str): - return False - if not arg: - # reject empty string - return False - for ch in arg: - if ch not in safe_chars: - return False - - return True - - -# _aix_support used by distutil.util calls subprocess.check_output() -def check_output(cmd, **kwargs): - if kwargs: - raise NotImplementedError(repr(kwargs)) - - if not _check_cmd(cmd): - raise ValueError(f"unsupported command: {cmd!r}") - - tmp_filename = "check_output.tmp" - if not isinstance(cmd, str): - cmd = " ".join(cmd) - cmd = f"{cmd} >{tmp_filename}" - - try: - # system() spawns a shell - status = os.system(cmd) - exitcode = os.waitstatus_to_exitcode(status) - if exitcode: - raise ValueError(f"Command {cmd!r} returned non-zero " - f"exit status {exitcode!r}") - - try: - with open(tmp_filename, "rb") as fp: - stdout = fp.read() - except FileNotFoundError: - stdout = b'' - finally: - try: - os.unlink(tmp_filename) - except OSError: - pass - - return stdout diff --git a/Lib/_collections_abc.py b/Lib/_collections_abc.py index e96e4c35..601107d2 100644 --- a/Lib/_collections_abc.py +++ b/Lib/_collections_abc.py @@ -6,6 +6,32 @@ Unit tests are in test_collections. """ +############ Maintenance notes ######################################### +# +# ABCs are different from other standard library modules in that they +# specify compliance tests. In general, once an ABC has been published, +# new methods (either abstract or concrete) cannot be added. +# +# Though classes that inherit from an ABC would automatically receive a +# new mixin method, registered classes would become non-compliant and +# violate the contract promised by ``isinstance(someobj, SomeABC)``. +# +# Though irritating, the correct procedure for adding new abstract or +# mixin methods is to create a new ABC as a subclass of the previous +# ABC. For example, union(), intersection(), and difference() cannot +# be added to Set but could go into a new ABC that extends Set. +# +# Because they are so hard to change, new ABCs should have their APIs +# carefully thought through prior to publication. +# +# Since ABCMeta only checks for the presence of methods, it is possible +# to alter the signature of a method by adding optional arguments +# or changing parameters names. This is still a bit dubious but at +# least it won't cause isinstance() to return an incorrect result. +# +# +####################################################################### + from abc import ABCMeta, abstractmethod import sys @@ -23,7 +49,7 @@ __all__ = ["Awaitable", "Coroutine", "Mapping", "MutableMapping", "MappingView", "KeysView", "ItemsView", "ValuesView", "Sequence", "MutableSequence", - "ByteString", + "ByteString", "Buffer", ] # This module has been renamed from collections.abc to _collections_abc to @@ -413,6 +439,21 @@ class Collection(Sized, Iterable, Container): return NotImplemented +class Buffer(metaclass=ABCMeta): + + __slots__ = () + + @abstractmethod + def __buffer__(self, flags: int, /) -> memoryview: + raise NotImplementedError + + @classmethod + def __subclasshook__(cls, C): + if cls is Buffer: + return _check_methods(C, "__buffer__") + return NotImplemented + + class _CallableGenericAlias(GenericAlias): """ Represent `Callable[argtypes, resulttype]`. @@ -455,15 +496,8 @@ class _CallableGenericAlias(GenericAlias): # rather than the default types.GenericAlias object. Most of the # code is copied from typing's _GenericAlias and the builtin # types.GenericAlias. - if not isinstance(item, tuple): item = (item,) - # A special case in PEP 612 where if X = Callable[P, int], - # then X[int, str] == X[[int, str]]. - if (len(self.__parameters__) == 1 - and _is_param_expr(self.__parameters__[0]) - and item and not _is_param_expr(item[0])): - item = (item,) new_args = super().__getitem__(item).__args__ @@ -491,9 +525,8 @@ def _type_repr(obj): Copied from :mod:`typing` since collections.abc shouldn't depend on that module. + (Keep this roughly in sync with the typing version.) """ - if isinstance(obj, GenericAlias): - return repr(obj) if isinstance(obj, type): if obj.__module__ == 'builtins': return obj.__qualname__ @@ -1038,8 +1071,27 @@ Sequence.register(str) Sequence.register(range) Sequence.register(memoryview) +class _DeprecateByteStringMeta(ABCMeta): + def __new__(cls, name, bases, namespace, **kwargs): + if name != "ByteString": + import warnings + + warnings._deprecated( + "collections.abc.ByteString", + remove=(3, 14), + ) + return super().__new__(cls, name, bases, namespace, **kwargs) + + def __instancecheck__(cls, instance): + import warnings + + warnings._deprecated( + "collections.abc.ByteString", + remove=(3, 14), + ) + return super().__instancecheck__(instance) -class ByteString(Sequence): +class ByteString(Sequence, metaclass=_DeprecateByteStringMeta): """This unifies bytes and bytearray. XXX Should add all their methods. diff --git a/Lib/_pydatetime.py b/Lib/_pydatetime.py new file mode 100644 index 00000000..a6d43399 --- /dev/null +++ b/Lib/_pydatetime.py @@ -0,0 +1,2647 @@ +"""Concrete date/time and related types. + +See http://www.iana.org/time-zones/repository/tz-link.html for +time zone and DST data sources. +""" + +__all__ = ("date", "datetime", "time", "timedelta", "timezone", "tzinfo", + "MINYEAR", "MAXYEAR", "UTC") + + +import time as _time +import math as _math +import sys +from operator import index as _index + +def _cmp(x, y): + return 0 if x == y else 1 if x > y else -1 + +def _get_class_module(self): + module_name = self.__class__.__module__ + if module_name == '_pydatetime': + return 'datetime' + else: + return module_name + +MINYEAR = 1 +MAXYEAR = 9999 +_MAXORDINAL = 3652059 # date.max.toordinal() + +# Utility functions, adapted from Python's Demo/classes/Dates.py, which +# also assumes the current Gregorian calendar indefinitely extended in +# both directions. Difference: Dates.py calls January 1 of year 0 day +# number 1. The code here calls January 1 of year 1 day number 1. This is +# to match the definition of the "proleptic Gregorian" calendar in Dershowitz +# and Reingold's "Calendrical Calculations", where it's the base calendar +# for all computations. See the book for algorithms for converting between +# proleptic Gregorian ordinals and many other calendar systems. + +# -1 is a placeholder for indexing purposes. +_DAYS_IN_MONTH = [-1, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] + +_DAYS_BEFORE_MONTH = [-1] # -1 is a placeholder for indexing purposes. +dbm = 0 +for dim in _DAYS_IN_MONTH[1:]: + _DAYS_BEFORE_MONTH.append(dbm) + dbm += dim +del dbm, dim + +def _is_leap(year): + "year -> 1 if leap year, else 0." + return year % 4 == 0 and (year % 100 != 0 or year % 400 == 0) + +def _days_before_year(year): + "year -> number of days before January 1st of year." + y = year - 1 + return y*365 + y//4 - y//100 + y//400 + +def _days_in_month(year, month): + "year, month -> number of days in that month in that year." + assert 1 <= month <= 12, month + if month == 2 and _is_leap(year): + return 29 + return _DAYS_IN_MONTH[month] + +def _days_before_month(year, month): + "year, month -> number of days in year preceding first day of month." + assert 1 <= month <= 12, 'month must be in 1..12' + return _DAYS_BEFORE_MONTH[month] + (month > 2 and _is_leap(year)) + +def _ymd2ord(year, month, day): + "year, month, day -> ordinal, considering 01-Jan-0001 as day 1." + assert 1 <= month <= 12, 'month must be in 1..12' + dim = _days_in_month(year, month) + assert 1 <= day <= dim, ('day must be in 1..%d' % dim) + return (_days_before_year(year) + + _days_before_month(year, month) + + day) + +_DI400Y = _days_before_year(401) # number of days in 400 years +_DI100Y = _days_before_year(101) # " " " " 100 " +_DI4Y = _days_before_year(5) # " " " " 4 " + +# A 4-year cycle has an extra leap day over what we'd get from pasting +# together 4 single years. +assert _DI4Y == 4 * 365 + 1 + +# Similarly, a 400-year cycle has an extra leap day over what we'd get from +# pasting together 4 100-year cycles. +assert _DI400Y == 4 * _DI100Y + 1 + +# OTOH, a 100-year cycle has one fewer leap day than we'd get from +# pasting together 25 4-year cycles. +assert _DI100Y == 25 * _DI4Y - 1 + +def _ord2ymd(n): + "ordinal -> (year, month, day), considering 01-Jan-0001 as day 1." + + # n is a 1-based index, starting at 1-Jan-1. The pattern of leap years + # repeats exactly every 400 years. The basic strategy is to find the + # closest 400-year boundary at or before n, then work with the offset + # from that boundary to n. Life is much clearer if we subtract 1 from + # n first -- then the values of n at 400-year boundaries are exactly + # those divisible by _DI400Y: + # + # D M Y n n-1 + # -- --- ---- ---------- ---------------- + # 31 Dec -400 -_DI400Y -_DI400Y -1 + # 1 Jan -399 -_DI400Y +1 -_DI400Y 400-year boundary + # ... + # 30 Dec 000 -1 -2 + # 31 Dec 000 0 -1 + # 1 Jan 001 1 0 400-year boundary + # 2 Jan 001 2 1 + # 3 Jan 001 3 2 + # ... + # 31 Dec 400 _DI400Y _DI400Y -1 + # 1 Jan 401 _DI400Y +1 _DI400Y 400-year boundary + n -= 1 + n400, n = divmod(n, _DI400Y) + year = n400 * 400 + 1 # ..., -399, 1, 401, ... + + # Now n is the (non-negative) offset, in days, from January 1 of year, to + # the desired date. Now compute how many 100-year cycles precede n. + # Note that it's possible for n100 to equal 4! In that case 4 full + # 100-year cycles precede the desired day, which implies the desired + # day is December 31 at the end of a 400-year cycle. + n100, n = divmod(n, _DI100Y) + + # Now compute how many 4-year cycles precede it. + n4, n = divmod(n, _DI4Y) + + # And now how many single years. Again n1 can be 4, and again meaning + # that the desired day is December 31 at the end of the 4-year cycle. + n1, n = divmod(n, 365) + + year += n100 * 100 + n4 * 4 + n1 + if n1 == 4 or n100 == 4: + assert n == 0 + return year-1, 12, 31 + + # Now the year is correct, and n is the offset from January 1. We find + # the month via an estimate that's either exact or one too large. + leapyear = n1 == 3 and (n4 != 24 or n100 == 3) + assert leapyear == _is_leap(year) + month = (n + 50) >> 5 + preceding = _DAYS_BEFORE_MONTH[month] + (month > 2 and leapyear) + if preceding > n: # estimate is too large + month -= 1 + preceding -= _DAYS_IN_MONTH[month] + (month == 2 and leapyear) + n -= preceding + assert 0 <= n < _days_in_month(year, month) + + # Now the year and month are correct, and n is the offset from the + # start of that month: we're done! + return year, month, n+1 + +# Month and day names. For localized versions, see the calendar module. +_MONTHNAMES = [None, "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] +_DAYNAMES = [None, "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"] + + +def _build_struct_time(y, m, d, hh, mm, ss, dstflag): + wday = (_ymd2ord(y, m, d) + 6) % 7 + dnum = _days_before_month(y, m) + d + return _time.struct_time((y, m, d, hh, mm, ss, wday, dnum, dstflag)) + +def _format_time(hh, mm, ss, us, timespec='auto'): + specs = { + 'hours': '{:02d}', + 'minutes': '{:02d}:{:02d}', + 'seconds': '{:02d}:{:02d}:{:02d}', + 'milliseconds': '{:02d}:{:02d}:{:02d}.{:03d}', + 'microseconds': '{:02d}:{:02d}:{:02d}.{:06d}' + } + + if timespec == 'auto': + # Skip trailing microseconds when us==0. + timespec = 'microseconds' if us else 'seconds' + elif timespec == 'milliseconds': + us //= 1000 + try: + fmt = specs[timespec] + except KeyError: + raise ValueError('Unknown timespec value') + else: + return fmt.format(hh, mm, ss, us) + +def _format_offset(off, sep=':'): + s = '' + if off is not None: + if off.days < 0: + sign = "-" + off = -off + else: + sign = "+" + hh, mm = divmod(off, timedelta(hours=1)) + mm, ss = divmod(mm, timedelta(minutes=1)) + s += "%s%02d%s%02d" % (sign, hh, sep, mm) + if ss or ss.microseconds: + s += "%s%02d" % (sep, ss.seconds) + + if ss.microseconds: + s += '.%06d' % ss.microseconds + return s + +# Correctly substitute for %z and %Z escapes in strftime formats. +def _wrap_strftime(object, format, timetuple): + # Don't call utcoffset() or tzname() unless actually needed. + freplace = None # the string to use for %f + zreplace = None # the string to use for %z + colonzreplace = None # the string to use for %:z + Zreplace = None # the string to use for %Z + + # Scan format for %z, %:z and %Z escapes, replacing as needed. + newformat = [] + push = newformat.append + i, n = 0, len(format) + while i < n: + ch = format[i] + i += 1 + if ch == '%': + if i < n: + ch = format[i] + i += 1 + if ch == 'f': + if freplace is None: + freplace = '%06d' % getattr(object, + 'microsecond', 0) + newformat.append(freplace) + elif ch == 'z': + if zreplace is None: + if hasattr(object, "utcoffset"): + zreplace = _format_offset(object.utcoffset(), sep="") + else: + zreplace = "" + assert '%' not in zreplace + newformat.append(zreplace) + elif ch == ':': + if i < n: + ch2 = format[i] + i += 1 + if ch2 == 'z': + if colonzreplace is None: + if hasattr(object, "utcoffset"): + colonzreplace = _format_offset(object.utcoffset(), sep=":") + else: + colonzreplace = "" + assert '%' not in colonzreplace + newformat.append(colonzreplace) + else: + push('%') + push(ch) + push(ch2) + elif ch == 'Z': + if Zreplace is None: + Zreplace = "" + if hasattr(object, "tzname"): + s = object.tzname() + if s is not None: + # strftime is going to have at this: escape % + Zreplace = s.replace('%', '%%') + newformat.append(Zreplace) + else: + push('%') + push(ch) + else: + push('%') + else: + push(ch) + newformat = "".join(newformat) + return _time.strftime(newformat, timetuple) + +# Helpers for parsing the result of isoformat() +def _is_ascii_digit(c): + return c in "0123456789" + +def _find_isoformat_datetime_separator(dtstr): + # See the comment in _datetimemodule.c:_find_isoformat_datetime_separator + len_dtstr = len(dtstr) + if len_dtstr == 7: + return 7 + + assert len_dtstr > 7 + date_separator = "-" + week_indicator = "W" + + if dtstr[4] == date_separator: + if dtstr[5] == week_indicator: + if len_dtstr < 8: + raise ValueError("Invalid ISO string") + if len_dtstr > 8 and dtstr[8] == date_separator: + if len_dtstr == 9: + raise ValueError("Invalid ISO string") + if len_dtstr > 10 and _is_ascii_digit(dtstr[10]): + # This is as far as we need to resolve the ambiguity for + # the moment - if we have YYYY-Www-##, the separator is + # either a hyphen at 8 or a number at 10. + # + # We'll assume it's a hyphen at 8 because it's way more + # likely that someone will use a hyphen as a separator than + # a number, but at this point it's really best effort + # because this is an extension of the spec anyway. + # TODO(pganssle): Document this + return 8 + return 10 + else: + # YYYY-Www (8) + return 8 + else: + # YYYY-MM-DD (10) + return 10 + else: + if dtstr[4] == week_indicator: + # YYYYWww (7) or YYYYWwwd (8) + idx = 7 + while idx < len_dtstr: + if not _is_ascii_digit(dtstr[idx]): + break + idx += 1 + + if idx < 9: + return idx + + if idx % 2 == 0: + # If the index of the last number is even, it's YYYYWwwd + return 7 + else: + return 8 + else: + # YYYYMMDD (8) + return 8 + + +def _parse_isoformat_date(dtstr): + # It is assumed that this is an ASCII-only string of lengths 7, 8 or 10, + # see the comment on Modules/_datetimemodule.c:_find_isoformat_datetime_separator + assert len(dtstr) in (7, 8, 10) + year = int(dtstr[0:4]) + has_sep = dtstr[4] == '-' + + pos = 4 + has_sep + if dtstr[pos:pos + 1] == "W": + # YYYY-?Www-?D? + pos += 1 + weekno = int(dtstr[pos:pos + 2]) + pos += 2 + + dayno = 1 + if len(dtstr) > pos: + if (dtstr[pos:pos + 1] == '-') != has_sep: + raise ValueError("Inconsistent use of dash separator") + + pos += has_sep + + dayno = int(dtstr[pos:pos + 1]) + + return list(_isoweek_to_gregorian(year, weekno, dayno)) + else: + month = int(dtstr[pos:pos + 2]) + pos += 2 + if (dtstr[pos:pos + 1] == "-") != has_sep: + raise ValueError("Inconsistent use of dash separator") + + pos += has_sep + day = int(dtstr[pos:pos + 2]) + + return [year, month, day] + + +_FRACTION_CORRECTION = [100000, 10000, 1000, 100, 10] + + +def _parse_hh_mm_ss_ff(tstr): + # Parses things of the form HH[:?MM[:?SS[{.,}fff[fff]]]] + len_str = len(tstr) + + time_comps = [0, 0, 0, 0] + pos = 0 + for comp in range(0, 3): + if (len_str - pos) < 2: + raise ValueError("Incomplete time component") + + time_comps[comp] = int(tstr[pos:pos+2]) + + pos += 2 + next_char = tstr[pos:pos+1] + + if comp == 0: + has_sep = next_char == ':' + + if not next_char or comp >= 2: + break + + if has_sep and next_char != ':': + raise ValueError("Invalid time separator: %c" % next_char) + + pos += has_sep + + if pos < len_str: + if tstr[pos] not in '.,': + raise ValueError("Invalid microsecond component") + else: + pos += 1 + + len_remainder = len_str - pos + + if len_remainder >= 6: + to_parse = 6 + else: + to_parse = len_remainder + + time_comps[3] = int(tstr[pos:(pos+to_parse)]) + if to_parse < 6: + time_comps[3] *= _FRACTION_CORRECTION[to_parse-1] + if (len_remainder > to_parse + and not all(map(_is_ascii_digit, tstr[(pos+to_parse):]))): + raise ValueError("Non-digit values in unparsed fraction") + + return time_comps + +def _parse_isoformat_time(tstr): + # Format supported is HH[:MM[:SS[.fff[fff]]]][+HH:MM[:SS[.ffffff]]] + len_str = len(tstr) + if len_str < 2: + raise ValueError("Isoformat time too short") + + # This is equivalent to re.search('[+-Z]', tstr), but faster + tz_pos = (tstr.find('-') + 1 or tstr.find('+') + 1 or tstr.find('Z') + 1) + timestr = tstr[:tz_pos-1] if tz_pos > 0 else tstr + + time_comps = _parse_hh_mm_ss_ff(timestr) + + tzi = None + if tz_pos == len_str and tstr[-1] == 'Z': + tzi = timezone.utc + elif tz_pos > 0: + tzstr = tstr[tz_pos:] + + # Valid time zone strings are: + # HH len: 2 + # HHMM len: 4 + # HH:MM len: 5 + # HHMMSS len: 6 + # HHMMSS.f+ len: 7+ + # HH:MM:SS len: 8 + # HH:MM:SS.f+ len: 10+ + + if len(tzstr) in (0, 1, 3): + raise ValueError("Malformed time zone string") + + tz_comps = _parse_hh_mm_ss_ff(tzstr) + + if all(x == 0 for x in tz_comps): + tzi = timezone.utc + else: + tzsign = -1 if tstr[tz_pos - 1] == '-' else 1 + + td = timedelta(hours=tz_comps[0], minutes=tz_comps[1], + seconds=tz_comps[2], microseconds=tz_comps[3]) + + tzi = timezone(tzsign * td) + + time_comps.append(tzi) + + return time_comps + +# tuple[int, int, int] -> tuple[int, int, int] version of date.fromisocalendar +def _isoweek_to_gregorian(year, week, day): + # Year is bounded this way because 9999-12-31 is (9999, 52, 5) + if not MINYEAR <= year <= MAXYEAR: + raise ValueError(f"Year is out of range: {year}") + + if not 0 < week < 53: + out_of_range = True + + if week == 53: + # ISO years have 53 weeks in them on years starting with a + # Thursday and leap years starting on a Wednesday + first_weekday = _ymd2ord(year, 1, 1) % 7 + if (first_weekday == 4 or (first_weekday == 3 and + _is_leap(year))): + out_of_range = False + + if out_of_range: + raise ValueError(f"Invalid week: {week}") + + if not 0 < day < 8: + raise ValueError(f"Invalid weekday: {day} (range is [1, 7])") + + # Now compute the offset from (Y, 1, 1) in days: + day_offset = (week - 1) * 7 + (day - 1) + + # Calculate the ordinal day for monday, week 1 + day_1 = _isoweek1monday(year) + ord_day = day_1 + day_offset + + return _ord2ymd(ord_day) + + +# Just raise TypeError if the arg isn't None or a string. +def _check_tzname(name): + if name is not None and not isinstance(name, str): + raise TypeError("tzinfo.tzname() must return None or string, " + "not '%s'" % type(name)) + +# name is the offset-producing method, "utcoffset" or "dst". +# offset is what it returned. +# If offset isn't None or timedelta, raises TypeError. +# If offset is None, returns None. +# Else offset is checked for being in range. +# If it is, its integer value is returned. Else ValueError is raised. +def _check_utc_offset(name, offset): + assert name in ("utcoffset", "dst") + if offset is None: + return + if not isinstance(offset, timedelta): + raise TypeError("tzinfo.%s() must return None " + "or timedelta, not '%s'" % (name, type(offset))) + if not -timedelta(1) < offset < timedelta(1): + raise ValueError("%s()=%s, must be strictly between " + "-timedelta(hours=24) and timedelta(hours=24)" % + (name, offset)) + +def _check_date_fields(year, month, day): + year = _index(year) + month = _index(month) + day = _index(day) + if not MINYEAR <= year <= MAXYEAR: + raise ValueError('year must be in %d..%d' % (MINYEAR, MAXYEAR), year) + if not 1 <= month <= 12: + raise ValueError('month must be in 1..12', month) + dim = _days_in_month(year, month) + if not 1 <= day <= dim: + raise ValueError('day must be in 1..%d' % dim, day) + return year, month, day + +def _check_time_fields(hour, minute, second, microsecond, fold): + hour = _index(hour) + minute = _index(minute) + second = _index(second) + microsecond = _index(microsecond) + if not 0 <= hour <= 23: + raise ValueError('hour must be in 0..23', hour) + if not 0 <= minute <= 59: + raise ValueError('minute must be in 0..59', minute) + if not 0 <= second <= 59: + raise ValueError('second must be in 0..59', second) + if not 0 <= microsecond <= 999999: + raise ValueError('microsecond must be in 0..999999', microsecond) + if fold not in (0, 1): + raise ValueError('fold must be either 0 or 1', fold) + return hour, minute, second, microsecond, fold + +def _check_tzinfo_arg(tz): + if tz is not None and not isinstance(tz, tzinfo): + raise TypeError("tzinfo argument must be None or of a tzinfo subclass") + +def _cmperror(x, y): + raise TypeError("can't compare '%s' to '%s'" % ( + type(x).__name__, type(y).__name__)) + +def _divide_and_round(a, b): + """divide a by b and round result to the nearest integer + + When the ratio is exactly half-way between two integers, + the even integer is returned. + """ + # Based on the reference implementation for divmod_near + # in Objects/longobject.c. + q, r = divmod(a, b) + # round up if either r / b > 0.5, or r / b == 0.5 and q is odd. + # The expression r / b > 0.5 is equivalent to 2 * r > b if b is + # positive, 2 * r < b if b negative. + r *= 2 + greater_than_half = r > b if b > 0 else r < b + if greater_than_half or r == b and q % 2 == 1: + q += 1 + + return q + + +class timedelta: + """Represent the difference between two datetime objects. + + Supported operators: + + - add, subtract timedelta + - unary plus, minus, abs + - compare to timedelta + - multiply, divide by int + + In addition, datetime supports subtraction of two datetime objects + returning a timedelta, and addition or subtraction of a datetime + and a timedelta giving a datetime. + + Representation: (days, seconds, microseconds). + """ + # The representation of (days, seconds, microseconds) was chosen + # arbitrarily; the exact rationale originally specified in the docstring + # was "Because I felt like it." + + __slots__ = '_days', '_seconds', '_microseconds', '_hashcode' + + def __new__(cls, days=0, seconds=0, microseconds=0, + milliseconds=0, minutes=0, hours=0, weeks=0): + # Doing this efficiently and accurately in C is going to be difficult + # and error-prone, due to ubiquitous overflow possibilities, and that + # C double doesn't have enough bits of precision to represent + # microseconds over 10K years faithfully. The code here tries to make + # explicit where go-fast assumptions can be relied on, in order to + # guide the C implementation; it's way more convoluted than speed- + # ignoring auto-overflow-to-long idiomatic Python could be. + + # XXX Check that all inputs are ints or floats. + + # Final values, all integer. + # s and us fit in 32-bit signed ints; d isn't bounded. + d = s = us = 0 + + # Normalize everything to days, seconds, microseconds. + days += weeks*7 + seconds += minutes*60 + hours*3600 + microseconds += milliseconds*1000 + + # Get rid of all fractions, and normalize s and us. + # Take a deep breath <wink>. + if isinstance(days, float): + dayfrac, days = _math.modf(days) + daysecondsfrac, daysecondswhole = _math.modf(dayfrac * (24.*3600.)) + assert daysecondswhole == int(daysecondswhole) # can't overflow + s = int(daysecondswhole) + assert days == int(days) + d = int(days) + else: + daysecondsfrac = 0.0 + d = days + assert isinstance(daysecondsfrac, float) + assert abs(daysecondsfrac) <= 1.0 + assert isinstance(d, int) + assert abs(s) <= 24 * 3600 + # days isn't referenced again before redefinition + + if isinstance(seconds, float): + secondsfrac, seconds = _math.modf(seconds) + assert seconds == int(seconds) + seconds = int(seconds) + secondsfrac += daysecondsfrac + assert abs(secondsfrac) <= 2.0 + else: + secondsfrac = daysecondsfrac + # daysecondsfrac isn't referenced again + assert isinstance(secondsfrac, float) + assert abs(secondsfrac) <= 2.0 + + assert isinstance(seconds, int) + days, seconds = divmod(seconds, 24*3600) + d += days + s += int(seconds) # can't overflow + assert isinstance(s, int) + assert abs(s) <= 2 * 24 * 3600 + # seconds isn't referenced again before redefinition + + usdouble = secondsfrac * 1e6 + assert abs(usdouble) < 2.1e6 # exact value not critical + # secondsfrac isn't referenced again + + if isinstance(microseconds, float): + microseconds = round(microseconds + usdouble) + seconds, microseconds = divmod(microseconds, 1000000) + days, seconds = divmod(seconds, 24*3600) + d += days + s += seconds + else: + microseconds = int(microseconds) + seconds, microseconds = divmod(microseconds, 1000000) + days, seconds = divmod(seconds, 24*3600) + d += days + s += seconds + microseconds = round(microseconds + usdouble) + assert isinstance(s, int) + assert isinstance(microseconds, int) + assert abs(s) <= 3 * 24 * 3600 + assert abs(microseconds) < 3.1e6 + + # Just a little bit of carrying possible for microseconds and seconds. + seconds, us = divmod(microseconds, 1000000) + s += seconds + days, s = divmod(s, 24*3600) + d += days + + assert isinstance(d, int) + assert isinstance(s, int) and 0 <= s < 24*3600 + assert isinstance(us, int) and 0 <= us < 1000000 + + if abs(d) > 999999999: + raise OverflowError("timedelta # of days is too large: %d" % d) + + self = object.__new__(cls) + self._days = d + self._seconds = s + self._microseconds = us + self._hashcode = -1 + return self + + def __repr__(self): + args = [] + if self._days: + args.append("days=%d" % self._days) + if self._seconds: + args.append("seconds=%d" % self._seconds) + if self._microseconds: + args.append("microseconds=%d" % self._microseconds) + if not args: + args.append('0') + return "%s.%s(%s)" % (_get_class_module(self), + self.__class__.__qualname__, + ', '.join(args)) + + def __str__(self): + mm, ss = divmod(self._seconds, 60) + hh, mm = divmod(mm, 60) + s = "%d:%02d:%02d" % (hh, mm, ss) + if self._days: + def plural(n): + return n, abs(n) != 1 and "s" or "" + s = ("%d day%s, " % plural(self._days)) + s + if self._microseconds: + s = s + ".%06d" % self._microseconds + return s + + def total_seconds(self): + """Total seconds in the duration.""" + return ((self.days * 86400 + self.seconds) * 10**6 + + self.microseconds) / 10**6 + + # Read-only field accessors + @property + def days(self): + """days""" + return self._days + + @property + def seconds(self): + """seconds""" + return self._seconds + + @property + def microseconds(self): + """microseconds""" + return self._microseconds + + def __add__(self, other): + if isinstance(other, timedelta): + # for CPython compatibility, we cannot use + # our __class__ here, but need a real timedelta + return timedelta(self._days + other._days, + self._seconds + other._seconds, + self._microseconds + other._microseconds) + return NotImplemented + + __radd__ = __add__ + + def __sub__(self, other): + if isinstance(other, timedelta): + # for CPython compatibility, we cannot use + # our __class__ here, but need a real timedelta + return timedelta(self._days - other._days, + self._seconds - other._seconds, + self._microseconds - other._microseconds) + return NotImplemented + + def __rsub__(self, other): + if isinstance(other, timedelta): + return -self + other + return NotImplemented + + def __neg__(self): + # for CPython compatibility, we cannot use + # our __class__ here, but need a real timedelta + return timedelta(-self._days, + -self._seconds, + -self._microseconds) + + def __pos__(self): + return self + + def __abs__(self): + if self._days < 0: + return -self + else: + return self + + def __mul__(self, other): + if isinstance(other, int): + # for CPython compatibility, we cannot use + # our __class__ here, but need a real timedelta + return timedelta(self._days * other, + self._seconds * other, + self._microseconds * other) + if isinstance(other, float): + usec = self._to_microseconds() + a, b = other.as_integer_ratio() + return timedelta(0, 0, _divide_and_round(usec * a, b)) + return NotImplemented + + __rmul__ = __mul__ + + def _to_microseconds(self): + return ((self._days * (24*3600) + self._seconds) * 1000000 + + self._microseconds) + + def __floordiv__(self, other): + if not isinstance(other, (int, timedelta)): + return NotImplemented + usec = self._to_microseconds() + if isinstance(other, timedelta): + return usec // other._to_microseconds() + if isinstance(other, int): + return timedelta(0, 0, usec // other) + + def __truediv__(self, other): + if not isinstance(other, (int, float, timedelta)): + return NotImplemented + usec = self._to_microseconds() + if isinstance(other, timedelta): + return usec / other._to_microseconds() + if isinstance(other, int): + return timedelta(0, 0, _divide_and_round(usec, other)) + if isinstance(other, float): + a, b = other.as_integer_ratio() + return timedelta(0, 0, _divide_and_round(b * usec, a)) + + def __mod__(self, other): + if isinstance(other, timedelta): + r = self._to_microseconds() % other._to_microseconds() + return timedelta(0, 0, r) + return NotImplemented + + def __divmod__(self, other): + if isinstance(other, timedelta): + q, r = divmod(self._to_microseconds(), + other._to_microseconds()) + return q, timedelta(0, 0, r) + return NotImplemented + + # Comparisons of timedelta objects with other. + + def __eq__(self, other): + if isinstance(other, timedelta): + return self._cmp(other) == 0 + else: + return NotImplemented + + def __le__(self, other): + if isinstance(other, timedelta): + return self._cmp(other) <= 0 + else: + return NotImplemented + + def __lt__(self, other): + if isinstance(other, timedelta): + return self._cmp(other) < 0 + else: + return NotImplemented + + def __ge__(self, other): + if isinstance(other, timedelta): + return self._cmp(other) >= 0 + else: + return NotImplemented + + def __gt__(self, other): + if isinstance(other, timedelta): + return self._cmp(other) > 0 + else: + return NotImplemented + + def _cmp(self, other): + assert isinstance(other, timedelta) + return _cmp(self._getstate(), other._getstate()) + + def __hash__(self): + if self._hashcode == -1: + self._hashcode = hash(self._getstate()) + return self._hashcode + + def __bool__(self): + return (self._days != 0 or + self._seconds != 0 or + self._microseconds != 0) + + # Pickle support. + + def _getstate(self): + return (self._days, self._seconds, self._microseconds) + + def __reduce__(self): + return (self.__class__, self._getstate()) + +timedelta.min = timedelta(-999999999) +timedelta.max = timedelta(days=999999999, hours=23, minutes=59, seconds=59, + microseconds=999999) +timedelta.resolution = timedelta(microseconds=1) + +class date: + """Concrete date type. + + Constructors: + + __new__() + fromtimestamp() + today() + fromordinal() + + Operators: + + __repr__, __str__ + __eq__, __le__, __lt__, __ge__, __gt__, __hash__ + __add__, __radd__, __sub__ (add/radd only with timedelta arg) + + Methods: + + timetuple() + toordinal() + weekday() + isoweekday(), isocalendar(), isoformat() + ctime() + strftime() + + Properties (readonly): + year, month, day + """ + __slots__ = '_year', '_month', '_day', '_hashcode' + + def __new__(cls, year, month=None, day=None): + """Constructor. + + Arguments: + + year, month, day (required, base 1) + """ + if (month is None and + isinstance(year, (bytes, str)) and len(year) == 4 and + 1 <= ord(year[2:3]) <= 12): + # Pickle support + if isinstance(year, str): + try: + year = year.encode('latin1') + except UnicodeEncodeError: + # More informative error message. + raise ValueError( + "Failed to encode latin1 string when unpickling " + "a date object. " + "pickle.load(data, encoding='latin1') is assumed.") + self = object.__new__(cls) + self.__setstate(year) + self._hashcode = -1 + return self + year, month, day = _check_date_fields(year, month, day) + self = object.__new__(cls) + self._year = year + self._month = month + self._day = day + self._hashcode = -1 + return self + + # Additional constructors + + @classmethod + def fromtimestamp(cls, t): + "Construct a date from a POSIX timestamp (like time.time())." + y, m, d, hh, mm, ss, weekday, jday, dst = _time.localtime(t) + return cls(y, m, d) + + @classmethod + def today(cls): + "Construct a date from time.time()." + t = _time.time() + return cls.fromtimestamp(t) + + @classmethod + def fromordinal(cls, n): + """Construct a date from a proleptic Gregorian ordinal. + + January 1 of year 1 is day 1. Only the year, month and day are + non-zero in the result. + """ + y, m, d = _ord2ymd(n) + return cls(y, m, d) + + @classmethod + def fromisoformat(cls, date_string): + """Construct a date from a string in ISO 8601 format.""" + if not isinstance(date_string, str): + raise TypeError('fromisoformat: argument must be str') + + if len(date_string) not in (7, 8, 10): + raise ValueError(f'Invalid isoformat string: {date_string!r}') + + try: + return cls(*_parse_isoformat_date(date_string)) + except Exception: + raise ValueError(f'Invalid isoformat string: {date_string!r}') + + @classmethod + def fromisocalendar(cls, year, week, day): + """Construct a date from the ISO year, week number and weekday. + + This is the inverse of the date.isocalendar() function""" + return cls(*_isoweek_to_gregorian(year, week, day)) + + # Conversions to string + + def __repr__(self): + """Convert to formal string, for repr(). + + >>> dt = datetime(2010, 1, 1) + >>> repr(dt) + 'datetime.datetime(2010, 1, 1, 0, 0)' + + >>> dt = datetime(2010, 1, 1, tzinfo=timezone.utc) + >>> repr(dt) + 'datetime.datetime(2010, 1, 1, 0, 0, tzinfo=datetime.timezone.utc)' + """ + return "%s.%s(%d, %d, %d)" % (_get_class_module(self), + self.__class__.__qualname__, + self._year, + self._month, + self._day) + # XXX These shouldn't depend on time.localtime(), because that + # clips the usable dates to [1970 .. 2038). At least ctime() is + # easily done without using strftime() -- that's better too because + # strftime("%c", ...) is locale specific. + + + def ctime(self): + "Return ctime() style string." + weekday = self.toordinal() % 7 or 7 + return "%s %s %2d 00:00:00 %04d" % ( + _DAYNAMES[weekday], + _MONTHNAMES[self._month], + self._day, self._year) + + def strftime(self, format): + """ + Format using strftime(). + + Example: "%d/%m/%Y, %H:%M:%S" + """ + return _wrap_strftime(self, format, self.timetuple()) + + def __format__(self, fmt): + if not isinstance(fmt, str): + raise TypeError("must be str, not %s" % type(fmt).__name__) + if len(fmt) != 0: + return self.strftime(fmt) + return str(self) + + def isoformat(self): + """Return the date formatted according to ISO. + + This is 'YYYY-MM-DD'. + + References: + - http://www.w3.org/TR/NOTE-datetime + - http://www.cl.cam.ac.uk/~mgk25/iso-time.html + """ + return "%04d-%02d-%02d" % (self._year, self._month, self._day) + + __str__ = isoformat + + # Read-only field accessors + @property + def year(self): + """year (1-9999)""" + return self._year + + @property + def month(self): + """month (1-12)""" + return self._month + + @property + def day(self): + """day (1-31)""" + return self._day + + # Standard conversions, __eq__, __le__, __lt__, __ge__, __gt__, + # __hash__ (and helpers) + + def timetuple(self): + "Return local time tuple compatible with time.localtime()." + return _build_struct_time(self._year, self._month, self._day, + 0, 0, 0, -1) + + def toordinal(self): + """Return proleptic Gregorian ordinal for the year, month and day. + + January 1 of year 1 is day 1. Only the year, month and day values + contribute to the result. + """ + return _ymd2ord(self._year, self._month, self._day) + + def replace(self, year=None, month=None, day=None): + """Return a new date with new values for the specified fields.""" + if year is None: + year = self._year + if month is None: + month = self._month + if day is None: + day = self._day + return type(self)(year, month, day) + + # Comparisons of date objects with other. + + def __eq__(self, other): + if isinstance(other, date): + return self._cmp(other) == 0 + return NotImplemented + + def __le__(self, other): + if isinstance(other, date): + return self._cmp(other) <= 0 + return NotImplemented + + def __lt__(self, other): + if isinstance(other, date): + return self._cmp(other) < 0 + return NotImplemented + + def __ge__(self, other): + if isinstance(other, date): + return self._cmp(other) >= 0 + return NotImplemented + + def __gt__(self, other): + if isinstance(other, date): + return self._cmp(other) > 0 + return NotImplemented + + def _cmp(self, other): + assert isinstance(other, date) + y, m, d = self._year, self._month, self._day + y2, m2, d2 = other._year, other._month, other._day + return _cmp((y, m, d), (y2, m2, d2)) + + def __hash__(self): + "Hash." + if self._hashcode == -1: + self._hashcode = hash(self._getstate()) + return self._hashcode + + # Computations + + def __add__(self, other): + "Add a date to a timedelta." + if isinstance(other, timedelta): + o = self.toordinal() + other.days + if 0 < o <= _MAXORDINAL: + return type(self).fromordinal(o) + raise OverflowError("result out of range") + return NotImplemented + + __radd__ = __add__ + + def __sub__(self, other): + """Subtract two dates, or a date and a timedelta.""" + if isinstance(other, timedelta): + return self + timedelta(-other.days) + if isinstance(other, date): + days1 = self.toordinal() + days2 = other.toordinal() + return timedelta(days1 - days2) + return NotImplemented + + def weekday(self): + "Return day of the week, where Monday == 0 ... Sunday == 6." + return (self.toordinal() + 6) % 7 + + # Day-of-the-week and week-of-the-year, according to ISO + + def isoweekday(self): + "Return day of the week, where Monday == 1 ... Sunday == 7." + # 1-Jan-0001 is a Monday + return self.toordinal() % 7 or 7 + + def isocalendar(self): + """Return a named tuple containing ISO year, week number, and weekday. + + The first ISO week of the year is the (Mon-Sun) week + containing the year's first Thursday; everything else derives + from that. + + The first week is 1; Monday is 1 ... Sunday is 7. + + ISO calendar algorithm taken from + http://www.phys.uu.nl/~vgent/calendar/isocalendar.htm + (used with permission) + """ + year = self._year + week1monday = _isoweek1monday(year) + today = _ymd2ord(self._year, self._month, self._day) + # Internally, week and day have origin 0 + week, day = divmod(today - week1monday, 7) + if week < 0: + year -= 1 + week1monday = _isoweek1monday(year) + week, day = divmod(today - week1monday, 7) + elif week >= 52: + if today >= _isoweek1monday(year+1): + year += 1 + week = 0 + return _IsoCalendarDate(year, week+1, day+1) + + # Pickle support. + + def _getstate(self): + yhi, ylo = divmod(self._year, 256) + return bytes([yhi, ylo, self._month, self._day]), + + def __setstate(self, string): + yhi, ylo, self._month, self._day = string + self._year = yhi * 256 + ylo + + def __reduce__(self): + return (self.__class__, self._getstate()) + +_date_class = date # so functions w/ args named "date" can get at the class + +date.min = date(1, 1, 1) +date.max = date(9999, 12, 31) +date.resolution = timedelta(days=1) + + +class tzinfo: + """Abstract base class for time zone info classes. + + Subclasses must override the tzname(), utcoffset() and dst() methods. + """ + __slots__ = () + + def tzname(self, dt): + "datetime -> string name of time zone." + raise NotImplementedError("tzinfo subclass must override tzname()") + + def utcoffset(self, dt): + "datetime -> timedelta, positive for east of UTC, negative for west of UTC" + raise NotImplementedError("tzinfo subclass must override utcoffset()") + + def dst(self, dt): + """datetime -> DST offset as timedelta, positive for east of UTC. + + Return 0 if DST not in effect. utcoffset() must include the DST + offset. + """ + raise NotImplementedError("tzinfo subclass must override dst()") + + def fromutc(self, dt): + "datetime in UTC -> datetime in local time." + + if not isinstance(dt, datetime): + raise TypeError("fromutc() requires a datetime argument") + if dt.tzinfo is not self: + raise ValueError("dt.tzinfo is not self") + + dtoff = dt.utcoffset() + if dtoff is None: + raise ValueError("fromutc() requires a non-None utcoffset() " + "result") + + # See the long comment block at the end of this file for an + # explanation of this algorithm. + dtdst = dt.dst() + if dtdst is None: + raise ValueError("fromutc() requires a non-None dst() result") + delta = dtoff - dtdst + if delta: + dt += delta + dtdst = dt.dst() + if dtdst is None: + raise ValueError("fromutc(): dt.dst gave inconsistent " + "results; cannot convert") + return dt + dtdst + + # Pickle support. + + def __reduce__(self): + getinitargs = getattr(self, "__getinitargs__", None) + if getinitargs: + args = getinitargs() + else: + args = () + return (self.__class__, args, self.__getstate__()) + + +class IsoCalendarDate(tuple): + + def __new__(cls, year, week, weekday, /): + return super().__new__(cls, (year, week, weekday)) + + @property + def year(self): + return self[0] + + @property + def week(self): + return self[1] + + @property + def weekday(self): + return self[2] + + def __reduce__(self): + # This code is intended to pickle the object without making the + # class public. See https://bugs.python.org/msg352381 + return (tuple, (tuple(self),)) + + def __repr__(self): + return (f'{self.__class__.__name__}' + f'(year={self[0]}, week={self[1]}, weekday={self[2]})') + + +_IsoCalendarDate = IsoCalendarDate +del IsoCalendarDate +_tzinfo_class = tzinfo + +class time: + """Time with time zone. + + Constructors: + + __new__() + + Operators: + + __repr__, __str__ + __eq__, __le__, __lt__, __ge__, __gt__, __hash__ + + Methods: + + strftime() + isoformat() + utcoffset() + tzname() + dst() + + Properties (readonly): + hour, minute, second, microsecond, tzinfo, fold + """ + __slots__ = '_hour', '_minute', '_second', '_microsecond', '_tzinfo', '_hashcode', '_fold' + + def __new__(cls, hour=0, minute=0, second=0, microsecond=0, tzinfo=None, *, fold=0): + """Constructor. + + Arguments: + + hour, minute (required) + second, microsecond (default to zero) + tzinfo (default to None) + fold (keyword only, default to zero) + """ + if (isinstance(hour, (bytes, str)) and len(hour) == 6 and + ord(hour[0:1])&0x7F < 24): + # Pickle support + if isinstance(hour, str): + try: + hour = hour.encode('latin1') + except UnicodeEncodeError: + # More informative error message. + raise ValueError( + "Failed to encode latin1 string when unpickling " + "a time object. " + "pickle.load(data, encoding='latin1') is assumed.") + self = object.__new__(cls) + self.__setstate(hour, minute or None) + self._hashcode = -1 + return self + hour, minute, second, microsecond, fold = _check_time_fields( + hour, minute, second, microsecond, fold) + _check_tzinfo_arg(tzinfo) + self = object.__new__(cls) + self._hour = hour + self._minute = minute + self._second = second + self._microsecond = microsecond + self._tzinfo = tzinfo + self._hashcode = -1 + self._fold = fold + return self + + # Read-only field accessors + @property + def hour(self): + """hour (0-23)""" + return self._hour + + @property + def minute(self): + """minute (0-59)""" + return self._minute + + @property + def second(self): + """second (0-59)""" + return self._second + + @property + def microsecond(self): + """microsecond (0-999999)""" + return self._microsecond + + @property + def tzinfo(self): + """timezone info object""" + return self._tzinfo + + @property + def fold(self): + return self._fold + + # Standard conversions, __hash__ (and helpers) + + # Comparisons of time objects with other. + + def __eq__(self, other): + if isinstance(other, time): + return self._cmp(other, allow_mixed=True) == 0 + else: + return NotImplemented + + def __le__(self, other): + if isinstance(other, time): + return self._cmp(other) <= 0 + else: + return NotImplemented + + def __lt__(self, other): + if isinstance(other, time): + return self._cmp(other) < 0 + else: + return NotImplemented + + def __ge__(self, other): + if isinstance(other, time): + return self._cmp(other) >= 0 + else: + return NotImplemented + + def __gt__(self, other): + if isinstance(other, time): + return self._cmp(other) > 0 + else: + return NotImplemented + + def _cmp(self, other, allow_mixed=False): + assert isinstance(other, time) + mytz = self._tzinfo + ottz = other._tzinfo + myoff = otoff = None + + if mytz is ottz: + base_compare = True + else: + myoff = self.utcoffset() + otoff = other.utcoffset() + base_compare = myoff == otoff + + if base_compare: + return _cmp((self._hour, self._minute, self._second, + self._microsecond), + (other._hour, other._minute, other._second, + other._microsecond)) + if myoff is None or otoff is None: + if allow_mixed: + return 2 # arbitrary non-zero value + else: + raise TypeError("cannot compare naive and aware times") + myhhmm = self._hour * 60 + self._minute - myoff//timedelta(minutes=1) + othhmm = other._hour * 60 + other._minute - otoff//timedelta(minutes=1) + return _cmp((myhhmm, self._second, self._microsecond), + (othhmm, other._second, other._microsecond)) + + def __hash__(self): + """Hash.""" + if self._hashcode == -1: + if self.fold: + t = self.replace(fold=0) + else: + t = self + tzoff = t.utcoffset() + if not tzoff: # zero or None + self._hashcode = hash(t._getstate()[0]) + else: + h, m = divmod(timedelta(hours=self.hour, minutes=self.minute) - tzoff, + timedelta(hours=1)) + assert not m % timedelta(minutes=1), "whole minute" + m //= timedelta(minutes=1) + if 0 <= h < 24: + self._hashcode = hash(time(h, m, self.second, self.microsecond)) + else: + self._hashcode = hash((h, m, self.second, self.microsecond)) + return self._hashcode + + # Conversion to string + + def _tzstr(self): + """Return formatted timezone offset (+xx:xx) or an empty string.""" + off = self.utcoffset() + return _format_offset(off) + + def __repr__(self): + """Convert to formal string, for repr().""" + if self._microsecond != 0: + s = ", %d, %d" % (self._second, self._microsecond) + elif self._second != 0: + s = ", %d" % self._second + else: + s = "" + s= "%s.%s(%d, %d%s)" % (_get_class_module(self), + self.__class__.__qualname__, + self._hour, self._minute, s) + if self._tzinfo is not None: + assert s[-1:] == ")" + s = s[:-1] + ", tzinfo=%r" % self._tzinfo + ")" + if self._fold: + assert s[-1:] == ")" + s = s[:-1] + ", fold=1)" + return s + + def isoformat(self, timespec='auto'): + """Return the time formatted according to ISO. + + The full format is 'HH:MM:SS.mmmmmm+zz:zz'. By default, the fractional + part is omitted if self.microsecond == 0. + + The optional argument timespec specifies the number of additional + terms of the time to include. Valid options are 'auto', 'hours', + 'minutes', 'seconds', 'milliseconds' and 'microseconds'. + """ + s = _format_time(self._hour, self._minute, self._second, + self._microsecond, timespec) + tz = self._tzstr() + if tz: + s += tz + return s + + __str__ = isoformat + + @classmethod + def fromisoformat(cls, time_string): + """Construct a time from a string in one of the ISO 8601 formats.""" + if not isinstance(time_string, str): + raise TypeError('fromisoformat: argument must be str') + + # The spec actually requires that time-only ISO 8601 strings start with + # T, but the extended format allows this to be omitted as long as there + # is no ambiguity with date strings. + time_string = time_string.removeprefix('T') + + try: + return cls(*_parse_isoformat_time(time_string)) + except Exception: + raise ValueError(f'Invalid isoformat string: {time_string!r}') + + def strftime(self, format): + """Format using strftime(). The date part of the timestamp passed + to underlying strftime should not be used. + """ + # The year must be >= 1000 else Python's strftime implementation + # can raise a bogus exception. + timetuple = (1900, 1, 1, + self._hour, self._minute, self._second, + 0, 1, -1) + return _wrap_strftime(self, format, timetuple) + + def __format__(self, fmt): + if not isinstance(fmt, str): + raise TypeError("must be str, not %s" % type(fmt).__name__) + if len(fmt) != 0: + return self.strftime(fmt) + return str(self) + + # Timezone functions + + def utcoffset(self): + """Return the timezone offset as timedelta, positive east of UTC + (negative west of UTC).""" + if self._tzinfo is None: + return None + offset = self._tzinfo.utcoffset(None) + _check_utc_offset("utcoffset", offset) + return offset + + def tzname(self): + """Return the timezone name. + + Note that the name is 100% informational -- there's no requirement that + it mean anything in particular. For example, "GMT", "UTC", "-500", + "-5:00", "EDT", "US/Eastern", "America/New York" are all valid replies. + """ + if self._tzinfo is None: + return None + name = self._tzinfo.tzname(None) + _check_tzname(name) + return name + + def dst(self): + """Return 0 if DST is not in effect, or the DST offset (as timedelta + positive eastward) if DST is in effect. + + This is purely informational; the DST offset has already been added to + the UTC offset returned by utcoffset() if applicable, so there's no + need to consult dst() unless you're interested in displaying the DST + info. + """ + if self._tzinfo is None: + return None + offset = self._tzinfo.dst(None) + _check_utc_offset("dst", offset) + return offset + + def replace(self, hour=None, minute=None, second=None, microsecond=None, + tzinfo=True, *, fold=None): + """Return a new time with new values for the specified fields.""" + if hour is None: + hour = self.hour + if minute is None: + minute = self.minute + if second is None: + second = self.second + if microsecond is None: + microsecond = self.microsecond + if tzinfo is True: + tzinfo = self.tzinfo + if fold is None: + fold = self._fold + return type(self)(hour, minute, second, microsecond, tzinfo, fold=fold) + + # Pickle support. + + def _getstate(self, protocol=3): + us2, us3 = divmod(self._microsecond, 256) + us1, us2 = divmod(us2, 256) + h = self._hour + if self._fold and protocol > 3: + h += 128 + basestate = bytes([h, self._minute, self._second, + us1, us2, us3]) + if self._tzinfo is None: + return (basestate,) + else: + return (basestate, self._tzinfo) + + def __setstate(self, string, tzinfo): + if tzinfo is not None and not isinstance(tzinfo, _tzinfo_class): + raise TypeError("bad tzinfo state arg") + h, self._minute, self._second, us1, us2, us3 = string + if h > 127: + self._fold = 1 + self._hour = h - 128 + else: + self._fold = 0 + self._hour = h + self._microsecond = (((us1 << 8) | us2) << 8) | us3 + self._tzinfo = tzinfo + + def __reduce_ex__(self, protocol): + return (self.__class__, self._getstate(protocol)) + + def __reduce__(self): + return self.__reduce_ex__(2) + +_time_class = time # so functions w/ args named "time" can get at the class + +time.min = time(0, 0, 0) +time.max = time(23, 59, 59, 999999) +time.resolution = timedelta(microseconds=1) + + +class datetime(date): + """datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]]) + + The year, month and day arguments are required. tzinfo may be None, or an + instance of a tzinfo subclass. The remaining arguments may be ints. + """ + __slots__ = date.__slots__ + time.__slots__ + + def __new__(cls, year, month=None, day=None, hour=0, minute=0, second=0, + microsecond=0, tzinfo=None, *, fold=0): + if (isinstance(year, (bytes, str)) and len(year) == 10 and + 1 <= ord(year[2:3])&0x7F <= 12): + # Pickle support + if isinstance(year, str): + try: + year = bytes(year, 'latin1') + except UnicodeEncodeError: + # More informative error message. + raise ValueError( + "Failed to encode latin1 string when unpickling " + "a datetime object. " + "pickle.load(data, encoding='latin1') is assumed.") + self = object.__new__(cls) + self.__setstate(year, month) + self._hashcode = -1 + return self + year, month, day = _check_date_fields(year, month, day) + hour, minute, second, microsecond, fold = _check_time_fields( + hour, minute, second, microsecond, fold) + _check_tzinfo_arg(tzinfo) + self = object.__new__(cls) + self._year = year + self._month = month + self._day = day + self._hour = hour + self._minute = minute + self._second = second + self._microsecond = microsecond + self._tzinfo = tzinfo + self._hashcode = -1 + self._fold = fold + return self + + # Read-only field accessors + @property + def hour(self): + """hour (0-23)""" + return self._hour + + @property + def minute(self): + """minute (0-59)""" + return self._minute + + @property + def second(self): + """second (0-59)""" + return self._second + + @property + def microsecond(self): + """microsecond (0-999999)""" + return self._microsecond + + @property + def tzinfo(self): + """timezone info object""" + return self._tzinfo + + @property + def fold(self): + return self._fold + + @classmethod + def _fromtimestamp(cls, t, utc, tz): + """Construct a datetime from a POSIX timestamp (like time.time()). + + A timezone info object may be passed in as well. + """ + frac, t = _math.modf(t) + us = round(frac * 1e6) + if us >= 1000000: + t += 1 + us -= 1000000 + elif us < 0: + t -= 1 + us += 1000000 + + converter = _time.gmtime if utc else _time.localtime + y, m, d, hh, mm, ss, weekday, jday, dst = converter(t) + ss = min(ss, 59) # clamp out leap seconds if the platform has them + result = cls(y, m, d, hh, mm, ss, us, tz) + if tz is None and not utc: + # As of version 2015f max fold in IANA database is + # 23 hours at 1969-09-30 13:00:00 in Kwajalein. + # Let's probe 24 hours in the past to detect a transition: + max_fold_seconds = 24 * 3600 + + # On Windows localtime_s throws an OSError for negative values, + # thus we can't perform fold detection for values of time less + # than the max time fold. See comments in _datetimemodule's + # version of this method for more details. + if t < max_fold_seconds and sys.platform.startswith("win"): + return result + + y, m, d, hh, mm, ss = converter(t - max_fold_seconds)[:6] + probe1 = cls(y, m, d, hh, mm, ss, us, tz) + trans = result - probe1 - timedelta(0, max_fold_seconds) + if trans.days < 0: + y, m, d, hh, mm, ss = converter(t + trans // timedelta(0, 1))[:6] + probe2 = cls(y, m, d, hh, mm, ss, us, tz) + if probe2 == result: + result._fold = 1 + elif tz is not None: + result = tz.fromutc(result) + return result + + @classmethod + def fromtimestamp(cls, timestamp, tz=None): + """Construct a datetime from a POSIX timestamp (like time.time()). + + A timezone info object may be passed in as well. + """ + _check_tzinfo_arg(tz) + + return cls._fromtimestamp(timestamp, tz is not None, tz) + + @classmethod + def utcfromtimestamp(cls, t): + """Construct a naive UTC datetime from a POSIX timestamp.""" + import warnings + warnings.warn("datetime.utcfromtimestamp() is deprecated and scheduled " + "for removal in a future version. Use timezone-aware " + "objects to represent datetimes in UTC: " + "datetime.datetime.fromtimestamp(t, datetime.UTC).", + DeprecationWarning, + stacklevel=2) + return cls._fromtimestamp(t, True, None) + + @classmethod + def now(cls, tz=None): + "Construct a datetime from time.time() and optional time zone info." + t = _time.time() + return cls.fromtimestamp(t, tz) + + @classmethod + def utcnow(cls): + "Construct a UTC datetime from time.time()." + import warnings + warnings.warn("datetime.utcnow() is deprecated and scheduled for " + "removal in a future version. Instead, Use timezone-aware " + "objects to represent datetimes in UTC: " + "datetime.datetime.now(datetime.UTC).", + DeprecationWarning, + stacklevel=2) + t = _time.time() + return cls._fromtimestamp(t, True, None) + + @classmethod + def combine(cls, date, time, tzinfo=True): + "Construct a datetime from a given date and a given time." + if not isinstance(date, _date_class): + raise TypeError("date argument must be a date instance") + if not isinstance(time, _time_class): + raise TypeError("time argument must be a time instance") + if tzinfo is True: + tzinfo = time.tzinfo + return cls(date.year, date.month, date.day, + time.hour, time.minute, time.second, time.microsecond, + tzinfo, fold=time.fold) + + @classmethod + def fromisoformat(cls, date_string): + """Construct a datetime from a string in one of the ISO 8601 formats.""" + if not isinstance(date_string, str): + raise TypeError('fromisoformat: argument must be str') + + if len(date_string) < 7: + raise ValueError(f'Invalid isoformat string: {date_string!r}') + + # Split this at the separator + try: + separator_location = _find_isoformat_datetime_separator(date_string) + dstr = date_string[0:separator_location] + tstr = date_string[(separator_location+1):] + + date_components = _parse_isoformat_date(dstr) + except ValueError: + raise ValueError( + f'Invalid isoformat string: {date_string!r}') from None + + if tstr: + try: + time_components = _parse_isoformat_time(tstr) + except ValueError: + raise ValueError( + f'Invalid isoformat string: {date_string!r}') from None + else: + time_components = [0, 0, 0, 0, None] + + return cls(*(date_components + time_components)) + + def timetuple(self): + "Return local time tuple compatible with time.localtime()." + dst = self.dst() + if dst is None: + dst = -1 + elif dst: + dst = 1 + else: + dst = 0 + return _build_struct_time(self.year, self.month, self.day, + self.hour, self.minute, self.second, + dst) + + def _mktime(self): + """Return integer POSIX timestamp.""" + epoch = datetime(1970, 1, 1) + max_fold_seconds = 24 * 3600 + t = (self - epoch) // timedelta(0, 1) + def local(u): + y, m, d, hh, mm, ss = _time.localtime(u)[:6] + return (datetime(y, m, d, hh, mm, ss) - epoch) // timedelta(0, 1) + + # Our goal is to solve t = local(u) for u. + a = local(t) - t + u1 = t - a + t1 = local(u1) + if t1 == t: + # We found one solution, but it may not be the one we need. + # Look for an earlier solution (if `fold` is 0), or a + # later one (if `fold` is 1). + u2 = u1 + (-max_fold_seconds, max_fold_seconds)[self.fold] + b = local(u2) - u2 + if a == b: + return u1 + else: + b = t1 - u1 + assert a != b + u2 = t - b + t2 = local(u2) + if t2 == t: + return u2 + if t1 == t: + return u1 + # We have found both offsets a and b, but neither t - a nor t - b is + # a solution. This means t is in the gap. + return (max, min)[self.fold](u1, u2) + + + def timestamp(self): + "Return POSIX timestamp as float" + if self._tzinfo is None: + s = self._mktime() + return s + self.microsecond / 1e6 + else: + return (self - _EPOCH).total_seconds() + + def utctimetuple(self): + "Return UTC time tuple compatible with time.gmtime()." + offset = self.utcoffset() + if offset: + self -= offset + y, m, d = self.year, self.month, self.day + hh, mm, ss = self.hour, self.minute, self.second + return _build_struct_time(y, m, d, hh, mm, ss, 0) + + def date(self): + "Return the date part." + return date(self._year, self._month, self._day) + + def time(self): + "Return the time part, with tzinfo None." + return time(self.hour, self.minute, self.second, self.microsecond, fold=self.fold) + + def timetz(self): + "Return the time part, with same tzinfo." + return time(self.hour, self.minute, self.second, self.microsecond, + self._tzinfo, fold=self.fold) + + def replace(self, year=None, month=None, day=None, hour=None, + minute=None, second=None, microsecond=None, tzinfo=True, + *, fold=None): + """Return a new datetime with new values for the specified fields.""" + if year is None: + year = self.year + if month is None: + month = self.month + if day is None: + day = self.day + if hour is None: + hour = self.hour + if minute is None: + minute = self.minute + if second is None: + second = self.second + if microsecond is None: + microsecond = self.microsecond + if tzinfo is True: + tzinfo = self.tzinfo + if fold is None: + fold = self.fold + return type(self)(year, month, day, hour, minute, second, + microsecond, tzinfo, fold=fold) + + def _local_timezone(self): + if self.tzinfo is None: + ts = self._mktime() + # Detect gap + ts2 = self.replace(fold=1-self.fold)._mktime() + if ts2 != ts: # This happens in a gap or a fold + if (ts2 > ts) == self.fold: + ts = ts2 + else: + ts = (self - _EPOCH) // timedelta(seconds=1) + localtm = _time.localtime(ts) + local = datetime(*localtm[:6]) + # Extract TZ data + gmtoff = localtm.tm_gmtoff + zone = localtm.tm_zone + return timezone(timedelta(seconds=gmtoff), zone) + + def astimezone(self, tz=None): + if tz is None: + tz = self._local_timezone() + elif not isinstance(tz, tzinfo): + raise TypeError("tz argument must be an instance of tzinfo") + + mytz = self.tzinfo + if mytz is None: + mytz = self._local_timezone() + myoffset = mytz.utcoffset(self) + else: + myoffset = mytz.utcoffset(self) + if myoffset is None: + mytz = self.replace(tzinfo=None)._local_timezone() + myoffset = mytz.utcoffset(self) + + if tz is mytz: + return self + + # Convert self to UTC, and attach the new time zone object. + utc = (self - myoffset).replace(tzinfo=tz) + + # Convert from UTC to tz's local time. + return tz.fromutc(utc) + + # Ways to produce a string. + + def ctime(self): + "Return ctime() style string." + weekday = self.toordinal() % 7 or 7 + return "%s %s %2d %02d:%02d:%02d %04d" % ( + _DAYNAMES[weekday], + _MONTHNAMES[self._month], + self._day, + self._hour, self._minute, self._second, + self._year) + + def isoformat(self, sep='T', timespec='auto'): + """Return the time formatted according to ISO. + + The full format looks like 'YYYY-MM-DD HH:MM:SS.mmmmmm'. + By default, the fractional part is omitted if self.microsecond == 0. + + If self.tzinfo is not None, the UTC offset is also attached, giving + giving a full format of 'YYYY-MM-DD HH:MM:SS.mmmmmm+HH:MM'. + + Optional argument sep specifies the separator between date and + time, default 'T'. + + The optional argument timespec specifies the number of additional + terms of the time to include. Valid options are 'auto', 'hours', + 'minutes', 'seconds', 'milliseconds' and 'microseconds'. + """ + s = ("%04d-%02d-%02d%c" % (self._year, self._month, self._day, sep) + + _format_time(self._hour, self._minute, self._second, + self._microsecond, timespec)) + + off = self.utcoffset() + tz = _format_offset(off) + if tz: + s += tz + + return s + + def __repr__(self): + """Convert to formal string, for repr().""" + L = [self._year, self._month, self._day, # These are never zero + self._hour, self._minute, self._second, self._microsecond] + if L[-1] == 0: + del L[-1] + if L[-1] == 0: + del L[-1] + s = "%s.%s(%s)" % (_get_class_module(self), + self.__class__.__qualname__, + ", ".join(map(str, L))) + if self._tzinfo is not None: + assert s[-1:] == ")" + s = s[:-1] + ", tzinfo=%r" % self._tzinfo + ")" + if self._fold: + assert s[-1:] == ")" + s = s[:-1] + ", fold=1)" + return s + + def __str__(self): + "Convert to string, for str()." + return self.isoformat(sep=' ') + + @classmethod + def strptime(cls, date_string, format): + 'string, format -> new datetime parsed from a string (like time.strptime()).' + import _strptime + return _strptime._strptime_datetime(cls, date_string, format) + + def utcoffset(self): + """Return the timezone offset as timedelta positive east of UTC (negative west of + UTC).""" + if self._tzinfo is None: + return None + offset = self._tzinfo.utcoffset(self) + _check_utc_offset("utcoffset", offset) + return offset + + def tzname(self): + """Return the timezone name. + + Note that the name is 100% informational -- there's no requirement that + it mean anything in particular. For example, "GMT", "UTC", "-500", + "-5:00", "EDT", "US/Eastern", "America/New York" are all valid replies. + """ + if self._tzinfo is None: + return None + name = self._tzinfo.tzname(self) + _check_tzname(name) + return name + + def dst(self): + """Return 0 if DST is not in effect, or the DST offset (as timedelta + positive eastward) if DST is in effect. + + This is purely informational; the DST offset has already been added to + the UTC offset returned by utcoffset() if applicable, so there's no + need to consult dst() unless you're interested in displaying the DST + info. + """ + if self._tzinfo is None: + return None + offset = self._tzinfo.dst(self) + _check_utc_offset("dst", offset) + return offset + + # Comparisons of datetime objects with other. + + def __eq__(self, other): + if isinstance(other, datetime): + return self._cmp(other, allow_mixed=True) == 0 + elif not isinstance(other, date): + return NotImplemented + else: + return False + + def __le__(self, other): + if isinstance(other, datetime): + return self._cmp(other) <= 0 + elif not isinstance(other, date): + return NotImplemented + else: + _cmperror(self, other) + + def __lt__(self, other): + if isinstance(other, datetime): + return self._cmp(other) < 0 + elif not isinstance(other, date): + return NotImplemented + else: + _cmperror(self, other) + + def __ge__(self, other): + if isinstance(other, datetime): + return self._cmp(other) >= 0 + elif not isinstance(other, date): + return NotImplemented + else: + _cmperror(self, other) + + def __gt__(self, other): + if isinstance(other, datetime): + return self._cmp(other) > 0 + elif not isinstance(other, date): + return NotImplemented + else: + _cmperror(self, other) + + def _cmp(self, other, allow_mixed=False): + assert isinstance(other, datetime) + mytz = self._tzinfo + ottz = other._tzinfo + myoff = otoff = None + + if mytz is ottz: + base_compare = True + else: + myoff = self.utcoffset() + otoff = other.utcoffset() + # Assume that allow_mixed means that we are called from __eq__ + if allow_mixed: + if myoff != self.replace(fold=not self.fold).utcoffset(): + return 2 + if otoff != other.replace(fold=not other.fold).utcoffset(): + return 2 + base_compare = myoff == otoff + + if base_compare: + return _cmp((self._year, self._month, self._day, + self._hour, self._minute, self._second, + self._microsecond), + (other._year, other._month, other._day, + other._hour, other._minute, other._second, + other._microsecond)) + if myoff is None or otoff is None: + if allow_mixed: + return 2 # arbitrary non-zero value + else: + raise TypeError("cannot compare naive and aware datetimes") + # XXX What follows could be done more efficiently... + diff = self - other # this will take offsets into account + if diff.days < 0: + return -1 + return diff and 1 or 0 + + def __add__(self, other): + "Add a datetime and a timedelta." + if not isinstance(other, timedelta): + return NotImplemented + delta = timedelta(self.toordinal(), + hours=self._hour, + minutes=self._minute, + seconds=self._second, + microseconds=self._microsecond) + delta += other + hour, rem = divmod(delta.seconds, 3600) + minute, second = divmod(rem, 60) + if 0 < delta.days <= _MAXORDINAL: + return type(self).combine(date.fromordinal(delta.days), + time(hour, minute, second, + delta.microseconds, + tzinfo=self._tzinfo)) + raise OverflowError("result out of range") + + __radd__ = __add__ + + def __sub__(self, other): + "Subtract two datetimes, or a datetime and a timedelta." + if not isinstance(other, datetime): + if isinstance(other, timedelta): + return self + -other + return NotImplemented + + days1 = self.toordinal() + days2 = other.toordinal() + secs1 = self._second + self._minute * 60 + self._hour * 3600 + secs2 = other._second + other._minute * 60 + other._hour * 3600 + base = timedelta(days1 - days2, + secs1 - secs2, + self._microsecond - other._microsecond) + if self._tzinfo is other._tzinfo: + return base + myoff = self.utcoffset() + otoff = other.utcoffset() + if myoff == otoff: + return base + if myoff is None or otoff is None: + raise TypeError("cannot mix naive and timezone-aware time") + return base + otoff - myoff + + def __hash__(self): + if self._hashcode == -1: + if self.fold: + t = self.replace(fold=0) + else: + t = self + tzoff = t.utcoffset() + if tzoff is None: + self._hashcode = hash(t._getstate()[0]) + else: + days = _ymd2ord(self.year, self.month, self.day) + seconds = self.hour * 3600 + self.minute * 60 + self.second + self._hashcode = hash(timedelta(days, seconds, self.microsecond) - tzoff) + return self._hashcode + + # Pickle support. + + def _getstate(self, protocol=3): + yhi, ylo = divmod(self._year, 256) + us2, us3 = divmod(self._microsecond, 256) + us1, us2 = divmod(us2, 256) + m = self._month + if self._fold and protocol > 3: + m += 128 + basestate = bytes([yhi, ylo, m, self._day, + self._hour, self._minute, self._second, + us1, us2, us3]) + if self._tzinfo is None: + return (basestate,) + else: + return (basestate, self._tzinfo) + + def __setstate(self, string, tzinfo): + if tzinfo is not None and not isinstance(tzinfo, _tzinfo_class): + raise TypeError("bad tzinfo state arg") + (yhi, ylo, m, self._day, self._hour, + self._minute, self._second, us1, us2, us3) = string + if m > 127: + self._fold = 1 + self._month = m - 128 + else: + self._fold = 0 + self._month = m + self._year = yhi * 256 + ylo + self._microsecond = (((us1 << 8) | us2) << 8) | us3 + self._tzinfo = tzinfo + + def __reduce_ex__(self, protocol): + return (self.__class__, self._getstate(protocol)) + + def __reduce__(self): + return self.__reduce_ex__(2) + + +datetime.min = datetime(1, 1, 1) +datetime.max = datetime(9999, 12, 31, 23, 59, 59, 999999) +datetime.resolution = timedelta(microseconds=1) + + +def _isoweek1monday(year): + # Helper to calculate the day number of the Monday starting week 1 + # XXX This could be done more efficiently + THURSDAY = 3 + firstday = _ymd2ord(year, 1, 1) + firstweekday = (firstday + 6) % 7 # See weekday() above + week1monday = firstday - firstweekday + if firstweekday > THURSDAY: + week1monday += 7 + return week1monday + + +class timezone(tzinfo): + __slots__ = '_offset', '_name' + + # Sentinel value to disallow None + _Omitted = object() + def __new__(cls, offset, name=_Omitted): + if not isinstance(offset, timedelta): + raise TypeError("offset must be a timedelta") + if name is cls._Omitted: + if not offset: + return cls.utc + name = None + elif not isinstance(name, str): + raise TypeError("name must be a string") + if not cls._minoffset <= offset <= cls._maxoffset: + raise ValueError("offset must be a timedelta " + "strictly between -timedelta(hours=24) and " + "timedelta(hours=24).") + return cls._create(offset, name) + + @classmethod + def _create(cls, offset, name=None): + self = tzinfo.__new__(cls) + self._offset = offset + self._name = name + return self + + def __getinitargs__(self): + """pickle support""" + if self._name is None: + return (self._offset,) + return (self._offset, self._name) + + def __eq__(self, other): + if isinstance(other, timezone): + return self._offset == other._offset + return NotImplemented + + def __hash__(self): + return hash(self._offset) + + def __repr__(self): + """Convert to formal string, for repr(). + + >>> tz = timezone.utc + >>> repr(tz) + 'datetime.timezone.utc' + >>> tz = timezone(timedelta(hours=-5), 'EST') + >>> repr(tz) + "datetime.timezone(datetime.timedelta(-1, 68400), 'EST')" + """ + if self is self.utc: + return 'datetime.timezone.utc' + if self._name is None: + return "%s.%s(%r)" % (_get_class_module(self), + self.__class__.__qualname__, + self._offset) + return "%s.%s(%r, %r)" % (_get_class_module(self), + self.__class__.__qualname__, + self._offset, self._name) + + def __str__(self): + return self.tzname(None) + + def utcoffset(self, dt): + if isinstance(dt, datetime) or dt is None: + return self._offset + raise TypeError("utcoffset() argument must be a datetime instance" + " or None") + + def tzname(self, dt): + if isinstance(dt, datetime) or dt is None: + if self._name is None: + return self._name_from_offset(self._offset) + return self._name + raise TypeError("tzname() argument must be a datetime instance" + " or None") + + def dst(self, dt): + if isinstance(dt, datetime) or dt is None: + return None + raise TypeError("dst() argument must be a datetime instance" + " or None") + + def fromutc(self, dt): + if isinstance(dt, datetime): + if dt.tzinfo is not self: + raise ValueError("fromutc: dt.tzinfo " + "is not self") + return dt + self._offset + raise TypeError("fromutc() argument must be a datetime instance" + " or None") + + _maxoffset = timedelta(hours=24, microseconds=-1) + _minoffset = -_maxoffset + + @staticmethod + def _name_from_offset(delta): + if not delta: + return 'UTC' + if delta < timedelta(0): + sign = '-' + delta = -delta + else: + sign = '+' + hours, rest = divmod(delta, timedelta(hours=1)) + minutes, rest = divmod(rest, timedelta(minutes=1)) + seconds = rest.seconds + microseconds = rest.microseconds + if microseconds: + return (f'UTC{sign}{hours:02d}:{minutes:02d}:{seconds:02d}' + f'.{microseconds:06d}') + if seconds: + return f'UTC{sign}{hours:02d}:{minutes:02d}:{seconds:02d}' + return f'UTC{sign}{hours:02d}:{minutes:02d}' + +UTC = timezone.utc = timezone._create(timedelta(0)) + +# bpo-37642: These attributes are rounded to the nearest minute for backwards +# compatibility, even though the constructor will accept a wider range of +# values. This may change in the future. +timezone.min = timezone._create(-timedelta(hours=23, minutes=59)) +timezone.max = timezone._create(timedelta(hours=23, minutes=59)) +_EPOCH = datetime(1970, 1, 1, tzinfo=timezone.utc) + +# Some time zone algebra. For a datetime x, let +# x.n = x stripped of its timezone -- its naive time. +# x.o = x.utcoffset(), and assuming that doesn't raise an exception or +# return None +# x.d = x.dst(), and assuming that doesn't raise an exception or +# return None +# x.s = x's standard offset, x.o - x.d +# +# Now some derived rules, where k is a duration (timedelta). +# +# 1. x.o = x.s + x.d +# This follows from the definition of x.s. +# +# 2. If x and y have the same tzinfo member, x.s = y.s. +# This is actually a requirement, an assumption we need to make about +# sane tzinfo classes. +# +# 3. The naive UTC time corresponding to x is x.n - x.o. +# This is again a requirement for a sane tzinfo class. +# +# 4. (x+k).s = x.s +# This follows from #2, and that datetime.timetz+timedelta preserves tzinfo. +# +# 5. (x+k).n = x.n + k +# Again follows from how arithmetic is defined. +# +# Now we can explain tz.fromutc(x). Let's assume it's an interesting case +# (meaning that the various tzinfo methods exist, and don't blow up or return +# None when called). +# +# The function wants to return a datetime y with timezone tz, equivalent to x. +# x is already in UTC. +# +# By #3, we want +# +# y.n - y.o = x.n [1] +# +# The algorithm starts by attaching tz to x.n, and calling that y. So +# x.n = y.n at the start. Then it wants to add a duration k to y, so that [1] +# becomes true; in effect, we want to solve [2] for k: +# +# (y+k).n - (y+k).o = x.n [2] +# +# By #1, this is the same as +# +# (y+k).n - ((y+k).s + (y+k).d) = x.n [3] +# +# By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start. +# Substituting that into [3], +# +# x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving +# k - (y+k).s - (y+k).d = 0; rearranging, +# k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so +# k = y.s - (y+k).d +# +# On the RHS, (y+k).d can't be computed directly, but y.s can be, and we +# approximate k by ignoring the (y+k).d term at first. Note that k can't be +# very large, since all offset-returning methods return a duration of magnitude +# less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must +# be 0, so ignoring it has no consequence then. +# +# In any case, the new value is +# +# z = y + y.s [4] +# +# It's helpful to step back at look at [4] from a higher level: it's simply +# mapping from UTC to tz's standard time. +# +# At this point, if +# +# z.n - z.o = x.n [5] +# +# we have an equivalent time, and are almost done. The insecurity here is +# at the start of daylight time. Picture US Eastern for concreteness. The wall +# time jumps from 1:59 to 3:00, and wall hours of the form 2:MM don't make good +# sense then. The docs ask that an Eastern tzinfo class consider such a time to +# be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST +# on the day DST starts. We want to return the 1:MM EST spelling because that's +# the only spelling that makes sense on the local wall clock. +# +# In fact, if [5] holds at this point, we do have the standard-time spelling, +# but that takes a bit of proof. We first prove a stronger result. What's the +# difference between the LHS and RHS of [5]? Let +# +# diff = x.n - (z.n - z.o) [6] +# +# Now +# z.n = by [4] +# (y + y.s).n = by #5 +# y.n + y.s = since y.n = x.n +# x.n + y.s = since z and y are have the same tzinfo member, +# y.s = z.s by #2 +# x.n + z.s +# +# Plugging that back into [6] gives +# +# diff = +# x.n - ((x.n + z.s) - z.o) = expanding +# x.n - x.n - z.s + z.o = cancelling +# - z.s + z.o = by #2 +# z.d +# +# So diff = z.d. +# +# If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time +# spelling we wanted in the endcase described above. We're done. Contrarily, +# if z.d = 0, then we have a UTC equivalent, and are also done. +# +# If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to +# add to z (in effect, z is in tz's standard time, and we need to shift the +# local clock into tz's daylight time). +# +# Let +# +# z' = z + z.d = z + diff [7] +# +# and we can again ask whether +# +# z'.n - z'.o = x.n [8] +# +# If so, we're done. If not, the tzinfo class is insane, according to the +# assumptions we've made. This also requires a bit of proof. As before, let's +# compute the difference between the LHS and RHS of [8] (and skipping some of +# the justifications for the kinds of substitutions we've done several times +# already): +# +# diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7] +# x.n - (z.n + diff - z'.o) = replacing diff via [6] +# x.n - (z.n + x.n - (z.n - z.o) - z'.o) = +# x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n +# - z.n + z.n - z.o + z'.o = cancel z.n +# - z.o + z'.o = #1 twice +# -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo +# z'.d - z.d +# +# So z' is UTC-equivalent to x iff z'.d = z.d at this point. If they are equal, +# we've found the UTC-equivalent so are done. In fact, we stop with [7] and +# return z', not bothering to compute z'.d. +# +# How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by +# a dst() offset, and starting *from* a time already in DST (we know z.d != 0), +# would have to change the result dst() returns: we start in DST, and moving +# a little further into it takes us out of DST. +# +# There isn't a sane case where this can happen. The closest it gets is at +# the end of DST, where there's an hour in UTC with no spelling in a hybrid +# tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During +# that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM +# UTC) because the docs insist on that, but 0:MM is taken as being in daylight +# time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local +# clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in +# standard time. Since that's what the local clock *does*, we want to map both +# UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous +# in local time, but so it goes -- it's the way the local clock works. +# +# When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0, +# so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going. +# z' = z + z.d = 1:MM then, and z'.d=0, and z'.d - z.d = -60 != 0 so [8] +# (correctly) concludes that z' is not UTC-equivalent to x. +# +# Because we know z.d said z was in daylight time (else [5] would have held and +# we would have stopped then), and we know z.d != z'.d (else [8] would have held +# and we have stopped then), and there are only 2 possible values dst() can +# return in Eastern, it follows that z'.d must be 0 (which it is in the example, +# but the reasoning doesn't depend on the example -- it depends on there being +# two possible dst() outcomes, one zero and the other non-zero). Therefore +# z' must be in standard time, and is the spelling we want in this case. +# +# Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is +# concerned (because it takes z' as being in standard time rather than the +# daylight time we intend here), but returning it gives the real-life "local +# clock repeats an hour" behavior when mapping the "unspellable" UTC hour into +# tz. +# +# When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with +# the 1:MM standard time spelling we want. +# +# So how can this break? One of the assumptions must be violated. Two +# possibilities: +# +# 1) [2] effectively says that y.s is invariant across all y belong to a given +# time zone. This isn't true if, for political reasons or continental drift, +# a region decides to change its base offset from UTC. +# +# 2) There may be versions of "double daylight" time where the tail end of +# the analysis gives up a step too early. I haven't thought about that +# enough to say. +# +# In any case, it's clear that the default fromutc() is strong enough to handle +# "almost all" time zones: so long as the standard offset is invariant, it +# doesn't matter if daylight time transition points change from year to year, or +# if daylight time is skipped in some years; it doesn't matter how large or +# small dst() may get within its bounds; and it doesn't even matter if some +# perverse time zone returns a negative dst()). So a breaking case must be +# pretty bizarre, and a tzinfo subclass can override fromutc() if it is. diff --git a/Lib/_pydecimal.py b/Lib/_pydecimal.py index f9d6c990..2692f2fc 100644 --- a/Lib/_pydecimal.py +++ b/Lib/_pydecimal.py @@ -159,7 +159,7 @@ import sys try: from collections import namedtuple as _namedtuple - DecimalTuple = _namedtuple('DecimalTuple', 'sign digits exponent') + DecimalTuple = _namedtuple('DecimalTuple', 'sign digits exponent', module='decimal') except ImportError: DecimalTuple = lambda *args: args diff --git a/Lib/_pyio.py b/Lib/_pyio.py index 0bfdeaaf..7f247ff4 100644 --- a/Lib/_pyio.py +++ b/Lib/_pyio.py @@ -303,22 +303,6 @@ except AttributeError: open_code = _open_code_with_warning -def __getattr__(name): - if name == "OpenWrapper": - # bpo-43680: Until Python 3.9, _pyio.open was not a static method and - # builtins.open was set to OpenWrapper to not become a bound method - # when set to a class variable. _io.open is a built-in function whereas - # _pyio.open is a Python function. In Python 3.10, _pyio.open() is now - # a static method, and builtins.open() is now io.open(). - import warnings - warnings.warn('OpenWrapper is deprecated, use open instead', - DeprecationWarning, stacklevel=2) - global OpenWrapper - OpenWrapper = open - return OpenWrapper - raise AttributeError(f"module {__name__!r} has no attribute {name!r}") - - # In normal operation, both `UnsupportedOperation`s should be bound to the # same object. try: @@ -654,10 +638,7 @@ class RawIOBase(IOBase): def readall(self): """Read until EOF, using multiple read() call.""" res = bytearray() - while True: - data = self.read(DEFAULT_BUFFER_SIZE) - if not data: - break + while data := self.read(DEFAULT_BUFFER_SIZE): res += data if res: return bytes(res) @@ -1145,6 +1126,7 @@ class BufferedReader(_BufferedIOMixin): do at most one raw read to satisfy it. We never return more than self.buffer_size. """ + self._checkClosed("peek of closed file") with self._read_lock: return self._peek_unlocked(size) @@ -1163,6 +1145,7 @@ class BufferedReader(_BufferedIOMixin): """Reads up to size bytes, with at most one read() system call.""" # Returns up to size bytes. If at least one byte is buffered, we # only return buffered bytes. Otherwise, we do one raw read. + self._checkClosed("read of closed file") if size < 0: size = self.buffer_size if size == 0: @@ -1180,6 +1163,8 @@ class BufferedReader(_BufferedIOMixin): def _readinto(self, buf, read1): """Read data into *buf* with at most one system call.""" + self._checkClosed("readinto of closed file") + # Need to create a memoryview object of type 'b', otherwise # we may not be able to assign bytes to it, and slicing it # would create a new object. @@ -1229,6 +1214,7 @@ class BufferedReader(_BufferedIOMixin): def seek(self, pos, whence=0): if whence not in valid_seek_flags: raise ValueError("invalid whence value") + self._checkClosed("seek of closed file") with self._read_lock: if whence == 1: pos -= len(self._read_buf) - self._read_pos diff --git a/Lib/_pylong.py b/Lib/_pylong.py new file mode 100644 index 00000000..936346e1 --- /dev/null +++ b/Lib/_pylong.py @@ -0,0 +1,285 @@ +"""Python implementations of some algorithms for use by longobject.c. +The goal is to provide asymptotically faster algorithms that can be +used for operations on integers with many digits. In those cases, the +performance overhead of the Python implementation is not significant +since the asymptotic behavior is what dominates runtime. Functions +provided by this module should be considered private and not part of any +public API. + +Note: for ease of maintainability, please prefer clear code and avoid +"micro-optimizations". This module will only be imported and used for +integers with a huge number of digits. Saving a few microseconds with +tricky or non-obvious code is not worth it. For people looking for +maximum performance, they should use something like gmpy2.""" + +import re +import decimal + + +def int_to_decimal(n): + """Asymptotically fast conversion of an 'int' to Decimal.""" + + # Function due to Tim Peters. See GH issue #90716 for details. + # https://github.com/python/cpython/issues/90716 + # + # The implementation in longobject.c of base conversion algorithms + # between power-of-2 and non-power-of-2 bases are quadratic time. + # This function implements a divide-and-conquer algorithm that is + # faster for large numbers. Builds an equal decimal.Decimal in a + # "clever" recursive way. If we want a string representation, we + # apply str to _that_. + + D = decimal.Decimal + D2 = D(2) + + BITLIM = 128 + + mem = {} + + def w2pow(w): + """Return D(2)**w and store the result. Also possibly save some + intermediate results. In context, these are likely to be reused + across various levels of the conversion to Decimal.""" + if (result := mem.get(w)) is None: + if w <= BITLIM: + result = D2**w + elif w - 1 in mem: + result = (t := mem[w - 1]) + t + else: + w2 = w >> 1 + # If w happens to be odd, w-w2 is one larger then w2 + # now. Recurse on the smaller first (w2), so that it's + # in the cache and the larger (w-w2) can be handled by + # the cheaper `w-1 in mem` branch instead. + result = w2pow(w2) * w2pow(w - w2) + mem[w] = result + return result + + def inner(n, w): + if w <= BITLIM: + return D(n) + w2 = w >> 1 + hi = n >> w2 + lo = n - (hi << w2) + return inner(lo, w2) + inner(hi, w - w2) * w2pow(w2) + + with decimal.localcontext() as ctx: + ctx.prec = decimal.MAX_PREC + ctx.Emax = decimal.MAX_EMAX + ctx.Emin = decimal.MIN_EMIN + ctx.traps[decimal.Inexact] = 1 + + if n < 0: + negate = True + n = -n + else: + negate = False + result = inner(n, n.bit_length()) + if negate: + result = -result + return result + + +def int_to_decimal_string(n): + """Asymptotically fast conversion of an 'int' to a decimal string.""" + return str(int_to_decimal(n)) + + +def _str_to_int_inner(s): + """Asymptotically fast conversion of a 'str' to an 'int'.""" + + # Function due to Bjorn Martinsson. See GH issue #90716 for details. + # https://github.com/python/cpython/issues/90716 + # + # The implementation in longobject.c of base conversion algorithms + # between power-of-2 and non-power-of-2 bases are quadratic time. + # This function implements a divide-and-conquer algorithm making use + # of Python's built in big int multiplication. Since Python uses the + # Karatsuba algorithm for multiplication, the time complexity + # of this function is O(len(s)**1.58). + + DIGLIM = 2048 + + mem = {} + + def w5pow(w): + """Return 5**w and store the result. + Also possibly save some intermediate results. In context, these + are likely to be reused across various levels of the conversion + to 'int'. + """ + if (result := mem.get(w)) is None: + if w <= DIGLIM: + result = 5**w + elif w - 1 in mem: + result = mem[w - 1] * 5 + else: + w2 = w >> 1 + # If w happens to be odd, w-w2 is one larger then w2 + # now. Recurse on the smaller first (w2), so that it's + # in the cache and the larger (w-w2) can be handled by + # the cheaper `w-1 in mem` branch instead. + result = w5pow(w2) * w5pow(w - w2) + mem[w] = result + return result + + def inner(a, b): + if b - a <= DIGLIM: + return int(s[a:b]) + mid = (a + b + 1) >> 1 + return inner(mid, b) + ((inner(a, mid) * w5pow(b - mid)) << (b - mid)) + + return inner(0, len(s)) + + +def int_from_string(s): + """Asymptotically fast version of PyLong_FromString(), conversion + of a string of decimal digits into an 'int'.""" + # PyLong_FromString() has already removed leading +/-, checked for invalid + # use of underscore characters, checked that string consists of only digits + # and underscores, and stripped leading whitespace. The input can still + # contain underscores and have trailing whitespace. + s = s.rstrip().replace('_', '') + return _str_to_int_inner(s) + + +def str_to_int(s): + """Asymptotically fast version of decimal string to 'int' conversion.""" + # FIXME: this doesn't support the full syntax that int() supports. + m = re.match(r'\s*([+-]?)([0-9_]+)\s*', s) + if not m: + raise ValueError('invalid literal for int() with base 10') + v = int_from_string(m.group(2)) + if m.group(1) == '-': + v = -v + return v + + +# Fast integer division, based on code from Mark Dickinson, fast_div.py +# GH-47701. Additional refinements and optimizations by Bjorn Martinsson. The +# algorithm is due to Burnikel and Ziegler, in their paper "Fast Recursive +# Division". + +_DIV_LIMIT = 4000 + + +def _div2n1n(a, b, n): + """Divide a 2n-bit nonnegative integer a by an n-bit positive integer + b, using a recursive divide-and-conquer algorithm. + + Inputs: + n is a positive integer + b is a positive integer with exactly n bits + a is a nonnegative integer such that a < 2**n * b + + Output: + (q, r) such that a = b*q+r and 0 <= r < b. + + """ + if a.bit_length() - n <= _DIV_LIMIT: + return divmod(a, b) + pad = n & 1 + if pad: + a <<= 1 + b <<= 1 + n += 1 + half_n = n >> 1 + mask = (1 << half_n) - 1 + b1, b2 = b >> half_n, b & mask + q1, r = _div3n2n(a >> n, (a >> half_n) & mask, b, b1, b2, half_n) + q2, r = _div3n2n(r, a & mask, b, b1, b2, half_n) + if pad: + r >>= 1 + return q1 << half_n | q2, r + + +def _div3n2n(a12, a3, b, b1, b2, n): + """Helper function for _div2n1n; not intended to be called directly.""" + if a12 >> n == b1: + q, r = (1 << n) - 1, a12 - (b1 << n) + b1 + else: + q, r = _div2n1n(a12, b1, n) + r = (r << n | a3) - q * b2 + while r < 0: + q -= 1 + r += b + return q, r + + +def _int2digits(a, n): + """Decompose non-negative int a into base 2**n + + Input: + a is a non-negative integer + + Output: + List of the digits of a in base 2**n in little-endian order, + meaning the most significant digit is last. The most + significant digit is guaranteed to be non-zero. + If a is 0 then the output is an empty list. + + """ + a_digits = [0] * ((a.bit_length() + n - 1) // n) + + def inner(x, L, R): + if L + 1 == R: + a_digits[L] = x + return + mid = (L + R) >> 1 + shift = (mid - L) * n + upper = x >> shift + lower = x ^ (upper << shift) + inner(lower, L, mid) + inner(upper, mid, R) + + if a: + inner(a, 0, len(a_digits)) + return a_digits + + +def _digits2int(digits, n): + """Combine base-2**n digits into an int. This function is the + inverse of `_int2digits`. For more details, see _int2digits. + """ + + def inner(L, R): + if L + 1 == R: + return digits[L] + mid = (L + R) >> 1 + shift = (mid - L) * n + return (inner(mid, R) << shift) + inner(L, mid) + + return inner(0, len(digits)) if digits else 0 + + +def _divmod_pos(a, b): + """Divide a non-negative integer a by a positive integer b, giving + quotient and remainder.""" + # Use grade-school algorithm in base 2**n, n = nbits(b) + n = b.bit_length() + a_digits = _int2digits(a, n) + + r = 0 + q_digits = [] + for a_digit in reversed(a_digits): + q_digit, r = _div2n1n((r << n) + a_digit, b, n) + q_digits.append(q_digit) + q_digits.reverse() + q = _digits2int(q_digits, n) + return q, r + + +def int_divmod(a, b): + """Asymptotically fast replacement for divmod, for 'int'. + Its time complexity is O(n**1.58), where n = #bits(a) + #bits(b). + """ + if b == 0: + raise ZeroDivisionError + elif b < 0: + q, r = int_divmod(-a, -b) + return q, -r + elif a < 0: + q, r = int_divmod(~a, b) + return ~q, b + ~r + else: + return _divmod_pos(a, b) diff --git a/Lib/_strptime.py b/Lib/_strptime.py index b97dfcce..77ccdc9e 100644 --- a/Lib/_strptime.py +++ b/Lib/_strptime.py @@ -290,22 +290,6 @@ def _calc_julian_from_U_or_W(year, week_of_year, day_of_week, week_starts_Mon): return 1 + days_to_week + day_of_week -def _calc_julian_from_V(iso_year, iso_week, iso_weekday): - """Calculate the Julian day based on the ISO 8601 year, week, and weekday. - ISO weeks start on Mondays, with week 01 being the week containing 4 Jan. - ISO week days range from 1 (Monday) to 7 (Sunday). - """ - correction = datetime_date(iso_year, 1, 4).isoweekday() + 3 - ordinal = (iso_week * 7) + iso_weekday - correction - # ordinal may be negative or 0 now, which means the date is in the previous - # calendar year - if ordinal < 1: - ordinal += datetime_date(iso_year, 1, 1).toordinal() - iso_year -= 1 - ordinal -= datetime_date(iso_year, 1, 1).toordinal() - return iso_year, ordinal - - def _strptime(data_string, format="%a %b %d %H:%M:%S %Y"): """Return a 2-tuple consisting of a time struct and an int containing the number of microseconds based on the input string and the @@ -483,7 +467,8 @@ def _strptime(data_string, format="%a %b %d %H:%M:%S %Y"): else: tz = value break - # Deal with the cases where ambiguities arize + + # Deal with the cases where ambiguities arise # don't assume default values for ISO week/year if year is None and iso_year is not None: if iso_week is None or weekday is None: @@ -511,7 +496,6 @@ def _strptime(data_string, format="%a %b %d %H:%M:%S %Y"): elif year is None: year = 1900 - # If we know the week of the year and what day of that week, we can figure # out the Julian day of the year. if julian is None and weekday is not None: @@ -520,7 +504,10 @@ def _strptime(data_string, format="%a %b %d %H:%M:%S %Y"): julian = _calc_julian_from_U_or_W(year, week_of_year, weekday, week_starts_Mon) elif iso_year is not None and iso_week is not None: - year, julian = _calc_julian_from_V(iso_year, iso_week, weekday + 1) + datetime_result = datetime_date.fromisocalendar(iso_year, iso_week, weekday + 1) + year = datetime_result.year + month = datetime_result.month + day = datetime_result.day if julian is not None and julian <= 0: year -= 1 yday = 366 if calendar.isleap(year) else 365 diff --git a/Lib/abc.py b/Lib/abc.py index 42048ddb..f8a4e11c 100644 --- a/Lib/abc.py +++ b/Lib/abc.py @@ -18,7 +18,7 @@ def abstractmethod(funcobj): class C(metaclass=ABCMeta): @abstractmethod - def my_abstract_method(self, ...): + def my_abstract_method(self, arg1, arg2, argN): ... """ funcobj.__isabstractmethod__ = True diff --git a/Lib/argparse.py b/Lib/argparse.py index 77619088..543d9944 100644 --- a/Lib/argparse.py +++ b/Lib/argparse.py @@ -345,21 +345,22 @@ class HelpFormatter(object): def get_lines(parts, indent, prefix=None): lines = [] line = [] + indent_length = len(indent) if prefix is not None: line_len = len(prefix) - 1 else: - line_len = len(indent) - 1 + line_len = indent_length - 1 for part in parts: if line_len + 1 + len(part) > text_width and line: lines.append(indent + ' '.join(line)) line = [] - line_len = len(indent) - 1 + line_len = indent_length - 1 line.append(part) line_len += len(part) + 1 if line: lines.append(indent + ' '.join(line)) if prefix is not None: - lines[0] = lines[0][len(indent):] + lines[0] = lines[0][indent_length:] return lines # if prog is short, follow it with optionals or positionals @@ -403,10 +404,18 @@ class HelpFormatter(object): except ValueError: continue else: - end = start + len(group._group_actions) + group_action_count = len(group._group_actions) + end = start + group_action_count if actions[start:end] == group._group_actions: + + suppressed_actions_count = 0 for action in group._group_actions: group_actions.add(action) + if action.help is SUPPRESS: + suppressed_actions_count += 1 + + exposed_actions_count = group_action_count - suppressed_actions_count + if not group.required: if start in inserts: inserts[start] += ' [' @@ -416,7 +425,7 @@ class HelpFormatter(object): inserts[end] += ']' else: inserts[end] = ']' - else: + elif exposed_actions_count > 1: if start in inserts: inserts[start] += ' (' else: @@ -490,7 +499,6 @@ class HelpFormatter(object): text = _re.sub(r'(%s) ' % open, r'\1', text) text = _re.sub(r' (%s)' % close, r'\1', text) text = _re.sub(r'%s *%s' % (open, close), r'', text) - text = _re.sub(r'\(([^|]*)\)', r'\1', text) text = text.strip() # return the text @@ -875,16 +883,19 @@ class Action(_AttributeHolder): raise NotImplementedError(_('.__call__() not defined')) +# FIXME: remove together with `BooleanOptionalAction` deprecated arguments. +_deprecated_default = object() + class BooleanOptionalAction(Action): def __init__(self, option_strings, dest, default=None, - type=None, - choices=None, + type=_deprecated_default, + choices=_deprecated_default, required=False, help=None, - metavar=None): + metavar=_deprecated_default): _option_strings = [] for option_string in option_strings: @@ -894,6 +905,24 @@ class BooleanOptionalAction(Action): option_string = '--no-' + option_string[2:] _option_strings.append(option_string) + # We need `_deprecated` special value to ban explicit arguments that + # match default value. Like: + # parser.add_argument('-f', action=BooleanOptionalAction, type=int) + for field_name in ('type', 'choices', 'metavar'): + if locals()[field_name] is not _deprecated_default: + warnings._deprecated( + field_name, + "{name!r} is deprecated as of Python 3.12 and will be " + "removed in Python {remove}.", + remove=(3, 14)) + + if type is _deprecated_default: + type = None + if choices is _deprecated_default: + choices = None + if metavar is _deprecated_default: + metavar = None + super().__init__( option_strings=_option_strings, dest=dest, @@ -2165,7 +2194,9 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer): # replace arguments referencing files with the file content else: try: - with open(arg_string[1:]) as args_file: + with open(arg_string[1:], + encoding=_sys.getfilesystemencoding(), + errors=_sys.getfilesystemencodeerrors()) as args_file: arg_strings = [] for arg_line in args_file.read().splitlines(): for arg in self.convert_arg_line_to_args(arg_line): @@ -2479,9 +2510,11 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer): not action.option_strings): if action.default is not None: value = action.default + self._check_value(action, value) else: + # since arg_strings is always [] at this point + # there is no need to use self._check_value(action, value) value = arg_strings - self._check_value(action, value) # single argument or optional argument produces a single value elif len(arg_strings) == 1 and action.nargs in [None, OPTIONAL]: @@ -2523,7 +2556,6 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer): # ArgumentTypeErrors indicate errors except ArgumentTypeError as err: - name = getattr(action.type, '__name__', repr(action.type)) msg = str(err) raise ArgumentError(action, msg) @@ -2595,9 +2627,11 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer): def _print_message(self, message, file=None): if message: - if file is None: - file = _sys.stderr - file.write(message) + file = file or _sys.stderr + try: + file.write(message) + except (AttributeError, OSError): + pass # =============== # Exiting methods diff --git a/Lib/ast.py b/Lib/ast.py index 623b9a1b..07044706 100644 --- a/Lib/ast.py +++ b/Lib/ast.py @@ -25,6 +25,7 @@ :license: Python License. """ import sys +import re from _ast import * from contextlib import contextmanager, nullcontext from enum import IntEnum, auto, _simple_enum @@ -40,12 +41,13 @@ def parse(source, filename='<unknown>', mode='exec', *, flags = PyCF_ONLY_AST if type_comments: flags |= PyCF_TYPE_COMMENTS - if isinstance(feature_version, tuple): + if feature_version is None: + feature_version = -1 + elif isinstance(feature_version, tuple): major, minor = feature_version # Should be a 2-tuple. - assert major == 3 + if major != 3: + raise ValueError(f"Unsupported major version: {major}") feature_version = minor - elif feature_version is None: - feature_version = -1 # Else it should be an int giving the minor version for 3.x. return compile(source, filename, mode, flags, _feature_version=feature_version) @@ -292,9 +294,7 @@ def get_docstring(node, clean=True): if not(node.body and isinstance(node.body[0], Expr)): return None node = node.body[0].value - if isinstance(node, Str): - text = node.s - elif isinstance(node, Constant) and isinstance(node.value, str): + if isinstance(node, Constant) and isinstance(node.value, str): text = node.value else: return None @@ -304,28 +304,17 @@ def get_docstring(node, clean=True): return text -def _splitlines_no_ff(source): +_line_pattern = re.compile(r"(.*?(?:\r\n|\n|\r|$))") +def _splitlines_no_ff(source, maxlines=None): """Split a string into lines ignoring form feed and other chars. This mimics how the Python parser splits source code. """ - idx = 0 lines = [] - next_line = '' - while idx < len(source): - c = source[idx] - next_line += c - idx += 1 - # Keep \r\n together - if c == '\r' and idx < len(source) and source[idx] == '\n': - next_line += '\n' - idx += 1 - if c in '\r\n': - lines.append(next_line) - next_line = '' - - if next_line: - lines.append(next_line) + for lineno, match in enumerate(_line_pattern.finditer(source), 1): + if maxlines is not None and lineno > maxlines: + break + lines.append(match[0]) return lines @@ -359,7 +348,7 @@ def get_source_segment(source, node, *, padded=False): except AttributeError: return None - lines = _splitlines_no_ff(source) + lines = _splitlines_no_ff(source, maxlines=end_lineno+1) if end_lineno == lineno: return lines[lineno].encode()[col_offset:end_col_offset].decode() @@ -508,20 +497,52 @@ class NodeTransformer(NodeVisitor): return node +_DEPRECATED_VALUE_ALIAS_MESSAGE = ( + "{name} is deprecated and will be removed in Python {remove}; use value instead" +) +_DEPRECATED_CLASS_MESSAGE = ( + "{name} is deprecated and will be removed in Python {remove}; " + "use ast.Constant instead" +) + + # If the ast module is loaded more than once, only add deprecated methods once if not hasattr(Constant, 'n'): # The following code is for backward compatibility. # It will be removed in future. - def _getter(self): + def _n_getter(self): + """Deprecated. Use value instead.""" + import warnings + warnings._deprecated( + "Attribute n", message=_DEPRECATED_VALUE_ALIAS_MESSAGE, remove=(3, 14) + ) + return self.value + + def _n_setter(self, value): + import warnings + warnings._deprecated( + "Attribute n", message=_DEPRECATED_VALUE_ALIAS_MESSAGE, remove=(3, 14) + ) + self.value = value + + def _s_getter(self): """Deprecated. Use value instead.""" + import warnings + warnings._deprecated( + "Attribute s", message=_DEPRECATED_VALUE_ALIAS_MESSAGE, remove=(3, 14) + ) return self.value - def _setter(self, value): + def _s_setter(self, value): + import warnings + warnings._deprecated( + "Attribute s", message=_DEPRECATED_VALUE_ALIAS_MESSAGE, remove=(3, 14) + ) self.value = value - Constant.n = property(_getter, _setter) - Constant.s = property(_getter, _setter) + Constant.n = property(_n_getter, _n_setter) + Constant.s = property(_s_getter, _s_setter) class _ABC(type): @@ -529,6 +550,13 @@ class _ABC(type): cls.__doc__ = """Deprecated AST node class. Use ast.Constant instead""" def __instancecheck__(cls, inst): + if cls in _const_types: + import warnings + warnings._deprecated( + f"ast.{cls.__qualname__}", + message=_DEPRECATED_CLASS_MESSAGE, + remove=(3, 14) + ) if not isinstance(inst, Constant): return False if cls in _const_types: @@ -552,6 +580,10 @@ def _new(cls, *args, **kwargs): if pos < len(args): raise TypeError(f"{cls.__name__} got multiple values for argument {key!r}") if cls in _const_types: + import warnings + warnings._deprecated( + f"ast.{cls.__qualname__}", message=_DEPRECATED_CLASS_MESSAGE, remove=(3, 14) + ) return Constant(*args, **kwargs) return Constant.__new__(cls, *args, **kwargs) @@ -574,10 +606,19 @@ class Ellipsis(Constant, metaclass=_ABC): _fields = () def __new__(cls, *args, **kwargs): - if cls is Ellipsis: + if cls is _ast_Ellipsis: + import warnings + warnings._deprecated( + "ast.Ellipsis", message=_DEPRECATED_CLASS_MESSAGE, remove=(3, 14) + ) return Constant(..., *args, **kwargs) return Constant.__new__(cls, *args, **kwargs) +# Keep another reference to Ellipsis in the global namespace +# so it can be referenced in Ellipsis.__new__ +# (The original "Ellipsis" name is removed from the global namespace later on) +_ast_Ellipsis = Ellipsis + _const_types = { Num: (int, float, complex), Str: (str,), @@ -1010,6 +1051,8 @@ class _Unparser(NodeVisitor): self.fill("@") self.traverse(deco) self.fill("class " + node.name) + if hasattr(node, "type_params"): + self._type_params_helper(node.type_params) with self.delimit_if("(", ")", condition = node.bases or node.keywords): comma = False for e in node.bases: @@ -1041,6 +1084,8 @@ class _Unparser(NodeVisitor): self.traverse(deco) def_str = fill_suffix + " " + node.name self.fill(def_str) + if hasattr(node, "type_params"): + self._type_params_helper(node.type_params) with self.delimit("(", ")"): self.traverse(node.args) if node.returns: @@ -1049,6 +1094,30 @@ class _Unparser(NodeVisitor): with self.block(extra=self.get_type_comment(node)): self._write_docstring_and_traverse_body(node) + def _type_params_helper(self, type_params): + if type_params is not None and len(type_params) > 0: + with self.delimit("[", "]"): + self.interleave(lambda: self.write(", "), self.traverse, type_params) + + def visit_TypeVar(self, node): + self.write(node.name) + if node.bound: + self.write(": ") + self.traverse(node.bound) + + def visit_TypeVarTuple(self, node): + self.write("*" + node.name) + + def visit_ParamSpec(self, node): + self.write("**" + node.name) + + def visit_TypeAlias(self, node): + self.fill("type ") + self.traverse(node.name) + self._type_params_helper(node.type_params) + self.write(" = ") + self.traverse(node.value) + def visit_For(self, node): self._for_helper("for ", node) @@ -1154,17 +1223,7 @@ class _Unparser(NodeVisitor): def visit_JoinedStr(self, node): self.write("f") - if self._avoid_backslashes: - with self.buffered() as buffer: - self._write_fstring_inner(node) - return self._write_str_avoiding_backslashes("".join(buffer)) - - # If we don't need to avoid backslashes globally (i.e., we only need - # to avoid them inside FormattedValues), it's cosmetically preferred - # to use escaped whitespace. That is, it's preferred to use backslashes - # for cases like: f"{x}\n". To accomplish this, we keep track of what - # in our buffer corresponds to FormattedValues and what corresponds to - # Constant parts of the f-string, and allow escapes accordingly. + fstring_parts = [] for value in node.values: with self.buffered() as buffer: @@ -1175,14 +1234,36 @@ class _Unparser(NodeVisitor): new_fstring_parts = [] quote_types = list(_ALL_QUOTES) + fallback_to_repr = False for value, is_constant in fstring_parts: - value, quote_types = self._str_literal_helper( - value, - quote_types=quote_types, - escape_special_whitespace=is_constant, - ) + if is_constant: + value, new_quote_types = self._str_literal_helper( + value, + quote_types=quote_types, + escape_special_whitespace=True, + ) + if set(new_quote_types).isdisjoint(quote_types): + fallback_to_repr = True + break + quote_types = new_quote_types + elif "\n" in value: + quote_types = [q for q in quote_types if q in _MULTI_QUOTES] + assert quote_types new_fstring_parts.append(value) + if fallback_to_repr: + # If we weren't able to find a quote type that works for all parts + # of the JoinedStr, fallback to using repr and triple single quotes. + quote_types = ["'''"] + new_fstring_parts.clear() + for value, is_constant in fstring_parts: + if is_constant: + value = repr('"' + value) # force repr to use single quotes + expected_prefix = "'\"" + assert value.startswith(expected_prefix), repr(value) + value = value[len(expected_prefix):-1] + new_fstring_parts.append(value) + value = "".join(new_fstring_parts) quote_type = quote_types[0] self.write(f"{quote_type}{value}{quote_type}") @@ -1202,16 +1283,12 @@ class _Unparser(NodeVisitor): def visit_FormattedValue(self, node): def unparse_inner(inner): - unparser = type(self)(_avoid_backslashes=True) + unparser = type(self)() unparser.set_precedence(_Precedence.TEST.next(), inner) return unparser.visit(inner) with self.delimit("{", "}"): expr = unparse_inner(node.value) - if "\\" in expr: - raise ValueError( - "Unable to avoid backslash in f-string expression part" - ) if expr.startswith("{"): # Separate pair of opening brackets as "{ {" self.write(" ") @@ -1708,6 +1785,22 @@ def unparse(ast_obj): return unparser.visit(ast_obj) +_deprecated_globals = { + name: globals().pop(name) + for name in ('Num', 'Str', 'Bytes', 'NameConstant', 'Ellipsis') +} + +def __getattr__(name): + if name in _deprecated_globals: + globals()[name] = value = _deprecated_globals[name] + import warnings + warnings._deprecated( + f"ast.{name}", message=_DEPRECATED_CLASS_MESSAGE, remove=(3, 14) + ) + return value + raise AttributeError(f"module 'ast' has no attribute '{name}'") + + def main(): import argparse diff --git a/Lib/asyncio/__init__.py b/Lib/asyncio/__init__.py index fed16ec7..03165a42 100644 --- a/Lib/asyncio/__init__.py +++ b/Lib/asyncio/__init__.py @@ -34,6 +34,7 @@ __all__ = (base_events.__all__ + streams.__all__ + subprocess.__all__ + tasks.__all__ + + taskgroups.__all__ + threads.__all__ + timeouts.__all__ + transports.__all__) diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py index c5c7bd46..25900465 100644 --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -377,7 +377,7 @@ class Server(events.AbstractServer): self._serving_forever_fut = None async def wait_closed(self): - if self._sockets is None or self._waiters is None: + if self._waiters is None or self._active_count == 0: return waiter = self._loop.create_future() self._waiters.append(waiter) @@ -561,8 +561,13 @@ class BaseEventLoop(events.AbstractEventLoop): 'asyncgen': agen }) - async def shutdown_default_executor(self): - """Schedule the shutdown of the default executor.""" + async def shutdown_default_executor(self, timeout=None): + """Schedule the shutdown of the default executor. + + The timeout parameter specifies the amount of time the executor will + be given to finish joining. The default value is None, which means + that the executor will be given an unlimited amount of time. + """ self._executor_shutdown_called = True if self._default_executor is None: return @@ -572,7 +577,13 @@ class BaseEventLoop(events.AbstractEventLoop): try: await future finally: - thread.join() + thread.join(timeout) + + if thread.is_alive(): + warnings.warn("The executor did not finishing joining " + f"its threads within {timeout} seconds.", + RuntimeWarning, stacklevel=2) + self._default_executor.shutdown(wait=False) def _do_shutdown(self, future): try: @@ -716,7 +727,7 @@ class BaseEventLoop(events.AbstractEventLoop): always relative to the current time. Each callback will be called exactly once. If two callbacks - are scheduled for exactly the same time, it undefined which + are scheduled for exactly the same time, it is undefined which will be called first. Any positional arguments after the callback will be passed to @@ -991,7 +1002,8 @@ class BaseEventLoop(events.AbstractEventLoop): local_addr=None, server_hostname=None, ssl_handshake_timeout=None, ssl_shutdown_timeout=None, - happy_eyeballs_delay=None, interleave=None): + happy_eyeballs_delay=None, interleave=None, + all_errors=False): """Connect to a TCP server. Create a streaming transport connection to a given internet host and @@ -1081,6 +1093,8 @@ class BaseEventLoop(events.AbstractEventLoop): if sock is None: exceptions = [exc for sub in exceptions for exc in sub] try: + if all_errors: + raise ExceptionGroup("create_connection failed", exceptions) if len(exceptions) == 1: raise exceptions[0] else: @@ -1805,7 +1819,22 @@ class BaseEventLoop(events.AbstractEventLoop): exc_info=True) else: try: - self._exception_handler(self, context) + ctx = None + thing = context.get("task") + if thing is None: + # Even though Futures don't have a context, + # Task is a subclass of Future, + # and sometimes the 'future' key holds a Task. + thing = context.get("future") + if thing is None: + # Handles also have a context. + thing = context.get("handle") + if thing is not None and hasattr(thing, "get_context"): + ctx = thing.get_context() + if ctx is not None and hasattr(ctx, "run"): + ctx.run(self._exception_handler, self, context) + else: + self._exception_handler(self, context) except (SystemExit, KeyboardInterrupt): raise except BaseException as exc: diff --git a/Lib/asyncio/base_futures.py b/Lib/asyncio/base_futures.py index cd811a78..7987963b 100644 --- a/Lib/asyncio/base_futures.py +++ b/Lib/asyncio/base_futures.py @@ -1,7 +1,6 @@ __all__ = () import reprlib -from _thread import get_ident from . import format_helpers diff --git a/Lib/asyncio/base_tasks.py b/Lib/asyncio/base_tasks.py index 26298e63..c907b683 100644 --- a/Lib/asyncio/base_tasks.py +++ b/Lib/asyncio/base_tasks.py @@ -15,11 +15,13 @@ def _task_repr_info(task): info.insert(1, 'name=%r' % task.get_name()) - coro = coroutines._format_coroutine(task._coro) - info.insert(2, f'coro=<{coro}>') - if task._fut_waiter is not None: - info.insert(3, f'wait_for={task._fut_waiter!r}') + info.insert(2, f'wait_for={task._fut_waiter!r}') + + if task._coro: + coro = coroutines._format_coroutine(task._coro) + info.insert(2, f'coro=<{coro}>') + return info diff --git a/Lib/asyncio/constants.py b/Lib/asyncio/constants.py index f171ead2..f0ce0433 100644 --- a/Lib/asyncio/constants.py +++ b/Lib/asyncio/constants.py @@ -26,6 +26,9 @@ SENDFILE_FALLBACK_READBUFFER_SIZE = 1024 * 256 FLOW_CONTROL_HIGH_WATER_SSL_READ = 256 # KiB FLOW_CONTROL_HIGH_WATER_SSL_WRITE = 512 # KiB +# Default timeout for joining the threads in the threadpool +THREAD_JOIN_TIMEOUT = 300 + # The enum should be here to break circular dependencies between # base_events and sslproto class _SendfileMode(enum.Enum): diff --git a/Lib/asyncio/coroutines.py b/Lib/asyncio/coroutines.py index 0e4b489f..ab4f30eb 100644 --- a/Lib/asyncio/coroutines.py +++ b/Lib/asyncio/coroutines.py @@ -4,7 +4,6 @@ import collections.abc import inspect import os import sys -import traceback import types @@ -26,8 +25,7 @@ def iscoroutinefunction(func): # Prioritize native coroutine check to speed-up # asyncio.iscoroutine. -_COROUTINE_TYPES = (types.CoroutineType, types.GeneratorType, - collections.abc.Coroutine) +_COROUTINE_TYPES = (types.CoroutineType, collections.abc.Coroutine) _iscoroutine_typecache = set() diff --git a/Lib/asyncio/events.py b/Lib/asyncio/events.py index b1799320..0ccf8510 100644 --- a/Lib/asyncio/events.py +++ b/Lib/asyncio/events.py @@ -13,6 +13,7 @@ __all__ = ( import contextvars import os +import signal import socket import subprocess import sys @@ -61,6 +62,9 @@ class Handle: info = self._repr_info() return '<{}>'.format(' '.join(info)) + def get_context(self): + return self._context + def cancel(self): if not self._cancelled: self._cancelled = True @@ -613,7 +617,7 @@ class AbstractEventLoopPolicy: def get_event_loop(self): """Get the event loop for the current context. - Returns an event loop object implementing the BaseEventLoop interface, + Returns an event loop object implementing the AbstractEventLoop interface, or raises an exception in case no event loop has been set for the current context and the current policy does not specify to create one. @@ -671,6 +675,23 @@ class BaseDefaultEventLoopPolicy(AbstractEventLoopPolicy): if (self._local._loop is None and not self._local._set_called and threading.current_thread() is threading.main_thread()): + stacklevel = 2 + try: + f = sys._getframe(1) + except AttributeError: + pass + else: + # Move up the call stack so that the warning is attached + # to the line outside asyncio itself. + while f: + module = f.f_globals.get('__name__') + if not (module == 'asyncio' or module.startswith('asyncio.')): + break + f = f.f_back + stacklevel += 1 + import warnings + warnings.warn('There is no current event loop', + DeprecationWarning, stacklevel=stacklevel) self.set_event_loop(self.new_event_loop()) if self._local._loop is None: @@ -782,14 +803,6 @@ def get_event_loop(): the result of `get_event_loop_policy().get_event_loop()` call. """ # NOTE: this function is implemented in C (see _asynciomodule.c) - return _py__get_event_loop() - - -def _get_event_loop(stacklevel=3): - # This internal method is going away in Python 3.12, left here only for - # backwards compatibility with 3.10.0 - 3.10.8 and 3.11.0. - # Similarly, this method's C equivalent in _asyncio is going away as well. - # See GH-99949 for more details. current_loop = _get_running_loop() if current_loop is not None: return current_loop @@ -822,7 +835,6 @@ _py__get_running_loop = _get_running_loop _py__set_running_loop = _set_running_loop _py_get_running_loop = get_running_loop _py_get_event_loop = get_event_loop -_py__get_event_loop = _get_event_loop try: @@ -830,7 +842,7 @@ try: # functions in asyncio. Pure Python implementation is # about 4 times slower than C-accelerated. from _asyncio import (_get_running_loop, _set_running_loop, - get_running_loop, get_event_loop, _get_event_loop) + get_running_loop, get_event_loop) except ImportError: pass else: @@ -839,4 +851,14 @@ else: _c__set_running_loop = _set_running_loop _c_get_running_loop = get_running_loop _c_get_event_loop = get_event_loop - _c__get_event_loop = _get_event_loop + + +if hasattr(os, 'fork'): + def on_fork(): + # Reset the loop and wakeupfd in the forked child process. + if _event_loop_policy is not None: + _event_loop_policy._local = BaseDefaultEventLoopPolicy._Local() + _set_running_loop(None) + signal.set_wakeup_fd(-1) + + os.register_at_fork(after_in_child=on_fork) diff --git a/Lib/asyncio/futures.py b/Lib/asyncio/futures.py index 3a6b44a0..97fc4e3f 100644 --- a/Lib/asyncio/futures.py +++ b/Lib/asyncio/futures.py @@ -77,7 +77,7 @@ class Future: the default event loop. """ if loop is None: - self._loop = events._get_event_loop() + self._loop = events.get_event_loop() else: self._loop = loop self._callbacks = [] @@ -413,7 +413,7 @@ def wrap_future(future, *, loop=None): assert isinstance(future, concurrent.futures.Future), \ f'concurrent.futures.Future is expected, got {future!r}' if loop is None: - loop = events._get_event_loop() + loop = events.get_event_loop() new_future = loop.create_future() _chain_future(future, new_future) return new_future diff --git a/Lib/asyncio/locks.py b/Lib/asyncio/locks.py index fd41dfd3..ce5d8d5b 100644 --- a/Lib/asyncio/locks.py +++ b/Lib/asyncio/locks.py @@ -8,7 +8,6 @@ import enum from . import exceptions from . import mixins -from . import tasks class _ContextManagerMixin: async def __aenter__(self): diff --git a/Lib/asyncio/proactor_events.py b/Lib/asyncio/proactor_events.py index c6aab408..1e2a730c 100644 --- a/Lib/asyncio/proactor_events.py +++ b/Lib/asyncio/proactor_events.py @@ -288,7 +288,8 @@ class _ProactorReadPipeTransport(_ProactorBasePipeTransport, # we got end-of-file so no need to reschedule a new read return - data = self._data[:length] + # It's a new slice so make it immutable so protocols upstream don't have problems + data = bytes(memoryview(self._data)[:length]) else: # the future will be replaced by next proactor.recv call fut.cancel() diff --git a/Lib/asyncio/runners.py b/Lib/asyncio/runners.py index b3e0c44b..1b892365 100644 --- a/Lib/asyncio/runners.py +++ b/Lib/asyncio/runners.py @@ -5,12 +5,11 @@ import enum import functools import threading import signal -import sys from . import coroutines from . import events from . import exceptions from . import tasks - +from . import constants class _State(enum.Enum): CREATED = "created" @@ -70,7 +69,8 @@ class Runner: loop = self._loop _cancel_all_tasks(loop) loop.run_until_complete(loop.shutdown_asyncgens()) - loop.run_until_complete(loop.shutdown_default_executor()) + loop.run_until_complete( + loop.shutdown_default_executor(constants.THREAD_JOIN_TIMEOUT)) finally: if self._set_event_loop: events.set_event_loop(None) @@ -157,12 +157,12 @@ class Runner: raise KeyboardInterrupt() -def run(main, *, debug=None): +def run(main, *, debug=None, loop_factory=None): """Execute the coroutine and return the result. This function runs the passed coroutine, taking care of - managing the asyncio event loop and finalizing asynchronous - generators. + managing the asyncio event loop, finalizing asynchronous + generators and closing the default executor. This function cannot be called when another asyncio event loop is running in the same thread. @@ -173,6 +173,10 @@ def run(main, *, debug=None): It should be used as a main entry point for asyncio programs, and should ideally only be called once. + The executor is given a timeout duration of 5 minutes to shutdown. + If the executor hasn't finished within that duration, a warning is + emitted and the executor is closed. + Example: async def main(): @@ -186,7 +190,7 @@ def run(main, *, debug=None): raise RuntimeError( "asyncio.run() cannot be called from a running event loop") - with Runner(debug=debug) as runner: + with Runner(debug=debug, loop_factory=loop_factory) as runner: return runner.run(main) diff --git a/Lib/asyncio/selector_events.py b/Lib/asyncio/selector_events.py index 8ab420d5..f895750e 100644 --- a/Lib/asyncio/selector_events.py +++ b/Lib/asyncio/selector_events.py @@ -9,6 +9,8 @@ __all__ = 'BaseSelectorEventLoop', import collections import errno import functools +import itertools +import os import selectors import socket import warnings @@ -28,6 +30,14 @@ from . import transports from . import trsock from .log import logger +_HAS_SENDMSG = hasattr(socket.socket, 'sendmsg') + +if _HAS_SENDMSG: + try: + SC_IOV_MAX = os.sysconf('SC_IOV_MAX') + except OSError: + # Fallback to send + _HAS_SENDMSG = False def _test_selector_event(selector, fd, event): # Test if the selector is monitoring 'event' events @@ -58,6 +68,7 @@ class BaseSelectorEventLoop(base_events.BaseEventLoop): def _make_socket_transport(self, sock, protocol, waiter=None, *, extra=None, server=None): + self._ensure_fd_no_transport(sock) return _SelectorSocketTransport(self, sock, protocol, waiter, extra, server) @@ -68,6 +79,7 @@ class BaseSelectorEventLoop(base_events.BaseEventLoop): ssl_handshake_timeout=constants.SSL_HANDSHAKE_TIMEOUT, ssl_shutdown_timeout=constants.SSL_SHUTDOWN_TIMEOUT, ): + self._ensure_fd_no_transport(rawsock) ssl_protocol = sslproto.SSLProtocol( self, protocol, sslcontext, waiter, server_side, server_hostname, @@ -80,6 +92,7 @@ class BaseSelectorEventLoop(base_events.BaseEventLoop): def _make_datagram_transport(self, sock, protocol, address=None, waiter=None, extra=None): + self._ensure_fd_no_transport(sock) return _SelectorDatagramTransport(self, sock, protocol, address, waiter, extra) @@ -754,8 +767,6 @@ class _SelectorTransport(transports._FlowControlMixin, max_size = 256 * 1024 # Buffer size passed to recv(). - _buffer_factory = bytearray # Constructs initial value for self._buffer. - # Attribute used in the destructor: it must be set even if the constructor # is not called (see _SelectorSslTransport which may start by raising an # exception) @@ -780,9 +791,11 @@ class _SelectorTransport(transports._FlowControlMixin, self.set_protocol(protocol) self._server = server - self._buffer = self._buffer_factory() + self._buffer = collections.deque() self._conn_lost = 0 # Set when call to connection_lost scheduled. self._closing = False # Set when close() called. + self._paused = False # Set when pause_reading() called + if self._server is not None: self._server._attach() loop._transports[self._sock_fd] = self @@ -828,6 +841,25 @@ class _SelectorTransport(transports._FlowControlMixin, def is_closing(self): return self._closing + def is_reading(self): + return not self.is_closing() and not self._paused + + def pause_reading(self): + if not self.is_reading(): + return + self._paused = True + self._loop._remove_reader(self._sock_fd) + if self._loop.get_debug(): + logger.debug("%r pauses reading", self) + + def resume_reading(self): + if self._closing or not self._paused: + return + self._paused = False + self._add_reader(self._sock_fd, self._read_ready) + if self._loop.get_debug(): + logger.debug("%r resumes reading", self) + def close(self): if self._closing: return @@ -884,12 +916,11 @@ class _SelectorTransport(transports._FlowControlMixin, self._server = None def get_write_buffer_size(self): - return len(self._buffer) + return sum(map(len, self._buffer)) def _add_reader(self, fd, callback, *args): - if self._closing: + if not self.is_reading(): return - self._loop._add_reader(fd, callback, *args) @@ -904,9 +935,11 @@ class _SelectorSocketTransport(_SelectorTransport): self._read_ready_cb = None super().__init__(loop, sock, protocol, extra, server) self._eof = False - self._paused = False self._empty_waiter = None - + if _HAS_SENDMSG: + self._write_ready = self._write_sendmsg + else: + self._write_ready = self._write_send # Disable the Nagle algorithm -- small writes will be # sent without waiting for the TCP ACK. This generally # decreases the latency (in some cases significantly.) @@ -929,25 +962,6 @@ class _SelectorSocketTransport(_SelectorTransport): super().set_protocol(protocol) - def is_reading(self): - return not self._paused and not self._closing - - def pause_reading(self): - if self._closing or self._paused: - return - self._paused = True - self._loop._remove_reader(self._sock_fd) - if self._loop.get_debug(): - logger.debug("%r pauses reading", self) - - def resume_reading(self): - if self._closing or not self._paused: - return - self._paused = False - self._add_reader(self._sock_fd, self._read_ready) - if self._loop.get_debug(): - logger.debug("%r resumes reading", self) - def _read_ready(self): self._read_ready_cb() @@ -1063,23 +1077,68 @@ class _SelectorSocketTransport(_SelectorTransport): self._fatal_error(exc, 'Fatal write error on socket transport') return else: - data = data[n:] + data = memoryview(data)[n:] if not data: return # Not all was written; register write handler. self._loop._add_writer(self._sock_fd, self._write_ready) # Add it to the buffer. - self._buffer.extend(data) + self._buffer.append(data) self._maybe_pause_protocol() - def _write_ready(self): + def _get_sendmsg_buffer(self): + return itertools.islice(self._buffer, SC_IOV_MAX) + + def _write_sendmsg(self): assert self._buffer, 'Data should not be empty' + if self._conn_lost: + return + try: + nbytes = self._sock.sendmsg(self._get_sendmsg_buffer()) + self._adjust_leftover_buffer(nbytes) + except (BlockingIOError, InterruptedError): + pass + except (SystemExit, KeyboardInterrupt): + raise + except BaseException as exc: + self._loop._remove_writer(self._sock_fd) + self._buffer.clear() + self._fatal_error(exc, 'Fatal write error on socket transport') + if self._empty_waiter is not None: + self._empty_waiter.set_exception(exc) + else: + self._maybe_resume_protocol() # May append to buffer. + if not self._buffer: + self._loop._remove_writer(self._sock_fd) + if self._empty_waiter is not None: + self._empty_waiter.set_result(None) + if self._closing: + self._call_connection_lost(None) + elif self._eof: + self._sock.shutdown(socket.SHUT_WR) + def _adjust_leftover_buffer(self, nbytes: int) -> None: + buffer = self._buffer + while nbytes: + b = buffer.popleft() + b_len = len(b) + if b_len <= nbytes: + nbytes -= b_len + else: + buffer.appendleft(b[nbytes:]) + break + + def _write_send(self): + assert self._buffer, 'Data should not be empty' if self._conn_lost: return try: - n = self._sock.send(self._buffer) + buffer = self._buffer.popleft() + n = self._sock.send(buffer) + if n != len(buffer): + # Not all data was written + self._buffer.appendleft(buffer[n:]) except (BlockingIOError, InterruptedError): pass except (SystemExit, KeyboardInterrupt): @@ -1091,8 +1150,6 @@ class _SelectorSocketTransport(_SelectorTransport): if self._empty_waiter is not None: self._empty_waiter.set_exception(exc) else: - if n: - del self._buffer[:n] self._maybe_resume_protocol() # May append to buffer. if not self._buffer: self._loop._remove_writer(self._sock_fd) @@ -1110,6 +1167,19 @@ class _SelectorSocketTransport(_SelectorTransport): if not self._buffer: self._sock.shutdown(socket.SHUT_WR) + def writelines(self, list_of_data): + if self._eof: + raise RuntimeError('Cannot call writelines() after write_eof()') + if self._empty_waiter is not None: + raise RuntimeError('unable to writelines; sendfile is in progress') + if not list_of_data: + return + self._buffer.extend([memoryview(data) for data in list_of_data]) + self._write_ready() + # If the entire buffer couldn't be written, register a write handler + if self._buffer: + self._loop._add_writer(self._sock_fd, self._write_ready) + def can_write_eof(self): return True @@ -1130,8 +1200,13 @@ class _SelectorSocketTransport(_SelectorTransport): def _reset_empty_waiter(self): self._empty_waiter = None + def close(self): + self._read_ready_cb = None + self._write_ready = None + super().close() + -class _SelectorDatagramTransport(_SelectorTransport): +class _SelectorDatagramTransport(_SelectorTransport, transports.DatagramTransport): _buffer_factory = collections.deque diff --git a/Lib/asyncio/sslproto.py b/Lib/asyncio/sslproto.py index bbf9cad6..488e17d8 100644 --- a/Lib/asyncio/sslproto.py +++ b/Lib/asyncio/sslproto.py @@ -244,7 +244,8 @@ class _SSLProtocolTransport(transports._FlowControlMixin, called with None as its argument. """ self._closed = True - self._ssl_protocol._abort() + if self._ssl_protocol is not None: + self._ssl_protocol._abort() def _force_close(self, exc): self._closed = True diff --git a/Lib/asyncio/streams.py b/Lib/asyncio/streams.py index d21a31d1..14861dff 100644 --- a/Lib/asyncio/streams.py +++ b/Lib/asyncio/streams.py @@ -5,7 +5,6 @@ __all__ = ( import collections import socket import sys -import warnings import weakref if hasattr(socket, 'AF_UNIX'): @@ -126,7 +125,7 @@ class FlowControlMixin(protocols.Protocol): def __init__(self, loop=None): if loop is None: - self._loop = events._get_event_loop(stacklevel=4) + self._loop = events.get_event_loop() else: self._loop = loop self._paused = False @@ -379,7 +378,8 @@ class StreamWriter: async def start_tls(self, sslcontext, *, server_hostname=None, - ssl_handshake_timeout=None): + ssl_handshake_timeout=None, + ssl_shutdown_timeout=None): """Upgrade an existing stream-based connection to TLS.""" server_side = self._protocol._client_connected_cb is not None protocol = self._protocol @@ -387,10 +387,15 @@ class StreamWriter: new_transport = await self._loop.start_tls( # type: ignore self._transport, protocol, sslcontext, server_side=server_side, server_hostname=server_hostname, - ssl_handshake_timeout=ssl_handshake_timeout) + ssl_handshake_timeout=ssl_handshake_timeout, + ssl_shutdown_timeout=ssl_shutdown_timeout) self._transport = new_transport protocol._replace_writer(self) + def __del__(self): + if not self._transport.is_closing(): + self.close() + class StreamReader: @@ -405,7 +410,7 @@ class StreamReader: self._limit = limit if loop is None: - self._loop = events._get_event_loop() + self._loop = events.get_event_loop() else: self._loop = loop self._buffer = bytearray() @@ -648,16 +653,17 @@ class StreamReader: async def read(self, n=-1): """Read up to `n` bytes from the stream. - If n is not provided, or set to -1, read until EOF and return all read - bytes. If the EOF was received and the internal buffer is empty, return - an empty bytes object. + If `n` is not provided or set to -1, + read until EOF, then return all read bytes. + If EOF was received and the internal buffer is empty, + return an empty bytes object. - If n is zero, return empty bytes object immediately. + If `n` is 0, return an empty bytes object immediately. - If n is positive, this function try to read `n` bytes, and may return - less or equal bytes than requested, but at least one byte. If EOF was - received before any byte is read, this function returns empty byte - object. + If `n` is positive, return at most `n` available bytes + as soon as at least 1 byte is available in the internal buffer. + If EOF is received before any byte is read, return an empty + bytes object. Returned value is not limited with limit, configured at stream creation. @@ -689,7 +695,7 @@ class StreamReader: await self._wait_for_data('read') # This will work right even if buffer is less than n bytes - data = bytes(self._buffer[:n]) + data = bytes(memoryview(self._buffer)[:n]) del self._buffer[:n] self._maybe_resume_transport() @@ -731,7 +737,7 @@ class StreamReader: data = bytes(self._buffer) self._buffer.clear() else: - data = bytes(self._buffer[:n]) + data = bytes(memoryview(self._buffer)[:n]) del self._buffer[:n] self._maybe_resume_transport() return data diff --git a/Lib/asyncio/subprocess.py b/Lib/asyncio/subprocess.py index cd10231f..c4e5ba20 100644 --- a/Lib/asyncio/subprocess.py +++ b/Lib/asyncio/subprocess.py @@ -81,6 +81,9 @@ class SubprocessStreamProtocol(streams.FlowControlMixin, self._stdin_closed.set_result(None) else: self._stdin_closed.set_exception(exc) + # Since calling `wait_closed()` is not mandatory, + # we shouldn't log the traceback if this is not awaited. + self._stdin_closed._log_traceback = False return if fd == 1: reader = self.stdout @@ -144,10 +147,11 @@ class Process: async def _feed_stdin(self, input): debug = self._loop.get_debug() - self.stdin.write(input) - if debug: - logger.debug( - '%r communicate: feed stdin (%s bytes)', self, len(input)) + if input is not None: + self.stdin.write(input) + if debug: + logger.debug( + '%r communicate: feed stdin (%s bytes)', self, len(input)) try: await self.stdin.drain() except (BrokenPipeError, ConnectionResetError) as exc: @@ -180,7 +184,7 @@ class Process: return output async def communicate(self, input=None): - if input is not None: + if self.stdin is not None: stdin = self._feed_stdin(input) else: stdin = self._noop() diff --git a/Lib/asyncio/taskgroups.py b/Lib/asyncio/taskgroups.py index 911419e1..930da53d 100644 --- a/Lib/asyncio/taskgroups.py +++ b/Lib/asyncio/taskgroups.py @@ -2,7 +2,7 @@ # license: PSFL. -__all__ = ["TaskGroup"] +__all__ = ("TaskGroup",) from . import events from . import exceptions @@ -10,7 +10,21 @@ from . import tasks class TaskGroup: + """Asynchronous context manager for managing groups of tasks. + Example use: + + async with asyncio.TaskGroup() as group: + task1 = group.create_task(some_coroutine(...)) + task2 = group.create_task(other_coroutine(...)) + print("Both tasks have completed now.") + + All tasks are awaited when the context manager exits. + + Any exceptions other than `asyncio.CancelledError` raised within + a task will cancel all remaining tasks and wait for them to exit. + The exceptions are then combined and raised as an `ExceptionGroup`. + """ def __init__(self): self._entered = False self._exiting = False @@ -135,6 +149,10 @@ class TaskGroup: self._errors = None def create_task(self, coro, *, name=None, context=None): + """Create a new task in this group and return it. + + Similar to `asyncio.create_task`. + """ if not self._entered: raise RuntimeError(f"TaskGroup {self!r} has not been entered") if self._exiting and not self._tasks: @@ -146,8 +164,14 @@ class TaskGroup: else: task = self._loop.create_task(coro, context=context) tasks._set_task_name(task, name) - task.add_done_callback(self._on_task_done) - self._tasks.add(task) + # optimization: Immediately call the done callback if the task is + # already done (e.g. if the coro was able to complete eagerly), + # and skip scheduling a done callback + if task.done(): + self._on_task_done(task) + else: + self._tasks.add(task) + task.add_done_callback(self._on_task_done) return task # Since Python 3.8 Tasks propagate all exceptions correctly, diff --git a/Lib/asyncio/tasks.py b/Lib/asyncio/tasks.py index 3e07ce52..152c9f8a 100644 --- a/Lib/asyncio/tasks.py +++ b/Lib/asyncio/tasks.py @@ -6,6 +6,7 @@ __all__ = ( 'wait', 'wait_for', 'as_completed', 'sleep', 'gather', 'shield', 'ensure_future', 'run_coroutine_threadsafe', 'current_task', 'all_tasks', + 'create_eager_task_factory', 'eager_task_factory', '_register_task', '_unregister_task', '_enter_task', '_leave_task', ) @@ -24,7 +25,7 @@ from . import coroutines from . import events from . import exceptions from . import futures -from .coroutines import _is_coroutine +from . import timeouts # Helper to generate new task names # This uses itertools.count() instead of a "+= 1" operation because the latter @@ -43,22 +44,26 @@ def all_tasks(loop=None): """Return a set of all tasks for the loop.""" if loop is None: loop = events.get_running_loop() - # Looping over a WeakSet (_all_tasks) isn't safe as it can be updated from another - # thread while we do so. Therefore we cast it to list prior to filtering. The list - # cast itself requires iteration, so we repeat it several times ignoring - # RuntimeErrors (which are not very likely to occur). See issues 34970 and 36607 for - # details. + # capturing the set of eager tasks first, so if an eager task "graduates" + # to a regular task in another thread, we don't risk missing it. + eager_tasks = list(_eager_tasks) + # Looping over the WeakSet isn't safe as it can be updated from another + # thread, therefore we cast it to list prior to filtering. The list cast + # itself requires iteration, so we repeat it several times ignoring + # RuntimeErrors (which are not very likely to occur). + # See issues 34970 and 36607 for details. + scheduled_tasks = None i = 0 while True: try: - tasks = list(_all_tasks) + scheduled_tasks = list(_scheduled_tasks) except RuntimeError: i += 1 if i >= 1000: raise else: break - return {t for t in tasks + return {t for t in itertools.chain(scheduled_tasks, eager_tasks) if futures._get_loop(t) is loop and not t.done()} @@ -93,7 +98,8 @@ class Task(futures._PyFuture): # Inherit Python Task implementation # status is still pending _log_destroy_pending = True - def __init__(self, coro, *, loop=None, name=None, context=None): + def __init__(self, coro, *, loop=None, name=None, context=None, + eager_start=False): super().__init__(loop=loop) if self._source_traceback: del self._source_traceback[-1] @@ -117,8 +123,11 @@ class Task(futures._PyFuture): # Inherit Python Task implementation else: self._context = context - self._loop.call_soon(self.__step, context=self._context) - _register_task(self) + if eager_start and self._loop.is_running(): + self.__eager_start() + else: + self._loop.call_soon(self.__step, context=self._context) + _register_task(self) def __del__(self): if self._state == futures._PENDING and self._log_destroy_pending: @@ -139,6 +148,9 @@ class Task(futures._PyFuture): # Inherit Python Task implementation def get_coro(self): return self._coro + def get_context(self): + return self._context + def get_name(self): return self._name @@ -247,6 +259,25 @@ class Task(futures._PyFuture): # Inherit Python Task implementation self._num_cancels_requested -= 1 return self._num_cancels_requested + def __eager_start(self): + prev_task = _swap_current_task(self._loop, self) + try: + _register_eager_task(self) + try: + self._context.run(self.__step_run_and_handle_result, None) + finally: + _unregister_eager_task(self) + finally: + try: + curtask = _swap_current_task(self._loop, prev_task) + assert curtask is self + finally: + if self.done(): + self._coro = None + self = None # Needed to break cycles when an exception occurs. + else: + _register_task(self) + def __step(self, exc=None): if self.done(): raise exceptions.InvalidStateError( @@ -255,11 +286,17 @@ class Task(futures._PyFuture): # Inherit Python Task implementation if not isinstance(exc, exceptions.CancelledError): exc = self._make_cancelled_error() self._must_cancel = False - coro = self._coro self._fut_waiter = None _enter_task(self._loop, self) - # Call either coro.throw(exc) or coro.send(None). + try: + self.__step_run_and_handle_result(exc) + finally: + _leave_task(self._loop, self) + self = None # Needed to break cycles when an exception occurs. + + def __step_run_and_handle_result(self, exc): + coro = self._coro try: if exc is None: # We use the `send` method directly, because coroutines @@ -331,7 +368,6 @@ class Task(futures._PyFuture): # Inherit Python Task implementation self._loop.call_soon( self.__step, new_exc, context=self._context) finally: - _leave_task(self._loop, self) self = None # Needed to break cycles when an exception occurs. def __wakeup(self, future): @@ -434,65 +470,44 @@ async def wait_for(fut, timeout): If the wait is cancelled, the task is also cancelled. + If the task supresses the cancellation and returns a value instead, + that value is returned. + This function is a coroutine. """ - loop = events.get_running_loop() + # The special case for timeout <= 0 is for the following case: + # + # async def test_waitfor(): + # func_started = False + # + # async def func(): + # nonlocal func_started + # func_started = True + # + # try: + # await asyncio.wait_for(func(), 0) + # except asyncio.TimeoutError: + # assert not func_started + # else: + # assert False + # + # asyncio.run(test_waitfor()) - if timeout is None: - return await fut - if timeout <= 0: - fut = ensure_future(fut, loop=loop) + if timeout is not None and timeout <= 0: + fut = ensure_future(fut) if fut.done(): return fut.result() - await _cancel_and_wait(fut, loop=loop) + await _cancel_and_wait(fut) try: return fut.result() except exceptions.CancelledError as exc: - raise exceptions.TimeoutError() from exc - - waiter = loop.create_future() - timeout_handle = loop.call_later(timeout, _release_waiter, waiter) - cb = functools.partial(_release_waiter, waiter) - - fut = ensure_future(fut, loop=loop) - fut.add_done_callback(cb) - - try: - # wait until the future completes or the timeout - try: - await waiter - except exceptions.CancelledError: - if fut.done(): - return fut.result() - else: - fut.remove_done_callback(cb) - # We must ensure that the task is not running - # after wait_for() returns. - # See https://bugs.python.org/issue32751 - await _cancel_and_wait(fut, loop=loop) - raise - - if fut.done(): - return fut.result() - else: - fut.remove_done_callback(cb) - # We must ensure that the task is not running - # after wait_for() returns. - # See https://bugs.python.org/issue32751 - await _cancel_and_wait(fut, loop=loop) - # In case task cancellation failed with some - # exception, we should re-raise it - # See https://bugs.python.org/issue40607 - try: - return fut.result() - except exceptions.CancelledError as exc: - raise exceptions.TimeoutError() from exc - finally: - timeout_handle.cancel() + raise TimeoutError from exc + async with timeouts.timeout(timeout): + return await fut async def _wait(fs, timeout, return_when, loop): """Internal helper for wait(). @@ -538,9 +553,10 @@ async def _wait(fs, timeout, return_when, loop): return done, pending -async def _cancel_and_wait(fut, loop): +async def _cancel_and_wait(fut): """Cancel the *fut* future or task and wait until it completes.""" + loop = events.get_running_loop() waiter = loop.create_future() cb = functools.partial(_release_waiter, waiter) fut.add_done_callback(cb) @@ -579,7 +595,7 @@ def as_completed(fs, *, timeout=None): from .queues import Queue # Import here to avoid circular import problem. done = Queue() - loop = events._get_event_loop() + loop = events.get_event_loop() todo = {ensure_future(f, loop=loop) for f in set(fs)} timeout_handle = None @@ -646,46 +662,33 @@ def ensure_future(coro_or_future, *, loop=None): If the argument is a Future, it is returned directly. """ - return _ensure_future(coro_or_future, loop=loop) - - -def _ensure_future(coro_or_future, *, loop=None): if futures.isfuture(coro_or_future): if loop is not None and loop is not futures._get_loop(coro_or_future): raise ValueError('The future belongs to a different loop than ' 'the one specified as the loop argument') return coro_or_future - called_wrap_awaitable = False + should_close = True if not coroutines.iscoroutine(coro_or_future): if inspect.isawaitable(coro_or_future): + async def _wrap_awaitable(awaitable): + return await awaitable + coro_or_future = _wrap_awaitable(coro_or_future) - called_wrap_awaitable = True + should_close = False else: raise TypeError('An asyncio.Future, a coroutine or an awaitable ' 'is required') if loop is None: - loop = events._get_event_loop(stacklevel=4) + loop = events.get_event_loop() try: return loop.create_task(coro_or_future) except RuntimeError: - if not called_wrap_awaitable: + if should_close: coro_or_future.close() raise -@types.coroutine -def _wrap_awaitable(awaitable): - """Helper for asyncio.ensure_future(). - - Wraps awaitable (an object with __await__) into a coroutine - that will later be wrapped in a Task by ensure_future(). - """ - return (yield from awaitable.__await__()) - -_wrap_awaitable._is_coroutine = _is_coroutine - - class _GatheringFuture(futures.Future): """Helper for gather(). @@ -746,7 +749,7 @@ def gather(*coros_or_futures, return_exceptions=False): gather won't cancel any other awaitables. """ if not coros_or_futures: - loop = events._get_event_loop() + loop = events.get_event_loop() outer = loop.create_future() outer.set_result([]) return outer @@ -810,11 +813,12 @@ def gather(*coros_or_futures, return_exceptions=False): children = [] nfuts = 0 nfinished = 0 + done_futs = [] loop = None outer = None # bpo-46672 for arg in coros_or_futures: if arg not in arg_to_fut: - fut = _ensure_future(arg, loop=loop) + fut = ensure_future(arg, loop=loop) if loop is None: loop = futures._get_loop(fut) if fut is not arg: @@ -826,7 +830,10 @@ def gather(*coros_or_futures, return_exceptions=False): nfuts += 1 arg_to_fut[arg] = fut - fut.add_done_callback(_done_callback) + if fut.done(): + done_futs.append(fut) + else: + fut.add_done_callback(_done_callback) else: # There's a duplicate Future object in coros_or_futures. @@ -835,6 +842,13 @@ def gather(*coros_or_futures, return_exceptions=False): children.append(fut) outer = _GatheringFuture(children, loop=loop) + # Run done callbacks after GatheringFuture created so any post-processing + # can be performed at this point + # optimization: in the special case that *all* futures finished eagerly, + # this will effectively complete the gather eagerly, with the last + # callback setting the result (or exception) on outer before returning it + for fut in done_futs: + _done_callback(fut) return outer @@ -871,7 +885,7 @@ def shield(arg): weak references to tasks. A task that isn't referenced elsewhere may get garbage collected at any time, even before it's done. """ - inner = _ensure_future(arg) + inner = ensure_future(arg) if inner.done(): # Shortcut. return inner @@ -927,8 +941,40 @@ def run_coroutine_threadsafe(coro, loop): return future -# WeakSet containing all alive tasks. -_all_tasks = weakref.WeakSet() +def create_eager_task_factory(custom_task_constructor): + """Create a function suitable for use as a task factory on an event-loop. + + Example usage: + + loop.set_task_factory( + asyncio.create_eager_task_factory(my_task_constructor)) + + Now, tasks created will be started immediately (rather than being first + scheduled to an event loop). The constructor argument can be any callable + that returns a Task-compatible object and has a signature compatible + with `Task.__init__`; it must have the `eager_start` keyword argument. + + Most applications will use `Task` for `custom_task_constructor` and in + this case there's no need to call `create_eager_task_factory()` + directly. Instead the global `eager_task_factory` instance can be + used. E.g. `loop.set_task_factory(asyncio.eager_task_factory)`. + """ + + def factory(loop, coro, *, name=None, context=None): + return custom_task_constructor( + coro, loop=loop, name=name, context=context, eager_start=True) + + return factory + + +eager_task_factory = create_eager_task_factory(Task) + + +# Collectively these two sets hold references to the complete set of active +# tasks. Eagerly executed tasks use a faster regular set as an optimization +# but may graduate to a WeakSet if the task blocks on IO. +_scheduled_tasks = weakref.WeakSet() +_eager_tasks = set() # Dictionary containing tasks that are currently active in # all running event loops. {EventLoop: Task} @@ -936,8 +982,13 @@ _current_tasks = {} def _register_task(task): - """Register a new task in asyncio as executed by loop.""" - _all_tasks.add(task) + """Register an asyncio Task scheduled to run on an event loop.""" + _scheduled_tasks.add(task) + + +def _register_eager_task(task): + """Register an asyncio Task about to be eagerly executed.""" + _eager_tasks.add(task) def _enter_task(loop, task): @@ -956,25 +1007,49 @@ def _leave_task(loop, task): del _current_tasks[loop] +def _swap_current_task(loop, task): + prev_task = _current_tasks.get(loop) + if task is None: + del _current_tasks[loop] + else: + _current_tasks[loop] = task + return prev_task + + def _unregister_task(task): - """Unregister a task.""" - _all_tasks.discard(task) + """Unregister a completed, scheduled Task.""" + _scheduled_tasks.discard(task) + + +def _unregister_eager_task(task): + """Unregister a task which finished its first eager step.""" + _eager_tasks.discard(task) +_py_current_task = current_task _py_register_task = _register_task +_py_register_eager_task = _register_eager_task _py_unregister_task = _unregister_task +_py_unregister_eager_task = _unregister_eager_task _py_enter_task = _enter_task _py_leave_task = _leave_task +_py_swap_current_task = _swap_current_task try: - from _asyncio import (_register_task, _unregister_task, - _enter_task, _leave_task, - _all_tasks, _current_tasks) + from _asyncio import (_register_task, _register_eager_task, + _unregister_task, _unregister_eager_task, + _enter_task, _leave_task, _swap_current_task, + _scheduled_tasks, _eager_tasks, _current_tasks, + current_task) except ImportError: pass else: + _c_current_task = current_task _c_register_task = _register_task + _c_register_eager_task = _register_eager_task _c_unregister_task = _unregister_task + _c_unregister_eager_task = _unregister_eager_task _c_enter_task = _enter_task _c_leave_task = _leave_task + _c_swap_current_task = _swap_current_task diff --git a/Lib/asyncio/timeouts.py b/Lib/asyncio/timeouts.py index 94d25535..029c4687 100644 --- a/Lib/asyncio/timeouts.py +++ b/Lib/asyncio/timeouts.py @@ -25,8 +25,18 @@ class _State(enum.Enum): @final class Timeout: + """Asynchronous context manager for cancelling overdue coroutines. + + Use `timeout()` or `timeout_at()` rather than instantiating this class directly. + """ def __init__(self, when: Optional[float]) -> None: + """Schedule a timeout that will trigger at a given loop time. + + - If `when` is `None`, the timeout will never trigger. + - If `when < loop.time()`, the timeout will trigger on the next + iteration of the event loop. + """ self._state = _State.CREATED self._timeout_handler: Optional[events.TimerHandle] = None @@ -34,9 +44,11 @@ class Timeout: self._when = when def when(self) -> Optional[float]: + """Return the current deadline.""" return self._when def reschedule(self, when: Optional[float]) -> None: + """Reschedule the timeout.""" assert self._state is not _State.CREATED if self._state is not _State.ENTERED: raise RuntimeError( @@ -72,6 +84,7 @@ class Timeout: async def __aenter__(self) -> "Timeout": self._state = _State.ENTERED self._task = tasks.current_task() + self._cancelling = self._task.cancelling() if self._task is None: raise RuntimeError("Timeout should be used inside a task") self.reschedule(self._when) @@ -92,10 +105,10 @@ class Timeout: if self._state is _State.EXPIRING: self._state = _State.EXPIRED - if self._task.uncancel() == 0 and exc_type is exceptions.CancelledError: - # Since there are no outstanding cancel requests, we're + if self._task.uncancel() <= self._cancelling and exc_type is exceptions.CancelledError: + # Since there are no new cancel requests, we're # handling this. - raise TimeoutError + raise TimeoutError from exc_val elif self._state is _State.ENTERED: self._state = _State.EXITED diff --git a/Lib/asyncio/unix_events.py b/Lib/asyncio/unix_events.py index 0495f332..17fb4d5f 100644 --- a/Lib/asyncio/unix_events.py +++ b/Lib/asyncio/unix_events.py @@ -195,22 +195,25 @@ class _UnixSelectorEventLoop(selector_events.BaseSelectorEventLoop): async def _make_subprocess_transport(self, protocol, args, shell, stdin, stdout, stderr, bufsize, extra=None, **kwargs): - with events.get_child_watcher() as watcher: + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + watcher = events.get_child_watcher() + + with watcher: if not watcher.is_active(): # Check early. # Raising exception before process creation # prevents subprocess execution if the watcher # is not ready to handle it. raise RuntimeError("asyncio.get_child_watcher() is not activated, " - "subprocess support is not installed.") + "subprocess support is not installed.") waiter = self.create_future() transp = _UnixSubprocessTransport(self, protocol, args, shell, - stdin, stdout, stderr, bufsize, - waiter=waiter, extra=extra, - **kwargs) - + stdin, stdout, stderr, bufsize, + waiter=waiter, extra=extra, + **kwargs) watcher.add_child_handler(transp.get_pid(), - self._child_watcher_callback, transp) + self._child_watcher_callback, transp) try: await waiter except (SystemExit, KeyboardInterrupt): @@ -482,13 +485,21 @@ class _UnixReadPipeTransport(transports.ReadTransport): self._loop.call_soon(self._protocol.connection_made, self) # only start reading when connection_made() has been called - self._loop.call_soon(self._loop._add_reader, + self._loop.call_soon(self._add_reader, self._fileno, self._read_ready) if waiter is not None: # only wake up the waiter when connection_made() has been called self._loop.call_soon(futures._set_result_unless_cancelled, waiter, None) + def _add_reader(self, fd, callback): + if not self.is_reading(): + return + self._loop._add_reader(fd, callback) + + def is_reading(self): + return not self._paused and not self._closing + def __repr__(self): info = [self.__class__.__name__] if self._pipe is None: @@ -529,7 +540,7 @@ class _UnixReadPipeTransport(transports.ReadTransport): self._loop.call_soon(self._call_connection_lost, None) def pause_reading(self): - if self._closing or self._paused: + if not self.is_reading(): return self._paused = True self._loop._remove_reader(self._fileno) @@ -843,6 +854,13 @@ class AbstractChildWatcher: waitpid(-1), there should be only one active object per process. """ + def __init_subclass__(cls) -> None: + if cls.__module__ != __name__: + warnings._deprecated("AbstractChildWatcher", + "{name!r} is deprecated as of Python 3.12 and will be " + "removed in Python {remove}.", + remove=(3, 14)) + def add_child_handler(self, pid, callback, *args): """Register a new child handler. @@ -911,10 +929,6 @@ class PidfdChildWatcher(AbstractChildWatcher): recent (5.3+) kernels. """ - def __init__(self): - self._loop = None - self._callbacks = {} - def __enter__(self): return self @@ -922,35 +936,22 @@ class PidfdChildWatcher(AbstractChildWatcher): pass def is_active(self): - return self._loop is not None and self._loop.is_running() + return True def close(self): - self.attach_loop(None) + pass def attach_loop(self, loop): - if self._loop is not None and loop is None and self._callbacks: - warnings.warn( - 'A loop is being detached ' - 'from a child watcher with pending handlers', - RuntimeWarning) - for pidfd, _, _ in self._callbacks.values(): - self._loop._remove_reader(pidfd) - os.close(pidfd) - self._callbacks.clear() - self._loop = loop + pass def add_child_handler(self, pid, callback, *args): - existing = self._callbacks.get(pid) - if existing is not None: - self._callbacks[pid] = existing[0], callback, args - else: - pidfd = os.pidfd_open(pid) - self._loop._add_reader(pidfd, self._do_wait, pid) - self._callbacks[pid] = pidfd, callback, args + loop = events.get_running_loop() + pidfd = os.pidfd_open(pid) + loop._add_reader(pidfd, self._do_wait, pid, pidfd, callback, args) - def _do_wait(self, pid): - pidfd, callback, args = self._callbacks.pop(pid) - self._loop._remove_reader(pidfd) + def _do_wait(self, pid, pidfd, callback, args): + loop = events.get_running_loop() + loop._remove_reader(pidfd) try: _, status = os.waitpid(pid, 0) except ChildProcessError: @@ -968,12 +969,9 @@ class PidfdChildWatcher(AbstractChildWatcher): callback(pid, returncode, *args) def remove_child_handler(self, pid): - try: - pidfd, _, _ = self._callbacks.pop(pid) - except KeyError: - return False - self._loop._remove_reader(pidfd) - os.close(pidfd) + # asyncio never calls remove_child_handler() !!! + # The method is no-op but is implemented because + # abstract base classes require it. return True @@ -1041,6 +1039,13 @@ class SafeChildWatcher(BaseChildWatcher): big number of children (O(n) each time SIGCHLD is raised) """ + def __init__(self): + super().__init__() + warnings._deprecated("SafeChildWatcher", + "{name!r} is deprecated as of Python 3.12 and will be " + "removed in Python {remove}.", + remove=(3, 14)) + def close(self): self._callbacks.clear() super().close() @@ -1119,6 +1124,10 @@ class FastChildWatcher(BaseChildWatcher): self._lock = threading.Lock() self._zombies = {} self._forks = 0 + warnings._deprecated("FastChildWatcher", + "{name!r} is deprecated as of Python 3.12 and will be " + "removed in Python {remove}.", + remove=(3, 14)) def close(self): self._callbacks.clear() @@ -1231,6 +1240,10 @@ class MultiLoopChildWatcher(AbstractChildWatcher): def __init__(self): self._callbacks = {} self._saved_sighandler = None + warnings._deprecated("MultiLoopChildWatcher", + "{name!r} is deprecated as of Python 3.12 and will be " + "removed in Python {remove}.", + remove=(3, 14)) def is_active(self): return self._saved_sighandler is not None @@ -1422,6 +1435,17 @@ class ThreadedChildWatcher(AbstractChildWatcher): self._threads.pop(expected_pid) +def can_use_pidfd(): + if not hasattr(os, 'pidfd_open'): + return False + try: + pid = os.getpid() + os.close(os.pidfd_open(pid, 0)) + except OSError: + # blocked by security policy like SECCOMP + return False + return True + class _UnixDefaultEventLoopPolicy(events.BaseDefaultEventLoopPolicy): """UNIX event loop policy with a watcher for child processes.""" @@ -1434,7 +1458,10 @@ class _UnixDefaultEventLoopPolicy(events.BaseDefaultEventLoopPolicy): def _init_watcher(self): with events._lock: if self._watcher is None: # pragma: no branch - self._watcher = ThreadedChildWatcher() + if can_use_pidfd(): + self._watcher = PidfdChildWatcher() + else: + self._watcher = ThreadedChildWatcher() if threading.current_thread() is threading.main_thread(): self._watcher.attach_loop(self._local._loop) @@ -1460,6 +1487,9 @@ class _UnixDefaultEventLoopPolicy(events.BaseDefaultEventLoopPolicy): if self._watcher is None: self._init_watcher() + warnings._deprecated("get_child_watcher", + "{name!r} is deprecated as of Python 3.12 and will be " + "removed in Python {remove}.", remove=(3, 14)) return self._watcher def set_child_watcher(self, watcher): @@ -1471,6 +1501,9 @@ class _UnixDefaultEventLoopPolicy(events.BaseDefaultEventLoopPolicy): self._watcher.close() self._watcher = watcher + warnings._deprecated("set_child_watcher", + "{name!r} is deprecated as of Python 3.12 and will be " + "removed in Python {remove}.", remove=(3, 14)) SelectorEventLoop = _UnixSelectorEventLoop diff --git a/Lib/asyncio/windows_events.py b/Lib/asyncio/windows_events.py index eb33551b..c9a5fb84 100644 --- a/Lib/asyncio/windows_events.py +++ b/Lib/asyncio/windows_events.py @@ -455,6 +455,17 @@ class IocpProactor: fut.set_result(value) return fut + @staticmethod + def finish_socket_func(trans, key, ov): + try: + return ov.getresult() + except OSError as exc: + if exc.winerror in (_overlapped.ERROR_NETNAME_DELETED, + _overlapped.ERROR_OPERATION_ABORTED): + raise ConnectionResetError(*exc.args) + else: + raise + def recv(self, conn, nbytes, flags=0): self._register_with_iocp(conn) ov = _overlapped.Overlapped(NULL) @@ -466,17 +477,7 @@ class IocpProactor: except BrokenPipeError: return self._result(b'') - def finish_recv(trans, key, ov): - try: - return ov.getresult() - except OSError as exc: - if exc.winerror in (_overlapped.ERROR_NETNAME_DELETED, - _overlapped.ERROR_OPERATION_ABORTED): - raise ConnectionResetError(*exc.args) - else: - raise - - return self._register(ov, conn, finish_recv) + return self._register(ov, conn, self.finish_socket_func) def recv_into(self, conn, buf, flags=0): self._register_with_iocp(conn) @@ -489,17 +490,7 @@ class IocpProactor: except BrokenPipeError: return self._result(0) - def finish_recv(trans, key, ov): - try: - return ov.getresult() - except OSError as exc: - if exc.winerror in (_overlapped.ERROR_NETNAME_DELETED, - _overlapped.ERROR_OPERATION_ABORTED): - raise ConnectionResetError(*exc.args) - else: - raise - - return self._register(ov, conn, finish_recv) + return self._register(ov, conn, self.finish_socket_func) def recvfrom(self, conn, nbytes, flags=0): self._register_with_iocp(conn) @@ -509,17 +500,7 @@ class IocpProactor: except BrokenPipeError: return self._result((b'', None)) - def finish_recv(trans, key, ov): - try: - return ov.getresult() - except OSError as exc: - if exc.winerror in (_overlapped.ERROR_NETNAME_DELETED, - _overlapped.ERROR_OPERATION_ABORTED): - raise ConnectionResetError(*exc.args) - else: - raise - - return self._register(ov, conn, finish_recv) + return self._register(ov, conn, self.finish_socket_func) def recvfrom_into(self, conn, buf, flags=0): self._register_with_iocp(conn) @@ -547,17 +528,7 @@ class IocpProactor: ov.WSASendTo(conn.fileno(), buf, flags, addr) - def finish_send(trans, key, ov): - try: - return ov.getresult() - except OSError as exc: - if exc.winerror in (_overlapped.ERROR_NETNAME_DELETED, - _overlapped.ERROR_OPERATION_ABORTED): - raise ConnectionResetError(*exc.args) - else: - raise - - return self._register(ov, conn, finish_send) + return self._register(ov, conn, self.finish_socket_func) def send(self, conn, buf, flags=0): self._register_with_iocp(conn) @@ -567,17 +538,7 @@ class IocpProactor: else: ov.WriteFile(conn.fileno(), buf) - def finish_send(trans, key, ov): - try: - return ov.getresult() - except OSError as exc: - if exc.winerror in (_overlapped.ERROR_NETNAME_DELETED, - _overlapped.ERROR_OPERATION_ABORTED): - raise ConnectionResetError(*exc.args) - else: - raise - - return self._register(ov, conn, finish_send) + return self._register(ov, conn, self.finish_socket_func) def accept(self, listener): self._register_with_iocp(listener) @@ -648,16 +609,7 @@ class IocpProactor: offset_low, offset_high, count, 0, 0) - def finish_sendfile(trans, key, ov): - try: - return ov.getresult() - except OSError as exc: - if exc.winerror in (_overlapped.ERROR_NETNAME_DELETED, - _overlapped.ERROR_OPERATION_ABORTED): - raise ConnectionResetError(*exc.args) - else: - raise - return self._register(ov, sock, finish_sendfile) + return self._register(ov, sock, self.finish_socket_func) def accept_pipe(self, pipe): self._register_with_iocp(pipe) diff --git a/Lib/base64.py b/Lib/base64.py index 7e9c2a2c..e233647e 100755 --- a/Lib/base64.py +++ b/Lib/base64.py @@ -508,14 +508,8 @@ MAXBINSIZE = (MAXLINESIZE//4)*3 def encode(input, output): """Encode a file; input and output are binary files.""" - while True: - s = input.read(MAXBINSIZE) - if not s: - break - while len(s) < MAXBINSIZE: - ns = input.read(MAXBINSIZE-len(s)) - if not ns: - break + while s := input.read(MAXBINSIZE): + while len(s) < MAXBINSIZE and (ns := input.read(MAXBINSIZE-len(s))): s += ns line = binascii.b2a_base64(s) output.write(line) @@ -523,10 +517,7 @@ def encode(input, output): def decode(input, output): """Decode a file; input and output are binary files.""" - while True: - line = input.readline() - if not line: - break + while line := input.readline(): s = binascii.a2b_base64(line) output.write(s) @@ -567,13 +558,12 @@ def decodebytes(s): def main(): """Small main program""" import sys, getopt - usage = """usage: %s [-h|-d|-e|-u|-t] [file|-] + usage = f"""usage: {sys.argv[0]} [-h|-d|-e|-u] [file|-] -h: print this help message and exit -d, -u: decode - -e: encode (default) - -t: encode and decode string 'Aladdin:open sesame'"""%sys.argv[0] + -e: encode (default)""" try: - opts, args = getopt.getopt(sys.argv[1:], 'hdeut') + opts, args = getopt.getopt(sys.argv[1:], 'hdeu') except getopt.error as msg: sys.stdout = sys.stderr print(msg) @@ -584,7 +574,6 @@ def main(): if o == '-e': func = encode if o == '-d': func = decode if o == '-u': func = decode - if o == '-t': test(); return if o == '-h': print(usage); return if args and args[0] != '-': with open(args[0], 'rb') as f: @@ -593,15 +582,5 @@ def main(): func(sys.stdin.buffer, sys.stdout.buffer) -def test(): - s0 = b"Aladdin:open sesame" - print(repr(s0)) - s1 = encodebytes(s0) - print(repr(s1)) - s2 = decodebytes(s1) - print(repr(s2)) - assert s0 == s2 - - if __name__ == '__main__': main() diff --git a/Lib/bdb.py b/Lib/bdb.py index 81fbb851..0f3eec65 100644 --- a/Lib/bdb.py +++ b/Lib/bdb.py @@ -570,9 +570,12 @@ class Bdb: rv = frame.f_locals['__return__'] s += '->' s += reprlib.repr(rv) - line = linecache.getline(filename, lineno, frame.f_globals) - if line: - s += lprefix + line.strip() + if lineno is not None: + line = linecache.getline(filename, lineno, frame.f_globals) + if line: + s += lprefix + line.strip() + else: + s += f'{lprefix}Warning: lineno is None' return s # The following methods can be called by clients to use diff --git a/Lib/bisect.py b/Lib/bisect.py index d37da74f..ca6ca724 100644 --- a/Lib/bisect.py +++ b/Lib/bisect.py @@ -8,6 +8,8 @@ def insort_right(a, x, lo=0, hi=None, *, key=None): Optional args lo (default 0) and hi (default len(a)) bound the slice of a to be searched. + + A custom key function can be supplied to customize the sort order. """ if key is None: lo = bisect_right(a, x, lo, hi) @@ -25,6 +27,8 @@ def bisect_right(a, x, lo=0, hi=None, *, key=None): Optional args lo (default 0) and hi (default len(a)) bound the slice of a to be searched. + + A custom key function can be supplied to customize the sort order. """ if lo < 0: @@ -57,6 +61,8 @@ def insort_left(a, x, lo=0, hi=None, *, key=None): Optional args lo (default 0) and hi (default len(a)) bound the slice of a to be searched. + + A custom key function can be supplied to customize the sort order. """ if key is None: @@ -74,6 +80,8 @@ def bisect_left(a, x, lo=0, hi=None, *, key=None): Optional args lo (default 0) and hi (default len(a)) bound the slice of a to be searched. + + A custom key function can be supplied to customize the sort order. """ if lo < 0: diff --git a/Lib/cProfile.py b/Lib/cProfile.py index 9fc97883..135a12c3 100755 --- a/Lib/cProfile.py +++ b/Lib/cProfile.py @@ -7,6 +7,8 @@ __all__ = ["run", "runctx", "Profile"] import _lsprof +import importlib.machinery +import io import profile as _pyprofile # ____________________________________________________________ @@ -167,11 +169,14 @@ def main(): else: progname = args[0] sys.path.insert(0, os.path.dirname(progname)) - with open(progname, 'rb') as fp: + with io.open_code(progname) as fp: code = compile(fp.read(), progname, 'exec') + spec = importlib.machinery.ModuleSpec(name='__main__', loader=None, + origin=progname) globs = { - '__file__': progname, - '__name__': '__main__', + '__spec__': spec, + '__file__': spec.origin, + '__name__': spec.name, '__package__': None, '__cached__': None, } diff --git a/Lib/calendar.py b/Lib/calendar.py index 65739643..baab52a1 100644 --- a/Lib/calendar.py +++ b/Lib/calendar.py @@ -7,8 +7,10 @@ set the first day of the week (0=Monday, 6=Sunday).""" import sys import datetime +from enum import IntEnum, global_enum import locale as _locale from itertools import repeat +import warnings __all__ = ["IllegalMonthError", "IllegalWeekdayError", "setfirstweekday", "firstweekday", "isleap", "leapdays", "weekday", "monthrange", @@ -16,6 +18,9 @@ __all__ = ["IllegalMonthError", "IllegalWeekdayError", "setfirstweekday", "timegm", "month_name", "month_abbr", "day_name", "day_abbr", "Calendar", "TextCalendar", "HTMLCalendar", "LocaleTextCalendar", "LocaleHTMLCalendar", "weekheader", + "Day", "Month", "JANUARY", "FEBRUARY", "MARCH", + "APRIL", "MAY", "JUNE", "JULY", + "AUGUST", "SEPTEMBER", "OCTOBER", "NOVEMBER", "DECEMBER", "MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY", "SATURDAY", "SUNDAY"] @@ -37,9 +42,46 @@ class IllegalWeekdayError(ValueError): return "bad weekday number %r; must be 0 (Monday) to 6 (Sunday)" % self.weekday -# Constants for months referenced later -January = 1 -February = 2 +def __getattr__(name): + if name in ('January', 'February'): + warnings.warn(f"The '{name}' attribute is deprecated, use '{name.upper()}' instead", + DeprecationWarning, stacklevel=2) + if name == 'January': + return 1 + else: + return 2 + + raise AttributeError(f"module '{__name__}' has no attribute '{name}'") + + +# Constants for months +@global_enum +class Month(IntEnum): + JANUARY = 1 + FEBRUARY = 2 + MARCH = 3 + APRIL = 4 + MAY = 5 + JUNE = 6 + JULY = 7 + AUGUST = 8 + SEPTEMBER = 9 + OCTOBER = 10 + NOVEMBER = 11 + DECEMBER = 12 + + +# Constants for days +@global_enum +class Day(IntEnum): + MONDAY = 0 + TUESDAY = 1 + WEDNESDAY = 2 + THURSDAY = 3 + FRIDAY = 4 + SATURDAY = 5 + SUNDAY = 6 + # Number of days per month (except for February in leap years) mdays = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] @@ -95,9 +137,6 @@ day_abbr = _localized_day('%a') month_name = _localized_month('%B') month_abbr = _localized_month('%b') -# Constants for weekdays -(MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY) = range(7) - def isleap(year): """Return True for leap years, False for non-leap years.""" @@ -116,7 +155,7 @@ def weekday(year, month, day): """Return weekday (0-6 ~ Mon-Sun) for year, month (1-12), day (1-31).""" if not datetime.MINYEAR <= year <= datetime.MAXYEAR: year = 2000 + year % 400 - return datetime.date(year, month, day).weekday() + return Day(datetime.date(year, month, day).weekday()) def monthrange(year, month): @@ -125,12 +164,12 @@ def monthrange(year, month): if not 1 <= month <= 12: raise IllegalMonthError(month) day1 = weekday(year, month, 1) - ndays = mdays[month] + (month == February and isleap(year)) + ndays = mdays[month] + (month == FEBRUARY and isleap(year)) return day1, ndays def _monthlen(year, month): - return mdays[month] + (month == February and isleap(year)) + return mdays[month] + (month == FEBRUARY and isleap(year)) def _prevmonth(year, month): @@ -260,10 +299,7 @@ class Calendar(object): Each month contains between 4 and 6 weeks and each week contains 1-7 days. Days are datetime.date objects. """ - months = [ - self.monthdatescalendar(year, i) - for i in range(January, January+12) - ] + months = [self.monthdatescalendar(year, m) for m in Month] return [months[i:i+width] for i in range(0, len(months), width) ] def yeardays2calendar(self, year, width=3): @@ -273,10 +309,7 @@ class Calendar(object): (day number, weekday number) tuples. Day numbers outside this month are zero. """ - months = [ - self.monthdays2calendar(year, i) - for i in range(January, January+12) - ] + months = [self.monthdays2calendar(year, m) for m in Month] return [months[i:i+width] for i in range(0, len(months), width) ] def yeardayscalendar(self, year, width=3): @@ -285,10 +318,7 @@ class Calendar(object): yeardatescalendar()). Entries in the week lists are day numbers. Day numbers outside this month are zero. """ - months = [ - self.monthdayscalendar(year, i) - for i in range(January, January+12) - ] + months = [self.monthdayscalendar(year, m) for m in Month] return [months[i:i+width] for i in range(0, len(months), width) ] @@ -509,7 +539,7 @@ class HTMLCalendar(Calendar): a('\n') a('<tr><th colspan="%d" class="%s">%s</th></tr>' % ( width, self.cssclass_year_head, theyear)) - for i in range(January, January+12, width): + for i in range(JANUARY, JANUARY+12, width): # months in this row months = range(i, min(i+width, 13)) a('<tr>') @@ -693,7 +723,7 @@ def main(args): parser.add_argument( "-L", "--locale", default=None, - help="locale to be used from month and weekday names" + help="locale to use for month and weekday names" ) parser.add_argument( "-e", "--encoding", diff --git a/Lib/cgitb.py b/Lib/cgitb.py index 8ce0e833..f6b97f25 100644 --- a/Lib/cgitb.py +++ b/Lib/cgitb.py @@ -74,7 +74,7 @@ def lookup(name, frame, locals): return 'global', frame.f_globals[name] if '__builtins__' in frame.f_globals: builtins = frame.f_globals['__builtins__'] - if type(builtins) is type({}): + if isinstance(builtins, dict): if name in builtins: return 'builtin', builtins[name] else: diff --git a/Lib/code.py b/Lib/code.py index 76000f8c..2bd5fa3e 100644 --- a/Lib/code.py +++ b/Lib/code.py @@ -106,6 +106,7 @@ class InteractiveInterpreter: """ type, value, tb = sys.exc_info() + sys.last_exc = value sys.last_type = type sys.last_value = value sys.last_traceback = tb @@ -119,7 +120,7 @@ class InteractiveInterpreter: else: # Stuff in the right filename value = SyntaxError(msg, (filename, lineno, offset, line)) - sys.last_value = value + sys.last_exc = sys.last_value = value if sys.excepthook is sys.__excepthook__: lines = traceback.format_exception_only(type, value) self.write(''.join(lines)) @@ -138,6 +139,7 @@ class InteractiveInterpreter: """ sys.last_type, sys.last_value, last_tb = ei = sys.exc_info() sys.last_traceback = last_tb + sys.last_exc = ei[1] try: lines = traceback.format_exception(ei[0], ei[1], last_tb.tb_next) if sys.excepthook is sys.__excepthook__: diff --git a/Lib/codecs.py b/Lib/codecs.py index 3b173b61..c1c55d8a 100644 --- a/Lib/codecs.py +++ b/Lib/codecs.py @@ -1115,13 +1115,3 @@ except LookupError: _false = 0 if _false: import encodings - -### Tests - -if __name__ == '__main__': - - # Make stdout translate Latin-1 output into UTF-8 output - sys.stdout = EncodedFile(sys.stdout, 'latin-1', 'utf-8') - - # Have stdin translate Latin-1 input into UTF-8 input - sys.stdin = EncodedFile(sys.stdin, 'utf-8', 'latin-1') diff --git a/Lib/collections/__init__.py b/Lib/collections/__init__.py index 7af8dcd5..8652dc8a 100644 --- a/Lib/collections/__init__.py +++ b/Lib/collections/__init__.py @@ -45,6 +45,11 @@ except ImportError: else: _collections_abc.MutableSequence.register(deque) +try: + from _collections import _deque_iterator +except ImportError: + pass + try: from _collections import defaultdict except ImportError: @@ -90,17 +95,19 @@ class OrderedDict(dict): # Individual links are kept alive by the hard reference in self.__map. # Those hard references disappear when a key is deleted from an OrderedDict. + def __new__(cls, /, *args, **kwds): + "Create the ordered dict object and set up the underlying structures." + self = dict.__new__(cls) + self.__hardroot = _Link() + self.__root = root = _proxy(self.__hardroot) + root.prev = root.next = root + self.__map = {} + return self + def __init__(self, other=(), /, **kwds): '''Initialize an ordered dictionary. The signature is the same as regular dictionaries. Keyword argument order is preserved. ''' - try: - self.__root - except AttributeError: - self.__hardroot = _Link() - self.__root = root = _proxy(self.__hardroot) - root.prev = root.next = root - self.__map = {} self.__update(other, **kwds) def __setitem__(self, key, value, @@ -267,7 +274,7 @@ class OrderedDict(dict): 'od.__repr__() <==> repr(od)' if not self: return '%s()' % (self.__class__.__name__,) - return '%s(%r)' % (self.__class__.__name__, list(self.items())) + return '%s(%r)' % (self.__class__.__name__, dict(self.items())) def __reduce__(self): 'Return state information for pickling' @@ -507,9 +514,12 @@ def namedtuple(typename, field_names, *, rename=False, defaults=None, module=Non # specified a particular module. if module is None: try: - module = _sys._getframe(1).f_globals.get('__name__', '__main__') - except (AttributeError, ValueError): - pass + module = _sys._getframemodulename(1) or '__main__' + except AttributeError: + try: + module = _sys._getframe(1).f_globals.get('__name__', '__main__') + except (AttributeError, ValueError): + pass if module is not None: result.__module__ = module @@ -1011,8 +1021,8 @@ class ChainMap(_collections_abc.MutableMapping): def __iter__(self): d = {} - for mapping in reversed(self.maps): - d.update(dict.fromkeys(mapping)) # reuses stored hash values if possible + for mapping in map(dict.fromkeys, reversed(self.maps)): + d |= mapping # reuses stored hash values if possible return iter(d) def __contains__(self, key): @@ -1132,10 +1142,17 @@ class UserDict(_collections_abc.MutableMapping): def __iter__(self): return iter(self.data) - # Modify __contains__ to work correctly when __missing__ is present + # Modify __contains__ and get() to work like dict + # does when __missing__ is present. def __contains__(self, key): return key in self.data + def get(self, key, default=None): + if key in self: + return self[key] + return default + + # Now, add the methods in dicts but not in MutableMapping def __repr__(self): return repr(self.data) diff --git a/Lib/colorsys.py b/Lib/colorsys.py index 9bdc83e3..bc897bd0 100644 --- a/Lib/colorsys.py +++ b/Lib/colorsys.py @@ -83,7 +83,7 @@ def rgb_to_hls(r, g, b): if l <= 0.5: s = rangec / sumc else: - s = rangec / (2.0-sumc) + s = rangec / (2.0-maxc-minc) # Not always 2.0-sumc: gh-106498. rc = (maxc-r) / rangec gc = (maxc-g) / rangec bc = (maxc-b) / rangec diff --git a/Lib/compileall.py b/Lib/compileall.py index a388931f..d394156c 100644 --- a/Lib/compileall.py +++ b/Lib/compileall.py @@ -97,9 +97,15 @@ def compile_dir(dir, maxlevels=None, ddir=None, force=False, files = _walk_dir(dir, quiet=quiet, maxlevels=maxlevels) success = True if workers != 1 and ProcessPoolExecutor is not None: + import multiprocessing + if multiprocessing.get_start_method() == 'fork': + mp_context = multiprocessing.get_context('forkserver') + else: + mp_context = None # If workers == 0, let ProcessPoolExecutor choose workers = workers or None - with ProcessPoolExecutor(max_workers=workers) as executor: + with ProcessPoolExecutor(max_workers=workers, + mp_context=mp_context) as executor: results = executor.map(partial(compile_file, ddir=ddir, force=force, rx=rx, quiet=quiet, diff --git a/Lib/concurrent/futures/process.py b/Lib/concurrent/futures/process.py index 7e2f5fa3..301207f5 100644 --- a/Lib/concurrent/futures/process.py +++ b/Lib/concurrent/futures/process.py @@ -49,6 +49,8 @@ import os from concurrent.futures import _base import queue import multiprocessing as mp +# This import is required to load the multiprocessing.connection submodule +# so that it can be accessed later as `mp.connection` import multiprocessing.connection from multiprocessing.queues import Queue import threading @@ -364,6 +366,11 @@ class _ExecutorManagerThread(threading.Thread): if self.is_shutting_down(): self.flag_executor_shutting_down() + # When only canceled futures remain in pending_work_items, our + # next call to wait_result_broken_or_wakeup would hang forever. + # This makes sure we have some running futures or none at all. + self.add_call_item_to_queue() + # Since no new work items can be added, it is safe to shutdown # this thread if there are no pending work items. if not self.pending_work_items: @@ -492,6 +499,10 @@ class _ExecutorManagerThread(threading.Thread): for p in self.processes.values(): p.terminate() + # Prevent queue writing to a pipe which is no longer read. + # https://github.com/python/cpython/issues/94777 + self.call_queue._reader.close() + # clean up resources self.join_executor_internals() @@ -616,9 +627,9 @@ class ProcessPoolExecutor(_base.Executor): max_workers: The maximum number of processes that can be used to execute the given calls. If None or not given then as many worker processes will be created as the machine has processors. - mp_context: A multiprocessing context to launch the workers. This - object should provide SimpleQueue, Queue and Process. Useful - to allow specific multiprocessing start methods. + mp_context: A multiprocessing context to launch the workers created + using the multiprocessing.get_context('start method') API. This + object should provide SimpleQueue, Queue and Process. initializer: A callable used to initialize worker processes. initargs: A tuple of arguments to pass to the initializer. max_tasks_per_child: The maximum number of tasks a worker process diff --git a/Lib/concurrent/futures/thread.py b/Lib/concurrent/futures/thread.py index 51c942f5..3b3a36a5 100644 --- a/Lib/concurrent/futures/thread.py +++ b/Lib/concurrent/futures/thread.py @@ -43,7 +43,7 @@ if hasattr(os, 'register_at_fork'): after_in_parent=_global_shutdown_lock.release) -class _WorkItem(object): +class _WorkItem: def __init__(self, future, fn, args, kwargs): self.future = future self.fn = fn @@ -78,17 +78,20 @@ def _worker(executor_reference, work_queue, initializer, initargs): return try: while True: - work_item = work_queue.get(block=True) - if work_item is not None: - work_item.run() - # Delete references to object. See issue16284 - del work_item - - # attempt to increment idle count + try: + work_item = work_queue.get_nowait() + except queue.Empty: + # attempt to increment idle count if queue is empty executor = executor_reference() if executor is not None: executor._idle_semaphore.release() del executor + work_item = work_queue.get(block=True) + + if work_item is not None: + work_item.run() + # Delete references to object. See GH-60488 + del work_item continue executor = executor_reference() diff --git a/Lib/configparser.py b/Lib/configparser.py index df2d7e33..e8aae217 100644 --- a/Lib/configparser.py +++ b/Lib/configparser.py @@ -59,7 +59,7 @@ ConfigParser -- responsible for parsing a list of instance. It will be used as the handler for option value pre-processing when using getters. RawConfigParser objects don't do any sort of interpolation, whereas ConfigParser uses an instance of - BasicInterpolation. The library also provides a ``zc.buildbot`` + BasicInterpolation. The library also provides a ``zc.buildout`` inspired ExtendedInterpolation implementation. When `converters` is given, it should be a dictionary where each key @@ -149,14 +149,14 @@ import re import sys import warnings -__all__ = ["NoSectionError", "DuplicateOptionError", "DuplicateSectionError", +__all__ = ("NoSectionError", "DuplicateOptionError", "DuplicateSectionError", "NoOptionError", "InterpolationError", "InterpolationDepthError", "InterpolationMissingOptionError", "InterpolationSyntaxError", "ParsingError", "MissingSectionHeaderError", - "ConfigParser", "SafeConfigParser", "RawConfigParser", + "ConfigParser", "RawConfigParser", "Interpolation", "BasicInterpolation", "ExtendedInterpolation", "LegacyInterpolation", "SectionProxy", "ConverterMapping", - "DEFAULTSECT", "MAX_INTERPOLATION_DEPTH"] + "DEFAULTSECT", "MAX_INTERPOLATION_DEPTH") _default_dict = dict DEFAULTSECT = "DEFAULT" @@ -298,41 +298,12 @@ class InterpolationDepthError(InterpolationError): class ParsingError(Error): """Raised when a configuration file does not follow legal syntax.""" - def __init__(self, source=None, filename=None): - # Exactly one of `source'/`filename' arguments has to be given. - # `filename' kept for compatibility. - if filename and source: - raise ValueError("Cannot specify both `filename' and `source'. " - "Use `source'.") - elif not filename and not source: - raise ValueError("Required argument `source' not given.") - elif filename: - source = filename - Error.__init__(self, 'Source contains parsing errors: %r' % source) + def __init__(self, source): + super().__init__(f'Source contains parsing errors: {source!r}') self.source = source self.errors = [] self.args = (source, ) - @property - def filename(self): - """Deprecated, use `source'.""" - warnings.warn( - "The 'filename' attribute will be removed in Python 3.12. " - "Use 'source' instead.", - DeprecationWarning, stacklevel=2 - ) - return self.source - - @filename.setter - def filename(self, value): - """Deprecated, user `source'.""" - warnings.warn( - "The 'filename' attribute will be removed in Python 3.12. " - "Use 'source' instead.", - DeprecationWarning, stacklevel=2 - ) - self.source = value - def append(self, lineno, line): self.errors.append((lineno, line)) self.message += '\n\t[line %2d]: %s' % (lineno, line) @@ -769,15 +740,6 @@ class RawConfigParser(MutableMapping): elements_added.add((section, key)) self.set(section, key, value) - def readfp(self, fp, filename=None): - """Deprecated, use read_file instead.""" - warnings.warn( - "This method will be removed in Python 3.12. " - "Use 'parser.read_file()' instead.", - DeprecationWarning, stacklevel=2 - ) - self.read_file(fp, source=filename) - def get(self, section, option, *, raw=False, vars=None, fallback=_UNSET): """Get an option value for a given section. @@ -1240,19 +1202,6 @@ class ConfigParser(RawConfigParser): self._interpolation = hold_interpolation -class SafeConfigParser(ConfigParser): - """ConfigParser alias for backwards compatibility purposes.""" - - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - warnings.warn( - "The SafeConfigParser class has been renamed to ConfigParser " - "in Python 3.2. This alias will be removed in Python 3.12." - " Use ConfigParser directly instead.", - DeprecationWarning, stacklevel=2 - ) - - class SectionProxy(MutableMapping): """A proxy for a single section from a parser.""" diff --git a/Lib/contextlib.py b/Lib/contextlib.py index 58e9a498..b5acbcb9 100644 --- a/Lib/contextlib.py +++ b/Lib/contextlib.py @@ -152,7 +152,7 @@ class _GeneratorContextManager( # tell if we get the same exception back value = typ() try: - self.gen.throw(typ, value, traceback) + self.gen.throw(value) except StopIteration as exc: # Suppress StopIteration *unless* it's the same exception that # was passed to throw(). This prevents a StopIteration @@ -219,7 +219,7 @@ class _AsyncGeneratorContextManager( # tell if we get the same exception back value = typ() try: - await self.gen.athrow(typ, value, traceback) + await self.gen.athrow(value) except StopAsyncIteration as exc: # Suppress StopIteration *unless* it's the same exception that # was passed to throw(). This prevents a StopIteration @@ -441,7 +441,16 @@ class suppress(AbstractContextManager): # exactly reproduce the limitations of the CPython interpreter. # # See http://bugs.python.org/issue12029 for more details - return exctype is not None and issubclass(exctype, self._exceptions) + if exctype is None: + return + if issubclass(exctype, self._exceptions): + return True + if issubclass(exctype, ExceptionGroup): + match, rest = excinst.split(self._exceptions) + if rest is None: + return True + raise rest + return False class _BaseExitStack: diff --git a/Lib/copy.py b/Lib/copy.py index 1b276afe..da2908ef 100644 --- a/Lib/copy.py +++ b/Lib/copy.py @@ -56,11 +56,6 @@ class Error(Exception): pass error = Error # backward compatibility -try: - from org.python.core import PyStringMap -except ImportError: - PyStringMap = None - __all__ = ["Error", "copy", "deepcopy"] def copy(x): @@ -106,13 +101,11 @@ _copy_dispatch = d = {} def _copy_immutable(x): return x -for t in (type(None), int, float, bool, complex, str, tuple, +for t in (types.NoneType, int, float, bool, complex, str, tuple, bytes, frozenset, type, range, slice, property, - types.BuiltinFunctionType, type(Ellipsis), type(NotImplemented), - types.FunctionType, weakref.ref): - d[t] = _copy_immutable -t = getattr(types, "CodeType", None) -if t is not None: + types.BuiltinFunctionType, types.EllipsisType, + types.NotImplementedType, types.FunctionType, types.CodeType, + weakref.ref): d[t] = _copy_immutable d[list] = list.copy @@ -120,9 +113,6 @@ d[dict] = dict.copy d[set] = set.copy d[bytearray] = bytearray.copy -if PyStringMap is not None: - d[PyStringMap] = PyStringMap.copy - del d, t def deepcopy(x, memo=None, _nil=[]): @@ -181,9 +171,9 @@ _deepcopy_dispatch = d = {} def _deepcopy_atomic(x, memo): return x -d[type(None)] = _deepcopy_atomic -d[type(Ellipsis)] = _deepcopy_atomic -d[type(NotImplemented)] = _deepcopy_atomic +d[types.NoneType] = _deepcopy_atomic +d[types.EllipsisType] = _deepcopy_atomic +d[types.NotImplementedType] = _deepcopy_atomic d[int] = _deepcopy_atomic d[float] = _deepcopy_atomic d[bool] = _deepcopy_atomic @@ -231,8 +221,6 @@ def _deepcopy_dict(x, memo, deepcopy=deepcopy): y[deepcopy(key, memo)] = deepcopy(value, memo) return y d[dict] = _deepcopy_dict -if PyStringMap is not None: - d[PyStringMap] = _deepcopy_dict def _deepcopy_method(x, memo): # Copy instance methods return type(x)(x.__func__, deepcopy(x.__self__, memo)) @@ -301,4 +289,4 @@ def _reconstruct(x, memo, func, args, y[key] = value return y -del types, weakref, PyStringMap +del types, weakref diff --git a/Lib/copyreg.py b/Lib/copyreg.py index c8a52a2d..57839240 100644 --- a/Lib/copyreg.py +++ b/Lib/copyreg.py @@ -25,16 +25,10 @@ def constructor(object): # Example: provide pickling support for complex numbers. -try: - complex -except NameError: - pass -else: +def pickle_complex(c): + return complex, (c.real, c.imag) - def pickle_complex(c): - return complex, (c.real, c.imag) - - pickle(complex, pickle_complex, complex) +pickle(complex, pickle_complex, complex) def pickle_union(obj): import functools, operator diff --git a/Lib/csv.py b/Lib/csv.py index bb3ee269..77f30c8d 100644 --- a/Lib/csv.py +++ b/Lib/csv.py @@ -4,16 +4,19 @@ csv.py - read/write/investigate CSV files """ import re +import types from _csv import Error, __version__, writer, reader, register_dialect, \ unregister_dialect, get_dialect, list_dialects, \ field_size_limit, \ QUOTE_MINIMAL, QUOTE_ALL, QUOTE_NONNUMERIC, QUOTE_NONE, \ + QUOTE_STRINGS, QUOTE_NOTNULL, \ __doc__ from _csv import Dialect as _Dialect from io import StringIO __all__ = ["QUOTE_MINIMAL", "QUOTE_ALL", "QUOTE_NONNUMERIC", "QUOTE_NONE", + "QUOTE_STRINGS", "QUOTE_NOTNULL", "Error", "Dialect", "__doc__", "excel", "excel_tab", "field_size_limit", "reader", "writer", "register_dialect", "get_dialect", "list_dialects", "Sniffer", @@ -80,6 +83,8 @@ register_dialect("unix", unix_dialect) class DictReader: def __init__(self, f, fieldnames=None, restkey=None, restval=None, dialect="excel", *args, **kwds): + if fieldnames is not None and iter(fieldnames) is fieldnames: + fieldnames = list(fieldnames) self._fieldnames = fieldnames # list of keys for the dict self.restkey = restkey # key to catch long rows self.restval = restval # default value for short rows @@ -126,13 +131,18 @@ class DictReader: d[key] = self.restval return d + __class_getitem__ = classmethod(types.GenericAlias) + class DictWriter: def __init__(self, f, fieldnames, restval="", extrasaction="raise", dialect="excel", *args, **kwds): + if fieldnames is not None and iter(fieldnames) is fieldnames: + fieldnames = list(fieldnames) self.fieldnames = fieldnames # list of keys for the dict self.restval = restval # for writing short dicts - if extrasaction.lower() not in ("raise", "ignore"): + extrasaction = extrasaction.lower() + if extrasaction not in ("raise", "ignore"): raise ValueError("extrasaction (%s) must be 'raise' or 'ignore'" % extrasaction) self.extrasaction = extrasaction @@ -156,11 +166,8 @@ class DictWriter: def writerows(self, rowdicts): return self.writer.writerows(map(self._dict_to_list, rowdicts)) -# Guard Sniffer's type checking against builds that exclude complex() -try: - complex -except NameError: - complex = float + __class_getitem__ = classmethod(types.GenericAlias) + class Sniffer: ''' @@ -428,7 +435,7 @@ class Sniffer: # on whether it's a header hasHeader = 0 for col, colType in columnTypes.items(): - if type(colType) == type(0): # it's a length + if isinstance(colType, int): # it's a length if len(header[col]) != colType: hasHeader += 1 else: diff --git a/Lib/ctypes/__init__.py b/Lib/ctypes/__init__.py index 26135ad9..95353bab 100644 --- a/Lib/ctypes/__init__.py +++ b/Lib/ctypes/__init__.py @@ -11,6 +11,7 @@ from _ctypes import CFuncPtr as _CFuncPtr from _ctypes import __version__ as _ctypes_version from _ctypes import RTLD_LOCAL, RTLD_GLOBAL from _ctypes import ArgumentError +from _ctypes import SIZEOF_TIME_T from struct import calcsize as _calcsize @@ -343,6 +344,8 @@ class CDLL(object): use_errno=False, use_last_error=False, winmode=None): + if name: + name = _os.fspath(name) self._name = name flags = self._func_flags_ if use_errno: @@ -443,7 +446,10 @@ class LibraryLoader(object): def __getattr__(self, name): if name[0] == '_': raise AttributeError(name) - dll = self._dlltype(name) + try: + dll = self._dlltype(name) + except OSError: + raise AttributeError(name) setattr(self, name, dll) return dll @@ -563,4 +569,11 @@ for kind in [c_ushort, c_uint, c_ulong, c_ulonglong]: elif sizeof(kind) == 8: c_uint64 = kind del(kind) +if SIZEOF_TIME_T == 8: + c_time_t = c_int64 +elif SIZEOF_TIME_T == 4: + c_time_t = c_int32 +else: + raise SystemError(f"Unexpected sizeof(time_t): {SIZEOF_TIME_T=}") + _reset_cache() diff --git a/Lib/ctypes/_aix.py b/Lib/ctypes/_aix.py index fc3e95cb..ee790f71 100644 --- a/Lib/ctypes/_aix.py +++ b/Lib/ctypes/_aix.py @@ -108,12 +108,8 @@ def get_ld_headers(file): p = Popen(["/usr/bin/dump", f"-X{AIX_ABI}", "-H", file], universal_newlines=True, stdout=PIPE, stderr=DEVNULL) # be sure to read to the end-of-file - getting all entries - while True: - ld_header = get_ld_header(p) - if ld_header: - ldr_headers.append((ld_header, get_ld_header_info(p))) - else: - break + while ld_header := get_ld_header(p): + ldr_headers.append((ld_header, get_ld_header_info(p))) p.stdout.close() p.wait() return ldr_headers diff --git a/Lib/ctypes/_endian.py b/Lib/ctypes/_endian.py index 34dee64b..b5446c04 100644 --- a/Lib/ctypes/_endian.py +++ b/Lib/ctypes/_endian.py @@ -37,7 +37,7 @@ class _swapped_union_meta(_swapped_meta, type(Union)): pass ################################################################ # Note: The Structure metaclass checks for the *presence* (not the -# value!) of a _swapped_bytes_ attribute to determine the bit order in +# value!) of a _swappedbytes_ attribute to determine the bit order in # structures containing bit fields. if sys.byteorder == "little": diff --git a/Lib/ctypes/macholib/fetch_macholib.bat b/Lib/ctypes/macholib/fetch_macholib.bat index f474d5cd..f9e1c0dc 100644 --- a/Lib/ctypes/macholib/fetch_macholib.bat +++ b/Lib/ctypes/macholib/fetch_macholib.bat @@ -1 +1 @@ -svn export --force http://svn.red-bean.com/bob/macholib/trunk/macholib/ . +svn export --force http://svn.red-bean.com/bob/macholib/trunk/macholib/ . diff --git a/Lib/ctypes/test/__main__.py b/Lib/ctypes/test/__main__.py deleted file mode 100644 index 362a9ec8..00000000 --- a/Lib/ctypes/test/__main__.py +++ /dev/null @@ -1,4 +0,0 @@ -from ctypes.test import load_tests -import unittest - -unittest.main() diff --git a/Lib/ctypes/wintypes.py b/Lib/ctypes/wintypes.py index c619d275..9c4e7214 100644 --- a/Lib/ctypes/wintypes.py +++ b/Lib/ctypes/wintypes.py @@ -1,7 +1,7 @@ # The most useful windows datatypes import ctypes -BYTE = ctypes.c_byte +BYTE = ctypes.c_ubyte WORD = ctypes.c_ushort DWORD = ctypes.c_ulong diff --git a/Lib/curses/ascii.py b/Lib/curses/ascii.py index 5b243be6..95acff33 100644 --- a/Lib/curses/ascii.py +++ b/Lib/curses/ascii.py @@ -46,7 +46,7 @@ controlnames = [ ] def _ctoi(c): - if type(c) == type(""): + if isinstance(c, str): return ord(c) else: return c @@ -69,19 +69,19 @@ def isctrl(c): return 0 <= _ctoi(c) < 32 def ismeta(c): return _ctoi(c) > 127 def ascii(c): - if type(c) == type(""): + if isinstance(c, str): return chr(_ctoi(c) & 0x7f) else: return _ctoi(c) & 0x7f def ctrl(c): - if type(c) == type(""): + if isinstance(c, str): return chr(_ctoi(c) & 0x1f) else: return _ctoi(c) & 0x1f def alt(c): - if type(c) == type(""): + if isinstance(c, str): return chr(_ctoi(c) | 0x80) else: return _ctoi(c) | 0x80 diff --git a/Lib/curses/textpad.py b/Lib/curses/textpad.py index 2079953a..aa87061b 100644 --- a/Lib/curses/textpad.py +++ b/Lib/curses/textpad.py @@ -102,7 +102,10 @@ class Textbox: self._insert_printable_char(ch) elif ch == curses.ascii.SOH: # ^a self.win.move(y, 0) - elif ch in (curses.ascii.STX,curses.KEY_LEFT, curses.ascii.BS,curses.KEY_BACKSPACE): + elif ch in (curses.ascii.STX,curses.KEY_LEFT, + curses.ascii.BS, + curses.KEY_BACKSPACE, + curses.ascii.DEL): if x > 0: self.win.move(y, x-1) elif y == 0: @@ -111,7 +114,7 @@ class Textbox: self.win.move(y-1, self._end_of_line(y-1)) else: self.win.move(y-1, self.maxx) - if ch in (curses.ascii.BS, curses.KEY_BACKSPACE): + if ch in (curses.ascii.BS, curses.KEY_BACKSPACE, curses.ascii.DEL): self.win.delch() elif ch == curses.ascii.EOT: # ^d self.win.delch() diff --git a/Lib/dataclasses.py b/Lib/dataclasses.py index 2bfeea51..3eacba84 100644 --- a/Lib/dataclasses.py +++ b/Lib/dataclasses.py @@ -4,7 +4,6 @@ import copy import types import inspect import keyword -import builtins import functools import itertools import abc @@ -223,6 +222,29 @@ _POST_INIT_NAME = '__post_init__' # https://bugs.python.org/issue33453 for details. _MODULE_IDENTIFIER_RE = re.compile(r'^(?:\s*(\w+)\s*\.)?\s*(\w+)') +# Atomic immutable types which don't require any recursive handling and for which deepcopy +# returns the same object. We can provide a fast-path for these types in asdict and astuple. +_ATOMIC_TYPES = frozenset({ + # Common JSON Serializable types + types.NoneType, + bool, + int, + float, + str, + # Other common types + complex, + bytes, + # Other types that are also unaffected by deepcopy + types.EllipsisType, + types.NotImplementedType, + types.CodeType, + types.BuiltinFunctionType, + types.FunctionType, + type, + range, + property, +}) + # This function's logic is copied from "recursive_repr" function in # reprlib module to avoid dependency. def _recursive_repr(user_function): @@ -341,15 +363,25 @@ class _DataclassParams: 'order', 'unsafe_hash', 'frozen', + 'match_args', + 'kw_only', + 'slots', + 'weakref_slot', ) - def __init__(self, init, repr, eq, order, unsafe_hash, frozen): + def __init__(self, + init, repr, eq, order, unsafe_hash, frozen, + match_args, kw_only, slots, weakref_slot): self.init = init self.repr = repr self.eq = eq self.order = order self.unsafe_hash = unsafe_hash self.frozen = frozen + self.match_args = match_args + self.kw_only = kw_only + self.slots = slots + self.weakref_slot = weakref_slot def __repr__(self): return ('_DataclassParams(' @@ -358,7 +390,11 @@ class _DataclassParams: f'eq={self.eq!r},' f'order={self.order!r},' f'unsafe_hash={self.unsafe_hash!r},' - f'frozen={self.frozen!r}' + f'frozen={self.frozen!r},' + f'match_args={self.match_args!r},' + f'kw_only={self.kw_only!r},' + f'slots={self.slots!r},' + f'weakref_slot={self.weakref_slot!r}' ')') @@ -419,14 +455,18 @@ def _create_fn(name, args, body, *, globals=None, locals=None, locals = {} return_annotation = '' if return_type is not MISSING: - locals['_return_type'] = return_type - return_annotation = '->_return_type' + locals['__dataclass_return_type__'] = return_type + return_annotation = '->__dataclass_return_type__' args = ','.join(args) body = '\n'.join(f' {b}' for b in body) # Compute the text of the entire function. txt = f' def {name}({args}){return_annotation}:\n{body}' + # Free variables in exec are resolved in the global namespace. + # The global namespace we have is user-provided, so we can't modify it for + # our purposes. So we put the things we need into locals and introduce a + # scope to allow the function we're creating to close over them. local_vars = ', '.join(locals.keys()) txt = f"def __create_fn__({local_vars}):\n{txt}\n return {name}" ns = {} @@ -450,14 +490,14 @@ def _field_init(f, frozen, globals, self_name, slots): # Return the text of the line in the body of __init__ that will # initialize this field. - default_name = f'_dflt_{f.name}' + default_name = f'__dataclass_dflt_{f.name}__' if f.default_factory is not MISSING: if f.init: # This field has a default factory. If a parameter is # given, use it. If not, call the factory. globals[default_name] = f.default_factory value = (f'{default_name}() ' - f'if {f.name} is _HAS_DEFAULT_FACTORY ' + f'if {f.name} is __dataclass_HAS_DEFAULT_FACTORY__ ' f'else {f.name}') else: # This is a field that's not in the __init__ params, but @@ -518,11 +558,11 @@ def _init_param(f): elif f.default is not MISSING: # There's a default, this will be the name that's used to look # it up. - default = f'=_dflt_{f.name}' + default = f'=__dataclass_dflt_{f.name}__' elif f.default_factory is not MISSING: # There's a factory function. Set a marker. - default = '=_HAS_DEFAULT_FACTORY' - return f'{f.name}:_type_{f.name}{default}' + default = '=__dataclass_HAS_DEFAULT_FACTORY__' + return f'{f.name}:__dataclass_type_{f.name}__{default}' def _init_fn(fields, std_fields, kw_only_fields, frozen, has_post_init, @@ -545,10 +585,9 @@ def _init_fn(fields, std_fields, kw_only_fields, frozen, has_post_init, raise TypeError(f'non-default argument {f.name!r} ' 'follows default argument') - locals = {f'_type_{f.name}': f.type for f in fields} + locals = {f'__dataclass_type_{f.name}__': f.type for f in fields} locals.update({ - 'MISSING': MISSING, - '_HAS_DEFAULT_FACTORY': _HAS_DEFAULT_FACTORY, + '__dataclass_HAS_DEFAULT_FACTORY__': _HAS_DEFAULT_FACTORY, '__dataclass_builtins_object__': object, }) @@ -599,21 +638,19 @@ def _repr_fn(fields, globals): def _frozen_get_del_attr(cls, fields, globals): locals = {'cls': cls, 'FrozenInstanceError': FrozenInstanceError} + condition = 'type(self) is cls' if fields: - fields_str = '(' + ','.join(repr(f.name) for f in fields) + ',)' - else: - # Special case for the zero-length tuple. - fields_str = '()' + condition += ' or name in {' + ', '.join(repr(f.name) for f in fields) + '}' return (_create_fn('__setattr__', ('self', 'name', 'value'), - (f'if type(self) is cls or name in {fields_str}:', + (f'if {condition}:', ' raise FrozenInstanceError(f"cannot assign to field {name!r}")', f'super(cls, self).__setattr__(name, value)'), locals=locals, globals=globals), _create_fn('__delattr__', ('self', 'name'), - (f'if type(self) is cls or name in {fields_str}:', + (f'if {condition}:', ' raise FrozenInstanceError(f"cannot delete field {name!r}")', f'super(cls, self).__delattr__(name)'), locals=locals, @@ -900,7 +937,9 @@ def _process_class(cls, init, repr, eq, order, unsafe_hash, frozen, globals = {} setattr(cls, _PARAMS, _DataclassParams(init, repr, eq, order, - unsafe_hash, frozen)) + unsafe_hash, frozen, + match_args, kw_only, + slots, weakref_slot)) # Find our base classes in reverse MRO order, and exclude # ourselves. In reversed order so that more derived classes @@ -919,10 +958,7 @@ def _process_class(cls, init, repr, eq, order, unsafe_hash, frozen, if getattr(b, _PARAMS).frozen: any_frozen_base = True - # Annotations that are defined in this class (not in base - # classes). If __annotations__ isn't present, then this class - # adds no new annotations. We use this to compute fields that are - # added by this class. + # Annotations defined specifically in this class (not in base classes). # # Fields are found from cls_annotations, which is guaranteed to be # ordered. Default values are from class attributes, if a field @@ -931,7 +967,7 @@ def _process_class(cls, init, repr, eq, order, unsafe_hash, frozen, # actual default value. Pseudo-fields ClassVars and InitVars are # included, despite the fact that they're not real fields. That's # dealt with later. - cls_annotations = cls.__dict__.get('__annotations__', {}) + cls_annotations = inspect.get_annotations(cls) # Now find fields in our class. While doing so, validate some # things, and set the default values (as class attributes) where @@ -1092,8 +1128,13 @@ def _process_class(cls, init, repr, eq, order, unsafe_hash, frozen, if not getattr(cls, '__doc__'): # Create a class doc-string. - cls.__doc__ = (cls.__name__ + - str(inspect.signature(cls)).replace(' -> None', '')) + try: + # In some cases fetching a signature is not possible. + # But, we surely should not fail in this case. + text_sig = str(inspect.signature(cls)).replace(' -> None', '') + except (TypeError, ValueError): + text_sig = '' + cls.__doc__ = (cls.__name__ + text_sig) if match_args: # I could probably compute this once @@ -1175,6 +1216,9 @@ def _add_slots(cls, is_frozen, weakref_slot): # Remove __dict__ itself. cls_dict.pop('__dict__', None) + # Clear existing `__weakref__` descriptor, it belongs to a previous type: + cls_dict.pop('__weakref__', None) # gh-102069 + # And finally create the class. qualname = getattr(cls, '__qualname__', None) cls = type(cls)(cls.__name__, cls.__bases__, cls_dict) @@ -1183,8 +1227,10 @@ def _add_slots(cls, is_frozen, weakref_slot): if is_frozen: # Need this for pickling frozen classes with slots. - cls.__getstate__ = _dataclass_getstate - cls.__setstate__ = _dataclass_setstate + if '__getstate__' not in cls_dict: + cls.__getstate__ = _dataclass_getstate + if '__setstate__' not in cls_dict: + cls.__setstate__ = _dataclass_setstate return cls @@ -1231,7 +1277,7 @@ def fields(class_or_instance): try: fields = getattr(class_or_instance, _FIELDS) except AttributeError: - raise TypeError('must be called with a dataclass type or instance') + raise TypeError('must be called with a dataclass type or instance') from None # Exclude pseudo-fields. Note that fields is sorted by insertion # order, so the order of the tuple is as the fields were defined. @@ -1267,7 +1313,7 @@ def asdict(obj, *, dict_factory=dict): If given, 'dict_factory' will be used instead of built-in dict. The function applies recursively to field values that are dataclass instances. This will also look into built-in containers: - tuples, lists, and dicts. + tuples, lists, and dicts. Other objects are copied with 'copy.deepcopy()'. """ if not _is_dataclass_instance(obj): raise TypeError("asdict() should be called on dataclass instances") @@ -1275,12 +1321,21 @@ def asdict(obj, *, dict_factory=dict): def _asdict_inner(obj, dict_factory): - if _is_dataclass_instance(obj): - result = [] - for f in fields(obj): - value = _asdict_inner(getattr(obj, f.name), dict_factory) - result.append((f.name, value)) - return dict_factory(result) + if type(obj) in _ATOMIC_TYPES: + return obj + elif _is_dataclass_instance(obj): + # fast path for the common case + if dict_factory is dict: + return { + f.name: _asdict_inner(getattr(obj, f.name), dict) + for f in fields(obj) + } + else: + result = [] + for f in fields(obj): + value = _asdict_inner(getattr(obj, f.name), dict_factory) + result.append((f.name, value)) + return dict_factory(result) elif isinstance(obj, tuple) and hasattr(obj, '_fields'): # obj is a namedtuple. Recurse into it, but the returned # object is another namedtuple of the same type. This is @@ -1308,6 +1363,13 @@ def _asdict_inner(obj, dict_factory): # above). return type(obj)(_asdict_inner(v, dict_factory) for v in obj) elif isinstance(obj, dict): + if hasattr(type(obj), 'default_factory'): + # obj is a defaultdict, which has a different constructor from + # dict as it requires the default_factory as its first arg. + result = type(obj)(getattr(obj, 'default_factory')) + for k, v in obj.items(): + result[_asdict_inner(k, dict_factory)] = _asdict_inner(v, dict_factory) + return result return type(obj)((_asdict_inner(k, dict_factory), _asdict_inner(v, dict_factory)) for k, v in obj.items()) @@ -1331,7 +1393,7 @@ def astuple(obj, *, tuple_factory=tuple): If given, 'tuple_factory' will be used instead of built-in tuple. The function applies recursively to field values that are dataclass instances. This will also look into built-in containers: - tuples, lists, and dicts. + tuples, lists, and dicts. Other objects are copied with 'copy.deepcopy()'. """ if not _is_dataclass_instance(obj): @@ -1340,7 +1402,9 @@ def astuple(obj, *, tuple_factory=tuple): def _astuple_inner(obj, tuple_factory): - if _is_dataclass_instance(obj): + if type(obj) in _ATOMIC_TYPES: + return obj + elif _is_dataclass_instance(obj): result = [] for f in fields(obj): value = _astuple_inner(getattr(obj, f.name), tuple_factory) @@ -1360,7 +1424,15 @@ def _astuple_inner(obj, tuple_factory): # above). return type(obj)(_astuple_inner(v, tuple_factory) for v in obj) elif isinstance(obj, dict): - return type(obj)((_astuple_inner(k, tuple_factory), _astuple_inner(v, tuple_factory)) + obj_type = type(obj) + if hasattr(obj_type, 'default_factory'): + # obj is a defaultdict, which has a different constructor from + # dict as it requires the default_factory as its first arg. + result = obj_type(getattr(obj, 'default_factory')) + for k, v in obj.items(): + result[_astuple_inner(k, tuple_factory)] = _astuple_inner(v, tuple_factory) + return result + return obj_type((_astuple_inner(k, tuple_factory), _astuple_inner(v, tuple_factory)) for k, v in obj.items()) else: return copy.deepcopy(obj) @@ -1369,7 +1441,7 @@ def _astuple_inner(obj, tuple_factory): def make_dataclass(cls_name, fields, *, bases=(), namespace=None, init=True, repr=True, eq=True, order=False, unsafe_hash=False, frozen=False, match_args=True, kw_only=False, slots=False, - weakref_slot=False): + weakref_slot=False, module=None): """Return a new dynamically created dataclass. The dataclass name will be 'cls_name'. 'fields' is an iterable @@ -1389,8 +1461,11 @@ def make_dataclass(cls_name, fields, *, bases=(), namespace=None, init=True, For the bases and namespace parameters, see the builtin type() function. - The parameters init, repr, eq, order, unsafe_hash, and frozen are passed to - dataclass(). + The parameters init, repr, eq, order, unsafe_hash, frozen, match_args, kw_only, + slots, and weakref_slot are passed to dataclass(). + + If module parameter is defined, the '__module__' attribute of the dataclass is + set to that value. """ if namespace is None: @@ -1433,6 +1508,19 @@ def make_dataclass(cls_name, fields, *, bases=(), namespace=None, init=True, # of generic dataclasses. cls = types.new_class(cls_name, bases, {}, exec_body_callback) + # For pickling to work, the __module__ variable needs to be set to the frame + # where the dataclass is created. + if module is None: + try: + module = sys._getframemodulename(1) or '__main__' + except AttributeError: + try: + module = sys._getframe(1).f_globals.get('__name__', '__main__') + except (AttributeError, ValueError): + pass + if module is not None: + cls.__module__ = module + # Apply the normal decorator. return dataclass(cls, init=init, repr=repr, eq=eq, order=order, unsafe_hash=unsafe_hash, frozen=frozen, diff --git a/Lib/datetime.py b/Lib/datetime.py index c3c2568f..a33d2d72 100644 --- a/Lib/datetime.py +++ b/Lib/datetime.py @@ -1,2639 +1,9 @@ -"""Concrete date/time and related types. - -See http://www.iana.org/time-zones/repository/tz-link.html for -time zone and DST data sources. -""" - -__all__ = ("date", "datetime", "time", "timedelta", "timezone", "tzinfo", - "MINYEAR", "MAXYEAR", "UTC") - - -import time as _time -import math as _math -import sys -from operator import index as _index - -def _cmp(x, y): - return 0 if x == y else 1 if x > y else -1 - -MINYEAR = 1 -MAXYEAR = 9999 -_MAXORDINAL = 3652059 # date.max.toordinal() - -# Utility functions, adapted from Python's Demo/classes/Dates.py, which -# also assumes the current Gregorian calendar indefinitely extended in -# both directions. Difference: Dates.py calls January 1 of year 0 day -# number 1. The code here calls January 1 of year 1 day number 1. This is -# to match the definition of the "proleptic Gregorian" calendar in Dershowitz -# and Reingold's "Calendrical Calculations", where it's the base calendar -# for all computations. See the book for algorithms for converting between -# proleptic Gregorian ordinals and many other calendar systems. - -# -1 is a placeholder for indexing purposes. -_DAYS_IN_MONTH = [-1, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] - -_DAYS_BEFORE_MONTH = [-1] # -1 is a placeholder for indexing purposes. -dbm = 0 -for dim in _DAYS_IN_MONTH[1:]: - _DAYS_BEFORE_MONTH.append(dbm) - dbm += dim -del dbm, dim - -def _is_leap(year): - "year -> 1 if leap year, else 0." - return year % 4 == 0 and (year % 100 != 0 or year % 400 == 0) - -def _days_before_year(year): - "year -> number of days before January 1st of year." - y = year - 1 - return y*365 + y//4 - y//100 + y//400 - -def _days_in_month(year, month): - "year, month -> number of days in that month in that year." - assert 1 <= month <= 12, month - if month == 2 and _is_leap(year): - return 29 - return _DAYS_IN_MONTH[month] - -def _days_before_month(year, month): - "year, month -> number of days in year preceding first day of month." - assert 1 <= month <= 12, 'month must be in 1..12' - return _DAYS_BEFORE_MONTH[month] + (month > 2 and _is_leap(year)) - -def _ymd2ord(year, month, day): - "year, month, day -> ordinal, considering 01-Jan-0001 as day 1." - assert 1 <= month <= 12, 'month must be in 1..12' - dim = _days_in_month(year, month) - assert 1 <= day <= dim, ('day must be in 1..%d' % dim) - return (_days_before_year(year) + - _days_before_month(year, month) + - day) - -_DI400Y = _days_before_year(401) # number of days in 400 years -_DI100Y = _days_before_year(101) # " " " " 100 " -_DI4Y = _days_before_year(5) # " " " " 4 " - -# A 4-year cycle has an extra leap day over what we'd get from pasting -# together 4 single years. -assert _DI4Y == 4 * 365 + 1 - -# Similarly, a 400-year cycle has an extra leap day over what we'd get from -# pasting together 4 100-year cycles. -assert _DI400Y == 4 * _DI100Y + 1 - -# OTOH, a 100-year cycle has one fewer leap day than we'd get from -# pasting together 25 4-year cycles. -assert _DI100Y == 25 * _DI4Y - 1 - -def _ord2ymd(n): - "ordinal -> (year, month, day), considering 01-Jan-0001 as day 1." - - # n is a 1-based index, starting at 1-Jan-1. The pattern of leap years - # repeats exactly every 400 years. The basic strategy is to find the - # closest 400-year boundary at or before n, then work with the offset - # from that boundary to n. Life is much clearer if we subtract 1 from - # n first -- then the values of n at 400-year boundaries are exactly - # those divisible by _DI400Y: - # - # D M Y n n-1 - # -- --- ---- ---------- ---------------- - # 31 Dec -400 -_DI400Y -_DI400Y -1 - # 1 Jan -399 -_DI400Y +1 -_DI400Y 400-year boundary - # ... - # 30 Dec 000 -1 -2 - # 31 Dec 000 0 -1 - # 1 Jan 001 1 0 400-year boundary - # 2 Jan 001 2 1 - # 3 Jan 001 3 2 - # ... - # 31 Dec 400 _DI400Y _DI400Y -1 - # 1 Jan 401 _DI400Y +1 _DI400Y 400-year boundary - n -= 1 - n400, n = divmod(n, _DI400Y) - year = n400 * 400 + 1 # ..., -399, 1, 401, ... - - # Now n is the (non-negative) offset, in days, from January 1 of year, to - # the desired date. Now compute how many 100-year cycles precede n. - # Note that it's possible for n100 to equal 4! In that case 4 full - # 100-year cycles precede the desired day, which implies the desired - # day is December 31 at the end of a 400-year cycle. - n100, n = divmod(n, _DI100Y) - - # Now compute how many 4-year cycles precede it. - n4, n = divmod(n, _DI4Y) - - # And now how many single years. Again n1 can be 4, and again meaning - # that the desired day is December 31 at the end of the 4-year cycle. - n1, n = divmod(n, 365) - - year += n100 * 100 + n4 * 4 + n1 - if n1 == 4 or n100 == 4: - assert n == 0 - return year-1, 12, 31 - - # Now the year is correct, and n is the offset from January 1. We find - # the month via an estimate that's either exact or one too large. - leapyear = n1 == 3 and (n4 != 24 or n100 == 3) - assert leapyear == _is_leap(year) - month = (n + 50) >> 5 - preceding = _DAYS_BEFORE_MONTH[month] + (month > 2 and leapyear) - if preceding > n: # estimate is too large - month -= 1 - preceding -= _DAYS_IN_MONTH[month] + (month == 2 and leapyear) - n -= preceding - assert 0 <= n < _days_in_month(year, month) - - # Now the year and month are correct, and n is the offset from the - # start of that month: we're done! - return year, month, n+1 - -# Month and day names. For localized versions, see the calendar module. -_MONTHNAMES = [None, "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] -_DAYNAMES = [None, "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"] - - -def _build_struct_time(y, m, d, hh, mm, ss, dstflag): - wday = (_ymd2ord(y, m, d) + 6) % 7 - dnum = _days_before_month(y, m) + d - return _time.struct_time((y, m, d, hh, mm, ss, wday, dnum, dstflag)) - -def _format_time(hh, mm, ss, us, timespec='auto'): - specs = { - 'hours': '{:02d}', - 'minutes': '{:02d}:{:02d}', - 'seconds': '{:02d}:{:02d}:{:02d}', - 'milliseconds': '{:02d}:{:02d}:{:02d}.{:03d}', - 'microseconds': '{:02d}:{:02d}:{:02d}.{:06d}' - } - - if timespec == 'auto': - # Skip trailing microseconds when us==0. - timespec = 'microseconds' if us else 'seconds' - elif timespec == 'milliseconds': - us //= 1000 - try: - fmt = specs[timespec] - except KeyError: - raise ValueError('Unknown timespec value') - else: - return fmt.format(hh, mm, ss, us) - -def _format_offset(off): - s = '' - if off is not None: - if off.days < 0: - sign = "-" - off = -off - else: - sign = "+" - hh, mm = divmod(off, timedelta(hours=1)) - mm, ss = divmod(mm, timedelta(minutes=1)) - s += "%s%02d:%02d" % (sign, hh, mm) - if ss or ss.microseconds: - s += ":%02d" % ss.seconds - - if ss.microseconds: - s += '.%06d' % ss.microseconds - return s - -# Correctly substitute for %z and %Z escapes in strftime formats. -def _wrap_strftime(object, format, timetuple): - # Don't call utcoffset() or tzname() unless actually needed. - freplace = None # the string to use for %f - zreplace = None # the string to use for %z - Zreplace = None # the string to use for %Z - - # Scan format for %z and %Z escapes, replacing as needed. - newformat = [] - push = newformat.append - i, n = 0, len(format) - while i < n: - ch = format[i] - i += 1 - if ch == '%': - if i < n: - ch = format[i] - i += 1 - if ch == 'f': - if freplace is None: - freplace = '%06d' % getattr(object, - 'microsecond', 0) - newformat.append(freplace) - elif ch == 'z': - if zreplace is None: - zreplace = "" - if hasattr(object, "utcoffset"): - offset = object.utcoffset() - if offset is not None: - sign = '+' - if offset.days < 0: - offset = -offset - sign = '-' - h, rest = divmod(offset, timedelta(hours=1)) - m, rest = divmod(rest, timedelta(minutes=1)) - s = rest.seconds - u = offset.microseconds - if u: - zreplace = '%c%02d%02d%02d.%06d' % (sign, h, m, s, u) - elif s: - zreplace = '%c%02d%02d%02d' % (sign, h, m, s) - else: - zreplace = '%c%02d%02d' % (sign, h, m) - assert '%' not in zreplace - newformat.append(zreplace) - elif ch == 'Z': - if Zreplace is None: - Zreplace = "" - if hasattr(object, "tzname"): - s = object.tzname() - if s is not None: - # strftime is going to have at this: escape % - Zreplace = s.replace('%', '%%') - newformat.append(Zreplace) - else: - push('%') - push(ch) - else: - push('%') - else: - push(ch) - newformat = "".join(newformat) - return _time.strftime(newformat, timetuple) - -# Helpers for parsing the result of isoformat() -def _is_ascii_digit(c): - return c in "0123456789" - -def _find_isoformat_datetime_separator(dtstr): - # See the comment in _datetimemodule.c:_find_isoformat_datetime_separator - len_dtstr = len(dtstr) - if len_dtstr == 7: - return 7 - - assert len_dtstr > 7 - date_separator = "-" - week_indicator = "W" - - if dtstr[4] == date_separator: - if dtstr[5] == week_indicator: - if len_dtstr < 8: - raise ValueError("Invalid ISO string") - if len_dtstr > 8 and dtstr[8] == date_separator: - if len_dtstr == 9: - raise ValueError("Invalid ISO string") - if len_dtstr > 10 and _is_ascii_digit(dtstr[10]): - # This is as far as we need to resolve the ambiguity for - # the moment - if we have YYYY-Www-##, the separator is - # either a hyphen at 8 or a number at 10. - # - # We'll assume it's a hyphen at 8 because it's way more - # likely that someone will use a hyphen as a separator than - # a number, but at this point it's really best effort - # because this is an extension of the spec anyway. - # TODO(pganssle): Document this - return 8 - return 10 - else: - # YYYY-Www (8) - return 8 - else: - # YYYY-MM-DD (10) - return 10 - else: - if dtstr[4] == week_indicator: - # YYYYWww (7) or YYYYWwwd (8) - idx = 7 - while idx < len_dtstr: - if not _is_ascii_digit(dtstr[idx]): - break - idx += 1 - - if idx < 9: - return idx - - if idx % 2 == 0: - # If the index of the last number is even, it's YYYYWwwd - return 7 - else: - return 8 - else: - # YYYYMMDD (8) - return 8 - - -def _parse_isoformat_date(dtstr): - # It is assumed that this is an ASCII-only string of lengths 7, 8 or 10, - # see the comment on Modules/_datetimemodule.c:_find_isoformat_datetime_separator - assert len(dtstr) in (7, 8, 10) - year = int(dtstr[0:4]) - has_sep = dtstr[4] == '-' - - pos = 4 + has_sep - if dtstr[pos:pos + 1] == "W": - # YYYY-?Www-?D? - pos += 1 - weekno = int(dtstr[pos:pos + 2]) - pos += 2 - - dayno = 1 - if len(dtstr) > pos: - if (dtstr[pos:pos + 1] == '-') != has_sep: - raise ValueError("Inconsistent use of dash separator") - - pos += has_sep - - dayno = int(dtstr[pos:pos + 1]) - - return list(_isoweek_to_gregorian(year, weekno, dayno)) - else: - month = int(dtstr[pos:pos + 2]) - pos += 2 - if (dtstr[pos:pos + 1] == "-") != has_sep: - raise ValueError("Inconsistent use of dash separator") - - pos += has_sep - day = int(dtstr[pos:pos + 2]) - - return [year, month, day] - - -_FRACTION_CORRECTION = [100000, 10000, 1000, 100, 10] - - -def _parse_hh_mm_ss_ff(tstr): - # Parses things of the form HH[:?MM[:?SS[{.,}fff[fff]]]] - len_str = len(tstr) - - time_comps = [0, 0, 0, 0] - pos = 0 - for comp in range(0, 3): - if (len_str - pos) < 2: - raise ValueError("Incomplete time component") - - time_comps[comp] = int(tstr[pos:pos+2]) - - pos += 2 - next_char = tstr[pos:pos+1] - - if comp == 0: - has_sep = next_char == ':' - - if not next_char or comp >= 2: - break - - if has_sep and next_char != ':': - raise ValueError("Invalid time separator: %c" % next_char) - - pos += has_sep - - if pos < len_str: - if tstr[pos] not in '.,': - raise ValueError("Invalid microsecond component") - else: - pos += 1 - - len_remainder = len_str - pos - - if len_remainder >= 6: - to_parse = 6 - else: - to_parse = len_remainder - - time_comps[3] = int(tstr[pos:(pos+to_parse)]) - if to_parse < 6: - time_comps[3] *= _FRACTION_CORRECTION[to_parse-1] - if (len_remainder > to_parse - and not all(map(_is_ascii_digit, tstr[(pos+to_parse):]))): - raise ValueError("Non-digit values in unparsed fraction") - - return time_comps - -def _parse_isoformat_time(tstr): - # Format supported is HH[:MM[:SS[.fff[fff]]]][+HH:MM[:SS[.ffffff]]] - len_str = len(tstr) - if len_str < 2: - raise ValueError("Isoformat time too short") - - # This is equivalent to re.search('[+-Z]', tstr), but faster - tz_pos = (tstr.find('-') + 1 or tstr.find('+') + 1 or tstr.find('Z') + 1) - timestr = tstr[:tz_pos-1] if tz_pos > 0 else tstr - - time_comps = _parse_hh_mm_ss_ff(timestr) - - tzi = None - if tz_pos == len_str and tstr[-1] == 'Z': - tzi = timezone.utc - elif tz_pos > 0: - tzstr = tstr[tz_pos:] - - # Valid time zone strings are: - # HH len: 2 - # HHMM len: 4 - # HH:MM len: 5 - # HHMMSS len: 6 - # HHMMSS.f+ len: 7+ - # HH:MM:SS len: 8 - # HH:MM:SS.f+ len: 10+ - - if len(tzstr) in (0, 1, 3): - raise ValueError("Malformed time zone string") - - tz_comps = _parse_hh_mm_ss_ff(tzstr) - - if all(x == 0 for x in tz_comps): - tzi = timezone.utc - else: - tzsign = -1 if tstr[tz_pos - 1] == '-' else 1 - - td = timedelta(hours=tz_comps[0], minutes=tz_comps[1], - seconds=tz_comps[2], microseconds=tz_comps[3]) - - tzi = timezone(tzsign * td) - - time_comps.append(tzi) - - return time_comps - -# tuple[int, int, int] -> tuple[int, int, int] version of date.fromisocalendar -def _isoweek_to_gregorian(year, week, day): - # Year is bounded this way because 9999-12-31 is (9999, 52, 5) - if not MINYEAR <= year <= MAXYEAR: - raise ValueError(f"Year is out of range: {year}") - - if not 0 < week < 53: - out_of_range = True - - if week == 53: - # ISO years have 53 weeks in them on years starting with a - # Thursday and leap years starting on a Wednesday - first_weekday = _ymd2ord(year, 1, 1) % 7 - if (first_weekday == 4 or (first_weekday == 3 and - _is_leap(year))): - out_of_range = False - - if out_of_range: - raise ValueError(f"Invalid week: {week}") - - if not 0 < day < 8: - raise ValueError(f"Invalid weekday: {day} (range is [1, 7])") - - # Now compute the offset from (Y, 1, 1) in days: - day_offset = (week - 1) * 7 + (day - 1) - - # Calculate the ordinal day for monday, week 1 - day_1 = _isoweek1monday(year) - ord_day = day_1 + day_offset - - return _ord2ymd(ord_day) - - -# Just raise TypeError if the arg isn't None or a string. -def _check_tzname(name): - if name is not None and not isinstance(name, str): - raise TypeError("tzinfo.tzname() must return None or string, " - "not '%s'" % type(name)) - -# name is the offset-producing method, "utcoffset" or "dst". -# offset is what it returned. -# If offset isn't None or timedelta, raises TypeError. -# If offset is None, returns None. -# Else offset is checked for being in range. -# If it is, its integer value is returned. Else ValueError is raised. -def _check_utc_offset(name, offset): - assert name in ("utcoffset", "dst") - if offset is None: - return - if not isinstance(offset, timedelta): - raise TypeError("tzinfo.%s() must return None " - "or timedelta, not '%s'" % (name, type(offset))) - if not -timedelta(1) < offset < timedelta(1): - raise ValueError("%s()=%s, must be strictly between " - "-timedelta(hours=24) and timedelta(hours=24)" % - (name, offset)) - -def _check_date_fields(year, month, day): - year = _index(year) - month = _index(month) - day = _index(day) - if not MINYEAR <= year <= MAXYEAR: - raise ValueError('year must be in %d..%d' % (MINYEAR, MAXYEAR), year) - if not 1 <= month <= 12: - raise ValueError('month must be in 1..12', month) - dim = _days_in_month(year, month) - if not 1 <= day <= dim: - raise ValueError('day must be in 1..%d' % dim, day) - return year, month, day - -def _check_time_fields(hour, minute, second, microsecond, fold): - hour = _index(hour) - minute = _index(minute) - second = _index(second) - microsecond = _index(microsecond) - if not 0 <= hour <= 23: - raise ValueError('hour must be in 0..23', hour) - if not 0 <= minute <= 59: - raise ValueError('minute must be in 0..59', minute) - if not 0 <= second <= 59: - raise ValueError('second must be in 0..59', second) - if not 0 <= microsecond <= 999999: - raise ValueError('microsecond must be in 0..999999', microsecond) - if fold not in (0, 1): - raise ValueError('fold must be either 0 or 1', fold) - return hour, minute, second, microsecond, fold - -def _check_tzinfo_arg(tz): - if tz is not None and not isinstance(tz, tzinfo): - raise TypeError("tzinfo argument must be None or of a tzinfo subclass") - -def _cmperror(x, y): - raise TypeError("can't compare '%s' to '%s'" % ( - type(x).__name__, type(y).__name__)) - -def _divide_and_round(a, b): - """divide a by b and round result to the nearest integer - - When the ratio is exactly half-way between two integers, - the even integer is returned. - """ - # Based on the reference implementation for divmod_near - # in Objects/longobject.c. - q, r = divmod(a, b) - # round up if either r / b > 0.5, or r / b == 0.5 and q is odd. - # The expression r / b > 0.5 is equivalent to 2 * r > b if b is - # positive, 2 * r < b if b negative. - r *= 2 - greater_than_half = r > b if b > 0 else r < b - if greater_than_half or r == b and q % 2 == 1: - q += 1 - - return q - - -class timedelta: - """Represent the difference between two datetime objects. - - Supported operators: - - - add, subtract timedelta - - unary plus, minus, abs - - compare to timedelta - - multiply, divide by int - - In addition, datetime supports subtraction of two datetime objects - returning a timedelta, and addition or subtraction of a datetime - and a timedelta giving a datetime. - - Representation: (days, seconds, microseconds). Why? Because I - felt like it. - """ - __slots__ = '_days', '_seconds', '_microseconds', '_hashcode' - - def __new__(cls, days=0, seconds=0, microseconds=0, - milliseconds=0, minutes=0, hours=0, weeks=0): - # Doing this efficiently and accurately in C is going to be difficult - # and error-prone, due to ubiquitous overflow possibilities, and that - # C double doesn't have enough bits of precision to represent - # microseconds over 10K years faithfully. The code here tries to make - # explicit where go-fast assumptions can be relied on, in order to - # guide the C implementation; it's way more convoluted than speed- - # ignoring auto-overflow-to-long idiomatic Python could be. - - # XXX Check that all inputs are ints or floats. - - # Final values, all integer. - # s and us fit in 32-bit signed ints; d isn't bounded. - d = s = us = 0 - - # Normalize everything to days, seconds, microseconds. - days += weeks*7 - seconds += minutes*60 + hours*3600 - microseconds += milliseconds*1000 - - # Get rid of all fractions, and normalize s and us. - # Take a deep breath <wink>. - if isinstance(days, float): - dayfrac, days = _math.modf(days) - daysecondsfrac, daysecondswhole = _math.modf(dayfrac * (24.*3600.)) - assert daysecondswhole == int(daysecondswhole) # can't overflow - s = int(daysecondswhole) - assert days == int(days) - d = int(days) - else: - daysecondsfrac = 0.0 - d = days - assert isinstance(daysecondsfrac, float) - assert abs(daysecondsfrac) <= 1.0 - assert isinstance(d, int) - assert abs(s) <= 24 * 3600 - # days isn't referenced again before redefinition - - if isinstance(seconds, float): - secondsfrac, seconds = _math.modf(seconds) - assert seconds == int(seconds) - seconds = int(seconds) - secondsfrac += daysecondsfrac - assert abs(secondsfrac) <= 2.0 - else: - secondsfrac = daysecondsfrac - # daysecondsfrac isn't referenced again - assert isinstance(secondsfrac, float) - assert abs(secondsfrac) <= 2.0 - - assert isinstance(seconds, int) - days, seconds = divmod(seconds, 24*3600) - d += days - s += int(seconds) # can't overflow - assert isinstance(s, int) - assert abs(s) <= 2 * 24 * 3600 - # seconds isn't referenced again before redefinition - - usdouble = secondsfrac * 1e6 - assert abs(usdouble) < 2.1e6 # exact value not critical - # secondsfrac isn't referenced again - - if isinstance(microseconds, float): - microseconds = round(microseconds + usdouble) - seconds, microseconds = divmod(microseconds, 1000000) - days, seconds = divmod(seconds, 24*3600) - d += days - s += seconds - else: - microseconds = int(microseconds) - seconds, microseconds = divmod(microseconds, 1000000) - days, seconds = divmod(seconds, 24*3600) - d += days - s += seconds - microseconds = round(microseconds + usdouble) - assert isinstance(s, int) - assert isinstance(microseconds, int) - assert abs(s) <= 3 * 24 * 3600 - assert abs(microseconds) < 3.1e6 - - # Just a little bit of carrying possible for microseconds and seconds. - seconds, us = divmod(microseconds, 1000000) - s += seconds - days, s = divmod(s, 24*3600) - d += days - - assert isinstance(d, int) - assert isinstance(s, int) and 0 <= s < 24*3600 - assert isinstance(us, int) and 0 <= us < 1000000 - - if abs(d) > 999999999: - raise OverflowError("timedelta # of days is too large: %d" % d) - - self = object.__new__(cls) - self._days = d - self._seconds = s - self._microseconds = us - self._hashcode = -1 - return self - - def __repr__(self): - args = [] - if self._days: - args.append("days=%d" % self._days) - if self._seconds: - args.append("seconds=%d" % self._seconds) - if self._microseconds: - args.append("microseconds=%d" % self._microseconds) - if not args: - args.append('0') - return "%s.%s(%s)" % (self.__class__.__module__, - self.__class__.__qualname__, - ', '.join(args)) - - def __str__(self): - mm, ss = divmod(self._seconds, 60) - hh, mm = divmod(mm, 60) - s = "%d:%02d:%02d" % (hh, mm, ss) - if self._days: - def plural(n): - return n, abs(n) != 1 and "s" or "" - s = ("%d day%s, " % plural(self._days)) + s - if self._microseconds: - s = s + ".%06d" % self._microseconds - return s - - def total_seconds(self): - """Total seconds in the duration.""" - return ((self.days * 86400 + self.seconds) * 10**6 + - self.microseconds) / 10**6 - - # Read-only field accessors - @property - def days(self): - """days""" - return self._days - - @property - def seconds(self): - """seconds""" - return self._seconds - - @property - def microseconds(self): - """microseconds""" - return self._microseconds - - def __add__(self, other): - if isinstance(other, timedelta): - # for CPython compatibility, we cannot use - # our __class__ here, but need a real timedelta - return timedelta(self._days + other._days, - self._seconds + other._seconds, - self._microseconds + other._microseconds) - return NotImplemented - - __radd__ = __add__ - - def __sub__(self, other): - if isinstance(other, timedelta): - # for CPython compatibility, we cannot use - # our __class__ here, but need a real timedelta - return timedelta(self._days - other._days, - self._seconds - other._seconds, - self._microseconds - other._microseconds) - return NotImplemented - - def __rsub__(self, other): - if isinstance(other, timedelta): - return -self + other - return NotImplemented - - def __neg__(self): - # for CPython compatibility, we cannot use - # our __class__ here, but need a real timedelta - return timedelta(-self._days, - -self._seconds, - -self._microseconds) - - def __pos__(self): - return self - - def __abs__(self): - if self._days < 0: - return -self - else: - return self - - def __mul__(self, other): - if isinstance(other, int): - # for CPython compatibility, we cannot use - # our __class__ here, but need a real timedelta - return timedelta(self._days * other, - self._seconds * other, - self._microseconds * other) - if isinstance(other, float): - usec = self._to_microseconds() - a, b = other.as_integer_ratio() - return timedelta(0, 0, _divide_and_round(usec * a, b)) - return NotImplemented - - __rmul__ = __mul__ - - def _to_microseconds(self): - return ((self._days * (24*3600) + self._seconds) * 1000000 + - self._microseconds) - - def __floordiv__(self, other): - if not isinstance(other, (int, timedelta)): - return NotImplemented - usec = self._to_microseconds() - if isinstance(other, timedelta): - return usec // other._to_microseconds() - if isinstance(other, int): - return timedelta(0, 0, usec // other) - - def __truediv__(self, other): - if not isinstance(other, (int, float, timedelta)): - return NotImplemented - usec = self._to_microseconds() - if isinstance(other, timedelta): - return usec / other._to_microseconds() - if isinstance(other, int): - return timedelta(0, 0, _divide_and_round(usec, other)) - if isinstance(other, float): - a, b = other.as_integer_ratio() - return timedelta(0, 0, _divide_and_round(b * usec, a)) - - def __mod__(self, other): - if isinstance(other, timedelta): - r = self._to_microseconds() % other._to_microseconds() - return timedelta(0, 0, r) - return NotImplemented - - def __divmod__(self, other): - if isinstance(other, timedelta): - q, r = divmod(self._to_microseconds(), - other._to_microseconds()) - return q, timedelta(0, 0, r) - return NotImplemented - - # Comparisons of timedelta objects with other. - - def __eq__(self, other): - if isinstance(other, timedelta): - return self._cmp(other) == 0 - else: - return NotImplemented - - def __le__(self, other): - if isinstance(other, timedelta): - return self._cmp(other) <= 0 - else: - return NotImplemented - - def __lt__(self, other): - if isinstance(other, timedelta): - return self._cmp(other) < 0 - else: - return NotImplemented - - def __ge__(self, other): - if isinstance(other, timedelta): - return self._cmp(other) >= 0 - else: - return NotImplemented - - def __gt__(self, other): - if isinstance(other, timedelta): - return self._cmp(other) > 0 - else: - return NotImplemented - - def _cmp(self, other): - assert isinstance(other, timedelta) - return _cmp(self._getstate(), other._getstate()) - - def __hash__(self): - if self._hashcode == -1: - self._hashcode = hash(self._getstate()) - return self._hashcode - - def __bool__(self): - return (self._days != 0 or - self._seconds != 0 or - self._microseconds != 0) - - # Pickle support. - - def _getstate(self): - return (self._days, self._seconds, self._microseconds) - - def __reduce__(self): - return (self.__class__, self._getstate()) - -timedelta.min = timedelta(-999999999) -timedelta.max = timedelta(days=999999999, hours=23, minutes=59, seconds=59, - microseconds=999999) -timedelta.resolution = timedelta(microseconds=1) - -class date: - """Concrete date type. - - Constructors: - - __new__() - fromtimestamp() - today() - fromordinal() - - Operators: - - __repr__, __str__ - __eq__, __le__, __lt__, __ge__, __gt__, __hash__ - __add__, __radd__, __sub__ (add/radd only with timedelta arg) - - Methods: - - timetuple() - toordinal() - weekday() - isoweekday(), isocalendar(), isoformat() - ctime() - strftime() - - Properties (readonly): - year, month, day - """ - __slots__ = '_year', '_month', '_day', '_hashcode' - - def __new__(cls, year, month=None, day=None): - """Constructor. - - Arguments: - - year, month, day (required, base 1) - """ - if (month is None and - isinstance(year, (bytes, str)) and len(year) == 4 and - 1 <= ord(year[2:3]) <= 12): - # Pickle support - if isinstance(year, str): - try: - year = year.encode('latin1') - except UnicodeEncodeError: - # More informative error message. - raise ValueError( - "Failed to encode latin1 string when unpickling " - "a date object. " - "pickle.load(data, encoding='latin1') is assumed.") - self = object.__new__(cls) - self.__setstate(year) - self._hashcode = -1 - return self - year, month, day = _check_date_fields(year, month, day) - self = object.__new__(cls) - self._year = year - self._month = month - self._day = day - self._hashcode = -1 - return self - - # Additional constructors - - @classmethod - def fromtimestamp(cls, t): - "Construct a date from a POSIX timestamp (like time.time())." - y, m, d, hh, mm, ss, weekday, jday, dst = _time.localtime(t) - return cls(y, m, d) - - @classmethod - def today(cls): - "Construct a date from time.time()." - t = _time.time() - return cls.fromtimestamp(t) - - @classmethod - def fromordinal(cls, n): - """Construct a date from a proleptic Gregorian ordinal. - - January 1 of year 1 is day 1. Only the year, month and day are - non-zero in the result. - """ - y, m, d = _ord2ymd(n) - return cls(y, m, d) - - @classmethod - def fromisoformat(cls, date_string): - """Construct a date from a string in ISO 8601 format.""" - if not isinstance(date_string, str): - raise TypeError('fromisoformat: argument must be str') - - if len(date_string) not in (7, 8, 10): - raise ValueError(f'Invalid isoformat string: {date_string!r}') - - try: - return cls(*_parse_isoformat_date(date_string)) - except Exception: - raise ValueError(f'Invalid isoformat string: {date_string!r}') - - @classmethod - def fromisocalendar(cls, year, week, day): - """Construct a date from the ISO year, week number and weekday. - - This is the inverse of the date.isocalendar() function""" - return cls(*_isoweek_to_gregorian(year, week, day)) - - # Conversions to string - - def __repr__(self): - """Convert to formal string, for repr(). - - >>> dt = datetime(2010, 1, 1) - >>> repr(dt) - 'datetime.datetime(2010, 1, 1, 0, 0)' - - >>> dt = datetime(2010, 1, 1, tzinfo=timezone.utc) - >>> repr(dt) - 'datetime.datetime(2010, 1, 1, 0, 0, tzinfo=datetime.timezone.utc)' - """ - return "%s.%s(%d, %d, %d)" % (self.__class__.__module__, - self.__class__.__qualname__, - self._year, - self._month, - self._day) - # XXX These shouldn't depend on time.localtime(), because that - # clips the usable dates to [1970 .. 2038). At least ctime() is - # easily done without using strftime() -- that's better too because - # strftime("%c", ...) is locale specific. - - - def ctime(self): - "Return ctime() style string." - weekday = self.toordinal() % 7 or 7 - return "%s %s %2d 00:00:00 %04d" % ( - _DAYNAMES[weekday], - _MONTHNAMES[self._month], - self._day, self._year) - - def strftime(self, fmt): - """ - Format using strftime(). - - Example: "%d/%m/%Y, %H:%M:%S" - """ - return _wrap_strftime(self, fmt, self.timetuple()) - - def __format__(self, fmt): - if not isinstance(fmt, str): - raise TypeError("must be str, not %s" % type(fmt).__name__) - if len(fmt) != 0: - return self.strftime(fmt) - return str(self) - - def isoformat(self): - """Return the date formatted according to ISO. - - This is 'YYYY-MM-DD'. - - References: - - http://www.w3.org/TR/NOTE-datetime - - http://www.cl.cam.ac.uk/~mgk25/iso-time.html - """ - return "%04d-%02d-%02d" % (self._year, self._month, self._day) - - __str__ = isoformat - - # Read-only field accessors - @property - def year(self): - """year (1-9999)""" - return self._year - - @property - def month(self): - """month (1-12)""" - return self._month - - @property - def day(self): - """day (1-31)""" - return self._day - - # Standard conversions, __eq__, __le__, __lt__, __ge__, __gt__, - # __hash__ (and helpers) - - def timetuple(self): - "Return local time tuple compatible with time.localtime()." - return _build_struct_time(self._year, self._month, self._day, - 0, 0, 0, -1) - - def toordinal(self): - """Return proleptic Gregorian ordinal for the year, month and day. - - January 1 of year 1 is day 1. Only the year, month and day values - contribute to the result. - """ - return _ymd2ord(self._year, self._month, self._day) - - def replace(self, year=None, month=None, day=None): - """Return a new date with new values for the specified fields.""" - if year is None: - year = self._year - if month is None: - month = self._month - if day is None: - day = self._day - return type(self)(year, month, day) - - # Comparisons of date objects with other. - - def __eq__(self, other): - if isinstance(other, date): - return self._cmp(other) == 0 - return NotImplemented - - def __le__(self, other): - if isinstance(other, date): - return self._cmp(other) <= 0 - return NotImplemented - - def __lt__(self, other): - if isinstance(other, date): - return self._cmp(other) < 0 - return NotImplemented - - def __ge__(self, other): - if isinstance(other, date): - return self._cmp(other) >= 0 - return NotImplemented - - def __gt__(self, other): - if isinstance(other, date): - return self._cmp(other) > 0 - return NotImplemented - - def _cmp(self, other): - assert isinstance(other, date) - y, m, d = self._year, self._month, self._day - y2, m2, d2 = other._year, other._month, other._day - return _cmp((y, m, d), (y2, m2, d2)) - - def __hash__(self): - "Hash." - if self._hashcode == -1: - self._hashcode = hash(self._getstate()) - return self._hashcode - - # Computations - - def __add__(self, other): - "Add a date to a timedelta." - if isinstance(other, timedelta): - o = self.toordinal() + other.days - if 0 < o <= _MAXORDINAL: - return type(self).fromordinal(o) - raise OverflowError("result out of range") - return NotImplemented - - __radd__ = __add__ - - def __sub__(self, other): - """Subtract two dates, or a date and a timedelta.""" - if isinstance(other, timedelta): - return self + timedelta(-other.days) - if isinstance(other, date): - days1 = self.toordinal() - days2 = other.toordinal() - return timedelta(days1 - days2) - return NotImplemented - - def weekday(self): - "Return day of the week, where Monday == 0 ... Sunday == 6." - return (self.toordinal() + 6) % 7 - - # Day-of-the-week and week-of-the-year, according to ISO - - def isoweekday(self): - "Return day of the week, where Monday == 1 ... Sunday == 7." - # 1-Jan-0001 is a Monday - return self.toordinal() % 7 or 7 - - def isocalendar(self): - """Return a named tuple containing ISO year, week number, and weekday. - - The first ISO week of the year is the (Mon-Sun) week - containing the year's first Thursday; everything else derives - from that. - - The first week is 1; Monday is 1 ... Sunday is 7. - - ISO calendar algorithm taken from - http://www.phys.uu.nl/~vgent/calendar/isocalendar.htm - (used with permission) - """ - year = self._year - week1monday = _isoweek1monday(year) - today = _ymd2ord(self._year, self._month, self._day) - # Internally, week and day have origin 0 - week, day = divmod(today - week1monday, 7) - if week < 0: - year -= 1 - week1monday = _isoweek1monday(year) - week, day = divmod(today - week1monday, 7) - elif week >= 52: - if today >= _isoweek1monday(year+1): - year += 1 - week = 0 - return _IsoCalendarDate(year, week+1, day+1) - - # Pickle support. - - def _getstate(self): - yhi, ylo = divmod(self._year, 256) - return bytes([yhi, ylo, self._month, self._day]), - - def __setstate(self, string): - yhi, ylo, self._month, self._day = string - self._year = yhi * 256 + ylo - - def __reduce__(self): - return (self.__class__, self._getstate()) - -_date_class = date # so functions w/ args named "date" can get at the class - -date.min = date(1, 1, 1) -date.max = date(9999, 12, 31) -date.resolution = timedelta(days=1) - - -class tzinfo: - """Abstract base class for time zone info classes. - - Subclasses must override the name(), utcoffset() and dst() methods. - """ - __slots__ = () - - def tzname(self, dt): - "datetime -> string name of time zone." - raise NotImplementedError("tzinfo subclass must override tzname()") - - def utcoffset(self, dt): - "datetime -> timedelta, positive for east of UTC, negative for west of UTC" - raise NotImplementedError("tzinfo subclass must override utcoffset()") - - def dst(self, dt): - """datetime -> DST offset as timedelta, positive for east of UTC. - - Return 0 if DST not in effect. utcoffset() must include the DST - offset. - """ - raise NotImplementedError("tzinfo subclass must override dst()") - - def fromutc(self, dt): - "datetime in UTC -> datetime in local time." - - if not isinstance(dt, datetime): - raise TypeError("fromutc() requires a datetime argument") - if dt.tzinfo is not self: - raise ValueError("dt.tzinfo is not self") - - dtoff = dt.utcoffset() - if dtoff is None: - raise ValueError("fromutc() requires a non-None utcoffset() " - "result") - - # See the long comment block at the end of this file for an - # explanation of this algorithm. - dtdst = dt.dst() - if dtdst is None: - raise ValueError("fromutc() requires a non-None dst() result") - delta = dtoff - dtdst - if delta: - dt += delta - dtdst = dt.dst() - if dtdst is None: - raise ValueError("fromutc(): dt.dst gave inconsistent " - "results; cannot convert") - return dt + dtdst - - # Pickle support. - - def __reduce__(self): - getinitargs = getattr(self, "__getinitargs__", None) - if getinitargs: - args = getinitargs() - else: - args = () - return (self.__class__, args, self.__getstate__()) - - -class IsoCalendarDate(tuple): - - def __new__(cls, year, week, weekday, /): - return super().__new__(cls, (year, week, weekday)) - - @property - def year(self): - return self[0] - - @property - def week(self): - return self[1] - - @property - def weekday(self): - return self[2] - - def __reduce__(self): - # This code is intended to pickle the object without making the - # class public. See https://bugs.python.org/msg352381 - return (tuple, (tuple(self),)) - - def __repr__(self): - return (f'{self.__class__.__name__}' - f'(year={self[0]}, week={self[1]}, weekday={self[2]})') - - -_IsoCalendarDate = IsoCalendarDate -del IsoCalendarDate -_tzinfo_class = tzinfo - -class time: - """Time with time zone. - - Constructors: - - __new__() - - Operators: - - __repr__, __str__ - __eq__, __le__, __lt__, __ge__, __gt__, __hash__ - - Methods: - - strftime() - isoformat() - utcoffset() - tzname() - dst() - - Properties (readonly): - hour, minute, second, microsecond, tzinfo, fold - """ - __slots__ = '_hour', '_minute', '_second', '_microsecond', '_tzinfo', '_hashcode', '_fold' - - def __new__(cls, hour=0, minute=0, second=0, microsecond=0, tzinfo=None, *, fold=0): - """Constructor. - - Arguments: - - hour, minute (required) - second, microsecond (default to zero) - tzinfo (default to None) - fold (keyword only, default to zero) - """ - if (isinstance(hour, (bytes, str)) and len(hour) == 6 and - ord(hour[0:1])&0x7F < 24): - # Pickle support - if isinstance(hour, str): - try: - hour = hour.encode('latin1') - except UnicodeEncodeError: - # More informative error message. - raise ValueError( - "Failed to encode latin1 string when unpickling " - "a time object. " - "pickle.load(data, encoding='latin1') is assumed.") - self = object.__new__(cls) - self.__setstate(hour, minute or None) - self._hashcode = -1 - return self - hour, minute, second, microsecond, fold = _check_time_fields( - hour, minute, second, microsecond, fold) - _check_tzinfo_arg(tzinfo) - self = object.__new__(cls) - self._hour = hour - self._minute = minute - self._second = second - self._microsecond = microsecond - self._tzinfo = tzinfo - self._hashcode = -1 - self._fold = fold - return self - - # Read-only field accessors - @property - def hour(self): - """hour (0-23)""" - return self._hour - - @property - def minute(self): - """minute (0-59)""" - return self._minute - - @property - def second(self): - """second (0-59)""" - return self._second - - @property - def microsecond(self): - """microsecond (0-999999)""" - return self._microsecond - - @property - def tzinfo(self): - """timezone info object""" - return self._tzinfo - - @property - def fold(self): - return self._fold - - # Standard conversions, __hash__ (and helpers) - - # Comparisons of time objects with other. - - def __eq__(self, other): - if isinstance(other, time): - return self._cmp(other, allow_mixed=True) == 0 - else: - return NotImplemented - - def __le__(self, other): - if isinstance(other, time): - return self._cmp(other) <= 0 - else: - return NotImplemented - - def __lt__(self, other): - if isinstance(other, time): - return self._cmp(other) < 0 - else: - return NotImplemented - - def __ge__(self, other): - if isinstance(other, time): - return self._cmp(other) >= 0 - else: - return NotImplemented - - def __gt__(self, other): - if isinstance(other, time): - return self._cmp(other) > 0 - else: - return NotImplemented - - def _cmp(self, other, allow_mixed=False): - assert isinstance(other, time) - mytz = self._tzinfo - ottz = other._tzinfo - myoff = otoff = None - - if mytz is ottz: - base_compare = True - else: - myoff = self.utcoffset() - otoff = other.utcoffset() - base_compare = myoff == otoff - - if base_compare: - return _cmp((self._hour, self._minute, self._second, - self._microsecond), - (other._hour, other._minute, other._second, - other._microsecond)) - if myoff is None or otoff is None: - if allow_mixed: - return 2 # arbitrary non-zero value - else: - raise TypeError("cannot compare naive and aware times") - myhhmm = self._hour * 60 + self._minute - myoff//timedelta(minutes=1) - othhmm = other._hour * 60 + other._minute - otoff//timedelta(minutes=1) - return _cmp((myhhmm, self._second, self._microsecond), - (othhmm, other._second, other._microsecond)) - - def __hash__(self): - """Hash.""" - if self._hashcode == -1: - if self.fold: - t = self.replace(fold=0) - else: - t = self - tzoff = t.utcoffset() - if not tzoff: # zero or None - self._hashcode = hash(t._getstate()[0]) - else: - h, m = divmod(timedelta(hours=self.hour, minutes=self.minute) - tzoff, - timedelta(hours=1)) - assert not m % timedelta(minutes=1), "whole minute" - m //= timedelta(minutes=1) - if 0 <= h < 24: - self._hashcode = hash(time(h, m, self.second, self.microsecond)) - else: - self._hashcode = hash((h, m, self.second, self.microsecond)) - return self._hashcode - - # Conversion to string - - def _tzstr(self): - """Return formatted timezone offset (+xx:xx) or an empty string.""" - off = self.utcoffset() - return _format_offset(off) - - def __repr__(self): - """Convert to formal string, for repr().""" - if self._microsecond != 0: - s = ", %d, %d" % (self._second, self._microsecond) - elif self._second != 0: - s = ", %d" % self._second - else: - s = "" - s= "%s.%s(%d, %d%s)" % (self.__class__.__module__, - self.__class__.__qualname__, - self._hour, self._minute, s) - if self._tzinfo is not None: - assert s[-1:] == ")" - s = s[:-1] + ", tzinfo=%r" % self._tzinfo + ")" - if self._fold: - assert s[-1:] == ")" - s = s[:-1] + ", fold=1)" - return s - - def isoformat(self, timespec='auto'): - """Return the time formatted according to ISO. - - The full format is 'HH:MM:SS.mmmmmm+zz:zz'. By default, the fractional - part is omitted if self.microsecond == 0. - - The optional argument timespec specifies the number of additional - terms of the time to include. Valid options are 'auto', 'hours', - 'minutes', 'seconds', 'milliseconds' and 'microseconds'. - """ - s = _format_time(self._hour, self._minute, self._second, - self._microsecond, timespec) - tz = self._tzstr() - if tz: - s += tz - return s - - __str__ = isoformat - - @classmethod - def fromisoformat(cls, time_string): - """Construct a time from a string in one of the ISO 8601 formats.""" - if not isinstance(time_string, str): - raise TypeError('fromisoformat: argument must be str') - - # The spec actually requires that time-only ISO 8601 strings start with - # T, but the extended format allows this to be omitted as long as there - # is no ambiguity with date strings. - time_string = time_string.removeprefix('T') - - try: - return cls(*_parse_isoformat_time(time_string)) - except Exception: - raise ValueError(f'Invalid isoformat string: {time_string!r}') - - - def strftime(self, fmt): - """Format using strftime(). The date part of the timestamp passed - to underlying strftime should not be used. - """ - # The year must be >= 1000 else Python's strftime implementation - # can raise a bogus exception. - timetuple = (1900, 1, 1, - self._hour, self._minute, self._second, - 0, 1, -1) - return _wrap_strftime(self, fmt, timetuple) - - def __format__(self, fmt): - if not isinstance(fmt, str): - raise TypeError("must be str, not %s" % type(fmt).__name__) - if len(fmt) != 0: - return self.strftime(fmt) - return str(self) - - # Timezone functions - - def utcoffset(self): - """Return the timezone offset as timedelta, positive east of UTC - (negative west of UTC).""" - if self._tzinfo is None: - return None - offset = self._tzinfo.utcoffset(None) - _check_utc_offset("utcoffset", offset) - return offset - - def tzname(self): - """Return the timezone name. - - Note that the name is 100% informational -- there's no requirement that - it mean anything in particular. For example, "GMT", "UTC", "-500", - "-5:00", "EDT", "US/Eastern", "America/New York" are all valid replies. - """ - if self._tzinfo is None: - return None - name = self._tzinfo.tzname(None) - _check_tzname(name) - return name - - def dst(self): - """Return 0 if DST is not in effect, or the DST offset (as timedelta - positive eastward) if DST is in effect. - - This is purely informational; the DST offset has already been added to - the UTC offset returned by utcoffset() if applicable, so there's no - need to consult dst() unless you're interested in displaying the DST - info. - """ - if self._tzinfo is None: - return None - offset = self._tzinfo.dst(None) - _check_utc_offset("dst", offset) - return offset - - def replace(self, hour=None, minute=None, second=None, microsecond=None, - tzinfo=True, *, fold=None): - """Return a new time with new values for the specified fields.""" - if hour is None: - hour = self.hour - if minute is None: - minute = self.minute - if second is None: - second = self.second - if microsecond is None: - microsecond = self.microsecond - if tzinfo is True: - tzinfo = self.tzinfo - if fold is None: - fold = self._fold - return type(self)(hour, minute, second, microsecond, tzinfo, fold=fold) - - # Pickle support. - - def _getstate(self, protocol=3): - us2, us3 = divmod(self._microsecond, 256) - us1, us2 = divmod(us2, 256) - h = self._hour - if self._fold and protocol > 3: - h += 128 - basestate = bytes([h, self._minute, self._second, - us1, us2, us3]) - if self._tzinfo is None: - return (basestate,) - else: - return (basestate, self._tzinfo) - - def __setstate(self, string, tzinfo): - if tzinfo is not None and not isinstance(tzinfo, _tzinfo_class): - raise TypeError("bad tzinfo state arg") - h, self._minute, self._second, us1, us2, us3 = string - if h > 127: - self._fold = 1 - self._hour = h - 128 - else: - self._fold = 0 - self._hour = h - self._microsecond = (((us1 << 8) | us2) << 8) | us3 - self._tzinfo = tzinfo - - def __reduce_ex__(self, protocol): - return (self.__class__, self._getstate(protocol)) - - def __reduce__(self): - return self.__reduce_ex__(2) - -_time_class = time # so functions w/ args named "time" can get at the class - -time.min = time(0, 0, 0) -time.max = time(23, 59, 59, 999999) -time.resolution = timedelta(microseconds=1) - - -class datetime(date): - """datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]]) - - The year, month and day arguments are required. tzinfo may be None, or an - instance of a tzinfo subclass. The remaining arguments may be ints. - """ - __slots__ = date.__slots__ + time.__slots__ - - def __new__(cls, year, month=None, day=None, hour=0, minute=0, second=0, - microsecond=0, tzinfo=None, *, fold=0): - if (isinstance(year, (bytes, str)) and len(year) == 10 and - 1 <= ord(year[2:3])&0x7F <= 12): - # Pickle support - if isinstance(year, str): - try: - year = bytes(year, 'latin1') - except UnicodeEncodeError: - # More informative error message. - raise ValueError( - "Failed to encode latin1 string when unpickling " - "a datetime object. " - "pickle.load(data, encoding='latin1') is assumed.") - self = object.__new__(cls) - self.__setstate(year, month) - self._hashcode = -1 - return self - year, month, day = _check_date_fields(year, month, day) - hour, minute, second, microsecond, fold = _check_time_fields( - hour, minute, second, microsecond, fold) - _check_tzinfo_arg(tzinfo) - self = object.__new__(cls) - self._year = year - self._month = month - self._day = day - self._hour = hour - self._minute = minute - self._second = second - self._microsecond = microsecond - self._tzinfo = tzinfo - self._hashcode = -1 - self._fold = fold - return self - - # Read-only field accessors - @property - def hour(self): - """hour (0-23)""" - return self._hour - - @property - def minute(self): - """minute (0-59)""" - return self._minute - - @property - def second(self): - """second (0-59)""" - return self._second - - @property - def microsecond(self): - """microsecond (0-999999)""" - return self._microsecond - - @property - def tzinfo(self): - """timezone info object""" - return self._tzinfo - - @property - def fold(self): - return self._fold - - @classmethod - def _fromtimestamp(cls, t, utc, tz): - """Construct a datetime from a POSIX timestamp (like time.time()). - - A timezone info object may be passed in as well. - """ - frac, t = _math.modf(t) - us = round(frac * 1e6) - if us >= 1000000: - t += 1 - us -= 1000000 - elif us < 0: - t -= 1 - us += 1000000 - - converter = _time.gmtime if utc else _time.localtime - y, m, d, hh, mm, ss, weekday, jday, dst = converter(t) - ss = min(ss, 59) # clamp out leap seconds if the platform has them - result = cls(y, m, d, hh, mm, ss, us, tz) - if tz is None and not utc: - # As of version 2015f max fold in IANA database is - # 23 hours at 1969-09-30 13:00:00 in Kwajalein. - # Let's probe 24 hours in the past to detect a transition: - max_fold_seconds = 24 * 3600 - - # On Windows localtime_s throws an OSError for negative values, - # thus we can't perform fold detection for values of time less - # than the max time fold. See comments in _datetimemodule's - # version of this method for more details. - if t < max_fold_seconds and sys.platform.startswith("win"): - return result - - y, m, d, hh, mm, ss = converter(t - max_fold_seconds)[:6] - probe1 = cls(y, m, d, hh, mm, ss, us, tz) - trans = result - probe1 - timedelta(0, max_fold_seconds) - if trans.days < 0: - y, m, d, hh, mm, ss = converter(t + trans // timedelta(0, 1))[:6] - probe2 = cls(y, m, d, hh, mm, ss, us, tz) - if probe2 == result: - result._fold = 1 - elif tz is not None: - result = tz.fromutc(result) - return result - - @classmethod - def fromtimestamp(cls, t, tz=None): - """Construct a datetime from a POSIX timestamp (like time.time()). - - A timezone info object may be passed in as well. - """ - _check_tzinfo_arg(tz) - - return cls._fromtimestamp(t, tz is not None, tz) - - @classmethod - def utcfromtimestamp(cls, t): - """Construct a naive UTC datetime from a POSIX timestamp.""" - return cls._fromtimestamp(t, True, None) - - @classmethod - def now(cls, tz=None): - "Construct a datetime from time.time() and optional time zone info." - t = _time.time() - return cls.fromtimestamp(t, tz) - - @classmethod - def utcnow(cls): - "Construct a UTC datetime from time.time()." - t = _time.time() - return cls.utcfromtimestamp(t) - - @classmethod - def combine(cls, date, time, tzinfo=True): - "Construct a datetime from a given date and a given time." - if not isinstance(date, _date_class): - raise TypeError("date argument must be a date instance") - if not isinstance(time, _time_class): - raise TypeError("time argument must be a time instance") - if tzinfo is True: - tzinfo = time.tzinfo - return cls(date.year, date.month, date.day, - time.hour, time.minute, time.second, time.microsecond, - tzinfo, fold=time.fold) - - @classmethod - def fromisoformat(cls, date_string): - """Construct a datetime from a string in one of the ISO 8601 formats.""" - if not isinstance(date_string, str): - raise TypeError('fromisoformat: argument must be str') - - if len(date_string) < 7: - raise ValueError(f'Invalid isoformat string: {date_string!r}') - - # Split this at the separator - try: - separator_location = _find_isoformat_datetime_separator(date_string) - dstr = date_string[0:separator_location] - tstr = date_string[(separator_location+1):] - - date_components = _parse_isoformat_date(dstr) - except ValueError: - raise ValueError( - f'Invalid isoformat string: {date_string!r}') from None - - if tstr: - try: - time_components = _parse_isoformat_time(tstr) - except ValueError: - raise ValueError( - f'Invalid isoformat string: {date_string!r}') from None - else: - time_components = [0, 0, 0, 0, None] - - return cls(*(date_components + time_components)) - - def timetuple(self): - "Return local time tuple compatible with time.localtime()." - dst = self.dst() - if dst is None: - dst = -1 - elif dst: - dst = 1 - else: - dst = 0 - return _build_struct_time(self.year, self.month, self.day, - self.hour, self.minute, self.second, - dst) - - def _mktime(self): - """Return integer POSIX timestamp.""" - epoch = datetime(1970, 1, 1) - max_fold_seconds = 24 * 3600 - t = (self - epoch) // timedelta(0, 1) - def local(u): - y, m, d, hh, mm, ss = _time.localtime(u)[:6] - return (datetime(y, m, d, hh, mm, ss) - epoch) // timedelta(0, 1) - - # Our goal is to solve t = local(u) for u. - a = local(t) - t - u1 = t - a - t1 = local(u1) - if t1 == t: - # We found one solution, but it may not be the one we need. - # Look for an earlier solution (if `fold` is 0), or a - # later one (if `fold` is 1). - u2 = u1 + (-max_fold_seconds, max_fold_seconds)[self.fold] - b = local(u2) - u2 - if a == b: - return u1 - else: - b = t1 - u1 - assert a != b - u2 = t - b - t2 = local(u2) - if t2 == t: - return u2 - if t1 == t: - return u1 - # We have found both offsets a and b, but neither t - a nor t - b is - # a solution. This means t is in the gap. - return (max, min)[self.fold](u1, u2) - - - def timestamp(self): - "Return POSIX timestamp as float" - if self._tzinfo is None: - s = self._mktime() - return s + self.microsecond / 1e6 - else: - return (self - _EPOCH).total_seconds() - - def utctimetuple(self): - "Return UTC time tuple compatible with time.gmtime()." - offset = self.utcoffset() - if offset: - self -= offset - y, m, d = self.year, self.month, self.day - hh, mm, ss = self.hour, self.minute, self.second - return _build_struct_time(y, m, d, hh, mm, ss, 0) - - def date(self): - "Return the date part." - return date(self._year, self._month, self._day) - - def time(self): - "Return the time part, with tzinfo None." - return time(self.hour, self.minute, self.second, self.microsecond, fold=self.fold) - - def timetz(self): - "Return the time part, with same tzinfo." - return time(self.hour, self.minute, self.second, self.microsecond, - self._tzinfo, fold=self.fold) - - def replace(self, year=None, month=None, day=None, hour=None, - minute=None, second=None, microsecond=None, tzinfo=True, - *, fold=None): - """Return a new datetime with new values for the specified fields.""" - if year is None: - year = self.year - if month is None: - month = self.month - if day is None: - day = self.day - if hour is None: - hour = self.hour - if minute is None: - minute = self.minute - if second is None: - second = self.second - if microsecond is None: - microsecond = self.microsecond - if tzinfo is True: - tzinfo = self.tzinfo - if fold is None: - fold = self.fold - return type(self)(year, month, day, hour, minute, second, - microsecond, tzinfo, fold=fold) - - def _local_timezone(self): - if self.tzinfo is None: - ts = self._mktime() - else: - ts = (self - _EPOCH) // timedelta(seconds=1) - localtm = _time.localtime(ts) - local = datetime(*localtm[:6]) - # Extract TZ data - gmtoff = localtm.tm_gmtoff - zone = localtm.tm_zone - return timezone(timedelta(seconds=gmtoff), zone) - - def astimezone(self, tz=None): - if tz is None: - tz = self._local_timezone() - elif not isinstance(tz, tzinfo): - raise TypeError("tz argument must be an instance of tzinfo") - - mytz = self.tzinfo - if mytz is None: - mytz = self._local_timezone() - myoffset = mytz.utcoffset(self) - else: - myoffset = mytz.utcoffset(self) - if myoffset is None: - mytz = self.replace(tzinfo=None)._local_timezone() - myoffset = mytz.utcoffset(self) - - if tz is mytz: - return self - - # Convert self to UTC, and attach the new time zone object. - utc = (self - myoffset).replace(tzinfo=tz) - - # Convert from UTC to tz's local time. - return tz.fromutc(utc) - - # Ways to produce a string. - - def ctime(self): - "Return ctime() style string." - weekday = self.toordinal() % 7 or 7 - return "%s %s %2d %02d:%02d:%02d %04d" % ( - _DAYNAMES[weekday], - _MONTHNAMES[self._month], - self._day, - self._hour, self._minute, self._second, - self._year) - - def isoformat(self, sep='T', timespec='auto'): - """Return the time formatted according to ISO. - - The full format looks like 'YYYY-MM-DD HH:MM:SS.mmmmmm'. - By default, the fractional part is omitted if self.microsecond == 0. - - If self.tzinfo is not None, the UTC offset is also attached, giving - giving a full format of 'YYYY-MM-DD HH:MM:SS.mmmmmm+HH:MM'. - - Optional argument sep specifies the separator between date and - time, default 'T'. - - The optional argument timespec specifies the number of additional - terms of the time to include. Valid options are 'auto', 'hours', - 'minutes', 'seconds', 'milliseconds' and 'microseconds'. - """ - s = ("%04d-%02d-%02d%c" % (self._year, self._month, self._day, sep) + - _format_time(self._hour, self._minute, self._second, - self._microsecond, timespec)) - - off = self.utcoffset() - tz = _format_offset(off) - if tz: - s += tz - - return s - - def __repr__(self): - """Convert to formal string, for repr().""" - L = [self._year, self._month, self._day, # These are never zero - self._hour, self._minute, self._second, self._microsecond] - if L[-1] == 0: - del L[-1] - if L[-1] == 0: - del L[-1] - s = "%s.%s(%s)" % (self.__class__.__module__, - self.__class__.__qualname__, - ", ".join(map(str, L))) - if self._tzinfo is not None: - assert s[-1:] == ")" - s = s[:-1] + ", tzinfo=%r" % self._tzinfo + ")" - if self._fold: - assert s[-1:] == ")" - s = s[:-1] + ", fold=1)" - return s - - def __str__(self): - "Convert to string, for str()." - return self.isoformat(sep=' ') - - @classmethod - def strptime(cls, date_string, format): - 'string, format -> new datetime parsed from a string (like time.strptime()).' - import _strptime - return _strptime._strptime_datetime(cls, date_string, format) - - def utcoffset(self): - """Return the timezone offset as timedelta positive east of UTC (negative west of - UTC).""" - if self._tzinfo is None: - return None - offset = self._tzinfo.utcoffset(self) - _check_utc_offset("utcoffset", offset) - return offset - - def tzname(self): - """Return the timezone name. - - Note that the name is 100% informational -- there's no requirement that - it mean anything in particular. For example, "GMT", "UTC", "-500", - "-5:00", "EDT", "US/Eastern", "America/New York" are all valid replies. - """ - if self._tzinfo is None: - return None - name = self._tzinfo.tzname(self) - _check_tzname(name) - return name - - def dst(self): - """Return 0 if DST is not in effect, or the DST offset (as timedelta - positive eastward) if DST is in effect. - - This is purely informational; the DST offset has already been added to - the UTC offset returned by utcoffset() if applicable, so there's no - need to consult dst() unless you're interested in displaying the DST - info. - """ - if self._tzinfo is None: - return None - offset = self._tzinfo.dst(self) - _check_utc_offset("dst", offset) - return offset - - # Comparisons of datetime objects with other. - - def __eq__(self, other): - if isinstance(other, datetime): - return self._cmp(other, allow_mixed=True) == 0 - elif not isinstance(other, date): - return NotImplemented - else: - return False - - def __le__(self, other): - if isinstance(other, datetime): - return self._cmp(other) <= 0 - elif not isinstance(other, date): - return NotImplemented - else: - _cmperror(self, other) - - def __lt__(self, other): - if isinstance(other, datetime): - return self._cmp(other) < 0 - elif not isinstance(other, date): - return NotImplemented - else: - _cmperror(self, other) - - def __ge__(self, other): - if isinstance(other, datetime): - return self._cmp(other) >= 0 - elif not isinstance(other, date): - return NotImplemented - else: - _cmperror(self, other) - - def __gt__(self, other): - if isinstance(other, datetime): - return self._cmp(other) > 0 - elif not isinstance(other, date): - return NotImplemented - else: - _cmperror(self, other) - - def _cmp(self, other, allow_mixed=False): - assert isinstance(other, datetime) - mytz = self._tzinfo - ottz = other._tzinfo - myoff = otoff = None - - if mytz is ottz: - base_compare = True - else: - myoff = self.utcoffset() - otoff = other.utcoffset() - # Assume that allow_mixed means that we are called from __eq__ - if allow_mixed: - if myoff != self.replace(fold=not self.fold).utcoffset(): - return 2 - if otoff != other.replace(fold=not other.fold).utcoffset(): - return 2 - base_compare = myoff == otoff - - if base_compare: - return _cmp((self._year, self._month, self._day, - self._hour, self._minute, self._second, - self._microsecond), - (other._year, other._month, other._day, - other._hour, other._minute, other._second, - other._microsecond)) - if myoff is None or otoff is None: - if allow_mixed: - return 2 # arbitrary non-zero value - else: - raise TypeError("cannot compare naive and aware datetimes") - # XXX What follows could be done more efficiently... - diff = self - other # this will take offsets into account - if diff.days < 0: - return -1 - return diff and 1 or 0 - - def __add__(self, other): - "Add a datetime and a timedelta." - if not isinstance(other, timedelta): - return NotImplemented - delta = timedelta(self.toordinal(), - hours=self._hour, - minutes=self._minute, - seconds=self._second, - microseconds=self._microsecond) - delta += other - hour, rem = divmod(delta.seconds, 3600) - minute, second = divmod(rem, 60) - if 0 < delta.days <= _MAXORDINAL: - return type(self).combine(date.fromordinal(delta.days), - time(hour, minute, second, - delta.microseconds, - tzinfo=self._tzinfo)) - raise OverflowError("result out of range") - - __radd__ = __add__ - - def __sub__(self, other): - "Subtract two datetimes, or a datetime and a timedelta." - if not isinstance(other, datetime): - if isinstance(other, timedelta): - return self + -other - return NotImplemented - - days1 = self.toordinal() - days2 = other.toordinal() - secs1 = self._second + self._minute * 60 + self._hour * 3600 - secs2 = other._second + other._minute * 60 + other._hour * 3600 - base = timedelta(days1 - days2, - secs1 - secs2, - self._microsecond - other._microsecond) - if self._tzinfo is other._tzinfo: - return base - myoff = self.utcoffset() - otoff = other.utcoffset() - if myoff == otoff: - return base - if myoff is None or otoff is None: - raise TypeError("cannot mix naive and timezone-aware time") - return base + otoff - myoff - - def __hash__(self): - if self._hashcode == -1: - if self.fold: - t = self.replace(fold=0) - else: - t = self - tzoff = t.utcoffset() - if tzoff is None: - self._hashcode = hash(t._getstate()[0]) - else: - days = _ymd2ord(self.year, self.month, self.day) - seconds = self.hour * 3600 + self.minute * 60 + self.second - self._hashcode = hash(timedelta(days, seconds, self.microsecond) - tzoff) - return self._hashcode - - # Pickle support. - - def _getstate(self, protocol=3): - yhi, ylo = divmod(self._year, 256) - us2, us3 = divmod(self._microsecond, 256) - us1, us2 = divmod(us2, 256) - m = self._month - if self._fold and protocol > 3: - m += 128 - basestate = bytes([yhi, ylo, m, self._day, - self._hour, self._minute, self._second, - us1, us2, us3]) - if self._tzinfo is None: - return (basestate,) - else: - return (basestate, self._tzinfo) - - def __setstate(self, string, tzinfo): - if tzinfo is not None and not isinstance(tzinfo, _tzinfo_class): - raise TypeError("bad tzinfo state arg") - (yhi, ylo, m, self._day, self._hour, - self._minute, self._second, us1, us2, us3) = string - if m > 127: - self._fold = 1 - self._month = m - 128 - else: - self._fold = 0 - self._month = m - self._year = yhi * 256 + ylo - self._microsecond = (((us1 << 8) | us2) << 8) | us3 - self._tzinfo = tzinfo - - def __reduce_ex__(self, protocol): - return (self.__class__, self._getstate(protocol)) - - def __reduce__(self): - return self.__reduce_ex__(2) - - -datetime.min = datetime(1, 1, 1) -datetime.max = datetime(9999, 12, 31, 23, 59, 59, 999999) -datetime.resolution = timedelta(microseconds=1) - - -def _isoweek1monday(year): - # Helper to calculate the day number of the Monday starting week 1 - # XXX This could be done more efficiently - THURSDAY = 3 - firstday = _ymd2ord(year, 1, 1) - firstweekday = (firstday + 6) % 7 # See weekday() above - week1monday = firstday - firstweekday - if firstweekday > THURSDAY: - week1monday += 7 - return week1monday - - -class timezone(tzinfo): - __slots__ = '_offset', '_name' - - # Sentinel value to disallow None - _Omitted = object() - def __new__(cls, offset, name=_Omitted): - if not isinstance(offset, timedelta): - raise TypeError("offset must be a timedelta") - if name is cls._Omitted: - if not offset: - return cls.utc - name = None - elif not isinstance(name, str): - raise TypeError("name must be a string") - if not cls._minoffset <= offset <= cls._maxoffset: - raise ValueError("offset must be a timedelta " - "strictly between -timedelta(hours=24) and " - "timedelta(hours=24).") - return cls._create(offset, name) - - @classmethod - def _create(cls, offset, name=None): - self = tzinfo.__new__(cls) - self._offset = offset - self._name = name - return self - - def __getinitargs__(self): - """pickle support""" - if self._name is None: - return (self._offset,) - return (self._offset, self._name) - - def __eq__(self, other): - if isinstance(other, timezone): - return self._offset == other._offset - return NotImplemented - - def __hash__(self): - return hash(self._offset) - - def __repr__(self): - """Convert to formal string, for repr(). - - >>> tz = timezone.utc - >>> repr(tz) - 'datetime.timezone.utc' - >>> tz = timezone(timedelta(hours=-5), 'EST') - >>> repr(tz) - "datetime.timezone(datetime.timedelta(-1, 68400), 'EST')" - """ - if self is self.utc: - return 'datetime.timezone.utc' - if self._name is None: - return "%s.%s(%r)" % (self.__class__.__module__, - self.__class__.__qualname__, - self._offset) - return "%s.%s(%r, %r)" % (self.__class__.__module__, - self.__class__.__qualname__, - self._offset, self._name) - - def __str__(self): - return self.tzname(None) - - def utcoffset(self, dt): - if isinstance(dt, datetime) or dt is None: - return self._offset - raise TypeError("utcoffset() argument must be a datetime instance" - " or None") - - def tzname(self, dt): - if isinstance(dt, datetime) or dt is None: - if self._name is None: - return self._name_from_offset(self._offset) - return self._name - raise TypeError("tzname() argument must be a datetime instance" - " or None") - - def dst(self, dt): - if isinstance(dt, datetime) or dt is None: - return None - raise TypeError("dst() argument must be a datetime instance" - " or None") - - def fromutc(self, dt): - if isinstance(dt, datetime): - if dt.tzinfo is not self: - raise ValueError("fromutc: dt.tzinfo " - "is not self") - return dt + self._offset - raise TypeError("fromutc() argument must be a datetime instance" - " or None") - - _maxoffset = timedelta(hours=24, microseconds=-1) - _minoffset = -_maxoffset - - @staticmethod - def _name_from_offset(delta): - if not delta: - return 'UTC' - if delta < timedelta(0): - sign = '-' - delta = -delta - else: - sign = '+' - hours, rest = divmod(delta, timedelta(hours=1)) - minutes, rest = divmod(rest, timedelta(minutes=1)) - seconds = rest.seconds - microseconds = rest.microseconds - if microseconds: - return (f'UTC{sign}{hours:02d}:{minutes:02d}:{seconds:02d}' - f'.{microseconds:06d}') - if seconds: - return f'UTC{sign}{hours:02d}:{minutes:02d}:{seconds:02d}' - return f'UTC{sign}{hours:02d}:{minutes:02d}' - -UTC = timezone.utc = timezone._create(timedelta(0)) - -# bpo-37642: These attributes are rounded to the nearest minute for backwards -# compatibility, even though the constructor will accept a wider range of -# values. This may change in the future. -timezone.min = timezone._create(-timedelta(hours=23, minutes=59)) -timezone.max = timezone._create(timedelta(hours=23, minutes=59)) -_EPOCH = datetime(1970, 1, 1, tzinfo=timezone.utc) - -# Some time zone algebra. For a datetime x, let -# x.n = x stripped of its timezone -- its naive time. -# x.o = x.utcoffset(), and assuming that doesn't raise an exception or -# return None -# x.d = x.dst(), and assuming that doesn't raise an exception or -# return None -# x.s = x's standard offset, x.o - x.d -# -# Now some derived rules, where k is a duration (timedelta). -# -# 1. x.o = x.s + x.d -# This follows from the definition of x.s. -# -# 2. If x and y have the same tzinfo member, x.s = y.s. -# This is actually a requirement, an assumption we need to make about -# sane tzinfo classes. -# -# 3. The naive UTC time corresponding to x is x.n - x.o. -# This is again a requirement for a sane tzinfo class. -# -# 4. (x+k).s = x.s -# This follows from #2, and that datetime.timetz+timedelta preserves tzinfo. -# -# 5. (x+k).n = x.n + k -# Again follows from how arithmetic is defined. -# -# Now we can explain tz.fromutc(x). Let's assume it's an interesting case -# (meaning that the various tzinfo methods exist, and don't blow up or return -# None when called). -# -# The function wants to return a datetime y with timezone tz, equivalent to x. -# x is already in UTC. -# -# By #3, we want -# -# y.n - y.o = x.n [1] -# -# The algorithm starts by attaching tz to x.n, and calling that y. So -# x.n = y.n at the start. Then it wants to add a duration k to y, so that [1] -# becomes true; in effect, we want to solve [2] for k: -# -# (y+k).n - (y+k).o = x.n [2] -# -# By #1, this is the same as -# -# (y+k).n - ((y+k).s + (y+k).d) = x.n [3] -# -# By #5, (y+k).n = y.n + k, which equals x.n + k because x.n=y.n at the start. -# Substituting that into [3], -# -# x.n + k - (y+k).s - (y+k).d = x.n; the x.n terms cancel, leaving -# k - (y+k).s - (y+k).d = 0; rearranging, -# k = (y+k).s - (y+k).d; by #4, (y+k).s == y.s, so -# k = y.s - (y+k).d -# -# On the RHS, (y+k).d can't be computed directly, but y.s can be, and we -# approximate k by ignoring the (y+k).d term at first. Note that k can't be -# very large, since all offset-returning methods return a duration of magnitude -# less than 24 hours. For that reason, if y is firmly in std time, (y+k).d must -# be 0, so ignoring it has no consequence then. -# -# In any case, the new value is -# -# z = y + y.s [4] -# -# It's helpful to step back at look at [4] from a higher level: it's simply -# mapping from UTC to tz's standard time. -# -# At this point, if -# -# z.n - z.o = x.n [5] -# -# we have an equivalent time, and are almost done. The insecurity here is -# at the start of daylight time. Picture US Eastern for concreteness. The wall -# time jumps from 1:59 to 3:00, and wall hours of the form 2:MM don't make good -# sense then. The docs ask that an Eastern tzinfo class consider such a time to -# be EDT (because it's "after 2"), which is a redundant spelling of 1:MM EST -# on the day DST starts. We want to return the 1:MM EST spelling because that's -# the only spelling that makes sense on the local wall clock. -# -# In fact, if [5] holds at this point, we do have the standard-time spelling, -# but that takes a bit of proof. We first prove a stronger result. What's the -# difference between the LHS and RHS of [5]? Let -# -# diff = x.n - (z.n - z.o) [6] -# -# Now -# z.n = by [4] -# (y + y.s).n = by #5 -# y.n + y.s = since y.n = x.n -# x.n + y.s = since z and y are have the same tzinfo member, -# y.s = z.s by #2 -# x.n + z.s -# -# Plugging that back into [6] gives -# -# diff = -# x.n - ((x.n + z.s) - z.o) = expanding -# x.n - x.n - z.s + z.o = cancelling -# - z.s + z.o = by #2 -# z.d -# -# So diff = z.d. -# -# If [5] is true now, diff = 0, so z.d = 0 too, and we have the standard-time -# spelling we wanted in the endcase described above. We're done. Contrarily, -# if z.d = 0, then we have a UTC equivalent, and are also done. -# -# If [5] is not true now, diff = z.d != 0, and z.d is the offset we need to -# add to z (in effect, z is in tz's standard time, and we need to shift the -# local clock into tz's daylight time). -# -# Let -# -# z' = z + z.d = z + diff [7] -# -# and we can again ask whether -# -# z'.n - z'.o = x.n [8] -# -# If so, we're done. If not, the tzinfo class is insane, according to the -# assumptions we've made. This also requires a bit of proof. As before, let's -# compute the difference between the LHS and RHS of [8] (and skipping some of -# the justifications for the kinds of substitutions we've done several times -# already): -# -# diff' = x.n - (z'.n - z'.o) = replacing z'.n via [7] -# x.n - (z.n + diff - z'.o) = replacing diff via [6] -# x.n - (z.n + x.n - (z.n - z.o) - z'.o) = -# x.n - z.n - x.n + z.n - z.o + z'.o = cancel x.n -# - z.n + z.n - z.o + z'.o = cancel z.n -# - z.o + z'.o = #1 twice -# -z.s - z.d + z'.s + z'.d = z and z' have same tzinfo -# z'.d - z.d -# -# So z' is UTC-equivalent to x iff z'.d = z.d at this point. If they are equal, -# we've found the UTC-equivalent so are done. In fact, we stop with [7] and -# return z', not bothering to compute z'.d. -# -# How could z.d and z'd differ? z' = z + z.d [7], so merely moving z' by -# a dst() offset, and starting *from* a time already in DST (we know z.d != 0), -# would have to change the result dst() returns: we start in DST, and moving -# a little further into it takes us out of DST. -# -# There isn't a sane case where this can happen. The closest it gets is at -# the end of DST, where there's an hour in UTC with no spelling in a hybrid -# tzinfo class. In US Eastern, that's 5:MM UTC = 0:MM EST = 1:MM EDT. During -# that hour, on an Eastern clock 1:MM is taken as being in standard time (6:MM -# UTC) because the docs insist on that, but 0:MM is taken as being in daylight -# time (4:MM UTC). There is no local time mapping to 5:MM UTC. The local -# clock jumps from 1:59 back to 1:00 again, and repeats the 1:MM hour in -# standard time. Since that's what the local clock *does*, we want to map both -# UTC hours 5:MM and 6:MM to 1:MM Eastern. The result is ambiguous -# in local time, but so it goes -- it's the way the local clock works. -# -# When x = 5:MM UTC is the input to this algorithm, x.o=0, y.o=-5 and y.d=0, -# so z=0:MM. z.d=60 (minutes) then, so [5] doesn't hold and we keep going. -# z' = z + z.d = 1:MM then, and z'.d=0, and z'.d - z.d = -60 != 0 so [8] -# (correctly) concludes that z' is not UTC-equivalent to x. -# -# Because we know z.d said z was in daylight time (else [5] would have held and -# we would have stopped then), and we know z.d != z'.d (else [8] would have held -# and we have stopped then), and there are only 2 possible values dst() can -# return in Eastern, it follows that z'.d must be 0 (which it is in the example, -# but the reasoning doesn't depend on the example -- it depends on there being -# two possible dst() outcomes, one zero and the other non-zero). Therefore -# z' must be in standard time, and is the spelling we want in this case. -# -# Note again that z' is not UTC-equivalent as far as the hybrid tzinfo class is -# concerned (because it takes z' as being in standard time rather than the -# daylight time we intend here), but returning it gives the real-life "local -# clock repeats an hour" behavior when mapping the "unspellable" UTC hour into -# tz. -# -# When the input is 6:MM, z=1:MM and z.d=0, and we stop at once, again with -# the 1:MM standard time spelling we want. -# -# So how can this break? One of the assumptions must be violated. Two -# possibilities: -# -# 1) [2] effectively says that y.s is invariant across all y belong to a given -# time zone. This isn't true if, for political reasons or continental drift, -# a region decides to change its base offset from UTC. -# -# 2) There may be versions of "double daylight" time where the tail end of -# the analysis gives up a step too early. I haven't thought about that -# enough to say. -# -# In any case, it's clear that the default fromutc() is strong enough to handle -# "almost all" time zones: so long as the standard offset is invariant, it -# doesn't matter if daylight time transition points change from year to year, or -# if daylight time is skipped in some years; it doesn't matter how large or -# small dst() may get within its bounds; and it doesn't even matter if some -# perverse time zone returns a negative dst()). So a breaking case must be -# pretty bizarre, and a tzinfo subclass can override fromutc() if it is. - try: from _datetime import * -except ImportError: - pass -else: - # Clean up unused names - del (_DAYNAMES, _DAYS_BEFORE_MONTH, _DAYS_IN_MONTH, _DI100Y, _DI400Y, - _DI4Y, _EPOCH, _MAXORDINAL, _MONTHNAMES, _build_struct_time, - _check_date_fields, _check_time_fields, - _check_tzinfo_arg, _check_tzname, _check_utc_offset, _cmp, _cmperror, - _date_class, _days_before_month, _days_before_year, _days_in_month, - _format_time, _format_offset, _index, _is_leap, _isoweek1monday, _math, - _ord2ymd, _time, _time_class, _tzinfo_class, _wrap_strftime, _ymd2ord, - _divide_and_round, _parse_isoformat_date, _parse_isoformat_time, - _parse_hh_mm_ss_ff, _IsoCalendarDate, _isoweek_to_gregorian, - _find_isoformat_datetime_separator, _FRACTION_CORRECTION, - _is_ascii_digit) - # XXX Since import * above excludes names that start with _, - # docstring does not get overwritten. In the future, it may be - # appropriate to maintain a single module level docstring and - # remove the following line. from _datetime import __doc__ +except ImportError: + from _pydatetime import * + from _pydatetime import __doc__ + +__all__ = ("date", "datetime", "time", "timedelta", "timezone", "tzinfo", + "MINYEAR", "MAXYEAR", "UTC") diff --git a/Lib/dis.py b/Lib/dis.py index 5bf52c3e..3a8e6ac3 100644 --- a/Lib/dis.py +++ b/Lib/dis.py @@ -11,6 +11,8 @@ from opcode import ( _cache_format, _inline_cache_entries, _nb_ops, + _intrinsic_1_descs, + _intrinsic_2_descs, _specializations, _specialized_instructions, ) @@ -34,9 +36,16 @@ MAKE_FUNCTION = opmap['MAKE_FUNCTION'] MAKE_FUNCTION_FLAGS = ('defaults', 'kwdefaults', 'annotations', 'closure') LOAD_CONST = opmap['LOAD_CONST'] +RETURN_CONST = opmap['RETURN_CONST'] LOAD_GLOBAL = opmap['LOAD_GLOBAL'] BINARY_OP = opmap['BINARY_OP'] JUMP_BACKWARD = opmap['JUMP_BACKWARD'] +FOR_ITER = opmap['FOR_ITER'] +SEND = opmap['SEND'] +LOAD_ATTR = opmap['LOAD_ATTR'] +LOAD_SUPER_ATTR = opmap['LOAD_SUPER_ATTR'] +CALL_INTRINSIC_1 = opmap['CALL_INTRINSIC_1'] +CALL_INTRINSIC_2 = opmap['CALL_INTRINSIC_2'] CACHE = opmap["CACHE"] @@ -60,10 +69,10 @@ def _try_compile(source, name): expect code objects """ try: - c = compile(source, name, 'eval') + return compile(source, name, 'eval') except SyntaxError: - c = compile(source, name, 'exec') - return c + pass + return compile(source, name, 'exec') def dis(x=None, *, file=None, depth=None, show_caches=False, adaptive=False): """Disassemble classes, methods, functions, and other compiled objects. @@ -114,7 +123,10 @@ def distb(tb=None, *, file=None, show_caches=False, adaptive=False): """Disassemble a traceback (default: last traceback).""" if tb is None: try: - tb = sys.last_traceback + if hasattr(sys, 'last_exc'): + tb = sys.last_exc.__traceback__ + else: + tb = sys.last_traceback except AttributeError: raise RuntimeError("no last traceback to disassemble") from None while tb.tb_next: tb = tb.tb_next @@ -361,9 +373,8 @@ def _get_const_value(op, arg, co_consts): assert op in hasconst argval = UNKNOWN - if op == LOAD_CONST: - if co_consts is not None: - argval = co_consts[arg] + if co_consts is not None: + argval = co_consts[arg] return argval def _get_const_info(op, arg, co_consts): @@ -450,6 +461,7 @@ def _get_instructions_bytes(code, varname_from_oparg=None, argrepr = '' positions = Positions(*next(co_positions, ())) deop = _deoptop(op) + caches = _inline_cache_entries[deop] if arg is not None: # Set argval to the dereferenced value of the argument when # available, and argrepr to the string representation of argval. @@ -463,6 +475,14 @@ def _get_instructions_bytes(code, varname_from_oparg=None, argval, argrepr = _get_name_info(arg//2, get_name) if (arg & 1) and argrepr: argrepr = "NULL + " + argrepr + elif deop == LOAD_ATTR: + argval, argrepr = _get_name_info(arg//2, get_name) + if (arg & 1) and argrepr: + argrepr = "NULL|self + " + argrepr + elif deop == LOAD_SUPER_ATTR: + argval, argrepr = _get_name_info(arg//4, get_name) + if (arg & 1) and argrepr: + argrepr = "NULL|self + " + argrepr else: argval, argrepr = _get_name_info(arg, get_name) elif deop in hasjabs: @@ -471,11 +491,12 @@ def _get_instructions_bytes(code, varname_from_oparg=None, elif deop in hasjrel: signed_arg = -arg if _is_backward_jump(deop) else arg argval = offset + 2 + signed_arg*2 + argval += 2 * caches argrepr = "to " + repr(argval) elif deop in haslocal or deop in hasfree: argval, argrepr = _get_name_info(arg, varname_from_oparg) elif deop in hascompare: - argval = cmp_op[arg] + argval = cmp_op[arg>>4] argrepr = argval elif deop == FORMAT_VALUE: argval, argrepr = FORMAT_VALUE_CONVERTERS[arg & 0x3] @@ -489,6 +510,10 @@ def _get_instructions_bytes(code, varname_from_oparg=None, if arg & (1<<i)) elif deop == BINARY_OP: _, argrepr = _nb_ops[arg] + elif deop == CALL_INTRINSIC_1: + argrepr = _intrinsic_1_descs[arg] + elif deop == CALL_INTRINSIC_2: + argrepr = _intrinsic_2_descs[arg] yield Instruction(_all_opname[op], op, arg, argval, argrepr, offset, starts_line, is_jump_target, positions) @@ -504,9 +529,8 @@ def _get_instructions_bytes(code, varname_from_oparg=None, for i in range(size): offset += 2 # Only show the fancy argrepr for a CACHE instruction when it's - # the first entry for a particular cache value and the - # instruction using it is actually quickened: - if i == 0 and op != deop: + # the first entry for a particular cache value: + if i == 0: data = code[offset: offset + 2 * size] argrepr = f"{name}: {int.from_bytes(data, sys.byteorder)}" else: @@ -569,7 +593,12 @@ def _disassemble_bytes(code, lasti=-1, varname_from_oparg=None, instr.offset > 0) if new_source_line: print(file=file) - is_current_instr = instr.offset == lasti + if show_caches: + is_current_instr = instr.offset == lasti + else: + # Each CACHE takes 2 bytes + is_current_instr = instr.offset <= lasti \ + <= instr.offset + 2 * _inline_cache_entries[_deoptop(instr.opcode)] print(instr._disassemble(lineno_width, is_current_instr, offset_width), file=file) if exception_entries: @@ -602,7 +631,7 @@ def _unpack_opargs(code): op = code[i] deop = _deoptop(op) caches = _inline_cache_entries[deop] - if deop >= HAVE_ARGUMENT: + if deop in hasarg: arg = code[i+1] | extended_arg extended_arg = (arg << 8) if deop == EXTENDED_ARG else 0 # The oparg is stored as a signed integer @@ -624,11 +653,14 @@ def findlabels(code): labels = [] for offset, op, arg in _unpack_opargs(code): if arg is not None: - if op in hasjrel: - if _is_backward_jump(op): + deop = _deoptop(op) + caches = _inline_cache_entries[deop] + if deop in hasjrel: + if _is_backward_jump(deop): arg = -arg label = offset + 2 + arg*2 - elif op in hasjabs: + label += 2 * caches + elif deop in hasjabs: label = arg*2 else: continue @@ -656,7 +688,6 @@ def _find_imports(co): the corresponding args to __import__. """ IMPORT_NAME = opmap['IMPORT_NAME'] - LOAD_CONST = opmap['LOAD_CONST'] consts = co.co_consts names = co.co_names diff --git a/Lib/distutils/README b/Lib/distutils/README deleted file mode 100644 index 73bd2518..00000000 --- a/Lib/distutils/README +++ /dev/null @@ -1,11 +0,0 @@ -This directory contains the Distutils package. - -There's a full documentation available at: - - https://docs.python.org/distutils/ - -The Distutils-SIG web page is also a good starting point: - - https://www.python.org/sigs/distutils-sig/ - -$Id$ diff --git a/Lib/distutils/__init__.py b/Lib/distutils/__init__.py deleted file mode 100644 index fdad6f65..00000000 --- a/Lib/distutils/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -"""distutils - -The main package for the Python Module Distribution Utilities. Normally -used from a setup script as - - from distutils.core import setup - - setup (...) -""" - -import sys -import warnings - -__version__ = sys.version[:sys.version.index(' ')] - -_DEPRECATION_MESSAGE = ("The distutils package is deprecated and slated for " - "removal in Python 3.12. Use setuptools or check " - "PEP 632 for potential alternatives") -warnings.warn(_DEPRECATION_MESSAGE, - DeprecationWarning, 2) diff --git a/Lib/distutils/_msvccompiler.py b/Lib/distutils/_msvccompiler.py deleted file mode 100644 index af8099a4..00000000 --- a/Lib/distutils/_msvccompiler.py +++ /dev/null @@ -1,539 +0,0 @@ -"""distutils._msvccompiler - -Contains MSVCCompiler, an implementation of the abstract CCompiler class -for Microsoft Visual Studio 2015. - -The module is compatible with VS 2015 and later. You can find legacy support -for older versions in distutils.msvc9compiler and distutils.msvccompiler. -""" - -# Written by Perry Stoll -# hacked by Robin Becker and Thomas Heller to do a better job of -# finding DevStudio (through the registry) -# ported to VS 2005 and VS 2008 by Christian Heimes -# ported to VS 2015 by Steve Dower - -import os -import subprocess -import winreg - -from distutils.errors import DistutilsExecError, DistutilsPlatformError, \ - CompileError, LibError, LinkError -from distutils.ccompiler import CCompiler, gen_lib_options -from distutils import log -from distutils.util import get_platform - -from itertools import count - -def _find_vc2015(): - try: - key = winreg.OpenKeyEx( - winreg.HKEY_LOCAL_MACHINE, - r"Software\Microsoft\VisualStudio\SxS\VC7", - access=winreg.KEY_READ | winreg.KEY_WOW64_32KEY - ) - except OSError: - log.debug("Visual C++ is not registered") - return None, None - - best_version = 0 - best_dir = None - with key: - for i in count(): - try: - v, vc_dir, vt = winreg.EnumValue(key, i) - except OSError: - break - if v and vt == winreg.REG_SZ and os.path.isdir(vc_dir): - try: - version = int(float(v)) - except (ValueError, TypeError): - continue - if version >= 14 and version > best_version: - best_version, best_dir = version, vc_dir - return best_version, best_dir - -def _find_vc2017(): - """Returns "15, path" based on the result of invoking vswhere.exe - If no install is found, returns "None, None" - - The version is returned to avoid unnecessarily changing the function - result. It may be ignored when the path is not None. - - If vswhere.exe is not available, by definition, VS 2017 is not - installed. - """ - root = os.environ.get("ProgramFiles(x86)") or os.environ.get("ProgramFiles") - if not root: - return None, None - - try: - path = subprocess.check_output([ - os.path.join(root, "Microsoft Visual Studio", "Installer", "vswhere.exe"), - "-latest", - "-prerelease", - "-requires", "Microsoft.VisualStudio.Component.VC.Tools.x86.x64", - "-property", "installationPath", - "-products", "*", - ], encoding="mbcs", errors="strict").strip() - except (subprocess.CalledProcessError, OSError, UnicodeDecodeError): - return None, None - - path = os.path.join(path, "VC", "Auxiliary", "Build") - if os.path.isdir(path): - return 15, path - - return None, None - -PLAT_SPEC_TO_RUNTIME = { - 'x86' : 'x86', - 'x86_amd64' : 'x64', - 'x86_arm' : 'arm', - 'x86_arm64' : 'arm64' -} - -def _find_vcvarsall(plat_spec): - # bpo-38597: Removed vcruntime return value - _, best_dir = _find_vc2017() - - if not best_dir: - best_version, best_dir = _find_vc2015() - - if not best_dir: - log.debug("No suitable Visual C++ version found") - return None, None - - vcvarsall = os.path.join(best_dir, "vcvarsall.bat") - if not os.path.isfile(vcvarsall): - log.debug("%s cannot be found", vcvarsall) - return None, None - - return vcvarsall, None - -def _get_vc_env(plat_spec): - if os.getenv("DISTUTILS_USE_SDK"): - return { - key.lower(): value - for key, value in os.environ.items() - } - - vcvarsall, _ = _find_vcvarsall(plat_spec) - if not vcvarsall: - raise DistutilsPlatformError("Unable to find vcvarsall.bat") - - try: - out = subprocess.check_output( - 'cmd /u /c "{}" {} && set'.format(vcvarsall, plat_spec), - stderr=subprocess.STDOUT, - ).decode('utf-16le', errors='replace') - except subprocess.CalledProcessError as exc: - log.error(exc.output) - raise DistutilsPlatformError("Error executing {}" - .format(exc.cmd)) - - env = { - key.lower(): value - for key, _, value in - (line.partition('=') for line in out.splitlines()) - if key and value - } - - return env - -def _find_exe(exe, paths=None): - """Return path to an MSVC executable program. - - Tries to find the program in several places: first, one of the - MSVC program search paths from the registry; next, the directories - in the PATH environment variable. If any of those work, return an - absolute path that is known to exist. If none of them work, just - return the original program name, 'exe'. - """ - if not paths: - paths = os.getenv('path').split(os.pathsep) - for p in paths: - fn = os.path.join(os.path.abspath(p), exe) - if os.path.isfile(fn): - return fn - return exe - -# A map keyed by get_platform() return values to values accepted by -# 'vcvarsall.bat'. Always cross-compile from x86 to work with the -# lighter-weight MSVC installs that do not include native 64-bit tools. -PLAT_TO_VCVARS = { - 'win32' : 'x86', - 'win-amd64' : 'x86_amd64', - 'win-arm32' : 'x86_arm', - 'win-arm64' : 'x86_arm64' -} - -class MSVCCompiler(CCompiler) : - """Concrete class that implements an interface to Microsoft Visual C++, - as defined by the CCompiler abstract class.""" - - compiler_type = 'msvc' - - # Just set this so CCompiler's constructor doesn't barf. We currently - # don't use the 'set_executables()' bureaucracy provided by CCompiler, - # as it really isn't necessary for this sort of single-compiler class. - # Would be nice to have a consistent interface with UnixCCompiler, - # though, so it's worth thinking about. - executables = {} - - # Private class data (need to distinguish C from C++ source for compiler) - _c_extensions = ['.c'] - _cpp_extensions = ['.cc', '.cpp', '.cxx'] - _rc_extensions = ['.rc'] - _mc_extensions = ['.mc'] - - # Needed for the filename generation methods provided by the - # base class, CCompiler. - src_extensions = (_c_extensions + _cpp_extensions + - _rc_extensions + _mc_extensions) - res_extension = '.res' - obj_extension = '.obj' - static_lib_extension = '.lib' - shared_lib_extension = '.dll' - static_lib_format = shared_lib_format = '%s%s' - exe_extension = '.exe' - - - def __init__(self, verbose=0, dry_run=0, force=0): - CCompiler.__init__ (self, verbose, dry_run, force) - # target platform (.plat_name is consistent with 'bdist') - self.plat_name = None - self.initialized = False - - def initialize(self, plat_name=None): - # multi-init means we would need to check platform same each time... - assert not self.initialized, "don't init multiple times" - if plat_name is None: - plat_name = get_platform() - # sanity check for platforms to prevent obscure errors later. - if plat_name not in PLAT_TO_VCVARS: - raise DistutilsPlatformError("--plat-name must be one of {}" - .format(tuple(PLAT_TO_VCVARS))) - - # Get the vcvarsall.bat spec for the requested platform. - plat_spec = PLAT_TO_VCVARS[plat_name] - - vc_env = _get_vc_env(plat_spec) - if not vc_env: - raise DistutilsPlatformError("Unable to find a compatible " - "Visual Studio installation.") - - self._paths = vc_env.get('path', '') - paths = self._paths.split(os.pathsep) - self.cc = _find_exe("cl.exe", paths) - self.linker = _find_exe("link.exe", paths) - self.lib = _find_exe("lib.exe", paths) - self.rc = _find_exe("rc.exe", paths) # resource compiler - self.mc = _find_exe("mc.exe", paths) # message compiler - self.mt = _find_exe("mt.exe", paths) # message compiler - - for dir in vc_env.get('include', '').split(os.pathsep): - if dir: - self.add_include_dir(dir.rstrip(os.sep)) - - for dir in vc_env.get('lib', '').split(os.pathsep): - if dir: - self.add_library_dir(dir.rstrip(os.sep)) - - self.preprocess_options = None - # bpo-38597: Always compile with dynamic linking - # Future releases of Python 3.x will include all past - # versions of vcruntime*.dll for compatibility. - self.compile_options = [ - '/nologo', '/Ox', '/W3', '/GL', '/DNDEBUG', '/MD' - ] - - self.compile_options_debug = [ - '/nologo', '/Od', '/MDd', '/Zi', '/W3', '/D_DEBUG' - ] - - ldflags = [ - '/nologo', '/INCREMENTAL:NO', '/LTCG' - ] - - ldflags_debug = [ - '/nologo', '/INCREMENTAL:NO', '/LTCG', '/DEBUG:FULL' - ] - - self.ldflags_exe = [*ldflags, '/MANIFEST:EMBED,ID=1'] - self.ldflags_exe_debug = [*ldflags_debug, '/MANIFEST:EMBED,ID=1'] - self.ldflags_shared = [*ldflags, '/DLL', '/MANIFEST:EMBED,ID=2', '/MANIFESTUAC:NO'] - self.ldflags_shared_debug = [*ldflags_debug, '/DLL', '/MANIFEST:EMBED,ID=2', '/MANIFESTUAC:NO'] - self.ldflags_static = [*ldflags] - self.ldflags_static_debug = [*ldflags_debug] - - self._ldflags = { - (CCompiler.EXECUTABLE, None): self.ldflags_exe, - (CCompiler.EXECUTABLE, False): self.ldflags_exe, - (CCompiler.EXECUTABLE, True): self.ldflags_exe_debug, - (CCompiler.SHARED_OBJECT, None): self.ldflags_shared, - (CCompiler.SHARED_OBJECT, False): self.ldflags_shared, - (CCompiler.SHARED_OBJECT, True): self.ldflags_shared_debug, - (CCompiler.SHARED_LIBRARY, None): self.ldflags_static, - (CCompiler.SHARED_LIBRARY, False): self.ldflags_static, - (CCompiler.SHARED_LIBRARY, True): self.ldflags_static_debug, - } - - self.initialized = True - - # -- Worker methods ------------------------------------------------ - - def object_filenames(self, - source_filenames, - strip_dir=0, - output_dir=''): - ext_map = { - **{ext: self.obj_extension for ext in self.src_extensions}, - **{ext: self.res_extension for ext in self._rc_extensions + self._mc_extensions}, - } - - output_dir = output_dir or '' - - def make_out_path(p): - base, ext = os.path.splitext(p) - if strip_dir: - base = os.path.basename(base) - else: - _, base = os.path.splitdrive(base) - if base.startswith((os.path.sep, os.path.altsep)): - base = base[1:] - try: - # XXX: This may produce absurdly long paths. We should check - # the length of the result and trim base until we fit within - # 260 characters. - return os.path.join(output_dir, base + ext_map[ext]) - except LookupError: - # Better to raise an exception instead of silently continuing - # and later complain about sources and targets having - # different lengths - raise CompileError("Don't know how to compile {}".format(p)) - - return list(map(make_out_path, source_filenames)) - - - def compile(self, sources, - output_dir=None, macros=None, include_dirs=None, debug=0, - extra_preargs=None, extra_postargs=None, depends=None): - - if not self.initialized: - self.initialize() - compile_info = self._setup_compile(output_dir, macros, include_dirs, - sources, depends, extra_postargs) - macros, objects, extra_postargs, pp_opts, build = compile_info - - compile_opts = extra_preargs or [] - compile_opts.append('/c') - if debug: - compile_opts.extend(self.compile_options_debug) - else: - compile_opts.extend(self.compile_options) - - - add_cpp_opts = False - - for obj in objects: - try: - src, ext = build[obj] - except KeyError: - continue - if debug: - # pass the full pathname to MSVC in debug mode, - # this allows the debugger to find the source file - # without asking the user to browse for it - src = os.path.abspath(src) - - if ext in self._c_extensions: - input_opt = "/Tc" + src - elif ext in self._cpp_extensions: - input_opt = "/Tp" + src - add_cpp_opts = True - elif ext in self._rc_extensions: - # compile .RC to .RES file - input_opt = src - output_opt = "/fo" + obj - try: - self.spawn([self.rc] + pp_opts + [output_opt, input_opt]) - except DistutilsExecError as msg: - raise CompileError(msg) - continue - elif ext in self._mc_extensions: - # Compile .MC to .RC file to .RES file. - # * '-h dir' specifies the directory for the - # generated include file - # * '-r dir' specifies the target directory of the - # generated RC file and the binary message resource - # it includes - # - # For now (since there are no options to change this), - # we use the source-directory for the include file and - # the build directory for the RC file and message - # resources. This works at least for win32all. - h_dir = os.path.dirname(src) - rc_dir = os.path.dirname(obj) - try: - # first compile .MC to .RC and .H file - self.spawn([self.mc, '-h', h_dir, '-r', rc_dir, src]) - base, _ = os.path.splitext(os.path.basename (src)) - rc_file = os.path.join(rc_dir, base + '.rc') - # then compile .RC to .RES file - self.spawn([self.rc, "/fo" + obj, rc_file]) - - except DistutilsExecError as msg: - raise CompileError(msg) - continue - else: - # how to handle this file? - raise CompileError("Don't know how to compile {} to {}" - .format(src, obj)) - - args = [self.cc] + compile_opts + pp_opts - if add_cpp_opts: - args.append('/EHsc') - args.append(input_opt) - args.append("/Fo" + obj) - args.extend(extra_postargs) - - try: - self.spawn(args) - except DistutilsExecError as msg: - raise CompileError(msg) - - return objects - - - def create_static_lib(self, - objects, - output_libname, - output_dir=None, - debug=0, - target_lang=None): - - if not self.initialized: - self.initialize() - objects, output_dir = self._fix_object_args(objects, output_dir) - output_filename = self.library_filename(output_libname, - output_dir=output_dir) - - if self._need_link(objects, output_filename): - lib_args = objects + ['/OUT:' + output_filename] - if debug: - pass # XXX what goes here? - try: - log.debug('Executing "%s" %s', self.lib, ' '.join(lib_args)) - self.spawn([self.lib] + lib_args) - except DistutilsExecError as msg: - raise LibError(msg) - else: - log.debug("skipping %s (up-to-date)", output_filename) - - - def link(self, - target_desc, - objects, - output_filename, - output_dir=None, - libraries=None, - library_dirs=None, - runtime_library_dirs=None, - export_symbols=None, - debug=0, - extra_preargs=None, - extra_postargs=None, - build_temp=None, - target_lang=None): - - if not self.initialized: - self.initialize() - objects, output_dir = self._fix_object_args(objects, output_dir) - fixed_args = self._fix_lib_args(libraries, library_dirs, - runtime_library_dirs) - libraries, library_dirs, runtime_library_dirs = fixed_args - - if runtime_library_dirs: - self.warn("I don't know what to do with 'runtime_library_dirs': " - + str(runtime_library_dirs)) - - lib_opts = gen_lib_options(self, - library_dirs, runtime_library_dirs, - libraries) - if output_dir is not None: - output_filename = os.path.join(output_dir, output_filename) - - if self._need_link(objects, output_filename): - ldflags = self._ldflags[target_desc, debug] - - export_opts = ["/EXPORT:" + sym for sym in (export_symbols or [])] - - ld_args = (ldflags + lib_opts + export_opts + - objects + ['/OUT:' + output_filename]) - - # The MSVC linker generates .lib and .exp files, which cannot be - # suppressed by any linker switches. The .lib files may even be - # needed! Make sure they are generated in the temporary build - # directory. Since they have different names for debug and release - # builds, they can go into the same directory. - build_temp = os.path.dirname(objects[0]) - if export_symbols is not None: - (dll_name, dll_ext) = os.path.splitext( - os.path.basename(output_filename)) - implib_file = os.path.join( - build_temp, - self.library_filename(dll_name)) - ld_args.append ('/IMPLIB:' + implib_file) - - if extra_preargs: - ld_args[:0] = extra_preargs - if extra_postargs: - ld_args.extend(extra_postargs) - - output_dir = os.path.dirname(os.path.abspath(output_filename)) - self.mkpath(output_dir) - try: - log.debug('Executing "%s" %s', self.linker, ' '.join(ld_args)) - self.spawn([self.linker] + ld_args) - except DistutilsExecError as msg: - raise LinkError(msg) - else: - log.debug("skipping %s (up-to-date)", output_filename) - - def spawn(self, cmd): - old_path = os.getenv('path') - try: - os.environ['path'] = self._paths - return super().spawn(cmd) - finally: - os.environ['path'] = old_path - - # -- Miscellaneous methods ----------------------------------------- - # These are all used by the 'gen_lib_options() function, in - # ccompiler.py. - - def library_dir_option(self, dir): - return "/LIBPATH:" + dir - - def runtime_library_dir_option(self, dir): - raise DistutilsPlatformError( - "don't know how to set runtime library search path for MSVC") - - def library_option(self, lib): - return self.library_filename(lib) - - def find_library_file(self, dirs, lib, debug=0): - # Prefer a debugging library if found (and requested), but deal - # with it if we don't have one. - if debug: - try_names = [lib + "_d", lib] - else: - try_names = [lib] - for dir in dirs: - for name in try_names: - libfile = os.path.join(dir, self.library_filename(name)) - if os.path.isfile(libfile): - return libfile - else: - # Oops, didn't find it in *any* of 'dirs' - return None diff --git a/Lib/distutils/archive_util.py b/Lib/distutils/archive_util.py deleted file mode 100644 index 565a3117..00000000 --- a/Lib/distutils/archive_util.py +++ /dev/null @@ -1,256 +0,0 @@ -"""distutils.archive_util - -Utility functions for creating archive files (tarballs, zip files, -that sort of thing).""" - -import os -from warnings import warn -import sys - -try: - import zipfile -except ImportError: - zipfile = None - - -from distutils.errors import DistutilsExecError -from distutils.spawn import spawn -from distutils.dir_util import mkpath -from distutils import log - -try: - from pwd import getpwnam -except ImportError: - getpwnam = None - -try: - from grp import getgrnam -except ImportError: - getgrnam = None - -def _get_gid(name): - """Returns a gid, given a group name.""" - if getgrnam is None or name is None: - return None - try: - result = getgrnam(name) - except KeyError: - result = None - if result is not None: - return result[2] - return None - -def _get_uid(name): - """Returns an uid, given a user name.""" - if getpwnam is None or name is None: - return None - try: - result = getpwnam(name) - except KeyError: - result = None - if result is not None: - return result[2] - return None - -def make_tarball(base_name, base_dir, compress="gzip", verbose=0, dry_run=0, - owner=None, group=None): - """Create a (possibly compressed) tar file from all the files under - 'base_dir'. - - 'compress' must be "gzip" (the default), "bzip2", "xz", "compress", or - None. ("compress" will be deprecated in Python 3.2) - - 'owner' and 'group' can be used to define an owner and a group for the - archive that is being built. If not provided, the current owner and group - will be used. - - The output tar file will be named 'base_dir' + ".tar", possibly plus - the appropriate compression extension (".gz", ".bz2", ".xz" or ".Z"). - - Returns the output filename. - """ - tar_compression = {'gzip': 'gz', 'bzip2': 'bz2', 'xz': 'xz', None: '', - 'compress': ''} - compress_ext = {'gzip': '.gz', 'bzip2': '.bz2', 'xz': '.xz', - 'compress': '.Z'} - - # flags for compression program, each element of list will be an argument - if compress is not None and compress not in compress_ext.keys(): - raise ValueError( - "bad value for 'compress': must be None, 'gzip', 'bzip2', " - "'xz' or 'compress'") - - archive_name = base_name + '.tar' - if compress != 'compress': - archive_name += compress_ext.get(compress, '') - - mkpath(os.path.dirname(archive_name), dry_run=dry_run) - - # creating the tarball - import tarfile # late import so Python build itself doesn't break - - log.info('Creating tar archive') - - uid = _get_uid(owner) - gid = _get_gid(group) - - def _set_uid_gid(tarinfo): - if gid is not None: - tarinfo.gid = gid - tarinfo.gname = group - if uid is not None: - tarinfo.uid = uid - tarinfo.uname = owner - return tarinfo - - if not dry_run: - tar = tarfile.open(archive_name, 'w|%s' % tar_compression[compress]) - try: - tar.add(base_dir, filter=_set_uid_gid) - finally: - tar.close() - - # compression using `compress` - if compress == 'compress': - warn("'compress' will be deprecated.", PendingDeprecationWarning) - # the option varies depending on the platform - compressed_name = archive_name + compress_ext[compress] - if sys.platform == 'win32': - cmd = [compress, archive_name, compressed_name] - else: - cmd = [compress, '-f', archive_name] - spawn(cmd, dry_run=dry_run) - return compressed_name - - return archive_name - -def make_zipfile(base_name, base_dir, verbose=0, dry_run=0): - """Create a zip file from all the files under 'base_dir'. - - The output zip file will be named 'base_name' + ".zip". Uses either the - "zipfile" Python module (if available) or the InfoZIP "zip" utility - (if installed and found on the default search path). If neither tool is - available, raises DistutilsExecError. Returns the name of the output zip - file. - """ - zip_filename = base_name + ".zip" - mkpath(os.path.dirname(zip_filename), dry_run=dry_run) - - # If zipfile module is not available, try spawning an external - # 'zip' command. - if zipfile is None: - if verbose: - zipoptions = "-r" - else: - zipoptions = "-rq" - - try: - spawn(["zip", zipoptions, zip_filename, base_dir], - dry_run=dry_run) - except DistutilsExecError: - # XXX really should distinguish between "couldn't find - # external 'zip' command" and "zip failed". - raise DistutilsExecError(("unable to create zip file '%s': " - "could neither import the 'zipfile' module nor " - "find a standalone zip utility") % zip_filename) - - else: - log.info("creating '%s' and adding '%s' to it", - zip_filename, base_dir) - - if not dry_run: - try: - zip = zipfile.ZipFile(zip_filename, "w", - compression=zipfile.ZIP_DEFLATED) - except RuntimeError: - zip = zipfile.ZipFile(zip_filename, "w", - compression=zipfile.ZIP_STORED) - - with zip: - if base_dir != os.curdir: - path = os.path.normpath(os.path.join(base_dir, '')) - zip.write(path, path) - log.info("adding '%s'", path) - for dirpath, dirnames, filenames in os.walk(base_dir): - for name in dirnames: - path = os.path.normpath(os.path.join(dirpath, name, '')) - zip.write(path, path) - log.info("adding '%s'", path) - for name in filenames: - path = os.path.normpath(os.path.join(dirpath, name)) - if os.path.isfile(path): - zip.write(path, path) - log.info("adding '%s'", path) - - return zip_filename - -ARCHIVE_FORMATS = { - 'gztar': (make_tarball, [('compress', 'gzip')], "gzip'ed tar-file"), - 'bztar': (make_tarball, [('compress', 'bzip2')], "bzip2'ed tar-file"), - 'xztar': (make_tarball, [('compress', 'xz')], "xz'ed tar-file"), - 'ztar': (make_tarball, [('compress', 'compress')], "compressed tar file"), - 'tar': (make_tarball, [('compress', None)], "uncompressed tar file"), - 'zip': (make_zipfile, [],"ZIP file") - } - -def check_archive_formats(formats): - """Returns the first format from the 'format' list that is unknown. - - If all formats are known, returns None - """ - for format in formats: - if format not in ARCHIVE_FORMATS: - return format - return None - -def make_archive(base_name, format, root_dir=None, base_dir=None, verbose=0, - dry_run=0, owner=None, group=None): - """Create an archive file (eg. zip or tar). - - 'base_name' is the name of the file to create, minus any format-specific - extension; 'format' is the archive format: one of "zip", "tar", "gztar", - "bztar", "xztar", or "ztar". - - 'root_dir' is a directory that will be the root directory of the - archive; ie. we typically chdir into 'root_dir' before creating the - archive. 'base_dir' is the directory where we start archiving from; - ie. 'base_dir' will be the common prefix of all files and - directories in the archive. 'root_dir' and 'base_dir' both default - to the current directory. Returns the name of the archive file. - - 'owner' and 'group' are used when creating a tar archive. By default, - uses the current owner and group. - """ - save_cwd = os.getcwd() - if root_dir is not None: - log.debug("changing into '%s'", root_dir) - base_name = os.path.abspath(base_name) - if not dry_run: - os.chdir(root_dir) - - if base_dir is None: - base_dir = os.curdir - - kwargs = {'dry_run': dry_run} - - try: - format_info = ARCHIVE_FORMATS[format] - except KeyError: - raise ValueError("unknown archive format '%s'" % format) - - func = format_info[0] - for arg, val in format_info[1]: - kwargs[arg] = val - - if format != 'zip': - kwargs['owner'] = owner - kwargs['group'] = group - - try: - filename = func(base_name, base_dir, **kwargs) - finally: - if root_dir is not None: - log.debug("changing back to '%s'", save_cwd) - os.chdir(save_cwd) - - return filename diff --git a/Lib/distutils/bcppcompiler.py b/Lib/distutils/bcppcompiler.py deleted file mode 100644 index 071fea5d..00000000 --- a/Lib/distutils/bcppcompiler.py +++ /dev/null @@ -1,393 +0,0 @@ -"""distutils.bcppcompiler - -Contains BorlandCCompiler, an implementation of the abstract CCompiler class -for the Borland C++ compiler. -""" - -# This implementation by Lyle Johnson, based on the original msvccompiler.py -# module and using the directions originally published by Gordon Williams. - -# XXX looks like there's a LOT of overlap between these two classes: -# someone should sit down and factor out the common code as -# WindowsCCompiler! --GPW - - -import os -from distutils.errors import \ - DistutilsExecError, \ - CompileError, LibError, LinkError, UnknownFileError -from distutils.ccompiler import \ - CCompiler, gen_preprocess_options -from distutils.file_util import write_file -from distutils.dep_util import newer -from distutils import log - -class BCPPCompiler(CCompiler) : - """Concrete class that implements an interface to the Borland C/C++ - compiler, as defined by the CCompiler abstract class. - """ - - compiler_type = 'bcpp' - - # Just set this so CCompiler's constructor doesn't barf. We currently - # don't use the 'set_executables()' bureaucracy provided by CCompiler, - # as it really isn't necessary for this sort of single-compiler class. - # Would be nice to have a consistent interface with UnixCCompiler, - # though, so it's worth thinking about. - executables = {} - - # Private class data (need to distinguish C from C++ source for compiler) - _c_extensions = ['.c'] - _cpp_extensions = ['.cc', '.cpp', '.cxx'] - - # Needed for the filename generation methods provided by the - # base class, CCompiler. - src_extensions = _c_extensions + _cpp_extensions - obj_extension = '.obj' - static_lib_extension = '.lib' - shared_lib_extension = '.dll' - static_lib_format = shared_lib_format = '%s%s' - exe_extension = '.exe' - - - def __init__ (self, - verbose=0, - dry_run=0, - force=0): - - CCompiler.__init__ (self, verbose, dry_run, force) - - # These executables are assumed to all be in the path. - # Borland doesn't seem to use any special registry settings to - # indicate their installation locations. - - self.cc = "bcc32.exe" - self.linker = "ilink32.exe" - self.lib = "tlib.exe" - - self.preprocess_options = None - self.compile_options = ['/tWM', '/O2', '/q', '/g0'] - self.compile_options_debug = ['/tWM', '/Od', '/q', '/g0'] - - self.ldflags_shared = ['/Tpd', '/Gn', '/q', '/x'] - self.ldflags_shared_debug = ['/Tpd', '/Gn', '/q', '/x'] - self.ldflags_static = [] - self.ldflags_exe = ['/Gn', '/q', '/x'] - self.ldflags_exe_debug = ['/Gn', '/q', '/x','/r'] - - - # -- Worker methods ------------------------------------------------ - - def compile(self, sources, - output_dir=None, macros=None, include_dirs=None, debug=0, - extra_preargs=None, extra_postargs=None, depends=None): - - macros, objects, extra_postargs, pp_opts, build = \ - self._setup_compile(output_dir, macros, include_dirs, sources, - depends, extra_postargs) - compile_opts = extra_preargs or [] - compile_opts.append ('-c') - if debug: - compile_opts.extend (self.compile_options_debug) - else: - compile_opts.extend (self.compile_options) - - for obj in objects: - try: - src, ext = build[obj] - except KeyError: - continue - # XXX why do the normpath here? - src = os.path.normpath(src) - obj = os.path.normpath(obj) - # XXX _setup_compile() did a mkpath() too but before the normpath. - # Is it possible to skip the normpath? - self.mkpath(os.path.dirname(obj)) - - if ext == '.res': - # This is already a binary file -- skip it. - continue # the 'for' loop - if ext == '.rc': - # This needs to be compiled to a .res file -- do it now. - try: - self.spawn (["brcc32", "-fo", obj, src]) - except DistutilsExecError as msg: - raise CompileError(msg) - continue # the 'for' loop - - # The next two are both for the real compiler. - if ext in self._c_extensions: - input_opt = "" - elif ext in self._cpp_extensions: - input_opt = "-P" - else: - # Unknown file type -- no extra options. The compiler - # will probably fail, but let it just in case this is a - # file the compiler recognizes even if we don't. - input_opt = "" - - output_opt = "-o" + obj - - # Compiler command line syntax is: "bcc32 [options] file(s)". - # Note that the source file names must appear at the end of - # the command line. - try: - self.spawn ([self.cc] + compile_opts + pp_opts + - [input_opt, output_opt] + - extra_postargs + [src]) - except DistutilsExecError as msg: - raise CompileError(msg) - - return objects - - # compile () - - - def create_static_lib (self, - objects, - output_libname, - output_dir=None, - debug=0, - target_lang=None): - - (objects, output_dir) = self._fix_object_args (objects, output_dir) - output_filename = \ - self.library_filename (output_libname, output_dir=output_dir) - - if self._need_link (objects, output_filename): - lib_args = [output_filename, '/u'] + objects - if debug: - pass # XXX what goes here? - try: - self.spawn ([self.lib] + lib_args) - except DistutilsExecError as msg: - raise LibError(msg) - else: - log.debug("skipping %s (up-to-date)", output_filename) - - # create_static_lib () - - - def link (self, - target_desc, - objects, - output_filename, - output_dir=None, - libraries=None, - library_dirs=None, - runtime_library_dirs=None, - export_symbols=None, - debug=0, - extra_preargs=None, - extra_postargs=None, - build_temp=None, - target_lang=None): - - # XXX this ignores 'build_temp'! should follow the lead of - # msvccompiler.py - - (objects, output_dir) = self._fix_object_args (objects, output_dir) - (libraries, library_dirs, runtime_library_dirs) = \ - self._fix_lib_args (libraries, library_dirs, runtime_library_dirs) - - if runtime_library_dirs: - log.warn("I don't know what to do with 'runtime_library_dirs': %s", - str(runtime_library_dirs)) - - if output_dir is not None: - output_filename = os.path.join (output_dir, output_filename) - - if self._need_link (objects, output_filename): - - # Figure out linker args based on type of target. - if target_desc == CCompiler.EXECUTABLE: - startup_obj = 'c0w32' - if debug: - ld_args = self.ldflags_exe_debug[:] - else: - ld_args = self.ldflags_exe[:] - else: - startup_obj = 'c0d32' - if debug: - ld_args = self.ldflags_shared_debug[:] - else: - ld_args = self.ldflags_shared[:] - - - # Create a temporary exports file for use by the linker - if export_symbols is None: - def_file = '' - else: - head, tail = os.path.split (output_filename) - modname, ext = os.path.splitext (tail) - temp_dir = os.path.dirname(objects[0]) # preserve tree structure - def_file = os.path.join (temp_dir, '%s.def' % modname) - contents = ['EXPORTS'] - for sym in (export_symbols or []): - contents.append(' %s=_%s' % (sym, sym)) - self.execute(write_file, (def_file, contents), - "writing %s" % def_file) - - # Borland C++ has problems with '/' in paths - objects2 = map(os.path.normpath, objects) - # split objects in .obj and .res files - # Borland C++ needs them at different positions in the command line - objects = [startup_obj] - resources = [] - for file in objects2: - (base, ext) = os.path.splitext(os.path.normcase(file)) - if ext == '.res': - resources.append(file) - else: - objects.append(file) - - - for l in library_dirs: - ld_args.append("/L%s" % os.path.normpath(l)) - ld_args.append("/L.") # we sometimes use relative paths - - # list of object files - ld_args.extend(objects) - - # XXX the command-line syntax for Borland C++ is a bit wonky; - # certain filenames are jammed together in one big string, but - # comma-delimited. This doesn't mesh too well with the - # Unix-centric attitude (with a DOS/Windows quoting hack) of - # 'spawn()', so constructing the argument list is a bit - # awkward. Note that doing the obvious thing and jamming all - # the filenames and commas into one argument would be wrong, - # because 'spawn()' would quote any filenames with spaces in - # them. Arghghh!. Apparently it works fine as coded... - - # name of dll/exe file - ld_args.extend([',',output_filename]) - # no map file and start libraries - ld_args.append(',,') - - for lib in libraries: - # see if we find it and if there is a bcpp specific lib - # (xxx_bcpp.lib) - libfile = self.find_library_file(library_dirs, lib, debug) - if libfile is None: - ld_args.append(lib) - # probably a BCPP internal library -- don't warn - else: - # full name which prefers bcpp_xxx.lib over xxx.lib - ld_args.append(libfile) - - # some default libraries - ld_args.append ('import32') - ld_args.append ('cw32mt') - - # def file for export symbols - ld_args.extend([',',def_file]) - # add resource files - ld_args.append(',') - ld_args.extend(resources) - - - if extra_preargs: - ld_args[:0] = extra_preargs - if extra_postargs: - ld_args.extend(extra_postargs) - - self.mkpath (os.path.dirname (output_filename)) - try: - self.spawn ([self.linker] + ld_args) - except DistutilsExecError as msg: - raise LinkError(msg) - - else: - log.debug("skipping %s (up-to-date)", output_filename) - - # link () - - # -- Miscellaneous methods ----------------------------------------- - - - def find_library_file (self, dirs, lib, debug=0): - # List of effective library names to try, in order of preference: - # xxx_bcpp.lib is better than xxx.lib - # and xxx_d.lib is better than xxx.lib if debug is set - # - # The "_bcpp" suffix is to handle a Python installation for people - # with multiple compilers (primarily Distutils hackers, I suspect - # ;-). The idea is they'd have one static library for each - # compiler they care about, since (almost?) every Windows compiler - # seems to have a different format for static libraries. - if debug: - dlib = (lib + "_d") - try_names = (dlib + "_bcpp", lib + "_bcpp", dlib, lib) - else: - try_names = (lib + "_bcpp", lib) - - for dir in dirs: - for name in try_names: - libfile = os.path.join(dir, self.library_filename(name)) - if os.path.exists(libfile): - return libfile - else: - # Oops, didn't find it in *any* of 'dirs' - return None - - # overwrite the one from CCompiler to support rc and res-files - def object_filenames (self, - source_filenames, - strip_dir=0, - output_dir=''): - if output_dir is None: output_dir = '' - obj_names = [] - for src_name in source_filenames: - # use normcase to make sure '.rc' is really '.rc' and not '.RC' - (base, ext) = os.path.splitext (os.path.normcase(src_name)) - if ext not in (self.src_extensions + ['.rc','.res']): - raise UnknownFileError("unknown file type '%s' (from '%s')" % \ - (ext, src_name)) - if strip_dir: - base = os.path.basename (base) - if ext == '.res': - # these can go unchanged - obj_names.append (os.path.join (output_dir, base + ext)) - elif ext == '.rc': - # these need to be compiled to .res-files - obj_names.append (os.path.join (output_dir, base + '.res')) - else: - obj_names.append (os.path.join (output_dir, - base + self.obj_extension)) - return obj_names - - # object_filenames () - - def preprocess (self, - source, - output_file=None, - macros=None, - include_dirs=None, - extra_preargs=None, - extra_postargs=None): - - (_, macros, include_dirs) = \ - self._fix_compile_args(None, macros, include_dirs) - pp_opts = gen_preprocess_options(macros, include_dirs) - pp_args = ['cpp32.exe'] + pp_opts - if output_file is not None: - pp_args.append('-o' + output_file) - if extra_preargs: - pp_args[:0] = extra_preargs - if extra_postargs: - pp_args.extend(extra_postargs) - pp_args.append(source) - - # We need to preprocess: either we're being forced to, or the - # source file is newer than the target (or the target doesn't - # exist). - if self.force or output_file is None or newer(source, output_file): - if output_file: - self.mkpath(os.path.dirname(output_file)) - try: - self.spawn(pp_args) - except DistutilsExecError as msg: - print(msg) - raise CompileError(msg) - - # preprocess() diff --git a/Lib/distutils/ccompiler.py b/Lib/distutils/ccompiler.py deleted file mode 100644 index 4c47f2ed..00000000 --- a/Lib/distutils/ccompiler.py +++ /dev/null @@ -1,1116 +0,0 @@ -"""distutils.ccompiler - -Contains CCompiler, an abstract base class that defines the interface -for the Distutils compiler abstraction model.""" - -import sys, os, re -from distutils.errors import * -from distutils.spawn import spawn -from distutils.file_util import move_file -from distutils.dir_util import mkpath -from distutils.dep_util import newer_group -from distutils.util import split_quoted, execute -from distutils import log - -class CCompiler: - """Abstract base class to define the interface that must be implemented - by real compiler classes. Also has some utility methods used by - several compiler classes. - - The basic idea behind a compiler abstraction class is that each - instance can be used for all the compile/link steps in building a - single project. Thus, attributes common to all of those compile and - link steps -- include directories, macros to define, libraries to link - against, etc. -- are attributes of the compiler instance. To allow for - variability in how individual files are treated, most of those - attributes may be varied on a per-compilation or per-link basis. - """ - - # 'compiler_type' is a class attribute that identifies this class. It - # keeps code that wants to know what kind of compiler it's dealing with - # from having to import all possible compiler classes just to do an - # 'isinstance'. In concrete CCompiler subclasses, 'compiler_type' - # should really, really be one of the keys of the 'compiler_class' - # dictionary (see below -- used by the 'new_compiler()' factory - # function) -- authors of new compiler interface classes are - # responsible for updating 'compiler_class'! - compiler_type = None - - # XXX things not handled by this compiler abstraction model: - # * client can't provide additional options for a compiler, - # e.g. warning, optimization, debugging flags. Perhaps this - # should be the domain of concrete compiler abstraction classes - # (UnixCCompiler, MSVCCompiler, etc.) -- or perhaps the base - # class should have methods for the common ones. - # * can't completely override the include or library searchg - # path, ie. no "cc -I -Idir1 -Idir2" or "cc -L -Ldir1 -Ldir2". - # I'm not sure how widely supported this is even by Unix - # compilers, much less on other platforms. And I'm even less - # sure how useful it is; maybe for cross-compiling, but - # support for that is a ways off. (And anyways, cross - # compilers probably have a dedicated binary with the - # right paths compiled in. I hope.) - # * can't do really freaky things with the library list/library - # dirs, e.g. "-Ldir1 -lfoo -Ldir2 -lfoo" to link against - # different versions of libfoo.a in different locations. I - # think this is useless without the ability to null out the - # library search path anyways. - - - # Subclasses that rely on the standard filename generation methods - # implemented below should override these; see the comment near - # those methods ('object_filenames()' et. al.) for details: - src_extensions = None # list of strings - obj_extension = None # string - static_lib_extension = None - shared_lib_extension = None # string - static_lib_format = None # format string - shared_lib_format = None # prob. same as static_lib_format - exe_extension = None # string - - # Default language settings. language_map is used to detect a source - # file or Extension target language, checking source filenames. - # language_order is used to detect the language precedence, when deciding - # what language to use when mixing source types. For example, if some - # extension has two files with ".c" extension, and one with ".cpp", it - # is still linked as c++. - language_map = {".c" : "c", - ".cc" : "c++", - ".cpp" : "c++", - ".cxx" : "c++", - ".m" : "objc", - } - language_order = ["c++", "objc", "c"] - - def __init__(self, verbose=0, dry_run=0, force=0): - self.dry_run = dry_run - self.force = force - self.verbose = verbose - - # 'output_dir': a common output directory for object, library, - # shared object, and shared library files - self.output_dir = None - - # 'macros': a list of macro definitions (or undefinitions). A - # macro definition is a 2-tuple (name, value), where the value is - # either a string or None (no explicit value). A macro - # undefinition is a 1-tuple (name,). - self.macros = [] - - # 'include_dirs': a list of directories to search for include files - self.include_dirs = [] - - # 'libraries': a list of libraries to include in any link - # (library names, not filenames: eg. "foo" not "libfoo.a") - self.libraries = [] - - # 'library_dirs': a list of directories to search for libraries - self.library_dirs = [] - - # 'runtime_library_dirs': a list of directories to search for - # shared libraries/objects at runtime - self.runtime_library_dirs = [] - - # 'objects': a list of object files (or similar, such as explicitly - # named library files) to include on any link - self.objects = [] - - for key in self.executables.keys(): - self.set_executable(key, self.executables[key]) - - def set_executables(self, **kwargs): - """Define the executables (and options for them) that will be run - to perform the various stages of compilation. The exact set of - executables that may be specified here depends on the compiler - class (via the 'executables' class attribute), but most will have: - compiler the C/C++ compiler - linker_so linker used to create shared objects and libraries - linker_exe linker used to create binary executables - archiver static library creator - - On platforms with a command-line (Unix, DOS/Windows), each of these - is a string that will be split into executable name and (optional) - list of arguments. (Splitting the string is done similarly to how - Unix shells operate: words are delimited by spaces, but quotes and - backslashes can override this. See - 'distutils.util.split_quoted()'.) - """ - - # Note that some CCompiler implementation classes will define class - # attributes 'cpp', 'cc', etc. with hard-coded executable names; - # this is appropriate when a compiler class is for exactly one - # compiler/OS combination (eg. MSVCCompiler). Other compiler - # classes (UnixCCompiler, in particular) are driven by information - # discovered at run-time, since there are many different ways to do - # basically the same things with Unix C compilers. - - for key in kwargs: - if key not in self.executables: - raise ValueError("unknown executable '%s' for class %s" % - (key, self.__class__.__name__)) - self.set_executable(key, kwargs[key]) - - def set_executable(self, key, value): - if isinstance(value, str): - setattr(self, key, split_quoted(value)) - else: - setattr(self, key, value) - - def _find_macro(self, name): - i = 0 - for defn in self.macros: - if defn[0] == name: - return i - i += 1 - return None - - def _check_macro_definitions(self, definitions): - """Ensures that every element of 'definitions' is a valid macro - definition, ie. either (name,value) 2-tuple or a (name,) tuple. Do - nothing if all definitions are OK, raise TypeError otherwise. - """ - for defn in definitions: - if not (isinstance(defn, tuple) and - (len(defn) in (1, 2) and - (isinstance (defn[1], str) or defn[1] is None)) and - isinstance (defn[0], str)): - raise TypeError(("invalid macro definition '%s': " % defn) + \ - "must be tuple (string,), (string, string), or " + \ - "(string, None)") - - - # -- Bookkeeping methods ------------------------------------------- - - def define_macro(self, name, value=None): - """Define a preprocessor macro for all compilations driven by this - compiler object. The optional parameter 'value' should be a - string; if it is not supplied, then the macro will be defined - without an explicit value and the exact outcome depends on the - compiler used (XXX true? does ANSI say anything about this?) - """ - # Delete from the list of macro definitions/undefinitions if - # already there (so that this one will take precedence). - i = self._find_macro (name) - if i is not None: - del self.macros[i] - - self.macros.append((name, value)) - - def undefine_macro(self, name): - """Undefine a preprocessor macro for all compilations driven by - this compiler object. If the same macro is defined by - 'define_macro()' and undefined by 'undefine_macro()' the last call - takes precedence (including multiple redefinitions or - undefinitions). If the macro is redefined/undefined on a - per-compilation basis (ie. in the call to 'compile()'), then that - takes precedence. - """ - # Delete from the list of macro definitions/undefinitions if - # already there (so that this one will take precedence). - i = self._find_macro (name) - if i is not None: - del self.macros[i] - - undefn = (name,) - self.macros.append(undefn) - - def add_include_dir(self, dir): - """Add 'dir' to the list of directories that will be searched for - header files. The compiler is instructed to search directories in - the order in which they are supplied by successive calls to - 'add_include_dir()'. - """ - self.include_dirs.append(dir) - - def set_include_dirs(self, dirs): - """Set the list of directories that will be searched to 'dirs' (a - list of strings). Overrides any preceding calls to - 'add_include_dir()'; subsequence calls to 'add_include_dir()' add - to the list passed to 'set_include_dirs()'. This does not affect - any list of standard include directories that the compiler may - search by default. - """ - self.include_dirs = dirs[:] - - def add_library(self, libname): - """Add 'libname' to the list of libraries that will be included in - all links driven by this compiler object. Note that 'libname' - should *not* be the name of a file containing a library, but the - name of the library itself: the actual filename will be inferred by - the linker, the compiler, or the compiler class (depending on the - platform). - - The linker will be instructed to link against libraries in the - order they were supplied to 'add_library()' and/or - 'set_libraries()'. It is perfectly valid to duplicate library - names; the linker will be instructed to link against libraries as - many times as they are mentioned. - """ - self.libraries.append(libname) - - def set_libraries(self, libnames): - """Set the list of libraries to be included in all links driven by - this compiler object to 'libnames' (a list of strings). This does - not affect any standard system libraries that the linker may - include by default. - """ - self.libraries = libnames[:] - - def add_library_dir(self, dir): - """Add 'dir' to the list of directories that will be searched for - libraries specified to 'add_library()' and 'set_libraries()'. The - linker will be instructed to search for libraries in the order they - are supplied to 'add_library_dir()' and/or 'set_library_dirs()'. - """ - self.library_dirs.append(dir) - - def set_library_dirs(self, dirs): - """Set the list of library search directories to 'dirs' (a list of - strings). This does not affect any standard library search path - that the linker may search by default. - """ - self.library_dirs = dirs[:] - - def add_runtime_library_dir(self, dir): - """Add 'dir' to the list of directories that will be searched for - shared libraries at runtime. - """ - self.runtime_library_dirs.append(dir) - - def set_runtime_library_dirs(self, dirs): - """Set the list of directories to search for shared libraries at - runtime to 'dirs' (a list of strings). This does not affect any - standard search path that the runtime linker may search by - default. - """ - self.runtime_library_dirs = dirs[:] - - def add_link_object(self, object): - """Add 'object' to the list of object files (or analogues, such as - explicitly named library files or the output of "resource - compilers") to be included in every link driven by this compiler - object. - """ - self.objects.append(object) - - def set_link_objects(self, objects): - """Set the list of object files (or analogues) to be included in - every link to 'objects'. This does not affect any standard object - files that the linker may include by default (such as system - libraries). - """ - self.objects = objects[:] - - - # -- Private utility methods -------------------------------------- - # (here for the convenience of subclasses) - - # Helper method to prep compiler in subclass compile() methods - - def _setup_compile(self, outdir, macros, incdirs, sources, depends, - extra): - """Process arguments and decide which source files to compile.""" - if outdir is None: - outdir = self.output_dir - elif not isinstance(outdir, str): - raise TypeError("'output_dir' must be a string or None") - - if macros is None: - macros = self.macros - elif isinstance(macros, list): - macros = macros + (self.macros or []) - else: - raise TypeError("'macros' (if supplied) must be a list of tuples") - - if incdirs is None: - incdirs = self.include_dirs - elif isinstance(incdirs, (list, tuple)): - incdirs = list(incdirs) + (self.include_dirs or []) - else: - raise TypeError( - "'include_dirs' (if supplied) must be a list of strings") - - if extra is None: - extra = [] - - # Get the list of expected output (object) files - objects = self.object_filenames(sources, strip_dir=0, - output_dir=outdir) - assert len(objects) == len(sources) - - pp_opts = gen_preprocess_options(macros, incdirs) - - build = {} - for i in range(len(sources)): - src = sources[i] - obj = objects[i] - ext = os.path.splitext(src)[1] - self.mkpath(os.path.dirname(obj)) - build[obj] = (src, ext) - - return macros, objects, extra, pp_opts, build - - def _get_cc_args(self, pp_opts, debug, before): - # works for unixccompiler, cygwinccompiler - cc_args = pp_opts + ['-c'] - if debug: - cc_args[:0] = ['-g'] - if before: - cc_args[:0] = before - return cc_args - - def _fix_compile_args(self, output_dir, macros, include_dirs): - """Typecheck and fix-up some of the arguments to the 'compile()' - method, and return fixed-up values. Specifically: if 'output_dir' - is None, replaces it with 'self.output_dir'; ensures that 'macros' - is a list, and augments it with 'self.macros'; ensures that - 'include_dirs' is a list, and augments it with 'self.include_dirs'. - Guarantees that the returned values are of the correct type, - i.e. for 'output_dir' either string or None, and for 'macros' and - 'include_dirs' either list or None. - """ - if output_dir is None: - output_dir = self.output_dir - elif not isinstance(output_dir, str): - raise TypeError("'output_dir' must be a string or None") - - if macros is None: - macros = self.macros - elif isinstance(macros, list): - macros = macros + (self.macros or []) - else: - raise TypeError("'macros' (if supplied) must be a list of tuples") - - if include_dirs is None: - include_dirs = self.include_dirs - elif isinstance(include_dirs, (list, tuple)): - include_dirs = list(include_dirs) + (self.include_dirs or []) - else: - raise TypeError( - "'include_dirs' (if supplied) must be a list of strings") - - return output_dir, macros, include_dirs - - def _prep_compile(self, sources, output_dir, depends=None): - """Decide which source files must be recompiled. - - Determine the list of object files corresponding to 'sources', - and figure out which ones really need to be recompiled. - Return a list of all object files and a dictionary telling - which source files can be skipped. - """ - # Get the list of expected output (object) files - objects = self.object_filenames(sources, output_dir=output_dir) - assert len(objects) == len(sources) - - # Return an empty dict for the "which source files can be skipped" - # return value to preserve API compatibility. - return objects, {} - - def _fix_object_args(self, objects, output_dir): - """Typecheck and fix up some arguments supplied to various methods. - Specifically: ensure that 'objects' is a list; if output_dir is - None, replace with self.output_dir. Return fixed versions of - 'objects' and 'output_dir'. - """ - if not isinstance(objects, (list, tuple)): - raise TypeError("'objects' must be a list or tuple of strings") - objects = list(objects) - - if output_dir is None: - output_dir = self.output_dir - elif not isinstance(output_dir, str): - raise TypeError("'output_dir' must be a string or None") - - return (objects, output_dir) - - def _fix_lib_args(self, libraries, library_dirs, runtime_library_dirs): - """Typecheck and fix up some of the arguments supplied to the - 'link_*' methods. Specifically: ensure that all arguments are - lists, and augment them with their permanent versions - (eg. 'self.libraries' augments 'libraries'). Return a tuple with - fixed versions of all arguments. - """ - if libraries is None: - libraries = self.libraries - elif isinstance(libraries, (list, tuple)): - libraries = list (libraries) + (self.libraries or []) - else: - raise TypeError( - "'libraries' (if supplied) must be a list of strings") - - if library_dirs is None: - library_dirs = self.library_dirs - elif isinstance(library_dirs, (list, tuple)): - library_dirs = list (library_dirs) + (self.library_dirs or []) - else: - raise TypeError( - "'library_dirs' (if supplied) must be a list of strings") - - if runtime_library_dirs is None: - runtime_library_dirs = self.runtime_library_dirs - elif isinstance(runtime_library_dirs, (list, tuple)): - runtime_library_dirs = (list(runtime_library_dirs) + - (self.runtime_library_dirs or [])) - else: - raise TypeError("'runtime_library_dirs' (if supplied) " - "must be a list of strings") - - return (libraries, library_dirs, runtime_library_dirs) - - def _need_link(self, objects, output_file): - """Return true if we need to relink the files listed in 'objects' - to recreate 'output_file'. - """ - if self.force: - return True - else: - if self.dry_run: - newer = newer_group (objects, output_file, missing='newer') - else: - newer = newer_group (objects, output_file) - return newer - - def detect_language(self, sources): - """Detect the language of a given file, or list of files. Uses - language_map, and language_order to do the job. - """ - if not isinstance(sources, list): - sources = [sources] - lang = None - index = len(self.language_order) - for source in sources: - base, ext = os.path.splitext(source) - extlang = self.language_map.get(ext) - try: - extindex = self.language_order.index(extlang) - if extindex < index: - lang = extlang - index = extindex - except ValueError: - pass - return lang - - - # -- Worker methods ------------------------------------------------ - # (must be implemented by subclasses) - - def preprocess(self, source, output_file=None, macros=None, - include_dirs=None, extra_preargs=None, extra_postargs=None): - """Preprocess a single C/C++ source file, named in 'source'. - Output will be written to file named 'output_file', or stdout if - 'output_file' not supplied. 'macros' is a list of macro - definitions as for 'compile()', which will augment the macros set - with 'define_macro()' and 'undefine_macro()'. 'include_dirs' is a - list of directory names that will be added to the default list. - - Raises PreprocessError on failure. - """ - pass - - def compile(self, sources, output_dir=None, macros=None, - include_dirs=None, debug=0, extra_preargs=None, - extra_postargs=None, depends=None): - """Compile one or more source files. - - 'sources' must be a list of filenames, most likely C/C++ - files, but in reality anything that can be handled by a - particular compiler and compiler class (eg. MSVCCompiler can - handle resource files in 'sources'). Return a list of object - filenames, one per source filename in 'sources'. Depending on - the implementation, not all source files will necessarily be - compiled, but all corresponding object filenames will be - returned. - - If 'output_dir' is given, object files will be put under it, while - retaining their original path component. That is, "foo/bar.c" - normally compiles to "foo/bar.o" (for a Unix implementation); if - 'output_dir' is "build", then it would compile to - "build/foo/bar.o". - - 'macros', if given, must be a list of macro definitions. A macro - definition is either a (name, value) 2-tuple or a (name,) 1-tuple. - The former defines a macro; if the value is None, the macro is - defined without an explicit value. The 1-tuple case undefines a - macro. Later definitions/redefinitions/ undefinitions take - precedence. - - 'include_dirs', if given, must be a list of strings, the - directories to add to the default include file search path for this - compilation only. - - 'debug' is a boolean; if true, the compiler will be instructed to - output debug symbols in (or alongside) the object file(s). - - 'extra_preargs' and 'extra_postargs' are implementation- dependent. - On platforms that have the notion of a command-line (e.g. Unix, - DOS/Windows), they are most likely lists of strings: extra - command-line arguments to prepend/append to the compiler command - line. On other platforms, consult the implementation class - documentation. In any event, they are intended as an escape hatch - for those occasions when the abstract compiler framework doesn't - cut the mustard. - - 'depends', if given, is a list of filenames that all targets - depend on. If a source file is older than any file in - depends, then the source file will be recompiled. This - supports dependency tracking, but only at a coarse - granularity. - - Raises CompileError on failure. - """ - # A concrete compiler class can either override this method - # entirely or implement _compile(). - macros, objects, extra_postargs, pp_opts, build = \ - self._setup_compile(output_dir, macros, include_dirs, sources, - depends, extra_postargs) - cc_args = self._get_cc_args(pp_opts, debug, extra_preargs) - - for obj in objects: - try: - src, ext = build[obj] - except KeyError: - continue - self._compile(obj, src, ext, cc_args, extra_postargs, pp_opts) - - # Return *all* object filenames, not just the ones we just built. - return objects - - def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts): - """Compile 'src' to product 'obj'.""" - # A concrete compiler class that does not override compile() - # should implement _compile(). - pass - - def create_static_lib(self, objects, output_libname, output_dir=None, - debug=0, target_lang=None): - """Link a bunch of stuff together to create a static library file. - The "bunch of stuff" consists of the list of object files supplied - as 'objects', the extra object files supplied to - 'add_link_object()' and/or 'set_link_objects()', the libraries - supplied to 'add_library()' and/or 'set_libraries()', and the - libraries supplied as 'libraries' (if any). - - 'output_libname' should be a library name, not a filename; the - filename will be inferred from the library name. 'output_dir' is - the directory where the library file will be put. - - 'debug' is a boolean; if true, debugging information will be - included in the library (note that on most platforms, it is the - compile step where this matters: the 'debug' flag is included here - just for consistency). - - 'target_lang' is the target language for which the given objects - are being compiled. This allows specific linkage time treatment of - certain languages. - - Raises LibError on failure. - """ - pass - - - # values for target_desc parameter in link() - SHARED_OBJECT = "shared_object" - SHARED_LIBRARY = "shared_library" - EXECUTABLE = "executable" - - def link(self, - target_desc, - objects, - output_filename, - output_dir=None, - libraries=None, - library_dirs=None, - runtime_library_dirs=None, - export_symbols=None, - debug=0, - extra_preargs=None, - extra_postargs=None, - build_temp=None, - target_lang=None): - """Link a bunch of stuff together to create an executable or - shared library file. - - The "bunch of stuff" consists of the list of object files supplied - as 'objects'. 'output_filename' should be a filename. If - 'output_dir' is supplied, 'output_filename' is relative to it - (i.e. 'output_filename' can provide directory components if - needed). - - 'libraries' is a list of libraries to link against. These are - library names, not filenames, since they're translated into - filenames in a platform-specific way (eg. "foo" becomes "libfoo.a" - on Unix and "foo.lib" on DOS/Windows). However, they can include a - directory component, which means the linker will look in that - specific directory rather than searching all the normal locations. - - 'library_dirs', if supplied, should be a list of directories to - search for libraries that were specified as bare library names - (ie. no directory component). These are on top of the system - default and those supplied to 'add_library_dir()' and/or - 'set_library_dirs()'. 'runtime_library_dirs' is a list of - directories that will be embedded into the shared library and used - to search for other shared libraries that *it* depends on at - run-time. (This may only be relevant on Unix.) - - 'export_symbols' is a list of symbols that the shared library will - export. (This appears to be relevant only on Windows.) - - 'debug' is as for 'compile()' and 'create_static_lib()', with the - slight distinction that it actually matters on most platforms (as - opposed to 'create_static_lib()', which includes a 'debug' flag - mostly for form's sake). - - 'extra_preargs' and 'extra_postargs' are as for 'compile()' (except - of course that they supply command-line arguments for the - particular linker being used). - - 'target_lang' is the target language for which the given objects - are being compiled. This allows specific linkage time treatment of - certain languages. - - Raises LinkError on failure. - """ - raise NotImplementedError - - - # Old 'link_*()' methods, rewritten to use the new 'link()' method. - - def link_shared_lib(self, - objects, - output_libname, - output_dir=None, - libraries=None, - library_dirs=None, - runtime_library_dirs=None, - export_symbols=None, - debug=0, - extra_preargs=None, - extra_postargs=None, - build_temp=None, - target_lang=None): - self.link(CCompiler.SHARED_LIBRARY, objects, - self.library_filename(output_libname, lib_type='shared'), - output_dir, - libraries, library_dirs, runtime_library_dirs, - export_symbols, debug, - extra_preargs, extra_postargs, build_temp, target_lang) - - - def link_shared_object(self, - objects, - output_filename, - output_dir=None, - libraries=None, - library_dirs=None, - runtime_library_dirs=None, - export_symbols=None, - debug=0, - extra_preargs=None, - extra_postargs=None, - build_temp=None, - target_lang=None): - self.link(CCompiler.SHARED_OBJECT, objects, - output_filename, output_dir, - libraries, library_dirs, runtime_library_dirs, - export_symbols, debug, - extra_preargs, extra_postargs, build_temp, target_lang) - - - def link_executable(self, - objects, - output_progname, - output_dir=None, - libraries=None, - library_dirs=None, - runtime_library_dirs=None, - debug=0, - extra_preargs=None, - extra_postargs=None, - target_lang=None): - self.link(CCompiler.EXECUTABLE, objects, - self.executable_filename(output_progname), output_dir, - libraries, library_dirs, runtime_library_dirs, None, - debug, extra_preargs, extra_postargs, None, target_lang) - - - # -- Miscellaneous methods ----------------------------------------- - # These are all used by the 'gen_lib_options() function; there is - # no appropriate default implementation so subclasses should - # implement all of these. - - def library_dir_option(self, dir): - """Return the compiler option to add 'dir' to the list of - directories searched for libraries. - """ - raise NotImplementedError - - def runtime_library_dir_option(self, dir): - """Return the compiler option to add 'dir' to the list of - directories searched for runtime libraries. - """ - raise NotImplementedError - - def library_option(self, lib): - """Return the compiler option to add 'lib' to the list of libraries - linked into the shared library or executable. - """ - raise NotImplementedError - - def has_function(self, funcname, includes=None, include_dirs=None, - libraries=None, library_dirs=None): - """Return a boolean indicating whether funcname is supported on - the current platform. The optional arguments can be used to - augment the compilation environment. - """ - # this can't be included at module scope because it tries to - # import math which might not be available at that point - maybe - # the necessary logic should just be inlined? - import tempfile - if includes is None: - includes = [] - if include_dirs is None: - include_dirs = [] - if libraries is None: - libraries = [] - if library_dirs is None: - library_dirs = [] - fd, fname = tempfile.mkstemp(".c", funcname, text=True) - f = os.fdopen(fd, "w") - try: - for incl in includes: - f.write("""#include "%s"\n""" % incl) - f.write("""\ -int main (int argc, char **argv) { - %s(); - return 0; -} -""" % funcname) - finally: - f.close() - try: - objects = self.compile([fname], include_dirs=include_dirs) - except CompileError: - return False - - try: - self.link_executable(objects, "a.out", - libraries=libraries, - library_dirs=library_dirs) - except (LinkError, TypeError): - return False - return True - - def find_library_file (self, dirs, lib, debug=0): - """Search the specified list of directories for a static or shared - library file 'lib' and return the full path to that file. If - 'debug' true, look for a debugging version (if that makes sense on - the current platform). Return None if 'lib' wasn't found in any of - the specified directories. - """ - raise NotImplementedError - - # -- Filename generation methods ----------------------------------- - - # The default implementation of the filename generating methods are - # prejudiced towards the Unix/DOS/Windows view of the world: - # * object files are named by replacing the source file extension - # (eg. .c/.cpp -> .o/.obj) - # * library files (shared or static) are named by plugging the - # library name and extension into a format string, eg. - # "lib%s.%s" % (lib_name, ".a") for Unix static libraries - # * executables are named by appending an extension (possibly - # empty) to the program name: eg. progname + ".exe" for - # Windows - # - # To reduce redundant code, these methods expect to find - # several attributes in the current object (presumably defined - # as class attributes): - # * src_extensions - - # list of C/C++ source file extensions, eg. ['.c', '.cpp'] - # * obj_extension - - # object file extension, eg. '.o' or '.obj' - # * static_lib_extension - - # extension for static library files, eg. '.a' or '.lib' - # * shared_lib_extension - - # extension for shared library/object files, eg. '.so', '.dll' - # * static_lib_format - - # format string for generating static library filenames, - # eg. 'lib%s.%s' or '%s.%s' - # * shared_lib_format - # format string for generating shared library filenames - # (probably same as static_lib_format, since the extension - # is one of the intended parameters to the format string) - # * exe_extension - - # extension for executable files, eg. '' or '.exe' - - def object_filenames(self, source_filenames, strip_dir=0, output_dir=''): - if output_dir is None: - output_dir = '' - obj_names = [] - for src_name in source_filenames: - base, ext = os.path.splitext(src_name) - base = os.path.splitdrive(base)[1] # Chop off the drive - base = base[os.path.isabs(base):] # If abs, chop off leading / - if ext not in self.src_extensions: - raise UnknownFileError( - "unknown file type '%s' (from '%s')" % (ext, src_name)) - if strip_dir: - base = os.path.basename(base) - obj_names.append(os.path.join(output_dir, - base + self.obj_extension)) - return obj_names - - def shared_object_filename(self, basename, strip_dir=0, output_dir=''): - assert output_dir is not None - if strip_dir: - basename = os.path.basename(basename) - return os.path.join(output_dir, basename + self.shared_lib_extension) - - def executable_filename(self, basename, strip_dir=0, output_dir=''): - assert output_dir is not None - if strip_dir: - basename = os.path.basename(basename) - return os.path.join(output_dir, basename + (self.exe_extension or '')) - - def library_filename(self, libname, lib_type='static', # or 'shared' - strip_dir=0, output_dir=''): - assert output_dir is not None - if lib_type not in ("static", "shared", "dylib", "xcode_stub"): - raise ValueError( - "'lib_type' must be \"static\", \"shared\", \"dylib\", or \"xcode_stub\"") - fmt = getattr(self, lib_type + "_lib_format") - ext = getattr(self, lib_type + "_lib_extension") - - dir, base = os.path.split(libname) - filename = fmt % (base, ext) - if strip_dir: - dir = '' - - return os.path.join(output_dir, dir, filename) - - - # -- Utility methods ----------------------------------------------- - - def announce(self, msg, level=1): - log.debug(msg) - - def debug_print(self, msg): - from distutils.debug import DEBUG - if DEBUG: - print(msg) - - def warn(self, msg): - sys.stderr.write("warning: %s\n" % msg) - - def execute(self, func, args, msg=None, level=1): - execute(func, args, msg, self.dry_run) - - def spawn(self, cmd): - spawn(cmd, dry_run=self.dry_run) - - def move_file(self, src, dst): - return move_file(src, dst, dry_run=self.dry_run) - - def mkpath (self, name, mode=0o777): - mkpath(name, mode, dry_run=self.dry_run) - - -# Map a sys.platform/os.name ('posix', 'nt') to the default compiler -# type for that platform. Keys are interpreted as re match -# patterns. Order is important; platform mappings are preferred over -# OS names. -_default_compilers = ( - - # Platform string mappings - - # on a cygwin built python we can use gcc like an ordinary UNIXish - # compiler - ('cygwin.*', 'unix'), - - # OS name mappings - ('posix', 'unix'), - ('nt', 'msvc'), - - ) - -def get_default_compiler(osname=None, platform=None): - """Determine the default compiler to use for the given platform. - - osname should be one of the standard Python OS names (i.e. the - ones returned by os.name) and platform the common value - returned by sys.platform for the platform in question. - - The default values are os.name and sys.platform in case the - parameters are not given. - """ - if osname is None: - osname = os.name - if platform is None: - platform = sys.platform - for pattern, compiler in _default_compilers: - if re.match(pattern, platform) is not None or \ - re.match(pattern, osname) is not None: - return compiler - # Default to Unix compiler - return 'unix' - -# Map compiler types to (module_name, class_name) pairs -- ie. where to -# find the code that implements an interface to this compiler. (The module -# is assumed to be in the 'distutils' package.) -compiler_class = { 'unix': ('unixccompiler', 'UnixCCompiler', - "standard UNIX-style compiler"), - 'msvc': ('_msvccompiler', 'MSVCCompiler', - "Microsoft Visual C++"), - 'cygwin': ('cygwinccompiler', 'CygwinCCompiler', - "Cygwin port of GNU C Compiler for Win32"), - 'mingw32': ('cygwinccompiler', 'Mingw32CCompiler', - "Mingw32 port of GNU C Compiler for Win32"), - 'bcpp': ('bcppcompiler', 'BCPPCompiler', - "Borland C++ Compiler"), - } - -def show_compilers(): - """Print list of available compilers (used by the "--help-compiler" - options to "build", "build_ext", "build_clib"). - """ - # XXX this "knows" that the compiler option it's describing is - # "--compiler", which just happens to be the case for the three - # commands that use it. - from distutils.fancy_getopt import FancyGetopt - compilers = [] - for compiler in compiler_class.keys(): - compilers.append(("compiler="+compiler, None, - compiler_class[compiler][2])) - compilers.sort() - pretty_printer = FancyGetopt(compilers) - pretty_printer.print_help("List of available compilers:") - - -def new_compiler(plat=None, compiler=None, verbose=0, dry_run=0, force=0): - """Generate an instance of some CCompiler subclass for the supplied - platform/compiler combination. 'plat' defaults to 'os.name' - (eg. 'posix', 'nt'), and 'compiler' defaults to the default compiler - for that platform. Currently only 'posix' and 'nt' are supported, and - the default compilers are "traditional Unix interface" (UnixCCompiler - class) and Visual C++ (MSVCCompiler class). Note that it's perfectly - possible to ask for a Unix compiler object under Windows, and a - Microsoft compiler object under Unix -- if you supply a value for - 'compiler', 'plat' is ignored. - """ - if plat is None: - plat = os.name - - try: - if compiler is None: - compiler = get_default_compiler(plat) - - (module_name, class_name, long_description) = compiler_class[compiler] - except KeyError: - msg = "don't know how to compile C/C++ code on platform '%s'" % plat - if compiler is not None: - msg = msg + " with '%s' compiler" % compiler - raise DistutilsPlatformError(msg) - - try: - module_name = "distutils." + module_name - __import__ (module_name) - module = sys.modules[module_name] - klass = vars(module)[class_name] - except ImportError: - raise DistutilsModuleError( - "can't compile C/C++ code: unable to load module '%s'" % \ - module_name) - except KeyError: - raise DistutilsModuleError( - "can't compile C/C++ code: unable to find class '%s' " - "in module '%s'" % (class_name, module_name)) - - # XXX The None is necessary to preserve backwards compatibility - # with classes that expect verbose to be the first positional - # argument. - return klass(None, dry_run, force) - - -def gen_preprocess_options(macros, include_dirs): - """Generate C pre-processor options (-D, -U, -I) as used by at least - two types of compilers: the typical Unix compiler and Visual C++. - 'macros' is the usual thing, a list of 1- or 2-tuples, where (name,) - means undefine (-U) macro 'name', and (name,value) means define (-D) - macro 'name' to 'value'. 'include_dirs' is just a list of directory - names to be added to the header file search path (-I). Returns a list - of command-line options suitable for either Unix compilers or Visual - C++. - """ - # XXX it would be nice (mainly aesthetic, and so we don't generate - # stupid-looking command lines) to go over 'macros' and eliminate - # redundant definitions/undefinitions (ie. ensure that only the - # latest mention of a particular macro winds up on the command - # line). I don't think it's essential, though, since most (all?) - # Unix C compilers only pay attention to the latest -D or -U - # mention of a macro on their command line. Similar situation for - # 'include_dirs'. I'm punting on both for now. Anyways, weeding out - # redundancies like this should probably be the province of - # CCompiler, since the data structures used are inherited from it - # and therefore common to all CCompiler classes. - pp_opts = [] - for macro in macros: - if not (isinstance(macro, tuple) and 1 <= len(macro) <= 2): - raise TypeError( - "bad macro definition '%s': " - "each element of 'macros' list must be a 1- or 2-tuple" - % macro) - - if len(macro) == 1: # undefine this macro - pp_opts.append("-U%s" % macro[0]) - elif len(macro) == 2: - if macro[1] is None: # define with no explicit value - pp_opts.append("-D%s" % macro[0]) - else: - # XXX *don't* need to be clever about quoting the - # macro value here, because we're going to avoid the - # shell at all costs when we spawn the command! - pp_opts.append("-D%s=%s" % macro) - - for dir in include_dirs: - pp_opts.append("-I%s" % dir) - return pp_opts - - -def gen_lib_options (compiler, library_dirs, runtime_library_dirs, libraries): - """Generate linker options for searching library directories and - linking with specific libraries. 'libraries' and 'library_dirs' are, - respectively, lists of library names (not filenames!) and search - directories. Returns a list of command-line options suitable for use - with some compiler (depending on the two format strings passed in). - """ - lib_opts = [] - - for dir in library_dirs: - lib_opts.append(compiler.library_dir_option(dir)) - - for dir in runtime_library_dirs: - opt = compiler.runtime_library_dir_option(dir) - if isinstance(opt, list): - lib_opts = lib_opts + opt - else: - lib_opts.append(opt) - - # XXX it's important that we *not* remove redundant library mentions! - # sometimes you really do have to say "-lfoo -lbar -lfoo" in order to - # resolve all symbols. I just hope we never have to say "-lfoo obj.o - # -lbar" to get things to work -- that's certainly a possibility, but a - # pretty nasty way to arrange your C code. - - for lib in libraries: - (lib_dir, lib_name) = os.path.split(lib) - if lib_dir: - lib_file = compiler.find_library_file([lib_dir], lib_name) - if lib_file: - lib_opts.append(lib_file) - else: - compiler.warn("no library file corresponding to " - "'%s' found (skipping)" % lib) - else: - lib_opts.append(compiler.library_option (lib)) - return lib_opts diff --git a/Lib/distutils/cmd.py b/Lib/distutils/cmd.py deleted file mode 100644 index dba3191e..00000000 --- a/Lib/distutils/cmd.py +++ /dev/null @@ -1,403 +0,0 @@ -"""distutils.cmd - -Provides the Command class, the base class for the command classes -in the distutils.command package. -""" - -import sys, os, re -from distutils.errors import DistutilsOptionError -from distutils import util, dir_util, file_util, archive_util, dep_util -from distutils import log - -class Command: - """Abstract base class for defining command classes, the "worker bees" - of the Distutils. A useful analogy for command classes is to think of - them as subroutines with local variables called "options". The options - are "declared" in 'initialize_options()' and "defined" (given their - final values, aka "finalized") in 'finalize_options()', both of which - must be defined by every command class. The distinction between the - two is necessary because option values might come from the outside - world (command line, config file, ...), and any options dependent on - other options must be computed *after* these outside influences have - been processed -- hence 'finalize_options()'. The "body" of the - subroutine, where it does all its work based on the values of its - options, is the 'run()' method, which must also be implemented by every - command class. - """ - - # 'sub_commands' formalizes the notion of a "family" of commands, - # eg. "install" as the parent with sub-commands "install_lib", - # "install_headers", etc. The parent of a family of commands - # defines 'sub_commands' as a class attribute; it's a list of - # (command_name : string, predicate : unbound_method | string | None) - # tuples, where 'predicate' is a method of the parent command that - # determines whether the corresponding command is applicable in the - # current situation. (Eg. we "install_headers" is only applicable if - # we have any C header files to install.) If 'predicate' is None, - # that command is always applicable. - # - # 'sub_commands' is usually defined at the *end* of a class, because - # predicates can be unbound methods, so they must already have been - # defined. The canonical example is the "install" command. - sub_commands = [] - - - # -- Creation/initialization methods ------------------------------- - - def __init__(self, dist): - """Create and initialize a new Command object. Most importantly, - invokes the 'initialize_options()' method, which is the real - initializer and depends on the actual command being - instantiated. - """ - # late import because of mutual dependence between these classes - from distutils.dist import Distribution - - if not isinstance(dist, Distribution): - raise TypeError("dist must be a Distribution instance") - if self.__class__ is Command: - raise RuntimeError("Command is an abstract class") - - self.distribution = dist - self.initialize_options() - - # Per-command versions of the global flags, so that the user can - # customize Distutils' behaviour command-by-command and let some - # commands fall back on the Distribution's behaviour. None means - # "not defined, check self.distribution's copy", while 0 or 1 mean - # false and true (duh). Note that this means figuring out the real - # value of each flag is a touch complicated -- hence "self._dry_run" - # will be handled by __getattr__, below. - # XXX This needs to be fixed. - self._dry_run = None - - # verbose is largely ignored, but needs to be set for - # backwards compatibility (I think)? - self.verbose = dist.verbose - - # Some commands define a 'self.force' option to ignore file - # timestamps, but methods defined *here* assume that - # 'self.force' exists for all commands. So define it here - # just to be safe. - self.force = None - - # The 'help' flag is just used for command-line parsing, so - # none of that complicated bureaucracy is needed. - self.help = 0 - - # 'finalized' records whether or not 'finalize_options()' has been - # called. 'finalize_options()' itself should not pay attention to - # this flag: it is the business of 'ensure_finalized()', which - # always calls 'finalize_options()', to respect/update it. - self.finalized = 0 - - # XXX A more explicit way to customize dry_run would be better. - def __getattr__(self, attr): - if attr == 'dry_run': - myval = getattr(self, "_" + attr) - if myval is None: - return getattr(self.distribution, attr) - else: - return myval - else: - raise AttributeError(attr) - - def ensure_finalized(self): - if not self.finalized: - self.finalize_options() - self.finalized = 1 - - # Subclasses must define: - # initialize_options() - # provide default values for all options; may be customized by - # setup script, by options from config file(s), or by command-line - # options - # finalize_options() - # decide on the final values for all options; this is called - # after all possible intervention from the outside world - # (command-line, option file, etc.) has been processed - # run() - # run the command: do whatever it is we're here to do, - # controlled by the command's various option values - - def initialize_options(self): - """Set default values for all the options that this command - supports. Note that these defaults may be overridden by other - commands, by the setup script, by config files, or by the - command-line. Thus, this is not the place to code dependencies - between options; generally, 'initialize_options()' implementations - are just a bunch of "self.foo = None" assignments. - - This method must be implemented by all command classes. - """ - raise RuntimeError("abstract method -- subclass %s must override" - % self.__class__) - - def finalize_options(self): - """Set final values for all the options that this command supports. - This is always called as late as possible, ie. after any option - assignments from the command-line or from other commands have been - done. Thus, this is the place to code option dependencies: if - 'foo' depends on 'bar', then it is safe to set 'foo' from 'bar' as - long as 'foo' still has the same value it was assigned in - 'initialize_options()'. - - This method must be implemented by all command classes. - """ - raise RuntimeError("abstract method -- subclass %s must override" - % self.__class__) - - - def dump_options(self, header=None, indent=""): - from distutils.fancy_getopt import longopt_xlate - if header is None: - header = "command options for '%s':" % self.get_command_name() - self.announce(indent + header, level=log.INFO) - indent = indent + " " - for (option, _, _) in self.user_options: - option = option.translate(longopt_xlate) - if option[-1] == "=": - option = option[:-1] - value = getattr(self, option) - self.announce(indent + "%s = %s" % (option, value), - level=log.INFO) - - def run(self): - """A command's raison d'etre: carry out the action it exists to - perform, controlled by the options initialized in - 'initialize_options()', customized by other commands, the setup - script, the command-line, and config files, and finalized in - 'finalize_options()'. All terminal output and filesystem - interaction should be done by 'run()'. - - This method must be implemented by all command classes. - """ - raise RuntimeError("abstract method -- subclass %s must override" - % self.__class__) - - def announce(self, msg, level=1): - """If the current verbosity level is of greater than or equal to - 'level' print 'msg' to stdout. - """ - log.log(level, msg) - - def debug_print(self, msg): - """Print 'msg' to stdout if the global DEBUG (taken from the - DISTUTILS_DEBUG environment variable) flag is true. - """ - from distutils.debug import DEBUG - if DEBUG: - print(msg) - sys.stdout.flush() - - - # -- Option validation methods ------------------------------------- - # (these are very handy in writing the 'finalize_options()' method) - # - # NB. the general philosophy here is to ensure that a particular option - # value meets certain type and value constraints. If not, we try to - # force it into conformance (eg. if we expect a list but have a string, - # split the string on comma and/or whitespace). If we can't force the - # option into conformance, raise DistutilsOptionError. Thus, command - # classes need do nothing more than (eg.) - # self.ensure_string_list('foo') - # and they can be guaranteed that thereafter, self.foo will be - # a list of strings. - - def _ensure_stringlike(self, option, what, default=None): - val = getattr(self, option) - if val is None: - setattr(self, option, default) - return default - elif not isinstance(val, str): - raise DistutilsOptionError("'%s' must be a %s (got `%s`)" - % (option, what, val)) - return val - - def ensure_string(self, option, default=None): - """Ensure that 'option' is a string; if not defined, set it to - 'default'. - """ - self._ensure_stringlike(option, "string", default) - - def ensure_string_list(self, option): - r"""Ensure that 'option' is a list of strings. If 'option' is - currently a string, we split it either on /,\s*/ or /\s+/, so - "foo bar baz", "foo,bar,baz", and "foo, bar baz" all become - ["foo", "bar", "baz"]. - """ - val = getattr(self, option) - if val is None: - return - elif isinstance(val, str): - setattr(self, option, re.split(r',\s*|\s+', val)) - else: - if isinstance(val, list): - ok = all(isinstance(v, str) for v in val) - else: - ok = False - if not ok: - raise DistutilsOptionError( - "'%s' must be a list of strings (got %r)" - % (option, val)) - - def _ensure_tested_string(self, option, tester, what, error_fmt, - default=None): - val = self._ensure_stringlike(option, what, default) - if val is not None and not tester(val): - raise DistutilsOptionError(("error in '%s' option: " + error_fmt) - % (option, val)) - - def ensure_filename(self, option): - """Ensure that 'option' is the name of an existing file.""" - self._ensure_tested_string(option, os.path.isfile, - "filename", - "'%s' does not exist or is not a file") - - def ensure_dirname(self, option): - self._ensure_tested_string(option, os.path.isdir, - "directory name", - "'%s' does not exist or is not a directory") - - - # -- Convenience methods for commands ------------------------------ - - def get_command_name(self): - if hasattr(self, 'command_name'): - return self.command_name - else: - return self.__class__.__name__ - - def set_undefined_options(self, src_cmd, *option_pairs): - """Set the values of any "undefined" options from corresponding - option values in some other command object. "Undefined" here means - "is None", which is the convention used to indicate that an option - has not been changed between 'initialize_options()' and - 'finalize_options()'. Usually called from 'finalize_options()' for - options that depend on some other command rather than another - option of the same command. 'src_cmd' is the other command from - which option values will be taken (a command object will be created - for it if necessary); the remaining arguments are - '(src_option,dst_option)' tuples which mean "take the value of - 'src_option' in the 'src_cmd' command object, and copy it to - 'dst_option' in the current command object". - """ - # Option_pairs: list of (src_option, dst_option) tuples - src_cmd_obj = self.distribution.get_command_obj(src_cmd) - src_cmd_obj.ensure_finalized() - for (src_option, dst_option) in option_pairs: - if getattr(self, dst_option) is None: - setattr(self, dst_option, getattr(src_cmd_obj, src_option)) - - def get_finalized_command(self, command, create=1): - """Wrapper around Distribution's 'get_command_obj()' method: find - (create if necessary and 'create' is true) the command object for - 'command', call its 'ensure_finalized()' method, and return the - finalized command object. - """ - cmd_obj = self.distribution.get_command_obj(command, create) - cmd_obj.ensure_finalized() - return cmd_obj - - # XXX rename to 'get_reinitialized_command()'? (should do the - # same in dist.py, if so) - def reinitialize_command(self, command, reinit_subcommands=0): - return self.distribution.reinitialize_command(command, - reinit_subcommands) - - def run_command(self, command): - """Run some other command: uses the 'run_command()' method of - Distribution, which creates and finalizes the command object if - necessary and then invokes its 'run()' method. - """ - self.distribution.run_command(command) - - def get_sub_commands(self): - """Determine the sub-commands that are relevant in the current - distribution (ie., that need to be run). This is based on the - 'sub_commands' class attribute: each tuple in that list may include - a method that we call to determine if the subcommand needs to be - run for the current distribution. Return a list of command names. - """ - commands = [] - for (cmd_name, method) in self.sub_commands: - if method is None or method(self): - commands.append(cmd_name) - return commands - - - # -- External world manipulation ----------------------------------- - - def warn(self, msg): - log.warn("warning: %s: %s\n", self.get_command_name(), msg) - - def execute(self, func, args, msg=None, level=1): - util.execute(func, args, msg, dry_run=self.dry_run) - - def mkpath(self, name, mode=0o777): - dir_util.mkpath(name, mode, dry_run=self.dry_run) - - def copy_file(self, infile, outfile, preserve_mode=1, preserve_times=1, - link=None, level=1): - """Copy a file respecting verbose, dry-run and force flags. (The - former two default to whatever is in the Distribution object, and - the latter defaults to false for commands that don't define it.)""" - return file_util.copy_file(infile, outfile, preserve_mode, - preserve_times, not self.force, link, - dry_run=self.dry_run) - - def copy_tree(self, infile, outfile, preserve_mode=1, preserve_times=1, - preserve_symlinks=0, level=1): - """Copy an entire directory tree respecting verbose, dry-run, - and force flags. - """ - return dir_util.copy_tree(infile, outfile, preserve_mode, - preserve_times, preserve_symlinks, - not self.force, dry_run=self.dry_run) - - def move_file (self, src, dst, level=1): - """Move a file respecting dry-run flag.""" - return file_util.move_file(src, dst, dry_run=self.dry_run) - - def spawn(self, cmd, search_path=1, level=1): - """Spawn an external command respecting dry-run flag.""" - from distutils.spawn import spawn - spawn(cmd, search_path, dry_run=self.dry_run) - - def make_archive(self, base_name, format, root_dir=None, base_dir=None, - owner=None, group=None): - return archive_util.make_archive(base_name, format, root_dir, base_dir, - dry_run=self.dry_run, - owner=owner, group=group) - - def make_file(self, infiles, outfile, func, args, - exec_msg=None, skip_msg=None, level=1): - """Special case of 'execute()' for operations that process one or - more input files and generate one output file. Works just like - 'execute()', except the operation is skipped and a different - message printed if 'outfile' already exists and is newer than all - files listed in 'infiles'. If the command defined 'self.force', - and it is true, then the command is unconditionally run -- does no - timestamp checks. - """ - if skip_msg is None: - skip_msg = "skipping %s (inputs unchanged)" % outfile - - # Allow 'infiles' to be a single string - if isinstance(infiles, str): - infiles = (infiles,) - elif not isinstance(infiles, (list, tuple)): - raise TypeError( - "'infiles' must be a string, or a list or tuple of strings") - - if exec_msg is None: - exec_msg = "generating %s from %s" % (outfile, ', '.join(infiles)) - - # If 'outfile' must be regenerated (either because it doesn't - # exist, is out-of-date, or the 'force' flag is true) then - # perform the action that presumably regenerates it - if self.force or dep_util.newer_group(infiles, outfile): - self.execute(func, args, exec_msg, level) - # Otherwise, print the "skip" message - else: - log.debug(skip_msg) diff --git a/Lib/distutils/command/__init__.py b/Lib/distutils/command/__init__.py deleted file mode 100644 index fd0bfae7..00000000 --- a/Lib/distutils/command/__init__.py +++ /dev/null @@ -1,30 +0,0 @@ -"""distutils.command - -Package containing implementation of all the standard Distutils -commands.""" - -__all__ = ['build', - 'build_py', - 'build_ext', - 'build_clib', - 'build_scripts', - 'clean', - 'install', - 'install_lib', - 'install_headers', - 'install_scripts', - 'install_data', - 'sdist', - 'register', - 'bdist', - 'bdist_dumb', - 'bdist_rpm', - 'check', - 'upload', - # These two are reserved for future use: - #'bdist_sdux', - #'bdist_pkgtool', - # Note: - # bdist_packager is not included because it only provides - # an abstract base class - ] diff --git a/Lib/distutils/command/bdist.py b/Lib/distutils/command/bdist.py deleted file mode 100644 index 60309e1f..00000000 --- a/Lib/distutils/command/bdist.py +++ /dev/null @@ -1,138 +0,0 @@ -"""distutils.command.bdist - -Implements the Distutils 'bdist' command (create a built [binary] -distribution).""" - -import os -from distutils.core import Command -from distutils.errors import * -from distutils.util import get_platform - - -def show_formats(): - """Print list of available formats (arguments to "--format" option). - """ - from distutils.fancy_getopt import FancyGetopt - formats = [] - for format in bdist.format_commands: - formats.append(("formats=" + format, None, - bdist.format_command[format][1])) - pretty_printer = FancyGetopt(formats) - pretty_printer.print_help("List of available distribution formats:") - - -class bdist(Command): - - description = "create a built (binary) distribution" - - user_options = [('bdist-base=', 'b', - "temporary directory for creating built distributions"), - ('plat-name=', 'p', - "platform name to embed in generated filenames " - "(default: %s)" % get_platform()), - ('formats=', None, - "formats for distribution (comma-separated list)"), - ('dist-dir=', 'd', - "directory to put final built distributions in " - "[default: dist]"), - ('skip-build', None, - "skip rebuilding everything (for testing/debugging)"), - ('owner=', 'u', - "Owner name used when creating a tar file" - " [default: current user]"), - ('group=', 'g', - "Group name used when creating a tar file" - " [default: current group]"), - ] - - boolean_options = ['skip-build'] - - help_options = [ - ('help-formats', None, - "lists available distribution formats", show_formats), - ] - - # The following commands do not take a format option from bdist - no_format_option = ('bdist_rpm',) - - # This won't do in reality: will need to distinguish RPM-ish Linux, - # Debian-ish Linux, Solaris, FreeBSD, ..., Windows, Mac OS. - default_format = {'posix': 'gztar', - 'nt': 'zip'} - - # Establish the preferred order (for the --help-formats option). - format_commands = ['rpm', 'gztar', 'bztar', 'xztar', 'ztar', 'tar', 'zip'] - - # And the real information. - format_command = {'rpm': ('bdist_rpm', "RPM distribution"), - 'gztar': ('bdist_dumb', "gzip'ed tar file"), - 'bztar': ('bdist_dumb', "bzip2'ed tar file"), - 'xztar': ('bdist_dumb', "xz'ed tar file"), - 'ztar': ('bdist_dumb', "compressed tar file"), - 'tar': ('bdist_dumb', "tar file"), - 'zip': ('bdist_dumb', "ZIP file"), - } - - def initialize_options(self): - self.bdist_base = None - self.plat_name = None - self.formats = None - self.dist_dir = None - self.skip_build = 0 - self.group = None - self.owner = None - - def finalize_options(self): - # have to finalize 'plat_name' before 'bdist_base' - if self.plat_name is None: - if self.skip_build: - self.plat_name = get_platform() - else: - self.plat_name = self.get_finalized_command('build').plat_name - - # 'bdist_base' -- parent of per-built-distribution-format - # temporary directories (eg. we'll probably have - # "build/bdist.<plat>/dumb", "build/bdist.<plat>/rpm", etc.) - if self.bdist_base is None: - build_base = self.get_finalized_command('build').build_base - self.bdist_base = os.path.join(build_base, - 'bdist.' + self.plat_name) - - self.ensure_string_list('formats') - if self.formats is None: - try: - self.formats = [self.default_format[os.name]] - except KeyError: - raise DistutilsPlatformError( - "don't know how to create built distributions " - "on platform %s" % os.name) - - if self.dist_dir is None: - self.dist_dir = "dist" - - def run(self): - # Figure out which sub-commands we need to run. - commands = [] - for format in self.formats: - try: - commands.append(self.format_command[format][0]) - except KeyError: - raise DistutilsOptionError("invalid format '%s'" % format) - - # Reinitialize and run each command. - for i in range(len(self.formats)): - cmd_name = commands[i] - sub_cmd = self.reinitialize_command(cmd_name) - if cmd_name not in self.no_format_option: - sub_cmd.format = self.formats[i] - - # passing the owner and group names for tar archiving - if cmd_name == 'bdist_dumb': - sub_cmd.owner = self.owner - sub_cmd.group = self.group - - # If we're going to need to run this command again, tell it to - # keep its temporary files around so subsequent runs go faster. - if cmd_name in commands[i+1:]: - sub_cmd.keep_temp = 1 - self.run_command(cmd_name) diff --git a/Lib/distutils/command/bdist_dumb.py b/Lib/distutils/command/bdist_dumb.py deleted file mode 100644 index f0d6b5b8..00000000 --- a/Lib/distutils/command/bdist_dumb.py +++ /dev/null @@ -1,123 +0,0 @@ -"""distutils.command.bdist_dumb - -Implements the Distutils 'bdist_dumb' command (create a "dumb" built -distribution -- i.e., just an archive to be unpacked under $prefix or -$exec_prefix).""" - -import os -from distutils.core import Command -from distutils.util import get_platform -from distutils.dir_util import remove_tree, ensure_relative -from distutils.errors import * -from distutils.sysconfig import get_python_version -from distutils import log - -class bdist_dumb(Command): - - description = "create a \"dumb\" built distribution" - - user_options = [('bdist-dir=', 'd', - "temporary directory for creating the distribution"), - ('plat-name=', 'p', - "platform name to embed in generated filenames " - "(default: %s)" % get_platform()), - ('format=', 'f', - "archive format to create (tar, gztar, bztar, xztar, " - "ztar, zip)"), - ('keep-temp', 'k', - "keep the pseudo-installation tree around after " + - "creating the distribution archive"), - ('dist-dir=', 'd', - "directory to put final built distributions in"), - ('skip-build', None, - "skip rebuilding everything (for testing/debugging)"), - ('relative', None, - "build the archive using relative paths " - "(default: false)"), - ('owner=', 'u', - "Owner name used when creating a tar file" - " [default: current user]"), - ('group=', 'g', - "Group name used when creating a tar file" - " [default: current group]"), - ] - - boolean_options = ['keep-temp', 'skip-build', 'relative'] - - default_format = { 'posix': 'gztar', - 'nt': 'zip' } - - def initialize_options(self): - self.bdist_dir = None - self.plat_name = None - self.format = None - self.keep_temp = 0 - self.dist_dir = None - self.skip_build = None - self.relative = 0 - self.owner = None - self.group = None - - def finalize_options(self): - if self.bdist_dir is None: - bdist_base = self.get_finalized_command('bdist').bdist_base - self.bdist_dir = os.path.join(bdist_base, 'dumb') - - if self.format is None: - try: - self.format = self.default_format[os.name] - except KeyError: - raise DistutilsPlatformError( - "don't know how to create dumb built distributions " - "on platform %s" % os.name) - - self.set_undefined_options('bdist', - ('dist_dir', 'dist_dir'), - ('plat_name', 'plat_name'), - ('skip_build', 'skip_build')) - - def run(self): - if not self.skip_build: - self.run_command('build') - - install = self.reinitialize_command('install', reinit_subcommands=1) - install.root = self.bdist_dir - install.skip_build = self.skip_build - install.warn_dir = 0 - - log.info("installing to %s", self.bdist_dir) - self.run_command('install') - - # And make an archive relative to the root of the - # pseudo-installation tree. - archive_basename = "%s.%s" % (self.distribution.get_fullname(), - self.plat_name) - - pseudoinstall_root = os.path.join(self.dist_dir, archive_basename) - if not self.relative: - archive_root = self.bdist_dir - else: - if (self.distribution.has_ext_modules() and - (install.install_base != install.install_platbase)): - raise DistutilsPlatformError( - "can't make a dumb built distribution where " - "base and platbase are different (%s, %s)" - % (repr(install.install_base), - repr(install.install_platbase))) - else: - archive_root = os.path.join(self.bdist_dir, - ensure_relative(install.install_base)) - - # Make the archive - filename = self.make_archive(pseudoinstall_root, - self.format, root_dir=archive_root, - owner=self.owner, group=self.group) - if self.distribution.has_ext_modules(): - pyversion = get_python_version() - else: - pyversion = 'any' - self.distribution.dist_files.append(('bdist_dumb', pyversion, - filename)) - - if not self.keep_temp: - remove_tree(self.bdist_dir, dry_run=self.dry_run) diff --git a/Lib/distutils/command/bdist_rpm.py b/Lib/distutils/command/bdist_rpm.py deleted file mode 100644 index 550cbfa1..00000000 --- a/Lib/distutils/command/bdist_rpm.py +++ /dev/null @@ -1,579 +0,0 @@ -"""distutils.command.bdist_rpm - -Implements the Distutils 'bdist_rpm' command (create RPM source and binary -distributions).""" - -import subprocess, sys, os -from distutils.core import Command -from distutils.debug import DEBUG -from distutils.file_util import write_file -from distutils.errors import * -from distutils.sysconfig import get_python_version -from distutils import log - -class bdist_rpm(Command): - - description = "create an RPM distribution" - - user_options = [ - ('bdist-base=', None, - "base directory for creating built distributions"), - ('rpm-base=', None, - "base directory for creating RPMs (defaults to \"rpm\" under " - "--bdist-base; must be specified for RPM 2)"), - ('dist-dir=', 'd', - "directory to put final RPM files in " - "(and .spec files if --spec-only)"), - ('python=', None, - "path to Python interpreter to hard-code in the .spec file " - "(default: \"python\")"), - ('fix-python', None, - "hard-code the exact path to the current Python interpreter in " - "the .spec file"), - ('spec-only', None, - "only regenerate spec file"), - ('source-only', None, - "only generate source RPM"), - ('binary-only', None, - "only generate binary RPM"), - ('use-bzip2', None, - "use bzip2 instead of gzip to create source distribution"), - - # More meta-data: too RPM-specific to put in the setup script, - # but needs to go in the .spec file -- so we make these options - # to "bdist_rpm". The idea is that packagers would put this - # info in setup.cfg, although they are of course free to - # supply it on the command line. - ('distribution-name=', None, - "name of the (Linux) distribution to which this " - "RPM applies (*not* the name of the module distribution!)"), - ('group=', None, - "package classification [default: \"Development/Libraries\"]"), - ('release=', None, - "RPM release number"), - ('serial=', None, - "RPM serial number"), - ('vendor=', None, - "RPM \"vendor\" (eg. \"Joe Blow <joe@example.com>\") " - "[default: maintainer or author from setup script]"), - ('packager=', None, - "RPM packager (eg. \"Jane Doe <jane@example.net>\") " - "[default: vendor]"), - ('doc-files=', None, - "list of documentation files (space or comma-separated)"), - ('changelog=', None, - "RPM changelog"), - ('icon=', None, - "name of icon file"), - ('provides=', None, - "capabilities provided by this package"), - ('requires=', None, - "capabilities required by this package"), - ('conflicts=', None, - "capabilities which conflict with this package"), - ('build-requires=', None, - "capabilities required to build this package"), - ('obsoletes=', None, - "capabilities made obsolete by this package"), - ('no-autoreq', None, - "do not automatically calculate dependencies"), - - # Actions to take when building RPM - ('keep-temp', 'k', - "don't clean up RPM build directory"), - ('no-keep-temp', None, - "clean up RPM build directory [default]"), - ('use-rpm-opt-flags', None, - "compile with RPM_OPT_FLAGS when building from source RPM"), - ('no-rpm-opt-flags', None, - "do not pass any RPM CFLAGS to compiler"), - ('rpm3-mode', None, - "RPM 3 compatibility mode (default)"), - ('rpm2-mode', None, - "RPM 2 compatibility mode"), - - # Add the hooks necessary for specifying custom scripts - ('prep-script=', None, - "Specify a script for the PREP phase of RPM building"), - ('build-script=', None, - "Specify a script for the BUILD phase of RPM building"), - - ('pre-install=', None, - "Specify a script for the pre-INSTALL phase of RPM building"), - ('install-script=', None, - "Specify a script for the INSTALL phase of RPM building"), - ('post-install=', None, - "Specify a script for the post-INSTALL phase of RPM building"), - - ('pre-uninstall=', None, - "Specify a script for the pre-UNINSTALL phase of RPM building"), - ('post-uninstall=', None, - "Specify a script for the post-UNINSTALL phase of RPM building"), - - ('clean-script=', None, - "Specify a script for the CLEAN phase of RPM building"), - - ('verify-script=', None, - "Specify a script for the VERIFY phase of the RPM build"), - - # Allow a packager to explicitly force an architecture - ('force-arch=', None, - "Force an architecture onto the RPM build process"), - - ('quiet', 'q', - "Run the INSTALL phase of RPM building in quiet mode"), - ] - - boolean_options = ['keep-temp', 'use-rpm-opt-flags', 'rpm3-mode', - 'no-autoreq', 'quiet'] - - negative_opt = {'no-keep-temp': 'keep-temp', - 'no-rpm-opt-flags': 'use-rpm-opt-flags', - 'rpm2-mode': 'rpm3-mode'} - - - def initialize_options(self): - self.bdist_base = None - self.rpm_base = None - self.dist_dir = None - self.python = None - self.fix_python = None - self.spec_only = None - self.binary_only = None - self.source_only = None - self.use_bzip2 = None - - self.distribution_name = None - self.group = None - self.release = None - self.serial = None - self.vendor = None - self.packager = None - self.doc_files = None - self.changelog = None - self.icon = None - - self.prep_script = None - self.build_script = None - self.install_script = None - self.clean_script = None - self.verify_script = None - self.pre_install = None - self.post_install = None - self.pre_uninstall = None - self.post_uninstall = None - self.prep = None - self.provides = None - self.requires = None - self.conflicts = None - self.build_requires = None - self.obsoletes = None - - self.keep_temp = 0 - self.use_rpm_opt_flags = 1 - self.rpm3_mode = 1 - self.no_autoreq = 0 - - self.force_arch = None - self.quiet = 0 - - def finalize_options(self): - self.set_undefined_options('bdist', ('bdist_base', 'bdist_base')) - if self.rpm_base is None: - if not self.rpm3_mode: - raise DistutilsOptionError( - "you must specify --rpm-base in RPM 2 mode") - self.rpm_base = os.path.join(self.bdist_base, "rpm") - - if self.python is None: - if self.fix_python: - self.python = sys.executable - else: - self.python = "python3" - elif self.fix_python: - raise DistutilsOptionError( - "--python and --fix-python are mutually exclusive options") - - if os.name != 'posix': - raise DistutilsPlatformError("don't know how to create RPM " - "distributions on platform %s" % os.name) - if self.binary_only and self.source_only: - raise DistutilsOptionError( - "cannot supply both '--source-only' and '--binary-only'") - - # don't pass CFLAGS to pure python distributions - if not self.distribution.has_ext_modules(): - self.use_rpm_opt_flags = 0 - - self.set_undefined_options('bdist', ('dist_dir', 'dist_dir')) - self.finalize_package_data() - - def finalize_package_data(self): - self.ensure_string('group', "Development/Libraries") - self.ensure_string('vendor', - "%s <%s>" % (self.distribution.get_contact(), - self.distribution.get_contact_email())) - self.ensure_string('packager') - self.ensure_string_list('doc_files') - if isinstance(self.doc_files, list): - for readme in ('README', 'README.txt'): - if os.path.exists(readme) and readme not in self.doc_files: - self.doc_files.append(readme) - - self.ensure_string('release', "1") - self.ensure_string('serial') # should it be an int? - - self.ensure_string('distribution_name') - - self.ensure_string('changelog') - # Format changelog correctly - self.changelog = self._format_changelog(self.changelog) - - self.ensure_filename('icon') - - self.ensure_filename('prep_script') - self.ensure_filename('build_script') - self.ensure_filename('install_script') - self.ensure_filename('clean_script') - self.ensure_filename('verify_script') - self.ensure_filename('pre_install') - self.ensure_filename('post_install') - self.ensure_filename('pre_uninstall') - self.ensure_filename('post_uninstall') - - # XXX don't forget we punted on summaries and descriptions -- they - # should be handled here eventually! - - # Now *this* is some meta-data that belongs in the setup script... - self.ensure_string_list('provides') - self.ensure_string_list('requires') - self.ensure_string_list('conflicts') - self.ensure_string_list('build_requires') - self.ensure_string_list('obsoletes') - - self.ensure_string('force_arch') - - def run(self): - if DEBUG: - print("before _get_package_data():") - print("vendor =", self.vendor) - print("packager =", self.packager) - print("doc_files =", self.doc_files) - print("changelog =", self.changelog) - - # make directories - if self.spec_only: - spec_dir = self.dist_dir - self.mkpath(spec_dir) - else: - rpm_dir = {} - for d in ('SOURCES', 'SPECS', 'BUILD', 'RPMS', 'SRPMS'): - rpm_dir[d] = os.path.join(self.rpm_base, d) - self.mkpath(rpm_dir[d]) - spec_dir = rpm_dir['SPECS'] - - # Spec file goes into 'dist_dir' if '--spec-only specified', - # build/rpm.<plat> otherwise. - spec_path = os.path.join(spec_dir, - "%s.spec" % self.distribution.get_name()) - self.execute(write_file, - (spec_path, - self._make_spec_file()), - "writing '%s'" % spec_path) - - if self.spec_only: # stop if requested - return - - # Make a source distribution and copy to SOURCES directory with - # optional icon. - saved_dist_files = self.distribution.dist_files[:] - sdist = self.reinitialize_command('sdist') - if self.use_bzip2: - sdist.formats = ['bztar'] - else: - sdist.formats = ['gztar'] - self.run_command('sdist') - self.distribution.dist_files = saved_dist_files - - source = sdist.get_archive_files()[0] - source_dir = rpm_dir['SOURCES'] - self.copy_file(source, source_dir) - - if self.icon: - if os.path.exists(self.icon): - self.copy_file(self.icon, source_dir) - else: - raise DistutilsFileError( - "icon file '%s' does not exist" % self.icon) - - # build package - log.info("building RPMs") - rpm_cmd = ['rpmbuild'] - - if self.source_only: # what kind of RPMs? - rpm_cmd.append('-bs') - elif self.binary_only: - rpm_cmd.append('-bb') - else: - rpm_cmd.append('-ba') - rpm_cmd.extend(['--define', '__python %s' % self.python]) - if self.rpm3_mode: - rpm_cmd.extend(['--define', - '_topdir %s' % os.path.abspath(self.rpm_base)]) - if not self.keep_temp: - rpm_cmd.append('--clean') - - if self.quiet: - rpm_cmd.append('--quiet') - - rpm_cmd.append(spec_path) - # Determine the binary rpm names that should be built out of this spec - # file - # Note that some of these may not be really built (if the file - # list is empty) - nvr_string = "%{name}-%{version}-%{release}" - src_rpm = nvr_string + ".src.rpm" - non_src_rpm = "%{arch}/" + nvr_string + ".%{arch}.rpm" - q_cmd = r"rpm -q --qf '%s %s\n' --specfile '%s'" % ( - src_rpm, non_src_rpm, spec_path) - - out = os.popen(q_cmd) - try: - binary_rpms = [] - source_rpm = None - while True: - line = out.readline() - if not line: - break - l = line.strip().split() - assert(len(l) == 2) - binary_rpms.append(l[1]) - # The source rpm is named after the first entry in the spec file - if source_rpm is None: - source_rpm = l[0] - - status = out.close() - if status: - raise DistutilsExecError("Failed to execute: %s" % repr(q_cmd)) - - finally: - out.close() - - self.spawn(rpm_cmd) - - if not self.dry_run: - if self.distribution.has_ext_modules(): - pyversion = get_python_version() - else: - pyversion = 'any' - - if not self.binary_only: - srpm = os.path.join(rpm_dir['SRPMS'], source_rpm) - assert(os.path.exists(srpm)) - self.move_file(srpm, self.dist_dir) - filename = os.path.join(self.dist_dir, source_rpm) - self.distribution.dist_files.append( - ('bdist_rpm', pyversion, filename)) - - if not self.source_only: - for rpm in binary_rpms: - rpm = os.path.join(rpm_dir['RPMS'], rpm) - if os.path.exists(rpm): - self.move_file(rpm, self.dist_dir) - filename = os.path.join(self.dist_dir, - os.path.basename(rpm)) - self.distribution.dist_files.append( - ('bdist_rpm', pyversion, filename)) - - def _dist_path(self, path): - return os.path.join(self.dist_dir, os.path.basename(path)) - - def _make_spec_file(self): - """Generate the text of an RPM spec file and return it as a - list of strings (one per line). - """ - # definitions and headers - spec_file = [ - '%define name ' + self.distribution.get_name(), - '%define version ' + self.distribution.get_version().replace('-','_'), - '%define unmangled_version ' + self.distribution.get_version(), - '%define release ' + self.release.replace('-','_'), - '', - 'Summary: ' + self.distribution.get_description(), - ] - - # Workaround for #14443 which affects some RPM based systems such as - # RHEL6 (and probably derivatives) - vendor_hook = subprocess.getoutput('rpm --eval %{__os_install_post}') - # Generate a potential replacement value for __os_install_post (whilst - # normalizing the whitespace to simplify the test for whether the - # invocation of brp-python-bytecompile passes in __python): - vendor_hook = '\n'.join([' %s \\' % line.strip() - for line in vendor_hook.splitlines()]) - problem = "brp-python-bytecompile \\\n" - fixed = "brp-python-bytecompile %{__python} \\\n" - fixed_hook = vendor_hook.replace(problem, fixed) - if fixed_hook != vendor_hook: - spec_file.append('# Workaround for http://bugs.python.org/issue14443') - spec_file.append('%define __os_install_post ' + fixed_hook + '\n') - - # put locale summaries into spec file - # XXX not supported for now (hard to put a dictionary - # in a config file -- arg!) - #for locale in self.summaries.keys(): - # spec_file.append('Summary(%s): %s' % (locale, - # self.summaries[locale])) - - spec_file.extend([ - 'Name: %{name}', - 'Version: %{version}', - 'Release: %{release}',]) - - # XXX yuck! this filename is available from the "sdist" command, - # but only after it has run: and we create the spec file before - # running "sdist", in case of --spec-only. - if self.use_bzip2: - spec_file.append('Source0: %{name}-%{unmangled_version}.tar.bz2') - else: - spec_file.append('Source0: %{name}-%{unmangled_version}.tar.gz') - - spec_file.extend([ - 'License: ' + self.distribution.get_license(), - 'Group: ' + self.group, - 'BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot', - 'Prefix: %{_prefix}', ]) - - if not self.force_arch: - # noarch if no extension modules - if not self.distribution.has_ext_modules(): - spec_file.append('BuildArch: noarch') - else: - spec_file.append( 'BuildArch: %s' % self.force_arch ) - - for field in ('Vendor', - 'Packager', - 'Provides', - 'Requires', - 'Conflicts', - 'Obsoletes', - ): - val = getattr(self, field.lower()) - if isinstance(val, list): - spec_file.append('%s: %s' % (field, ' '.join(val))) - elif val is not None: - spec_file.append('%s: %s' % (field, val)) - - - if self.distribution.get_url() != 'UNKNOWN': - spec_file.append('Url: ' + self.distribution.get_url()) - - if self.distribution_name: - spec_file.append('Distribution: ' + self.distribution_name) - - if self.build_requires: - spec_file.append('BuildRequires: ' + - ' '.join(self.build_requires)) - - if self.icon: - spec_file.append('Icon: ' + os.path.basename(self.icon)) - - if self.no_autoreq: - spec_file.append('AutoReq: 0') - - spec_file.extend([ - '', - '%description', - self.distribution.get_long_description() - ]) - - # put locale descriptions into spec file - # XXX again, suppressed because config file syntax doesn't - # easily support this ;-( - #for locale in self.descriptions.keys(): - # spec_file.extend([ - # '', - # '%description -l ' + locale, - # self.descriptions[locale], - # ]) - - # rpm scripts - # figure out default build script - def_setup_call = "%s %s" % (self.python,os.path.basename(sys.argv[0])) - def_build = "%s build" % def_setup_call - if self.use_rpm_opt_flags: - def_build = 'env CFLAGS="$RPM_OPT_FLAGS" ' + def_build - - # insert contents of files - - # XXX this is kind of misleading: user-supplied options are files - # that we open and interpolate into the spec file, but the defaults - # are just text that we drop in as-is. Hmmm. - - install_cmd = ('%s install -O1 --root=$RPM_BUILD_ROOT ' - '--record=INSTALLED_FILES') % def_setup_call - - script_options = [ - ('prep', 'prep_script', "%setup -n %{name}-%{unmangled_version}"), - ('build', 'build_script', def_build), - ('install', 'install_script', install_cmd), - ('clean', 'clean_script', "rm -rf $RPM_BUILD_ROOT"), - ('verifyscript', 'verify_script', None), - ('pre', 'pre_install', None), - ('post', 'post_install', None), - ('preun', 'pre_uninstall', None), - ('postun', 'post_uninstall', None), - ] - - for (rpm_opt, attr, default) in script_options: - # Insert contents of file referred to, if no file is referred to - # use 'default' as contents of script - val = getattr(self, attr) - if val or default: - spec_file.extend([ - '', - '%' + rpm_opt,]) - if val: - with open(val) as f: - spec_file.extend(f.read().split('\n')) - else: - spec_file.append(default) - - - # files section - spec_file.extend([ - '', - '%files -f INSTALLED_FILES', - '%defattr(-,root,root)', - ]) - - if self.doc_files: - spec_file.append('%doc ' + ' '.join(self.doc_files)) - - if self.changelog: - spec_file.extend([ - '', - '%changelog',]) - spec_file.extend(self.changelog) - - return spec_file - - def _format_changelog(self, changelog): - """Format the changelog correctly and convert it to a list of strings - """ - if not changelog: - return changelog - new_changelog = [] - for line in changelog.strip().split('\n'): - line = line.strip() - if line[0] == '*': - new_changelog.extend(['', line]) - elif line[0] == '-': - new_changelog.append(line) - else: - new_changelog.append(' ' + line) - - # strip trailing newline inserted by first changelog entry - if not new_changelog[0]: - del new_changelog[0] - - return new_changelog diff --git a/Lib/distutils/command/build.py b/Lib/distutils/command/build.py deleted file mode 100644 index a86df0bc..00000000 --- a/Lib/distutils/command/build.py +++ /dev/null @@ -1,157 +0,0 @@ -"""distutils.command.build - -Implements the Distutils 'build' command.""" - -import sys, os -from distutils.core import Command -from distutils.errors import DistutilsOptionError -from distutils.util import get_platform - - -def show_compilers(): - from distutils.ccompiler import show_compilers - show_compilers() - - -class build(Command): - - description = "build everything needed to install" - - user_options = [ - ('build-base=', 'b', - "base directory for build library"), - ('build-purelib=', None, - "build directory for platform-neutral distributions"), - ('build-platlib=', None, - "build directory for platform-specific distributions"), - ('build-lib=', None, - "build directory for all distribution (defaults to either " + - "build-purelib or build-platlib"), - ('build-scripts=', None, - "build directory for scripts"), - ('build-temp=', 't', - "temporary build directory"), - ('plat-name=', 'p', - "platform name to build for, if supported " - "(default: %s)" % get_platform()), - ('compiler=', 'c', - "specify the compiler type"), - ('parallel=', 'j', - "number of parallel build jobs"), - ('debug', 'g', - "compile extensions and libraries with debugging information"), - ('force', 'f', - "forcibly build everything (ignore file timestamps)"), - ('executable=', 'e', - "specify final destination interpreter path (build.py)"), - ] - - boolean_options = ['debug', 'force'] - - help_options = [ - ('help-compiler', None, - "list available compilers", show_compilers), - ] - - def initialize_options(self): - self.build_base = 'build' - # these are decided only after 'build_base' has its final value - # (unless overridden by the user or client) - self.build_purelib = None - self.build_platlib = None - self.build_lib = None - self.build_temp = None - self.build_scripts = None - self.compiler = None - self.plat_name = None - self.debug = None - self.force = 0 - self.executable = None - self.parallel = None - - def finalize_options(self): - if self.plat_name is None: - self.plat_name = get_platform() - else: - # plat-name only supported for windows (other platforms are - # supported via ./configure flags, if at all). Avoid misleading - # other platforms. - if os.name != 'nt': - raise DistutilsOptionError( - "--plat-name only supported on Windows (try " - "using './configure --help' on your platform)") - - plat_specifier = ".%s-%d.%d" % (self.plat_name, *sys.version_info[:2]) - - # Make it so Python 2.x and Python 2.x with --with-pydebug don't - # share the same build directories. Doing so confuses the build - # process for C modules - if hasattr(sys, 'gettotalrefcount'): - plat_specifier += '-pydebug' - - # 'build_purelib' and 'build_platlib' just default to 'lib' and - # 'lib.<plat>' under the base build directory. We only use one of - # them for a given distribution, though -- - if self.build_purelib is None: - self.build_purelib = os.path.join(self.build_base, 'lib') - if self.build_platlib is None: - self.build_platlib = os.path.join(self.build_base, - 'lib' + plat_specifier) - - # 'build_lib' is the actual directory that we will use for this - # particular module distribution -- if user didn't supply it, pick - # one of 'build_purelib' or 'build_platlib'. - if self.build_lib is None: - if self.distribution.ext_modules: - self.build_lib = self.build_platlib - else: - self.build_lib = self.build_purelib - - # 'build_temp' -- temporary directory for compiler turds, - # "build/temp.<plat>" - if self.build_temp is None: - self.build_temp = os.path.join(self.build_base, - 'temp' + plat_specifier) - if self.build_scripts is None: - self.build_scripts = os.path.join(self.build_base, - 'scripts-%d.%d' % sys.version_info[:2]) - - if self.executable is None and sys.executable: - self.executable = os.path.normpath(sys.executable) - - if isinstance(self.parallel, str): - try: - self.parallel = int(self.parallel) - except ValueError: - raise DistutilsOptionError("parallel should be an integer") - - def run(self): - # Run all relevant sub-commands. This will be some subset of: - # - build_py - pure Python modules - # - build_clib - standalone C libraries - # - build_ext - Python extensions - # - build_scripts - (Python) scripts - for cmd_name in self.get_sub_commands(): - self.run_command(cmd_name) - - - # -- Predicates for the sub-command list --------------------------- - - def has_pure_modules(self): - return self.distribution.has_pure_modules() - - def has_c_libraries(self): - return self.distribution.has_c_libraries() - - def has_ext_modules(self): - return self.distribution.has_ext_modules() - - def has_scripts(self): - return self.distribution.has_scripts() - - - sub_commands = [('build_py', has_pure_modules), - ('build_clib', has_c_libraries), - ('build_ext', has_ext_modules), - ('build_scripts', has_scripts), - ] diff --git a/Lib/distutils/command/build_clib.py b/Lib/distutils/command/build_clib.py deleted file mode 100644 index 3e20ef23..00000000 --- a/Lib/distutils/command/build_clib.py +++ /dev/null @@ -1,209 +0,0 @@ -"""distutils.command.build_clib - -Implements the Distutils 'build_clib' command, to build a C/C++ library -that is included in the module distribution and needed by an extension -module.""" - - -# XXX this module has *lots* of code ripped-off quite transparently from -# build_ext.py -- not surprisingly really, as the work required to build -# a static library from a collection of C source files is not really all -# that different from what's required to build a shared object file from -# a collection of C source files. Nevertheless, I haven't done the -# necessary refactoring to account for the overlap in code between the -# two modules, mainly because a number of subtle details changed in the -# cut 'n paste. Sigh. - -import os -from distutils.core import Command -from distutils.errors import * -from distutils.sysconfig import customize_compiler -from distutils import log - -def show_compilers(): - from distutils.ccompiler import show_compilers - show_compilers() - - -class build_clib(Command): - - description = "build C/C++ libraries used by Python extensions" - - user_options = [ - ('build-clib=', 'b', - "directory to build C/C++ libraries to"), - ('build-temp=', 't', - "directory to put temporary build by-products"), - ('debug', 'g', - "compile with debugging information"), - ('force', 'f', - "forcibly build everything (ignore file timestamps)"), - ('compiler=', 'c', - "specify the compiler type"), - ] - - boolean_options = ['debug', 'force'] - - help_options = [ - ('help-compiler', None, - "list available compilers", show_compilers), - ] - - def initialize_options(self): - self.build_clib = None - self.build_temp = None - - # List of libraries to build - self.libraries = None - - # Compilation options for all libraries - self.include_dirs = None - self.define = None - self.undef = None - self.debug = None - self.force = 0 - self.compiler = None - - - def finalize_options(self): - # This might be confusing: both build-clib and build-temp default - # to build-temp as defined by the "build" command. This is because - # I think that C libraries are really just temporary build - # by-products, at least from the point of view of building Python - # extensions -- but I want to keep my options open. - self.set_undefined_options('build', - ('build_temp', 'build_clib'), - ('build_temp', 'build_temp'), - ('compiler', 'compiler'), - ('debug', 'debug'), - ('force', 'force')) - - self.libraries = self.distribution.libraries - if self.libraries: - self.check_library_list(self.libraries) - - if self.include_dirs is None: - self.include_dirs = self.distribution.include_dirs or [] - if isinstance(self.include_dirs, str): - self.include_dirs = self.include_dirs.split(os.pathsep) - - # XXX same as for build_ext -- what about 'self.define' and - # 'self.undef' ? - - - def run(self): - if not self.libraries: - return - - # Yech -- this is cut 'n pasted from build_ext.py! - from distutils.ccompiler import new_compiler - self.compiler = new_compiler(compiler=self.compiler, - dry_run=self.dry_run, - force=self.force) - customize_compiler(self.compiler) - - if self.include_dirs is not None: - self.compiler.set_include_dirs(self.include_dirs) - if self.define is not None: - # 'define' option is a list of (name,value) tuples - for (name,value) in self.define: - self.compiler.define_macro(name, value) - if self.undef is not None: - for macro in self.undef: - self.compiler.undefine_macro(macro) - - self.build_libraries(self.libraries) - - - def check_library_list(self, libraries): - """Ensure that the list of libraries is valid. - - `library` is presumably provided as a command option 'libraries'. - This method checks that it is a list of 2-tuples, where the tuples - are (library_name, build_info_dict). - - Raise DistutilsSetupError if the structure is invalid anywhere; - just returns otherwise. - """ - if not isinstance(libraries, list): - raise DistutilsSetupError( - "'libraries' option must be a list of tuples") - - for lib in libraries: - if not isinstance(lib, tuple) and len(lib) != 2: - raise DistutilsSetupError( - "each element of 'libraries' must a 2-tuple") - - name, build_info = lib - - if not isinstance(name, str): - raise DistutilsSetupError( - "first element of each tuple in 'libraries' " - "must be a string (the library name)") - - if '/' in name or (os.sep != '/' and os.sep in name): - raise DistutilsSetupError("bad library name '%s': " - "may not contain directory separators" % lib[0]) - - if not isinstance(build_info, dict): - raise DistutilsSetupError( - "second element of each tuple in 'libraries' " - "must be a dictionary (build info)") - - - def get_library_names(self): - # Assume the library list is valid -- 'check_library_list()' is - # called from 'finalize_options()', so it should be! - if not self.libraries: - return None - - lib_names = [] - for (lib_name, build_info) in self.libraries: - lib_names.append(lib_name) - return lib_names - - - def get_source_files(self): - self.check_library_list(self.libraries) - filenames = [] - for (lib_name, build_info) in self.libraries: - sources = build_info.get('sources') - if sources is None or not isinstance(sources, (list, tuple)): - raise DistutilsSetupError( - "in 'libraries' option (library '%s'), " - "'sources' must be present and must be " - "a list of source filenames" % lib_name) - - filenames.extend(sources) - return filenames - - - def build_libraries(self, libraries): - for (lib_name, build_info) in libraries: - sources = build_info.get('sources') - if sources is None or not isinstance(sources, (list, tuple)): - raise DistutilsSetupError( - "in 'libraries' option (library '%s'), " - "'sources' must be present and must be " - "a list of source filenames" % lib_name) - sources = list(sources) - - log.info("building '%s' library", lib_name) - - # First, compile the source code to object files in the library - # directory. (This should probably change to putting object - # files in a temporary build directory.) - macros = build_info.get('macros') - include_dirs = build_info.get('include_dirs') - objects = self.compiler.compile(sources, - output_dir=self.build_temp, - macros=macros, - include_dirs=include_dirs, - debug=self.debug) - - # Now "link" the object files together into a static library. - # (On Unix at least, this isn't really linking -- it just - # builds an archive. Whatever.) - self.compiler.create_static_lib(objects, lib_name, - output_dir=self.build_clib, - debug=self.debug) diff --git a/Lib/distutils/command/build_ext.py b/Lib/distutils/command/build_ext.py deleted file mode 100644 index f287b349..00000000 --- a/Lib/distutils/command/build_ext.py +++ /dev/null @@ -1,754 +0,0 @@ -"""distutils.command.build_ext - -Implements the Distutils 'build_ext' command, for building extension -modules (currently limited to C extensions, should accommodate C++ -extensions ASAP).""" - -import contextlib -import os -import re -import sys -from distutils.core import Command -from distutils.errors import * -from distutils.sysconfig import customize_compiler, get_python_version -from distutils.sysconfig import get_config_h_filename -from distutils.dep_util import newer_group -from distutils.extension import Extension -from distutils.util import get_platform -from distutils import log - -from site import USER_BASE - -# An extension name is just a dot-separated list of Python NAMEs (ie. -# the same as a fully-qualified module name). -extension_name_re = re.compile \ - (r'^[a-zA-Z_][a-zA-Z_0-9]*(\.[a-zA-Z_][a-zA-Z_0-9]*)*$') - - -def show_compilers (): - from distutils.ccompiler import show_compilers - show_compilers() - - -class build_ext(Command): - - description = "build C/C++ extensions (compile/link to build directory)" - - # XXX thoughts on how to deal with complex command-line options like - # these, i.e. how to make it so fancy_getopt can suck them off the - # command line and make it look like setup.py defined the appropriate - # lists of tuples of what-have-you. - # - each command needs a callback to process its command-line options - # - Command.__init__() needs access to its share of the whole - # command line (must ultimately come from - # Distribution.parse_command_line()) - # - it then calls the current command class' option-parsing - # callback to deal with weird options like -D, which have to - # parse the option text and churn out some custom data - # structure - # - that data structure (in this case, a list of 2-tuples) - # will then be present in the command object by the time - # we get to finalize_options() (i.e. the constructor - # takes care of both command-line and client options - # in between initialize_options() and finalize_options()) - - sep_by = " (separated by '%s')" % os.pathsep - user_options = [ - ('build-lib=', 'b', - "directory for compiled extension modules"), - ('build-temp=', 't', - "directory for temporary files (build by-products)"), - ('plat-name=', 'p', - "platform name to cross-compile for, if supported " - "(default: %s)" % get_platform()), - ('inplace', 'i', - "ignore build-lib and put compiled extensions into the source " + - "directory alongside your pure Python modules"), - ('include-dirs=', 'I', - "list of directories to search for header files" + sep_by), - ('define=', 'D', - "C preprocessor macros to define"), - ('undef=', 'U', - "C preprocessor macros to undefine"), - ('libraries=', 'l', - "external C libraries to link with"), - ('library-dirs=', 'L', - "directories to search for external C libraries" + sep_by), - ('rpath=', 'R', - "directories to search for shared C libraries at runtime"), - ('link-objects=', 'O', - "extra explicit link objects to include in the link"), - ('debug', 'g', - "compile/link with debugging information"), - ('force', 'f', - "forcibly build everything (ignore file timestamps)"), - ('compiler=', 'c', - "specify the compiler type"), - ('parallel=', 'j', - "number of parallel build jobs"), - ('swig-cpp', None, - "make SWIG create C++ files (default is C)"), - ('swig-opts=', None, - "list of SWIG command line options"), - ('swig=', None, - "path to the SWIG executable"), - ('user', None, - "add user include, library and rpath") - ] - - boolean_options = ['inplace', 'debug', 'force', 'swig-cpp', 'user'] - - help_options = [ - ('help-compiler', None, - "list available compilers", show_compilers), - ] - - def initialize_options(self): - self.extensions = None - self.build_lib = None - self.plat_name = None - self.build_temp = None - self.inplace = 0 - self.package = None - - self.include_dirs = None - self.define = None - self.undef = None - self.libraries = None - self.library_dirs = None - self.rpath = None - self.link_objects = None - self.debug = None - self.force = None - self.compiler = None - self.swig = None - self.swig_cpp = None - self.swig_opts = None - self.user = None - self.parallel = None - - def finalize_options(self): - from distutils import sysconfig - - self.set_undefined_options('build', - ('build_lib', 'build_lib'), - ('build_temp', 'build_temp'), - ('compiler', 'compiler'), - ('debug', 'debug'), - ('force', 'force'), - ('parallel', 'parallel'), - ('plat_name', 'plat_name'), - ) - - if self.package is None: - self.package = self.distribution.ext_package - - self.extensions = self.distribution.ext_modules - - # Make sure Python's include directories (for Python.h, pyconfig.h, - # etc.) are in the include search path. - py_include = sysconfig.get_python_inc() - plat_py_include = sysconfig.get_python_inc(plat_specific=1) - if self.include_dirs is None: - self.include_dirs = self.distribution.include_dirs or [] - if isinstance(self.include_dirs, str): - self.include_dirs = self.include_dirs.split(os.pathsep) - - # If in a virtualenv, add its include directory - # Issue 16116 - if sys.exec_prefix != sys.base_exec_prefix: - self.include_dirs.append(os.path.join(sys.exec_prefix, 'include')) - - # Put the Python "system" include dir at the end, so that - # any local include dirs take precedence. - self.include_dirs.extend(py_include.split(os.path.pathsep)) - if plat_py_include != py_include: - self.include_dirs.extend( - plat_py_include.split(os.path.pathsep)) - - self.ensure_string_list('libraries') - self.ensure_string_list('link_objects') - - # Life is easier if we're not forever checking for None, so - # simplify these options to empty lists if unset - if self.libraries is None: - self.libraries = [] - if self.library_dirs is None: - self.library_dirs = [] - elif isinstance(self.library_dirs, str): - self.library_dirs = self.library_dirs.split(os.pathsep) - - if self.rpath is None: - self.rpath = [] - elif isinstance(self.rpath, str): - self.rpath = self.rpath.split(os.pathsep) - - # for extensions under windows use different directories - # for Release and Debug builds. - # also Python's library directory must be appended to library_dirs - if os.name == 'nt': - # the 'libs' directory is for binary installs - we assume that - # must be the *native* platform. But we don't really support - # cross-compiling via a binary install anyway, so we let it go. - self.library_dirs.append(os.path.join(sys.exec_prefix, 'libs')) - if sys.base_exec_prefix != sys.prefix: # Issue 16116 - self.library_dirs.append(os.path.join(sys.base_exec_prefix, 'libs')) - if self.debug: - self.build_temp = os.path.join(self.build_temp, "Debug") - else: - self.build_temp = os.path.join(self.build_temp, "Release") - - # Append the source distribution include and library directories, - # this allows distutils on windows to work in the source tree - self.include_dirs.append(os.path.dirname(get_config_h_filename())) - _sys_home = getattr(sys, '_home', None) - if _sys_home: - self.library_dirs.append(_sys_home) - - # Use the .lib files for the correct architecture - if self.plat_name == 'win32': - suffix = 'win32' - else: - # win-amd64 - suffix = self.plat_name[4:] - new_lib = os.path.join(sys.exec_prefix, 'PCbuild') - if suffix: - new_lib = os.path.join(new_lib, suffix) - self.library_dirs.append(new_lib) - - # For extensions under Cygwin, Python's library directory must be - # appended to library_dirs - if sys.platform[:6] == 'cygwin': - if sys.executable.startswith(os.path.join(sys.exec_prefix, "bin")): - # building third party extensions - self.library_dirs.append(os.path.join(sys.prefix, "lib", - "python" + get_python_version(), - "config")) - else: - # building python standard extensions - self.library_dirs.append('.') - - # For building extensions with a shared Python library, - # Python's library directory must be appended to library_dirs - # See Issues: #1600860, #4366 - if (sysconfig.get_config_var('Py_ENABLE_SHARED')): - if not sysconfig.python_build: - # building third party extensions - self.library_dirs.append(sysconfig.get_config_var('LIBDIR')) - else: - # building python standard extensions - self.library_dirs.append('.') - - # The argument parsing will result in self.define being a string, but - # it has to be a list of 2-tuples. All the preprocessor symbols - # specified by the 'define' option will be set to '1'. Multiple - # symbols can be separated with commas. - - if self.define: - defines = self.define.split(',') - self.define = [(symbol, '1') for symbol in defines] - - # The option for macros to undefine is also a string from the - # option parsing, but has to be a list. Multiple symbols can also - # be separated with commas here. - if self.undef: - self.undef = self.undef.split(',') - - if self.swig_opts is None: - self.swig_opts = [] - else: - self.swig_opts = self.swig_opts.split(' ') - - # Finally add the user include and library directories if requested - if self.user: - user_include = os.path.join(USER_BASE, "include") - user_lib = os.path.join(USER_BASE, "lib") - if os.path.isdir(user_include): - self.include_dirs.append(user_include) - if os.path.isdir(user_lib): - self.library_dirs.append(user_lib) - self.rpath.append(user_lib) - - if isinstance(self.parallel, str): - try: - self.parallel = int(self.parallel) - except ValueError: - raise DistutilsOptionError("parallel should be an integer") - - def run(self): - from distutils.ccompiler import new_compiler - - # 'self.extensions', as supplied by setup.py, is a list of - # Extension instances. See the documentation for Extension (in - # distutils.extension) for details. - # - # For backwards compatibility with Distutils 0.8.2 and earlier, we - # also allow the 'extensions' list to be a list of tuples: - # (ext_name, build_info) - # where build_info is a dictionary containing everything that - # Extension instances do except the name, with a few things being - # differently named. We convert these 2-tuples to Extension - # instances as needed. - - if not self.extensions: - return - - # If we were asked to build any C/C++ libraries, make sure that the - # directory where we put them is in the library search path for - # linking extensions. - if self.distribution.has_c_libraries(): - build_clib = self.get_finalized_command('build_clib') - self.libraries.extend(build_clib.get_library_names() or []) - self.library_dirs.append(build_clib.build_clib) - - # Setup the CCompiler object that we'll use to do all the - # compiling and linking - self.compiler = new_compiler(compiler=self.compiler, - verbose=self.verbose, - dry_run=self.dry_run, - force=self.force) - customize_compiler(self.compiler) - # If we are cross-compiling, init the compiler now (if we are not - # cross-compiling, init would not hurt, but people may rely on - # late initialization of compiler even if they shouldn't...) - if os.name == 'nt' and self.plat_name != get_platform(): - self.compiler.initialize(self.plat_name) - - # And make sure that any compile/link-related options (which might - # come from the command-line or from the setup script) are set in - # that CCompiler object -- that way, they automatically apply to - # all compiling and linking done here. - if self.include_dirs is not None: - self.compiler.set_include_dirs(self.include_dirs) - if self.define is not None: - # 'define' option is a list of (name,value) tuples - for (name, value) in self.define: - self.compiler.define_macro(name, value) - if self.undef is not None: - for macro in self.undef: - self.compiler.undefine_macro(macro) - if self.libraries is not None: - self.compiler.set_libraries(self.libraries) - if self.library_dirs is not None: - self.compiler.set_library_dirs(self.library_dirs) - if self.rpath is not None: - self.compiler.set_runtime_library_dirs(self.rpath) - if self.link_objects is not None: - self.compiler.set_link_objects(self.link_objects) - - # Now actually compile and link everything. - self.build_extensions() - - def check_extensions_list(self, extensions): - """Ensure that the list of extensions (presumably provided as a - command option 'extensions') is valid, i.e. it is a list of - Extension objects. We also support the old-style list of 2-tuples, - where the tuples are (ext_name, build_info), which are converted to - Extension instances here. - - Raise DistutilsSetupError if the structure is invalid anywhere; - just returns otherwise. - """ - if not isinstance(extensions, list): - raise DistutilsSetupError( - "'ext_modules' option must be a list of Extension instances") - - for i, ext in enumerate(extensions): - if isinstance(ext, Extension): - continue # OK! (assume type-checking done - # by Extension constructor) - - if not isinstance(ext, tuple) or len(ext) != 2: - raise DistutilsSetupError( - "each element of 'ext_modules' option must be an " - "Extension instance or 2-tuple") - - ext_name, build_info = ext - - log.warn("old-style (ext_name, build_info) tuple found in " - "ext_modules for extension '%s' " - "-- please convert to Extension instance", ext_name) - - if not (isinstance(ext_name, str) and - extension_name_re.match(ext_name)): - raise DistutilsSetupError( - "first element of each tuple in 'ext_modules' " - "must be the extension name (a string)") - - if not isinstance(build_info, dict): - raise DistutilsSetupError( - "second element of each tuple in 'ext_modules' " - "must be a dictionary (build info)") - - # OK, the (ext_name, build_info) dict is type-safe: convert it - # to an Extension instance. - ext = Extension(ext_name, build_info['sources']) - - # Easy stuff: one-to-one mapping from dict elements to - # instance attributes. - for key in ('include_dirs', 'library_dirs', 'libraries', - 'extra_objects', 'extra_compile_args', - 'extra_link_args'): - val = build_info.get(key) - if val is not None: - setattr(ext, key, val) - - # Medium-easy stuff: same syntax/semantics, different names. - ext.runtime_library_dirs = build_info.get('rpath') - if 'def_file' in build_info: - log.warn("'def_file' element of build info dict " - "no longer supported") - - # Non-trivial stuff: 'macros' split into 'define_macros' - # and 'undef_macros'. - macros = build_info.get('macros') - if macros: - ext.define_macros = [] - ext.undef_macros = [] - for macro in macros: - if not (isinstance(macro, tuple) and len(macro) in (1, 2)): - raise DistutilsSetupError( - "'macros' element of build info dict " - "must be 1- or 2-tuple") - if len(macro) == 1: - ext.undef_macros.append(macro[0]) - elif len(macro) == 2: - ext.define_macros.append(macro) - - extensions[i] = ext - - def get_source_files(self): - self.check_extensions_list(self.extensions) - filenames = [] - - # Wouldn't it be neat if we knew the names of header files too... - for ext in self.extensions: - filenames.extend(ext.sources) - return filenames - - def get_outputs(self): - # Sanity check the 'extensions' list -- can't assume this is being - # done in the same run as a 'build_extensions()' call (in fact, we - # can probably assume that it *isn't*!). - self.check_extensions_list(self.extensions) - - # And build the list of output (built) filenames. Note that this - # ignores the 'inplace' flag, and assumes everything goes in the - # "build" tree. - outputs = [] - for ext in self.extensions: - outputs.append(self.get_ext_fullpath(ext.name)) - return outputs - - def build_extensions(self): - # First, sanity-check the 'extensions' list - self.check_extensions_list(self.extensions) - if self.parallel: - self._build_extensions_parallel() - else: - self._build_extensions_serial() - - def _build_extensions_parallel(self): - workers = self.parallel - if self.parallel is True: - workers = os.cpu_count() # may return None - try: - from concurrent.futures import ThreadPoolExecutor - except ImportError: - workers = None - - if workers is None: - self._build_extensions_serial() - return - - with ThreadPoolExecutor(max_workers=workers) as executor: - futures = [executor.submit(self.build_extension, ext) - for ext in self.extensions] - for ext, fut in zip(self.extensions, futures): - with self._filter_build_errors(ext): - fut.result() - - def _build_extensions_serial(self): - for ext in self.extensions: - with self._filter_build_errors(ext): - self.build_extension(ext) - - @contextlib.contextmanager - def _filter_build_errors(self, ext): - try: - yield - except (CCompilerError, DistutilsError, CompileError) as e: - if not ext.optional: - raise - self.warn('building extension "%s" failed: %s' % - (ext.name, e)) - - def build_extension(self, ext): - sources = ext.sources - if sources is None or not isinstance(sources, (list, tuple)): - raise DistutilsSetupError( - "in 'ext_modules' option (extension '%s'), " - "'sources' must be present and must be " - "a list of source filenames" % ext.name) - # sort to make the resulting .so file build reproducible - sources = sorted(sources) - - ext_path = self.get_ext_fullpath(ext.name) - depends = sources + ext.depends - if not (self.force or newer_group(depends, ext_path, 'newer')): - log.debug("skipping '%s' extension (up-to-date)", ext.name) - return - else: - log.info("building '%s' extension", ext.name) - - # First, scan the sources for SWIG definition files (.i), run - # SWIG on 'em to create .c files, and modify the sources list - # accordingly. - sources = self.swig_sources(sources, ext) - - # Next, compile the source code to object files. - - # XXX not honouring 'define_macros' or 'undef_macros' -- the - # CCompiler API needs to change to accommodate this, and I - # want to do one thing at a time! - - # Two possible sources for extra compiler arguments: - # - 'extra_compile_args' in Extension object - # - CFLAGS environment variable (not particularly - # elegant, but people seem to expect it and I - # guess it's useful) - # The environment variable should take precedence, and - # any sensible compiler will give precedence to later - # command line args. Hence we combine them in order: - extra_args = ext.extra_compile_args or [] - - macros = ext.define_macros[:] - for undef in ext.undef_macros: - macros.append((undef,)) - - objects = self.compiler.compile(sources, - output_dir=self.build_temp, - macros=macros, - include_dirs=ext.include_dirs, - debug=self.debug, - extra_postargs=extra_args, - depends=ext.depends) - - # XXX outdated variable, kept here in case third-part code - # needs it. - self._built_objects = objects[:] - - # Now link the object files together into a "shared object" -- - # of course, first we have to figure out all the other things - # that go into the mix. - if ext.extra_objects: - objects.extend(ext.extra_objects) - extra_args = ext.extra_link_args or [] - - # Detect target language, if not provided - language = ext.language or self.compiler.detect_language(sources) - - self.compiler.link_shared_object( - objects, ext_path, - libraries=self.get_libraries(ext), - library_dirs=ext.library_dirs, - runtime_library_dirs=ext.runtime_library_dirs, - extra_postargs=extra_args, - export_symbols=self.get_export_symbols(ext), - debug=self.debug, - build_temp=self.build_temp, - target_lang=language) - - def swig_sources(self, sources, extension): - """Walk the list of source files in 'sources', looking for SWIG - interface (.i) files. Run SWIG on all that are found, and - return a modified 'sources' list with SWIG source files replaced - by the generated C (or C++) files. - """ - new_sources = [] - swig_sources = [] - swig_targets = {} - - # XXX this drops generated C/C++ files into the source tree, which - # is fine for developers who want to distribute the generated - # source -- but there should be an option to put SWIG output in - # the temp dir. - - if self.swig_cpp: - log.warn("--swig-cpp is deprecated - use --swig-opts=-c++") - - if self.swig_cpp or ('-c++' in self.swig_opts) or \ - ('-c++' in extension.swig_opts): - target_ext = '.cpp' - else: - target_ext = '.c' - - for source in sources: - (base, ext) = os.path.splitext(source) - if ext == ".i": # SWIG interface file - new_sources.append(base + '_wrap' + target_ext) - swig_sources.append(source) - swig_targets[source] = new_sources[-1] - else: - new_sources.append(source) - - if not swig_sources: - return new_sources - - swig = self.swig or self.find_swig() - swig_cmd = [swig, "-python"] - swig_cmd.extend(self.swig_opts) - if self.swig_cpp: - swig_cmd.append("-c++") - - # Do not override commandline arguments - if not self.swig_opts: - for o in extension.swig_opts: - swig_cmd.append(o) - - for source in swig_sources: - target = swig_targets[source] - log.info("swigging %s to %s", source, target) - self.spawn(swig_cmd + ["-o", target, source]) - - return new_sources - - def find_swig(self): - """Return the name of the SWIG executable. On Unix, this is - just "swig" -- it should be in the PATH. Tries a bit harder on - Windows. - """ - if os.name == "posix": - return "swig" - elif os.name == "nt": - # Look for SWIG in its standard installation directory on - # Windows (or so I presume!). If we find it there, great; - # if not, act like Unix and assume it's in the PATH. - for vers in ("1.3", "1.2", "1.1"): - fn = os.path.join("c:\\swig%s" % vers, "swig.exe") - if os.path.isfile(fn): - return fn - else: - return "swig.exe" - else: - raise DistutilsPlatformError( - "I don't know how to find (much less run) SWIG " - "on platform '%s'" % os.name) - - # -- Name generators ----------------------------------------------- - # (extension names, filenames, whatever) - def get_ext_fullpath(self, ext_name): - """Returns the path of the filename for a given extension. - - The file is located in `build_lib` or directly in the package - (inplace option). - """ - fullname = self.get_ext_fullname(ext_name) - modpath = fullname.split('.') - filename = self.get_ext_filename(modpath[-1]) - - if not self.inplace: - # no further work needed - # returning : - # build_dir/package/path/filename - filename = os.path.join(*modpath[:-1]+[filename]) - return os.path.join(self.build_lib, filename) - - # the inplace option requires to find the package directory - # using the build_py command for that - package = '.'.join(modpath[0:-1]) - build_py = self.get_finalized_command('build_py') - package_dir = os.path.abspath(build_py.get_package_dir(package)) - - # returning - # package_dir/filename - return os.path.join(package_dir, filename) - - def get_ext_fullname(self, ext_name): - """Returns the fullname of a given extension name. - - Adds the `package.` prefix""" - if self.package is None: - return ext_name - else: - return self.package + '.' + ext_name - - def get_ext_filename(self, ext_name): - r"""Convert the name of an extension (eg. "foo.bar") into the name - of the file from which it will be loaded (eg. "foo/bar.so", or - "foo\bar.pyd"). - """ - from distutils.sysconfig import get_config_var - ext_path = ext_name.split('.') - ext_suffix = get_config_var('EXT_SUFFIX') - return os.path.join(*ext_path) + ext_suffix - - def get_export_symbols(self, ext): - """Return the list of symbols that a shared extension has to - export. This either uses 'ext.export_symbols' or, if it's not - provided, "PyInit_" + module_name. Only relevant on Windows, where - the .pyd file (DLL) must export the module "PyInit_" function. - """ - suffix = '_' + ext.name.split('.')[-1] - try: - # Unicode module name support as defined in PEP-489 - # https://peps.python.org/pep-0489/#export-hook-name - suffix.encode('ascii') - except UnicodeEncodeError: - suffix = 'U' + suffix.encode('punycode').replace(b'-', b'_').decode('ascii') - - initfunc_name = "PyInit" + suffix - if initfunc_name not in ext.export_symbols: - ext.export_symbols.append(initfunc_name) - return ext.export_symbols - - def get_libraries(self, ext): - """Return the list of libraries to link against when building a - shared extension. On most platforms, this is just 'ext.libraries'; - on Windows, we add the Python library (eg. python20.dll). - """ - # The python library is always needed on Windows. For MSVC, this - # is redundant, since the library is mentioned in a pragma in - # pyconfig.h that MSVC groks. The other Windows compilers all seem - # to need it mentioned explicitly, though, so that's what we do. - # Append '_d' to the python import library on debug builds. - if sys.platform == "win32": - from distutils._msvccompiler import MSVCCompiler - if not isinstance(self.compiler, MSVCCompiler): - template = "python%d%d" - if self.debug: - template = template + '_d' - pythonlib = (template % - (sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff)) - # don't extend ext.libraries, it may be shared with other - # extensions, it is a reference to the original list - return ext.libraries + [pythonlib] - else: - # On Android only the main executable and LD_PRELOADs are considered - # to be RTLD_GLOBAL, all the dependencies of the main executable - # remain RTLD_LOCAL and so the shared libraries must be linked with - # libpython when python is built with a shared python library (issue - # bpo-21536). - # On Cygwin (and if required, other POSIX-like platforms based on - # Windows like MinGW) it is simply necessary that all symbols in - # shared libraries are resolved at link time. - from distutils.sysconfig import get_config_var - link_libpython = False - if get_config_var('Py_ENABLE_SHARED'): - # A native build on an Android device or on Cygwin - if hasattr(sys, 'getandroidapilevel'): - link_libpython = True - elif sys.platform == 'cygwin': - link_libpython = True - elif '_PYTHON_HOST_PLATFORM' in os.environ: - # We are cross-compiling for one of the relevant platforms - if get_config_var('ANDROID_API_LEVEL') != 0: - link_libpython = True - elif get_config_var('MACHDEP') == 'cygwin': - link_libpython = True - - if link_libpython: - ldversion = get_config_var('LDVERSION') - return ext.libraries + ['python' + ldversion] - - return ext.libraries diff --git a/Lib/distutils/command/build_py.py b/Lib/distutils/command/build_py.py deleted file mode 100644 index edc2171c..00000000 --- a/Lib/distutils/command/build_py.py +++ /dev/null @@ -1,416 +0,0 @@ -"""distutils.command.build_py - -Implements the Distutils 'build_py' command.""" - -import os -import importlib.util -import sys -import glob - -from distutils.core import Command -from distutils.errors import * -from distutils.util import convert_path, Mixin2to3 -from distutils import log - -class build_py (Command): - - description = "\"build\" pure Python modules (copy to build directory)" - - user_options = [ - ('build-lib=', 'd', "directory to \"build\" (copy) to"), - ('compile', 'c', "compile .py to .pyc"), - ('no-compile', None, "don't compile .py files [default]"), - ('optimize=', 'O', - "also compile with optimization: -O1 for \"python -O\", " - "-O2 for \"python -OO\", and -O0 to disable [default: -O0]"), - ('force', 'f', "forcibly build everything (ignore file timestamps)"), - ] - - boolean_options = ['compile', 'force'] - negative_opt = {'no-compile' : 'compile'} - - def initialize_options(self): - self.build_lib = None - self.py_modules = None - self.package = None - self.package_data = None - self.package_dir = None - self.compile = 0 - self.optimize = 0 - self.force = None - - def finalize_options(self): - self.set_undefined_options('build', - ('build_lib', 'build_lib'), - ('force', 'force')) - - # Get the distribution options that are aliases for build_py - # options -- list of packages and list of modules. - self.packages = self.distribution.packages - self.py_modules = self.distribution.py_modules - self.package_data = self.distribution.package_data - self.package_dir = {} - if self.distribution.package_dir: - for name, path in self.distribution.package_dir.items(): - self.package_dir[name] = convert_path(path) - self.data_files = self.get_data_files() - - # Ick, copied straight from install_lib.py (fancy_getopt needs a - # type system! Hell, *everything* needs a type system!!!) - if not isinstance(self.optimize, int): - try: - self.optimize = int(self.optimize) - assert 0 <= self.optimize <= 2 - except (ValueError, AssertionError): - raise DistutilsOptionError("optimize must be 0, 1, or 2") - - def run(self): - # XXX copy_file by default preserves atime and mtime. IMHO this is - # the right thing to do, but perhaps it should be an option -- in - # particular, a site administrator might want installed files to - # reflect the time of installation rather than the last - # modification time before the installed release. - - # XXX copy_file by default preserves mode, which appears to be the - # wrong thing to do: if a file is read-only in the working - # directory, we want it to be installed read/write so that the next - # installation of the same module distribution can overwrite it - # without problems. (This might be a Unix-specific issue.) Thus - # we turn off 'preserve_mode' when copying to the build directory, - # since the build directory is supposed to be exactly what the - # installation will look like (ie. we preserve mode when - # installing). - - # Two options control which modules will be installed: 'packages' - # and 'py_modules'. The former lets us work with whole packages, not - # specifying individual modules at all; the latter is for - # specifying modules one-at-a-time. - - if self.py_modules: - self.build_modules() - if self.packages: - self.build_packages() - self.build_package_data() - - self.byte_compile(self.get_outputs(include_bytecode=0)) - - def get_data_files(self): - """Generate list of '(package,src_dir,build_dir,filenames)' tuples""" - data = [] - if not self.packages: - return data - for package in self.packages: - # Locate package source directory - src_dir = self.get_package_dir(package) - - # Compute package build directory - build_dir = os.path.join(*([self.build_lib] + package.split('.'))) - - # Length of path to strip from found files - plen = 0 - if src_dir: - plen = len(src_dir)+1 - - # Strip directory from globbed filenames - filenames = [ - file[plen:] for file in self.find_data_files(package, src_dir) - ] - data.append((package, src_dir, build_dir, filenames)) - return data - - def find_data_files(self, package, src_dir): - """Return filenames for package's data files in 'src_dir'""" - globs = (self.package_data.get('', []) - + self.package_data.get(package, [])) - files = [] - for pattern in globs: - # Each pattern has to be converted to a platform-specific path - filelist = glob.glob(os.path.join(glob.escape(src_dir), convert_path(pattern))) - # Files that match more than one pattern are only added once - files.extend([fn for fn in filelist if fn not in files - and os.path.isfile(fn)]) - return files - - def build_package_data(self): - """Copy data files into build directory""" - lastdir = None - for package, src_dir, build_dir, filenames in self.data_files: - for filename in filenames: - target = os.path.join(build_dir, filename) - self.mkpath(os.path.dirname(target)) - self.copy_file(os.path.join(src_dir, filename), target, - preserve_mode=False) - - def get_package_dir(self, package): - """Return the directory, relative to the top of the source - distribution, where package 'package' should be found - (at least according to the 'package_dir' option, if any).""" - path = package.split('.') - - if not self.package_dir: - if path: - return os.path.join(*path) - else: - return '' - else: - tail = [] - while path: - try: - pdir = self.package_dir['.'.join(path)] - except KeyError: - tail.insert(0, path[-1]) - del path[-1] - else: - tail.insert(0, pdir) - return os.path.join(*tail) - else: - # Oops, got all the way through 'path' without finding a - # match in package_dir. If package_dir defines a directory - # for the root (nameless) package, then fallback on it; - # otherwise, we might as well have not consulted - # package_dir at all, as we just use the directory implied - # by 'tail' (which should be the same as the original value - # of 'path' at this point). - pdir = self.package_dir.get('') - if pdir is not None: - tail.insert(0, pdir) - - if tail: - return os.path.join(*tail) - else: - return '' - - def check_package(self, package, package_dir): - # Empty dir name means current directory, which we can probably - # assume exists. Also, os.path.exists and isdir don't know about - # my "empty string means current dir" convention, so we have to - # circumvent them. - if package_dir != "": - if not os.path.exists(package_dir): - raise DistutilsFileError( - "package directory '%s' does not exist" % package_dir) - if not os.path.isdir(package_dir): - raise DistutilsFileError( - "supposed package directory '%s' exists, " - "but is not a directory" % package_dir) - - # Require __init__.py for all but the "root package" - if package: - init_py = os.path.join(package_dir, "__init__.py") - if os.path.isfile(init_py): - return init_py - else: - log.warn(("package init file '%s' not found " + - "(or not a regular file)"), init_py) - - # Either not in a package at all (__init__.py not expected), or - # __init__.py doesn't exist -- so don't return the filename. - return None - - def check_module(self, module, module_file): - if not os.path.isfile(module_file): - log.warn("file %s (for module %s) not found", module_file, module) - return False - else: - return True - - def find_package_modules(self, package, package_dir): - self.check_package(package, package_dir) - module_files = glob.glob(os.path.join(glob.escape(package_dir), "*.py")) - modules = [] - setup_script = os.path.abspath(self.distribution.script_name) - - for f in module_files: - abs_f = os.path.abspath(f) - if abs_f != setup_script: - module = os.path.splitext(os.path.basename(f))[0] - modules.append((package, module, f)) - else: - self.debug_print("excluding %s" % setup_script) - return modules - - def find_modules(self): - """Finds individually-specified Python modules, ie. those listed by - module name in 'self.py_modules'. Returns a list of tuples (package, - module_base, filename): 'package' is a tuple of the path through - package-space to the module; 'module_base' is the bare (no - packages, no dots) module name, and 'filename' is the path to the - ".py" file (relative to the distribution root) that implements the - module. - """ - # Map package names to tuples of useful info about the package: - # (package_dir, checked) - # package_dir - the directory where we'll find source files for - # this package - # checked - true if we have checked that the package directory - # is valid (exists, contains __init__.py, ... ?) - packages = {} - - # List of (package, module, filename) tuples to return - modules = [] - - # We treat modules-in-packages almost the same as toplevel modules, - # just the "package" for a toplevel is empty (either an empty - # string or empty list, depending on context). Differences: - # - don't check for __init__.py in directory for empty package - for module in self.py_modules: - path = module.split('.') - package = '.'.join(path[0:-1]) - module_base = path[-1] - - try: - (package_dir, checked) = packages[package] - except KeyError: - package_dir = self.get_package_dir(package) - checked = 0 - - if not checked: - init_py = self.check_package(package, package_dir) - packages[package] = (package_dir, 1) - if init_py: - modules.append((package, "__init__", init_py)) - - # XXX perhaps we should also check for just .pyc files - # (so greedy closed-source bastards can distribute Python - # modules too) - module_file = os.path.join(package_dir, module_base + ".py") - if not self.check_module(module, module_file): - continue - - modules.append((package, module_base, module_file)) - - return modules - - def find_all_modules(self): - """Compute the list of all modules that will be built, whether - they are specified one-module-at-a-time ('self.py_modules') or - by whole packages ('self.packages'). Return a list of tuples - (package, module, module_file), just like 'find_modules()' and - 'find_package_modules()' do.""" - modules = [] - if self.py_modules: - modules.extend(self.find_modules()) - if self.packages: - for package in self.packages: - package_dir = self.get_package_dir(package) - m = self.find_package_modules(package, package_dir) - modules.extend(m) - return modules - - def get_source_files(self): - return [module[-1] for module in self.find_all_modules()] - - def get_module_outfile(self, build_dir, package, module): - outfile_path = [build_dir] + list(package) + [module + ".py"] - return os.path.join(*outfile_path) - - def get_outputs(self, include_bytecode=1): - modules = self.find_all_modules() - outputs = [] - for (package, module, module_file) in modules: - package = package.split('.') - filename = self.get_module_outfile(self.build_lib, package, module) - outputs.append(filename) - if include_bytecode: - if self.compile: - outputs.append(importlib.util.cache_from_source( - filename, optimization='')) - if self.optimize > 0: - outputs.append(importlib.util.cache_from_source( - filename, optimization=self.optimize)) - - outputs += [ - os.path.join(build_dir, filename) - for package, src_dir, build_dir, filenames in self.data_files - for filename in filenames - ] - - return outputs - - def build_module(self, module, module_file, package): - if isinstance(package, str): - package = package.split('.') - elif not isinstance(package, (list, tuple)): - raise TypeError( - "'package' must be a string (dot-separated), list, or tuple") - - # Now put the module source file into the "build" area -- this is - # easy, we just copy it somewhere under self.build_lib (the build - # directory for Python source). - outfile = self.get_module_outfile(self.build_lib, package, module) - dir = os.path.dirname(outfile) - self.mkpath(dir) - return self.copy_file(module_file, outfile, preserve_mode=0) - - def build_modules(self): - modules = self.find_modules() - for (package, module, module_file) in modules: - # Now "build" the module -- ie. copy the source file to - # self.build_lib (the build directory for Python source). - # (Actually, it gets copied to the directory for this package - # under self.build_lib.) - self.build_module(module, module_file, package) - - def build_packages(self): - for package in self.packages: - # Get list of (package, module, module_file) tuples based on - # scanning the package directory. 'package' is only included - # in the tuple so that 'find_modules()' and - # 'find_package_tuples()' have a consistent interface; it's - # ignored here (apart from a sanity check). Also, 'module' is - # the *unqualified* module name (ie. no dots, no package -- we - # already know its package!), and 'module_file' is the path to - # the .py file, relative to the current directory - # (ie. including 'package_dir'). - package_dir = self.get_package_dir(package) - modules = self.find_package_modules(package, package_dir) - - # Now loop over the modules we found, "building" each one (just - # copy it to self.build_lib). - for (package_, module, module_file) in modules: - assert package == package_ - self.build_module(module, module_file, package) - - def byte_compile(self, files): - if sys.dont_write_bytecode: - self.warn('byte-compiling is disabled, skipping.') - return - - from distutils.util import byte_compile - prefix = self.build_lib - if prefix[-1] != os.sep: - prefix = prefix + os.sep - - # XXX this code is essentially the same as the 'byte_compile() - # method of the "install_lib" command, except for the determination - # of the 'prefix' string. Hmmm. - if self.compile: - byte_compile(files, optimize=0, - force=self.force, prefix=prefix, dry_run=self.dry_run) - if self.optimize > 0: - byte_compile(files, optimize=self.optimize, - force=self.force, prefix=prefix, dry_run=self.dry_run) - -class build_py_2to3(build_py, Mixin2to3): - def run(self): - self.updated_files = [] - - # Base class code - if self.py_modules: - self.build_modules() - if self.packages: - self.build_packages() - self.build_package_data() - - # 2to3 - self.run_2to3(self.updated_files) - - # Remaining base class code - self.byte_compile(self.get_outputs(include_bytecode=0)) - - def build_module(self, module, module_file, package): - res = build_py.build_module(self, module, module_file, package) - if res[1]: - # file was copied - self.updated_files.append(res[0]) - return res diff --git a/Lib/distutils/command/build_scripts.py b/Lib/distutils/command/build_scripts.py deleted file mode 100644 index ccc70e64..00000000 --- a/Lib/distutils/command/build_scripts.py +++ /dev/null @@ -1,160 +0,0 @@ -"""distutils.command.build_scripts - -Implements the Distutils 'build_scripts' command.""" - -import os, re -from stat import ST_MODE -from distutils import sysconfig -from distutils.core import Command -from distutils.dep_util import newer -from distutils.util import convert_path, Mixin2to3 -from distutils import log -import tokenize - -# check if Python is called on the first line with this expression -first_line_re = re.compile(b'^#!.*python[0-9.]*([ \t].*)?$') - -class build_scripts(Command): - - description = "\"build\" scripts (copy and fixup #! line)" - - user_options = [ - ('build-dir=', 'd', "directory to \"build\" (copy) to"), - ('force', 'f', "forcibly build everything (ignore file timestamps"), - ('executable=', 'e', "specify final destination interpreter path"), - ] - - boolean_options = ['force'] - - - def initialize_options(self): - self.build_dir = None - self.scripts = None - self.force = None - self.executable = None - self.outfiles = None - - def finalize_options(self): - self.set_undefined_options('build', - ('build_scripts', 'build_dir'), - ('force', 'force'), - ('executable', 'executable')) - self.scripts = self.distribution.scripts - - def get_source_files(self): - return self.scripts - - def run(self): - if not self.scripts: - return - self.copy_scripts() - - - def copy_scripts(self): - r"""Copy each script listed in 'self.scripts'; if it's marked as a - Python script in the Unix way (first line matches 'first_line_re', - ie. starts with "\#!" and contains "python"), then adjust the first - line to refer to the current Python interpreter as we copy. - """ - self.mkpath(self.build_dir) - outfiles = [] - updated_files = [] - for script in self.scripts: - adjust = False - script = convert_path(script) - outfile = os.path.join(self.build_dir, os.path.basename(script)) - outfiles.append(outfile) - - if not self.force and not newer(script, outfile): - log.debug("not copying %s (up-to-date)", script) - continue - - # Always open the file, but ignore failures in dry-run mode -- - # that way, we'll get accurate feedback if we can read the - # script. - try: - f = open(script, "rb") - except OSError: - if not self.dry_run: - raise - f = None - else: - encoding, lines = tokenize.detect_encoding(f.readline) - f.seek(0) - first_line = f.readline() - if not first_line: - self.warn("%s is an empty file (skipping)" % script) - continue - - match = first_line_re.match(first_line) - if match: - adjust = True - post_interp = match.group(1) or b'' - - if adjust: - log.info("copying and adjusting %s -> %s", script, - self.build_dir) - updated_files.append(outfile) - if not self.dry_run: - if not sysconfig.python_build: - executable = self.executable - else: - executable = os.path.join( - sysconfig.get_config_var("BINDIR"), - "python%s%s" % (sysconfig.get_config_var("VERSION"), - sysconfig.get_config_var("EXE"))) - executable = os.fsencode(executable) - shebang = b"#!" + executable + post_interp + b"\n" - # Python parser starts to read a script using UTF-8 until - # it gets a #coding:xxx cookie. The shebang has to be the - # first line of a file, the #coding:xxx cookie cannot be - # written before. So the shebang has to be decodable from - # UTF-8. - try: - shebang.decode('utf-8') - except UnicodeDecodeError: - raise ValueError( - "The shebang ({!r}) is not decodable " - "from utf-8".format(shebang)) - # If the script is encoded to a custom encoding (use a - # #coding:xxx cookie), the shebang has to be decodable from - # the script encoding too. - try: - shebang.decode(encoding) - except UnicodeDecodeError: - raise ValueError( - "The shebang ({!r}) is not decodable " - "from the script encoding ({})" - .format(shebang, encoding)) - with open(outfile, "wb") as outf: - outf.write(shebang) - outf.writelines(f.readlines()) - if f: - f.close() - else: - if f: - f.close() - updated_files.append(outfile) - self.copy_file(script, outfile) - - if os.name == 'posix': - for file in outfiles: - if self.dry_run: - log.info("changing mode of %s", file) - else: - oldmode = os.stat(file)[ST_MODE] & 0o7777 - newmode = (oldmode | 0o555) & 0o7777 - if newmode != oldmode: - log.info("changing mode of %s from %o to %o", - file, oldmode, newmode) - os.chmod(file, newmode) - # XXX should we modify self.outfiles? - return outfiles, updated_files - -class build_scripts_2to3(build_scripts, Mixin2to3): - - def copy_scripts(self): - outfiles, updated_files = build_scripts.copy_scripts(self) - if not self.dry_run: - self.run_2to3(updated_files) - return outfiles, updated_files diff --git a/Lib/distutils/command/check.py b/Lib/distutils/command/check.py deleted file mode 100644 index 73a30f3a..00000000 --- a/Lib/distutils/command/check.py +++ /dev/null @@ -1,148 +0,0 @@ -"""distutils.command.check - -Implements the Distutils 'check' command. -""" -from distutils.core import Command -from distutils.errors import DistutilsSetupError - -try: - # docutils is installed - from docutils.utils import Reporter - from docutils.parsers.rst import Parser - from docutils import frontend - from docutils import nodes - - class SilentReporter(Reporter): - - def __init__(self, source, report_level, halt_level, stream=None, - debug=0, encoding='ascii', error_handler='replace'): - self.messages = [] - Reporter.__init__(self, source, report_level, halt_level, stream, - debug, encoding, error_handler) - - def system_message(self, level, message, *children, **kwargs): - self.messages.append((level, message, children, kwargs)) - return nodes.system_message(message, level=level, - type=self.levels[level], - *children, **kwargs) - - HAS_DOCUTILS = True -except Exception: - # Catch all exceptions because exceptions besides ImportError probably - # indicate that docutils is not ported to Py3k. - HAS_DOCUTILS = False - -class check(Command): - """This command checks the meta-data of the package. - """ - description = ("perform some checks on the package") - user_options = [('metadata', 'm', 'Verify meta-data'), - ('restructuredtext', 'r', - ('Checks if long string meta-data syntax ' - 'are reStructuredText-compliant')), - ('strict', 's', - 'Will exit with an error if a check fails')] - - boolean_options = ['metadata', 'restructuredtext', 'strict'] - - def initialize_options(self): - """Sets default values for options.""" - self.restructuredtext = 0 - self.metadata = 1 - self.strict = 0 - self._warnings = 0 - - def finalize_options(self): - pass - - def warn(self, msg): - """Counts the number of warnings that occurs.""" - self._warnings += 1 - return Command.warn(self, msg) - - def run(self): - """Runs the command.""" - # perform the various tests - if self.metadata: - self.check_metadata() - if self.restructuredtext: - if HAS_DOCUTILS: - self.check_restructuredtext() - elif self.strict: - raise DistutilsSetupError('The docutils package is needed.') - - # let's raise an error in strict mode, if we have at least - # one warning - if self.strict and self._warnings > 0: - raise DistutilsSetupError('Please correct your package.') - - def check_metadata(self): - """Ensures that all required elements of meta-data are supplied. - - Required fields: - name, version, URL - - Recommended fields: - (author and author_email) or (maintainer and maintainer_email) - - Warns if any are missing. - """ - metadata = self.distribution.metadata - - missing = [] - for attr in ('name', 'version', 'url'): - if not (hasattr(metadata, attr) and getattr(metadata, attr)): - missing.append(attr) - - if missing: - self.warn("missing required meta-data: %s" % ', '.join(missing)) - if metadata.author: - if not metadata.author_email: - self.warn("missing meta-data: if 'author' supplied, " + - "'author_email' should be supplied too") - elif metadata.maintainer: - if not metadata.maintainer_email: - self.warn("missing meta-data: if 'maintainer' supplied, " + - "'maintainer_email' should be supplied too") - else: - self.warn("missing meta-data: either (author and author_email) " + - "or (maintainer and maintainer_email) " + - "should be supplied") - - def check_restructuredtext(self): - """Checks if the long string fields are reST-compliant.""" - data = self.distribution.get_long_description() - for warning in self._check_rst_data(data): - line = warning[-1].get('line') - if line is None: - warning = warning[1] - else: - warning = '%s (line %s)' % (warning[1], line) - self.warn(warning) - - def _check_rst_data(self, data): - """Returns warnings when the provided data doesn't compile.""" - # the include and csv_table directives need this to be a path - source_path = self.distribution.script_name or 'setup.py' - parser = Parser() - settings = frontend.OptionParser(components=(Parser,)).get_default_values() - settings.tab_width = 4 - settings.pep_references = None - settings.rfc_references = None - reporter = SilentReporter(source_path, - settings.report_level, - settings.halt_level, - stream=settings.warning_stream, - debug=settings.debug, - encoding=settings.error_encoding, - error_handler=settings.error_encoding_error_handler) - - document = nodes.document(settings, reporter, source=source_path) - document.note_source(source_path, -1) - try: - parser.parse(data, document) - except AttributeError as e: - reporter.messages.append( - (-1, 'Could not finish the parsing: %s.' % e, '', {})) - - return reporter.messages diff --git a/Lib/distutils/command/clean.py b/Lib/distutils/command/clean.py deleted file mode 100644 index 0cb27016..00000000 --- a/Lib/distutils/command/clean.py +++ /dev/null @@ -1,76 +0,0 @@ -"""distutils.command.clean - -Implements the Distutils 'clean' command.""" - -# contributed by Bastian Kleineidam <calvin@cs.uni-sb.de>, added 2000-03-18 - -import os -from distutils.core import Command -from distutils.dir_util import remove_tree -from distutils import log - -class clean(Command): - - description = "clean up temporary files from 'build' command" - user_options = [ - ('build-base=', 'b', - "base build directory (default: 'build.build-base')"), - ('build-lib=', None, - "build directory for all modules (default: 'build.build-lib')"), - ('build-temp=', 't', - "temporary build directory (default: 'build.build-temp')"), - ('build-scripts=', None, - "build directory for scripts (default: 'build.build-scripts')"), - ('bdist-base=', None, - "temporary directory for built distributions"), - ('all', 'a', - "remove all build output, not just temporary by-products") - ] - - boolean_options = ['all'] - - def initialize_options(self): - self.build_base = None - self.build_lib = None - self.build_temp = None - self.build_scripts = None - self.bdist_base = None - self.all = None - - def finalize_options(self): - self.set_undefined_options('build', - ('build_base', 'build_base'), - ('build_lib', 'build_lib'), - ('build_scripts', 'build_scripts'), - ('build_temp', 'build_temp')) - self.set_undefined_options('bdist', - ('bdist_base', 'bdist_base')) - - def run(self): - # remove the build/temp.<plat> directory (unless it's already - # gone) - if os.path.exists(self.build_temp): - remove_tree(self.build_temp, dry_run=self.dry_run) - else: - log.debug("'%s' does not exist -- can't clean it", - self.build_temp) - - if self.all: - # remove build directories - for directory in (self.build_lib, - self.bdist_base, - self.build_scripts): - if os.path.exists(directory): - remove_tree(directory, dry_run=self.dry_run) - else: - log.warn("'%s' does not exist -- can't clean it", - directory) - - # just for the heck of it, try to remove the base build directory: - # we might have emptied it right now, but if not we don't care - if not self.dry_run: - try: - os.rmdir(self.build_base) - log.info("removing '%s'", self.build_base) - except OSError: - pass diff --git a/Lib/distutils/command/command_template b/Lib/distutils/command/command_template deleted file mode 100644 index 6106819d..00000000 --- a/Lib/distutils/command/command_template +++ /dev/null @@ -1,33 +0,0 @@ -"""distutils.command.x - -Implements the Distutils 'x' command. -""" - -# created 2000/mm/dd, John Doe - -__revision__ = "$Id$" - -from distutils.core import Command - - -class x(Command): - - # Brief (40-50 characters) description of the command - description = "" - - # List of option tuples: long name, short name (None if no short - # name), and help string. - user_options = [('', '', - ""), - ] - - def initialize_options(self): - self. = None - self. = None - self. = None - - def finalize_options(self): - if self.x is None: - self.x = - - def run(self): diff --git a/Lib/distutils/command/config.py b/Lib/distutils/command/config.py deleted file mode 100644 index aeda408e..00000000 --- a/Lib/distutils/command/config.py +++ /dev/null @@ -1,344 +0,0 @@ -"""distutils.command.config - -Implements the Distutils 'config' command, a (mostly) empty command class -that exists mainly to be sub-classed by specific module distributions and -applications. The idea is that while every "config" command is different, -at least they're all named the same, and users always see "config" in the -list of standard commands. Also, this is a good place to put common -configure-like tasks: "try to compile this C code", or "figure out where -this header file lives". -""" - -import os, re - -from distutils.core import Command -from distutils.errors import DistutilsExecError -from distutils.sysconfig import customize_compiler -from distutils import log - -LANG_EXT = {"c": ".c", "c++": ".cxx"} - -class config(Command): - - description = "prepare to build" - - user_options = [ - ('compiler=', None, - "specify the compiler type"), - ('cc=', None, - "specify the compiler executable"), - ('include-dirs=', 'I', - "list of directories to search for header files"), - ('define=', 'D', - "C preprocessor macros to define"), - ('undef=', 'U', - "C preprocessor macros to undefine"), - ('libraries=', 'l', - "external C libraries to link with"), - ('library-dirs=', 'L', - "directories to search for external C libraries"), - - ('noisy', None, - "show every action (compile, link, run, ...) taken"), - ('dump-source', None, - "dump generated source files before attempting to compile them"), - ] - - - # The three standard command methods: since the "config" command - # does nothing by default, these are empty. - - def initialize_options(self): - self.compiler = None - self.cc = None - self.include_dirs = None - self.libraries = None - self.library_dirs = None - - # maximal output for now - self.noisy = 1 - self.dump_source = 1 - - # list of temporary files generated along-the-way that we have - # to clean at some point - self.temp_files = [] - - def finalize_options(self): - if self.include_dirs is None: - self.include_dirs = self.distribution.include_dirs or [] - elif isinstance(self.include_dirs, str): - self.include_dirs = self.include_dirs.split(os.pathsep) - - if self.libraries is None: - self.libraries = [] - elif isinstance(self.libraries, str): - self.libraries = [self.libraries] - - if self.library_dirs is None: - self.library_dirs = [] - elif isinstance(self.library_dirs, str): - self.library_dirs = self.library_dirs.split(os.pathsep) - - def run(self): - pass - - # Utility methods for actual "config" commands. The interfaces are - # loosely based on Autoconf macros of similar names. Sub-classes - # may use these freely. - - def _check_compiler(self): - """Check that 'self.compiler' really is a CCompiler object; - if not, make it one. - """ - # We do this late, and only on-demand, because this is an expensive - # import. - from distutils.ccompiler import CCompiler, new_compiler - if not isinstance(self.compiler, CCompiler): - self.compiler = new_compiler(compiler=self.compiler, - dry_run=self.dry_run, force=1) - customize_compiler(self.compiler) - if self.include_dirs: - self.compiler.set_include_dirs(self.include_dirs) - if self.libraries: - self.compiler.set_libraries(self.libraries) - if self.library_dirs: - self.compiler.set_library_dirs(self.library_dirs) - - def _gen_temp_sourcefile(self, body, headers, lang): - filename = "_configtest" + LANG_EXT[lang] - with open(filename, "w") as file: - if headers: - for header in headers: - file.write("#include <%s>\n" % header) - file.write("\n") - file.write(body) - if body[-1] != "\n": - file.write("\n") - return filename - - def _preprocess(self, body, headers, include_dirs, lang): - src = self._gen_temp_sourcefile(body, headers, lang) - out = "_configtest.i" - self.temp_files.extend([src, out]) - self.compiler.preprocess(src, out, include_dirs=include_dirs) - return (src, out) - - def _compile(self, body, headers, include_dirs, lang): - src = self._gen_temp_sourcefile(body, headers, lang) - if self.dump_source: - dump_file(src, "compiling '%s':" % src) - (obj,) = self.compiler.object_filenames([src]) - self.temp_files.extend([src, obj]) - self.compiler.compile([src], include_dirs=include_dirs) - return (src, obj) - - def _link(self, body, headers, include_dirs, libraries, library_dirs, - lang): - (src, obj) = self._compile(body, headers, include_dirs, lang) - prog = os.path.splitext(os.path.basename(src))[0] - self.compiler.link_executable([obj], prog, - libraries=libraries, - library_dirs=library_dirs, - target_lang=lang) - - if self.compiler.exe_extension is not None: - prog = prog + self.compiler.exe_extension - self.temp_files.append(prog) - - return (src, obj, prog) - - def _clean(self, *filenames): - if not filenames: - filenames = self.temp_files - self.temp_files = [] - log.info("removing: %s", ' '.join(filenames)) - for filename in filenames: - try: - os.remove(filename) - except OSError: - pass - - - # XXX these ignore the dry-run flag: what to do, what to do? even if - # you want a dry-run build, you still need some sort of configuration - # info. My inclination is to make it up to the real config command to - # consult 'dry_run', and assume a default (minimal) configuration if - # true. The problem with trying to do it here is that you'd have to - # return either true or false from all the 'try' methods, neither of - # which is correct. - - # XXX need access to the header search path and maybe default macros. - - def try_cpp(self, body=None, headers=None, include_dirs=None, lang="c"): - """Construct a source file from 'body' (a string containing lines - of C/C++ code) and 'headers' (a list of header files to include) - and run it through the preprocessor. Return true if the - preprocessor succeeded, false if there were any errors. - ('body' probably isn't of much use, but what the heck.) - """ - from distutils.ccompiler import CompileError - self._check_compiler() - ok = True - try: - self._preprocess(body, headers, include_dirs, lang) - except CompileError: - ok = False - - self._clean() - return ok - - def search_cpp(self, pattern, body=None, headers=None, include_dirs=None, - lang="c"): - """Construct a source file (just like 'try_cpp()'), run it through - the preprocessor, and return true if any line of the output matches - 'pattern'. 'pattern' should either be a compiled regex object or a - string containing a regex. If both 'body' and 'headers' are None, - preprocesses an empty file -- which can be useful to determine the - symbols the preprocessor and compiler set by default. - """ - self._check_compiler() - src, out = self._preprocess(body, headers, include_dirs, lang) - - if isinstance(pattern, str): - pattern = re.compile(pattern) - - with open(out) as file: - match = False - while True: - line = file.readline() - if line == '': - break - if pattern.search(line): - match = True - break - - self._clean() - return match - - def try_compile(self, body, headers=None, include_dirs=None, lang="c"): - """Try to compile a source file built from 'body' and 'headers'. - Return true on success, false otherwise. - """ - from distutils.ccompiler import CompileError - self._check_compiler() - try: - self._compile(body, headers, include_dirs, lang) - ok = True - except CompileError: - ok = False - - log.info(ok and "success!" or "failure.") - self._clean() - return ok - - def try_link(self, body, headers=None, include_dirs=None, libraries=None, - library_dirs=None, lang="c"): - """Try to compile and link a source file, built from 'body' and - 'headers', to executable form. Return true on success, false - otherwise. - """ - from distutils.ccompiler import CompileError, LinkError - self._check_compiler() - try: - self._link(body, headers, include_dirs, - libraries, library_dirs, lang) - ok = True - except (CompileError, LinkError): - ok = False - - log.info(ok and "success!" or "failure.") - self._clean() - return ok - - def try_run(self, body, headers=None, include_dirs=None, libraries=None, - library_dirs=None, lang="c"): - """Try to compile, link to an executable, and run a program - built from 'body' and 'headers'. Return true on success, false - otherwise. - """ - from distutils.ccompiler import CompileError, LinkError - self._check_compiler() - try: - src, obj, exe = self._link(body, headers, include_dirs, - libraries, library_dirs, lang) - self.spawn([exe]) - ok = True - except (CompileError, LinkError, DistutilsExecError): - ok = False - - log.info(ok and "success!" or "failure.") - self._clean() - return ok - - - # -- High-level methods -------------------------------------------- - # (these are the ones that are actually likely to be useful - # when implementing a real-world config command!) - - def check_func(self, func, headers=None, include_dirs=None, - libraries=None, library_dirs=None, decl=0, call=0): - """Determine if function 'func' is available by constructing a - source file that refers to 'func', and compiles and links it. - If everything succeeds, returns true; otherwise returns false. - - The constructed source file starts out by including the header - files listed in 'headers'. If 'decl' is true, it then declares - 'func' (as "int func()"); you probably shouldn't supply 'headers' - and set 'decl' true in the same call, or you might get errors about - a conflicting declarations for 'func'. Finally, the constructed - 'main()' function either references 'func' or (if 'call' is true) - calls it. 'libraries' and 'library_dirs' are used when - linking. - """ - self._check_compiler() - body = [] - if decl: - body.append("int %s ();" % func) - body.append("int main () {") - if call: - body.append(" %s();" % func) - else: - body.append(" %s;" % func) - body.append("}") - body = "\n".join(body) + "\n" - - return self.try_link(body, headers, include_dirs, - libraries, library_dirs) - - def check_lib(self, library, library_dirs=None, headers=None, - include_dirs=None, other_libraries=[]): - """Determine if 'library' is available to be linked against, - without actually checking that any particular symbols are provided - by it. 'headers' will be used in constructing the source file to - be compiled, but the only effect of this is to check if all the - header files listed are available. Any libraries listed in - 'other_libraries' will be included in the link, in case 'library' - has symbols that depend on other libraries. - """ - self._check_compiler() - return self.try_link("int main (void) { }", headers, include_dirs, - [library] + other_libraries, library_dirs) - - def check_header(self, header, include_dirs=None, library_dirs=None, - lang="c"): - """Determine if the system header file named by 'header_file' - exists and can be found by the preprocessor; return true if so, - false otherwise. - """ - return self.try_cpp(body="/* No body */", headers=[header], - include_dirs=include_dirs) - -def dump_file(filename, head=None): - """Dumps a file content into log.info. - - If head is not None, will be dumped before the file content. - """ - if head is None: - log.info('%s', filename) - else: - log.info(head) - file = open(filename) - try: - log.info(file.read()) - finally: - file.close() diff --git a/Lib/distutils/command/install.py b/Lib/distutils/command/install.py deleted file mode 100644 index 01d5331a..00000000 --- a/Lib/distutils/command/install.py +++ /dev/null @@ -1,679 +0,0 @@ -"""distutils.command.install - -Implements the Distutils 'install' command.""" - -import sys -import sysconfig -import os -import re - -from distutils import log -from distutils.core import Command -from distutils.debug import DEBUG -from distutils.sysconfig import get_config_vars -from distutils.errors import DistutilsPlatformError -from distutils.file_util import write_file -from distutils.util import convert_path, subst_vars, change_root -from distutils.util import get_platform -from distutils.errors import DistutilsOptionError - -from site import USER_BASE -from site import USER_SITE - -HAS_USER_SITE = (USER_SITE is not None) - -# The keys to an installation scheme; if any new types of files are to be -# installed, be sure to add an entry to every scheme in -# sysconfig._INSTALL_SCHEMES, and to SCHEME_KEYS here. -SCHEME_KEYS = ('purelib', 'platlib', 'headers', 'scripts', 'data') - -# The following code provides backward-compatible INSTALL_SCHEMES -# while making the sysconfig module the single point of truth. -# This makes it easier for OS distributions where they need to -# alter locations for packages installations in a single place. -# Note that this module is deprecated (PEP 632); all consumers -# of this information should switch to using sysconfig directly. -INSTALL_SCHEMES = {"unix_prefix": {}, "unix_home": {}, "nt": {}} - -# Copy from sysconfig._INSTALL_SCHEMES -for key in SCHEME_KEYS: - for distutils_scheme_name, sys_scheme_name in ( - ("unix_prefix", "posix_prefix"), ("unix_home", "posix_home"), - ("nt", "nt")): - sys_key = key - sys_scheme = sysconfig._INSTALL_SCHEMES[sys_scheme_name] - if key == "headers" and key not in sys_scheme: - # On POSIX-y platforms, Python will: - # - Build from .h files in 'headers' (only there when - # building CPython) - # - Install .h files to 'include' - # When 'headers' is missing, fall back to 'include' - sys_key = 'include' - INSTALL_SCHEMES[distutils_scheme_name][key] = sys_scheme[sys_key] - -# Transformation to different template format -for main_key in INSTALL_SCHEMES: - for key, value in INSTALL_SCHEMES[main_key].items(): - # Change all ocurences of {variable} to $variable - value = re.sub(r"\{(.+?)\}", r"$\g<1>", value) - value = value.replace("$installed_base", "$base") - value = value.replace("$py_version_nodot_plat", "$py_version_nodot") - if key == "headers": - value += "/$dist_name" - if sys.version_info >= (3, 9) and key == "platlib": - # platlibdir is available since 3.9: bpo-1294959 - value = value.replace("/lib/", "/$platlibdir/") - INSTALL_SCHEMES[main_key][key] = value - -# The following part of INSTALL_SCHEMES has a different definition -# than the one in sysconfig, but because both depend on the site module, -# the outcomes should be the same. -if HAS_USER_SITE: - INSTALL_SCHEMES['nt_user'] = { - 'purelib': '$usersite', - 'platlib': '$usersite', - 'headers': '$userbase/Python$py_version_nodot/Include/$dist_name', - 'scripts': '$userbase/Python$py_version_nodot/Scripts', - 'data' : '$userbase', - } - - INSTALL_SCHEMES['unix_user'] = { - 'purelib': '$usersite', - 'platlib': '$usersite', - 'headers': - '$userbase/include/python$py_version_short$abiflags/$dist_name', - 'scripts': '$userbase/bin', - 'data' : '$userbase', - } - - -class install(Command): - - description = "install everything from build directory" - - user_options = [ - # Select installation scheme and set base director(y|ies) - ('prefix=', None, - "installation prefix"), - ('exec-prefix=', None, - "(Unix only) prefix for platform-specific files"), - ('home=', None, - "(Unix only) home directory to install under"), - - # Or, just set the base director(y|ies) - ('install-base=', None, - "base installation directory (instead of --prefix or --home)"), - ('install-platbase=', None, - "base installation directory for platform-specific files " + - "(instead of --exec-prefix or --home)"), - ('root=', None, - "install everything relative to this alternate root directory"), - - # Or, explicitly set the installation scheme - ('install-purelib=', None, - "installation directory for pure Python module distributions"), - ('install-platlib=', None, - "installation directory for non-pure module distributions"), - ('install-lib=', None, - "installation directory for all module distributions " + - "(overrides --install-purelib and --install-platlib)"), - - ('install-headers=', None, - "installation directory for C/C++ headers"), - ('install-scripts=', None, - "installation directory for Python scripts"), - ('install-data=', None, - "installation directory for data files"), - - # Byte-compilation options -- see install_lib.py for details, as - # these are duplicated from there (but only install_lib does - # anything with them). - ('compile', 'c', "compile .py to .pyc [default]"), - ('no-compile', None, "don't compile .py files"), - ('optimize=', 'O', - "also compile with optimization: -O1 for \"python -O\", " - "-O2 for \"python -OO\", and -O0 to disable [default: -O0]"), - - # Miscellaneous control options - ('force', 'f', - "force installation (overwrite any existing files)"), - ('skip-build', None, - "skip rebuilding everything (for testing/debugging)"), - - # Where to install documentation (eventually!) - #('doc-format=', None, "format of documentation to generate"), - #('install-man=', None, "directory for Unix man pages"), - #('install-html=', None, "directory for HTML documentation"), - #('install-info=', None, "directory for GNU info files"), - - ('record=', None, - "filename in which to record list of installed files"), - ] - - boolean_options = ['compile', 'force', 'skip-build'] - - if HAS_USER_SITE: - user_options.append(('user', None, - "install in user site-package '%s'" % USER_SITE)) - boolean_options.append('user') - - negative_opt = {'no-compile' : 'compile'} - - - def initialize_options(self): - """Initializes options.""" - # High-level options: these select both an installation base - # and scheme. - self.prefix = None - self.exec_prefix = None - self.home = None - self.user = 0 - - # These select only the installation base; it's up to the user to - # specify the installation scheme (currently, that means supplying - # the --install-{platlib,purelib,scripts,data} options). - self.install_base = None - self.install_platbase = None - self.root = None - - # These options are the actual installation directories; if not - # supplied by the user, they are filled in using the installation - # scheme implied by prefix/exec-prefix/home and the contents of - # that installation scheme. - self.install_purelib = None # for pure module distributions - self.install_platlib = None # non-pure (dists w/ extensions) - self.install_headers = None # for C/C++ headers - self.install_lib = None # set to either purelib or platlib - self.install_scripts = None - self.install_data = None - if HAS_USER_SITE: - self.install_userbase = USER_BASE - self.install_usersite = USER_SITE - - self.compile = None - self.optimize = None - - # Deprecated - # These two are for putting non-packagized distributions into their - # own directory and creating a .pth file if it makes sense. - # 'extra_path' comes from the setup file; 'install_path_file' can - # be turned off if it makes no sense to install a .pth file. (But - # better to install it uselessly than to guess wrong and not - # install it when it's necessary and would be used!) Currently, - # 'install_path_file' is always true unless some outsider meddles - # with it. - self.extra_path = None - self.install_path_file = 1 - - # 'force' forces installation, even if target files are not - # out-of-date. 'skip_build' skips running the "build" command, - # handy if you know it's not necessary. 'warn_dir' (which is *not* - # a user option, it's just there so the bdist_* commands can turn - # it off) determines whether we warn about installing to a - # directory not in sys.path. - self.force = 0 - self.skip_build = 0 - self.warn_dir = 1 - - # These are only here as a conduit from the 'build' command to the - # 'install_*' commands that do the real work. ('build_base' isn't - # actually used anywhere, but it might be useful in future.) They - # are not user options, because if the user told the install - # command where the build directory is, that wouldn't affect the - # build command. - self.build_base = None - self.build_lib = None - - # Not defined yet because we don't know anything about - # documentation yet. - #self.install_man = None - #self.install_html = None - #self.install_info = None - - self.record = None - - - # -- Option finalizing methods ------------------------------------- - # (This is rather more involved than for most commands, - # because this is where the policy for installing third- - # party Python modules on various platforms given a wide - # array of user input is decided. Yes, it's quite complex!) - - def finalize_options(self): - """Finalizes options.""" - # This method (and its helpers, like 'finalize_unix()', - # 'finalize_other()', and 'select_scheme()') is where the default - # installation directories for modules, extension modules, and - # anything else we care to install from a Python module - # distribution. Thus, this code makes a pretty important policy - # statement about how third-party stuff is added to a Python - # installation! Note that the actual work of installation is done - # by the relatively simple 'install_*' commands; they just take - # their orders from the installation directory options determined - # here. - - # Check for errors/inconsistencies in the options; first, stuff - # that's wrong on any platform. - - if ((self.prefix or self.exec_prefix or self.home) and - (self.install_base or self.install_platbase)): - raise DistutilsOptionError( - "must supply either prefix/exec-prefix/home or " + - "install-base/install-platbase -- not both") - - if self.home and (self.prefix or self.exec_prefix): - raise DistutilsOptionError( - "must supply either home or prefix/exec-prefix -- not both") - - if self.user and (self.prefix or self.exec_prefix or self.home or - self.install_base or self.install_platbase): - raise DistutilsOptionError("can't combine user with prefix, " - "exec_prefix/home, or install_(plat)base") - - # Next, stuff that's wrong (or dubious) only on certain platforms. - if os.name != "posix": - if self.exec_prefix: - self.warn("exec-prefix option ignored on this platform") - self.exec_prefix = None - - # Now the interesting logic -- so interesting that we farm it out - # to other methods. The goal of these methods is to set the final - # values for the install_{lib,scripts,data,...} options, using as - # input a heady brew of prefix, exec_prefix, home, install_base, - # install_platbase, user-supplied versions of - # install_{purelib,platlib,lib,scripts,data,...}, and the - # INSTALL_SCHEME dictionary above. Phew! - - self.dump_dirs("pre-finalize_{unix,other}") - - if os.name == 'posix': - self.finalize_unix() - else: - self.finalize_other() - - self.dump_dirs("post-finalize_{unix,other}()") - - # Expand configuration variables, tilde, etc. in self.install_base - # and self.install_platbase -- that way, we can use $base or - # $platbase in the other installation directories and not worry - # about needing recursive variable expansion (shudder). - - py_version = sys.version.split()[0] - (prefix, exec_prefix) = get_config_vars('prefix', 'exec_prefix') - try: - abiflags = sys.abiflags - except AttributeError: - # sys.abiflags may not be defined on all platforms. - abiflags = '' - self.config_vars = {'dist_name': self.distribution.get_name(), - 'dist_version': self.distribution.get_version(), - 'dist_fullname': self.distribution.get_fullname(), - 'py_version': py_version, - 'py_version_short': '%d.%d' % sys.version_info[:2], - 'py_version_nodot': '%d%d' % sys.version_info[:2], - 'sys_prefix': prefix, - 'prefix': prefix, - 'sys_exec_prefix': exec_prefix, - 'exec_prefix': exec_prefix, - 'abiflags': abiflags, - 'platlibdir': sys.platlibdir, - } - - if HAS_USER_SITE: - self.config_vars['userbase'] = self.install_userbase - self.config_vars['usersite'] = self.install_usersite - - if sysconfig.is_python_build(True): - self.config_vars['srcdir'] = sysconfig.get_config_var('srcdir') - - self.expand_basedirs() - - self.dump_dirs("post-expand_basedirs()") - - # Now define config vars for the base directories so we can expand - # everything else. - self.config_vars['base'] = self.install_base - self.config_vars['platbase'] = self.install_platbase - - if DEBUG: - from pprint import pprint - print("config vars:") - pprint(self.config_vars) - - # Expand "~" and configuration variables in the installation - # directories. - self.expand_dirs() - - self.dump_dirs("post-expand_dirs()") - - # Create directories in the home dir: - if self.user: - self.create_home_path() - - # Pick the actual directory to install all modules to: either - # install_purelib or install_platlib, depending on whether this - # module distribution is pure or not. Of course, if the user - # already specified install_lib, use their selection. - if self.install_lib is None: - if self.distribution.ext_modules: # has extensions: non-pure - self.install_lib = self.install_platlib - else: - self.install_lib = self.install_purelib - - - # Convert directories from Unix /-separated syntax to the local - # convention. - self.convert_paths('lib', 'purelib', 'platlib', - 'scripts', 'data', 'headers') - if HAS_USER_SITE: - self.convert_paths('userbase', 'usersite') - - # Deprecated - # Well, we're not actually fully completely finalized yet: we still - # have to deal with 'extra_path', which is the hack for allowing - # non-packagized module distributions (hello, Numerical Python!) to - # get their own directories. - self.handle_extra_path() - self.install_libbase = self.install_lib # needed for .pth file - self.install_lib = os.path.join(self.install_lib, self.extra_dirs) - - # If a new root directory was supplied, make all the installation - # dirs relative to it. - if self.root is not None: - self.change_roots('libbase', 'lib', 'purelib', 'platlib', - 'scripts', 'data', 'headers') - - self.dump_dirs("after prepending root") - - # Find out the build directories, ie. where to install from. - self.set_undefined_options('build', - ('build_base', 'build_base'), - ('build_lib', 'build_lib')) - - # Punt on doc directories for now -- after all, we're punting on - # documentation completely! - - def dump_dirs(self, msg): - """Dumps the list of user options.""" - if not DEBUG: - return - from distutils.fancy_getopt import longopt_xlate - log.debug(msg + ":") - for opt in self.user_options: - opt_name = opt[0] - if opt_name[-1] == "=": - opt_name = opt_name[0:-1] - if opt_name in self.negative_opt: - opt_name = self.negative_opt[opt_name] - opt_name = opt_name.translate(longopt_xlate) - val = not getattr(self, opt_name) - else: - opt_name = opt_name.translate(longopt_xlate) - val = getattr(self, opt_name) - log.debug(" %s: %s", opt_name, val) - - def finalize_unix(self): - """Finalizes options for posix platforms.""" - if self.install_base is not None or self.install_platbase is not None: - if ((self.install_lib is None and - self.install_purelib is None and - self.install_platlib is None) or - self.install_headers is None or - self.install_scripts is None or - self.install_data is None): - raise DistutilsOptionError( - "install-base or install-platbase supplied, but " - "installation scheme is incomplete") - return - - if self.user: - if self.install_userbase is None: - raise DistutilsPlatformError( - "User base directory is not specified") - self.install_base = self.install_platbase = self.install_userbase - self.select_scheme("unix_user") - elif self.home is not None: - self.install_base = self.install_platbase = self.home - self.select_scheme("unix_home") - else: - if self.prefix is None: - if self.exec_prefix is not None: - raise DistutilsOptionError( - "must not supply exec-prefix without prefix") - - self.prefix = os.path.normpath(sys.prefix) - self.exec_prefix = os.path.normpath(sys.exec_prefix) - - else: - if self.exec_prefix is None: - self.exec_prefix = self.prefix - - self.install_base = self.prefix - self.install_platbase = self.exec_prefix - self.select_scheme("unix_prefix") - - def finalize_other(self): - """Finalizes options for non-posix platforms""" - if self.user: - if self.install_userbase is None: - raise DistutilsPlatformError( - "User base directory is not specified") - self.install_base = self.install_platbase = self.install_userbase - self.select_scheme(os.name + "_user") - elif self.home is not None: - self.install_base = self.install_platbase = self.home - self.select_scheme("unix_home") - else: - if self.prefix is None: - self.prefix = os.path.normpath(sys.prefix) - - self.install_base = self.install_platbase = self.prefix - try: - self.select_scheme(os.name) - except KeyError: - raise DistutilsPlatformError( - "I don't know how to install stuff on '%s'" % os.name) - - def select_scheme(self, name): - """Sets the install directories by applying the install schemes.""" - # it's the caller's problem if they supply a bad name! - scheme = INSTALL_SCHEMES[name] - for key in SCHEME_KEYS: - attrname = 'install_' + key - if getattr(self, attrname) is None: - setattr(self, attrname, scheme[key]) - - def _expand_attrs(self, attrs): - for attr in attrs: - val = getattr(self, attr) - if val is not None: - if os.name == 'posix' or os.name == 'nt': - val = os.path.expanduser(val) - val = subst_vars(val, self.config_vars) - setattr(self, attr, val) - - def expand_basedirs(self): - """Calls `os.path.expanduser` on install_base, install_platbase and - root.""" - self._expand_attrs(['install_base', 'install_platbase', 'root']) - - def expand_dirs(self): - """Calls `os.path.expanduser` on install dirs.""" - self._expand_attrs(['install_purelib', 'install_platlib', - 'install_lib', 'install_headers', - 'install_scripts', 'install_data',]) - - def convert_paths(self, *names): - """Call `convert_path` over `names`.""" - for name in names: - attr = "install_" + name - setattr(self, attr, convert_path(getattr(self, attr))) - - def handle_extra_path(self): - """Set `path_file` and `extra_dirs` using `extra_path`.""" - if self.extra_path is None: - self.extra_path = self.distribution.extra_path - - if self.extra_path is not None: - log.warn( - "Distribution option extra_path is deprecated. " - "See issue27919 for details." - ) - if isinstance(self.extra_path, str): - self.extra_path = self.extra_path.split(',') - - if len(self.extra_path) == 1: - path_file = extra_dirs = self.extra_path[0] - elif len(self.extra_path) == 2: - path_file, extra_dirs = self.extra_path - else: - raise DistutilsOptionError( - "'extra_path' option must be a list, tuple, or " - "comma-separated string with 1 or 2 elements") - - # convert to local form in case Unix notation used (as it - # should be in setup scripts) - extra_dirs = convert_path(extra_dirs) - else: - path_file = None - extra_dirs = '' - - # XXX should we warn if path_file and not extra_dirs? (in which - # case the path file would be harmless but pointless) - self.path_file = path_file - self.extra_dirs = extra_dirs - - def change_roots(self, *names): - """Change the install directories pointed by name using root.""" - for name in names: - attr = "install_" + name - setattr(self, attr, change_root(self.root, getattr(self, attr))) - - def create_home_path(self): - """Create directories under ~.""" - if not self.user: - return - home = convert_path(os.path.expanduser("~")) - for name, path in self.config_vars.items(): - if path.startswith(home) and not os.path.isdir(path): - self.debug_print("os.makedirs('%s', 0o700)" % path) - os.makedirs(path, 0o700) - - # -- Command execution methods ------------------------------------- - - def run(self): - """Runs the command.""" - # Obviously have to build before we can install - if not self.skip_build: - self.run_command('build') - # If we built for any other platform, we can't install. - build_plat = self.distribution.get_command_obj('build').plat_name - # check warn_dir - it is a clue that the 'install' is happening - # internally, and not to sys.path, so we don't check the platform - # matches what we are running. - if self.warn_dir and build_plat != get_platform(): - raise DistutilsPlatformError("Can't install when " - "cross-compiling") - - # Run all sub-commands (at least those that need to be run) - for cmd_name in self.get_sub_commands(): - self.run_command(cmd_name) - - if self.path_file: - self.create_path_file() - - # write list of installed files, if requested. - if self.record: - outputs = self.get_outputs() - if self.root: # strip any package prefix - root_len = len(self.root) - for counter in range(len(outputs)): - outputs[counter] = outputs[counter][root_len:] - self.execute(write_file, - (self.record, outputs), - "writing list of installed files to '%s'" % - self.record) - - sys_path = map(os.path.normpath, sys.path) - sys_path = map(os.path.normcase, sys_path) - install_lib = os.path.normcase(os.path.normpath(self.install_lib)) - if (self.warn_dir and - not (self.path_file and self.install_path_file) and - install_lib not in sys_path): - log.debug(("modules installed to '%s', which is not in " - "Python's module search path (sys.path) -- " - "you'll have to change the search path yourself"), - self.install_lib) - - def create_path_file(self): - """Creates the .pth file""" - filename = os.path.join(self.install_libbase, - self.path_file + ".pth") - if self.install_path_file: - self.execute(write_file, - (filename, [self.extra_dirs]), - "creating %s" % filename) - else: - self.warn("path file '%s' not created" % filename) - - - # -- Reporting methods --------------------------------------------- - - def get_outputs(self): - """Assembles the outputs of all the sub-commands.""" - outputs = [] - for cmd_name in self.get_sub_commands(): - cmd = self.get_finalized_command(cmd_name) - # Add the contents of cmd.get_outputs(), ensuring - # that outputs doesn't contain duplicate entries - for filename in cmd.get_outputs(): - if filename not in outputs: - outputs.append(filename) - - if self.path_file and self.install_path_file: - outputs.append(os.path.join(self.install_libbase, - self.path_file + ".pth")) - - return outputs - - def get_inputs(self): - """Returns the inputs of all the sub-commands""" - # XXX gee, this looks familiar ;-( - inputs = [] - for cmd_name in self.get_sub_commands(): - cmd = self.get_finalized_command(cmd_name) - inputs.extend(cmd.get_inputs()) - - return inputs - - # -- Predicates for sub-command list ------------------------------- - - def has_lib(self): - """Returns true if the current distribution has any Python - modules to install.""" - return (self.distribution.has_pure_modules() or - self.distribution.has_ext_modules()) - - def has_headers(self): - """Returns true if the current distribution has any headers to - install.""" - return self.distribution.has_headers() - - def has_scripts(self): - """Returns true if the current distribution has any scripts to. - install.""" - return self.distribution.has_scripts() - - def has_data(self): - """Returns true if the current distribution has any data to. - install.""" - return self.distribution.has_data_files() - - # 'sub_commands': a list of commands this command might have to run to - # get its work done. See cmd.py for more info. - sub_commands = [('install_lib', has_lib), - ('install_headers', has_headers), - ('install_scripts', has_scripts), - ('install_data', has_data), - ('install_egg_info', lambda self:True), - ] diff --git a/Lib/distutils/command/install_data.py b/Lib/distutils/command/install_data.py deleted file mode 100644 index 947cd76a..00000000 --- a/Lib/distutils/command/install_data.py +++ /dev/null @@ -1,79 +0,0 @@ -"""distutils.command.install_data - -Implements the Distutils 'install_data' command, for installing -platform-independent data files.""" - -# contributed by Bastian Kleineidam - -import os -from distutils.core import Command -from distutils.util import change_root, convert_path - -class install_data(Command): - - description = "install data files" - - user_options = [ - ('install-dir=', 'd', - "base directory for installing data files " - "(default: installation base dir)"), - ('root=', None, - "install everything relative to this alternate root directory"), - ('force', 'f', "force installation (overwrite existing files)"), - ] - - boolean_options = ['force'] - - def initialize_options(self): - self.install_dir = None - self.outfiles = [] - self.root = None - self.force = 0 - self.data_files = self.distribution.data_files - self.warn_dir = 1 - - def finalize_options(self): - self.set_undefined_options('install', - ('install_data', 'install_dir'), - ('root', 'root'), - ('force', 'force'), - ) - - def run(self): - self.mkpath(self.install_dir) - for f in self.data_files: - if isinstance(f, str): - # it's a simple file, so copy it - f = convert_path(f) - if self.warn_dir: - self.warn("setup script did not provide a directory for " - "'%s' -- installing right in '%s'" % - (f, self.install_dir)) - (out, _) = self.copy_file(f, self.install_dir) - self.outfiles.append(out) - else: - # it's a tuple with path to install to and a list of files - dir = convert_path(f[0]) - if not os.path.isabs(dir): - dir = os.path.join(self.install_dir, dir) - elif self.root: - dir = change_root(self.root, dir) - self.mkpath(dir) - - if f[1] == []: - # If there are no files listed, the user must be - # trying to create an empty directory, so add the - # directory to the list of output files. - self.outfiles.append(dir) - else: - # Copy files, adding them to the list of output files. - for data in f[1]: - data = convert_path(data) - (out, _) = self.copy_file(data, dir) - self.outfiles.append(out) - - def get_inputs(self): - return self.data_files or [] - - def get_outputs(self): - return self.outfiles diff --git a/Lib/distutils/command/install_egg_info.py b/Lib/distutils/command/install_egg_info.py deleted file mode 100644 index 0ddc7367..00000000 --- a/Lib/distutils/command/install_egg_info.py +++ /dev/null @@ -1,77 +0,0 @@ -"""distutils.command.install_egg_info - -Implements the Distutils 'install_egg_info' command, for installing -a package's PKG-INFO metadata.""" - - -from distutils.cmd import Command -from distutils import log, dir_util -import os, sys, re - -class install_egg_info(Command): - """Install an .egg-info file for the package""" - - description = "Install package's PKG-INFO metadata as an .egg-info file" - user_options = [ - ('install-dir=', 'd', "directory to install to"), - ] - - def initialize_options(self): - self.install_dir = None - - def finalize_options(self): - self.set_undefined_options('install_lib',('install_dir','install_dir')) - basename = "%s-%s-py%d.%d.egg-info" % ( - to_filename(safe_name(self.distribution.get_name())), - to_filename(safe_version(self.distribution.get_version())), - *sys.version_info[:2] - ) - self.target = os.path.join(self.install_dir, basename) - self.outputs = [self.target] - - def run(self): - target = self.target - if os.path.isdir(target) and not os.path.islink(target): - dir_util.remove_tree(target, dry_run=self.dry_run) - elif os.path.exists(target): - self.execute(os.unlink,(self.target,),"Removing "+target) - elif not os.path.isdir(self.install_dir): - self.execute(os.makedirs, (self.install_dir,), - "Creating "+self.install_dir) - log.info("Writing %s", target) - if not self.dry_run: - with open(target, 'w', encoding='UTF-8') as f: - self.distribution.metadata.write_pkg_file(f) - - def get_outputs(self): - return self.outputs - - -# The following routines are taken from setuptools' pkg_resources module and -# can be replaced by importing them from pkg_resources once it is included -# in the stdlib. - -def safe_name(name): - """Convert an arbitrary string to a standard distribution name - - Any runs of non-alphanumeric/. characters are replaced with a single '-'. - """ - return re.sub('[^A-Za-z0-9.]+', '-', name) - - -def safe_version(version): - """Convert an arbitrary string to a standard version string - - Spaces become dots, and all other non-alphanumeric characters become - dashes, with runs of multiple dashes condensed to a single dash. - """ - version = version.replace(' ','.') - return re.sub('[^A-Za-z0-9.]+', '-', version) - - -def to_filename(name): - """Convert a project or version name to its filename-escaped form - - Any '-' characters are currently replaced with '_'. - """ - return name.replace('-','_') diff --git a/Lib/distutils/command/install_headers.py b/Lib/distutils/command/install_headers.py deleted file mode 100644 index 9bb0b18d..00000000 --- a/Lib/distutils/command/install_headers.py +++ /dev/null @@ -1,47 +0,0 @@ -"""distutils.command.install_headers - -Implements the Distutils 'install_headers' command, to install C/C++ header -files to the Python include directory.""" - -from distutils.core import Command - - -# XXX force is never used -class install_headers(Command): - - description = "install C/C++ header files" - - user_options = [('install-dir=', 'd', - "directory to install header files to"), - ('force', 'f', - "force installation (overwrite existing files)"), - ] - - boolean_options = ['force'] - - def initialize_options(self): - self.install_dir = None - self.force = 0 - self.outfiles = [] - - def finalize_options(self): - self.set_undefined_options('install', - ('install_headers', 'install_dir'), - ('force', 'force')) - - - def run(self): - headers = self.distribution.headers - if not headers: - return - - self.mkpath(self.install_dir) - for header in headers: - (out, _) = self.copy_file(header, self.install_dir) - self.outfiles.append(out) - - def get_inputs(self): - return self.distribution.headers or [] - - def get_outputs(self): - return self.outfiles diff --git a/Lib/distutils/command/install_lib.py b/Lib/distutils/command/install_lib.py deleted file mode 100644 index 6154cf09..00000000 --- a/Lib/distutils/command/install_lib.py +++ /dev/null @@ -1,217 +0,0 @@ -"""distutils.command.install_lib - -Implements the Distutils 'install_lib' command -(install all Python modules).""" - -import os -import importlib.util -import sys - -from distutils.core import Command -from distutils.errors import DistutilsOptionError - - -# Extension for Python source files. -PYTHON_SOURCE_EXTENSION = ".py" - -class install_lib(Command): - - description = "install all Python modules (extensions and pure Python)" - - # The byte-compilation options are a tad confusing. Here are the - # possible scenarios: - # 1) no compilation at all (--no-compile --no-optimize) - # 2) compile .pyc only (--compile --no-optimize; default) - # 3) compile .pyc and "opt-1" .pyc (--compile --optimize) - # 4) compile "opt-1" .pyc only (--no-compile --optimize) - # 5) compile .pyc and "opt-2" .pyc (--compile --optimize-more) - # 6) compile "opt-2" .pyc only (--no-compile --optimize-more) - # - # The UI for this is two options, 'compile' and 'optimize'. - # 'compile' is strictly boolean, and only decides whether to - # generate .pyc files. 'optimize' is three-way (0, 1, or 2), and - # decides both whether to generate .pyc files and what level of - # optimization to use. - - user_options = [ - ('install-dir=', 'd', "directory to install to"), - ('build-dir=','b', "build directory (where to install from)"), - ('force', 'f', "force installation (overwrite existing files)"), - ('compile', 'c', "compile .py to .pyc [default]"), - ('no-compile', None, "don't compile .py files"), - ('optimize=', 'O', - "also compile with optimization: -O1 for \"python -O\", " - "-O2 for \"python -OO\", and -O0 to disable [default: -O0]"), - ('skip-build', None, "skip the build steps"), - ] - - boolean_options = ['force', 'compile', 'skip-build'] - negative_opt = {'no-compile' : 'compile'} - - def initialize_options(self): - # let the 'install' command dictate our installation directory - self.install_dir = None - self.build_dir = None - self.force = 0 - self.compile = None - self.optimize = None - self.skip_build = None - - def finalize_options(self): - # Get all the information we need to install pure Python modules - # from the umbrella 'install' command -- build (source) directory, - # install (target) directory, and whether to compile .py files. - self.set_undefined_options('install', - ('build_lib', 'build_dir'), - ('install_lib', 'install_dir'), - ('force', 'force'), - ('compile', 'compile'), - ('optimize', 'optimize'), - ('skip_build', 'skip_build'), - ) - - if self.compile is None: - self.compile = True - if self.optimize is None: - self.optimize = False - - if not isinstance(self.optimize, int): - try: - self.optimize = int(self.optimize) - if self.optimize not in (0, 1, 2): - raise AssertionError - except (ValueError, AssertionError): - raise DistutilsOptionError("optimize must be 0, 1, or 2") - - def run(self): - # Make sure we have built everything we need first - self.build() - - # Install everything: simply dump the entire contents of the build - # directory to the installation directory (that's the beauty of - # having a build directory!) - outfiles = self.install() - - # (Optionally) compile .py to .pyc - if outfiles is not None and self.distribution.has_pure_modules(): - self.byte_compile(outfiles) - - # -- Top-level worker functions ------------------------------------ - # (called from 'run()') - - def build(self): - if not self.skip_build: - if self.distribution.has_pure_modules(): - self.run_command('build_py') - if self.distribution.has_ext_modules(): - self.run_command('build_ext') - - def install(self): - if os.path.isdir(self.build_dir): - outfiles = self.copy_tree(self.build_dir, self.install_dir) - else: - self.warn("'%s' does not exist -- no Python modules to install" % - self.build_dir) - return - return outfiles - - def byte_compile(self, files): - if sys.dont_write_bytecode: - self.warn('byte-compiling is disabled, skipping.') - return - - from distutils.util import byte_compile - - # Get the "--root" directory supplied to the "install" command, - # and use it as a prefix to strip off the purported filename - # encoded in bytecode files. This is far from complete, but it - # should at least generate usable bytecode in RPM distributions. - install_root = self.get_finalized_command('install').root - - if self.compile: - byte_compile(files, optimize=0, - force=self.force, prefix=install_root, - dry_run=self.dry_run) - if self.optimize > 0: - byte_compile(files, optimize=self.optimize, - force=self.force, prefix=install_root, - verbose=self.verbose, dry_run=self.dry_run) - - - # -- Utility methods ----------------------------------------------- - - def _mutate_outputs(self, has_any, build_cmd, cmd_option, output_dir): - if not has_any: - return [] - - build_cmd = self.get_finalized_command(build_cmd) - build_files = build_cmd.get_outputs() - build_dir = getattr(build_cmd, cmd_option) - - prefix_len = len(build_dir) + len(os.sep) - outputs = [] - for file in build_files: - outputs.append(os.path.join(output_dir, file[prefix_len:])) - - return outputs - - def _bytecode_filenames(self, py_filenames): - bytecode_files = [] - for py_file in py_filenames: - # Since build_py handles package data installation, the - # list of outputs can contain more than just .py files. - # Make sure we only report bytecode for the .py files. - ext = os.path.splitext(os.path.normcase(py_file))[1] - if ext != PYTHON_SOURCE_EXTENSION: - continue - if self.compile: - bytecode_files.append(importlib.util.cache_from_source( - py_file, optimization='')) - if self.optimize > 0: - bytecode_files.append(importlib.util.cache_from_source( - py_file, optimization=self.optimize)) - - return bytecode_files - - - # -- External interface -------------------------------------------- - # (called by outsiders) - - def get_outputs(self): - """Return the list of files that would be installed if this command - were actually run. Not affected by the "dry-run" flag or whether - modules have actually been built yet. - """ - pure_outputs = \ - self._mutate_outputs(self.distribution.has_pure_modules(), - 'build_py', 'build_lib', - self.install_dir) - if self.compile: - bytecode_outputs = self._bytecode_filenames(pure_outputs) - else: - bytecode_outputs = [] - - ext_outputs = \ - self._mutate_outputs(self.distribution.has_ext_modules(), - 'build_ext', 'build_lib', - self.install_dir) - - return pure_outputs + bytecode_outputs + ext_outputs - - def get_inputs(self): - """Get the list of files that are input to this command, ie. the - files that get installed as they are named in the build tree. - The files in this list correspond one-to-one to the output - filenames returned by 'get_outputs()'. - """ - inputs = [] - - if self.distribution.has_pure_modules(): - build_py = self.get_finalized_command('build_py') - inputs.extend(build_py.get_outputs()) - - if self.distribution.has_ext_modules(): - build_ext = self.get_finalized_command('build_ext') - inputs.extend(build_ext.get_outputs()) - - return inputs diff --git a/Lib/distutils/command/install_scripts.py b/Lib/distutils/command/install_scripts.py deleted file mode 100644 index 31a1130e..00000000 --- a/Lib/distutils/command/install_scripts.py +++ /dev/null @@ -1,60 +0,0 @@ -"""distutils.command.install_scripts - -Implements the Distutils 'install_scripts' command, for installing -Python scripts.""" - -# contributed by Bastian Kleineidam - -import os -from distutils.core import Command -from distutils import log -from stat import ST_MODE - - -class install_scripts(Command): - - description = "install scripts (Python or otherwise)" - - user_options = [ - ('install-dir=', 'd', "directory to install scripts to"), - ('build-dir=','b', "build directory (where to install from)"), - ('force', 'f', "force installation (overwrite existing files)"), - ('skip-build', None, "skip the build steps"), - ] - - boolean_options = ['force', 'skip-build'] - - def initialize_options(self): - self.install_dir = None - self.force = 0 - self.build_dir = None - self.skip_build = None - - def finalize_options(self): - self.set_undefined_options('build', ('build_scripts', 'build_dir')) - self.set_undefined_options('install', - ('install_scripts', 'install_dir'), - ('force', 'force'), - ('skip_build', 'skip_build'), - ) - - def run(self): - if not self.skip_build: - self.run_command('build_scripts') - self.outfiles = self.copy_tree(self.build_dir, self.install_dir) - if os.name == 'posix': - # Set the executable bits (owner, group, and world) on - # all the scripts we just installed. - for file in self.get_outputs(): - if self.dry_run: - log.info("changing mode of %s", file) - else: - mode = ((os.stat(file)[ST_MODE]) | 0o555) & 0o7777 - log.info("changing mode of %s to %o", file, mode) - os.chmod(file, mode) - - def get_inputs(self): - return self.distribution.scripts or [] - - def get_outputs(self): - return self.outfiles or [] diff --git a/Lib/distutils/command/register.py b/Lib/distutils/command/register.py deleted file mode 100644 index 0fac94e9..00000000 --- a/Lib/distutils/command/register.py +++ /dev/null @@ -1,304 +0,0 @@ -"""distutils.command.register - -Implements the Distutils 'register' command (register with the repository). -""" - -# created 2002/10/21, Richard Jones - -import getpass -import io -import urllib.parse, urllib.request -from warnings import warn - -from distutils.core import PyPIRCCommand -from distutils.errors import * -from distutils import log - -class register(PyPIRCCommand): - - description = ("register the distribution with the Python package index") - user_options = PyPIRCCommand.user_options + [ - ('list-classifiers', None, - 'list the valid Trove classifiers'), - ('strict', None , - 'Will stop the registering if the meta-data are not fully compliant') - ] - boolean_options = PyPIRCCommand.boolean_options + [ - 'verify', 'list-classifiers', 'strict'] - - sub_commands = [('check', lambda self: True)] - - def initialize_options(self): - PyPIRCCommand.initialize_options(self) - self.list_classifiers = 0 - self.strict = 0 - - def finalize_options(self): - PyPIRCCommand.finalize_options(self) - # setting options for the `check` subcommand - check_options = {'strict': ('register', self.strict), - 'restructuredtext': ('register', 1)} - self.distribution.command_options['check'] = check_options - - def run(self): - self.finalize_options() - self._set_config() - - # Run sub commands - for cmd_name in self.get_sub_commands(): - self.run_command(cmd_name) - - if self.dry_run: - self.verify_metadata() - elif self.list_classifiers: - self.classifiers() - else: - self.send_metadata() - - def check_metadata(self): - """Deprecated API.""" - warn("distutils.command.register.check_metadata is deprecated, \ - use the check command instead", PendingDeprecationWarning) - check = self.distribution.get_command_obj('check') - check.ensure_finalized() - check.strict = self.strict - check.restructuredtext = 1 - check.run() - - def _set_config(self): - ''' Reads the configuration file and set attributes. - ''' - config = self._read_pypirc() - if config != {}: - self.username = config['username'] - self.password = config['password'] - self.repository = config['repository'] - self.realm = config['realm'] - self.has_config = True - else: - if self.repository not in ('pypi', self.DEFAULT_REPOSITORY): - raise ValueError('%s not found in .pypirc' % self.repository) - if self.repository == 'pypi': - self.repository = self.DEFAULT_REPOSITORY - self.has_config = False - - def classifiers(self): - ''' Fetch the list of classifiers from the server. - ''' - url = self.repository+'?:action=list_classifiers' - response = urllib.request.urlopen(url) - log.info(self._read_pypi_response(response)) - - def verify_metadata(self): - ''' Send the metadata to the package index server to be checked. - ''' - # send the info to the server and report the result - (code, result) = self.post_to_server(self.build_post_data('verify')) - log.info('Server response (%s): %s', code, result) - - def send_metadata(self): - ''' Send the metadata to the package index server. - - Well, do the following: - 1. figure who the user is, and then - 2. send the data as a Basic auth'ed POST. - - First we try to read the username/password from $HOME/.pypirc, - which is a ConfigParser-formatted file with a section - [distutils] containing username and password entries (both - in clear text). Eg: - - [distutils] - index-servers = - pypi - - [pypi] - username: fred - password: sekrit - - Otherwise, to figure who the user is, we offer the user three - choices: - - 1. use existing login, - 2. register as a new user, or - 3. set the password to a random string and email the user. - - ''' - # see if we can short-cut and get the username/password from the - # config - if self.has_config: - choice = '1' - username = self.username - password = self.password - else: - choice = 'x' - username = password = '' - - # get the user's login info - choices = '1 2 3 4'.split() - while choice not in choices: - self.announce('''\ -We need to know who you are, so please choose either: - 1. use your existing login, - 2. register as a new user, - 3. have the server generate a new password for you (and email it to you), or - 4. quit -Your selection [default 1]: ''', log.INFO) - choice = input() - if not choice: - choice = '1' - elif choice not in choices: - print('Please choose one of the four options!') - - if choice == '1': - # get the username and password - while not username: - username = input('Username: ') - while not password: - password = getpass.getpass('Password: ') - - # set up the authentication - auth = urllib.request.HTTPPasswordMgr() - host = urllib.parse.urlparse(self.repository)[1] - auth.add_password(self.realm, host, username, password) - # send the info to the server and report the result - code, result = self.post_to_server(self.build_post_data('submit'), - auth) - self.announce('Server response (%s): %s' % (code, result), - log.INFO) - - # possibly save the login - if code == 200: - if self.has_config: - # sharing the password in the distribution instance - # so the upload command can reuse it - self.distribution.password = password - else: - self.announce(('I can store your PyPI login so future ' - 'submissions will be faster.'), log.INFO) - self.announce('(the login will be stored in %s)' % \ - self._get_rc_file(), log.INFO) - choice = 'X' - while choice.lower() not in 'yn': - choice = input('Save your login (y/N)?') - if not choice: - choice = 'n' - if choice.lower() == 'y': - self._store_pypirc(username, password) - - elif choice == '2': - data = {':action': 'user'} - data['name'] = data['password'] = data['email'] = '' - data['confirm'] = None - while not data['name']: - data['name'] = input('Username: ') - while data['password'] != data['confirm']: - while not data['password']: - data['password'] = getpass.getpass('Password: ') - while not data['confirm']: - data['confirm'] = getpass.getpass(' Confirm: ') - if data['password'] != data['confirm']: - data['password'] = '' - data['confirm'] = None - print("Password and confirm don't match!") - while not data['email']: - data['email'] = input(' EMail: ') - code, result = self.post_to_server(data) - if code != 200: - log.info('Server response (%s): %s', code, result) - else: - log.info('You will receive an email shortly.') - log.info(('Follow the instructions in it to ' - 'complete registration.')) - elif choice == '3': - data = {':action': 'password_reset'} - data['email'] = '' - while not data['email']: - data['email'] = input('Your email address: ') - code, result = self.post_to_server(data) - log.info('Server response (%s): %s', code, result) - - def build_post_data(self, action): - # figure the data to send - the metadata plus some additional - # information used by the package server - meta = self.distribution.metadata - data = { - ':action': action, - 'metadata_version' : '1.0', - 'name': meta.get_name(), - 'version': meta.get_version(), - 'summary': meta.get_description(), - 'home_page': meta.get_url(), - 'author': meta.get_contact(), - 'author_email': meta.get_contact_email(), - 'license': meta.get_licence(), - 'description': meta.get_long_description(), - 'keywords': meta.get_keywords(), - 'platform': meta.get_platforms(), - 'classifiers': meta.get_classifiers(), - 'download_url': meta.get_download_url(), - # PEP 314 - 'provides': meta.get_provides(), - 'requires': meta.get_requires(), - 'obsoletes': meta.get_obsoletes(), - } - if data['provides'] or data['requires'] or data['obsoletes']: - data['metadata_version'] = '1.1' - return data - - def post_to_server(self, data, auth=None): - ''' Post a query to the server, and return a string response. - ''' - if 'name' in data: - self.announce('Registering %s to %s' % (data['name'], - self.repository), - log.INFO) - # Build up the MIME payload for the urllib2 POST data - boundary = '--------------GHSKFJDLGDS7543FJKLFHRE75642756743254' - sep_boundary = '\n--' + boundary - end_boundary = sep_boundary + '--' - body = io.StringIO() - for key, value in data.items(): - # handle multiple entries for the same name - if type(value) not in (type([]), type( () )): - value = [value] - for value in value: - value = str(value) - body.write(sep_boundary) - body.write('\nContent-Disposition: form-data; name="%s"'%key) - body.write("\n\n") - body.write(value) - if value and value[-1] == '\r': - body.write('\n') # write an extra newline (lurve Macs) - body.write(end_boundary) - body.write("\n") - body = body.getvalue().encode("utf-8") - - # build the Request - headers = { - 'Content-type': 'multipart/form-data; boundary=%s; charset=utf-8'%boundary, - 'Content-length': str(len(body)) - } - req = urllib.request.Request(self.repository, body, headers) - - # handle HTTP and include the Basic Auth handler - opener = urllib.request.build_opener( - urllib.request.HTTPBasicAuthHandler(password_mgr=auth) - ) - data = '' - try: - result = opener.open(req) - except urllib.error.HTTPError as e: - if self.show_response: - data = e.fp.read() - result = e.code, e.msg - except urllib.error.URLError as e: - result = 500, str(e) - else: - if self.show_response: - data = self._read_pypi_response(result) - result = 200, 'OK' - if self.show_response: - msg = '\n'.join(('-' * 75, data, '-' * 75)) - self.announce(msg, log.INFO) - return result diff --git a/Lib/distutils/command/sdist.py b/Lib/distutils/command/sdist.py deleted file mode 100644 index b4996fcb..00000000 --- a/Lib/distutils/command/sdist.py +++ /dev/null @@ -1,494 +0,0 @@ -"""distutils.command.sdist - -Implements the Distutils 'sdist' command (create a source distribution).""" - -import os -import sys -from glob import glob -from warnings import warn - -from distutils.core import Command -from distutils import dir_util -from distutils import file_util -from distutils import archive_util -from distutils.text_file import TextFile -from distutils.filelist import FileList -from distutils import log -from distutils.util import convert_path -from distutils.errors import DistutilsTemplateError, DistutilsOptionError - - -def show_formats(): - """Print all possible values for the 'formats' option (used by - the "--help-formats" command-line option). - """ - from distutils.fancy_getopt import FancyGetopt - from distutils.archive_util import ARCHIVE_FORMATS - formats = [] - for format in ARCHIVE_FORMATS.keys(): - formats.append(("formats=" + format, None, - ARCHIVE_FORMATS[format][2])) - formats.sort() - FancyGetopt(formats).print_help( - "List of available source distribution formats:") - - -class sdist(Command): - - description = "create a source distribution (tarball, zip file, etc.)" - - def checking_metadata(self): - """Callable used for the check sub-command. - - Placed here so user_options can view it""" - return self.metadata_check - - user_options = [ - ('template=', 't', - "name of manifest template file [default: MANIFEST.in]"), - ('manifest=', 'm', - "name of manifest file [default: MANIFEST]"), - ('use-defaults', None, - "include the default file set in the manifest " - "[default; disable with --no-defaults]"), - ('no-defaults', None, - "don't include the default file set"), - ('prune', None, - "specifically exclude files/directories that should not be " - "distributed (build tree, RCS/CVS dirs, etc.) " - "[default; disable with --no-prune]"), - ('no-prune', None, - "don't automatically exclude anything"), - ('manifest-only', 'o', - "just regenerate the manifest and then stop " - "(implies --force-manifest)"), - ('force-manifest', 'f', - "forcibly regenerate the manifest and carry on as usual. " - "Deprecated: now the manifest is always regenerated."), - ('formats=', None, - "formats for source distribution (comma-separated list)"), - ('keep-temp', 'k', - "keep the distribution tree around after creating " + - "archive file(s)"), - ('dist-dir=', 'd', - "directory to put the source distribution archive(s) in " - "[default: dist]"), - ('metadata-check', None, - "Ensure that all required elements of meta-data " - "are supplied. Warn if any missing. [default]"), - ('owner=', 'u', - "Owner name used when creating a tar file [default: current user]"), - ('group=', 'g', - "Group name used when creating a tar file [default: current group]"), - ] - - boolean_options = ['use-defaults', 'prune', - 'manifest-only', 'force-manifest', - 'keep-temp', 'metadata-check'] - - help_options = [ - ('help-formats', None, - "list available distribution formats", show_formats), - ] - - negative_opt = {'no-defaults': 'use-defaults', - 'no-prune': 'prune' } - - sub_commands = [('check', checking_metadata)] - - READMES = ('README', 'README.txt', 'README.rst') - - def initialize_options(self): - # 'template' and 'manifest' are, respectively, the names of - # the manifest template and manifest file. - self.template = None - self.manifest = None - - # 'use_defaults': if true, we will include the default file set - # in the manifest - self.use_defaults = 1 - self.prune = 1 - - self.manifest_only = 0 - self.force_manifest = 0 - - self.formats = ['gztar'] - self.keep_temp = 0 - self.dist_dir = None - - self.archive_files = None - self.metadata_check = 1 - self.owner = None - self.group = None - - def finalize_options(self): - if self.manifest is None: - self.manifest = "MANIFEST" - if self.template is None: - self.template = "MANIFEST.in" - - self.ensure_string_list('formats') - - bad_format = archive_util.check_archive_formats(self.formats) - if bad_format: - raise DistutilsOptionError( - "unknown archive format '%s'" % bad_format) - - if self.dist_dir is None: - self.dist_dir = "dist" - - def run(self): - # 'filelist' contains the list of files that will make up the - # manifest - self.filelist = FileList() - - # Run sub commands - for cmd_name in self.get_sub_commands(): - self.run_command(cmd_name) - - # Do whatever it takes to get the list of files to process - # (process the manifest template, read an existing manifest, - # whatever). File list is accumulated in 'self.filelist'. - self.get_file_list() - - # If user just wanted us to regenerate the manifest, stop now. - if self.manifest_only: - return - - # Otherwise, go ahead and create the source distribution tarball, - # or zipfile, or whatever. - self.make_distribution() - - def check_metadata(self): - """Deprecated API.""" - warn("distutils.command.sdist.check_metadata is deprecated, \ - use the check command instead", PendingDeprecationWarning) - check = self.distribution.get_command_obj('check') - check.ensure_finalized() - check.run() - - def get_file_list(self): - """Figure out the list of files to include in the source - distribution, and put it in 'self.filelist'. This might involve - reading the manifest template (and writing the manifest), or just - reading the manifest, or just using the default file set -- it all - depends on the user's options. - """ - # new behavior when using a template: - # the file list is recalculated every time because - # even if MANIFEST.in or setup.py are not changed - # the user might have added some files in the tree that - # need to be included. - # - # This makes --force the default and only behavior with templates. - template_exists = os.path.isfile(self.template) - if not template_exists and self._manifest_is_not_generated(): - self.read_manifest() - self.filelist.sort() - self.filelist.remove_duplicates() - return - - if not template_exists: - self.warn(("manifest template '%s' does not exist " + - "(using default file list)") % - self.template) - self.filelist.findall() - - if self.use_defaults: - self.add_defaults() - - if template_exists: - self.read_template() - - if self.prune: - self.prune_file_list() - - self.filelist.sort() - self.filelist.remove_duplicates() - self.write_manifest() - - def add_defaults(self): - """Add all the default files to self.filelist: - - README or README.txt - - setup.py - - test/test*.py - - all pure Python modules mentioned in setup script - - all files pointed by package_data (build_py) - - all files defined in data_files. - - all files defined as scripts. - - all C sources listed as part of extensions or C libraries - in the setup script (doesn't catch C headers!) - Warns if (README or README.txt) or setup.py are missing; everything - else is optional. - """ - self._add_defaults_standards() - self._add_defaults_optional() - self._add_defaults_python() - self._add_defaults_data_files() - self._add_defaults_ext() - self._add_defaults_c_libs() - self._add_defaults_scripts() - - @staticmethod - def _cs_path_exists(fspath): - """ - Case-sensitive path existence check - - >>> sdist._cs_path_exists(__file__) - True - >>> sdist._cs_path_exists(__file__.upper()) - False - """ - if not os.path.exists(fspath): - return False - # make absolute so we always have a directory - abspath = os.path.abspath(fspath) - directory, filename = os.path.split(abspath) - return filename in os.listdir(directory) - - def _add_defaults_standards(self): - standards = [self.READMES, self.distribution.script_name] - for fn in standards: - if isinstance(fn, tuple): - alts = fn - got_it = False - for fn in alts: - if self._cs_path_exists(fn): - got_it = True - self.filelist.append(fn) - break - - if not got_it: - self.warn("standard file not found: should have one of " + - ', '.join(alts)) - else: - if self._cs_path_exists(fn): - self.filelist.append(fn) - else: - self.warn("standard file '%s' not found" % fn) - - def _add_defaults_optional(self): - optional = ['test/test*.py', 'setup.cfg'] - for pattern in optional: - files = filter(os.path.isfile, glob(pattern)) - self.filelist.extend(files) - - def _add_defaults_python(self): - # build_py is used to get: - # - python modules - # - files defined in package_data - build_py = self.get_finalized_command('build_py') - - # getting python files - if self.distribution.has_pure_modules(): - self.filelist.extend(build_py.get_source_files()) - - # getting package_data files - # (computed in build_py.data_files by build_py.finalize_options) - for pkg, src_dir, build_dir, filenames in build_py.data_files: - for filename in filenames: - self.filelist.append(os.path.join(src_dir, filename)) - - def _add_defaults_data_files(self): - # getting distribution.data_files - if self.distribution.has_data_files(): - for item in self.distribution.data_files: - if isinstance(item, str): - # plain file - item = convert_path(item) - if os.path.isfile(item): - self.filelist.append(item) - else: - # a (dirname, filenames) tuple - dirname, filenames = item - for f in filenames: - f = convert_path(f) - if os.path.isfile(f): - self.filelist.append(f) - - def _add_defaults_ext(self): - if self.distribution.has_ext_modules(): - build_ext = self.get_finalized_command('build_ext') - self.filelist.extend(build_ext.get_source_files()) - - def _add_defaults_c_libs(self): - if self.distribution.has_c_libraries(): - build_clib = self.get_finalized_command('build_clib') - self.filelist.extend(build_clib.get_source_files()) - - def _add_defaults_scripts(self): - if self.distribution.has_scripts(): - build_scripts = self.get_finalized_command('build_scripts') - self.filelist.extend(build_scripts.get_source_files()) - - def read_template(self): - """Read and parse manifest template file named by self.template. - - (usually "MANIFEST.in") The parsing and processing is done by - 'self.filelist', which updates itself accordingly. - """ - log.info("reading manifest template '%s'", self.template) - template = TextFile(self.template, strip_comments=1, skip_blanks=1, - join_lines=1, lstrip_ws=1, rstrip_ws=1, - collapse_join=1) - - try: - while True: - line = template.readline() - if line is None: # end of file - break - - try: - self.filelist.process_template_line(line) - # the call above can raise a DistutilsTemplateError for - # malformed lines, or a ValueError from the lower-level - # convert_path function - except (DistutilsTemplateError, ValueError) as msg: - self.warn("%s, line %d: %s" % (template.filename, - template.current_line, - msg)) - finally: - template.close() - - def prune_file_list(self): - """Prune off branches that might slip into the file list as created - by 'read_template()', but really don't belong there: - * the build tree (typically "build") - * the release tree itself (only an issue if we ran "sdist" - previously with --keep-temp, or it aborted) - * any RCS, CVS, .svn, .hg, .git, .bzr, _darcs directories - """ - build = self.get_finalized_command('build') - base_dir = self.distribution.get_fullname() - - self.filelist.exclude_pattern(None, prefix=build.build_base) - self.filelist.exclude_pattern(None, prefix=base_dir) - - if sys.platform == 'win32': - seps = r'/|\\' - else: - seps = '/' - - vcs_dirs = ['RCS', 'CVS', r'\.svn', r'\.hg', r'\.git', r'\.bzr', - '_darcs'] - vcs_ptrn = r'(^|%s)(%s)(%s).*' % (seps, '|'.join(vcs_dirs), seps) - self.filelist.exclude_pattern(vcs_ptrn, is_regex=1) - - def write_manifest(self): - """Write the file list in 'self.filelist' (presumably as filled in - by 'add_defaults()' and 'read_template()') to the manifest file - named by 'self.manifest'. - """ - if self._manifest_is_not_generated(): - log.info("not writing to manually maintained " - "manifest file '%s'" % self.manifest) - return - - content = self.filelist.files[:] - content.insert(0, '# file GENERATED by distutils, do NOT edit') - self.execute(file_util.write_file, (self.manifest, content), - "writing manifest file '%s'" % self.manifest) - - def _manifest_is_not_generated(self): - # check for special comment used in 3.1.3 and higher - if not os.path.isfile(self.manifest): - return False - - fp = open(self.manifest) - try: - first_line = fp.readline() - finally: - fp.close() - return first_line != '# file GENERATED by distutils, do NOT edit\n' - - def read_manifest(self): - """Read the manifest file (named by 'self.manifest') and use it to - fill in 'self.filelist', the list of files to include in the source - distribution. - """ - log.info("reading manifest file '%s'", self.manifest) - with open(self.manifest) as manifest: - for line in manifest: - # ignore comments and blank lines - line = line.strip() - if line.startswith('#') or not line: - continue - self.filelist.append(line) - - def make_release_tree(self, base_dir, files): - """Create the directory tree that will become the source - distribution archive. All directories implied by the filenames in - 'files' are created under 'base_dir', and then we hard link or copy - (if hard linking is unavailable) those files into place. - Essentially, this duplicates the developer's source tree, but in a - directory named after the distribution, containing only the files - to be distributed. - """ - # Create all the directories under 'base_dir' necessary to - # put 'files' there; the 'mkpath()' is just so we don't die - # if the manifest happens to be empty. - self.mkpath(base_dir) - dir_util.create_tree(base_dir, files, dry_run=self.dry_run) - - # And walk over the list of files, either making a hard link (if - # os.link exists) to each one that doesn't already exist in its - # corresponding location under 'base_dir', or copying each file - # that's out-of-date in 'base_dir'. (Usually, all files will be - # out-of-date, because by default we blow away 'base_dir' when - # we're done making the distribution archives.) - - if hasattr(os, 'link'): # can make hard links on this system - link = 'hard' - msg = "making hard links in %s..." % base_dir - else: # nope, have to copy - link = None - msg = "copying files to %s..." % base_dir - - if not files: - log.warn("no files to distribute -- empty manifest?") - else: - log.info(msg) - for file in files: - if not os.path.isfile(file): - log.warn("'%s' not a regular file -- skipping", file) - else: - dest = os.path.join(base_dir, file) - self.copy_file(file, dest, link=link) - - self.distribution.metadata.write_pkg_info(base_dir) - - def make_distribution(self): - """Create the source distribution(s). First, we create the release - tree with 'make_release_tree()'; then, we create all required - archive files (according to 'self.formats') from the release tree. - Finally, we clean up by blowing away the release tree (unless - 'self.keep_temp' is true). The list of archive files created is - stored so it can be retrieved later by 'get_archive_files()'. - """ - # Don't warn about missing meta-data here -- should be (and is!) - # done elsewhere. - base_dir = self.distribution.get_fullname() - base_name = os.path.join(self.dist_dir, base_dir) - - self.make_release_tree(base_dir, self.filelist.files) - archive_files = [] # remember names of files we create - # tar archive must be created last to avoid overwrite and remove - if 'tar' in self.formats: - self.formats.append(self.formats.pop(self.formats.index('tar'))) - - for fmt in self.formats: - file = self.make_archive(base_name, fmt, base_dir=base_dir, - owner=self.owner, group=self.group) - archive_files.append(file) - self.distribution.dist_files.append(('sdist', '', file)) - - self.archive_files = archive_files - - if not self.keep_temp: - dir_util.remove_tree(base_dir, dry_run=self.dry_run) - - def get_archive_files(self): - """Return the list of archive files created when the command - was run, or None if the command hasn't run yet. - """ - return self.archive_files diff --git a/Lib/distutils/command/upload.py b/Lib/distutils/command/upload.py deleted file mode 100644 index e0ecb655..00000000 --- a/Lib/distutils/command/upload.py +++ /dev/null @@ -1,215 +0,0 @@ -""" -distutils.command.upload - -Implements the Distutils 'upload' subcommand (upload package to a package -index). -""" - -import os -import io -import hashlib -from base64 import standard_b64encode -from urllib.error import HTTPError -from urllib.request import urlopen, Request -from urllib.parse import urlparse -from distutils.errors import DistutilsError, DistutilsOptionError -from distutils.core import PyPIRCCommand -from distutils.spawn import spawn -from distutils import log - - -# PyPI Warehouse supports MD5, SHA256, and Blake2 (blake2-256) -# https://bugs.python.org/issue40698 -_FILE_CONTENT_DIGESTS = { - "md5_digest": getattr(hashlib, "md5", None), - "sha256_digest": getattr(hashlib, "sha256", None), - "blake2_256_digest": getattr(hashlib, "blake2b", None), -} - - -class upload(PyPIRCCommand): - - description = "upload binary package to PyPI" - - user_options = PyPIRCCommand.user_options + [ - ('sign', 's', - 'sign files to upload using gpg'), - ('identity=', 'i', 'GPG identity used to sign files'), - ] - - boolean_options = PyPIRCCommand.boolean_options + ['sign'] - - def initialize_options(self): - PyPIRCCommand.initialize_options(self) - self.username = '' - self.password = '' - self.show_response = 0 - self.sign = False - self.identity = None - - def finalize_options(self): - PyPIRCCommand.finalize_options(self) - if self.identity and not self.sign: - raise DistutilsOptionError( - "Must use --sign for --identity to have meaning" - ) - config = self._read_pypirc() - if config != {}: - self.username = config['username'] - self.password = config['password'] - self.repository = config['repository'] - self.realm = config['realm'] - - # getting the password from the distribution - # if previously set by the register command - if not self.password and self.distribution.password: - self.password = self.distribution.password - - def run(self): - if not self.distribution.dist_files: - msg = ("Must create and upload files in one command " - "(e.g. setup.py sdist upload)") - raise DistutilsOptionError(msg) - for command, pyversion, filename in self.distribution.dist_files: - self.upload_file(command, pyversion, filename) - - def upload_file(self, command, pyversion, filename): - # Makes sure the repository URL is compliant - schema, netloc, url, params, query, fragments = \ - urlparse(self.repository) - if params or query or fragments: - raise AssertionError("Incompatible url %s" % self.repository) - - if schema not in ('http', 'https'): - raise AssertionError("unsupported schema " + schema) - - # Sign if requested - if self.sign: - gpg_args = ["gpg", "--detach-sign", "-a", filename] - if self.identity: - gpg_args[2:2] = ["--local-user", self.identity] - spawn(gpg_args, - dry_run=self.dry_run) - - # Fill in the data - send all the meta-data in case we need to - # register a new release - f = open(filename,'rb') - try: - content = f.read() - finally: - f.close() - - meta = self.distribution.metadata - data = { - # action - ':action': 'file_upload', - 'protocol_version': '1', - - # identify release - 'name': meta.get_name(), - 'version': meta.get_version(), - - # file content - 'content': (os.path.basename(filename),content), - 'filetype': command, - 'pyversion': pyversion, - - # additional meta-data - 'metadata_version': '1.0', - 'summary': meta.get_description(), - 'home_page': meta.get_url(), - 'author': meta.get_contact(), - 'author_email': meta.get_contact_email(), - 'license': meta.get_licence(), - 'description': meta.get_long_description(), - 'keywords': meta.get_keywords(), - 'platform': meta.get_platforms(), - 'classifiers': meta.get_classifiers(), - 'download_url': meta.get_download_url(), - # PEP 314 - 'provides': meta.get_provides(), - 'requires': meta.get_requires(), - 'obsoletes': meta.get_obsoletes(), - } - - data['comment'] = '' - - # file content digests - for digest_name, digest_cons in _FILE_CONTENT_DIGESTS.items(): - if digest_cons is None: - continue - try: - data[digest_name] = digest_cons(content).hexdigest() - except ValueError: - # hash digest not available or blocked by security policy - pass - - if self.sign: - with open(filename + ".asc", "rb") as f: - data['gpg_signature'] = (os.path.basename(filename) + ".asc", - f.read()) - - # set up the authentication - user_pass = (self.username + ":" + self.password).encode('ascii') - # The exact encoding of the authentication string is debated. - # Anyway PyPI only accepts ascii for both username or password. - auth = "Basic " + standard_b64encode(user_pass).decode('ascii') - - # Build up the MIME payload for the POST data - boundary = '--------------GHSKFJDLGDS7543FJKLFHRE75642756743254' - sep_boundary = b'\r\n--' + boundary.encode('ascii') - end_boundary = sep_boundary + b'--\r\n' - body = io.BytesIO() - for key, value in data.items(): - title = '\r\nContent-Disposition: form-data; name="%s"' % key - # handle multiple entries for the same name - if not isinstance(value, list): - value = [value] - for value in value: - if type(value) is tuple: - title += '; filename="%s"' % value[0] - value = value[1] - else: - value = str(value).encode('utf-8') - body.write(sep_boundary) - body.write(title.encode('utf-8')) - body.write(b"\r\n\r\n") - body.write(value) - body.write(end_boundary) - body = body.getvalue() - - msg = "Submitting %s to %s" % (filename, self.repository) - self.announce(msg, log.INFO) - - # build the Request - headers = { - 'Content-type': 'multipart/form-data; boundary=%s' % boundary, - 'Content-length': str(len(body)), - 'Authorization': auth, - } - - request = Request(self.repository, data=body, - headers=headers) - # send the data - try: - result = urlopen(request) - status = result.getcode() - reason = result.msg - except HTTPError as e: - status = e.code - reason = e.msg - except OSError as e: - self.announce(str(e), log.ERROR) - raise - - if status == 200: - self.announce('Server response (%s): %s' % (status, reason), - log.INFO) - if self.show_response: - text = self._read_pypi_response(result) - msg = '\n'.join(('-' * 75, text, '-' * 75)) - self.announce(msg, log.INFO) - else: - msg = 'Upload failed (%s): %s' % (status, reason) - self.announce(msg, log.ERROR) - raise DistutilsError(msg) diff --git a/Lib/distutils/config.py b/Lib/distutils/config.py deleted file mode 100644 index a201c86a..00000000 --- a/Lib/distutils/config.py +++ /dev/null @@ -1,133 +0,0 @@ -"""distutils.pypirc - -Provides the PyPIRCCommand class, the base class for the command classes -that uses .pypirc in the distutils.command package. -""" -import os -from configparser import RawConfigParser -import warnings - -from distutils.cmd import Command - -DEFAULT_PYPIRC = """\ -[distutils] -index-servers = - pypi - -[pypi] -username:%s -password:%s -""" - -class PyPIRCCommand(Command): - """Base command that knows how to handle the .pypirc file - """ - DEFAULT_REPOSITORY = 'https://upload.pypi.org/legacy/' - DEFAULT_REALM = 'pypi' - repository = None - realm = None - - user_options = [ - ('repository=', 'r', - "url of repository [default: %s]" % \ - DEFAULT_REPOSITORY), - ('show-response', None, - 'display full response text from server')] - - boolean_options = ['show-response'] - - def _get_rc_file(self): - """Returns rc file path.""" - return os.path.join(os.path.expanduser('~'), '.pypirc') - - def _store_pypirc(self, username, password): - """Creates a default .pypirc file.""" - rc = self._get_rc_file() - with os.fdopen(os.open(rc, os.O_CREAT | os.O_WRONLY, 0o600), 'w') as f: - f.write(DEFAULT_PYPIRC % (username, password)) - - def _read_pypirc(self): - """Reads the .pypirc file.""" - rc = self._get_rc_file() - if os.path.exists(rc): - self.announce('Using PyPI login from %s' % rc) - repository = self.repository or self.DEFAULT_REPOSITORY - - config = RawConfigParser() - config.read(rc) - sections = config.sections() - if 'distutils' in sections: - # let's get the list of servers - index_servers = config.get('distutils', 'index-servers') - _servers = [server.strip() for server in - index_servers.split('\n') - if server.strip() != ''] - if _servers == []: - # nothing set, let's try to get the default pypi - if 'pypi' in sections: - _servers = ['pypi'] - else: - # the file is not properly defined, returning - # an empty dict - return {} - for server in _servers: - current = {'server': server} - current['username'] = config.get(server, 'username') - - # optional params - for key, default in (('repository', - self.DEFAULT_REPOSITORY), - ('realm', self.DEFAULT_REALM), - ('password', None)): - if config.has_option(server, key): - current[key] = config.get(server, key) - else: - current[key] = default - - # work around people having "repository" for the "pypi" - # section of their config set to the HTTP (rather than - # HTTPS) URL - if (server == 'pypi' and - repository in (self.DEFAULT_REPOSITORY, 'pypi')): - current['repository'] = self.DEFAULT_REPOSITORY - return current - - if (current['server'] == repository or - current['repository'] == repository): - return current - elif 'server-login' in sections: - # old format - server = 'server-login' - if config.has_option(server, 'repository'): - repository = config.get(server, 'repository') - else: - repository = self.DEFAULT_REPOSITORY - return {'username': config.get(server, 'username'), - 'password': config.get(server, 'password'), - 'repository': repository, - 'server': server, - 'realm': self.DEFAULT_REALM} - - return {} - - def _read_pypi_response(self, response): - """Read and decode a PyPI HTTP response.""" - with warnings.catch_warnings(): - warnings.simplefilter("ignore", DeprecationWarning) - import cgi - content_type = response.getheader('content-type', 'text/plain') - encoding = cgi.parse_header(content_type)[1].get('charset', 'ascii') - return response.read().decode(encoding) - - def initialize_options(self): - """Initialize options.""" - self.repository = None - self.realm = None - self.show_response = 0 - - def finalize_options(self): - """Finalizes options.""" - if self.repository is None: - self.repository = self.DEFAULT_REPOSITORY - if self.realm is None: - self.realm = self.DEFAULT_REALM diff --git a/Lib/distutils/core.py b/Lib/distutils/core.py deleted file mode 100644 index d603d4a4..00000000 --- a/Lib/distutils/core.py +++ /dev/null @@ -1,234 +0,0 @@ -"""distutils.core - -The only module that needs to be imported to use the Distutils; provides -the 'setup' function (which is to be called from the setup script). Also -indirectly provides the Distribution and Command classes, although they are -really defined in distutils.dist and distutils.cmd. -""" - -import os -import sys - -from distutils.debug import DEBUG -from distutils.errors import * - -# Mainly import these so setup scripts can "from distutils.core import" them. -from distutils.dist import Distribution -from distutils.cmd import Command -from distutils.config import PyPIRCCommand -from distutils.extension import Extension - -# This is a barebones help message generated displayed when the user -# runs the setup script with no arguments at all. More useful help -# is generated with various --help options: global help, list commands, -# and per-command help. -USAGE = """\ -usage: %(script)s [global_opts] cmd1 [cmd1_opts] [cmd2 [cmd2_opts] ...] - or: %(script)s --help [cmd1 cmd2 ...] - or: %(script)s --help-commands - or: %(script)s cmd --help -""" - -def gen_usage (script_name): - script = os.path.basename(script_name) - return USAGE % vars() - - -# Some mild magic to control the behaviour of 'setup()' from 'run_setup()'. -_setup_stop_after = None -_setup_distribution = None - -# Legal keyword arguments for the setup() function -setup_keywords = ('distclass', 'script_name', 'script_args', 'options', - 'name', 'version', 'author', 'author_email', - 'maintainer', 'maintainer_email', 'url', 'license', - 'description', 'long_description', 'keywords', - 'platforms', 'classifiers', 'download_url', - 'requires', 'provides', 'obsoletes', - ) - -# Legal keyword arguments for the Extension constructor -extension_keywords = ('name', 'sources', 'include_dirs', - 'define_macros', 'undef_macros', - 'library_dirs', 'libraries', 'runtime_library_dirs', - 'extra_objects', 'extra_compile_args', 'extra_link_args', - 'swig_opts', 'export_symbols', 'depends', 'language') - -def setup (**attrs): - """The gateway to the Distutils: do everything your setup script needs - to do, in a highly flexible and user-driven way. Briefly: create a - Distribution instance; find and parse config files; parse the command - line; run each Distutils command found there, customized by the options - supplied to 'setup()' (as keyword arguments), in config files, and on - the command line. - - The Distribution instance might be an instance of a class supplied via - the 'distclass' keyword argument to 'setup'; if no such class is - supplied, then the Distribution class (in dist.py) is instantiated. - All other arguments to 'setup' (except for 'cmdclass') are used to set - attributes of the Distribution instance. - - The 'cmdclass' argument, if supplied, is a dictionary mapping command - names to command classes. Each command encountered on the command line - will be turned into a command class, which is in turn instantiated; any - class found in 'cmdclass' is used in place of the default, which is - (for command 'foo_bar') class 'foo_bar' in module - 'distutils.command.foo_bar'. The command class must provide a - 'user_options' attribute which is a list of option specifiers for - 'distutils.fancy_getopt'. Any command-line options between the current - and the next command are used to set attributes of the current command - object. - - When the entire command-line has been successfully parsed, calls the - 'run()' method on each command object in turn. This method will be - driven entirely by the Distribution object (which each command object - has a reference to, thanks to its constructor), and the - command-specific options that became attributes of each command - object. - """ - - global _setup_stop_after, _setup_distribution - - # Determine the distribution class -- either caller-supplied or - # our Distribution (see below). - klass = attrs.get('distclass') - if klass: - del attrs['distclass'] - else: - klass = Distribution - - if 'script_name' not in attrs: - attrs['script_name'] = os.path.basename(sys.argv[0]) - if 'script_args' not in attrs: - attrs['script_args'] = sys.argv[1:] - - # Create the Distribution instance, using the remaining arguments - # (ie. everything except distclass) to initialize it - try: - _setup_distribution = dist = klass(attrs) - except DistutilsSetupError as msg: - if 'name' not in attrs: - raise SystemExit("error in setup command: %s" % msg) - else: - raise SystemExit("error in %s setup command: %s" % \ - (attrs['name'], msg)) - - if _setup_stop_after == "init": - return dist - - # Find and parse the config file(s): they will override options from - # the setup script, but be overridden by the command line. - dist.parse_config_files() - - if DEBUG: - print("options (after parsing config files):") - dist.dump_option_dicts() - - if _setup_stop_after == "config": - return dist - - # Parse the command line and override config files; any - # command-line errors are the end user's fault, so turn them into - # SystemExit to suppress tracebacks. - try: - ok = dist.parse_command_line() - except DistutilsArgError as msg: - raise SystemExit(gen_usage(dist.script_name) + "\nerror: %s" % msg) - - if DEBUG: - print("options (after parsing command line):") - dist.dump_option_dicts() - - if _setup_stop_after == "commandline": - return dist - - # And finally, run all the commands found on the command line. - if ok: - try: - dist.run_commands() - except KeyboardInterrupt: - raise SystemExit("interrupted") - except OSError as exc: - if DEBUG: - sys.stderr.write("error: %s\n" % (exc,)) - raise - else: - raise SystemExit("error: %s" % (exc,)) - - except (DistutilsError, - CCompilerError) as msg: - if DEBUG: - raise - else: - raise SystemExit("error: " + str(msg)) - - return dist - -# setup () - - -def run_setup (script_name, script_args=None, stop_after="run"): - """Run a setup script in a somewhat controlled environment, and - return the Distribution instance that drives things. This is useful - if you need to find out the distribution meta-data (passed as - keyword args from 'script' to 'setup()', or the contents of the - config files or command-line. - - 'script_name' is a file that will be read and run with 'exec()'; - 'sys.argv[0]' will be replaced with 'script' for the duration of the - call. 'script_args' is a list of strings; if supplied, - 'sys.argv[1:]' will be replaced by 'script_args' for the duration of - the call. - - 'stop_after' tells 'setup()' when to stop processing; possible - values: - init - stop after the Distribution instance has been created and - populated with the keyword arguments to 'setup()' - config - stop after config files have been parsed (and their data - stored in the Distribution instance) - commandline - stop after the command-line ('sys.argv[1:]' or 'script_args') - have been parsed (and the data stored in the Distribution) - run [default] - stop after all commands have been run (the same as if 'setup()' - had been called in the usual way - - Returns the Distribution instance, which provides all information - used to drive the Distutils. - """ - if stop_after not in ('init', 'config', 'commandline', 'run'): - raise ValueError("invalid value for 'stop_after': %r" % (stop_after,)) - - global _setup_stop_after, _setup_distribution - _setup_stop_after = stop_after - - save_argv = sys.argv.copy() - g = {'__file__': script_name} - try: - try: - sys.argv[0] = script_name - if script_args is not None: - sys.argv[1:] = script_args - with open(script_name, 'rb') as f: - exec(f.read(), g) - finally: - sys.argv = save_argv - _setup_stop_after = None - except SystemExit: - # Hmm, should we do something if exiting with a non-zero code - # (ie. error)? - pass - - if _setup_distribution is None: - raise RuntimeError(("'distutils.core.setup()' was never called -- " - "perhaps '%s' is not a Distutils setup script?") % \ - script_name) - - # I wonder if the setup script's namespace -- g and l -- would be of - # any interest to callers? - #print "_setup_distribution:", _setup_distribution - return _setup_distribution - -# run_setup () diff --git a/Lib/distutils/dep_util.py b/Lib/distutils/dep_util.py deleted file mode 100644 index d74f5e4e..00000000 --- a/Lib/distutils/dep_util.py +++ /dev/null @@ -1,92 +0,0 @@ -"""distutils.dep_util - -Utility functions for simple, timestamp-based dependency of files -and groups of files; also, function based entirely on such -timestamp dependency analysis.""" - -import os -from distutils.errors import DistutilsFileError - - -def newer (source, target): - """Return true if 'source' exists and is more recently modified than - 'target', or if 'source' exists and 'target' doesn't. Return false if - both exist and 'target' is the same age or younger than 'source'. - Raise DistutilsFileError if 'source' does not exist. - """ - if not os.path.exists(source): - raise DistutilsFileError("file '%s' does not exist" % - os.path.abspath(source)) - if not os.path.exists(target): - return 1 - - from stat import ST_MTIME - mtime1 = os.stat(source)[ST_MTIME] - mtime2 = os.stat(target)[ST_MTIME] - - return mtime1 > mtime2 - -# newer () - - -def newer_pairwise (sources, targets): - """Walk two filename lists in parallel, testing if each source is newer - than its corresponding target. Return a pair of lists (sources, - targets) where source is newer than target, according to the semantics - of 'newer()'. - """ - if len(sources) != len(targets): - raise ValueError("'sources' and 'targets' must be same length") - - # build a pair of lists (sources, targets) where source is newer - n_sources = [] - n_targets = [] - for i in range(len(sources)): - if newer(sources[i], targets[i]): - n_sources.append(sources[i]) - n_targets.append(targets[i]) - - return (n_sources, n_targets) - -# newer_pairwise () - - -def newer_group (sources, target, missing='error'): - """Return true if 'target' is out-of-date with respect to any file - listed in 'sources'. In other words, if 'target' exists and is newer - than every file in 'sources', return false; otherwise return true. - 'missing' controls what we do when a source file is missing; the - default ("error") is to blow up with an OSError from inside 'stat()'; - if it is "ignore", we silently drop any missing source files; if it is - "newer", any missing source files make us assume that 'target' is - out-of-date (this is handy in "dry-run" mode: it'll make you pretend to - carry out commands that wouldn't work because inputs are missing, but - that doesn't matter because you're not actually going to run the - commands). - """ - # If the target doesn't even exist, then it's definitely out-of-date. - if not os.path.exists(target): - return 1 - - # Otherwise we have to find out the hard way: if *any* source file - # is more recent than 'target', then 'target' is out-of-date and - # we can immediately return true. If we fall through to the end - # of the loop, then 'target' is up-to-date and we return false. - from stat import ST_MTIME - target_mtime = os.stat(target)[ST_MTIME] - for source in sources: - if not os.path.exists(source): - if missing == 'error': # blow up when we stat() the file - pass - elif missing == 'ignore': # missing source dropped from - continue # target's dependency list - elif missing == 'newer': # missing source means target is - return 1 # out-of-date - - source_mtime = os.stat(source)[ST_MTIME] - if source_mtime > target_mtime: - return 1 - else: - return 0 - -# newer_group () diff --git a/Lib/distutils/dir_util.py b/Lib/distutils/dir_util.py deleted file mode 100644 index d5cd8e3e..00000000 --- a/Lib/distutils/dir_util.py +++ /dev/null @@ -1,210 +0,0 @@ -"""distutils.dir_util - -Utility functions for manipulating directories and directory trees.""" - -import os -import errno -from distutils.errors import DistutilsFileError, DistutilsInternalError -from distutils import log - -# cache for by mkpath() -- in addition to cheapening redundant calls, -# eliminates redundant "creating /foo/bar/baz" messages in dry-run mode -_path_created = {} - -# I don't use os.makedirs because a) it's new to Python 1.5.2, and -# b) it blows up if the directory already exists (I want to silently -# succeed in that case). -def mkpath(name, mode=0o777, verbose=1, dry_run=0): - """Create a directory and any missing ancestor directories. - - If the directory already exists (or if 'name' is the empty string, which - means the current directory, which of course exists), then do nothing. - Raise DistutilsFileError if unable to create some directory along the way - (eg. some sub-path exists, but is a file rather than a directory). - If 'verbose' is true, print a one-line summary of each mkdir to stdout. - Return the list of directories actually created. - """ - - global _path_created - - # Detect a common bug -- name is None - if not isinstance(name, str): - raise DistutilsInternalError( - "mkpath: 'name' must be a string (got %r)" % (name,)) - - # XXX what's the better way to handle verbosity? print as we create - # each directory in the path (the current behaviour), or only announce - # the creation of the whole path? (quite easy to do the latter since - # we're not using a recursive algorithm) - - name = os.path.normpath(name) - created_dirs = [] - if os.path.isdir(name) or name == '': - return created_dirs - if _path_created.get(os.path.abspath(name)): - return created_dirs - - (head, tail) = os.path.split(name) - tails = [tail] # stack of lone dirs to create - - while head and tail and not os.path.isdir(head): - (head, tail) = os.path.split(head) - tails.insert(0, tail) # push next higher dir onto stack - - # now 'head' contains the deepest directory that already exists - # (that is, the child of 'head' in 'name' is the highest directory - # that does *not* exist) - for d in tails: - #print "head = %s, d = %s: " % (head, d), - head = os.path.join(head, d) - abs_head = os.path.abspath(head) - - if _path_created.get(abs_head): - continue - - if verbose >= 1: - log.info("creating %s", head) - - if not dry_run: - try: - os.mkdir(head, mode) - except OSError as exc: - if not (exc.errno == errno.EEXIST and os.path.isdir(head)): - raise DistutilsFileError( - "could not create '%s': %s" % (head, exc.args[-1])) - created_dirs.append(head) - - _path_created[abs_head] = 1 - return created_dirs - -def create_tree(base_dir, files, mode=0o777, verbose=1, dry_run=0): - """Create all the empty directories under 'base_dir' needed to put 'files' - there. - - 'base_dir' is just the name of a directory which doesn't necessarily - exist yet; 'files' is a list of filenames to be interpreted relative to - 'base_dir'. 'base_dir' + the directory portion of every file in 'files' - will be created if it doesn't already exist. 'mode', 'verbose' and - 'dry_run' flags are as for 'mkpath()'. - """ - # First get the list of directories to create - need_dir = set() - for file in files: - need_dir.add(os.path.join(base_dir, os.path.dirname(file))) - - # Now create them - for dir in sorted(need_dir): - mkpath(dir, mode, verbose=verbose, dry_run=dry_run) - -def copy_tree(src, dst, preserve_mode=1, preserve_times=1, - preserve_symlinks=0, update=0, verbose=1, dry_run=0): - """Copy an entire directory tree 'src' to a new location 'dst'. - - Both 'src' and 'dst' must be directory names. If 'src' is not a - directory, raise DistutilsFileError. If 'dst' does not exist, it is - created with 'mkpath()'. The end result of the copy is that every - file in 'src' is copied to 'dst', and directories under 'src' are - recursively copied to 'dst'. Return the list of files that were - copied or might have been copied, using their output name. The - return value is unaffected by 'update' or 'dry_run': it is simply - the list of all files under 'src', with the names changed to be - under 'dst'. - - 'preserve_mode' and 'preserve_times' are the same as for - 'copy_file'; note that they only apply to regular files, not to - directories. If 'preserve_symlinks' is true, symlinks will be - copied as symlinks (on platforms that support them!); otherwise - (the default), the destination of the symlink will be copied. - 'update' and 'verbose' are the same as for 'copy_file'. - """ - from distutils.file_util import copy_file - - if not dry_run and not os.path.isdir(src): - raise DistutilsFileError( - "cannot copy tree '%s': not a directory" % src) - try: - names = os.listdir(src) - except OSError as e: - if dry_run: - names = [] - else: - raise DistutilsFileError( - "error listing files in '%s': %s" % (src, e.strerror)) - - if not dry_run: - mkpath(dst, verbose=verbose) - - outputs = [] - - for n in names: - src_name = os.path.join(src, n) - dst_name = os.path.join(dst, n) - - if n.startswith('.nfs'): - # skip NFS rename files - continue - - if preserve_symlinks and os.path.islink(src_name): - link_dest = os.readlink(src_name) - if verbose >= 1: - log.info("linking %s -> %s", dst_name, link_dest) - if not dry_run: - os.symlink(link_dest, dst_name) - outputs.append(dst_name) - - elif os.path.isdir(src_name): - outputs.extend( - copy_tree(src_name, dst_name, preserve_mode, - preserve_times, preserve_symlinks, update, - verbose=verbose, dry_run=dry_run)) - else: - copy_file(src_name, dst_name, preserve_mode, - preserve_times, update, verbose=verbose, - dry_run=dry_run) - outputs.append(dst_name) - - return outputs - -def _build_cmdtuple(path, cmdtuples): - """Helper for remove_tree().""" - for f in os.listdir(path): - real_f = os.path.join(path,f) - if os.path.isdir(real_f) and not os.path.islink(real_f): - _build_cmdtuple(real_f, cmdtuples) - else: - cmdtuples.append((os.remove, real_f)) - cmdtuples.append((os.rmdir, path)) - -def remove_tree(directory, verbose=1, dry_run=0): - """Recursively remove an entire directory tree. - - Any errors are ignored (apart from being reported to stdout if 'verbose' - is true). - """ - global _path_created - - if verbose >= 1: - log.info("removing '%s' (and everything under it)", directory) - if dry_run: - return - cmdtuples = [] - _build_cmdtuple(directory, cmdtuples) - for cmd in cmdtuples: - try: - cmd[0](cmd[1]) - # remove dir from cache if it's already there - abspath = os.path.abspath(cmd[1]) - if abspath in _path_created: - del _path_created[abspath] - except OSError as exc: - log.warn("error removing %s: %s", directory, exc) - -def ensure_relative(path): - """Take the full path 'path', and make it a relative path. - - This is useful to make 'path' the second argument to os.path.join(). - """ - drive, path = os.path.splitdrive(path) - if path[0:1] == os.sep: - path = drive + path[1:] - return path diff --git a/Lib/distutils/dist.py b/Lib/distutils/dist.py deleted file mode 100644 index 6cf0a0d6..00000000 --- a/Lib/distutils/dist.py +++ /dev/null @@ -1,1256 +0,0 @@ -"""distutils.dist - -Provides the Distribution class, which represents the module distribution -being built/installed/distributed. -""" - -import sys -import os -import re -from email import message_from_file - -try: - import warnings -except ImportError: - warnings = None - -from distutils.errors import * -from distutils.fancy_getopt import FancyGetopt, translate_longopt -from distutils.util import check_environ, strtobool, rfc822_escape -from distutils import log -from distutils.debug import DEBUG - -# Regex to define acceptable Distutils command names. This is not *quite* -# the same as a Python NAME -- I don't allow leading underscores. The fact -# that they're very similar is no coincidence; the default naming scheme is -# to look for a Python module named after the command. -command_re = re.compile(r'^[a-zA-Z]([a-zA-Z0-9_]*)$') - - -def _ensure_list(value, fieldname): - if isinstance(value, str): - # a string containing comma separated values is okay. It will - # be converted to a list by Distribution.finalize_options(). - pass - elif not isinstance(value, list): - # passing a tuple or an iterator perhaps, warn and convert - typename = type(value).__name__ - msg = f"Warning: '{fieldname}' should be a list, got type '{typename}'" - log.log(log.WARN, msg) - value = list(value) - return value - - -class Distribution: - """The core of the Distutils. Most of the work hiding behind 'setup' - is really done within a Distribution instance, which farms the work out - to the Distutils commands specified on the command line. - - Setup scripts will almost never instantiate Distribution directly, - unless the 'setup()' function is totally inadequate to their needs. - However, it is conceivable that a setup script might wish to subclass - Distribution for some specialized purpose, and then pass the subclass - to 'setup()' as the 'distclass' keyword argument. If so, it is - necessary to respect the expectations that 'setup' has of Distribution. - See the code for 'setup()', in core.py, for details. - """ - - # 'global_options' describes the command-line options that may be - # supplied to the setup script prior to any actual commands. - # Eg. "./setup.py -n" or "./setup.py --quiet" both take advantage of - # these global options. This list should be kept to a bare minimum, - # since every global option is also valid as a command option -- and we - # don't want to pollute the commands with too many options that they - # have minimal control over. - # The fourth entry for verbose means that it can be repeated. - global_options = [ - ('verbose', 'v', "run verbosely (default)", 1), - ('quiet', 'q', "run quietly (turns verbosity off)"), - ('dry-run', 'n', "don't actually do anything"), - ('help', 'h', "show detailed help message"), - ('no-user-cfg', None, - 'ignore pydistutils.cfg in your home directory'), - ] - - # 'common_usage' is a short (2-3 line) string describing the common - # usage of the setup script. - common_usage = """\ -Common commands: (see '--help-commands' for more) - - setup.py build will build the package underneath 'build/' - setup.py install will install the package -""" - - # options that are not propagated to the commands - display_options = [ - ('help-commands', None, - "list all available commands"), - ('name', None, - "print package name"), - ('version', 'V', - "print package version"), - ('fullname', None, - "print <package name>-<version>"), - ('author', None, - "print the author's name"), - ('author-email', None, - "print the author's email address"), - ('maintainer', None, - "print the maintainer's name"), - ('maintainer-email', None, - "print the maintainer's email address"), - ('contact', None, - "print the maintainer's name if known, else the author's"), - ('contact-email', None, - "print the maintainer's email address if known, else the author's"), - ('url', None, - "print the URL for this package"), - ('license', None, - "print the license of the package"), - ('licence', None, - "alias for --license"), - ('description', None, - "print the package description"), - ('long-description', None, - "print the long package description"), - ('platforms', None, - "print the list of platforms"), - ('classifiers', None, - "print the list of classifiers"), - ('keywords', None, - "print the list of keywords"), - ('provides', None, - "print the list of packages/modules provided"), - ('requires', None, - "print the list of packages/modules required"), - ('obsoletes', None, - "print the list of packages/modules made obsolete") - ] - display_option_names = [translate_longopt(x[0]) for x in display_options] - - # negative options are options that exclude other options - negative_opt = {'quiet': 'verbose'} - - # -- Creation/initialization methods ------------------------------- - - def __init__(self, attrs=None): - """Construct a new Distribution instance: initialize all the - attributes of a Distribution, and then use 'attrs' (a dictionary - mapping attribute names to values) to assign some of those - attributes their "real" values. (Any attributes not mentioned in - 'attrs' will be assigned to some null value: 0, None, an empty list - or dictionary, etc.) Most importantly, initialize the - 'command_obj' attribute to the empty dictionary; this will be - filled in with real command objects by 'parse_command_line()'. - """ - - # Default values for our command-line options - self.verbose = 1 - self.dry_run = 0 - self.help = 0 - for attr in self.display_option_names: - setattr(self, attr, 0) - - # Store the distribution meta-data (name, version, author, and so - # forth) in a separate object -- we're getting to have enough - # information here (and enough command-line options) that it's - # worth it. Also delegate 'get_XXX()' methods to the 'metadata' - # object in a sneaky and underhanded (but efficient!) way. - self.metadata = DistributionMetadata() - for basename in self.metadata._METHOD_BASENAMES: - method_name = "get_" + basename - setattr(self, method_name, getattr(self.metadata, method_name)) - - # 'cmdclass' maps command names to class objects, so we - # can 1) quickly figure out which class to instantiate when - # we need to create a new command object, and 2) have a way - # for the setup script to override command classes - self.cmdclass = {} - - # 'command_packages' is a list of packages in which commands - # are searched for. The factory for command 'foo' is expected - # to be named 'foo' in the module 'foo' in one of the packages - # named here. This list is searched from the left; an error - # is raised if no named package provides the command being - # searched for. (Always access using get_command_packages().) - self.command_packages = None - - # 'script_name' and 'script_args' are usually set to sys.argv[0] - # and sys.argv[1:], but they can be overridden when the caller is - # not necessarily a setup script run from the command-line. - self.script_name = None - self.script_args = None - - # 'command_options' is where we store command options between - # parsing them (from config files, the command-line, etc.) and when - # they are actually needed -- ie. when the command in question is - # instantiated. It is a dictionary of dictionaries of 2-tuples: - # command_options = { command_name : { option : (source, value) } } - self.command_options = {} - - # 'dist_files' is the list of (command, pyversion, file) that - # have been created by any dist commands run so far. This is - # filled regardless of whether the run is dry or not. pyversion - # gives sysconfig.get_python_version() if the dist file is - # specific to a Python version, 'any' if it is good for all - # Python versions on the target platform, and '' for a source - # file. pyversion should not be used to specify minimum or - # maximum required Python versions; use the metainfo for that - # instead. - self.dist_files = [] - - # These options are really the business of various commands, rather - # than of the Distribution itself. We provide aliases for them in - # Distribution as a convenience to the developer. - self.packages = None - self.package_data = {} - self.package_dir = None - self.py_modules = None - self.libraries = None - self.headers = None - self.ext_modules = None - self.ext_package = None - self.include_dirs = None - self.extra_path = None - self.scripts = None - self.data_files = None - self.password = '' - - # And now initialize bookkeeping stuff that can't be supplied by - # the caller at all. 'command_obj' maps command names to - # Command instances -- that's how we enforce that every command - # class is a singleton. - self.command_obj = {} - - # 'have_run' maps command names to boolean values; it keeps track - # of whether we have actually run a particular command, to make it - # cheap to "run" a command whenever we think we might need to -- if - # it's already been done, no need for expensive filesystem - # operations, we just check the 'have_run' dictionary and carry on. - # It's only safe to query 'have_run' for a command class that has - # been instantiated -- a false value will be inserted when the - # command object is created, and replaced with a true value when - # the command is successfully run. Thus it's probably best to use - # '.get()' rather than a straight lookup. - self.have_run = {} - - # Now we'll use the attrs dictionary (ultimately, keyword args from - # the setup script) to possibly override any or all of these - # distribution options. - - if attrs: - # Pull out the set of command options and work on them - # specifically. Note that this order guarantees that aliased - # command options will override any supplied redundantly - # through the general options dictionary. - options = attrs.get('options') - if options is not None: - del attrs['options'] - for (command, cmd_options) in options.items(): - opt_dict = self.get_option_dict(command) - for (opt, val) in cmd_options.items(): - opt_dict[opt] = ("setup script", val) - - if 'licence' in attrs: - attrs['license'] = attrs['licence'] - del attrs['licence'] - msg = "'licence' distribution option is deprecated; use 'license'" - if warnings is not None: - warnings.warn(msg) - else: - sys.stderr.write(msg + "\n") - - # Now work on the rest of the attributes. Any attribute that's - # not already defined is invalid! - for (key, val) in attrs.items(): - if hasattr(self.metadata, "set_" + key): - getattr(self.metadata, "set_" + key)(val) - elif hasattr(self.metadata, key): - setattr(self.metadata, key, val) - elif hasattr(self, key): - setattr(self, key, val) - else: - msg = "Unknown distribution option: %s" % repr(key) - warnings.warn(msg) - - # no-user-cfg is handled before other command line args - # because other args override the config files, and this - # one is needed before we can load the config files. - # If attrs['script_args'] wasn't passed, assume false. - # - # This also make sure we just look at the global options - self.want_user_cfg = True - - if self.script_args is not None: - for arg in self.script_args: - if not arg.startswith('-'): - break - if arg == '--no-user-cfg': - self.want_user_cfg = False - break - - self.finalize_options() - - def get_option_dict(self, command): - """Get the option dictionary for a given command. If that - command's option dictionary hasn't been created yet, then create it - and return the new dictionary; otherwise, return the existing - option dictionary. - """ - dict = self.command_options.get(command) - if dict is None: - dict = self.command_options[command] = {} - return dict - - def dump_option_dicts(self, header=None, commands=None, indent=""): - from pprint import pformat - - if commands is None: # dump all command option dicts - commands = sorted(self.command_options.keys()) - - if header is not None: - self.announce(indent + header) - indent = indent + " " - - if not commands: - self.announce(indent + "no commands known yet") - return - - for cmd_name in commands: - opt_dict = self.command_options.get(cmd_name) - if opt_dict is None: - self.announce(indent + - "no option dict for '%s' command" % cmd_name) - else: - self.announce(indent + - "option dict for '%s' command:" % cmd_name) - out = pformat(opt_dict) - for line in out.split('\n'): - self.announce(indent + " " + line) - - # -- Config file finding/parsing methods --------------------------- - - def find_config_files(self): - """Find as many configuration files as should be processed for this - platform, and return a list of filenames in the order in which they - should be parsed. The filenames returned are guaranteed to exist - (modulo nasty race conditions). - - There are three possible config files: distutils.cfg in the - Distutils installation directory (ie. where the top-level - Distutils __inst__.py file lives), a file in the user's home - directory named .pydistutils.cfg on Unix and pydistutils.cfg - on Windows/Mac; and setup.cfg in the current directory. - - The file in the user's home directory can be disabled with the - --no-user-cfg option. - """ - files = [] - check_environ() - - # Where to look for the system-wide Distutils config file - sys_dir = os.path.dirname(sys.modules['distutils'].__file__) - - # Look for the system config file - sys_file = os.path.join(sys_dir, "distutils.cfg") - if os.path.isfile(sys_file): - files.append(sys_file) - - # What to call the per-user config file - if os.name == 'posix': - user_filename = ".pydistutils.cfg" - else: - user_filename = "pydistutils.cfg" - - # And look for the user config file - if self.want_user_cfg: - user_file = os.path.join(os.path.expanduser('~'), user_filename) - if os.path.isfile(user_file): - files.append(user_file) - - # All platforms support local setup.cfg - local_file = "setup.cfg" - if os.path.isfile(local_file): - files.append(local_file) - - if DEBUG: - self.announce("using config files: %s" % ', '.join(files)) - - return files - - def parse_config_files(self, filenames=None): - from configparser import ConfigParser - - # Ignore install directory options if we have a venv - if sys.prefix != sys.base_prefix: - ignore_options = [ - 'install-base', 'install-platbase', 'install-lib', - 'install-platlib', 'install-purelib', 'install-headers', - 'install-scripts', 'install-data', 'prefix', 'exec-prefix', - 'home', 'user', 'root'] - else: - ignore_options = [] - - ignore_options = frozenset(ignore_options) - - if filenames is None: - filenames = self.find_config_files() - - if DEBUG: - self.announce("Distribution.parse_config_files():") - - parser = ConfigParser() - for filename in filenames: - if DEBUG: - self.announce(" reading %s" % filename) - parser.read(filename) - for section in parser.sections(): - options = parser.options(section) - opt_dict = self.get_option_dict(section) - - for opt in options: - if opt != '__name__' and opt not in ignore_options: - val = parser.get(section,opt) - opt = opt.replace('-', '_') - opt_dict[opt] = (filename, val) - - # Make the ConfigParser forget everything (so we retain - # the original filenames that options come from) - parser.__init__() - - # If there was a "global" section in the config file, use it - # to set Distribution options. - - if 'global' in self.command_options: - for (opt, (src, val)) in self.command_options['global'].items(): - alias = self.negative_opt.get(opt) - try: - if alias: - setattr(self, alias, not strtobool(val)) - elif opt in ('verbose', 'dry_run'): # ugh! - setattr(self, opt, strtobool(val)) - else: - setattr(self, opt, val) - except ValueError as msg: - raise DistutilsOptionError(msg) - - # -- Command-line parsing methods ---------------------------------- - - def parse_command_line(self): - """Parse the setup script's command line, taken from the - 'script_args' instance attribute (which defaults to 'sys.argv[1:]' - -- see 'setup()' in core.py). This list is first processed for - "global options" -- options that set attributes of the Distribution - instance. Then, it is alternately scanned for Distutils commands - and options for that command. Each new command terminates the - options for the previous command. The allowed options for a - command are determined by the 'user_options' attribute of the - command class -- thus, we have to be able to load command classes - in order to parse the command line. Any error in that 'options' - attribute raises DistutilsGetoptError; any error on the - command-line raises DistutilsArgError. If no Distutils commands - were found on the command line, raises DistutilsArgError. Return - true if command-line was successfully parsed and we should carry - on with executing commands; false if no errors but we shouldn't - execute commands (currently, this only happens if user asks for - help). - """ - # - # We now have enough information to show the Macintosh dialog - # that allows the user to interactively specify the "command line". - # - toplevel_options = self._get_toplevel_options() - - # We have to parse the command line a bit at a time -- global - # options, then the first command, then its options, and so on -- - # because each command will be handled by a different class, and - # the options that are valid for a particular class aren't known - # until we have loaded the command class, which doesn't happen - # until we know what the command is. - - self.commands = [] - parser = FancyGetopt(toplevel_options + self.display_options) - parser.set_negative_aliases(self.negative_opt) - parser.set_aliases({'licence': 'license'}) - args = parser.getopt(args=self.script_args, object=self) - option_order = parser.get_option_order() - log.set_verbosity(self.verbose) - - # for display options we return immediately - if self.handle_display_options(option_order): - return - while args: - args = self._parse_command_opts(parser, args) - if args is None: # user asked for help (and got it) - return - - # Handle the cases of --help as a "global" option, ie. - # "setup.py --help" and "setup.py --help command ...". For the - # former, we show global options (--verbose, --dry-run, etc.) - # and display-only options (--name, --version, etc.); for the - # latter, we omit the display-only options and show help for - # each command listed on the command line. - if self.help: - self._show_help(parser, - display_options=len(self.commands) == 0, - commands=self.commands) - return - - # Oops, no commands found -- an end-user error - if not self.commands: - raise DistutilsArgError("no commands supplied") - - # All is well: return true - return True - - def _get_toplevel_options(self): - """Return the non-display options recognized at the top level. - - This includes options that are recognized *only* at the top - level as well as options recognized for commands. - """ - return self.global_options + [ - ("command-packages=", None, - "list of packages that provide distutils commands"), - ] - - def _parse_command_opts(self, parser, args): - """Parse the command-line options for a single command. - 'parser' must be a FancyGetopt instance; 'args' must be the list - of arguments, starting with the current command (whose options - we are about to parse). Returns a new version of 'args' with - the next command at the front of the list; will be the empty - list if there are no more commands on the command line. Returns - None if the user asked for help on this command. - """ - # late import because of mutual dependence between these modules - from distutils.cmd import Command - - # Pull the current command from the head of the command line - command = args[0] - if not command_re.match(command): - raise SystemExit("invalid command name '%s'" % command) - self.commands.append(command) - - # Dig up the command class that implements this command, so we - # 1) know that it's a valid command, and 2) know which options - # it takes. - try: - cmd_class = self.get_command_class(command) - except DistutilsModuleError as msg: - raise DistutilsArgError(msg) - - # Require that the command class be derived from Command -- want - # to be sure that the basic "command" interface is implemented. - if not issubclass(cmd_class, Command): - raise DistutilsClassError( - "command class %s must subclass Command" % cmd_class) - - # Also make sure that the command object provides a list of its - # known options. - if not (hasattr(cmd_class, 'user_options') and - isinstance(cmd_class.user_options, list)): - msg = ("command class %s must provide " - "'user_options' attribute (a list of tuples)") - raise DistutilsClassError(msg % cmd_class) - - # If the command class has a list of negative alias options, - # merge it in with the global negative aliases. - negative_opt = self.negative_opt - if hasattr(cmd_class, 'negative_opt'): - negative_opt = negative_opt.copy() - negative_opt.update(cmd_class.negative_opt) - - # Check for help_options in command class. They have a different - # format (tuple of four) so we need to preprocess them here. - if (hasattr(cmd_class, 'help_options') and - isinstance(cmd_class.help_options, list)): - help_options = fix_help_options(cmd_class.help_options) - else: - help_options = [] - - # All commands support the global options too, just by adding - # in 'global_options'. - parser.set_option_table(self.global_options + - cmd_class.user_options + - help_options) - parser.set_negative_aliases(negative_opt) - (args, opts) = parser.getopt(args[1:]) - if hasattr(opts, 'help') and opts.help: - self._show_help(parser, display_options=0, commands=[cmd_class]) - return - - if (hasattr(cmd_class, 'help_options') and - isinstance(cmd_class.help_options, list)): - help_option_found=0 - for (help_option, short, desc, func) in cmd_class.help_options: - if hasattr(opts, parser.get_attr_name(help_option)): - help_option_found=1 - if callable(func): - func() - else: - raise DistutilsClassError( - "invalid help function %r for help option '%s': " - "must be a callable object (function, etc.)" - % (func, help_option)) - - if help_option_found: - return - - # Put the options from the command-line into their official - # holding pen, the 'command_options' dictionary. - opt_dict = self.get_option_dict(command) - for (name, value) in vars(opts).items(): - opt_dict[name] = ("command line", value) - - return args - - def finalize_options(self): - """Set final values for all the options on the Distribution - instance, analogous to the .finalize_options() method of Command - objects. - """ - for attr in ('keywords', 'platforms'): - value = getattr(self.metadata, attr) - if value is None: - continue - if isinstance(value, str): - value = [elm.strip() for elm in value.split(',')] - setattr(self.metadata, attr, value) - - def _show_help(self, parser, global_options=1, display_options=1, - commands=[]): - """Show help for the setup script command-line in the form of - several lists of command-line options. 'parser' should be a - FancyGetopt instance; do not expect it to be returned in the - same state, as its option table will be reset to make it - generate the correct help text. - - If 'global_options' is true, lists the global options: - --verbose, --dry-run, etc. If 'display_options' is true, lists - the "display-only" options: --name, --version, etc. Finally, - lists per-command help for every command name or command class - in 'commands'. - """ - # late import because of mutual dependence between these modules - from distutils.core import gen_usage - from distutils.cmd import Command - - if global_options: - if display_options: - options = self._get_toplevel_options() - else: - options = self.global_options - parser.set_option_table(options) - parser.print_help(self.common_usage + "\nGlobal options:") - print('') - - if display_options: - parser.set_option_table(self.display_options) - parser.print_help( - "Information display options (just display " + - "information, ignore any commands)") - print('') - - for command in self.commands: - if isinstance(command, type) and issubclass(command, Command): - klass = command - else: - klass = self.get_command_class(command) - if (hasattr(klass, 'help_options') and - isinstance(klass.help_options, list)): - parser.set_option_table(klass.user_options + - fix_help_options(klass.help_options)) - else: - parser.set_option_table(klass.user_options) - parser.print_help("Options for '%s' command:" % klass.__name__) - print('') - - print(gen_usage(self.script_name)) - - def handle_display_options(self, option_order): - """If there were any non-global "display-only" options - (--help-commands or the metadata display options) on the command - line, display the requested info and return true; else return - false. - """ - from distutils.core import gen_usage - - # User just wants a list of commands -- we'll print it out and stop - # processing now (ie. if they ran "setup --help-commands foo bar", - # we ignore "foo bar"). - if self.help_commands: - self.print_commands() - print('') - print(gen_usage(self.script_name)) - return 1 - - # If user supplied any of the "display metadata" options, then - # display that metadata in the order in which the user supplied the - # metadata options. - any_display_options = 0 - is_display_option = {} - for option in self.display_options: - is_display_option[option[0]] = 1 - - for (opt, val) in option_order: - if val and is_display_option.get(opt): - opt = translate_longopt(opt) - value = getattr(self.metadata, "get_"+opt)() - if opt in ['keywords', 'platforms']: - print(','.join(value)) - elif opt in ('classifiers', 'provides', 'requires', - 'obsoletes'): - print('\n'.join(value)) - else: - print(value) - any_display_options = 1 - - return any_display_options - - def print_command_list(self, commands, header, max_length): - """Print a subset of the list of all commands -- used by - 'print_commands()'. - """ - print(header + ":") - - for cmd in commands: - klass = self.cmdclass.get(cmd) - if not klass: - klass = self.get_command_class(cmd) - try: - description = klass.description - except AttributeError: - description = "(no description available)" - - print(" %-*s %s" % (max_length, cmd, description)) - - def print_commands(self): - """Print out a help message listing all available commands with a - description of each. The list is divided into "standard commands" - (listed in distutils.command.__all__) and "extra commands" - (mentioned in self.cmdclass, but not a standard command). The - descriptions come from the command class attribute - 'description'. - """ - import distutils.command - std_commands = distutils.command.__all__ - is_std = {} - for cmd in std_commands: - is_std[cmd] = 1 - - extra_commands = [] - for cmd in self.cmdclass.keys(): - if not is_std.get(cmd): - extra_commands.append(cmd) - - max_length = 0 - for cmd in (std_commands + extra_commands): - if len(cmd) > max_length: - max_length = len(cmd) - - self.print_command_list(std_commands, - "Standard commands", - max_length) - if extra_commands: - print() - self.print_command_list(extra_commands, - "Extra commands", - max_length) - - def get_command_list(self): - """Get a list of (command, description) tuples. - The list is divided into "standard commands" (listed in - distutils.command.__all__) and "extra commands" (mentioned in - self.cmdclass, but not a standard command). The descriptions come - from the command class attribute 'description'. - """ - # Currently this is only used on Mac OS, for the Mac-only GUI - # Distutils interface (by Jack Jansen) - import distutils.command - std_commands = distutils.command.__all__ - is_std = {} - for cmd in std_commands: - is_std[cmd] = 1 - - extra_commands = [] - for cmd in self.cmdclass.keys(): - if not is_std.get(cmd): - extra_commands.append(cmd) - - rv = [] - for cmd in (std_commands + extra_commands): - klass = self.cmdclass.get(cmd) - if not klass: - klass = self.get_command_class(cmd) - try: - description = klass.description - except AttributeError: - description = "(no description available)" - rv.append((cmd, description)) - return rv - - # -- Command class/object methods ---------------------------------- - - def get_command_packages(self): - """Return a list of packages from which commands are loaded.""" - pkgs = self.command_packages - if not isinstance(pkgs, list): - if pkgs is None: - pkgs = '' - pkgs = [pkg.strip() for pkg in pkgs.split(',') if pkg != ''] - if "distutils.command" not in pkgs: - pkgs.insert(0, "distutils.command") - self.command_packages = pkgs - return pkgs - - def get_command_class(self, command): - """Return the class that implements the Distutils command named by - 'command'. First we check the 'cmdclass' dictionary; if the - command is mentioned there, we fetch the class object from the - dictionary and return it. Otherwise we load the command module - ("distutils.command." + command) and fetch the command class from - the module. The loaded class is also stored in 'cmdclass' - to speed future calls to 'get_command_class()'. - - Raises DistutilsModuleError if the expected module could not be - found, or if that module does not define the expected class. - """ - klass = self.cmdclass.get(command) - if klass: - return klass - - for pkgname in self.get_command_packages(): - module_name = "%s.%s" % (pkgname, command) - klass_name = command - - try: - __import__(module_name) - module = sys.modules[module_name] - except ImportError: - continue - - try: - klass = getattr(module, klass_name) - except AttributeError: - raise DistutilsModuleError( - "invalid command '%s' (no class '%s' in module '%s')" - % (command, klass_name, module_name)) - - self.cmdclass[command] = klass - return klass - - raise DistutilsModuleError("invalid command '%s'" % command) - - def get_command_obj(self, command, create=1): - """Return the command object for 'command'. Normally this object - is cached on a previous call to 'get_command_obj()'; if no command - object for 'command' is in the cache, then we either create and - return it (if 'create' is true) or return None. - """ - cmd_obj = self.command_obj.get(command) - if not cmd_obj and create: - if DEBUG: - self.announce("Distribution.get_command_obj(): " - "creating '%s' command object" % command) - - klass = self.get_command_class(command) - cmd_obj = self.command_obj[command] = klass(self) - self.have_run[command] = 0 - - # Set any options that were supplied in config files - # or on the command line. (NB. support for error - # reporting is lame here: any errors aren't reported - # until 'finalize_options()' is called, which means - # we won't report the source of the error.) - options = self.command_options.get(command) - if options: - self._set_command_options(cmd_obj, options) - - return cmd_obj - - def _set_command_options(self, command_obj, option_dict=None): - """Set the options for 'command_obj' from 'option_dict'. Basically - this means copying elements of a dictionary ('option_dict') to - attributes of an instance ('command'). - - 'command_obj' must be a Command instance. If 'option_dict' is not - supplied, uses the standard option dictionary for this command - (from 'self.command_options'). - """ - command_name = command_obj.get_command_name() - if option_dict is None: - option_dict = self.get_option_dict(command_name) - - if DEBUG: - self.announce(" setting options for '%s' command:" % command_name) - for (option, (source, value)) in option_dict.items(): - if DEBUG: - self.announce(" %s = %s (from %s)" % (option, value, - source)) - try: - bool_opts = [translate_longopt(o) - for o in command_obj.boolean_options] - except AttributeError: - bool_opts = [] - try: - neg_opt = command_obj.negative_opt - except AttributeError: - neg_opt = {} - - try: - is_string = isinstance(value, str) - if option in neg_opt and is_string: - setattr(command_obj, neg_opt[option], not strtobool(value)) - elif option in bool_opts and is_string: - setattr(command_obj, option, strtobool(value)) - elif hasattr(command_obj, option): - setattr(command_obj, option, value) - else: - raise DistutilsOptionError( - "error in %s: command '%s' has no such option '%s'" - % (source, command_name, option)) - except ValueError as msg: - raise DistutilsOptionError(msg) - - def reinitialize_command(self, command, reinit_subcommands=0): - """Reinitializes a command to the state it was in when first - returned by 'get_command_obj()': ie., initialized but not yet - finalized. This provides the opportunity to sneak option - values in programmatically, overriding or supplementing - user-supplied values from the config files and command line. - You'll have to re-finalize the command object (by calling - 'finalize_options()' or 'ensure_finalized()') before using it for - real. - - 'command' should be a command name (string) or command object. If - 'reinit_subcommands' is true, also reinitializes the command's - sub-commands, as declared by the 'sub_commands' class attribute (if - it has one). See the "install" command for an example. Only - reinitializes the sub-commands that actually matter, ie. those - whose test predicates return true. - - Returns the reinitialized command object. - """ - from distutils.cmd import Command - if not isinstance(command, Command): - command_name = command - command = self.get_command_obj(command_name) - else: - command_name = command.get_command_name() - - if not command.finalized: - return command - command.initialize_options() - command.finalized = 0 - self.have_run[command_name] = 0 - self._set_command_options(command) - - if reinit_subcommands: - for sub in command.get_sub_commands(): - self.reinitialize_command(sub, reinit_subcommands) - - return command - - # -- Methods that operate on the Distribution ---------------------- - - def announce(self, msg, level=log.INFO): - log.log(level, msg) - - def run_commands(self): - """Run each command that was seen on the setup script command line. - Uses the list of commands found and cache of command objects - created by 'get_command_obj()'. - """ - for cmd in self.commands: - self.run_command(cmd) - - # -- Methods that operate on its Commands -------------------------- - - def run_command(self, command): - """Do whatever it takes to run a command (including nothing at all, - if the command has already been run). Specifically: if we have - already created and run the command named by 'command', return - silently without doing anything. If the command named by 'command' - doesn't even have a command object yet, create one. Then invoke - 'run()' on that command object (or an existing one). - """ - # Already been here, done that? then return silently. - if self.have_run.get(command): - return - - log.info("running %s", command) - cmd_obj = self.get_command_obj(command) - cmd_obj.ensure_finalized() - cmd_obj.run() - self.have_run[command] = 1 - - # -- Distribution query methods ------------------------------------ - - def has_pure_modules(self): - return len(self.packages or self.py_modules or []) > 0 - - def has_ext_modules(self): - return self.ext_modules and len(self.ext_modules) > 0 - - def has_c_libraries(self): - return self.libraries and len(self.libraries) > 0 - - def has_modules(self): - return self.has_pure_modules() or self.has_ext_modules() - - def has_headers(self): - return self.headers and len(self.headers) > 0 - - def has_scripts(self): - return self.scripts and len(self.scripts) > 0 - - def has_data_files(self): - return self.data_files and len(self.data_files) > 0 - - def is_pure(self): - return (self.has_pure_modules() and - not self.has_ext_modules() and - not self.has_c_libraries()) - - # -- Metadata query methods ---------------------------------------- - - # If you're looking for 'get_name()', 'get_version()', and so forth, - # they are defined in a sneaky way: the constructor binds self.get_XXX - # to self.metadata.get_XXX. The actual code is in the - # DistributionMetadata class, below. - -class DistributionMetadata: - """Dummy class to hold the distribution meta-data: name, version, - author, and so forth. - """ - - _METHOD_BASENAMES = ("name", "version", "author", "author_email", - "maintainer", "maintainer_email", "url", - "license", "description", "long_description", - "keywords", "platforms", "fullname", "contact", - "contact_email", "classifiers", "download_url", - # PEP 314 - "provides", "requires", "obsoletes", - ) - - def __init__(self, path=None): - if path is not None: - self.read_pkg_file(open(path)) - else: - self.name = None - self.version = None - self.author = None - self.author_email = None - self.maintainer = None - self.maintainer_email = None - self.url = None - self.license = None - self.description = None - self.long_description = None - self.keywords = None - self.platforms = None - self.classifiers = None - self.download_url = None - # PEP 314 - self.provides = None - self.requires = None - self.obsoletes = None - - def read_pkg_file(self, file): - """Reads the metadata values from a file object.""" - msg = message_from_file(file) - - def _read_field(name): - value = msg[name] - if value == 'UNKNOWN': - return None - return value - - def _read_list(name): - values = msg.get_all(name, None) - if values == []: - return None - return values - - metadata_version = msg['metadata-version'] - self.name = _read_field('name') - self.version = _read_field('version') - self.description = _read_field('summary') - # we are filling author only. - self.author = _read_field('author') - self.maintainer = None - self.author_email = _read_field('author-email') - self.maintainer_email = None - self.url = _read_field('home-page') - self.license = _read_field('license') - - if 'download-url' in msg: - self.download_url = _read_field('download-url') - else: - self.download_url = None - - self.long_description = _read_field('description') - self.description = _read_field('summary') - - if 'keywords' in msg: - self.keywords = _read_field('keywords').split(',') - - self.platforms = _read_list('platform') - self.classifiers = _read_list('classifier') - - # PEP 314 - these fields only exist in 1.1 - if metadata_version == '1.1': - self.requires = _read_list('requires') - self.provides = _read_list('provides') - self.obsoletes = _read_list('obsoletes') - else: - self.requires = None - self.provides = None - self.obsoletes = None - - def write_pkg_info(self, base_dir): - """Write the PKG-INFO file into the release tree. - """ - with open(os.path.join(base_dir, 'PKG-INFO'), 'w', - encoding='UTF-8') as pkg_info: - self.write_pkg_file(pkg_info) - - def write_pkg_file(self, file): - """Write the PKG-INFO format data to a file object. - """ - version = '1.0' - if (self.provides or self.requires or self.obsoletes or - self.classifiers or self.download_url): - version = '1.1' - - file.write('Metadata-Version: %s\n' % version) - file.write('Name: %s\n' % self.get_name()) - file.write('Version: %s\n' % self.get_version()) - file.write('Summary: %s\n' % self.get_description()) - file.write('Home-page: %s\n' % self.get_url()) - file.write('Author: %s\n' % self.get_contact()) - file.write('Author-email: %s\n' % self.get_contact_email()) - file.write('License: %s\n' % self.get_license()) - if self.download_url: - file.write('Download-URL: %s\n' % self.download_url) - - long_desc = rfc822_escape(self.get_long_description()) - file.write('Description: %s\n' % long_desc) - - keywords = ','.join(self.get_keywords()) - if keywords: - file.write('Keywords: %s\n' % keywords) - - self._write_list(file, 'Platform', self.get_platforms()) - self._write_list(file, 'Classifier', self.get_classifiers()) - - # PEP 314 - self._write_list(file, 'Requires', self.get_requires()) - self._write_list(file, 'Provides', self.get_provides()) - self._write_list(file, 'Obsoletes', self.get_obsoletes()) - - def _write_list(self, file, name, values): - for value in values: - file.write('%s: %s\n' % (name, value)) - - # -- Metadata query methods ---------------------------------------- - - def get_name(self): - return self.name or "UNKNOWN" - - def get_version(self): - return self.version or "0.0.0" - - def get_fullname(self): - return "%s-%s" % (self.get_name(), self.get_version()) - - def get_author(self): - return self.author or "UNKNOWN" - - def get_author_email(self): - return self.author_email or "UNKNOWN" - - def get_maintainer(self): - return self.maintainer or "UNKNOWN" - - def get_maintainer_email(self): - return self.maintainer_email or "UNKNOWN" - - def get_contact(self): - return self.maintainer or self.author or "UNKNOWN" - - def get_contact_email(self): - return self.maintainer_email or self.author_email or "UNKNOWN" - - def get_url(self): - return self.url or "UNKNOWN" - - def get_license(self): - return self.license or "UNKNOWN" - get_licence = get_license - - def get_description(self): - return self.description or "UNKNOWN" - - def get_long_description(self): - return self.long_description or "UNKNOWN" - - def get_keywords(self): - return self.keywords or [] - - def set_keywords(self, value): - self.keywords = _ensure_list(value, 'keywords') - - def get_platforms(self): - return self.platforms or ["UNKNOWN"] - - def set_platforms(self, value): - self.platforms = _ensure_list(value, 'platforms') - - def get_classifiers(self): - return self.classifiers or [] - - def set_classifiers(self, value): - self.classifiers = _ensure_list(value, 'classifiers') - - def get_download_url(self): - return self.download_url or "UNKNOWN" - - # PEP 314 - def get_requires(self): - return self.requires or [] - - def set_requires(self, value): - import distutils.versionpredicate - for v in value: - distutils.versionpredicate.VersionPredicate(v) - self.requires = list(value) - - def get_provides(self): - return self.provides or [] - - def set_provides(self, value): - value = [v.strip() for v in value] - for v in value: - import distutils.versionpredicate - distutils.versionpredicate.split_provision(v) - self.provides = value - - def get_obsoletes(self): - return self.obsoletes or [] - - def set_obsoletes(self, value): - import distutils.versionpredicate - for v in value: - distutils.versionpredicate.VersionPredicate(v) - self.obsoletes = list(value) - -def fix_help_options(options): - """Convert a 4-tuple 'help_options' list as found in various command - classes to the 3-tuple form required by FancyGetopt. - """ - new_options = [] - for help_tuple in options: - new_options.append(help_tuple[0:3]) - return new_options diff --git a/Lib/distutils/errors.py b/Lib/distutils/errors.py deleted file mode 100644 index 8b93059e..00000000 --- a/Lib/distutils/errors.py +++ /dev/null @@ -1,97 +0,0 @@ -"""distutils.errors - -Provides exceptions used by the Distutils modules. Note that Distutils -modules may raise standard exceptions; in particular, SystemExit is -usually raised for errors that are obviously the end-user's fault -(eg. bad command-line arguments). - -This module is safe to use in "from ... import *" mode; it only exports -symbols whose names start with "Distutils" and end with "Error".""" - -class DistutilsError (Exception): - """The root of all Distutils evil.""" - pass - -class DistutilsModuleError (DistutilsError): - """Unable to load an expected module, or to find an expected class - within some module (in particular, command modules and classes).""" - pass - -class DistutilsClassError (DistutilsError): - """Some command class (or possibly distribution class, if anyone - feels a need to subclass Distribution) is found not to be holding - up its end of the bargain, ie. implementing some part of the - "command "interface.""" - pass - -class DistutilsGetoptError (DistutilsError): - """The option table provided to 'fancy_getopt()' is bogus.""" - pass - -class DistutilsArgError (DistutilsError): - """Raised by fancy_getopt in response to getopt.error -- ie. an - error in the command line usage.""" - pass - -class DistutilsFileError (DistutilsError): - """Any problems in the filesystem: expected file not found, etc. - Typically this is for problems that we detect before OSError - could be raised.""" - pass - -class DistutilsOptionError (DistutilsError): - """Syntactic/semantic errors in command options, such as use of - mutually conflicting options, or inconsistent options, - badly-spelled values, etc. No distinction is made between option - values originating in the setup script, the command line, config - files, or what-have-you -- but if we *know* something originated in - the setup script, we'll raise DistutilsSetupError instead.""" - pass - -class DistutilsSetupError (DistutilsError): - """For errors that can be definitely blamed on the setup script, - such as invalid keyword arguments to 'setup()'.""" - pass - -class DistutilsPlatformError (DistutilsError): - """We don't know how to do something on the current platform (but - we do know how to do it on some platform) -- eg. trying to compile - C files on a platform not supported by a CCompiler subclass.""" - pass - -class DistutilsExecError (DistutilsError): - """Any problems executing an external program (such as the C - compiler, when compiling C files).""" - pass - -class DistutilsInternalError (DistutilsError): - """Internal inconsistencies or impossibilities (obviously, this - should never be seen if the code is working!).""" - pass - -class DistutilsTemplateError (DistutilsError): - """Syntax error in a file list template.""" - -class DistutilsByteCompileError(DistutilsError): - """Byte compile error.""" - -# Exception classes used by the CCompiler implementation classes -class CCompilerError (Exception): - """Some compile/link operation failed.""" - -class PreprocessError (CCompilerError): - """Failure to preprocess one or more C/C++ files.""" - -class CompileError (CCompilerError): - """Failure to compile one or more C/C++ source files.""" - -class LibError (CCompilerError): - """Failure to create a static library from one or more C/C++ object - files.""" - -class LinkError (CCompilerError): - """Failure to link one or more C/C++ object files into an executable - or shared library file.""" - -class UnknownFileError (CCompilerError): - """Attempt to process an unknown file type.""" diff --git a/Lib/distutils/extension.py b/Lib/distutils/extension.py deleted file mode 100644 index e85032ec..00000000 --- a/Lib/distutils/extension.py +++ /dev/null @@ -1,241 +0,0 @@ -"""distutils.extension - -Provides the Extension class, used to describe C/C++ extension -modules in setup scripts.""" - -import os -import re -import warnings - -# This class is really only used by the "build_ext" command, so it might -# make sense to put it in distutils.command.build_ext. However, that -# module is already big enough, and I want to make this class a bit more -# complex to simplify some common cases ("foo" module in "foo.c") and do -# better error-checking ("foo.c" actually exists). -# -# Also, putting this in build_ext.py means every setup script would have to -# import that large-ish module (indirectly, through distutils.core) in -# order to do anything. - -class Extension: - """Just a collection of attributes that describes an extension - module and everything needed to build it (hopefully in a portable - way, but there are hooks that let you be as unportable as you need). - - Instance attributes: - name : string - the full name of the extension, including any packages -- ie. - *not* a filename or pathname, but Python dotted name - sources : [string] - list of source filenames, relative to the distribution root - (where the setup script lives), in Unix form (slash-separated) - for portability. Source files may be C, C++, SWIG (.i), - platform-specific resource files, or whatever else is recognized - by the "build_ext" command as source for a Python extension. - include_dirs : [string] - list of directories to search for C/C++ header files (in Unix - form for portability) - define_macros : [(name : string, value : string|None)] - list of macros to define; each macro is defined using a 2-tuple, - where 'value' is either the string to define it to or None to - define it without a particular value (equivalent of "#define - FOO" in source or -DFOO on Unix C compiler command line) - undef_macros : [string] - list of macros to undefine explicitly - library_dirs : [string] - list of directories to search for C/C++ libraries at link time - libraries : [string] - list of library names (not filenames or paths) to link against - runtime_library_dirs : [string] - list of directories to search for C/C++ libraries at run time - (for shared extensions, this is when the extension is loaded) - extra_objects : [string] - list of extra files to link with (eg. object files not implied - by 'sources', static library that must be explicitly specified, - binary resource files, etc.) - extra_compile_args : [string] - any extra platform- and compiler-specific information to use - when compiling the source files in 'sources'. For platforms and - compilers where "command line" makes sense, this is typically a - list of command-line arguments, but for other platforms it could - be anything. - extra_link_args : [string] - any extra platform- and compiler-specific information to use - when linking object files together to create the extension (or - to create a new static Python interpreter). Similar - interpretation as for 'extra_compile_args'. - export_symbols : [string] - list of symbols to be exported from a shared extension. Not - used on all platforms, and not generally necessary for Python - extensions, which typically export exactly one symbol: "init" + - extension_name. - swig_opts : [string] - any extra options to pass to SWIG if a source file has the .i - extension. - depends : [string] - list of files that the extension depends on - language : string - extension language (i.e. "c", "c++", "objc"). Will be detected - from the source extensions if not provided. - optional : boolean - specifies that a build failure in the extension should not abort the - build process, but simply not install the failing extension. - """ - - # When adding arguments to this constructor, be sure to update - # setup_keywords in core.py. - def __init__(self, name, sources, - include_dirs=None, - define_macros=None, - undef_macros=None, - library_dirs=None, - libraries=None, - runtime_library_dirs=None, - extra_objects=None, - extra_compile_args=None, - extra_link_args=None, - export_symbols=None, - swig_opts = None, - depends=None, - language=None, - optional=None, - **kw # To catch unknown keywords - ): - if not isinstance(name, str): - raise AssertionError("'name' must be a string") - if not (isinstance(sources, list) and - all(isinstance(v, str) for v in sources)): - raise AssertionError("'sources' must be a list of strings") - - self.name = name - self.sources = sources - self.include_dirs = include_dirs or [] - self.define_macros = define_macros or [] - self.undef_macros = undef_macros or [] - self.library_dirs = library_dirs or [] - self.libraries = libraries or [] - self.runtime_library_dirs = runtime_library_dirs or [] - self.extra_objects = extra_objects or [] - self.extra_compile_args = extra_compile_args or [] - self.extra_link_args = extra_link_args or [] - self.export_symbols = export_symbols or [] - self.swig_opts = swig_opts or [] - self.depends = depends or [] - self.language = language - self.optional = optional - - # If there are unknown keyword options, warn about them - if len(kw) > 0: - options = [repr(option) for option in kw] - options = ', '.join(sorted(options)) - msg = "Unknown Extension options: %s" % options - warnings.warn(msg) - - def __repr__(self): - return '<%s.%s(%r) at %#x>' % ( - self.__class__.__module__, - self.__class__.__qualname__, - self.name, - id(self)) - - -def read_setup_file(filename): - """Reads a Setup file and returns Extension instances.""" - from distutils.sysconfig import (parse_makefile, expand_makefile_vars, - _variable_rx) - - from distutils.text_file import TextFile - from distutils.util import split_quoted - - # First pass over the file to gather "VAR = VALUE" assignments. - vars = parse_makefile(filename) - - # Second pass to gobble up the real content: lines of the form - # <module> ... [<sourcefile> ...] [<cpparg> ...] [<library> ...] - file = TextFile(filename, - strip_comments=1, skip_blanks=1, join_lines=1, - lstrip_ws=1, rstrip_ws=1) - try: - extensions = [] - - while True: - line = file.readline() - if line is None: # eof - break - if re.match(_variable_rx, line): # VAR=VALUE, handled in first pass - continue - - if line[0] == line[-1] == "*": - file.warn("'%s' lines not handled yet" % line) - continue - - line = expand_makefile_vars(line, vars) - words = split_quoted(line) - - # NB. this parses a slightly different syntax than the old - # makesetup script: here, there must be exactly one extension per - # line, and it must be the first word of the line. I have no idea - # why the old syntax supported multiple extensions per line, as - # they all wind up being the same. - - module = words[0] - ext = Extension(module, []) - append_next_word = None - - for word in words[1:]: - if append_next_word is not None: - append_next_word.append(word) - append_next_word = None - continue - - suffix = os.path.splitext(word)[1] - switch = word[0:2] ; value = word[2:] - - if suffix in (".c", ".cc", ".cpp", ".cxx", ".c++", ".m", ".mm"): - # hmm, should we do something about C vs. C++ sources? - # or leave it up to the CCompiler implementation to - # worry about? - ext.sources.append(word) - elif switch == "-I": - ext.include_dirs.append(value) - elif switch == "-D": - equals = value.find("=") - if equals == -1: # bare "-DFOO" -- no value - ext.define_macros.append((value, None)) - else: # "-DFOO=blah" - ext.define_macros.append((value[0:equals], - value[equals+2:])) - elif switch == "-U": - ext.undef_macros.append(value) - elif switch == "-C": # only here 'cause makesetup has it! - ext.extra_compile_args.append(word) - elif switch == "-l": - ext.libraries.append(value) - elif switch == "-L": - ext.library_dirs.append(value) - elif switch == "-R": - ext.runtime_library_dirs.append(value) - elif word == "-rpath": - append_next_word = ext.runtime_library_dirs - elif word == "-Xlinker": - append_next_word = ext.extra_link_args - elif word == "-Xcompiler": - append_next_word = ext.extra_compile_args - elif switch == "-u": - ext.extra_link_args.append(word) - if not value: - append_next_word = ext.extra_link_args - elif suffix in (".a", ".so", ".sl", ".o", ".dylib"): - # NB. a really faithful emulation of makesetup would - # append a .o file to extra_objects only if it - # had a slash in it; otherwise, it would s/.o/.c/ - # and append it to sources. Hmmmm. - ext.extra_objects.append(word) - else: - file.warn("unrecognized argument '%s'" % word) - - extensions.append(ext) - finally: - file.close() - - return extensions diff --git a/Lib/distutils/fancy_getopt.py b/Lib/distutils/fancy_getopt.py deleted file mode 100644 index 7d170dd2..00000000 --- a/Lib/distutils/fancy_getopt.py +++ /dev/null @@ -1,457 +0,0 @@ -"""distutils.fancy_getopt - -Wrapper around the standard getopt module that provides the following -additional features: - * short and long options are tied together - * options have help strings, so fancy_getopt could potentially - create a complete usage summary - * options set attributes of a passed-in object -""" - -import sys, string, re -import getopt -from distutils.errors import * - -# Much like command_re in distutils.core, this is close to but not quite -# the same as a Python NAME -- except, in the spirit of most GNU -# utilities, we use '-' in place of '_'. (The spirit of LISP lives on!) -# The similarities to NAME are again not a coincidence... -longopt_pat = r'[a-zA-Z](?:[a-zA-Z0-9-]*)' -longopt_re = re.compile(r'^%s$' % longopt_pat) - -# For recognizing "negative alias" options, eg. "quiet=!verbose" -neg_alias_re = re.compile("^(%s)=!(%s)$" % (longopt_pat, longopt_pat)) - -# This is used to translate long options to legitimate Python identifiers -# (for use as attributes of some object). -longopt_xlate = str.maketrans('-', '_') - -class FancyGetopt: - """Wrapper around the standard 'getopt()' module that provides some - handy extra functionality: - * short and long options are tied together - * options have help strings, and help text can be assembled - from them - * options set attributes of a passed-in object - * boolean options can have "negative aliases" -- eg. if - --quiet is the "negative alias" of --verbose, then "--quiet" - on the command line sets 'verbose' to false - """ - - def __init__(self, option_table=None): - # The option table is (currently) a list of tuples. The - # tuples may have 3 or four values: - # (long_option, short_option, help_string [, repeatable]) - # if an option takes an argument, its long_option should have '=' - # appended; short_option should just be a single character, no ':' - # in any case. If a long_option doesn't have a corresponding - # short_option, short_option should be None. All option tuples - # must have long options. - self.option_table = option_table - - # 'option_index' maps long option names to entries in the option - # table (ie. those 3-tuples). - self.option_index = {} - if self.option_table: - self._build_index() - - # 'alias' records (duh) alias options; {'foo': 'bar'} means - # --foo is an alias for --bar - self.alias = {} - - # 'negative_alias' keeps track of options that are the boolean - # opposite of some other option - self.negative_alias = {} - - # These keep track of the information in the option table. We - # don't actually populate these structures until we're ready to - # parse the command-line, since the 'option_table' passed in here - # isn't necessarily the final word. - self.short_opts = [] - self.long_opts = [] - self.short2long = {} - self.attr_name = {} - self.takes_arg = {} - - # And 'option_order' is filled up in 'getopt()'; it records the - # original order of options (and their values) on the command-line, - # but expands short options, converts aliases, etc. - self.option_order = [] - - def _build_index(self): - self.option_index.clear() - for option in self.option_table: - self.option_index[option[0]] = option - - def set_option_table(self, option_table): - self.option_table = option_table - self._build_index() - - def add_option(self, long_option, short_option=None, help_string=None): - if long_option in self.option_index: - raise DistutilsGetoptError( - "option conflict: already an option '%s'" % long_option) - else: - option = (long_option, short_option, help_string) - self.option_table.append(option) - self.option_index[long_option] = option - - def has_option(self, long_option): - """Return true if the option table for this parser has an - option with long name 'long_option'.""" - return long_option in self.option_index - - def get_attr_name(self, long_option): - """Translate long option name 'long_option' to the form it - has as an attribute of some object: ie., translate hyphens - to underscores.""" - return long_option.translate(longopt_xlate) - - def _check_alias_dict(self, aliases, what): - assert isinstance(aliases, dict) - for (alias, opt) in aliases.items(): - if alias not in self.option_index: - raise DistutilsGetoptError(("invalid %s '%s': " - "option '%s' not defined") % (what, alias, alias)) - if opt not in self.option_index: - raise DistutilsGetoptError(("invalid %s '%s': " - "aliased option '%s' not defined") % (what, alias, opt)) - - def set_aliases(self, alias): - """Set the aliases for this option parser.""" - self._check_alias_dict(alias, "alias") - self.alias = alias - - def set_negative_aliases(self, negative_alias): - """Set the negative aliases for this option parser. - 'negative_alias' should be a dictionary mapping option names to - option names, both the key and value must already be defined - in the option table.""" - self._check_alias_dict(negative_alias, "negative alias") - self.negative_alias = negative_alias - - def _grok_option_table(self): - """Populate the various data structures that keep tabs on the - option table. Called by 'getopt()' before it can do anything - worthwhile. - """ - self.long_opts = [] - self.short_opts = [] - self.short2long.clear() - self.repeat = {} - - for option in self.option_table: - if len(option) == 3: - long, short, help = option - repeat = 0 - elif len(option) == 4: - long, short, help, repeat = option - else: - # the option table is part of the code, so simply - # assert that it is correct - raise ValueError("invalid option tuple: %r" % (option,)) - - # Type- and value-check the option names - if not isinstance(long, str) or len(long) < 2: - raise DistutilsGetoptError(("invalid long option '%s': " - "must be a string of length >= 2") % long) - - if (not ((short is None) or - (isinstance(short, str) and len(short) == 1))): - raise DistutilsGetoptError("invalid short option '%s': " - "must a single character or None" % short) - - self.repeat[long] = repeat - self.long_opts.append(long) - - if long[-1] == '=': # option takes an argument? - if short: short = short + ':' - long = long[0:-1] - self.takes_arg[long] = 1 - else: - # Is option is a "negative alias" for some other option (eg. - # "quiet" == "!verbose")? - alias_to = self.negative_alias.get(long) - if alias_to is not None: - if self.takes_arg[alias_to]: - raise DistutilsGetoptError( - "invalid negative alias '%s': " - "aliased option '%s' takes a value" - % (long, alias_to)) - - self.long_opts[-1] = long # XXX redundant?! - self.takes_arg[long] = 0 - - # If this is an alias option, make sure its "takes arg" flag is - # the same as the option it's aliased to. - alias_to = self.alias.get(long) - if alias_to is not None: - if self.takes_arg[long] != self.takes_arg[alias_to]: - raise DistutilsGetoptError( - "invalid alias '%s': inconsistent with " - "aliased option '%s' (one of them takes a value, " - "the other doesn't" - % (long, alias_to)) - - # Now enforce some bondage on the long option name, so we can - # later translate it to an attribute name on some object. Have - # to do this a bit late to make sure we've removed any trailing - # '='. - if not longopt_re.match(long): - raise DistutilsGetoptError( - "invalid long option name '%s' " - "(must be letters, numbers, hyphens only" % long) - - self.attr_name[long] = self.get_attr_name(long) - if short: - self.short_opts.append(short) - self.short2long[short[0]] = long - - def getopt(self, args=None, object=None): - """Parse command-line options in args. Store as attributes on object. - - If 'args' is None or not supplied, uses 'sys.argv[1:]'. If - 'object' is None or not supplied, creates a new OptionDummy - object, stores option values there, and returns a tuple (args, - object). If 'object' is supplied, it is modified in place and - 'getopt()' just returns 'args'; in both cases, the returned - 'args' is a modified copy of the passed-in 'args' list, which - is left untouched. - """ - if args is None: - args = sys.argv[1:] - if object is None: - object = OptionDummy() - created_object = True - else: - created_object = False - - self._grok_option_table() - - short_opts = ' '.join(self.short_opts) - try: - opts, args = getopt.getopt(args, short_opts, self.long_opts) - except getopt.error as msg: - raise DistutilsArgError(msg) - - for opt, val in opts: - if len(opt) == 2 and opt[0] == '-': # it's a short option - opt = self.short2long[opt[1]] - else: - assert len(opt) > 2 and opt[:2] == '--' - opt = opt[2:] - - alias = self.alias.get(opt) - if alias: - opt = alias - - if not self.takes_arg[opt]: # boolean option? - assert val == '', "boolean option can't have value" - alias = self.negative_alias.get(opt) - if alias: - opt = alias - val = 0 - else: - val = 1 - - attr = self.attr_name[opt] - # The only repeating option at the moment is 'verbose'. - # It has a negative option -q quiet, which should set verbose = 0. - if val and self.repeat.get(attr) is not None: - val = getattr(object, attr, 0) + 1 - setattr(object, attr, val) - self.option_order.append((opt, val)) - - # for opts - if created_object: - return args, object - else: - return args - - def get_option_order(self): - """Returns the list of (option, value) tuples processed by the - previous run of 'getopt()'. Raises RuntimeError if - 'getopt()' hasn't been called yet. - """ - if self.option_order is None: - raise RuntimeError("'getopt()' hasn't been called yet") - else: - return self.option_order - - def generate_help(self, header=None): - """Generate help text (a list of strings, one per suggested line of - output) from the option table for this FancyGetopt object. - """ - # Blithely assume the option table is good: probably wouldn't call - # 'generate_help()' unless you've already called 'getopt()'. - - # First pass: determine maximum length of long option names - max_opt = 0 - for option in self.option_table: - long = option[0] - short = option[1] - l = len(long) - if long[-1] == '=': - l = l - 1 - if short is not None: - l = l + 5 # " (-x)" where short == 'x' - if l > max_opt: - max_opt = l - - opt_width = max_opt + 2 + 2 + 2 # room for indent + dashes + gutter - - # Typical help block looks like this: - # --foo controls foonabulation - # Help block for longest option looks like this: - # --flimflam set the flim-flam level - # and with wrapped text: - # --flimflam set the flim-flam level (must be between - # 0 and 100, except on Tuesdays) - # Options with short names will have the short name shown (but - # it doesn't contribute to max_opt): - # --foo (-f) controls foonabulation - # If adding the short option would make the left column too wide, - # we push the explanation off to the next line - # --flimflam (-l) - # set the flim-flam level - # Important parameters: - # - 2 spaces before option block start lines - # - 2 dashes for each long option name - # - min. 2 spaces between option and explanation (gutter) - # - 5 characters (incl. space) for short option name - - # Now generate lines of help text. (If 80 columns were good enough - # for Jesus, then 78 columns are good enough for me!) - line_width = 78 - text_width = line_width - opt_width - big_indent = ' ' * opt_width - if header: - lines = [header] - else: - lines = ['Option summary:'] - - for option in self.option_table: - long, short, help = option[:3] - text = wrap_text(help, text_width) - if long[-1] == '=': - long = long[0:-1] - - # Case 1: no short option at all (makes life easy) - if short is None: - if text: - lines.append(" --%-*s %s" % (max_opt, long, text[0])) - else: - lines.append(" --%-*s " % (max_opt, long)) - - # Case 2: we have a short option, so we have to include it - # just after the long option - else: - opt_names = "%s (-%s)" % (long, short) - if text: - lines.append(" --%-*s %s" % - (max_opt, opt_names, text[0])) - else: - lines.append(" --%-*s" % opt_names) - - for l in text[1:]: - lines.append(big_indent + l) - return lines - - def print_help(self, header=None, file=None): - if file is None: - file = sys.stdout - for line in self.generate_help(header): - file.write(line + "\n") - - -def fancy_getopt(options, negative_opt, object, args): - parser = FancyGetopt(options) - parser.set_negative_aliases(negative_opt) - return parser.getopt(args, object) - - -WS_TRANS = {ord(_wschar) : ' ' for _wschar in string.whitespace} - -def wrap_text(text, width): - """wrap_text(text : string, width : int) -> [string] - - Split 'text' into multiple lines of no more than 'width' characters - each, and return the list of strings that results. - """ - if text is None: - return [] - if len(text) <= width: - return [text] - - text = text.expandtabs() - text = text.translate(WS_TRANS) - chunks = re.split(r'( +|-+)', text) - chunks = [ch for ch in chunks if ch] # ' - ' results in empty strings - lines = [] - - while chunks: - cur_line = [] # list of chunks (to-be-joined) - cur_len = 0 # length of current line - - while chunks: - l = len(chunks[0]) - if cur_len + l <= width: # can squeeze (at least) this chunk in - cur_line.append(chunks[0]) - del chunks[0] - cur_len = cur_len + l - else: # this line is full - # drop last chunk if all space - if cur_line and cur_line[-1][0] == ' ': - del cur_line[-1] - break - - if chunks: # any chunks left to process? - # if the current line is still empty, then we had a single - # chunk that's too big too fit on a line -- so we break - # down and break it up at the line width - if cur_len == 0: - cur_line.append(chunks[0][0:width]) - chunks[0] = chunks[0][width:] - - # all-whitespace chunks at the end of a line can be discarded - # (and we know from the re.split above that if a chunk has - # *any* whitespace, it is *all* whitespace) - if chunks[0][0] == ' ': - del chunks[0] - - # and store this line in the list-of-all-lines -- as a single - # string, of course! - lines.append(''.join(cur_line)) - - return lines - - -def translate_longopt(opt): - """Convert a long option name to a valid Python identifier by - changing "-" to "_". - """ - return opt.translate(longopt_xlate) - - -class OptionDummy: - """Dummy class just used as a place to hold command-line option - values as instance attributes.""" - - def __init__(self, options=[]): - """Create a new OptionDummy instance. The attributes listed in - 'options' will be initialized to None.""" - for opt in options: - setattr(self, opt, None) - - -if __name__ == "__main__": - text = """\ -Tra-la-la, supercalifragilisticexpialidocious. -How *do* you spell that odd word, anyways? -(Someone ask Mary -- she'll know [or she'll -say, "How should I know?"].)""" - - for w in (10, 20, 30, 40): - print("width: %d" % w) - print("\n".join(wrap_text(text, w))) - print() diff --git a/Lib/distutils/file_util.py b/Lib/distutils/file_util.py deleted file mode 100644 index b3fee35a..00000000 --- a/Lib/distutils/file_util.py +++ /dev/null @@ -1,238 +0,0 @@ -"""distutils.file_util - -Utility functions for operating on single files. -""" - -import os -from distutils.errors import DistutilsFileError -from distutils import log - -# for generating verbose output in 'copy_file()' -_copy_action = { None: 'copying', - 'hard': 'hard linking', - 'sym': 'symbolically linking' } - - -def _copy_file_contents(src, dst, buffer_size=16*1024): - """Copy the file 'src' to 'dst'; both must be filenames. Any error - opening either file, reading from 'src', or writing to 'dst', raises - DistutilsFileError. Data is read/written in chunks of 'buffer_size' - bytes (default 16k). No attempt is made to handle anything apart from - regular files. - """ - # Stolen from shutil module in the standard library, but with - # custom error-handling added. - fsrc = None - fdst = None - try: - try: - fsrc = open(src, 'rb') - except OSError as e: - raise DistutilsFileError("could not open '%s': %s" % (src, e.strerror)) - - if os.path.exists(dst): - try: - os.unlink(dst) - except OSError as e: - raise DistutilsFileError( - "could not delete '%s': %s" % (dst, e.strerror)) - - try: - fdst = open(dst, 'wb') - except OSError as e: - raise DistutilsFileError( - "could not create '%s': %s" % (dst, e.strerror)) - - while True: - try: - buf = fsrc.read(buffer_size) - except OSError as e: - raise DistutilsFileError( - "could not read from '%s': %s" % (src, e.strerror)) - - if not buf: - break - - try: - fdst.write(buf) - except OSError as e: - raise DistutilsFileError( - "could not write to '%s': %s" % (dst, e.strerror)) - finally: - if fdst: - fdst.close() - if fsrc: - fsrc.close() - -def copy_file(src, dst, preserve_mode=1, preserve_times=1, update=0, - link=None, verbose=1, dry_run=0): - """Copy a file 'src' to 'dst'. If 'dst' is a directory, then 'src' is - copied there with the same name; otherwise, it must be a filename. (If - the file exists, it will be ruthlessly clobbered.) If 'preserve_mode' - is true (the default), the file's mode (type and permission bits, or - whatever is analogous on the current platform) is copied. If - 'preserve_times' is true (the default), the last-modified and - last-access times are copied as well. If 'update' is true, 'src' will - only be copied if 'dst' does not exist, or if 'dst' does exist but is - older than 'src'. - - 'link' allows you to make hard links (os.link) or symbolic links - (os.symlink) instead of copying: set it to "hard" or "sym"; if it is - None (the default), files are copied. Don't set 'link' on systems that - don't support it: 'copy_file()' doesn't check if hard or symbolic - linking is available. If hardlink fails, falls back to - _copy_file_contents(). - - Under Mac OS, uses the native file copy function in macostools; on - other systems, uses '_copy_file_contents()' to copy file contents. - - Return a tuple (dest_name, copied): 'dest_name' is the actual name of - the output file, and 'copied' is true if the file was copied (or would - have been copied, if 'dry_run' true). - """ - # XXX if the destination file already exists, we clobber it if - # copying, but blow up if linking. Hmmm. And I don't know what - # macostools.copyfile() does. Should definitely be consistent, and - # should probably blow up if destination exists and we would be - # changing it (ie. it's not already a hard/soft link to src OR - # (not update) and (src newer than dst). - - from distutils.dep_util import newer - from stat import ST_ATIME, ST_MTIME, ST_MODE, S_IMODE - - if not os.path.isfile(src): - raise DistutilsFileError( - "can't copy '%s': doesn't exist or not a regular file" % src) - - if os.path.isdir(dst): - dir = dst - dst = os.path.join(dst, os.path.basename(src)) - else: - dir = os.path.dirname(dst) - - if update and not newer(src, dst): - if verbose >= 1: - log.debug("not copying %s (output up-to-date)", src) - return (dst, 0) - - try: - action = _copy_action[link] - except KeyError: - raise ValueError("invalid value '%s' for 'link' argument" % link) - - if verbose >= 1: - if os.path.basename(dst) == os.path.basename(src): - log.info("%s %s -> %s", action, src, dir) - else: - log.info("%s %s -> %s", action, src, dst) - - if dry_run: - return (dst, 1) - - # If linking (hard or symbolic), use the appropriate system call - # (Unix only, of course, but that's the caller's responsibility) - elif link == 'hard': - if not (os.path.exists(dst) and os.path.samefile(src, dst)): - try: - os.link(src, dst) - return (dst, 1) - except OSError: - # If hard linking fails, fall back on copying file - # (some special filesystems don't support hard linking - # even under Unix, see issue #8876). - pass - elif link == 'sym': - if not (os.path.exists(dst) and os.path.samefile(src, dst)): - os.symlink(src, dst) - return (dst, 1) - - # Otherwise (non-Mac, not linking), copy the file contents and - # (optionally) copy the times and mode. - _copy_file_contents(src, dst) - if preserve_mode or preserve_times: - st = os.stat(src) - - # According to David Ascher <da@ski.org>, utime() should be done - # before chmod() (at least under NT). - if preserve_times: - os.utime(dst, (st[ST_ATIME], st[ST_MTIME])) - if preserve_mode: - os.chmod(dst, S_IMODE(st[ST_MODE])) - - return (dst, 1) - - -# XXX I suspect this is Unix-specific -- need porting help! -def move_file (src, dst, - verbose=1, - dry_run=0): - - """Move a file 'src' to 'dst'. If 'dst' is a directory, the file will - be moved into it with the same name; otherwise, 'src' is just renamed - to 'dst'. Return the new full name of the file. - - Handles cross-device moves on Unix using 'copy_file()'. What about - other systems??? - """ - from os.path import exists, isfile, isdir, basename, dirname - import errno - - if verbose >= 1: - log.info("moving %s -> %s", src, dst) - - if dry_run: - return dst - - if not isfile(src): - raise DistutilsFileError("can't move '%s': not a regular file" % src) - - if isdir(dst): - dst = os.path.join(dst, basename(src)) - elif exists(dst): - raise DistutilsFileError( - "can't move '%s': destination '%s' already exists" % - (src, dst)) - - if not isdir(dirname(dst)): - raise DistutilsFileError( - "can't move '%s': destination '%s' not a valid path" % - (src, dst)) - - copy_it = False - try: - os.rename(src, dst) - except OSError as e: - (num, msg) = e.args - if num == errno.EXDEV: - copy_it = True - else: - raise DistutilsFileError( - "couldn't move '%s' to '%s': %s" % (src, dst, msg)) - - if copy_it: - copy_file(src, dst, verbose=verbose) - try: - os.unlink(src) - except OSError as e: - (num, msg) = e.args - try: - os.unlink(dst) - except OSError: - pass - raise DistutilsFileError( - "couldn't move '%s' to '%s' by copy/delete: " - "delete '%s' failed: %s" - % (src, dst, src, msg)) - return dst - - -def write_file (filename, contents): - """Create a file with the specified name and write 'contents' (a - sequence of strings without line terminators) to it. - """ - f = open(filename, "w") - try: - for line in contents: - f.write(line + "\n") - finally: - f.close() diff --git a/Lib/distutils/filelist.py b/Lib/distutils/filelist.py deleted file mode 100644 index c92d5fdb..00000000 --- a/Lib/distutils/filelist.py +++ /dev/null @@ -1,327 +0,0 @@ -"""distutils.filelist - -Provides the FileList class, used for poking about the filesystem -and building lists of files. -""" - -import os, re -import fnmatch -import functools -from distutils.util import convert_path -from distutils.errors import DistutilsTemplateError, DistutilsInternalError -from distutils import log - -class FileList: - """A list of files built by on exploring the filesystem and filtered by - applying various patterns to what we find there. - - Instance attributes: - dir - directory from which files will be taken -- only used if - 'allfiles' not supplied to constructor - files - list of filenames currently being built/filtered/manipulated - allfiles - complete list of files under consideration (ie. without any - filtering applied) - """ - - def __init__(self, warn=None, debug_print=None): - # ignore argument to FileList, but keep them for backwards - # compatibility - self.allfiles = None - self.files = [] - - def set_allfiles(self, allfiles): - self.allfiles = allfiles - - def findall(self, dir=os.curdir): - self.allfiles = findall(dir) - - def debug_print(self, msg): - """Print 'msg' to stdout if the global DEBUG (taken from the - DISTUTILS_DEBUG environment variable) flag is true. - """ - from distutils.debug import DEBUG - if DEBUG: - print(msg) - - # -- List-like methods --------------------------------------------- - - def append(self, item): - self.files.append(item) - - def extend(self, items): - self.files.extend(items) - - def sort(self): - # Not a strict lexical sort! - sortable_files = sorted(map(os.path.split, self.files)) - self.files = [] - for sort_tuple in sortable_files: - self.files.append(os.path.join(*sort_tuple)) - - - # -- Other miscellaneous utility methods --------------------------- - - def remove_duplicates(self): - # Assumes list has been sorted! - for i in range(len(self.files) - 1, 0, -1): - if self.files[i] == self.files[i - 1]: - del self.files[i] - - - # -- "File template" methods --------------------------------------- - - def _parse_template_line(self, line): - words = line.split() - action = words[0] - - patterns = dir = dir_pattern = None - - if action in ('include', 'exclude', - 'global-include', 'global-exclude'): - if len(words) < 2: - raise DistutilsTemplateError( - "'%s' expects <pattern1> <pattern2> ..." % action) - patterns = [convert_path(w) for w in words[1:]] - elif action in ('recursive-include', 'recursive-exclude'): - if len(words) < 3: - raise DistutilsTemplateError( - "'%s' expects <dir> <pattern1> <pattern2> ..." % action) - dir = convert_path(words[1]) - patterns = [convert_path(w) for w in words[2:]] - elif action in ('graft', 'prune'): - if len(words) != 2: - raise DistutilsTemplateError( - "'%s' expects a single <dir_pattern>" % action) - dir_pattern = convert_path(words[1]) - else: - raise DistutilsTemplateError("unknown action '%s'" % action) - - return (action, patterns, dir, dir_pattern) - - def process_template_line(self, line): - # Parse the line: split it up, make sure the right number of words - # is there, and return the relevant words. 'action' is always - # defined: it's the first word of the line. Which of the other - # three are defined depends on the action; it'll be either - # patterns, (dir and patterns), or (dir_pattern). - (action, patterns, dir, dir_pattern) = self._parse_template_line(line) - - # OK, now we know that the action is valid and we have the - # right number of words on the line for that action -- so we - # can proceed with minimal error-checking. - if action == 'include': - self.debug_print("include " + ' '.join(patterns)) - for pattern in patterns: - if not self.include_pattern(pattern, anchor=1): - log.warn("warning: no files found matching '%s'", - pattern) - - elif action == 'exclude': - self.debug_print("exclude " + ' '.join(patterns)) - for pattern in patterns: - if not self.exclude_pattern(pattern, anchor=1): - log.warn(("warning: no previously-included files " - "found matching '%s'"), pattern) - - elif action == 'global-include': - self.debug_print("global-include " + ' '.join(patterns)) - for pattern in patterns: - if not self.include_pattern(pattern, anchor=0): - log.warn(("warning: no files found matching '%s' " - "anywhere in distribution"), pattern) - - elif action == 'global-exclude': - self.debug_print("global-exclude " + ' '.join(patterns)) - for pattern in patterns: - if not self.exclude_pattern(pattern, anchor=0): - log.warn(("warning: no previously-included files matching " - "'%s' found anywhere in distribution"), - pattern) - - elif action == 'recursive-include': - self.debug_print("recursive-include %s %s" % - (dir, ' '.join(patterns))) - for pattern in patterns: - if not self.include_pattern(pattern, prefix=dir): - log.warn(("warning: no files found matching '%s' " - "under directory '%s'"), - pattern, dir) - - elif action == 'recursive-exclude': - self.debug_print("recursive-exclude %s %s" % - (dir, ' '.join(patterns))) - for pattern in patterns: - if not self.exclude_pattern(pattern, prefix=dir): - log.warn(("warning: no previously-included files matching " - "'%s' found under directory '%s'"), - pattern, dir) - - elif action == 'graft': - self.debug_print("graft " + dir_pattern) - if not self.include_pattern(None, prefix=dir_pattern): - log.warn("warning: no directories found matching '%s'", - dir_pattern) - - elif action == 'prune': - self.debug_print("prune " + dir_pattern) - if not self.exclude_pattern(None, prefix=dir_pattern): - log.warn(("no previously-included directories found " - "matching '%s'"), dir_pattern) - else: - raise DistutilsInternalError( - "this cannot happen: invalid action '%s'" % action) - - - # -- Filtering/selection methods ----------------------------------- - - def include_pattern(self, pattern, anchor=1, prefix=None, is_regex=0): - """Select strings (presumably filenames) from 'self.files' that - match 'pattern', a Unix-style wildcard (glob) pattern. Patterns - are not quite the same as implemented by the 'fnmatch' module: '*' - and '?' match non-special characters, where "special" is platform- - dependent: slash on Unix; colon, slash, and backslash on - DOS/Windows; and colon on Mac OS. - - If 'anchor' is true (the default), then the pattern match is more - stringent: "*.py" will match "foo.py" but not "foo/bar.py". If - 'anchor' is false, both of these will match. - - If 'prefix' is supplied, then only filenames starting with 'prefix' - (itself a pattern) and ending with 'pattern', with anything in between - them, will match. 'anchor' is ignored in this case. - - If 'is_regex' is true, 'anchor' and 'prefix' are ignored, and - 'pattern' is assumed to be either a string containing a regex or a - regex object -- no translation is done, the regex is just compiled - and used as-is. - - Selected strings will be added to self.files. - - Return True if files are found, False otherwise. - """ - # XXX docstring lying about what the special chars are? - files_found = False - pattern_re = translate_pattern(pattern, anchor, prefix, is_regex) - self.debug_print("include_pattern: applying regex r'%s'" % - pattern_re.pattern) - - # delayed loading of allfiles list - if self.allfiles is None: - self.findall() - - for name in self.allfiles: - if pattern_re.search(name): - self.debug_print(" adding " + name) - self.files.append(name) - files_found = True - return files_found - - - def exclude_pattern (self, pattern, - anchor=1, prefix=None, is_regex=0): - """Remove strings (presumably filenames) from 'files' that match - 'pattern'. Other parameters are the same as for - 'include_pattern()', above. - The list 'self.files' is modified in place. - Return True if files are found, False otherwise. - """ - files_found = False - pattern_re = translate_pattern(pattern, anchor, prefix, is_regex) - self.debug_print("exclude_pattern: applying regex r'%s'" % - pattern_re.pattern) - for i in range(len(self.files)-1, -1, -1): - if pattern_re.search(self.files[i]): - self.debug_print(" removing " + self.files[i]) - del self.files[i] - files_found = True - return files_found - - -# ---------------------------------------------------------------------- -# Utility functions - -def _find_all_simple(path): - """ - Find all files under 'path' - """ - results = ( - os.path.join(base, file) - for base, dirs, files in os.walk(path, followlinks=True) - for file in files - ) - return filter(os.path.isfile, results) - - -def findall(dir=os.curdir): - """ - Find all files under 'dir' and return the list of full filenames. - Unless dir is '.', return full filenames with dir prepended. - """ - files = _find_all_simple(dir) - if dir == os.curdir: - make_rel = functools.partial(os.path.relpath, start=dir) - files = map(make_rel, files) - return list(files) - - -def glob_to_re(pattern): - """Translate a shell-like glob pattern to a regular expression; return - a string containing the regex. Differs from 'fnmatch.translate()' in - that '*' does not match "special characters" (which are - platform-specific). - """ - pattern_re = fnmatch.translate(pattern) - - # '?' and '*' in the glob pattern become '.' and '.*' in the RE, which - # IMHO is wrong -- '?' and '*' aren't supposed to match slash in Unix, - # and by extension they shouldn't match such "special characters" under - # any OS. So change all non-escaped dots in the RE to match any - # character except the special characters (currently: just os.sep). - sep = os.sep - if os.sep == '\\': - # we're using a regex to manipulate a regex, so we need - # to escape the backslash twice - sep = r'\\\\' - escaped = r'\1[^%s]' % sep - pattern_re = re.sub(r'((?<!\\)(\\\\)*)\.', escaped, pattern_re) - return pattern_re - - -def translate_pattern(pattern, anchor=1, prefix=None, is_regex=0): - """Translate a shell-like wildcard pattern to a compiled regular - expression. Return the compiled regex. If 'is_regex' true, - then 'pattern' is directly compiled to a regex (if it's a string) - or just returned as-is (assumes it's a regex object). - """ - if is_regex: - if isinstance(pattern, str): - return re.compile(pattern) - else: - return pattern - - # ditch start and end characters - start, _, end = glob_to_re('_').partition('_') - - if pattern: - pattern_re = glob_to_re(pattern) - assert pattern_re.startswith(start) and pattern_re.endswith(end) - else: - pattern_re = '' - - if prefix is not None: - prefix_re = glob_to_re(prefix) - assert prefix_re.startswith(start) and prefix_re.endswith(end) - prefix_re = prefix_re[len(start): len(prefix_re) - len(end)] - sep = os.sep - if os.sep == '\\': - sep = r'\\' - pattern_re = pattern_re[len(start): len(pattern_re) - len(end)] - pattern_re = r'%s\A%s%s.*%s%s' % (start, prefix_re, sep, pattern_re, end) - else: # no prefix -- respect anchor flag - if anchor: - pattern_re = r'%s\A%s' % (start, pattern_re[len(start):]) - - return re.compile(pattern_re) diff --git a/Lib/distutils/msvccompiler.py b/Lib/distutils/msvccompiler.py deleted file mode 100644 index f0d04fdb..00000000 --- a/Lib/distutils/msvccompiler.py +++ /dev/null @@ -1,642 +0,0 @@ -"""distutils.msvccompiler - -Contains MSVCCompiler, an implementation of the abstract CCompiler class -for the Microsoft Visual Studio. -""" - -# Written by Perry Stoll -# hacked by Robin Becker and Thomas Heller to do a better job of -# finding DevStudio (through the registry) - -import sys, os -from distutils.errors import \ - DistutilsExecError, DistutilsPlatformError, \ - CompileError, LibError, LinkError -from distutils.ccompiler import \ - CCompiler, gen_lib_options -from distutils import log - -_can_read_reg = False -try: - import winreg - - _can_read_reg = True - hkey_mod = winreg - - RegOpenKeyEx = winreg.OpenKeyEx - RegEnumKey = winreg.EnumKey - RegEnumValue = winreg.EnumValue - RegError = winreg.error - -except ImportError: - try: - import win32api - import win32con - _can_read_reg = True - hkey_mod = win32con - - RegOpenKeyEx = win32api.RegOpenKeyEx - RegEnumKey = win32api.RegEnumKey - RegEnumValue = win32api.RegEnumValue - RegError = win32api.error - except ImportError: - log.info("Warning: Can't read registry to find the " - "necessary compiler setting\n" - "Make sure that Python modules winreg, " - "win32api or win32con are installed.") - -if _can_read_reg: - HKEYS = (hkey_mod.HKEY_USERS, - hkey_mod.HKEY_CURRENT_USER, - hkey_mod.HKEY_LOCAL_MACHINE, - hkey_mod.HKEY_CLASSES_ROOT) - -def read_keys(base, key): - """Return list of registry keys.""" - try: - handle = RegOpenKeyEx(base, key) - except RegError: - return None - L = [] - i = 0 - while True: - try: - k = RegEnumKey(handle, i) - except RegError: - break - L.append(k) - i += 1 - return L - -def read_values(base, key): - """Return dict of registry keys and values. - - All names are converted to lowercase. - """ - try: - handle = RegOpenKeyEx(base, key) - except RegError: - return None - d = {} - i = 0 - while True: - try: - name, value, type = RegEnumValue(handle, i) - except RegError: - break - name = name.lower() - d[convert_mbcs(name)] = convert_mbcs(value) - i += 1 - return d - -def convert_mbcs(s): - dec = getattr(s, "decode", None) - if dec is not None: - try: - s = dec("mbcs") - except UnicodeError: - pass - return s - -class MacroExpander: - def __init__(self, version): - self.macros = {} - self.load_macros(version) - - def set_macro(self, macro, path, key): - for base in HKEYS: - d = read_values(base, path) - if d: - self.macros["$(%s)" % macro] = d[key] - break - - def load_macros(self, version): - vsbase = r"Software\Microsoft\VisualStudio\%0.1f" % version - self.set_macro("VCInstallDir", vsbase + r"\Setup\VC", "productdir") - self.set_macro("VSInstallDir", vsbase + r"\Setup\VS", "productdir") - net = r"Software\Microsoft\.NETFramework" - self.set_macro("FrameworkDir", net, "installroot") - try: - if version > 7.0: - self.set_macro("FrameworkSDKDir", net, "sdkinstallrootv1.1") - else: - self.set_macro("FrameworkSDKDir", net, "sdkinstallroot") - except KeyError as exc: # - raise DistutilsPlatformError( - """Python was built with Visual Studio 2003; -extensions must be built with a compiler than can generate compatible binaries. -Visual Studio 2003 was not found on this system. If you have Cygwin installed, -you can try compiling with MingW32, by passing "-c mingw32" to setup.py.""") - - p = r"Software\Microsoft\NET Framework Setup\Product" - for base in HKEYS: - try: - h = RegOpenKeyEx(base, p) - except RegError: - continue - key = RegEnumKey(h, 0) - d = read_values(base, r"%s\%s" % (p, key)) - self.macros["$(FrameworkVersion)"] = d["version"] - - def sub(self, s): - for k, v in self.macros.items(): - s = s.replace(k, v) - return s - -def get_build_version(): - """Return the version of MSVC that was used to build Python. - - For Python 2.3 and up, the version number is included in - sys.version. For earlier versions, assume the compiler is MSVC 6. - """ - prefix = "MSC v." - i = sys.version.find(prefix) - if i == -1: - return 6 - i = i + len(prefix) - s, rest = sys.version[i:].split(" ", 1) - majorVersion = int(s[:-2]) - 6 - if majorVersion >= 13: - # v13 was skipped and should be v14 - majorVersion += 1 - minorVersion = int(s[2:3]) / 10.0 - # I don't think paths are affected by minor version in version 6 - if majorVersion == 6: - minorVersion = 0 - if majorVersion >= 6: - return majorVersion + minorVersion - # else we don't know what version of the compiler this is - return None - -def get_build_architecture(): - """Return the processor architecture. - - Possible results are "Intel" or "AMD64". - """ - - prefix = " bit (" - i = sys.version.find(prefix) - if i == -1: - return "Intel" - j = sys.version.find(")", i) - return sys.version[i+len(prefix):j] - -def normalize_and_reduce_paths(paths): - """Return a list of normalized paths with duplicates removed. - - The current order of paths is maintained. - """ - # Paths are normalized so things like: /a and /a/ aren't both preserved. - reduced_paths = [] - for p in paths: - np = os.path.normpath(p) - # XXX(nnorwitz): O(n**2), if reduced_paths gets long perhaps use a set. - if np not in reduced_paths: - reduced_paths.append(np) - return reduced_paths - - -class MSVCCompiler(CCompiler) : - """Concrete class that implements an interface to Microsoft Visual C++, - as defined by the CCompiler abstract class.""" - - compiler_type = 'msvc' - - # Just set this so CCompiler's constructor doesn't barf. We currently - # don't use the 'set_executables()' bureaucracy provided by CCompiler, - # as it really isn't necessary for this sort of single-compiler class. - # Would be nice to have a consistent interface with UnixCCompiler, - # though, so it's worth thinking about. - executables = {} - - # Private class data (need to distinguish C from C++ source for compiler) - _c_extensions = ['.c'] - _cpp_extensions = ['.cc', '.cpp', '.cxx'] - _rc_extensions = ['.rc'] - _mc_extensions = ['.mc'] - - # Needed for the filename generation methods provided by the - # base class, CCompiler. - src_extensions = (_c_extensions + _cpp_extensions + - _rc_extensions + _mc_extensions) - res_extension = '.res' - obj_extension = '.obj' - static_lib_extension = '.lib' - shared_lib_extension = '.dll' - static_lib_format = shared_lib_format = '%s%s' - exe_extension = '.exe' - - def __init__(self, verbose=0, dry_run=0, force=0): - CCompiler.__init__ (self, verbose, dry_run, force) - self.__version = get_build_version() - self.__arch = get_build_architecture() - if self.__arch == "Intel": - # x86 - if self.__version >= 7: - self.__root = r"Software\Microsoft\VisualStudio" - self.__macros = MacroExpander(self.__version) - else: - self.__root = r"Software\Microsoft\Devstudio" - self.__product = "Visual Studio version %s" % self.__version - else: - # Win64. Assume this was built with the platform SDK - self.__product = "Microsoft SDK compiler %s" % (self.__version + 6) - - self.initialized = False - - def initialize(self): - self.__paths = [] - if "DISTUTILS_USE_SDK" in os.environ and "MSSdk" in os.environ and self.find_exe("cl.exe"): - # Assume that the SDK set up everything alright; don't try to be - # smarter - self.cc = "cl.exe" - self.linker = "link.exe" - self.lib = "lib.exe" - self.rc = "rc.exe" - self.mc = "mc.exe" - else: - self.__paths = self.get_msvc_paths("path") - - if len(self.__paths) == 0: - raise DistutilsPlatformError("Python was built with %s, " - "and extensions need to be built with the same " - "version of the compiler, but it isn't installed." - % self.__product) - - self.cc = self.find_exe("cl.exe") - self.linker = self.find_exe("link.exe") - self.lib = self.find_exe("lib.exe") - self.rc = self.find_exe("rc.exe") # resource compiler - self.mc = self.find_exe("mc.exe") # message compiler - self.set_path_env_var('lib') - self.set_path_env_var('include') - - # extend the MSVC path with the current path - try: - for p in os.environ['path'].split(';'): - self.__paths.append(p) - except KeyError: - pass - self.__paths = normalize_and_reduce_paths(self.__paths) - os.environ['path'] = ";".join(self.__paths) - - self.preprocess_options = None - if self.__arch == "Intel": - self.compile_options = [ '/nologo', '/Ox', '/MD', '/W3', '/GX' , - '/DNDEBUG'] - self.compile_options_debug = ['/nologo', '/Od', '/MDd', '/W3', '/GX', - '/Z7', '/D_DEBUG'] - else: - # Win64 - self.compile_options = [ '/nologo', '/Ox', '/MD', '/W3', '/GS-' , - '/DNDEBUG'] - self.compile_options_debug = ['/nologo', '/Od', '/MDd', '/W3', '/GS-', - '/Z7', '/D_DEBUG'] - - self.ldflags_shared = ['/DLL', '/nologo', '/INCREMENTAL:NO'] - if self.__version >= 7: - self.ldflags_shared_debug = [ - '/DLL', '/nologo', '/INCREMENTAL:no', '/DEBUG' - ] - else: - self.ldflags_shared_debug = [ - '/DLL', '/nologo', '/INCREMENTAL:no', '/pdb:None', '/DEBUG' - ] - self.ldflags_static = [ '/nologo'] - - self.initialized = True - - # -- Worker methods ------------------------------------------------ - - def object_filenames(self, - source_filenames, - strip_dir=0, - output_dir=''): - # Copied from ccompiler.py, extended to return .res as 'object'-file - # for .rc input file - if output_dir is None: output_dir = '' - obj_names = [] - for src_name in source_filenames: - (base, ext) = os.path.splitext (src_name) - base = os.path.splitdrive(base)[1] # Chop off the drive - base = base[os.path.isabs(base):] # If abs, chop off leading / - if ext not in self.src_extensions: - # Better to raise an exception instead of silently continuing - # and later complain about sources and targets having - # different lengths - raise CompileError ("Don't know how to compile %s" % src_name) - if strip_dir: - base = os.path.basename (base) - if ext in self._rc_extensions: - obj_names.append (os.path.join (output_dir, - base + self.res_extension)) - elif ext in self._mc_extensions: - obj_names.append (os.path.join (output_dir, - base + self.res_extension)) - else: - obj_names.append (os.path.join (output_dir, - base + self.obj_extension)) - return obj_names - - - def compile(self, sources, - output_dir=None, macros=None, include_dirs=None, debug=0, - extra_preargs=None, extra_postargs=None, depends=None): - - if not self.initialized: - self.initialize() - compile_info = self._setup_compile(output_dir, macros, include_dirs, - sources, depends, extra_postargs) - macros, objects, extra_postargs, pp_opts, build = compile_info - - compile_opts = extra_preargs or [] - compile_opts.append ('/c') - if debug: - compile_opts.extend(self.compile_options_debug) - else: - compile_opts.extend(self.compile_options) - - for obj in objects: - try: - src, ext = build[obj] - except KeyError: - continue - if debug: - # pass the full pathname to MSVC in debug mode, - # this allows the debugger to find the source file - # without asking the user to browse for it - src = os.path.abspath(src) - - if ext in self._c_extensions: - input_opt = "/Tc" + src - elif ext in self._cpp_extensions: - input_opt = "/Tp" + src - elif ext in self._rc_extensions: - # compile .RC to .RES file - input_opt = src - output_opt = "/fo" + obj - try: - self.spawn([self.rc] + pp_opts + - [output_opt] + [input_opt]) - except DistutilsExecError as msg: - raise CompileError(msg) - continue - elif ext in self._mc_extensions: - # Compile .MC to .RC file to .RES file. - # * '-h dir' specifies the directory for the - # generated include file - # * '-r dir' specifies the target directory of the - # generated RC file and the binary message resource - # it includes - # - # For now (since there are no options to change this), - # we use the source-directory for the include file and - # the build directory for the RC file and message - # resources. This works at least for win32all. - h_dir = os.path.dirname(src) - rc_dir = os.path.dirname(obj) - try: - # first compile .MC to .RC and .H file - self.spawn([self.mc] + - ['-h', h_dir, '-r', rc_dir] + [src]) - base, _ = os.path.splitext (os.path.basename (src)) - rc_file = os.path.join (rc_dir, base + '.rc') - # then compile .RC to .RES file - self.spawn([self.rc] + - ["/fo" + obj] + [rc_file]) - - except DistutilsExecError as msg: - raise CompileError(msg) - continue - else: - # how to handle this file? - raise CompileError("Don't know how to compile %s to %s" - % (src, obj)) - - output_opt = "/Fo" + obj - try: - self.spawn([self.cc] + compile_opts + pp_opts + - [input_opt, output_opt] + - extra_postargs) - except DistutilsExecError as msg: - raise CompileError(msg) - - return objects - - - def create_static_lib(self, - objects, - output_libname, - output_dir=None, - debug=0, - target_lang=None): - - if not self.initialized: - self.initialize() - (objects, output_dir) = self._fix_object_args(objects, output_dir) - output_filename = self.library_filename(output_libname, - output_dir=output_dir) - - if self._need_link(objects, output_filename): - lib_args = objects + ['/OUT:' + output_filename] - if debug: - pass # XXX what goes here? - try: - self.spawn([self.lib] + lib_args) - except DistutilsExecError as msg: - raise LibError(msg) - else: - log.debug("skipping %s (up-to-date)", output_filename) - - - def link(self, - target_desc, - objects, - output_filename, - output_dir=None, - libraries=None, - library_dirs=None, - runtime_library_dirs=None, - export_symbols=None, - debug=0, - extra_preargs=None, - extra_postargs=None, - build_temp=None, - target_lang=None): - - if not self.initialized: - self.initialize() - (objects, output_dir) = self._fix_object_args(objects, output_dir) - fixed_args = self._fix_lib_args(libraries, library_dirs, - runtime_library_dirs) - (libraries, library_dirs, runtime_library_dirs) = fixed_args - - if runtime_library_dirs: - self.warn ("I don't know what to do with 'runtime_library_dirs': " - + str (runtime_library_dirs)) - - lib_opts = gen_lib_options(self, - library_dirs, runtime_library_dirs, - libraries) - if output_dir is not None: - output_filename = os.path.join(output_dir, output_filename) - - if self._need_link(objects, output_filename): - if target_desc == CCompiler.EXECUTABLE: - if debug: - ldflags = self.ldflags_shared_debug[1:] - else: - ldflags = self.ldflags_shared[1:] - else: - if debug: - ldflags = self.ldflags_shared_debug - else: - ldflags = self.ldflags_shared - - export_opts = [] - for sym in (export_symbols or []): - export_opts.append("/EXPORT:" + sym) - - ld_args = (ldflags + lib_opts + export_opts + - objects + ['/OUT:' + output_filename]) - - # The MSVC linker generates .lib and .exp files, which cannot be - # suppressed by any linker switches. The .lib files may even be - # needed! Make sure they are generated in the temporary build - # directory. Since they have different names for debug and release - # builds, they can go into the same directory. - if export_symbols is not None: - (dll_name, dll_ext) = os.path.splitext( - os.path.basename(output_filename)) - implib_file = os.path.join( - os.path.dirname(objects[0]), - self.library_filename(dll_name)) - ld_args.append ('/IMPLIB:' + implib_file) - - if extra_preargs: - ld_args[:0] = extra_preargs - if extra_postargs: - ld_args.extend(extra_postargs) - - self.mkpath(os.path.dirname(output_filename)) - try: - self.spawn([self.linker] + ld_args) - except DistutilsExecError as msg: - raise LinkError(msg) - - else: - log.debug("skipping %s (up-to-date)", output_filename) - - - # -- Miscellaneous methods ----------------------------------------- - # These are all used by the 'gen_lib_options() function, in - # ccompiler.py. - - def library_dir_option(self, dir): - return "/LIBPATH:" + dir - - def runtime_library_dir_option(self, dir): - raise DistutilsPlatformError( - "don't know how to set runtime library search path for MSVC++") - - def library_option(self, lib): - return self.library_filename(lib) - - - def find_library_file(self, dirs, lib, debug=0): - # Prefer a debugging library if found (and requested), but deal - # with it if we don't have one. - if debug: - try_names = [lib + "_d", lib] - else: - try_names = [lib] - for dir in dirs: - for name in try_names: - libfile = os.path.join(dir, self.library_filename (name)) - if os.path.exists(libfile): - return libfile - else: - # Oops, didn't find it in *any* of 'dirs' - return None - - # Helper methods for using the MSVC registry settings - - def find_exe(self, exe): - """Return path to an MSVC executable program. - - Tries to find the program in several places: first, one of the - MSVC program search paths from the registry; next, the directories - in the PATH environment variable. If any of those work, return an - absolute path that is known to exist. If none of them work, just - return the original program name, 'exe'. - """ - for p in self.__paths: - fn = os.path.join(os.path.abspath(p), exe) - if os.path.isfile(fn): - return fn - - # didn't find it; try existing path - for p in os.environ['Path'].split(';'): - fn = os.path.join(os.path.abspath(p),exe) - if os.path.isfile(fn): - return fn - - return exe - - def get_msvc_paths(self, path, platform='x86'): - """Get a list of devstudio directories (include, lib or path). - - Return a list of strings. The list will be empty if unable to - access the registry or appropriate registry keys not found. - """ - if not _can_read_reg: - return [] - - path = path + " dirs" - if self.__version >= 7: - key = (r"%s\%0.1f\VC\VC_OBJECTS_PLATFORM_INFO\Win32\Directories" - % (self.__root, self.__version)) - else: - key = (r"%s\6.0\Build System\Components\Platforms" - r"\Win32 (%s)\Directories" % (self.__root, platform)) - - for base in HKEYS: - d = read_values(base, key) - if d: - if self.__version >= 7: - return self.__macros.sub(d[path]).split(";") - else: - return d[path].split(";") - # MSVC 6 seems to create the registry entries we need only when - # the GUI is run. - if self.__version == 6: - for base in HKEYS: - if read_values(base, r"%s\6.0" % self.__root) is not None: - self.warn("It seems you have Visual Studio 6 installed, " - "but the expected registry settings are not present.\n" - "You must at least run the Visual Studio GUI once " - "so that these entries are created.") - break - return [] - - def set_path_env_var(self, name): - """Set environment variable 'name' to an MSVC path type value. - - This is equivalent to a SET command prior to execution of spawned - commands. - """ - - if name == "lib": - p = self.get_msvc_paths("library") - else: - p = self.get_msvc_paths(name) - if p: - os.environ[name] = ';'.join(p) - - -if get_build_version() >= 8.0: - log.debug("Importing new compiler from distutils.msvc9compiler") - OldMSVCCompiler = MSVCCompiler - from distutils.msvc9compiler import MSVCCompiler - # get_build_architecture not really relevant now we support cross-compile - from distutils.msvc9compiler import MacroExpander diff --git a/Lib/distutils/spawn.py b/Lib/distutils/spawn.py deleted file mode 100644 index 31df3f7f..00000000 --- a/Lib/distutils/spawn.py +++ /dev/null @@ -1,129 +0,0 @@ -"""distutils.spawn - -Provides the 'spawn()' function, a front-end to various platform- -specific functions for launching another program in a sub-process. -Also provides the 'find_executable()' to search the path for a given -executable name. -""" - -import sys -import os -import subprocess - -from distutils.errors import DistutilsPlatformError, DistutilsExecError -from distutils.debug import DEBUG -from distutils import log - - -if sys.platform == 'darwin': - _cfg_target = None - _cfg_target_split = None - - -def spawn(cmd, search_path=1, verbose=0, dry_run=0): - """Run another program, specified as a command list 'cmd', in a new process. - - 'cmd' is just the argument list for the new process, ie. - cmd[0] is the program to run and cmd[1:] are the rest of its arguments. - There is no way to run a program with a name different from that of its - executable. - - If 'search_path' is true (the default), the system's executable - search path will be used to find the program; otherwise, cmd[0] - must be the exact path to the executable. If 'dry_run' is true, - the command will not actually be run. - - Raise DistutilsExecError if running the program fails in any way; just - return on success. - """ - # cmd is documented as a list, but just in case some code passes a tuple - # in, protect our %-formatting code against horrible death - cmd = list(cmd) - - log.info(' '.join(cmd)) - if dry_run: - return - - if search_path: - executable = find_executable(cmd[0]) - if executable is not None: - cmd[0] = executable - - env = None - if sys.platform == 'darwin': - global _cfg_target, _cfg_target_split - if _cfg_target is None: - from distutils import sysconfig - _cfg_target = sysconfig.get_config_var( - 'MACOSX_DEPLOYMENT_TARGET') or '' - if _cfg_target: - _cfg_target_split = [int(x) for x in _cfg_target.split('.')] - if _cfg_target: - # Ensure that the deployment target of the build process is not - # less than 10.3 if the interpreter was built for 10.3 or later. - # This ensures extension modules are built with correct - # compatibility values, specifically LDSHARED which can use - # '-undefined dynamic_lookup' which only works on >= 10.3. - cur_target = os.environ.get('MACOSX_DEPLOYMENT_TARGET', _cfg_target) - cur_target_split = [int(x) for x in cur_target.split('.')] - if _cfg_target_split[:2] >= [10, 3] and cur_target_split[:2] < [10, 3]: - my_msg = ('$MACOSX_DEPLOYMENT_TARGET mismatch: ' - 'now "%s" but "%s" during configure;' - 'must use 10.3 or later' - % (cur_target, _cfg_target)) - raise DistutilsPlatformError(my_msg) - env = dict(os.environ, - MACOSX_DEPLOYMENT_TARGET=cur_target) - - try: - proc = subprocess.Popen(cmd, env=env) - proc.wait() - exitcode = proc.returncode - except OSError as exc: - if not DEBUG: - cmd = cmd[0] - raise DistutilsExecError( - "command %r failed: %s" % (cmd, exc.args[-1])) from exc - - if exitcode: - if not DEBUG: - cmd = cmd[0] - raise DistutilsExecError( - "command %r failed with exit code %s" % (cmd, exitcode)) - - -def find_executable(executable, path=None): - """Tries to find 'executable' in the directories listed in 'path'. - - A string listing directories separated by 'os.pathsep'; defaults to - os.environ['PATH']. Returns the complete filename or None if not found. - """ - _, ext = os.path.splitext(executable) - if (sys.platform == 'win32') and (ext != '.exe'): - executable = executable + '.exe' - - if os.path.isfile(executable): - return executable - - if path is None: - path = os.environ.get('PATH', None) - if path is None: - try: - path = os.confstr("CS_PATH") - except (AttributeError, ValueError): - # os.confstr() or CS_PATH is not available - path = os.defpath - # bpo-35755: Don't use os.defpath if the PATH environment variable is - # set to an empty string - - # PATH='' doesn't match, whereas PATH=':' looks in the current directory - if not path: - return None - - paths = path.split(os.pathsep) - for p in paths: - f = os.path.join(p, executable) - if os.path.isfile(f): - # the file exists, we have a shot at spawn working - return f - return None diff --git a/Lib/distutils/sysconfig.py b/Lib/distutils/sysconfig.py deleted file mode 100644 index 03b85584..00000000 --- a/Lib/distutils/sysconfig.py +++ /dev/null @@ -1,346 +0,0 @@ -"""Provide access to Python's configuration information. The specific -configuration variables available depend heavily on the platform and -configuration. The values may be retrieved using -get_config_var(name), and the list of variables is available via -get_config_vars().keys(). Additional convenience functions are also -available. - -Written by: Fred L. Drake, Jr. -Email: <fdrake@acm.org> -""" - -import _imp -import os -import re -import sys -import warnings - -from functools import partial - -from .errors import DistutilsPlatformError - -from sysconfig import ( - _PREFIX as PREFIX, - _BASE_PREFIX as BASE_PREFIX, - _EXEC_PREFIX as EXEC_PREFIX, - _BASE_EXEC_PREFIX as BASE_EXEC_PREFIX, - _PROJECT_BASE as project_base, - _PYTHON_BUILD as python_build, - _init_posix as sysconfig_init_posix, - parse_config_h as sysconfig_parse_config_h, - - _init_non_posix, - - _variable_rx, - _findvar1_rx, - _findvar2_rx, - - expand_makefile_vars, - is_python_build, - get_config_h_filename, - get_config_var, - get_config_vars, - get_makefile_filename, - get_python_version, -) - -# This is better than -# from sysconfig import _CONFIG_VARS as _config_vars -# because it makes sure that the global dictionary is initialized -# which might not be true in the time of import. -_config_vars = get_config_vars() - -warnings.warn( - 'The distutils.sysconfig module is deprecated, use sysconfig instead', - DeprecationWarning, - stacklevel=2 -) - - -# Following functions are the same as in sysconfig but with different API -def parse_config_h(fp, g=None): - return sysconfig_parse_config_h(fp, vars=g) - - -_python_build = partial(is_python_build, check_home=True) -_init_posix = partial(sysconfig_init_posix, _config_vars) -_init_nt = partial(_init_non_posix, _config_vars) - - -# Similar function is also implemented in sysconfig as _parse_makefile -# but without the parsing capabilities of distutils.text_file.TextFile. -def parse_makefile(fn, g=None): - """Parse a Makefile-style file. - A dictionary containing name/value pairs is returned. If an - optional dictionary is passed in as the second argument, it is - used instead of a new dictionary. - """ - from distutils.text_file import TextFile - fp = TextFile(fn, strip_comments=1, skip_blanks=1, join_lines=1, errors="surrogateescape") - - if g is None: - g = {} - done = {} - notdone = {} - - while True: - line = fp.readline() - if line is None: # eof - break - m = re.match(_variable_rx, line) - if m: - n, v = m.group(1, 2) - v = v.strip() - # `$$' is a literal `$' in make - tmpv = v.replace('$$', '') - - if "$" in tmpv: - notdone[n] = v - else: - try: - v = int(v) - except ValueError: - # insert literal `$' - done[n] = v.replace('$$', '$') - else: - done[n] = v - - # Variables with a 'PY_' prefix in the makefile. These need to - # be made available without that prefix through sysconfig. - # Special care is needed to ensure that variable expansion works, even - # if the expansion uses the name without a prefix. - renamed_variables = ('CFLAGS', 'LDFLAGS', 'CPPFLAGS') - - # do variable interpolation here - while notdone: - for name in list(notdone): - value = notdone[name] - m = re.search(_findvar1_rx, value) or re.search(_findvar2_rx, value) - if m: - n = m.group(1) - found = True - if n in done: - item = str(done[n]) - elif n in notdone: - # get it on a subsequent round - found = False - elif n in os.environ: - # do it like make: fall back to environment - item = os.environ[n] - - elif n in renamed_variables: - if name.startswith('PY_') and name[3:] in renamed_variables: - item = "" - - elif 'PY_' + n in notdone: - found = False - - else: - item = str(done['PY_' + n]) - else: - done[n] = item = "" - if found: - after = value[m.end():] - value = value[:m.start()] + item + after - if "$" in after: - notdone[name] = value - else: - try: value = int(value) - except ValueError: - done[name] = value.strip() - else: - done[name] = value - del notdone[name] - - if name.startswith('PY_') \ - and name[3:] in renamed_variables: - - name = name[3:] - if name not in done: - done[name] = value - else: - # bogus variable reference; just drop it since we can't deal - del notdone[name] - - fp.close() - - # strip spurious spaces - for k, v in done.items(): - if isinstance(v, str): - done[k] = v.strip() - - # save the results in the global dictionary - g.update(done) - return g - - -# Following functions are deprecated together with this module and they -# have no direct replacement - -# Calculate the build qualifier flags if they are defined. Adding the flags -# to the include and lib directories only makes sense for an installation, not -# an in-source build. -build_flags = '' -try: - if not python_build: - build_flags = sys.abiflags -except AttributeError: - # It's not a configure-based build, so the sys module doesn't have - # this attribute, which is fine. - pass - - -def customize_compiler(compiler): - """Do any platform-specific customization of a CCompiler instance. - - Mainly needed on Unix, so we can plug in the information that - varies across Unices and is stored in Python's Makefile. - """ - if compiler.compiler_type == "unix": - if sys.platform == "darwin": - # Perform first-time customization of compiler-related - # config vars on OS X now that we know we need a compiler. - # This is primarily to support Pythons from binary - # installers. The kind and paths to build tools on - # the user system may vary significantly from the system - # that Python itself was built on. Also the user OS - # version and build tools may not support the same set - # of CPU architectures for universal builds. - if not _config_vars.get('CUSTOMIZED_OSX_COMPILER'): - import _osx_support - _osx_support.customize_compiler(_config_vars) - _config_vars['CUSTOMIZED_OSX_COMPILER'] = 'True' - - (cc, cxx, cflags, ccshared, ldshared, shlib_suffix, ar, ar_flags) = \ - get_config_vars('CC', 'CXX', 'CFLAGS', - 'CCSHARED', 'LDSHARED', 'SHLIB_SUFFIX', 'AR', 'ARFLAGS') - - if 'CC' in os.environ: - newcc = os.environ['CC'] - if (sys.platform == 'darwin' - and 'LDSHARED' not in os.environ - and ldshared.startswith(cc)): - # On OS X, if CC is overridden, use that as the default - # command for LDSHARED as well - ldshared = newcc + ldshared[len(cc):] - cc = newcc - if 'CXX' in os.environ: - cxx = os.environ['CXX'] - if 'LDSHARED' in os.environ: - ldshared = os.environ['LDSHARED'] - if 'CPP' in os.environ: - cpp = os.environ['CPP'] - else: - cpp = cc + " -E" # not always - if 'LDFLAGS' in os.environ: - ldshared = ldshared + ' ' + os.environ['LDFLAGS'] - if 'CFLAGS' in os.environ: - cflags = cflags + ' ' + os.environ['CFLAGS'] - ldshared = ldshared + ' ' + os.environ['CFLAGS'] - if 'CPPFLAGS' in os.environ: - cpp = cpp + ' ' + os.environ['CPPFLAGS'] - cflags = cflags + ' ' + os.environ['CPPFLAGS'] - ldshared = ldshared + ' ' + os.environ['CPPFLAGS'] - if 'AR' in os.environ: - ar = os.environ['AR'] - if 'ARFLAGS' in os.environ: - archiver = ar + ' ' + os.environ['ARFLAGS'] - else: - archiver = ar + ' ' + ar_flags - - cc_cmd = cc + ' ' + cflags - compiler.set_executables( - preprocessor=cpp, - compiler=cc_cmd, - compiler_so=cc_cmd + ' ' + ccshared, - compiler_cxx=cxx, - linker_so=ldshared, - linker_exe=cc, - archiver=archiver) - - compiler.shared_lib_extension = shlib_suffix - - -def get_python_inc(plat_specific=0, prefix=None): - """Return the directory containing installed Python header files. - - If 'plat_specific' is false (the default), this is the path to the - non-platform-specific header files, i.e. Python.h and so on; - otherwise, this is the path to platform-specific header files - (namely pyconfig.h). - - If 'prefix' is supplied, use it instead of sys.base_prefix or - sys.base_exec_prefix -- i.e., ignore 'plat_specific'. - """ - if prefix is None: - prefix = plat_specific and BASE_EXEC_PREFIX or BASE_PREFIX - if os.name == "posix": - if python_build: - # Assume the executable is in the build directory. The - # pyconfig.h file should be in the same directory. Since - # the build directory may not be the source directory, we - # must use "srcdir" from the makefile to find the "Include" - # directory. - if plat_specific: - return project_base - else: - incdir = os.path.join(get_config_var('srcdir'), 'Include') - return os.path.normpath(incdir) - python_dir = 'python' + get_python_version() + build_flags - return os.path.join(prefix, "include", python_dir) - elif os.name == "nt": - if python_build: - # Include both the include and PC dir to ensure we can find - # pyconfig.h - return (os.path.join(prefix, "include") + os.path.pathsep + - os.path.join(prefix, "PC")) - return os.path.join(prefix, "include") - else: - raise DistutilsPlatformError( - "I don't know where Python installs its C header files " - "on platform '%s'" % os.name) - - -def get_python_lib(plat_specific=0, standard_lib=0, prefix=None): - """Return the directory containing the Python library (standard or - site additions). - - If 'plat_specific' is true, return the directory containing - platform-specific modules, i.e. any module from a non-pure-Python - module distribution; otherwise, return the platform-shared library - directory. If 'standard_lib' is true, return the directory - containing standard Python library modules; otherwise, return the - directory for site-specific modules. - - If 'prefix' is supplied, use it instead of sys.base_prefix or - sys.base_exec_prefix -- i.e., ignore 'plat_specific'. - """ - if prefix is None: - if standard_lib: - prefix = plat_specific and BASE_EXEC_PREFIX or BASE_PREFIX - else: - prefix = plat_specific and EXEC_PREFIX or PREFIX - - if os.name == "posix": - if plat_specific or standard_lib: - # Platform-specific modules (any module from a non-pure-Python - # module distribution) or standard Python library modules. - libdir = sys.platlibdir - else: - # Pure Python - libdir = "lib" - libpython = os.path.join(prefix, libdir, - "python" + get_python_version()) - if standard_lib: - return libpython - else: - return os.path.join(libpython, "site-packages") - elif os.name == "nt": - if standard_lib: - return os.path.join(prefix, "Lib") - else: - return os.path.join(prefix, "Lib", "site-packages") - else: - raise DistutilsPlatformError( - "I don't know where Python installs its library " - "on platform '%s'" % os.name) diff --git a/Lib/distutils/tests/Setup.sample b/Lib/distutils/tests/Setup.sample deleted file mode 100644 index 36c4290d..00000000 --- a/Lib/distutils/tests/Setup.sample +++ /dev/null @@ -1,67 +0,0 @@ -# Setup file from the pygame project - -#--StartConfig -SDL = -I/usr/include/SDL -D_REENTRANT -lSDL -FONT = -lSDL_ttf -IMAGE = -lSDL_image -MIXER = -lSDL_mixer -SMPEG = -lsmpeg -PNG = -lpng -JPEG = -ljpeg -SCRAP = -lX11 -PORTMIDI = -lportmidi -PORTTIME = -lporttime -#--EndConfig - -#DEBUG = -C-W -C-Wall -DEBUG = - -#the following modules are optional. you will want to compile -#everything you can, but you can ignore ones you don't have -#dependencies for, just comment them out - -imageext src/imageext.c $(SDL) $(IMAGE) $(PNG) $(JPEG) $(DEBUG) -font src/font.c $(SDL) $(FONT) $(DEBUG) -mixer src/mixer.c $(SDL) $(MIXER) $(DEBUG) -mixer_music src/music.c $(SDL) $(MIXER) $(DEBUG) -_numericsurfarray src/_numericsurfarray.c $(SDL) $(DEBUG) -_numericsndarray src/_numericsndarray.c $(SDL) $(MIXER) $(DEBUG) -movie src/movie.c $(SDL) $(SMPEG) $(DEBUG) -scrap src/scrap.c $(SDL) $(SCRAP) $(DEBUG) -_camera src/_camera.c src/camera_v4l2.c src/camera_v4l.c $(SDL) $(DEBUG) -pypm src/pypm.c $(SDL) $(PORTMIDI) $(PORTTIME) $(DEBUG) - -GFX = src/SDL_gfx/SDL_gfxPrimitives.c -#GFX = src/SDL_gfx/SDL_gfxBlitFunc.c src/SDL_gfx/SDL_gfxPrimitives.c -gfxdraw src/gfxdraw.c $(SDL) $(GFX) $(DEBUG) - - - -#these modules are required for pygame to run. they only require -#SDL as a dependency. these should not be altered - -base src/base.c $(SDL) $(DEBUG) -cdrom src/cdrom.c $(SDL) $(DEBUG) -color src/color.c $(SDL) $(DEBUG) -constants src/constants.c $(SDL) $(DEBUG) -display src/display.c $(SDL) $(DEBUG) -event src/event.c $(SDL) $(DEBUG) -fastevent src/fastevent.c src/fastevents.c $(SDL) $(DEBUG) -key src/key.c $(SDL) $(DEBUG) -mouse src/mouse.c $(SDL) $(DEBUG) -rect src/rect.c $(SDL) $(DEBUG) -rwobject src/rwobject.c $(SDL) $(DEBUG) -surface src/surface.c src/alphablit.c src/surface_fill.c $(SDL) $(DEBUG) -surflock src/surflock.c $(SDL) $(DEBUG) -time src/time.c $(SDL) $(DEBUG) -joystick src/joystick.c $(SDL) $(DEBUG) -draw src/draw.c $(SDL) $(DEBUG) -image src/image.c $(SDL) $(DEBUG) -overlay src/overlay.c $(SDL) $(DEBUG) -transform src/transform.c src/rotozoom.c src/scale2x.c src/scale_mmx.c $(SDL) $(DEBUG) -mask src/mask.c src/bitmask.c $(SDL) $(DEBUG) -bufferproxy src/bufferproxy.c $(SDL) $(DEBUG) -pixelarray src/pixelarray.c $(SDL) $(DEBUG) -_arraysurfarray src/_arraysurfarray.c $(SDL) $(DEBUG) - - diff --git a/Lib/distutils/tests/__init__.py b/Lib/distutils/tests/__init__.py deleted file mode 100644 index 16d011fd..00000000 --- a/Lib/distutils/tests/__init__.py +++ /dev/null @@ -1,41 +0,0 @@ -"""Test suite for distutils. - -This test suite consists of a collection of test modules in the -distutils.tests package. Each test module has a name starting with -'test' and contains a function test_suite(). The function is expected -to return an initialized unittest.TestSuite instance. - -Tests for the command classes in the distutils.command package are -included in distutils.tests as well, instead of using a separate -distutils.command.tests package, since command identification is done -by import rather than matching pre-defined names. - -""" - -import os -import sys -import unittest -from test.support import run_unittest -from test.support.warnings_helper import save_restore_warnings_filters - - -here = os.path.dirname(__file__) or os.curdir - - -def test_suite(): - suite = unittest.TestSuite() - for fn in os.listdir(here): - if fn.startswith("test") and fn.endswith(".py"): - modname = "distutils.tests." + fn[:-3] - # bpo-40055: Save/restore warnings filters to leave them unchanged. - # Importing tests imports docutils which imports pkg_resources - # which adds a warnings filter. - with save_restore_warnings_filters(): - __import__(modname) - module = sys.modules[modname] - suite.addTest(module.test_suite()) - return suite - - -if __name__ == "__main__": - run_unittest(test_suite()) diff --git a/Lib/distutils/tests/includetest.rst b/Lib/distutils/tests/includetest.rst deleted file mode 100644 index d7b4ae38..00000000 --- a/Lib/distutils/tests/includetest.rst +++ /dev/null @@ -1 +0,0 @@ -This should be included. diff --git a/Lib/distutils/tests/support.py b/Lib/distutils/tests/support.py deleted file mode 100644 index 23b907b6..00000000 --- a/Lib/distutils/tests/support.py +++ /dev/null @@ -1,209 +0,0 @@ -"""Support code for distutils test cases.""" -import os -import sys -import shutil -import tempfile -import unittest -import sysconfig -from copy import deepcopy -from test.support import os_helper - -from distutils import log -from distutils.log import DEBUG, INFO, WARN, ERROR, FATAL -from distutils.core import Distribution - - -class LoggingSilencer(object): - - def setUp(self): - super().setUp() - self.threshold = log.set_threshold(log.FATAL) - # catching warnings - # when log will be replaced by logging - # we won't need such monkey-patch anymore - self._old_log = log.Log._log - log.Log._log = self._log - self.logs = [] - - def tearDown(self): - log.set_threshold(self.threshold) - log.Log._log = self._old_log - super().tearDown() - - def _log(self, level, msg, args): - if level not in (DEBUG, INFO, WARN, ERROR, FATAL): - raise ValueError('%s wrong log level' % str(level)) - if not isinstance(msg, str): - raise TypeError("msg should be str, not '%.200s'" - % (type(msg).__name__)) - self.logs.append((level, msg, args)) - - def get_logs(self, *levels): - return [msg % args for level, msg, args - in self.logs if level in levels] - - def clear_logs(self): - self.logs = [] - - -class TempdirManager(object): - """Mix-in class that handles temporary directories for test cases. - - This is intended to be used with unittest.TestCase. - """ - - def setUp(self): - super().setUp() - self.old_cwd = os.getcwd() - self.tempdirs = [] - - def tearDown(self): - # Restore working dir, for Solaris and derivatives, where rmdir() - # on the current directory fails. - os.chdir(self.old_cwd) - super().tearDown() - while self.tempdirs: - tmpdir = self.tempdirs.pop() - os_helper.rmtree(tmpdir) - - def mkdtemp(self): - """Create a temporary directory that will be cleaned up. - - Returns the path of the directory. - """ - d = tempfile.mkdtemp() - self.tempdirs.append(d) - return d - - def write_file(self, path, content='xxx'): - """Writes a file in the given path. - - - path can be a string or a sequence. - """ - if isinstance(path, (list, tuple)): - path = os.path.join(*path) - f = open(path, 'w') - try: - f.write(content) - finally: - f.close() - - def create_dist(self, pkg_name='foo', **kw): - """Will generate a test environment. - - This function creates: - - a Distribution instance using keywords - - a temporary directory with a package structure - - It returns the package directory and the distribution - instance. - """ - tmp_dir = self.mkdtemp() - pkg_dir = os.path.join(tmp_dir, pkg_name) - os.mkdir(pkg_dir) - dist = Distribution(attrs=kw) - - return pkg_dir, dist - - -class DummyCommand: - """Class to store options for retrieval via set_undefined_options().""" - - def __init__(self, **kwargs): - for kw, val in kwargs.items(): - setattr(self, kw, val) - - def ensure_finalized(self): - pass - - -class EnvironGuard(object): - - def setUp(self): - super(EnvironGuard, self).setUp() - self.old_environ = deepcopy(os.environ) - - def tearDown(self): - for key, value in self.old_environ.items(): - if os.environ.get(key) != value: - os.environ[key] = value - - for key in tuple(os.environ.keys()): - if key not in self.old_environ: - del os.environ[key] - - super(EnvironGuard, self).tearDown() - - -def copy_xxmodule_c(directory): - """Helper for tests that need the xxmodule.c source file. - - Example use: - - def test_compile(self): - copy_xxmodule_c(self.tmpdir) - self.assertIn('xxmodule.c', os.listdir(self.tmpdir)) - - If the source file can be found, it will be copied to *directory*. If not, - the test will be skipped. Errors during copy are not caught. - """ - filename = _get_xxmodule_path() - if filename is None: - raise unittest.SkipTest('cannot find xxmodule.c (test must run in ' - 'the python build dir)') - shutil.copy(filename, directory) - - -def _get_xxmodule_path(): - srcdir = sysconfig.get_config_var('srcdir') - candidates = [ - # use installed copy if available - os.path.join(os.path.dirname(__file__), 'xxmodule.c'), - # otherwise try using copy from build directory - os.path.join(srcdir, 'Modules', 'xxmodule.c'), - # srcdir mysteriously can be $srcdir/Lib/distutils/tests when - # this file is run from its parent directory, so walk up the - # tree to find the real srcdir - os.path.join(srcdir, '..', '..', '..', 'Modules', 'xxmodule.c'), - ] - for path in candidates: - if os.path.exists(path): - return path - - -def fixup_build_ext(cmd): - """Function needed to make build_ext tests pass. - - When Python was built with --enable-shared on Unix, -L. is not enough to - find libpython<blah>.so, because regrtest runs in a tempdir, not in the - source directory where the .so lives. - - When Python was built with in debug mode on Windows, build_ext commands - need their debug attribute set, and it is not done automatically for - some reason. - - This function handles both of these things. Example use: - - cmd = build_ext(dist) - support.fixup_build_ext(cmd) - cmd.ensure_finalized() - - Unlike most other Unix platforms, Mac OS X embeds absolute paths - to shared libraries into executables, so the fixup is not needed there. - """ - if os.name == 'nt': - cmd.debug = sys.executable.endswith('_d.exe') - elif sysconfig.get_config_var('Py_ENABLE_SHARED'): - # To further add to the shared builds fun on Unix, we can't just add - # library_dirs to the Extension() instance because that doesn't get - # plumbed through to the final compiler command. - runshared = sysconfig.get_config_var('RUNSHARED') - if runshared is None: - cmd.library_dirs = ['.'] - else: - if sys.platform == 'darwin': - cmd.library_dirs = [] - else: - name, equals, value = runshared.partition('=') - cmd.library_dirs = [d for d in value.split(os.pathsep) if d] diff --git a/Lib/distutils/tests/test_archive_util.py b/Lib/distutils/tests/test_archive_util.py deleted file mode 100644 index 8aec8407..00000000 --- a/Lib/distutils/tests/test_archive_util.py +++ /dev/null @@ -1,396 +0,0 @@ -# -*- coding: utf-8 -*- -"""Tests for distutils.archive_util.""" -import unittest -import os -import sys -import tarfile -from os.path import splitdrive -import warnings - -from distutils import archive_util -from distutils.archive_util import (check_archive_formats, make_tarball, - make_zipfile, make_archive, - ARCHIVE_FORMATS) -from distutils.spawn import find_executable, spawn -from distutils.tests import support -from test.support import run_unittest, patch -from test.support.os_helper import change_cwd -from test.support.warnings_helper import check_warnings - -try: - import grp - import pwd - UID_GID_SUPPORT = True -except ImportError: - UID_GID_SUPPORT = False - -try: - import zipfile - ZIP_SUPPORT = True -except ImportError: - ZIP_SUPPORT = find_executable('zip') - -try: - import zlib - ZLIB_SUPPORT = True -except ImportError: - ZLIB_SUPPORT = False - -try: - import bz2 -except ImportError: - bz2 = None - -try: - import lzma -except ImportError: - lzma = None - -def can_fs_encode(filename): - """ - Return True if the filename can be saved in the file system. - """ - if os.path.supports_unicode_filenames: - return True - try: - filename.encode(sys.getfilesystemencoding()) - except UnicodeEncodeError: - return False - return True - - -class ArchiveUtilTestCase(support.TempdirManager, - support.LoggingSilencer, - unittest.TestCase): - - @unittest.skipUnless(ZLIB_SUPPORT, 'Need zlib support to run') - def test_make_tarball(self, name='archive'): - # creating something to tar - tmpdir = self._create_files() - self._make_tarball(tmpdir, name, '.tar.gz') - # trying an uncompressed one - self._make_tarball(tmpdir, name, '.tar', compress=None) - - @unittest.skipUnless(ZLIB_SUPPORT, 'Need zlib support to run') - def test_make_tarball_gzip(self): - tmpdir = self._create_files() - self._make_tarball(tmpdir, 'archive', '.tar.gz', compress='gzip') - - @unittest.skipUnless(bz2, 'Need bz2 support to run') - def test_make_tarball_bzip2(self): - tmpdir = self._create_files() - self._make_tarball(tmpdir, 'archive', '.tar.bz2', compress='bzip2') - - @unittest.skipUnless(lzma, 'Need lzma support to run') - def test_make_tarball_xz(self): - tmpdir = self._create_files() - self._make_tarball(tmpdir, 'archive', '.tar.xz', compress='xz') - - @unittest.skipUnless(can_fs_encode('Ã¥rchiv'), - 'File system cannot handle this filename') - def test_make_tarball_latin1(self): - """ - Mirror test_make_tarball, except filename contains latin characters. - """ - self.test_make_tarball('Ã¥rchiv') # note this isn't a real word - - @unittest.skipUnless(can_fs_encode('のアーカイブ'), - 'File system cannot handle this filename') - def test_make_tarball_extended(self): - """ - Mirror test_make_tarball, except filename contains extended - characters outside the latin charset. - """ - self.test_make_tarball('のアーカイブ') # japanese for archive - - def _make_tarball(self, tmpdir, target_name, suffix, **kwargs): - tmpdir2 = self.mkdtemp() - unittest.skipUnless(splitdrive(tmpdir)[0] == splitdrive(tmpdir2)[0], - "source and target should be on same drive") - - base_name = os.path.join(tmpdir2, target_name) - - # working with relative paths to avoid tar warnings - with change_cwd(tmpdir): - make_tarball(splitdrive(base_name)[1], 'dist', **kwargs) - - # check if the compressed tarball was created - tarball = base_name + suffix - self.assertTrue(os.path.exists(tarball)) - self.assertEqual(self._tarinfo(tarball), self._created_files) - - def _tarinfo(self, path): - tar = tarfile.open(path) - try: - names = tar.getnames() - names.sort() - return names - finally: - tar.close() - - _zip_created_files = ['dist/', 'dist/file1', 'dist/file2', - 'dist/sub/', 'dist/sub/file3', 'dist/sub2/'] - _created_files = [p.rstrip('/') for p in _zip_created_files] - - def _create_files(self): - # creating something to tar - tmpdir = self.mkdtemp() - dist = os.path.join(tmpdir, 'dist') - os.mkdir(dist) - self.write_file([dist, 'file1'], 'xxx') - self.write_file([dist, 'file2'], 'xxx') - os.mkdir(os.path.join(dist, 'sub')) - self.write_file([dist, 'sub', 'file3'], 'xxx') - os.mkdir(os.path.join(dist, 'sub2')) - return tmpdir - - @unittest.skipUnless(find_executable('tar') and find_executable('gzip') - and ZLIB_SUPPORT, - 'Need the tar, gzip and zlib command to run') - def test_tarfile_vs_tar(self): - tmpdir = self._create_files() - tmpdir2 = self.mkdtemp() - base_name = os.path.join(tmpdir2, 'archive') - old_dir = os.getcwd() - os.chdir(tmpdir) - try: - make_tarball(base_name, 'dist') - finally: - os.chdir(old_dir) - - # check if the compressed tarball was created - tarball = base_name + '.tar.gz' - self.assertTrue(os.path.exists(tarball)) - - # now create another tarball using `tar` - tarball2 = os.path.join(tmpdir, 'archive2.tar.gz') - tar_cmd = ['tar', '-cf', 'archive2.tar', 'dist'] - gzip_cmd = ['gzip', '-f', '-9', 'archive2.tar'] - old_dir = os.getcwd() - os.chdir(tmpdir) - try: - spawn(tar_cmd) - spawn(gzip_cmd) - finally: - os.chdir(old_dir) - - self.assertTrue(os.path.exists(tarball2)) - # let's compare both tarballs - self.assertEqual(self._tarinfo(tarball), self._created_files) - self.assertEqual(self._tarinfo(tarball2), self._created_files) - - # trying an uncompressed one - base_name = os.path.join(tmpdir2, 'archive') - old_dir = os.getcwd() - os.chdir(tmpdir) - try: - make_tarball(base_name, 'dist', compress=None) - finally: - os.chdir(old_dir) - tarball = base_name + '.tar' - self.assertTrue(os.path.exists(tarball)) - - # now for a dry_run - base_name = os.path.join(tmpdir2, 'archive') - old_dir = os.getcwd() - os.chdir(tmpdir) - try: - make_tarball(base_name, 'dist', compress=None, dry_run=True) - finally: - os.chdir(old_dir) - tarball = base_name + '.tar' - self.assertTrue(os.path.exists(tarball)) - - @unittest.skipUnless(find_executable('compress'), - 'The compress program is required') - def test_compress_deprecated(self): - tmpdir = self._create_files() - base_name = os.path.join(self.mkdtemp(), 'archive') - - # using compress and testing the PendingDeprecationWarning - old_dir = os.getcwd() - os.chdir(tmpdir) - try: - with check_warnings() as w: - warnings.simplefilter("always") - make_tarball(base_name, 'dist', compress='compress') - finally: - os.chdir(old_dir) - tarball = base_name + '.tar.Z' - self.assertTrue(os.path.exists(tarball)) - self.assertEqual(len(w.warnings), 1) - - # same test with dry_run - os.remove(tarball) - old_dir = os.getcwd() - os.chdir(tmpdir) - try: - with check_warnings() as w: - warnings.simplefilter("always") - make_tarball(base_name, 'dist', compress='compress', - dry_run=True) - finally: - os.chdir(old_dir) - self.assertFalse(os.path.exists(tarball)) - self.assertEqual(len(w.warnings), 1) - - @unittest.skipUnless(ZIP_SUPPORT and ZLIB_SUPPORT, - 'Need zip and zlib support to run') - def test_make_zipfile(self): - # creating something to tar - tmpdir = self._create_files() - base_name = os.path.join(self.mkdtemp(), 'archive') - with change_cwd(tmpdir): - make_zipfile(base_name, 'dist') - - # check if the compressed tarball was created - tarball = base_name + '.zip' - self.assertTrue(os.path.exists(tarball)) - with zipfile.ZipFile(tarball) as zf: - self.assertEqual(sorted(zf.namelist()), self._zip_created_files) - - @unittest.skipUnless(ZIP_SUPPORT, 'Need zip support to run') - def test_make_zipfile_no_zlib(self): - patch(self, archive_util.zipfile, 'zlib', None) # force zlib ImportError - - called = [] - zipfile_class = zipfile.ZipFile - def fake_zipfile(*a, **kw): - if kw.get('compression', None) == zipfile.ZIP_STORED: - called.append((a, kw)) - return zipfile_class(*a, **kw) - - patch(self, archive_util.zipfile, 'ZipFile', fake_zipfile) - - # create something to tar and compress - tmpdir = self._create_files() - base_name = os.path.join(self.mkdtemp(), 'archive') - with change_cwd(tmpdir): - make_zipfile(base_name, 'dist') - - tarball = base_name + '.zip' - self.assertEqual(called, - [((tarball, "w"), {'compression': zipfile.ZIP_STORED})]) - self.assertTrue(os.path.exists(tarball)) - with zipfile.ZipFile(tarball) as zf: - self.assertEqual(sorted(zf.namelist()), self._zip_created_files) - - def test_check_archive_formats(self): - self.assertEqual(check_archive_formats(['gztar', 'xxx', 'zip']), - 'xxx') - self.assertIsNone(check_archive_formats(['gztar', 'bztar', 'xztar', - 'ztar', 'tar', 'zip'])) - - def test_make_archive(self): - tmpdir = self.mkdtemp() - base_name = os.path.join(tmpdir, 'archive') - self.assertRaises(ValueError, make_archive, base_name, 'xxx') - - def test_make_archive_cwd(self): - current_dir = os.getcwd() - def _breaks(*args, **kw): - raise RuntimeError() - ARCHIVE_FORMATS['xxx'] = (_breaks, [], 'xxx file') - try: - try: - make_archive('xxx', 'xxx', root_dir=self.mkdtemp()) - except: - pass - self.assertEqual(os.getcwd(), current_dir) - finally: - del ARCHIVE_FORMATS['xxx'] - - def test_make_archive_tar(self): - base_dir = self._create_files() - base_name = os.path.join(self.mkdtemp() , 'archive') - res = make_archive(base_name, 'tar', base_dir, 'dist') - self.assertTrue(os.path.exists(res)) - self.assertEqual(os.path.basename(res), 'archive.tar') - self.assertEqual(self._tarinfo(res), self._created_files) - - @unittest.skipUnless(ZLIB_SUPPORT, 'Need zlib support to run') - def test_make_archive_gztar(self): - base_dir = self._create_files() - base_name = os.path.join(self.mkdtemp() , 'archive') - res = make_archive(base_name, 'gztar', base_dir, 'dist') - self.assertTrue(os.path.exists(res)) - self.assertEqual(os.path.basename(res), 'archive.tar.gz') - self.assertEqual(self._tarinfo(res), self._created_files) - - @unittest.skipUnless(bz2, 'Need bz2 support to run') - def test_make_archive_bztar(self): - base_dir = self._create_files() - base_name = os.path.join(self.mkdtemp() , 'archive') - res = make_archive(base_name, 'bztar', base_dir, 'dist') - self.assertTrue(os.path.exists(res)) - self.assertEqual(os.path.basename(res), 'archive.tar.bz2') - self.assertEqual(self._tarinfo(res), self._created_files) - - @unittest.skipUnless(lzma, 'Need xz support to run') - def test_make_archive_xztar(self): - base_dir = self._create_files() - base_name = os.path.join(self.mkdtemp() , 'archive') - res = make_archive(base_name, 'xztar', base_dir, 'dist') - self.assertTrue(os.path.exists(res)) - self.assertEqual(os.path.basename(res), 'archive.tar.xz') - self.assertEqual(self._tarinfo(res), self._created_files) - - def test_make_archive_owner_group(self): - # testing make_archive with owner and group, with various combinations - # this works even if there's not gid/uid support - if UID_GID_SUPPORT: - group = grp.getgrgid(0)[0] - owner = pwd.getpwuid(0)[0] - else: - group = owner = 'root' - - base_dir = self._create_files() - root_dir = self.mkdtemp() - base_name = os.path.join(self.mkdtemp() , 'archive') - res = make_archive(base_name, 'zip', root_dir, base_dir, owner=owner, - group=group) - self.assertTrue(os.path.exists(res)) - - res = make_archive(base_name, 'zip', root_dir, base_dir) - self.assertTrue(os.path.exists(res)) - - res = make_archive(base_name, 'tar', root_dir, base_dir, - owner=owner, group=group) - self.assertTrue(os.path.exists(res)) - - res = make_archive(base_name, 'tar', root_dir, base_dir, - owner='kjhkjhkjg', group='oihohoh') - self.assertTrue(os.path.exists(res)) - - @unittest.skipUnless(ZLIB_SUPPORT, "Requires zlib") - @unittest.skipUnless(UID_GID_SUPPORT, "Requires grp and pwd support") - def test_tarfile_root_owner(self): - tmpdir = self._create_files() - base_name = os.path.join(self.mkdtemp(), 'archive') - old_dir = os.getcwd() - os.chdir(tmpdir) - group = grp.getgrgid(0)[0] - owner = pwd.getpwuid(0)[0] - try: - archive_name = make_tarball(base_name, 'dist', compress=None, - owner=owner, group=group) - finally: - os.chdir(old_dir) - - # check if the compressed tarball was created - self.assertTrue(os.path.exists(archive_name)) - - # now checks the rights - archive = tarfile.open(archive_name) - try: - for member in archive.getmembers(): - self.assertEqual(member.uid, 0) - self.assertEqual(member.gid, 0) - finally: - archive.close() - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(ArchiveUtilTestCase) - -if __name__ == "__main__": - run_unittest(test_suite()) diff --git a/Lib/distutils/tests/test_bdist.py b/Lib/distutils/tests/test_bdist.py deleted file mode 100644 index 241fc9ad..00000000 --- a/Lib/distutils/tests/test_bdist.py +++ /dev/null @@ -1,52 +0,0 @@ -"""Tests for distutils.command.bdist.""" -import os -import unittest -from test.support import run_unittest - -import warnings -with warnings.catch_warnings(): - warnings.simplefilter('ignore', DeprecationWarning) - from distutils.command.bdist import bdist - from distutils.tests import support - - -class BuildTestCase(support.TempdirManager, - unittest.TestCase): - - def test_formats(self): - # let's create a command and make sure - # we can set the format - dist = self.create_dist()[1] - cmd = bdist(dist) - cmd.formats = ['tar'] - cmd.ensure_finalized() - self.assertEqual(cmd.formats, ['tar']) - - # what formats does bdist offer? - formats = ['bztar', 'gztar', 'rpm', 'tar', 'xztar', 'zip', 'ztar'] - found = sorted(cmd.format_command) - self.assertEqual(found, formats) - - def test_skip_build(self): - # bug #10946: bdist --skip-build should trickle down to subcommands - dist = self.create_dist()[1] - cmd = bdist(dist) - cmd.skip_build = 1 - cmd.ensure_finalized() - dist.command_obj['bdist'] = cmd - - for name in ['bdist_dumb']: # bdist_rpm does not support --skip-build - subcmd = cmd.get_finalized_command(name) - if getattr(subcmd, '_unsupported', False): - # command is not supported on this build - continue - self.assertTrue(subcmd.skip_build, - '%s should take --skip-build from bdist' % name) - - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(BuildTestCase) - - -if __name__ == '__main__': - run_unittest(test_suite()) diff --git a/Lib/distutils/tests/test_bdist_dumb.py b/Lib/distutils/tests/test_bdist_dumb.py deleted file mode 100644 index bb860c8a..00000000 --- a/Lib/distutils/tests/test_bdist_dumb.py +++ /dev/null @@ -1,97 +0,0 @@ -"""Tests for distutils.command.bdist_dumb.""" - -import os -import sys -import zipfile -import unittest -from test.support import run_unittest - -from distutils.core import Distribution -from distutils.command.bdist_dumb import bdist_dumb -from distutils.tests import support - -SETUP_PY = """\ -from distutils.core import setup -import foo - -setup(name='foo', version='0.1', py_modules=['foo'], - url='xxx', author='xxx', author_email='xxx') - -""" - -try: - import zlib - ZLIB_SUPPORT = True -except ImportError: - ZLIB_SUPPORT = False - - -class BuildDumbTestCase(support.TempdirManager, - support.LoggingSilencer, - support.EnvironGuard, - unittest.TestCase): - - def setUp(self): - super(BuildDumbTestCase, self).setUp() - self.old_location = os.getcwd() - self.old_sys_argv = sys.argv, sys.argv[:] - - def tearDown(self): - os.chdir(self.old_location) - sys.argv = self.old_sys_argv[0] - sys.argv[:] = self.old_sys_argv[1] - super(BuildDumbTestCase, self).tearDown() - - @unittest.skipUnless(ZLIB_SUPPORT, 'Need zlib support to run') - def test_simple_built(self): - - # let's create a simple package - tmp_dir = self.mkdtemp() - pkg_dir = os.path.join(tmp_dir, 'foo') - os.mkdir(pkg_dir) - self.write_file((pkg_dir, 'setup.py'), SETUP_PY) - self.write_file((pkg_dir, 'foo.py'), '#') - self.write_file((pkg_dir, 'MANIFEST.in'), 'include foo.py') - self.write_file((pkg_dir, 'README'), '') - - dist = Distribution({'name': 'foo', 'version': '0.1', - 'py_modules': ['foo'], - 'url': 'xxx', 'author': 'xxx', - 'author_email': 'xxx'}) - dist.script_name = 'setup.py' - os.chdir(pkg_dir) - - sys.argv = ['setup.py'] - cmd = bdist_dumb(dist) - - # so the output is the same no matter - # what is the platform - cmd.format = 'zip' - - cmd.ensure_finalized() - cmd.run() - - # see what we have - dist_created = os.listdir(os.path.join(pkg_dir, 'dist')) - base = "%s.%s.zip" % (dist.get_fullname(), cmd.plat_name) - - self.assertEqual(dist_created, [base]) - - # now let's check what we have in the zip file - fp = zipfile.ZipFile(os.path.join('dist', base)) - try: - contents = fp.namelist() - finally: - fp.close() - - contents = sorted(filter(None, map(os.path.basename, contents))) - wanted = ['foo-0.1-py%s.%s.egg-info' % sys.version_info[:2], 'foo.py'] - if not sys.dont_write_bytecode: - wanted.append('foo.%s.pyc' % sys.implementation.cache_tag) - self.assertEqual(contents, sorted(wanted)) - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(BuildDumbTestCase) - -if __name__ == '__main__': - run_unittest(test_suite()) diff --git a/Lib/distutils/tests/test_bdist_rpm.py b/Lib/distutils/tests/test_bdist_rpm.py deleted file mode 100644 index 7eefa7b9..00000000 --- a/Lib/distutils/tests/test_bdist_rpm.py +++ /dev/null @@ -1,141 +0,0 @@ -"""Tests for distutils.command.bdist_rpm.""" - -import unittest -import sys -import os -from test.support import run_unittest, requires_zlib - -from distutils.core import Distribution -from distutils.command.bdist_rpm import bdist_rpm -from distutils.tests import support -from distutils.spawn import find_executable - -SETUP_PY = """\ -from distutils.core import setup -import foo - -setup(name='foo', version='0.1', py_modules=['foo'], - url='xxx', author='xxx', author_email='xxx') - -""" - -class BuildRpmTestCase(support.TempdirManager, - support.EnvironGuard, - support.LoggingSilencer, - unittest.TestCase): - - def setUp(self): - try: - sys.executable.encode("UTF-8") - except UnicodeEncodeError: - raise unittest.SkipTest("sys.executable is not encodable to UTF-8") - - super(BuildRpmTestCase, self).setUp() - self.old_location = os.getcwd() - self.old_sys_argv = sys.argv, sys.argv[:] - - def tearDown(self): - os.chdir(self.old_location) - sys.argv = self.old_sys_argv[0] - sys.argv[:] = self.old_sys_argv[1] - super(BuildRpmTestCase, self).tearDown() - - # XXX I am unable yet to make this test work without - # spurious sdtout/stderr output under Mac OS X - @unittest.skipUnless(sys.platform.startswith('linux'), - 'spurious sdtout/stderr output under Mac OS X') - @requires_zlib() - @unittest.skipIf(find_executable('rpm') is None, - 'the rpm command is not found') - @unittest.skipIf(find_executable('rpmbuild') is None, - 'the rpmbuild command is not found') - # import foo fails with safe path - @unittest.skipIf(sys.flags.safe_path, - 'PYTHONSAFEPATH changes default sys.path') - def test_quiet(self): - # let's create a package - tmp_dir = self.mkdtemp() - os.environ['HOME'] = tmp_dir # to confine dir '.rpmdb' creation - pkg_dir = os.path.join(tmp_dir, 'foo') - os.mkdir(pkg_dir) - self.write_file((pkg_dir, 'setup.py'), SETUP_PY) - self.write_file((pkg_dir, 'foo.py'), '#') - self.write_file((pkg_dir, 'MANIFEST.in'), 'include foo.py') - self.write_file((pkg_dir, 'README'), '') - - dist = Distribution({'name': 'foo', 'version': '0.1', - 'py_modules': ['foo'], - 'url': 'xxx', 'author': 'xxx', - 'author_email': 'xxx'}) - dist.script_name = 'setup.py' - os.chdir(pkg_dir) - - sys.argv = ['setup.py'] - cmd = bdist_rpm(dist) - cmd.fix_python = True - - # running in quiet mode - cmd.quiet = 1 - cmd.ensure_finalized() - cmd.run() - - dist_created = os.listdir(os.path.join(pkg_dir, 'dist')) - self.assertIn('foo-0.1-1.noarch.rpm', dist_created) - - # bug #2945: upload ignores bdist_rpm files - self.assertIn(('bdist_rpm', 'any', 'dist/foo-0.1-1.src.rpm'), dist.dist_files) - self.assertIn(('bdist_rpm', 'any', 'dist/foo-0.1-1.noarch.rpm'), dist.dist_files) - - # XXX I am unable yet to make this test work without - # spurious sdtout/stderr output under Mac OS X - @unittest.skipUnless(sys.platform.startswith('linux'), - 'spurious sdtout/stderr output under Mac OS X') - @requires_zlib() - # http://bugs.python.org/issue1533164 - @unittest.skipIf(find_executable('rpm') is None, - 'the rpm command is not found') - @unittest.skipIf(find_executable('rpmbuild') is None, - 'the rpmbuild command is not found') - # import foo fails with safe path - @unittest.skipIf(sys.flags.safe_path, - 'PYTHONSAFEPATH changes default sys.path') - def test_no_optimize_flag(self): - # let's create a package that breaks bdist_rpm - tmp_dir = self.mkdtemp() - os.environ['HOME'] = tmp_dir # to confine dir '.rpmdb' creation - pkg_dir = os.path.join(tmp_dir, 'foo') - os.mkdir(pkg_dir) - self.write_file((pkg_dir, 'setup.py'), SETUP_PY) - self.write_file((pkg_dir, 'foo.py'), '#') - self.write_file((pkg_dir, 'MANIFEST.in'), 'include foo.py') - self.write_file((pkg_dir, 'README'), '') - - dist = Distribution({'name': 'foo', 'version': '0.1', - 'py_modules': ['foo'], - 'url': 'xxx', 'author': 'xxx', - 'author_email': 'xxx'}) - dist.script_name = 'setup.py' - os.chdir(pkg_dir) - - sys.argv = ['setup.py'] - cmd = bdist_rpm(dist) - cmd.fix_python = True - - cmd.quiet = 1 - cmd.ensure_finalized() - cmd.run() - - dist_created = os.listdir(os.path.join(pkg_dir, 'dist')) - self.assertIn('foo-0.1-1.noarch.rpm', dist_created) - - # bug #2945: upload ignores bdist_rpm files - self.assertIn(('bdist_rpm', 'any', 'dist/foo-0.1-1.src.rpm'), dist.dist_files) - self.assertIn(('bdist_rpm', 'any', 'dist/foo-0.1-1.noarch.rpm'), dist.dist_files) - - os.remove(os.path.join(pkg_dir, 'dist', 'foo-0.1-1.noarch.rpm')) - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(BuildRpmTestCase) - -if __name__ == '__main__': - run_unittest(test_suite()) diff --git a/Lib/distutils/tests/test_build.py b/Lib/distutils/tests/test_build.py deleted file mode 100644 index 71b5e164..00000000 --- a/Lib/distutils/tests/test_build.py +++ /dev/null @@ -1,57 +0,0 @@ -"""Tests for distutils.command.build.""" -import unittest -import os -import sys -from test.support import run_unittest - -from distutils.command.build import build -from distutils.tests import support -from sysconfig import get_platform - -class BuildTestCase(support.TempdirManager, - support.LoggingSilencer, - unittest.TestCase): - - @unittest.skipUnless(sys.executable, "test requires sys.executable") - def test_finalize_options(self): - pkg_dir, dist = self.create_dist() - cmd = build(dist) - cmd.finalize_options() - - # if not specified, plat_name gets the current platform - self.assertEqual(cmd.plat_name, get_platform()) - - # build_purelib is build + lib - wanted = os.path.join(cmd.build_base, 'lib') - self.assertEqual(cmd.build_purelib, wanted) - - # build_platlib is 'build/lib.platform-x.x[-pydebug]' - # examples: - # build/lib.macosx-10.3-i386-2.7 - plat_spec = '.%s-%d.%d' % (cmd.plat_name, *sys.version_info[:2]) - if hasattr(sys, 'gettotalrefcount'): - self.assertTrue(cmd.build_platlib.endswith('-pydebug')) - plat_spec += '-pydebug' - wanted = os.path.join(cmd.build_base, 'lib' + plat_spec) - self.assertEqual(cmd.build_platlib, wanted) - - # by default, build_lib = build_purelib - self.assertEqual(cmd.build_lib, cmd.build_purelib) - - # build_temp is build/temp.<plat> - wanted = os.path.join(cmd.build_base, 'temp' + plat_spec) - self.assertEqual(cmd.build_temp, wanted) - - # build_scripts is build/scripts-x.x - wanted = os.path.join(cmd.build_base, - 'scripts-%d.%d' % sys.version_info[:2]) - self.assertEqual(cmd.build_scripts, wanted) - - # executable is os.path.normpath(sys.executable) - self.assertEqual(cmd.executable, os.path.normpath(sys.executable)) - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(BuildTestCase) - -if __name__ == "__main__": - run_unittest(test_suite()) diff --git a/Lib/distutils/tests/test_build_clib.py b/Lib/distutils/tests/test_build_clib.py deleted file mode 100644 index 95f92828..00000000 --- a/Lib/distutils/tests/test_build_clib.py +++ /dev/null @@ -1,147 +0,0 @@ -"""Tests for distutils.command.build_clib.""" -import unittest -import os -import sys -import sysconfig - -from test.support import ( - run_unittest, missing_compiler_executable, requires_subprocess -) - -from distutils.command.build_clib import build_clib -from distutils.errors import DistutilsSetupError -from distutils.tests import support - -class BuildCLibTestCase(support.TempdirManager, - support.LoggingSilencer, - unittest.TestCase): - - def setUp(self): - super().setUp() - self._backup_CONFIG_VARS = dict(sysconfig._CONFIG_VARS) - - def tearDown(self): - super().tearDown() - sysconfig._CONFIG_VARS.clear() - sysconfig._CONFIG_VARS.update(self._backup_CONFIG_VARS) - - def test_check_library_dist(self): - pkg_dir, dist = self.create_dist() - cmd = build_clib(dist) - - # 'libraries' option must be a list - self.assertRaises(DistutilsSetupError, cmd.check_library_list, 'foo') - - # each element of 'libraries' must a 2-tuple - self.assertRaises(DistutilsSetupError, cmd.check_library_list, - ['foo1', 'foo2']) - - # first element of each tuple in 'libraries' - # must be a string (the library name) - self.assertRaises(DistutilsSetupError, cmd.check_library_list, - [(1, 'foo1'), ('name', 'foo2')]) - - # library name may not contain directory separators - self.assertRaises(DistutilsSetupError, cmd.check_library_list, - [('name', 'foo1'), - ('another/name', 'foo2')]) - - # second element of each tuple must be a dictionary (build info) - self.assertRaises(DistutilsSetupError, cmd.check_library_list, - [('name', {}), - ('another', 'foo2')]) - - # those work - libs = [('name', {}), ('name', {'ok': 'good'})] - cmd.check_library_list(libs) - - def test_get_source_files(self): - pkg_dir, dist = self.create_dist() - cmd = build_clib(dist) - - # "in 'libraries' option 'sources' must be present and must be - # a list of source filenames - cmd.libraries = [('name', {})] - self.assertRaises(DistutilsSetupError, cmd.get_source_files) - - cmd.libraries = [('name', {'sources': 1})] - self.assertRaises(DistutilsSetupError, cmd.get_source_files) - - cmd.libraries = [('name', {'sources': ['a', 'b']})] - self.assertEqual(cmd.get_source_files(), ['a', 'b']) - - cmd.libraries = [('name', {'sources': ('a', 'b')})] - self.assertEqual(cmd.get_source_files(), ['a', 'b']) - - cmd.libraries = [('name', {'sources': ('a', 'b')}), - ('name2', {'sources': ['c', 'd']})] - self.assertEqual(cmd.get_source_files(), ['a', 'b', 'c', 'd']) - - def test_build_libraries(self): - - pkg_dir, dist = self.create_dist() - cmd = build_clib(dist) - class FakeCompiler: - def compile(*args, **kw): - pass - create_static_lib = compile - - cmd.compiler = FakeCompiler() - - # build_libraries is also doing a bit of typo checking - lib = [('name', {'sources': 'notvalid'})] - self.assertRaises(DistutilsSetupError, cmd.build_libraries, lib) - - lib = [('name', {'sources': list()})] - cmd.build_libraries(lib) - - lib = [('name', {'sources': tuple()})] - cmd.build_libraries(lib) - - def test_finalize_options(self): - pkg_dir, dist = self.create_dist() - cmd = build_clib(dist) - - cmd.include_dirs = 'one-dir' - cmd.finalize_options() - self.assertEqual(cmd.include_dirs, ['one-dir']) - - cmd.include_dirs = None - cmd.finalize_options() - self.assertEqual(cmd.include_dirs, []) - - cmd.distribution.libraries = 'WONTWORK' - self.assertRaises(DistutilsSetupError, cmd.finalize_options) - - @unittest.skipIf(sys.platform == 'win32', "can't test on Windows") - @requires_subprocess() - def test_run(self): - pkg_dir, dist = self.create_dist() - cmd = build_clib(dist) - - foo_c = os.path.join(pkg_dir, 'foo.c') - self.write_file(foo_c, 'int main(void) { return 1;}\n') - cmd.libraries = [('foo', {'sources': [foo_c]})] - - build_temp = os.path.join(pkg_dir, 'build') - os.mkdir(build_temp) - cmd.build_temp = build_temp - cmd.build_clib = build_temp - - # Before we run the command, we want to make sure - # all commands are present on the system. - ccmd = missing_compiler_executable() - if ccmd is not None: - self.skipTest('The %r command is not found' % ccmd) - - # this should work - cmd.run() - - # let's check the result - self.assertIn('libfoo.a', os.listdir(build_temp)) - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(BuildCLibTestCase) - -if __name__ == "__main__": - run_unittest(test_suite()) diff --git a/Lib/distutils/tests/test_build_ext.py b/Lib/distutils/tests/test_build_ext.py deleted file mode 100644 index 4ebeafec..00000000 --- a/Lib/distutils/tests/test_build_ext.py +++ /dev/null @@ -1,555 +0,0 @@ -import sys -import os -from io import StringIO -import textwrap - -from distutils.core import Distribution -from distutils.command.build_ext import build_ext -from distutils import sysconfig -from distutils.tests.support import (TempdirManager, LoggingSilencer, - copy_xxmodule_c, fixup_build_ext) -from distutils.extension import Extension -from distutils.errors import ( - CompileError, DistutilsPlatformError, DistutilsSetupError, - UnknownFileError) - -import unittest -from test import support -from test.support import os_helper -from test.support.script_helper import assert_python_ok -from test.support import threading_helper - -# http://bugs.python.org/issue4373 -# Don't load the xx module more than once. -ALREADY_TESTED = False - - -class BuildExtTestCase(TempdirManager, - LoggingSilencer, - unittest.TestCase): - def setUp(self): - # Create a simple test environment - super(BuildExtTestCase, self).setUp() - self.tmp_dir = self.mkdtemp() - import site - self.old_user_base = site.USER_BASE - site.USER_BASE = self.mkdtemp() - from distutils.command import build_ext - build_ext.USER_BASE = site.USER_BASE - self.old_config_vars = dict(sysconfig._config_vars) - - # bpo-30132: On Windows, a .pdb file may be created in the current - # working directory. Create a temporary working directory to cleanup - # everything at the end of the test. - self.enterContext(os_helper.change_cwd(self.tmp_dir)) - - def tearDown(self): - import site - site.USER_BASE = self.old_user_base - from distutils.command import build_ext - build_ext.USER_BASE = self.old_user_base - sysconfig._config_vars.clear() - sysconfig._config_vars.update(self.old_config_vars) - super(BuildExtTestCase, self).tearDown() - - def build_ext(self, *args, **kwargs): - return build_ext(*args, **kwargs) - - @support.requires_subprocess() - def test_build_ext(self): - cmd = support.missing_compiler_executable() - if cmd is not None: - self.skipTest('The %r command is not found' % cmd) - global ALREADY_TESTED - copy_xxmodule_c(self.tmp_dir) - xx_c = os.path.join(self.tmp_dir, 'xxmodule.c') - xx_ext = Extension('xx', [xx_c]) - dist = Distribution({'name': 'xx', 'ext_modules': [xx_ext]}) - dist.package_dir = self.tmp_dir - cmd = self.build_ext(dist) - fixup_build_ext(cmd) - cmd.build_lib = self.tmp_dir - cmd.build_temp = self.tmp_dir - - old_stdout = sys.stdout - if not support.verbose: - # silence compiler output - sys.stdout = StringIO() - try: - cmd.ensure_finalized() - cmd.run() - finally: - sys.stdout = old_stdout - - if ALREADY_TESTED: - self.skipTest('Already tested in %s' % ALREADY_TESTED) - else: - ALREADY_TESTED = type(self).__name__ - - code = textwrap.dedent(f""" - tmp_dir = {self.tmp_dir!r} - - import sys - import unittest - from test import support - - sys.path.insert(0, tmp_dir) - import xx - - class Tests(unittest.TestCase): - def test_xx(self): - for attr in ('error', 'foo', 'new', 'roj'): - self.assertTrue(hasattr(xx, attr)) - - self.assertEqual(xx.foo(2, 5), 7) - self.assertEqual(xx.foo(13,15), 28) - self.assertEqual(xx.new().demo(), None) - if support.HAVE_DOCSTRINGS: - doc = 'This is a template module just for instruction.' - self.assertEqual(xx.__doc__, doc) - self.assertIsInstance(xx.Null(), xx.Null) - self.assertIsInstance(xx.Str(), xx.Str) - - - unittest.main() - """) - assert_python_ok('-c', code) - - def test_solaris_enable_shared(self): - dist = Distribution({'name': 'xx'}) - cmd = self.build_ext(dist) - old = sys.platform - - sys.platform = 'sunos' # fooling finalize_options - from distutils.sysconfig import _config_vars - old_var = _config_vars.get('Py_ENABLE_SHARED') - _config_vars['Py_ENABLE_SHARED'] = 1 - try: - cmd.ensure_finalized() - finally: - sys.platform = old - if old_var is None: - del _config_vars['Py_ENABLE_SHARED'] - else: - _config_vars['Py_ENABLE_SHARED'] = old_var - - # make sure we get some library dirs under solaris - self.assertGreater(len(cmd.library_dirs), 0) - - def test_user_site(self): - import site - dist = Distribution({'name': 'xx'}) - cmd = self.build_ext(dist) - - # making sure the user option is there - options = [name for name, short, lable in - cmd.user_options] - self.assertIn('user', options) - - # setting a value - cmd.user = 1 - - # setting user based lib and include - lib = os.path.join(site.USER_BASE, 'lib') - incl = os.path.join(site.USER_BASE, 'include') - os.mkdir(lib) - os.mkdir(incl) - - # let's run finalize - cmd.ensure_finalized() - - # see if include_dirs and library_dirs - # were set - self.assertIn(lib, cmd.library_dirs) - self.assertIn(lib, cmd.rpath) - self.assertIn(incl, cmd.include_dirs) - - @threading_helper.requires_working_threading() - def test_optional_extension(self): - - # this extension will fail, but let's ignore this failure - # with the optional argument. - modules = [Extension('foo', ['xxx'], optional=False)] - dist = Distribution({'name': 'xx', 'ext_modules': modules}) - cmd = self.build_ext(dist) - cmd.ensure_finalized() - self.assertRaises((UnknownFileError, CompileError), - cmd.run) # should raise an error - - modules = [Extension('foo', ['xxx'], optional=True)] - dist = Distribution({'name': 'xx', 'ext_modules': modules}) - cmd = self.build_ext(dist) - cmd.ensure_finalized() - cmd.run() # should pass - - def test_finalize_options(self): - # Make sure Python's include directories (for Python.h, pyconfig.h, - # etc.) are in the include search path. - modules = [Extension('foo', ['xxx'], optional=False)] - dist = Distribution({'name': 'xx', 'ext_modules': modules}) - cmd = self.build_ext(dist) - cmd.finalize_options() - - py_include = sysconfig.get_python_inc() - for p in py_include.split(os.path.pathsep): - self.assertIn(p, cmd.include_dirs) - - plat_py_include = sysconfig.get_python_inc(plat_specific=1) - for p in plat_py_include.split(os.path.pathsep): - self.assertIn(p, cmd.include_dirs) - - # make sure cmd.libraries is turned into a list - # if it's a string - cmd = self.build_ext(dist) - cmd.libraries = 'my_lib, other_lib lastlib' - cmd.finalize_options() - self.assertEqual(cmd.libraries, ['my_lib', 'other_lib', 'lastlib']) - - # make sure cmd.library_dirs is turned into a list - # if it's a string - cmd = self.build_ext(dist) - cmd.library_dirs = 'my_lib_dir%sother_lib_dir' % os.pathsep - cmd.finalize_options() - self.assertIn('my_lib_dir', cmd.library_dirs) - self.assertIn('other_lib_dir', cmd.library_dirs) - - # make sure rpath is turned into a list - # if it's a string - cmd = self.build_ext(dist) - cmd.rpath = 'one%stwo' % os.pathsep - cmd.finalize_options() - self.assertEqual(cmd.rpath, ['one', 'two']) - - # make sure cmd.link_objects is turned into a list - # if it's a string - cmd = build_ext(dist) - cmd.link_objects = 'one two,three' - cmd.finalize_options() - self.assertEqual(cmd.link_objects, ['one', 'two', 'three']) - - # XXX more tests to perform for win32 - - # make sure define is turned into 2-tuples - # strings if they are ','-separated strings - cmd = self.build_ext(dist) - cmd.define = 'one,two' - cmd.finalize_options() - self.assertEqual(cmd.define, [('one', '1'), ('two', '1')]) - - # make sure undef is turned into a list of - # strings if they are ','-separated strings - cmd = self.build_ext(dist) - cmd.undef = 'one,two' - cmd.finalize_options() - self.assertEqual(cmd.undef, ['one', 'two']) - - # make sure swig_opts is turned into a list - cmd = self.build_ext(dist) - cmd.swig_opts = None - cmd.finalize_options() - self.assertEqual(cmd.swig_opts, []) - - cmd = self.build_ext(dist) - cmd.swig_opts = '1 2' - cmd.finalize_options() - self.assertEqual(cmd.swig_opts, ['1', '2']) - - def test_check_extensions_list(self): - dist = Distribution() - cmd = self.build_ext(dist) - cmd.finalize_options() - - #'extensions' option must be a list of Extension instances - self.assertRaises(DistutilsSetupError, - cmd.check_extensions_list, 'foo') - - # each element of 'ext_modules' option must be an - # Extension instance or 2-tuple - exts = [('bar', 'foo', 'bar'), 'foo'] - self.assertRaises(DistutilsSetupError, cmd.check_extensions_list, exts) - - # first element of each tuple in 'ext_modules' - # must be the extension name (a string) and match - # a python dotted-separated name - exts = [('foo-bar', '')] - self.assertRaises(DistutilsSetupError, cmd.check_extensions_list, exts) - - # second element of each tuple in 'ext_modules' - # must be a dictionary (build info) - exts = [('foo.bar', '')] - self.assertRaises(DistutilsSetupError, cmd.check_extensions_list, exts) - - # ok this one should pass - exts = [('foo.bar', {'sources': [''], 'libraries': 'foo', - 'some': 'bar'})] - cmd.check_extensions_list(exts) - ext = exts[0] - self.assertIsInstance(ext, Extension) - - # check_extensions_list adds in ext the values passed - # when they are in ('include_dirs', 'library_dirs', 'libraries' - # 'extra_objects', 'extra_compile_args', 'extra_link_args') - self.assertEqual(ext.libraries, 'foo') - self.assertFalse(hasattr(ext, 'some')) - - # 'macros' element of build info dict must be 1- or 2-tuple - exts = [('foo.bar', {'sources': [''], 'libraries': 'foo', - 'some': 'bar', 'macros': [('1', '2', '3'), 'foo']})] - self.assertRaises(DistutilsSetupError, cmd.check_extensions_list, exts) - - exts[0][1]['macros'] = [('1', '2'), ('3',)] - cmd.check_extensions_list(exts) - self.assertEqual(exts[0].undef_macros, ['3']) - self.assertEqual(exts[0].define_macros, [('1', '2')]) - - def test_get_source_files(self): - modules = [Extension('foo', ['xxx'], optional=False)] - dist = Distribution({'name': 'xx', 'ext_modules': modules}) - cmd = self.build_ext(dist) - cmd.ensure_finalized() - self.assertEqual(cmd.get_source_files(), ['xxx']) - - def test_unicode_module_names(self): - modules = [ - Extension('foo', ['aaa'], optional=False), - Extension('föö', ['uuu'], optional=False), - ] - dist = Distribution({'name': 'xx', 'ext_modules': modules}) - cmd = self.build_ext(dist) - cmd.ensure_finalized() - self.assertRegex(cmd.get_ext_filename(modules[0].name), r'foo(_d)?\..*') - self.assertRegex(cmd.get_ext_filename(modules[1].name), r'föö(_d)?\..*') - self.assertEqual(cmd.get_export_symbols(modules[0]), ['PyInit_foo']) - self.assertEqual(cmd.get_export_symbols(modules[1]), ['PyInitU_f_gkaa']) - - def test_compiler_option(self): - # cmd.compiler is an option and - # should not be overridden by a compiler instance - # when the command is run - dist = Distribution() - cmd = self.build_ext(dist) - cmd.compiler = 'unix' - cmd.ensure_finalized() - cmd.run() - self.assertEqual(cmd.compiler, 'unix') - - @support.requires_subprocess() - def test_get_outputs(self): - cmd = support.missing_compiler_executable() - if cmd is not None: - self.skipTest('The %r command is not found' % cmd) - tmp_dir = self.mkdtemp() - c_file = os.path.join(tmp_dir, 'foo.c') - self.write_file(c_file, 'void PyInit_foo(void) {}\n') - ext = Extension('foo', [c_file], optional=False) - dist = Distribution({'name': 'xx', - 'ext_modules': [ext]}) - cmd = self.build_ext(dist) - fixup_build_ext(cmd) - cmd.ensure_finalized() - self.assertEqual(len(cmd.get_outputs()), 1) - - cmd.build_lib = os.path.join(self.tmp_dir, 'build') - cmd.build_temp = os.path.join(self.tmp_dir, 'tempt') - - # issue #5977 : distutils build_ext.get_outputs - # returns wrong result with --inplace - other_tmp_dir = os.path.realpath(self.mkdtemp()) - old_wd = os.getcwd() - os.chdir(other_tmp_dir) - try: - cmd.inplace = 1 - cmd.run() - so_file = cmd.get_outputs()[0] - finally: - os.chdir(old_wd) - self.assertTrue(os.path.exists(so_file)) - ext_suffix = sysconfig.get_config_var('EXT_SUFFIX') - self.assertTrue(so_file.endswith(ext_suffix)) - so_dir = os.path.dirname(so_file) - self.assertEqual(so_dir, other_tmp_dir) - - cmd.inplace = 0 - cmd.compiler = None - cmd.run() - so_file = cmd.get_outputs()[0] - self.assertTrue(os.path.exists(so_file)) - self.assertTrue(so_file.endswith(ext_suffix)) - so_dir = os.path.dirname(so_file) - self.assertEqual(so_dir, cmd.build_lib) - - # inplace = 0, cmd.package = 'bar' - build_py = cmd.get_finalized_command('build_py') - build_py.package_dir = {'': 'bar'} - path = cmd.get_ext_fullpath('foo') - # checking that the last directory is the build_dir - path = os.path.split(path)[0] - self.assertEqual(path, cmd.build_lib) - - # inplace = 1, cmd.package = 'bar' - cmd.inplace = 1 - other_tmp_dir = os.path.realpath(self.mkdtemp()) - old_wd = os.getcwd() - os.chdir(other_tmp_dir) - try: - path = cmd.get_ext_fullpath('foo') - finally: - os.chdir(old_wd) - # checking that the last directory is bar - path = os.path.split(path)[0] - lastdir = os.path.split(path)[-1] - self.assertEqual(lastdir, 'bar') - - def test_ext_fullpath(self): - ext = sysconfig.get_config_var('EXT_SUFFIX') - # building lxml.etree inplace - #etree_c = os.path.join(self.tmp_dir, 'lxml.etree.c') - #etree_ext = Extension('lxml.etree', [etree_c]) - #dist = Distribution({'name': 'lxml', 'ext_modules': [etree_ext]}) - dist = Distribution() - cmd = self.build_ext(dist) - cmd.inplace = 1 - cmd.distribution.package_dir = {'': 'src'} - cmd.distribution.packages = ['lxml', 'lxml.html'] - curdir = os.getcwd() - wanted = os.path.join(curdir, 'src', 'lxml', 'etree' + ext) - path = cmd.get_ext_fullpath('lxml.etree') - self.assertEqual(wanted, path) - - # building lxml.etree not inplace - cmd.inplace = 0 - cmd.build_lib = os.path.join(curdir, 'tmpdir') - wanted = os.path.join(curdir, 'tmpdir', 'lxml', 'etree' + ext) - path = cmd.get_ext_fullpath('lxml.etree') - self.assertEqual(wanted, path) - - # building twisted.runner.portmap not inplace - build_py = cmd.get_finalized_command('build_py') - build_py.package_dir = {} - cmd.distribution.packages = ['twisted', 'twisted.runner.portmap'] - path = cmd.get_ext_fullpath('twisted.runner.portmap') - wanted = os.path.join(curdir, 'tmpdir', 'twisted', 'runner', - 'portmap' + ext) - self.assertEqual(wanted, path) - - # building twisted.runner.portmap inplace - cmd.inplace = 1 - path = cmd.get_ext_fullpath('twisted.runner.portmap') - wanted = os.path.join(curdir, 'twisted', 'runner', 'portmap' + ext) - self.assertEqual(wanted, path) - - - @unittest.skipUnless(sys.platform == 'darwin', 'test only relevant for MacOSX') - def test_deployment_target_default(self): - # Issue 9516: Test that, in the absence of the environment variable, - # an extension module is compiled with the same deployment target as - # the interpreter. - self._try_compile_deployment_target('==', None) - - @unittest.skipUnless(sys.platform == 'darwin', 'test only relevant for MacOSX') - def test_deployment_target_too_low(self): - # Issue 9516: Test that an extension module is not allowed to be - # compiled with a deployment target less than that of the interpreter. - self.assertRaises(DistutilsPlatformError, - self._try_compile_deployment_target, '>', '10.1') - - @unittest.skipUnless(sys.platform == 'darwin', 'test only relevant for MacOSX') - def test_deployment_target_higher_ok(self): - # Issue 9516: Test that an extension module can be compiled with a - # deployment target higher than that of the interpreter: the ext - # module may depend on some newer OS feature. - deptarget = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') - if deptarget: - # increment the minor version number (i.e. 10.6 -> 10.7) - deptarget = [int(x) for x in deptarget.split('.')] - deptarget[-1] += 1 - deptarget = '.'.join(str(i) for i in deptarget) - self._try_compile_deployment_target('<', deptarget) - - def _try_compile_deployment_target(self, operator, target): - orig_environ = os.environ - os.environ = orig_environ.copy() - self.addCleanup(setattr, os, 'environ', orig_environ) - - if target is None: - if os.environ.get('MACOSX_DEPLOYMENT_TARGET'): - del os.environ['MACOSX_DEPLOYMENT_TARGET'] - else: - os.environ['MACOSX_DEPLOYMENT_TARGET'] = target - - deptarget_c = os.path.join(self.tmp_dir, 'deptargetmodule.c') - - with open(deptarget_c, 'w') as fp: - fp.write(textwrap.dedent('''\ - #include <AvailabilityMacros.h> - - int dummy; - - #if TARGET %s MAC_OS_X_VERSION_MIN_REQUIRED - #else - #error "Unexpected target" - #endif - - ''' % operator)) - - # get the deployment target that the interpreter was built with - target = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') - target = tuple(map(int, target.split('.')[0:2])) - # format the target value as defined in the Apple - # Availability Macros. We can't use the macro names since - # at least one value we test with will not exist yet. - if target[:2] < (10, 10): - # for 10.1 through 10.9.x -> "10n0" - target = '%02d%01d0' % target - else: - # for 10.10 and beyond -> "10nn00" - if len(target) >= 2: - target = '%02d%02d00' % target - else: - # 11 and later can have no minor version (11 instead of 11.0) - target = '%02d0000' % target - deptarget_ext = Extension( - 'deptarget', - [deptarget_c], - extra_compile_args=['-DTARGET=%s'%(target,)], - ) - dist = Distribution({ - 'name': 'deptarget', - 'ext_modules': [deptarget_ext] - }) - dist.package_dir = self.tmp_dir - cmd = self.build_ext(dist) - cmd.build_lib = self.tmp_dir - cmd.build_temp = self.tmp_dir - - try: - old_stdout = sys.stdout - if not support.verbose: - # silence compiler output - sys.stdout = StringIO() - try: - cmd.ensure_finalized() - cmd.run() - finally: - sys.stdout = old_stdout - - except CompileError: - self.fail("Wrong deployment target during compilation") - - -class ParallelBuildExtTestCase(BuildExtTestCase): - - def build_ext(self, *args, **kwargs): - build_ext = super().build_ext(*args, **kwargs) - build_ext.parallel = True - return build_ext - - -def test_suite(): - suite = unittest.TestSuite() - suite.addTest(unittest.TestLoader().loadTestsFromTestCase(BuildExtTestCase)) - suite.addTest(unittest.TestLoader().loadTestsFromTestCase(ParallelBuildExtTestCase)) - return suite - -if __name__ == '__main__': - support.run_unittest(__name__) diff --git a/Lib/distutils/tests/test_build_py.py b/Lib/distutils/tests/test_build_py.py deleted file mode 100644 index 44a06cc9..00000000 --- a/Lib/distutils/tests/test_build_py.py +++ /dev/null @@ -1,181 +0,0 @@ -"""Tests for distutils.command.build_py.""" - -import os -import sys -import unittest - -from distutils.command.build_py import build_py -from distutils.core import Distribution -from distutils.errors import DistutilsFileError - -from distutils.tests import support -from test.support import run_unittest, requires_subprocess - - -class BuildPyTestCase(support.TempdirManager, - support.LoggingSilencer, - unittest.TestCase): - - def test_package_data(self): - sources = self.mkdtemp() - f = open(os.path.join(sources, "__init__.py"), "w") - try: - f.write("# Pretend this is a package.") - finally: - f.close() - f = open(os.path.join(sources, "README.txt"), "w") - try: - f.write("Info about this package") - finally: - f.close() - - destination = self.mkdtemp() - - dist = Distribution({"packages": ["pkg"], - "package_dir": {"pkg": sources}}) - # script_name need not exist, it just need to be initialized - dist.script_name = os.path.join(sources, "setup.py") - dist.command_obj["build"] = support.DummyCommand( - force=0, - build_lib=destination) - dist.packages = ["pkg"] - dist.package_data = {"pkg": ["README.txt"]} - dist.package_dir = {"pkg": sources} - - cmd = build_py(dist) - cmd.compile = 1 - cmd.ensure_finalized() - self.assertEqual(cmd.package_data, dist.package_data) - - cmd.run() - - # This makes sure the list of outputs includes byte-compiled - # files for Python modules but not for package data files - # (there shouldn't *be* byte-code files for those!). - self.assertEqual(len(cmd.get_outputs()), 3) - pkgdest = os.path.join(destination, "pkg") - files = os.listdir(pkgdest) - pycache_dir = os.path.join(pkgdest, "__pycache__") - self.assertIn("__init__.py", files) - self.assertIn("README.txt", files) - if sys.dont_write_bytecode: - self.assertFalse(os.path.exists(pycache_dir)) - else: - pyc_files = os.listdir(pycache_dir) - self.assertIn("__init__.%s.pyc" % sys.implementation.cache_tag, - pyc_files) - - def test_empty_package_dir(self): - # See bugs #1668596/#1720897 - sources = self.mkdtemp() - open(os.path.join(sources, "__init__.py"), "w").close() - - testdir = os.path.join(sources, "doc") - os.mkdir(testdir) - open(os.path.join(testdir, "testfile"), "w").close() - - os.chdir(sources) - dist = Distribution({"packages": ["pkg"], - "package_dir": {"pkg": ""}, - "package_data": {"pkg": ["doc/*"]}}) - # script_name need not exist, it just need to be initialized - dist.script_name = os.path.join(sources, "setup.py") - dist.script_args = ["build"] - dist.parse_command_line() - - try: - dist.run_commands() - except DistutilsFileError: - self.fail("failed package_data test when package_dir is ''") - - @unittest.skipIf(sys.dont_write_bytecode, 'byte-compile disabled') - @requires_subprocess() - def test_byte_compile(self): - project_dir, dist = self.create_dist(py_modules=['boiledeggs']) - os.chdir(project_dir) - self.write_file('boiledeggs.py', 'import antigravity') - cmd = build_py(dist) - cmd.compile = 1 - cmd.build_lib = 'here' - cmd.finalize_options() - cmd.run() - - found = os.listdir(cmd.build_lib) - self.assertEqual(sorted(found), ['__pycache__', 'boiledeggs.py']) - found = os.listdir(os.path.join(cmd.build_lib, '__pycache__')) - self.assertEqual(found, - ['boiledeggs.%s.pyc' % sys.implementation.cache_tag]) - - @unittest.skipIf(sys.dont_write_bytecode, 'byte-compile disabled') - @requires_subprocess() - def test_byte_compile_optimized(self): - project_dir, dist = self.create_dist(py_modules=['boiledeggs']) - os.chdir(project_dir) - self.write_file('boiledeggs.py', 'import antigravity') - cmd = build_py(dist) - cmd.compile = 0 - cmd.optimize = 1 - cmd.build_lib = 'here' - cmd.finalize_options() - cmd.run() - - found = os.listdir(cmd.build_lib) - self.assertEqual(sorted(found), ['__pycache__', 'boiledeggs.py']) - found = os.listdir(os.path.join(cmd.build_lib, '__pycache__')) - expect = 'boiledeggs.{}.opt-1.pyc'.format(sys.implementation.cache_tag) - self.assertEqual(sorted(found), [expect]) - - def test_dir_in_package_data(self): - """ - A directory in package_data should not be added to the filelist. - """ - # See bug 19286 - sources = self.mkdtemp() - pkg_dir = os.path.join(sources, "pkg") - - os.mkdir(pkg_dir) - open(os.path.join(pkg_dir, "__init__.py"), "w").close() - - docdir = os.path.join(pkg_dir, "doc") - os.mkdir(docdir) - open(os.path.join(docdir, "testfile"), "w").close() - - # create the directory that could be incorrectly detected as a file - os.mkdir(os.path.join(docdir, 'otherdir')) - - os.chdir(sources) - dist = Distribution({"packages": ["pkg"], - "package_data": {"pkg": ["doc/*"]}}) - # script_name need not exist, it just need to be initialized - dist.script_name = os.path.join(sources, "setup.py") - dist.script_args = ["build"] - dist.parse_command_line() - - try: - dist.run_commands() - except DistutilsFileError: - self.fail("failed package_data when data dir includes a dir") - - def test_dont_write_bytecode(self): - # makes sure byte_compile is not used - dist = self.create_dist()[1] - cmd = build_py(dist) - cmd.compile = 1 - cmd.optimize = 1 - - old_dont_write_bytecode = sys.dont_write_bytecode - sys.dont_write_bytecode = True - try: - cmd.byte_compile([]) - finally: - sys.dont_write_bytecode = old_dont_write_bytecode - - self.assertIn('byte-compiling is disabled', - self.logs[0][1] % self.logs[0][2]) - - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(BuildPyTestCase) - -if __name__ == "__main__": - run_unittest(test_suite()) diff --git a/Lib/distutils/tests/test_build_scripts.py b/Lib/distutils/tests/test_build_scripts.py deleted file mode 100644 index f299e51e..00000000 --- a/Lib/distutils/tests/test_build_scripts.py +++ /dev/null @@ -1,112 +0,0 @@ -"""Tests for distutils.command.build_scripts.""" - -import os -import unittest - -from distutils.command.build_scripts import build_scripts -from distutils.core import Distribution -from distutils import sysconfig - -from distutils.tests import support -from test.support import run_unittest - - -class BuildScriptsTestCase(support.TempdirManager, - support.LoggingSilencer, - unittest.TestCase): - - def test_default_settings(self): - cmd = self.get_build_scripts_cmd("/foo/bar", []) - self.assertFalse(cmd.force) - self.assertIsNone(cmd.build_dir) - - cmd.finalize_options() - - self.assertTrue(cmd.force) - self.assertEqual(cmd.build_dir, "/foo/bar") - - def test_build(self): - source = self.mkdtemp() - target = self.mkdtemp() - expected = self.write_sample_scripts(source) - - cmd = self.get_build_scripts_cmd(target, - [os.path.join(source, fn) - for fn in expected]) - cmd.finalize_options() - cmd.run() - - built = os.listdir(target) - for name in expected: - self.assertIn(name, built) - - def get_build_scripts_cmd(self, target, scripts): - import sys - dist = Distribution() - dist.scripts = scripts - dist.command_obj["build"] = support.DummyCommand( - build_scripts=target, - force=1, - executable=sys.executable - ) - return build_scripts(dist) - - def write_sample_scripts(self, dir): - expected = [] - expected.append("script1.py") - self.write_script(dir, "script1.py", - ("#! /usr/bin/env python2.3\n" - "# bogus script w/ Python sh-bang\n" - "pass\n")) - expected.append("script2.py") - self.write_script(dir, "script2.py", - ("#!/usr/bin/python\n" - "# bogus script w/ Python sh-bang\n" - "pass\n")) - expected.append("shell.sh") - self.write_script(dir, "shell.sh", - ("#!/bin/sh\n" - "# bogus shell script w/ sh-bang\n" - "exit 0\n")) - return expected - - def write_script(self, dir, name, text): - f = open(os.path.join(dir, name), "w") - try: - f.write(text) - finally: - f.close() - - def test_version_int(self): - source = self.mkdtemp() - target = self.mkdtemp() - expected = self.write_sample_scripts(source) - - - cmd = self.get_build_scripts_cmd(target, - [os.path.join(source, fn) - for fn in expected]) - cmd.finalize_options() - - # http://bugs.python.org/issue4524 - # - # On linux-g++-32 with command line `./configure --enable-ipv6 - # --with-suffix=3`, python is compiled okay but the build scripts - # failed when writing the name of the executable - old = sysconfig.get_config_vars().get('VERSION') - sysconfig._config_vars['VERSION'] = 4 - try: - cmd.run() - finally: - if old is not None: - sysconfig._config_vars['VERSION'] = old - - built = os.listdir(target) - for name in expected: - self.assertIn(name, built) - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(BuildScriptsTestCase) - -if __name__ == "__main__": - run_unittest(test_suite()) diff --git a/Lib/distutils/tests/test_check.py b/Lib/distutils/tests/test_check.py deleted file mode 100644 index 91bcdceb..00000000 --- a/Lib/distutils/tests/test_check.py +++ /dev/null @@ -1,163 +0,0 @@ -"""Tests for distutils.command.check.""" -import os -import textwrap -import unittest -from test.support import run_unittest - -from distutils.command.check import check, HAS_DOCUTILS -from distutils.tests import support -from distutils.errors import DistutilsSetupError - -try: - import pygments -except ImportError: - pygments = None - - -HERE = os.path.dirname(__file__) - - -class CheckTestCase(support.LoggingSilencer, - support.TempdirManager, - unittest.TestCase): - - def _run(self, metadata=None, cwd=None, **options): - if metadata is None: - metadata = {} - if cwd is not None: - old_dir = os.getcwd() - os.chdir(cwd) - pkg_info, dist = self.create_dist(**metadata) - cmd = check(dist) - cmd.initialize_options() - for name, value in options.items(): - setattr(cmd, name, value) - cmd.ensure_finalized() - cmd.run() - if cwd is not None: - os.chdir(old_dir) - return cmd - - def test_check_metadata(self): - # let's run the command with no metadata at all - # by default, check is checking the metadata - # should have some warnings - cmd = self._run() - self.assertEqual(cmd._warnings, 2) - - # now let's add the required fields - # and run it again, to make sure we don't get - # any warning anymore - metadata = {'url': 'xxx', 'author': 'xxx', - 'author_email': 'xxx', - 'name': 'xxx', 'version': 'xxx'} - cmd = self._run(metadata) - self.assertEqual(cmd._warnings, 0) - - # now with the strict mode, we should - # get an error if there are missing metadata - self.assertRaises(DistutilsSetupError, self._run, {}, **{'strict': 1}) - - # and of course, no error when all metadata are present - cmd = self._run(metadata, strict=1) - self.assertEqual(cmd._warnings, 0) - - # now a test with non-ASCII characters - metadata = {'url': 'xxx', 'author': '\u00c9ric', - 'author_email': 'xxx', 'name': 'xxx', - 'version': 'xxx', - 'description': 'Something about esszet \u00df', - 'long_description': 'More things about esszet \u00df'} - cmd = self._run(metadata) - self.assertEqual(cmd._warnings, 0) - - @unittest.skipUnless(HAS_DOCUTILS, "won't test without docutils") - def test_check_document(self): - pkg_info, dist = self.create_dist() - cmd = check(dist) - - # let's see if it detects broken rest - broken_rest = 'title\n===\n\ntest' - msgs = cmd._check_rst_data(broken_rest) - self.assertEqual(len(msgs), 1) - - # and non-broken rest - rest = 'title\n=====\n\ntest' - msgs = cmd._check_rst_data(rest) - self.assertEqual(len(msgs), 0) - - @unittest.skipUnless(HAS_DOCUTILS, "won't test without docutils") - def test_check_restructuredtext(self): - # let's see if it detects broken rest in long_description - broken_rest = 'title\n===\n\ntest' - pkg_info, dist = self.create_dist(long_description=broken_rest) - cmd = check(dist) - cmd.check_restructuredtext() - self.assertEqual(cmd._warnings, 1) - - # let's see if we have an error with strict=1 - metadata = {'url': 'xxx', 'author': 'xxx', - 'author_email': 'xxx', - 'name': 'xxx', 'version': 'xxx', - 'long_description': broken_rest} - self.assertRaises(DistutilsSetupError, self._run, metadata, - **{'strict': 1, 'restructuredtext': 1}) - - # and non-broken rest, including a non-ASCII character to test #12114 - metadata['long_description'] = 'title\n=====\n\ntest \u00df' - cmd = self._run(metadata, strict=1, restructuredtext=1) - self.assertEqual(cmd._warnings, 0) - - # check that includes work to test #31292 - metadata['long_description'] = 'title\n=====\n\n.. include:: includetest.rst' - cmd = self._run(metadata, cwd=HERE, strict=1, restructuredtext=1) - self.assertEqual(cmd._warnings, 0) - - @unittest.skipUnless(HAS_DOCUTILS, "won't test without docutils") - def test_check_restructuredtext_with_syntax_highlight(self): - # Don't fail if there is a `code` or `code-block` directive - - example_rst_docs = [] - example_rst_docs.append(textwrap.dedent("""\ - Here's some code: - - .. code:: python - - def foo(): - pass - """)) - example_rst_docs.append(textwrap.dedent("""\ - Here's some code: - - .. code-block:: python - - def foo(): - pass - """)) - - for rest_with_code in example_rst_docs: - pkg_info, dist = self.create_dist(long_description=rest_with_code) - cmd = check(dist) - cmd.check_restructuredtext() - msgs = cmd._check_rst_data(rest_with_code) - if pygments is not None: - self.assertEqual(len(msgs), 0) - else: - self.assertEqual(len(msgs), 1) - self.assertEqual( - str(msgs[0][1]), - 'Cannot analyze code. Pygments package not found.' - ) - - def test_check_all(self): - - metadata = {'url': 'xxx', 'author': 'xxx'} - self.assertRaises(DistutilsSetupError, self._run, - {}, **{'strict': 1, - 'restructuredtext': 1}) - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(CheckTestCase) - -if __name__ == "__main__": - run_unittest(test_suite()) diff --git a/Lib/distutils/tests/test_clean.py b/Lib/distutils/tests/test_clean.py deleted file mode 100644 index 92367499..00000000 --- a/Lib/distutils/tests/test_clean.py +++ /dev/null @@ -1,49 +0,0 @@ -"""Tests for distutils.command.clean.""" -import os -import unittest - -from distutils.command.clean import clean -from distutils.tests import support -from test.support import run_unittest - -class cleanTestCase(support.TempdirManager, - support.LoggingSilencer, - unittest.TestCase): - - def test_simple_run(self): - pkg_dir, dist = self.create_dist() - cmd = clean(dist) - - # let's add some elements clean should remove - dirs = [(d, os.path.join(pkg_dir, d)) - for d in ('build_temp', 'build_lib', 'bdist_base', - 'build_scripts', 'build_base')] - - for name, path in dirs: - os.mkdir(path) - setattr(cmd, name, path) - if name == 'build_base': - continue - for f in ('one', 'two', 'three'): - self.write_file(os.path.join(path, f)) - - # let's run the command - cmd.all = 1 - cmd.ensure_finalized() - cmd.run() - - # make sure the files where removed - for name, path in dirs: - self.assertFalse(os.path.exists(path), - '%s was not removed' % path) - - # let's run the command again (should spit warnings but succeed) - cmd.all = 1 - cmd.ensure_finalized() - cmd.run() - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(cleanTestCase) - -if __name__ == "__main__": - run_unittest(test_suite()) diff --git a/Lib/distutils/tests/test_cmd.py b/Lib/distutils/tests/test_cmd.py deleted file mode 100644 index 2319214a..00000000 --- a/Lib/distutils/tests/test_cmd.py +++ /dev/null @@ -1,126 +0,0 @@ -"""Tests for distutils.cmd.""" -import unittest -import os -from test.support import captured_stdout, run_unittest - -from distutils.cmd import Command -from distutils.dist import Distribution -from distutils.errors import DistutilsOptionError -from distutils import debug - -class MyCmd(Command): - def initialize_options(self): - pass - -class CommandTestCase(unittest.TestCase): - - def setUp(self): - dist = Distribution() - self.cmd = MyCmd(dist) - - def test_ensure_string_list(self): - - cmd = self.cmd - cmd.not_string_list = ['one', 2, 'three'] - cmd.yes_string_list = ['one', 'two', 'three'] - cmd.not_string_list2 = object() - cmd.yes_string_list2 = 'ok' - cmd.ensure_string_list('yes_string_list') - cmd.ensure_string_list('yes_string_list2') - - self.assertRaises(DistutilsOptionError, - cmd.ensure_string_list, 'not_string_list') - - self.assertRaises(DistutilsOptionError, - cmd.ensure_string_list, 'not_string_list2') - - cmd.option1 = 'ok,dok' - cmd.ensure_string_list('option1') - self.assertEqual(cmd.option1, ['ok', 'dok']) - - cmd.option2 = ['xxx', 'www'] - cmd.ensure_string_list('option2') - - cmd.option3 = ['ok', 2] - self.assertRaises(DistutilsOptionError, cmd.ensure_string_list, - 'option3') - - - def test_make_file(self): - - cmd = self.cmd - - # making sure it raises when infiles is not a string or a list/tuple - self.assertRaises(TypeError, cmd.make_file, - infiles=1, outfile='', func='func', args=()) - - # making sure execute gets called properly - def _execute(func, args, exec_msg, level): - self.assertEqual(exec_msg, 'generating out from in') - cmd.force = True - cmd.execute = _execute - cmd.make_file(infiles='in', outfile='out', func='func', args=()) - - def test_dump_options(self): - - msgs = [] - def _announce(msg, level): - msgs.append(msg) - cmd = self.cmd - cmd.announce = _announce - cmd.option1 = 1 - cmd.option2 = 1 - cmd.user_options = [('option1', '', ''), ('option2', '', '')] - cmd.dump_options() - - wanted = ["command options for 'MyCmd':", ' option1 = 1', - ' option2 = 1'] - self.assertEqual(msgs, wanted) - - def test_ensure_string(self): - cmd = self.cmd - cmd.option1 = 'ok' - cmd.ensure_string('option1') - - cmd.option2 = None - cmd.ensure_string('option2', 'xxx') - self.assertTrue(hasattr(cmd, 'option2')) - - cmd.option3 = 1 - self.assertRaises(DistutilsOptionError, cmd.ensure_string, 'option3') - - def test_ensure_filename(self): - cmd = self.cmd - cmd.option1 = __file__ - cmd.ensure_filename('option1') - cmd.option2 = 'xxx' - self.assertRaises(DistutilsOptionError, cmd.ensure_filename, 'option2') - - def test_ensure_dirname(self): - cmd = self.cmd - cmd.option1 = os.path.dirname(__file__) or os.curdir - cmd.ensure_dirname('option1') - cmd.option2 = 'xxx' - self.assertRaises(DistutilsOptionError, cmd.ensure_dirname, 'option2') - - def test_debug_print(self): - cmd = self.cmd - with captured_stdout() as stdout: - cmd.debug_print('xxx') - stdout.seek(0) - self.assertEqual(stdout.read(), '') - - debug.DEBUG = True - try: - with captured_stdout() as stdout: - cmd.debug_print('xxx') - stdout.seek(0) - self.assertEqual(stdout.read(), 'xxx\n') - finally: - debug.DEBUG = False - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(CommandTestCase) - -if __name__ == '__main__': - run_unittest(test_suite()) diff --git a/Lib/distutils/tests/test_config.py b/Lib/distutils/tests/test_config.py deleted file mode 100644 index 8ab70efb..00000000 --- a/Lib/distutils/tests/test_config.py +++ /dev/null @@ -1,141 +0,0 @@ -"""Tests for distutils.pypirc.pypirc.""" -import os -import unittest - -from distutils.core import PyPIRCCommand -from distutils.core import Distribution -from distutils.log import set_threshold -from distutils.log import WARN - -from distutils.tests import support -from test.support import run_unittest - -PYPIRC = """\ -[distutils] - -index-servers = - server1 - server2 - server3 - -[server1] -username:me -password:secret - -[server2] -username:meagain -password: secret -realm:acme -repository:http://another.pypi/ - -[server3] -username:cbiggles -password:yh^%#rest-of-my-password -""" - -PYPIRC_OLD = """\ -[server-login] -username:tarek -password:secret -""" - -WANTED = """\ -[distutils] -index-servers = - pypi - -[pypi] -username:tarek -password:xxx -""" - - -class BasePyPIRCCommandTestCase(support.TempdirManager, - support.LoggingSilencer, - support.EnvironGuard, - unittest.TestCase): - - def setUp(self): - """Patches the environment.""" - super(BasePyPIRCCommandTestCase, self).setUp() - self.tmp_dir = self.mkdtemp() - os.environ['HOME'] = self.tmp_dir - os.environ['USERPROFILE'] = self.tmp_dir - self.rc = os.path.join(self.tmp_dir, '.pypirc') - self.dist = Distribution() - - class command(PyPIRCCommand): - def __init__(self, dist): - PyPIRCCommand.__init__(self, dist) - def initialize_options(self): - pass - finalize_options = initialize_options - - self._cmd = command - self.old_threshold = set_threshold(WARN) - - def tearDown(self): - """Removes the patch.""" - set_threshold(self.old_threshold) - super(BasePyPIRCCommandTestCase, self).tearDown() - - -class PyPIRCCommandTestCase(BasePyPIRCCommandTestCase): - - def test_server_registration(self): - # This test makes sure PyPIRCCommand knows how to: - # 1. handle several sections in .pypirc - # 2. handle the old format - - # new format - self.write_file(self.rc, PYPIRC) - cmd = self._cmd(self.dist) - config = cmd._read_pypirc() - - config = list(sorted(config.items())) - waited = [('password', 'secret'), ('realm', 'pypi'), - ('repository', 'https://upload.pypi.org/legacy/'), - ('server', 'server1'), ('username', 'me')] - self.assertEqual(config, waited) - - # old format - self.write_file(self.rc, PYPIRC_OLD) - config = cmd._read_pypirc() - config = list(sorted(config.items())) - waited = [('password', 'secret'), ('realm', 'pypi'), - ('repository', 'https://upload.pypi.org/legacy/'), - ('server', 'server-login'), ('username', 'tarek')] - self.assertEqual(config, waited) - - def test_server_empty_registration(self): - cmd = self._cmd(self.dist) - rc = cmd._get_rc_file() - self.assertFalse(os.path.exists(rc)) - cmd._store_pypirc('tarek', 'xxx') - self.assertTrue(os.path.exists(rc)) - f = open(rc) - try: - content = f.read() - self.assertEqual(content, WANTED) - finally: - f.close() - - def test_config_interpolation(self): - # using the % character in .pypirc should not raise an error (#20120) - self.write_file(self.rc, PYPIRC) - cmd = self._cmd(self.dist) - cmd.repository = 'server3' - config = cmd._read_pypirc() - - config = list(sorted(config.items())) - waited = [('password', 'yh^%#rest-of-my-password'), ('realm', 'pypi'), - ('repository', 'https://upload.pypi.org/legacy/'), - ('server', 'server3'), ('username', 'cbiggles')] - self.assertEqual(config, waited) - - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(PyPIRCCommandTestCase) - -if __name__ == "__main__": - run_unittest(test_suite()) diff --git a/Lib/distutils/tests/test_config_cmd.py b/Lib/distutils/tests/test_config_cmd.py deleted file mode 100644 index c79db68a..00000000 --- a/Lib/distutils/tests/test_config_cmd.py +++ /dev/null @@ -1,103 +0,0 @@ -"""Tests for distutils.command.config.""" -import unittest -import os -import sys -import sysconfig -from test.support import ( - run_unittest, missing_compiler_executable, requires_subprocess -) - -from distutils.command.config import dump_file, config -from distutils.tests import support -from distutils import log - -class ConfigTestCase(support.LoggingSilencer, - support.TempdirManager, - unittest.TestCase): - - def _info(self, msg, *args): - for line in msg.splitlines(): - self._logs.append(line) - - def setUp(self): - super(ConfigTestCase, self).setUp() - self._logs = [] - self.old_log = log.info - log.info = self._info - self.old_config_vars = dict(sysconfig._CONFIG_VARS) - - def tearDown(self): - log.info = self.old_log - sysconfig._CONFIG_VARS.clear() - sysconfig._CONFIG_VARS.update(self.old_config_vars) - super(ConfigTestCase, self).tearDown() - - def test_dump_file(self): - this_file = os.path.splitext(__file__)[0] + '.py' - f = open(this_file) - try: - numlines = len(f.readlines()) - finally: - f.close() - - dump_file(this_file, 'I am the header') - self.assertEqual(len(self._logs), numlines+1) - - @unittest.skipIf(sys.platform == 'win32', "can't test on Windows") - @requires_subprocess() - def test_search_cpp(self): - cmd = missing_compiler_executable(['preprocessor']) - if cmd is not None: - self.skipTest('The %r command is not found' % cmd) - pkg_dir, dist = self.create_dist() - cmd = config(dist) - cmd._check_compiler() - compiler = cmd.compiler - if sys.platform[:3] == "aix" and "xlc" in compiler.preprocessor[0].lower(): - self.skipTest('xlc: The -E option overrides the -P, -o, and -qsyntaxonly options') - - # simple pattern searches - match = cmd.search_cpp(pattern='xxx', body='/* xxx */') - self.assertEqual(match, 0) - - match = cmd.search_cpp(pattern='_configtest', body='/* xxx */') - self.assertEqual(match, 1) - - def test_finalize_options(self): - # finalize_options does a bit of transformation - # on options - pkg_dir, dist = self.create_dist() - cmd = config(dist) - cmd.include_dirs = 'one%stwo' % os.pathsep - cmd.libraries = 'one' - cmd.library_dirs = 'three%sfour' % os.pathsep - cmd.ensure_finalized() - - self.assertEqual(cmd.include_dirs, ['one', 'two']) - self.assertEqual(cmd.libraries, ['one']) - self.assertEqual(cmd.library_dirs, ['three', 'four']) - - def test_clean(self): - # _clean removes files - tmp_dir = self.mkdtemp() - f1 = os.path.join(tmp_dir, 'one') - f2 = os.path.join(tmp_dir, 'two') - - self.write_file(f1, 'xxx') - self.write_file(f2, 'xxx') - - for f in (f1, f2): - self.assertTrue(os.path.exists(f)) - - pkg_dir, dist = self.create_dist() - cmd = config(dist) - cmd._clean(f1, f2) - - for f in (f1, f2): - self.assertFalse(os.path.exists(f)) - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(ConfigTestCase) - -if __name__ == "__main__": - run_unittest(test_suite()) diff --git a/Lib/distutils/tests/test_core.py b/Lib/distutils/tests/test_core.py deleted file mode 100644 index 700a22da..00000000 --- a/Lib/distutils/tests/test_core.py +++ /dev/null @@ -1,140 +0,0 @@ -"""Tests for distutils.core.""" - -import io -import distutils.core -import os -import shutil -import sys -from test.support import captured_stdout, run_unittest -from test.support import os_helper -import unittest -from distutils.tests import support -from distutils import log - -# setup script that uses __file__ -setup_using___file__ = """\ - -__file__ - -from distutils.core import setup -setup() -""" - -setup_prints_cwd = """\ - -import os -print(os.getcwd()) - -from distutils.core import setup -setup() -""" - -setup_does_nothing = """\ -from distutils.core import setup -setup() -""" - - -setup_defines_subclass = """\ -from distutils.core import setup -from distutils.command.install import install as _install - -class install(_install): - sub_commands = _install.sub_commands + ['cmd'] - -setup(cmdclass={'install': install}) -""" - -class CoreTestCase(support.EnvironGuard, unittest.TestCase): - - def setUp(self): - super(CoreTestCase, self).setUp() - self.old_stdout = sys.stdout - self.cleanup_testfn() - self.old_argv = sys.argv, sys.argv[:] - self.addCleanup(log.set_threshold, log._global_log.threshold) - - def tearDown(self): - sys.stdout = self.old_stdout - self.cleanup_testfn() - sys.argv = self.old_argv[0] - sys.argv[:] = self.old_argv[1] - super(CoreTestCase, self).tearDown() - - def cleanup_testfn(self): - path = os_helper.TESTFN - if os.path.isfile(path): - os.remove(path) - elif os.path.isdir(path): - shutil.rmtree(path) - - def write_setup(self, text, path=os_helper.TESTFN): - f = open(path, "w") - try: - f.write(text) - finally: - f.close() - return path - - def test_run_setup_provides_file(self): - # Make sure the script can use __file__; if that's missing, the test - # setup.py script will raise NameError. - distutils.core.run_setup( - self.write_setup(setup_using___file__)) - - def test_run_setup_preserves_sys_argv(self): - # Make sure run_setup does not clobber sys.argv - argv_copy = sys.argv.copy() - distutils.core.run_setup( - self.write_setup(setup_does_nothing)) - self.assertEqual(sys.argv, argv_copy) - - def test_run_setup_defines_subclass(self): - # Make sure the script can use __file__; if that's missing, the test - # setup.py script will raise NameError. - dist = distutils.core.run_setup( - self.write_setup(setup_defines_subclass)) - install = dist.get_command_obj('install') - self.assertIn('cmd', install.sub_commands) - - def test_run_setup_uses_current_dir(self): - # This tests that the setup script is run with the current directory - # as its own current directory; this was temporarily broken by a - # previous patch when TESTFN did not use the current directory. - sys.stdout = io.StringIO() - cwd = os.getcwd() - - # Create a directory and write the setup.py file there: - os.mkdir(os_helper.TESTFN) - setup_py = os.path.join(os_helper.TESTFN, "setup.py") - distutils.core.run_setup( - self.write_setup(setup_prints_cwd, path=setup_py)) - - output = sys.stdout.getvalue() - if output.endswith("\n"): - output = output[:-1] - self.assertEqual(cwd, output) - - def test_debug_mode(self): - # this covers the code called when DEBUG is set - sys.argv = ['setup.py', '--name'] - with captured_stdout() as stdout: - distutils.core.setup(name='bar') - stdout.seek(0) - self.assertEqual(stdout.read(), 'bar\n') - - distutils.core.DEBUG = True - try: - with captured_stdout() as stdout: - distutils.core.setup(name='bar') - finally: - distutils.core.DEBUG = False - stdout.seek(0) - wanted = "options (after parsing config files):\n" - self.assertEqual(stdout.readlines()[0], wanted) - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(CoreTestCase) - -if __name__ == "__main__": - run_unittest(test_suite()) diff --git a/Lib/distutils/tests/test_cygwinccompiler.py b/Lib/distutils/tests/test_cygwinccompiler.py deleted file mode 100644 index 0912ffd1..00000000 --- a/Lib/distutils/tests/test_cygwinccompiler.py +++ /dev/null @@ -1,154 +0,0 @@ -"""Tests for distutils.cygwinccompiler.""" -import unittest -import sys -import os -from io import BytesIO -from test.support import run_unittest - -from distutils import cygwinccompiler -from distutils.cygwinccompiler import (check_config_h, - CONFIG_H_OK, CONFIG_H_NOTOK, - CONFIG_H_UNCERTAIN, get_versions, - get_msvcr) -from distutils.tests import support - -class FakePopen(object): - test_class = None - - def __init__(self, cmd, shell, stdout): - self.cmd = cmd.split()[0] - exes = self.test_class._exes - if self.cmd in exes: - # issue #6438 in Python 3.x, Popen returns bytes - self.stdout = BytesIO(exes[self.cmd]) - else: - self.stdout = os.popen(cmd, 'r') - - -class CygwinCCompilerTestCase(support.TempdirManager, - unittest.TestCase): - - def setUp(self): - super(CygwinCCompilerTestCase, self).setUp() - self.version = sys.version - self.python_h = os.path.join(self.mkdtemp(), 'python.h') - from distutils import sysconfig - self.old_get_config_h_filename = sysconfig.get_config_h_filename - sysconfig.get_config_h_filename = self._get_config_h_filename - self.old_find_executable = cygwinccompiler.find_executable - cygwinccompiler.find_executable = self._find_executable - self._exes = {} - self.old_popen = cygwinccompiler.Popen - FakePopen.test_class = self - cygwinccompiler.Popen = FakePopen - - def tearDown(self): - sys.version = self.version - from distutils import sysconfig - sysconfig.get_config_h_filename = self.old_get_config_h_filename - cygwinccompiler.find_executable = self.old_find_executable - cygwinccompiler.Popen = self.old_popen - super(CygwinCCompilerTestCase, self).tearDown() - - def _get_config_h_filename(self): - return self.python_h - - def _find_executable(self, name): - if name in self._exes: - return name - return None - - def test_check_config_h(self): - - # check_config_h looks for "GCC" in sys.version first - # returns CONFIG_H_OK if found - sys.version = ('2.6.1 (r261:67515, Dec 6 2008, 16:42:21) \n[GCC ' - '4.0.1 (Apple Computer, Inc. build 5370)]') - - self.assertEqual(check_config_h()[0], CONFIG_H_OK) - - # then it tries to see if it can find "__GNUC__" in pyconfig.h - sys.version = 'something without the *CC word' - - # if the file doesn't exist it returns CONFIG_H_UNCERTAIN - self.assertEqual(check_config_h()[0], CONFIG_H_UNCERTAIN) - - # if it exists but does not contain __GNUC__, it returns CONFIG_H_NOTOK - self.write_file(self.python_h, 'xxx') - self.assertEqual(check_config_h()[0], CONFIG_H_NOTOK) - - # and CONFIG_H_OK if __GNUC__ is found - self.write_file(self.python_h, 'xxx __GNUC__ xxx') - self.assertEqual(check_config_h()[0], CONFIG_H_OK) - - def test_get_versions(self): - - # get_versions calls distutils.spawn.find_executable on - # 'gcc', 'ld' and 'dllwrap' - self.assertEqual(get_versions(), (None, None, None)) - - # Let's fake we have 'gcc' and it returns '3.4.5' - self._exes['gcc'] = b'gcc (GCC) 3.4.5 (mingw special)\nFSF' - res = get_versions() - self.assertEqual(str(res[0]), '3.4.5') - - # and let's see what happens when the version - # doesn't match the regular expression - # (\d+\.\d+(\.\d+)*) - self._exes['gcc'] = b'very strange output' - res = get_versions() - self.assertEqual(res[0], None) - - # same thing for ld - self._exes['ld'] = b'GNU ld version 2.17.50 20060824' - res = get_versions() - self.assertEqual(str(res[1]), '2.17.50') - self._exes['ld'] = b'@(#)PROGRAM:ld PROJECT:ld64-77' - res = get_versions() - self.assertEqual(res[1], None) - - # and dllwrap - self._exes['dllwrap'] = b'GNU dllwrap 2.17.50 20060824\nFSF' - res = get_versions() - self.assertEqual(str(res[2]), '2.17.50') - self._exes['dllwrap'] = b'Cheese Wrap' - res = get_versions() - self.assertEqual(res[2], None) - - def test_get_msvcr(self): - - # none - sys.version = ('2.6.1 (r261:67515, Dec 6 2008, 16:42:21) ' - '\n[GCC 4.0.1 (Apple Computer, Inc. build 5370)]') - self.assertEqual(get_msvcr(), None) - - # MSVC 7.0 - sys.version = ('2.5.1 (r251:54863, Apr 18 2007, 08:51:08) ' - '[MSC v.1300 32 bits (Intel)]') - self.assertEqual(get_msvcr(), ['msvcr70']) - - # MSVC 7.1 - sys.version = ('2.5.1 (r251:54863, Apr 18 2007, 08:51:08) ' - '[MSC v.1310 32 bits (Intel)]') - self.assertEqual(get_msvcr(), ['msvcr71']) - - # VS2005 / MSVC 8.0 - sys.version = ('2.5.1 (r251:54863, Apr 18 2007, 08:51:08) ' - '[MSC v.1400 32 bits (Intel)]') - self.assertEqual(get_msvcr(), ['msvcr80']) - - # VS2008 / MSVC 9.0 - sys.version = ('2.5.1 (r251:54863, Apr 18 2007, 08:51:08) ' - '[MSC v.1500 32 bits (Intel)]') - self.assertEqual(get_msvcr(), ['msvcr90']) - - # unknown - sys.version = ('2.5.1 (r251:54863, Apr 18 2007, 08:51:08) ' - '[MSC v.1999 32 bits (Intel)]') - self.assertRaises(ValueError, get_msvcr) - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(CygwinCCompilerTestCase) - -if __name__ == '__main__': - run_unittest(test_suite()) diff --git a/Lib/distutils/tests/test_dep_util.py b/Lib/distutils/tests/test_dep_util.py deleted file mode 100644 index 0d52740a..00000000 --- a/Lib/distutils/tests/test_dep_util.py +++ /dev/null @@ -1,80 +0,0 @@ -"""Tests for distutils.dep_util.""" -import unittest -import os - -from distutils.dep_util import newer, newer_pairwise, newer_group -from distutils.errors import DistutilsFileError -from distutils.tests import support -from test.support import run_unittest - -class DepUtilTestCase(support.TempdirManager, unittest.TestCase): - - def test_newer(self): - - tmpdir = self.mkdtemp() - new_file = os.path.join(tmpdir, 'new') - old_file = os.path.abspath(__file__) - - # Raise DistutilsFileError if 'new_file' does not exist. - self.assertRaises(DistutilsFileError, newer, new_file, old_file) - - # Return true if 'new_file' exists and is more recently modified than - # 'old_file', or if 'new_file' exists and 'old_file' doesn't. - self.write_file(new_file) - self.assertTrue(newer(new_file, 'I_dont_exist')) - self.assertTrue(newer(new_file, old_file)) - - # Return false if both exist and 'old_file' is the same age or younger - # than 'new_file'. - self.assertFalse(newer(old_file, new_file)) - - def test_newer_pairwise(self): - tmpdir = self.mkdtemp() - sources = os.path.join(tmpdir, 'sources') - targets = os.path.join(tmpdir, 'targets') - os.mkdir(sources) - os.mkdir(targets) - one = os.path.join(sources, 'one') - two = os.path.join(sources, 'two') - three = os.path.abspath(__file__) # I am the old file - four = os.path.join(targets, 'four') - self.write_file(one) - self.write_file(two) - self.write_file(four) - - self.assertEqual(newer_pairwise([one, two], [three, four]), - ([one],[three])) - - def test_newer_group(self): - tmpdir = self.mkdtemp() - sources = os.path.join(tmpdir, 'sources') - os.mkdir(sources) - one = os.path.join(sources, 'one') - two = os.path.join(sources, 'two') - three = os.path.join(sources, 'three') - old_file = os.path.abspath(__file__) - - # return true if 'old_file' is out-of-date with respect to any file - # listed in 'sources'. - self.write_file(one) - self.write_file(two) - self.write_file(three) - self.assertTrue(newer_group([one, two, three], old_file)) - self.assertFalse(newer_group([one, two, old_file], three)) - - # missing handling - os.remove(one) - self.assertRaises(OSError, newer_group, [one, two, old_file], three) - - self.assertFalse(newer_group([one, two, old_file], three, - missing='ignore')) - - self.assertTrue(newer_group([one, two, old_file], three, - missing='newer')) - - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(DepUtilTestCase) - -if __name__ == "__main__": - run_unittest(test_suite()) diff --git a/Lib/distutils/tests/test_dir_util.py b/Lib/distutils/tests/test_dir_util.py deleted file mode 100644 index ebd89f32..00000000 --- a/Lib/distutils/tests/test_dir_util.py +++ /dev/null @@ -1,143 +0,0 @@ -"""Tests for distutils.dir_util.""" -import unittest -import os -import stat -import sys -from unittest.mock import patch - -from distutils import dir_util, errors -from distutils.dir_util import (mkpath, remove_tree, create_tree, copy_tree, - ensure_relative) - -from distutils import log -from distutils.tests import support -from test.support import run_unittest, is_emscripten, is_wasi - - -class DirUtilTestCase(support.TempdirManager, unittest.TestCase): - - def _log(self, msg, *args): - if len(args) > 0: - self._logs.append(msg % args) - else: - self._logs.append(msg) - - def setUp(self): - super(DirUtilTestCase, self).setUp() - self._logs = [] - tmp_dir = self.mkdtemp() - self.root_target = os.path.join(tmp_dir, 'deep') - self.target = os.path.join(self.root_target, 'here') - self.target2 = os.path.join(tmp_dir, 'deep2') - self.old_log = log.info - log.info = self._log - - def tearDown(self): - log.info = self.old_log - super(DirUtilTestCase, self).tearDown() - - def test_mkpath_remove_tree_verbosity(self): - - mkpath(self.target, verbose=0) - wanted = [] - self.assertEqual(self._logs, wanted) - remove_tree(self.root_target, verbose=0) - - mkpath(self.target, verbose=1) - wanted = ['creating %s' % self.root_target, - 'creating %s' % self.target] - self.assertEqual(self._logs, wanted) - self._logs = [] - - remove_tree(self.root_target, verbose=1) - wanted = ["removing '%s' (and everything under it)" % self.root_target] - self.assertEqual(self._logs, wanted) - - @unittest.skipIf(sys.platform.startswith('win'), - "This test is only appropriate for POSIX-like systems.") - @unittest.skipIf( - is_emscripten or is_wasi, - "Emscripten's/WASI's umask is a stub." - ) - def test_mkpath_with_custom_mode(self): - # Get and set the current umask value for testing mode bits. - umask = os.umask(0o002) - os.umask(umask) - mkpath(self.target, 0o700) - self.assertEqual( - stat.S_IMODE(os.stat(self.target).st_mode), 0o700 & ~umask) - mkpath(self.target2, 0o555) - self.assertEqual( - stat.S_IMODE(os.stat(self.target2).st_mode), 0o555 & ~umask) - - def test_create_tree_verbosity(self): - - create_tree(self.root_target, ['one', 'two', 'three'], verbose=0) - self.assertEqual(self._logs, []) - remove_tree(self.root_target, verbose=0) - - wanted = ['creating %s' % self.root_target] - create_tree(self.root_target, ['one', 'two', 'three'], verbose=1) - self.assertEqual(self._logs, wanted) - - remove_tree(self.root_target, verbose=0) - - def test_copy_tree_verbosity(self): - - mkpath(self.target, verbose=0) - - copy_tree(self.target, self.target2, verbose=0) - self.assertEqual(self._logs, []) - - remove_tree(self.root_target, verbose=0) - - mkpath(self.target, verbose=0) - a_file = os.path.join(self.target, 'ok.txt') - with open(a_file, 'w') as f: - f.write('some content') - - wanted = ['copying %s -> %s' % (a_file, self.target2)] - copy_tree(self.target, self.target2, verbose=1) - self.assertEqual(self._logs, wanted) - - remove_tree(self.root_target, verbose=0) - remove_tree(self.target2, verbose=0) - - def test_copy_tree_skips_nfs_temp_files(self): - mkpath(self.target, verbose=0) - - a_file = os.path.join(self.target, 'ok.txt') - nfs_file = os.path.join(self.target, '.nfs123abc') - for f in a_file, nfs_file: - with open(f, 'w') as fh: - fh.write('some content') - - copy_tree(self.target, self.target2) - self.assertEqual(os.listdir(self.target2), ['ok.txt']) - - remove_tree(self.root_target, verbose=0) - remove_tree(self.target2, verbose=0) - - def test_ensure_relative(self): - if os.sep == '/': - self.assertEqual(ensure_relative('/home/foo'), 'home/foo') - self.assertEqual(ensure_relative('some/path'), 'some/path') - else: # \\ - self.assertEqual(ensure_relative('c:\\home\\foo'), 'c:home\\foo') - self.assertEqual(ensure_relative('home\\foo'), 'home\\foo') - - def test_copy_tree_exception_in_listdir(self): - """ - An exception in listdir should raise a DistutilsFileError - """ - with patch("os.listdir", side_effect=OSError()), \ - self.assertRaises(errors.DistutilsFileError): - src = self.tempdirs[-1] - dir_util.copy_tree(src, None) - - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(DirUtilTestCase) - -if __name__ == "__main__": - run_unittest(test_suite()) diff --git a/Lib/distutils/tests/test_dist.py b/Lib/distutils/tests/test_dist.py deleted file mode 100644 index 2ef70d98..00000000 --- a/Lib/distutils/tests/test_dist.py +++ /dev/null @@ -1,529 +0,0 @@ -"""Tests for distutils.dist.""" -import os -import io -import sys -import unittest -import warnings -import textwrap - -from unittest import mock - -from distutils.dist import Distribution, fix_help_options -from distutils.cmd import Command - -from test.support import ( - captured_stdout, captured_stderr, run_unittest -) -from test.support.os_helper import TESTFN -from distutils.tests import support -from distutils import log - - -class test_dist(Command): - """Sample distutils extension command.""" - - user_options = [ - ("sample-option=", "S", "help text"), - ] - - def initialize_options(self): - self.sample_option = None - - -class TestDistribution(Distribution): - """Distribution subclasses that avoids the default search for - configuration files. - - The ._config_files attribute must be set before - .parse_config_files() is called. - """ - - def find_config_files(self): - return self._config_files - - -class DistributionTestCase(support.LoggingSilencer, - support.TempdirManager, - support.EnvironGuard, - unittest.TestCase): - - def setUp(self): - super(DistributionTestCase, self).setUp() - self.argv = sys.argv, sys.argv[:] - del sys.argv[1:] - - def tearDown(self): - sys.argv = self.argv[0] - sys.argv[:] = self.argv[1] - super(DistributionTestCase, self).tearDown() - - def create_distribution(self, configfiles=()): - d = TestDistribution() - d._config_files = configfiles - d.parse_config_files() - d.parse_command_line() - return d - - def test_command_packages_unspecified(self): - sys.argv.append("build") - d = self.create_distribution() - self.assertEqual(d.get_command_packages(), ["distutils.command"]) - - def test_command_packages_cmdline(self): - from distutils.tests.test_dist import test_dist - sys.argv.extend(["--command-packages", - "foo.bar,distutils.tests", - "test_dist", - "-Ssometext", - ]) - d = self.create_distribution() - # let's actually try to load our test command: - self.assertEqual(d.get_command_packages(), - ["distutils.command", "foo.bar", "distutils.tests"]) - cmd = d.get_command_obj("test_dist") - self.assertIsInstance(cmd, test_dist) - self.assertEqual(cmd.sample_option, "sometext") - - def test_venv_install_options(self): - sys.argv.append("install") - self.addCleanup(os.unlink, TESTFN) - - fakepath = '/somedir' - - with open(TESTFN, "w") as f: - print(("[install]\n" - "install-base = {0}\n" - "install-platbase = {0}\n" - "install-lib = {0}\n" - "install-platlib = {0}\n" - "install-purelib = {0}\n" - "install-headers = {0}\n" - "install-scripts = {0}\n" - "install-data = {0}\n" - "prefix = {0}\n" - "exec-prefix = {0}\n" - "home = {0}\n" - "user = {0}\n" - "root = {0}").format(fakepath), file=f) - - # Base case: Not in a Virtual Environment - with mock.patch.multiple(sys, prefix='/a', base_prefix='/a') as values: - d = self.create_distribution([TESTFN]) - - option_tuple = (TESTFN, fakepath) - - result_dict = { - 'install_base': option_tuple, - 'install_platbase': option_tuple, - 'install_lib': option_tuple, - 'install_platlib': option_tuple, - 'install_purelib': option_tuple, - 'install_headers': option_tuple, - 'install_scripts': option_tuple, - 'install_data': option_tuple, - 'prefix': option_tuple, - 'exec_prefix': option_tuple, - 'home': option_tuple, - 'user': option_tuple, - 'root': option_tuple, - } - - self.assertEqual( - sorted(d.command_options.get('install').keys()), - sorted(result_dict.keys())) - - for (key, value) in d.command_options.get('install').items(): - self.assertEqual(value, result_dict[key]) - - # Test case: In a Virtual Environment - with mock.patch.multiple(sys, prefix='/a', base_prefix='/b') as values: - d = self.create_distribution([TESTFN]) - - for key in result_dict.keys(): - self.assertNotIn(key, d.command_options.get('install', {})) - - def test_command_packages_configfile(self): - sys.argv.append("build") - self.addCleanup(os.unlink, TESTFN) - f = open(TESTFN, "w") - try: - print("[global]", file=f) - print("command_packages = foo.bar, splat", file=f) - finally: - f.close() - - d = self.create_distribution([TESTFN]) - self.assertEqual(d.get_command_packages(), - ["distutils.command", "foo.bar", "splat"]) - - # ensure command line overrides config: - sys.argv[1:] = ["--command-packages", "spork", "build"] - d = self.create_distribution([TESTFN]) - self.assertEqual(d.get_command_packages(), - ["distutils.command", "spork"]) - - # Setting --command-packages to '' should cause the default to - # be used even if a config file specified something else: - sys.argv[1:] = ["--command-packages", "", "build"] - d = self.create_distribution([TESTFN]) - self.assertEqual(d.get_command_packages(), ["distutils.command"]) - - def test_empty_options(self): - # an empty options dictionary should not stay in the - # list of attributes - - # catching warnings - warns = [] - - def _warn(msg): - warns.append(msg) - - self.addCleanup(setattr, warnings, 'warn', warnings.warn) - warnings.warn = _warn - dist = Distribution(attrs={'author': 'xxx', 'name': 'xxx', - 'version': 'xxx', 'url': 'xxxx', - 'options': {}}) - - self.assertEqual(len(warns), 0) - self.assertNotIn('options', dir(dist)) - - def test_finalize_options(self): - attrs = {'keywords': 'one,two', - 'platforms': 'one,two'} - - dist = Distribution(attrs=attrs) - dist.finalize_options() - - # finalize_option splits platforms and keywords - self.assertEqual(dist.metadata.platforms, ['one', 'two']) - self.assertEqual(dist.metadata.keywords, ['one', 'two']) - - attrs = {'keywords': 'foo bar', - 'platforms': 'foo bar'} - dist = Distribution(attrs=attrs) - dist.finalize_options() - self.assertEqual(dist.metadata.platforms, ['foo bar']) - self.assertEqual(dist.metadata.keywords, ['foo bar']) - - def test_get_command_packages(self): - dist = Distribution() - self.assertEqual(dist.command_packages, None) - cmds = dist.get_command_packages() - self.assertEqual(cmds, ['distutils.command']) - self.assertEqual(dist.command_packages, - ['distutils.command']) - - dist.command_packages = 'one,two' - cmds = dist.get_command_packages() - self.assertEqual(cmds, ['distutils.command', 'one', 'two']) - - def test_announce(self): - # make sure the level is known - dist = Distribution() - args = ('ok',) - kwargs = {'level': 'ok2'} - self.assertRaises(ValueError, dist.announce, args, kwargs) - - - def test_find_config_files_disable(self): - # Ticket #1180: Allow user to disable their home config file. - temp_home = self.mkdtemp() - if os.name == 'posix': - user_filename = os.path.join(temp_home, ".pydistutils.cfg") - else: - user_filename = os.path.join(temp_home, "pydistutils.cfg") - - with open(user_filename, 'w') as f: - f.write('[distutils]\n') - - def _expander(path): - return temp_home - - old_expander = os.path.expanduser - os.path.expanduser = _expander - try: - d = Distribution() - all_files = d.find_config_files() - - d = Distribution(attrs={'script_args': ['--no-user-cfg']}) - files = d.find_config_files() - finally: - os.path.expanduser = old_expander - - # make sure --no-user-cfg disables the user cfg file - self.assertEqual(len(all_files)-1, len(files)) - -class MetadataTestCase(support.TempdirManager, support.EnvironGuard, - unittest.TestCase): - - def setUp(self): - super(MetadataTestCase, self).setUp() - self.argv = sys.argv, sys.argv[:] - - def tearDown(self): - sys.argv = self.argv[0] - sys.argv[:] = self.argv[1] - super(MetadataTestCase, self).tearDown() - - def format_metadata(self, dist): - sio = io.StringIO() - dist.metadata.write_pkg_file(sio) - return sio.getvalue() - - def test_simple_metadata(self): - attrs = {"name": "package", - "version": "1.0"} - dist = Distribution(attrs) - meta = self.format_metadata(dist) - self.assertIn("Metadata-Version: 1.0", meta) - self.assertNotIn("provides:", meta.lower()) - self.assertNotIn("requires:", meta.lower()) - self.assertNotIn("obsoletes:", meta.lower()) - - def test_provides(self): - attrs = {"name": "package", - "version": "1.0", - "provides": ["package", "package.sub"]} - dist = Distribution(attrs) - self.assertEqual(dist.metadata.get_provides(), - ["package", "package.sub"]) - self.assertEqual(dist.get_provides(), - ["package", "package.sub"]) - meta = self.format_metadata(dist) - self.assertIn("Metadata-Version: 1.1", meta) - self.assertNotIn("requires:", meta.lower()) - self.assertNotIn("obsoletes:", meta.lower()) - - def test_provides_illegal(self): - self.assertRaises(ValueError, Distribution, - {"name": "package", - "version": "1.0", - "provides": ["my.pkg (splat)"]}) - - def test_requires(self): - attrs = {"name": "package", - "version": "1.0", - "requires": ["other", "another (==1.0)"]} - dist = Distribution(attrs) - self.assertEqual(dist.metadata.get_requires(), - ["other", "another (==1.0)"]) - self.assertEqual(dist.get_requires(), - ["other", "another (==1.0)"]) - meta = self.format_metadata(dist) - self.assertIn("Metadata-Version: 1.1", meta) - self.assertNotIn("provides:", meta.lower()) - self.assertIn("Requires: other", meta) - self.assertIn("Requires: another (==1.0)", meta) - self.assertNotIn("obsoletes:", meta.lower()) - - def test_requires_illegal(self): - self.assertRaises(ValueError, Distribution, - {"name": "package", - "version": "1.0", - "requires": ["my.pkg (splat)"]}) - - def test_requires_to_list(self): - attrs = {"name": "package", - "requires": iter(["other"])} - dist = Distribution(attrs) - self.assertIsInstance(dist.metadata.requires, list) - - - def test_obsoletes(self): - attrs = {"name": "package", - "version": "1.0", - "obsoletes": ["other", "another (<1.0)"]} - dist = Distribution(attrs) - self.assertEqual(dist.metadata.get_obsoletes(), - ["other", "another (<1.0)"]) - self.assertEqual(dist.get_obsoletes(), - ["other", "another (<1.0)"]) - meta = self.format_metadata(dist) - self.assertIn("Metadata-Version: 1.1", meta) - self.assertNotIn("provides:", meta.lower()) - self.assertNotIn("requires:", meta.lower()) - self.assertIn("Obsoletes: other", meta) - self.assertIn("Obsoletes: another (<1.0)", meta) - - def test_obsoletes_illegal(self): - self.assertRaises(ValueError, Distribution, - {"name": "package", - "version": "1.0", - "obsoletes": ["my.pkg (splat)"]}) - - def test_obsoletes_to_list(self): - attrs = {"name": "package", - "obsoletes": iter(["other"])} - dist = Distribution(attrs) - self.assertIsInstance(dist.metadata.obsoletes, list) - - def test_classifier(self): - attrs = {'name': 'Boa', 'version': '3.0', - 'classifiers': ['Programming Language :: Python :: 3']} - dist = Distribution(attrs) - self.assertEqual(dist.get_classifiers(), - ['Programming Language :: Python :: 3']) - meta = self.format_metadata(dist) - self.assertIn('Metadata-Version: 1.1', meta) - - def test_classifier_invalid_type(self): - attrs = {'name': 'Boa', 'version': '3.0', - 'classifiers': ('Programming Language :: Python :: 3',)} - with captured_stderr() as error: - d = Distribution(attrs) - # should have warning about passing a non-list - self.assertIn('should be a list', error.getvalue()) - # should be converted to a list - self.assertIsInstance(d.metadata.classifiers, list) - self.assertEqual(d.metadata.classifiers, - list(attrs['classifiers'])) - - def test_keywords(self): - attrs = {'name': 'Monty', 'version': '1.0', - 'keywords': ['spam', 'eggs', 'life of brian']} - dist = Distribution(attrs) - self.assertEqual(dist.get_keywords(), - ['spam', 'eggs', 'life of brian']) - - def test_keywords_invalid_type(self): - attrs = {'name': 'Monty', 'version': '1.0', - 'keywords': ('spam', 'eggs', 'life of brian')} - with captured_stderr() as error: - d = Distribution(attrs) - # should have warning about passing a non-list - self.assertIn('should be a list', error.getvalue()) - # should be converted to a list - self.assertIsInstance(d.metadata.keywords, list) - self.assertEqual(d.metadata.keywords, list(attrs['keywords'])) - - def test_platforms(self): - attrs = {'name': 'Monty', 'version': '1.0', - 'platforms': ['GNU/Linux', 'Some Evil Platform']} - dist = Distribution(attrs) - self.assertEqual(dist.get_platforms(), - ['GNU/Linux', 'Some Evil Platform']) - - def test_platforms_invalid_types(self): - attrs = {'name': 'Monty', 'version': '1.0', - 'platforms': ('GNU/Linux', 'Some Evil Platform')} - with captured_stderr() as error: - d = Distribution(attrs) - # should have warning about passing a non-list - self.assertIn('should be a list', error.getvalue()) - # should be converted to a list - self.assertIsInstance(d.metadata.platforms, list) - self.assertEqual(d.metadata.platforms, list(attrs['platforms'])) - - def test_download_url(self): - attrs = {'name': 'Boa', 'version': '3.0', - 'download_url': 'http://example.org/boa'} - dist = Distribution(attrs) - meta = self.format_metadata(dist) - self.assertIn('Metadata-Version: 1.1', meta) - - def test_long_description(self): - long_desc = textwrap.dedent("""\ - example:: - We start here - and continue here - and end here.""") - attrs = {"name": "package", - "version": "1.0", - "long_description": long_desc} - - dist = Distribution(attrs) - meta = self.format_metadata(dist) - meta = meta.replace('\n' + 8 * ' ', '\n') - self.assertIn(long_desc, meta) - - def test_custom_pydistutils(self): - # fixes #2166 - # make sure pydistutils.cfg is found - if os.name == 'posix': - user_filename = ".pydistutils.cfg" - else: - user_filename = "pydistutils.cfg" - - temp_dir = self.mkdtemp() - user_filename = os.path.join(temp_dir, user_filename) - f = open(user_filename, 'w') - try: - f.write('.') - finally: - f.close() - - try: - dist = Distribution() - - # linux-style - if sys.platform in ('linux', 'darwin'): - os.environ['HOME'] = temp_dir - files = dist.find_config_files() - self.assertIn(user_filename, files) - - # win32-style - if sys.platform == 'win32': - # home drive should be found - os.environ['USERPROFILE'] = temp_dir - files = dist.find_config_files() - self.assertIn(user_filename, files, - '%r not found in %r' % (user_filename, files)) - finally: - os.remove(user_filename) - - def test_fix_help_options(self): - help_tuples = [('a', 'b', 'c', 'd'), (1, 2, 3, 4)] - fancy_options = fix_help_options(help_tuples) - self.assertEqual(fancy_options[0], ('a', 'b', 'c')) - self.assertEqual(fancy_options[1], (1, 2, 3)) - - def test_show_help(self): - # smoke test, just makes sure some help is displayed - self.addCleanup(log.set_threshold, log._global_log.threshold) - dist = Distribution() - sys.argv = [] - dist.help = 1 - dist.script_name = 'setup.py' - with captured_stdout() as s: - dist.parse_command_line() - - output = [line for line in s.getvalue().split('\n') - if line.strip() != ''] - self.assertTrue(output) - - - def test_read_metadata(self): - attrs = {"name": "package", - "version": "1.0", - "long_description": "desc", - "description": "xxx", - "download_url": "http://example.com", - "keywords": ['one', 'two'], - "requires": ['foo']} - - dist = Distribution(attrs) - metadata = dist.metadata - - # write it then reloads it - PKG_INFO = io.StringIO() - metadata.write_pkg_file(PKG_INFO) - PKG_INFO.seek(0) - metadata.read_pkg_file(PKG_INFO) - - self.assertEqual(metadata.name, "package") - self.assertEqual(metadata.version, "1.0") - self.assertEqual(metadata.description, "xxx") - self.assertEqual(metadata.download_url, 'http://example.com') - self.assertEqual(metadata.keywords, ['one', 'two']) - self.assertEqual(metadata.platforms, ['UNKNOWN']) - self.assertEqual(metadata.obsoletes, None) - self.assertEqual(metadata.requires, ['foo']) - -def test_suite(): - suite = unittest.TestSuite() - suite.addTest(unittest.TestLoader().loadTestsFromTestCase(DistributionTestCase)) - suite.addTest(unittest.TestLoader().loadTestsFromTestCase(MetadataTestCase)) - return suite - -if __name__ == "__main__": - run_unittest(test_suite()) diff --git a/Lib/distutils/tests/test_extension.py b/Lib/distutils/tests/test_extension.py deleted file mode 100644 index 2b08930e..00000000 --- a/Lib/distutils/tests/test_extension.py +++ /dev/null @@ -1,70 +0,0 @@ -"""Tests for distutils.extension.""" -import unittest -import os -import warnings - -from test.support import run_unittest -from test.support.warnings_helper import check_warnings -from distutils.extension import read_setup_file, Extension - -class ExtensionTestCase(unittest.TestCase): - - def test_read_setup_file(self): - # trying to read a Setup file - # (sample extracted from the PyGame project) - setup = os.path.join(os.path.dirname(__file__), 'Setup.sample') - - exts = read_setup_file(setup) - names = [ext.name for ext in exts] - names.sort() - - # here are the extensions read_setup_file should have created - # out of the file - wanted = ['_arraysurfarray', '_camera', '_numericsndarray', - '_numericsurfarray', 'base', 'bufferproxy', 'cdrom', - 'color', 'constants', 'display', 'draw', 'event', - 'fastevent', 'font', 'gfxdraw', 'image', 'imageext', - 'joystick', 'key', 'mask', 'mixer', 'mixer_music', - 'mouse', 'movie', 'overlay', 'pixelarray', 'pypm', - 'rect', 'rwobject', 'scrap', 'surface', 'surflock', - 'time', 'transform'] - - self.assertEqual(names, wanted) - - def test_extension_init(self): - # the first argument, which is the name, must be a string - self.assertRaises(AssertionError, Extension, 1, []) - ext = Extension('name', []) - self.assertEqual(ext.name, 'name') - - # the second argument, which is the list of files, must - # be a list of strings - self.assertRaises(AssertionError, Extension, 'name', 'file') - self.assertRaises(AssertionError, Extension, 'name', ['file', 1]) - ext = Extension('name', ['file1', 'file2']) - self.assertEqual(ext.sources, ['file1', 'file2']) - - # others arguments have defaults - for attr in ('include_dirs', 'define_macros', 'undef_macros', - 'library_dirs', 'libraries', 'runtime_library_dirs', - 'extra_objects', 'extra_compile_args', 'extra_link_args', - 'export_symbols', 'swig_opts', 'depends'): - self.assertEqual(getattr(ext, attr), []) - - self.assertEqual(ext.language, None) - self.assertEqual(ext.optional, None) - - # if there are unknown keyword options, warn about them - with check_warnings() as w: - warnings.simplefilter('always') - ext = Extension('name', ['file1', 'file2'], chic=True) - - self.assertEqual(len(w.warnings), 1) - self.assertEqual(str(w.warnings[0].message), - "Unknown Extension options: 'chic'") - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(ExtensionTestCase) - -if __name__ == "__main__": - run_unittest(test_suite()) diff --git a/Lib/distutils/tests/test_file_util.py b/Lib/distutils/tests/test_file_util.py deleted file mode 100644 index 551151b0..00000000 --- a/Lib/distutils/tests/test_file_util.py +++ /dev/null @@ -1,126 +0,0 @@ -"""Tests for distutils.file_util.""" -import unittest -import os -import errno -from unittest.mock import patch - -from distutils.file_util import move_file, copy_file -from distutils import log -from distutils.tests import support -from distutils.errors import DistutilsFileError -from test.support import run_unittest -from test.support.os_helper import unlink - - -class FileUtilTestCase(support.TempdirManager, unittest.TestCase): - - def _log(self, msg, *args): - if len(args) > 0: - self._logs.append(msg % args) - else: - self._logs.append(msg) - - def setUp(self): - super(FileUtilTestCase, self).setUp() - self._logs = [] - self.old_log = log.info - log.info = self._log - tmp_dir = self.mkdtemp() - self.source = os.path.join(tmp_dir, 'f1') - self.target = os.path.join(tmp_dir, 'f2') - self.target_dir = os.path.join(tmp_dir, 'd1') - - def tearDown(self): - log.info = self.old_log - super(FileUtilTestCase, self).tearDown() - - def test_move_file_verbosity(self): - f = open(self.source, 'w') - try: - f.write('some content') - finally: - f.close() - - move_file(self.source, self.target, verbose=0) - wanted = [] - self.assertEqual(self._logs, wanted) - - # back to original state - move_file(self.target, self.source, verbose=0) - - move_file(self.source, self.target, verbose=1) - wanted = ['moving %s -> %s' % (self.source, self.target)] - self.assertEqual(self._logs, wanted) - - # back to original state - move_file(self.target, self.source, verbose=0) - - self._logs = [] - # now the target is a dir - os.mkdir(self.target_dir) - move_file(self.source, self.target_dir, verbose=1) - wanted = ['moving %s -> %s' % (self.source, self.target_dir)] - self.assertEqual(self._logs, wanted) - - def test_move_file_exception_unpacking_rename(self): - # see issue 22182 - with patch("os.rename", side_effect=OSError("wrong", 1)), \ - self.assertRaises(DistutilsFileError): - with open(self.source, 'w') as fobj: - fobj.write('spam eggs') - move_file(self.source, self.target, verbose=0) - - def test_move_file_exception_unpacking_unlink(self): - # see issue 22182 - with patch("os.rename", side_effect=OSError(errno.EXDEV, "wrong")), \ - patch("os.unlink", side_effect=OSError("wrong", 1)), \ - self.assertRaises(DistutilsFileError): - with open(self.source, 'w') as fobj: - fobj.write('spam eggs') - move_file(self.source, self.target, verbose=0) - - @unittest.skipUnless(hasattr(os, 'link'), 'requires os.link') - def test_copy_file_hard_link(self): - with open(self.source, 'w') as f: - f.write('some content') - # Check first that copy_file() will not fall back on copying the file - # instead of creating the hard link. - try: - os.link(self.source, self.target) - except OSError as e: - self.skipTest('os.link: %s' % e) - else: - unlink(self.target) - st = os.stat(self.source) - copy_file(self.source, self.target, link='hard') - st2 = os.stat(self.source) - st3 = os.stat(self.target) - self.assertTrue(os.path.samestat(st, st2), (st, st2)) - self.assertTrue(os.path.samestat(st2, st3), (st2, st3)) - with open(self.source, 'r') as f: - self.assertEqual(f.read(), 'some content') - - @unittest.skipUnless(hasattr(os, 'link'), 'requires os.link') - def test_copy_file_hard_link_failure(self): - # If hard linking fails, copy_file() falls back on copying file - # (some special filesystems don't support hard linking even under - # Unix, see issue #8876). - with open(self.source, 'w') as f: - f.write('some content') - st = os.stat(self.source) - with patch("os.link", side_effect=OSError(0, "linking unsupported")): - copy_file(self.source, self.target, link='hard') - st2 = os.stat(self.source) - st3 = os.stat(self.target) - self.assertTrue(os.path.samestat(st, st2), (st, st2)) - self.assertFalse(os.path.samestat(st2, st3), (st2, st3)) - for fn in (self.source, self.target): - with open(fn, 'r') as f: - self.assertEqual(f.read(), 'some content') - - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(FileUtilTestCase) - -if __name__ == "__main__": - run_unittest(test_suite()) diff --git a/Lib/distutils/tests/test_filelist.py b/Lib/distutils/tests/test_filelist.py deleted file mode 100644 index 98c97e49..00000000 --- a/Lib/distutils/tests/test_filelist.py +++ /dev/null @@ -1,340 +0,0 @@ -"""Tests for distutils.filelist.""" -import os -import re -import unittest -from distutils import debug -from distutils.log import WARN -from distutils.errors import DistutilsTemplateError -from distutils.filelist import glob_to_re, translate_pattern, FileList -from distutils import filelist - -from test.support import os_helper -from test.support import captured_stdout, run_unittest -from distutils.tests import support - -MANIFEST_IN = """\ -include ok -include xo -exclude xo -include foo.tmp -include buildout.cfg -global-include *.x -global-include *.txt -global-exclude *.tmp -recursive-include f *.oo -recursive-exclude global *.x -graft dir -prune dir3 -""" - - -def make_local_path(s): - """Converts '/' in a string to os.sep""" - return s.replace('/', os.sep) - - -class FileListTestCase(support.LoggingSilencer, - unittest.TestCase): - - def assertNoWarnings(self): - self.assertEqual(self.get_logs(WARN), []) - self.clear_logs() - - def assertWarnings(self): - self.assertGreater(len(self.get_logs(WARN)), 0) - self.clear_logs() - - def test_glob_to_re(self): - sep = os.sep - if os.sep == '\\': - sep = re.escape(os.sep) - - for glob, regex in ( - # simple cases - ('foo*', r'(?s:foo[^%(sep)s]*)\Z'), - ('foo?', r'(?s:foo[^%(sep)s])\Z'), - ('foo??', r'(?s:foo[^%(sep)s][^%(sep)s])\Z'), - # special cases - (r'foo\\*', r'(?s:foo\\\\[^%(sep)s]*)\Z'), - (r'foo\\\*', r'(?s:foo\\\\\\[^%(sep)s]*)\Z'), - ('foo????', r'(?s:foo[^%(sep)s][^%(sep)s][^%(sep)s][^%(sep)s])\Z'), - (r'foo\\??', r'(?s:foo\\\\[^%(sep)s][^%(sep)s])\Z')): - regex = regex % {'sep': sep} - self.assertEqual(glob_to_re(glob), regex) - - def test_process_template_line(self): - # testing all MANIFEST.in template patterns - file_list = FileList() - l = make_local_path - - # simulated file list - file_list.allfiles = ['foo.tmp', 'ok', 'xo', 'four.txt', - 'buildout.cfg', - # filelist does not filter out VCS directories, - # it's sdist that does - l('.hg/last-message.txt'), - l('global/one.txt'), - l('global/two.txt'), - l('global/files.x'), - l('global/here.tmp'), - l('f/o/f.oo'), - l('dir/graft-one'), - l('dir/dir2/graft2'), - l('dir3/ok'), - l('dir3/sub/ok.txt'), - ] - - for line in MANIFEST_IN.split('\n'): - if line.strip() == '': - continue - file_list.process_template_line(line) - - wanted = ['ok', - 'buildout.cfg', - 'four.txt', - l('.hg/last-message.txt'), - l('global/one.txt'), - l('global/two.txt'), - l('f/o/f.oo'), - l('dir/graft-one'), - l('dir/dir2/graft2'), - ] - - self.assertEqual(file_list.files, wanted) - - def test_debug_print(self): - file_list = FileList() - with captured_stdout() as stdout: - file_list.debug_print('xxx') - self.assertEqual(stdout.getvalue(), '') - - debug.DEBUG = True - try: - with captured_stdout() as stdout: - file_list.debug_print('xxx') - self.assertEqual(stdout.getvalue(), 'xxx\n') - finally: - debug.DEBUG = False - - def test_set_allfiles(self): - file_list = FileList() - files = ['a', 'b', 'c'] - file_list.set_allfiles(files) - self.assertEqual(file_list.allfiles, files) - - def test_remove_duplicates(self): - file_list = FileList() - file_list.files = ['a', 'b', 'a', 'g', 'c', 'g'] - # files must be sorted beforehand (sdist does it) - file_list.sort() - file_list.remove_duplicates() - self.assertEqual(file_list.files, ['a', 'b', 'c', 'g']) - - def test_translate_pattern(self): - # not regex - self.assertTrue(hasattr( - translate_pattern('a', anchor=True, is_regex=False), - 'search')) - - # is a regex - regex = re.compile('a') - self.assertEqual( - translate_pattern(regex, anchor=True, is_regex=True), - regex) - - # plain string flagged as regex - self.assertTrue(hasattr( - translate_pattern('a', anchor=True, is_regex=True), - 'search')) - - # glob support - self.assertTrue(translate_pattern( - '*.py', anchor=True, is_regex=False).search('filelist.py')) - - def test_exclude_pattern(self): - # return False if no match - file_list = FileList() - self.assertFalse(file_list.exclude_pattern('*.py')) - - # return True if files match - file_list = FileList() - file_list.files = ['a.py', 'b.py'] - self.assertTrue(file_list.exclude_pattern('*.py')) - - # test excludes - file_list = FileList() - file_list.files = ['a.py', 'a.txt'] - file_list.exclude_pattern('*.py') - self.assertEqual(file_list.files, ['a.txt']) - - def test_include_pattern(self): - # return False if no match - file_list = FileList() - file_list.set_allfiles([]) - self.assertFalse(file_list.include_pattern('*.py')) - - # return True if files match - file_list = FileList() - file_list.set_allfiles(['a.py', 'b.txt']) - self.assertTrue(file_list.include_pattern('*.py')) - - # test * matches all files - file_list = FileList() - self.assertIsNone(file_list.allfiles) - file_list.set_allfiles(['a.py', 'b.txt']) - file_list.include_pattern('*') - self.assertEqual(file_list.allfiles, ['a.py', 'b.txt']) - - def test_process_template(self): - l = make_local_path - # invalid lines - file_list = FileList() - for action in ('include', 'exclude', 'global-include', - 'global-exclude', 'recursive-include', - 'recursive-exclude', 'graft', 'prune', 'blarg'): - self.assertRaises(DistutilsTemplateError, - file_list.process_template_line, action) - - # include - file_list = FileList() - file_list.set_allfiles(['a.py', 'b.txt', l('d/c.py')]) - - file_list.process_template_line('include *.py') - self.assertEqual(file_list.files, ['a.py']) - self.assertNoWarnings() - - file_list.process_template_line('include *.rb') - self.assertEqual(file_list.files, ['a.py']) - self.assertWarnings() - - # exclude - file_list = FileList() - file_list.files = ['a.py', 'b.txt', l('d/c.py')] - - file_list.process_template_line('exclude *.py') - self.assertEqual(file_list.files, ['b.txt', l('d/c.py')]) - self.assertNoWarnings() - - file_list.process_template_line('exclude *.rb') - self.assertEqual(file_list.files, ['b.txt', l('d/c.py')]) - self.assertWarnings() - - # global-include - file_list = FileList() - file_list.set_allfiles(['a.py', 'b.txt', l('d/c.py')]) - - file_list.process_template_line('global-include *.py') - self.assertEqual(file_list.files, ['a.py', l('d/c.py')]) - self.assertNoWarnings() - - file_list.process_template_line('global-include *.rb') - self.assertEqual(file_list.files, ['a.py', l('d/c.py')]) - self.assertWarnings() - - # global-exclude - file_list = FileList() - file_list.files = ['a.py', 'b.txt', l('d/c.py')] - - file_list.process_template_line('global-exclude *.py') - self.assertEqual(file_list.files, ['b.txt']) - self.assertNoWarnings() - - file_list.process_template_line('global-exclude *.rb') - self.assertEqual(file_list.files, ['b.txt']) - self.assertWarnings() - - # recursive-include - file_list = FileList() - file_list.set_allfiles(['a.py', l('d/b.py'), l('d/c.txt'), - l('d/d/e.py')]) - - file_list.process_template_line('recursive-include d *.py') - self.assertEqual(file_list.files, [l('d/b.py'), l('d/d/e.py')]) - self.assertNoWarnings() - - file_list.process_template_line('recursive-include e *.py') - self.assertEqual(file_list.files, [l('d/b.py'), l('d/d/e.py')]) - self.assertWarnings() - - # recursive-exclude - file_list = FileList() - file_list.files = ['a.py', l('d/b.py'), l('d/c.txt'), l('d/d/e.py')] - - file_list.process_template_line('recursive-exclude d *.py') - self.assertEqual(file_list.files, ['a.py', l('d/c.txt')]) - self.assertNoWarnings() - - file_list.process_template_line('recursive-exclude e *.py') - self.assertEqual(file_list.files, ['a.py', l('d/c.txt')]) - self.assertWarnings() - - # graft - file_list = FileList() - file_list.set_allfiles(['a.py', l('d/b.py'), l('d/d/e.py'), - l('f/f.py')]) - - file_list.process_template_line('graft d') - self.assertEqual(file_list.files, [l('d/b.py'), l('d/d/e.py')]) - self.assertNoWarnings() - - file_list.process_template_line('graft e') - self.assertEqual(file_list.files, [l('d/b.py'), l('d/d/e.py')]) - self.assertWarnings() - - # prune - file_list = FileList() - file_list.files = ['a.py', l('d/b.py'), l('d/d/e.py'), l('f/f.py')] - - file_list.process_template_line('prune d') - self.assertEqual(file_list.files, ['a.py', l('f/f.py')]) - self.assertNoWarnings() - - file_list.process_template_line('prune e') - self.assertEqual(file_list.files, ['a.py', l('f/f.py')]) - self.assertWarnings() - - -class FindAllTestCase(unittest.TestCase): - @os_helper.skip_unless_symlink - def test_missing_symlink(self): - with os_helper.temp_cwd(): - os.symlink('foo', 'bar') - self.assertEqual(filelist.findall(), []) - - def test_basic_discovery(self): - """ - When findall is called with no parameters or with - '.' as the parameter, the dot should be omitted from - the results. - """ - with os_helper.temp_cwd(): - os.mkdir('foo') - file1 = os.path.join('foo', 'file1.txt') - os_helper.create_empty_file(file1) - os.mkdir('bar') - file2 = os.path.join('bar', 'file2.txt') - os_helper.create_empty_file(file2) - expected = [file2, file1] - self.assertEqual(sorted(filelist.findall()), expected) - - def test_non_local_discovery(self): - """ - When findall is called with another path, the full - path name should be returned. - """ - with os_helper.temp_dir() as temp_dir: - file1 = os.path.join(temp_dir, 'file1.txt') - os_helper.create_empty_file(file1) - expected = [file1] - self.assertEqual(filelist.findall(temp_dir), expected) - - -def test_suite(): - return unittest.TestSuite([ - unittest.TestLoader().loadTestsFromTestCase(FileListTestCase), - unittest.TestLoader().loadTestsFromTestCase(FindAllTestCase), - ]) - - -if __name__ == "__main__": - run_unittest(test_suite()) diff --git a/Lib/distutils/tests/test_install.py b/Lib/distutils/tests/test_install.py deleted file mode 100644 index c38f98b8..00000000 --- a/Lib/distutils/tests/test_install.py +++ /dev/null @@ -1,261 +0,0 @@ -"""Tests for distutils.command.install.""" - -import os -import sys -import unittest -import site - -from test.support import captured_stdout, run_unittest, requires_subprocess - -from distutils import sysconfig -from distutils.command.install import install, HAS_USER_SITE -from distutils.command import install as install_module -from distutils.command.build_ext import build_ext -from distutils.command.install import INSTALL_SCHEMES -from distutils.core import Distribution -from distutils.errors import DistutilsOptionError -from distutils.extension import Extension - -from distutils.tests import support -from test import support as test_support - - -def _make_ext_name(modname): - return modname + sysconfig.get_config_var('EXT_SUFFIX') - - -class InstallTestCase(support.TempdirManager, - support.EnvironGuard, - support.LoggingSilencer, - unittest.TestCase): - - def setUp(self): - super().setUp() - self._backup_config_vars = dict(sysconfig._config_vars) - - def tearDown(self): - super().tearDown() - sysconfig._config_vars.clear() - sysconfig._config_vars.update(self._backup_config_vars) - - def test_home_installation_scheme(self): - # This ensure two things: - # - that --home generates the desired set of directory names - # - test --home is supported on all platforms - builddir = self.mkdtemp() - destination = os.path.join(builddir, "installation") - - dist = Distribution({"name": "foopkg"}) - # script_name need not exist, it just need to be initialized - dist.script_name = os.path.join(builddir, "setup.py") - dist.command_obj["build"] = support.DummyCommand( - build_base=builddir, - build_lib=os.path.join(builddir, "lib"), - ) - - cmd = install(dist) - cmd.home = destination - cmd.ensure_finalized() - - self.assertEqual(cmd.install_base, destination) - self.assertEqual(cmd.install_platbase, destination) - - def check_path(got, expected): - got = os.path.normpath(got) - expected = os.path.normpath(expected) - self.assertEqual(got, expected) - - libdir = os.path.join(destination, "lib", "python") - check_path(cmd.install_lib, libdir) - platlibdir = os.path.join(destination, sys.platlibdir, "python") - check_path(cmd.install_platlib, platlibdir) - check_path(cmd.install_purelib, libdir) - check_path(cmd.install_headers, - os.path.join(destination, "include", "python", "foopkg")) - check_path(cmd.install_scripts, os.path.join(destination, "bin")) - check_path(cmd.install_data, destination) - - @unittest.skipUnless(HAS_USER_SITE, 'need user site') - def test_user_site(self): - # test install with --user - # preparing the environment for the test - self.old_user_base = site.USER_BASE - self.old_user_site = site.USER_SITE - self.tmpdir = self.mkdtemp() - self.user_base = os.path.join(self.tmpdir, 'B') - self.user_site = os.path.join(self.tmpdir, 'S') - site.USER_BASE = self.user_base - site.USER_SITE = self.user_site - install_module.USER_BASE = self.user_base - install_module.USER_SITE = self.user_site - - def _expanduser(path): - return self.tmpdir - self.old_expand = os.path.expanduser - os.path.expanduser = _expanduser - - def cleanup(): - site.USER_BASE = self.old_user_base - site.USER_SITE = self.old_user_site - install_module.USER_BASE = self.old_user_base - install_module.USER_SITE = self.old_user_site - os.path.expanduser = self.old_expand - - self.addCleanup(cleanup) - - if HAS_USER_SITE: - for key in ('nt_user', 'unix_user'): - self.assertIn(key, INSTALL_SCHEMES) - - dist = Distribution({'name': 'xx'}) - cmd = install(dist) - - # making sure the user option is there - options = [name for name, short, lable in - cmd.user_options] - self.assertIn('user', options) - - # setting a value - cmd.user = 1 - - # user base and site shouldn't be created yet - self.assertFalse(os.path.exists(self.user_base)) - self.assertFalse(os.path.exists(self.user_site)) - - # let's run finalize - cmd.ensure_finalized() - - # now they should - self.assertTrue(os.path.exists(self.user_base)) - self.assertTrue(os.path.exists(self.user_site)) - - self.assertIn('userbase', cmd.config_vars) - self.assertIn('usersite', cmd.config_vars) - - def test_handle_extra_path(self): - dist = Distribution({'name': 'xx', 'extra_path': 'path,dirs'}) - cmd = install(dist) - - # two elements - cmd.handle_extra_path() - self.assertEqual(cmd.extra_path, ['path', 'dirs']) - self.assertEqual(cmd.extra_dirs, 'dirs') - self.assertEqual(cmd.path_file, 'path') - - # one element - cmd.extra_path = ['path'] - cmd.handle_extra_path() - self.assertEqual(cmd.extra_path, ['path']) - self.assertEqual(cmd.extra_dirs, 'path') - self.assertEqual(cmd.path_file, 'path') - - # none - dist.extra_path = cmd.extra_path = None - cmd.handle_extra_path() - self.assertEqual(cmd.extra_path, None) - self.assertEqual(cmd.extra_dirs, '') - self.assertEqual(cmd.path_file, None) - - # three elements (no way !) - cmd.extra_path = 'path,dirs,again' - self.assertRaises(DistutilsOptionError, cmd.handle_extra_path) - - def test_finalize_options(self): - dist = Distribution({'name': 'xx'}) - cmd = install(dist) - - # must supply either prefix/exec-prefix/home or - # install-base/install-platbase -- not both - cmd.prefix = 'prefix' - cmd.install_base = 'base' - self.assertRaises(DistutilsOptionError, cmd.finalize_options) - - # must supply either home or prefix/exec-prefix -- not both - cmd.install_base = None - cmd.home = 'home' - self.assertRaises(DistutilsOptionError, cmd.finalize_options) - - # can't combine user with prefix/exec_prefix/home or - # install_(plat)base - cmd.prefix = None - cmd.user = 'user' - self.assertRaises(DistutilsOptionError, cmd.finalize_options) - - def test_record(self): - install_dir = self.mkdtemp() - project_dir, dist = self.create_dist(py_modules=['hello'], - scripts=['sayhi']) - os.chdir(project_dir) - self.write_file('hello.py', "def main(): print('o hai')") - self.write_file('sayhi', 'from hello import main; main()') - - cmd = install(dist) - dist.command_obj['install'] = cmd - cmd.root = install_dir - cmd.record = os.path.join(project_dir, 'filelist') - cmd.ensure_finalized() - cmd.run() - - f = open(cmd.record) - try: - content = f.read() - finally: - f.close() - - found = [os.path.basename(line) for line in content.splitlines()] - expected = ['hello.py', 'hello.%s.pyc' % sys.implementation.cache_tag, - 'sayhi', - 'UNKNOWN-0.0.0-py%s.%s.egg-info' % sys.version_info[:2]] - self.assertEqual(found, expected) - - @requires_subprocess() - def test_record_extensions(self): - cmd = test_support.missing_compiler_executable() - if cmd is not None: - self.skipTest('The %r command is not found' % cmd) - install_dir = self.mkdtemp() - project_dir, dist = self.create_dist(ext_modules=[ - Extension('xx', ['xxmodule.c'])]) - os.chdir(project_dir) - support.copy_xxmodule_c(project_dir) - - buildextcmd = build_ext(dist) - support.fixup_build_ext(buildextcmd) - buildextcmd.ensure_finalized() - - cmd = install(dist) - dist.command_obj['install'] = cmd - dist.command_obj['build_ext'] = buildextcmd - cmd.root = install_dir - cmd.record = os.path.join(project_dir, 'filelist') - cmd.ensure_finalized() - cmd.run() - - f = open(cmd.record) - try: - content = f.read() - finally: - f.close() - - found = [os.path.basename(line) for line in content.splitlines()] - expected = [_make_ext_name('xx'), - 'UNKNOWN-0.0.0-py%s.%s.egg-info' % sys.version_info[:2]] - self.assertEqual(found, expected) - - def test_debug_mode(self): - # this covers the code called when DEBUG is set - old_logs_len = len(self.logs) - install_module.DEBUG = True - try: - with captured_stdout(): - self.test_record() - finally: - install_module.DEBUG = False - self.assertGreater(len(self.logs), old_logs_len) - - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(InstallTestCase) - -if __name__ == "__main__": - run_unittest(test_suite()) diff --git a/Lib/distutils/tests/test_install_data.py b/Lib/distutils/tests/test_install_data.py deleted file mode 100644 index 6191d2fa..00000000 --- a/Lib/distutils/tests/test_install_data.py +++ /dev/null @@ -1,75 +0,0 @@ -"""Tests for distutils.command.install_data.""" -import os -import unittest - -from distutils.command.install_data import install_data -from distutils.tests import support -from test.support import run_unittest - -class InstallDataTestCase(support.TempdirManager, - support.LoggingSilencer, - support.EnvironGuard, - unittest.TestCase): - - def test_simple_run(self): - pkg_dir, dist = self.create_dist() - cmd = install_data(dist) - cmd.install_dir = inst = os.path.join(pkg_dir, 'inst') - - # data_files can contain - # - simple files - # - a tuple with a path, and a list of file - one = os.path.join(pkg_dir, 'one') - self.write_file(one, 'xxx') - inst2 = os.path.join(pkg_dir, 'inst2') - two = os.path.join(pkg_dir, 'two') - self.write_file(two, 'xxx') - - cmd.data_files = [one, (inst2, [two])] - self.assertEqual(cmd.get_inputs(), [one, (inst2, [two])]) - - # let's run the command - cmd.ensure_finalized() - cmd.run() - - # let's check the result - self.assertEqual(len(cmd.get_outputs()), 2) - rtwo = os.path.split(two)[-1] - self.assertTrue(os.path.exists(os.path.join(inst2, rtwo))) - rone = os.path.split(one)[-1] - self.assertTrue(os.path.exists(os.path.join(inst, rone))) - cmd.outfiles = [] - - # let's try with warn_dir one - cmd.warn_dir = 1 - cmd.ensure_finalized() - cmd.run() - - # let's check the result - self.assertEqual(len(cmd.get_outputs()), 2) - self.assertTrue(os.path.exists(os.path.join(inst2, rtwo))) - self.assertTrue(os.path.exists(os.path.join(inst, rone))) - cmd.outfiles = [] - - # now using root and empty dir - cmd.root = os.path.join(pkg_dir, 'root') - inst3 = os.path.join(cmd.install_dir, 'inst3') - inst4 = os.path.join(pkg_dir, 'inst4') - three = os.path.join(cmd.install_dir, 'three') - self.write_file(three, 'xx') - cmd.data_files = [one, (inst2, [two]), - ('inst3', [three]), - (inst4, [])] - cmd.ensure_finalized() - cmd.run() - - # let's check the result - self.assertEqual(len(cmd.get_outputs()), 4) - self.assertTrue(os.path.exists(os.path.join(inst2, rtwo))) - self.assertTrue(os.path.exists(os.path.join(inst, rone))) - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(InstallDataTestCase) - -if __name__ == "__main__": - run_unittest(test_suite()) diff --git a/Lib/distutils/tests/test_install_headers.py b/Lib/distutils/tests/test_install_headers.py deleted file mode 100644 index 1aa4d09c..00000000 --- a/Lib/distutils/tests/test_install_headers.py +++ /dev/null @@ -1,39 +0,0 @@ -"""Tests for distutils.command.install_headers.""" -import os -import unittest - -from distutils.command.install_headers import install_headers -from distutils.tests import support -from test.support import run_unittest - -class InstallHeadersTestCase(support.TempdirManager, - support.LoggingSilencer, - support.EnvironGuard, - unittest.TestCase): - - def test_simple_run(self): - # we have two headers - header_list = self.mkdtemp() - header1 = os.path.join(header_list, 'header1') - header2 = os.path.join(header_list, 'header2') - self.write_file(header1) - self.write_file(header2) - headers = [header1, header2] - - pkg_dir, dist = self.create_dist(headers=headers) - cmd = install_headers(dist) - self.assertEqual(cmd.get_inputs(), headers) - - # let's run the command - cmd.install_dir = os.path.join(pkg_dir, 'inst') - cmd.ensure_finalized() - cmd.run() - - # let's check the results - self.assertEqual(len(cmd.get_outputs()), 2) - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(InstallHeadersTestCase) - -if __name__ == "__main__": - run_unittest(test_suite()) diff --git a/Lib/distutils/tests/test_install_lib.py b/Lib/distutils/tests/test_install_lib.py deleted file mode 100644 index f840d1a9..00000000 --- a/Lib/distutils/tests/test_install_lib.py +++ /dev/null @@ -1,117 +0,0 @@ -"""Tests for distutils.command.install_data.""" -import sys -import os -import importlib.util -import unittest - -from distutils.command.install_lib import install_lib -from distutils.extension import Extension -from distutils.tests import support -from distutils.errors import DistutilsOptionError -from test.support import run_unittest, requires_subprocess - - -class InstallLibTestCase(support.TempdirManager, - support.LoggingSilencer, - support.EnvironGuard, - unittest.TestCase): - - def test_finalize_options(self): - dist = self.create_dist()[1] - cmd = install_lib(dist) - - cmd.finalize_options() - self.assertEqual(cmd.compile, 1) - self.assertEqual(cmd.optimize, 0) - - # optimize must be 0, 1, or 2 - cmd.optimize = 'foo' - self.assertRaises(DistutilsOptionError, cmd.finalize_options) - cmd.optimize = '4' - self.assertRaises(DistutilsOptionError, cmd.finalize_options) - - cmd.optimize = '2' - cmd.finalize_options() - self.assertEqual(cmd.optimize, 2) - - @unittest.skipIf(sys.dont_write_bytecode, 'byte-compile disabled') - @requires_subprocess() - def test_byte_compile(self): - project_dir, dist = self.create_dist() - os.chdir(project_dir) - cmd = install_lib(dist) - cmd.compile = cmd.optimize = 1 - - f = os.path.join(project_dir, 'foo.py') - self.write_file(f, '# python file') - cmd.byte_compile([f]) - pyc_file = importlib.util.cache_from_source('foo.py', optimization='') - pyc_opt_file = importlib.util.cache_from_source('foo.py', - optimization=cmd.optimize) - self.assertTrue(os.path.exists(pyc_file)) - self.assertTrue(os.path.exists(pyc_opt_file)) - - def test_get_outputs(self): - project_dir, dist = self.create_dist() - os.chdir(project_dir) - os.mkdir('spam') - cmd = install_lib(dist) - - # setting up a dist environment - cmd.compile = cmd.optimize = 1 - cmd.install_dir = self.mkdtemp() - f = os.path.join(project_dir, 'spam', '__init__.py') - self.write_file(f, '# python package') - cmd.distribution.ext_modules = [Extension('foo', ['xxx'])] - cmd.distribution.packages = ['spam'] - cmd.distribution.script_name = 'setup.py' - - # get_outputs should return 4 elements: spam/__init__.py and .pyc, - # foo.import-tag-abiflags.so / foo.pyd - outputs = cmd.get_outputs() - self.assertEqual(len(outputs), 4, outputs) - - def test_get_inputs(self): - project_dir, dist = self.create_dist() - os.chdir(project_dir) - os.mkdir('spam') - cmd = install_lib(dist) - - # setting up a dist environment - cmd.compile = cmd.optimize = 1 - cmd.install_dir = self.mkdtemp() - f = os.path.join(project_dir, 'spam', '__init__.py') - self.write_file(f, '# python package') - cmd.distribution.ext_modules = [Extension('foo', ['xxx'])] - cmd.distribution.packages = ['spam'] - cmd.distribution.script_name = 'setup.py' - - # get_inputs should return 2 elements: spam/__init__.py and - # foo.import-tag-abiflags.so / foo.pyd - inputs = cmd.get_inputs() - self.assertEqual(len(inputs), 2, inputs) - - @requires_subprocess() - def test_dont_write_bytecode(self): - # makes sure byte_compile is not used - dist = self.create_dist()[1] - cmd = install_lib(dist) - cmd.compile = 1 - cmd.optimize = 1 - - old_dont_write_bytecode = sys.dont_write_bytecode - sys.dont_write_bytecode = True - try: - cmd.byte_compile([]) - finally: - sys.dont_write_bytecode = old_dont_write_bytecode - - self.assertIn('byte-compiling is disabled', - self.logs[0][1] % self.logs[0][2]) - - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(InstallLibTestCase) - -if __name__ == "__main__": - run_unittest(test_suite()) diff --git a/Lib/distutils/tests/test_install_scripts.py b/Lib/distutils/tests/test_install_scripts.py deleted file mode 100644 index 648db3b1..00000000 --- a/Lib/distutils/tests/test_install_scripts.py +++ /dev/null @@ -1,82 +0,0 @@ -"""Tests for distutils.command.install_scripts.""" - -import os -import unittest - -from distutils.command.install_scripts import install_scripts -from distutils.core import Distribution - -from distutils.tests import support -from test.support import run_unittest - - -class InstallScriptsTestCase(support.TempdirManager, - support.LoggingSilencer, - unittest.TestCase): - - def test_default_settings(self): - dist = Distribution() - dist.command_obj["build"] = support.DummyCommand( - build_scripts="/foo/bar") - dist.command_obj["install"] = support.DummyCommand( - install_scripts="/splat/funk", - force=1, - skip_build=1, - ) - cmd = install_scripts(dist) - self.assertFalse(cmd.force) - self.assertFalse(cmd.skip_build) - self.assertIsNone(cmd.build_dir) - self.assertIsNone(cmd.install_dir) - - cmd.finalize_options() - - self.assertTrue(cmd.force) - self.assertTrue(cmd.skip_build) - self.assertEqual(cmd.build_dir, "/foo/bar") - self.assertEqual(cmd.install_dir, "/splat/funk") - - def test_installation(self): - source = self.mkdtemp() - expected = [] - - def write_script(name, text): - expected.append(name) - f = open(os.path.join(source, name), "w") - try: - f.write(text) - finally: - f.close() - - write_script("script1.py", ("#! /usr/bin/env python2.3\n" - "# bogus script w/ Python sh-bang\n" - "pass\n")) - write_script("script2.py", ("#!/usr/bin/python\n" - "# bogus script w/ Python sh-bang\n" - "pass\n")) - write_script("shell.sh", ("#!/bin/sh\n" - "# bogus shell script w/ sh-bang\n" - "exit 0\n")) - - target = self.mkdtemp() - dist = Distribution() - dist.command_obj["build"] = support.DummyCommand(build_scripts=source) - dist.command_obj["install"] = support.DummyCommand( - install_scripts=target, - force=1, - skip_build=1, - ) - cmd = install_scripts(dist) - cmd.finalize_options() - cmd.run() - - installed = os.listdir(target) - for name in expected: - self.assertIn(name, installed) - - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(InstallScriptsTestCase) - -if __name__ == "__main__": - run_unittest(test_suite()) diff --git a/Lib/distutils/tests/test_log.py b/Lib/distutils/tests/test_log.py deleted file mode 100644 index ec2ae028..00000000 --- a/Lib/distutils/tests/test_log.py +++ /dev/null @@ -1,46 +0,0 @@ -"""Tests for distutils.log""" - -import io -import sys -import unittest -from test.support import swap_attr, run_unittest - -from distutils import log - -class TestLog(unittest.TestCase): - def test_non_ascii(self): - # Issues #8663, #34421: test that non-encodable text is escaped with - # backslashreplace error handler and encodable non-ASCII text is - # output as is. - for errors in ('strict', 'backslashreplace', 'surrogateescape', - 'replace', 'ignore'): - with self.subTest(errors=errors): - stdout = io.TextIOWrapper(io.BytesIO(), - encoding='cp437', errors=errors) - stderr = io.TextIOWrapper(io.BytesIO(), - encoding='cp437', errors=errors) - old_threshold = log.set_threshold(log.DEBUG) - try: - with swap_attr(sys, 'stdout', stdout), \ - swap_attr(sys, 'stderr', stderr): - log.debug('Dεbug\tMėssãge') - log.fatal('Fαtal\tÈrrōr') - finally: - log.set_threshold(old_threshold) - - stdout.seek(0) - self.assertEqual(stdout.read().rstrip(), - 'Dεbug\tM?ss?ge' if errors == 'replace' else - 'Dεbug\tMssge' if errors == 'ignore' else - 'Dεbug\tM\\u0117ss\\xe3ge') - stderr.seek(0) - self.assertEqual(stderr.read().rstrip(), - 'Fαtal\t?rr?r' if errors == 'replace' else - 'Fαtal\trrr' if errors == 'ignore' else - 'Fαtal\t\\xc8rr\\u014dr') - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(TestLog) - -if __name__ == "__main__": - run_unittest(test_suite()) diff --git a/Lib/distutils/tests/test_msvc9compiler.py b/Lib/distutils/tests/test_msvc9compiler.py deleted file mode 100644 index 6235405e..00000000 --- a/Lib/distutils/tests/test_msvc9compiler.py +++ /dev/null @@ -1,184 +0,0 @@ -"""Tests for distutils.msvc9compiler.""" -import sys -import unittest -import os - -from distutils.errors import DistutilsPlatformError -from distutils.tests import support -from test.support import run_unittest - -# A manifest with the only assembly reference being the msvcrt assembly, so -# should have the assembly completely stripped. Note that although the -# assembly has a <security> reference the assembly is removed - that is -# currently a "feature", not a bug :) -_MANIFEST_WITH_ONLY_MSVC_REFERENCE = """\ -<?xml version="1.0" encoding="UTF-8" standalone="yes"?> -<assembly xmlns="urn:schemas-microsoft-com:asm.v1" - manifestVersion="1.0"> - <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> - <security> - <requestedPrivileges> - <requestedExecutionLevel level="asInvoker" uiAccess="false"> - </requestedExecutionLevel> - </requestedPrivileges> - </security> - </trustInfo> - <dependency> - <dependentAssembly> - <assemblyIdentity type="win32" name="Microsoft.VC90.CRT" - version="9.0.21022.8" processorArchitecture="x86" - publicKeyToken="XXXX"> - </assemblyIdentity> - </dependentAssembly> - </dependency> -</assembly> -""" - -# A manifest with references to assemblies other than msvcrt. When processed, -# this assembly should be returned with just the msvcrt part removed. -_MANIFEST_WITH_MULTIPLE_REFERENCES = """\ -<?xml version="1.0" encoding="UTF-8" standalone="yes"?> -<assembly xmlns="urn:schemas-microsoft-com:asm.v1" - manifestVersion="1.0"> - <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> - <security> - <requestedPrivileges> - <requestedExecutionLevel level="asInvoker" uiAccess="false"> - </requestedExecutionLevel> - </requestedPrivileges> - </security> - </trustInfo> - <dependency> - <dependentAssembly> - <assemblyIdentity type="win32" name="Microsoft.VC90.CRT" - version="9.0.21022.8" processorArchitecture="x86" - publicKeyToken="XXXX"> - </assemblyIdentity> - </dependentAssembly> - </dependency> - <dependency> - <dependentAssembly> - <assemblyIdentity type="win32" name="Microsoft.VC90.MFC" - version="9.0.21022.8" processorArchitecture="x86" - publicKeyToken="XXXX"></assemblyIdentity> - </dependentAssembly> - </dependency> -</assembly> -""" - -_CLEANED_MANIFEST = """\ -<?xml version="1.0" encoding="UTF-8" standalone="yes"?> -<assembly xmlns="urn:schemas-microsoft-com:asm.v1" - manifestVersion="1.0"> - <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> - <security> - <requestedPrivileges> - <requestedExecutionLevel level="asInvoker" uiAccess="false"> - </requestedExecutionLevel> - </requestedPrivileges> - </security> - </trustInfo> - <dependency> - - </dependency> - <dependency> - <dependentAssembly> - <assemblyIdentity type="win32" name="Microsoft.VC90.MFC" - version="9.0.21022.8" processorArchitecture="x86" - publicKeyToken="XXXX"></assemblyIdentity> - </dependentAssembly> - </dependency> -</assembly>""" - -if sys.platform=="win32": - from distutils.msvccompiler import get_build_version - if get_build_version()>=8.0: - SKIP_MESSAGE = None - else: - SKIP_MESSAGE = "These tests are only for MSVC8.0 or above" -else: - SKIP_MESSAGE = "These tests are only for win32" - -@unittest.skipUnless(SKIP_MESSAGE is None, SKIP_MESSAGE) -class msvc9compilerTestCase(support.TempdirManager, - unittest.TestCase): - - def test_no_compiler(self): - # makes sure query_vcvarsall raises - # a DistutilsPlatformError if the compiler - # is not found - from distutils.msvc9compiler import query_vcvarsall - def _find_vcvarsall(version): - return None - - from distutils import msvc9compiler - old_find_vcvarsall = msvc9compiler.find_vcvarsall - msvc9compiler.find_vcvarsall = _find_vcvarsall - try: - self.assertRaises(DistutilsPlatformError, query_vcvarsall, - 'wont find this version') - finally: - msvc9compiler.find_vcvarsall = old_find_vcvarsall - - def test_reg_class(self): - from distutils.msvc9compiler import Reg - self.assertRaises(KeyError, Reg.get_value, 'xxx', 'xxx') - - # looking for values that should exist on all - # windows registry versions. - path = r'Control Panel\Desktop' - v = Reg.get_value(path, 'dragfullwindows') - self.assertIn(v, ('0', '1', '2')) - - import winreg - HKCU = winreg.HKEY_CURRENT_USER - keys = Reg.read_keys(HKCU, 'xxxx') - self.assertEqual(keys, None) - - keys = Reg.read_keys(HKCU, r'Control Panel') - self.assertIn('Desktop', keys) - - def test_remove_visual_c_ref(self): - from distutils.msvc9compiler import MSVCCompiler - tempdir = self.mkdtemp() - manifest = os.path.join(tempdir, 'manifest') - f = open(manifest, 'w') - try: - f.write(_MANIFEST_WITH_MULTIPLE_REFERENCES) - finally: - f.close() - - compiler = MSVCCompiler() - compiler._remove_visual_c_ref(manifest) - - # see what we got - f = open(manifest) - try: - # removing trailing spaces - content = '\n'.join([line.rstrip() for line in f.readlines()]) - finally: - f.close() - - # makes sure the manifest was properly cleaned - self.assertEqual(content, _CLEANED_MANIFEST) - - def test_remove_entire_manifest(self): - from distutils.msvc9compiler import MSVCCompiler - tempdir = self.mkdtemp() - manifest = os.path.join(tempdir, 'manifest') - f = open(manifest, 'w') - try: - f.write(_MANIFEST_WITH_ONLY_MSVC_REFERENCE) - finally: - f.close() - - compiler = MSVCCompiler() - got = compiler._remove_visual_c_ref(manifest) - self.assertIsNone(got) - - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(msvc9compilerTestCase) - -if __name__ == "__main__": - run_unittest(test_suite()) diff --git a/Lib/distutils/tests/test_msvccompiler.py b/Lib/distutils/tests/test_msvccompiler.py deleted file mode 100644 index dd67c3eb..00000000 --- a/Lib/distutils/tests/test_msvccompiler.py +++ /dev/null @@ -1,81 +0,0 @@ -"""Tests for distutils._msvccompiler.""" -import sys -import unittest -import os - -from distutils.errors import DistutilsPlatformError -from distutils.tests import support -from test.support import run_unittest - - -SKIP_MESSAGE = (None if sys.platform == "win32" else - "These tests are only for win32") - -@unittest.skipUnless(SKIP_MESSAGE is None, SKIP_MESSAGE) -class msvccompilerTestCase(support.TempdirManager, - unittest.TestCase): - - def test_no_compiler(self): - import distutils._msvccompiler as _msvccompiler - # makes sure query_vcvarsall raises - # a DistutilsPlatformError if the compiler - # is not found - def _find_vcvarsall(plat_spec): - return None, None - - old_find_vcvarsall = _msvccompiler._find_vcvarsall - _msvccompiler._find_vcvarsall = _find_vcvarsall - try: - self.assertRaises(DistutilsPlatformError, - _msvccompiler._get_vc_env, - 'wont find this version') - finally: - _msvccompiler._find_vcvarsall = old_find_vcvarsall - - def test_get_vc_env_unicode(self): - import distutils._msvccompiler as _msvccompiler - - test_var = 'ṰḖṤṪ┅ṼẨṜ' - test_value = '₃⁴₅' - - # Ensure we don't early exit from _get_vc_env - old_distutils_use_sdk = os.environ.pop('DISTUTILS_USE_SDK', None) - os.environ[test_var] = test_value - try: - env = _msvccompiler._get_vc_env('x86') - self.assertIn(test_var.lower(), env) - self.assertEqual(test_value, env[test_var.lower()]) - finally: - os.environ.pop(test_var) - if old_distutils_use_sdk: - os.environ['DISTUTILS_USE_SDK'] = old_distutils_use_sdk - - def test_get_vc2017(self): - import distutils._msvccompiler as _msvccompiler - - # This function cannot be mocked, so pass it if we find VS 2017 - # and mark it skipped if we do not. - version, path = _msvccompiler._find_vc2017() - if version: - self.assertGreaterEqual(version, 15) - self.assertTrue(os.path.isdir(path)) - else: - raise unittest.SkipTest("VS 2017 is not installed") - - def test_get_vc2015(self): - import distutils._msvccompiler as _msvccompiler - - # This function cannot be mocked, so pass it if we find VS 2015 - # and mark it skipped if we do not. - version, path = _msvccompiler._find_vc2015() - if version: - self.assertGreaterEqual(version, 14) - self.assertTrue(os.path.isdir(path)) - else: - raise unittest.SkipTest("VS 2015 is not installed") - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(msvccompilerTestCase) - -if __name__ == "__main__": - run_unittest(test_suite()) diff --git a/Lib/distutils/tests/test_register.py b/Lib/distutils/tests/test_register.py deleted file mode 100644 index 7805c6d3..00000000 --- a/Lib/distutils/tests/test_register.py +++ /dev/null @@ -1,324 +0,0 @@ -"""Tests for distutils.command.register.""" -import os -import unittest -import getpass -import urllib -import warnings - -from test.support import run_unittest -from test.support.warnings_helper import check_warnings - -from distutils.command import register as register_module -from distutils.command.register import register -from distutils.errors import DistutilsSetupError -from distutils.log import INFO - -from distutils.tests.test_config import BasePyPIRCCommandTestCase - -try: - import docutils -except ImportError: - docutils = None - -PYPIRC_NOPASSWORD = """\ -[distutils] - -index-servers = - server1 - -[server1] -username:me -""" - -WANTED_PYPIRC = """\ -[distutils] -index-servers = - pypi - -[pypi] -username:tarek -password:password -""" - -class Inputs(object): - """Fakes user inputs.""" - def __init__(self, *answers): - self.answers = answers - self.index = 0 - - def __call__(self, prompt=''): - try: - return self.answers[self.index] - finally: - self.index += 1 - -class FakeOpener(object): - """Fakes a PyPI server""" - def __init__(self): - self.reqs = [] - - def __call__(self, *args): - return self - - def open(self, req, data=None, timeout=None): - self.reqs.append(req) - return self - - def read(self): - return b'xxx' - - def getheader(self, name, default=None): - return { - 'content-type': 'text/plain; charset=utf-8', - }.get(name.lower(), default) - - -class RegisterTestCase(BasePyPIRCCommandTestCase): - - def setUp(self): - super(RegisterTestCase, self).setUp() - # patching the password prompt - self._old_getpass = getpass.getpass - def _getpass(prompt): - return 'password' - getpass.getpass = _getpass - urllib.request._opener = None - self.old_opener = urllib.request.build_opener - self.conn = urllib.request.build_opener = FakeOpener() - - def tearDown(self): - getpass.getpass = self._old_getpass - urllib.request._opener = None - urllib.request.build_opener = self.old_opener - super(RegisterTestCase, self).tearDown() - - def _get_cmd(self, metadata=None): - if metadata is None: - metadata = {'url': 'xxx', 'author': 'xxx', - 'author_email': 'xxx', - 'name': 'xxx', 'version': 'xxx'} - pkg_info, dist = self.create_dist(**metadata) - return register(dist) - - def test_create_pypirc(self): - # this test makes sure a .pypirc file - # is created when requested. - - # let's create a register instance - cmd = self._get_cmd() - - # we shouldn't have a .pypirc file yet - self.assertFalse(os.path.exists(self.rc)) - - # patching input and getpass.getpass - # so register gets happy - # - # Here's what we are faking : - # use your existing login (choice 1.) - # Username : 'tarek' - # Password : 'password' - # Save your login (y/N)? : 'y' - inputs = Inputs('1', 'tarek', 'y') - register_module.input = inputs.__call__ - # let's run the command - try: - cmd.run() - finally: - del register_module.input - - # we should have a brand new .pypirc file - self.assertTrue(os.path.exists(self.rc)) - - # with the content similar to WANTED_PYPIRC - f = open(self.rc) - try: - content = f.read() - self.assertEqual(content, WANTED_PYPIRC) - finally: - f.close() - - # now let's make sure the .pypirc file generated - # really works : we shouldn't be asked anything - # if we run the command again - def _no_way(prompt=''): - raise AssertionError(prompt) - register_module.input = _no_way - - cmd.show_response = 1 - cmd.run() - - # let's see what the server received : we should - # have 2 similar requests - self.assertEqual(len(self.conn.reqs), 2) - req1 = dict(self.conn.reqs[0].headers) - req2 = dict(self.conn.reqs[1].headers) - - self.assertEqual(req1['Content-length'], '1374') - self.assertEqual(req2['Content-length'], '1374') - self.assertIn(b'xxx', self.conn.reqs[1].data) - - def test_password_not_in_file(self): - - self.write_file(self.rc, PYPIRC_NOPASSWORD) - cmd = self._get_cmd() - cmd._set_config() - cmd.finalize_options() - cmd.send_metadata() - - # dist.password should be set - # therefore used afterwards by other commands - self.assertEqual(cmd.distribution.password, 'password') - - def test_registering(self): - # this test runs choice 2 - cmd = self._get_cmd() - inputs = Inputs('2', 'tarek', 'tarek@ziade.org') - register_module.input = inputs.__call__ - try: - # let's run the command - cmd.run() - finally: - del register_module.input - - # we should have send a request - self.assertEqual(len(self.conn.reqs), 1) - req = self.conn.reqs[0] - headers = dict(req.headers) - self.assertEqual(headers['Content-length'], '608') - self.assertIn(b'tarek', req.data) - - def test_password_reset(self): - # this test runs choice 3 - cmd = self._get_cmd() - inputs = Inputs('3', 'tarek@ziade.org') - register_module.input = inputs.__call__ - try: - # let's run the command - cmd.run() - finally: - del register_module.input - - # we should have send a request - self.assertEqual(len(self.conn.reqs), 1) - req = self.conn.reqs[0] - headers = dict(req.headers) - self.assertEqual(headers['Content-length'], '290') - self.assertIn(b'tarek', req.data) - - @unittest.skipUnless(docutils is not None, 'needs docutils') - def test_strict(self): - # testing the script option - # when on, the register command stops if - # the metadata is incomplete or if - # long_description is not reSt compliant - - # empty metadata - cmd = self._get_cmd({}) - cmd.ensure_finalized() - cmd.strict = 1 - self.assertRaises(DistutilsSetupError, cmd.run) - - # metadata are OK but long_description is broken - metadata = {'url': 'xxx', 'author': 'xxx', - 'author_email': 'éxéxé', - 'name': 'xxx', 'version': 'xxx', - 'long_description': 'title\n==\n\ntext'} - - cmd = self._get_cmd(metadata) - cmd.ensure_finalized() - cmd.strict = 1 - self.assertRaises(DistutilsSetupError, cmd.run) - - # now something that works - metadata['long_description'] = 'title\n=====\n\ntext' - cmd = self._get_cmd(metadata) - cmd.ensure_finalized() - cmd.strict = 1 - inputs = Inputs('1', 'tarek', 'y') - register_module.input = inputs.__call__ - # let's run the command - try: - cmd.run() - finally: - del register_module.input - - # strict is not by default - cmd = self._get_cmd() - cmd.ensure_finalized() - inputs = Inputs('1', 'tarek', 'y') - register_module.input = inputs.__call__ - # let's run the command - try: - cmd.run() - finally: - del register_module.input - - # and finally a Unicode test (bug #12114) - metadata = {'url': 'xxx', 'author': '\u00c9ric', - 'author_email': 'xxx', 'name': 'xxx', - 'version': 'xxx', - 'description': 'Something about esszet \u00df', - 'long_description': 'More things about esszet \u00df'} - - cmd = self._get_cmd(metadata) - cmd.ensure_finalized() - cmd.strict = 1 - inputs = Inputs('1', 'tarek', 'y') - register_module.input = inputs.__call__ - # let's run the command - try: - cmd.run() - finally: - del register_module.input - - @unittest.skipUnless(docutils is not None, 'needs docutils') - def test_register_invalid_long_description(self): - description = ':funkie:`str`' # mimic Sphinx-specific markup - metadata = {'url': 'xxx', 'author': 'xxx', - 'author_email': 'xxx', - 'name': 'xxx', 'version': 'xxx', - 'long_description': description} - cmd = self._get_cmd(metadata) - cmd.ensure_finalized() - cmd.strict = True - inputs = Inputs('2', 'tarek', 'tarek@ziade.org') - register_module.input = inputs - self.addCleanup(delattr, register_module, 'input') - - self.assertRaises(DistutilsSetupError, cmd.run) - - def test_check_metadata_deprecated(self): - # makes sure make_metadata is deprecated - cmd = self._get_cmd() - with check_warnings() as w: - warnings.simplefilter("always") - cmd.check_metadata() - self.assertEqual(len(w.warnings), 1) - - def test_list_classifiers(self): - cmd = self._get_cmd() - cmd.list_classifiers = 1 - cmd.run() - results = self.get_logs(INFO) - self.assertEqual(results, ['running check', 'xxx']) - - def test_show_response(self): - # test that the --show-response option return a well formatted response - cmd = self._get_cmd() - inputs = Inputs('1', 'tarek', 'y') - register_module.input = inputs.__call__ - cmd.show_response = 1 - try: - cmd.run() - finally: - del register_module.input - - results = self.get_logs(INFO) - self.assertEqual(results[3], 75 * '-' + '\nxxx\n' + 75 * '-') - - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(RegisterTestCase) - -if __name__ == "__main__": - run_unittest(test_suite()) diff --git a/Lib/distutils/tests/test_sdist.py b/Lib/distutils/tests/test_sdist.py deleted file mode 100644 index 46b3a13e..00000000 --- a/Lib/distutils/tests/test_sdist.py +++ /dev/null @@ -1,493 +0,0 @@ -"""Tests for distutils.command.sdist.""" -import os -import tarfile -import unittest -import warnings -import zipfile -from os.path import join -from textwrap import dedent -from test.support import captured_stdout, run_unittest -from test.support.warnings_helper import check_warnings - -try: - import zlib - ZLIB_SUPPORT = True -except ImportError: - ZLIB_SUPPORT = False - -try: - import grp - import pwd - UID_GID_SUPPORT = True -except ImportError: - UID_GID_SUPPORT = False - -from distutils.command.sdist import sdist, show_formats -from distutils.core import Distribution -from distutils.tests.test_config import BasePyPIRCCommandTestCase -from distutils.errors import DistutilsOptionError -from distutils.spawn import find_executable -from distutils.log import WARN -from distutils.filelist import FileList -from distutils.archive_util import ARCHIVE_FORMATS - -SETUP_PY = """ -from distutils.core import setup -import somecode - -setup(name='fake') -""" - -MANIFEST = """\ -# file GENERATED by distutils, do NOT edit -README -buildout.cfg -inroot.txt -setup.py -data%(sep)sdata.dt -scripts%(sep)sscript.py -some%(sep)sfile.txt -some%(sep)sother_file.txt -somecode%(sep)s__init__.py -somecode%(sep)sdoc.dat -somecode%(sep)sdoc.txt -""" - -class SDistTestCase(BasePyPIRCCommandTestCase): - - def setUp(self): - # PyPIRCCommandTestCase creates a temp dir already - # and put it in self.tmp_dir - super(SDistTestCase, self).setUp() - # setting up an environment - self.old_path = os.getcwd() - os.mkdir(join(self.tmp_dir, 'somecode')) - os.mkdir(join(self.tmp_dir, 'dist')) - # a package, and a README - self.write_file((self.tmp_dir, 'README'), 'xxx') - self.write_file((self.tmp_dir, 'somecode', '__init__.py'), '#') - self.write_file((self.tmp_dir, 'setup.py'), SETUP_PY) - os.chdir(self.tmp_dir) - - def tearDown(self): - # back to normal - os.chdir(self.old_path) - super(SDistTestCase, self).tearDown() - - def get_cmd(self, metadata=None): - """Returns a cmd""" - if metadata is None: - metadata = {'name': 'fake', 'version': '1.0', - 'url': 'xxx', 'author': 'xxx', - 'author_email': 'xxx'} - dist = Distribution(metadata) - dist.script_name = 'setup.py' - dist.packages = ['somecode'] - dist.include_package_data = True - cmd = sdist(dist) - cmd.dist_dir = 'dist' - return dist, cmd - - @unittest.skipUnless(ZLIB_SUPPORT, 'Need zlib support to run') - def test_prune_file_list(self): - # this test creates a project with some VCS dirs and an NFS rename - # file, then launches sdist to check they get pruned on all systems - - # creating VCS directories with some files in them - os.mkdir(join(self.tmp_dir, 'somecode', '.svn')) - self.write_file((self.tmp_dir, 'somecode', '.svn', 'ok.py'), 'xxx') - - os.mkdir(join(self.tmp_dir, 'somecode', '.hg')) - self.write_file((self.tmp_dir, 'somecode', '.hg', - 'ok'), 'xxx') - - os.mkdir(join(self.tmp_dir, 'somecode', '.git')) - self.write_file((self.tmp_dir, 'somecode', '.git', - 'ok'), 'xxx') - - self.write_file((self.tmp_dir, 'somecode', '.nfs0001'), 'xxx') - - # now building a sdist - dist, cmd = self.get_cmd() - - # zip is available universally - # (tar might not be installed under win32) - cmd.formats = ['zip'] - - cmd.ensure_finalized() - cmd.run() - - # now let's check what we have - dist_folder = join(self.tmp_dir, 'dist') - files = os.listdir(dist_folder) - self.assertEqual(files, ['fake-1.0.zip']) - - zip_file = zipfile.ZipFile(join(dist_folder, 'fake-1.0.zip')) - try: - content = zip_file.namelist() - finally: - zip_file.close() - - # making sure everything has been pruned correctly - expected = ['', 'PKG-INFO', 'README', 'setup.py', - 'somecode/', 'somecode/__init__.py'] - self.assertEqual(sorted(content), ['fake-1.0/' + x for x in expected]) - - @unittest.skipUnless(ZLIB_SUPPORT, 'Need zlib support to run') - @unittest.skipIf(find_executable('tar') is None, - "The tar command is not found") - @unittest.skipIf(find_executable('gzip') is None, - "The gzip command is not found") - def test_make_distribution(self): - # now building a sdist - dist, cmd = self.get_cmd() - - # creating a gztar then a tar - cmd.formats = ['gztar', 'tar'] - cmd.ensure_finalized() - cmd.run() - - # making sure we have two files - dist_folder = join(self.tmp_dir, 'dist') - result = os.listdir(dist_folder) - result.sort() - self.assertEqual(result, ['fake-1.0.tar', 'fake-1.0.tar.gz']) - - os.remove(join(dist_folder, 'fake-1.0.tar')) - os.remove(join(dist_folder, 'fake-1.0.tar.gz')) - - # now trying a tar then a gztar - cmd.formats = ['tar', 'gztar'] - - cmd.ensure_finalized() - cmd.run() - - result = os.listdir(dist_folder) - result.sort() - self.assertEqual(result, ['fake-1.0.tar', 'fake-1.0.tar.gz']) - - @unittest.skipUnless(ZLIB_SUPPORT, 'Need zlib support to run') - def test_add_defaults(self): - - # http://bugs.python.org/issue2279 - - # add_default should also include - # data_files and package_data - dist, cmd = self.get_cmd() - - # filling data_files by pointing files - # in package_data - dist.package_data = {'': ['*.cfg', '*.dat'], - 'somecode': ['*.txt']} - self.write_file((self.tmp_dir, 'somecode', 'doc.txt'), '#') - self.write_file((self.tmp_dir, 'somecode', 'doc.dat'), '#') - - # adding some data in data_files - data_dir = join(self.tmp_dir, 'data') - os.mkdir(data_dir) - self.write_file((data_dir, 'data.dt'), '#') - some_dir = join(self.tmp_dir, 'some') - os.mkdir(some_dir) - # make sure VCS directories are pruned (#14004) - hg_dir = join(self.tmp_dir, '.hg') - os.mkdir(hg_dir) - self.write_file((hg_dir, 'last-message.txt'), '#') - # a buggy regex used to prevent this from working on windows (#6884) - self.write_file((self.tmp_dir, 'buildout.cfg'), '#') - self.write_file((self.tmp_dir, 'inroot.txt'), '#') - self.write_file((some_dir, 'file.txt'), '#') - self.write_file((some_dir, 'other_file.txt'), '#') - - dist.data_files = [('data', ['data/data.dt', - 'buildout.cfg', - 'inroot.txt', - 'notexisting']), - 'some/file.txt', - 'some/other_file.txt'] - - # adding a script - script_dir = join(self.tmp_dir, 'scripts') - os.mkdir(script_dir) - self.write_file((script_dir, 'script.py'), '#') - dist.scripts = [join('scripts', 'script.py')] - - cmd.formats = ['zip'] - cmd.use_defaults = True - - cmd.ensure_finalized() - cmd.run() - - # now let's check what we have - dist_folder = join(self.tmp_dir, 'dist') - files = os.listdir(dist_folder) - self.assertEqual(files, ['fake-1.0.zip']) - - zip_file = zipfile.ZipFile(join(dist_folder, 'fake-1.0.zip')) - try: - content = zip_file.namelist() - finally: - zip_file.close() - - # making sure everything was added - expected = ['', 'PKG-INFO', 'README', 'buildout.cfg', - 'data/', 'data/data.dt', 'inroot.txt', - 'scripts/', 'scripts/script.py', 'setup.py', - 'some/', 'some/file.txt', 'some/other_file.txt', - 'somecode/', 'somecode/__init__.py', 'somecode/doc.dat', - 'somecode/doc.txt'] - self.assertEqual(sorted(content), ['fake-1.0/' + x for x in expected]) - - # checking the MANIFEST - f = open(join(self.tmp_dir, 'MANIFEST')) - try: - manifest = f.read() - finally: - f.close() - self.assertEqual(manifest, MANIFEST % {'sep': os.sep}) - - @unittest.skipUnless(ZLIB_SUPPORT, 'Need zlib support to run') - def test_metadata_check_option(self): - # testing the `medata-check` option - dist, cmd = self.get_cmd(metadata={}) - - # this should raise some warnings ! - # with the `check` subcommand - cmd.ensure_finalized() - cmd.run() - warnings = [msg for msg in self.get_logs(WARN) if - msg.startswith('warning: check:')] - self.assertEqual(len(warnings), 2) - - # trying with a complete set of metadata - self.clear_logs() - dist, cmd = self.get_cmd() - cmd.ensure_finalized() - cmd.metadata_check = 0 - cmd.run() - warnings = [msg for msg in self.get_logs(WARN) if - msg.startswith('warning: check:')] - self.assertEqual(len(warnings), 0) - - def test_check_metadata_deprecated(self): - # makes sure make_metadata is deprecated - dist, cmd = self.get_cmd() - with check_warnings() as w: - warnings.simplefilter("always") - cmd.check_metadata() - self.assertEqual(len(w.warnings), 1) - - def test_show_formats(self): - with captured_stdout() as stdout: - show_formats() - - # the output should be a header line + one line per format - num_formats = len(ARCHIVE_FORMATS.keys()) - output = [line for line in stdout.getvalue().split('\n') - if line.strip().startswith('--formats=')] - self.assertEqual(len(output), num_formats) - - def test_finalize_options(self): - dist, cmd = self.get_cmd() - cmd.finalize_options() - - # default options set by finalize - self.assertEqual(cmd.manifest, 'MANIFEST') - self.assertEqual(cmd.template, 'MANIFEST.in') - self.assertEqual(cmd.dist_dir, 'dist') - - # formats has to be a string splitable on (' ', ',') or - # a stringlist - cmd.formats = 1 - self.assertRaises(DistutilsOptionError, cmd.finalize_options) - cmd.formats = ['zip'] - cmd.finalize_options() - - # formats has to be known - cmd.formats = 'supazipa' - self.assertRaises(DistutilsOptionError, cmd.finalize_options) - - # the following tests make sure there is a nice error message instead - # of a traceback when parsing an invalid manifest template - - def _check_template(self, content): - dist, cmd = self.get_cmd() - os.chdir(self.tmp_dir) - self.write_file('MANIFEST.in', content) - cmd.ensure_finalized() - cmd.filelist = FileList() - cmd.read_template() - warnings = self.get_logs(WARN) - self.assertEqual(len(warnings), 1) - - def test_invalid_template_unknown_command(self): - self._check_template('taunt knights *') - - def test_invalid_template_wrong_arguments(self): - # this manifest command takes one argument - self._check_template('prune') - - @unittest.skipIf(os.name != 'nt', 'test relevant for Windows only') - def test_invalid_template_wrong_path(self): - # on Windows, trailing slashes are not allowed - # this used to crash instead of raising a warning: #8286 - self._check_template('include examples/') - - @unittest.skipUnless(ZLIB_SUPPORT, 'Need zlib support to run') - def test_get_file_list(self): - # make sure MANIFEST is recalculated - dist, cmd = self.get_cmd() - - # filling data_files by pointing files in package_data - dist.package_data = {'somecode': ['*.txt']} - self.write_file((self.tmp_dir, 'somecode', 'doc.txt'), '#') - cmd.formats = ['gztar'] - cmd.ensure_finalized() - cmd.run() - - f = open(cmd.manifest) - try: - manifest = [line.strip() for line in f.read().split('\n') - if line.strip() != ''] - finally: - f.close() - - self.assertEqual(len(manifest), 5) - - # adding a file - self.write_file((self.tmp_dir, 'somecode', 'doc2.txt'), '#') - - # make sure build_py is reinitialized, like a fresh run - build_py = dist.get_command_obj('build_py') - build_py.finalized = False - build_py.ensure_finalized() - - cmd.run() - - f = open(cmd.manifest) - try: - manifest2 = [line.strip() for line in f.read().split('\n') - if line.strip() != ''] - finally: - f.close() - - # do we have the new file in MANIFEST ? - self.assertEqual(len(manifest2), 6) - self.assertIn('doc2.txt', manifest2[-1]) - - @unittest.skipUnless(ZLIB_SUPPORT, 'Need zlib support to run') - def test_manifest_marker(self): - # check that autogenerated MANIFESTs have a marker - dist, cmd = self.get_cmd() - cmd.ensure_finalized() - cmd.run() - - f = open(cmd.manifest) - try: - manifest = [line.strip() for line in f.read().split('\n') - if line.strip() != ''] - finally: - f.close() - - self.assertEqual(manifest[0], - '# file GENERATED by distutils, do NOT edit') - - @unittest.skipUnless(ZLIB_SUPPORT, "Need zlib support to run") - def test_manifest_comments(self): - # make sure comments don't cause exceptions or wrong includes - contents = dedent("""\ - # bad.py - #bad.py - good.py - """) - dist, cmd = self.get_cmd() - cmd.ensure_finalized() - self.write_file((self.tmp_dir, cmd.manifest), contents) - self.write_file((self.tmp_dir, 'good.py'), '# pick me!') - self.write_file((self.tmp_dir, 'bad.py'), "# don't pick me!") - self.write_file((self.tmp_dir, '#bad.py'), "# don't pick me!") - cmd.run() - self.assertEqual(cmd.filelist.files, ['good.py']) - - @unittest.skipUnless(ZLIB_SUPPORT, 'Need zlib support to run') - def test_manual_manifest(self): - # check that a MANIFEST without a marker is left alone - dist, cmd = self.get_cmd() - cmd.formats = ['gztar'] - cmd.ensure_finalized() - self.write_file((self.tmp_dir, cmd.manifest), 'README.manual') - self.write_file((self.tmp_dir, 'README.manual'), - 'This project maintains its MANIFEST file itself.') - cmd.run() - self.assertEqual(cmd.filelist.files, ['README.manual']) - - f = open(cmd.manifest) - try: - manifest = [line.strip() for line in f.read().split('\n') - if line.strip() != ''] - finally: - f.close() - - self.assertEqual(manifest, ['README.manual']) - - archive_name = join(self.tmp_dir, 'dist', 'fake-1.0.tar.gz') - archive = tarfile.open(archive_name) - try: - filenames = [tarinfo.name for tarinfo in archive] - finally: - archive.close() - self.assertEqual(sorted(filenames), ['fake-1.0', 'fake-1.0/PKG-INFO', - 'fake-1.0/README.manual']) - - @unittest.skipUnless(ZLIB_SUPPORT, "requires zlib") - @unittest.skipUnless(UID_GID_SUPPORT, "Requires grp and pwd support") - @unittest.skipIf(find_executable('tar') is None, - "The tar command is not found") - @unittest.skipIf(find_executable('gzip') is None, - "The gzip command is not found") - def test_make_distribution_owner_group(self): - # now building a sdist - dist, cmd = self.get_cmd() - - # creating a gztar and specifying the owner+group - cmd.formats = ['gztar'] - cmd.owner = pwd.getpwuid(0)[0] - cmd.group = grp.getgrgid(0)[0] - cmd.ensure_finalized() - cmd.run() - - # making sure we have the good rights - archive_name = join(self.tmp_dir, 'dist', 'fake-1.0.tar.gz') - archive = tarfile.open(archive_name) - try: - for member in archive.getmembers(): - self.assertEqual(member.uid, 0) - self.assertEqual(member.gid, 0) - finally: - archive.close() - - # building a sdist again - dist, cmd = self.get_cmd() - - # creating a gztar - cmd.formats = ['gztar'] - cmd.ensure_finalized() - cmd.run() - - # making sure we have the good rights - archive_name = join(self.tmp_dir, 'dist', 'fake-1.0.tar.gz') - archive = tarfile.open(archive_name) - - # note that we are not testing the group ownership here - # because, depending on the platforms and the container - # rights (see #7408) - try: - for member in archive.getmembers(): - self.assertEqual(member.uid, os.getuid()) - finally: - archive.close() - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(SDistTestCase) - -if __name__ == "__main__": - run_unittest(test_suite()) diff --git a/Lib/distutils/tests/test_spawn.py b/Lib/distutils/tests/test_spawn.py deleted file mode 100644 index a0a1145d..00000000 --- a/Lib/distutils/tests/test_spawn.py +++ /dev/null @@ -1,139 +0,0 @@ -"""Tests for distutils.spawn.""" -import os -import stat -import sys -import unittest.mock -from test.support import run_unittest, unix_shell, requires_subprocess -from test.support import os_helper - -from distutils.spawn import find_executable -from distutils.spawn import spawn -from distutils.errors import DistutilsExecError -from distutils.tests import support - - -@requires_subprocess() -class SpawnTestCase(support.TempdirManager, - support.LoggingSilencer, - unittest.TestCase): - - @unittest.skipUnless(os.name in ('nt', 'posix'), - 'Runs only under posix or nt') - def test_spawn(self): - tmpdir = self.mkdtemp() - - # creating something executable - # through the shell that returns 1 - if sys.platform != 'win32': - exe = os.path.join(tmpdir, 'foo.sh') - self.write_file(exe, '#!%s\nexit 1' % unix_shell) - else: - exe = os.path.join(tmpdir, 'foo.bat') - self.write_file(exe, 'exit 1') - - os.chmod(exe, 0o777) - self.assertRaises(DistutilsExecError, spawn, [exe]) - - # now something that works - if sys.platform != 'win32': - exe = os.path.join(tmpdir, 'foo.sh') - self.write_file(exe, '#!%s\nexit 0' % unix_shell) - else: - exe = os.path.join(tmpdir, 'foo.bat') - self.write_file(exe, 'exit 0') - - os.chmod(exe, 0o777) - spawn([exe]) # should work without any error - - def test_find_executable(self): - with os_helper.temp_dir() as tmp_dir: - # use TESTFN to get a pseudo-unique filename - program_noeext = os_helper.TESTFN - # Give the temporary program an ".exe" suffix for all. - # It's needed on Windows and not harmful on other platforms. - program = program_noeext + ".exe" - - filename = os.path.join(tmp_dir, program) - with open(filename, "wb"): - pass - os.chmod(filename, stat.S_IXUSR) - - # test path parameter - rv = find_executable(program, path=tmp_dir) - self.assertEqual(rv, filename) - - if sys.platform == 'win32': - # test without ".exe" extension - rv = find_executable(program_noeext, path=tmp_dir) - self.assertEqual(rv, filename) - - # test find in the current directory - with os_helper.change_cwd(tmp_dir): - rv = find_executable(program) - self.assertEqual(rv, program) - - # test non-existent program - dont_exist_program = "dontexist_" + program - rv = find_executable(dont_exist_program , path=tmp_dir) - self.assertIsNone(rv) - - # PATH='': no match, except in the current directory - with os_helper.EnvironmentVarGuard() as env: - env['PATH'] = '' - with unittest.mock.patch('distutils.spawn.os.confstr', - return_value=tmp_dir, create=True), \ - unittest.mock.patch('distutils.spawn.os.defpath', - tmp_dir): - rv = find_executable(program) - self.assertIsNone(rv) - - # look in current directory - with os_helper.change_cwd(tmp_dir): - rv = find_executable(program) - self.assertEqual(rv, program) - - # PATH=':': explicitly looks in the current directory - with os_helper.EnvironmentVarGuard() as env: - env['PATH'] = os.pathsep - with unittest.mock.patch('distutils.spawn.os.confstr', - return_value='', create=True), \ - unittest.mock.patch('distutils.spawn.os.defpath', ''): - rv = find_executable(program) - self.assertIsNone(rv) - - # look in current directory - with os_helper.change_cwd(tmp_dir): - rv = find_executable(program) - self.assertEqual(rv, program) - - # missing PATH: test os.confstr("CS_PATH") and os.defpath - with os_helper.EnvironmentVarGuard() as env: - env.pop('PATH', None) - - # without confstr - with unittest.mock.patch('distutils.spawn.os.confstr', - side_effect=ValueError, - create=True), \ - unittest.mock.patch('distutils.spawn.os.defpath', - tmp_dir): - rv = find_executable(program) - self.assertEqual(rv, filename) - - # with confstr - with unittest.mock.patch('distutils.spawn.os.confstr', - return_value=tmp_dir, create=True), \ - unittest.mock.patch('distutils.spawn.os.defpath', ''): - rv = find_executable(program) - self.assertEqual(rv, filename) - - def test_spawn_missing_exe(self): - with self.assertRaises(DistutilsExecError) as ctx: - spawn(['does-not-exist']) - self.assertIn("command 'does-not-exist' failed", str(ctx.exception)) - - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(SpawnTestCase) - -if __name__ == "__main__": - run_unittest(test_suite()) diff --git a/Lib/distutils/tests/test_sysconfig.py b/Lib/distutils/tests/test_sysconfig.py deleted file mode 100644 index 6833d22a..00000000 --- a/Lib/distutils/tests/test_sysconfig.py +++ /dev/null @@ -1,264 +0,0 @@ -"""Tests for distutils.sysconfig.""" -import contextlib -import os -import shutil -import subprocess -import sys -import textwrap -import unittest - -from distutils import sysconfig -from distutils.ccompiler import get_default_compiler -from distutils.tests import support -from test.support import run_unittest, swap_item, requires_subprocess, is_wasi -from test.support.os_helper import TESTFN -from test.support.warnings_helper import check_warnings - - -class SysconfigTestCase(support.EnvironGuard, unittest.TestCase): - def setUp(self): - super(SysconfigTestCase, self).setUp() - self.makefile = None - - def tearDown(self): - if self.makefile is not None: - os.unlink(self.makefile) - self.cleanup_testfn() - super(SysconfigTestCase, self).tearDown() - - def cleanup_testfn(self): - if os.path.isfile(TESTFN): - os.remove(TESTFN) - elif os.path.isdir(TESTFN): - shutil.rmtree(TESTFN) - - @unittest.skipIf(is_wasi, "Incompatible with WASI mapdir and OOT builds") - def test_get_config_h_filename(self): - config_h = sysconfig.get_config_h_filename() - self.assertTrue(os.path.isfile(config_h), config_h) - - def test_get_python_lib(self): - # XXX doesn't work on Linux when Python was never installed before - #self.assertTrue(os.path.isdir(lib_dir), lib_dir) - # test for pythonxx.lib? - self.assertNotEqual(sysconfig.get_python_lib(), - sysconfig.get_python_lib(prefix=TESTFN)) - - def test_get_config_vars(self): - cvars = sysconfig.get_config_vars() - self.assertIsInstance(cvars, dict) - self.assertTrue(cvars) - - @unittest.skipIf(is_wasi, "Incompatible with WASI mapdir and OOT builds") - def test_srcdir(self): - # See Issues #15322, #15364. - srcdir = sysconfig.get_config_var('srcdir') - - self.assertTrue(os.path.isabs(srcdir), srcdir) - self.assertTrue(os.path.isdir(srcdir), srcdir) - - if sysconfig.python_build: - # The python executable has not been installed so srcdir - # should be a full source checkout. - Python_h = os.path.join(srcdir, 'Include', 'Python.h') - self.assertTrue(os.path.exists(Python_h), Python_h) - # <srcdir>/PC/pyconfig.h always exists even if unused on POSIX. - pyconfig_h = os.path.join(srcdir, 'PC', 'pyconfig.h') - self.assertTrue(os.path.exists(pyconfig_h), pyconfig_h) - pyconfig_h_in = os.path.join(srcdir, 'pyconfig.h.in') - self.assertTrue(os.path.exists(pyconfig_h_in), pyconfig_h_in) - elif os.name == 'posix': - self.assertEqual( - os.path.dirname(sysconfig.get_makefile_filename()), - srcdir) - - def test_srcdir_independent_of_cwd(self): - # srcdir should be independent of the current working directory - # See Issues #15322, #15364. - srcdir = sysconfig.get_config_var('srcdir') - cwd = os.getcwd() - try: - os.chdir('..') - srcdir2 = sysconfig.get_config_var('srcdir') - finally: - os.chdir(cwd) - self.assertEqual(srcdir, srcdir2) - - def customize_compiler(self): - # make sure AR gets caught - class compiler: - compiler_type = 'unix' - - def set_executables(self, **kw): - self.exes = kw - - sysconfig_vars = { - 'AR': 'sc_ar', - 'CC': 'sc_cc', - 'CXX': 'sc_cxx', - 'ARFLAGS': '--sc-arflags', - 'CFLAGS': '--sc-cflags', - 'CCSHARED': '--sc-ccshared', - 'LDSHARED': 'sc_ldshared', - 'SHLIB_SUFFIX': 'sc_shutil_suffix', - - # On macOS, disable _osx_support.customize_compiler() - 'CUSTOMIZED_OSX_COMPILER': 'True', - } - - comp = compiler() - with contextlib.ExitStack() as cm: - for key, value in sysconfig_vars.items(): - cm.enter_context(swap_item(sysconfig._config_vars, key, value)) - sysconfig.customize_compiler(comp) - - return comp - - @unittest.skipUnless(get_default_compiler() == 'unix', - 'not testing if default compiler is not unix') - def test_customize_compiler(self): - # Make sure that sysconfig._config_vars is initialized - sysconfig.get_config_vars() - - os.environ['AR'] = 'env_ar' - os.environ['CC'] = 'env_cc' - os.environ['CPP'] = 'env_cpp' - os.environ['CXX'] = 'env_cxx --env-cxx-flags' - os.environ['LDSHARED'] = 'env_ldshared' - os.environ['LDFLAGS'] = '--env-ldflags' - os.environ['ARFLAGS'] = '--env-arflags' - os.environ['CFLAGS'] = '--env-cflags' - os.environ['CPPFLAGS'] = '--env-cppflags' - - comp = self.customize_compiler() - self.assertEqual(comp.exes['archiver'], - 'env_ar --env-arflags') - self.assertEqual(comp.exes['preprocessor'], - 'env_cpp --env-cppflags') - self.assertEqual(comp.exes['compiler'], - 'env_cc --sc-cflags --env-cflags --env-cppflags') - self.assertEqual(comp.exes['compiler_so'], - ('env_cc --sc-cflags ' - '--env-cflags ''--env-cppflags --sc-ccshared')) - self.assertEqual(comp.exes['compiler_cxx'], - 'env_cxx --env-cxx-flags') - self.assertEqual(comp.exes['linker_exe'], - 'env_cc') - self.assertEqual(comp.exes['linker_so'], - ('env_ldshared --env-ldflags --env-cflags' - ' --env-cppflags')) - self.assertEqual(comp.shared_lib_extension, 'sc_shutil_suffix') - - del os.environ['AR'] - del os.environ['CC'] - del os.environ['CPP'] - del os.environ['CXX'] - del os.environ['LDSHARED'] - del os.environ['LDFLAGS'] - del os.environ['ARFLAGS'] - del os.environ['CFLAGS'] - del os.environ['CPPFLAGS'] - - comp = self.customize_compiler() - self.assertEqual(comp.exes['archiver'], - 'sc_ar --sc-arflags') - self.assertEqual(comp.exes['preprocessor'], - 'sc_cc -E') - self.assertEqual(comp.exes['compiler'], - 'sc_cc --sc-cflags') - self.assertEqual(comp.exes['compiler_so'], - 'sc_cc --sc-cflags --sc-ccshared') - self.assertEqual(comp.exes['compiler_cxx'], - 'sc_cxx') - self.assertEqual(comp.exes['linker_exe'], - 'sc_cc') - self.assertEqual(comp.exes['linker_so'], - 'sc_ldshared') - self.assertEqual(comp.shared_lib_extension, 'sc_shutil_suffix') - - def test_parse_makefile_base(self): - self.makefile = TESTFN - fd = open(self.makefile, 'w') - try: - fd.write(r"CONFIG_ARGS= '--arg1=optarg1' 'ENV=LIB'" '\n') - fd.write('VAR=$OTHER\nOTHER=foo') - finally: - fd.close() - d = sysconfig.parse_makefile(self.makefile) - self.assertEqual(d, {'CONFIG_ARGS': "'--arg1=optarg1' 'ENV=LIB'", - 'OTHER': 'foo'}) - - def test_parse_makefile_literal_dollar(self): - self.makefile = TESTFN - fd = open(self.makefile, 'w') - try: - fd.write(r"CONFIG_ARGS= '--arg1=optarg1' 'ENV=\$$LIB'" '\n') - fd.write('VAR=$OTHER\nOTHER=foo') - finally: - fd.close() - d = sysconfig.parse_makefile(self.makefile) - self.assertEqual(d, {'CONFIG_ARGS': r"'--arg1=optarg1' 'ENV=\$LIB'", - 'OTHER': 'foo'}) - - - def test_sysconfig_module(self): - import sysconfig as global_sysconfig - self.assertEqual(global_sysconfig.get_config_var('CFLAGS'), - sysconfig.get_config_var('CFLAGS')) - self.assertEqual(global_sysconfig.get_config_var('LDFLAGS'), - sysconfig.get_config_var('LDFLAGS')) - - @unittest.skipIf(sysconfig.get_config_var('CUSTOMIZED_OSX_COMPILER'), - 'compiler flags customized') - def test_sysconfig_compiler_vars(self): - # On OS X, binary installers support extension module building on - # various levels of the operating system with differing Xcode - # configurations. This requires customization of some of the - # compiler configuration directives to suit the environment on - # the installed machine. Some of these customizations may require - # running external programs and, so, are deferred until needed by - # the first extension module build. With Python 3.3, only - # the Distutils version of sysconfig is used for extension module - # builds, which happens earlier in the Distutils tests. This may - # cause the following tests to fail since no tests have caused - # the global version of sysconfig to call the customization yet. - # The solution for now is to simply skip this test in this case. - # The longer-term solution is to only have one version of sysconfig. - - import sysconfig as global_sysconfig - if sysconfig.get_config_var('CUSTOMIZED_OSX_COMPILER'): - self.skipTest('compiler flags customized') - self.assertEqual(global_sysconfig.get_config_var('LDSHARED'), - sysconfig.get_config_var('LDSHARED')) - self.assertEqual(global_sysconfig.get_config_var('CC'), - sysconfig.get_config_var('CC')) - - @requires_subprocess() - def test_customize_compiler_before_get_config_vars(self): - # Issue #21923: test that a Distribution compiler - # instance can be called without an explicit call to - # get_config_vars(). - with open(TESTFN, 'w') as f: - f.writelines(textwrap.dedent('''\ - from distutils.core import Distribution - config = Distribution().get_command_obj('config') - # try_compile may pass or it may fail if no compiler - # is found but it should not raise an exception. - rc = config.try_compile('int x;') - ''')) - p = subprocess.Popen([str(sys.executable), TESTFN], - stdout=subprocess.PIPE, - stderr=subprocess.STDOUT, - universal_newlines=True) - outs, errs = p.communicate() - self.assertEqual(0, p.returncode, "Subprocess failed: " + outs) - - -def test_suite(): - suite = unittest.TestSuite() - suite.addTest(unittest.TestLoader().loadTestsFromTestCase(SysconfigTestCase)) - return suite - - -if __name__ == '__main__': - run_unittest(test_suite()) diff --git a/Lib/distutils/tests/test_text_file.py b/Lib/distutils/tests/test_text_file.py deleted file mode 100644 index ebac3d52..00000000 --- a/Lib/distutils/tests/test_text_file.py +++ /dev/null @@ -1,107 +0,0 @@ -"""Tests for distutils.text_file.""" -import os -import unittest -from distutils.text_file import TextFile -from distutils.tests import support -from test.support import run_unittest - -TEST_DATA = """# test file - -line 3 \\ -# intervening comment - continues on next line -""" - -class TextFileTestCase(support.TempdirManager, unittest.TestCase): - - def test_class(self): - # old tests moved from text_file.__main__ - # so they are really called by the buildbots - - # result 1: no fancy options - result1 = ['# test file\n', '\n', 'line 3 \\\n', - '# intervening comment\n', - ' continues on next line\n'] - - # result 2: just strip comments - result2 = ["\n", - "line 3 \\\n", - " continues on next line\n"] - - # result 3: just strip blank lines - result3 = ["# test file\n", - "line 3 \\\n", - "# intervening comment\n", - " continues on next line\n"] - - # result 4: default, strip comments, blank lines, - # and trailing whitespace - result4 = ["line 3 \\", - " continues on next line"] - - # result 5: strip comments and blanks, plus join lines (but don't - # "collapse" joined lines - result5 = ["line 3 continues on next line"] - - # result 6: strip comments and blanks, plus join lines (and - # "collapse" joined lines - result6 = ["line 3 continues on next line"] - - def test_input(count, description, file, expected_result): - result = file.readlines() - self.assertEqual(result, expected_result) - - tmpdir = self.mkdtemp() - filename = os.path.join(tmpdir, "test.txt") - out_file = open(filename, "w") - try: - out_file.write(TEST_DATA) - finally: - out_file.close() - - in_file = TextFile(filename, strip_comments=0, skip_blanks=0, - lstrip_ws=0, rstrip_ws=0) - try: - test_input(1, "no processing", in_file, result1) - finally: - in_file.close() - - in_file = TextFile(filename, strip_comments=1, skip_blanks=0, - lstrip_ws=0, rstrip_ws=0) - try: - test_input(2, "strip comments", in_file, result2) - finally: - in_file.close() - - in_file = TextFile(filename, strip_comments=0, skip_blanks=1, - lstrip_ws=0, rstrip_ws=0) - try: - test_input(3, "strip blanks", in_file, result3) - finally: - in_file.close() - - in_file = TextFile(filename) - try: - test_input(4, "default processing", in_file, result4) - finally: - in_file.close() - - in_file = TextFile(filename, strip_comments=1, skip_blanks=1, - join_lines=1, rstrip_ws=1) - try: - test_input(5, "join lines without collapsing", in_file, result5) - finally: - in_file.close() - - in_file = TextFile(filename, strip_comments=1, skip_blanks=1, - join_lines=1, rstrip_ws=1, collapse_join=1) - try: - test_input(6, "join lines with collapsing", in_file, result6) - finally: - in_file.close() - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(TextFileTestCase) - -if __name__ == "__main__": - run_unittest(test_suite()) diff --git a/Lib/distutils/tests/test_unixccompiler.py b/Lib/distutils/tests/test_unixccompiler.py deleted file mode 100644 index a3484d4f..00000000 --- a/Lib/distutils/tests/test_unixccompiler.py +++ /dev/null @@ -1,145 +0,0 @@ -"""Tests for distutils.unixccompiler.""" -import sys -import unittest -from test.support import run_unittest -from test.support.os_helper import EnvironmentVarGuard - -from distutils import sysconfig -from distutils.unixccompiler import UnixCCompiler - -class UnixCCompilerTestCase(unittest.TestCase): - - def setUp(self): - self._backup_platform = sys.platform - self._backup_get_config_var = sysconfig.get_config_var - self._backup_config_vars = dict(sysconfig._config_vars) - class CompilerWrapper(UnixCCompiler): - def rpath_foo(self): - return self.runtime_library_dir_option('/foo') - self.cc = CompilerWrapper() - - def tearDown(self): - sys.platform = self._backup_platform - sysconfig.get_config_var = self._backup_get_config_var - sysconfig._config_vars.clear() - sysconfig._config_vars.update(self._backup_config_vars) - - @unittest.skipIf(sys.platform == 'win32', "can't test on Windows") - def test_runtime_libdir_option(self): - # Issue#5900 - # - # Ensure RUNPATH is added to extension modules with RPATH if - # GNU ld is used - - # darwin - sys.platform = 'darwin' - self.assertEqual(self.cc.rpath_foo(), '-L/foo') - - # hp-ux - sys.platform = 'hp-ux' - old_gcv = sysconfig.get_config_var - def gcv(v): - return 'xxx' - sysconfig.get_config_var = gcv - self.assertEqual(self.cc.rpath_foo(), ['+s', '-L/foo']) - - def gcv(v): - return 'gcc' - sysconfig.get_config_var = gcv - self.assertEqual(self.cc.rpath_foo(), ['-Wl,+s', '-L/foo']) - - def gcv(v): - return 'g++' - sysconfig.get_config_var = gcv - self.assertEqual(self.cc.rpath_foo(), ['-Wl,+s', '-L/foo']) - - sysconfig.get_config_var = old_gcv - - # GCC GNULD - sys.platform = 'bar' - def gcv(v): - if v == 'CC': - return 'gcc' - elif v == 'GNULD': - return 'yes' - sysconfig.get_config_var = gcv - self.assertEqual(self.cc.rpath_foo(), '-Wl,--enable-new-dtags,-R/foo') - - # GCC non-GNULD - sys.platform = 'bar' - def gcv(v): - if v == 'CC': - return 'gcc' - elif v == 'GNULD': - return 'no' - sysconfig.get_config_var = gcv - self.assertEqual(self.cc.rpath_foo(), '-Wl,-R/foo') - - # GCC GNULD with fully qualified configuration prefix - # see #7617 - sys.platform = 'bar' - def gcv(v): - if v == 'CC': - return 'x86_64-pc-linux-gnu-gcc-4.4.2' - elif v == 'GNULD': - return 'yes' - sysconfig.get_config_var = gcv - self.assertEqual(self.cc.rpath_foo(), '-Wl,--enable-new-dtags,-R/foo') - - # non-GCC GNULD - sys.platform = 'bar' - def gcv(v): - if v == 'CC': - return 'cc' - elif v == 'GNULD': - return 'yes' - sysconfig.get_config_var = gcv - self.assertEqual(self.cc.rpath_foo(), '-R/foo') - - # non-GCC non-GNULD - sys.platform = 'bar' - def gcv(v): - if v == 'CC': - return 'cc' - elif v == 'GNULD': - return 'no' - sysconfig.get_config_var = gcv - self.assertEqual(self.cc.rpath_foo(), '-R/foo') - - @unittest.skipUnless(sys.platform == 'darwin', 'test only relevant for OS X') - def test_osx_cc_overrides_ldshared(self): - # Issue #18080: - # ensure that setting CC env variable also changes default linker - def gcv(v): - if v == 'LDSHARED': - return 'gcc-4.2 -bundle -undefined dynamic_lookup ' - return 'gcc-4.2' - sysconfig.get_config_var = gcv - with EnvironmentVarGuard() as env: - env['CC'] = 'my_cc' - del env['LDSHARED'] - sysconfig.customize_compiler(self.cc) - self.assertEqual(self.cc.linker_so[0], 'my_cc') - - @unittest.skipUnless(sys.platform == 'darwin', 'test only relevant for OS X') - def test_osx_explicit_ldshared(self): - # Issue #18080: - # ensure that setting CC env variable does not change - # explicit LDSHARED setting for linker - def gcv(v): - if v == 'LDSHARED': - return 'gcc-4.2 -bundle -undefined dynamic_lookup ' - return 'gcc-4.2' - sysconfig.get_config_var = gcv - with EnvironmentVarGuard() as env: - env['CC'] = 'my_cc' - env['LDSHARED'] = 'my_ld -bundle -dynamic' - sysconfig.customize_compiler(self.cc) - self.assertEqual(self.cc.linker_so[0], 'my_ld') - - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(UnixCCompilerTestCase) - -if __name__ == "__main__": - run_unittest(test_suite()) diff --git a/Lib/distutils/tests/test_upload.py b/Lib/distutils/tests/test_upload.py deleted file mode 100644 index d6797414..00000000 --- a/Lib/distutils/tests/test_upload.py +++ /dev/null @@ -1,223 +0,0 @@ -"""Tests for distutils.command.upload.""" -import os -import unittest -import unittest.mock as mock -from urllib.error import HTTPError - -from test.support import run_unittest - -from distutils.command import upload as upload_mod -from distutils.command.upload import upload -from distutils.core import Distribution -from distutils.errors import DistutilsError -from distutils.log import ERROR, INFO - -from distutils.tests.test_config import PYPIRC, BasePyPIRCCommandTestCase - -PYPIRC_LONG_PASSWORD = """\ -[distutils] - -index-servers = - server1 - server2 - -[server1] -username:me -password:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - -[server2] -username:meagain -password: secret -realm:acme -repository:http://another.pypi/ -""" - - -PYPIRC_NOPASSWORD = """\ -[distutils] - -index-servers = - server1 - -[server1] -username:me -""" - -class FakeOpen(object): - - def __init__(self, url, msg=None, code=None): - self.url = url - if not isinstance(url, str): - self.req = url - else: - self.req = None - self.msg = msg or 'OK' - self.code = code or 200 - - def getheader(self, name, default=None): - return { - 'content-type': 'text/plain; charset=utf-8', - }.get(name.lower(), default) - - def read(self): - return b'xyzzy' - - def getcode(self): - return self.code - - -class uploadTestCase(BasePyPIRCCommandTestCase): - - def setUp(self): - super(uploadTestCase, self).setUp() - self.old_open = upload_mod.urlopen - upload_mod.urlopen = self._urlopen - self.last_open = None - self.next_msg = None - self.next_code = None - - def tearDown(self): - upload_mod.urlopen = self.old_open - super(uploadTestCase, self).tearDown() - - def _urlopen(self, url): - self.last_open = FakeOpen(url, msg=self.next_msg, code=self.next_code) - return self.last_open - - def test_finalize_options(self): - - # new format - self.write_file(self.rc, PYPIRC) - dist = Distribution() - cmd = upload(dist) - cmd.finalize_options() - for attr, waited in (('username', 'me'), ('password', 'secret'), - ('realm', 'pypi'), - ('repository', 'https://upload.pypi.org/legacy/')): - self.assertEqual(getattr(cmd, attr), waited) - - def test_saved_password(self): - # file with no password - self.write_file(self.rc, PYPIRC_NOPASSWORD) - - # make sure it passes - dist = Distribution() - cmd = upload(dist) - cmd.finalize_options() - self.assertEqual(cmd.password, None) - - # make sure we get it as well, if another command - # initialized it at the dist level - dist.password = 'xxx' - cmd = upload(dist) - cmd.finalize_options() - self.assertEqual(cmd.password, 'xxx') - - def test_upload(self): - tmp = self.mkdtemp() - path = os.path.join(tmp, 'xxx') - self.write_file(path) - command, pyversion, filename = 'xxx', '2.6', path - dist_files = [(command, pyversion, filename)] - self.write_file(self.rc, PYPIRC_LONG_PASSWORD) - - # lets run it - pkg_dir, dist = self.create_dist(dist_files=dist_files) - cmd = upload(dist) - cmd.show_response = 1 - cmd.ensure_finalized() - cmd.run() - - # what did we send ? - headers = dict(self.last_open.req.headers) - self.assertGreaterEqual(int(headers['Content-length']), 2162) - content_type = headers['Content-type'] - self.assertTrue(content_type.startswith('multipart/form-data')) - self.assertEqual(self.last_open.req.get_method(), 'POST') - expected_url = 'https://upload.pypi.org/legacy/' - self.assertEqual(self.last_open.req.get_full_url(), expected_url) - data = self.last_open.req.data - self.assertIn(b'xxx',data) - self.assertIn(b'protocol_version', data) - self.assertIn(b'sha256_digest', data) - self.assertIn( - b'cd2eb0837c9b4c962c22d2ff8b5441b7b45805887f051d39bf133b583baf' - b'6860', - data - ) - if b'md5_digest' in data: - self.assertIn(b'f561aaf6ef0bf14d4208bb46a4ccb3ad', data) - if b'blake2_256_digest' in data: - self.assertIn( - b'b6f289a27d4fe90da63c503bfe0a9b761a8f76bb86148565065f040be' - b'6d1c3044cf7ded78ef800509bccb4b648e507d88dc6383d67642aadcc' - b'ce443f1534330a', - data - ) - - # The PyPI response body was echoed - results = self.get_logs(INFO) - self.assertEqual(results[-1], 75 * '-' + '\nxyzzy\n' + 75 * '-') - - # bpo-32304: archives whose last byte was b'\r' were corrupted due to - # normalization intended for Mac OS 9. - def test_upload_correct_cr(self): - # content that ends with \r should not be modified. - tmp = self.mkdtemp() - path = os.path.join(tmp, 'xxx') - self.write_file(path, content='yy\r') - command, pyversion, filename = 'xxx', '2.6', path - dist_files = [(command, pyversion, filename)] - self.write_file(self.rc, PYPIRC_LONG_PASSWORD) - - # other fields that ended with \r used to be modified, now are - # preserved. - pkg_dir, dist = self.create_dist( - dist_files=dist_files, - description='long description\r' - ) - cmd = upload(dist) - cmd.show_response = 1 - cmd.ensure_finalized() - cmd.run() - - headers = dict(self.last_open.req.headers) - self.assertGreaterEqual(int(headers['Content-length']), 2172) - self.assertIn(b'long description\r', self.last_open.req.data) - - def test_upload_fails(self): - self.next_msg = "Not Found" - self.next_code = 404 - self.assertRaises(DistutilsError, self.test_upload) - - def test_wrong_exception_order(self): - tmp = self.mkdtemp() - path = os.path.join(tmp, 'xxx') - self.write_file(path) - dist_files = [('xxx', '2.6', path)] # command, pyversion, filename - self.write_file(self.rc, PYPIRC_LONG_PASSWORD) - - pkg_dir, dist = self.create_dist(dist_files=dist_files) - tests = [ - (OSError('oserror'), 'oserror', OSError), - (HTTPError('url', 400, 'httperror', {}, None), - 'Upload failed (400): httperror', DistutilsError), - ] - for exception, expected, raised_exception in tests: - with self.subTest(exception=type(exception).__name__): - with mock.patch('distutils.command.upload.urlopen', - new=mock.Mock(side_effect=exception)): - with self.assertRaises(raised_exception): - cmd = upload(dist) - cmd.ensure_finalized() - cmd.run() - results = self.get_logs(ERROR) - self.assertIn(expected, results[-1]) - self.clear_logs() - - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(uploadTestCase) - -if __name__ == "__main__": - run_unittest(test_suite()) diff --git a/Lib/distutils/tests/test_util.py b/Lib/distutils/tests/test_util.py deleted file mode 100644 index f9c223f0..00000000 --- a/Lib/distutils/tests/test_util.py +++ /dev/null @@ -1,313 +0,0 @@ -"""Tests for distutils.util.""" -import os -import sys -import unittest -from copy import copy -from test.support import run_unittest -from unittest import mock - -from distutils.errors import DistutilsPlatformError, DistutilsByteCompileError -from distutils.util import (get_platform, convert_path, change_root, - check_environ, split_quoted, strtobool, - rfc822_escape, byte_compile, - grok_environment_error) -from distutils import util # used to patch _environ_checked -from distutils.sysconfig import get_config_vars -from distutils import sysconfig -from distutils.tests import support -import _osx_support - -class UtilTestCase(support.EnvironGuard, unittest.TestCase): - - def setUp(self): - super(UtilTestCase, self).setUp() - # saving the environment - self.name = os.name - self.platform = sys.platform - self.version = sys.version - self.sep = os.sep - self.join = os.path.join - self.isabs = os.path.isabs - self.splitdrive = os.path.splitdrive - self._config_vars = copy(sysconfig._config_vars) - - # patching os.uname - if hasattr(os, 'uname'): - self.uname = os.uname - self._uname = os.uname() - else: - self.uname = None - self._uname = None - - os.uname = self._get_uname - - def tearDown(self): - # getting back the environment - os.name = self.name - sys.platform = self.platform - sys.version = self.version - os.sep = self.sep - os.path.join = self.join - os.path.isabs = self.isabs - os.path.splitdrive = self.splitdrive - if self.uname is not None: - os.uname = self.uname - else: - del os.uname - sysconfig._config_vars.clear() - sysconfig._config_vars.update(self._config_vars) - super(UtilTestCase, self).tearDown() - - def _set_uname(self, uname): - self._uname = uname - - def _get_uname(self): - return self._uname - - def test_get_platform(self): - - # windows XP, 32bits - os.name = 'nt' - sys.version = ('2.4.4 (#71, Oct 18 2006, 08:34:43) ' - '[MSC v.1310 32 bit (Intel)]') - sys.platform = 'win32' - self.assertEqual(get_platform(), 'win32') - - # windows XP, amd64 - os.name = 'nt' - sys.version = ('2.4.4 (#71, Oct 18 2006, 08:34:43) ' - '[MSC v.1310 32 bit (Amd64)]') - sys.platform = 'win32' - self.assertEqual(get_platform(), 'win-amd64') - - # macbook - os.name = 'posix' - sys.version = ('2.5 (r25:51918, Sep 19 2006, 08:49:13) ' - '\n[GCC 4.0.1 (Apple Computer, Inc. build 5341)]') - sys.platform = 'darwin' - self._set_uname(('Darwin', 'macziade', '8.11.1', - ('Darwin Kernel Version 8.11.1: ' - 'Wed Oct 10 18:23:28 PDT 2007; ' - 'root:xnu-792.25.20~1/RELEASE_I386'), 'i386')) - _osx_support._remove_original_values(get_config_vars()) - get_config_vars()['MACOSX_DEPLOYMENT_TARGET'] = '10.3' - - get_config_vars()['CFLAGS'] = ('-fno-strict-aliasing -DNDEBUG -g ' - '-fwrapv -O3 -Wall -Wstrict-prototypes') - - cursize = sys.maxsize - sys.maxsize = (2 ** 31)-1 - try: - self.assertEqual(get_platform(), 'macosx-10.3-i386') - finally: - sys.maxsize = cursize - - # macbook with fat binaries (fat, universal or fat64) - _osx_support._remove_original_values(get_config_vars()) - get_config_vars()['MACOSX_DEPLOYMENT_TARGET'] = '10.4' - get_config_vars()['CFLAGS'] = ('-arch ppc -arch i386 -isysroot ' - '/Developer/SDKs/MacOSX10.4u.sdk ' - '-fno-strict-aliasing -fno-common ' - '-dynamic -DNDEBUG -g -O3') - - self.assertEqual(get_platform(), 'macosx-10.4-fat') - - _osx_support._remove_original_values(get_config_vars()) - os.environ['MACOSX_DEPLOYMENT_TARGET'] = '10.1' - self.assertEqual(get_platform(), 'macosx-10.4-fat') - - - _osx_support._remove_original_values(get_config_vars()) - get_config_vars()['CFLAGS'] = ('-arch x86_64 -arch i386 -isysroot ' - '/Developer/SDKs/MacOSX10.4u.sdk ' - '-fno-strict-aliasing -fno-common ' - '-dynamic -DNDEBUG -g -O3') - - self.assertEqual(get_platform(), 'macosx-10.4-intel') - - _osx_support._remove_original_values(get_config_vars()) - get_config_vars()['CFLAGS'] = ('-arch x86_64 -arch ppc -arch i386 -isysroot ' - '/Developer/SDKs/MacOSX10.4u.sdk ' - '-fno-strict-aliasing -fno-common ' - '-dynamic -DNDEBUG -g -O3') - self.assertEqual(get_platform(), 'macosx-10.4-fat3') - - _osx_support._remove_original_values(get_config_vars()) - get_config_vars()['CFLAGS'] = ('-arch ppc64 -arch x86_64 -arch ppc -arch i386 -isysroot ' - '/Developer/SDKs/MacOSX10.4u.sdk ' - '-fno-strict-aliasing -fno-common ' - '-dynamic -DNDEBUG -g -O3') - self.assertEqual(get_platform(), 'macosx-10.4-universal') - - _osx_support._remove_original_values(get_config_vars()) - get_config_vars()['CFLAGS'] = ('-arch x86_64 -arch ppc64 -isysroot ' - '/Developer/SDKs/MacOSX10.4u.sdk ' - '-fno-strict-aliasing -fno-common ' - '-dynamic -DNDEBUG -g -O3') - - self.assertEqual(get_platform(), 'macosx-10.4-fat64') - - for arch in ('ppc', 'i386', 'x86_64', 'ppc64'): - _osx_support._remove_original_values(get_config_vars()) - get_config_vars()['CFLAGS'] = ('-arch %s -isysroot ' - '/Developer/SDKs/MacOSX10.4u.sdk ' - '-fno-strict-aliasing -fno-common ' - '-dynamic -DNDEBUG -g -O3'%(arch,)) - - self.assertEqual(get_platform(), 'macosx-10.4-%s'%(arch,)) - - - # linux debian sarge - os.name = 'posix' - sys.version = ('2.3.5 (#1, Jul 4 2007, 17:28:59) ' - '\n[GCC 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)]') - sys.platform = 'linux2' - self._set_uname(('Linux', 'aglae', '2.6.21.1dedibox-r7', - '#1 Mon Apr 30 17:25:38 CEST 2007', 'i686')) - - self.assertEqual(get_platform(), 'linux-i686') - - # XXX more platforms to tests here - - def test_convert_path(self): - # linux/mac - os.sep = '/' - def _join(path): - return '/'.join(path) - os.path.join = _join - - self.assertEqual(convert_path('/home/to/my/stuff'), - '/home/to/my/stuff') - - # win - os.sep = '\\' - def _join(*path): - return '\\'.join(path) - os.path.join = _join - - self.assertRaises(ValueError, convert_path, '/home/to/my/stuff') - self.assertRaises(ValueError, convert_path, 'home/to/my/stuff/') - - self.assertEqual(convert_path('home/to/my/stuff'), - 'home\\to\\my\\stuff') - self.assertEqual(convert_path('.'), - os.curdir) - - def test_change_root(self): - # linux/mac - os.name = 'posix' - def _isabs(path): - return path[0] == '/' - os.path.isabs = _isabs - def _join(*path): - return '/'.join(path) - os.path.join = _join - - self.assertEqual(change_root('/root', '/old/its/here'), - '/root/old/its/here') - self.assertEqual(change_root('/root', 'its/here'), - '/root/its/here') - - # windows - os.name = 'nt' - def _isabs(path): - return path.startswith('c:\\') - os.path.isabs = _isabs - def _splitdrive(path): - if path.startswith('c:'): - return ('', path.replace('c:', '')) - return ('', path) - os.path.splitdrive = _splitdrive - def _join(*path): - return '\\'.join(path) - os.path.join = _join - - self.assertEqual(change_root('c:\\root', 'c:\\old\\its\\here'), - 'c:\\root\\old\\its\\here') - self.assertEqual(change_root('c:\\root', 'its\\here'), - 'c:\\root\\its\\here') - - # BugsBunny os (it's a great os) - os.name = 'BugsBunny' - self.assertRaises(DistutilsPlatformError, - change_root, 'c:\\root', 'its\\here') - - # XXX platforms to be covered: mac - - def test_check_environ(self): - util._environ_checked = 0 - os.environ.pop('HOME', None) - - check_environ() - - self.assertEqual(os.environ['PLAT'], get_platform()) - self.assertEqual(util._environ_checked, 1) - - @unittest.skipUnless(os.name == 'posix', 'specific to posix') - def test_check_environ_getpwuid(self): - util._environ_checked = 0 - os.environ.pop('HOME', None) - - try: - import pwd - except ImportError: - raise unittest.SkipTest("Test requires pwd module.") - - # only set pw_dir field, other fields are not used - result = pwd.struct_passwd((None, None, None, None, None, - '/home/distutils', None)) - with mock.patch.object(pwd, 'getpwuid', return_value=result): - check_environ() - self.assertEqual(os.environ['HOME'], '/home/distutils') - - util._environ_checked = 0 - os.environ.pop('HOME', None) - - # bpo-10496: Catch pwd.getpwuid() error - with mock.patch.object(pwd, 'getpwuid', side_effect=KeyError): - check_environ() - self.assertNotIn('HOME', os.environ) - - def test_split_quoted(self): - self.assertEqual(split_quoted('""one"" "two" \'three\' \\four'), - ['one', 'two', 'three', 'four']) - - def test_strtobool(self): - yes = ('y', 'Y', 'yes', 'True', 't', 'true', 'True', 'On', 'on', '1') - no = ('n', 'no', 'f', 'false', 'off', '0', 'Off', 'No', 'N') - - for y in yes: - self.assertTrue(strtobool(y)) - - for n in no: - self.assertFalse(strtobool(n)) - - def test_rfc822_escape(self): - header = 'I am a\npoor\nlonesome\nheader\n' - res = rfc822_escape(header) - wanted = ('I am a%(8s)spoor%(8s)slonesome%(8s)s' - 'header%(8s)s') % {'8s': '\n'+8*' '} - self.assertEqual(res, wanted) - - def test_dont_write_bytecode(self): - # makes sure byte_compile raise a DistutilsError - # if sys.dont_write_bytecode is True - old_dont_write_bytecode = sys.dont_write_bytecode - sys.dont_write_bytecode = True - try: - self.assertRaises(DistutilsByteCompileError, byte_compile, []) - finally: - sys.dont_write_bytecode = old_dont_write_bytecode - - def test_grok_environment_error(self): - # test obsolete function to ensure backward compat (#4931) - exc = IOError("Unable to find batch file") - msg = grok_environment_error(exc) - self.assertEqual(msg, "error: Unable to find batch file") - - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(UtilTestCase) - -if __name__ == "__main__": - run_unittest(test_suite()) diff --git a/Lib/distutils/tests/test_version.py b/Lib/distutils/tests/test_version.py deleted file mode 100644 index 1563e022..00000000 --- a/Lib/distutils/tests/test_version.py +++ /dev/null @@ -1,87 +0,0 @@ -"""Tests for distutils.version.""" -import unittest -from distutils.version import LooseVersion -from distutils.version import StrictVersion -from test.support import run_unittest - -class VersionTestCase(unittest.TestCase): - - def test_prerelease(self): - version = StrictVersion('1.2.3a1') - self.assertEqual(version.version, (1, 2, 3)) - self.assertEqual(version.prerelease, ('a', 1)) - self.assertEqual(str(version), '1.2.3a1') - - version = StrictVersion('1.2.0') - self.assertEqual(str(version), '1.2') - - def test_cmp_strict(self): - versions = (('1.5.1', '1.5.2b2', -1), - ('161', '3.10a', ValueError), - ('8.02', '8.02', 0), - ('3.4j', '1996.07.12', ValueError), - ('3.2.pl0', '3.1.1.6', ValueError), - ('2g6', '11g', ValueError), - ('0.9', '2.2', -1), - ('1.2.1', '1.2', 1), - ('1.1', '1.2.2', -1), - ('1.2', '1.1', 1), - ('1.2.1', '1.2.2', -1), - ('1.2.2', '1.2', 1), - ('1.2', '1.2.2', -1), - ('0.4.0', '0.4', 0), - ('1.13++', '5.5.kw', ValueError)) - - for v1, v2, wanted in versions: - try: - res = StrictVersion(v1)._cmp(StrictVersion(v2)) - except ValueError: - if wanted is ValueError: - continue - else: - raise AssertionError(("cmp(%s, %s) " - "shouldn't raise ValueError") - % (v1, v2)) - self.assertEqual(res, wanted, - 'cmp(%s, %s) should be %s, got %s' % - (v1, v2, wanted, res)) - res = StrictVersion(v1)._cmp(v2) - self.assertEqual(res, wanted, - 'cmp(%s, %s) should be %s, got %s' % - (v1, v2, wanted, res)) - res = StrictVersion(v1)._cmp(object()) - self.assertIs(res, NotImplemented, - 'cmp(%s, %s) should be NotImplemented, got %s' % - (v1, v2, res)) - - - def test_cmp(self): - versions = (('1.5.1', '1.5.2b2', -1), - ('161', '3.10a', 1), - ('8.02', '8.02', 0), - ('3.4j', '1996.07.12', -1), - ('3.2.pl0', '3.1.1.6', 1), - ('2g6', '11g', -1), - ('0.960923', '2.2beta29', -1), - ('1.13++', '5.5.kw', -1)) - - - for v1, v2, wanted in versions: - res = LooseVersion(v1)._cmp(LooseVersion(v2)) - self.assertEqual(res, wanted, - 'cmp(%s, %s) should be %s, got %s' % - (v1, v2, wanted, res)) - res = LooseVersion(v1)._cmp(v2) - self.assertEqual(res, wanted, - 'cmp(%s, %s) should be %s, got %s' % - (v1, v2, wanted, res)) - res = LooseVersion(v1)._cmp(object()) - self.assertIs(res, NotImplemented, - 'cmp(%s, %s) should be NotImplemented, got %s' % - (v1, v2, res)) - -def test_suite(): - return unittest.TestLoader().loadTestsFromTestCase(VersionTestCase) - -if __name__ == "__main__": - run_unittest(test_suite()) diff --git a/Lib/distutils/tests/test_versionpredicate.py b/Lib/distutils/tests/test_versionpredicate.py deleted file mode 100644 index 28ae09dc..00000000 --- a/Lib/distutils/tests/test_versionpredicate.py +++ /dev/null @@ -1,13 +0,0 @@ -"""Tests harness for distutils.versionpredicate. - -""" - -import distutils.versionpredicate -import doctest -from test.support import run_unittest - -def test_suite(): - return doctest.DocTestSuite(distutils.versionpredicate) - -if __name__ == '__main__': - run_unittest(test_suite()) diff --git a/Lib/distutils/text_file.py b/Lib/distutils/text_file.py deleted file mode 100644 index 93abad38..00000000 --- a/Lib/distutils/text_file.py +++ /dev/null @@ -1,286 +0,0 @@ -"""text_file - -provides the TextFile class, which gives an interface to text files -that (optionally) takes care of stripping comments, ignoring blank -lines, and joining lines with backslashes.""" - -import sys, io - - -class TextFile: - """Provides a file-like object that takes care of all the things you - commonly want to do when processing a text file that has some - line-by-line syntax: strip comments (as long as "#" is your - comment character), skip blank lines, join adjacent lines by - escaping the newline (ie. backslash at end of line), strip - leading and/or trailing whitespace. All of these are optional - and independently controllable. - - Provides a 'warn()' method so you can generate warning messages that - report physical line number, even if the logical line in question - spans multiple physical lines. Also provides 'unreadline()' for - implementing line-at-a-time lookahead. - - Constructor is called as: - - TextFile (filename=None, file=None, **options) - - It bombs (RuntimeError) if both 'filename' and 'file' are None; - 'filename' should be a string, and 'file' a file object (or - something that provides 'readline()' and 'close()' methods). It is - recommended that you supply at least 'filename', so that TextFile - can include it in warning messages. If 'file' is not supplied, - TextFile creates its own using 'io.open()'. - - The options are all boolean, and affect the value returned by - 'readline()': - strip_comments [default: true] - strip from "#" to end-of-line, as well as any whitespace - leading up to the "#" -- unless it is escaped by a backslash - lstrip_ws [default: false] - strip leading whitespace from each line before returning it - rstrip_ws [default: true] - strip trailing whitespace (including line terminator!) from - each line before returning it - skip_blanks [default: true} - skip lines that are empty *after* stripping comments and - whitespace. (If both lstrip_ws and rstrip_ws are false, - then some lines may consist of solely whitespace: these will - *not* be skipped, even if 'skip_blanks' is true.) - join_lines [default: false] - if a backslash is the last non-newline character on a line - after stripping comments and whitespace, join the following line - to it to form one "logical line"; if N consecutive lines end - with a backslash, then N+1 physical lines will be joined to - form one logical line. - collapse_join [default: false] - strip leading whitespace from lines that are joined to their - predecessor; only matters if (join_lines and not lstrip_ws) - errors [default: 'strict'] - error handler used to decode the file content - - Note that since 'rstrip_ws' can strip the trailing newline, the - semantics of 'readline()' must differ from those of the builtin file - object's 'readline()' method! In particular, 'readline()' returns - None for end-of-file: an empty string might just be a blank line (or - an all-whitespace line), if 'rstrip_ws' is true but 'skip_blanks' is - not.""" - - default_options = { 'strip_comments': 1, - 'skip_blanks': 1, - 'lstrip_ws': 0, - 'rstrip_ws': 1, - 'join_lines': 0, - 'collapse_join': 0, - 'errors': 'strict', - } - - def __init__(self, filename=None, file=None, **options): - """Construct a new TextFile object. At least one of 'filename' - (a string) and 'file' (a file-like object) must be supplied. - They keyword argument options are described above and affect - the values returned by 'readline()'.""" - if filename is None and file is None: - raise RuntimeError("you must supply either or both of 'filename' and 'file'") - - # set values for all options -- either from client option hash - # or fallback to default_options - for opt in self.default_options.keys(): - if opt in options: - setattr(self, opt, options[opt]) - else: - setattr(self, opt, self.default_options[opt]) - - # sanity check client option hash - for opt in options.keys(): - if opt not in self.default_options: - raise KeyError("invalid TextFile option '%s'" % opt) - - if file is None: - self.open(filename) - else: - self.filename = filename - self.file = file - self.current_line = 0 # assuming that file is at BOF! - - # 'linebuf' is a stack of lines that will be emptied before we - # actually read from the file; it's only populated by an - # 'unreadline()' operation - self.linebuf = [] - - def open(self, filename): - """Open a new file named 'filename'. This overrides both the - 'filename' and 'file' arguments to the constructor.""" - self.filename = filename - self.file = io.open(self.filename, 'r', errors=self.errors) - self.current_line = 0 - - def close(self): - """Close the current file and forget everything we know about it - (filename, current line number).""" - file = self.file - self.file = None - self.filename = None - self.current_line = None - file.close() - - def gen_error(self, msg, line=None): - outmsg = [] - if line is None: - line = self.current_line - outmsg.append(self.filename + ", ") - if isinstance(line, (list, tuple)): - outmsg.append("lines %d-%d: " % tuple(line)) - else: - outmsg.append("line %d: " % line) - outmsg.append(str(msg)) - return "".join(outmsg) - - def error(self, msg, line=None): - raise ValueError("error: " + self.gen_error(msg, line)) - - def warn(self, msg, line=None): - """Print (to stderr) a warning message tied to the current logical - line in the current file. If the current logical line in the - file spans multiple physical lines, the warning refers to the - whole range, eg. "lines 3-5". If 'line' supplied, it overrides - the current line number; it may be a list or tuple to indicate a - range of physical lines, or an integer for a single physical - line.""" - sys.stderr.write("warning: " + self.gen_error(msg, line) + "\n") - - def readline(self): - """Read and return a single logical line from the current file (or - from an internal buffer if lines have previously been "unread" - with 'unreadline()'). If the 'join_lines' option is true, this - may involve reading multiple physical lines concatenated into a - single string. Updates the current line number, so calling - 'warn()' after 'readline()' emits a warning about the physical - line(s) just read. Returns None on end-of-file, since the empty - string can occur if 'rstrip_ws' is true but 'strip_blanks' is - not.""" - # If any "unread" lines waiting in 'linebuf', return the top - # one. (We don't actually buffer read-ahead data -- lines only - # get put in 'linebuf' if the client explicitly does an - # 'unreadline()'. - if self.linebuf: - line = self.linebuf[-1] - del self.linebuf[-1] - return line - - buildup_line = '' - - while True: - # read the line, make it None if EOF - line = self.file.readline() - if line == '': - line = None - - if self.strip_comments and line: - - # Look for the first "#" in the line. If none, never - # mind. If we find one and it's the first character, or - # is not preceded by "\", then it starts a comment -- - # strip the comment, strip whitespace before it, and - # carry on. Otherwise, it's just an escaped "#", so - # unescape it (and any other escaped "#"'s that might be - # lurking in there) and otherwise leave the line alone. - - pos = line.find("#") - if pos == -1: # no "#" -- no comments - pass - - # It's definitely a comment -- either "#" is the first - # character, or it's elsewhere and unescaped. - elif pos == 0 or line[pos-1] != "\\": - # Have to preserve the trailing newline, because it's - # the job of a later step (rstrip_ws) to remove it -- - # and if rstrip_ws is false, we'd better preserve it! - # (NB. this means that if the final line is all comment - # and has no trailing newline, we will think that it's - # EOF; I think that's OK.) - eol = (line[-1] == '\n') and '\n' or '' - line = line[0:pos] + eol - - # If all that's left is whitespace, then skip line - # *now*, before we try to join it to 'buildup_line' -- - # that way constructs like - # hello \\ - # # comment that should be ignored - # there - # result in "hello there". - if line.strip() == "": - continue - else: # it's an escaped "#" - line = line.replace("\\#", "#") - - # did previous line end with a backslash? then accumulate - if self.join_lines and buildup_line: - # oops: end of file - if line is None: - self.warn("continuation line immediately precedes " - "end-of-file") - return buildup_line - - if self.collapse_join: - line = line.lstrip() - line = buildup_line + line - - # careful: pay attention to line number when incrementing it - if isinstance(self.current_line, list): - self.current_line[1] = self.current_line[1] + 1 - else: - self.current_line = [self.current_line, - self.current_line + 1] - # just an ordinary line, read it as usual - else: - if line is None: # eof - return None - - # still have to be careful about incrementing the line number! - if isinstance(self.current_line, list): - self.current_line = self.current_line[1] + 1 - else: - self.current_line = self.current_line + 1 - - # strip whitespace however the client wants (leading and - # trailing, or one or the other, or neither) - if self.lstrip_ws and self.rstrip_ws: - line = line.strip() - elif self.lstrip_ws: - line = line.lstrip() - elif self.rstrip_ws: - line = line.rstrip() - - # blank line (whether we rstrip'ed or not)? skip to next line - # if appropriate - if (line == '' or line == '\n') and self.skip_blanks: - continue - - if self.join_lines: - if line[-1] == '\\': - buildup_line = line[:-1] - continue - - if line[-2:] == '\\\n': - buildup_line = line[0:-2] + '\n' - continue - - # well, I guess there's some actual content there: return it - return line - - def readlines(self): - """Read and return the list of all logical lines remaining in the - current file.""" - lines = [] - while True: - line = self.readline() - if line is None: - return lines - lines.append(line) - - def unreadline(self, line): - """Push 'line' (a string) onto an internal buffer that will be - checked by future 'readline()' calls. Handy for implementing - a parser with line-at-a-time lookahead.""" - self.linebuf.append(line) diff --git a/Lib/distutils/unixccompiler.py b/Lib/distutils/unixccompiler.py deleted file mode 100644 index d00c4898..00000000 --- a/Lib/distutils/unixccompiler.py +++ /dev/null @@ -1,329 +0,0 @@ -"""distutils.unixccompiler - -Contains the UnixCCompiler class, a subclass of CCompiler that handles -the "typical" Unix-style command-line C compiler: - * macros defined with -Dname[=value] - * macros undefined with -Uname - * include search directories specified with -Idir - * libraries specified with -lllib - * library search directories specified with -Ldir - * compile handled by 'cc' (or similar) executable with -c option: - compiles .c to .o - * link static library handled by 'ar' command (possibly with 'ranlib') - * link shared library handled by 'cc -shared' -""" - -import os, sys, re - -from distutils import sysconfig -from distutils.dep_util import newer -from distutils.ccompiler import \ - CCompiler, gen_preprocess_options, gen_lib_options -from distutils.errors import \ - DistutilsExecError, CompileError, LibError, LinkError -from distutils import log - -if sys.platform == 'darwin': - import _osx_support - -# XXX Things not currently handled: -# * optimization/debug/warning flags; we just use whatever's in Python's -# Makefile and live with it. Is this adequate? If not, we might -# have to have a bunch of subclasses GNUCCompiler, SGICCompiler, -# SunCCompiler, and I suspect down that road lies madness. -# * even if we don't know a warning flag from an optimization flag, -# we need some way for outsiders to feed preprocessor/compiler/linker -# flags in to us -- eg. a sysadmin might want to mandate certain flags -# via a site config file, or a user might want to set something for -# compiling this module distribution only via the setup.py command -# line, whatever. As long as these options come from something on the -# current system, they can be as system-dependent as they like, and we -# should just happily stuff them into the preprocessor/compiler/linker -# options and carry on. - - -class UnixCCompiler(CCompiler): - - compiler_type = 'unix' - - # These are used by CCompiler in two places: the constructor sets - # instance attributes 'preprocessor', 'compiler', etc. from them, and - # 'set_executable()' allows any of these to be set. The defaults here - # are pretty generic; they will probably have to be set by an outsider - # (eg. using information discovered by the sysconfig about building - # Python extensions). - executables = {'preprocessor' : None, - 'compiler' : ["cc"], - 'compiler_so' : ["cc"], - 'compiler_cxx' : ["cc"], - 'linker_so' : ["cc", "-shared"], - 'linker_exe' : ["cc"], - 'archiver' : ["ar", "-cr"], - 'ranlib' : None, - } - - if sys.platform[:6] == "darwin": - executables['ranlib'] = ["ranlib"] - - # Needed for the filename generation methods provided by the base - # class, CCompiler. NB. whoever instantiates/uses a particular - # UnixCCompiler instance should set 'shared_lib_ext' -- we set a - # reasonable common default here, but it's not necessarily used on all - # Unices! - - src_extensions = [".c",".C",".cc",".cxx",".cpp",".m"] - obj_extension = ".o" - static_lib_extension = ".a" - shared_lib_extension = ".so" - dylib_lib_extension = ".dylib" - xcode_stub_lib_extension = ".tbd" - static_lib_format = shared_lib_format = dylib_lib_format = "lib%s%s" - xcode_stub_lib_format = dylib_lib_format - if sys.platform == "cygwin": - exe_extension = ".exe" - - def preprocess(self, source, output_file=None, macros=None, - include_dirs=None, extra_preargs=None, extra_postargs=None): - fixed_args = self._fix_compile_args(None, macros, include_dirs) - ignore, macros, include_dirs = fixed_args - pp_opts = gen_preprocess_options(macros, include_dirs) - pp_args = self.preprocessor + pp_opts - if output_file: - pp_args.extend(['-o', output_file]) - if extra_preargs: - pp_args[:0] = extra_preargs - if extra_postargs: - pp_args.extend(extra_postargs) - pp_args.append(source) - - # We need to preprocess: either we're being forced to, or we're - # generating output to stdout, or there's a target output file and - # the source file is newer than the target (or the target doesn't - # exist). - if self.force or output_file is None or newer(source, output_file): - if output_file: - self.mkpath(os.path.dirname(output_file)) - try: - self.spawn(pp_args) - except DistutilsExecError as msg: - raise CompileError(msg) - - def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts): - compiler_so = self.compiler_so - if sys.platform == 'darwin': - compiler_so = _osx_support.compiler_fixup(compiler_so, - cc_args + extra_postargs) - try: - self.spawn(compiler_so + cc_args + [src, '-o', obj] + - extra_postargs) - except DistutilsExecError as msg: - raise CompileError(msg) - - def create_static_lib(self, objects, output_libname, - output_dir=None, debug=0, target_lang=None): - objects, output_dir = self._fix_object_args(objects, output_dir) - - output_filename = \ - self.library_filename(output_libname, output_dir=output_dir) - - if self._need_link(objects, output_filename): - self.mkpath(os.path.dirname(output_filename)) - self.spawn(self.archiver + - [output_filename] + - objects + self.objects) - - # Not many Unices required ranlib anymore -- SunOS 4.x is, I - # think the only major Unix that does. Maybe we need some - # platform intelligence here to skip ranlib if it's not - # needed -- or maybe Python's configure script took care of - # it for us, hence the check for leading colon. - if self.ranlib: - try: - self.spawn(self.ranlib + [output_filename]) - except DistutilsExecError as msg: - raise LibError(msg) - else: - log.debug("skipping %s (up-to-date)", output_filename) - - def link(self, target_desc, objects, - output_filename, output_dir=None, libraries=None, - library_dirs=None, runtime_library_dirs=None, - export_symbols=None, debug=0, extra_preargs=None, - extra_postargs=None, build_temp=None, target_lang=None): - objects, output_dir = self._fix_object_args(objects, output_dir) - fixed_args = self._fix_lib_args(libraries, library_dirs, - runtime_library_dirs) - libraries, library_dirs, runtime_library_dirs = fixed_args - - lib_opts = gen_lib_options(self, library_dirs, runtime_library_dirs, - libraries) - if not isinstance(output_dir, (str, type(None))): - raise TypeError("'output_dir' must be a string or None") - if output_dir is not None: - output_filename = os.path.join(output_dir, output_filename) - - if self._need_link(objects, output_filename): - ld_args = (objects + self.objects + - lib_opts + ['-o', output_filename]) - if debug: - ld_args[:0] = ['-g'] - if extra_preargs: - ld_args[:0] = extra_preargs - if extra_postargs: - ld_args.extend(extra_postargs) - self.mkpath(os.path.dirname(output_filename)) - try: - if target_desc == CCompiler.EXECUTABLE: - linker = self.linker_exe[:] - else: - linker = self.linker_so[:] - if target_lang == "c++" and self.compiler_cxx: - # skip over environment variable settings if /usr/bin/env - # is used to set up the linker's environment. - # This is needed on OSX. Note: this assumes that the - # normal and C++ compiler have the same environment - # settings. - i = 0 - if os.path.basename(linker[0]) == "env": - i = 1 - while '=' in linker[i]: - i += 1 - - if os.path.basename(linker[i]) == 'ld_so_aix': - # AIX platforms prefix the compiler with the ld_so_aix - # script, so we need to adjust our linker index - offset = 1 - else: - offset = 0 - - linker[i+offset] = self.compiler_cxx[i] - - if sys.platform == 'darwin': - linker = _osx_support.compiler_fixup(linker, ld_args) - - self.spawn(linker + ld_args) - except DistutilsExecError as msg: - raise LinkError(msg) - else: - log.debug("skipping %s (up-to-date)", output_filename) - - # -- Miscellaneous methods ----------------------------------------- - # These are all used by the 'gen_lib_options() function, in - # ccompiler.py. - - def library_dir_option(self, dir): - return "-L" + dir - - def _is_gcc(self, compiler_name): - # clang uses same syntax for rpath as gcc - return any(name in compiler_name for name in ("gcc", "g++", "clang")) - - def runtime_library_dir_option(self, dir): - # XXX Hackish, at the very least. See Python bug #445902: - # http://sourceforge.net/tracker/index.php - # ?func=detail&aid=445902&group_id=5470&atid=105470 - # Linkers on different platforms need different options to - # specify that directories need to be added to the list of - # directories searched for dependencies when a dynamic library - # is sought. GCC on GNU systems (Linux, FreeBSD, ...) has to - # be told to pass the -R option through to the linker, whereas - # other compilers and gcc on other systems just know this. - # Other compilers may need something slightly different. At - # this time, there's no way to determine this information from - # the configuration data stored in the Python installation, so - # we use this hack. - compiler = os.path.basename(sysconfig.get_config_var("CC")) - if sys.platform[:6] == "darwin": - # MacOSX's linker doesn't understand the -R flag at all - return "-L" + dir - elif sys.platform[:7] == "freebsd": - return "-Wl,-rpath=" + dir - elif sys.platform[:5] == "hp-ux": - if self._is_gcc(compiler): - return ["-Wl,+s", "-L" + dir] - return ["+s", "-L" + dir] - else: - if self._is_gcc(compiler): - # gcc on non-GNU systems does not need -Wl, but can - # use it anyway. Since distutils has always passed in - # -Wl whenever gcc was used in the past it is probably - # safest to keep doing so. - if sysconfig.get_config_var("GNULD") == "yes": - # GNU ld needs an extra option to get a RUNPATH - # instead of just an RPATH. - return "-Wl,--enable-new-dtags,-R" + dir - else: - return "-Wl,-R" + dir - else: - # No idea how --enable-new-dtags would be passed on to - # ld if this system was using GNU ld. Don't know if a - # system like this even exists. - return "-R" + dir - - def library_option(self, lib): - return "-l" + lib - - def find_library_file(self, dirs, lib, debug=0): - shared_f = self.library_filename(lib, lib_type='shared') - dylib_f = self.library_filename(lib, lib_type='dylib') - xcode_stub_f = self.library_filename(lib, lib_type='xcode_stub') - static_f = self.library_filename(lib, lib_type='static') - - if sys.platform == 'darwin': - # On OSX users can specify an alternate SDK using - # '-isysroot', calculate the SDK root if it is specified - # (and use it further on) - # - # Note that, as of Xcode 7, Apple SDKs may contain textual stub - # libraries with .tbd extensions rather than the normal .dylib - # shared libraries installed in /. The Apple compiler tool - # chain handles this transparently but it can cause problems - # for programs that are being built with an SDK and searching - # for specific libraries. Callers of find_library_file need to - # keep in mind that the base filename of the returned SDK library - # file might have a different extension from that of the library - # file installed on the running system, for example: - # /Applications/Xcode.app/Contents/Developer/Platforms/ - # MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/ - # usr/lib/libedit.tbd - # vs - # /usr/lib/libedit.dylib - cflags = sysconfig.get_config_var('CFLAGS') - m = re.search(r'-isysroot\s*(\S+)', cflags) - if m is None: - sysroot = _osx_support._default_sysroot(sysconfig.get_config_var('CC')) - else: - sysroot = m.group(1) - - - - for dir in dirs: - shared = os.path.join(dir, shared_f) - dylib = os.path.join(dir, dylib_f) - static = os.path.join(dir, static_f) - xcode_stub = os.path.join(dir, xcode_stub_f) - - if sys.platform == 'darwin' and ( - dir.startswith('/System/') or ( - dir.startswith('/usr/') and not dir.startswith('/usr/local/'))): - - shared = os.path.join(sysroot, dir[1:], shared_f) - dylib = os.path.join(sysroot, dir[1:], dylib_f) - static = os.path.join(sysroot, dir[1:], static_f) - xcode_stub = os.path.join(sysroot, dir[1:], xcode_stub_f) - - # We're second-guessing the linker here, with not much hard - # data to go on: GCC seems to prefer the shared library, so I'm - # assuming that *all* Unix C compilers do. And of course I'm - # ignoring even GCC's "-static" option. So sue me. - if os.path.exists(dylib): - return dylib - elif os.path.exists(xcode_stub): - return xcode_stub - elif os.path.exists(shared): - return shared - elif os.path.exists(static): - return static - - # Oops, didn't find it in *any* of 'dirs' - return None diff --git a/Lib/distutils/util.py b/Lib/distutils/util.py deleted file mode 100644 index 2ce5c5b6..00000000 --- a/Lib/distutils/util.py +++ /dev/null @@ -1,562 +0,0 @@ -"""distutils.util - -Miscellaneous utility functions -- anything that doesn't fit into -one of the other *util.py modules. -""" - -import os -import re -import importlib.util -import string -import sys -import distutils -from distutils.errors import DistutilsPlatformError -from distutils.dep_util import newer -from distutils.spawn import spawn -from distutils import log -from distutils.errors import DistutilsByteCompileError - -def get_host_platform(): - """Return a string that identifies the current platform. This is used mainly to - distinguish platform-specific build directories and platform-specific built - distributions. Typically includes the OS name and version and the - architecture (as supplied by 'os.uname()'), although the exact information - included depends on the OS; eg. on Linux, the kernel version isn't - particularly important. - - Examples of returned values: - linux-i586 - linux-alpha (?) - solaris-2.6-sun4u - - Windows will return one of: - win-amd64 (64bit Windows on AMD64 (aka x86_64, Intel64, EM64T, etc) - win32 (all others - specifically, sys.platform is returned) - - For other non-POSIX platforms, currently just returns 'sys.platform'. - - """ - if os.name == 'nt': - if 'amd64' in sys.version.lower(): - return 'win-amd64' - if '(arm)' in sys.version.lower(): - return 'win-arm32' - if '(arm64)' in sys.version.lower(): - return 'win-arm64' - return sys.platform - - # Set for cross builds explicitly - if "_PYTHON_HOST_PLATFORM" in os.environ: - return os.environ["_PYTHON_HOST_PLATFORM"] - - if os.name != "posix" or not hasattr(os, 'uname'): - # XXX what about the architecture? NT is Intel or Alpha, - # Mac OS is M68k or PPC, etc. - return sys.platform - - # Try to distinguish various flavours of Unix - - (osname, host, release, version, machine) = os.uname() - - # Convert the OS name to lowercase, remove '/' characters, and translate - # spaces (for "Power Macintosh") - osname = osname.lower().replace('/', '') - machine = machine.replace(' ', '_') - machine = machine.replace('/', '-') - - if osname[:5] == "linux": - # At least on Linux/Intel, 'machine' is the processor -- - # i386, etc. - # XXX what about Alpha, SPARC, etc? - return "%s-%s" % (osname, machine) - elif osname[:5] == "sunos": - if release[0] >= "5": # SunOS 5 == Solaris 2 - osname = "solaris" - release = "%d.%s" % (int(release[0]) - 3, release[2:]) - # We can't use "platform.architecture()[0]" because a - # bootstrap problem. We use a dict to get an error - # if some suspicious happens. - bitness = {2147483647:"32bit", 9223372036854775807:"64bit"} - machine += ".%s" % bitness[sys.maxsize] - # fall through to standard osname-release-machine representation - elif osname[:3] == "aix": - from _aix_support import aix_platform - return aix_platform() - elif osname[:6] == "cygwin": - osname = "cygwin" - rel_re = re.compile (r'[\d.]+', re.ASCII) - m = rel_re.match(release) - if m: - release = m.group() - elif osname[:6] == "darwin": - import _osx_support, distutils.sysconfig - osname, release, machine = _osx_support.get_platform_osx( - distutils.sysconfig.get_config_vars(), - osname, release, machine) - - return "%s-%s-%s" % (osname, release, machine) - -def get_platform(): - if os.name == 'nt': - TARGET_TO_PLAT = { - 'x86' : 'win32', - 'x64' : 'win-amd64', - 'arm' : 'win-arm32', - } - return TARGET_TO_PLAT.get(os.environ.get('VSCMD_ARG_TGT_ARCH')) or get_host_platform() - else: - return get_host_platform() - -def convert_path (pathname): - """Return 'pathname' as a name that will work on the native filesystem, - i.e. split it on '/' and put it back together again using the current - directory separator. Needed because filenames in the setup script are - always supplied in Unix style, and have to be converted to the local - convention before we can actually use them in the filesystem. Raises - ValueError on non-Unix-ish systems if 'pathname' either starts or - ends with a slash. - """ - if os.sep == '/': - return pathname - if not pathname: - return pathname - if pathname[0] == '/': - raise ValueError("path '%s' cannot be absolute" % pathname) - if pathname[-1] == '/': - raise ValueError("path '%s' cannot end with '/'" % pathname) - - paths = pathname.split('/') - while '.' in paths: - paths.remove('.') - if not paths: - return os.curdir - return os.path.join(*paths) - -# convert_path () - - -def change_root (new_root, pathname): - """Return 'pathname' with 'new_root' prepended. If 'pathname' is - relative, this is equivalent to "os.path.join(new_root,pathname)". - Otherwise, it requires making 'pathname' relative and then joining the - two, which is tricky on DOS/Windows and Mac OS. - """ - if os.name == 'posix': - if not os.path.isabs(pathname): - return os.path.join(new_root, pathname) - else: - return os.path.join(new_root, pathname[1:]) - - elif os.name == 'nt': - (drive, path) = os.path.splitdrive(pathname) - if path[0] == '\\': - path = path[1:] - return os.path.join(new_root, path) - - else: - raise DistutilsPlatformError("nothing known about platform '%s'" % os.name) - - -_environ_checked = 0 -def check_environ (): - """Ensure that 'os.environ' has all the environment variables we - guarantee that users can use in config files, command-line options, - etc. Currently this includes: - HOME - user's home directory (Unix only) - PLAT - description of the current platform, including hardware - and OS (see 'get_platform()') - """ - global _environ_checked - if _environ_checked: - return - - if os.name == 'posix' and 'HOME' not in os.environ: - try: - import pwd - os.environ['HOME'] = pwd.getpwuid(os.getuid())[5] - except (ImportError, KeyError): - # bpo-10496: if the current user identifier doesn't exist in the - # password database, do nothing - pass - - if 'PLAT' not in os.environ: - os.environ['PLAT'] = get_platform() - - _environ_checked = 1 - - -def subst_vars (s, local_vars): - """Perform shell/Perl-style variable substitution on 'string'. Every - occurrence of '$' followed by a name is considered a variable, and - variable is substituted by the value found in the 'local_vars' - dictionary, or in 'os.environ' if it's not in 'local_vars'. - 'os.environ' is first checked/augmented to guarantee that it contains - certain values: see 'check_environ()'. Raise ValueError for any - variables not found in either 'local_vars' or 'os.environ'. - """ - check_environ() - def _subst (match, local_vars=local_vars): - var_name = match.group(1) - if var_name in local_vars: - return str(local_vars[var_name]) - else: - return os.environ[var_name] - - try: - return re.sub(r'\$([a-zA-Z_][a-zA-Z_0-9]*)', _subst, s) - except KeyError as var: - raise ValueError("invalid variable '$%s'" % var) - -# subst_vars () - - -def grok_environment_error (exc, prefix="error: "): - # Function kept for backward compatibility. - # Used to try clever things with EnvironmentErrors, - # but nowadays str(exception) produces good messages. - return prefix + str(exc) - - -# Needed by 'split_quoted()' -_wordchars_re = _squote_re = _dquote_re = None -def _init_regex(): - global _wordchars_re, _squote_re, _dquote_re - _wordchars_re = re.compile(r'[^\\\'\"%s ]*' % string.whitespace) - _squote_re = re.compile(r"'(?:[^'\\]|\\.)*'") - _dquote_re = re.compile(r'"(?:[^"\\]|\\.)*"') - -def split_quoted (s): - """Split a string up according to Unix shell-like rules for quotes and - backslashes. In short: words are delimited by spaces, as long as those - spaces are not escaped by a backslash, or inside a quoted string. - Single and double quotes are equivalent, and the quote characters can - be backslash-escaped. The backslash is stripped from any two-character - escape sequence, leaving only the escaped character. The quote - characters are stripped from any quoted string. Returns a list of - words. - """ - - # This is a nice algorithm for splitting up a single string, since it - # doesn't require character-by-character examination. It was a little - # bit of a brain-bender to get it working right, though... - if _wordchars_re is None: _init_regex() - - s = s.strip() - words = [] - pos = 0 - - while s: - m = _wordchars_re.match(s, pos) - end = m.end() - if end == len(s): - words.append(s[:end]) - break - - if s[end] in string.whitespace: # unescaped, unquoted whitespace: now - words.append(s[:end]) # we definitely have a word delimiter - s = s[end:].lstrip() - pos = 0 - - elif s[end] == '\\': # preserve whatever is being escaped; - # will become part of the current word - s = s[:end] + s[end+1:] - pos = end+1 - - else: - if s[end] == "'": # slurp singly-quoted string - m = _squote_re.match(s, end) - elif s[end] == '"': # slurp doubly-quoted string - m = _dquote_re.match(s, end) - else: - raise RuntimeError("this can't happen (bad char '%c')" % s[end]) - - if m is None: - raise ValueError("bad string (mismatched %s quotes?)" % s[end]) - - (beg, end) = m.span() - s = s[:beg] + s[beg+1:end-1] + s[end:] - pos = m.end() - 2 - - if pos >= len(s): - words.append(s) - break - - return words - -# split_quoted () - - -def execute (func, args, msg=None, verbose=0, dry_run=0): - """Perform some action that affects the outside world (eg. by - writing to the filesystem). Such actions are special because they - are disabled by the 'dry_run' flag. This method takes care of all - that bureaucracy for you; all you have to do is supply the - function to call and an argument tuple for it (to embody the - "external action" being performed), and an optional message to - print. - """ - if msg is None: - msg = "%s%r" % (func.__name__, args) - if msg[-2:] == ',)': # correct for singleton tuple - msg = msg[0:-2] + ')' - - log.info(msg) - if not dry_run: - func(*args) - - -def strtobool (val): - """Convert a string representation of truth to true (1) or false (0). - - True values are 'y', 'yes', 't', 'true', 'on', and '1'; false values - are 'n', 'no', 'f', 'false', 'off', and '0'. Raises ValueError if - 'val' is anything else. - """ - val = val.lower() - if val in ('y', 'yes', 't', 'true', 'on', '1'): - return 1 - elif val in ('n', 'no', 'f', 'false', 'off', '0'): - return 0 - else: - raise ValueError("invalid truth value %r" % (val,)) - - -def byte_compile (py_files, - optimize=0, force=0, - prefix=None, base_dir=None, - verbose=1, dry_run=0, - direct=None): - """Byte-compile a collection of Python source files to .pyc - files in a __pycache__ subdirectory. 'py_files' is a list - of files to compile; any files that don't end in ".py" are silently - skipped. 'optimize' must be one of the following: - 0 - don't optimize - 1 - normal optimization (like "python -O") - 2 - extra optimization (like "python -OO") - If 'force' is true, all files are recompiled regardless of - timestamps. - - The source filename encoded in each bytecode file defaults to the - filenames listed in 'py_files'; you can modify these with 'prefix' and - 'basedir'. 'prefix' is a string that will be stripped off of each - source filename, and 'base_dir' is a directory name that will be - prepended (after 'prefix' is stripped). You can supply either or both - (or neither) of 'prefix' and 'base_dir', as you wish. - - If 'dry_run' is true, doesn't actually do anything that would - affect the filesystem. - - Byte-compilation is either done directly in this interpreter process - with the standard py_compile module, or indirectly by writing a - temporary script and executing it. Normally, you should let - 'byte_compile()' figure out to use direct compilation or not (see - the source for details). The 'direct' flag is used by the script - generated in indirect mode; unless you know what you're doing, leave - it set to None. - """ - - # Late import to fix a bootstrap issue: _posixsubprocess is built by - # setup.py, but setup.py uses distutils. - import subprocess - - # nothing is done if sys.dont_write_bytecode is True - if sys.dont_write_bytecode: - raise DistutilsByteCompileError('byte-compiling is disabled.') - - # First, if the caller didn't force us into direct or indirect mode, - # figure out which mode we should be in. We take a conservative - # approach: choose direct mode *only* if the current interpreter is - # in debug mode and optimize is 0. If we're not in debug mode (-O - # or -OO), we don't know which level of optimization this - # interpreter is running with, so we can't do direct - # byte-compilation and be certain that it's the right thing. Thus, - # always compile indirectly if the current interpreter is in either - # optimize mode, or if either optimization level was requested by - # the caller. - if direct is None: - direct = (__debug__ and optimize == 0) - - # "Indirect" byte-compilation: write a temporary script and then - # run it with the appropriate flags. - if not direct: - try: - from tempfile import mkstemp - (script_fd, script_name) = mkstemp(".py") - except ImportError: - from tempfile import mktemp - (script_fd, script_name) = None, mktemp(".py") - log.info("writing byte-compilation script '%s'", script_name) - if not dry_run: - if script_fd is not None: - script = os.fdopen(script_fd, "w") - else: - script = open(script_name, "w") - - with script: - script.write("""\ -from distutils.util import byte_compile -files = [ -""") - - # XXX would be nice to write absolute filenames, just for - # safety's sake (script should be more robust in the face of - # chdir'ing before running it). But this requires abspath'ing - # 'prefix' as well, and that breaks the hack in build_lib's - # 'byte_compile()' method that carefully tacks on a trailing - # slash (os.sep really) to make sure the prefix here is "just - # right". This whole prefix business is rather delicate -- the - # problem is that it's really a directory, but I'm treating it - # as a dumb string, so trailing slashes and so forth matter. - - #py_files = map(os.path.abspath, py_files) - #if prefix: - # prefix = os.path.abspath(prefix) - - script.write(",\n".join(map(repr, py_files)) + "]\n") - script.write(""" -byte_compile(files, optimize=%r, force=%r, - prefix=%r, base_dir=%r, - verbose=%r, dry_run=0, - direct=1) -""" % (optimize, force, prefix, base_dir, verbose)) - - msg = distutils._DEPRECATION_MESSAGE - cmd = [sys.executable] - cmd.extend(subprocess._optim_args_from_interpreter_flags()) - cmd.append(f'-Wignore:{msg}:DeprecationWarning') - cmd.append(script_name) - spawn(cmd, dry_run=dry_run) - execute(os.remove, (script_name,), "removing %s" % script_name, - dry_run=dry_run) - - # "Direct" byte-compilation: use the py_compile module to compile - # right here, right now. Note that the script generated in indirect - # mode simply calls 'byte_compile()' in direct mode, a weird sort of - # cross-process recursion. Hey, it works! - else: - from py_compile import compile - - for file in py_files: - if file[-3:] != ".py": - # This lets us be lazy and not filter filenames in - # the "install_lib" command. - continue - - # Terminology from the py_compile module: - # cfile - byte-compiled file - # dfile - purported source filename (same as 'file' by default) - if optimize >= 0: - opt = '' if optimize == 0 else optimize - cfile = importlib.util.cache_from_source( - file, optimization=opt) - else: - cfile = importlib.util.cache_from_source(file) - dfile = file - if prefix: - if file[:len(prefix)] != prefix: - raise ValueError("invalid prefix: filename %r doesn't start with %r" - % (file, prefix)) - dfile = dfile[len(prefix):] - if base_dir: - dfile = os.path.join(base_dir, dfile) - - cfile_base = os.path.basename(cfile) - if direct: - if force or newer(file, cfile): - log.info("byte-compiling %s to %s", file, cfile_base) - if not dry_run: - compile(file, cfile, dfile) - else: - log.debug("skipping byte-compilation of %s to %s", - file, cfile_base) - -# byte_compile () - -def rfc822_escape (header): - """Return a version of the string escaped for inclusion in an - RFC-822 header, by ensuring there are 8 spaces space after each newline. - """ - lines = header.split('\n') - sep = '\n' + 8 * ' ' - return sep.join(lines) - -# 2to3 support - -def run_2to3(files, fixer_names=None, options=None, explicit=None): - """Invoke 2to3 on a list of Python files. - The files should all come from the build area, as the - modification is done in-place. To reduce the build time, - only files modified since the last invocation of this - function should be passed in the files argument.""" - - if not files: - return - - # Make this class local, to delay import of 2to3 - from lib2to3.refactor import RefactoringTool, get_fixers_from_package - class DistutilsRefactoringTool(RefactoringTool): - def log_error(self, msg, *args, **kw): - log.error(msg, *args) - - def log_message(self, msg, *args): - log.info(msg, *args) - - def log_debug(self, msg, *args): - log.debug(msg, *args) - - if fixer_names is None: - fixer_names = get_fixers_from_package('lib2to3.fixes') - r = DistutilsRefactoringTool(fixer_names, options=options) - r.refactor(files, write=True) - -def copydir_run_2to3(src, dest, template=None, fixer_names=None, - options=None, explicit=None): - """Recursively copy a directory, only copying new and changed files, - running run_2to3 over all newly copied Python modules afterward. - - If you give a template string, it's parsed like a MANIFEST.in. - """ - from distutils.dir_util import mkpath - from distutils.file_util import copy_file - from distutils.filelist import FileList - filelist = FileList() - curdir = os.getcwd() - os.chdir(src) - try: - filelist.findall() - finally: - os.chdir(curdir) - filelist.files[:] = filelist.allfiles - if template: - for line in template.splitlines(): - line = line.strip() - if not line: continue - filelist.process_template_line(line) - copied = [] - for filename in filelist.files: - outname = os.path.join(dest, filename) - mkpath(os.path.dirname(outname)) - res = copy_file(os.path.join(src, filename), outname, update=1) - if res[1]: copied.append(outname) - run_2to3([fn for fn in copied if fn.lower().endswith('.py')], - fixer_names=fixer_names, options=options, explicit=explicit) - return copied - -class Mixin2to3: - '''Mixin class for commands that run 2to3. - To configure 2to3, setup scripts may either change - the class variables, or inherit from individual commands - to override how 2to3 is invoked.''' - - # provide list of fixers to run; - # defaults to all from lib2to3.fixers - fixer_names = None - - # options dictionary - options = None - - # list of fixers to invoke even though they are marked as explicit - explicit = None - - def run_2to3(self, files): - return run_2to3(files, self.fixer_names, self.options, self.explicit) diff --git a/Lib/distutils/version.py b/Lib/distutils/version.py deleted file mode 100644 index c33bebae..00000000 --- a/Lib/distutils/version.py +++ /dev/null @@ -1,347 +0,0 @@ -# -# distutils/version.py -# -# Implements multiple version numbering conventions for the -# Python Module Distribution Utilities. -# -# $Id$ -# - -"""Provides classes to represent module version numbers (one class for -each style of version numbering). There are currently two such classes -implemented: StrictVersion and LooseVersion. - -Every version number class implements the following interface: - * the 'parse' method takes a string and parses it to some internal - representation; if the string is an invalid version number, - 'parse' raises a ValueError exception - * the class constructor takes an optional string argument which, - if supplied, is passed to 'parse' - * __str__ reconstructs the string that was passed to 'parse' (or - an equivalent string -- ie. one that will generate an equivalent - version number instance) - * __repr__ generates Python code to recreate the version number instance - * _cmp compares the current instance with either another instance - of the same class or a string (which will be parsed to an instance - of the same class, thus must follow the same rules) -""" - -import re - -class Version: - """Abstract base class for version numbering classes. Just provides - constructor (__init__) and reproducer (__repr__), because those - seem to be the same for all version numbering classes; and route - rich comparisons to _cmp. - """ - - def __init__ (self, vstring=None): - if vstring: - self.parse(vstring) - - def __repr__ (self): - return "%s ('%s')" % (self.__class__.__name__, str(self)) - - def __eq__(self, other): - c = self._cmp(other) - if c is NotImplemented: - return c - return c == 0 - - def __lt__(self, other): - c = self._cmp(other) - if c is NotImplemented: - return c - return c < 0 - - def __le__(self, other): - c = self._cmp(other) - if c is NotImplemented: - return c - return c <= 0 - - def __gt__(self, other): - c = self._cmp(other) - if c is NotImplemented: - return c - return c > 0 - - def __ge__(self, other): - c = self._cmp(other) - if c is NotImplemented: - return c - return c >= 0 - - -# Interface for version-number classes -- must be implemented -# by the following classes (the concrete ones -- Version should -# be treated as an abstract class). -# __init__ (string) - create and take same action as 'parse' -# (string parameter is optional) -# parse (string) - convert a string representation to whatever -# internal representation is appropriate for -# this style of version numbering -# __str__ (self) - convert back to a string; should be very similar -# (if not identical to) the string supplied to parse -# __repr__ (self) - generate Python code to recreate -# the instance -# _cmp (self, other) - compare two version numbers ('other' may -# be an unparsed version string, or another -# instance of your version class) - - -class StrictVersion (Version): - - """Version numbering for anal retentives and software idealists. - Implements the standard interface for version number classes as - described above. A version number consists of two or three - dot-separated numeric components, with an optional "pre-release" tag - on the end. The pre-release tag consists of the letter 'a' or 'b' - followed by a number. If the numeric components of two version - numbers are equal, then one with a pre-release tag will always - be deemed earlier (lesser) than one without. - - The following are valid version numbers (shown in the order that - would be obtained by sorting according to the supplied cmp function): - - 0.4 0.4.0 (these two are equivalent) - 0.4.1 - 0.5a1 - 0.5b3 - 0.5 - 0.9.6 - 1.0 - 1.0.4a3 - 1.0.4b1 - 1.0.4 - - The following are examples of invalid version numbers: - - 1 - 2.7.2.2 - 1.3.a4 - 1.3pl1 - 1.3c4 - - The rationale for this version numbering system will be explained - in the distutils documentation. - """ - - version_re = re.compile(r'^(\d+) \. (\d+) (\. (\d+))? ([ab](\d+))?$', - re.VERBOSE | re.ASCII) - - - def parse (self, vstring): - match = self.version_re.match(vstring) - if not match: - raise ValueError("invalid version number '%s'" % vstring) - - (major, minor, patch, prerelease, prerelease_num) = \ - match.group(1, 2, 4, 5, 6) - - if patch: - self.version = tuple(map(int, [major, minor, patch])) - else: - self.version = tuple(map(int, [major, minor])) + (0,) - - if prerelease: - self.prerelease = (prerelease[0], int(prerelease_num)) - else: - self.prerelease = None - - - def __str__ (self): - - if self.version[2] == 0: - vstring = '.'.join(map(str, self.version[0:2])) - else: - vstring = '.'.join(map(str, self.version)) - - if self.prerelease: - vstring = vstring + self.prerelease[0] + str(self.prerelease[1]) - - return vstring - - - def _cmp (self, other): - if isinstance(other, str): - other = StrictVersion(other) - elif not isinstance(other, StrictVersion): - return NotImplemented - - if self.version != other.version: - # numeric versions don't match - # prerelease stuff doesn't matter - if self.version < other.version: - return -1 - else: - return 1 - - # have to compare prerelease - # case 1: neither has prerelease; they're equal - # case 2: self has prerelease, other doesn't; other is greater - # case 3: self doesn't have prerelease, other does: self is greater - # case 4: both have prerelease: must compare them! - - if (not self.prerelease and not other.prerelease): - return 0 - elif (self.prerelease and not other.prerelease): - return -1 - elif (not self.prerelease and other.prerelease): - return 1 - elif (self.prerelease and other.prerelease): - if self.prerelease == other.prerelease: - return 0 - elif self.prerelease < other.prerelease: - return -1 - else: - return 1 - else: - assert False, "never get here" - -# end class StrictVersion - - -# The rules according to Greg Stein: -# 1) a version number has 1 or more numbers separated by a period or by -# sequences of letters. If only periods, then these are compared -# left-to-right to determine an ordering. -# 2) sequences of letters are part of the tuple for comparison and are -# compared lexicographically -# 3) recognize the numeric components may have leading zeroes -# -# The LooseVersion class below implements these rules: a version number -# string is split up into a tuple of integer and string components, and -# comparison is a simple tuple comparison. This means that version -# numbers behave in a predictable and obvious way, but a way that might -# not necessarily be how people *want* version numbers to behave. There -# wouldn't be a problem if people could stick to purely numeric version -# numbers: just split on period and compare the numbers as tuples. -# However, people insist on putting letters into their version numbers; -# the most common purpose seems to be: -# - indicating a "pre-release" version -# ('alpha', 'beta', 'a', 'b', 'pre', 'p') -# - indicating a post-release patch ('p', 'pl', 'patch') -# but of course this can't cover all version number schemes, and there's -# no way to know what a programmer means without asking him. -# -# The problem is what to do with letters (and other non-numeric -# characters) in a version number. The current implementation does the -# obvious and predictable thing: keep them as strings and compare -# lexically within a tuple comparison. This has the desired effect if -# an appended letter sequence implies something "post-release": -# eg. "0.99" < "0.99pl14" < "1.0", and "5.001" < "5.001m" < "5.002". -# -# However, if letters in a version number imply a pre-release version, -# the "obvious" thing isn't correct. Eg. you would expect that -# "1.5.1" < "1.5.2a2" < "1.5.2", but under the tuple/lexical comparison -# implemented here, this just isn't so. -# -# Two possible solutions come to mind. The first is to tie the -# comparison algorithm to a particular set of semantic rules, as has -# been done in the StrictVersion class above. This works great as long -# as everyone can go along with bondage and discipline. Hopefully a -# (large) subset of Python module programmers will agree that the -# particular flavour of bondage and discipline provided by StrictVersion -# provides enough benefit to be worth using, and will submit their -# version numbering scheme to its domination. The free-thinking -# anarchists in the lot will never give in, though, and something needs -# to be done to accommodate them. -# -# Perhaps a "moderately strict" version class could be implemented that -# lets almost anything slide (syntactically), and makes some heuristic -# assumptions about non-digits in version number strings. This could -# sink into special-case-hell, though; if I was as talented and -# idiosyncratic as Larry Wall, I'd go ahead and implement a class that -# somehow knows that "1.2.1" < "1.2.2a2" < "1.2.2" < "1.2.2pl3", and is -# just as happy dealing with things like "2g6" and "1.13++". I don't -# think I'm smart enough to do it right though. -# -# In any case, I've coded the test suite for this module (see -# ../test/test_version.py) specifically to fail on things like comparing -# "1.2a2" and "1.2". That's not because the *code* is doing anything -# wrong, it's because the simple, obvious design doesn't match my -# complicated, hairy expectations for real-world version numbers. It -# would be a snap to fix the test suite to say, "Yep, LooseVersion does -# the Right Thing" (ie. the code matches the conception). But I'd rather -# have a conception that matches common notions about version numbers. - -class LooseVersion (Version): - - """Version numbering for anarchists and software realists. - Implements the standard interface for version number classes as - described above. A version number consists of a series of numbers, - separated by either periods or strings of letters. When comparing - version numbers, the numeric components will be compared - numerically, and the alphabetic components lexically. The following - are all valid version numbers, in no particular order: - - 1.5.1 - 1.5.2b2 - 161 - 3.10a - 8.02 - 3.4j - 1996.07.12 - 3.2.pl0 - 3.1.1.6 - 2g6 - 11g - 0.960923 - 2.2beta29 - 1.13++ - 5.5.kw - 2.0b1pl0 - - In fact, there is no such thing as an invalid version number under - this scheme; the rules for comparison are simple and predictable, - but may not always give the results you want (for some definition - of "want"). - """ - - component_re = re.compile(r'(\d+ | [a-z]+ | \.)', re.VERBOSE) - - def __init__ (self, vstring=None): - if vstring: - self.parse(vstring) - - - def parse (self, vstring): - # I've given up on thinking I can reconstruct the version string - # from the parsed tuple -- so I just store the string here for - # use by __str__ - self.vstring = vstring - components = [x for x in self.component_re.split(vstring) - if x and x != '.'] - for i, obj in enumerate(components): - try: - components[i] = int(obj) - except ValueError: - pass - - self.version = components - - - def __str__ (self): - return self.vstring - - - def __repr__ (self): - return "LooseVersion ('%s')" % str(self) - - - def _cmp (self, other): - if isinstance(other, str): - other = LooseVersion(other) - elif not isinstance(other, LooseVersion): - return NotImplemented - - if self.version == other.version: - return 0 - if self.version < other.version: - return -1 - if self.version > other.version: - return 1 - - -# end class LooseVersion diff --git a/Lib/distutils/versionpredicate.py b/Lib/distutils/versionpredicate.py deleted file mode 100644 index 062c98f2..00000000 --- a/Lib/distutils/versionpredicate.py +++ /dev/null @@ -1,166 +0,0 @@ -"""Module for parsing and testing package version predicate strings. -""" -import re -import distutils.version -import operator - - -re_validPackage = re.compile(r"(?i)^\s*([a-z_]\w*(?:\.[a-z_]\w*)*)(.*)", - re.ASCII) -# (package) (rest) - -re_paren = re.compile(r"^\s*\((.*)\)\s*$") # (list) inside of parentheses -re_splitComparison = re.compile(r"^\s*(<=|>=|<|>|!=|==)\s*([^\s,]+)\s*$") -# (comp) (version) - - -def splitUp(pred): - """Parse a single version comparison. - - Return (comparison string, StrictVersion) - """ - res = re_splitComparison.match(pred) - if not res: - raise ValueError("bad package restriction syntax: %r" % pred) - comp, verStr = res.groups() - return (comp, distutils.version.StrictVersion(verStr)) - -compmap = {"<": operator.lt, "<=": operator.le, "==": operator.eq, - ">": operator.gt, ">=": operator.ge, "!=": operator.ne} - -class VersionPredicate: - """Parse and test package version predicates. - - >>> v = VersionPredicate('pyepat.abc (>1.0, <3333.3a1, !=1555.1b3)') - - The `name` attribute provides the full dotted name that is given:: - - >>> v.name - 'pyepat.abc' - - The str() of a `VersionPredicate` provides a normalized - human-readable version of the expression:: - - >>> print(v) - pyepat.abc (> 1.0, < 3333.3a1, != 1555.1b3) - - The `satisfied_by()` method can be used to determine with a given - version number is included in the set described by the version - restrictions:: - - >>> v.satisfied_by('1.1') - True - >>> v.satisfied_by('1.4') - True - >>> v.satisfied_by('1.0') - False - >>> v.satisfied_by('4444.4') - False - >>> v.satisfied_by('1555.1b3') - False - - `VersionPredicate` is flexible in accepting extra whitespace:: - - >>> v = VersionPredicate(' pat( == 0.1 ) ') - >>> v.name - 'pat' - >>> v.satisfied_by('0.1') - True - >>> v.satisfied_by('0.2') - False - - If any version numbers passed in do not conform to the - restrictions of `StrictVersion`, a `ValueError` is raised:: - - >>> v = VersionPredicate('p1.p2.p3.p4(>=1.0, <=1.3a1, !=1.2zb3)') - Traceback (most recent call last): - ... - ValueError: invalid version number '1.2zb3' - - It the module or package name given does not conform to what's - allowed as a legal module or package name, `ValueError` is - raised:: - - >>> v = VersionPredicate('foo-bar') - Traceback (most recent call last): - ... - ValueError: expected parenthesized list: '-bar' - - >>> v = VersionPredicate('foo bar (12.21)') - Traceback (most recent call last): - ... - ValueError: expected parenthesized list: 'bar (12.21)' - - """ - - def __init__(self, versionPredicateStr): - """Parse a version predicate string. - """ - # Fields: - # name: package name - # pred: list of (comparison string, StrictVersion) - - versionPredicateStr = versionPredicateStr.strip() - if not versionPredicateStr: - raise ValueError("empty package restriction") - match = re_validPackage.match(versionPredicateStr) - if not match: - raise ValueError("bad package name in %r" % versionPredicateStr) - self.name, paren = match.groups() - paren = paren.strip() - if paren: - match = re_paren.match(paren) - if not match: - raise ValueError("expected parenthesized list: %r" % paren) - str = match.groups()[0] - self.pred = [splitUp(aPred) for aPred in str.split(",")] - if not self.pred: - raise ValueError("empty parenthesized list in %r" - % versionPredicateStr) - else: - self.pred = [] - - def __str__(self): - if self.pred: - seq = [cond + " " + str(ver) for cond, ver in self.pred] - return self.name + " (" + ", ".join(seq) + ")" - else: - return self.name - - def satisfied_by(self, version): - """True if version is compatible with all the predicates in self. - The parameter version must be acceptable to the StrictVersion - constructor. It may be either a string or StrictVersion. - """ - for cond, ver in self.pred: - if not compmap[cond](version, ver): - return False - return True - - -_provision_rx = None - -def split_provision(value): - """Return the name and optional version number of a provision. - - The version number, if given, will be returned as a `StrictVersion` - instance, otherwise it will be `None`. - - >>> split_provision('mypkg') - ('mypkg', None) - >>> split_provision(' mypkg( 1.2 ) ') - ('mypkg', StrictVersion ('1.2')) - """ - global _provision_rx - if _provision_rx is None: - _provision_rx = re.compile( - r"([a-zA-Z_]\w*(?:\.[a-zA-Z_]\w*)*)(?:\s*\(\s*([^)\s]+)\s*\))?$", - re.ASCII) - value = value.strip() - m = _provision_rx.match(value) - if not m: - raise ValueError("illegal provides specification: %r" % value) - ver = m.group(2) or None - if ver: - ver = distutils.version.StrictVersion(ver) - return m.group(1), ver diff --git a/Lib/doctest.py b/Lib/doctest.py index dafad505..a63df46a 100644 --- a/Lib/doctest.py +++ b/Lib/doctest.py @@ -207,7 +207,13 @@ def _normalize_module(module, depth=2): elif isinstance(module, str): return __import__(module, globals(), locals(), ["*"]) elif module is None: - return sys.modules[sys._getframe(depth).f_globals['__name__']] + try: + try: + return sys.modules[sys._getframemodulename(depth)] + except AttributeError: + return sys.modules[sys._getframe(depth).f_globals['__name__']] + except KeyError: + pass else: raise TypeError("Expected a module, string, or None") @@ -1104,7 +1110,7 @@ class DocTestFinder: if source_lines is None: return None pat = re.compile(r'^\s*class\s*%s\b' % - getattr(obj, '__name__', '-')) + re.escape(getattr(obj, '__name__', '-'))) for i, line in enumerate(source_lines): if pat.match(line): lineno = i diff --git a/Lib/email/__init__.py b/Lib/email/__init__.py index fae87243..9fa47783 100644 --- a/Lib/email/__init__.py +++ b/Lib/email/__init__.py @@ -25,7 +25,6 @@ __all__ = [ ] - # Some convenience routines. Don't import Parser and Message as side-effects # of importing email since those cascadingly import most of the rest of the # email package. diff --git a/Lib/email/_header_value_parser.py b/Lib/email/_header_value_parser.py index e637e6df..0d6bd812 100644 --- a/Lib/email/_header_value_parser.py +++ b/Lib/email/_header_value_parser.py @@ -1987,7 +1987,7 @@ def get_address_list(value): try: token, value = get_address(value) address_list.append(token) - except errors.HeaderParseError as err: + except errors.HeaderParseError: leader = None if value[0] in CFWS_LEADER: leader, value = get_cfws(value) @@ -2096,7 +2096,7 @@ def get_msg_id(value): except errors.HeaderParseError: try: token, value = get_no_fold_literal(value) - except errors.HeaderParseError as e: + except errors.HeaderParseError: try: token, value = get_domain(value) msg_id.defects.append(errors.ObsoleteHeaderDefect( @@ -2443,7 +2443,6 @@ def get_parameter(value): raise errors.HeaderParseError("Parameter not followed by '='") param.append(ValueTerminal('=', 'parameter-separator')) value = value[1:] - leader = None if value and value[0] in CFWS_LEADER: token, value = get_cfws(value) param.append(token) @@ -2568,7 +2567,7 @@ def parse_mime_parameters(value): try: token, value = get_parameter(value) mime_parameters.append(token) - except errors.HeaderParseError as err: + except errors.HeaderParseError: leader = None if value[0] in CFWS_LEADER: leader, value = get_cfws(value) @@ -2626,7 +2625,6 @@ def parse_content_type_header(value): don't do that. """ ctype = ContentType() - recover = False if not value: ctype.defects.append(errors.HeaderMissingRequiredValue( "Missing content type specification")) diff --git a/Lib/email/base64mime.py b/Lib/email/base64mime.py index a7cc3736..4cdf2266 100644 --- a/Lib/email/base64mime.py +++ b/Lib/email/base64mime.py @@ -45,7 +45,6 @@ EMPTYSTRING = '' MISC_LEN = 7 - # Helpers def header_length(bytearray): """Return the length of s when it is encoded with base64.""" @@ -57,7 +56,6 @@ def header_length(bytearray): return n - def header_encode(header_bytes, charset='iso-8859-1'): """Encode a single header line with Base64 encoding in a given charset. @@ -72,7 +70,6 @@ def header_encode(header_bytes, charset='iso-8859-1'): return '=?%s?b?%s?=' % (charset, encoded) - def body_encode(s, maxlinelen=76, eol=NL): r"""Encode a string with base64. @@ -98,7 +95,6 @@ def body_encode(s, maxlinelen=76, eol=NL): return EMPTYSTRING.join(encvec) - def decode(string): """Decode a raw base64 string, returning a bytes object. diff --git a/Lib/email/charset.py b/Lib/email/charset.py index d3d759ad..04380110 100644 --- a/Lib/email/charset.py +++ b/Lib/email/charset.py @@ -18,7 +18,6 @@ from email import errors from email.encoders import encode_7or8bit - # Flags for types of header encodings QP = 1 # Quoted-Printable BASE64 = 2 # Base64 @@ -32,7 +31,6 @@ UNKNOWN8BIT = 'unknown-8bit' EMPTYSTRING = '' - # Defaults CHARSETS = { # input header enc body enc output conv @@ -104,7 +102,6 @@ CODEC_MAP = { } - # Convenience functions for extending the above mappings def add_charset(charset, header_enc=None, body_enc=None, output_charset=None): """Add character set properties to the global registry. @@ -112,8 +109,8 @@ def add_charset(charset, header_enc=None, body_enc=None, output_charset=None): charset is the input character set, and must be the canonical name of a character set. - Optional header_enc and body_enc is either Charset.QP for - quoted-printable, Charset.BASE64 for base64 encoding, Charset.SHORTEST for + Optional header_enc and body_enc is either charset.QP for + quoted-printable, charset.BASE64 for base64 encoding, charset.SHORTEST for the shortest of qp or base64 encoding, or None for no encoding. SHORTEST is only valid for header_enc. It describes how message headers and message bodies in the input charset are to be encoded. Default is no @@ -153,7 +150,6 @@ def add_codec(charset, codecname): CODEC_MAP[charset] = codecname - # Convenience function for encoding strings, taking into account # that they might be unknown-8bit (ie: have surrogate-escaped bytes) def _encode(string, codec): @@ -163,7 +159,6 @@ def _encode(string, codec): return string.encode(codec) - class Charset: """Map character sets to their email properties. @@ -185,13 +180,13 @@ class Charset: header_encoding: If the character set must be encoded before it can be used in an email header, this attribute will be set to - Charset.QP (for quoted-printable), Charset.BASE64 (for - base64 encoding), or Charset.SHORTEST for the shortest of + charset.QP (for quoted-printable), charset.BASE64 (for + base64 encoding), or charset.SHORTEST for the shortest of QP or BASE64 encoding. Otherwise, it will be None. body_encoding: Same as header_encoding, but describes the encoding for the mail message's body, which indeed may be different than the - header encoding. Charset.SHORTEST is not allowed for + header encoding. charset.SHORTEST is not allowed for body_encoding. output_charset: Some character sets must be converted before they can be @@ -346,7 +341,6 @@ class Charset: if not lines and not current_line: lines.append(None) else: - separator = (' ' if lines else '') joined_line = EMPTYSTRING.join(current_line) header_bytes = _encode(joined_line, codec) lines.append(encoder(header_bytes)) diff --git a/Lib/email/encoders.py b/Lib/email/encoders.py index 0a66acb6..17bd1ab7 100644 --- a/Lib/email/encoders.py +++ b/Lib/email/encoders.py @@ -16,7 +16,6 @@ from base64 import encodebytes as _bencode from quopri import encodestring as _encodestring - def _qencode(s): enc = _encodestring(s, quotetabs=True) # Must encode spaces, which quopri.encodestring() doesn't do @@ -34,7 +33,6 @@ def encode_base64(msg): msg['Content-Transfer-Encoding'] = 'base64' - def encode_quopri(msg): """Encode the message's payload in quoted-printable. @@ -46,7 +44,6 @@ def encode_quopri(msg): msg['Content-Transfer-Encoding'] = 'quoted-printable' - def encode_7or8bit(msg): """Set the Content-Transfer-Encoding header to 7bit or 8bit.""" orig = msg.get_payload(decode=True) @@ -64,6 +61,5 @@ def encode_7or8bit(msg): msg['Content-Transfer-Encoding'] = '7bit' - def encode_noop(msg): """Do nothing.""" diff --git a/Lib/email/feedparser.py b/Lib/email/feedparser.py index 97d3f514..c2881d9b 100644 --- a/Lib/email/feedparser.py +++ b/Lib/email/feedparser.py @@ -41,7 +41,6 @@ NL = '\n' NeedMoreData = object() - class BufferedSubFile(object): """A file-ish object that can have new data loaded into it. @@ -132,7 +131,6 @@ class BufferedSubFile(object): return line - class FeedParser: """A feed-style parser of email.""" @@ -189,7 +187,7 @@ class FeedParser: assert not self._msgstack # Look for final set of defects if root.get_content_maintype() == 'multipart' \ - and not root.is_multipart(): + and not root.is_multipart() and not self._headersonly: defect = errors.MultipartInvariantViolationDefect() self.policy.handle_defect(root, defect) return root @@ -266,7 +264,7 @@ class FeedParser: yield NeedMoreData continue break - msg = self._pop_message() + self._pop_message() # We need to pop the EOF matcher in order to tell if we're at # the end of the current file, not the end of the last block # of message headers. diff --git a/Lib/email/generator.py b/Lib/email/generator.py index c9b12162..7ccbe10e 100644 --- a/Lib/email/generator.py +++ b/Lib/email/generator.py @@ -22,7 +22,6 @@ NLCRE = re.compile(r'\r\n|\r|\n') fcre = re.compile(r'^From ', re.MULTILINE) - class Generator: """Generates output from a Message object tree. @@ -170,7 +169,7 @@ class Generator: # parameter. # # The way we do this, so as to make the _handle_*() methods simpler, - # is to cache any subpart writes into a buffer. The we write the + # is to cache any subpart writes into a buffer. Then we write the # headers and the buffer contents. That way, subpart handlers can # Do The Right Thing, and can still modify the Content-Type: header if # necessary. @@ -392,7 +391,7 @@ class Generator: def _compile_re(cls, s, flags): return re.compile(s, flags) - + class BytesGenerator(Generator): """Generates a bytes version of a Message object tree. @@ -443,7 +442,6 @@ class BytesGenerator(Generator): return re.compile(s.encode('ascii'), flags) - _FMT = '[Non-text (%(type)s) part of message omitted, filename %(filename)s]' class DecodedGenerator(Generator): @@ -503,7 +501,6 @@ class DecodedGenerator(Generator): }, file=self) - # Helper used by Generator._make_boundary _width = len(repr(sys.maxsize-1)) _fmt = '%%0%dd' % _width diff --git a/Lib/email/header.py b/Lib/email/header.py index 4ab0032b..984851a7 100644 --- a/Lib/email/header.py +++ b/Lib/email/header.py @@ -52,12 +52,10 @@ fcre = re.compile(r'[\041-\176]+:$') _embedded_header = re.compile(r'\n[^ \t]+:') - # Helpers _max_append = email.quoprimime._max_append - def decode_header(header): """Decode a message header value without converting charset. @@ -152,7 +150,6 @@ def decode_header(header): return collapsed - def make_header(decoded_seq, maxlinelen=None, header_name=None, continuation_ws=' '): """Create a Header from a sequence of pairs as returned by decode_header() @@ -175,7 +172,6 @@ def make_header(decoded_seq, maxlinelen=None, header_name=None, return h - class Header: def __init__(self, s=None, charset=None, maxlinelen=None, header_name=None, @@ -409,7 +405,6 @@ class Header: self._chunks = chunks - class _ValueFormatter: def __init__(self, headerlen, maxlen, continuation_ws, splitchars): self._maxlen = maxlen diff --git a/Lib/email/iterators.py b/Lib/email/iterators.py index b5502ee9..3410935e 100644 --- a/Lib/email/iterators.py +++ b/Lib/email/iterators.py @@ -15,7 +15,6 @@ import sys from io import StringIO - # This function will become a method of the Message class def walk(self): """Walk over the message tree, yielding each subpart. @@ -29,7 +28,6 @@ def walk(self): yield from subpart.walk() - # These two functions are imported into the Iterators.py interface module. def body_line_iterator(msg, decode=False): """Iterate over the parts, returning string payloads line-by-line. @@ -55,7 +53,6 @@ def typed_subpart_iterator(msg, maintype='text', subtype=None): yield subpart - def _structure(msg, fp=None, level=0, include_default=False): """A handy debugging aid""" if fp is None: diff --git a/Lib/email/message.py b/Lib/email/message.py index 65fda507..411118c7 100644 --- a/Lib/email/message.py +++ b/Lib/email/message.py @@ -14,7 +14,7 @@ from io import BytesIO, StringIO # Intrapackage imports from email import utils from email import errors -from email._policybase import Policy, compat32 +from email._policybase import compat32 from email import charset as _charset from email._encoded_words import decode_b Charset = _charset.Charset @@ -448,7 +448,11 @@ class Message: self._headers = newheaders def __contains__(self, name): - return name.lower() in [k.lower() for k, v in self._headers] + name_lower = name.lower() + for k, v in self._headers: + if name_lower == k.lower(): + return True + return False def __iter__(self): for field, value in self._headers: diff --git a/Lib/email/mime/base.py b/Lib/email/mime/base.py index 1a3f9b51..f601f621 100644 --- a/Lib/email/mime/base.py +++ b/Lib/email/mime/base.py @@ -11,7 +11,6 @@ import email.policy from email import message - class MIMEBase(message.Message): """Base class for MIME specializations.""" diff --git a/Lib/email/mime/message.py b/Lib/email/mime/message.py index 07e4f2d1..61836b5a 100644 --- a/Lib/email/mime/message.py +++ b/Lib/email/mime/message.py @@ -10,7 +10,6 @@ from email import message from email.mime.nonmultipart import MIMENonMultipart - class MIMEMessage(MIMENonMultipart): """Class representing message/* MIME documents.""" diff --git a/Lib/email/mime/multipart.py b/Lib/email/mime/multipart.py index 2d3f2888..94d81c77 100644 --- a/Lib/email/mime/multipart.py +++ b/Lib/email/mime/multipart.py @@ -9,7 +9,6 @@ __all__ = ['MIMEMultipart'] from email.mime.base import MIMEBase - class MIMEMultipart(MIMEBase): """Base class for MIME multipart/* type messages.""" diff --git a/Lib/email/mime/nonmultipart.py b/Lib/email/mime/nonmultipart.py index e1f51968..a41386eb 100644 --- a/Lib/email/mime/nonmultipart.py +++ b/Lib/email/mime/nonmultipart.py @@ -10,7 +10,6 @@ from email import errors from email.mime.base import MIMEBase - class MIMENonMultipart(MIMEBase): """Base class for MIME non-multipart type messages.""" diff --git a/Lib/email/mime/text.py b/Lib/email/mime/text.py index 35b44238..7672b789 100644 --- a/Lib/email/mime/text.py +++ b/Lib/email/mime/text.py @@ -6,11 +6,9 @@ __all__ = ['MIMEText'] -from email.charset import Charset from email.mime.nonmultipart import MIMENonMultipart - class MIMEText(MIMENonMultipart): """Class for generating text/* type MIME documents.""" @@ -37,6 +35,6 @@ class MIMEText(MIMENonMultipart): _charset = 'utf-8' MIMENonMultipart.__init__(self, 'text', _subtype, policy=policy, - **{'charset': str(_charset)}) + charset=str(_charset)) self.set_payload(_text, _charset) diff --git a/Lib/email/parser.py b/Lib/email/parser.py index 7db4da1f..06d99b17 100644 --- a/Lib/email/parser.py +++ b/Lib/email/parser.py @@ -49,10 +49,7 @@ class Parser: feedparser = FeedParser(self._class, policy=self.policy) if headersonly: feedparser._set_headersonly() - while True: - data = fp.read(8192) - if not data: - break + while data := fp.read(8192): feedparser.feed(data) return feedparser.close() @@ -67,7 +64,6 @@ class Parser: return self.parse(StringIO(text), headersonly=headersonly) - class HeaderParser(Parser): def parse(self, fp, headersonly=True): return Parser.parse(self, fp, True) @@ -75,7 +71,7 @@ class HeaderParser(Parser): def parsestr(self, text, headersonly=True): return Parser.parsestr(self, text, True) - + class BytesParser: def __init__(self, *args, **kw): diff --git a/Lib/email/utils.py b/Lib/email/utils.py index cfdfeb3f..81da5394 100644 --- a/Lib/email/utils.py +++ b/Lib/email/utils.py @@ -143,13 +143,13 @@ def formatdate(timeval=None, localtime=False, usegmt=False): # 2822 requires that day and month names be the English abbreviations. if timeval is None: timeval = time.time() - if localtime or usegmt: - dt = datetime.datetime.fromtimestamp(timeval, datetime.timezone.utc) - else: - dt = datetime.datetime.utcfromtimestamp(timeval) + dt = datetime.datetime.fromtimestamp(timeval, datetime.timezone.utc) + if localtime: dt = dt.astimezone() usegmt = False + elif not usegmt: + dt = dt.replace(tzinfo=None) return format_datetime(dt, usegmt) def format_datetime(dt, usegmt=False): @@ -331,41 +331,23 @@ def collapse_rfc2231_value(value, errors='replace', # better than not having it. # -def localtime(dt=None, isdst=-1): +def localtime(dt=None, isdst=None): """Return local time as an aware datetime object. If called without arguments, return current time. Otherwise *dt* argument should be a datetime instance, and it is converted to the local time zone according to the system time zone database. If *dt* is naive (that is, dt.tzinfo is None), it is assumed to be in local time. - In this case, a positive or zero value for *isdst* causes localtime to - presume initially that summer time (for example, Daylight Saving Time) - is or is not (respectively) in effect for the specified time. A - negative value for *isdst* causes the localtime() function to attempt - to divine whether summer time is in effect for the specified time. + The isdst parameter is ignored. """ + if isdst is not None: + import warnings + warnings._deprecated( + "The 'isdst' parameter to 'localtime'", + message='{name} is deprecated and slated for removal in Python {remove}', + remove=(3, 14), + ) if dt is None: - return datetime.datetime.now(datetime.timezone.utc).astimezone() - if dt.tzinfo is not None: - return dt.astimezone() - # We have a naive datetime. Convert to a (localtime) timetuple and pass to - # system mktime together with the isdst hint. System mktime will return - # seconds since epoch. - tm = dt.timetuple()[:-1] + (isdst,) - seconds = time.mktime(tm) - localtm = time.localtime(seconds) - try: - delta = datetime.timedelta(seconds=localtm.tm_gmtoff) - tz = datetime.timezone(delta, localtm.tm_zone) - except AttributeError: - # Compute UTC offset and compare with the value implied by tm_isdst. - # If the values match, use the zone name implied by tm_isdst. - delta = dt - datetime.datetime(*time.gmtime(seconds)[:6]) - dst = time.daylight and localtm.tm_isdst > 0 - gmtoff = -(time.altzone if dst else time.timezone) - if delta == datetime.timedelta(seconds=gmtoff): - tz = datetime.timezone(delta, time.tzname[dst]) - else: - tz = datetime.timezone(delta) - return dt.replace(tzinfo=tz) + dt = datetime.datetime.now() + return dt.astimezone() diff --git a/Lib/encodings/idna.py b/Lib/encodings/idna.py index bf98f513..5396047a 100644 --- a/Lib/encodings/idna.py +++ b/Lib/encodings/idna.py @@ -101,6 +101,16 @@ def ToASCII(label): raise UnicodeError("label empty or too long") def ToUnicode(label): + if len(label) > 1024: + # Protection from https://github.com/python/cpython/issues/98433. + # https://datatracker.ietf.org/doc/html/rfc5894#section-6 + # doesn't specify a label size limit prior to NAMEPREP. But having + # one makes practical sense. + # This leaves ample room for nameprep() to remove Nothing characters + # per https://www.rfc-editor.org/rfc/rfc3454#section-3.1 while still + # preventing us from wasting time decoding a big thing that'll just + # hit the actual <= 63 length limit in Step 6. + raise UnicodeError("label way too long") # Step 1: Check for ASCII if isinstance(label, bytes): pure_ascii = True diff --git a/Lib/ensurepip/__init__.py b/Lib/ensurepip/__init__.py index 1a2f57c0..1fb1d505 100644 --- a/Lib/ensurepip/__init__.py +++ b/Lib/ensurepip/__init__.py @@ -9,11 +9,9 @@ from importlib import resources __all__ = ["version", "bootstrap"] -_PACKAGE_NAMES = ('setuptools', 'pip') -_SETUPTOOLS_VERSION = "65.5.0" -_PIP_VERSION = "22.3.1" +_PACKAGE_NAMES = ('pip',) +_PIP_VERSION = "23.2.1" _PROJECTS = [ - ("setuptools", _SETUPTOOLS_VERSION, "py3"), ("pip", _PIP_VERSION, "py3"), ] @@ -153,17 +151,17 @@ def _bootstrap(*, root=None, upgrade=False, user=False, _disable_pip_configuration_settings() - # By default, installing pip and setuptools installs all of the + # By default, installing pip installs all of the # following scripts (X.Y == running Python version): # - # pip, pipX, pipX.Y, easy_install, easy_install-X.Y + # pip, pipX, pipX.Y # # pip 1.5+ allows ensurepip to request that some of those be left out if altinstall: - # omit pip, pipX and easy_install + # omit pip, pipX os.environ["ENSUREPIP_OPTIONS"] = "altinstall" elif not default_pip: - # omit pip and easy_install + # omit pip os.environ["ENSUREPIP_OPTIONS"] = "install" with tempfile.TemporaryDirectory() as tmpdir: @@ -271,14 +269,14 @@ def _main(argv=None): action="store_true", default=False, help=("Make an alternate install, installing only the X.Y versioned " - "scripts (Default: pipX, pipX.Y, easy_install-X.Y)."), + "scripts (Default: pipX, pipX.Y)."), ) parser.add_argument( "--default-pip", action="store_true", default=False, help=("Make a default pip install, installing the unqualified pip " - "and easy_install in addition to the versioned scripts."), + "in addition to the versioned scripts."), ) args = parser.parse_args(argv) diff --git a/Lib/ensurepip/_bundled/pip-22.3.1-py3-none-any.whl b/Lib/ensurepip/_bundled/pip-23.2.1-py3-none-any.whl similarity index 54% rename from Lib/ensurepip/_bundled/pip-22.3.1-py3-none-any.whl rename to Lib/ensurepip/_bundled/pip-23.2.1-py3-none-any.whl index c5b7753e757df23620ad5f039050e7dcd49fffb5..ba28ef02e265f032560e28e40b2be0bd6e2e964f 100644 GIT binary patch delta 1039830 zcmZ5{Q*@vW&uwjMYTLFs_0+bew(-=qJ+*DyQ`<JDc6;9M@;|xC%F11`R`%XWrn7wi zmIG+NWWgaYKtMoXK=5Rq)Sc4dHxtloz`g7E5&~*~|Ap+IYgf8JK|s{OK|qlIOLVYw zU@|bUHL|obFkp1>)KiwV-(W`QdDlQW>!053;6auRAaG}J!-EowKT8j1fGxnEd4D9s z?6fRRBK#oypw0}8gXRC>vU58jaSLJ3{fZ~573fH?$|LCli$zp>$T+Jcp5>#PALkdy z4iG<J@C0BCtL^q^6i}wKFA56;hgU(22eo^i8=4=jdG5SI$RL41*7;?MXZ9ogu5E@P z`H~=U&Yt96W==dU=OO%1hIhc39lxJ4s0SZJS!VZuo>4h|Z$a(BdieKr@u2fqF_@nU zlL=4R>9TbD(hQ>It%mMXrXUq_B!vtg2t>d*x+&<4fnsAyv6yu*mL|llUrm#&{sCtR zckOkk$yn2MaHqlg)64#sxu<NcdVI7x({97?QjOUb{)7!5$vsW+Zg!!pb>KVVq}Y~9 ztj0F0&aU~HMS6Q$4n|#qTLP|%j7|t_0vEe_#s3+s8fD$-z)LK5w20()SVfJk8DLD} zJtQ3Ac*!;UoE<MsGzj{HTgk!N`_6=sqWi~ShBu2pe9Hat+f#AZ<Aa}j9Mz;k!Id%* z_81$p!L04M(<~#5W?f#EG2bCBhM;^db4zRc@6ANtz8=!|uZp`IpFjIV|F`^p&=e`N zU?3nxkRTwKARvvK;QzoN@c(Oqq*<tAi2rp%V+V9FDANBt1j29=9Rv^%aOxyESW-aN z`JfH8=R(7fCyW9;@twO^wUGRN_Ogxjw#}SB%cfjaH!@f<nkErGzNMM*``LvH1dW*H z#)dX+sUNLhvXIC?2xRrXD@{-7*hX&)tDq*f%SwyNbNZ>-Fr?~l6T^ArQ4V#*jNEaE z%^H$L-@(9r*Kh$hXY+3@E#NEK<PE4#J=RES32Ru*kkV@E`u069*Y?}lj%d=ll<+mx z(o5wZOrcnSxRIEKoH6*JRrz~eW$?Xqg>>qLamud7s0oN8#S8pXvpinedZF>%*7iYS z`h(%eS<NAdH#Ba@rEgGFvDuiQlSkJzu20yc=u>&12K;anO(u8yk(z!K_W@AA@D!r8 zcMWnUUyh4HEAe+I@OvIJurR{AT?oNMQNH^~v;gm+ifHM8ILR}C{Jr2%dO$g1P+H64 zP$<e>Dd0TMGCM_rzF!=ZneF}}R3m~gJImzd5nb?}(-MSiclVcoOW-pyE1$oWb98K% z{C$(Wtsu`%sool;kAH!&2_i6gd%j+fTz}~nQ^v;Vz1Gk~pJep%v6xDfMb0E1hw0&m zs6W20oh=$#yJzd9qS_A8b)(13@B=}RZ89Kx$C}E?0fGNXR=0ePi@i<L@L%8Gl!yZC zML#JMzeLqDR9#$pEciMUaJD18gHl;a9n=N_UugQb%7L@cyv~67>QLY|^whzyQXI4E zN__YO!yFo6QF={-uEnG)8DGk=xJs@+emrIOeP3U`a9E_XKpxHD&WT9*H}ZwSGNwk+ zi%29ktT5e&lflpU`~WU{Wla|k36Fq1Q2w5ieqQnsxHSmIKYB_DC+c2y^lVD()h^{A z@jod7<gyf1o_}-9z)b)n%haK#6>w}4VAGG%inAK!uxB^W+kvmlr<yuJxrXd73TsQ{ z0>WK)-np*TGVIJqU7Fsz^cTS(%xR@C?Ix+BhxFlRkNF@FvMIrj*~!K}{!V2L&J;TS z+zRe0vXBc7I1>v)i;;P&;R-tq*Wx41QNs5xa6P_!t`PC9c?iI!lMsk|!K#cxpS)UY zrikuO_BtYjFQA0Iy^^ntF{~+IGSJ!7_s}1`IDc6e61hy}5Z~n!Q>w3krBm3sxO$jP zmLmNQNiJReH>uZ*6WsD0#&a_6!7i<VG&a4><qGTe-)sxl=|}G;#Cx;{miFK%@`$XY z6=(v`J8}|Ca!sJm<(DiZ3^fjh0}?F;M+%?$SPH@)Q)oLrn(A8t$<8Sb@&>(?1_2af zH532hKh+QC&^wwLE69G53vOy&Sy&VWG1xDC+)#~y(*5rY^l;3E8M~J7v+Frkb0<4M zCE`N>0(pPyetPO~tuSo;#JRva+6RT+M_)sjY6-(S4m$vo!8JeJNNj|IBIc;zYB0=I zLW(Do`Z2TiywiXSx1U2SI8@A2-w8%qQz&E1)|9?F(qv<)!`d>YLlDlT=Br^uP6!`; z4US7felrFh*!k8WL8hV$&U=MfPJt~8kq(+vPY~ws9}lVKbo{(a#Ev+<W_tiaVv2;; z!Z}F<asptlvUs6~+|z_8KjkeVIBiT4y-zC2=P#i@&H73FOQ5fIa+9M|h4H&kKxMCI zMO>FVp-zd+3uaIB8d>vVRS|!i=yHl`h->yZ!Z?08DvfflO?o_vGfZgMHVUVZ8Srss z;7tO3D~K<v5T$I+l<h4oz#iDg%M?Au^ZqJjqy=_hq{K+XCWv9O&wl^LmlAu=jif2F zAlz@2W9h}7h;Zp>7^iS8OE#E&-ayTuv9%Z<TOk*KBjIjI<bRgUd(z_@YPDP=5d^0* zF9jP;{_AWY&xXmJo?&DfmEYQGo^B+2WO1oRwebe?Drq*^(lRInrYQ}=AB6|PunYx4 zzz>K<RQKB=nFY~;z05~@iS+H-Pzs{!oS=WM3caX{-P5Rg{Iq!0N|R>`*$E;lx@o}A zAo?B0rKu;SDu7xdXtniu+a*HpUXx14CRwTt9pnz8pf92oOx}9e;YRd1j7J>V8R>ff z*J^JpGju)w!ot^q&CBR8mJA|P61)1x4;sK>Ra0@u;?DOP*#-$U42zHIn6ryc#v@@< zW)!_L<Im8F0`t0T5*MQC5DWQZS~cawmtP7d9IV>xaRH5v%U3A4n*Juk&uGC>+L3b1 z<5%d6saw^ozI<~Q=!K|Lv1WEm*GGR=MoaB2OmRmA1#e!(e#B#OGIcreFt6{&>I%5w z4$WtPg^_SBa<a|`52`{IvWGs1`{RK41w%DVh(YO_#xJ_y!Ku6=oadI~hcejz8K#an z%gsGm;6bX8Tj!6WF5AH0hjJzAyp2NTe%#j$hPow`#lb*<KcjmmF_qj*(ShHD1nb1y zZF3adfj>n^-FD(f0U;9LuBw}4L<NvL!273_HS7=XRrPwj96zxt@0Ju->~{?Gd%hnW zKlcuXAHA^2A_ImG{GpPBve7Ip5;`W)!^VEsDP15X!&t~)@@i_pRpf_~rpjwIm5?NK z!B)X7&0a4AXJ@^&f@hdj)r>DVq5<i~0p$7(MrvxhFg$w*ud8{o$G#^y6afEd_lkMb z$U&R;Ja<QF>OAN)bHa`VEFl5oJ6kUz;k~WC=#%D-MK)Bcjysr(Bv!X9uW@%H&PHis zrUTSk_{fGTbzMPFIcnjHD++oLeB3-yGc+!zS1kT*?yai|mtXHDJLhKiip!Ve%&=gi zfkz$Sw!0>8O!PCFKOhWq7O2TY*R;}t{#!;yx2Y6|Tsz?Rr<-6X=(5PI>e9O^z{vxh z<>&M}8t>aJ==l8QZ{Kddz4*Z!<uO4|;emRrv{Wp*&9@x0AQhW{w;l84Hp@Clyk0sC zp%qZt9eMbVQ-?)>cFF4a(=JDM?{R25Idd9(27mJHfZtAtBv&K?0`Mt*!Z-2#2VR($ z<ob1WL8Bs)TMyjU<}2TMk9lg%rBaQcy3%OHcNnY&itcO;M7^u`G2*gBT$!Y-jT$nl z$PzT?<W10=>#Rnc^xY1{^79p`k;FB{?0Qi2n+`S_8<<)ZXNcDFV-u-32Ay;#t{SJ$ z<>C;9uGB9Fy(1Ie0)q%=0#Nsmgbv`i?ml;kc4q2jzvRAX|5cf<7-5N4jx=%Ppkow^ zoWDM@`_)Tv-(*uk22sFCD?!EnbEI%iLCutnX6ty$&%h?HUfuR)Ugxh-N9ODtwM=6D zGujjVY|pyVGDw4qvMa|f1~(}cIS`BCMvgxdx+pTFb(2{o3}8J|8HZ9<1h!*)I^W&^ zHEEY>@>0^G?uC~NVeSAPQIxi9$jDzYsFe%Bl)<ohi67V?+9#rew6}I6E{R{lMMzMI zs+8yPN?W!MwcqR?LxqGFS8^;%76g@ZBs1n+BeU*nzKy*3c^eU^qhAwXdfeO7eA>J{ zN?1f3^@=*!fY3q~bnBy%8?uxv;^roo47hu=!tB2p=Bm!J-XI6t1OlEWz1LX{0S0z` z9P9w8>vzD|)G~JeOUk8a|Nf<HQlO1@&r%JrJkXv~p7TAh+=$lJVTz2L@esv)%;zsI zJ1<L$<#~WFuH!n9c5PuFJVVlM{HYfpaSS%PzkA66Eas45ML+t*rCqgt5cD1u6V;sz zN*rE1{#6uei<iX96cc9ZXy%2c|FE)1H)O<cwL}thv`&sh&+%118t0Ey&d;P<f+TLH zf#a+H%Z|^0CO5p$SuCB&?+k}2LHK?jZcXo@BKm#p4I4?|$;OADiSP9mUX3*?`X&im zHyqRoRH69&nzNvsu?rdJ@o>y`DG-<a4Ub^bf*dx7^TQI)rmGAD5^8>`b>phZsPKu5 zgw`cf;%m!^uUfMZlQffXt_sF{k7vJcR@+WHMUR^#(sCL`-ArjKPZtX1U&`+4LZsBs zAE-G$(Bi7iEDpWP%&c#1C8+u%V3EF|tmSb@02=1e+UkW->r|BIN4>y|1uKYLcF<W* z=WOPe_SyP-9ejUQR;3nhF;2h2=EnQ_Bc8ibyUg2{Vc8nSn#8yjCPsr^kLNF^oGxvk zEfgx%uKUAqHRt(c;n+a-quZTDS6|3*-S6SlLkqoaBIYZ>1b2}7gT1HW%_BG!uZ4*f z(76(LhTH1No(GfT`E9BG<}I_kYI?*Ua&WrLWu5l;Ztl~090wiv)pG^;@Iz^9md0H? zi$+Gqr8o42VCF+_#rowNuJ-`KPV`HP@3$l77%>Ljhe15k+*8~ZMpTo3_lMb*K7Ll> z^3khyxOSi5SMUF2E=Y6zgZ3!@(UERy5D+YowCg59>_jXWz^~W1vJXaWtZUI>Q{6wZ zW17NkFOAr37dZ^P9!+C@9b?=fjfzg<+xt(3UZQM5mu_YWA}w}98&l)G;0(PzXO=)x zRySI$DWm&&o|89A))XV-Lq0t%-P8OfTelsdP&%o-pT)3U>Al{)W_pyZ8ooFU!xf6( ziw=JWtT$~v(1inJ{=wR(>#m2tRmSt_rKx6g%Fy#*?TAj&Nhy`UOmn(dn%AmN;am9S zLFEpg?_62Yp!}lX<oW9}K}QV-r8~;l)^#~?bF6FZQPTWPYWPspJe?UkdZ{$V*nGp6 z=}zZTdgmr(qGvf{znY8>S)zg!y|hCaFKbb48RaDskm{*z;BzzM{a&pCB6i&A1<=T* zw2!T9SfU7ZT&d9=7Ar7kVsi=tBYxvHj!Wf~nrFh9S~iOi#;*n*cD4~SDWzy~T%+A2 z`;MC^4bUniz77v(-RS$=@4MbTx7zDd)&A+}7<kiCva|^wKiZA^QNA7-yoow#XOqmh z=3Ns5RAYe|a5>-pV|p<0B>5MB43ygF9f=zMs$rv;)ED%6(8SO|K!v?)Imbw9T|f$A zJFDWZMlOy}{uRPJF6GKv>8^%2!&;G?60AK*o5^4f&!RJZ44?0$qCuNrUdU0K&DK3Z za05>5Rw_lQ{t6`-Y2M|>`DfJok!Fd{%mzXN(6wQ;jNVPRq40#GSw@k!+b!V#{*|oe zSgB&R+lbLq-kLr#)>0-;Ta97E;DqPgUz9rZ-G4=##5BxjQyn>ws7~*9uezCi;a0zI zWN({9&Puz%C<<p7#qr%SCNNkv*%2IY;@D}wtq|Y~Ni`0?k$}3}#>~Q_P=#n3vtDio zkP#5L>!^QTx%l-lb<sQCU&f$p;?D5Xn2w_kMXNlKFm;@@g`MtD-<jBuPR$~hNohNl z#b8=5vA*Zew#y7FZTOBVRPwy}P;S#XCiB2x7?(OhA}fm?2Nn>CHTR<{l+)Qub8m{` z8_kh^Z*ua1I}wG4$Osh0m^R$>dc(#7oQb&{+>4z8#aBAa5thLmq}cfx_xrXK?%4-? zUaX3p2b>LHd=~|jp6~~H0fL5qEm0%CM-e7xQmdpRKY|ZObBjp6XWX*3JJj&oFs?=M zS_IajX6#A_Gp4b+8*AU2?5L~R$%4q_yX^}07o9jIJg{nVn}ek+gGYQ5>>GFiHKQfe z8YF^4=r#&zk69kSS8egs--rY#fpj*J$~+qLT2BtuW8vk@H290$&pIo-vOK=FtrcK& zfo#6Qlxh^T_)BX8T3!78?4I7dp(spH?d8#b(aU|Rf4i!ktk!ei!=GR<ny@q<@5UJO zM1mIx*SeNmN&m8q1qbuCmTl|;x;8}$ya-Hg%{*z3C?-aWIZM=!@8aUVK1@%IRvPas zrlEL<5S%84)R`U(TZu}2HtM~Pii(6Gc#srZLS#2F68~6aI4F%;S&JcUQ$-7&%Bh12 z6mq&sc!`uqvNk3EhtEl$kCGteED3xUO9kK%KSr?B%?<lf)1&gfX9b>sX4DMPbBhiu z!l;vBrLFmvT)k+nbrC;tpZs%WJ7j{QM&cz{w6vkspFSjd5U7eGkl#8XYOQJyKBR+3 zWhS|WHN+WUj&agu->KPHvGRgcEUC^%G!y>Xp%Pm5-wD`-<VT5k?^aVB@V9F^uwE{j z!dDlqIpXqP9c~4BOhj7%eOLNQTxwir*yvxXt-++DDS4`DrVBZ%U-l@T)LmAZmRJN$ za`;a!FAbG{bVETRgII$ZV9^RHO$@UV542E&A@xWI$hIfZ@QmCp=dP&4nYLVs9jGuZ zuPJ{~X1gC@lb*Ft4-}*EG8WW&di>Vd?spd#I{7Rd$J=P6?!<rqJY#Y+w=Eb_DUQ0S zt-`P-cYXZq+Uyi9x=G#(f96A`J-~vR>yUEy-4246H_`Qw6KEtu*|Ewhlb!4TcpA>1 zY<pHdQ&YoKOUmGPRze1MmFE3d+ee@8&LNKpo^6M^i$mg?LYdr@HvKxQ_)4)&BH}|` zlV2p710$Z2pKfXjkc&M=Oe_rq#F33_y!v9pv_Zf<Gz;+`_*L8zzgCy<*x6$<Nqq?1 z7&bCBjiKvO60mMB8;0Q{*ouTs9|=V{gKxeWIMfQ$Bi*^Z@A$YjWb?o-cEkPn`#}x^ zu(TL9ooz(?Yf8lyL02a)>z{lLtOq580nK|I=jXnD;h)z9)G>%?rdG`2Wy2@+bwEPg zP?ieE8qu}HS*AxQBXRIITF4J|J-B%cb<9x|R1{a(Ul6Oi1gluYyR#0;#ablnDB`gx z(qic~41odz16O^S@y6*#<mSj>wXP@$pR+-_;5ExzGHv0zhLO_KpBnnEVNKE&h<?_y z*iSyF0O}~fA}=cLAS+AH^u(Du?SLT6EADR!JzU_D6e>+92D|h4scPCikQde=T22+- zppLChW6XirbmJ|0619lr<nZnm{}}|ybNy(36F-A`+N4C(x#$7GHJl1R<RP@ogx14y zsnM2~*lRZPtS=XOFM#-5JBTQ_6PBaBSQ-Phtt1A}eZQkDeYnkEd)^|_(Ry0ktk%nH zE5f658*y~KL=Hga#AMS6TYNQ4eI9QVc3GTZ!J4_}{b@|Jt6ZoX;Y-tR*QqMw^WN6^ zPl=Pf*^@K`R}PrAUdnQ4JC%d=(VZNP*r_gI-rNOoKfx@u(z_|>r}s5yayx~kaT}Cl zBy0m7qQ6mUsY@Dfr!4bzD}CZq3zbDcDV&&Kl!nxCw;+#xv|NKPwhdF~_azqIYt0M~ zDpG$t41a9XQjugQZmfpCDY1gR3!(!D<l`yyry+Wk-ZYg{U&?D!pXu1fWBomj=ufMX zuZl~hhr&E1Ghe->ubef0GVS*wGN%w7Qlh|5EcCsu0-Y!%`7F@b5`Iibu5Kl!Ikyk! zhm(7xPQ8>qG*B15Q74i}zCX?>UMe)xQR{xO``(kUB^_ntyHejW59~4jMo<W->YtQ- zmU@wII>ELgYQ26O-Y&Jy)ap~*{4vn$mdh3Jefp@d@6%JS3P4d94=`vgx;AguL(>GD z{psJM>uYANqiXLsgPzDgdCa2yBkEn0D3>J?UI$!C2t#2i{S3y@x7_61kv}D_^@XSt zul^!;l<s+Nns@7Dy4=X3?YPeC6qg-QY?H3sFXDUc={nF%8_+yt&M9@&U+5LQCl?E& z)h)=NETnjg)}oFijSTfWm=(c4j!ObQE1?~AnM-c({}daIXbBj6G^XfiXz>>?&!{W$ zhky!7OASe1d>SXZnRa4%Xfs+b!(;SeGu_2A(Lu@V>F`3c636c|!hgOLe??l1JOsvQ zHywY9gyXW_rNfW92YY>v(9^{#yy;PJS?Q3aquP21X9j=$043LOsi?iIk|_a3x>0#8 z4E4(O1num4S|#Lt{ezlAU*TKDUQ_COM>aCbTNxr`x2GT%^Y(H#M+;itr;|RJE@ONl zaUHll5tsO;>Yt*f5sErjGI}E<1L==MdD@!bLj{y?NIDyXync9*NW9$qtCol1o*oJ8 zc7*<k3m+o)$;7^5cU5sdH6#ycwidKcexG%+n2w}kTQVHC@J%)gqn)y1Z?*|$TjCd= zS%fEmMRg5Lm(ym1FgXhx<P*g2Z(M)Shrc}rkZU9A1pL~nJoC$|{ipWLA}$zU?Ro8^ zKKUOl_fRVR7`xJhpuM%<FC`a*-}{D-=uOSwLC@fHwIBJmqK{lW&YK0Oifza81%Iez z7WK_)f#UDOxi8j|!p}`#_~_8{jj<^k_?#ivYirP4Lr?iJ5_Y0ThOpoGYxfd1c&RUH zO_UTL%+#yCORh=?8C7^xJOYYo_VdbkeK#ACI%))T^7e9<s#!$g-)wbi_MrIIRmi~e zaV3|mAFx`k_xa1(qXYnWa^fyKE`}Xog<W66n0kEf(gQ&~ZKPULPS~}D@_PmIvNCd= z=Xc|E-Zn=yA2PZfu?l*tv2jm9_5MBC8D<`M4z?YoUxK6au}1(IUuFIT6rVgPnk#($ ztvJ{C5T<H;wFg{BD%XADYZRhFzwMe+#+H=&u!x!Wa39XtdAPevI@xk`S(*D^=3g~a z!!uler26u<IFL*N7Ova4pYZ>eMaZ!1G6bOfx98$a0~G+pN}41^12#CH+`loiBMVrM z%P#D=HxXX08-}kSWs``{Mxh30F`{BU6DR_buigSTcl>Sy647YJrPVLP*dmux$3~w& zhgXPU{21?w+qTAv&?KgprE@p$IA-WdJep~sgD#Axw1$tg4<*z$uSbK(QmL#34KFq8 zb1>9~ohhAKh=pxv0M;5(%_jK<#G1F@?*{R5W0J(kQX8rYOj-7LGPlv^x>I~Vkl@Fd zu`4*GZe{<Wz<+R4X)x}HupJoE`XpF#5g(ifHX38e#kvedAk3{ct@~)d3><?pi%}K$ zNe?wMV8*dL9+a^zL{K1t0yNV?swPue6C!2b>FKbfN3Lo`fi-)pS|}KQwRbdR&bYYy z&+wdZ2@d1ZzP>}s12Q*Cj1R$+PULqqKmFuz<;0lPFnQQIj%?**C3>e-h+5Jwvwq8r zhIldJEEYv46&iS+b3p)p|D}D^^vqM~b7&@#{OIgA^Ch2!N<@_)Da~KipRNvi5CgPH z6O7+JUVcuu!0X#Tr(ZcbVO*_Uyg^ib8$o=_q70W#xs@@8EQaiXH(8H{4k?%HIcemi zoVVmy%?6D>F1;Y*)unTh{7^mN@S;%$Kmcg65?UU71iv0`!26By>+HqL%kRSv?gDH` z;gHnO*b>%^Uq!dK-#MuN;X@_*qV{0H{p5$n0{UhfaHJf70OD4+uLZmQ80ZV)+Z6<k zNtfDVOuMKyyDEP7J1<QxT$|xKZe^iTx(?I|gmCsA^{j*ORg``>P`!(<^X2Tt25r-P zSU&MgZN*#dmgAjXS;4wSQAmy|01b2H#^O(K6{j?(#exr=X+qMKw_!k&bl-jTw(wmC ze|Iz@P`I6&D}UASvT%#Z0QsIc?eyb;id~l(5>m$F*3!$>)r&QTsYanhLzqE{z>-(; z_{Y3$FWJ)*U-pU5a3S=c*ck=I{l=(+q?i4V%U0Yx_yOox5a^(2Rn*iKE1VG)uS{;J z7?AuN1E2KRwRcls5a*|Vwu}hpYY2rJB$9;+(7zCP6rxL&@q#SH6ok@;S>iLk{|4EQ zcw5V2iO=`O_r*s^7zpk4XVdY3KuG}O1>Q94ur)$1z_y61Vs#ACg2WwL=jUCw*n=@l z6tUbXQC$zgEPFILQ==&;Em5HYA*7f#td)GFYRZ^Q{ykz4nMb*!Rez?hP;Q}N6#qse zpnONc%t+VQ5I_{k`4a}8b>+)9uUs)C5TtK~_!%2}ft1L1AHi>O6f1`q&OZe+6jNK9 zY+!C`xKAC@2#y)<f@`S9;3c;hQlkl{O@ji2gn>Cdz$EX~gba=wELmv?jA)1=t+Ghf z#=vG3i4?&Gw7p=~z_K&)nn)kim^hUj_>^k&#AZ+$QY#}%_N7M$)#<F^eW1o^!TC|n zimnFZgI&)hHYhney?T$$0=W^N9v)yGnrpN8Z-H6$z_#UFpszzK#w4HA;i&R-CuB_Q zgVUISiQ7~de^7%O4IPj4ffS2Y5N3`DHzyPMl*k>H5aGnDROB@JSHw`-bp`}60N!nI zNd!Je5(LnQw4G89?)LUOs4@{hbSUr-j80Wx;l71PQl4~<GS~a`7ZUVfx8M`c!hH4! z?zpNP2(HCw%g%+xtW`~&dwLUiiD<4IotDX`uf2hIwT|^U_<mOFE%o|OmB}j1uf|#? zs0Ybv*^q$I)bUCh`N8VLT+wO)^nGB=EW+O8!Y_l0t8y~Z@q$&s#<(<^5TGr}yCJxz zqiLnPIV3FQeQ~r{t6iu`g6vfwUDJXK^(eVCyc%jDhZugY%j@InkmTYZRiF*yD*wFe zM6BCyX`Y(;Bsj<W-f3C$Aec`G;i;t{lLiXy;kaRY+ZZPZjp9ZwLADryvQ?})G3!Yj z#YMvQa>xLw>I~5JLFqsX!$$UUG<hKqF;h$kmU@4LAs8(cQGI+?cBNsK!~HcUh{`Ag z9(Jf9_@9PsV+<zIa0k4V6af3EYULP@C(XyahjTLx4gFGlSkN0mx+Nkii&$K2C+z)k zOaxl>n9!5Yn+VZmHK`Y{gUbC2ECE+dxSeB^fTelBCR2pef6TvUM+jp1(R~+HF1%@7 zs49sy7zTmI27YU=u5kgF{}A1lN`36pdS5b_CFZw`xA%At{2clLJJLizN!w+bB8TPv zGlns9_m;t-KpllPt_$5b=Xa$e)xTdPL3<WM+FCC@u^kRKO6KPP_di)@<L1{G*2l&{ zuN5(P)apG#!iN-Qf85J@u^XbEyII!+QNPKBP(;P~SQ7Vb&HrXNefcP3-({V$itWX) zZpUceIC-|}thqm8M-jLk0&G}K{!uasPvp@?9QYs)1yl`<bv>tm$gZQ>5P!&JaY@Y+ zw0xq)SXaSmsU8y$qUzL2=h(Sl0VYHRM^oXupwH~miD7I^Q`xf3M+km-lYPOCRHc44 z59LSoCjN<y8ajr~E~z~3`#0wFXLWnPkkuMldlAyR1NXb#c2R|DOQT9ShQZj@gQyq; z9+oJKL1n0Yi|y_?rlkuL@@G$|afZJPDWpm``zndp33viPCM6Sbg!2e)Wk?veMFz!C z#es~%IiYra1>3`l!b+(P;v_$S%<h5Fb%0_}-CHav!{;Qyh?a-mswrvcE44-TIj6Xu zg2hiDs8WI`z_z-SK#uW4z{#gSb3b$yZcGFeR&sn9MXlaR(~ecIjajG7kO<7_z%}Da zr!VjxY+xTS4q1e7MNup}mTQud<PDiHP<!GSewU~Z{r5+*gZ?qkZGtI|YA93;)#+>> zeC}rZ?u*1BxEcw@yU2`JGT^zh{n?be`QLjYmg2)qe0^&18FqCdL!5Q(?(vUqyF$NC z@isE`_2YRH$(tj3^RNTI^`2xG8&lbHzqO|10S8z>%Vc-sp?b#{kuf~rEUX$0Gpo>+ z&h?Zml&FzgdSQBBWQG^T`*hCa@M`xa^fY7Uf(Hkuu8%Wvi{L_hd)U7*rZJxiMe33B zmE`C`qb;uO>-FvFvF2D&NeqRQ&@6FtH2rll`q|R^OKA3skmI^!IgXlBE6kJWwF6|^ zy7m;Xwx%1t&J40!KCiY(`(41^$9`Vr=a&-jXP4n{3C9$=<HUA<P_8J6>pomhGy|rO zSYL&SFlc=0m=lgSkGEz&NJXe7NuZeX0!_KhRO>8qiJ~kGd&hY-`4INce-{d68!zA` zF@KUR6yK4lU;<(U5`P&CTH9XY(eO~bOIZs8+SmPB!qa%JjmK0mKdhm5)UD{QFklF& zTn2g2UK?P7W|U8Zs|=YiRik99vl;poU~ztOlGkC?9~<QD|LQr-^iG_0E7|4ap+bC= zuB*kMyKPY18<t4t@?_h7aFmnu&2VF-{rH7ukj&rOfaunbvgEO*cX5hBfXes@E_de& zILeO%3wv<E4$crY_L@0l;}z0j6`|2A_NWH1@1NS|)z#owg+Gg5fhVUxyzJ$*_sjx~ zvNSDuUUFD?-19Ex`rHI*eu(^ehsJ9v5U#%eL<E&m#9b506R_+8iarIHDdBKIaRd~2 zJg9z|CYTk`hIAFeYpMpNRWR0~QgvAX_wnrXuNE{SMyAd7;r8>lp~k%p&j=ss9C%1- zym8`Q-s8^30WkDc{p@2uu#P0%b)%gZcS+s!qERTZ;xu<@p|ig<VcL%w+%#~LLe9bO zP;3<WUlfiE#R^oqZEky-<Um_z?^B=#Hd#DWE>7iR6J4{w0R^3bBfE=hP>N#U7BVWW zdOCO|)4^cse52>}vhx;ijDX4p%8&7A!zan?UZ1GawQ=LDvj?4GYnkj7+H0DAEB?(L zk;eg-WS3RvIo}Whre0(Un%M>(b!eXMJ3*w-4)`s&YPC_?iX_>Vz5Hm#UMlPRH@XpX zd7`?-$Q;2NsI|R!-&!)$S6B!73L={%Ik*r9!S*Wc{1z{AyJ~8N53;1K&49&!If@L5 zcUraj6&mza?><aRvrx+k0wo*H!^rx$kv@aaIjz+;>G6Y&1Cp8o0Xoj-Kc;23@R@Cw zOOjPqNq+KqcTrl~PAMsis>%<lPqW+Tu<aH9&Ci7H;OKa$)z{IRaNGbI?c2L(Fpz^< zV>LvNWBWRTTEqSs;Gqa2Nmfn8f`1HlUdh;DwUoeYY>N4|WYGUM({r9rihW9w2Kl#L z)l3C%+b+Emw(P1GDG^~c0R_f)`KHQ7wfHk%EC*}Ex!vIYygnbRG;CwFnUhv;|E#mS zsZV_lF@s{a(u`tvyu=uQf6=>rOOy_(&_Q_DYaq)1*1^<r*1_PBRfHoj*!z`lQ)%70 z@0rAS3g2RCEw2)j$p<Am1!}P{mFXQHg}uI&KCAm+3}u5+diCL`3V&BBA@ZOwnFJH5 zDbNH0`^OirCuHn1yQ`(fHL=60o|&>5-8*SDuHC=&BluuPpj#Z63bCGEtEiCS@cVqj zQZAc9MAGSId^Wr5z&NrVo8r>#{@NSu{W{{2cG!W?1QZZl%1QswgR}AEpI6qsW4R*R z)XVgxiTqQaUTS|Q`I2K#^Saw5y!Pn$Qf>M6;rzTBt+hZW5X|olQ(X7?h8)*8RK8Z7 zS&o%;{i|{?(1i+=ttULTb+u@~k2uV(QXZ~uu|Q{K<%Ak@^)%&s{EVp@<-9VuOFI~R z#%_8oANtzNEsIXG_k^LkDvd1ckGFd%9MM_u?V@R!HR3=oV6T9*+yE=pyJ!cI+g{0o zc~jR%?$#za#Tn&2pCS>7AqbFUG<$UaPl$lJbdC;iHNgZ5^UTYrbho0K67F;|bKY9q zcPCprj^#>GH`MRU6M*Ie%Zb8gwQ2ms{Ppes@Fh(cA|^_?MIcGOgC-;fna8IBGOSX; z6)O@B#OlgNz^ozh1J!s({<(Yy>R9ebs-@Dv-5T;iJ3;=1thHtF*__+4@VoO$_b!UE z^;~8P$UE@3Vlb*LyN5i~HY_vak@uz6W%rz3De9SLWgU?(fN?B)z%^7<KBsi$U7OB_ z&SKkX1w}?XL96TwS}u<jJ;br-M+frf%g@V=)BGmNR-mm~*4n?W++`m@ih+wq#EA;m zD~D2Nt%fLard{cpPVSLAO^s;QsTxl~54tCjQVT%BC<}Yv*4~`nJfF;IsYu)BUsu69 z2@>2)A=JMjLUvg*y+*M|6ZjDM2#}kZ%phn}bgHkrZxje=_v3Jnqig3MaBNFeIQo!H zdbS*%+grfN8T4Fu(giEGcoytS0j>E>5k76rRl+06?=SjZ@+0fQ%V+v?2Z`G4mnMw_ z91TFxIrqbrXQw?1Nk(mk^4S61z@tky5}*Gt*Y<IUliF%jnWBt4c$fn-s{`c*vmm$d zng_#R(pN)~%ZwJQ-AKkj?^P9M6y6UpETacszNQ_4m)mT%Vli8_=vlPlDKKtwKboK> z*WvSzjsupW@SJG{QFaNL|Kt3q{kaW`kR_mYUCjrtah55IwWQWGlE2@8x%Al<5ma#1 z4{Pk*9PgekBxAE>;oW<12W`HMv@P!Yy_rQlGw8#9f15*+>qc>MG-u`ZVE%<^ROg+u zSkq*iX1b{!lv|ZOl2#>?|Fs+LdEqyaVCdfNuJZmu@ar3QWADu0&G{ep#)dh{!Z$B6 z1d>5of43lMiQ^h~?B%zm2h7a|IMdEpm=W{K|98JRp4JH2g$DxCt_uQ!2a@L3Oh^E1 z@ozXCaHigT!3B5gFi@a*v!<y|bSlIwR4a7O|ERrEpgi)hj0`3p!6+yB*~vkxW_!go zx%@TqHTWgnV>$x~(jR5&nwX}gF`xKz_kXqtI&)7+MA}Z9#II7I%!+kXFjo0WS}Riz zSJ>&m_*qz3DN!)Q8ds?r$#uh23k+?zYZTBg7febt=pISXm`n6v7_~6|kmme>4C@!U zq1JF0L{4Xx5OT)AE;OOh03&+_9|-$Bj!cJ>!tKOZq8tQY%A5%LN-w9vBCA}Eu<1k+ zr^>MeBbwy_F+<CN2FI*ul5kWUek5aFKUV%aFLcL$bNbT+?`Vxaqjo@a92oFapFlRt zl$%Ooj~h^3?mc!+&w6c#`x~;*Qg^keO@Mk1E7v)BuZn{!5yd<%X^e!SFTX-|+L&lG z9`pAR4z^TB|I<MbHn%sE|NH6kii_-)G-4uwn=Zk{lLf679kO?4t|R2^XV=W`UsQ0? z#GS#(`vImy1G;jVqrvrYTp$kKk3W#f3X+b=+lz8;06MaapTn9o_kQL-`SpMfB5Ak* z#86H98l)K^s?*AhSQ;~=Qm=5IRFk*QU9(9miFi~B?5pgVRJ9GR#P=VZ-->;fxNi(R zT8Y%-JCygEtX8O_W@yRhN`4}f|GWfiwL?kg8)(Wc;E^X|s<!nR4FII|NurEqP;4TE zi6Pu9lZP{AubH`sfyD4>tT3TcQc{Ysx#54Qv#0LZB~!hfF#cx1pkZ!~TXG|k_Sxjc zLhf>69MleBv_(fKk2TP;zJNrg%^Cml`1T`+{dT)wGo1W0sQ5h|WXn2K9oBhhn=6f- zuv-hqBP$5eHg3qu0vPfW=P{!>u5vJr!bo-F%)w6)kEU{*o|S&|&%#Li^$|aU58&;w zY}XA%kb;?`%Grw7hJGM@htnto7eMz-G~CM^fYAj^V)qe)bMQMw%r68w;zxYwV>Pk^ z+_#CIsXylNB4^&#H$*J9<JLl{njXF0R0i|ERdP+i#b-4t0d^YbKIB(1X8FO(>%)q& zLlg}@8L{Fa&xTA434Mer@#O{RcGu>3V>s*BXe#oSJL$}`8m2@PNi{PxE#hNY!~^z& zTxyy@Gz}@xJDH&tHu_n5CVzXh<P4rj`9;`}8CCLt7*Vv~bhP|*b*(0pR|HR<2+373 zbMiJ&H?5i}00jYg{Yb5!8l|mR6)w2-ZkQZ``$4qNO?Xx<)jv4UHA|Y<j~vgofEnGW zLipZPNqaakFT^psj-B1f2f{&EBe{$qSELnXO)v6Rlb>FAGQ2JxO6-^5*nN>Y3`crC zp_~b<2`GpuOg!`~xQ9oMOd9h)BA7VL0pmIFArq85Kt==enb-)zN~s#85!qx>)``D5 z5#!}znTyUWU0pGk6G5m@4^D@TCMfS%f?{E9?CY)R%L^L8i$2$?-Tewxu&;VsOw-gq z%KaXLGuG3llZOls(>cbQaJ`_Z49{vG`^^76^XW={OPnbbynJifGWsv%hK;A8v+j&k zmV10CAkntL#eydH(wNGuI7F_3`A-%GKL|=ro>bS}!|l%y>ys^Xym<_kyu(l}9H)B3 zIUT){@*W!8jN4r(SvMmRF~*8{m0}lETgM!1eULp7ezT+v4eCaXeV<veOw)MTC-w$V zkg-sg6GsnavM+TX5~UO)*BG;=OBI@wS<7())Y&kNqy6q`y+CHTd^Sh_t28_0XCELE zDjb7AG@S*P>dE|YWtZjo-I0GRA}q=U<5O7QI%>R-eg8yfe|oLS`~c@45EI_*e-@i_ zCAn@nt2ygCh}fmB!gnnVAEy|}KyO{yT+(b;2|TtenyxTB)^4Y!esolSZf&gB1l!pH zfY^n(j{S?;XP&fj{9eHFY-fm3Z$KcxgI7ChYtoVmTBGKDDJ-WHm$PdgBd~ckEm${@ zEQhgIO>ypRF;j&OyFEVHxy_u-kZxz`(^${kvNB^AJKTKVWKQdG)J*J&WFrho5uBS& zR6#8r$S=DhKYlNs-MCDKDN&(t-xm%v8<MDa5}7ZP%)4dL?L0Wd=$)@7O@Uh5xZ|c@ z38k?~bu$z^d36B%lM!OaS>K=bdAa}IHrQxmo`k+Xh1^}RzbKQ~Bq!`y+y8uD0DfQZ zfX|~NTW~4#RGp>GcP7vGIpkxF(F{RTa_*{7{dJLtC}VDK>V|;*DEyCKChtH?Qzly| zNcX1lZ$6gO6ogKZXIH`BdRfGsi`(r5ZX9XCX8({ip-9Qm`~=`NYH7ckaS{0L`O|-f z%`60dP~1l^?>5YmqfRnqn_8rrw(?IyZiTVkaIE#=!JA*4<qcY@s_%*>T$Js?zNgL5 zXscr$j$hp|^(NqW;fUfsV+sH{V^?P#RlMAH2`C2@hCeE<FTo%WzE}LK8}$5l$Yn&L z?jJo9zR3&ktX<Yz45bh|uH6MzCDIL5AB{-Z>a}azIt`BhV%P$XveP@7)%}&a+p&G6 zj79=kaWs)(;9GBcCn$&s6ee6P|3>Ye>(8zqU*a#_eRx^xw|R>e56gg9o=rnK6Q${{ zlfKh+`H0>8Rfi(`ynf_Xh89jN$~UX6oRb6#+k&p2wJ7c9f^tc1^77Hh??UE!8M6IJ z)@h_%fd_xF7tH4^Rj8v_x;n60Q}=h@sy-<vjhvyHk1p1@L5Ry$DQtiBD}V<1_i6W` z?6LPk2Sxo(srtauvH}M(U=H+TXr`%7_7(pCH0F75DCYEkQH~MLO(_aZQ^kjxdro$_ zTw3r@uUgFvEm#C&ja+MYqK#M*2`l*Dq4&25AjJH{+SkkuGFFNN|GkA;bbkVUf7<lz zU0!_CHr;qwq8$PpPC^F|=Y-S-yxH1$eI31A&-3RFbAb1$mrLO4uX`?DmC86jcyf_G z8s19OGFfOGy2BovFq;-_v?JqyHz%UBd3rKvBoT|@4}?`zCCt`VroFR`E}skyExE?_ zZi*v{L65Nk!M$+Kc^>kutQtsIDs0$Pz8YqKRi{l%EUD6|)IHn-R>$EhQxPXQ3+gd& zwd&vdBngAqln6koG~d-;Rd)uX1Znn|-%Rd3{=$I=Cf1(vppY#Z=N~lL){PcPQJmNv z=IG75cU3fW6uz;x{vvP$4Db{;mZ8}jiPUIPaZGYdza}wtBz=rFC%?|3P@3!L7k<>6 z1OXJ@yC8HrPSpDH=mDAAd9wP3_AL=43<8kRMH`Z>(@)@M(RdDd+jE2PbRRYM5t}7? zi-{uPD|S}(;LKP<Q<{lIbD#O9mmu;2hKJsMbjJ;<>drN^6-JFnS@Tk!2|4c?0t=yu zo#<*&78>sc4b2I>HB;kz(HI+s75O=Hsl2bMvP^F?$5VA$KHC1cXF7I~t9VNwXJ2!C zQvJ$udm4Z$`TFPNuVvz#oSVXhqj-r^C><iL3pu|6qmeo-{=7`cn5_6|U3%rk!R-mx z;1mAOanykZ47|`*isRKqf&2q3h`+jE;Fxxq<;M_YOHb8GVuoBVFwWfJ5SI$(?ElS8 z;WC_`LQ0D`Dl0JVXytH_7d+-ST3YzgLz}B#*%?4YL4`1;-fy-2=qk;kAa`=S_Lka! z!JY#F*UUh$*cC4a9HD~7pLPK$6ctNtlcRM?=UcGG3{BeDYV1Lj%n<=QLuAnbrL*R~ zrkbnZWg3QTF#8GN-Z&!^Z=L=ei(*a84PlE|kSfW#g6Be#6R?J*k!5GG4*Fy7<h2+$ z`Ak6K{%(FQ?L?o0{T;&sIj!T_SZ0NLG2gn5mf+zq!Al)Z*XF^Go{kP)sk{!HnbSfH z>PMJVtLrk!ZEs!ky`mhsBMB~{;$qE01_4iY`6H`(Heq(q+k39|AP}36`bsh-WD><q zTsiv-Zk{uXW+{zK!Q|7qNAhYYc8Km$`zc^0)oQlS&%Ka9Aaf-4Or52z+JTe)*b0Id zQSNC<xDWxK<I$?0hyNOHd$KG*-Xbsd!03bv?J=)o<saEn!o25Trau92^B$5+Ga;io z_FhzE7w0YCz!W2Z3wGiQ)!09PHE#GE;JnT{21Wj(T`V5=CvZJDO&@8chNS1u(GB2U z=hr(oIscAPv!LO5DBe&KQ25)ie@cnxNo2C2B_O+iuE>Qo`$Q8LxUFUxXz#Vkz}oPH z=u357gjmtIE<y9Ggg{}Xh3D9!Iq2vpv!Y;w$&6uZy95dW16FyCNpij`IInF}wndt* zm%VUZh)WK3l$weSi&Uc^DA878E(#>9*|x<U;p5tv9F|~2(>avqj=g?BY*G)HiqkSQ zO6C>z!gdbk5QA=g!A&c+{)U&U#tD_@V4DKN)&dOHZ#u<U8CV0M7zg5x;RE6APa7ZM zL=NaaY}$$6Fn#^Vby|`pe=M7BYpS+lRQ|4;ERl5g-jqIBhntp<;XU%5>j#?ogN3;s zA#lsLjqG(_8Zys+B2-@5rCTk=kaaQ!Hh}c)4&f@p{k(*cS&A9G1Luah#pXCnul6@k z^($n^2jOoj`>Eb6UV#XOO&xxRJ*1MzQ-hj@0Qp;#W)!8bL6KIoea#Y_yixMxYae|J ztfW&nAFVQo8{>(@B5>nny9dbD!c*Xa3XS*O+yMRIk7S-b*ty+DNYs{&)EdY#J%wOb z^JnWL-E+(5!UEUm3X~)7(rQb1KQQ6tHuF4a>sGrE@fjodVFaZU!yk4Ao~98GUG8!( zlBDFR-^(nixJ<ZJ17j{-&9dV<#_FI(mRTaMtFhjvNeJureoBn%1}3m(tzG=05r*at z$=9r-M(+IJYV_ax(8gLgS-vka!Y_ZYygm)ZwuPXl1y#m1xnh*VnhZppM}7f_610Np zg;X4?-{IzEuU~W8KqGuewPE=H`Z{~qrkk3eMS0zcY@&9MK%!$Sw#{(_`|0iG0Ab_L z53@V@_exMHuca>!;v3*kcM|cuU_*Zw>}fF^U2Q<}q#ZK6%i>gaA5K-_8vl;l!@5n7 zxyz26Nt?A;6GV~SHq=+v=!VcTL)~Bcb2BWr430FT41Oxl=Zqx#iY7UAVciYgbTnIL zEazzHyzL1{Nn{IE-f&4F_0;R8X?GlH{AR(DLd2C^f?2WJ=Qp4P3ajRyY8dB3IXX7E z>;31h?^c!{ft=>DY_KGe9Ha{2=J=yDE@P=9wJ@=)5R<Xi;sitlda;a2RiF=+xCbE_ zTbKyGB9eA{ybY+~UsQ^!$zYK5-o7ePMRY^g%toQ9gGYa{5Y^euzG5Yb{!l6K)IG*u zl2vY6J8o^Y_1Az0V?TwpuR{M>AoA83a;I)bob=g!GB>`gO8{O!fi!je?-}T+IZv8l zy;LF71JB%~i{AK1M}gRDu|@4V<I#PL?g(Y-V-u?rRX7y=K7<91vWqqP2*WV{A8gLY z7<*d&&Dce+;F3`kVkB-Ls2UneL2=}2PffwECJykb#q@yVPk1<SFsQ0VwZ#13*(9aQ zTn6q!Y}tsTF>?Ln*f-$$V}4+l?N=TMnh#=A1jP#yb(oK1B*%k0NZ+aLcK1+9K6w7n zgL3LDEGTK>%`e0ZBxhb3=&65P)0!4Y>XvQGtj;NgbP2yg;gb*6Spu(M*(a|3hnkLt zMq!aeYjA)P|Bh{(&MXQ|d}n3YVh*uOST-qxwZlFH%3;g24s8j`Jt%I`#)PCGPZ<$P zcxXjTiR|)D=$b;890YiWUsFo3qk}J%CcV#|X_OUGQwd&W<r(E1Qlxyj;kPG`BLy*= zOqI+w6B}^VjCG=Lri#DVV=&9>8d8pHSN_)8QWpTY(P&`S2TCQ$|4caw{&5jr{$%AX z-OJR>&ZvwSk`3(I^*Ea5=AC;!T{j-~_FK`^W>mEer;<xn5=oBD2Jft{NDgGE({L;a zQT2q=LC0caW}35X126m<D>hgu8zkz$-N=A9Ylj-V8ZAkPP6#jB`AWY<PMt#3%*iJ- zxV;9v*hNXJyBm_B8TrVNAf}Bt-ba5kz(RgETJfZWtjp@+4MAXw>8yu>qSxfru%fL? zzAa%*x+jP}?uz3=tLwF~fS~On8~MtJl}@-!T1Af#r?ZwkK{R^T%d$rrqqIT8lHx&f zs)K+))HP!91PzL`MN?}im?v;DUvBNRXLSNC)-0INyG<R&F{Tq#swPLtn37l#nTfe0 zCnUPgzF=~zhba%2KbtCxAZ8FAIs~(i4<B9D4}BB924^4c4a8NV83={Emlbt>H@Ka3 zOej4R%r8QmlM$l*OoJ8_t&*F_RK0FF<VE?Fq?xjlb9UoC`GBd2G*fT+`*%!Kefb{% z_hRi}%^-Go4x+xBO<DzX6m->R?U2u)i<L%jb-_?{E_Ox@Ts$b91Qzz<>^J_dbs*M^ zSn4r}G6{WwgcGtoK6eX<IqHaE?ofS8mpnrd>4ja)C=+jlHtm$-N=^JT`Q5-#WK%p7 zlm*+R%>n&eopG2xqvJp{Gw$u0Na7y=7KFkw+)Z5V7<<v&+TVF{ZGAl_Mj(=W2=yc1 zjD+qy>nzGsKd>Cb@IVjKR$z%EMqeZIK~fai@V(MhrbHuC9NU*Dlfz$r^;fabUU{uo zxz{K;%~kY&e|{glW6GYS`iCqiG%|2?1^p8TCJU|w^(RHHY6YX!E7C-bex7f@R%cXW zrS!k^hdZ@u>q*>fcITkjP)njHo`WK2LT9mt?p}|r6kS7cJUqCK^Pd`#F*>u!$r<HW zXQ`O}Iz7bj^pm)t0d{+n=m%`4CPf`(5fW%s7Rj|}2cgfgOZ?3$NoG>{e1zs)3#9jD z3zH=If6Dw>&YDQQ&={1;e))p{hkptTe54>6uo0U23hS3>BfN$CvOCQ8RAfHEnbfG0 zJ{7oF@sAstpy_-Y6o1KilI@4O#jp6V3DW!R*od$am*&{CjCNM!B5>5#RN0nCXJ+%9 zU*d2L98f1cukT%~P}XdNu#}t0==q5|<u)NoB#t>l(1!j$s?H%i6D~@(v2EM7ZQHh0 zvA@_hDy&p&+qP}n=B@ibJ?NgF`Nmo6-OVt`Le}D2OY8u^YJu&v`+2Iyy8K;%vdRhF zBR+9yxH<&$JPIY{X<32ONzony{KO0PBT}dUE_-O>&?>^dFZl)*m~eLIrB>FgAt13p zdn+z_toN!j4TsyXv*^-`So$AoB2E2<$A3QKpPo!BKGBJxB+FLbdS9cAy6R3pmGt#% zBuT$3OAnwh_;&W-sMwRK7lnCqI-kZ_qB&y-?MazHz4tZ|?csR(GIY4Jou@CiEw^o; z-yZ#ZfB7_sspB!<u2GSJN1HBTVJ!*52f6vQISQ_p4chG)zJEj9cMkbRtXJ5wE3&Xu zozYB7MlSq46lz8Wlh(&ll9=WZcgOfOl0vsNNCY@AZPyJ&jNv_FU$hwaJDHmz*`6|P zUj-2a7sgLqLMwJbsyH%{ri0K0ij}Q*bg8dI<1F-_0&4sO5<2#bm5m?Q438_|w3l7c zO}5QVf9e9aQ~H%4q;3-mA-c?KSdDE~8ThsSikn!nDxd_34IxkM3rFBg@8`k2r_-LK z2M;Lpg?^M)%Y_eP0Btn9ek{52xX@bZikSA5fnn9=c)5ze9jV9#av2EY5)iOS$k{%P zvqAp;Rx}KFA{@G(1@Q39e1Rt3z1{rWjtJtvD>BwP1`s|HB5?6O<`p;Gh#^~w6#%W$ z!rq$*37+@k>4C>rOBTYPHrY3%Gf~f0R{|VfU4;i}5?ZrDdNECbl$b75i=Kp&n!t*M zV09v@St4QJCWAU;h-Ja&Az=m1>fx3eX(!=XBKCIINdTtTPB@-&UXG_`q;BuqQK=R% zeXp&0boSWNOX8iKnZ80+We`=Tf_e0Vy71m*?UabK+Sh@W-P*Ze2P12)*cKaJLV#5( z=hI>&xMg0ta&On1($ko0c7JZWmNk>|zO5H3VZ8MZB5Z9Ygs^yR*Q-i#Mdgh*9J~#= z^k)K{&E`S{w?sd*K%Hfj6}%c8R<l2wP;xn0c52%^;pBBTH{9Fi&m4?BX*FZ$xUPsM z%T|7dnumqaGi_)&c;bq2w7+p7Spd?r0JYExmuZ-T#l$W<`|;q>)iJ$kPryx&s6@%F z9qEe&M_%!()s`(F^{AE^Jde2qN9}XomwO@9|8dQCh$Ev~j-PGbR*x*K;~}QH`4S|9 zKJ3+!z@bcj%jE)%-?hT=F_Zxzts}~q_u!S{QtqqSAyC>+A%B4SISrM^4bc3nKm}Oz z*5v;F@#~_(=svw-Y-nR)r3L`C{kt3d;X$0Kt<}>**wkk`Uee0?LVu57-YDAi&+@qC zFH!Tv38r9Ur6p%HpaJGm@40u=W!@kPY1&OiOwC9a`<O!9a(tpd&HJ?o%rle&UZbn= z%hJk3ml@Cn{cx-Zpex5qIe?rL*XzX}{r7U=t_n(wD^9*d=`GWnF<CMdHFR(hhnPY< z6|8eUl`$_SJfbQVIfc+np=n*d^_L+`!)=JevdE1M@4yl7Ku1U2Lhu_H-O*D8-QZRu z9_Rgi^EY=L`4TM!r7CX+f`#L140O$$1(l4uy`xJ>`;{pj*SA#iK7dxT(It|#N9-?M zhXSXInvn*VOPGN7Fw$}>A6L*T+F{#1n~C1w@fBC}6;rwTKe@#(3dvpKrt1~I$Jr9m zm}bFQPgT<QavHbE(1`}R|Li&{HfinngBSL6*b(r~zri5E@iX}Y$;}!Je)<7dLFFJX z+o<Z%D|=XdC<d-wD*=3wXuLNGtn}3+TGKU%!#74uLCjRhDB5~{D&MM2TWUE4?^o&l zKedg$8TV6Ur;e?DAfB=yy{AA0%$+D#jG{^MvNxn6AGT_*FHZWh$BxLw@u|ufrg!vn zzlQW2dJlaWn3f2F-=<hX5hRS)^bP_@Bcf60g;doTwENZ`$p9{J%ZoEl+MPGabkl@r z_y_bwpyed>E@h$D38#w*ZO4ldsO`_}Z`rA)MkB=JdPds7bkS#^2Ue4_%$fZ(ICn!H zBXO#90>>Nj_C(=Dji9lNY+!j{s>(z;!zf>)wUzNz)<B+bdT~dT1*3<cj|Jj1$v%{$ zx)@a-xpZy{YygGs2B9Xtg8URNdas7twsws^<&3G1sy2QVXx>;cB}9a6EC4RnU{<Om z@%ByKk4kc;<Z3MEYODGk&!1>#jZrsH$Cwc^(3&HjJwifXyt^~bSVEwOxwHZwGU4%> z_NKx2DEjjyaGAwv=6w}6{zr`S_e1j&ftpBFhi^+3B7n|E@_B~#(lQ9T?8G_Y<GkK@ zX$|%B%-%v*d#e7m-*DtXNCWpY=H1dVw{C<hTmx2ub>q19ZVua@OZ?nLASFjcEHbLa zn6F#Z8XC(3M%~oa;_g$im#%B&&29N`^hY-sEdq}OqYDNaZSSY0S%G)|-NmxL7UwG* zyDLFdW`NX^(1Aa^C>NyjQyi<&I+#lNmh<hk3g&qKxXIEjY~;_mWo#<<32K$!>(%7H z?`a1|nQsT@JNB4mI2~XdV1k3W7R&*r$SfrUcK=LF(5;fA4;N9tozva}9gCDivxcvR zd$?m#*q=e)v(`H)x#P+o(EklJgZ#^Ek(R{-hX4PWE!I&s8@13tKyS(Ra%_MhbI4Hw z_d0#OfNg_X`dUO`rrFi|7@YXS<in!i!k>@C6f@a}KO26X`9dbyMO0Cruga+(2Dl?+ zU+0I#IKM9~z7wr^ZDY3^bUboOa~8)Tq>En-*c?uI_rx~~(rs{izKalGpAB?cjDF6P z<2_gzS0=i31Ywt~P(yRJJ?;UAwo4E1k&b;<=7Ru8>p=r5&T2qOt`}wYPKhFH8edU` z^ic>fBF$YJhF^2^TTI_fPJNsQ{)pmD%$x<X!2-%lxX&NKzGnb|875|<!Qsxl&h2fI z6nFL%&Rl&{;{`%t-SX8s59>;{B5jQFSejsc?DAGrCH5Y~pA4|%-2^~6I1B@pO<GJv zSYYzQVTG$nkC9QW8GRTkL8cm9%6`AkH`(%6!OM1)&$au*KmJC%q1l_MNsDvW_NtM) zvXj~g+TW7ETDQRFNm|xT8_*Z^s|*IQNr;n*j1U3i_lGza1Mh@G^5q?+(r+1b*k`4X z<dJZb;EHmHpGuEHe;L5`+;G$g^LEa$e7*hSPz|dV)ISrj`)$NVZW59&U<7>Ph#Ct? z4@wBJxS#a3L1O3ZmqZ=T)NhBqImkMysFz(N7v8>mpgIlr!mPwaeoiASmL>11P5oxG zpZzqsUfJL{IFK}()vpepFc6~_jFi|PvmR@53DUJ01E<uCwO@dWYCP1u4~6A<H%JQ~ z<q3_bVjTFxKw!n~i!7Vavt`F|KzIE~GiO$0!DlfrO1Th~YOFEjQaq6Y0AdLYcQv|| zg#;QbTU7gZbZ{>Tr1~IG0__*{r@~ln2;sn}8LWHe)>(lqlU1V)Wpk$h5Ccao!Qpn0 zwWqxSneWNufJri*A`@_Mvb-W2a9DDXA~WjX=hrw6J)QP}A7g7@jw6%#HDdCxB8NfC z(C+$?JTN^Ji+d{f@(Tf~gCA-QlIK-tXxvn`mv&rzii)l5E>yp8)jA9(<LSmcfVMO0 zv{Fl7g~I7id<_)54iV)$_(az+MqvkG<sT7vaa6G%qymy!b&B40<YXNsdU)FiW2V9n z16`zWxL5S#6eSYC0<aEN0Qu55y)YG>s1UDXSluKNeJ+rC5c;W^f+^zf^nx8zp<e7m zdEHfVC74}hpy};vBR+T1*VLu8$9IjX06P@FvkGH4egQIho{_ejGLHTz!=g~FT@Hl~ zQU+@N23`i%`B+^nTDOtBIuX;oBO28x%ItP?!YLvViUI#*c4a)=?p)QO%JDT5@YJ>w zhupCJJu0>MBad*wq8I#RJ7qk;H-@@1-bIdRrx-2V?%#;4T9ZGSOP&GNmY}3mfI#xD z{{1Ik&|V-#PFIa_en@f~We_~bfJzJ0T3{nLEaFYsO~^o~Lf-4AQ6bOh+(hPM%c?m) zC%!o$qjfVn5KdseY{Z<2_zoBd|4{YktWwG7W{|8N6W$Z=j`nVcqAExL>{Q0P!QZLp zb$!rrx?sl%>o4<IR}1KA2IAL#DY!>x(ljKz0P#7!9xs=N<EN*8(ExUR^R;C*T|Hp| zE{*>12RQkUPg5H$f^tWhnpheu+7SLegNH1G6WzVXB?Hl{Zc8#)YPCwoLyc{PpSD@9 zdXXyF4ZD<l3YTb1g?&^2IO@lu$BB%?TpUOCW!K!>@6py!JP*uX3R?0;RwRz!l>M#0 zq1JiPY$1bhg5Y=j<{+t%(C~Rj$=P68PY*|#3v=<-X`iPX{x*6lUc{Bg&(o0;MZ#Y= z@?m&VWfCiK?_V1AuW-2PmLis+utFOdJs1=(5+Qdy;O9Bg6?66jC^W;By+Rg%8vT9y zO%>#Nu@QU(^T?KP+4-aAdSlNKA|P8ypFv$Agb$2NhOxJ$1Q#Ic1?A268%iO2*n&(m z_&_3hvlnrn;Tr6)?oj}vh`f&(dwbSk@v<p5vKnLyRlQOCWKE9;S38E9oJ+QyShsHX z88dj2U0^)xMS5=la$}H_il_CGCvSZ@h;D<@ASH?DRdW!c;Z3#fGGxdHJOPaU%r!(+ z`dyl$xnm(q>82sh09W&nm7PY|#+1Ai{uFc#6m`I<fGYH&0}zy;SVnw<fcq7bHcQCP z6@zH#fer6)sK+=01s5AaLP5R>c3rZ+qAN-eYyJ6Zhr=*n`8g1ePpo$AlE<V&%kxyh z8Qo|NHQ^<)Rctb2e%SPqeEKMJfz$E%xWI6GxX&TPm_%EQ(P(I{0EtyW(@PC;I^Y-X z^=i-}{Y2)>>5VB&;)qA2aycKqY|k&h%$E9tE4&>>r-~)}UndL>MKUnvQQ$QmYhQ5k z7PvUJWOY!0)8p?+!<__$3i)CnOSBfwtLaQp1-E3|9j`)uc4@$k&+#~xUw%ja!{%GZ z!OID=-2SQw5%CK?q{Pt)9bv-Y3;IVA-`A8cy|c^TaK!tqaNd63T(PqdeB&CqqqF13 zP8Da5V2`>$uLZcS!j3OUu20EXKdc8<o?peJJLF1$#Zic|#_&8*7=ZvoRZQMm%xb-S zTI*n*ja`~&)+F!3Y0VT1;FMm3y?Qk_&R)1LeExHDN@BM<X}9^85$jY$o||^hA%rkA z;d%rQIA9oJ1Z|!JB1XFJvVt*636mQj!hL!@mdz5rJyM)dfYH)kdrmRWV4H;w!9~O~ z$My+e*_B&_nJ0=&hy{px|GmE>Ht3M%Qi?nBi=+}l&HJC%HT-M1<%TUcmQo0KBy$%c zWkV?cRl<E9e|F0Aac$}E0=B(KF|ow?9(Ni_Ej1khE$(g{6A0`am_oF~E!BuZq63=} zVjbl11D&0?2g~|sl~@+)*I$i}gH^<;&51b8Y$T-&=><O!!JAQQ5+5$Ou`~)HDItHV zl83DF`<b%g(!=yl{uz4$%K~d8YJo4o@H#@e;&PJU=*q*1wI87W-KIQicphmIw7~!Y zoe-uYg@B?ZD{5c?bmKQ#(fwa)jPT(|82Lny>DK#8Te2-EI)odf6Ee5*@!`O<3+*h- zl+nxXu!O&TdIqA&#<R#eo`UHU`NB{98&+59=jasKS4?Is`@1piQ?03Gk1*ZK)>BOm z3<YVl-%eB<S_;?SHMK8z?A5|$%3BqlrhCf&WTD4yE~HumG>T<@4T(vH>eo{~)<GEb zymj(0tVK7{Ey$0hUy7J{k8LmOjMC6sViaPy{oZ__Nrz{cx>g~f>pqF?r;Z<08c{JP zL}~Gf%12&fm^S-sHpYLc7;ASS8F&3}T&en!uC8x9j>lX26#fWa@gzuMq?y94MT@36 zK_tqj<93|`ygt;3yS?-?3Lsdnok$DU;NS9gywB4q0N=DJNW&8tO}HgJkl4%S+@2e- z)vrIu0HE3aA@-=Np-Sz@*=dW98<9mmTA2?jLs6)@T*-^@j65B!_Y*g@<G2Rqdh*6) ztpcOR2v&<qdpBZ!=9<L;LO2f7hXfku!~&h(E_cs>fu(~H;-F(K*-CdY3Dz*gG24Mu zh~BPAl>u4eY_XdVnE>lI_>wqp%8DbqyVs{sDsDXKhpry}DZygwQklnY1uLJidi<Gd zl>06*0-9|)?STuF5`vKqOqvV0Ru%h!WIeV9ZRfkscNVX=33lCvx3!*`ndcMBx2Lt4 ziUvb~hNb3D=8Oev6i97D6CxzDr?35TAz9fxzhV-2Twj`&$R%xTf@nzA)M*@{CR}m7 z(TU*f&G;yE#n^EvGV$^wT%9FTij^@3G{OY~%aBdFfX}nvVj$f<K45eR!^9m3e#KrD zn@h<A1U^&aE(pv`{BczmJ{Bo<RvM*`40aU263Qlx!Jp`8b~L>Z9ygR$mKrI~$<<Pn z?*@w_=$Ff5)k^ub3uc_{7M@#saXi`>!nE-F4Bzq-I8JPCR>&PvoSCRf_p6_u0cV8J zxI-C8C=X#JX$m@!x!}!N#q=0N$_Lp9dS{ocB3TvzBxN*9a}F(5)*=N?W92~u^8^6M zW~9>a2v@j^Z3RzG$uU9EUknU&y$g?7aawE9OqVC^yK=N%bAI_`^k-9yUZ}{eod|D7 z%bYz*ENhlX5z!0Opc84W(_x`A`;E^vVg97nAgW_s>I{NeqMKpIUY3|*H#ifaM}eeS z{?Ul$<qM*%8pc*3xC{@rc4}(bq7(r@wmp@6{Iwiki>&H|j@W<zwf^M3%@G?(QVOo2 zua5Kq8N76&SAV-f@Z&4M87DRw@TTt_Pc}hQHq%E;JesLEScKDAY(B8?i3RFxH46m2 zNxi%C3%MOO;P}=eN6UvDOY8|UVX>6USNIlkjw((p@9<2SIEXCjPrxX(?^i0oZzR_* zzNY7M%@;oBD~J^4Mtmsek_O?d_oILUYjt{6;`D{TMaZwP7%Qvn%=pxpQxtitzr;_@ z5YCEokzzO~c{k3=3j5MmsF!3}rR1+AyAB-rJJm2@G58Za$g?}&A>HhTz2j;*>*XFa z>Ojxb@&M6KNEc0|Dei_7g#!tIw$Z#xQ%&~d6&JdTUGDEo3PO+3p8jR_zP}aaa*xxJ zKv%Fh5&r<2Qd0n#nWrg5#8xpAU)&9@CTQXeSitGQTSWfQzAaf-BBbJgs?-1myq6RV zIBPqrB`z6z3Rk7NS{zUj-I@l%>|b6nur!Ug4DrRUh!pv7wR{Sxx=dm~2vOtX{?$a9 z<Dt`TJA<DujAz(<MWvmKLxza2xeQA|9?h_-c~avs(RHn;v7$ISFPlpC04bZRCD!Cg zFNYy>o^<-&aj(8+U|o_A=5Ut}AweGmLLE$HkKkLI<rW(m!>{A3ZVe6>lFR}$IiYMF zLr(fG7gu>|wEX2c-^h7@QFj)ixmD7KG&2vq_xOdlm65owRmd^&+=99f=p!Zg5UTsp zLY0SP^5(Sq6svN?r1etTAmn%*`o}5_e?JK^z6(2A<ipD%3$=;~XswJp@!BaV0e5Iw z`5zJrT3rQicS1D%vpt%4X4W6Erg6_e1EKKr)!%|2b&iSlU+=bnF8c(zor1!erXh-n zO))NAvWH+lY_;aap!V@)Fz$uL>M-DeCqZJj+AFe+6Q*R7?=xJU46D1$oNR$ViZ@pG zuclf(%RJ(syh38A*l*{b7NGu)jt&V_ZQWgK`Eeah9a|{)t!|F|)C}=h#{)7MJoi?I z%8eMRJ1MIiKaK8yFr~|`yfqgTUIr>|xBhx2W8mYI?UMc&Mh!awU__LM4aH$!p?gb7 zX6sXn4JU&({@riiet5rc!lW8<+l$Rs-vy2M*^|=RKe40M2s#+(mH5oJpPfy|STufO z*^Z!y)aL%6V=j+&5+hGr&5m^(Drw6)zQ4+Lb2p3B@yOr+l><U!;8>Nhda7x4krbR~ zh}GG!;FA1VOxI_dfBY3&4j()3bwtKAi!$MnfZbPqb&SEVsD%<9GB1(b2d8w>V3lvA z^QFt<__S9Y6!^GM2r$b>V$`i+Ps&Ik39r~N1@M@Jm7^q+osd~J8)R>-qHe%_*yVBI zbW7@xV1I}KjIR2oWHf@Q$C4~O7bhy)jScK@$k=@<fj#>TT<iz&<1(bKqc-wwzzq8b zd!ZuRaVMyQ3(=PJ=M_7a_ws3*BfDFSB|RK9;*Og>t~h=3($rX(8<?}lEv7N(-)^Wf zL_F^k@D|SFPA<}^P0)|ttCLl)(u$#{Jxi}ZJ<3D@Mg@GTb;<Tz(>jU@_1?J(H->S~ zxALueR?642t;|Qm+f&;KvYaq_;WRvncBK(+uRKV$qnqB3*GIBD6y>CM$0RN2X@ALz z^T;-1Vx$@OotEBBm?gkGpkN=9!}>U3+apD^1ktW7RM2#~ELY2EsgE?wG#GZY-8X$H z@o?4vRW+`t&q|S<8qfBlgHDZkh&<s}2p@AVQ&U$gu6-Lvqm03Yy<S!k2uIM^L3`mQ zinH7FovoBc6#q>9mz3{X`cI5O4Ffiz7?*DAmbuSZ*8t&HDl^@q2d8e<#^7lK_?kuJ z+-(Am;OMoG!Cv)SKp$Az&}GW;OPW#q;4%n+*1h<6Vh&t&wr0#gA%Nc1NH)$a>iQrB zrk|3v%B?X{R&dskGzCU7^NH|zyNs77y5N${&1hbn+ODf=lFS}UYYMGsVu%?2?s736 zB_+HxUCs<wtZona`6aRTqc(~T2ao;7z|{$$6Au)8B^&`dwjh?{M8IVk!fG3(P{095 zR}-o(p|j&iDu6X4dsu+N_^Lh>!0~i_;9J~9N~T4e(yfVDF=4bbVZ`~~!FaorvdCJ~ zftQw2anTUvgq*%Hu>hf<)*wz7s?f_YQP5IGAy6{_@x!wr-6|%JB9j34t?fa?!q0mA zc)Ps`c-?&t&7_YFRlF=FfhN;k!Yu)&IG}S}X_?4V*$bB~)KD=jx(dF(QS5hxryoV_ zOqX;M!Rad-Jd5P&A@qJy`Ov@`+%m!o9lURB^ILVXn;-_PS_JS3n|Ue@jW<ESDcTXV zpU&7qxa2`EuH%oeic7?G{_**S)Vk^VXD9S;cM=1F!u+Jth%{$oDK1jkFz99mY&`|* z$SJ>7SA1<njUpxt4&L8oe<XWtp0S2)acDBO!41rRK$*Nbz|9Rw!j%OH%vzcB3=2B9 zozTLE+2I8epq!CHV6APohAsjBx7$5~`7kp37gr|2kW6e$0kDnVY`**WhLMm^f}Sh; zl_1&C3t@%V!IUr<cvVCg6Wp8J+A(fTE}nAT34OoA%jz3ZRMaKA(I^DI+CsuT;5Fk^ zN)=`BG^9LQa3Z?V!2j8SUC~~d1==A9qb%Eevw`ZfHX69{WPA6Z^|VixC2WyR6~&Q# zzS#8Dd;aVM1R#1?AFn(ZnCpD*|4bVBReBCjj6aQk{m0S(q40#WNotKV6;I{49JjoA z&ux4=PM@9wrnsV=t_M|q?YUO;*Tk<CxL-2CrMvPQYTz{$hGN^ds78-r*J6yo59Gey zk>pivptJXq>{%>d1LS2k0lxVhv|OVLK;NL^uW*uSX@IDgP$CNRTI9g4Qk#O(pMpfw z@CT78x;>uAz;xeT2vm`Y2E4&YAr*HdQ3aeSStLipt(aiO5NLJXpzVfs8wdDi$K99E zzac9JUe>=h0)ryAV(ca%{}9U?Q?}3K`rmotwNX_7+gn0sW`5wG+Wgub@`BFH(iT~Y z&buRoO8}I};lSftLT6lZE(n+jRTPIDamQ2#|EAH-cmkO$!pz?mFqdSAf9uvc)(Mnh zj@g=RZu*DI1|JVPieJlNH0{bye*||1*mj=1HzUpe>TjPe*>h8>okg(b2yoo{vPDt{ zzOz!Eg|WM&3?Gq7MzlvTl?Cz$)rS`3#6@d3T?0%HR>J8W;NnEPL}7a6+HtgT;Q@_w zPx%1b`Xr)Xm4QYM`=Rw5X!iK}KCSR|d{eb$Z411f!ax+FY4&`6c+?mO0-jqqXMoo< zsdiUH;+}w7sdBpps9qc#2v%sm>8JGmCE2N5Y8y08_4duu#nx@IIGu;+`;9pW*>1oG zLjv|6RzO0W%5ehce7Qh2ZV4I0c`G)aHR{{j(PKC#cgH!vI<Guu6ycD1a)`n(LbhZR z>rU2)gI(tg{F3<Dv*&gQ=t>+TqE=IhS8>DDP$$Tk?M6*`gDexDhHzd_u7W0t*w&y5 zwwz>77p8vitk`%A(ABb!3@>(HN+j6+`2zqp)H~{!yj8wR#8L7N9z#wm<-hd;DG~}( z3Ix_%`wcaJ1bSe^OgR_*K1tzZ-PaUiaH|93Q6Xb<eJPXSl+ir!N<}&?^|lQLy+38Y zr0npeR9uM%P80V}q&mW0Z64!~p2wzB5wRZ0mQE|<JY-aU3sJ|$f_W`mr!$x5odr}N zBodFee3dc_7&Dd%aA_pD(L*t+_XuZ!zc!MQx-<0+o(*OvHOc!eW9>&4<0EIAp|)KK z`Hs6^!bW9mOnmN{BunZc+<@Dc(eHhn>@>^>{$#A#9cD?i0$<h4w@-Gk4vys!9k1D; zQ)W-eaU60~uN*4Xo=p~s-v$tZ69E3yedI#*mi?K-zs{+&uV%l6bf`(e9E2;cCuqnl zBiY%jUeRS#3+)pL4-Sn0ej*Knh31wPDzr-hHbI9%$0%|gEH1|;p)=PTzY{}#pxVTS z(3rgORIiZ1v|m0k;KnI()X19E&sr5zNj#mPa5X0o3@l)wI%d>vhc=C>l>}g4ZPJ#? zh;dB9hA~SuTyqEt_zW0D?>FOz$M|ibs5e$LSlQXo5JDW?4N{E2e6rEB&-NQ(&}L8e z2mS^>bQ>tHdJ6I~1arqYopj7U4ZkOxXX!MiHj)_aBuDZ>sWVsTq9pc*OvLTXF-D6% z0-xX0cOYXS4u2<ymy-W1y#YuByDf3aks9E1?4exBcM_JSF>kuMvG-;)|C16Mg+|RV z2)B&BV75-W`{89I+tw@;a-B_5Sm=c@2ovAjLPR5~T#Dxz5TH3Gf4Y4NNsThso;w9? zT^QvfBS(o1Nx|Au4kk_=);Cg4KCX+oYPaEn{uYi9b2P|NR73$6gaaZrOY=eSg}7*H zwTxvwIMHaA`mNep1KH`D`0<to4{9S2CO=6Ssx+bpOEExXngmbmMa3A))o#L8OUj>k z16FP7&Kr1^_JuYt`3SRdz|nEVqw;;Uq>GU+wnf9jWG70#lFX94A|7*<C@zEbg@Q~! z@M3)L60TQ_kf)T<2m!cv-Jr6dvi%2Gq#=`WU+=;{y5l5-??410sLBxif_KEvXTZQT zDkUiLb)k?x3H|rdf(Sey)oSwr2hjNJvJh;@uY$wK3%J^8MY%EfT84$!g+9?207jE= zqm&wAI<z|L1}p;Sd>1iN^0|-(2{BqFC0IENL1w~cpZ(Jf8GsBOMfZ|twJWGh_V;Wa zCElKaP__X+V{(Bh=u=^kLVB<|0nnVl`~#~@^W}>9Wsf-GFUZnlcHufk%JV-ZYm~|& zeaNbE<YkW`pn;ZY&D@*~WoyIT;#hH5b_2C3N5Khd^MLoWkx3K8ODNyyODH#JHTq1| z{fq>Jq;lV3EWn%7budf;E@b)UEaXytRQ)kl3@OfE8%hUtSl~3niZ#)#?EuFb`HerZ zKGn^stkn(BX*}3Yr*rC6))=L(`QG3@SGAQ}iq=cNfr(B2O#P{!!fT~B>t^b>_b+|! z><z%cekTEI2&E}z#X#P+x`tHcq{|gMU3;(KocSO)4Fn+Vzvc^Q?L2e?r^Ch^(k|fs zD5=!o{UBZGzGCAQ!-IaG-rwnj{F0#mix$1llA6YWLf@?7s>04#d~Q*0Ytpzillv`R zGGfCue>|=v=E7OWXAXk&Z1&r;xk4t;_8=jAv2J3Kvzx89Ic2Kc`Qm1J`gCQz@`^{X z;1%pBR2Lv4=e%$pOSmGZ2=c|a3RLFj<Z4i`3f(sUQFI~QGs#UJvhKP~31QJ^O!2cr zNcl~x94I$oyD{9Nu6o^Qn-n0Q?vd1>3j3#X(-bu>R^`+d$dDZ&Lmp%KctwLotN}G^ zn*nK{lGL4=B!kl1%Sy*4(LkTtR}+SirZw|=u@~SeA#*g&-4ik21~!=-67s(O*>Xna z3INJ{kjV7v6l!plY>;Df=+H&@eLPpbHPzJB>F>bXVV<l5A?d>4F<g4q%4~QFJ1pqS zPlY@*_*2GrT(6ZH-0qY;u?LJj`=!2}15IA_Ab|m7Hxa544{rbw&5}2~^7=9`!XV|} za0JLjz4@Hv*8R-ab4$k}6wE32X5%uHOInt^kd-t?EJt%@I%gIVY*I(<Fz*dnhs^zZ z7m09r{1?voAy8?<c0yf5O7jt3*xlx4)9p;`5bto`4O(EX!N7@+p?o=B=22I7;+lv= zhO6URfX>+Gd(1NL#sWOgi^1oZtmw##JQ^Tdy9mr5^<wS@6n1b}Fp7Fl*i~n5XS>`U z2Tg09M^B?wnecU5Y*T%5932)~I8J=v991vgToLue<5PH(w2B!<iBV8H+(^Y1PrZGC z*7>#&@FlnXJDfC0^aQ?C_SrP2&A>8i#+E#~TX-Z&L6Vh5|4XP&<@w@c8ysw+stK@^ z#L()M$?(*7vF!M18eYDH^d13JI*?)+S~CI>D-?QO$xEBn*q#$)S}=m_tGBx`C+25! z4er9UZi4BSFU2Ge5M3>6)r@rB3o|Ol*ziWA_jeCM^K6azgK5@c!)T^SxK-{St7^&G zVtu`nw1Jyd_2po5rwgK<U(+=6>mDGuDno?pBH#v<1##|E|2IxJHg>|j$Mr!1^W2#Z zhFE4RmeOpq>>yk+Uukcke}-YY5mnI{-tF$1Clqi@RLxbN?!%J3))I=ipUESJVXt5D zT=ae_H%e3=s4Ye_ux`QG-v>KvpFU3}9u(#RIbKB-)5ahf-f$*cxN03u%@0Vn+bboT zVkRJGe+B^!K3)T=M5^@`%Ergsqz&Ii8Rec@$j<}(%i-|wXn4;2Aj(?H-!d2YTlo`6 zb5)S#_(lq|QNq&l2jAdCf%CJxH`SQ`q<bw1fjiG~f%3A6YTaPXcx{{0Z9*1eqyyAS z%24HFr4qrUXtZ}$e8+o?>k7aL$`#XjGPSFh5()f`_Rr<!QQd~UsH2s_)YI5{03iv~ zd%W`GD(CGoaP1sXbOgitBb1D<QM+vNifRG`z56vn)i4x#J*BBQKS`e~lXPb$;8HL( zQABwej^H!GL&M&3$np9%{u{_Au=@`qo#}~av!{x0y;?M|QS=IXYcBxp_}O3uVHzkH zSL$PGE(&yYH{q^2cz{%2OkiK@LJ|d03sR|;&55s=^R>airtnwo2VKkb#p`LT4%|@Y zH-TkFdQ@U$*-cuIP3_r}jL{I~9W;B4K-e^<Kgs(_1RJh^+yUxCDr^h2^LL+40-jr9 zLH9w&Z!(S_u>Z!Ae@MXp8~{p2cFg<lyo*qr;a><SARsiH^!#=Zw6qoiuyn;10_27h zM<l5KUid;)doTQ3*kh2S&zAkqi~JS>M8K4euH(UfdwU|b)i`}FkawI#dzWl&(*}hE zE>`-WfPC_G3rP%hm8b)T=bjhdqU$tE%lChkm$`0qz@<k87p(7ZZIb@kmO>G8G>Y+6 z%A6u8YNG7tl6bX>bubZD>>|Sgh2;fFtaBBrE<KrdgYsGN3yuVjeucNXr56PtCiTh3 zZ<F9WuMIg-FY<K4%KouhU|{@8k%YSF$>)t2G|}dSgkNqgRSKm}<}hW8CR=e$KaDmg z%4|GMJZ&^lFr$p_u!beJ2|6~axl%D3dcrE0bF)#QoGl$fYJf_4Y0e7MR&pX2D1_m6 z6t`>A#J^-REt~K0n(xZ(<1=aioC0z&w^aKR$aY5#wa>T-u&I6Zkq(-)10Y5ESvWgq zH1HTrCp)^cc9%A-Sww(<nU50@(F0NS<>7npc;WN<EYVP4%CY9{=`*m!Jr6^W{#t-> zT{iC+aiS!8BYTLlyH)od(L*u%A1=!>7~&gUw4$H>`8PuL$}{C?B9<Aj{+en_&QaFf z7Im$@tdm!Q1d}Tyr8@zedDHX;GWD0`{AvsLt=!d^5jJ&jWxTODSH&&HQ3*v%#$=#L zhK!FVy<?rXndQBoHPNwcyJVpF)^cLB48Z{BOT0MVD~71^NjF!ZfrXL9U}#I)m)HCc z%$me8AFDU3IrW=Z;WsS+U$I0{G$dxE{JD*My8xF;F?--XVGOcO_;)5KxLlhyy&vzg ze4!@EUSo_p0&X<CmrIk8Kk7jRix)9UX14~Hd}6;1u0c^9Tjv^KELS)=w<YT{UJ3zv zXN*LVG}ubzwEpaJl`gJJZdA^pFAGkrUQi|9FFvHsWS0}x&`>zQ37j1$ISXYK^=o+| z(up9rs}%I<)9<PT3E+ESGN~8@x-{Ei;(~E*Lfy<tW5!vJQKJ_SvZ(@JRgDh1tsz!p zOMoeCj?4@!fAc8O7+EE<qQn$|RfrhK$(f?ZAF_z9drglHIhlq)U$$yu+t|rX>=&2y zHS(U{Rl$Zdg!qa8fAbzB)*cA`Uboa~3qyJL1L>EH2-9wGpcifL<HtpCVjI@?l8%^4 zEbJpi?rZLNw?Qw=a+bl$_c^;4_AQT#hjtnM7m-tN8*)|-sBQIX%gn8Fl1OPL4Gn@c z+cd{i`kgh1zq}RkCUf++^YcpX_ODDRndABrMF048yV)ZEE_qy|<*(-Q@q+MADbEpl zj|}%R`E?MzfIVN@#MlHVaTR7mQKK%B1+*n6%I?v5_f6t!9!=Q#!Ha@+2^*JHmYH66 zsqcAW&AO!)3s9?yj6xs>M$}CqDT`6EsX+ReEF!`RxX3;&lFM?5Okf$k6LV0u00t-= zANn!a+dLsavETxB!yy)kTd8yIQecG2YONON=ofKCfB@~;$|@e=9#MhEr6m?bW}j4Z zI;hmAaq+T)C^2r2S17^S7e1;`61KH@7UyC<S){K5okOU&UG^_8=kXvlmv9y<Yl2LG zmZg>L6olg<wg73T!EY30X&ii<f>|2|SAm@Z-OWG%^4Uf#MArkNLWT^DsFZ%gn_gno zi@~(+d^NbbGTSQERmzgm^{iQ?TH!s#5RRHxvO8bH5YX2`k}sv&J9;rslFIhk;IP4w zu44GCn*O=xeCYYZAin&JWK)lZl({sbpSt>0vk+^8;znJ6Pxzh3WrJBqe_@~mu_}Y* zTV)F%X|~YSU!zz{qXh-0!a{L)C?11BFduE$&E4*Xg{Ey?h6P!CUMJKzsBp+wo%iHO znM8biw_jh6ztEUd@v%W*NmYlEkhQ7(L+N0wNZc49e=$AkPzax>Nna&n@X0WfVNJa8 zBaMdpx0i*<$Zw9T^RKuebIOw07uCy1&4Nw9;~{Kh$ln5sE7A1f;9M#F<?s$Jlzjal z-`%8CT5!0JhLc-l5|YHqMscM@Z8_q^KA>7<W8y3^@|}TBzvryrhA8JYiZ$)7AOpE$ z_$jgO@sN@shoh`4h4d|YZuWQWbe)>AStX^ysmel4de=Up2x6As7U4J;u)+2rQqTJU zqc*uQEoMVmIH%gwlNOnH<0id6`PID5@3MZcUmtJ#hVh>kzkYf7xJ(Id>e1y9I1oU> zkk`LKW5fj$1lD3w@T(B=_o2i!ElU@^ustj~b6L8AX-V(?{xT9>wgtzBQ474?$-0MJ z_s5P`Wa2n`3dZNOwaIv3bbe`QxJ+;aB%<yngQJ6_EIj&6+fk4<X*luLg}uC}1kh`k zN5WIfC#D~>NEhEONujw$*EulVAUCkLTf@St$gORjp%vH{MKlWxnIo}LlKH$5Y^I4K zuoNIF3yFa1`_Ia$5@gqZr8)2@iQ?1s<n26!mkgP7zmA^3e!seU{Wy8JJ-k8zQcd;d zsiC(-o@ip6+khF+n)wTy^JEOICxaGNLDLQTYMYIvt!6D}olVOz$Dm8fQni}ftBHt+ z%_1X=vNfpl4gQrq+xy^L%Ele0mhgM|BU6vmxx1vJt*0$+T@p7^eiH@aM<(i~UuIzC zHj_KDZLVjhUtMn7f@+p!`va7Ky;@hKRUGr#4GqdVNdf|Vj~sjpO!yyNQlAa)dn4NR zw%Tc+(S+^b{<(xQy^R!fFU<#d)PK7p$6t^OTY~hUIHEy4V8NyNwAs20n{MMPcUzw> z->trfn3@xBTm7U}CLTx|W(h_<-tP5Df^BeoYz7`!BEaJNCf8(*S|Gy!`Dh&sj1c6d z74)NGl2~3YAaO87eMYz^S-*IM>T?dzDijpxAPA5i9@1t9mSObZWTp%}<0^c&(?WYK zH{|<>qUiM8oc9e^_}Mlh9Kt}ku$1|pBOESw6<$hPFn)%^3WuZK?H{8ZR<=o)?fC1! zB$o#00TjkTAe1>K9-a$8-!oH`Rg<T(F`hvA2r+4W+>2@iRd#ieobXP&H)=iYi5$a& zRD<er``B;1rL&OrGSpGMt1@utG3}%57?^Z2s@OM-u85};d{^bA2-MZmb)-w5iD`ec z3o*O?z<cSL#MHRHxGl#~>vm1_#kCGwp7zbA2sFXHVZCl~eO6LH2A7{QS53`L-T>3@ z`Lp!mk9_G}&z=jVpHe}&5Fb(&-fATeaH8d2@uihtL4Pmm1V7FWNciz)@RwZJxYXl& zB*JlMvIw^7&QGaJbj-J=oN>nL1g}GI1XN=65w4;7cM1^oB07-w=y8tQ-~^-t4tCq{ zx@S%oMqqgu*fhBSJd+AuY-trHtOyR}w7$1Dj;Ez~uMfY|EM!$1Zvr96T+m-qjDlAl zc1Uz{+?f?(rL%Tqf2$hGDM)kuepm1vI~5GhqY4B1*in0*SrJHV%o`)rc`;OX{a~H< zkp5@QknAs(6c}r7*G+)BmCIokA1<Pk(*$5OtKhJn;)K}%rVt)LEIis31p+6It$gJ8 zm$XK}U}%_1LNfJ6!-B(EgW({b60A<(w8ytNQn0MZbhz8{sW@R&|3#j|)8bc2TAKaX zJ^-J*AK#xH)N-7b30{T8k!z;KNqz4uzey8l=wxJ6+r?1V2g-=dBt~x)AiPbKMvRLj zDVYMCzD9)rsH-A(9c?+a^%VE9BJ8(2BT^>~&Y1NfSf%^$o62PjAB*K4zi1A4@h1Xh zr%A-A1=o6713{VelV{}@snwPu53Z(vERoW@d}FR15a;p*b!}{feA_Rs^~%47=_^h5 z57Wa?7R(+6|L;a$-eYW$l?Vt(0oW~F_!#)Vjyd@@5FPMFYq8f((k5$i@O0!n6s=N1 z6?LUEq9HBwtipqiK^9Izg0u^gZ&p3=^YzZoh?HVZQ{BO%sf`ktnVWf?>o5Pp6jf-@ zB}dDzdDK2OUZ`QstjVd~roGa&eWX(1mWtkBmt)(sn5v;&m8CNEL_*tmrHaAIud*Qj z=UXdfiV&c#u_&*@roC>pME6wgk(|E3Hq%n)4Y@^=vus{a%tPz2>$k2Y^rGFMb_OSi z_q6b&gZa>%^%wlJro0NIH1=BF&85bzVA)#zf=A=Rjvi2ftA9!}Mc;WWklpt?T0#>% zPO$K3X~H>qCfa{Nw}gE<7kK2nK18|<`*HGI0uunwHsj*xd~2+H?B#{n03kN%ma~QS zixGtGIhT46qi5J{YJ3SsXw(R*WxnDbfeHSiY69J;IV7_05J}vo&YB}N4tUb0V_U&U zLY>2Qn9n_n@GIlE>H4XDsl75E^=rJry3@LTlW%Gw8y9Qcm(KP<^Un_Fi+cMteYrEZ zC_12_nC?NRm*_q~gS#gb89MX$XlTaL@}vY4bF5;4(~|Tlj>62pM@)j5aJp8PU8Se! zO=1OZD#k8<>IpA_<fhqHETxm1A%KT6;Knrzl=Ta!f-_*jw}^qWH;Dfl3M@XEcQ>{^ zYUS*bV@Ms9;xZ|~a-1aluh+9;4%!*bsSV(jIQK|fF1kvtC%InBjPu*O{r&8Pm0r&H zqe`P!r$k-d{dsgk8^`taZU2#vn_IxkE$j34-52cl2ALbX>@vDt)r&rn#*yBMTPIb8 z`Z`%}k-Yjb#Af{CV+f(ZEHCZxd)Jw3Gr!N5&;~`7lg5R8LkK;IAH&%mHvh%BtQsI9 z-MVYhy$Un^<Yv2D&H&%Alc#HS$2xV1bpd>}hq|P<sEfdv9qDwm)&uUKr@%5eL@JwX zz@P?_L|WZi<09lmt}qb;l;WmnsBqKFq|HlxXEqJD{LbUtUi(y9u}^Sw_4Na9FX%ME zpUghN%^IqypvNmeLlS?O|J+k=YY_k^L(Pf`bf72^as>A*(8B7{aOJKuYo}~=``S9P zZ`3^tblVgmz*HH(=~O7t8y)YD+Q5GRKH4l?RQSq?Bm?S+y>h{43o)=)dqTlj5xfF% zQ1Q4-^1E?3z+b`Y#{gJDvbC;8(*3CeH^%8YG8yBXeRQawI5?}+`8_+AeGw2atZKuj zK{UZhn@|HUea9^q@FY!`S)`cM!&u*0<M7n{tRe9QOZjPb^TB$j30?Y7Oe)8*-=-(d zW#Bp$5qxFS3PIMzmY^-R62>WV`imzIRt552c2tR(<8xRfVohbnA({KMs%XBFPw&N> zM8u2i%F|X6?V3pomO5R3`v-uG4nB>C$-Gjlt*I?cf;+si2!DORXRk!U{Qztig65W= zJ3){E<gT(|Bx1v|3Up8LtQ)@YxuF8uAvz%w=obi9{K6G~mw{Vg+z&BSJY3*6-c*;g zIQtEC+J&$6X}H#d$9|q+PI!v5dP79nz5xYue!X(Ww($TVre8fLK?IoEUDsPM6dm4X zqn)?OP7&`G7kM-B2b#cwlROt?1CCKFjGrWBr}wCy^PD$oKjT3T0tyhW;g3!ecpFe= zB6GkIYs-0%SJvPOxSn~=^p35ENomCj>*YN1OH4oO#Ndu>P$gitX#&wG6z(+(s%sJ| zpO9x?SnM9}ZEjqq764$c*z!+ctjTRLvQyF4F4~|)>Y4}vQ3yG3^eW_ARB8!{!-WyW zHHAqBRrPg(R4$HDm@!@tm2UJDd4sSTAtCXD5HM`ED;sB21&b!ofNdcPj(yt!8O&k* z7AG#f%Xo9Pdqr^%3=9K+PQ)TT9sG(OS`ToQ*s$Sa7-yzalmY;21*O7*9R@MG3?kQM z+Ajo|Cy4j92LGW8Rs#h(gAXLL7S2SY3J9z7q5GXmFOq4rBPhm|=Q5O)X}Ls(b*~!o z$2up#LC6S~1++PLwF1pZSKEQj#7XrKM=#n6Q*9U*Y|K0TZ@D9wmY|(2njMH<I~z_K z6O$D#<85Y4dLp1*l=ub?`;{Mh5dw-f0OI%pXBoz}3}SHr7dF<KBLh&v>;d<S^N>#R z=7LU_br$#s$N6Q#a7KZ#GAs7&Aa9YVA6=|>>|5_o!BujAxZnNC!b5F^7tYN1lY8yP zI}MlzeAf%<p9W4j8Skc1a9F?N??8a1)}i)oXUpOn&%bdA@suXc^x%ic=x#29GZd!s za5w<r%{E5p5S6QBO8Jl<sbw7y0w55_ly$PYo53PLOhhlv&IZc~2rgzV{_dm08(h}w z4Fj^DSHrd6V4RoVuI;#xpT8PAg}1wwuLDDv7B2UxUTvpYIfEa@8<$tLbcx~*2!(Oi z?8*$P0t1+6ey}7w7b={T>tUS)^`ldzpIaadSC1AD?~zx?u0DHzgDqnH!&g9Bdq9Jx zIl+g-SXi>*T|;LjqtLkC7>4vUQo)C)uIFh6{?_`7_wAZmOHh0ili;Hm70v&wnlT9m zEZWWE2@!;01hTq26>fQ4Q~#MlxHjMew;e%S5e9SuKaD+?ahNrf$P^#_xfJvTJA27& z#R+hH9+Oe4e96}a@lDOIr8Sxa+hmB8BF}dh8lOZI-E5pcyK3DA!L1o4sXYghMTC2! zE~;~dx&`4&p`WEuEBSHr^8S8)oys=+=SBAL|5JT~d6I<!ErIKWjBSr<(VcgUr29y7 zivY%6Bp}z`%A>u{?i$OzD9n%%nQ2ePxN8TBz^Ic<z7|M)w4CA#CZjc<>YbC<LI%L- zN&!`z@^+v=wah0Em4PpKeS-;9t4gQmrSQtfp*HoY)#mo%&=7uc3_rwNkf3qikhUyD zh+8&uLl*F_kg<wJO#743jf<rXpqYp10RSAg<^A;AHOkeTl!8YhwS(g{?x0R#$HxHd z?}4d=0I-LLJiatdzCLk1(dA=cy#r}x3nKQ6RP+REeGHfR@W1aHcW)ajj)rlIXK!yE zE)Z_c-|zQNV|TcJIQ_WVx<TXZu%rZLr#PiP&9VqaQy}`Wh(h*zLFpN@u5>^V(gEfi ztcyp8Pjl)azw-;7>msT}KPBi3oP}A;q6sM4q~UYIZjE3d9z;Gu=4n}CFr#hRkrGgq z$V89vdlyJo?BPv1Tu*V|2#2HTR=!c0YPuw1FkZa=W}~rvCT2_%gmpr89yXvISw`~2 zi)ZYMVjY43ofgSz0F~eijar_E*8@(2Jv4Sy)FO91ox=rMj^ci9AC9IGwPRJq=Bt(u zy*2{P`CGiBDU?CzuZ7eJM)N_;?ef7YtPtx4QqPL16B$qVHn_j1>YP4dFEvl0=`Zk$ zkK%HY_8Rj;Nq44ccsv8!K=CJZSHDhu_i-~b|Ft8b0=%yaxCpYKK~iB-Y=D`aeFs~! z26CoVxXHUpiUDl>L)wO@#K8y2@v2>(fWzjfGgiB?*q4o9@Zk@8U6obJPT*c$`#Qx% zY7iB1zbj+>_HXu94_f}WhrAjjLsUMQ&b*%!cJ`RPF?@lLCfMY_GiCF3fkmO>Y5I>9 z!0^SGd&=<2x3j;@j%CG^3;;cQ32mSZmRu-BAu!J96f=von`C_+0&c>MblAZx;_vs+ zr!bExmFytmk+2DH8dXk?Rx+^;V<l6?6P=LcYRp{S=tN^|!U?bh0~1W>vk7;{QYRiz zp*tqbK%hjU>|aml3<x(>O1dP7ZEgu9;Kb9gqc=+l!5zjkB;2hqJiz7aTN-ftzvcb| zlqmtRGqH(*GgJ3Vv*=f7e=)^bkl^**2pXVBqW*QX{XQ3aYyzh**jBop6&blVNW_0? zLV*_p!Dk>DF4!At`O}VDCD=|%+4A+mKcnjI#TBX>A(szveoyTg3mP7d_UycluC>CZ z&ZSplI~YG_?XT7b%Rd2lv0))^xIH5f5n*_tPNWu#Y0zrOHMk&V)$sEo6h$7GWU<u= zZI`16I?K?i>Kzl)aWN9|8B_l*ueMu2hQT%A_{h%mpicm5G4jyc3_K62(eFz;SGecU zdX*dtU&_7qWpCYyj6lf`<OAa*0vY1!02fXxRM~Ad#!9ka5n!t#up;sqRjRAGhHrAG z@jwhkt&G?aph#3^q8F)@Kk#IxdITxmI~gee!UiF9J?Gsq-AReU{jb_!-=92i(s%A@ z1N0WWfZT8Ap8Q~FaJ};ddd;Ioe24eIp0ZRR+{yN5os3)~+n5TOxJp9lMrCRyctBZW z5q0nB=*eW90q)+#-QVY-OEhEw);9hn2MsHtQ8f>l@T-vMRFuBSCD>l^5CK+4Jo;w| zL?nN+Y2@k33Fu3tKSfsXZMZ&LgjV!L<`VaXiPy=0W%8A9LCu#)fJi4u&gHjrU|<fH zjjn+9gO|_<a1NaZm6;`HfLSkvnE;-;{c~N(UGQ=V0eIT^+Z`C)KCf>W-?l1<#5Rio zCZ1N8`_l@z><}$w8SxL5tyS1LDBtj|Jk8RjQ<hBQ{iJ4x@eKpa2%iOV#@MuGQhkFW ze>+oYHELT?VVmqUxS>0c=k-`lM&V8DLhzC`8qD1x;glVFslcl99~9YpNgH2}^BSqo z7SRc|0E`dB!qpq^6Lz{;5RbhQ|BtJ8impV9wnbyxwr#Vbif!9=Qpt)_LB&?Z#)@s* zwr%^?+4r^A+CBgCd-O3!ml4DK1<P>_GQ#nb8%jzEFWI40qz7N!q#!TId|wDj_ceZf zuAu^xQn*PDjH)hDn6bJo$M|f4v)!LUXpIV1gl>lOBiF)^2Yl0R!k~8%VhLB-ZOv;Y zrfs5cw>KKnTUDJ+7Zoz3ke8utbm{AHIshNhaanXy*Zl7>7uR|<?R`^61F#%a>G21J z{aGTowa6F&Lw$oB{RZVDLUjPtkj1Wtvxo=qxEFBee;Y)F<VbA+f_~2~bv0tmjY~Er z93zDT+8%$E_(3Gx(G+B@G*|g&?9D2%0G?w&2-;EoH#hPa(%uJZ7s3(6te7)h31Bcq z_~ts42{96pbJ8+bCcKml#e=h@!;3FLY3j38jH-D~1Yu2uJ}cmPg5e|@=_4BlsL?;S zlvRvx0rgP83#B#A*%%Wh2TJb%S&rIH3;RQD&kx=lC!c$_UQJH;lJ8jY=4ZFx(ly$f zhsvuS94;qxRL=on;XEE769L2y3{WALIaFvp<e5-3H2*tZl8sIQi^>al4(gZ9I$0)h zIc++_pg*m(4nYNPan`o<PAIlKbfb`V%#YL5_XTXBO=G1JpdpSGKnu;2FMzX`A;=g^ z$qvC)a_1^q{rxF>ECF?#+1AqUW%$6DQ;G)e_iQPyTlv;bsLbxF(an2P0cgFqQ&m54 z?wu?0-PYEGWfGp?F?G0M!w|!wNa15@;-bB!JbEhCSi(CF9-`V+9O(PQq6w|p=uK>= zG^K6w<-Nvr()a`_!L3wA;7*pC`0VWq@#<eY;oc}}L;3c}u-&7R6+jB3@R4S0+TIf5 zX+;U`xSn>4_W>A~oO&bf17!97*-s(-vtTkINSpaU|MT<`NN-QHS&fZ~FqhY+<5H-a z;^rj5Pjdxd?KF{%V`zQ9Pw_l$Mm}&Bf+@JR>D^Rt@hUL;&#Mude~anUU^b>&-oA@Y zW>y(vnf9zoFKwKJp=EdZpl29^Q5spoSrtFZStx{auvI4<Z5;{3094|;#F4>$C-J5Q ziOEDW)V@iRSqxndh_lif_wD_~Ku>5@p?$E|;0XxC>Nm)xqt(TvK&Jpevg0{wx20Ba zN>=<5M!ac~X|{>C;N?Q)od8`Ls&A;vsH#jLC{<tYxbu8TJ+Nd>ei(OhJ2v>z_tJ5R z|E{@pv(-VqX)xD`1(Xm^cMot<k>H3&068-V>e~Cv?3w<Frm~6B6xqus>x6Gul-k0N z1EG!-1cdE2Pf;$Q3fJ?#J#hklT<v1GGaqKfe^lWfwQG&yMwlZab2BZc_17;J=NfTZ z`VF2P>p-^)nhk2$m85{nuaE5Y3`#5{tqx&myriqjA#<Go0eh%nozRlnMLW%fJyu$s zvsO&36NN5js%DcdvlD0M@{LTjc8PxwR(y86GRfFgtyrxnF;#E3F~28(4Cpj~%X0AA zsgpOpN_;-!o~%)kQGt<kw<$mP6Td(y1Lm#>D?@SSJ;yz4RPE83yk2LN^^?0yGAt}x zboa_Hwj(HT0BF`u#OUw)FEoZfc%;3?hM${4Z~RV8MW7cmtZaxm4FzerJm!)Op$fkz zIT%>rqqOTFr74HvAjcL<Iu6bAv@gLrXr<g=<RbR+$XppfP}jjtEbFEzZi)VNqqaw_ zyQ*tp$PRJJL2ZPAHsY3FFGP(ZiKro?(llcZ6=j$g0UC>7f}iNZ$Wkw^0|oh1rgiBV z7dne$(9pAXQK6I&PR1ZUsa#~)9cTjE-_F*$;*3|iLso^6>A@$)YDz)fFwUROUJu?f zsMpkVmxqs`E33qqa6yn~`NA47Z<zTa3z8#1qksJEB&HKy3I3r%Ds*H=DKWPChr5mK zg`H3g34oaowd7~J?FS0JeRD~V7q?I31}s}MXAqLjFz|iC@qtH<KpM}kmKxISkw^Gu zEv2F7Sy&Y;h<LjRKO_J6z>#iL!<n~k#S&Lzuk;mgGuzZGviZm?P+>s^iD_9;d6|9v zQ8mZ0kxNwWLv_mKEn{E~kDqsi&~r^QQ{5bk2yk)3+`N=swzf88Vt#gW!uaI&YjHcy z@Gnd5&B@AVycmUAbvz~*uN>Y;<ejs+MS$2%31)IH?am%cKd0-D1mKfnZcc8To~md3 zJ*5m(PVJjOwVqlrgXLq+tW|Dug-4_ise<AgLPtdjY01F8)x6atpL06u<$me07Q7LO z0f+*=H8l3sHIkCMFRkdT4O9;ahCQVPBf?mRh$n{roX4^waM!OO8Y`~_hGKw5-zasQ zCm&7-68^Orhjn~yr0f+rTfe#YB$+@l{CsQ^R{7j+dT|W{ypK8u4Er}-4WDt+`;DWy z#7LDZ?%9iKNA2G%aSZguV5a~1d~Ax913*G#o_;10mvBQ`IqKTsW&~>O_~4-CS&Hz6 zEEK2O-iKB?<q>Gy`oRkm7&o2U-_=aNU%E~z&h|<Pf!WXDhr1&$luSMm>Jr}Wr=Jo5 zKe5_<Mm6(6(3%dz^y_|%8Bc=jmH{fv7MK|i-=<PxD8i=*GTd9;N!xQD10OGY0heg` zi08d_63N$%wX~&OUFOPZT>j}D?xu1$`Sr?Hv;s41;(cO_@l-Ec?MS3r+U;O}KXI?o z5DiqlmWPyQ`dI7ri?m>}2akK2x@dPYuFA}ZF;^sw8-0F5t(R6f2{s4>AHq1?42Ws^ zg3G_}OKvzD9?*cSqw=gtliv=80a9g5%%$8UQPk6e-yFgbX>pOcW&}U%phG_h#95X& z7x9R*=)zHkzFtwY!|_`fZ<pKTsW9@83Dl&~81jF9l;Y;x7RpB&j5T|O?NbkX<(cv) zb_(^Qe}=M8VR7e_yW-EZ^|ZQVCx|BUZk$H6rp`Jic@{~1OcC(cx4zQy0KW8A+K;?J zELEW>qf~%V(ahUH;02~KJaSrWmymPO^pmW@Fa-7}ne39CrJxf%xnQu7kZZF&18Oxr z5>Qw8u(?AD(g>2mz#Y*69+Bi-KVB`Ss5bjZ+CN}L6$owvq6ziOmZR&QF;y{6=&S2! z|9rSLGJ0-PZ2344>roq!01RY0+9;{JfFZM=`|(ksXfI1I(_63y?_MvC!=aM&m_!~J zZ^CPrLA_8QCRWT%UeG)f2WYiA+!zx!ravnI22>Icmr3C%9|w(fU|%wbJOqs*yaRbr z`O#q_%8|iq@)p+(yJ)b1kW0eLl*X&Hi#`*eM&7|;c!#fxwCj+(fTLSYqf>BWu1A<) zYOt|=%GLL$pSY)Q_+dEF#CrD`A(cgK5FR_a+feYg_&Ky2I?vXeHM%iq+pkb(u^SP7 zB+^8~U}x^V<_$ocfN;;+&64#D1*^KDrmaH{dRn&r12-TW3Gv@OmWr1CJdcqScxRsV zcp_p0saG1-FRkenKx(@&k;o;TA25)9q0d$jDM!#FMhE$VkS1@w(U*B*7gAS^)M5&L z;xq(#?LhZFH^D`XTCt4XLW`=T{HmP)is(vp96?1bUZkq@N1Bu42-l|BtHAEsXK=Qe zfQTfIDLl27qHXk4D9{KFR`R_o_?>~m0~SVLID=Ig)~-DUfbVCA_WHcSM^c9k0vam8 zyFdNC2`O0QBEB-vCWaajoL#Tj%V0>_4=?=75(Pu_a*J@5=xpcG>4&%A2=BZ;0ctTQ zx1sQNapOW$FH}uJqk&lew|*4j5$lmRfkPeS_^N5Gew_Itk;`9i&btZPdnFL}HE*I3 zLNR8R+h{g+z|i`xMW!;)?ej<TYS_!{wQ70c?*SgrWfEg3(sxFmXi#e7TN=I;4KF&% zD7_?ge8`+@?PS%oF^xS?mpFL|%F9(Zrd}|#A5y(M@p~0NTO6cD6apC#RI6{lQX{Xj zilq6q;Q50U5gfxGhZ>ALhPfairYtxw!oQIa?}huV0K~~Vcov=0XGO5e@I(L9r=C0B zW%)RH@i1K3F%eD}JufNO?R&a1xsFRP@HmM-KQ_oYe-r4@VTuE<HjrDPjF9^(tW4>g zL`DTsl#X`B7c5pt!|eUx71gn3ZP_^+na(rFJc2@=u%dMY<&EBgH{M2?b=Crf`34}c z{|IKg0Inw*nG3RceRQq5vtSri6o+^d7X-763=XK(l7~mSTwFwmDpGVnHQ)^E6u!b> z>>B-!8~uvsDx$o&zOv3U-I^fdTjZ|U0@&P+W{w&8Fz{k^p2-;;m!Cx^LY^tFtxQtL zBD~@rQ+b>_7Z38Q%Sr@WsY8_Q82Mb<aWZz30kJnDmqR<%%MxyOZWJnK!E%=coCD%* zDq&-WiU7g4!xuyzAP_t9j<`%hP;UPyv24pjV*&ihzcd+QDm?aS)U<9Gyhm#?9rJ;q zMU<stlCT~8mnY<9wUnA62SPB+ll{an%88m!Ak0d>@0ux5AT(Z^GtrNgK}RHcmIRzT zz_=*XdBpuL&c;drJmZoRjj+Y<j%V%nBFGBNcsoR6S?3K-Q>p<K*#j|(5;G~>-hL=n zB!og>^+4!l#?~3((Z_3&Jd|&FT`-2P*x#OD(bF8Sb?|E>E>+gx`cf0u?XVBzwz;Sc zIH=j(YS@b>R_<`_hRTD)~>r%VSm(Ks9OErx#*E8q*R*=XNTj%h>n4#t2JW3eFFJ z6{|1SRgH2vIs&UFHeFeKheqCGv`Xk>AI~`zTp-?*ale(rbyJmINx1Ln!h6ImT2P=g z*dC<}!L)?z(qf=7!-<!dwS#EHi`NT#HHTb$w7Z*0Sx7{cV_8Sk;<GOJXjZTkz{?uc zeB>WrxsT16OK8=8Ge?n@E@JBYB(ZcGh^@ue!WzI{l67$pJ<;YlLyhKARZ*E`=_1d% z`l8h_ZP?!H>169mtsZHq%%v~p6lT8X^-bOa?rAMKeoWtSNOz>wX>iMwi|(YEVqaZO zI}SCOEmMufdozU>5agkSX<$eOc#Nnb)hUg*njaHzT~4_XqYUJ6HH^?x9eFKI*XP^X z`Z-F+gYl|L3Mhi>%^Pf+bC>Ue-86ABbc0mVX#1CX?_br6Jr?gfy2`od7z{qhTE)># zOMQ>ffz<&WDUquty3a1;G%{Jm>h=x>&rNrc&woS74MM6M>A5jRf#`<>_&N$BG-dHR zj|T2ULrLMJM>L{IQnS1t|CRGXV3_WSvC+<(`jEq%iohz)@40Bue{BLsB8Lk)46zj$ znv!~C`y5~X=Can8$X2j)Mf`9`{0bSG+Nign+;1venA#a<B5LMHCt`#URR_{*a@uQa z(em993$<ChF{ya5k*4$m1pAmAS<;PX3Ob{iehlXlnfD{4wP`MknZB~+ITsl1_nSdH zMNb4C(d%^+z#B*KX}AQ!h{tTt*f**0`(DXJBZ^I(>M8F~z~1>K&~#j+v*p24ddBW9 z!uya|Tf2y{iN45r&O`)j_>dWdo<vc$g;<W4=(zz%hDmPjz`K?JBB0WivV1W0t?V4s zrlBqGeWvbXwVl#Y&Jn8EBjpS&6O%1<sej!l9RqT1_BItJ1P#_<aVL?QFe{TzE|TLb z9;hTJoV-+7)J_`}R<T$POKRH?_P^4VUEFrnY9E7@%D@-OHHTMwY=?l(l#sPFR;OXt z!Sj4U_<v~p4g>iCxWp{`(}zvIw!>@nXy0%8)nLcILM<PCTIy62+$)Bm#ClPECAc1+ zyUmFqqw)$>fo2V(Qf}+m7iRO6#W0qqU7!Eb$pjtS_YM3z!nXhUL^}A1cb^Vz4QSTX zA8Bn>90o6>QtVXFd{_<(0U`pb7H>3)5>8uWO`hk!PWpg=&5IM8wB;kTd;6Ln<W8b} zAJyWOnZbSuEaQ$0J3)ungbzmPPN4WGvGzxJ1Yzj}RBUof;hCH$f9vw#Q(;D-%Z6}I z1XYED>{isM+5?#VTe)Asy)2yU{s@m@8&yP18@}L+zsQ=!Y=2z7EJqzYT;4uADgb`^ z3kY_7yk>O)QUbb}sOl)&OsBeW5`9NXzH&oZ4;-M9)&6#O{Qmn~%^MA0>|3`}MkGlU z?E)7Nz;aiqKtW$P8EO0%8r^nMAA1R|8J|O^(0#uIW=5>dEDVN8k$2*ex)C}RbpGD2 z=wvnxtPUelN>Wa$(mmTI(-<sa>KzTcSnyxGR!ojCfUp%w<K*oU;WkuxGS69Q%sqX3 zb=}kt+R6xce6$oH?wVoU70vST);p5)^lGTpyA6f=%TS_*db=Ub&3_Y{52j932`H~d zp*<30nyF@z&y9Zlo_Z3+@}VYwzlnOKee(zQ>h@|G)r&fjf_%fWb(_Zv<!ErOapTI= zz-LeZaHL}LT<F*9=tTAAf3BF|py!T!Fs1xV(y}yfd%Q_;n6sB1vPJC~pa0Avhnw&^ zuZleRo{wux-O(oKHCF|qmza_TZ+LM<KE6Uc=^hzt2E1wNlLDr9Hcm_Za>_Q0+PGN| zbbfB}X8-zMZ9rsF@{IJL^-OuDp#KSWEgULa&>;Uwec==T=92^Vxe>4D(uXju0ZE z-tkDlkvzF8MP~WkxG%(%aU$i{budTc4hmO+-(BGe*&Ll)U=1_y((%Z|2~+nUQL6l> zF+Y%kH5w7d@I<Lv_KlKZ%~OuOi#>wfMXhvY<&X83Y3C<(&ySOZb5fvB5zKxq@wKDx z@)(g9x9cAEtNa2Gy-1YRQ?QlhRo*c1W+gXj6cGehT{_HQ=w~JwX3afwc&en^#7!k; zF78za?I~m&$#=RPT86I0BYangPIC_8DDW9B+>G*`ZzT`~&r$b=K}o^hF_`k~o>&Yu zUeIg|)#sN-Zz!uX)-klB5m&KrWd*SO!4ZT-YSQ{G*=qur873Ye7BV4Jkow_GdY=1K z7|SwGW4Jy$8iQ9WSeGgMYDKvdo5ei1oC6`;5gieGa&N19c4(kYZ3oYu7ryGj;XW3F z?Z5FA`YaC2zbZP-y{b*p>E1;K3q(W`ci`+5wCoHQUrzvsU8S!LXGd@x?cMGPFIN6o zQE8cFY0n2Fu~qc0X5=EZ7u@dmSfJ{Ok9e)3g%`dMh5a0_a!-Iv5~V_E#7gKq6~p;> zd&@xQCV<wa^OZkZlfteEY^-Qg=5+JpWE-F#sp6ThAm1^g=A-tcMDV+$%x`>b*;gur zLTK3(OIH42;g>IO#Jjz&%)Mu{nP>%CO?qmQ1400xUXgd1i!aTCq`%UW>yVM#S)^wY z-|?@921}52Cb>1cAl0rIb#5zxMuKzfrTq~8iLP2Yu_c5`j(~3&E$ciFHvn(63!Tdf zYpLzZ+QU_A>MDGjJ9e;U2Q!B){lgviDTcEdBy2stzV3=Q^Cp-!#tm6&Yot>hQ8f*U z4KWh{`KXncBYMNGduvl@X=iD2X35G55#87Xy%dV}j5^iR8<msi{kVk-@st%99IxY} zW2vcii!4}^RJ~r{PwWD7BpU_|x;w)xfy^hYkUwh|@x3_3RZwh_aE#8>EN`G*>#qJv zw$@!AsM2P_!7BSui8jH0Y958et~r3VVgm_CJroZ*VO~H%$YdJyoi0kFQ*yGuQ3to0 zbmqe4#jH{ogeR};kaLg=G5=(A=1YDiXB7$F=Tb!nPT|?06XJ$HmaPjr-2-lV1%<$B z`E9L8HM&K3E7^yBHlp%)#4*p4e(#+gK|J@jKbm4O*9=^fB%0EYF(~SXBB}%^8E^sC zyeZ^mP}ecBAuaVHlh7;_Uhj(#uPm`JIcV?5huX3i;$icD`}rda>1Y~QF`1Z)_|MtV zNC!Sjt41<vJ{GB9<P2M`()|&iSl>gCvTM)ObH51{A%l?4b|0P`b{zpwH6CJYPysM? zh$a~=2!yrf%N;_bTKwVLenYxkwN?Q_w^nP<CGZS|*1Ymm>4L9v-8oM+q^r{me0hhC z*%!`uw;!v^<`DK4lRl$piPDpIWC~t50HF`R+_;7+Z$S~qlc7s)Ofms&-QT~uvA#vF zwtwCFNuSFmfq3IFg|;9?c~W0o{l+^;#`k*D+M`8cVVR0^WNSS1Q2&TD1{nf?OI|%E zGHFgVZ^Io{VhD$nhXD&5oihyXG3LtCkQ{{7t{ojy$)=e}G90E^vKjRw5>bJpPUI;9 zQLI2)YQO15UVV03DKpG{Et^MfPUekWhEzoR;p!2`wCvi&p=W<_<nz%RerG32TM}kU z;*tTf*;GTr!E}T%-N|}i)dQ-E#g0+jzI3W6TI!g-lL<R^e{?MB^o#!`>#El)`3nW{ zKjDc5-&KhJ%~3=yJjF{e5D*}ADl72+Gd|e05~0*{wm*aY_k!4<lwAnppQqwy>Mkq9 z|20o^v=SjD8g=~un_NyT>LLNulAUYy;v-?Y4^~Uu2g=f((HSr}G&g0J=9b0TX=3}0 zYA?AkjHMmOFIf<BW7ZY7x^SlcYxH8In}S!~tj+hY9OI*3VQrtfd%uYJmR5sw)Xw2t z)k(@<7t1`$HT6@!B{&(;QNBuF;dEc$ZGrFJW*TqK-@DA&ZL6y@%TEMcfG(*tcg&3M zsWY|cv2GpSl11hZ{)p9F^7Ir*dDWJ^r+Rj&wLT|Ye^B3Abf-mx1uiL=6_r<IBKd<e zyB`|X*B!T6Haj{EwjDh=E+3zsuHVlK8+Lp<4|df&(R<LEHJfP4Lw8J#VYXjpCNQgA zOL92VmB%zIVIBj=j1vH{x>Mt-46s~`q1I{Fkr_~_?1-jG!D^04r$y#w)lm+Jow*OL z+-L6PGTRZ;*y>ggU%bbWh04SCO;zid?GCTOrM|CX%wv0U4Qd2<FrMG+D5@z0PbHiM z`jKZ}3m8++wn+#@_>|&p_0<0sT#}uRq}l@>AqFygoi1FByIufBKN(jCWZu5$(7AG3 zW#_*B+C@8~RW>R*T}N@9(srb0th+BVMO+wC5;7nDnHo321A019O?=JSxAk(L&*fRf zVRQLKy0XzKVp;c@cmMZnRLZs2qJBlj4hZ8nw4D}Zd(-eH?n{#%i&u}hdu|tPgG{X} z98|&h5~X2ig)Cs^EuBtf6byi0XMwi|9|vyJrb93lFIOcoN(c@jvyVWuVK%QiZOvy` z`WI=qFWX%IX~cGJ#yEWE6RLu!4*{xmqtJaD(<oY0v{|5=_&1ik%;F5@p!i}KRG_so z&ug_b{Op^r8+=i2QlZ}aV#A5YHb|hS(UKfz40wOxb1p#DC2Z7Y2zu7TPvh>acVaaN zKA=k4S8aG<Dfn^g<>?{hC_k@=!0U6jzlcjJ3KGu;<#9mk1E=94VJyX3$DBW>I6P`F ze+NJ1h!Gkp$mgLh5y+6!mpin@h`c%rK;(Ka8Bsv<Q!xW^-VrqEw^FvZdHQSjx*6$r zf273OTLPF2Immg`l{~S(Y_J1&dnmO)`(Wegy&y%WEQeSR7*v%E^1}w)A8nJ9<g9F7 zT_Ox6k0wMWotk5-$)K+lM+)AWE|CqV&Zft)Ah$7x6VUeLqXwIA&&<F;L8N7$A;I8a z4F#S=cGl1fDJBs<X|I7r<DK0^IM^<UMKO(ZU;_Aoq0n~FHFlGKXhA|iOtk7ph*1yj zMd~^ndw+W(h$}R>hmPT`hh^;hG<w9W$PA!)VH$4hZ5m`7=odGq63@+#N8LX+(^x~4 zr*W<MIPY*uG$MGZpx|d9<iUTvclMd}{5lcoGy2uiYXjw2G`3*tSt}47?tBt@Kq#)} zW({Z)e;4@|0BQM(oQbI8f`fc{p<x=kg5Yn`*w<E|nCqf}_Vx4Nk_X1Y_*jbhrvvZh zx(d@hT3p5uBQ>7#t4w&yDK(JwuaGvKu{5_0J)6c4!3yqZD080DIz$r6OXc|`<otj? z%c=umWn*GEYynq)g;wtn^R=LoEcBO|+?N5EQRO=EL{%$)>r`B%dT#^cjdHD<jfqae zFL)n(dhL`BV-HlZEfM$DC_C1xGcHc;NF?o#fL?568A@;LeD%E`K3vxPohIBG^P;k% z-#XEhM$mLn7Q}G^4g)JpJPc5+jdg+f0SO@A7JjRUWKnEbDbV!hIXE99{BfXy6Q}?y zNRhUn)7_8FtrxWDr-{_hh&XV-DYw)y=L^K*fF|d^wD|7Eni;u3(!Np{atN3Lx;TbD zb(~+Ml{-e#CY^PdlB)UqaRthCT@{`)^w8u@mO~mdI_rN)T3*C=;}qXAf|Ehk18Rqp zN+a#ttK+GMhduMxpKKxChT*b^uAcytUpNSYaULJx+uy_2tDPg)tRxR%qT|6|785E9 z1Z&6f6kdpgz6bZS>|7~V@gkKQy}B?@1hx=ZTWO^0mFWCPN~f(B_&e8lB+hG#)<_lT z_|APxD9Ar#RlFA6G>B-O$VrkBpe$+db*!gI3+$k0V(@agPSm5fa1aX0=BfcwQBG!l ziXot_>5}{+>349fV!N`9$4Sswx>?{4LeL={S8Kt4GhdjDI+G9)o!#dCd5%B7*eQHW zAVn9o+)MrtI<vvqKTkqq4O|ag^lsbUO!i|1s7ts<AUSJ$Ovi=9L(Hlq$x*!-Ua)uQ zd@6NLKAl2U%vSemfHZ9{0m%Uo)@R9Ygq4l*No{|!s%lj#c)KX4+U*a1?$AGB$sroe z5&Q<B&a{*|CxUO7m(U7}S;kxyMK}5$9@0p+7MV7w_e_S$fTDr~LZ(TP$j$d91&=@- z=WCpPBx&s{Sgk`JEgp%5S<JbY_6&_dP;*?O%_BhL8XO<|tJt#_(YFT-=*L<!gYf<p z_4=`3yeK3WcLfRYDKN`Vc}4xjQsKn@>eg<kw>HhgGe<aZ_j8||0jvl70rZ9CClaWh zlh;nc%r33ws)~+t2bdjZ#no?r^u0XNP@vBI^h4XRuN*`n9&sC#ub%lSu|WEhG2W74 zZqVn-l3zjZKRH+h%HCf<?tA0Fg50s0wSF}7DmjnUUX02Cf0h-A#vk{n2%Q^6&W9ix zNiI&03(0itu@9~hz@Yta-?SKATuK<Q-M*9%#=(%FR9P>u($};x2_s8)FN1vsxJWT? zRNa*MF&nGRK8@1KrXe2?r>50lk?u0zWsKgv$V-zUiVl<OI$s!oE$d9qE^Sd8{tlUB zfN4qR<bj^t&bxKJsE@oVQo^vOIp)v}rg}tXg^(r;HF2+UHN!s9t7ue)DVAZ7L`c90 z3r<?_2T=m-trjuDP&T;9OWGpT=0;}xyb2aQD5K$*11FbRxG94SKEk(j&n*eC1FtE} z<@TqMvTIpy2+b;hJV=xJ4%-ySfS(g=nQKJMI2JEmS?LR*2h+n!9dL|BViOr)@B~o> z8yWx+9p*NV3TNYZE@d@D7f)Z|-Z1L20a}f=&V!kqgAk>J<<H^Zkbow`4O&EKZPv(S zs~K_&D^hmQblG}dGKs&6z#CTb5~3O`YYm11j@r}q`T7C)czY*inx0?3_guEb=BBmS z6*4LnkbfE!{y5ybV-N&<FN;vI2zC4WeldN%Jbiqy34VS(TzZ$zPQHE@a*WyBN>d-R zh$TnLuRW<}j5bu+X2;iaK_$JHU-wM)JDh}Ir7NytC(+ojW)6L+L`<)h>lsanlwfa~ zP0P58n#TjOX+&pqW}WNuxp2!o4$4i41I<tZlXFZ`FIfZ2)DTUo!3v4*^KpqZb}VS9 zV@cKR7@P7mi{3MeF>HhiQ+7=z!9aWhUd8l@5>4#zO(xPI&gSIB=o0gNbEy!Z5bbe$ z1`RNjTl(o8H!)Tc%0gzi5_|&+`HTCnN6hFSd!qo+@>B$xnbLw;(?!tnsP7>Q1{H%G z>^D}i=U16z<kU5mE?f$(56MK2<ZIt;P==A-t56f9zx!i;!Kk)cI{gl~-H*k-o~{=1 zH)=p(6HK!6gPvt(-+V|bB;Prdn}|kb6M3oxk%{6<tu2l9c4s(+*vBDcDh^uoaBSDN z#<>D0Cs8o?U@UrWOP;_{slR?9*%XXwq}7tBD6d1}-8#bhqC4=&JnH=QDkvQM$x!zJ zB5@@W$O2)p12#Jy<gU~FD5$01hh#=gp)Go@K`vfUG-4gqV0xtsum4bO?LFf%H*^Jq z9TKEFp>uJA(%d81E9a=BOIrkw@3e<x+yo6kCdlwh+-*8Z9^Z#Psanfe5LQV&qMR=8 z($3El>NSI1#eVT*VYU=WKvM=E7pV)ZA%nJ=T}LZwpt$QLm|xRw*Tj(_PJt<SA!@^8 z`DG(#TrsVha&&0+H9;BB6!&AT7I;at56`K<K#Qsg#%1V1Rc{^f%Z~MP<*h6o{TT<~ z6wtoUfw&UR|002_C#Sl45s?~RYt|}V#3~y!N(pTZ`a6H}0s9pqD!879#vy@Y_Jvqt zaJbthZ|T#9nn+;lDSQD0Mvx?fw?MKG;GR=}gu2Drt6YHgmFD`1@I{7g`css~0j0fD zr5E9rK?Gha?=IFnaLqH%St=$TTHF*MA&7^t`kAI4GEpZ0O|0e)M}13(qej*CqRF;y z%3KtHg;dgbf*8M~c9fF1Bg<bisy!UpsWJC6mDQlT3(#=(HGvA_uI7h?or5><TK!WL z#w-i-A!ugRU;xL=#k-XMOWEX!o0u>XgNi{x*Ka3N$gB!vidhU53pfQ23@ZiTkql}a z=vqjMW~~MDR7(4Zh_Vh9+6vPsd4k!Qycn7F=O=8NzkZD%98%)LBi$v<x8BctOLfNj z0Ikqur2gfUKmEzxk8mv@46(mr{Z;Nr$>RYVn^1YT7vBVDEwZQZBYgE`f-0p`7M*&_ zJtCPL?2Tc93Nzb`O`n1H_BtJ~VzUy5q0W~K!mggOs*w?;8u`@w@0++nVT~BAyUYU9 z0>@IU^f@%D0?lL_VtTJS_7zkF^PqHG;zc0$WsXAF0n;S5nz(DUz8#E#UXk{7Cqui* z*YuqiLwa5_V55YWSmZf4p-F88s)8n5<G5wL>Xu~2(Au?<x+?s9N^Sty2!bt;r)nox z!hJRC+fqDm$YL#qz2{Xs7K(?Or(*{x*d62}*EE8#vQqtgdV2D4V-Sj-x4;zPa#ahh z&NbL46!Tq2(sK=MNltLT-QYPm>9M`lxEP6T;U?lh7isB9+O|I);^A`vdowd)$Wvx5 zR7Op|me#NgvtDaEp=AQZmM{`<3-Owy!4XLA-22uH%vMRxzp(|rjM+EK1<oJ^vv;j3 zk%aPqbp}Wr+HeMYL3^_{t$^O|ptF_Qqs{Ei_KIbyiuHqjt~(xN^bLI0!pYGaQBs8V zrxmz#qYt`=i5soX*y^EX$i9aSymRX0-oZu?yhHsGfw>NNWYY&&ra(I6ZR@ornz6f( z+t^wus;t~FHb>n=eKO@dOLrJn;5sW@RBW65Bi?SBd}M4BX0Jy@=T$*O+|!-kpwP2I z1|9};ys^+{)>QevU9;*sbNL@9L8-5aDfh{*=mhKunP?F&KQ3|{iapiODhgeLgC56g zYl+;ewYN7KcaQ)oV|_RLJt#L}3KbQx6jsq27qKjYn6I`rUia;eUpp+IQh%AcS4*x2 zc}fKJ{fBlO2lsfs4m>Fj_6z{Ou<EQ_KazPu#m8Hj;08{7x4W!;?<C8X<0cT9q0~7b zX}6$qZ1PPkO$^0&H@88?jT$1-9etGvnZ**G8GI0^X)^(&<>5NS9kA}raz#8OZN5FS zfm2RN3<dn|e1_0C;Mc8jp94{;Pa|NT_v8}fX#je58J~7j32w2{y!=j1DXY1@hg_f+ z9S884o+P~!7r)E9qCMHf-XJ?zc+me2V8|x&i=9<7*uttHi39!IEQcCFNGOI?ChOU{ zzt)X<KL}u*itP)%S6L@})r_riRpMR`j_|~ci#_3iyV^&gM_^RtNRT*t4I(CK!G?=1 z*B)(W$o6*W>D2ef@<8o%Dj-^j`fouDd);fao)BpwbHXrl(jfNuZcRcjb5ge<sjnf0 zry-3ib4s(=H&pSvb^pdAKlPs|+TYkBMV2H>c6)#jJz;r{PmeuS94NhcYVEg_epG*& zpogahlEcifdx|!kysSulHyrd9Mg<GnyK6-9vmQsOkutvc>^B4`0R!$fw<yAkWBL{I zx7N`G&otU%u3-fZKHR5f^Q982pg(7F_yV{y1PbID5I^;^EhIp*e0o#)chi=dGF3vR zQ+oi6_cUU2^Le)M(Mq?#{F$K2ofF$tk9dWaXx)nEqy|d@pkOZ+#x5;+P(=xS*8+X| zme>d05|7ow15Dl=3wA$S2@<5rD8In3xY389x6;s7pwKZ{w+Hb=&_s!aVFPXPJUsUi zW%R4?RwjUP+pzXov-$YRBKL1}E<C!eLNmZ0WRjTh^o(2|(K$R-E3>{bC;5v}{(MA5 zfnk3I?W>zB#E?wAZM?qk&$Jd8<7;g?T!;&Ae1F+$(V+c`TY%Acy6@`C2VB%wq`n=A z+E%+D&2S`}tzyt4CmJ0=pAolPD5+Brj!qm`;n7x}X}Mm$<QzwV5+C}dLP*&SB_DwJ zxqR2?W23L6q=3E;wOqn2UqSHp6Pp-g-PKDC_rds?Ef;F~*QRC8iKBZ>*H%9Q(m0>S z9fI(EdCRari08j*5%%=2U`iZ3AiFO?jA>3ljD*|YzY$}G`QJhUzZYL6((ry6bTf%7 z&|<Ebo~4R2sBFW^Y5L<}?OLCn)JFnF1N*zftP@-ZOBtCFo5{utmuun?^9G{}l&{;Z z%MpkJOrNq!&gCMr@{`S3{JoBRSc#@xB!gR^RTy-aJG*WLej&De@lPM;e$#tUnW+Ya z`xLetA5BC3)L44#Y&EjFYT{*;UpiV>J96(AHC3xwVI<5*;p?V4y{obhIAQ^)hZM{b zWiWQ`kK}o|aTO_q|Mn9@r(T&K#{D7|d)Y&-&JnnK`Wgw$ymbGX>gA9XNL}$KYpv|+ zarsw8j8WU_UHpu8@k^Jxsz(M6<@79F9hFd?4|`UTCPF~=e3((wP<*Kk_GfOJB~8zY z&pXB`hzb#HnD|AYSG339XsHRn)B>g_pIy-m1w-iyUn2m6{PvqjvQp?IL+_H)Ve1{Z z{0@&TeG{wuA_;vX`<ZrCe<lP2nuIc6B5tpbG}6ax04XW12cgzLV4s>e7+80Ei>s1S zEs@;l+nmn$DSyYMT5vR)y<1lkxiv)bHGPYkH~en);Oo}BwOBLoeu#$h(f$AWN9*n8 z7NP!YY5DX4k=6P~)3~LQT7Y5xPx4Bl<*M_4H^};p)hUSoPK@aoaqgl2@>#M8|8twB z-n9M8X4%|A1p^qZ?(Mr|UBW6168>2Efuc@r#d2L$g4<UOcK2<Be5X<aw!oV{00}x@ z41uEJ2TZ>dk9Tf_+hl^Tv<@moZrwNUgsb+Bpba(#Mb#5S!OvmXjIwDr6Aukdu@nz9 zI(0wD*WPAOLo?S?yQ!+uPpHC>C+y06X2f=vOqG`y$^o$3z7;W+?C7_uQ^h(Yr+6M9 z(J*Iod&G@Wrox$A)Lw(Y0FA7@et1jMJfUk{;FI^1;`i^KfuMZufs9IFp{d$|*qBU% zW;R>)&|(pCbmHtFU6j?k)*2_zOsP0mEY(TPt1YFOnj?YJgf&&Ru1Uehx^c-%ppL33 zn^(VJ!U5(~i_Q~{olzcPWUKMD(_IVD&k*0C!x`4Gl`7;ykPjuKR1kXapEe1rL~mWM zd?nwukXFwV#10`|5vj4d)KTYy7WGVEhJy!4Fh;^&q?ARndQk`NXKw#Mwcg^HGp;Ak z4|0PO{!>l~+<92*yYldQ>fN=@<El>0Xz{S_r2s-whPxOEMyf<x;j5129X9;yJI>9x zEZu!6OsRYS)-uFaLDkHzRktbR$!{4rbdvqaBW%koEk~h(SV*N{%<aE>|HIOP3O4;h z9>ncyV2$aeK5`a*iXWpwk&%!g@@-XHVe$8(p&H%hgQOwXoFvagtIWl5+8R?r@Sv#% zCl8<k|F0zwwhN9dmR*@Eg+?M}ZG`J3TbJK1<XI*t?~4)wAxx?-Q3O-iw0_3DyOuXG zp$VTn&gsVqI$3ARULjFVdahr6wp=$+YaYpzH<Cg&jfTPgKA_r87LsZ2Z(i?O+uC^= z^Xh&`hN7V)g8MmoU$Qk>>ZCv7Bo9Z~cNd_wm5mB~!{17wz#rmt>~3U9UfJdx#4uj^ z+#i&-VrZnEnN~#s1)Psd+X&5uPOzBOO}m?K4Fu2Er%$&cqVaZ@<7Ud{Mo99c-E0v+ z7_6uR;B4iSyjrz6OwGW?iKi<_K334hQ8HH!-`tC6b8wxlIO_Mf;9hjC{0oCq`wY0q z+}2s4o`&X6@FEOZ2Q|G_1uC`hw_Rm<70>8SjHC_{Mr=j*YKW{wBlt~;uW877Q9z)h z?VsQVhFf`9IsLAhmQ4CHZMS;r`9V&sd@K{Ex``+u?L<p;zpXZe?pL*aMT6rzGtivv zE3)E|HLT$91HyG5X!2vQlxuUI#0%%-=FLtqN3q2urr27X-cSzFg2(|Z?OQ$(a3BRb znK*nvM0ni;W@yKaU0pi!7z*h3FC~fMCV-i-wjLz2$2CX<J2U{bNi;rW2is&%OgYp7 zB~H9PBm|{ML_Bgtn+|(d=zaH6xdRv%LDs5Vek&%%99e^Xt0lf3x&Aj9{Eqgw<p0qV zPf-8=WPk%$nVZ@&Ie9m#%iHd=pme@#A_N8@8q^>Ect-P~Z;z|%3?acVzpx^g)sc1> z?cR>>CUczkK-Ne7Ey(UDw1rPu*Ej^JRBT=7P`8$j6^)p}A4>v#jIK%e){8xrvPU%? z{6LCNps^MyO*ms+O_yiZcubVeVn6<93|1Mw+)M%xx|#6?Bb-r;d!IZSE)E&~d;a*j zzt34%d*T%*`7T4CoJD1p1Dd@xz<^D?MRJcb)_V~LEqBRKTwJ*jqT+?qXV5Y)XWT!S zE?9713s(S})=Xo@II3nb*jU|0l3b&6I=C<$m8drB*6T5#Q%FF#A-|!C7#6;j!d~nh z6^#kdPJtcl40k6mp<pKNj#}^PU$l7)QCPA}(+zi~LzeoA7Qxfnv#dcuvQj2if{*AT zGg~S-5r9;so(1`At)1ck7RmnxzdjlPU)tfz_EmF-EqM3Xh(l|!Jz;bhT!L<<-x=pV zquYql235f&VZue6DqY%AeMP1mjpCgZK1l#jM=*(?QD8AfVCvJ;{?I#aU)HS?pT1e+ z$@K^1!F2xQ*h;!%GZ!#bP2!Vokk4zkiPqjR3DhofP4JJ<$2!NAZlVVqUUDA}f%_4B zT^07f==F^&N0R?UUJDrqQ?IzQ32O*FN8SIqoSoX*WawEVCX~yIdZAiIRDAlk_=+4L z1xWtjc#Hj&k}E;zgZZQ%P=6YBz83yT4Ox1VIoFZMet0CfY9?q;kJ5aK80AyE>?fVu zKf^2du`rFKMwDs{AEUXAc#+MUr*QgEXj5Vx7-b7tEFAy8$g;xR-@%6vARr0IARrX~ z5X{NiiP_NF!Oc9CI0PK>e=rIz5$X&Hu<o$Wh2r<DiGWcc+nD09+1z#m7I6*&IyV5! zhJqhf!i@4*InhXPVXFS_6qBi|-r8*Qi5H*BN@wrijbr#t&Lr9qfg~$T>6gsB@rU1* z2ohzG&7(CpZt`pQ4Hok>>sOR^%cx~_dR(>}nMLg-P)UWTt*i4c{qqFwtTLYj;3USZ ziBr@)tQO*CPNp<kK&F|#`A2epwNjokegfO0XMhfSOX+k#V9kvW`?$WAz3tP_MKH&3 zbE^jhq5mX{7GfoW`t03T<k;k|3|44BO6x`hre*C0adQ62zneBj&y*cUXU2r3mC-Wj zFNA|nGlT}-5hCc@EU@sj@bt|qz)cxZC_kZMbvFX6Tf~?9m19ZwWSFF9Grd2yFw?Uy zI1v%uTBB4{Y|;l%_ZL9S+J)13>iVeJ`(mhH$nE{+{y3Is(;oqS8yX$%`}w`!aws+k zGf-;TVNVvwbiQF+a+hdh{M+Yr*q7YQQU=nvC!^GkK}frMWxPI;b@?6-AnFs*Le0WA zY@!+iOIpx=>h_Dh`K{Pnyo-~dEdHwwFBz|h)7D9cdRJz+$9chy2($c$8Y>e`*c5<K z89YHfVfqKAF}h3(Vlu~U;UCqVF=|LGnbc4)2B;Ku@Kh={`0?V!n*Fq@6#Tp(e{}_y zM)%(<mT0J=_{F-*%)0%h0IZYpjWJk7&E+-7;0Ey-jvk#x<{BQKJiSy`MshpEkcqOm zCGo*SHrbh-UE?dE7(-KTj2GLWq9+#mXo?T*-GyphgS&@5eL-qgCZJB4qV);XLR$g{ zj|H|)z#82(uzGB)u%d1?xcVB-JC?p_H!!F5reKlX!2n)?`@x+TfHR@y?{bJ71@PDR zXTjD0SWol9Ti9e$EPhnrU@0|Wp+3v~(>cgP;mAL&eerA{$t>yy{F30P*h~<-tg$wn zcM7%!+EiTSZmNtTir$Ge`A-luk+KzuHcZZGJbu56H-2wp*z@Sl(i9m8E?}!s?zS(R z=(0`i%nj;api+te+}kwmF3a_b-hT_PX4qIY<^~(^4c74=y>_V;zAKc}|A5Rxg3&G* ziGic=%?#H2AOOahj*$xMj=&JnQUv(`V<LC+k5}3(>D`-P$rT6{z7=q~nmIQ1*8bjy z6yN{*SLiz5z=Ze&!JO69z6tlsW6bsTdUD#;fH6{E{0LM7jNqjdO@no=otWAWEVkm| z{h-@+vc;;S${P-ogvTRFaw6MYD`%(sDP~HrW1)N2b!Jsmpw`d!&ENctWpiDkVjGk_ zaq;<$HlN)-W#>m%kJXS^wg^<%(Krin54$Zxh&9QXsK=bWP&+;2hiksY5Nn-y;ln4Q zWPM$zkQ`tDlxI@sRi6==aSDxGaSJ-VLVYh}TLfAr7ghUq*kYK+u8%-Wv#138%10b7 zXe8QV*-$5O?{b@)0SDvGJX-AaFLumduxYUBf-GB#_GaHHanl>7{xq?IVisH=r)_Cv z_-o7N*B-a{BUpxL4jy@J#4(^rN)T`CtW8-lYTauUK!!;#7#(L_5bQNVQ67tQ|Bl02 zk=^iyU6Grx_J?s;TA!e}#$e1ui&eM(NR3KBU<3c&c#+cfU>ilmC&~3alwCTr@XxKA z4?kf~Dor2>Dw@e+fyaCJ%*ZA?$i49jK!SlHdB88(d2$#4`u}eECW?K$SoK)fD)9ed zb&x#bPUgQYz8m-dV)YIhD6EQ^xrw{wKd{c$)^*%yL-pS_>@A0hfv^iXaChbsvEjD@ z<vuoPXRa2VL2DeBL{m?wt7rMx=I@UZxA8<T@CQ=59PLjyRo9(Bl_8)$Dbf?kCLX;} z0t_n&TesQ61J8lCirTS^-JwO+=yCm5$6r9I)O<Eu7e<bcFMF0BPnG(i=+LZ54-wCe zYDgqHH1yTcR^lSQTdsq#Wl$P^rlpFn1IbV?BG(*7Yl2GM?U5+rjxAu$W98WjWo<e- zw2!!bck!S)l<hH(?mKNxHOE>OGd(l40LLu6VvmiPU85(G6<h=RG+a&st!azy*7lZ` zwpQLzvUkY~$w4`@$SAK{49#K0ige>Z(80aWM5VfGFGq#iXvv1Qhc1j4aYJz4(8YU( z>>2f6NHY_u!Crdt_D*wXG}V_n3f9wn3f8qcRW@5FovG6gu!8Kve-LLSt0MGQ0J-Ow z2cOh;>QBGw$!_-JWM{eArngQJy-VsjMHQx#c7D((#nm2`c5&){kqeM8tKP|LXw|tb zmV>Mj&ZoAR^5%rDN`+0pdlG$#(^>vRhRf<fj#P_e@Au16y5F3MK~z9Q81uDdet85& zObIHG{o~FR5x*Vo7~lkW`2U%H0W;cx@k<l=U&$XrL7s_39V`&VL|&8`;BT_@J|Z!t z!p%C>5qsIcf^sjBMJDJJpa$`8vw!|;B<evQ5Mg>NC$tssrGZ#<XC>D*0^WQ!plOgM zB!PU&3O0bbk>>Ue?|t=yTZ0hM_M8=h4r<#g_o(HQu6ktdLNUpwAy*`$1Ku@i4Zs1= z6p{&*^{}jB_|R3hz{W&HXLh>gIR1z%3Ma70gb`y(814w;y*S!1b+4iEsRB!UuqXfH zj*i=)Hq7(uLK8vn12Y1sYP#Y}?|XF})&>YZU<lMSL-xb0sL}QbVnPr5fF)=OzD`Sn zfN$)Ss2@ZC^{=kZ7k(IMz!|dS7}i}HRV5p_?K*h8;0IpU<;jIJlS{_K2;-<lh}~0z zS~Y{{*oL6;*+<4)M}%L?uZT25(Gz`oVr_WtZV%3R!CUGr2Vsm`!har3Q#GQ%DpTpb z%zMz2Ptva5`Bd!kgHM9Y7^DT?0%{)ZU}y(wXF^zmDGDUWM%D^UK!wqxK}HYW@O>2@ ziqkEW%6teyjOzVxZH=x0G$||j)a^*ak=FHvfwVQbh<GGY!0=8lIxPl4jj@`~oo`v* zP^O<YJZ2fMC?@h?h>}<;C`wO^d+=TbT5N&*w$#$?8rdwBG*<m;fZ*`wjE)z+H*s3z zk{(x<Dzk&$u`(PIz&29?$v`cYVLbQZUy7=b5>*-S90$V;9}HKU)z)F5-^drjqwylz zh<K(CHjQud3avE3RCit13*iq@&A3zBXH+^#-8x=O2nLcFhf4tZSaRQu!f^8Vm<)e4 z=lUwkqy;i8S5(&HAJ#-Y3Y!FzqUAOWQbmudHHz-@Rq_`WzzgqCcY5@Z-#U2BXldS; z88u42z}Z;#j%o`Atyp{qVY;#P`DzNIRVGKH_n2N>w;eWwEO74|I63HO*sb@yzvq!i z!}|lj@J~+E2hrzQl6B9dfk9N|fXnDa?N7_-daI45b<edXhX~VRD6JB>BEo$#F2KSP zuTG1I)o+Yozz4U4<B@7F>@oCx_G!n~!d9nXD1{Af(|jv28<)S4ZYdN+17>y)#_MhW zSd9cZOv+<HD@6bnC^)7Zja_x)F?Jqf8^+8UFj$^HCM5)P<N|lXC9R?dltc_R_|R~a zS~>h-p8!I?|DFli4Z@AOhi<E~S}=<pK4b)qip`A#;Lua`N#(6Q7hJ>V$JZ%lgmagR z0-H%JqPyee=bgRL3aRXbiw6a5NbrijGoik;4lX-h5JGgJc{h9X1RMS<!_f|luz3To z<q#|KZX{9Awj#T0Tdo6{K9z$*IO-0PkFe`4-PeQ@L~`O)<GZ0h=3$@?79&)1iJstZ z`W@dpAZLVk#^<ZO`<o0S=`mG0PqT!k&Cf7lJFlPQdK;Sk$I%cXSe5xJaHM&+oT~8h zK`l#tNIwI=6vw?2sgd7dVXJVy@eeOcz%<ng-(I%J@fjgz)yp5^rI375!Xf8Qw`j_W zbAsRfxk?s1HHFz31zEg)t_gn0%8++47gn@k0FqE%S=!&cXFdi5>1?yM;9>n&pWf50 zex<!*Rc7u-A0x`p4m3dvK~(6ey0!DsetphExL{@m4A~e%WP$@aIlNC=_EKr`RB-V3 z5mJ&KVwOZSi9*DTN?%fuLY@OBaOzP^p0Iw`Q-J5u&utT%t&8nA$Xbc5RY}B6<nYf3 zz=Tk=swxJ-6CuR_;p^h@Z$)FV3m+OOmaPv@jIpKEk~r`SAwJp`gvVd4NA~qJU@z=| zm><xx^L~9%#MMrs)4Rs0_KtzKft{Vlx%`yFq~Aa)$DId<Sbxk&sIlsyt(<nMC>bb7 z1LL8=>EF+)?FjNtZs|-Gf78!;1?S8X0Gn6FJ8503*4(ZhS&t5Djo4<w-0>XdW~p;+ z+rQHxS?zqx3gWNG7`e|v49QXO5v*@;;fR3@JvM25;_zc2-h=keNd>r)rrKhGNq_k1 zey;~YGX|6kp7)w6;ed$1N(_#t)3EtG48m9}&h+e*X8QY#N6pK<6xmorZcQcL1Fk#p z5T9mqObvLZA@%~Gfwi0+H58I9mO@)E@uebvOi2asKIodn`L_7MQ`Xk~grz_}h#+Zy zFS9@8yJQtjL_I1p!Gwl{7_%sPrT3o)?JgXTE=o@r-q61>cTKe*XM_A7uFm<Z6R_R- z*|u%lwq28L+x5*gVX|%8wrjF&PB!1pbJlv-dd{D4|8nWxdw;siOh@y*Muq_TpH3cb zE<U1+0t>xce%)O?AWT@ZYM*_7ymQHTKs}tEPaYBTF~BSg6+Ra7n!f4BVEY~v1ueR} zoJVy*7RDb*Q5hwF5BqN>O8WFPg~Y!6H&OaY;~ZRL@a;!PzJm520c7g`Of3LY2M>E& z2P4y;!KGMJ$6<p5?FZaQ#D|s$tg}H71}uyYC&g(f#Ed4pl1gM~b+&3Qnn)wftq%A^ zpjJV#<F4ih{Y{?(>(%2@{L-Vbj*{P^!_dmQ%}>L+VcASs(Zap}A*K1<Ck7g5zJWtd zazxMRzKm?Gf085%tIZOh8U&EcaW=>osVU+fOhd#|HlN7}&@O2;wAxzFPB<}T_bn-2 zzfP|zxDmW*-@|z#`llzUm0)4-(S+7#s+y~6M%Nf4Y=`~;+5Y`}brt*mPK~S{Z2q<Q z+Obz~{-s)}^$NyA<A^~PLalBY!WkmV7mUR3%uAJ97C=v{W8KHW9t03J0BWq)P4k_R z$5szui-FK~>Lyb;<466Voz3_O{wQb%ufWmaeCpzWeP17!jJdvjg&)w-F5Xz13PsY^ z8Pc4X+imryFH~#bSL#TcHZL|DiQ_!if*G#ZO}SiDjmpICpYauV-cb%%jKJS0FxcdF zFwbctxnB1G#80*BuK}_Lbv16lr-Il<z{?31QB_69Iq{mtgKxq+eN=27q3MZZFh1XO z)LG_KD-3DENg;}rzxB0<B-lH^23*?@AV-g1kz@x#l!w@wLI1|lU>*E9-ph$ah)8h) zHveP4cI$ldBzObUMMDA2w2)x2j8YjyO>Z<-0hSkws7re`Ee5#5dCSh5@ZtK59U+Q1 zt%_hIu5~P=_kt3Bl+srWa+f6tg47^5P@l;?dBv8e&8E75>ynte5Vab~>G1pgi)`B^ z@QcL9F+=rTb!Kx=y+5q3B9b~48z~c9Yb&8QIV3YL5vlbuGVOr%l_(BAl%DaHPy<Mg zA(0*f^Y<U&E;WD#jkd5~{i;S8J8Jh<szb+d!r7CGFuAx-v1PRp=$njD;Uw)-=X|W| z=oA72#7~wugvn{fnGN2)4-%)$OO9K4*ofguz}t#}f2Z;FMQA6&YW8Oa*RhVRw-D$Z z#T1IdWb4uc-W98X`u)+|1k4E-Z+E2fscTi8k8fiBMG-*K_D^ZrD35~T<7IyX=)#zb z$Uwy~juC9=3;TNWS4bDAGUoll-^gO=_?0pL%viKPaX5SDhB70KMPg5me?t74pQBd& zB{DvWR`_SDHRQAR1)hpmcD+=BKT`Y+ml971=9HnoTF=4+86`_~bV)eOF0aSSus?)d zN%`4iQKkUx(5jCpCt>sg?b2_+yhDZ8jHglg-FV<GSSa}-L^~G{-aUj+YMTwsj-WtT zuZ6?V;M_Wb3I|4WP!0X<M}?X4#<qUC32wo`g9u~V{J~75e%1#ok|yi?yPA=p&Oh<l zf2(X-x!^W91i4-K;_u%E4@~LYxb^ct(@G<N82tcm;CExO%7$6!WgPf6jnp;$<%4{_ zVNQqsCUJjoJsCTd5Pyq<TJ1+jE99M?@tY$>vfyI+@?4=t>W#^)BQIn@;Y8l}Wx;*f zioYoQ9+!?hq&CZ{$sC?Eb7Og(msMs$*+d6r)P8v!HmCemR3z|>J|Fu2autt{&JT<M zQ*H|&q+Ip##VIM_CoT{*<EP2q+6)$j+7?Ips&Itnu)<uoAE}RrvtlTImotDsWGr-m zSn2ibpY-->U9q&m<FBKGw|pbQ{ijGO8X4C+7OFAfHh0kR@wF?{rADTRDP{yIiL4~u z%{4J>Oe3u7&Z)VZTLR(GFr4eT6_m6G<XsJjTg4zK|GNEgM)2@t?XJ_8Xi9`cy&QDX z`y%grr@JF3*e{<ChZQHGi^9XZeD&uvDDwkOPXpb1ig{*0{}hI$>I*NgWl~5JCSh$u z*@mzp3bJ5sOvXX&mB69<Z3DZL<oX?`%o^B8em2<9@!x%Ee_`XE-X4#$(+IvCXVL@g zRX#WsXgIktvAdo$T(?l{|JeK74n}7}cLn&&>|yCWI!#e_G0Q1E0+;RHK_|x|92#n7 zNyXIMR@De=Xl>dS;2iFahPaD9V{xu|05@=*bbX{-VcV!jz>B6=o!(fJ<0ATI*7u@p zj4<Xjy!xr8Xi{**WU4_R-%WJGr6*E*eMvi|!-t5Y7`Dtc0A!yD|9kPxMLLH^`8f@m z!u>}Q|Gz!M+}X^`+w7-fRBLR-9<U(+t__UDMP$S?4-TqHq%7ML<B*=~@E9j)oD-~U zmg{3i&$gU5zyGfOSs?ot$)6(7)O_;Jd615rJ-5v4JG8WY{>SP7t`$m7Y`{VHiD`DT z5cxcgN^tR%&S8_j4gOs#Pe+`AR8ATCsE>vrN+J?KHtR}ng{i%V8ZADJTp{6s|I03+ z<M(K(*sRkEDRgsy^x@Oi^z_BXh7HMjz)^p=u><fI&Ovmk4M{gD3hdp4V`|%6v&v$! z7uT+Jv$fF-4d1zb3;NTDrcl+n{%rm6G-w&dJ^P0LjCJ*q{qU(t|D%T2Y80v_S@_tl ze&aPj^Xp%j-{&+>x!oSxlo&Yb)b;6(pW5+Rl_?>sGv9j?jK@AUgZP>9;Eq0cg2_mH zZknCuvWj+fnGfXG!xt1$Vjyu4aFB$v*b_wnmnj{gKP0PGO6X2&H!DAIIhBiw$RynB zAfkXzWYX6fEG#}%xNWW7s2=ikjP52#;voh=IswQ6erYPDDNtl@2pUTzD5A^`wgpQ* zT#!EjMug^dU=?%Z9JCYn{7wM5NI(tk$JYv)X>rs4Prv(atzas+nII;r(~WI^VPvBP z$MqP>nK0owO2aX1(*W~<jE@k*BGC5`s>We_dEcB@*h;uaa(BWuaz7~0I@~r1n==ex zy({89<8wCA`Tpt$`6suHzOg&5E{;2h?P&94_lVb;_zH>{UO@HBG4F#eQI1B-^U8IM z;qk>D39I}CjW+=1I<+GX!A-5sAQnU`<d3y*Jx)#eS-ea^;cf`AkAiE!aF(6lADhoL z>4a42gpR$*i?ke@q$Et&b&(_6-XU(l(J_1~)QoJu;`@t;!azrktP-UR$YUL;q<h>? z|Cr)f#Nw!0lC$D8^oH*pV<c=%y?**0a+3AZ#_$FE2eUVvX6BIWD<`bDt`r$JdvD&l zsF^n=KwEQPMeEyGVd;){{|EpI;cJhS%=)!N{%WA?RiW!2%^rX_@G>fM?XeC>AJjpR z`d5<#`TjypYux+S&w=i1R^%vgj~$wy=%s)p5HaRbXH|q2ua;3;1<ca0BFE61KyK}# zER>uc8Wkh8cr{pG11Gq!hv#^}2(d9V*KQepeyRU_`_RDd_>Hn~^ob@qYkC&ViSyDC z7bhE%=T)7a4$+8eE`v2)THqN#Uhe*CI><dLCM#}<YThCIinBSLcW)iJ-L%<X1)-rT zE<KJUAW&^Q&OOK4-@q+$uM`tYpU)ph$)Z-$Bt&(ij!&9~xoXOnEdA<gIz36ob}yq! zik&{Vlr`BJ&z;zte(zc9RP?@(#h@e`REV!NFTON)*V!IW`(SW?ag@nSg*p2tL|T~f z4rK+O=3~FRxFrpetk-nynud2}ybia7|KtBukybx=U|i7ue1*4WApw*8uib`Q;RtQ} zXC7@w`Og)t^=BU42L=RRVPh5r^$}9}itcX(=Ijg!P2Cc)+hAWU<o;mcd=6Pu3ILnn z*Cze&Ys8yu$&+npz8#aZna`&`e0zj}kt{kkx5LJWRv?*f;zo7DKTlD&Ev_W&97;TM zRw><5FhhH?T3EIARD=63DiVL!4?@^)a3FCc9LGX>23v=Imjj-7)aLt~gX)qEE$<>m z%FL|Wu@DskTTY0;zA9b@T3^LFFUf6XYnJj!A<Q>(NJ~G~n^W<GBl={X<KWSntD$M6 zhM7wc;wb4uDEl6e($in^<d>g}@ok9pXbhV8mY{|YphBmQ_6cAi((y#Ig|zB~h-j4g zp~{pi_(`UaUI9y}!n~RX80`fHd1U5-zsd$BT}9)F@Ow$8ci2}OC}*RIs^{#Lf@dx0 z`)A!0)2^w(o(#1ilWa;2;_2G&(ch%<T-}n8L*&KrgKfjHenFUk89zK9|69HcL?Bpm zb8QX|In_V`HAd?sG6WJbbPzeSNhcmg-p#ksh(B~m!2^&Fe`kq62{Dt)pI=Wmq;W-Q z1OW+5acs?Ldf1)Wr4JZ(<TlGF(n4-NgUPG|XUJaJX+R>*<JL+bi%~g6*WZxgPBzHv zy{y-5b?G=rX4@?w=wTWC9%CI#7|^<*)acX`^a|;!u!mUZP~Xg5pfZt+P*imgG56l{ zp2r;h`D6&I9ZYLYZ`r1Q5#<buw`o^UTy@}bFyTmios(lO;Iz}U2r>j$fUBOBC*QT} zC)Rr)1}k!JlGo48jhZJ?v9EMupgD*yE1Nbe7o|$7o%fT}@+^PnpK|}`;W2iX&A4N= zFIFBI2)uN+Y#Cluo{LapP>^)u`0Fr%`FF22<qS|Er=;83m*%@>a&-4(tm7n%(>@D| zbs`+%h0SPDZ3`pk)$r$cp%Q)JlAKXC|IBlgprz&w(mI2ju#%h3fQo!tey_{}0|O|C zYDDCjST4o)Eikj57P007oRo(o6_t`(-j1W*%CP_JKZ^8Se8r)AViF!j(IM}rTu|iE zVi7=vPOM#7O;_6~B8jWjJv(W`l$kNMlc0Lm#|c^S@#mnP`ozNg14%FB3Ek-HJ?ODj zZe)sp;qsn*7qjB-^j)WW<>WSA7*0?iM;z^*8{DVs=2G`0iRLL|;>w;<$w>N|i*|>y zVZ!%CIzsJia=O}Vk?~Z-fU41WBy`}MU>D$FZR~{2=^|)CIxquz3L~F`xJ0E_mxKMq zjAGGzcb?XJt>7?dkgD`Nn1D6|8g~^+Ze%`uw5YDOh1^0@b>EbEhzU_0wekV3YI=gt z8;6^dBUBiJrus`>=Cf|H#mR1IFHdM**Ej1hk<u=MkFVfik2#8dEW2(znDY1yDTltq z1V+vf>!hchVNLAR<r|-S&h!!YzlV}z9*7c!pP|GRF7<y9Mya#-z;LPXJp_<|VvU`j z6&A_=*}zGOSq=ox$cKFwU1uH`Khj*NqZ<skU&<mKUc7=Vd4TGz_gd<AlIbMk@SSny z^Hyyv;Wf#+0xqNqXN=PHv7sw$hYLO@hA`X+p#5?Vfy3h*3X{IKaslH??5O2NShE$I zDf?9BDY9a@<kItT!0)u-=olOj6H~)Z;K_(D`U8>Bpr`RTvlDZRM#x5<sGrfOq?T`D zc4pGB9A2e^+MA<dn3Rc(s9MihCoSp*p@a7~O19UjIX`vf{pdP2!uRMVFU3*yLHyp_ z?(y-|bg`Pd&EO@-2RKG~4CNrtbl2L#!s{Q9gA*4ukuR+|VS;M?lD!2?b)=d%xAzxw zvY<=%NFK8lHcpSo0>NJvV#rkNi*ik3t9FTxL{6KlO54+S{c0JUh#5LOu&Cbv`ZUwR z5RgP_BNZtwhdUA?3>e&@^jL&3rw_8|WbL@3B@5_R%2m2q8T^#wvRrWfRkFJmWtqe= zcG}@BoLiLki{>lwj5!V9Gl^RitO?hrh}Ii8di$2ELZm`+(_vmn+)9NAzWD(`*gUXx z3bz|8n-Dv?=IlI%N|NN^Lh3eb)}n`ZKOy>@?$%>2DV_s7a#Hu5C>tfafNa)kU=E$W zO~@yV7a_Lda`x^asWKR^V_D>XoG`Cp`47VyUS@%oGFjLi+e!#9xe%jNWJdjS59-os zIzrKxD@GUmE9Wq$`(U>vpu_y(Fw)>du9)Yu^2pE(sv16&t>|MCI>_>#-%~=Y;w_U7 zko0mo#*!$brY6SW^llhA?U@9uF_>T`BFWbV0ktxjuf`mBz;3cVOwO!H;$SEW7d*64 zhW?$X_@mifr=|;_^JP;^UJj{ykoilY0G6`dPW7935XGe`2cEXG>oCu+<oBze@facf z_2_*M*lQyBNKb^l!`xA0c}qplZP@dT9d)Y{sVVQ6KYyZvL~y+P)7lf)U~vxgBUTL^ z+qH$cybj~DAdFxRNW8vE;B09l6RSD(?8Nb8RPiY8iz@)&f%u2>iC(i~3S)<&@A<(_ z`**tm)q7y%Z=B#7PMUuOWDRDh!J8j*SH_s&@vq?5<gJhIUsjy3ir%_7jJ3q}ygOXr z3LA`v+chTXE77<Nlw8nmvuBQ-14Fn2*z4^6$;oVO_y~<RwDXs$g75h+=e_>wD)$+$ zo^dXM2m|f_oNMlo++n<BC14FIZP_4()i7?E^rrG~Y!>(=O+RiQy?Tm$ayFK1vN*0O zCzG(FbL?^dDGI|UG?9{=12cuxST+m~iwf_Rr$w^AsNT0Sww`VvRiOtnEOSPap+0P^ z>xH@9K3#FEo9cZeaF0Ix^Gi>)$~XT&(31|QJ72%;IbWBuEEE|-^TdQH(Jc6-g@)@w z?!LXNM&JCs_)_hY;?miW6-k<D;|9~s#2Lmh$~vO=(7!_6qXyrsH#7Xuhm6y(a{eT< zQIAo{-1S8B{v~l<{eb-M>N6?8aifC=1O(yq|Emu=;L~AaEV=i+HjM>JE+3`4v+oh6 zP**pjZR=rvC?fF+T|Zb>nKT_YQjMz!pLp!^-?M=E7`8JNfXq@+)0WIxV7tp}=X#oJ z=c=LuxuItAoa%(Ix4eRFr!u>0p`@a7XTn!?#V!$ZtF|j%@}gs1B-T82SqA3wc>nYD zb)zu~5OrAE`0K>wHnz#Kc)w)YKQ$G1;YPhCqusO7=B`36iqyVg(nHyqbW&Yi(k(|X zbENYp2QP%E8E1f1OZ0?Fw($ZXD7UtlF6RK%VS$7bzVTm0!P%17V3~u_o9zN3i`Be0 zX{KqbLk)1=@1Ew5G}9&b%oN%MZa$P7FIvGCfERshgKf_JJ2!u?`~}PSiu6{BbVWi( z1<oglLrr2;oYmUZv1DU8w0a^(brAQj2GHlre;b?*Cw0^_xq~?`-V=)HuBl~#Je3y} zIZ>(P(K=|<9Ql$x!jUwx+001%Fz$vITfx<~^XltG?lxN6hi>X58eMvZ>Y<U&uo*=u zfJGfdW6-yh?UxZF5J{y%vrJ6dFTnhw)syfthtS_B-msu#b3*Tr<O`CS49vQTE+rRX z2UK{TOT^wM6nvx@?2)FO!#>2i<yckxh<R6=)Oj`;x*(Gv;{cd;=|;Z-(}k;m6jb>$ zRJ5>7MA+(<&L+{<8AgL%&-=#Is<u}i0Ata5rG&kFsze1vd-Xkq9tMlnk^YqPNx`}; zofojr9Zb&4bC8d%OL9BbZt{fUX4NXC(At@V^`FFIYnz}T0IKQ<FOpC*h}zAdo*p~P z0VbCVNKsm?3&jiASLd{_?iS5-WgT0(nq8w!W^fu<)}^C4=r!-lCx|;W=vikj;0i)+ zzR3!BbDse%L<0KfG~-NuQRFbJ^!P)skl_$-mWzTuwO96Lxqbc+5<JNRt-$aM;x^G+ z!jMlK<Km&Q3>VwH)<`2W>qwSn;pO3(h*YB%P0{`vV&cWcOI{XCR5z}98GvqdpCnYL z7<;-Ul65^}5Q$W5yQE7x77(ZiP?;91jPpMCcg=Ta39b&_ig7&w@b&h=f5Fc({1_*4 zdO-p;TpcvL4V<|xm6n*kFiu6wDymtj=Xp9I{6o#<cwZHYLMuY7JtCyc+Hi<T4<Rvp z>zEEx4H@ifm7n_`IA3MvrL3q;E1vSmo(jqzWS&SuOVo)&$@y;|RWg194r$IEr46*f zsY2jc#?bevry7w{Gd^pFa=WPBm36H@7@-EEYW&c|QAz2oEtvFoOdvXRr2;M}RG-X0 zJuSiq*2Ix?SHj;uq#X$U_|3ClA+;vh#Mfv@$c4#ZT%>D$Q0f0F=36p>35=by?{lX) z=MCwmM_%KCwrGTW1b@s22vHx!p2Af1CUio2Y%HO4@|DHv)`#@2=<30eEDjs1Ut<!@ z1hwCjOxHQ#Q5lLc^`C1X-~_BK3<0|;jAR?#&$n3a_X2UsJTEoVx!1#j_TLuJ#NuW( ziw_&UKw}|S2^j9Qzf`NQGl5fp6?;YvAZs$B^m{g)^!4>6S0@+(;8Q@rj#(I`L*u+C zF`|4`2L>?kcitp`mj!ByD<W~d=!DkS=H<oh!?k*+!mou{`v@;#aJ%)hY<#eW4tLpc zyg9AlJ6XKV+`-yU{Bc=SKm%T7KA^+C=A!NducyfZDs+K!@?Esp1Df>WgX&Up`@o5% zqm7?U_3|eMjr<A$XI|UErHz_Ro$}c=WRdH0h8Ui3Sq^OL_bS^kcGjCV_jF$a*)Cm3 zl5}pozJxXSSFCZTp0$ptd*VTisIFfG6ImX1G=?Z=uUQzuwkjTY7ERas0pr9^d6s@y zp?a3PpByOHebZAB7T?bye2M#}e=^?A8t?BhXSVr$-X<9V-Wd~}3xbXOn7?mCWN<6g zlbgq^rdpujj7hu!PEQ=K_l;4kJBF*)Tl+MtxDn<%ak7|ZkMu1zF(PxV1~rV|>;VO= zKcV6VWM#I!>4&FMG9V81RS*>7y*Cmp>49`ouq+<^j-o)`C{aPR+7x9IZeQb_O8$>_ zsXWt)as_+<N=r&DS>?mYcA#QXZ`Jm4_b8BAwHNBtVIvqn>7i;8CO4eJh^Dy-Nnppr zg0)8bezC`B$S_z(A!;>^lK=@=xJ64#ep<U{kVPQJbmn`nu=x)u0oW?!FUAUXoDCNo zbTd9+Xhgv0(&a>LuXi)p9as7(7iM!wKj2gSh9C;yD_`r_kU&U9MmnR^{!6%+yq0BC zUFJv@NfzkTSWlMw9^P2%F5Gn>xQbcb;<<4b;^D*J7Tj|BB$aF1BUS_cx;a5S35U~k ziS(BZoKgW(I}pMIY!jCs*OCl|8mMa<1PbvtY#Hd35ww6*dZ0xqfNBv2)wL9}O$f9r zK9e7i?qbj?i~91fge&CKv;kQ*CXXiSlf-~ghWeK?yJfQ8FYX&%Uv6s%F(|B>;7T8y ziLro<E-*CxU#<KK!2Dp8`x&H=mcXcQpUeM>AwJajmUe1<>3pjCK^ZsK1ku!RSZU*k zGn>MGCk^-sJZT!PB$yG|x-BmgIb>{4gafkyrlG(^<g1-NpbH%FHX}pDA;U_Rm8L&v zvGWL04jDjq3O^_kz<gRr_Kvj>g4+qX!NZB(N<v`66euv87qK4Z>6@iX);ATEz#Pm@ zBG(!)7SrOFd<KlP7g_X(kr^_q>p>)(lHY?<U!3XS!v!)umNu!<tsguW(nppi#^b61 z{g9enLj71VVo$*wI<-$e;Uh|6J=8=Optvg(hLa(z4>nzqv14@Ltk&`woo8*3RXZDM zzk?O%Uq#$4SW!o<FLwNB*~>UZ8pG#v7Dx-I@PMZK5h<fi@=5c|dJ;RoU%mthnV%1M zUFfom0CIRx&=r4$|3wd;A^t%$LLu7$7+wKeUG(QUf_2_|5t?k!F(m{0e;*Xcef^cV z?FqIQn0w6f!3L;|MpM5DDR20ZGW$Hc8N*}`yjM-1JmPEPG46re<XsvxqsT=vteR=2 z(H)SciodE8(4=FX*T64Uj>c=!>g@R*tf<))2FMP*HhKv9Wpi4k?3lszn(v(fP=I7h z!o0@@tjLtGmLP=!>;n01n?d6<ejrAGIw_F*(|A3PLo<PfMh)U|w~Cr0Qjqf{h=*92 z6synObY^`KBm8YY$tPujQ17VKKNu==Am36PZcA6XDvj!7F+z5_EJUkivxPawR{pWl z-ddbjAv@Fbr{;)fPfNh^45&8%X9$d>Q<fl8ehe=?(~<kDz5Mjv2^3g}J{EL9r{{e} z5%~bHv&nCekOZhSX5AxNw1SbT$0OiAriHcs<V;Xc-78@WT`KQ8dKTpEI+}?|a0x}I zxTMBFki<a}2QDXt2~l=hB&G!uSBYvX9?VXW5}EU4X?=8%W=$Za2IhPK-Z#&DCJa)~ zv|xNP><ecoWY+M>oaN|Cf42VuU=5sCGDDL|RI&fHJxn6|e7}sljTZMM6kIuVciuo* zgPAc?pd6~D&5qCANDraljMEPTB0hS5eOhk6RKcY$QEv|w#mh2VVU_n7ua6nt-xfu1 zG;r8Qamb~@vp(CB7u*j(8^~pQBo)sTP{D~`T`wmOF)v1V3M|7f$cqVh86+fi>OZr` z`)xArVzfIj+rysn`w1A88V<64L!pE*B0(1t-Nq{#YoN_hL6|gKgR)Ubd(h~l@!QMe z>FKfYSM68(%X{O>%$N655H+UgyWuC%7Vs_boFJ|EFL`pRu__vXMY<vS>7$cBh~(*g zb^)sT1Be=XTNC$)FsbYSZj$k^MDpoas2)Ff!4A4WTWdZsN;ZKTlm!*Ig@Q+?8D{n9 z5wV+mi|g-OLseQ90c+kytv<bFekJA%6lEtwkCNQ&qnvW<f?4AjBU=Pn`V8y*16J4{ zXd$D4i=c<djA1a~X{(YTD1H*MYPRo7WHQSRLiMZ|bI3=$CAS%g;pjJztZd#blc(Yl zo8k}SU5V0cgUO#6Js4~XY2`ucI;%5#`%jH=GZgs~QtU<>WuK>9qW!|3iUZ{APWZKh zR9ZUVL_L#}@)fRm)Xaq1g_`rn`SQ085I*ij!Ba^jt!!n$FSt%kv?a#p#i%nQU6?Qt zl$)03RctAwS%f&TGnKvGy|#E-VTr1!TuS3^I|cD({aF3<Tk3}*-$7E=*bZcui<<Tz za}N;nLFEpaPuIoSLLN!G8`Q4CwX)5KLJJwX{^(gA?th6f_dR65i6&la6PC6Gnyy1P z0=48i@m*B_VgIbkZ5~*uRwKC=tfETM=q;3?8_?B@k|xqL{PT$dUIKxVY%E@6lt%Z{ z2o55tL199hdi&_n1m9rHy5mXO4SFRsuV^ohbq|iEA2?gwaGEeT5tQDj`nDhCf<?@i zoZa!96FYv#k1*ob0Cqd`LoHN`=J!Ri8JzUx2M!c~${~c6!0}_ZdB(=0vcP2LZ;W*j z{;wv=31U6?t}+o0mX=3nt@^Xen&|SmTrR_))1_OYNTX|)Zo<{UyTS(P;qocb#;(TY z6Ys$j^Ge+mE=`p!THP#%zFA$zNlGl^iyINj?$f0J?wfnDuCoTwmh$S^>~$lV8sO>> zbNW+&s+}wV6F$sS>zvFtWkstqR9QxDDEt%>+0?~dx^knTY<>w&&PVC{attA?;;4jv zUOU8#j5N;L5dMOuFa4C}YYwK+DH(P=L&i$5U@4aCF2dlId0(8|d^H4;#oNY`_Hw?X zRBzwX#shW1kZwpC<BW-06S2FEfVM&uFNP2hE@*tR(snD1EW||u63vePN1r!E)fdqR zM$mTqXj*`R%}sDCr4e``Zbxv4UJ&nK!H|c;fS{{^_ty4S$=2^%f(r*nM$~J)JMHpK zGjMZnR6fi76LN<C0^bw*_9l=}Jj>AeW-vC)lv(3iYMVu?gk}ba`GV$99-pn58@UKT zu9T3UD+Rz_K%M|UXgKxuX6n#_;KC{5d`1wq(V7s2T&46o#S^>aHbX;L-dFRW+)X>5 z#?H)vBtl|ti-|IXgYthHbR?cwOnVn+T7tpj+rVWd?2EHdejygEUmyS5haJd**-!uC z+b~5#cN7uaqQ&@yHANM4LWm~FCD#P7ZtZl0BCu3JfJl}97~I4gkXBDQ(aq)WR_5_$ z&PhhYuE0Z;B{qnrGh80m%cr->`yzr`NVMQ%nNCGvGoW@VCu%Rtn=)0Z%TrC@#ebz* z%7>Eav)t(GiwDA!MwH~*W~-pQ{<9ijx}H!jVtVbtKhVLe?SXA*$lmr-qP+nnl!!GW zjeFrqbsGK8#8$DjEWRL_Ct9Om^x77sAFxA;H>}Ah>8CFXMl_RFv_Yq>G>oFV<X=Gx zGnV<>=-f#HH|Af+qm`BYvz3!qp2apzh<5THhKpd+S)L*Lfsfb_v#z`DPL9eSt(%GO z+yvPQB|rRzLRKb7r$pY6Uq}F;=PI|UmfBcJ9Txgd7M#i<vYnXQ`=RrlKwvHc)=?y> zn1nGj?dpW1ZCuu_YvHchbYge^m?fk+RxNX&$s^Bjzm6Asir@BBP1k$Yh7p~A=0by+ zhLd4kSytSSc&1^IvZ>Hd0}agFFWzAqp${Q;XA|*95J63Bn<gurU{?Spv0J&2@-TfV zoy+BIQ>STnVvfh$(1=AU+b;h^c1!%fj1jhhAJ3+BUuFHQ%4#+}Y8BH0BR4Q$nf&6U zU*chAB{oXJ57#!K%6SS*H6;zNCM=R-SFaDtTWGGS3n8%n6}Q^C=07<7)%e9e!U#bo zfFQ1nA!R|^RtE%J`cMR5*cZ95PeX7H6<Jw=u|xQ)6g!ahGH3e(eZ@Kwx-rR&Sif<< zkgU!MahL@qP@Y-r`D2pN419DmH-R?yv?a3Pjz^S(SgLh|rRz6uC4M3F<vqJZ_Ls?V z*=(|=e?Ut{>*<w~Q(})gyPm|kXGN7F3tbulh|lPQxrM^q;@>ggugP%3=*bCxjeq!F zXUOsk|1s2+4A$;R$NI!7CNn;#8Qo^~Mw*DsrO!)D*6x=6imw~~!*%do=UA$=Vw5W# zUwtk)?regLcMF7YJEJY4(5;`xKVlst6d@0@5G=tbM!pe3#M)jc{33XCV~;9a{J@*w z&C%n(DO7eiV!%*<gt+SOKuSy9h)G(-Q~21syvr*Jtb1ausd{_a4(ll;fx?x*%!YU- z7`n9Jd+uZMRC;oXah~UA1H|yODyN%(E(C#tR>r8AE24P!h@NQmE{>KNIT64Bx?=L( zzO?umf?JgSyb_M~`Q0pwCg+Q5<WA11{yRQa;Z<U0(_dA9W3SbR{v+Iuhji?%qpE4T zp)l%kSLl&rd3=lOhL6}+c8#IqoH_Ow0-vsx4`t$49&fRO_;Kd;8z-izRKY#t=+8#} zt`m7QL9WRo5$kcQdTT=0<Kff<Zuxo@8qMM<U5tXmHRmt_TfCAZRnPit+Vv2(>gpkO z@@CbcB+3eq<WquTbUz^#ZK@I|5jBYPHR^C0qmll}yoIMDyEVu9<sVBL1x<)A^X4=H zbzk%r4muM~j)v-4Peh2Jr{apx?u?XozqxDb70_b{j1h*fjfokpm4-@0FDc98rfTbg z`oxbuS+P$Qb5aud^^`fQ5a)5->=o<((O_LOTr&)CE+=0b_gu&6)!{63R2pVVXOHwV zcA)P6?lo$)PV2eq$omq7*RLz7YwY~yNPA(St*&~N#0t1LX62{4-Ma1!Q>I*NcPJu! ziotpjCiP!sA0W!v0Lg8eI$l=LbU~ECu_eRRGiw!KvqZd@8sQ6k>Ri>o;XiJI;AJY+ zdgBLZ%(4GN4mLFe0>d4>I{IS)2>}dZ8}P9wnIG1)(bBd-)LUQYJZT}tpF!Z_H2Wky z=~s3W*4m+r)qwab#J3~Zu&rQnVfgtMfztHoVn%cfCxr<Z*=>OJq?%yefgLU!H!%8x zDDIdJhy|c2LxdR?#gL~ch)^|b0h5GJU5^Ryqh&gmp(NqkQu-T8nB>B`;(x>Z?+l2| zAA&2*{&L6fL(U%CpRVepVr&xed5Fiqhgm`zCqUc>Qb0A(P(n>>Hd(0HPSvjeWN%*6 zrFsINbdRf|@_VGS&7O>8Xg$ZL4-|rU<n7DAuBbTWx<1yI*Fw!9Q+q;L(4qA#i^v~9 z!*>|8iidd2ENSIz{Z9&xKDnta4H22E(U!>I!^RTatsh5^R<LLLrlQr2LiG1%2LF<f zX}<jC3f7x*d-#@^$*;`T997~=lTCe-c}~`r7*yq$A?`#@@-S68`d`&qZCwzW=bC32 z9rK53x}4Jr**RIZLM~0RaGP0|Pn{0{Fq~W^RX3H1jsAKFLUSsJ4Tp83(Ik)QE~y7_ zuF`{d=5TvT>~>X+%JMo@%{M}OVBe1DNjXqK^HU>u^JaQj8D*#58mi6nE7ISjHg6sE zGuCZ;XbF5*#$&&BH?RA2^75nSSeg@geC+fpX4QA9Xv*PkJooEbbY2+^=a?Y@G}yua z;?rGB(6?jbP4HfLy2o$HJO#YY0tIf$88J0~i7RjID`9}~e<~m^Yl2w)nvEJH?0Mho z4D~|g!%GZTUflwkD<UlFX(OMkz@T`h%eAjMPsEF?&6KuzUmpe_v(T3wKW2JZlzNUr z59Eh{tcX>u>*cE!ff!7+?~7UhaF(EdXIZZB@=$rZ-qGweY8CHcc+^fIf3KR4%XVHY z9eEr`6*iaoo3>_B)^CL>Py`9*)*oQrt_|JGeJT8&(LlJE^rcB%Ir@yldgFgkGa;Nh zAx5k3#^{atd3v^wc{m~LRh#7c(R0qnxn@5vUVc62O?X%)A2kSJ?_4wh<jp+AI+Cw? z?aM7Q*6bzsS^ZrcNL67irQZUS8_p{5t5^}?gnTDBixJjg_^UTmVz;w5UQ1!~-<T;Y zYk9ZH_DH}G7u@c5f6-r;BX($?K>j~bBsUOA;fhyzMs_-8o;YZ}VN5T@i^LY^5yPjF zmc@7q+(v4#gQgUPV|hjZ-BG||*p7+q^{h`K$X(3zcv1Pb>AmX{cw;c*+afVZ-6qCF zM)O}{yGW(I?>EULu#4-|*1eeN)URZP&|ATeG)`IE&{TUV8-WOYy)(Z)tR`;4{0`ba zQACmx&`V^Ao5^ziYL_5e*J{tU4DR_qe-nc?VJOG*B`2`3dE(6hQr34&nW&Df8lim# zYngyuDooBs(Vp<~o4@&4wuf;9kZtfmUp%#6t`4D?ip5veS-Qss*D{l`d{lM=M^lB2 zD-1kJj(0_#cN}`v&Jbzc1U)^lQS^o5+iLzH;keFvEzm%9r9%T;KX8Zv^lB(B_(foL zb{gVH4I}%ge|9Z^{$xjugcRistB@<EuY}s&eOC0kaQf6>?8Et9wJMoqY<xTn;+?QT z%plGs%9|uTDprBM*kU%<d?G!GwmDc|l5;h}fe~l^bve~B*UOzi69(@g6codt%Z&a( z6Ys(&3eNGs?YIF~cU)SEeDFINh7EZvq0&%UCM+@$6E+8clmqZ6MB!nC`a(S7(*!rX zpcbQZuBx|3j_1i-Ec3nO%I~8My*;<`H{QxDT&B*$&!iJj+8e!b!oR*z?UGhHtp(Xt zb5B4lr^`jeg_TjSBkSTPEibybdP81`2WH6$lkEXW-ky}7+^Im@f}Z#9s(e5GVN(zv zdJbx8j-4_<1fosK)EF8^QT@?*h`rk^H{m}GZ>=4<)7c8U-E>}-G%5wT*Q9*q_Xi$* zs9kC2?S8Dvl>G@kdW<DA?h_8gyKz+dCAx<+{v`5>L3DzQvYVVBG}*)K@oAbmc0F_7 zr?<6SgKTow(%WI#8_MhHZ5G+vEG^y=7C-dC^D8sJrp&fB&*|_9mvUe1UQVHeNU2W^ zZ(?7!xI1=vg+d2@ozQ*{nq}3ew3C3)td(4wR9+-R)-@5v!>p@g3FnP|o$-8X&T3+P z7c*<hsXJOCAA#l1MU{o)I1O@qf?Kn=4;{Hg!dQSxnrlfr0)cb`1No?M{1}L}n3elW z<O&7w83P*`h7%k6)Weo&*;tSd8&*kYW782WSV|>XUCRw-M8rx%!E%e%NY8V)S7Gdo zUWIp$dh6jg$rvL(dzeina%e~6@(ic%o)Kw3{pmSkQ6Cv2`3uyh<oZ|X_`pp;lmh3+ zY7Bse&e&NW*j+S8U#G^tY#N`Og|m|n8M716WqDbgN{h-zazIu*8DrWjN_;|L@wv~4 zxnuBqC-@ukN|VzTR;^kJsCGkSM`w9!SC%2oo_gSVn$Z3h3MGK*!>FWkZaVC_K?EBP z<p%jPp4C<SOxE=Y?t;Oa3`zZbvgFiJF?wl_Ct-qUHhH#6a@uW{pHu7p>9d@`8%Q0n zOLlq|Fg!$f0d1it<UPin<4L(Kx*z572a)+D<>L7Qbm&$L$F^;^tjzv)@wu%T7mf$* z#*NB}s~^nnCxNY4ydk3nj+|J%ejBxxW_8dd?kp0G-P*G6F03YfuDjJYn5J$I5%5ye z7}V)CP1wfL>*Vn<^!PTtcHxoZp4JF(q9MOU=Y!c=VZAkh?6(b4#vcL~?DqY<N-~+! zwmi<f2wS3rmgMW|!z5^b(iS?->N#wN4Nw*QOhxn_g6}*xNgb(+7!s^Z=|bf@q*k)Y zCz|mCXcG%LtzE<K3<$#2KvJlN0uo_V)s*$KPY;`T_G+R)@^p6XD-7t|7s06Wmo#@n zf=K9?w}3r9bB5=?|Br!@fxD8-5Do~aJcS>a8CWcpg&&v_z2)Fg-=46`#@U=J>l*tv zVTZ=UVPmR2KQMvxjt7v1hrrj#r?}TwY}7rV=k@V1vdbJEwaH;Pvg@e9Al^f7W+QBw z_Ac;~xz2o0<M3d1>83fqL2!<Zcl+oF-ljt15PwToHFb#}m_^1RBXX-7<KJxdMGU#_ z+Jb*vfIjo+e)!Jc8Abu$i2S-v_=PD=L(y-M2#p~oF6RV?^$v5~xKeSS$;=Cv&bH{% z(6I^nuZy^yi&SL+U;<$HR7U||ENR3_xjb<(^u@Zb7W5S%37G)*U%Ok7-6*0e7@#7& zu1&324Yk%i44oHx4|p-oyUr%a-W>$i>%pPhFx!m{_;2<=vPT=U>oW?ea{|D4rWgt- zpPA+xC8}o@Z(<*0(svm<O!L>+<$Or<HG;vO(BzpI-O)`t16SU{<0*|D39r9NZ=GfW zI(76{OsAz*+|TFH%OL{4KF?4qaIW<CtTX)Hl0ab~`DM72AD+P!T!#=Ia8i{8fr%Ll z8Z!Fqy{3s!>RD%NXOkwL3&2ehsziLHVKAK;NawqGxVih&Ah(rQcT)$GcPdiz1%ZW) z&@AgE?g-o%`m+oh(UZ~3P$_oUs}0G)S^@_-#TIefwj`OEn)#);fHCMYL%L4II!RM0 zl=Qhp&^J)D)r;4p`qNvnx&6fb?Ql6Vh#5|hERhwCNkz_y(0oem8ZxS~v{OZefGGhv zQ(sILfYUb&#TS7~o%5ZrPin-zp5~tG!JcA;z78h5@ei$!6_>9I44OcPX<yG8p0jBU zUShH?|2+0L)!y*UhSG$~b9Z?gE{x#6k!ti->-y~s(#J_`u6_U>L|8AV9DYfS(qL0# zcZW4hY14z(bN`jaXE91C4}8X(z)Qf*s%nJp<!=tA6bJ6erjY0!#l~7BC^f=wSW)Fb zeEOVh7%C^GdlNmadR&cG{AHP;L(cTX-0OeXm1)&N+``&PbSVxfELqMJ;r>IqISe^= zv<OXt6!~TB)Y)QA)i)?*df}p^lpC3Tll?}KuA7wO8ca`=g9fV!WNQbeHL?I{bt^2? zML1+{%giloX2`h3x}@p|0ZZ_4Rdzuyxi=-O_*9&m;$o;RNFGi!8N(TLHTh5dY~Ew$ zf}?l4WKfHo4AU?4-zbk@XcOQt`hD&-l|i@~M4lUwZnFu(z{5tRTM{rCv!%KIf|gOU zHUz1ET25o;WX~%ilVMFC#2En(TKdlOsk7)^9C;^4<*I|DtPK~14kicFCJu$;HZw!s zH(K?pWz&eG75~&ClnlIYR<W>Hju2qYbJHYLCTaaTGI%1&sn3@1q73K47yWg;BrOz$ zVeK<x%pBSYJoS=|AhRKoevPahrKd*|v6uT`)(Wf74;OHsb_P@Y{S*LT!d>w5oGW`= zH3j2TpyF}9V|<{lGpZY>^@|e}Yuq1q;8{S5b8(Dup4TnjT-vLqIVgSz0$tC(2duQV z9`W1NXcae-uoQN}7o?6p97fTk0in$u3qBOQN>`2ve28aI%<+u4XhuPh^}h+T<r7q) zf!yWqM&9hiC651#9RCKe3e2_)%@)Bzhz%or4O;p_<Nr%;z}<c*Y`&=$pV0f;4>QQH zp0h`{tD=N3aThLcb@x}UpzAO+WTa$7*2B=;=I4N~$mb+56!{A;uE6o^Q~2+3yQUeX z==jlLt-{Cwd>2vETI00anYA45{c#UbZ9W~X(6!(BbW%f_np^-NX)h)os0^B0&f;LI zY5b<3sK3BVX7pg7WSccX4uSxh$pd>?TkXjT1>0Y!SltYmilF-ZaXf(0tp>bd+_~&P z{Omkno{)dM{Y@=Z!<hVnPmR9XJZ_adB%qBY+(k7JX_a9Hxn$fm8hs&~o8i2&Pq6Yg z_L{*j|2(n&*Ch-9H=IgmTupk5?ihi!w;JOgd!``cILVpYF<UQqmJzr=^$b=09Mwoj zCg<;2U7*33t*62aW}aew9r_iG+<8yFlXJr4%vI&)rqdi~rgEk}efz?@8O`*$D!hy6 zD)YYiHt-Q}PXl*pXYV9X(>v(tp?|wo1B(yRY_ELd<L;RNZk*lGO70lyK1B!2Y!d4t z1ZLX87ur)xs92Vsjl3fX;~Gy+L6Zdi$rRw@@pVkH941CA!Tgyl$Pj1`&t9vug9?5+ z=tOj^#n{WvP~3N`F)?BBDg+3@<Fwu0tk|Fip~g<<F92lNqNUL>@|)UgdfW*0Blb>7 z!B?Av@RD%=f{@Dxvb2bVZKLKPkY@OMc}Gt|B_ZhooR3d0>+3$G)h}~Vj8P!C{<?0X zBAgDKmwSjBTJ>2&5OQ5%6?J!?BEx?fz>IJC;SDgpM8L?6@mxLOo)t8xJ2sT{+pU}B zp+8A#21-U{vInh{XiYGh6WNBzYU&FJN*ag;T@&|!2w;EIMn^<{M$B_~U&p*}{TPfw zup+!6SG^K)rzK2t`VH;Sl)Q~XlD?b=+pq|mzg=Ut!~4+2`aOA}`Dn(^(6k^)0e<uN zn0-rY(R>`td3}+EZ*x{`8{GcMdnFuCN*im@L|EY30V{CRh)ZG5jCN1@u;}1fPM+A{ zgR!6hoe&{bcO~lz0wseX)>h{@j>98eZ+=6x&vVn3Df>Rha{I`buBC{9ct-r8O`;nU z0xK$XH00)~$+7l=WlNVry2$uSJi@EwJ%1b+nu=#=aRy4n^N(0)CMc#<M2MlB7%OuT zuM`Iiud#X$3H+@q?8<{Ip{}9Qco<`W2(wwh2jOrc)fcxuo1OxLJKDH_4g}pxWQ5eX zBKha=gIk{7Ie02_mH9nwI$Er@sI0;ACcnVoGr|Z|i;}*7Vjh9>ero?Yvg;`kg9}7u zTzF&#!7@7g-b2}>SmxOoTfYFO685?t9o)aBQrZR!wG*hAXf~PP52YoyB4-b>4^a%j z+iyvD5o2}5MJYP<x;;18>W#{v4>V4+@8M)mtU<*)5sYD2>3K|+!QVjE60<thiFsXY z-$wV_qg|AXTU3$ckO(iVws<GI@gN$pu>-8ZjeN2~vk};)i0vs0-$TQ*cvC<#^0zfr zex8Zl<j-$`r^3xNR5522>HXO4q4PiB&&LRIi-m0(DClN3fuy-jq@=Wm?o#uZhFLhC zGQyK>qmq3ts8$R<p0~%Ep>~DF!FA}r!l|te;#LLq890*I>c!R<e=4+@0A!-ufho1Q z8f3)MU+qWo6(;48#2!d}3aEFS&K6vgEU`asi?O1Kc!>nbDd2!xa6&bAGKnkz);0kq zd$P<@WlSn7DHb678algmI!3)6|KsBM8fTXMkNF#a4;`CSmJ)T+<0q(lIwWNqmS=j} z8K;05JEJ;zi4cnD0ulI130kAk<nOtCG*`450cs16**CQ_vw|oCzJH{L^M@0sR*FYl z(ZRu%F1g$7z&R>=*~)pp#~rN!0c^Yp?yKL$<HLu|sKy7$*?NLlqLg4ee_jlNzec8{ zL-`HLG1T%+0?sc2RDCvx&}{q93}7T~@THo7%8X{E^tIc2)!_Fh-ZH#F{vZ*=NJEEw z{Z^k|wG<%(Hje{mJPk@Nu^xxmt~7*dtpbS7Z*R{*uZ=a3gAuN3814Z99Q$F6UFkHf zCf#gcxbUSga?I#XmasEXt!GHgN6-ABG>F%MfV<Y}lS_YjP8I%&TOmMgSK9?~%cfsF zb+!vi{%5<In1@epk!VT~gk>VNxRGfUcOp5)sEA6-;*!pl+Djs?*<`6Fu9Wp5iPwr| zLTvwb{L;6IF6=S*o0QIkSLfpS3dugYdA1-OcSs!Q+c-+79+v@x)}Bycrq#A6?KP!( zd%QeMlu|zZ*5JRTfvpkJz*&(0i3m|A5*zM^1Oh_EP6g%%#!ppL{xRF?I2^Q~{ExpD z42>4JVb-EhKaW!08$-S^%Cz-_7z#|H0N>qAy12}AtKj={3Qjsc$*ffZN%nA)E7c(^ zCA>#9gMG`NapTjvv;*|Qd&`9#iemcMp$mK1@adr*lBe~)(K2+uLzVkIZ||%f`RVtv z{ZXEa`zT_;7vEFcb3I_C!N#kRW!`%Y^QhADLIIt>w#S*R0IS&+qO@S&Ze=2p^G;E@ zg^0#9nf?^SNqlK+KOM24s$(#)wfUfj<tGvZV)~H_NR^%<bmjS(@Y?0+=IH$VZO`cU zJrP@N`|+Ox!Mqnru8M>iQUXQ`pZrPf%a_$tm8M!1w|~M--qHXp{1&dUeCPe`q{V_u ziLF@g=7BM&;T8rl@Ufoa<|Z;gl39y(bwwB=sE_B__GP^4d$yehoPcz~ET;<7+7*x6 zt|jfkOx|y|YQt>fa0TH-9Y@)Ph>Y~Oh<r`t>k~{OlEySJkLJs-V{3SXYus_2X#`!4 zOYs|=DfYW4X?6gAG$>SXB9{)<d(E${AE0Ow`XK6izqRj7WPzip^G=XfF$y3WrH5Eg zUwF)d9flMGZ`xBYRYQg+!aTM9(Z?OKbX`+Ede2!IKf<1hPn1VFuKq$VVMb$_cP+xG z1rEEgb$lM7R_T%hn=PZd|1YY>MD#y+2MA<`?ue2d3N!#2{PuQ?{2-1L{qnz{wm6Lk zX4EckCnFjV_B9#-&ZR~gp%A5Yg09U<`^$yv`&IVz=O6R&o%!D?2TlxF=aD6X?Ycff z;@jM@ow$YVE$7i6y?V!K1Vw%nXN|Vh30uDRMxA0z0E=-PQf&i9bf+rwl+%>_2SFrR zR0wsx<PsnwBb(z3E0jkhGSB`Rk{rVE4d^0xx5ArR&plNWftuOO<=zK8oQB?pM^!$G zd$_bH&bB%e#(Q$DQfX$3sKo63s<7$xWN=j+QnF@#QgP%B(XvxglNQ;p*$4^C8?+hp z^chzEm-6j9y0UD{sb0`G05h3^|97x$<o!gNSTX=>L{PVO^5npG@~GyH20t=|@^}vV zNMYbj_b(GjS$Scp-x)#yq~Hs>N02f*<)!Z;qn=@~7bCdHuU!HyXsV<>-fE4}hHD~B z1u>N}P)7MqMI>6fg8Ma&+T8L?fv~x0=+UX~QmiS!F%SxjjJnHZ+M*tx%%ZR?4$Kp@ zDmOs8h;4ijZM<|b0A`c{M^vF-V2Ww18028&xgmU8vJ@!61GQ6lRs^tcUFSg5B)(kl z5xRQ4a+=`*;U{DXp2LMP7YP55dsb5}&fxHn@)>F!X%$8#Z?sF&Pstx3OjI0DQYo`b zOFB7!dA$@uJ@g0a&XXm%=!KCqA54=dNfRKKAml^nXbbY=#bLCLC5sjNx9YqM*do2o zZQ$fi2+v>*AukfL1gSVHl86#!B&t8>>zHC*DftD1qP$pxyWu_96Ra?DQ~QFi!r!dY zkVl+!>W%8Mn(oX~Em2Gaa@a9F&L=khuS7(~!y!Gi6-%4i5`mBaHKg?r+DGW_=<0{5 z8~fcUOLE7QkSH7Z>s-xhld+FGzq)ZMLR#l(#VYM$021e7a8;&VHHv^jYfeK&&dOw< z!CB)?QvuqT<N_Z=s*&3Xg6ywro#f0D8*-#W@+tefI9_csNJtc!nqH;Z#R&O<n@)?W zNJ*WVTsstF>fe;3%StYL;so)9ZfHRAG`I=uO~cIp<Laz}@(P-6%?ku~2o52*ySux) zySqDVG`PFF2AAOOZoyrGyL(Q)|EoH6&OcXEHMMJ3%}r0Q?tYdTVx+)Vw=MMV2x;2B zA}#R|a6ja=C6nTzZp_&kLe_izi0iQp(-&iG`#NibkoeNM=(65kp@=SO7C1C{;N|nI zynSz>Nf>G8YA?Z-MrNO9Jw~aEeup+8rW-!TN~}vA8-D{Qlf1kLTcEvu_4HB`Vl9=K zVW$Ta6r7R^EB5<H=Yv+8*>3h6O0M`WO?*%e!Ar!Auo}`Q-6%=MyHL3&56>G#VvP7Y z2xOd^8{Cki*3)m+cewJ5A_#!!!xOgBOa;;P(K&m!lj6R?CbxS}r9uBxa*YN0fVcgH z$vpSs$mjWkzA9r5Npl4IgG{G)tkmV!?m++@$qXLTpLzX^;i*N2Jd??;^h!coR~b{@ zElSpAP20G+Xgm6BsfwN{#H<_9;C2CSJ<~>L1=~_sx7AdXWz_uDi3}GZ&zYyX{cPk1 zpNAd`qO0ekqs;H18zw@cDcSIS&F7@v60Z44xEob-I))Q`R(Dimc|C>0zI--9OKw1x zq(X}mWioV5Zrct5P5Lp{?;FIwPyVS6k8Ws08l7Ge=tMExs`|gDXJ$VS?a6aDjOKA- zp*;j{@PBnrJIR`%-?pOhjNBJ>jd&s@-KCu@KjyL=F{e1kJ}qtj;LWN|Y{XyKWHPL` zQBvqY7+5)S<mS6@OK7(Yo4;L?b_L4OH$1w8EEdIYrwMNS+rejknDfM?Z=Qc!IeWOf zDTF*H)rueAVbNH@y8WvGuYVT$p5u{p9+ZvzIe+;@w(AV-NX;=gPtFhqrdv-=#oY5q zAi|P18^?xsgiNLeHF5dzwA&C)=+RWnb?&c+If_i6=2F=znM@F2i>1^oF@?EL;WqPU z4j)KH)kY|*)$jljm6RflykR&xB5L8NqL^mO_(oX`)*bMBxcQ{O*TeKjPoFuaxT|nM zo&J;LfI00v$25vRGPcEML16I!{Qt2(s=$@x@ZV4pJ#t!p`@f;2|IjtkP_#fu|DyhX zsT!Opii1%2g)`zQX;sKW?M8x2AQ6<=XjfD81j(4<b5F6qZ%7qUWGePqu&}lXNB-R| z^;On(_{rWaN!Bft(KUk0HJHQ1qmQ=?O6->FJRX%1H9ar1)jCaB%~d!8`Qyz-&7=Au zX(PB4GV3Z9!d7G~O5;ER4WP7}u0|au9+7BPf{$I9ZJVIIN)vLfrFoF?5BYhUd)DpO zHEevHCld?Zl-lGP-7}_9vE+y$?xf|oKuJ%_q1|CaT#a5+Ps%pZw;IOqFYtdOJk-2q z8(6B&eNG}qHKY1h<}_)_Fd-T6d5tHOhmK*@EO2fF75bzmU|M8O0#+=RI`jdAtEczM ztrmwRs;#*_aId%Z{SU@$Wy}XzYV+nQW~+paSh2NqT3&nqRIY)}MGd?QMwe{U=2z;R ziJ<ts{l1ecN>~kvvlMz>)j7d6lhlh@KO_qoLd792CAtP>O?U&<Bbl^yv!}M)i5F}1 zDyc+LU!>02Jsdh6py_ZNxA@DAE-@$Kl%R&y+3Svxzj?4h3O_aWA3f}irhfa~fAEU~ zRVlmrdtDMCiIc~=%_WMKWjNaQQuBujiWPg<DxZvtVBP?<A<!<)69%gyF10H$mb|Bq zOEH3KvgIBM5}a0IAxR=An0+bZAs$DIhZ9$6*>d=hH_tp87`q85scF$+hh*}#qU91< zJuQN}j-Brc9;s=_+YvdsAz&P?nccvBX8hq($IFNi=}aqlz;)%BiaBBYrN!gAL%sFn z0Q}iRJZ5M?%iUZP38U{_C#i}--d+MqS66wngB1tQQ;3MUmPF2%R*ldJtB^|X^_i9L zDS`(kiF|7nfY0Sib>nX4()5C={_EkxyI(;XuJl+8H^L(|g-gyPXY8cU0`csk;OVe` z(7_oPbt~OK&8)N3jbJLqnFpttL#N-x^<KvLPSF`{jraK68TYHCCM<hx+x9-upsC%7 z=o}tn4a{v^IFtGwe|D(6%7vE6Fp|u{`GmJSJ&!OO5H|O;S$BS5_xBStF^y%RV@3O# z*=%IWhr2ws$5WK${o>EJ_=`IYDW*-4`HX(XePQZ@jqN8v*NfI)$;JaJjIVC*PI968 z(rSdoDk6sjrC$GDcp>g^A0o4j8&>|YE^r1th|BzB-B~`JP!Qy>_l=A>-;A7;Jekgp zRkh_H0Ia*FI45AIZ05^{^({GkZJt+smZa^$l1bAet<U8mI+qXw`ghGWocfF3CjL|f z8CY+}c?U_{@u|MLi+G+Ef|nRyg^^mELZQ27QKr3)TS$DXt*F;gdfsu*T7&CIks5(R z^t#N0HIGdGZIQ)jQw5Pdu4$QwqX>;cPRXuV0JQISxy%=`aOslyu}V9$%dnMn$l_M2 z^A{{^J3{-fFIH?${oikiq<U6Z6RqVE-%p-|n}(;0iC%O#SUD_}ZqZ>ZVGI01w=5;& z>JQRVY74SFe|Cc&$g^=2hvfEJn6_s|4#rLo3;h{BULuCMAFkJ+I`GFnSNYs=Qw3cM zfyzhUiYJPjfLLOFT)w376F8zmi?G?AG^}faOW10Ag*TlnNA~OyDRjiKi^F{|72FOd zIThBt<{{SNLcfGdNRR7JXhgOK>L1Rc{k}zs_HDQnPiupr$?l5V{7DrD8F^kLfj^dX zihg`^`QK%SMIMR-DEWVBknI0MN=!r6|CbAC+5Kly^PiP%UmGPg#IFWFY$!-Irh7z6 zMcdvryKg}OhQ*Cjp_pok&Zi%*n+eIZ+Rob0EGRm}FB=InUDu<ddPOlN(hlqmTa%`q zi@$st)|aH%bnv=N+MQw;F*VQMWXdsZk6pr`ZuDj(tTt&~SsTXMstD4x%R4dt{2BrN zc70KFC^vI1Pu%Qv)+n&Au<<cBwBLbec(A89t%Udh8E9J>LO1)Md#9cYwbL<t4R5!b zj%bi?T`FvXv!ys&$aC20e7m=T12>R?aXEvMu)B($Glwg{W9%on?NG0z_I0rk^+GO9 zY5<KS#ZoD?+V;3=?N_Co)~!bG9*F>!_}6v!7o#3tGhb~*y>>8l*RKzIN%|&Mjiph! z0;fFYQ*)5Y?Q8-x=4rL6r{pPL7_P-zFT6T~^+dwuhb?@8C>NR>_Asgy2rtR}-O*@3 zuh8NYa}^f9x_Q^g@jhrZS{GMH>}Z{f`E{<vEPL4)I-9|~QL7@PdG0F&D<0r8y|>1~ zkvH>kWiyY%D4Xs~^K?wj`Ne&<+UO9bB^tjW2<jB>R5@tMLSML7`uu6a=_iyOExVwy zdp{kYeC@I!tqV3&;ab$%99Wlldk$96;E5i|*DtxtwhwE3Fc4MNh;03YlYwGKqpLpI zyYea=oPm#mNFd41w8ImV6nfx-ZJm30<?JWT_76gGYJ4%hw%;0x22{Jf?LX^Mu`C+{ z{QI=wjrzA}CkbiSvb}t2#3Ih>$~RKQw}gg%84{tapOBn!go%r?abEF!(SVAFE=I2D z{H+#`+ngl#E@BgrTgZWCGJ{vdaZc|2Naw><htP<a>`d3!Y3!AoCsYN<f(w(#e2D|u zs|R>LmYA*FAak?Z#JsW#o+y_S3Jcw1ADZ2BCHgHQUq+N0#(XNfq2_2Qo_*2jGVVFy zzLooCJ<ZfO&zbcNq$SY5(BYlVprEb3wL*h%kVMZ~O>_7iX{3wizP*ca$QP~^v)VcI zm)9!pIF-~Brm9Nu-7O0M>va5}<;*;#PyD!;m>K<aF3%i_+ciBRtXS|p%yafIH>mU! zO*t1yAOEQ7nLT2Jj;5BaC#jh+%+?7<aryLG)N<eCFv2jiZl-eH`j1DY44EPB4kD|- z-}?!4R{;Wi_g{=2vh9z?y#BlPQMs;67}O_8izTf_?rj)0a$Zz`sJ&w?6k)UW#`ET* z^Ic&=t}sIhldAPg4r53c=htfMu6{bX8swx1=rXod8fi53$?BqJo`wF5`#XI~c=QU3 zPxWO6eE9wh-7r3$%k*@uN6mND7vFRu`iG9@4Mn;`MhLx08^>q*O#_%MN<WI<D1L2P zjO*{)$qJ@#$Zi$D8k}QRND7E{?}ij@{3jpf=CdAwoasly%9%)+30KNPg?YhyB#*bA z7AAEJ$$P@@zsc8!Iz}z=4N=~^KSzw`m;=rS`9!6BO<dQDRS|+$Wv)$>p*|+xm8P=u zypAQlKVK+^3eZD0>ga;Ya7N$)a`Jj}&y!8fwX&(S^hex4E=Bz#8=h|w%K>8PzK%hM zp*&$Ked=ULr<b3rYUHoOdYUL<=qPfLx4VFmK|SKsO<q^`a<eicuq(-{pLog1xjqeZ z@g!~|3-iCr{WZPOqE)_B=HBQA3mE9Jb7PUqFJdvk$jfW2O5IaAD((ms8eowt{Nvvy z)e%=3i+P{{z26-S1A~r8OzWumP2v^2@rDBkGO1Vpf%m)MX^Rq|-k<FMt`t02a?G<S z62ygk&KF>BaNLVu>rsgJz6Z(sA8bP(7|wU%#XFxOx70tzmmbq4%wvAV`f&1D$yjNY z+>(dbSWp?<ZenrN6s1<_I1AIZLN(`f9(1KmF?zNDT2qdx(Y<h!{^Sf#i|ksR8q9El zmJ;7kD+-v%8j4zu3A=r~;u3kTLyfPqkuq!IyemsPMmj@po5KjQrprtkSPacf&Bn~S zmb5etaV5IojUkDW2mmkN(b11ICUx8OSvOeKUE{%5Fg{qBOXG@f3m4Dh$C!&78-z*a zk570&daOcOl4`@tR@tqsQ%*w%xhlO~y7C$qtDpT4VQb<8pFBX6j@c@yn6G%euOURp zx|C8SfQ7g@2l-MY8$S{jfukkQLA~mcP|s;G{w|c>E@Q8U*za`O*;69;?4&=l_aM!9 zK6Yue-Z0oCh-XDADjAxE{Ks%RUR+0b0G${h#~2cGZ%7L{98&e?iI{KlH9I!sXi?Fb zf=Oe~1IJR~_vu$W#pqX-+UH9?Kew5<EO}aOglX^Fb>+jj6bu{4tykvIw3`1gUx~^# zNAloD*z?bld_r@<=CN&!oRLyzFL36fSCSVV+E#7c7I?|BYL5)APjs|7B|wWK-lqn# z`FFQMFQxlo!(sgGab9o?$-V3qq(d)7l1ihNPqrcshswzwj!CUMzNaH&{MO=j?(?Ty zi92z=$&aH5-?j5&2d<U{A7N2TZ45W7t-^nKB?{}=oPPE|{O=gN;D$)g0|Eonh5!Sj z_`h`bv<*#gn6z(wgh(y5<{-uYTFoctI$}fr^B@?4{BI8PKgSG~AZ+mevRh=VK{25J zZZ~W|1knH8emH|j|4Vcc5s;ZC`u7V$u>W$A^W8vDX;N+=w*QetN$po*$I!vRJO%%U zCDrop^b0be`)JHC{=y6It^P{B0g0dQzJ!@AKEaUh?uwU`*cF!a$i!<a$2ahZdr(A4 z?bSF`LsX_xqc`iwhszu^*dm4wE~2M9{*{EHK%bBEoQvhlBpWtKSs1n-=L2{J@)Q$Q z&E?tvb6xpxfP(H(`my&u_2uU}4P{&t6xN!>>QV?`@r7JRKzC}+E`t)%y(mjT*Jkor zJ!ty?XDym)eJ5u?k4$g^g2Df)K#@I<dfmCd1F^eNSRfYxIh2m=G@HxrdYO_a+BZ6S zSfn@Zc$uX>PA?3;qRa|Q*Au@7vF4|oivMfSV>rY}5Eqi4p*7fVJ?y_Z0h4xjsMtuq z1Rdf56HgDafj66uUxDF{QLwbdwmSAU(gmty&XVclY|damb454}x$47AS^#VneQcHD z*7@6ru39iZpR&)V1do^;x-NZ5$T|!IqmLF#@0JN?nyhXg+GiM^s+|w-g&XJPmJHE@ z_A+p7R#la`v&jC^n`e(qlXtraTKfAIic1{;_Tspg3sbjUe@%g`#unztzSh9SCk}Op zcp`WK5vgy4@pV440`XY0i<JX!s)dor$e&B6#kTir0?by>09~(l{nl9n{w!)*2A<9% zJYqcTy@6(Vq1W$CiNW58d1yZ04h%g6br^|nXU9+5G;H`(gz}K1pE6G=|9Vuq_bi)% zIOmO>{b)5XGtLBop*oH_*NGpo(-IBPV?t-#C$R|{rwL`2&y^d>!0UcBI1jRM)qK0r z?yn3itd))LMS}c=SLz&e^rNCN2vFn)srNZNKWmDHOp-rKClc#^bynl~r5qj<+sn6R zjvm3|_xcYst1#MjwF#2>L0K2%(Bp9fAARGo<OaqPwL{21N?|#x*kv}s1)SMjCY45q zGIU9JO^+|gYt=PHx4)x4w}WU?l9Lp44Wf+wzF!@uz$=?m<1TI`Kx1t}eJu=NUamQR z6!oq1pvq}3l%dw8=}fROCD8v|YPP4Fg&%=%*d14%!Gm=D;Dfe4bmG9FmVxn0%L@ac z0F!a&fc<ZA534HN&|^g5P0#Cj0=GYZpXIx8>}%-YMPYfup^%oUIF(zyS-!6IgJ-s# zGqE}l`eaX)L?%QXw1r#ng0Lw1i9-y6TXWgzUF%_rTu$v3TYoZKxjbiW@1lHXuKqoo zqL3`hYVO~@8{Mdpir=0?LjT1w`d4W8kqIta!sLiWRb=U%z$@ug#+H%m4#k$G5nv4u z0}f9s58rtWl1iubMrsxM{xISYUoy*~M<T@$R<IQIG0b+8|HJqcAmm_|e@5-MbUdB? zS<!c+e5yAufr2yY*qc_YT9L@Lm6i|=VnIl(>g>>!FZj%>8+J>Z4F`RdZScOqjc$Aq zzFS-c{QX(Fmj!Kc4D1Xf01Sf{nJtI8XS%HeQV*MMIE7op^tzYylN(JjED}%6$-54= z4HRivtZfA7vzl*yiM7uuX-p9yEKqKmR0N0^l$T~30m4E3j|aT%Uv!5A5-_lvBrq_t zv^X~qR$6rg2m^3g7f;-Npdr66MIgsmlD9vzZ!37h*OAvfbJMMFXrrk`{xMn*!UoF- zW~t@$(qkZS$OjRw?5m-pQ6@cv#<=i5tJX@EJn37OpTS}Sdi6$fmu^HiDnpGvZ%#y| z{@7DPmMpo1#G?ChQ&;?h|4+c+>db7LHA`Ng+<O)9MrNOS@lwk>6VUN$vd^kMu64gw zEiWtk`?6Q;dH*q1)WhrdxhczQm1SV|q5Q~lgRzrhfyaeDQ;GEXX|${%r)O^-q@Q=` z@qAf^OGwCcpw~PR<<X$eX4g%V<}l%6k#A3tw%DF%$1%@&HE}ncubvyn_NCoUcHK;i z!>t*h<yfq3D4(dtKYKxn2di@1-dk@-0`@I9j(^dt%SSfs8^Ap*k%_56zy=z(`Sv7> z@&!A%lkObptUg%pgk`Cx{`^_yww#s~qdQgJXOi!$lXFpjbyo_^pW8efT74jqcf7s` zk5468lQ>PkAC|SRUpb<TIao+6V8{>Zzcc`WeF1UWF)NLg{%?{3*%fVeJ4R{X4R-3z z3x5PZ)SAH`7ZrcAN)Nsz_;Z09ZZ@qqFr><DwoHkOcnK?fyBSE>3eS!DE4d(_dU0EL zoH{j4^p=?0H7HTUmq5;#XS_V_X2J7wgkh(`)~qYpB>8mWQTK7^va+Wx+f^FbV73uR z=uT_RY)7WEt8}6PVAXdeUM9M&|EMqdRYF`8b%I$Hyn&c!1l>p7TVHTBksu>jU7ugx zl9DWj#(?ZxUf|_E>}Y_GVf?b+{Vn$s*S^{`-9A=U=PCTmG0kp~&h4$yuUYGB^Et<q zbE^dD&r~eumtU3{_Bq<syPt2k-#LK~gU|cDA!LEvT;5-hUa-Qx7c%QycFU4Gb-wfm zZ~99)G%WIgTiX{C?ryHC7<Dyb-!b<V2iM7xGSc%^nX)b=RxddC`2B?%lNI8BTpT>i z&CUJ5#0g0MG6RQ}E5^jf{fcP?&5XU36c31@{Z(W4s}A`~Lo^^85a9js`Y&aCLSy`L z|ChKnKW}03bLMNyqv}7OX-(wF<LU!#j82T!fq@6Ze=7fB)0x&Q6%&F?ll>tTq`phX zX{Wt5PJeb33#Sn1j^a-#gctYM5#(dk+ON4o&sT8`+bzujh^q!*pj}|EGw2U`XILl~ z6?eVuFCLU&$Joe;${rLlBj1*PvCrDZePqLlSg`!c%wN>uh{$)sj<G0g?`)sYf-I9w z9{MXZiX?$8ys4n57%W<W|F1s+nU9`2i}!!c*0Jve7m02UFC9ffUbGZ`Dalz@Swfj> zW=4SJek+joYw>_d_F=tT|JepocMBC674r@@FKsiA=Cx$H({2sXYXw#SbCuVaI0uQ~ zvBi@&Wr6zi+uU)DTU+3ggw-q3l!U6UOH7a_!Ea0c3w~&1g}@bgBc8mK$zxzJpJRi_ zSaW&S7R52I7-s%0Y2LwK%S!I`)DDElmr0UU*HgEJfQ9pYHn(F)u$fGG^EsbFY<rsm zp}r+8H5+adA0x`8oAO>DU$7H$>R;8-Kwn{nHPBDELx4^O28~4G6Ah6WMsAgHtUZK; z{SbBU-EqrAmWBIefSgdld)!62k=O2tajfW1={Yyrkf*YlWz_-2bq`f-w;CFj>FB|q zZU<)a94$@7noJ--IK|RMZOI{!=mx%o_p*A6XG7AVtF;fQNzE2e4fq73OT&s_2bKKD zY%k^%;?fMF=M#X7jkkxk;2C4l<r}+j{3G>mG>q(Y+pl@UVO*VZT$4(w2aI~{K0ppS zyoq@v2XQi~Ica}W?eX+e!=UHW=krM8DfaL4>&(Ko-0!_j)HpnhUbU``a}C3>-{8rS zhYgA$KlWQ77lmK}XOy?~+iHwWLh%H$Nu22F81UbL7qCJ2r4W^37Sm#1U}$w<CHQR( zkEKOM)#&9Jc3eX)Ko*K^VJ&c~fYKx5eZxG(?~IT@5Z{Y`OGWC}JsAl&q`2SOLC(Cv z-)RI-gzepNXXV*FrNQZ&1sA0AVpnplBwxQciY{V>Zbsw-N40c~G=)j(tP*-7-OS_` zr(}&f94$}}G^)wA5Hl$0KI8#*2Q|<?$sadox$H2gZ9j3b_q<eSCgPiL-WMWGredFq zFu;KEGC^j|T=kv9HPyQ8Dmt0KtGhZE$z+v(rW&@LKfmKVDgl=61)H-ZBa|p@o?dh3 z95kkJXiHVV(;&K)w#Q6myKU_y+_86y&Etjg{FMb_CnS00D@>@P5*Vs~@eH2wyU^yT z7Akl@O0ZWjG|ws}=VIw;Eynf$Fzdm#U;VdxBaxxRfme|BboKNuU~=}%k%|NF6$>Xj z6X_UuE<y(Tes{NFWs2m}#+UT-D+(^m0ClA%O>K}MG^L2|%&x2TgbOQW84<gBAuj_> z9h*{!FYvl-AwBdp##roT?;!MfpsUu;4JJ0|R<rTyMxLtIYz8SVUEqBx4U_=-3e150 zHWxmMGmw)ax-jji_Wt9=lk}KwjH+9YNMPjBnu&0`XsJy|9!V{dOw_i%8-$(d-sU-} z+;&IQXIN}?Fy@DtsfDX!Dq?`Ic;~t<Rz8`ZKM8*|s_7Yp(R42cL4C6ooc}<Cd4eV6 zK*x`%9S?cs$1&Nz{oIG4=LI9T2?)eZauu@kb&NA}i{LLLLo%!vYV#QnaM6W-EAj;e z%Vj31+DY*;5%7)gD%>{x!Mx-8X>Q5T(45|U0Fw^-#b=qS!pkhQk7jUv#{lC#MQEOe z$9p!<=GmMM@mf7ccVf(rj>r)d+yXB;_h%>tEO+2WF}S3=&9nW{T;1*67$EO9^z8x5 zK)St*u97#9K9whOY+@BDv-10-ICys~#~JlgRr5~PL}eUKQ?$U*ER4hXwann7h_|e9 zf@n@hz9DznP4a<jOV=!*s7_3Nvy@RbtLX^XE0u={u8wiA$wx(>LMP=@SRG`Tvn=8u zWk&RaGJXh64MBhYDN={k1FD3^v9!nER(A1N!PxxmWqNkswwk;g3|^or;GGWLPXsrQ zcduxzEc&BX%A?J{WkInp^<9z?;3vVb#?Jgun~&h&HJ#VSA0SyZ;&ZCTc9j{xrNM!k z__E?Bo9;13OJ4OVd#~zS5Uwlfsvn}i{`($-qK0B-*Hg6aE57vOEFkLsiZV79m$Y7u zh>SI3p+lc_`SIa{o{i`PjbDy+DNFuRyJ+vMlRA5?q+6V^hhpqSPxBP!*7}9#f~DWU zMx*{r&?`$Bl*@XrggKb!csULu-$?W++mtaGZlepWOLKz}V6G%cPol{+rRDoelKP9t z9Sg7LD!U_s)i+SiD1dY883a+r1m8Z$%o?GKoC;3@_QMP=QiWc5O*FP=?~GOoYcQ3{ zD8P(=#VQldBY<Q@abzJvus34lW`2#!c5xRA7adbpBd{4{fm3JG2%Xc^VVRjrXEib$ zAkql&z@iXEWe6h&jzCwJ7GD;+V8K5Cn~}Q8N*>nII&j{R3;d%FSM6t5e47OOrj_Hd zF=z#47_QY(%XCUSicAq3mqLOz<4rVL0w0D+hG=Uk4~i4(E<q)19EV(37))^s=CKua zAO76D8eC0ja1S8JYWWfc{DQLpucGoK@e&)-`0IU@tEYxhV~c0tqUq}%^L~d62j#Wz zvL|jKdOWWl0^mBEn+R6Z8R=fo4fJNs=@?(Ka7)pCK})1@jUx=o5^3n^UsH`WU9kL1 zUTMYjO+}W6&Wk)3T1jk_<zX-j)(x+)_Vr>hJL`{OYEynk*JI{-K|XW~4>VQN#HB=7 z&BA?SQ+_j@{m;~)H|AA;w6KTSat9sF_+oBzL`id<5x}>LJ--4lF6+Rm#ifu8a#?V{ zGoD;SB9XE-8x6XlU>{xih9Uf|NN_kz^?a9mn$WqI!gC|4QI^u>hh6&&5BkWSBW#j3 zcB}v{{uYy?olT_5023rT4-EC6I$F-Dz_j1($%n}@57ZfiMcD%zb2t0Wks;n$*AhuC zMvztC+5vyz@JRFRj@+6Fc-}WvYbg98Y%E2Vj5*YNNu@|_eL^N5cRs=~%<x<Oe6nr$ z`{yT9U!5Yt-Yg=BY#7cpgg83y10$7(f3_*==O5QR1+cmt?>}S5YL2fhXqnoH{CjiL z)XGR35ruj7J@qgii%l{#1LIVTRd2f=52U^yAplM!Ld4NGb7recRq?w<a<*;CPEHH( zA0a%_MAo|{IH_PI64P#&;6X^o7R00kR&s1MK_R%Eo06PMN)J|KB`Jm~<Y#MntRu$s zQd5?!TwmjY)V#^fsy7vmoye9OxUbnjRL%hfML!C~^_ttj-G*clGgYf&D|eYT60FBm zhJjC-RkdpE$BMjf`H%@~^e1*#JlQ=(4;snIIZ^=F_npCwd(?L?9%R<hvC7j_Gnow~ z4y3*T#;z)sH|NtHR}M$%?k!Y+&FGhm7uIK7qwSP(UP?gSAM+FjG)dZxY<f5edI$_T zo!@fxmD6Tn)2SN1qT8s{7jgN)_AXU8KY*YKYGj)h2M;3ZWIe?q81-rdB5y@np&jCT zpL+x$&MiI<EN+>wc`qXaC4B?W>)8qryd?ONfV;by#Yd;}e(QFfU4f|N@Xwwd0Ni9^ z=wl+ZRba2t`7k%FBd1Cub+4N_cx$+FYeMiZoH{W`^sX&9WhhVq-?_c4mtaWqFTlR! zJS@|QHIK(>(2`X+LAnBmiPfAES$)nO4MQ*Pu3=2QzbWAB`r`5Vq}^K-p&Zp{S<6j> zW4i?FuC_#%-JCI#xsYDHkdF~KUubm;V}>&8CJ2|YgWIVQG!a<>OCD4XvIt5PhO7nB z;aMn?=fNW+#&Iwkw<ayNufHS31ID6?3iAX(Y^vX_8R|vv635CJwPTX(@JQ9Oe@{3s zUvRjhxlb)|BDw#9Pe>13xPgU}AMuKkhLt>4D&!L3b`$y>GLnMiY-kuCz!2FCF9M}6 z!A`l2i&owkDZPUn<vkO%<4?ipV%?HlLxQV9NF~wl;B(*f_}~;#re4;o0DEGmMao*_ zP-!&@h{**W3-K@!j!`^@DK>)vfgzlmy31?v3hx84-N4<nQm949fwzb8kRYix(5l=M zGuW@bDbj~>-f50wy0s@}Y^tnoRGoZ}#`Z4@8>5y)Q2p=GWLqng_8ZG1>rDK^+=Rp7 z^z_I^u|4Nb@Ox;)XDL_XfORnEo0CU0tT=v7?l*F)6^&dzG%y&72)-6X$)%9P>flf! ziq3Sx&v^1gLiFiH^&ih2q9FSuPaN?_EoXj}o2j5J@sXdnt9hc_LA6i?oEp~gsMX?b zh!PdhU@sk=lI+5;Op&2CWvfWRB9P&9;IbEw{p*U9NtBoh*_Br;KuqSCbyqo^mY`ju zKo1N;)rOvuo9eEo7H5)GcwE6inb6N~2Omxd3sqQo4PoRA<Z<(Xvbgd%oWU$X=%Toj zMbJD+?=O}KNej#<>3`+J>uK3Y^?sp+R;8q8UFHvV5lu{ta&th>C}f)i<lUlB{9s?* z$AqRB!LOA{hrGki1HKC=W#4c_EW7O0FOm=!Q=-GyHW6|(9-x<wXEZevNnD;}9uhG> zf)s}rT%lmRIZAXTqf4dG`gDJHZ!%Eb3Z@Y<@&BqFo8G;gyV;=~8CW~4p&G?zCBgb4 z>^Xq&cUUBlfXLz8PsoC9in}}cBa3Q2_&aCEa&Sp!)D2Fl2Cz9as}ZfMuo}-Dwng!m zSo;(kHmO*5&mvc1Ws((fv|B$MRA^eiupzDmz5lZy90GPH%cBNEvzRW&b1?Mp5iMU@ z=nI|eHK()j?#CYv+3`rR+luWu7ei6?Lx)N0$D^9x5}olW$vPr?r+~68A^mgBqTIk( zA;v(}B=B;I4EPeR>f(PjGE=`#9T??N#MC&}HsC2O9R){p(Q7tDkJHo|a$sy!{SCss zW9VCVqM^0r$$mI)k-faElS}5@<#W_kWuPg>P0XaHwAm-nwrX*Qi6%y+E?5JF^g#)B zSZj}`|7fEoiRrxOaidK>NGmJwuf=P8I0_K{hc1LZ0LF?3)#xTGiHW@!&8(vt;FfRd zP`-iV`0!&bp7Pm9{(NHLQ;{7cHDj1WV%ii~`-mlGs#x$t+rO;?QyHB+jXlVZ9EVpV zhmfN3^cYmYAf_0~uUz(=8^phu20>De&)0W*u0QKo*%pOj=8bIe4`i{ww#KGn<@~tv zbzr2w2YALCXAPZ~zU*l}5Ztghc9#~$^4o+Ki+@9kC8CUXB|jmQL#epwQ)-IT>p2ds z(!g%ry^r_rDcVEzrEw`O!KG5okp)G;ksO>VGvI<M9vx<))GH_BcW>b^r7dbh$$IB5 zT-<W@8an%}K$Vgpa<~g%<yHqQ6!x(yo}OVGc;#iob4N-#^@4r>&A}5;GN4I#N(sNM zc1#wD)7MWT0;58NfqhJqIpO_dHgIvMG89!cxu&dyDw+kVL3LJt3r^CJmm-~ujS z9Am7Q6%Glv{}-iennktP$WqxmM`u9N;Msyq=&e{YXOCQW*a^V+5s_LU6_0zO(9Dbj zU~Sq&Wj?|pbK{AN+`NuFYLf1fve7?96U3g<?Ln|A&tFTNR1qA3#VXj4Z;jJ@!REoZ zF8g_PVsUyHxPKrWX`6T)LGxxM^$AHcRh}|}jb~4Hu))E&gU7f!^JIyYAd_ML2Q}=v zs`S+Zf;K`S>@<asoWLeY0d-^CH>O}6U|`^+mjgV8SHU=Ql5o~55l6t!YZmG5{lpvC z)+3!yJUj>Y#3t0Cggl|cR2V!3QGM<$6@3BwEIy&B*hjv)7SS(8hh9)8k3G!OoXX&q z@;SxuN2B0@OI*?>5N|{wp*Z-sk?fE6f0##VC&IupN>Azez1pkcV{YJ>X{r5ygmGtj zDKTC|dKrD&5E&YyBI8tS2BCG~zZI3fMT)E*qE;_Far}_uq?p)(6>qw81oUEzJJ4y? zU~~OaF(F#?$wR%tL@%ZnRmUnwTt)q5_C2F=5>zxAthN@i5H9Qxb}lVIVQnT%seWCb zq8k#7{odNllS@7^rIapLfO{O^^LF-A7i3`>Fw;?aAnTH2tQ+sIW6Knop*W)Vad4*l z$NqEzI)?{uJD@ehZq|s3GHIX)#mQ177j$*%su(7a%R!l4nHykPv(pQ&Cw4HAn|0W! z-B23L>T`GqQEnE);WC0#8<I?iJzK3fb093v50hj&Ur=F^8hEE4{(TV`5{xPtJQI}C zlA4wg;PLJKJ!b>q-Mu5&c44Ct0>2WUvh&--sgt1-Gd9M^ng04{Eg3H7yAaKhkKJW_ z?tE&#G&uu_XAE-pZhR*RC>86TPu{{NR$FgCYd<x!ktvFHRY3miF|V8k7Z^Z@Ncv^B zCJIhHM^`n(rg*eBAmIl{RJ-aTo!*AFy;LQt2}xW)JFipJ8Ivyjew>h-4<_H6ElHyM zVBcj5r^qnwe)~>JxW?F!YjsXO_$?=6V?5h`YHbWK0}TAQrfwNZd$J~lEpKF1A)`QC zCR2k4z6QS>J*84tGqESBT#1KN*&x0qmu<XQO;qp@x);LpHopS2kT<7WXD77a@28(O z@KJltt{M;}>iJf;>P~}U7hzsXHA_*;W}skG+~l8=+#W2~l(ek}5C|>?zPmy@!OoH8 zeLSXeZmvJHt7neC>v!MUhTZ2$Z2al@B}}Ka1qt&tU;#s+T~;a>ssAZ&(#u(n^FtdN zZtqXIEsxumv^#Vl)$?w#5}n)}(PyUD8NE_6P_Gb-MsBXe(Kf|4ZG7GZbM-DsG-1{5 zg}-Au2o?<KiwpET4gcyZ0(owTt5>mJxV`j!mgp0Qxf9ea7*w<d@oXIrL&jGWrQCpG zY;Vd-JX#TBevu^?lzGWMfx+I#8{KEX`%Nvhyo>f*5~(O~h-?j4Dld6N{?-fVR8(Q{ ze=}Xx`zl>A%wy*4rKHhwUNY`wN687>gN}gc{G%+4o~m(xVh~y0g;aDs0J8sKrymh_ zXdsx?Rc!G0Q8si6mt5nvuH<lS*U6w-XMd0r*jg1b)}SkQX~X^AXI^&zqJ`_ptb<7E zSK59|1V~1}Yid4E>hbtze5^D{x-)$`Xm||Db|xtc$Fm`7f9LxH;j5ZVN{jn2iSck- zrTM9IPkXzCN$bD#3xUGFc3Su?<Y#xUs*%HKlNc60w1TwT5m_t=GOhm6kJAk11KpdQ zI8)eS^%Cu{qLQLPqarcp^@W&MC^ZwTT?oNRooECA{bwo5cx|S9(LqU;Dl;r2VlLzb zphJglfK+}8^C&d?N}eKDQ;-MzQ7yC}*hkRKja5mhUMM|y9XeM~O4DV0dn{~2ATfDQ zje?u0Prs+p!8J3dKdKln3|iRz>@mktxjBqbgeD{r^4j-msJn3(E7(&d?SZl5h98^R zi6I5-Lry9@tj6G!N5;z{wYo86rWg`U{yrt<@O$CT#`80h_CSzK$)&=oFU{Zzkb03r zI?6FmfnY`ZiZT1PogUOW7BN5b8jT9+JA0JT%_>+KduCPQ1iDG%xL<3LyC}~CTR+Dc z;b~Pv%+?KXtp3O?9rm@`vLP>%IsHNm^q>Jcb&lm@o<KXF)?T4|i;9;dp4(5<*ID>( zhkThGFr-Z@HcI&>jQy0Eyk1f#hRrGz=qn8D?CehP#+E3t<mc;CyTP8tjUUij#hV_- zj6IfuNAkteZx982ZbG?6^r!-&Q?c{#?u#|E*Fq^=&}TDg9vUfw?YQ!Pp3mVS{NsV2 zNrl6O_BP=X_sF8s+Lm0g)UHU;$f<kP!Qw(ETbIyn6G<a2nL3VFBRLCT*CK~#hs~>8 zMAvoZf=|EJE@b(d&pgxDM7{WQlj)ON3wt{x?KAko@CZtlv07{vp|520b&h*oKd@1= zNiN|`Mj9ii86BW1F4)Kl3RxA!plSi@dO~w9&F(o>Pv>2^&5H_aCh};cM>neFI_r!V zk)g7tu-$4j{}0rEw_K6bq*D%z#NG^2vH7P%s~=I&tr&gC9>6w*fiHJ}b*+Z06d&1i zd^w(B%5$YS5Z7CFSQ<zBeNxNP?j1#DylAFA8JP}y*Sk8N{T)mlC7st<#SSofOKdS} zrT_|j#72ief^MABfjzU$cNyK@(~f3S>SR*`D{<4_mByLP#G<VPC)HFxNYNL~uC4TI z)G@H6QeWCjLkfAY{BC#<X}Swb0E{p5n~U;us;`OS&Ys|d38*1si6z>JQv|`;W|=7% z-L^lZ67Q$j<vmm!ezS46mH-;|<9D#03tc4oj;wjhB?sGNn=H-~|8T)rES_6xz6`K_ z2Gk#90TzZ8(pJelonbMOQrH^C3$0eR&-=@XUJ<Sf{3xB~)#IbrvKir@!ox14m*2TL zdA<()a27`v=L%sMJL+b1)tJ@ZY=INt)6)?~T+U&`2}+*`#4%h_mIJm6-H9pG@_5X& zH}aL&bP;2h!~`QZYWvP=gZRt@T;#Q~DAM%lfvD)a=EgHhdQAHvQm*%bsOdsO<pB$9 zc3lMZ2yIGx*&G<cf`0rP5o}s+UfSACPKEb`y>BB0l5X$WzSW2EcrV{|1&)5_BG<fo z^e4!|z5aFWWw`ipv<KLoCee|7(Uo}i#0*J-7f}2<XjFAwLu+$7g?3Jm6aqJ_-a0u= zLw6&g@%clBS2^q`LRBlOee}!lY-=npOvO)w7$2@1HgxDSQ#WR2I-TxZYfM^ZCsfb^ zwTq!QI0;y)YitFZ=O0qaecSXL*9wdy67LM;-!a09gqa_`T9`mx0o(`nC~IRuj;(s1 z#rVOSy%CeV|DU0Zvak?l^r<k)JGqW9#QM(o)nC5bf&UC=g5><JLRxIvZD<n)Okuqv zgRQ}>0(Vu_olaZ!k;9PYMAo@J5o14b!ot6@A{#NfoQR|dctl3P*0`pMgKPCqB&U3e z!%s8GzgSpp-Pi$E2zav|$OtHr%8K$~_>{amE<uNR$#%y&PU^Y0kAVY<+rii?dZ!$l z=f55^j8W(pBJkVmqQwn{sL)qk+f~ge-{-R(D7vuMDV@l^Wx`%UK+nMa)XQ-A$EA#F zsB{tTR+cD<qfeqh?lrwJ`z~kSNsn67CuqXGjz&j~uI&!Q=7nG*#y2?AW;ftP4+(cR z$=S=m!SCh;!-Xhh=dh5wjI506-`BYcyP^FF*Ug`yp0c!*yEW2wqhM2Zc!2y>Q8}6_ z!2j}Cc2z2^{L-uxbXU{^qxxNrzIOJXVE?WJo9Zv`gp?I+pDv{&Gwr%lSND7}Vu2do zCwvlOT6_l_kmt4bLIsm8DBN4PJ0RiD_z(7+UY&|=$OY%o_A5#7@34EBYgYsd;spPq zWk)<Cy!Vi0R~}0k(AGQPz)~Db+ADQi@zx}i@W;9Q-Fs$1P{Qn<M&M8O4phjCRi20c za8^u#`|3TFWF8P9P3|}Py=0&1mT{a=+3tX|qaX{Ijf;%+?m&)+Bs_TSF-i%(!G+{l zghie>d#5m*J3|wbLU%heUvrLJTPcVtI6QU8-n>@O3LP}I>Y;JXYFd6~m0N{8;S?55 z_p&}OuY-TFsKOqt_A>a3iF+8!V?mU}H9pLyGe8xKr+s~Go%=leBzx|0WY?CMeeA`< zv10}J4803|a~FOa)MpQIq7%vP+%7<d`ZkT9HPRQxsb3IcMHimz`X2HaX|bjc{$XL) z<D<ZLZ7)Ybs6hbGAY}?Tc+=k?$_DyY&?g8SR5g{AN;~=TY?&#j@I#mv@vG)4RcZR& z{A(_u7T?qDxm~KCP2de{2{XlG8E1IGhS&q%)|q$NQsyx#y{P{X0<uOHDkj^vac^H7 z=t%Y4Qf7aso!2S4Ik~f)pGS%-HF@}q81&}D{D>s6#u3vAKaYBGBU`j&0XqwEf|?)K zZW}Nm6mW@<&+_<H4BDR6__Y5Z08@3B+C((eOV-rwYXe6AAUVES%7_EcIfidTsNjHM zOQn<{4GQF}y+NGebrGEUsvPy!_^nj;KpwIQ8<M4*z%W$jXP*t(mUc;&zQ-R#;CjLO zxdP`eZn{I{5dP2iAnF}gKR0nR0a~Gjk$9J&%(&yzif(U&pt)py!K>CSyqrjXEulBB zv{o$6vGBQjexW<l%xB9l<5$N<O=G}3^WbmoY^V~-pqcgSoYCYJd6Zo*6NT)Q1+ljE z;|a=N<t+IE1h|>OJNIqb_1CzcD*>}cWQta#(zZjM^B!*vdWcPVqDF^8^0@Druz#8% z6_Iv1p&@|*mYe>tqNhSnlp-8IPl=q1CQxD$Zv2PI&%L6gXVRr-i{CdE&S=0!=E%<* zxC#XJz{Z3PIabHU)HBZuj}bo?*<|;_v@Ippk$C(QbE~}(yI`HsvEKm-g4l2+Z;eCE z1o^Uw(Jf^oAk@WmmuXHXa$O_o1@J*D^$D4=hl(2X{IHtc7}LsXEWD^C$c!J!T-2mP zpRH?{NsJ{(miv!6UDlNzuMdD}7B63VXoH@W5XG1$qK7Z|I2Su^ju=U4&}*H7kTfs# z$>F+m&W0Izb=W&fg+t#$z2f4pAg&jv=Sr;1S5-dU&4ohiR$)I+^`VuWlE6y-bou!E zE|%b4k(-#)+nosqj9BFJi^m9iu0CyLXP&RqIp3dDw%XwNvu95p!f${-GI}(lr^7iF z$4BM}HP2@;KgDlf6lJ1UXXW^UhC?}A)sWIBxKb;O2*s*yAT*9Ehgz_a#^>}3yNmfX z*mMbbJq^vFe++H9Enp03trBj}Ty3(^6%LBqdLT^MCfTGD=>mrhzydrlsB<0qwkW;f z>^)%H*IS&4IEm%U@=v*yP8PQm4TwpDCpb`@&HUrMeX2uaV@=W_aDpqq-B=+`Q$+rv z_At!!r#du9!kiK-vz%LvVl=<lE*8eExRY6flFD+}yMs>OvKw8%qvQ##(UE*4P~NmV zY42BbqAc5>#@#8Kp9!hqVzO>k?0IU77*E5)LGX{qIcMT+gil~6xI}@pQ4srY>`q`% zpEs3UH<RN(c)UrcF<|{&t$MINW||Q#i*Mz?>btXb#*a#05MdjqkOr~+kJ{U}W!SL6 zt)=Zv!|aF_{3}TFRU`YjziJc=%%+dHi*q^~o_LWAYHW!K-gHJ(5NBbG(T4?0N7t*f z9t0werw)GkpB&i#{~T7DnDN2oKUcYIoTTqY7-|1$L2Qw)2E{`HT4G}a#k}6(yaeKo znbQkT)8H7362$({o1-DkKEo=*-9|1DLt!F`OA&Yid6)fo;#c7k9Lo0nZKC~&50bXF zmDMk_J4Eb-bmyaVZ@GJXB^S01QVQA@Dbp!h3SYJ7H<R3|IuvX#F!7-_t|y!wehID< zgZPWYhQ_yiZMKMjxD`z4JKu3}{(^OTm%wG|9d+CN1J@AJ2Jl|#(pALQ&UV|;^gz?q zyVkFZugjY+LwPEC0pTdgQ7cv$r;&m(#0?f3*jnGvym$8Pm$^CY4DU}q$5`yk-OWXU z6GjfP<|hB%OVt~iKSa>tmKUy`%yQy7>Rh0Bm>h7c&(=Z#M%TwuWzw}y9@1+I)2#lu z?b_UYuDM6_N6Z~ryKw@GYa=DQPgEQ$Z3fC67UCzU3C`r+1%)cY4C>WWA0%%w2N!4L zB-J}u9s}248=SsWxB&$;Lg~TFkM<6~SHn~jEA=ED3*#W7dj1!CDu`IJfgTME0_+R# zf7?py=0Nai{*54bfXB{dojvnk3znlR56#86YPRXZpvs?Vsg2=|*!_s4(wywDLQ+X# zxdiT@rs|9Po~t|X03xw5_qD7J*(^z-=N&H~^tW@$pV0J_lj6|^Q4b6T(pBG@`L>VD zHt3(NnxxjYJ*Ul&{PGR1rH46MxpZRn`XDePLc)@>ZqFieK+NEsQYB+VEcI#VO|77T zRsMC)q)pm1Y+JWN4ZET#o{JYQZB><=`*%{Pt~C7R-oyI7$H<&O9ME<g1@Ha)(O!$v z(=Cw>Wb<}<l+?&^C17B?&7bm9SKfGVvfCu>!1c{$nVMmoGvTD!kA`6ZLlY(CMD<YV zVIv-A%}*&9aM|Ttik-KY=*?5W8u?bZEFtK2e|R90w{+MLo_bTOMM$Rx2N+D~LQF4; z<R}pL`jpyx$(>Lxw9L`QrQMQG)OxD@6c+#K>HKx3<gi2;qPunL>Yh7?GBSxYa!}E? zpiGD$BVZf$daz!4Dq>0v@}#zz=u$wR%n78eu0!nttZEwPlvi^mURcNQb{xZmgigqp z1+US&<j<D-!PLoHRpW_K)zL%-pynLE-yiRvjM3!3DjtIy1jINg9q6GL89+i^RDf%X z1*{PN4KSD+V!*21&iin@HMu{04l7b9`?jm+Nx|9_%sj<><4oDE@Vd8yO30qVG8-+X zPOfqQ=$DXg=B@x#!-myivT`WCx|CDw(b7CA`RTpd6=L=Ad))HURLlYDBBbZD>$OXD z0A?DjCV4sAxV}ayE!f6OyJoL|LVvIX0RNKHQ1?^ii?8B7+N4&LRCXi+<@lm%|6IU= zsyxO##js6*nG%=-j@3M`k2H2pUiNZ5#G@}T3AzY;{x08C?7=^HPS?w>Tu&L9!jF$| zSgDz8(sa{j-4zKfI3Q@HC(Xy{d4GQ5Axp*t^BF}$Kh>a%p^SB-NmdDV1t|)1*n%ws zO7CmLu<e<giyJz@P45d2FbYe3=p>3_R*)jsQy@v_o(++E6%<%|D3pj?IvBzfJ9Y(r z%NA?R1q{({p;HX|1V)caM38=_NiP+Siu&eMR9x$A%4HX|Fw+~xtr+>ngAbe5iIr+` z83dS`Xp5wl8dIfdbwhp1f-I{NJrTf-OK~KbsMP7dI<rcpyCGs7JD$5f4${DiQXvYC z;20+~Kx>dveR+jdP4X`23dB#tJ^#lV!N@<Bj<L9cRR9-_#=Lb;DUYBIfL?`5Q6lmc z&Dpx)3~e3v#3c@H!Dj6K74tOLkrd@2@y(zoMm`SU=6~RwI4VN6ps)~dCn_E5c<ko# ze>jmigG;3Cm{%&SF=f>^n_DQG$>Xzj`+}xf-B?Uo5mavU#D9UwK`k|CidqJ^nB<PG z;<M(X47=czIessB-qK!a%|3G!J0vuJ$*zt9>#ouPMf|Quk#mOSg^O9KE?1bQ=O@g` z702&qc<v?sM@=e_U8MVhfCm*o7SqxVX|Lk=GW5E+lV~`)9-;enFVER8`$$V4#BQ$b zh0!?cyrT%Yy#x0p0u%MX88;BX5j3SDf|0w3VwZN~VkJ->zx$$V`fY#6OhosqS7(<L z%&|V>b158kFc{*rZ|!JhuO`(Y8o!)r%Z<CiWKf@jKE|6L7-&2Pay^$Xltr;(eR|c< zAOrVSCyssR6=5~^K+|5oTAxUj>7l@*dsl%EBXmDj3dCsoH%&%sfRq6!l0xulpLkaP z35@OHc%E*lXB7CdBOXD-->{cLVhLJ}sF~ddFTlBDKKmumk?~+2qzTbgh2bIeXu)kA zlIusIN5<jG!bdm68=}@ThF$9LJF9*yOpY_+{c_8}sEsc?w0}dX@Cnc4n7Tb}I5IT) zR~%>$91%>e-p`wh*jfh0T&PE=<>fF}i03%&bq5!yB=^V%kRw@Oij=tD?>zCr*s(L= z+Yq!lWwXutlWfr_?0i1c)g8=4RO%&2WO=o4i%`E0%iOB3oqMq|XWHt2!goI&&+Yeo zJ9l|skvM8~cy5d%{ca(`4H0ll&JNZX(Tg*T)(QpHyg((URZR-;f&L27LKIh-q1Mq` zYATf~rjnigJ&&NOlXzEvMZ!bC0Pp$g4&IhCJ&1VV+7>cp=uW=he2mg$`%VMZk2gxe zMWqQpO*qc`s{n(=W+k}(&c^olk?20+yJ<^TJr`T{xN<seS(v79a2^|D`)8?rtwl>H z%NNq%U!pjROYJ&<OGgS`Zx`Xj+|+c?HggQIZir&4(QxxI`+eb4M}pXt2~kx?Uz5<Y z^u#g>Qw@<(%6ju>zrB;U!B@89CJUxgFCrE1b2EQQ6mh>SI4(~0G6MWr<0kNZSrklP zF~5>g=+kjFsB|!PSxRLH22S(;!__$kcM`09JI=<oZQHhO+cy5OZQI`1wry);ZLsm1 z=bTUH{WeuST~jqx)AOsl@4hZsmVl5zldJ`JJQlFG80v1obeS3Pr8b1prdl1Qegao` zh7my6q~vFvUc7VkIjbYnjYvBUT1GWhbv&w)G7TG`USdDEFu{kj#YS$|x0!u%)6_D! zP)3p!L4;#?ZlbUwr-@@QC|8sr{A6k+Ipx?=yTBuTjnCy~V;!YRR|?kj<>q<yA}GWG zXM%oW?@9zHlDvQiyHIhOLS<)hW0!)TB?1#Nc1X~$z#|3@+5CmI!I*wr*pN?hhL*?i z1nDesuG$Lx9U0;~$t}zVIh9gkTXqGbx2sTt*&U31^0)Uo`>My&`EGE3&T`3x5vUd4 z8k<y5lRq*SssK2H8M+I>Q?pX$S1%c-`{sBlc_RWK#S6*}d_joSI01r@QYjo9A|Q+J zYH^E@P8+R-jtp8JSSS6tF^C9wMML^t_?HCskw{yh2HzhorP(2CAF{RdoL>`c<-&DM zWI56=RkRV0$fUR<CTuc?9T1#eg$Nx2ZzC&+b>WjO;M8p2eiNHnvT`O?!8{*KopFEd z9p6p?<wpn@6t{D*;Lr21y=i`kcSJpLl~;HHlleyD;`mA)Q@t2bfE2_%*juH+aeUaN zW0mqkH-}$^gLwbM^M;Dddb{9K1+UWdPnK7u$yMN+hKIt|ev|47qUx<AoOs|`y=z9u zVi{eD0DW2+4GKi^%xXDED&C+HLTFH<;;rHX;%bKPz7oD(fBuc}!@ZKG+Dgk^wh19T z1p6oR{R2(sWaW1|w1K*VuJ=PO(2|wiR`j1O@zgSU^2(ghY-Q1~Cjiw`C_=pLY8a2Z z7tmIX@pd*$*zU89U4`X5QF;Gr8a85E5hr<j7*X*^q$k?`Ilu2(e=Re@0YLdI1_1~l zVH2hNV+Cc^&Hgp)PN8if;9Q3{68tl2zZYm1sV%1x*=1$={)MJPClpH&2Pn`AwYQZ| zxivC1j(A+;U*G9XL;736IH!b!()d;o+0&Xeqod?{5G)jy{+Ra7yqwFp+yKObbc|RU zT34Qnb-SH}2=K)GHfzwaud13m#I*=u>7slrr4(+Yt)nl3(}9+_2q&7or8bR$$KwL= zOds(JIx&;avtD8P62=~9pUY3ARjtgrXn<FuwCn)%eB!$fC}kEI*P&&gH{8(^Wb6<a zuO!Tk?&6>8ie>eBObJ}1ggsOxHu4a)2#|2taL?ot_ICKQ$Ww$8!J7!<+O0LfX3HBL z)U+XC0=Ea^>6^#<j39YbtD5Y+-IXb7lW}*txd^=?x{m5Y^=l%QalBmjsp=6TqtTCp zCqGYU+;O9y;Gz0yJiNUM6)#zDquOo1XE*~w{!a#x%Osg)S(G1)01}R4x;N_skTZVF zH3YR`!aIH8sd5aE!U@~)&hIS1;SJkqtnS$qwtWOVJdd(UZ7kHCcT1h}j-sw&l%8RI zAc=a6OSu!**zyjj#b0UE++0^wqLcmQM!>`If=6>?CARFpy`C|Jd_I4DG^ID`TH;}% z#ek-$<OpX+fzd_wamQukq;awmhV2?6>V~CQ2gsHkPg*X?k%NEJalIb^IE^iq&Dfq2 zNTPOO&YjBO*IqN0B8&@=9tw&bSpbY9#A+kKc$NE$Z;$Pt&7HS%jPGJ4yBzruCd!~G zBUw6e>Y$8o+%IA8!$6Z2R-6N(8Ed)ler=H4W}uaz$Atid5sTM!(m>JQcL6=EELw!W z;(D|sf%3DZ;#Y+3AXw%BvWO}5)(m;<Y}U!mJ8z*p>|jgXPV+k{J7`t~L=GxYem!0p zZy6ppt3`4>?ZMAoEysS=IOQRT31xK$?^IV^wc@Aid6)0_b16#=P2;?l>++0zWPJsv z$f?qZJl%hP8TD#!ZEvoZYmN8(a$W<{|EM)!39e!><uTGmU-=*f<c&qR?t~3m)3#Jz z+v93P13Tgys!8e{#av@5eoxC?MbI3<QnQDHzbUa4ACNP11P{>ida~z>Z%N^JYHLW^ zI$%cQjPK6TUNmmFT4=e+RKD77<tAcer=85a4g+AZZfE4KO-}Ge58QWZ+0<^EYo|`m zW6v`a<KC&^Vf+vPd3dc{OhZ1j4AzaCM521^YV{d#nQD)D&YggOEwbjF+Dp7{`;kxk z-ag@(wj~D6K6c>7u$Wp0-0sHL`TZ!KxfE@$d5F^44vX7p2n`Vr$s#yby6I_DxJ@$i z7T@W>iWB=Q2t<rq-U1J2Glmn{J8PseNw-(>Gu4@6JC6u}Fp`_pUO$hbdvI@ZG|#{0 z>rVZ)Hj-Sb$MoPKige3)y$Y7sU5ptHc7wszI2c_;<f!yRLm7G#LKIz)uHW@tz}G(a zA>5|;0b}X5uR4eqH#sCAHF!&_de&WPqzEvqIiHi93aIL{Y8t*ILsc!e?8r6!r3Szr zTe2LR*`w_MOxX>!p}=()I~Ddp-YUAjI<C{(2?hZ`MmZz?SeeL5>fp|7dH;=L+b-v` zYV%t4iL5?D^T<iFl26<Ag-W2bs(I%sDrRKquINhuTj=p<?`~*m#@loPXuK8aAPT~8 z5fLAtafzIRB(m${GmO9?8}r)G1~j${%R0%+@bne%9-W+jy^Wz<qg$JhxVC`?q11xB zV}k~hY2A<3`)oV9QlWp|$?VDVFI%J(2N^0i^)*CVy@F3sc6U9`qL375uf{pFmLY*v zhog0H8SKC-xB+|zr(i*fp3VG*oZgXO1axgv{5g7efOBFr_)qc}Btss)Z27&dW7TMI z)mSq?`!*Nf_r>=cHE-?20SIUbjm??8W>qjid1P;+bYA2-h=^U`y8;Vmqz&D!??yQj z`_zL<w&@$?;X0DOE07;YVE3E3czCbQAHlYIbXqTqkX_ptXi{EIU&YXUjnRqy(Ai?T z_6XVHCpG=iidCOh4SKp96Eo-D@aY~N%`pcQNKx&Mj4sNUQdOM5QBtPZXPlUQ<;v&Y zpL^9bPaVBjduU(x4@@7V*SMTMOEfQRxa8k#?NzruU+DGBgy}cM|G6&ks>z)}5|F&a zrkmo_^WZz~(^c|xaJ|&V@z;;k_)IIbhgO6?r^Q>vxL3H_)D14ocWKZte9qF%8ubHQ z2cZv;b9SQJJ5_vmiad_8l_GwP)ExVdOvu(WHNugvV(P+<9@0e^=S<<q8de;ZF<i;N zCzLLVLe(DtPbMobmHdV?T{umny&D+xT@Mc+y{@_JvY5jsST=fkgQHi;ijiwKTJdiK zoHl@Lh#W~dgcIdiY--i9>xni(Tf_mlk94R#U*~5Q2-gTi_G`;B+&GNNR<`(rxBgXr z`LhL8$t73SwXeawbnZX>_!Qhn;>O*JlP=oGebq!TUgLm6`nIx`2(o~hLAEg=SFulk z%Gc^&W}VW;ub{j4W<6K6P4pc&I1*~%^fP*{mof<V3sE846Ift&oHsf;HzfhGjsoT9 z%3Y0iF<4-M7{pf&ih^_<h9S-SXCFuWi>Ve;Aod07^jX>D_P3U*_q|SQ!6Kw?zZ=@L zZ5(kfT4X}5S_E9;a?g243H5=sV_~#&1{UF@_%rM&n7c1-)KiPBTU4cTwx)D5T#7_Q zG}0~1q@~s@k0XH*Ep*0AFctyZQ@`7(iT9ui{L9T*tL#$_ug4Xn3e#K(l7J3VB@7Am zn1k1W{ekgJPe^2+;3=OwV)pZ|_VFZ43I4raLEN@$c{9=7Gr&1z)22FG*E@Q0tell2 zZC#GxHQ9M)K7mIY+&~C6jurVcS6E3m0Edz9;26?~{N_l%bQfMT-8r#BEvIPk*h?v1 zUv<PImocxdcB1&8@;67>^n*pwle77Hw(z9ZK;_$(%Urzh-{ugw*;s@5b-NTU*`N2I z2xa@NwCMh7oAU%<AW-Ss)#3k!_}^NfTM2wK5)=^7GDdpN0x&^3*Z2>P$<ATB9qFsL zFDOAtGka1S4E!dFZu>Cd-)4ao$TC&ZAR}0v=r!|d6nD~tHx6mvXWl`y{;GT3SsO&4 z266aM<^jtbY%1x5j+!%#n$5ZqMYAE~0Cwq(W-Tj?n$A@1M22nbiQG`k^(D8-V474C zExN_kki1}{)v{2l&iL&Mpr~c~N_9`wmLvn+$Blt{l&Ru5$W7W<zjb<XaQ9jJSg}dK zeT=QyMr#vhC6TYY<0F$pe4gIHdUfJvyP>wouEw|rsV0eWY%=T$=h-&3)X(P#?6*{9 zCkg&IkkR`r^$O;ulD$XT^}n6~wtO)wBT`uv`&i4{Qgyo5q#-dY0OprQ6`HNfBfZ$Q z6CG<-?)Fd;_GteiC-5z!2OZd!)>h_|bxW%InuGJO^$H$OZ;%Czl`O;bMZCb*-6D9N zDh*v5vJs)c)Gp?5$bFjo;x?ot=f+UnNA|jBKSTuM<0(va{3ZBMUs1xlyp;~Bl`?E1 zjeB>uOj?IPS&*(IARXpjF>1E)F;>T^v}F<Ned5rSy$9{a@4Ur*J7Z+f2Ew+L(G$lY zHB#Z!61_$J{eJktIo|PoLjwrz!+5)4&51vTPx~bN@2|0fgSQ_~=$Dh)$LGb~+V@G+ zzbL*j&5(g2UvC%BgTF-78_+tg5?v~G3*)gEZDVl-NTm9pfLSab7&I&&0>#|lfELej z&52mOe`>C(>$}i!fxh+BLhq?OfiaQ%oo(gAkP<wGypjOlzc)|s@oRI@pnI*5L7VUG zqAzwZOVPcxA@rlKhQ_@I;<9{uf9Iqzd^Qemd*;FBMuG?lS-WC1$BAB7V@t&r9(pLF zPK<w7i1I~t0X$gU0*aI<&ejQCOvc@M%yCHRQF-L=j(Eh3nd&$a`a=78N&@oNq&IG7 zWQwulQ2nGm%EjmidfVQ_6dT2WL=O^`mK%{yRriwgJ~o5`Q%sN7YUl6|72iH7BBV$< z#xi0;F5~^E{Xk^AvG2`&lRAem4=0|`#bePqf!-tr0cC%$)4Jc26wi{MJYfxblAkbX zIT%&^k~5U2X8TA>{*ZUHTdsiPZHs9+BySnQmX(p01xJ}}hn>AwCct;Whp=ZPdgx~V z9Dl(T1xX(`LAH9*o;MgXbfK#-9h1+%s}d{?xp!|iThbuZ+EAysz`O4ZDg)=Jnz5Kn zh~NP=091cemafCl0v~$|SkU-=9YfYpVJvOr4E5u*nS-P#7FCvf!JDqaRK*pAW)F)5 z@v?a(@vWx(CjE|a&Z16E9-tpMA77g7T1%AwGwIyB4XI(rudsNO(qU33s)PYo6f0N< zKDtO+fZLi9QH+*O;L6bLjfyTL1}0M~5GRxy0$?Vdd(^s^wai^}8Qtyqc5Ep-bf6** zkxEgQz^D8kP1Po$aU#0FM$4|;#6h9yMyV-*-)vZ}baa(8g4PMguexBPtEqIH`i>ZU zVMa=@fW;B|mr*#wU5`5@h=E`=I|*U`ZXPOYv$D*btN<#4B$Z31%EPBe$D&Tb>i!z~ z1@MO(N;mkpT{}($`Li7fg5C8Y49Hg^bZNUiL6i|dRPn?<V45(!aWm9HUV$Y!7^r-h z6B^v`IG^jESyag&@gB>0cXD||J<W^g%Z74-Sn@J12JJ?X5PmC(#H@XO;6Nl21ntAs zQ>0GhL2`n6=d=3tHb;zGL1I{jQd(1b383|R$qa@wDaWSz3Ke|iRi0|~W1_r|rDWzy z?HI4@Yx#ih4mnFH680y-e*qIQ^QaNQkb75JIz)5rClOEM64}%YY-P>I4vX;~$OaY2 z!Z5`+YC%KVj~98N=tQY#<!S_#_zS;eX#;1<Y(YGmgKXB{p9xy;d4{bey`?zz0f6b$ zSu+A%pY_}ucbNBUoOkgdjwX~QKP5-ypTplJf2=RX+c5F+*7w>|GfZBN4BgkAB~BRm zH4~nGfN9k4a;?a{0cY%zu+#^<461rgAbXd2A9H630fp2do0j#bHN$KQtbRh?G2=Sg z>DWW!S>Y@**$265S875srn%h24RF}C$1v9%eEx7b5mi`=87?wxvP_jp;R`tA*rwE0 zQ`O#$j<kS~Y_fNxH1{<*<M2aGIC(fdxt6_j7>$XUJk8$g*4=}cYH`>VE<W|qfgb-h z(71e41<Yl<lmo!U6r;#@%fULTS{QS!s~z!PG!E+8ekF(H7oa3}#e<5(0-ggE%@o?K zHRz1s=@(NOnZ9d18-||J_gpsa;OIO2*XBV-by!&sVsO8lOWUdiYJ@=!+K>@mXK%7u zcH3p*(J+>%ujlNpX>;-6uB8>0LFQc`-4Auv6b}+wz!cu?2QU(|>_<39tic+-Ymfp^ zPkwPO;e8GaNox%<qx6}#1AvxvneE<&uo0rl*XDI~QLJA{Ygnj-aDv5!&yNtzhW_Aq zxpuI+PLIL!Xx(HK8MD%+&(E+u^<tFtW>I4vKrW`g3}@DvPSb;_#w)H+pCIE=DA>i} zPk*!yPRQTfRb*O~!@i+VKkli=lk2SLg8_584~F%I=Wb#y?Vo$T0X8g1xGg>K_C1KP zn=H<_@OL~VxLpgzx0x)a|H{FdqWd&aZRskEkC3@nm?usR`Z)6-+tmaIM*#Ap!1nd| zjfZWKl{?R4i4Xj!gBGX4y}Tonr=WQ3O?5o`lqGlwi`*>n`TgFS%^kGM=1JuERYHo4 zncs3yb;gp~;y5{#0k^z!bLTLmmQWciT8b8^Eey4SFM%rbl}Ey{Me$@j9%|O4QRpCY z;casitXx!}PD0%FeA}8s<!Qf_xz^&!#YmU6({#flVl|doTF=c?s2V5?4cEC?bBYg) z34j&d2wkiCWUEQZ<W%YLfryje<kJ6ozv84BdK-%grWv3Z174aIPmY5xt2n$@D2E-v znE;Tj;|O&$t$$A5ZPZa-2~v8acWR-s{H-0~+jo+x9ID%#i#z!1cB^W&xcEx)dUZNc zy+cjZW5>PLI@n&6aYx@nc|iAZrk*)22^9MrO9S8_+gUoMwrdQ+I#!;LX8!!x?6mT^ zbEo-a$||3GIM-u6;Wu1CP792`3K_|cq8&LXKP7H5sq?$OgQ)>NUugfEp#+P|s^@<) z6i|Bh0x$!>VT%*p?}uQ$9KOyH)tC$ZOeBat?z)tFWtv@JRo+Djotbu)5lahAj5bF3 zw)di<if`&)n4{l)a9AOLW`w$A7_DuX3|NcxPwg!Jc?Wr*uoh8>e?#wIgMRx~W#u zys>5_ORZ5_Sqob!y<2kFgq)g0tuoWVSBw8n__PhMAzd?q)1p6~v=o%#w_Maq+j1ag zBydkNX1GR;5h~vdZk6b;_u+g$7yY;v4cHr<K8T-S7Z-jMS}i*Wr6kb4@1&BcNMtvo zzi0;BJV~SLdgz$Z=<h~0t4|JJ$!ECE^i^@|O(FLYh}PB$E0;?Pluc#TkBG0lBtvCt zEMEa?T3kRjXx=wi<z#4OmNrb8y+(GaNLW?KhC0$YXAx{SQZm_0gT@G^$l@0Ior~5R zUvuITqRAYflevp!E&g&%nd#$Wk>i)L+Y%9ytmh}M0irV1r)xy%;#g_WfH-`oVvKe7 zj$CkMn}l~^(CyT>1rfBT;})yXWnMjpyLSLiytJz|L45%|amdd`WX(YO9@^&C;kp-a ztQ;Y2iRPgwKt^O)*cQo|=Gm#VU`JYIS&RE%un{qT#%NN3>vw|UVE)pqYaZMFHgm9V zH7}JuJ9xT1mzt$^oL$u9CcAQ$^8PW8-|$*=AjA7_pf*^)G)u&6h~uJx>jV|q4zK_) zqhrQ4W}dE3`nt7}CP?|duRk6xKK@ikFDE{r)2|K6@{l@rzoa~M<<0K@dp!Ld*@}L- zW%xQhS^S$V6JgB6QI-b*8Tl*VgUDKQP(+L=LIt`Av1UNIM_DehJQiJq*jqy0;_6?$ zZK0|Yx6!}IqO%!kK^o>yFYqU$)mL8trS`bk%q89WN~KKWESzBudy6jXs8>0-P)@y9 zW)qDT^fNGyb?f2gZwU?J<nB91^cYPLsvI6j22rnz=YPPDK|o(lt9TJ~*jmSt26s@X zAQPoBB%&n4Jty2=3%^J~t2+f+MlL^YCM;I+=Mvepaov5dh6|ojFn;B=02M|8;MQS_ z&}r9QZKt$kap(GdFVPm`+?BNX%jmpe?Qk)XL#8o9EB0*oUn&cp@Mep!RoG6U2*|E1 z;>*o4H$JubO4eQjr-B#|z2z^7L|$B^Z5MKg`57#eO+?gTz^qP*M~$xWILTGc%ws=! zIdHKzf{|B1c8iPqeQn@Bxkd^B;+_5GFh=acDGGN;U`>u);&S448Zb-CDR&4Y+N>6S zP&5p~Q38^d5IsgDa8=25gp{Sq2?L$14daY`nyix55Z@e>2&jmNli=eHDu;x)%sTec z`P;!I@~kM^Eciq=-`sZV%e}u5#NDEPISKH%DZ7#yj}&Ti=E9}jpmTl$+NT6Wid7ng z+|Qh6AT_YkkR`VvrF66-1WhMuguH_jw>}6)>5yaR^{hE>X+1KCLf%Y^9yYJbtJhBp z=h;oAX1lF0ZAom@lA5+uUAb!L1sZLd$=FMc`m(QQ(k}i`P}Z|&$q8-RwaCe^<j=tq zB1$0M7jxDDd8GgyzM<m)BxYNc7*4BC6`c`T@dgF3AK{Oo1(iy%!J(G#ur;kvw~?PB zsB}D$wkoz_d_jD|*jxonA&=7v7B$UyugA~M1v;%as{}6l^J=4g#vunMh~T$VF3h1| zGtOe@iXFzwC*%o))j#t5RW^GrTzNxSup50ScnNoc2sp=J1`s3xKc~#++g2vC8&z&R ztebp(6wiWLzcsEpO$uw7rzE783?jQ##T%SdvnV%q#*V_cSfML1;Z(3NRRq$<EoYjn zuHuW>?N(8I1PJ;Fi(hoW^R^GVc1G)l*2%=lg!f*izCGrAJTxV%CybzdVQJ$xDz0ro z%3UIhybWg`M{LFcAmtMQpfqBk|E%EWv%dTOT4CINfW|e@eEpJutvxiflK<2^$q<r~ z!+h4aWwR5N?xI8t^L~O=ih#;0Ns@Y-Y9Uy3TAiEq?R6Q&6%lbi_MWEn-Ki&}2~&99 zeb@f88!3@kx+7sgPLBeCSLc(-f42#q9Gca#!z8CN%lP>lfTFKfG(B{ZM<`TmZdNhY zu(U&^G?E(;B7Z#%{<LSDhIr$`JX_f(B~^Ew3dO)Las{)xz_iWW>Et=UT!}VK{O~(B zhb<5I_lLU&CEm#OULVXFoT&eyC<UzhrF5zn<G*oa7pQ7ZGDH&V>-RvFcPUE@ZCjKs z2PA4%u#Z`J08jxgb~ognlE>@v69Jx<nN@!MJd#PiyWYqQ_4a}m-tWlFAbNG6z2^)1 z(6FWQbSHeQ^xwdY#7EmAeVKC2{))=(g5zd%%*7QpEh5%*agqF9zvg-5cT=I0dvbpv zX{F*+jk`XBz_=TT$aExxvg)w!%vY>yjmRSxv{qUz1MDeM*y-b2M5ooa;Atn)JVd=* zU7G*U@+!%sJBj?8x4xENDXUruo(|20>jK@FYFY)_qG!8keTJY~Fo%aU_1K-*4ZlGs zU%3D6W;R{qu6s*UEI0m*SMl_O=o-+OPHoG7Q}2$b5<Gb@Rk8Mng|y}vqqh5d#qRwA z{$JD%1mFjV`!0$yeKRAOo|{_}OONg@h(D>2i&|b>>o{m1>M3M#ec+tB@NrWA>TJZh z(9lwy4-Pt|y$9#Id#SXU_mL3m{@!Wf7m-C+37ALxatCZ;Jo)Gdbp_q^yqtXvAPl{> zC;(lEEbi@`Q%x<r8;LdL%je!$1VR}P&RgIq0>+Z6zp9`h0f-R_`V1vRHlts0G#Y74 z^iXih3NaS09z#!lhrk9DSK{ihToH}AT_eCG6=;?guIcr)5GC*9m_NAc{LSbsfAeyy z^;po^`Ipij#q;Fio$IrsE`vQifVW3V!%s)YfkY~&d|l_q--n4jI?++!9TT-i?!~|& z0BFxP+O8@LG$k004_`5kS6Awe!E+2i%BMG-sdLzSbt#w<v6=ig-p&WODFtWAs!;|7 zAvMo?dA!b+Q>Vusye|rK?kiCn$+ZQmtJcCXaZwuRHML)sZ)j>+v&D4hA5W<jXh0WU zFs!xQh8xNb{*DCda~?SVp<f~Q-x)aoz)0MWRCzp8ARmC^7x|7RM>mLeW7j_DL1Y0M z>W&uoel&APsIk(>+zI~TAmYfn+3hD=zh$8p+hjLpdGVV|+%|H3Al+01q5z29G=0Ci z*6QUm?frQ`o0hy}!<Ml6MPnG=kx}K<ztSO1$$ZQK(%^Sn)vT|G6xw;o!jn`X0MVEN zu@Sm3E|sg^rS){<$?h&RfWgVnQS0mN;PUUeLGSt@@IovtiH0V35P;wBIzNAVbLu^r zMnhe`=#!`Lpb!G%w+WROdOI6q(4U1k@VwFUc8o*L(J%g-w3Fm-p#Kejm3d;yfj?05 zkDmZY@PF*Ubji~n`QA?h7j*j95I!UzSAEO=h#k>yO#}8Aa;lc()|dbqQ*wduas)zb z6^3G<RT3mH%`)32Q&nm*9pd!`Um0U68;lMcEYdSGlf}XwHCxz9CR({ny>c6@XjAbz z9VxAC4|3^MHdQymtjP!=G+~NR)3T*d7}bfm<V3rX_w+plL!Hv9qSu!!*31hqyL~EZ zQ)+-hQ#-B$rH-08e>&rHuWqT+m@{QZQY1qKOhsij>gLRg5QMLXDn_sDkk1c2bI^mn z4d%g-tmW+G^y-!5+nu%GWx_!Z=UPImcMo<+2^QkG&+6CtcH}Lbc_{u2%p#{oB~-E4 z?562Vw8l$PZJAlkHN}^20WJervxV}pPi3uU!m2iEI$_s$j#lXk>QVlyJDod2cm(52 zf%B|)Zc0M>W#7T>NRB<fQ7=EkN%#?BboM>hPS--(^@CTL?M7S?E<yjIq-!|^`hGIh zST_sHPyvSzA3ieEt^7dzMn(>~zyH$1%wJzf&AmJ4^7n=}X=pHFe}e+RkF?N**cD<^ zETSdL<XM*5lD^IYJdwkWyVGokJ|99=S_D2%)$`p4>nipr&s7S&29W;I{(#X}ihOi1 z1>MfuPDI+{$oyXoO4mDKf79zu4&V5H=s|4+@f>2S#wiSB??QpHfnfbnwX_#}z^-wl zV?T|Um`<ddpmI-dxT^wO$-`N-A)ikM0$-oM3DWbGa}+xWn_F9S-?7P9d8>4}>6qlx zs4l=qo?aG18}0?LNHXRU!TrfP2W@3GvQ^W<NloPvfGg1C9K$o^7AS8}6u%mZdVbUV zAuW=?W@lHF9(&d&!+ejL&<wc@eaDBrzZ{JTjX+QzqxLo9-6;Xe{JL}Zfy`FV*et<U z^TimHgbKI10WW80{JbIMm^(zSuRK7=A0Ah9r*&IdMCtmiV`sys#NEj@mF`K<+fHKa zW#yaKe;~2)bm18?ABC!;VsQhY*`!U0p6N#>36@7B(02SyT(eY#1)8xE9@U#-xwV{9 zZX0eho#2YNv6KN3HV6A?_80m*Wo&;!Rm6prJEwe`!2P2XgDSxP(2`8;pbE|&aYB}v zNY?V_jNaMlYW6#=M?g^Y^KuHTC`R!Mmt*_<A}WO~yn0^AUF@YZed_0$hvsviU4V6r z+c&GLH|PD6W>NlY0AUXXC$w!|gG&@r4S5My&@(D3%or9>S_NFff0{xgsyhTCikQJ! z<5DNVFKelC{ut(8HhaY@UR2mPU$xII0935>+A6+U9A#U~jthr6>hk-P)p<L%1{<vx zJoZ#L?y#K)2it#v>%){M=~lTmRxbXgAAj5<cuj7?T(Z;DhMWBuHUh6x37k_mYthZ1 z%ed99nok&@z|heZ=Whc(rDUXasTMk;;9+5=+h=lE3212ez?b?uGiQcB(%2UbE|3p_ ziO%C=pu0U5scu`?-^1Y0XhZq;rt^Lg<)Wt^A8k4GEdDVw*GCyie@v~AA)5J98j?gz z7gD>PA>z1sxL_|@N*8&`w8h$`G5GHO<o$fGa(5!;du7l4#D|9%5cuDP%a=sy!04w7 zxE(Q_so}@Q5P%2*)z-5Q><<24W+}%hFbvp#sHFP_U+nK#KtMgl|LGV0&y98$z_8f= zz0nU0L<;6Vm+6xTASwTu5*WAkr1e8n)rL$@3<X7P`<W8}`kxWvVX@KXpSALdAbnu@ zzmG+2V@CxUh59dtP|_O(<7XHK4+w}V9SIeLEIn`ZXBF+y(s9@xMf2Y?VA>&M<j|ZE z`FkoXhOH_N*DjBU<A@|gXg+apqpAx(g(bZU_Idj`i=`iiLB))$8em56amw>jJ>Ah7 ziy@|Cw!67#C+msyMKdFm*P_w!Q1xBbJXTy8_bI`nTbU|wApE_c7v|v4<Ypv|=Lf5h zUG&@HfC0dE#~pQ8yB7P<x)JR$`r7la@Of0dYC9U?O`x`pSx({Kp@|MCv*2=B+IeuD z^VYbw*-I2>N-am}rPJQlX^r&X=-It$7Di^ZjY-oF>e@T%FlMxNpamgMFGcwm#l54~ zTf;i0@U)DrzuDOr1FWswmy`9x8@lQ8{CUmvJ_P`UN24Fz1HFqL2e*o7QQtz};_K3y z<jQ;{zUcR3e0H|S`Ai@GZuj@ybNEYc0rSii7CTPq<oAXY4%i#g^LBLcvlYCNmc&7E zC3JQgyW?u`LS~@x&$eV3uQ<nHrw1NXg2xBF6c)RjNA?W)S}0IWkB61jjoW0Ev^RG> zI3d8}@S^?@NWiZL=^s;Q1+AAUC-DK$&B8ww=44NdxFv;Rzb)0nSnAw3rkdpAzC}*u zJ;5h%j*W<cI;tHx9J;wli}I2&(mf(3iRC|rT^M@P0fo&zxb-4hT9r8{RyAiFWs`0w z32j?;|0uiR-WG`CXSq8LTnH4jb5bisch~_fq0w8y|B{`E_m6;I=H6_P$ch^5QWcE! zp^&GqLz`kOsvm+3RE)t;N*1{Uu?yAQk%{ElKqc=vn2RYM9IX<GG%*omoBI)X$spVP zWt`5S7J(a2OP(epgZV2VO|p0NDH)~0Cg@7h5TNivIR=Q%#O(Nlmn)ESAUN5MT0sCb z@rrn%S+i6pj`k#K>ySIF<YRcFJefyU-U+50;3{JFRQF_@WcJJ}XGL^8J$r;&uW4SM zVBRJO7lLzD4>eA1bIOCHv$)c7w>hgYy+H)(v!IcBLqaBkv@(&R&@F<zh-jheiUNZg zXp(3k<z~0!f%zP!oB7Q)GVz=z%ih#ow7||;PjAb<TNcq>T>+zsF|0<uS>*ER;A7W5 zXXcMS-gGMNRI|W0Z0R~gAoM8p!{I*vNX^LWR8mbK5pf@seHqhph(Krn-eOuB{We)L zV5jn}birK&`%Y<A9KTr9p8N~TlO_*Zz36wuv8-jKkq+Y3w>6%X&gQ89{?JoF<$7gL zGsTwkc1d`(7KMX}C~=UG2b6rd;PXKL#Phk-tI1;#In22cOp-Z5nU8Qma!NCa=8xCp zWUuoPO|G@|tb4F@P?W+0X4@$NP=(jz9)^Wfzi1Ts8nZnxMSjrs^#T^1dCMly);+_p zZfg8hWkKFabRASQ7d8~!eQ%p~FDgXO!c*cj5@x3GzrOFwte=jfts}<u1H>*<9v9_^ zIt1kzhKQ&70ayglKFTLv%p{Cv`^K(V-GH(Xrrd<CFL&Zh4_^a7h8+8lRaKj=Oa(HL zF<U2^^ti~G!SmqapZvWqO4a1t>EJY`+R)@V(r8xR;|U65?9)s=w<cV^oGTV7?hDJz zj{_`Mzl*6eYyF_`E)@NFPPS!9hFYv_A}ytUe{esJ7LEr!w|YR^2B7E>^-_-@UIUD- zLdRu0+;wJqkZT-p;XT998R9?xTj4`Yv-8e!zQ&OP)v%*6r=oDw?}&Jfa)FZ5N!TAh zoAgn{k3_5&B@5ufSbC2!0gGBDv?yw8aPD$F#tfS2I`&9O;sOl*<EQQSUbM8Bf~4k` z5EIYP^<;aHIEV#Jsf0k9z`>D|n-1Qch)mU6^P~nDt~UhqBzEnB-2H6F=*DB2|Lr7D zCG)adR+VrPdTPdjOsL8}ezhLI;LS|B)NY4B(C&aV<)_foK|O8yx74yesV}sJaVmuE z$c?FUNxhK>6_t7cRLv!sJs(W!w#q5f{rpUuhSpylHi<$Tn4S7{h0@F4fgV5v!&e}- zVXv{+8(#p>r_}Tyl7=$Ox@`L3(Dw3{6#r>vI>RU#!phxA>Pa`pHnv*G8q9;|19_jh zonV|A8U17`MYPGb&AHAzChf6RM?`;*`FcY|iBr8Oo}?#%@WFx53J(%PhSM${8tv1^ z4CGP0>Hd&DM5r6EAVu&W8lMep&|?}+{zA^q-SGkxMv)>Kv($n@%0L#L4DKszqNBWi zPqiXV2&^_nv$N?Qi_J6?CJ!ast1FwWRmF_~*q?O#JFT#{KFn8hGU(Oq6<k#BrUMw* zw}C#xUA@2_WnIFHBAh6vpD=syGz4M9`!X|*aGd%Zeoe{TM~Y|p@XdaKZZ=%Nux)8& z6;%N2mXB@<7A#~;&?=@WhZzY=s;`8N!ku-BHUag8elsVodjsLUB+Wo?w!BXSM_*3U zkVfl<mt4_tUqT#l(X8bC(84dl+Q1M}(g&XW@DQavPVuZ7P)vcXp^2Z7?n?0#(PgFH zp?M+U;(huniK?U5JERh|9kAi@s>p|~J(~a+-nNK$WRT<4dx+aEqd)XhWpXU3xvtLY z`FLTOHr6E`teAkH-ajx^{->>qHLx}+jhIT(B-vy%Gu(<d=2IC?r8%N9QrL*~(bqiH z&W)4>mEUhI;U5f{Hr-Th?`QUURkBO?AKuYODeSh*OC(+5JV{1oXnTA?G-nsy?|%Re zCv7|LPFq-Z>&Y9VelOnB%lC&=%a*%zp#u0dRssG&1B2Mat`T}fpK(?sU3s?r^Zf!V zY5Wt?W11}X=v#U@GTUUF=Qmio54rtdLI~3cr^N!14PYK~$)Q^iO6n4wYGvxZrV;HB z$~rvN4MXm?VrC3ACG~61s}uIhSZM$_-T4s}V2lE?_`g$(H%dp|OS$kZ2bt!Me67Ev z>QJz`ibay^d!gA5w}WDf(e8jYw?gSy$&NIPEVEbb9UfPJk-Tn?VM=bpw^BFS40z#6 znMHp+8JV!<Og|~CCw_M$g+)V2F#W5#Il|-7N#%piG(1&{4m55Yz<pNO5w<3@BVp5n zpxe%t$d-@c3m>=t`~StVbSnxFxBnz1G{yo2uOBM?E@=9EB?xLOB}m$T8T34rIB6CC zC(gwAPjXA61c6NNqXK~kVCnq`WA1kPf|ekrH&KiIuoyvit!p+E4X?xcX97C%CM8v; z#nM=Rd@<m!w_PM+Q7Km?bj$)J%lDpp2ByW7#C`eS^1VJ^F``PW2VG_8Q6F@dlXc)t z)#@o^eOYX(lI&EXJtP<NcNbZ%?^72E3F*8lP+p}O1sY^B;|{TaLpQOhkQ#V6763z~ z<oFi!ezH{7Vxz1|BjF`fpuuAjOj>1IQA`r>eo`85x#W#*gtq5<eN|CwzD%OsYu;<Y zl&pJx_Jk>T4L4EQ0(BHca(X@eEI_-|fx%zSAiqA1A-&q{&HVKZ7qM8EMM3BZ3!5w} zr>{enAsyo!+#UwNK6RltB*TujU~t>(?a`*6_bD~^<>&tVsnz-Vyz}Ym4~zZ%4~;p` zlq@wVN7>Q)i^yct_g<G~5r{o!QcGyjrmPG*W3FXpO*v3$06aUS0Raxt)C>B{$ffq$ z8~hH(Jp&~clGIYCs>220DwyBlB1+EK`8gPYqnn7^-zW-jWwpUvl$#H#F^mK$T%B{3 zxj!;+Ke}$n5<|s117j**rH!N?IF215FrZ39O%o4+gAS8ae=t6Zza~LeUs9wtT83>^ zV0D#Ps@u2}=H{v0)WtB&x1lVxNu7{~+Cu2@VtP^F@#4e^dKOoe5SFZi<3*?ufTb{~ zW&z~4{?`sby)Hl(k^h}9uRjACe3>x`nZgswt^M0AoNK7G?0LbRp@^rzUBSIp)$pE= zWLYsv9w*qZAd?z_>Q3s?c#<gbWE(A`Wr=PORf0w|J9f1W67%&@s)nU~zIO#CLZS&& z8!KRWAS^0$p_~h#A93BDqDd7<UI`;C7b~4ex}FAzwr`m$(H9FQ1cs7U$J#M@0QLIn zFkTKqYAId$0}TQm5jl%`X@Rq+-V1u&`(!jAbElyVy!n{zU~ga94nZJ{Ya<bwcs)5| z<2~e>7#J`;$u99uM1q39xRMt4XJ;noszt{^(BHNCfaNIa`j~Z9=@Q2G7TR%*0QOJR z4I>tyXcvqeR0#pdF}18mjf^IG*lz$S*&7~Y#|V<blRv=3oh6csd>wyMThB`iI)hzd z2Fk9KaUtOz_8&0*2i$<kVW%2g-~kZ@)qZD-(r0MvVqB$N?n`SwenOE?nHCjFjiP+u zd|`G&VY_|zc?<B`@saT%*BW>RBxtLVXD|@}-RL^RxNJnwLfi@2kcUhm*Xh?#vWW`4 z?KvyO*f0Lbbr?!D9F!s$`O~0smjo%26FWs->YGSLF0%qgK@ho4*oUw>#^?`_zfhTA zJD%@~;+nYR@nLv}0$IWaAPOr=L>e{yn-K<%IYSY^Zi~Jo*y}ml4~?W^G(hx{DjaqI zDYVPk@Q&pL-JI>K*3L(3(H%iGKF-U1eFEe_G;yRtt1^5x-PxFNlb}edJkTY4rntRB zy8&31zcP)sYJR7%Ml;}1M-}DPi|lJbr?BbmTEBIS%_)QrNI#}nGCmQSfHwpRF4k7o zqI4Io$V&_wZL;uUG!i27MBtVZqL9M@irP4gR1oIIY3?@*-?OGF&TO&hO2T<#16pNc zj?R&moz-zt0BMZYKH|d_e57D{+ry!CEBTvdTgH5G66C^|eFlNYxK-tk(0i{xvdk~C z&IHy54@Dfgcn5sk@l5x<1re;_Rv+_$Eha7Jjl;jt$dxwDlsKq}KO(zQ0I|M+DEUwj zgiWxZ0w!1BD|Q#Z;5b;;sQel|OQ@VuJe|4cfmB!BscX-FP;NOVx(6Bj6dG=NAc^@_ zR0NsUS6Kb6Q{N*)&pZ26-8SHObI27Oo=e1{H`FcjWuDwG+(^PCgS;`q#WvS|zhJ8g z3|94HC{|A*bHg}}ULs#5-h03S$Bu_1{ed<*6v7DU*Qs76m4&8&QCQd<AcU_lL%(Dl z%esTGIfUrsmvb-S20b`%theP=FwGHFEekyaHUe!SI`j{mVZ}${Mz=;0KJ=evKMt(z z8fD*u-;V>em7qZt5Z3R@(G3c~YYkJL4rH^0vu#G;qiZ<fCiG|t*K4`}F%njVJR<22 zCh4GzPtZ+RZQa&f?koZ^q5ueTZZ<g~V&%^qV4=lw^?jChX=B_S=av=f*~DEtI_E{j zPq3&3piK=j&=sy;(Q|Y-M&70LF6%ily=%=-2D2a&2<diKl#PZM4BR^+@=nM#Fqfry z?{9qB*RP&*TJP<N3f4A&E6CRI^+-L7fpMF?E`0kREm;^8N_HvlbeyG)QD5fe#Ea<~ z69%35Mr)cO+PnNh!X~<*$SFnX<_1SayDqYAq2WRuj3E8u>o5n?ygj7=euWqFS>qm^ zc-4qrp)&;?Q@azsO|?-uGTM>Tz)C<BeyVvJ+9p_ufZI+;?SU9zi9tSiV_**(e~48d zc5g<UW$o=u@uDRpb4?qvNy@Q08uIG8-i8t(!3lJP3R$niJ0QfTluO(gMKI1_K%nrC zF%rKYu*91C%SG=l@BW+;hjg5HkM2w9hWrTMa4c-GXkc>u2*+1=Sfs<oj}JEp+p))X z@TjS=tRrWVv$;aF%(r{lz2xzrdxy<AA(c>;P8GV1r$aL`%`2oswlHL#xn)Rh4y3#W zDgKDA0cOf`{&~CNmEeENGHnJwo?p=aR#sqGL0*C3{!h<<VXrd*^iySKN=IS`5k?=Q z%xZynhHwRifVD}i%?}bZEJ+^8Ot)eOAq0j`k75TQ0=(Etj6Hy|_^`Tj>Kn~yA3&!_ z*r)IoxTYTkD+w`<I+H~kgUpnQkYtX-`QHPY4e?NnIiDoHy%m(4g83ebP^UMIqPYgU zB^-M6fcQ}1xQ>##iZr!R-JmVz2Xzgv+-08*N|VRb;!g+=5;4{Y_s6Qoqa7d95l?{i zimPOF0VwZ-l|{s}>7@;*#I?5dC0#*R<%(I5m$DZ$Po7Y*xP*zvbEm1?QiYmg^wz1u zxgVv5tq?8DcQaf36eK}H`6F%jI|3Yc=WPm(Z5^S2+N6UF8%MC<xfj5x%UMol<AKDL z0k%0#5MKj*ke{%jLRwOgN-%SPyk{^<6KK9BKxjUKgGdKev9WRBSNsIEW(XhQuO)EA zT34A)!i4g;7{N$rx%oq_AlIlwTQ6|sj$g}$m9pTIj!E7(SmPGx6SRL#eL_EdE3T+x z`#VbE9t7E%_GP2{FROVOIk%8Dnzf4Wr9)3D56n=4CzYGgnBvepuB4{tuc+a8S7g_3 z0bbE}VY*?&4F%zCZ4Toqp$3uI<BeJV7C}=zv1eE+xD{9!#>~E`mVTLE;jq=ekJ)Z7 z&*8L__-Hrs#3JOa5IspdWC@KyJZqZs?3b5MB97rz;h65g=)*_3?Ak6{#O+*m7QoXx zn0dbQc6whA?EP5G*~`s!@hk4VP+M2D0gBE{e1VT$U0=w`hE)%ETYKWx)HTNR@XisJ zuH14%Rd<-e*GDA7PqE?C(r)w1yiyDsYW=2~cttyf#nReIZv3|3nFb&Le1KP;fhpz% zV%mK*%d~wlnEy-esWw!lz*{4X^G&r2l6-u!w}-5|3z@QwPrIW2W7z~r3r~C#pqZ7i zL0f)MtCrkup+(#~Vr0E5T;}@EK(*ehujj66vdbkAbFv(By_;}tW&4!^xtXcQD(wdE zH2cS2W7*ihBjxSTgZF)s|LS9!v93&LCp1#OpPzT$%paf<a{G{pV*vdA|Jp+v*_Ib_ z&KCd1wn;0lewlCiZ$9p!G6I)C1Ay=|Eh}3j3RJ3_woq#>-g({9lfMBE{(~A~BG;_t zMmW4Hbg3{>BKM>XvDV;`>YjwH<)=hcAnIvVWE|4(2ng2lb{qfDlg#*tHW*D(BJak7 z%8*wM5`x5+80`vE{aHg9E%}=9xn{}~!7Mz*-f_jA{(3++9@SapJ9jSHaPL^Pk_**# zw2*#2nKyZT+tU|A@k^agu5GzG@-cjY{_jUWwv(XQi3tRxq67qln;xJDf|>5m4FV1D z*ltbzIr`teOnz`2V<{84B)VgD%`JVs`rD7zqNz(eH7E=djs%{INKy(#;@j^QR3V9k z%1Yiv{o09>(9y}sX|LVzxAxjk0j|?}ch#-Z9on8!djky4%+E<l730*x&Y;FdZM#OS zixn=GRY6ZBZN#e+JvNCax=dfJ!*T@BjVk@KttQ_Z>C>FeCTpTk&V%&P^L^VUvGEr} zV($Cv;mM$U`LSm6ZfI?!`=neWbWve1iVfs|pngR9^tQ{5>h&etO=mfk@-_YCunT&# zoF^Gi+*Ge-siq<TexB=kvq;s7el0c!2F!3_O^$hw-&QFFdG%!V<1@OrSYrdQ0O%3$ z_WO94xx6Mx7pB{3z<9Lrxm7DXB|2FxvaEwC)mR_bo!*jly=E36#Ii-~Q@U)tGf-`$ zyX<(8-))x6x>i~1prtDUq-Xd2BK!O237Xx&UuPS2<@t9&C|+btN(-A&*hlc(urALC z@o}(-usxWi(#ZpP?wT1@U^xx|^p%WVpuSLJ<>rczXNo)vt5=@E^gU`biMBextPvK| z$b!Rr>3H6OOgo^iED=>sOE7phqqIFKF(Lunl)kzn=7Ppk2Si|<AEy7nn@StVov!$@ zh!*(Z)ogiHsob>lM+f)ve4Xua8{a#t&&%WQ<O-`v_FFrO;vMpyb+8;T*ZZL>fXDkf z$cvZJ>i2O=4L~LtRjB196U@#xW%Jo{b#4@qBP3ZNb4Eg8h%>QOjF`-!0;Soxt2(~W zJ?)sb!dghB<f&Xd`)pK18Y2E3_InCjLkMUt!P#P=O2y6<KBSU;0s4SdsV8C<0)}sC zh_}E+=|Hj{;_R1jXhkG|`i~#K&+2sgNUE<E-9;1Yn?IB@nwK5YgJ9~B_b+;&x2^l^ zH6LmAP|E21VXntNErVq>clXx|TW8UqV=9_qL%@<mQPAn+i2_kvH-%~C;)UMGvS_;W zg%Zbwxp`}Fj3PQx;M+m<K$2)P>CXO<p!Mm<*w~h6bOVG9*hHIvUr1DEJ;?o3*Ua29 zFsVj;vMFYMbbn2q(*}E)4jjLRBwJ!|i3SADIpRf#v{?_0!Mn2AkTa?i3Gu4g5aUz9 zzOKdVznvpKGS`&U+J037$tT57A`46PGsn|sb?Qh+y`7VS1VP<k(w)RYQZvw(SgRm% ztw<*-Ak~2|(Q+&RN>gmYpe&P$>UkGmeuC{dC=I=%Mhv#7vbyLXpNw9BiWK6oE(`UC z0d(jCbjZw!mq(zB2L800O0YE87x1>TVt&zt6+oy@!`;eTC?I#R6et82v$En*-$v+# zDO9aSG}5OE{8y^yh^uIxR=P2~u!%V9{lv{!`9%0@BmF5rc}L!SVnTqQ|I-z@{Fg|x zeQ|_d`xfmNmpq^%nmQ0KHQ-&Fy!m7t9pzB`9mRrRd~aAdx1lPZ@#xqY$qWng8NHc$ zJ(O0dQCGI8M?kFpQW}5L$Z}k$<#5aOk{0$amE9e5d*5uwz#FdBhU<oIKRr2(Q*l)O zF>HCJrY<_5U@?3;XIe&#JxDXJfu;46ls$@`-)%i;9XI$Zk3nfP<2^w<$V<+xS~3O0 z4b-^JISEd>N1RU6<GRyEYg7^lPIVnGfD;r#{k&qhG>TlVU;_!a1`7cU9nNYptn)f6 zN`Kvb*s=<3CI+&cG=|#A@JX<rY~YK<VLs;T$z2mrK@0h3;+n2gnL;pwN_ng}8{%!i z{x8ujCvZ0$5OXz80&Ud*dbf$?U<6ZCv*46h4{ZQ`H-?g4py1(6!T2;!LQ~WUZ9&gy z3=tWB5C#0ul8(cIpIy{WnYJ(j-Z$g0iuMrKon-^adrf)}1Ug4^JT;YM9tHQFs0Hto z7B@5iW)z3d2~xtBM4Ie<>W>qsh*2ez7+%_M_-wAu?OQru8l6DAUSJg?zOZz(YSPER z5v~YuXhpa%vr-?4vzsF8ia+3QBevsURT_w$f8iy#QP>In#zV{d6iI-wtU}|`EN8+V zm$P6jQ*G6BhXJRxkZ4fhzbfrx^Gc`Tw)WZpX^Ik0`po`a{i@Y(QGVrhjVg>HPKX0e z$c$T2N4Sj5FziL8U~_QkHAbOBWEE4r<{iP;Z+dQhT91X?F?AW71v&|wVW2u4Aa)^w z)k;yjSzJykX?#2L`3(E^au2rfGBuJz$|XQwn%VmTvk?6Ny81;x{t@DSALjeWS!5L8 ztjnXGaycT2IMs?2{j6T4V5vw8Xf-Z>v>;j(bQhTOE14Cj1ILfS$ix52`YvHrPANG! zP{4_mw{DnB^9{ZPM7?vlPD<b7EMT#M_i616a+0b?A&8t0t=5$p$|`Wt9O{8loA8!4 zO5CVD^tZ1dlJo3%lhS2Yu9YX;LIEX!>oDkb83MN}Rbc>sd@r`3YoSSbMJ4CX=MMYA z=J^mxW$@?4(drx>7OPwLzk&`7{EL%INX#|cN#%07=*T7URxyHI*(rE|8vj?E`kedZ z=@tC?iyhhx>Yrr*KBJ~faGZr5S3#nHaE6&+!ICygNLa&Z=+UsrcJWwQyZSOf8*)DH zad%)2^zW_{O8Y=#X7I-5((bGg>xWM>XfG_~49&bpd%QKG?C``=z5w?>bL8SIDTA-4 zr)&?2xqLhVxgWOG03br6+%he4h}m8w*@po1Z(5MMh={2s=W&(s0;sK9EIQtupb?Zw zkSHG+=2q7jSd^uN!xmHH|KsW$!ZVGwbsO8ZZQHhO+x8#ZsMt=$NyWBZv29n3o4faE z+<Q7-XEnaweAb$C%<=L&&;YJ-$}&ga<NKkZt}Cmguh{}64A5cHhYe`L5WZhOurQ$r z#6wV22IGNGs^MRjLd)rGPWKc_$zsG@uHff4=LTcBxy|n=ro6mWBlwMsT%@C>;md&V zix7jE;uQ8@+*r=$C*=}@D}(3woW<m(=ul63M9`vpz(dbj-cFAx_5lSF;!$$_6aH@X zLU}?MoxUitXiR`cX$qfV9X%6#HgHk;gbA2Gaw8;J*2o>A#R0bHs8rHWJW7o89VkyD znzB1U>PK-}#*N5p_oy$1{E(LO;bHZyw`E5kbKLjv!;$O0(Skf)c&@SG!q6>+C&MsK zv!~-(DzNeMZ#=)SRROc%<H<U%u^Ax)vwy0FpD`Pg<EWh5x9}<`*h5(-<i`dj6SzcQ zps>#qfWRK1XI?CoSf?#k!~`uR6f0}(f<{G(ms1~iL5lS~%!Ec!onUq}FFaU}QUis% zl3-IwEYsgOqAcOX2q`4xXEI9Q3}fKBFE1#zkn?@ltua2b>;UWsx5dA`f^f9To>NPl zB#M)+^eh;#C$kmkdb?A|uF)N^EO%TixLu&cA2p^Jhr<r#PAGp;Rm4~>>@72CE;P)s zVY*^OS;E67SM)}vKX-mqdh!MDrA0XnJJH8wKzdF8Ah7=28`_JxL$k80RNRI^6KWwI zs4^jzL9*!CmjPUzzI45vjY%E02*40{Eb2k2&YOB;13NKVX=XFaAAmhpO$9UY^7BC0 z=k48re86rC3hD$;36PF@W<*82Nk0<px!k10TmH-;9|){CBaNSuqB9ym2PTM_1UUIh z;RHj&e;2ebw=`V$-2t)2XX?s4QOF`WE&?;>J{G=Yn*vfGnfi86ukx_5=Ku8Z`Dq?G zM7==jWXjvE=bP0Bjpi^d#FJLa00lfLJa72Qe$Ig08i>(N;+?kqdH~5A&oMcEZJNzL zl_M|P629mpILT%*D0OY*4_PKCMvwX>YGXY$7W2H*vrpc-4}$s&I28|$=Ft<1&--J| z=#1auFb*(ad3Bhc0jwVQvpIFm`*$tDsP-;i$k_}vg@HM@N>QiR5J!lmQV*~1m2sMY zc|J5^C>|p;UL);R?;lj<UlOVV9d!FGJG^-n)4-9$1RxKfsw#Nn#O^-IP8t_I(y;xR z4M{Jv5x6?>Q5G`vt07IuL*E*vG?f=_jG0K><z2wyXn$E8HMk5i76#aP!R^V&fT<vW z_l;I{%kNAA)4@N>Slo5KCZi8F+f>-*B(ezZHQq#~pi9hbBcLjhggo~h6RBJL&oa-h zm@z~#ozHGp2zzj>5(FCdqWf%-I5mS8QgxvyY_vkpGKQA~kik?{#lR<X1c!tnHQS3k z@jQTec^pfwr(mhwzWg;v$C1;~5MpjDX63UvU;Uhw^B8Z9geLVodx7N7371yU{KBjp z1r+!ofm~9=khY-5FD6DPTaI$m<JsCZD6J&SzG^fTVIcjqKVySAr6+a0<+saJht`IU z_hkr~i;alGtOR@$?+ZOSjwCl@LJd<9km7*gMc~cezGly$h)x6?h$bNrz7lHA$^=dw zV*h2Rpo5E(T@}|BA$tGNz}7-b7zv0?v&W8<7r-84Ug(-wD96LkpUdGt;+9++CG?Er zXM<TmoK`n<beZwU#%^q*Y0-$wU*}^YB9UtdUhasBj0yvb`IzjR=6m?>e*rze=>Q1L z9+{dexR;~@Bg-wG9=Wz$h)|7Yr^b)K$Z(oY2kB9kgqNr#QG{1=vO=PEn-6Obxkw!! zQa&^7cbM`Bv0wKV73GVT__&!`yFcCR63PXiBv&gb5mT9<b&c#lDT*YWUPS9b2H_He zcZ^q%qq5^73tNlgNsgA@CemG4ivc8Xw*})n<5IU4bz|fg$|eOiNhBd7PKh^7qMqB( zz08?*+}tIk!kcM?Mq4wLqX$CogRCJ8vtQNgIUNkPk!g){&xG7!m-s~MCntJ^ft14+ z(;bmWm`drc3pNxaxE(lL)RNo5L)ITmV<km_3?9T<g~>x$N#HKVo!h>Nr+`sjth;y% z9*|ryYZTG4%G?Rr)oRWx&xnjCJ$1wj0m5ep8$fNHbU3~|8;p<n{)LBI`B(k-E3qUP zQ}VfTpOljWFrwRSpUv#pAlvPw#~<tl4jsaxxm_IA0XMeT4liJzC%j+>{TE<nU)>zc zf>BNf-I}>VMNU1@K&iH-J;2!fRW~G8Ufb0kEg(Ga&Vzv<*yvdYk~G*vbOLmNnVZJ^ zz*s8ntqo&B%tShHF%{xpHMt_6)8|JrjZ5dBoAd<6wH3R7rEIwPBam3W<23X9iRXRj z*kHfFHGzBnw^BmH!8vtKCLI6Y&66{PD)?Kt_!D>?V`O#Ygmx$f&wyEi3BkIUW<{## zdk7OaxA7_>qe3d(=p22KY1ICw2qPy}WbOp&V1!hm(>pOkO0S7q12^tqXD*bx1*dG} ze5U$t*SAC?19kD8E7%9<8Q2W%KWmGlL8bZHpWIvVGjwFzQe<q43X}Y?Ot>8F#Lqao z+A@t32TvFt-rAhlzJSsR&JJOg3x|goz=_BwhejrIG~0SU)d{oejQ?-vo>4YcADd;} zx)#Y>8nr#QDfpV+c4ZE=ER+{|2yeL22D%0OGH+Ta+Y&(LR%t_T{@qqb&dxHNW3I&# zQRkl>(*$bRAslXpY=x0^hKm-Ty&w|RAokira%Flf0iZ6gcfh^{EBuRRV+dk#OT<iF zV~9gf;npW59;)aGby<5`30%chgnk=Y>OqT;`mZ5Y$A^CbeM;+L+K#XU60<=k5B)^$ zR=4fBp{@u~eW6@7IJ-67V`ksA**L7}H^QvVQ~-}jdgcXSwAu#6%4-hnu3<p|$$6M0 z7cM>5PH`={Fu;T47xEHS)YvngTjmE$7E8jHpc8mNZuiLp^BhrtbT0qlh@h(SiXbvH zX4A+iX?${?HTMS-$CC%j4sjS5ZFTJBk*>tF^~WBE4AphG)9v7u*Ad$@;dZdJ-Ip!P z)hq{iEC`Wj`!!DH9ryZ3HsvailSs==V0e4vH|Q2hEnu+wGeu!g;7BLY!?ZB-$PV1h zc@+Y9EsQ2~r2mxE6-0FO3SOtc9YydS4F~%?vlIVU(PYtN{8U5xw!YeKNr}(IYMRDe zHy9sj@Yn&1NEL)6S(qXF9H@%gL*pd558Q4PTT87kyu-Eo*5lHzo@X(A*2~}vyl&jm zN!v4T7QhGyPPTxs#Kl{M(a!6FUiQR@8M5j4AY`ZI_wwexvfQ?@J(QJklV(Vfm0g!@ zNc+s5g2dgm;hl@VhA&hKtti2OHv?kceStj@zYL=An*z5X5lH#Y^1pvtW}E3d;c30@ zqSXXqt$PHB7I!uckpXX6xuEi%s5ew&t)vp6Kk1WPl)9XZ8J-t2YtWRG@8zBq`Eo0i z?P}LtcH5toX*{(pg(xIO9{~=lN!JcOrd#m&Wn`WTNTcBd!t35j%VX)T1u@;JtjuWv zj^@P)^Sx#WlYw}GQga_}VNMtJzbU>XUGD8}00cMw?r%-rbKmk!-9Hs`<8bGFI28}s z7tlf~m8r`EsoYxJ)?Upr)#8h(o)dR&YmM_2Xyn1^qahBoWpARrlI|tu6J;$f-zbGD zYs;g&>?K?~H=GU!X||pNL7Kv`>yw2OMKK&Iurjm|1+4*H4|+DVwUcnWF4riim3Q3a z1gnaZ@>0{inbrxycWjrq(-OI6)7cqT1dt^1moBRM%`Zxzav{p7p_#N-p*@u@<(@Q> zFt0j6S^+QTGT1LWxB^`P)t~JMb`5Sv%r(>WvMc@Ob?9HHMrrx}Zg}}k?8ohv;BR7$ zth&WbIJ7){ETH}H{uJggbQ>%D6_#8N-wDtm^ReguYO<}*<H<{p+ZFir*oax#2H1?4 z<ms~IBu#fg5z<l1mc~hVSs`th3t=o@Yj~TBUgO7a0&n#wiYQ3jcEA43T(}@j7}D?G zCXDEMWb5(Vyl3D3&d~bLp;(_lf>N_QHLqjo+3e%M!d3U!gVxlv*Y|bRC)?;(0~0Uw z@viO0I9L%5V<LV&4Xpl`A?uF+BA~+DKX(f^-_F%?)s$?K;3imqGe3t<fE^yd0k2ER zh;~(%&D*t#$;ETXsYC%0G1UJlECat6#AOv50krs#%u$QZYaYfDqIwat6ZY~?W#XPV zrN4z}{S#5nF2avpb7ME&PZ!uH`-ZyjK<MUu2-G8jp^|DcR(A<s%gNw?7yt{$y0rb- z!>h#$OKy$E#Sz~1QP;^P1LG&HZC@25tU$dE`1?<p32OWoZAnEd#j_2Q=1|`JzZ_4s z>%2C^x;7LKSAjwE3opJ0Q_aBS<iCD{nt)G5kqngX0fW-YN!p&N*?h=)L)Et0hH8h| zwAu4m)U*s_AvgZJ0XPjDT!5*x=G~`lrI`0KG>rOTV?T;;h}q<D0@&PWjvxwg?Kz32 zABHftch%!yVwB8B*>O1QpyNdr%d_i@?gM(d*3^@rKtBG^d|I@L*9#WTKC~qr*Lit@ zcq%x7p9eZ&(D^=toDP+I?};BGwuYRzYbupvdR(es6kIii`-Wn19YEM95~sk<89BFy z`b3~`ZsN6(=2)#v%6nG|UCT8NJQx0YbkkoYNGGr?CalDF?zoAhV%)V0HSG5F185RL zCnVFVJnN_-d0I$Ry;!YKaKm{%N&<+>`bl>!hAEVtK)kIci{%#t8u~o71O^t&%{?z2 zBsTe53mB5$pRyRAQNSO=?XHmvcBurYm!#LST^QNhM9oWER53kViyE*gR!4Zmx}b)~ zyGLQ1?%{$o17$54qr`-lAy`3y!F2roX9eN<X-w|R?AnPlR}u_flXKa2W|cvsB#yeB zF3#uDFRb|*c@xf{%Wyb|-i)1(EIB53^E23xQXIy;CN`c9U;ru~W8#{NS=mo`o@$Z( z0j^mkb*PhTyF+nPQ{S*4@8Iin?Dn(8BLRu!>4OkYXr;{|T%oj$joSDTxr3=ldu};n zMgba-hn_?{r-TLb4pbOtVA!$a0;d|39&-(K?LcSBb=zoY4YWUDaPUGDvV*IdN$-;| z3c{c;3r+P&DIlc@hp}0sMa-4nmM?0Azi1JyYFW&>BJ#TGZ!(;XqEWNtuun|mZ{A^< zq>MSCrZ?m06_`5m0EQ9`zxuepe}~0Of6HiI2V?O&gZmCuzjYn&}by^IU)j@~%j z?Fn>0doKHDk6=ySF8F#er<xFcoFw9TG#2-Wb3Y~yF#<UEu>A#TOB~~;-8g?PU$|G~ z0_Kd)j^ApQPI<4KJKO#bd~f%6>4x(9;8Q5x*iR_k&7x4QV4>G;@34laz80{o+B^2m zX-u(Utm7Dys{<yg*W}&7@&$k<LiHj`mQM-@P_xqvq`!`vX8p{1A1I#rDilP(4gy$F z<u==K*#L}|S=pi6VJQFI&fqPoMDx$-78Y9+6hA^dzoey*V#iJ)EIMtpS@JQq?FjHV zVROvlhBnR0OT{w{CzN-_ebq>?Rk@}S>C=)V1@`h6Zx)~XdoKQpr-{RtMt<}oG$vbv zcW7)`NceH(17J2H#wpr)5A+ElJdg48HW`oE5rCi(aIEtgD>wik{O%vrbc|v#WW+jc z`7}Y|dO1a=A`LyYzglX&H#$@r_VSraC#T;<93*}VcyufU|EutbobujF7ODfGja$Td zL6lgvW~o0I3)rP5IO)T6`Iox%1qR-|<HNM}`o9n;T)g{pyC3jr9~k66z&X-50a9zB z5{Sot@u!y)zkVwSARtndbfi#FwDg~2sB~c!5E2lu+jMgkkP$+Tnv)lUx8L<Gav{Xl z9XfOv+SECwoGPo;ZR2wEjF{;%svuT?PnMzg?uVzAjq9Olht_+>H4JL370t`DXS%aj z>UO@x)}Ephb)}f79@)&bfYeM&lZcGGK}l+9gwHwZ_n_H(zkvWdwan-0{mXyx(9@w? zoM}sW+>F(pmj<uF{szT<TIBI|w7z^|Q2NjerD8KgMdw7+I>G2=$#j|+GC00~!^;sS z#{_?QU%x)x)0|5D?s3Sr*&6KwGp6I5Y;Inui$uyU&qw_rwSGagm~|Og$uvnBe99~0 zst2};+NZFHd$W2oLfn%=i-c(mfw4&i!8Tn&e_;gpfP(a0=zam$ZR+|kOn;ti+|-m- z{Wq-1NRX%n#nOj>u|j>Kz4-?KnM0<Zf`({OqWrx;PDG^f5refmdm*Ih0T=S^>6ZDV zaX2?W{R8UXKnpt-On3M$-l*$Wv{$zTJf^qcIjAHrPxrwRj184zTbLS)-X6dA@aB-F z3l%dINCrCK;C5UKsAO4S`dA8z+;?ZSY}RFZ$>m4?00}@Iy2zQiX59rKN}N>zdM<yE z{8OXv4%vXf)0b~lUqfnX&|)xo;C-Dup^ZO~x))Pp@Z*RMo_`#TMARidaA`sjo+gnz zfi;*je``~(M!D`8<p`Z-raigvla0#8>l()$s8<xP{ms!UDnyA~Jbe~b9$#!0<J4oN zG%l^DA*;aCDgZNgnoAFGVT_y$+IcqYCA1KHSLT1#q6jUwMKqjuZ@qrDXV(6{gFAp* zd~_s4c0)!C+?hbEOo=GAHJVtFh7(BI;{j2eUCtYfdP6SO+}>Q0BFwHeXAOZ~f@`9e zgX82;Ae#UL&b*xF1n7DKN0_e|#2-mfS=hg7ZfuY_<L2S}(W3w~lx!UOwD-#)jjkR- z^;MB0CSH!N{-WWKj50H|b*Ke!qYKai`&ITmsT7B$or=m32A&s^=hcVcm6l3sMWPI5 zUyz!O!q^lYf(HmKjH!YOqBAoSYnPD6*JX<8mLWtdPt7t7#vAEA&Q5W(i(#fG+uJ@o zzOKynzFXiM_WA?v{=sg;jK#V2y<=+>bzw?k0^ivYxDlf@{V=BIb5;7rIC2ykRFsx4 zV-a%8$cI$0b01We=7;Q%{h>N&q}!fmof!OYJ997l`oyNgVL5U=ZqSV?8nx`M(}}|% z7AwnmY6``AOJRo9ghxEnIo|7;ep!`+Ez;kn0^yAgm6U*-l;5kFqLSnYD5p=O`Opb% z4JFFi0JhUQR-Wo`_yWqd;jmGNVnE#zbb>F<G>?7t2^^9fQyC|roL4;k1qpJ8_I<WM z6zs3+@Qe*_E3gh*87!QK!K3r!Th85|M-SXJtYb*^U7U?2&f&Xo6tj}YHb8ysk|A$U zB2hd9!yllDmA2|qPIqjMo-PArn7e>q>UNAW>JBuL33&}XC+Ntu47|vb3xS#Z0O?)a zQ9Q_gy=;%gQw%vxNd}(iw7B)R7(kg+*nw^GP(HGo%-J5w_}-IOV)K0g{mu<E8&Z`O zJ*?ZhPSf|v987QX8ChWx%Sfze69G;C!tfz)JO+TlmgfSNx)thT(c^Mrr{^+dlohgR zVl2`{-?PC5)10&$vXX9-&`<g535>#8!IpNC!O0vMH68K>pDTw_Esk`?bB2*muMI3m z<Jro!QYe-gZa2*tb(Kl!X~1+CvY};up*4Lq`UIPRBBFda5I<Sl6sH`?2>8jOV_p^f zi-FHUxp?qyO(K8MP8+r{Z212Vq+3U{K#=~2LRr@Z`2zbdkg{n6!u8+vpmZz?5c~gN zs-jvl-?8XGK>SMS&U8QJ_;!K-5irbW>$)+P^fS9gYODRVS!~R^9cTKN`H#VCLlsx! z%o9bLN~IAJR<u?S76ho&ar?(kUFQiumQ<rBr*WD&QpVZYnddWGM%fwkMV+^2CLit_ zyzP4j-CI`cxMKBMg908N-dzjhxdxg0Mw5enDqZHMz17<r_s+m4A*^yb7r-+Q%{~oH z<hGH)M}r)5x-U6dlTQ2L+GyqOcSqGmOv$BI7%V#cfSi#!7I?kj6SN^^jYzraPu$3< zxJP2ynQ-^kU9BQcfHN@Bqb9>++A5s?R)*ss%rDx^`q^iYWvvwpo8BGn!0=k@bM+Ql zo_>U7{2hwnD!HXWOF;tqT|nn)XVGPA_0FwKyf&i!nrr-q(y6<s0mhL;|1Jp86Ygj8 z;Rd~<C%*0q;SrD@%*8oy`K`J@;wm=S`X`CELHf@}ANIvp#ZLR*kDJ6UscVh6Guk3) zE)EpDecSvM-IjLSJUn^WC`mXT_yVX;@n$C<hhm$_7dEF^*PqrAz_=@N>GgXYBR8s= z8I@5hA2gwpMbb^rO}fX3(#5aL>uSmu-cyT{-&7ZNuz5`wBws|2;SoG`8@~Iq15_DY z`uAaOy!|UWX^x8?5oA)L;!tg+?<>%)gVz~f{%B%5jkpJR6{wwX`?c2r%4eJYLr6$? zOETS6i-q?#i0*?QAi(K%1@qg_*YBPN5b$xmmQZKN7van(tQ*)4X%1>dDX9@=p@DTA z5z1ubkrCKD!3dJH&f+V1qq{wi^gZ$97_?4>QeILShz!*O0!;%2%JWm|B*=K#ht|Q= zRB$?|#R8~D2`Fgi5WL?bgo17jhL_0@#5QnFSx~FB8K)os7zj@~Q?t8YuYB#_n7)## z|Md2w^XVoX3^dTP)>^A&4f&Jj_bI!~`&|Tx6~oJzLt~LV<yJ8)um(oPtV?&F$qh!| z3T>@pAbU~!yU6_pa<7AwuhNrde9A85^&OCKfqRPRvMlP{5I^Q2#YYiQhx~WoXTn`q zsZRYBbmQy*!j;Wg0Y=vcw^Jbh^1cK3I@7ywJs3oGpmfIH){&D!bA%3j#O4QF_#fTj zKd|0PnA*(8-{s+-^vJrv-!L@Ax6pn|ba=yx5#OgD72h-oS|GB@wzH%3oW468qu3^u z2#lO<ULy)FSXiLz!ecf)rVXtRro}dt@f)Rlq)SBsI$RNv6o8l8Vl2NFSevgc2EXit z@`3ukbhjZ@kfFE`rr0vVKC0Xgh*-AIb9AI<a}DSf(7VU<rA<a8$BOc|M9_*KREO%_ zu#$Fnj9j|xqsHyEg&yWu@Y(-uO(pjn=#ZNFB{x<c5hUo&Hx&&OVA7+rK$#j(SL-Vq zU|{wEys;n>g!iMvTQNb1O#6h1YO&?nUE2`KTXo?^fXkMjE^xvdem$aDQ1Y+r1>yA7 zj^!@uuz&(}vFRlWNKRiUJTj#M<p}tGtCn$og=wIpnfOu$0ApdjzHcbmuOx=oD*$UF ztiOia_tS-nLCb}MS}Z>EI=}4pgJ;YbrvY;U2tHJVkOl}VDiJl{4f(y^4iy0bZ!ZZu z!c`3cFIMXOKKGB#|F#w*06tTBsl$VkmwN~2(*JIwa=}r63*B2bc6>ii?>wLPW)~S* zF$%Lz3=4NWS^U1W^)+S3=(m+u;zE7Mk|O(Fes`F)hXh9?G3rp+VPGo7^#0X{{DoNx zIJdB7AtL~5Zz+=~b@AGz2ER3)3aKCkJ_3%<kL$KSznONp*qk!ILZ1p#!(cd%ZzY=P z{It6k5R_H?e*G%vq#SiL$ieIOM#z-)L2z9tG~D@iJ$Di>*v#DIy9oC<<~^>N7<rU@ zRNrFArJgnX_&hvWsgo=w5^;{mCCKjq+>Qce$-Y=R&ggf5*kqRAEz_1!<7^IEyExzW za=Dg0@kMOtcV`2y%|XDnxRT5HwTEsoJb0$D-fc{-IWp34LQ7MP>{Bp5g$2?8O}f8H zqwYRXP8QBm?_M$AVL%Tkwi_QEq4?{`HGZ(2K&ldC*~cUleF?S<Q9giPEiB~$Tynu? z9>b2j$*vRql#PkF?$9yo!E<pk<@D7}v7nH`0^fpA<WTF1-@_v=tBykgZv)^R2u%^8 zC^cgLNUOuff|T$>Dnr|%YsgJ4^cnKg{$0$05pnr7VFpt#(+_#O#GLQn`V5Xpj!QJs zB)((4C4-8TE1EV|`jFvuV4~p%5d3AgLOIIz1zxqj+8!QaI0vW*7E*6JnQen)CaR<b zGo)7+gmucLe{VA-x2TqzMX(TFr6i)Ztvc*DB?C+Ka$M3dT1_R$K1EKOk2_0jVCinU zD6oqC=rKM}X|TNfcVzPN+>5$P!W37ejnF`{96FtKNlF`$S0q&+3CzU?fR|vmj&*F~ z%wPkphZRfuQu3=;Bel5;CRslxzp<z?fMVDm%{QDraTab0C#SG8f|?gqrspoM_xeS% zq&jQ3E3^dlLP+Nitj)IIY*95ekv&+Wmbwe&lQeTee8cQie$O>iD#E3uQ$<ZmxvTTo z1sqq5HX}|`e@(DTXm-X0u=PgJq@x5qiW9O8QT9bJ?g-67UFtI7zi6?7d+5kdY6oum z;RXLT^YbEh=9WUCM$*XZa7FA(Rtt>!MSaD(@%PXqV<BaiO5V8WxOL$Lq(aQ({o9S! z6rGha#~j~@u}EBbIQx6u4m*u{TV=zH|C!}>iU0*Vd^c%z*lqR)aPUkB_&$8UK}<R6 z`YbE=o0<`7EOc2Mh+Z9gI;=XiSt!yGD+tyW-2&AeXz2_{(0i0odn=B`+dGC-Q?UT{ z<x6f8uSNtRU3GNYUu*ZorA2g+yvhw_EUtQ&%PlbaKuZ#hBSgTS>?>gdR!$1(loJZA zhq&QT&2ASafQqRGtX>g)XK5*pZ^#094ZNrOS^bVosR!!Uj-{eJ61V4m4_l$9rvM?@ zF)POav!Zr}v(spHaf|V7#!!8SF&&_e2dY<I!KTido9h&(ZEl9fIRp_fs_S#GWp79s z&lI>+fqQ~MHt6q%a1Mk%jprUx3WIyc`@ngRj1U^2X5Bpl;FSWf7K?J54hC1_MLNWM z)wmt1U`(8X?vB?9P3D7`pJbb}l6iyHPBAhNA90Z|^qad(ErnFuM2cMrh)PAQRs{*< z^OTcKs%U`T7A?!k?i1jfoMG0L+7Y2-`;?fg<$S~R9&0#0op!OBI{Szsqjmhc!`FZy zY@ymlIAr4iD;^C+V%=!4kTBlsw2z>N7NzYa1DPS9emk;DT5067%aNp;u6-4WJk*!t z+^De7P^PsClGZQNna_KmX}meZ0)9@ML|Vs->-bsEe4|0}tK8*5I=4$_m`dKG9RZF* z0jVY#i*e&q1Ipc2$t28hj<n+6#9axmmUSY3rGFaN9xQ2BCN=TGW<wcq878aB9Hb8z zQggiLvO=uKKrH1i*hdy*e5X9}a#NEorxoh``auYb@AC7!1yF&h6X;_?gV7453OX5o zq(P~v8L+2EL$KpjU<d}mAt-!jAtP^fQ53y}=*2P7x~{RVcv4d%<1Z$uGlA&m7pu7n z=3U1DpNOmJQA&>vwaUM5b{t>*C#t3E`sw=eB3g_GR5!(hR8;FO7NW+&re%VR%!BGL z1lE=@v-1f08St?dJPIT*N-<wL{t4L9d2@=Rx_zf2NF7|1l%EI_&mBFb{w`oC)%<kL z8@8Q~@9wQ6$t^q6ZD(($=FhuJX()86l47s{NZ~qr-=tEy+HyY=)ec=bj3t}wiXPNa zk5byK4pc|SIPtcoqe;%EO@<^byo0|-@jT?J920Tk4Qo8fVZptd!vpK4sTrN9^Hm#9 zl8jk#NW3#qRD8VLO^Xj|inCVvdYO{I<GCU1_eW*WS_iu{;x$=m9i>l8OT={|PW(9F z)JpNk_x0f`S#yy=D-KUu>r(9J({cUD%>SSfm}@}ABW=K-*Q|pw+IsH>^y^U2*IX#H z4hs~H)b4|Hj#rmv3jq<?jU9k&1Yq|~?sKgL9vB502*I*Qx7@ekx|L=Zfw+=fwnORc zk9mXPXz=M@XenRG-y-dX_8}V~ku+Ze1fE8oR_xc{B2#RfR5yz=289jpg^q`0_~G}C z8Y?Por^qp+EU=2E==oTcoMIbmt)!kQp2qb8Bp>mF_sx++wuL{P?^)K_!q)j`d9=S3 z2uob)p!t8|ixTwHWPu!Z^uuLUmnF*=Tc|+we$&F$nCVy(6d<RHRc&Oq5=mA9`d%P5 z@jf0?xx(k;7E`?sH>ZBCu0i>H{3(~Y5UJAqQeV4+s;#3&4e&J%kQio3S@kI!sl3sO zENk`c2j$sRnjW|M2$ghZ{ha|AQ+@F~7;5WxpcHOvXdCM4T2K)Nbw{hxIr1fk;XN7r z3Ed$PM?+Y>m%!11=t{}#&w)gMSUr(@#2T}}(($#yhug$P^A!gZCiFZj-e1`VY7eKn zzR<t24JSvYqGC1UZ*|_?B(qRwPN_y**%>Qg;J$NOuojz&6{@R&MF|f^nQjuXioxK4 zX~Yxdo2>o?de<iDR3IOsyEaF)`$7n;t)ETC$_`NB0*hCJOu|S<Qf|}&w2odtfLNjt zF|X%8pwu<%Od>w=Ogn9VBdJ#mSlGc(xThzUNVCCV7oX0FH1a;0;jo!A(G+2&t9H$R z;jVeX%L;)%kkM6*ijy-CdKkmWI{t!e+8yiBg)$wqwV+S-GwzK8n;*amie#QfNqsro zJ$4c<Yv3qwA%TY4re<ORB%jUE$e5$lLqGPj$j9iZ^-uzZg?^$Z3y8M~t^4=qq<Vj} z<#7jhh(2ppm%FDfB}oro?H1}M>=}!DKT2r+)(h^`SQYK}n3~LUE)NSh)+tYNTX!}T zCyx5muRM7A=Nk;=>*=Adh42<8(Aq_53%r)WvknR#osb!LMA^3vxQ|~e0zE?J2-6}9 zre#n3v;%Jb*CIGHQAB9tmIZo{IDkW6XSRz4lyXba)p_A|&{ZU_{Xn%~PXz*VRk#0L z;rfUHtz;Vqn&T{(K{!<)6U4NMG#3ksjq5&lf!GLkwW9q|mjYd%zT}+DkDs1#xuEEu zkj7;~tw<9^JCSh-sHK7|2H`Z^!&Ni**LH}nal4sD>P`ICt><pkSrYYBZ*BzT+X?a) zqoF}4pCl_3qg%Lg=ls5)$g$-$jiGwq0gW)Gq^e;%J|c0xnJ3T1CrK-ysr=t`rtTfM zJGhBKeZWs9^tJ<hZFO1L-NWI)sI8;08}~#~Q2`o#Uj01-pu#glNpgjbuIofE&3Og- zw|ZKLwu?=_Yu9EA#%kpeNTGqcI=e^FX$PU%B<5JQ9R?F5F>b5euFyS(CUaFoNsJl$ zqkur7E_3h7cGCjuiet)bS(9NW_BoPMv1e}21}V8<xK&WlN|w9DTxO0x0am}McKERn z6JIeIeIg|bK<)QEN@RSc%(+$tCa{+149X6G1<1V{T2{c#NW;AFH7;pzQ&*&UC!XGw zkDiEU^UX&{>e?&Rjgfnw{&1;#HbAh8q_g20VoWR|^N@856_H+0V#53r*2*Opj<<TJ zEcvqXp~zBQHYNv+Hek3BXmzqsG!Du@HuN+II+pMdV4NoosR$b_8y?|Be;)?9OP1nf z?!8Hgs3+#quO5=zxFCS@i$71J%(!%{enf9V*;pZXIp|VMc_CBcDBIuDO>czxFym5Z z1Tn88qm=-kpp)^Q3B|Ksce`K>Gi=Rxj9I4-Ym_J`J|oNtp76^rsd|xAg&}n9w%|$T zDS{*jpjf;2l`|4e%M3W{Nev9MeNX{8EQ@&i)QDzS`s0iDMB^r+8g(_apGO)!EC56a z`#HzEd_jhR`<gS+CD2>eg#S5!F{Vpbr<!P<yXRr+(i#ez6cQ9U2$QBkpjzo76-oz# zEHtqAkda7A&Bwxb;X7wjzm7Y@=zM~-u4!}*==FVp;%z*$H~SHFbykQYzT(Vel=>k3 zfd@rB{J=X-pmk-^=N#*ylQ}z1>hQ`7y(4taLpMpV=j_-_dVJY#N@Mh<$Q)GKc*X~7 zt#ZSKwRMcP!c>cJ-Paj)%k<2%ym+*P148<%=u$WvA<e^?yZtnk${zeGzxCEEL};b} zKzG4Buk#cCn<-DrWjQ4PmZs#d{uM$^tWds#9~e`BVtgamQ7E!!C)%%dD!pfccjRtJ zlwVq2#wm!;4oD#P+3Q06XIml@POt=L;?#egs5^7dEcRdv`vzvUsT)f896M%waF{Wl zS@s~1@#k8Z`+mHpokYld$9RiqY{9J&;NAjoatVm^AGJIqP<+^U^i$ZHcwfTt{(U$y z6|+_N`Wh^Lf7P14BJN3yaQBRnx|Kc~ECA(m@n>iknFPxy%hD6W%JayX_YB2@x)K3_ zZ`h4U+8g9y^=?lj{EP?&6ifmqW0IvSqGsfi$i)WdYY+u9J{ftGAeJup#IJe;(DCaZ z0CM@NI~_?G0l$%OTfd=~={5S4%x?8}>qUYpnJ&*L;sG&C-B@ALiDF=BShQY64YC$F zdw-b%k~NH72Zwk4W49?soVzpy51&+eB{2KjfL&_Dy%mj%f+QxZJguW{c|U<!8K_(D z5noQn+%Hq!FL2+;H9l|+8KEg+zy!ZVN8jNHKbqj={ubDi!(R)2AaHprv`3*4oin%D zoTfEHWEgPduGX3jQ15)t7RtE|>nX66dvX~OmF^d>7(iq*?~YheadvZB+cvwbW9uEN zTKA_p-`{1zxVwe#T#V-fXy}qAlhvwx6dPan%~ht{+H4qPI4kp;9QRf~z^PIT-^FF< zGCnREnsBAj<cAF08i=2^miSSNHO7z_`*aY@(kG|LQ)6?idLx^bOmm1!?0Tp^dAS4Z zoXfu<=VYfQ+FI5>D|oG(4+lq83%EHN1eBRhq9@}(`W78AL=U;LswF_}4RbZZTpn&m zUGPP>zT?>($f8l7Cl`hD04j!RgO^XP#4S~vDw;Y3JpC#e3oUZ>FradIt^E)^Y2Cbu z{ZP6{3SB-*SHQZ+nE(d@t*8`&A?G)dgZgo<rb6poIQ6`}+mFsX1g_yv7s6T;17;z2 zQ3)C`>gpKqfjt@<q5NbZno;C)#|`LB+ygoPI)nj&=?$KDoPqscKuBd8&JLDnW@-A4 z8JtFIL$J@>Kep(?UrAW!%MhY)&r83>B!$(r4hj@y_l4v3C%M|3ari_SzDH6~jk%`d zetC<<{7UN~niySiH4kbo-AO;ivbe@wQqnJ*yQ$%d6LRzF$XU*;yFW##dV~qW`aqQG z7d3<_VnjS^MQDgX7iUerJ+Z8|jPFXuDA&2|gj80P%1CKGmA!#97yH08FA-|r8TeWs zhtFbI(|%Lw`NT!WUfuuxUt3A72yP(Z|I-A{@C4z4{7=94U)415%8#LG8UMdgr9b^% zsPyeg0{C=D0LUXiyZAA34f4W-{(|e3Vxn5bd3q7D2mFuo#+b;n!)+st`2_4MT{6lg z|FIfHGtahWrc+KjC*gIiz$SV6jR4@q@&4>>QhmrFtoFAG;-hS23JB(Yx0Tlj?)ByJ zKD<}uVVO81=~Kk2=J_pU8I6hV{A#s1!F=kj3R^;&PvjrK9F7#vE1~)4xZeZHA`#9_ zEyK3nRzP&dz7mMEL8TaHmo>YeslM!jzOKOOn%yr9J=-S{@NiAV$^x*NbXEvKb|xTG z3KtILOyY3Bc;8B7zvR1Fu8z<3)Y|@Y@hLX^98qhLwfZ>M!{A8Ov}U!3Y5;G43rgdp z6z99&yFeZQ`F%^lW;s~K1-1w%pn>7Lx>8FW1M*i4#a0s9V@k=%W71F((Io<dZ1p|E z74rM~d3aQ#O)D=%AvuOEX5=>1AxO#wnh9n~#zoE<hTA_1Cvq)q_UZ)ZM->n$2rsd< zW)ftP+nZuL4>)89onwew@ZnITCxLy}5q94hdA&Qp3FQ+;tVXaUEDR_K>QmwM#!P5A z8p-16Q*Cgs6rnduGZG^5=P~Z?t~o@#a-fdeBv?c6O`W4wO;wr9Z<6bF`3{YM{LoqN zSa;N*O4n4xRS<EqR`b%(@+XprjvJvE?In|aX^^o*t>k@Xp;fMCl~?!zVp74i<Gy-- z8M$@<t4yX(w!_NpJlg~Elv2a&i9c=}%e*FQxV!RLM32f-SFLzB_~1KS8}Qva55r3n zo*GN^t9CX}TAcLifx>`pq8NB-oCek6Cf{1gX!%co-s9iMJ5hBVDy9{aDbGnxTlDE@ z6%LfaQT<12929sUnPejA<WPT;W~%!eB4{!I#5~=6;xBRv%;*cO6={;7nTRU1T4E2S z^**Dck(YTlBmwABO$>#TS`CSM9FkIB_%I@%u)E1sBr@tLycV4X!`T^#_~EE)Jtji? zi~Zt<ac#+<+bw))TCsL;AuVI1v8q*`1_TCq`JY5mX(vI#1{LsHig16fA}}jj)$K^Y zkALo0IPO?-**A_{`zZZMfS8EyxHL{?laZ@cC<2s<*|?vl$>}0fo0KyXeZ@5!gUnnm zNk-?=)3}dw4|vGPfC9FWE7KGGR@5VL&_8ez(Yh~iEKSh~M1Smqc;UN3pO6lB4&nBl zrGY85f@nR!{eBW5kPWAE#5DmExD6^GXF)>BO=Uw80UbClUVh^jQult~1oMt+v>rPa z-PIpAqZ>B+sw%9CMp4{3lvHZ4YB&h?2sU624=A%^{hNQeHk4O=H@WxCK!+|_5%_SM z=`TGIeL;M)#H2@N%ct&7!2p2HC=b6?uko7#8GMo}<fye(;xuH<aQl3WyC4jJ&PYwy z6bBk9a-c@oqhc4WrDJcSJD23e75HzMDsT%q^#ocK!dnd4UMRIYy-KDmkf#<r#)-q+ zAoB3Jjj;j7<@qtaJa{qqrp0BAS4rgUg7{`;+X-Y2J3fDvICe4zj8zHU)7E8v(|H3O zO`iL0>xm+<0D)=oN)EhcJ;Wmb$*K?LSF#fU{O<fgg$+?Np1xRssU;i&RPdEKcCyk_ zLZNVOa*~7XiMAOSW4N3t+L=N4vcsgS0H82dZY{B1nEF#o_wDb7^S6^I3C=1^?Y&-1 zxJ^b2Q$<~E!R#237XimbJP>A}j1$+Kn$E%-Kb@hL5Fz%?X_Xc3JgPT<{S%t5z&vjW z)Dl>Bm{StQhBYcAS_8vYbM_OKSGQ3yl|$>jhMM>s{KiX{&9%ZFY51|$CI&9%#q;(g zKQHisywff%xbWPKA#zm1pSr~?dG_%lSwARWp?uHE9k$!!RJ&|rzm0?no&rSwvU|PY z{N}<WCtMfv!tHR>b9V~hmR3G$2+bpPf$+KIBsnEu4EYbAK8=FHLnm`FH>h#}C_4T7 z!Wv9fLx=rJYc}BIM_N?0bTkWZr>#|%S$^-KmAfQXarI}-#Tn=6wm5nE!smq^(kyEN zq5JmPDo7KoUh0`7WPXoKD;_CI&Mh`Yh;8mxEW2a;m2sb1f1eyMH{?eU&8a7~1HV5{ zu2u(}c(;3b<CwNg#cy)`{Ha#*GS7S`4AoK3BKbwi*Uki~Y21NI$SIz-uF9}+yHo&Q zU4v5PQ&jX(ZKQ}Oq4Zs*9I+SdlUOwN=IDZE5Gy5x@P}vY-}#8HxS>{DVtC&lTyBqy zch^8xSCR0h(}E5F6VC6wJrIl3CX6R=*7pM8w7`i0@aQM&oRB_#=7tm08T>d=qg=$X z)3U+5%z6e16$;Uf&yTs>QE2Fp>_pXP!aK62zs9a^=N`p~-1@EF&xMNu^Yoj@jDdY@ zuMn338L!=8iRo_7K?e^U=Kb+*Qepn<PF&CHq^rpczAMK7xos*jFJC1O$g67-_bS2Z zv~Y4JOyWUTEc@27wq1HGW-2*baI1fD(Ti0AUen9@0cV$(1xfAP8ns^}^8m&#kZ}NS zyI@0SHYca7P`1VXK$yd`kwpo-nyd`$Wkap(M?lbty*hdcDnc1-kpMGZM<*oTU!P~7 zE%4A!+%;~%p8@$P$)Ikf4NZ%=oXNBKyxzSv@+o6F{iV7nq?2dbU5|}B62Ap-cA@BN z#%!FXE8aGBU49Ud33sS!S4Z~2yrGZ~bgo??x5h`0N}nhk|C_P8y&oMbT)Uc*t=EIb zZPtirgcuP7qhCZiG*(j~oPuUDIG_}*Hyl=9iZ2F0{dTcuw_Q!GTyiaN&nWkSdEE%+ z-AM|SqqF?DM=(P#G3?`gz4eSGH(ES_Ly$CqRd0~P$j>tLREO*<WHk!S+Ux<=>*Vz| zVf2R=f)K}1PU3buA1`+ev0&RD)`aZcUL4$)k4zb+E3?hUN4@PfcpQwv<gk53#Ni{y zF7FI*_Ewf%xt+8LN&mC1uQ5oWiw6Ppl<O@q+;RV1i0R{?4SRw*+>Z0H!|2AGl~MWm z5?@`pOaw}G9oG*Ji;Wu68gZw7Gw;-qgL5w6>gQJDBX@yO2>s2QVD*;?c6>Kq-}u?v zgff#LYkNPMwgW24RN(#p#h2iJWDWT>W{1(3KtOd;>3hsz|CxwGr87<uzyPlJK3z9j zl6x=e`if5|RA?6!*5!0(Pc8ID#}|L2`r4J};^s#LN&VkAcRw&|?dd~6?-sZa2w7S} zw(m{3YI$R1!mvrhjur(}Fs=3`RH<1Wa~`?eU-6{$v?&d`8C2%5o9ca*L5RGv>crtf z8Zo+b76S94_2VN@+F?Q4LI4e3XX@{c!!+<#B-<~l2NpbVVJ4h$co0jIL35ntG`TeU zWbcRHyV5EkGA(<GX_il(S#=tL(f*rbaTOk6RwKvLbtFfBSr|E=v}>HZk1Gw(%n5jZ zSLi=9F)XSv3<RgkthUfICPCOV(>=h4uqP3fIr5p@wtv?BemK3nIRRMqPVaPQsw`T! zED9Qow=MK;N6G>D->V23NSX6&--8&RM@)iHkEwpTg&a<s6y`fzkgyBxSTfo0WW};+ zIB^(1QZ<q>(%T%HEiKudM{JKV9pCBfQm1>{l;;|6WIFK5dnrdHI}aBbwxfXh`xkg@ zC0-y;hy=KQy*+*o+XLL(y}j=)hL6@9Rl|jP@#l6N9qT$Oxb5?Unt^*1aJe)~14A&z z|6J!a+7?Fhg{15t3agvrYqB$0%QBH4Gf}HHCMST*b_(v`2}2Fdh{aOs9U@F;FVk9W z3F`6<2d@@u<6*`F<2Ho}vi)w6GaeNOsuGh<Ac5?f3e@YfB?d&IAhqv%yvV32ll<yZ z_$_6Y&^Xl;H&)eODYn3rwic4>58N9Oj+2Xg-=VY7;Ajl}N&{Jw*v~xig7zlBnXa|0 z(6c9dr&E^2C|L~3!3k2MBEhupr|RT2qaD`7!bQBT#Ger4A~YU*q}>t17?eedu{ZZt z(jWpl3#8?Wt`4YN7xV)!$Jm&E!BsT=zKv6xJ{6~5Bnu8naPk7%P<-&3kYdg({|q$J z86<`(njjVOg_rR<yQo54AP0lAwix$u4H99<t5V(&97-4)#Lc@)vuZ|Qxz*ib!--R} z6y2Gkxk19Z2wopiPQ8nZB$+ef92!V34JBs!)x3!hwa%S7pZ+(}v*ZWFs9SOd00fIz z4b8o&tAAOLr^}Gpbz)%uMsL9*2%f5vA&a=sQ{Njqe{iB!CCc_sSB?ci1#k=c0{jW| z4Q6+ycD8a7IeJ|=T@ZQON$>HQ>N(X3PR>$^A=(_dqzitX^&BAv(kZ{%!SC#6f;a#d zXEA0P<R5{lHr&M_QQGON50B5!i)a{k@cMksx_CZptc4cDfnKWBNA2={vS(%?_(1gR zQJXL?y?zWU?lFIPK0YWtBaDwf6rV75=nIJ(r~5*t-^GFmz%+5|Jj&Rqjjh_IbH{-Q z|3vU~Rj3-QvzNn3lm{PRhpYzyw>{nF1%(Fcp`dt|?7=OLRpDh`C{u_yPVUCM5F_k{ zm%d_DG>rwxMCO+%s^61)Idgs5c(RvI{|!td8+!%aVXky;{B7<nzTS*x+w7JAawoj+ zp!9;l7oe5a29dbpQUQXYKW?MXsN_h14(JRf48q_}{^?lacYpk#sS=hCrypB44;Pc3 zj<Y*k6218bvx<Oju3q3hY+MeWPgrmuKXqUZh)sSw_yB*wUN7|d=MQxw?rTC4Um$Ad z2(IpO@w?8|p!eY!GwhJR8H0@V1~&9D)V`#@QyH;1wuM9sy^mVJ2sMO%hkJ840t#{k z(JNzvj6}=J*7(}848<R^BP|LSfKp&ik_0QL(hy0akGuvDzEKe<75`93C}Mvbz&bIr zn7ML=pd^HqG3S&`cbwOMukk$+;nfR*$=+XTPp%ssu6PIg1sUvs&WMK}Rabe~(G93u zp_QrOWsRgn1vMivOA_h#17qTO0mgE75^YViq7MfGnJ*~Yl_Gx~=@P+UA4?t@xNWe% z2U8;@d*qL)#N=!nS6UA?ZDFxfuQ{S;sTSa`9s5t2CxASuNf=c&%H)G$rS+Tcu8OvZ zV}XYvN~whQK?N)NKb9(t{af*XD*|qYB&<w<0Lj)sQj22YGA0Ba!U_O$0yI}3$JIg5 z$L~B@ug@@e2+3Tw7AjQeUY_0!VZ;66Mjy)))6%OuD-LM#!b}yM4zpr<E$IeTLTlUV zyykiK#9^`XgGhEYS8^!0%r@gp0Nd!~4+eqR`@IZ--s*}0A>M2|7EK2U3oIM)>0zV; z$E=v~1cw7vZ|BGq3RN+;2e?o!X{M`ZSIl*PuGzBf<bB=y${s@t6@IZ~XliK1Xxx6W z79qI{y`R&q&_CLMdP}(04pts_79n5F#v#1`d=t+Kzxnb#F%C@L^E=1kgWv0E*ue7G z;susg<p)d0jP(%l13%~-7hB-T$5yB_*r<fEvQiCA2V<>|YAo5q0xaww3q10dL?db- z&``Kw(`MP$DW5i=n0vIza`<!W%R5h=7Y)7*8?mw<oY1g7Qh(l1_^T^J5zN^C0LqV# zfCREYcW1IoH!BE=n@O$y_5&}&T78~H80H3~FDFW$(LGS2@TJdwf7er=({yZxy(0~a z{!qOhi=psr`z`z(fG2uglbS8SXy7Q$F$f~)PgU=5cuw%$kRhd75la-9)0;I^;P;F5 z!h{2%7-8Fd%?{Ak)Gek}-=k*WR!x8RWvvtDkoXm-wFHNd96?{M?IHt~x@Zm%Kmxzb z8#tg@hE(&Q&(+J@{R;u)_VoGTBK!4-mmmH~8xy@PD%uPR5Pm&A7fVU}k1H4=)!G6w zB|L=(DJ~`fST7x9MhQ{7o&ldqgOVF3S*32zgWhyk1#ZyPXrX_YDA~{^f^8$Hd>H+- z2ayew#0&HVRM#a_q@alCbgIhDl8)7D3_ho7^R-Bvsi><q8i)GlvMG8WBClwey@~B7 zjE4iJq)W96_%X?HJ2^NQ>i6{KHp)1F31#C)Fg{lx=k|x}_LJT7Yy*4BrAnpUb_V5L z8|Z=8&$Y3v95;s!kE#1EpME|^(fpmOMvSraIefT1in-;+{cel|!~^^qwCXWO8S@AU zdinUi%<p&Bnh-%#h~JPDkt{~g-%$fkfy5}JX;!rWgV{zbzt83W@|8cIHD>p^Mt0Mz zvRz`L`DZ|}`D>6MuKGf0B(`gfQwIkUk(t(c%P_-Dkh%~K_0Yoc(Bvx8P0L53)*BW4 zOFYsw-#5wmgM<dPq>bw-oFg>3dW%i^&1Q~dYs<tE^FXIy8=Do>fF4OV#VxNcV6F?N zR`7$Y-z4zW_%}Cg2F~jT{tFi*8e~O6jw*H$QL!X)VjcQhkqV@pO93rOZ*D4m*hLSV zaT!rO<}Su7FAI}I#meVeM7P9j8tt&NlVd1Z?#R?tlwYUdsHjW6IP(?jV-109Fugbi z{}i0S)&iY%eKY5?3E(;ZgZr!fdq`maXug~%-7y6O5>nIl-1!i$H{Cx4gc<-VSKr;k z?1^l85<VD7A(4k9N<lAy#73uUHl;o&edAMvZy4mWnWMA~Bqb5M^@Kz2wlJN|u$ZH% znxfB+_;~U~0G%MY2m;J9ada(a$hx&B!gFH7RgRAp)7XpFo)LiKX@#tmuc$(0+0hQ| zYT=ziCDWSDrXU2lFT(siH4X4cfG1|w<;UheR0oG^R>CvH_Ejp^_!F&^-&cV-IvT*) zC!)V3;sE@7i4d%!<8XVjTC~;#k<NKyp1G)x(flHWP`zIUR>+RaF*&WgF~;}dt_jWF zYxcUYh^)DY05*rjVGTl4IAF^v4C^3ta;H8z0hhQpdhma^I>+xm!nR$<w$a#)oyNA) zIB9I#nb=Mm+YNuQoyN9p8x6Yqyzl<7pZyoyYt6dW%&hyo&f_3?6N`z=Rfz!jVHT(h zCQnh3j&$)>jd_2-kPy-4DXvHbfX#hnQ#};XX9Q5FQGR(ZIVRIM(*?q@KdY`r@JWO4 z=D~Y43X#VKvE0V3)vW3sg?F)OTQSkEpn5qq$9EBeC9Un1P&W)_E*W~?5-DyF`Yx}o zJs3TMxKkSn&ilG6Z|jzW@^%3EeK$`;xB&XA!c|oJPJCQ)U3HuE`5EESo+pL&oeExG zn-O>y2D7&TA-9c8KiJqQJ26(}>_hVOhv6Zs8mP$R+;T!a6{^zTS1LukRug#Y)K-w& zg$a;moK6c{Ciuwj8iJ!$GPkps2(U^R7`3P*Gi33PDX1g~TYuVd%^Co`#gx6!ThHZ* zixSsz6){}I9qH<kwOzxP0E(7Q`2aOHYRt|hSp(@gB2b$!qMJL(1Rn2~rYA@vy?RIj zSr8oy^81&Gbo<%4fukMA+2>G^^qf#GmdDKb(QS8T_)Ph57(|<6$>aW-Q|}nVzEako zs7t>lEx1zR$tUI|X9a<Q#~hOa9bVow0ZUZM6W!qJZXYnV>fSFLO_-20F>+yvkOtuj zPrryXaq%j{kmqpTi#O38c|6kJxR!pbK{|VWtUTDhV2-Jmxg{RmikalTnW0XlIz3u? zZU?&jJS%Rbbw8gooarJDwA_8`bLRV&{sgYr&Sp8fN}<gy<sA;BtvnN>puCz-IT&={ z$xcle^d!Ua7CH0`P#CT+dYdR}k9fulravJ_#}pmWB?r!>F@t?cXN6k%!P=4j<U}?J zTcc4-)G+OICR3JOd<pGw7*ey)b8_@i``+=vW|Ka=31%$2A$%yq{sLHoGOU19jojVk zVyVi4ffc2zzhwZ?Tn*zBA@^_j(!QBrBs>8c4c>nUCxoRkc3~T(WpV|Dp#p|cVsBQm zsT2}+vtZPE(2X`B!0IHN+(ACvRAgU){&sxss{Fkee;$$6zvB!)yATJb;U$x@t^{3I z)skb;2v>0kRjFgfzJSuM%mgOGzwS|g(W`R!Bh6PI2R#T(gZsduWPbImx+m?Nvl6>u zHEk+=8=;+n|Kj-5xF)2A2Q7Z-=ZtdH7d)#(gs+eaeZSQS!20!e820*R_S4Y<b)(Y% z;HXLMM}!YYyZU=PGkun+OF-kgMQZ0I<<!I^hshC2KBsZkyy^$+qgwf9d9k$g`Dpa+ zaddugV&m8Vxm3TVdUvd4<&t{{7TYIb#y5r-Yp2%ow$?1ri2ICo)|!vb2*j<1Y4^d& z4f(sO<<%~E**aaOwUJCGxecX>3~f#}5rUhrM?v&Oyb<<kcfmg)(FBR2HN2pwifWwt zstR)yt!Ne71n|`+<<!V08c?b@0jz>$No5Nd4emHVz>GN_U@4&2FE_eGz&@~k_N4GE zUE^P|fwRfShEmfsb<1z6fzv%4**0VyBe;+Z>Qr29W!w(ks+g%O{JPZ$iSz}8gBnBF ztHjJIJgiFSDO$Qf`W+?w1}V-4IuQ1b{Ku+m{?9)#m5u>m!#iIuGuw-aJ$r9l2mS^r zY`)I`c^`XtV#{gF{>I@3P%f!QZg&JI%ASt$=3onI3?Lp$cUT^UL`k)fcmtu$XGJCv z)pF$2#Cru4BZPXSFoGM8NSR2+(yy#-sNxMzk&jah%$ST0lF;C=c3g#xhj^rY@oZNh ztQv@Dak;p_jSC*%+qqjTACLFAUcI0d?X&@ao>#GWu1UK%l$D(xQx%>pOY{3qkj{Fb zsqFda8d*Iurr{2?+b-VR5Y|)O^D=In>D**Q4nnqhsuHcAt+>G<3WMf}0vV1vF~M#? z2?=yI@S3kC-RQF1`vtTfO*jd^h8DYtAj@f`k{rgL2p=xugY>O&XHiPByxP&n`wA6E z;jC_<U>J&RG!QNjGC#$F3|lf3=}s*SnkuG?;z*qf44()nCvTddNA#{VCn>0j3vyCj zy`#3^O~6iBY#7U}Vp$TWD55{ltS;-I*s(xfE<Ea;lU6)6cDIqMw`?dkzDa`M>H?dO zKEnLQmljn+7E%ycNsJ=RWg1zQwwMn9&^LU)SU&7U+2O$$50lG859WAuyLmj~9Y$KN z4g=w4Cg^*J)pU<PzX(BEY?B<c8nGWgcdvWKeuJs5k>l(Q`TM!)%Vf4n@q}w?+8)oe zEgV@B(rhd>FO8p7Xrzppg5(&k^n|ip)UhK_CpaBZStp98j@Hf{yfXm?w%i5?Wbo`L zqgrK5@y5C4;qlAxd&k_`$XerFzmluP*{k*`SgPUDUZ|YMsN_10vDL+H^cF_abWdGg zD*`mlyozK|%AYlsjY!YF@(wmj+v3aK@#hZuQy_g*&t9qgO^0}Se`%?MB^74cN&=+M zT;Xadt-tnXgyfW6d!3A8?g&73o1j0Nk!MGwAXutzutaaPV*Gaydt!+Gi92SQcGl;D zU1`6Ite!bnpkxVFEaR!C$bsvi=Xpql#|w|}q4C2~QC!}uDn01}Tki$yAJ(BHOIhDR zA%I@!RTC*4a>4Ri;az)Vo5GTd`u;{m=?}+k!D$+YXcY&+0G8Cji5-ABNuc&7>_0K# zgC1HuPM_dRO&;a<aPk@T5vRH4`po$Qre$hq7TlPS$o*{H$>jx4gXjA#4$-xkhbV_= znZLox>M|*0k?0RBPlpa5XEfjWv1_*A*}KXcBDn#beXgc2#BVyNi255}@n(+iac}*b z<{yNaWF}O;^)LBLy^=tWUjt2FfB^`1V7d(k_JZ*@-VPxRD>J6|s-#an7Ipr@nMdH$ z#Q|a?-z&r=0W|$CD;vz5ql%B)VkhcZ7dHpzSL~jg!mb=FtHLh+zl%k=ehalYegYjf zBY&_-1W5do&@k~ByV{vT(l=If?w-x7sJe~Cn-m_%4Udsw{rG`eC^T~l_5uU;zUT_J z#WeMe?mKa^U;c}lgNA>K*IcpGk}GDe&-dK;Kk!VfGJp5Ci7jbKUao7Eid?TfS$`a{ zH~e5;;O8Scv;J{Ga3-F<btx_f-^twwx0=QOQWOGm*x~3RjH?U9#qBP%B&RlCCX-F1 zhi7Oi%EzG~UPuR?peYc~24kyGX=`DfREcVxL_tZ5&woA`yqPgr3!j@rxpKqFv+Lz- zm*6diG}HTCP4vBO;I?h&77(82NUkG4Qb7x$`hCx!m;2GpT^Hu%V<+UJ!3S4;m%}dF zVH~~++quX<wpz`UUYC7iWkfBjgbS~E`>5iTsFX48I&xsPZDaD%Mmo&*Xwf4^ntgIo zliz=b9*(A5a)SC?R7pc%)@smA+C(0vC?YjhA$Yd3RI{ND_Sd<X>-4@u1C#B?HH7P$ zA)aMKcSm4d<b?IECiKIY@l9~;tBI}g_A{!8Oh%rG6z#96LbY!JByaJkuB7Qlbz-PM z&94@#%{ZW-e)y=1ZbC8Ws6zOwD|tXh6J8f*N!CQ>2`OstoD8vkf>ex=;<~iLJ#RUJ zPx5TRDd*mB!L*?eaRxheF)r9J=CSMMQ5R`;-O-?r7_7Cz?fgyP`U+|oXXqzd=9E4L z1p<nleyHW&*a$%uQqU_m{SC5VL{hP0@k-iocmyC{W%(|~eucPx)=FUU$JH-K!Mw7v zb~5V2#7!ZdBIH%rtBO9s{AFg=HT;`X&^5PTHJ%!ZDh-OJmwIH3kt4_NO><(KEd6u6 z@A|1%5{WPeHrC0wYUiDbn7Z}>PHiO2JeNfuJnGaXng<W5ts;tzVGxIFRkgV84gTpe z5?_Ja^o5YBf5)23pDUdtADMNQQj#m^1TzRAEO!daL$hD<ol>7yY}0a$YA|zKh_bM6 zStRT%abJYM@ycSqp_-wlayyxrXuI}?bUdt5<fqUW3FBW=inC#?W~<MX3OZ+~LL93& zC!d8W{QC@&PjM4QM6WQ_j%v?PsPw?+1^}3WO%u9E&yHYQyvn!!8^PkVT1jMEe?$@E z$=2<Ri1q0N?+uP&3HTBD0)x+&{Mt<B=y~R4qK76qm(hnh79Hv`tEAPicecFWo(Fua zHBeXRE)^rAwx|y$7LHbIJRhh$uN9s0Q-)(&$RfS6eSgcAem+%dvh82W9?iN~7|_e8 z=R?dy@z$_NZFYrTreJB`S@&ZoAb;DWKmQB<|JBao@*!UTuYW4K6yhG@f3;FDA&|sr z`M)5@|7QU~E2VZV^`HJAmEb>K1R9`PYdvoLpJ4A<6YU37BAA3FW<Dy@Mw%@o)MUvB zjMpj?lun`DV*Afx_kE_PZN7mlX_+VcBm!v=^*4(!b_=El=eBpz%KH3zTf#YenLgen ztg2Bt>Kh-ad&o`JIxVKOXbEi(#<XH<kB<6P#^%oINPhPlZdTn|EA?50-xz?i_7NM| zwJi8wAfJ<7@R_IvxKPHe#&G^^C|AwI@%<nB(H-%RZm#w3fNbX{B?D)T21$g<qj`|K z;&)dD<`$}b#T%ma*>_K~<!Sim`l{@W@YLm<azH!KLq=LLtC`NFDTNc{igJpBB>WeK z%Xc>Vb8%df4W&i~@rHnzTLADL%TS(&9DmQTU3X4E$MDU))sE*G%#=Y;DaElJHq`(z zUeagO9W@`=-KSf&7X)d)%1xvAB;#v?5dLb@S3l@}xCurnYC)4iOFF081Q9rO3`YHi zXdB_t)>SQaZ1AvV9Q$rq&+vl*$4erV6tLzp=#K^CC9uS=#eou}Rt73p&v(Iv1T>;H zmba+vg=eAL)`DYw*079?9>8b&gykd7S>r{c?QyQ<$XIfgcv-2BA?<3{&2_=gz6EAv z#VA)PHeRP>oRuDJDCEDW&|NdgUTOQk3_{&ZWn7#pjlg-&nCTr9!)yo51Vpid87F76 zlS-SPX;KGVOS6uPYXIV`UbpK=OQm*|gbJ|bUin1Q;GyA32=+y?rs>(Swni?((sinZ zjb#Ke-M~zAXXu&MKIhhqEK3s{JlwWYu_;z1d&0Twze}upD|i_;J?e5q@(P`DdF}P@ z!%cHZXil^pZdio5`>-yMjfIA16&XxsPZ0;hyYK0r>CU8tbO4xHY!6}ugv>Pla``^Y zpww!4fIXvx9|%0kZ&I5^=Hd3tV@fv{?c|4m8ZaD!&@bx4JYu%apC%0R^$7|=dK-)p z!B!dSy>0h0kaG~bRagTz^&##KrWKFzCq^r*<|{r2Rm>!NIqdWxn~J{z9HBk{_hzwW zgX%)<v-OfI18jVgGd^gV-nE>l!oF>zf3h>c)^4-WnbN3P{IOo+>xazH#`<L#&DWB! zSvhj2WJcIukKz#L#qK)>r3;-j3PZ4?(XK}Lw!PS<XK8TMcvMKr+(jZXWbwv|XuhN@ zdBHCc=hx-AiI6{5{2^`OFzjo^OKjEHCduj*S>|Cp<N#!!?a5o>aix~rV$EP?_Czon zLNwEE6)5i4hX!rGF}e3nIt1s8Kj{v1V;kc_n8NzFnu~h6!w{Q1r6H#H!cRRAVv$h7 zSi>sc)v^xFp6QrV!pv}=>_HZGcpDS}IBx5?#;jNZ>^~`v&0M|$3~lL|{7@Mj4Rnbc z>zJWbKcFgzyCl(vzoG_GpqCPXchkjf=vNv*$5>NQ^AE^?;E72{r%=lWvqh6#W&BQg z!aw_w<o7e1Nwar3+*9!<ju5h)N!DCp1o@=M43<(~X&wHn;uXHdG;1=0Q&6(Iu)flH zWAzATe6YpM8q=aGN06vglpb<8T`c>EZr>om2SB8B&3jY_XoeRtU*7YKq<}44=)K8n zw1J7?bNCsskioj^iAluxoyeHSHuPTQs<Oh|EWEgFYbCuTh^)3GcWvS(+FllB2$Z=z z#4;W2P8=ZoAso?yuK8gbg(GIhn?zK$nY*#7BY@>4+A^~<YJf1D9)Q+?vBfLG><X=e z3Ear4rY}G8p}QUm9K*qaCB^D$i?UTA#ZTM8tn2xE7Vg!v39f^7`3=nrtKJZdCM&!Z zOfQ%2Ek#Rn_JVvv&}EzOb%%Cy+p6N2tCow^{#LRQIbYbLPWHw{J6`K#9clEDyC}5a zC?MxGj5yLbXFq&!bA-Rv87Wd%{XLIb0<wZCoZAtiD%cmue(M<6^7yO`pRK5sXJr%E zK7<4zGx-|5n0RkKV(8G<PiU}TA0vtx#<vHHoC+@s;hh_vK^F*XDSY)n8YUq8B7})G z-1);tWUED@O<?apEVOoE9P5!`<`+(1{=#zWc4NqHI$c->NeTPBnE*{Y%S^0rFi_$R z9zdk@`IEGMMC_3r4V<#OjGd1Rws(u;E~I6UTL^4Qi0R$kuqfX<oLem26yMl9op-bg z^QQ@?RNFPxFDf<37F}AhICizB+xK@b=SI4gvMJ=TZj+P&VQ8YOiSOZd_YdOFP|@ZB z#e4Yj#h4k$A$MrvK0(HXpRo?mLO}gj&;V9B#K3wFxZjfzDX|~^4h#MF&Me>bw%CUR z@V@Ji+XE_le~4&mMew|cW^E<zl*e(O?H5>QK=d!9b}rb8+80W)4dxpd=)+L@HU$F* zL#%Asq0yKOeF+!!XvMX!x^o^ZsaQ99gL&EnFlH;vH$~&wZ1~5-UzA*a@d8knhs3F1 zst-3~xO4oH&ljE;{qpsOA?kqUSXV|l*?ygWxV>i*t|7w3>Yw8@p^rQ3_BO~l5hE>T zgKk*^#(@tW=^r}-4@A^cWej$4iNj*@A*Sz;UR5(rh`ZqScrO;EuP#-C)7s|N|F$Ff zI7g7gx>%Pt12zWE29R`r0{msWGn$?;O=}^4!`leX!&fVfa{G6_aYs5h&uEM8AAk9U zeYN-hM&$nz@+1Dj4Ne3wFs(Ee&_5^Ly8SxO)22b6in4hBSpS3}2o;83%eG7(>%=sw zdERRT27+-mvb4UO>Xgzx0oZo&OqAA6+Pq`}i6*Ws?C!R0pI9$D7fAP=XJS|E#p-=G z|8>;TqV96u?cBD4(EU$X)c>`vlG&^1Uxc5SWKbbmazKLAt^C_)H#SHqE3*VRu%p^t z#NMpC+wcDUb6bZ$dWr6}ccI_VzLIPFT3gLIv8nMz{`SSTwnC?UA7SmL^sA-5pOF{j z%aQvQJJ~K;%X9MU8Hom`Fu8JK-EfdqRD1HL;&_^GOOXP642SA$dnw$FEF9C2@<n<f zm3pHT=_+$?OF5U%MtYKNsq+%Bp&7)@w^Ytb8T3I<AAmsh1U&*OqW*#A`Bh8`Mfsck zl(se<<L>P;CoQ!;r5dbNYlV3Z6Y%!9tf@(I|6DudZYf}DM%62S*HwPcr_oYHGwUN} zwpIUBme)OfS!k$Bt)&L~4N)BhU+;eOGw}P?SrgAP!Q{PZofa17&!hvOmLb?7lQG`s zO-3Wr$j}fKHlIZk%Cr<0afX0l<Y#lcjaE0fFV%Wdwc!O~bbJf1N#~XO23VkGXI)VB zH!Z!XtUn-f!YLci*UY84?oByrYJ=wQo1^nI-;;v9>YS0FSIoPZwaYG8@m|}kHM`i) zFu}+bg+EMRU9Nw=P;<fp=RMr?+pdkFkZmVpFn3Km23q&sX*h*`-ak(CsaPm>-+DnN zldehsQpvX86JwnZ*&+mtA^rN#B=c9C&drj78=^E<ZqK8g@(<gLxS33bqcbgM?m<&3 z)?#sNm-KLi`+3E|{~&$!G-#-3N=tM_!CcMD<rS+9#G%Z~HkX?KQ;?O3lvRHPI!*R* zmRa~gP&uDuYpl{)Tu{U9k!rz4<XUvtPsfBk;cP^8Vjp4xui<Am8D&$`0l0N_1Y4AD zTtj4}J({Ed3mMW$Vz|=C!i`HC^}u7V6@DG6J|1#4@^4;-#YO?xC$AG)aw!1;@-M0U zq`My9`)3`K1UAZmIKnNkKqFKUxc8zK!v$%b5+<s|R$XQ{AI6%ED9g}qzuN*#zbbaB zg>k6=&LPWH&Z8J_mcpc+5_8erEMi5|!SZorkR&d*bp5e`f;QW1hSgu3OscXNH#*TG zOB4#(g4iFDmc<@nf`#@I41YPWsc@H1@0&O2oRGEB3;%a8pjUTkurD_xz<)!wbs#5D z=67LkKz;L<`0n1aUD={h7ShIC@344*slL9y-)SQohi4^Rr@B%6F>vx;TVBNF&`T_Y z83iKqnv8si*X$Nk<aSOQ_z}B#QRzv|;^m}Qj{{qRa$w;OqoKm}ww%0jvA{T)(^JNi z0u@q~zkcZs0@kT~pyEGu>`DC?T4F@O1b#0z7R2_*4EaHjTngBj<m{!q24h-zKBQHA zLvU%}Kn-BmNo6I^5=71u`%NlBx<RRxwqN@0f8sTpBr%#USGZ?O5Nj^Z73!P|D9tPj z)z~YB5x_JpyyDrwWrM#K3z1h&hFc0?7NE)5BP5Mh0RDnsGxq#Z`mul7JR1@CX3uzK zOw<KjAB|pT#mZlCJ7JX&80{6m7?|3PDeDu6*0Wa)nR_l0$!Zu8vdL*ZfS;*vlKObn zS3<kCxP6Fj2_t`3h7+dD94@6NE^a6<h+v_@`Yw*z9@n61kceB>Z<?@wEb`&|*7Q{P zoX1Ef4RoNTj6ipE>G#Yl@C~4#B1%<>0Ki`yp*f!)KWU1gZj@_Q5g0OHK5^)$2l|P| z>vtK*QDRO_wMYi6Dg0LACfNWHJaO@paz3?F-Wsf6dowxh4tEG#R|~&Ldl$BayGERt z)Nrpf4wS{84a<QX_D5~K!#Z*5`=?1rc_$y`|1#53^wb^vUq@D30lc>6?t>$Ufue{Z zUXlud)0&={KHZEM?KBBbr;PVzy{D!T(<v3~wqBY4UhlqQN1W>L5fmtIr|`_}GKy&$ zFDX^j$7KBUt+{kCwUO_T@;Nie+m)b<X2!DK_kv^8!+ak~QaI6%Eqs2MAH+=uybwF2 zfN3SHqjj;B(jN`1bv`@6W{RhF{>b_4oETVj+%PuUP$cp@_Sapl#N$@CogwA}%Jq{C z%s3vqryV7gCz{$!Eobl&(HIJFF(<Y?z1*;vO_5435kXPOHBpi&5|$QN)rF`ad6)xx z6dsPI;34$|rD9)pb{A*`8AHESf$C=@Ks-BX`T|sQYOkhx*GeA0mdnPI70GkU5kP^C zD#n#7|6t2v=(3T=U(0$w_l0&_C3Ig;Aie3{Re(yDXtL!o8@;=xeKvm`tPP{5-K#Up zO<gr_3ya~YK#jXx>3x(au5E<NdoBXXZw5=Cc3J6j>DZDL)ep)Ze-Tn%*X_6+aLw3d z#gio@C>qIrPr6>~a#j;n2vzyoN1Nc@a4Jp+y#%;NadM|LqMS{goP<2Q)1WLnSy%A0 zDnXoFVqvr^&ug^@wn&Vcg*nmN^x`0(NnPNaNbdc;r7Ruvo*U8c_nXxx?6lykS;5w< zeeI@uyp&yI_76H6W9+96MiV>$2uBvs^a6!n!aU&Yp<{7siT2`R>|4*SgCFAdueSz; zUF{T5101I=-a?EAbVj+}M3g%^_YUUAQS*%rrRm$Vh~K(|q15@xNh&;?@FmIQWLr;G zPBoJYd_r2N`s}ZF9$Be<v#n}sTV|o1()D~<@B70rkLR?E;D02)jH<o?+2Y)Sb~&ZC zO;sq2(E`Yn868)w`LbWalD$!NY_y`tpYcvPvXgqJWA!Ftx6-{nj(Pu*jJ=LVp1n#R zh&He=p0e8e^z;QX`Md+WubzdzqHx5^lBCV+1zKIKon1Ukmo16i(#}Eir_aRD5CVr; zi_#wf;(CI0!?w(4$K&8YZ%Wl0;@%<)ZOjrcx~av)2$eFUJI@!#?!gwnkOW_51Oe^< zHd<50D5GC2QfC|X5J&-M{cOD0%s03CU#rp;Eq%X_<{CRdtbWl?C!}YfrozTA59hPw zBf~I^h3*pCa)92)1nV35ii#1XBJd<!^>mUS%QGsT5YPD$&D#D0IFpep=kC*CqW}H7 zKq)0(Oks-je8OkC^Y~%V2>j2c$AP?#p6f~NY<vZxZjsR`q)eNt*A^y~cGqR(j0r2l zxoX~7pR6al-$Y-<8(jpzT5UBL^i_V))89Nf>@!sAW-o?Lp2v5#Ltd~iddaZuzTIuO ze}`i{pgV+}B=*N&pcJ~p<SZ^Nhv6-$y1Yb27L&@<wK&nzjdIdR;5hALe|b7k!6byF z*2ZV|OUu^Q)j8<$64>5_JJ$>oF#3DcO42DD;8DAk*z<WKa0+lx$k3;U6sf7<Ru;ud zMp}GKP+k>CMh9DcB8S4Y{pfgMkYt({D?Cy=WuXmp8w6J|_%*BdY?Hh7*b!#5>&1YF z$-_Wkx#IHpz*F?BKn;4K=m=C;w}hv|6BLpXiz))RnnQ>9j(KikL*7I4bxm9q>~9D~ znLm;L`z|TE(6DpjpGADo@jpEkdf+2|oh!9x+Mw@|G@|QRg=_O_Ym32GVvTYcOopIX z#z$DCwO(PmoI*}Vg?O0pPtW!nxrAzp#aw>)0KT2E+yTYw*8Uqcdxrd0WBaJC-S--< z(9<>Jrt7G7)%A9D3A6T21{YsPt_=C9sj0;d8|3S;dO@tkpE}DOIW@dyHNd%Fn+kok zPFJPFqvYWYXv=DG0lJg<>!Q)HUyFkqjG_DRk>@YRPB#w~ZXVGeOu5G;vlbS=YksXO z{(M}-MluGjqH?a{V!56~F1s^q(p|lp?ap(8sCn4E?y+{J7o!zhUMm({9x;}9G`B|r zEH+B$GHtyoD-|})6}r1eoq!c25duVu98EX%s{8sE3Fb=QvX2^&=q5z##Blz3`?$ly z9MAx@!35nhuJPB#0BjB{+Cy}r7&Bkfum^;i>wT%}_z>P?A7rI4jpdu$zj9t<AAh}m zcfO(5Q#;Y!_w3DH2J>>GZshLO(tVZJSqnD$)9${1KiR@gx8?oiCvbJAuyx2>!5M>y z8Nzv&wcO6Pa5<^T*{dbh6+q???d{OLflI|u`S`=Hg)8{mlxihoMeHYO@xnOcr|o6? z_Rak91IwZp&3rRa_eAW|ET5)kyY89>xLNYfSu7JW8U}jTMoUTPTd}?YZp$BurfQ`J z`slNvCr|ioB@O{S8{je@h!;|gr62NZ{)MWpeVpZ=A-r35r`+PQ2na!!P5|GSf)g|9 zy8WN8Cf7UL=Ntn2noeP2LOpfK4X<L;@e4|c#w<;gIkZJ_CR^Sq7k}9sj^Ed4lhNGf zjn_cmJx>VBKgH#h<o8|;{=Kx1ZQfj;_eq0_ka{_6VlvX01yCNgiu7i(3Mo`LJtNCS z?eY3B;@y$o#5&NsOATD030DH7_w)91BzD%eTE!~t;gyCvE)W{xmQ6C*gqX5AF#`i# zf)p&5UG;4_)Cd9WA#z+z<c?ngZQY931h%HbzOX$xNQBqTwaR#&Hv6y~mEUXEn+C{y z1^C1!z?K=R0L3w3sLo=Gd8%K*htBTq?#;8hP2#6BAdO9^xxib<3)c)o(jm#-;xup{ zXUJ5uv;wUAH=I&)5#L`LZj91D3~aO*xK~bw{&~FJZu1~t-DUKtr#M>2*+ypAdYN9w zb|(0AICjpqq8t#mEui+4U6;u)*#2bc+zi4{m<3%p0<`pbWi@K?-Ci-3uV7*|%kmL0 zVRG29d=)UIskkBI0il-1insA{82c_e#Z5Etyi<$S_L@y}yr8H6#7LHZ>YDpZ^j?Hn z6+5uno9Llbnh<qJ#1$(7(*0}x+YP))`3o>CNp&}=8IzrQrBZi$7w9)vBW?z<aAtOg zcEo370Jn?DNci!KJGN3b7gR#$N$U8o*+cglWu}qLJ_g||!$^(I6816w01qKaxL#EE zX%Kfl*k5PnC_6BCT)ZdOu3+=%t-^^KVF`S1eu<d|lFz%MbL5IgV$ge@s9*7{+cIYe zAH>dV-Ymt}r#ZFeUBVPMbZbKvy&ufFO}9EAAm*A7o!lpg=d}$^;utGr-<;Lxk5ca- z-8uHf+`e;~CaDEiw8!NStuwu@l|p&Y6Qqnuk$lne?`E*axSo-<a253*&Ai)R^j$#u zyZV(qhEE4A<DZwRv==Lw<%Fa~xDZ8tX`NXg_JbYwU~_s2u)g&BF~S$<c`{F&yr8 z0L7={IsEFW-p_U)OK)3u&Yk9U&WNSm)_c6FOPceBgAzZsdyfbf+1}xI1{2#u&2LfW z1m<TjSO*dBVuG1*^5#cQ0;+<ekI%d39iF`AR?0$uOZaxV5*(JY7~&Zg)o1a8PO%oR z_YIA833hQddME$dz@TI-Tubl<oXExc0KPx;A|!i2T;(c{I8dKT?{74|`G|vs5KNbG zE`#L{Qsp4T2m2CkT5{01USI*bR?S~1RdOtRIPT~Nnr9Be92nYq$OM!T3*lP);yN9o zz*MQzcso|<-6L5rqaC@O<YxziA6325Ydax#vUo8hGC=;LkVxfME>brSqcgt_AT=~V z9kOOX_6^cB)%3Qzb2*p4jw<nz{NCjIM+o%@5dj^C@+TbQ;nrTJziZZ;K(%Ncg<hcV zMKva$ApVo?FfM+>A(d9>>lE^*_y(DJt^X1pc2HuV*y3(G7q6*+W#f95qL&KlJJ{=o zV?>cn7H%)Xpg%2Vw|fkYFG`FEK*Tb(WDPr|=%FZTX0SVQ0!3FZ<7k~5Yl|fvKv>=V zcBY%n!{ZiyZoFBU1qr=#hU1vn0zD#_nG&@}#l8mhE$kXiA;`#R4<UW6J<k%m@YaGM zZ>}5G0y+12BD3D%nAk5#!??%S*f1%%yE<y<7m)%0)<94$hv8^mf*g4WEF3f|(j~0) zn@1~?#mdb}kjjft1{^M-V!#g)J6rCoDxE&1f2@$rE3IBXZbK!X8MK|Uo<(juqfi!{ z1_+HtlI57gC(`*<(i`Hv6xECs^*BIf_p(r?#Ix`YKpq_hO0NX1ZbB#p0>!KxASRH2 z6b?4D(-#q6g1Id4X<He<zK;ZdygJwF#K=_J^Iepwqje3Q(`#<Z{M%v3X1dm1OL%8> z>c8s2i!qH)u7E{jZXa>nA<mcpO>;N-`T$7=|FL9$mYE?2rdZ;AM~yDWsFnQ}Jqfkn zf+g;xTFsBd;$enRmxOauBgI{tM%>L=L6$dbXk!g|=Y^SJe0_9)2a?r;Ikf8hQz4O6 zDY)`9JBh7za}$gr*p*01qH$)O@4ILt#*lh_;o8#tsEeq)y{i8pBzs19Wmc@!VvWGo z@`C~xC3vsx)%agD@|et{^!%SK!nVkSj=Y{qgFgE&2joY|up#VCW7^tgXVu*|?yg)J zG$JsFgj^ZWO4czzMxs1PpOn1qwa3f=G<2s{8dT~U&s>NMZ7sf8w&jsO7Fh)B!+64s z0;nfg9aSNvJJD)6vW5o2`UM}cB6L$}@Xiw*tFQZ^aP?!nw7OOYNxtgN)1GE8Kpwt- zZ%($=(cA}e49)ct1FJsH;0gTWMPUr0nE20E1ClhB`SwoWx6I?Fs!_IIkw}_FTt2x4 zgA6+vjP%!6oNo7!FqkW!ib&)~W>MJ?g*2{TAW(6{79Wk%uJ)js6(6cJM|69Q<J%ip zA=Y?TzVw|n8P>IvTO1wngC#FWlv!L#m-C9s6xD7v@GJDA0?gNrmEr?G-G}UuPVgq? zBigk{Lj5x!E-97|gm|wQJU7;|vrCJsG~K@nb7qfjD+nAh$7s>nyJ%-UL}O9CX+(Rf z{ZZ~Y<ZPH{)=03Z5YOMgjArfRf#ZjYBRmUQE0`8}wddNSIN61PTG<VTGEFnCa0HqW zo{vI{S@zpt3Go8{Vf#R<JOiiR?ND62FYxdqKV$)i-AG81tK~<L!NBIKW~nEJ_=r@L zC!r#mpesr^$+}Aqk}J#|-kXKzu-*XH@p=jERgAu9N>oK|-@O6<5)ZdqL<au3GQ)u& zuFXT_MdW~G=%sfm{O_v~3^OOhxaU`}QO40NZ|4r5h8ljAqfJ9yf`I~YeSygMf#0-s zFunuQl$ZlX)uSh6@~KETLph4Q2$}NcxfM{5Vr<GMyoor+D{s<QbYvwmbjvNjC0!D( z#iTH$k~|y05GbZ>o5!J7ZU#O*k2=gLwUnoJ5YO=)ja_mEN)Z%Fh~UI`{Itjw&8q3p zLL?0=-2*dLuBu$YbmTvv4i*&pLaWSk6}W+j3m+4I^)xCRnhhKIQB0GN0B7y)s&zK0 z^VlQ}7q9^I2(aWYEQO?7c0ZKazAJQ`_j~5A47a4RK&LDn62G>>!6Y_1d1e1z=uPwb z&91!+(&_)~O<+WlDYC9EGm_hTTAe9=G(_$fCJV_wPXHqWiCj-ew3jw`&Y7G?(meqV z`EoQ-#^z_s-SZ9&qZ#ovzi#?BuKCpfosBMf%+<mUE+=OYOYu&d#OV@i-Svjif#Z|* zr&SOrko_swofI77nttU+?!2_Iw5B;K0qXXCMVj%H1kSsq=$9g7t@ZEqk~sA46ID>N z_c24sIpR3dUDzsFSPg-#5c=>PbSHp9q6v#vjQQ@dv5CJH6CtLj%1ZF?3o)nTBS`J% zQAAXTla|Q9RRyb-G_$tSjVn1VVOG<45blM4n-qrPz_-w7=T9BuC8J)(TtPy0yb8Ka zN(9&a%IKO!-b@9SD^X+#C+nwfzv#p<F@Fx@h^GSD;8k~uW=l1WicL*oDo23QNRXu^ z^@E{wAof%*VuoVsS%0#KiDz!VCkD?2{exKi-1FO)5s~@2Esv;uT2L_STT3kpUKO-| z>ukG<Ca2EQfg?2W=r;skUD<GIM(xu^iP`M)*7^cS916w`Xn{RvhUOm4mR$khbFarh zpyPYFgYY<M@KshNP6#F}G9B;;eLq2OhCg`DAZe{cJmC^@@ORYa^D3)sdqg=YZy+cH zl2_#46PC*7@|3d??wKwg;4QG?5g)Aj@~Mb}i9*4Ic~IaMcWytk5WtyWi?nx*3Vd7^ ztX)LPzfyu1E#l(v`Jtt9S7d(vS!YnYcAUK-k-Rf1fG5T2j>d$cgaoP%<u%idB(qUx zFbr3iAn990+_k+*aiv2);_j%vFIczWBvHtTc&nXlXlbJHk>#Ukh>JAXCe=Y?Ch23U zPzD^?z#wHeXi@*}6`U2YU8pSrZMFSLx~s3CckhH59M1e|d|dZW%HW7Hs-<+bw2e=X z?5p@5aaSVgf-nmy=m5a`fPvzmF@m#^*3<$cC5N!<h}DIz&orK8|7g(1B1MdvO;GGL z_s3pe51zU#aFE>T2Oo~HA%^iV0N7N4-wOWyUwA98W#3hC#Dp-Ycvu9ANE82^(e9Fu zFe|J|_+|54s=Fp%h7}fK>~r~Tj|DwA<6+75jNO%5INF(r%@H_~^pP2Zi^Yoxa3b7P zf&E7e&4Shs?}v9353B3(orFFxq}C5m>D)|<@wC|{6xGXfLTrCJ_zeM@4|(&gqsZ%+ zlFZU7N|*bB(oS+RfYd+|j;P?!)v#(?iiW)rQ+;DTfUDVleav==w5`Ar=9{Nomz0x; zu@J1>LBgD9ejPyI9wH(asVue&{}lD(TG#a^@<qNR2vRO=kD$+7CBLYTnYtlq9*nDr zfC%s8O*!g%wn%E^hQkMA4MbaW9iB4|lUkBJrpf6tHWeIH#oSH5OA-AXx-!ksYtr-c ztr%{1c}U6R5`fgHX>YBtNi&r^xc0P(^4Zknevl|Y>IL+0`NXN{O24G^5-hSG*Jp6k z5yc{DZ=VPPgI(xEZ;GOJi(wup)8C${LY!ftg9=_7VO2wn)nHc<<T-F{9vDG<#V|P! z>BwLCOS@B7tYh-p5#$<w4;TKWiMAe~)YrTEvtOe0_FapPve8qVuxpLRnH$sRWH(3; zRtLgLmkDU6MAi4?L$H(3&YI7_0h-H-pUafE(x7spy}Tc}Nd(MTK6{-#?=NEiylsCL zY=|JLqPQH5G7brArmWS_y_6p~f~PjL&Wr@iuZ+g=g!M;U0CU%!=j8jS8gqo_Be7*W zt<wLboH;v7^Co}MHxRcjT(X11HF;5?t0Xxj^MF$byF|ogFq+T+mL!n6g58Kl%=_Ny zenvk8-<~!{e(_W<g#jIyIKHtRwmP}AdL85uNX(Hxjl~n)x*w!e-^~5nI`?^8Qb+6I z!VV?M4(f(_yNXxk4^yBclCd;x6$zds3ydgCE_3F9is`Iw*fp7V#Ha0%vwVmUT~NL% zDe(Srw%S3Xl-KD)j>nDX23<Q{#E!FtOT>DMcIu%~9Wyb@W=jI5lv)AR#eUNvaW}16 zNyVrEX<yd&P>g3fS3}K?C9uxJPj5$Lj)MSgc%`cpFw#RltdW^8P=>oOtu;**Q4yQs zuEPRvI*K25OYnCdlh9cljarUP9;X{#19*6qm+?eAeJ3FJ(T~AVt}pc-z^B)T-!0Nw zlLLz_#C3U~O_bY)&FTMfNQH+C%X`~@BuQEWYf_RwkQ<jjM4!}!KnyD2Aze=}b@k}_ z<9ffcU_&W~mShNO!;>`5@AQA#Y-s7NRtRpkbK^f4?!6++zRiY7nZAg?f+FU60)C}8 z&Z!-fh0A7qIfdU7+pCOY|L)C8!K)QwJaeq*wpiJUu8ys#;TPn-M`=*Ir*xW+=(^9; z%q!(#ST`w>tTL5a!J)}}8TRcjm%Q~>HD6(rXd|K`RwKHO;<`4o03UT@HF2XJoCK1R zR0-Xm;IeYQNqvk%ez8}6d!I*gO@OW4mCcnv;?j;{O@;2NbW3~XMGcGAW~$)si>wr} zcIQlr=OBBNYC4Jm`+SN7cTV=elh>Co2l!ZltKKEMG7EGLJp3hiOOZ&3{X^4jxrT|O zkn{8Uya6d-ER<itQOq@O$``HLov|s~+uH}yz1Ok592=)%>`bk6VIKd^%mRAt^LIi> z3UefoU;`IOGlBdavu7kLOH+g3=wBq~%L}!MKoun((kt1GsuW3xU2WpS<{ZSU6Mer= z*eN}Y0%vQ!`{;9Py&IS`311D9vmBFybBe=_u;g4Xh(%|IyF4be?vter^J7guCDaH9 z(BvZDT3J-pf9gR`U#M@<<^Yh!zWeK%<;DAsQ~6X>L-LCpc#eHfk{-l7Q4?wi7N;1j zLccP9emxm#w%4h8gbz!Qms6~1C+VY;JI2N9ye}B~LZE&s^;=QEyZo}gGHv}IBurJc zZ#V=adzcCbXC#&V(h@1g#Tn$m9}Z@Lb~X8s;tz_YirrK*Q(pU7@d6N}hR_U+*gvp> z68%tQW&R~#nssWg9E20&_{QX4K2u)2*3zQcbOlHi3$mFYTR<k@56tLIbgt+XVPOs< zHs8mFK*6P4tm5y{9q3hm_kv?%oQ9aMNWlSlxl30c2^|<-mH7MN_`kQWJ>#tKk#K4| zUD5d=Y3>1iB-!fxSb$Ar*weEp-fssA;o^B`+^t@SD1{$;bjiKyQwuHaMU;udAlC9d z$ki)osR}!9JjPvYxKhIAb9lP^O61h26EgoBZ37|)8rJaz%%ZI?+nxEQquq8!K7oxt z^*nse9h_hmrnj?V6k3!uew{@_?Pjc=GeF#CTSd+fi5vX#cmX_usZ0VU|AZwQf7!Vp zg83<BSXC1Yvz|RSt=ACh2-L&&y)7ioGs;a2zGHz03#e3S=l10Lq78$V4|AorRKKE( zM0iX(Ud2L8=+?ucqO*hvr<h#l%;bN@#2x1e42DKT%5sK5<2fB>B+FQyzn?fz3yp;p zgZ~Yh3;sE@Mh7fJfd~|%lQ*sy9Z<x%^-N1X#G_VgZ}Bf(2p3=Vd2ja*o9MIf$>=P; zP|yz|j^v!+XNr?(2N)}4Z}rO<<Ok&KV1x>r&Ch0LR+%yic2ZP1?8R6y4k;GSOzW2f z<nbZ+PGOU%(lr~arTpQl{i8<RJU0=lU$nIs`F3o1NDiR%<S@TNa?8B{T09rf=Xy<R z@W+TkHB+hR$%-tntuhJ@55g+%b?mZvjd)eGn+$^M*yPVXQ@x2#gOjifv}IK<53om- zuXtz)f!6i3`V*_n{JLxqY4=8Uj;4d^Ud3^%t*o`9X87RIP|0eo8jQ6MyxWAEG*MM8 z_VX9cR{(W{Y^btGw*j{Lk0_O(U}eJ;xtR!>UVS6P^oRVGF!Y20HBIM;`5$_cNFGLh zsB4)VxtU=!OkyDD6RL`l+c~OF2xyp#!Kas*k^cHT<kl2z4AVQ7**)<`+cRmU&Sh`& z=cg4%?omz$6XSr!9VQ2da^k^q^nXaBXH|m%V*uo8WXZ!=&-aJ!kVt2eQYX^gc3NxP z42&M-ff`dN#aUh!S%|ey<yq}z5H<96riw~Ue6YEiOmf<xcv%apR%*=V+enOFn8m!u zZ)V^7pZzusAdIlb7R$jEKwbjxljm@JT&aAg0|NDVaVV14{YUdcAPhQeHsWuh)eqF~ z%)k_UFU9bmBSZn521bSHE$FEB-)qlwc=eYk3}9d1YT`u2F*VYig-vPGVZ#poI!T<l znu`jxXE7M(Kc{J@X84CU-qH$oOB~vd<$9;qlIujO5|a_|H9Rsgd>cb1o|D{_<TR@3 zy4};bc(&DBs(nbpr3v!#+%>ZnBD2^|RsodQ-V)G?l1FLp>+zkHbk=|<B;!G6;l2`? zQ6syNtaUl2nSls_l(luymUu|=QGAN3;q%E*AqkvU0h2nK+Xt)PLs%G}McH|8JOU<6 zaw+%M@NPijetRp$mSWYW*GgYjDyBesqI4>ZClQ2~R|UAf{7z4qs<iG2YL%L8Jg{_B zW<}B%f+TG?sG{#wV@ZXsrHl#RVu+`W_lIe=FBc3wWjNz)ISJ)=-R~z*(SjG1&xnyv z)o)lz=JU&u9c@`eN|ci9N}8MtbJ+}V^15dG0MSnF0CdWNZyp1(ds@(tLjsY3R8nMx zx*}vb{AMG`O%Aclw;GDQ|DXrc<^ZN*Sl>f9%$JiYA!-aq1q9m*Lt9&>MUU>Fi6Wud zg5%w%Jwv|Y(1)%oHqT{d)l`PE&5KE@0+R7o1*{@W7D=S-iK3{=D6xQg&uuy4Q|8Z{ z>yJCzdZX}N7|`5!u6&V^#GUlv8)=8ICjq8E!~Ia4>}J7Ur}*P9@?Aj)5&%;p4F`%^ zB~c*C+E6027e;%b5AL=}jZUw)h}h22e@EQWtQdpNavufnFPTW@NYJjS<DVZku89SG zXf}E{Y^?%5rnr6*5)A(iQlG5tX=6n7L28&YAq=43EfDyJDcSB0sokYRNvF3647&i% zE~*^<q9Qq2gbee3Rc~6`2L!xOGx<jOrVgerFGVAx5pbO)GB2f@Rw0vnPvZ8hG&!+B z9Z}S&jE&c@oPQxn#gq>91d`Q4B*ovcsa@B-0XN3iTtA7bqEgA>sO?O*C(1&H6$vBC zYc|I0%uDodZ@1aFql9ILOI3~@Q-y6^V-Agl2SH6X&K}i2%Fhm^fks2F7Oq!!G+2JA zr|gbwH1LwvGPSY7;?tOz(l0oNy*+g_HalieiHN&y!t=D0Jkt8NyF67H9BJ{y`q-O~ z{{MDbNjQh8fd#Bdim}IZsd$pV!^gnKc3nS%k<b*zIrpeO7fz!6?DnR>Wrz7w)W(Gl zu!8lk;W58UIr_)$AClfcRdGf!rWgeWDQFZ#W*xAji%m6hTEI!3!B8leJ2JRO*6b4= z(1iaa6iA8$Bi~E#e&GNZyhow>XT6YvD;X6qKp&L^|K#F>Ay^Vh5#fxwtiEzUqynd1 z#2U>UGd@=#tC5m58>bk2Zb%t9)W?nUnZe}j>f7Xrd|p2R%nQm*fY2w9gl~>)MP?s; z-`S=nKVyoszR(i}Vqzf8zOjkDO}jCF{hn{;({UH*hht{*cs8Wj;VmhJlre|qDzgM8 z!8pgQ7|B0tyMg`}Xz>~2?@F-aii=4fD7ts1CHv<D@jp1FG_@dVt|cir;))(=j4>?~ zkaK#E`F`93-KU2j*%^%eEAkO7so^&pak-wF0l8~bkxU9NEqX7!p6#ksw5P&>7wT?t zW!GZK`#8ea3o!KEm+g_!1fF>)@}mL#u#=ctbfg;Xwju||=)o4x(eHP6f;3=?tKWM5 zqD_9>J*eO1hSwE$z8&)}K*gZZ>86DMj(J}tHD^(QgzemV_=I`fskJvwe!0gu*H1r` z5cE>Pu}k4&fl%}ZQqxg-&6DZdaO;W3ovWutnxVc<772Q7fl%3IEH{Kb6DXYRlgn>R zWu4eY35mL7?>5I_eovDyP}TdtM;2tZ>TgvvnxEslXNDS=X+7CZzu}d*2&sOIe-Cqh zU}EnDnq)E{&;!t2dYcHi;cqY*6CfBC3RajT#*k};?s=(V;pyeRg!|XC6dZ9&G#m`Z zda&<HMdGU*;C?K%g?BnVr!i{|f3u_gD+u`%*U2|^dw`TXLEL+Hbgj#KKcbsqi{Q=) zV!(Klu8->GW)tPFwH#Jl$r`HuB1sUW_)*giOus_JQ<Kup3M<dUn!{ks>#k%^&ka(T z-3C7SEX!?b_U1MxT7qx?DUH)|jYHqCdvvwT9H&lx_C=%h`9M%4#?<|g(SN%pF8A=; z-NwVpYVFS&aDyzR8uiiN#Ie(Nk}U5jK&!lz3gy@LuE{rOneKCK>te6@y3Y0Lu$pLy zCG^UC`HuSE8F5<60)*uMs%^j*A;zHpr(fWI1IYb=00WDIPU~BMph}ybCWZr;9KAwQ z6dcxBkixG2V2605Be%l1<H10Uplr6s4}=-7Zz?lTo7>0*QI<{ikWl@$>g38{Y8HG+ z@|LckjUvG-P7>)y;pD|1vBaB*<6R+u-IA{nQ$7eTn#A((qlhX*3zD?a1KST>;bjk^ zT5t4O7;7COu44CC32o*++8O|EFCN8%+fz3M^8O4F<{hx)^R>_r%~*Zo$ntEI=rUN@ zIuZC*B(<<hMd5ofQ;KI%sR|Z<y$0+4lj+%K&C!;~8`#fwa^qzYd+|2Dk(djpz*&^@ zPaoJJ1XMG-+GHC1-h>Mrx=J|ky$r5y>g9W9o1-=u?!u4rMp^myQA7c_(DiTJBi7$$ zd}}d_7uoqaZP|_&q0cyJm-fIkdfTwE_55OlDk&%61q+4K_4^NGu07WtRg*~s5MSad zA+Qs|*0Xdy|6YkvB=s^QCGT^D5G(an($H~k*Zx!EUUzPX%}SD=Q^nlnHtOIOsZ3m3 z3+gR^2q(gr-7KYkWi$agf1NNjjDKZ7|8<(x!vEvTVtyH8sS~}A{LT?W_Hd^PK0JYp z_sb^%bl5Z^_%xjn;bvLlGiErxZs-0yLxIBiOu+A0iT}YR%=~;Ym%Zwtw>XHaBwc-* z%f+G0bI>cQL~LAJC-A2{Abz7^Qie2*8q%{wa(s^qI%D2fUfl~gJETr`DvvrV&WJQ4 zu-Ke2$2I%>u0**HcLmampb%s(ZaGRX(!K*m#_l&X5EtJuI+tEZ1q|Q4h~ttEZuhd3 zbx`81nub5MNqVr0ag;LK3iYfZ{K?dQa(aY4kRNzE-O9d0|MzeP&@hbI{+q*oXfUv} zpiPKxfZTuPulrmRZOiDNRF&@$jg-&zoH!i$cXJ1su6)%}DwK?379b=Wwc+_s&-vp( z>TbV?HY)F=Z6|kt7+dG6M1$q5>%ypvkw;*iSVa1``r_#3oInE$+QgY{&3h)UE@u%F z&nojNK-O|Sy{PUFvClS&jt~#e=+=ZY7I!BAkp8-UxXp;CSab3F#jo>w_#c9dv0^~> zS%au}(OUG-K&`)wSmA-y<|mTnhw@bNFT9PsHi~U;*Q+HRyK~wEnU`kAo1f$85|b6n z7ig$OHXA`H)vMZx{%^D&GrSc0W`#ia@Hh)G%{+n?`-nk1keE6$|1^S!**f0VhZ71s zbP^^SCJ)o~hE`7^=31X%>}DZ8ER(`T^RI$YWvDwo(tY7VPiOPngCffcS(Rxjvk`Kn z+B|^kef&;LEBv*!qbvCQJRUh3tY>yQ^==nduMllonH+Y_)WvD~Z*|`P;p&{iGXa)v z9ox2T+nLz5Z5v-~PVmLHolI;`FcaIhoqzT@S9{<0Wj|HjRcozRzQD4}veZ9G);?AS zp6ree9-H$*YEwmd%yTbB8hgDD;5iyo%Zk1Opu!vaOo9-9o56{9GU*95%Cf!z?^B;3 z4JU_MB6MDv*V_@|_=6kOXx$MoV=TAr!1l~Tl0fX5V0R|uU2^pItS2&<c)U#r{H$_@ zk`?6_=Nj+ogvy)Q-5l~C(G#IRQrIXr(VZPSAgYaM=uYYmzof@5HYAqC0e8)bvzZLQ zJg4rw(JF2A>ci9wg__(}rECG3znTu3l0AZT#Dj46(p9-ahiu}#q7I%N0?eVdkU3>z zdP86x;0TdGA{{0|!yNKbQsn5_rv=;fzlNd&@TlyV`SG7(YMfZ+ZuO<Qzx3-(>sS6q zvi&bOv|VTi%oqIs)ku`D5sR~bh(>k@;G8xX25@eU2n%?#4+aIW+h9TIIoCpn2tw2o zMJ{bfBKlL(qMVgvM=NHR*duE$lQz1^RQlcXw&Ky9A&G4xd2hMZjmyb*4%<QqWdT(d zV*`HPLl~UE<hy&&<5g0VoRy|jPJrDv=f33T<-R3kB4_G!>Bd9uNLAW}zbZ6VF?+jT zyny$KR*z7a$omTTAq!1ZW+1;{nxXbGf%C9eV9hLMo)X9UH3f<**D^o!m?=!0)N5(P z7?w;9H_tN4cVPmoh#DeNfsee}Tz}>a^;TWL0(({9@(RCr5?=WCN2B1EQFWgj%c~V; zVna!&<6lMWer1_@66_4Lcazu9;1$*my%~XsnIOJB#`p_}w}vT8GA|b#9NGl`Q5P<h z)3VE8<?|z}8+M1{GMM4uNaPWvj4S*xWoayq0_mAGTeu<!|Au;_T{}1b^*}EoNafxG zPymJ_hpXBdCwMHyXMxZ?w8^os$Oxq>SypC3I;T;=C6N>Hdz@{Pr(bJSe|G-#LE=}5 z(rJ4;(N_t8_AA`iP+ZY-L4lJz`!$U&r@UL6TLos}(6$Ymb84vsFZmR=OS?iY;vUUj z^QyIB*>0J#hGlG<kuRjnU&2Idt@wFqd6Bx3!_z{KiE{F;9LunT#_xvhZ;AuB68=bj z4V#CJd7;SA*Z)}emdh)~gup<cK%)PZD;A*2B^Uv4X8{Zfh;syn22fXU%K3LM-nHVA z$bws1eJ4#yACeNQ($=UZTdNqr!FgD@S{2%=tG;`_jA8Mu13(i6osN2ZNZv&8p;g;! zl^IcOsu^wKt_BF9iNk4qg?S1wffR&DrUe&}8nuXo38C{!+Pq6PpY}?)%f(5Lob`F1 zwMt(*5pvO%(7T`2fCjEq{UF%Gxfd{ZcQIYtu|LI{)>Z=Sbm0+%Vdoi-wc!favp%t5 z5J=WLXFnp^PI`y6XEOE#*)&naZ0!pW0vg35X>gYYZ&ghd`|F*Zke4zIHqtAfKl?I< z<plW*-Ntkn<A5UB`(Ohm!V7<UgS?0>G5g-<5(BzZEOdsU0ktSX^ydOE<X;4W`iYYR zIALJRqyig){fCF|KR~EFXrgHnPb7;O5H>t^IDYt&;5C?G)^Qf6j%A$EZ1{1wp<sC# zmvuY!@(Dho=WpmfRMo!*Hx#tQ(ngma6BrH3h8A$9n`K+ITjweZBt?XaU~{cgy1=ph zb8ft$ep$`E0{r=FsA#btcoEU?9Co~L4v5FC%v8($bj;mcS^L7t%0-z4##E7gd@<ge zo2>k;3Qo$ESJ-(#sj73cFD_%)F1Qkx){JV!&lmO>Li*?kHtwqLiy`&dGpHg*t(!M( zJ%=<h{MmLGUc<xD=!JCSxD?7)xduxR7VuJH`M!SsQ4)}S2{2z*g)nJX;u;*G`)U7W zyDF2~^>TBh|H@sN6mTGBnoCn_k7YoB=U4mOHq)}49)X-9WK(#@aT9I=cZdDot+Czv z1We}tGYNqs7hryf`2S2LhHYmB@c;TH7!a@tMgqLL0D}Q$&J&>l0@Mu>b4V}(j<rxy z6fE(UiH%K(vmOd3JhNL86^7VcHJZjtgPI?=v2W~hG7Zort^}XSjtQolE?{*H6EXhj zZA*e=F9oz>{Gzk)VmWz$YC0mKMg%Vd7?veqGX-<q7!*@%WPYJbYT*v_9&&iGf{(?p z*Y1j+ERBR(yr2KzxzKZ*NwAhBv>6LT_TyOPqI3fy`M^$Q)*FrdQi;vbr{@?b<}~`F z5ujM5L{KwIKp(~BC^_BOpFuf?S)*VBisRpGj(X3c?YkV!tq+yp@%HfOXnm**wOC~_ zSRZOJggAe@p+^(KP(Xhdf$5p^qTtmj`QYh>Q`g~8sT%wOxW29Xyjz9fz{h`R)eRe! z@LlXWnmYFnI%K8@ktmwntC0oj%78m(QQ2nTX72WOMae}DaFH;{X-Q1sGagH{?mp7P z962{|vXC+^5MA<c3;h|JeZb{Rg(bRpawv*$#iRGZXY5*SmqN{XBg`!qttVwV7{rHY za7*lM=4mki*d8W3l3~j|b0~^os&ade2O{Z8Ss7&Kb6KB;PTdVFp)hGmCPD-YH_cHT zA|}7$ZB6N2mgCFsmuSX!COfn?^np?#tN(2XFaFZ-w=c}STXf_KKHBV&*)|}k9ct9q zD_JOe!b@CU6y>@232*nR&@$S4tP63cZ(w2hVDLgtXHcEAS?Pzq*wwZ+lz8wzeGRc> zVxXS{1Vqga1cdfKWs9Oc_7Thw8esMf8W?>a-7306c;cwEZngt{3eD{9lgq6!@rERY zMY+5rv4vaF_H38AKpWHKnjLR@UuR)Jd?lua0>cl;^xC2XgAzVIC*Zn;>k&nx%!#kk zguD1@*MGa#nG8dySqfH8+9ydLTg<WI7^W+uIaJmhCmdoL-~(&LmVBw&2H+%srfOD7 z-A;%)m>#$5hj|XP)xvC`O66GC&gSAE*%Bs&_GK%4M05rxL+$YDg=)C(RDkriYe}sj z_3gG{R%=32Rx~1xQ$YTb>7mVPoIViH1KD7D(1@=anL|v*Qb6#<_G<vE3X&m=+_Wj~ zCB7mzcPzz;CnwLx8^nSm0@$TCAYFm}>Uds51mEiU2jsv49lT&1E`SbnuB7biw_GH) z_w*)iOPy8!kqw4t)&q4T6vXASRdhIH3^|u{++glploz4twcXnVZ>iR+4G#JdPrjPi zm3_Og?}A)O<h#S`6{gp@Mp8(yaKc)1;}2U$U!kJE8bnqhyM|4l1RyZJs9Ot>D%P4C z<^6-oVcX6r;H2UQ^3)`*IDorwcGFOUbUQ(cel-VC`g2@wii|VeIUpEUnIj{zQ2EEu zx`-6T8Chx?G8E)!Tc0oqhmL<@`pyw)N{y(=n0Z+g(U;(ynhg+JZsVXJl-v)=Q~_)G zdS1AlmITg6deZp^H?hZCCY+xt$qy2c;c2VcStUz2O7##K1`r(XSrOxjN#Ms97%sr? zO#x93c9;+WE6ES?fZ26b=jS;3LQf9fjuWrxH2X$;MrecjB2*19N1x6}E`}>Ukj~<e zzY-mtL*h|^bkzcG-9T-#MV{)FwORBk*3kdx@ge9!`A@nD3*`+>|38BG=uHR+3<3An z^viGSHwtK~pS`5Hwd@7-Efji?IN*SFPbpalY|~|mGfJ@mAV>#BYq*?GiUBL6^{nLI z90g77PV4<-)L^oe;NOdr71Wju1P<G?$ox4eXi{iBz8P4f_R?}pbSRl^b(55k!fYcZ zJQ=8dFJCnn8L7HGJU)d&-}~Zc@!NggH&Tr(q8l-uKWR2jVN6O8g9mu<m7)OY@3wkB zd-zH<qY$7LRd#la;(nNNAmtc*g?sYpniu3{6eH+6ojFo7znLIdsy7yc&J9ANR|LtV zjUY*h?i0hR+aU!j*cegnQuD*{!4_aufZh-P0y`4HHn2{>X!K~SV9|`XuYuR*;*Rjc zD(63A-gyS=vq1>k$|CuL$bbmA0DZBzfV01w@_=R-EDas5!fGhe@Jh*^o+R96`q70m zA>~tt=f)+XTI7<VCV=jsFwI_p<8NJnA?ezX9i$r*o7RqRzNUlZh%1U<iRU`H4_QDK zgq7x4Ko9%tRHA8^@$}sztr%=HgZ5A;1IBs?Oa`G++0mKWEK>P*^9UvY&;1aMLi2n` z+@|fSvon{F&>)0peFlAJK&7X;xtOm$@vd$2?CAvANa*9wGJ)xrwjie8yk+!(n|-n- z6tt97c0o;1n^i3tpT2sM`$?7iqG~%&l+F9?Hd%hG13jqF3;qxFI1Sk~MO~$U)Qbuh zthke&Tk^3`7Xmc)!lQeD>Sq#AE(0+m3)AL{bDW>yS<+1VDeH3q%Zv6-<G8aTqk768 zG9tVUO+y`+fjzV`p<(CA#g4uP2}JDQhat5u3Y51l$t1aMe+bZolgV}rs?P1oZM)$7 zqrRqcv7r0eKsdzZjUk!MD!v+f@lG)og$b3b0%kqiW?5*@JMst6i%q|gwO3C$X6743 zeJ~aA&J^zu0&Y+`ur4=qxaY?Y*LRzF?d1B2=!|7Oi@Q>~Iy!cPYA?=N?%ibBC>fn( z5d1G@(`FhkY8x`{EL;J>`afD)F+fyXGh2!MHXt|>{jv2;;DME=JtYbfOy6R9VmL_R z_qq)<Mg#zFWeX4&l3)34AAAk7z&pg!-9E?i#FmP2g4!Wi+I#BJbgy()mEb2*{;4u} z<AscKMN39FP%~tX97iitib}W$eu_2gke99SxMP3ach$Hf^r)<2ZOErzFdG_}4;?C0 zn1K`O8s)^?cxY-!9|N;;IIl%Wp5=B}ned$K%IQN~b`21nJ;!uin1I&tH<|PCuTare zQ{=|Ymrd1!8PKv3E#P*r>#;WT;W?LB&1HivYI}I*Z;G8y0%;Y+HL3gA$Qme-EUt_X zua;-(OkRwtxzpOHYVHktOEXyMbRkIUXWe`mGzFo`?WJdNM&VC0c7(rz@W_;YIWSx; ziWS$;a0ftrv0|}C>cY#6Fg8o#Tmc*81U~ftuouR~wBO8z@*y86;s=Av<!Dl#<0{{= zh=nrWRPPI7UJD71H>-6<m)Q5<S%DyQxASD=&53nN@s+}G;3z`X5g;q;+ItA+`;meC zQ&_cP&;s_F##?efAkY75i}r<6qf?LKESpg$TLcgcLe$CNcB8TaMAbImPz4RHl@88S zO~!d?#y93xs6vYsTRW=7HWbCyD6lwFv$OKIg^42q?nw6rC8Ap}44C$S8hx;dX6c1+ zp4^$Gr{z+$2)mgUFp0*-yxJung;Bq1TVGgXr2cwDXfwX#^L)pVU(Bh1Oz9<E<-igo zdjc$o0FpLB2Yyr34|o-Q6vJXp!To7Ki!#@g<S`HyVw*KMK6&h~SccMJxwN=?XR$1| zr9L%$`nsG}Aesq^ZL>%SY9cc|3O+cBRxA@jkjJ$e)N^kMGYILYfW;c+_Dwc9nb6au zA#VXu9&WQvYSOMqjdh;h>zK)Q%ntVKc>?%Tq%=roVCf8Ss#q<iZpbNHXavBv{cal` zWXb2u^9vPyqB63L&QAQZ+2PKiH#}(@=13BV86hPP0+6W+`cupQ!x}MRlJw1D+&AY4 z#xbJuQp7$kt8y-$EKURnCfT67v?H%mUVZ3~DrBS_4YsC<2!%$;2BQtbAayZgDi1(l zsyd5FN6k<a{`SASxLBM@!7gY1bId%WlrPNx{%S>e+Ys-DQrApHU1@5Sy<?nHRSD-~ zzSIs2H8gr~89BfJEly-5LG4f)4Ho`PkQ><lJ$7(Cj7xGpqkR$iGIs)RN2|=vf3h_n zA%06!A_d3^d=QED)m){FApS%0;}H<!T2fN|U}|vp6?Ennlty;tiSX+&Xg7;!?s#IN zJ<%`#aHRn1MI%E7R#hP8+M=#IJ3h9WNt*@xuJ$-eK+b)S!WWaf>o94JD0KrBhc%tO zvQlA3u<|i)e3vY<++l3byvwq277rT^ZiXcma1?(`3A2)dDAql6JF%vk4+6lEIy(tf z!Lj56Nol{XkRPDb_H-bNg&6Ow>R--)!g&V~_;AAYlGwkX<%p*a3&P*c)#?L7gILln zr!7#-bX5{16Ahp|y>JRDO<uvS5s_xb#b+D?>wvKA)E+}5!}@OdVECd922ca?K3;`` zMzzp^qm7@q*0XZ+;lX|`BY*&ZmksjZz?5E^1ov;R$r9llm}3|y;?YBv1!9J&-Z(@E zmwJ2ov76KAotyPqQ}k&c^}rBPoum-bZF&u%pcfPhx#8IGsX@Htrmea5m~5KCYXQ0b zJ#-vo(+4-r`7G3T|CAqnr%Cz$INS-o8`-)x=@5-FA(_f2C=@)w`hfiR#O^Ps3y7X! zF@rpU5ge0AA7GgxOGB9_AH(|NkhV$dRccidYb*=9#20}8A=VMuMF}(>`^s)g!!JSv zytQkSlm!wHh3Vyn@E@u>g3EB7uc05sbsnX|t^y`W*T_<`AAz5=3IrePld0F<(Xw|} z!zeUO+ny~0mh>#xya3^$F`1i}*mH#$#D8oK4`Xa>3+0BQU8OBAgqQ7+-`n6|RPNTH zyT?mag-P^=G!s~J?;cptTiU|LNRZB@cY6AWi*42IgtI7Sv)pQb{!!jLC@~BQny6S* zvK)Rjv{oY6*J)uY<u>KRos%fQ%2ztQIHT5xHjc4!OK@6gZ~S}z5Rpu7G?+!gqCRQ% z8!iLw=^Hb}P)CX;(+}QT>@o@y6*#4^6-P*LV4)?>2o;+h;Nyfe*QZ(sV@QMmU@UD4 zDhKzo0l!cGa3E}fKrV0>AYB!yRI&i!5I9+}(tJSHHZ75kxJEPixMXOLSMpVg4AUeG z4RLKDrw)-ULjkN7HYYl@V6H{1$nu4fP#`=F@KxLu{!L<$-5a+1)u?^&@^VZ3)Ha4# z!5v#qBlHVHn0aj?8_=rO*#mGR;nB9?nl(BVhUiRFaLeo(2eL+VV+P^mT}_+L=Ji3? z`Qf=YLu2za4B_CQN~~DFN_-9S5%#5c8Ds^g_KIg?5dg4M_~7|<Yt8gGmi?WAgIx1M zwT=(h%FhWWe(Qzbu6<|EZx^eOPiHUd?hT1>T-g_)r;FFu#Rq@8M?eyIGrigjM9aOM zx$K*OGlu`*66cRMn@brCauM%bfkl7s_~`FSVXJ)G#u4bFkQT}DGcUEGTEdv<vL(Me z!{cGQmjGk**~uQ%M;#ddv^!J9LNMriC3HW@@jjCn3yb*+z>!4Fi1D5Q7PjtwBFby? zD}_ZAW^KNyurU=B{Mm=K>F$KTx2yRQ!AnNRCx7q}<=`Rs@d*cK$?4#TnHb^ZQzb-@ zF2f86-UV0MoC&)8d?2gu5l?J<-b5#2Ai>RW2n9?iQV!0|=<|AdyF=Z(s836C5JrFP zACp^O<Ods1$(X03AZ6(uFwn<?DtfZbBE=)gxbG<m{RXj}*UkQNvr3Cejz5O8a_vpZ zU*zYFo*tXLLD6dF6lu_uYoaLQa4gB>$Hi6FND%qA!y4iG_JHpk%rRv@lWA&GR4k%F z(*T&5R;xac>*!Gpu}{~l(>GuK4A=qV3G_=;G<Sk+wBB@KajQF(H$p*7nTc@pRt!}d zpWIcTQ)u!`XXWl06d;C^7d%|?{T(K-UzO}Ig@l^#@pCn5X&`A2Be_M@d?vszNDwPT zLB^0u^1&-tC>7gqP_*c;`xZ6H98JBTHw$2YB<;Yp+YN$rK$<>P9euyXrxNRM-uke` z*iGg^gZWgyPERl2)ddx8AXq!J_J@V4f2TTgxQ%(F@f<OI*8Q*cRXPc0<nN=>G2flj zmIu;IDeHA+`ro#3-N$)=Gu5~17&&$Or-Kz?Zah8FY`XdxVZin;^4X%~VFp5=7%f1q zgt7XVL|o7wj-Q?j6PUB9uGVO29_x+V^}99x)%R4BRhI?Cu(*5%+R$M<pKhH4*WO1) z%vAJc2^2JG+n&sin>It7?QDixKQHLmhV~DCW552%O3+YqIREvl>-qzB9!MLl%xbAn z4a5lH&o!+GF;6XO$$4$g7@)%8eJ#Lz;xWcj8kHNqjqKe8B2YFPHKP`T9v1VkR~u~n z_-_pny`IhULha2I#T^`K(D1t)6oM~#8n|Z!HXCb67|4CRFMnzOC@VF`ZCIT9ofuSu zW<&aR^|LF-dG7pBqJ7haSel#=n~a4L78&u8{8UU(*$$WUQk<nVG&)lddpsar*;|^E zqK6<Jhxa#;7(&pa0FIk+wb8wNjbMBA^(FOhe%Bs$B&a#3f9lnjxnb8x5|*~PtOcUt zT^lV3bWgbAbNdEF`DfB9Hbk>>K5~kTuCQqY14;7NmOy2#CR4L=NAaip>-C6WE~pEn z-{{S8!9J+!snOp@tL~#w^6!A5D|$zY69g)ADoty<^DV@L&A4;{R;ZZ)_(?LLy4HR$ z;`=7uoS}cyn7SdYC<R9i)?>G?xb3VAH?`@Q^pSUz-@4QtON**-UNRfrxsdXimM^!s z7u9*gMVf+<0P5^W{S9P1^YvG}7qochiPHYJJe9EvawttDsVdwGd_G|9Qa{K~Je-=X z1L{GP2gGQ*=qmzJyQL~}XtONm2EB)FKy3lXU*+iJaNUbtl^#}G$C|>Y(Ev6Vu@z&0 zjq<`x;ps1$XEr@bM3+(Y1S0#_+X;Qn%(7PsY1~A{)vBDq$Ay|Bo1N0$^W9Jik6ldT zhXIdJ4-xsh(W4{s{3@W@eN!d%9eU6dP%+_bOWfa4-PB2&R$Tii85Ml3F8>&AS)U2R z|9tB>ZjqR)J<yu_UalKG@NS%JlTV92&<Hc?w5=eNbp1sJ%dsBR@m-~Tp|MF6IT-#H zOy|Gyy<I)=9>c^j+ztGW6CGWHscEe2R2sRO5i@JNJ6q9Ha|g&Tc@*5%#!4K&#pXC_ z7bdg}Wo&Kbnl)NUxJGw5Z)|s*+^RoPuQr8_EfbB9t7rHQO+rX=OVGg(wOR}0vo_RD z+-9!&O)~Xj{>5u9EEboKM2AzbQM-F{5vVy`*|`mhMur-w4Pm;ozENk?<WsZ3|01wx zdwvtjXXj|=V*$*hvRu1Z@dPIc&(INPU%+^+_TH>48G&Y46LOmhwB1fkpg24k2&O-p zC`gr^x)5uD8Wv*ztv`jiiJt27+RHYxb>d~9y}9N~fw{gx<B%HI`fZbEnJe#5JV5Be zDj`@VrfEB<<J+k;1d;ByT(B~w1ZLt<t9pB~FM36Zu>jydI~c+E8ghH3Fra3p7)-Dj z%JhPah$Vj+Xyq50FJLEv_DIXx@+FbzqyB8V?u^>Sh4!|cd4H(}Pr5d`6epzxjRP=Q zMjG*ihFr<6g8%;g4Q{;E_iQ2ps{7PP^Q5Htu<j?%)5CDui6-|dK34Zd2<v&zHrH*6 zGhO*ID+&PllzlPAy;Nz2M%tVo;V()Qm?y@y>R?42=|<LEdJT+<s+`i_`V*jD9@lns zH2N|{X?kH~&MA+E1ZHR^^V`O0bKEH!%m=Svi}6p}8W+4u=Z}pH&7Pj6lzXmJ!vcWO zdnZV}=6vK7Bk|#q3Ci>Zb=hP=qm)}CLg%<`ogv_+A6KkF9Gs$jTsOAK0_-T27HCP( zIPmGcC(gSs-b_B86xFI-Q_#$HT;NxHUZ(4aUGqELxA#%b@CAW}*yw=m1`oNjjnN=V zHO=Hy`g{&X=`drTXS8xIm*3J%=}6vpDxj4yrUiQ6d)8*ALC3mV_MyhBbq(fWVor)p z0ux{cB1IAgS5x2j1h#RAN05Q)U0C7zsCaE`>wSPJe5ES%ZAuYF;<c3A6()rzg4HNe zG0~NvC<9%n>oz)}51-?#BLQW{Gm_L(L-3u@$$!>p9?GKW*ksA(NDnRXp`JX2dPvVa zVeUeLT<hg#Jq>K1e@_01>UPRv4ClM54+NkPd^BAusA&S*Y*PPTp&%M?`OTA4{T)pk zbH@2-S%=iPAn<EvqrO}0gF=JSJ~5N^uQF=?b#?NNf=ZehL`aM-996=Q!wQQB9hbiq z5T;6R-hX)=$tXGFapjPhzjbSjyDxYgJ0|qLjqnstl;@}oEuPTzQ#MX#s{t-~K?5Lg zi{Lw*@JI*a-ItV_*+VIfH35r_YU+}ne>`j;x>Us5>0b62Nig5{ec0oNlx?n}e$Q(% z0z`u<Ui%~AR|7>4a>^k?t3mc;%gHNaj^t$#UVG40EZZFo+D5|b&0U|)--%jCI24fQ zb$_`h>!m&-b}}XSM<Bd-_S^YDp&wxCR<k8J&(997re%F*!4Ps~${S1<`K-&2>DPrz z;~0Eop#G|4^3gwrb3W7nS0i;lA7Zg#)#vB&R*%6Ho8q?4s+P=k9Wg)z5@UN&?;nxy zS!HEM_6%kDjxr%a#jwe*W(K+8ykThh7sL2Ee1mw^9S7fWR=u1={Dv+I)e5ks(Cz=K zEgHf;b{bOfyglX(e+7j>MFpCrHROIi;Oo_z82VcjG`+!ZaVQdb5m31uieIlVa0uwq z`$B*1oRG~BH;adr!*73-X1n{V^m?_8t4a5WVB$yo)xkMEzwpJl+f<L+VV0I>`nh6N zaE)!3VcT7FvhE%S*DKZE6$Y>&pzs<1WjVxX&q&zl?^1}C#XC_p$H!ri7k#&LqGI&m zB$z*KZoZe=1_18Z?&^v!SxLgAIb0JpgC#J8fK%4T-W|u~Y-jaMymf!Tx3j4gQJ9H+ zy}$E*EH73Ax9K}i5bCixt4I2B1Lc!8-;oQadb2O73k4ow7V$%?g8-Y&N$P?n0=~b> zVQFHFbOi#<n6ZxRN_zCig7N|wBw^m}4giL^Il1`)w^v<;KBYE!FO$W{XjJfAXY<i; zrQ+JEG=i>j?_1H~AQw8=y+<MSSPy14?o(_%EMCDYT}Bn~o5z&+zl(axj*RhrKzJAA z+7o>u?K;-q>mp7OIRJzV$%l=fM-u3~FwP8sa&c3Fb*HORnpm@9j*p}(ZA6St;fwpQ z5xYW*4<b!?(P!KEe*e#hzc*J;Cs03dfRQb5Kq&1{Cl*W4mhI$VMGdWoZvtt>e7926 z#h?xK-x`w7k~-H8&DCE1xar8uMQMva)cN;-Q>5CpWX(Q5003346#P<QXKL!Hhkp)f z6znh5`yQ4M4UR|Z14dOxhJc&V&PKh98{(?B9*e|-rYa+~EE78BeNl_j+wRS$6Rr_s zJA^;KS{CP-CuWeE0Mee{os!u`@x7&fErBCBHhcLj7lm9Je4?;0Ofx=4RVsCu$wfQJ zwXmL^p(~X`Yk+Om&d<I&xUz7na5B*{Akt2MY@|_xTteJit<`6@mZR^Qcg@?{H_2k+ zL=EmJlf320OM3t_>b02@T&U%A!~W7f@Vk+KuWeg00?%aec4f#!YpmDo*<)qe^=c&$ z9$x|J>wi{%J-<TxW5Gc{n*PPd5dz&Az%hY-Sm20&^_UHw|75_@7-HGqyny3%qe#QR z4?+FxMvPZpKXjzDogkkOv=RFXkZUrZYD8~ph`5#Ts5)El$TEU1Wwc2{nbWN+nRs!h zSa_X2<UMcgMDruQ$%UBbPb$dN=p;+rSc&N-&Y?rce1(}MAIGA*vmt;mPkHN)%yP96 zC9ePwF=Ce?Jryf3@h7G4+00dP3jEE3kBSPm0mo31s@sh*P67GFkq(R62vEu=#&Qnf zG$v;P^@qr|NG-xDEg@CH9iTS?zq94r%u4*pI6(u8aGJR-!WWi8&^&zz%HfLuTRCe? z{HY^aX|7e!GTl^zIh}!n?RNSFVu|szQ|kqoLywW!N&hn#bV9$Ujy$Yw@H4V+Tv&Dx z!UHJ2fE47oNiG*>jpNR;$2mV(R56gC`%`EejW(z7Xx;uT?aS~;dPA>=b%5V;Ig_?& z;=tAQ=JTON;kt2BAoJIKp1+?U=`Y*zm9a@^fz3qpPeYqyczlOT*963S_!TsohYxx{ z+)p{B9PLNvkVs|G6IF2NJH)=;<K|3$=y^)b8%A@Jb<l4{a3nvhvtbC0z#SCA<KGr! zA}y-pbP48U9W=|R{2`*^vwc@Fh8gJ#Em_EpTzW>=;JmbyRIgE+34km-M^a3LXH5fW zf^F}Ub08G(L6Jr!Pss)W1dMym%kLJTCx+$+x~C=up<7v=$5=x~O>(J@y|f=gitXt} zm+PA>);N<pl@RA@e2M+x?72bDA4;ngSex}Mol-aa)^jBy{v6TX_9DYvPHe%OydPld zYSUt~XUF8HF&%ko=yDP2cYyzkXguE~a~ckF;(Rt{%JfzZ5ZpyO=_)G8<@OHP^W;~w zV%{+Pxu};4KgGiAezk{_S3k0cbRNiAX&NOkU-4TazGx`S!L<>X^3f`hy%L)dp(2S% z{5f5*q5UF3bIOSymVh*ExFH;BDd8!JVL!~HN9k8r|C?IyYX>tdxHcsK+7Z=)zGm^c z)^(D+X$8@&2fE52P7fl!>oOLw$!ERcU?jj8Zs~g={**4>?A1}<yGHo??3_AvPtoS6 zo$)3TFTla1;h+}KvDrHCy_?0E5D+<KNGCVF(gs5KgrBer3q4o5Ke}k0{^rO~nA@}0 zb+~VTwU7=aJoo9@yp*icNC^77BY4|--U#J0U)t28ZUgJE^UzBFcLXSnxz@!;Oa`>T zNrVwWv+Wb}e=qEN`<rkP(Lg}<ME;Z6i~;Ny0fzv};ejIqHu3Ee_uFo}0Fc!VwzS7; zMAGwv;eT7acn^X&cqxESLv_V-Xb$I^SePnn@y#pWTbZP^$v-bVV#*}!DE!iS2#}5i z#ra@D`tBaMn7tT;)x&wBnsybK<l53W{S2xiut&J}#<=Qj?CVwt>)lrA(q(aK*ISZX zvwm+~K~Av)238FhZWJ0VXYpUiQ$^IFlUZkwJ_wB!o*jIq4m|OCCIMLNl-L&}*GUW_ zF8>mRGHk15mk?{RVbh}-lzhOo@he5m*J(&VZvXtT8A!{zlu!Y!Yz5Jl@LP*2L*=xa zl3!@>&%9MIJoudq1&UrBZp(osYB$oty8;y%PYA&bz}I&p*RD49QK4~B^6Q<=4lrz@ zt9RCCo^ahT%^X~F<;TC~&ijXH%mzJou?pX~G@g1=p?j~zYIa~muHn^`RDF4}$m4>4 zvZ&j+UdDur$A*8Z4H|1_9Csb~XVE;ApM~t)J5Wr`tl5YAG2>GC(tobE6Dsk_?JK}t zcolsOu<T*F_D;5%>BXA%;fYk#Ap70^OMI~XDPGRYFl5@;uknQzvqi(o#gvZr^4Np% zywV0b$*gdXAnYq8_vPs2h|?LaBz}8ln$A^Oi~UsYB@haOLlgt+iTH&D5<y`2JH^2; zDgn<hluyCUfrE9~kEmfMdcq+EJiLRdBKhP60IUvMJ{9Ui|1o=-8L3}7Lm>{njX^eX zCsTLsliP54kZb+(4NZ5w^JKinyIBb@v%jkn)~m9M6hxQBn=_jdb}oa$ex%L{K`5A% zpY#hn4}w4@G#dts8bst{(>Pq!wY<iPy+zlVhTg81_2OF27n@3E0+~#vD6{6r?|C&a zfPVR|%b%VErxBI#d3&y@;dII!?Rz>@VNOmhQpbRa9gX2UK$XHfUY>99Sox!`3<Z&K zux^k6_o+}#==IQx4#t+g5dhF^DBPtZ)rW{RJQY>&2*+|ruLI|s;<PGiHi+!flPUx4 z73I}xUwu<t5sDihVDB7iB@ha0G;Q4hz*5iyf=7i9*ztf394RiuTSR|Zow^0BfL|pN zrF(Lh+9Oou;WQVaDd7B~K;U3Us0t}JWrmN!1ogAL84mA;-j!6jNIp52wC*DrEPN1X z!j22Gf#psW*CzoMkUX)*#_|q}THBcSl^&xQZmOsYcr}=B2i%w54<=o8H`qx7E{$wX zm}xupVBG4~udy|}4x0o1s!t&ctzh^kegiaPyXYI&YYk<7?LIz6e0P84+H&uZL6pIb zVUDW|fJFzc?#9%oLFkcoE~P{2iuUJ-n&?NIJ!@S&VzntaVzfg4MZ#BRiy51yL&wD! zHYQw(Ct$p5TpDogMFdmlXr`kC%vW;0^Jp~$&xxZvPX97>VudCdTV|<q-xK>aL6qkW zTD*#i2CE__OYujq0QYBxV{ha#PTXx!C@245_p+vf*^QM)aT1|PP`55rvK{aw7m}Aw z8)APQ#1G*QgwnXzLCvLrwu7}s0%`cx)GlA_d<ApZ{7s)FP>5*E#3x|_P`Fm?Qh~Fk zGsiKFQHvF7W@`&u*fAW`?EVT4Q)b?PNCfpy#2o#ACk*;}0UALBj_eH{<6cc$tX>K< zt;aoqbU|_Fx;@$G&m*N3hYTG@8NN0*i~vD3`$r=KLKpfjEeb^b@J@Ao-Ggc}&<ps{ zJp9O8%;EAUdxQaJ$9t0n&<b<_z3Jx+j^;NeVUK*s5^quP8K~0j1@9XaA<Oyv9BDr} zl&lzx59-%1qWr1m-H;s^w@0+ZVrPsp+>#85lhD~PWi(o{19^$qXkIkHh|t4bx%#o| zf&|)yLZEEB?P-ou4ef_uZFJz3*i?%SY#<qZi{&=_5tHMP-yEa}xc0!1<c72%!%(af z6vLDJWfld9!Zzq0>Mnw}W_ISgQ>5;V5u>sJdlP3KMUk$dyz@jZxY;(m>FNeaoM^lW zL3@lOu39HVDKef?HXY#u>#`1fF&W?*EvI8}_OJ$l^j#K9lX@?V67efKLuxT!$D;A- z`uYh`MKzg23005+_^UH1mwGLEvO#k0Jwsd7b+!#D@Bs{itu$F>#n@AY-33po4{2K! z`X*ng5-C-!CfQDF!V(SBZg+g~DU?%28br~M@SnlYbqdj@?4pJv#Yw|O*c6Z=P60C7 z)W9bEOA2>K?)}=++nyHDvsvDO72hL*oMX9@Y)j^bbq|&VH1u*a$$H<O!979hy*^<T zahG84Y)0iEtNM_Dj)~tB{uJBkb?Y%@w$ova4G|pMfEByT!$Bs+(Sb?_Sri(3iL>V6 zOZS%c>#qarit3B7NPZ&O^Q~-e3y0$v)|vMe`Kd{<$+s&RK;Xlm9l>#|tV3S!4Y`(_ ze3ph%5Z9&%aORTaF4ysKV~=AaC(8$PUzI$?v7}ItzCi{v^Nhj33==PI4fDjyn>)~< zT?_|VP(ZiB_oU){T?!0ybD%2Z2H}E`1JoV@$)Ee#Xj3Py8)3zy8~Qj{`0Yk-hLL0D z_qOAbR0K`OoddcRo~#kWOQed$Oz|7EqRhU6ZXJcBNT!EzHsB$2B68W_%pgih<M_u? zZ=<%NVW?%wm#mKBHREBKqt&wCR#F~Q^RK{y9Lwc>+O|F_Q{&kiZM;lw#O^i!as!lr z=w#pw7?@*`#_0Bcs7CQOb1;f=E6m~T&wy%V;1r-pKyNZ|8Ne;HJ-@4k%w1%cu65B3 z5vRMN`p(}EPc))<{^TUz<rQVa-0F*eIc92HDW^|5$bkZXIYRhJS+u7gYoh)-v<TSL zgnj;agQacFJEfob0M+uzfmS<$OKRhFFY9H|6+B?*%!E|XL5V@NW3BBDxq%1GAP`w= zN&3@u42LoaPXj1~8I^uF2Up6TkUr5>Azgu&xIsFu6buynm&@K|+{4Ac470WT9pooX zr}Ft#EX?E0rHUowUS}R$jxHBr#_|vYZuGcPmxOOfQTBTex0H>M1R2|s3Vm+nbJ?Lk zFi%*8{pT^wAuDb}3f};G8d-i>Guk8QhSHewnL{<Lv^Kyx`x>nRqhXy@q2%Z>X)DjT z>31VddKneC#~H$Hcj-GH@92u3+TdAd&DQ$kS<_kH(-6_M=2pr+E22tuyT^HpK-p?% zR^TQ7O<Gw7!zAgVtj{9gQJNF3>pw>|RkWVugb&V7Cjl1&`j7g*kcpz}0&AdVhe*uY zPPtq<0i)iehqbaXA6RW*yy_=f*%euVt(7<|Ki8mfs#)6^y%<Os5E>!c%0UiGm=53y z6O>s9H};yRj@`MAio$d)sPXo@3V0T6_P}lihPt@cK^6Hr*Uw#Ljv2ivtg#wsnL7l6 zUBZA;es2}I#Ht7c;3IQmhIr~u_W^RfXc?O!fT`izT6<DA1cmKkss@md)y9AW32>(( zVGnP%Ri2dVXP-`J`l^ENGJ=={@%7Hpxh+mN@;+w|-{KCu1Ch{~C@xu!DAI1KF~ow@ zFQiE3{wNSbL|o|oxSnj|yoqcb${|m3&+mVJtt<~I7WgB(oaG54-)Zmg(`T^zr-kJo zfGw-`HakR%4!69ed*IKdjfb3tLFH=sJy`#FJ_r##*Rg<K#-s?IZo}nrxyr31dS}0e zpWg>zP{nWB7}fYbxharQA2VBYW+7Ly?;*6W*w>x|3^597z}&7R>z|MAxi3<bgi5$_ zvl)tN;%VM`5Y_GeypSs?xJ%{Dw0CP>0A9LXVGd40)~&A-CvU(XSC^Ul4AH7bX>>xl zp(~<<54r+|<S}())M-Y}i$kRVveFLjGGb*wnZM0R0&-Qwrw(AW(8k570l@$h{HIb4 za!KATr?WcDb7i9D`nckZP;tlV4!)Vl%@H*IWI|C^G>+v2Q}x}9Dj(-6frGYPK#Skm zO6<*an9Y1Y`Vj<|+#C`}kqbIhz9{XRij)rN<Q!zeN;&<L%W?o7Z3evG=k6N+hR>z7 zkf$xl1s&J7z2eG)bo}17to<2B0K$L-!9T+9?H)V>=84!8Z#L;JY~Bd<FB{n>KSMMA zrsbG^na~wK&hw#yMtcKDhqba;KzOL8<lNZV7m3xJD3Ppnlk`xY3UPO(EK2m%zGCi~ zBDTX?gA3&ygd#9FW(<OSGzJpDb|!H0<Ao&`=(3eq6n~URtAJi%E-$uws-IY())OcQ zSUSnQ?ETdXpD7IXK&WNJ<;BOc)qq?9|KS|w-DJZq>7*znUvp_A3EIUExS&ePt>L4G zPIM(fKL`7ed=wINjs1-jUP&Z%GJ77P*Yx!Gu;V&t3itYgCCQ8(Ai|wSdx9{KLIS4b z2^I11Nco7V{jKjYrf(esFAtBEF}O>J6PoqLm%#lh#(i%WY%(zF=S(nJ8adPQuu7yC ze5W=w6J{*EG3OHL;f%fw7$%133>vHEnYZaQC<dqwh9!33N;q0CdX=9b{YlbHVu*jk zIDw@Pn3XMVRg6PIym20ql(qFo*`Wt#yBPN_+J-_76D->rx3$QdwyAOZ;^S(h7hq+_ zh6Ql6qi3#MW(bPJMc=8y<9LL;eeJv#{=qRWg0LlTfEcN<-Ab1RC~@Uq)F@n<`TN?m zO!YDR*&NJv1dSKioNkoz=Jeqm^Pq)DPys=A-9H+F+WE&Th}*cdNkW8Ei^em>ff7w3 z=nXU{O*247N*JR#p_O?HDyc;1iC27rpKX5#LLKshBbqeY7{}LA6N)Bc3G_~<JWAd5 z*q8DeM9ay!wfEQqWLU=d*OGgGw8BZMdrV*~H16w>xOOA*)&9NiT6f;+juxl4Dz4tW z1dFAxWZs3HMZ3|)`rOD59l(kx;}^LMJqOl-<y%(>d9R0-@Z;qAWJ!!x<LlUmX5Yb| ztqbDJ4WuQiL4t_nbsf8o7@CSEVwcxG-Z5@PT-EO~k*-4n;J@7;RX%oGBXpp_DHhOK zdxG}HuPhK_+IZRW%9Iz=GakzbkX1im@J=b5PYxP(O`;||9wVi)%OLk?G@5}&Xl;95 z%KXQNAoDCT57nfVUN#T)ecl3CU`V8gB#tlmduAM9V6?hC$8jEl9>cbfv96yRhn=w0 z_Fu*-f-}^BxChf<eC(CYL~y(SwQPB@nLJ5>T`Fc?_KqF*eu@k(_*li(w@TZSyV<F= zcXh+K_5Sbc%g?`%X^{sLYC%Rl?TNX%_xA`wi}lNwYL2$do9PRem;%qO5>f#7zmGHa z8VNDm?Oa%jh44(ljvgpz0fPO<>qfF}_*kmWW@4EDWt&{56DHhN-#NL{DXN&)atL=s ziEUUb4LvP1X4KVn1Xnq1zxk+7$>r$gggWCV+e5&;$r$7q;;8!X49<;SrZ*!#NAJCp zg9Dr4ap$sxAVogbF`y@9bBcSOi#598g=xEcp%wo*^2}Nz5G`LZvZv$Lo#-PLx%r** zL|PAU{C*d-`3u67_>17jmiUt~040R@;}bb8fkkb}`&(u9q|^aG>5gaXK<;?LM%q@& z7kI*_M7@k&Z+5LZJgluBQ<juECVwGUowttq@<E+sk!4ntei+lQ?NM|0wFl=>z%I%? zNrDfmP`<rjoGmIy3&X4jyQQ5Yc^*7}(3=eKdNS1PQ<WOHVWa2unSP*YWKK0tdgpxm zLmj<aMj-Fw&EbtX*stbwzG#x~nIF1d59Cvp*P7{^X79a(t$(S1M++GE&CZ7ZWBUE@ z1!(b&YgM@VKu?YQy0l8y7Jc#hI)^FfVmBN}V4hO=2lzP&n*S#X{)bbC`A|}%GeI&S zPq{hPeM0B4iN;3WoNhumrQlnO_YEQus&aH8QG<^T0p+WL8Q~*(AjF`anttf^0~MnQ zz3e>~DPNv>@mG#?4pmY|<d}69PS4BG{;v^0rYaw8CHz(Q*JCTjcPHk}1lk=}a6?uQ z)fdj1>Zzwp`~~FHgoWZq!BY)>CxgFgjjI`C%5&VE8sGLNIT_45hxB53ihGs|lN5E( zeRQX1jgt8}gonzcViNH1GJ>2M;_9Dvew@ek3;n<6IgVY?KlL#{K;|TXE)3wzfK{`G zLX!2<wlVoM!36U1wMX&Rg%$&ya8g$qvIr0iaOoqLkL_onBUl6r-u25!34-K|=YW}j zX=lD%#jSC`g9LrO#UgDZlPqmkw}ylVXQtR?Nr&TE8@fe+N4UjXt0SL1<z*M!wys_o zSLuhb;aeL+>{Kd$?fTmq5~+JEApfoj7<1m~0G^VWWlpxk`@TM*@^q0XHT!k`vY6;b z=d0`RI@R3Ga6hGbw~jp0wC^N5Dck0w)&AkTF_7)>RHWRwdR|6<M#ubmS>x0&VLxbR z6GQbo2Ch>q)?Ek7QfKO1LxE7ErtqU7Ro`xnSgUHt!*o|=eXuAj@%=am@P_^aW^p8< zyH2Y~z4E6|*M_;R4mXxhxw>bJL}Omsh2!~?pt}Z~C3lZv%u%Y`)!BlVgiWyZz1W1k zK|3zU-$#|XN^!bsi=MlRjAw(~S_%wF;COD3!iBn4)6@<j$R<cc5c)DHGDDQE-=4;& zq-OxUvW9_P{adO2fYz-7;H~T7w%wP7rmEVN-gtLhU$sAD>baw{4r`hBA?*9nyMd{( zrXHVU!9oRVQ*#4rQ*z-@wv7aT)0N!OygI7oQ8&lFOF`kU$~Vk+7Nnwn=szR8?gTOk z{?zj;CJDBYo*X$-fMR%xOgbpMMJ5l%u^L)_&7-%qFRQ4Jq^7S5KwVXoedzvpc<Gqs zSihpKCn$X-jHfQ#Q!;F3w$XD&HE8=-m#uM(cIWF*<>?59uZ2y5VL)Am|I@GOwDSo2 zqc~8Ml1)$kc;&#G%jfCsaH?3#D%o&i8{kvjn|E2-_i78b*G6qf=4rC}Z^6ITDV8y; zu!Ysp5U}VV%DXuSFiq-5?tOc?b6QnW+9nYG{2EbtI{6DurQV**l6p#2^?^5zI1J_@ zRRl5-h51&Ne8~n4sXmF6RB~jhp^sSrku1ffDlkse&m)r<1#Mz?$be~;4VG$dkp5U( zBuQPbl=uw?^SfGOt8Q2p>@njzAu%Cg*rpvVkx1x+Du5#r&`2cg{}9iki&+8sXJWoO z-}#ZX`(tc^*!Xk1=kx4R>LY=~-|Nf$yN~!vc!H@nuji9P+&}m0_2A$!ySbRSX_?w; ztllV>NxD4uA9T%zuicl+g3-$*xLZ8u1Ovy7M0VX@n_Sr4A@8!T-nNcFgJiOho+Srw z@l}974;AGA(9)t69Fm+S@ff%Pt?8np?$brMNK)&y$XTmD<*8L`Xx=t~d1GF4Ur}S{ z2iZxrzF=v0OXr8OB)es42OERVZ$vV6uDc)(?0BSuyZ~nwiWyCXDtrA~U;d<_V{~Lu zW+VkK5oC6tkFAvnrUOc=>ibARO<&mwU7@brtu3?<pq~lk;S(H!6kRV-w4{B?Nmi{> zF)zwBCgKp1ma(Cy2(R6ROrz9^7)-VxK}xZJT|qCI*W8+!e20)O8xPWmWtv(k=$D#s z6>N7Rn!$!itfp1BTyZ63I`4GXAZb&zs91y!$N@p<vd&?u*>y>vf~VJOu!*v+Ka=ew z>VISdsCjHNl`g|`dd#^~J@pkYOMnzIJC)d7=&ekLqGkCwnXp5%wzx8zkPj_KLapuM zK=E=!_`u@(D3jlAt_Q7jByZ+Vb_kOGMHmks(s~4|h0)4r*Rq{M>JKK{LKl|0FnC~* z1F4u^W<AiT4X!&wwdFLtj#eKVwTl?XdMQB$Wd55oS+r!1k<Q+$O5lZq?}oL-Gnl}3 zI9DHj+r;9wuA&2yO*OQT`!R!m6UA4a_g=s?*bVnWkb`{5h}|5Ez+n4--3*3GO}vBj zXJpAI36ELgyV-^@xAyejFg*TpjMa=Thbs%t<w0B=)ZSik5L@>Yy(eYPehgI#`>@Xi zRNW_6<=)dgJcrzZDN=Bv`!tj`mcweMtY9_i$G38glj>^7RjM9sLo)F6JvBhg$|OYi z#BNcpc@)E{_LWOeJ+{EKqL=P+#2Nc0c);g?GkUcxgU3PVGWNn|@33YmEI1vQ=@8UI zt{?^RUiyKz37AmngHCdzG5+n2anKe5^q+L>Q`=0BYQLN)`B1`!@)W1HsVtB?pvQOp z5<ZZBXZM)eoZw37NOTkAe~%_z*$A~hGMDs%ls5JZa?p^)qlPV+%r<sx@UgzYR;UsG z%D@*RK2zeKn_dpx>NftP<-tAo_l3o-GhH%BZ?%Qfxl9(MWJVjFf}r==0&=GX0LqO9 z)bZ>PI(W;s>qieMe(ABm=E9B}N}#l7Gsek-k7xP}A&9Ogm&CaRJ(;Y6Mz`1@G9{g% zM5L)498pa)kEk=<@{CNh40S1>7E5yB*CMjf(%0DGw=kw|sOxHO{Fnpb+PS1+N80F! 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�YfaFxLVNBly>?8fJuWvLSu- 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�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�~@zHZitD7TRR2 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�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 delta 1005963 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%0A&@FOQ13yVcR4&r8K&~W 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∈)^OKnFpYKD{L)~8+#)43B7Ka2?AQ6<_ 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Μ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%0AvQ1%Hk@}6PDrCu!(Bn1HSp^Y`%Nu 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 $K0HD4%$i|_zyN*$ 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 cwE=j<z3v4@m+UMCflvXih6Y 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%0AcrtsFI{Sjti1`+nw>5~M>U5fLTC94kLDR#N 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ℑ;$-KY&E}JdvLzDf0c;^z3=}3@ah*z1+3GeC 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¤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�{~)2VH<@RAd(PB?BtGW6q?x3;jL#+mWBhcSp{P^PF&q9u$k` zGCj6n-Ha0Sf(qKs{lKglN1{^^2E&^_a(>{5T^DLurRcsKk^SEqJm2!tL5VkSDgI35 z2+a9ifp=%osm~cJDl%~S#x#}w1Rk*kfNl=(Ch2}}ba#v}R1fscOc=q5En^tqw4dlt z{<PWRe1E7B*}cOgh^VLx8#o(WJ*&^KF#QQ5VE<+A0*X6SZ{&wdvH#&jD&!AQC4^jR zg#sd_OZZoA&!Jf-^id1<h!se&0Y+HbTxd2@Er+Gr7&|!Sa2-QLWDTUum1dX*V4K6S zrrD=w@(;Fj`t|L1;hjqr_rVFI+%O=Y_P0%PsGToJ@?@=MGTcLfl+FoLRC{20M;_sF z9;yzuB~zno=_-8^n~F+*X@tC7k|!Y(nis{MbBgF>fcCz3&PsD4wxRxC#u=TVc31Z_ zX(Efn3)eDahjp`9y-{36ddxds0Ee+Uxj1EvN?o98NA3cx^E0KqCgPAYEE>FXTl^(y z?6Rr)V`%(-KA8M~AjmP;ya)G0C86JCdmsTFrHdU`{o-k0mXTl=CNq+izM?np28vL1 zWP{3b|00m8I$8up7WnOV3?+X=-c)%0L3$CoSHoX_RQxQXr6>|zb<1;jfH@Q-`2b6W zA))DLT#zL3z6h}1u+)0<I5ze+<D~EUdZJz3njucFJL|q=78t}^f(y1RXDpw~L{;P# ziNu&tURiSy#(kmT&kjq<wq9J3BUE%3F=LC5=iy_LZzF(*&COnS&-d=~m(cfapAf*o zV~1xS8P-pFs6}rmJhD^)03k$f=uRD6!K>l8vAT2lGI4Fs#a;K<cS?NEbnrkFDuhH= zDZk0UfqRyO0QUEf_yp5DIbZZ2q9(#aWYsN3tX?106sVK87xR5iNGF5%cHCcya3+Sp z*80{K2>zp_^7&{OC`b_F1TM^&>V);^2M}X?$e{abkT=zwRt8eFfX@U=2qO^DX~RFo zk`f@Iq?xeDlU8*<jr#E8CRLizuqD6ZrJk0?xt*sQTL)V^2esE=X`#O~&(lI31r!Q{ zim^m|W+zc2#EA;(EcmzGQ)E<NHcl2Gf0tPgE6!{sX(K^h?lud`Jcy8?AWR{gI5S1h z#6E)i1;P4*0{v8N0H2*~Lo=+Bq^IIpMrSCumm><15MJCNun>&G4~uoI7uqp~NIIt# zo`2^c23^w#JamhlHkR{5<M;~Io9Rd)wW8&U=JlM)8bsTrn{C8OBG>3Yq7OW4M~I!J zE)op{ZxoZ%o#TJ2o>305nrh*@H;U|={3-;u&H_cf3%CN|2jtthIO3r48cc;rxKpXB zXxxMul;U7#N-rDn&1PO2qlnGSi}hd6(^VC)==RZ-RG}@B)exdA_D^6}Mt*gz=FQH7 zc+~1g$czKD<`{^cLO=?4mSD2*IM2b|(^MGpytvC#nFQ(<$0V7Q8H(IOTYLYaokV!w zU73h=fjpn}17?Zo+-Ri;^YpvXgIT(>NuBn&rN_o#tuKizY)(yW@R}h8m+RuRMdoef zKdhNKFq7}4)ZV)aXzexsl|OK5b@)=1f4_*<Ov@_h9W32DXs2_)muje;H4%OH7(3)f zR$g>@Np{bwXfN(~lv7;o8K^z>mF?K+^*9}PUu0$H0$QdWbOkte?uqh&8mQ-8!%xc# zww8-lE-VdtauVvcr3b{<zm~Uyba*xvpY%sdURZ6Pd!7srzTDaD9-!OQbdQ=RKeiz} z@syoDqm<Evb*pTv1)~h;Fm4zy0Gjmt-N*sg&mJEh9PSmxhPG|5iA{@F?6+TG<Q=aC z$m${f0Mf5%W_v82#eYo_aPO&H-#;D|7F^%fZLcRP&eNC%mR^}GD$DG{gTuee7hQS) zFWd4ljeAjFBBI;oQ+bna;iiR$a;{eb%~{qw^g?LQyLij6<CHsV9XsFC+t+==(|&M9 zI-?m%Y?>@>JuikB)1z!ee_tEn^M?#-=u0pFfTf>P-aiF>o)d3zW5NKPX#hyji~pq0 z?T>M<(CdEK#2W$5uA3wQ@*IHSM4-j=wxz{>g`AUY^dyAvhFY7z%=@bwSU;=??9Ev$ zzGP6{A|Xy{jezzfS5L}VB|!fK+a>a1haQ8Ve-|`-3t^X_(@)gVF<k-sXG{T-R|~+z z5Q802#<Q5ry%jx_rRbnvHrd}D*4~TwB+?!h(zXt#@1^Rlunst(n#{llmj^lm^FBQ- zo!a`2K2)puBMiNIte0g95bi24Y+_FWAwc&0r@gKI-I-W*35-(wyPR=OSXV`fbV0>< zff00{yqk5AIdi<wRCK9YYe7!m&N$#v!=vQ9!)g)1+dknGXE=Ufu1b;9Zpq;O$XlI> zM2<QmoLWT_GKG$wRb5P>L|af9qv!4AlQPY5r&OfoM&WjT)uVk$fK)Kitp_HLMD(r$ z2%DWY4FU<5o9&$s7xS>o7DNG4C<Aa)MP3OAG9;Abl{gYu>J8u;Q!wNIbpwdB6K_mS za6#b@|3fqs%HO@U{_)IyeSWZ?Co;@hGmdKL3vO&5z*XMtgQgr-%h3X2`YO0&iwA(t zRg;7(FgEUwdF}<fm~Cd%NI9-=gQjcL*sm2<PqBDY8pzS?xRBdBq}ID<U-9~l87AVM z<cQDLXBvsa02*%f?^z)yq!Vy5TeNUpw_;I_TG*Jw;-7aCu~0*}G3{9{d1@xKd#~c? zek6s*c>*8i`1|@S7jhREy)!cqQK6Qqm5iYM(0X`G&C6AR%jJyb(&_j90UDeFD-7K~ zMcJ&_ulC^;M&5bqRw7mT8oP%FK~;nD18xt>&w7iyoL97ch?`W+I(q=EX05LO%K9`p zg2-Ue$%0Wi!$@o^Y?17}!{%s%nJQHgGsR#JkMr&G;S}skwebf<ACj$yq2su{v?Osw z<X<Aurf~|^Zuc0QH(P967XU5AZs;iPj(>Id?SylaM)@@F|F884mMbDS{X=_8Mf%bE z1WH{(z(E0+nAzI8{7@;jG<6(s#8CZq44nQR8MQd+jwB&hkrr?WDTx)cD-%So$zRs< zxjJlR+aV8%<aah9gD91&s)kR97{seVBWv85SZ3dX2?V&9KQr6#lv5K4awc3&W=(ip zTaW~DN|TaqVv{QY4bWarP~NK`zV|CI*Ur2j{L=?q4-?~}rIx1OG}7gA>~=~P7fWU6 z=YDjz&_OusMsoQ+|MR-JZ)3@<)o-XGaZHGNg&&0kA^$Lud~1ph^M#*7JWLZoEJl7; zLKG!>9HBMx9Yc}S<lHYmidd9E3ZAivT%HRhzaQ*BiTyNxiK$w$Zb>;i7>wW6g4x*+ zdH(|Zi#p$bweIkE<l3;KMols6($&7eb?9>KZ-V#@d43bHeDpAz@LR&2FgXHd0*6p| ztscmr*{-L*IPhmWqVJ3SaGu2sSC|uSfw6cItu7n&2&v>`oa|%8pn+2lEP*C>%sa}L z)7cGuXlMC==PjthXdxi{NTr;6gDBVR`ndp5fvoW@o}9DN@tRWI%KqITb8e!fG;(d% zf5s@6UeCnxdWjae>!fyQdbvKu=o?8{HAnqC-3MIa$`u?2$;2P+Vws9+%?6uh&cx@& zB$;~%WgB~`u(A_}LX46yxk!YIXVpNE!MEdsh%}ILVC+E0Jw3*0Z`|)nRtW$2gc}0L z8NO<4Ul~M2Ve=isU~F#tr8|&wdFu5Mu6qb13*AARMZzxB;0XLnls!C!P(Ud=PbJm! zwJ{r@UGQ7}<ZUeB?(ENY@uM)8F8QMgTKv@ufB&RK$Lywq-AI#CDZ=U{mK?vf>^*=K z!*Q1w>ve4UV12=(EakmGeEtsmcBKZ$RCvlNxH!&*5ZIYO*okRz_HLwbPwcO97G}&| zo+4<@frn&!{kp;Z<2z>Ry0^+?Nn>pLUgpg*=4qxytwoIEkB1)y0>_J5lI)s%sec6e zw<8>SxyHEaaB^U27CP^7-%oBB!m3)Pj7LaDvqDPJE1N`N6uocau6E!)vS1PLs|1+5 zpG`$a?^L~iO^xJrX7>PhMw%a3+1|W~2|_ihJP~JR{IENTf@9bx__=Iy*hf3At_?m! zw8L>Xlo5Hwi*q9))2t%DD@p@<ODhI<7OrvI#Rclzo-V9o^uaowHXueoqEE>c)77~0 z5VL42miR0gk!=LK<liRcsE<70OduoXVL%90F7ipMEcDvzo@)S}t>Vyy&07t`tp2`1 zl8xQX6HGoLo~$DclD02~2B!GdDANQpA*&!Od`?rCs~>&I5_b;$+|o^^XjGCjxfa&~ zyG_DJlgV)H(HwHrsRZH4if)tK=vq1v40dk%)-6@Tn_j62<5*07QHUCFHC9^2B{~Y6 zg%gG8hB^xz_83iUFDixrmx(d0dwOb@?kB>J8`-^^U$p~HtxQxiwxQ&#hDMat{STY3 z9g~D~DRYN2Qf;i*eC_~9^{w!{Tj)ImRjKT&h*!DVKgV-XSd%?i<%jAfKi`ZDe65X% z5q8)imN|<DqTzGJy+j8XCa2$*<FvncgO4lBplDL_>LY$g3Ym!ShTobWTY{eDRBUJ? zr_~=zYTf>4tkEhLCkLysJ||DZC!yoova!$!`|+1vj<~qW?wmv~pKS?l>xNnZYeUxB zb+W+0N>V1nrZCdMw=7{>w{(H-=xGyssgF^v;yqL+*vKg(6Vd_@P7@-IN$cY8X4mnC z9%~i0dkQqi;T!`J4!2nVd=Nsrn<HUn>!aT*dg|pKhHa2lr_{@>$;kOIm#+OgT8lb6 z$hrUPp|PW9wMIw0WY%gCrR4IfHdppWK1bHi^WQ<&S<B9)LiaYn(d7Nk)ca$r%jZU+ zr=v-r?O`M4#jgkO4L&bR@SFehe(&I>$NRo7*xrFZgTMV@WTvIGg@66y>}&f<Apw8p zg#w|JLqL>1X~$oUWEH#NUL=A>l}q@W!%^J|&USa2X+)Xe>l@PkxAvg<N9@(KV7-TB zVo1#s#{Y%u>0y4Hn15K$Wa9tx3HbRGtRUbZrPAVJLj!DFHpCNm-e}AdI-t{LX}iTL z`c+MJE?Vj9RT`d^HJahU6GV`aAQ^!yBQ73#+Tva+pHpoG%pq8S%0{?+UW~LZXy+Cd z7HZF~&w$bFJgn5i^>EQESvQ)A{iaQAl8bffB@b995ZY#MpWGCS`pBofbjd%e@qMyU zPi{v+D^r_rvC#n&->*l!o_7atQ2?LMV>O9Rs1|3hww<8{lI`nAO1b`463E&8vn@l6 z;Red0e8AWHQe0}^!%Au&gM~o0fqst1V8=uw2g3}#eoDN7L66tl^NI&{o@GM3P=c6X z&+MZ<;ccQ3G{c_`Sp<X8-vk(V31U%l{-DsM@oVfL?m+-!k``r?9^UVVH3PqPSo#?T zKfll8%hKKZk%!zFoodUYNI&X94dc|13p-EhMAXG^C38C9+>bH?>QgchyvvS)!8RK0 z>J(-FG@K}pzV?vKcRQwBn41+!t&*0uUu998lP>B5JmN|a_PO)eIVW9mMUomIX-FdO zXnl*K-8+E224|`o1YwtK4<q>~a+?Jp5?>I^2Vhgd_=%{VtRBygg$)>gSSV#?0b^>J zHe_Hc0my&4!<EgR&t0QY(OiQH<WasU;mH<I^Pj=3TVS1+E@JZ&1M<s9qLk1TqO|j{ zU{T09#FpMv84YZXYaidJXkInY-p|Kd7yjtb+gX6m-?4`R_0cO%t*v+RVzmP^goM0L zOAFk8m;+7%y!l5t<sE<-FHg^WpyEiLTH#ihsf7Kb(M+8n6M9AYw(Sc*D6&r9wEk|R z1{@oo2d1Z|!z}VX`Ot6PF5hTGpu~L!z|ebLA#5QHx%{AOY&V}y<=G+#z$l=QdV<J) zylH@^rpXD$4yNAn;!z^&b_?Kl$kUC5XraH1GE^Qyegl=!j-oCtvZ*%d;Gwrg@C1ba z2AkQGW_gb~V1?Zj;VotSJ3hM=3bW90pEET3$ijl&6Dj8%Eg2%x3iSsPS$8FCVObUn z22E3SL&X^e{*aq1PVfD-3SLcTqm5M&r$_;ypm2y};uM18VyUT#fDJe2wJuxE*P+8% zJ`)0qf7ltu9o$YDgG<HvpaVfg<H_Akr*kulY<FSJiO<?zJ!6@21;^+iLi6Nk=3xGg zRvrz5T$Yw<WYk(XTq{F;VB{4lN)HG|3s0=o^)|Leh>*fQNw+*1n+HAQv#W|=?=uFV zn2V9WTn7J1pzFGW#O0og?CU3T)b%i~Qj)~F;N#*d7m6UNo)pU<qk&`_FLbh0H-Wau zvb>LSq>}r|Mqbr9GF8<<DbD8Z%+#CX$RCrG7G(|FyZLa$2?S-jiafXL$$qxZLa+=F zasvia2vehE;;NzBpy0saWGA{P5C9;OQDCOzdmek%JGFO5NL_M(%^N$R&TjLu<lx@4 zfTgi|;ZvKlS9{?z^DhK*70#xdB}2)Ef(KQRdSU+2@&*Nkt|UaOOhP{lfC!5T%I7(~ zl_Mz(wc^fy9BzhK;C#2_iH#t+=Fg8%Nv$}__WfgX6~2D+f)g<Zi;_z{Yyoio1I=}h z@rO{xz_fKD&1kh~+}Q=O8%j61c#Wz_ok$p&f&3pOTjNYQ&^m{fN*kquQy|=k5dQ3{ zqO62bK}4E=gVdS=RvYr&f^B_7TIpV$Rk*mgoV?I7CKt9r>76pU)_5Z|6iajqRpuC2 zA?;Kjs+PA*1=|=hpIblg8WEri#5s+KEweM`_pP)_W>==1Ckj%5IgoVmZA(%Vt-Bge zrK~v^_6Bb&Az21W!$;v*f)e(k`JS&lO39R0Fsd!Hfo+AT`_njji?8=(61RE`x4UoI zW=ZE_YXTfG7tXr9Lm(G}MRSY%{{v<~nZNk#Y6I7csqX9bDqcw|n^ac%+)1y=e;cVb z?YYGO8`@QeVZx-i5@LsHhG=`0k^jWiy76nqHx(&Y>?WOUqr5l-;MB~M$)m*v24V#q zSj&^}Cclw;GSawtc~arP71j15tExUsDPK&dmh)CXRre%gPTf329L{=2+=g9aU`(3G z!&0g_qnh6`wiXS-6aywz@8S6;e^oGJ&s?Wshv+*F5h&6FlLpJk$na6c2?^)~aHd3X zldma&F#)#<fZ8mK5#D!_LmAZhNL6x)u1vNx6_4fK=3vM?FwB%*VX`bk=Ad5*L?w%T zHwbA34oto)AydmE8DgR?I37Vv*0Td9kC?1soS)(5Y{JgZz_H_8409PZf4<Ixnp@f% z4ASgUQN$oq2}6;bM={G~j)=G$`n?{(%JL~}fJv$p21C1|szT)9gdjr;rwW1fn1zwO zTonXZV*=R;rUnA68G-EcehnlK17`HZ!m5D)i&?d!LJb63V8uA+sVWGth}BWg#;Sq< zi&!1mim!p>VMN<uWGlV~e*&xtfo#>+Ku{JFt0P<YH4tD?bHPdOH4tD;31sWO27*F? zS+#Xv0|6GZYU{oR0`Fp0ZQa*EfW=)GTlX~(U=gchTlX~(WC~(+Z0o)T0xUA^*w%dw z1XyI+v90?WNFHY7m}6V_CFrx;BmE`Ja(SL*Y385bEhP2ltzPLyf2uy|BHhPJk)(yV zmSTsKmfR(6U7QEH-I>YmBHiwySo%aE1C0M{efY|M-+ML-pRKMwO+L5(<-b})@`F#{ zt55yT@N@eE!n5@?LO(1&<ejT;5!M0<EC$g2_w$SAZ{MAFT5VYNhq763iQ|{I4VDzD zWvxV6%2kv^C}`Q|5yh_RDRy9O$q}eq;yl&In~s-RBpM}uwaiY<P09NxDXu`ZZy@{E zt-{zH5v@cB+(Y&Xvn7vp1dQXXk{`bRuxQ)YBGpCCG=AADN818MQslg1A}(G%xA>>2 zs<(~Cv3lDcURii$dmGSSM)@v0<fMaeQS6O<fb<1S7uYQ;l$+^!d=~<#Fg6z^@9?35 zP`@nE<EpQJj=(N>joe;qXEhYO@0gFW-~OlUv+(&5El02}b&LG==eBZC{qeoO{m*}U z9p=j?QghNn+r{(5_twmIO?%br0luUvRd|Rb>`2376THxFSHeAZ8Q_m+DhD!_w=k9c zHL7}4xP<(}E=zYZD-MQtb^m0Twk~QM<G%vGDrk#;6;STF*G((<ie*h@XW$21!w7~~ zT;=76x~MsIRIH3`-xlc$oT@|ES7YFIzFDT-J|=6F2h4Fm5k)Rbv9HrKcI17rk&7E- zzl<dyAlNh7hJ}Q1qDasU8=x>@M|Q<1F{U(y;W$c!ZwqKHq&kk==2q%Hap3<#;OWV7 zghI`KY%rP4_EEEy&cB9|zR32H2$dTXr*{Nhlv?r2b1q9g9l|>3LUNs@`($}aGQhwk z5G8V@U#iGgb4&<q^7no85l$J263GO^igT8M<t$t0uJ`e^uJ7;&QCTtHF6A(HsyxL+ zZp<wETx#WZ#Y_H@;{b(rH*guDg^xlzYoYjm#C&Mum6_ttVVpC<b-1|UVRu2KV99$y zcCCo)s8yU*bhk+1NC~MoS*ygM(@EF1K+E3k>S{bEahudTKXx5&5jo;}W=ptqF)KjY zuwx!FfP2k}k~Qa6uNUYs86RKTY|`UPb7X#K<=Tr9@2$yKkK#o~#4lxq?9mP3gc$ID zizZKJMO~DCDJPW|Lyqy0OL{}&DG8;Sm-{tRZnwbHH`W$JJ``rT^B7Y_YASEHve=|c z6DG0D2~gMmB8F;ASB;RlxZEN++<NOp1_yd5wbY9aihZh=qT=gZOrKpx82j=_jolmE z)O5_1ZQSYV`C1mYQYNDJ3=SK>&LZA_=aAqZ6*q{CyjA=~3D&a<>BfeNhCz6@c*9C) zzVbMGd}5|*6&f0Q?$>t!T1Lt7o#;>4G!2`!QpoX?xhkcq72R?3ser*2G{w1R$58KK zYno(P7UOKx&@SL1m+fVKf4WlGzRf`U-YA~QWk*n}68r{g7g)oI>Q68_uaRDV|0Wm3 zgC-{{D}K5gdDmf+HiUMgSdIRmRp1QD76IW-#VSt2Ldj^JP)_ym6#MY2avLC3J5OO1 zhZPmIB>mpA?_u|}@3j`bwB$1jr=Z?tNepQb9o~d)jljk-6JOEe<ED~z&CKVHt!oqi zL6+}28^?B3D%wFQ?G6S(pX5}3-;wcl`#!_#x))YBYEUW+E3rx78BOM(0Nf2|K(`Kl zoEl!ba~|XSo?6GNdA>?p$E5wiyt(Ob!@E5CtDN_HgHhY4f_fOd0T#?&USvm=Lfs=! zOJie2<E2@&ruQ5fYtGna*n#R(H5~E5u72Ao1{LO981WmAd#EK<*xsv19J6?!g8p1o z->K`aF+L+syT(XRFGh~C<G{_jof`PQ%;YTkl>CGrm7{DLE>cY=a4ubJKqb1p*CoJF zWiWbUp`L}2=F{pnmpv&OHh+EZba2%HBd8c-;DggqBYbo^VR%LBj-qP*`-F^!AF8dD zW*W=2xy97fUA(M)zQ;!KX-)iNX0$tzV!O|&L;T%bZ~-VjY2$iFh5aLT$CvGk2X=%x zE0o^m>c`6D^Ae|<@8YQNy^dE?bu1IVoYWS7nv3CMRbE5G&&rc`JAcTaPzmS~!!9oB zd(EqnsoF=^c3kj~V4CD(_Rm8Jx#oSi@#DBui*}-wT`Ezfq-)bJQ&_DCYjEEGh1$Mg z4?mclu{)+t*h`uF+!Z_0?4qPiHzDsKnRZ0C+r4V+!D7-AGGBx{^ctXhUk5helX63U z8B7>FtuO0)!<pA~9DnvkGp|#PYYoI3`voS{S*P@-L;M511mvkh%`hP44|^Rk>b0Fn zGi7G|>7XNKgGM*-LGwOR65pEj>f+KO8ln9d!JB(F{|u7<VVyH@zUdL?n?hObjq%<C zWUxrKn^FSz<Mq{>=JlNd{4q_&S|o04I6gtRffA16Gk(+Y8Gpa4`24t#v`lZ4brvqA zibi}jacW;a96dg~)N{=dLS1YWDc)!D_uHu0h?Rt6f%*Ykx7s8wJ9rSX-`8S~=IN?2 z2;pP{{|eYnKB8rS18#`fXLoaycTX^pzV|B4U%88+_K1CRQ$hU4dr3D*vn>?Wf0avT zTCnMe7&L^p_kZT+fPR&jyT!i}uR-Dv)EDAmk8ZM(CD^Cm`&Z<7k1c!R6kk1n#1gx# zqP`%C^t%0e2FDr53%aZyi*FzkcYEy`8jxVjx#-o2;HPr3>rZM}6k;@$K|{scKxQ!P zH_*xDV<$tf!xig=i**a>n>*c3Q{d|~9p<da)Ua^90)K)k`CBoZfPPui*iQOJpsE30 zg1KE}1{g@*#juADGk=6c&aO0}wz4JRf3#uU4AQ*an$xF_Bv0C+_<71U#ZOr<AC2Rc z^m2c6xtE~_vZ2e5Q^0?7|K-yCE?51zu4*5cdiQCrqNzRPDfigCu~z)2HMthtIyN_l zu!n7<6n|?>V;4;SC$3hx?)x%Nt4edk(d^=()iRA!JoN_~dFR8wpwd6J1vamyaRW7v z?gY#b_#>GR&hQyu2&8nSqZ7D3g(*v82f?gDzxSR%VW*F<6N?s4({0w~9v2?V4Yg`> zs~o6wx5@#xy~Y34M`5a!SV`Bw^^&ewN}l?s4u4Ooqc^BQvoz0x6%>o=>IHw3-5s}% z>-IS=Ch$Fq@@9<H8p6KV$ns#D^`Y8<f7gB8zTqsN!TDwl|E>ob&Oh-^<ZbY<J~Pbr zel`%#V1YJd%u)oa6GhDt!dxTf`hLu7!n{Vz>t;+x_lD6H{ds~QKz9!U>Y)e0HjI)W z@PC^BP63h8e^MdI)AEJ87yM`;6ybF_e2EYCVB@=Zn&w=S)4hJCHD@w@zDaL`Rhohy z&*>EvC{+<8muoqvE=M`38!qYMe7{Y6b=v5_>0w!H;K<SuC>8$1bMDDFj&^yJd&eff z(eKFp2HPoG9p)bWTAU6|hgi<_Z|0BA2Y)S>$o%8BW4J%cyAqXt#&ir5ytu^FKd)@J z%AJHod`^F;!S_FQ#7&zTIX4~g5&gb)w-G@`$$iy`Tj^7cz8&DVUn8}Dt(z<GBYMl& z!$Ep)wi2B2Hf&#}9HzPejiFV+0enw*;JIiM7G~waA>tGNVT0rMEcF~!swhiu{bX{T zj#zo0?75#oZ?y92Yfr87wbg*E7w~#>*VB?s_6j!+zvUaP;d~|EZ^HZ;0<P}iv$@-? z7{}wclX4muR}qpgzWFOe)TZ9G+GJgNlh!9T+O59>P)h>@6aWAK2mtDSWmUHgFB;7O z1nPceRkz+S8p#I_>V9Qa{PoyGmr?)#jdlT-5d<3+m&`aC4S#YQN3t;ZpHI=J9lHW# z2)fvwaqt*Ehn8ep^GTvsqQ_@eqi8mP2H7L98`Iqo$zkZk_YnJp`y^X=sj93?H$d9* z%$_hJBm&)4S+}gL%&feW=j*!ZlCo;o#k|`q`Dd-a)vf-vUgh1gZqD`Z_R75K&YB`$ zl+~$z@Q+n_vVXU1>hmN&nJ4`4;Je2Y^}FqweBPZG-C4b$GK;*+=c~MJi&mF4k0!~o zELOH)(Us?gD22c2?Q&DiySiQ(AQw%(Zt2}=(XACU{f2+iyR+_mrC${7JYO?Bo)i75 zY_UW9t}7a+t+HK}bFO%vcW3(fyeL=nRCfHluIjF?%6~b(x?0<zf8XTi#gTe4NnX^8 z&5FMtsaY#d^7(uCX{xC?*Y!qwiTXS{oZ#Q1zr1>yJ^u0O<Nx*S<q!1ept_<jkMq?k zKUo#@>q$B9=-V?jDEs_*+4A!j`5GFcA1_t!7Dt=4E_S%?%DT!|+-z~#nJ(BuI0XFm zQ>9AN*ME5q4UG5p$|WGv^h43K>Sb0|%R2dXmW;lbBwvsBv20|#&tVNzyUD9Y&E>pS z-<nMYvz*P(iurpO$zHK)3jtwWuBX|DqFU6=l%Qp*!$k${w(dmI6i^f9foaM-37Vu= z<0SbkSvUFVdA^@ibuzEj==NyYrUu!Xrfw95cYkNadBKP^&5HB-Z)MgLYQN15!njXO z(Mx!l!LG~=o<2T&`R4HX)9lBi7tgcr4`07HIGUJ;Z~puPKhrQ)^{E0|EsDk<Ac8wm zqcVt+Jg-k*V<E1VugcTPY;5>3p+7IgzMiU?stwr3@Z-%@+ZE@NL;<Z9S#x?~N>*J{ zuYYV={K+qI?E2MH`0?kwDf6o1_h;qlnQHs2vtxL<S*?Dwk0;6NV%>-bT=P6{-fz~r z5>G?k^0$m$>#{}OZW^;9FX-oaQFW7q-|<Akl<DPM=cl$;ui(cdp-I3Wx>Qqi-IXbZ zzb1;NzzXNp0#R9)Bn&itF6U<%>?D5Q6o01*m-XA%_={h)^LkylW6kiHdEXR;srm+g z=~u-m4Ai`%pZaBYwK8zuz>f+2v6PC+ESy3bNz`hbmx_R7xD9lXCr`gW`04pkcJ%c1 zi)Swno@YltK7H|20agh7^uJymzCO}Vj=262R5vg$O=p25P4IuwAEzy>IiWvq)PK42 z9!ZizK?Mz&W*4O*AQy&S{7gR;&bIZc_`b+Hg$k{xuqr<kmTG+{#H+SbrCU2M@M~}H zPd~l-iyC;QC*kqo^PgV4e3Q(QhY!CB-adc!@+rQ1@L=!fXD^=|{tUnLaXoDj+eYJL zHcL|OYr3~5HUrFys-buL+qX!h-+!uudXl6tap}8v=G)$%Hf>ifuV|yIYD^^Gri)^k zZ&qEZimr+!{+%l<DH{0JKvVE#sdlD<a;WIxa#df1V3zf2fpwdD4S$Q(s$92a3*Qxi zshdJo-`m5(IC)t=KFh09rtx^D@9n)jRO@!|@`tAitS&H8=S<gJQMv5R(SMU?FSGBT zJ%9T0P!)pHC(GJSu`pRSU6zVC)v7{qIWN|V;@}@OBk{@)T)2ln9Yp}wn{GGAPW6W_ z=%=q=M?kAnWH-=G^+$Vq@J#)C{q*1kAk4@a*u?A2!~-#Qs%NU;tDlZEl%Z;>UD(rr z(}%C2-RtzxSAW2hBHfpV#DDbZvmbsu%D#K1j<57#w8WdEgO^VZUO)M0@PRks6Lome zp+2(w3bPVvn!YLjQ6%*e4&FqQpQ(DjhXpRmMR&HZ*uPGfSCoOC>PmBJMwLnK%oT#R zcd$AXKPv#!gX;7+Qh!xeMN5tE{ik7j-Qf_A)tdhE??mnIB+KXspnsBCmJnxchtsOT z?uQfO&jkZ8<5(4^`TR=Ly8Yxtal5*X|8BX;Pq8!fBH<SXmYU!!oYfa)Ri1Co?abQK z)7H!{V>R>3tu@u*sh8I6{86(}6VHpEH%b&xWs}?>!X&BHtLCC?i{$%U@s9>%QO#?R za`qEN8a245{1BH`;(wCvegq+YG{^vaPp&YaNk-}@Xu1}-4-ICl!TgO#?!IBR-#SG2 z9n!g~(BS!H@*!WTp#taGl#2ovC^AtsQ(^(#CC)y0{dPzARh@w#CcwjL08pG=4fRRc zLNyfHkj)2haE{xZrBAE~DA_-Avc<ZlC}ty;2l%@!;GS04FMnngFU}N;M4+IP3Yz-U z2D{%tRI6?PVu}A$9Nbz7k5~9hotbLI=Vh7I)#_^07OUkrx%Vw1?7k5)6!ga+UjW() z7Bgwj>dk7AY!s#<kOY93zMyzgC}yNmYoO$H1$(MdcuLrIQFdpebki-<@t*0AVhKf0 zQkMp$POn}Q_<tPhXyR5=$?2XcNyS=Q6+Rwq6F{)1vKjNe)`i{5z`QsQ)X7*C7g;uP zACG-Ns@y_}zlv(ks8#)Yijy$*=aH+~x!SBj2Vo^f0Ahv1yY?#+G2*OBkQp>*g6N?+ z7F$8k%o|j)<Z|~)hPqId9vZV1jHM$U9FLl81!M?@2Y&}Q=hoVSO5CcxrU|!eyok08 zL}0M)_MP?<A{vq0cB1i-_RKW0MKnTtc&rEr(1NlpD@6gSc`-tCv7H;cn^f-;gN+KV zd8Uy~JyYLD4<>}=L#-J&H)_#*AA+oVvmLVA@2!w|e{6-z<rGx@HULv^maRZ_L6~>` zIslfp&VN>@TuuSyZv!yRhT00%lvHrd_rWEDt+vB@;mJGWtvS@yVz8g80<+<Y;e)Dh zD!WB|JmK;)t{5M-E(74)M(_#fAoT{JSG%4ogqnC3PlQ;qGqnIb#3PwEhD$Z<`Fzlv zdWSRZj}bJspS&zC^n<ogEb573knNsK@@irC(SLZ$ssG>pu@AttIHYNpUeG}%pohZ! zGK#fjJ!tuOK?GyJ^NMsv6rA9^?Y<(6RANaOC2uj`k3YqH%iR)e4R8DOO><Ky1e3G; z%UI9^_**@53Ubob$?-94%H!j0?CEcYs1Etq6%iL!!QoSf+aspk&bLF++Y^oHPN@Db zvwvi_qb<RL?{d)ic(C`M;UyR8ie8uVv&VVcjr1jz)ps2z04INgyUgw^?^O4$l9M92 z1J?$3U{B;`mOT00pdD+OvY4cUI7S?=#<bT43}|h2&(wD%FTdN5-i>Lv)9G|*ltBaA zhudz}pj~er&6~bQi4M~!)4bv8+WTfpsed6EnbhBAg0rXYzAjqOkMA=6&yoYY6?PVk z7N=MwCs%qNrh9fKSdC9B5zN!XAPB7jv;m6A20MkisC=~ookrfPQ{0o|P)+FzW4<tO zyE4(&MDJ8vS+!ZMGI>!q^Y7?DL$4P(U&9^BQ@9@;8BMmcz<75G`cqg`E|1zYxPSRM z&nviGW34LR6ciWFOU>>941w#g2TqGh{ZN#!QbYrkvZHqF;YL}Nox%x?3JOD!#)6_A zm)T_}nSgAt0RH{tcxKi^&%Eu;6<AT|6&a;}t<vPK=%Sr_y7!|~!A#a`z8O^$(;}{* z);dwBnJ1^^heB<*<x-J(e>XWZhJSVT(XQYv{%7!Gl3eo9b!AVj$ZTfR?2JIU?=IEj zOZO3oVpqS?q`Px&r(Es`+uKWhfY=_Lt6iQcJe%pu?I}MoB|u3@(@1j#*j-ecb41IL zn1Bfn&l7KGi5cqXa>BsIkwSR+2(bJuXIA{NyOm&v%z2k}4%JvUYQcbPsDBcIz|!&h zrYMqqARhb2{|%Er)o(TVVwlG`_%kKuDkz(_;FI2EF*NDcN<GCJ9Eh6~I@V=J>rJ=b zbW=T~fvxN>d@lm(=4QH*_nziO=zoFKI{IH~AMZuE1I(jQr_-Jmrzgd!;yQR}p=J^a zI}Kdo0DBaZ#pOJM<3)57NPqU*@A9@V^j7Ulr@{xgNipT!q8{iI30N8~y%Q`$Y<?Sk zw77!@V-Y)aGtARMNC|4D9me*DqVrG{(UYJ!DzkFww$6gPySthkE`*$uDbO6~MNBLp zP&4Eo@)B>>6JTmq{xOxnTD8;E0T*3h-9xi$(PV+QsyNyF253{^9e)=X8syCt*&I!` zZ%|c_3^QnpZdwI!kjlrXC<55mb{1uIRy1Wtw{mK!;X<ze{2bhGWX3V02HaQNih9Z4 zhPR)bNq-OOIazPoGn$N%ZT)}fPBde#*F0p)BB15c4p;}Q>m4wFYVXj?s@nnM&|+#k zw)M<s1pUlAge>L*$A6)zvn__UO07Xpyrr~n)v5VD`tr7C23d&Bq*d5x3^a*N$D|e! zAGy`3w?HxRi~ABgOZ?LNc6bBGMeRL=xZcTTxkQHje;VqmS=YUap8}{*^5$e!&)<hy zWSS#pcQvOQ9Be$5Z};B?02ak+_rh$Trw}uc0aTk*FQ~){bbo<H;V>j{KvMcTg?sOH zMwLeT{Wz#ytYjOsb#B%K)){Dl=}I`UeBIBe8V6wa-?UZC=ZJxgd$Awz*&x3wG3`hX zi;Ax9^D4<#YN@Kc1M5Jtz1)F1Qo);&$LOhiRxXNczG>RJA$m3;8nSP#H`TPJ=^%C6 zLfk|fcqwFld4EKVOiyP#mm}=Q4F3-n18;T~#(c!njQRt=E9@oq6JJBY<27W$4BRmS ziHzM<obu`o=|+XJVdVFs=H|z?C!TUbTZ5~)YXIBr+exq^)J)@n0T=?>C7iEm@`S82 zTL1^|U6m_O#E8vzMUP%n(`f$N^4puX;4#~BNy7celYc2DV3vfe_76?HS&!uE;+eTp z$m2ZwHhD-#r+E7IflEN03v0G!?z<qAU8JIX^7gP#ARUiHrHP^di&-k|ZDOafLsP=z z*z5tPF}OQXL?xq^M#xu(LXNHs8hC$?M#gG@D+0--M!56-N1p!96b;RWJJsHVNMOCQ zJ2=C%c7OVWL1Z^4%TfLw4v^#&p1RhLt+=s)B4QIsjW|6fg*ZZq>RTk(kzp%b;`I)c zFcrE(Q7g-^&DIivr4q<SbkqnE^Syd%F0=pyjSMt7bRf4#bC%_5C1mM#trpd#IxuV7 z)jjT!kh%j(!QpH-*;IOasG`#M!zs5!DOCL*t$!}i6j?=YezzG9idHT8KtTS$-bD~y zJO0F2U8lqhHNT@^+`VcF^c4~-fT~yRCiAP^s|Y8YG#nl*q<08oA0ys6BkqA|mUXPr zp<1Uh53uOYD7Y7#gja>*Pktj1S5FHius=#gb5OH}$7^&a7&npWbUN{VA)$KrPB6iX zVt-yYc~>+0%Y><qVzhXpQ)}WDB}@Mt8e+y_7ltmy_Pr_SBb4v#qQvIRHTJEm4{DdI zX`nVV)!upb5T=z3kaVCo?1%tbTt?hu_HuMLhnYr4(d6#k_ZQ|Tc3Yf67VjkmB-jMS z0vN}3O31z;-JPj_!h(nk8@I<j@z5*?V}EQ`w%Ok{>nprTG$z!&SFO^d`l7f4I@?WE zp?fLVI{b+s0TWm#K<|yd*f`|C=Tvb4r7C!)P);>O><sxRy{+=|;-2bQSrrRfd-lu$ zhZNKw@B8Dl_V60$Og1qZ@6bqlR;*yVa-C_GAq$aZU=poLXBjoHOw!Z3K7}ioT7My9 z3d2?s_b8}0hHb-8l{EN&zxcnN0k@jZL2i8m&(mNa=whMz>dzv8`g<n@MN|-2=-QWW zdlNWU(1xyJ*6-OX907xul-jR)2!0-P%|7}M;I_~wDSPvmH%Cv=CF+_`1#XrWd9 zJ|cb+yqJ0&n5aajrX}XaboBbCr+?Tqmt*%CuN1rXP4+(S?PX3+vzG@i&;#(AeEk%v ztCc44EC-D{J%%NA>P;0HId4bfj{~kpN9fxByq>E`8yP?U=?Wg$3wbJ);8V6y#^$x5 z8LL7pMM9Nw)`GL;zI42VcYT^O3<NM@FT-r9(4%gyX26$>MLosqEs9HhF@OKS@X$n# ze^gjFI{5Cf?fR>x{-9X&HaSzTGzF!5BjkJ($2Bk7)^`0ry$}YPigH1RtMCqShw;SW z1!fxJnCL0so)qdRQL-GWCGG7z^WCI5fQmvjadf7*Jw8_Ed1cMJ$nJpvICNR9<9WRR z%VuE?hH4MMGN`hn=0k}QJ%3}utK4dHeo{1jB7}h%HT~+FtK>lIPEdgn8K0}AP+N<4 zpJBz8?9eM1^)&ACn_6alkFO_tq0t%D2dMwtI$hN#YLE58)zrPWKwPz<PufASarft; zQPQgQ_hq(aj`nuy8_o8j=oF@8u5Y4X1@wl0g5|WU;?JI|A~&Y}sDA<DVYY_5IsMT2 z9;ku^2CFC4+=pT%tQFMxwglcYZs?$>e#S(5gl^b^(>+2X3ka;hCD^`=?82_<O=Ddd zojp>Nc-|c!+XL<RcmluS=sG@zjjn#!Q|kD5nmjM^58zz}Z}Lr7LpfkE)mNHuA>7x^ zyf99e$;kJe5n~{qx_|o%_W3h)<{SoMu7I~z(Z~(nqZX~3<$%hOI>QX%P5PpF7USdB z+YK(cy%(kBW^U3GSxph(BIpRC{7?tldfAby$56v>iVjPn^JT&(Y@+y2R9|ZAKc^Y; zj5Y1hMf`|w_yy>L%KT#0DitNVJ|UbVi)`c=bmL^7V8?-e?tc-v?<d8|@k=EQoY6H4 zu(IHC4}|de7+m8Obf$X{)2CFd#PE2aPBMCS=#GURvnK6AHC8w_rR<J*(Ufp6P`eFK zk8BHn-;{+BWDjj4->C;hj$8<AY(-y`#HZL}Hf9>?w6(tu2!`XmZugJb-DcWd6vt|| z0b!UOwBS0p?|<HeHtn`64M;LFH!&`v5(X&<>-FjiznG~B?j;b?(B`P>j0oxWO}U^` zctyO>t+ry9pJd>RA5Py(!}y>+q6K4}g}nC3p)%aF06Fj}&ev0MiYu9T5!odIsptZd zi+X<RdL}*oO`&Q-9Rd?!eLu;;hah^EIz`-v?T6E2@_!z1pMwx^Jcz^W?6u1f_M2k4 zf2>bqs(9R|%)tW?;|PVI*~6P&!_l)9NcMpO5QV3+xxgc6TyCNd-xTk20DDp_kPcyt z^{4CYGvMBN-j#D(7{s%I{zJSc3`Mrf6sy9g8b_dxVla3?)th5J7}{;ktsx%TF3kbu zkWHe!o_`W>8n5A9#;2oVjYKdTh-pR9trW&<Eu6dEpTUWtVbG~Tom-eSB%gnzGV1FR zCq{jrGdxn(QR{TY0wvror*Hp{|9Y3Ck);M^#S6{j^pBy)3S#UI@7s?xF7In8nmLJw zsG4=4G9)`+7THOC8ENo!0kfsZJiOM<H8??wx_`Q3LT)Km!{f&t9h-^!H?lE`)UxTv z?g~D3*5S0!jvst=j&O3g9MjdO20WkaBc#8=$wJ}7*d>bcs4;M=`oisZq|dkOFDT~} z!LAmHDc0xc2Erv`yC#~Tr?<|E>O<Mo)xM74N4tPclIwQL?{~MZyDJUttdJr^V^1pQ zn14<vIZT8mZ9@98iByVBtmez!&qGhSdXJ#d6TZVQ&Z5AMr3LT3wT9ub`%DJe{MBAZ z!|#~gA+WK1K!EiWFrFQvX?X|*`N}>Z>?P;~CI}!5#W3-#B!^6AoPZ9v!dqujvq)Nd z_qB+#i2O?5xOC74aaSeG0pOq=dZ$lw(SJV~WiT>BHpWC0sy;skUc;HVr8b{nI+_IT z-7q#IZV)(5(n$Xtd{4b|1=UqvT*Q%}bAFVkZQFoPfu2!GIxb+v33>=!lheMc%T=9s zk$RQ}ntA~-bZZH(n$Oe;Ku*P$Sc1d>hvuf09D3PtyrLHPF9QG+ak}2HNs%cwGk-O# z%99M*&HWaXac;X*Gp@eFF&cJW$*y@|gJ20HG)9dB;KS8mZ*R`6&#dnL6udK19juT; z7^a~Gr)tQDB&G_52=Be>^P)U0yU{r86nwNBE|^|<RbwWq{$;)orY9PsKU;3phyLl( zK5PS%g%KTxr;4ETO%w%{+cHhY<$qYt6V|-REEy=#u#_GS8yR?JXuVs2CD<9$d-rA5 z7YT%?5+$w~(e&869q7DM&Vw-=-h?ciBSG^5^Tko0rdlhTy?q(jm3eGFW1Oq&g^ll) zGw;O(`|u_o+}QCAT`rTpO}xYAl^a)Y*yLVpYUK!qHr~Kyi*2$}d$#(W-+#KHoXy0W z$i)q-ik(@O(L*sk0d7blMn5k?fcLtG9~U>s@4OnGzJBKM)qd#`ZC&Ay`-T*mGh#fw zA(LWu#;mP_cg`ipfB~9Q&I^)()&p(<EiLQ-iXQT2l<!7Ere0A{&b9hm`SP8=PT(zq z9&7q4{q=M8WaOK<i?G}?8-IP<B_wDt3QW;Vvy7AQJusRx&2hT#1(P}Rn9hly7EZ?; z)-sGCEcF-=oYZ&w_wYk24rYdXbPG7b|IF0|c#?NmQB=|uY}|bhPkRlyjgHu-;^qZ< zxajYKY#<3vA<!Ej2N~E%D%3Z_itx*upWyV+h0MnFkB!CV{KUKs=zm*yCDnU=1Vv*< zh&K3y<C=YAcExdepP|)=h~em%oVW;Utwv_nXk<k3^QX*saBSD}!sUWJXHCB^&HzH& zlea$cWcMO88sXyB!X#Q_<?0erhy<R#^GO<&RjX*N%R^U}3@qXthXKd=neVWd={Ndj z3eS_-H3G-)ACqga_J0bA+4$qPX`ihz(0<z_YapUN*YciBNlE5LOge(_fg(;9xQT(V z)_iPe359>+D)Q@kBb>AtklN>Yr^W<7G2r<8EK@_cEQ<w#N6YS2=(d0-8jTpff@!}d zRL-C$U?G!{8ivOncMO8tR5GU#)8Gu<IZ-v#zFD^}Y|^?rjDPUK)1ULUV`D6;9E%AX z*@IJd6ddjeSy<WrC<5^*dO^)_U!11>B?|jBAtSWmU?TmEs#U@Iy%Qk_k(~!ik)nIT znGhmS2w>M)5p4=e5My6VkD^?l(>XSVaqLOZ%tswkaCy~6110q747m4E+eQgQo>unm zv5B8x(Iy<4sed4{z0PoGB{>9NQrlLqXL#JMQ}mZvJ9&+To^QjmE5_N^(A22hqhfyC zgw-iJ#2*tT!s7MHjfbxx0|4mz(=oaEj>gkfec`y2^B@E`#XybR>w-sLo|Ii0k;ZmH zMELagbH^@X*D^A*&CagYXW-(89fb9Um(ymQH(d!kaetKF^8`*$j*zJlup0zv616*y z;)?_*$b{p!Z|FmCbUm$5d&ph{R9qYH(tSQZ6Ba4q!RC<C&moP4=!kHk?(YW~jl|k# znMk{Rqc<tpCv5A;J?M!09)rsXhi=_V@a_Y4%>=Fj&W#wh{v-c6^3poGAQ&d$9U?yV z1CtHe%YS0Fm=RPP@4G;gO^bn+z=GGre=~JoLx36&7G;>40u*vNfctG(KRLszP^Xi8 z^SHW7i0hC0@rp<YVE_c<V76ibqd(d%#ntgUI!X^K)dAq%5yYZw*Q@+WN5W&tB?lw5 zdExCT(eeyyi_rF~B5&-{#uxK36v89hUDBOL?|*c_jr@cmWQ6RXL&>VI`@%#$-m!zl zf*DKR1yD_!s}nCV7(o_Fk3=K7MS3$F7;}dKOOa@ruh;752!4o-1<_>u(Z|R7s$P>h zNZx8I0qi9uf;)@xPB-nM>da`18@BefbGmkTQN<!GVQr6QMQGBkBB&6SSeI$^&|-(^ zjeq{#X)kB%vK10|1#gEwx^XUacia$U{cHCfl;cQSK(MqFs!bRlODi%P*$d51plK7p z4GdGH(?Rcv<4vmRv5XrQmzD9*TlBWb&lha;v&{_wK-=ibBK(}cofr|laA$tZ5_^V8 zhrN|^y2)rTvDNbs%xT!8OE$EXAF}K2&VNz6VCyPaOsCk^*Z9<Q^;#Qt;r^ZQ1u7kD z1;;S5n|$3AAIf^u`sTntV6e`WIw9J1k-tYP?W=mDEpVlo;?}Tc82huM7`SpzPuQT? zG>V4BI!J0K+-Mex{g|usa*+B;3u&|^W*t>Pb>X9fmxTsZ&-jg6WV~wTDI2ng3xBtZ z5G7?$v(AanHsik@`L;+BU;WnwM4;r+(L&Oqn+0#X8p(pUxLdj@<B;k8m{q(n(uRTa zxcfh0oV-N|y9dp$XdE>$1dENr33f1M%kQ1}Iu8MkoaN^bea)@Wz}TSoqQfxdawa5s zyC~YZ5_&MOMh^iaPft-zE`pi*aeto<WsAlls#<j2UUs6$F2K+N4NY;aQ0aMtnT0Ts zLA+b5IA5zhmLgu7Z$mhCf_noC3`Ky@DV?@Q!YpK}GU2yC8q;EWIt4GEO}D)Fb-F!3 zKAv?4iJnjkT`$Z4+KjZamg6*_##RG>rJ+us@3H=F#P6PY5W1vY@@P3}_<vedQF9bq zn+k5*6p)L#Oekj*?h@QW(YZN>9%Y|>2gn9vvA`^11?vh$E>K=By6CJL^z^QDw;^b( zl7sY0I;3SHwR>5qrOC2$OiP_*DVZ#oms9&n<`;8XPRqrrSd}NX^Pc+VGoEU8(+0}> zYymTRrp|FCz~$vR615X_i+|{pIJg0Z5sZn|`3xoVswFf2Ha2E)m4btW0bcc4m7%5E zJ8`)n@s+Bk6P#bmXgLuA{Dxstsh)c~MbG5LGX)FyGw}Cbv;dkVxK6A=hg^0WI+I4Z z-sTI~;dufYT9BSL6;5MunV&-%Ow$<o|APGO!4|D1&+Z>4u+#Y5Q-2)Lss`1DV+cUi zoPnMc^BjWCUZ@38C+VGz0xO7H%d7LcDYh(8belWs;eox*%55lq%PsA0V+kj+GoxE` zKoe>;i~<{RaG(i9)ghBSQhmZ3q>a`4s=lbwsPGuv3^T~S>13OHJBw~8ncy7J*5^j1 z<Cr!PBJV<S$$(9HF@K{wzVaUhC&ut>7}N_}#C_-L@MjUdzFXd;?U+5B1ihgb_J-8+ zo#nHM3g};M88P!Se<`FrMbApW_=07y`C6kVdMgsy&O?phK-xtC7+mimNp8|XmRy~Z zREuOb)66#B$XJp&mQ#-L(zXLB=-fzxj#`3EoEFAmzjnG$3V$2^`oSc5^p$`&U^{Qh zY)}8mJ=^)dDmYC{S0>ixtZvERMQ2h+RC1M~e4dOB)G1b~Ba_JcM3DMPa`*<njImd* zn)*bYgI5&6+|a$CFPL-Nv=T6|OA5MFWLl!2tQ|6WbU41~pm!d)*IdMy^(J!>?T0hy z{=w_dNmJzS?SJ~;(5~|KHkC1ZN>ktlrjfTZiySnG{45C;j>C~)Pzkm99^mB;@GhW4 zShvMyQQr&D(6N{VapCI+dqD@ZZ*rq{bk8Xzc79|Eqm(B?`7A>xUQA-MV(P|{1<E(! z$$@93X98gk53*7rCmPIpPAOo44sEkm!8OpDjtIXLs(&<eQ_0A0O6LEv3B~%Z7Tis( zp?cb&8{5W)N32b!*lW1b`Ofk?9;*OLc-oIZ0j~YE+i?IaHV=}E!!@Rn(pbn7-&^&8 z^pMeYW_SL96^*BG8`34Z%hEIPen!8(nRkN-+;r+~cmg6!x14qdhZu3ai66`Z8J+qd zgWa|akAIa&d)GhvQN*Xan$>FPdJQg9^W+W`yQ2ijjoPClph+^8jHCnOP(RDTS|A+{ z<}<=3$1;()fAiub8RDKqvz6TCs&`|_hDN9sTGgi{80D;R625{W5QvuG$}UJyWXeA! z!Ps4mZ@>MPP9AxGpkp3A_F|pu3N{)#m+-hSD1U?3l)4ipsSUU!&;99v&vZJ)zive7 z^zBIv$)41NDQ^AUk80}c<mb9sE#BULmxhf}EuH)Z4*Bu6Os#sclE>cq-~c#CjiWeo z&y5(;>T9-{hEBNQ??o;qE*>x|hJ${SE$KYsX*^=-I}j}5XPDSz2uZa~LS9{UXLO+f zwtvzTjSUeq#V)2(q)wF10|J+nb5y1XsXyTuj(XRzf*DTE3y4_SU9HPG-FMLj1=ELB z0e9mVA%@cSy)Q5%ieh~0)$qYheHp!?doCx$4ZRZKd32Z)Q0DAoj4OSqMwt^t-jd^; z!pz446TE@kU;I{09YG$769ON~ZqfscUVje4`UC{PR>-n*B}HeMu5q5f2PJFUW%FD( zw&{vDrW~{-dgK$ASh!7Z-}%lqNCMm+JVs^Rk=UoRHQ^eqF{O5Bc{|SVe{pb7`o&_W zG>fVaKcjiM$lExG`;?M#APA2J<lUk@?9qRy4FR!w3GBBs5M5IGaSrLXPYQhKoqwIQ zFr1TeL@5~M$q6P%#x}@vB;RJWv_m!ufEn312dlPD^!07RX*<-=??CxG$+~XQjB(e? zX1G9r&buTa#yZe=#}ktq5$XY=>RLU1SUqs0DPNa&8$S@I{e^FXyddVih<DMh%c_F& zMsXY9a=)m%HVs~992S8K5&S8?bbpE$#bTel)&a4n4`ir=rK0I)*&4uM)DKbc(ex{k zzaV{s4Y>A6PxQIO!y`2ubzu-IxVV>}WX!jG@JePefgvjNI0DLG&L=OEGq)OsNrE8A z6!3})<W+gjw-{|vBpm+u9@A1THTHt&;1Wa|%yx((W?T2bdW+^apcXC};eUF#K=B1d zrKQ+F{?L4K^1y{0E_<w*mm)|imRASn8iEpG4X+7>EZc;qH@pK5_**PdG={@LJJFp^ z0tyq#7{jL@0pIgBo`{vJaQlt7Rc$#}gTjZ~%-zaj^=JGy`ZD9(Lh_eiP_5()|Mw%I z`71OFAH_T;wTS5tT97G``+tMTK0FD@esITyybk0}Ef<n%5ASoR6JeW_nEIh?%ad|d zc2`DrW_Yoc7Ap3*c0Ed@ow2I#<ESA!4B4MR&kfE?!oo(97~*P&nR}`;aRq6(&<aq@ z;LExLgO(+ln3+&zr4F1W49|+Hr3|?_YV=r0Qfz&(ly{vluR;*u1b?7m@-J<zCX;>z zn@~W_^&NOi{e$wVcZ0~l<LQkRMyY7f+m_>!a<&^YaW;F|O^uGC_7gS$Y;pk+HbKDb z9Dc@;D7|!G1E}db%6bk!+tF5F8qJx9x3(t^>Kb@~Qzt<QWM2X^aQ*F}{0??5s)k1G zi`)dXyZP$G;p}Ln;(yqjIKyyvG_6S1m7Q_C#P7&d^$<brVh81X>n5}O1Xzsv=e&Vy zPE;N??4|(8VX9V(@UOw<M8QiHkuN&XbEK>x22k9dLUy%%4OC;+h_=}i1gI}lsR9xV zRL3gOUM+76QOOI)qMk3oh8$x!#}oxbC+q+qwrzWMe9RdXuz!<n*g>K`i2l?-k%K8s zeSVG}Jy-ftUqtLuo1-&ku4UV*y==k-9?AWrp(sQ>U-OW15F@ZNV$g;b={8=}5R086 zDnj>(Pt~i{g5YzZCPnd$iyF7>qQ>rs@xK8v#?(M|g}s4b^_S(THrJ$0)#{mm1%S&Y zr-#!aut+vo^?$;cAjYQXZtiGYD6<4a`MAg%jQBcVZ5F1IvCry^$t2Bzl6RHN2-jUW zooW)+tIcT%>4=JMKD7h~`h?SLhTvj34~e4v&+%;1IjPm&RR;ykEMX|l26|{4=)%v4 zO`J~(v>Q~FLUJ52b;Vf$rk{fYqb<1Hoc){f76%1Jrhmm1c41SCic$qS5*|cIx$vx~ zlQh>9i)Kl6JfQ3FS=0qxik@!rCRZmjR}Xd}dRoo94XW{&%7@t-)y&Un80@ZTnDENz z=I<N6LK}e@Wc@YyG@`)x|Ls{cI;T9%ZIF3XM~k~jLeAbCiIhMobkCuHxz)ljGIv7O z?~c#=MSpZBBBg1M3dLu}w<$8Ev>J~lOeIjPjPP2dXdT`{|Lvx!HClbLt1LWb*s#LD zoq}`CM9y3b*D1`m4j%SSo1<XyXW~1rJ!uBf?pNl><dkjw301<}u6IR(G~oy@ZPG%d z5*geagyQE;O2w(3X!X=pjB{_N0@|?+8;^FZWPfBO;#gG_cn40aMxDNmIW25j6nmlU z1m&h6{oR?&aeB*Kv>34e%E`ad1oqtU(V=`teKQ+D<5u4yT$~j;37^cb5YR#{Zt@YZ zso{-LUoL8Lpm7Nk!tik<CoYE0vdT=t!>csHMLi`tj)6%eXn_YB0Rh+IdgFz9+K%cs z$A9x6OStF5gKnXULt><5k8n5f+%eZZHeM`}H*@j~F}CXf-{l-hnMtu>5*FbNhh*Lr zAJo<JT3jdoMR6;@Q*EkM`M#he098Rd0k8%00Fpn}1PVd^ge$J2h)_|PjkPLIn!FkI z+S;;J^!)JAtRefo2NVym+s>}kwaqE@AAgM}AKrWJBFEEiw0&235=U>or9%Ai)4-aH z?s9ZAogjM3U1ok{y3ez|-6UBWUE1c;Ouk7T`gZa!Ys#u%lVO<)TV{_zV8foSYltaO zV)kt~lu$K8j_DEhN9<*Esnmnl+w-+>vGh=BmQb?KyzNFY>L5HXM5b?Wy>OF+rhhhO zWZB{gB*Dcn+4M4z32Uc8_EDladWOTqgBu7*d=Gjky_e9rK@$U~>nIAiGJ@KSuKpL- znY#(Wse&CN0h*X{GlK@^(S+lJ&IE=y@j~I_bF}{Kc>UWtMPeEPCoUP{KnWO@kWj3H zV4%zNr^=>&N1VO3UHP}><G&|qP=6_fTN=ei@s5O@qgf81s($}9Z7wY{k$MwkHH*GI zF3gh+PYAz8-V6qwEI>0Ojx4vB8y?lQ*P@yhZJ%oA${&*cmg!lV>G_HgA%j1t%wS_H zaWQWXv5cI(;h+?A69mNwc1Naj*XRyKF7zo|uT$RD;709^<2inVW)1p!?0*LZ0`9vv z9biUGnO&KZ_-$)U4h(Co^F>d%aWEpqA;dz)+c0WQEVU>Tq*)Uk6i25JBntt_?`V&I zn_$pJX;vrha<d}Nce!a$JwyzD#}1kLXcT(OOS{fumnveqQ4&N>+|;YQg1mB=dX7Yk zMU!8ENODp)c-S>)+?RW7J%0tI`$bX$??X|ptm5XD0v&dg7)%TW!`tk@y~MMV7<Ae} zz?PY%WRA!!2~ZdnBkF)xIUC8t4N=o+t3)Q9WL)b32R!zH8*Glcf`e|cNYcMnsT2_v z*TtTIKC1R-(Db&05|$ivpK#K%9Df2*+WlaT9i6aKY$fx3Fhq+cO@BM{fbhx8zL`bn z9PtV+;2^{p(VBpOO2|C8DIy2m8IR0+)?A45QjEqJ=(?TIM#f%O+)Bf7lRWr}2_8L| zxR1RqX^#(BvhZLn+f_L)!sqbO<8RlivdeOas?yYJ|BUFJ!BEZVjUwRW`)iOYy~xa# zn3-?=mDJ{(sek<ign#ZSUT7SD>>fvvk;Qx(5#9hZY7xQ3mSKcY$3>Hy>;iEB_mWjn zX<r;4fNEC4_%?aa=lrz5A`s-ZcS1E48Kp^@-0fdy-aCeE9RV2|zw2NAr6q>Fh0uxS zhCPTk8GlLym9z;XGaYy3^aa!a^*z*WpVe}N9hcD}T`lnS1AknS$PZ)qq*NH2{cY2B z<x)Di|B0TwKoKBhtKgnzxdQtWQ{#{y^;O{{J6m$Z=sZ1Jii!L>yOwk;!M(WTUVaz6 zJUEKo8Gz=+C|!u%L-RHp)$fSzLn$rY!lvKDOP$gNb^whN>1D}PL8x*DST0n^>uWQ# ztFsBbWjSVNf`4`2k}K03Xc+d(fygKl8tO5ou(Y_Jq^ykvNAy*(#J_XAA%Jg+$6ck! ztfdXif4U3jq_HiMOi{lvt;4Z{4b`g!H&m=v<+?4~o!a6QkX!S8Qo$f8-Uh>?5^Ks6 z;lkJHE4Md5C2!t>ND8^V5t$V77c{jkDWTz_Wetsa7JufDKf0ALq(m9YDUzF{WG!rk zqLa5^6mj~deJZURIzAtJ<VZl^<pU7>HH1Mg#vut3aO@%hDEljfX5P7;>u%3HJ{j~l zNGi-RPsKw{4CAH-PY0PDoT8aCwLOJ&nw*)KTm8(fGLH9us;SOQ)1RJlhC<8?u^3Xf ziTMF48h=g;_mz`(jVQV-Z-Jpv#d#(<RpCrw?t$ns@R(=(H!PsXI@4cnu#^IwWd03E zC*kGjz;TLam`*H2Y8;3kcH05n%bi+ayehI95dD!^GSAS!tvQ|7YnHxRQ6<J`xfP`n zo}wV?%9a-ccXSf$TviNYV?=l?ykKUW5v&K5V}C`1OfF}6k2kKoX(Hy+fo&qfom_!^ z5QmMca!O#b&Kn9)2mWH@j4|k-4b`L_4x8QQiMeLiU!xFvOvaJxJkWOZK8cP6B7RY# zlNwijwlw*<**NK>prNtG68hOg^j$3~1>Q!m!F>m=G!z(6WSh({LBK({*oDe*bwPic zH-8Ng`!vNtMc^2Va3}<5O<DZtH@HJ_AOI&J4QtX_S&j|7xvIMS5>@4(5iCLlyMn4O z(6{Ilta+y03tZLfywustm5piZzt77R-DX0RO`4r+m=L_ixJD=+JvBWcfg3p)LguX? z)q&8<^+`>vgW9*(ln2$-J0Uj}Yfq>uz<<f6Pt3Zp{Pa%{hOA0EV5r`CV$S&qNUOOp zED=-6Mwlq{s5Jv-Wk;(LttcNklTNx~@{h%vU^J<n8y%=8*c59`uHG0SjIzg^6x{_F zB#~6L$h+L*?7?3qUe#(s`zrT}KZh04OC#!#R3l{`5J6Dv`SryQG;WNt?ekAAgMSRR za3dKco}zxYMu!igK6DpqYec*@CP#<Sm=XW?`=Gihoid7V?%bm5py!_Q2H^o8>Vcrb znk7R1hU<GpfMN0=V<J#OSqu#qO5%j5>P&QI3<znimY`yQLQU>p<VCzpy}^$T0Ft9= zM~eo0Or&w5yEz_v3NbS@*_}Ag8h^_(*PmEUGOss~zT8oIEVIud+kT?6E@qKH3&);G z1Dj<hq=5b?dgn+g>h~m&3xIgd)W1;r;C0YYrhlu;Y7}9ksi!OK1jGwBFYN`kzQ5B) zr^l`AY`Vh3-PsJp4ufVes&CzD84`AMA_ZAv5TXg5Sj$-yi{vMqOE0wAfPdW!tm>8# z_s!xE*nm7m+K_13hdEo?&Wg)5ME6zi`wfeBZR?fdFuN;f7=6ny_IndEaFBBt3Y50D zlJYqHlq7?q|7gy>Cr`JO6)cNvtHw-<h^bP99~tC@w;P~RWD|<2??Tztz7#hJn?P{2 z#}Ii>0V*=}l$Qg7&$XAw#(#nR|NVddce>ks1M~nSmqL_B+734H=0Jdw`jE1GYY@!f zNt0jbTV}j7)@(&Wl|i5&pPd1Q)Ow*fY>BH_M<ol{0K))WPjJuoTU@ROP#^1eqjn5+ z!MKC1Oe-HOOlnl2?*lcC>JcDzzFkl_=OL&c!4IY8x5jg6f(*W7aDN@XHm1YZC5C*z zp>Nvr`}Jle1aN#a!-wQqGUI;Oxt-asj!(dZIzPkzz4V<FP6L3;AR6q?LTa45{BvK& zn22NEvkIemRCRR^fpTnp>y)}Bwg{HY$bFT?T%A*JC-JxKW81c^iET`5+qUzI?PP+9 zZQHh;iEZ1t`JZ!d)jg-GAG-RfAG&&d_ugxNR>DYqd*fEwdcW3)mm!B2zNZ&!*IU5G z>O9G?%jyO38wzWN^)bMPeIF>lkPt*_ug1vhTy{mm@d^hR4`l(&hyy8r3_ir(<7<Vc zkR#hk7Aaewj2_Y&AbF(iM@H*>S^}ly>u9g)qfogh7E5r)H&?TY7G<+2iyDM2g|r@< z6on&fTJtlCb#zTMn0HW8T7lO;wv>a&&k0&6TJpUqCHBQkNd_okzWP&8dR7cFE3v~v zz!*4gkV<QVJEt0uS?VYe2IKtsr`rlp&7qN#46_$UBw5zu=9qK%D3>RD3H?Z>gtAwp z=d8E!>s!w9k}p#w8w0{Bh;F8E#7}p<-oeK$s>r^RAIJ%2CG3c(O<7wO<WY&74E8Mk zVp<^ZR9?cii3Fru-$N5Rn<pj~d7X8KzVBlRV$=m1RABi`X9WYWm7cZJTyI3}Rh7Py zCIujjoM0V5h1$UHE0_vKQm{T+-7_F;|0Wy0Md>Z<GvQIT-8_Pq;wdzrrRnU%)<_48 zC+bsM7<kO%rY6iixPvhEeUtE{>6hYlN8m?O*m2Z_LjxoxI=pX~y!)r;F<l!3<xFC- zl?VI<{$zWHX?~EcUE{BPR=Mo)xP%08@;pqR4$W})Ho1Y`u7zA}7EJDSG(u8wa-NMS z<g#xx#njkpTzvTlwx0e1zCu(66AM=yMvJ|GF$`RkJ}7D>FPE{-f`w%Rae_%fc9-2& zvI_Hblm~!rx<_V%xxLe;<DPjWK}*Es&f^^inooJm3QyzR5$A5ScI)lDVC_CThS3R% zH+8=KPA8{eI`r5p8=Djsz3#cRUQSGhR3r*W)LAIlnsC)6LNS(7<p67J>1HCECu18l z5lBw{jdNadHW<bNZXUOBNdqd2(E0^yYp+O>A^;fTHcC|$i*9OO!<LfuyqRChgsf?C zdahPND@2%PznHYn0R&|;Qxz5_c<D7(u^R4qFBU9#C2=x{WHjw@kUYWkgvw%=q9_I1 z7Q#=;DiO2YLERt3+b$VCy^I8<3h>7KW-*mMyC<KWNBaImv&NeJb-6Y5oUvv;+O-#q zNDWAH(SocVvML!3Y_sG2LfAI)W-XP9<6*7+vhG-!Wl%?Hu@`tl;AfsG*y_Le$Db(W z5QMC!H!A-j>u`8H#xF#!O19<fASI=&rg-CUD>>}IQ5mP=OpR>uyIS(VAFb^&c&24+ zV8>Iw(*}}5hBvJ*U0R+$^bY|fsdxgjzXTw1X>!L`bQ4Dm&#A1!Zr7UJo3U&P>@#~~ zz-B^}GfP4uPxpquSkX;wLb=!kU~Mfxm8@!A>MlGBfjdqtZy1j|M!3YNLQ@$Q&PYb9 zqy)5B!ZIqM7$c$sdeg0AejQa&%E3Gh3-L91=cbp!$8>V#sK<UkMPu&;b4cr2XaZ2x zd+bDnm$U7bZgdPv4?l@qYd`gZoGnSJ<vwA5UC0<nT?qblfOU9X=s#+47^nwNO=}<) z;sdlWBit^BSc5u^Or?pL!htQs@6CoQrr_fuJo`r#`YRQ`Rn=IDA7K(l%LAFkVkjUC zjt@D7*$&ESNoD=8k??UG;L8$O5CPzrU-@F+mDty#GpX@P-QhVnOBHWH?Bi|@#ZQvN zJ$L1qSwVVm4p}i&nbe!M1-~ZoDFlvGglU{Xvx1rI;3J&2xVlKTKw{sy)jwiXT=Z7U zGrdO#zgvgV(4L5Wn7&hyarXPI?v7UzR^aQ@h|6Rj49>NiIf2{*1Vahb_YMfQC0kT> z{mF=n)Mm9hiNPO0Xa(pdJNwM)5a+{HYdIu!Fsv+G1d$xOvJPp}t^r&cU^iU~MY^~| zj^MUh`}7=2L~yY$mTq){N{CCO-yOsOc73CJ(WjqmtlLI`$(uN=ucUNm`LC0o*ccoh zJgnRO!qGtuL`)Uf!Fo^WuYhGrw-5<-THs(?<VyJ*R}4+>j2n7K43qS|z4K^Hm_%VV zS9X6wGO*r1$NY4c7dYKt+V_r`9}-yOW}TpSq9z<zgV$8|w7Jo(@Ap56piLYeuN0g- zC}j;6gYxpJEO?wp)pUMZ+#5UAK1gkA?TWSOoCEi$2!e$QeXZSNmH_C4^z*}ddOxXN zG!~!K<_9}nEX>8A9t89fiP1QP8bRi0-6lmvrY`p-p`HD&m)!cU2`1p_B7y?tB^f10 z^yQAT3UiuayujasB|)kZioyv!L1Qa_m+O}_2W(dz8M)8>ZKL5C`LP_v*#x8!MOlB3 zG~VNaVL|YZ_Bm1lKLg-JQVo7~>sC%YJ<A0B1@DOh4f4?$i-Di*=90$Qz=#Wo20_KK zzI&N;#%7_NxumKogpA~IZW-|sK~<=VGhLeH;Ao|~u&yc@$>5gV)Y1bSK5(%#2&bY# zC#5-|RLMGH1B+3$`4kMMo-fHFhsWz=?8PcL(-aETjb+nd@d0fX$s*B%UUlipf$bKN zFkJg1`&kjP{hkp^%lO+VH*ozgE~1ij6Fp$?Mr4I6JO1H4(8f9sO;F>++?%sf2t@YQ z9?}FAJB~8Q5+bG&0Z(BcSQCEe@jF0Xbi4%oNYD+UtLR-3-AG3>JBw|yd0?2qHhakG zHwN>6Rjbr;)d7%TZ%~rMR2v8(>HV-x0i4NPYyv32A^tFo86O*N+i>>1I$#&bxD(12 zPPKuB@n)f8S@KdBL(rT}SMhHx-^(wibV$FBLhF|oi5k45N(nr8G>5TZo*w#)@}@N5 z5*CQR{sm10e1*VfWEK@Xp~4TE=<BEFHYy<TASSkE69L?X+2kIqT{gT;nHH;;wk7X+ zHD=wT6hGll@Cu-`&}ErWgs_qrAadpuIZd8&3s50zUfv-d7-#pmQY^==J9!2|(aa1R zxl|CL1{3MEeU`_f^$$`HUypQJGw-}-0|eP=ey3XX3f;LISQ6vIF5&f-&3<h3&i#!f zZRk#+NdvI3zH=wO`C>pzP%wE=bju5?WbS?^acWIXwnz~gO%6Uwxwx9YMcMxVl?}{# zq|e1cM<Tt<q<`nXBK%evJsOR_ffFJ81;!Fo`{=fO!YfWf@vxO4ez}1#aZRbFTNNIa z_v@z&6~Ub-*9|(2sH7exKKv^|Cw_NZnCbq2>I&EvG66qhGR%x_5U?>AsRZ9;{CkLu z<<|!txN6WNl;mmSpAXp@slbd-p>~l49ENa`;>u~j1bub}rN8~l)Q}I#Cd}tPe)S-* zDcm&KsJeOmNN21CA1z_r=eLnkHB97OuCE~*{3z*)fr9u6tw=uPnA*8#`Z?W%lc7c9 z032ZZJO(9kh6|z2?9pN9p*^q&5b_gb0CTT-2X`rM;Q~Lh&?^IZcCJ~c6%}O-@!rP0 z5VB6boWT`NjCVX<B)-hA-Z+z(qjeR?eYLyshe}+CTSn3nt|Y6(x0{o8t_<oO{Gu<V z*(A*Jhvws;7MZt|;rU#hNyK3>j0!f_CJW&3_ZjS*ru#bK@E1{~_ak-0ix(3J8gL9L z%(gXLSM>!xP3H!nr4&Qc1P_Vtx3G1(cXbVWDc1}<%$~BQI(OKQ(iS#d??-+EOsu}- z>mk(}T0*2sP8iZT%ltP9jGA*+N(Rl1w}xmQ5Z^ZC-t|Z2-qjISZ!L{bzmnjJ2LNUQ zU3CxkM<T8Zb{a~^3Ekbwh&#*WteyiZx5}jZhV<N~ad81gadB}$`$#M%N@=rI`F}-{ zh4WtGvxBHAHSx)hZmLDIkeIVXPR|~n^^Jf!lZY#4H$Los;sBY#;u_61Fb?0<;Yff8 zCkk@A2plM)7tDk}uxEr6-N}%u=>VYMz=R{CJx-{~Y!EiUnBu1#r)j@+&)r}SOJ1d5 z0TS(vu&F{g3R7AE{UR=fK&7gLJzdW?SpsE&;812s+2+R<LVoz2p)>D4%c2$&$iDCk zm65+WsSE#_1#+oM9D3qH`}K7NqN_b-p89|A3BAUNP%*joyO~^e>S2=dPyytUd1SUz zu1_q_!ZvSjsOwXy*uSZ-hrT@Mb|G$dMqq&~kowGqA<!EqZ%h_Zjqqm;Aif`g$k4Ja zRjz17sknaxCGg6qHT-e?U)6U~bOq$pVNh9XK*Bvee5JjWn723VT87q)_-_*<wFY5B z3PzFN!&idS4lHiUr$n|m`hY2+L>{PF5e(yk9~Z?ErrJV}y|j{Xd`^PGxuC3p;UZ6x zG)BFLlio2j*0^52_>O$WBl=N9HGi_KF0vZ=Hf#;mc($FAFzfY_oXgreBLO*NO?HIj zDK}-#p|nY$U^=^3EVnCD7_F;Qddk(rE<B>3exxte{h*$ZaKJ8HD}a;d3Pjj|E<$%c z1Cn2_xup+{q8<B8I-Dw>1$~#DH1~m0X>F^UtLsU!>nh3)gf5pM=^xxYHyC{cTpyrd zXd7~BtbI&==H6Ffa7G9%GAE+c<=9H=a2gZSP=@pHVII48@Q`xIEkPujuy#EKiQjR; zmEe75MvtHC<5l*958#vRpMX5=?Dw`@ED(je3VX8ptHli<a|7MKxYZ~#z(DdA^a=75 z*{JqwFt;l4XJZ)k@%nKg2-CiPASYJu)1?tztLGldhtuxzWTuxj@5(hX`SF1=WA4pC zSE2Zcpatwz^Vk+wg7&5K^eXEIYUdcV0vC}kmr+vp&J}2W25?tlJ8lW4<2G-RYrOs> z4V7;kcO$!bnk2(p8QmGZL3!@E+;)Ha`5iP423v5grMGN?ET)M0A%rD)&*ttR9%06C zH5U)?L<G`a32QY!+*Y11Uw(bQQ)VcWcj=TFSNvU`I{mD-<ru;Qe7wcwH6(n*v)EER z;qhY+<Mu5W0DL5N?}LX^*EuHSk_R6c_ij+%Z~W9QKu+?q^Yh*mpw9F-6;!hRaHS#8 z3Nd!2$n$?SwR=A^9KD0HOCG;WVMZM+>Bsu<`n+D;oKB2{$!B+c7&f1#Ja>n-s6P%H zYNLRYG&08e&QefnIbj6>;NjNWr3sd!`&*yo!T`H(fDf5U*eVGD8PVfqtA*@G$xY_s zUY5gMY1y>XEyN^T(t&CVB{~5zRS>zq#?%Hb0jde->dIqbR;h%^=c_2x;m~kT1%=?x z{a@4Ps#Swu70tBMMR$|D4=>KXL?`uE%F3<fJg8y_CQ^od#e|U2E~?4{Y&vt`m`xh7 zb=VJo0U#ioikrw?uJ>h1nXIudlpwRWd!nuuzI{U8jhI-^HtX2fGyjmaBho+S^oO!O z(%)J2Y)eKPYIR7>p)IAT^z^S6k)Ur~I?_7D-}g`uAh^z5r8?5btu_f^9jelDTw7#b z6n$~ATzw8;hfa8Qp!!mZSC|mnpdCG-d_CQ;0JqRL&o8JbD!q%b!vW6T2_i-af@*kN z>%v)ie44C7qPRLZP-NPoNaJMBLABm9+)U73+h-SL^m@A$k&zlb!u<Pk6}3G&uI0U7 zKTL|}xVp`KFh49>fu(~mlzuskijP9O#w-UVI%(85`G^hOO&#(H5_N0MTpj%8Jgmx3 zfblO=*iyixnE|x9G~>B!N4vC|E5eqgh<gq%<Q)RiKyDbbhUb9_v7gA2IZ+9=vu<p| zL36T0j8JUL>&NY*wm#{{n_DftTj&h{tU&Z;=^)ca+x87BNg}xKmQ2TiW&Yp@HX@HS z1l61yv}&(@!V0g03>Bv!oEYf>NsAv0ApcqftX8uX0__hwq?I*yP9)rd+J&2cUsPsH zWNfyyu++HI&K0CXs$f(o2`|4E{bh3-wGSO@;fl?Ko_4m$d<X3mt;+T%LP4C0rnBXt zu@#IfzF)=pW(~RyjRBZUX)m2y^mG+bOqED1w-u(=!fU@)RfKjnBU$!j8+`c3|AX%j zT<$VuRxLT|!3oDuFMu4T?=wxqZw7xyZiVAGDr8dU!ES=%Mu&bkzX-%%NuLzxlSWNY z<EDL#Rv%RslM=kBli)>f32wcLYHS%cbw_dI^jy+Ck{5AVEWSIPhs`!Kl0?Q=?ujrE z64GJZR!AblQDYV;f&Cg-oPfIlxLlK-iV#E7rX#YfCK*48#><A&MD-T3QYsyK{qVP( zGzd<xvo|d^@^(+%n#d*Z(nSmS?RJXm6U_k~V4h+(!9>IWofw&$i5{L=TvVS7otS}L zHHALF5RSZ&tyo`(yHK<<Z|u)xm=gN|stH+Vj=Et*GH_3eLfdI}q_9~7*y&*Q&FBB) zaQnt6z2ySaBrp3jXG?@Z{2@tJPTl}wfYA^%bR3-MzVmT*(QOj-{B1EpxfPOFWfb+} zf8y<j$OYf!XJm(X-Cc;kc0HG~YTO(c@3MkoHA1-qj}wUMi0ff@ee&Kyh7Z>}W5y#v z$wSsn1hJUC5B~%75cmWTPj|CTM|(t|4dSxTL=ZaD{vZtLTjDjMW}U9Rz3duz8_+-& zxMj0dbH{~QQ9ay`wF0Q+GQ5=O`M02l9(Yy^G;Ov>m)f1-F9&L#;2LnPkZ-1c(Z6ac zx)5IPpjQuqA=Q!G;(|tFQ^5cA)9?aP#pK=_)k2Pi9vR`C*{%QtO6~>*RH4o1dR53o zcK!?ou6;yMZg486(@k@f_BSpgwtXD^l;|)PyQhEsJ1iMs3m41L59t6g3Y2+g95S)2 zm1#9ZZzcfc7E)eRhgI5=Rt@|rcgyDe{MsowmiRZfu)>(##p{uc|M~JTq@0H|rx9K$ zYp_e%GDGL-^Ku86+PyEq{%!R1xqFTYDKTmqF3jD4QE#<3Wa}xFDhN@EV*c6~skrML z7L@xysJJ|y7Ve)a+P0`ZC$~bf*3!C_DKDD%3&Q38^GurcJDDJ))sQJR&^Wr_VUFh6 z`ZMbxPx~shY+!<C`(R8{na=#Qsp^gS^9cvW=i|ul>oN-<^hwnRl-R%fy<m+M;16`& zEhZf%!dmHrR#}jq%;=RreS2%^o3P6D!p)Zdj&DptNcX2s0Am1XU_4f~lsRu2Y@d~d zG}R}Y_hX6Kp<7ARBZYmXUVv~x+xX}S*BsH^n|p`&c1q!g6Os52&a6IXP=W@l{2KH& zqUS3&I^q*hqUwy%Qu%OJpJi1;9t}Px5F*4OG2wDHrRU`9YisEH@xp9$enud&BiwH( zy@4zts}TjBt;B8=&gokGK)ErZU{);V>6|HkA!mze_GGOwSs%)}X07}lT-{o1K4hvf zQy<-)?K`i2y^?yD74b0mNqjpt{@qg~Dwb`7takt?Hd5_DFcPfpw<c7A@n;87z37QR z0Kovsh=SmL(dB&qxk_Nol`@50T>pqLP&1F>!p0D(O8Qc<qHa@uPB1z94UrJ~!04hy z|5_AlB7F1p0^coU%ett8o!gt={#)MtdXI>p7*n1%=`O;74qIfkW_^R-qy%$Ju%5_4 znGEolxuUUILOqdE_g<Vg0XejK@FzWTd5yqW;aV5>%+A5!C~Ps`fj#L|@5nl>j#$ra zNppDkY)p2KzkxVVgS_YZrRDi|mKvN<v|Le*vruQyiFp?rq&^Rf#jULbf@n^sfyl{} zrI2CH0(@Ea{j1;PjHxqHU$-Wgag__s+y$Tp#}55jAZfa4jZoeZECNJOuiq1^;OJw+ z!VJ+NSe0uxx<ml|C_CBcu2-p6#eN(@n4XwtL%tVv{Q6O8aQX-jUG%d&^174^&JvjL zCXhL9@tKLszLC2zFoKq%LBD`|Y54gvg`12q<^-;$YG;<oy`QMT<qLO|hApXhL=W(D zC;!XU%4@s2FzFrA%*4#|NWjmnb5zvLMy8<!T2w^j6)mL%ogjP*`Ukn5X|f?-7#zD~ zsL*^y;?(7w)2G|d01rot3B|AOT*KuyBX(HwS~gFCl0ulYFanDmkU_S)3fCxx&0N9+ zwAig-GIcsO8p0<<@Vf_Zq|VaHL=ND3Q~i`=P0IAjQhYif)fLIP4~Dc*#9e!(i^h%I zYc&U1dvT}AwT(??uUY<h?JLO9djhgh534iFxuM+~;E$RA9#OUlOK5TPz77o8`rOVM zGFoB|w5^Z5qw$q>XazcbDK1Gz1SEHk;y^*?e7cKl)e;~m@L8iCRuiXDLl5w12Y-Xp zX5^oE$~=@c6Hegw+UcG}H!bUcf&MnAdP~S+1KJ2gEQurdr$@E?-dI_W;4H=WK*#|{ z?BS^7uIo$S4cbSCLK!%VGnjjpy#8`0bR*ny=Xx{DhT6U7){U?}cfX(fv0+PJYC<9N z^yFMa`laD2<8+e4<9xirGzAFv{NBh?L4KCab2BS*>XAc$70z?DM_$CWTM%qet8`mI zECOBpnm^?F2;1<uj))zHW;Yl9B(D{g&GRVm%wtu}l~m4ZJm0Z6jv+^%R<7m^EESS^ z1Nc4NAR=aV!TW*{vniwGdH1Sfjl)Au^7_rhxH~=DZBf@d=Tk&@7y@X+AK@QDtWW}h zk4gr06$?S^!c05@+fLEOoLZSTt@qf4q~h$}+AlqlZh#H9#Ro>DlS~?QmOMGG=Kh?` z$`@K4(41O|PFc1Vg+_WFD8sYuOXVZU@ui4Q@T^>y&|<B5C7YFL^uR4&>v4aDuQ{<k z+>WrRXc+?qN!<aH`vI(e;dJ!M7l(?3yU=_d;b5E?JJAo{-mY8g)x>RYlss>TZV`Bd zg%|Bz{6@TZCn&wGV!#%=SpT!OS&&_kyGlM&{dYC(m;nPng2BH0?mB~ncJ4-RBKTQJ ztQSZhFYWus0lwf<NAs7FAcVF~8HOIU#+|q5gXFe@VcGZho)iGZa{iMtCrP1d7lP<* zcEZmYG+Sh*hGO`;N@0&;ys$v%+V6a{hI2w0zk6YOAT@$ei?5Rqt(wv?J6e>yJ6EU~ zY^Y)M%N(1EWH=<`wK&<RKlu-rasK%r<F-+ZdpqM<ZA1z?<=nAfFh3}51?RN>nodWr zfR{<id%KvC{|rELD-x6=qVQ^wutcTDe7aXv#vXq`Rbu#zzB|KWb=^pZ|9q^~tdLs5 z=O-g2WYQv0svkIFEDWUXRz2-um2c@u>REJMx7b%95<l%_hxyJ?6wcq)-1PTMOx0N( z&&cP>b7Dj$LR&^3<+S)~4w|q@;qI@{5C2J?23bVR?o5C#&F&x!=Ri@7nR<C6nlrz8 z;FS8nA1cZE_`IueY{KdZOW92f!rz3pmi2s~&24kHzs*iNsn;JDhAih0e(ULDOkg4G z%)Q!=M)yTqxL^xHprQHEvjK%`&-SL`dl^xl%8OGVOgyaJ;1XWzYA1d>$~gDnB?Nc! z>R^lCXHEm`AS)(m;M8+!#(#-<X%%Of{d)Tyi?xKcqE0x{(u?{%MvhlNz~$%)jz$aL zl!KQ^)7%xED$p5bAnoa@6<s}ijb~70OuSpqAPx2g5gLOza%hwiDq{9RxL{v*)+8iK z!DSUd3_cd!&Kq%QMR_f4G83y?P+@;{&ft4Kk#7X(MMZVfbn<X|A}cr<Ukp-a`QtpB ztBMmX(AF(ieQf*A{QAONG#OO2hyL2M(*lw{>WAv0&l&n65lCM%I8faA5Jl35CDR2~ z_oaranp}~P?Nf)6)4`qY2-SBYBCc*xgKm&jk%Jt`L~e&!DiM)Twt5;|GB-^@C!Jrm zjoAQb<l-BXi0gi{%Kzp|^Sk}iLs`ZI@07y-u%$O0>^JJ``m4c<i1CiU-^qN9zHjwX zwn)3UEz_4T!jODiApPjbZC7cxv`<^V<R=Yl<{bkBv*0+|;U{PapEz}H00>qBXb&bT zA%q+$>)y&wjiceAQ-?0!fuYM&{%SiF+T#%*!I153RjLm-X$Y@pZGMQD;wXtf%d--a zXO+37-Jpmi_%ysbnM*s(qlV*p+2MZsc{RzTSM)E%fj47m)C9j~9lxfJv$)gGugExp z$3;51qqxYtzxsaIHLoY<uPgfeP*z(4O^A5E(ok3e{B4-SS)&A4w|NU-MO@5$DSH4K zIhxndjNx&-9Gx!M2yUXW*$3GO3-~HOmAVtAN|YjS1>;sa)hf+TOAP8yZWr+;i)tqy zQSvc=2pYfIS9@=0+8p8YAI^ecJmf;e09I>pK>w1Bxn6%#Z;@tRuDK$o0a(LO?v4H; zL-BU3!uo)J!p^lga}Vy2N6vSdI5Xgl2VY<wZ1&$f#B+GnDzo+cr7WmG)ld%3UnAgW zreZWI_nEsVI0Ccdw)~yhywN5C@i^f)_7E1Ax4^B_=*3y9ud#J(weL*fk+jN^t1EY$ zL~qUG@>Z%VHW;0$;l}8a&N^T}MPDj4D>*Em9g8qIH?GH6DNt8Az0H#)Ob&qVv}wqK ztgi@D=<1?(B>1!fc!DWX2HRArLCVtz;Zm|oG4-J&lETr*uQ%>f6{S(!&$p%h1KU@G zaQito`|H%}K}QlcdBhTuuv~8?kKK?B(qVYoSj)PMM;&-dUpC(z=3(lPo{-ebBd|OB zS6<)t>5Pv~Rq|?ddtKW|7-<0D)gs?Ib1q3j-{*lQ<wgT8U|Zsd^0Q8(Dw*obd9xDZ z8$z9Z#r=-weQY3(8q89UgOq{qiAEVHwL4)Tznr19A;=!>_N;obqUE|1^NjZc67Cn8 zyH+mgocfEF<0IzIc&>D-%wZs46*eG49V<@`QzI^C4g$B}pNPkPaUXybHc&||S)9)E zb+ZoucaoqKYYo4Tx2RFX7!`HE=z7opYS*9zU&d7TaNjPAP`&_yM)WOXdtQa^SE>$6 zM1h})DR3;SygaomEnv4+U7fh{_~FZ380Evk1l&l)l-?ouj>R9#D?LMuyek*JbE#Ca zD$BG>I~4S-h@7E|`7XKpqeC}&Zzb%f1B`BebHk9Ou=o?8bFcW;y5129sgY04Gadl> zV9sJ(iHz=N@2M@ia<})SNyXp)D~r8_FBS(K1nfVc%@(zIoG<YIzST&<A%{Zv&r<?Q zo{d`wARrXN)I1$5)YKgkY_Qa~20~;&k><AjIy;izv%ZiABYQ54?0k_fkN}!>6#R)F z&=^6eA(BOUN}FV%w35_@;rDxNp=bmNIgcelV%oE>#MZ5cd*O4Sx+K2!IE-k;U)T`- zSsi)|Z+gih?vz5*jWfikp|H4|t?%1chK{cH`}>h~+@Nn6ngosBZHu5UU7{C&Cd>5b z-7rE)CH2G-cO8llnPQfO>F|U6v<w6L1pdGMVwH(O=;on93yF#;N*!qy!FwkTf&!RS zHo`b|8wpV<Y-p9<9bcClCtjLSP-K?bc;^&Uo!GEG#fL3WcYa`zOo>KC_k7|k8(IrT zh3r)e2dCOqshC$0_Q^3#X8IYx>-6P9IjaOH3YtL`A%45-Ig(KMn?L!d^pW87EyALG zh<U4<XOB|@ZNSGoq>fkka(1aNC}dwTr(}o37cb}a${a)i{srY)46s)zDrO)OJH%=q zf)knP7~x2oTO+7yE79*==5ky&Z?C~V8?#DKUV>5*<6wLj?<o^mr$0u3qQSv(6tsUE z#EhHiF??a!xsI#ukxn`(9@>da!Ki4CO&R(Gn%P3*;bQs5YYl%qr%%~@e(W}N$&6;G z#H}91T?aCtQhf=-d!W?k|Kc6g?tNHLUDF_S*vU4XkpJljl*_ycDy`aS$<WL+mJUj6 zm8t~ftH8yI=3L0v32vwWY(iT@9-n{fp(%hYcsu!kC7G#lamV1-1y?E+M^_l?;=WHq zUXM0Y%e79EDl{J(!bEBq?#5{_jR#`$hIxVs96;PiV&9~<<wo`s^9ji*(7guIR8VZu zSk&dK#+Uy-2&EPopd}$M9I*8Lr4}}(i&BVT*g4#?Z9q-NS-i&sz-E{&2ZUC@3x#60 zX7rxhKy<~8Y{O(q%$J0Xd8+QBVrdC<rgP!jir*KslIrz@OX9p8ZOWvtFltx!i&3Cs zoCR~R#qKh(YftIQX0NHphOsLGQ$aOW&%r|lPq}zO6iqN}ies`fbQtC~nkY+8XN;%> zmbsajQ7o&h*Sa+VM!agZDbf5PE85BAXH<h{-6aE~Lc@aZS$-0nhoh1$CKm3WwLXJE zy!%T|2F~XT2|?9J-+b@9PaJbIv>eU4EpTvL8me$GMNm~XD`hi~5y=^e<y{&fT1&{e z_6ND-Ku@<j%qFvaW7H0$hG<6w5*w5w7LD`>B>29?98FFDUUM^%1u2hr`xa<EA`vV; zCtdlQvSemfz~+8Nsg-n7h?z%Zk`=50t0*0V-u=j=7^d+M1Ej1r%|0d_y`CV7XIL#t zN1fSLJzd$eAf(+{9lcyi<r%&>>~6=p+m(Oks>qB==iPZ)vv=~C14`(vX4<%8#-+IC z<h0uI%QJleITlMhT8h&~y|Y?HtOFRw&(52=HZ&s*>*@Vfs=Fn0<)-mK#V-xnZmXwk z9K9ZTf3KAwmjw>fxtH(T&cU|Nsf$xap5J$E&nqpPvBq5vs3BRFZttwPg8y}s_>dwG zxw*a`g&myfIyv5&T{=D`D|&|Wf&oMJjtxDpj4g!#X38=o^K<@!B|_1uN=quE*y-wd zKzPoQxQ;z!@8_#e0cF!v_Xi0Gt=&qfIpMAH0aKD!o1PTS9gg=|lQ?BHMU6dC<w7YL z;&gm@ArgGP)%A0)ObP6AwN_Famu&IvfaLvUt$Q0I@n~Vb#?rf=?*WeVzH~at0Am2F zMqG#o><S?kz16ufAad`NahO0p5F~AObotWYyBB^r7nFdstMYRe>(;yCw0m91BbBmf z)ic5)&fIdk;guA!=zW2bRd)Y<s!A!==1ek7{P`+M3E_FRlC%2we<uhZ47J*c5}9AT z@3MfAQ+<_hCsj|+;dKqhP1qxT`|a_gk<`opU_J-d?{WNvfa-2K0{igkq(?(B+cYR8 z$N}!3Z^Fmrwavr+b?Oa{vxs&2q|Y<_R$tn57%p)v_to*H77aoZbPJm76aL^Wr#McE zA@)f74w8i7OstLD_(qC?)rlsY;;;QaZ2G^J8|4}x``vU31CJmjL4MzTO^gs;j$j7@ zEdO!8WPLF~hE|@`-t_23Xyyyzwro6fQT>JCed<W4Tn5#Mbnk#`xm&thst78V=1k^X z5%UCn&4D$l34orrzs@)up*)9+@N0iRWM!e%)5^+~>>sSMx|g6$y-e16hM&h2`8koE zA(NirHJ$o2qL785Zi=6hZk7!kU7mvhPRG0Rc)L_VVD@Kvs+O(6c*@a<LHNS=YpOUZ zML3pID-LVk*0OSoVi9#Uv=_5s$y`U%dL=Ku!&wdh@-}za8qUU&a$S!3J8`sK&=rC+ z!ykI*^8L~)myK0RmhjD`f96d2mb4aUjFIuP)96RpOvKWs;nU}6FBSC|zaSOhWkA8u ze&W!efc{H7XNzzi{x7?Fv;>D1?7wyNxdMk6_`h_Nqojk%8w3bQ0V35P9tSg(uL=hV z5WB{N<U6AteV1Hn$qy7!t}WeCx^%@)q`HJ57W%u_wwBbJL{Rm+tNXyr;6BlRCX>tA zZ1`hUQmpqU>(djgolWN=;2oeogIx*eri&U{Iow-6J7o@nbR65^SwVaC&xD@x{s?;g zissSGKa+!=S<I=Pa!0$RDa;fzAc)%nNadNv`1baHN9S9pvsUfG*4&DX-IMRKwAfS} z%l|e$qu%5E%F`$a5Hj_TH|U-b(s!vYOQtXC6@`Y8sdkXSk&8sNBC-T&A8gwV$J2~J zM+3*qj3k-UP}hu07uq<DWKFd&v+-IgWT)=@29j6GT`?xaO~(||U+JW5gW&7~I7_(u zHriIeEKPb|&0}qxAK{pGC?s!rfu^yMNcoBp;*#U4xL}_t`?yn0_L#>ODeu6zs=A=Z zgkTvHB;<<l<V{z8=@2(b|DH&HYn3n(wW?LBEvTC^aTuGFoT`p!4>u7$8JJI4`BiJ& z=*-UIBt%+(%}G3kWW~V7TsJTX2xNsMP-NiP$1(J^bSO(!kwSk*Gjm$(=F2DIZ2oHy z#m?#62$&l77+ySSgo)bI&qV0#_AMqC;tAXT3%h8~{_IlgylVv;yhfEoARqGWq|NSL z(`gvV=}4XUl9~o}T6GdA+%F_O{TD(kebDhs+bO}Ljk?o$<WyE6!c~0_aBhQ|X;gJh zcDu?y;X7R={A9kyZ?EK!%R!@42jsHng0=ia5z~h9cX`ds9>qST<`u#+hsQhRy`^Cx z737bKTvfVY&0FYs^TyYeWis~qV1;zebDsEam<`@{x!t3o&cB;I?8tLm>}Y*%*A)>F zfUxp*yqP!Q>>BdRf6jqu|KA7f7EE(11O@~&k$P2wvkG8Bhk#cJ$Ifbmans1dz!37U z``bm{^9v^swi%SBgx(F56D;2#T8IR5NDy9@oPMY!Q8m&=6_xZeHJ=-~u9PK@Rb+$b zjUqJH{DG2`yTI|_oNBg<lf(v@Hr`a%K&m5cNT`<NL)B0P1<2Q|_EnX@BqkjVn$DE` z0h%gN#}5$NqMKhADd3u`ak`nAb41Yjv@<cqy<-H?=S3fB)D;Tbib(yh9!=~839Q=b zNyV99l(?K(M|*s@xfhCG(wOu`qv1F|e5aZ?E{JH9DXdA=di-{<Z6c3Sg&X&Ego1M2 zA~E|sI~UQ<S>_k6q4`(ThHMcrkCgp&HWT8(wI)C&vMG0shEJG@mRK07zyPL(q3w)6 zfaUqIHTV7t9>BIHu8x%5_hiECa$R>)Yu{!6Ehs=Sm&9YxpXQZ^=GOmWxf8#E&the4 z_G+}0EEkf*fQXzakLr)9P$tlp88!6Wg^U3g(wkz=`mcw;$EbHFX(CtL5vu!!$?rn> zB^e;V_w>)p%jc}?N|VASR`lriWLAXb;<Z;x*m3qt{`W5s_fUp6eLv?ln4*+Z!zqmA zMGos3K5Q^n6xfL=SW~2kit>fcE{TQa8HlpCl+v~(-?NCVENApx#kwR3D^_-NXILNO zy5g~(3izViHk)oO5^*=T^}$BnmnDR^AHG=N{7pf*#o9kNxOPsDgK|R?Ijg^?Yd4j= zKN^BuS-n0dG8WNwQnUVJGuIw+BVDz@LXdGoK$w^+9@=7#|MD0wWDAz7=G03R6xooq zOQ=(yZ*`Q(rlSABftBQAlr>U59j7j#+zF@gnf#5k)|q-0Bu0cv`uFN?zhlM~gaQy7 za!#L#T4bLtKe5PBOp$JoRSe*nLT;rpvlWRq$c$S@oiyVh35lb9u^p}&a38p}LGCg9 z{`}<Bp)ZF2lD@{tzBQYLL`V7nlG?H2L>7R2D56Bu|5La?uNzRl0>2m{Neyn2sYCrY z8bz=kMYiuRUj~AYiaN_GbkU)8lq{fR9Y5!_fC}f~nM<Jk+-6cH|BUUXLHUWQ7T(d0 zvp6MV&@kjcSmA0Y#cPjhOpbl<;_R4Fd*=13VMp6>r?a#3A_T`B|NbvcW7<<%Y7ORX zAlmaCuAEqbr5iy^u{xHYP^&?Iwe@h-$HmdPmpfK?(oHQKDU|)jTaxzmh8OMmvb){q zKvfUpz}$xG=2K3|)%O2P<rFaPNfCkt0&*lzB|84mleQ*8gw*&(95gbEO&jldKHK>u z5BVoi3uYA32ryt%1(PK=!21@@fH4{InB7|HXd@0Dp7&C)c}me1XU2jJ#ybdwHn|WR zeXk#k#xmJ=Y)TW(A+CGh7z$hOWYHu_mb+f>2}IGks&J3|0@mc`eo8Zr5uhfDsK_rV z;|al1K!z|mk_94GaXhzLMmgY6sEePT_bx6bnbD|$ga(qb1qk9GgEQY6*b_Wfv+5m& zg&mqt0Td)M<Iv&v7sKyKP+(*8hX`R|sX3~SuF+ABD5m5FrS{Z%<>`Sy2ljiGy^&<G zk$-BF-xpP*;fdh;O@S}K_W*GPk7boYMTjqGb*^zOH-V)<`#qabwgh#$^JfH^SwnD7 zvs%|z(F96jw9C#E24P0>2X-lH<M?kSF&gANPUAl#^Gw0v1aPlxYQIuVE8_3g;8FDp zY*c&bsta9{Aoj8KrQrtKfjbI7Tu}u0qnpRE)nXs9*5pj;%ns5!nE^V1#)k4`+H%IV zHI$_5s#Jr*RHVj#KswrU_sCki4qRxQt(Az#%J3jF0u;eTxJHSF%W7e&_cgNA$)t<{ z%%QbMyN=HLfxo5B+BrBxRe-5!Xt-wgq0FgpcLSM~{@{pRe&4a&7yBO+rGF~XW|P{> zT?Smy!JqqiC?Uk{|4<0njGlTmxd}rlKb=CwyKSwd8}falmGx4J`lu+6={9$DJ3OuU zEmG$XFd20ev`_C}L+4lCMyBAAB@`a~dmS8}bFD<ur^F}f^;)^?;(bp4fhq$6Iy(?! z9bfd!YQ;|`)gaa15VQHm480LkmR5F-J`A1nv!Qgs%=xr0wE?5D21FjmLMvDP!^1ni z@VSpzy#yx(o34b*BW{t49jnCir^aI3a8#maywZh3BsZ79{y;<=CqqFD0#Dg@t5+90 zfzY9fmIg#TXBg3}dv%y2c^O4W`6~`{nR8ui{I|KfwSZphU#LRBO?8p|3SC13Op+SC zHY2?`UZ<k!F@W2w;0KJ4`@8gpV4nuOt{IW0U97z$Fo;t@d${-5ZT|-$BA-e8T2Q2& z#;+3JPT1^UaHej#EuK;P{YMH6R+bcc><wAhix`ZwcE+o-a+w&6L`g)2szU)~s8#wR z`-cqy`<xTRBLSvU1dl&nvX~_P)P=d7U4qa;U=J6x4?x-QAZt!Mr2C*D&KixhyTC+! z@a_3$Vjtr|C5A<R)7Pc+_e;#Whg*S_Y{B+h$K&PUc6LpM5NgYSljqCIdy9Q`Cohqb z=0#4Dx*kXs3Hk&?&CXzy&xy0o1tAg^CO{)yGilO*;y@P(*BhFSvWLOwWSfgT*kxP4 zC#cCV43N%YtD5KQ@wxx_d<|&xdgL?MrWUnC8H#xMb-41|vs62izm9XQhZDd0;<bEd zg9}swyf1Wmz+pWuLo@Sod~Zw~L!`uN-&7q#fJ6#!)6?fKnq6rW&WD%N`7j2wXbQz8 z*PvVhn1@`okHBcI;=OQv^ukQ%cfaI6i!4t%UqCUfT7JJ7aC>Rz?H=MGn$0^C*gaQ@ z$1Fr-9f}DTEYS<fhP_Utnhj~%vR6x6YK-}6W6@$77_uasm8ymX3-QdbUtEc35|kk) zGDA$`zkwN#gnBG(6U|;7$yyQq&qToprSnz?99Bf?o6~?^EIUwW=@^;$t-nF|mASxW zh5+hyIGT=f532&T@?ZBlAlFoXn?pu9Ml#t}YgoMbAZ@M#ErePqB&Z+xQ=865p6wZ@ zC!Yw<?3{J>ys;bG`!X@e$4BMEYIDMt{}!XMFJbJuVoF~+wXy9bL(HNK#QJW*fR28- zEWM%3n$m82oXii45RTlMOJ2=XVIE^%>H)6BTAa6dE}Ms08%8FbjZ>xu9&LBLd|@=A zovs)aXNrEmm8d5#Or@(61jiy0qy>4Jixv$p65%g&&Q8Hj5v>^f`A3sJ7Y<g*D;AHl z^KDe8smM6hp<(gY1#j=*f*sB+^!X?k-g%8fNj8Dg*_u(?aXMT|I1N)*dHo>t<_W;Q zuB!t+K7NHT>Bj6KVBsE$r@S72W_t#y;n1p(_=~&iDuruLRHZ}$ru11xaoXU<#siV$ zv_v>on&d>-nR+NV{k)E$l<W>tT403-)7+tHXjNP@_-95p7j|{JV*LONnc6$dA2P>K zp7#vXcYc7uqPkoaJU6pEXgDZyst+JhIE3`z-!@*gE(LlF^~D!yJNTT$lSVmE%lrMl zan|U}H|&UY-9)2?RXqqd`Y%gIFI)*Z9V1nlskTD$9~)I_ktWpqff6&!(!4ouMJraK zf7a7!R8=N7k#rYPC-{EmQ+Sv-Sx?_QB0UIfaYE{lDW0EAVyI_q$)6k3^kRSwr=ec- zM*raZ9`K<AMf2OO-|VcTyJA6b2t|{L=DU17g+Sz10pfGF>s$V;_?2mYJgxEx#VJWL zL*rlzDy!BEL|rao^tXj5-&l;bnQytOdl4Fg=teOX#ycii9o>(ogpWTV3hKjcY91O( zZ3ssx`17ws_{nXdYfQ8SL=!;7qnA;Xexpt?%b<8V-RWe8)7A#ZBM5R!EZ@__*b(`7 zm@aSMpq_*-Tm3=kE%U=7A;E*77hIpEjvm3|VlwWL(h+M|=E4Z78B$(@16)~q<*h?q zQ5DGYtq=VVFAW;3*Yb3&P8g?(C0WDA@o~<mckT1WI@`;1u1%x@?FNAAaN8~TFn~PU z%IUMI(H}j}6iOdFe=Zq}R~$O-_V=GF_q6GT$_rSz#;@I28G(ax35vGN&CkoXZp%*S zZU~eXv1|+ijfS#+&0ZyH&v5iw8@QKpEyKm}Ueq&7R1}824MK&MkA5qN#X=NY$$Nv% zNFBcZiA(Q0vpBkh9clpI-n)G=q>1SnXI!ms`5Qq^<%SvuG4$D$dUdPNIU&NPDw;;p z`Wknwr*EXq6+i^!@x{y?VRkF{%M-y2rf#Zzt*$%5yUU6y9h+^U*Fu}Q;bPoABio_H zUJkh+8^(Yi(>EYOeNWK_GpcREh*LmqbR-7Mttq`6PTcV%$r1n~v*jRec-!loG7Dh0 zkV2KFKf5h(h(o_DMaXERaMY2<GS~7h7T41f$dK>fw&!VWCX46a(C_yRk}KKn-!2m5 z@plzuLI4>gfHWnmkO0kh{PeQ8V{-ud;)WZrW#d#c7SM9!6t?H{kun%OZDe}8$A0wr zyW9aiE_3~Gu>m-FIvZ`4igG!laLEMTxNAxA&<sv?JKkW5X`Z7XLbB{R!MbdK^|&&e zveqsZXs>0E>tdi2Ev9C`)C<!xd){cA?${*gLppj0=JX`k^Hhg7#~e}h!#ZL-f>z$2 zE1BQ{M<ry@?fVwb^C07k#Z-hKy@afS_6E)o|3?nccE))S_@9TuJl)L#dT=114%Afr zC|t~xUK}WZ`v2?FJ1!)_je?{|AmW&rV7K$N_RaHyhX~53Oo~&0C&uohe{Q==oMD>s z;HTKg!_P_|;meP7TzB)RX<hC#D54BjE3OGwX;`9AJ$DRG(j=}KlOBjr>W>+NtW;M2 zD?Wnmw69c1T!QvVeqp)SR+`AMZP^FyZkYgR-_};$<{Y*seK|h+ecEZr8Fba0&-L4| z(^{EDE9*=HedkkY1sv5M{LS<qP(#zUU~72_M<lLVku#U`Eh3EGmIPc?*424+yGZw% z=1J=bkI~6^{|Z<x3R%rM^Q$7uMu(^L=Mf;!T{A97c=T)O+b@NQq+h5M%z@Wf(p&}L zDZl(tx6#*b@%iOb5C<`cTXfcY7ULpuuF3?Omxbsx1F3wZ$o5Jq@RzmtN&!NS;t#n1 zwoMu`IC)B#IKa3GTk~-K;@3<%bui~~0ky^eaGih3VgFCt*<;S7?r_Lh4@&pKx_Abw zhXTAbIaE*TKGJv%)=m!wyuARS&EyUcJ%>JKFtyxk0^KtqEg6vJY4rGIT2PcK$V&vU z!H9IjzDUueO7_{qx%3#gB=Hi3UcEtZ>T*Tod@EPvv1?JW`y^N-+-G}8^yd-=##j_X zQ>gos?*RLD0_4anqG8zWcC!(Gj8?=O7j}KqE*%)DrKC%ibf($=?<@eWI&lF&q5<+6 zEgb3N6nUX{_3?W;@F6e;$p$moYeOf#1xe#6*?rq^_lrOZSt{VGWTEXoo8oW-_^9^f z-zg%P7;mt2Y?yK6CGSD?q_Z<#ZWuc`Dz738%Quu5nvxUMxiRke2=dghfN&F2x#kP2 z%B69}qkWz*?nb4r+{YzJ+M_)nsQ&{^YIOKtW6hv5(o(o1SFypG)t;xn!}ef(-KG@3 zSCvZnN3P~V;8Ap-uyAR(4==Be>*pRfu4*UEyHkN&x-x$l9OmOmFPT<5`$yNtmuj0B zSd0Y~Cs_yXNEHN6L4j7&>m=+s3-E9I;HAMdKf#lh5M!}a?C?2yE9iPa!(O=0NG$1| z{aALlYq8n)dLAiI-#KKQVmSlb2m?SQ?%{q-XlKKpInNXh+SQA&E>FMta^8VngZ|5_ z?G^mQcY)ag=ADBeL{8?2ek3n<dCQ6H&FyI0i0;nx_HB+TH*_UhqH9Q?ZPS`756E3A z;FmxqO2np<2a>#woE;8;&D!;PQO{wGCB;xHm0p=R#1K^SUgr)}&hX{Sm*nM}GLY!k zHUYfc65|w<Ia|qqa7j7-K|lUJmo8}yiLk|)LsqQa*2L+RA4OkAQ?72}rAM|%ics<~ z4~0p#vAfIq8V~mZBK$&V+{)yf2R>!qi<=g;+wdm>v)eftGy5_?7*^d%(}kzKs3S=9 zKH*RDAJgfzOVI3s(0{gUCRh>ve8j!^>q}wo1&{PK8I#n?eQN!;385kTvc@vR+J}I< zsSqs9SPWQwj^obO4qe^tjTo{;MHXfTmg|4BO|k>=EfN3Xhvn$pS9@^0qZn|aoz5G* z<JTdW&kkZuaOMgDTu#5sT%;`|6P#m&LF^jbe%N*RS#;+q+O5u2f2QS&u!PV|gSVbC z)CeJch|@-M7Kd_X8^eX2Tv}~wIG}PCP05xr{}gZ+u)ww8gRLpUr#jm62S~14AWV7` zB%e7fJa~7ly?B4L?ZkxOJ_~vz^0~kCsUbxz_OVyz$N5Q$3dbk>dYR{W3i^6O^>NJT z7B7eb$xab~#bxx%gsiitNBK3>)gdLZG+hbE*+(j+ImarT>iu8Ec8lN;PA}Mh^>GF6 z?)zThfq>rFQ-Ldg>TdFJ97cc=IrTPmn0L^V?3;>j;`HRz1*X&{m+a<~-|EQbzklif zUbnhzR|o<>ilNE}>MlcfURM}VUarCz7(;`wo^0DzNq+wdx3gGpHy<spsSqChnM}0% zSn%+1gb&EU)rw9dzRMk$E?r>lys2t;syiPS{6eM&dGUNs<zQ^U-0lMS+zvd~^vGJA zWRzna*l&ZbeH3HdovSWY+^)O|C11-)WWO#rmab9M9Ij~Jt|VE&{4x*tTm(|7564W* zWCN8ePdUwtt3>tH1}IDxd+J`|&@+7~po*;nW$u(=-m&iLlL`5v=tLDK^LFwOf&=uU zzElulmb%w2f$s@CmRJC&BUe1El|XTxq*f4~L4>?>eZZNIaK2?_2uzj`6-GI`K#7LP zvk~}6)=$HXzm}plh1fu6y8h(wa%IMVZS6tcwQ8tnKdYpY`Di&;##%lBo6NdVCnh0e z%~EakT}KV&m)>_H>Kz_Gu}M0L9d#N<(7_EH3py&R5tiR2uLuETcZ4KvsDCp;$<;TT z6dxc3(n)13Kg8`>H3UqN@5H?_Ya|d<i%3bPQQ>8T6k4JTQh4px-PND3F?e~ZL(Rhv zjM7qcO+zX|fb5b%T78~BUDj344wAtB5psxm+uC2#>jO8Xeap2B6WsXO<!Zi=&B8R= zUZw(<NUKG%k%R_7sj_oE`m<dJ>D(gWO=*#uXa}fwUy0X&(G0PV)|Z!s(nWbG+M~Lf zP4te&u~}KVK+lF4;`!W4#0!y<HN6C#E4v=hhKyt-x3?u?*}{xMB|n0YPnVM^pvoA} zRy7_Jng45yrD~vGQ}EFKGeGd9KCvL;mpYdgx(bUH51tQz=xw@_)c+(|tko-SYc|QH z46`DthSxUn-0cdM!L2RWc109&k#FP$bMNaK{6-3!#;G;5j$tJ~(*v5G;57PNZ$ojV z-uxqj(YDZtRO+7KqLr}0Di?@|6j)ADqrRI*GocmixJOs)tealoW-f)`w5&889?B=m zVGB8uD&+&%mGwo*gC+9R9{Wa#5@M&a%|ud&QS{3SN+#>Yh-F)8w!DBK?*NnIR&wTg z`hywo2#1a-Y!lkeQXwcd<|p|Iw0wd`^rZ%e6wp@yqJk75^6rc-LtBl*uON!b-%QA* z#>^7utD3q)n8H15b=)FVoJo&7rsyL};B%qKf$)<fFgs1egr0IIvVQRfOa+t$^eoCo zrT6BNm&$+b_BqeRRm>iqruBcgI;ZH&!X*vIw%xI9+qP}n`eWO+ZQHhOCmlQ8(`(M$ zoVnfC-`cC{#Z#vO$DY`{h*`^r5WMQ$FG^dSXvm4AscUXUSdZo&RZnr{;p)(|tz3&Z z&bxcoWQPVZWeZUE)gl=&V<D|J4n7)2iW-Kjy1psa0dBcn<WTEr2qgjLPxAo4_pI=X z0ryKcDJR8}8TlB4J4B%=@K23v5ug0_rFIDhOXb*4%eEZ@(k=^MiWCf`I+spCAqqsO zq<xsggN$1Ymd8;NO1Ct{ZthT#d(>UfJUY=xWoXVvEIw(}#k>Z4g?c%rogX)Azj85* zHgBP-^HKW(O(eAH_3yt1Rb=I)<6Wh?e;sOdqq4Yel~;JBdIO|nhHZ5w@{07SM>T2t zmdJvV)9>bRXaE5*L_#wes7ac)HLUOAwl0#R-X*|9F*4+G@qz&S6I~vN0Vx*MZ5U$^ z;?x?0q3}yBBsI}lFn%gj5NkJfH{f01q~qbs1i9iLr8)f(53_{HDfc{1u6SR2n+jyb zmUzQ&#TPJ)-4?rB!XK77)dS}_myq6T`6#7ZcTRj^7eIG;L|e<TX%YU?(vt@w>PyJA z8u`k!W1strE$H?!Q-)YRS=^8&jgZUOfhPe59F#AdN&XEAEL}i{^iFdYmIjIe1f^4k zFjbb8m2G-k9!(DO^o@EOd=UG_YT@&TzFz26J8|7Ew1kfa!Zdxs3h$}OE){xIPE;_t z=9@Y#D!@bg%dK8L35}*#>q;~?nxZzyX0283q%k`ai0lizWQX$X#ay{!lSrUxIEgOk z3lg!xKKc!dpn>5`eSGVy3Po!*-QJ9fL@+{lC@S+bZ9(cwk<veGXurJhX4u%$hZef- zo6OZ4PUaUBsZ5kfxZKcT4HpZwd9zt|p$hOt7ywE{v8kw5tPC##s#^6e!_?`@<^xZ! zXG&2lyoLp-zvU`e^3q_Y6TLWt*op2M2LGLj(fdR_3To|s7O%2Ez3)b_SG?6AF5n`x z5h?`g&UJ*G)UvuZ`J)memi`~^>DKxm2n6f^g}zKS145jLY_v`F$>&a5uWHw|ChR?E z7a%~>lwr0$649=VT50Px*;`$8S!hoaBB!$aD71H`S&^T$M0fb^vBr8?R1)v})>=|E zu7s;s0Xua7(u6c6>)~5cc5rwg$_pale}kTC3*3cl7-Z^`SWkLFPm2lOZ8C1~cCQO= z)XTWtd0WMF+ch7u5=V9W2y^oR>6Es+46u9O!qWsV#l|1+wYCXuROmgj8Y^qiWD-X= z{^H6}w6s?0_HyWVaL7bB_)#6OuS?Imb5}{Pbk#mPC6R&HO6ED~#Q)0MQnK(o=@h_6 z@EVV0U-ltGM*2J*;sU-Rb&6LDpIM<pF!7izP=*~!zw4@siSvp~7p}g*9*HCk008nw z|4=(|(DrsPUYQ-mZ_~7Br{<6=A|)*0vtbN3afj61j+h*&5OM^UunNDT5YL8Ar4R-V z4055#d|{b0*};3K$lHpApE6$)q^)=C<Q5nz`AyqduJ6D7F)H-qeYcali>}*gVRnBh zMIEiY77K|;pAsL-{fd-D1>jkf10uQ(?mX+I48(E<D`n@mmWtqcjrf!tmxlFIveTBI z8){}GRMJ%KBB#EsPTC;s+Dw}y=X4{VGOx7hPfyF1VV$n<s*M++8+DDP>D3M#*?D!u zE-;d3m{ncH#yta6Te*XvU(2%@@|KFtK0)ng>4Q1!3@WMFe!EljWL+;F1M&pp?HQ>! zcSrnX-@4j9323v7ncAd*d8jN^^9tty%%~F?#udOha#~0Um(MZmN4%0w6ne?uhRp<- zF^Lsh(jvCB`A+WOm#VDE_Q@3Gj}XyE`qR=J7!owHX?E6>e`f0n@5g<iyS`QyeW{mp zG;-0d*+j(jO-_2wfjM@%0g)@-k=irorf|@HU99Ap-MpLbWpW2zTE<;8oTw3>SaJc* zI=*LuI($kWWWe<)P4C+R)~Mt>g=yP4k-TN|i{)$Qov5-zdmu8%%NRa;3Bpef&JisB zwBxU4NR5`>H_m%Gmw(?;zgWI%VkX6Ul#1+3#q?SdD@s`YBFf0v1B{_<C!*gB>s>j- z!7C@C{T7Cn?f{wr)c0D<yli78vePHph77p{73-07lQ5Ft+z{>Llwy3Zs%z@wDC!l# zO*-j!i?S*YsB~>U<mn;2`yS)YxV%}rXgwcVXu~a>l@Kg?wUH65>o%;m9>&{|{`oK9 zrhGN!pZMYxd3qNm02UXTxyWNeSI@&bm4xZ`kt;Hd68ESV6~tt`ouDn4T4UFlt?MY} zT*vIqQiw5$=%q^BwKW9X-<l8Hl)&lwY(?iq+tv>irFT`9M{%?S21&^HF!f1VRgBB` zoQDURgA3m^V$|Lcp&6Fmc#-tFp<~V5W-MT=T!>?uD56@t0JlBaP*t8$ke}>@(!$*g zzLVc#<Vxl{5h@_XZGJ`B5BG)Ku2<NZ#n}wpf#O+^W@-hvvyisyFTOpGM1i_joCuF) zRiJeBymDoP47^O(YNnMugBGf$-9fRlgTEAh^715r&sYTrglx_0_^znlcdPYN2|pz+ znX;w6Gn@6_0BBhG3Zr!Il7*Tc2#zp1V6Ng$yhg0P(Y#v@KclHOkX=;O-T1sm?4q*! zp1MO<Q5@5OqAm}28YfrmJAKc)nG%725DC;ziru88)#Z8|GLVLxr!wTM%gjRfCfjgD zu{)cjgWisMm=*krX=K(AG4NIUaGY%!_U~htBzl^<0SmWj#VOGN#pj|A`!CORG#aXx z;IgS&<Mg+Qc`Zgno_Dx^X|~^=3<Z6L44v${8zvKs1VlRDR~EdK7(b2@a*I3y&nVNL zd;1t#BJcO;M_BSqRJkPTaOTvI+Olw9lvStqXt*m|1!lG$#xUV`x4h!LM0koqaNnrs z<9u0w0ZPMhN4aib#azWw%P~Ikp3J-gWVGevm@;E%RX|x+CZ+Y`$4~WfGh1#k4#oV3 z*}Je*8#Sq$XUAFie|&ppJB>}dRsJ;JYx=ULcjfS7>j_21r;1iBoalJ59=(L6u#yDN zWaA5@M(qw{P4@o^M886mx{(q+pbBkqAgB3B0IX9i97k?sOwOdL0FQQlX8GKhIlzH8 z@1z(Q$%Pq+0ZgYu*vBL^=Ik4P*L_%!Hw^#Txf*cW3za0Xw_-UEisT!ex119&));X{ ze!LO?nu7K1;$faPFUSZ2|51_<CzD7!{ISRw+*FlI3r+viW%5~XN}A5weq=P7UgxH& z0g!?ooh#@lFRWBAkldr*iN?cs7mim|2Q=Wkz{KRy)YP4vo>GhQ4>6(D_IZyfZnuSw zgdgG+t)YyPv-MJi6W-tq3a3wHxAB6;CZ#c$AQH{a5v#@@)SMFh3nnd$Ly2UUOFCG_ zlW4!7`sRlkS$;6j?jv};vb%1DRQCK$;K;CU#IF;7cXFM9V(C}vV;CwvOoRVgF@a3Y zu$TM;``>a}S0chyE&>pcF311MY3aLdzaRmvxOy%-Z4Y|=AZBGI`qInJM-*}lDiY3i zWO22Lr!AMW@Ny51-0HkX(g8_zncr`BAcXvq2gGJ&Z%Ei9cgBG~`h+j;<J>~;dB19T z+Q^KT7oFAGIZD)79PTV>n4LfJ)Y`E-la_H@`-^>ny051G-F02PMfYWULdboJ$Myp3 z-my4qv&(tyF2wZIb1DAmKxMO;hKN{(3^bG^CQ+LlO)N@56t%CQq+WAgyI^zX!vT_C zWyJmCB(;rxyW;%1Zw<`mKfY00O2)m$+2UA1vF;`ktv62aI{dwVI1TQ<fb{py!$+vw z=o6CdyVAcx2YzwIqvhhH33SEhy#xy|IWgaY>ZZp2>$hdQ{l<@is%-}UO^ybB>21KP zRNQk)fD4Or0N@uszM9-57Zv?wSFvw#Nm`Xab214?KdF?yjn#0z@_-iyJVox1qy-qi z+jE(N^g(NA>`p5DJn*$-QT;_0n%M4I5v8(xwwt)42L<UMKG~*V#m2vjt7vfmcQ;`} zmC}sF^Zi7`n$jr5Z=yb4Jmz%O??@^#pltu=MD+%s0I6F!3->z65Z5%^H4U=eCU^hU z7guwSG4Sn4z0nM@N3L?oEkZXx+~LmsfVzY<XvnX=8nMr$o(MZ<^F^{qZQC26Q!&uj z3z36*{do0CFQUzyAaBTg+)iA;sSsCL9ZENbNvfpZafz+eChTj^eywz%JHu&b)khuG zTSzUip@RK^jtsX+L??Ie`YwDs+?G{RoL!og1rrajhNzz6U=O;Bv-rB%K2#jbCrK0d zcynNXr<VOaVdVq<9C5G<&Np-h2&S2ilE^QxW!4TKD^emw=l#`3(Ewxsy?PC%yOZ7O zC7VfX`+c_hU6n1Vk`UwsosJT~0RY)ul12<uxUj@4h*|KD^)&f`qX0#rj=kBee_L7V z8VXxrLTC^Z<V#dTVo;Jn6<1=609%*+IA(!JH;sHdlA>~n#!DdZylr!zP{2~OCmaE6 zSyV{3e$a9O9NFJQLEHssI%Rtg9B|5ENBhpcSBq>7;a>sjqvE=NExcx{6<omO1du_T zG9XM97FTzHwg^Y^(nkR!@gJw5dx~?C81&t6FH|uYOkl`fWF_S-uRgmD+bq@jOl1N2 zM?B^t$bm06MwT2}p4Pr190aVC*=odk3_VgFhS=yvAqV2LnM(tZwg~*}QMOoL;?{W^ zd5xG4KBI^lHEGk14g2A6-Ab7p!3)l~$sOEW&pr<BK_2F#;k5=5H`y>r#t6lU+@hb| z*k5H4n%wDBXiL*5z`zlbl`)$O6c`yP4{id?t{mYL>YFO*M$>RA{ao1;lt>g&OL-zo zBm=C_Nuwzvd}08QtfK<kg0$fqP_iMqn;s{eBvOXP+b)5xut1Ud5*;wS9%y6XIKnGC zU^Ed=XZgBezNSfv38C4f-I?*a@)C)i>KTi)qPVa`;6AKI>u=UijRS}S#S&TZVgiBT zE7ir~J~0z>0`wghF|J3J%DF|BB)qakhSC@u$IVq9Uq^sG{Xr}4=Yk;U=7Z4PP75a! z<cKCz*HhdCL=%!UW@xnbwCI$E%={>c%e<*;{JtM)!k*CavrYarR_2-VFdk!<lg@Jz z8GP8u%B(Z_LDSv3z?aLCX4|PL-npE))4vdE1hyJCvBl%0+ETOR@05JkXoU1R_LP*U zl2bCiOrd}d@j)w)rXZXKZtBmvmzSZi^hNWTslH*Dvso7u&KzT3ZUU$(O-ar;pNE4| z;yAwymy}|@u1htE9ZKrATA2x_n4~u3`$5Nud?dNt)}mPK*8~`C{1+M6QAJt~|6NB4 zD*lA+PUaRjtpZY(aBi%h5*U?n7WB0QaG?isctJp<0HLa!mQU2g6*W%=Ey4X~^60H? zRn!S*HLkmXs^7R)I`ts<MkzCJt5c!*C2&$Vfo?pCLt|hQiz7_Kq>v5y7wYaG!Cf1f zy$4pmiVOJ!jz>gGiHr#iO^(c=@*3Q{M4t&enfvXg6%!skt@p{-ymM-KGvua%&<IE* zLuvrw{*}6+2fUn8XPLQxB{x)`JsImt<TlPTXFQUeR{Eh)C7O@eZrQw<p4~w{kD?f5 z`^nbuT49skBweQ)t7AuLQ%sy)VW2Gz(8AlOR&J<Q>QEwnMy2WfdMX<tO;`H4c*`zg zV!=Z(d8V^yW8O@0#Mx9SUsFD*A9jWGNGgDDbUkBj{?{7^I>yM<G2SbC@iQYiM5VxB zvIofYu_^j;WP~mS@-+>}6vBrT-K@(lhoLxkt)VniHp-)G6dm=(6e%C0O{j9-N!=Nn zXWIy9I|#0I=lB<;LS9__7$_TR@CKpC;_W#j)3DFZW$hwqwg^J=f?N^k-gYpDeh%Q4 zmx4f?t7ZQ|9}@AACmWwJs|&x{1!*qUaM|#jk=y(+(KqI(5+Ml^v#~UQ;;p>CmVskQ zN<J5HG<om+=DyBO>qIS2T)IufF@r${(ih>F@K?)%p2nW-H0n*4nx&q7bEt8!+CICa zKvf-%c&^u}PixjZg;?A06RCulp#xwrTx1s?DiK^ikV_5Y>^S<jjJ(`ggYGAkM?o{j z9wdHZpF4DSyUnzv%}{KP`>((h8iJ@Xc;SeDwp*kJdX>t*6q67W$XR6NpW>Yqrb;J( zk)pR_T~~JA)wdM8)GWI0fj`NL;sDrsfdbPEn!7e3MoDB>l59?@vWG}!Fbg1hMdcVn z(pM$}h2Ku5s?>PVL`T_CVH@ROMwbnS>u(1^F4cuVk>oM?f|8+#5O!#Th}4WIMUN`c z2n2hour1g;TgVTOEhTrG2%DV{Zz(cR_^0~W{vUAcvoB^6k0qIZt~q@vCZ5`KG229@ z)Y+~Muf?e&5AjAW_LqTMWiCKFL5p&&YA$%$h0&tqcS)FfkllBj19HE=a`|C1>DS3I zoEw2LX13?0*l&sT%-(Hh#rMX!(NY%*j2?uqV)&SGw#o;O3WQ%~d2!0s3QinHIlV5a zF(NTP+70pbiDi?B`Rtp{62QUqd`PoFozw4FMU{QNV^02!n7C_a!~B4kU<AIHV<F<w zN6IIRa}x&l!27apoO6^5cy>(U(C{K>19!R#cEt1YVcWRBlKGR0YpkS=JEV`|3Ic=! z;h2&yS_PXRS=hA!AXF9|hIsxaA)WlOlArMcenXc~Y)SvP$IkRnc?nm>UbAR2?;xfG z^(=6GmBsh$oEZb*FR1|baOY-C{LZWPbx4>RiIf)Pu@|2zr$C}kSqf3|UbuWCAMhjM z*^+-zaJP0iGP_xh2x?e>@6ad{#V8&BuQtjbl5$n_e|bwz&e^~7ZL!C}_xeh6`18XO zW?{$XACbOP9J+tDCK_AZ1i=QLN-?dK(wn>$h?bFxrUbmEf?)w5><)%mJ_znrfI@%C z4khOb%Y@$+(i3RE#Vx+j6W3ke@j{cEJ{1h6A+#o$gxwSTCN-E|ycKq`i7Cueh57l1 z#z{*YvOh8Q&k~}IToU8tPD0TOB-@!+HNUNl&T-pf-S9xD<dEh%4V@5u#yw-5_EWA= zPcAVvj$E1&bOHdh6CXKp8roaVuGWPLZF3oB)>cNM8n5NP#WDDKy*TM3BwVRGTfgtD za$LCYB_t%+(thkZOT~oFT$0d6+iJFpB#(ggC1f`4qwIDWD(szWidY*M2<=#ey0$c8 zS$+$o@m13>^~CpHd59!c=lP_``I!&|^^FCxVEZFp15E(fo1fm%ZZCfB&y)jirqZ%B z8ZbE>$-DQI`)~M`eD|Xs2YHoJNi4K0AY%N>tyMg}x(-)*v=dOX_H>h*aNch=S)PmF zO}asR+Aj4rpD!rpLz7OAtf_X3@Q;b;Rrh>bb+gu^Q3NYqSK;km0-(S&`U+AUwo3S? zUK@0$I7I<yHihbt{7xlaO5zu0zTI(qt2O5^1Oqx1SSsN`LyJ~8d(f13J+PGJfOuLe zWw&c)<G?pIJN3`dIm-`D4R`IrX$~$DMx=mSbuymJ4sJw;hJEdpNAzF$+Z=q_HNu!E z%HT_;vsh@elWv=p0)OSqF=!bys*6nCtR7J;`Ue4jeX}ivMLem+<p-Q!VXxJEDIF?3 zUPRv^S`w-p!!v0<2~#05JVK-9<$9g7KAWa~<sDDHBk;@i-ih@Dl7MsvYOZo&a(BA$ zFO@Bw^pIVn!22mN5DC)hugLsP#N!|8vDmd^c0u@3F|b=O$J|CiQ%{kZBsb{MJnQTZ z`@R7j=mnfb^d4qL*VUi+<;TC;1o6q;dqDe9wi|+b9=#9X34E|7?d!IcM1HoU{A@9G zMYDR*;3o*uT)zTvUd#BJ_0dKt@lA1(9&7_@+0A@d(mu-DEf5eV75a6%hB@+k56=|{ z?yu+f?!%)Eb`CGYJ?`#z;|cCBZT>NR2Xz1!H{-u{54V3a>>Qq+|K2?e2Yl$fpF_q! zW=ecq{UW$u<%wUJ{}rZ%K3}SktkB)MoqOHSqDqZTU3#WT!Hnk;*w?5jWXhfRAoZoH zSOV8-m09@~^xk%{zHgf&#-J8_L9ig>CQ0e%<;$DBa=M{}mj;3&-T@o>ZLze#&Sn6x zkm=_hR)cfj)qXxe_3EDU?Q!L-9iL9_!sn|W_yzHi!;x~gbo{-_`ZQD*F$3rP9eg_A zB(6^|KVdLAeW83c7qwf$EC@%A+>xFcWu6%Knv7k5Eq#`KZ1PB))Ln*9Zks(fv3|1c z5U|>xkRCt5^l+F=LNvV;<I9nR??nLE{zk)PKwO4EDFizGPP^k;QHwr4P5C7-6`>ta zMd1K3XaEAA2PW-{>qfoyyv;7h-`H18$#u))D74BSNqc&jBP0iIB+g&piBdFf7$Kng z%zBzs4reVzZ=MOTWzqPXI~)XOG;Q*iB;uFt@hw!VeNQUL_lO0P`<T`AE?K{%cTWCE z{aQbnQ&bW~qr{>+QiASw+PkIsM<aD<5-x2k0#bHpIf!tBJ@Y!BMP}G}YEO~uDO|?& zU!eb9Zrd@=ajgF1X-e*o61e~KH0Np4k-%^<(;eG?!2nvdeO$IXkpJ%IgN$d-C~-uY za?P!lQ}G;=%O9~vvb5Fp#?6r|laex>i2zFpoRR<B?CJr54TRI@TAAsP2aXzJZv5OD zPm*q<7a3bMZjyeS8PY|?j2ewrlOEG1=6>qGQY-I%(9ayFL^Jsq*wTBcMrbD84q0cD zw`bj;?f|CZuB^socE1ZFu2UEaDlc0+`=y7Qz9k}N{{2RpqxDkJyfWf8y+*}6vmcp; z8%<ti5bz<B#zhhL@2%0%y|hZAzD&V~>cQqs=vk2?W8qC+%aF7*=>(TGjIxM**kqZk zMv~f1{D{VNp0`awyByk5GtY9ZaGGWMP}PHR)Bq3vkP!?A+W(TsN9{(g>(7^A!NI{$ z8WDQri|V(*^?%~eAmRA)&U4v$+EVpuw!+YptN%&+b?$DX1WDF1zT~!zr!j4SDP{k8 zmG}IICOD29V9+*sLo(q(t(=r@R^KBg8D|W1tK8Gm5OXmEXG>*c1)>9<vxf{U)rD$o z;eQS16pcd?78?u&gox?!q9bM4@9)%RD097aDxZzVoCiD%yw;`c<j|wKy+Yc8`aB>w zyV<;`f3m^3WS2a9D^TJ~R*eulqY82qSj1D2HF?dXv>`1_zDAKG#f|T*Fvb&pogM*S zBV?i~V@)O;^f0N!*l9WrCN!snM-TNlEud0xgd!*C7A(VW#ELAbN7%k`3##<1awA3D zqce>k`vV0cMoTO5nu#VwAm+?+EXj6A|H)0WTy3&SxSH$3v$2C)M;0f}d-0n~YvKEB zALLD+O(Df-pHs#1w+#e^msTj(mC{7&z@;<`w0{btp@G%Z6$)**-O^E8JZ#fIDge~p z3>~urBTJ@}jzHZs`H!7aNt~v}0;Fy!@RGm!RKRYjW<(ZloLHJ_02mL#1_tVNQ}`RW zB2!5fiml0LRz|wf>o`lojP-e+(nTKp&0*vO_XtX-q5$0JwJ>SJ--fLVROEs!{<{-p zUvPal4%SKRL`I-m*(PvpU36lNEdY?gNQ58DCeS6%g5|7Pt4y}1bm#H5ARQ2yGqYez zEk<1z3SnWQVBu&%*q74i={LEoOf;MKQkBpxf3va+AyG3Fbnv!g1c6Y4%pkPGo4ox- zEkP32n_@Q|NO&~%uj?C(HH<cftuV&AAy1%dED{5BGI)XJEz7!qVW1JtVL+c+TS;I5 zxo``eE9(%WOwux^JX(h&ObRsd*k2JON7xZ$LB;je-<?R%vYkF#ro0m5qLSCZ+xw0e z1~wBu>WIWUCQ6b+2_ejQii~tfH#4uvXJ0*ISqecizy!VHeX0RzF36R&<NhRV=T#m& zz+v;>G=ECNI>ytPQ5I3M-~e}@TL>tnMWdT6MO04vNR*cRf3Ql~XxnAKx}s^w^vw=Q z0xbK4WbAcj!|$0UttTYS1UBJD4O)(M5Y~VX&tBE<zeq*Lo!}`LYUYT4!|RY<-ZW@X zFA#7%;+80<NEb=3c&#Ksng`Af$+>Wxj%0d^I9Zb=3YLSmKxZ^h-2l*iH7V-rnnkXh zU5dSSb_~zR9tfJ45e7i%%T7i{1E<+Wb!2zZ1Ts0MHm3s#uj%snnk@SDS>~bq$MY9n z2mKkN4ct{QEl16gL<dR+`KRDLu}pr?#-^Ui|M7pV2k7he^>uY-Uhry=%XgXV;Sr?4 z1F<g~7&Hga;R5%zTL54kZ0!Z~bh+Ms&&eC`{Pc6~*3a+d)6LzaMJq%<MaOHnFCRTV zr;0pXx;|XxT6dKF_BeOg?+x!C-8{Wo{aU8cfqbqnMc<MPeq{>k81bD|r<o9{UY+8I z1XWl!cb;N7t4UP=k>Jo{1yyBbz3WxQCPom3WiJuPnkKi&W&wmy5{mJ%{P1yY0F_Rb zz9JL0!9BODWCJtPFf_WhuJ;z#%Oc_UgB6#xr^3P|widUsaf#o~mHarl#f3u`_$|sv z9?lrowD~4Dp)NtJRSDqu1&49x&19>5EAj%f|CwOkc9&d$nMd%6B+aubLJgl7RKA5F z6>NtIaJDpT)&*!DXSJ3=80DnmH=Y9ubzDk<#R7&uEtfi|wLAp(NyhE6uS6C|OM#}; z?S>r|w<p~WO17YGBo~FU*kQZnQ8G{>2b0In9npi&tar!~yfdc>P+TVpI-Q|w^kB5R z&rn_iq!yOX5Qrm7rorn-S};mnSYfymjt~^j!vqh5w*i~{L|}F~j*~oGeha`cgTU@v z_;3ef2ZouzkoaiW81+)Y!TOZgc$VkQgFr2Ch-=W+3y>^#4ffjDu1;o-5mO04^iv%o zSt%5jibJ9nu6kCUnh#G@tix20GUYBRVq`M|%mssRlFoaNQ>rkUac)qVf+E?bg)oxu zPSKL@i2%}s2)1TT7WP!E=uxtI>%{hs1l5}qwHNwRIk}Lyb5CWqCOO;1-5V3JCP-~d z>)|pC^i@&NEGJ=>5&wA5W!=m3uA1-U#f)0M-0_K^so(5s4*?xttJe>%LQ~o-*?h+V zq&^-~VjhZby!{M!2N#}SE2e6%#1|lzgz)0TSpWtv+(_A5jj-f060K$otha+GkpP}z z4BR+<B)7HEUoXwS3ICwbGC$dc;C8A97E@D?9k2RjtX(as8`p!GO^W@y?}!S6A%owm z<H|ZsSjgw3!kS;u5A-RP6V%on6-Us^r(FL>$UDluJ%+K@aBsX?=xh$Dx}GPYp_3&< z+Xo=Jl(B;@^X3YvWx0cG{^ADdPRM>CaokHnw&X58bw*&M26Q1^#l1sBaz6K7&a5SP zi`X>lK{bd@hdGukB7rh`wC#0Net2#SM)15<LO8@uTd433znJ0WHYqb>(wnF!6tdiW zcQ2u*MdvllT!bTN2(QPn*$7hIxEhHFvkuT&T^+UDJ1covpIC>GObu235vmQg)iRr# zXe2Ns=isvSXt{n(5-Z?hD?`Cbze}XJV1EHimFAu8maP5Nax>scv!A*WlS(-{$Ex|l zm^A-97eX1*9fsAaO~Z!NkF$HG2~l8q=9XvcE$^6oJKHuzk*@ktE@|i9$Z)vuuNzCR z*0;otLOXl(1ea-}6~9sg^Zl!o6940TMz`7-cU2reFD-1A?R~0B>TJ+xa=N9|vuPZ6 zTk3Cx$*?<y$e{$v=a%VWV67KtPEKS85#v@@cy}DHdOOCHHFFY?v1V%=|HZPhj%(kp z8FVR8gOm>uaW}M*Nxi!HKVw#(V+LTW$ytmuTC?OaHfVh@BE#lIvdu`f-n`lRV_xBH zuGZ1jw<5P&^C*}cq8tBqu+uaDQzJaY!A+sfp5~ld`gi?2h={{2rI~;M`_$0U#f0E@ zoAqyUqU&7)*p8pLK9cclKVK`b=oN(%)?(m^0(0Mnr~Z*R{~1Me5Z`mL&NBd5_B{}D zma78S7N$1j@SM>A^`GfuL5{bDJPM|f+vUSf6>w1dPxN0w6x1oIMs3SO5<%3IX<yId z>eaR@F5F5?^Rr!PyYT(ut&D{n>f&3^3EGXHU22<3U2I~-hfPa{Qj^q^o%pH^S8G*_ zbOxtl1@kSA*_ik!T68el?u!6hv+^a;E=2V5=fu^`xPP-3*e?*m{naRN;3st?oh0AZ z$Fmr}d3WL+(?h&nM(R5?VXAAWH5&u7sSkPkkL>7a#Bx~LV1658WvbgBpK_JbnBw#1 zbTXg0ypP#If70JN#caa+VP+`3Me8oU>s%lT{4otM_160*J!M*%9tQxrUG7@%+e)~! zS0CltW@o|C+rTMQx44wh*p`E}CzN~LfI0YvmxOu*RwyLTnU`J~`nyYL9m)&jKc+{q z+N7F1XJFc5b8Tv^*$U;&#R75&hZgJtT)bSWB9;c<S{8Bb7O?Dc15gAM+tf0fi-$zn z_&>f&nNld`+0Ic}_M!l#^TwV$IsV`5toNr6(aHIr65?iDrP{Jwfz$d|;fe+1)&tx< z3IiV$_oH!$@tcbeiv`q7{k3$c_kY~o9v&W-X&9dw*aDUuK3pOK=0_Yp^7Dhaplz}N z9(c3Cr}RXOfrCEHlQS;63)7yhbjCL&9z&w9;ww@wl^Do)C7yt6Z_Fr0nn3T)=b>GM zVWuY-<TKo^se_^eGX1-#nDS5$K6A#)#b^vlFK9WguaEcB#hdpN3!A+9G-CYCOvv$7 z?%JMCUx;DeIB0>LsV>>@-|K0W?rAT6$Ya#qWgJHr$Q{0|4me{**b0Y;fBg;(2;QHk zgA@9fnfE64FF^sAj~+PngO8mRW%m?-%P4vr>UuI{s{^0@6Yi?ILDx-0XJEj<GT6Hd zRL4O7bp{cCf!XrBSz@#vD;ezf<>@r01Zap+4%r8qtixDbe4IYs8}=1Ft;|Q5xMonJ z-x)F(@06M)D@}5g0`IjgI>nn59L0tG14DZKDwwT#0W=_D8e|)R4vmHpR^Qw4P_Oyd z=FNg@7T=R2nI*l$e4+9z*D6bETmn549Y6)>N!~>~Td1CT;IWx!Cz3eIn#l88uee2d z!%cUVVJQ6#h{o@CQCay1_B_nP$}Uf6$T!m<c$r4ty<GmmM~z5V58cxH=gs=l=*M_F zQ06ohn<tft7BTD*X%GoYZYHU4Ji;H)|6bp+MU3^opn-rO2>&;S+W!23g8=g%=l}#5 zZsGrNe5#>wu^|5QbsQ15?Ee4-PRO|T|JnQyI9*Ufp@4uWiPIMmaj^mRX14T>UbosZ z@&Cv^eP0?4SB1(&SW=0}O5k!$+hy^jVqIcNC9t7wmu#q!D5PE8_KSb_4rNXhm+DZ_ z_|zclB@x1(-px5n+}GLI635e`X@;)bE=fDzZ_A$^Kcb(`1$^JGwsU&y$sE9HF`{#e z^p>Iwpe4Rk+4Pw^9ohiyp1V68gB<k$FE@Apv}B9fSbRT#Wqgub+>y_+@1#RV0~%ZL zPoYWNQK{9M>_pB+W0Q&TG<R2>rh`SRYd5^=`y{K&oAX$p5TZ5bXPzEaTHGItW!K<G zO?Z&+e{tRMv`wK&`!Fla`@CxdxrPHC+n&{+0h2R3!-uhEKYKt{rw^0*oy(*7g4~1a zEk})js&k{JE%nx0L7Jf&jy3~}4VlzqN=Io=X2gz)R2zQp9W>c>S+Kuw_ZeYZ$h7`! zLII#(*OLC6qs5-aT(jzYGMOUoy6Ltfp)!%sYp|+na<X1d!%je^X=VnnrT60ROeh}J zI<0Q1yk-8AX9qZOJ}6*J1&MH8(qz2KoJU&`WvJZXgx`#VT@wjTtg_-yFfZS)9kZIp z(sHwH_m<ekSUct*yZ1lWP@c!$R$^p#v|5>xfi+QBS;nVnmAx*jOi;AwS;whZoXvB0 z1x2{3b&P!n@%P$Sf0o1%s_WcfKS+$yTbxY<GMf#Ae+EqRb*?WGc;6-J72^e$bX_3K zL=W3*!}#ODKJCh@Si`nV84Pq*Niy(|bNGx}mTy^aa0721W;vV^U=4YC%=!e>vBIsz zJbx>+vEh}N7$Uhw7m(K}YyOJ#0$!d?cu7lSb7KVG#e0KmRuCo8L^%?jrBu)xPuQPR z#tkf?hX(Y4-xv_r*^elL*wFExeZpi^^*<A4L+X$tcfG|J+@4C=Xf7#ej*v<APf@bz zhtY6(XOsFm9<lv`unw?HT{I0DaVabomQq)l<jB*kJzOD5k~!s+EI#O-Sl?f$YS#=R zwRnUJ;h~bD@1UJt8IDow_9gzRkqlZ^ND9X`F9keFG2LhnZ}9!C0)JNbzE=KAHluPD zPbt%@Q8%QA0+kFenCUin^<(76Z6V>y?2=szayBJkGDaR>6M+*dgx<{+x0|{TzpBiw z`Z#&fovR!!O&AaIEr}QW(p^C-uW_79Ah{gQ<&|=35`iFXt%@BK!|Pd;S&x*IHrS^M zW(gP)wSmWfAKism2o)M0S!h8FCgL6MB(U7MW(~~5OOSJR+16w-1Vi13Ep3>HFu#`7 z#xfikgIaP7bPR-+o1%pyxKEgM4Gje*aGk7lyo*0W$gH@h=fFO;(GyrLGgQN;4jmvk zYaTDV`l~?jE1&nz*SDkd$@PG|>tNRVhB_d%iLeF458PG?kbxuV9v*AUt<vxU*G3Th zGh{1Zeg3eK5H3&I<9Tm5b5ilECW5Dh1m=f_$&gnS?03e5SCb>d@^Biwy?Dvmc&JZg zSZXoM4=&Bgk5&l0Y+0^WhA|4fCM3oy0|DIZoy5(@(RG`R_S$4|JxGgtB@E!!9t{AK zzIR>Kg4Oifdg$uY6Y^b1<Vq<f?TS)kt>w$nQe~b37kQYu$3r4HfO$Q1HX<i5DNxr@ z-8P<zeA?Vpk2$vxR9F1iapS;vL)91a#^xTgM8+ReN**O?hMp+vv8%YY7TO$qk${Fw z@9mP7=HBg-GWtktJdq-bL^kxNW*>mxpy2V7z)*gCN&<XvmKzdCr20E3kfa9}TJp|{ z(GVp(JaVs_FtB_lC`z(I%TSbg#u#*Qc6b;MlDls+{gs!88>1tb-uC?Uh|CExb?<F+ zI)ikBf5;}o5R=M}%DBDoRH()Ei3lDxl{SHklALMm=9`t8`^hL)RwydU<O;yUYfKKK z(qC0QvV%T{o=mP%-k0*UqV!?@XD>e+PuYi{u4$NBTZF;JTjeNAfsbBrR(B6~J`7EJ zH!Iq8gc7mLJP@2523zNY$1RN7a{^H$JdqG?x<j^YwV4mNqTv>}0&+4Zq*LE>Lkl!e zv277gT6ZCs7Z@Ij1P41;ff0~@YC3oeyUkbMcG_Yh`y2G}v_z!n5pW;EQrMe@Up|90 zx<(l4vRk;TJQ>4#+2EgYl@jdbS3$vOw}Kr9eOL&5#nB%1TgVV(cIacHDB>xYm~kqS zelShl6JN_5%&^o~z918#`DvjWS6$6)6fDHpwrrI0P8j(P5+}pIn;WoT<RBYRBzS~X zj8+)x3>cyQCp!;WrS|2%3|aswU)`~a!X~jG+AIiavB4|K^MC{SgyvUq)_h>lwt{Y! zH7Dm;zDjf0rGKBAyGy_KCwEQ;>DdJSoRnHa=xjrgbH@Tf#0vCLPnf`EkXWo@SQRAI z*ls=F0>w?+$`hhTHv_nY*1v?ntr3AlMg-=5_}mKB!_=C2LO@aM^aa!G<|5C|uj2_f zZYwcaoZnrYJ#%siGtwvDnbK?nEqE*tc6l6=U+K}LaMD!r9tX0Q(H>&Rn<&%8lVawt zER(VHzAI>BDJ`B*=-ci0>B>6%abnhEQ{;XkCC7*%4dW16o&cWg)BB-#BIre1&%QVf z5|;#(PQ)7yRG;T35=8*KKgS?je%3$hFc$|R_L>5SZ<(m*ikYa@pgmUWIhtl)MLXOr zB40}PA6Sxmaj^DuW2I5RH2L%%#zQiAbj3^PBwk(j%JU-{w@iuNHJ4A5gHo(=sn~Oz zRa;r+=uph$Sb%lYyH0_w*cTFmxdJb|hdKGZyoW#rL1pV}6rHzghI=zAOZWjY@SG4C z&Keh`w8^N1d8zHi>a03Kz9724hPh|H+vi@#hwu?5Jj%F2#edy6eSW5!f6cpi0OKLa z{j~`)TDBIgX1EMaTBLZnQ0|aab)}y*Gk5*cCSCWT&t&~<>ZwCm1a~t6k1;9nG-Z&g zt$Ka(57Sme{{DaS56}&w(j_4f&_UdPdN_52xUc}5<n6J<{Wp!6LPQ9=C~xv}+sv+s zq$A2kvQ*M^npPtrLM~llSP(cM>-5d7zj=3g8i<SsB1vwY-2<oSoXafB%gejVyHA2` z+UaT}W!bb2O-1~ZE5Efe&z;vyOJ%ak<+!JpyVBU9VQPS<zG>~mdutUi)H+eD)Jk;< zRW1SH(iSh-I~1p7mZofI{VPr0S+h7VuPW-p+q(2ia(gpWUi5z(6RQZqQY??T(4u9} zT;4gVQM0S2tY+jgYtFm^#8lF}Zk?ZO%W!SmY}QxiFTHco&+Drmt-mmsX`x7QGTuc8 zo?ad5^T-tbeBVqO<oCZjNlL{>*Lr&;op}McXG=d{R9{k{3Q%sgT?A)<QH(BbPjR3# z&#u;SOXQi7&(a~hyS1{D`q6;+d9iaSeb+a=Q+yLfduqhh*mdHlJL}*+>xmB8zWwQJ z2Chy@D%;9cBe9puDn+%U!3>iA5v@-iLx7UZv{kI>#*Xa3NyzKXop&S7RUfs~Qda?$ zNbMtC((@XZm6Xzk(TGh~X@69*)|E|onCbGT$uoifrgWBlQBF=f+ciD#1q#{8o^faE zWyty}lrfHRv*gZwBVf9SS?3BQcbY(cC!RDdcun8<W)A;l<ZMGA+{o8!g7EFva=>0N zSeegnuCBq#GRRHSV6NpzZNV$|uQLT0eXdT>OpiGn{+y8Nyx)|K$#{q&&sfMC3#T&K zQc&(y>2Y6UHuX%uPnX#@jlNoJ(oT2E_(PL)O-xU_cU@H))1<<Ddp@Qc=>Oc_Hm^@6 z=M(gMJ>AGXzM4HAoo=7JG-E2{_d>{bkWc6kdd+e(Wb<Z6T{x`<P_86umWlzq>BX8; zw8*BWg;iG|piPLBMNAA^#D@+H;Ka0NMoZCNns!cHWHAT!i>TbBYG6(}X(hTgp}KNr z1@+q%+2=<yhfRq2P2C_sDNN;$RjS1?H@V^rVE(RWS1ziZ3RAX7Agkfm+KLscnpJ#T zdOCx;0{>7X$x4YT%kKx@MI8e2RaS^WoxTzU&DBBi#TJuGMfD8?|Av5Iq!Si5OP9rl z5LnDAQ*J7Q@B}fdwk6G$QFq)Eg?8A+6Viy2Ma&{XK(L{S2PsppkI!0`G*47tGWA$2 z%aP0jIikqXehN&9SKBvI(%gg$iMf>q)7GnS{6-R`Zn%?FBt5bnqO=B3gn_N*3G1@8 zWY;kUvr@UjgfqJ(BUCgLNfDuXjmzqQR1;9OzISlfE7YP1$`G&30uO5PmHF%4u(_qB zl8#9JD?Hwg8P1_(YtMyCdsri_kT8}QLlnVm2^y7tm2rJrx%=0FLyQoDvuzn7vgBkL zMOA{Y6&dB1%-Ti{P{IJDJFB64k($wPYNyem_*Nlu(pK5}(kRiuzx^JqVQ~rt)k?s~ zN0(Gvb4@oGK@-KHW0jHyrfYI!JTp@VoC>0sQ_+r@I3R%_T#`blmsI9if=wO&p#>K0 z)#iCACViW=?NDtk_6}rWx*|3iNz#!e@HZ@>Xf4FRGnEk0gFgUZcP5fA%=<(==T{#! zv~Mr+alx-vIRSYLQ^M}y`M{RNc3@KwD#mjtp!_or(;TMyaNzPv&)kk|dnnvGv_jpd z1+kGj3{w0pT_Jsf`%NG%WR5OLH33yp#8+C-DtQUTPl=vCH>(Oq?9B0}1J5E^iBufM zv07*a28Im6v5J6Z+N+!35vvg>Shy0U)q=cfx#KGECzn_e?bPh2(rWKm44OVHdt&M5 zg{t8cx+yNIWww~^Rqfi&J@Tg-{qsw9ts&m3ng~RzzQppmn$@zgN;ZXgVmlR4RK6{k zh82vV$_QT*B9I139)^F^R>@VZ)N7R^5fk*PXE^igA}PQe$ENNYQGl9vDEYQmv*~+) z@)MI#MVC;p5oSt{Ht0TS!Sfbf;tcUY<yt~$iVK$G5v^kRwRBJ}Jcg<IEW4MrtdM;H z8UDPe!W*<|c1m;zUV?wLd~(KSB2Fr6zifMJ1w&J-AkD9va}dG>0>&^aGuT009VLmC zimF#f@>;-hXo%KwMSeyT=-M?9O@S;LnFPwXHARk;WOfw?<v8t^r(xC_GznqESh~!! z3S-w?A<N7OsJ8%zO3aeFcAs&JmFpT%OcNUlf_ZJ&Dn*)HbDhHPoqur&&ilwEt`#N* zix*0o-xL2tY9MZJ$a@gf-w5&v=YsN<UM;rjA9R3{2Rk~lHe<bPluC3au1^jNi~!Z* zsWI&&OROpF($!HsxShP4H@D67RM6PEl{FNL+Pi|I;%=hK>|)Es-oLFa%-Kau6Q zMPPKJ2;Or2T^#oq-XM%zBSCdz$s6|jC^Oh<q-O2F(X0GG0|EZ_2@(nnkg`R(wCt+1 z4@kiC&-IZ_!gQzXzjp$QWQt3toDtI~qj{ElHOMi^qt}DLN{o~b2dA!jYgL@-YQxHO zi7QK`%KW5M7B+jztNPnjMiPs`VkPk5OydvI8hWRxps`%J5ahp65S&Ithm=MT7)X8| zGbc?gD=-iuR|Eidf^ZDUDIA-To>W0oPYJjRp3~H}6^jfLO%GEHGl7eOs63{@?e`Jg z^t(C=xePQ&{3CR(bkZcWeD)7JluB1(icjIp>N|Ts7s4(XUbEH0Zc@uw&SX9zh;Jwz zNT80Osbv154kQCozk<84tN3U44WOK7miwa;6^?jku>1Fp=X7fqHNM{T=VEu_S`tt- z0ZUitr1FPjx(9waZ7p%?0|?hGTt>PG2FE2cu&LgBnvSWjM|v^oSCI%GgA-aSYAzcB zGTzxijJZXU9&kWf!(-%0TE--doq+?!vM^{B&T#UH*Mto5NgsACOMFw?tZK+hfaiUr zZA;jLjjm>>^>OcSn|VYYu1u2f7j(dL%jTH=xf&P4B$l$t(~*Ub_|nGLDJZvz)s22P z;gm8?x5lrLOevGMt-4YW3m4zteKG_c8mzBl@8e{H7i5wzA>ytvbrI3{iFW_Wx=ze7 zI&7+Vc`0hb=J%CRVR=NT2x<wc{qf?(lP4wDVVzThjtnCpvi@ihFeJQ|lO}+j&B$N` ztYqDwYM?k8wtTF=6em~A&%l@LV|nGM3xjm?=#|2&r(WN`x_97?T*QzQ?FZ<<tL?(t zxF#|PKiGhg7Q(lJL@gMw2AIrkY(XlDR-l3uenvLV)^zGex;-K$x;;1#1L82xy}0CD zss&`f`^S7kT)UQIAUoQ_ApQV4WP8Ts^77n%vS#mNd96&?NPvGn^Uy0Yq3mnVD|$iz zR@#p?6iqCp^PPetnr;>5;NnVzg@zt$SDF$djOO~W0_7T;*3Br~{kj<wP#MUE{DHnf z&HTARJZXuO{4IYFqUa|or@^-Om$iP5k2{``LRd@0%PQGNYeHdIf!G1yp{VXHR~`JK zT2m$OIV1!6RrFP^p`hToh839Et7zsff_mp7Mi~YSsa`9phCm9-o1=<5Y@)iAN&Y@> zcY7}+f`e=o3&itG2qfCNEiskg3z=aQ<fg<uNMX_XEh(YmFRfr3*rQZVZZ0LTCR$FN zqA^l|ls@`$Y}(hyGxh+JHBtoFbL?>VHT(@1#%4<%=@tS}7O3-VmBNuPIK7f>?gX}n zsn-pfvxi%Zu#d*qXtQO0o-rFIteGv7b<G=uR)-mvfZSoBw+)`Q@~>M0Ux?k3fI*Rj zpWwQ8%eM+0mST_E)QEO<dAB0Jd(VYR43ls@bK-~9yk$!WM-o7Se}*!yYO8h>0I2yw zfqb=7V`^P+t}(L_lAH6EuyN|2q%>(`Y{YZAEZqz#=x!8L?Jk89tkH@UmDV!cuNRM; zfgdQ*^+%7uOhJ_O`Nq(NI1**Lv3&7!5HSVrYOZl9a2^@OcmOd4#TOw3&36dK?7Uzh z2qw{IfbUb9${7F*SR5H%b(wCEHd_8RS<caepNs^>Z^!Z&5S^SsK*)g})e4E-D}0?i zdZpPj*=;}1YvhOx?5z)xw$bhzH#CghAFqm@Q&I<}v<F_dzvQ%hB_~gdA`S^M4XUP| zvb%N)1K%e{Zs$OD%nm(mlwN+}UZ;6#F&SXl(Eg%x&jiS1Jy2OLH7@CEqL%A}#xF>h zQ6Ff0EUdoi-+Ci8_WuN~SGj~hD>%=*;7kXa_xGn7hc^OTNyIXB)i3QK4=S0(N6oZm z!G())?|%*d1x($KtDhGTxGM^o9iueXI2A&sk2n6z!m*M<P;2KR;@tE%b_XIC*dy-Q zmYpaCSO5xzCgwV3&K8I&AdvE;_}dc76j7OLA8TsC?wrd+kF$m(1L=9obulPgq9wA; zd#xy$yMnY?Vs5cA{_q#=I^f5VPDa%LlZ;row1{s>r`8s>p;5$dwy0XtxChU33@5Dd zjK07G_;K1^GwOGj&w{vhZzRwx!=SjqT9FM;B><8hNQCiwkzsH@tPM33C(`Fd2&F7v zfnUe7eCOC#`gq_T3@U5~en?qXW;#rU$^F^$^~d*2w{w4G)(V?_<Zzz#90lW#kmF1+ zcoDW^G4?lPW{rgbf+nuH%x|9J5U0rFm`w8N6Vw+?#<=tdOLfQNEPRp5D92;;wq6qK zaRD~=R&O&@RZJGRbxISSD|x~a%^jNc@DDg<8r`hDqb$xhm=Cj=i6)|En?zzjL_fhZ zwhl!nH(Ppagy{Thk}<YX9kWy@x*dXXc<tD29;ZcYN4?XSwL-s#7B}L4jDG7~TEg?` ztXrZc^2RgSZN5yNN8Gd*k=e|cA%|`!C<7>7XraBFC!$07B<QS7x|O)knk+LXNLzGQ zx;BFlaVzsgzao(iew7UxL+og+S$O@)Fzl(6(e=exWV=N?_2uqp{3>ku3w4&HTRRx9 z<csX~qr5xq6(#|(#GBn}2odO?T@X~?x`N|iQkk{ZOe-@*><~)kTlJ5x?5c}ezXY)F z=P5Gr7VLgh6<=8f4R2qTig0^=3rY*drstp1*-4<$d{!a5H?px|={@~<vSMko`ZG=0 z48VMG%P}4rT$t*hOIi@LjpG~Pd<S*LPVv)aRF1oH%VRS|9k+gBBVn05*%h4THXa_M za-V?1Hs14pqT+^P6PKUy*XAWa(*e+A<(3TMpNX(mQ;Z;6XJWF|Fan<MTw)`ye~6FV z46dgn%pFdMbJ@&Vf2z9vkzsAhfQqt#zuZ*mINB@?JT3`SuPsIUSLr`NzuFbe@Te=0 zofOy(9U+3y<$z!tVeOHK{3j9Xe+hWKo~6uDU6#7I6kWzR;y^rP%HBA|H3107=A#g` zLcf}xT-kEV=P;v4Dw~dMMqsQ+bWw;4EyX<Z!lc+(smI`iFynqPl34oT(S;<;9YJN1 zMkC}Z!J?PNY$$0`bOeRyx93>H{ng#a(sWV2Q}nzq{7WSi3<<j-yT_1ji9FNHt*P$@ z{WnLBGe`g*ct1GnI{Ke5Hvm`+jYm$o_ZYZs_AYd$0dE$^k_Q*id)S$kdOSIeZjaCJ z_k8_?Z)n>3t}iumC2Fq#Qb@}G)$jfCJsQt%TQkSR-1p1<-sPMy7GvT{l*$pU_E`RJ z%@W-mj_T-OQ>Oh7rQNk;tO_9alz%H>$on{ja|V)0K%p2B>fy#rdl^tBS4FzC+}qSe z{EO9b&8on{)r9tvC7b&C<Rtzsq#P!&ABb*Lcn|zrRc6&yv#_!R4|p+>-b$se3A-)3 zD`RP5%>Lhz;Axe@7;rgSZ5=4H6r2A6i9mM0St#Ao%9!P4ErU5^YPQnw@S-0fpk$zo zX8cf=+u$F_pDnX|Ude*_;V7MFe-Y9unwT($?Q|{IX$8a~q+p)WGO80Tx-gc`h{Myf zNmE{c)*uU;_|u$RJ##aW9+)5XE_9)a=q<Fg;yst`WpgrO>}Uk+Ob=jJzU@S(dN!(k z6*v$V56Vq>L*xF{{WfHG6^pgyc&P(rZF0>JRx(T~I~asnXuEk05Ac-7f4%S`nnHns zu3nk5yOR+g;_kwnD;*7^PHz9Q9gaM;f>OGNKmjZX_yE*2<&aLQ2#HxQsB48#>heth zh>3Z}C*3*Nqy?NP%}|kR2S6`e)4oR=_N1sekAvcl9e+N+$Ib~D$JPO`MW*+skV?$6 zRc03Y@bMS>@Zk-cok4Ffe+>g=ZgGQJpvby%a)vn1EV3)We6xUm2mYE$YbmF*Ucyl7 zoJPZ^dm@e0JnqY6o8(PDp*3CaP;Du{%)lXOtw?Z{)0E)XyO1HLfivw<VIjj=w)J?> z$JeXy+p#@L9us&cxZ#06;v?PRB5&7cE75I<P+m4DVZ9TAm<4|Ff8C=n8|wf=6ph}O znN}KJuR5-qE#}%$)NlLn)<-sx@$c>q!^;!BF?Q$KdzjNEEpuvH@d2G+)rJl`f{Ra= z!(Aw{cRfvIYc{6}y>*}O?)u!lbFKLerqan;1gd)%nDIGu(JhxBK*t0Zqjt*?5>h-? zmXQvA>t2>scAh~)e|9qfBe#85ClkivEcpqy#3Sv;YPew*s>)LB)E-Q{0!dNg!iY_~ zT;jPylk>eWp@zC8LpmN#S!Wu2(v}=dA31B;PK_*G&Vze?7_DhhRG0B|v1OIO=^;xG zgPS<Do%&YXn`qQE5;5bEL8qHk2Bzo}Up%$h_4mTaCz#aTf1r$_T~JV=K*(aI(PJjF zsfpM^t$#YB80JBV+pgS-4i%3)BT^54Kz@-&SYb3ky^<73^zC6agR~NXYZ^(rHQE-n z8RTx;0mGWo{|FA=T2{^0>M-VSS#{Ynw`OeeYq?vV8LP*E$JFQE7Ej_;o8yeNop!-d zMgTNMX!<t5e|h!+CNa0mm+n0AQ1@(rc8Jhgmu^G`!0>j4qdW@XcT%-!5C{zFjj%yF zwJFL;#_7Y5=5%88)S{?0R%<Tu{TIXJ9$mEtc7z4@I-So^i&}4>EZDsyqyRW&sc&P~ zg*E|t`|gNsio29hC6=AI-$NN;x5^y2f!dXwsx*8@f9v7Eju+9jSJjRCY3*j6=G>Z_ zz{-m2!`Qv{Ev|H}>K>#C$5!jZa9gf+qF1tu%)rhO{P#_8;auJAP%iMS8?9i^rSGqy z5cqOVPMK$3qP`kB-^ku<)GFAT(z)+Gj7UFmWGEO<6@+~nO~9V<R@#4TDBT@GvH=LS zox|HEe{W!wjg-UKBH4vNQjGDBo#lB)ckQKC+~JngU0R^qj(wPa=huD!-`eh2z31ms zXDF9Oo$15_4R{k3=(@F9PlA-TIQZt;Drfyl`UY6%>#uL39fH;g7n<kDHm(^tMim;M z>v(X}UW;^h_ORPl_Jl!eKMsob(3CZrbQdz;f8s7LcOM2QdCXszHC^MRtdLU7s&vt? zD%4h4b&C^ee41^D_0-95Ug=OwH)>tl-oAsYy11(?D>n6Pg9oaX<{}rWZi#n<6gYQm z3Ord}C<`gy_TL|*_TavCHyi-kK=$U~Yg`<4e2S=xT&%0?pWE?HF6!%=+_`)m;#KJp ze?ODozqk38_(5XFKgeq9E=du$5zR~T>QT6%1wxu`o}=^eXvSa;N4{+xIP0(Hkfl0X zsmIY~nHvQ4$xFq8O_c(Qwbl>aU3;JNP~+YmX?njHi*>)%=$T=~E}6?d=%kjEhwSNo zX?bZXZI|c&FSp^c>|>BQba(Ed+j93be;t-~VhvIb=!vP@%8&(IgZliM4w~T=PV5G} zR{X>$06Q5qCA+!G=;3x;1}}8uu?2mrn>mpUIucrM00)WpB-QP(e`ha(8Rou&adc^2 zaOEnVZX2X9R4^EH%AhfZ%Sk%c*4p{kj^!zyka!!3EqFUr5Ffl)iAXTU$q{~?f1NtW z$ye3Qx7W79opWyR@(xzJ84bU8ZKaDhND#4i*0qSf$G6)ADXuZjK(7P9_ff~CH3b!O z;BAP|mn56lr+5pg(OR^Et0D-SdYNc2Jj><^jKF(RAYkc+Au72lKk%rgRmz4FhoT#L z7z(XR^{(8O^27&t@7FZH;Pavqf7C@*)hzyDNQFBdaQWBVIA}B1+XN9pVuP=Y=XUhZ zBr6u>XqCRl3(C6bSpfw0{SR8Qqm?>}lQ6=kV13M!;C9qbOhKhS;yYGtO?KsumSj_y z7h?P7<l4Hy>dpirGTYmMn>{8IpQA|BD>_c^Dh$QlI`RsTX5I})*)Yrpe{u(K<TE|! zU&H|qRQpf%CSjly6znYlbz8u(D!O}($lP|*3#9xChe;5SmJxZU?jO>rJ$?DOmV4F( zU4;O6c6ZVN>R;fq#T?spl-VM^khJhm7lWcfY4!|+^b}Z_>7`tj+5HC(lgs(y{bl}M zHuwYnhu>xPzMd~utKw>%e?9!e{l3kOyYDmVqQpXm__$pR>TDXb)co6%y#OaZdL6RW z!U6go3hvxX5!@uvb6T>6J?_I-_bR#y<K2@<w_>`Qkax4wO8?pS;+(F=^IQoZ9UOKA z73s?+TT?mc7z(r3O&n5c43Cx(pl(`Gw~1;p==)mW4U?0^KU<96e`Qdk*}&fzubXY> zl8=XSYrsY-<s>xH9W5UoNF77O86tK&6vm5aG#W+6oS!9+naJC(0(fIP^`Z;40VdyH zI|AQ`K;Vx*EXp#D9_<6xbR3(P-QW~uLGxfYm<>9Oqg~jBHyZR47@v<LAg5n^4E+XQ zoPJ@VxNxR63S2M~f90r0N8$5PCW3hmo-6TDF-bi@&aSlf10Dxaw$!)cUjHT&zbcBy zp;E#d=?^So;^<HeUXLl|1%JogT{!$vnkRNO^ml1DOZ#|uw4;Igttq#sBVpwC%Au!9 zJq7kCVyaTb(_0eSCv{fZ&L&}i9rDE&KC<AY@NV|sX;}2ne^7_bPVBmO9P7Xh@SXiE zEI(+|eCe6)ASLW8;IL7!QyCwuh>uXhdlc}XYe?W@y*#=MKlXjP-nM)XZ|JPs_BMaD ztv^`Lq+e~|ZETGSPU2ZK71z~#g^a9jAogNH?T4I9ES43!d5k}rA4lCq&(PC*XKMRV zSMsz1;nWbaf68v9htCm_n$Uxn*A{va0l!f(m03e~6Xv@o5c4P}Ew%^`RpX&cb%WUN zogrEc9R!Py!|325d+yo^wxDjZUx=CJ?bxOcl!|}RSySwLdW6uKK(Qh)zrxrwJMe8I zF0{LCB(Ihu=IXXG#aN$Lm%d78@EceMng9pe2S?fle_@LXX@6*uL(Qo#V1e{bKzLAv z+ZAq#2$&GQ4dFN2Im6L%&y{Hr4zFVrGz{M|MLIBX_**P=k35g0jz#=nD1Oh_uq6)| zlg-e0$>u>DMCXHe@d$N?Mz_RkIoqg4=duCQDsb7hy{g-noq!#}W8JYrp`{)^!W?V$ z>;UWOe+bLzBboJ+tfhl2r30;`ohEcA$th(r9enK@R^#gEL0P#H%<{$Ypr518Nfg4M z=gRc3e)LQURV&#N2dd1l{&V&0E3{9?euT0ND9UaO(XIVhi7|QB_3?LtD9>l#7j|02 z|0KydSa5d70}qKi?!xE*Q9K}W^f|?kj<U4de+|{y<=KPu9X`yGq5zMwP<+`XVx~2n zyB^>nhE=}_^%=~Q<DxfTT*yq8lApb2JG)DHb{mIU_rz}_IrziY_0*N-UOheI!IoEj z_#pHYr1-*DBmY}%0lq(#Z#L97k^pn6W5#EOLKA%ow$;B+wFsCI+17EIdf2$TIpr(1 ze-3U_4{nofB^m5(`B)8mjJ9Ot->WBk_ky<3`V@1eopP{-EH<lzbROHI(gDJz35qU| zxkBH_7Q4+4pO~j#cXUs?_pRNdLu)X@AEc;_dJY#^@GWP1KlajXg}&k&yEOkaK&U)w zJfex2VTj%|!$_bJ1+7?xJ3RBxw5AZAe_o8>K+-WzvmWhnn*l!7y~St8sv?p}#q!vY zf8L>X)w8iyiAN2#-D=+&WmVM|9p>L~ta_=eoOY`Nb{{-tjRhwW@$EHNC$6d+GriE+ zz+;_HWna?YzPLwgKHTk3bk2}`<Q(On@EG^SN!*8Acp>leq5=2D7SP599ThrZf9N`v zGgnp#cl`3CQ<8QwcdowbZfO3-?L}^%-KC8F>qWolR%jZ@-5-ImJ5!@5dZj+tu=Td4 zPPe)W{jJ)jbho_H#j{z{J~BrnIc`U_+f3`xwYyjNsjM?R!M<vrKxR1iA3{FvvTG>3 z=d$bnZ2A6NTfT!AGIvNq;D<JUfBenNz(nV1HK)(a;l6P5^;*r*y~oHqd(8FmaeZ`V zt1d{sO()2ZPi1Yd_b&N?lh$_fkXdQf7%E~m@fv-{uEO<oxCZc#YP95%+XVdk20h;~ zV7GyG?|e1dRh_OjXOT&<w=Y6)7YDiv1HDTEy*nC%A4xdjO}5W<lTv5je|72A=LdfY zEPNlc`}*3yo0j)J_4OG033@uiPtc16NHuXHidgHLU&rb2@MjK=`W~34c<^Ij2i(;E ze?kY>U-0^S>e>PK-){=K1xM<Q@&|lG;#0qCfCBWJ+^lc*N|=kG)pi8;K^gWvW%GGv zwYY6QwZ#j!KM@uBh*R$cf2p7T8Oeas4PLLh|HC#1d~U{Gm+XJu5Fd8Maa}GNbv?5G z0ZN>}bhI8_wa9!nJ_>(&N$Fs^dE<u)FV=bO?L^Tx;;IeU;j_N@+!J@$B`Wyn86l$M zq?Z}641S|hPqK7ZR<orq`01}Ry+9{}Hu-Rr-ZbUx;;&L7<S#|mf5Z-q&%=;NlO035 zo>iIJ7w%;M8{s7#K;G1axbeKxd0B0JP}D*4vesu_a9fc+=p*b`=_#O(*E6V$vuIJ4 zG;94%C7`66`$h4g{L|K#w(t3)AN^V8c`1G^t9<@dYpDW1TX*mN13&S>{RgA_5AOSk z4<Ysb!_i$o_4;>1fARaF_^+Xe?+wNMp?EM955a}}?#98f&4AG~tpHtiC#NoT!}yS2 zDht4zGG5y`eN6c}npI%(!{iQRi12$lcz<$KEjQ5C6kn$s`~VSMv$;8^&GiwC)~1Rk zHz6^IX6n+@=+s=6>NnfnQD$20W|UQ0oCkB(5;5tfUu;(Yf7qnWky-Oim8AvV)&K+Q z=TCxtR98bn7h`>Zj6`1ThGJmOQIAf$qT_Sfn{`@U(D%iEsIn%jm*UNurq5qfBEJv) z1O^8t0i2g=1$G$#yF2<rt6T``EW)GG=_>sv)bkaNFa8F&3QxR$6-|QbE>hYFI_A`r z`6$_ql{PJbK{^s0V^a4Ma)B???fm>BO+EU)A)1Bs<b$;jTbf@D44YBz-yIB2{smA= z0|XQR000O8>V9QaawAA@TP^?qV(FLfuNoJZ{J9?pe=cx&?R{%+<VKR<cl`=Z8HZ-| zl&U3r_HYoE-f4Gxyqa~}hP!8tJwYf@RV;~C6<I^FT3yrV1MXMc|F{Jf*spv4<bKJ; zBOj3u)}tRD&z=f)i)3a-z9J(dA|oQp<*IJFq^yrherh+Ze(W}@vbxc4_jyynYkM?r z>SdB&e@_#Y@bs%^BY1DSCZBf8qPwkUoM&1u7R9tH>#EgxXT_h_MUXlc&|a2*DOCAc z-sRIp-nNA;uRo2Fd08xM#-b~ih0cY~vtrTZoLtsA;m7>`{QIx+wiqRUs@nAmKNhp^ zS4ER!Lpb{~?{0O0X;CiJ*JZxaU-6m0)~01Ye?X~k%R7MFc6rCC-EC9kGZ-|T>Fd`; z)s2!LzpbZtqvRDOtE`)q?d2;N$>KVn-o1jaCSAZuj}rJjtu`Zi_^Pb(W^?{Mzdg$r zi~M>~sJFW6iZ|VhyvlEihQB?>Sx}GVwBx65imGVJDZiX|FeC=Xw`Hp`eV4<?zFMzz zf68~oJ+_fwzF*-W<_ms%iIr4SmG%nSpc^R4+rs$t&$(*gpDF+}IvO4wm2<?%@#~^# z;nSq7=5_LAmZV>dlK(b5qs)=<`L@LNFOG^uTZl}nay6d76wK;o%mpUUtfFcqimI|n z@>#NK@|$ITmQ*!hD>UJV=VGk0&dWv7e*(UalAEHNOaVx}Q1dlbZ#wHUejO#>H1&El zO8&TRyK=sHLCXa&0vg35Zl`>FTi)C*;D2b32J?^hlgjk-dbJT5{>ZN{$~UD#=kcO^ zUD(dO*3ef?ebW?eJGstH=^xa$uW}8(g;A<3_?P^u6T6M=;Y)lGt?#fmw)>0qmzF{s z5r61a-rk)*Pcn^Q>43isMoC$9fET)@m<ZVv_M`*(eE|8sDY{oc4fL9Ttorfd;u46+ zqRzX^qobqAIV3Soj192K`Cz0m*DNvsdPF2BnczCT<5isUABB>G!QiP{{Yh6RKwrvw zR!*VjO|o7gxk~i#k0I|76`B?EWC9poc7Kye+7^rX$YeT8Ovj)_9Sp^!oWVykC=7JM z6`gUnR9o<e(9DEGNA;tdLBYj=;3qfPsRJ@O?{3yvUExp@xl4yfZsN3F!ukig3pq|~ z(i#Az!?78Gp&gZGUD1FHljARw?*O*#nQgP|f=SM2uXCV5I@t`m`fl?1eG5BmvVX$V z<64jP;XW@rT^NU8j2~?3EszVKB^~8U9q3}N@F&5$W9DQ7;^?*JH<>N#f)t~Xs!<w= zdX7Cv!=P}`Z`-Cgo~iLm<-~|8Gq+=-q$%c5>^6JVtc#&s5`aWSqt*nWz(B6NfrsX> z{Wgen`eRdc>!zYK2k0BZGN<gwynhvMrW4$f&&;NFfmGoFd55pxObhyWdFd8-oi9Xw zH>(HwS^}24y~-HDbc<DOA^S()f3C|4SIiN14jHjK?pdog;WOS+FZ8B-A?YO0LA~F* z-&JE~MLTUuYVH|uHx11F;HSE|Ls~f=4>(g-cTV@2vLXeCCUcg2-PIE{%YSFdbzLuz zayOb4Q9Gu9p*Bqy3iJ*(Y`_Tv;tx4&^PGtLFmitqNJ#HpfT~5f5+`i|t<VG%a-E)V z9@^>7>>h_h0Q=?`r){8{&zL;v%d0b}{Bxjl?QJpZ&95`4{HrzevNtoOs+_US0O{2D zRLy7E;()})uf47BC+(^L>VM%*5Fun7OU#x>i_+{Z$@L~7R;okB4B4k7H~2W_rTDbD zX(fhpVv@!y8lELjMW!XNP>EvVlfj~>2E$}iuakQiHQaT%@`9=!n@R*SCn+HFD5({u z0Ql!3v7XcBLPL^N$gAK^ZaN2J4%z4VdeOC*qF2PgR;89iN)zDJ^M49cl4`xYhEaiv z+OAl&23}IO33MmbT^(AGatS3V&X5E5DI|mVQcg8ekMv|?6X$gU<Cg2RB%dSWSme`N zJyCV#Gy<nybjL2du;yor0@%pz)-pB;j3E+PcbEv*EKJQMr-nb4FjXQHyKkU{@L-!a z1=`=C$b_2%<Tts?3V(J0LNU7o_zPUk3DohOnFAynEwXBf$^+Hvk#hQlGDx#@M~nJ) zdSdHj);Klm)ae*~#pxix$bTapxdF+bnt51dh>RRFNoe+~!|vN5;ySd+R^!sA-PPo# zL{A;KcM14{p6v#XnURbDoHhcQsh@@IvU8CI_yU@`TrX+TlYg|V)SS1&<htnYi=s-9 zS*HpV7c+FL1!5{_idtjgvUsjiAjfKvZxGK6dt`CN5Zwrbmq>m%5!gK<DX=uFM_qDP z)%P9-+6DU~aXo^#_R#L+X~l~lTZyXxkOladHLWaq^GLQ4SEeM=foOu-feRy_u%tJ@ zE!Hwu7brw=N`E@IFe4yn@#R}2w(`rn!SE8hED1Ks^U1{}vq-WPW0K=%wnqDeKagit z?Eza$2$<2oqae{;YMJ{QW_OoN=Dvp6#R|y8vzu|~zM{nE4s~kLC$o=!F~IX5i)CJ- z3Qv_2S%zXng_x)-vZMA`jrS<JBW3bs<P-T!{T+onN`GdaY@%l6GW{^xLeR4ajR&%! z**E;DMVhI<iqB?TzAw95D{Px08&okW)se<o!CdQ~ULhl1o*Df+l8Bp$XHQtq;!>v2 zGW-Za4v5A=cWG1+Lfg<#E?BX^>roq9JCiJVmfa)ZTM8tjq?o{d^=Kb@q@vrrnjzol z>Ki4}IDd)?M@T<QSXm*^Vo?LiYnXvJ&?f?M0m#Y^@1f&R3Jy;zAzFjNt$1}aPAF-n z`Q{yhDo>s-qcYsFE%BdJT&1B(9bvxohDhVm*{%^l7F-s*-T?b&OD#%LIbp6;jPWpz zA6fxql@lYa9m$aOMrgxeQt&G`>GuE#R&2L14S!^;5X}R8j`m3-knJ0)k*nGk1(r5m zQlX8?FNPIJTGws%sa%0j1%`dSsq$rE!GV~x6&mIi+B!gaq_77x#}pBLYK!9TKrp6= z0E3dl9$>t+Oe$U0!J>ly4Ce%}>-aQ=de@73dZ#sYqDLtfeNO}=m>~wzXSbQqvRXCu zT7Ro~uz`8g<eO2lES7b%d0iIwBRaQ2DLVNqVQNv{RCQBaRQ2(?!Y{L9fI1?HxhZGG zrK!G(bdM^&9tO|=vl@g0i)D6sc<-yA)0Nv{T!p*lCTLXHB}Fj&UNQ9dpSWF=L-wLo z-MGaS?{<TjYU<0SOXJ#}Hn-_5os1mZ=zn&-OaU)aX#9w47{=S*9=XJ>PbH5>cK(j) z>Y`=)^%miz**zBd0hcDIF{|hEw%}140fWOzP9DOOkczHqf7}QZ1JULC2G7@HOC>e{ z4h9Rp*(P_zVzEDIr`#U(GRTg?+9m=fFF`7booA;5DnIa;Np&Qgx<|tolk>}wK7R$q z7s*|&yK+%>n}nf&q^TIC9GQDM$U`apx&}5n*Q_YyfR_(A=VCZ#$>h9`zu3v{SrCwg zU$!!Alk=V$wjC>|S{!!nZ=Q7%9j{mZ`m`P9zUfYkbn8Z{a(yIm-{h+a@+~|J_~eTb zN?TfL8Sruc;lqz?RbdYw9!?g1nSYaoo|6N@A&;8q$+gD=IBUE;vq+s28YtnEL{=0{ zt$K{gxhDivAY~qhbobio2H!5NV2n)8E7aMdDGyL9)MHUu(&^^2QKA%<i{f|z#gqE_ z=VIES%IlgyB+GhMc$$3F6Lt~hJ$Fe#{sj&i6!s4uP6ZxL1s+ZX4mcI~0Dm=opib|l zcF9x25-mBA)ri<m%MB@B<UyzYYtX4bukR~Z__I(ij=u-h`Bv4rV)iWqKDN9b{<EJ_ ze5ha%PwfaP8mtxvkfZ#)GSow%9w&}i%z9N+lDiaK!oXn@K(b)Ln)`t}z0R#{KQ9JN zHvo3Rz78}8e!ZU0K|rc*tbe@D2_Qh$Gx~1$L#)i<2aBeun|51{s<=l{ds~*raeEtR zjhpX*asJz6oY~$~vCS(Gw?7TSTim`LJmB^NZvQoeLWSKQpL$=r)H@{R*pFuLfc6h) z|4GoE@v#s2M?EC}qpC_s_3>9wmEarcI}}`cM>DFH{@^+{b&QkmtAE8t+i<qDBokb{ zSSK!93)U=BqlG~k*?dIjv#z+=sG3H2Qjna@*VXjws;tLY>y-tj7j~$ZL8vBGwHglx z6644PttZ(Iy0xnoA`LxtU>YmYo#vxdJ1bQE3}8nsioC?Dap0QTRFQUfXIur?8IAo` zLsnN8mb^d{-D}d4ynildY{I5TQX;lG{V-}A)*KK@mTgj#_Prx<VhE2DJf3?{v^^-= z9u#f==@e}rkvywy@j-Q$JgDv-RCjx+?yMBX^Cz2)ODZEyA!N!j^E3)pai$+c5-~QJ z;%|IbCR2aKhzSj1Y}<FtYsIAQrB4h@g}Br)S;3De37(rvV}C>8nO{Hs>Y25az@vC& zB*8@azMR2KYFY*4$sn2{fz~c!nZL1eTilPX*MNdd+$M~sj%bG;bm_jM{)sG2#<BL* z%h?z|^~n?%m*R{92wW)BUiR$2Q0^A4PdkZ&Z{K<Fl<~7CO!oAdmV{`VHQV5R+HS#^ zegmVPb5|5q9Dm^y5MOb<E*CT61zXNRlVI1Gu+?;i24+-K5jhj+Dk5eAZJo(8dq8b- zhrwwh3eC7*Z-`0w!EkOYVG#pFO+lVf12H_sP5Bx{DcmNk1FkCr(%M0eH^t@*$=O2z z$BmBZqGYI`o}0Yk-4&|vfCoD%e{{NsCQ98c+nAdsgMZjCU94wH(h=@#a@eQq28uAz zQx@7|O$3GgiMB2is|9&wbgM>eA*&;Nq4GVx&|R|$oui2X?egVnB%7Y~ApQlxFNJ|4 z{tB|fN&czWe2ug%tb{aPP6-pCLjKCRZBFvru)|+EqZO9NpTZs6@FRiYe*gFjIfnbD zc)dMGmVZVzLylWuC*?Qe_g=sl{Klq{)R4p1(#zX=4U0OqVi@I_&?*{k0jUM;5_M_% zrq(_>lvZug0966-&2<T_Z#F75s)3OUz-_oIG*%mt)#a{><*M7@nn4Yp%WrP+*AU>& zydgtH)?k!8-gC#`z0}(-9PAPEYBKqe9As6Qe1DN49^Px-T_Ze;VQQ9Dw32<Nn7n}U z<dKSb@(5<SRDx#IU752@(E2?TRWMQxx%R36Di)S2Kh5f{9ULUMTA&^%YqH155-fWc zhK`UgDPax^v2J=HpN>x=f+-0~sgBv=%4wKHyDdp)v<Cr^)<wN`CxiWQJ39JC8BT*a za(@R?Ah#J+(*Fm;HFAeb=%>emqjvg#W@6SL#KiG=+GBl<q6<u;Or{Yym7N_qGFqY> z|H$Xh1>;Us=E;EA?lJ1%Cd<6JTdz_lyBq$aL=O|K*l{zCXh#pWG<TFdiHlnJK18Ag zc0diq-e?gfeRQmd@YT2>5d#Xcj9F9L*nhNun9$l}JW#V<6v+yBE8x<Omq}AjZ^s63 z43eTGk#2effGeTw`x6v19v_FONJj9GH6Z)yt%VQVTB3_4Tvz@&A?8Tu2$zNIn`F8K zr#p<S7PZe&g?e)nI;5RDo8a~l#$jHcSYpB=g1@37$7B_%8EuxIInLRc8}JM>E`N%7 zCo(b>iX2$tPeei!3s(d~a|tT7`T+XdBNvN~qd;Qc+-$vFR0$qp)3VHX?A#<C0!ZTr zH&F(I%jAH(2T2uzY*kOtUW<b+?Y(Fa_v~Ql4aOg|G5;Y1&s@>MN^vynu5`xGf(^>- zH?;E2SdR2KXL2@dRiT6>DtKR@x_|u=F+)lrQtfl<?ys?>ZS}K#E1RiS3meSqvR&s3 z_ZTb2t-|-oeL2HJVaLG0A>2Pv20X{h8$=S4s8QiCUoRF36?cjF?;g%veg$VP2a$7w z2%)9P?@qSUcFz_goSEJB7~wGQw#o2@Ziih4t?&;g{&u}&cF6W7<sQOj-hVjtFzPz9 z`@zjDaVV3+@+swS5f{`~vbOSQ4A-^Nc=P%o-X@}46#!ihi&g#0{7rho?HJRSq2aA` z1RSgJBgV?z{3T}29B4Mcp_`kgHzRnOwp$E<+H6e-?R4a2@u1PPWJV21zJtZg&0`b- zeBR@6fo|Sldy4jSBC>5en}74p<svv3>5a@BJ)N^org-f3^&($^{J-ZmMmpbui@40` zA$$mH0q+@FqtE>u^iy?c{jz1{DSEWWzVm$3Csj`F{~DA+4tM)kXihA~;P~tq{~KsF z!^%|(#=x=z6t)_hr$bn$Dl%0DG&)uJL;q~52zc|9$_%&FWM(OhB!6T@3OhwSqNu<z zt30PQUo_JKq>7t(EI-LR2fDF8@ORqf3>b4D=I(X&c-&@Hr{ng+*_U68Pv-CbiwwSJ z8!!PTSJczj9GFv)3#N5lMM7*14p!FH>u$C7>~L62vXB&mnWSD^XkVws`O0ZblSl%U zFvMeNBDBHyx+2{zr+@dw55u1nInt=q<-ipQ2rFN$7G#eX>p!j-F;`MHN&W5G9R+Ip zGozDVx5YNd?-5!pKJCJA>Vt%5<X8?v=_o80r48gz_xZOjo4b=3Ge#B+T(9`<QGl#} zC_N6(qE9B8(a&lHa;B;z6VK7DJ=}G*0IL4Fi9912|8bMVe1Bx(+0E3;5<2@i{`o!a z7SU5W9*lIlXh&K%>K)<7H)-DWIk+INzRFraN*llf4z_7K(<gm9j;vo9#eL*7T%UV$ z)8ZOR<Pf>xJNN#`rf-o=?E7oLAIQ3%&&xL?0r1TN<5fAmn_%K3uYftDbQjBzFNlTw zyTG~!|L1?5o`3wuzv`#|`#=B9KK{E&|M&m+--AoH^y$gTiNpo{gcoqw6+wTWP~)Q< z$$aqE7C0N9&fmS|F1&*Yf70$6ocH1a13|%<1$aw3I&0!6QK7fXC~}uk#XyX`d+g#W z3?r)Jev%Y#wbdENw2!u8t$}+`zS*&UU*%iOXmFSOQhz`TVX)D<$dx@}tTBpaIS`$Y zAyI_!#f!6-FV)GZ1C9ejV*s98G(xD7+j`w>HSkt!{{(?ej9k-Ovy{VB12j48J-&@` zMxU``hq2$jFUj)VT6V9R0`G=Mel9z$!j|?e7_9v7_Ghxxh{m{s-a+Wg`~l~-dSWx( zAU8Qa7k^p2d7o07bFkE`7hJptNLn2t8Sc}LQI{ihhrEz;2&=``Z3M-KkIxg+ksTG7 ze1jv|-H;aVv&YlF!vK)dF6`D5ke0y4PgCebn?RsM@ay_4LEF<Ax_#Vs-Ksr%^5mxM zZr9fc=SlbHnfm8?QC~k<<}EBc{?K-_@yZ@jEq}{u-4*0@M0y7pty%ecS<le-CpFy} zj*|a+VhJe{A}FH@+cE|kW)AR4_fXsH5fpcTco*XfM}V79@Xk&?pS?SKtC~n}+fc*< z!qp&vZQ$YzjfUh;gW5d)0DK$XV7BMJVb3TG!}r13FJ!nZU}qgOF9x+p4s%vaVeeX) z>3<a}(zu$*Knb}w4OFU`a1k9iEWGf3MMJ_m=$%UFP|v;ZfH6cdY%l8hch6Ld4@RbG zy{@_^D&j^lz8NQvkfVQsO#LIplY9j{iwfGeuFy4)&7sK#4&9*tyw0nx?8-vBm%fCh zif*E_);nIK+LE^B*waQ!xG1U{fHkWN9)G4O@GQXS=B=wuEZ81)1r#Y+)%VzudQQGv z5!R_KRyl}?(CW}NNcr=rEV6;LLD7tHWP49<_GIfRnu@)sD>kZ@Cxd;h?tSYn(}&E0 z{pGiNGdzqZ&Z3aFJVnTY<&|hqMV|f6Y6kx>a6y=ZHoEnsYf`n|qN~ZJ?1Q(~#((>* z0QPPMqNX$4?>PD0Af|t@D{`hhiUzTh4bR<Z*NP<HRw6DMs>DXUG=bH9^7;6S<eRS^ z#ZT_ZL5-9EZG?6I6O5?x#HK8x<e$o~M#+ovtEA|rAEd=}s`eP>Lkx)fj#y>KGN-a% zbUi%F7t{4Z(TpW9P}l^bjS(7h(0@X4)H_0hgDxXfB_97>qtB49E;w*Wh4;gS;<7WD zPG#?}eA=gPp{L))fc(T!{{*;-e_rsPZ}`tE{__L>`I`UycmDG)@aHlFd3y5s?>tYz zEezpbvBP)VU+ymVmOIOR<*ss1dpar=b8bgLs-Bj3nJEg;IPZkWS(cnKmVcZcg_t`b zwX3jD2o!oYD{p<0=5pz?(fF;Y``!HAHd#vJttZ6AcakuVX)c%WnrgF|rixNwGy5?_ zLc#sYGK`9nPcS6Gy7k8cO1yjW)|7siXocq>gdkO69@vmmH2YGpD?0Ej-;KVd^P(YJ z+&%ZJ+x0T9O#FU!RGp(Xo_|!~ABPQ(0M+@lT6w3&)gf(rD&qekqHM+nF~mWShC3<} zu+}%uoj4lrcTp9$Q>*V(`Z7mMO6@(%;v}Auq|3ZAvQeIZAeGxWGVWu_UR?uuW!%cp zE}I~lIk23RTjo3Wo;pvGIy(Bjxs_X(7MNzAN8JmB(U9;me05tI_kYKh9lEXy@}w>S z+lm?C=5dX>#d_W0M}2428P$At^*{7LUa=dl@1~E}=CZe{84;95&Yy!|($>?Gl(-}W zb=Vd@WFk+N(poJgd>qye<(hCqGim5}bw&_`M7vhn*@|ACsbP4Zd#(@U`?^${E$F^U zr5721!<$<JU}B>^d4HEFYf$ELW#BN$*%`${b`12e(oy~OI{dmV#2R@X?sK7oHZWfU zIhS#m=*9pAg0A{V&MUlonWB}<#k9g-RaReh*6*85m(91z+nGeqr`6_?2m~agGv=`; z?DDY5pgwiV01)uy40w9&GRUyV6_nBHb(tH~QkM<bn#p#ocYnN`>dAZ!FUT&tOfl(A zv1<5v*pE##z-Cx*l(oT{u>ppG!;M>gm#wQ;zkK8B)hgOJ`X0fy_~EpNZei7c5qRmb z+G0F|Uw4&F><tFb@iwpvm!8|vu-lA>GK+k9J<HGFI}}fs`5TahGi3ILeS^lbm8u`_ zg*i)p{FZN`;X1l()=^L$<ut?2Hz_9w#NFnNL85WB=T#~9cC}8wiL88Vx>h9j``8OF zZ^{r}N2Kts?+zcc(x2THm%>^bDSu4Z&5SM~e$hpbWp<xa7(Dm;&P9)1qvcs&-_>c% zd-nX5JX~x`yu&w2aIUVfxmQ=tJl^JX=Vfdz^)R^exZhaVvWkxNizqJ2=<LUS-O*vT z7#=CmGuWEaY(e@E-EaLZGS(W;>UB5HTRVk4>3|JFHaE-AF&RzH5ywOP9)GEZw#kV% z#YEu^%0{Q=WPB3U%%m=MgV1OJ4U@+xQumZxmQ_lrBQpD@hb_k=I~NdJlzbTBu(k%q zc#0{Au$%f=%YztUCepOQI0Zz=B+e3C!6T+Fyj*izz4&7pS{>}_;upuKmtz|m<Jcyg zi0^&_B&aMo*}n~RS)u4BzJHqtLaug#E*^C9$Fvs`x$xpGC4q@^Kp=qpQCr3Jz%#<K z2lt8SZIphI0NsP1?$P-NAgX5&1A>8SAx3EOiF{R)&>h9vxJ^N1!5f=2_OSJ|1VlZ0 zjlR6?QCr)X*eJd!K`GdP{TGuS6V$a8<s!8po+O?jnJTVJ2t_?0LVwZq-MmJsoL10Z zSH0pa((x2SM*0^!xm!c#cEEEKQ3K8!ho{C!|F~Xl0C``OZ_1e4Vnq?uj!D>&p={BE zC<VDXZa1|hSf$3oFb<^&S$SVB7Fcs{$Vv)xsUi!u-K<`Bdq@6MHuacGTRqVpr^2oQ zW3#E(+=8m$AXFGNDu20BnbV;N=^6`|>8&z1)W`<~(KKR|iczK{g#<Rf;a1anod1bN zQFVXuSu7mD59%6rdCj^G#Wgi&FV-Ab!*px^Lb#fKidd*kF)N#5+D&-sW02J>>zqoR z!}&*e0)BP1Y5=`}tS$2ms;;n`+gvPUrA5;mR4L@&2HL7^Qh%+WapMjV2D07;5AJW! zmoF6HJnT?w#&ERTFl2Wa&_Ll5PLL&^Z&r8+7a1T<5aHY?+HTp!9G2hLk3)xmbRyHc z`t-|@PpWnWS@#J`kB7xRq0_glNS*bI6B)*4Yk>FYdgy7JhrrQXk$~}@E-@UKp7`o6 zI_z)=F@xMv<Q1+6Vf`{W!I0x&!cv8<h7A4|s;>K&`du3_PL?D5jmB&w8^97a@;6$Q zj`K|q>512)Mfn<=^ey~x&r!YTs5nYEK<d@^f88V8YJ8zYBBXkbFx!H$`UnooAoJe) zGs9}gymvP<_SXiNd0rbLfAMp{r!6i)G4!4;T0Rb>u%Irr93|uN*p(!-gsV9ay@H5W zVD&48Q~JR&G0e9)toJc`o#Vl(awpW`Ae<=i!qL?&tAkUN9d<oQO(c%twmQ(K1o=iQ z<48}^{@QZO;?It8u8yrtpuHg@?g$pj`P_{hYB*UCN;pD0A7%lf71DVFpS<aD&6}I` z(n0vx=&PH&liQasUmGHSbpdl^(G;lD6P#;`jxQS2j!=uF54nmrBqR%;Km2Wt;;ese zRKQ_qV)57<#su^_%sfz@?q`EAEp&t*`lcJ^m5x5Acv%Kwlj6j1Bo)IahEp+1BjL7Y zN6!QtRCjrxE9WRSu_JXsGi<-bf}Gu57k45mI=rRnZKzTV!^$0h9@*R-6&wD>kLMk_ ztREWjyGQY%_Z=fxD}F5=Y7%!fO%{7qDY&ItcoY?$w$w<J;sqq)9Me&>UM#NgzEu-v zE@^LBHJ~>1F`K)l!`^Q5Rz8ch^ZdEn(x;}C9Uqu~g!bJPn{BN-L<5e(G)n-tIj|hp zMIqF&`?pjoniW@n)Tb;o=gi)BXo>4H$XgIkZL(#0%t6-{_0CI7??0=Kbwl&fuJ+KN zG1sVhD+&W9n^Uj0wx(X~Zj7wUxk_BNQZpH4J0bl{4wCNcSfd@D#k*+Tzs=oVChyx| z_h07zw|{fH8fCl4@xG|uc$s+Ij69T*YtK7oJq@>}B1XP{RQcTRqRDX+mWb;=Q5@Md zCN`n`7rE^0r@FawE<3}YiXrcdyC>sQF;4M*IoOP2ETWuTZ?sc7uq=4-A~`VfC~Obq zsWK&Le9%buVln|iWjeqb!n`6c2ClhK^`dseX`CB}Q(w*$YTlxTLe3pSWO1+BGW5Xe zsY-c@hAi%X5o3X^ao`|h&W2nPgfoZx+|5LX-x`+SVqLJ#jK})@0!Z(2y<{H7(K}uj z-97CMK&D9{#IRCN)d|S6D~do5Mq!NoveS{r&E$6Z9n?y9UMYgf7h+kA5}0`8E|;xK zOH$J<h5&8|UtKG#>+&zfY#45Gwqi6V!3t9cRkpf+c+0Z%H*|?Cdu%p!qLMxH*^D;J zRNnBR?*lQ_Y-<dGQIo8I#{kF%+6~K5&N*O-i<l6}VB;BK3QJWuI65S^C(JzQD0evE z$RrT1FqfdHa*z#wbSV*Mj;70s#L?n!v*dKkK;^U7B%_&;r`MQ%#U6~&tCMBVZfxs< zs@cwe*6A?FV~$PiHfOJ$?%C@2Vo`nFQ~%BtT)T<C#~*783-0Tr?Mb(4+lEBmMBeRr z%JGLTQ{1*EQQ1`2LOW1!qa$Aa!}bKxiyh5S9efKQiMC7sD!_F`p$u|m1jMoT4Fw}j z0vR?(H>HoWCw<_Sw0(atQwn2kOzL-DqiJD(=4D%WApaTH3*Rh~{DjdNs#-cWk_rZf z7({U7pHcGA`;AuhkUH94?IMuPJb#v;gY$BwE})qb3qnQMD_4U=2<{r1(7YeCQEl-C zVQ6Lt(P_oP-9q9JwhDP+6+$YzP_Qq@ZoS5ggv-QF{c+C3EQPwK`Cwi7rqW$(^^6jK zpxWpd)~<>vMuvMt*&YoXkdFU9?>GvamebLRjrDOFg+IwwY)9sO_hJdbm&@n^ucDy~ zKu3wU(M}h2TTJ){QEg4k3I+etbo}VvHLV-vZxZ|7K8?TL>(uerd$%+V&>r_oQ@)*d zOyh5ld#3UC_`r?tm)Y(3Ch%W;*8F>a!-H$XAEt80RPxo;v5EYp=Io%m-XA8iZz6eE z4R@?2cB_VjuOoj?j&%F|<hyPqcUihmbmzE(EFa_Eafx7`_U>_uqM!Qyae?Na<__|Y zA%UEurnypgCXUR7;)q@5LU9WH+WM-d2YExv8)Q8RvIYzYtubhwC!@KNM1@9wh6^0r zPA|(eU)<-LHfgR$Nh3n>O(+#(*p7d$%PMVa^7vu2z-VzztJyo}1cA$;6aZaI2iLru zJNkDp+`*p@oZh_sP4jM`<0j&lp~GJTwoGru+ULvTQJ7`hMZCG`y130>m-V_Kg%6R6 za?wG{t_YV6G{pUh1(gY~nN-t%m=0!m(?K&JU9g+i6MXUpk3QQmK7{hefYzxXYW51> z(;-YJ`PeXN3{(N`DKZ!2=qA!CAaV@;<GMmc>`&aZzTgG;lOu90l~v9-!0aNi79R$I zveOx(n8km93Lrc~=jrrtU2$<VQAOHx{^a|C+fZuJwt0y3CN5#SQXt8HtyhXZT}d?9 zqTAJ~R-$RR;tfsvHHn8GA{aXB(Amy?95wk^AVi-H-ba-1h&%l#c5$^l3{=-*Yq66- zZ5KSn!6~;A)sfUn1+K(PNw1iz`U%ojMZ+F$dh?S5FEAUYNMe5UWF7kGKn@o^w<27d zTW;w#S>m^K>tFA!-TLQ$(z?uj?X`z7_r_woy#sPaG-o=rDdM(c^W4ACm_8d7WNI(0 zG!b2p3sN476!maSrcP+w?U?bCNzyW}*6<=Cb;C?<$TEtqdA_>RYvk%mE%Ynu4sUB$ zS3AR9yNt;BbG?k?+wWE#81*==`0`09$KBZBJ*HvGjG6EJ=o%J(yvHoot8fxYyG%RK zyeSIBYRE}L>;K4Y*1wt|_Ab8m$L!<HhO8)Psqks_a+*m~1iD9__oi?!>9)s6K*X%r zl~o-U?at^(!rR4h6H&rsL%X9epKrDAS*SmLtfNLetv0<T8-PxK;+<Lg<oLlz0<7N$ zd)b@}zA!E2o8~ot4e}5BS*{9?(z$W16UAw6wC*ktd)BxMkj>c(OrJ+aKs}wI;Ub@T zpd_{@#I2IpGY(Hli&kdrg{EVNMD7&<mQJV67x_&;49B62Z=#_<+4{ST^&`;3kvcs$ zCW(1T3Yf>^RVw#5iov8(o8r&wvQY+VY;|t#8CR(Jktv;j2$O{ya^_9lQ9$g1Xm>W2 z=WjBBlRf0mHA0AHQ67~6oz>{qd&FcQI4A6}WAkz@R>mRlL{K&#po5}2LCV~jEbD_c z0daPM)HyR<CfrdN%`{)nZ|*oNBMI4KZwQWkq;YZNfW5O`00c4`kL_|ME<@DSM#7Q) z;EX}W@7+~@aMmldy+%30-fqF)T#22us1_<>xOsEj+LOQcI}y%}sv*SZV5q;0iN&_5 zC`VK?6EaT4C6hxo3SbU{T0=oZ?js`dgrCg>l@|?`3%<WV5Zxkx-(&6+I6u=zZ5A(? z`lv;aG>J)_V5CT2K7eT=wC{1OJDj27Baf5Axt#-l7^uBDANE#P@>g5CWb%aP6#XE` z<F0IZEI$GdZ-zCtdm9sLY8CsTaK&4^ZOvrF_?7Qaw?c_FQX6S{J?C2Ec}sz2w|Le% za~f*H`vdlQMvi+jG|B~88FxD&>~;*v2eVu|2ElSVeERbdIGsJWl#jv?^>ZNGr8lxt zBs?{Lm!IxroepM^_Gd;u7S~YDb)daI0!_22;+q9=W<CW^6x|rYs2CBtugw^v3XYK# zT#YApoJ2lVd?=w5%5Q-=_s1cJuDBH;B6y`E=W)c3)4%>I+9_596S|XSe;>wFmjC~m z+2lIVTHJ;%0&Wvy8SV?>fer0rL${Z3A}EW0NKed%GKtz2J4k6Gc!wPJhK$+eYi4iT zBP;r{ov65deNJc*^67fQ+gAT*zM;QG#F^3-GQQti-P1(=EcvFX*Q@k##226Z^lTY* zIH6Pf+ATaQjlYQ7gP1?4rSJmMe!b~bN2mwO{H|caIqA$Oj_HH#3!CD1ZZD!Gc^3nJ zuHJM7cNKNXr|V;Ax?<w7H1^U@-;sIe4hHO<S7qR4!@5rGIty$jaMc(Gsj2TRzk2Q1 zB*pIr<(MN+Rl`jbspuvrub)5)?UI?0=qQKes-EEKpgJ@3Gr68R`dU^rqY3j8_ouS( z_9|MG4uNW|HXdnp-w>zt#mm||RrTj4C@i6oiw0?Y)0DIHu`>oEydQ{;6Vns)+Zd^E zBbkUnBF^}vV=R|XY8xJZw`j(G?%ZviI{8yqc+jM6ucSYPuPfO)k=p@<w_>^^VKQmT z>8*6H-9n0A0R3p)#m)iZRA3ED*ADg~kI-h9?N)XOJsKC^BJu<EEF2y5FhxtWhCZDM zGwz;9FjJvW9$`-(X#>fF=&CQ7lTXmBhzF{FAH_+zToyAt!dh&9lGKUx=AEdYqsLum zf^&ri1U;eis2x}4*!}&rGd6slr=xM$pLxR9!UxTJ$&J^F9JSHq$!fjefGbt$9otX~ z5pzCRp@T}ZdEWfudYuo{yX@M73FUE%2WfSqV#^qFSe$(v*DL1xuipQ_>Xkz$41Rl2 zu0n*ACQjj|M0b0C1)t57g-L3HGW9piz@wS*pD@`3P|qAOJCYGcBC~_C%@j{c-TsJN zDiOoqt(k(x2h=m%k>LD5y7wZ@k^lKqPcuz^MjyVZ#jh#(t@I}KR5$vw+GyN{NI_~@ zzb+28UU^>N^lN1|ata*=rEI%HH8@Wh!ufMiZg0$=6^pokLgnZPZ7e5MzAPpaGB%q` zFpkb-GB_ja*CxMN=4a?~NG^f-jp7Z;C0dIn4X}3gQhu?<Bjg$|2IdbcSBXF1i%4wN z$Zd1lk87nD<fL{}b@>~e_>$g4vSQRZ^_AsWRIyBzu<QKMqenQ6i@IJ-@P3DsUG$|` zbLmQK9KVcz$>*!fOB2raTt#U>ardUE)JxJ~c5Syo1^`I@=qd@S%CI~X-dP0*P{F17 zjd8JSHo~!{DbTRE<@}J{2Aq~<3W_F@ps5tM4*47pvw85OqqYEJGqYf*?vHS*?{Ae& z=HkTUc-deAEae%jHr;Jq3A14`5M&X!%`B6ocsxgc21y6=x<*s)>%8GVe^G|Iu4phg z#njL7pDzXqklxv)v<`4DY|H3MQ5DFQ!p)F*AbFuk&H(DhSZamX;6!f-(bK_smEhGI zqvWEz%&X1Clk!q(9*DiUubVp=3v2LlJ-tOk@{1*`HbCM_>Q#I3<kF3R(z(F`2S30( zcN^1xX4s<FQ<(Uob&I_nVE7tX-UAg)4aW!VQSp-tWAIKkix!j%i&vX{$2FV|zQOR1 zCFud0&2MzyE(KLU%<EubwR#0lH&eZWRjVkNCVow0Q#RDs9B~}UOh@iY(RI0*NyA)P zkzri8-gs~}4qP;Lr_H!E&YKtMQp}nOJ?R90FNOKG!Sclvw|A$B4TNv)tp^vtU|s5) zN%1CgZ8}Z2$2br^?|}dxis}-&J1r<k;1&>H^nlnDi$#5Z`RcZ;?j!`d0@wC~*N?mr zpeMw;Nfu_|r{>rsI~o7oaA*F{W&SU`12zm^+%Ae@h1WWq1}bCT&&K!%ISEu}z)&PB ze;+gSH+3)So0RCXM&04?=>GvwO9KQH000080P22aRiN#9iVg_?0O22((U2Gum*659 z1eg4|9}j=6S^aM0ND=>ko}%&TbavKpCM&`pBfR1`_Ryib<Fv^NL5RFPp7xBvV_V(! zW``4h@DA`Uh{xecsOk^*hdoJ7B2p%?ySl2n>Q`Sq^|9~xK#p`ctSa6eNj0|R&~=R< zwOVTUSd_FpFtt9^M`o6eUE2*^TbFw2)Yt9aEPj78Fiy7(OUbvj7*g{4eyF>aHY-J( zm0i<uL;Mv!qy)&@UBUNTm!=qa-8XFTXz$d!iLMo0!z_h-OwB(^v`EQ2V9)qFCdS5W z{ma;&KvT2zck1!G`cvI%iX)?9<P-Dn)Z>x0hJ|2zd@=;L>d`C?C#%>kKBVf;-Kl4* z)n|X?`|-F1`CUcI1Ld>?>4I!o)q%(_`mqu03qso(JOpPTob`+jV)euOZ*Sigx8MBf zEy>C2^=h>$8!80(fp>e(g!nb(v3r(evm)>lMUk?BAe6+tCQitf@{GI}Y)7^y!t3&o znYC;sH-5?YLb1S~p&MvJ;;QK=c(&7?O*VhdVZ^|Cz)(wu15@mO!zv1P7qFXLuh$tE zYQX=$?^=d`xl|1F!b2mFrc-B=;IccS+d<D42%m_3*=x)0vEB^_64$NI=nwKW@X@-% zA}1d{prRi>5bzAd%Ur!fcqUx1wj0|?$L`p+ZNIVYbnLuwI#$QFZQHhO+dALg|7f3C zP1dZgTBWD%l6Nk`U*I|XDq67f0c6`EVxFYi&DeNeX@Fm}&^c2p80suaML;VyfL?%I zW8Lg$tXdqQ57J4-Aa&yqdM{tveU+L)4!qw)&$TCKb3iz$3pRs<^8%KjaH#7F0;o!` zmiwTZt4<{NMwc2wmRn|g9eAX8fT;fXCNb*kU&!TzlmTxrTapG-Tb1pu!Sf)>LxtnH zWEiM18%oa@5u&l$_*T}v0AR&F#Hczq7wcW+zVir;3Wi~L9+fdX^s-tRQ4=1TCFC1; zfn(NmkgX^gtP)oR+C35$4B=sbb#ZqRCxj8Q4cbH*@_h7EppX$Lr$zynq+lK;e^7P^ ze<-m`3QAqA@EaHZ!2!9Awk#Rm40>9`hAwx%L4ACJ&c_ECjn>gPDDXQ$2BnQBqNgw} zo3?;)f({}2r=JpOp9NX2D|bfhjPK1<xbrZ;QA5Br@2&Kn27kdM$gyVPI><2q4@-%i zdl0f-dh`g7396-f&lcNLw)`|jiES*lo7ZpnCnjW9@<Pz#K>~WKCRge?3b{lYgD)u; zVynT}*k}k!vyMgx8weE7aI!t^#V1S@Wr=bYMR4sER;53*qGvpjnny6=BI(};an?W@ z3DzwQu5EqLY+<e})&w<~#C2nr7D?15rgfIDGDYYR|KdzG_#v&cUvD6}y=#*Tor=e* zbAwGBO(S2DFUM~eMp!Lsradf|(NbuPtglYFPkk&2<DJRq0fsDxCO|El@#e>}UO1(0 z9LRm_NMFG26m`?xA4PFvz*AuqV?m;<`LQ?yoau&`$MhuX8+wD#LTSW*zD@*5M{X%L z`4A0HzJlPTS6U6HL2Y#K!vmUm$4Ryl{w{qCDA`_s5<v;Dw2{lyj><p3O!KW>{gPTp zFj<S$0wF{82d=DIh1FD#UL1OIpvIqY1TM{yJ46x>Z5)IM#?($&h*8QKSv}SfmiQvq z_R>|QusjVzcdD=<v(*<X9jJsFv88c7v-_imJ#M!*2J#vX)i~IzQ2juBYpaJ7*-u1h z@pjAA#eL%pEvr;LC8(HDG6DMJ;4_2iADcWkRu(2ifZ$-sle^|AE}$JxGFa2D3v%hS zMJz8z<F0sveKEfMmb;Bxtk4YM$j{yAP55_CUH|z^`i*0|Xw~u>qGyOj^nuk4B;h@n zQflw>iUN{`xw3tF@#ShijVm84cb2;d1{LK9@(utl-Ej}HupU77a#GE_SV5Mi0WFA7 z3l{YSM1squQ#h-Hm!Em5(L6B~d8Q>H>v&1{%{)N&s4y$ibQ$kcI5ira=<)@skv5UT zo|DPcm1Qw<z}q(auKRh0CIexvIJ)JZTtXqsnbgx5@`$Sx)m9cJl;$)a7hoQq#UKM< z0OSSr%RNF)4(oTFG7HBn!vhvEm7NtEb)}|&c905*C$z^24~x-CmA_;tmW0SFWyl|V z&1=Al;X(dtoyb6KKB3Dtdv7$7yzo-U{Ds|oGj#v1GoNBurIKfH*(`f$dBE&<c-G@u z#bC@Mj-_v?@xcnC_lo!y|93QZkQeGnBXu+L2hP(LFY^G+Tdb!f5rDMuR<h3jgJCZZ z%&tvtBM9@gfoqr0V-Uo$4o-$0ERg$-LpL$NE6I+^{9To;;=^7dJIj@({a{!-$KQ^w z)0gY4&TlkA`LHh%$foYmbw3j?B>aabuDU$9Qn__+o)_}*l@s=DbElhZ>(jd?%?@Ej zgT~Yr-9v<I;=DC(-3Y2;LNu?7t)oB_C`C+T7a{*A+y*@iOCQtDTy9u;C@q6z#5x8C zfhfc$ZQ4NVpe%+fM+&#O<OsHOUGIfT*Ds;|bp6;A+4XeTTqCt@6KCFN$H(izoY$fv z2a^xn1i}-i?UAJh`lpCt5qFZh@nIg<aBEe~x+bibjY?3Og-H49exG1X8iO$dD23Em z21g7j)+ZEzH|jIc^W9aOXSAgC{v*a3gi(9<8=aMQ^)^TW-fw1d&Iov+2@y(akz$hL zIl~L9ZQK3!uScZF5i?C^7ys!5=}vaOYbh^OU{1I97=AVz#9`)RxQN$ztA$E1_58R+ z#n4QHD8pf9({{~-j~QxoPAtP7NKL#YfsM~TSKJqmmQrvNPq_x=(F5~5J=E%C%82uC z__q2~s?YF>Pz%nv2PUy<Xu^z`Ma->NB+pyFP%rm`hie>4NnGDz@-efGX<Zd9^*cP# z;P}u>nl|TBoQI0+6^|0opI+Ky@Y%B{b}})x23bNRfK;SPp?Xs8$sO?D_99<ez3#Fg zuzom@S)Cm>zeth^WQ>Fx3sSp^Dj$&~r|(eWMY0{#$}lEYP7f~iSb)=QHU+lauhk$x z#`A4T8#(sv$*YPWw<o^oWfH1R2}lHgnj|)2!d*_a%{AWQ76l!%a$)oOr`Y4OT`0D; z${Q!|^|@1hG?fv+?!)KAVA*wWI<sljbA-j8Z&W$bq3#RXP<To}l-5%|NM7;(&!bwV z-SKeX{~w>>A`s63?0?M^{Sdq|#B)D0z+o37HUT6Eh*64uBpyx*eJCCt5G$h?7KKd; zu4cp72pj7697hKWb)1@;-oQ^6Yax|RGKR&+?a=<8;|yqSWQL^8I5TpV-)4ERJO5O0 zR8-8k=mWjRLKw8nKUExDQRtLsZDkqM^=aT>KC1^g>WEevsZLe<HqWP-Ts60x?KW3T ztXeS||Iofos*zY-tM|aJ0-bUe${*_&>^vWzcmdKV(85gQCW?Rit^O9mE&z=Duajoz z_7UV={=Ra*?5vjtKceEh3LsPP=_qQJ;Tpbxme&Vb%m2BNpf1bLn89ht9{O!#jUB2H z$h7&JWrC(iQ$e6Ajd&5e8C3mmLHuFazPJLFvj4w86rr96VOXbTGGHSM%QzgrH7TcP zjm5$nABDqqg4bSSvDG^At-MI7CIAxf`yPT4xq5S6gcW`d*?yUrlCU{sBUekiM;_#p z7*ck$Za5Sk;GNui?gp(UOUand;y~(c7nIW=M`KOgi!vg|Y>ll&#}pR{S-0{_{f|HU z7!(%hY_u+EQ!b8k9ncQJW9`^}ke_&Xh$e!KHW|cHYfpq=wexOT<#5Qi6Z&hIa6*eF ze@(7GGJ<02n4UsAS?*BiWwWdR!mc{eyVe-0y0C%Q4ktdY)*J~Ps5iQz39<V3HYqM* zO6d_1!XG}lrAn*6PYH5JB#yxaBeoj^4(KD@8rpAK>Mshu3k=4VTlZKrs#=4mh-0KU zV18@Pxj<<e%_gXwVK{NzoR}mA8DJv9`4?@Wt>*F42Y(I+MT`{TA59Etzt+Ky;A>s9 z#A0~pDQYu?owYuReJ!SN4*41j+Q6g#AG(qPQmsCsYxvo$72N&hAZzGb=4zlCexNu9 ze<A#1H?C)e0BAKNR|KIIDtLV!X&L!q3~CT)ziM1Z*#Ykq|4rTY*XMfhqvZ<YlCuhw zXfVbNOB#z0DJc7W4}A~|Rl~}b+A*s{RlZsXNkvnr$N8ux^p;#n)Jd5s9<?plj-mBT z9jl;OZw4vBL=dGAaY_R|Y=vJ^&hJsMZ!XZ@7WKBi3`ovwImdG}3-8L7Igrf$HCk60 zeX&#%dvjCl9*eB;5;+p~fjp4nGJ*5BeDI#ESr9tkQH3lQ1C`g2EQi^%>GOKvc<<~a zQEJ}M{PKVlT<|NQxc{|uS8mQZ;$(j>IIJMB=izCPgs3*bh+cXlz%62pB!aC0BX2!g ziQiMQ4QMX;pi$#FahrS(2E{mv$`eO58|6pLTVY1zrevHV?xt_WvG?CyN>lkJS5zpN z(|=dbzD~hcm!X|wW>7dh6nlz(-$C*lEgKvlZXJ%svQ`0ERt3Tv!RS}$8eQoL=tPYx z=^HZMPgawci0I~i_<8O4Chh}<uDrS<O^cCHc)-1tXc$*SD4`Pu%bDB%ihK>5?)N%$ z0`p$;OT3jI2CVg$?qqw#82*HkhnKw4pA716|NET(q~xQFStqee-wVv&lO${I!xxG} zJqb*o_;^`1-I|0XtepSgrN-ks2yf!r+;DbKTU44Y-kuAsAB;=EJNmI0iV!|d72RC6 zLx5iNvOe5lzgghdtcwD0tIwc*{HG0DsWrKFUX0arMiBX>RZm+!8H>-)Kp*$HrEuC- zSB(MpEP8wcwPb*Zm_nvPD=nrU+a5RBu-%v8Yy_zhys~nC%<ix{-Vz#javFQbf48B` zsHsk*YqRM0;V0(&-``F`v#dVuYZag6)ih9&?R`gm`^<n}-tvG?;N=hA|E*1TCjFaI z{)?GKXekDfcqG8sO*Rz29RudzFlQNtBbkud2x0(anHrB!QLktjsr$he`}lg_^Y&J= z$iCz){2O`H6<2eEH-9<iy;FwA=M*RFj+~DcZ5y~VcIzt04x$RqtMngg%*ZCaGOHO* z(n`L1&Xh@8GfsvY&7F%{TZi@Ra5y&Bs*Z(EcKBiy%Qaww;pgg(`rgP(kZ?<TpoN@^ z9KVUzPKM)!!^fUsDx6Nv`-ZIFz>sB~iQ3H)gx{HiyBq|J9n#!O?6bKp)8%mR$;{o0 zah>LqnvF;E4UV*4(gfr#0AuJkOdpkGa(91@gh<ILyV9!6kb$g`B{H0_|D$egy?*Oe z?4pD>u{RLMzA`}e4c<=eh^w<wsNH3@TeqDObL#_)q1QG|w0h5`xj2>5ZY455`;UfB z`6*nQ4KWf&pEv&UUk0NZEl%Z@*5nI>mz$n%xm;h0@QJ;LfnFBd7mUMoGY6;xY@JsK z1W_+|;oM;@IS;*v7h3)N)Z9*$*xu|>8=ET)JAWX<ktHeqOumJUs+v-z60O`GV_6){ zj;%cNfuQ!HFl2YO6zqC3y#0FeAX%NC-Vs2*zjJ(+Sgx^MBa3PW?V+kNk6t7Ri$v5V z%{`8J29SON3!A8Zq@`1wWhXDflBorIV$kQFT0^DNot>T~R!!~$i#0c@AK^5$Yq5T_ z#tD>>7Ow}Sj5fghfl{-3ZniOMS%GSPj4%?^()csQ+tBn&RQ_>w8;T(Up;B(`%?aMh zwj=I<H1-$6PSVwTR3t6L&F;8%AMVn=51`i`Dpc8pl8oI8+!(gY@tLShaJ)h1Rp)Ne zkA+R2_f2JfQ=T+wbF{_kASr=yE!nz~>>fBGU=bZl`K!e^NW@X+cM0U8@??gwc@0D* zJSXFh*fq8hq=R{|-Ky3BRrh-H0UN({E|Yo6o!uU<4x>d)G}Yqc6RMWi6PuBDR{>|0 zcXO(oKqwJX>3<6=U)(MUR*skue{TfkpCX)B-;m<_kBQIibnOfW5ZEQ&NYtWcltF;a z-ZH#ePU254FXaXPbF<x)Dz2tSUZ;In3YxUE`UI}Z*{R5<Y$J5j56!*i#3a^|B}w^$ zhDuou$TRVi=W59~Fc)=<<`l41Q7O%;eQ*zh{!%)NUa{6=cz3;8J8w(NF%8QxtSosN z-PzodjDzCmfi?_{dB#IhkB4D5l@GuznTu&K`F@&dMY&!bw<w;fFWUAcb+B;Jm7r*% zNjJ&(Lc0A$QN=bG`W!wH&Cf{T);UB-jH9wEF8|u{s=OLDX?&{Zk8IlICNCj`V4$UH zqMHx?YxgWNY5RKQFZN2ruOMGh0fGhO6V}Uu`{NBkpYW~jI*8^{h=rYC)D&PHH^H^t zuPSiI1WEsclZY}`#+nSUr77qs*Lc;%&d4=V5=B+UNm-rbKR<p6f4tXLBw?tm9=$!9 z!*^S0IW{Q&FxzNGq83O!XBAjwtA1G5Q{hRz{jC$d*WJM#Wj_5F-W4)Np`J@KiW8O( z`wzGAM?%v!g~pS7yN-R>HH-w<PuhBNs+;B3|8DZs_Rt5+?RtSbMvCnGtNNp8E{uKD zqZlNJ@kQjxB`<LIYqjIq1G;H5tECZQ#MuV-ZB1~}wAqgh{_8TcGT}ijv+w|v=5YmW z2F)D8sb|Y*?D^#W*^x)k&iH=R@glj}UD1MGf+firbK>LJm=BmO6DkPQjmd!$7~Nxe ztN!Bxrm#FJZZ>jh+(!>D?0&i>-EHTNExLgz>%EPSv2}ThW{@-rDSm}AqKNvQ>q~Y` zJJcK2-X+2>4cN%Fe@oqW$99zxV2YAV2haXqJU$;9l5H8ZSGQ%lr6<&|-|XR$<c*-z z1k>tcRC&r0RDmjyzm?=1fAr+1TKwhs1I@L@sqkEIy<_BDmt0RZBEyM1F(mkZgLhPb zA-@X*2na6x|M1ALQffPhU|Qbd@M=MU;)j9fo5eL2Y`8XXu$Wfnx2(Q<@+(4&BiP;` zX&ki{P4ft+el=_8B@FO<mHZI?q;b}yYAo$8GaI=>&u@aDPwBo)>hAS?@Q?&*n_Q;) zv`OwCy|yJsg&_>u3+(ZPJ3?1Iq!nhO9q&J?9OE<LR9d01&g2YWO@{%1`k-SVV1B;5 zzx3fy53a%t?h=x_V%)ciA;!E^m$<<#TCUq|`2PJL`W1e>nbat1xPt(Y#<3@(H!Gh1 z6D723R+?%}9EPcChd?ncISD_5AIWH{sjq(ZKUvzZtN81*Bl2JS{}44>p+5vdz!qG# zNA#}pLd9q<*jP-;nvc^qOhh7pfrjVy8l@ItS~<~*V2Eu|nn}T9$Z3#Ye8=q&`ijRf zBz{c1DA+g|10yGr+j9{q_Qicz*{9Ak*EsB<?5VyiHv5Ac#C_c}6#nA6C^cqS`{B?` zJ8i;X+&J|0J-n4aY8E(cyOjiuUfClYrcCZA)vayC-h4=BL(hdJ4`c5@6-NpAx63OP zZWRT>l$wf=yXga`YBx~%9sTc^8EgB*6_Cg<zMzwDPW$VmXU<ywyh=v#)!)izwuV?F z5I>Mg7}qk?wNK8y<(#7_njeV0oU_(mmZ!tYCS}>TAA<xBIneYD4PZA-GG}rR_gp>{ zjj4@@Cc7zPrv3D+9A!zsbs>6;q4-VJt(vbtyrGfw^sRLv<?!Bvty^4n8q}4ltug~u z2rE{vn5Pat#5t)baNkPWYNnj)Wggru4>Ofy5DP4$E2&IcX0$Af*jCv3XG!S$fIzu< zpGAU}mn??Z#aid9Wb1Y8#cg|7{k_+4e<N!7qrMtkT`Kd<dH|vZdc<Wd?wYl46EEvv z*ThoT#mmLg6EYEn-*+_m)9ZA1Pq2vo106a~i0vE0W!_A@nOFKX?LkGoUy7by4eEM@ zt!vk}A2;nT@c(*zi+2)UC>YZJRC^QphV+aWARxK={}011*hvJJ!jy`K1dOp<pT_T) zh)_{BC0CB7D<bpMqYi--7E|rVhG+$`Oyh0(*mxoEEf7{opiDA_0)!7;uhbaybj*0_ z(UU4yV=8xRs=MN4{kvlR+{`c;@&Qb*m($<^bQUX2lc%pCS5B%*v)(=Rh35F^abcC! z+}%ArOU`e^yy3|6kJqiKf#;1?)_|;LJ4E8Da)%Y!3dc^YKKG{s<dLztmk~)IKlg{d zn7G5e)&ww1XyLIL<@18g!Sqe59c69Fy3Bey#ZEuTs;`G(2v{S=o#=|Wy5vRu<D~)i zY3a~95*%%j&s1REpU^3dOWcA2yG()XxxCG}ndy=2=t&}@b@~|ybfj$fXjHIZf(o_0 z|B2t?)U=8SO^DE@W4~b#YoJ+IRy%3<fS@IlTd0Q5^Jlml+13|uU*pPCI2<jnFO!S> z{mrccWI9Plebg||Kh}SF7Mh+5Ky}~~Vu9+d?$V0qKy0?ZC>IJHRv8N2yf9?qsu;(b z;9=Ck&|@=EdgVk1%0K=={wsxQZlzpV(5x^~ETx0m1aR?i^X&g)BGe%H+RZJ%52>QR z5L+-18JRe66O$NuP~nbcq4W)z1O$FRWBYx^2PniMGw!bBXySAW0(0=YI$HTg>IGR} z$1+S*pRs6o1$aM?AGx^sx?~t)8De5l-+CH&vUS}mzJoe|r1)bUM7f88R|%XaH>l@N zv>mq_50NinSPr$HO?ux`dvgYWAuP9{jfWo|h3e_Vf`<in2iP4V@FmS@6aH?lPCf;N z>4b$u*257S!t0|u!2S0jf~8EgLbXEKF(a`I_26$qE{u3-UA)A$W>Y?bkO|59U!z_a z>~{QD&}1mUS0W*~yqlUP{SnbJ)s%gEl5q}>VLP>RChcQmihOIrrhQdB{=+L@i0E=H zr1nH{(_bbb`Qh{0ViWD->a3-mkn9~;G6x0eYy=e+VD0h~QC@u%xgT#}D1pX->wXXp zFjEg`uILib)46?u4&skWC%em~V9G(^j83<LCd+HUf%j^o`MckNCYFMkV%uE9xPPa3 zvQcO$IDf(}jdX|-<9DKZJL(ff*^0i&b-+l@oWh}ssOsxz@uCR&a(7FRww<HZ+Lg!_ znGM-RZZF@i%6~0$CH-`O&kYh=^}0j;Gjt@2bX<LD!+g>VPl+d;LN|TPKK@H`mcGga zDGvDpBz>+_USmqIwFquUWPis!L^3MZTd0wnv}-?*z<4lv+^1bsV`a%jkpxq?#>5CS z9l4L;vR|CF(+?^Kd1&a=!aU;<kuymS9CjvI2k2?j4Iq1ibuo>?o~&MPDi<mLL$Q(2 zW`bT!gDNjeIR*T~TZ8?(>y^u#k8^DWMHbEh942F?+toDut9Oz=I@#*N?IIdd&KSp7 zzkyc-k+4@0K3<OK@A-w&2-Pdxy4#hjUqm)Vcu#-G{cL&H^82p9oB6}vrGT5gvUYHW zjS;VzQHL$z;xENAAMW!R{vl>UF{SEmx|u(Q0ae670>wQW{M@$2<xltWnBnL95*9E5 z_zfa#Y>5q}o#i|~KiB|<1|>a9hAU-5=r2*d%b6|^6XqKYsQAfLc;-t&vSbUet`%zz zp?OOYHsU4Ra<WZYFNY(OFd$g9(@mP6{7v_J%aITJ)f9;zjVbM*lKS5p&aT-K2zD)X zOniC@2easI2ZwS+kPdT=^<d1e6?7qHpewIM;rbws-)WR?5J6n7$UqG5a_PtnHZLFc zQwy<5-oTiPEUhR-Vc0HV+$bX=o~}%MQv@;+9)`^epm}v~<~smYEy^PlX_JERrhg#X z#|M`&XIL?%MBvPTKj;1e*705Z(F^xVGN{xBS0@xqK6mdov?;!Bx+oW~E$(d@5al)Y zqCJp$`~x2?T199X$^=vpb1PCCp_0p@gUKZ(_D-YR=C&c_uf&JRG}1<xOp=hqTK$NA zgqFYz34JPH$XZ!DychPvrSaPg@=KCwX!y-SdMJ`_0#2rD{xlNnpJ3mis@QrNu^McH z>*F~}QzS;c?g90(+!UHjpFFrDa6%iTL;y~t`W`)f+DQZo3VO_;Y^0Ii#7IJq2ATRN zRixd*(MS~xecHg*;8(U!*k)gk_)almEpy1+Z6(O+Q+k8KRBf>d0zRadF2Y$VY`)ju zK5P`r#U_%GV9MDK2HYDq5x~~9WDvIyn%bw4BB6h>%3)D2m7-hTRBv4%u;mOI^j#|g zI&iriT}te~n~Sey__pWq6pWdxxYtJ6M&?o~brfEJ(be-sunjglCc|CVbyH}~eW6^@ zFsv}P2jl$!3oa~LE9PiSq4G8}jBc|hVG%Njn;}23qRH{axj_f}Ru2PK{V$H+9c^{* z&L@Q&q6M0<ifJrzTaRk#Kztbaq!D}P>^l8=5$(iLhk1!o*f%_8MI$s}&A2iKI8keu znIhi0s@XXPdcvodx;5Xo0=r_iA24wwI8rE@jL+s>@n8x)7(`A4-nMiKh4A5A=lNkb z$4Vb0Grn1H?piYG20Cdz=!1gmcU(5k=Z4YfX}UO`@U*J|LcvfX;NV;K8$~d6Y)rN- zQhW2|r8GEfF{+q)Ed@esjy^k#Z>VG!@gVOQ$H+L9?wtXIiFG^QPz@z}!k2^W;q3=P zLVWfb^!3Y3CweYrRZQgeetOl|budL6@uh>6Y=GtZP@kV{7hVP#wB_vf=Bzq6y%hhz z(SO1t%_%OU`mN$4pq$6|j0@2a7tM&fR?-7$m*`5Pl+LKMbJUm>e+RHKMT8Pyz5#>q zUa+a}0Hg4s*<QC+6Aq2$!^F1Fe!id=?uarMI_GBlwLT0BfBfs(SX6UB_gB9jX$8x_ zj*{v3Vs$u$Bh^t0;=D>OcxwSk7(I3R&y0o8Fx{R$U#9U4;IW9Q8>QfWIUt8&c2x~o zbpU~vhV-eI+2u>N7Uz--zqr;Mjhm{ErDiG<i!=lziPsSSa{?toe>5G!3ihpx!`u%O zq$+YRpSMc#Y$!d>Y5znHJE6Bf?%m_aKRIqdRdE=?DErZRaN?eCg=pZjWNOaCEE`wE z-@couYY&SCXq&0&g6w@qZTzl$k4w@27#N4i?F7GYG&Toyn%=;UKlX>R+&#P*X3Kn; z_`_6PL)L0%X8idGj_`_s-wQ6zoQF_viME1*(PD@OJv>1X-QT-$;cgRQk073enDy1& zMI-Vb<tr1TR6)n*Z@EX$xE#h>>RnWd=N6^*>(Oro;J?-+WM{;6@#KtAlWiX7gWQgT z2MM-DbP??`7<a0z^y?bpaFLUQWSf7=P}TDp9ECVxx|XiG^QB~&&+DVT$<2>&n+Lz$ zwwbs&c_sCCHoR;PV=~vW$RB5p%oi>lDnd>2v<{$DaolNL@QPY!>JBiU@$q|dmI7Ec z?<-snfgE2mj;EFvvhn2eHtr#-f<b+;l9O>Po%mAOfw1_!z^<tQG1>kOLWkct&s2rO z!`<^wFC%sR!*lTI;eo?G{Eh<~7Ll5uptdJ>!y%Q3Xs)E0M_7K@qY|hS7c+Xpr1R9E z44!-9P{jJQG1A6|W;R!UR2x3{eH4P{rCSInfFz0~?1qft?3Z;jIHoN3T<{xPp<Q<; zGK@{aI_!M2_%M<v_LkgP%ef#3|7=@b?PMXTOA?9Z<%SWpD~`pz+J-ucJ(e~#nx;Wq zMxA&><L%*%6*`T+lefWsqs?kZJrpz%4OY@GFOe?C?5z7dk-~AXNR;{($Zlji6v3^f z0F^DhIVjg$<PD5cjM&y=tEmsggHDl^>6E)`d9lkMeXwTs^IEpzsrdSP;Lz-iZdF_f zett<&iMvDIj+epLcJYG!>T_GCyg?o7jy;m~tu5KkhE1(=<9FFndO_}F;HB@s@4uN# z3$qp@UIvwKOUG5qmoH$0uj?p8Zi#yb0#|GM>xChY_9FvVQL=7r0}0YC9m%o7150wd z(L0;0Vw~UXy-g5^?@dNN!`3;&(G=@Vv6Uy$qVz?=jp!;udR6J>Zh(O`pIuE|ocLEx zqvzv!op^+{VI?!q+F>+4eg$}of9kRbkq4^(H0Y*(xKKxl;Zmakt*x#A7pzIbKoZn$ zDyVMEU&G48-pj?<iea5CogX|{VU?@11s388m&t}ks8`JuwxJkZB|<Ui(cbYpTj)fH z-L<QHU&*TEHEN=a^NO7f2!C$fFLj`$qs63gX^vJAk_>D;hJKQ2u<In`^nV|#<6-eN zeSRbk34|~yEf%G)u-sH;GM~Vf0yCJeQ#IYN#4Jg6W*9kZLb=Y@0E4x|ejHCO4Qy#^ z?KW6yr~T51QPTWXJ__vdPr1~MC!sXp>LBad+gIs8{qoHP?HB(wh*mMIfMj8=uF2qW zCXz(mUuo&<b8OpFzop%H$rHY1Mscp*q1(>6l*f|6BL#;ED+lbvwf#<QfuP#3_>opQ z!?_C_-u?9Sa}M+JccC*nS|mkNrYZP;GcLmMPuO6f0&txLIFBweT-Vhe3R!o7Y%~ib zJY-SA>OG>P(_}{5a+6@VqP6{MN9kfrL%Le9SK?R)wG9E58V>0gSZ{i1jZ5>64(RQ1 z=-FQa8#^J#Q?@QSOBn?Fz){?$Q_VTl5bR16jC)m`lH&bl>kaF=51+S{^98?*?5N<f zsqH$Hvq=mxo}%(5JP1yiB%A-Jeytcg1yopVYm`vB#<7wJFOdu8XK=GvnnAaSK+Z^u zqMs_<u1+b_s1BRgGrK3{&j!4&<fM9FTYy0v-YGNibQj0oADQh3sJ`Woba%h$#`GyG z36i*`qpXJfbIGu0fV7)(45IBy3?8>p;Pa-kU01wKJq@|1kBxwr6>(-EnCiT$$G5z} z_GYYg`0!LP6ZN$9829RhY_+rRSv^EgbkZMk^Jx#LO7EqB&%!%)?#lVXA5o1#lXzEi zZjg!un@`;ZIl~?Tg6mf*kHz3lh_)kT!0gw}JncI)aapfP>eTQ{rf^ib8s<S9MG)vN z-wi0T)(x&8my<^$c8QO+BN%|KKm(FmR4!cB*1YS(|508ePpZRVUHY)~<JEQJFM&P= zyul22JCmAV<W>cZZh68uWQ`{3V%FOQe;9%y{6|5pa=wQF5)lFy8%Asy2Ll7`ge{;2 z*nC3AT8vC*ofX{Ihp}r1XSo&D)_HJbzCptwqQ&zYYUQuI)J9afy>%3JNY{MM+G%fV zlUq+%K5nksU#ke1okA+ilA8kyiGJ&e`Z5OwVJ6uD2r-WYg}kvHHGSRIZr<B4q~@t_ zpdHhkcluU<McW(TMpO48k{Mvz^ryK#nq|WL5#`^|qhYt-_d}wl^W0)-AgjjAiKLxg zf_Wpc)koL<+aYfsKTv}$6_5Sy(WSEDshvGey<)q5TAR*6A@<{~RbIX_t?<X7EXCSQ zmAHG!Qsb@#n!6<H=Z1W**^vqvBD?61{1bx5|7od!SE*~`W&Ky&tgu^G{&#ri%|8qz zIb6dpIk#0M(HsGbn$K|!^!R&r+N0QKmPOqenqznNbrBcY;7wcTO(~dtFnCCzJ`tOL zmQ14ETRA2!<%X=*xou?Ih#ZBAt6p20Oa>)Y?_L36Rtm!rQxbELD_gv;FdiW6T`$o! z9g0Xmp^O~@v6^=IP4wTdb^F>}uYkWA<}lWmW0fe6F@Ym!G)O`k6RsfGGFA8+0xWw1 zanG${#Xm_I_V#sWjZCBeY1IOLUT%cvgHS>(->70@!L_N`3_^G0duQhBrz|p3@xz&6 z`b4(GBzG3jV@U_cUNpNMvFDdk35nfxjey<2#CXkvEkioYe<z4u!bF^wpP$@?Ur$nH zKTPR<cLO=>(OF@x>aFPzbO@?X*aJ#ARjA(uOo|6nzcIju7tH3bBWm?v3G+ZYkY}-c zT92|nZ1qgK0FoC<=Xu<4_9(PRU@`{zxO#g7mQhae)pzl2fZxZoQkSn*HLgt&gepov zg7&zal;vnrsX|;I;$WnO(Us1_q%5*<E=gDc`Io^XiY1?g{wt&8vk?+pZ21pjF)KvQ zT3gyTi=O$U6ygmr0c}*NLX4(@Zb;wp{LROIIq<CTYOR-enz^J*tRl{QEoYsX#hwKJ zrAO!6i)6T?Bhb(hlF`(Oihq#gmN{#IL<f!8TS~E|Pn+{`C8Fet!><bqw+gRKTz9GL zpsKPb@&M%>a62|pXP$?ulf@_sVh`$-Y`%Nu`Wt4&3l)3ouECK6_sYjA4taqx?S1pa zQY_MeFskT6nQ%ho^AlE%!>#!!uTZW-x|KZ0kT#{2zZqNZY6>zw9AouUE-^1a#M2=% z9^?&+^aNmaK<X776R89I;fjUuGR_6PdLfc24#ndda!*DkGy}I|mq1fhM2Gt0BGQ@J zE*bR#<S-~qK@gdie>UZqVIU(V{l%kwyn-cf%{vv>P08_u54VB<7;=S|oML=v4(j%7 zu2zt=?>zFag&M@&#(esKnp;<(bYRxqLSwG$qBS~s`KwTp|LmcW-yo+11k>yLfHe+s zcbIJjuJ}sJuUnh=?SR~cvyXCy`iqo>9mG($jZ`ptMZ`=CnVe8SOqpz{9&@#Zk_0kC z>{6lIDF~DDFa`3IED9o#%?MUqx;oubq%qd(Y5mJ}mCu#J_M^C@vHmi!iOATz01k!e zwQLae&|1e*zwegFgOUy%-S=nSZYUk)_b3%E-AY`>ZZ|nWi0RA*{w{(ywsmJ3^35H9 zO)l})$_iybjicSq6J9vb<4=}i8sgN`gpZ7=Mhg&~^($th>(5BwKrI)OWMtg~)Qfqe zS96_gk$vk$?dgzK7jc5oy^c~*0$~q3tpV3_EArYd+Hn~FC+EVZ0LQo5_un!K`*(m@ z9TfCXmoHTXv|l$?CtN*Fc)n5uoAHbijN?OI;}c>*+Fbq*^#AQW7Kj8p$^17e#YFwz zh9l7VkCnZ>nbZGVe%9D>*x*0`z8E+zFv*SUE^QTnBEz&B!mpbNCkP;f3Nvw-p(jxX z6fR&7eZOqQCrFJeyu5J<l9Ap7xp#K#5YTR2_7UooH50$s70_3<)v0<gp54?`B}MN) zVG#OtbQwDUyZ>Y9ydRfP`zW;vrm2zXvjBtcWh@seT6?;>+uGVYZce@Xri3H2-y;pK zL+S~Fj$)sL{Bp$=QD)p$M{dT%)XS(JV0UMnYw*m{b5E-b6h4q|qSE@al<@Lyg1Hx) z4d(KYN7Tj6qxhlBUK;-(B#yNo5BGMtujAFC{$ip?YK%Iv5A%~){Ex&%-HqkUqz(+D zzjr{=vKE1YAFc0oK^4f7ejuTnuw|mv$y<~!5F6Ztt4k9FaBh;`$#Xw6g6V(lYMy}G zB%7toileqBcq>5vOAOdkagaB>=?cK_qCWm3x+BkSIr=0l?A_QQ(O1E5*|wcTP(_7K z&(Q06{)3S|EvV)T>qQ)BXZTxQ=K=UTSJsVE>B-IF%u*X+qyR8$nZnG_w$fQ0D-J6d z5n(ckNIhP^h(>hf(>gl{*8>0RoUf};j8^YLicuWY2`fac<hPoSoicrypD_6_J=`Ec zibRyiodSMMqx~a(H7yaA)nbbWy$phevn6%(T`xMc98QU_l)P_dEdE_!WFD|H#bw#r z5N*b0ZrxCx^uHQ4AXy{L8Y&utu<??$>_g@!`<FCml3qO5s8)<>h;e6r#8~2iWk(^4 zxp%c7;d<sj4F6M-XtiOdCQN$=8AvVv(m5V&WNirvHQZ=c52QX5h0|8CzNJQY<2270 zTL9fjg_=4I?IU`P_Zb5g)EF>3roN1Ly^OxWiD;!W@w&oyQqijYwvCUp%~t2th3^1Y z715@A90m`?M15LC!OfC$6K<LIcPPwv>9iJfKP3|k0qF0wJ;&vgAXsk#2@BBDdhDu( zI5kP?^JvbA-(uSYO7<Z=4V_d9l^5D`Ky$sti9jo)Ma*!!1{5v&OJQJzW&+)H6_G*~ z4|_ax7KKCg3@ldZYjP-Nf>1{ZIm+2BRP((wRmnx9k|F{@Ac;NytPG6{vix=`c1EVf z@4dxZ)Z7B7i8`D8N9JABRv$iO8O@%8{$4M_r+U_<puSvS-@L#PET_}Roi&|muecgF zWG5ksoc3DH-jproiYyRxC#$M@5rQu#?mWsomO_?~_=X+h7I9JJ2(^nCB;VLT>?t-c zy1Ftob5mbs*n+{{lm&O~<}*oF!0asV<nU5;8w<6#!GN8^8qO;0&h<zRk-toV1Q?gq zPTltso6l7-_Jor8I7q0vBxwYPL(GJr9dSy`IxZ}@$neRhV-IZFJfz>TWm>^<h)|tI zvy$V?c@LV-L|r=;1LJtr@wU3{e9Ztq5lmy5X(?eu%p}U3f}-TEI64RraMav05-O{0 z7SdjI1djy^7(Ys1^}(t5CZhVW&6NYh>^?PChl*YHp6^5hf`u8nriI7a&O#vcd&`(L zJ>(o6#D*<XO@RoQsp|+;NfC9nNVn{b=?*VGF-n0~C(@_4`ww4(Juh<fV!YCXDNjZ< zavr+vW`na%<mcHwvXOr^O-in;Ztga0hUwrOPQ+_i|J||NwR!(J&I*2*RfL6K5o@$m zHJ;=A@0+Oet0xUfp!!G!vKxlCNs4SMz8*<BvU!rVz}be}Fa`ru@YsZiNaavwJa95B z8*D^!3b(jlf+DZ;?_WtRTkA|+PHKdEeQnv2=`K1wE0IZQ`yI8_v{MOe!iVI^BX7c5 z7y_a7{G@XJJMd^F(HyN3L7F`y192h<@_%D*3urwa4dnmMePXD1fZCWKApYk6Z|JGi zg7*uUx;V!d?l+h`P~|~zm3`5uAd_%&E~7k$!i`Y}1<C-jer)a9^YzZGXn3pSguJp` zregLVbZu*4f%PkukZjwwp%Y`Mn@jU(O`_86EPt}T5QX`L?9IOWFQ(1dR|Xa1vU0w6 zO2<?)b|hJ3GMq4Bk?gDF(}8Mc@+RQA#nB5`(V<`RQTNKM|Ig&E`Jbmt;%FULB)rGB zmCmphF1d+g+m6V^2L|DYG3u`)(1LVJI+mFR-S}*}da?=E89X2C2SGvbm3s_fz`#&9 z)sZ=!zh!&oNed^OC_@WWUmKkp?4QJu$R~VW3<Rc*@PH1_wq(4rJRslK!NrS3%EJV3 z;X$y+_vPKz?~SnpC=h~5bt(%X!1bEdO7#NUnS^QfkHM5gNF+bExkz`&DoQkLSvSHK zFpfbSuxm_E)PiQ_B6L%rI~WD&4EV=X3EG5Qjf{kZDXoTK{2kWH$BlB!iH)ESes3H< zvVjJnX1=eU{G&UnA{ODImh9=%KwAWC4WEGR{3GNreIlNaG~|QSSPeBB@>&P38KQ9L zCP0MAq7{8N<e8pD-1GbH^<`f#S*AD^2*V1BBIH8X{i843G3rkqMBDK;5l)E8A8<a3 zJ|9ZUuSA;9esm7y^1Pl9sqwmOie!?RQTJ<KXCMr6s7E)sgYQTqaCbi=jf)3Z>VE(u zyeX&&X*7l&6m#0tUt3AZcWT|B+1nWOjKy@tL|-{Rfc$t9Hiw;VpFcFR!M736eY%~Y zvw=JnFXf(rmxd0<8dXQ-7Rinp4d<9hK2i5~f+`$KBsnr1WXdIXi07Sb2;Gn-uml}c zraLSt1rBFmMt9R+zc|?Tb#DM@)}2Tc=hdve_drxosD#)i#k#5?G?Gg|4mss@`etWz zR5RRPUWrL>`N+Pjl*r4oCmuP#B0_tV;za8AuL1_sDu5?ii~_0(ZE65jhq)ymnmK~R zIxFm&ZHRrmOAnvnK%N!q@=_$1q7F6e{6+-)cakSsNj**?=o#S>qQ5WDcChi#j}5#F zMLxq*JAnN(mOdqiY}Frgm`x0eLbC)O)@yz=73`FRc6RvHByzQ_M>mLLyZU3sByu)+ z?V4gu&{ROfv(d^ZzP+Pv)CKh<vJf&p^mI7M_gqB-aV|PCDG7n<8v?^(_5S;l?lF0L zKFP5V@py2ZcwM%-P0<c0h}h-ULH?h-u)E5MXIZ(<4Mn&^B=I`oP%IbY)${knC}`&z zc=m-qIp+Y;EjE-%iMZo+lU8%5d5%d9e36z->WC~6y(S+KiFSY6Q&6V@M$n4?zzgo5 z&vIeJ5BJ?#d-z9=-s)nmL@Xc=)&@)yrkfABM?RcCaRzVDH4Gmx&IJ04nNKn6gqly# zF*~RCLG|SAKhrror|-e}<c*sTc)|ySo?*;9!MgpN_w);Y<PVJ-u+WFUf1NbD$8Pf} zUhA~T)7AYRSv&iDIy!pW5bW&X>$(l)2bo~y+5_URF@W1y9@VCOyKaa^+eXz&emQ;g zPnoCm+kfneumPXrjEDuw(?{KgT-xSwsqp->-b*$%W~(`TE|&ziwnN>vH|tdY_laBB z%kUMVQH#xW!4z)CTi8N@yTK(}PnKU-fpO2<)iX5DHF#bi7V_!~^3}|FvzGHtwXmKe zZ*$G!%enw#fM2%Sei$wal@BGtg&k#TTD*dk%7h<KX+eRhs5<M9j4<z>CiO>bbB5^r zkOEcJzbt=kSYA+C6$$#XJ~adyb6T!-zpQIo9`^FVcGJ!NS6Y8S!OCp{Kt@+7<Fvr^ zfM0FgV8IhE?u;AzvfOk`W-vrSf{7-H6bBZz5C13ImN}q*s~`yOC+csTm=By|A7XIf z@O3FLP*l<eGt%B_umGeyl?L?(A#i7E7O&?=%m#LVoj4e^q6S3b7$t@q1jA18!jNXa zTtuKsbUn8M?lT{0^1tQ8+gDHU!$zogvfhdq_ww2q@XhnolHq=~-l_;|>wPcG-IZ{y z^4pmha5-l-6_W!?T*LK2e0GJHY^YTZBXK+6bBw+^R|}8El7Qlak9fry$@h}ZZR}$_ zRH)~_0-l=JFdFFss{rM9sRB#ThH)vlRj{%2(e)Kb4nX+|Scz-gQ#GU#ZLUf?rc{xy z%)vW?SNT#EWa^W`g*JSyGEbEyeXYbnV={Yh4DLVVAHx!aD{n#syDZ6=Y4v}}$1V~; zDCSvkVLX>=D0i9^K|b8blt<2XB4S^!EK4EN%bwWhg|&sVxsBPgPs6`gOGy|oUIWMI z1wyBN<h%&!ASg5$Xs?Pozg}ZkLxE{rBwqpdEwi=L$;0mAp9A75aom703mYZqpuP-U z337#ekKo!^t{h&>`<jkd)qkUng{|m7ys&~gkm5m#iK5kUpQNJ<s-xhJ;nKv3o0;ij zjIyTNP-wJqd~HPr>S1=q^hD%!BUq0~LJ(dyy@Ow6pOsE4IR{QtY;SzOr!u4N2hTUS zqpNPeP?JikYFT(tYlcuD$hdKM(Z;z!HRp4F6{WT{(GLXyDRA(~j9I&T(*N=T1IQB4 zU8h+G-clz|h-qPfrFMs+^(C4McGu<ap@@d-p83FvtmPJ!9&533h6Uy5fo1)s|8}z* z@T34j+s8^*PAe|1SIdK8yyCxNwZ$Ojn*8EoNvhJ_+<*Gu1EE@@#!GD=QFd$N8EDSX z)@wO;4va#EKA$d3OK03)dKi3x2<e69^6-|GKlX}%$$0@DOSjvB0e0I)SPw<Y)rG1I zPH700GHZ*>1XvN{n1pP<aE=YJcNuM}EfP|6V@`da%=odXd2W90>JZ@QO4X4*;g73z zw$wxPwD)KGXcgZe%8?`KH{e>(g8Oyu?aCfpB6Vg__SQH8LJSO)=qL#IWTR*E582g- zT%RoxC7Li<hHfBIiF$R*cNME26WOhPqaQbApkrw_tRvP5D9DAnt8}?aCp@6Z-!C=E zw69_xv3J^C?B9BP<#*!2k6|}is&D8qSYu?HrybKKE{<02I3CSmuXLr@`Xx~%WbJ+4 zDDQf}YQOm1W9>U#wY~<_sM>L?aJmE>M8ZKsJ;+`ghUvu$BTjIgwCf>GbM3eLmJ{^b zWd~%aUr(_B@L)XC8&Cb|9s0h)%W1d_4Pu6>4dn~IT;l0HuWLJCJbkk_u8tK0qRL}n zRQOY39n5H)buX5T(dwP51&`;O?nGTRG}_N<z+QadY+PMJ&(DGD&>Qw<5i&<gM;tr! z114!&?jS*D#1LQV_*?jAJtnUYX%E8SS;<W#If|)!3%I-3P%VGX@tcT=R8S}GO0%G{ zQ?Sumi|HUQ&ncL$h;ygq5D@j2jYg^b?PU~ssMbU=MJKEMWM=}G`qdnu9PeZ9BsUOP zEEIXU4!{X{6BU45GOE&BTVNi`VUvv_7TV-&SHfqW(B!`Trc!5m^Yin>TZ7#f#Kp+P z2+Un?+Qztr8LN><#^+)avno36<V7Iqu96i~%7R;-YZ?_LpiSAKkL@!ML2Xu)6C)0x zq#HD{Q61j1XY0U8>1+}+y4)gje=n5F_1H<+ToOyU3UZ*OKQ4<F#Z65^t!sKjHn^a) zusI@3Rza}BzaTn9nEry2*(T+}h9U_xMBW6+;BsZ3A70yHk_6PCF@t(80__X#eh-{r zL=hx!YyewzMZkzzbxpubc0-=8VcZEE{P!tJ83b12ExI5LA|OgUV`9K8kSFnkNyLKx zlyhp%fd;5%MU|I{rPkxUkNLpiVKPqb^>w{Z|7HNmZFq#6>OR4IS3_9eIyg8>UQ7$! zRzvF{)GTDltzO>erY%A2_TD!5m^x51Wa1LeH<HV$zIpuB$pnJXW}v?pS%Eb>zx#yK z>y>0127clZljl1;uyWn5MNtz|9h8wAX1k8H<_JVKRs0~$courjXRN2>k8^zoyoQy> zE={7u9cn5G`0&^_#*>hW>UC`0D|o=%D%1$OV88AX>&FZ^CjPt&@<)Ve((8ua%W5_0 zPFy;BWk|}pc2_rN%t65KXI(iw>QrWk@^G2%)IS}TDtmC)2o^-#5*zB_i99PDkwDk{ ziv|V-EUMZ-)syr*2el2dY>F8~ygE3Aj(Gewu~C`aC7Ye*=1QUu(POt%+qSZF_U*45 z5r-Nkr)ewL<x_48EzR`lT#{jsVW{JbhFpWRP}<PNM2iw5r`6z8l*6CUpqA7<DoO$D z_wD|(W13JO*+ba;WO(qcErwvqhXAy}>;at?)%~<atGer1Nr?81kq<saIGu4(^1~%y z?ZOJA6MU23YOiYT@fZcBH5~Q-@g;`+Bc{y^E^iYUc=LHUow}Xzmq5W)ihg81I!*nh z0oRI}29ZgsrdLqjV`o>MhgP^0NCh==zEc}r2tNIpLVp^g+pkZ77Cv+{nl!U*cnIWi zI@XW4n7XT?m>3dB9z%o2C_B~|@ppkaK5F}wS%##pd~1hCm*l?=G101`ThLotzIZ5w z>+j-PnsEZ7>N+k=3#tch4InuWenK2jKFYWMBno9?&)5GX3}sKs(|;uhUHX-0|F}sK zY$Xqe$XAh|L`jM`uy(E_n2#XZkq<<aTE=GPdAd~(73n44LJ)^_lI%G$xC&wJ%rI3H z`HUmipF4Lx--Pj*j09qAdTg5=>F|N~C4yURna}LcdZN@ap*7$*?>4qY72n$!J!ZH` z05aC-_8a-i6fp^c*zK(d%^=vjrZ-rlFjw?kJ!4WZs92r#l8fyrvF-eC3xLTKRP$S* z0%{Z2@3rlks}V~I*sYlZ|Iu-c`&d;yoM+y(o5#ghHgXenPrW^+Mi6x|W_x4M{s2R* zS1^dC<Em9H4PhyN_aZ~}5pudDK|6p%Yq{%Csa&aobMvr3#6n@NZX#8a3*MX4_xXY( z9PY=90{pLHG?=v=uyVZDYJuS`)+BTk1ewp$x`u?%HXyhqvnYE?!}Wwb%+Cs3S!0v) zrbNaG@EI7KtSL>yqHH_?Y;v#AeN6+6>m(N_4h1U1dT`xXh$?zXEG4v!X59rc;mUtC z1iW0W7dpW;I}HRL+mtmn!k&|q4@#8`*Qzr$mSv@eeWY4Po7JX_mVkrH%Ag||mx;Qe z$QP&k8nd{o<;+{E)L%-Ndp1>Hmh$XNtz}DIE#=O`9i&>%dKgjwTb+GhnCsQb{p zTSbaJ_36|o`^MsBh>ifr9$1Gicxaw^#4{RSUJ{fuH_77aY%XDIc6i(+w7L`QPc<eE z@#y`k4*yM|O#eS2BS7jw^}Bjn{BNOF!Bt%3tB??rT@L_W5t7;*(cxuB8??bMPs=;w zL%F451swU^YQjK32BJ?>HLJ^2q5c<6pi}JoRk5Z1+>w;~%W?EE9=jW#W<n4xd+3*! zX37pnxGd*F6X_30chQZV5;t=2dhkFBvFntNQX<12P@`pROrSZHEcBD5u8~Zi9X47X z^Q0G(bNE99${rah^ev(`@1cjzYHIf7N&%fOMlN8Y`Bd=59?6Mi{<#vWN`)~gHgETZ z*p&Ze-T|gh<JJLkj#6)cfpyz;kbvby-cNBSr?fS!W{^O+l?Vbgrqzp_i^@hC<tLy= zkL+4*K<(?j4A{IQk+zilyI4%?kp!{M0cys<uOTz~T}^O5e-SqH%M!r`CZy^lS9o%& zfT4PF#>Qku+jI)c;iqPK>Eoecy<8+l<U+<1%x)aKL*8{9{G?r74X{f)DDpw(M^hwI z1VbhEGxYt7@qVYhzRR@=uM12~AT71*vLHr4jt8y84LA&2G9Y@Q+c{Nq&O_F_5bN3| zok?s>cZ#PJGxs3yQaEKGo41=03C~{Zqan@sa8hJ`ZV)H=imtl+h&3hdc}#`<{{fId zZ@+-_QLyhbXqVW(Az-&yH?XS(B>I-IH<A9_*y{&l5k`WStvv)bwP6B^x<Zn4CN<FT zJyedEaUvm1lpLsk5rVcWR+=_1Kq{d{H!p#mziyKB_r!)(j+ClQoM2qFA5ES$k#|QC z&bAR!|Nck!_|(DXYM}hUI|s{TEx+6k8sIUR@^}e|a|*>D_jupG%G+lUI<XNL#<+I0 z*ubcja!(%3A;n1u;a~;f%Hz*6zFn6m)#^~c__F1F6^Yk>YBFn;XJH%_;hzMHE&bBE zo`?{~WA&M#04{T-z8|(geV5v82d{Lg5^O_l$9Riua|0Nha22*T{gpuf3vj_p5B$15 zgT)(ZpiIC89({Gkt%VpGT7(_1;9PJ|nQ7*FUl_2rf;s|9pgC6zxB*hYYV9^d2YSq2 zmD4h674ABJiq&P4LoHh+#l8|H%e~EtSl!XkcP!MM3W(?-uuo(yu&)dJ@E=U#ti9X) z!}5QDVzllN`bi4T9mY$Tg?NEe;@rOsj{Sc%m*|veQ~&}Q#fB2a%8Q<3GVi$g=$|W8 zdHjdTIjZDg=<Ka`QqrcnTbyN7bH1H4H>WY<mIP3LpOrug9EoMTT1h$_v3H#iaqBkX ze8<hXM)nR?Nd-yMSKaXMp-ZmURm=ZhBM)06zj}4_SQjl9H~(8!1ZXXIWKAErLPv>G z?R5LJ`QulnxY<8x<-+4@9f<Jb<nsLe>6@R<emZwPY$R`^#eV)dPM6u|g1--_N2tD4 z6uv@#hRjngy;dyU$CBgl>Pyfh{9(B<4sQhx2L3fpzu-D3fWYTl6+Ga})gUsTOi*II z%Hu)@79<|_F9H?Z`nSqtky!L6DD=pJ=|H7Z_=1hwVYw9E-eAsuYxVJ7t)`=?C=tnv z=a(<XH&=Ir^nP=Pl<ukNi0`Q}HCjU+7ryO(;SW5NRXwYW#ZavW$;`*~i&yb-cIVxA zynp396KlWxa;I_KtG8ZpyPs96d2ISEyE<XdDRtI{mSUr!^5+I7_1|-F^>`}DN~y!9 zIG2ku*`tQ(&j&k7b%|~r``&a_0#_2SfEu*j<={Qzw@L6&y?a%8oO%o368rVq@;+OC z!7X@6#UbG3m+;k@QBbViB&XGGU;6^$$Yr)GC!bLO5Le%+bPw%w_~z*TmsD3Bc4pA# z(Q>I~Kv_vMu=bcvpS5{K5O)7=EI@jIx650(ZbWna07GuT!-wZich>>B18VHD`)F3b zZ>62r9E0vRm{+SN-sRr=epTSA$A1QYP5emwz52DQ8oqDC-hp{5D9v7;1Q2gW?I6^i zxbtM>;<+A`ci8=?G<a{~h3&x0%D-@)>Pks|hWY;hgsLGOgx+T=?hX%4X(Xn)83v!6 z4*=8;8tUjAM(o=1Tps70mKp^E<(3t~vNr{g4_o*u@>hjR))3-8;x9q-RYUiGg$ae? zBhI6G9oAd)I}Q#GY}{)O8%E~;s=y~CWwcQD`>0^5z-LoEUo`#y6Xpch^1o0}bzFMq zag#E>Nz&dwvcV~T&YB<@4~a*sS_<xYfJ%O=!S_4}8q%FZ=$rih_k+fw#a)geo5jsx zQ#H~<Pm=f3h#$&qYb&6DNOOgM9(7+mK6Xa5-4$zJt9V-un(&_i*!x5ee-7GG?s3tA z(Q{nMO*T2DYPVPp+Ff?&hvshLUHLR46#pcYa@(P1+cw$$3}Q_1N&s_(Tgfsm7E#_= z^rFIB9FfPn7(%#^iRe=lCv?si6-rJDY}7e8<hh~#)lTMr0Z>Z=1QY-g000O8>V9Qa z@d~C;)d2ti>I9botQr@WV7(s+w>-`p-vJKleq~hxh<TrR9{>P}hnE4Y8W)#9&>I(j zClHdHODbU<u0l()tvg9piFA~N$AIAOEEg6Q*aNVl_I!SnJVah8Pm=za8O#^3q%8Zc zQU|+4eDuup^z`)C^vsr<ZPWHq)1}*@UmunHxUGtQ)wCP++zNHq?K^ebi;w+nTWpV3 zZL^7r>qR6#oPPN<f#<Goi$%W?{kmCyGEBeUmi3JSn;k`Po!0w=Zl0Bkp6_1tqAji~ z!A~#CPQHI#Y{c?>w^d)h-S%Zu7ZpF9i9hZ{y%6e27Bb+^_gi`QT@3}3qxlizwJo=4 z{z25srcJl|n~kXZF0I5z(JEYD;=>`}PC?&@KBqVN^**lw>m<6_iLR3`fwK93s;mTl znW(et_mxmpp3y_mMQ`M1dU2?<g%Q0`7)_MyoA;u&2kB|E!Ea2w=WW}xeEYSiMO!ZT z;rC*H+qBDJtmNHpb1hmmVlcA3Dt*?szz%Y3uu;B!w=R3pZ3`UA`2?Q3zN{3QPphKq zUN`+$&8}VsMir1;r;DcUi?TL<2I?g|btBN*V!1T9^$kBJ>gHJqSaiTfoop`6tESm1 zaJ+{>Zo6K7T{Kmr+36`hBoXj<z0BL2YYkI(%`oOq`7u#9%<o+i{chLw<!b+mrdATY zg<3@WR&={cwf6mPyYC0~{T)BPDnFLBgxH9p+qJr_SNw>Sl>nU}I%@`h<i|wabPCMl z(uDuuY?Cl3DHO;#+#em$a3e&N@eI8HX^})}nqD3qy?gQc*|+b`;FFR=DTtk3Y-aN) z%cA&Q38Qq|#YfMce|7rZ%k%vFo9C~d19-e?>gIh>#z#jFqVu(gR!vnkw>XM&Iuy|3 z>!K6OsHvlM-*3B<M~`lQ%6`4O2I_AfDdrk(uB+zy(WZdr+u<eRRP^wwdj$V%N)ST8 zm(b{Gv=X<`rdgJ&a#7H5MYjSP-4si4baeXq>_z_a#n<1QpOCz}&~%VQyM$i+FieOO zemk4HGednKuFB$D{18hhIaw9RvfO0n?M~QV(>JZyw#~w+Xt6JUYE_S%&kn?OwG$3R ziXE7!NX`26onPIixB+Ym1&U%L{c=}UeOXV`NMK*>>IG8RfxBsiumSO(5Y?#0B--KZ zsX!8#WTJv3Rf5$|m3sbhA+`a;ybe4Qi-rg@LK6@WO||su|F@zoQ9U}PTCuchN1@Rd z10Rflo%SGwuXp`_)BqCTd2!>iLR;Rf``qLR7U>S$Uf?X$m61M};3}z9fIOAxg~xx~ zsL>4t|Dx_h>ld*2LBW0_ilu?5OJ@akw!2>2kOzlI6@3GeZ`&VgfOP4>9)_UsbAStf zltSj&>D%9bUKyiDyI8#c9HK_ncL#~%v)P2;2~;~Je<b*S-NjI#{wZlB!S61V%=+&u zo2<q@MMRBtZcI`+)VrU+^7(v9ZjC^XiLbGq{Jc`kuj(@kvk*IdE}3?4F#qzR?d^-F z-{fci@%sGq-`VIxBk_m007E>lu<H0E8f>g2;xEgheXl;CT>SCq^>?qneE#+<fBNmq z?_Ryml^ywi=JeUK7q7pDI=?tNI$Gcii_Z2yjE`VUZo~{6+xZEh9mnyPU`9p^1Lj~< zfNPA9QIDW002~qIzdDXEzFUfw;gO*`NIuuB6V)n-=sxdBv}xHrkB)!KRAK}q5?_lR zTP7QvvA8M0iP2snS4P;VQf*NJ;@~U2*nr)QP-01cqYy<8qHSB;Y>JbpZlXo=0bJgL zeYgg7aMPmO#oeJ!OkfM-iH0%}4f#*OPY#oIi;dwj?uTJJGe!yiEqdrlC2k5(dO$3L zaP}}_ck{fg%RbN5I3dId#}e3m!GXH49Q4aeBE{>bHYkC`Q#tsHVzCxeiuy-gtXxH9 zSCVjlT!<O9p1{zz^Py(E`gU)>7@Ac6i)x!Fm-)c~u6%CQB1mP}j`mM(CkC<>;I+m> zTcYZOUGHR_gz1q(T7xIq?an4DNnPmi%6Oh-O7PvVyb8BDKl(YRIz`+DX625Uv&iFu zR`k2J_IdAOz~OQj1RiWKvsgYKW-yzw(*$>aX)$0BWVtXFG(hHfr1h?<W=;(rGvTFp z!ba{QruXrs2QLRYP(pqQl(AXG`>fH(;s<f`P@)7goNo~CD1Pvmt~d!6SM0|XC>)^* zbxW0mnRBE@)Z|_l;bnXoE>QMGRW7_D{Ccd=px51U`b((jJRlQB*ciEwqN560@jktO z{50)lO&_<E)<S4v+*1QJ(GG_RggTfhQXh7cdWU<xDYj#3V@&1ff{H+R??}5%*@2F^ z$tS1Qv|tQF-&x�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 F=|9`ma*hB1 diff --git a/Lib/ensurepip/_bundled/setuptools-65.5.0-py3-none-any.whl b/Lib/ensurepip/_bundled/setuptools-65.5.0-py3-none-any.whl deleted file mode 100644 index 123a13e2c6b2543f83a7f0040ad153f8de633558..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1232695 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%0D^IX0brE*=J2*SVT%f_h_#D$WZFB>4<3qYQ5= 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νS>c$rrefWjz=!<){VkfOx8%cuIi8jsPR1A|c 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 !@xnnot34$ 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�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%0A*gYMV|TW)s@^IQ^H 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%0DQ)NbfNc`ie4h=X2&x72bh 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 k4<fk=3xCr|bHWyj255gQa&D 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 H&vpL;_cN&o diff --git a/Lib/enum.py b/Lib/enum.py index 5cff4171..c207dc23 100644 --- a/Lib/enum.py +++ b/Lib/enum.py @@ -12,6 +12,7 @@ __all__ = [ 'FlagBoundary', 'STRICT', 'CONFORM', 'EJECT', 'KEEP', 'global_flag_repr', 'global_enum_repr', 'global_str', 'global_enum', 'EnumCheck', 'CONTINUOUS', 'NAMED_FLAGS', 'UNIQUE', + 'pickle_by_global_name', 'pickle_by_enum_name', ] @@ -189,37 +190,48 @@ class property(DynamicClassAttribute): a corresponding enum member. """ + member = None + _attr_type = None + _cls_type = None + def __get__(self, instance, ownerclass=None): if instance is None: - try: - return ownerclass._member_map_[self.name] - except KeyError: + if self.member is not None: + return self.member + else: raise AttributeError( '%r has no attribute %r' % (ownerclass, self.name) ) - else: - if self.fget is None: - raise AttributeError( - '%r member has no attribute %r' % (ownerclass, self.name) - ) - else: - return self.fget(instance) + if self.fget is not None: + # use previous enum.property + return self.fget(instance) + elif self._attr_type == 'attr': + # look up previous attibute + return getattr(self._cls_type, self.name) + elif self._attr_type == 'desc': + # use previous descriptor + return getattr(instance._value_, self.name) + # look for a member by this name. + try: + return ownerclass._member_map_[self.name] + except KeyError: + raise AttributeError( + '%r has no attribute %r' % (ownerclass, self.name) + ) from None def __set__(self, instance, value): - if self.fset is None: - raise AttributeError( - "<enum %r> cannot set attribute %r" % (self.clsname, self.name) - ) - else: + if self.fset is not None: return self.fset(instance, value) + raise AttributeError( + "<enum %r> cannot set attribute %r" % (self.clsname, self.name) + ) def __delete__(self, instance): - if self.fdel is None: - raise AttributeError( - "<enum %r> cannot delete attribute %r" % (self.clsname, self.name) - ) - else: + if self.fdel is not None: return self.fdel(instance) + raise AttributeError( + "<enum %r> cannot delete attribute %r" % (self.clsname, self.name) + ) def __set_name__(self, ownerclass, name): self.name = name @@ -250,28 +262,32 @@ class _proto_member: args = (args, ) # wrap it one more time if not enum_class._use_args_: enum_member = enum_class._new_member_(enum_class) - if not hasattr(enum_member, '_value_'): + else: + enum_member = enum_class._new_member_(enum_class, *args) + if not hasattr(enum_member, '_value_'): + if enum_class._member_type_ is object: + enum_member._value_ = value + else: try: enum_member._value_ = enum_class._member_type_(*args) except Exception as exc: - enum_member._value_ = value - else: - enum_member = enum_class._new_member_(enum_class, *args) - if not hasattr(enum_member, '_value_'): - if enum_class._member_type_ is object: - enum_member._value_ = value - else: - try: - enum_member._value_ = enum_class._member_type_(*args) - except Exception as exc: - raise TypeError( - '_value_ not set in __new__, unable to create it' - ) from None + new_exc = TypeError( + '_value_ not set in __new__, unable to create it' + ) + new_exc.__cause__ = exc + raise new_exc value = enum_member._value_ enum_member._name_ = member_name enum_member.__objclass__ = enum_class enum_member.__init__(*args) enum_member._sort_order_ = len(enum_class._member_names_) + + if Flag is not None and issubclass(enum_class, Flag): + enum_class._flag_mask_ |= value + if _is_single_bit(value): + enum_class._singles_mask_ |= value + enum_class._all_bits_ = 2 ** ((enum_class._flag_mask_).bit_length()) - 1 + # If another member with the same value was already defined, the # new member becomes an alias to the existing one. try: @@ -301,29 +317,40 @@ class _proto_member: ): # no other instances found, record this member in _member_names_ enum_class._member_names_.append(member_name) - # get redirect in place before adding to _member_map_ - # but check for other instances in parent classes first - need_override = False - descriptor = None + # if necessary, get redirect in place and then add it to _member_map_ + found_descriptor = None + descriptor_type = None + class_type = None for base in enum_class.__mro__[1:]: - descriptor = base.__dict__.get(member_name) - if descriptor is not None: - if isinstance(descriptor, (property, DynamicClassAttribute)): + attr = base.__dict__.get(member_name) + if attr is not None: + if isinstance(attr, (property, DynamicClassAttribute)): + found_descriptor = attr + class_type = base + descriptor_type = 'enum' break + elif _is_descriptor(attr): + found_descriptor = attr + descriptor_type = descriptor_type or 'desc' + class_type = class_type or base + continue else: - need_override = True - # keep looking for an enum.property - if descriptor and not need_override: - # previous enum.property found, no further action needed - pass - elif descriptor and need_override: + descriptor_type = 'attr' + class_type = base + if found_descriptor: redirect = property() + redirect.member = enum_member redirect.__set_name__(enum_class, member_name) - # Previous enum.property found, but some other inherited attribute - # is in the way; copy fget, fset, fdel to this one. - redirect.fget = descriptor.fget - redirect.fset = descriptor.fset - redirect.fdel = descriptor.fdel + if descriptor_type in ('enum','desc'): + # earlier descriptor found; copy fget, fset, fdel to this one. + redirect.fget = getattr(found_descriptor, 'fget', None) + redirect._get = getattr(found_descriptor, '__get__', None) + redirect.fset = getattr(found_descriptor, 'fset', None) + redirect._set = getattr(found_descriptor, '__set__', None) + redirect.fdel = getattr(found_descriptor, 'fdel', None) + redirect._del = getattr(found_descriptor, '__delete__', None) + redirect._attr_type = descriptor_type + redirect._cls_type = class_type setattr(enum_class, member_name, redirect) else: setattr(enum_class, member_name, enum_member) @@ -512,8 +539,13 @@ class EnumType(type): # # adjust the sunders _order_ = classdict.pop('_order_', None) + _gnv = classdict.get('_generate_next_value_') + if _gnv is not None and type(_gnv) is not staticmethod: + _gnv = staticmethod(_gnv) # convert to normal dict classdict = dict(classdict.items()) + if _gnv is not None: + classdict['_generate_next_value_'] = _gnv # # data type of member and the controlling Enum class member_type, first_enum = metacls._get_mixins_(cls, bases) @@ -524,12 +556,8 @@ class EnumType(type): classdict['_use_args_'] = use_args # # convert future enum members into temporary _proto_members - # and record integer values in case this will be a Flag - flag_mask = 0 for name in member_names: value = classdict[name] - if isinstance(value, int): - flag_mask |= value classdict[name] = _proto_member(value) # # house-keeping structures @@ -546,8 +574,9 @@ class EnumType(type): boundary or getattr(first_enum, '_boundary_', None) ) - classdict['_flag_mask_'] = flag_mask - classdict['_all_bits_'] = 2 ** ((flag_mask).bit_length()) - 1 + classdict['_flag_mask_'] = 0 + classdict['_singles_mask_'] = 0 + classdict['_all_bits_'] = 0 classdict['_inverted_'] = None try: exc = None @@ -636,21 +665,10 @@ class EnumType(type): ): delattr(enum_class, '_boundary_') delattr(enum_class, '_flag_mask_') + delattr(enum_class, '_singles_mask_') delattr(enum_class, '_all_bits_') delattr(enum_class, '_inverted_') elif Flag is not None and issubclass(enum_class, Flag): - # ensure _all_bits_ is correct and there are no missing flags - single_bit_total = 0 - multi_bit_total = 0 - for flag in enum_class._member_map_.values(): - flag_value = flag._value_ - if _is_single_bit(flag_value): - single_bit_total |= flag_value - else: - # multi-bit flags are considered aliases - multi_bit_total |= flag_value - enum_class._flag_mask_ = single_bit_total - # # set correct __iter__ member_list = [m._value_ for m in enum_class] if member_list != sorted(member_list): @@ -679,7 +697,7 @@ class EnumType(type): 'member order does not match _order_:\n %r\n %r' % (enum_class._member_names_, _order_) ) - + # return enum_class def __bool__(cls): @@ -688,7 +706,7 @@ class EnumType(type): """ return True - def __call__(cls, value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None): + def __call__(cls, value, names=None, *values, module=None, qualname=None, type=None, start=1, boundary=None): """ Either returns an existing member, or creates a new enum class. @@ -696,6 +714,8 @@ class EnumType(type): to an enumeration member (i.e. Color(3)) and for the functional API (i.e. Color = Enum('Color', names='RED GREEN BLUE')). + The value lookup branch is chosen if the enum is final. + When used for the functional API: `value` will be the name of the new class. @@ -713,12 +733,20 @@ class EnumType(type): `type`, if set, will be mixed in as the first base class. """ - if names is None: # simple value lookup + if cls._member_map_: + # simple value lookup if members exist + if names: + value = (value, names) + values return cls.__new__(cls, value) # otherwise, functional API: we're creating a new Enum type + if names is None and type is None: + # no body? no data-type? possibly wrong usage + raise TypeError( + f"{cls} has no members; specify `names=()` if you meant to create a new, empty, enum" + ) return cls._create_( - value, - names, + class_name=value, + names=names, module=module, qualname=qualname, type=type, @@ -726,26 +754,16 @@ class EnumType(type): boundary=boundary, ) - def __contains__(cls, member): - """ - Return True if member is a member of this enum - raises TypeError if member is not an enum member + def __contains__(cls, value): + """Return True if `value` is in `cls`. - note: in 3.12 TypeError will no longer be raised, and True will also be - returned if member is the value of a member in this enum + `value` is in `cls` if: + 1) `value` is a member of `cls`, or + 2) `value` is the value of one of the `cls`'s members. """ - if not isinstance(member, Enum): - import warnings - warnings.warn( - "in 3.12 __contains__ will no longer raise TypeError, but will return True or\n" - "False depending on whether the value is a member or the value of a member", - DeprecationWarning, - stacklevel=2, - ) - raise TypeError( - "unsupported operand type(s) for 'in': '%s' and '%s'" % ( - type(member).__qualname__, cls.__class__.__qualname__)) - return isinstance(member, cls) and member._name_ in cls._member_map_ + if isinstance(value, cls): + return True + return value in cls._value2member_map_ or value in cls._unhashable_values_ def __delattr__(cls, attr): # nicer error message when someone tries to delete an attribute @@ -772,22 +790,6 @@ class EnumType(type): # return whatever mixed-in data type has return sorted(set(dir(cls._member_type_)) | interesting) - def __getattr__(cls, name): - """ - Return the enum member matching `name` - - We use __getattr__ instead of descriptors or inserting into the enum - class' __dict__ in order to support `name` and `value` being both - properties for enum members (which live in the class' __dict__) and - enum members themselves. - """ - if _is_dunder(name): - raise AttributeError(name) - try: - return cls._member_map_[name] - except KeyError: - raise AttributeError(name) from None - def __getitem__(cls, name): """ Return the member matching `name`. @@ -868,6 +870,8 @@ class EnumType(type): value = first_enum._generate_next_value_(name, start, count, last_values[:]) last_values.append(value) names.append((name, value)) + if names is None: + names = () # Here, names is either an iterable of (name, value) or a mapping. for item in names: @@ -877,13 +881,15 @@ class EnumType(type): member_name, member_value = item classdict[member_name] = member_value - # TODO: replace the frame hack if a blessed way to know the calling - # module is ever developed if module is None: try: - module = sys._getframe(2).f_globals['__name__'] - except (AttributeError, ValueError, KeyError): - pass + module = sys._getframemodulename(2) + except AttributeError: + # Fall back on _getframe if _getframemodulename is missing + try: + module = sys._getframe(2).f_globals['__name__'] + except (AttributeError, ValueError, KeyError): + pass if module is None: _make_class_unpicklable(classdict) else: @@ -924,7 +930,6 @@ class EnumType(type): body['__module__'] = module tmp_cls = type(name, (object, ), body) cls = _simple_enum(etype=cls, boundary=boundary or KEEP)(tmp_cls) - cls.__reduce_ex__ = _reduce_ex_by_global_name if as_global: global_enum(cls) else: @@ -936,7 +941,7 @@ class EnumType(type): def _check_for_existing_members_(mcls, class_name, bases): for chain in bases: for base in chain.__mro__: - if issubclass(base, Enum) and base._member_names_: + if isinstance(base, EnumType) and base._member_names_: raise TypeError( "<enum %r> cannot extend %r" % (class_name, base) @@ -952,13 +957,10 @@ class EnumType(type): """ if not bases: return object, Enum - - mcls._check_for_existing_members_(class_name, bases) - # ensure final parent class is an Enum derivative, find any concrete # data type, and check that Enum has no members first_enum = bases[-1] - if not issubclass(first_enum, Enum): + if not isinstance(first_enum, EnumType): raise TypeError("new enumerations should be created as " "`EnumName([mixin_type, ...] [data_type,] enum_type)`") member_type = mcls._find_data_type_(class_name, bases) or object @@ -970,16 +972,25 @@ class EnumType(type): for base in chain.__mro__: if base is object: continue - elif issubclass(base, Enum): + elif isinstance(base, EnumType): # if we hit an Enum, use it's _value_repr_ return base._value_repr_ elif '__repr__' in base.__dict__: # this is our data repr - return base.__dict__['__repr__'] + # double-check if a dataclass with a default __repr__ + if ( + '__dataclass_fields__' in base.__dict__ + and '__dataclass_params__' in base.__dict__ + and base.__dict__['__dataclass_params__'].repr + ): + return _dataclass_repr + else: + return base.__dict__['__repr__'] return None @classmethod def _find_data_type_(mcls, class_name, bases): + # a datatype has a __new__ method, or a __dataclass_fields__ attribute data_types = set() base_chain = set() for chain in bases: @@ -988,13 +999,11 @@ class EnumType(type): base_chain.add(base) if base is object: continue - elif issubclass(base, Enum): + elif isinstance(base, EnumType): if base._member_type_ is not object: data_types.add(base._member_type_) break - elif '__new__' in base.__dict__ or '__init__' in base.__dict__: - if issubclass(base, Enum): - continue + elif '__new__' in base.__dict__ or '__dataclass_fields__' in base.__dict__: data_types.add(candidate or base) break else: @@ -1066,20 +1075,20 @@ class Enum(metaclass=EnumType): Access them by: - - attribute access:: + - attribute access: - >>> Color.RED - <Color.RED: 1> + >>> Color.RED + <Color.RED: 1> - value lookup: - >>> Color(1) - <Color.RED: 1> + >>> Color(1) + <Color.RED: 1> - name lookup: - >>> Color['RED'] - <Color.RED: 1> + >>> Color['RED'] + <Color.RED: 1> Enumerations can be iterated over, and know how many members they have: @@ -1093,6 +1102,13 @@ class Enum(metaclass=EnumType): attributes -- see the documentation for details. """ + @classmethod + def __signature__(cls): + if cls._member_names_: + return '(*values)' + else: + return '(new_class_name, /, names, *, module=None, qualname=None, type=None, start=1, boundary=None)' + def __new__(cls, value): # all enum instances are actually created during class construction # without calling this method; this method is called by the metaclass' @@ -1112,6 +1128,11 @@ class Enum(metaclass=EnumType): for member in cls._member_map_.values(): if member._value_ == value: return member + # still not found -- verify that members exist, in-case somebody got here mistakenly + # (such as via super when trying to override __new__) + if not cls._member_map_: + raise TypeError("%r has no members defined" % cls) + # # still not found -- try _missing_ hook try: exc = None @@ -1147,6 +1168,7 @@ class Enum(metaclass=EnumType): def __init__(self, *args, **kwds): pass + @staticmethod def _generate_next_value_(name, start, count, last_values): """ Generate the next value when not given. @@ -1175,7 +1197,7 @@ class Enum(metaclass=EnumType): DeprecationWarning, stacklevel=3, ) - for v in last_values: + for v in reversed(last_values): try: return v + 1 except TypeError: @@ -1230,15 +1252,21 @@ class Enum(metaclass=EnumType): return hash(self._name_) def __reduce_ex__(self, proto): - return getattr, (self.__class__, self._name_) + return self.__class__, (self._value_, ) + + def __deepcopy__(self,memo): + return self + + def __copy__(self): + return self # enum.property is used to provide access to the `name` and # `value` attributes of enum members while keeping some measure of # protection from modification, while still allowing for an enumeration - # to have members named `name` and `value`. This works because enumeration - # members are not set directly on the enum class; they are kept in a - # separate structure, _member_map_, which is where enum.property looks for - # them + # to have members named `name` and `value`. This works because each + # instance of enum.property saves its companion member, which it returns + # on class lookup; on instance lookup it either executes a provided function + # or raises an AttributeError. @property def name(self): @@ -1289,6 +1317,7 @@ class StrEnum(str, ReprEnum): member._value_ = value return member + @staticmethod def _generate_next_value_(name, start, count, last_values): """ Return the lower-cased version of the member name. @@ -1296,16 +1325,22 @@ class StrEnum(str, ReprEnum): return name.lower() -def _reduce_ex_by_global_name(self, proto): +def pickle_by_global_name(self, proto): + # should not be used with Flag-type enums return self.name +_reduce_ex_by_global_name = pickle_by_global_name + +def pickle_by_enum_name(self, proto): + # should not be used with Flag-type enums + return getattr, (self.__class__, self._name_) class FlagBoundary(StrEnum): """ control how out of range values are handled - "strict" -> error is raised [default for Flag] + "strict" -> error is raised [default for Flag] "conform" -> extra bits are discarded - "eject" -> lose flag status [default for IntFlag] - "keep" -> keep flag status and all bits + "eject" -> lose flag status + "keep" -> keep flag status and all bits [default for IntFlag] """ STRICT = auto() CONFORM = auto() @@ -1314,30 +1349,14 @@ class FlagBoundary(StrEnum): STRICT, CONFORM, EJECT, KEEP = FlagBoundary -class Flag(Enum, boundary=CONFORM): +class Flag(Enum, boundary=STRICT): """ Support for flags """ - def __reduce_ex__(self, proto): - cls = self.__class__ - unknown = self._value_ & ~cls._flag_mask_ - member_value = self._value_ & cls._flag_mask_ - if unknown and member_value: - return _or_, (cls(member_value), unknown) - for val in _iter_bits_lsb(member_value): - rest = member_value & ~val - if rest: - return _or_, (cls(rest), cls._value2member_map_.get(val)) - else: - break - if self._name_ is None: - return cls, (self._value_,) - else: - return getattr, (cls, self._name_) - _numeric_repr_ = repr + @staticmethod def _generate_next_value_(name, start, count, last_values): """ Generate the next value when not given. @@ -1392,6 +1411,7 @@ class Flag(Enum, boundary=CONFORM): # - value must not include any skipped flags (e.g. if bit 2 is not # defined, then 0d10 is invalid) flag_mask = cls._flag_mask_ + singles_mask = cls._singles_mask_ all_bits = cls._all_bits_ neg_value = None if ( @@ -1423,7 +1443,8 @@ class Flag(Enum, boundary=CONFORM): value = all_bits + 1 + value # get members and unknown unknown = value & ~flag_mask - member_value = value & flag_mask + aliases = value & ~singles_mask + member_value = value & singles_mask if unknown and cls._boundary_ is not KEEP: raise ValueError( '%s(%r) --> unknown values %r [%s]' @@ -1437,21 +1458,34 @@ class Flag(Enum, boundary=CONFORM): pseudo_member = cls._member_type_.__new__(cls, value) if not hasattr(pseudo_member, '_value_'): pseudo_member._value_ = value - if member_value: - pseudo_member._name_ = '|'.join([ - m._name_ for m in cls._iter_member_(member_value) - ]) - if unknown: + if member_value or aliases: + members = [] + combined_value = 0 + for m in cls._iter_member_(member_value): + members.append(m) + combined_value |= m._value_ + if aliases: + value = member_value | aliases + for n, pm in cls._member_map_.items(): + if pm not in members and pm._value_ and pm._value_ & value == pm._value_: + members.append(pm) + combined_value |= pm._value_ + unknown = value ^ combined_value + pseudo_member._name_ = '|'.join([m._name_ for m in members]) + if not combined_value: + pseudo_member._name_ = None + elif unknown and cls._boundary_ is STRICT: + raise ValueError('%r: no members with value %r' % (cls, unknown)) + elif unknown: pseudo_member._name_ += '|%s' % cls._numeric_repr_(unknown) else: pseudo_member._name_ = None # use setdefault in case another thread already created a composite - # with this value, but only if all members are known - # note: zero is a special case -- add it - if not unknown: - pseudo_member = cls._value2member_map_.setdefault(value, pseudo_member) - if neg_value is not None: - cls._value2member_map_[neg_value] = pseudo_member + # with this value + # note: zero is a special case -- always add it + pseudo_member = cls._value2member_map_.setdefault(value, pseudo_member) + if neg_value is not None: + cls._value2member_map_[neg_value] = pseudo_member return pseudo_member def __contains__(self, other): @@ -1523,14 +1557,10 @@ class Flag(Enum, boundary=CONFORM): def __invert__(self): if self._inverted_ is None: - if self._boundary_ is KEEP: - # use all bits + if self._boundary_ in (EJECT, KEEP): self._inverted_ = self.__class__(~self._value_) else: - # calculate flags not in this member - self._inverted_ = self.__class__(self._flag_mask_ ^ self._value_) - if isinstance(self._inverted_, self.__class__): - self._inverted_._inverted_ = self + self._inverted_ = self.__class__(self._singles_mask_ & ~self._value_) return self._inverted_ __rand__ = __and__ @@ -1565,10 +1595,13 @@ def unique(enumeration): (enumeration, alias_details)) return enumeration -def _power_of_two(value): - if value < 1: - return False - return value == 2 ** _high_bit(value) +def _dataclass_repr(self): + dcf = self.__dataclass_fields__ + return ', '.join( + '%s=%r' % (k, getattr(self, k)) + for k in dcf.keys() + if dcf[k].repr + ) def global_enum_repr(self): """ @@ -1670,6 +1703,7 @@ def _simple_enum(etype=Enum, *, boundary=None, use_args=None): body['_boundary_'] = boundary or etype._boundary_ body['_flag_mask_'] = None body['_all_bits_'] = None + body['_singles_mask_'] = None body['_inverted_'] = None body['__or__'] = Flag.__or__ body['__xor__'] = Flag.__xor__ @@ -1711,10 +1745,12 @@ def _simple_enum(etype=Enum, *, boundary=None, use_args=None): value = gnv(name, 1, len(member_names), gnv_last_values) if value in value2member_map: # an alias to an existing member + member = value2member_map[value] redirect = property() + redirect.member = member redirect.__set_name__(enum_class, name) setattr(enum_class, name, redirect) - member_map[name] = value2member_map[value] + member_map[name] = member else: # create the member if use_args: @@ -1730,6 +1766,7 @@ def _simple_enum(etype=Enum, *, boundary=None, use_args=None): member.__objclass__ = enum_class member.__init__(value) redirect = property() + redirect.member = member redirect.__set_name__(enum_class, name) setattr(enum_class, name, redirect) member_map[name] = member @@ -1742,7 +1779,8 @@ def _simple_enum(etype=Enum, *, boundary=None, use_args=None): else: multi_bits |= value gnv_last_values.append(value) - enum_class._flag_mask_ = single_bits + enum_class._flag_mask_ = single_bits | multi_bits + enum_class._singles_mask_ = single_bits enum_class._all_bits_ = 2 ** ((single_bits|multi_bits).bit_length()) - 1 # set correct __iter__ member_list = [m._value_ for m in enum_class] @@ -1757,10 +1795,12 @@ def _simple_enum(etype=Enum, *, boundary=None, use_args=None): value = value.value if value in value2member_map: # an alias to an existing member + member = value2member_map[value] redirect = property() + redirect.member = member redirect.__set_name__(enum_class, name) setattr(enum_class, name, redirect) - member_map[name] = value2member_map[value] + member_map[name] = member else: # create the member if use_args: @@ -1777,6 +1817,7 @@ def _simple_enum(etype=Enum, *, boundary=None, use_args=None): member.__init__(value) member._sort_order_ = len(member_names) redirect = property() + redirect.member = member redirect.__set_name__(enum_class, name) setattr(enum_class, name, redirect) member_map[name] = member @@ -2034,7 +2075,6 @@ def _old_convert_(etype, name, module, filter, source=None, *, boundary=None): # unless some values aren't comparable, in which case sort by name members.sort(key=lambda t: t[0]) cls = etype(name, members, module=module, boundary=boundary or KEEP) - cls.__reduce_ex__ = _reduce_ex_by_global_name return cls _stdlib_enums = IntEnum, StrEnum, IntFlag diff --git a/Lib/filecmp.py b/Lib/filecmp.py index 70a4b23c..30bd900f 100644 --- a/Lib/filecmp.py +++ b/Lib/filecmp.py @@ -157,17 +157,17 @@ class dircmp: a_path = os.path.join(self.left, x) b_path = os.path.join(self.right, x) - ok = 1 + ok = True try: a_stat = os.stat(a_path) except OSError: # print('Can\'t stat', a_path, ':', why.args[1]) - ok = 0 + ok = False try: b_stat = os.stat(b_path) except OSError: # print('Can\'t stat', b_path, ':', why.args[1]) - ok = 0 + ok = False if ok: a_type = stat.S_IFMT(a_stat.st_mode) @@ -242,7 +242,7 @@ class dircmp: methodmap = dict(subdirs=phase4, same_files=phase3, diff_files=phase3, funny_files=phase3, - common_dirs = phase2, common_files=phase2, common_funny=phase2, + common_dirs=phase2, common_files=phase2, common_funny=phase2, common=phase1, left_only=phase1, right_only=phase1, left_list=phase0, right_list=phase0) diff --git a/Lib/fileinput.py b/Lib/fileinput.py index e234dc9e..1b25f28f 100644 --- a/Lib/fileinput.py +++ b/Lib/fileinput.py @@ -399,7 +399,7 @@ class FileInput: def hook_compressed(filename, mode, *, encoding=None, errors=None): - if encoding is None: # EncodingWarning is emitted in FileInput() already. + if encoding is None and "b" not in mode: # EncodingWarning is emitted in FileInput() already. encoding = "locale" ext = os.path.splitext(filename)[1] if ext == '.gz': diff --git a/Lib/fractions.py b/Lib/fractions.py index f9ac882e..c95db073 100644 --- a/Lib/fractions.py +++ b/Lib/fractions.py @@ -4,6 +4,7 @@ """Fraction, infinite-precision, rational numbers.""" from decimal import Decimal +import functools import math import numbers import operator @@ -20,13 +21,46 @@ _PyHASH_MODULUS = sys.hash_info.modulus # _PyHASH_MODULUS. _PyHASH_INF = sys.hash_info.inf +@functools.lru_cache(maxsize = 1 << 14) +def _hash_algorithm(numerator, denominator): + + # To make sure that the hash of a Fraction agrees with the hash + # of a numerically equal integer, float or Decimal instance, we + # follow the rules for numeric hashes outlined in the + # documentation. (See library docs, 'Built-in Types'). + + try: + dinv = pow(denominator, -1, _PyHASH_MODULUS) + except ValueError: + # ValueError means there is no modular inverse. + hash_ = _PyHASH_INF + else: + # The general algorithm now specifies that the absolute value of + # the hash is + # (|N| * dinv) % P + # where N is self._numerator and P is _PyHASH_MODULUS. That's + # optimized here in two ways: first, for a non-negative int i, + # hash(i) == i % P, but the int hash implementation doesn't need + # to divide, and is faster than doing % P explicitly. So we do + # hash(|N| * dinv) + # instead. Second, N is unbounded, so its product with dinv may + # be arbitrarily expensive to compute. The final answer is the + # same if we use the bounded |N| % P instead, which can again + # be done with an int hash() call. If 0 <= i < P, hash(i) == i, + # so this nested hash() call wastes a bit of time making a + # redundant copy when |N| < P, but can save an arbitrarily large + # amount of computation for large |N|. + hash_ = hash(hash(abs(numerator)) * dinv) + result = hash_ if numerator >= 0 else -hash_ + return -2 if result == -1 else result + _RATIONAL_FORMAT = re.compile(r""" \A\s* # optional whitespace at the start, (?P<sign>[-+]?) # an optional sign, then (?=\d|\.\d) # lookahead for digit or .digit (?P<num>\d*|\d+(_\d+)*) # numerator (possibly empty) (?: # followed by - (?:/(?P<denom>\d+(_\d+)*))? # an optional denominator + (?:\s*/\s*(?P<denom>\d+(_\d+)*))? # an optional denominator | # or (?:\.(?P<decimal>d*|\d+(_\d+)*))? # an optional fractional part (?:E(?P<exp>[-+]?\d+(_\d+)*))? # and optional exponent @@ -35,6 +69,96 @@ _RATIONAL_FORMAT = re.compile(r""" """, re.VERBOSE | re.IGNORECASE) +# Helpers for formatting + +def _round_to_exponent(n, d, exponent, no_neg_zero=False): + """Round a rational number to the nearest multiple of a given power of 10. + + Rounds the rational number n/d to the nearest integer multiple of + 10**exponent, rounding to the nearest even integer multiple in the case of + a tie. Returns a pair (sign: bool, significand: int) representing the + rounded value (-1)**sign * significand * 10**exponent. + + If no_neg_zero is true, then the returned sign will always be False when + the significand is zero. Otherwise, the sign reflects the sign of the + input. + + d must be positive, but n and d need not be relatively prime. + """ + if exponent >= 0: + d *= 10**exponent + else: + n *= 10**-exponent + + # The divmod quotient is correct for round-ties-towards-positive-infinity; + # In the case of a tie, we zero out the least significant bit of q. + q, r = divmod(n + (d >> 1), d) + if r == 0 and d & 1 == 0: + q &= -2 + + sign = q < 0 if no_neg_zero else n < 0 + return sign, abs(q) + + +def _round_to_figures(n, d, figures): + """Round a rational number to a given number of significant figures. + + Rounds the rational number n/d to the given number of significant figures + using the round-ties-to-even rule, and returns a triple + (sign: bool, significand: int, exponent: int) representing the rounded + value (-1)**sign * significand * 10**exponent. + + In the special case where n = 0, returns a significand of zero and + an exponent of 1 - figures, for compatibility with formatting. + Otherwise, the returned significand satisfies + 10**(figures - 1) <= significand < 10**figures. + + d must be positive, but n and d need not be relatively prime. + figures must be positive. + """ + # Special case for n == 0. + if n == 0: + return False, 0, 1 - figures + + # Find integer m satisfying 10**(m - 1) <= abs(n)/d <= 10**m. (If abs(n)/d + # is a power of 10, either of the two possible values for m is fine.) + str_n, str_d = str(abs(n)), str(d) + m = len(str_n) - len(str_d) + (str_d <= str_n) + + # Round to a multiple of 10**(m - figures). The significand we get + # satisfies 10**(figures - 1) <= significand <= 10**figures. + exponent = m - figures + sign, significand = _round_to_exponent(n, d, exponent) + + # Adjust in the case where significand == 10**figures, to ensure that + # 10**(figures - 1) <= significand < 10**figures. + if len(str(significand)) == figures + 1: + significand //= 10 + exponent += 1 + + return sign, significand, exponent + + +# Pattern for matching float-style format specifications; +# supports 'e', 'E', 'f', 'F', 'g', 'G' and '%' presentation types. +_FLOAT_FORMAT_SPECIFICATION_MATCHER = re.compile(r""" + (?: + (?P<fill>.)? + (?P<align>[<>=^]) + )? + (?P<sign>[-+ ]?) + (?P<no_neg_zero>z)? + (?P<alt>\#)? + # A '0' that's *not* followed by another digit is parsed as a minimum width + # rather than a zeropad flag. + (?P<zeropad>0(?=[0-9]))? + (?P<minimumwidth>0|[1-9][0-9]*)? + (?P<thousands_sep>[,_])? + (?:\.(?P<precision>0|[1-9][0-9]*))? + (?P<presentation_type>[eEfFgG%]) +""", re.DOTALL | re.VERBOSE).fullmatch + + class Fraction(numbers.Rational): """This class implements rational numbers. @@ -59,7 +183,7 @@ class Fraction(numbers.Rational): __slots__ = ('_numerator', '_denominator') # We're immutable, so use __new__ not __init__ - def __new__(cls, numerator=0, denominator=None, *, _normalize=True): + def __new__(cls, numerator=0, denominator=None): """Constructs a Rational. Takes a string like '3/2' or '1.5', another Rational instance, a @@ -155,12 +279,11 @@ class Fraction(numbers.Rational): if denominator == 0: raise ZeroDivisionError('Fraction(%s, 0)' % numerator) - if _normalize: - g = math.gcd(numerator, denominator) - if denominator < 0: - g = -g - numerator //= g - denominator //= g + g = math.gcd(numerator, denominator) + if denominator < 0: + g = -g + numerator //= g + denominator //= g self._numerator = numerator self._denominator = denominator return self @@ -177,7 +300,7 @@ class Fraction(numbers.Rational): elif not isinstance(f, float): raise TypeError("%s.from_float() only takes floats, not %r (%s)" % (cls.__name__, f, type(f).__name__)) - return cls(*f.as_integer_ratio()) + return cls._from_coprime_ints(*f.as_integer_ratio()) @classmethod def from_decimal(cls, dec): @@ -189,13 +312,28 @@ class Fraction(numbers.Rational): raise TypeError( "%s.from_decimal() only takes Decimals, not %r (%s)" % (cls.__name__, dec, type(dec).__name__)) - return cls(*dec.as_integer_ratio()) + return cls._from_coprime_ints(*dec.as_integer_ratio()) + + @classmethod + def _from_coprime_ints(cls, numerator, denominator, /): + """Convert a pair of ints to a rational number, for internal use. + + The ratio of integers should be in lowest terms and the denominator + should be positive. + """ + obj = super(Fraction, cls).__new__(cls) + obj._numerator = numerator + obj._denominator = denominator + return obj + + def is_integer(self): + """Return True if the Fraction is an integer.""" + return self._denominator == 1 def as_integer_ratio(self): - """Return the integer ratio as a tuple. + """Return a pair of integers, whose ratio is equal to the original Fraction. - Return a tuple of two integers, whose ratio is equal to the - Fraction and with a positive denominator. + The ratio is in lowest terms and has a positive denominator. """ return (self._numerator, self._denominator) @@ -245,14 +383,16 @@ class Fraction(numbers.Rational): break p0, q0, p1, q1 = p1, q1, p0+a*p1, q2 n, d = d, n-a*d - k = (max_denominator-q0)//q1 - bound1 = Fraction(p0+k*p1, q0+k*q1) - bound2 = Fraction(p1, q1) - if abs(bound2 - self) <= abs(bound1-self): - return bound2 + + # Determine which of the candidates (p0+k*p1)/(q0+k*q1) and p1/q1 is + # closer to self. The distance between them is 1/(q1*(q0+k*q1)), while + # the distance from p1/q1 to self is d/(q1*self._denominator). So we + # need to compare 2*(q0+k*q1) with self._denominator/d. + if 2*d*(q0+k*q1) <= self._denominator: + return Fraction._from_coprime_ints(p1, q1) else: - return bound1 + return Fraction._from_coprime_ints(p0+k*p1, q0+k*q1) @property def numerator(a): @@ -274,6 +414,122 @@ class Fraction(numbers.Rational): else: return '%s/%s' % (self._numerator, self._denominator) + def __format__(self, format_spec, /): + """Format this fraction according to the given format specification.""" + + # Backwards compatiblility with existing formatting. + if not format_spec: + return str(self) + + # Validate and parse the format specifier. + match = _FLOAT_FORMAT_SPECIFICATION_MATCHER(format_spec) + if match is None: + raise ValueError( + f"Invalid format specifier {format_spec!r} " + f"for object of type {type(self).__name__!r}" + ) + elif match["align"] is not None and match["zeropad"] is not None: + # Avoid the temptation to guess. + raise ValueError( + f"Invalid format specifier {format_spec!r} " + f"for object of type {type(self).__name__!r}; " + "can't use explicit alignment when zero-padding" + ) + fill = match["fill"] or " " + align = match["align"] or ">" + pos_sign = "" if match["sign"] == "-" else match["sign"] + no_neg_zero = bool(match["no_neg_zero"]) + alternate_form = bool(match["alt"]) + zeropad = bool(match["zeropad"]) + minimumwidth = int(match["minimumwidth"] or "0") + thousands_sep = match["thousands_sep"] + precision = int(match["precision"] or "6") + presentation_type = match["presentation_type"] + trim_zeros = presentation_type in "gG" and not alternate_form + trim_point = not alternate_form + exponent_indicator = "E" if presentation_type in "EFG" else "e" + + # Round to get the digits we need, figure out where to place the point, + # and decide whether to use scientific notation. 'point_pos' is the + # relative to the _end_ of the digit string: that is, it's the number + # of digits that should follow the point. + if presentation_type in "fF%": + exponent = -precision + if presentation_type == "%": + exponent -= 2 + negative, significand = _round_to_exponent( + self._numerator, self._denominator, exponent, no_neg_zero) + scientific = False + point_pos = precision + else: # presentation_type in "eEgG" + figures = ( + max(precision, 1) + if presentation_type in "gG" + else precision + 1 + ) + negative, significand, exponent = _round_to_figures( + self._numerator, self._denominator, figures) + scientific = ( + presentation_type in "eE" + or exponent > 0 + or exponent + figures <= -4 + ) + point_pos = figures - 1 if scientific else -exponent + + # Get the suffix - the part following the digits, if any. + if presentation_type == "%": + suffix = "%" + elif scientific: + suffix = f"{exponent_indicator}{exponent + point_pos:+03d}" + else: + suffix = "" + + # String of output digits, padded sufficiently with zeros on the left + # so that we'll have at least one digit before the decimal point. + digits = f"{significand:0{point_pos + 1}d}" + + # Before padding, the output has the form f"{sign}{leading}{trailing}", + # where `leading` includes thousands separators if necessary and + # `trailing` includes the decimal separator where appropriate. + sign = "-" if negative else pos_sign + leading = digits[: len(digits) - point_pos] + frac_part = digits[len(digits) - point_pos :] + if trim_zeros: + frac_part = frac_part.rstrip("0") + separator = "" if trim_point and not frac_part else "." + trailing = separator + frac_part + suffix + + # Do zero padding if required. + if zeropad: + min_leading = minimumwidth - len(sign) - len(trailing) + # When adding thousands separators, they'll be added to the + # zero-padded portion too, so we need to compensate. + leading = leading.zfill( + 3 * min_leading // 4 + 1 if thousands_sep else min_leading + ) + + # Insert thousands separators if required. + if thousands_sep: + first_pos = 1 + (len(leading) - 1) % 3 + leading = leading[:first_pos] + "".join( + thousands_sep + leading[pos : pos + 3] + for pos in range(first_pos, len(leading), 3) + ) + + # We now have a sign and a body. Pad with fill character if necessary + # and return. + body = leading + trailing + padding = fill * (minimumwidth - len(sign) - len(body)) + if align == ">": + return padding + sign + body + elif align == "<": + return sign + body + padding + elif align == "^": + half = len(padding) // 2 + return padding[:half] + sign + body + padding[half:] + else: # align == "=" + return sign + padding + body + def _operator_fallbacks(monomorphic_operator, fallback_operator): """Generates forward and reverse operators given a purely-rational operator and a function from the operator module. @@ -355,8 +611,10 @@ class Fraction(numbers.Rational): """ def forward(a, b): - if isinstance(b, (int, Fraction)): + if isinstance(b, Fraction): return monomorphic_operator(a, b) + elif isinstance(b, int): + return monomorphic_operator(a, Fraction(b)) elif isinstance(b, float): return fallback_operator(float(a), b) elif isinstance(b, complex): @@ -369,7 +627,7 @@ class Fraction(numbers.Rational): def reverse(b, a): if isinstance(a, numbers.Rational): # Includes ints. - return monomorphic_operator(a, b) + return monomorphic_operator(Fraction(a), b) elif isinstance(a, numbers.Real): return fallback_operator(float(a), float(b)) elif isinstance(a, numbers.Complex): @@ -451,40 +709,40 @@ class Fraction(numbers.Rational): def _add(a, b): """a + b""" - na, da = a.numerator, a.denominator - nb, db = b.numerator, b.denominator + na, da = a._numerator, a._denominator + nb, db = b._numerator, b._denominator g = math.gcd(da, db) if g == 1: - return Fraction(na * db + da * nb, da * db, _normalize=False) + return Fraction._from_coprime_ints(na * db + da * nb, da * db) s = da // g t = na * (db // g) + nb * s g2 = math.gcd(t, g) if g2 == 1: - return Fraction(t, s * db, _normalize=False) - return Fraction(t // g2, s * (db // g2), _normalize=False) + return Fraction._from_coprime_ints(t, s * db) + return Fraction._from_coprime_ints(t // g2, s * (db // g2)) __add__, __radd__ = _operator_fallbacks(_add, operator.add) def _sub(a, b): """a - b""" - na, da = a.numerator, a.denominator - nb, db = b.numerator, b.denominator + na, da = a._numerator, a._denominator + nb, db = b._numerator, b._denominator g = math.gcd(da, db) if g == 1: - return Fraction(na * db - da * nb, da * db, _normalize=False) + return Fraction._from_coprime_ints(na * db - da * nb, da * db) s = da // g t = na * (db // g) - nb * s g2 = math.gcd(t, g) if g2 == 1: - return Fraction(t, s * db, _normalize=False) - return Fraction(t // g2, s * (db // g2), _normalize=False) + return Fraction._from_coprime_ints(t, s * db) + return Fraction._from_coprime_ints(t // g2, s * (db // g2)) __sub__, __rsub__ = _operator_fallbacks(_sub, operator.sub) def _mul(a, b): """a * b""" - na, da = a.numerator, a.denominator - nb, db = b.numerator, b.denominator + na, da = a._numerator, a._denominator + nb, db = b._numerator, b._denominator g1 = math.gcd(na, db) if g1 > 1: na //= g1 @@ -493,15 +751,17 @@ class Fraction(numbers.Rational): if g2 > 1: nb //= g2 da //= g2 - return Fraction(na * nb, db * da, _normalize=False) + return Fraction._from_coprime_ints(na * nb, db * da) __mul__, __rmul__ = _operator_fallbacks(_mul, operator.mul) def _div(a, b): """a / b""" # Same as _mul(), with inversed b. - na, da = a.numerator, a.denominator - nb, db = b.numerator, b.denominator + nb, db = b._numerator, b._denominator + if nb == 0: + raise ZeroDivisionError('Fraction(%s, 0)' % db) + na, da = a._numerator, a._denominator g1 = math.gcd(na, nb) if g1 > 1: na //= g1 @@ -513,7 +773,7 @@ class Fraction(numbers.Rational): n, d = na * db, nb * da if d < 0: n, d = -n, -d - return Fraction(n, d, _normalize=False) + return Fraction._from_coprime_ints(n, d) __truediv__, __rtruediv__ = _operator_fallbacks(_div, operator.truediv) @@ -550,17 +810,17 @@ class Fraction(numbers.Rational): if b.denominator == 1: power = b.numerator if power >= 0: - return Fraction(a._numerator ** power, - a._denominator ** power, - _normalize=False) - elif a._numerator >= 0: - return Fraction(a._denominator ** -power, - a._numerator ** -power, - _normalize=False) + return Fraction._from_coprime_ints(a._numerator ** power, + a._denominator ** power) + elif a._numerator > 0: + return Fraction._from_coprime_ints(a._denominator ** -power, + a._numerator ** -power) + elif a._numerator == 0: + raise ZeroDivisionError('Fraction(%s, 0)' % + a._denominator ** -power) else: - return Fraction((-a._denominator) ** -power, - (-a._numerator) ** -power, - _normalize=False) + return Fraction._from_coprime_ints((-a._denominator) ** -power, + (-a._numerator) ** -power) else: # A fractional power will generally produce an # irrational number. @@ -584,15 +844,15 @@ class Fraction(numbers.Rational): def __pos__(a): """+a: Coerces a subclass instance to Fraction""" - return Fraction(a._numerator, a._denominator, _normalize=False) + return Fraction._from_coprime_ints(a._numerator, a._denominator) def __neg__(a): """-a""" - return Fraction(-a._numerator, a._denominator, _normalize=False) + return Fraction._from_coprime_ints(-a._numerator, a._denominator) def __abs__(a): """abs(a)""" - return Fraction(abs(a._numerator), a._denominator, _normalize=False) + return Fraction._from_coprime_ints(abs(a._numerator), a._denominator) def __int__(a, _index=operator.index): """int(a)""" @@ -610,12 +870,12 @@ class Fraction(numbers.Rational): def __floor__(a): """math.floor(a)""" - return a.numerator // a.denominator + return a._numerator // a._denominator def __ceil__(a): """math.ceil(a)""" # The negations cleverly convince floordiv to return the ceiling. - return -(-a.numerator // a.denominator) + return -(-a._numerator // a._denominator) def __round__(self, ndigits=None): """round(self, ndigits) @@ -623,10 +883,11 @@ class Fraction(numbers.Rational): Rounds half toward even. """ if ndigits is None: - floor, remainder = divmod(self.numerator, self.denominator) - if remainder * 2 < self.denominator: + d = self._denominator + floor, remainder = divmod(self._numerator, d) + if remainder * 2 < d: return floor - elif remainder * 2 > self.denominator: + elif remainder * 2 > d: return floor + 1 # Deal with the half case: elif floor % 2 == 0: @@ -644,36 +905,7 @@ class Fraction(numbers.Rational): def __hash__(self): """hash(self)""" - - # To make sure that the hash of a Fraction agrees with the hash - # of a numerically equal integer, float or Decimal instance, we - # follow the rules for numeric hashes outlined in the - # documentation. (See library docs, 'Built-in Types'). - - try: - dinv = pow(self._denominator, -1, _PyHASH_MODULUS) - except ValueError: - # ValueError means there is no modular inverse. - hash_ = _PyHASH_INF - else: - # The general algorithm now specifies that the absolute value of - # the hash is - # (|N| * dinv) % P - # where N is self._numerator and P is _PyHASH_MODULUS. That's - # optimized here in two ways: first, for a non-negative int i, - # hash(i) == i % P, but the int hash implementation doesn't need - # to divide, and is faster than doing % P explicitly. So we do - # hash(|N| * dinv) - # instead. Second, N is unbounded, so its product with dinv may - # be arbitrarily expensive to compute. The final answer is the - # same if we use the bounded |N| % P instead, which can again - # be done with an int hash() call. If 0 <= i < P, hash(i) == i, - # so this nested hash() call wastes a bit of time making a - # redundant copy when |N| < P, but can save an arbitrarily large - # amount of computation for large |N|. - hash_ = hash(hash(abs(self._numerator)) * dinv) - result = hash_ if self._numerator >= 0 else -hash_ - return -2 if result == -1 else result + return _hash_algorithm(self._numerator, self._denominator) def __eq__(a, b): """a == b""" diff --git a/Lib/ftplib.py b/Lib/ftplib.py index 7c5a5071..a56e0c30 100644 --- a/Lib/ftplib.py +++ b/Lib/ftplib.py @@ -434,10 +434,7 @@ class FTP: """ self.voidcmd('TYPE I') with self.transfercmd(cmd, rest) as conn: - while 1: - data = conn.recv(blocksize) - if not data: - break + while data := conn.recv(blocksize): callback(data) # shutdown ssl layer if _SSLSocket is not None and isinstance(conn, _SSLSocket): @@ -496,10 +493,7 @@ class FTP: """ self.voidcmd('TYPE I') with self.transfercmd(cmd, rest) as conn: - while 1: - buf = fp.read(blocksize) - if not buf: - break + while buf := fp.read(blocksize): conn.sendall(buf) if callback: callback(buf) @@ -561,7 +555,7 @@ class FTP: LIST command. (This *should* only be used for a pathname.)''' cmd = 'LIST' func = None - if args[-1:] and type(args[-1]) != type(''): + if args[-1:] and not isinstance(args[-1], str): args, func = args[:-1], args[-1] for arg in args: if arg: @@ -713,28 +707,12 @@ else: '221 Goodbye.' >>> ''' - ssl_version = ssl.PROTOCOL_TLS_CLIENT def __init__(self, host='', user='', passwd='', acct='', - keyfile=None, certfile=None, context=None, - timeout=_GLOBAL_DEFAULT_TIMEOUT, source_address=None, *, - encoding='utf-8'): - if context is not None and keyfile is not None: - raise ValueError("context and keyfile arguments are mutually " - "exclusive") - if context is not None and certfile is not None: - raise ValueError("context and certfile arguments are mutually " - "exclusive") - if keyfile is not None or certfile is not None: - import warnings - warnings.warn("keyfile and certfile are deprecated, use a " - "custom context instead", DeprecationWarning, 2) - self.keyfile = keyfile - self.certfile = certfile + *, context=None, timeout=_GLOBAL_DEFAULT_TIMEOUT, + source_address=None, encoding='utf-8'): if context is None: - context = ssl._create_stdlib_context(self.ssl_version, - certfile=certfile, - keyfile=keyfile) + context = ssl._create_stdlib_context() self.context = context self._prot_p = False super().__init__(host, user, passwd, acct, @@ -749,7 +727,7 @@ else: '''Set up secure control connection by using TLS/SSL.''' if isinstance(self.sock, ssl.SSLSocket): raise ValueError("Already using TLS") - if self.ssl_version >= ssl.PROTOCOL_TLS: + if self.context.protocol >= ssl.PROTOCOL_TLS: resp = self.voidcmd('AUTH TLS') else: resp = self.voidcmd('AUTH SSL') diff --git a/Lib/functools.py b/Lib/functools.py index 43ead512..2ae4290f 100644 --- a/Lib/functools.py +++ b/Lib/functools.py @@ -30,7 +30,7 @@ from types import GenericAlias # wrapper functions that can handle naive introspection WRAPPER_ASSIGNMENTS = ('__module__', '__name__', '__qualname__', '__doc__', - '__annotations__') + '__annotations__', '__type_params__') WRAPPER_UPDATES = ('__dict__',) def update_wrapper(wrapper, wrapped, @@ -956,18 +956,16 @@ class singledispatchmethod: ################################################################################ -### cached_property() - computed once per instance, cached as attribute +### cached_property() - property result cached as instance attribute ################################################################################ _NOT_FOUND = object() - class cached_property: def __init__(self, func): self.func = func self.attrname = None self.__doc__ = func.__doc__ - self.lock = RLock() def __set_name__(self, owner, name): if self.attrname is None: @@ -994,19 +992,15 @@ class cached_property: raise TypeError(msg) from None val = cache.get(self.attrname, _NOT_FOUND) if val is _NOT_FOUND: - with self.lock: - # check if another thread filled cache while we awaited lock - val = cache.get(self.attrname, _NOT_FOUND) - if val is _NOT_FOUND: - val = self.func(instance) - try: - cache[self.attrname] = val - except TypeError: - msg = ( - f"The '__dict__' attribute on {type(instance).__name__!r} instance " - f"does not support item assignment for caching {self.attrname!r} property." - ) - raise TypeError(msg) from None + val = self.func(instance) + try: + cache[self.attrname] = val + except TypeError: + msg = ( + f"The '__dict__' attribute on {type(instance).__name__!r} instance " + f"does not support item assignment for caching {self.attrname!r} property." + ) + raise TypeError(msg) from None return val __class_getitem__ = classmethod(GenericAlias) diff --git a/Lib/genericpath.py b/Lib/genericpath.py index ce36451a..1bd5b389 100644 --- a/Lib/genericpath.py +++ b/Lib/genericpath.py @@ -7,7 +7,7 @@ import os import stat __all__ = ['commonprefix', 'exists', 'getatime', 'getctime', 'getmtime', - 'getsize', 'isdir', 'isfile', 'samefile', 'sameopenfile', + 'getsize', 'isdir', 'isfile', 'islink', 'samefile', 'sameopenfile', 'samestat'] @@ -45,6 +45,18 @@ def isdir(s): return stat.S_ISDIR(st.st_mode) +# Is a path a symbolic link? +# This will always return false on systems where os.lstat doesn't exist. + +def islink(path): + """Test whether a path is a symbolic link""" + try: + st = os.lstat(path) + except (OSError, ValueError, AttributeError): + return False + return stat.S_ISLNK(st.st_mode) + + def getsize(filename): """Return the size of a file, reported by os.stat().""" return os.stat(filename).st_size diff --git a/Lib/getopt.py b/Lib/getopt.py index 9d4cab1b..5419d77f 100644 --- a/Lib/getopt.py +++ b/Lib/getopt.py @@ -81,7 +81,7 @@ def getopt(args, shortopts, longopts = []): """ opts = [] - if type(longopts) == type(""): + if isinstance(longopts, str): longopts = [longopts] else: longopts = list(longopts) diff --git a/Lib/gettext.py b/Lib/gettext.py index 6c5ec4e5..b72b15f8 100644 --- a/Lib/gettext.py +++ b/Lib/gettext.py @@ -422,10 +422,12 @@ class GNUTranslations(NullTranslations): missing = object() tmsg = self._catalog.get(message, missing) if tmsg is missing: - if self._fallback: - return self._fallback.gettext(message) - return message - return tmsg + tmsg = self._catalog.get((message, self.plural(1)), missing) + if tmsg is not missing: + return tmsg + if self._fallback: + return self._fallback.gettext(message) + return message def ngettext(self, msgid1, msgid2, n): try: @@ -444,10 +446,12 @@ class GNUTranslations(NullTranslations): missing = object() tmsg = self._catalog.get(ctxt_msg_id, missing) if tmsg is missing: - if self._fallback: - return self._fallback.pgettext(context, message) - return message - return tmsg + tmsg = self._catalog.get((ctxt_msg_id, self.plural(1)), missing) + if tmsg is not missing: + return tmsg + if self._fallback: + return self._fallback.pgettext(context, message) + return message def npgettext(self, context, msgid1, msgid2, n): ctxt_msg_id = self.CONTEXT % (context, msgid1) diff --git a/Lib/gzip.py b/Lib/gzip.py index 5b20e5ba..177f9080 100644 --- a/Lib/gzip.py +++ b/Lib/gzip.py @@ -21,6 +21,9 @@ _COMPRESS_LEVEL_FAST = 1 _COMPRESS_LEVEL_TRADEOFF = 6 _COMPRESS_LEVEL_BEST = 9 +READ_BUFFER_SIZE = 128 * 1024 +_WRITE_BUFFER_SIZE = 4 * io.DEFAULT_BUFFER_SIZE + def open(filename, mode="rb", compresslevel=_COMPRESS_LEVEL_BEST, encoding=None, errors=None, newline=None): @@ -118,6 +121,21 @@ class BadGzipFile(OSError): """Exception raised in some cases for invalid gzip files.""" +class _WriteBufferStream(io.RawIOBase): + """Minimal object to pass WriteBuffer flushes into GzipFile""" + def __init__(self, gzip_file): + self.gzip_file = gzip_file + + def write(self, data): + return self.gzip_file._write_raw(data) + + def seekable(self): + return False + + def writable(self): + return True + + class GzipFile(_compression.BaseStream): """The GzipFile class simulates most of the methods of a file object with the exception of the truncate() method. @@ -182,6 +200,7 @@ class GzipFile(_compression.BaseStream): if mode is None: mode = getattr(fileobj, 'mode', 'rb') + if mode.startswith('r'): self.mode = READ raw = _GzipReader(fileobj) @@ -204,6 +223,9 @@ class GzipFile(_compression.BaseStream): zlib.DEF_MEM_LEVEL, 0) self._write_mtime = mtime + self._buffer_size = _WRITE_BUFFER_SIZE + self._buffer = io.BufferedWriter(_WriteBufferStream(self), + buffer_size=self._buffer_size) else: raise ValueError("Invalid mode: {!r}".format(mode)) @@ -212,14 +234,6 @@ class GzipFile(_compression.BaseStream): if self.mode == WRITE: self._write_gzip_header(compresslevel) - @property - def filename(self): - import warnings - warnings.warn("use the name attribute", DeprecationWarning, 2) - if self.mode == WRITE and self.name[-3:] != ".gz": - return self.name + ".gz" - return self.name - @property def mtime(self): """Last modification time read from stream, or None""" @@ -237,6 +251,11 @@ class GzipFile(_compression.BaseStream): self.bufsize = 0 self.offset = 0 # Current file offset for seek(), tell(), etc + def tell(self): + self._check_not_closed() + self._buffer.flush() + return super().tell() + def _write_gzip_header(self, compresslevel): self.fileobj.write(b'\037\213') # magic header self.fileobj.write(b'\010') # compression method @@ -278,6 +297,10 @@ class GzipFile(_compression.BaseStream): if self.fileobj is None: raise ValueError("write() on closed GzipFile object") + return self._buffer.write(data) + + def _write_raw(self, data): + # Called by our self._buffer underlying WriteBufferStream. if isinstance(data, (bytes, bytearray)): length = len(data) else: @@ -328,9 +351,9 @@ class GzipFile(_compression.BaseStream): fileobj = self.fileobj if fileobj is None: return - self.fileobj = None try: if self.mode == WRITE: + self._buffer.flush() fileobj.write(self.compress.flush()) write32u(fileobj, self.crc) # self.size may exceed 2 GiB, or even 4 GiB @@ -338,6 +361,7 @@ class GzipFile(_compression.BaseStream): elif self.mode == READ: self._buffer.close() finally: + self.fileobj = None myfileobj = self.myfileobj if myfileobj: self.myfileobj = None @@ -346,6 +370,7 @@ class GzipFile(_compression.BaseStream): def flush(self,zlib_mode=zlib.Z_SYNC_FLUSH): self._check_not_closed() if self.mode == WRITE: + self._buffer.flush() # Ensure the compressor's buffer is flushed self.fileobj.write(self.compress.flush(zlib_mode)) self.fileobj.flush() @@ -376,6 +401,9 @@ class GzipFile(_compression.BaseStream): def seek(self, offset, whence=io.SEEK_SET): if self.mode == WRITE: + self._check_not_closed() + # Flush buffer to ensure validity of self.offset + self._buffer.flush() if whence != io.SEEK_SET: if whence == io.SEEK_CUR: offset = self.offset + offset @@ -384,10 +412,10 @@ class GzipFile(_compression.BaseStream): if offset < self.offset: raise OSError('Negative seek in write mode') count = offset - self.offset - chunk = b'\0' * 1024 - for i in range(count // 1024): + chunk = b'\0' * self._buffer_size + for i in range(count // self._buffer_size): self.write(chunk) - self.write(b'\0' * (count % 1024)) + self.write(b'\0' * (count % self._buffer_size)) elif self.mode == READ: self._check_not_closed() return self._buffer.seek(offset, whence) @@ -454,7 +482,7 @@ def _read_gzip_header(fp): class _GzipReader(_compression.DecompressReader): def __init__(self, fp): - super().__init__(_PaddedFile(fp), zlib.decompressobj, + super().__init__(_PaddedFile(fp), zlib._ZlibDecompressor, wbits=-zlib.MAX_WBITS) # Set flag indicating start of a new member self._new_member = True @@ -502,12 +530,13 @@ class _GzipReader(_compression.DecompressReader): self._new_member = False # Read a chunk of data from the file - buf = self._fp.read(io.DEFAULT_BUFFER_SIZE) + if self._decompressor.needs_input: + buf = self._fp.read(READ_BUFFER_SIZE) + uncompress = self._decompressor.decompress(buf, size) + else: + uncompress = self._decompressor.decompress(b"", size) - uncompress = self._decompressor.decompress(buf, size) - if self._decompressor.unconsumed_tail != b"": - self._fp.prepend(self._decompressor.unconsumed_tail) - elif self._decompressor.unused_data != b"": + if self._decompressor.unused_data != b"": # Prepend the already read bytes to the fileobj so they can # be seen by _read_eof() and _read_gzip_header() self._fp.prepend(self._decompressor.unused_data) @@ -518,14 +547,11 @@ class _GzipReader(_compression.DecompressReader): raise EOFError("Compressed file ended before the " "end-of-stream marker was reached") - self._add_read_data( uncompress ) + self._crc = zlib.crc32(uncompress, self._crc) + self._stream_size += len(uncompress) self._pos += len(uncompress) return uncompress - def _add_read_data(self, data): - self._crc = zlib.crc32(data, self._crc) - self._stream_size = self._stream_size + len(data) - def _read_eof(self): # We've read to the end of the file # We check that the computed CRC and size of the @@ -655,7 +681,7 @@ def main(): f = builtins.open(arg, "rb") g = open(arg + ".gz", "wb") while True: - chunk = f.read(io.DEFAULT_BUFFER_SIZE) + chunk = f.read(READ_BUFFER_SIZE) if not chunk: break g.write(chunk) diff --git a/Lib/hashlib.py b/Lib/hashlib.py index b546a3fd..1b16441c 100644 --- a/Lib/hashlib.py +++ b/Lib/hashlib.py @@ -65,7 +65,7 @@ algorithms_guaranteed = set(__always_supported) algorithms_available = set(__always_supported) __all__ = __always_supported + ('new', 'algorithms_guaranteed', - 'algorithms_available', 'pbkdf2_hmac', 'file_digest') + 'algorithms_available', 'file_digest') __builtin_constructor_cache = {} @@ -92,13 +92,13 @@ def __get_builtin_constructor(name): import _md5 cache['MD5'] = cache['md5'] = _md5.md5 elif name in {'SHA256', 'sha256', 'SHA224', 'sha224'}: - import _sha256 - cache['SHA224'] = cache['sha224'] = _sha256.sha224 - cache['SHA256'] = cache['sha256'] = _sha256.sha256 + import _sha2 + cache['SHA224'] = cache['sha224'] = _sha2.sha224 + cache['SHA256'] = cache['sha256'] = _sha2.sha256 elif name in {'SHA512', 'sha512', 'SHA384', 'sha384'}: - import _sha512 - cache['SHA384'] = cache['sha384'] = _sha512.sha384 - cache['SHA512'] = cache['sha512'] = _sha512.sha512 + import _sha2 + cache['SHA384'] = cache['sha384'] = _sha2.sha384 + cache['SHA512'] = cache['sha512'] = _sha2.sha512 elif name in {'blake2b', 'blake2s'}: import _blake2 cache['blake2b'] = _blake2.blake2b @@ -180,72 +180,10 @@ except ImportError: try: # OpenSSL's PKCS5_PBKDF2_HMAC requires OpenSSL 1.0+ with HMAC and SHA from _hashlib import pbkdf2_hmac + __all__ += ('pbkdf2_hmac',) except ImportError: - from warnings import warn as _warn - _trans_5C = bytes((x ^ 0x5C) for x in range(256)) - _trans_36 = bytes((x ^ 0x36) for x in range(256)) - - def pbkdf2_hmac(hash_name, password, salt, iterations, dklen=None): - """Password based key derivation function 2 (PKCS #5 v2.0) - - This Python implementations based on the hmac module about as fast - as OpenSSL's PKCS5_PBKDF2_HMAC for short passwords and much faster - for long passwords. - """ - _warn( - "Python implementation of pbkdf2_hmac() is deprecated.", - category=DeprecationWarning, - stacklevel=2 - ) - if not isinstance(hash_name, str): - raise TypeError(hash_name) - - if not isinstance(password, (bytes, bytearray)): - password = bytes(memoryview(password)) - if not isinstance(salt, (bytes, bytearray)): - salt = bytes(memoryview(salt)) - - # Fast inline HMAC implementation - inner = new(hash_name) - outer = new(hash_name) - blocksize = getattr(inner, 'block_size', 64) - if len(password) > blocksize: - password = new(hash_name, password).digest() - password = password + b'\x00' * (blocksize - len(password)) - inner.update(password.translate(_trans_36)) - outer.update(password.translate(_trans_5C)) - - def prf(msg, inner=inner, outer=outer): - # PBKDF2_HMAC uses the password as key. We can re-use the same - # digest objects and just update copies to skip initialization. - icpy = inner.copy() - ocpy = outer.copy() - icpy.update(msg) - ocpy.update(icpy.digest()) - return ocpy.digest() - - if iterations < 1: - raise ValueError(iterations) - if dklen is None: - dklen = outer.digest_size - if dklen < 1: - raise ValueError(dklen) - - dkey = b'' - loop = 1 - from_bytes = int.from_bytes - while len(dkey) < dklen: - prev = prf(salt + loop.to_bytes(4)) - # endianness doesn't matter here as long to / from use the same - rkey = from_bytes(prev) - for i in range(iterations - 1): - prev = prf(prev) - # rkey = rkey ^ prev - rkey ^= from_bytes(prev) - loop += 1 - dkey += rkey.to_bytes(inner.digest_size) - - return dkey[:dklen] + pass + try: # OpenSSL's scrypt requires OpenSSL 1.1+ diff --git a/Lib/html/__init__.py b/Lib/html/__init__.py index da0a0a3c..1543460c 100644 --- a/Lib/html/__init__.py +++ b/Lib/html/__init__.py @@ -25,7 +25,7 @@ def escape(s, quote=True): return s -# see http://www.w3.org/TR/html5/syntax.html#tokenizing-character-references +# see https://html.spec.whatwg.org/multipage/parsing.html#numeric-character-reference-end-state _invalid_charrefs = { 0x00: '\ufffd', # REPLACEMENT CHARACTER diff --git a/Lib/html/entities.py b/Lib/html/entities.py index dc508631..eb6dc121 100644 --- a/Lib/html/entities.py +++ b/Lib/html/entities.py @@ -3,8 +3,7 @@ __all__ = ['html5', 'name2codepoint', 'codepoint2name', 'entitydefs'] -# maps the HTML entity name to the Unicode code point -# from https://html.spec.whatwg.org/multipage/named-characters.html +# maps HTML4 entity name to the Unicode code point name2codepoint = { 'AElig': 0x00c6, # latin capital letter AE = latin capital ligature AE, U+00C6 ISOlat1 'Aacute': 0x00c1, # latin capital letter A with acute, U+00C1 ISOlat1 @@ -261,7 +260,11 @@ name2codepoint = { } -# maps the HTML5 named character references to the equivalent Unicode character(s) +# HTML5 named character references +# Generated by Tools/build/parse_html5_entities.py +# from https://html.spec.whatwg.org/entities.json and +# https://html.spec.whatwg.org/multipage/named-characters.html. +# Map HTML5 named character references to the equivalent Unicode character(s). html5 = { 'Aacute': '\xc1', 'aacute': '\xe1', diff --git a/Lib/html/parser.py b/Lib/html/parser.py index bef0f4fe..13c95c34 100644 --- a/Lib/html/parser.py +++ b/Lib/html/parser.py @@ -89,6 +89,7 @@ class HTMLParser(_markupbase.ParserBase): If convert_charrefs is True (the default), all character references are automatically converted to the corresponding Unicode characters. """ + super().__init__() self.convert_charrefs = convert_charrefs self.reset() @@ -98,7 +99,7 @@ class HTMLParser(_markupbase.ParserBase): self.lasttag = '???' self.interesting = interesting_normal self.cdata_elem = None - _markupbase.ParserBase.reset(self) + super().reset() def feed(self, data): r"""Feed data to the parser. diff --git a/Lib/http/__init__.py b/Lib/http/__init__.py index cd2885dc..e093a1fe 100644 --- a/Lib/http/__init__.py +++ b/Lib/http/__init__.py @@ -31,6 +31,26 @@ class HTTPStatus: obj.description = description return obj + @property + def is_informational(self): + return 100 <= self <= 199 + + @property + def is_success(self): + return 200 <= self <= 299 + + @property + def is_redirection(self): + return 300 <= self <= 399 + + @property + def is_client_error(self): + return 400 <= self <= 499 + + @property + def is_server_error(self): + return 500 <= self <= 599 + # informational CONTINUE = 100, 'Continue', 'Request received, please continue' SWITCHING_PROTOCOLS = (101, 'Switching Protocols', diff --git a/Lib/http/client.py b/Lib/http/client.py index 4622a8f4..b35b1d63 100644 --- a/Lib/http/client.py +++ b/Lib/http/client.py @@ -221,8 +221,9 @@ def _read_headers(fp): break return headers -def parse_headers(fp, _class=HTTPMessage): - """Parses only RFC2822 headers from a file pointer. +def _parse_header_lines(header_lines, _class=HTTPMessage): + """ + Parses only RFC2822 headers from header lines. email Parser wants to see strings rather than bytes. But a TextIOWrapper around self.rfile would buffer too many bytes @@ -231,10 +232,15 @@ def parse_headers(fp, _class=HTTPMessage): to parse. """ - headers = _read_headers(fp) - hstring = b''.join(headers).decode('iso-8859-1') + hstring = b''.join(header_lines).decode('iso-8859-1') return email.parser.Parser(_class=_class).parsestr(hstring) +def parse_headers(fp, _class=HTTPMessage): + """Parses only RFC2822 headers from a file pointer.""" + + headers = _read_headers(fp) + return _parse_header_lines(headers, _class) + class HTTPResponse(io.BufferedIOBase): @@ -448,6 +454,7 @@ class HTTPResponse(io.BufferedIOBase): return self.fp is None def read(self, amt=None): + """Read and return the response body, or up to the next amt bytes.""" if self.fp is None: return b"" @@ -578,11 +585,7 @@ class HTTPResponse(io.BufferedIOBase): assert self.chunked != _UNKNOWN value = [] try: - while True: - chunk_left = self._get_chunk_left() - if chunk_left is None: - break - + while (chunk_left := self._get_chunk_left()) is not None: if amt is not None and amt <= chunk_left: value.append(self._safe_read(amt)) self.chunk_left = chunk_left - amt @@ -786,6 +789,20 @@ class HTTPResponse(io.BufferedIOBase): ''' return self.status + +def _create_https_context(http_version): + # Function also used by urllib.request to be able to set the check_hostname + # attribute on a context object. + context = ssl._create_default_https_context() + # send ALPN extension to indicate HTTP/1.1 protocol + if http_version == 11: + context.set_alpn_protocols(['http/1.1']) + # enable PHA for TLS 1.3 connections if available + if context.post_handshake_auth is not None: + context.post_handshake_auth = True + return context + + class HTTPConnection: _http_vsn = 11 @@ -847,6 +864,7 @@ class HTTPConnection: self._tunnel_host = None self._tunnel_port = None self._tunnel_headers = {} + self._raw_proxy_headers = None (self.host, self.port) = self._get_hostport(host, port) @@ -859,9 +877,9 @@ class HTTPConnection: def set_tunnel(self, host, port=None, headers=None): """Set up host and port for HTTP CONNECT tunnelling. - In a connection that uses HTTP CONNECT tunneling, the host passed to the - constructor is used as a proxy server that relays all communication to - the endpoint passed to `set_tunnel`. This done by sending an HTTP + In a connection that uses HTTP CONNECT tunnelling, the host passed to + the constructor is used as a proxy server that relays all communication + to the endpoint passed to `set_tunnel`. This done by sending an HTTP CONNECT request to the proxy server when the connection is established. This method must be called before the HTTP connection has been @@ -869,6 +887,13 @@ class HTTPConnection: The headers argument should be a mapping of extra HTTP headers to send with the CONNECT request. + + As HTTP/1.1 is used for HTTP CONNECT tunnelling request, as per the RFC + (https://tools.ietf.org/html/rfc7231#section-4.3.6), a HTTP Host: + header must be provided, matching the authority-form of the request + target provided as the destination for the CONNECT request. If a + HTTP Host: header is not provided via the headers argument, one + is generated and transmitted automatically. """ if self.sock: @@ -876,10 +901,15 @@ class HTTPConnection: self._tunnel_host, self._tunnel_port = self._get_hostport(host, port) if headers: - self._tunnel_headers = headers + self._tunnel_headers = headers.copy() else: self._tunnel_headers.clear() + if not any(header.lower() == "host" for header in self._tunnel_headers): + encoded_host = self._tunnel_host.encode("idna").decode("ascii") + self._tunnel_headers["Host"] = "%s:%d" % ( + encoded_host, self._tunnel_port) + def _get_hostport(self, host, port): if port is None: i = host.rfind(':') @@ -904,8 +934,9 @@ class HTTPConnection: self.debuglevel = level def _tunnel(self): - connect = b"CONNECT %s:%d HTTP/1.0\r\n" % ( - self._tunnel_host.encode("ascii"), self._tunnel_port) + connect = b"CONNECT %s:%d %s\r\n" % ( + self._tunnel_host.encode("idna"), self._tunnel_port, + self._http_vsn_str.encode("ascii")) headers = [connect] for header, value in self._tunnel_headers.items(): headers.append(f"{header}: {value}\r\n".encode("latin-1")) @@ -917,23 +948,35 @@ class HTTPConnection: del headers response = self.response_class(self.sock, method=self._method) - (version, code, message) = response._read_status() + try: + (version, code, message) = response._read_status() - if code != http.HTTPStatus.OK: - self.close() - raise OSError(f"Tunnel connection failed: {code} {message.strip()}") - while True: - line = response.fp.readline(_MAXLINE + 1) - if len(line) > _MAXLINE: - raise LineTooLong("header line") - if not line: - # for sites which EOF without sending a trailer - break - if line in (b'\r\n', b'\n', b''): - break + self._raw_proxy_headers = _read_headers(response.fp) if self.debuglevel > 0: - print('header:', line.decode()) + for header in self._raw_proxy_headers: + print('header:', header.decode()) + + if code != http.HTTPStatus.OK: + self.close() + raise OSError(f"Tunnel connection failed: {code} {message.strip()}") + + finally: + response.close() + + def get_proxy_response_headers(self): + """ + Returns a dictionary with the headers of the response + received from the proxy server to the CONNECT request + sent to set the tunnel. + + If the CONNECT request was not sent, the method returns None. + """ + return ( + _parse_header_lines(self._raw_proxy_headers) + if self._raw_proxy_headers is not None + else None + ) def connect(self): """Connect to the host and port specified in __init__.""" @@ -980,14 +1023,11 @@ class HTTPConnection: print("send:", repr(data)) if hasattr(data, "read") : if self.debuglevel > 0: - print("sendIng a read()able") + print("sending a readable") encode = self._is_textIO(data) if encode and self.debuglevel > 0: print("encoding file using iso-8859-1") - while 1: - datablock = data.read(self.blocksize) - if not datablock: - break + while datablock := data.read(self.blocksize): if encode: datablock = datablock.encode("iso-8859-1") sys.audit("http.client.send", self, datablock) @@ -1013,14 +1053,11 @@ class HTTPConnection: def _read_readable(self, readable): if self.debuglevel > 0: - print("sendIng a read()able") + print("reading a readable") encode = self._is_textIO(readable) if encode and self.debuglevel > 0: print("encoding file using iso-8859-1") - while True: - datablock = readable.read(self.blocksize) - if not datablock: - break + while datablock := readable.read(self.blocksize): if encode: datablock = datablock.encode("iso-8859-1") yield datablock @@ -1400,46 +1437,15 @@ else: default_port = HTTPS_PORT - # XXX Should key_file and cert_file be deprecated in favour of context? - - def __init__(self, host, port=None, key_file=None, cert_file=None, - timeout=socket._GLOBAL_DEFAULT_TIMEOUT, - source_address=None, *, context=None, - check_hostname=None, blocksize=8192): + def __init__(self, host, port=None, + *, timeout=socket._GLOBAL_DEFAULT_TIMEOUT, + source_address=None, context=None, blocksize=8192): super(HTTPSConnection, self).__init__(host, port, timeout, source_address, blocksize=blocksize) - if (key_file is not None or cert_file is not None or - check_hostname is not None): - import warnings - warnings.warn("key_file, cert_file and check_hostname are " - "deprecated, use a custom context instead.", - DeprecationWarning, 2) - self.key_file = key_file - self.cert_file = cert_file if context is None: - context = ssl._create_default_https_context() - # send ALPN extension to indicate HTTP/1.1 protocol - if self._http_vsn == 11: - context.set_alpn_protocols(['http/1.1']) - # enable PHA for TLS 1.3 connections if available - if context.post_handshake_auth is not None: - context.post_handshake_auth = True - will_verify = context.verify_mode != ssl.CERT_NONE - if check_hostname is None: - check_hostname = context.check_hostname - if check_hostname and not will_verify: - raise ValueError("check_hostname needs a SSL context with " - "either CERT_OPTIONAL or CERT_REQUIRED") - if key_file or cert_file: - context.load_cert_chain(cert_file, key_file) - # cert and key file means the user wants to authenticate. - # enable TLS 1.3 PHA implicitly even for custom contexts. - if context.post_handshake_auth is not None: - context.post_handshake_auth = True + context = _create_https_context(self._http_vsn) self._context = context - if check_hostname is not None: - self._context.check_hostname = check_hostname def connect(self): "Connect to a host on a given (SSL) port." diff --git a/Lib/http/cookiejar.py b/Lib/http/cookiejar.py index e622fc36..bd89370e 100644 --- a/Lib/http/cookiejar.py +++ b/Lib/http/cookiejar.py @@ -104,9 +104,9 @@ def time2isoz(t=None): """ if t is None: - dt = datetime.datetime.utcnow() + dt = datetime.datetime.now(tz=datetime.UTC) else: - dt = datetime.datetime.utcfromtimestamp(t) + dt = datetime.datetime.fromtimestamp(t, tz=datetime.UTC) return "%04d-%02d-%02d %02d:%02d:%02dZ" % ( dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second) @@ -122,9 +122,9 @@ def time2netscape(t=None): """ if t is None: - dt = datetime.datetime.utcnow() + dt = datetime.datetime.now(tz=datetime.UTC) else: - dt = datetime.datetime.utcfromtimestamp(t) + dt = datetime.datetime.fromtimestamp(t, tz=datetime.UTC) return "%s, %02d-%s-%04d %02d:%02d:%02d GMT" % ( DAYS[dt.weekday()], dt.day, MONTHS[dt.month-1], dt.year, dt.hour, dt.minute, dt.second) @@ -640,7 +640,7 @@ def eff_request_host(request): """ erhn = req_host = request_host(request) - if req_host.find(".") == -1 and not IPV4_RE.search(req_host): + if "." not in req_host: erhn = req_host + ".local" return req_host, erhn @@ -1918,9 +1918,7 @@ class LWPCookieJar(FileCookieJar): "comment", "commenturl") try: - while 1: - line = f.readline() - if line == "": break + while (line := f.readline()) != "": if not line.startswith(header): continue line = line[len(header):].strip() @@ -2020,12 +2018,9 @@ class MozillaCookieJar(FileCookieJar): filename) try: - while 1: - line = f.readline() + while (line := f.readline()) != "": rest = {} - if line == "": break - # httponly is a cookie flag as defined in rfc6265 # when encoded in a netscape cookie file, # the line is prepended with "#HttpOnly_" diff --git a/Lib/http/server.py b/Lib/http/server.py index eef7cbb3..ca6240d9 100644 --- a/Lib/http/server.py +++ b/Lib/http/server.py @@ -300,6 +300,10 @@ class BaseHTTPRequestHandler(socketserver.StreamRequestHandler): # - Leading zeros MUST be ignored by recipients. if len(version_number) != 2: raise ValueError + if any(not component.isdigit() for component in version_number): + raise ValueError("non digit in http version") + if any(len(component) > 10 for component in version_number): + raise ValueError("unreasonable length http version") version_number = int(version_number[0]), int(version_number[1]) except (ValueError, IndexError): self.send_error( @@ -653,6 +657,7 @@ class SimpleHTTPRequestHandler(BaseHTTPRequestHandler): """ server_version = "SimpleHTTP/" + __version__ + index_pages = ("index.html", "index.htm") extensions_map = _encodings_map_default = { '.gz': 'application/gzip', '.Z': 'application/octet-stream', @@ -706,7 +711,7 @@ class SimpleHTTPRequestHandler(BaseHTTPRequestHandler): self.send_header("Content-Length", "0") self.end_headers() return None - for index in "index.html", "index.htm": + for index in self.index_pages: index = os.path.join(path, index) if os.path.isfile(index): path = index @@ -790,7 +795,7 @@ class SimpleHTTPRequestHandler(BaseHTTPRequestHandler): displaypath = urllib.parse.unquote(self.path, errors='surrogatepass') except UnicodeDecodeError: - displaypath = urllib.parse.unquote(path) + displaypath = urllib.parse.unquote(self.path) displaypath = html.escape(displaypath, quote=False) enc = sys.getfilesystemencoding() title = f'Directory listing for {displaypath}' diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt index e64e96f7..f258797c 100644 --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -1,9 +1,28 @@ +What's New in IDLE 3.12.0 +(since 3.11.0) +Released on 2023-10-02 +========================= + + +gh-104719: Remove IDLE's modification of tokenize.tabsize and test +other uses of tokenize data and methods. + +gh-104499: Fix completions for Tk Aqua 8.7 (currently blank). + +gh-104486: Make About print both tcl and tk versions if different, +as is expected someday. + +gh-88496 Fix IDLE test hang on macOS. + +gh-103314 Support sys.last_exc after exceptions in Shell. +Patch by Irit Katriel. + + What's New in IDLE 3.11.0 (since 3.10.0) -Released on 2022-10-03 +Released on 2022-10-24 ========================= - gh-97527: Fix a bug in the previous bugfix that caused IDLE to not start when run with 3.10.8, 3.12.0a1, and at least Microsoft Python 3.10.2288.0 installed without the Lib/test package. 3.11.0 was never diff --git a/Lib/idlelib/autocomplete_w.py b/Lib/idlelib/autocomplete_w.py index 0f835a9c..24320b5a 100644 --- a/Lib/idlelib/autocomplete_w.py +++ b/Lib/idlelib/autocomplete_w.py @@ -182,16 +182,11 @@ class AutoCompleteWindow: self.userwantswindow = userWantsWin self.lasttypedstart = self.start - # Put widgets in place self.autocompletewindow = acw = Toplevel(self.widget) - # Put it in a position so that it is not seen. - acw.wm_geometry("+10000+10000") - # Make it float + acw.withdraw() acw.wm_overrideredirect(1) try: - # This command is only needed and available on Tk >= 8.4.0 for OSX - # Without it, call tips intrude on the typing process by grabbing - # the focus. + # Prevent grabbing focus on macOS. acw.tk.call("::tk::unsupported::MacWindowStyle", "style", acw._w, "help", "noActivates") except TclError: @@ -271,6 +266,7 @@ class AutoCompleteWindow: # place acw above current line new_y -= acw_height acw.wm_geometry("+%d+%d" % (new_x, new_y)) + acw.deiconify() acw.update_idletasks() except TclError: pass diff --git a/Lib/idlelib/calltip_w.py b/Lib/idlelib/calltip_w.py index 1e0404aa..27854606 100644 --- a/Lib/idlelib/calltip_w.py +++ b/Lib/idlelib/calltip_w.py @@ -25,7 +25,7 @@ class CalltipWindow(TooltipBase): text_widget: a Text widget with code for which call-tips are desired """ # Note: The Text widget will be accessible as self.anchor_widget - super(CalltipWindow, self).__init__(text_widget) + super().__init__(text_widget) self.label = self.text = None self.parenline = self.parencol = self.lastline = None @@ -54,7 +54,7 @@ class CalltipWindow(TooltipBase): return self.lastline = curline self.anchor_widget.see("insert") - super(CalltipWindow, self).position_window() + super().position_window() def showtip(self, text, parenleft, parenright): """Show the call-tip, bind events which will close it and reposition it. @@ -73,7 +73,7 @@ class CalltipWindow(TooltipBase): self.parenline, self.parencol = map( int, self.anchor_widget.index(parenleft).split(".")) - super(CalltipWindow, self).showtip() + super().showtip() self._bind_events() @@ -143,7 +143,7 @@ class CalltipWindow(TooltipBase): # ValueError may be raised by MultiCall pass - super(CalltipWindow, self).hidetip() + super().hidetip() def _bind_events(self): """Bind event handlers.""" diff --git a/Lib/idlelib/colorizer.py b/Lib/idlelib/colorizer.py index e9f19c14..b4df3530 100644 --- a/Lib/idlelib/colorizer.py +++ b/Lib/idlelib/colorizer.py @@ -310,7 +310,7 @@ class ColorDelegator(Delegator): # crumb telling the next invocation to resume here # in case update tells us to leave. self.tag_add("TODO", next) - self.update() + self.update_idletasks() if self.stop_colorizing: if DEBUG: print("colorizing stopped") return diff --git a/Lib/idlelib/debugger.py b/Lib/idlelib/debugger.py index ccd03e46..452c62b4 100644 --- a/Lib/idlelib/debugger.py +++ b/Lib/idlelib/debugger.py @@ -49,9 +49,9 @@ class Idb(bdb.Bdb): filename = code.co_filename lineno = frame.f_lineno basename = os.path.basename(filename) - message = "%s:%s" % (basename, lineno) + message = f"{basename}:{lineno}" if code.co_name != "?": - message = "%s: %s()" % (message, code.co_name) + message = f"{message}: {code.co_name}()" return message @@ -213,7 +213,8 @@ class Debugger: m1 = "%s" % str(type) if value is not None: try: - m1 = "%s: %s" % (m1, str(value)) + # TODO redo entire section, tries not needed. + m1 = f"{m1}: {value}" except: pass bg = "yellow" diff --git a/Lib/idlelib/debugobj.py b/Lib/idlelib/debugobj.py index 5a4c9978..71d01c70 100644 --- a/Lib/idlelib/debugobj.py +++ b/Lib/idlelib/debugobj.py @@ -87,7 +87,7 @@ class SequenceTreeItem(ObjectTreeItem): continue def setfunction(value, key=key, object=self.object): object[key] = value - item = make_objecttreeitem("%r:" % (key,), value, setfunction) + item = make_objecttreeitem(f"{key!r}:", value, setfunction) sublist.append(item) return sublist diff --git a/Lib/idlelib/dynoption.py b/Lib/idlelib/dynoption.py index 9c6ffa43..d5dfc3ed 100644 --- a/Lib/idlelib/dynoption.py +++ b/Lib/idlelib/dynoption.py @@ -2,24 +2,19 @@ OptionMenu widget modified to allow dynamic menu reconfiguration and setting of highlightthickness """ -import copy - from tkinter import OptionMenu, _setit, StringVar, Button class DynOptionMenu(OptionMenu): - """ - unlike OptionMenu, our kwargs can include highlightthickness + """Add SetMenu and highlightthickness to OptionMenu. + + Highlightthickness adds space around menu button. """ def __init__(self, master, variable, value, *values, **kwargs): - # TODO copy value instead of whole dict - kwargsCopy=copy.copy(kwargs) - if 'highlightthickness' in list(kwargs.keys()): - del(kwargs['highlightthickness']) + highlightthickness = kwargs.pop('highlightthickness', None) OptionMenu.__init__(self, master, variable, value, *values, **kwargs) - self.config(highlightthickness=kwargsCopy.get('highlightthickness')) - #self.menu=self['menu'] - self.variable=variable - self.command=kwargs.get('command') + self['highlightthickness'] = highlightthickness + self.variable = variable + self.command = kwargs.get('command') def SetMenu(self,valueList,value=None): """ @@ -38,14 +33,15 @@ def _dyn_option_menu(parent): # htest # from tkinter import Toplevel # + StringVar, Button top = Toplevel(parent) - top.title("Tets dynamic option menu") + top.title("Test dynamic option menu") x, y = map(int, parent.geometry().split('+')[1:]) top.geometry("200x100+%d+%d" % (x + 250, y + 175)) top.focus_set() var = StringVar(top) var.set("Old option set") #Set the default value - dyn = DynOptionMenu(top,var, "old1","old2","old3","old4") + dyn = DynOptionMenu(top, var, "old1","old2","old3","old4", + highlightthickness=5) dyn.pack() def update(): @@ -54,5 +50,6 @@ def _dyn_option_menu(parent): # htest # button.pack() if __name__ == '__main__': + # Only module without unittests because of intention to replace. from idlelib.idle_test.htest import run run(_dyn_option_menu) diff --git a/Lib/idlelib/editor.py b/Lib/idlelib/editor.py index 08d6aa2e..69b27d06 100644 --- a/Lib/idlelib/editor.py +++ b/Lib/idlelib/editor.py @@ -38,12 +38,13 @@ darwin = sys.platform == 'darwin' def _sphinx_version(): "Format sys.version_info to produce the Sphinx version string used to install the chm docs" major, minor, micro, level, serial = sys.version_info - release = '%s%s' % (major, minor) - release += '%s' % (micro,) + # TODO remove unneeded function since .chm no longer installed + release = f'{major}{minor}' + release += f'{micro}' if level == 'candidate': - release += 'rc%s' % (serial,) + release += f'rc{serial}' elif level != 'final': - release += '%s%s' % (level[0], serial) + release += f'{level[0]}{serial}' return release @@ -445,6 +446,26 @@ class EditorWindow: self.status_bar.set_label('column', 'Col: %s' % column) self.status_bar.set_label('line', 'Ln: %s' % line) + + """ Menu definitions and functions. + * self.menubar - the always visible horizontal menu bar. + * mainmenu.menudefs - a list of tuples, one for each menubar item. + Each tuple pairs a lower-case name and list of dropdown items. + Each item is a name, virtual event pair or None for separator. + * mainmenu.default_keydefs - maps events to keys. + * text.keydefs - same. + * cls.menu_specs - menubar name, titlecase display form pairs + with Alt-hotkey indicator. A subset of menudefs items. + * self.menudict - map menu name to dropdown menu. + * self.recent_files_menu - 2nd level cascade in the file cascade. + * self.wmenu_end - set in __init__ (purpose unclear). + + createmenubar, postwindowsmenu, update_menu_label, update_menu_state, + ApplyKeybings (2nd part), reset_help_menu_entries, + _extra_help_callback, update_recent_files_list, + apply_bindings, fill_menus, (other functions?) + """ + menu_specs = [ ("file", "_File"), ("edit", "_Edit"), @@ -455,8 +476,22 @@ class EditorWindow: ("help", "_Help"), ] - def createmenubar(self): + """Populate the menu bar widget for the editor window. + + Each option on the menubar is itself a cascade-type Menu widget + with the menubar as the parent. The names, labels, and menu + shortcuts for the menubar items are stored in menu_specs. Each + submenu is subsequently populated in fill_menus(), except for + 'Recent Files' which is added to the File menu here. + + Instance variables: + menubar: Menu widget containing first level menu items. + menudict: Dictionary of {menuname: Menu instance} items. The keys + represent the valid menu items for this window and may be a + subset of all the menudefs available. + recent_files_menu: Menu widget contained within the 'file' menudict. + """ mbar = self.menubar self.menudict = menudict = {} for name, label in self.menu_specs: @@ -479,7 +514,10 @@ class EditorWindow: self.reset_help_menu_entries() def postwindowsmenu(self): - # Only called when Window menu exists + """Callback to register window. + + Only called when Window menu exists. + """ menu = self.menudict['window'] end = menu.index("end") if end is None: @@ -858,8 +896,11 @@ class EditorWindow: self.set_width() def RemoveKeybindings(self): - "Remove the keybindings before they are changed." - # Called from configdialog.py + """Remove the virtual, configurable keybindings. + + Leaves the default Tk Text keybindings. + """ + # Called from configdialog.deactivate_current_config. self.mainmenu.default_keydefs = keydefs = idleConf.GetCurrentKeySet() for event, keylist in keydefs.items(): self.text.event_delete(event, *keylist) @@ -870,15 +911,19 @@ class EditorWindow: self.text.event_delete(event, *keylist) def ApplyKeybindings(self): - "Update the keybindings after they are changed" - # Called from configdialog.py + """Apply the virtual, configurable keybindings. + + Alse update hotkeys to current keyset. + """ + # Called from configdialog.activate_config_changes. self.mainmenu.default_keydefs = keydefs = idleConf.GetCurrentKeySet() self.apply_bindings() for extensionName in self.get_standard_extension_names(): xkeydefs = idleConf.GetExtensionBindings(extensionName) if xkeydefs: self.apply_bindings(xkeydefs) - #update menu accelerators + + # Update menu accelerators. menuEventDict = {} for menu in self.mainmenu.menudefs: menuEventDict[menu[0]] = {} @@ -913,25 +958,25 @@ class EditorWindow: type='int') def reset_help_menu_entries(self): - "Update the additional help entries on the Help menu" + """Update the additional help entries on the Help menu.""" help_list = idleConf.GetAllExtraHelpSourcesList() helpmenu = self.menudict['help'] - # first delete the extra help entries, if any + # First delete the extra help entries, if any. helpmenu_length = helpmenu.index(END) if helpmenu_length > self.base_helpmenu_length: helpmenu.delete((self.base_helpmenu_length + 1), helpmenu_length) - # then rebuild them + # Then rebuild them. if help_list: helpmenu.add_separator() for entry in help_list: - cmd = self.__extra_help_callback(entry[1]) + cmd = self._extra_help_callback(entry[1]) helpmenu.add_command(label=entry[0], command=cmd) - # and update the menu dictionary + # And update the menu dictionary. self.menudict['help'] = helpmenu - def __extra_help_callback(self, helpfile): - "Create a callback with the helpfile value frozen at definition time" - def display_extra_help(helpfile=helpfile): + def _extra_help_callback(self, resource): + """Return a callback that loads resource (file or web page).""" + def display_extra_help(helpfile=resource): if not helpfile.startswith(('www', 'http')): helpfile = os.path.normpath(helpfile) if sys.platform[:3] == 'win': @@ -950,7 +995,7 @@ class EditorWindow: rf_list = [] file_path = self.recent_files_path if file_path and os.path.exists(file_path): - with open(file_path, 'r', + with open(file_path, encoding='utf_8', errors='replace') as rf_list_file: rf_list = rf_list_file.readlines() if new_file: @@ -1157,6 +1202,7 @@ class EditorWindow: self.text.bind(vevent, getattr(ins, methodname)) def apply_bindings(self, keydefs=None): + """Add events with keys to self.text.""" if keydefs is None: keydefs = self.mainmenu.default_keydefs text = self.text @@ -1166,9 +1212,10 @@ class EditorWindow: text.event_add(event, *keylist) def fill_menus(self, menudefs=None, keydefs=None): - """Add appropriate entries to the menus and submenus + """Fill in dropdown menus used by this window. - Menus that are absent or None in self.menudict are ignored. + Items whose name begins with '!' become checkbuttons. + Other names indicate commands. None becomes a separator. """ if menudefs is None: menudefs = self.mainmenu.menudefs @@ -1181,7 +1228,7 @@ class EditorWindow: if not menu: continue for entry in entrylist: - if not entry: + if entry is None: menu.add_separator() else: label, eventname = entry @@ -1217,11 +1264,13 @@ class EditorWindow: else: raise NameError(name) - def get_var_obj(self, name, vartype=None): - var = self.tkinter_vars.get(name) + def get_var_obj(self, eventname, vartype=None): + """Return a tkinter variable instance for the event. + """ + var = self.tkinter_vars.get(eventname) if not var and vartype: - # create a Tkinter variable object with self.text as master: - self.tkinter_vars[name] = var = vartype(self.text) + # Create a Tkinter variable object. + self.tkinter_vars[eventname] = var = vartype(self.text) return var # Tk implementations of "virtual text methods" -- each platform @@ -1458,7 +1507,7 @@ class EditorWindow: else: self.reindent_to(y.compute_backslash_indent()) else: - assert 0, "bogus continuation type %r" % (c,) + assert 0, f"bogus continuation type {c!r}" return "break" # This line starts a brand new statement; indent relative to @@ -1522,7 +1571,7 @@ class EditorWindow: # blocks are found). def guess_indent(self): - opener, indented = IndentSearcher(self.text, self.tabwidth).run() + opener, indented = IndentSearcher(self.text).run() if opener and indented: raw, indentsmall = get_line_indent(opener, self.tabwidth) raw, indentlarge = get_line_indent(indented, self.tabwidth) @@ -1560,15 +1609,10 @@ def get_line_indent(line, tabwidth): class IndentSearcher: + "Manage initial indent guess, returned by run method." - # .run() chews over the Text widget, looking for a block opener - # and the stmt following it. Returns a pair, - # (line containing block opener, line containing stmt) - # Either or both may be None. - - def __init__(self, text, tabwidth): + def __init__(self, text): self.text = text - self.tabwidth = tabwidth self.i = self.finished = 0 self.blkopenline = self.indentedline = None @@ -1584,7 +1628,8 @@ class IndentSearcher: def tokeneater(self, type, token, start, end, line, INDENT=tokenize.INDENT, NAME=tokenize.NAME, - OPENERS=('class', 'def', 'for', 'if', 'try', 'while')): + OPENERS=('class', 'def', 'for', 'if', 'match', 'try', + 'while', 'with')): if self.finished: pass elif type == NAME and token in OPENERS: @@ -1594,26 +1639,33 @@ class IndentSearcher: self.finished = 1 def run(self): - save_tabsize = tokenize.tabsize - tokenize.tabsize = self.tabwidth + """Return 2 lines containing block opener and and indent. + + Either the indent line or both may be None. + """ try: - try: - tokens = tokenize.generate_tokens(self.readline) - for token in tokens: - self.tokeneater(*token) - except (tokenize.TokenError, SyntaxError): - # since we cut off the tokenizer early, we can trigger - # spurious errors - pass - finally: - tokenize.tabsize = save_tabsize + tokens = tokenize.generate_tokens(self.readline) + for token in tokens: + self.tokeneater(*token) + except (tokenize.TokenError, SyntaxError): + # Stopping the tokenizer early can trigger spurious errors. + pass return self.blkopenline, self.indentedline ### end autoindent code ### + def prepstr(s): - # Helper to extract the underscore from a string, e.g. - # prepstr("Co_py") returns (2, "Copy"). + """Extract the underscore from a string. + + For example, prepstr("Co_py") returns (2, "Copy"). + + Args: + s: String with underscore. + + Returns: + Tuple of (position of underscore, string without underscore). + """ i = s.find('_') if i >= 0: s = s[:i] + s[i+1:] @@ -1627,6 +1679,18 @@ keynames = { } def get_accelerator(keydefs, eventname): + """Return a formatted string for the keybinding of an event. + + Convert the first keybinding for a given event to a form that + can be displayed as an accelerator on the menu. + + Args: + keydefs: Dictionary of valid events to keybindings. + eventname: Event to retrieve keybinding for. + + Returns: + Formatted string of the keybinding. + """ keylist = keydefs.get(eventname) # issue10940: temporary workaround to prevent hang with OS X Cocoa Tk 8.5 # if not keylist: @@ -1636,14 +1700,23 @@ def get_accelerator(keydefs, eventname): "<<change-indentwidth>>"}): return "" s = keylist[0] + # Convert strings of the form -singlelowercase to -singleuppercase. s = re.sub(r"-[a-z]\b", lambda m: m.group().upper(), s) + # Convert certain keynames to their symbol. s = re.sub(r"\b\w+\b", lambda m: keynames.get(m.group(), m.group()), s) + # Remove Key- from string. s = re.sub("Key-", "", s) - s = re.sub("Cancel","Ctrl-Break",s) # dscherer@cmu.edu + # Convert Cancel to Ctrl-Break. + s = re.sub("Cancel", "Ctrl-Break", s) # dscherer@cmu.edu + # Convert Control to Ctrl-. s = re.sub("Control-", "Ctrl-", s) + # Change - to +. s = re.sub("-", "+", s) + # Change >< to space. s = re.sub("><", " ", s) + # Remove <. s = re.sub("<", "", s) + # Remove >. s = re.sub(">", "", s) return s diff --git a/Lib/idlelib/filelist.py b/Lib/idlelib/filelist.py index 254f5caf..f87781d2 100644 --- a/Lib/idlelib/filelist.py +++ b/Lib/idlelib/filelist.py @@ -22,7 +22,7 @@ class FileList: # This can happen when bad filename is passed on command line: messagebox.showerror( "File Error", - "%r is a directory." % (filename,), + f"{filename!r} is a directory.", master=self.root) return None key = os.path.normcase(filename) @@ -90,7 +90,7 @@ class FileList: self.inversedict[conflict] = None messagebox.showerror( "Name Conflict", - "You now have multiple edit windows open for %r" % (filename,), + f"You now have multiple edit windows open for {filename!r}", master=self.root) self.dict[newkey] = edit self.inversedict[edit] = newkey diff --git a/Lib/idlelib/help_about.py b/Lib/idlelib/help_about.py index a0085a40..cfa4ca78 100644 --- a/Lib/idlelib/help_about.py +++ b/Lib/idlelib/help_about.py @@ -11,15 +11,12 @@ from tkinter import SUNKEN, TOP, BOTTOM, LEFT, X, BOTH, W, EW, NSEW, E from idlelib import textview -version = python_version() +pyver = python_version() - -def build_bits(): - "Return bits for platform." - if sys.platform == 'darwin': - return '64' if sys.maxsize > 2**32 else '32' - else: - return architecture()[0][:2] +if sys.platform == 'darwin': + bits = '64' if sys.maxsize > 2**32 else '32' +else: + bits = architecture()[0][:2] class AboutDialog(Toplevel): @@ -45,7 +42,7 @@ class AboutDialog(Toplevel): self.create_widgets() self.resizable(height=False, width=False) self.title(title or - f'About IDLE {version} ({build_bits()} bit)') + f'About IDLE {pyver} ({bits} bit)') self.transient(parent) self.grab_set() self.protocol("WM_DELETE_WINDOW", self.ok) @@ -76,8 +73,8 @@ class AboutDialog(Toplevel): bg=self.bg, font=('courier', 24, 'bold')) header.grid(row=0, column=0, sticky=E, padx=10, pady=10) - tk_patchlevel = self.info_patchlevel() - ext = '.png' if tk_patchlevel >= (8, 6) else '.gif' + tkpatch = self._root().getvar('tk_patchLevel') + ext = '.png' if tkpatch >= '8.6' else '.gif' icon = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'Icons', f'idle_48{ext}') self.icon_image = PhotoImage(master=self._root(), file=icon) @@ -102,13 +99,11 @@ class AboutDialog(Toplevel): height=2, bg=self.bg).grid(row=8, column=0, sticky=EW, columnspan=3, padx=5, pady=5) - pyver = Label(frame_background, - text='Python version: ' + version, - fg=self.fg, bg=self.bg) - pyver.grid(row=9, column=0, sticky=W, padx=10, pady=0) - tkver = Label(frame_background, text=f'Tk version: {tk_patchlevel}', - fg=self.fg, bg=self.bg) - tkver.grid(row=9, column=1, sticky=W, padx=2, pady=0) + tclver = str(self.info_patchlevel()) + tkver = ' and ' + tkpatch if tkpatch != tclver else '' + versions = f"Python {pyver} with tcl/tk {tclver}{tkver}" + vers = Label(frame_background, text=versions, fg=self.fg, bg=self.bg) + vers.grid(row=9, column=0, sticky=W, padx=10, pady=0) py_buttons = Frame(frame_background, bg=self.bg) py_buttons.grid(row=10, column=0, columnspan=2, sticky=NSEW) self.py_license = Button(py_buttons, text='License', width=8, @@ -128,10 +123,10 @@ class AboutDialog(Toplevel): height=2, bg=self.bg).grid(row=11, column=0, sticky=EW, columnspan=3, padx=5, pady=5) - idlever = Label(frame_background, - text='IDLE version: ' + version, + idle = Label(frame_background, + text='IDLE', fg=self.fg, bg=self.bg) - idlever.grid(row=12, column=0, sticky=W, padx=10, pady=0) + idle.grid(row=12, column=0, sticky=W, padx=10, pady=0) idle_buttons = Frame(frame_background, bg=self.bg) idle_buttons.grid(row=13, column=0, columnspan=3, sticky=NSEW) self.readme = Button(idle_buttons, text='README', width=8, diff --git a/Lib/idlelib/idle.bat b/Lib/idlelib/idle.bat index 3d619a37..e77b96e9 100644 --- a/Lib/idlelib/idle.bat +++ b/Lib/idlelib/idle.bat @@ -1,4 +1,4 @@ -@echo off -rem Start IDLE using the appropriate Python interpreter -set CURRDIR=%~dp0 -start "IDLE" "%CURRDIR%..\..\pythonw.exe" "%CURRDIR%idle.pyw" %1 %2 %3 %4 %5 %6 %7 %8 %9 +@echo off +rem Start IDLE using the appropriate Python interpreter +set CURRDIR=%~dp0 +start "IDLE" "%CURRDIR%..\..\pythonw.exe" "%CURRDIR%idle.pyw" %1 %2 %3 %4 %5 %6 %7 %8 %9 diff --git a/Lib/idlelib/idle_test/README.txt b/Lib/idlelib/idle_test/README.txt index 566bfd17..cacd06db 100644 --- a/Lib/idlelib/idle_test/README.txt +++ b/Lib/idlelib/idle_test/README.txt @@ -146,14 +146,17 @@ python -m unittest -v idlelib.idle_test python -m test -v -ugui test_idle python -m test.test_idle -The idle tests are 'discovered' by -idlelib.idle_test.__init__.load_tests, which is also imported into -test.test_idle. Normally, neither file should be changed when working on -individual test modules. The third command runs unittest indirectly -through regrtest. The same happens when the entire test suite is run -with 'python -m test'. So that command must work for buildbots to stay -green. Idle tests must not disturb the environment in a way that makes -other tests fail (issue 18081). +IDLE tests are 'discovered' by idlelib.idle_test.__init__.load_tests +when this is imported into test.test_idle. Normally, neither file +should be changed when working on individual test modules. The third +command runs unittest indirectly through regrtest. The same happens when +the entire test suite is run with 'python -m test'. So that command must +work for buildbots to stay green. IDLE tests must not disturb the +environment in a way that makes other tests fail (GH-62281). + +To test subsets of modules, see idlelib.idle_test.__init__. This +can be used to find refleaks or possible sources of "Theme changed" +tcl messages (GH-71383). To run an individual Testcase or test method, extend the dotted name given to unittest on the command line or use the test -m option. The diff --git a/Lib/idlelib/idle_test/__init__.py b/Lib/idlelib/idle_test/__init__.py index ad067b40..79b5d102 100644 --- a/Lib/idlelib/idle_test/__init__.py +++ b/Lib/idlelib/idle_test/__init__.py @@ -1,17 +1,27 @@ -'''idlelib.idle_test is a private implementation of test.test_idle, -which tests the IDLE application as part of the stdlib test suite. -Run IDLE tests alone with "python -m test.test_idle". -Starting with Python 3.6, IDLE requires tcl/tk 8.5 or later. +"""idlelib.idle_test implements test.test_idle, which tests the IDLE +application as part of the stdlib test suite. +Run IDLE tests alone with "python -m test.test_idle (-v)". This package and its contained modules are subject to change and any direct use is at your own risk. -''' +""" from os.path import dirname +# test_idle imports load_tests for test discovery (default all). +# To run subsets of idlelib module tests, insert '[<chars>]' after '_'. +# Example: insert '[ac]' for modules beginning with 'a' or 'c'. +# Additional .discover/.addTest pairs with separate inserts work. +# Example: pairs with 'c' and 'g' test c* files and grep. + def load_tests(loader, standard_tests, pattern): this_dir = dirname(__file__) top_dir = dirname(dirname(this_dir)) - package_tests = loader.discover(start_dir=this_dir, pattern='test*.py', + module_tests = loader.discover(start_dir=this_dir, + pattern='test_*.py', # Insert here. top_level_dir=top_dir) - standard_tests.addTests(package_tests) + standard_tests.addTests(module_tests) +## module_tests = loader.discover(start_dir=this_dir, +## pattern='test_*.py', # Insert here. +## top_level_dir=top_dir) +## standard_tests.addTests(module_tests) return standard_tests diff --git a/Lib/idlelib/idle_test/test_config.py b/Lib/idlelib/idle_test/test_config.py index 697fda52..08ed76fe 100644 --- a/Lib/idlelib/idle_test/test_config.py +++ b/Lib/idlelib/idle_test/test_config.py @@ -191,7 +191,7 @@ class IdleConfTest(unittest.TestCase): idle_dir = os.path.abspath(sys.path[0]) for ctype in conf.config_types: config_path = os.path.join(idle_dir, '../config-%s.def' % ctype) - with open(config_path, 'r') as f: + with open(config_path) as f: cls.config_string[ctype] = f.read() cls.orig_warn = config._warn diff --git a/Lib/idlelib/idle_test/test_editor.py b/Lib/idlelib/idle_test/test_editor.py index fdb47abf..9296a6d2 100644 --- a/Lib/idlelib/idle_test/test_editor.py +++ b/Lib/idlelib/idle_test/test_editor.py @@ -1,10 +1,10 @@ -"Test editor, coverage 35%." +"Test editor, coverage 53%." from idlelib import editor import unittest from collections import namedtuple from test.support import requires -from tkinter import Tk +from tkinter import Tk, Text Editor = editor.EditorWindow @@ -31,7 +31,7 @@ class EditorWindowTest(unittest.TestCase): e._close() -class TestGetLineIndent(unittest.TestCase): +class GetLineIndentTest(unittest.TestCase): def test_empty_lines(self): for tabwidth in [1, 2, 4, 6, 8]: for line in ['', '\n']: @@ -181,6 +181,36 @@ class IndentAndNewlineTest(unittest.TestCase): eq(get('1.0', 'end'), ' def f1(self, a,\n \n return a + b\n') +class IndentSearcherTest(unittest.TestCase): + + @classmethod + def setUpClass(cls): + requires('gui') + cls.root = Tk() + cls.root.withdraw() + cls.text = Text(cls.root) + + @classmethod + def tearDownClass(cls): + cls.root.destroy() + del cls.root + + def test_searcher(self): + text = self.text + searcher = (self.text) + test_info = (# text, (block, indent)) + ("", (None, None)), + ("[1,", (None, None)), # TokenError + ("if 1:\n", ('if 1:\n', None)), + ("if 1:\n 2\n 3\n", ('if 1:\n', ' 2\n')), + ) + for code, expected_pair in test_info: + with self.subTest(code=code): + insert(text, code) + actual_pair = editor.IndentSearcher(text).run() + self.assertEqual(actual_pair, expected_pair) + + class RMenuTest(unittest.TestCase): @classmethod diff --git a/Lib/idlelib/idle_test/test_help_about.py b/Lib/idlelib/idle_test/test_help_about.py index b915535a..8b79487b 100644 --- a/Lib/idlelib/idle_test/test_help_about.py +++ b/Lib/idlelib/idle_test/test_help_about.py @@ -36,7 +36,7 @@ class LiveDialogTest(unittest.TestCase): del cls.root def test_build_bits(self): - self.assertIn(help_about.build_bits(), ('32', '64')) + self.assertIn(help_about.bits, ('32', '64')) def test_dialog_title(self): """Test about dialog title""" @@ -107,7 +107,7 @@ class DefaultTitleTest(unittest.TestCase): """Test about dialog title""" self.assertEqual(self.dialog.title(), f'About IDLE {python_version()}' - f' ({help_about.build_bits()} bit)') + f' ({help_about.bits} bit)') class CloseTest(unittest.TestCase): diff --git a/Lib/idlelib/idle_test/test_iomenu.py b/Lib/idlelib/idle_test/test_iomenu.py index 2fb836db..e0642cf0 100644 --- a/Lib/idlelib/idle_test/test_iomenu.py +++ b/Lib/idlelib/idle_test/test_iomenu.py @@ -8,6 +8,12 @@ from idlelib.editor import EditorWindow from idlelib import util from idlelib.idle_test.mock_idle import Func +# Fail if either tokenize.open and t.detect_encoding does not exist. +# These are used in loadfile and encode. +# Also used in pyshell.MI.execfile and runscript.tabnanny. +from tokenize import open, detect_encoding +# Remove when we have proper tests that use both. + class IOBindingTest(unittest.TestCase): diff --git a/Lib/idlelib/idle_test/test_outwin.py b/Lib/idlelib/idle_test/test_outwin.py index e347bfca..d6e85ad6 100644 --- a/Lib/idlelib/idle_test/test_outwin.py +++ b/Lib/idlelib/idle_test/test_outwin.py @@ -159,7 +159,7 @@ class ModuleFunctionTest(unittest.TestCase): for line, expected_output in test_lines: self.assertEqual(flh(line), expected_output) if expected_output: - mock_open.assert_called_with(expected_output[0], 'r') + mock_open.assert_called_with(expected_output[0]) if __name__ == '__main__': diff --git a/Lib/idlelib/idle_test/test_run.py b/Lib/idlelib/idle_test/test_run.py index ec4637c5..a38e43dc 100644 --- a/Lib/idlelib/idle_test/test_run.py +++ b/Lib/idlelib/idle_test/test_run.py @@ -39,7 +39,8 @@ class ExceptionTest(unittest.TestCase): data = (('1/0', ZeroDivisionError, "division by zero\n"), ('abc', NameError, "name 'abc' is not defined. " - "Did you mean: 'abs'?\n"), + "Did you mean: 'abs'? " + "Or did you forget to import 'abc'?\n"), ('int.reel', AttributeError, "type object 'int' has no attribute 'reel'. " "Did you mean: 'real'?\n"), diff --git a/Lib/idlelib/idle_test/test_sidebar.py b/Lib/idlelib/idle_test/test_sidebar.py index 049531e6..fb52b3a0 100644 --- a/Lib/idlelib/idle_test/test_sidebar.py +++ b/Lib/idlelib/idle_test/test_sidebar.py @@ -57,7 +57,7 @@ class LineNumbersTest(unittest.TestCase): @classmethod def tearDownClass(cls): cls.editwin.per.close() - cls.root.update() + cls.root.update_idletasks() cls.root.destroy() del cls.text, cls.text_frame, cls.editwin, cls.root @@ -328,7 +328,7 @@ class LineNumbersTest(unittest.TestCase): self.assertEqual(self.linenumber.sidebar_text.index('@0,0'), '11.0') # Generate a mouse-wheel event and make sure it scrolled up or down. - # The meaning of the "delta" is OS-dependant, so this just checks for + # The meaning of the "delta" is OS-dependent, so this just checks for # any change. self.linenumber.sidebar_text.event_generate('<MouseWheel>', x=0, y=0, @@ -691,11 +691,12 @@ class ShellSidebarTest(unittest.TestCase): self.assertIsNotNone(text.dlineinfo(text.index(f'{last_lineno}.0'))) # Scroll up using the <MouseWheel> event. - # The meaning delta is platform-dependant. + # The meaning of delta is platform-dependent. delta = -1 if sys.platform == 'darwin' else 120 sidebar.canvas.event_generate('<MouseWheel>', x=0, y=0, delta=delta) yield - self.assertIsNone(text.dlineinfo(text.index(f'{last_lineno}.0'))) + if sys.platform != 'darwin': # .update_idletasks() does not work. + self.assertIsNone(text.dlineinfo(text.index(f'{last_lineno}.0'))) # Scroll back down using the <Button-5> event. sidebar.canvas.event_generate('<Button-5>', x=0, y=0) diff --git a/Lib/idlelib/idle_test/test_stackviewer.py b/Lib/idlelib/idle_test/test_stackviewer.py index 98f53f95..55f51038 100644 --- a/Lib/idlelib/idle_test/test_stackviewer.py +++ b/Lib/idlelib/idle_test/test_stackviewer.py @@ -6,19 +6,12 @@ from test.support import requires from tkinter import Tk from idlelib.tree import TreeNode, ScrolledCanvas -import sys class StackBrowserTest(unittest.TestCase): @classmethod def setUpClass(cls): - svs = stackviewer.sys - try: - abc - except NameError: - svs.last_type, svs.last_value, svs.last_traceback = ( - sys.exc_info()) requires('gui') cls.root = Tk() @@ -26,8 +19,6 @@ class StackBrowserTest(unittest.TestCase): @classmethod def tearDownClass(cls): - svs = stackviewer.sys - del svs.last_traceback, svs.last_type, svs.last_value cls.root.update_idletasks() ## for id in cls.root.tk.call('after', 'info'): @@ -36,7 +27,10 @@ class StackBrowserTest(unittest.TestCase): del cls.root def test_init(self): - sb = stackviewer.StackBrowser(self.root) + try: + abc + except NameError as exc: + sb = stackviewer.StackBrowser(self.root, exc) isi = self.assertIsInstance isi(stackviewer.sc, ScrolledCanvas) isi(stackviewer.item, stackviewer.StackTreeItem) diff --git a/Lib/idlelib/macosx.py b/Lib/idlelib/macosx.py index 89b64570..2ea02ec0 100644 --- a/Lib/idlelib/macosx.py +++ b/Lib/idlelib/macosx.py @@ -174,9 +174,8 @@ def overrideRootMenu(root, flist): del mainmenu.menudefs[-3][1][0:2] menubar = Menu(root) root.configure(menu=menubar) - menudict = {} - menudict['window'] = menu = Menu(menubar, name='window', tearoff=0) + menu = Menu(menubar, name='window', tearoff=0) menubar.add_cascade(label='Window', menu=menu, underline=0) def postwindowsmenu(menu=menu): @@ -226,8 +225,7 @@ def overrideRootMenu(root, flist): if isCarbonTk(): # for Carbon AquaTk, replace the default Tk apple menu - menudict['application'] = menu = Menu(menubar, name='apple', - tearoff=0) + menu = Menu(menubar, name='apple', tearoff=0) menubar.add_cascade(label='IDLE', menu=menu) mainmenu.menudefs.insert(0, ('application', [ diff --git a/Lib/idlelib/multicall.py b/Lib/idlelib/multicall.py index dc020012..0200f445 100644 --- a/Lib/idlelib/multicall.py +++ b/Lib/idlelib/multicall.py @@ -52,9 +52,9 @@ else: _modifier_masks = (MC_CONTROL, MC_ALT, MC_SHIFT, MC_META) # a dictionary to map a modifier name into its number -_modifier_names = dict([(name, number) +_modifier_names = {name: number for number in range(len(_modifiers)) - for name in _modifiers[number]]) + for name in _modifiers[number]} # In 3.4, if no shell window is ever open, the underlying Tk widget is # destroyed before .__del__ methods here are called. The following @@ -134,7 +134,7 @@ def expand_substates(states): return nb statelist = [] for state in states: - substates = list(set(state & x for x in states)) + substates = list({state & x for x in states}) substates.sort(key=nbits, reverse=True) statelist.append(substates) return statelist @@ -258,9 +258,9 @@ _types = ( _binder_classes = (_ComplexBinder,) * 4 + (_SimpleBinder,) * (len(_types)-4) # A dictionary to map a type name into its number -_type_names = dict([(name, number) +_type_names = {name: number for number in range(len(_types)) - for name in _types[number]]) + for name in _types[number]} _keysym_re = re.compile(r"^\w+$") _button_re = re.compile(r"^[1-5]$") diff --git a/Lib/idlelib/outwin.py b/Lib/idlelib/outwin.py index 5ab08bba..610031e2 100644 --- a/Lib/idlelib/outwin.py +++ b/Lib/idlelib/outwin.py @@ -42,7 +42,7 @@ def file_line_helper(line): if match: filename, lineno = match.group(1, 2) try: - f = open(filename, "r") + f = open(filename) f.close() break except OSError: @@ -112,7 +112,7 @@ class OutputWindow(EditorWindow): assert isinstance(s, str) self.text.insert(mark, s, tags) self.text.see(mark) - self.text.update() + self.text.update_idletasks() return len(s) def writelines(self, lines): diff --git a/Lib/idlelib/pyshell.py b/Lib/idlelib/pyshell.py index e68233a5..60287003 100755 --- a/Lib/idlelib/pyshell.py +++ b/Lib/idlelib/pyshell.py @@ -249,7 +249,7 @@ class PyShellEditorWindow(EditorWindow): breaks = self.breakpoints filename = self.io.filename try: - with open(self.breakpointPath, "r") as fp: + with open(self.breakpointPath) as fp: lines = fp.readlines() except OSError: lines = [] @@ -279,7 +279,7 @@ class PyShellEditorWindow(EditorWindow): if filename is None: return if os.path.isfile(self.breakpointPath): - with open(self.breakpointPath, "r") as fp: + with open(self.breakpointPath) as fp: lines = fp.readlines() for line in lines: if line.startswith(filename + '='): @@ -441,7 +441,7 @@ class ModifiedInterpreter(InteractiveInterpreter): # run from the IDLE source directory. del_exitf = idleConf.GetOption('main', 'General', 'delete-exitfunc', default=False, type='bool') - command = "__import__('idlelib.run').run.main(%r)" % (del_exitf,) + command = f"__import__('idlelib.run').run.main({del_exitf!r})" return [sys.executable] + w + ["-c", command, str(self.port)] def start_subprocess(self): @@ -574,9 +574,9 @@ class ModifiedInterpreter(InteractiveInterpreter): self.runcommand("""if 1: import sys as _sys - _sys.path = %r + _sys.path = {!r} del _sys - \n""" % (path,)) + \n""".format(path)) active_seq = None @@ -703,14 +703,14 @@ class ModifiedInterpreter(InteractiveInterpreter): def prepend_syspath(self, filename): "Prepend sys.path with file's directory if not already included" self.runcommand("""if 1: - _filename = %r + _filename = {!r} import sys as _sys from os.path import dirname as _dirname _dir = _dirname(_filename) if not _dir in _sys.path: _sys.path.insert(0, _dir) del _filename, _sys, _dirname, _dir - \n""" % (filename,)) + \n""".format(filename)) def showsyntaxerror(self, filename=None): """Override Interactive Interpreter method: Use Colorizing @@ -1363,19 +1363,19 @@ class PyShell(OutputWindow): self.text.tag_remove(self.user_input_insert_tags, index_before) self.shell_sidebar.update_sidebar() - def open_stack_viewer(self, event=None): + def open_stack_viewer(self, event=None): # -n mode only if self.interp.rpcclt: return self.interp.remote_stack_viewer() + + from idlelib.stackviewer import StackBrowser try: - sys.last_traceback + StackBrowser(self.root, sys.last_exc, self.flist) except: messagebox.showerror("No stack trace", "There is no stack trace yet.\n" - "(sys.last_traceback is not defined)", + "(sys.last_exc is not defined)", parent=self.text) - return - from idlelib.stackviewer import StackBrowser - StackBrowser(self.root, self.flist) + return None def view_restart_mark(self, event=None): self.text.see("iomark") @@ -1536,7 +1536,7 @@ def main(): try: opts, args = getopt.getopt(sys.argv[1:], "c:deihnr:st:") except getopt.error as msg: - print("Error: %s\n%s" % (msg, usage_msg), file=sys.stderr) + print(f"Error: {msg}\n{usage_msg}", file=sys.stderr) sys.exit(2) for o, a in opts: if o == '-c': @@ -1668,9 +1668,9 @@ def main(): if cmd or script: shell.interp.runcommand("""if 1: import sys as _sys - _sys.argv = %r + _sys.argv = {!r} del _sys - \n""" % (sys.argv,)) + \n""".format(sys.argv)) if cmd: shell.interp.execsource(cmd) elif script: diff --git a/Lib/idlelib/redirector.py b/Lib/idlelib/redirector.py index 9ab34c5a..4928340e 100644 --- a/Lib/idlelib/redirector.py +++ b/Lib/idlelib/redirector.py @@ -47,9 +47,8 @@ class WidgetRedirector: tk.createcommand(w, self.dispatch) def __repr__(self): - return "%s(%s<%s>)" % (self.__class__.__name__, - self.widget.__class__.__name__, - self.widget._w) + w = self.widget + return f"{self.__class__.__name__,}({w.__class__.__name__}<{w._w}>)" def close(self): "Unregister operations and revert redirection created by .__init__." @@ -143,8 +142,7 @@ class OriginalCommand: self.orig_and_operation = (redir.orig, operation) def __repr__(self): - return "%s(%r, %r)" % (self.__class__.__name__, - self.redir, self.operation) + return f"{self.__class__.__name__,}({self.redir!r}, {self.operation!r})" def __call__(self, *args): return self.tk_call(self.orig_and_operation + args) diff --git a/Lib/idlelib/rpc.py b/Lib/idlelib/rpc.py index 62eec84c..b08b80c9 100644 --- a/Lib/idlelib/rpc.py +++ b/Lib/idlelib/rpc.py @@ -174,7 +174,7 @@ class SocketIO: except TypeError: return ("ERROR", "Bad request format") if oid not in self.objtable: - return ("ERROR", "Unknown object id: %r" % (oid,)) + return ("ERROR", f"Unknown object id: {oid!r}") obj = self.objtable[oid] if methodname == "__methods__": methods = {} @@ -185,7 +185,7 @@ class SocketIO: _getattributes(obj, attributes) return ("OK", attributes) if not hasattr(obj, methodname): - return ("ERROR", "Unsupported method name: %r" % (methodname,)) + return ("ERROR", f"Unsupported method name: {methodname!r}") method = getattr(obj, methodname) try: if how == 'CALL': diff --git a/Lib/idlelib/run.py b/Lib/idlelib/run.py index 577c49eb..53e80a9b 100644 --- a/Lib/idlelib/run.py +++ b/Lib/idlelib/run.py @@ -52,13 +52,13 @@ def idle_formatwarning(message, category, filename, lineno, line=None): """Format warnings the IDLE way.""" s = "\nWarning (from warnings module):\n" - s += ' File \"%s\", line %s\n' % (filename, lineno) + s += f' File \"{filename}\", line {lineno}\n' if line is None: line = linecache.getline(filename, lineno) line = line.strip() if line: s += " %s\n" % line - s += "%s: %s\n" % (category.__name__, message) + s += f"{category.__name__}: {message}\n" return s def idle_showwarning_subproc( @@ -140,11 +140,12 @@ def main(del_exitfunc=False): capture_warnings(True) sys.argv[:] = [""] - sockthread = threading.Thread(target=manage_socket, - name='SockThread', - args=((LOCALHOST, port),)) - sockthread.daemon = True - sockthread.start() + threading.Thread(target=manage_socket, + name='SockThread', + args=((LOCALHOST, port),), + daemon=True, + ).start() + while True: try: if exit_now: @@ -239,6 +240,7 @@ def print_exception(): efile = sys.stderr typ, val, tb = excinfo = sys.exc_info() sys.last_type, sys.last_value, sys.last_traceback = excinfo + sys.last_exc = val seen = set() def print_exc(typ, exc, tb): @@ -621,7 +623,7 @@ class Executive: def stackviewer(self, flist_oid=None): if self.user_exc_info: - typ, val, tb = self.user_exc_info + _, exc, tb = self.user_exc_info else: return None flist = None @@ -629,9 +631,8 @@ class Executive: flist = self.rpchandler.get_remote_proxy(flist_oid) while tb and tb.tb_frame.f_globals["__name__"] in ["rpc", "run"]: tb = tb.tb_next - sys.last_type = typ - sys.last_value = val - item = stackviewer.StackTreeItem(flist, tb) + exc.__traceback__ = tb + item = stackviewer.StackTreeItem(exc, flist) return debugobj_r.remote_object_tree_item(item) diff --git a/Lib/idlelib/stackviewer.py b/Lib/idlelib/stackviewer.py index 94ffb4ef..7b00c4cd 100644 --- a/Lib/idlelib/stackviewer.py +++ b/Lib/idlelib/stackviewer.py @@ -1,33 +1,30 @@ import linecache import os -import sys import tkinter as tk from idlelib.debugobj import ObjectTreeItem, make_objecttreeitem from idlelib.tree import TreeNode, TreeItem, ScrolledCanvas -def StackBrowser(root, flist=None, tb=None, top=None): +def StackBrowser(root, exc, flist=None, top=None): global sc, item, node # For testing. if top is None: top = tk.Toplevel(root) sc = ScrolledCanvas(top, bg="white", highlightthickness=0) sc.frame.pack(expand=1, fill="both") - item = StackTreeItem(flist, tb) + item = StackTreeItem(exc, flist) node = TreeNode(sc.canvas, None, item) node.expand() class StackTreeItem(TreeItem): - def __init__(self, flist=None, tb=None): + def __init__(self, exc, flist=None): self.flist = flist - self.stack = self.get_stack(tb) - self.text = self.get_exception() + self.stack = self.get_stack(None if exc is None else exc.__traceback__) + self.text = f"{type(exc).__name__}: {str(exc)}" def get_stack(self, tb): - if tb is None: - tb = sys.last_traceback stack = [] if tb and tb.tb_frame is None: tb = tb.tb_next @@ -36,17 +33,7 @@ class StackTreeItem(TreeItem): tb = tb.tb_next return stack - def get_exception(self): - type = sys.last_type - value = sys.last_value - if hasattr(type, "__name__"): - type = type.__name__ - s = str(type) - if value is not None: - s = s + ": " + str(value) - return s - - def GetText(self): + def GetText(self): # Titlecase names are overrides. return self.text def GetSubList(self): @@ -133,19 +120,9 @@ def _stack_viewer(parent): # htest # flist = PyShellFileList(top) try: # to obtain a traceback object intentional_name_error - except NameError: - exc_type, exc_value, exc_tb = sys.exc_info() - # inject stack trace to sys - sys.last_type = exc_type - sys.last_value = exc_value - sys.last_traceback = exc_tb - - StackBrowser(top, flist=flist, top=top, tb=exc_tb) - - # restore sys to original state - del sys.last_type - del sys.last_value - del sys.last_traceback + except NameError as e: + StackBrowser(top, e, flist=flist, top=top) + if __name__ == '__main__': from unittest import main diff --git a/Lib/idlelib/textview.py b/Lib/idlelib/textview.py index a66c1a43..23f0f4cb 100644 --- a/Lib/idlelib/textview.py +++ b/Lib/idlelib/textview.py @@ -169,7 +169,7 @@ def view_file(parent, title, filename, encoding, modal=True, wrap='word', with contents of the file. """ try: - with open(filename, 'r', encoding=encoding) as file: + with open(filename, encoding=encoding) as file: contents = file.read() except OSError: showerror(title='File Load Error', diff --git a/Lib/idlelib/tooltip.py b/Lib/idlelib/tooltip.py index d714318d..3983690d 100644 --- a/Lib/idlelib/tooltip.py +++ b/Lib/idlelib/tooltip.py @@ -92,7 +92,7 @@ class OnHoverTooltipBase(TooltipBase): e.g. after hovering over the anchor widget with the mouse for enough time. """ - super(OnHoverTooltipBase, self).__init__(anchor_widget) + super().__init__(anchor_widget) self.hover_delay = hover_delay self._after_id = None @@ -107,7 +107,7 @@ class OnHoverTooltipBase(TooltipBase): self.anchor_widget.unbind("<Button>", self._id3) # pragma: no cover except TclError: pass - super(OnHoverTooltipBase, self).__del__() + super().__del__() def _show_event(self, event=None): """event handler to display the tooltip""" @@ -139,7 +139,7 @@ class OnHoverTooltipBase(TooltipBase): self.unschedule() except TclError: # pragma: no cover pass - super(OnHoverTooltipBase, self).hidetip() + super().hidetip() class Hovertip(OnHoverTooltipBase): @@ -154,7 +154,7 @@ class Hovertip(OnHoverTooltipBase): e.g. after hovering over the anchor widget with the mouse for enough time. """ - super(Hovertip, self).__init__(anchor_widget, hover_delay=hover_delay) + super().__init__(anchor_widget, hover_delay=hover_delay) self.text = text def showcontents(self): diff --git a/Lib/idlelib/tree.py b/Lib/idlelib/tree.py index 5947268f..5f30f0f6 100644 --- a/Lib/idlelib/tree.py +++ b/Lib/idlelib/tree.py @@ -32,7 +32,7 @@ except NameError: if os.path.isdir(_icondir): ICONDIR = _icondir elif not os.path.isdir(ICONDIR): - raise RuntimeError("can't find icon directory (%r)" % (ICONDIR,)) + raise RuntimeError(f"can't find icon directory ({ICONDIR!r})") def listicons(icondir=ICONDIR): """Utility to display the available icons.""" diff --git a/Lib/idlelib/undo.py b/Lib/idlelib/undo.py index 85ecffec..5f10c0f0 100644 --- a/Lib/idlelib/undo.py +++ b/Lib/idlelib/undo.py @@ -309,7 +309,7 @@ class CommandSequence(Command): s = self.__class__.__name__ strs = [] for cmd in self.cmds: - strs.append(" %r" % (cmd,)) + strs.append(f" {cmd!r}") return s + "(\n" + ",\n".join(strs) + "\n)" def __len__(self): diff --git a/Lib/imaplib.py b/Lib/imaplib.py index fa4c0f8f..577b4b9b 100644 --- a/Lib/imaplib.py +++ b/Lib/imaplib.py @@ -1285,16 +1285,12 @@ if HAVE_SSL: """IMAP4 client class over SSL connection - Instantiate with: IMAP4_SSL([host[, port[, keyfile[, certfile[, ssl_context[, timeout=None]]]]]]) + Instantiate with: IMAP4_SSL([host[, port[, ssl_context[, timeout=None]]]]) host - host's name (default: localhost); port - port number (default: standard IMAP4 SSL port); - keyfile - PEM formatted file that contains your private key (default: None); - certfile - PEM formatted certificate chain file (default: None); ssl_context - a SSLContext object that contains your certificate chain and private key (default: None) - Note: if ssl_context is provided, then parameters keyfile or - certfile should not be set otherwise ValueError is raised. timeout - socket timeout (default: None) If timeout is not given or is None, the global default socket timeout is used @@ -1302,23 +1298,10 @@ if HAVE_SSL: """ - def __init__(self, host='', port=IMAP4_SSL_PORT, keyfile=None, - certfile=None, ssl_context=None, timeout=None): - if ssl_context is not None and keyfile is not None: - raise ValueError("ssl_context and keyfile arguments are mutually " - "exclusive") - if ssl_context is not None and certfile is not None: - raise ValueError("ssl_context and certfile arguments are mutually " - "exclusive") - if keyfile is not None or certfile is not None: - import warnings - warnings.warn("keyfile and certfile are deprecated, use a " - "custom ssl_context instead", DeprecationWarning, 2) - self.keyfile = keyfile - self.certfile = certfile + def __init__(self, host='', port=IMAP4_SSL_PORT, + *, ssl_context=None, timeout=None): if ssl_context is None: - ssl_context = ssl._create_stdlib_context(certfile=certfile, - keyfile=keyfile) + ssl_context = ssl._create_stdlib_context() self.ssl_context = ssl_context IMAP4.__init__(self, host, port, timeout) diff --git a/Lib/imghdr.py b/Lib/imghdr.py index 6a372e66..33868883 100644 --- a/Lib/imghdr.py +++ b/Lib/imghdr.py @@ -14,6 +14,7 @@ warnings._deprecated(__name__, remove=(3, 13)) #-------------------------# def what(file, h=None): + """Return the type of image contained in a file or byte stream.""" f = None try: if h is None: @@ -40,7 +41,7 @@ def what(file, h=None): tests = [] def test_jpeg(h, f): - """JPEG data with JFIF or Exif markers; and raw JPEG""" + """Test for JPEG data with JFIF or Exif markers; and raw JPEG.""" if h[6:10] in (b'JFIF', b'Exif'): return 'jpeg' elif h[:4] == b'\xff\xd8\xff\xdb': @@ -49,34 +50,35 @@ def test_jpeg(h, f): tests.append(test_jpeg) def test_png(h, f): + """Verify if the image is a PNG.""" if h.startswith(b'\211PNG\r\n\032\n'): return 'png' tests.append(test_png) def test_gif(h, f): - """GIF ('87 and '89 variants)""" + """Verify if the image is a GIF ('87 or '89 variants).""" if h[:6] in (b'GIF87a', b'GIF89a'): return 'gif' tests.append(test_gif) def test_tiff(h, f): - """TIFF (can be in Motorola or Intel byte order)""" + """Verify if the image is a TIFF (can be in Motorola or Intel byte order).""" if h[:2] in (b'MM', b'II'): return 'tiff' tests.append(test_tiff) def test_rgb(h, f): - """SGI image library""" + """test for the SGI image library.""" if h.startswith(b'\001\332'): return 'rgb' tests.append(test_rgb) def test_pbm(h, f): - """PBM (portable bitmap)""" + """Verify if the image is a PBM (portable bitmap).""" if len(h) >= 3 and \ h[0] == ord(b'P') and h[1] in b'14' and h[2] in b' \t\n\r': return 'pbm' @@ -84,7 +86,7 @@ def test_pbm(h, f): tests.append(test_pbm) def test_pgm(h, f): - """PGM (portable graymap)""" + """Verify if the image is a PGM (portable graymap).""" if len(h) >= 3 and \ h[0] == ord(b'P') and h[1] in b'25' and h[2] in b' \t\n\r': return 'pgm' @@ -92,7 +94,7 @@ def test_pgm(h, f): tests.append(test_pgm) def test_ppm(h, f): - """PPM (portable pixmap)""" + """Verify if the image is a PPM (portable pixmap).""" if len(h) >= 3 and \ h[0] == ord(b'P') and h[1] in b'36' and h[2] in b' \t\n\r': return 'ppm' @@ -100,32 +102,35 @@ def test_ppm(h, f): tests.append(test_ppm) def test_rast(h, f): - """Sun raster file""" + """test for the Sun raster file.""" if h.startswith(b'\x59\xA6\x6A\x95'): return 'rast' tests.append(test_rast) def test_xbm(h, f): - """X bitmap (X10 or X11)""" + """Verify if the image is a X bitmap (X10 or X11).""" if h.startswith(b'#define '): return 'xbm' tests.append(test_xbm) def test_bmp(h, f): + """Verify if the image is a BMP file.""" if h.startswith(b'BM'): return 'bmp' tests.append(test_bmp) def test_webp(h, f): + """Verify if the image is a WebP.""" if h.startswith(b'RIFF') and h[8:12] == b'WEBP': return 'webp' tests.append(test_webp) def test_exr(h, f): + """verify is the image ia a OpenEXR fileOpenEXR.""" if h.startswith(b'\x76\x2f\x31\x01'): return 'exr' diff --git a/Lib/imp.py b/Lib/imp.py deleted file mode 100644 index fc42c157..00000000 --- a/Lib/imp.py +++ /dev/null @@ -1,346 +0,0 @@ -"""This module provides the components needed to build your own __import__ -function. Undocumented functions are obsolete. - -In most cases it is preferred you consider using the importlib module's -functionality over this module. - -""" -# (Probably) need to stay in _imp -from _imp import (lock_held, acquire_lock, release_lock, - get_frozen_object, is_frozen_package, - init_frozen, is_builtin, is_frozen, - _fix_co_filename, _frozen_module_names) -try: - from _imp import create_dynamic -except ImportError: - # Platform doesn't support dynamic loading. - create_dynamic = None - -from importlib._bootstrap import _ERR_MSG, _exec, _load, _builtin_from_name -from importlib._bootstrap_external import SourcelessFileLoader - -from importlib import machinery -from importlib import util -import importlib -import os -import sys -import tokenize -import types -import warnings - -warnings.warn("the imp module is deprecated in favour of importlib and slated " - "for removal in Python 3.12; " - "see the module's documentation for alternative uses", - DeprecationWarning, stacklevel=2) - -# DEPRECATED -SEARCH_ERROR = 0 -PY_SOURCE = 1 -PY_COMPILED = 2 -C_EXTENSION = 3 -PY_RESOURCE = 4 -PKG_DIRECTORY = 5 -C_BUILTIN = 6 -PY_FROZEN = 7 -PY_CODERESOURCE = 8 -IMP_HOOK = 9 - - -def new_module(name): - """**DEPRECATED** - - Create a new module. - - The module is not entered into sys.modules. - - """ - return types.ModuleType(name) - - -def get_magic(): - """**DEPRECATED** - - Return the magic number for .pyc files. - """ - return util.MAGIC_NUMBER - - -def get_tag(): - """Return the magic tag for .pyc files.""" - return sys.implementation.cache_tag - - -def cache_from_source(path, debug_override=None): - """**DEPRECATED** - - Given the path to a .py file, return the path to its .pyc file. - - The .py file does not need to exist; this simply returns the path to the - .pyc file calculated as if the .py file were imported. - - If debug_override is not None, then it must be a boolean and is used in - place of sys.flags.optimize. - - If sys.implementation.cache_tag is None then NotImplementedError is raised. - - """ - with warnings.catch_warnings(): - warnings.simplefilter('ignore') - return util.cache_from_source(path, debug_override) - - -def source_from_cache(path): - """**DEPRECATED** - - Given the path to a .pyc. file, return the path to its .py file. - - The .pyc file does not need to exist; this simply returns the path to - the .py file calculated to correspond to the .pyc file. If path does - not conform to PEP 3147 format, ValueError will be raised. If - sys.implementation.cache_tag is None then NotImplementedError is raised. - - """ - return util.source_from_cache(path) - - -def get_suffixes(): - """**DEPRECATED**""" - extensions = [(s, 'rb', C_EXTENSION) for s in machinery.EXTENSION_SUFFIXES] - source = [(s, 'r', PY_SOURCE) for s in machinery.SOURCE_SUFFIXES] - bytecode = [(s, 'rb', PY_COMPILED) for s in machinery.BYTECODE_SUFFIXES] - - return extensions + source + bytecode - - -class NullImporter: - - """**DEPRECATED** - - Null import object. - - """ - - def __init__(self, path): - if path == '': - raise ImportError('empty pathname', path='') - elif os.path.isdir(path): - raise ImportError('existing directory', path=path) - - def find_module(self, fullname): - """Always returns None.""" - return None - - -class _HackedGetData: - - """Compatibility support for 'file' arguments of various load_*() - functions.""" - - def __init__(self, fullname, path, file=None): - super().__init__(fullname, path) - self.file = file - - def get_data(self, path): - """Gross hack to contort loader to deal w/ load_*()'s bad API.""" - if self.file and path == self.path: - # The contract of get_data() requires us to return bytes. Reopen the - # file in binary mode if needed. - if not self.file.closed: - file = self.file - if 'b' not in file.mode: - file.close() - if self.file.closed: - self.file = file = open(self.path, 'rb') - - with file: - return file.read() - else: - return super().get_data(path) - - -class _LoadSourceCompatibility(_HackedGetData, machinery.SourceFileLoader): - - """Compatibility support for implementing load_source().""" - - -def load_source(name, pathname, file=None): - loader = _LoadSourceCompatibility(name, pathname, file) - spec = util.spec_from_file_location(name, pathname, loader=loader) - if name in sys.modules: - module = _exec(spec, sys.modules[name]) - else: - module = _load(spec) - # To allow reloading to potentially work, use a non-hacked loader which - # won't rely on a now-closed file object. - module.__loader__ = machinery.SourceFileLoader(name, pathname) - module.__spec__.loader = module.__loader__ - return module - - -class _LoadCompiledCompatibility(_HackedGetData, SourcelessFileLoader): - - """Compatibility support for implementing load_compiled().""" - - -def load_compiled(name, pathname, file=None): - """**DEPRECATED**""" - loader = _LoadCompiledCompatibility(name, pathname, file) - spec = util.spec_from_file_location(name, pathname, loader=loader) - if name in sys.modules: - module = _exec(spec, sys.modules[name]) - else: - module = _load(spec) - # To allow reloading to potentially work, use a non-hacked loader which - # won't rely on a now-closed file object. - module.__loader__ = SourcelessFileLoader(name, pathname) - module.__spec__.loader = module.__loader__ - return module - - -def load_package(name, path): - """**DEPRECATED**""" - if os.path.isdir(path): - extensions = (machinery.SOURCE_SUFFIXES[:] + - machinery.BYTECODE_SUFFIXES[:]) - for extension in extensions: - init_path = os.path.join(path, '__init__' + extension) - if os.path.exists(init_path): - path = init_path - break - else: - raise ValueError('{!r} is not a package'.format(path)) - spec = util.spec_from_file_location(name, path, - submodule_search_locations=[]) - if name in sys.modules: - return _exec(spec, sys.modules[name]) - else: - return _load(spec) - - -def load_module(name, file, filename, details): - """**DEPRECATED** - - Load a module, given information returned by find_module(). - - The module name must include the full package name, if any. - - """ - suffix, mode, type_ = details - if mode and (not mode.startswith('r') or '+' in mode): - raise ValueError('invalid file open mode {!r}'.format(mode)) - elif file is None and type_ in {PY_SOURCE, PY_COMPILED}: - msg = 'file object required for import (type code {})'.format(type_) - raise ValueError(msg) - elif type_ == PY_SOURCE: - return load_source(name, filename, file) - elif type_ == PY_COMPILED: - return load_compiled(name, filename, file) - elif type_ == C_EXTENSION and load_dynamic is not None: - if file is None: - with open(filename, 'rb') as opened_file: - return load_dynamic(name, filename, opened_file) - else: - return load_dynamic(name, filename, file) - elif type_ == PKG_DIRECTORY: - return load_package(name, filename) - elif type_ == C_BUILTIN: - return init_builtin(name) - elif type_ == PY_FROZEN: - return init_frozen(name) - else: - msg = "Don't know how to import {} (type code {})".format(name, type_) - raise ImportError(msg, name=name) - - -def find_module(name, path=None): - """**DEPRECATED** - - Search for a module. - - If path is omitted or None, search for a built-in, frozen or special - module and continue search in sys.path. The module name cannot - contain '.'; to search for a submodule of a package, pass the - submodule name and the package's __path__. - - """ - if not isinstance(name, str): - raise TypeError("'name' must be a str, not {}".format(type(name))) - elif not isinstance(path, (type(None), list)): - # Backwards-compatibility - raise RuntimeError("'path' must be None or a list, " - "not {}".format(type(path))) - - if path is None: - if is_builtin(name): - return None, None, ('', '', C_BUILTIN) - elif is_frozen(name): - return None, None, ('', '', PY_FROZEN) - else: - path = sys.path - - for entry in path: - package_directory = os.path.join(entry, name) - for suffix in ['.py', machinery.BYTECODE_SUFFIXES[0]]: - package_file_name = '__init__' + suffix - file_path = os.path.join(package_directory, package_file_name) - if os.path.isfile(file_path): - return None, package_directory, ('', '', PKG_DIRECTORY) - for suffix, mode, type_ in get_suffixes(): - file_name = name + suffix - file_path = os.path.join(entry, file_name) - if os.path.isfile(file_path): - break - else: - continue - break # Break out of outer loop when breaking out of inner loop. - else: - raise ImportError(_ERR_MSG.format(name), name=name) - - encoding = None - if 'b' not in mode: - with open(file_path, 'rb') as file: - encoding = tokenize.detect_encoding(file.readline)[0] - file = open(file_path, mode, encoding=encoding) - return file, file_path, (suffix, mode, type_) - - -def reload(module): - """**DEPRECATED** - - Reload the module and return it. - - The module must have been successfully imported before. - - """ - return importlib.reload(module) - - -def init_builtin(name): - """**DEPRECATED** - - Load and return a built-in module by name, or None is such module doesn't - exist - """ - try: - return _builtin_from_name(name) - except ImportError: - return None - - -if create_dynamic: - def load_dynamic(name, path, file=None): - """**DEPRECATED** - - Load an extension module. - """ - import importlib.machinery - loader = importlib.machinery.ExtensionFileLoader(name, path) - - # Issue #24748: Skip the sys.modules check in _load_module_shim; - # always load new extension - spec = importlib.machinery.ModuleSpec( - name=name, loader=loader, origin=path) - return _load(spec) - -else: - load_dynamic = None diff --git a/Lib/importlib/__init__.py b/Lib/importlib/__init__.py index ce618832..707c081c 100644 --- a/Lib/importlib/__init__.py +++ b/Lib/importlib/__init__.py @@ -70,41 +70,6 @@ def invalidate_caches(): finder.invalidate_caches() -def find_loader(name, path=None): - """Return the loader for the specified module. - - This is a backward-compatible wrapper around find_spec(). - - This function is deprecated in favor of importlib.util.find_spec(). - - """ - warnings.warn('Deprecated since Python 3.4 and slated for removal in ' - 'Python 3.12; use importlib.util.find_spec() instead', - DeprecationWarning, stacklevel=2) - try: - loader = sys.modules[name].__loader__ - if loader is None: - raise ValueError('{}.__loader__ is None'.format(name)) - else: - return loader - except KeyError: - pass - except AttributeError: - raise ValueError('{}.__loader__ is not set'.format(name)) from None - - spec = _bootstrap._find_spec(name, path) - # We won't worry about malformed specs (missing attributes). - if spec is None: - return None - if spec.loader is None: - if spec.submodule_search_locations is None: - raise ImportError('spec for {} missing loader'.format(name), - name=name) - raise ImportError('namespace packages do not have loaders', - name=name) - return spec.loader - - def import_module(name, package=None): """Import a module. @@ -116,9 +81,8 @@ def import_module(name, package=None): level = 0 if name.startswith('.'): if not package: - msg = ("the 'package' argument is required to perform a relative " - "import for {!r}") - raise TypeError(msg.format(name)) + raise TypeError("the 'package' argument is required to perform a " + f"relative import for {name!r}") for character in name: if character != '.': break @@ -144,8 +108,7 @@ def reload(module): raise TypeError("reload() argument must be a module") if sys.modules.get(name) is not module: - msg = "module {} not in sys.modules" - raise ImportError(msg.format(name), name=name) + raise ImportError(f"module {name} not in sys.modules", name=name) if name in _RELOADING: return _RELOADING[name] _RELOADING[name] = module @@ -155,8 +118,7 @@ def reload(module): try: parent = sys.modules[parent_name] except KeyError: - msg = "parent {!r} not in sys.modules" - raise ImportError(msg.format(parent_name), + raise ImportError(f"parent {parent_name!r} not in sys.modules", name=parent_name) from None else: pkgpath = parent.__path__ diff --git a/Lib/importlib/_abc.py b/Lib/importlib/_abc.py index f80348fc..693b4661 100644 --- a/Lib/importlib/_abc.py +++ b/Lib/importlib/_abc.py @@ -1,7 +1,6 @@ """Subset of importlib.abc used to reduce importlib.util imports.""" from . import _bootstrap import abc -import warnings class Loader(metaclass=abc.ABCMeta): @@ -38,17 +37,3 @@ class Loader(metaclass=abc.ABCMeta): raise ImportError # Warning implemented in _load_module_shim(). return _bootstrap._load_module_shim(self, fullname) - - def module_repr(self, module): - """Return a module's repr. - - Used by the module type when the method does not raise - NotImplementedError. - - This method is deprecated. - - """ - warnings.warn("importlib.abc.Loader.module_repr() is deprecated and " - "slated for removal in Python 3.12", DeprecationWarning) - # The exception will cause ModuleType.__repr__ to ignore this method. - raise NotImplementedError diff --git a/Lib/importlib/_bootstrap.py b/Lib/importlib/_bootstrap.py index afb95f4e..ec2e56f6 100644 --- a/Lib/importlib/_bootstrap.py +++ b/Lib/importlib/_bootstrap.py @@ -51,17 +51,178 @@ def _new_module(name): # Module-level locking ######################################################## -# A dict mapping module names to weakrefs of _ModuleLock instances -# Dictionary protected by the global import lock +# For a list that can have a weakref to it. +class _List(list): + pass + + +# Copied from weakref.py with some simplifications and modifications unique to +# bootstrapping importlib. Many methods were simply deleting for simplicity, so if they +# are needed in the future they may work if simply copied back in. +class _WeakValueDictionary: + + def __init__(self): + self_weakref = _weakref.ref(self) + + # Inlined to avoid issues with inheriting from _weakref.ref before _weakref is + # set by _setup(). Since there's only one instance of this class, this is + # not expensive. + class KeyedRef(_weakref.ref): + + __slots__ = "key", + + def __new__(type, ob, key): + self = super().__new__(type, ob, type.remove) + self.key = key + return self + + def __init__(self, ob, key): + super().__init__(ob, self.remove) + + @staticmethod + def remove(wr): + nonlocal self_weakref + + self = self_weakref() + if self is not None: + if self._iterating: + self._pending_removals.append(wr.key) + else: + _weakref._remove_dead_weakref(self.data, wr.key) + + self._KeyedRef = KeyedRef + self.clear() + + def clear(self): + self._pending_removals = [] + self._iterating = set() + self.data = {} + + def _commit_removals(self): + pop = self._pending_removals.pop + d = self.data + while True: + try: + key = pop() + except IndexError: + return + _weakref._remove_dead_weakref(d, key) + + def get(self, key, default=None): + if self._pending_removals: + self._commit_removals() + try: + wr = self.data[key] + except KeyError: + return default + else: + if (o := wr()) is None: + return default + else: + return o + + def setdefault(self, key, default=None): + try: + o = self.data[key]() + except KeyError: + o = None + if o is None: + if self._pending_removals: + self._commit_removals() + self.data[key] = self._KeyedRef(default, key) + return default + else: + return o + + +# A dict mapping module names to weakrefs of _ModuleLock instances. +# Dictionary protected by the global import lock. _module_locks = {} -# A dict mapping thread ids to _ModuleLock instances -_blocking_on = {} + +# A dict mapping thread IDs to weakref'ed lists of _ModuleLock instances. +# This maps a thread to the module locks it is blocking on acquiring. The +# values are lists because a single thread could perform a re-entrant import +# and be "in the process" of blocking on locks for more than one module. A +# thread can be "in the process" because a thread cannot actually block on +# acquiring more than one lock but it can have set up bookkeeping that reflects +# that it intends to block on acquiring more than one lock. +# +# The dictionary uses a WeakValueDictionary to avoid keeping unnecessary +# lists around, regardless of GC runs. This way there's no memory leak if +# the list is no longer needed (GH-106176). +_blocking_on = None + + +class _BlockingOnManager: + """A context manager responsible to updating ``_blocking_on``.""" + def __init__(self, thread_id, lock): + self.thread_id = thread_id + self.lock = lock + + def __enter__(self): + """Mark the running thread as waiting for self.lock. via _blocking_on.""" + # Interactions with _blocking_on are *not* protected by the global + # import lock here because each thread only touches the state that it + # owns (state keyed on its thread id). The global import lock is + # re-entrant (i.e., a single thread may take it more than once) so it + # wouldn't help us be correct in the face of re-entrancy either. + + self.blocked_on = _blocking_on.setdefault(self.thread_id, _List()) + self.blocked_on.append(self.lock) + + def __exit__(self, *args, **kwargs): + """Remove self.lock from this thread's _blocking_on list.""" + self.blocked_on.remove(self.lock) class _DeadlockError(RuntimeError): pass + +def _has_deadlocked(target_id, *, seen_ids, candidate_ids, blocking_on): + """Check if 'target_id' is holding the same lock as another thread(s). + + The search within 'blocking_on' starts with the threads listed in + 'candidate_ids'. 'seen_ids' contains any threads that are considered + already traversed in the search. + + Keyword arguments: + target_id -- The thread id to try to reach. + seen_ids -- A set of threads that have already been visited. + candidate_ids -- The thread ids from which to begin. + blocking_on -- A dict representing the thread/blocking-on graph. This may + be the same object as the global '_blocking_on' but it is + a parameter to reduce the impact that global mutable + state has on the result of this function. + """ + if target_id in candidate_ids: + # If we have already reached the target_id, we're done - signal that it + # is reachable. + return True + + # Otherwise, try to reach the target_id from each of the given candidate_ids. + for tid in candidate_ids: + if not (candidate_blocking_on := blocking_on.get(tid)): + # There are no edges out from this node, skip it. + continue + elif tid in seen_ids: + # bpo 38091: the chain of tid's we encounter here eventually leads + # to a fixed point or a cycle, but does not reach target_id. + # This means we would not actually deadlock. This can happen if + # other threads are at the beginning of acquire() below. + return False + seen_ids.add(tid) + + # Follow the edges out from this thread. + edges = [lock.owner for lock in candidate_blocking_on] + if _has_deadlocked(target_id, seen_ids=seen_ids, candidate_ids=edges, + blocking_on=blocking_on): + return True + + return False + + class _ModuleLock: """A recursive lock implementation which is able to detect deadlocks (e.g. thread 1 trying to take locks A then B, and thread 2 trying to @@ -69,33 +230,76 @@ class _ModuleLock: """ def __init__(self, name): - self.lock = _thread.allocate_lock() + # Create an RLock for protecting the import process for the + # corresponding module. Since it is an RLock, a single thread will be + # able to take it more than once. This is necessary to support + # re-entrancy in the import system that arises from (at least) signal + # handlers and the garbage collector. Consider the case of: + # + # import foo + # -> ... + # -> importlib._bootstrap._ModuleLock.acquire + # -> ... + # -> <garbage collector> + # -> __del__ + # -> import foo + # -> ... + # -> importlib._bootstrap._ModuleLock.acquire + # -> _BlockingOnManager.__enter__ + # + # If a different thread than the running one holds the lock then the + # thread will have to block on taking the lock, which is what we want + # for thread safety. + self.lock = _thread.RLock() self.wakeup = _thread.allocate_lock() + + # The name of the module for which this is a lock. self.name = name + + # Can end up being set to None if this lock is not owned by any thread + # or the thread identifier for the owning thread. self.owner = None - self.count = 0 - self.waiters = 0 + + # Represent the number of times the owning thread has acquired this lock + # via a list of True. This supports RLock-like ("re-entrant lock") + # behavior, necessary in case a single thread is following a circular + # import dependency and needs to take the lock for a single module + # more than once. + # + # Counts are represented as a list of True because list.append(True) + # and list.pop() are both atomic and thread-safe in CPython and it's hard + # to find another primitive with the same properties. + self.count = [] + + # This is a count of the number of threads that are blocking on + # self.wakeup.acquire() awaiting to get their turn holding this module + # lock. When the module lock is released, if this is greater than + # zero, it is decremented and `self.wakeup` is released one time. The + # intent is that this will let one other thread make more progress on + # acquiring this module lock. This repeats until all the threads have + # gotten a turn. + # + # This is incremented in self.acquire() when a thread notices it is + # going to have to wait for another thread to finish. + # + # See the comment above count for explanation of the representation. + self.waiters = [] def has_deadlock(self): - # Deadlock avoidance for concurrent circular imports. - me = _thread.get_ident() - tid = self.owner - seen = set() - while True: - lock = _blocking_on.get(tid) - if lock is None: - return False - tid = lock.owner - if tid == me: - return True - if tid in seen: - # bpo 38091: the chain of tid's we encounter here - # eventually leads to a fixpoint or a cycle, but - # does not reach 'me'. This means we would not - # actually deadlock. This can happen if other - # threads are at the beginning of acquire() below. - return False - seen.add(tid) + # To avoid deadlocks for concurrent or re-entrant circular imports, + # look at _blocking_on to see if any threads are blocking + # on getting the import lock for any module for which the import lock + # is held by this thread. + return _has_deadlocked( + # Try to find this thread. + target_id=_thread.get_ident(), + seen_ids=set(), + # Start from the thread that holds the import lock for this + # module. + candidate_ids=[self.owner], + # Use the global "blocking on" state. + blocking_on=_blocking_on, + ) def acquire(self): """ @@ -104,39 +308,82 @@ class _ModuleLock: Otherwise, the lock is always acquired and True is returned. """ tid = _thread.get_ident() - _blocking_on[tid] = self - try: + with _BlockingOnManager(tid, self): while True: + # Protect interaction with state on self with a per-module + # lock. This makes it safe for more than one thread to try to + # acquire the lock for a single module at the same time. with self.lock: - if self.count == 0 or self.owner == tid: + if self.count == [] or self.owner == tid: + # If the lock for this module is unowned then we can + # take the lock immediately and succeed. If the lock + # for this module is owned by the running thread then + # we can also allow the acquire to succeed. This + # supports circular imports (thread T imports module A + # which imports module B which imports module A). self.owner = tid - self.count += 1 + self.count.append(True) return True + + # At this point we know the lock is held (because count != + # 0) by another thread (because owner != tid). We'll have + # to get in line to take the module lock. + + # But first, check to see if this thread would create a + # deadlock by acquiring this module lock. If it would + # then just stop with an error. + # + # It's not clear who is expected to handle this error. + # There is one handler in _lock_unlock_module but many + # times this method is called when entering the context + # manager _ModuleLockManager instead - so _DeadlockError + # will just propagate up to application code. + # + # This seems to be more than just a hypothetical - + # https://stackoverflow.com/questions/59509154 + # https://github.com/encode/django-rest-framework/issues/7078 if self.has_deadlock(): - raise _DeadlockError('deadlock detected by %r' % self) + raise _DeadlockError(f'deadlock detected by {self!r}') + + # Check to see if we're going to be able to acquire the + # lock. If we are going to have to wait then increment + # the waiters so `self.release` will know to unblock us + # later on. We do this part non-blockingly so we don't + # get stuck here before we increment waiters. We have + # this extra acquire call (in addition to the one below, + # outside the self.lock context manager) to make sure + # self.wakeup is held when the next acquire is called (so + # we block). This is probably needlessly complex and we + # should just take self.wakeup in the return codepath + # above. if self.wakeup.acquire(False): - self.waiters += 1 - # Wait for a release() call + self.waiters.append(None) + + # Now take the lock in a blocking fashion. This won't + # complete until the thread holding this lock + # (self.owner) calls self.release. self.wakeup.acquire() + + # Taking the lock has served its purpose (making us wait), so we can + # give it up now. We'll take it w/o blocking again on the + # next iteration around this 'while' loop. self.wakeup.release() - finally: - del _blocking_on[tid] def release(self): tid = _thread.get_ident() with self.lock: if self.owner != tid: raise RuntimeError('cannot release un-acquired lock') - assert self.count > 0 - self.count -= 1 - if self.count == 0: + assert len(self.count) > 0 + self.count.pop() + if not len(self.count): self.owner = None - if self.waiters: - self.waiters -= 1 + if len(self.waiters) > 0: + self.waiters.pop() self.wakeup.release() def __repr__(self): - return '_ModuleLock({!r}) at {}'.format(self.name, id(self)) + return f'_ModuleLock({self.name!r}) at {id(self)}' class _DummyModuleLock: @@ -157,7 +404,7 @@ class _DummyModuleLock: self.count -= 1 def __repr__(self): - return '_DummyModuleLock({!r}) at {}'.format(self.name, id(self)) + return f'_DummyModuleLock({self.name!r}) at {id(self)}' class _ModuleLockManager: @@ -253,7 +500,7 @@ def _requires_builtin(fxn): """Decorator to verify the named module is built-in.""" def _requires_builtin_wrapper(self, fullname): if fullname not in sys.builtin_module_names: - raise ImportError('{!r} is not a built-in module'.format(fullname), + raise ImportError(f'{fullname!r} is not a built-in module', name=fullname) return fxn(self, fullname) _wrap(_requires_builtin_wrapper, fxn) @@ -264,7 +511,7 @@ def _requires_frozen(fxn): """Decorator to verify the named module is frozen.""" def _requires_frozen_wrapper(self, fullname): if not _imp.is_frozen(fullname): - raise ImportError('{!r} is not a frozen module'.format(fullname), + raise ImportError(f'{fullname!r} is not a frozen module', name=fullname) return fxn(self, fullname) _wrap(_requires_frozen_wrapper, fxn) @@ -296,11 +543,6 @@ def _module_repr(module): loader = getattr(module, '__loader__', None) if spec := getattr(module, "__spec__", None): return _module_repr_from_spec(spec) - elif hasattr(loader, 'module_repr'): - try: - return loader.module_repr(module) - except Exception: - pass # Fall through to a catch-all which always succeeds. try: name = module.__name__ @@ -310,11 +552,11 @@ def _module_repr(module): filename = module.__file__ except AttributeError: if loader is None: - return '<module {!r}>'.format(name) + return f'<module {name!r}>' else: - return '<module {!r} ({!r})>'.format(name, loader) + return f'<module {name!r} ({loader!r})>' else: - return '<module {!r} from {!r}>'.format(name, filename) + return f'<module {name!r} from {filename!r}>' class ModuleSpec: @@ -368,14 +610,12 @@ class ModuleSpec: self._cached = None def __repr__(self): - args = ['name={!r}'.format(self.name), - 'loader={!r}'.format(self.loader)] + args = [f'name={self.name!r}', f'loader={self.loader!r}'] if self.origin is not None: - args.append('origin={!r}'.format(self.origin)) + args.append(f'origin={self.origin!r}') if self.submodule_search_locations is not None: - args.append('submodule_search_locations={}' - .format(self.submodule_search_locations)) - return '{}({})'.format(self.__class__.__name__, ', '.join(args)) + args.append(f'submodule_search_locations={self.submodule_search_locations}') + return f'{self.__class__.__name__}({", ".join(args)})' def __eq__(self, other): smsl = self.submodule_search_locations @@ -582,18 +822,17 @@ def module_from_spec(spec): def _module_repr_from_spec(spec): """Return the repr to use for the module.""" - # We mostly replicate _module_repr() using the spec attributes. name = '?' if spec.name is None else spec.name if spec.origin is None: if spec.loader is None: - return '<module {!r}>'.format(name) + return f'<module {name!r}>' else: - return '<module {!r} ({!r})>'.format(name, spec.loader) + return f'<module {name!r} (namespace) from {list(spec.loader._path)}>' else: if spec.has_location: - return '<module {!r} from {!r}>'.format(name, spec.origin) + return f'<module {name!r} from {spec.origin!r}>' else: - return '<module {!r} ({})>'.format(spec.name, spec.origin) + return f'<module {spec.name!r} ({spec.origin})>' # Used by importlib.reload() and _load_module_shim(). @@ -602,7 +841,7 @@ def _exec(spec, module): name = spec.name with _ModuleLockManager(name): if sys.modules.get(name) is not module: - msg = 'module {!r} not in sys.modules'.format(name) + msg = f'module {name!r} not in sys.modules' raise ImportError(msg, name=name) try: if spec.loader is None: @@ -734,46 +973,18 @@ class BuiltinImporter: _ORIGIN = "built-in" - @staticmethod - def module_repr(module): - """Return repr for the module. - - The method is deprecated. The import machinery does the job itself. - - """ - _warnings.warn("BuiltinImporter.module_repr() is deprecated and " - "slated for removal in Python 3.12", DeprecationWarning) - return f'<module {module.__name__!r} ({BuiltinImporter._ORIGIN})>' - @classmethod def find_spec(cls, fullname, path=None, target=None): - if path is not None: - return None if _imp.is_builtin(fullname): return spec_from_loader(fullname, cls, origin=cls._ORIGIN) else: return None - @classmethod - def find_module(cls, fullname, path=None): - """Find the built-in module. - - If 'path' is ever specified then the search is considered a failure. - - This method is deprecated. Use find_spec() instead. - - """ - _warnings.warn("BuiltinImporter.find_module() is deprecated and " - "slated for removal in Python 3.12; use find_spec() instead", - DeprecationWarning) - spec = cls.find_spec(fullname, path) - return spec.loader if spec is not None else None - @staticmethod def create_module(spec): """Create a built-in module""" if spec.name not in sys.builtin_module_names: - raise ImportError('{!r} is not a built-in module'.format(spec.name), + raise ImportError(f'{spec.name!r} is not a built-in module', name=spec.name) return _call_with_frames_removed(_imp.create_builtin, spec) @@ -814,17 +1025,6 @@ class FrozenImporter: _ORIGIN = "frozen" - @staticmethod - def module_repr(m): - """Return repr for the module. - - The method is deprecated. The import machinery does the job itself. - - """ - _warnings.warn("FrozenImporter.module_repr() is deprecated and " - "slated for removal in Python 3.12", DeprecationWarning) - return '<module {!r} ({})>'.format(m.__name__, FrozenImporter._ORIGIN) - @classmethod def _fix_up_module(cls, module): spec = module.__spec__ @@ -949,18 +1149,6 @@ class FrozenImporter: spec.submodule_search_locations.insert(0, pkgdir) return spec - @classmethod - def find_module(cls, fullname, path=None): - """Find a frozen module. - - This method is deprecated. Use find_spec() instead. - - """ - _warnings.warn("FrozenImporter.find_module() is deprecated and " - "slated for removal in Python 3.12; use find_spec() instead", - DeprecationWarning) - return cls if _imp.is_frozen(fullname) else None - @staticmethod def create_module(spec): """Set __file__, if able.""" @@ -1040,17 +1228,7 @@ def _resolve_name(name, package, level): if len(bits) < level: raise ImportError('attempted relative import beyond top-level package') base = bits[0] - return '{}.{}'.format(base, name) if name else base - - -def _find_spec_legacy(finder, name, path): - msg = (f"{_object_name(finder)}.find_spec() not found; " - "falling back to find_module()") - _warnings.warn(msg, ImportWarning) - loader = finder.find_module(name, path) - if loader is None: - return None - return spec_from_loader(name, loader) + return f'{base}.{name}' if name else base def _find_spec(name, path, target=None): @@ -1073,9 +1251,7 @@ def _find_spec(name, path, target=None): try: find_spec = finder.find_spec except AttributeError: - spec = _find_spec_legacy(finder, name, path) - if spec is None: - continue + continue else: spec = find_spec(name, path, target) if spec is not None: @@ -1103,7 +1279,7 @@ def _find_spec(name, path, target=None): def _sanity_check(name, package, level): """Verify arguments are "sane".""" if not isinstance(name, str): - raise TypeError('module name must be str, not {}'.format(type(name))) + raise TypeError(f'module name must be str, not {type(name)}') if level < 0: raise ValueError('level must be >= 0') if level > 0: @@ -1133,13 +1309,13 @@ def _find_and_load_unlocked(name, import_): try: path = parent_module.__path__ except AttributeError: - msg = (_ERR_MSG + '; {!r} is not a package').format(name, parent) + msg = f'{_ERR_MSG_PREFIX}{name!r}; {parent!r} is not a package' raise ModuleNotFoundError(msg, name=name) from None parent_spec = parent_module.__spec__ child = name.rpartition('.')[2] spec = _find_spec(name, path) if spec is None: - raise ModuleNotFoundError(_ERR_MSG.format(name), name=name) + raise ModuleNotFoundError(f'{_ERR_MSG_PREFIX}{name!r}', name=name) else: if parent_spec: # Temporarily add child we are currently importing to parent's @@ -1184,8 +1360,7 @@ def _find_and_load(name, import_): _lock_unlock_module(name) if module is None: - message = ('import of {} halted; ' - 'None in sys.modules'.format(name)) + message = f'import of {name} halted; None in sys.modules' raise ModuleNotFoundError(message, name=name) return module @@ -1229,7 +1404,7 @@ def _handle_fromlist(module, fromlist, import_, *, recursive=False): _handle_fromlist(module, module.__all__, import_, recursive=True) elif not hasattr(module, x): - from_name = '{}.{}'.format(module.__name__, x) + from_name = f'{module.__name__}.{x}' try: _call_with_frames_removed(import_, from_name) except ModuleNotFoundError as exc: @@ -1256,7 +1431,7 @@ def _calc___package__(globals): if spec is not None and package != spec.parent: _warnings.warn("__package__ != __spec__.parent " f"({package!r} != {spec.parent!r})", - ImportWarning, stacklevel=3) + DeprecationWarning, stacklevel=3) return package elif spec is not None: return spec.parent @@ -1322,7 +1497,7 @@ def _setup(sys_module, _imp_module): modules, those two modules must be explicitly passed in. """ - global _imp, sys + global _imp, sys, _blocking_on _imp = _imp_module sys = sys_module @@ -1350,6 +1525,9 @@ def _setup(sys_module, _imp_module): builtin_module = sys.modules[builtin_name] setattr(self_module, builtin_name, builtin_module) + # Instantiation requires _weakref to have been set. + _blocking_on = _WeakValueDictionary() + def _install(sys_module, _imp_module): """Install importers for builtin and frozen modules""" diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py index f603a89f..73ac4405 100644 --- a/Lib/importlib/_bootstrap_external.py +++ b/Lib/importlib/_bootstrap_external.py @@ -182,12 +182,22 @@ else: return path.startswith(path_separators) +def _path_abspath(path): + """Replacement for os.path.abspath.""" + if not _path_isabs(path): + for sep in path_separators: + path = path.removeprefix(f".{sep}") + return _path_join(_os.getcwd(), path) + else: + return path + + def _write_atomic(path, data, mode=0o666): """Best-effort function to write data to a path atomically. Be prepared to handle a FileExistsError if concurrent writing of the temporary file is attempted.""" # id() is used to generate a pseudo-random filename. - path_tmp = '{}.{}'.format(path, id(path)) + path_tmp = f'{path}.{id(path)}' fd = _os.open(path_tmp, _os.O_EXCL | _os.O_CREAT | _os.O_WRONLY, mode & 0o666) try: @@ -403,11 +413,45 @@ _code_type = type(_write_atomic.__code__) # Python 3.11a7 3492 (make POP_JUMP_IF_NONE/NOT_NONE/TRUE/FALSE relative) # Python 3.11a7 3493 (Make JUMP_IF_TRUE_OR_POP/JUMP_IF_FALSE_OR_POP relative) # Python 3.11a7 3494 (New location info table) -# Python 3.11b4 3495 (Set line number of module's RESUME instr to 0 per PEP 626) -# Python 3.12 will start with magic number 3500 - +# Python 3.12a1 3500 (Remove PRECALL opcode) +# Python 3.12a1 3501 (YIELD_VALUE oparg == stack_depth) +# Python 3.12a1 3502 (LOAD_FAST_CHECK, no NULL-check in LOAD_FAST) +# Python 3.12a1 3503 (Shrink LOAD_METHOD cache) +# Python 3.12a1 3504 (Merge LOAD_METHOD back into LOAD_ATTR) +# Python 3.12a1 3505 (Specialization/Cache for FOR_ITER) +# Python 3.12a1 3506 (Add BINARY_SLICE and STORE_SLICE instructions) +# Python 3.12a1 3507 (Set lineno of module's RESUME to 0) +# Python 3.12a1 3508 (Add CLEANUP_THROW) +# Python 3.12a1 3509 (Conditional jumps only jump forward) +# Python 3.12a2 3510 (FOR_ITER leaves iterator on the stack) +# Python 3.12a2 3511 (Add STOPITERATION_ERROR instruction) +# Python 3.12a2 3512 (Remove all unused consts from code objects) +# Python 3.12a4 3513 (Add CALL_INTRINSIC_1 instruction, removed STOPITERATION_ERROR, PRINT_EXPR, IMPORT_STAR) +# Python 3.12a4 3514 (Remove ASYNC_GEN_WRAP, LIST_TO_TUPLE, and UNARY_POSITIVE) +# Python 3.12a5 3515 (Embed jump mask in COMPARE_OP oparg) +# Python 3.12a5 3516 (Add COMPARE_AND_BRANCH instruction) +# Python 3.12a5 3517 (Change YIELD_VALUE oparg to exception block depth) +# Python 3.12a6 3518 (Add RETURN_CONST instruction) +# Python 3.12a6 3519 (Modify SEND instruction) +# Python 3.12a6 3520 (Remove PREP_RERAISE_STAR, add CALL_INTRINSIC_2) +# Python 3.12a7 3521 (Shrink the LOAD_GLOBAL caches) +# Python 3.12a7 3522 (Removed JUMP_IF_FALSE_OR_POP/JUMP_IF_TRUE_OR_POP) +# Python 3.12a7 3523 (Convert COMPARE_AND_BRANCH back to COMPARE_OP) +# Python 3.12a7 3524 (Shrink the BINARY_SUBSCR caches) +# Python 3.12b1 3525 (Shrink the CALL caches) +# Python 3.12b1 3526 (Add instrumentation support) +# Python 3.12b1 3527 (Add LOAD_SUPER_ATTR) +# Python 3.12b1 3528 (Add LOAD_SUPER_ATTR_METHOD specialization) +# Python 3.12b1 3529 (Inline list/dict/set comprehensions) +# Python 3.12b1 3530 (Shrink the LOAD_SUPER_ATTR caches) +# Python 3.12b1 3531 (Add PEP 695 changes) + +# Python 3.13 will start with 3550 + +# Please don't copy-paste the same pre-release tag for new entries above!!! +# You should always use the *upcoming* tag. For example, if 3.12a6 came out +# a week ago, I should put "Python 3.12a7" next to my new magic number. -# # MAGIC must change whenever the bytecode emitted by the compiler may no # longer be understood by older implementations of the eval loop (usually # due to the addition of new opcodes). @@ -417,7 +461,7 @@ _code_type = type(_write_atomic.__code__) # Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array # in PC/launcher.c must also be updated. -MAGIC_NUMBER = (3495).to_bytes(2, 'little') + b'\r\n' +MAGIC_NUMBER = (3531).to_bytes(2, 'little') + b'\r\n' _RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c @@ -474,8 +518,8 @@ def cache_from_source(path, debug_override=None, *, optimization=None): optimization = str(optimization) if optimization != '': if not optimization.isalnum(): - raise ValueError('{!r} is not alphanumeric'.format(optimization)) - almost_filename = '{}.{}{}'.format(almost_filename, _OPT, optimization) + raise ValueError(f'{optimization!r} is not alphanumeric') + almost_filename = f'{almost_filename}.{_OPT}{optimization}' filename = almost_filename + BYTECODE_SUFFIXES[0] if sys.pycache_prefix is not None: # We need an absolute path to the py file to avoid the possibility of @@ -486,8 +530,7 @@ def cache_from_source(path, debug_override=None, *, optimization=None): # make it absolute (`C:\Somewhere\Foo\Bar`), then make it root-relative # (`Somewhere\Foo\Bar`), so we end up placing the bytecode file in an # unambiguous `C:\Bytecode\Somewhere\Foo\Bar\`. - if not _path_isabs(head): - head = _path_join(_os.getcwd(), head) + head = _path_abspath(head) # Strip initial drive from a Windows path. We know we have an absolute # path here, so the second part of the check rules out a POSIX path that @@ -619,26 +662,6 @@ def _check_name(method): return _check_name_wrapper -def _find_module_shim(self, fullname): - """Try to find a loader for the specified module by delegating to - self.find_loader(). - - This method is deprecated in favor of finder.find_spec(). - - """ - _warnings.warn("find_module() is deprecated and " - "slated for removal in Python 3.12; use find_spec() instead", - DeprecationWarning) - # Call find_loader(). If it returns a string (indicating this - # is a namespace package portion), generate a warning and - # return None. - loader, portions = self.find_loader(fullname) - if loader is None and len(portions): - msg = 'Not importing directory {}: missing __init__' - _warnings.warn(msg.format(portions[0]), ImportWarning) - return loader - - def _classify_pyc(data, name, exc_details): """Perform basic validity checking of a pyc header and return the flags field, which determines how the pyc should be further validated against the source. @@ -733,7 +756,7 @@ def _compile_bytecode(data, name=None, bytecode_path=None, source_path=None): _imp._fix_co_filename(code, source_path) return code else: - raise ImportError('Non-code object in {!r}'.format(bytecode_path), + raise ImportError(f'Non-code object in {bytecode_path!r}', name=name, path=bytecode_path) @@ -800,11 +823,10 @@ def spec_from_file_location(name, location=None, *, loader=None, pass else: location = _os.fspath(location) - if not _path_isabs(location): - try: - location = _path_join(_os.getcwd(), location) - except OSError: - pass + try: + location = _path_abspath(location) + except OSError: + pass # If the location is on the filesystem, but doesn't actually exist, # we could return None here, indicating that the location is not @@ -846,6 +868,54 @@ def spec_from_file_location(name, location=None, *, loader=None, return spec +def _bless_my_loader(module_globals): + """Helper function for _warnings.c + + See GH#97850 for details. + """ + # 2022-10-06(warsaw): For now, this helper is only used in _warnings.c and + # that use case only has the module globals. This function could be + # extended to accept either that or a module object. However, in the + # latter case, it would be better to raise certain exceptions when looking + # at a module, which should have either a __loader__ or __spec__.loader. + # For backward compatibility, it is possible that we'll get an empty + # dictionary for the module globals, and that cannot raise an exception. + if not isinstance(module_globals, dict): + return None + + missing = object() + loader = module_globals.get('__loader__', None) + spec = module_globals.get('__spec__', missing) + + if loader is None: + if spec is missing: + # If working with a module: + # raise AttributeError('Module globals is missing a __spec__') + return None + elif spec is None: + raise ValueError('Module globals is missing a __spec__.loader') + + spec_loader = getattr(spec, 'loader', missing) + + if spec_loader in (missing, None): + if loader is None: + exc = AttributeError if spec_loader is missing else ValueError + raise exc('Module globals is missing a __spec__.loader') + _warnings.warn( + 'Module globals is missing a __spec__.loader', + DeprecationWarning) + spec_loader = loader + + assert spec_loader is not None + if loader is not None and loader != spec_loader: + _warnings.warn( + 'Module globals; __loader__ != __spec__.loader', + DeprecationWarning) + return loader + + return spec_loader + + # Loaders ##################################################################### class WindowsRegistryFinder: @@ -898,22 +968,6 @@ class WindowsRegistryFinder: origin=filepath) return spec - @classmethod - def find_module(cls, fullname, path=None): - """Find module named in the registry. - - This method is deprecated. Use find_spec() instead. - - """ - _warnings.warn("WindowsRegistryFinder.find_module() is deprecated and " - "slated for removal in Python 3.12; use find_spec() instead", - DeprecationWarning) - spec = cls.find_spec(fullname, path) - if spec is not None: - return spec.loader - else: - return None - class _LoaderBasics: @@ -935,8 +989,8 @@ class _LoaderBasics: """Execute the module.""" code = self.get_code(module.__name__) if code is None: - raise ImportError('cannot load module {!r} when get_code() ' - 'returns None'.format(module.__name__)) + raise ImportError(f'cannot load module {module.__name__!r} when ' + 'get_code() returns None') _bootstrap._call_with_frames_removed(exec, code, module.__dict__) def load_module(self, fullname): @@ -1077,7 +1131,8 @@ class SourceLoader(_LoaderBasics): source_mtime is not None): if hash_based: if source_hash is None: - source_hash = _imp.source_hash(source_bytes) + source_hash = _imp.source_hash(_RAW_MAGIC_NUMBER, + source_bytes) data = _code_to_hash_pyc(code_object, source_hash, check_source) else: data = _code_to_timestamp_pyc(code_object, source_mtime, @@ -1321,7 +1376,7 @@ class _NamespacePath: return len(self._recalculate()) def __repr__(self): - return '_NamespacePath({!r})'.format(self._path) + return f'_NamespacePath({self._path!r})' def __contains__(self, item): return item in self._recalculate() @@ -1332,22 +1387,11 @@ class _NamespacePath: # This class is actually exposed publicly in a namespace package's __loader__ # attribute, so it should be available through a non-private name. -# https://bugs.python.org/issue35673 +# https://github.com/python/cpython/issues/92054 class NamespaceLoader: def __init__(self, name, path, path_finder): self._path = _NamespacePath(name, path, path_finder) - @staticmethod - def module_repr(module): - """Return repr for the module. - - The method is deprecated. The import machinery does the job itself. - - """ - _warnings.warn("NamespaceLoader.module_repr() is deprecated and " - "slated for removal in Python 3.12", DeprecationWarning) - return '<module {!r} (namespace)>'.format(module.__name__) - def is_package(self, fullname): return True @@ -1440,27 +1484,6 @@ class PathFinder: sys.path_importer_cache[path] = finder return finder - @classmethod - def _legacy_get_spec(cls, fullname, finder): - # This would be a good place for a DeprecationWarning if - # we ended up going that route. - if hasattr(finder, 'find_loader'): - msg = (f"{_bootstrap._object_name(finder)}.find_spec() not found; " - "falling back to find_loader()") - _warnings.warn(msg, ImportWarning) - loader, portions = finder.find_loader(fullname) - else: - msg = (f"{_bootstrap._object_name(finder)}.find_spec() not found; " - "falling back to find_module()") - _warnings.warn(msg, ImportWarning) - loader = finder.find_module(fullname) - portions = [] - if loader is not None: - return _bootstrap.spec_from_loader(fullname, loader) - spec = _bootstrap.ModuleSpec(fullname, None) - spec.submodule_search_locations = portions - return spec - @classmethod def _get_spec(cls, fullname, path, target=None): """Find the loader or namespace_path for this module/package name.""" @@ -1472,10 +1495,7 @@ class PathFinder: continue finder = cls._path_importer_cache(entry) if finder is not None: - if hasattr(finder, 'find_spec'): - spec = finder.find_spec(fullname, target) - else: - spec = cls._legacy_get_spec(fullname, finder) + spec = finder.find_spec(fullname, target) if spec is None: continue if spec.loader is not None: @@ -1517,22 +1537,6 @@ class PathFinder: else: return spec - @classmethod - def find_module(cls, fullname, path=None): - """find the module on sys.path or 'path' based on sys.path_hooks and - sys.path_importer_cache. - - This method is deprecated. Use find_spec() instead. - - """ - _warnings.warn("PathFinder.find_module() is deprecated and " - "slated for removal in Python 3.12; use find_spec() instead", - DeprecationWarning) - spec = cls.find_spec(fullname, path) - if spec is None: - return None - return spec.loader - @staticmethod def find_distributions(*args, **kwargs): """ @@ -1567,10 +1571,8 @@ class FileFinder: # Base (directory) path if not path or path == '.': self.path = _os.getcwd() - elif not _path_isabs(path): - self.path = _path_join(_os.getcwd(), path) else: - self.path = path + self.path = _path_abspath(path) self._path_mtime = -1 self._path_cache = set() self._relaxed_path_cache = set() @@ -1579,23 +1581,6 @@ class FileFinder: """Invalidate the directory mtime.""" self._path_mtime = -1 - find_module = _find_module_shim - - def find_loader(self, fullname): - """Try to find a loader for the specified module, or the namespace - package portions. Returns (loader, list-of-portions). - - This method is deprecated. Use find_spec() instead. - - """ - _warnings.warn("FileFinder.find_loader() is deprecated and " - "slated for removal in Python 3.12; use find_spec() instead", - DeprecationWarning) - spec = self.find_spec(fullname) - if spec is None: - return None, [] - return spec.loader, spec.submodule_search_locations or [] - def _get_spec(self, loader_class, fullname, path, smsl, target): loader = loader_class(fullname, path) return spec_from_file_location(fullname, path, loader=loader, @@ -1675,7 +1660,7 @@ class FileFinder: for item in contents: name, dot, suffix = item.partition('.') if dot: - new_name = '{}.{}'.format(name, suffix.lower()) + new_name = f'{name}.{suffix.lower()}' else: new_name = name lower_suffix_contents.add(new_name) @@ -1702,7 +1687,7 @@ class FileFinder: return path_hook_for_FileFinder def __repr__(self): - return 'FileFinder({!r})'.format(self.path) + return f'FileFinder({self.path!r})' # Import setup ############################################################### @@ -1720,6 +1705,8 @@ def _fix_up_module(ns, name, pathname, cpathname=None): loader = SourceFileLoader(name, pathname) if not spec: spec = spec_from_file_location(name, pathname, loader=loader) + if cpathname: + spec.cached = _path_abspath(cpathname) try: ns['__spec__'] = spec ns['__loader__'] = loader diff --git a/Lib/importlib/abc.py b/Lib/importlib/abc.py index 3fa151f3..b56fa94e 100644 --- a/Lib/importlib/abc.py +++ b/Lib/importlib/abc.py @@ -15,20 +15,29 @@ from ._abc import Loader import abc import warnings -# for compatibility with Python 3.10 -from .resources.abc import ResourceReader, Traversable, TraversableResources +from .resources import abc as _resources_abc __all__ = [ - 'Loader', 'Finder', 'MetaPathFinder', 'PathEntryFinder', + 'Loader', 'MetaPathFinder', 'PathEntryFinder', 'ResourceLoader', 'InspectLoader', 'ExecutionLoader', 'FileLoader', 'SourceLoader', - - # for compatibility with Python 3.10 - 'ResourceReader', 'Traversable', 'TraversableResources', ] +def __getattr__(name): + """ + For backwards compatibility, continue to make names + from _resources_abc available through this module. #93963 + """ + if name in _resources_abc.__all__: + obj = getattr(_resources_abc, name) + warnings._deprecated(f"{__name__}.{name}", remove=(3, 14)) + globals()[name] = obj + return obj + raise AttributeError(f'module {__name__!r} has no attribute {name!r}') + + def _register(abstract_cls, *classes): for cls in classes: abstract_cls.register(cls) @@ -40,38 +49,6 @@ def _register(abstract_cls, *classes): abstract_cls.register(frozen_cls) -class Finder(metaclass=abc.ABCMeta): - - """Legacy abstract base class for import finders. - - It may be subclassed for compatibility with legacy third party - reimplementations of the import system. Otherwise, finder - implementations should derive from the more specific MetaPathFinder - or PathEntryFinder ABCs. - - Deprecated since Python 3.3 - """ - - def __init__(self): - warnings.warn("the Finder ABC is deprecated and " - "slated for removal in Python 3.12; use MetaPathFinder " - "or PathEntryFinder instead", - DeprecationWarning) - - @abc.abstractmethod - def find_module(self, fullname, path=None): - """An abstract method that should find a module. - The fullname is a str and the optional path is a str or None. - Returns a Loader object or None. - """ - warnings.warn("importlib.abc.Finder along with its find_module() " - "method are deprecated and " - "slated for removal in Python 3.12; use " - "MetaPathFinder.find_spec() or " - "PathEntryFinder.find_spec() instead", - DeprecationWarning) - - class MetaPathFinder(metaclass=abc.ABCMeta): """Abstract base class for import finders on sys.meta_path.""" @@ -79,27 +56,6 @@ class MetaPathFinder(metaclass=abc.ABCMeta): # We don't define find_spec() here since that would break # hasattr checks we do to support backward compatibility. - def find_module(self, fullname, path): - """Return a loader for the module. - - If no module is found, return None. The fullname is a str and - the path is a list of strings or None. - - This method is deprecated since Python 3.4 in favor of - finder.find_spec(). If find_spec() exists then backwards-compatible - functionality is provided for this method. - - """ - warnings.warn("MetaPathFinder.find_module() is deprecated since Python " - "3.4 in favor of MetaPathFinder.find_spec() and is " - "slated for removal in Python 3.12", - DeprecationWarning, - stacklevel=2) - if not hasattr(self, 'find_spec'): - return None - found = self.find_spec(fullname, path) - return found.loader if found is not None else None - def invalidate_caches(self): """An optional method for clearing the finder's cache, if any. This method is used by importlib.invalidate_caches(). @@ -113,43 +69,6 @@ class PathEntryFinder(metaclass=abc.ABCMeta): """Abstract base class for path entry finders used by PathFinder.""" - # We don't define find_spec() here since that would break - # hasattr checks we do to support backward compatibility. - - def find_loader(self, fullname): - """Return (loader, namespace portion) for the path entry. - - The fullname is a str. The namespace portion is a sequence of - path entries contributing to part of a namespace package. The - sequence may be empty. If loader is not None, the portion will - be ignored. - - The portion will be discarded if another path entry finder - locates the module as a normal module or package. - - This method is deprecated since Python 3.4 in favor of - finder.find_spec(). If find_spec() is provided than backwards-compatible - functionality is provided. - """ - warnings.warn("PathEntryFinder.find_loader() is deprecated since Python " - "3.4 in favor of PathEntryFinder.find_spec() " - "(available since 3.4)", - DeprecationWarning, - stacklevel=2) - if not hasattr(self, 'find_spec'): - return None, [] - found = self.find_spec(fullname) - if found is not None: - if not found.submodule_search_locations: - portions = [] - else: - portions = found.submodule_search_locations - return found.loader, portions - else: - return None, [] - - find_module = _bootstrap_external._find_module_shim - def invalidate_caches(self): """An optional method for clearing the finder's cache, if any. This method is used by PathFinder.invalidate_caches(). diff --git a/Lib/importlib/metadata/__init__.py b/Lib/importlib/metadata/__init__.py index bbdbceeb..82e0ce1b 100644 --- a/Lib/importlib/metadata/__init__.py +++ b/Lib/importlib/metadata/__init__.py @@ -12,7 +12,9 @@ import warnings import functools import itertools import posixpath +import contextlib import collections +import inspect from . import _adapters, _meta from ._collections import FreezableDefaultDict, Pair @@ -24,7 +26,7 @@ from contextlib import suppress from importlib import import_module from importlib.abc import MetaPathFinder from itertools import starmap -from typing import List, Mapping, Optional, Union +from typing import List, Mapping, Optional, cast __all__ = [ @@ -134,6 +136,7 @@ class DeprecatedTuple: 1 """ + # Do not remove prior to 2023-05-01 or Python 3.13 _warn = functools.partial( warnings.warn, "EntryPoint tuple interface is deprecated. Access members by name.", @@ -222,17 +225,6 @@ class EntryPoint(DeprecatedTuple): vars(self).update(dist=dist) return self - def __iter__(self): - """ - Supply iter so one may construct dicts of EntryPoints by name. - """ - msg = ( - "Construction of dict of EntryPoints is deprecated in " - "favor of EntryPoints." - ) - warnings.warn(msg, DeprecationWarning) - return iter((self.name, self)) - def matches(self, **params): """ EntryPoint matches the given parameters. @@ -278,77 +270,7 @@ class EntryPoint(DeprecatedTuple): return hash(self._key()) -class DeprecatedList(list): - """ - Allow an otherwise immutable object to implement mutability - for compatibility. - - >>> recwarn = getfixture('recwarn') - >>> dl = DeprecatedList(range(3)) - >>> dl[0] = 1 - >>> dl.append(3) - >>> del dl[3] - >>> dl.reverse() - >>> dl.sort() - >>> dl.extend([4]) - >>> dl.pop(-1) - 4 - >>> dl.remove(1) - >>> dl += [5] - >>> dl + [6] - [1, 2, 5, 6] - >>> dl + (6,) - [1, 2, 5, 6] - >>> dl.insert(0, 0) - >>> dl - [0, 1, 2, 5] - >>> dl == [0, 1, 2, 5] - True - >>> dl == (0, 1, 2, 5) - True - >>> len(recwarn) - 1 - """ - - __slots__ = () - - _warn = functools.partial( - warnings.warn, - "EntryPoints list interface is deprecated. Cast to list if needed.", - DeprecationWarning, - stacklevel=2, - ) - - def _wrap_deprecated_method(method_name: str): # type: ignore - def wrapped(self, *args, **kwargs): - self._warn() - return getattr(super(), method_name)(*args, **kwargs) - - return method_name, wrapped - - locals().update( - map( - _wrap_deprecated_method, - '__setitem__ __delitem__ append reverse extend pop remove ' - '__iadd__ insert sort'.split(), - ) - ) - - def __add__(self, other): - if not isinstance(other, tuple): - self._warn() - other = tuple(other) - return self.__class__(tuple(self) + other) - - def __eq__(self, other): - if not isinstance(other, tuple): - self._warn() - other = tuple(other) - - return tuple(self).__eq__(other) - - -class EntryPoints(DeprecatedList): +class EntryPoints(tuple): """ An immutable collection of selectable EntryPoint objects. """ @@ -359,14 +281,6 @@ class EntryPoints(DeprecatedList): """ Get the EntryPoint in self matching name. """ - if isinstance(name, int): - warnings.warn( - "Accessing entry points by index is deprecated. " - "Cast to tuple if needed.", - DeprecationWarning, - stacklevel=2, - ) - return super().__getitem__(name) try: return next(iter(self.select(name=name))) except StopIteration: @@ -390,10 +304,6 @@ class EntryPoints(DeprecatedList): def groups(self): """ Return the set of all groups of all entry points. - - For coverage while SelectableGroups is present. - >>> EntryPoints().groups - set() """ return {ep.group for ep in self} @@ -409,101 +319,6 @@ class EntryPoints(DeprecatedList): ) -class Deprecated: - """ - Compatibility add-in for mapping to indicate that - mapping behavior is deprecated. - - >>> recwarn = getfixture('recwarn') - >>> class DeprecatedDict(Deprecated, dict): pass - >>> dd = DeprecatedDict(foo='bar') - >>> dd.get('baz', None) - >>> dd['foo'] - 'bar' - >>> list(dd) - ['foo'] - >>> list(dd.keys()) - ['foo'] - >>> 'foo' in dd - True - >>> list(dd.values()) - ['bar'] - >>> len(recwarn) - 1 - """ - - _warn = functools.partial( - warnings.warn, - "SelectableGroups dict interface is deprecated. Use select.", - DeprecationWarning, - stacklevel=2, - ) - - def __getitem__(self, name): - self._warn() - return super().__getitem__(name) - - def get(self, name, default=None): - self._warn() - return super().get(name, default) - - def __iter__(self): - self._warn() - return super().__iter__() - - def __contains__(self, *args): - self._warn() - return super().__contains__(*args) - - def keys(self): - self._warn() - return super().keys() - - def values(self): - self._warn() - return super().values() - - -class SelectableGroups(Deprecated, dict): - """ - A backward- and forward-compatible result from - entry_points that fully implements the dict interface. - """ - - @classmethod - def load(cls, eps): - by_group = operator.attrgetter('group') - ordered = sorted(eps, key=by_group) - grouped = itertools.groupby(ordered, by_group) - return cls((group, EntryPoints(eps)) for group, eps in grouped) - - @property - def _all(self): - """ - Reconstruct a list of all entrypoints from the groups. - """ - groups = super(Deprecated, self).values() - return EntryPoints(itertools.chain.from_iterable(groups)) - - @property - def groups(self): - return self._all.groups - - @property - def names(self): - """ - for coverage: - >>> SelectableGroups().names - set() - """ - return self._all.names - - def select(self, **params): - if not params: - return self - return self._all.select(**params) - - class PackagePath(pathlib.PurePosixPath): """A reference to a path in a package""" @@ -528,11 +343,30 @@ class FileHash: return f'<FileHash mode: {self.mode} value: {self.value}>' -class Distribution: +class DeprecatedNonAbstract: + def __new__(cls, *args, **kwargs): + all_names = { + name for subclass in inspect.getmro(cls) for name in vars(subclass) + } + abstract = { + name + for name in all_names + if getattr(getattr(cls, name), '__isabstractmethod__', False) + } + if abstract: + warnings.warn( + f"Unimplemented abstract methods {abstract}", + DeprecationWarning, + stacklevel=2, + ) + return super().__new__(cls) + + +class Distribution(DeprecatedNonAbstract): """A Python distribution package.""" @abc.abstractmethod - def read_text(self, filename): + def read_text(self, filename) -> Optional[str]: """Attempt to load metadata file given by the name. :param filename: The name of the file in the distribution info. @@ -606,7 +440,7 @@ class Distribution: The returned object will have keys that name the various bits of metadata. See PEP 566 for details. """ - text = ( + opt_text = ( self.read_text('METADATA') or self.read_text('PKG-INFO') # This last clause is here to support old egg-info files. Its @@ -614,6 +448,7 @@ class Distribution: # (which points to the egg-info file) attribute unchanged. or self.read_text('') ) + text = cast(str, opt_text) return _adapters.Message(email.message_from_string(text)) @property @@ -642,8 +477,8 @@ class Distribution: :return: List of PackagePath for this distribution or None Result is `None` if the metadata file that enumerates files - (i.e. RECORD for dist-info or SOURCES.txt for egg-info) is - missing. + (i.e. RECORD for dist-info, or installed-files.txt or + SOURCES.txt for egg-info) is missing. Result may be empty if the metadata exists but is empty. """ @@ -656,9 +491,19 @@ class Distribution: @pass_none def make_files(lines): - return list(starmap(make_file, csv.reader(lines))) + return starmap(make_file, csv.reader(lines)) - return make_files(self._read_files_distinfo() or self._read_files_egginfo()) + @pass_none + def skip_missing_files(package_paths): + return list(filter(lambda path: path.locate().exists(), package_paths)) + + return skip_missing_files( + make_files( + self._read_files_distinfo() + or self._read_files_egginfo_installed() + or self._read_files_egginfo_sources() + ) + ) def _read_files_distinfo(self): """ @@ -667,10 +512,45 @@ class Distribution: text = self.read_text('RECORD') return text and text.splitlines() - def _read_files_egginfo(self): + def _read_files_egginfo_installed(self): + """ + Read installed-files.txt and return lines in a similar + CSV-parsable format as RECORD: each file must be placed + relative to the site-packages directory and must also be + quoted (since file names can contain literal commas). + + This file is written when the package is installed by pip, + but it might not be written for other installation methods. + Assume the file is accurate if it exists. """ - SOURCES.txt might contain literal commas, so wrap each line - in quotes. + text = self.read_text('installed-files.txt') + # Prepend the .egg-info/ subdir to the lines in this file. + # But this subdir is only available from PathDistribution's + # self._path. + subdir = getattr(self, '_path', None) + if not text or not subdir: + return + + paths = ( + (subdir / name) + .resolve() + .relative_to(self.locate_file('').resolve()) + .as_posix() + for name in text.splitlines() + ) + return map('"{}"'.format, paths) + + def _read_files_egginfo_sources(self): + """ + Read SOURCES.txt and return lines in a similar CSV-parsable + format as RECORD: each file name must be quoted (since it + might contain literal commas). + + Note that SOURCES.txt is not a reliable source for what + files are installed by a package. This file is generated + for a source archive, and the files that are present + there (e.g. setup.py) may not correctly reflect the files + that are present after the package has been installed. """ text = self.read_text('SOURCES.txt') return text and map('"{}"'.format, text.splitlines()) @@ -1017,27 +897,19 @@ Wrapper for ``distributions`` to return unique distributions by name. """ -def entry_points(**params) -> Union[EntryPoints, SelectableGroups]: +def entry_points(**params) -> EntryPoints: """Return EntryPoint objects for all installed packages. Pass selection parameters (group or name) to filter the result to entry points matching those properties (see EntryPoints.select()). - For compatibility, returns ``SelectableGroups`` object unless - selection parameters are supplied. In the future, this function - will return ``EntryPoints`` instead of ``SelectableGroups`` - even when no selection parameters are supplied. - - For maximum future compatibility, pass selection parameters - or invoke ``.select`` with parameters on the result. - - :return: EntryPoints or SelectableGroups for all installed packages. + :return: EntryPoints for all installed packages. """ eps = itertools.chain.from_iterable( dist.entry_points for dist in _unique(distributions()) ) - return SelectableGroups.load(eps).select(**params) + return EntryPoints(eps).select(**params) def files(distribution_name): @@ -1081,8 +953,13 @@ def _top_level_declared(dist): def _top_level_inferred(dist): - return { - f.parts[0] if len(f.parts) > 1 else f.with_suffix('').name + opt_names = { + f.parts[0] if len(f.parts) > 1 else inspect.getmodulename(f) for f in always_iterable(dist.files) - if f.suffix == ".py" } + + @pass_none + def importable_name(name): + return '.' not in name + + return filter(importable_name, opt_names) diff --git a/Lib/importlib/metadata/_adapters.py b/Lib/importlib/metadata/_adapters.py index aa460d3e..6aed69a3 100644 --- a/Lib/importlib/metadata/_adapters.py +++ b/Lib/importlib/metadata/_adapters.py @@ -1,3 +1,5 @@ +import functools +import warnings import re import textwrap import email.message @@ -5,6 +7,15 @@ import email.message from ._text import FoldedCase +# Do not remove prior to 2024-01-01 or Python 3.14 +_warn = functools.partial( + warnings.warn, + "Implicit None on return values is deprecated and will raise KeyErrors.", + DeprecationWarning, + stacklevel=2, +) + + class Message(email.message.Message): multiple_use_keys = set( map( @@ -39,6 +50,16 @@ class Message(email.message.Message): def __iter__(self): return super().__iter__() + def __getitem__(self, item): + """ + Warn users that a ``KeyError`` can be expected when a + mising key is supplied. Ref python/importlib_metadata#371. + """ + res = super().__getitem__(item) + if res is None: + _warn() + return res + def _repair_headers(self): def redent(value): "Correct for RFC822 indentation" diff --git a/Lib/importlib/metadata/_meta.py b/Lib/importlib/metadata/_meta.py index d5c05761..c9a7ef90 100644 --- a/Lib/importlib/metadata/_meta.py +++ b/Lib/importlib/metadata/_meta.py @@ -1,4 +1,5 @@ -from typing import Any, Dict, Iterator, List, Protocol, TypeVar, Union +from typing import Protocol +from typing import Any, Dict, Iterator, List, Optional, TypeVar, Union, overload _T = TypeVar("_T") @@ -17,7 +18,21 @@ class PackageMetadata(Protocol): def __iter__(self) -> Iterator[str]: ... # pragma: no cover - def get_all(self, name: str, failobj: _T = ...) -> Union[List[Any], _T]: + @overload + def get(self, name: str, failobj: None = None) -> Optional[str]: + ... # pragma: no cover + + @overload + def get(self, name: str, failobj: _T) -> Union[str, _T]: + ... # pragma: no cover + + # overload per python/importlib_metadata#435 + @overload + def get_all(self, name: str, failobj: None = None) -> Optional[List[Any]]: + ... # pragma: no cover + + @overload + def get_all(self, name: str, failobj: _T) -> Union[List[Any], _T]: """ Return all values associated with a possibly multi-valued key. """ @@ -29,18 +44,19 @@ class PackageMetadata(Protocol): """ -class SimplePath(Protocol): +class SimplePath(Protocol[_T]): """ A minimal subset of pathlib.Path required by PathDistribution. """ - def joinpath(self) -> 'SimplePath': + def joinpath(self) -> _T: ... # pragma: no cover - def __truediv__(self) -> 'SimplePath': + def __truediv__(self, other: Union[str, _T]) -> _T: ... # pragma: no cover - def parent(self) -> 'SimplePath': + @property + def parent(self) -> _T: ... # pragma: no cover def read_text(self) -> str: diff --git a/Lib/importlib/resources/_adapters.py b/Lib/importlib/resources/_adapters.py index ea363d86..50688fbb 100644 --- a/Lib/importlib/resources/_adapters.py +++ b/Lib/importlib/resources/_adapters.py @@ -34,9 +34,7 @@ def _io_wrapper(file, mode='r', *args, **kwargs): return TextIOWrapper(file, *args, **kwargs) elif mode == 'rb': return file - raise ValueError( - "Invalid mode value '{}', only 'r' and 'rb' are supported".format(mode) - ) + raise ValueError(f"Invalid mode value '{mode}', only 'r' and 'rb' are supported") class CompatibilityFiles: diff --git a/Lib/importlib/resources/_common.py b/Lib/importlib/resources/_common.py index ca1fa8ab..a3902535 100644 --- a/Lib/importlib/resources/_common.py +++ b/Lib/importlib/resources/_common.py @@ -5,25 +5,58 @@ import functools import contextlib import types import importlib +import inspect +import warnings +import itertools -from typing import Union, Optional +from typing import Union, Optional, cast from .abc import ResourceReader, Traversable from ._adapters import wrap_spec Package = Union[types.ModuleType, str] +Anchor = Package -def files(package): - # type: (Package) -> Traversable +def package_to_anchor(func): """ - Get a Traversable resource from a package + Replace 'package' parameter as 'anchor' and warn about the change. + + Other errors should fall through. + + >>> files('a', 'b') + Traceback (most recent call last): + TypeError: files() takes from 0 to 1 positional arguments but 2 were given + """ + undefined = object() + + @functools.wraps(func) + def wrapper(anchor=undefined, package=undefined): + if package is not undefined: + if anchor is not undefined: + return func(anchor, package) + warnings.warn( + "First parameter to files is renamed to 'anchor'", + DeprecationWarning, + stacklevel=2, + ) + return func(package) + elif anchor is undefined: + return func() + return func(anchor) + + return wrapper + + +@package_to_anchor +def files(anchor: Optional[Anchor] = None) -> Traversable: + """ + Get a Traversable resource for an anchor. """ - return from_package(get_package(package)) + return from_package(resolve(anchor)) -def get_resource_reader(package): - # type: (types.ModuleType) -> Optional[ResourceReader] +def get_resource_reader(package: types.ModuleType) -> Optional[ResourceReader]: """ Return the package's loader if it's a ResourceReader. """ @@ -39,24 +72,39 @@ def get_resource_reader(package): return reader(spec.name) # type: ignore -def resolve(cand): - # type: (Package) -> types.ModuleType - return cand if isinstance(cand, types.ModuleType) else importlib.import_module(cand) +@functools.singledispatch +def resolve(cand: Optional[Anchor]) -> types.ModuleType: + return cast(types.ModuleType, cand) + + +@resolve.register +def _(cand: str) -> types.ModuleType: + return importlib.import_module(cand) + +@resolve.register +def _(cand: None) -> types.ModuleType: + return resolve(_infer_caller().f_globals['__name__']) -def get_package(package): - # type: (Package) -> types.ModuleType - """Take a package name or module object and return the module. - Raise an exception if the resolved module is not a package. +def _infer_caller(): """ - resolved = resolve(package) - if wrap_spec(resolved).submodule_search_locations is None: - raise TypeError(f'{package!r} is not a package') - return resolved + Walk the stack and find the frame of the first caller not in this module. + """ + + def is_this_file(frame_info): + return frame_info.filename == __file__ + + def is_wrapper(frame_info): + return frame_info.function == 'wrapper' + + not_this_file = itertools.filterfalse(is_this_file, inspect.stack()) + # also exclude 'wrapper' due to singledispatch in the call stack + callers = itertools.filterfalse(is_wrapper, not_this_file) + return next(callers).frame -def from_package(package): +def from_package(package: types.ModuleType): """ Return a Traversable object for the given package. @@ -67,10 +115,14 @@ def from_package(package): @contextlib.contextmanager -def _tempfile(reader, suffix='', - # gh-93353: Keep a reference to call os.remove() in late Python - # finalization. - *, _os_remove=os.remove): +def _tempfile( + reader, + suffix='', + # gh-93353: Keep a reference to call os.remove() in late Python + # finalization. + *, + _os_remove=os.remove, +): # Not using tempfile.NamedTemporaryFile as it leads to deeper 'try' # blocks due to the need to close the temporary file to work on Windows # properly. @@ -89,13 +141,30 @@ def _tempfile(reader, suffix='', pass +def _temp_file(path): + return _tempfile(path.read_bytes, suffix=path.name) + + +def _is_present_dir(path: Traversable) -> bool: + """ + Some Traversables implement ``is_dir()`` to raise an + exception (i.e. ``FileNotFoundError``) when the + directory doesn't exist. This function wraps that call + to always return a boolean and only return True + if there's a dir and it exists. + """ + with contextlib.suppress(FileNotFoundError): + return path.is_dir() + return False + + @functools.singledispatch def as_file(path): """ Given a Traversable object, return that object as a path on the local file system in a context manager. """ - return _tempfile(path.read_bytes, suffix=path.name) + return _temp_dir(path) if _is_present_dir(path) else _temp_file(path) @as_file.register(pathlib.Path) @@ -105,3 +174,34 @@ def _(path): Degenerate behavior for pathlib.Path objects. """ yield path + + +@contextlib.contextmanager +def _temp_path(dir: tempfile.TemporaryDirectory): + """ + Wrap tempfile.TemporyDirectory to return a pathlib object. + """ + with dir as result: + yield pathlib.Path(result) + + +@contextlib.contextmanager +def _temp_dir(path): + """ + Given a traversable dir, recursively replicate the whole tree + to the file system in a context manager. + """ + assert path.is_dir() + with _temp_path(tempfile.TemporaryDirectory()) as temp_dir: + yield _write_contents(temp_dir, path) + + +def _write_contents(target, source): + child = target.joinpath(source.name) + if source.is_dir(): + child.mkdir() + for item in source.iterdir(): + _write_contents(child, item) + else: + child.write_bytes(source.read_bytes()) + return child diff --git a/Lib/importlib/resources/_itertools.py b/Lib/importlib/resources/_itertools.py index cce05582..7b775ef5 100644 --- a/Lib/importlib/resources/_itertools.py +++ b/Lib/importlib/resources/_itertools.py @@ -1,35 +1,38 @@ -from itertools import filterfalse +# from more_itertools 9.0 +def only(iterable, default=None, too_long=None): + """If *iterable* has only one item, return it. + If it has zero items, return *default*. + If it has more than one item, raise the exception given by *too_long*, + which is ``ValueError`` by default. + >>> only([], default='missing') + 'missing' + >>> only([1]) + 1 + >>> only([1, 2]) # doctest: +IGNORE_EXCEPTION_DETAIL + Traceback (most recent call last): + ... + ValueError: Expected exactly one item in iterable, but got 1, 2, + and perhaps more.' + >>> only([1, 2], too_long=TypeError) # doctest: +IGNORE_EXCEPTION_DETAIL + Traceback (most recent call last): + ... + TypeError + Note that :func:`only` attempts to advance *iterable* twice to ensure there + is only one item. See :func:`spy` or :func:`peekable` to check + iterable contents less destructively. + """ + it = iter(iterable) + first_value = next(it, default) -from typing import ( - Callable, - Iterable, - Iterator, - Optional, - Set, - TypeVar, - Union, -) - -# Type and type variable definitions -_T = TypeVar('_T') -_U = TypeVar('_U') - - -def unique_everseen( - iterable: Iterable[_T], key: Optional[Callable[[_T], _U]] = None -) -> Iterator[_T]: - "List unique elements, preserving order. Remember all elements ever seen." - # unique_everseen('AAAABBBCCDAABBB') --> A B C D - # unique_everseen('ABBCcAD', str.lower) --> A B C D - seen: Set[Union[_T, _U]] = set() - seen_add = seen.add - if key is None: - for element in filterfalse(seen.__contains__, iterable): - seen_add(element) - yield element + try: + second_value = next(it) + except StopIteration: + pass else: - for element in iterable: - k = key(element) - if k not in seen: - seen_add(k) - yield element + msg = ( + 'Expected exactly one item in iterable, but got {!r}, {!r}, ' + 'and perhaps more.'.format(first_value, second_value) + ) + raise too_long or ValueError(msg) + + return first_value diff --git a/Lib/importlib/resources/_legacy.py b/Lib/importlib/resources/_legacy.py index 1d5d3f1f..b1ea8105 100644 --- a/Lib/importlib/resources/_legacy.py +++ b/Lib/importlib/resources/_legacy.py @@ -27,8 +27,7 @@ def deprecated(func): return wrapper -def normalize_path(path): - # type: (Any) -> str +def normalize_path(path: Any) -> str: """Normalize a path by ensuring it is a string. If the resulting string contains path separators, an exception is raised. diff --git a/Lib/importlib/resources/abc.py b/Lib/importlib/resources/abc.py index 0b7bfdc4..6750a7aa 100644 --- a/Lib/importlib/resources/abc.py +++ b/Lib/importlib/resources/abc.py @@ -1,6 +1,8 @@ import abc import io +import itertools import os +import pathlib from typing import Any, BinaryIO, Iterable, Iterator, NoReturn, Text, Optional from typing import runtime_checkable, Protocol from typing import Union @@ -53,6 +55,10 @@ class ResourceReader(metaclass=abc.ABCMeta): raise FileNotFoundError +class TraversalError(Exception): + pass + + @runtime_checkable class Traversable(Protocol): """ @@ -95,7 +101,6 @@ class Traversable(Protocol): Return True if self is a file """ - @abc.abstractmethod def joinpath(self, *descendants: StrPath) -> "Traversable": """ Return Traversable resolved with any descendants applied. @@ -104,6 +109,22 @@ class Traversable(Protocol): and each may contain multiple levels separated by ``posixpath.sep`` (``/``). """ + if not descendants: + return self + names = itertools.chain.from_iterable( + path.parts for path in map(pathlib.PurePosixPath, descendants) + ) + target = next(names) + matches = ( + traversable for traversable in self.iterdir() if traversable.name == target + ) + try: + match = next(matches) + except StopIteration: + raise TraversalError( + "Target not found during traversal.", target, list(names) + ) + return match.joinpath(*names) def __truediv__(self, child: StrPath) -> "Traversable": """ @@ -121,7 +142,8 @@ class Traversable(Protocol): accepted by io.TextIOWrapper. """ - @abc.abstractproperty + @property + @abc.abstractmethod def name(self) -> str: """ The base name of this object without any parent references. diff --git a/Lib/importlib/resources/readers.py b/Lib/importlib/resources/readers.py index b470a206..c3cdf769 100644 --- a/Lib/importlib/resources/readers.py +++ b/Lib/importlib/resources/readers.py @@ -1,11 +1,12 @@ import collections -import operator +import itertools import pathlib +import operator import zipfile from . import abc -from ._itertools import unique_everseen +from ._itertools import only def remove_duplicates(items): @@ -41,8 +42,10 @@ class ZipReader(abc.TraversableResources): raise FileNotFoundError(exc.args[0]) def is_resource(self, path): - # workaround for `zipfile.Path.is_file` returning true - # for non-existent paths. + """ + Workaround for `zipfile.Path.is_file` returning true + for non-existent paths. + """ target = self.files().joinpath(path) return target.is_file() and target.exists() @@ -67,8 +70,10 @@ class MultiplexedPath(abc.Traversable): raise NotADirectoryError('MultiplexedPath only supports directories') def iterdir(self): - files = (file for path in self._paths for file in path.iterdir()) - return unique_everseen(files, key=operator.attrgetter('name')) + children = (child for path in self._paths for child in path.iterdir()) + by_name = operator.attrgetter('name') + groups = itertools.groupby(sorted(children, key=by_name), key=by_name) + return map(self._follow, (locs for name, locs in groups)) def read_bytes(self): raise FileNotFoundError(f'{self} is not a file') @@ -82,15 +87,32 @@ class MultiplexedPath(abc.Traversable): def is_file(self): return False - def joinpath(self, child): - # first try to find child in current paths - for file in self.iterdir(): - if file.name == child: - return file - # if it does not exist, construct it with the first path - return self._paths[0] / child + def joinpath(self, *descendants): + try: + return super().joinpath(*descendants) + except abc.TraversalError: + # One of the paths did not resolve (a directory does not exist). + # Just return something that will not exist. + return self._paths[0].joinpath(*descendants) + + @classmethod + def _follow(cls, children): + """ + Construct a MultiplexedPath if needed. + + If children contains a sole element, return it. + Otherwise, return a MultiplexedPath of the items. + Unless one of the items is not a Directory, then return the first. + """ + subdirs, one_dir, one_file = itertools.tee(children, 3) - __truediv__ = joinpath + try: + return only(one_dir) + except ValueError: + try: + return cls(*subdirs) + except NotADirectoryError: + return next(one_file) def open(self, *args, **kwargs): raise FileNotFoundError(f'{self} is not a file') diff --git a/Lib/importlib/resources/simple.py b/Lib/importlib/resources/simple.py index d0fbf237..7770c922 100644 --- a/Lib/importlib/resources/simple.py +++ b/Lib/importlib/resources/simple.py @@ -16,31 +16,28 @@ class SimpleReader(abc.ABC): provider. """ - @abc.abstractproperty - def package(self): - # type: () -> str + @property + @abc.abstractmethod + def package(self) -> str: """ The name of the package for which this reader loads resources. """ @abc.abstractmethod - def children(self): - # type: () -> List['SimpleReader'] + def children(self) -> List['SimpleReader']: """ Obtain an iterable of SimpleReader for available child containers (e.g. directories). """ @abc.abstractmethod - def resources(self): - # type: () -> List[str] + def resources(self) -> List[str]: """ Obtain available named resources for this virtual package. """ @abc.abstractmethod - def open_binary(self, resource): - # type: (str) -> BinaryIO + def open_binary(self, resource: str) -> BinaryIO: """ Obtain a File-like for a named resource. """ @@ -50,13 +47,35 @@ class SimpleReader(abc.ABC): return self.package.split('.')[-1] +class ResourceContainer(Traversable): + """ + Traversable container for a package's resources via its reader. + """ + + def __init__(self, reader: SimpleReader): + self.reader = reader + + def is_dir(self): + return True + + def is_file(self): + return False + + def iterdir(self): + files = (ResourceHandle(self, name) for name in self.reader.resources) + dirs = map(ResourceContainer, self.reader.children()) + return itertools.chain(files, dirs) + + def open(self, *args, **kwargs): + raise IsADirectoryError() + + class ResourceHandle(Traversable): """ Handle to a named resource in a ResourceReader. """ - def __init__(self, parent, name): - # type: (ResourceContainer, str) -> None + def __init__(self, parent: ResourceContainer, name: str): self.parent = parent self.name = name # type: ignore @@ -76,44 +95,6 @@ class ResourceHandle(Traversable): raise RuntimeError("Cannot traverse into a resource") -class ResourceContainer(Traversable): - """ - Traversable container for a package's resources via its reader. - """ - - def __init__(self, reader): - # type: (SimpleReader) -> None - self.reader = reader - - def is_dir(self): - return True - - def is_file(self): - return False - - def iterdir(self): - files = (ResourceHandle(self, name) for name in self.reader.resources) - dirs = map(ResourceContainer, self.reader.children()) - return itertools.chain(files, dirs) - - def open(self, *args, **kwargs): - raise IsADirectoryError() - - @staticmethod - def _flatten(compound_names): - for name in compound_names: - yield from name.split('/') - - def joinpath(self, *descendants): - if not descendants: - return self - names = self._flatten(descendants) - target = next(names) - return next( - traversable for traversable in self.iterdir() if traversable.name == target - ).joinpath(*names) - - class TraversableReader(TraversableResources, SimpleReader): """ A TraversableResources based on SimpleReader. Resource providers diff --git a/Lib/importlib/util.py b/Lib/importlib/util.py index 8623c898..f4d6e823 100644 --- a/Lib/importlib/util.py +++ b/Lib/importlib/util.py @@ -11,12 +11,9 @@ from ._bootstrap_external import decode_source from ._bootstrap_external import source_from_cache from ._bootstrap_external import spec_from_file_location -from contextlib import contextmanager import _imp -import functools import sys import types -import warnings def source_hash(source_bytes): @@ -63,10 +60,10 @@ def _find_spec_from_path(name, path=None): try: spec = module.__spec__ except AttributeError: - raise ValueError('{}.__spec__ is not set'.format(name)) from None + raise ValueError(f'{name}.__spec__ is not set') from None else: if spec is None: - raise ValueError('{}.__spec__ is None'.format(name)) + raise ValueError(f'{name}.__spec__ is None') return spec @@ -108,115 +105,64 @@ def find_spec(name, package=None): try: spec = module.__spec__ except AttributeError: - raise ValueError('{}.__spec__ is not set'.format(name)) from None + raise ValueError(f'{name}.__spec__ is not set') from None else: if spec is None: - raise ValueError('{}.__spec__ is None'.format(name)) + raise ValueError(f'{name}.__spec__ is None') return spec -@contextmanager -def _module_to_load(name): - is_reload = name in sys.modules - - module = sys.modules.get(name) - if not is_reload: - # This must be done before open() is called as the 'io' module - # implicitly imports 'locale' and would otherwise trigger an - # infinite loop. - module = type(sys)(name) - # This must be done before putting the module in sys.modules - # (otherwise an optimization shortcut in import.c becomes wrong) - module.__initializing__ = True - sys.modules[name] = module - try: - yield module - except Exception: - if not is_reload: - try: - del sys.modules[name] - except KeyError: - pass - finally: - module.__initializing__ = False +# Normally we would use contextlib.contextmanager. However, this module +# is imported by runpy, which means we want to avoid any unnecessary +# dependencies. Thus we use a class. +class _incompatible_extension_module_restrictions: + """A context manager that can temporarily skip the compatibility check. -def set_package(fxn): - """Set __package__ on the returned module. + NOTE: This function is meant to accommodate an unusual case; one + which is likely to eventually go away. There's is a pretty good + chance this is not what you were looking for. - This function is deprecated. + WARNING: Using this function to disable the check can lead to + unexpected behavior and even crashes. It should only be used during + extension module development. - """ - @functools.wraps(fxn) - def set_package_wrapper(*args, **kwargs): - warnings.warn('The import system now takes care of this automatically; ' - 'this decorator is slated for removal in Python 3.12', - DeprecationWarning, stacklevel=2) - module = fxn(*args, **kwargs) - if getattr(module, '__package__', None) is None: - module.__package__ = module.__name__ - if not hasattr(module, '__path__'): - module.__package__ = module.__package__.rpartition('.')[0] - return module - return set_package_wrapper + If "disable_check" is True then the compatibility check will not + happen while the context manager is active. Otherwise the check + *will* happen. + Normally, extensions that do not support multiple interpreters + may not be imported in a subinterpreter. That implies modules + that do not implement multi-phase init or that explicitly of out. -def set_loader(fxn): - """Set __loader__ on the returned module. + Likewise for modules import in a subinterpeter with its own GIL + when the extension does not support a per-interpreter GIL. This + implies the module does not have a Py_mod_multiple_interpreters slot + set to Py_MOD_PER_INTERPRETER_GIL_SUPPORTED. - This function is deprecated. + In both cases, this context manager may be used to temporarily + disable the check for compatible extension modules. + You can get the same effect as this function by implementing the + basic interface of multi-phase init (PEP 489) and lying about + support for mulitple interpreters (or per-interpreter GIL). """ - @functools.wraps(fxn) - def set_loader_wrapper(self, *args, **kwargs): - warnings.warn('The import system now takes care of this automatically; ' - 'this decorator is slated for removal in Python 3.12', - DeprecationWarning, stacklevel=2) - module = fxn(self, *args, **kwargs) - if getattr(module, '__loader__', None) is None: - module.__loader__ = self - return module - return set_loader_wrapper - - -def module_for_loader(fxn): - """Decorator to handle selecting the proper module for loaders. - - The decorated function is passed the module to use instead of the module - name. The module passed in to the function is either from sys.modules if - it already exists or is a new module. If the module is new, then __name__ - is set the first argument to the method, __loader__ is set to self, and - __package__ is set accordingly (if self.is_package() is defined) will be set - before it is passed to the decorated function (if self.is_package() does - not work for the module it will be set post-load). - - If an exception is raised and the decorator created the module it is - subsequently removed from sys.modules. - - The decorator assumes that the decorated function takes the module name as - the second argument. - """ - warnings.warn('The import system now takes care of this automatically; ' - 'this decorator is slated for removal in Python 3.12', - DeprecationWarning, stacklevel=2) - @functools.wraps(fxn) - def module_for_loader_wrapper(self, fullname, *args, **kwargs): - with _module_to_load(fullname) as module: - module.__loader__ = self - try: - is_package = self.is_package(fullname) - except (ImportError, AttributeError): - pass - else: - if is_package: - module.__package__ = fullname - else: - module.__package__ = fullname.rpartition('.')[0] - # If __package__ was not set above, __import__() will do it later. - return fxn(self, module, *args, **kwargs) - - return module_for_loader_wrapper + def __init__(self, *, disable_check): + self.disable_check = bool(disable_check) + + def __enter__(self): + self.old = _imp._override_multi_interp_extensions_check(self.override) + return self + + def __exit__(self, *args): + old = self.old + del self.old + _imp._override_multi_interp_extensions_check(old) + + @property + def override(self): + return -1 if self.disable_check else 1 class _LazyModule(types.ModuleType): diff --git a/Lib/inspect.py b/Lib/inspect.py index bc49e680..a550202b 100644 --- a/Lib/inspect.py +++ b/Lib/inspect.py @@ -34,11 +34,16 @@ __author__ = ('Ka-Ping Yee <ping@lfw.org>', 'Yury Selivanov <yselivanov@sprymix.com>') __all__ = [ + "AGEN_CLOSED", + "AGEN_CREATED", + "AGEN_RUNNING", + "AGEN_SUSPENDED", "ArgInfo", "Arguments", "Attribute", "BlockFinder", "BoundArguments", + "BufferFlags", "CORO_CLOSED", "CORO_CREATED", "CORO_RUNNING", @@ -77,6 +82,8 @@ __all__ = [ "getabsfile", "getargs", "getargvalues", + "getasyncgenlocals", + "getasyncgenstate", "getattr_static", "getblock", "getcallargs", @@ -125,6 +132,7 @@ __all__ = [ "ismodule", "isroutine", "istraceback", + "markcoroutinefunction", "signature", "stack", "trace", @@ -281,30 +289,15 @@ def get_annotations(obj, *, globals=None, locals=None, eval_str=False): # ----------------------------------------------------------- type-checking def ismodule(object): - """Return true if the object is a module. - - Module objects provide these attributes: - __cached__ pathname to byte compiled file - __doc__ documentation string - __file__ filename (missing for built-in modules)""" + """Return true if the object is a module.""" return isinstance(object, types.ModuleType) def isclass(object): - """Return true if the object is a class. - - Class objects provide these attributes: - __doc__ documentation string - __module__ name of module in which this class was defined""" + """Return true if the object is a class.""" return isinstance(object, type) def ismethod(object): - """Return true if the object is an instance method. - - Instance method objects provide these attributes: - __doc__ documentation string - __name__ name with which this method was defined - __func__ function object containing implementation of method - __self__ instance to which this method is bound""" + """Return true if the object is an instance method.""" return isinstance(object, types.MethodType) def ismethoddescriptor(object): @@ -406,12 +399,31 @@ def isgeneratorfunction(obj): See help(isfunction) for a list of attributes.""" return _has_code_flag(obj, CO_GENERATOR) +# A marker for markcoroutinefunction and iscoroutinefunction. +_is_coroutine_marker = object() + +def _has_coroutine_mark(f): + while ismethod(f): + f = f.__func__ + f = functools._unwrap_partial(f) + return getattr(f, "_is_coroutine_marker", None) is _is_coroutine_marker + +def markcoroutinefunction(func): + """ + Decorator to ensure callable is recognised as a coroutine function. + """ + if hasattr(func, '__func__'): + func = func.__func__ + func._is_coroutine_marker = _is_coroutine_marker + return func + def iscoroutinefunction(obj): """Return true if the object is a coroutine function. - Coroutine functions are defined with "async def" syntax. + Coroutine functions are normally defined with "async def" syntax, but may + be marked via markcoroutinefunction. """ - return _has_code_flag(obj, CO_COROUTINE) + return _has_code_flag(obj, CO_COROUTINE) or _has_coroutine_mark(obj) def isasyncgenfunction(obj): """Return true if the object is an asynchronous generator function. @@ -552,7 +564,7 @@ def _getmembers(object, predicate, getter): processed = set() names = dir(object) if isclass(object): - mro = (object,) + getmro(object) + mro = getmro(object) # add any DynamicClassAttributes to the list of names if object is a class; # this may result in duplicate entries if, for example, a virtual # attribute with the same name as a DynamicClassAttribute exists @@ -671,7 +683,7 @@ def classify_class_attrs(cls): if name == '__dict__': raise Exception("__dict__ is special, don't want the proxy") get_obj = getattr(cls, name) - except Exception as exc: + except Exception: pass else: homecls = getattr(get_obj, "__objclass__", homecls) @@ -946,6 +958,9 @@ def getsourcefile(object): elif any(filename.endswith(s) for s in importlib.machinery.EXTENSION_SUFFIXES): return None + # return a filename found in the linecache even if it doesn't exist on disk + if filename in linecache.cache: + return filename if os.path.exists(filename): return filename # only return a non-existent filename if the module has a PEP 302 loader @@ -954,9 +969,6 @@ def getsourcefile(object): return filename elif getattr(getattr(module, "__spec__", None), "loader", None) is not None: return filename - # or it is in the linecache - elif filename in linecache.cache: - return filename def getabsfile(object, _filename=None): """Return an absolute path to the source or compiled file for an object. @@ -1230,6 +1242,14 @@ def getblock(lines): blockfinder.tokeneater(*_token) except (EndOfBlock, IndentationError): pass + except SyntaxError as e: + if "unmatched" not in e.msg: + raise e from None + _, *_token_info = _token + try: + blockfinder.tokeneater(tokenize.NEWLINE, *_token_info) + except (EndOfBlock, IndentationError): + pass return lines[:blockfinder.last] def getsourcelines(object): @@ -1317,7 +1337,6 @@ def getargs(co): nkwargs = co.co_kwonlyargcount args = list(names[:nargs]) kwonlyargs = list(names[nargs:nargs+nkwargs]) - step = 0 nargs += nkwargs varargs = None @@ -1756,15 +1775,17 @@ def stack(context=1): def trace(context=1): """Return a list of records for the stack below the current exception.""" - return getinnerframes(sys.exc_info()[2], context) + exc = sys.exception() + tb = None if exc is None else exc.__traceback__ + return getinnerframes(tb, context) # ------------------------------------------------ static version of getattr _sentinel = object() +_static_getmro = type.__dict__['__mro__'].__get__ +_get_dunder_dict_of_class = type.__dict__["__dict__"].__get__ -def _static_getmro(klass): - return type.__dict__['__mro__'].__get__(klass) def _check_instance(obj, attr): instance_dict = {} @@ -1777,34 +1798,25 @@ def _check_instance(obj, attr): def _check_class(klass, attr): for entry in _static_getmro(klass): - if _shadowed_dict(type(entry)) is _sentinel: - try: - return entry.__dict__[attr] - except KeyError: - pass + if _shadowed_dict(type(entry)) is _sentinel and attr in entry.__dict__: + return entry.__dict__[attr] return _sentinel -def _is_type(obj): - try: - _static_getmro(obj) - except TypeError: - return False - return True - -def _shadowed_dict(klass): - dict_attr = type.__dict__["__dict__"] - for entry in _static_getmro(klass): - try: - class_dict = dict_attr.__get__(entry)["__dict__"] - except KeyError: - pass - else: +@functools.lru_cache() +def _shadowed_dict_from_mro_tuple(mro): + for entry in mro: + dunder_dict = _get_dunder_dict_of_class(entry) + if '__dict__' in dunder_dict: + class_dict = dunder_dict['__dict__'] if not (type(class_dict) is types.GetSetDescriptorType and class_dict.__name__ == "__dict__" and class_dict.__objclass__ is entry): return class_dict return _sentinel +def _shadowed_dict(klass): + return _shadowed_dict_from_mro_tuple(_static_getmro(klass)) + def getattr_static(obj, attr, default=_sentinel): """Retrieve attributes without triggering dynamic lookup via the descriptor protocol, __getattr__ or __getattribute__. @@ -1817,8 +1829,10 @@ def getattr_static(obj, attr, default=_sentinel): documentation for details. """ instance_result = _sentinel - if not _is_type(obj): - klass = type(obj) + + objtype = type(obj) + if type not in _static_getmro(objtype): + klass = objtype dict_attr = _shadowed_dict(klass) if (dict_attr is _sentinel or type(dict_attr) is types.MemberDescriptorType): @@ -1829,8 +1843,10 @@ def getattr_static(obj, attr, default=_sentinel): klass_result = _check_class(klass, attr) if instance_result is not _sentinel and klass_result is not _sentinel: - if (_check_class(type(klass_result), '__get__') is not _sentinel and - _check_class(type(klass_result), '__set__') is not _sentinel): + if _check_class(type(klass_result), "__get__") is not _sentinel and ( + _check_class(type(klass_result), "__set__") is not _sentinel + or _check_class(type(klass_result), "__delete__") is not _sentinel + ): return klass_result if instance_result is not _sentinel: @@ -1841,11 +1857,11 @@ def getattr_static(obj, attr, default=_sentinel): if obj is klass: # for types we check the metaclass too for entry in _static_getmro(type(klass)): - if _shadowed_dict(type(entry)) is _sentinel: - try: - return entry.__dict__[attr] - except KeyError: - pass + if ( + _shadowed_dict(type(entry)) is _sentinel + and attr in entry.__dict__ + ): + return entry.__dict__[attr] if default is not _sentinel: return default raise AttributeError(attr) @@ -1931,6 +1947,50 @@ def getcoroutinelocals(coroutine): return {} +# ----------------------------------- asynchronous generator introspection + +AGEN_CREATED = 'AGEN_CREATED' +AGEN_RUNNING = 'AGEN_RUNNING' +AGEN_SUSPENDED = 'AGEN_SUSPENDED' +AGEN_CLOSED = 'AGEN_CLOSED' + + +def getasyncgenstate(agen): + """Get current state of an asynchronous generator object. + + Possible states are: + AGEN_CREATED: Waiting to start execution. + AGEN_RUNNING: Currently being executed by the interpreter. + AGEN_SUSPENDED: Currently suspended at a yield expression. + AGEN_CLOSED: Execution has completed. + """ + if agen.ag_running: + return AGEN_RUNNING + if agen.ag_suspended: + return AGEN_SUSPENDED + if agen.ag_frame is None: + return AGEN_CLOSED + return AGEN_CREATED + + +def getasyncgenlocals(agen): + """ + Get the mapping of asynchronous generator local variables to their current + values. + + A dict is returned, with the keys the local variable names and values the + bound values.""" + + if not isasyncgen(agen): + raise TypeError(f"{agen!r} is not a Python async generator") + + frame = getattr(agen, "ag_frame", None) + if frame is not None: + return agen.ag_frame.f_locals + else: + return {} + + ############################################################################### ### Function Signature Object (PEP 362) ############################################################################### @@ -2102,26 +2162,21 @@ def _signature_strip_non_python_syntax(signature): Private helper function. Takes a signature in Argument Clinic's extended signature format. - Returns a tuple of three things: - * that signature re-rendered in standard Python syntax, + Returns a tuple of two things: + * that signature re-rendered in standard Python syntax, and * the index of the "self" parameter (generally 0), or None if - the function does not have a "self" parameter, and - * the index of the last "positional only" parameter, - or None if the signature has no positional-only parameters. + the function does not have a "self" parameter. """ if not signature: - return signature, None, None + return signature, None self_parameter = None - last_positional_only = None lines = [l.encode('ascii') for l in signature.split('\n') if l] generator = iter(lines).__next__ token_stream = tokenize.tokenize(generator) - delayed_comma = False - skip_next_comma = False text = [] add = text.append @@ -2138,35 +2193,18 @@ def _signature_strip_non_python_syntax(signature): if type == OP: if string == ',': - if skip_next_comma: - skip_next_comma = False - else: - assert not delayed_comma - delayed_comma = True - current_parameter += 1 - continue - - if string == '/': - assert not skip_next_comma - assert last_positional_only is None - skip_next_comma = True - last_positional_only = current_parameter - 1 - continue + current_parameter += 1 - if (type == ERRORTOKEN) and (string == '$'): + if (type == OP) and (string == '$'): assert self_parameter is None self_parameter = current_parameter continue - if delayed_comma: - delayed_comma = False - if not ((type == OP) and (string == ')')): - add(', ') add(string) if (string == ','): add(' ') - clean_signature = ''.join(text) - return clean_signature, self_parameter, last_positional_only + clean_signature = ''.join(text).strip().replace("\n", "") + return clean_signature, self_parameter def _signature_fromstr(cls, obj, s, skip_bound_arg=True): @@ -2175,8 +2213,7 @@ def _signature_fromstr(cls, obj, s, skip_bound_arg=True): """ Parameter = cls._parameter_cls - clean_signature, self_parameter, last_positional_only = \ - _signature_strip_non_python_syntax(s) + clean_signature, self_parameter = _signature_strip_non_python_syntax(s) program = "def foo" + clean_signature + ": pass" @@ -2265,17 +2302,17 @@ def _signature_fromstr(cls, obj, s, skip_bound_arg=True): parameters.append(Parameter(name, kind, default=default, annotation=empty)) # non-keyword-only parameters - args = reversed(f.args.args) - defaults = reversed(f.args.defaults) - iter = itertools.zip_longest(args, defaults, fillvalue=None) - if last_positional_only is not None: - kind = Parameter.POSITIONAL_ONLY - else: - kind = Parameter.POSITIONAL_OR_KEYWORD - for i, (name, default) in enumerate(reversed(list(iter))): + total_non_kw_args = len(f.args.posonlyargs) + len(f.args.args) + required_non_kw_args = total_non_kw_args - len(f.args.defaults) + defaults = itertools.chain(itertools.repeat(None, required_non_kw_args), f.args.defaults) + + kind = Parameter.POSITIONAL_ONLY + for (name, default) in zip(f.args.posonlyargs, defaults): + p(name, default) + + kind = Parameter.POSITIONAL_OR_KEYWORD + for (name, default) in zip(f.args.args, defaults): p(name, default) - if i == last_positional_only: - kind = Parameter.POSITIONAL_OR_KEYWORD # *args if f.args.vararg: @@ -2474,10 +2511,18 @@ def _signature_from_callable(obj, *, pass else: if sig is not None: + # since __text_signature__ is not writable on classes, __signature__ + # may contain text (or be a callable that returns text); + # if so, convert it + o_sig = sig + if not isinstance(sig, (Signature, str)) and callable(sig): + sig = sig() + if isinstance(sig, str): + sig = _signature_fromstr(sigcls, obj, sig) if not isinstance(sig, Signature): raise TypeError( 'unexpected object {!r} in __signature__ ' - 'attribute'.format(sig)) + 'attribute'.format(o_sig)) return sig try: @@ -2536,17 +2581,18 @@ def _signature_from_callable(obj, *, factory_method = None new = _signature_get_user_defined_method(obj, '__new__') init = _signature_get_user_defined_method(obj, '__init__') - # Now we check if the 'obj' class has an own '__new__' method - if '__new__' in obj.__dict__: - factory_method = new - # or an own '__init__' method - elif '__init__' in obj.__dict__: - factory_method = init - # If not, we take inherited '__new__' or '__init__', if present - elif new is not None: - factory_method = new - elif init is not None: - factory_method = init + + # Go through the MRO and see if any class has user-defined + # pure Python __new__ or __init__ method + for base in obj.__mro__: + # Now we check if the 'obj' class has an own '__new__' method + if new is not None and '__new__' in base.__dict__: + factory_method = new + break + # or an own '__init__' method + elif init is not None and '__init__' in base.__dict__: + factory_method = init + break if factory_method is not None: sig = _get_signature_of(factory_method) @@ -2793,7 +2839,7 @@ class Parameter: return '<{} "{}">'.format(self.__class__.__name__, self) def __hash__(self): - return hash((self.name, self.kind, self.annotation, self.default)) + return hash((self._name, self._kind, self._annotation, self._default)) def __eq__(self, other): if self is other: @@ -2978,7 +3024,7 @@ class Signature: if __validate_parameters__: params = OrderedDict() top_kind = _POSITIONAL_ONLY - kind_defaults = False + seen_default = False for param in parameters: kind = param.kind @@ -2993,21 +3039,19 @@ class Signature: kind.description) raise ValueError(msg) elif kind > top_kind: - kind_defaults = False top_kind = kind if kind in (_POSITIONAL_ONLY, _POSITIONAL_OR_KEYWORD): if param.default is _empty: - if kind_defaults: + if seen_default: # No default for this parameter, but the - # previous parameter of the same kind had - # a default + # previous parameter of had a default msg = 'non-default argument follows default ' \ 'argument' raise ValueError(msg) else: # There is a default for this parameter. - kind_defaults = True + seen_default = True if name in params: msg = 'duplicate parameter name: {!r}'.format(name) @@ -3121,8 +3165,12 @@ class Signature: parameters_ex = (param,) break else: - msg = 'missing a required argument: {arg!r}' - msg = msg.format(arg=param.name) + if param.kind == _KEYWORD_ONLY: + argtype = ' keyword-only' + else: + argtype = '' + msg = 'missing a required{argtype} argument: {arg!r}' + msg = msg.format(arg=param.name, argtype=argtype) raise TypeError(msg) from None else: # We have a positional argument to process @@ -3280,6 +3328,28 @@ def signature(obj, *, follow_wrapped=True, globals=None, locals=None, eval_str=F globals=globals, locals=locals, eval_str=eval_str) +class BufferFlags(enum.IntFlag): + SIMPLE = 0x0 + WRITABLE = 0x1 + FORMAT = 0x4 + ND = 0x8 + STRIDES = 0x10 | ND + C_CONTIGUOUS = 0x20 | STRIDES + F_CONTIGUOUS = 0x40 | STRIDES + ANY_CONTIGUOUS = 0x80 | STRIDES + INDIRECT = 0x100 | STRIDES + CONTIG = ND | WRITABLE + CONTIG_RO = ND + STRIDED = STRIDES | WRITABLE + STRIDED_RO = STRIDES + RECORDS = STRIDES | WRITABLE | FORMAT + RECORDS_RO = STRIDES | FORMAT + FULL = INDIRECT | WRITABLE | FORMAT + FULL_RO = INDIRECT | FORMAT + READ = 0x100 + WRITE = 0x200 + + def _main(): """ Logic for inspecting an object given at command line """ import argparse diff --git a/Lib/io.py b/Lib/io.py index a4186499..50ce9743 100644 --- a/Lib/io.py +++ b/Lib/io.py @@ -57,22 +57,6 @@ from _io import (DEFAULT_BUFFER_SIZE, BlockingIOError, UnsupportedOperation, IncrementalNewlineDecoder, text_encoding, TextIOWrapper) -def __getattr__(name): - if name == "OpenWrapper": - # bpo-43680: Until Python 3.9, _pyio.open was not a static method and - # builtins.open was set to OpenWrapper to not become a bound method - # when set to a class variable. _io.open is a built-in function whereas - # _pyio.open is a Python function. In Python 3.10, _pyio.open() is now - # a static method, and builtins.open() is now io.open(). - import warnings - warnings.warn('OpenWrapper is deprecated, use open instead', - DeprecationWarning, stacklevel=2) - global OpenWrapper - OpenWrapper = open - return OpenWrapper - raise AttributeError(f"module {__name__!r} has no attribute {name!r}") - - # Pretend this exception was created here. UnsupportedOperation.__module__ = "io" diff --git a/Lib/ipaddress.py b/Lib/ipaddress.py index 1cb71d80..af1d5c48 100644 --- a/Lib/ipaddress.py +++ b/Lib/ipaddress.py @@ -1821,9 +1821,6 @@ class _BaseV6: def _explode_shorthand_ip_string(self): """Expand a shortened IPv6 address. - Args: - ip_str: A string, the IPv6 address. - Returns: A string, the expanded IPv6 address. diff --git a/Lib/keyword.py b/Lib/keyword.py index cc2b46b7..e22c8378 100644 --- a/Lib/keyword.py +++ b/Lib/keyword.py @@ -56,7 +56,8 @@ kwlist = [ softkwlist = [ '_', 'case', - 'match' + 'match', + 'type' ] iskeyword = frozenset(kwlist).__contains__ diff --git a/Lib/lib2to3/pgen2/token.py b/Lib/lib2to3/pgen2/token.py index 5f6612f5..2a55138e 100755 --- a/Lib/lib2to3/pgen2/token.py +++ b/Lib/lib2to3/pgen2/token.py @@ -72,7 +72,7 @@ NT_OFFSET = 256 tok_name = {} for _name, _value in list(globals().items()): - if type(_value) is type(0): + if isinstance(_value, int): tok_name[_value] = _name diff --git a/Lib/locale.py b/Lib/locale.py index 7a7694e1..e94f0d1a 100644 --- a/Lib/locale.py +++ b/Lib/locale.py @@ -26,7 +26,7 @@ import functools # trying the import. So __all__ is also fiddled at the end of the file. __all__ = ["getlocale", "getdefaultlocale", "getpreferredencoding", "Error", "setlocale", "resetlocale", "localeconv", "strcoll", "strxfrm", - "str", "atof", "atoi", "format", "format_string", "currency", + "str", "atof", "atoi", "format_string", "currency", "normalize", "LC_CTYPE", "LC_COLLATE", "LC_TIME", "LC_MONETARY", "LC_NUMERIC", "LC_ALL", "CHAR_MAX", "getencoding"] @@ -247,21 +247,6 @@ def format_string(f, val, grouping=False, monetary=False): return new_f % val -def format(percent, value, grouping=False, monetary=False, *additional): - """Deprecated, use format_string instead.""" - import warnings - warnings.warn( - "This method will be removed in a future version of Python. " - "Use 'locale.format_string()' instead.", - DeprecationWarning, stacklevel=2 - ) - - match = _percent_re.match(percent) - if not match or len(match.group())!= len(percent): - raise ValueError(("format() must be given exactly one %%char " - "format specifier, %s not valid") % repr(percent)) - return _format(percent, value, grouping, monetary, *additional) - def currency(val, symbol=True, grouping=False, international=False): """Formats val according to the currency settings in the current locale.""" @@ -560,7 +545,9 @@ def getdefaultlocale(envvars=('LC_ALL', 'LC_CTYPE', 'LANG', 'LANGUAGE')): "Use setlocale(), getencoding() and getlocale() instead", DeprecationWarning, stacklevel=2 ) + return _getdefaultlocale(envvars) +def _getdefaultlocale(envvars=('LC_ALL', 'LC_CTYPE', 'LANG', 'LANGUAGE')): try: # check if it's supported by the _locale module import _locale @@ -654,7 +641,7 @@ except ImportError: # On Android langinfo.h and CODESET are missing, and UTF-8 is # always used in mbstowcs() and wcstombs(). return 'utf-8' - encoding = getdefaultlocale()[1] + encoding = _getdefaultlocale()[1] if encoding is None: # LANG not set, default to UTF-8 encoding = 'utf-8' @@ -975,7 +962,7 @@ locale_alias = { 'c.ascii': 'C', 'c.en': 'C', 'c.iso88591': 'en_US.ISO8859-1', - 'c.utf8': 'en_US.UTF-8', + 'c.utf8': 'C.UTF-8', 'c_c': 'C', 'c_c.c': 'C', 'ca': 'ca_ES.ISO8859-1', diff --git a/Lib/logging/__init__.py b/Lib/logging/__init__.py index bcee2bab..056380fb 100644 --- a/Lib/logging/__init__.py +++ b/Lib/logging/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2001-2019 by Vinay Sajip. All Rights Reserved. +# Copyright 2001-2022 by Vinay Sajip. All Rights Reserved. # # Permission to use, copy, modify, and distribute this software and its # documentation for any purpose and without fee is hereby granted, @@ -18,7 +18,7 @@ Logging package for Python. Based on PEP 282 and comments thereto in comp.lang.python. -Copyright (C) 2001-2019 Vinay Sajip. All Rights Reserved. +Copyright (C) 2001-2022 Vinay Sajip. All Rights Reserved. To use, simply 'import logging' and log away! """ @@ -38,7 +38,8 @@ __all__ = ['BASIC_FORMAT', 'BufferingFormatter', 'CRITICAL', 'DEBUG', 'ERROR', 'exception', 'fatal', 'getLevelName', 'getLogger', 'getLoggerClass', 'info', 'log', 'makeLogRecord', 'setLoggerClass', 'shutdown', 'warn', 'warning', 'getLogRecordFactory', 'setLogRecordFactory', - 'lastResort', 'raiseExceptions', 'getLevelNamesMapping'] + 'lastResort', 'raiseExceptions', 'getLevelNamesMapping', + 'getHandlerByName', 'getHandlerNames'] import threading @@ -64,20 +65,25 @@ _startTime = time.time() raiseExceptions = True # -# If you don't want threading information in the log, set this to zero +# If you don't want threading information in the log, set this to False # logThreads = True # -# If you don't want multiprocessing information in the log, set this to zero +# If you don't want multiprocessing information in the log, set this to False # logMultiprocessing = True # -# If you don't want process information in the log, set this to zero +# If you don't want process information in the log, set this to False # logProcesses = True +# +# If you don't want asyncio task information in the log, set this to False +# +logAsyncioTasks = True + #--------------------------------------------------------------------------- # Level related stuff #--------------------------------------------------------------------------- @@ -167,8 +173,8 @@ else: #pragma: no cover """Return the frame object for the caller's stack frame.""" try: raise Exception - except Exception: - return sys.exc_info()[2].tb_frame.f_back + except Exception as exc: + return exc.__traceback__.tb_frame.f_back # # _srcfile is used when walking the stack to check when we've got the first @@ -361,6 +367,15 @@ class LogRecord(object): else: self.process = None + self.taskName = None + if logAsyncioTasks: + asyncio = sys.modules.get('asyncio') + if asyncio: + try: + self.taskName = asyncio.current_task().get_name() + except Exception: + pass + def __repr__(self): return '<LogRecord: %s, %s, %s, %s, "%s">'%(self.name, self.levelno, self.pathname, self.lineno, self.msg) @@ -566,6 +581,7 @@ class Formatter(object): (typically at application startup time) %(thread)d Thread ID (if available) %(threadName)s Thread name (if available) + %(taskName)s Task name (if available) %(process)d Process ID (if available) %(message)s The result of record.getMessage(), computed just as the record is emitted @@ -817,23 +833,36 @@ class Filterer(object): Determine if a record is loggable by consulting all the filters. The default is to allow the record to be logged; any filter can veto - this and the record is then dropped. Returns a zero value if a record - is to be dropped, else non-zero. + this by returning a false value. + If a filter attached to a handler returns a log record instance, + then that instance is used in place of the original log record in + any further processing of the event by that handler. + If a filter returns any other true value, the original log record + is used in any further processing of the event by that handler. + + If none of the filters return false values, this method returns + a log record. + If any of the filters return a false value, this method returns + a false value. .. versionchanged:: 3.2 Allow filters to be just callables. + + .. versionchanged:: 3.12 + Allow filters to return a LogRecord instead of + modifying it in place. """ - rv = True for f in self.filters: if hasattr(f, 'filter'): result = f.filter(record) else: result = f(record) # assume callable - will raise if not if not result: - rv = False - break - return rv + return False + if isinstance(result, LogRecord): + record = result + return record #--------------------------------------------------------------------------- # Handler classes and functions @@ -870,6 +899,23 @@ def _addHandlerRef(handler): finally: _releaseLock() + +def getHandlerByName(name): + """ + Get a handler with the specified *name*, or None if there isn't one with + that name. + """ + return _handlers.get(name) + + +def getHandlerNames(): + """ + Return all known handler names as an immutable set. + """ + result = set(_handlers.keys()) + return frozenset(result) + + class Handler(Filterer): """ Handler instances dispatch logging events to specific destinations. @@ -968,10 +1014,14 @@ class Handler(Filterer): Emission depends on filters which may have been added to the handler. Wrap the actual emission of the record with acquisition/release of - the I/O thread lock. Returns whether the filter passed the record for - emission. + the I/O thread lock. + + Returns an instance of the log record that was emitted + if it passed all filters, otherwise a false value is returned. """ rv = self.filter(record) + if isinstance(rv, LogRecord): + record = rv if rv: self.acquire() try: @@ -1483,7 +1533,7 @@ class Logger(Filterer): To pass exception information, use the keyword argument exc_info with a true value, e.g. - logger.info("Houston, we have a %s", "interesting problem", exc_info=1) + logger.info("Houston, we have a %s", "notable problem", exc_info=1) """ if self.isEnabledFor(INFO): self._log(INFO, msg, args, **kwargs) @@ -1640,8 +1690,14 @@ class Logger(Filterer): This method is used for unpickled records received from a socket, as well as those created locally. Logger-level filtering is applied. """ - if (not self.disabled) and self.filter(record): - self.callHandlers(record) + if self.disabled: + return + maybe_record = self.filter(record) + if not maybe_record: + return + if isinstance(maybe_record, LogRecord): + record = maybe_record + self.callHandlers(record) def addHandler(self, hdlr): """ @@ -1772,6 +1828,25 @@ class Logger(Filterer): suffix = '.'.join((self.name, suffix)) return self.manager.getLogger(suffix) + def getChildren(self): + + def _hierlevel(logger): + if logger is logger.manager.root: + return 0 + return 1 + logger.name.count('.') + + d = self.manager.loggerDict + _acquireLock() + try: + # exclude PlaceHolders - the last check is to ensure that lower-level + # descendants aren't returned - if there are placeholders, a logger's + # parent field might point to a grandparent or ancestor thereof. + return set(item for item in d.values() + if isinstance(item, Logger) and item.parent is self and + _hierlevel(item) == 1 + _hierlevel(item.parent)) + finally: + _releaseLock() + def __repr__(self): level = getLevelName(self.getEffectiveLevel()) return '<%s %s (%s)>' % (self.__class__.__name__, self.name, level) @@ -2189,7 +2264,11 @@ def shutdown(handlerList=_handlerList): if h: try: h.acquire() - h.flush() + # MemoryHandlers might not want to be flushed on close, + # but circular imports prevent us scoping this to just + # those handlers. hence the default to True. + if getattr(h, 'flushOnClose', True): + h.flush() h.close() except (OSError, ValueError): # Ignore errors which might be caused diff --git a/Lib/logging/config.py b/Lib/logging/config.py index f9ef7b53..a68281d3 100644 --- a/Lib/logging/config.py +++ b/Lib/logging/config.py @@ -1,4 +1,4 @@ -# Copyright 2001-2019 by Vinay Sajip. All Rights Reserved. +# Copyright 2001-2022 by Vinay Sajip. All Rights Reserved. # # Permission to use, copy, modify, and distribute this software and its # documentation for any purpose and without fee is hereby granted, @@ -19,15 +19,18 @@ Configuration functions for the logging package for Python. The core package is based on PEP 282 and comments thereto in comp.lang.python, and influenced by Apache's log4j system. -Copyright (C) 2001-2019 Vinay Sajip. All Rights Reserved. +Copyright (C) 2001-2022 Vinay Sajip. All Rights Reserved. To use, simply 'import logging' and log away! """ import errno +import functools import io import logging import logging.handlers +import os +import queue import re import struct import threading @@ -58,15 +61,24 @@ def fileConfig(fname, defaults=None, disable_existing_loggers=True, encoding=Non """ import configparser + if isinstance(fname, str): + if not os.path.exists(fname): + raise FileNotFoundError(f"{fname} doesn't exist") + elif not os.path.getsize(fname): + raise RuntimeError(f'{fname} is an empty file') + if isinstance(fname, configparser.RawConfigParser): cp = fname else: - cp = configparser.ConfigParser(defaults) - if hasattr(fname, 'readline'): - cp.read_file(fname) - else: - encoding = io.text_encoding(encoding) - cp.read(fname, encoding=encoding) + try: + cp = configparser.ConfigParser(defaults) + if hasattr(fname, 'readline'): + cp.read_file(fname) + else: + encoding = io.text_encoding(encoding) + cp.read(fname, encoding=encoding) + except configparser.ParsingError as e: + raise RuntimeError(f'{fname} is invalid: {e}') formatters = _create_formatters(cp) @@ -112,11 +124,18 @@ def _create_formatters(cp): fs = cp.get(sectname, "format", raw=True, fallback=None) dfs = cp.get(sectname, "datefmt", raw=True, fallback=None) stl = cp.get(sectname, "style", raw=True, fallback='%') + defaults = cp.get(sectname, "defaults", raw=True, fallback=None) + c = logging.Formatter class_name = cp[sectname].get("class") if class_name: c = _resolve(class_name) - f = c(fs, dfs, stl) + + if defaults is not None: + defaults = eval(defaults, vars(logging)) + f = c(fs, dfs, stl, defaults=defaults) + else: + f = c(fs, dfs, stl) formatters[form] = f return formatters @@ -563,7 +582,7 @@ class DictConfigurator(BaseConfigurator): handler.name = name handlers[name] = handler except Exception as e: - if 'target not configured yet' in str(e.__cause__): + if ' not configured yet' in str(e.__cause__): deferred.append(name) else: raise ValueError('Unable to configure handler ' @@ -666,18 +685,27 @@ class DictConfigurator(BaseConfigurator): dfmt = config.get('datefmt', None) style = config.get('style', '%') cname = config.get('class', None) + defaults = config.get('defaults', None) if not cname: c = logging.Formatter else: c = _resolve(cname) + kwargs = {} + + # Add defaults only if it exists. + # Prevents TypeError in custom formatter callables that do not + # accept it. + if defaults is not None: + kwargs['defaults'] = defaults + # A TypeError would be raised if "validate" key is passed in with a formatter callable # that does not accept "validate" as a parameter if 'validate' in config: # if user hasn't mentioned it, the default will be fine - result = c(fmt, dfmt, style, config['validate']) + result = c(fmt, dfmt, style, config['validate'], **kwargs) else: - result = c(fmt, dfmt, style) + result = c(fmt, dfmt, style, **kwargs) return result @@ -702,6 +730,21 @@ class DictConfigurator(BaseConfigurator): except Exception as e: raise ValueError('Unable to add filter %r' % f) from e + def _configure_queue_handler(self, klass, **kwargs): + if 'queue' in kwargs: + q = kwargs['queue'] + else: + q = queue.Queue() # unbounded + rhl = kwargs.get('respect_handler_level', False) + if 'listener' in kwargs: + lklass = kwargs['listener'] + else: + lklass = logging.handlers.QueueListener + listener = lklass(q, *kwargs['handlers'], respect_handler_level=rhl) + handler = klass(q) + handler.listener = listener + return handler + def configure_handler(self, config): """Configure a handler from a dictionary.""" config_copy = dict(config) # for restoring in case of error @@ -721,26 +764,83 @@ class DictConfigurator(BaseConfigurator): factory = c else: cname = config.pop('class') - klass = self.resolve(cname) - #Special case for handler which refers to another handler + if callable(cname): + klass = cname + else: + klass = self.resolve(cname) if issubclass(klass, logging.handlers.MemoryHandler) and\ 'target' in config: + # Special case for handler which refers to another handler try: - th = self.config['handlers'][config['target']] + tn = config['target'] + th = self.config['handlers'][tn] if not isinstance(th, logging.Handler): config.update(config_copy) # restore for deferred cfg raise TypeError('target not configured yet') config['target'] = th except Exception as e: - raise ValueError('Unable to set target handler ' - '%r' % config['target']) from e + raise ValueError('Unable to set target handler %r' % tn) from e + elif issubclass(klass, logging.handlers.QueueHandler): + # Another special case for handler which refers to other handlers + if 'handlers' not in config: + raise ValueError('No handlers specified for a QueueHandler') + if 'queue' in config: + qspec = config['queue'] + if not isinstance(qspec, queue.Queue): + if isinstance(qspec, str): + q = self.resolve(qspec) + if not callable(q): + raise TypeError('Invalid queue specifier %r' % qspec) + q = q() + elif isinstance(qspec, dict): + if '()' not in qspec: + raise TypeError('Invalid queue specifier %r' % qspec) + q = self.configure_custom(dict(qspec)) + else: + raise TypeError('Invalid queue specifier %r' % qspec) + config['queue'] = q + if 'listener' in config: + lspec = config['listener'] + if isinstance(lspec, type): + if not issubclass(lspec, logging.handlers.QueueListener): + raise TypeError('Invalid listener specifier %r' % lspec) + else: + if isinstance(lspec, str): + listener = self.resolve(lspec) + if isinstance(listener, type) and\ + not issubclass(listener, logging.handlers.QueueListener): + raise TypeError('Invalid listener specifier %r' % lspec) + elif isinstance(lspec, dict): + if '()' not in lspec: + raise TypeError('Invalid listener specifier %r' % lspec) + listener = self.configure_custom(dict(lspec)) + else: + raise TypeError('Invalid listener specifier %r' % lspec) + if not callable(listener): + raise TypeError('Invalid listener specifier %r' % lspec) + config['listener'] = listener + hlist = [] + try: + for hn in config['handlers']: + h = self.config['handlers'][hn] + if not isinstance(h, logging.Handler): + config.update(config_copy) # restore for deferred cfg + raise TypeError('Required handler %r ' + 'is not configured yet' % hn) + hlist.append(h) + except Exception as e: + raise ValueError('Unable to set required handler %r' % hn) from e + config['handlers'] = hlist elif issubclass(klass, logging.handlers.SMTPHandler) and\ 'mailhost' in config: config['mailhost'] = self.as_tuple(config['mailhost']) elif issubclass(klass, logging.handlers.SysLogHandler) and\ 'address' in config: config['address'] = self.as_tuple(config['address']) - factory = klass + if issubclass(klass, logging.handlers.QueueHandler): + factory = functools.partial(self._configure_queue_handler, klass) + else: + factory = klass props = config.pop('.', None) kwargs = {k: config[k] for k in config if valid_ident(k)} try: diff --git a/Lib/logging/handlers.py b/Lib/logging/handlers.py index f5a9760f..671cc959 100644 --- a/Lib/logging/handlers.py +++ b/Lib/logging/handlers.py @@ -1399,7 +1399,7 @@ class MemoryHandler(BufferingHandler): records to the target, if there is one. Override if you want different behaviour. - The record buffer is also cleared by this operation. + The record buffer is only cleared if a target has been set. """ self.acquire() try: @@ -1444,6 +1444,7 @@ class QueueHandler(logging.Handler): """ logging.Handler.__init__(self) self.queue = queue + self.listener = None # will be set to listener if configured via dictConfig() def enqueue(self, record): """ diff --git a/Lib/mailbox.py b/Lib/mailbox.py index 70da07ed..59834a2b 100644 --- a/Lib/mailbox.py +++ b/Lib/mailbox.py @@ -1956,10 +1956,7 @@ class _ProxyFile: def __iter__(self): """Iterate over lines.""" - while True: - line = self.readline() - if not line: - return + while line := self.readline(): yield line def tell(self): diff --git a/Lib/mailcap.py b/Lib/mailcap.py index 7278ea70..2f4656e8 100644 --- a/Lib/mailcap.py +++ b/Lib/mailcap.py @@ -90,9 +90,7 @@ def _readmailcapfile(fp, lineno): the viewing command is stored with the key "view". """ caps = {} - while 1: - line = fp.readline() - if not line: break + while line := fp.readline(): # Ignore comments and blank lines if line[0] == '#' or line.strip() == '': continue diff --git a/Lib/mimetypes.py b/Lib/mimetypes.py index f6c43b3b..37228de4 100644 --- a/Lib/mimetypes.py +++ b/Lib/mimetypes.py @@ -217,10 +217,7 @@ class MimeTypes: list of standard types, else to the list of non-standard types. """ - while 1: - line = fp.readline() - if not line: - break + while line := fp.readline(): words = line.split() for i in range(len(words)): if words[i][0] == '#': @@ -427,8 +424,8 @@ def _default_mime_types(): # Make sure the entry with the preferred file extension for a particular mime type # appears before any others of the same mimetype. types_map = _types_map_default = { - '.js' : 'application/javascript', - '.mjs' : 'application/javascript', + '.js' : 'text/javascript', + '.mjs' : 'text/javascript', '.json' : 'application/json', '.webmanifest': 'application/manifest+json', '.doc' : 'application/msword', diff --git a/Lib/multiprocessing/connection.py b/Lib/multiprocessing/connection.py index b08144f7..04eaea81 100644 --- a/Lib/multiprocessing/connection.py +++ b/Lib/multiprocessing/connection.py @@ -722,39 +722,227 @@ if sys.platform == 'win32': # Authentication stuff # -MESSAGE_LENGTH = 20 +MESSAGE_LENGTH = 40 # MUST be > 20 -CHALLENGE = b'#CHALLENGE#' -WELCOME = b'#WELCOME#' -FAILURE = b'#FAILURE#' +_CHALLENGE = b'#CHALLENGE#' +_WELCOME = b'#WELCOME#' +_FAILURE = b'#FAILURE#' -def deliver_challenge(connection, authkey): +# multiprocessing.connection Authentication Handshake Protocol Description +# (as documented for reference after reading the existing code) +# ============================================================================= +# +# On Windows: native pipes with "overlapped IO" are used to send the bytes, +# instead of the length prefix SIZE scheme described below. (ie: the OS deals +# with message sizes for us) +# +# Protocol error behaviors: +# +# On POSIX, any failure to receive the length prefix into SIZE, for SIZE greater +# than the requested maxsize to receive, or receiving fewer than SIZE bytes +# results in the connection being closed and auth to fail. +# +# On Windows, receiving too few bytes is never a low level _recv_bytes read +# error, receiving too many will trigger an error only if receive maxsize +# value was larger than 128 OR the if the data arrived in smaller pieces. +# +# Serving side Client side +# ------------------------------ --------------------------------------- +# 0. Open a connection on the pipe. +# 1. Accept connection. +# 2. Random 20+ bytes -> MESSAGE +# Modern servers always send +# more than 20 bytes and include +# a {digest} prefix on it with +# their preferred HMAC digest. +# Legacy ones send ==20 bytes. +# 3. send 4 byte length (net order) +# prefix followed by: +# b'#CHALLENGE#' + MESSAGE +# 4. Receive 4 bytes, parse as network byte +# order integer. If it is -1, receive an +# additional 8 bytes, parse that as network +# byte order. The result is the length of +# the data that follows -> SIZE. +# 5. Receive min(SIZE, 256) bytes -> M1 +# 6. Assert that M1 starts with: +# b'#CHALLENGE#' +# 7. Strip that prefix from M1 into -> M2 +# 7.1. Parse M2: if it is exactly 20 bytes in +# length this indicates a legacy server +# supporting only HMAC-MD5. Otherwise the +# 7.2. preferred digest is looked up from an +# expected "{digest}" prefix on M2. No prefix +# or unsupported digest? <- AuthenticationError +# 7.3. Put divined algorithm name in -> D_NAME +# 8. Compute HMAC-D_NAME of AUTHKEY, M2 -> C_DIGEST +# 9. Send 4 byte length prefix (net order) +# followed by C_DIGEST bytes. +# 10. Receive 4 or 4+8 byte length +# prefix (#4 dance) -> SIZE. +# 11. Receive min(SIZE, 256) -> C_D. +# 11.1. Parse C_D: legacy servers +# accept it as is, "md5" -> D_NAME +# 11.2. modern servers check the length +# of C_D, IF it is 16 bytes? +# 11.2.1. "md5" -> D_NAME +# and skip to step 12. +# 11.3. longer? expect and parse a "{digest}" +# prefix into -> D_NAME. +# Strip the prefix and store remaining +# bytes in -> C_D. +# 11.4. Don't like D_NAME? <- AuthenticationError +# 12. Compute HMAC-D_NAME of AUTHKEY, +# MESSAGE into -> M_DIGEST. +# 13. Compare M_DIGEST == C_D: +# 14a: Match? Send length prefix & +# b'#WELCOME#' +# <- RETURN +# 14b: Mismatch? Send len prefix & +# b'#FAILURE#' +# <- CLOSE & AuthenticationError +# 15. Receive 4 or 4+8 byte length prefix (net +# order) again as in #4 into -> SIZE. +# 16. Receive min(SIZE, 256) bytes -> M3. +# 17. Compare M3 == b'#WELCOME#': +# 17a. Match? <- RETURN +# 17b. Mismatch? <- CLOSE & AuthenticationError +# +# If this RETURNed, the connection remains open: it has been authenticated. +# +# Length prefixes are used consistently. Even on the legacy protocol, this +# was good fortune and allowed us to evolve the protocol by using the length +# of the opening challenge or length of the returned digest as a signal as +# to which protocol the other end supports. + +_ALLOWED_DIGESTS = frozenset( + {b'md5', b'sha256', b'sha384', b'sha3_256', b'sha3_384'}) +_MAX_DIGEST_LEN = max(len(_) for _ in _ALLOWED_DIGESTS) + +# Old hmac-md5 only server versions from Python <=3.11 sent a message of this +# length. It happens to not match the length of any supported digest so we can +# use a message of this length to indicate that we should work in backwards +# compatible md5-only mode without a {digest_name} prefix on our response. +_MD5ONLY_MESSAGE_LENGTH = 20 +_MD5_DIGEST_LEN = 16 +_LEGACY_LENGTHS = (_MD5ONLY_MESSAGE_LENGTH, _MD5_DIGEST_LEN) + + +def _get_digest_name_and_payload(message: bytes) -> (str, bytes): + """Returns a digest name and the payload for a response hash. + + If a legacy protocol is detected based on the message length + or contents the digest name returned will be empty to indicate + legacy mode where MD5 and no digest prefix should be sent. + """ + # modern message format: b"{digest}payload" longer than 20 bytes + # legacy message format: 16 or 20 byte b"payload" + if len(message) in _LEGACY_LENGTHS: + # Either this was a legacy server challenge, or we're processing + # a reply from a legacy client that sent an unprefixed 16-byte + # HMAC-MD5 response. All messages using the modern protocol will + # be longer than either of these lengths. + return '', message + if (message.startswith(b'{') and + (curly := message.find(b'}', 1, _MAX_DIGEST_LEN+2)) > 0): + digest = message[1:curly] + if digest in _ALLOWED_DIGESTS: + payload = message[curly+1:] + return digest.decode('ascii'), payload + raise AuthenticationError( + 'unsupported message length, missing digest prefix, ' + f'or unsupported digest: {message=}') + + +def _create_response(authkey, message): + """Create a MAC based on authkey and message + + The MAC algorithm defaults to HMAC-MD5, unless MD5 is not available or + the message has a '{digest_name}' prefix. For legacy HMAC-MD5, the response + is the raw MAC, otherwise the response is prefixed with '{digest_name}', + e.g. b'{sha256}abcdefg...' + + Note: The MAC protects the entire message including the digest_name prefix. + """ import hmac + digest_name = _get_digest_name_and_payload(message)[0] + # The MAC protects the entire message: digest header and payload. + if not digest_name: + # Legacy server without a {digest} prefix on message. + # Generate a legacy non-prefixed HMAC-MD5 reply. + try: + return hmac.new(authkey, message, 'md5').digest() + except ValueError: + # HMAC-MD5 is not available (FIPS mode?), fall back to + # HMAC-SHA2-256 modern protocol. The legacy server probably + # doesn't support it and will reject us anyways. :shrug: + digest_name = 'sha256' + # Modern protocol, indicate the digest used in the reply. + response = hmac.new(authkey, message, digest_name).digest() + return b'{%s}%s' % (digest_name.encode('ascii'), response) + + +def _verify_challenge(authkey, message, response): + """Verify MAC challenge + + If our message did not include a digest_name prefix, the client is allowed + to select a stronger digest_name from _ALLOWED_DIGESTS. + + In case our message is prefixed, a client cannot downgrade to a weaker + algorithm, because the MAC is calculated over the entire message + including the '{digest_name}' prefix. + """ + import hmac + response_digest, response_mac = _get_digest_name_and_payload(response) + response_digest = response_digest or 'md5' + try: + expected = hmac.new(authkey, message, response_digest).digest() + except ValueError: + raise AuthenticationError(f'{response_digest=} unsupported') + if len(expected) != len(response_mac): + raise AuthenticationError( + f'expected {response_digest!r} of length {len(expected)} ' + f'got {len(response_mac)}') + if not hmac.compare_digest(expected, response_mac): + raise AuthenticationError('digest received was wrong') + + +def deliver_challenge(connection, authkey: bytes, digest_name='sha256'): if not isinstance(authkey, bytes): raise ValueError( "Authkey must be bytes, not {0!s}".format(type(authkey))) + assert MESSAGE_LENGTH > _MD5ONLY_MESSAGE_LENGTH, "protocol constraint" message = os.urandom(MESSAGE_LENGTH) - connection.send_bytes(CHALLENGE + message) - digest = hmac.new(authkey, message, 'md5').digest() + message = b'{%s}%s' % (digest_name.encode('ascii'), message) + # Even when sending a challenge to a legacy client that does not support + # digest prefixes, they'll take the entire thing as a challenge and + # respond to it with a raw HMAC-MD5. + connection.send_bytes(_CHALLENGE + message) response = connection.recv_bytes(256) # reject large message - if response == digest: - connection.send_bytes(WELCOME) + try: + _verify_challenge(authkey, message, response) + except AuthenticationError: + connection.send_bytes(_FAILURE) + raise else: - connection.send_bytes(FAILURE) - raise AuthenticationError('digest received was wrong') + connection.send_bytes(_WELCOME) -def answer_challenge(connection, authkey): - import hmac + +def answer_challenge(connection, authkey: bytes): if not isinstance(authkey, bytes): raise ValueError( "Authkey must be bytes, not {0!s}".format(type(authkey))) message = connection.recv_bytes(256) # reject large message - assert message[:len(CHALLENGE)] == CHALLENGE, 'message = %r' % message - message = message[len(CHALLENGE):] - digest = hmac.new(authkey, message, 'md5').digest() + if not message.startswith(_CHALLENGE): + raise AuthenticationError( + f'Protocol error, expected challenge: {message=}') + message = message[len(_CHALLENGE):] + if len(message) < _MD5ONLY_MESSAGE_LENGTH: + raise AuthenticationError('challenge too short: {len(message)} bytes') + digest = _create_response(authkey, message) connection.send_bytes(digest) response = connection.recv_bytes(256) # reject large message - if response != WELCOME: + if response != _WELCOME: raise AuthenticationError('digest sent was rejected') # diff --git a/Lib/multiprocessing/context.py b/Lib/multiprocessing/context.py index b1960ea2..de8a2648 100644 --- a/Lib/multiprocessing/context.py +++ b/Lib/multiprocessing/context.py @@ -258,6 +258,7 @@ class DefaultContext(BaseContext): return self._actual_context._name def get_all_start_methods(self): + """Returns a list of the supported start methods, default first.""" if sys.platform == 'win32': return ['spawn'] else: diff --git a/Lib/multiprocessing/forkserver.py b/Lib/multiprocessing/forkserver.py index 22a911a7..4642707d 100644 --- a/Lib/multiprocessing/forkserver.py +++ b/Lib/multiprocessing/forkserver.py @@ -61,7 +61,7 @@ class ForkServer(object): def set_forkserver_preload(self, modules_names): '''Set list of module names to try to load in forkserver process.''' - if not all(type(mod) is str for mod in self._preload_modules): + if not all(type(mod) is str for mod in modules_names): raise TypeError('module_names must be a list of strings') self._preload_modules = modules_names diff --git a/Lib/multiprocessing/managers.py b/Lib/multiprocessing/managers.py index 3f6479b7..b6534939 100644 --- a/Lib/multiprocessing/managers.py +++ b/Lib/multiprocessing/managers.py @@ -433,7 +433,6 @@ class Server(object): self.id_to_refcount[ident] = 1 self.id_to_obj[ident] = \ self.id_to_local_proxy_obj[ident] - obj, exposed, gettypeid = self.id_to_obj[ident] util.debug('Server re-enabled tracking & INCREF %r', ident) else: raise ke diff --git a/Lib/multiprocessing/pool.py b/Lib/multiprocessing/pool.py index 961d7e59..4f5d88cb 100644 --- a/Lib/multiprocessing/pool.py +++ b/Lib/multiprocessing/pool.py @@ -696,7 +696,7 @@ class Pool(object): if (not result_handler.is_alive()) and (len(cache) != 0): raise AssertionError( - "Cannot have cache with result_hander not alive") + "Cannot have cache with result_handler not alive") result_handler._state = TERMINATE change_notifier.put(None) diff --git a/Lib/multiprocessing/process.py b/Lib/multiprocessing/process.py index c03c859b..271ba3fd 100644 --- a/Lib/multiprocessing/process.py +++ b/Lib/multiprocessing/process.py @@ -61,7 +61,7 @@ def parent_process(): def _cleanup(): # check for processes which have finished for p in list(_children): - if p._popen.poll() is not None: + if (child_popen := p._popen) and child_popen.poll() is not None: _children.discard(p) # diff --git a/Lib/multiprocessing/queues.py b/Lib/multiprocessing/queues.py index f37f114a..daf9ee94 100644 --- a/Lib/multiprocessing/queues.py +++ b/Lib/multiprocessing/queues.py @@ -280,6 +280,8 @@ class Queue(object): import traceback traceback.print_exc() + __class_getitem__ = classmethod(types.GenericAlias) + _sentinel = object() diff --git a/Lib/multiprocessing/spawn.py b/Lib/multiprocessing/spawn.py index 09f8a229..daac1ecc 100644 --- a/Lib/multiprocessing/spawn.py +++ b/Lib/multiprocessing/spawn.py @@ -31,11 +31,13 @@ if sys.platform != 'win32': WINSERVICE = False else: WINEXE = getattr(sys, 'frozen', False) - WINSERVICE = sys.executable.lower().endswith("pythonservice.exe") + WINSERVICE = sys.executable and sys.executable.lower().endswith("pythonservice.exe") def set_executable(exe): global _python_exe - if sys.platform == 'win32': + if exe is None: + _python_exe = exe + elif sys.platform == 'win32': _python_exe = os.fsdecode(exe) else: _python_exe = os.fsencode(exe) @@ -148,7 +150,11 @@ def _check_not_importing_main(): ... The "freeze_support()" line can be omitted if the program - is not going to be frozen to produce an executable.''') + is not going to be frozen to produce an executable. + + To fix this issue, refer to the "Safe importing of main module" + section in https://docs.python.org/3/library/multiprocessing.html + ''') def get_preparation_data(name): diff --git a/Lib/multiprocessing/synchronize.py b/Lib/multiprocessing/synchronize.py index 42624b54..3ccbfe31 100644 --- a/Lib/multiprocessing/synchronize.py +++ b/Lib/multiprocessing/synchronize.py @@ -50,8 +50,8 @@ class SemLock(object): def __init__(self, kind, value, maxvalue, *, ctx): if ctx is None: ctx = context._default_context.get_context() - name = ctx.get_start_method() - unlink_now = sys.platform == 'win32' or name == 'fork' + self._is_fork_ctx = ctx.get_start_method() == 'fork' + unlink_now = sys.platform == 'win32' or self._is_fork_ctx for i in range(100): try: sl = self._semlock = _multiprocessing.SemLock( @@ -103,6 +103,11 @@ class SemLock(object): if sys.platform == 'win32': h = context.get_spawning_popen().duplicate_for_child(sl.handle) else: + if self._is_fork_ctx: + raise RuntimeError('A SemLock created in a fork context is being ' + 'shared with a process in a spawn context. This is ' + 'not supported. Please use the same context to create ' + 'multiprocessing objects and Process.') h = sl.handle return (h, sl.kind, sl.maxvalue, sl.name) @@ -110,6 +115,8 @@ class SemLock(object): self._semlock = _multiprocessing.SemLock._rebuild(*state) util.debug('recreated blocker with handle %r' % state[0]) self._make_methods() + # Ensure that deserialized SemLock can be serialized again (gh-108520). + self._is_fork_ctx = False @staticmethod def _make_name(): diff --git a/Lib/netrc.py b/Lib/netrc.py index c1358aac..b285fd8e 100644 --- a/Lib/netrc.py +++ b/Lib/netrc.py @@ -2,7 +2,7 @@ # Module and documentation by Eric S. Raymond, 21 Dec 1998 -import os, shlex, stat +import os, stat __all__ = ["netrc", "NetrcParseError"] diff --git a/Lib/ntpath.py b/Lib/ntpath.py index 1cfb15b7..df3402d4 100644 --- a/Lib/ntpath.py +++ b/Lib/ntpath.py @@ -24,13 +24,13 @@ import genericpath from genericpath import * -__all__ = ["normcase","isabs","join","splitdrive","split","splitext", +__all__ = ["normcase","isabs","join","splitdrive","splitroot","split","splitext", "basename","dirname","commonprefix","getsize","getmtime", "getatime","getctime", "islink","exists","lexists","isdir","isfile", "ismount", "expanduser","expandvars","normpath","abspath", "curdir","pardir","sep","pathsep","defpath","altsep", "extsep","devnull","realpath","supports_unicode_filenames","relpath", - "samefile", "sameopenfile", "samestat", "commonpath"] + "samefile", "sameopenfile", "samestat", "commonpath", "isjunction"] def _get_bothseps(path): if isinstance(path, bytes): @@ -117,19 +117,21 @@ def join(path, *paths): try: if not paths: path[:0] + sep #23780: Ensure compatible data type even if p is null. - result_drive, result_path = splitdrive(path) + result_drive, result_root, result_path = splitroot(path) for p in map(os.fspath, paths): - p_drive, p_path = splitdrive(p) - if p_path and p_path[0] in seps: + p_drive, p_root, p_path = splitroot(p) + if p_root: # Second path is absolute if p_drive or not result_drive: result_drive = p_drive + result_root = p_root result_path = p_path continue elif p_drive and p_drive != result_drive: if p_drive.lower() != result_drive.lower(): # Different drives => ignore the first path entirely result_drive = p_drive + result_root = p_root result_path = p_path continue # Same drive in different case @@ -139,10 +141,10 @@ def join(path, *paths): result_path = result_path + sep result_path = result_path + p_path ## add separator between UNC and non-absolute path - if (result_path and result_path[0] not in seps and - result_drive and result_drive[-1:] != colon): + if (result_path and not result_root and + result_drive and result_drive[-1:] not in colon + seps): return result_drive + sep + result_path - return result_drive + result_path + return result_drive + result_root + result_path except (TypeError, AttributeError, BytesWarning): genericpath._check_arg_types('join', path, *paths) raise @@ -169,35 +171,61 @@ def splitdrive(p): Paths cannot contain both a drive letter and a UNC path. + """ + drive, root, tail = splitroot(p) + return drive, root + tail + + +def splitroot(p): + """Split a pathname into drive, root and tail. The drive is defined + exactly as in splitdrive(). On Windows, the root may be a single path + separator or an empty string. The tail contains anything after the root. + For example: + + splitroot('//server/share/') == ('//server/share', '/', '') + splitroot('C:/Users/Barney') == ('C:', '/', 'Users/Barney') + splitroot('C:///spam///ham') == ('C:', '/', '//spam///ham') + splitroot('Windows/notepad') == ('', '', 'Windows/notepad') """ p = os.fspath(p) - if len(p) >= 2: - if isinstance(p, bytes): - sep = b'\\' - altsep = b'/' - colon = b':' - unc_prefix = b'\\\\?\\UNC\\' - else: - sep = '\\' - altsep = '/' - colon = ':' - unc_prefix = '\\\\?\\UNC\\' - normp = p.replace(altsep, sep) - if normp[0:2] == sep * 2: + if isinstance(p, bytes): + sep = b'\\' + altsep = b'/' + colon = b':' + unc_prefix = b'\\\\?\\UNC\\' + empty = b'' + else: + sep = '\\' + altsep = '/' + colon = ':' + unc_prefix = '\\\\?\\UNC\\' + empty = '' + normp = p.replace(altsep, sep) + if normp[:1] == sep: + if normp[1:2] == sep: # UNC drives, e.g. \\server\share or \\?\UNC\server\share # Device drives, e.g. \\.\device or \\?\device start = 8 if normp[:8].upper() == unc_prefix else 2 index = normp.find(sep, start) if index == -1: - return p, p[:0] + return p, empty, empty index2 = normp.find(sep, index + 1) if index2 == -1: - return p, p[:0] - return p[:index2], p[index2:] - if normp[1:2] == colon: - # Drive-letter drives, e.g. X: - return p[:2], p[2:] - return p[:0], p + return p, empty, empty + return p[:index2], p[index2:index2 + 1], p[index2 + 1:] + else: + # Relative path with root, e.g. \Windows + return empty, p[:1], p[1:] + elif normp[1:2] == colon: + if normp[2:3] == sep: + # Absolute drive-letter path, e.g. X:\Windows + return p[:2], p[2:3], p[3:] + else: + # Relative path with drive, e.g. X:Windows + return p[:2], empty, p[2:] + else: + # Relative path, e.g. Windows + return empty, empty, p # Split a path in head (everything up to the last '/') and tail (the @@ -212,15 +240,13 @@ def split(p): Either part may be empty.""" p = os.fspath(p) seps = _get_bothseps(p) - d, p = splitdrive(p) + d, r, p = splitroot(p) # set i to index beyond p's last slash i = len(p) while i and p[i-1] not in seps: i -= 1 head, tail = p[:i], p[i:] # now tail has no slashes - # remove trailing slashes from head, unless it's all slashes - head = head.rstrip(seps) or head - return d + head, tail + return d + r + head.rstrip(seps), tail # Split a path in root and extension. @@ -250,18 +276,23 @@ def dirname(p): """Returns the directory component of a pathname""" return split(p)[0] -# Is a path a symbolic link? -# This will always return false on systems where os.lstat doesn't exist. -def islink(path): - """Test whether a path is a symbolic link. - This will always return false for Windows prior to 6.0. - """ - try: - st = os.lstat(path) - except (OSError, ValueError, AttributeError): +# Is a path a junction? + +if hasattr(os.stat_result, 'st_reparse_tag'): + def isjunction(path): + """Test whether a path is a junction""" + try: + st = os.lstat(path) + except (OSError, ValueError, AttributeError): + return False + return bool(st.st_reparse_tag == stat.IO_REPARSE_TAG_MOUNT_POINT) +else: + def isjunction(path): + """Test whether a path is a junction""" + os.fspath(path) return False - return stat.S_ISLNK(st.st_mode) + # Being true for dangling symbolic links is also useful. @@ -293,10 +324,10 @@ def ismount(path): path = os.fspath(path) seps = _get_bothseps(path) path = abspath(path) - root, rest = splitdrive(path) - if root and root[0] in seps: - return (not rest) or (rest in seps) - if rest and rest in seps: + drive, root, rest = splitroot(path) + if drive and drive[0] in seps: + return not rest + if root and not rest: return True if _getvolumepathname: @@ -507,13 +538,8 @@ except ImportError: curdir = '.' pardir = '..' path = path.replace(altsep, sep) - prefix, path = splitdrive(path) - - # collapse initial backslashes - if path.startswith(sep): - prefix += sep - path = path.lstrip(sep) - + drive, root, path = splitroot(path) + prefix = drive + root comps = path.split(sep) i = 0 while i < len(comps): @@ -523,7 +549,7 @@ except ImportError: if i > 0 and comps[i-1] != pardir: del comps[i-1:i+1] i -= 1 - elif i == 0 and prefix.endswith(sep): + elif i == 0 and root: del comps[i] else: i += 1 @@ -644,7 +670,7 @@ else: # Non-strict algorithm is to find as much of the target directory # as we can and join the rest. - tail = '' + tail = path[:0] while path: try: path = _getfinalpathname(path) @@ -695,6 +721,14 @@ else: try: path = _getfinalpathname(path) initial_winerror = 0 + except ValueError as ex: + # gh-106242: Raised for embedded null characters + # In strict mode, we convert into an OSError. + # Non-strict mode returns the path as-is, since we've already + # made it absolute. + if strict: + raise OSError(str(ex)) from None + path = normpath(path) except OSError as ex: if strict: raise @@ -714,6 +748,10 @@ else: try: if _getfinalpathname(spath) == path: path = spath + except ValueError as ex: + # Unexpected, as an invalid path should not have gained a prefix + # at any point, but we ignore this error just in case. + pass except OSError as ex: # If the path does not exist and originally did not exist, then # strip the prefix anyway. @@ -722,9 +760,8 @@ else: return path -# Win9x family and earlier have no Unicode filename support. -supports_unicode_filenames = (hasattr(sys, "getwindowsversion") and - sys.getwindowsversion()[3] >= 2) +# All supported version have Unicode filename support. +supports_unicode_filenames = True def relpath(path, start=None): """Return a relative version of a path""" @@ -748,8 +785,8 @@ def relpath(path, start=None): try: start_abs = abspath(normpath(start)) path_abs = abspath(normpath(path)) - start_drive, start_rest = splitdrive(start_abs) - path_drive, path_rest = splitdrive(path_abs) + start_drive, _, start_rest = splitroot(start_abs) + path_drive, _, path_rest = splitroot(path_abs) if normcase(start_drive) != normcase(path_drive): raise ValueError("path is on mount %r, start on mount %r" % ( path_drive, start_drive)) @@ -799,21 +836,19 @@ def commonpath(paths): curdir = '.' try: - drivesplits = [splitdrive(p.replace(altsep, sep).lower()) for p in paths] - split_paths = [p.split(sep) for d, p in drivesplits] + drivesplits = [splitroot(p.replace(altsep, sep).lower()) for p in paths] + split_paths = [p.split(sep) for d, r, p in drivesplits] - try: - isabs, = set(p[:1] == sep for d, p in drivesplits) - except ValueError: - raise ValueError("Can't mix absolute and relative paths") from None + if len({r for d, r, p in drivesplits}) != 1: + raise ValueError("Can't mix absolute and relative paths") # Check that all drive letters or UNC paths match. The check is made only # now otherwise type errors for mixing strings and bytes would not be # caught. - if len(set(d for d, p in drivesplits)) != 1: + if len({d for d, r, p in drivesplits}) != 1: raise ValueError("Paths don't have the same drive") - drive, path = splitdrive(paths[0].replace(altsep, sep)) + drive, root, path = splitroot(paths[0].replace(altsep, sep)) common = path.split(sep) common = [c for c in common if c and c != curdir] @@ -827,19 +862,36 @@ def commonpath(paths): else: common = common[:len(s1)] - prefix = drive + sep if isabs else drive - return prefix + sep.join(common) + return drive + root + sep.join(common) except (TypeError, AttributeError): genericpath._check_arg_types('commonpath', *paths) raise try: - # The genericpath.isdir implementation uses os.stat and checks the mode - # attribute to tell whether or not the path is a directory. - # This is overkill on Windows - just pass the path to GetFileAttributes - # and check the attribute from there. - from nt import _isdir as isdir + # The isdir(), isfile(), islink() and exists() implementations in + # genericpath use os.stat(). This is overkill on Windows. Use simpler + # builtin functions if they are available. + from nt import _path_isdir as isdir + from nt import _path_isfile as isfile + from nt import _path_islink as islink + from nt import _path_exists as exists except ImportError: - # Use genericpath.isdir as imported above. + # Use genericpath.* as imported above pass + + +try: + from nt import _path_isdevdrive +except ImportError: + def isdevdrive(path): + """Determines whether the specified path is on a Windows Dev Drive.""" + # Never a Dev Drive + return False +else: + def isdevdrive(path): + """Determines whether the specified path is on a Windows Dev Drive.""" + try: + return _path_isdevdrive(abspath(path)) + except OSError: + return False diff --git a/Lib/numbers.py b/Lib/numbers.py index 0985dd85..a2913e32 100644 --- a/Lib/numbers.py +++ b/Lib/numbers.py @@ -5,6 +5,31 @@ TODO: Fill out more detailed documentation on the operators.""" +############ Maintenance notes ######################################### +# +# ABCs are different from other standard library modules in that they +# specify compliance tests. In general, once an ABC has been published, +# new methods (either abstract or concrete) cannot be added. +# +# Though classes that inherit from an ABC would automatically receive a +# new mixin method, registered classes would become non-compliant and +# violate the contract promised by ``isinstance(someobj, SomeABC)``. +# +# Though irritating, the correct procedure for adding new abstract or +# mixin methods is to create a new ABC as a subclass of the previous +# ABC. +# +# Because they are so hard to change, new ABCs should have their APIs +# carefully thought through prior to publication. +# +# Since ABCMeta only checks for the presence of methods, it is possible +# to alter the signature of a method by adding optional arguments +# or changing parameter names. This is still a bit dubious but at +# least it won't cause isinstance() to return an incorrect result. +# +# +####################################################################### + from abc import ABCMeta, abstractmethod __all__ = ["Number", "Complex", "Real", "Rational", "Integral"] @@ -118,7 +143,7 @@ class Complex(Number): @abstractmethod def __pow__(self, exponent): - """self**exponent; should promote to float or complex when necessary.""" + """self ** exponent; should promote to float or complex when necessary.""" raise NotImplementedError @abstractmethod @@ -167,7 +192,7 @@ class Real(Complex): """trunc(self): Truncates self to an Integral. Returns an Integral i such that: - * i>0 iff self>0; + * i > 0 iff self > 0; * abs(i) <= abs(self); * for any Integral j satisfying the first two conditions, abs(i) >= abs(j) [i.e. i has "maximal" abs among those]. @@ -203,7 +228,7 @@ class Real(Complex): return (self // other, self % other) def __rdivmod__(self, other): - """divmod(other, self): The pair (self // other, self % other). + """divmod(other, self): The pair (other // self, other % self). Sometimes this can be computed faster than the pair of operations. diff --git a/Lib/opcode.py b/Lib/opcode.py index bc3c02af..6bb2f1c1 100644 --- a/Lib/opcode.py +++ b/Lib/opcode.py @@ -4,9 +4,9 @@ opcode module - potentially shared between dis and other modules which operate on bytecodes (e.g. peephole optimizers). """ -__all__ = ["cmp_op", "hasconst", "hasname", "hasjrel", "hasjabs", - "haslocal", "hascompare", "hasfree", "opname", "opmap", - "HAVE_ARGUMENT", "EXTENDED_ARG", "hasnargs"] +__all__ = ["cmp_op", "hasarg", "hasconst", "hasname", "hasjrel", "hasjabs", + "haslocal", "hascompare", "hasfree", "hasexc", "opname", "opmap", + "HAVE_ARGUMENT", "EXTENDED_ARG"] # It's a chicken-and-egg I'm afraid: # We're imported before _opcode's made. @@ -23,6 +23,7 @@ except ImportError: cmp_op = ('<', '<=', '==', '!=', '>', '>=') +hasarg = [] hasconst = [] hasname = [] hasjrel = [] @@ -30,13 +31,24 @@ hasjabs = [] haslocal = [] hascompare = [] hasfree = [] -hasnargs = [] # unused +hasexc = [] + + +ENABLE_SPECIALIZATION = True + +def is_pseudo(op): + return op >= MIN_PSEUDO_OPCODE and op <= MAX_PSEUDO_OPCODE + +oplists = [hasarg, hasconst, hasname, hasjrel, hasjabs, + haslocal, hascompare, hasfree, hasexc] opmap = {} -opname = ['<%r>' % (op,) for op in range(256)] + +## pseudo opcodes (used in the compiler) mapped to the values +## they can become in the actual code. +_pseudo_ops = {} def def_op(name, op): - opname[op] = name opmap[name] = op def name_op(name, op): @@ -51,21 +63,42 @@ def jabs_op(name, op): def_op(name, op) hasjabs.append(op) +def pseudo_op(name, op, real_ops): + def_op(name, op) + _pseudo_ops[name] = real_ops + # add the pseudo opcode to the lists its targets are in + for oplist in oplists: + res = [opmap[rop] in oplist for rop in real_ops] + if any(res): + assert all(res) + oplist.append(op) + + # Instruction opcodes for compiled code # Blank lines correspond to available opcodes def_op('CACHE', 0) def_op('POP_TOP', 1) def_op('PUSH_NULL', 2) +def_op('INTERPRETER_EXIT', 3) + +def_op('END_FOR', 4) +def_op('END_SEND', 5) def_op('NOP', 9) -def_op('UNARY_POSITIVE', 10) + def_op('UNARY_NEGATIVE', 11) def_op('UNARY_NOT', 12) def_op('UNARY_INVERT', 15) +# We reserve 17 as it is the initial value for the specializing counter +# This helps us catch cases where we attempt to execute a cache. +def_op('RESERVED', 17) + def_op('BINARY_SUBSCR', 25) +def_op('BINARY_SLICE', 26) +def_op('STORE_SLICE', 27) def_op('GET_LEN', 30) def_op('MATCH_MAPPING', 31) @@ -82,28 +115,27 @@ def_op('GET_ANEXT', 51) def_op('BEFORE_ASYNC_WITH', 52) def_op('BEFORE_WITH', 53) def_op('END_ASYNC_FOR', 54) +def_op('CLEANUP_THROW', 55) def_op('STORE_SUBSCR', 60) def_op('DELETE_SUBSCR', 61) def_op('GET_ITER', 68) def_op('GET_YIELD_FROM_ITER', 69) -def_op('PRINT_EXPR', 70) + def_op('LOAD_BUILD_CLASS', 71) def_op('LOAD_ASSERTION_ERROR', 74) def_op('RETURN_GENERATOR', 75) -def_op('LIST_TO_TUPLE', 82) def_op('RETURN_VALUE', 83) -def_op('IMPORT_STAR', 84) + def_op('SETUP_ANNOTATIONS', 85) -def_op('YIELD_VALUE', 86) -def_op('ASYNC_GEN_WRAP', 87) -def_op('PREP_RERAISE_STAR', 88) +def_op('LOAD_LOCALS', 87) + def_op('POP_EXCEPT', 89) -HAVE_ARGUMENT = 90 # Opcodes from here have an argument: +HAVE_ARGUMENT = 90 # real opcodes from here have an argument: name_op('STORE_NAME', 90) # Index in name list name_op('DELETE_NAME', 91) # "" @@ -128,25 +160,27 @@ hascompare.append(107) name_op('IMPORT_NAME', 108) # Index in name list name_op('IMPORT_FROM', 109) # Index in name list jrel_op('JUMP_FORWARD', 110) # Number of words to skip -jrel_op('JUMP_IF_FALSE_OR_POP', 111) # Number of words to skip -jrel_op('JUMP_IF_TRUE_OR_POP', 112) # "" -jrel_op('POP_JUMP_FORWARD_IF_FALSE', 114) -jrel_op('POP_JUMP_FORWARD_IF_TRUE', 115) +jrel_op('POP_JUMP_IF_FALSE', 114) +jrel_op('POP_JUMP_IF_TRUE', 115) name_op('LOAD_GLOBAL', 116) # Index in name list def_op('IS_OP', 117) def_op('CONTAINS_OP', 118) def_op('RERAISE', 119) def_op('COPY', 120) +def_op('RETURN_CONST', 121) +hasconst.append(121) def_op('BINARY_OP', 122) -jrel_op('SEND', 123) # Number of bytes to skip -def_op('LOAD_FAST', 124) # Local variable number +jrel_op('SEND', 123) # Number of words to skip +def_op('LOAD_FAST', 124) # Local variable number, no null check haslocal.append(124) def_op('STORE_FAST', 125) # Local variable number haslocal.append(125) def_op('DELETE_FAST', 126) # Local variable number haslocal.append(126) -jrel_op('POP_JUMP_FORWARD_IF_NOT_NONE', 128) -jrel_op('POP_JUMP_FORWARD_IF_NONE', 129) +def_op('LOAD_FAST_CHECK', 127) # Local variable number +haslocal.append(127) +jrel_op('POP_JUMP_IF_NOT_NONE', 128) +jrel_op('POP_JUMP_IF_NONE', 129) def_op('RAISE_VARARGS', 130) # Number of raise arguments (1, 2, or 3) def_op('GET_AWAITABLE', 131) def_op('MAKE_FUNCTION', 132) # Flags @@ -163,18 +197,19 @@ hasfree.append(138) def_op('DELETE_DEREF', 139) hasfree.append(139) jrel_op('JUMP_BACKWARD', 140) # Number of words to skip (backwards) - +name_op('LOAD_SUPER_ATTR', 141) def_op('CALL_FUNCTION_EX', 142) # Flags +def_op('LOAD_FAST_AND_CLEAR', 143) # Local variable number +haslocal.append(143) def_op('EXTENDED_ARG', 144) EXTENDED_ARG = 144 def_op('LIST_APPEND', 145) def_op('SET_ADD', 146) def_op('MAP_ADD', 147) -def_op('LOAD_CLASSDEREF', 148) hasfree.append(148) def_op('COPY_FREE_VARS', 149) - +def_op('YIELD_VALUE', 150) def_op('RESUME', 151) # This must be kept in sync with deepfreeze.py def_op('MATCH_CLASS', 152) @@ -182,25 +217,74 @@ def_op('FORMAT_VALUE', 155) def_op('BUILD_CONST_KEY_MAP', 156) def_op('BUILD_STRING', 157) -name_op('LOAD_METHOD', 160) - def_op('LIST_EXTEND', 162) def_op('SET_UPDATE', 163) def_op('DICT_MERGE', 164) def_op('DICT_UPDATE', 165) -def_op('PRECALL', 166) def_op('CALL', 171) def_op('KW_NAMES', 172) hasconst.append(172) +def_op('CALL_INTRINSIC_1', 173) +def_op('CALL_INTRINSIC_2', 174) + +name_op('LOAD_FROM_DICT_OR_GLOBALS', 175) +def_op('LOAD_FROM_DICT_OR_DEREF', 176) +hasfree.append(176) + +# Instrumented instructions +MIN_INSTRUMENTED_OPCODE = 237 + +def_op('INSTRUMENTED_LOAD_SUPER_ATTR', 237) +def_op('INSTRUMENTED_POP_JUMP_IF_NONE', 238) +def_op('INSTRUMENTED_POP_JUMP_IF_NOT_NONE', 239) +def_op('INSTRUMENTED_RESUME', 240) +def_op('INSTRUMENTED_CALL', 241) +def_op('INSTRUMENTED_RETURN_VALUE', 242) +def_op('INSTRUMENTED_YIELD_VALUE', 243) +def_op('INSTRUMENTED_CALL_FUNCTION_EX', 244) +def_op('INSTRUMENTED_JUMP_FORWARD', 245) +def_op('INSTRUMENTED_JUMP_BACKWARD', 246) +def_op('INSTRUMENTED_RETURN_CONST', 247) +def_op('INSTRUMENTED_FOR_ITER', 248) +def_op('INSTRUMENTED_POP_JUMP_IF_FALSE', 249) +def_op('INSTRUMENTED_POP_JUMP_IF_TRUE', 250) +def_op('INSTRUMENTED_END_FOR', 251) +def_op('INSTRUMENTED_END_SEND', 252) +def_op('INSTRUMENTED_INSTRUCTION', 253) +def_op('INSTRUMENTED_LINE', 254) +# 255 is reserved + +hasarg.extend([op for op in opmap.values() if op >= HAVE_ARGUMENT]) + +MIN_PSEUDO_OPCODE = 256 + +pseudo_op('SETUP_FINALLY', 256, ['NOP']) +hasexc.append(256) +pseudo_op('SETUP_CLEANUP', 257, ['NOP']) +hasexc.append(257) +pseudo_op('SETUP_WITH', 258, ['NOP']) +hasexc.append(258) +pseudo_op('POP_BLOCK', 259, ['NOP']) + +pseudo_op('JUMP', 260, ['JUMP_FORWARD', 'JUMP_BACKWARD']) +pseudo_op('JUMP_NO_INTERRUPT', 261, ['JUMP_FORWARD', 'JUMP_BACKWARD_NO_INTERRUPT']) + +pseudo_op('LOAD_METHOD', 262, ['LOAD_ATTR']) +pseudo_op('LOAD_SUPER_METHOD', 263, ['LOAD_SUPER_ATTR']) +pseudo_op('LOAD_ZERO_SUPER_METHOD', 264, ['LOAD_SUPER_ATTR']) +pseudo_op('LOAD_ZERO_SUPER_ATTR', 265, ['LOAD_SUPER_ATTR']) + +pseudo_op('STORE_FAST_MAYBE_NULL', 266, ['STORE_FAST']) + +MAX_PSEUDO_OPCODE = MIN_PSEUDO_OPCODE + len(_pseudo_ops) - 1 + +del def_op, name_op, jrel_op, jabs_op, pseudo_op + +opname = ['<%r>' % (op,) for op in range(MAX_PSEUDO_OPCODE + 1)] +for op, i in opmap.items(): + opname[i] = op -jrel_op('POP_JUMP_BACKWARD_IF_NOT_NONE', 173) -jrel_op('POP_JUMP_BACKWARD_IF_NONE', 174) -jrel_op('POP_JUMP_BACKWARD_IF_FALSE', 175) -jrel_op('POP_JUMP_BACKWARD_IF_TRUE', 176) - - -del def_op, name_op, jrel_op, jabs_op _nb_ops = [ ("NB_ADD", "+"), @@ -231,9 +315,31 @@ _nb_ops = [ ("NB_INPLACE_XOR", "^="), ] +_intrinsic_1_descs = [ + "INTRINSIC_1_INVALID", + "INTRINSIC_PRINT", + "INTRINSIC_IMPORT_STAR", + "INTRINSIC_STOPITERATION_ERROR", + "INTRINSIC_ASYNC_GEN_WRAP", + "INTRINSIC_UNARY_POSITIVE", + "INTRINSIC_LIST_TO_TUPLE", + "INTRINSIC_TYPEVAR", + "INTRINSIC_PARAMSPEC", + "INTRINSIC_TYPEVARTUPLE", + "INTRINSIC_SUBSCRIPT_GENERIC", + "INTRINSIC_TYPEALIAS", +] + +_intrinsic_2_descs = [ + "INTRINSIC_2_INVALID", + "INTRINSIC_PREP_RERAISE_STAR", + "INTRINSIC_TYPEVAR_WITH_BOUND", + "INTRINSIC_TYPEVAR_WITH_CONSTRAINTS", + "INTRINSIC_SET_FUNCTION_TYPE_PARAMS", +] + _specializations = { "BINARY_OP": [ - "BINARY_OP_ADAPTIVE", "BINARY_OP_ADD_FLOAT", "BINARY_OP_ADD_INT", "BINARY_OP_ADD_UNICODE", @@ -244,35 +350,58 @@ _specializations = { "BINARY_OP_SUBTRACT_INT", ], "BINARY_SUBSCR": [ - "BINARY_SUBSCR_ADAPTIVE", "BINARY_SUBSCR_DICT", "BINARY_SUBSCR_GETITEM", "BINARY_SUBSCR_LIST_INT", "BINARY_SUBSCR_TUPLE_INT", ], "CALL": [ - "CALL_ADAPTIVE", "CALL_PY_EXACT_ARGS", "CALL_PY_WITH_DEFAULTS", + "CALL_BOUND_METHOD_EXACT_ARGS", + "CALL_BUILTIN_CLASS", + "CALL_BUILTIN_FAST_WITH_KEYWORDS", + "CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS", + "CALL_NO_KW_BUILTIN_FAST", + "CALL_NO_KW_BUILTIN_O", + "CALL_NO_KW_ISINSTANCE", + "CALL_NO_KW_LEN", + "CALL_NO_KW_LIST_APPEND", + "CALL_NO_KW_METHOD_DESCRIPTOR_FAST", + "CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS", + "CALL_NO_KW_METHOD_DESCRIPTOR_O", + "CALL_NO_KW_STR_1", + "CALL_NO_KW_TUPLE_1", + "CALL_NO_KW_TYPE_1", ], "COMPARE_OP": [ - "COMPARE_OP_ADAPTIVE", - "COMPARE_OP_FLOAT_JUMP", - "COMPARE_OP_INT_JUMP", - "COMPARE_OP_STR_JUMP", + "COMPARE_OP_FLOAT", + "COMPARE_OP_INT", + "COMPARE_OP_STR", ], - "EXTENDED_ARG": [ - "EXTENDED_ARG_QUICK", + "FOR_ITER": [ + "FOR_ITER_LIST", + "FOR_ITER_TUPLE", + "FOR_ITER_RANGE", + "FOR_ITER_GEN", ], - "JUMP_BACKWARD": [ - "JUMP_BACKWARD_QUICK", + "LOAD_SUPER_ATTR": [ + "LOAD_SUPER_ATTR_ATTR", + "LOAD_SUPER_ATTR_METHOD", ], "LOAD_ATTR": [ - "LOAD_ATTR_ADAPTIVE", + # These potentially push [NULL, bound method] onto the stack. + "LOAD_ATTR_CLASS", + "LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN", "LOAD_ATTR_INSTANCE_VALUE", "LOAD_ATTR_MODULE", + "LOAD_ATTR_PROPERTY", "LOAD_ATTR_SLOT", "LOAD_ATTR_WITH_HINT", + # These will always push [unbound method, self] onto the stack. + "LOAD_ATTR_METHOD_LAZY_DICT", + "LOAD_ATTR_METHOD_NO_DICT", + "LOAD_ATTR_METHOD_WITH_VALUES", ], "LOAD_CONST": [ "LOAD_CONST__LOAD_FAST", @@ -282,42 +411,10 @@ _specializations = { "LOAD_FAST__LOAD_FAST", ], "LOAD_GLOBAL": [ - "LOAD_GLOBAL_ADAPTIVE", "LOAD_GLOBAL_BUILTIN", "LOAD_GLOBAL_MODULE", ], - "LOAD_METHOD": [ - "LOAD_METHOD_ADAPTIVE", - "LOAD_METHOD_CLASS", - "LOAD_METHOD_MODULE", - "LOAD_METHOD_NO_DICT", - "LOAD_METHOD_WITH_DICT", - "LOAD_METHOD_WITH_VALUES", - ], - "PRECALL": [ - "PRECALL_ADAPTIVE", - "PRECALL_BOUND_METHOD", - "PRECALL_BUILTIN_CLASS", - "PRECALL_BUILTIN_FAST_WITH_KEYWORDS", - "PRECALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS", - "PRECALL_NO_KW_BUILTIN_FAST", - "PRECALL_NO_KW_BUILTIN_O", - "PRECALL_NO_KW_ISINSTANCE", - "PRECALL_NO_KW_LEN", - "PRECALL_NO_KW_LIST_APPEND", - "PRECALL_NO_KW_METHOD_DESCRIPTOR_FAST", - "PRECALL_NO_KW_METHOD_DESCRIPTOR_NOARGS", - "PRECALL_NO_KW_METHOD_DESCRIPTOR_O", - "PRECALL_NO_KW_STR_1", - "PRECALL_NO_KW_TUPLE_1", - "PRECALL_NO_KW_TYPE_1", - "PRECALL_PYFUNC", - ], - "RESUME": [ - "RESUME_QUICK", - ], "STORE_ATTR": [ - "STORE_ATTR_ADAPTIVE", "STORE_ATTR_INSTANCE_VALUE", "STORE_ATTR_SLOT", "STORE_ATTR_WITH_HINT", @@ -327,34 +424,27 @@ _specializations = { "STORE_FAST__STORE_FAST", ], "STORE_SUBSCR": [ - "STORE_SUBSCR_ADAPTIVE", "STORE_SUBSCR_DICT", "STORE_SUBSCR_LIST_INT", ], "UNPACK_SEQUENCE": [ - "UNPACK_SEQUENCE_ADAPTIVE", "UNPACK_SEQUENCE_LIST", "UNPACK_SEQUENCE_TUPLE", "UNPACK_SEQUENCE_TWO_TUPLE", ], + "SEND": [ + "SEND_GEN", + ], } _specialized_instructions = [ opcode for family in _specializations.values() for opcode in family ] -_specialization_stats = [ - "success", - "failure", - "hit", - "deferred", - "miss", - "deopt", -] _cache_format = { "LOAD_GLOBAL": { "counter": 1, "index": 1, - "module_keys_version": 2, + "module_keys_version": 1, "builtin_keys_version": 1, }, "BINARY_OP": { @@ -365,39 +455,35 @@ _cache_format = { }, "COMPARE_OP": { "counter": 1, - "mask": 1, }, "BINARY_SUBSCR": { "counter": 1, - "type_version": 2, - "func_version": 1, + }, + "FOR_ITER": { + "counter": 1, + }, + "LOAD_SUPER_ATTR": { + "counter": 1, }, "LOAD_ATTR": { "counter": 1, "version": 2, - "index": 1, + "keys_version": 2, + "descr": 4, }, "STORE_ATTR": { "counter": 1, "version": 2, "index": 1, }, - "LOAD_METHOD": { - "counter": 1, - "type_version": 2, - "dict_offset": 1, - "keys_version": 2, - "descr": 4, - }, "CALL": { "counter": 1, "func_version": 2, - "min_args": 1, }, - "PRECALL": { + "STORE_SUBSCR": { "counter": 1, }, - "STORE_SUBSCR": { + "SEND": { "counter": 1, }, } diff --git a/Lib/os.py b/Lib/os.py index fd1e774f..598c9e50 100644 --- a/Lib/os.py +++ b/Lib/os.py @@ -340,89 +340,95 @@ def walk(top, topdown=True, onerror=None, followlinks=False): """ sys.audit("os.walk", top, topdown, onerror, followlinks) - return _walk(fspath(top), topdown, onerror, followlinks) - -def _walk(top, topdown, onerror, followlinks): - dirs = [] - nondirs = [] - walk_dirs = [] - - # We may not have read permission for top, in which case we can't - # get a list of the files the directory contains. os.walk - # always suppressed the exception then, rather than blow up for a - # minor reason when (say) a thousand readable directories are still - # left to visit. That logic is copied here. - try: - # Note that scandir is global in this module due - # to earlier import-*. - scandir_it = scandir(top) - except OSError as error: - if onerror is not None: - onerror(error) - return - with scandir_it: - while True: - try: + stack = [fspath(top)] + islink, join = path.islink, path.join + while stack: + top = stack.pop() + if isinstance(top, tuple): + yield top + continue + + dirs = [] + nondirs = [] + walk_dirs = [] + + # We may not have read permission for top, in which case we can't + # get a list of the files the directory contains. + # We suppress the exception here, rather than blow up for a + # minor reason when (say) a thousand readable directories are still + # left to visit. + try: + scandir_it = scandir(top) + except OSError as error: + if onerror is not None: + onerror(error) + continue + + cont = False + with scandir_it: + while True: try: - entry = next(scandir_it) - except StopIteration: + try: + entry = next(scandir_it) + except StopIteration: + break + except OSError as error: + if onerror is not None: + onerror(error) + cont = True break - except OSError as error: - if onerror is not None: - onerror(error) - return - try: - is_dir = entry.is_dir() - except OSError: - # If is_dir() raises an OSError, consider that the entry is not - # a directory, same behaviour than os.path.isdir(). - is_dir = False - - if is_dir: - dirs.append(entry.name) - else: - nondirs.append(entry.name) + try: + is_dir = entry.is_dir() + except OSError: + # If is_dir() raises an OSError, consider the entry not to + # be a directory, same behaviour as os.path.isdir(). + is_dir = False - if not topdown and is_dir: - # Bottom-up: recurse into sub-directory, but exclude symlinks to - # directories if followlinks is False - if followlinks: - walk_into = True + if is_dir: + dirs.append(entry.name) else: - try: - is_symlink = entry.is_symlink() - except OSError: - # If is_symlink() raises an OSError, consider that the - # entry is not a symbolic link, same behaviour than - # os.path.islink(). - is_symlink = False - walk_into = not is_symlink - - if walk_into: - walk_dirs.append(entry.path) - - # Yield before recursion if going top down - if topdown: - yield top, dirs, nondirs - - # Recurse into sub-directories - islink, join = path.islink, path.join - for dirname in dirs: - new_path = join(top, dirname) - # Issue #23605: os.path.islink() is used instead of caching - # entry.is_symlink() result during the loop on os.scandir() because - # the caller can replace the directory entry during the "yield" - # above. - if followlinks or not islink(new_path): - yield from _walk(new_path, topdown, onerror, followlinks) - else: - # Recurse into sub-directories - for new_path in walk_dirs: - yield from _walk(new_path, topdown, onerror, followlinks) - # Yield after recursion if going bottom up - yield top, dirs, nondirs + nondirs.append(entry.name) + + if not topdown and is_dir: + # Bottom-up: traverse into sub-directory, but exclude + # symlinks to directories if followlinks is False + if followlinks: + walk_into = True + else: + try: + is_symlink = entry.is_symlink() + except OSError: + # If is_symlink() raises an OSError, consider the + # entry not to be a symbolic link, same behaviour + # as os.path.islink(). + is_symlink = False + walk_into = not is_symlink + + if walk_into: + walk_dirs.append(entry.path) + if cont: + continue + + if topdown: + # Yield before sub-directory traversal if going top down + yield top, dirs, nondirs + # Traverse into sub-directories + for dirname in reversed(dirs): + new_path = join(top, dirname) + # bpo-23605: os.path.islink() is used instead of caching + # entry.is_symlink() result during the loop on os.scandir() because + # the caller can replace the directory entry during the "yield" + # above. + if followlinks or not islink(new_path): + stack.append(new_path) + else: + # Yield after sub-directory traversal if going bottom up + stack.append((top, dirs, nondirs)) + # Traverse into sub-directories + for new_path in reversed(walk_dirs): + stack.append(new_path) __all__.append("walk") diff --git a/Lib/pathlib.py b/Lib/pathlib.py index 9d40d88e..65631b70 100644 --- a/Lib/pathlib.py +++ b/Lib/pathlib.py @@ -1,3 +1,10 @@ +"""Object-oriented filesystem paths. + +This module provides classes to represent abstract paths and concrete +paths with operations that have semantics appropriate for different +operating systems. +""" + import fnmatch import functools import io @@ -9,7 +16,6 @@ import sys import warnings from _collections_abc import Sequence from errno import ENOENT, ENOTDIR, EBADF, ELOOP -from operator import attrgetter from stat import S_ISDIR, S_ISLNK, S_ISREG, S_ISSOCK, S_ISBLK, S_ISCHR, S_ISFIFO from urllib.parse import quote_from_bytes as urlquote_from_bytes @@ -23,6 +29,14 @@ __all__ = [ # Internals # +# Reference for Windows paths can be found at +# https://learn.microsoft.com/en-gb/windows/win32/fileio/naming-a-file . +_WIN_RESERVED_NAMES = frozenset( + {'CON', 'PRN', 'AUX', 'NUL', 'CONIN$', 'CONOUT$'} | + {f'COM{c}' for c in '123456789\xb9\xb2\xb3'} | + {f'LPT{c}' for c in '123456789\xb9\xb2\xb3'} +) + _WINERROR_NOT_READY = 21 # drive exists but is not accessible _WINERROR_INVALID_NAME = 123 # fix for bpo-35306 _WINERROR_CANT_RESOLVE_FILENAME = 1921 # broken symlink pointing to itself @@ -40,271 +54,108 @@ def _ignore_error(exception): getattr(exception, 'winerror', None) in _IGNORED_WINERRORS) -def _is_wildcard_pattern(pat): - # Whether this pattern needs actual matching using fnmatch, or can - # be looked up directly as a file. - return "*" in pat or "?" in pat or "[" in pat - +@functools.cache +def _is_case_sensitive(flavour): + return flavour.normcase('Aa') == 'Aa' -class _Flavour(object): - """A flavour implements a particular (platform-specific) set of path - semantics.""" +# +# Globbing helpers +# - def __init__(self): - self.join = self.sep.join - def parse_parts(self, parts): - parsed = [] - sep = self.sep - altsep = self.altsep - drv = root = '' - it = reversed(parts) - for part in it: - if not part: - continue - if altsep: - part = part.replace(altsep, sep) - drv, root, rel = self.splitroot(part) - if sep in rel: - for x in reversed(rel.split(sep)): - if x and x != '.': - parsed.append(sys.intern(x)) - else: - if rel and rel != '.': - parsed.append(sys.intern(rel)) - if drv or root: - if not drv: - # If no drive is present, try to find one in the previous - # parts. This makes the result of parsing e.g. - # ("C:", "/", "a") reasonably intuitive. - for part in it: - if not part: - continue - if altsep: - part = part.replace(altsep, sep) - drv = self.splitroot(part)[0] - if drv: - break - break - if drv or root: - parsed.append(drv + root) - parsed.reverse() - return drv, root, parsed +# fnmatch.translate() returns a regular expression that includes a prefix and +# a suffix, which enable matching newlines and ensure the end of the string is +# matched, respectively. These features are undesirable for our implementation +# of PurePatch.match(), which represents path separators as newlines and joins +# pattern segments together. As a workaround, we define a slice object that +# can remove the prefix and suffix from any translate() result. See the +# _compile_pattern_lines() function for more details. +_FNMATCH_PREFIX, _FNMATCH_SUFFIX = fnmatch.translate('_').split('_') +_FNMATCH_SLICE = slice(len(_FNMATCH_PREFIX), -len(_FNMATCH_SUFFIX)) +_SWAP_SEP_AND_NEWLINE = { + '/': str.maketrans({'/': '\n', '\n': '/'}), + '\\': str.maketrans({'\\': '\n', '\n': '\\'}), +} - def join_parsed_parts(self, drv, root, parts, drv2, root2, parts2): - """ - Join the two paths represented by the respective - (drive, root, parts) tuples. Return a new (drive, root, parts) tuple. - """ - if root2: - if not drv2 and drv: - return drv, root2, [drv + root2] + parts2[1:] - elif drv2: - if drv2 == drv or self.casefold(drv2) == self.casefold(drv): - # Same drive => second path is relative to the first - return drv, root, parts + parts2[1:] - else: - # Second path is non-anchored (common case) - return drv, root, parts + parts2 - return drv2, root2, parts2 - - -class _WindowsFlavour(_Flavour): - # Reference for Windows paths can be found at - # http://msdn.microsoft.com/en-us/library/aa365247%28v=vs.85%29.aspx - - sep = '\\' - altsep = '/' - has_drv = True - pathmod = ntpath - - is_supported = (os.name == 'nt') - - drive_letters = set('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') - ext_namespace_prefix = '\\\\?\\' - - reserved_names = ( - {'CON', 'PRN', 'AUX', 'NUL', 'CONIN$', 'CONOUT$'} | - {'COM%s' % c for c in '123456789\xb9\xb2\xb3'} | - {'LPT%s' % c for c in '123456789\xb9\xb2\xb3'} - ) - - # Interesting findings about extended paths: - # * '\\?\c:\a' is an extended path, which bypasses normal Windows API - # path processing. Thus relative paths are not resolved and slash is not - # translated to backslash. It has the native NT path limit of 32767 - # characters, but a bit less after resolving device symbolic links, - # such as '\??\C:' => '\Device\HarddiskVolume2'. - # * '\\?\c:/a' looks for a device named 'C:/a' because slash is a - # regular name character in the object namespace. - # * '\\?\c:\foo/bar' is invalid because '/' is illegal in NT filesystems. - # The only path separator at the filesystem level is backslash. - # * '//?/c:\a' and '//?/c:/a' are effectively equivalent to '\\.\c:\a' and - # thus limited to MAX_PATH. - # * Prior to Windows 8, ANSI API bytes paths are limited to MAX_PATH, - # even with the '\\?\' prefix. - - def splitroot(self, part, sep=sep): - first = part[0:1] - second = part[1:2] - if (second == sep and first == sep): - # XXX extended paths should also disable the collapsing of "." - # components (according to MSDN docs). - prefix, part = self._split_extended_path(part) - first = part[0:1] - second = part[1:2] - else: - prefix = '' - third = part[2:3] - if (second == sep and first == sep and third != sep): - # is a UNC path: - # vvvvvvvvvvvvvvvvvvvvv root - # \\machine\mountpoint\directory\etc\... - # directory ^^^^^^^^^^^^^^ - index = part.find(sep, 2) - if index != -1: - index2 = part.find(sep, index + 1) - # a UNC path can't have two slashes in a row - # (after the initial two) - if index2 != index + 1: - if index2 == -1: - index2 = len(part) - if prefix: - return prefix + part[1:index2], sep, part[index2+1:] - else: - return part[:index2], sep, part[index2+1:] - drv = root = '' - if second == ':' and first in self.drive_letters: - drv = part[:2] - part = part[2:] - first = third - if first == sep: - root = first - part = part.lstrip(sep) - return prefix + drv, root, part - - def casefold(self, s): - return s.lower() - - def casefold_parts(self, parts): - return [p.lower() for p in parts] - - def compile_pattern(self, pattern): - return re.compile(fnmatch.translate(pattern), re.IGNORECASE).fullmatch - - def _split_extended_path(self, s, ext_prefix=ext_namespace_prefix): - prefix = '' - if s.startswith(ext_prefix): - prefix = s[:4] - s = s[4:] - if s.startswith('UNC\\'): - prefix += s[:3] - s = '\\' + s[3:] - return prefix, s - - def is_reserved(self, parts): - # NOTE: the rules for reserved names seem somewhat complicated - # (e.g. r"..\NUL" is reserved but not r"foo\NUL" if "foo" does not - # exist). We err on the side of caution and return True for paths - # which are not considered reserved by Windows. - if not parts: - return False - if parts[0].startswith('\\\\'): - # UNC paths are never reserved - return False - name = parts[-1].partition('.')[0].partition(':')[0].rstrip(' ') - return name.upper() in self.reserved_names - def make_uri(self, path): - # Under Windows, file URIs use the UTF-8 encoding. - drive = path.drive - if len(drive) == 2 and drive[1] == ':': - # It's a path on a local drive => 'file:///c:/a/b' - rest = path.as_posix()[2:].lstrip('/') - return 'file:///%s/%s' % ( - drive, urlquote_from_bytes(rest.encode('utf-8'))) +@functools.lru_cache() +def _make_selector(pattern_parts, flavour, case_sensitive): + pat = pattern_parts[0] + if not pat: + return _TerminatingSelector() + if pat == '**': + child_parts_idx = 1 + while child_parts_idx < len(pattern_parts) and pattern_parts[child_parts_idx] == '**': + child_parts_idx += 1 + child_parts = pattern_parts[child_parts_idx:] + if '**' in child_parts: + cls = _DoubleRecursiveWildcardSelector else: - # It's a path on a network drive => 'file://host/share/a/b' - return 'file:' + urlquote_from_bytes(path.as_posix().encode('utf-8')) - - -class _PosixFlavour(_Flavour): - sep = '/' - altsep = '' - has_drv = False - pathmod = posixpath - - is_supported = (os.name != 'nt') - - def splitroot(self, part, sep=sep): - if part and part[0] == sep: - stripped_part = part.lstrip(sep) - # According to POSIX path resolution: - # http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap04.html#tag_04_11 - # "A pathname that begins with two successive slashes may be - # interpreted in an implementation-defined manner, although more - # than two leading slashes shall be treated as a single slash". - if len(part) - len(stripped_part) == 2: - return '', sep * 2, stripped_part - else: - return '', sep, stripped_part + cls = _RecursiveWildcardSelector + else: + child_parts = pattern_parts[1:] + if pat == '..': + cls = _ParentSelector + elif '**' in pat: + raise ValueError("Invalid pattern: '**' can only be an entire path component") else: - return '', '', part - - def casefold(self, s): - return s - - def casefold_parts(self, parts): - return parts - - def compile_pattern(self, pattern): - return re.compile(fnmatch.translate(pattern)).fullmatch + cls = _WildcardSelector + return cls(pat, child_parts, flavour, case_sensitive) - def is_reserved(self, parts): - return False - def make_uri(self, path): - # We represent the path using the local filesystem encoding, - # for portability to other applications. - bpath = bytes(path) - return 'file://' + urlquote_from_bytes(bpath) +@functools.lru_cache(maxsize=256) +def _compile_pattern(pat, case_sensitive): + flags = re.NOFLAG if case_sensitive else re.IGNORECASE + return re.compile(fnmatch.translate(pat), flags).match -_windows_flavour = _WindowsFlavour() -_posix_flavour = _PosixFlavour() +@functools.lru_cache() +def _compile_pattern_lines(pattern_lines, case_sensitive): + """Compile the given pattern lines to an `re.Pattern` object. + The *pattern_lines* argument is a glob-style pattern (e.g. '*/*.py') with + its path separators and newlines swapped (e.g. '*\n*.py`). By using + newlines to separate path components, and not setting `re.DOTALL`, we + ensure that the `*` wildcard cannot match path separators. -# -# Globbing helpers -# - -def _make_selector(pattern_parts, flavour): - pat = pattern_parts[0] - child_parts = pattern_parts[1:] - if not pat: - return _TerminatingSelector() - if pat == '**': - cls = _RecursiveWildcardSelector - elif '**' in pat: - raise ValueError("Invalid pattern: '**' can only be an entire path component") - elif _is_wildcard_pattern(pat): - cls = _WildcardSelector - else: - cls = _PreciseSelector - return cls(pat, child_parts, flavour) + The returned `re.Pattern` object may have its `match()` method called to + match a complete pattern, or `search()` to match from the right. The + argument supplied to these methods must also have its path separators and + newlines swapped. + """ -if hasattr(functools, "lru_cache"): - _make_selector = functools.lru_cache()(_make_selector) + # Match the start of the path, or just after a path separator + parts = ['^'] + for part in pattern_lines.splitlines(keepends=True): + if part == '*\n': + part = r'.+\n' + elif part == '*': + part = r'.+' + else: + # Any other component: pass to fnmatch.translate(). We slice off + # the common prefix and suffix added by translate() to ensure that + # re.DOTALL is not set, and the end of the string not matched, + # respectively. With DOTALL not set, '*' wildcards will not match + # path separators, because the '.' characters in the pattern will + # not match newlines. + part = fnmatch.translate(part)[_FNMATCH_SLICE] + parts.append(part) + # Match the end of the path, always. + parts.append(r'\Z') + flags = re.MULTILINE + if not case_sensitive: + flags |= re.IGNORECASE + return re.compile(''.join(parts), flags=flags) class _Selector: """A selector matches a specific glob pattern part against the children of a given path.""" - def __init__(self, child_parts, flavour): + def __init__(self, child_parts, flavour, case_sensitive): self.child_parts = child_parts if child_parts: - self.successor = _make_selector(child_parts, flavour) + self.successor = _make_selector(child_parts, flavour, case_sensitive) self.dironly = True else: self.successor = _TerminatingSelector() @@ -314,105 +165,95 @@ class _Selector: """Iterate over all child paths of `parent_path` matched by this selector. This can contain parent_path itself.""" path_cls = type(parent_path) - is_dir = path_cls.is_dir - exists = path_cls.exists scandir = path_cls._scandir - if not is_dir(parent_path): + if not parent_path.is_dir(): return iter([]) - return self._select_from(parent_path, is_dir, exists, scandir) + return self._select_from(parent_path, scandir) class _TerminatingSelector: - def _select_from(self, parent_path, is_dir, exists, scandir): + def _select_from(self, parent_path, scandir): yield parent_path -class _PreciseSelector(_Selector): +class _ParentSelector(_Selector): - def __init__(self, name, child_parts, flavour): - self.name = name - _Selector.__init__(self, child_parts, flavour) + def __init__(self, name, child_parts, flavour, case_sensitive): + _Selector.__init__(self, child_parts, flavour, case_sensitive) - def _select_from(self, parent_path, is_dir, exists, scandir): - try: - path = parent_path._make_child_relpath(self.name) - if (is_dir if self.dironly else exists)(path): - for p in self.successor._select_from(path, is_dir, exists, scandir): - yield p - except PermissionError: - return + def _select_from(self, parent_path, scandir): + path = parent_path._make_child_relpath('..') + for p in self.successor._select_from(path, scandir): + yield p class _WildcardSelector(_Selector): - def __init__(self, pat, child_parts, flavour): - self.match = flavour.compile_pattern(pat) - _Selector.__init__(self, child_parts, flavour) + def __init__(self, pat, child_parts, flavour, case_sensitive): + _Selector.__init__(self, child_parts, flavour, case_sensitive) + if case_sensitive is None: + # TODO: evaluate case-sensitivity of each directory in _select_from() + case_sensitive = _is_case_sensitive(flavour) + self.match = _compile_pattern(pat, case_sensitive) - def _select_from(self, parent_path, is_dir, exists, scandir): + def _select_from(self, parent_path, scandir): try: + # We must close the scandir() object before proceeding to + # avoid exhausting file descriptors when globbing deep trees. with scandir(parent_path) as scandir_it: entries = list(scandir_it) + except OSError: + pass + else: for entry in entries: if self.dironly: try: - # "entry.is_dir()" can raise PermissionError - # in some cases (see bpo-38894), which is not - # among the errors ignored by _ignore_error() if not entry.is_dir(): continue - except OSError as e: - if not _ignore_error(e): - raise + except OSError: continue name = entry.name if self.match(name): path = parent_path._make_child_relpath(name) - for p in self.successor._select_from(path, is_dir, exists, scandir): + for p in self.successor._select_from(path, scandir): yield p - except PermissionError: - return class _RecursiveWildcardSelector(_Selector): - def __init__(self, pat, child_parts, flavour): - _Selector.__init__(self, child_parts, flavour) + def __init__(self, pat, child_parts, flavour, case_sensitive): + _Selector.__init__(self, child_parts, flavour, case_sensitive) - def _iterate_directories(self, parent_path, is_dir, scandir): + def _iterate_directories(self, parent_path): yield parent_path - try: - with scandir(parent_path) as scandir_it: - entries = list(scandir_it) - for entry in entries: - entry_is_dir = False - try: - entry_is_dir = entry.is_dir() - except OSError as e: - if not _ignore_error(e): - raise - if entry_is_dir and not entry.is_symlink(): - path = parent_path._make_child_relpath(entry.name) - for p in self._iterate_directories(path, is_dir, scandir): - yield p - except PermissionError: - return + for dirpath, dirnames, _ in parent_path.walk(): + for dirname in dirnames: + yield dirpath._make_child_relpath(dirname) + + def _select_from(self, parent_path, scandir): + successor_select = self.successor._select_from + for starting_point in self._iterate_directories(parent_path): + for p in successor_select(starting_point, scandir): + yield p + - def _select_from(self, parent_path, is_dir, exists, scandir): +class _DoubleRecursiveWildcardSelector(_RecursiveWildcardSelector): + """ + Like _RecursiveWildcardSelector, but also de-duplicates results from + successive selectors. This is necessary if the pattern contains + multiple non-adjacent '**' segments. + """ + + def _select_from(self, parent_path, scandir): + yielded = set() try: - yielded = set() - try: - successor_select = self.successor._select_from - for starting_point in self._iterate_directories(parent_path, is_dir, scandir): - for p in successor_select(starting_point, is_dir, exists, scandir): - if p not in yielded: - yield p - yielded.add(p) - finally: - yielded.clear() - except PermissionError: - return + for p in super()._select_from(parent_path, scandir): + if p not in yielded: + yield p + yielded.add(p) + finally: + yielded.clear() # @@ -422,20 +263,16 @@ class _RecursiveWildcardSelector(_Selector): class _PathParents(Sequence): """This object provides sequence-like access to the logical ancestors of a path. Don't try to construct it yourself.""" - __slots__ = ('_pathcls', '_drv', '_root', '_parts') + __slots__ = ('_path', '_drv', '_root', '_tail') def __init__(self, path): - # We don't store the instance to avoid reference cycles - self._pathcls = type(path) - self._drv = path._drv - self._root = path._root - self._parts = path._parts + self._path = path + self._drv = path.drive + self._root = path.root + self._tail = path._tail def __len__(self): - if self._drv or self._root: - return len(self._parts) - 1 - else: - return len(self._parts) + return len(self._tail) def __getitem__(self, idx): if isinstance(idx, slice): @@ -445,11 +282,11 @@ class _PathParents(Sequence): raise IndexError(idx) if idx < 0: idx += len(self) - return self._pathcls._from_parsed_parts(self._drv, self._root, - self._parts[:-idx - 1]) + return self._path._from_parsed_parts(self._drv, self._root, + self._tail[:-idx - 1]) def __repr__(self): - return "<{}.parents>".format(self._pathcls.__name__) + return "<{}.parents>".format(type(self._path).__name__) class PurePath(object): @@ -461,12 +298,49 @@ class PurePath(object): PureWindowsPath object. You can also instantiate either of these classes directly, regardless of your system. """ + __slots__ = ( - '_drv', '_root', '_parts', - '_str', '_hash', '_pparts', '_cached_cparts', + # The `_raw_paths` slot stores unnormalized string paths. This is set + # in the `__init__()` method. + '_raw_paths', + + # The `_drv`, `_root` and `_tail_cached` slots store parsed and + # normalized parts of the path. They are set when any of the `drive`, + # `root` or `_tail` properties are accessed for the first time. The + # three-part division corresponds to the result of + # `os.path.splitroot()`, except that the tail is further split on path + # separators (i.e. it is a list of strings), and that the root and + # tail are normalized. + '_drv', '_root', '_tail_cached', + + # The `_str` slot stores the string representation of the path, + # computed from the drive, root and tail when `__str__()` is called + # for the first time. It's used to implement `_str_normcase` + '_str', + + # The `_str_normcase_cached` slot stores the string path with + # normalized case. It is set when the `_str_normcase` property is + # accessed for the first time. It's used to implement `__eq__()` + # `__hash__()`, and `_parts_normcase` + '_str_normcase_cached', + + # The `_parts_normcase_cached` slot stores the case-normalized + # string path after splitting on path separators. It's set when the + # `_parts_normcase` property is accessed for the first time. It's used + # to implement comparison methods like `__lt__()`. + '_parts_normcase_cached', + + # The `_lines_cached` slot stores the string path with path separators + # and newlines swapped. This is used to implement `match()`. + '_lines_cached', + + # The `_hash` slot stores the hash of the case-normalized string + # path. It's set when `__hash__()` is called for the first time. + '_hash', ) + _flavour = os.path - def __new__(cls, *args): + def __new__(cls, *args, **kwargs): """Construct a PurePath from one or several strings and or existing PurePath objects. The strings and path objects are combined so as to yield a canonicalized path, which is incorporated into the @@ -474,64 +348,91 @@ class PurePath(object): """ if cls is PurePath: cls = PureWindowsPath if os.name == 'nt' else PurePosixPath - return cls._from_parts(args) + return object.__new__(cls) def __reduce__(self): # Using the parts tuple helps share interned path parts # when pickling related paths. - return (self.__class__, tuple(self._parts)) - - @classmethod - def _parse_args(cls, args): - # This is useful when you don't want to create an instance, just - # canonicalize some constructor arguments. - parts = [] - for a in args: - if isinstance(a, PurePath): - parts += a._parts - else: - a = os.fspath(a) - if isinstance(a, str): - # Force-cast str subclasses to str (issue #21127) - parts.append(str(a)) + return (self.__class__, self.parts) + + def __init__(self, *args): + paths = [] + for arg in args: + if isinstance(arg, PurePath): + if arg._flavour is ntpath and self._flavour is posixpath: + # GH-103631: Convert separators for backwards compatibility. + paths.extend(path.replace('\\', '/') for path in arg._raw_paths) else: + paths.extend(arg._raw_paths) + else: + try: + path = os.fspath(arg) + except TypeError: + path = arg + if not isinstance(path, str): raise TypeError( - "argument should be a str object or an os.PathLike " - "object returning str, not %r" - % type(a)) - return cls._flavour.parse_parts(parts) + "argument should be a str or an os.PathLike " + "object where __fspath__ returns a str, " + f"not {type(path).__name__!r}") + paths.append(path) + self._raw_paths = paths - @classmethod - def _from_parts(cls, args): - # We need to call _parse_args on the instance, so as to get the - # right flavour. - self = object.__new__(cls) - drv, root, parts = self._parse_args(args) - self._drv = drv - self._root = root - self._parts = parts - return self + def with_segments(self, *pathsegments): + """Construct a new path object from any number of path-like objects. + Subclasses may override this method to customize how new path objects + are created from methods like `iterdir()`. + """ + return type(self)(*pathsegments) @classmethod - def _from_parsed_parts(cls, drv, root, parts): - self = object.__new__(cls) + def _parse_path(cls, path): + if not path: + return '', '', [] + sep = cls._flavour.sep + altsep = cls._flavour.altsep + if altsep: + path = path.replace(altsep, sep) + drv, root, rel = cls._flavour.splitroot(path) + if not root and drv.startswith(sep) and not drv.endswith(sep): + drv_parts = drv.split(sep) + if len(drv_parts) == 4 and drv_parts[2] not in '?.': + # e.g. //server/share + root = sep + elif len(drv_parts) == 6: + # e.g. //?/unc/server/share + root = sep + parsed = [sys.intern(str(x)) for x in rel.split(sep) if x and x != '.'] + return drv, root, parsed + + def _load_parts(self): + paths = self._raw_paths + if len(paths) == 0: + path = '' + elif len(paths) == 1: + path = paths[0] + else: + path = self._flavour.join(*paths) + drv, root, tail = self._parse_path(path) self._drv = drv self._root = root - self._parts = parts - return self + self._tail_cached = tail + + def _from_parsed_parts(self, drv, root, tail): + path_str = self._format_parsed_parts(drv, root, tail) + path = self.with_segments(path_str) + path._str = path_str or '.' + path._drv = drv + path._root = root + path._tail_cached = tail + return path @classmethod - def _format_parsed_parts(cls, drv, root, parts): + def _format_parsed_parts(cls, drv, root, tail): if drv or root: - return drv + root + cls._flavour.join(parts[1:]) - else: - return cls._flavour.join(parts) - - def _make_child(self, args): - drv, root, parts = self._parse_args(args) - drv, root, parts = self._flavour.join_parsed_parts( - self._drv, self._root, self._parts, drv, root, parts) - return self._from_parsed_parts(drv, root, parts) + return drv + root + cls._flavour.sep.join(tail) + elif tail and cls._flavour.splitdrive(tail[0])[0]: + tail = ['.'] + tail + return cls._flavour.sep.join(tail) def __str__(self): """Return the string representation of the path, suitable for @@ -539,8 +440,8 @@ class PurePath(object): try: return self._str except AttributeError: - self._str = self._format_parsed_parts(self._drv, self._root, - self._parts) or '.' + self._str = self._format_parsed_parts(self.drive, self.root, + self._tail) or '.' return self._str def __fspath__(self): @@ -564,68 +465,128 @@ class PurePath(object): """Return the path as a 'file' URI.""" if not self.is_absolute(): raise ValueError("relative path can't be expressed as a file URI") - return self._flavour.make_uri(self) + + drive = self.drive + if len(drive) == 2 and drive[1] == ':': + # It's a path on a local drive => 'file:///c:/a/b' + prefix = 'file:///' + drive + path = self.as_posix()[2:] + elif drive: + # It's a path on a network drive => 'file://host/share/a/b' + prefix = 'file:' + path = self.as_posix() + else: + # It's a posix path => 'file:///etc/hosts' + prefix = 'file://' + path = str(self) + return prefix + urlquote_from_bytes(os.fsencode(path)) + + @property + def _str_normcase(self): + # String with normalized case, for hashing and equality checks + try: + return self._str_normcase_cached + except AttributeError: + if _is_case_sensitive(self._flavour): + self._str_normcase_cached = str(self) + else: + self._str_normcase_cached = str(self).lower() + return self._str_normcase_cached + + @property + def _parts_normcase(self): + # Cached parts with normalized case, for comparisons. + try: + return self._parts_normcase_cached + except AttributeError: + self._parts_normcase_cached = self._str_normcase.split(self._flavour.sep) + return self._parts_normcase_cached @property - def _cparts(self): - # Cached casefolded parts, for hashing and comparison + def _lines(self): + # Path with separators and newlines swapped, for pattern matching. try: - return self._cached_cparts + return self._lines_cached except AttributeError: - self._cached_cparts = self._flavour.casefold_parts(self._parts) - return self._cached_cparts + path_str = str(self) + if path_str == '.': + self._lines_cached = '' + else: + trans = _SWAP_SEP_AND_NEWLINE[self._flavour.sep] + self._lines_cached = path_str.translate(trans) + return self._lines_cached def __eq__(self, other): if not isinstance(other, PurePath): return NotImplemented - return self._cparts == other._cparts and self._flavour is other._flavour + return self._str_normcase == other._str_normcase and self._flavour is other._flavour def __hash__(self): try: return self._hash except AttributeError: - self._hash = hash(tuple(self._cparts)) + self._hash = hash(self._str_normcase) return self._hash def __lt__(self, other): if not isinstance(other, PurePath) or self._flavour is not other._flavour: return NotImplemented - return self._cparts < other._cparts + return self._parts_normcase < other._parts_normcase def __le__(self, other): if not isinstance(other, PurePath) or self._flavour is not other._flavour: return NotImplemented - return self._cparts <= other._cparts + return self._parts_normcase <= other._parts_normcase def __gt__(self, other): if not isinstance(other, PurePath) or self._flavour is not other._flavour: return NotImplemented - return self._cparts > other._cparts + return self._parts_normcase > other._parts_normcase def __ge__(self, other): if not isinstance(other, PurePath) or self._flavour is not other._flavour: return NotImplemented - return self._cparts >= other._cparts + return self._parts_normcase >= other._parts_normcase + + @property + def drive(self): + """The drive prefix (letter or UNC path), if any.""" + try: + return self._drv + except AttributeError: + self._load_parts() + return self._drv - drive = property(attrgetter('_drv'), - doc="""The drive prefix (letter or UNC path), if any.""") + @property + def root(self): + """The root of the path, if any.""" + try: + return self._root + except AttributeError: + self._load_parts() + return self._root - root = property(attrgetter('_root'), - doc="""The root of the path, if any.""") + @property + def _tail(self): + try: + return self._tail_cached + except AttributeError: + self._load_parts() + return self._tail_cached @property def anchor(self): """The concatenation of the drive and root, or ''.""" - anchor = self._drv + self._root + anchor = self.drive + self.root return anchor @property def name(self): """The final path component, if any.""" - parts = self._parts - if len(parts) == (1 if (self._drv or self._root) else 0): + tail = self._tail + if not tail: return '' - return parts[-1] + return tail[-1] @property def suffix(self): @@ -668,12 +629,12 @@ class PurePath(object): """Return a new path with the file name changed.""" if not self.name: raise ValueError("%r has an empty name" % (self,)) - drv, root, parts = self._flavour.parse_parts((name,)) - if (not name or name[-1] in [self._flavour.sep, self._flavour.altsep] - or drv or root or len(parts) != 1): + f = self._flavour + drv, root, tail = f.splitroot(name) + if drv or root or not tail or f.sep in tail or (f.altsep and f.altsep in tail): raise ValueError("Invalid name %r" % (name)) - return self._from_parsed_parts(self._drv, self._root, - self._parts[:-1] + [name]) + return self._from_parsed_parts(self.drive, self.root, + self._tail[:-1] + [name]) def with_stem(self, stem): """Return a new path with the stem changed.""" @@ -697,137 +658,144 @@ class PurePath(object): name = name + suffix else: name = name[:-len(old_suffix)] + suffix - return self._from_parsed_parts(self._drv, self._root, - self._parts[:-1] + [name]) + return self._from_parsed_parts(self.drive, self.root, + self._tail[:-1] + [name]) - def relative_to(self, *other): + def relative_to(self, other, /, *_deprecated, walk_up=False): """Return the relative path to another path identified by the passed arguments. If the operation is not possible (because this is not - a subpath of the other path), raise ValueError. - """ - # For the purpose of this method, drive and root are considered - # separate parts, i.e.: - # Path('c:/').relative_to('c:') gives Path('/') - # Path('c:/').relative_to('/') raise ValueError - if not other: - raise TypeError("need at least one argument") - parts = self._parts - drv = self._drv - root = self._root - if root: - abs_parts = [drv, root] + parts[1:] - else: - abs_parts = parts - to_drv, to_root, to_parts = self._parse_args(other) - if to_root: - to_abs_parts = [to_drv, to_root] + to_parts[1:] + related to the other path), raise ValueError. + + The *walk_up* parameter controls whether `..` may be used to resolve + the path. + """ + if _deprecated: + msg = ("support for supplying more than one positional argument " + "to pathlib.PurePath.relative_to() is deprecated and " + "scheduled for removal in Python {remove}") + warnings._deprecated("pathlib.PurePath.relative_to(*args)", msg, + remove=(3, 14)) + other = self.with_segments(other, *_deprecated) + for step, path in enumerate([other] + list(other.parents)): + if self.is_relative_to(path): + break + elif not walk_up: + raise ValueError(f"{str(self)!r} is not in the subpath of {str(other)!r}") + elif path.name == '..': + raise ValueError(f"'..' segment in {str(other)!r} cannot be walked") else: - to_abs_parts = to_parts - n = len(to_abs_parts) - cf = self._flavour.casefold_parts - if (root or drv) if n == 0 else cf(abs_parts[:n]) != cf(to_abs_parts): - formatted = self._format_parsed_parts(to_drv, to_root, to_parts) - raise ValueError("{!r} is not in the subpath of {!r}" - " OR one path is relative and the other is absolute." - .format(str(self), str(formatted))) - return self._from_parsed_parts('', root if n == 1 else '', - abs_parts[n:]) - - def is_relative_to(self, *other): + raise ValueError(f"{str(self)!r} and {str(other)!r} have different anchors") + parts = ['..'] * step + self._tail[len(path._tail):] + return self.with_segments(*parts) + + def is_relative_to(self, other, /, *_deprecated): """Return True if the path is relative to another path or False. """ - try: - self.relative_to(*other) - return True - except ValueError: - return False + if _deprecated: + msg = ("support for supplying more than one argument to " + "pathlib.PurePath.is_relative_to() is deprecated and " + "scheduled for removal in Python {remove}") + warnings._deprecated("pathlib.PurePath.is_relative_to(*args)", + msg, remove=(3, 14)) + other = self.with_segments(other, *_deprecated) + return other == self or other in self.parents @property def parts(self): """An object providing sequence-like access to the components in the filesystem path.""" - # We cache the tuple to avoid building a new one each time .parts - # is accessed. XXX is this necessary? - try: - return self._pparts - except AttributeError: - self._pparts = tuple(self._parts) - return self._pparts + if self.drive or self.root: + return (self.drive + self.root,) + tuple(self._tail) + else: + return tuple(self._tail) - def joinpath(self, *args): + def joinpath(self, *pathsegments): """Combine this path with one or several arguments, and return a new path representing either a subpath (if all arguments are relative paths) or a totally different path (if one of the arguments is anchored). """ - return self._make_child(args) + return self.with_segments(self, *pathsegments) def __truediv__(self, key): try: - return self._make_child((key,)) + return self.joinpath(key) except TypeError: return NotImplemented def __rtruediv__(self, key): try: - return self._from_parts([key] + self._parts) + return self.with_segments(key, self) except TypeError: return NotImplemented @property def parent(self): """The logical parent of the path.""" - drv = self._drv - root = self._root - parts = self._parts - if len(parts) == 1 and (drv or root): + drv = self.drive + root = self.root + tail = self._tail + if not tail: return self - return self._from_parsed_parts(drv, root, parts[:-1]) + return self._from_parsed_parts(drv, root, tail[:-1]) @property def parents(self): """A sequence of this path's logical parents.""" + # The value of this property should not be cached on the path object, + # as doing so would introduce a reference cycle. return _PathParents(self) def is_absolute(self): """True if the path is absolute (has both a root and, if applicable, a drive).""" - if not self._root: + if self._flavour is ntpath: + # ntpath.isabs() is defective - see GH-44626. + return bool(self.drive and self.root) + elif self._flavour is posixpath: + # Optimization: work with raw paths on POSIX. + for path in self._raw_paths: + if path.startswith('/'): + return True return False - return not self._flavour.has_drv or bool(self._drv) + else: + return self._flavour.isabs(str(self)) def is_reserved(self): """Return True if the path contains one of the special names reserved by the system, if any.""" - return self._flavour.is_reserved(self._parts) + if self._flavour is posixpath or not self._tail: + return False + + # NOTE: the rules for reserved names seem somewhat complicated + # (e.g. r"..\NUL" is reserved but not r"foo\NUL" if "foo" does not + # exist). We err on the side of caution and return True for paths + # which are not considered reserved by Windows. + if self.drive.startswith('\\\\'): + # UNC paths are never reserved. + return False + name = self._tail[-1].partition('.')[0].partition(':')[0].rstrip(' ') + return name.upper() in _WIN_RESERVED_NAMES - def match(self, path_pattern): + def match(self, path_pattern, *, case_sensitive=None): """ Return True if this path matches the given pattern. """ - cf = self._flavour.casefold - path_pattern = cf(path_pattern) - drv, root, pat_parts = self._flavour.parse_parts((path_pattern,)) - if not pat_parts: + if not isinstance(path_pattern, PurePath): + path_pattern = self.with_segments(path_pattern) + if case_sensitive is None: + case_sensitive = _is_case_sensitive(self._flavour) + pattern = _compile_pattern_lines(path_pattern._lines, case_sensitive) + if path_pattern.drive or path_pattern.root: + return pattern.match(self._lines) is not None + elif path_pattern._tail: + return pattern.search(self._lines) is not None + else: raise ValueError("empty pattern") - if drv and drv != cf(self._drv): - return False - if root and root != cf(self._root): - return False - parts = self._cparts - if drv or root: - if len(pat_parts) != len(parts): - return False - pat_parts = pat_parts[1:] - elif len(pat_parts) > len(parts): - return False - for part, pat in zip(reversed(parts), reversed(pat_parts)): - if not fnmatch.fnmatchcase(part, pat): - return False - return True + # Can't subclass os.PathLike from PurePath and keep the constructor -# optimizations in PurePath._parse_args(). +# optimizations in PurePath.__slots__. os.PathLike.register(PurePath) @@ -837,7 +805,7 @@ class PurePosixPath(PurePath): On a POSIX system, instantiating a PurePath should return this object. However, you can also instantiate it directly on any system. """ - _flavour = _posix_flavour + _flavour = posixpath __slots__ = () @@ -847,7 +815,7 @@ class PureWindowsPath(PurePath): On a Windows system, instantiating a PurePath should return this object. However, you can also instantiate it directly on any system. """ - _flavour = _windows_flavour + _flavour = ntpath __slots__ = () @@ -865,173 +833,175 @@ class Path(PurePath): """ __slots__ = () - def __new__(cls, *args, **kwargs): - if cls is Path: - cls = WindowsPath if os.name == 'nt' else PosixPath - self = cls._from_parts(args) - if not self._flavour.is_supported: - raise NotImplementedError("cannot instantiate %r on your system" - % (cls.__name__,)) - return self - - def _make_child_relpath(self, part): - # This is an optimization used for dir walking. `part` must be - # a single part relative to this path. - parts = self._parts + [part] - return self._from_parsed_parts(self._drv, self._root, parts) - - def __enter__(self): - # In previous versions of pathlib, __exit__() marked this path as - # closed; subsequent attempts to perform I/O would raise an IOError. - # This functionality was never documented, and had the effect of - # making Path objects mutable, contrary to PEP 428. - # In Python 3.9 __exit__() was made a no-op. - # In Python 3.11 __enter__() began emitting DeprecationWarning. - # In Python 3.13 __enter__() and __exit__() should be removed. - warnings.warn("pathlib.Path.__enter__() is deprecated and scheduled " - "for removal in Python 3.13; Path objects as a context " - "manager is a no-op", - DeprecationWarning, stacklevel=2) - return self - - def __exit__(self, t, v, tb): - pass - - # Public API - - @classmethod - def cwd(cls): - """Return a new path pointing to the current working directory - (as returned by os.getcwd()). + def stat(self, *, follow_symlinks=True): """ - return cls(os.getcwd()) - - @classmethod - def home(cls): - """Return a new path pointing to the user's home directory (as - returned by os.path.expanduser('~')). + Return the result of the stat() system call on this path, like + os.stat() does. """ - return cls("~").expanduser() + return os.stat(self, follow_symlinks=follow_symlinks) - def samefile(self, other_path): - """Return whether other_path is the same or not as this file - (as returned by os.path.samefile()). + def lstat(self): """ - st = self.stat() - try: - other_st = other_path.stat() - except AttributeError: - other_st = self.__class__(other_path).stat() - return os.path.samestat(st, other_st) - - def iterdir(self): - """Iterate over the files in this directory. Does not yield any - result for the special paths '.' and '..'. + Like stat(), except if the path points to a symlink, the symlink's + status information is returned, rather than its target's. """ - for name in os.listdir(self): - yield self._make_child_relpath(name) + return self.stat(follow_symlinks=False) - def _scandir(self): - # bpo-24132: a future version of pathlib will support subclassing of - # pathlib.Path to customize how the filesystem is accessed. This - # includes scandir(), which is used to implement glob(). - return os.scandir(self) - def glob(self, pattern): - """Iterate over this subtree and yield all existing files (of any - kind, including directories) matching the given relative pattern. - """ - sys.audit("pathlib.Path.glob", self, pattern) - if not pattern: - raise ValueError("Unacceptable pattern: {!r}".format(pattern)) - drv, root, pattern_parts = self._flavour.parse_parts((pattern,)) - if drv or root: - raise NotImplementedError("Non-relative patterns are unsupported") - if pattern[-1] in (self._flavour.sep, self._flavour.altsep): - pattern_parts.append('') - selector = _make_selector(tuple(pattern_parts), self._flavour) - for p in selector.select_from(self): - yield p + # Convenience functions for querying the stat results - def rglob(self, pattern): - """Recursively yield all existing files (of any kind, including - directories) matching the given relative pattern, anywhere in - this subtree. + def exists(self, *, follow_symlinks=True): """ - sys.audit("pathlib.Path.rglob", self, pattern) - drv, root, pattern_parts = self._flavour.parse_parts((pattern,)) - if drv or root: - raise NotImplementedError("Non-relative patterns are unsupported") - if pattern and pattern[-1] in (self._flavour.sep, self._flavour.altsep): - pattern_parts.append('') - selector = _make_selector(("**",) + tuple(pattern_parts), self._flavour) - for p in selector.select_from(self): - yield p - - def absolute(self): - """Return an absolute version of this path by prepending the current - working directory. No normalization or symlink resolution is performed. + Whether this path exists. - Use resolve() to get the canonical path to a file. + This method normally follows symlinks; to check whether a symlink exists, + add the argument follow_symlinks=False. """ - if self.is_absolute(): - return self - return self._from_parts([self.cwd()] + self._parts) + try: + self.stat(follow_symlinks=follow_symlinks) + except OSError as e: + if not _ignore_error(e): + raise + return False + except ValueError: + # Non-encodable path + return False + return True - def resolve(self, strict=False): + def is_dir(self): """ - Make the path absolute, resolving all symlinks on the way and also - normalizing it. + Whether this path is a directory. """ - - def check_eloop(e): - winerror = getattr(e, 'winerror', 0) - if e.errno == ELOOP or winerror == _WINERROR_CANT_RESOLVE_FILENAME: - raise RuntimeError("Symlink loop from %r" % e.filename) - try: - s = os.path.realpath(self, strict=strict) + return S_ISDIR(self.stat().st_mode) except OSError as e: - check_eloop(e) - raise - p = self._from_parts((s,)) + if not _ignore_error(e): + raise + # Path doesn't exist or is a broken symlink + # (see http://web.archive.org/web/20200623061726/https://bitbucket.org/pitrou/pathlib/issues/12/ ) + return False + except ValueError: + # Non-encodable path + return False - # In non-strict mode, realpath() doesn't raise on symlink loops. - # Ensure we get an exception by calling stat() - if not strict: - try: - p.stat() - except OSError as e: - check_eloop(e) - return p + def is_file(self): + """ + Whether this path is a regular file (also True for symlinks pointing + to regular files). + """ + try: + return S_ISREG(self.stat().st_mode) + except OSError as e: + if not _ignore_error(e): + raise + # Path doesn't exist or is a broken symlink + # (see http://web.archive.org/web/20200623061726/https://bitbucket.org/pitrou/pathlib/issues/12/ ) + return False + except ValueError: + # Non-encodable path + return False - def stat(self, *, follow_symlinks=True): + def is_mount(self): """ - Return the result of the stat() system call on this path, like - os.stat() does. + Check if this path is a mount point """ - return os.stat(self, follow_symlinks=follow_symlinks) + return self._flavour.ismount(self) - def owner(self): + def is_symlink(self): """ - Return the login name of the file owner. + Whether this path is a symbolic link. """ try: - import pwd - return pwd.getpwuid(self.stat().st_uid).pw_name - except ImportError: - raise NotImplementedError("Path.owner() is unsupported on this system") + return S_ISLNK(self.lstat().st_mode) + except OSError as e: + if not _ignore_error(e): + raise + # Path doesn't exist + return False + except ValueError: + # Non-encodable path + return False - def group(self): + def is_junction(self): """ - Return the group name of the file gid. + Whether this path is a junction. """ + return self._flavour.isjunction(self) + def is_block_device(self): + """ + Whether this path is a block device. + """ try: - import grp - return grp.getgrgid(self.stat().st_gid).gr_name - except ImportError: - raise NotImplementedError("Path.group() is unsupported on this system") + return S_ISBLK(self.stat().st_mode) + except OSError as e: + if not _ignore_error(e): + raise + # Path doesn't exist or is a broken symlink + # (see http://web.archive.org/web/20200623061726/https://bitbucket.org/pitrou/pathlib/issues/12/ ) + return False + except ValueError: + # Non-encodable path + return False + + def is_char_device(self): + """ + Whether this path is a character device. + """ + try: + return S_ISCHR(self.stat().st_mode) + except OSError as e: + if not _ignore_error(e): + raise + # Path doesn't exist or is a broken symlink + # (see http://web.archive.org/web/20200623061726/https://bitbucket.org/pitrou/pathlib/issues/12/ ) + return False + except ValueError: + # Non-encodable path + return False + + def is_fifo(self): + """ + Whether this path is a FIFO. + """ + try: + return S_ISFIFO(self.stat().st_mode) + except OSError as e: + if not _ignore_error(e): + raise + # Path doesn't exist or is a broken symlink + # (see http://web.archive.org/web/20200623061726/https://bitbucket.org/pitrou/pathlib/issues/12/ ) + return False + except ValueError: + # Non-encodable path + return False + + def is_socket(self): + """ + Whether this path is a socket. + """ + try: + return S_ISSOCK(self.stat().st_mode) + except OSError as e: + if not _ignore_error(e): + raise + # Path doesn't exist or is a broken symlink + # (see http://web.archive.org/web/20200623061726/https://bitbucket.org/pitrou/pathlib/issues/12/ ) + return False + except ValueError: + # Non-encodable path + return False + + def samefile(self, other_path): + """Return whether other_path is the same or not as this file + (as returned by os.path.samefile()). + """ + st = self.stat() + try: + other_st = other_path.stat() + except AttributeError: + other_st = self.with_segments(other_path).stat() + return self._flavour.samestat(st, other_st) def open(self, mode='r', buffering=-1, encoding=None, errors=None, newline=None): @@ -1078,13 +1048,239 @@ class Path(PurePath): with self.open(mode='w', encoding=encoding, errors=errors, newline=newline) as f: return f.write(data) + def iterdir(self): + """Yield path objects of the directory contents. + + The children are yielded in arbitrary order, and the + special entries '.' and '..' are not included. + """ + for name in os.listdir(self): + yield self._make_child_relpath(name) + + def _scandir(self): + # bpo-24132: a future version of pathlib will support subclassing of + # pathlib.Path to customize how the filesystem is accessed. This + # includes scandir(), which is used to implement glob(). + return os.scandir(self) + + def _make_child_relpath(self, name): + path_str = str(self) + tail = self._tail + if tail: + path_str = f'{path_str}{self._flavour.sep}{name}' + elif path_str != '.': + path_str = f'{path_str}{name}' + else: + path_str = name + path = self.with_segments(path_str) + path._str = path_str + path._drv = self.drive + path._root = self.root + path._tail_cached = tail + [name] + return path + + def glob(self, pattern, *, case_sensitive=None): + """Iterate over this subtree and yield all existing files (of any + kind, including directories) matching the given relative pattern. + """ + sys.audit("pathlib.Path.glob", self, pattern) + if not pattern: + raise ValueError("Unacceptable pattern: {!r}".format(pattern)) + drv, root, pattern_parts = self._parse_path(pattern) + if drv or root: + raise NotImplementedError("Non-relative patterns are unsupported") + if pattern[-1] in (self._flavour.sep, self._flavour.altsep): + pattern_parts.append('') + selector = _make_selector(tuple(pattern_parts), self._flavour, case_sensitive) + for p in selector.select_from(self): + yield p + + def rglob(self, pattern, *, case_sensitive=None): + """Recursively yield all existing files (of any kind, including + directories) matching the given relative pattern, anywhere in + this subtree. + """ + sys.audit("pathlib.Path.rglob", self, pattern) + drv, root, pattern_parts = self._parse_path(pattern) + if drv or root: + raise NotImplementedError("Non-relative patterns are unsupported") + if pattern and pattern[-1] in (self._flavour.sep, self._flavour.altsep): + pattern_parts.append('') + selector = _make_selector(("**",) + tuple(pattern_parts), self._flavour, case_sensitive) + for p in selector.select_from(self): + yield p + + def walk(self, top_down=True, on_error=None, follow_symlinks=False): + """Walk the directory tree from this directory, similar to os.walk().""" + sys.audit("pathlib.Path.walk", self, on_error, follow_symlinks) + paths = [self] + + while paths: + path = paths.pop() + if isinstance(path, tuple): + yield path + continue + + # We may not have read permission for self, in which case we can't + # get a list of the files the directory contains. os.walk() + # always suppressed the exception in that instance, rather than + # blow up for a minor reason when (say) a thousand readable + # directories are still left to visit. That logic is copied here. + try: + scandir_it = path._scandir() + except OSError as error: + if on_error is not None: + on_error(error) + continue + + with scandir_it: + dirnames = [] + filenames = [] + for entry in scandir_it: + try: + is_dir = entry.is_dir(follow_symlinks=follow_symlinks) + except OSError: + # Carried over from os.path.isdir(). + is_dir = False + + if is_dir: + dirnames.append(entry.name) + else: + filenames.append(entry.name) + + if top_down: + yield path, dirnames, filenames + else: + paths.append((path, dirnames, filenames)) + + paths += [path._make_child_relpath(d) for d in reversed(dirnames)] + + def __init__(self, *args, **kwargs): + if kwargs: + msg = ("support for supplying keyword arguments to pathlib.PurePath " + "is deprecated and scheduled for removal in Python {remove}") + warnings._deprecated("pathlib.PurePath(**kwargs)", msg, remove=(3, 14)) + super().__init__(*args) + + def __new__(cls, *args, **kwargs): + if cls is Path: + cls = WindowsPath if os.name == 'nt' else PosixPath + return object.__new__(cls) + + def __enter__(self): + # In previous versions of pathlib, __exit__() marked this path as + # closed; subsequent attempts to perform I/O would raise an IOError. + # This functionality was never documented, and had the effect of + # making Path objects mutable, contrary to PEP 428. + # In Python 3.9 __exit__() was made a no-op. + # In Python 3.11 __enter__() began emitting DeprecationWarning. + # In Python 3.13 __enter__() and __exit__() should be removed. + warnings.warn("pathlib.Path.__enter__() is deprecated and scheduled " + "for removal in Python 3.13; Path objects as a context " + "manager is a no-op", + DeprecationWarning, stacklevel=2) + return self + + def __exit__(self, t, v, tb): + pass + + # Public API + + @classmethod + def cwd(cls): + """Return a new path pointing to the current working directory.""" + # We call 'absolute()' rather than using 'os.getcwd()' directly to + # enable users to replace the implementation of 'absolute()' in a + # subclass and benefit from the new behaviour here. This works because + # os.path.abspath('.') == os.getcwd(). + return cls().absolute() + + @classmethod + def home(cls): + """Return a new path pointing to the user's home directory (as + returned by os.path.expanduser('~')). + """ + return cls("~").expanduser() + + def absolute(self): + """Return an absolute version of this path by prepending the current + working directory. No normalization or symlink resolution is performed. + + Use resolve() to get the canonical path to a file. + """ + if self.is_absolute(): + return self + elif self.drive: + # There is a CWD on each drive-letter drive. + cwd = self._flavour.abspath(self.drive) + else: + cwd = os.getcwd() + # Fast path for "empty" paths, e.g. Path("."), Path("") or Path(). + # We pass only one argument to with_segments() to avoid the cost + # of joining, and we exploit the fact that getcwd() returns a + # fully-normalized string by storing it in _str. This is used to + # implement Path.cwd(). + if not self.root and not self._tail: + result = self.with_segments(cwd) + result._str = cwd + return result + return self.with_segments(cwd, self) + + def resolve(self, strict=False): + """ + Make the path absolute, resolving all symlinks on the way and also + normalizing it. + """ + + def check_eloop(e): + winerror = getattr(e, 'winerror', 0) + if e.errno == ELOOP or winerror == _WINERROR_CANT_RESOLVE_FILENAME: + raise RuntimeError("Symlink loop from %r" % e.filename) + + try: + s = self._flavour.realpath(self, strict=strict) + except OSError as e: + check_eloop(e) + raise + p = self.with_segments(s) + + # In non-strict mode, realpath() doesn't raise on symlink loops. + # Ensure we get an exception by calling stat() + if not strict: + try: + p.stat() + except OSError as e: + check_eloop(e) + return p + + def owner(self): + """ + Return the login name of the file owner. + """ + try: + import pwd + return pwd.getpwuid(self.stat().st_uid).pw_name + except ImportError: + raise NotImplementedError("Path.owner() is unsupported on this system") + + def group(self): + """ + Return the group name of the file gid. + """ + + try: + import grp + return grp.getgrgid(self.stat().st_gid).gr_name + except ImportError: + raise NotImplementedError("Path.group() is unsupported on this system") + def readlink(self): """ Return the path to which the symbolic link points. """ if not hasattr(os, "readlink"): raise NotImplementedError("os.readlink() not available on this system") - return self._from_parts((os.readlink(self),)) + return self.with_segments(os.readlink(self)) def touch(self, mode=0o666, exist_ok=True): """ @@ -1155,13 +1351,6 @@ class Path(PurePath): """ os.rmdir(self) - def lstat(self): - """ - Like stat(), except if the path points to a symlink, the symlink's - status information is returned, rather than its target's. - """ - return self.stat(follow_symlinks=False) - def rename(self, target): """ Rename this path to the target path. @@ -1173,7 +1362,7 @@ class Path(PurePath): Returns the new Path instance pointing to the target path. """ os.rename(self, target) - return self.__class__(target) + return self.with_segments(target) def replace(self, target): """ @@ -1186,7 +1375,7 @@ class Path(PurePath): Returns the new Path instance pointing to the target path. """ os.replace(self, target) - return self.__class__(target) + return self.with_segments(target) def symlink_to(self, target, target_is_directory=False): """ @@ -1207,183 +1396,17 @@ class Path(PurePath): raise NotImplementedError("os.link() not available on this system") os.link(target, self) - def link_to(self, target): - """ - Make the target path a hard link pointing to this path. - - Note this function does not make this path a hard link to *target*, - despite the implication of the function and argument names. The order - of arguments (target, link) is the reverse of Path.symlink_to, but - matches that of os.link. - - Deprecated since Python 3.10 and scheduled for removal in Python 3.12. - Use `hardlink_to()` instead. - """ - warnings.warn("pathlib.Path.link_to() is deprecated and is scheduled " - "for removal in Python 3.12. " - "Use pathlib.Path.hardlink_to() instead.", - DeprecationWarning, stacklevel=2) - self.__class__(target).hardlink_to(self) - - # Convenience functions for querying the stat results - - def exists(self): - """ - Whether this path exists. - """ - try: - self.stat() - except OSError as e: - if not _ignore_error(e): - raise - return False - except ValueError: - # Non-encodable path - return False - return True - - def is_dir(self): - """ - Whether this path is a directory. - """ - try: - return S_ISDIR(self.stat().st_mode) - except OSError as e: - if not _ignore_error(e): - raise - # Path doesn't exist or is a broken symlink - # (see http://web.archive.org/web/20200623061726/https://bitbucket.org/pitrou/pathlib/issues/12/ ) - return False - except ValueError: - # Non-encodable path - return False - - def is_file(self): - """ - Whether this path is a regular file (also True for symlinks pointing - to regular files). - """ - try: - return S_ISREG(self.stat().st_mode) - except OSError as e: - if not _ignore_error(e): - raise - # Path doesn't exist or is a broken symlink - # (see http://web.archive.org/web/20200623061726/https://bitbucket.org/pitrou/pathlib/issues/12/ ) - return False - except ValueError: - # Non-encodable path - return False - - def is_mount(self): - """ - Check if this path is a POSIX mount point - """ - # Need to exist and be a dir - if not self.exists() or not self.is_dir(): - return False - - try: - parent_dev = self.parent.stat().st_dev - except OSError: - return False - - dev = self.stat().st_dev - if dev != parent_dev: - return True - ino = self.stat().st_ino - parent_ino = self.parent.stat().st_ino - return ino == parent_ino - - def is_symlink(self): - """ - Whether this path is a symbolic link. - """ - try: - return S_ISLNK(self.lstat().st_mode) - except OSError as e: - if not _ignore_error(e): - raise - # Path doesn't exist - return False - except ValueError: - # Non-encodable path - return False - - def is_block_device(self): - """ - Whether this path is a block device. - """ - try: - return S_ISBLK(self.stat().st_mode) - except OSError as e: - if not _ignore_error(e): - raise - # Path doesn't exist or is a broken symlink - # (see http://web.archive.org/web/20200623061726/https://bitbucket.org/pitrou/pathlib/issues/12/ ) - return False - except ValueError: - # Non-encodable path - return False - - def is_char_device(self): - """ - Whether this path is a character device. - """ - try: - return S_ISCHR(self.stat().st_mode) - except OSError as e: - if not _ignore_error(e): - raise - # Path doesn't exist or is a broken symlink - # (see http://web.archive.org/web/20200623061726/https://bitbucket.org/pitrou/pathlib/issues/12/ ) - return False - except ValueError: - # Non-encodable path - return False - - def is_fifo(self): - """ - Whether this path is a FIFO. - """ - try: - return S_ISFIFO(self.stat().st_mode) - except OSError as e: - if not _ignore_error(e): - raise - # Path doesn't exist or is a broken symlink - # (see http://web.archive.org/web/20200623061726/https://bitbucket.org/pitrou/pathlib/issues/12/ ) - return False - except ValueError: - # Non-encodable path - return False - - def is_socket(self): - """ - Whether this path is a socket. - """ - try: - return S_ISSOCK(self.stat().st_mode) - except OSError as e: - if not _ignore_error(e): - raise - # Path doesn't exist or is a broken symlink - # (see http://web.archive.org/web/20200623061726/https://bitbucket.org/pitrou/pathlib/issues/12/ ) - return False - except ValueError: - # Non-encodable path - return False - def expanduser(self): """ Return a new path with expanded ~ and ~user constructs (as returned by os.path.expanduser) """ - if (not (self._drv or self._root) and - self._parts and self._parts[0][:1] == '~'): - homedir = os.path.expanduser(self._parts[0]) + if (not (self.drive or self.root) and + self._tail and self._tail[0][:1] == '~'): + homedir = self._flavour.expanduser(self._tail[0]) if homedir[:1] == "~": raise RuntimeError("Could not determine home directory.") - return self._from_parts([homedir] + self._parts[1:]) + drv, root, tail = self._parse_path(homedir) + return self._from_parsed_parts(drv, root, tail + self._tail[1:]) return self @@ -1395,6 +1418,11 @@ class PosixPath(Path, PurePosixPath): """ __slots__ = () + if os.name == 'nt': + def __new__(cls, *args, **kwargs): + raise NotImplementedError( + f"cannot instantiate {cls.__name__!r} on your system") + class WindowsPath(Path, PureWindowsPath): """Path subclass for Windows systems. @@ -1402,5 +1430,7 @@ class WindowsPath(Path, PureWindowsPath): """ __slots__ = () - def is_mount(self): - raise NotImplementedError("Path.is_mount() is unsupported on this system") + if os.name != 'nt': + def __new__(cls, *args, **kwargs): + raise NotImplementedError( + f"cannot instantiate {cls.__name__!r} on your system") diff --git a/Lib/pdb.py b/Lib/pdb.py index 411ce531..6b6feac1 100755 --- a/Lib/pdb.py +++ b/Lib/pdb.py @@ -107,15 +107,6 @@ def find_function(funcname, filename): return funcname, filename, lineno return None -def getsourcelines(obj): - lines, lineno = inspect.findsource(obj) - if inspect.isframe(obj) and obj.f_globals is obj.f_locals: - # must be a module frame: do not try to cut a block out of it - return lines, 1 - elif inspect.ismodule(obj): - return lines, 1 - return inspect.getblock(lines[lineno:]), lineno+1 - def lasti2lineno(code, lasti): linestarts = list(dis.findlinestarts(code)) linestarts.reverse() @@ -163,7 +154,7 @@ class _ScriptTarget(str): @property def code(self): - with io.open(self) as fp: + with io.open_code(self) as fp: return f"exec(compile({fp.read()!r}, {self!r}, 'exec'))" @@ -279,6 +270,8 @@ class Pdb(bdb.Bdb, cmd.Cmd): self.lineno = None self.stack = [] self.curindex = 0 + if hasattr(self, 'curframe') and self.curframe: + self.curframe.f_globals.pop('__pdb_convenience_variables', None) self.curframe = None self.tb_lineno.clear() @@ -297,6 +290,7 @@ class Pdb(bdb.Bdb, cmd.Cmd): # locals whenever the .f_locals accessor is called, so we # cache it here to ensure that modifications are not overwritten. self.curframe_locals = self.curframe.f_locals + self.set_convenience_variable(self.curframe, '_frame', self.curframe) return self.execRcLines() # Can be executed earlier than 'setup' if desired @@ -368,6 +362,7 @@ class Pdb(bdb.Bdb, cmd.Cmd): if self._wait_for_mainpyfile: return frame.f_locals['__return__'] = return_value + self.set_convenience_variable(frame, '_retval', return_value) self.message('--Return--') self.interaction(frame, None) @@ -378,6 +373,7 @@ class Pdb(bdb.Bdb, cmd.Cmd): return exc_type, exc_value, exc_traceback = exc_info frame.f_locals['__exception__'] = exc_type, exc_value + self.set_convenience_variable(frame, '_exception', exc_value) # An 'Internal StopIteration' exception is an exception debug event # issued by the interpreter when handling a subgenerator run with @@ -386,8 +382,7 @@ class Pdb(bdb.Bdb, cmd.Cmd): # stop when the debuggee is returning from such generators. prefix = 'Internal ' if (not exc_traceback and exc_type is StopIteration) else '' - self.message('%s%s' % (prefix, - traceback.format_exception_only(exc_type, exc_value)[-1].strip())) + self.message('%s%s' % (prefix, self._format_exc(exc_value))) self.interaction(frame, exc_traceback) # General interaction function @@ -404,6 +399,7 @@ class Pdb(bdb.Bdb, cmd.Cmd): self.message('--KeyboardInterrupt--') # Called before loop, handles display expressions + # Set up convenience variable containers def preloop(self): displaying = self.displaying.get(self.curframe) if displaying: @@ -444,7 +440,7 @@ class Pdb(bdb.Bdb, cmd.Cmd): self.message(repr(obj)) def default(self, line): - if line[:1] == '!': line = line[1:] + if line[:1] == '!': line = line[1:].strip() locals = self.curframe_locals globals = self.curframe.f_globals try: @@ -487,6 +483,9 @@ class Pdb(bdb.Bdb, cmd.Cmd): next = line[marker+2:].lstrip() self.cmdqueue.append(next) line = line[:marker].rstrip() + + # Replace all the convenience variables + line = re.sub(r'\$([a-zA-Z_][a-zA-Z0-9_]*)', r'__pdb_convenience_variables["\1"]', line) return line def onecmd(self, line): @@ -537,6 +536,13 @@ class Pdb(bdb.Bdb, cmd.Cmd): def error(self, msg): print('***', msg, file=self.stdout) + # convenience variables + + def set_convenience_variable(self, frame, name, value): + if '__pdb_convenience_variables' not in frame.f_globals: + frame.f_globals['__pdb_convenience_variables'] = {} + frame.f_globals['__pdb_convenience_variables'][name] = value + # Generic completion functions. Individual complete_foo methods can be # assigned below to one of these functions. @@ -596,7 +602,7 @@ class Pdb(bdb.Bdb, cmd.Cmd): # Return true to exit from the command loop def do_commands(self, arg): - """commands [bpnumber] + """(Pdb) commands [bpnumber] (com) ... (com) end (Pdb) @@ -682,6 +688,7 @@ class Pdb(bdb.Bdb, cmd.Cmd): def do_break(self, arg, temporary = 0): """b(reak) [ ([filename:]lineno | function) [, condition] ] + Without argument, list all breaks. With a line number argument, set a break at this line in the @@ -711,6 +718,9 @@ class Pdb(bdb.Bdb, cmd.Cmd): if comma > 0: # parse stuff after comma: "condition" cond = arg[comma+1:].lstrip() + if err := self._compile_error_message(cond): + self.error('Invalid condition %s: %r' % (cond, err)) + return arg = arg[:comma].rstrip() # parse stuff before comma: [filename:]lineno | function colon = arg.rfind(':') @@ -787,6 +797,7 @@ class Pdb(bdb.Bdb, cmd.Cmd): def do_tbreak(self, arg): """tbreak [ ([filename:]lineno | function) [, condition] ] + Same arguments as break, but sets a temporary breakpoint: it is automatically deleted when first hit. """ @@ -851,6 +862,7 @@ class Pdb(bdb.Bdb, cmd.Cmd): def do_enable(self, arg): """enable bpnumber [bpnumber ...] + Enables the breakpoints given as a space separated list of breakpoint numbers. """ @@ -868,6 +880,7 @@ class Pdb(bdb.Bdb, cmd.Cmd): def do_disable(self, arg): """disable bpnumber [bpnumber ...] + Disables the breakpoints given as a space separated list of breakpoint numbers. Disabling a breakpoint means it cannot cause the program to stop execution, but unlike clearing a @@ -888,6 +901,7 @@ class Pdb(bdb.Bdb, cmd.Cmd): def do_condition(self, arg): """condition bpnumber [condition] + Set a new condition for the breakpoint, an expression which must evaluate to true before the breakpoint is honored. If condition is absent, any existing condition is removed; i.e., @@ -896,6 +910,9 @@ class Pdb(bdb.Bdb, cmd.Cmd): args = arg.split(' ', 1) try: cond = args[1] + if err := self._compile_error_message(cond): + self.error('Invalid condition %s: %r' % (cond, err)) + return except IndexError: cond = None try: @@ -915,6 +932,7 @@ class Pdb(bdb.Bdb, cmd.Cmd): def do_ignore(self, arg): """ignore bpnumber [count] + Set the ignore count for the given breakpoint number. If count is omitted, the ignore count is set to 0. A breakpoint becomes active when the ignore count is zero. When non-zero, @@ -949,7 +967,8 @@ class Pdb(bdb.Bdb, cmd.Cmd): complete_ignore = _complete_bpnumber def do_clear(self, arg): - """cl(ear) filename:lineno\ncl(ear) [bpnumber [bpnumber...]] + """cl(ear) [filename:lineno | bpnumber ...] + With a space separated list of breakpoint numbers, clear those breakpoints. Without argument, clear all breaks (but first ask confirmation). With a filename:lineno argument, @@ -1001,6 +1020,7 @@ class Pdb(bdb.Bdb, cmd.Cmd): def do_where(self, arg): """w(here) + Print a stack trace, with the most recent frame at the bottom. An arrow indicates the "current frame", which determines the context of most commands. 'bt' is an alias for this command. @@ -1014,11 +1034,13 @@ class Pdb(bdb.Bdb, cmd.Cmd): self.curindex = number self.curframe = self.stack[self.curindex][0] self.curframe_locals = self.curframe.f_locals + self.set_convenience_variable(self.curframe, '_frame', self.curframe) self.print_stack_entry(self.stack[self.curindex]) self.lineno = None def do_up(self, arg): """u(p) [count] + Move the current frame count (default one) levels up in the stack trace (to an older frame). """ @@ -1039,6 +1061,7 @@ class Pdb(bdb.Bdb, cmd.Cmd): def do_down(self, arg): """d(own) [count] + Move the current frame count (default one) levels down in the stack trace (to a newer frame). """ @@ -1059,6 +1082,7 @@ class Pdb(bdb.Bdb, cmd.Cmd): def do_until(self, arg): """unt(il) [lineno] + Without argument, continue execution until the line with a number greater than the current one is reached. With a line number, continue execution until a line with a number greater @@ -1083,6 +1107,7 @@ class Pdb(bdb.Bdb, cmd.Cmd): def do_step(self, arg): """s(tep) + Execute the current line, stop at the first possible occasion (either in a function that is called or in the current function). @@ -1093,6 +1118,7 @@ class Pdb(bdb.Bdb, cmd.Cmd): def do_next(self, arg): """n(ext) + Continue execution until the next line in the current function is reached or it returns. """ @@ -1102,6 +1128,7 @@ class Pdb(bdb.Bdb, cmd.Cmd): def do_run(self, arg): """run [args...] + Restart the debugged python program. If a string is supplied it is split with "shlex", and the result is used as the new sys.argv. History, breakpoints, actions and debugger options @@ -1123,6 +1150,7 @@ class Pdb(bdb.Bdb, cmd.Cmd): def do_return(self, arg): """r(eturn) + Continue execution until the current function returns. """ self.set_return(self.curframe) @@ -1131,6 +1159,7 @@ class Pdb(bdb.Bdb, cmd.Cmd): def do_continue(self, arg): """c(ont(inue)) + Continue execution, only stop when a breakpoint is encountered. """ if not self.nosigint: @@ -1149,6 +1178,7 @@ class Pdb(bdb.Bdb, cmd.Cmd): def do_jump(self, arg): """j(ump) lineno + Set the next line that will be executed. Only available in the bottom-most frame. This lets you jump back and execute code again, or jump forward to skip code that you don't want @@ -1178,6 +1208,7 @@ class Pdb(bdb.Bdb, cmd.Cmd): def do_debug(self, arg): """debug code + Enter a recursive debugger that steps through the code argument (which is an arbitrary expression or statement to be executed in the current environment). @@ -1199,7 +1230,8 @@ class Pdb(bdb.Bdb, cmd.Cmd): complete_debug = _complete_expression def do_quit(self, arg): - """q(uit)\nexit + """q(uit) | exit + Quit from the debugger. The program being executed is aborted. """ self._user_requested_quit = True @@ -1211,6 +1243,7 @@ class Pdb(bdb.Bdb, cmd.Cmd): def do_EOF(self, arg): """EOF + Handles the receipt of EOF as a command. """ self.message('') @@ -1220,6 +1253,7 @@ class Pdb(bdb.Bdb, cmd.Cmd): def do_args(self, arg): """a(rgs) + Print the argument list of the current function. """ co = self.curframe.f_code @@ -1237,6 +1271,7 @@ class Pdb(bdb.Bdb, cmd.Cmd): def do_retval(self, arg): """retval + Print the return value for the last return of a function. """ if '__return__' in self.curframe_locals: @@ -1258,14 +1293,12 @@ class Pdb(bdb.Bdb, cmd.Cmd): return eval(arg, self.curframe.f_globals, self.curframe_locals) else: return eval(arg, frame.f_globals, frame.f_locals) - except: - exc_info = sys.exc_info()[:2] - err = traceback.format_exception_only(*exc_info)[-1].strip() - return _rstr('** raised %s **' % err) + except BaseException as exc: + return _rstr('** raised %s **' % self._format_exc(exc)) def _error_exc(self): - exc_info = sys.exc_info()[:2] - self.error(traceback.format_exception_only(*exc_info)[-1].strip()) + exc = sys.exception() + self.error(self._format_exc(exc)) def _msg_val_func(self, arg, func): try: @@ -1279,12 +1312,14 @@ class Pdb(bdb.Bdb, cmd.Cmd): def do_p(self, arg): """p expression + Print the value of the expression. """ self._msg_val_func(arg, repr) def do_pp(self, arg): """pp expression + Pretty-print the value of the expression. """ self._msg_val_func(arg, pprint.pformat) @@ -1294,7 +1329,7 @@ class Pdb(bdb.Bdb, cmd.Cmd): complete_pp = _complete_expression def do_list(self, arg): - """l(ist) [first [,last] | .] + """l(ist) [first[, last] | .] List source code for the current file. Without arguments, list 11 lines around the current line or continue the previous @@ -1351,13 +1386,14 @@ class Pdb(bdb.Bdb, cmd.Cmd): do_l = do_list def do_longlist(self, arg): - """longlist | ll + """ll | longlist + List the whole source code for the current function or frame. """ filename = self.curframe.f_code.co_filename breaklist = self.get_file_breaks(filename) try: - lines, lineno = getsourcelines(self.curframe) + lines, lineno = self._getsourcelines(self.curframe) except OSError as err: self.error(err) return @@ -1366,6 +1402,7 @@ class Pdb(bdb.Bdb, cmd.Cmd): def do_source(self, arg): """source expression + Try to get source code for the given object and display it. """ try: @@ -1373,7 +1410,7 @@ class Pdb(bdb.Bdb, cmd.Cmd): except: return try: - lines, lineno = getsourcelines(obj) + lines, lineno = self._getsourcelines(obj) except (OSError, TypeError) as err: self.error(err) return @@ -1403,7 +1440,8 @@ class Pdb(bdb.Bdb, cmd.Cmd): self.message(s + '\t' + line.rstrip()) def do_whatis(self, arg): - """whatis arg + """whatis expression + Print the type of the argument. """ try: @@ -1446,13 +1484,19 @@ class Pdb(bdb.Bdb, cmd.Cmd): Without expression, list all display expressions for the current frame. """ if not arg: - self.message('Currently displaying:') - for item in self.displaying.get(self.curframe, {}).items(): - self.message('%s: %r' % item) + if self.displaying: + self.message('Currently displaying:') + for item in self.displaying.get(self.curframe, {}).items(): + self.message('%s: %r' % item) + else: + self.message('No expression is being displayed') else: - val = self._getval_except(arg) - self.displaying.setdefault(self.curframe, {})[arg] = val - self.message('display %s: %r' % (arg, val)) + if err := self._compile_error_message(arg): + self.error('Unable to display %s: %r' % (arg, err)) + else: + val = self._getval_except(arg) + self.displaying.setdefault(self.curframe, {})[arg] = val + self.message('display %s: %r' % (arg, val)) complete_display = _complete_expression @@ -1485,7 +1529,8 @@ class Pdb(bdb.Bdb, cmd.Cmd): code.interact("*interactive*", local=ns) def do_alias(self, arg): - """alias [name [command [parameter parameter ...] ]] + """alias [name [command]] + Create an alias called 'name' that executes 'command'. The command must *not* be enclosed in quotes. Replaceable parameters can be indicated by %1, %2, and so on, while %* is @@ -1521,6 +1566,7 @@ class Pdb(bdb.Bdb, cmd.Cmd): def do_unalias(self, arg): """unalias name + Delete the specified alias. """ args = arg.split() @@ -1563,6 +1609,7 @@ class Pdb(bdb.Bdb, cmd.Cmd): def do_help(self, arg): """h(elp) + Without argument, print the list of available commands. With a command name as argument, print help about that command. "help pdb" shows the full pdb documentation. @@ -1586,17 +1633,21 @@ class Pdb(bdb.Bdb, cmd.Cmd): if command.__doc__ is None: self.error('No help for %r; __doc__ string missing' % arg) return - self.message(command.__doc__.rstrip()) + self.message(self._help_message_from_doc(command.__doc__)) do_h = do_help def help_exec(self): """(!) statement + Execute the (one-line) statement in the context of the current stack frame. The exclamation point can be omitted unless the - first word of the statement resembles a debugger command. To - assign to a global variable you must always prefix the command - with a 'global' command, e.g.: + first word of the statement resembles a debugger command, e.g.: + (Pdb) ! n=42 + (Pdb) + + To assign to a global variable you must always prefix the command with + a 'global' command, e.g.: (Pdb) global list_options; list_options = ['-l'] (Pdb) """ @@ -1651,6 +1702,46 @@ class Pdb(bdb.Bdb, cmd.Cmd): self.run(target.code) + def _format_exc(self, exc: BaseException): + return traceback.format_exception_only(exc)[-1].strip() + + def _compile_error_message(self, expr): + """Return the error message as string if compiling `expr` fails.""" + try: + compile(expr, "<stdin>", "eval") + except SyntaxError as exc: + return _rstr(self._format_exc(exc)) + return "" + + def _getsourcelines(self, obj): + # GH-103319 + # inspect.getsourcelines() returns lineno = 0 for + # module-level frame which breaks our code print line number + # This method should be replaced by inspect.getsourcelines(obj) + # once this bug is fixed in inspect + lines, lineno = inspect.getsourcelines(obj) + lineno = max(1, lineno) + return lines, lineno + + def _help_message_from_doc(self, doc): + lines = [line.strip() for line in doc.rstrip().splitlines()] + if not lines: + return "No help message found." + if "" in lines: + usage_end = lines.index("") + else: + usage_end = 1 + formatted = [] + indent = " " * len(self.prompt) + for i, line in enumerate(lines): + if i == 0: + prefix = "Usage: " + elif i < usage_end: + prefix = " " + else: + prefix = "" + formatted.append(indent + prefix + line) + return "\n".join(formatted) # Collect all command help into docstring, if not run with -OO @@ -1674,9 +1765,27 @@ if __doc__ is not None: # Simplified interface def run(statement, globals=None, locals=None): + """Execute the *statement* (given as a string or a code object) + under debugger control. + + The debugger prompt appears before any code is executed; you can set + breakpoints and type continue, or you can step through the statement + using step or next. + + The optional *globals* and *locals* arguments specify the + environment in which the code is executed; by default the + dictionary of the module __main__ is used (see the explanation of + the built-in exec() or eval() functions.). + """ Pdb().run(statement, globals, locals) def runeval(expression, globals=None, locals=None): + """Evaluate the *expression* (given as a string or a code object) + under debugger control. + + When runeval() returns, it returns the value of the expression. + Otherwise this function is similar to run(). + """ return Pdb().runeval(expression, globals, locals) def runctx(statement, globals, locals): @@ -1684,9 +1793,23 @@ def runctx(statement, globals, locals): run(statement, globals, locals) def runcall(*args, **kwds): + """Call the function (a function or method object, not a string) + with the given arguments. + + When runcall() returns, it returns whatever the function call + returned. The debugger prompt appears as soon as the function is + entered. + """ return Pdb().runcall(*args, **kwds) def set_trace(*, header=None): + """Enter the debugger at the calling stack frame. + + This is useful to hard-code a breakpoint at a given point in a + program, even if the code is not otherwise being debugged (e.g. when + an assertion fails). If given, *header* is printed to the console + just before debugging begins. + """ pdb = Pdb() if header is not None: pdb.message(header) @@ -1695,11 +1818,18 @@ def set_trace(*, header=None): # Post-Mortem interface def post_mortem(t=None): + """Enter post-mortem debugging of the given *traceback* object. + + If no traceback is given, it uses the one of the exception that is + currently being handled (an exception must be being handled if the + default is to be used). + """ # handling the default if t is None: - # sys.exc_info() returns (type, value, traceback) if an exception is - # being handled, otherwise it returns None - t = sys.exc_info()[2] + exc = sys.exception() + if exc is not None: + t = exc.__traceback__ + if t is None: raise ValueError("A valid traceback must be passed if no " "exception is being handled") @@ -1709,7 +1839,12 @@ def post_mortem(t=None): p.interaction(None, t) def pm(): - post_mortem(sys.last_traceback) + """Enter post-mortem debugging of the traceback found in sys.last_traceback.""" + if hasattr(sys, 'last_exc'): + tb = sys.last_exc.__traceback__ + else: + tb = sys.last_traceback + post_mortem(tb) # Main program for testing @@ -1778,18 +1913,18 @@ def main(): except Restart: print("Restarting", target, "with arguments:") print("\t" + " ".join(sys.argv[1:])) - except SystemExit: + except SystemExit as e: # In most cases SystemExit does not warrant a post-mortem session. print("The program exited via sys.exit(). Exit status:", end=' ') - print(sys.exc_info()[1]) + print(e) except SyntaxError: traceback.print_exc() sys.exit(1) - except: + except BaseException as e: traceback.print_exc() print("Uncaught exception. Entering post mortem debugging") print("Running 'cont' or 'step' will restart the program") - t = sys.exc_info()[2] + t = e.__traceback__ pdb.interaction(None, t) print("Post mortem debugger finished. The " + target + " will be restarted") diff --git a/Lib/pickle.py b/Lib/pickle.py index f027e043..fe86f80f 100644 --- a/Lib/pickle.py +++ b/Lib/pickle.py @@ -98,12 +98,6 @@ class _Stop(Exception): def __init__(self, value): self.value = value -# Jython has PyStringMap; it's a dict subclass with string keys -try: - from org.python.core import PyStringMap -except ImportError: - PyStringMap = None - # Pickle opcodes. See pickletools.py for extensive docs. The listing # here is in kind-of alphabetical order of 1-character pickle code. # pickletools groups them by purpose. @@ -972,8 +966,6 @@ class _Pickler: self._batch_setitems(obj.items()) dispatch[dict] = save_dict - if PyStringMap is not None: - dispatch[PyStringMap] = save_dict def _batch_setitems(self, items): # Helper to batch up SETITEMS sequences; proto >= 1 only @@ -1489,7 +1481,7 @@ class _Unpickler: value = klass(*args) except TypeError as err: raise TypeError("in constructor for %s: %s" % - (klass.__name__, str(err)), sys.exc_info()[2]) + (klass.__name__, str(err)), err.__traceback__) else: value = klass.__new__(klass) self.append(value) diff --git a/Lib/pkgutil.py b/Lib/pkgutil.py index bdebfd2f..dccbec52 100644 --- a/Lib/pkgutil.py +++ b/Lib/pkgutil.py @@ -14,7 +14,7 @@ import warnings __all__ = [ 'get_importer', 'iter_importers', 'get_loader', 'find_loader', 'walk_packages', 'iter_modules', 'get_data', - 'ImpImporter', 'ImpLoader', 'read_code', 'extend_path', + 'read_code', 'extend_path', 'ModuleInfo', ] @@ -23,20 +23,6 @@ ModuleInfo = namedtuple('ModuleInfo', 'module_finder name ispkg') ModuleInfo.__doc__ = 'A namedtuple with minimal info about a module.' -def _get_spec(finder, name): - """Return the finder-specific module spec.""" - # Works with legacy finders. - try: - find_spec = finder.find_spec - except AttributeError: - loader = finder.find_module(name) - if loader is None: - return None - return importlib.util.spec_from_loader(name, loader) - else: - return find_spec(name) - - def read_code(stream): # This helper is needed in order for the PEP 302 emulation to # correctly handle compiled files @@ -185,187 +171,6 @@ iter_importer_modules.register( importlib.machinery.FileFinder, _iter_file_finder_modules) -def _import_imp(): - global imp - with warnings.catch_warnings(): - warnings.simplefilter('ignore', DeprecationWarning) - imp = importlib.import_module('imp') - -class ImpImporter: - """PEP 302 Finder that wraps Python's "classic" import algorithm - - ImpImporter(dirname) produces a PEP 302 finder that searches that - directory. ImpImporter(None) produces a PEP 302 finder that searches - the current sys.path, plus any modules that are frozen or built-in. - - Note that ImpImporter does not currently support being used by placement - on sys.meta_path. - """ - - def __init__(self, path=None): - global imp - warnings.warn("This emulation is deprecated and slated for removal " - "in Python 3.12; use 'importlib' instead", - DeprecationWarning) - _import_imp() - self.path = path - - def find_module(self, fullname, path=None): - # Note: we ignore 'path' argument since it is only used via meta_path - subname = fullname.split(".")[-1] - if subname != fullname and self.path is None: - return None - if self.path is None: - path = None - else: - path = [os.path.realpath(self.path)] - try: - file, filename, etc = imp.find_module(subname, path) - except ImportError: - return None - return ImpLoader(fullname, file, filename, etc) - - def iter_modules(self, prefix=''): - if self.path is None or not os.path.isdir(self.path): - return - - yielded = {} - import inspect - try: - filenames = os.listdir(self.path) - except OSError: - # ignore unreadable directories like import does - filenames = [] - filenames.sort() # handle packages before same-named modules - - for fn in filenames: - modname = inspect.getmodulename(fn) - if modname=='__init__' or modname in yielded: - continue - - path = os.path.join(self.path, fn) - ispkg = False - - if not modname and os.path.isdir(path) and '.' not in fn: - modname = fn - try: - dircontents = os.listdir(path) - except OSError: - # ignore unreadable directories like import does - dircontents = [] - for fn in dircontents: - subname = inspect.getmodulename(fn) - if subname=='__init__': - ispkg = True - break - else: - continue # not a package - - if modname and '.' not in modname: - yielded[modname] = 1 - yield prefix + modname, ispkg - - -class ImpLoader: - """PEP 302 Loader that wraps Python's "classic" import algorithm - """ - code = source = None - - def __init__(self, fullname, file, filename, etc): - warnings.warn("This emulation is deprecated and slated for removal in " - "Python 3.12; use 'importlib' instead", - DeprecationWarning) - _import_imp() - self.file = file - self.filename = filename - self.fullname = fullname - self.etc = etc - - def load_module(self, fullname): - self._reopen() - try: - mod = imp.load_module(fullname, self.file, self.filename, self.etc) - finally: - if self.file: - self.file.close() - # Note: we don't set __loader__ because we want the module to look - # normal; i.e. this is just a wrapper for standard import machinery - return mod - - def get_data(self, pathname): - with open(pathname, "rb") as file: - return file.read() - - def _reopen(self): - if self.file and self.file.closed: - mod_type = self.etc[2] - if mod_type==imp.PY_SOURCE: - self.file = open(self.filename, 'r') - elif mod_type in (imp.PY_COMPILED, imp.C_EXTENSION): - self.file = open(self.filename, 'rb') - - def _fix_name(self, fullname): - if fullname is None: - fullname = self.fullname - elif fullname != self.fullname: - raise ImportError("Loader for module %s cannot handle " - "module %s" % (self.fullname, fullname)) - return fullname - - def is_package(self, fullname): - fullname = self._fix_name(fullname) - return self.etc[2]==imp.PKG_DIRECTORY - - def get_code(self, fullname=None): - fullname = self._fix_name(fullname) - if self.code is None: - mod_type = self.etc[2] - if mod_type==imp.PY_SOURCE: - source = self.get_source(fullname) - self.code = compile(source, self.filename, 'exec') - elif mod_type==imp.PY_COMPILED: - self._reopen() - try: - self.code = read_code(self.file) - finally: - self.file.close() - elif mod_type==imp.PKG_DIRECTORY: - self.code = self._get_delegate().get_code() - return self.code - - def get_source(self, fullname=None): - fullname = self._fix_name(fullname) - if self.source is None: - mod_type = self.etc[2] - if mod_type==imp.PY_SOURCE: - self._reopen() - try: - self.source = self.file.read() - finally: - self.file.close() - elif mod_type==imp.PY_COMPILED: - if os.path.exists(self.filename[:-1]): - with open(self.filename[:-1], 'r') as f: - self.source = f.read() - elif mod_type==imp.PKG_DIRECTORY: - self.source = self._get_delegate().get_source() - return self.source - - def _get_delegate(self): - finder = ImpImporter(self.filename) - spec = _get_spec(finder, '__init__') - return spec.loader - - def get_filename(self, fullname=None): - fullname = self._fix_name(fullname) - mod_type = self.etc[2] - if mod_type==imp.PKG_DIRECTORY: - return self._get_delegate().get_filename() - elif mod_type in (imp.PY_SOURCE, imp.PY_COMPILED, imp.C_EXTENSION): - return self.filename - return None - - try: import zipimport from zipimport import zipimporter @@ -465,6 +270,10 @@ def get_loader(module_or_name): If the named module is not already imported, its containing package (if any) is imported, in order to establish the package __path__. """ + warnings._deprecated("pkgutil.get_loader", + f"{warnings._DEPRECATED_MSG}; " + "use importlib.util.find_spec() instead", + remove=(3, 14)) if module_or_name in sys.modules: module_or_name = sys.modules[module_or_name] if module_or_name is None: @@ -489,6 +298,10 @@ def find_loader(fullname): importlib.util.find_spec that converts most failures to ImportError and only returns the loader rather than the full spec """ + warnings._deprecated("pkgutil.find_loader", + f"{warnings._DEPRECATED_MSG}; " + "use importlib.util.find_spec() instead", + remove=(3, 14)) if fullname.startswith('.'): msg = "Relative module name {!r} not supported".format(fullname) raise ImportError(msg) @@ -511,10 +324,10 @@ def extend_path(path, name): from pkgutil import extend_path __path__ = extend_path(__path__, __name__) - This will add to the package's __path__ all subdirectories of - directories on sys.path named after the package. This is useful - if one wants to distribute different parts of a single logical - package as multiple directories. + For each directory on sys.path that has a subdirectory that + matches the package name, add the subdirectory to the package's + __path__. This is useful if one wants to distribute different + parts of a single logical package as multiple directories. It also looks for *.pkg files beginning where * matches the name argument. This feature is similar to *.pth files (see site.py), diff --git a/Lib/platform.py b/Lib/platform.py index 9b9d88bf..7bb22208 100755 --- a/Lib/platform.py +++ b/Lib/platform.py @@ -136,11 +136,11 @@ _ver_stages = { 'pl': 200, 'p': 200, } -_component_re = re.compile(r'([0-9]+|[._+-])') def _comparable_version(version): + component_re = re.compile(r'([0-9]+|[._+-])') result = [] - for v in _component_re.split(version): + for v in component_re.split(version): if v not in '._+-': try: v = int(v, 10) @@ -152,11 +152,6 @@ def _comparable_version(version): ### Platform specific APIs -_libc_search = re.compile(b'(__libc_init)' - b'|' - b'(GLIBC_([0-9.]+))' - b'|' - br'(libc(_\w+)?\.so(?:\.(\d[0-9.]*))?)', re.ASCII) def libc_ver(executable=None, lib='', version='', chunksize=16384): @@ -190,6 +185,12 @@ def libc_ver(executable=None, lib='', version='', chunksize=16384): # sys.executable is not set. return lib, version + libc_search = re.compile(b'(__libc_init)' + b'|' + b'(GLIBC_([0-9.]+))' + b'|' + br'(libc(_\w+)?\.so(?:\.(\d[0-9.]*))?)', re.ASCII) + V = _comparable_version # We use os.path.realpath() # here to work around problems with Cygwin not being @@ -200,7 +201,7 @@ def libc_ver(executable=None, lib='', version='', chunksize=16384): pos = 0 while pos < len(binary): if b'libc' in binary or b'GLIBC' in binary: - m = _libc_search.search(binary, pos) + m = libc_search.search(binary, pos) else: m = None if not m or m.end() == len(binary): @@ -247,9 +248,6 @@ def _norm_version(version, build=''): version = '.'.join(strings[:3]) return version -_ver_output = re.compile(r'(?:([\w ]+) ([\w.]+) ' - r'.*' - r'\[.* ([\d.]+)\])') # Examples of VER command output: # @@ -295,9 +293,13 @@ def _syscmd_ver(system='', release='', version='', else: return system, release, version + ver_output = re.compile(r'(?:([\w ]+) ([\w.]+) ' + r'.*' + r'\[.* ([\d.]+)\])') + # Parse the output info = info.strip() - m = _ver_output.match(info) + m = ver_output.match(info) if m is not None: system, release, version = m.groups() # Strip trailing dots from version and release @@ -310,34 +312,52 @@ def _syscmd_ver(system='', release='', version='', version = _norm_version(version) return system, release, version -_WIN32_CLIENT_RELEASES = { - (5, 0): "2000", - (5, 1): "XP", - # Strictly, 5.2 client is XP 64-bit, but platform.py historically - # has always called it 2003 Server - (5, 2): "2003Server", - (5, None): "post2003", - - (6, 0): "Vista", - (6, 1): "7", - (6, 2): "8", - (6, 3): "8.1", - (6, None): "post8.1", - - (10, 0): "10", - (10, None): "post10", -} - -# Server release name lookup will default to client names if necessary -_WIN32_SERVER_RELEASES = { - (5, 2): "2003Server", - - (6, 0): "2008Server", - (6, 1): "2008ServerR2", - (6, 2): "2012Server", - (6, 3): "2012ServerR2", - (6, None): "post2012ServerR2", -} +try: + import _wmi +except ImportError: + def _wmi_query(*keys): + raise OSError("not supported") +else: + def _wmi_query(table, *keys): + table = { + "OS": "Win32_OperatingSystem", + "CPU": "Win32_Processor", + }[table] + data = _wmi.exec_query("SELECT {} FROM {}".format( + ",".join(keys), + table, + )).split("\0") + split_data = (i.partition("=") for i in data) + dict_data = {i[0]: i[2] for i in split_data} + return (dict_data[k] for k in keys) + + +_WIN32_CLIENT_RELEASES = [ + ((10, 1, 0), "post11"), + ((10, 0, 22000), "11"), + ((6, 4, 0), "10"), + ((6, 3, 0), "8.1"), + ((6, 2, 0), "8"), + ((6, 1, 0), "7"), + ((6, 0, 0), "Vista"), + ((5, 2, 3790), "XP64"), + ((5, 2, 0), "XPMedia"), + ((5, 1, 0), "XP"), + ((5, 0, 0), "2000"), +] + +_WIN32_SERVER_RELEASES = [ + ((10, 1, 0), "post2022Server"), + ((10, 0, 20348), "2022Server"), + ((10, 0, 17763), "2019Server"), + ((6, 4, 0), "2016Server"), + ((6, 3, 0), "2012ServerR2"), + ((6, 2, 0), "2012Server"), + ((6, 1, 0), "2008ServerR2"), + ((6, 0, 0), "2008Server"), + ((5, 2, 0), "2003Server"), + ((5, 0, 0), "2000Server"), +] def win32_is_iot(): return win32_edition() in ('IoTUAP', 'NanoServer', 'WindowsCoreHeadless', 'IoTEdgeOS') @@ -360,22 +380,40 @@ def win32_edition(): return None -def win32_ver(release='', version='', csd='', ptype=''): +def _win32_ver(version, csd, ptype): + # Try using WMI first, as this is the canonical source of data + try: + (version, product_type, ptype, spmajor, spminor) = _wmi_query( + 'OS', + 'Version', + 'ProductType', + 'BuildType', + 'ServicePackMajorVersion', + 'ServicePackMinorVersion', + ) + is_client = (int(product_type) == 1) + if spminor and spminor != '0': + csd = f'SP{spmajor}.{spminor}' + else: + csd = f'SP{spmajor}' + return version, csd, ptype, is_client + except OSError: + pass + + # Fall back to a combination of sys.getwindowsversion and "ver" try: from sys import getwindowsversion except ImportError: - return release, version, csd, ptype + return version, csd, ptype, True winver = getwindowsversion() + is_client = (getattr(winver, 'product_type', 1) == 1) try: - major, minor, build = map(int, _syscmd_ver()[2].split('.')) + version = _syscmd_ver()[2] + major, minor, build = map(int, version.split('.')) except ValueError: major, minor, build = winver.platform_version or winver[:3] - version = '{0}.{1}.{2}'.format(major, minor, build) - - release = (_WIN32_CLIENT_RELEASES.get((major, minor)) or - _WIN32_CLIENT_RELEASES.get((major, None)) or - release) + version = '{0}.{1}.{2}'.format(major, minor, build) # getwindowsversion() reflect the compatibility mode Python is # running under, and so the service pack value is only going to be @@ -387,12 +425,6 @@ def win32_ver(release='', version='', csd='', ptype=''): if csd[:13] == 'Service Pack ': csd = 'SP' + csd[13:] - # VER_NT_SERVER = 3 - if getattr(winver, 'product_type', None) == 3: - release = (_WIN32_SERVER_RELEASES.get((major, minor)) or - _WIN32_SERVER_RELEASES.get((major, None)) or - release) - try: try: import winreg @@ -408,6 +440,18 @@ def win32_ver(release='', version='', csd='', ptype=''): except OSError: pass + return version, csd, ptype, is_client + +def win32_ver(release='', version='', csd='', ptype=''): + is_client = False + + version, csd, ptype, is_client = _win32_ver(version, csd, ptype) + + if version: + intversion = tuple(map(int, version.split('.'))) + releases = _WIN32_CLIENT_RELEASES if is_client else _WIN32_SERVER_RELEASES + release = next((r for v, r in releases if v <= intversion), release) + return release, version, csd, ptype @@ -562,7 +606,7 @@ def _platform(*args): platform = platform.replace('unknown', '') # Fold '--'s and remove trailing '-' - while 1: + while True: cleaned = platform.replace('--', '-') if cleaned == platform: break @@ -726,6 +770,21 @@ def _get_machine_win32(): # http://www.geocities.com/rick_lively/MANUALS/ENV/MSWIN/PROCESSI.HTM # WOW64 processes mask the native architecture + try: + [arch, *_] = _wmi_query('CPU', 'Architecture') + except OSError: + pass + else: + try: + arch = ['x86', 'MIPS', 'Alpha', 'PowerPC', None, + 'ARM', 'ia64', None, None, + 'AMD64', None, None, 'ARM64', + ][int(arch)] + except (ValueError, IndexError): + pass + else: + if arch: + return arch return ( os.environ.get('PROCESSOR_ARCHITEW6432', '') or os.environ.get('PROCESSOR_ARCHITECTURE', '') @@ -739,7 +798,12 @@ class _Processor: return func() or '' def get_win32(): - return os.environ.get('PROCESSOR_IDENTIFIER', _get_machine_win32()) + try: + manufacturer, caption = _wmi_query('CPU', 'Manufacturer', 'Caption') + except OSError: + return os.environ.get('PROCESSOR_IDENTIFIER', _get_machine_win32()) + else: + return f'{caption}, {manufacturer}' def get_OpenVMS(): try: @@ -971,32 +1035,6 @@ def processor(): ### Various APIs for extracting information from sys.version -_sys_version_parser = re.compile( - r'([\w.+]+)\s*' # "version<space>" - r'\(#?([^,]+)' # "(#buildno" - r'(?:,\s*([\w ]*)' # ", builddate" - r'(?:,\s*([\w :]*))?)?\)\s*' # ", buildtime)<space>" - r'\[([^\]]+)\]?', re.ASCII) # "[compiler]" - -_ironpython_sys_version_parser = re.compile( - r'IronPython\s*' - r'([\d\.]+)' - r'(?: \(([\d\.]+)\))?' - r' on (.NET [\d\.]+)', re.ASCII) - -# IronPython covering 2.6 and 2.7 -_ironpython26_sys_version_parser = re.compile( - r'([\d.]+)\s*' - r'\(IronPython\s*' - r'[\d.]+\s*' - r'\(([\d.]+)\) on ([\w.]+ [\d.]+(?: \(\d+-bit\))?)\)' -) - -_pypy_sys_version_parser = re.compile( - r'([\w.+]+)\s*' - r'\(#?([^,]+),\s*([\w ]+),\s*([\w :]+)\)\s*' - r'\[PyPy [^\]]+\]?') - _sys_version_cache = {} def _sys_version(sys_version=None): @@ -1028,28 +1066,17 @@ def _sys_version(sys_version=None): if result is not None: return result - # Parse it - if 'IronPython' in sys_version: - # IronPython - name = 'IronPython' - if sys_version.startswith('IronPython'): - match = _ironpython_sys_version_parser.match(sys_version) - else: - match = _ironpython26_sys_version_parser.match(sys_version) + sys_version_parser = re.compile( + r'([\w.+]+)\s*' # "version<space>" + r'\(#?([^,]+)' # "(#buildno" + r'(?:,\s*([\w ]*)' # ", builddate" + r'(?:,\s*([\w :]*))?)?\)\s*' # ", buildtime)<space>" + r'\[([^\]]+)\]?', re.ASCII) # "[compiler]" - if match is None: - raise ValueError( - 'failed to parse IronPython sys.version: %s' % - repr(sys_version)) - - version, alt_version, compiler = match.groups() - buildno = '' - builddate = '' - - elif sys.platform.startswith('java'): + if sys.platform.startswith('java'): # Jython name = 'Jython' - match = _sys_version_parser.match(sys_version) + match = sys_version_parser.match(sys_version) if match is None: raise ValueError( 'failed to parse Jython sys.version: %s' % @@ -1061,8 +1088,13 @@ def _sys_version(sys_version=None): elif "PyPy" in sys_version: # PyPy + pypy_sys_version_parser = re.compile( + r'([\w.+]+)\s*' + r'\(#?([^,]+),\s*([\w ]+),\s*([\w :]+)\)\s*' + r'\[PyPy [^\]]+\]?') + name = "PyPy" - match = _pypy_sys_version_parser.match(sys_version) + match = pypy_sys_version_parser.match(sys_version) if match is None: raise ValueError("failed to parse PyPy sys.version: %s" % repr(sys_version)) @@ -1071,7 +1103,7 @@ def _sys_version(sys_version=None): else: # CPython - match = _sys_version_parser.match(sys_version) + match = sys_version_parser.match(sys_version) if match is None: raise ValueError( 'failed to parse CPython sys.version: %s' % @@ -1109,7 +1141,6 @@ def python_implementation(): Currently, the following implementations are identified: 'CPython' (C implementation of Python), - 'IronPython' (.NET implementation of Python), 'Jython' (Java implementation of Python), 'PyPy' (Python implementation of Python). @@ -1184,7 +1215,7 @@ def python_compiler(): _platform_cache = {} -def platform(aliased=0, terse=0): +def platform(aliased=False, terse=False): """ Returns a single string identifying the underlying platform with as much useful information as possible (but no more :). @@ -1230,7 +1261,7 @@ def platform(aliased=0, terse=0): else: platform = _platform(system, release, version, csd) - elif system in ('Linux',): + elif system == 'Linux': # check for libc vs. glibc libcname, libcversion = libc_ver() platform = _platform(system, release, machine, processor, @@ -1261,13 +1292,6 @@ def platform(aliased=0, terse=0): ### freedesktop.org os-release standard # https://www.freedesktop.org/software/systemd/man/os-release.html -# NAME=value with optional quotes (' or "). The regular expression is less -# strict than shell lexer, but that's ok. -_os_release_line = re.compile( - "^(?P<name>[a-zA-Z0-9_]+)=(?P<quote>[\"\']?)(?P<value>.*)(?P=quote)$" -) -# unescape five special characters mentioned in the standard -_os_release_unescape = re.compile(r"\\([\\\$\"\'`])") # /etc takes precedence over /usr/lib _os_release_candidates = ("/etc/os-release", "/usr/lib/os-release") _os_release_cache = None @@ -1282,10 +1306,18 @@ def _parse_os_release(lines): "PRETTY_NAME": "Linux", } + # NAME=value with optional quotes (' or "). The regular expression is less + # strict than shell lexer, but that's ok. + os_release_line = re.compile( + "^(?P<name>[a-zA-Z0-9_]+)=(?P<quote>[\"\']?)(?P<value>.*)(?P=quote)$" + ) + # unescape five special characters mentioned in the standard + os_release_unescape = re.compile(r"\\([\\\$\"\'`])") + for line in lines: - mo = _os_release_line.match(line) + mo = os_release_line.match(line) if mo is not None: - info[mo.group('name')] = _os_release_unescape.sub( + info[mo.group('name')] = os_release_unescape.sub( r"\1", mo.group('value') ) diff --git a/Lib/plistlib.py b/Lib/plistlib.py index 664890d2..3292c30d 100644 --- a/Lib/plistlib.py +++ b/Lib/plistlib.py @@ -21,6 +21,9 @@ datetime.datetime objects. Generate Plist example: + import datetime + import plistlib + pl = dict( aString = "Doodah", aList = ["A", "B", 12, 32.1, [1, 2, 3]], @@ -28,22 +31,28 @@ Generate Plist example: anInt = 728, aDict = dict( anotherString = "<hello & hi there!>", - aUnicodeValue = "M\xe4ssig, Ma\xdf", + aThirdString = "M\xe4ssig, Ma\xdf", aTrueValue = True, aFalseValue = False, ), someData = b"<binary gunk>", someMoreData = b"<lots of binary gunk>" * 10, - aDate = datetime.datetime.fromtimestamp(time.mktime(time.gmtime())), + aDate = datetime.datetime.now() ) - with open(fileName, 'wb') as fp: - dump(pl, fp) + print(plistlib.dumps(pl).decode()) Parse Plist example: - with open(fileName, 'rb') as fp: - pl = load(fp) - print(pl["aKey"]) + import plistlib + + plist = b'''<plist version="1.0"> + <dict> + <key>foo</key> + <string>bar</string> + </dict> + </plist>''' + pl = plistlib.loads(plist) + print(pl["foo"]) """ __all__ = [ "InvalidFileException", "FMT_XML", "FMT_BINARY", "load", "dump", "loads", "dumps", "UID" @@ -199,7 +208,7 @@ class _PlistParser: def add_object(self, value): if self.current_key is not None: - if not isinstance(self.stack[-1], type({})): + if not isinstance(self.stack[-1], dict): raise ValueError("unexpected element at line %d" % self.parser.CurrentLineNumber) self.stack[-1][self.current_key] = value @@ -208,7 +217,7 @@ class _PlistParser: # this is the root object self.root = value else: - if not isinstance(self.stack[-1], type([])): + if not isinstance(self.stack[-1], list): raise ValueError("unexpected element at line %d" % self.parser.CurrentLineNumber) self.stack[-1].append(value) @@ -232,7 +241,7 @@ class _PlistParser: self.stack.pop() def end_key(self): - if self.current_key or not isinstance(self.stack[-1], type({})): + if self.current_key or not isinstance(self.stack[-1], dict): raise ValueError("unexpected key at line %d" % self.parser.CurrentLineNumber) self.current_key = self.get_data() diff --git a/Lib/poplib.py b/Lib/poplib.py index 0f858731..9a5ef03c 100644 --- a/Lib/poplib.py +++ b/Lib/poplib.py @@ -419,35 +419,19 @@ if HAVE_SSL: class POP3_SSL(POP3): """POP3 client class over SSL connection - Instantiate with: POP3_SSL(hostname, port=995, keyfile=None, certfile=None, - context=None) + Instantiate with: POP3_SSL(hostname, port=995, context=None) hostname - the hostname of the pop3 over ssl server port - port number - keyfile - PEM formatted file that contains your private key - certfile - PEM formatted certificate chain file context - a ssl.SSLContext See the methods of the parent class POP3 for more documentation. """ - def __init__(self, host, port=POP3_SSL_PORT, keyfile=None, certfile=None, - timeout=socket._GLOBAL_DEFAULT_TIMEOUT, context=None): - if context is not None and keyfile is not None: - raise ValueError("context and keyfile arguments are mutually " - "exclusive") - if context is not None and certfile is not None: - raise ValueError("context and certfile arguments are mutually " - "exclusive") - if keyfile is not None or certfile is not None: - import warnings - warnings.warn("keyfile and certfile are deprecated, use a " - "custom context instead", DeprecationWarning, 2) - self.keyfile = keyfile - self.certfile = certfile + def __init__(self, host, port=POP3_SSL_PORT, + *, timeout=socket._GLOBAL_DEFAULT_TIMEOUT, context=None): if context is None: - context = ssl._create_stdlib_context(certfile=certfile, - keyfile=keyfile) + context = ssl._create_stdlib_context() self.context = context POP3.__init__(self, host, port, timeout) @@ -457,7 +441,7 @@ if HAVE_SSL: server_hostname=self.host) return sock - def stls(self, keyfile=None, certfile=None, context=None): + def stls(self, context=None): """The method unconditionally raises an exception since the STLS command doesn't make any sense on an already established SSL/TLS session. diff --git a/Lib/posixpath.py b/Lib/posixpath.py index 5b4d78bc..e4f155e4 100644 --- a/Lib/posixpath.py +++ b/Lib/posixpath.py @@ -28,14 +28,14 @@ import stat import genericpath from genericpath import * -__all__ = ["normcase","isabs","join","splitdrive","split","splitext", +__all__ = ["normcase","isabs","join","splitdrive","splitroot","split","splitext", "basename","dirname","commonprefix","getsize","getmtime", "getatime","getctime","islink","exists","lexists","isdir","isfile", "ismount", "expanduser","expandvars","normpath","abspath", "samefile","sameopenfile","samestat", "curdir","pardir","sep","pathsep","defpath","altsep","extsep", "devnull","realpath","supports_unicode_filenames","relpath", - "commonpath"] + "commonpath", "isjunction"] def _get_sep(path): @@ -135,6 +135,35 @@ def splitdrive(p): return p[:0], p +def splitroot(p): + """Split a pathname into drive, root and tail. On Posix, drive is always + empty; the root may be empty, a single slash, or two slashes. The tail + contains anything after the root. For example: + + splitroot('foo/bar') == ('', '', 'foo/bar') + splitroot('/foo/bar') == ('', '/', 'foo/bar') + splitroot('//foo/bar') == ('', '//', 'foo/bar') + splitroot('///foo/bar') == ('', '/', '//foo/bar') + """ + p = os.fspath(p) + if isinstance(p, bytes): + sep = b'/' + empty = b'' + else: + sep = '/' + empty = '' + if p[:1] != sep: + # Relative path, e.g.: 'foo' + return empty, empty, p + elif p[1:2] != sep or p[2:3] == sep: + # Absolute path, e.g.: '/foo', '///foo', '////foo', etc. + return empty, sep, p[1:] + else: + # Precisely two leading slashes, e.g.: '//foo'. Implementation defined per POSIX, see + # https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13 + return empty, p[:2], p[2:] + + # Return the tail (basename) part of a path, same as split(path)[1]. def basename(p): @@ -158,16 +187,14 @@ def dirname(p): return head -# Is a path a symbolic link? -# This will always return false on systems where os.lstat doesn't exist. +# Is a path a junction? + +def isjunction(path): + """Test whether a path is a junction + Junctions are not a part of posix semantics""" + os.fspath(path) + return False -def islink(path): - """Test whether a path is a symbolic link""" - try: - st = os.lstat(path) - except (OSError, ValueError, AttributeError): - return False - return stat.S_ISLNK(st.st_mode) # Being true for dangling symbolic links is also useful. @@ -362,13 +389,7 @@ except ImportError: dotdot = '..' if path == empty: return dot - initial_slashes = path.startswith(sep) - # POSIX allows one or two initial slashes, but treats three or more - # as single slash. - # (see https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13) - if (initial_slashes and - path.startswith(sep*2) and not path.startswith(sep*3)): - initial_slashes = 2 + _, initial_slashes, path = splitroot(path) comps = path.split(sep) new_comps = [] for comp in comps: @@ -380,9 +401,7 @@ except ImportError: elif new_comps: new_comps.pop() comps = new_comps - path = sep.join(comps) - if initial_slashes: - path = sep*initial_slashes + path + path = initial_slashes + sep.join(comps) return path or dot else: diff --git a/Lib/pprint.py b/Lib/pprint.py index 575688d8..34ed1263 100644 --- a/Lib/pprint.py +++ b/Lib/pprint.py @@ -637,19 +637,6 @@ def _recursion(object): % (type(object).__name__, id(object))) -def _perfcheck(object=None): - import time - if object is None: - object = [("string", (1, 2), [3, 4], {5: 6, 7: 8})] * 100000 - p = PrettyPrinter() - t1 = time.perf_counter() - p._safe_repr(object, {}, None, 0, True) - t2 = time.perf_counter() - p.pformat(object) - t3 = time.perf_counter() - print("_safe_repr:", t2 - t1) - print("pformat:", t3 - t2) - def _wrap_bytes_repr(object, width, allowance): current = b'' last = len(object) // 4 * 4 @@ -666,6 +653,3 @@ def _wrap_bytes_repr(object, width, allowance): current = candidate if current: yield repr(current) - -if __name__ == "__main__": - _perfcheck() diff --git a/Lib/profile.py b/Lib/profile.py index d8599fb4..4b82523b 100755 --- a/Lib/profile.py +++ b/Lib/profile.py @@ -24,6 +24,8 @@ # governing permissions and limitations under the License. +import importlib.machinery +import io import sys import time import marshal @@ -587,11 +589,14 @@ def main(): else: progname = args[0] sys.path.insert(0, os.path.dirname(progname)) - with open(progname, 'rb') as fp: + with io.open_code(progname) as fp: code = compile(fp.read(), progname, 'exec') + spec = importlib.machinery.ModuleSpec(name='__main__', loader=None, + origin=progname) globs = { - '__file__': progname, - '__name__': '__main__', + '__spec__': spec, + '__file__': spec.origin, + '__name__': spec.name, '__package__': None, '__cached__': None, } diff --git a/Lib/pstats.py b/Lib/pstats.py index 80408313..51bcca84 100644 --- a/Lib/pstats.py +++ b/Lib/pstats.py @@ -223,8 +223,6 @@ class Stats: for word, tup in self.sort_arg_dict_default.items(): fragment = word while fragment: - if not fragment: - break if fragment in dict: bad_list[fragment] = 0 break diff --git a/Lib/pty.py b/Lib/pty.py index 8d8ce40d..1d97994a 100644 --- a/Lib/pty.py +++ b/Lib/pty.py @@ -40,6 +40,9 @@ def master_open(): Open a pty master and return the fd, and the filename of the slave end. Deprecated, use openpty() instead.""" + import warnings + warnings.warn("Use pty.openpty() instead.", DeprecationWarning, stacklevel=2) # Remove API in 3.14 + try: master_fd, slave_fd = os.openpty() except (AttributeError, OSError): @@ -69,6 +72,9 @@ def slave_open(tty_name): opened filedescriptor. Deprecated, use openpty() instead.""" + import warnings + warnings.warn("Use pty.openpty() instead.", DeprecationWarning, stacklevel=2) # Remove API in 3.14 + result = os.open(tty_name, os.O_RDWR) try: from fcntl import ioctl, I_PUSH @@ -101,32 +107,14 @@ def fork(): master_fd, slave_fd = openpty() pid = os.fork() if pid == CHILD: - # Establish a new session. - os.setsid() os.close(master_fd) - - # Slave becomes stdin/stdout/stderr of child. - os.dup2(slave_fd, STDIN_FILENO) - os.dup2(slave_fd, STDOUT_FILENO) - os.dup2(slave_fd, STDERR_FILENO) - if slave_fd > STDERR_FILENO: - os.close(slave_fd) - - # Explicitly open the tty to make it become a controlling tty. - tmp_fd = os.open(os.ttyname(STDOUT_FILENO), os.O_RDWR) - os.close(tmp_fd) + os.login_tty(slave_fd) else: os.close(slave_fd) # Parent and child process. return pid, master_fd -def _writen(fd, data): - """Write all the data to a descriptor.""" - while data: - n = os.write(fd, data) - data = data[n:] - def _read(fd): """Default read function.""" return os.read(fd, 1024) @@ -136,9 +124,42 @@ def _copy(master_fd, master_read=_read, stdin_read=_read): Copies pty master -> standard output (master_read) standard input -> pty master (stdin_read)""" - fds = [master_fd, STDIN_FILENO] - while fds: - rfds, _wfds, _xfds = select(fds, [], []) + if os.get_blocking(master_fd): + # If we write more than tty/ndisc is willing to buffer, we may block + # indefinitely. So we set master_fd to non-blocking temporarily during + # the copy operation. + os.set_blocking(master_fd, False) + try: + _copy(master_fd, master_read=master_read, stdin_read=stdin_read) + finally: + # restore blocking mode for backwards compatibility + os.set_blocking(master_fd, True) + return + high_waterlevel = 4096 + stdin_avail = master_fd != STDIN_FILENO + stdout_avail = master_fd != STDOUT_FILENO + i_buf = b'' + o_buf = b'' + while 1: + rfds = [] + wfds = [] + if stdin_avail and len(i_buf) < high_waterlevel: + rfds.append(STDIN_FILENO) + if stdout_avail and len(o_buf) < high_waterlevel: + rfds.append(master_fd) + if stdout_avail and len(o_buf) > 0: + wfds.append(STDOUT_FILENO) + if len(i_buf) > 0: + wfds.append(master_fd) + + rfds, wfds, _xfds = select(rfds, wfds, []) + + if STDOUT_FILENO in wfds: + try: + n = os.write(STDOUT_FILENO, o_buf) + o_buf = o_buf[n:] + except OSError: + stdout_avail = False if master_fd in rfds: # Some OSes signal EOF by returning an empty byte string, @@ -150,19 +171,22 @@ def _copy(master_fd, master_read=_read, stdin_read=_read): if not data: # Reached EOF. return # Assume the child process has exited and is # unreachable, so we clean up. - else: - os.write(STDOUT_FILENO, data) + o_buf += data + + if master_fd in wfds: + n = os.write(master_fd, i_buf) + i_buf = i_buf[n:] - if STDIN_FILENO in rfds: + if stdin_avail and STDIN_FILENO in rfds: data = stdin_read(STDIN_FILENO) if not data: - fds.remove(STDIN_FILENO) + stdin_avail = False else: - _writen(master_fd, data) + i_buf += data def spawn(argv, master_read=_read, stdin_read=_read): """Create a spawned process.""" - if type(argv) == type(''): + if isinstance(argv, str): argv = (argv,) sys.audit('pty.spawn', argv) diff --git a/Lib/pydoc.py b/Lib/pydoc.py index 088a3ba8..185f09e6 100755 --- a/Lib/pydoc.py +++ b/Lib/pydoc.py @@ -389,8 +389,17 @@ def synopsis(filename, cache={}): class ErrorDuringImport(Exception): """Errors that occurred while trying to import something to document it.""" def __init__(self, filename, exc_info): + if not isinstance(exc_info, tuple): + assert isinstance(exc_info, BaseException) + self.exc = type(exc_info) + self.value = exc_info + self.tb = exc_info.__traceback__ + else: + warnings.warn("A tuple value for exc_info is deprecated, use an exception instance", + DeprecationWarning) + + self.exc, self.value, self.tb = exc_info self.filename = filename - self.exc, self.value, self.tb = exc_info def __str__(self): exc = self.exc.__name__ @@ -411,8 +420,8 @@ def importfile(path): spec = importlib.util.spec_from_file_location(name, path, loader=loader) try: return importlib._bootstrap._load(spec) - except: - raise ErrorDuringImport(path, sys.exc_info()) + except BaseException as err: + raise ErrorDuringImport(path, err) def safeimport(path, forceload=0, cache={}): """Import a module; handle errors; return None if the module isn't found. @@ -439,25 +448,21 @@ def safeimport(path, forceload=0, cache={}): # Prevent garbage collection. cache[key] = sys.modules[key] del sys.modules[key] - module = __import__(path) - except: + module = importlib.import_module(path) + except BaseException as err: # Did the error occur before or after the module was found? - (exc, value, tb) = info = sys.exc_info() if path in sys.modules: # An error occurred while executing the imported module. - raise ErrorDuringImport(sys.modules[path].__file__, info) - elif exc is SyntaxError: + raise ErrorDuringImport(sys.modules[path].__file__, err) + elif type(err) is SyntaxError: # A SyntaxError occurred before we could execute the module. - raise ErrorDuringImport(value.filename, info) - elif issubclass(exc, ImportError) and value.name == path: + raise ErrorDuringImport(err.filename, err) + elif isinstance(err, ImportError) and err.name == path: # No such module in the path. return None else: # Some other error occurred during the importing process. - raise ErrorDuringImport(path, sys.exc_info()) - for part in path.split('.')[1:]: - try: module = getattr(module, part) - except AttributeError: return None + raise ErrorDuringImport(path, err) return module # ---------------------------------------------------- formatter base class @@ -504,7 +509,7 @@ class Doc: basedir = os.path.normcase(basedir) if (isinstance(object, type(os)) and - (object.__name__ in ('errno', 'exceptions', 'gc', 'imp', + (object.__name__ in ('errno', 'exceptions', 'gc', 'marshal', 'posix', 'signal', 'sys', '_thread', 'zipimport') or (file.startswith(basedir) and @@ -686,9 +691,7 @@ class HTMLDoc(Doc): r'RFC[- ]?(\d+)|' r'PEP[- ]?(\d+)|' r'(self\.)?(\w+))') - while True: - match = pattern.search(text, here) - if not match: break + while match := pattern.search(text, here): start, end = match.span() results.append(escape(text[here:start])) @@ -723,7 +726,7 @@ class HTMLDoc(Doc): """Produce HTML for a class tree as given by inspect.getclasstree().""" result = '' for entry in tree: - if type(entry) is type(()): + if isinstance(entry, tuple): c, bases = entry result = result + '<dt class="heading-text">' result = result + self.classlink(c, modname) @@ -733,7 +736,7 @@ class HTMLDoc(Doc): parents.append(self.classlink(base, modname)) result = result + '(' + ', '.join(parents) + ')' result = result + '\n</dt>' - elif type(entry) is type([]): + elif isinstance(entry, list): result = result + '<dd>\n%s</dd>\n' % self.formattree( entry, modname, c) return '<dl>\n%s</dl>\n' % result @@ -1171,8 +1174,7 @@ class TextDoc(Doc): def indent(self, text, prefix=' '): """Indent text by prepending a given prefix to each line.""" if not text: return '' - lines = [prefix + line for line in text.split('\n')] - if lines: lines[-1] = lines[-1].rstrip() + lines = [(prefix + line).rstrip() for line in text.split('\n')] return '\n'.join(lines) def section(self, title, contents): @@ -1186,14 +1188,14 @@ class TextDoc(Doc): """Render in text a class tree as returned by inspect.getclasstree().""" result = '' for entry in tree: - if type(entry) is type(()): + if isinstance(entry, tuple): c, bases = entry result = result + prefix + classname(c, modname) if bases and bases != (parent,): parents = (classname(c, modname) for c in bases) result = result + '(%s)' % ', '.join(parents) result = result + '\n' - elif type(entry) is type([]): + elif isinstance(entry, list): result = result + self.formattree( entry, modname, c, prefix + ' ') return result @@ -1778,12 +1780,21 @@ def render_doc(thing, title='Python Library Documentation: %s', forceload=0, return title % desc + '\n\n' + renderer.document(object, name) def doc(thing, title='Python Library Documentation: %s', forceload=0, - output=None): + output=None, is_cli=False): """Display text documentation, given an object or a path to an object.""" if output is None: - pager(render_doc(thing, title, forceload)) + try: + pager(render_doc(thing, title, forceload)) + except ImportError as exc: + if is_cli: + raise + print(exc) else: - output.write(render_doc(thing, title, forceload, plaintext)) + try: + s = render_doc(thing, title, forceload, plaintext) + except ImportError as exc: + s = str(exc) + output.write(s) def writedoc(thing, forceload=0): """Write HTML documentation to a file in the current directory.""" @@ -2000,8 +2011,8 @@ class Helper: if request is not self._GoInteractive: try: self.help(request) - except ImportError as e: - self.output.write(f'{e}\n') + except ImportError as err: + self.output.write(f'{err}\n') else: self.intro() self.interact() @@ -2042,8 +2053,8 @@ has the same effect as typing a particular string at the help> prompt. self.output.flush() return self.input.readline() - def help(self, request): - if type(request) is type(''): + def help(self, request, is_cli=False): + if isinstance(request, str): request = request.strip() if request == 'keywords': self.listkeywords() elif request == 'symbols': self.listsymbols() @@ -2054,13 +2065,13 @@ has the same effect as typing a particular string at the help> prompt. elif request in self.symbols: self.showsymbol(request) elif request in ['True', 'False', 'None']: # special case these keywords since they are objects too - doc(eval(request), 'Help on %s:') + doc(eval(request), 'Help on %s:', is_cli=is_cli) elif request in self.keywords: self.showtopic(request) elif request in self.topics: self.showtopic(request) - elif request: doc(request, 'Help on %s:', output=self._output) - else: doc(str, 'Help on %s:', output=self._output) + elif request: doc(request, 'Help on %s:', output=self._output, is_cli=is_cli) + else: doc(str, 'Help on %s:', output=self._output, is_cli=is_cli) elif isinstance(request, Helper): self() - else: doc(request, 'Help on %s:', output=self._output) + else: doc(request, 'Help on %s:', output=self._output, is_cli=is_cli) self.output.write('\n') def intro(self): @@ -2128,7 +2139,7 @@ module "pydoc_data.topics" could not be found. if not target: self.output.write('no documentation found for %s\n' % repr(topic)) return - if type(target) is type(''): + if isinstance(target, str): return self.showtopic(target, more_xrefs) label, xrefs = target @@ -2237,7 +2248,7 @@ class ModuleScanner: callback(None, modname, '') else: try: - spec = pkgutil._get_spec(importer, modname) + spec = importer.find_spec(modname) except SyntaxError: # raised by tests for bad coding cookies or BOM continue @@ -2408,8 +2419,8 @@ def _start_server(urlhandler, hostname, port): docsvr = DocServer(self.host, self.port, self.ready) self.docserver = docsvr docsvr.serve_until_quit() - except Exception as e: - self.error = e + except Exception as err: + self.error = err def ready(self, server): self.serving = True @@ -2798,7 +2809,7 @@ def cli(): else: writedoc(arg) else: - help.help(arg) + help.help(arg, is_cli=True) except (ImportError, ErrorDuringImport) as value: print(value) sys.exit(1) diff --git a/Lib/pydoc_data/topics.py b/Lib/pydoc_data/topics.py index 7e3f4f98..28a5e06d 100644 --- a/Lib/pydoc_data/topics.py +++ b/Lib/pydoc_data/topics.py @@ -1,5 +1,6 @@ # -*- coding: utf-8 -*- -# Autogenerated by Sphinx on Tue Feb 7 13:37:35 2023 +# Autogenerated by Sphinx on Mon Oct 2 13:45:14 2023 +# as part of the release process. topics = {'assert': 'The "assert" statement\n' '**********************\n' '\n' @@ -208,7 +209,7 @@ topics = {'assert': 'The "assert" statement\n' 'the\n' ' subscript must have a type compatible with the mapping’s key ' 'type,\n' - ' and the mapping is then asked to create a key/datum pair ' + ' and the mapping is then asked to create a key/value pair ' 'which maps\n' ' the subscript to the assigned object. This can either ' 'replace an\n' @@ -538,77 +539,7 @@ topics = {'assert': 'The "assert" statement\n' ' **PEP 492** - Coroutines with async and await syntax\n' ' The proposal that made coroutines a proper standalone concept ' 'in\n' - ' Python, and added supporting syntax.\n' - '\n' - '-[ Footnotes ]-\n' - '\n' - '[1] The exception is propagated to the invocation stack unless ' - 'there\n' - ' is a "finally" clause which happens to raise another ' - 'exception.\n' - ' That new exception causes the old one to be lost.\n' - '\n' - '[2] In pattern matching, a sequence is defined as one of the\n' - ' following:\n' - '\n' - ' * a class that inherits from "collections.abc.Sequence"\n' - '\n' - ' * a Python class that has been registered as\n' - ' "collections.abc.Sequence"\n' - '\n' - ' * a builtin class that has its (CPython) ' - '"Py_TPFLAGS_SEQUENCE"\n' - ' bit set\n' - '\n' - ' * a class that inherits from any of the above\n' - '\n' - ' The following standard library classes are sequences:\n' - '\n' - ' * "array.array"\n' - '\n' - ' * "collections.deque"\n' - '\n' - ' * "list"\n' - '\n' - ' * "memoryview"\n' - '\n' - ' * "range"\n' - '\n' - ' * "tuple"\n' - '\n' - ' Note:\n' - '\n' - ' Subject values of type "str", "bytes", and "bytearray" do ' - 'not\n' - ' match sequence patterns.\n' - '\n' - '[3] In pattern matching, a mapping is defined as one of the ' - 'following:\n' - '\n' - ' * a class that inherits from "collections.abc.Mapping"\n' - '\n' - ' * a Python class that has been registered as\n' - ' "collections.abc.Mapping"\n' - '\n' - ' * a builtin class that has its (CPython) ' - '"Py_TPFLAGS_MAPPING"\n' - ' bit set\n' - '\n' - ' * a class that inherits from any of the above\n' - '\n' - ' The standard library classes "dict" and ' - '"types.MappingProxyType"\n' - ' are mappings.\n' - '\n' - '[4] A string literal appearing as the first statement in the ' - 'function\n' - ' body is transformed into the function’s "__doc__" attribute ' - 'and\n' - ' therefore the function’s *docstring*.\n' - '\n' - '[5] A string literal appearing as the first statement in the class\n' - ' body is transformed into the namespace’s "__doc__" item and\n' - ' therefore the class’s *docstring*.\n', + ' Python, and added supporting syntax.\n', 'atom-identifiers': 'Identifiers (Names)\n' '*******************\n' '\n' @@ -1075,9 +1006,7 @@ topics = {'assert': 'The "assert" statement\n' 'for each\n' ' instance.\n' '\n' - '\n' - 'Notes on using *__slots__*\n' - '--------------------------\n' + 'Notes on using *__slots__*:\n' '\n' '* When inheriting from a class without *__slots__*, the ' '"__dict__" and\n' @@ -1134,10 +1063,11 @@ topics = {'assert': 'The "assert" statement\n' 'future, a\n' ' check may be added to prevent this.\n' '\n' - '* Nonempty *__slots__* does not work for classes derived ' - 'from\n' - ' “variable-length” built-in types such as "int", ' - '"bytes" and "tuple".\n' + '* "TypeError" will be raised if nonempty *__slots__* are ' + 'defined for a\n' + ' class derived from a ""variable-length" built-in type" ' + 'such as\n' + ' "int", "bytes", and "tuple".\n' '\n' '* Any non-string *iterable* may be assigned to ' '*__slots__*.\n' @@ -1747,8 +1677,8 @@ topics = {'assert': 'The "assert" statement\n' 'standard\n' 'type hierarchy):\n' '\n' - ' classdef ::= [decorators] "class" classname [inheritance] ":" ' - 'suite\n' + ' classdef ::= [decorators] "class" classname [type_params] ' + '[inheritance] ":" suite\n' ' inheritance ::= "(" [argument_list] ")"\n' ' classname ::= identifier\n' '\n' @@ -1812,6 +1742,19 @@ topics = {'assert': 'The "assert" statement\n' '"assignment_expression". Previously, the grammar was much more\n' 'restrictive; see **PEP 614** for details.\n' '\n' + 'A list of type parameters may be given in square brackets ' + 'immediately\n' + 'after the class’s name. This indicates to static type checkers ' + 'that\n' + 'the class is generic. At runtime, the type parameters can be ' + 'retrieved\n' + 'from the class’s "__type_params__" attribute. See Generic classes ' + 'for\n' + 'more.\n' + '\n' + 'Changed in version 3.12: Type parameter lists are new in Python ' + '3.12.\n' + '\n' '**Programmer’s note:** Variables defined in the class definition ' 'are\n' 'class attributes; they are shared by instances. Instance ' @@ -2499,42 +2442,33 @@ topics = {'assert': 'The "assert" statement\n' 'alive\n' 'until the next garbage collection occurs.\n' '\n' - 'Before an "except" clause’s suite is executed, details about ' - 'the\n' - 'exception are stored in the "sys" module and can be accessed ' - 'via\n' - '"sys.exc_info()". "sys.exc_info()" returns a 3-tuple consisting ' - 'of the\n' - 'exception class, the exception instance and a traceback object ' - '(see\n' - 'section The standard type hierarchy) identifying the point in ' - 'the\n' - 'program where the exception occurred. The details about the ' - 'exception\n' - 'accessed via "sys.exc_info()" are restored to their previous ' - 'values\n' - 'when leaving an exception handler:\n' + 'Before an "except" clause’s suite is executed, the exception is ' + 'stored\n' + 'in the "sys" module, where it can be accessed from within the ' + 'body of\n' + 'the "except" clause by calling "sys.exception()". When leaving ' + 'an\n' + 'exception handler, the exception stored in the "sys" module is ' + 'reset\n' + 'to its previous value:\n' '\n' - ' >>> print(sys.exc_info())\n' - ' (None, None, None)\n' + ' >>> print(sys.exception())\n' + ' None\n' ' >>> try:\n' ' ... raise TypeError\n' ' ... except:\n' - ' ... print(sys.exc_info())\n' + ' ... print(repr(sys.exception()))\n' ' ... try:\n' ' ... raise ValueError\n' ' ... except:\n' - ' ... print(sys.exc_info())\n' - ' ... print(sys.exc_info())\n' + ' ... print(repr(sys.exception()))\n' + ' ... print(repr(sys.exception()))\n' ' ...\n' - " (<class 'TypeError'>, TypeError(), <traceback object at " - '0x10efad080>)\n' - " (<class 'ValueError'>, ValueError(), <traceback object at " - '0x10efad040>)\n' - " (<class 'TypeError'>, TypeError(), <traceback object at " - '0x10efad080>)\n' - ' >>> print(sys.exc_info())\n' - ' (None, None, None)\n' + ' TypeError()\n' + ' ValueError()\n' + ' TypeError()\n' + ' >>> print(sys.exception())\n' + ' None\n' '\n' '\n' '"except*" clause\n' @@ -2581,9 +2515,12 @@ topics = {'assert': 'The "assert" statement\n' '\n' 'Any remaining exceptions that were not handled by any "except*" ' 'clause\n' - 'are re-raised at the end, combined into an exception group along ' - 'with\n' - 'all exceptions that were raised from within "except*" clauses.\n' + 'are re-raised at the end, along with all exceptions that were ' + 'raised\n' + 'from within the "except*" clauses. If this list contains more ' + 'than one\n' + 'exception to reraise, they are combined into an exception ' + 'group.\n' '\n' 'If the raised exception is not an exception group and its type ' 'matches\n' @@ -3081,7 +3018,7 @@ topics = {'assert': 'The "assert" statement\n' 'AS\n' 'pattern binds the subject to the name on the right of the as ' 'keyword\n' - 'and succeeds. "capture_pattern" cannot be a a "_".\n' + 'and succeeds. "capture_pattern" cannot be a "_".\n' '\n' 'In simple terms "P as NAME" will match with "P", and on success ' 'it\n' @@ -3559,8 +3496,8 @@ topics = {'assert': 'The "assert" statement\n' '(see\n' 'section The standard type hierarchy):\n' '\n' - ' funcdef ::= [decorators] "def" funcname "(" ' - '[parameter_list] ")"\n' + ' funcdef ::= [decorators] "def" funcname ' + '[type_params] "(" [parameter_list] ")"\n' ' ["->" expression] ":" suite\n' ' decorators ::= decorator+\n' ' decorator ::= "@" assignment_expression ' @@ -3622,6 +3559,19 @@ topics = {'assert': 'The "assert" statement\n' '"assignment_expression". Previously, the grammar was much more\n' 'restrictive; see **PEP 614** for details.\n' '\n' + 'A list of type parameters may be given in square brackets ' + 'between the\n' + 'function’s name and the opening parenthesis for its parameter ' + 'list.\n' + 'This indicates to static type checkers that the function is ' + 'generic.\n' + 'At runtime, the type parameters can be retrieved from the ' + 'function’s\n' + '"__type_params__" attribute. See Generic functions for more.\n' + '\n' + 'Changed in version 3.12: Type parameter lists are new in Python ' + '3.12.\n' + '\n' 'When one or more *parameters* have the form *parameter* "="\n' '*expression*, the function is said to have “default parameter ' 'values.”\n' @@ -3764,8 +3714,8 @@ topics = {'assert': 'The "assert" statement\n' 'standard\n' 'type hierarchy):\n' '\n' - ' classdef ::= [decorators] "class" classname [inheritance] ' - '":" suite\n' + ' classdef ::= [decorators] "class" classname [type_params] ' + '[inheritance] ":" suite\n' ' inheritance ::= "(" [argument_list] ")"\n' ' classname ::= identifier\n' '\n' @@ -3833,6 +3783,19 @@ topics = {'assert': 'The "assert" statement\n' '"assignment_expression". Previously, the grammar was much more\n' 'restrictive; see **PEP 614** for details.\n' '\n' + 'A list of type parameters may be given in square brackets ' + 'immediately\n' + 'after the class’s name. This indicates to static type checkers ' + 'that\n' + 'the class is generic. At runtime, the type parameters can be ' + 'retrieved\n' + 'from the class’s "__type_params__" attribute. See Generic ' + 'classes for\n' + 'more.\n' + '\n' + 'Changed in version 3.12: Type parameter lists are new in Python ' + '3.12.\n' + '\n' '**Programmer’s note:** Variables defined in the class definition ' 'are\n' 'class attributes; they are shared by instances. Instance ' @@ -3990,6 +3953,272 @@ topics = {'assert': 'The "assert" statement\n' 'concept in\n' ' Python, and added supporting syntax.\n' '\n' + '\n' + 'Type parameter lists\n' + '====================\n' + '\n' + 'New in version 3.12.\n' + '\n' + ' type_params ::= "[" type_param ("," type_param)* "]"\n' + ' type_param ::= typevar | typevartuple | paramspec\n' + ' typevar ::= identifier (":" expression)?\n' + ' typevartuple ::= "*" identifier\n' + ' paramspec ::= "**" identifier\n' + '\n' + 'Functions (including coroutines), classes and type aliases may ' + 'contain\n' + 'a type parameter list:\n' + '\n' + ' def max[T](args: list[T]) -> T:\n' + ' ...\n' + '\n' + ' async def amax[T](args: list[T]) -> T:\n' + ' ...\n' + '\n' + ' class Bag[T]:\n' + ' def __iter__(self) -> Iterator[T]:\n' + ' ...\n' + '\n' + ' def add(self, arg: T) -> None:\n' + ' ...\n' + '\n' + ' type ListOrSet[T] = list[T] | set[T]\n' + '\n' + 'Semantically, this indicates that the function, class, or type ' + 'alias\n' + 'is generic over a type variable. This information is primarily ' + 'used by\n' + 'static type checkers, and at runtime, generic objects behave ' + 'much like\n' + 'their non-generic counterparts.\n' + '\n' + 'Type parameters are declared in square brackets ("[]") ' + 'immediately\n' + 'after the name of the function, class, or type alias. The type\n' + 'parameters are accessible within the scope of the generic ' + 'object, but\n' + 'not elsewhere. Thus, after a declaration "def func[T](): pass", ' + 'the\n' + 'name "T" is not available in the module scope. Below, the ' + 'semantics of\n' + 'generic objects are described with more precision. The scope of ' + 'type\n' + 'parameters is modeled with a special function (technically, an\n' + 'annotation scope) that wraps the creation of the generic ' + 'object.\n' + '\n' + 'Generic functions, classes, and type aliases have a ' + '"__type_params__"\n' + 'attribute listing their type parameters.\n' + '\n' + 'Type parameters come in three kinds:\n' + '\n' + '* "typing.TypeVar", introduced by a plain name (e.g., "T").\n' + ' Semantically, this represents a single type to a type ' + 'checker.\n' + '\n' + '* "typing.TypeVarTuple", introduced by a name prefixed with a ' + 'single\n' + ' asterisk (e.g., "*Ts"). Semantically, this stands for a tuple ' + 'of any\n' + ' number of types.\n' + '\n' + '* "typing.ParamSpec", introduced by a name prefixed with two ' + 'asterisks\n' + ' (e.g., "**P"). Semantically, this stands for the parameters of ' + 'a\n' + ' callable.\n' + '\n' + '"typing.TypeVar" declarations can define *bounds* and ' + '*constraints*\n' + 'with a colon (":") followed by an expression. A single ' + 'expression\n' + 'after the colon indicates a bound (e.g. "T: int"). Semantically, ' + 'this\n' + 'means that the "typing.TypeVar" can only represent types that ' + 'are a\n' + 'subtype of this bound. A parenthesized tuple of expressions ' + 'after the\n' + 'colon indicates a set of constraints (e.g. "T: (str, bytes)"). ' + 'Each\n' + 'member of the tuple should be a type (again, this is not ' + 'enforced at\n' + 'runtime). Constrained type variables can only take on one of the ' + 'types\n' + 'in the list of constraints.\n' + '\n' + 'For "typing.TypeVar"s declared using the type parameter list ' + 'syntax,\n' + 'the bound and constraints are not evaluated when the generic ' + 'object is\n' + 'created, but only when the value is explicitly accessed through ' + 'the\n' + 'attributes "__bound__" and "__constraints__". To accomplish ' + 'this, the\n' + 'bounds or constraints are evaluated in a separate annotation ' + 'scope.\n' + '\n' + '"typing.TypeVarTuple"s and "typing.ParamSpec"s cannot have ' + 'bounds or\n' + 'constraints.\n' + '\n' + 'The following example indicates the full set of allowed type ' + 'parameter\n' + 'declarations:\n' + '\n' + ' def overly_generic[\n' + ' SimpleTypeVar,\n' + ' TypeVarWithBound: int,\n' + ' TypeVarWithConstraints: (str, bytes),\n' + ' *SimpleTypeVarTuple,\n' + ' **SimpleParamSpec,\n' + ' ](\n' + ' a: SimpleTypeVar,\n' + ' b: TypeVarWithBound,\n' + ' c: Callable[SimpleParamSpec, TypeVarWithConstraints],\n' + ' *d: SimpleTypeVarTuple,\n' + ' ): ...\n' + '\n' + '\n' + 'Generic functions\n' + '-----------------\n' + '\n' + 'Generic functions are declared as follows:\n' + '\n' + ' def func[T](arg: T): ...\n' + '\n' + 'This syntax is equivalent to:\n' + '\n' + ' annotation-def TYPE_PARAMS_OF_func():\n' + ' T = typing.TypeVar("T")\n' + ' def func(arg: T): ...\n' + ' func.__type_params__ = (T,)\n' + ' return func\n' + ' func = TYPE_PARAMS_OF_func()\n' + '\n' + 'Here "annotation-def" indicates an annotation scope, which is ' + 'not\n' + 'actually bound to any name at runtime. (One other liberty is ' + 'taken in\n' + 'the translation: the syntax does not go through attribute access ' + 'on\n' + 'the "typing" module, but creates an instance of ' + '"typing.TypeVar"\n' + 'directly.)\n' + '\n' + 'The annotations of generic functions are evaluated within the\n' + 'annotation scope used for declaring the type parameters, but ' + 'the\n' + 'function’s defaults and decorators are not.\n' + '\n' + 'The following example illustrates the scoping rules for these ' + 'cases,\n' + 'as well as for additional flavors of type parameters:\n' + '\n' + ' @decorator\n' + ' def func[T: int, *Ts, **P](*args: *Ts, arg: Callable[P, T] = ' + 'some_default):\n' + ' ...\n' + '\n' + 'Except for the lazy evaluation of the "TypeVar" bound, this is\n' + 'equivalent to:\n' + '\n' + ' DEFAULT_OF_arg = some_default\n' + '\n' + ' annotation-def TYPE_PARAMS_OF_func():\n' + '\n' + ' annotation-def BOUND_OF_T():\n' + ' return int\n' + ' # In reality, BOUND_OF_T() is evaluated only on demand.\n' + ' T = typing.TypeVar("T", bound=BOUND_OF_T())\n' + '\n' + ' Ts = typing.TypeVarTuple("Ts")\n' + ' P = typing.ParamSpec("P")\n' + '\n' + ' def func(*args: *Ts, arg: Callable[P, T] = ' + 'DEFAULT_OF_arg):\n' + ' ...\n' + '\n' + ' func.__type_params__ = (T, Ts, P)\n' + ' return func\n' + ' func = decorator(TYPE_PARAMS_OF_func())\n' + '\n' + 'The capitalized names like "DEFAULT_OF_arg" are not actually ' + 'bound at\n' + 'runtime.\n' + '\n' + '\n' + 'Generic classes\n' + '---------------\n' + '\n' + 'Generic classes are declared as follows:\n' + '\n' + ' class Bag[T]: ...\n' + '\n' + 'This syntax is equivalent to:\n' + '\n' + ' annotation-def TYPE_PARAMS_OF_Bag():\n' + ' T = typing.TypeVar("T")\n' + ' class Bag(typing.Generic[T]):\n' + ' __type_params__ = (T,)\n' + ' ...\n' + ' return Bag\n' + ' Bag = TYPE_PARAMS_OF_Bag()\n' + '\n' + 'Here again "annotation-def" (not a real keyword) indicates an\n' + 'annotation scope, and the name "TYPE_PARAMS_OF_Bag" is not ' + 'actually\n' + 'bound at runtime.\n' + '\n' + 'Generic classes implicitly inherit from "typing.Generic". The ' + 'base\n' + 'classes and keyword arguments of generic classes are evaluated ' + 'within\n' + 'the type scope for the type parameters, and decorators are ' + 'evaluated\n' + 'outside that scope. This is illustrated by this example:\n' + '\n' + ' @decorator\n' + ' class Bag(Base[T], arg=T): ...\n' + '\n' + 'This is equivalent to:\n' + '\n' + ' annotation-def TYPE_PARAMS_OF_Bag():\n' + ' T = typing.TypeVar("T")\n' + ' class Bag(Base[T], typing.Generic[T], arg=T):\n' + ' __type_params__ = (T,)\n' + ' ...\n' + ' return Bag\n' + ' Bag = decorator(TYPE_PARAMS_OF_Bag())\n' + '\n' + '\n' + 'Generic type aliases\n' + '--------------------\n' + '\n' + 'The "type" statement can also be used to create a generic type ' + 'alias:\n' + '\n' + ' type ListOrSet[T] = list[T] | set[T]\n' + '\n' + 'Except for the lazy evaluation of the value, this is equivalent ' + 'to:\n' + '\n' + ' annotation-def TYPE_PARAMS_OF_ListOrSet():\n' + ' T = typing.TypeVar("T")\n' + '\n' + ' annotation-def VALUE_OF_ListOrSet():\n' + ' return list[T] | set[T]\n' + ' # In reality, the value is lazily evaluated\n' + ' return typing.TypeAliasType("ListOrSet", ' + 'VALUE_OF_ListOrSet(), type_params=(T,))\n' + ' ListOrSet = TYPE_PARAMS_OF_ListOrSet()\n' + '\n' + 'Here, "annotation-def" (not a real keyword) indicates an ' + 'annotation\n' + 'scope. The capitalized names like "TYPE_PARAMS_OF_ListOrSet" are ' + 'not\n' + 'actually bound at runtime.\n' + '\n' '-[ Footnotes ]-\n' '\n' '[1] The exception is propagated to the invocation stack unless ' @@ -4533,7 +4762,7 @@ topics = {'assert': 'The "assert" statement\n' 'objects and\n' ' implements an "__eq__()" method, it should not ' 'implement\n' - ' "__hash__()", since the implementation of hashable ' + ' "__hash__()", since the implementation of *hashable* ' 'collections\n' ' requires that a key’s hash value is immutable (if the ' 'object’s hash\n' @@ -4595,8 +4824,7 @@ topics = {'assert': 'The "assert" statement\n' 'case\n' ' performance of a dict insertion, O(n^2) complexity. ' 'See\n' - ' http://www.ocert.org/advisories/ocert-2011-003.html ' - 'for\n' + ' http://ocert.org/advisories/ocert-2011-003.html for\n' ' details.Changing hash values affects the iteration ' 'order of sets.\n' ' Python has never made guarantees about this ordering ' @@ -4659,20 +4887,41 @@ topics = {'assert': 'The "assert" statement\n' 'traces of\n' ' Python programs.\n' '\n' - 'The debugger’s prompt is "(Pdb)". Typical usage to run a program ' - 'under\n' - 'control of the debugger is:\n' + 'The typical usage to break into the debugger is to insert:\n' '\n' - ' >>> import pdb\n' - ' >>> import mymodule\n' - " >>> pdb.run('mymodule.test()')\n" - ' > <string>(0)?()\n' - ' (Pdb) continue\n' - ' > <string>(1)?()\n' + ' import pdb; pdb.set_trace()\n' + '\n' + 'Or:\n' + '\n' + ' breakpoint()\n' + '\n' + 'at the location you want to break into the debugger, and then ' + 'run the\n' + 'program. You can then step through the code following this ' + 'statement,\n' + 'and continue running without the debugger using the "continue"\n' + 'command.\n' + '\n' + 'New in version 3.7: The built-in "breakpoint()", when called ' + 'with\n' + 'defaults, can be used instead of "import pdb; pdb.set_trace()".\n' + '\n' + ' def double(x):\n' + ' breakpoint()\n' + ' return x * 2\n' + ' val = 3\n' + ' print(f"{val} * 2 is {double(val)}")\n' + '\n' + 'The debugger’s prompt is "(Pdb)", which is the indicator that ' + 'you are\n' + 'in debug mode:\n' + '\n' + ' > ...(3)double()\n' + ' -> return x * 2\n' + ' (Pdb) p x\n' + ' 3\n' ' (Pdb) continue\n' - " NameError: 'spam'\n" - ' > <string>(1)?()\n' - ' (Pdb)\n' + ' 3 * 2 is 6\n' '\n' 'Changed in version 3.3: Tab-completion via the "readline" module ' 'is\n' @@ -4680,13 +4929,12 @@ topics = {'assert': 'The "assert" statement\n' 'global\n' 'and local names are offered as arguments of the "p" command.\n' '\n' - '"pdb.py" can also be invoked as a script to debug other ' - 'scripts. For\n' - 'example:\n' + 'You can also invoke "pdb" from the command line to debug other\n' + 'scripts. For example:\n' '\n' - ' python3 -m pdb myscript.py\n' + ' python -m pdb myscript.py\n' '\n' - 'When invoked as a script, pdb will automatically enter ' + 'When invoked as a module, pdb will automatically enter ' 'post-mortem\n' 'debugging if the program being debugged exits abnormally. After ' 'post-\n' @@ -4698,47 +4946,43 @@ topics = {'assert': 'The "assert" statement\n' 'the\n' 'debugger upon program’s exit.\n' '\n' - 'New in version 3.2: "pdb.py" now accepts a "-c" option that ' - 'executes\n' - 'commands as if given in a ".pdbrc" file, see Debugger Commands.\n' + 'New in version 3.2: "-c" option is introduced to execute ' + 'commands as\n' + 'if given in a ".pdbrc" file, see Debugger Commands.\n' '\n' - 'New in version 3.7: "pdb.py" now accepts a "-m" option that ' - 'execute\n' - 'modules similar to the way "python3 -m" does. As with a script, ' - 'the\n' - 'debugger will pause execution just before the first line of the\n' - 'module.\n' - '\n' - 'The typical usage to break into the debugger is to insert:\n' - '\n' - ' import pdb; pdb.set_trace()\n' + 'New in version 3.7: "-m" option is introduced to execute ' + 'modules\n' + 'similar to the way "python -m" does. As with a script, the ' + 'debugger\n' + 'will pause execution just before the first line of the module.\n' '\n' - 'at the location you want to break into the debugger, and then ' - 'run the\n' - 'program. You can then step through the code following this ' - 'statement,\n' - 'and continue running without the debugger using the "continue"\n' - 'command.\n' + 'Typical usage to execute a statement under control of the ' + 'debugger is:\n' '\n' - 'New in version 3.7: The built-in "breakpoint()", when called ' - 'with\n' - 'defaults, can be used instead of "import pdb; pdb.set_trace()".\n' + ' >>> import pdb\n' + ' >>> def f(x):\n' + ' ... print(1 / x)\n' + ' >>> pdb.run("f(2)")\n' + ' > <string>(1)<module>()\n' + ' (Pdb) continue\n' + ' 0.5\n' + ' >>>\n' '\n' 'The typical usage to inspect a crashed program is:\n' '\n' ' >>> import pdb\n' - ' >>> import mymodule\n' - ' >>> mymodule.test()\n' + ' >>> def f(x):\n' + ' ... print(1 / x)\n' + ' ...\n' + ' >>> f(0)\n' ' Traceback (most recent call last):\n' ' File "<stdin>", line 1, in <module>\n' - ' File "./mymodule.py", line 4, in test\n' - ' test2()\n' - ' File "./mymodule.py", line 3, in test2\n' - ' print(spam)\n' - ' NameError: spam\n' + ' File "<stdin>", line 2, in f\n' + ' ZeroDivisionError: division by zero\n' ' >>> pdb.pm()\n' - ' > ./mymodule.py(3)test2()\n' - ' -> print(spam)\n' + ' > <stdin>(2)f()\n' + ' (Pdb) p x\n' + ' 0\n' ' (Pdb)\n' '\n' 'The module defines the following functions; each enters the ' @@ -4768,8 +5012,8 @@ topics = {'assert': 'The "assert" statement\n' 'object)\n' ' under debugger control. When "runeval()" returns, it returns ' 'the\n' - ' value of the expression. Otherwise this function is similar ' - 'to\n' + ' value of the *expression*. Otherwise this function is ' + 'similar to\n' ' "run()".\n' '\n' 'pdb.runcall(function, *args, **kwds)\n' @@ -4922,6 +5166,29 @@ topics = {'assert': 'The "assert" statement\n' 'implicit\n' 'string concatenation "\';\'\';\'" or "";"";"".\n' '\n' + 'To set a temporary global variable, use a *convenience ' + 'variable*. A\n' + '*convenience variable* is a variable whose name starts with ' + '"$". For\n' + 'example, "$foo = 1" sets a global variable "$foo" which you can ' + 'use in\n' + 'the debugger session. The *convenience variables* are cleared ' + 'when\n' + 'the program resumes execution so it’s less likely to interfere ' + 'with\n' + 'your program compared to using normal variables like "foo = 1".\n' + '\n' + 'There are three preset *convenience variables*:\n' + '\n' + '* "$_frame": the current frame you are debugging\n' + '\n' + '* "$_retval": the return value if the frame is returning\n' + '\n' + '* "$_exception": the exception if the frame is raising an ' + 'exception\n' + '\n' + 'New in version 3.12.\n' + '\n' 'If a file ".pdbrc" exists in the user’s home directory or in ' 'the\n' 'current directory, it is read with "\'utf-8\'" encoding and ' @@ -4957,9 +5224,9 @@ topics = {'assert': 'The "assert" statement\n' '\n' ' Print a stack trace, with the most recent frame at the ' 'bottom. An\n' - ' arrow indicates the current frame, which determines the ' - 'context of\n' - ' most commands.\n' + ' arrow (">") indicates the current frame, which determines ' + 'the\n' + ' context of most commands.\n' '\n' 'd(own) [count]\n' '\n' @@ -5015,7 +5282,7 @@ topics = {'assert': 'The "assert" statement\n' 'first\n' ' ask confirmation).\n' '\n' - 'disable [bpnumber ...]\n' + 'disable bpnumber [bpnumber ...]\n' '\n' ' Disable the breakpoints given as a space separated list of\n' ' breakpoint numbers. Disabling a breakpoint means it cannot ' @@ -5024,21 +5291,22 @@ topics = {'assert': 'The "assert" statement\n' 'breakpoint, it\n' ' remains in the list of breakpoints and can be (re-)enabled.\n' '\n' - 'enable [bpnumber ...]\n' + 'enable bpnumber [bpnumber ...]\n' '\n' ' Enable the breakpoints specified.\n' '\n' 'ignore bpnumber [count]\n' '\n' ' Set the ignore count for the given breakpoint number. If ' - 'count is\n' - ' omitted, the ignore count is set to 0. A breakpoint becomes ' - 'active\n' - ' when the ignore count is zero. When non-zero, the count is\n' - ' decremented each time the breakpoint is reached and the ' - 'breakpoint\n' - ' is not disabled and any associated condition evaluates to ' - 'true.\n' + '*count*\n' + ' is omitted, the ignore count is set to 0. A breakpoint ' + 'becomes\n' + ' active when the ignore count is zero. When non-zero, the ' + '*count*\n' + ' is decremented each time the breakpoint is reached and the\n' + ' breakpoint is not disabled and any associated condition ' + 'evaluates\n' + ' to true.\n' '\n' 'condition bpnumber [condition]\n' '\n' @@ -5088,7 +5356,7 @@ topics = {'assert': 'The "assert" statement\n' ' breakpoint—which could have its own command list, leading to\n' ' ambiguities about which list to execute.\n' '\n' - ' If you use the ‘silent’ command in the command list, the ' + ' If you use the "silent" command in the command list, the ' 'usual\n' ' message about stopping at a breakpoint is not printed. This ' 'may be\n' @@ -5123,11 +5391,10 @@ topics = {'assert': 'The "assert" statement\n' 'number\n' ' greater than the current one is reached.\n' '\n' - ' With a line number, continue execution until a line with a ' - 'number\n' - ' greater or equal to that is reached. In both cases, also ' - 'stop when\n' - ' the current frame returns.\n' + ' With *lineno*, continue execution until a line with a number\n' + ' greater or equal to *lineno* is reached. In both cases, also ' + 'stop\n' + ' when the current frame returns.\n' '\n' ' Changed in version 3.2: Allow giving an explicit line ' 'number.\n' @@ -5187,13 +5454,14 @@ topics = {'assert': 'The "assert" statement\n' '\n' 'a(rgs)\n' '\n' - ' Print the argument list of the current function.\n' + ' Print the arguments of the current function and their ' + 'current\n' + ' values.\n' '\n' 'p expression\n' '\n' - ' Evaluate the *expression* in the current context and print ' - 'its\n' - ' value.\n' + ' Evaluate *expression* in the current context and print its ' + 'value.\n' '\n' ' Note:\n' '\n' @@ -5203,37 +5471,85 @@ topics = {'assert': 'The "assert" statement\n' '\n' 'pp expression\n' '\n' - ' Like the "p" command, except the value of the expression is ' + ' Like the "p" command, except the value of *expression* is ' 'pretty-\n' ' printed using the "pprint" module.\n' '\n' 'whatis expression\n' '\n' - ' Print the type of the *expression*.\n' + ' Print the type of *expression*.\n' '\n' 'source expression\n' '\n' - ' Try to get source code for the given object and display it.\n' + ' Try to get source code of *expression* and display it.\n' '\n' ' New in version 3.2.\n' '\n' 'display [expression]\n' '\n' - ' Display the value of the expression if it changed, each time\n' + ' Display the value of *expression* if it changed, each time\n' ' execution stops in the current frame.\n' '\n' - ' Without expression, list all display expressions for the ' + ' Without *expression*, list all display expressions for the ' 'current\n' ' frame.\n' '\n' + ' Note:\n' + '\n' + ' Display evaluates *expression* and compares to the result ' + 'of the\n' + ' previous evaluation of *expression*, so when the result is\n' + ' mutable, display may not be able to pick up the changes.\n' + '\n' + ' Example:\n' + '\n' + ' lst = []\n' + ' breakpoint()\n' + ' pass\n' + ' lst.append(1)\n' + ' print(lst)\n' + '\n' + ' Display won’t realize "lst" has been changed because the ' + 'result of\n' + ' evaluation is modified in place by "lst.append(1)" before ' + 'being\n' + ' compared:\n' + '\n' + ' > example.py(3)<module>()\n' + ' -> pass\n' + ' (Pdb) display lst\n' + ' display lst: []\n' + ' (Pdb) n\n' + ' > example.py(4)<module>()\n' + ' -> lst.append(1)\n' + ' (Pdb) n\n' + ' > example.py(5)<module>()\n' + ' -> print(lst)\n' + ' (Pdb)\n' + '\n' + ' You can do some tricks with copy mechanism to make it work:\n' + '\n' + ' > example.py(3)<module>()\n' + ' -> pass\n' + ' (Pdb) display lst[:]\n' + ' display lst[:]: []\n' + ' (Pdb) n\n' + ' > example.py(4)<module>()\n' + ' -> lst.append(1)\n' + ' (Pdb) n\n' + ' > example.py(5)<module>()\n' + ' -> print(lst)\n' + ' display lst[:]: [1] [old: []]\n' + ' (Pdb)\n' + '\n' ' New in version 3.2.\n' '\n' 'undisplay [expression]\n' '\n' - ' Do not display the expression any more in the current frame.\n' - ' Without expression, clear all display expressions for the ' - 'current\n' - ' frame.\n' + ' Do not display *expression* anymore in the current frame. ' + 'Without\n' + ' *expression*, clear all display expressions for the current ' + 'frame.\n' '\n' ' New in version 3.2.\n' '\n' @@ -5249,16 +5565,16 @@ topics = {'assert': 'The "assert" statement\n' '\n' 'alias [name [command]]\n' '\n' - ' Create an alias called *name* that executes *command*. The ' - 'command\n' - ' must *not* be enclosed in quotes. Replaceable parameters can ' - 'be\n' - ' indicated by "%1", "%2", and so on, while "%*" is replaced by ' - 'all\n' - ' the parameters. If no command is given, the current alias ' - 'for\n' - ' *name* is shown. If no arguments are given, all aliases are ' - 'listed.\n' + ' Create an alias called *name* that executes *command*. The\n' + ' *command* must *not* be enclosed in quotes. Replaceable ' + 'parameters\n' + ' can be indicated by "%1", "%2", and so on, while "%*" is ' + 'replaced\n' + ' by all the parameters. If *command* is omitted, the current ' + 'alias\n' + ' for *name* is shown. If no arguments are given, all aliases ' + 'are\n' + ' listed.\n' '\n' ' Aliases may be nested and can contain anything that can be ' 'legally\n' @@ -5277,14 +5593,14 @@ topics = {'assert': 'The "assert" statement\n' ' in the ".pdbrc" file):\n' '\n' ' # Print instance variables (usage "pi classInst")\n' - ' alias pi for k in %1.__dict__.keys(): ' - 'print("%1.",k,"=",%1.__dict__[k])\n' + ' alias pi for k in %1.__dict__.keys(): print(f"%1.{k} = ' + '{%1.__dict__[k]}")\n' ' # Print instance variables in self\n' ' alias ps pi self\n' '\n' 'unalias name\n' '\n' - ' Delete the specified alias.\n' + ' Delete the specified alias *name*.\n' '\n' '! statement\n' '\n' @@ -5292,11 +5608,14 @@ topics = {'assert': 'The "assert" statement\n' 'current\n' ' stack frame. The exclamation point can be omitted unless the ' 'first\n' - ' word of the statement resembles a debugger command. To set ' - 'a\n' - ' global variable, you can prefix the assignment command with ' - 'a\n' - ' "global" statement on the same line, e.g.:\n' + ' word of the statement resembles a debugger command, e.g.:\n' + '\n' + ' (Pdb) ! n=42\n' + ' (Pdb)\n' + '\n' + ' To set a global variable, you can prefix the assignment ' + 'command\n' + ' with a "global" statement on the same line, e.g.:\n' '\n' " (Pdb) global list_options; list_options = ['-l']\n" ' (Pdb)\n' @@ -5304,12 +5623,13 @@ topics = {'assert': 'The "assert" statement\n' 'run [args ...]\n' 'restart [args ...]\n' '\n' - ' Restart the debugged Python program. If an argument is ' - 'supplied,\n' - ' it is split with "shlex" and the result is used as the new\n' - ' "sys.argv". History, breakpoints, actions and debugger ' - 'options are\n' - ' preserved. "restart" is an alias for "run".\n' + ' Restart the debugged Python program. If *args* is supplied, ' + 'it is\n' + ' split with "shlex" and the result is used as the new ' + '"sys.argv".\n' + ' History, breakpoints, actions and debugger options are ' + 'preserved.\n' + ' "restart" is an alias for "run".\n' '\n' 'q(uit)\n' '\n' @@ -5318,15 +5638,16 @@ topics = {'assert': 'The "assert" statement\n' '\n' 'debug code\n' '\n' - ' Enter a recursive debugger that steps through the code ' - 'argument\n' - ' (which is an arbitrary expression or statement to be executed ' - 'in\n' - ' the current environment).\n' + ' Enter a recursive debugger that steps through *code* (which ' + 'is an\n' + ' arbitrary expression or statement to be executed in the ' + 'current\n' + ' environment).\n' '\n' 'retval\n' '\n' - ' Print the return value for the last return of a function.\n' + ' Print the return value for the last return of the current ' + 'function.\n' '\n' '-[ Footnotes ]-\n' '\n' @@ -5365,30 +5686,31 @@ topics = {'assert': 'The "assert" statement\n' 'dict': 'Dictionary displays\n' '*******************\n' '\n' - 'A dictionary display is a possibly empty series of key/datum pairs\n' - 'enclosed in curly braces:\n' + 'A dictionary display is a possibly empty series of dict items\n' + '(key/value pairs) enclosed in curly braces:\n' '\n' - ' dict_display ::= "{" [key_datum_list | dict_comprehension] ' + ' dict_display ::= "{" [dict_item_list | dict_comprehension] ' '"}"\n' - ' key_datum_list ::= key_datum ("," key_datum)* [","]\n' - ' key_datum ::= expression ":" expression | "**" or_expr\n' + ' dict_item_list ::= dict_item ("," dict_item)* [","]\n' + ' dict_item ::= expression ":" expression | "**" or_expr\n' ' dict_comprehension ::= expression ":" expression comp_for\n' '\n' 'A dictionary display yields a new dictionary object.\n' '\n' - 'If a comma-separated sequence of key/datum pairs is given, they are\n' + 'If a comma-separated sequence of dict items is given, they are\n' 'evaluated from left to right to define the entries of the ' 'dictionary:\n' 'each key object is used as a key into the dictionary to store the\n' - 'corresponding datum. This means that you can specify the same key\n' - 'multiple times in the key/datum list, and the final dictionary’s ' + 'corresponding value. This means that you can specify the same key\n' + 'multiple times in the dict item list, and the final dictionary’s ' 'value\n' 'for that key will be the last one given.\n' '\n' 'A double asterisk "**" denotes *dictionary unpacking*. Its operand\n' 'must be a *mapping*. Each mapping item is added to the new\n' - 'dictionary. Later values replace values already set by earlier\n' - 'key/datum pairs and earlier dictionary unpackings.\n' + 'dictionary. Later values replace values already set by earlier ' + 'dict\n' + 'items and earlier dictionary unpackings.\n' '\n' 'New in version 3.5: Unpacking into dictionary displays, originally\n' 'proposed by **PEP 448**.\n' @@ -5404,7 +5726,7 @@ topics = {'assert': 'The "assert" statement\n' 'Restrictions on the types of the key values are listed earlier in\n' 'section The standard type hierarchy. (To summarize, the key type\n' 'should be *hashable*, which excludes all mutable objects.) Clashes\n' - 'between duplicate keys are not detected; the last datum (textually\n' + 'between duplicate keys are not detected; the last value (textually\n' 'rightmost in the display) stored for a given key value prevails.\n' '\n' 'Changed in version 3.8: Prior to Python 3.8, in dict ' @@ -5605,6 +5927,10 @@ topics = {'assert': 'The "assert" statement\n' '\n' '* "import" statements.\n' '\n' + '* "type" statements.\n' + '\n' + '* type parameter lists.\n' + '\n' 'The "import" statement of the form "from ... import *" binds ' 'all names\n' 'defined in the imported module, except those beginning with an\n' @@ -5711,7 +6037,9 @@ topics = {'assert': 'The "assert" statement\n' 'scope.\n' '"SyntaxError" is raised at compile time if the given name does ' 'not\n' - 'exist in any enclosing function scope.\n' + 'exist in any enclosing function scope. Type parameters cannot ' + 'be\n' + 'rebound with the "nonlocal" statement.\n' '\n' 'The namespace for a module is automatically created the first ' 'time a\n' @@ -5734,17 +6062,162 @@ topics = {'assert': 'The "assert" statement\n' 'the class. The scope of names defined in a class block is ' 'limited to\n' 'the class block; it does not extend to the code blocks of ' - 'methods –\n' - 'this includes comprehensions and generator expressions since ' - 'they are\n' - 'implemented using a function scope. This means that the ' - 'following\n' - 'will fail:\n' + 'methods.\n' + 'This includes comprehensions and generator expressions, but it ' + 'does\n' + 'not include annotation scopes, which have access to their ' + 'enclosing\n' + 'class scopes. This means that the following will fail:\n' '\n' ' class A:\n' ' a = 42\n' ' b = list(a + i for i in range(10))\n' '\n' + 'However, the following will succeed:\n' + '\n' + ' class A:\n' + ' type Alias = Nested\n' + ' class Nested: pass\n' + '\n' + " print(A.Alias.__value__) # <type 'A.Nested'>\n" + '\n' + '\n' + 'Annotation scopes\n' + '-----------------\n' + '\n' + 'Type parameter lists and "type" statements introduce ' + '*annotation\n' + 'scopes*, which behave mostly like function scopes, but with ' + 'some\n' + 'exceptions discussed below. *Annotations* currently do not use\n' + 'annotation scopes, but they are expected to use annotation ' + 'scopes in\n' + 'Python 3.13 when **PEP 649** is implemented.\n' + '\n' + 'Annotation scopes are used in the following contexts:\n' + '\n' + '* Type parameter lists for generic type aliases.\n' + '\n' + '* Type parameter lists for generic functions. A generic ' + 'function’s\n' + ' annotations are executed within the annotation scope, but ' + 'its\n' + ' defaults and decorators are not.\n' + '\n' + '* Type parameter lists for generic classes. A generic class’s ' + 'base\n' + ' classes and keyword arguments are executed within the ' + 'annotation\n' + ' scope, but its decorators are not.\n' + '\n' + '* The bounds and constraints for type variables (lazily ' + 'evaluated).\n' + '\n' + '* The value of type aliases (lazily evaluated).\n' + '\n' + 'Annotation scopes differ from function scopes in the following ' + 'ways:\n' + '\n' + '* Annotation scopes have access to their enclosing class ' + 'namespace. If\n' + ' an annotation scope is immediately within a class scope, or ' + 'within\n' + ' another annotation scope that is immediately within a class ' + 'scope,\n' + ' the code in the annotation scope can use names defined in the ' + 'class\n' + ' scope as if it were executed directly within the class body. ' + 'This\n' + ' contrasts with regular functions defined within classes, ' + 'which\n' + ' cannot access names defined in the class scope.\n' + '\n' + '* Expressions in annotation scopes cannot contain "yield", ' + '"yield\n' + ' from", "await", or ":=" expressions. (These expressions are ' + 'allowed\n' + ' in other scopes contained within the annotation scope.)\n' + '\n' + '* Names defined in annotation scopes cannot be rebound with ' + '"nonlocal"\n' + ' statements in inner scopes. This includes only type ' + 'parameters, as\n' + ' no other syntactic elements that can appear within annotation ' + 'scopes\n' + ' can introduce new names.\n' + '\n' + '* While annotation scopes have an internal name, that name is ' + 'not\n' + ' reflected in the *__qualname__* of objects defined within the ' + 'scope.\n' + ' Instead, the "__qualname__" of such objects is as if the ' + 'object were\n' + ' defined in the enclosing scope.\n' + '\n' + 'New in version 3.12: Annotation scopes were introduced in ' + 'Python 3.12\n' + 'as part of **PEP 695**.\n' + '\n' + '\n' + 'Lazy evaluation\n' + '---------------\n' + '\n' + 'The values of type aliases created through the "type" statement ' + 'are\n' + '*lazily evaluated*. The same applies to the bounds and ' + 'constraints of\n' + 'type variables created through the type parameter syntax. This ' + 'means\n' + 'that they are not evaluated when the type alias or type ' + 'variable is\n' + 'created. Instead, they are only evaluated when doing so is ' + 'necessary\n' + 'to resolve an attribute access.\n' + '\n' + 'Example:\n' + '\n' + ' >>> type Alias = 1/0\n' + ' >>> Alias.__value__\n' + ' Traceback (most recent call last):\n' + ' ...\n' + ' ZeroDivisionError: division by zero\n' + ' >>> def func[T: 1/0](): pass\n' + ' >>> T = func.__type_params__[0]\n' + ' >>> T.__bound__\n' + ' Traceback (most recent call last):\n' + ' ...\n' + ' ZeroDivisionError: division by zero\n' + '\n' + 'Here the exception is raised only when the "__value__" ' + 'attribute of\n' + 'the type alias or the "__bound__" attribute of the type ' + 'variable is\n' + 'accessed.\n' + '\n' + 'This behavior is primarily useful for references to types that ' + 'have\n' + 'not yet been defined when the type alias or type variable is ' + 'created.\n' + 'For example, lazy evaluation enables creation of mutually ' + 'recursive\n' + 'type aliases:\n' + '\n' + ' from typing import Literal\n' + '\n' + ' type SimpleExpr = int | Parenthesized\n' + ' type Parenthesized = tuple[Literal["("], Expr, ' + 'Literal[")"]]\n' + ' type Expr = SimpleExpr | tuple[SimpleExpr, Literal["+", ' + '"-"], Expr]\n' + '\n' + 'Lazily evaluated values are evaluated in annotation scope, ' + 'which means\n' + 'that names that appear inside the lazily evaluated value are ' + 'looked up\n' + 'as if they were used in the immediately enclosing scope.\n' + '\n' + 'New in version 3.12.\n' + '\n' '\n' 'Builtins and restricted execution\n' '---------------------------------\n' @@ -6049,22 +6522,26 @@ topics = {'assert': 'The "assert" statement\n' 'positional\n' 'argument, and if it’s a keyword, it refers to a named ' 'keyword\n' - 'argument. If the numerical arg_names in a format string ' - 'are 0, 1, 2,\n' - '… in sequence, they can all be omitted (not just some) and ' - 'the numbers\n' - '0, 1, 2, … will be automatically inserted in that order. ' - 'Because\n' - '*arg_name* is not quote-delimited, it is not possible to ' - 'specify\n' - 'arbitrary dictionary keys (e.g., the strings "\'10\'" or ' - '"\':-]\'") within\n' - 'a format string. The *arg_name* can be followed by any ' - 'number of index\n' - 'or attribute expressions. An expression of the form ' - '"\'.name\'" selects\n' - 'the named attribute using "getattr()", while an expression ' - 'of the form\n' + 'argument. An *arg_name* is treated as a number if a call ' + 'to\n' + '"str.isdecimal()" on the string would return true. If the ' + 'numerical\n' + 'arg_names in a format string are 0, 1, 2, … in sequence, ' + 'they can all\n' + 'be omitted (not just some) and the numbers 0, 1, 2, … will ' + 'be\n' + 'automatically inserted in that order. Because *arg_name* is ' + 'not quote-\n' + 'delimited, it is not possible to specify arbitrary ' + 'dictionary keys\n' + '(e.g., the strings "\'10\'" or "\':-]\'") within a format ' + 'string. The\n' + '*arg_name* can be followed by any number of index or ' + 'attribute\n' + 'expressions. An expression of the form "\'.name\'" selects ' + 'the named\n' + 'attribute using "getattr()", while an expression of the ' + 'form\n' '"\'[index]\'" does an index lookup using "__getitem__()".\n' '\n' 'Changed in version 3.1: The positional argument specifiers ' @@ -6179,7 +6656,8 @@ topics = {'assert': 'The "assert" statement\n' 'The general form of a *standard format specifier* is:\n' '\n' ' format_spec ::= ' - '[[fill]align][sign][z][#][0][width][grouping_option][.precision][type]\n' + '[[fill]align][sign]["z"]["#"]["0"][width][grouping_option]["." ' + 'precision][type]\n' ' fill ::= <any character>\n' ' align ::= "<" | ">" | "=" | "^"\n' ' sign ::= "+" | "-" | " "\n' @@ -6784,8 +7262,8 @@ topics = {'assert': 'The "assert" statement\n' '(see\n' 'section The standard type hierarchy):\n' '\n' - ' funcdef ::= [decorators] "def" funcname "(" ' - '[parameter_list] ")"\n' + ' funcdef ::= [decorators] "def" funcname ' + '[type_params] "(" [parameter_list] ")"\n' ' ["->" expression] ":" suite\n' ' decorators ::= decorator+\n' ' decorator ::= "@" assignment_expression ' @@ -6847,6 +7325,19 @@ topics = {'assert': 'The "assert" statement\n' '"assignment_expression". Previously, the grammar was much more\n' 'restrictive; see **PEP 614** for details.\n' '\n' + 'A list of type parameters may be given in square brackets ' + 'between the\n' + 'function’s name and the opening parenthesis for its parameter ' + 'list.\n' + 'This indicates to static type checkers that the function is ' + 'generic.\n' + 'At runtime, the type parameters can be retrieved from the ' + 'function’s\n' + '"__type_params__" attribute. See Generic functions for more.\n' + '\n' + 'Changed in version 3.12: Type parameter lists are new in Python ' + '3.12.\n' + '\n' 'When one or more *parameters* have the form *parameter* "="\n' '*expression*, the function is said to have “default parameter ' 'values.”\n' @@ -7160,8 +7651,8 @@ topics = {'assert': 'The "assert" statement\n' '\n' 'A non-normative HTML file listing all valid identifier ' 'characters for\n' - 'Unicode 14.0.0 can be found at\n' - 'https://www.unicode.org/Public/14.0.0/ucd/DerivedCoreProperties.txt\n' + 'Unicode 15.0.0 can be found at\n' + 'https://www.unicode.org/Public/15.0.0/ucd/DerivedCoreProperties.txt\n' '\n' '\n' 'Keywords\n' @@ -7189,19 +7680,24 @@ topics = {'assert': 'The "assert" statement\n' '\n' 'Some identifiers are only reserved under specific contexts. ' 'These are\n' - 'known as *soft keywords*. The identifiers "match", "case" ' - 'and "_" can\n' - 'syntactically act as keywords in contexts related to the ' - 'pattern\n' - 'matching statement, but this distinction is done at the ' - 'parser level,\n' - 'not when tokenizing.\n' + 'known as *soft keywords*. The identifiers "match", "case", ' + '"type" and\n' + '"_" can syntactically act as keywords in certain contexts, ' + 'but this\n' + 'distinction is done at the parser level, not when ' + 'tokenizing.\n' '\n' - 'As soft keywords, their use with pattern matching is possible ' - 'while\n' - 'still preserving compatibility with existing code that uses ' - '"match",\n' - '"case" and "_" as identifier names.\n' + 'As soft keywords, their use in the grammar is possible while ' + 'still\n' + 'preserving compatibility with existing code that uses these ' + 'names as\n' + 'identifier names.\n' + '\n' + '"match", "case", and "_" are used in the "match" statement. ' + '"type" is\n' + 'used in the "type" statement.\n' + '\n' + 'Changed in version 3.12: "type" is now a soft keyword.\n' '\n' '\n' 'Reserved classes of identifiers\n' @@ -7721,6 +8217,10 @@ topics = {'assert': 'The "assert" statement\n' '\n' '* "import" statements.\n' '\n' + '* "type" statements.\n' + '\n' + '* type parameter lists.\n' + '\n' 'The "import" statement of the form "from ... import *" binds all ' 'names\n' 'defined in the imported module, except those beginning with an\n' @@ -7820,7 +8320,8 @@ topics = {'assert': 'The "assert" statement\n' 'scope.\n' '"SyntaxError" is raised at compile time if the given name does ' 'not\n' - 'exist in any enclosing function scope.\n' + 'exist in any enclosing function scope. Type parameters cannot be\n' + 'rebound with the "nonlocal" statement.\n' '\n' 'The namespace for a module is automatically created the first time ' 'a\n' @@ -7842,30 +8343,168 @@ topics = {'assert': 'The "assert" statement\n' 'of\n' 'the class. The scope of names defined in a class block is limited ' 'to\n' - 'the class block; it does not extend to the code blocks of methods ' - '–\n' - 'this includes comprehensions and generator expressions since they ' - 'are\n' - 'implemented using a function scope. This means that the ' - 'following\n' - 'will fail:\n' + 'the class block; it does not extend to the code blocks of ' + 'methods.\n' + 'This includes comprehensions and generator expressions, but it ' + 'does\n' + 'not include annotation scopes, which have access to their ' + 'enclosing\n' + 'class scopes. This means that the following will fail:\n' '\n' ' class A:\n' ' a = 42\n' ' b = list(a + i for i in range(10))\n' '\n' + 'However, the following will succeed:\n' '\n' - 'Builtins and restricted execution\n' - '=================================\n' + ' class A:\n' + ' type Alias = Nested\n' + ' class Nested: pass\n' '\n' - '**CPython implementation detail:** Users should not touch\n' - '"__builtins__"; it is strictly an implementation detail. Users\n' - 'wanting to override values in the builtins namespace should ' - '"import"\n' - 'the "builtins" module and modify its attributes appropriately.\n' + " print(A.Alias.__value__) # <type 'A.Nested'>\n" '\n' - 'The builtins namespace associated with the execution of a code ' - 'block\n' + '\n' + 'Annotation scopes\n' + '=================\n' + '\n' + 'Type parameter lists and "type" statements introduce *annotation\n' + 'scopes*, which behave mostly like function scopes, but with some\n' + 'exceptions discussed below. *Annotations* currently do not use\n' + 'annotation scopes, but they are expected to use annotation scopes ' + 'in\n' + 'Python 3.13 when **PEP 649** is implemented.\n' + '\n' + 'Annotation scopes are used in the following contexts:\n' + '\n' + '* Type parameter lists for generic type aliases.\n' + '\n' + '* Type parameter lists for generic functions. A generic ' + 'function’s\n' + ' annotations are executed within the annotation scope, but its\n' + ' defaults and decorators are not.\n' + '\n' + '* Type parameter lists for generic classes. A generic class’s ' + 'base\n' + ' classes and keyword arguments are executed within the ' + 'annotation\n' + ' scope, but its decorators are not.\n' + '\n' + '* The bounds and constraints for type variables (lazily ' + 'evaluated).\n' + '\n' + '* The value of type aliases (lazily evaluated).\n' + '\n' + 'Annotation scopes differ from function scopes in the following ' + 'ways:\n' + '\n' + '* Annotation scopes have access to their enclosing class ' + 'namespace. If\n' + ' an annotation scope is immediately within a class scope, or ' + 'within\n' + ' another annotation scope that is immediately within a class ' + 'scope,\n' + ' the code in the annotation scope can use names defined in the ' + 'class\n' + ' scope as if it were executed directly within the class body. ' + 'This\n' + ' contrasts with regular functions defined within classes, which\n' + ' cannot access names defined in the class scope.\n' + '\n' + '* Expressions in annotation scopes cannot contain "yield", "yield\n' + ' from", "await", or ":=" expressions. (These expressions are ' + 'allowed\n' + ' in other scopes contained within the annotation scope.)\n' + '\n' + '* Names defined in annotation scopes cannot be rebound with ' + '"nonlocal"\n' + ' statements in inner scopes. This includes only type parameters, ' + 'as\n' + ' no other syntactic elements that can appear within annotation ' + 'scopes\n' + ' can introduce new names.\n' + '\n' + '* While annotation scopes have an internal name, that name is not\n' + ' reflected in the *__qualname__* of objects defined within the ' + 'scope.\n' + ' Instead, the "__qualname__" of such objects is as if the object ' + 'were\n' + ' defined in the enclosing scope.\n' + '\n' + 'New in version 3.12: Annotation scopes were introduced in Python ' + '3.12\n' + 'as part of **PEP 695**.\n' + '\n' + '\n' + 'Lazy evaluation\n' + '===============\n' + '\n' + 'The values of type aliases created through the "type" statement ' + 'are\n' + '*lazily evaluated*. The same applies to the bounds and constraints ' + 'of\n' + 'type variables created through the type parameter syntax. This ' + 'means\n' + 'that they are not evaluated when the type alias or type variable ' + 'is\n' + 'created. Instead, they are only evaluated when doing so is ' + 'necessary\n' + 'to resolve an attribute access.\n' + '\n' + 'Example:\n' + '\n' + ' >>> type Alias = 1/0\n' + ' >>> Alias.__value__\n' + ' Traceback (most recent call last):\n' + ' ...\n' + ' ZeroDivisionError: division by zero\n' + ' >>> def func[T: 1/0](): pass\n' + ' >>> T = func.__type_params__[0]\n' + ' >>> T.__bound__\n' + ' Traceback (most recent call last):\n' + ' ...\n' + ' ZeroDivisionError: division by zero\n' + '\n' + 'Here the exception is raised only when the "__value__" attribute ' + 'of\n' + 'the type alias or the "__bound__" attribute of the type variable ' + 'is\n' + 'accessed.\n' + '\n' + 'This behavior is primarily useful for references to types that ' + 'have\n' + 'not yet been defined when the type alias or type variable is ' + 'created.\n' + 'For example, lazy evaluation enables creation of mutually ' + 'recursive\n' + 'type aliases:\n' + '\n' + ' from typing import Literal\n' + '\n' + ' type SimpleExpr = int | Parenthesized\n' + ' type Parenthesized = tuple[Literal["("], Expr, Literal[")"]]\n' + ' type Expr = SimpleExpr | tuple[SimpleExpr, Literal["+", "-"], ' + 'Expr]\n' + '\n' + 'Lazily evaluated values are evaluated in annotation scope, which ' + 'means\n' + 'that names that appear inside the lazily evaluated value are ' + 'looked up\n' + 'as if they were used in the immediately enclosing scope.\n' + '\n' + 'New in version 3.12.\n' + '\n' + '\n' + 'Builtins and restricted execution\n' + '=================================\n' + '\n' + '**CPython implementation detail:** Users should not touch\n' + '"__builtins__"; it is strictly an implementation detail. Users\n' + 'wanting to override values in the builtins namespace should ' + '"import"\n' + 'the "builtins" module and modify its attributes appropriately.\n' + '\n' + 'The builtins namespace associated with the execution of a code ' + 'block\n' 'is actually found by looking up the name "__builtins__" in its ' 'global\n' 'namespace; this should be a dictionary or a module (in the latter ' @@ -9017,6 +9656,14 @@ topics = {'assert': 'The "assert" statement\n' '\n' ' New in version 3.3.\n' '\n' + 'definition.__type_params__\n' + '\n' + ' The type parameters of generic classes, functions, and ' + 'type\n' + ' aliases.\n' + '\n' + ' New in version 3.12.\n' + '\n' 'class.__mro__\n' '\n' ' This attribute is a tuple of classes that are considered ' @@ -9040,7 +9687,8 @@ topics = {'assert': 'The "assert" statement\n' ' still alive. The list is in definition order. Example:\n' '\n' ' >>> int.__subclasses__()\n' - " [<class 'bool'>]\n", + " [<class 'bool'>, <enum 'IntEnum'>, <flag 'IntFlag'>, " + "<class 're._constants._NamedIntConstant'>]\n", 'specialnames': 'Special method names\n' '********************\n' '\n' @@ -9453,7 +10101,7 @@ topics = {'assert': 'The "assert" statement\n' ' hashable collections. If a class defines mutable objects ' 'and\n' ' implements an "__eq__()" method, it should not implement\n' - ' "__hash__()", since the implementation of hashable ' + ' "__hash__()", since the implementation of *hashable* ' 'collections\n' ' requires that a key’s hash value is immutable (if the ' 'object’s hash\n' @@ -9513,8 +10161,7 @@ topics = {'assert': 'The "assert" statement\n' ' by carefully chosen inputs that exploit the worst case\n' ' performance of a dict insertion, O(n^2) complexity. ' 'See\n' - ' http://www.ocert.org/advisories/ocert-2011-003.html ' - 'for\n' + ' http://ocert.org/advisories/ocert-2011-003.html for\n' ' details.Changing hash values affects the iteration ' 'order of sets.\n' ' Python has never made guarantees about this ordering ' @@ -9932,9 +10579,7 @@ topics = {'assert': 'The "assert" statement\n' 'each\n' ' instance.\n' '\n' - '\n' - 'Notes on using *__slots__*\n' - '~~~~~~~~~~~~~~~~~~~~~~~~~~\n' + 'Notes on using *__slots__*:\n' '\n' '* When inheriting from a class without *__slots__*, the ' '"__dict__" and\n' @@ -9990,10 +10635,11 @@ topics = {'assert': 'The "assert" statement\n' 'future, a\n' ' check may be added to prevent this.\n' '\n' - '* Nonempty *__slots__* does not work for classes derived ' - 'from\n' - ' “variable-length” built-in types such as "int", "bytes" ' - 'and "tuple".\n' + '* "TypeError" will be raised if nonempty *__slots__* are ' + 'defined for a\n' + ' class derived from a ""variable-length" built-in type" ' + 'such as\n' + ' "int", "bytes", and "tuple".\n' '\n' '* Any non-string *iterable* may be assigned to *__slots__*.\n' '\n' @@ -10167,20 +10813,37 @@ topics = {'assert': 'The "assert" statement\n' 'Resolving MRO entries\n' '---------------------\n' '\n' - 'If a base that appears in class definition is not an ' + 'object.__mro_entries__(self, bases)\n' + '\n' + ' If a base that appears in a class definition is not an ' 'instance of\n' - '"type", then an "__mro_entries__" method is searched on it. ' - 'If found,\n' - 'it is called with the original bases tuple. This method must ' - 'return a\n' - 'tuple of classes that will be used instead of this base. The ' - 'tuple may\n' - 'be empty, in such case the original base is ignored.\n' + ' "type", then an "__mro_entries__()" method is searched on ' + 'the base.\n' + ' If an "__mro_entries__()" method is found, the base is ' + 'substituted\n' + ' with the result of a call to "__mro_entries__()" when ' + 'creating the\n' + ' class. The method is called with the original bases tuple ' + 'passed to\n' + ' the *bases* parameter, and must return a tuple of classes ' + 'that will\n' + ' be used instead of the base. The returned tuple may be ' + 'empty: in\n' + ' these cases, the original base is ignored.\n' '\n' 'See also:\n' '\n' - ' **PEP 560** - Core support for typing module and generic ' - 'types\n' + ' "types.resolve_bases()"\n' + ' Dynamically resolve bases that are not instances of ' + '"type".\n' + '\n' + ' "types.get_original_bases()"\n' + ' Retrieve a class’s “original bases” prior to ' + 'modifications by\n' + ' "__mro_entries__()".\n' + '\n' + ' **PEP 560**\n' + ' Core support for typing module and generic types.\n' '\n' '\n' 'Determining the appropriate metaclass\n' @@ -11156,6 +11819,61 @@ topics = {'assert': 'The "assert" statement\n' ' The specification for the Python "match" statement.\n' '\n' '\n' + 'Emulating buffer types\n' + '======================\n' + '\n' + 'The buffer protocol provides a way for Python objects to ' + 'expose\n' + 'efficient access to a low-level memory array. This protocol ' + 'is\n' + 'implemented by builtin types such as "bytes" and ' + '"memoryview", and\n' + 'third-party libraries may define additional buffer types.\n' + '\n' + 'While buffer types are usually implemented in C, it is also ' + 'possible\n' + 'to implement the protocol in Python.\n' + '\n' + 'object.__buffer__(self, flags)\n' + '\n' + ' Called when a buffer is requested from *self* (for ' + 'example, by the\n' + ' "memoryview" constructor). The *flags* argument is an ' + 'integer\n' + ' representing the kind of buffer requested, affecting for ' + 'example\n' + ' whether the returned buffer is read-only or writable.\n' + ' "inspect.BufferFlags" provides a convenient way to ' + 'interpret the\n' + ' flags. The method must return a "memoryview" object.\n' + '\n' + 'object.__release_buffer__(self, buffer)\n' + '\n' + ' Called when a buffer is no longer needed. The *buffer* ' + 'argument is\n' + ' a "memoryview" object that was previously returned by\n' + ' "__buffer__()". The method must release any resources ' + 'associated\n' + ' with the buffer. This method should return "None". Buffer ' + 'objects\n' + ' that do not need to perform any cleanup are not required ' + 'to\n' + ' implement this method.\n' + '\n' + 'New in version 3.12.\n' + '\n' + 'See also:\n' + '\n' + ' **PEP 688** - Making the buffer protocol accessible in ' + 'Python\n' + ' Introduces the Python "__buffer__" and ' + '"__release_buffer__"\n' + ' methods.\n' + '\n' + ' "collections.abc.Buffer"\n' + ' ABC for buffer types.\n' + '\n' + '\n' 'Special method lookup\n' '=====================\n' '\n' @@ -11303,8 +12021,8 @@ topics = {'assert': 'The "assert" statement\n' ' "casefold()" converts it to ""ss"".\n' '\n' ' The casefolding algorithm is described in section 3.13 ' - 'of the\n' - ' Unicode Standard.\n' + '‘Default\n' + ' Case Folding’ of the Unicode Standard.\n' '\n' ' New in version 3.3.\n' '\n' @@ -11521,9 +12239,10 @@ topics = {'assert': 'The "assert" statement\n' 'property\n' ' being one of “Lm”, “Lt”, “Lu”, “Ll”, or “Lo”. Note ' 'that this is\n' - ' different from the “Alphabetic” property defined in the ' - 'Unicode\n' - ' Standard.\n' + ' different from the Alphabetic property defined in the ' + 'section 4.10\n' + ' ‘Letters, Alphabetic, and Ideographic’ of the Unicode ' + 'Standard.\n' '\n' 'str.isascii()\n' '\n' @@ -11570,9 +12289,9 @@ topics = {'assert': 'The "assert" statement\n' 'according to the\n' ' language definition, section Identifiers and keywords.\n' '\n' - ' Call "keyword.iskeyword()" to test whether string "s" ' - 'is a reserved\n' - ' identifier, such as "def" and "class".\n' + ' "keyword.iskeyword()" can be used to test whether ' + 'string "s" is a\n' + ' reserved identifier, such as "def" and "class".\n' '\n' ' Example:\n' '\n' @@ -11695,8 +12414,8 @@ topics = {'assert': 'The "assert" statement\n' ' converted to lowercase.\n' '\n' ' The lowercasing algorithm used is described in section ' - '3.13 of the\n' - ' Unicode Standard.\n' + '3.13\n' + ' ‘Default Case Folding’ of the Unicode Standard.\n' '\n' 'str.lstrip([chars])\n' '\n' @@ -12162,8 +12881,8 @@ topics = {'assert': 'The "assert" statement\n' ' uppercase), but e.g. “Lt” (Letter, titlecase).\n' '\n' ' The uppercasing algorithm used is described in section ' - '3.13 of the\n' - ' Unicode Standard.\n' + '3.13\n' + ' ‘Default Case Folding’ of the Unicode Standard.\n' '\n' 'str.zfill(width)\n' '\n' @@ -12232,12 +12951,15 @@ topics = {'assert': 'The "assert" statement\n' 'single quotes ("\'") or double quotes ("""). They can also be ' 'enclosed\n' 'in matching groups of three single or double quotes (these are\n' - 'generally referred to as *triple-quoted strings*). The ' - 'backslash\n' - '("\\") character is used to escape characters that otherwise have ' - 'a\n' - 'special meaning, such as newline, backslash itself, or the quote\n' + 'generally referred to as *triple-quoted strings*). The backslash ' + '("\\")\n' + 'character is used to give special meaning to otherwise ordinary\n' + 'characters like "n", which means ‘newline’ when escaped ("\\n"). ' + 'It can\n' + 'also be used to escape characters that otherwise have a special\n' + 'meaning, such as newline, backslash itself, or the quote ' 'character.\n' + 'See escape sequences below for examples.\n' '\n' 'Bytes literals are always prefixed with "\'b\'" or "\'B\'"; they ' 'produce\n' @@ -12284,77 +13006,81 @@ topics = {'assert': 'The "assert" statement\n' 'the\n' 'literal, i.e. either "\'" or """.)\n' '\n' + '\n' + 'Escape sequences\n' + '================\n' + '\n' 'Unless an "\'r\'" or "\'R\'" prefix is present, escape sequences ' 'in string\n' 'and bytes literals are interpreted according to rules similar to ' 'those\n' 'used by Standard C. The recognized escape sequences are:\n' '\n' - '+-------------------+-----------------------------------+---------+\n' - '| Escape Sequence | Meaning | Notes ' - '|\n' - '|===================|===================================|=========|\n' - '| "\\"<newline> | Backslash and newline ignored | ' - '(1) |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\\\" | Backslash ("\\") ' - '| |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\\'" | Single quote ("\'") ' - '| |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\"" | Double quote (""") ' + '+---------------------------+-----------------------------------+---------+\n' + '| Escape Sequence | Meaning | ' + 'Notes |\n' + '|===========================|===================================|=========|\n' + '| "\\"<newline> | Backslash and newline ignored ' + '| (1) |\n' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\\\" | Backslash ' + '("\\") | |\n' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\\'" | Single quote ' + '("\'") | |\n' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\"" | Double quote (""") ' '| |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\a" | ASCII Bell (BEL) ' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\a" | ASCII Bell (BEL) ' '| |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\b" | ASCII Backspace (BS) ' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\b" | ASCII Backspace (BS) ' '| |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\f" | ASCII Formfeed (FF) ' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\f" | ASCII Formfeed (FF) ' '| |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\n" | ASCII Linefeed (LF) ' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\n" | ASCII Linefeed (LF) ' '| |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\r" | ASCII Carriage Return (CR) ' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\r" | ASCII Carriage Return (CR) ' '| |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\t" | ASCII Horizontal Tab (TAB) ' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\t" | ASCII Horizontal Tab (TAB) ' '| |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\v" | ASCII Vertical Tab (VT) ' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\v" | ASCII Vertical Tab (VT) ' '| |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\ooo" | Character with octal value *ooo* | ' - '(2,4) |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\xhh" | Character with hex value *hh* | ' - '(3,4) |\n' - '+-------------------+-----------------------------------+---------+\n' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\*ooo*" | Character with octal value *ooo* ' + '| (2,4) |\n' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\x*hh*" | Character with hex value *hh* ' + '| (3,4) |\n' + '+---------------------------+-----------------------------------+---------+\n' '\n' 'Escape sequences only recognized in string literals are:\n' '\n' - '+-------------------+-----------------------------------+---------+\n' - '| Escape Sequence | Meaning | Notes ' - '|\n' - '|===================|===================================|=========|\n' - '| "\\N{name}" | Character named *name* in the | ' - '(5) |\n' - '| | Unicode database | ' - '|\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\uxxxx" | Character with 16-bit hex value | ' - '(6) |\n' - '| | *xxxx* | ' - '|\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\Uxxxxxxxx" | Character with 32-bit hex value | ' - '(7) |\n' - '| | *xxxxxxxx* | ' - '|\n' - '+-------------------+-----------------------------------+---------+\n' + '+---------------------------+-----------------------------------+---------+\n' + '| Escape Sequence | Meaning | ' + 'Notes |\n' + '|===========================|===================================|=========|\n' + '| "\\N{*name*}" | Character named *name* in the ' + '| (5) |\n' + '| | Unicode database ' + '| |\n' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\u*xxxx*" | Character with 16-bit hex value ' + '| (6) |\n' + '| | *xxxx* ' + '| |\n' + '+---------------------------+-----------------------------------+---------+\n' + '| "\\U*xxxxxxxx*" | Character with 32-bit hex value ' + '| (7) |\n' + '| | *xxxxxxxx* ' + '| |\n' + '+---------------------------+-----------------------------------+---------+\n' '\n' 'Notes:\n' '\n' @@ -12373,10 +13099,12 @@ topics = {'assert': 'The "assert" statement\n' '2. As in Standard C, up to three octal digits are accepted.\n' '\n' ' Changed in version 3.11: Octal escapes with value larger than\n' - ' "0o377" produce a "DeprecationWarning". In a future Python ' - 'version\n' - ' they will be a "SyntaxWarning" and eventually a ' - '"SyntaxError".\n' + ' "0o377" produce a "DeprecationWarning".\n' + '\n' + ' Changed in version 3.12: Octal escapes with value larger than\n' + ' "0o377" produce a "SyntaxWarning". In a future Python version ' + 'they\n' + ' will be eventually a "SyntaxError".\n' '\n' '3. Unlike in Standard C, exactly two hex digits are required.\n' '\n' @@ -12411,9 +13139,13 @@ topics = {'assert': 'The "assert" statement\n' '\n' ' Changed in version 3.6: Unrecognized escape sequences produce ' 'a\n' - ' "DeprecationWarning". In a future Python version they will be ' + ' "DeprecationWarning".\n' + '\n' + ' Changed in version 3.12: Unrecognized escape sequences produce ' 'a\n' - ' "SyntaxWarning" and eventually a "SyntaxError".\n' + ' "SyntaxWarning". In a future Python version they will be ' + 'eventually\n' + ' a "SyntaxError".\n' '\n' 'Even in a raw literal, quotes can be escaped with a backslash, ' 'but the\n' @@ -12527,7 +13259,7 @@ topics = {'assert': 'The "assert" statement\n' 'are\n' 'most of the built-in objects considered false:\n' '\n' - '* constants defined to be false: "None" and "False".\n' + '* constants defined to be false: "None" and "False"\n' '\n' '* zero of any numeric type: "0", "0.0", "0j", "Decimal(0)",\n' ' "Fraction(0, 1)"\n' @@ -12635,37 +13367,31 @@ topics = {'assert': 'The "assert" statement\n' 'cycle with the stack frame, keeping all locals in that frame alive\n' 'until the next garbage collection occurs.\n' '\n' - 'Before an "except" clause’s suite is executed, details about the\n' - 'exception are stored in the "sys" module and can be accessed via\n' - '"sys.exc_info()". "sys.exc_info()" returns a 3-tuple consisting of ' - 'the\n' - 'exception class, the exception instance and a traceback object (see\n' - 'section The standard type hierarchy) identifying the point in the\n' - 'program where the exception occurred. The details about the ' - 'exception\n' - 'accessed via "sys.exc_info()" are restored to their previous values\n' - 'when leaving an exception handler:\n' + 'Before an "except" clause’s suite is executed, the exception is ' + 'stored\n' + 'in the "sys" module, where it can be accessed from within the body ' + 'of\n' + 'the "except" clause by calling "sys.exception()". When leaving an\n' + 'exception handler, the exception stored in the "sys" module is reset\n' + 'to its previous value:\n' '\n' - ' >>> print(sys.exc_info())\n' - ' (None, None, None)\n' + ' >>> print(sys.exception())\n' + ' None\n' ' >>> try:\n' ' ... raise TypeError\n' ' ... except:\n' - ' ... print(sys.exc_info())\n' + ' ... print(repr(sys.exception()))\n' ' ... try:\n' ' ... raise ValueError\n' ' ... except:\n' - ' ... print(sys.exc_info())\n' - ' ... print(sys.exc_info())\n' + ' ... print(repr(sys.exception()))\n' + ' ... print(repr(sys.exception()))\n' ' ...\n' - " (<class 'TypeError'>, TypeError(), <traceback object at " - '0x10efad080>)\n' - " (<class 'ValueError'>, ValueError(), <traceback object at " - '0x10efad040>)\n' - " (<class 'TypeError'>, TypeError(), <traceback object at " - '0x10efad080>)\n' - ' >>> print(sys.exc_info())\n' - ' (None, None, None)\n' + ' TypeError()\n' + ' ValueError()\n' + ' TypeError()\n' + ' >>> print(sys.exception())\n' + ' None\n' '\n' '\n' '"except*" clause\n' @@ -12704,9 +13430,10 @@ topics = {'assert': 'The "assert" statement\n' '\n' 'Any remaining exceptions that were not handled by any "except*" ' 'clause\n' - 'are re-raised at the end, combined into an exception group along ' - 'with\n' - 'all exceptions that were raised from within "except*" clauses.\n' + 'are re-raised at the end, along with all exceptions that were raised\n' + 'from within the "except*" clauses. If this list contains more than ' + 'one\n' + 'exception to reraise, they are combined into an exception group.\n' '\n' 'If the raised exception is not an exception group and its type ' 'matches\n' @@ -12813,1145 +13540,1185 @@ topics = {'assert': 'The "assert" statement\n' 'definition\n' 'may change in the future.\n' '\n' + '\n' 'None\n' - ' This type has a single value. There is a single object with ' - 'this\n' - ' value. This object is accessed through the built-in name "None". ' - 'It\n' - ' is used to signify the absence of a value in many situations, ' - 'e.g.,\n' - ' it is returned from functions that don’t explicitly return\n' - ' anything. Its truth value is false.\n' + '====\n' + '\n' + 'This type has a single value. There is a single object with this\n' + 'value. This object is accessed through the built-in name "None". It ' + 'is\n' + 'used to signify the absence of a value in many situations, e.g., it ' + 'is\n' + 'returned from functions that don’t explicitly return anything. Its\n' + 'truth value is false.\n' + '\n' '\n' 'NotImplemented\n' - ' This type has a single value. There is a single object with ' - 'this\n' - ' value. This object is accessed through the built-in name\n' - ' "NotImplemented". Numeric methods and rich comparison methods\n' - ' should return this value if they do not implement the operation ' - 'for\n' - ' the operands provided. (The interpreter will then try the\n' - ' reflected operation, or some other fallback, depending on the\n' - ' operator.) It should not be evaluated in a boolean context.\n' + '==============\n' '\n' - ' See Implementing the arithmetic operations for more details.\n' + 'This type has a single value. There is a single object with this\n' + 'value. This object is accessed through the built-in name\n' + '"NotImplemented". Numeric methods and rich comparison methods ' + 'should\n' + 'return this value if they do not implement the operation for the\n' + 'operands provided. (The interpreter will then try the reflected\n' + 'operation, or some other fallback, depending on the operator.) It\n' + 'should not be evaluated in a boolean context.\n' + '\n' + 'See Implementing the arithmetic operations for more details.\n' + '\n' + 'Changed in version 3.9: Evaluating "NotImplemented" in a boolean\n' + 'context is deprecated. While it currently evaluates as true, it ' + 'will\n' + 'emit a "DeprecationWarning". It will raise a "TypeError" in a ' + 'future\n' + 'version of Python.\n' '\n' - ' Changed in version 3.9: Evaluating "NotImplemented" in a ' - 'boolean\n' - ' context is deprecated. While it currently evaluates as true, it\n' - ' will emit a "DeprecationWarning". It will raise a "TypeError" in ' - 'a\n' - ' future version of Python.\n' '\n' 'Ellipsis\n' - ' This type has a single value. There is a single object with ' - 'this\n' - ' value. This object is accessed through the literal "..." or the\n' - ' built-in name "Ellipsis". Its truth value is true.\n' + '========\n' + '\n' + 'This type has a single value. There is a single object with this\n' + 'value. This object is accessed through the literal "..." or the ' + 'built-\n' + 'in name "Ellipsis". Its truth value is true.\n' + '\n' '\n' '"numbers.Number"\n' - ' These are created by numeric literals and returned as results ' - 'by\n' - ' arithmetic operators and arithmetic built-in functions. ' - 'Numeric\n' - ' objects are immutable; once created their value never changes.\n' - ' Python numbers are of course strongly related to mathematical\n' - ' numbers, but subject to the limitations of numerical ' - 'representation\n' - ' in computers.\n' - '\n' - ' The string representations of the numeric classes, computed by\n' - ' "__repr__()" and "__str__()", have the following properties:\n' - '\n' - ' * They are valid numeric literals which, when passed to their ' + '================\n' + '\n' + 'These are created by numeric literals and returned as results by\n' + 'arithmetic operators and arithmetic built-in functions. Numeric\n' + 'objects are immutable; once created their value never changes. ' + 'Python\n' + 'numbers are of course strongly related to mathematical numbers, ' + 'but\n' + 'subject to the limitations of numerical representation in ' + 'computers.\n' + '\n' + 'The string representations of the numeric classes, computed by\n' + '"__repr__()" and "__str__()", have the following properties:\n' + '\n' + '* They are valid numeric literals which, when passed to their ' 'class\n' - ' constructor, produce an object having the value of the ' - 'original\n' - ' numeric.\n' + ' constructor, produce an object having the value of the original\n' + ' numeric.\n' '\n' - ' * The representation is in base 10, when possible.\n' + '* The representation is in base 10, when possible.\n' '\n' - ' * Leading zeros, possibly excepting a single zero before a ' - 'decimal\n' - ' point, are not shown.\n' + '* Leading zeros, possibly excepting a single zero before a decimal\n' + ' point, are not shown.\n' '\n' - ' * Trailing zeros, possibly excepting a single zero after a ' - 'decimal\n' - ' point, are not shown.\n' + '* Trailing zeros, possibly excepting a single zero after a decimal\n' + ' point, are not shown.\n' '\n' - ' * A sign is shown only when the number is negative.\n' + '* A sign is shown only when the number is negative.\n' '\n' - ' Python distinguishes between integers, floating point numbers, ' - 'and\n' - ' complex numbers:\n' + 'Python distinguishes between integers, floating point numbers, and\n' + 'complex numbers:\n' '\n' - ' "numbers.Integral"\n' - ' These represent elements from the mathematical set of ' - 'integers\n' - ' (positive and negative).\n' '\n' - ' There are two types of integers:\n' + '"numbers.Integral"\n' + '------------------\n' '\n' - ' Integers ("int")\n' - ' These represent numbers in an unlimited range, subject to\n' - ' available (virtual) memory only. For the purpose of ' - 'shift\n' - ' and mask operations, a binary representation is assumed, ' - 'and\n' - ' negative numbers are represented in a variant of 2’s\n' - ' complement which gives the illusion of an infinite string ' - 'of\n' - ' sign bits extending to the left.\n' + 'These represent elements from the mathematical set of integers\n' + '(positive and negative).\n' '\n' - ' Booleans ("bool")\n' - ' These represent the truth values False and True. The two\n' - ' objects representing the values "False" and "True" are ' - 'the\n' - ' only Boolean objects. The Boolean type is a subtype of ' + 'Note:\n' + '\n' + ' The rules for integer representation are intended to give the ' + 'most\n' + ' meaningful interpretation of shift and mask operations involving\n' + ' negative integers.\n' + '\n' + 'There are two types of integers:\n' + '\n' + 'Integers ("int")\n' + ' These represent numbers in an unlimited range, subject to ' + 'available\n' + ' (virtual) memory only. For the purpose of shift and mask\n' + ' operations, a binary representation is assumed, and negative\n' + ' numbers are represented in a variant of 2’s complement which ' + 'gives\n' + ' the illusion of an infinite string of sign bits extending to ' 'the\n' - ' integer type, and Boolean values behave like the values 0 ' - 'and\n' - ' 1, respectively, in almost all contexts, the exception ' - 'being\n' - ' that when converted to a string, the strings ""False"" or\n' - ' ""True"" are returned, respectively.\n' + ' left.\n' '\n' - ' The rules for integer representation are intended to give ' + 'Booleans ("bool")\n' + ' These represent the truth values False and True. The two ' + 'objects\n' + ' representing the values "False" and "True" are the only Boolean\n' + ' objects. The Boolean type is a subtype of the integer type, and\n' + ' Boolean values behave like the values 0 and 1, respectively, in\n' + ' almost all contexts, the exception being that when converted to ' + 'a\n' + ' string, the strings ""False"" or ""True"" are returned,\n' + ' respectively.\n' + '\n' + '\n' + '"numbers.Real" ("float")\n' + '------------------------\n' + '\n' + 'These represent machine-level double precision floating point ' + 'numbers.\n' + 'You are at the mercy of the underlying machine architecture (and C ' + 'or\n' + 'Java implementation) for the accepted range and handling of ' + 'overflow.\n' + 'Python does not support single-precision floating point numbers; ' 'the\n' - ' most meaningful interpretation of shift and mask operations\n' - ' involving negative integers.\n' - '\n' - ' "numbers.Real" ("float")\n' - ' These represent machine-level double precision floating ' - 'point\n' - ' numbers. You are at the mercy of the underlying machine\n' - ' architecture (and C or Java implementation) for the accepted\n' - ' range and handling of overflow. Python does not support ' - 'single-\n' - ' precision floating point numbers; the savings in processor ' - 'and\n' - ' memory usage that are usually the reason for using these are\n' - ' dwarfed by the overhead of using objects in Python, so there ' - 'is\n' - ' no reason to complicate the language with two kinds of ' - 'floating\n' - ' point numbers.\n' - '\n' - ' "numbers.Complex" ("complex")\n' - ' These represent complex numbers as a pair of machine-level\n' - ' double precision floating point numbers. The same caveats ' - 'apply\n' - ' as for floating point numbers. The real and imaginary parts ' - 'of a\n' - ' complex number "z" can be retrieved through the read-only\n' - ' attributes "z.real" and "z.imag".\n' + 'savings in processor and memory usage that are usually the reason ' + 'for\n' + 'using these are dwarfed by the overhead of using objects in Python, ' + 'so\n' + 'there is no reason to complicate the language with two kinds of\n' + 'floating point numbers.\n' + '\n' + '\n' + '"numbers.Complex" ("complex")\n' + '-----------------------------\n' + '\n' + 'These represent complex numbers as a pair of machine-level double\n' + 'precision floating point numbers. The same caveats apply as for\n' + 'floating point numbers. The real and imaginary parts of a complex\n' + 'number "z" can be retrieved through the read-only attributes ' + '"z.real"\n' + 'and "z.imag".\n' + '\n' '\n' 'Sequences\n' - ' These represent finite ordered sets indexed by non-negative\n' - ' numbers. The built-in function "len()" returns the number of ' - 'items\n' - ' of a sequence. When the length of a sequence is *n*, the index ' + '=========\n' + '\n' + 'These represent finite ordered sets indexed by non-negative ' + 'numbers.\n' + 'The built-in function "len()" returns the number of items of a\n' + 'sequence. When the length of a sequence is *n*, the index set ' + 'contains\n' + 'the numbers 0, 1, …, *n*-1. Item *i* of sequence *a* is selected ' + 'by\n' + '"a[i]".\n' + '\n' + 'Sequences also support slicing: "a[i:j]" selects all items with ' + 'index\n' + '*k* such that *i* "<=" *k* "<" *j*. When used as an expression, a\n' + 'slice is a sequence of the same type. This implies that the index ' 'set\n' - ' contains the numbers 0, 1, …, *n*-1. Item *i* of sequence *a* ' - 'is\n' - ' selected by "a[i]".\n' + 'is renumbered so that it starts at 0.\n' '\n' - ' Sequences also support slicing: "a[i:j]" selects all items with\n' - ' index *k* such that *i* "<=" *k* "<" *j*. When used as an\n' - ' expression, a slice is a sequence of the same type. This ' - 'implies\n' - ' that the index set is renumbered so that it starts at 0.\n' + 'Some sequences also support “extended slicing” with a third “step”\n' + 'parameter: "a[i:j:k]" selects all items of *a* with index *x* where ' + '"x\n' + '= i + n*k", *n* ">=" "0" and *i* "<=" *x* "<" *j*.\n' '\n' - ' Some sequences also support “extended slicing” with a third ' - '“step”\n' - ' parameter: "a[i:j:k]" selects all items of *a* with index *x* ' - 'where\n' - ' "x = i + n*k", *n* ">=" "0" and *i* "<=" *x* "<" *j*.\n' + 'Sequences are distinguished according to their mutability:\n' '\n' - ' Sequences are distinguished according to their mutability:\n' '\n' - ' Immutable sequences\n' - ' An object of an immutable sequence type cannot change once it ' - 'is\n' - ' created. (If the object contains references to other ' - 'objects,\n' - ' these other objects may be mutable and may be changed; ' - 'however,\n' - ' the collection of objects directly referenced by an ' - 'immutable\n' - ' object cannot change.)\n' + 'Immutable sequences\n' + '-------------------\n' '\n' - ' The following types are immutable sequences:\n' + 'An object of an immutable sequence type cannot change once it is\n' + 'created. (If the object contains references to other objects, ' + 'these\n' + 'other objects may be mutable and may be changed; however, the\n' + 'collection of objects directly referenced by an immutable object\n' + 'cannot change.)\n' '\n' - ' Strings\n' - ' A string is a sequence of values that represent Unicode ' - 'code\n' - ' points. All the code points in the range "U+0000 - ' - 'U+10FFFF"\n' - ' can be represented in a string. Python doesn’t have a ' - 'char\n' - ' type; instead, every code point in the string is ' - 'represented\n' - ' as a string object with length "1". The built-in ' - 'function\n' - ' "ord()" converts a code point from its string form to an\n' - ' integer in the range "0 - 10FFFF"; "chr()" converts an\n' - ' integer in the range "0 - 10FFFF" to the corresponding ' - 'length\n' - ' "1" string object. "str.encode()" can be used to convert ' - 'a\n' - ' "str" to "bytes" using the given text encoding, and\n' - ' "bytes.decode()" can be used to achieve the opposite.\n' + 'The following types are immutable sequences:\n' '\n' - ' Tuples\n' - ' The items of a tuple are arbitrary Python objects. Tuples ' - 'of\n' - ' two or more items are formed by comma-separated lists of\n' - ' expressions. A tuple of one item (a ‘singleton’) can be\n' - ' formed by affixing a comma to an expression (an expression ' - 'by\n' - ' itself does not create a tuple, since parentheses must be\n' - ' usable for grouping of expressions). An empty tuple can ' + 'Strings\n' + ' A string is a sequence of values that represent Unicode code\n' + ' points. All the code points in the range "U+0000 - U+10FFFF" can ' 'be\n' - ' formed by an empty pair of parentheses.\n' - '\n' - ' Bytes\n' - ' A bytes object is an immutable array. The items are ' - '8-bit\n' - ' bytes, represented by integers in the range 0 <= x < 256.\n' - ' Bytes literals (like "b\'abc\'") and the built-in ' - '"bytes()"\n' - ' constructor can be used to create bytes objects. Also, ' - 'bytes\n' - ' objects can be decoded to strings via the "decode()" ' - 'method.\n' + ' represented in a string. Python doesn’t have a char type; ' + 'instead,\n' + ' every code point in the string is represented as a string ' + 'object\n' + ' with length "1". The built-in function "ord()" converts a code\n' + ' point from its string form to an integer in the range "0 - ' + '10FFFF";\n' + ' "chr()" converts an integer in the range "0 - 10FFFF" to the\n' + ' corresponding length "1" string object. "str.encode()" can be ' + 'used\n' + ' to convert a "str" to "bytes" using the given text encoding, ' + 'and\n' + ' "bytes.decode()" can be used to achieve the opposite.\n' '\n' - ' Mutable sequences\n' - ' Mutable sequences can be changed after they are created. ' - 'The\n' - ' subscription and slicing notations can be used as the target ' + 'Tuples\n' + ' The items of a tuple are arbitrary Python objects. Tuples of two ' + 'or\n' + ' more items are formed by comma-separated lists of expressions. ' + 'A\n' + ' tuple of one item (a ‘singleton’) can be formed by affixing a ' + 'comma\n' + ' to an expression (an expression by itself does not create a ' + 'tuple,\n' + ' since parentheses must be usable for grouping of expressions). ' + 'An\n' + ' empty tuple can be formed by an empty pair of parentheses.\n' + '\n' + 'Bytes\n' + ' A bytes object is an immutable array. The items are 8-bit ' + 'bytes,\n' + ' represented by integers in the range 0 <= x < 256. Bytes ' + 'literals\n' + ' (like "b\'abc\'") and the built-in "bytes()" constructor can be ' + 'used\n' + ' to create bytes objects. Also, bytes objects can be decoded to\n' + ' strings via the "decode()" method.\n' + '\n' + '\n' + 'Mutable sequences\n' + '-----------------\n' + '\n' + 'Mutable sequences can be changed after they are created. The\n' + 'subscription and slicing notations can be used as the target of\n' + 'assignment and "del" (delete) statements.\n' + '\n' + 'Note:\n' + '\n' + ' The "collections" and "array" module provide additional examples ' 'of\n' - ' assignment and "del" (delete) statements.\n' + ' mutable sequence types.\n' '\n' - ' There are currently two intrinsic mutable sequence types:\n' + 'There are currently two intrinsic mutable sequence types:\n' '\n' - ' Lists\n' - ' The items of a list are arbitrary Python objects. Lists ' - 'are\n' - ' formed by placing a comma-separated list of expressions ' - 'in\n' - ' square brackets. (Note that there are no special cases ' - 'needed\n' - ' to form lists of length 0 or 1.)\n' + 'Lists\n' + ' The items of a list are arbitrary Python objects. Lists are ' + 'formed\n' + ' by placing a comma-separated list of expressions in square\n' + ' brackets. (Note that there are no special cases needed to form\n' + ' lists of length 0 or 1.)\n' '\n' - ' Byte Arrays\n' - ' A bytearray object is a mutable array. They are created ' - 'by\n' - ' the built-in "bytearray()" constructor. Aside from being\n' - ' mutable (and hence unhashable), byte arrays otherwise ' - 'provide\n' - ' the same interface and functionality as immutable "bytes"\n' - ' objects.\n' + 'Byte Arrays\n' + ' A bytearray object is a mutable array. They are created by the\n' + ' built-in "bytearray()" constructor. Aside from being mutable ' + '(and\n' + ' hence unhashable), byte arrays otherwise provide the same ' + 'interface\n' + ' and functionality as immutable "bytes" objects.\n' '\n' - ' The extension module "array" provides an additional example ' - 'of a\n' - ' mutable sequence type, as does the "collections" module.\n' '\n' 'Set types\n' - ' These represent unordered, finite sets of unique, immutable\n' - ' objects. As such, they cannot be indexed by any subscript. ' - 'However,\n' - ' they can be iterated over, and the built-in function "len()"\n' - ' returns the number of items in a set. Common uses for sets are ' - 'fast\n' - ' membership testing, removing duplicates from a sequence, and\n' - ' computing mathematical operations such as intersection, union,\n' - ' difference, and symmetric difference.\n' - '\n' - ' For set elements, the same immutability rules apply as for\n' - ' dictionary keys. Note that numeric types obey the normal rules ' - 'for\n' - ' numeric comparison: if two numbers compare equal (e.g., "1" and\n' - ' "1.0"), only one of them can be contained in a set.\n' + '=========\n' + '\n' + 'These represent unordered, finite sets of unique, immutable ' + 'objects.\n' + 'As such, they cannot be indexed by any subscript. However, they can ' + 'be\n' + 'iterated over, and the built-in function "len()" returns the number ' + 'of\n' + 'items in a set. Common uses for sets are fast membership testing,\n' + 'removing duplicates from a sequence, and computing mathematical\n' + 'operations such as intersection, union, difference, and symmetric\n' + 'difference.\n' + '\n' + 'For set elements, the same immutability rules apply as for ' + 'dictionary\n' + 'keys. Note that numeric types obey the normal rules for numeric\n' + 'comparison: if two numbers compare equal (e.g., "1" and "1.0"), ' + 'only\n' + 'one of them can be contained in a set.\n' '\n' - ' There are currently two intrinsic set types:\n' + 'There are currently two intrinsic set types:\n' '\n' - ' Sets\n' - ' These represent a mutable set. They are created by the ' + 'Sets\n' + ' These represent a mutable set. They are created by the built-in\n' + ' "set()" constructor and can be modified afterwards by several\n' + ' methods, such as "add()".\n' + '\n' + 'Frozen sets\n' + ' These represent an immutable set. They are created by the ' 'built-in\n' - ' "set()" constructor and can be modified afterwards by ' - 'several\n' - ' methods, such as "add()".\n' - '\n' - ' Frozen sets\n' - ' These represent an immutable set. They are created by the\n' - ' built-in "frozenset()" constructor. As a frozenset is ' - 'immutable\n' - ' and *hashable*, it can be used again as an element of ' - 'another\n' - ' set, or as a dictionary key.\n' + ' "frozenset()" constructor. As a frozenset is immutable and\n' + ' *hashable*, it can be used again as an element of another set, ' + 'or\n' + ' as a dictionary key.\n' + '\n' '\n' 'Mappings\n' - ' These represent finite sets of objects indexed by arbitrary ' - 'index\n' - ' sets. The subscript notation "a[k]" selects the item indexed by ' + '========\n' + '\n' + 'These represent finite sets of objects indexed by arbitrary index\n' + 'sets. The subscript notation "a[k]" selects the item indexed by ' '"k"\n' - ' from the mapping "a"; this can be used in expressions and as ' - 'the\n' - ' target of assignments or "del" statements. The built-in ' - 'function\n' - ' "len()" returns the number of items in a mapping.\n' + 'from the mapping "a"; this can be used in expressions and as the\n' + 'target of assignments or "del" statements. The built-in function\n' + '"len()" returns the number of items in a mapping.\n' '\n' - ' There is currently a single intrinsic mapping type:\n' + 'There is currently a single intrinsic mapping type:\n' '\n' - ' Dictionaries\n' - ' These represent finite sets of objects indexed by nearly\n' - ' arbitrary values. The only types of values not acceptable ' - 'as\n' - ' keys are values containing lists or dictionaries or other\n' - ' mutable types that are compared by value rather than by ' - 'object\n' - ' identity, the reason being that the efficient implementation ' - 'of\n' - ' dictionaries requires a key’s hash value to remain constant.\n' - ' Numeric types used for keys obey the normal rules for ' - 'numeric\n' - ' comparison: if two numbers compare equal (e.g., "1" and ' - '"1.0")\n' - ' then they can be used interchangeably to index the same\n' - ' dictionary entry.\n' - '\n' - ' Dictionaries preserve insertion order, meaning that keys will ' - 'be\n' - ' produced in the same order they were added sequentially over ' - 'the\n' - ' dictionary. Replacing an existing key does not change the ' - 'order,\n' - ' however removing a key and re-inserting it will add it to ' + '\n' + 'Dictionaries\n' + '------------\n' + '\n' + 'These represent finite sets of objects indexed by nearly arbitrary\n' + 'values. The only types of values not acceptable as keys are ' + 'values\n' + 'containing lists or dictionaries or other mutable types that are\n' + 'compared by value rather than by object identity, the reason being\n' + 'that the efficient implementation of dictionaries requires a key’s\n' + 'hash value to remain constant. Numeric types used for keys obey ' 'the\n' - ' end instead of keeping its old place.\n' + 'normal rules for numeric comparison: if two numbers compare equal\n' + '(e.g., "1" and "1.0") then they can be used interchangeably to ' + 'index\n' + 'the same dictionary entry.\n' '\n' - ' Dictionaries are mutable; they can be created by the "{...}"\n' - ' notation (see section Dictionary displays).\n' + 'Dictionaries preserve insertion order, meaning that keys will be\n' + 'produced in the same order they were added sequentially over the\n' + 'dictionary. Replacing an existing key does not change the order,\n' + 'however removing a key and re-inserting it will add it to the end\n' + 'instead of keeping its old place.\n' '\n' - ' The extension modules "dbm.ndbm" and "dbm.gnu" provide\n' - ' additional examples of mapping types, as does the ' - '"collections"\n' - ' module.\n' + 'Dictionaries are mutable; they can be created by the "{...}" ' + 'notation\n' + '(see section Dictionary displays).\n' + '\n' + 'The extension modules "dbm.ndbm" and "dbm.gnu" provide additional\n' + 'examples of mapping types, as does the "collections" module.\n' + '\n' + 'Changed in version 3.7: Dictionaries did not preserve insertion ' + 'order\n' + 'in versions of Python before 3.6. In CPython 3.6, insertion order ' + 'was\n' + 'preserved, but it was considered an implementation detail at that ' + 'time\n' + 'rather than a language guarantee.\n' '\n' - ' Changed in version 3.7: Dictionaries did not preserve ' - 'insertion\n' - ' order in versions of Python before 3.6. In CPython 3.6,\n' - ' insertion order was preserved, but it was considered an\n' - ' implementation detail at that time rather than a language\n' - ' guarantee.\n' '\n' 'Callable types\n' - ' These are the types to which the function call operation (see\n' - ' section Calls) can be applied:\n' + '==============\n' + '\n' + 'These are the types to which the function call operation (see ' + 'section\n' + 'Calls) can be applied:\n' '\n' - ' User-defined functions\n' - ' A user-defined function object is created by a function\n' - ' definition (see section Function definitions). It should be\n' - ' called with an argument list containing the same number of ' - 'items\n' - ' as the function’s formal parameter list.\n' '\n' - ' Special attributes:\n' + 'User-defined functions\n' + '----------------------\n' + '\n' + 'A user-defined function object is created by a function definition\n' + '(see section Function definitions). It should be called with an\n' + 'argument list containing the same number of items as the ' + 'function’s\n' + 'formal parameter list.\n' + '\n' + 'Special attributes:\n' '\n' - ' ' '+---------------------------+---------------------------------+-------------+\n' - ' | Attribute | Meaning ' + '| Attribute | Meaning ' '| |\n' - ' ' '|===========================|=================================|=============|\n' - ' | "__doc__" | The function’s documentation ' - '| Writable |\n' - ' | | string, or "None" if ' + '| "__doc__" | The function’s documentation | ' + 'Writable |\n' + '| | string, or "None" if ' '| |\n' - ' | | unavailable; not inherited by ' + '| | unavailable; not inherited by ' '| |\n' - ' | | subclasses. ' + '| | subclasses. ' '| |\n' - ' ' '+---------------------------+---------------------------------+-------------+\n' - ' | "__name__" | The function’s name. ' - '| Writable |\n' - ' ' + '| "__name__" | The function’s name. | ' + 'Writable |\n' '+---------------------------+---------------------------------+-------------+\n' - ' | "__qualname__" | The function’s *qualified ' - '| Writable |\n' - ' | | name*. New in version 3.3. ' + '| "__qualname__" | The function’s *qualified | ' + 'Writable |\n' + '| | name*. New in version 3.3. ' '| |\n' - ' ' '+---------------------------+---------------------------------+-------------+\n' - ' | "__module__" | The name of the module the ' - '| Writable |\n' - ' | | function was defined in, or ' + '| "__module__" | The name of the module the | ' + 'Writable |\n' + '| | function was defined in, or ' '| |\n' - ' | | "None" if unavailable. ' + '| | "None" if unavailable. ' '| |\n' - ' ' '+---------------------------+---------------------------------+-------------+\n' - ' | "__defaults__" | A tuple containing default ' - '| Writable |\n' - ' | | argument values for those ' + '| "__defaults__" | A tuple containing default | ' + 'Writable |\n' + '| | argument values for those ' '| |\n' - ' | | arguments that have defaults, ' + '| | arguments that have defaults, ' '| |\n' - ' | | or "None" if no arguments have ' + '| | or "None" if no arguments have ' '| |\n' - ' | | a default value. ' + '| | a default value. ' '| |\n' - ' ' '+---------------------------+---------------------------------+-------------+\n' - ' | "__code__" | The code object representing ' - '| Writable |\n' - ' | | the compiled function body. ' + '| "__code__" | The code object representing | ' + 'Writable |\n' + '| | the compiled function body. ' '| |\n' - ' ' '+---------------------------+---------------------------------+-------------+\n' - ' | "__globals__" | A reference to the dictionary ' - '| Read-only |\n' - ' | | that holds the function’s ' + '| "__globals__" | A reference to the dictionary | ' + 'Read-only |\n' + '| | that holds the function’s ' '| |\n' - ' | | global variables — the global ' + '| | global variables — the global ' '| |\n' - ' | | namespace of the module in ' + '| | namespace of the module in ' '| |\n' - ' | | which the function was defined. ' + '| | which the function was defined. ' '| |\n' - ' ' '+---------------------------+---------------------------------+-------------+\n' - ' | "__dict__" | The namespace supporting ' - '| Writable |\n' - ' | | arbitrary function attributes. ' + '| "__dict__" | The namespace supporting | ' + 'Writable |\n' + '| | arbitrary function attributes. ' '| |\n' - ' ' '+---------------------------+---------------------------------+-------------+\n' - ' | "__closure__" | "None" or a tuple of cells that ' - '| Read-only |\n' - ' | | contain bindings for the ' + '| "__closure__" | "None" or a tuple of cells that | ' + 'Read-only |\n' + '| | contain bindings for the ' '| |\n' - ' | | function’s free variables. See ' + '| | function’s free variables. See ' '| |\n' - ' | | below for information on the ' + '| | below for information on the ' '| |\n' - ' | | "cell_contents" attribute. ' + '| | "cell_contents" attribute. ' '| |\n' - ' ' '+---------------------------+---------------------------------+-------------+\n' - ' | "__annotations__" | A dict containing annotations ' - '| Writable |\n' - ' | | of parameters. The keys of the ' + '| "__annotations__" | A dict containing annotations | ' + 'Writable |\n' + '| | of parameters. The keys of the ' '| |\n' - ' | | dict are the parameter names, ' + '| | dict are the parameter names, ' '| |\n' - ' | | and "\'return\'" for the ' - 'return | |\n' - ' | | annotation, if provided. For ' + '| | and "\'return\'" for the return ' '| |\n' - ' | | more information on working ' + '| | annotation, if provided. For ' '| |\n' - ' | | with this attribute, see ' + '| | more information on working ' '| |\n' - ' | | Annotations Best Practices. ' + '| | with this attribute, see ' + '| |\n' + '| | Annotations Best Practices. ' + '| |\n' + '+---------------------------+---------------------------------+-------------+\n' + '| "__kwdefaults__" | A dict containing defaults for | ' + 'Writable |\n' + '| | keyword-only parameters. ' '| |\n' - ' ' '+---------------------------+---------------------------------+-------------+\n' - ' | "__kwdefaults__" | A dict containing defaults for ' - '| Writable |\n' - ' | | keyword-only parameters. ' + '| "__type_params__" | A tuple containing the type | ' + 'Writable |\n' + '| | parameters of a generic ' + '| |\n' + '| | function. ' '| |\n' - ' ' '+---------------------------+---------------------------------+-------------+\n' '\n' - ' Most of the attributes labelled “Writable” check the type of ' - 'the\n' - ' assigned value.\n' + 'Most of the attributes labelled “Writable” check the type of the\n' + 'assigned value.\n' '\n' - ' Function objects also support getting and setting arbitrary\n' - ' attributes, which can be used, for example, to attach ' - 'metadata\n' - ' to functions. Regular attribute dot-notation is used to get ' - 'and\n' - ' set such attributes. *Note that the current implementation ' - 'only\n' - ' supports function attributes on user-defined functions. ' - 'Function\n' - ' attributes on built-in functions may be supported in the\n' - ' future.*\n' - '\n' - ' A cell object has the attribute "cell_contents". This can be\n' - ' used to get the value of the cell, as well as set the value.\n' - '\n' - ' Additional information about a function’s definition can be\n' - ' retrieved from its code object; see the description of ' - 'internal\n' - ' types below. The "cell" type can be accessed in the "types"\n' - ' module.\n' - '\n' - ' Instance methods\n' - ' An instance method object combines a class, a class instance ' - 'and\n' - ' any callable object (normally a user-defined function).\n' - '\n' - ' Special read-only attributes: "__self__" is the class ' - 'instance\n' - ' object, "__func__" is the function object; "__doc__" is the\n' - ' method’s documentation (same as "__func__.__doc__"); ' - '"__name__"\n' - ' is the method name (same as "__func__.__name__"); ' - '"__module__"\n' - ' is the name of the module the method was defined in, or ' - '"None"\n' - ' if unavailable.\n' + 'Function objects also support getting and setting arbitrary\n' + 'attributes, which can be used, for example, to attach metadata to\n' + 'functions. Regular attribute dot-notation is used to get and set ' + 'such\n' + 'attributes. *Note that the current implementation only supports\n' + 'function attributes on user-defined functions. Function attributes ' + 'on\n' + 'built-in functions may be supported in the future.*\n' '\n' - ' Methods also support accessing (but not setting) the ' - 'arbitrary\n' - ' function attributes on the underlying function object.\n' + 'A cell object has the attribute "cell_contents". This can be used ' + 'to\n' + 'get the value of the cell, as well as set the value.\n' '\n' - ' User-defined method objects may be created when getting an\n' - ' attribute of a class (perhaps via an instance of that class), ' - 'if\n' - ' that attribute is a user-defined function object or a class\n' - ' method object.\n' - '\n' - ' When an instance method object is created by retrieving a ' - 'user-\n' - ' defined function object from a class via one of its ' - 'instances,\n' - ' its "__self__" attribute is the instance, and the method ' - 'object\n' - ' is said to be bound. The new method’s "__func__" attribute ' - 'is\n' - ' the original function object.\n' + 'Additional information about a function’s definition can be ' + 'retrieved\n' + 'from its code object; see the description of internal types below. ' + 'The\n' + '"cell" type can be accessed in the "types" module.\n' '\n' - ' When an instance method object is created by retrieving a ' - 'class\n' - ' method object from a class or instance, its "__self__" ' - 'attribute\n' - ' is the class itself, and its "__func__" attribute is the\n' - ' function object underlying the class method.\n' '\n' - ' When an instance method object is called, the underlying\n' - ' function ("__func__") is called, inserting the class ' - 'instance\n' - ' ("__self__") in front of the argument list. For instance, ' - 'when\n' - ' "C" is a class which contains a definition for a function ' - '"f()",\n' - ' and "x" is an instance of "C", calling "x.f(1)" is equivalent ' - 'to\n' - ' calling "C.f(x, 1)".\n' + 'Instance methods\n' + '----------------\n' + '\n' + 'An instance method object combines a class, a class instance and ' + 'any\n' + 'callable object (normally a user-defined function).\n' '\n' - ' When an instance method object is derived from a class ' + 'Special read-only attributes: "__self__" is the class instance ' + 'object,\n' + '"__func__" is the function object; "__doc__" is the method’s\n' + 'documentation (same as "__func__.__doc__"); "__name__" is the ' 'method\n' - ' object, the “class instance” stored in "__self__" will ' - 'actually\n' - ' be the class itself, so that calling either "x.f(1)" or ' - '"C.f(1)"\n' - ' is equivalent to calling "f(C,1)" where "f" is the ' - 'underlying\n' - ' function.\n' - '\n' - ' Note that the transformation from function object to ' - 'instance\n' - ' method object happens each time the attribute is retrieved ' - 'from\n' - ' the instance. In some cases, a fruitful optimization is to\n' - ' assign the attribute to a local variable and call that local\n' - ' variable. Also notice that this transformation only happens ' - 'for\n' - ' user-defined functions; other callable objects (and all non-\n' - ' callable objects) are retrieved without transformation. It ' - 'is\n' - ' also important to note that user-defined functions which are\n' - ' attributes of a class instance are not converted to bound\n' - ' methods; this *only* happens when the function is an ' + 'name (same as "__func__.__name__"); "__module__" is the name of ' + 'the\n' + 'module the method was defined in, or "None" if unavailable.\n' + '\n' + 'Methods also support accessing (but not setting) the arbitrary\n' + 'function attributes on the underlying function object.\n' + '\n' + 'User-defined method objects may be created when getting an ' + 'attribute\n' + 'of a class (perhaps via an instance of that class), if that ' 'attribute\n' - ' of the class.\n' + 'is a user-defined function object or a class method object.\n' '\n' - ' Generator functions\n' - ' A function or method which uses the "yield" statement (see\n' - ' section The yield statement) is called a *generator ' - 'function*.\n' - ' Such a function, when called, always returns an *iterator*\n' - ' object which can be used to execute the body of the ' - 'function:\n' - ' calling the iterator’s "iterator.__next__()" method will ' - 'cause\n' - ' the function to execute until it provides a value using the\n' - ' "yield" statement. When the function executes a "return"\n' - ' statement or falls off the end, a "StopIteration" exception ' - 'is\n' - ' raised and the iterator will have reached the end of the set ' + 'When an instance method object is created by retrieving a ' + 'user-defined\n' + 'function object from a class via one of its instances, its ' + '"__self__"\n' + 'attribute is the instance, and the method object is said to be ' + 'bound.\n' + 'The new method’s "__func__" attribute is the original function ' + 'object.\n' + '\n' + 'When an instance method object is created by retrieving a class ' + 'method\n' + 'object from a class or instance, its "__self__" attribute is the ' + 'class\n' + 'itself, and its "__func__" attribute is the function object ' + 'underlying\n' + 'the class method.\n' + '\n' + 'When an instance method object is called, the underlying function\n' + '("__func__") is called, inserting the class instance ("__self__") ' + 'in\n' + 'front of the argument list. For instance, when "C" is a class ' + 'which\n' + 'contains a definition for a function "f()", and "x" is an instance ' 'of\n' - ' values to be returned.\n' - '\n' - ' Coroutine functions\n' - ' A function or method which is defined using "async def" is\n' - ' called a *coroutine function*. Such a function, when ' - 'called,\n' - ' returns a *coroutine* object. It may contain "await"\n' - ' expressions, as well as "async with" and "async for" ' - 'statements.\n' - ' See also the Coroutine Objects section.\n' - '\n' - ' Asynchronous generator functions\n' - ' A function or method which is defined using "async def" and\n' - ' which uses the "yield" statement is called a *asynchronous\n' - ' generator function*. Such a function, when called, returns ' - 'an\n' - ' *asynchronous iterator* object which can be used in an ' - '"async\n' - ' for" statement to execute the body of the function.\n' + '"C", calling "x.f(1)" is equivalent to calling "C.f(x, 1)".\n' + '\n' + 'When an instance method object is derived from a class method ' + 'object,\n' + 'the “class instance” stored in "__self__" will actually be the ' + 'class\n' + 'itself, so that calling either "x.f(1)" or "C.f(1)" is equivalent ' + 'to\n' + 'calling "f(C,1)" where "f" is the underlying function.\n' '\n' - ' Calling the asynchronous iterator’s "aiterator.__anext__" ' + 'Note that the transformation from function object to instance ' 'method\n' - ' will return an *awaitable* which when awaited will execute ' + 'object happens each time the attribute is retrieved from the ' + 'instance.\n' + 'In some cases, a fruitful optimization is to assign the attribute ' + 'to a\n' + 'local variable and call that local variable. Also notice that this\n' + 'transformation only happens for user-defined functions; other ' + 'callable\n' + 'objects (and all non-callable objects) are retrieved without\n' + 'transformation. It is also important to note that user-defined\n' + 'functions which are attributes of a class instance are not ' + 'converted\n' + 'to bound methods; this *only* happens when the function is an\n' + 'attribute of the class.\n' + '\n' + '\n' + 'Generator functions\n' + '-------------------\n' + '\n' + 'A function or method which uses the "yield" statement (see section ' + 'The\n' + 'yield statement) is called a *generator function*. Such a ' + 'function,\n' + 'when called, always returns an *iterator* object which can be used ' + 'to\n' + 'execute the body of the function: calling the iterator’s\n' + '"iterator.__next__()" method will cause the function to execute ' 'until\n' - ' it provides a value using the "yield" expression. When the\n' - ' function executes an empty "return" statement or falls off ' + 'it provides a value using the "yield" statement. When the ' + 'function\n' + 'executes a "return" statement or falls off the end, a ' + '"StopIteration"\n' + 'exception is raised and the iterator will have reached the end of ' 'the\n' - ' end, a "StopAsyncIteration" exception is raised and the\n' - ' asynchronous iterator will have reached the end of the set ' - 'of\n' - ' values to be yielded.\n' + 'set of values to be returned.\n' '\n' - ' Built-in functions\n' - ' A built-in function object is a wrapper around a C function.\n' - ' Examples of built-in functions are "len()" and "math.sin()"\n' - ' ("math" is a standard built-in module). The number and type ' - 'of\n' - ' the arguments are determined by the C function. Special ' - 'read-\n' - ' only attributes: "__doc__" is the function’s documentation\n' - ' string, or "None" if unavailable; "__name__" is the ' - 'function’s\n' - ' name; "__self__" is set to "None" (but see the next item);\n' - ' "__module__" is the name of the module the function was ' - 'defined\n' - ' in or "None" if unavailable.\n' '\n' - ' Built-in methods\n' - ' This is really a different disguise of a built-in function, ' - 'this\n' - ' time containing an object passed to the C function as an\n' - ' implicit extra argument. An example of a built-in method is\n' - ' "alist.append()", assuming *alist* is a list object. In this\n' - ' case, the special read-only attribute "__self__" is set to ' + 'Coroutine functions\n' + '-------------------\n' + '\n' + 'A function or method which is defined using "async def" is called ' + 'a\n' + '*coroutine function*. Such a function, when called, returns a\n' + '*coroutine* object. It may contain "await" expressions, as well ' + 'as\n' + '"async with" and "async for" statements. See also the Coroutine\n' + 'Objects section.\n' + '\n' + '\n' + 'Asynchronous generator functions\n' + '--------------------------------\n' + '\n' + 'A function or method which is defined using "async def" and which ' + 'uses\n' + 'the "yield" statement is called a *asynchronous generator ' + 'function*.\n' + 'Such a function, when called, returns an *asynchronous iterator*\n' + 'object which can be used in an "async for" statement to execute ' 'the\n' - ' object denoted by *alist*.\n' + 'body of the function.\n' '\n' - ' Classes\n' - ' Classes are callable. These objects normally act as ' - 'factories\n' - ' for new instances of themselves, but variations are possible ' - 'for\n' - ' class types that override "__new__()". The arguments of the\n' - ' call are passed to "__new__()" and, in the typical case, to\n' - ' "__init__()" to initialize the new instance.\n' + 'Calling the asynchronous iterator’s "aiterator.__anext__" method ' + 'will\n' + 'return an *awaitable* which when awaited will execute until it\n' + 'provides a value using the "yield" expression. When the function\n' + 'executes an empty "return" statement or falls off the end, a\n' + '"StopAsyncIteration" exception is raised and the asynchronous ' + 'iterator\n' + 'will have reached the end of the set of values to be yielded.\n' + '\n' + '\n' + 'Built-in functions\n' + '------------------\n' + '\n' + 'A built-in function object is a wrapper around a C function. ' + 'Examples\n' + 'of built-in functions are "len()" and "math.sin()" ("math" is a\n' + 'standard built-in module). The number and type of the arguments ' + 'are\n' + 'determined by the C function. Special read-only attributes: ' + '"__doc__"\n' + 'is the function’s documentation string, or "None" if unavailable;\n' + '"__name__" is the function’s name; "__self__" is set to "None" ' + '(but\n' + 'see the next item); "__module__" is the name of the module the\n' + 'function was defined in or "None" if unavailable.\n' + '\n' + '\n' + 'Built-in methods\n' + '----------------\n' + '\n' + 'This is really a different disguise of a built-in function, this ' + 'time\n' + 'containing an object passed to the C function as an implicit extra\n' + 'argument. An example of a built-in method is "alist.append()",\n' + 'assuming *alist* is a list object. In this case, the special ' + 'read-only\n' + 'attribute "__self__" is set to the object denoted by *alist*.\n' + '\n' + '\n' + 'Classes\n' + '-------\n' + '\n' + 'Classes are callable. These objects normally act as factories for ' + 'new\n' + 'instances of themselves, but variations are possible for class ' + 'types\n' + 'that override "__new__()". The arguments of the call are passed ' + 'to\n' + '"__new__()" and, in the typical case, to "__init__()" to ' + 'initialize\n' + 'the new instance.\n' + '\n' + '\n' + 'Class Instances\n' + '---------------\n' + '\n' + 'Instances of arbitrary classes can be made callable by defining a\n' + '"__call__()" method in their class.\n' '\n' - ' Class Instances\n' - ' Instances of arbitrary classes can be made callable by ' - 'defining\n' - ' a "__call__()" method in their class.\n' '\n' 'Modules\n' - ' Modules are a basic organizational unit of Python code, and are\n' - ' created by the import system as invoked either by the "import"\n' - ' statement, or by calling functions such as\n' - ' "importlib.import_module()" and built-in "__import__()". A ' - 'module\n' - ' object has a namespace implemented by a dictionary object (this ' - 'is\n' - ' the dictionary referenced by the "__globals__" attribute of\n' - ' functions defined in the module). Attribute references are\n' - ' translated to lookups in this dictionary, e.g., "m.x" is ' - 'equivalent\n' - ' to "m.__dict__["x"]". A module object does not contain the code\n' - ' object used to initialize the module (since it isn’t needed ' - 'once\n' - ' the initialization is done).\n' + '=======\n' + '\n' + 'Modules are a basic organizational unit of Python code, and are\n' + 'created by the import system as invoked either by the "import"\n' + 'statement, or by calling functions such as ' + '"importlib.import_module()"\n' + 'and built-in "__import__()". A module object has a namespace\n' + 'implemented by a dictionary object (this is the dictionary ' + 'referenced\n' + 'by the "__globals__" attribute of functions defined in the ' + 'module).\n' + 'Attribute references are translated to lookups in this dictionary,\n' + 'e.g., "m.x" is equivalent to "m.__dict__["x"]". A module object ' + 'does\n' + 'not contain the code object used to initialize the module (since ' + 'it\n' + 'isn’t needed once the initialization is done).\n' + '\n' + 'Attribute assignment updates the module’s namespace dictionary, ' + 'e.g.,\n' + '"m.x = 1" is equivalent to "m.__dict__["x"] = 1".\n' '\n' - ' Attribute assignment updates the module’s namespace dictionary,\n' - ' e.g., "m.x = 1" is equivalent to "m.__dict__["x"] = 1".\n' + 'Predefined (writable) attributes:\n' '\n' - ' Predefined (writable) attributes:\n' + ' "__name__"\n' + ' The module’s name.\n' '\n' - ' "__name__"\n' - ' The module’s name.\n' + ' "__doc__"\n' + ' The module’s documentation string, or "None" if unavailable.\n' '\n' - ' "__doc__"\n' - ' The module’s documentation string, or "None" if ' - 'unavailable.\n' + ' "__file__"\n' + ' The pathname of the file from which the module was loaded, if ' + 'it\n' + ' was loaded from a file. The "__file__" attribute may be ' + 'missing\n' + ' for certain types of modules, such as C modules that are\n' + ' statically linked into the interpreter. For extension ' + 'modules\n' + ' loaded dynamically from a shared library, it’s the pathname ' + 'of\n' + ' the shared library file.\n' '\n' - ' "__file__"\n' - ' The pathname of the file from which the module was loaded, ' - 'if\n' - ' it was loaded from a file. The "__file__" attribute may ' - 'be\n' - ' missing for certain types of modules, such as C modules ' - 'that\n' - ' are statically linked into the interpreter. For ' - 'extension\n' - ' modules loaded dynamically from a shared library, it’s ' - 'the\n' - ' pathname of the shared library file.\n' - '\n' - ' "__annotations__"\n' - ' A dictionary containing *variable annotations* collected\n' - ' during module body execution. For best practices on ' - 'working\n' - ' with "__annotations__", please see Annotations Best\n' - ' Practices.\n' - '\n' - ' Special read-only attribute: "__dict__" is the module’s ' - 'namespace\n' - ' as a dictionary object.\n' - '\n' - ' **CPython implementation detail:** Because of the way CPython\n' - ' clears module dictionaries, the module dictionary will be ' - 'cleared\n' - ' when the module falls out of scope even if the dictionary still ' - 'has\n' - ' live references. To avoid this, copy the dictionary or keep ' + ' "__annotations__"\n' + ' A dictionary containing *variable annotations* collected ' + 'during\n' + ' module body execution. For best practices on working with\n' + ' "__annotations__", please see Annotations Best Practices.\n' + '\n' + 'Special read-only attribute: "__dict__" is the module’s namespace ' + 'as a\n' + 'dictionary object.\n' + '\n' + '**CPython implementation detail:** Because of the way CPython ' + 'clears\n' + 'module dictionaries, the module dictionary will be cleared when ' 'the\n' - ' module around while using its dictionary directly.\n' + 'module falls out of scope even if the dictionary still has live\n' + 'references. To avoid this, copy the dictionary or keep the module\n' + 'around while using its dictionary directly.\n' + '\n' '\n' 'Custom classes\n' - ' Custom class types are typically created by class definitions ' - '(see\n' - ' section Class definitions). A class has a namespace implemented ' - 'by\n' - ' a dictionary object. Class attribute references are translated ' - 'to\n' - ' lookups in this dictionary, e.g., "C.x" is translated to\n' - ' "C.__dict__["x"]" (although there are a number of hooks which ' + '==============\n' + '\n' + 'Custom class types are typically created by class definitions (see\n' + 'section Class definitions). A class has a namespace implemented by ' + 'a\n' + 'dictionary object. Class attribute references are translated to\n' + 'lookups in this dictionary, e.g., "C.x" is translated to\n' + '"C.__dict__["x"]" (although there are a number of hooks which ' 'allow\n' - ' for other means of locating attributes). When the attribute name ' + 'for other means of locating attributes). When the attribute name ' 'is\n' - ' not found there, the attribute search continues in the base\n' - ' classes. This search of the base classes uses the C3 method\n' - ' resolution order which behaves correctly even in the presence ' - 'of\n' - ' ‘diamond’ inheritance structures where there are multiple\n' - ' inheritance paths leading back to a common ancestor. Additional\n' - ' details on the C3 MRO used by Python can be found in the\n' - ' documentation accompanying the 2.3 release at\n' - ' https://www.python.org/download/releases/2.3/mro/.\n' - '\n' - ' When a class attribute reference (for class "C", say) would ' - 'yield a\n' - ' class method object, it is transformed into an instance method\n' - ' object whose "__self__" attribute is "C". When it would yield ' + 'not found there, the attribute search continues in the base ' + 'classes.\n' + 'This search of the base classes uses the C3 method resolution ' + 'order\n' + 'which behaves correctly even in the presence of ‘diamond’ ' + 'inheritance\n' + 'structures where there are multiple inheritance paths leading back ' + 'to\n' + 'a common ancestor. Additional details on the C3 MRO used by Python ' + 'can\n' + 'be found in the documentation accompanying the 2.3 release at\n' + 'https://www.python.org/download/releases/2.3/mro/.\n' + '\n' + 'When a class attribute reference (for class "C", say) would yield ' 'a\n' - ' static method object, it is transformed into the object wrapped ' - 'by\n' - ' the static method object. See section Implementing Descriptors ' - 'for\n' - ' another way in which attributes retrieved from a class may ' - 'differ\n' - ' from those actually contained in its "__dict__".\n' + 'class method object, it is transformed into an instance method ' + 'object\n' + 'whose "__self__" attribute is "C". When it would yield a static\n' + 'method object, it is transformed into the object wrapped by the ' + 'static\n' + 'method object. See section Implementing Descriptors for another way ' + 'in\n' + 'which attributes retrieved from a class may differ from those ' + 'actually\n' + 'contained in its "__dict__".\n' + '\n' + 'Class attribute assignments update the class’s dictionary, never ' + 'the\n' + 'dictionary of a base class.\n' + '\n' + 'A class object can be called (see above) to yield a class instance\n' + '(see below).\n' '\n' - ' Class attribute assignments update the class’s dictionary, ' - 'never\n' - ' the dictionary of a base class.\n' + 'Special attributes:\n' '\n' - ' A class object can be called (see above) to yield a class ' - 'instance\n' - ' (see below).\n' + ' "__name__"\n' + ' The class name.\n' '\n' - ' Special attributes:\n' + ' "__module__"\n' + ' The name of the module in which the class was defined.\n' '\n' - ' "__name__"\n' - ' The class name.\n' + ' "__dict__"\n' + ' The dictionary containing the class’s namespace.\n' '\n' - ' "__module__"\n' - ' The name of the module in which the class was defined.\n' + ' "__bases__"\n' + ' A tuple containing the base classes, in the order of their\n' + ' occurrence in the base class list.\n' '\n' - ' "__dict__"\n' - ' The dictionary containing the class’s namespace.\n' + ' "__doc__"\n' + ' The class’s documentation string, or "None" if undefined.\n' '\n' - ' "__bases__"\n' - ' A tuple containing the base classes, in the order of ' - 'their\n' - ' occurrence in the base class list.\n' + ' "__annotations__"\n' + ' A dictionary containing *variable annotations* collected ' + 'during\n' + ' class body execution. For best practices on working with\n' + ' "__annotations__", please see Annotations Best Practices.\n' '\n' - ' "__doc__"\n' - ' The class’s documentation string, or "None" if undefined.\n' + ' "__type_params__"\n' + ' A tuple containing the type parameters of a generic class.\n' '\n' - ' "__annotations__"\n' - ' A dictionary containing *variable annotations* collected\n' - ' during class body execution. For best practices on ' - 'working\n' - ' with "__annotations__", please see Annotations Best\n' - ' Practices.\n' '\n' 'Class instances\n' - ' A class instance is created by calling a class object (see ' - 'above).\n' - ' A class instance has a namespace implemented as a dictionary ' - 'which\n' - ' is the first place in which attribute references are searched.\n' - ' When an attribute is not found there, and the instance’s class ' - 'has\n' - ' an attribute by that name, the search continues with the class\n' - ' attributes. If a class attribute is found that is a ' - 'user-defined\n' - ' function object, it is transformed into an instance method ' - 'object\n' - ' whose "__self__" attribute is the instance. Static method and\n' - ' class method objects are also transformed; see above under\n' - ' “Classes”. See section Implementing Descriptors for another way ' - 'in\n' - ' which attributes of a class retrieved via its instances may ' - 'differ\n' - ' from the objects actually stored in the class’s "__dict__". If ' - 'no\n' - ' class attribute is found, and the object’s class has a\n' - ' "__getattr__()" method, that is called to satisfy the lookup.\n' + '===============\n' '\n' - ' Attribute assignments and deletions update the instance’s\n' - ' dictionary, never a class’s dictionary. If the class has a\n' - ' "__setattr__()" or "__delattr__()" method, this is called ' - 'instead\n' - ' of updating the instance dictionary directly.\n' + 'A class instance is created by calling a class object (see above). ' + 'A\n' + 'class instance has a namespace implemented as a dictionary which ' + 'is\n' + 'the first place in which attribute references are searched. When ' + 'an\n' + 'attribute is not found there, and the instance’s class has an\n' + 'attribute by that name, the search continues with the class\n' + 'attributes. If a class attribute is found that is a user-defined\n' + 'function object, it is transformed into an instance method object\n' + 'whose "__self__" attribute is the instance. Static method and ' + 'class\n' + 'method objects are also transformed; see above under “Classes”. ' + 'See\n' + 'section Implementing Descriptors for another way in which ' + 'attributes\n' + 'of a class retrieved via its instances may differ from the objects\n' + 'actually stored in the class’s "__dict__". If no class attribute ' + 'is\n' + 'found, and the object’s class has a "__getattr__()" method, that ' + 'is\n' + 'called to satisfy the lookup.\n' + '\n' + 'Attribute assignments and deletions update the instance’s ' + 'dictionary,\n' + 'never a class’s dictionary. If the class has a "__setattr__()" or\n' + '"__delattr__()" method, this is called instead of updating the\n' + 'instance dictionary directly.\n' + '\n' + 'Class instances can pretend to be numbers, sequences, or mappings ' + 'if\n' + 'they have methods with certain special names. See section Special\n' + 'method names.\n' '\n' - ' Class instances can pretend to be numbers, sequences, or ' - 'mappings\n' - ' if they have methods with certain special names. See section\n' - ' Special method names.\n' + 'Special attributes: "__dict__" is the attribute dictionary;\n' + '"__class__" is the instance’s class.\n' '\n' - ' Special attributes: "__dict__" is the attribute dictionary;\n' - ' "__class__" is the instance’s class.\n' '\n' 'I/O objects (also known as file objects)\n' - ' A *file object* represents an open file. Various shortcuts are\n' - ' available to create file objects: the "open()" built-in ' - 'function,\n' - ' and also "os.popen()", "os.fdopen()", and the "makefile()" ' - 'method\n' - ' of socket objects (and perhaps by other functions or methods\n' - ' provided by extension modules).\n' + '========================================\n' + '\n' + 'A *file object* represents an open file. Various shortcuts are\n' + 'available to create file objects: the "open()" built-in function, ' + 'and\n' + 'also "os.popen()", "os.fdopen()", and the "makefile()" method of\n' + 'socket objects (and perhaps by other functions or methods provided ' + 'by\n' + 'extension modules).\n' + '\n' + 'The objects "sys.stdin", "sys.stdout" and "sys.stderr" are ' + 'initialized\n' + 'to file objects corresponding to the interpreter’s standard input,\n' + 'output and error streams; they are all open in text mode and ' + 'therefore\n' + 'follow the interface defined by the "io.TextIOBase" abstract ' + 'class.\n' '\n' - ' The objects "sys.stdin", "sys.stdout" and "sys.stderr" are\n' - ' initialized to file objects corresponding to the interpreter’s\n' - ' standard input, output and error streams; they are all open in ' - 'text\n' - ' mode and therefore follow the interface defined by the\n' - ' "io.TextIOBase" abstract class.\n' '\n' 'Internal types\n' - ' A few types used internally by the interpreter are exposed to ' - 'the\n' - ' user. Their definitions may change with future versions of the\n' - ' interpreter, but they are mentioned here for completeness.\n' - '\n' - ' Code objects\n' - ' Code objects represent *byte-compiled* executable Python ' - 'code,\n' - ' or *bytecode*. The difference between a code object and a\n' - ' function object is that the function object contains an ' - 'explicit\n' - ' reference to the function’s globals (the module in which it ' - 'was\n' - ' defined), while a code object contains no context; also the\n' - ' default argument values are stored in the function object, ' - 'not\n' - ' in the code object (because they represent values calculated ' - 'at\n' - ' run-time). Unlike function objects, code objects are ' - 'immutable\n' - ' and contain no references (directly or indirectly) to ' - 'mutable\n' - ' objects.\n' - '\n' - ' Special read-only attributes: "co_name" gives the function ' - 'name;\n' - ' "co_qualname" gives the fully qualified function name;\n' - ' "co_argcount" is the total number of positional arguments\n' - ' (including positional-only arguments and arguments with ' - 'default\n' - ' values); "co_posonlyargcount" is the number of ' - 'positional-only\n' - ' arguments (including arguments with default values);\n' - ' "co_kwonlyargcount" is the number of keyword-only arguments\n' - ' (including arguments with default values); "co_nlocals" is ' - 'the\n' - ' number of local variables used by the function (including\n' - ' arguments); "co_varnames" is a tuple containing the names of ' - 'the\n' - ' local variables (starting with the argument names);\n' - ' "co_cellvars" is a tuple containing the names of local ' - 'variables\n' - ' that are referenced by nested functions; "co_freevars" is a\n' - ' tuple containing the names of free variables; "co_code" is a\n' - ' string representing the sequence of bytecode instructions;\n' - ' "co_consts" is a tuple containing the literals used by the\n' - ' bytecode; "co_names" is a tuple containing the names used by ' - 'the\n' - ' bytecode; "co_filename" is the filename from which the code ' - 'was\n' - ' compiled; "co_firstlineno" is the first line number of the\n' - ' function; "co_lnotab" is a string encoding the mapping from\n' - ' bytecode offsets to line numbers (for details see the source\n' - ' code of the interpreter); "co_stacksize" is the required ' - 'stack\n' - ' size; "co_flags" is an integer encoding a number of flags ' - 'for\n' - ' the interpreter.\n' + '==============\n' '\n' - ' The following flag bits are defined for "co_flags": bit ' - '"0x04"\n' - ' is set if the function uses the "*arguments" syntax to accept ' - 'an\n' - ' arbitrary number of positional arguments; bit "0x08" is set ' - 'if\n' - ' the function uses the "**keywords" syntax to accept ' - 'arbitrary\n' - ' keyword arguments; bit "0x20" is set if the function is a\n' - ' generator.\n' + 'A few types used internally by the interpreter are exposed to the\n' + 'user. Their definitions may change with future versions of the\n' + 'interpreter, but they are mentioned here for completeness.\n' + '\n' + '\n' + 'Code objects\n' + '------------\n' '\n' - ' Future feature declarations ("from __future__ import ' - 'division")\n' - ' also use bits in "co_flags" to indicate whether a code ' + 'Code objects represent *byte-compiled* executable Python code, or\n' + '*bytecode*. The difference between a code object and a function ' 'object\n' - ' was compiled with a particular feature enabled: bit "0x2000" ' + 'is that the function object contains an explicit reference to the\n' + 'function’s globals (the module in which it was defined), while a ' + 'code\n' + 'object contains no context; also the default argument values are\n' + 'stored in the function object, not in the code object (because ' + 'they\n' + 'represent values calculated at run-time). Unlike function ' + 'objects,\n' + 'code objects are immutable and contain no references (directly or\n' + 'indirectly) to mutable objects.\n' + '\n' + 'Special read-only attributes: "co_name" gives the function name;\n' + '"co_qualname" gives the fully qualified function name; ' + '"co_argcount"\n' + 'is the total number of positional arguments (including ' + 'positional-only\n' + 'arguments and arguments with default values); "co_posonlyargcount" ' + 'is\n' + 'the number of positional-only arguments (including arguments with\n' + 'default values); "co_kwonlyargcount" is the number of keyword-only\n' + 'arguments (including arguments with default values); "co_nlocals" ' + 'is\n' + 'the number of local variables used by the function (including\n' + 'arguments); "co_varnames" is a tuple containing the names of the ' + 'local\n' + 'variables (starting with the argument names); "co_cellvars" is a ' + 'tuple\n' + 'containing the names of local variables that are referenced by ' + 'nested\n' + 'functions; "co_freevars" is a tuple containing the names of free\n' + 'variables; "co_code" is a string representing the sequence of ' + 'bytecode\n' + 'instructions; "co_consts" is a tuple containing the literals used ' + 'by\n' + 'the bytecode; "co_names" is a tuple containing the names used by ' + 'the\n' + 'bytecode; "co_filename" is the filename from which the code was\n' + 'compiled; "co_firstlineno" is the first line number of the ' + 'function;\n' + '"co_lnotab" is a string encoding the mapping from bytecode offsets ' + 'to\n' + 'line numbers (for details see the source code of the interpreter, ' 'is\n' - ' set if the function was compiled with future division ' - 'enabled;\n' - ' bits "0x10" and "0x1000" were used in earlier versions of\n' - ' Python.\n' + 'deprecated since 3.12 and may be removed in 3.14); "co_stacksize" ' + 'is\n' + 'the required stack size; "co_flags" is an integer encoding a number ' + 'of\n' + 'flags for the interpreter.\n' '\n' - ' Other bits in "co_flags" are reserved for internal use.\n' + 'The following flag bits are defined for "co_flags": bit "0x04" is ' + 'set\n' + 'if the function uses the "*arguments" syntax to accept an ' + 'arbitrary\n' + 'number of positional arguments; bit "0x08" is set if the function ' + 'uses\n' + 'the "**keywords" syntax to accept arbitrary keyword arguments; bit\n' + '"0x20" is set if the function is a generator.\n' + '\n' + 'Future feature declarations ("from __future__ import division") ' + 'also\n' + 'use bits in "co_flags" to indicate whether a code object was ' + 'compiled\n' + 'with a particular feature enabled: bit "0x2000" is set if the ' + 'function\n' + 'was compiled with future division enabled; bits "0x10" and ' + '"0x1000"\n' + 'were used in earlier versions of Python.\n' '\n' - ' If a code object represents a function, the first item in\n' - ' "co_consts" is the documentation string of the function, or\n' - ' "None" if undefined.\n' + 'Other bits in "co_flags" are reserved for internal use.\n' '\n' - ' codeobject.co_positions()\n' + 'If a code object represents a function, the first item in ' + '"co_consts"\n' + 'is the documentation string of the function, or "None" if ' + 'undefined.\n' '\n' - ' Returns an iterable over the source code positions of ' - 'each\n' - ' bytecode instruction in the code object.\n' + 'codeobject.co_positions()\n' '\n' - ' The iterator returns tuples containing the "(start_line,\n' - ' end_line, start_column, end_column)". The *i-th* tuple\n' - ' corresponds to the position of the source code that ' - 'compiled\n' - ' to the *i-th* instruction. Column information is ' - '0-indexed\n' - ' utf-8 byte offsets on the given source line.\n' + ' Returns an iterable over the source code positions of each ' + 'bytecode\n' + ' instruction in the code object.\n' '\n' - ' This positional information can be missing. A ' - 'non-exhaustive\n' - ' lists of cases where this may happen:\n' + ' The iterator returns tuples containing the "(start_line, ' + 'end_line,\n' + ' start_column, end_column)". The *i-th* tuple corresponds to the\n' + ' position of the source code that compiled to the *i-th*\n' + ' instruction. Column information is 0-indexed utf-8 byte offsets ' + 'on\n' + ' the given source line.\n' '\n' - ' * Running the interpreter with "-X" "no_debug_ranges".\n' + ' This positional information can be missing. A non-exhaustive ' + 'lists\n' + ' of cases where this may happen:\n' '\n' - ' * Loading a pyc file compiled while using "-X"\n' - ' "no_debug_ranges".\n' + ' * Running the interpreter with "-X" "no_debug_ranges".\n' '\n' - ' * Position tuples corresponding to artificial ' - 'instructions.\n' + ' * Loading a pyc file compiled while using "-X" ' + '"no_debug_ranges".\n' '\n' - ' * Line and column numbers that can’t be represented due ' - 'to\n' - ' implementation specific limitations.\n' + ' * Position tuples corresponding to artificial instructions.\n' '\n' - ' When this occurs, some or all of the tuple elements can ' - 'be\n' - ' "None".\n' + ' * Line and column numbers that can’t be represented due to\n' + ' implementation specific limitations.\n' '\n' - ' New in version 3.11.\n' + ' When this occurs, some or all of the tuple elements can be ' + '"None".\n' '\n' - ' Note:\n' + ' New in version 3.11.\n' '\n' - ' This feature requires storing column positions in code\n' - ' objects which may result in a small increase of disk ' - 'usage\n' - ' of compiled Python files or interpreter memory usage. ' - 'To\n' - ' avoid storing the extra information and/or deactivate\n' - ' printing the extra traceback information, the "-X"\n' - ' "no_debug_ranges" command line flag or the\n' - ' "PYTHONNODEBUGRANGES" environment variable can be used.\n' + ' Note:\n' '\n' - ' Frame objects\n' - ' Frame objects represent execution frames. They may occur in\n' - ' traceback objects (see below), and are also passed to ' - 'registered\n' - ' trace functions.\n' + ' This feature requires storing column positions in code ' + 'objects\n' + ' which may result in a small increase of disk usage of ' + 'compiled\n' + ' Python files or interpreter memory usage. To avoid storing ' + 'the\n' + ' extra information and/or deactivate printing the extra ' + 'traceback\n' + ' information, the "-X" "no_debug_ranges" command line flag or ' + 'the\n' + ' "PYTHONNODEBUGRANGES" environment variable can be used.\n' + '\n' + '\n' + 'Frame objects\n' + '-------------\n' + '\n' + 'Frame objects represent execution frames. They may occur in ' + 'traceback\n' + 'objects (see below), and are also passed to registered trace\n' + 'functions.\n' + '\n' + 'Special read-only attributes: "f_back" is to the previous stack ' + 'frame\n' + '(towards the caller), or "None" if this is the bottom stack frame;\n' + '"f_code" is the code object being executed in this frame; ' + '"f_locals"\n' + 'is the dictionary used to look up local variables; "f_globals" is ' + 'used\n' + 'for global variables; "f_builtins" is used for built-in ' + '(intrinsic)\n' + 'names; "f_lasti" gives the precise instruction (this is an index ' + 'into\n' + 'the bytecode string of the code object).\n' + '\n' + 'Accessing "f_code" raises an auditing event "object.__getattr__" ' + 'with\n' + 'arguments "obj" and ""f_code"".\n' + '\n' + 'Special writable attributes: "f_trace", if not "None", is a ' + 'function\n' + 'called for various events during code execution (this is used by ' + 'the\n' + 'debugger). Normally an event is triggered for each new source line ' + '-\n' + 'this can be disabled by setting "f_trace_lines" to "False".\n' '\n' - ' Special read-only attributes: "f_back" is to the previous ' - 'stack\n' - ' frame (towards the caller), or "None" if this is the bottom\n' - ' stack frame; "f_code" is the code object being executed in ' + 'Implementations *may* allow per-opcode events to be requested by\n' + 'setting "f_trace_opcodes" to "True". Note that this may lead to\n' + 'undefined interpreter behaviour if exceptions raised by the trace\n' + 'function escape to the function being traced.\n' + '\n' + '"f_lineno" is the current line number of the frame — writing to ' 'this\n' - ' frame; "f_locals" is the dictionary used to look up local\n' - ' variables; "f_globals" is used for global variables;\n' - ' "f_builtins" is used for built-in (intrinsic) names; ' - '"f_lasti"\n' - ' gives the precise instruction (this is an index into the\n' - ' bytecode string of the code object).\n' - '\n' - ' Accessing "f_code" raises an auditing event ' - '"object.__getattr__"\n' - ' with arguments "obj" and ""f_code"".\n' - '\n' - ' Special writable attributes: "f_trace", if not "None", is a\n' - ' function called for various events during code execution ' - '(this\n' - ' is used by the debugger). Normally an event is triggered for\n' - ' each new source line - this can be disabled by setting\n' - ' "f_trace_lines" to "False".\n' - '\n' - ' Implementations *may* allow per-opcode events to be requested ' - 'by\n' - ' setting "f_trace_opcodes" to "True". Note that this may lead ' - 'to\n' - ' undefined interpreter behaviour if exceptions raised by the\n' - ' trace function escape to the function being traced.\n' + 'from within a trace function jumps to the given line (only for the\n' + 'bottom-most frame). A debugger can implement a Jump command (aka ' + 'Set\n' + 'Next Statement) by writing to f_lineno.\n' '\n' - ' "f_lineno" is the current line number of the frame — writing ' - 'to\n' - ' this from within a trace function jumps to the given line ' - '(only\n' - ' for the bottom-most frame). A debugger can implement a Jump\n' - ' command (aka Set Next Statement) by writing to f_lineno.\n' + 'Frame objects support one method:\n' '\n' - ' Frame objects support one method:\n' + 'frame.clear()\n' '\n' - ' frame.clear()\n' + ' This method clears all references to local variables held by ' + 'the\n' + ' frame. Also, if the frame belonged to a generator, the ' + 'generator\n' + ' is finalized. This helps break reference cycles involving ' + 'frame\n' + ' objects (for example when catching an exception and storing its\n' + ' traceback for later use).\n' '\n' - ' This method clears all references to local variables held ' - 'by\n' - ' the frame. Also, if the frame belonged to a generator, ' + ' "RuntimeError" is raised if the frame is currently executing.\n' + '\n' + ' New in version 3.4.\n' + '\n' + '\n' + 'Traceback objects\n' + '-----------------\n' + '\n' + 'Traceback objects represent a stack trace of an exception. A\n' + 'traceback object is implicitly created when an exception occurs, ' + 'and\n' + 'may also be explicitly created by calling "types.TracebackType".\n' + '\n' + 'For implicitly created tracebacks, when the search for an ' + 'exception\n' + 'handler unwinds the execution stack, at each unwound level a ' + 'traceback\n' + 'object is inserted in front of the current traceback. When an\n' + 'exception handler is entered, the stack trace is made available to ' 'the\n' - ' generator is finalized. This helps break reference ' - 'cycles\n' - ' involving frame objects (for example when catching an\n' - ' exception and storing its traceback for later use).\n' + 'program. (See section The try statement.) It is accessible as the\n' + 'third item of the tuple returned by "sys.exc_info()", and as the\n' + '"__traceback__" attribute of the caught exception.\n' '\n' - ' "RuntimeError" is raised if the frame is currently ' - 'executing.\n' + 'When the program contains no suitable handler, the stack trace is\n' + 'written (nicely formatted) to the standard error stream; if the\n' + 'interpreter is interactive, it is also made available to the user ' + 'as\n' + '"sys.last_traceback".\n' '\n' - ' New in version 3.4.\n' + 'For explicitly created tracebacks, it is up to the creator of the\n' + 'traceback to determine how the "tb_next" attributes should be ' + 'linked\n' + 'to form a full stack trace.\n' '\n' - ' Traceback objects\n' - ' Traceback objects represent a stack trace of an exception. ' - 'A\n' - ' traceback object is implicitly created when an exception ' - 'occurs,\n' - ' and may also be explicitly created by calling\n' - ' "types.TracebackType".\n' - '\n' - ' For implicitly created tracebacks, when the search for an\n' - ' exception handler unwinds the execution stack, at each ' - 'unwound\n' - ' level a traceback object is inserted in front of the current\n' - ' traceback. When an exception handler is entered, the stack\n' - ' trace is made available to the program. (See section The try\n' - ' statement.) It is accessible as the third item of the tuple\n' - ' returned by "sys.exc_info()", and as the "__traceback__"\n' - ' attribute of the caught exception.\n' - '\n' - ' When the program contains no suitable handler, the stack ' - 'trace\n' - ' is written (nicely formatted) to the standard error stream; ' - 'if\n' - ' the interpreter is interactive, it is also made available to ' + 'Special read-only attributes: "tb_frame" points to the execution ' + 'frame\n' + 'of the current level; "tb_lineno" gives the line number where the\n' + 'exception occurred; "tb_lasti" indicates the precise instruction. ' + 'The\n' + 'line number and last instruction in the traceback may differ from ' 'the\n' - ' user as "sys.last_traceback".\n' + 'line number of its frame object if the exception occurred in a ' + '"try"\n' + 'statement with no matching except clause or with a finally clause.\n' '\n' - ' For explicitly created tracebacks, it is up to the creator ' - 'of\n' - ' the traceback to determine how the "tb_next" attributes ' - 'should\n' - ' be linked to form a full stack trace.\n' - '\n' - ' Special read-only attributes: "tb_frame" points to the ' - 'execution\n' - ' frame of the current level; "tb_lineno" gives the line ' - 'number\n' - ' where the exception occurred; "tb_lasti" indicates the ' - 'precise\n' - ' instruction. The line number and last instruction in the\n' - ' traceback may differ from the line number of its frame object ' + 'Accessing "tb_frame" raises an auditing event "object.__getattr__"\n' + 'with arguments "obj" and ""tb_frame"".\n' + '\n' + 'Special writable attribute: "tb_next" is the next level in the ' + 'stack\n' + 'trace (towards the frame where the exception occurred), or "None" ' 'if\n' - ' the exception occurred in a "try" statement with no matching\n' - ' except clause or with a finally clause.\n' + 'there is no next level.\n' '\n' - ' Accessing "tb_frame" raises an auditing event\n' - ' "object.__getattr__" with arguments "obj" and ""tb_frame"".\n' + 'Changed in version 3.7: Traceback objects can now be explicitly\n' + 'instantiated from Python code, and the "tb_next" attribute of ' + 'existing\n' + 'instances can be updated.\n' '\n' - ' Special writable attribute: "tb_next" is the next level in ' - 'the\n' - ' stack trace (towards the frame where the exception occurred), ' - 'or\n' - ' "None" if there is no next level.\n' '\n' - ' Changed in version 3.7: Traceback objects can now be ' - 'explicitly\n' - ' instantiated from Python code, and the "tb_next" attribute ' - 'of\n' - ' existing instances can be updated.\n' + 'Slice objects\n' + '-------------\n' '\n' - ' Slice objects\n' - ' Slice objects are used to represent slices for ' - '"__getitem__()"\n' - ' methods. They are also created by the built-in "slice()"\n' - ' function.\n' + 'Slice objects are used to represent slices for "__getitem__()"\n' + 'methods. They are also created by the built-in "slice()" ' + 'function.\n' '\n' - ' Special read-only attributes: "start" is the lower bound; ' - '"stop"\n' - ' is the upper bound; "step" is the step value; each is "None" ' - 'if\n' - ' omitted. These attributes can have any type.\n' + 'Special read-only attributes: "start" is the lower bound; "stop" ' + 'is\n' + 'the upper bound; "step" is the step value; each is "None" if ' + 'omitted.\n' + 'These attributes can have any type.\n' '\n' - ' Slice objects support one method:\n' + 'Slice objects support one method:\n' '\n' - ' slice.indices(self, length)\n' + 'slice.indices(self, length)\n' '\n' - ' This method takes a single integer argument *length* and\n' - ' computes information about the slice that the slice ' - 'object\n' - ' would describe if applied to a sequence of *length* ' - 'items.\n' - ' It returns a tuple of three integers; respectively these ' - 'are\n' - ' the *start* and *stop* indices and the *step* or stride\n' - ' length of the slice. Missing or out-of-bounds indices are\n' - ' handled in a manner consistent with regular slices.\n' - '\n' - ' Static method objects\n' - ' Static method objects provide a way of defeating the\n' - ' transformation of function objects to method objects ' - 'described\n' - ' above. A static method object is a wrapper around any other\n' - ' object, usually a user-defined method object. When a static\n' - ' method object is retrieved from a class or a class instance, ' - 'the\n' - ' object actually returned is the wrapped object, which is not\n' - ' subject to any further transformation. Static method objects ' - 'are\n' - ' also callable. Static method objects are created by the ' - 'built-in\n' - ' "staticmethod()" constructor.\n' + ' This method takes a single integer argument *length* and ' + 'computes\n' + ' information about the slice that the slice object would describe ' + 'if\n' + ' applied to a sequence of *length* items. It returns a tuple of\n' + ' three integers; respectively these are the *start* and *stop*\n' + ' indices and the *step* or stride length of the slice. Missing ' + 'or\n' + ' out-of-bounds indices are handled in a manner consistent with\n' + ' regular slices.\n' '\n' - ' Class method objects\n' - ' A class method object, like a static method object, is a ' - 'wrapper\n' - ' around another object that alters the way in which that ' - 'object\n' - ' is retrieved from classes and class instances. The behaviour ' + '\n' + 'Static method objects\n' + '---------------------\n' + '\n' + 'Static method objects provide a way of defeating the transformation ' 'of\n' - ' class method objects upon such retrieval is described above,\n' - ' under “User-defined methods”. Class method objects are ' - 'created\n' - ' by the built-in "classmethod()" constructor.\n', + 'function objects to method objects described above. A static ' + 'method\n' + 'object is a wrapper around any other object, usually a ' + 'user-defined\n' + 'method object. When a static method object is retrieved from a ' + 'class\n' + 'or a class instance, the object actually returned is the wrapped\n' + 'object, which is not subject to any further transformation. Static\n' + 'method objects are also callable. Static method objects are created ' + 'by\n' + 'the built-in "staticmethod()" constructor.\n' + '\n' + '\n' + 'Class method objects\n' + '--------------------\n' + '\n' + 'A class method object, like a static method object, is a wrapper\n' + 'around another object that alters the way in which that object is\n' + 'retrieved from classes and class instances. The behaviour of class\n' + 'method objects upon such retrieval is described above, under ' + '“User-\n' + 'defined methods”. Class method objects are created by the built-in\n' + '"classmethod()" constructor.\n', 'typesfunctions': 'Functions\n' '*********\n' '\n' @@ -14100,6 +14867,7 @@ topics = {'assert': 'The "assert" statement\n' ' >>> class Counter(dict):\n' ' ... def __missing__(self, key):\n' ' ... return 0\n' + ' ...\n' ' >>> c = Counter()\n' " >>> c['red']\n" ' 0\n' @@ -14398,7 +15166,7 @@ topics = {'assert': 'The "assert" statement\n' ' New in version 3.10.\n' '\n' 'Keys views are set-like since their entries are unique and ' - 'hashable.\n' + '*hashable*.\n' 'If all values are hashable, so that "(key, value)" pairs are ' 'unique\n' 'and hashable, then the items view is also set-like. (Values ' @@ -14409,7 +15177,11 @@ topics = {'assert': 'The "assert" statement\n' 'abstract\n' 'base class "collections.abc.Set" are available (for example, ' '"==",\n' - '"<", or "^").\n' + '"<", or "^"). While using set operators, set-like views ' + 'accept any\n' + 'iterable as the other operand, unlike sets which only accept ' + 'sets as\n' + 'the input.\n' '\n' 'An example of dictionary view usage:\n' '\n' @@ -14422,6 +15194,7 @@ topics = {'assert': 'The "assert" statement\n' ' >>> n = 0\n' ' >>> for val in values:\n' ' ... n += val\n' + ' ...\n' ' >>> print(n)\n' ' 504\n' '\n' @@ -14441,8 +15214,12 @@ topics = {'assert': 'The "assert" statement\n' ' >>> # set operations\n' " >>> keys & {'eggs', 'bacon', 'salad'}\n" " {'bacon'}\n" - " >>> keys ^ {'sausage', 'juice'}\n" - " {'juice', 'sausage', 'bacon', 'spam'}\n" + " >>> keys ^ {'sausage', 'juice'} == {'juice', 'sausage', " + "'bacon', 'spam'}\n" + ' True\n' + " >>> keys | ['juice', 'juice', 'juice'] == {'bacon', " + "'spam', 'juice'}\n" + ' True\n' '\n' ' >>> # get back a read-only proxy for the original ' 'dictionary\n' diff --git a/Lib/quopri.py b/Lib/quopri.py index 08899c5c..f36cf7b3 100755 --- a/Lib/quopri.py +++ b/Lib/quopri.py @@ -67,10 +67,7 @@ def encode(input, output, quotetabs, header=False): output.write(s + lineEnd) prevline = None - while 1: - line = input.readline() - if not line: - break + while line := input.readline(): outline = [] # Strip off any readline induced trailing newline stripped = b'' @@ -126,9 +123,7 @@ def decode(input, output, header=False): return new = b'' - while 1: - line = input.readline() - if not line: break + while line := input.readline(): i, n = 0, len(line) if n > 0 and line[n-1:n] == b'\n': partial = 0; n = n-1 diff --git a/Lib/random.py b/Lib/random.py index d07fffba..84bbfc5d 100644 --- a/Lib/random.py +++ b/Lib/random.py @@ -32,6 +32,11 @@ circular uniform von Mises + discrete distributions + ---------------------- + binomial + + General notes on the underlying Mersenne Twister core generator: * The period is 2**19937-1. @@ -49,8 +54,9 @@ from warnings import warn as _warn from math import log as _log, exp as _exp, pi as _pi, e as _e, ceil as _ceil from math import sqrt as _sqrt, acos as _acos, cos as _cos, sin as _sin from math import tau as TWOPI, floor as _floor, isfinite as _isfinite +from math import lgamma as _lgamma, fabs as _fabs, log2 as _log2 from os import urandom as _urandom -from _collections_abc import Set as _Set, Sequence as _Sequence +from _collections_abc import Sequence as _Sequence from operator import index as _index from itertools import accumulate as _accumulate, repeat as _repeat from bisect import bisect as _bisect @@ -68,6 +74,7 @@ __all__ = [ "Random", "SystemRandom", "betavariate", + "binomialvariate", "choice", "choices", "expovariate", @@ -236,7 +243,7 @@ class Random(_random.Random): "Return a random int in the range [0,n). Defined for n > 0." getrandbits = self.getrandbits - k = n.bit_length() # don't use (n-1) here because n can be 1 + k = n.bit_length() r = getrandbits(k) # 0 <= r < 2**k while r >= n: r = getrandbits(k) @@ -291,58 +298,25 @@ class Random(_random.Random): # This code is a bit messy to make it fast for the # common case while still doing adequate error checking. - try: - istart = _index(start) - except TypeError: - istart = int(start) - if istart != start: - _warn('randrange() will raise TypeError in the future', - DeprecationWarning, 2) - raise ValueError("non-integer arg 1 for randrange()") - _warn('non-integer arguments to randrange() have been deprecated ' - 'since Python 3.10 and will be removed in a subsequent ' - 'version', - DeprecationWarning, 2) + istart = _index(start) if stop is None: # We don't check for "step != 1" because it hasn't been # type checked and converted to an integer yet. if step is not _ONE: - raise TypeError('Missing a non-None stop argument') + raise TypeError("Missing a non-None stop argument") if istart > 0: return self._randbelow(istart) raise ValueError("empty range for randrange()") - # stop argument supplied. - try: - istop = _index(stop) - except TypeError: - istop = int(stop) - if istop != stop: - _warn('randrange() will raise TypeError in the future', - DeprecationWarning, 2) - raise ValueError("non-integer stop for randrange()") - _warn('non-integer arguments to randrange() have been deprecated ' - 'since Python 3.10 and will be removed in a subsequent ' - 'version', - DeprecationWarning, 2) + # Stop argument supplied. + istop = _index(stop) width = istop - istart - try: - istep = _index(step) - except TypeError: - istep = int(step) - if istep != step: - _warn('randrange() will raise TypeError in the future', - DeprecationWarning, 2) - raise ValueError("non-integer step for randrange()") - _warn('non-integer arguments to randrange() have been deprecated ' - 'since Python 3.10 and will be removed in a subsequent ' - 'version', - DeprecationWarning, 2) + istep = _index(step) # Fast path. if istep == 1: if width > 0: return istart + self._randbelow(width) - raise ValueError("empty range for randrange() (%d, %d, %d)" % (istart, istop, width)) + raise ValueError(f"empty range in randrange({start}, {stop})") # Non-unit step argument supplied. if istep > 0: @@ -352,7 +326,7 @@ class Random(_random.Random): else: raise ValueError("zero step for randrange()") if n <= 0: - raise ValueError("empty range for randrange()") + raise ValueError(f"empty range in randrange({start}, {stop}, {step})") return istart + istep * self._randbelow(n) def randint(self, a, b): @@ -610,7 +584,7 @@ class Random(_random.Random): """ return _exp(self.normalvariate(mu, sigma)) - def expovariate(self, lambd): + def expovariate(self, lambd=1.0): """Exponential distribution. lambd is 1.0 divided by the desired mean. It should be @@ -780,6 +754,92 @@ class Random(_random.Random): return alpha * (-_log(u)) ** (1.0 / beta) + ## -------------------- discrete distributions --------------------- + + def binomialvariate(self, n=1, p=0.5): + """Binomial random variable. + + Gives the number of successes for *n* independent trials + with the probability of success in each trial being *p*: + + sum(random() < p for i in range(n)) + + Returns an integer in the range: 0 <= X <= n + + """ + # Error check inputs and handle edge cases + if n < 0: + raise ValueError("n must be non-negative") + if p <= 0.0 or p >= 1.0: + if p == 0.0: + return 0 + if p == 1.0: + return n + raise ValueError("p must be in the range 0.0 <= p <= 1.0") + + random = self.random + + # Fast path for a common case + if n == 1: + return _index(random() < p) + + # Exploit symmetry to establish: p <= 0.5 + if p > 0.5: + return n - self.binomialvariate(n, 1.0 - p) + + if n * p < 10.0: + # BG: Geometric method by Devroye with running time of O(np). + # https://dl.acm.org/doi/pdf/10.1145/42372.42381 + x = y = 0 + c = _log2(1.0 - p) + if not c: + return x + while True: + y += _floor(_log2(random()) / c) + 1 + if y > n: + return x + x += 1 + + # BTRS: Transformed rejection with squeeze method by Wolfgang Hörmann + # https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.47.8407&rep=rep1&type=pdf + assert n*p >= 10.0 and p <= 0.5 + setup_complete = False + + spq = _sqrt(n * p * (1.0 - p)) # Standard deviation of the distribution + b = 1.15 + 2.53 * spq + a = -0.0873 + 0.0248 * b + 0.01 * p + c = n * p + 0.5 + vr = 0.92 - 4.2 / b + + while True: + + u = random() + u -= 0.5 + us = 0.5 - _fabs(u) + k = _floor((2.0 * a / us + b) * u + c) + if k < 0 or k > n: + continue + + # The early-out "squeeze" test substantially reduces + # the number of acceptance condition evaluations. + v = random() + if us >= 0.07 and v <= vr: + return k + + # Acceptance-rejection test. + # Note, the original paper erroneously omits the call to log(v) + # when comparing to the log of the rescaled binomial distribution. + if not setup_complete: + alpha = (2.83 + 5.1 / b) * spq + lpq = _log(p / (1.0 - p)) + m = _floor((n + 1) * p) # Mode of the distribution + h = _lgamma(m + 1) + _lgamma(n - m + 1) + setup_complete = True # Only needs to be done once + v *= alpha / (a / (us * us) + b) + if _log(v) <= h - _lgamma(k + 1) - _lgamma(n - k + 1) + (k - m) * lpq: + return k + + ## ------------------------------------------------------------------ ## --------------- Operating System Random Source ------------------ @@ -846,6 +906,7 @@ vonmisesvariate = _inst.vonmisesvariate gammavariate = _inst.gammavariate gauss = _inst.gauss betavariate = _inst.betavariate +binomialvariate = _inst.binomialvariate paretovariate = _inst.paretovariate weibullvariate = _inst.weibullvariate getstate = _inst.getstate @@ -870,15 +931,17 @@ def _test_generator(n, func, args): low = min(data) high = max(data) - print(f'{t1 - t0:.3f} sec, {n} times {func.__name__}') + print(f'{t1 - t0:.3f} sec, {n} times {func.__name__}{args!r}') print('avg %g, stddev %g, min %g, max %g\n' % (xbar, sigma, low, high)) -def _test(N=2000): +def _test(N=10_000): _test_generator(N, random, ()) _test_generator(N, normalvariate, (0.0, 1.0)) _test_generator(N, lognormvariate, (0.0, 1.0)) _test_generator(N, vonmisesvariate, (0.0, 1.0)) + _test_generator(N, binomialvariate, (15, 0.60)) + _test_generator(N, binomialvariate, (100, 0.75)) _test_generator(N, gammavariate, (0.01, 1.0)) _test_generator(N, gammavariate, (0.1, 1.0)) _test_generator(N, gammavariate, (0.1, 2.0)) diff --git a/Lib/re/__init__.py b/Lib/re/__init__.py index d58c2117..4515650a 100644 --- a/Lib/re/__init__.py +++ b/Lib/re/__init__.py @@ -124,6 +124,7 @@ This module also defines an exception 'error'. import enum from . import _compiler, _parser import functools +import _sre # public symbols @@ -229,7 +230,8 @@ def compile(pattern, flags=0): def purge(): "Clear the regular expression caches" _cache.clear() - _compile_repl.cache_clear() + _cache2.clear() + _compile_template.cache_clear() def template(pattern, flags=0): "Compile a template pattern, returning a Pattern object, deprecated" @@ -266,61 +268,70 @@ Match = type(_compiler.compile('', 0).match('')) # -------------------------------------------------------------------- # internals -_cache = {} # ordered! - +# Use the fact that dict keeps the insertion order. +# _cache2 uses the simple FIFO policy which has better latency. +# _cache uses the LRU policy which has better hit rate. +_cache = {} # LRU +_cache2 = {} # FIFO _MAXCACHE = 512 +_MAXCACHE2 = 256 +assert _MAXCACHE2 < _MAXCACHE + def _compile(pattern, flags): # internal: compile pattern if isinstance(flags, RegexFlag): flags = flags.value try: - return _cache[type(pattern), pattern, flags] + return _cache2[type(pattern), pattern, flags] except KeyError: pass - if isinstance(pattern, Pattern): - if flags: - raise ValueError( - "cannot process flags argument with a compiled pattern") - return pattern - if not _compiler.isstring(pattern): - raise TypeError("first argument must be string or compiled pattern") - if flags & T: - import warnings - warnings.warn("The re.TEMPLATE/re.T flag is deprecated " - "as it is an undocumented flag " - "without an obvious purpose. " - "Don't use it.", - DeprecationWarning) - p = _compiler.compile(pattern, flags) - if not (flags & DEBUG): + + key = (type(pattern), pattern, flags) + # Item in _cache should be moved to the end if found. + p = _cache.pop(key, None) + if p is None: + if isinstance(pattern, Pattern): + if flags: + raise ValueError( + "cannot process flags argument with a compiled pattern") + return pattern + if not _compiler.isstring(pattern): + raise TypeError("first argument must be string or compiled pattern") + if flags & T: + import warnings + warnings.warn("The re.TEMPLATE/re.T flag is deprecated " + "as it is an undocumented flag " + "without an obvious purpose. " + "Don't use it.", + DeprecationWarning) + p = _compiler.compile(pattern, flags) + if flags & DEBUG: + return p if len(_cache) >= _MAXCACHE: - # Drop the oldest item + # Drop the least recently used item. + # next(iter(_cache)) is known to have linear amortized time, + # but it is used here to avoid a dependency from using OrderedDict. + # For the small _MAXCACHE value it doesn't make much of a difference. try: del _cache[next(iter(_cache))] except (StopIteration, RuntimeError, KeyError): pass - _cache[type(pattern), pattern, flags] = p + # Append to the end. + _cache[key] = p + + if len(_cache2) >= _MAXCACHE2: + # Drop the oldest item. + try: + del _cache2[next(iter(_cache2))] + except (StopIteration, RuntimeError, KeyError): + pass + _cache2[key] = p return p @functools.lru_cache(_MAXCACHE) -def _compile_repl(repl, pattern): +def _compile_template(pattern, repl): # internal: compile replacement pattern - return _parser.parse_template(repl, pattern) - -def _expand(pattern, match, template): - # internal: Match.expand implementation hook - template = _parser.parse_template(template, pattern) - return _parser.expand_template(template, match) - -def _subx(pattern, template): - # internal: Pattern.sub/subn implementation helper - template = _compile_repl(template, pattern) - if not template[0] and len(template[1]) == 1: - # literal replacement - return template[1][0] - def filter(match, template=template): - return _parser.expand_template(template, match) - return filter + return _sre.template(pattern, _parser.parse_template(repl, pattern)) # register myself for pickling diff --git a/Lib/re/_constants.py b/Lib/re/_constants.py index 10ee14bf..d8718d36 100644 --- a/Lib/re/_constants.py +++ b/Lib/re/_constants.py @@ -13,7 +13,7 @@ # update when constants are added or removed -MAGIC = 20220615 +MAGIC = 20221023 from _sre import MAXREPEAT, MAXGROUPS diff --git a/Lib/re/_parser.py b/Lib/re/_parser.py index f747a039..74bda2f1 100644 --- a/Lib/re/_parser.py +++ b/Lib/re/_parser.py @@ -114,7 +114,6 @@ class SubPattern: self.width = None def dump(self, level=0): - nl = True seqtypes = (tuple, list) for op, av in self.data: print(level*" " + str(op), end='') @@ -136,6 +135,9 @@ class SubPattern: if item_no: print(level*" " + "ELSE") item_no.dump(level+1) + elif isinstance(av, SubPattern): + print() + av.dump(level+1) elif isinstance(av, seqtypes): nl = False for a in av: @@ -292,17 +294,13 @@ class Tokenizer: msg = msg.encode('ascii', 'backslashreplace').decode('ascii') return error(msg, self.string, self.tell() - offset) - def checkgroupname(self, name, offset, nested): + def checkgroupname(self, name, offset): + if not (self.istext or name.isascii()): + msg = "bad character in group name %a" % name + raise self.error(msg, len(name) + offset) if not name.isidentifier(): msg = "bad character in group name %r" % name raise self.error(msg, len(name) + offset) - if not (self.istext or name.isascii()): - import warnings - warnings.warn( - "bad character in group name %a at position %d" % - (name, self.tell() - len(name) - offset), - DeprecationWarning, stacklevel=nested + 7 - ) def _class_escape(source, escape): # handle escape code inside character class @@ -718,11 +716,11 @@ def _parse(source, state, verbose, nested, first=False): if sourcematch("<"): # named group: skip forward to end of name name = source.getuntil(">", "group name") - source.checkgroupname(name, 1, nested) + source.checkgroupname(name, 1) elif sourcematch("="): # named backreference name = source.getuntil(")", "group name") - source.checkgroupname(name, 1, nested) + source.checkgroupname(name, 1) gid = state.groupdict.get(name) if gid is None: msg = "unknown group name %r" % name @@ -783,20 +781,14 @@ def _parse(source, state, verbose, nested, first=False): elif char == "(": # conditional backreference group condname = source.getuntil(")", "group name") - if condname.isidentifier(): - source.checkgroupname(condname, 1, nested) + if not (condname.isdecimal() and condname.isascii()): + source.checkgroupname(condname, 1) condgroup = state.groupdict.get(condname) if condgroup is None: msg = "unknown group name %r" % condname raise source.error(msg, len(condname) + 1) else: - try: - condgroup = int(condname) - if condgroup < 0: - raise ValueError - except ValueError: - msg = "bad character in group name %r" % condname - raise source.error(msg, len(condname) + 1) from None + condgroup = int(condname) if not condgroup: raise source.error("bad group number", len(condname) + 1) @@ -994,24 +986,28 @@ def parse(str, flags=0, state=None): return p -def parse_template(source, state): +def parse_template(source, pattern): # parse 're' replacement string into list of literals and # group references s = Tokenizer(source) sget = s.get - groups = [] - literals = [] + result = [] literal = [] lappend = literal.append + def addliteral(): + if s.istext: + result.append(''.join(literal)) + else: + # The tokenizer implicitly decodes bytes objects as latin-1, we must + # therefore re-encode the final representation. + result.append(''.join(literal).encode('latin-1')) + del literal[:] def addgroup(index, pos): - if index > state.groups: + if index > pattern.groups: raise s.error("invalid group reference %d" % index, pos) - if literal: - literals.append(''.join(literal)) - del literal[:] - groups.append((len(literals), index)) - literals.append(None) - groupindex = state.groupindex + addliteral() + result.append(index) + groupindex = pattern.groupindex while True: this = sget() if this is None: @@ -1023,20 +1019,14 @@ def parse_template(source, state): if not s.match("<"): raise s.error("missing <") name = s.getuntil(">", "group name") - if name.isidentifier(): - s.checkgroupname(name, 1, -1) + if not (name.isdecimal() and name.isascii()): + s.checkgroupname(name, 1) try: index = groupindex[name] except KeyError: raise IndexError("unknown group name %r" % name) from None else: - try: - index = int(name) - if index < 0: - raise ValueError - except ValueError: - raise s.error("bad character in group name %r" % name, - len(name) + 1) from None + index = int(name) if index >= MAXGROUPS: raise s.error("invalid group reference %d" % index, len(name) + 1) @@ -1079,22 +1069,5 @@ def parse_template(source, state): lappend(this) else: lappend(this) - if literal: - literals.append(''.join(literal)) - if not isinstance(source, str): - # The tokenizer implicitly decodes bytes objects as latin-1, we must - # therefore re-encode the final representation. - literals = [None if s is None else s.encode('latin-1') for s in literals] - return groups, literals - -def expand_template(template, match): - g = match.group - empty = match.string[:0] - groups, literals = template - literals = literals[:] - try: - for index, group in groups: - literals[index] = g(group) or empty - except IndexError: - raise error("invalid group reference %d" % index) from None - return empty.join(literals) + addliteral() + return result diff --git a/Lib/reprlib.py b/Lib/reprlib.py index f3518df1..a92b3e3d 100644 --- a/Lib/reprlib.py +++ b/Lib/reprlib.py @@ -35,19 +35,24 @@ def recursive_repr(fillvalue='...'): class Repr: - def __init__(self): - self.fillvalue = '...' - self.maxlevel = 6 - self.maxtuple = 6 - self.maxlist = 6 - self.maxarray = 5 - self.maxdict = 4 - self.maxset = 6 - self.maxfrozenset = 6 - self.maxdeque = 6 - self.maxstring = 30 - self.maxlong = 40 - self.maxother = 30 + def __init__( + self, *, maxlevel=6, maxtuple=6, maxlist=6, maxarray=5, maxdict=4, + maxset=6, maxfrozenset=6, maxdeque=6, maxstring=30, maxlong=40, + maxother=30, fillvalue='...', indent=None, + ): + self.maxlevel = maxlevel + self.maxtuple = maxtuple + self.maxlist = maxlist + self.maxarray = maxarray + self.maxdict = maxdict + self.maxset = maxset + self.maxfrozenset = maxfrozenset + self.maxdeque = maxdeque + self.maxstring = maxstring + self.maxlong = maxlong + self.maxother = maxother + self.fillvalue = fillvalue + self.indent = indent def repr(self, x): return self.repr1(x, self.maxlevel) @@ -62,6 +67,26 @@ class Repr: else: return self.repr_instance(x, level) + def _join(self, pieces, level): + if self.indent is None: + return ', '.join(pieces) + if not pieces: + return '' + indent = self.indent + if isinstance(indent, int): + if indent < 0: + raise ValueError( + f'Repr.indent cannot be negative int (was {indent!r})' + ) + indent *= ' ' + try: + sep = ',\n' + (self.maxlevel - level + 1) * indent + except TypeError as error: + raise TypeError( + f'Repr.indent must be a str, int or None, not {type(indent)}' + ) from error + return sep.join(('', *pieces, ''))[1:-len(indent) or None] + def _repr_iterable(self, x, level, left, right, maxiter, trail=''): n = len(x) if level <= 0 and n: @@ -72,8 +97,8 @@ class Repr: pieces = [repr1(elem, newlevel) for elem in islice(x, maxiter)] if n > maxiter: pieces.append(self.fillvalue) - s = ', '.join(pieces) - if n == 1 and trail: + s = self._join(pieces, level) + if n == 1 and trail and self.indent is None: right = trail + right return '%s%s%s' % (left, s, right) @@ -120,7 +145,7 @@ class Repr: pieces.append('%s: %s' % (keyrepr, valrepr)) if n > self.maxdict: pieces.append(self.fillvalue) - s = ', '.join(pieces) + s = self._join(pieces, level) return '{%s}' % (s,) def repr_str(self, x, level): diff --git a/Lib/runpy.py b/Lib/runpy.py index 54fc136d..42f896c9 100644 --- a/Lib/runpy.py +++ b/Lib/runpy.py @@ -279,12 +279,7 @@ def run_path(path_name, init_globals=None, run_name=None): pkg_name = run_name.rpartition(".")[0] from pkgutil import get_importer importer = get_importer(path_name) - # Trying to avoid importing imp so as to not consume the deprecation warning. - is_NullImporter = False - if type(importer).__module__ == 'imp': - if type(importer).__name__ == 'NullImporter': - is_NullImporter = True - if isinstance(importer, type(None)) or is_NullImporter: + if isinstance(importer, type(None)): # Not a valid sys.path entry, so run the code directly # execfile() doesn't help as we want to allow compiled files code, fname = _get_code_from_file(run_name, path_name) diff --git a/Lib/secrets.py b/Lib/secrets.py index 900381a8..566a09b7 100644 --- a/Lib/secrets.py +++ b/Lib/secrets.py @@ -13,7 +13,6 @@ __all__ = ['choice', 'randbelow', 'randbits', 'SystemRandom', import base64 -import binascii from hmac import compare_digest from random import SystemRandom @@ -56,7 +55,7 @@ def token_hex(nbytes=None): 'f9bf78b9a18ce6d46a0cd2b0b86df9da' """ - return binascii.hexlify(token_bytes(nbytes)).decode('ascii') + return token_bytes(nbytes).hex() def token_urlsafe(nbytes=None): """Return a random URL-safe text string, in Base64 encoding. diff --git a/Lib/shlex.py b/Lib/shlex.py index 4801a6c1..f4821616 100644 --- a/Lib/shlex.py +++ b/Lib/shlex.py @@ -305,9 +305,7 @@ class shlex: def split(s, comments=False, posix=True): """Split the string *s* using shell-like syntax.""" if s is None: - import warnings - warnings.warn("Passing None for 's' to shlex.split() is deprecated.", - DeprecationWarning, stacklevel=2) + raise ValueError("s argument must not be None") lex = shlex(s, posix=posix) lex.whitespace_split = True if not comments: @@ -335,10 +333,7 @@ def quote(s): def _print_tokens(lexer): - while 1: - tt = lexer.get_token() - if not tt: - break + while tt := lexer.get_token(): print("Token: " + repr(tt)) if __name__ == '__main__': diff --git a/Lib/shutil.py b/Lib/shutil.py index bfed796d..b37bd082 100644 --- a/Lib/shutil.py +++ b/Lib/shutil.py @@ -10,6 +10,7 @@ import stat import fnmatch import collections import errno +import warnings try: import zlib @@ -39,6 +40,11 @@ if os.name == 'posix': elif _WINDOWS: import nt +if sys.platform == 'win32': + import _winapi +else: + _winapi = None + COPY_BUFSIZE = 1024 * 1024 if _WINDOWS else 64 * 1024 # This should never be removed, see rationale in: # https://bugs.python.org/issue43743#msg393429 @@ -182,7 +188,8 @@ def _copyfileobj_readinto(fsrc, fdst, length=COPY_BUFSIZE): break elif n < length: with mv[:n] as smv: - fdst.write(smv) + fdst_write(smv) + break else: fdst_write(mv) @@ -193,10 +200,7 @@ def copyfileobj(fsrc, fdst, length=0): # Localize variable access to minimize overhead. fsrc_read = fsrc.read fdst_write = fdst.write - while True: - buf = fsrc_read(length) - if not buf: - break + while buf := fsrc_read(length): fdst_write(buf) def _samefile(src, dst): @@ -330,7 +334,7 @@ if hasattr(os, 'listxattr'): os.setxattr(dst, name, value, follow_symlinks=follow_symlinks) except OSError as e: if e.errno not in (errno.EPERM, errno.ENOTSUP, errno.ENODATA, - errno.EINVAL): + errno.EINVAL, errno.EACCES): raise else: def _copyxattr(*args, **kwargs): @@ -433,6 +437,29 @@ def copy2(src, dst, *, follow_symlinks=True): """ if os.path.isdir(dst): dst = os.path.join(dst, os.path.basename(src)) + + if hasattr(_winapi, "CopyFile2"): + src_ = os.fsdecode(src) + dst_ = os.fsdecode(dst) + flags = _winapi.COPY_FILE_ALLOW_DECRYPTED_DESTINATION # for compat + if not follow_symlinks: + flags |= _winapi.COPY_FILE_COPY_SYMLINK + try: + _winapi.CopyFile2(src_, dst_, flags) + return dst + except OSError as exc: + if (exc.winerror == _winapi.ERROR_PRIVILEGE_NOT_HELD + and not follow_symlinks): + # Likely encountered a symlink we aren't allowed to create. + # Fall back on the old code + pass + elif exc.winerror == _winapi.ERROR_ACCESS_DENIED: + # Possibly encountered a hidden or readonly file we can't + # overwrite. Fall back on old code + pass + else: + raise + copyfile(src, dst, follow_symlinks=follow_symlinks) copystat(src, dst, follow_symlinks=follow_symlinks) return dst @@ -564,18 +591,6 @@ def copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2, dirs_exist_ok=dirs_exist_ok) if hasattr(os.stat_result, 'st_file_attributes'): - # Special handling for directory junctions to make them behave like - # symlinks for shutil.rmtree, since in general they do not appear as - # regular links. - def _rmtree_isdir(entry): - try: - st = entry.stat(follow_symlinks=False) - return (stat.S_ISDIR(st.st_mode) and not - (st.st_file_attributes & stat.FILE_ATTRIBUTE_REPARSE_POINT - and st.st_reparse_tag == stat.IO_REPARSE_TAG_MOUNT_POINT)) - except OSError: - return False - def _rmtree_islink(path): try: st = os.lstat(path) @@ -585,54 +600,53 @@ if hasattr(os.stat_result, 'st_file_attributes'): except OSError: return False else: - def _rmtree_isdir(entry): - try: - return entry.is_dir(follow_symlinks=False) - except OSError: - return False - def _rmtree_islink(path): return os.path.islink(path) # version vulnerable to race conditions -def _rmtree_unsafe(path, onerror): +def _rmtree_unsafe(path, onexc): try: with os.scandir(path) as scandir_it: entries = list(scandir_it) - except OSError: - onerror(os.scandir, path, sys.exc_info()) + except OSError as err: + onexc(os.scandir, path, err) entries = [] for entry in entries: fullname = entry.path - if _rmtree_isdir(entry): + try: + is_dir = entry.is_dir(follow_symlinks=False) + except OSError: + is_dir = False + + if is_dir and not entry.is_junction(): try: if entry.is_symlink(): # This can only happen if someone replaces # a directory with a symlink after the call to # os.scandir or entry.is_dir above. raise OSError("Cannot call rmtree on a symbolic link") - except OSError: - onerror(os.path.islink, fullname, sys.exc_info()) + except OSError as err: + onexc(os.path.islink, fullname, err) continue - _rmtree_unsafe(fullname, onerror) + _rmtree_unsafe(fullname, onexc) else: try: os.unlink(fullname) - except OSError: - onerror(os.unlink, fullname, sys.exc_info()) + except OSError as err: + onexc(os.unlink, fullname, err) try: os.rmdir(path) - except OSError: - onerror(os.rmdir, path, sys.exc_info()) + except OSError as err: + onexc(os.rmdir, path, err) # Version using fd-based APIs to protect against races -def _rmtree_safe_fd(topfd, path, onerror): +def _rmtree_safe_fd(topfd, path, onexc): try: with os.scandir(topfd) as scandir_it: entries = list(scandir_it) except OSError as err: err.filename = path - onerror(os.scandir, path, sys.exc_info()) + onexc(os.scandir, path, err) return for entry in entries: fullname = os.path.join(path, entry.name) @@ -645,25 +659,25 @@ def _rmtree_safe_fd(topfd, path, onerror): try: orig_st = entry.stat(follow_symlinks=False) is_dir = stat.S_ISDIR(orig_st.st_mode) - except OSError: - onerror(os.lstat, fullname, sys.exc_info()) + except OSError as err: + onexc(os.lstat, fullname, err) continue if is_dir: try: dirfd = os.open(entry.name, os.O_RDONLY, dir_fd=topfd) dirfd_closed = False - except OSError: - onerror(os.open, fullname, sys.exc_info()) + except OSError as err: + onexc(os.open, fullname, err) else: try: if os.path.samestat(orig_st, os.fstat(dirfd)): - _rmtree_safe_fd(dirfd, fullname, onerror) + _rmtree_safe_fd(dirfd, fullname, onexc) try: os.close(dirfd) dirfd_closed = True os.rmdir(entry.name, dir_fd=topfd) - except OSError: - onerror(os.rmdir, fullname, sys.exc_info()) + except OSError as err: + onexc(os.rmdir, fullname, err) else: try: # This can only happen if someone replaces @@ -671,23 +685,23 @@ def _rmtree_safe_fd(topfd, path, onerror): # os.scandir or stat.S_ISDIR above. raise OSError("Cannot call rmtree on a symbolic " "link") - except OSError: - onerror(os.path.islink, fullname, sys.exc_info()) + except OSError as err: + onexc(os.path.islink, fullname, err) finally: if not dirfd_closed: os.close(dirfd) else: try: os.unlink(entry.name, dir_fd=topfd) - except OSError: - onerror(os.unlink, fullname, sys.exc_info()) + except OSError as err: + onexc(os.unlink, fullname, err) _use_fd_functions = ({os.open, os.stat, os.unlink, os.rmdir} <= os.supports_dir_fd and os.scandir in os.supports_fd and os.stat in os.supports_follow_symlinks) -def rmtree(path, ignore_errors=False, onerror=None, *, dir_fd=None): +def rmtree(path, ignore_errors=False, onerror=None, *, onexc=None, dir_fd=None): """Recursively delete a directory tree. If dir_fd is not None, it should be a file descriptor open to a directory; @@ -695,21 +709,44 @@ def rmtree(path, ignore_errors=False, onerror=None, *, dir_fd=None): dir_fd may not be implemented on your platform. If it is unavailable, using it will raise a NotImplementedError. - If ignore_errors is set, errors are ignored; otherwise, if onerror - is set, it is called to handle the error with arguments (func, + If ignore_errors is set, errors are ignored; otherwise, if onexc or + onerror is set, it is called to handle the error with arguments (func, path, exc_info) where func is platform and implementation dependent; path is the argument to that function that caused it to fail; and - exc_info is a tuple returned by sys.exc_info(). If ignore_errors - is false and onerror is None, an exception is raised. + the value of exc_info describes the exception. For onexc it is the + exception instance, and for onerror it is a tuple as returned by + sys.exc_info(). If ignore_errors is false and both onexc and + onerror are None, the exception is reraised. + onerror is deprecated and only remains for backwards compatibility. + If both onerror and onexc are set, onerror is ignored and onexc is used. """ + + if onerror is not None: + warnings.warn("onerror argument is deprecated, use onexc instead", + DeprecationWarning, stacklevel=2) + sys.audit("shutil.rmtree", path, dir_fd) if ignore_errors: - def onerror(*args): + def onexc(*args): pass - elif onerror is None: - def onerror(*args): + elif onerror is None and onexc is None: + def onexc(*args): raise + elif onexc is None: + if onerror is None: + def onexc(*args): + raise + else: + # delegate to onerror + def onexc(*args): + func, path, exc = args + if exc is None: + exc_info = None, None, None + else: + exc_info = type(exc), exc, exc.__traceback__ + return onerror(func, path, exc_info) + if _use_fd_functions: # While the unsafe rmtree works fine on bytes, the fd based does not. if isinstance(path, bytes): @@ -718,30 +755,30 @@ def rmtree(path, ignore_errors=False, onerror=None, *, dir_fd=None): # lstat()/open()/fstat() trick. try: orig_st = os.lstat(path, dir_fd=dir_fd) - except Exception: - onerror(os.lstat, path, sys.exc_info()) + except Exception as err: + onexc(os.lstat, path, err) return try: fd = os.open(path, os.O_RDONLY, dir_fd=dir_fd) fd_closed = False - except Exception: - onerror(os.open, path, sys.exc_info()) + except Exception as err: + onexc(os.open, path, err) return try: if os.path.samestat(orig_st, os.fstat(fd)): - _rmtree_safe_fd(fd, path, onerror) + _rmtree_safe_fd(fd, path, onexc) try: os.close(fd) fd_closed = True os.rmdir(path, dir_fd=dir_fd) - except OSError: - onerror(os.rmdir, path, sys.exc_info()) + except OSError as err: + onexc(os.rmdir, path, err) else: try: # symlinks to directories are forbidden, see bug #1669 raise OSError("Cannot call rmtree on a symbolic link") - except OSError: - onerror(os.path.islink, path, sys.exc_info()) + except OSError as err: + onexc(os.path.islink, path, err) finally: if not fd_closed: os.close(fd) @@ -752,11 +789,11 @@ def rmtree(path, ignore_errors=False, onerror=None, *, dir_fd=None): if _rmtree_islink(path): # symlinks to directories are forbidden, see bug #1669 raise OSError("Cannot call rmtree on a symbolic link") - except OSError: - onerror(os.path.islink, path, sys.exc_info()) - # can't continue even if onerror hook returns + except OSError as err: + onexc(os.path.islink, path, err) + # can't continue even if onexc hook returns return - return _rmtree_unsafe(path, onerror) + return _rmtree_unsafe(path, onexc) # Allow introspection of whether or not the hardening against symlink # attacks is supported on the current platform @@ -1023,28 +1060,30 @@ def _make_zipfile(base_name, base_dir, verbose=0, dry_run=0, zip_filename = os.path.abspath(zip_filename) return zip_filename +_make_tarball.supports_root_dir = True +_make_zipfile.supports_root_dir = True + # Maps the name of the archive format to a tuple containing: # * the archiving function # * extra keyword arguments # * description -# * does it support the root_dir argument? _ARCHIVE_FORMATS = { 'tar': (_make_tarball, [('compress', None)], - "uncompressed tar file", True), + "uncompressed tar file"), } if _ZLIB_SUPPORTED: _ARCHIVE_FORMATS['gztar'] = (_make_tarball, [('compress', 'gzip')], - "gzip'ed tar-file", True) - _ARCHIVE_FORMATS['zip'] = (_make_zipfile, [], "ZIP file", True) + "gzip'ed tar-file") + _ARCHIVE_FORMATS['zip'] = (_make_zipfile, [], "ZIP file") if _BZ2_SUPPORTED: _ARCHIVE_FORMATS['bztar'] = (_make_tarball, [('compress', 'bzip2')], - "bzip2'ed tar-file", True) + "bzip2'ed tar-file") if _LZMA_SUPPORTED: _ARCHIVE_FORMATS['xztar'] = (_make_tarball, [('compress', 'xz')], - "xz'ed tar-file", True) + "xz'ed tar-file") def get_archive_formats(): """Returns a list of supported formats for archiving and unarchiving. @@ -1075,7 +1114,7 @@ def register_archive_format(name, function, extra_args=None, description=''): if not isinstance(element, (tuple, list)) or len(element) !=2: raise TypeError('extra_args elements are : (arg_name, value)') - _ARCHIVE_FORMATS[name] = (function, extra_args, description, False) + _ARCHIVE_FORMATS[name] = (function, extra_args, description) def unregister_archive_format(name): del _ARCHIVE_FORMATS[name] @@ -1114,10 +1153,14 @@ def make_archive(base_name, format, root_dir=None, base_dir=None, verbose=0, if base_dir is None: base_dir = os.curdir - support_root_dir = format_info[3] + supports_root_dir = getattr(func, 'supports_root_dir', False) save_cwd = None if root_dir is not None: - if support_root_dir: + stmd = os.stat(root_dir).st_mode + if not stat.S_ISDIR(stmd): + raise NotADirectoryError(errno.ENOTDIR, 'Not a directory', root_dir) + + if supports_root_dir: # Support path-like base_name here for backwards-compatibility. base_name = os.fspath(base_name) kwargs['root_dir'] = root_dir @@ -1231,7 +1274,7 @@ def _unpack_zipfile(filename, extract_dir): finally: zip.close() -def _unpack_tarfile(filename, extract_dir): +def _unpack_tarfile(filename, extract_dir, *, filter=None): """Unpack tar/tar.gz/tar.bz2/tar.xz `filename` to `extract_dir` """ import tarfile # late import for breaking circular dependency @@ -1241,7 +1284,7 @@ def _unpack_tarfile(filename, extract_dir): raise ReadError( "%s is not a compressed or uncompressed tar file" % filename) try: - tarobj.extractall(extract_dir) + tarobj.extractall(extract_dir, filter=filter) finally: tarobj.close() @@ -1274,7 +1317,7 @@ def _find_unpack_format(filename): return name return None -def unpack_archive(filename, extract_dir=None, format=None): +def unpack_archive(filename, extract_dir=None, format=None, *, filter=None): """Unpack an archive. `filename` is the name of the archive. @@ -1288,6 +1331,9 @@ def unpack_archive(filename, extract_dir=None, format=None): was registered for that extension. In case none is found, a ValueError is raised. + + If `filter` is given, it is passed to the underlying + extraction function. """ sys.audit("shutil.unpack_archive", filename, extract_dir, format) @@ -1297,6 +1343,10 @@ def unpack_archive(filename, extract_dir=None, format=None): extract_dir = os.fspath(extract_dir) filename = os.fspath(filename) + if filter is None: + filter_kwargs = {} + else: + filter_kwargs = {'filter': filter} if format is not None: try: format_info = _UNPACK_FORMATS[format] @@ -1304,7 +1354,7 @@ def unpack_archive(filename, extract_dir=None, format=None): raise ValueError("Unknown unpack format '{0}'".format(format)) from None func = format_info[1] - func(filename, extract_dir, **dict(format_info[2])) + func(filename, extract_dir, **dict(format_info[2]), **filter_kwargs) else: # we need to look at the registered unpackers supported extensions format = _find_unpack_format(filename) @@ -1312,7 +1362,7 @@ def unpack_archive(filename, extract_dir=None, format=None): raise ReadError("Unknown archive format '{0}'".format(filename)) func = _UNPACK_FORMATS[format][1] - kwargs = dict(_UNPACK_FORMATS[format][2]) + kwargs = dict(_UNPACK_FORMATS[format][2]) | filter_kwargs func(filename, extract_dir, **kwargs) @@ -1438,6 +1488,16 @@ def _access_check(fn, mode): and not os.path.isdir(fn)) +def _win_path_needs_curdir(cmd, mode): + """ + On Windows, we can use NeedCurrentDirectoryForExePath to figure out + if we should add the cwd to PATH when searching for executables if + the mode is executable. + """ + return (not (mode & os.X_OK)) or _winapi.NeedCurrentDirectoryForExePath( + os.fsdecode(cmd)) + + def which(cmd, mode=os.F_OK | os.X_OK, path=None): """Given a command, mode, and a PATH string, return the path which conforms to the given mode on the PATH, or None if there is no such @@ -1448,60 +1508,54 @@ def which(cmd, mode=os.F_OK | os.X_OK, path=None): path. """ - # If we're given a path with a directory part, look it up directly rather - # than referring to PATH directories. This includes checking relative to the - # current directory, e.g. ./script - if os.path.dirname(cmd): - if _access_check(cmd, mode): - return cmd - return None - use_bytes = isinstance(cmd, bytes) - if path is None: - path = os.environ.get("PATH", None) - if path is None: - try: - path = os.confstr("CS_PATH") - except (AttributeError, ValueError): - # os.confstr() or CS_PATH is not available - path = os.defpath - # bpo-35755: Don't use os.defpath if the PATH environment variable is - # set to an empty string - - # PATH='' doesn't match, whereas PATH=':' looks in the current directory - if not path: - return None - - if use_bytes: - path = os.fsencode(path) - path = path.split(os.fsencode(os.pathsep)) + # If we're given a path with a directory part, look it up directly rather + # than referring to PATH directories. This includes checking relative to + # the current directory, e.g. ./script + dirname, cmd = os.path.split(cmd) + if dirname: + path = [dirname] else: - path = os.fsdecode(path) - path = path.split(os.pathsep) + if path is None: + path = os.environ.get("PATH", None) + if path is None: + try: + path = os.confstr("CS_PATH") + except (AttributeError, ValueError): + # os.confstr() or CS_PATH is not available + path = os.defpath + # bpo-35755: Don't use os.defpath if the PATH environment variable + # is set to an empty string + + # PATH='' doesn't match, whereas PATH=':' looks in the current + # directory + if not path: + return None - if sys.platform == "win32": - # The current directory takes precedence on Windows. - curdir = os.curdir if use_bytes: - curdir = os.fsencode(curdir) - if curdir not in path: + path = os.fsencode(path) + path = path.split(os.fsencode(os.pathsep)) + else: + path = os.fsdecode(path) + path = path.split(os.pathsep) + + if sys.platform == "win32" and _win_path_needs_curdir(cmd, mode): + curdir = os.curdir + if use_bytes: + curdir = os.fsencode(curdir) path.insert(0, curdir) + if sys.platform == "win32": # PATHEXT is necessary to check on Windows. pathext_source = os.getenv("PATHEXT") or _WIN_DEFAULT_PATHEXT pathext = [ext for ext in pathext_source.split(os.pathsep) if ext] if use_bytes: pathext = [os.fsencode(ext) for ext in pathext] - # See if the given file matches any of the expected path extensions. - # This will allow us to short circuit when given "python.exe". - # If it does match, only test that one, otherwise we have to try - # others. - if any(cmd.lower().endswith(ext.lower()) for ext in pathext): - files = [cmd] - else: - files = [cmd + ext for ext in pathext] + + # Always try checking the originally given cmd, if it doesn't match, try pathext + files = [cmd] + [cmd + ext for ext in pathext] else: # On other platforms you don't have things like PATHEXT to tell you # what file suffixes are executable, so just pass on cmd as-is. diff --git a/Lib/site.py b/Lib/site.py index 69670d9d..672fa7b0 100644 --- a/Lib/site.py +++ b/Lib/site.py @@ -190,11 +190,11 @@ def addpackage(sitedir, name, known_paths): if not dircase in known_paths and os.path.exists(dir): sys.path.append(dir) known_paths.add(dircase) - except Exception: + except Exception as exc: print("Error processing line {:d} of {}:\n".format(n+1, fullname), file=sys.stderr) import traceback - for record in traceback.format_exception(*sys.exc_info()): + for record in traceback.format_exception(exc): for line in record.splitlines(): print(' '+line, file=sys.stderr) print("\nRemainder of file ignored", file=sys.stderr) @@ -404,12 +404,7 @@ def setquit(): def setcopyright(): """Set 'copyright' and 'credits' in builtins""" builtins.copyright = _sitebuiltins._Printer("copyright", sys.copyright) - if sys.platform[:4] == 'java': - builtins.credits = _sitebuiltins._Printer( - "credits", - "Jython is maintained by the Jython developers (www.jython.org).") - else: - builtins.credits = _sitebuiltins._Printer("credits", """\ + builtins.credits = _sitebuiltins._Printer("credits", """\ Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands for supporting Python development. See www.python.org for more information.""") files, dirs = [], [] @@ -497,20 +492,23 @@ def venv(known_paths): executable = sys._base_executable = os.environ['__PYVENV_LAUNCHER__'] else: executable = sys.executable - exe_dir, _ = os.path.split(os.path.abspath(executable)) + exe_dir = os.path.dirname(os.path.abspath(executable)) site_prefix = os.path.dirname(exe_dir) sys._home = None conf_basename = 'pyvenv.cfg' - candidate_confs = [ - conffile for conffile in ( - os.path.join(exe_dir, conf_basename), - os.path.join(site_prefix, conf_basename) + candidate_conf = next( + ( + conffile for conffile in ( + os.path.join(exe_dir, conf_basename), + os.path.join(site_prefix, conf_basename) ) - if os.path.isfile(conffile) - ] + if os.path.isfile(conffile) + ), + None + ) - if candidate_confs: - virtual_conf = candidate_confs[0] + if candidate_conf: + virtual_conf = candidate_conf system_site = "true" # Issue 25185: Use UTF-8, as that's what the venv module uses when # writing the file. diff --git a/Lib/smtplib.py b/Lib/smtplib.py index 324a1c19..18c91746 100755 --- a/Lib/smtplib.py +++ b/Lib/smtplib.py @@ -749,14 +749,14 @@ class SMTP: # We could not login successfully. Return result of last attempt. raise last_exception - def starttls(self, keyfile=None, certfile=None, context=None): + def starttls(self, *, context=None): """Puts the connection to the SMTP server into TLS mode. If there has been no previous EHLO or HELO command this session, this method tries ESMTP EHLO first. If the server supports TLS, this will encrypt the rest of the SMTP - session. If you provide the keyfile and certfile parameters, + session. If you provide the context parameter, the identity of the SMTP server and client can be checked. This, however, depends on whether the socket module really checks the certificates. @@ -774,19 +774,8 @@ class SMTP: if resp == 220: if not _have_ssl: raise RuntimeError("No SSL support included in this Python") - if context is not None and keyfile is not None: - raise ValueError("context and keyfile arguments are mutually " - "exclusive") - if context is not None and certfile is not None: - raise ValueError("context and certfile arguments are mutually " - "exclusive") - if keyfile is not None or certfile is not None: - import warnings - warnings.warn("keyfile and certfile are deprecated, use a " - "custom context instead", DeprecationWarning, 2) if context is None: - context = ssl._create_stdlib_context(certfile=certfile, - keyfile=keyfile) + context = ssl._create_stdlib_context() self.sock = context.wrap_socket(self.sock, server_hostname=self._host) self.file = None @@ -1017,35 +1006,18 @@ if _have_ssl: compiled with SSL support). If host is not specified, '' (the local host) is used. If port is omitted, the standard SMTP-over-SSL port (465) is used. local_hostname and source_address have the same meaning - as they do in the SMTP class. keyfile and certfile are also optional - - they can contain a PEM formatted private key and certificate chain file - for the SSL connection. context also optional, can contain a - SSLContext, and is an alternative to keyfile and certfile; If it is - specified both keyfile and certfile must be None. + as they do in the SMTP class. context also optional, can contain a + SSLContext. """ default_port = SMTP_SSL_PORT def __init__(self, host='', port=0, local_hostname=None, - keyfile=None, certfile=None, - timeout=socket._GLOBAL_DEFAULT_TIMEOUT, + *, timeout=socket._GLOBAL_DEFAULT_TIMEOUT, source_address=None, context=None): - if context is not None and keyfile is not None: - raise ValueError("context and keyfile arguments are mutually " - "exclusive") - if context is not None and certfile is not None: - raise ValueError("context and certfile arguments are mutually " - "exclusive") - if keyfile is not None or certfile is not None: - import warnings - warnings.warn("keyfile and certfile are deprecated, use a " - "custom context instead", DeprecationWarning, 2) - self.keyfile = keyfile - self.certfile = certfile if context is None: - context = ssl._create_stdlib_context(certfile=certfile, - keyfile=keyfile) + context = ssl._create_stdlib_context() self.context = context SMTP.__init__(self, host, port, local_hostname, timeout, source_address) @@ -1127,10 +1099,7 @@ if __name__ == '__main__': toaddrs = prompt("To").split(',') print("Enter message, end with ^D:") msg = '' - while 1: - line = sys.stdin.readline() - if not line: - break + while line := sys.stdin.readline(): msg = msg + line print("Message length is %d" % len(msg)) diff --git a/Lib/socket.py b/Lib/socket.py index 5a896bee..321fcda5 100644 --- a/Lib/socket.py +++ b/Lib/socket.py @@ -28,6 +28,7 @@ socket.getdefaulttimeout() -- get the default timeout value socket.setdefaulttimeout() -- set the default timeout value create_connection() -- connects to an address, with an optional timeout and optional source address. +create_server() -- create a TCP socket and bind it to a specified address. [*] not available on all platforms! @@ -909,7 +910,7 @@ def create_server(address, *, family=AF_INET, backlog=None, reuse_port=False, # address, effectively preventing this one from accepting # connections. Also, it may set the process in a state where # it'll no longer respond to any signals or graceful kills. - # See: msdn2.microsoft.com/en-us/library/ms740621(VS.85).aspx + # See: https://learn.microsoft.com/windows/win32/winsock/using-so-reuseaddr-and-so-exclusiveaddruse if os.name not in ('nt', 'cygwin') and \ hasattr(_socket, 'SO_REUSEADDR'): try: diff --git a/Lib/socketserver.py b/Lib/socketserver.py index 30a5cfa5..cd028ef1 100644 --- a/Lib/socketserver.py +++ b/Lib/socketserver.py @@ -141,6 +141,8 @@ if hasattr(socket, "AF_UNIX"): __all__.extend(["UnixStreamServer","UnixDatagramServer", "ThreadingUnixStreamServer", "ThreadingUnixDatagramServer"]) + if hasattr(os, "fork"): + __all__.extend(["ForkingUnixStreamServer", "ForkingUnixDatagramServer"]) # poll/select have the advantage of not requiring any extra file descriptor, # contrarily to epoll/kqueue (also, they require a single syscall). @@ -292,8 +294,7 @@ class BaseServer: selector.register(self, selectors.EVENT_READ) while True: - ready = selector.select(timeout) - if ready: + if selector.select(timeout): return self._handle_request_noblock() else: if timeout is not None: @@ -728,6 +729,11 @@ if hasattr(socket, 'AF_UNIX'): class ThreadingUnixDatagramServer(ThreadingMixIn, UnixDatagramServer): pass + if hasattr(os, "fork"): + class ForkingUnixStreamServer(ForkingMixIn, UnixStreamServer): pass + + class ForkingUnixDatagramServer(ForkingMixIn, UnixDatagramServer): pass + class BaseRequestHandler: """Base class for request handler classes. diff --git a/Lib/sqlite3/__init__.py b/Lib/sqlite3/__init__.py index 5a2dbd36..927267cf 100644 --- a/Lib/sqlite3/__init__.py +++ b/Lib/sqlite3/__init__.py @@ -55,17 +55,16 @@ The sqlite3 module is written by Gerhard Häring <gh@ghaering.de>. """ from sqlite3.dbapi2 import * +from sqlite3.dbapi2 import (_deprecated_names, + _deprecated_version_info, + _deprecated_version) -# bpo-42264: OptimizedUnicode was deprecated in Python 3.10. It's scheduled -# for removal in Python 3.12. def __getattr__(name): - if name == "OptimizedUnicode": - import warnings - msg = (""" - OptimizedUnicode is deprecated and will be removed in Python 3.12. - Since Python 3.3 it has simply been an alias for 'str'. - """) - warnings.warn(msg, DeprecationWarning, stacklevel=2) - return str - raise AttributeError(f"module 'sqlite3' has no attribute '{name}'") + if name in _deprecated_names: + from warnings import warn + + warn(f"{name} is deprecated and will be removed in Python 3.14", + DeprecationWarning, stacklevel=2) + return globals()[f"_deprecated_{name}"] + raise AttributeError(f"module {__name__!r} has no attribute {name!r}") diff --git a/Lib/sqlite3/__main__.py b/Lib/sqlite3/__main__.py new file mode 100644 index 00000000..3b597633 --- /dev/null +++ b/Lib/sqlite3/__main__.py @@ -0,0 +1,127 @@ +"""A simple SQLite CLI for the sqlite3 module. + +Apart from using 'argparse' for the command-line interface, +this module implements the REPL as a thin wrapper around +the InteractiveConsole class from the 'code' stdlib module. +""" +import sqlite3 +import sys + +from argparse import ArgumentParser +from code import InteractiveConsole +from textwrap import dedent + + +def execute(c, sql, suppress_errors=True): + """Helper that wraps execution of SQL code. + + This is used both by the REPL and by direct execution from the CLI. + + 'c' may be a cursor or a connection. + 'sql' is the SQL string to execute. + """ + + try: + for row in c.execute(sql): + print(row) + except sqlite3.Error as e: + tp = type(e).__name__ + try: + print(f"{tp} ({e.sqlite_errorname}): {e}", file=sys.stderr) + except AttributeError: + print(f"{tp}: {e}", file=sys.stderr) + if not suppress_errors: + sys.exit(1) + + +class SqliteInteractiveConsole(InteractiveConsole): + """A simple SQLite REPL.""" + + def __init__(self, connection): + super().__init__() + self._con = connection + self._cur = connection.cursor() + + def runsource(self, source, filename="<input>", symbol="single"): + """Override runsource, the core of the InteractiveConsole REPL. + + Return True if more input is needed; buffering is done automatically. + Return False is input is a complete statement ready for execution. + """ + match source: + case ".version": + print(f"{sqlite3.sqlite_version}") + case ".help": + print("Enter SQL code and press enter.") + case ".quit": + sys.exit(0) + case _: + if not sqlite3.complete_statement(source): + return True + execute(self._cur, source) + return False + + +def main(*args): + parser = ArgumentParser( + description="Python sqlite3 CLI", + prog="python -m sqlite3", + ) + parser.add_argument( + "filename", type=str, default=":memory:", nargs="?", + help=( + "SQLite database to open (defaults to ':memory:'). " + "A new database is created if the file does not previously exist." + ), + ) + parser.add_argument( + "sql", type=str, nargs="?", + help=( + "An SQL query to execute. " + "Any returned rows are printed to stdout." + ), + ) + parser.add_argument( + "-v", "--version", action="version", + version=f"SQLite version {sqlite3.sqlite_version}", + help="Print underlying SQLite library version", + ) + args = parser.parse_args(*args) + + if args.filename == ":memory:": + db_name = "a transient in-memory database" + else: + db_name = repr(args.filename) + + # Prepare REPL banner and prompts. + if sys.platform == "win32" and "idlelib.run" not in sys.modules: + eofkey = "CTRL-Z" + else: + eofkey = "CTRL-D" + banner = dedent(f""" + sqlite3 shell, running on SQLite version {sqlite3.sqlite_version} + Connected to {db_name} + + Each command will be run using execute() on the cursor. + Type ".help" for more information; type ".quit" or {eofkey} to quit. + """).strip() + sys.ps1 = "sqlite> " + sys.ps2 = " ... " + + con = sqlite3.connect(args.filename, isolation_level=None) + try: + if args.sql: + # SQL statement provided on the command-line; execute it directly. + execute(con, args.sql, suppress_errors=False) + else: + # No SQL provided; start the REPL. + console = SqliteInteractiveConsole(con) + console.interact(banner, exitmsg="") + finally: + con.close() + + sys.exit(0) + + +if __name__ == "__main__": + main(sys.argv[1:]) diff --git a/Lib/sqlite3/dbapi2.py b/Lib/sqlite3/dbapi2.py index 7cf4dd32..56fc0461 100644 --- a/Lib/sqlite3/dbapi2.py +++ b/Lib/sqlite3/dbapi2.py @@ -25,6 +25,9 @@ import time import collections.abc from _sqlite3 import * +from _sqlite3 import _deprecated_version + +_deprecated_names = frozenset({"version", "version_info"}) paramstyle = "qmark" @@ -45,23 +48,32 @@ def TimeFromTicks(ticks): def TimestampFromTicks(ticks): return Timestamp(*time.localtime(ticks)[:6]) -version_info = tuple([int(x) for x in version.split(".")]) +_deprecated_version_info = tuple(map(int, _deprecated_version.split("."))) sqlite_version_info = tuple([int(x) for x in sqlite_version.split(".")]) Binary = memoryview collections.abc.Sequence.register(Row) def register_adapters_and_converters(): + from warnings import warn + + msg = ("The default {what} is deprecated as of Python 3.12; " + "see the sqlite3 documentation for suggested replacement recipes") + def adapt_date(val): + warn(msg.format(what="date adapter"), DeprecationWarning, stacklevel=2) return val.isoformat() def adapt_datetime(val): + warn(msg.format(what="datetime adapter"), DeprecationWarning, stacklevel=2) return val.isoformat(" ") def convert_date(val): + warn(msg.format(what="date converter"), DeprecationWarning, stacklevel=2) return datetime.date(*map(int, val.split(b"-"))) def convert_timestamp(val): + warn(msg.format(what="timestamp converter"), DeprecationWarning, stacklevel=2) datepart, timepart = val.split(b" ") year, month, day = map(int, datepart.split(b"-")) timepart_full = timepart.split(b".") @@ -82,20 +94,15 @@ def register_adapters_and_converters(): register_adapters_and_converters() -# bpo-24464: enable_shared_cache was deprecated in Python 3.10. It's -# scheduled for removal in Python 3.12. -def enable_shared_cache(enable): - from _sqlite3 import enable_shared_cache as _old_enable_shared_cache - import warnings - msg = ( - "enable_shared_cache is deprecated and will be removed in Python 3.12. " - "Shared cache is strongly discouraged by the SQLite 3 documentation. " - "If shared cache must be used, open the database in URI mode using" - "the cache=shared query parameter." - ) - warnings.warn(msg, DeprecationWarning, stacklevel=2) - return _old_enable_shared_cache(enable) - # Clean up namespace del(register_adapters_and_converters) + +def __getattr__(name): + if name in _deprecated_names: + from warnings import warn + + warn(f"{name} is deprecated and will be removed in Python 3.14", + DeprecationWarning, stacklevel=2) + return globals()[f"_deprecated_{name}"] + raise AttributeError(f"module {__name__!r} has no attribute {name!r}") diff --git a/Lib/sqlite3/dump.py b/Lib/sqlite3/dump.py index 07b9da10..1cf8759f 100644 --- a/Lib/sqlite3/dump.py +++ b/Lib/sqlite3/dump.py @@ -16,6 +16,7 @@ def _iterdump(connection): directly but instead called from the Connection method, iterdump(). """ + writeable_schema = False cu = connection.cursor() yield('BEGIN TRANSACTION;') @@ -42,13 +43,15 @@ def _iterdump(connection): yield('ANALYZE "sqlite_master";') elif table_name.startswith('sqlite_'): continue - # NOTE: Virtual table support not implemented - #elif sql.startswith('CREATE VIRTUAL TABLE'): - # qtable = table_name.replace("'", "''") - # yield("INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"\ - # "VALUES('table','{0}','{0}',0,'{1}');".format( - # qtable, - # sql.replace("''"))) + elif sql.startswith('CREATE VIRTUAL TABLE'): + if not writeable_schema: + writeable_schema = True + yield('PRAGMA writable_schema=ON;') + yield("INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)" + "VALUES('table','{0}','{0}',0,'{1}');".format( + table_name.replace("'", "''"), + sql.replace("'", "''"), + )) else: yield('{0};'.format(sql)) @@ -74,6 +77,9 @@ def _iterdump(connection): for name, type, sql in schema_res.fetchall(): yield('{0};'.format(sql)) + if writeable_schema: + yield('PRAGMA writable_schema=OFF;') + # gh-79009: Yield statements concerning the sqlite_sequence table at the # end of the transaction. for row in sqlite_sequence: diff --git a/Lib/ssl.py b/Lib/ssl.py index ebac1d60..c4c5a4ca 100644 --- a/Lib/ssl.py +++ b/Lib/ssl.py @@ -106,7 +106,7 @@ from _ssl import ( SSLSyscallError, SSLEOFError, SSLCertVerificationError ) from _ssl import txt2obj as _txt2obj, nid2obj as _nid2obj -from _ssl import RAND_status, RAND_add, RAND_bytes, RAND_pseudo_bytes +from _ssl import RAND_status, RAND_add, RAND_bytes try: from _ssl import RAND_egd except ImportError: @@ -373,68 +373,6 @@ def _ipaddress_match(cert_ipaddress, host_ip): return ip == host_ip -def match_hostname(cert, hostname): - """Verify that *cert* (in decoded format as returned by - SSLSocket.getpeercert()) matches the *hostname*. RFC 2818 and RFC 6125 - rules are followed. - - The function matches IP addresses rather than dNSNames if hostname is a - valid ipaddress string. IPv4 addresses are supported on all platforms. - IPv6 addresses are supported on platforms with IPv6 support (AF_INET6 - and inet_pton). - - CertificateError is raised on failure. On success, the function - returns nothing. - """ - warnings.warn( - "ssl.match_hostname() is deprecated", - category=DeprecationWarning, - stacklevel=2 - ) - if not cert: - raise ValueError("empty or no certificate, match_hostname needs a " - "SSL socket or SSL context with either " - "CERT_OPTIONAL or CERT_REQUIRED") - try: - host_ip = _inet_paton(hostname) - except ValueError: - # Not an IP address (common case) - host_ip = None - dnsnames = [] - san = cert.get('subjectAltName', ()) - for key, value in san: - if key == 'DNS': - if host_ip is None and _dnsname_match(value, hostname): - return - dnsnames.append(value) - elif key == 'IP Address': - if host_ip is not None and _ipaddress_match(value, host_ip): - return - dnsnames.append(value) - if not dnsnames: - # The subject is only checked when there is no dNSName entry - # in subjectAltName - for sub in cert.get('subject', ()): - for key, value in sub: - # XXX according to RFC 2818, the most specific Common Name - # must be used. - if key == 'commonName': - if _dnsname_match(value, hostname): - return - dnsnames.append(value) - if len(dnsnames) > 1: - raise CertificateError("hostname %r " - "doesn't match either of %s" - % (hostname, ', '.join(map(repr, dnsnames)))) - elif len(dnsnames) == 1: - raise CertificateError("hostname %r " - "doesn't match %r" - % (hostname, dnsnames[0])) - else: - raise CertificateError("no appropriate commonName or " - "subjectAltName fields were found") - - DefaultVerifyPaths = namedtuple("DefaultVerifyPaths", "cafile capath openssl_cafile_env openssl_cafile openssl_capath_env " "openssl_capath") @@ -1037,7 +975,7 @@ class SSLSocket(socket): ) self = cls.__new__(cls, **kwargs) super(SSLSocket, self).__init__(**kwargs) - self.settimeout(sock.gettimeout()) + sock_timeout = sock.gettimeout() sock.detach() self._context = context @@ -1056,9 +994,42 @@ class SSLSocket(socket): if e.errno != errno.ENOTCONN: raise connected = False + blocking = self.getblocking() + self.setblocking(False) + try: + # We are not connected so this is not supposed to block, but + # testing revealed otherwise on macOS and Windows so we do + # the non-blocking dance regardless. Our raise when any data + # is found means consuming the data is harmless. + notconn_pre_handshake_data = self.recv(1) + except OSError as e: + # EINVAL occurs for recv(1) on non-connected on unix sockets. + if e.errno not in (errno.ENOTCONN, errno.EINVAL): + raise + notconn_pre_handshake_data = b'' + self.setblocking(blocking) + if notconn_pre_handshake_data: + # This prevents pending data sent to the socket before it was + # closed from escaping to the caller who could otherwise + # presume it came through a successful TLS connection. + reason = "Closed before TLS handshake with data in recv buffer." + notconn_pre_handshake_data_error = SSLError(e.errno, reason) + # Add the SSLError attributes that _ssl.c always adds. + notconn_pre_handshake_data_error.reason = reason + notconn_pre_handshake_data_error.library = None + try: + self.close() + except OSError: + pass + try: + raise notconn_pre_handshake_data_error + finally: + # Explicitly break the reference cycle. + notconn_pre_handshake_data_error = None else: connected = True + self.settimeout(sock_timeout) # Must come after setblocking() calls. self._connected = connected if connected: # create the SSL object @@ -1419,36 +1390,6 @@ SSLContext.sslsocket_class = SSLSocket SSLContext.sslobject_class = SSLObject -def wrap_socket(sock, keyfile=None, certfile=None, - server_side=False, cert_reqs=CERT_NONE, - ssl_version=PROTOCOL_TLS, ca_certs=None, - do_handshake_on_connect=True, - suppress_ragged_eofs=True, - ciphers=None): - warnings.warn( - "ssl.wrap_socket() is deprecated, use SSLContext.wrap_socket()", - category=DeprecationWarning, - stacklevel=2 - ) - if server_side and not certfile: - raise ValueError("certfile must be specified for server-side " - "operations") - if keyfile and not certfile: - raise ValueError("certfile must be specified") - context = SSLContext(ssl_version) - context.verify_mode = cert_reqs - if ca_certs: - context.load_verify_locations(ca_certs) - if certfile: - context.load_cert_chain(certfile, keyfile) - if ciphers: - context.set_ciphers(ciphers) - return context.wrap_socket( - sock=sock, server_side=server_side, - do_handshake_on_connect=do_handshake_on_connect, - suppress_ragged_eofs=suppress_ragged_eofs - ) - # some utility functions def cert_time_to_seconds(cert_time): diff --git a/Lib/statistics.py b/Lib/statistics.py index 3b3b43ba..6bd214bb 100644 --- a/Lib/statistics.py +++ b/Lib/statistics.py @@ -134,11 +134,11 @@ import sys from fractions import Fraction from decimal import Decimal -from itertools import groupby, repeat +from itertools import count, groupby, repeat from bisect import bisect_left, bisect_right -from math import hypot, sqrt, fabs, exp, erf, tau, log, fsum +from math import hypot, sqrt, fabs, exp, erf, tau, log, fsum, sumprod from functools import reduce -from operator import mul +from operator import itemgetter from collections import Counter, namedtuple, defaultdict _SQRT2 = sqrt(2.0) @@ -356,6 +356,60 @@ def _fail_neg(values, errmsg='negative value'): yield x +def _rank(data, /, *, key=None, reverse=False, ties='average', start=1) -> list[float]: + """Rank order a dataset. The lowest value has rank 1. + + Ties are averaged so that equal values receive the same rank: + + >>> data = [31, 56, 31, 25, 75, 18] + >>> _rank(data) + [3.5, 5.0, 3.5, 2.0, 6.0, 1.0] + + The operation is idempotent: + + >>> _rank([3.5, 5.0, 3.5, 2.0, 6.0, 1.0]) + [3.5, 5.0, 3.5, 2.0, 6.0, 1.0] + + It is possible to rank the data in reverse order so that the + highest value has rank 1. Also, a key-function can extract + the field to be ranked: + + >>> goals = [('eagles', 45), ('bears', 48), ('lions', 44)] + >>> _rank(goals, key=itemgetter(1), reverse=True) + [2.0, 1.0, 3.0] + + Ranks are conventionally numbered starting from one; however, + setting *start* to zero allows the ranks to be used as array indices: + + >>> prize = ['Gold', 'Silver', 'Bronze', 'Certificate'] + >>> scores = [8.1, 7.3, 9.4, 8.3] + >>> [prize[int(i)] for i in _rank(scores, start=0, reverse=True)] + ['Bronze', 'Certificate', 'Gold', 'Silver'] + + """ + # If this function becomes public at some point, more thought + # needs to be given to the signature. A list of ints is + # plausible when ties is "min" or "max". When ties is "average", + # either list[float] or list[Fraction] is plausible. + + # Default handling of ties matches scipy.stats.mstats.spearmanr. + if ties != 'average': + raise ValueError(f'Unknown tie resolution method: {ties!r}') + if key is not None: + data = map(key, data) + val_pos = sorted(zip(data, count()), reverse=reverse) + i = start - 1 + result = [0] * len(val_pos) + for _, g in groupby(val_pos, key=itemgetter(0)): + group = list(g) + size = len(group) + rank = i + (size + 1) / 2 + for value, orig_pos in group: + result[orig_pos] = rank + i += size + return result + + def _integer_sqrt_of_frac_rto(n: int, m: int) -> int: """Square root of n/m, rounded to the nearest integer using round-to-odd.""" # Reference: https://www.lri.fr/~melquion/doc/05-imacs17_1-expose.pdf @@ -442,28 +496,26 @@ def fmean(data, weights=None): >>> fmean([3.5, 4.0, 5.25]) 4.25 """ - try: - n = len(data) - except TypeError: - # Handle iterators that do not define __len__(). - n = 0 - def count(iterable): - nonlocal n - for n, x in enumerate(iterable, start=1): - yield x - data = count(data) if weights is None: + try: + n = len(data) + except TypeError: + # Handle iterators that do not define __len__(). + n = 0 + def count(iterable): + nonlocal n + for n, x in enumerate(iterable, start=1): + yield x + data = count(data) total = fsum(data) if not n: raise StatisticsError('fmean requires at least one data point') return total / n - try: - num_weights = len(weights) - except TypeError: + if not isinstance(weights, (list, tuple)): weights = list(weights) - num_weights = len(weights) - num = fsum(map(mul, data, weights)) - if n != num_weights: + try: + num = sumprod(data, weights) + except ValueError: raise StatisticsError('data and weights must be the same length') den = fsum(weights) if not den: @@ -984,18 +1036,16 @@ def covariance(x, y, /): raise StatisticsError('covariance requires at least two data points') xbar = fsum(x) / n ybar = fsum(y) / n - sxy = fsum((xi - xbar) * (yi - ybar) for xi, yi in zip(x, y)) + sxy = sumprod((xi - xbar for xi in x), (yi - ybar for yi in y)) return sxy / (n - 1) -def correlation(x, y, /): +def correlation(x, y, /, *, method='linear'): """Pearson's correlation coefficient Return the Pearson's correlation coefficient for two inputs. Pearson's - correlation coefficient *r* takes values between -1 and +1. It measures the - strength and direction of the linear relationship, where +1 means very - strong, positive linear relationship, -1 very strong, negative linear - relationship, and 0 no linear relationship. + correlation coefficient *r* takes values between -1 and +1. It measures + the strength and direction of a linear relationship. >>> x = [1, 2, 3, 4, 5, 6, 7, 8, 9] >>> y = [9, 8, 7, 6, 5, 4, 3, 2, 1] @@ -1004,17 +1054,34 @@ def correlation(x, y, /): >>> correlation(x, y) -1.0 + If *method* is "ranked", computes Spearman's rank correlation coefficient + for two inputs. The data is replaced by ranks. Ties are averaged + so that equal values receive the same rank. The resulting coefficient + measures the strength of a monotonic relationship. + + Spearman's rank correlation coefficient is appropriate for ordinal + data or for continuous data that doesn't meet the linear proportion + requirement for Pearson's correlation coefficient. """ n = len(x) if len(y) != n: raise StatisticsError('correlation requires that both inputs have same number of data points') if n < 2: raise StatisticsError('correlation requires at least two data points') - xbar = fsum(x) / n - ybar = fsum(y) / n - sxy = fsum((xi - xbar) * (yi - ybar) for xi, yi in zip(x, y)) - sxx = fsum((d := xi - xbar) * d for xi in x) - syy = fsum((d := yi - ybar) * d for yi in y) + if method not in {'linear', 'ranked'}: + raise ValueError(f'Unknown method: {method!r}') + if method == 'ranked': + start = (n - 1) / -2 # Center rankings around zero + x = _rank(x, start=start) + y = _rank(y, start=start) + else: + xbar = fsum(x) / n + ybar = fsum(y) / n + x = [xi - xbar for xi in x] + y = [yi - ybar for yi in y] + sxy = sumprod(x, y) + sxx = sumprod(x, x) + syy = sumprod(y, y) try: return sxy / sqrt(sxx * syy) except ZeroDivisionError: @@ -1067,14 +1134,13 @@ def linear_regression(x, y, /, *, proportional=False): raise StatisticsError('linear regression requires that both inputs have same number of data points') if n < 2: raise StatisticsError('linear regression requires at least two data points') - if proportional: - sxy = fsum(xi * yi for xi, yi in zip(x, y)) - sxx = fsum(xi * xi for xi in x) - else: + if not proportional: xbar = fsum(x) / n ybar = fsum(y) / n - sxy = fsum((xi - xbar) * (yi - ybar) for xi, yi in zip(x, y)) - sxx = fsum((d := xi - xbar) * d for xi in x) + x = [xi - xbar for xi in x] # List because used three times below + y = (yi - ybar for yi in y) # Generator because only used once below + sxy = sumprod(x, y) + 0.0 # Add zero to coerce result to a float + sxx = sumprod(x, x) try: slope = sxy / sxx # equivalent to: covariance(x, y) / variance(x) except ZeroDivisionError: @@ -1193,7 +1259,7 @@ class NormalDist: "Generate *n* samples for a given mean and standard deviation." gauss = random.gauss if seed is None else random.Random(seed).gauss mu, sigma = self._mu, self._sigma - return [gauss(mu, sigma) for i in range(n)] + return [gauss(mu, sigma) for _ in repeat(None, n)] def pdf(self, x): "Probability density function. P(x <= X < x+dx) / dx" @@ -1221,8 +1287,6 @@ class NormalDist: """ if p <= 0.0 or p >= 1.0: raise StatisticsError('p must be in the range 0.0 < p < 1.0') - if self._sigma <= 0.0: - raise StatisticsError('cdf() not defined when sigma at or below zero') return _normal_dist_inv_cdf(p, self._mu, self._sigma) def quantiles(self, n=4): diff --git a/Lib/subprocess.py b/Lib/subprocess.py index 9cadd1bf..6df5dd55 100644 --- a/Lib/subprocess.py +++ b/Lib/subprocess.py @@ -346,7 +346,7 @@ def _args_from_interpreter_flags(): if dev_mode: args.extend(('-X', 'dev')) for opt in ('faulthandler', 'tracemalloc', 'importtime', - 'showrefcount', 'utf8'): + 'frozen_modules', 'showrefcount', 'utf8'): if opt in xoptions: value = xoptions[opt] if value is True: @@ -872,37 +872,6 @@ class Popen: 'and universal_newlines are supplied but ' 'different. Pass one or the other.') - # Input and output objects. The general principle is like - # this: - # - # Parent Child - # ------ ----- - # p2cwrite ---stdin---> p2cread - # c2pread <--stdout--- c2pwrite - # errread <--stderr--- errwrite - # - # On POSIX, the child objects are file descriptors. On - # Windows, these are Windows file handles. The parent objects - # are file descriptors on both platforms. The parent objects - # are -1 when not using PIPEs. The child objects are -1 - # when not redirecting. - - (p2cread, p2cwrite, - c2pread, c2pwrite, - errread, errwrite) = self._get_handles(stdin, stdout, stderr) - - # We wrap OS handles *before* launching the child, otherwise a - # quickly terminating child could make our fds unwrappable - # (see #8458). - - if _mswindows: - if p2cwrite != -1: - p2cwrite = msvcrt.open_osfhandle(p2cwrite.Detach(), 0) - if c2pread != -1: - c2pread = msvcrt.open_osfhandle(c2pread.Detach(), 0) - if errread != -1: - errread = msvcrt.open_osfhandle(errread.Detach(), 0) - self.text_mode = encoding or errors or text or universal_newlines if self.text_mode and encoding is None: self.encoding = encoding = _text_encoding() @@ -1003,6 +972,39 @@ class Popen: if uid < 0: raise ValueError(f"User ID cannot be negative, got {uid}") + # Input and output objects. The general principle is like + # this: + # + # Parent Child + # ------ ----- + # p2cwrite ---stdin---> p2cread + # c2pread <--stdout--- c2pwrite + # errread <--stderr--- errwrite + # + # On POSIX, the child objects are file descriptors. On + # Windows, these are Windows file handles. The parent objects + # are file descriptors on both platforms. The parent objects + # are -1 when not using PIPEs. The child objects are -1 + # when not redirecting. + + (p2cread, p2cwrite, + c2pread, c2pwrite, + errread, errwrite) = self._get_handles(stdin, stdout, stderr) + + # From here on, raising exceptions may cause file descriptor leakage + + # We wrap OS handles *before* launching the child, otherwise a + # quickly terminating child could make our fds unwrappable + # (see #8458). + + if _mswindows: + if p2cwrite != -1: + p2cwrite = msvcrt.open_osfhandle(p2cwrite.Detach(), 0) + if c2pread != -1: + c2pread = msvcrt.open_osfhandle(c2pread.Detach(), 0) + if errread != -1: + errread = msvcrt.open_osfhandle(errread.Detach(), 0) + try: if p2cwrite != -1: self.stdin = io.open(p2cwrite, 'wb', bufsize) @@ -1306,6 +1308,26 @@ class Popen: # Prevent a double close of these handles/fds from __init__ on error. self._closed_child_pipe_fds = True + @contextlib.contextmanager + def _on_error_fd_closer(self): + """Helper to ensure file descriptors opened in _get_handles are closed""" + to_close = [] + try: + yield to_close + except: + if hasattr(self, '_devnull'): + to_close.append(self._devnull) + del self._devnull + for fd in to_close: + try: + if _mswindows and isinstance(fd, Handle): + fd.Close() + else: + os.close(fd) + except OSError: + pass + raise + if _mswindows: # # Windows methods @@ -1321,61 +1343,68 @@ class Popen: c2pread, c2pwrite = -1, -1 errread, errwrite = -1, -1 - if stdin is None: - p2cread = _winapi.GetStdHandle(_winapi.STD_INPUT_HANDLE) - if p2cread is None: - p2cread, _ = _winapi.CreatePipe(None, 0) - p2cread = Handle(p2cread) - _winapi.CloseHandle(_) - elif stdin == PIPE: - p2cread, p2cwrite = _winapi.CreatePipe(None, 0) - p2cread, p2cwrite = Handle(p2cread), Handle(p2cwrite) - elif stdin == DEVNULL: - p2cread = msvcrt.get_osfhandle(self._get_devnull()) - elif isinstance(stdin, int): - p2cread = msvcrt.get_osfhandle(stdin) - else: - # Assuming file-like object - p2cread = msvcrt.get_osfhandle(stdin.fileno()) - p2cread = self._make_inheritable(p2cread) - - if stdout is None: - c2pwrite = _winapi.GetStdHandle(_winapi.STD_OUTPUT_HANDLE) - if c2pwrite is None: - _, c2pwrite = _winapi.CreatePipe(None, 0) - c2pwrite = Handle(c2pwrite) - _winapi.CloseHandle(_) - elif stdout == PIPE: - c2pread, c2pwrite = _winapi.CreatePipe(None, 0) - c2pread, c2pwrite = Handle(c2pread), Handle(c2pwrite) - elif stdout == DEVNULL: - c2pwrite = msvcrt.get_osfhandle(self._get_devnull()) - elif isinstance(stdout, int): - c2pwrite = msvcrt.get_osfhandle(stdout) - else: - # Assuming file-like object - c2pwrite = msvcrt.get_osfhandle(stdout.fileno()) - c2pwrite = self._make_inheritable(c2pwrite) - - if stderr is None: - errwrite = _winapi.GetStdHandle(_winapi.STD_ERROR_HANDLE) - if errwrite is None: - _, errwrite = _winapi.CreatePipe(None, 0) - errwrite = Handle(errwrite) - _winapi.CloseHandle(_) - elif stderr == PIPE: - errread, errwrite = _winapi.CreatePipe(None, 0) - errread, errwrite = Handle(errread), Handle(errwrite) - elif stderr == STDOUT: - errwrite = c2pwrite - elif stderr == DEVNULL: - errwrite = msvcrt.get_osfhandle(self._get_devnull()) - elif isinstance(stderr, int): - errwrite = msvcrt.get_osfhandle(stderr) - else: - # Assuming file-like object - errwrite = msvcrt.get_osfhandle(stderr.fileno()) - errwrite = self._make_inheritable(errwrite) + with self._on_error_fd_closer() as err_close_fds: + if stdin is None: + p2cread = _winapi.GetStdHandle(_winapi.STD_INPUT_HANDLE) + if p2cread is None: + p2cread, _ = _winapi.CreatePipe(None, 0) + p2cread = Handle(p2cread) + err_close_fds.append(p2cread) + _winapi.CloseHandle(_) + elif stdin == PIPE: + p2cread, p2cwrite = _winapi.CreatePipe(None, 0) + p2cread, p2cwrite = Handle(p2cread), Handle(p2cwrite) + err_close_fds.extend((p2cread, p2cwrite)) + elif stdin == DEVNULL: + p2cread = msvcrt.get_osfhandle(self._get_devnull()) + elif isinstance(stdin, int): + p2cread = msvcrt.get_osfhandle(stdin) + else: + # Assuming file-like object + p2cread = msvcrt.get_osfhandle(stdin.fileno()) + p2cread = self._make_inheritable(p2cread) + + if stdout is None: + c2pwrite = _winapi.GetStdHandle(_winapi.STD_OUTPUT_HANDLE) + if c2pwrite is None: + _, c2pwrite = _winapi.CreatePipe(None, 0) + c2pwrite = Handle(c2pwrite) + err_close_fds.append(c2pwrite) + _winapi.CloseHandle(_) + elif stdout == PIPE: + c2pread, c2pwrite = _winapi.CreatePipe(None, 0) + c2pread, c2pwrite = Handle(c2pread), Handle(c2pwrite) + err_close_fds.extend((c2pread, c2pwrite)) + elif stdout == DEVNULL: + c2pwrite = msvcrt.get_osfhandle(self._get_devnull()) + elif isinstance(stdout, int): + c2pwrite = msvcrt.get_osfhandle(stdout) + else: + # Assuming file-like object + c2pwrite = msvcrt.get_osfhandle(stdout.fileno()) + c2pwrite = self._make_inheritable(c2pwrite) + + if stderr is None: + errwrite = _winapi.GetStdHandle(_winapi.STD_ERROR_HANDLE) + if errwrite is None: + _, errwrite = _winapi.CreatePipe(None, 0) + errwrite = Handle(errwrite) + err_close_fds.append(errwrite) + _winapi.CloseHandle(_) + elif stderr == PIPE: + errread, errwrite = _winapi.CreatePipe(None, 0) + errread, errwrite = Handle(errread), Handle(errwrite) + err_close_fds.extend((errread, errwrite)) + elif stderr == STDOUT: + errwrite = c2pwrite + elif stderr == DEVNULL: + errwrite = msvcrt.get_osfhandle(self._get_devnull()) + elif isinstance(stderr, int): + errwrite = msvcrt.get_osfhandle(stderr) + else: + # Assuming file-like object + errwrite = msvcrt.get_osfhandle(stderr.fileno()) + errwrite = self._make_inheritable(errwrite) return (p2cread, p2cwrite, c2pread, c2pwrite, @@ -1480,7 +1509,23 @@ class Popen: if shell: startupinfo.dwFlags |= _winapi.STARTF_USESHOWWINDOW startupinfo.wShowWindow = _winapi.SW_HIDE - comspec = os.environ.get("COMSPEC", "cmd.exe") + if not executable: + # gh-101283: without a fully-qualified path, before Windows + # checks the system directories, it first looks in the + # application directory, and also the current directory if + # NeedCurrentDirectoryForExePathW(ExeName) is true, so try + # to avoid executing unqualified "cmd.exe". + comspec = os.environ.get('ComSpec') + if not comspec: + system_root = os.environ.get('SystemRoot', '') + comspec = os.path.join(system_root, 'System32', 'cmd.exe') + if not os.path.isabs(comspec): + raise FileNotFoundError('shell not found: neither %ComSpec% nor %SystemRoot% is set') + if os.path.isabs(comspec): + executable = comspec + else: + comspec = executable + args = '{} /c "{}"'.format (comspec, args) if cwd is not None: @@ -1646,52 +1691,56 @@ class Popen: c2pread, c2pwrite = -1, -1 errread, errwrite = -1, -1 - if stdin is None: - pass - elif stdin == PIPE: - p2cread, p2cwrite = os.pipe() - if self.pipesize > 0 and hasattr(fcntl, "F_SETPIPE_SZ"): - fcntl.fcntl(p2cwrite, fcntl.F_SETPIPE_SZ, self.pipesize) - elif stdin == DEVNULL: - p2cread = self._get_devnull() - elif isinstance(stdin, int): - p2cread = stdin - else: - # Assuming file-like object - p2cread = stdin.fileno() + with self._on_error_fd_closer() as err_close_fds: + if stdin is None: + pass + elif stdin == PIPE: + p2cread, p2cwrite = os.pipe() + err_close_fds.extend((p2cread, p2cwrite)) + if self.pipesize > 0 and hasattr(fcntl, "F_SETPIPE_SZ"): + fcntl.fcntl(p2cwrite, fcntl.F_SETPIPE_SZ, self.pipesize) + elif stdin == DEVNULL: + p2cread = self._get_devnull() + elif isinstance(stdin, int): + p2cread = stdin + else: + # Assuming file-like object + p2cread = stdin.fileno() - if stdout is None: - pass - elif stdout == PIPE: - c2pread, c2pwrite = os.pipe() - if self.pipesize > 0 and hasattr(fcntl, "F_SETPIPE_SZ"): - fcntl.fcntl(c2pwrite, fcntl.F_SETPIPE_SZ, self.pipesize) - elif stdout == DEVNULL: - c2pwrite = self._get_devnull() - elif isinstance(stdout, int): - c2pwrite = stdout - else: - # Assuming file-like object - c2pwrite = stdout.fileno() + if stdout is None: + pass + elif stdout == PIPE: + c2pread, c2pwrite = os.pipe() + err_close_fds.extend((c2pread, c2pwrite)) + if self.pipesize > 0 and hasattr(fcntl, "F_SETPIPE_SZ"): + fcntl.fcntl(c2pwrite, fcntl.F_SETPIPE_SZ, self.pipesize) + elif stdout == DEVNULL: + c2pwrite = self._get_devnull() + elif isinstance(stdout, int): + c2pwrite = stdout + else: + # Assuming file-like object + c2pwrite = stdout.fileno() - if stderr is None: - pass - elif stderr == PIPE: - errread, errwrite = os.pipe() - if self.pipesize > 0 and hasattr(fcntl, "F_SETPIPE_SZ"): - fcntl.fcntl(errwrite, fcntl.F_SETPIPE_SZ, self.pipesize) - elif stderr == STDOUT: - if c2pwrite != -1: - errwrite = c2pwrite - else: # child's stdout is not set, use parent's stdout - errwrite = sys.__stdout__.fileno() - elif stderr == DEVNULL: - errwrite = self._get_devnull() - elif isinstance(stderr, int): - errwrite = stderr - else: - # Assuming file-like object - errwrite = stderr.fileno() + if stderr is None: + pass + elif stderr == PIPE: + errread, errwrite = os.pipe() + err_close_fds.extend((errread, errwrite)) + if self.pipesize > 0 and hasattr(fcntl, "F_SETPIPE_SZ"): + fcntl.fcntl(errwrite, fcntl.F_SETPIPE_SZ, self.pipesize) + elif stderr == STDOUT: + if c2pwrite != -1: + errwrite = c2pwrite + else: # child's stdout is not set, use parent's stdout + errwrite = sys.__stdout__.fileno() + elif stderr == DEVNULL: + errwrite = self._get_devnull() + elif isinstance(stderr, int): + errwrite = stderr + else: + # Assuming file-like object + errwrite = stderr.fileno() return (p2cread, p2cwrite, c2pread, c2pwrite, diff --git a/Lib/sunau.py b/Lib/sunau.py index 94c42f15..c6caab95 100644 --- a/Lib/sunau.py +++ b/Lib/sunau.py @@ -160,7 +160,7 @@ def _write_u32(file, x): class Au_read: def __init__(self, f): - if type(f) == type(''): + if isinstance(f, str): import builtins f = builtins.open(f, 'rb') self._opened = True @@ -312,7 +312,7 @@ class Au_read: class Au_write: def __init__(self, f): - if type(f) == type(''): + if isinstance(f, str): import builtins f = builtins.open(f, 'wb') self._opened = True diff --git a/Lib/symtable.py b/Lib/symtable.py index 5dd71ffc..4b0bc6f4 100644 --- a/Lib/symtable.py +++ b/Lib/symtable.py @@ -62,8 +62,8 @@ class SymbolTable: def get_type(self): """Return the type of the symbol table. - The values returned are 'class', 'module' and - 'function'. + The values returned are 'class', 'module', 'function', + 'annotation', 'TypeVar bound', 'type alias', and 'type parameter'. """ if self._table.type == _symtable.TYPE_MODULE: return "module" @@ -71,8 +71,15 @@ class SymbolTable: return "function" if self._table.type == _symtable.TYPE_CLASS: return "class" - assert self._table.type in (1, 2, 3), \ - "unexpected type: {0}".format(self._table.type) + if self._table.type == _symtable.TYPE_ANNOTATION: + return "annotation" + if self._table.type == _symtable.TYPE_TYPE_VAR_BOUND: + return "TypeVar bound" + if self._table.type == _symtable.TYPE_TYPE_ALIAS: + return "type alias" + if self._table.type == _symtable.TYPE_TYPE_PARAM: + return "type parameter" + assert False, f"unexpected type: {self._table.type}" def get_id(self): """Return an identifier for the table. diff --git a/Lib/sysconfig.py b/Lib/sysconfig.py index ebe37118..122d441b 100644 --- a/Lib/sysconfig.py +++ b/Lib/sysconfig.py @@ -2,7 +2,8 @@ import os import sys -from os.path import pardir, realpath +import threading +from os.path import realpath __all__ = [ 'get_config_h_filename', @@ -172,7 +173,11 @@ _PREFIX = os.path.normpath(sys.prefix) _BASE_PREFIX = os.path.normpath(sys.base_prefix) _EXEC_PREFIX = os.path.normpath(sys.exec_prefix) _BASE_EXEC_PREFIX = os.path.normpath(sys.base_exec_prefix) +# Mutex guarding initialization of _CONFIG_VARS. +_CONFIG_VARS_LOCK = threading.RLock() _CONFIG_VARS = None +# True iff _CONFIG_VARS has been fully initialized. +_CONFIG_VARS_INITIALIZED = False _USER_BASE = None # Regexes needed for parsing Makefile (and similar syntaxes, @@ -539,7 +544,12 @@ def _init_non_posix(vars): vars['LIBDEST'] = get_path('stdlib') vars['BINLIBDEST'] = get_path('platstdlib') vars['INCLUDEPY'] = get_path('include') - vars['EXT_SUFFIX'] = _imp.extension_suffixes()[0] + try: + # GH-99201: _imp.extension_suffixes may be empty when + # HAVE_DYNAMIC_LOADING is not set. In this case, don't set EXT_SUFFIX. + vars['EXT_SUFFIX'] = _imp.extension_suffixes()[0] + except IndexError: + pass vars['EXE'] = '.exe' vars['VERSION'] = _PY_VERSION_SHORT_NO_DOT vars['BINDIR'] = os.path.dirname(_safe_realpath(sys.executable)) @@ -626,6 +636,71 @@ def get_path(name, scheme=get_default_scheme(), vars=None, expand=True): return get_paths(scheme, vars, expand)[name] +def _init_config_vars(): + global _CONFIG_VARS + _CONFIG_VARS = {} + # Normalized versions of prefix and exec_prefix are handy to have; + # in fact, these are the standard versions used most places in the + # Distutils. + _CONFIG_VARS['prefix'] = _PREFIX + _CONFIG_VARS['exec_prefix'] = _EXEC_PREFIX + _CONFIG_VARS['py_version'] = _PY_VERSION + _CONFIG_VARS['py_version_short'] = _PY_VERSION_SHORT + _CONFIG_VARS['py_version_nodot'] = _PY_VERSION_SHORT_NO_DOT + _CONFIG_VARS['installed_base'] = _BASE_PREFIX + _CONFIG_VARS['base'] = _PREFIX + _CONFIG_VARS['installed_platbase'] = _BASE_EXEC_PREFIX + _CONFIG_VARS['platbase'] = _EXEC_PREFIX + _CONFIG_VARS['projectbase'] = _PROJECT_BASE + _CONFIG_VARS['platlibdir'] = sys.platlibdir + try: + _CONFIG_VARS['abiflags'] = sys.abiflags + except AttributeError: + # sys.abiflags may not be defined on all platforms. + _CONFIG_VARS['abiflags'] = '' + try: + _CONFIG_VARS['py_version_nodot_plat'] = sys.winver.replace('.', '') + except AttributeError: + _CONFIG_VARS['py_version_nodot_plat'] = '' + + if os.name == 'nt': + _init_non_posix(_CONFIG_VARS) + _CONFIG_VARS['VPATH'] = sys._vpath + if os.name == 'posix': + _init_posix(_CONFIG_VARS) + if _HAS_USER_BASE: + # Setting 'userbase' is done below the call to the + # init function to enable using 'get_config_var' in + # the init-function. + _CONFIG_VARS['userbase'] = _getuserbase() + + # Always convert srcdir to an absolute path + srcdir = _CONFIG_VARS.get('srcdir', _PROJECT_BASE) + if os.name == 'posix': + if _PYTHON_BUILD: + # If srcdir is a relative path (typically '.' or '..') + # then it should be interpreted relative to the directory + # containing Makefile. + base = os.path.dirname(get_makefile_filename()) + srcdir = os.path.join(base, srcdir) + else: + # srcdir is not meaningful since the installation is + # spread about the filesystem. We choose the + # directory containing the Makefile since we know it + # exists. + srcdir = os.path.dirname(get_makefile_filename()) + _CONFIG_VARS['srcdir'] = _safe_realpath(srcdir) + + # OS X platforms require special customization to handle + # multi-architecture, multi-os-version installers + if sys.platform == 'darwin': + import _osx_support + _osx_support.customize_config_vars(_CONFIG_VARS) + + global _CONFIG_VARS_INITIALIZED + _CONFIG_VARS_INITIALIZED = True + + def get_config_vars(*args): """With no arguments, return a dictionary of all configuration variables relevant for the current platform. @@ -636,66 +711,16 @@ def get_config_vars(*args): With arguments, return a list of values that result from looking up each argument in the configuration variable dictionary. """ - global _CONFIG_VARS - if _CONFIG_VARS is None: - _CONFIG_VARS = {} - # Normalized versions of prefix and exec_prefix are handy to have; - # in fact, these are the standard versions used most places in the - # Distutils. - _CONFIG_VARS['prefix'] = _PREFIX - _CONFIG_VARS['exec_prefix'] = _EXEC_PREFIX - _CONFIG_VARS['py_version'] = _PY_VERSION - _CONFIG_VARS['py_version_short'] = _PY_VERSION_SHORT - _CONFIG_VARS['py_version_nodot'] = _PY_VERSION_SHORT_NO_DOT - _CONFIG_VARS['installed_base'] = _BASE_PREFIX - _CONFIG_VARS['base'] = _PREFIX - _CONFIG_VARS['installed_platbase'] = _BASE_EXEC_PREFIX - _CONFIG_VARS['platbase'] = _EXEC_PREFIX - _CONFIG_VARS['projectbase'] = _PROJECT_BASE - _CONFIG_VARS['platlibdir'] = sys.platlibdir - try: - _CONFIG_VARS['abiflags'] = sys.abiflags - except AttributeError: - # sys.abiflags may not be defined on all platforms. - _CONFIG_VARS['abiflags'] = '' - try: - _CONFIG_VARS['py_version_nodot_plat'] = sys.winver.replace('.', '') - except AttributeError: - _CONFIG_VARS['py_version_nodot_plat'] = '' - - if os.name == 'nt': - _init_non_posix(_CONFIG_VARS) - _CONFIG_VARS['VPATH'] = sys._vpath - if os.name == 'posix': - _init_posix(_CONFIG_VARS) - if _HAS_USER_BASE: - # Setting 'userbase' is done below the call to the - # init function to enable using 'get_config_var' in - # the init-function. - _CONFIG_VARS['userbase'] = _getuserbase() - - # Always convert srcdir to an absolute path - srcdir = _CONFIG_VARS.get('srcdir', _PROJECT_BASE) - if os.name == 'posix': - if _PYTHON_BUILD: - # If srcdir is a relative path (typically '.' or '..') - # then it should be interpreted relative to the directory - # containing Makefile. - base = os.path.dirname(get_makefile_filename()) - srcdir = os.path.join(base, srcdir) - else: - # srcdir is not meaningful since the installation is - # spread about the filesystem. We choose the - # directory containing the Makefile since we know it - # exists. - srcdir = os.path.dirname(get_makefile_filename()) - _CONFIG_VARS['srcdir'] = _safe_realpath(srcdir) - - # OS X platforms require special customization to handle - # multi-architecture, multi-os-version installers - if sys.platform == 'darwin': - import _osx_support - _osx_support.customize_config_vars(_CONFIG_VARS) + + # Avoid claiming the lock once initialization is complete. + if not _CONFIG_VARS_INITIALIZED: + with _CONFIG_VARS_LOCK: + # Test again with the lock held to avoid races. Note that + # we test _CONFIG_VARS here, not _CONFIG_VARS_INITIALIZED, + # to ensure that recursive calls to get_config_vars() + # don't re-enter init_config_vars(). + if _CONFIG_VARS is None: + _init_config_vars() if args: vals = [] diff --git a/Lib/tabnanny.py b/Lib/tabnanny.py index a47f5a96..e2ac6837 100755 --- a/Lib/tabnanny.py +++ b/Lib/tabnanny.py @@ -35,6 +35,7 @@ def errprint(*args): sys.stderr.write(sep + str(arg)) sep = " " sys.stderr.write("\n") + sys.exit(1) def main(): import getopt @@ -44,7 +45,6 @@ def main(): opts, args = getopt.getopt(sys.argv[1:], "qv") except getopt.error as msg: errprint(msg) - return for o, a in opts: if o == '-q': filename_only = filename_only + 1 @@ -52,7 +52,6 @@ def main(): verbose = verbose + 1 if not args: errprint("Usage:", sys.argv[0], "[-v] file_or_directory ...") - return for arg in args: check(arg) @@ -108,6 +107,10 @@ def check(file): errprint("%r: Token Error: %s" % (file, msg)) return + except SyntaxError as msg: + errprint("%r: Token Error: %s" % (file, msg)) + return + except IndentationError as msg: errprint("%r: Indentation Error: %s" % (file, msg)) return @@ -273,6 +276,12 @@ def format_witnesses(w): return prefix + " " + ', '.join(firsts) def process_tokens(tokens): + try: + _process_tokens(tokens) + except TabError as e: + raise NannyNag(e.lineno, e.msg, e.text) + +def _process_tokens(tokens): INDENT = tokenize.INDENT DEDENT = tokenize.DEDENT NEWLINE = tokenize.NEWLINE diff --git a/Lib/tarfile.py b/Lib/tarfile.py index 87f44d99..02f5e3b6 100755 --- a/Lib/tarfile.py +++ b/Lib/tarfile.py @@ -46,6 +46,7 @@ import time import struct import copy import re +import warnings try: import pwd @@ -57,19 +58,19 @@ except ImportError: grp = None # os.symlink on Windows prior to 6.0 raises NotImplementedError -symlink_exception = (AttributeError, NotImplementedError) -try: - # OSError (winerror=1314) will be raised if the caller does not hold the - # SeCreateSymbolicLinkPrivilege privilege - symlink_exception += (OSError,) -except NameError: - pass +# OSError (winerror=1314) will be raised if the caller does not hold the +# SeCreateSymbolicLinkPrivilege privilege +symlink_exception = (AttributeError, NotImplementedError, OSError) # from tarfile import * __all__ = ["TarFile", "TarInfo", "is_tarfile", "TarError", "ReadError", "CompressionError", "StreamError", "ExtractError", "HeaderError", "ENCODING", "USTAR_FORMAT", "GNU_FORMAT", "PAX_FORMAT", - "DEFAULT_FORMAT", "open"] + "DEFAULT_FORMAT", "open","fully_trusted_filter", "data_filter", + "tar_filter", "FilterError", "AbsoluteLinkError", + "OutsideDestinationError", "SpecialFileError", "AbsolutePathError", + "LinkOutsideDestinationError"] + #--------------------------------------------------------- # tar constants @@ -158,6 +159,8 @@ else: def stn(s, length, encoding, errors): """Convert a string to a null-terminated bytes object. """ + if s is None: + raise ValueError("metadata cannot contain None") s = s.encode(encoding, errors) return s[:length] + (length - len(s)) * NUL @@ -336,7 +339,8 @@ class _Stream: _Stream is intended to be used only internally. """ - def __init__(self, name, mode, comptype, fileobj, bufsize): + def __init__(self, name, mode, comptype, fileobj, bufsize, + compresslevel): """Construct a _Stream object. """ self._extfileobj = True @@ -368,10 +372,10 @@ class _Stream: self.zlib = zlib self.crc = zlib.crc32(b"") if mode == "r": - self._init_read_gz() self.exception = zlib.error + self._init_read_gz() else: - self._init_write_gz() + self._init_write_gz(compresslevel) elif comptype == "bz2": try: @@ -383,7 +387,7 @@ class _Stream: self.cmp = bz2.BZ2Decompressor() self.exception = OSError else: - self.cmp = bz2.BZ2Compressor() + self.cmp = bz2.BZ2Compressor(compresslevel) elif comptype == "xz": try: @@ -410,13 +414,14 @@ class _Stream: if hasattr(self, "closed") and not self.closed: self.close() - def _init_write_gz(self): + def _init_write_gz(self, compresslevel): """Initialize for writing with gzip compression. """ - self.cmp = self.zlib.compressobj(9, self.zlib.DEFLATED, - -self.zlib.MAX_WBITS, - self.zlib.DEF_MEM_LEVEL, - 0) + self.cmp = self.zlib.compressobj(compresslevel, + self.zlib.DEFLATED, + -self.zlib.MAX_WBITS, + self.zlib.DEF_MEM_LEVEL, + 0) timestamp = struct.pack("<L", int(time.time())) self.__write(b"\037\213\010\010" + timestamp + b"\002\377") if self.name.endswith(".gz"): @@ -603,12 +608,12 @@ class _FileInFile(object): object. """ - def __init__(self, fileobj, offset, size, blockinfo=None): + def __init__(self, fileobj, offset, size, name, blockinfo=None): self.fileobj = fileobj self.offset = offset self.size = size self.position = 0 - self.name = getattr(fileobj, "name", None) + self.name = name self.closed = False if blockinfo is None: @@ -705,13 +710,138 @@ class ExFileObject(io.BufferedReader): def __init__(self, tarfile, tarinfo): fileobj = _FileInFile(tarfile.fileobj, tarinfo.offset_data, - tarinfo.size, tarinfo.sparse) + tarinfo.size, tarinfo.name, tarinfo.sparse) super().__init__(fileobj) #class ExFileObject + +#----------------------------- +# extraction filters (PEP 706) +#----------------------------- + +class FilterError(TarError): + pass + +class AbsolutePathError(FilterError): + def __init__(self, tarinfo): + self.tarinfo = tarinfo + super().__init__(f'member {tarinfo.name!r} has an absolute path') + +class OutsideDestinationError(FilterError): + def __init__(self, tarinfo, path): + self.tarinfo = tarinfo + self._path = path + super().__init__(f'{tarinfo.name!r} would be extracted to {path!r}, ' + + 'which is outside the destination') + +class SpecialFileError(FilterError): + def __init__(self, tarinfo): + self.tarinfo = tarinfo + super().__init__(f'{tarinfo.name!r} is a special file') + +class AbsoluteLinkError(FilterError): + def __init__(self, tarinfo): + self.tarinfo = tarinfo + super().__init__(f'{tarinfo.name!r} is a link to an absolute path') + +class LinkOutsideDestinationError(FilterError): + def __init__(self, tarinfo, path): + self.tarinfo = tarinfo + self._path = path + super().__init__(f'{tarinfo.name!r} would link to {path!r}, ' + + 'which is outside the destination') + +def _get_filtered_attrs(member, dest_path, for_data=True): + new_attrs = {} + name = member.name + dest_path = os.path.realpath(dest_path) + # Strip leading / (tar's directory separator) from filenames. + # Include os.sep (target OS directory separator) as well. + if name.startswith(('/', os.sep)): + name = new_attrs['name'] = member.path.lstrip('/' + os.sep) + if os.path.isabs(name): + # Path is absolute even after stripping. + # For example, 'C:/foo' on Windows. + raise AbsolutePathError(member) + # Ensure we stay in the destination + target_path = os.path.realpath(os.path.join(dest_path, name)) + if os.path.commonpath([target_path, dest_path]) != dest_path: + raise OutsideDestinationError(member, target_path) + # Limit permissions (no high bits, and go-w) + mode = member.mode + if mode is not None: + # Strip high bits & group/other write bits + mode = mode & 0o755 + if for_data: + # For data, handle permissions & file types + if member.isreg() or member.islnk(): + if not mode & 0o100: + # Clear executable bits if not executable by user + mode &= ~0o111 + # Ensure owner can read & write + mode |= 0o600 + elif member.isdir() or member.issym(): + # Ignore mode for directories & symlinks + mode = None + else: + # Reject special files + raise SpecialFileError(member) + if mode != member.mode: + new_attrs['mode'] = mode + if for_data: + # Ignore ownership for 'data' + if member.uid is not None: + new_attrs['uid'] = None + if member.gid is not None: + new_attrs['gid'] = None + if member.uname is not None: + new_attrs['uname'] = None + if member.gname is not None: + new_attrs['gname'] = None + # Check link destination for 'data' + if member.islnk() or member.issym(): + if os.path.isabs(member.linkname): + raise AbsoluteLinkError(member) + if member.issym(): + target_path = os.path.join(dest_path, + os.path.dirname(name), + member.linkname) + else: + target_path = os.path.join(dest_path, + member.linkname) + target_path = os.path.realpath(target_path) + if os.path.commonpath([target_path, dest_path]) != dest_path: + raise LinkOutsideDestinationError(member, target_path) + return new_attrs + +def fully_trusted_filter(member, dest_path): + return member + +def tar_filter(member, dest_path): + new_attrs = _get_filtered_attrs(member, dest_path, False) + if new_attrs: + return member.replace(**new_attrs, deep=False) + return member + +def data_filter(member, dest_path): + new_attrs = _get_filtered_attrs(member, dest_path, True) + if new_attrs: + return member.replace(**new_attrs, deep=False) + return member + +_NAMED_FILTERS = { + "fully_trusted": fully_trusted_filter, + "tar": tar_filter, + "data": data_filter, +} + #------------------ # Exported Classes #------------------ + +# Sentinel for replace() defaults, meaning "don't change the attribute" +_KEEP = object() + class TarInfo(object): """Informational class which holds the details about an archive member given by a tar header block. @@ -792,12 +922,44 @@ class TarInfo(object): def __repr__(self): return "<%s %r at %#x>" % (self.__class__.__name__,self.name,id(self)) + def replace(self, *, + name=_KEEP, mtime=_KEEP, mode=_KEEP, linkname=_KEEP, + uid=_KEEP, gid=_KEEP, uname=_KEEP, gname=_KEEP, + deep=True, _KEEP=_KEEP): + """Return a deep copy of self with the given attributes replaced. + """ + if deep: + result = copy.deepcopy(self) + else: + result = copy.copy(self) + if name is not _KEEP: + result.name = name + if mtime is not _KEEP: + result.mtime = mtime + if mode is not _KEEP: + result.mode = mode + if linkname is not _KEEP: + result.linkname = linkname + if uid is not _KEEP: + result.uid = uid + if gid is not _KEEP: + result.gid = gid + if uname is not _KEEP: + result.uname = uname + if gname is not _KEEP: + result.gname = gname + return result + def get_info(self): """Return the TarInfo's attributes as a dictionary. """ + if self.mode is None: + mode = None + else: + mode = self.mode & 0o7777 info = { "name": self.name, - "mode": self.mode & 0o7777, + "mode": mode, "uid": self.uid, "gid": self.gid, "size": self.size, @@ -820,6 +982,9 @@ class TarInfo(object): """Return a tar header as a string of 512 byte blocks. """ info = self.get_info() + for name, value in info.items(): + if value is None: + raise ValueError("%s may not be None" % name) if format == USTAR_FORMAT: return self.create_ustar_header(info, encoding, errors) @@ -950,6 +1115,12 @@ class TarInfo(object): devmajor = stn("", 8, encoding, errors) devminor = stn("", 8, encoding, errors) + # None values in metadata should cause ValueError. + # itn()/stn() do this for all fields except type. + filetype = info.get("type", REGTYPE) + if filetype is None: + raise ValueError("TarInfo.type must not be None") + parts = [ stn(info.get("name", ""), 100, encoding, errors), itn(info.get("mode", 0) & 0o7777, 8, format), @@ -958,7 +1129,7 @@ class TarInfo(object): itn(info.get("size", 0), 12, format), itn(info.get("mtime", 0), 12, format), b" ", # checksum field - info.get("type", REGTYPE), + filetype, stn(info.get("linkname", ""), 100, encoding, errors), info.get("magic", POSIX_MAGIC), stn(info.get("uname", ""), 32, encoding, errors), @@ -1264,11 +1435,7 @@ class TarInfo(object): # the newline. keyword and value are both UTF-8 encoded strings. regex = re.compile(br"(\d+) ([^=]+)=") pos = 0 - while True: - match = regex.match(buf, pos) - if not match: - break - + while match := regex.match(buf, pos): length, keyword = match.groups() length = int(length) if length == 0: @@ -1468,6 +1635,8 @@ class TarFile(object): fileobject = ExFileObject # The file-object for extractfile(). + extraction_filter = None # The default filter for extraction. + def __init__(self, name=None, mode="r", fileobj=None, format=None, tarinfo=None, dereference=None, ignore_zeros=None, encoding=None, errors="surrogateescape", pax_headers=None, debug=None, @@ -1659,7 +1828,9 @@ class TarFile(object): if filemode not in ("r", "w"): raise ValueError("mode must be 'r' or 'w'") - stream = _Stream(name, filemode, comptype, fileobj, bufsize) + compresslevel = kwargs.pop("compresslevel", 9) + stream = _Stream(name, filemode, comptype, fileobj, bufsize, + compresslevel) try: t = cls(name, filemode, stream, **kwargs) except: @@ -1940,7 +2111,10 @@ class TarFile(object): members = self for tarinfo in members: if verbose: - _safe_print(stat.filemode(tarinfo.mode)) + if tarinfo.mode is None: + _safe_print("??????????") + else: + _safe_print(stat.filemode(tarinfo.mode)) _safe_print("%s/%s" % (tarinfo.uname or tarinfo.uid, tarinfo.gname or tarinfo.gid)) if tarinfo.ischr() or tarinfo.isblk(): @@ -1948,8 +2122,11 @@ class TarFile(object): ("%d,%d" % (tarinfo.devmajor, tarinfo.devminor))) else: _safe_print("%10d" % tarinfo.size) - _safe_print("%d-%02d-%02d %02d:%02d:%02d" \ - % time.localtime(tarinfo.mtime)[:6]) + if tarinfo.mtime is None: + _safe_print("????-??-?? ??:??:??") + else: + _safe_print("%d-%02d-%02d %02d:%02d:%02d" \ + % time.localtime(tarinfo.mtime)[:6]) _safe_print(tarinfo.name + ("/" if tarinfo.isdir() else "")) @@ -2036,32 +2213,63 @@ class TarFile(object): self.members.append(tarinfo) - def extractall(self, path=".", members=None, *, numeric_owner=False): + def _get_filter_function(self, filter): + if filter is None: + filter = self.extraction_filter + if filter is None: + warnings.warn( + 'Python 3.14 will, by default, filter extracted tar ' + + 'archives and reject files or modify their metadata. ' + + 'Use the filter argument to control this behavior.', + DeprecationWarning) + return fully_trusted_filter + if isinstance(filter, str): + raise TypeError( + 'String names are not supported for ' + + 'TarFile.extraction_filter. Use a function such as ' + + 'tarfile.data_filter directly.') + return filter + if callable(filter): + return filter + try: + return _NAMED_FILTERS[filter] + except KeyError: + raise ValueError(f"filter {filter!r} not found") from None + + def extractall(self, path=".", members=None, *, numeric_owner=False, + filter=None): """Extract all members from the archive to the current working directory and set owner, modification time and permissions on directories afterwards. `path' specifies a different directory to extract to. `members' is optional and must be a subset of the list returned by getmembers(). If `numeric_owner` is True, only the numbers for user/group names are used and not the names. + + The `filter` function will be called on each member just + before extraction. + It can return a changed TarInfo or None to skip the member. + String names of common filters are accepted. """ directories = [] + filter_function = self._get_filter_function(filter) if members is None: members = self - for tarinfo in members: + for member in members: + tarinfo = self._get_extract_tarinfo(member, filter_function, path) + if tarinfo is None: + continue if tarinfo.isdir(): - # Extract directories with a safe mode. + # For directories, delay setting attributes until later, + # since permissions can interfere with extraction and + # extracting contents can reset mtime. directories.append(tarinfo) - tarinfo = copy.copy(tarinfo) - tarinfo.mode = 0o700 - # Do not set_attrs directories, as we will do that further down - self.extract(tarinfo, path, set_attrs=not tarinfo.isdir(), - numeric_owner=numeric_owner) + self._extract_one(tarinfo, path, set_attrs=not tarinfo.isdir(), + numeric_owner=numeric_owner) # Reverse sort directories. - directories.sort(key=lambda a: a.name) - directories.reverse() + directories.sort(key=lambda a: a.name, reverse=True) # Set correct owner, mtime and filemode on directories. for tarinfo in directories: @@ -2071,12 +2279,10 @@ class TarFile(object): self.utime(tarinfo, dirpath) self.chmod(tarinfo, dirpath) except ExtractError as e: - if self.errorlevel > 1: - raise - else: - self._dbg(1, "tarfile: %s" % e) + self._handle_nonfatal_error(e) - def extract(self, member, path="", set_attrs=True, *, numeric_owner=False): + def extract(self, member, path="", set_attrs=True, *, numeric_owner=False, + filter=None): """Extract a member from the archive to the current working directory, using its full name. Its file information is extracted as accurately as possible. `member' may be a filename or a TarInfo object. You can @@ -2084,35 +2290,70 @@ class TarFile(object): mtime, mode) are set unless `set_attrs' is False. If `numeric_owner` is True, only the numbers for user/group names are used and not the names. + + The `filter` function will be called before extraction. + It can return a changed TarInfo or None to skip the member. + String names of common filters are accepted. """ - self._check("r") + filter_function = self._get_filter_function(filter) + tarinfo = self._get_extract_tarinfo(member, filter_function, path) + if tarinfo is not None: + self._extract_one(tarinfo, path, set_attrs, numeric_owner) + def _get_extract_tarinfo(self, member, filter_function, path): + """Get filtered TarInfo (or None) from member, which might be a str""" if isinstance(member, str): tarinfo = self.getmember(member) else: tarinfo = member + unfiltered = tarinfo + try: + tarinfo = filter_function(tarinfo, path) + except (OSError, FilterError) as e: + self._handle_fatal_error(e) + except ExtractError as e: + self._handle_nonfatal_error(e) + if tarinfo is None: + self._dbg(2, "tarfile: Excluded %r" % unfiltered.name) + return None # Prepare the link target for makelink(). if tarinfo.islnk(): + tarinfo = copy.copy(tarinfo) tarinfo._link_target = os.path.join(path, tarinfo.linkname) + return tarinfo + + def _extract_one(self, tarinfo, path, set_attrs, numeric_owner): + """Extract from filtered tarinfo to disk""" + self._check("r") try: self._extract_member(tarinfo, os.path.join(path, tarinfo.name), set_attrs=set_attrs, numeric_owner=numeric_owner) except OSError as e: - if self.errorlevel > 0: - raise - else: - if e.filename is None: - self._dbg(1, "tarfile: %s" % e.strerror) - else: - self._dbg(1, "tarfile: %s %r" % (e.strerror, e.filename)) + self._handle_fatal_error(e) except ExtractError as e: - if self.errorlevel > 1: - raise + self._handle_nonfatal_error(e) + + def _handle_nonfatal_error(self, e): + """Handle non-fatal error (ExtractError) according to errorlevel""" + if self.errorlevel > 1: + raise + else: + self._dbg(1, "tarfile: %s" % e) + + def _handle_fatal_error(self, e): + """Handle "fatal" error according to self.errorlevel""" + if self.errorlevel > 0: + raise + elif isinstance(e, OSError): + if e.filename is None: + self._dbg(1, "tarfile: %s" % e.strerror) else: - self._dbg(1, "tarfile: %s" % e) + self._dbg(1, "tarfile: %s %r" % (e.strerror, e.filename)) + else: + self._dbg(1, "tarfile: %s %s" % (type(e).__name__, e)) def extractfile(self, member): """Extract a member from the archive as a file object. `member' may be @@ -2199,9 +2440,13 @@ class TarFile(object): """Make a directory called targetpath. """ try: - # Use a safe mode for the directory, the real mode is set - # later in _extract_member(). - os.mkdir(targetpath, 0o700) + if tarinfo.mode is None: + # Use the system's default mode + os.mkdir(targetpath) + else: + # Use a safe mode for the directory, the real mode is set + # later in _extract_member(). + os.mkdir(targetpath, 0o700) except FileExistsError: pass @@ -2244,6 +2489,9 @@ class TarFile(object): raise ExtractError("special devices not supported by system") mode = tarinfo.mode + if mode is None: + # Use mknod's default + mode = 0o600 if tarinfo.isblk(): mode |= stat.S_IFBLK else: @@ -2265,7 +2513,6 @@ class TarFile(object): os.unlink(targetpath) os.symlink(tarinfo.linkname, targetpath) else: - # See extract(). if os.path.exists(tarinfo._link_target): os.link(tarinfo._link_target, targetpath) else: @@ -2290,15 +2537,19 @@ class TarFile(object): u = tarinfo.uid if not numeric_owner: try: - if grp: + if grp and tarinfo.gname: g = grp.getgrnam(tarinfo.gname)[2] except KeyError: pass try: - if pwd: + if pwd and tarinfo.uname: u = pwd.getpwnam(tarinfo.uname)[2] except KeyError: pass + if g is None: + g = -1 + if u is None: + u = -1 try: if tarinfo.issym() and hasattr(os, "lchown"): os.lchown(targetpath, u, g) @@ -2310,6 +2561,8 @@ class TarFile(object): def chmod(self, tarinfo, targetpath): """Set file permissions of targetpath according to tarinfo. """ + if tarinfo.mode is None: + return try: os.chmod(targetpath, tarinfo.mode) except OSError as e: @@ -2318,10 +2571,13 @@ class TarFile(object): def utime(self, tarinfo, targetpath): """Set modification time of targetpath according to tarinfo. """ + mtime = tarinfo.mtime + if mtime is None: + return if not hasattr(os, 'utime'): return try: - os.utime(targetpath, (tarinfo.mtime, tarinfo.mtime)) + os.utime(targetpath, (mtime, mtime)) except OSError as e: raise ExtractError("could not change modification time") from e @@ -2399,13 +2655,26 @@ class TarFile(object): members = self.getmembers() # Limit the member search list up to tarinfo. + skipping = False if tarinfo is not None: - members = members[:members.index(tarinfo)] + try: + index = members.index(tarinfo) + except ValueError: + # The given starting point might be a (modified) copy. + # We'll later skip members until we find an equivalent. + skipping = True + else: + # Happy fast path + members = members[:index] if normalize: name = os.path.normpath(name) for member in reversed(members): + if skipping: + if tarinfo.offset == member.offset: + skipping = False + continue if normalize: member_name = os.path.normpath(member.name) else: @@ -2414,14 +2683,16 @@ class TarFile(object): if name == member_name: return member + if skipping: + # Starting point was not found + raise ValueError(tarinfo) + def _load(self): """Read through the entire archive file and look for readable members. """ - while True: - tarinfo = self.next() - if tarinfo is None: - break + while self.next() is not None: + pass self._loaded = True def _check(self, mode=None): @@ -2506,6 +2777,7 @@ class TarFile(object): #-------------------- # exported functions #-------------------- + def is_tarfile(name): """Return True if name points to a tar archive that we are able to handle, else return False. @@ -2534,6 +2806,10 @@ def main(): parser = argparse.ArgumentParser(description=description) parser.add_argument('-v', '--verbose', action='store_true', default=False, help='Verbose output') + parser.add_argument('--filter', metavar='<filtername>', + choices=_NAMED_FILTERS, + help='Filter for extraction') + group = parser.add_mutually_exclusive_group(required=True) group.add_argument('-l', '--list', metavar='<tarfile>', help='Show listing of a tarfile') @@ -2545,8 +2821,12 @@ def main(): help='Create tarfile from sources') group.add_argument('-t', '--test', metavar='<tarfile>', help='Test if a tarfile is valid') + args = parser.parse_args() + if args.filter and args.extract is None: + parser.exit(1, '--filter is only valid for extraction\n') + if args.test is not None: src = args.test if is_tarfile(src): @@ -2577,7 +2857,7 @@ def main(): if is_tarfile(src): with TarFile.open(src, 'r:*') as tf: - tf.extractall(path=curdir) + tf.extractall(path=curdir, filter=args.filter) if args.verbose: if curdir == '.': msg = '{!r} file is extracted.'.format(src) diff --git a/Lib/tempfile.py b/Lib/tempfile.py index 480c1723..2b4f4313 100644 --- a/Lib/tempfile.py +++ b/Lib/tempfile.py @@ -376,7 +376,7 @@ def mkdtemp(suffix=None, prefix=None, dir=None): continue else: raise - return file + return _os.path.abspath(file) raise FileExistsError(_errno.EEXIST, "No usable temporary directory name found") @@ -418,42 +418,42 @@ class _TemporaryFileCloser: underlying file object, without adding a __del__ method to the temporary file.""" - file = None # Set here since __del__ checks it + cleanup_called = False close_called = False - def __init__(self, file, name, delete=True): + def __init__(self, file, name, delete=True, delete_on_close=True): self.file = file self.name = name self.delete = delete + self.delete_on_close = delete_on_close - # NT provides delete-on-close as a primitive, so we don't need - # the wrapper to do anything special. We still use it so that - # file.name is useful (i.e. not "(fdopen)") with NamedTemporaryFile. - if _os.name != 'nt': - # Cache the unlinker so we don't get spurious errors at - # shutdown when the module-level "os" is None'd out. Note - # that this must be referenced as self.unlink, because the - # name TemporaryFileWrapper may also get None'd out before - # __del__ is called. - - def close(self, unlink=_os.unlink): - if not self.close_called and self.file is not None: - self.close_called = True - try: + def cleanup(self, windows=(_os.name == 'nt'), unlink=_os.unlink): + if not self.cleanup_called: + self.cleanup_called = True + try: + if not self.close_called: + self.close_called = True self.file.close() - finally: - if self.delete: + finally: + # Windows provides delete-on-close as a primitive, in which + # case the file was deleted by self.file.close(). + if self.delete and not (windows and self.delete_on_close): + try: unlink(self.name) + except FileNotFoundError: + pass - # Need to ensure the file is deleted on __del__ - def __del__(self): - self.close() - - else: - def close(self): - if not self.close_called: - self.close_called = True + def close(self): + if not self.close_called: + self.close_called = True + try: self.file.close() + finally: + if self.delete and self.delete_on_close: + self.cleanup() + + def __del__(self): + self.cleanup() class _TemporaryFileWrapper: @@ -464,11 +464,11 @@ class _TemporaryFileWrapper: remove the file when it is no longer needed. """ - def __init__(self, file, name, delete=True): + def __init__(self, file, name, delete=True, delete_on_close=True): self.file = file self.name = name - self.delete = delete - self._closer = _TemporaryFileCloser(file, name, delete) + self._closer = _TemporaryFileCloser(file, name, delete, + delete_on_close) def __getattr__(self, name): # Attribute lookups are delegated to the underlying file @@ -499,7 +499,7 @@ class _TemporaryFileWrapper: # deleted when used in a with statement def __exit__(self, exc, value, tb): result = self.file.__exit__(exc, value, tb) - self.close() + self._closer.cleanup() return result def close(self): @@ -518,10 +518,10 @@ class _TemporaryFileWrapper: for line in self.file: yield line - def NamedTemporaryFile(mode='w+b', buffering=-1, encoding=None, newline=None, suffix=None, prefix=None, - dir=None, delete=True, *, errors=None): + dir=None, delete=True, *, errors=None, + delete_on_close=True): """Create and return a temporary file. Arguments: 'prefix', 'suffix', 'dir' -- as for mkstemp. @@ -529,7 +529,10 @@ def NamedTemporaryFile(mode='w+b', buffering=-1, encoding=None, 'buffering' -- the buffer size argument to io.open (default -1). 'encoding' -- the encoding argument to io.open (default None) 'newline' -- the newline argument to io.open (default None) - 'delete' -- whether the file is deleted on close (default True). + 'delete' -- whether the file is automatically deleted (default True). + 'delete_on_close' -- if 'delete', whether the file is deleted on close + (default True) or otherwise either on context manager exit + (if context manager was used) or on object finalization. . 'errors' -- the errors argument to io.open (default None) The file is created as mkstemp() would do it. @@ -548,7 +551,7 @@ def NamedTemporaryFile(mode='w+b', buffering=-1, encoding=None, # Setting O_TEMPORARY in the flags causes the OS to delete # the file when it is closed. This is only supported by Windows. - if _os.name == 'nt' and delete: + if _os.name == 'nt' and delete and delete_on_close: flags |= _os.O_TEMPORARY if "b" not in mode: @@ -567,12 +570,13 @@ def NamedTemporaryFile(mode='w+b', buffering=-1, encoding=None, raw = getattr(file, 'buffer', file) raw = getattr(raw, 'raw', raw) raw.name = name - return _TemporaryFileWrapper(file, name, delete) + return _TemporaryFileWrapper(file, name, delete, delete_on_close) except: file.close() raise except: - if name is not None and not (_os.name == 'nt' and delete): + if name is not None and not ( + _os.name == 'nt' and delete and delete_on_close): _os.unlink(name) raise @@ -846,22 +850,31 @@ class TemporaryDirectory: ... Upon exiting the context, the directory and everything contained - in it are removed. + in it are removed (unless delete=False is passed or an exception + is raised during cleanup and ignore_cleanup_errors is not True). + + Optional Arguments: + suffix - A str suffix for the directory name. (see mkdtemp) + prefix - A str prefix for the directory name. (see mkdtemp) + dir - A directory to create this temp dir in. (see mkdtemp) + ignore_cleanup_errors - False; ignore exceptions during cleanup? + delete - True; whether the directory is automatically deleted. """ def __init__(self, suffix=None, prefix=None, dir=None, - ignore_cleanup_errors=False): + ignore_cleanup_errors=False, *, delete=True): self.name = mkdtemp(suffix, prefix, dir) self._ignore_cleanup_errors = ignore_cleanup_errors + self._delete = delete self._finalizer = _weakref.finalize( self, self._cleanup, self.name, warn_message="Implicitly cleaning up {!r}".format(self), - ignore_errors=self._ignore_cleanup_errors) + ignore_errors=self._ignore_cleanup_errors, delete=self._delete) @classmethod def _rmtree(cls, name, ignore_errors=False): - def onerror(func, path, exc_info): - if issubclass(exc_info[0], PermissionError): + def onexc(func, path, exc): + if isinstance(exc, PermissionError): def resetperms(path): try: _os.chflags(path, 0) @@ -881,18 +894,19 @@ class TemporaryDirectory: cls._rmtree(path, ignore_errors=ignore_errors) except FileNotFoundError: pass - elif issubclass(exc_info[0], FileNotFoundError): + elif isinstance(exc, FileNotFoundError): pass else: if not ignore_errors: raise - _shutil.rmtree(name, onerror=onerror) + _shutil.rmtree(name, onexc=onexc) @classmethod - def _cleanup(cls, name, warn_message, ignore_errors=False): - cls._rmtree(name, ignore_errors=ignore_errors) - _warnings.warn(warn_message, ResourceWarning) + def _cleanup(cls, name, warn_message, ignore_errors=False, delete=True): + if delete: + cls._rmtree(name, ignore_errors=ignore_errors) + _warnings.warn(warn_message, ResourceWarning) def __repr__(self): return "<{} {!r}>".format(self.__class__.__name__, self.name) @@ -901,7 +915,8 @@ class TemporaryDirectory: return self.name def __exit__(self, exc, value, tb): - self.cleanup() + if self._delete: + self.cleanup() def cleanup(self): if self._finalizer.detach() or _os.path.exists(self.name): diff --git a/Lib/test/.ruff.toml b/Lib/test/.ruff.toml new file mode 100644 index 00000000..3bdd472c --- /dev/null +++ b/Lib/test/.ruff.toml @@ -0,0 +1,42 @@ +fix = true +select = [ + "F811", # Redefinition of unused variable (useful for finding test methods with the same name) +] +extend-exclude = [ + # Failed to lint + "badsyntax_pep3120.py", + "encoded_modules/module_iso_8859_1.py", + "encoded_modules/module_koi8_r.py", + # Failed to parse + "badsyntax_3131.py", + "support/socket_helper.py", + "test_fstring.py", + "test_lib2to3/data/bom.py", + "test_lib2to3/data/crlf.py", + "test_lib2to3/data/different_encoding.py", + "test_lib2to3/data/false_encoding.py", + "test_lib2to3/data/py2_test_grammar.py", + # TODO Fix: F811 Redefinition of unused name + "test_buffer.py", + "test_capi/test_misc.py", + "test_capi/test_unicode.py", + "test_ctypes/test_arrays.py", + "test_ctypes/test_functions.py", + "test_dataclasses.py", + "test_descr.py", + "test_enum.py", + "test_functools.py", + "test_genericclass.py", + "test_grammar.py", + "test_import/__init__.py", + "test_keywordonlyarg.py", + "test_lib2to3/data/py3_test_grammar.py", + "test_pkg.py", + "test_subclassinit.py", + "test_tokenize.py", + "test_typing.py", + "test_yield_from.py", + "time_hashlib.py", + # Pending https://github.com/python/cpython/pull/109139 + "test_monitoring.py", +] diff --git a/Lib/test/_test_eintr.py b/Lib/test/_test_eintr.py index e43b59d0..006581f7 100644 --- a/Lib/test/_test_eintr.py +++ b/Lib/test/_test_eintr.py @@ -403,11 +403,9 @@ class SignalEINTRTest(EINTRBaseTest): old_mask = signal.pthread_sigmask(signal.SIG_BLOCK, [signum]) self.addCleanup(signal.pthread_sigmask, signal.SIG_UNBLOCK, [signum]) - t0 = time.monotonic() proc = self.subprocess(code) with kill_on_error(proc): wait_func(signum) - dt = time.monotonic() - t0 self.assertEqual(proc.wait(), 0) @@ -497,16 +495,18 @@ class FNTLEINTRTest(EINTRBaseTest): proc = self.subprocess(code) with kill_on_error(proc): with open(os_helper.TESTFN, 'wb') as f: - while True: # synchronize the subprocess - dt = time.monotonic() - start_time - if dt > 60.0: - raise Exception("failed to sync child in %.1f sec" % dt) + # synchronize the subprocess + start_time = time.monotonic() + for _ in support.sleeping_retry(support.LONG_TIMEOUT, error=False): try: lock_func(f, fcntl.LOCK_EX | fcntl.LOCK_NB) lock_func(f, fcntl.LOCK_UN) - time.sleep(0.01) except BlockingIOError: break + else: + dt = time.monotonic() - start_time + raise Exception("failed to sync child in %.1f sec" % dt) + # the child locked the file just a moment ago for 'sleep_time' seconds # that means that the lock below will block for 'sleep_time' minus some # potential context switch delay diff --git a/Lib/test/_test_embed_set_config.py b/Lib/test/_test_embed_set_config.py index 7ff641b3..0c016b5d 100644 --- a/Lib/test/_test_embed_set_config.py +++ b/Lib/test/_test_embed_set_config.py @@ -84,7 +84,6 @@ class SetConfigTests(unittest.TestCase): 'skip_source_first_line', '_install_importlib', '_init_main', - '_isolated_interpreter', ] if MS_WINDOWS: options.append('legacy_windows_stdio') diff --git a/Lib/test/_test_embed_structseq.py b/Lib/test/_test_embed_structseq.py index 868f9f83..834daa4d 100644 --- a/Lib/test/_test_embed_structseq.py +++ b/Lib/test/_test_embed_structseq.py @@ -1,27 +1,31 @@ import sys import types -import unittest +# Note: This test file can't import `unittest` since the runtime can't +# currently guarantee that it will not leak memory. Doing so will mark +# the test as passing but with reference leaks. This can safely import +# the `unittest` library once there's a strict guarantee of no leaks +# during runtime shutdown. # bpo-46417: Test that structseq types used by the sys module are still # valid when Py_Finalize()/Py_Initialize() are called multiple times. -class TestStructSeq(unittest.TestCase): +class TestStructSeq: # test PyTypeObject members - def check_structseq(self, obj_type): + def _check_structseq(self, obj_type): # ob_refcnt - self.assertGreaterEqual(sys.getrefcount(obj_type), 1) + assert sys.getrefcount(obj_type) > 1 # tp_base - self.assertTrue(issubclass(obj_type, tuple)) + assert issubclass(obj_type, tuple) # tp_bases - self.assertEqual(obj_type.__bases__, (tuple,)) + assert obj_type.__bases__ == (tuple,) # tp_dict - self.assertIsInstance(obj_type.__dict__, types.MappingProxyType) + assert isinstance(obj_type.__dict__, types.MappingProxyType) # tp_mro - self.assertEqual(obj_type.__mro__, (obj_type, tuple, object)) + assert obj_type.__mro__ == (obj_type, tuple, object) # tp_name - self.assertIsInstance(type.__name__, str) + assert isinstance(type.__name__, str) # tp_subclasses - self.assertEqual(obj_type.__subclasses__(), []) + assert obj_type.__subclasses__() == [] def test_sys_attrs(self): for attr_name in ( @@ -32,23 +36,23 @@ class TestStructSeq(unittest.TestCase): 'thread_info', # ThreadInfoType 'version_info', # VersionInfoType ): - with self.subTest(attr=attr_name): - attr = getattr(sys, attr_name) - self.check_structseq(type(attr)) + attr = getattr(sys, attr_name) + self._check_structseq(type(attr)) def test_sys_funcs(self): func_names = ['get_asyncgen_hooks'] # AsyncGenHooksType if hasattr(sys, 'getwindowsversion'): func_names.append('getwindowsversion') # WindowsVersionType for func_name in func_names: - with self.subTest(func=func_name): - func = getattr(sys, func_name) - obj = func() - self.check_structseq(type(obj)) + func = getattr(sys, func_name) + obj = func() + self._check_structseq(type(obj)) try: - unittest.main() + tests = TestStructSeq() + tests.test_sys_attrs() + tests.test_sys_funcs() except SystemExit as exc: if exc.args[0] != 0: raise diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index b50a1543..044bfc97 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -13,6 +13,7 @@ import sys import os import gc import errno +import functools import signal import array import socket @@ -31,6 +32,7 @@ from test import support from test.support import hashlib_helper from test.support import import_helper from test.support import os_helper +from test.support import script_helper from test.support import socket_helper from test.support import threading_helper from test.support import warnings_helper @@ -48,6 +50,7 @@ import multiprocessing.heap import multiprocessing.managers import multiprocessing.pool import multiprocessing.queues +from multiprocessing.connection import wait, AuthenticationError from multiprocessing import util @@ -124,13 +127,13 @@ else: # BaseManager.shutdown_timeout SHUTDOWN_TIMEOUT = support.SHORT_TIMEOUT +WAIT_ACTIVE_CHILDREN_TIMEOUT = 5.0 + HAVE_GETVALUE = not getattr(_multiprocessing, 'HAVE_BROKEN_SEM_GETVALUE', False) WIN32 = (sys.platform == "win32") -from multiprocessing.connection import wait - def wait_for_handle(handle, timeout): if timeout is not None and timeout < 0.0: timeout = None @@ -170,6 +173,59 @@ def check_enough_semaphores(): "to run the test (required: %d)." % nsems_min) +def only_run_in_spawn_testsuite(reason): + """Returns a decorator: raises SkipTest when SM != spawn at test time. + + This can be useful to save overall Python test suite execution time. + "spawn" is the universal mode available on all platforms so this limits the + decorated test to only execute within test_multiprocessing_spawn. + + This would not be necessary if we refactored our test suite to split things + into other test files when they are not start method specific to be rerun + under all start methods. + """ + + def decorator(test_item): + + @functools.wraps(test_item) + def spawn_check_wrapper(*args, **kwargs): + if (start_method := multiprocessing.get_start_method()) != "spawn": + raise unittest.SkipTest(f"{start_method=}, not 'spawn'; {reason}") + return test_item(*args, **kwargs) + + return spawn_check_wrapper + + return decorator + + +class TestInternalDecorators(unittest.TestCase): + """Logic within a test suite that could errantly skip tests? Test it!""" + + @unittest.skipIf(sys.platform == "win32", "test requires that fork exists.") + def test_only_run_in_spawn_testsuite(self): + if multiprocessing.get_start_method() != "spawn": + raise unittest.SkipTest("only run in test_multiprocessing_spawn.") + + try: + @only_run_in_spawn_testsuite("testing this decorator") + def return_four_if_spawn(): + return 4 + except Exception as err: + self.fail(f"expected decorated `def` not to raise; caught {err}") + + orig_start_method = multiprocessing.get_start_method(allow_none=True) + try: + multiprocessing.set_start_method("spawn", force=True) + self.assertEqual(return_four_if_spawn(), 4) + multiprocessing.set_start_method("fork", force=True) + with self.assertRaises(unittest.SkipTest) as ctx: + return_four_if_spawn() + self.assertIn("testing this decorator", str(ctx.exception)) + self.assertIn("start_method=", str(ctx.exception)) + finally: + multiprocessing.set_start_method(orig_start_method, force=True) + + # # Creates a wrapper for a function which records the time it takes to finish # @@ -273,6 +329,7 @@ class _TestProcess(BaseTestCase): p.join() self.assertEqual(p.exitcode, 0) + @support.requires_resource('cpu') def test_args_argument(self): # bpo-45735: Using list or tuple as *args* in constructor could # achieve the same effect. @@ -618,6 +675,7 @@ class _TestProcess(BaseTestCase): close_queue(q) + @support.requires_resource('walltime') def test_many_processes(self): if self.TYPE == 'threads': self.skipTest('test not appropriate for {}'.format(self.TYPE)) @@ -3040,7 +3098,7 @@ class _TestRemoteManager(BaseTestCase): del queue -@hashlib_helper.requires_hashdigest('md5') +@hashlib_helper.requires_hashdigest('sha256') class _TestManagerRestart(BaseTestCase): @classmethod @@ -3529,7 +3587,7 @@ class _TestPoll(BaseTestCase): # @unittest.skipUnless(HAS_REDUCTION, "test needs multiprocessing.reduction") -@hashlib_helper.requires_hashdigest('md5') +@hashlib_helper.requires_hashdigest('sha256') class _TestPicklingConnections(BaseTestCase): ALLOWED_TYPES = ('processes',) @@ -3832,7 +3890,7 @@ class _TestSharedCTypes(BaseTestCase): @unittest.skipUnless(HAS_SHMEM, "requires multiprocessing.shared_memory") -@hashlib_helper.requires_hashdigest('md5') +@hashlib_helper.requires_hashdigest('sha256') class _TestSharedMemory(BaseTestCase): ALLOWED_TYPES = ('processes',) @@ -4318,18 +4376,13 @@ class _TestSharedMemory(BaseTestCase): p.terminate() p.wait() - deadline = time.monotonic() + support.LONG_TIMEOUT - t = 0.1 - while time.monotonic() < deadline: - time.sleep(t) - t = min(t*2, 5) + err_msg = ("A SharedMemory segment was leaked after " + "a process was abruptly terminated") + for _ in support.sleeping_retry(support.LONG_TIMEOUT, err_msg): try: smm = shared_memory.SharedMemory(name, create=False) except FileNotFoundError: break - else: - raise AssertionError("A SharedMemory segment was leaked after" - " a process was abruptly terminated.") if os.name == 'posix': # Without this line it was raising warnings like: @@ -4415,6 +4468,7 @@ class _TestFinalize(BaseTestCase): result = [obj for obj in iter(conn.recv, 'STOP')] self.assertEqual(result, ['a', 'b', 'd10', 'd03', 'd02', 'd01', 'e']) + @support.requires_resource('cpu') def test_thread_safety(self): # bpo-24484: _run_finalizers() should be thread-safe def cb(): @@ -4639,7 +4693,7 @@ class TestInvalidHandle(unittest.TestCase): -@hashlib_helper.requires_hashdigest('md5') +@hashlib_helper.requires_hashdigest('sha256') class OtherTest(unittest.TestCase): # TODO: add more tests for deliver/answer challenge. def test_deliver_challenge_auth_failure(self): @@ -4659,7 +4713,7 @@ class OtherTest(unittest.TestCase): def recv_bytes(self, size): self.count += 1 if self.count == 1: - return multiprocessing.connection.CHALLENGE + return multiprocessing.connection._CHALLENGE elif self.count == 2: return b'something bogus' return b'' @@ -4669,6 +4723,44 @@ class OtherTest(unittest.TestCase): multiprocessing.connection.answer_challenge, _FakeConnection(), b'abc') + +@hashlib_helper.requires_hashdigest('md5') +@hashlib_helper.requires_hashdigest('sha256') +class ChallengeResponseTest(unittest.TestCase): + authkey = b'supadupasecretkey' + + def create_response(self, message): + return multiprocessing.connection._create_response( + self.authkey, message + ) + + def verify_challenge(self, message, response): + return multiprocessing.connection._verify_challenge( + self.authkey, message, response + ) + + def test_challengeresponse(self): + for algo in [None, "md5", "sha256"]: + with self.subTest(f"{algo=}"): + msg = b'is-twenty-bytes-long' # The length of a legacy message. + if algo: + prefix = b'{%s}' % algo.encode("ascii") + else: + prefix = b'' + msg = prefix + msg + response = self.create_response(msg) + if not response.startswith(prefix): + self.fail(response) + self.verify_challenge(msg, response) + + # TODO(gpshead): We need integration tests for handshakes between modern + # deliver_challenge() and verify_response() code and connections running a + # test-local copy of the legacy Python <=3.11 implementations. + + # TODO(gpshead): properly annotate tests for requires_hashdigest rather than + # only running these on a platform supporting everything. otherwise logic + # issues preventing it from working on FIPS mode setups will be hidden. + # # Test Manager.start()/Pool.__init__() initializer feature - see issue 5585 # @@ -4676,7 +4768,7 @@ class OtherTest(unittest.TestCase): def initializer(ns): ns.test += 1 -@hashlib_helper.requires_hashdigest('md5') +@hashlib_helper.requires_hashdigest('sha256') class TestInitializers(unittest.TestCase): def setUp(self): self.mgr = multiprocessing.Manager() @@ -4862,6 +4954,7 @@ class TestWait(unittest.TestCase): def test_wait_socket_slow(self): self.test_wait_socket(True) + @support.requires_resource('walltime') def test_wait_timeout(self): from multiprocessing.connection import wait @@ -4890,6 +4983,7 @@ class TestWait(unittest.TestCase): sem.release() time.sleep(period) + @support.requires_resource('walltime') def test_wait_integer(self): from multiprocessing.connection import wait @@ -4970,11 +5064,13 @@ class TestFlags(unittest.TestCase): conn.send(tuple(sys.flags)) @classmethod - def run_in_child(cls): + def run_in_child(cls, start_method): import json - r, w = multiprocessing.Pipe(duplex=False) - p = multiprocessing.Process(target=cls.run_in_grandchild, args=(w,)) - p.start() + mp = multiprocessing.get_context(start_method) + r, w = mp.Pipe(duplex=False) + p = mp.Process(target=cls.run_in_grandchild, args=(w,)) + with warnings.catch_warnings(category=DeprecationWarning): + p.start() grandchild_flags = r.recv() p.join() r.close() @@ -4985,8 +5081,10 @@ class TestFlags(unittest.TestCase): def test_flags(self): import json # start child process using unusual flags - prog = ('from test._test_multiprocessing import TestFlags; ' + - 'TestFlags.run_in_child()') + prog = ( + 'from test._test_multiprocessing import TestFlags; ' + f'TestFlags.run_in_child({multiprocessing.get_start_method()!r})' + ) data = subprocess.check_output( [sys.executable, '-E', '-S', '-O', '-c', prog]) child_flags, grandchild_flags = json.loads(data.decode('ascii')) @@ -5238,6 +5336,14 @@ class TestStartMethod(unittest.TestCase): self.assertRaises(ValueError, ctx.set_start_method, None) self.check_context(ctx) + def test_context_check_module_types(self): + try: + ctx = multiprocessing.get_context('forkserver') + except ValueError: + raise unittest.SkipTest('forkserver should be available') + with self.assertRaisesRegex(TypeError, 'module_names must be a list of strings'): + ctx.set_forkserver_preload([1, 2, 3]) + def test_set_get(self): multiprocessing.set_forkserver_preload(PRELOAD) count = 0 @@ -5282,6 +5388,54 @@ class TestStartMethod(unittest.TestCase): print(err) self.fail("failed spawning forkserver or grandchild") + @unittest.skipIf(sys.platform == "win32", + "Only Spawn on windows so no risk of mixing") + @only_run_in_spawn_testsuite("avoids redundant testing.") + def test_mixed_startmethod(self): + # Fork-based locks cannot be used with spawned process + for process_method in ["spawn", "forkserver"]: + queue = multiprocessing.get_context("fork").Queue() + process_ctx = multiprocessing.get_context(process_method) + p = process_ctx.Process(target=close_queue, args=(queue,)) + err_msg = "A SemLock created in a fork" + with self.assertRaisesRegex(RuntimeError, err_msg): + p.start() + + # non-fork-based locks can be used with all other start methods + for queue_method in ["spawn", "forkserver"]: + for process_method in multiprocessing.get_all_start_methods(): + queue = multiprocessing.get_context(queue_method).Queue() + process_ctx = multiprocessing.get_context(process_method) + p = process_ctx.Process(target=close_queue, args=(queue,)) + p.start() + p.join() + + @classmethod + def _put_one_in_queue(cls, queue): + queue.put(1) + + @classmethod + def _put_two_and_nest_once(cls, queue): + queue.put(2) + process = multiprocessing.Process(target=cls._put_one_in_queue, args=(queue,)) + process.start() + process.join() + + def test_nested_startmethod(self): + # gh-108520: Regression test to ensure that child process can send its + # arguments to another process + queue = multiprocessing.Queue() + + process = multiprocessing.Process(target=self._put_two_and_nest_once, args=(queue,)) + process.start() + process.join() + + results = [] + while not queue.empty(): + results.append(queue.get()) + + self.assertEqual(results, [2, 1]) + @unittest.skipIf(sys.platform == "win32", "test semantics don't make sense on Windows") @@ -5292,13 +5446,12 @@ class TestResourceTracker(unittest.TestCase): # Check that killing process does not leak named semaphores # cmd = '''if 1: - import time, os, tempfile + import time, os import multiprocessing as mp from multiprocessing import resource_tracker from multiprocessing.shared_memory import SharedMemory mp.set_start_method("spawn") - rand = tempfile._RandomNameSequence() def create_and_register_resource(rtype): @@ -5339,9 +5492,10 @@ class TestResourceTracker(unittest.TestCase): p.terminate() p.wait() - deadline = time.monotonic() + support.LONG_TIMEOUT - while time.monotonic() < deadline: - time.sleep(.5) + err_msg = (f"A {rtype} resource was leaked after a process was " + f"abruptly terminated") + for _ in support.sleeping_retry(support.SHORT_TIMEOUT, + err_msg): try: _resource_unlink(name2, rtype) except OSError as e: @@ -5349,10 +5503,7 @@ class TestResourceTracker(unittest.TestCase): # EINVAL self.assertIn(e.errno, (errno.ENOENT, errno.EINVAL)) break - else: - raise AssertionError( - f"A {rtype} resource was leaked after a process was " - f"abruptly terminated.") + err = p.stderr.read().decode('utf-8') p.stderr.close() expected = ('resource_tracker: There appear to be 2 leaked {} ' @@ -5539,7 +5690,7 @@ class TestPoolNotLeakOnFailure(unittest.TestCase): any(process.is_alive() for process in forked_processes)) -@hashlib_helper.requires_hashdigest('md5') +@hashlib_helper.requires_hashdigest('sha256') class TestSyncManagerTypes(unittest.TestCase): """Test all the types which can be shared between a parent and a child process by using a manager which acts as an intermediary @@ -5588,18 +5739,18 @@ class TestSyncManagerTypes(unittest.TestCase): # but this can take a bit on slow machines, so wait a few seconds # if there are other children too (see #17395). join_process(self.proc) + + timeout = WAIT_ACTIVE_CHILDREN_TIMEOUT start_time = time.monotonic() - t = 0.01 - while len(multiprocessing.active_children()) > 1: - time.sleep(t) - t *= 2 - dt = time.monotonic() - start_time - if dt >= 5.0: - test.support.environment_altered = True - support.print_warning(f"multiprocessing.Manager still has " - f"{multiprocessing.active_children()} " - f"active children after {dt} seconds") + for _ in support.sleeping_retry(timeout, error=False): + if len(multiprocessing.active_children()) <= 1: break + else: + dt = time.monotonic() - start_time + support.environment_altered = True + support.print_warning(f"multiprocessing.Manager still has " + f"{multiprocessing.active_children()} " + f"active children after {dt:.1f} seconds") def run_worker(self, worker, obj): self.proc = multiprocessing.Process(target=worker, args=(obj, )) @@ -5704,45 +5855,48 @@ class TestSyncManagerTypes(unittest.TestCase): @classmethod def _test_list(cls, obj): - assert obj[0] == 5 - assert obj.count(5) == 1 - assert obj.index(5) == 0 + case = unittest.TestCase() + case.assertEqual(obj[0], 5) + case.assertEqual(obj.count(5), 1) + case.assertEqual(obj.index(5), 0) obj.sort() obj.reverse() for x in obj: pass - assert len(obj) == 1 - assert obj.pop(0) == 5 + case.assertEqual(len(obj), 1) + case.assertEqual(obj.pop(0), 5) def test_list(self): o = self.manager.list() o.append(5) self.run_worker(self._test_list, o) - assert not o + self.assertIsNotNone(o) self.assertEqual(len(o), 0) @classmethod def _test_dict(cls, obj): - assert len(obj) == 1 - assert obj['foo'] == 5 - assert obj.get('foo') == 5 - assert list(obj.items()) == [('foo', 5)] - assert list(obj.keys()) == ['foo'] - assert list(obj.values()) == [5] - assert obj.copy() == {'foo': 5} - assert obj.popitem() == ('foo', 5) + case = unittest.TestCase() + case.assertEqual(len(obj), 1) + case.assertEqual(obj['foo'], 5) + case.assertEqual(obj.get('foo'), 5) + case.assertListEqual(list(obj.items()), [('foo', 5)]) + case.assertListEqual(list(obj.keys()), ['foo']) + case.assertListEqual(list(obj.values()), [5]) + case.assertDictEqual(obj.copy(), {'foo': 5}) + case.assertTupleEqual(obj.popitem(), ('foo', 5)) def test_dict(self): o = self.manager.dict() o['foo'] = 5 self.run_worker(self._test_dict, o) - assert not o + self.assertIsNotNone(o) self.assertEqual(len(o), 0) @classmethod def _test_value(cls, obj): - assert obj.value == 1 - assert obj.get() == 1 + case = unittest.TestCase() + case.assertEqual(obj.value, 1) + case.assertEqual(obj.get(), 1) obj.set(2) def test_value(self): @@ -5753,10 +5907,11 @@ class TestSyncManagerTypes(unittest.TestCase): @classmethod def _test_array(cls, obj): - assert obj[0] == 0 - assert obj[1] == 1 - assert len(obj) == 2 - assert list(obj) == [0, 1] + case = unittest.TestCase() + case.assertEqual(obj[0], 0) + case.assertEqual(obj[1], 1) + case.assertEqual(len(obj), 2) + case.assertListEqual(list(obj), [0, 1]) def test_array(self): o = self.manager.Array('i', [0, 1]) @@ -5764,8 +5919,9 @@ class TestSyncManagerTypes(unittest.TestCase): @classmethod def _test_namespace(cls, obj): - assert obj.x == 0 - assert obj.y == 1 + case = unittest.TestCase() + case.assertEqual(obj.x, 0) + case.assertEqual(obj.y, 1) def test_namespace(self): o = self.manager.Namespace() @@ -5775,6 +5931,7 @@ class TestSyncManagerTypes(unittest.TestCase): class TestNamedResource(unittest.TestCase): + @only_run_in_spawn_testsuite("spawn specific test.") def test_global_named_resource_spawn(self): # # gh-90549: Check that global named resources in main module @@ -5785,22 +5942,18 @@ class TestNamedResource(unittest.TestCase): with open(testfn, 'w', encoding='utf-8') as f: f.write(textwrap.dedent('''\ import multiprocessing as mp - ctx = mp.get_context('spawn') - global_resource = ctx.Semaphore() - def submain(): pass - if __name__ == '__main__': p = ctx.Process(target=submain) p.start() p.join() ''')) - rc, out, err = test.support.script_helper.assert_python_ok(testfn) + rc, out, err = script_helper.assert_python_ok(testfn) # on error, err = 'UserWarning: resource_tracker: There appear to # be 1 leaked semaphore objects to clean up at shutdown' - self.assertEqual(err, b'') + self.assertFalse(err, msg=err.decode('utf-8')) class MiscTestCase(unittest.TestCase): @@ -5809,6 +5962,24 @@ class MiscTestCase(unittest.TestCase): support.check__all__(self, multiprocessing, extra=multiprocessing.__all__, not_exported=['SUBDEBUG', 'SUBWARNING']) + @only_run_in_spawn_testsuite("avoids redundant testing.") + def test_spawn_sys_executable_none_allows_import(self): + # Regression test for a bug introduced in + # https://github.com/python/cpython/issues/90876 that caused an + # ImportError in multiprocessing when sys.executable was None. + # This can be true in embedded environments. + rc, out, err = script_helper.assert_python_ok( + "-c", + """if 1: + import sys + sys.executable = None + assert "multiprocessing" not in sys.modules, "already imported!" + import multiprocessing + import multiprocessing.spawn # This should not fail\n""", + ) + self.assertEqual(rc, 0) + self.assertFalse(err, msg=err.decode('utf-8')) + # # Mixins @@ -5896,18 +6067,17 @@ class ManagerMixin(BaseMixin): # only the manager process should be returned by active_children() # but this can take a bit on slow machines, so wait a few seconds # if there are other children too (see #17395) + timeout = WAIT_ACTIVE_CHILDREN_TIMEOUT start_time = time.monotonic() - t = 0.01 - while len(multiprocessing.active_children()) > 1: - time.sleep(t) - t *= 2 - dt = time.monotonic() - start_time - if dt >= 5.0: - test.support.environment_altered = True - support.print_warning(f"multiprocessing.Manager still has " - f"{multiprocessing.active_children()} " - f"active children after {dt} seconds") + for _ in support.sleeping_retry(timeout, error=False): + if len(multiprocessing.active_children()) <= 1: break + else: + dt = time.monotonic() - start_time + support.environment_altered = True + support.print_warning(f"multiprocessing.Manager still has " + f"{multiprocessing.active_children()} " + f"active children after {dt:.1f} seconds") gc.collect() # do garbage collection if cls.manager._number_of_objects() != 0: @@ -5949,7 +6119,8 @@ class ThreadsMixin(BaseMixin): # Functions used to create test cases from the base ones in this module # -def install_tests_in_module_dict(remote_globs, start_method): +def install_tests_in_module_dict(remote_globs, start_method, + only_type=None, exclude_types=False): __module__ = remote_globs['__name__'] local_globs = globals() ALL_TYPES = {'processes', 'threads', 'manager'} @@ -5962,16 +6133,23 @@ def install_tests_in_module_dict(remote_globs, start_method): continue assert set(base.ALLOWED_TYPES) <= ALL_TYPES, base.ALLOWED_TYPES for type_ in base.ALLOWED_TYPES: + if only_type and type_ != only_type: + continue + if exclude_types: + continue newname = 'With' + type_.capitalize() + name[1:] Mixin = local_globs[type_.capitalize() + 'Mixin'] class Temp(base, Mixin, unittest.TestCase): pass if type_ == 'manager': - Temp = hashlib_helper.requires_hashdigest('md5')(Temp) + Temp = hashlib_helper.requires_hashdigest('sha256')(Temp) Temp.__name__ = Temp.__qualname__ = newname Temp.__module__ = __module__ remote_globs[newname] = Temp elif issubclass(base, unittest.TestCase): + if only_type: + continue + class Temp(base, object): pass Temp.__name__ = Temp.__qualname__ = name diff --git a/Lib/test/_test_venv_multiprocessing.py b/Lib/test/_test_venv_multiprocessing.py index af72e915..ad985dd8 100644 --- a/Lib/test/_test_venv_multiprocessing.py +++ b/Lib/test/_test_venv_multiprocessing.py @@ -1,7 +1,6 @@ import multiprocessing import random import sys -import time def fill_queue(queue, code): queue.put(code) @@ -30,6 +29,7 @@ def test_func(): def main(): + multiprocessing.set_start_method('spawn') test_pool = multiprocessing.Process(target=test_func) test_pool.start() test_pool.join() diff --git a/Lib/test/audiodata/pluck-pcm24-ext.wav b/Lib/test/audiodata/pluck-pcm24-ext.wav new file mode 100644 index 0000000000000000000000000000000000000000..e4c2d133597d85079671147e52bacffef232995d GIT binary patch literal 19922 zcmWieWn5HW6UT4u-c5E{mhKJ_MM@C?2@6rNK*2@@6;$j$B6c8(fsKJ+VgQngC?X*! zA}!s$%XaU*kI#$qW?szae9t+bnfc9`m5UcFs0jvu(D`cvcf=etvjYGC!y!O(8UXBo zK!6D70XqK{{Lc>lTL8cWP6EJdVD^LkJGN{)i2Som&;THE%fT(D|M}TI9eOx{Gu8*K zRsiK%&eOO^OXo@0pY*l6c1tet?yE&I0c<t;B_SJB?uIwSV{1c;et0X^Wamv=A)I;F zerxT-iwJ}Je}}yloX^(>C#);a9_@cc(D+@@Yi~bgVc**p7P@m^f2f;M$9we45iRKK zRJdcCgRN92<xb!c<#w4^i>Y$kL0XokRL$(+`YL-9HD|jjiiW+**DEuQl!$Uw?JYZI zZNiJSejj2X(Z>GC|B*L;DqB{iQEV3S@hK~^hx>K4E`XjcjMTyLM4v!50Gu37Wf`U| z&i$a_UAXc|2|YJ=s%;aa!>f)}%1Fx_oIXx_8L;j6dJ0xe!b~aWi>GN&sCyTM^aW@{ z{=7_>t2rquaG%i7)e2Y?PRYF3veuJ$tbmg>1FT!n7B^Rkwm$kkDBx6CO+Fush&8;b zH!!tIvA@12OZn}|;jZPgNHupl=5+D@`gU|~46u3MWxZH?iOJvwZ7efva@Qi+@?i1O zw2QGzlzY;+)^_StA)#!e`uo+%{SVb45fbx36}5I%$(VY#!3Vn-ym!u~yN^JDVC;<s zvDDQumq0D-8pWNNR||FbCTe{FX1P@8{^PZz>;7Y3J)%`_@xu6zri&ddH<G^Lz_FlR z)UxD}!*6LJU0u;(bh@-*po{YQPv}t-60pLUI)a`a)@mS;qZnIwQM88OR||uf&te{Q zS~LDM`@{@U{A|b96VQP4F7IVfH;LPvq53*<2l*hHyID(T<%C_N6+389Zw2<NwD+Cc zkLaZC7+odheJA^o;%Z2z`R(a-N4pb?r@yKie7c=Wvg1St(-%ZalB1KJ)74KRyH|PR z^Cr-}v+(pi;?r8Vv3hWoNR8TrB{^W7SIX$oII$>TbP_mRr<K7&4i1n*Zj&Fjv3-AO zT#g&LPiJZF3Rk-8{9~V5tYfn>KCG1W!gu)BQ|71RKSqOT|4!pZ1-WiH_p5^9-_XOG zLmNI-|9k^w`99xysp#hCu6Gup?~jA^7fHi?TZpaHBIn;v7BkajXM*U=@?|cH2C73l zxU>>oN2~YKfWJu<RvXj?=O0QRi`VtZndC{%!5Pzz4ti+-qv^d*Pc>Y7)vaF2SqgOp z7{Wfaoh>!`C4Jqxmfr1lL!BXGZ#y`8nQV4~G@$%`F&AqFD;Hk@Pwk}YE(PfY%JdQd zf6*~I8~5L_{9_6>Ti&@O26uKaIk*HkJKHC$7Vg_IxyFXX`7*s>1zlr)L+dl<+Y{Td zd;fpuRVTEAEM_-;&@AK4NZZ4h(7)jqK>f#FYDX$?qMF;0%j}!_`zen$w(WjTUi02M zfkVtmS%6<4ru8W7CFtuptJnHb6L!n`otgi<wc*V3+l?0Bw9;FKP$lWo{mL5*qzT49 z1YzBQZ(Fh@V|`ttqmxSt+?geVmlKfQ1HCU8?d5m7GkN`&th+9zpoOfitNyg)89l%I z{o(yXkBg@c9p}EOWqdm+^O>KYUI@fgywh%mZG{wrt?;oSD0(3@{HAsNN?;!DEh@rZ zL#q24`1}p>nw7Zriw)-UpnWI%yCaEx%bXuvpjsbl>N97I?_Kj|j7463Gc}K$d1fks zpt&$}&)usU|MuTgLQ$s2flla?xVaW$)KpM@)q(QyWA~W?vIki!K?h9;2tpHx3*_KN z6?*N?JpOblQEI$<)Bo9DFj!s#N|LKa@=TW**U6y=D>h~!XM*LH*;v?_@<4s*wW#mE z%{eK}Zf)xa%d#}uUiL)(?0SH8<v;Bz;CJ@8pfjd-y>}t3Jllgd`4;sJJ@~Dz+&i_t z4oOwWJq+s4kzt?sCvks>;x~}n5~5c;b=e(c=EgQyA5wj@b3KalI0hSO_~kX-(_Ua{ zsgajTfh&ewj})ZV#me#+Iph4`lV$Wzd{4c<Oj=XrK%`bdR<=sY_;=Tr?dY|Q*Y^~W zb+I|QtpwX;yDKAz`d7;mw8&eETW=mG`#8}q*rV*7fxS`0$G0^65K^VYZfF`6&33Ci z$Lt-t^h;Zdl-ZPjj4>ea&k3XShSj^+5nhIk6%As2#U1AZr0dP{p1E_DZ?Qi*GN6t& z(fQrYHtQvA?po3Ix4yS?)klP$+%<F-O84r`?ee&uJuFJonE#UZKwDAvR7ra{v}qH; zzA?=_n;bDuU^zkpZnMSfi7#Jv<ru=5^~~hW_zv-`*CY(*HZ0Ln$L(FScQ3Zph@5N= zF^1^LEYz=3y5a=&>L2qSGlq~UxN?QnfF;fT`G58s?`hoZ^2ki``J>9OrwIQn8FvWI z`OWg{q{j&r6ZvE$f^3qB>Kpo8yh<!=*GttRt@bnUG@@#q@f|$CJn8Y`eS;SCGw1qC zW{JxJssXj^>4-Ru5c9s-Q4hC}aDYf@%-WpVg`7AG7H8kUu1F`3wyv3m!@Ev*;*XjN zuXSQSz@Xf&Z)woQKfV0gX*q{S9>tnG;_@S;LfT=qo2KB~Ao?;VBf6XB*4MRvlv*X# z|GJMf5;~f)0D(v4tsC(DW8Pc(R3(zOBOyvo(;TlZWvsOgvKeo#SKkRo>gU4w(d14a z=AEVVS(lg*Nty|tPReT;^A>H6O`yGPP>r{f!$WJgr2n7&&|E@>3;uc!X>U_@eITVN z6<B(b#0&HOsU!+7ncQ_H-AZE4!YDN@eto9Q(F4`-M(lTc@7{^fbo}Gt<U{>YLr?`1 zYL`|$Jc|jNgxkJLWRE{NR!=6akhWy>N4j{t{MtEBTeSXb$FYfDx88Q%`mWMT>R!Sn zWc&8V{xwN48^g}p7pa8%G{n<o_-~<jZ3iVfKWCxuzi3gLJ*Kf{pYG5i%1UP`Jc+bs zjH1OD<^DXzlw$dgN$WqdIcfR}@@1dHJo~*=j%$>Ji{RxzgmMIZP9+XVr~|_m08?|@ zxuomKOisU3Cz<}pX{P5x%F9Q21xtwaZ3j=;5awCUyyHR=Jb$Hmf#N-9VpK{R^7Q45 z5FLNmI252|m(h|%l;K-G){YF{Bcm==T4A%3zkk&1`);HcK<%GnmBm5M<(0FQ>f`Q{ z?w%5|_Ak>@lXlkqO&<LRT3pI0opBjx^@@(SXzj2?mm!DmSJmSN&=L&>zvr;)oF;nf z9JS_1zND#CM<C-Z;=HSL_3p2RGqfHAe+gWod6}xQ+K<}unP|EniE8NC##d#8IS)2V z8Fg?-usHP_plBBzKj2Hwll3Md8^2>aR{)QMgu~f*?<r~;bz0PU&67W#oH@Z-zCwL# zT;oZ~iiQKUrhUab#?e8iMS~v+JA>B2i%D;G7E)U%_rmM`>?N1Gc+tNS4W_y2ONsNW zfY?Rkg@D^x4&6YG&ezwP8+j#)uc>=Vu|I;!O_;MV3t4xwF6p^?&4te5DY5pQ&g65G z2a;P)*!71P+4#TfNPVZzG3@YqQZN71^=9wDLbJX@u8jN2p>PRv(QHoqJNvdZGMzZ$ z+Xm#tHgP<OdC>OfwGr)#=;EnIT3Kp<8AOYj&2mz~UTMAi<|zkd#&26i<U4vpD!#V1 z_`y#8Cha+&Z;2ni&<sAM%9(}VpF~!ik}Z8s-P|>8S~Tmk-Iw!4>}gM${&1P^(!zE~ z=xeZsU^=<i)4(;IU|F*3#9`F2s_nfq<t01su{QZekV7kvu*P?xK^mdD8UX&F9GS(@ zaN1p-8N-2P=l#&kf~8U4ly{FB=rX@J5lI*t3E8Ti>-W<qN9;4Bf9=!BgyU_UtNUwE z?Z>w}_J&%maPByo-Tkbf`+Pxjwz~g*I5l$HC?`bgOYT%qv=#4;qPma1h=#JxOPjS> zDNZfWu<o<O!eS}AJz6koOp9Bnmuw4Fof}>1BfASxLTh=RIaV)tobpKVr$3yo;|>Fz z0{e%?&pnmr4nY21gtqU3ZHMULd#urZ_KxX2dxQ1D%ZrD#*%zh-(YcJ7uF_m9O7vkl zM~>KDjQn|=@NNU%LMJsZdL0pnURX`NJqWv$tRnfrmo*tX%L(sd=qb4r_Rnc^k8Ap0 zFZR&UI((?m!;((><hG!kP_YcnKaEv-SN?b|nHJfx=P5@R)a|Q3@YR>RIjaL$YTY>A zt|jFj8tYzm?YH5`fPE}5P(F4ePG|dEzRO?pr;sW@u9<y{G>Iy7pK7Vj^@Kjq9}6sY zU9EE^bwFiCd!*FUIR*H6i%tI%*Lf)r3deDojf2HF-CKR|!T8rgqhAR;fy(0BCIw-V z6fGfSnDZS97)z)0#1D0Ycgf3!4aYX-xQFT{0?sGiYYqkL<abicS5L@CV0`iN2?X|( zm@&^0YOFpWTL|g&@theD!8aspH`u$^M!piMwF0PL$Qa4?*lx{@C;nc(%=T-1r6w^p z+8XUu6SbR7N8Ir&zu!-}63(aJuYYkQ-0tND1Cih0L9>qU(=Ahd+Q}L!FSO^CU%kv| zXl0lvCU-)L>f{^{niZLsQL*;d+UIUjyg}9LSnc`3;Xp6Lh%2QJPwH9)wi=75Wz|~3 zhZwB@3OglWU*$g!8f#x~dg#h9qaJ0mM~hEueb%1BuUHH`RE)Q2SQet`mqZ1PtXDzQ zyiS8$8g=JJ)3aL&H&G2tHfbifvM^h_ASwCJQm*eDQ2omT7{hYkyBxj`?p|A6{2toJ z{~fRqus-VZ0|Hnx=glvL>y1GzG5JiG{^U`XGnHQj>E4=nGv2Iea2*SIOFCpS?N<|C z`ea~Lt|atq^;&yQpjKN?aR2>L9O?aA@Wdii+NN+IGRnK7otn;u4zvG``l>lM*RVd! zlPuh0!M_Wr_USKcr~MYIY2La==S<>BM)crH6+>_M!>?PNl<0Tl*GbAvm2~}u+_6p` zc4aXABfG|<-*yILYR%C5J&Y=d8^<<_$x}LhU^%~{e43?LAD~-m1@2yH$}VKhO}6|o zy~2O4vBh=C^>mh7*mRrSq{jntIA7hGYH8LZ_ZH1Q)1^v(+<WpduG?CEvlYAZ%j)N9 z{6DuPR^~`co5to<)L~zmeJY!stSnn@&_gIben5Nm*r?MO#foL$b_wX-A&YR86yL2` zuAbnf)G@fd|Mg0j+q5mswOHoe+HT3b$LzNH^7qX0k>rQnt}eXp4yw0?{O3%|LKnDc z*!Z(H1H1`Pq<U|xri!wSzZ|avp6czoSiPG<8MId?w#g1VvU^XD*FKUwz1(|sgk00m zT`gs@z7Nc((Aa0l&Ao22@P#^R0b55?V_gP5FU>H#LlIzQ+3{2BSD;N2wI%nRNn8A& zhr4F7!1j(NVY)H#BSF6ItS&V~bgtJuKUy}FB=IO#*ZlZKamVBIC>Gy<uxCpaFD2Su zHajy#e;$m^Hr3^4tLHlyXBJi1PU<SIw9gNr68ubKIGCm%DSx-{mY}hpKiXwqJ?~U^ zPw~X_(3Xx9rlxCJ4xKOz6m);vJ5U=l-ibHgE)>1vgJrGiy;By~C@BA!<yeyD$}FTo zt^Z&euQS*<<wNr}LtSHDRil#leJ6k8G*RU~cHP3E(*@X5X@}twc-^;-SAmSoV*@8( z4O4&KixtKWBJit1+v0^*U^m>IVE&^*`slMQy^J}TZdbc_*hy&8Y1-Z(qQ@5+h9AKl zY?!wX30eTH<QPu=edh)*p*x8fBv$^o_#^i|pnF0n&V@e|`I6M+n_HYiTQ&Fnpq6bg zSRAK1r#78b{5niGsNT}>%z#Q`uq!sGPAt}P&zs7=*PGxyBnharkajq0_Z%fPFX!v_ z%xKwBZq;_PccCYr?8)T?{&|@vKcFWHc@4!lnm*Z1>F=_i<goI0Q0t%SKi<L9IcNCE zseSQT_R;nq7JFdy`iS4zDWlEIP4|0+r-&gp+bW&Fd$#RwXVV%|2YrU9>g&S9jDOmS z7?GrRT2tRaj>^~BpyiUxOo!BE)H~UBHB6yI-*`i8>qt1cHH$uNzFff2UY<DlID!?w zaC9Kr@#`C&`A_DX_3BM~8b2*0<Od914<Vmg?A%CXP~ObtWM~_Tv@`9E3ZAPs1(+qB zX&iFZkKz4%YfpOEOL~(j)xV*i(>nf{$=#XRH*WPKqOASU&PIsRGJ2Ex<ae9aXZw}4 zgF!xE=!h^)+Mx9iALR}$orAt>({|fJ8{6;1W3d9gb=*Gd)R_rYTXY9kcZjz#OPAKZ zd5_0$?%R(~823@^6<tw7)L+A`+F4-z*^Uq4<b!)hNpHz5xC}w{pY5c*Pcw*`Fm9&M zdc*Da38h984)(v1<xi}`CY0*~^;Udq-<=LU-3taZ@<a02nkB<QYgslo2P3}N-Sy?= z8|&M6fG^B@>fLC!yZ#!iWWMw?nF+J`H@zLmdSg2*Vs9IEIKzYQjR(TovIn%Qld6Pi z@Ut&U?|Fh%dyUfe4!bQ=ExFXApx3V|?O2pqqka1CA5T^I!LI2B_FTR3!Rf49>GC8> zCzgr`E!!g$<oG1iSD*G9o1WRDLC>@hs5F-kD_lZYy$+odVYIQJntf8$-V+@J*7)ZQ z1QVnydX#Z7qix+A*uS6)Zz0ZFGPx)ay;Y~q*sh)OjhPP`si@}1LzrQE9NHTcdQa^) z8{sD(ns1K<ayDrh{p=+()omZ84S|!Du9};Z22QMJx&9gmrQ7s63M$nm@-@VD3FD4I zT2o;2EkB)cck0sjI_Exm{@kOh@8{&Bqvvc)f8MNj@lkhmjV5AK{$?65?;Pj4_f%B5 zL8jeMdJv_esJHHSN9d&<fLF1rwcBsQgx7!l#U>VdWbUQUriB@*CZma}0AfO8)5Ftb z#~G5H{^WOD>ns<_SBc|abNW3ls+Xi;wyW2^fHKfpm9|mck==OIdE$5?_Ge}Hiz`~u zS?$^{Nuv3^epd)@*H5j(VIKl``6_ea0Bg^FBjlU;2^ssx0{a=4@OK|<fGow9ETfVm z034+us~*1JDN9@=fPRchm(kZ3^apxq=4>45*=5o9Q*7XAY3@tY*Ol%zGI%`E?5s4{ zn5$SjUw2#8%+2fB^h`I$>#VSQ`uc4wWyqM}H@aSRnL?uW$m;rmaYE=?@@qpVP5a!m z0eioRX<Y-$d#ct-2Cg}Eu&)e1FV{LA&-=W@wup$?@zez$iJ@oOULPkdj2r<T5jXwO zIl6|p#CE3WJlXMs?(#)6(d&tAdnk**>X>>gapZ?3Z?e%=bn0x+J~jKrSjWgFW?O0B zoc(CmO8#{Y(03Acc}e!U$<}f*_!($XGDCmV-7ZX<$o03<F_!mS)3ZXcv1Js>riocK zVq}urzjhdFBN=_`XIx@@yFOCz+r-;a{`9H!$6n^<2Iw}$)Mv2$;!)!{D97ZWHfm=P z7sdz~cjwHd-AJ%D2%ryLkQ(f!&iPW|9gpo$*L^=W<?tSvAsLBh8GL#)e0EYbjWPNp z=g%m4v_H1~XW!_I>0n$5FK(^%myPO&+Zd7_!d%^<yD)k%xu+%=8N7y^TL&MluxFD{ z|23Ak+^8$n%2GY5#*yExe}Ls9WuiyijQGKHO7CDi1F+~kRis<y)c@hQhV690NDEl1 zL&#VFc|6sQkJBm-wy3;iaQTOgoukIq6!W@Ms<T(w=$P{QUE(UmWZbxL#f}NVo}ud- z5n$Hf-cF4Mjfo<a;R8qYs~^^;;o4=7sqwCs)>i#Snx@4+2YZWIYCuc&jQlWT)+9{q zU*Ux0kV+a*j}nTV_;-UdsBxpBq(SiUu+WS$QO?sDN*Plup}uVz*U#>AUNwH%vF_E4 zF|7|=*5@gTt$`b&s-Dtob|rka5l5XPs($rluYhl8ORO@%+tZ8={70}mYqPtEvMP^i z!K3nXyOy;<=RL~qhVk|Zo9G96&qP74_MP@g`n$gOU+vW$Jt%yjAYEUK#xrrqNw@b9 zrEil(W4z8&J!`|=S_}7@xUYjvgP2jv)Y6a8#vHEGF+u95k<Ngj@F?s9GOQUvPkhXs zHOt_{T>x*go|d4Ou}Nz@!#Z3&E^jy4*U%fXN8^eeK~DK68yzMYzyr5go^b?bhfc7R zdTvpVx{9DnE9Ww$$#?sF?{b(2sBzqJQ#xz-&O~yrpiwd|+1Q-6Z>;)tzujjp*OF2k zrM%RoS6@!Z>4k0wp|wXRti9mi|9H-x!1co#$=BeawdSlR<UouaWJ0?-mmBDV<j?w% zo6NUps2$ndTbCus&FZ-2t(AoLqXMJ9XGA{sT5C6w-z%X_PxVIDAbY76o1SV+4p@xt zXB}i2Ud<uxyFgp^2Ym1opLthEJt{C=GCZ0yyz-c&=<n$F?WF!3L2H`s@8hs|hfU0o z{+mAruQhB!zKiy_7~_QA`&Y=dRN0+AmBl8L+dq}!Fz0Ehh@IG?cRr)#Gw;qXYV?b$ zm)Dik+8a%KxsR_Yz1NIuzhp+f9KY-UQd`CoCi?l$#uQe)i|%lp)~I$RD_2Em8rKsy z2uYKUq>k_6v_eSn55pAGy+pW(0mr=bW4%cxtvY3=Xd#J;n|?$O&1Ol0Fy60bK~*o^ zV5odUM?@C-EMefmbVKP2ac;Xop9%H9nbg&(`Wu!aN2bhzc9U+%OdXTxf9L6@d?BwI zB~cOy%xJaOOoi`pp{8=weBGGsXP!Si$;$wHBP5wltV5B6kTk2SWBPY?nTL5=Q<ego zml>WPALw{YSeeV6?IkN4U~UVS%aCa`n+ZjW9PCzWJu!h-Zqz)Z(UiRpGjpn&S<J~c znw)iYr1UOIsT}nSLvJje*#C?db$%jp<xt5S-tlzNz2B;`UudQQ=}snUTS%JNtbCaQ z&exYr9Z)()Lc+ON<W8+W!RTm{w$)4eZYDI!CmrqWu_j7l*8H-M=$ld7S@5>~myN0- zY2fE5Tlh?(*<oBUM9a?9dVAYo5rM4r%=G?8qSchqm2aeDueB<I(YqGJs2su@T~$K_ zKK-EBCY>8oGI?Oe)MPWaX_<=AF57a1s#Qq1@x=7dbUoJ;E1h6VFq_I+s4v|(xhe$W zMvcP{MQTTch{*m#nK`u)Cx1BX(bcWb)->zYR>usUY{eHGsfURZH^O?q*$#?VDGHyD z<W(YBQJj@7@>u(+A6cC3j|AUCMI$llB6}!u5OoVimgJ&$PpV2o@i2GUw<j`_0C0q$ za@)>~@<l&*YtO#TXxM`;E~Uy>jIC;w{<dz|_Psa!MXRExZRs#SQr2IROEbJ7J=Se> z{Da1nSikO(p<@!GU1_|jl(c`PzHlaS{$~a{4$G?H!!B^%E9J^iFvmj{Vj<dI#G7%R zm$-o6c2s_Nmm)2dFx{O{*QmF$N;~O^Wmd4c`jOVw2)!YWxVR4}beTANPq1pCvf``s z;t;#Kh2%SFjqWk<7U^&OPd_qExcdXJ`d}MVZ*=f=#}$LVR@xN(-N>xh>fU~y(KF?l zYr-SJB7<bn>q6;=ZK~cd@W?QM@(Z$*5XP9QvS(`dQfb_D>9#Cv!A|8)I(=jVsV;>* z)U0`tOLapvZfgi0K=P%V+oCFZF1R%}JGSn>JGwM<fK&?kbL5{)^twYe=j$0i&NQ-O z>a;#EY<@@g=d;IX=(!T=Zw}ZoAIi?cjZUc=Nx*_e<+Ev0J(f7=vLLcm5N9E;3Q(9F zg%(D`&pKF#>sbD)%r2#w-u2S+^wC?c#M%OYsN|`Qe|Va{(jbw9^nvQ5Alscb34CYd zooS>TFw}3y=cWL1hk=rtgMY2M63n{cW24>&M&pFyL3{BbANg4andc?R>U{B-vEmz3 zaVZK)VZwL2;4POBCkyq90QK2pQn{6sbX}QuNa=o#Wa3C}Udz(a)iSVVi25`<+Z2IH zSs}kS>qNIKucfiKS<AQoP~hN(V%g#>l`WIGEm^CbZFKUiQO%G+ZintWclN_xMnfXC zdKalw1zGQd!e*+uO04md3NFG`meQ5CWNuc%Bb9<OwXEustj!LrNdgO$8bPO-rEFu- zcasxW4Duv;7tDx#+Q7c+qUT)hkCWnEx)O&l<jiJj>uH^@{U-F?hEG@~SwrZy+rXn( zj>W#d`G5P8g&ik;53RgDuJvH5JyOwEC<=S8s$MGQR*DD16u5_E=~}qx6n=UUvFs;Y z9|EvEFfS`PM@QCjTkf8sJeUu^2Fb}wG(OJK(nw|ynT(Z3zz2Hra>jTBt$WYbj_Y5V z?frXx1rINu#Y_K+^DYqQ*0KLi*Nwpq9Bqs&LbST>=}RrBo;8{ml8F|FQT+u-mqZ=z z328?tTAoAGH;QQ)in+V_!W8}zP<pIJl5z?EmJay3&{}UYv{DV8=9mO)7`+nf8~>*6 zvja2}<xwQg!)4-&4Ds<^jN3}P+@^s_%_O+)?Qm11g2rmXH>{IvT-H6je6(hIyUx$y z{ehfn{mIJ(c<&)zoi_ll5F{=V4Y<id!uTCqq0D)zrH$x;r${LmcIpS-{-?4@mdhID zMZ=0URzPqr8h?u%^NjU+Kiz*ZgHn#@SSm(?`NNal5x#vP>smIw=&7(B4e1>(v4f`d zsF@OWiWYM$Ua$PAenq>+>U_hvGia4c$Hk90Ya{(U6a6UyBWDvL8Wk7`d2v|eG()-0 zaVoHKYSk&Bg+TNrRwa84{OfmFZD*_k^jtQZsKbmy0fRl2nm7G%A0<A$Vf^w-=`M58 z=N@JL2@O9xl2erhwU9McYsv#P?BcPOPL;#9jt*ez!qdNR{m1to<d+prC>Ii_2)DTu zy5K+Mbdn$YNVHCGlI4VdGFI5SpsqfsdpdF9GUVEGz{5sSd`PwBu59rt+|-6pvYKda z%c{IXiC)Hh{e<u?Q`r<QX|Cwe6%X5=XnE<}|Cl*8H9k5s8*UhvmL#$dc#+@z&^ENv zZW^c9^cqlGkP}?})e@pSkHu$Gytbn2lhIW@>S<)8?xi?bu2^BqExW~ioI7RdEppG6 z9u|YY8)2Pej2Desw**FNwsEMvzTk@vqaEWop!){K9tEo29~Lb>qWt-rc}5OpVwUrd z{`*cbiEE%fa#e4*jjy7$Clm^AziFQr!0ntRkv-u2E+^~ia^(WZRmQ1y<y?Nm7kiEH zJ(R{*<R>2^PpqgHt<W`zDE~El#73U|5+5=a8-)W0Fi1uvC^fZ?-y&T;!uszJ!F02F z<{EjjfA0aCiMXvTmNy3TmXFJ)M())RYGQ=$8f?Sa@Y4#`^m$Cidi2>jy`MyQzsSJ( zDCy~Eof9zKNJ8@+Azl6t`dkU+l*_>DicEBh{E{1EJ<Isph(-mt7m{bo>u`I}yK z(qM6zfx24v>oxrv6?P|wE?1A)Z-91|ihdYkE@YN20lfRyQnwHdMT|9{kP7}NUyJc+ zEq_0HOPbepdI$5<v=vTFUdB1v&)li~wV+`VH*D6}(&;?o6@%aMrCZIFZ)HGg8e{)q zg3V2GO*HcNmE`hUP#npBS_2x9Ao@(g3?FT87O7`5n;{|Oo>!wBWlw+4-}_w3{TAn! z!}${v7U3gNAJC;grf&aWB|THW?$&sPP}As0t%-KOKlCTo;QAd(?R<UH{ftxJH1%ha z`;*a~<-jjX^`)(f;5z<8;neZ}CbMwS%(YVooRJhrwl<CKEhC~UbS<xFw_Vm5s?c{d z08Tt*_4CFr*OKVo;tQit)&MJGDYVkWa$PnddBDKXo_O(qGS?Ol_3hAkDVaUqoisxb zcu!5z=4%bp>xXzojrhCDsqwkPyH@g6SPy7R#dEi)&n&`DOtIYW!jubSz7uktB=mU- zF&}Wp3!vPqkU;_g%F`w5kQO^>$Nnb%+Nt8DW9?6S@YMqPsy2r;V<$?u$KQ-ZIgyY1 za|+flr}fM9QYd-92)_Zyyq9^H2_HJFM<COmtuRn#G8tLgf9*&+KG6bSV&0n}JqP6z zQwfkNNd3mSbwS)>$7$0-zSRmI)lw%CaQ<xe`llMD+B$0rb+*Mqip^}R9h0G_>14Tx z&mzU;vrNheyT;9VCy4v6=!F#$qSKV<D3;XS<+@oy_3CTC#YdLmPqy=h3h7gsymc4U zzZdX&;|ITe<4wF9;A|30uj39})#fW~`)g2qEJ?{m_8aroc*5^Laq2AK#{Ee9VghHs zzVImu&u8ytp_4<3TX%q<$zD8F9GuiK>^cdV^66!xo5iHkZxfp;XohVf_jkmOM*#jD zJTgW-Q;0aQv;($lm_N{;Glz+2>Xp49e%PS7<bt|Fo3ur!dN!fldqw<iE58pASH^SD zEGRN-O6E;jPm_O>YKqmw2$}Y_K+V-#kohKBvzKscYZ*^)A#)DxoK%ymAX^NY9p6pv zzpqo4g*Mr!o_+wXPWJ9QF0ITQknQ6e?F6v-Q!aG+Y>%nKf0Z+rO_{h49%k~6S`B6R zi6#QT4JVX>95(YUXt0yG#vQpv=JpsMyPUa1DO_YvY(GU9zotJFgXS|??jGp%yK+|x z$SrN){(rI+(LMIoQ=6%R?4#qW0W@OQ#O)*GEQVm_F65q@swM@>ln`SLiS7-|Be5Di z!Me|_8I}opHXOp6Aa-!7`f?4eyA(^V2EPtTr?yEH1Hvm4Q;qAv(k`ySJMzzGB6}j! zBnYq#(=O4X9&#aa-ZPG$=SCl35KahL(>0F8Y5ujKyS+BmPN!KVvJ-15n%-)667pws zu+&eHTs72~Be>-OIJa`6-%z(b;ry!`-L`S!y9a%ZxHsB{Z5e`78DP{B`Q%}(o56t9 zb7a^9`5Vn?4I(J3rfwz?&fP%y`Na7f_1w%!$38M9f1~6V@|FL=TaS+Ht5c9w{hGJ< z-OYSW{zUv$B-L}`i!Q3_p0ZvH=UtTb-GvkGL8UoF<ty5fEA*P<?3FqiwS3*pzX)%< zbh5QD`vT@AC9da#iU;I}e=8UF3udJVvrU1tpHrGC<Zg<<S4-o2rozyVZIy};DWvvm z6h$cSaw?7ZMey<zJ)O>cy;S4#3=<cwM)5V)b-Kp76WHV~QjYdmS{ruRX9O^lB!0zq z9^uVgP3el`%(GA&o|-tcZTS7yiME@gfi>K1VPN(Zv0t60jgxw~7Pd`=U<&u^a>Cmn z{?{U+aT6+CK{B7CgVd6J)9B&X$sK1DuZsx!Hz%IoQ|DI<mCO(sp5vA7;}n}g2gwso zKM6)pIDXF{m%F0%9>|w(>Ia{R@NZPTiI!NvB<!Xi@YFGIAsR7tmuF%8cCEN~z^VjV z-c99-NpPu=prK5*w+h=fC0O#3YzGLcylJysrM*3@9DCgF7rESqaBa50X9a0-fIwJ5 zDaz5{_|yF>jdEfcxSILel<5Wl;Tvf^p`3FN@+fgMpP`h{)rrO;zd2;Pu&JUmia*wq z$9zYtcaOhr9UE(&_&X1n6T;`UGcJ|N{1(98#<*bmRCo-0<E0>e6LJ4E^bMPAU!-+y z6IE{wZErUfGgnoQkk$uHwLJv8T1M`8$Q<pa$h&#AZUEP7a>H~&>5a(-1~g+Ue<&OY zL*%F563?%K{<To%XHeOLG+qJgzb8a_zjo^ae65A{S_LqD5p$-6`r=76p@yITZ+PIo zdi!1Jhi-DTtEhfH<*b*)&_*-+i;~|%<re_fFGL+Zuva>t+(zV2(HvJ&x<d@974$Dh z7(Wb{;|D<LWsUJ1{su#mM$FjoIKJs$C-0Svw1srGUC`jAOb_HvD97gV$DK$M$M=rE zs>QBoaWDO#=N}hcI0oP2Da_k>NtS@+2Vu)H#K@Ky<3jp7QxkbXeQ=KYV;y}$7pp6z zHeVF@6cO^H#z@1eejew?6_M9Z%w~{lUW`;CoLUEP|G}wauE<MEaeD*tuc>;&912aJ z=(C*Giqm&#ptFfumpHiM5qp(6SRBh5c#hRdsCW2$5{yJJRbG76r*5(-OLp-pY1s+s z%A*Xgg9>pT9jaD4S4#r4fx1SX;S1=@IK?37U!iS)?5F%%qH%|<QCI=_e$Y6XEzW&M zi4PtRvp~+BkR@JLAFDxiQ>A_zRh4rDQO_o(?sEnylNPoUi96Jc6O-&ORDYCzDGTnu zB4NE2?8#R`J4CT@!0&8i*o%<Wt`Rd#t}>+_w4vV^#C3Mj7uksWc9J{#$0N94KEw&C zlUwgrKUge`Ux19=p9)+D%*>cFq9BJR1rJE5xJl+oCI31Pd@7?V14#b@a_J%s-~li# zTk{YBWT`bDjp9FjG(H~^B+Vl|{HVBU1$8LMAXOc~MlVSe{FC%0BBlOD2KByr87$Ym zhTRS4(I#<E7ji&0<e#gjd5U;?9-VZClA($0xkQUUB0rN(3D=$&#t0jBNW97c_XFsz zRAr%)I_-c&Eu0)Z!Y{GpylUs9@RS2<Iq|p27dcZ-Y~-^-xaX$mgRd-8DJp)Vid_V2 z9tOXa(K<4SAu<Z8pbXsr=W}VSMbe9!)S?ZO=dKcVKbq9Oj;;4rJ#vv<D}>+Y2tQ=t z{@Q}iRd7S7@TeO~)s=R(puZ<n8Q#>7m*EOu(ybWsOItANDjlo>c5Gvu*8&56(UVUI zw|^yXS|&eiM%Y_Tep3qQ)e*KV!8G4egMu+JpXsl}oYyF+ApUM_DsLX{wG6fG0MeK1 zekzCceQB|4QHcj(M;lo+ree$`+Y2TVal(w1qC_cJPebQdsQW<dLWErA#;yG*(mBXY z{K0$oNbz>oKb40b-^tsNkIeQEuDvJ8IwN6wiKA>4hdRNA!`N>zW$X}qx{Na7K+>9k z!Y!$JcJjtSN-LS`WreowoeVt%I>;3V{wnjeV6Uap6b7E$A)2@Z&;BJ6ZAEViB-{+* zB}e6%LdunE0NzDnwi2w<z*qvs?H-VIkG6sYJw8VBOc$l|$fv$ZRkw*o+sWV9@T4B$ z{YSvPo~&8{+{84`UIey;s%g4_F@g8s9v<<OkhvIG{#g6xGRWW|b?<D#?=WIQ9{TY+ zey;)b8JK)<jZnoE(Dp*~x5SGY_~vxXcD>T*%#??xRHu3>bfqxOM{Z!k5A!8dFXz7s zBK$EB{@o#SIWNAtMcflDdvhKj>Z&enBSUY1q!X0(?S!ioWTApIt6brOk%OzJh8j`M z)yaD)@S$7sbH6ZyDCqP}g|H6W|3lhs1HbE*3~okyzf1SuBm9@Fa9l!J`V5QOK+dGY zt073#Lp&J|oOwxBeuAj`C?-<zVNLSS8<Iy&MAuf*uR!Ea6k-<+DF;zaF=+UMrD*}# zoWo_0!3CRmX_bH(1KIQ)nEaykSO})7DSueV+BImj6ES`+WOk7lGlRRi8VPIW>pMXi zN<z*i9O7fQ7OHBvyepq&+(16xS`1Z7r^*FU4sg>hK{QU7lPV<Q^7^gfmW$#WFQnHl z<IQgs_I+s08?1#wSz`oGGb7Y>5^LtD-lUU8PVp~fpqbpsswAW|Os2>Njy?v9G1bGH zn8`fF!`IM~DcQAEXsn(*s}|93SD06mQwG(759G)=aCIn@_!-f;4HRuc7rMgc$)p{L z(hcqCz0>0R%ZV-{=!rNaL>Fn~K$f1w@F&o?wpPR#<Q)p0PKEp|`0@hq{Wj>#Hn6@x zbA$!8<WoGJ!X^%+xjP6)P(;6<u(NE+Hxbd$=bOxi3Yrn4Qv6X2zL}sdI4>yelUpVV z<|j!4PfHG?qW_}6FP=idF5;hFVfk)lriVDJRjf^rTHnJiUz8UgAVwkT{Bz{{W*`k9 zZk<3JkEjDZP)3mOtr<G~B<HFMxeiMMIpBCRfK_4z7crr;D%}KHov&DHhu+z$cxQ>s z-l6<Hlf3eY`jw1aauj&>5ef`|$G!r@7X;&Na14aT0P=Y?MCPOjFC}dHPJFf<(Ig<= zuCPr8@>B^O?PTR|fMaanxjt~$Qo+syXqyP2Lr~dSMrj08@}81*8s6}kl&M6{hZ7!O zBKUpev-TsaD|kJ-p_RMfH8TL$54cB(+R924G^DtfDzq(^zK<1mI*3RA;tw&QO)`-^ zLxkN{1?q{{@0T1pDk*4GGtSFm0m9!)%Iiv!U<D496U~@#={fAiC&D|L*eaSR3+C$D z6CAt5Tl=Be1VDck;B^z5OU8)tV8jL0mH{GdO!>Y9o>->}N+wlxs*N-#-7s)gAI_W) ztwzCH{>aS`c;iii`jO(*eL`EN2<=9?*Amtaz{@GflpJbV2fKDap37K4n_)*W^5+5^ zpDz@Hu-^fE-(~3a7J6j~v^tl<OM_K<<T>pKX#>${9|6@6Nv|N6PVtEOkZ~S3k_Kd1 z0ZnT$*LUJG#mZ+VM8Vav`z4}X_LAluSbdQwE}YnxB69hquD248*-N9ROI9<~)0?Dl z0qnC?F@H1Z`girQ#b|mc*qnq<IU#SVBxkn~j?A9QX+e&6h|;{^4R-heAF$&V_I5RX zZvqeq)j`*Z&GXd<6XBR`>VsA2Xe_4Bpp>zJTc_cRy<kiP7<K_>=)u?W5P_wN*N9kT ziN@WLi;v;EJK&gA$n}TN&Uw(?|DeJk&3*_TyFfg-4yNoB-=M<=Y|Q^Hgu7CAH$s9g zO2$oi>kRVP2c(9LUfV{<IVMS{MMm!M<gRcLhF=c`ZEgbTZunILss0aDc%Zlem!pv) z|1c?4M{W8<yt<7*WQmnsSag8+3Mez16u()ndSEY2zXk>Q%U2YlbG%elchSqKc>I5W ze<H+)lHq2Eaz5|JOoSj8hP%K+zSxCtAo>C;m=CPl07U8IyDW&@IIK7l9@~Y*lF%2H z_+JItEE+(Buy;GS>MfY(48Q&b<+>m<lhiulh!0I%{0lxf0M6BfjV>d1)<UKspphlC zLc+*=2#xEL7Hhz<_EIYzRL50adj@sektfR`%{EHKZrItL{P_?v?*&@!NwAX0f=3Wi z7cc7;oU$B~4S<UpfX_HSV~1>Kjhe@lXw6b)Efn!@%2c(=qi-ZT><IIJiG}TW*ekKi zxJ*MTwkuSY{gfCafjjofj!KD#B#Ncgs4a-C-U>Q&1Izm5jo+YCd-&-~;oObF;bv&t zLUr#D==}`)Sr0%%_}(e}^BsaR2LH4lp4fzU_!3W!<BKZEOfJy932`=rG|7<M8UB3) z3PusE0Xu7l5Z{X<@55sTfJY~Ue?n@Ep;a#c*IMxPK@DR|sAL^E@fMWJlw&s_<+ySv z6q@IWF5U-e7g79B_#K7(9Yh|{NQGU<*9A)FKS<j)KCu>l_*`{vEi{e+d2fLHRJl(+ z7F{dJ3{$;{6|r08elHb~Ez&bfk=-99b`^kqh=klKw_GIw+?Dr!O4?rmm1^lxE2505 zSpO4s%v066|C>9-Y4enC)`Ls)1hG!gmob5<HgsaKD)0h0?;&=#4sbq&8@mD~D#UOQ zzkeQ{n!sBU2$y4ljs&vZdQh(saor77t%aD|;Y1f`x((vcg!`^Q{<|%)`~?R^Vw*Hz zUOh5%5wy_@@c0A1{6bqK1+Q$U+zEklg^GtEP~2i=8w(2BN|0+qW3iOnYtZy@5<L#~ zTuicCgEa0@Pd|mc^bw?&!!6U4xhat6z`p@QFy*}h-jB~eE8Q8Yeq18T2bC{g$d_QU zoy*~;#ZojL?AMnr`K`b@B`v**JXHFz1<!7lUI`*>IwVicMM<BOS`sM50Xug<rDYE6 zql%tbgQtoFrYpf&3zdsBz@m$o+arKD6F2t;nwKGY`au0lxOEOtS%)~60O$3|l=~pt zgAn-un)4F6cpk=Opqn?c@-g6Y1c`nl6_60`A(eO~+>(jdUWF74Knn+%Aoa8oY@I>X zoChuHQVBgFMYp0t40aa7=X$`@G4eBaD5H*4CWMymAkD3XckjgC>mtY33hl4Le}2nF zNzn4AK+`JlW|lIy1AjGJ7DK>(%@DsGR^F<Ry%Wp#&4Ug<mHo$rP7F&MzAEpWm4@Ui zR7a&Y#<-VE`Z5L~xXV|>qYI3cZJF@fMd}Ba)r;)#xEL|&56t-}Fn$08ELSKl0?*cC zIZJ`_5^RMYu<Je?paay^z$L-Jf?3GNW+34qsplQ2bDPlg8dC6~IXB_o&7kp8<jf3k z%ROXpTsCt7Lb;-R^$0$(1exfCa9u#|2h}bhml;6&A5ziz5UCJj%!WRdDJ;f8cN@s+ zBiOcp9Kr!(-jQ6+Lhp8xRxgBev_a}in4BkK2f>@)%HGC7hBJZfJHdq8s#TW2uRdAT zCG140nEh0BSVzXFRU9z}55>v%?17>(WT78a|Jlj@W+^Ns(zrN`G)MO04xDW*pR_<# zg^D$Ekd2R3+2=5`P1x%?$<~v2#Dw4%9~W+x>tOh}5mq#S_y54ce&PKi5PbkwbiyW% zfVcpDR1CahkW6lXrsD+H6iCM%K9&IQss`u#A}=n2dtV}eyTUFWslBWi<-&gXaHBtb zG6*>G4ElN#eYqVvQ%zlT7<zvg_`DNhausK^pd%Fkvlc9gBi(NU`%+2w1EIUiNb|>` z)hUoV7<Qc_;n85X8fj?=v@8{8ZwD#i>Y_!!!>jTey%-WMS#GZuUzH}sC`;t{fVN`u zJ!r*TxyF5UVYcjStwOR*cCJ%x_Mfb^0&2CDC*~2qA5tg_5IZZ?*B$uYN_CWttY!j> zTqV4D06%hBmURy|sZeX&#}~c9!tUdN9?-0>xV#s3WCPzrVL>`zzaK3)0G@InuH6ki zKL#IK2WQlRhs}^H#US|sVslP;`wBA9Bo`VW;ge9v8QAGAK$(EtG>DTAAkTDaQ5rPM z0y4M)onNLrItNO*f&Wt}2Tq~q8o;Riq;W&2$DYK03K^BcY8W=@l^VA~i_E3Rogrxl z7PuaiVd|7{AjeHnZHRvcrP0^a_dTUM`AWYI%<75a+FeNgRc>_{vz;NAqDoGK>~n;A zvRbwX2TlFuf1QX0s}xN-gqgL<B3B@IsamyP-m(WP91xBH_@V}>rU&jBrXE^^kKe{# zgy8|HVEIMdp$=X=i0{^hOXGmA6-1UV$lpNhbcK|8aHBO$9{^X1;Ad6frPD~+7gfz| zM7m4f?u)c2LBlWbdof@=3qGBV>}-c}-KoRBAkKX_>N7;=D_i$KURSYk3gmf&s6POf zEF?M7p(z<kI|7yDAj|8alI!w}T<Afqq{tNdNWyNd1Jh4pm-YklcE#Kf{P}BX%b1$1 zB{hsx^;D_#^pt<1prTod!MS+pUHRlzW&8|z6jvpu$~^+X(g^wF9YXgU#j0?E=PBjb zB;Yfkdi6r#j;TLB6zzJ5`M61!_F-o`RB8Y}eij3a@irVdyc&O>3E$4ce@sGc^8s6Z z;sp{YK0<VqffjuD#Tc|1fewF$$G(B0^+;5Qdixb*JXHQ=HNxTnd&l9Ei^26VaN9-L zmkq~WqksTBZ4#;FLyTh8tCvu0r8>(G8dy&tlAymd(i0shu>yS@3EA!?Xy-x?{goOI zp<kaQF1nD3qgoXX7PMfy&HzRU%3bmJf|WA&S=cE}>B@4|oC?*h1f?MxO1Y_6Jc{2D z%4f7Fr=OB*-d7DSmbcsi#7E@IB}kQ>;?P-w?gHhdR50tZ>PVH6_(W}eSo~)ZwzEv~ z<R0d;T=lX78{Uh>Pht@XfUX0+d^`O43O?&E)T9p}v4q^ez^CKHoNr*3Eix|`Dw_$_ zU4+wf!S^$flg(Jyf5_Pj^5ON!s&-r(LCliDlw0uK$IuHecu66-#|(}Dh;OxE*O%(x z256m=`s;3J)?6gg5)yqvZHyp7DjKyC+9M#Or9$<?DwB&)n^0oHgq(s@DVx9nGQKty zh|pD;r{i;_GMxihx|<X<R3GbB@;a5P?t=uLLiit$5u_l5t27$rif|R4EDw|8uOG?( z4U_2EDcVv94#vs?JLp4z>Oj5fL9m*?T|!Z)hxbb~S7OPZl)Y!MEvvEd9IToF_zN(A z1z%W;2Q)xudhvTdk>LBlrCmg60{A{0`6pwvw?OPgaB@0mq=X+n!s9m}*$Vm6bqM<> zrqV+Ua>27D@CGjE9}S=UNE%)Yhjb7n-f-U=%m9TCH>o~lK#Pswe;NP#TGVnj^mi+Y ztb?3`h&!)B%2+JsJe0CmnywE$IjS_>4+b!C_IrStrRu4{gYU@WbFhHJ(xbc8VzyE+ zOI1w(r+k&g<3QmpML$Q?s;xLYTNU<A-mwGk|0Lh?1n#p`IG!Xdl_;<*$Qf1zd{q~L zYR&D^-?{3u%O#^)*jy`R+A=I`26pN+mX?QyRbtoPLow6v#SPG%5BS}=2(%M0@gctV z2SY9+Ni(4ORESQ4D{p{>6>zdQVB?95KTzxoMsl0g>1K%VJ@~K*?m7aRUxYJWp=Wl$ z^8e7^8{no=ylDn3ey6(90KKI^t^Yxa7NX%QNal*>Z-Ms56QBRf>23JdbI>7k*-i_n z?USPLBpAxao>c%tv(&j9ynd$Q?J%~zUV1B6eIZ71>y&DKI6%CjyfYW{?NWrFR}Y6N zN}N;;N_oiu_Nq_LmOypW6l1Fi>0OFgQ+RW|GV&gl@J+R4k4)!~8d)oO*s0!kO;KQk zEmf<jYcTyi`1$*ohd<PbVWkaF!CCxG3G6cqNWus+NZ_=5<TelFRY7ib&`>h?<O;kt z7bw<5-fdJq@kCYu>Mm16>mq170F!5cM;^iTH;Dhm!{%+M!9n;%BXE8>41QLP%As5` znDQ7p>qjKSK#vIMi#?EY3Nbth%3_0CFF@}Ia+ev9p1Gp^7O0(#mG%LCZ`CK*fcAIA zW@FsLOI9FP>rKel)T?4LaErgn13STNOQp9N=5t?>=cT&gs?gqx9V06|RzM5qDC}4S z{HG!|5hguXZVkshl2r2#%Bf!JRc9o^7wSqx5j~+!DOJ1JU>}@u+8!*v0o+xGRsDpl zLhymr@HH7u&mugn0*<#KTi$?x9GXai;;w_om&4TnnAiuOaZ%-%B4C7ytcP^FgOwBT zPAZs~1ACt$5U;@zN|bRKUeE)s-3Q-Rs^YC+dut%I26}pj(3JvVjl@5vp@C###VzQd z4K(W}6h~7K1E7rea&8V-y#nJxU^yErm<O1JD8p9a-g&b4dD!S>d8vUqU<kWqri$JV zmPRUj^RRc#is7v)^-hH|75hA0LCygk7ATH<LKLNnk)QCVlS)@I@GeyK;IQH$N$t@p zxq3{!`=Z>pObx}UaZG&x!g~U-)Gc7sbFAPqq_V-|Aej6EcUnxaz78zsBNqF?R$ExQ z4BGq{jMahTW`Wys;X10i14RDU!I`+_oPK}&zR&%6ii|?p$F3wx6SB0ZY*`{wlaj46 zWtkA7=2xV#Zy^=3MMfc0RHTw6AwqU~T9qY=5%qlT?c4P`f5N%0bFS<4KJWL5t)mkS zl=53By^c)9_-;0-k5a-96T@o#z*w@b6mCV4gNt~m6WO~^Zu<xgZ<RY|VQPZjq<wHY zOz-$%xT;Sq;-T4sf*WjJsw*wT{Y!cOp4d7-%vp$zyrfl;vT3-Ehl=J|y7UFy%v^l% zXS3(x)2C^LgKTI|<Bl?UOm(@!t-RFKZn$8cirtl}T(wqF-Uial(`c?0JG_F5GNw1J z>5v;=)=L+dz_nfZ+c$jZ8=>tjy8cA*5n{thNKwV)+fW=U6Sc|}PZTJX*kSmB8yRl| zo3ik4ui;l0{3x7+zvY*;q#}(v{Ukmk(SREAO~KxIr1k{4a)Njs($7Ci9P&u^e$w+Z zZ}27|H-wWuDKb`?Zi1Mr7j+6u=Ia%lhPFAxAQ6(>*;#+sFh@7D8o!>y9UXAaNnyAR zHF>h^OH$3$u`Drjj4mvRKMm&EWVXx<Tfd_VuE_%~RKJe>c&aW7;aj5A)_ag=h&s4} z(Cg~W0m^<4+7cf~Gh#(v%<U>`eA~3jk{3N}-uM@{zQT57^UBL2NAlGD=nrqf*Fivu zNRNZJfpS%l@@L-`NKw`|p^7k~SAxA>VB4dx*b_TXCV}yyPbTq6rHL&ah?gB+6AJ_E zo<nYwgH0l7ZK@w|f;@;+1|^W<Xz?+Kw3{Zr^d{94NYNX3XQWqo8D84xJx_%m&Pwld zurGoyT?^krbVnI}^_Xer;ej`W+j+G9F{`hT2W-^Duj1-h-P~F};XdnE$I@S-j(wO> zf8@HEYMlA(R&<{;ce$t@{{^M(S1<aJ&xPtyYb9d}?UIa}f6%@oT0$o5`le=AW4<}A zIbjj^oyo{aUcN{CTEp*-L7VNwekZW~SFBhML!6{DQX;=gpRdZqo9NatQg{eoP_flw z803vFnUFAhS+<*8c}?ftBnC~w_bzeO$8ML2-FWalO3v-oOFlwkdTLfDkR?-O-g=VC zc=>OndkD~vP?Vwhk_UChdP(W<DMis<fI-K^!woRJK$qAKj9i%Qdi?6HIQ9SqIr8e( z$Sg;F*<TjU*PZDnUX5Vh7JPIts`Fv3)}fSKnt6eT*wZe9c!^g15G#EztFx;h@}=5- zsB&=<4KoIV8XCiR{NJp0j4qcmpYZ0O>3n7_9kGk+{Do67-~3q~>LXN%4WmW<B6!(N zdd8ET1v0WkiQJ7c^2qc>_*x&BFc`wTal3LzE0FDc$+ID>_bHO%BlcV(CO^=Cvt;aj zJp3Rjsn%2;AZhzGYCIX#79EZt-mmy~d-C@M{GbU8rfc->f$=9zi$!)xy>cQAJkH7B z9nfU2vi>mn869^3kIfK{Ur>)TeCjYX*M<go%GEKtPxHm(3|bk$Z%{chjy+C80~_g< zZX$0b?b4S|XhR1Lk?}9o@CC5_qng@5x#mo>f<XT@tw|S})od2kS$$#iBActm@*WX% zM>sdK7G=5IGez!gE4pQ39wI_r;S&}8ZOG8$QY0zg7NCu<iJ2vSGzH?C@dzJGF2Hpw zw0IP$JkI(>k>;m-Spqp$jNIeN@nBrDjTjErOxsF=OErV`lH_No?Egsi8y+~G<bFdb z0{T5yY9ByMuI6hd)O6HrxCnX2(TY9r{Ed2U7>r#>;VhoIL+sSYyCwfV8<k$7x=k|Y zt?uCgQ8<G}p5UWGW$R+5dx|EQGrjGiA(6%o;(NwWm&Zb3>bNr8jA-0Da?+K?XT$bq zG|N*y3}ikx)P!obJh9nv6xaKeo?FXbbN>AjcL<i}C7%|65BZ5FcHmVdT73Y+2zhL| zVmk`C)suc0+pGe+yV%ATn}$Q&CS=~095Cf}zNGtN-a>O9_M;V>TlO9v7)tztl@}qz zlxoa3l8<rt-WqZRi(TW$zs{&m!YfzhYZ2J))(l98TLUy>lVN=bzP%g%j-fhRfC1Fu zDjqydWcI{ArV969)X|)MOlcAF)G-BO0?>Ug_`<KEE8*8lQJFW>HVXEXZlA=j2GH1z zLhVbn3-Ocg)cXus=0jtDLdtV$UnfodnX;Aoma{hH&AqI7^DTAVYTo5KPrArEkCOpS zyrvVr=pj~^fl0Agd<x8bWv00@&ln*_TwkKku`uNb&ixagb%j1TD4`lIUgjB&<U%L@ zIFJ~OM>AHE3`5-b2Z_8+uKJNZ-!$v~B+5*97eL-j7CCmL;<7AeU~-*U6+)(`#v}zQ z%{51k!=WMYa~sU?Wi^iQo~di@;7yFzTH%gcgwHOtGM2S1mUg?<(r@C<BlU1A5%Gth zBlxU`=;jXAl7uM%ws94|7DJzm6+Tm`<406Jnnrt*y5-crFIo4N<_Dp*{_LwWv#4Ni zN9ck^^G~7b$aQ>1DBqFBqdLpoKR7K!6K9CV)-WqyyjccX7a5@?KYvIItoUC-9kU^F zHU1uf7n*^#3MJ)$cDxwfo2;&5lV*^i)w02h7&oE<H&Wk?be=)bEzP&zNybk&??G(N z32a5K*-6w0)@G!0F3jt$`I!KbJv1fJFzPnUj(`MPe%}FZH>wuJxat(Icfji}ihd_i zpkV2BQZ%UMUFGIXb@)herGiKJanFCyr!3ZjpPMb&_!OR+Pv^A}9>Mh4dNhAdi!X^R zjHGe)WMD1rRgD^#ux!Np)Ux0cIvXec$x$ue$m@pisH^;QgV5@@WjJCkLao7@uZVt* zu+d(w+C%Ki<ZVV`Vvyw<=sXjTJcth?I8RYg9QYK8Rfv>Vv)JLpJXD5`BhSlFg&ldc z9Rfy@A8R!8?8(1dNCyWpxu5jxP5!GCQMJ%(JDg92lP{E~JHfEEMh%CpwuA*i`z|7J z3`82y7UgrPGmoEwf4L(9)6m!je2aqSc+k_f^5A9l!U7TP$M5ao)Bi+^t5^m`jb6;E zo{z4hNwwVRFum6fEe)m5k{~ah+Ds-XjnrlePF&3@Qn}YxrtP67%-~D9tI2zL`*QaF z4u5)A+$LiFXtZFKn2?R#GlgDHxHnw3cOV@f$UgPta~R6`2@X~`@FLDE!yavL%34@G zQ5sjlPR`bMC9;h?XF;s)qFPhZ%LvBwAcbu;Q~Qu8N@DsG({r+Q8<LkKLY{&1XWVcE zT(&9EAz)musDHqjgXFz8JZcbrLt(B9J@W|re_=gb@xgmyS1#&vg)3bV&8GQY(xXuI z+AJ)-vtC);sxR_2-~}ygwTaEP5d%$F;bVUL27Q$#qmR%V<KS>QjUGp$^;qOd+%}RO zn<+d6dwW(jSjhF;s63I|?`6GT^PVR}QU|eCmBrrTz*gM;s<;GDH&hn>2MKxd-7~Uf zF<NOvj5}eI2e|S&w(W%DJitFy#@~kiBY2X8-%p7n9Y{<H8f-`&pToTgiHK3o6Y|7O z@z*C??9jshAZ43yx(;6Mc=;Acw^Rz|1AC~1O^3SYq-Z?s&5`lF!0Iebx{r+$SlBEa zoh|(CpaOkSIS^U(Vsf=Cs8cumBWCSqdrEosJy~tZ$1O$TA2xQU7-`GC-{TWL(0m`+ zkV`jc@#BYd%@C5&jUD)mNA6?xHNwq^x3{Ms*YFqZ)IHfe$cb5h<pbA<n`R>AmVB^8 z__^YhH$>k${J~NVIS-H}ebdNo4|Jj*DU;~MM;xAn^Lyc^E%#FeIVMANB)?G$ITJ;; z3MrdV@DJEKALqV@_wAHJ)i7#@l3WYzO3=G!5Wh|MCV|Zz)L}WSdqDP$gVJPWm?fA> zl0N`&DC*Y+p7&(?^Ra~&YvqcA4vVb&C~UfTZ;gK6$Tn=3KYP-U0`bpymLqslfP~rH zBMK!Ku@J2=UBvD`;foEKdwVG=>HJXKG6kPnk$uD1!a*?UH2Za#9Mhj)dr6n?;zumh zWiPn9N(UH-?@nTxgUCN9o&FN;?eU|B;^PZ^a+tid6hyl8+e+-5QMcd7;m>G-0UY1i zlCj18dxCB%nzI`gmh!4%XrSDv3KqDa?pl~>h9in#=r%I-7K}WljK2*g{&-vlbV?H6 zwu8YW^uQG!&L{R}U>c>oGXytdWy~*NY>G#G$5CfkRu)dOWad-wc7M^i1htM9f7zoS zPg#7TJRL|EYekbv>rKTgLs=EXQ`e)3KUkQf93RfCN_a0j7X3jSQ|T9qwwW;043q7c Q)*8Hv*qfH;RsUcA1BAud=l}o! literal 0 HcmV?d00001 diff --git a/Lib/test/audit-tests.py b/Lib/test/audit-tests.py index e7f8a945..9504829e 100644 --- a/Lib/test/audit-tests.py +++ b/Lib/test/audit-tests.py @@ -419,6 +419,69 @@ def test_sys_getframe(): sys._getframe() +def test_sys_getframemodulename(): + import sys + + def hook(event, args): + if event.startswith("sys."): + print(event, *args) + + sys.addaudithook(hook) + sys._getframemodulename() + + +def test_threading(): + import _thread + + def hook(event, args): + if event.startswith(("_thread.", "cpython.PyThreadState", "test.")): + print(event, args) + + sys.addaudithook(hook) + + lock = _thread.allocate_lock() + lock.acquire() + + class test_func: + def __repr__(self): return "<test_func>" + def __call__(self): + sys.audit("test.test_func") + lock.release() + + i = _thread.start_new_thread(test_func(), ()) + lock.acquire() + + +def test_threading_abort(): + # Ensures that aborting PyThreadState_New raises the correct exception + import _thread + + class ThreadNewAbortError(Exception): + pass + + def hook(event, args): + if event == "cpython.PyThreadState_New": + raise ThreadNewAbortError() + + sys.addaudithook(hook) + + try: + _thread.start_new_thread(lambda: None, ()) + except ThreadNewAbortError: + # Other exceptions are raised and the test will fail + pass + + +def test_wmi_exec_query(): + import _wmi + + def hook(event, args): + if event.startswith("_wmi."): + print(event, args[0]) + + sys.addaudithook(hook) + _wmi.exec_query("SELECT * FROM Win32_OperatingSystem") + def test_syslog(): import syslog @@ -451,6 +514,17 @@ def test_not_in_gc(): assert hook not in o +def test_sys_monitoring_register_callback(): + import sys + + def hook(event, args): + if event.startswith("sys.monitoring"): + print(event, args) + + sys.addaudithook(hook) + sys.monitoring.register_callback(1, 1, None) + + if __name__ == "__main__": from test.support import suppress_msvcrt_asserts diff --git a/Lib/test/bisect_cmd.py b/Lib/test/bisect_cmd.py index 0bdd7a43..5cb804bd 100755 --- a/Lib/test/bisect_cmd.py +++ b/Lib/test/bisect_cmd.py @@ -109,9 +109,10 @@ def parse_args(): def main(): args = parse_args() - if '-w' in args.test_args or '--verbose2' in args.test_args: - print("WARNING: -w/--verbose2 option should not be used to bisect!") - print() + for opt in ('-w', '--rerun', '--verbose2'): + if opt in args.test_args: + print(f"WARNING: {opt} option should not be used to bisect!") + print() if args.input: with open(args.input) as fp: diff --git a/Lib/test/clinic.test b/Lib/test/clinic.test.c similarity index 69% rename from Lib/test/clinic.test rename to Lib/test/clinic.test.c index 0abadbe7..04227e41 100644 --- a/Lib/test/clinic.test +++ b/Lib/test/clinic.test.c @@ -3,6 +3,10 @@ output preset block [clinic start generated code]*/ /*[clinic end generated code: output=da39a3ee5e6b4b0d input=3c81ac2402d06a8b]*/ +/*[clinic input] +class Test "TestObj *" "TestType" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=fc7e50384d12b83f]*/ /*[clinic input] test_object_converter @@ -61,6 +65,58 @@ test_object_converter_impl(PyObject *module, PyObject *a, PyObject *b, /*[clinic end generated code: output=886f4f9b598726b6 input=005e6a8a711a869b]*/ +/*[clinic input] +cloned = test_object_converter +Check the clone feature. +[clinic start generated code]*/ + +PyDoc_STRVAR(cloned__doc__, +"cloned($module, a, b, c, d, /)\n" +"--\n" +"\n" +"Check the clone feature."); + +#define CLONED_METHODDEF \ + {"cloned", _PyCFunction_CAST(cloned), METH_FASTCALL, cloned__doc__}, + +static PyObject * +cloned_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c, + PyUnicode_Object *d); + +static PyObject * +cloned(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *a; + PyObject *b; + PyObject *c; + PyUnicode_Object *d; + + if (!_PyArg_CheckPositional("cloned", nargs, 4, 4)) { + goto exit; + } + a = args[0]; + if (!PyUnicode_FSConverter(args[1], &b)) { + goto exit; + } + if (!PyUnicode_Check(args[2])) { + _PyArg_BadArgument("cloned", "argument 3", "str", args[2]); + goto exit; + } + c = args[2]; + d = (PyUnicode_Object *)args[3]; + return_value = cloned_impl(module, a, b, c, d); + +exit: + return return_value; +} + +static PyObject * +cloned_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c, + PyUnicode_Object *d) +/*[clinic end generated code: output=026b483e27c38065 input=0543614019d6fcc7]*/ + + /*[clinic input] test_object_converter_one_arg @@ -1808,17 +1864,11 @@ test_Py_UNICODE_converter(PyObject *module, PyObject *const *args, Py_ssize_t na exit: /* Cleanup for a */ - #if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *)a); - #endif /* USE_UNICODE_WCHAR_CACHE */ /* Cleanup for b */ - #if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *)b); - #endif /* USE_UNICODE_WCHAR_CACHE */ /* Cleanup for c */ - #if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *)c); - #endif /* USE_UNICODE_WCHAR_CACHE */ return return_value; } @@ -1828,7 +1878,7 @@ test_Py_UNICODE_converter_impl(PyObject *module, const Py_UNICODE *a, const Py_UNICODE *b, const Py_UNICODE *c, const Py_UNICODE *d, Py_ssize_t d_length, const Py_UNICODE *e, Py_ssize_t e_length) -/*[clinic end generated code: output=9d41b3a38a0f6f2f input=064a3b68ad7f04b0]*/ +/*[clinic end generated code: output=9f34a249b3071fdd input=064a3b68ad7f04b0]*/ /*[clinic input] @@ -1925,8 +1975,31 @@ static PyObject * test_keywords(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), &_Py_ID(b), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"a", "b", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_keywords", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_keywords", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject *a; PyObject *b; @@ -1945,7 +2018,7 @@ exit: static PyObject * test_keywords_impl(PyObject *module, PyObject *a, PyObject *b) -/*[clinic end generated code: output=c03a52cfca192d3b input=0d3484844749c05b]*/ +/*[clinic end generated code: output=73d46a9ae3320f96 input=0d3484844749c05b]*/ /*[clinic input] @@ -1972,8 +2045,31 @@ static PyObject * test_keywords_kwonly(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), &_Py_ID(b), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"a", "b", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_keywords_kwonly", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_keywords_kwonly", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject *a; PyObject *b; @@ -1992,7 +2088,7 @@ exit: static PyObject * test_keywords_kwonly_impl(PyObject *module, PyObject *a, PyObject *b) -/*[clinic end generated code: output=4704adcb6c7df928 input=384adc78bfa0bff7]*/ +/*[clinic end generated code: output=c9f02a41f425897d input=384adc78bfa0bff7]*/ /*[clinic input] @@ -2020,8 +2116,31 @@ static PyObject * test_keywords_opt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), &_Py_ID(b), &_Py_ID(c), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"a", "b", "c", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_keywords_opt", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_keywords_opt", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *a; @@ -2053,7 +2172,7 @@ exit: static PyObject * test_keywords_opt_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c) -/*[clinic end generated code: output=de3ee1039da35fa1 input=eda7964f784f4607]*/ +/*[clinic end generated code: output=b35d4e66f7283e46 input=eda7964f784f4607]*/ /*[clinic input] @@ -2083,8 +2202,31 @@ static PyObject * test_keywords_opt_kwonly(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), &_Py_ID(b), &_Py_ID(c), &_Py_ID(d), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"a", "b", "c", "d", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_keywords_opt_kwonly", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_keywords_opt_kwonly", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *a; @@ -2127,7 +2269,7 @@ exit: static PyObject * test_keywords_opt_kwonly_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c, PyObject *d) -/*[clinic end generated code: output=996394678586854e input=209387a4815e5082]*/ +/*[clinic end generated code: output=ede7e6e65106bf2b input=209387a4815e5082]*/ /*[clinic input] @@ -2156,8 +2298,31 @@ static PyObject * test_keywords_kwonly_opt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), &_Py_ID(b), &_Py_ID(c), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"a", "b", "c", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_keywords_kwonly_opt", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_keywords_kwonly_opt", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *a; @@ -2189,7 +2354,7 @@ exit: static PyObject * test_keywords_kwonly_opt_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c) -/*[clinic end generated code: output=4ea9947a903a2f24 input=18393cc64fa000f4]*/ +/*[clinic end generated code: output=36d4df939a4c3eef input=18393cc64fa000f4]*/ /*[clinic input] @@ -2216,8 +2381,31 @@ static PyObject * test_posonly_keywords(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(b), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "b", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_posonly_keywords", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_posonly_keywords", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject *a; PyObject *b; @@ -2236,7 +2424,7 @@ exit: static PyObject * test_posonly_keywords_impl(PyObject *module, PyObject *a, PyObject *b) -/*[clinic end generated code: output=478aad346a188a80 input=1767b0ebdf06060e]*/ +/*[clinic end generated code: output=4835f4b6cf386c28 input=1767b0ebdf06060e]*/ /*[clinic input] @@ -2264,8 +2452,31 @@ static PyObject * test_posonly_kwonly(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(c), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "c", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_posonly_kwonly", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_posonly_kwonly", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject *a; PyObject *c; @@ -2284,7 +2495,7 @@ exit: static PyObject * test_posonly_kwonly_impl(PyObject *module, PyObject *a, PyObject *c) -/*[clinic end generated code: output=d747975a0b28e9c2 input=9042f2818f664839]*/ +/*[clinic end generated code: output=2570ea156a8d3cb5 input=9042f2818f664839]*/ /*[clinic input] @@ -2314,8 +2525,31 @@ static PyObject * test_posonly_keywords_kwonly(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(b), &_Py_ID(c), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "b", "c", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_posonly_keywords_kwonly", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_posonly_keywords_kwonly", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; PyObject *a; PyObject *b; @@ -2337,7 +2571,7 @@ exit: static PyObject * test_posonly_keywords_kwonly_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c) -/*[clinic end generated code: output=5b99f692f8ddaa4a input=29546ebdca492fea]*/ +/*[clinic end generated code: output=aaa0e6b5ce02900d input=29546ebdca492fea]*/ /*[clinic input] @@ -2367,8 +2601,31 @@ static PyObject * test_posonly_keywords_opt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(b), &_Py_ID(c), &_Py_ID(d), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "b", "c", "d", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_posonly_keywords_opt", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_posonly_keywords_opt", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; PyObject *a; @@ -2402,7 +2659,7 @@ exit: static PyObject * test_posonly_keywords_opt_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c, PyObject *d) -/*[clinic end generated code: output=fd5dfbac5727aebb input=cdf5a9625e554e9b]*/ +/*[clinic end generated code: output=1d9f2d8420d0a85f input=cdf5a9625e554e9b]*/ /*[clinic input] @@ -2431,8 +2688,31 @@ static PyObject * test_posonly_keywords_opt2(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(b), &_Py_ID(c), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "b", "c", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_posonly_keywords_opt2", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_posonly_keywords_opt2", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *a; @@ -2464,7 +2744,7 @@ exit: static PyObject * test_posonly_keywords_opt2_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c) -/*[clinic end generated code: output=777f58ac70775420 input=1581299d21d16f14]*/ +/*[clinic end generated code: output=a83caa0505b296cf input=1581299d21d16f14]*/ /*[clinic input] @@ -2494,8 +2774,31 @@ static PyObject * test_posonly_opt_keywords_opt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(c), &_Py_ID(d), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "", "c", "d", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_posonly_opt_keywords_opt", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_posonly_opt_keywords_opt", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *a; @@ -2534,7 +2837,7 @@ exit: static PyObject * test_posonly_opt_keywords_opt_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c, PyObject *d) -/*[clinic end generated code: output=2c18b8edff78ed22 input=408798ec3d42949f]*/ +/*[clinic end generated code: output=0b24fba3dc04d26b input=408798ec3d42949f]*/ /*[clinic input] @@ -2565,8 +2868,31 @@ static PyObject * test_posonly_kwonly_opt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(b), &_Py_ID(c), &_Py_ID(d), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "b", "c", "d", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_posonly_kwonly_opt", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_posonly_kwonly_opt", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; PyObject *a; @@ -2600,7 +2926,7 @@ exit: static PyObject * test_posonly_kwonly_opt_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c, PyObject *d) -/*[clinic end generated code: output=8db9ab5602e1efaf input=8d8e5643bbbc2309]*/ +/*[clinic end generated code: output=592b217bca2f7bcc input=8d8e5643bbbc2309]*/ /*[clinic input] @@ -2630,8 +2956,31 @@ static PyObject * test_posonly_kwonly_opt2(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(b), &_Py_ID(c), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "b", "c", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_posonly_kwonly_opt2", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_posonly_kwonly_opt2", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *a; @@ -2663,7 +3012,7 @@ exit: static PyObject * test_posonly_kwonly_opt2_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c) -/*[clinic end generated code: output=6cfe546265d85d2c input=f7e5eed94f75fff0]*/ +/*[clinic end generated code: output=b8b00420826bc11f input=f7e5eed94f75fff0]*/ /*[clinic input] @@ -2694,8 +3043,31 @@ static PyObject * test_posonly_opt_kwonly_opt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(c), &_Py_ID(d), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "", "c", "d", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_posonly_opt_kwonly_opt", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_posonly_opt_kwonly_opt", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *a; @@ -2734,7 +3106,7 @@ exit: static PyObject * test_posonly_opt_kwonly_opt_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c, PyObject *d) -/*[clinic end generated code: output=8b5e21a30cad22b7 input=1e557dc979d120fd]*/ +/*[clinic end generated code: output=3b9ee879ebee285a input=1e557dc979d120fd]*/ /*[clinic input] @@ -2767,8 +3139,31 @@ static PyObject * test_posonly_keywords_kwonly_opt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(b), &_Py_ID(c), &_Py_ID(d), &_Py_ID(e), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "b", "c", "d", "e", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_posonly_keywords_kwonly_opt", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_posonly_keywords_kwonly_opt", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3; PyObject *a; @@ -2805,7 +3200,7 @@ static PyObject * test_posonly_keywords_kwonly_opt_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c, PyObject *d, PyObject *e) -/*[clinic end generated code: output=950b9ace38b8b4a7 input=c3884a4f956fdc89]*/ +/*[clinic end generated code: output=d380f84f81cc0e45 input=c3884a4f956fdc89]*/ /*[clinic input] @@ -2836,8 +3231,31 @@ static PyObject * test_posonly_keywords_kwonly_opt2(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(b), &_Py_ID(c), &_Py_ID(d), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "b", "c", "d", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_posonly_keywords_kwonly_opt2", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_posonly_keywords_kwonly_opt2", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; PyObject *a; @@ -2871,7 +3289,7 @@ exit: static PyObject * test_posonly_keywords_kwonly_opt2_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c, PyObject *d) -/*[clinic end generated code: output=fb6951a21b517317 input=68d01d7c0f6dafb0]*/ +/*[clinic end generated code: output=ee629e962cb06992 input=68d01d7c0f6dafb0]*/ /*[clinic input] @@ -2905,8 +3323,31 @@ static PyObject * test_posonly_keywords_opt_kwonly_opt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(b), &_Py_ID(c), &_Py_ID(d), &_Py_ID(e), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "b", "c", "d", "e", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_posonly_keywords_opt_kwonly_opt", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_posonly_keywords_opt_kwonly_opt", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; PyObject *a; @@ -2952,7 +3393,7 @@ static PyObject * test_posonly_keywords_opt_kwonly_opt_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c, PyObject *d, PyObject *e) -/*[clinic end generated code: output=4db10815a99a857e input=d0883d45876f186c]*/ +/*[clinic end generated code: output=a2721babb42ecfd1 input=d0883d45876f186c]*/ /*[clinic input] @@ -2986,8 +3427,31 @@ static PyObject * test_posonly_keywords_opt2_kwonly_opt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(b), &_Py_ID(c), &_Py_ID(d), &_Py_ID(e), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "b", "c", "d", "e", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_posonly_keywords_opt2_kwonly_opt", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_posonly_keywords_opt2_kwonly_opt", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *a; @@ -3038,7 +3502,7 @@ static PyObject * test_posonly_keywords_opt2_kwonly_opt_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c, PyObject *d, PyObject *e) -/*[clinic end generated code: output=0416689b23ebf66e input=c95e2e1ec93035ad]*/ +/*[clinic end generated code: output=0626203eedb6e7e8 input=c95e2e1ec93035ad]*/ /*[clinic input] @@ -3074,8 +3538,31 @@ static PyObject * test_posonly_opt_keywords_opt_kwonly_opt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(c), &_Py_ID(d), &_Py_ID(e), &_Py_ID(f), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "", "c", "d", "e", "f", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_posonly_opt_keywords_opt_kwonly_opt", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_posonly_opt_keywords_opt_kwonly_opt", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[6]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *a; @@ -3134,7 +3621,7 @@ test_posonly_opt_keywords_opt_kwonly_opt_impl(PyObject *module, PyObject *a, PyObject *b, PyObject *c, PyObject *d, PyObject *e, PyObject *f) -/*[clinic end generated code: output=8892a137a8c8f46f input=9914857713c5bbf8]*/ +/*[clinic end generated code: output=07d8acc04558a5a0 input=9914857713c5bbf8]*/ /*[clinic input] test_keyword_only_parameter @@ -3160,8 +3647,31 @@ static PyObject * test_keyword_only_parameter(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(co_lnotab), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"co_lnotab", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_keyword_only_parameter", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_keyword_only_parameter", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyBytesObject *co_lnotab = (PyBytesObject *)self->co_lnotab; @@ -3187,7 +3697,7 @@ exit: static PyObject * test_keyword_only_parameter_impl(PyObject *module, PyBytesObject *co_lnotab) -/*[clinic end generated code: output=332b5f4b444c5d55 input=303df5046c7e37a3]*/ +/*[clinic end generated code: output=b12fe2e515a62603 input=303df5046c7e37a3]*/ /*[clinic input] @@ -3222,6 +3732,47 @@ test_preprocessor_guarded_else_impl(PyObject *module) /*[clinic end generated code: output=13af7670aac51b12 input=6657ab31d74c29fc]*/ #endif +#ifndef CONDITION_C +/*[clinic input] +test_preprocessor_guarded_ifndef_condition_c +[clinic start generated code]*/ + +static PyObject * +test_preprocessor_guarded_ifndef_condition_c_impl(PyObject *module) +/*[clinic end generated code: output=ed422e8c895bb0a5 input=e9b50491cea2b668]*/ +#else +/*[clinic input] +test_preprocessor_guarded_ifndef_not_condition_c +[clinic start generated code]*/ + +static PyObject * +test_preprocessor_guarded_ifndef_not_condition_c_impl(PyObject *module) +/*[clinic end generated code: output=de6f4c6a67f8c536 input=da74e30e01c6f2c5]*/ +#endif + +#if \ +CONDITION_D +/*[clinic input] +test_preprocessor_guarded_if_with_continuation +[clinic start generated code]*/ + +static PyObject * +test_preprocessor_guarded_if_with_continuation_impl(PyObject *module) +/*[clinic end generated code: output=3d0712ca9e2d15b9 input=4a956fd91be30284]*/ +#endif + +#if CONDITION_E || CONDITION_F +#warning "different type of CPP directive" +/*[clinic input] +test_preprocessor_guarded_if_e_or_f +Makes sure cpp.Monitor handles other directives than preprocessor conditionals. +[clinic start generated code]*/ + +static PyObject * +test_preprocessor_guarded_if_e_or_f_impl(PyObject *module) +/*[clinic end generated code: output=e49d24ff64ad88bc input=57b9c37f938bc4f1]*/ +#endif + /*[clinic input] dump buffer output pop @@ -3281,6 +3832,79 @@ test_preprocessor_guarded_else(PyObject *module, PyObject *Py_UNUSED(ignored)) #endif /* !defined(CONDITION_A) && !(CONDITION_B) */ +#if !defined(CONDITION_C) + +PyDoc_STRVAR(test_preprocessor_guarded_ifndef_condition_c__doc__, +"test_preprocessor_guarded_ifndef_condition_c($module, /)\n" +"--\n" +"\n"); + +#define TEST_PREPROCESSOR_GUARDED_IFNDEF_CONDITION_C_METHODDEF \ + {"test_preprocessor_guarded_ifndef_condition_c", (PyCFunction)test_preprocessor_guarded_ifndef_condition_c, METH_NOARGS, test_preprocessor_guarded_ifndef_condition_c__doc__}, + +static PyObject * +test_preprocessor_guarded_ifndef_condition_c(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return test_preprocessor_guarded_ifndef_condition_c_impl(module); +} + +#endif /* !defined(CONDITION_C) */ + +#if defined(CONDITION_C) + +PyDoc_STRVAR(test_preprocessor_guarded_ifndef_not_condition_c__doc__, +"test_preprocessor_guarded_ifndef_not_condition_c($module, /)\n" +"--\n" +"\n"); + +#define TEST_PREPROCESSOR_GUARDED_IFNDEF_NOT_CONDITION_C_METHODDEF \ + {"test_preprocessor_guarded_ifndef_not_condition_c", (PyCFunction)test_preprocessor_guarded_ifndef_not_condition_c, METH_NOARGS, test_preprocessor_guarded_ifndef_not_condition_c__doc__}, + +static PyObject * +test_preprocessor_guarded_ifndef_not_condition_c(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return test_preprocessor_guarded_ifndef_not_condition_c_impl(module); +} + +#endif /* defined(CONDITION_C) */ + +#if (CONDITION_D) + +PyDoc_STRVAR(test_preprocessor_guarded_if_with_continuation__doc__, +"test_preprocessor_guarded_if_with_continuation($module, /)\n" +"--\n" +"\n"); + +#define TEST_PREPROCESSOR_GUARDED_IF_WITH_CONTINUATION_METHODDEF \ + {"test_preprocessor_guarded_if_with_continuation", (PyCFunction)test_preprocessor_guarded_if_with_continuation, METH_NOARGS, test_preprocessor_guarded_if_with_continuation__doc__}, + +static PyObject * +test_preprocessor_guarded_if_with_continuation(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return test_preprocessor_guarded_if_with_continuation_impl(module); +} + +#endif /* (CONDITION_D) */ + +#if (CONDITION_E || CONDITION_F) + +PyDoc_STRVAR(test_preprocessor_guarded_if_e_or_f__doc__, +"test_preprocessor_guarded_if_e_or_f($module, /)\n" +"--\n" +"\n" +"Makes sure cpp.Monitor handles other directives than preprocessor conditionals."); + +#define TEST_PREPROCESSOR_GUARDED_IF_E_OR_F_METHODDEF \ + {"test_preprocessor_guarded_if_e_or_f", (PyCFunction)test_preprocessor_guarded_if_e_or_f, METH_NOARGS, test_preprocessor_guarded_if_e_or_f__doc__}, + +static PyObject * +test_preprocessor_guarded_if_e_or_f(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return test_preprocessor_guarded_if_e_or_f_impl(module); +} + +#endif /* (CONDITION_E || CONDITION_F) */ + #ifndef TEST_PREPROCESSOR_GUARDED_CONDITION_A_METHODDEF #define TEST_PREPROCESSOR_GUARDED_CONDITION_A_METHODDEF #endif /* !defined(TEST_PREPROCESSOR_GUARDED_CONDITION_A_METHODDEF) */ @@ -3292,7 +3916,23 @@ test_preprocessor_guarded_else(PyObject *module, PyObject *Py_UNUSED(ignored)) #ifndef TEST_PREPROCESSOR_GUARDED_ELSE_METHODDEF #define TEST_PREPROCESSOR_GUARDED_ELSE_METHODDEF #endif /* !defined(TEST_PREPROCESSOR_GUARDED_ELSE_METHODDEF) */ -/*[clinic end generated code: output=3804bb18d454038c input=3fc80c9989d2f2e1]*/ + +#ifndef TEST_PREPROCESSOR_GUARDED_IFNDEF_CONDITION_C_METHODDEF + #define TEST_PREPROCESSOR_GUARDED_IFNDEF_CONDITION_C_METHODDEF +#endif /* !defined(TEST_PREPROCESSOR_GUARDED_IFNDEF_CONDITION_C_METHODDEF) */ + +#ifndef TEST_PREPROCESSOR_GUARDED_IFNDEF_NOT_CONDITION_C_METHODDEF + #define TEST_PREPROCESSOR_GUARDED_IFNDEF_NOT_CONDITION_C_METHODDEF +#endif /* !defined(TEST_PREPROCESSOR_GUARDED_IFNDEF_NOT_CONDITION_C_METHODDEF) */ + +#ifndef TEST_PREPROCESSOR_GUARDED_IF_WITH_CONTINUATION_METHODDEF + #define TEST_PREPROCESSOR_GUARDED_IF_WITH_CONTINUATION_METHODDEF +#endif /* !defined(TEST_PREPROCESSOR_GUARDED_IF_WITH_CONTINUATION_METHODDEF) */ + +#ifndef TEST_PREPROCESSOR_GUARDED_IF_E_OR_F_METHODDEF + #define TEST_PREPROCESSOR_GUARDED_IF_E_OR_F_METHODDEF +#endif /* !defined(TEST_PREPROCESSOR_GUARDED_IF_E_OR_F_METHODDEF) */ +/*[clinic end generated code: output=fcfae7cac7a99e62 input=3fc80c9989d2f2e1]*/ /*[clinic input] test_vararg_and_posonly @@ -3368,8 +4008,31 @@ static PyObject * test_vararg(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"a", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_vararg", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_vararg", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject *a; PyObject *__clinic_args = NULL; @@ -3389,7 +4052,7 @@ exit: static PyObject * test_vararg_impl(PyObject *module, PyObject *a, PyObject *args) -/*[clinic end generated code: output=ce9334333757f6ea input=81d33815ad1bae6e]*/ +/*[clinic end generated code: output=880365c61ae205d7 input=81d33815ad1bae6e]*/ /*[clinic input] test_vararg_with_default @@ -3417,8 +4080,31 @@ static PyObject * test_vararg_with_default(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), &_Py_ID(b), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"a", "b", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_vararg_with_default", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_vararg_with_default", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = Py_MIN(nargs, 1) + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *a; @@ -3449,7 +4135,7 @@ exit: static PyObject * test_vararg_with_default_impl(PyObject *module, PyObject *a, PyObject *args, int b) -/*[clinic end generated code: output=32fb19dd6bcf9185 input=6e110b54acd9b22d]*/ +/*[clinic end generated code: output=291e9a5a09831128 input=6e110b54acd9b22d]*/ /*[clinic input] test_vararg_with_only_defaults @@ -3477,8 +4163,31 @@ static PyObject * test_vararg_with_only_defaults(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(b), &_Py_ID(c), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"b", "c", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_vararg_with_only_defaults", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_vararg_with_only_defaults", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = 0 + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *__clinic_args = NULL; @@ -3514,7 +4223,7 @@ exit: static PyObject * test_vararg_with_only_defaults_impl(PyObject *module, PyObject *args, int b, PyObject *c) -/*[clinic end generated code: output=7e393689e6ce61a3 input=fa56a709a035666e]*/ +/*[clinic end generated code: output=dd21b28f0db26a4b input=fa56a709a035666e]*/ /*[clinic input] test_paramname_module @@ -3537,8 +4246,31 @@ static PyObject * test_paramname_module(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(module), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"module", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "test_paramname_module", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "test_paramname_module", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *mod; @@ -3555,4 +4287,726 @@ exit: static PyObject * test_paramname_module_impl(PyObject *module, PyObject *mod) -/*[clinic end generated code: output=23379a7ffa65c514 input=afefe259667f13ba]*/ +/*[clinic end generated code: output=4a2a849ecbcc8b53 input=afefe259667f13ba]*/ + +/*[clinic input] +mangle1 + + args: object + kwnames: object + return_value: object + _keywords: object + _parser: object + argsbuf: object + fastargs: object + nargs: object + noptargs: object + +[clinic start generated code]*/ + +PyDoc_STRVAR(mangle1__doc__, +"mangle1($module, /, args, kwnames, return_value, _keywords, _parser,\n" +" argsbuf, fastargs, nargs, noptargs)\n" +"--\n" +"\n"); + +#define MANGLE1_METHODDEF \ + {"mangle1", _PyCFunction_CAST(mangle1), METH_FASTCALL|METH_KEYWORDS, mangle1__doc__}, + +static PyObject * +mangle1_impl(PyObject *module, PyObject *args, PyObject *kwnames, + PyObject *return_value, PyObject *_keywords, PyObject *_parser, + PyObject *argsbuf, PyObject *fastargs, PyObject *nargs, + PyObject *noptargs); + +static PyObject * +mangle1(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 9 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(args), &_Py_ID(kwnames), &_Py_ID(return_value), &_Py_ID(_keywords), &_Py_ID(_parser), &_Py_ID(argsbuf), &_Py_ID(fastargs), &_Py_ID(nargs), &_Py_ID(noptargs), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"args", "kwnames", "return_value", "_keywords", "_parser", "argsbuf", "fastargs", "nargs", "noptargs", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "mangle1", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[9]; + PyObject *__clinic_args; + PyObject *__clinic_kwnames; + PyObject *__clinic_return_value; + PyObject *__clinic__keywords; + PyObject *__clinic__parser; + PyObject *__clinic_argsbuf; + PyObject *__clinic_fastargs; + PyObject *__clinic_nargs; + PyObject *__clinic_noptargs; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 9, 9, 0, argsbuf); + if (!args) { + goto exit; + } + __clinic_args = args[0]; + __clinic_kwnames = args[1]; + __clinic_return_value = args[2]; + __clinic__keywords = args[3]; + __clinic__parser = args[4]; + __clinic_argsbuf = args[5]; + __clinic_fastargs = args[6]; + __clinic_nargs = args[7]; + __clinic_noptargs = args[8]; + return_value = mangle1_impl(module, __clinic_args, __clinic_kwnames, __clinic_return_value, __clinic__keywords, __clinic__parser, __clinic_argsbuf, __clinic_fastargs, __clinic_nargs, __clinic_noptargs); + +exit: + return return_value; +} + +static PyObject * +mangle1_impl(PyObject *module, PyObject *args, PyObject *kwnames, + PyObject *return_value, PyObject *_keywords, PyObject *_parser, + PyObject *argsbuf, PyObject *fastargs, PyObject *nargs, + PyObject *noptargs) +/*[clinic end generated code: output=083e5076be9987c3 input=a3ed51bdedf8a3c7]*/ + +/*[clinic input] +mangle2 + + args: object + kwargs: object + return_value: object + +[clinic start generated code]*/ + +PyDoc_STRVAR(mangle2__doc__, +"mangle2($module, /, args, kwargs, return_value)\n" +"--\n" +"\n"); + +#define MANGLE2_METHODDEF \ + {"mangle2", _PyCFunction_CAST(mangle2), METH_FASTCALL|METH_KEYWORDS, mangle2__doc__}, + +static PyObject * +mangle2_impl(PyObject *module, PyObject *args, PyObject *kwargs, + PyObject *return_value); + +static PyObject * +mangle2(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(args), &_Py_ID(kwargs), &_Py_ID(return_value), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"args", "kwargs", "return_value", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "mangle2", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[3]; + PyObject *__clinic_args; + PyObject *__clinic_kwargs; + PyObject *__clinic_return_value; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 3, 3, 0, argsbuf); + if (!args) { + goto exit; + } + __clinic_args = args[0]; + __clinic_kwargs = args[1]; + __clinic_return_value = args[2]; + return_value = mangle2_impl(module, __clinic_args, __clinic_kwargs, __clinic_return_value); + +exit: + return return_value; +} + +static PyObject * +mangle2_impl(PyObject *module, PyObject *args, PyObject *kwargs, + PyObject *return_value) +/*[clinic end generated code: output=2ebb62aaefe7590a input=391766fee51bad7a]*/ + + +/*[clinic input] +Test.cls_with_param + cls: defining_class + / + a: int +[clinic start generated code]*/ + +PyDoc_STRVAR(Test_cls_with_param__doc__, +"cls_with_param($self, /, a)\n" +"--\n" +"\n"); + +#define TEST_CLS_WITH_PARAM_METHODDEF \ + {"cls_with_param", _PyCFunction_CAST(Test_cls_with_param), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, Test_cls_with_param__doc__}, + +static PyObject * +Test_cls_with_param_impl(TestObj *self, PyTypeObject *cls, int a); + +static PyObject * +Test_cls_with_param(TestObj *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"a", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "cls_with_param", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + int a; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + a = _PyLong_AsInt(args[0]); + if (a == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = Test_cls_with_param_impl(self, cls, a); + +exit: + return return_value; +} + +static PyObject * +Test_cls_with_param_impl(TestObj *self, PyTypeObject *cls, int a) +/*[clinic end generated code: output=00218e7f583e6c81 input=af158077bd237ef9]*/ + + +/*[clinic input] +Test.__init__ +Empty init method. +[clinic start generated code]*/ + +PyDoc_STRVAR(Test___init____doc__, +"Test()\n" +"--\n" +"\n" +"Empty init method."); + +static int +Test___init___impl(TestObj *self); + +static int +Test___init__(PyObject *self, PyObject *args, PyObject *kwargs) +{ + int return_value = -1; + PyTypeObject *base_tp = TestType; + + if ((Py_IS_TYPE(self, base_tp) || + Py_TYPE(self)->tp_new == base_tp->tp_new) && + !_PyArg_NoPositional("Test", args)) { + goto exit; + } + if ((Py_IS_TYPE(self, base_tp) || + Py_TYPE(self)->tp_new == base_tp->tp_new) && + !_PyArg_NoKeywords("Test", kwargs)) { + goto exit; + } + return_value = Test___init___impl((TestObj *)self); + +exit: + return return_value; +} + +static int +Test___init___impl(TestObj *self) +/*[clinic end generated code: output=f6a35c85bc5b408f input=4ea79fee54d0c3ff]*/ + + +/*[clinic input] +@classmethod +Test.__new__ +Empty new method. +[clinic start generated code]*/ + +PyDoc_STRVAR(Test__doc__, +"Test()\n" +"--\n" +"\n" +"Empty new method."); + +static PyObject * +Test_impl(PyTypeObject *type); + +static PyObject * +Test(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + PyTypeObject *base_tp = TestType; + + if ((type == base_tp || type->tp_init == base_tp->tp_init) && + !_PyArg_NoPositional("Test", args)) { + goto exit; + } + if ((type == base_tp || type->tp_init == base_tp->tp_init) && + !_PyArg_NoKeywords("Test", kwargs)) { + goto exit; + } + return_value = Test_impl(type); + +exit: + return return_value; +} + +static PyObject * +Test_impl(PyTypeObject *type) +/*[clinic end generated code: output=68a117adc057940f input=6fe98a19f097907f]*/ + + +/*[clinic input] +Test.cls_no_params + cls: defining_class + / +[clinic start generated code]*/ + +PyDoc_STRVAR(Test_cls_no_params__doc__, +"cls_no_params($self, /)\n" +"--\n" +"\n"); + +#define TEST_CLS_NO_PARAMS_METHODDEF \ + {"cls_no_params", _PyCFunction_CAST(Test_cls_no_params), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, Test_cls_no_params__doc__}, + +static PyObject * +Test_cls_no_params_impl(TestObj *self, PyTypeObject *cls); + +static PyObject * +Test_cls_no_params(TestObj *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + if (nargs) { + PyErr_SetString(PyExc_TypeError, "cls_no_params() takes no arguments"); + return NULL; + } + return Test_cls_no_params_impl(self, cls); +} + +static PyObject * +Test_cls_no_params_impl(TestObj *self, PyTypeObject *cls) +/*[clinic end generated code: output=cc8845f22cff3dcb input=e7e2e4e344e96a11]*/ + + +/*[clinic input] +Test.metho_not_default_return_converter -> int + a: object + / +[clinic start generated code]*/ + +PyDoc_STRVAR(Test_metho_not_default_return_converter__doc__, +"metho_not_default_return_converter($self, a, /)\n" +"--\n" +"\n"); + +#define TEST_METHO_NOT_DEFAULT_RETURN_CONVERTER_METHODDEF \ + {"metho_not_default_return_converter", (PyCFunction)Test_metho_not_default_return_converter, METH_O, Test_metho_not_default_return_converter__doc__}, + +static int +Test_metho_not_default_return_converter_impl(TestObj *self, PyObject *a); + +static PyObject * +Test_metho_not_default_return_converter(TestObj *self, PyObject *a) +{ + PyObject *return_value = NULL; + int _return_value; + + _return_value = Test_metho_not_default_return_converter_impl(self, a); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromLong((long)_return_value); + +exit: + return return_value; +} + +static int +Test_metho_not_default_return_converter_impl(TestObj *self, PyObject *a) +/*[clinic end generated code: output=3350de11bd538007 input=428657129b521177]*/ + + +/*[clinic input] +Test.an_metho_arg_named_arg + arg: int + Name should be mangled to 'arg_' in generated output. + / +[clinic start generated code]*/ + +PyDoc_STRVAR(Test_an_metho_arg_named_arg__doc__, +"an_metho_arg_named_arg($self, arg, /)\n" +"--\n" +"\n" +"\n" +"\n" +" arg\n" +" Name should be mangled to \'arg_\' in generated output."); + +#define TEST_AN_METHO_ARG_NAMED_ARG_METHODDEF \ + {"an_metho_arg_named_arg", (PyCFunction)Test_an_metho_arg_named_arg, METH_O, Test_an_metho_arg_named_arg__doc__}, + +static PyObject * +Test_an_metho_arg_named_arg_impl(TestObj *self, int arg); + +static PyObject * +Test_an_metho_arg_named_arg(TestObj *self, PyObject *arg_) +{ + PyObject *return_value = NULL; + int arg; + + arg = _PyLong_AsInt(arg_); + if (arg == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = Test_an_metho_arg_named_arg_impl(self, arg); + +exit: + return return_value; +} + +static PyObject * +Test_an_metho_arg_named_arg_impl(TestObj *self, int arg) +/*[clinic end generated code: output=7d590626642194ae input=2a53a57cf5624f95]*/ + + +/*[clinic input] +Test.__init__ + *args: object + / +Varargs init method. For example, nargs is translated to PyTuple_GET_SIZE. +[clinic start generated code]*/ + +PyDoc_STRVAR(Test___init____doc__, +"Test(*args)\n" +"--\n" +"\n" +"Varargs init method. For example, nargs is translated to PyTuple_GET_SIZE."); + +static int +Test___init___impl(TestObj *self, PyObject *args); + +static int +Test___init__(PyObject *self, PyObject *args, PyObject *kwargs) +{ + int return_value = -1; + PyTypeObject *base_tp = TestType; + PyObject *__clinic_args = NULL; + + if ((Py_IS_TYPE(self, base_tp) || + Py_TYPE(self)->tp_new == base_tp->tp_new) && + !_PyArg_NoKeywords("Test", kwargs)) { + goto exit; + } + if (!_PyArg_CheckPositional("Test", PyTuple_GET_SIZE(args), 0, PY_SSIZE_T_MAX)) { + goto exit; + } + __clinic_args = PyTuple_GetSlice(0, -1); + return_value = Test___init___impl((TestObj *)self, __clinic_args); + +exit: + Py_XDECREF(__clinic_args); + return return_value; +} + +static int +Test___init___impl(TestObj *self, PyObject *args) +/*[clinic end generated code: output=0ed1009fe0dcf98d input=96c3ddc0cd38fc0c]*/ + + +/*[clinic input] +@classmethod +Test.__new__ + *args: object + / +Varargs new method. For example, nargs is translated to PyTuple_GET_SIZE. +[clinic start generated code]*/ + +PyDoc_STRVAR(Test__doc__, +"Test(*args)\n" +"--\n" +"\n" +"Varargs new method. For example, nargs is translated to PyTuple_GET_SIZE."); + +static PyObject * +Test_impl(PyTypeObject *type, PyObject *args); + +static PyObject * +Test(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + PyTypeObject *base_tp = TestType; + PyObject *__clinic_args = NULL; + + if ((type == base_tp || type->tp_init == base_tp->tp_init) && + !_PyArg_NoKeywords("Test", kwargs)) { + goto exit; + } + if (!_PyArg_CheckPositional("Test", PyTuple_GET_SIZE(args), 0, PY_SSIZE_T_MAX)) { + goto exit; + } + __clinic_args = PyTuple_GetSlice(0, -1); + return_value = Test_impl(type, __clinic_args); + +exit: + Py_XDECREF(__clinic_args); + return return_value; +} + +static PyObject * +Test_impl(PyTypeObject *type, PyObject *args) +/*[clinic end generated code: output=8b219f6633e2a2e9 input=26a672e2e9750120]*/ + + +/*[clinic input] +Test.__init__ + a: object +Init method with positional or keyword arguments. +[clinic start generated code]*/ + +PyDoc_STRVAR(Test___init____doc__, +"Test(a)\n" +"--\n" +"\n" +"Init method with positional or keyword arguments."); + +static int +Test___init___impl(TestObj *self, PyObject *a); + +static int +Test___init__(PyObject *self, PyObject *args, PyObject *kwargs) +{ + int return_value = -1; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"a", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "Test", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject * const *fastargs; + Py_ssize_t nargs = PyTuple_GET_SIZE(args); + PyObject *a; + + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 1, 0, argsbuf); + if (!fastargs) { + goto exit; + } + a = fastargs[0]; + return_value = Test___init___impl((TestObj *)self, a); + +exit: + return return_value; +} + +static int +Test___init___impl(TestObj *self, PyObject *a) +/*[clinic end generated code: output=0b9ca79638ab3ecb input=a8f9222a6ab35c59]*/ + + +/*[clinic input] +@classmethod +Test.class_method +[clinic start generated code]*/ + +PyDoc_STRVAR(Test_class_method__doc__, +"class_method($type, /)\n" +"--\n" +"\n"); + +#define TEST_CLASS_METHOD_METHODDEF \ + {"class_method", (PyCFunction)Test_class_method, METH_NOARGS|METH_CLASS, Test_class_method__doc__}, + +static PyObject * +Test_class_method_impl(PyTypeObject *type); + +static PyObject * +Test_class_method(PyTypeObject *type, PyObject *Py_UNUSED(ignored)) +{ + return Test_class_method_impl(type); +} + +static PyObject * +Test_class_method_impl(PyTypeObject *type) +/*[clinic end generated code: output=47fb7ecca1abcaaa input=43bc4a0494547b80]*/ + + +/*[clinic input] +@staticmethod +Test.static_method +[clinic start generated code]*/ + +PyDoc_STRVAR(Test_static_method__doc__, +"static_method()\n" +"--\n" +"\n"); + +#define TEST_STATIC_METHOD_METHODDEF \ + {"static_method", (PyCFunction)Test_static_method, METH_NOARGS|METH_STATIC, Test_static_method__doc__}, + +static PyObject * +Test_static_method_impl(); + +static PyObject * +Test_static_method(void *null, PyObject *Py_UNUSED(ignored)) +{ + return Test_static_method_impl(); +} + +static PyObject * +Test_static_method_impl() +/*[clinic end generated code: output=82524a63025cf7ab input=dae892fac55ae72b]*/ + + +/*[clinic input] +@coexist +Test.meth_coexist +[clinic start generated code]*/ + +PyDoc_STRVAR(Test_meth_coexist__doc__, +"meth_coexist($self, /)\n" +"--\n" +"\n"); + +#define TEST_METH_COEXIST_METHODDEF \ + {"meth_coexist", (PyCFunction)Test_meth_coexist, METH_NOARGS|METH_COEXIST, Test_meth_coexist__doc__}, + +static PyObject * +Test_meth_coexist_impl(TestObj *self); + +static PyObject * +Test_meth_coexist(TestObj *self, PyObject *Py_UNUSED(ignored)) +{ + return Test_meth_coexist_impl(self); +} + +static PyObject * +Test_meth_coexist_impl(TestObj *self) +/*[clinic end generated code: output=808a293d0cd27439 input=2a1d75b5e6fec6dd]*/ + + +/*[clinic input] +output push +output preset buffer +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=5bff3376ee0df0b5]*/ + +/*[clinic input] +buffer_clear + a: int +We'll call 'destination buffer clear' after this. + +Argument Clinic's buffer preset puts most generated code into the +'buffer' destination, except from 'impl_definition', which is put into +the 'block' destination, so we should expect everything but +'impl_definition' to be cleared. +[clinic start generated code]*/ + +static PyObject * +buffer_clear_impl(PyObject *module, int a) +/*[clinic end generated code: output=f14bba74677e1846 input=a4c308a6fdab043c]*/ + +/*[clinic input] +destination buffer clear +output pop +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=f20d06adb8252084]*/ + + +/*[clinic input] +output push +destination test1 new buffer +output everything suppress +output docstring_definition test1 +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=5a77c454970992fc]*/ + +/*[clinic input] +new_dest + a: int +Only this docstring should be outputted to test1. +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=da5af421ed8996ed]*/ + +/*[clinic input] +dump test1 +output pop +[clinic start generated code]*/ + +PyDoc_STRVAR(new_dest__doc__, +"new_dest($module, /, a)\n" +"--\n" +"\n" +"Only this docstring should be outputted to test1."); +/*[clinic end generated code: output=9cac703f51d90e84 input=090db8df4945576d]*/ diff --git a/Lib/test/cmath_testcases.txt b/Lib/test/cmath_testcases.txt index dd7e458d..0165e176 100644 --- a/Lib/test/cmath_testcases.txt +++ b/Lib/test/cmath_testcases.txt @@ -1536,6 +1536,7 @@ sqrt0141 sqrt -1.797e+308 -9.9999999999999999e+306 -> 3.7284476432057307e+152 -1 sqrt0150 sqrt 1.7976931348623157e+308 0.0 -> 1.3407807929942596355e+154 0.0 sqrt0151 sqrt 2.2250738585072014e-308 0.0 -> 1.4916681462400413487e-154 0.0 sqrt0152 sqrt 5e-324 0.0 -> 2.2227587494850774834e-162 0.0 +sqrt0153 sqrt 5e-324 1.0 -> 0.7071067811865476 0.7071067811865476 -- special values sqrt1000 sqrt 0.0 0.0 -> 0.0 0.0 @@ -1744,6 +1745,7 @@ cosh0023 cosh 2.218885944363501 2.0015727395883687 -> -1.94294321081968 4.129026 -- large real part cosh0030 cosh 710.5 2.3519999999999999 -> -1.2967465239355998e+308 1.3076707908857333e+308 cosh0031 cosh -710.5 0.69999999999999996 -> 1.4085466381392499e+308 -1.1864024666450239e+308 +cosh0032 cosh 720.0 0.0 -> inf 0.0 overflow -- Additional real values (mpmath) cosh0050 cosh 1e-150 0.0 -> 1.0 0.0 @@ -1853,6 +1855,7 @@ sinh0023 sinh 0.043713693678420068 0.22512549887532657 -> 0.042624198673416713 0 -- large real part sinh0030 sinh 710.5 -2.3999999999999999 -> -1.3579970564885919e+308 -1.24394470907798e+308 sinh0031 sinh -710.5 0.80000000000000004 -> -1.2830671601735164e+308 1.3210954193997678e+308 +sinh0032 sinh 720.0 0.0 -> inf 0.0 overflow -- Additional real values (mpmath) sinh0050 sinh 1e-100 0.0 -> 1.00000000000000002e-100 0.0 diff --git a/Lib/test/crashers/infinite_loop_re.py b/Lib/test/crashers/infinite_loop_re.py index 9aecc568..c84f28d6 100644 --- a/Lib/test/crashers/infinite_loop_re.py +++ b/Lib/test/crashers/infinite_loop_re.py @@ -1,5 +1,5 @@ -# This was taken from http://python.org/sf/1541697 +# This was taken from https://bugs.python.org/issue1541697 # It's not technically a crasher. It may not even truly be infinite, # however, I haven't waited a long time to see the result. It takes # 100% of CPU while running this and should be fixed. diff --git a/Lib/test/datetimetester.py b/Lib/test/datetimetester.py index bb677222..55e06195 100644 --- a/Lib/test/datetimetester.py +++ b/Lib/test/datetimetester.py @@ -2,19 +2,19 @@ See https://www.zope.dev/Members/fdrake/DateTimeWiki/TestCases """ -import io -import itertools import bisect import copy import decimal -import functools -import sys +import io +import itertools import os import pickle import random import re import struct +import sys import unittest +import warnings from array import array @@ -40,6 +40,10 @@ except ImportError: # Needed by test_datetime import _strptime +try: + import _pydatetime +except ImportError: + pass # pickle_loads = {pickle.loads, pickle._loads} @@ -48,11 +52,12 @@ pickle_choices = [(pickle, pickle, proto) for proto in range(pickle.HIGHEST_PROTOCOL + 1)] assert len(pickle_choices) == pickle.HIGHEST_PROTOCOL + 1 +EPOCH_NAIVE = datetime(1970, 1, 1, 0, 0) # For calculating transitions + # An arbitrary collection of objects of non-datetime types, for testing # mixed-type comparisons. OTHERSTUFF = (10, 34.5, "abc", {}, [], ()) - # XXX Copied from test_float. INF = float("inf") NAN = float("nan") @@ -93,7 +98,7 @@ class TestModule(unittest.TestCase): if '_Fast' in self.__class__.__name__: self.skipTest('Only run for Pure Python implementation') - dar = datetime_module._divide_and_round + dar = _pydatetime._divide_and_round self.assertEqual(dar(-10, -3), 3) self.assertEqual(dar(5, -2), -2) @@ -1464,8 +1469,8 @@ class TestDate(HarmlessMixedComparison, unittest.TestCase): # test that unicode input is allowed (issue 2782) self.assertEqual(t.strftime("%m"), "03") - # A naive object replaces %z and %Z w/ empty strings. - self.assertEqual(t.strftime("'%z' '%Z'"), "'' ''") + # A naive object replaces %z, %:z and %Z w/ empty strings. + self.assertEqual(t.strftime("'%z' '%:z' '%Z'"), "'' '' ''") #make sure that invalid format specifiers are handled correctly #self.assertRaises(ValueError, t.strftime, "%e") @@ -1490,6 +1495,9 @@ class TestDate(HarmlessMixedComparison, unittest.TestCase): #check that this standard extension works t.strftime("%f") + # bpo-41260: The parameter was named "fmt" in the pure python impl. + t.strftime(format="%f") + def test_strftime_trailing_percent(self): # bpo-35066: Make sure trailing '%' doesn't cause datetime's strftime to # complain. Different libcs have different handling of trailing @@ -1529,7 +1537,7 @@ class TestDate(HarmlessMixedComparison, unittest.TestCase): for fmt in ["m:%m d:%d y:%y", "m:%m d:%d y:%y H:%H M:%M S:%S", - "%z %Z", + "%z %:z %Z", ]: self.assertEqual(dt.__format__(fmt), dt.strftime(fmt)) self.assertEqual(a.__format__(fmt), dt.strftime(fmt)) @@ -2135,7 +2143,7 @@ class TestDateTime(TestDate): for fmt in ["m:%m d:%d y:%y", "m:%m d:%d y:%y H:%H M:%M S:%S", - "%z %Z", + "%z %:z %Z", ]: self.assertEqual(dt.__format__(fmt), dt.strftime(fmt)) self.assertEqual(a.__format__(fmt), dt.strftime(fmt)) @@ -2424,12 +2432,19 @@ class TestDateTime(TestDate): got = self.theclass.fromtimestamp(ts) self.verify_field_equality(expected, got) + def test_fromtimestamp_keyword_arg(self): + import time + + # gh-85432: The parameter was named "t" in the pure-Python impl. + self.theclass.fromtimestamp(timestamp=time.time()) + def test_utcfromtimestamp(self): import time ts = time.time() expected = time.gmtime(ts) - got = self.theclass.utcfromtimestamp(ts) + with self.assertWarns(DeprecationWarning): + got = self.theclass.utcfromtimestamp(ts) self.verify_field_equality(expected, got) # Run with US-style DST rules: DST begins 2 a.m. on second Sunday in @@ -2475,8 +2490,12 @@ class TestDateTime(TestDate): @support.run_with_tz('MSK-03') # Something east of Greenwich def test_microsecond_rounding(self): + def utcfromtimestamp(*args, **kwargs): + with self.assertWarns(DeprecationWarning): + return self.theclass.utcfromtimestamp(*args, **kwargs) + for fts in [self.theclass.fromtimestamp, - self.theclass.utcfromtimestamp]: + utcfromtimestamp]: zero = fts(0) self.assertEqual(zero.second, 0) self.assertEqual(zero.microsecond, 0) @@ -2573,10 +2592,11 @@ class TestDateTime(TestDate): self.theclass.fromtimestamp(ts) def test_utcfromtimestamp_limits(self): - try: - self.theclass.utcfromtimestamp(-2**32 - 1) - except (OSError, OverflowError): - self.skipTest("Test not valid on this platform") + with self.assertWarns(DeprecationWarning): + try: + self.theclass.utcfromtimestamp(-2**32 - 1) + except (OSError, OverflowError): + self.skipTest("Test not valid on this platform") min_dt = self.theclass.min.replace(tzinfo=timezone.utc) min_ts = min_dt.timestamp() @@ -2589,10 +2609,11 @@ class TestDateTime(TestDate): ("maximum", max_ts, max_dt.replace(tzinfo=None)), ]: with self.subTest(test_name, ts=ts, expected=expected): - try: - actual = self.theclass.utcfromtimestamp(ts) - except (OSError, OverflowError) as exc: - self.skipTest(str(exc)) + with self.assertWarns(DeprecationWarning): + try: + actual = self.theclass.utcfromtimestamp(ts) + except (OSError, OverflowError) as exc: + self.skipTest(str(exc)) self.assertEqual(actual, expected) @@ -2607,9 +2628,10 @@ class TestDateTime(TestDate): for test_name, ts in test_cases: with self.subTest(test_name, ts=ts): with self.assertRaises((ValueError, OverflowError)): - # converting a Python int to C time_t can raise a - # OverflowError, especially on 32-bit platforms. - self.theclass.utcfromtimestamp(ts) + with self.assertWarns(DeprecationWarning): + # converting a Python int to C time_t can raise a + # OverflowError, especially on 32-bit platforms. + self.theclass.utcfromtimestamp(ts) def test_insane_fromtimestamp(self): # It's possible that some platform maps time_t to double, @@ -2626,8 +2648,9 @@ class TestDateTime(TestDate): # exempt such platforms (provided they return reasonable # results!). for insane in -1e200, 1e200: - self.assertRaises(OverflowError, self.theclass.utcfromtimestamp, - insane) + with self.assertWarns(DeprecationWarning): + self.assertRaises(OverflowError, self.theclass.utcfromtimestamp, + insane) @unittest.skipIf(sys.platform == "win32", "Windows doesn't accept negative timestamps") def test_negative_float_fromtimestamp(self): @@ -2637,7 +2660,8 @@ class TestDateTime(TestDate): @unittest.skipIf(sys.platform == "win32", "Windows doesn't accept negative timestamps") def test_negative_float_utcfromtimestamp(self): - d = self.theclass.utcfromtimestamp(-1.05) + with self.assertWarns(DeprecationWarning): + d = self.theclass.utcfromtimestamp(-1.05) self.assertEqual(d, self.theclass(1969, 12, 31, 23, 59, 58, 950000)) def test_utcnow(self): @@ -2647,8 +2671,11 @@ class TestDateTime(TestDate): # a second of each other. tolerance = timedelta(seconds=1) for dummy in range(3): - from_now = self.theclass.utcnow() - from_timestamp = self.theclass.utcfromtimestamp(time.time()) + with self.assertWarns(DeprecationWarning): + from_now = self.theclass.utcnow() + + with self.assertWarns(DeprecationWarning): + from_timestamp = self.theclass.utcfromtimestamp(time.time()) if abs(from_timestamp - from_now) <= tolerance: break # Else try again a few times. @@ -2778,6 +2805,7 @@ class TestDateTime(TestDate): tz = timezone(-timedelta(hours=2, seconds=s, microseconds=us)) t = t.replace(tzinfo=tz) self.assertEqual(t.strftime("%z"), "-0200" + z) + self.assertEqual(t.strftime("%:z"), "-02:00:" + z) # bpo-34482: Check that surrogates don't cause a crash. try: @@ -2947,7 +2975,11 @@ class TestDateTime(TestDate): constr_name=constr_name): constructor = getattr(base_obj, constr_name) - dt = constructor(*constr_args) + if constr_name == "utcfromtimestamp": + with self.assertWarns(DeprecationWarning): + dt = constructor(*constr_args) + else: + dt = constructor(*constr_args) # Test that it creates the right subclass self.assertIsInstance(dt, DateTimeSubclass) @@ -2977,7 +3009,11 @@ class TestDateTime(TestDate): for name, meth_name, kwargs in test_cases: with self.subTest(name): constr = getattr(DateTimeSubclass, meth_name) - dt = constr(**kwargs) + if meth_name == "utcnow": + with self.assertWarns(DeprecationWarning): + dt = constr(**kwargs) + else: + dt = constr(**kwargs) self.assertIsInstance(dt, DateTimeSubclass) self.assertEqual(dt.extra, 7) @@ -3516,8 +3552,8 @@ class TestTime(HarmlessMixedComparison, unittest.TestCase): def test_strftime(self): t = self.theclass(1, 2, 3, 4) self.assertEqual(t.strftime('%H %M %S %f'), "01 02 03 000004") - # A naive object replaces %z and %Z with empty strings. - self.assertEqual(t.strftime("'%z' '%Z'"), "'' ''") + # A naive object replaces %z, %:z and %Z with empty strings. + self.assertEqual(t.strftime("'%z' '%:z' '%Z'"), "'' '' ''") # bpo-34482: Check that surrogates don't cause a crash. try: @@ -3525,6 +3561,9 @@ class TestTime(HarmlessMixedComparison, unittest.TestCase): except UnicodeEncodeError: pass + # gh-85432: The parameter was named "fmt" in the pure-Python impl. + t.strftime(format="%f") + def test_format(self): t = self.theclass(1, 2, 3, 4) self.assertEqual(t.__format__(''), str(t)) @@ -3935,10 +3974,10 @@ class TestTimeTZ(TestTime, TZInfoBase, unittest.TestCase): self.assertEqual(repr(t4), d + "(0, 0, 0, 40)") self.assertEqual(repr(t5), d + "(0, 0, 0, 40, tzinfo=utc)") - self.assertEqual(t1.strftime("%H:%M:%S %%Z=%Z %%z=%z"), - "07:47:00 %Z=EST %z=-0500") - self.assertEqual(t2.strftime("%H:%M:%S %Z %z"), "12:47:00 UTC +0000") - self.assertEqual(t3.strftime("%H:%M:%S %Z %z"), "13:47:00 MET +0100") + self.assertEqual(t1.strftime("%H:%M:%S %%Z=%Z %%z=%z %%:z=%:z"), + "07:47:00 %Z=EST %z=-0500 %:z=-05:00") + self.assertEqual(t2.strftime("%H:%M:%S %Z %z %:z"), "12:47:00 UTC +0000 +00:00") + self.assertEqual(t3.strftime("%H:%M:%S %Z %z %:z"), "13:47:00 MET +0100 +01:00") yuck = FixedOffset(-1439, "%z %Z %%z%%Z") t1 = time(23, 59, tzinfo=yuck) @@ -4630,7 +4669,8 @@ class TestDateTimeTZ(TestDateTime, TZInfoBase, unittest.TestCase): for dummy in range(3): now = datetime.now(weirdtz) self.assertIs(now.tzinfo, weirdtz) - utcnow = datetime.utcnow().replace(tzinfo=utc) + with self.assertWarns(DeprecationWarning): + utcnow = datetime.utcnow().replace(tzinfo=utc) now2 = utcnow.astimezone(weirdtz) if abs(now - now2) < timedelta(seconds=30): break @@ -4664,7 +4704,8 @@ class TestDateTimeTZ(TestDateTime, TZInfoBase, unittest.TestCase): # Try to make sure tz= actually does some conversion. timestamp = 1000000000 - utcdatetime = datetime.utcfromtimestamp(timestamp) + with self.assertWarns(DeprecationWarning): + utcdatetime = datetime.utcfromtimestamp(timestamp) # In POSIX (epoch 1970), that's 2001-09-09 01:46:40 UTC, give or take. # But on some flavor of Mac, it's nowhere near that. So we can't have # any idea here what time that actually is, we can only test that @@ -4678,7 +4719,8 @@ class TestDateTimeTZ(TestDateTime, TZInfoBase, unittest.TestCase): def test_tzinfo_utcnow(self): meth = self.theclass.utcnow # Ensure it doesn't require tzinfo (i.e., that this doesn't blow up). - base = meth() + with self.assertWarns(DeprecationWarning): + base = meth() # Try with and without naming the keyword; for whatever reason, # utcnow() doesn't accept a tzinfo argument. off42 = FixedOffset(42, "42") @@ -4690,12 +4732,15 @@ class TestDateTimeTZ(TestDateTime, TZInfoBase, unittest.TestCase): meth = self.theclass.utcfromtimestamp ts = time.time() # Ensure it doesn't require tzinfo (i.e., that this doesn't blow up). - base = meth(ts) + with self.assertWarns(DeprecationWarning): + base = meth(ts) # Try with and without naming the keyword; for whatever reason, # utcfromtimestamp() doesn't accept a tzinfo argument. off42 = FixedOffset(42, "42") - self.assertRaises(TypeError, meth, ts, off42) - self.assertRaises(TypeError, meth, ts, tzinfo=off42) + with warnings.catch_warnings(category=DeprecationWarning): + warnings.simplefilter("ignore", category=DeprecationWarning) + self.assertRaises(TypeError, meth, ts, off42) + self.assertRaises(TypeError, meth, ts, tzinfo=off42) def test_tzinfo_timetuple(self): # TestDateTime tested most of this. datetime adds a twist to the @@ -5297,7 +5342,7 @@ class TestTimezoneConversions(unittest.TestCase): def test_fromutc(self): self.assertRaises(TypeError, Eastern.fromutc) # not enough args - now = datetime.utcnow().replace(tzinfo=utc_real) + now = datetime.now(tz=utc_real) self.assertRaises(ValueError, Eastern.fromutc, now) # wrong tzinfo now = now.replace(tzinfo=Eastern) # insert correct tzinfo enow = Eastern.fromutc(now) # doesn't blow up @@ -5399,9 +5444,11 @@ class Oddballs(unittest.TestCase): self.assertEqual(datetime_sc, as_datetime) def test_extra_attributes(self): + with self.assertWarns(DeprecationWarning): + utcnow = datetime.utcnow() for x in [date.today(), time(), - datetime.utcnow(), + utcnow, timedelta(), tzinfo(), timezone(timedelta())]: @@ -6061,14 +6108,14 @@ class ZoneInfo(tzinfo): def transitions(self): for (_, prev_ti), (t, ti) in pairs(zip(self.ut, self.ti)): shift = ti[0] - prev_ti[0] - yield datetime.utcfromtimestamp(t), shift + yield (EPOCH_NAIVE + timedelta(seconds=t)), shift def nondst_folds(self): """Find all folds with the same value of isdst on both sides of the transition.""" for (_, prev_ti), (t, ti) in pairs(zip(self.ut, self.ti)): shift = ti[0] - prev_ti[0] if shift < ZERO and ti[1] == prev_ti[1]: - yield datetime.utcfromtimestamp(t), -shift, prev_ti[2], ti[2] + yield _utcfromtimestamp(datetime, t,), -shift, prev_ti[2], ti[2] @classmethod def print_all_nondst_folds(cls, same_abbr=False, start_year=1): @@ -6161,7 +6208,7 @@ class ZoneInfoTest(unittest.TestCase): self.assertEqual(ldt.fold, 0) @unittest.skipUnless( - hasattr(time, "tzset"), "time module has no attribute tzset" + hasattr(_time, "tzset"), "time module has no attribute tzset" ) def test_system_transitions(self): if ('Riyadh8' in self.zonename or @@ -6200,6 +6247,10 @@ class ZoneInfoTest(unittest.TestCase): ts1 = dt.replace(fold=1).timestamp() self.assertEqual(ts0, s0 + ss / 2) self.assertEqual(ts1, s0 - ss / 2) + # gh-83861 + utc0 = dt.astimezone(timezone.utc) + utc1 = dt.replace(fold=1).astimezone(timezone.utc) + self.assertEqual(utc0, utc1 + timedelta(0, ss)) finally: if TZ is None: del os.environ['TZ'] diff --git a/Lib/test/fork_wait.py b/Lib/test/fork_wait.py index 4d3dbd8e..8c32895f 100644 --- a/Lib/test/fork_wait.py +++ b/Lib/test/fork_wait.py @@ -9,10 +9,11 @@ On some systems (e.g. Solaris without posix threads) we find that all active threads survive in the child after a fork(); this is an error. """ -import os, sys, time, unittest +import os, time, unittest import threading from test import support from test.support import threading_helper +import warnings LONGSLEEP = 2 @@ -54,10 +55,8 @@ class ForkWait(unittest.TestCase): self.threads.append(thread) # busy-loop to wait for threads - deadline = time.monotonic() + support.SHORT_TIMEOUT - while len(self.alive) < NUM_THREADS: - time.sleep(0.1) - if deadline < time.monotonic(): + for _ in support.sleeping_retry(support.SHORT_TIMEOUT): + if len(self.alive) >= NUM_THREADS: break a = sorted(self.alive.keys()) @@ -65,19 +64,17 @@ class ForkWait(unittest.TestCase): prefork_lives = self.alive.copy() - if sys.platform in ['unixware7']: - cpid = os.fork1() - else: - cpid = os.fork() - - if cpid == 0: - # Child - time.sleep(LONGSLEEP) - n = 0 - for key in self.alive: - if self.alive[key] != prefork_lives[key]: - n += 1 - os._exit(n) - else: - # Parent - self.wait_impl(cpid, exitcode=0) + # Ignore the warning about fork with threads. + with warnings.catch_warnings(category=DeprecationWarning, + action="ignore"): + if (cpid := os.fork()) == 0: + # Child + time.sleep(LONGSLEEP) + n = 0 + for key in self.alive: + if self.alive[key] != prefork_lives[key]: + n += 1 + os._exit(n) + else: + # Parent + self.wait_impl(cpid, exitcode=0) diff --git a/Lib/test/inspect_fodder.py b/Lib/test/inspect_fodder.py index e1287a31..60ba7aa7 100644 --- a/Lib/test/inspect_fodder.py +++ b/Lib/test/inspect_fodder.py @@ -1,7 +1,7 @@ # line 1 'A module docstring.' -import sys, inspect +import inspect # line 5 # line 7 @@ -41,8 +41,8 @@ class StupidGit: def argue(self, a, b, c): try: spam(a, b, c) - except: - self.ex = sys.exc_info() + except BaseException as e: + self.ex = e self.tr = inspect.trace() @property @@ -78,8 +78,8 @@ async def lobbest(grenade): currentframe = inspect.currentframe() try: raise Exception() -except: - tb = sys.exc_info()[2] +except BaseException as e: + tb = e.__traceback__ class Callable: def __call__(self, *args): @@ -113,3 +113,8 @@ class WhichComments: # after asyncf - line 113 # end of WhichComments - line 114 # after WhichComments - line 115 + +# Test that getsource works on a line that includes +# a closing parenthesis with the opening paren being in another line +( +); after_closing = lambda: 1 diff --git a/Lib/test/inspect_fodder2.py b/Lib/test/inspect_fodder2.py index 2dc49817..03464613 100644 --- a/Lib/test/inspect_fodder2.py +++ b/Lib/test/inspect_fodder2.py @@ -273,3 +273,20 @@ def deco_factory(**kwargs): @deco_factory(foo=(1 + 2), bar=lambda: 1) def complex_decorated(foo=0, bar=lambda: 0): return foo + bar() + +# line 276 +parenthesized_lambda = ( + lambda: ()) +parenthesized_lambda2 = [ + lambda: ()][0] +parenthesized_lambda3 = {0: + lambda: ()}[0] + +# line 285 +post_line_parenthesized_lambda1 = (lambda: () +) + +# line 289 +nested_lambda = ( + lambda right: [].map( + lambda length: ())) diff --git a/Lib/test/leakers/test_ctypes.py b/Lib/test/leakers/test_ctypes.py index 7d7e9ff3..ec09ac36 100644 --- a/Lib/test/leakers/test_ctypes.py +++ b/Lib/test/leakers/test_ctypes.py @@ -1,5 +1,5 @@ -# Taken from Lib/ctypes/test/test_keeprefs.py, PointerToStructure.test(). +# Taken from Lib/test/test_ctypes/test_keeprefs.py, PointerToStructure.test(). from ctypes import Structure, c_int, POINTER import gc diff --git a/Lib/test/levenshtein_examples.json b/Lib/test/levenshtein_examples.json new file mode 100644 index 00000000..a32672cf --- /dev/null +++ b/Lib/test/levenshtein_examples.json @@ -0,0 +1,50002 @@ +[ + [ + "", + "", + 0 + ], + [ + "", + "AabBbb", + 12 + ], + [ + "", + "AbaC", + 8 + ], + [ + "", + "B", + 2 + ], + [ + "", + "Ba", + 4 + ], + [ + "", + "CBaACCCa", + 16 + ], + [ + "", + "CCbBC", + 10 + ], + [ + "", + "CcbCbaaAB", + 18 + ], + [ + "", + "bAa", + 6 + ], + [ + "", + "bAaCABb", + 14 + ], + [ + "A", + "A", + 0 + ], + [ + "A", + "AA", + 2 + ], + [ + "A", + "AABCAabcC", + 16 + ], + [ + "A", + "AACB", + 6 + ], + [ + "A", + "AACC", + 6 + ], + [ + "A", + "ABAaBbc", + 12 + ], + [ + "A", + "ABCcC", + 8 + ], + [ + "A", + "ABa", + 4 + ], + [ + "A", + "ABbBabcaa", + 16 + ], + [ + "A", + "ABbbCBcA", + 14 + ], + [ + "A", + "ACCBcBbBb", + 16 + ], + [ + "A", + "ACa", + 4 + ], + [ + "A", + "ACb", + 4 + ], + [ + "A", + "ACcbbaAB", + 14 + ], + [ + "A", + "AaAaccAb", + 14 + ], + [ + "A", + "AaabbCC", + 12 + ], + [ + "A", + "AabB", + 6 + ], + [ + "A", + "AbBa", + 6 + ], + [ + "A", + "AbBaA", + 8 + ], + [ + "A", + "AbCBBCaC", + 14 + ], + [ + "A", + "AbCb", + 6 + ], + [ + "A", + "AbcB", + 6 + ], + [ + "A", + "B", + 2 + ], + [ + "A", + "BA", + 2 + ], + [ + "A", + "BABbCc", + 10 + ], + [ + "A", + "BABca", + 8 + ], + [ + "A", + "BB", + 4 + ], + [ + "A", + "BBaBBaa", + 13 + ], + [ + "A", + "BBbbaAA", + 12 + ], + [ + "A", + "BCCAAc", + 10 + ], + [ + "A", + "BCa", + 5 + ], + [ + "A", + "BCcaC", + 9 + ], + [ + "A", + "BCccaa", + 11 + ], + [ + "A", + "BaacCbC", + 13 + ], + [ + "A", + "BabCC", + 9 + ], + [ + "A", + "Bac", + 5 + ], + [ + "A", + "BbCbb", + 10 + ], + [ + "A", + "BbaBAC", + 10 + ], + [ + "A", + "Bbc", + 6 + ], + [ + "A", + "BcB", + 6 + ], + [ + "A", + "BcCAbCBA", + 14 + ], + [ + "A", + "BcaaCbCB", + 15 + ], + [ + "A", + "C", + 2 + ], + [ + "A", + "CA", + 2 + ], + [ + "A", + "CABAacB", + 12 + ], + [ + "A", + "CABBABBc", + 14 + ], + [ + "A", + "CAaaBc", + 10 + ], + [ + "A", + "CBAA", + 6 + ], + [ + "A", + "CBCcBaBAB", + 16 + ], + [ + "A", + "CBcbc", + 10 + ], + [ + "A", + "CC", + 4 + ], + [ + "A", + "CCA", + 4 + ], + [ + "A", + "CCB", + 6 + ], + [ + "A", + "CCBaACcC", + 14 + ], + [ + "A", + "CCBcAAacb", + 16 + ], + [ + "A", + "CaCCaA", + 10 + ], + [ + "A", + "CbAB", + 6 + ], + [ + "A", + "CbBaAACC", + 14 + ], + [ + "A", + "CbCCbB", + 12 + ], + [ + "A", + "CbacBb", + 11 + ], + [ + "A", + "CbbABc", + 10 + ], + [ + "A", + "CcC", + 6 + ], + [ + "A", + "CcCacAAAC", + 16 + ], + [ + "A", + "CccCbaCcb", + 17 + ], + [ + "A", + "a", + 1 + ], + [ + "A", + "aABABBa", + 12 + ], + [ + "A", + "aABBA", + 8 + ], + [ + "A", + "aABCaBCa", + 14 + ], + [ + "A", + "aACBabAC", + 14 + ], + [ + "A", + "aBCb", + 7 + ], + [ + "A", + "aBaB", + 7 + ], + [ + "A", + "aBbBb", + 9 + ], + [ + "A", + "aC", + 3 + ], + [ + "A", + "aCA", + 4 + ], + [ + "A", + "aaBBb", + 9 + ], + [ + "A", + "aaC", + 5 + ], + [ + "A", + "aaCb", + 7 + ], + [ + "A", + "aaCbABbb", + 14 + ], + [ + "A", + "aaCcbb", + 11 + ], + [ + "A", + "aaaaCcAB", + 14 + ], + [ + "A", + "aaabb", + 9 + ], + [ + "A", + "aaacCabCC", + 17 + ], + [ + "A", + "aacBccCAC", + 16 + ], + [ + "A", + "aacC", + 7 + ], + [ + "A", + "abCAb", + 8 + ], + [ + "A", + "abbBcaccc", + 17 + ], + [ + "A", + "acCAB", + 8 + ], + [ + "A", + "acacBcAA", + 14 + ], + [ + "A", + "b", + 2 + ], + [ + "A", + "bABACaB", + 12 + ], + [ + "A", + "bAbA", + 6 + ], + [ + "A", + "bAbaBc", + 10 + ], + [ + "A", + "bBAa", + 6 + ], + [ + "A", + "bBa", + 5 + ], + [ + "A", + "bBaCAab", + 12 + ], + [ + "A", + "bBaCaCBbB", + 17 + ], + [ + "A", + "bBbAbaBa", + 14 + ], + [ + "A", + "bBbacabAb", + 16 + ], + [ + "A", + "bCCbA", + 8 + ], + [ + "A", + "bCCbB", + 10 + ], + [ + "A", + "bCbbACc", + 12 + ], + [ + "A", + "bCbbc", + 10 + ], + [ + "A", + "baACBCB", + 12 + ], + [ + "A", + "babABb", + 10 + ], + [ + "A", + "bacB", + 7 + ], + [ + "A", + "bacacA", + 10 + ], + [ + "A", + "bb", + 4 + ], + [ + "A", + "bbCa", + 7 + ], + [ + "A", + "bbCbaa", + 11 + ], + [ + "A", + "bbbAcb", + 10 + ], + [ + "A", + "bc", + 4 + ], + [ + "A", + "bcAAcCAb", + 14 + ], + [ + "A", + "bcC", + 6 + ], + [ + "A", + "bcbbaab", + 13 + ], + [ + "A", + "c", + 2 + ], + [ + "A", + "cAB", + 4 + ], + [ + "A", + "cACAc", + 8 + ], + [ + "A", + "cAaBccaC", + 14 + ], + [ + "A", + "cAcAaCAc", + 14 + ], + [ + "A", + "cBAaC", + 8 + ], + [ + "A", + "cBAac", + 8 + ], + [ + "A", + "cBCAABbc", + 14 + ], + [ + "A", + "cBaCbab", + 13 + ], + [ + "A", + "cBacA", + 8 + ], + [ + "A", + "cBb", + 6 + ], + [ + "A", + "cC", + 4 + ], + [ + "A", + "cCBABaC", + 12 + ], + [ + "A", + "cCCCa", + 9 + ], + [ + "A", + "cCa", + 5 + ], + [ + "A", + "cCaAaCaCB", + 16 + ], + [ + "A", + "cCabbbCa", + 15 + ], + [ + "A", + "caacCacAb", + 16 + ], + [ + "A", + "cabbC", + 9 + ], + [ + "A", + "cb", + 4 + ], + [ + "A", + "cbC", + 6 + ], + [ + "A", + "cbCAaAaAB", + 16 + ], + [ + "A", + "cbbaaAbbB", + 16 + ], + [ + "A", + "cc", + 4 + ], + [ + "A", + "ccCcCBaB", + 15 + ], + [ + "A", + "ccabbC", + 11 + ], + [ + "AA", + "AA", + 0 + ], + [ + "AA", + "ACAA", + 4 + ], + [ + "AA", + "BAc", + 4 + ], + [ + "AA", + "BC", + 4 + ], + [ + "AA", + "BaccaAA", + 10 + ], + [ + "AA", + "Bba", + 5 + ], + [ + "AA", + "BbcbcccAB", + 16 + ], + [ + "AA", + "CAb", + 4 + ], + [ + "AA", + "Cc", + 4 + ], + [ + "AA", + "CcBACCa", + 11 + ], + [ + "AA", + "aCBa", + 6 + ], + [ + "AA", + "aaBA", + 5 + ], + [ + "AA", + "aaBac", + 8 + ], + [ + "AA", + "bAAabBA", + 10 + ], + [ + "AA", + "bABbacbb", + 13 + ], + [ + "AA", + "bBbBbc", + 12 + ], + [ + "AA", + "bC", + 4 + ], + [ + "AA", + "bCabb", + 9 + ], + [ + "AA", + "baAB", + 5 + ], + [ + "AA", + "bbBaBcCBB", + 17 + ], + [ + "AA", + "bbBbAaaB", + 13 + ], + [ + "AA", + "c", + 4 + ], + [ + "AA", + "cACaCbab", + 13 + ], + [ + "AA", + "cBbCbBcA", + 14 + ], + [ + "AA", + "cBba", + 7 + ], + [ + "AA", + "cCbBBCca", + 15 + ], + [ + "AA", + "cacaca", + 10 + ], + [ + "AA", + "ccbccAa", + 11 + ], + [ + "AAA", + "B", + 6 + ], + [ + "AAA", + "C", + 6 + ], + [ + "AAA", + "aBBbcAaBa", + 14 + ], + [ + "AAA", + "aacbbBbbc", + 16 + ], + [ + "AAA", + "abAb", + 5 + ], + [ + "AAA", + "cccaAbBcB", + 15 + ], + [ + "AAAAABA", + "CaBcAaa", + 10 + ], + [ + "AAABACbC", + "BBBC", + 11 + ], + [ + "AAABAbaaA", + "CBbbacb", + 12 + ], + [ + "AAABa", + "AA", + 6 + ], + [ + "AAABc", + "cbBabcaBA", + 14 + ], + [ + "AAAC", + "acBcCCcC", + 13 + ], + [ + "AAACAbAaa", + "BCc", + 16 + ], + [ + "AAACBACc", + "CaCabAc", + 10 + ], + [ + "AAACCbbcA", + "bc", + 14 + ], + [ + "AAACa", + "A", + 8 + ], + [ + "AAACbCaa", + "acABAAa", + 9 + ], + [ + "AAACbaaa", + "BBa", + 13 + ], + [ + "AAAa", + "bBaaCc", + 9 + ], + [ + "AAAaAB", + "BCB", + 10 + ], + [ + "AAAaAcC", + "CAbBcBBC", + 12 + ], + [ + "AAAaCAAb", + "aBbAbaaA", + 12 + ], + [ + "AAAaCaA", + "cBcABaAb", + 11 + ], + [ + "AAAaaaaA", + "ABBBcaA", + 10 + ], + [ + "AAAb", + "AcC", + 6 + ], + [ + "AAAb", + "B", + 7 + ], + [ + "AAAbAB", + "cCBaAbcc", + 11 + ], + [ + "AAAbBcbc", + "C", + 15 + ], + [ + "AAAbaAABb", + "cCcAaca", + 15 + ], + [ + "AAAbbaA", + "Cbcc", + 12 + ], + [ + "AAAbbc", + "ABcaCCbca", + 11 + ], + [ + "AAAbcAcBA", + "bBaACAC", + 13 + ], + [ + "AAAbcbCa", + "cabCCbCba", + 10 + ], + [ + "AAAcAcCC", + "cbBCAAB", + 13 + ], + [ + "AAAcBAbCB", + "cbbABC", + 12 + ], + [ + "AAB", + "CB", + 4 + ], + [ + "AAB", + "accAC", + 7 + ], + [ + "AAB", + "bCCbaBbAc", + 15 + ], + [ + "AAB", + "bbb", + 5 + ], + [ + "AAB", + "bcCBcC", + 10 + ], + [ + "AABA", + "AAc", + 4 + ], + [ + "AABA", + "cBCAbA", + 7 + ], + [ + "AABABCcCc", + "abAC", + 12 + ], + [ + "AABAaB", + "BAB", + 6 + ], + [ + "AABAbAa", + "BcaB", + 11 + ], + [ + "AABAcb", + "cca", + 10 + ], + [ + "AABBA", + "AbAaCBb", + 8 + ], + [ + "AABBAACcC", + "A", + 16 + ], + [ + "AABBBcb", + "B", + 12 + ], + [ + "AABBCaB", + "bAbBA", + 8 + ], + [ + "AABBCabC", + "BCC", + 10 + ], + [ + "AABBCcB", + "cABBBAACc", + 10 + ], + [ + "AABBabAA", + "A", + 14 + ], + [ + "AABBac", + "BACCCB", + 10 + ], + [ + "AABBc", + "CAaBaA", + 7 + ], + [ + "AABCb", + "CcaCab", + 8 + ], + [ + "AABCbccb", + "B", + 14 + ], + [ + "AABCcA", + "BabC", + 8 + ], + [ + "AABCcB", + "BAB", + 8 + ], + [ + "AABCca", + "AbBBC", + 7 + ], + [ + "AABCcbBB", + "Bab", + 12 + ], + [ + "AABa", + "ACCcBA", + 7 + ], + [ + "AABa", + "BCcbaAa", + 11 + ], + [ + "AABa", + "C", + 8 + ], + [ + "AABaAc", + "Ccaa", + 9 + ], + [ + "AABaC", + "aA", + 7 + ], + [ + "AABaCccb", + "AABaAAbc", + 8 + ], + [ + "AABabcc", + "ccaABC", + 11 + ], + [ + "AABacB", + "cCbaa", + 9 + ], + [ + "AABacBac", + "AcAa", + 10 + ], + [ + "AABaccb", + "CcbBbbc", + 12 + ], + [ + "AABbBa", + "bBAcbaaB", + 10 + ], + [ + "AABbCc", + "AccbaB", + 8 + ], + [ + "AABba", + "cBbAc", + 7 + ], + [ + "AABbaBa", + "BBaAbb", + 10 + ], + [ + "AABc", + "BccAAA", + 10 + ], + [ + "AABcABaaA", + "cbB", + 14 + ], + [ + "AABcAC", + "acabAC", + 7 + ], + [ + "AABcBbcb", + "baAACAbAB", + 11 + ], + [ + "AABcCB", + "ca", + 10 + ], + [ + "AABcaBC", + "AaAaab", + 8 + ], + [ + "AAC", + "CBabAaB", + 11 + ], + [ + "AAC", + "aBA", + 5 + ], + [ + "AAC", + "aCBCBbac", + 13 + ], + [ + "AAC", + "aCa", + 5 + ], + [ + "AAC", + "baaBAba", + 11 + ], + [ + "AAC", + "bbAbc", + 7 + ], + [ + "AACA", + "aaCB", + 4 + ], + [ + "AACA", + "ab", + 7 + ], + [ + "AACA", + "cc", + 7 + ], + [ + "AACAba", + "CBAAaAB", + 9 + ], + [ + "AACAba", + "b", + 10 + ], + [ + "AACAbbc", + "AbaCABCcB", + 8 + ], + [ + "AACBACbcB", + "b", + 16 + ], + [ + "AACBC", + "Abbc", + 6 + ], + [ + "AACBC", + "aaCcAb", + 8 + ], + [ + "AACBCA", + "A", + 10 + ], + [ + "AACBCcbaa", + "cbBca", + 12 + ], + [ + "AACBaB", + "AAcABBA", + 7 + ], + [ + "AACBc", + "aABCaACA", + 10 + ], + [ + "AACC", + "bB", + 8 + ], + [ + "AACCA", + "b", + 10 + ], + [ + "AACCAC", + "Ccab", + 8 + ], + [ + "AACCBBAac", + "abbabb", + 14 + ], + [ + "AACCCCbc", + "BBCCaB", + 11 + ], + [ + "AACCCc", + "bcCbaBACA", + 14 + ], + [ + "AACCaBcA", + "BaC", + 13 + ], + [ + "AACCaca", + "ccbaBBaB", + 13 + ], + [ + "AACCc", + "b", + 10 + ], + [ + "AACa", + "BAC", + 4 + ], + [ + "AACaAaBA", + "AbcbB", + 11 + ], + [ + "AACaac", + "C", + 10 + ], + [ + "AACacB", + "CcbCBaBb", + 11 + ], + [ + "AACb", + "AC", + 4 + ], + [ + "AACb", + "ac", + 6 + ], + [ + "AACbAC", + "BBCCBCa", + 10 + ], + [ + "AACbC", + "bb", + 8 + ], + [ + "AACbbcaa", + "bbaaBCBb", + 14 + ], + [ + "AACbc", + "AbcbbBcCB", + 11 + ], + [ + "AACbc", + "aCCB", + 6 + ], + [ + "AACbcAaAb", + "BABcaBBAA", + 12 + ], + [ + "AACbcb", + "cabBc", + 8 + ], + [ + "AACc", + "BbCC", + 5 + ], + [ + "AACc", + "bbb", + 8 + ], + [ + "AACcAABAC", + "CBAcBaABa", + 11 + ], + [ + "AACcAb", + "CBCbCACcb", + 11 + ], + [ + "AACcCAAc", + "AbAACbCC", + 11 + ], + [ + "AACcabbC", + "cAAccbAB", + 9 + ], + [ + "AACcbA", + "BCCCcaCc", + 12 + ], + [ + "AAa", + "ACCC", + 6 + ], + [ + "AAa", + "BcAC", + 6 + ], + [ + "AAa", + "CACcaAAAb", + 13 + ], + [ + "AAa", + "CAaCA", + 6 + ], + [ + "AAa", + "aCcBACb", + 11 + ], + [ + "AAa", + "abACAA", + 7 + ], + [ + "AAa", + "b", + 6 + ], + [ + "AAa", + "cAAaBA", + 6 + ], + [ + "AAa", + "cBaB", + 6 + ], + [ + "AAaA", + "ca", + 6 + ], + [ + "AAaACcb", + "ABCcb", + 6 + ], + [ + "AAaB", + "aCAC", + 6 + ], + [ + "AAaB", + "cbAb", + 6 + ], + [ + "AAaBA", + "bBAc", + 8 + ], + [ + "AAaBB", + "ABCCaCBb", + 9 + ], + [ + "AAaBa", + "AcB", + 6 + ], + [ + "AAaBaB", + "aCcb", + 9 + ], + [ + "AAaBacBaC", + "CacABc", + 12 + ], + [ + "AAaBbAb", + "cC", + 14 + ], + [ + "AAaBbcaa", + "caB", + 12 + ], + [ + "AAaC", + "aCbBcBCB", + 13 + ], + [ + "AAaCACAB", + "cBa", + 14 + ], + [ + "AAaCCaCaA", + "baACABCCA", + 10 + ], + [ + "AAaCCcbb", + "aa", + 13 + ], + [ + "AAaCaccb", + "AAA", + 11 + ], + [ + "AAaCbAAAc", + "babcbBccb", + 14 + ], + [ + "AAaCcB", + "aA", + 9 + ], + [ + "AAaa", + "Abcbb", + 8 + ], + [ + "AAaaA", + "ACaCAcaa", + 9 + ], + [ + "AAaaB", + "cAaaAB", + 4 + ], + [ + "AAaaBbaC", + "bbCaCBc", + 12 + ], + [ + "AAaaCBabC", + "bBb", + 14 + ], + [ + "AAaacacca", + "C", + 17 + ], + [ + "AAaaccbA", + "CB", + 14 + ], + [ + "AAabAbac", + "cbABacbbc", + 11 + ], + [ + "AAabBBaA", + "caCcAAB", + 13 + ], + [ + "AAabCA", + "CbACAA", + 9 + ], + [ + "AAabCbCA", + "ACb", + 10 + ], + [ + "AAabb", + "B", + 9 + ], + [ + "AAabc", + "cBc", + 7 + ], + [ + "AAacA", + "CBBcB", + 8 + ], + [ + "AAacA", + "Cc", + 8 + ], + [ + "AAacCBCBc", + "bAaacCc", + 9 + ], + [ + "AAacCaBa", + "a", + 14 + ], + [ + "AAacCbCCC", + "BaB", + 15 + ], + [ + "AAaccABAA", + "bBCb", + 16 + ], + [ + "AAb", + "AbB", + 3 + ], + [ + "AAb", + "B", + 5 + ], + [ + "AAb", + "aCBbBBa", + 11 + ], + [ + "AAb", + "bAAc", + 4 + ], + [ + "AAb", + "bABA", + 5 + ], + [ + "AAb", + "bBCbBbaCA", + 16 + ], + [ + "AAb", + "bbBBaB", + 10 + ], + [ + "AAb", + "bbCcAb", + 8 + ], + [ + "AAbA", + "Bbb", + 6 + ], + [ + "AAbAAaBCC", + "b", + 16 + ], + [ + "AAbABB", + "Ca", + 11 + ], + [ + "AAbAaBBcB", + "BABaCB", + 10 + ], + [ + "AAbBBb", + "a", + 11 + ], + [ + "AAbBCCb", + "bA", + 12 + ], + [ + "AAbBbBcC", + "C", + 14 + ], + [ + "AAbBbbBcc", + "aCA", + 16 + ], + [ + "AAbC", + "cBbBCBBb", + 12 + ], + [ + "AAbCbBcC", + "BaABcCaCc", + 11 + ], + [ + "AAbCcCbC", + "a", + 15 + ], + [ + "AAba", + "cBCabCC", + 11 + ], + [ + "AAba", + "cBcBCcaBc", + 15 + ], + [ + "AAbaCabC", + "Aa", + 12 + ], + [ + "AAbabb", + "cbBAca", + 10 + ], + [ + "AAbb", + "AcbaaAB", + 9 + ], + [ + "AAbb", + "bccb", + 6 + ], + [ + "AAbbAcAB", + "cbacaBBBA", + 14 + ], + [ + "AAbbBAaAC", + "bcbaabc", + 11 + ], + [ + "AAbbbB", + "bCa", + 10 + ], + [ + "AAbcBbA", + "aaccCbB", + 8 + ], + [ + "AAbcaBBBA", + "ABb", + 13 + ], + [ + "AAbcacaB", + "cAAAbBb", + 12 + ], + [ + "AAbcbacC", + "abbbAaCCa", + 10 + ], + [ + "AAc", + "ACAc", + 2 + ], + [ + "AAc", + "AbB", + 4 + ], + [ + "AAc", + "BAabA", + 7 + ], + [ + "AAc", + "aAbc", + 3 + ], + [ + "AAc", + "aaaaacAA", + 12 + ], + [ + "AAc", + "aab", + 4 + ], + [ + "AAc", + "c", + 4 + ], + [ + "AAcA", + "AAbAAA", + 6 + ], + [ + "AAcABCA", + "bBBAbab", + 11 + ], + [ + "AAcAC", + "cCAAa", + 8 + ], + [ + "AAcAac", + "cAcA", + 6 + ], + [ + "AAcAbBcB", + "AAAAB", + 8 + ], + [ + "AAcAccAb", + "Ccac", + 11 + ], + [ + "AAcBBBcCB", + "A", + 16 + ], + [ + "AAcBbA", + "Aa", + 9 + ], + [ + "AAcC", + "bCbcaCCa", + 12 + ], + [ + "AAcCabaB", + "cACAC", + 11 + ], + [ + "AAcaACCBA", + "abcBCca", + 11 + ], + [ + "AAcaCBAcB", + "cCaBCcC", + 11 + ], + [ + "AAcab", + "A", + 8 + ], + [ + "AAcab", + "AcaabCccc", + 12 + ], + [ + "AAcb", + "aCBCcCBcC", + 14 + ], + [ + "AAcbAccc", + "CcccbA", + 12 + ], + [ + "AAcbCCAcB", + "BbbCaACc", + 11 + ], + [ + "AAcbCca", + "a", + 12 + ], + [ + "AAcbc", + "caCcb", + 7 + ], + [ + "AAcc", + "CcaBbcC", + 10 + ], + [ + "AAccB", + "cCca", + 7 + ], + [ + "AAccb", + "aA", + 7 + ], + [ + "AAccccbAA", + "caAaa", + 14 + ], + [ + "AB", + "A", + 2 + ], + [ + "AB", + "AACca", + 8 + ], + [ + "AB", + "ABcAc", + 6 + ], + [ + "AB", + "ACCACCbC", + 13 + ], + [ + "AB", + "BAA", + 4 + ], + [ + "AB", + "BAbac", + 7 + ], + [ + "AB", + "BC", + 4 + ], + [ + "AB", + "BbaCAc", + 10 + ], + [ + "AB", + "Bbac", + 7 + ], + [ + "AB", + "BcA", + 6 + ], + [ + "AB", + "CAAacB", + 8 + ], + [ + "AB", + "CC", + 4 + ], + [ + "AB", + "CCaabBcb", + 13 + ], + [ + "AB", + "CCcB", + 6 + ], + [ + "AB", + "CbA", + 5 + ], + [ + "AB", + "aCAC", + 6 + ], + [ + "AB", + "bBA", + 4 + ], + [ + "AB", + "bCbB", + 6 + ], + [ + "AB", + "bCccbbb", + 13 + ], + [ + "AB", + "bbb", + 5 + ], + [ + "AB", + "bcAbAAA", + 11 + ], + [ + "AB", + "bcbC", + 7 + ], + [ + "AB", + "c", + 4 + ], + [ + "AB", + "cCabccbCB", + 15 + ], + [ + "AB", + "caCBB", + 7 + ], + [ + "AB", + "caaac", + 9 + ], + [ + "AB", + "cababCa", + 12 + ], + [ + "ABA", + "A", + 4 + ], + [ + "ABA", + "ACBcBa", + 7 + ], + [ + "ABA", + "AcAb", + 4 + ], + [ + "ABA", + "abbBaaC", + 10 + ], + [ + "ABA", + "c", + 6 + ], + [ + "ABA", + "caAaCCbc", + 13 + ], + [ + "ABAAB", + "cbB", + 7 + ], + [ + "ABAABacbC", + "Ba", + 14 + ], + [ + "ABAAaCAa", + "cABb", + 14 + ], + [ + "ABAAaaBb", + "BCACaB", + 8 + ], + [ + "ABAAabb", + "bAcABc", + 9 + ], + [ + "ABAAabbCC", + "cbcBc", + 15 + ], + [ + "ABAAbBCb", + "aCACb", + 9 + ], + [ + "ABAAc", + "AbCc", + 5 + ], + [ + "ABAAcC", + "A", + 10 + ], + [ + "ABABBCaBb", + "aAcBcc", + 12 + ], + [ + "ABABCAB", + "cbBBCaA", + 8 + ], + [ + "ABABaaCc", + "BBBBBAB", + 11 + ], + [ + "ABABbCCab", + "aAC", + 13 + ], + [ + "ABAC", + "abaAC", + 4 + ], + [ + "ABACAccCC", + "BBCBcbCAc", + 11 + ], + [ + "ABACCAACA", + "aAacA", + 11 + ], + [ + "ABACaa", + "BA", + 8 + ], + [ + "ABACb", + "b", + 8 + ], + [ + "ABACbaCcC", + "cCBBbCbC", + 12 + ], + [ + "ABAa", + "A", + 6 + ], + [ + "ABAaAbbc", + "ccaCBA", + 13 + ], + [ + "ABAaB", + "bb", + 8 + ], + [ + "ABAaCCAB", + "acba", + 12 + ], + [ + "ABAaaBCBB", + "BaCC", + 12 + ], + [ + "ABAacbAbA", + "ABAb", + 10 + ], + [ + "ABAb", + "AcA", + 4 + ], + [ + "ABAb", + "cCab", + 5 + ], + [ + "ABAbACCB", + "cBCB", + 10 + ], + [ + "ABAbBC", + "BBAacabC", + 9 + ], + [ + "ABAbCCb", + "BAA", + 10 + ], + [ + "ABAbaCBB", + "aaCbbbBB", + 9 + ], + [ + "ABAbaCcC", + "bac", + 10 + ], + [ + "ABAc", + "CBACCbBA", + 11 + ], + [ + "ABAcAcB", + "Ac", + 10 + ], + [ + "ABAca", + "aCcCaAbC", + 12 + ], + [ + "ABAcaBc", + "bCaabABAb", + 14 + ], + [ + "ABAcaac", + "BcA", + 9 + ], + [ + "ABAcabA", + "aa", + 11 + ], + [ + "ABAcb", + "cCa", + 9 + ], + [ + "ABB", + "acaccCcA", + 15 + ], + [ + "ABB", + "bAaAAC", + 10 + ], + [ + "ABB", + "bBbAA", + 7 + ], + [ + "ABB", + "bac", + 6 + ], + [ + "ABBAAaCc", + "CaCaCAaCc", + 9 + ], + [ + "ABBAAbb", + "acBbCba", + 9 + ], + [ + "ABBAAc", + "bBccabAcB", + 11 + ], + [ + "ABBAbbAA", + "abAaaa", + 10 + ], + [ + "ABBAcBaa", + "Ab", + 13 + ], + [ + "ABBAcbAc", + "abBccbA", + 6 + ], + [ + "ABBBAa", + "ccBbcBa", + 9 + ], + [ + "ABBBAbAcc", + "abCaCAbcc", + 10 + ], + [ + "ABBBB", + "cAaCBCbCb", + 12 + ], + [ + "ABBBCaB", + "BaAbBabBa", + 12 + ], + [ + "ABBCC", + "aBBbaBAab", + 13 + ], + [ + "ABBCCc", + "aAcAbB", + 11 + ], + [ + "ABBCCcab", + "AcBcbcbAc", + 10 + ], + [ + "ABBa", + "bA", + 6 + ], + [ + "ABBaACA", + "cbBcAB", + 9 + ], + [ + "ABBaACCcb", + "bbCCcCb", + 10 + ], + [ + "ABBaa", + "bcabCCC", + 12 + ], + [ + "ABBabAbAC", + "AbcbbAcCc", + 10 + ], + [ + "ABBaba", + "BCcbAaBCA", + 13 + ], + [ + "ABBacb", + "CAbcBAbBa", + 11 + ], + [ + "ABBb", + "Aabc", + 5 + ], + [ + "ABBb", + "aAcAb", + 6 + ], + [ + "ABBbBAbCA", + "CCBACAAb", + 14 + ], + [ + "ABBbCbb", + "bccbcAc", + 11 + ], + [ + "ABBbb", + "aAabbCbCC", + 11 + ], + [ + "ABBcBBC", + "bCaB", + 10 + ], + [ + "ABBcCCC", + "bABbaCCC", + 5 + ], + [ + "ABBcb", + "aCc", + 7 + ], + [ + "ABBcbcC", + "AACBbAC", + 8 + ], + [ + "ABBccBcAa", + "ABa", + 12 + ], + [ + "ABBccCBA", + "CCCACa", + 12 + ], + [ + "ABBccc", + "B", + 10 + ], + [ + "ABC", + "BAaACA", + 8 + ], + [ + "ABC", + "BCc", + 4 + ], + [ + "ABC", + "CAa", + 6 + ], + [ + "ABC", + "CBca", + 5 + ], + [ + "ABC", + "CbCbbCB", + 11 + ], + [ + "ABC", + "bacacB", + 10 + ], + [ + "ABC", + "c", + 5 + ], + [ + "ABCAB", + "bAaAc", + 8 + ], + [ + "ABCAC", + "BaCBaC", + 7 + ], + [ + "ABCAa", + "aABbb", + 8 + ], + [ + "ABCAbAacA", + "cbCAa", + 11 + ], + [ + "ABCBC", + "AB", + 6 + ], + [ + "ABCBa", + "CcAACBC", + 8 + ], + [ + "ABCBa", + "caBbccC", + 10 + ], + [ + "ABCCAa", + "A", + 10 + ], + [ + "ABCCC", + "CC", + 6 + ], + [ + "ABCCbcBc", + "AbCBcBB", + 6 + ], + [ + "ABCCcCBB", + "bbccAbBBc", + 11 + ], + [ + "ABCCccaB", + "aCcACCCa", + 10 + ], + [ + "ABCaBa", + "BBb", + 8 + ], + [ + "ABCaBa", + "bbAcAA", + 10 + ], + [ + "ABCaC", + "bcCcab", + 8 + ], + [ + "ABCaa", + "AbCcaAb", + 6 + ], + [ + "ABCab", + "b", + 8 + ], + [ + "ABCabB", + "AAc", + 9 + ], + [ + "ABCb", + "CBBBC", + 7 + ], + [ + "ABCb", + "aABCcBC", + 7 + ], + [ + "ABCbAA", + "Ba", + 9 + ], + [ + "ABCbBBbc", + "cabbbCbcB", + 11 + ], + [ + "ABCbC", + "cc", + 8 + ], + [ + "ABCbCaCCc", + "aABB", + 15 + ], + [ + "ABCbaaCbb", + "CBbBBABBB", + 12 + ], + [ + "ABCbaaac", + "aaCaCCCca", + 13 + ], + [ + "ABCbbA", + "BCaAa", + 7 + ], + [ + "ABCbcC", + "ccbBBa", + 11 + ], + [ + "ABCc", + "Aa", + 6 + ], + [ + "ABCcAabbB", + "cCCaBBc", + 11 + ], + [ + "ABCcBcbC", + "Bcbcc", + 8 + ], + [ + "ABCcb", + "CacBAb", + 9 + ], + [ + "ABCccaAcC", + "BaAcBbC", + 12 + ], + [ + "ABa", + "AaabCa", + 7 + ], + [ + "ABa", + "CaA", + 5 + ], + [ + "ABaABc", + "caC", + 9 + ], + [ + "ABaAC", + "Caca", + 8 + ], + [ + "ABaAb", + "bAaC", + 7 + ], + [ + "ABaB", + "c", + 8 + ], + [ + "ABaBa", + "aacCAc", + 10 + ], + [ + "ABaBb", + "acbaBCcb", + 8 + ], + [ + "ABaBccB", + "BacbBBBcb", + 11 + ], + [ + "ABaCAb", + "aba", + 8 + ], + [ + "ABaCCC", + "aCAaacbc", + 10 + ], + [ + "ABaCc", + "bB", + 8 + ], + [ + "ABaa", + "CCcCC", + 10 + ], + [ + "ABabAbb", + "BCAcB", + 9 + ], + [ + "ABabBC", + "acc", + 9 + ], + [ + "ABabBaAc", + "AbBCbaBBB", + 12 + ], + [ + "ABababAC", + "aabaaBAA", + 8 + ], + [ + "ABabb", + "bBb", + 6 + ], + [ + "ABabcBacC", + "aC", + 14 + ], + [ + "ABabcBcc", + "BAcB", + 9 + ], + [ + "ABacCac", + "bbaCBcbcB", + 11 + ], + [ + "ABacbAAab", + "bC", + 16 + ], + [ + "ABacbbaCC", + "CbCbcbBAA", + 13 + ], + [ + "ABb", + "AaAcB", + 7 + ], + [ + "ABb", + "B", + 4 + ], + [ + "ABb", + "BB", + 3 + ], + [ + "ABb", + "BBaCCAAA", + 14 + ], + [ + "ABb", + "bBBaA", + 7 + ], + [ + "ABb", + "baCaaBaa", + 13 + ], + [ + "ABbA", + "CaACAABa", + 12 + ], + [ + "ABbACAC", + "BAcBBaB", + 12 + ], + [ + "ABbACAaAa", + "Cca", + 14 + ], + [ + "ABbAaa", + "cbacaa", + 7 + ], + [ + "ABbAaaB", + "BBc", + 11 + ], + [ + "ABbAacbAC", + "bAbAaacaa", + 11 + ], + [ + "ABbAbA", + "aaAaB", + 9 + ], + [ + "ABbBAb", + "a", + 11 + ], + [ + "ABbBcCbcA", + "acaAacBAB", + 15 + ], + [ + "ABbCC", + "caACcc", + 9 + ], + [ + "ABbCaAbb", + "b", + 14 + ], + [ + "ABbCb", + "aABCBBca", + 10 + ], + [ + "ABbCbA", + "A", + 10 + ], + [ + "ABbCbA", + "AbCbB", + 4 + ], + [ + "ABbCbbBa", + "B", + 14 + ], + [ + "ABbCcB", + "AaCccab", + 8 + ], + [ + "ABbaACBCc", + "baBCbCbcB", + 11 + ], + [ + "ABbaabcCC", + "aaaacAAAA", + 15 + ], + [ + "ABbacAAA", + "CAAccb", + 13 + ], + [ + "ABbb", + "cAaC", + 8 + ], + [ + "ABbbA", + "BCcbb", + 8 + ], + [ + "ABbbC", + "ABBc", + 4 + ], + [ + "ABbbbB", + "BCabaCc", + 12 + ], + [ + "ABbc", + "bBcAAac", + 10 + ], + [ + "ABbcc", + "AbBABaaa", + 11 + ], + [ + "ABbccBA", + "cACaCcCC", + 11 + ], + [ + "ABc", + "a", + 5 + ], + [ + "ABc", + "aA", + 5 + ], + [ + "ABc", + "b", + 5 + ], + [ + "ABcA", + "CB", + 6 + ], + [ + "ABcAa", + "BcbAC", + 6 + ], + [ + "ABcAaB", + "ab", + 9 + ], + [ + "ABcAbAa", + "AcAABbb", + 9 + ], + [ + "ABcAc", + "c", + 8 + ], + [ + "ABcAcCAc", + "cAcBcCaC", + 8 + ], + [ + "ABcBBcCCB", + "BaAcBbC", + 12 + ], + [ + "ABcBbAb", + "aAbACcAca", + 13 + ], + [ + "ABcBcCCbB", + "cbAC", + 13 + ], + [ + "ABcC", + "Cabc", + 6 + ], + [ + "ABcC", + "c", + 6 + ], + [ + "ABcCAaCc", + "C", + 14 + ], + [ + "ABcCAbCba", + "CcBa", + 12 + ], + [ + "ABcCBb", + "CAb", + 8 + ], + [ + "ABcCCa", + "bCaca", + 7 + ], + [ + "ABcCCcBa", + "Cbc", + 12 + ], + [ + "ABcCbbBbC", + "b", + 16 + ], + [ + "ABcaBC", + "Bcc", + 7 + ], + [ + "ABcaBb", + "CB", + 9 + ], + [ + "ABcb", + "a", + 7 + ], + [ + "ABcbAcc", + "AbBa", + 9 + ], + [ + "ABcbBC", + "cCcAa", + 10 + ], + [ + "ABcbCacCb", + "ba", + 14 + ], + [ + "ABcc", + "bAAcbCa", + 9 + ], + [ + "ABccA", + "CA", + 7 + ], + [ + "ABcccb", + "CB", + 10 + ], + [ + "AC", + "A", + 2 + ], + [ + "AC", + "AAb", + 4 + ], + [ + "AC", + "AB", + 2 + ], + [ + "AC", + "ABBc", + 5 + ], + [ + "AC", + "ABaaaBc", + 11 + ], + [ + "AC", + "ACBaAbb", + 10 + ], + [ + "AC", + "AaBcBC", + 8 + ], + [ + "AC", + "AaCCCB", + 8 + ], + [ + "AC", + "AabB", + 6 + ], + [ + "AC", + "AacAaBc", + 11 + ], + [ + "AC", + "AbBCacbA", + 12 + ], + [ + "AC", + "AbbbcbACb", + 14 + ], + [ + "AC", + "B", + 4 + ], + [ + "AC", + "BBbA", + 8 + ], + [ + "AC", + "BCaa", + 6 + ], + [ + "AC", + "BbCaaA", + 10 + ], + [ + "AC", + "BcAab", + 8 + ], + [ + "AC", + "C", + 2 + ], + [ + "AC", + "CAcb", + 5 + ], + [ + "AC", + "Ca", + 4 + ], + [ + "AC", + "CabAB", + 8 + ], + [ + "AC", + "aABaABAB", + 14 + ], + [ + "AC", + "aAacbbcAC", + 14 + ], + [ + "AC", + "aBCaCBba", + 13 + ], + [ + "AC", + "aa", + 3 + ], + [ + "AC", + "aaaBBabAb", + 16 + ], + [ + "AC", + "baccAbcB", + 13 + ], + [ + "AC", + "c", + 3 + ], + [ + "AC", + "cACCaBA", + 10 + ], + [ + "AC", + "cCaaAacaA", + 15 + ], + [ + "AC", + "cbcbbcC", + 12 + ], + [ + "ACA", + "Aa", + 3 + ], + [ + "ACA", + "C", + 4 + ], + [ + "ACA", + "CbaaBc", + 11 + ], + [ + "ACA", + "aAABAAcb", + 12 + ], + [ + "ACA", + "cACCbaAaC", + 12 + ], + [ + "ACAA", + "AcaAAb", + 5 + ], + [ + "ACAABBaC", + "A", + 14 + ], + [ + "ACAABcA", + "bCBACacC", + 10 + ], + [ + "ACAAC", + "bB", + 10 + ], + [ + "ACAAC", + "cBaaCabaC", + 11 + ], + [ + "ACAAa", + "CAa", + 4 + ], + [ + "ACAAaCaA", + "AAacb", + 9 + ], + [ + "ACAAbcaAa", + "bba", + 14 + ], + [ + "ACABA", + "bAB", + 6 + ], + [ + "ACABA", + "c", + 9 + ], + [ + "ACABABA", + "CcC", + 12 + ], + [ + "ACABACaB", + "bcBAaAB", + 8 + ], + [ + "ACABbCaBc", + "cA", + 15 + ], + [ + "ACAC", + "aaBAA", + 7 + ], + [ + "ACACB", + "aaCcbaBC", + 11 + ], + [ + "ACACBB", + "cCb", + 8 + ], + [ + "ACACBbccA", + "BABbAc", + 10 + ], + [ + "ACACC", + "BaAA", + 8 + ], + [ + "ACACa", + "Bccc", + 8 + ], + [ + "ACACbB", + "aCaacAaC", + 11 + ], + [ + "ACACbab", + "cC", + 11 + ], + [ + "ACAaA", + "Aaabbc", + 9 + ], + [ + "ACAaB", + "caBBcB", + 9 + ], + [ + "ACAaBA", + "CAbCC", + 8 + ], + [ + "ACAaCBccb", + "c", + 16 + ], + [ + "ACAabbCAc", + "BB", + 16 + ], + [ + "ACAb", + "AaaCC", + 7 + ], + [ + "ACAbBCaCA", + "A", + 16 + ], + [ + "ACAbbaaBA", + "aacacABbc", + 15 + ], + [ + "ACAbcB", + "bcBCB", + 7 + ], + [ + "ACAc", + "CCbcaabA", + 12 + ], + [ + "ACAcBCc", + "AcaAbcb", + 8 + ], + [ + "ACAcaabA", + "CACbBC", + 10 + ], + [ + "ACB", + "ACbbaBb", + 8 + ], + [ + "ACB", + "aCbbc", + 6 + ], + [ + "ACB", + "baBacBAB", + 12 + ], + [ + "ACB", + "cabbCcBA", + 11 + ], + [ + "ACBA", + "CbCCCaCAc", + 14 + ], + [ + "ACBAC", + "CaABbbcBA", + 13 + ], + [ + "ACBACBB", + "cAABCbBC", + 9 + ], + [ + "ACBACCba", + "ACBCcCb", + 5 + ], + [ + "ACBAbCBc", + "bC", + 12 + ], + [ + "ACBAba", + "aAaCaC", + 10 + ], + [ + "ACBAcb", + "aCACc", + 6 + ], + [ + "ACBB", + "bAbb", + 6 + ], + [ + "ACBBAB", + "BbBCb", + 8 + ], + [ + "ACBBABBa", + "bbabA", + 11 + ], + [ + "ACBBBaA", + "bccbA", + 10 + ], + [ + "ACBBBaCA", + "bCCCB", + 12 + ], + [ + "ACBBcAccc", + "ab", + 16 + ], + [ + "ACBCCC", + "a", + 11 + ], + [ + "ACBCbaa", + "ACCAbCCb", + 10 + ], + [ + "ACBaA", + "BcBcBcA", + 9 + ], + [ + "ACBaBa", + "AaAa", + 6 + ], + [ + "ACBabaa", + "abcAbbb", + 10 + ], + [ + "ACBabbab", + "CAa", + 11 + ], + [ + "ACBac", + "BcbcCb", + 9 + ], + [ + "ACBb", + "bcCAca", + 10 + ], + [ + "ACBbCaaBB", + "Cc", + 15 + ], + [ + "ACBba", + "CcaAbbc", + 10 + ], + [ + "ACBbaAbAC", + "aCabbAC", + 7 + ], + [ + "ACBbcAcB", + "cb", + 13 + ], + [ + "ACBcAB", + "cb", + 9 + ], + [ + "ACBcaaAAb", + "ACBA", + 10 + ], + [ + "ACC", + "BcccCaAba", + 15 + ], + [ + "ACC", + "Ccb", + 5 + ], + [ + "ACC", + "aB", + 5 + ], + [ + "ACC", + "bBcABBbAC", + 14 + ], + [ + "ACC", + "cABA", + 6 + ], + [ + "ACC", + "caACC", + 4 + ], + [ + "ACCA", + "BaaBc", + 9 + ], + [ + "ACCA", + "BacAabAAa", + 14 + ], + [ + "ACCACABB", + "ABAAbBaBa", + 11 + ], + [ + "ACCAbB", + "CcbAacC", + 11 + ], + [ + "ACCAccAB", + "ACbCC", + 10 + ], + [ + "ACCBAAC", + "Ac", + 11 + ], + [ + "ACCBAaBC", + "a", + 14 + ], + [ + "ACCBB", + "BcCccabbA", + 13 + ], + [ + "ACCBBcac", + "CCB", + 10 + ], + [ + "ACCBCBC", + "AcaaCacba", + 11 + ], + [ + "ACCBac", + "aCACaCc", + 7 + ], + [ + "ACCBb", + "BaCac", + 8 + ], + [ + "ACCBbcbAC", + "AAaCaCBCC", + 12 + ], + [ + "ACCBcCBB", + "aBBABb", + 10 + ], + [ + "ACCBcaaCa", + "CBb", + 14 + ], + [ + "ACCBcc", + "bbAa", + 11 + ], + [ + "ACCCAaCcC", + "CBAc", + 12 + ], + [ + "ACCCBac", + "CcCBACBB", + 9 + ], + [ + "ACCCC", + "CACCACc", + 5 + ], + [ + "ACCCb", + "CbBaCcb", + 9 + ], + [ + "ACCCbaCAc", + "abACCC", + 11 + ], + [ + "ACCaAACa", + "C", + 14 + ], + [ + "ACCaACAa", + "a", + 14 + ], + [ + "ACCaB", + "A", + 8 + ], + [ + "ACCaCA", + "a", + 10 + ], + [ + "ACCaaAc", + "A", + 12 + ], + [ + "ACCac", + "a", + 8 + ], + [ + "ACCbA", + "aCCBa", + 3 + ], + [ + "ACCbB", + "BaAa", + 10 + ], + [ + "ACCbC", + "CcbaCC", + 7 + ], + [ + "ACCbCba", + "a", + 12 + ], + [ + "ACCbaBbb", + "aA", + 14 + ], + [ + "ACCbba", + "aaCBCbccB", + 11 + ], + [ + "ACCbbbC", + "BCbABAbaA", + 13 + ], + [ + "ACCbcBa", + "aCBaBcbC", + 9 + ], + [ + "ACCbcbccB", + "caAAbaCcb", + 13 + ], + [ + "ACCcAccCc", + "AccAb", + 11 + ], + [ + "ACCcBcB", + "AcBcAAca", + 9 + ], + [ + "ACCcC", + "a", + 9 + ], + [ + "ACCcaC", + "cCA", + 8 + ], + [ + "ACCcacC", + "BBaaAcAab", + 14 + ], + [ + "ACa", + "AcbCAbaB", + 10 + ], + [ + "ACa", + "Bca", + 3 + ], + [ + "ACa", + "ba", + 4 + ], + [ + "ACa", + "baAAaba", + 10 + ], + [ + "ACaA", + "A", + 6 + ], + [ + "ACaA", + "ABCAba", + 6 + ], + [ + "ACaA", + "acbCc", + 8 + ], + [ + "ACaA", + "cc", + 7 + ], + [ + "ACaAC", + "cABCBAc", + 7 + ], + [ + "ACaAcABa", + "cCAACC", + 10 + ], + [ + "ACaB", + "ABAbccB", + 9 + ], + [ + "ACaB", + "bAAAaAbAA", + 13 + ], + [ + "ACaBBBCB", + "AaAC", + 10 + ], + [ + "ACaBBaAa", + "AcaBcBbcB", + 9 + ], + [ + "ACaBCB", + "cc", + 10 + ], + [ + "ACaBCBb", + "b", + 12 + ], + [ + "ACaBacCc", + "bb", + 15 + ], + [ + "ACaBcb", + "BcCc", + 9 + ], + [ + "ACaCACc", + "c", + 12 + ], + [ + "ACaCBccBc", + "CcABCcBcb", + 9 + ], + [ + "ACaCCBA", + "AAcacC", + 8 + ], + [ + "ACaa", + "BAAc", + 7 + ], + [ + "ACaaBAbc", + "ACAccba", + 9 + ], + [ + "ACaabb", + "BCAb", + 7 + ], + [ + "ACaacBa", + "cBCBAc", + 11 + ], + [ + "ACabABBA", + "CAcCbB", + 10 + ], + [ + "ACabC", + "B", + 9 + ], + [ + "ACabac", + "BACcbCcbB", + 10 + ], + [ + "ACabbcA", + "aCacc", + 7 + ], + [ + "ACaccaa", + "AA", + 11 + ], + [ + "ACb", + "A", + 4 + ], + [ + "ACb", + "cBAab", + 6 + ], + [ + "ACb", + "ccbccbB", + 11 + ], + [ + "ACbA", + "AaBacA", + 7 + ], + [ + "ACbA", + "BaCCbA", + 5 + ], + [ + "ACbA", + "abACa", + 7 + ], + [ + "ACbACcbaB", + "ccc", + 14 + ], + [ + "ACbAbaCBC", + "acbaba", + 9 + ], + [ + "ACbB", + "aCACBAbb", + 9 + ], + [ + "ACbBA", + "CACB", + 6 + ], + [ + "ACbBCC", + "bcbCaAB", + 11 + ], + [ + "ACbBa", + "B", + 8 + ], + [ + "ACbBaCab", + "cbB", + 11 + ], + [ + "ACbCCbBb", + "aaca", + 14 + ], + [ + "ACbCaA", + "bAbC", + 8 + ], + [ + "ACbCb", + "c", + 9 + ], + [ + "ACbCc", + "ABc", + 5 + ], + [ + "ACbCcbA", + "accAAAaCc", + 15 + ], + [ + "ACba", + "acABAcbC", + 11 + ], + [ + "ACba", + "bCabba", + 6 + ], + [ + "ACbaAaA", + "BaaAbcC", + 12 + ], + [ + "ACbaAbB", + "AaBbbbb", + 8 + ], + [ + "ACbaAc", + "ABaBbCBcB", + 12 + ], + [ + "ACbaCAC", + "bBcaC", + 8 + ], + [ + "ACbaCaB", + "cbaA", + 8 + ], + [ + "ACbaaaB", + "CAcA", + 10 + ], + [ + "ACbabABB", + "BCBABBAc", + 11 + ], + [ + "ACbabcac", + "ABBA", + 11 + ], + [ + "ACbbBB", + "cAbbaC", + 8 + ], + [ + "ACbbBb", + "abAAbCab", + 10 + ], + [ + "ACbbCc", + "AccCbBAAB", + 11 + ], + [ + "ACbbca", + "cbABC", + 9 + ], + [ + "ACbbccB", + "b", + 12 + ], + [ + "ACbcBBc", + "CBacBbCbA", + 11 + ], + [ + "ACbcCba", + "abBBc", + 10 + ], + [ + "ACbcCccA", + "BBaA", + 13 + ], + [ + "ACc", + "AABbabcbb", + 14 + ], + [ + "ACc", + "ABbCcC", + 6 + ], + [ + "ACc", + "ABcBaB", + 8 + ], + [ + "ACc", + "a", + 5 + ], + [ + "ACc", + "b", + 6 + ], + [ + "ACc", + "baCBbbCbc", + 13 + ], + [ + "ACc", + "bcAcC", + 6 + ], + [ + "ACc", + "c", + 4 + ], + [ + "ACcA", + "CbcBBcbb", + 13 + ], + [ + "ACcA", + "aBBA", + 5 + ], + [ + "ACcAAb", + "ccAa", + 6 + ], + [ + "ACcABac", + "cA", + 10 + ], + [ + "ACcAc", + "baC", + 8 + ], + [ + "ACcBCBbbB", + "aA", + 17 + ], + [ + "ACcBa", + "ABBbBAbca", + 12 + ], + [ + "ACcBa", + "abbaca", + 9 + ], + [ + "ACcBba", + "baaAcAcA", + 12 + ], + [ + "ACcBbaa", + "CbCcCCBAC", + 12 + ], + [ + "ACcC", + "AcCABAC", + 8 + ], + [ + "ACcCACb", + "CABB", + 9 + ], + [ + "ACcCC", + "ccabBBC", + 11 + ], + [ + "ACcCa", + "Bcb", + 8 + ], + [ + "ACcCacAa", + "CbCba", + 10 + ], + [ + "ACcCc", + "bbBCC", + 7 + ], + [ + "ACca", + "cBBCBcbC", + 12 + ], + [ + "ACcaCAb", + "aaA", + 9 + ], + [ + "ACcaaAb", + "CaCAc", + 8 + ], + [ + "ACcabc", + "AAACb", + 8 + ], + [ + "ACcac", + "abBCBCc", + 9 + ], + [ + "ACcbB", + "caBaa", + 10 + ], + [ + "ACcbC", + "aCA", + 7 + ], + [ + "ACcbaBb", + "aCACCCAaA", + 12 + ], + [ + "ACcbbC", + "cacb", + 8 + ], + [ + "ACcbcCBB", + "A", + 14 + ], + [ + "ACcc", + "Cca", + 4 + ], + [ + "ACcca", + "accBbB", + 8 + ], + [ + "ACccabBC", + "Bb", + 14 + ], + [ + "ACccb", + "C", + 8 + ], + [ + "ACccbCccb", + "BbCacaA", + 14 + ], + [ + "ACccca", + "A", + 10 + ], + [ + "Aa", + "A", + 2 + ], + [ + "Aa", + "AAcac", + 6 + ], + [ + "Aa", + "ABBa", + 4 + ], + [ + "Aa", + "AbAabCcB", + 12 + ], + [ + "Aa", + "AbCCCCbcC", + 16 + ], + [ + "Aa", + "AbccAA", + 9 + ], + [ + "Aa", + "B", + 4 + ], + [ + "Aa", + "BA", + 3 + ], + [ + "Aa", + "BB", + 4 + ], + [ + "Aa", + "BBaccBAc", + 14 + ], + [ + "Aa", + "BCAaBb", + 8 + ], + [ + "Aa", + "BaBBAc", + 10 + ], + [ + "Aa", + "BaBcCaBc", + 13 + ], + [ + "Aa", + "BaCc", + 6 + ], + [ + "Aa", + "BabcCcAb", + 14 + ], + [ + "Aa", + "BbBB", + 8 + ], + [ + "Aa", + "C", + 4 + ], + [ + "Aa", + "CAabcaaAB", + 14 + ], + [ + "Aa", + "CAbbCbCB", + 14 + ], + [ + "Aa", + "CBBaBccb", + 14 + ], + [ + "Aa", + "CBCAccba", + 12 + ], + [ + "Aa", + "a", + 2 + ], + [ + "Aa", + "aAc", + 4 + ], + [ + "Aa", + "aacb", + 5 + ], + [ + "Aa", + "acAAacaB", + 12 + ], + [ + "Aa", + "acaA", + 5 + ], + [ + "Aa", + "acbc", + 7 + ], + [ + "Aa", + "b", + 4 + ], + [ + "Aa", + "bBA", + 5 + ], + [ + "Aa", + "bBABbc", + 10 + ], + [ + "Aa", + "baABcc", + 10 + ], + [ + "Aa", + "babbc", + 8 + ], + [ + "Aa", + "bbabBCac", + 13 + ], + [ + "Aa", + "cAAB", + 5 + ], + [ + "Aa", + "cC", + 4 + ], + [ + "Aa", + "caCAB", + 8 + ], + [ + "Aa", + "ccabB", + 8 + ], + [ + "AaA", + "Acbc", + 6 + ], + [ + "AaA", + "BBAcB", + 8 + ], + [ + "AaA", + "BaAbb", + 6 + ], + [ + "AaA", + "CAcBB", + 8 + ], + [ + "AaA", + "Cc", + 6 + ], + [ + "AaA", + "a", + 4 + ], + [ + "AaA", + "bAcaab", + 7 + ], + [ + "AaA", + "bCbCac", + 10 + ], + [ + "AaA", + "bCcaBAa", + 10 + ], + [ + "AaA", + "cAbaCAbB", + 10 + ], + [ + "AaAA", + "bcacBb", + 10 + ], + [ + "AaAABca", + "aACbAbaa", + 9 + ], + [ + "AaAAbA", + "CAbA", + 6 + ], + [ + "AaAAbBCcc", + "bbcAb", + 14 + ], + [ + "AaAAcbcbB", + "aAcCCBba", + 11 + ], + [ + "AaABbA", + "BBaACcACA", + 12 + ], + [ + "AaABc", + "cCcaBB", + 9 + ], + [ + "AaABcBAbb", + "BABAbaB", + 11 + ], + [ + "AaACCAb", + "C", + 12 + ], + [ + "AaACCaac", + "aabBbAbCA", + 13 + ], + [ + "AaACa", + "BBb", + 10 + ], + [ + "AaAaABB", + "CABcCCcCA", + 16 + ], + [ + "AaAaBbCc", + "B", + 14 + ], + [ + "AaAaa", + "cba", + 8 + ], + [ + "AaAabb", + "CACAA", + 9 + ], + [ + "AaAaccCB", + "bAaacBbaA", + 12 + ], + [ + "AaAb", + "cABAcb", + 6 + ], + [ + "AaAbAaAb", + "a", + 14 + ], + [ + "AaAbAbbB", + "aA", + 12 + ], + [ + "AaAbBba", + "CCBac", + 12 + ], + [ + "AaAbb", + "BbaB", + 8 + ], + [ + "AaAbbc", + "cAAcCC", + 8 + ], + [ + "AaAbc", + "a", + 8 + ], + [ + "AaAc", + "aAaCA", + 6 + ], + [ + "AaAcA", + "BCAAAba", + 8 + ], + [ + "AaAccaBbc", + "baAcAACaa", + 11 + ], + [ + "AaB", + "AbbAbb", + 8 + ], + [ + "AaB", + "Bca", + 6 + ], + [ + "AaB", + "bbaAb", + 7 + ], + [ + "AaB", + "bcABBBCc", + 12 + ], + [ + "AaB", + "caAb", + 5 + ], + [ + "AaBA", + "cBAB", + 6 + ], + [ + "AaBACC", + "BCAAbB", + 10 + ], + [ + "AaBACaBA", + "cAc", + 13 + ], + [ + "AaBAa", + "c", + 10 + ], + [ + "AaBAc", + "CcACba", + 10 + ], + [ + "AaBAcBcaa", + "cb", + 15 + ], + [ + "AaBBAC", + "ACAca", + 9 + ], + [ + "AaBBAcbcc", + "CbCcBb", + 14 + ], + [ + "AaBBbcA", + "A", + 12 + ], + [ + "AaBCcbCB", + "CCcAb", + 11 + ], + [ + "AaBa", + "abA", + 4 + ], + [ + "AaBa", + "bbbCabA", + 10 + ], + [ + "AaBaaaCBa", + "A", + 16 + ], + [ + "AaBabBCb", + "aBac", + 9 + ], + [ + "AaBbB", + "bBaa", + 8 + ], + [ + "AaBba", + "ab", + 6 + ], + [ + "AaBbba", + "caAbBAa", + 7 + ], + [ + "AaBbbaac", + "Cbcca", + 12 + ], + [ + "AaBbbbA", + "AabcBAa", + 7 + ], + [ + "AaBc", + "bAaaBaCCB", + 11 + ], + [ + "AaBcA", + "aCbCbB", + 9 + ], + [ + "AaBcAbBC", + "CBCACaBBA", + 12 + ], + [ + "AaBccbA", + "BBcaaccb", + 10 + ], + [ + "AaC", + "AACcabcAa", + 13 + ], + [ + "AaC", + "ABAaabA", + 10 + ], + [ + "AaC", + "Acc", + 3 + ], + [ + "AaC", + "aCCB", + 5 + ], + [ + "AaC", + "bbbbbbAA", + 15 + ], + [ + "AaCA", + "CCc", + 6 + ], + [ + "AaCAAAcac", + "ABB", + 16 + ], + [ + "AaCAAbaa", + "CCbABc", + 11 + ], + [ + "AaCACCa", + "BCcBACc", + 10 + ], + [ + "AaCACCbcc", + "CAacc", + 10 + ], + [ + "AaCAcAcB", + "bbA", + 14 + ], + [ + "AaCB", + "BbBC", + 8 + ], + [ + "AaCB", + "bCCbBAA", + 10 + ], + [ + "AaCBa", + "ACAbC", + 7 + ], + [ + "AaCBaC", + "Ba", + 8 + ], + [ + "AaCBaaAAC", + "CaBc", + 13 + ], + [ + "AaCBbBBa", + "CBbAcCBb", + 12 + ], + [ + "AaCCAAC", + "ACaBb", + 9 + ], + [ + "AaCCAbcBB", + "BCaab", + 13 + ], + [ + "AaCCCB", + "AaaAA", + 8 + ], + [ + "AaCCCBB", + "bB", + 11 + ], + [ + "AaCCcbB", + "BCcaCcB", + 9 + ], + [ + "AaCCcc", + "cbc", + 9 + ], + [ + "AaCaAAa", + "ccccBbcaC", + 15 + ], + [ + "AaCaCccb", + "aCB", + 11 + ], + [ + "AaCaaaA", + "a", + 12 + ], + [ + "AaCaac", + "CBabAA", + 10 + ], + [ + "AaCac", + "AbaBC", + 7 + ], + [ + "AaCbbbBaB", + "ccC", + 16 + ], + [ + "AaCbcCb", + "ccAAaB", + 12 + ], + [ + "AaCc", + "a", + 6 + ], + [ + "AaCcABAa", + "B", + 14 + ], + [ + "AaCcAbC", + "Bb", + 12 + ], + [ + "AaCcBBcc", + "cBb", + 11 + ], + [ + "AaCcaCBaA", + "ABca", + 12 + ], + [ + "AaCcab", + "bBcB", + 9 + ], + [ + "AaCcacA", + "BBBAcbC", + 13 + ], + [ + "AaCcbBbCa", + "BBBAaabCb", + 14 + ], + [ + "AaCcc", + "abcBAb", + 10 + ], + [ + "AaCccBBCb", + "cB", + 14 + ], + [ + "AaCccbC", + "baaaaAb", + 11 + ], + [ + "Aaa", + "BaAA", + 5 + ], + [ + "Aaa", + "CbabcBBB", + 14 + ], + [ + "Aaa", + "aAa", + 2 + ], + [ + "Aaa", + "aBB", + 5 + ], + [ + "Aaa", + "bAAbBaBcc", + 13 + ], + [ + "Aaa", + "ca", + 4 + ], + [ + "AaaA", + "aBabbB", + 9 + ], + [ + "AaaA", + "baCb", + 6 + ], + [ + "AaaAAC", + "a", + 10 + ], + [ + "AaaAAaC", + "b", + 14 + ], + [ + "AaaACAcbA", + "CBAcAC", + 12 + ], + [ + "AaaACa", + "BABcccC", + 11 + ], + [ + "AaaAbBAab", + "bacccCc", + 16 + ], + [ + "AaaAcBCB", + "Bbbb", + 14 + ], + [ + "AaaAcb", + "AcabAA", + 8 + ], + [ + "AaaB", + "aaCAC", + 6 + ], + [ + "AaaBABa", + "bBaC", + 11 + ], + [ + "AaaBCaCC", + "c", + 15 + ], + [ + "AaaBa", + "CBCBc", + 8 + ], + [ + "AaaC", + "aaAc", + 3 + ], + [ + "AaaC", + "b", + 8 + ], + [ + "AaaC", + "caaBCAABc", + 12 + ], + [ + "AaaCB", + "ABcbBCCA", + 12 + ], + [ + "AaaCcbcc", + "B", + 15 + ], + [ + "Aaaa", + "abCBCBa", + 11 + ], + [ + "AaaaA", + "CccAB", + 9 + ], + [ + "AaaaBcb", + "BCabBBBC", + 11 + ], + [ + "AaaaCCC", + "BBcaacaCB", + 11 + ], + [ + "AaaacbC", + "CcAcBACcb", + 13 + ], + [ + "AaabA", + "cB", + 9 + ], + [ + "AaabACBca", + "bAc", + 12 + ], + [ + "AaabCAC", + "bCaacCbB", + 10 + ], + [ + "Aaaba", + "BbccCaa", + 12 + ], + [ + "AaabaBba", + "aBaB", + 9 + ], + [ + "Aaababb", + "BcbBCcc", + 13 + ], + [ + "AaabcBb", + "abab", + 8 + ], + [ + "Aaac", + "BAbaab", + 6 + ], + [ + "AaacACBc", + "ACbbCaABA", + 12 + ], + [ + "AaaccCBcb", + "CBabaCACb", + 11 + ], + [ + "AaacccCc", + "c", + 14 + ], + [ + "Aab", + "BcBaaCBC", + 12 + ], + [ + "Aab", + "CBBaACcBA", + 15 + ], + [ + "Aab", + "a", + 4 + ], + [ + "AabA", + "acCbacA", + 9 + ], + [ + "AabAAcBBB", + "aa", + 15 + ], + [ + "AabAbBbcB", + "AcCcA", + 14 + ], + [ + "AabAccB", + "AcabBCb", + 8 + ], + [ + "AabBABc", + "AAabbCcCc", + 9 + ], + [ + "AabBCAaC", + "aBcCbc", + 10 + ], + [ + "AabBCC", + "A", + 10 + ], + [ + "AabBaBcBB", + "cbcc", + 14 + ], + [ + "AabBacAaa", + "aAc", + 13 + ], + [ + "AabBba", + "bcabb", + 8 + ], + [ + "AabBbc", + "CcAaA", + 12 + ], + [ + "AabBcBca", + "Ca", + 13 + ], + [ + "AabBcbc", + "ac", + 10 + ], + [ + "AabCbA", + "B", + 11 + ], + [ + "AabCbC", + "ccBbc", + 8 + ], + [ + "Aaba", + "BBaa", + 6 + ], + [ + "AabaACCC", + "aaBBcccCa", + 10 + ], + [ + "AabaCCccc", + "BaB", + 15 + ], + [ + "AabbA", + "AB", + 7 + ], + [ + "AabbABCBb", + "aBB", + 12 + ], + [ + "AabbB", + "AA", + 7 + ], + [ + "AabbB", + "bCCC", + 10 + ], + [ + "AabbbbbC", + "bBbBaB", + 10 + ], + [ + "AabbcCACc", + "AAa", + 14 + ], + [ + "Aabc", + "bBCbc", + 6 + ], + [ + "Aabc", + "bbA", + 6 + ], + [ + "AabcAAbCc", + "Aa", + 14 + ], + [ + "AabcBBb", + "bAbAcCBB", + 8 + ], + [ + "AabcBb", + "bb", + 8 + ], + [ + "AabcC", + "BbbBcbbC", + 10 + ], + [ + "AabcbCa", + "CB", + 12 + ], + [ + "Aac", + "Bccc", + 6 + ], + [ + "Aac", + "CBABCbaA", + 12 + ], + [ + "Aac", + "Cb", + 6 + ], + [ + "Aac", + "a", + 4 + ], + [ + "Aac", + "aBbCCaaa", + 13 + ], + [ + "Aac", + "baBAcA", + 8 + ], + [ + "Aac", + "c", + 4 + ], + [ + "Aac", + "caAABac", + 8 + ], + [ + "AacA", + "ACcBA", + 4 + ], + [ + "AacA", + "BaaAccBcA", + 11 + ], + [ + "AacAABbaa", + "a", + 16 + ], + [ + "AacABAB", + "CCc", + 12 + ], + [ + "AacAcbbC", + "cbCa", + 12 + ], + [ + "AacBBCc", + "BcBAA", + 10 + ], + [ + "AacBaA", + "AAa", + 7 + ], + [ + "AacBbaCBB", + "CcbC", + 12 + ], + [ + "AacBbcccc", + "CbACCaBab", + 18 + ], + [ + "AacC", + "BcBcAbb", + 12 + ], + [ + "AacCaBcaB", + "CAAb", + 13 + ], + [ + "AacCacC", + "CaABC", + 9 + ], + [ + "AacCcCcAC", + "CCBBabBA", + 16 + ], + [ + "AacCcc", + "Aab", + 8 + ], + [ + "AacaaCc", + "bAaA", + 10 + ], + [ + "AacacB", + "aaBBB", + 7 + ], + [ + "AacacBC", + "CBBcAcba", + 10 + ], + [ + "AacacBb", + "AAabbcaC", + 10 + ], + [ + "Aacb", + "c", + 6 + ], + [ + "AacbAAA", + "BbcBaCCCb", + 14 + ], + [ + "Aacbaa", + "aCBbbCaAc", + 12 + ], + [ + "Aacc", + "ACAA", + 6 + ], + [ + "Aacc", + "CBAcB", + 7 + ], + [ + "AaccAB", + "baAcAcbcc", + 11 + ], + [ + "AaccABc", + "bB", + 12 + ], + [ + "AaccAaAb", + "acb", + 10 + ], + [ + "AaccB", + "ac", + 6 + ], + [ + "AaccBcc", + "BC", + 11 + ], + [ + "AaccC", + "bAbacBAa", + 10 + ], + [ + "AaccaAc", + "Bc", + 12 + ], + [ + "AaccaBa", + "B", + 12 + ], + [ + "AaccaCcBb", + "bABCca", + 13 + ], + [ + "Aaccac", + "c", + 10 + ], + [ + "AacccAa", + "AC", + 11 + ], + [ + "AacccAcC", + "ab", + 14 + ], + [ + "AacccBBcC", + "Bb", + 15 + ], + [ + "Ab", + "A", + 2 + ], + [ + "Ab", + "AA", + 2 + ], + [ + "Ab", + "AaabCAAA", + 12 + ], + [ + "Ab", + "AbACAaCAA", + 14 + ], + [ + "Ab", + "AbCCAAACc", + 14 + ], + [ + "Ab", + "AbCbAa", + 8 + ], + [ + "Ab", + "Ac", + 2 + ], + [ + "Ab", + "AcaABbc", + 10 + ], + [ + "Ab", + "BAcCa", + 8 + ], + [ + "Ab", + "BBc", + 5 + ], + [ + "Ab", + "BbcAcCCaa", + 16 + ], + [ + "Ab", + "CABa", + 5 + ], + [ + "Ab", + "CAaB", + 5 + ], + [ + "Ab", + "CCBcAbbc", + 12 + ], + [ + "Ab", + "CaBc", + 6 + ], + [ + "Ab", + "CbBCAbaBc", + 14 + ], + [ + "Ab", + "aCAccA", + 10 + ], + [ + "Ab", + "aab", + 3 + ], + [ + "Ab", + "acaCBAa", + 12 + ], + [ + "Ab", + "bA", + 4 + ], + [ + "Ab", + "bCBc", + 7 + ], + [ + "Ab", + "c", + 4 + ], + [ + "Ab", + "cBBB", + 7 + ], + [ + "Ab", + "cC", + 4 + ], + [ + "Ab", + "cCAaBbbBC", + 14 + ], + [ + "Ab", + "cCaAcc", + 10 + ], + [ + "Ab", + "caA", + 5 + ], + [ + "Ab", + "caCacCcBC", + 16 + ], + [ + "Ab", + "cbcacAC", + 12 + ], + [ + "Ab", + "ccAbB", + 6 + ], + [ + "Ab", + "ccb", + 4 + ], + [ + "AbA", + "BCBAaC", + 9 + ], + [ + "AbA", + "BbBAaA", + 8 + ], + [ + "AbA", + "CcBa", + 6 + ], + [ + "AbA", + "aAC", + 5 + ], + [ + "AbA", + "b", + 4 + ], + [ + "AbA", + "caABB", + 7 + ], + [ + "AbA", + "ccc", + 6 + ], + [ + "AbAA", + "CBba", + 6 + ], + [ + "AbAAC", + "BAAC", + 3 + ], + [ + "AbAAC", + "bbab", + 7 + ], + [ + "AbAACaAb", + "C", + 14 + ], + [ + "AbAACbbBB", + "BCbaa", + 13 + ], + [ + "AbAAbC", + "caCaAAAbA", + 11 + ], + [ + "AbAAcbBa", + "BabBBCa", + 11 + ], + [ + "AbAB", + "Ab", + 4 + ], + [ + "AbAB", + "Bcb", + 6 + ], + [ + "AbAB", + "ac", + 7 + ], + [ + "AbABCa", + "cC", + 10 + ], + [ + "AbABa", + "BAaaCB", + 9 + ], + [ + "AbACABc", + "aBCACA", + 8 + ], + [ + "AbACBCA", + "aBB", + 10 + ], + [ + "AbACaa", + "AcAba", + 6 + ], + [ + "AbACbA", + "A", + 10 + ], + [ + "AbACbAA", + "aACA", + 7 + ], + [ + "AbACccccb", + "cCbbCBA", + 15 + ], + [ + "AbAaABB", + "BcaaA", + 9 + ], + [ + "AbAaAb", + "CB", + 11 + ], + [ + "AbAaC", + "AacbbACba", + 11 + ], + [ + "AbAaCAab", + "CabaacCaA", + 9 + ], + [ + "AbAaaa", + "AaC", + 8 + ], + [ + "AbAacaaac", + "abACABAc", + 8 + ], + [ + "AbAb", + "bbccBB", + 9 + ], + [ + "AbAbCba", + "BCbA", + 8 + ], + [ + "AbAbabac", + "bc", + 12 + ], + [ + "AbAbbBaab", + "bbabb", + 10 + ], + [ + "AbAc", + "BcbBCbC", + 11 + ], + [ + "AbAcACAa", + "cBcBBA", + 11 + ], + [ + "AbAcB", + "c", + 8 + ], + [ + "AbAcbCbca", + "AcBaaB", + 13 + ], + [ + "AbAccAbBc", + "aACcAACbA", + 11 + ], + [ + "AbAccBCa", + "BACCAaA", + 10 + ], + [ + "AbB", + "AABC", + 4 + ], + [ + "AbB", + "AbCbCCc", + 9 + ], + [ + "AbB", + "BcaAbAAAb", + 13 + ], + [ + "AbB", + "bBBA", + 5 + ], + [ + "AbB", + "cAaaaB", + 8 + ], + [ + "AbB", + "cbbABB", + 7 + ], + [ + "AbBAcCAC", + "CAAbcCC", + 9 + ], + [ + "AbBB", + "AAAAC", + 8 + ], + [ + "AbBBabc", + "Bcb", + 10 + ], + [ + "AbBBbCaA", + "AaCccAAA", + 11 + ], + [ + "AbBBcaAaa", + "bcbBbcCb", + 13 + ], + [ + "AbBCAacC", + "c", + 14 + ], + [ + "AbBCAcaa", + "aa", + 12 + ], + [ + "AbBCBbA", + "abbcBb", + 5 + ], + [ + "AbBaABC", + "AabAAbc", + 6 + ], + [ + "AbBaBB", + "AAaAca", + 9 + ], + [ + "AbBaCC", + "CAb", + 10 + ], + [ + "AbBaaAb", + "ACcBcca", + 11 + ], + [ + "AbBabBa", + "bccBAbb", + 10 + ], + [ + "AbBb", + "A", + 6 + ], + [ + "AbBb", + "BbaAB", + 7 + ], + [ + "AbBbA", + "babCBABbb", + 11 + ], + [ + "AbBbAABc", + "AbAa", + 9 + ], + [ + "AbBbCb", + "bcAACCcac", + 15 + ], + [ + "AbBbb", + "aCAC", + 9 + ], + [ + "AbBbbacbC", + "CcbccAb", + 14 + ], + [ + "AbBbcb", + "Ab", + 8 + ], + [ + "AbBbcbabC", + "Ba", + 14 + ], + [ + "AbBcBaaCc", + "BbcAB", + 13 + ], + [ + "AbBcaaCCA", + "aba", + 13 + ], + [ + "AbBcb", + "BAaAcb", + 6 + ], + [ + "AbBcc", + "AaccBc", + 6 + ], + [ + "AbBcccB", + "cB", + 10 + ], + [ + "AbC", + "BccBcC", + 9 + ], + [ + "AbC", + "C", + 4 + ], + [ + "AbCAA", + "CCcCcacBa", + 14 + ], + [ + "AbCABa", + "ACBC", + 6 + ], + [ + "AbCACa", + "BcaBacAA", + 12 + ], + [ + "AbCACcBbB", + "C", + 16 + ], + [ + "AbCAc", + "BbCbcBCAb", + 12 + ], + [ + "AbCB", + "Caa", + 8 + ], + [ + "AbCB", + "acbAc", + 7 + ], + [ + "AbCB", + "caaaba", + 10 + ], + [ + "AbCBbB", + "BacABACaB", + 13 + ], + [ + "AbCBbbC", + "cACb", + 10 + ], + [ + "AbCCcAbc", + "abB", + 12 + ], + [ + "AbCCca", + "C", + 10 + ], + [ + "AbCCcacba", + "aaAaabcb", + 13 + ], + [ + "AbCa", + "CcAaCAaA", + 10 + ], + [ + "AbCa", + "aBcccBBa", + 11 + ], + [ + "AbCaA", + "bBbAB", + 8 + ], + [ + "AbCaAAbab", + "BCbCcb", + 13 + ], + [ + "AbCaC", + "AbABC", + 4 + ], + [ + "AbCaabBCB", + "Cb", + 14 + ], + [ + "AbCabbc", + "BcCaB", + 9 + ], + [ + "AbCacAacb", + "aaAAAAC", + 12 + ], + [ + "AbCb", + "A", + 6 + ], + [ + "AbCb", + "BbaBcaCb", + 10 + ], + [ + "AbCbC", + "Cc", + 7 + ], + [ + "AbCbaB", + "aCac", + 7 + ], + [ + "AbCc", + "bAaCac", + 6 + ], + [ + "AbCcBBACC", + "cACC", + 10 + ], + [ + "AbCcbaBCA", + "cccCAbbCA", + 11 + ], + [ + "Aba", + "ACA", + 3 + ], + [ + "Aba", + "C", + 6 + ], + [ + "Aba", + "aB", + 4 + ], + [ + "Aba", + "bccccA", + 11 + ], + [ + "Aba", + "cabbcC", + 9 + ], + [ + "AbaAACBCb", + "CACabC", + 13 + ], + [ + "AbaAabca", + "CBCBCA", + 12 + ], + [ + "AbaAb", + "cb", + 8 + ], + [ + "AbaB", + "aCaB", + 3 + ], + [ + "AbaBAaCbC", + "cbbacCbA", + 10 + ], + [ + "AbaBAbaB", + "cbaC", + 12 + ], + [ + "AbaBBcbAA", + "bCaaC", + 14 + ], + [ + "AbaBCa", + "B", + 10 + ], + [ + "AbaBCbaB", + "acBcb", + 10 + ], + [ + "AbaBaca", + "acAAABBB", + 13 + ], + [ + "AbaBcCba", + "accBCABAB", + 12 + ], + [ + "AbaC", + "BAAb", + 7 + ], + [ + "AbaC", + "aA", + 6 + ], + [ + "AbaCb", + "B", + 9 + ], + [ + "AbaCbBc", + "ACBAaCAcA", + 11 + ], + [ + "Abaa", + "aAcBb", + 8 + ], + [ + "Abaa", + "cbbAaabCc", + 12 + ], + [ + "AbaaAbab", + "CCaaBc", + 11 + ], + [ + "AbaaAc", + "bAba", + 8 + ], + [ + "AbaaabCBb", + "aa", + 14 + ], + [ + "Abab", + "bbbBb", + 6 + ], + [ + "Abab", + "cab", + 4 + ], + [ + "AbabBBb", + "CaAAc", + 12 + ], + [ + "AbabCC", + "CACcAabA", + 12 + ], + [ + "AbabcCbb", + "AbcCcbB", + 7 + ], + [ + "AbacAa", + "bCAAabcCa", + 10 + ], + [ + "AbacB", + "CBaCBAcBa", + 11 + ], + [ + "AbacBCc", + "B", + 12 + ], + [ + "AbacBbBCC", + "bC", + 14 + ], + [ + "AbacaaCB", + "B", + 14 + ], + [ + "AbacaaaBC", + "AacAa", + 9 + ], + [ + "Abacb", + "AcccbAb", + 8 + ], + [ + "Abb", + "Aba", + 2 + ], + [ + "Abb", + "Ac", + 4 + ], + [ + "Abb", + "BCcba", + 8 + ], + [ + "AbbA", + "BCb", + 6 + ], + [ + "AbbABab", + "baacCBb", + 11 + ], + [ + "AbbACbab", + "ccAcA", + 12 + ], + [ + "AbbAcA", + "CabbA", + 7 + ], + [ + "AbbB", + "b", + 6 + ], + [ + "AbbBbCbAC", + "bCCaBA", + 13 + ], + [ + "AbbBbb", + "BBcAbaAbB", + 11 + ], + [ + "AbbBcaaBa", + "aAAAaCAba", + 13 + ], + [ + "AbbCACaB", + "CbBBAbcB", + 9 + ], + [ + "AbbCB", + "AAC", + 6 + ], + [ + "AbbCBbCA", + "aAa", + 14 + ], + [ + "AbbCCA", + "bBBcbaAcC", + 13 + ], + [ + "AbbCCaBCB", + "AabbCB", + 9 + ], + [ + "AbbCCcAAb", + "ABCbbBCC", + 13 + ], + [ + "AbbCaCCa", + "B", + 15 + ], + [ + "AbbCbBC", + "Cc", + 11 + ], + [ + "AbbCcA", + "BaaCcBac", + 11 + ], + [ + "AbbaBacBC", + "BaCaCBcC", + 10 + ], + [ + "Abbaa", + "aCbBbc", + 8 + ], + [ + "Abbb", + "bBab", + 5 + ], + [ + "Abbbba", + "BbbaA", + 6 + ], + [ + "AbbcBbA", + "cCbCcaC", + 11 + ], + [ + "Abc", + "CBAaABCCc", + 13 + ], + [ + "Abc", + "Cab", + 5 + ], + [ + "Abc", + "ba", + 4 + ], + [ + "Abc", + "cCBCa", + 8 + ], + [ + "AbcAAAa", + "CBcBBAabc", + 11 + ], + [ + "AbcABaa", + "cCcBCb", + 10 + ], + [ + "AbcAcA", + "B", + 11 + ], + [ + "AbcB", + "AbaCBBaA", + 9 + ], + [ + "AbcBAA", + "BAAb", + 8 + ], + [ + "AbcBBaBB", + "CCBACAA", + 13 + ], + [ + "AbcBCcAA", + "abbABCcCa", + 8 + ], + [ + "AbcCACAbB", + "aBcCb", + 10 + ], + [ + "AbcCAacab", + "a", + 16 + ], + [ + "AbcCa", + "cBAaab", + 9 + ], + [ + "AbcCbbc", + "ACccaBbAB", + 10 + ], + [ + "AbcaA", + "cac", + 6 + ], + [ + "AbcaBABac", + "aA", + 14 + ], + [ + "AbcaBbBcA", + "CBbA", + 11 + ], + [ + "AbcaCAAAB", + "ac", + 15 + ], + [ + "AbcacabA", + "ABbaAC", + 10 + ], + [ + "Abcb", + "AbCCcbb", + 6 + ], + [ + "AbcbA", + "b", + 8 + ], + [ + "AbcbABc", + "bCBCabbBb", + 12 + ], + [ + "AbcbB", + "A", + 8 + ], + [ + "AbcbbC", + "bABbBAa", + 10 + ], + [ + "Abcc", + "bAABaA", + 9 + ], + [ + "Abcc", + "cAABAAa", + 11 + ], + [ + "AbccB", + "cA", + 8 + ], + [ + "Abccc", + "bba", + 8 + ], + [ + "Ac", + "ACbAa", + 7 + ], + [ + "Ac", + "AbB", + 4 + ], + [ + "Ac", + "BCB", + 5 + ], + [ + "Ac", + "BCacCBaBb", + 15 + ], + [ + "Ac", + "BaaCB", + 8 + ], + [ + "Ac", + "BacBbABCa", + 15 + ], + [ + "Ac", + "Bacc", + 5 + ], + [ + "Ac", + "BbaBaACcC", + 14 + ], + [ + "Ac", + "BccaAa", + 10 + ], + [ + "Ac", + "CA", + 4 + ], + [ + "Ac", + "CABacA", + 8 + ], + [ + "Ac", + "CABbbCA", + 11 + ], + [ + "Ac", + "CAa", + 4 + ], + [ + "Ac", + "CBCaAcBaB", + 14 + ], + [ + "Ac", + "CCA", + 5 + ], + [ + "Ac", + "CCcbBBc", + 12 + ], + [ + "Ac", + "CbBBBBbBA", + 18 + ], + [ + "Ac", + "Cbba", + 8 + ], + [ + "Ac", + "aCaa", + 6 + ], + [ + "Ac", + "aCbca", + 7 + ], + [ + "Ac", + "aaBC", + 6 + ], + [ + "Ac", + "aaCAa", + 8 + ], + [ + "Ac", + "aaaA", + 7 + ], + [ + "Ac", + "aabca", + 7 + ], + [ + "Ac", + "abcAAaB", + 11 + ], + [ + "Ac", + "acaBBbaAC", + 15 + ], + [ + "Ac", + "bAaa", + 6 + ], + [ + "Ac", + "bCCCCC", + 11 + ], + [ + "Ac", + "baAcB", + 6 + ], + [ + "Ac", + "bc", + 2 + ], + [ + "Ac", + "cB", + 4 + ], + [ + "Ac", + "cBaaaAAAb", + 16 + ], + [ + "Ac", + "cC", + 3 + ], + [ + "Ac", + "cCAcbCA", + 10 + ], + [ + "Ac", + "cCcCAAA", + 12 + ], + [ + "Ac", + "cbAAcc", + 8 + ], + [ + "AcA", + "ABAACCbc", + 12 + ], + [ + "AcA", + "BBBb", + 8 + ], + [ + "AcA", + "CcabCab", + 11 + ], + [ + "AcA", + "acA", + 1 + ], + [ + "AcA", + "bAbCc", + 7 + ], + [ + "AcA", + "bccBB", + 8 + ], + [ + "AcA", + "cCCA", + 5 + ], + [ + "AcAAAb", + "Acba", + 7 + ], + [ + "AcAABAc", + "bCaa", + 11 + ], + [ + "AcAABBc", + "c", + 12 + ], + [ + "AcAACA", + "cCb", + 8 + ], + [ + "AcAACBb", + "AbaA", + 9 + ], + [ + "AcAAbb", + "abBbA", + 9 + ], + [ + "AcAAcBaB", + "caB", + 10 + ], + [ + "AcABCCba", + "Ca", + 12 + ], + [ + "AcABa", + "aAbBBCA", + 9 + ], + [ + "AcAC", + "c", + 6 + ], + [ + "AcACB", + "aBBCbBabC", + 13 + ], + [ + "AcACCBA", + "c", + 12 + ], + [ + "AcACCaACA", + "aCAAAcABC", + 12 + ], + [ + "AcACaA", + "Ac", + 8 + ], + [ + "AcACcC", + "bABBAcC", + 8 + ], + [ + "AcACccA", + "CaacccB", + 8 + ], + [ + "AcAa", + "b", + 8 + ], + [ + "AcAaaCBA", + "abB", + 12 + ], + [ + "AcAac", + "BBCCC", + 9 + ], + [ + "AcAb", + "cCBBcBCAc", + 14 + ], + [ + "AcAbA", + "cCbbBcb", + 11 + ], + [ + "AcAbBabb", + "BBCBa", + 12 + ], + [ + "AcAbBcABC", + "baCcCcb", + 15 + ], + [ + "AcAbCB", + "ccCCaC", + 10 + ], + [ + "AcAba", + "CcBcBcC", + 11 + ], + [ + "AcAbb", + "bAAbc", + 6 + ], + [ + "AcAcB", + "aAcBAbC", + 8 + ], + [ + "AcAcCB", + "bc", + 10 + ], + [ + "AcAcCCCbb", + "BAaBC", + 14 + ], + [ + "AcAcbacA", + "cb", + 12 + ], + [ + "AcB", + "AbCbCa", + 8 + ], + [ + "AcB", + "CCABca", + 8 + ], + [ + "AcB", + "aBA", + 5 + ], + [ + "AcB", + "b", + 5 + ], + [ + "AcB", + "bCB", + 3 + ], + [ + "AcB", + "cBBaB", + 8 + ], + [ + "AcB", + "caBcC", + 7 + ], + [ + "AcB", + "caCCCaA", + 12 + ], + [ + "AcBAAa", + "ac", + 9 + ], + [ + "AcBAbbAA", + "ACCB", + 12 + ], + [ + "AcBB", + "AAAccBcA", + 10 + ], + [ + "AcBB", + "BaccCCACc", + 15 + ], + [ + "AcBB", + "bBCA", + 8 + ], + [ + "AcBB", + "cCAaaBaBb", + 12 + ], + [ + "AcBBAC", + "AaCA", + 8 + ], + [ + "AcBBACA", + "aAA", + 9 + ], + [ + "AcBBACCaC", + "abBcCAC", + 8 + ], + [ + "AcBBaB", + "aC", + 10 + ], + [ + "AcBBbbaBc", + "CC", + 16 + ], + [ + "AcBBbcb", + "ABBAAc", + 8 + ], + [ + "AcBBcabc", + "a", + 14 + ], + [ + "AcBC", + "ACabcCbBB", + 12 + ], + [ + "AcBC", + "AacAcBCcA", + 10 + ], + [ + "AcBC", + "bCbcAbbA", + 13 + ], + [ + "AcBCAcb", + "AB", + 10 + ], + [ + "AcBCCaAbc", + "ca", + 14 + ], + [ + "AcBCCb", + "aCcCAccc", + 11 + ], + [ + "AcBCaccAA", + "cBAcc", + 9 + ], + [ + "AcBCb", + "aBbaBac", + 11 + ], + [ + "AcBCcbCb", + "AAABCa", + 11 + ], + [ + "AcBCcbbaB", + "bBbC", + 14 + ], + [ + "AcBa", + "BBbCBAA", + 10 + ], + [ + "AcBaCCbCa", + "bbBBb", + 14 + ], + [ + "AcBaCCc", + "aaCcca", + 8 + ], + [ + "AcBaacCb", + "BBbbCbcC", + 13 + ], + [ + "AcBbAb", + "BabcbBbc", + 11 + ], + [ + "AcBbAc", + "cbAbC", + 7 + ], + [ + "AcBbaac", + "bA", + 11 + ], + [ + "AcBbbbB", + "ACaa", + 11 + ], + [ + "AcBc", + "abAcbb", + 7 + ], + [ + "AcBcAcA", + "aaCBAaAAa", + 11 + ], + [ + "AcBcBBB", + "a", + 13 + ], + [ + "AcBcCba", + "BCb", + 8 + ], + [ + "AcBca", + "Ab", + 7 + ], + [ + "AcBcbbA", + "ABb", + 8 + ], + [ + "AcBcbbA", + "BB", + 11 + ], + [ + "AcBcbcA", + "B", + 12 + ], + [ + "AcBccbbbC", + "CbBAAbB", + 13 + ], + [ + "AcBcccC", + "b", + 13 + ], + [ + "AcC", + "ACAbc", + 6 + ], + [ + "AcC", + "bBBA", + 8 + ], + [ + "AcC", + "bbCBACbcA", + 14 + ], + [ + "AcC", + "c", + 4 + ], + [ + "AcC", + "cBBa", + 8 + ], + [ + "AcCACC", + "bbAcCCcc", + 8 + ], + [ + "AcCACaCA", + "CBcCCB", + 11 + ], + [ + "AcCAb", + "bCBAACBC", + 12 + ], + [ + "AcCAbA", + "Bac", + 11 + ], + [ + "AcCAbcaBb", + "Cb", + 14 + ], + [ + "AcCAcCCCA", + "AcCC", + 10 + ], + [ + "AcCBA", + "a", + 9 + ], + [ + "AcCBBaBb", + "AC", + 12 + ], + [ + "AcCBba", + "CaaBCAa", + 10 + ], + [ + "AcCCAA", + "BcA", + 8 + ], + [ + "AcCCBcc", + "bbBACCa", + 13 + ], + [ + "AcCCCbb", + "AcaAc", + 9 + ], + [ + "AcCCb", + "bb", + 8 + ], + [ + "AcCCba", + "BC", + 10 + ], + [ + "AcCCcBACB", + "cb", + 15 + ], + [ + "AcCCccCB", + "baaCaAaB", + 12 + ], + [ + "AcCa", + "AAaCcC", + 8 + ], + [ + "AcCaAcccA", + "AaaaBaCBB", + 13 + ], + [ + "AcCaBCACC", + "a", + 16 + ], + [ + "AcCaC", + "CAcC", + 6 + ], + [ + "AcCaa", + "Ccab", + 6 + ], + [ + "AcCabb", + "BbCBa", + 9 + ], + [ + "AcCb", + "A", + 6 + ], + [ + "AcCbA", + "BaCcaC", + 9 + ], + [ + "AcCbA", + "aA", + 7 + ], + [ + "AcCbBb", + "CCAcb", + 7 + ], + [ + "AcCba", + "cBBbCbCc", + 12 + ], + [ + "AcCbac", + "cCBa", + 5 + ], + [ + "AcCbbbc", + "BbBbABCBc", + 12 + ], + [ + "AcCbc", + "ABBaaAc", + 10 + ], + [ + "AcCc", + "BBBAA", + 10 + ], + [ + "AcCc", + "CABBBCaCb", + 13 + ], + [ + "AcCc", + "acCbACCcc", + 11 + ], + [ + "AcCcA", + "AbCbabBc", + 11 + ], + [ + "AcCcABb", + "cCBaAc", + 9 + ], + [ + "AcCcBB", + "AAaCAaA", + 10 + ], + [ + "AcCcabBCB", + "BcA", + 15 + ], + [ + "AcCcb", + "bC", + 8 + ], + [ + "AcCccABB", + "bbCbbCB", + 12 + ], + [ + "AcCccbBBb", + "ACABAa", + 12 + ], + [ + "Aca", + "BaAA", + 6 + ], + [ + "Aca", + "CCBCCB", + 11 + ], + [ + "Aca", + "cA", + 3 + ], + [ + "AcaAAA", + "CcbbaB", + 9 + ], + [ + "AcaABAaCb", + "CcCACC", + 12 + ], + [ + "AcaABCa", + "bacAcA", + 9 + ], + [ + "AcaAcBC", + "ccbAaa", + 10 + ], + [ + "AcaBACCb", + "ACacBaBAb", + 8 + ], + [ + "AcaBAabCb", + "ACACAbaCB", + 9 + ], + [ + "AcaBC", + "ABacC", + 4 + ], + [ + "AcaBCa", + "AbBC", + 6 + ], + [ + "AcaBacc", + "CBB", + 11 + ], + [ + "AcaBcba", + "AbAbCBcC", + 10 + ], + [ + "AcaC", + "Aca", + 2 + ], + [ + "AcaCB", + "C", + 8 + ], + [ + "AcaCBB", + "cbacccC", + 11 + ], + [ + "AcaCBb", + "CCcaBC", + 8 + ], + [ + "AcaCa", + "bCA", + 7 + ], + [ + "AcaCaC", + "BB", + 12 + ], + [ + "AcaCbcC", + "aBBCccaC", + 9 + ], + [ + "AcaCc", + "CaaCBBb", + 10 + ], + [ + "AcaCc", + "aBaCb", + 5 + ], + [ + "AcaCcAc", + "acA", + 8 + ], + [ + "Acaa", + "BACcCA", + 7 + ], + [ + "AcaaA", + "bacbCca", + 10 + ], + [ + "Acaaa", + "ACccca", + 6 + ], + [ + "AcaaaaaBA", + "b", + 17 + ], + [ + "AcaaabbAC", + "AACbc", + 12 + ], + [ + "AcaabBaAc", + "aCAbBBCaA", + 10 + ], + [ + "AcaacaAAB", + "CA", + 15 + ], + [ + "AcaacbaC", + "A", + 14 + ], + [ + "Acab", + "AB", + 5 + ], + [ + "AcabA", + "BCcca", + 8 + ], + [ + "AcabBAcB", + "B", + 14 + ], + [ + "AcabCaab", + "cCCaBB", + 9 + ], + [ + "AcabcC", + "AC", + 8 + ], + [ + "Acabca", + "cCCC", + 9 + ], + [ + "AcacaAbbb", + "abB", + 13 + ], + [ + "AcacaBC", + "bbaCB", + 9 + ], + [ + "AcacaCCCc", + "aBbbcACA", + 14 + ], + [ + "AcaccB", + "aaBc", + 7 + ], + [ + "Acb", + "BcbA", + 4 + ], + [ + "Acb", + "BccCaB", + 9 + ], + [ + "Acb", + "aC", + 4 + ], + [ + "Acb", + "bAccAa", + 8 + ], + [ + "Acb", + "ccAcbaB", + 8 + ], + [ + "AcbA", + "cA", + 4 + ], + [ + "AcbAAcaA", + "Cba", + 11 + ], + [ + "AcbAB", + "cbBbAa", + 8 + ], + [ + "AcbACBAaA", + "cc", + 15 + ], + [ + "AcbB", + "C", + 7 + ], + [ + "AcbBa", + "aAABbACcB", + 13 + ], + [ + "AcbBaCb", + "bCcacBbA", + 12 + ], + [ + "AcbBaba", + "CbbCBaB", + 9 + ], + [ + "AcbBb", + "abBbA", + 5 + ], + [ + "AcbC", + "bbCaA", + 8 + ], + [ + "AcbCAC", + "CcACABBb", + 10 + ], + [ + "AcbCAc", + "aaBCaAbAa", + 12 + ], + [ + "AcbCBcc", + "aA", + 13 + ], + [ + "AcbCaCb", + "ccAABC", + 10 + ], + [ + "AcbCcBCa", + "bbbcAcB", + 11 + ], + [ + "AcbCcbCa", + "CcaABBcCa", + 11 + ], + [ + "Acba", + "aACbbBcc", + 11 + ], + [ + "AcbaCAA", + "bAaBbaca", + 10 + ], + [ + "Acbab", + "acBc", + 6 + ], + [ + "AcbbAcCa", + "cCb", + 12 + ], + [ + "AcbbC", + "B", + 9 + ], + [ + "Acbbb", + "cCbCAACA", + 13 + ], + [ + "AcbbcAB", + "cca", + 9 + ], + [ + "Acbc", + "AbCaCB", + 8 + ], + [ + "Acbc", + "Bac", + 6 + ], + [ + "AcbcBB", + "ABBBB", + 5 + ], + [ + "AcbcBcA", + "AaaBaba", + 11 + ], + [ + "AcbcCbcbA", + "ac", + 15 + ], + [ + "Acc", + "BbBCABBb", + 14 + ], + [ + "Acc", + "aAbBbBca", + 12 + ], + [ + "Acc", + "aa", + 5 + ], + [ + "Acc", + "aaBcC", + 6 + ], + [ + "Acc", + "bCbAaCab", + 13 + ], + [ + "AccA", + "BCBA", + 5 + ], + [ + "AccA", + "aC", + 6 + ], + [ + "AccAB", + "Bcb", + 7 + ], + [ + "AccABcbBC", + "AAcBcAcc", + 9 + ], + [ + "AccACBbA", + "c", + 14 + ], + [ + "AccAbcC", + "cbbB", + 10 + ], + [ + "AccBbab", + "bcAaaaA", + 10 + ], + [ + "AccC", + "BBbca", + 8 + ], + [ + "AccCBBACa", + "b", + 17 + ], + [ + "AccCCCcaa", + "aabC", + 15 + ], + [ + "AccCcAA", + "CCbAaABCA", + 13 + ], + [ + "Acca", + "C", + 7 + ], + [ + "Acca", + "aB", + 7 + ], + [ + "AccaCABA", + "CBBBc", + 13 + ], + [ + "AccaaAbbC", + "BaAB", + 13 + ], + [ + "Accb", + "baBaaCaCa", + 15 + ], + [ + "Accbbbb", + "bA", + 12 + ], + [ + "Accbcc", + "aaAAcb", + 9 + ], + [ + "Accc", + "ABbAB", + 8 + ], + [ + "AcccAC", + "BAAbCacBb", + 13 + ], + [ + "AcccAbbB", + "BaBCa", + 14 + ], + [ + "AcccBAAbC", + "CCbCb", + 13 + ], + [ + "AcccCACac", + "BAbccaC", + 11 + ], + [ + "AcccCabab", + "bBAAaBaA", + 13 + ], + [ + "AcccCb", + "BACacbcC", + 9 + ], + [ + "AcccaCb", + "CBBCcaCB", + 8 + ], + [ + "Acccac", + "acCaAcaCb", + 9 + ], + [ + "B", + "A", + 2 + ], + [ + "B", + "AAABB", + 8 + ], + [ + "B", + "AAAcc", + 10 + ], + [ + "B", + "AABBcC", + 10 + ], + [ + "B", + "AABCBb", + 10 + ], + [ + "B", + "AAC", + 6 + ], + [ + "B", + "AACA", + 8 + ], + [ + "B", + "AACaaaa", + 14 + ], + [ + "B", + "AAcaBa", + 10 + ], + [ + "B", + "AAcacbab", + 15 + ], + [ + "B", + "ABBc", + 6 + ], + [ + "B", + "ABCBcBCB", + 14 + ], + [ + "B", + "ABaAba", + 10 + ], + [ + "B", + "ABaB", + 6 + ], + [ + "B", + "ABaBba", + 10 + ], + [ + "B", + "ABaaCcBa", + 14 + ], + [ + "B", + "ABc", + 4 + ], + [ + "B", + "ACB", + 4 + ], + [ + "B", + "ACCCCCBc", + 14 + ], + [ + "B", + "ACbbC", + 9 + ], + [ + "B", + "ACbbCA", + 11 + ], + [ + "B", + "AaA", + 6 + ], + [ + "B", + "AaACbbaaB", + 16 + ], + [ + "B", + "AaAaCCbaa", + 17 + ], + [ + "B", + "AaBaBcba", + 14 + ], + [ + "B", + "AabcAaa", + 13 + ], + [ + "B", + "AacCacAb", + 15 + ], + [ + "B", + "AaccbBacB", + 16 + ], + [ + "B", + "Ab", + 3 + ], + [ + "B", + "AbBc", + 6 + ], + [ + "B", + "AbaBCcaBa", + 16 + ], + [ + "B", + "Abc", + 5 + ], + [ + "B", + "AcA", + 6 + ], + [ + "B", + "AcBA", + 6 + ], + [ + "B", + "AcBaBbCc", + 14 + ], + [ + "B", + "AcCc", + 8 + ], + [ + "B", + "AcaC", + 8 + ], + [ + "B", + "AccBacc", + 12 + ], + [ + "B", + "B", + 0 + ], + [ + "B", + "BAA", + 4 + ], + [ + "B", + "BBAbCc", + 10 + ], + [ + "B", + "BBAccA", + 10 + ], + [ + "B", + "BBBCb", + 8 + ], + [ + "B", + "BBa", + 4 + ], + [ + "B", + "BBaAcacab", + 16 + ], + [ + "B", + "BBc", + 4 + ], + [ + "B", + "BC", + 2 + ], + [ + "B", + "BCC", + 4 + ], + [ + "B", + "BCCbaBA", + 12 + ], + [ + "B", + "BCbCb", + 8 + ], + [ + "B", + "BCcC", + 6 + ], + [ + "B", + "BCcCccC", + 12 + ], + [ + "B", + "BCcb", + 6 + ], + [ + "B", + "BCcc", + 6 + ], + [ + "B", + "Ba", + 2 + ], + [ + "B", + "BaBCAaCAa", + 16 + ], + [ + "B", + "Baca", + 6 + ], + [ + "B", + "BacbcaCaC", + 16 + ], + [ + "B", + "BbcCCbAbb", + 16 + ], + [ + "B", + "BcACbAAC", + 14 + ], + [ + "B", + "BcACbbbc", + 14 + ], + [ + "B", + "BcabCBbab", + 16 + ], + [ + "B", + "C", + 2 + ], + [ + "B", + "CAAb", + 7 + ], + [ + "B", + "CAAba", + 9 + ], + [ + "B", + "CACcA", + 10 + ], + [ + "B", + "CB", + 2 + ], + [ + "B", + "CBCcAcbb", + 14 + ], + [ + "B", + "CBc", + 4 + ], + [ + "B", + "CBcA", + 6 + ], + [ + "B", + "CBcCC", + 8 + ], + [ + "B", + "CCaaCaac", + 16 + ], + [ + "B", + "CCcBBCb", + 12 + ], + [ + "B", + "Ca", + 4 + ], + [ + "B", + "CaCC", + 8 + ], + [ + "B", + "Caa", + 6 + ], + [ + "B", + "Cab", + 5 + ], + [ + "B", + "Cacbc", + 9 + ], + [ + "B", + "Cb", + 3 + ], + [ + "B", + "Cbc", + 5 + ], + [ + "B", + "CbcaAaACC", + 17 + ], + [ + "B", + "CbccCbca", + 15 + ], + [ + "B", + "Cc", + 4 + ], + [ + "B", + "CcAacCAA", + 16 + ], + [ + "B", + "CcBb", + 6 + ], + [ + "B", + "CcbBb", + 8 + ], + [ + "B", + "Ccc", + 6 + ], + [ + "B", + "a", + 2 + ], + [ + "B", + "aAA", + 6 + ], + [ + "B", + "aAACAb", + 11 + ], + [ + "B", + "aABCB", + 8 + ], + [ + "B", + "aACaCCBbA", + 16 + ], + [ + "B", + "aB", + 2 + ], + [ + "B", + "aBBbc", + 8 + ], + [ + "B", + "aBabc", + 8 + ], + [ + "B", + "aBcbCA", + 10 + ], + [ + "B", + "aBccCCBC", + 14 + ], + [ + "B", + "aC", + 4 + ], + [ + "B", + "aCBBAAc", + 12 + ], + [ + "B", + "aCBcA", + 8 + ], + [ + "B", + "aCCaAabB", + 14 + ], + [ + "B", + "aCCcbbac", + 15 + ], + [ + "B", + "aCa", + 6 + ], + [ + "B", + "aCaBABACa", + 16 + ], + [ + "B", + "aCcbCA", + 11 + ], + [ + "B", + "aaBBac", + 10 + ], + [ + "B", + "aaBCC", + 8 + ], + [ + "B", + "aab", + 5 + ], + [ + "B", + "aabBcbBa", + 14 + ], + [ + "B", + "aacbAB", + 10 + ], + [ + "B", + "abA", + 5 + ], + [ + "B", + "abAAA", + 9 + ], + [ + "B", + "abBBCBBcb", + 16 + ], + [ + "B", + "abC", + 5 + ], + [ + "B", + "abCcacAC", + 15 + ], + [ + "B", + "ac", + 4 + ], + [ + "B", + "acAbAB", + 10 + ], + [ + "B", + "acBcBba", + 12 + ], + [ + "B", + "b", + 1 + ], + [ + "B", + "bA", + 3 + ], + [ + "B", + "bAAbcbb", + 13 + ], + [ + "B", + "bABAacc", + 12 + ], + [ + "B", + "bACA", + 7 + ], + [ + "B", + "bAaAbBbcb", + 16 + ], + [ + "B", + "bAc", + 5 + ], + [ + "B", + "bB", + 2 + ], + [ + "B", + "bC", + 3 + ], + [ + "B", + "bCAbccaCA", + 17 + ], + [ + "B", + "bCCA", + 7 + ], + [ + "B", + "bCabCB", + 10 + ], + [ + "B", + "bCabcCa", + 13 + ], + [ + "B", + "ba", + 3 + ], + [ + "B", + "baba", + 7 + ], + [ + "B", + "babaa", + 9 + ], + [ + "B", + "bb", + 3 + ], + [ + "B", + "bbc", + 5 + ], + [ + "B", + "bbcbCCCb", + 15 + ], + [ + "B", + "bc", + 3 + ], + [ + "B", + "bcCBCacb", + 14 + ], + [ + "B", + "bcaAcbbB", + 14 + ], + [ + "B", + "c", + 2 + ], + [ + "B", + "cABAAb", + 10 + ], + [ + "B", + "cAaaACc", + 14 + ], + [ + "B", + "cAcCA", + 10 + ], + [ + "B", + "cAccC", + 10 + ], + [ + "B", + "cB", + 2 + ], + [ + "B", + "cBBBa", + 8 + ], + [ + "B", + "cBaCCba", + 12 + ], + [ + "B", + "cBbbaAaBC", + 16 + ], + [ + "B", + "cBcCaA", + 10 + ], + [ + "B", + "cC", + 4 + ], + [ + "B", + "cCABB", + 8 + ], + [ + "B", + "cCBAacA", + 12 + ], + [ + "B", + "cCbBBAccB", + 16 + ], + [ + "B", + "cCbcaBaca", + 16 + ], + [ + "B", + "cCcBaC", + 10 + ], + [ + "B", + "cCcbcaCcc", + 17 + ], + [ + "B", + "cabBca", + 10 + ], + [ + "B", + "cabccaAAB", + 16 + ], + [ + "B", + "cb", + 3 + ], + [ + "B", + "cbAACcCCb", + 17 + ], + [ + "B", + "cbAC", + 7 + ], + [ + "B", + "cbBbCC", + 10 + ], + [ + "B", + "cbC", + 5 + ], + [ + "B", + "cbCaba", + 11 + ], + [ + "B", + "cbCbBBaa", + 14 + ], + [ + "B", + "cbaaAAA", + 13 + ], + [ + "B", + "cbaaCAb", + 13 + ], + [ + "B", + "cbbCaccA", + 15 + ], + [ + "B", + "cbbb", + 7 + ], + [ + "B", + "cbcCa", + 9 + ], + [ + "B", + "ccABaB", + 10 + ], + [ + "B", + "ccAc", + 8 + ], + [ + "B", + "ccCbCbc", + 13 + ], + [ + "B", + "ccabaC", + 11 + ], + [ + "B", + "ccb", + 5 + ], + [ + "BA", + "A", + 2 + ], + [ + "BA", + "ABaabAbAc", + 14 + ], + [ + "BA", + "B", + 2 + ], + [ + "BA", + "BBABbCAaB", + 14 + ], + [ + "BA", + "BBcaC", + 7 + ], + [ + "BA", + "BBcacAbcb", + 14 + ], + [ + "BA", + "BCbCbbcAB", + 14 + ], + [ + "BA", + "CACCAaac", + 14 + ], + [ + "BA", + "CAaaacb", + 12 + ], + [ + "BA", + "CBC", + 4 + ], + [ + "BA", + "aACbbcba", + 14 + ], + [ + "BA", + "ab", + 4 + ], + [ + "BA", + "abCAa", + 7 + ], + [ + "BA", + "b", + 3 + ], + [ + "BA", + "bABaAca", + 10 + ], + [ + "BA", + "baCCBbC", + 12 + ], + [ + "BA", + "bbBcB", + 8 + ], + [ + "BA", + "bbbCC", + 9 + ], + [ + "BA", + "bbbaBA", + 8 + ], + [ + "BA", + "bbbbCBb", + 12 + ], + [ + "BA", + "cBABaC", + 8 + ], + [ + "BA", + "cBBbbA", + 8 + ], + [ + "BA", + "cC", + 4 + ], + [ + "BA", + "ccB", + 6 + ], + [ + "BA", + "ccCa", + 7 + ], + [ + "BAA", + "A", + 4 + ], + [ + "BAA", + "abA", + 4 + ], + [ + "BAA", + "acCAc", + 8 + ], + [ + "BAA", + "bB", + 5 + ], + [ + "BAA", + "bbcACCCAB", + 13 + ], + [ + "BAA", + "bcBC", + 7 + ], + [ + "BAA", + "cBaCaBc", + 10 + ], + [ + "BAAA", + "B", + 6 + ], + [ + "BAAA", + "BBCacaC", + 10 + ], + [ + "BAAA", + "bBAc", + 5 + ], + [ + "BAAAAAA", + "CbcbAc", + 12 + ], + [ + "BAAAACb", + "cbcACabBc", + 13 + ], + [ + "BAAAC", + "cbCBcbCC", + 12 + ], + [ + "BAAAaCCAB", + "bcCB", + 12 + ], + [ + "BAAAabC", + "CCaaaAcc", + 11 + ], + [ + "BAAAbcBa", + "aCcAAAcc", + 12 + ], + [ + "BAABC", + "bccab", + 9 + ], + [ + "BAABaC", + "Cbb", + 11 + ], + [ + "BAABabAb", + "ACC", + 14 + ], + [ + "BAAC", + "bB", + 7 + ], + [ + "BAAC", + "ccaBab", + 10 + ], + [ + "BAAC", + "ccbC", + 6 + ], + [ + "BAACAA", + "a", + 11 + ], + [ + "BAACaC", + "Cac", + 7 + ], + [ + "BAAaA", + "a", + 8 + ], + [ + "BAAaACaC", + "bb", + 15 + ], + [ + "BAAaB", + "ccAcbA", + 9 + ], + [ + "BAAaa", + "b", + 9 + ], + [ + "BAAaa", + "cacCaBc", + 11 + ], + [ + "BAAaaac", + "c", + 12 + ], + [ + "BAAaabB", + "aaAAA", + 9 + ], + [ + "BAAaac", + "BCaCcCAB", + 12 + ], + [ + "BAAacA", + "ccBAcCAc", + 11 + ], + [ + "BAAb", + "AA", + 4 + ], + [ + "BAAbAC", + "BbAccCba", + 10 + ], + [ + "BAAbCbbC", + "CCCBBc", + 11 + ], + [ + "BAAbacbC", + "aBAabc", + 9 + ], + [ + "BAAbbACC", + "CCABb", + 11 + ], + [ + "BAAcCBa", + "ACcA", + 9 + ], + [ + "BAAcaBBCa", + "AccB", + 12 + ], + [ + "BAAcac", + "Bb", + 10 + ], + [ + "BAAcc", + "CACbabA", + 11 + ], + [ + "BAB", + "AcbBaaBa", + 11 + ], + [ + "BAB", + "BB", + 2 + ], + [ + "BAB", + "Caa", + 5 + ], + [ + "BAB", + "cc", + 6 + ], + [ + "BABA", + "abbccc", + 11 + ], + [ + "BABA", + "caCca", + 8 + ], + [ + "BABB", + "bBCCBcAcb", + 13 + ], + [ + "BABBAAc", + "caAaa", + 10 + ], + [ + "BABBbCA", + "bAca", + 9 + ], + [ + "BABBc", + "BCCcAcCC", + 11 + ], + [ + "BABCB", + "AB", + 6 + ], + [ + "BABCcBbA", + "CBb", + 10 + ], + [ + "BABa", + "abbbaccAa", + 14 + ], + [ + "BABabAB", + "b", + 12 + ], + [ + "BABacA", + "abcBA", + 8 + ], + [ + "BABb", + "cC", + 8 + ], + [ + "BABbC", + "BaA", + 7 + ], + [ + "BABbb", + "Ccc", + 10 + ], + [ + "BABc", + "aB", + 5 + ], + [ + "BABcACCaC", + "CbbBaCbaC", + 10 + ], + [ + "BABcBA", + "CA", + 9 + ], + [ + "BABcBCaBc", + "CBAaBCC", + 11 + ], + [ + "BABcBcBa", + "bCBACcc", + 11 + ], + [ + "BABcaBB", + "bAaabb", + 7 + ], + [ + "BABcb", + "CcCAaC", + 11 + ], + [ + "BABcbcaa", + "BbbCcAAab", + 11 + ], + [ + "BABccba", + "cCbbbA", + 10 + ], + [ + "BAC", + "BB", + 4 + ], + [ + "BAC", + "BBacAbC", + 8 + ], + [ + "BAC", + "BaacBaC", + 9 + ], + [ + "BAC", + "BbbBaB", + 9 + ], + [ + "BAC", + "CAAaa", + 8 + ], + [ + "BAC", + "CBBbBccbc", + 15 + ], + [ + "BAC", + "b", + 5 + ], + [ + "BAC", + "babAAcA", + 10 + ], + [ + "BACACcCcc", + "cbB", + 16 + ], + [ + "BACB", + "AaCABa", + 7 + ], + [ + "BACBAACba", + "BaA", + 13 + ], + [ + "BACBCAC", + "A", + 12 + ], + [ + "BACBaB", + "Bcbc", + 8 + ], + [ + "BACBbCbB", + "ACaAAaCb", + 12 + ], + [ + "BACC", + "ab", + 7 + ], + [ + "BACCBcbaa", + "ab", + 15 + ], + [ + "BACCCAaCA", + "bCCcBb", + 12 + ], + [ + "BACCbABA", + "AAAAcAB", + 10 + ], + [ + "BACCbAac", + "AcBCaacB", + 10 + ], + [ + "BACCc", + "BbAAcA", + 7 + ], + [ + "BACCc", + "aBbbBBCa", + 12 + ], + [ + "BACaC", + "CB", + 8 + ], + [ + "BACab", + "bCA", + 6 + ], + [ + "BACb", + "AcBC", + 6 + ], + [ + "BACbAbCbC", + "BbC", + 12 + ], + [ + "BACbbaaAc", + "ACabC", + 11 + ], + [ + "BACcBbcCb", + "AcbB", + 11 + ], + [ + "BACcbBbc", + "AC", + 12 + ], + [ + "BACccabb", + "bAcAAa", + 10 + ], + [ + "BACcccA", + "aacC", + 10 + ], + [ + "BAa", + "AC", + 4 + ], + [ + "BAa", + "AbCBcA", + 9 + ], + [ + "BAa", + "CabbAabb", + 11 + ], + [ + "BAa", + "cBaAa", + 4 + ], + [ + "BAaA", + "BCB", + 6 + ], + [ + "BAaABbB", + "ABabABcbC", + 9 + ], + [ + "BAaAbCc", + "acb", + 10 + ], + [ + "BAaAcCb", + "AbbC", + 10 + ], + [ + "BAaAcbB", + "Aa", + 10 + ], + [ + "BAaBBaAb", + "bBaBcaAAa", + 9 + ], + [ + "BAaBaB", + "A", + 10 + ], + [ + "BAaBbCc", + "cacBaAcaB", + 13 + ], + [ + "BAaBbabc", + "A", + 14 + ], + [ + "BAaBcCaaa", + "ab", + 15 + ], + [ + "BAaBcCb", + "aCAA", + 11 + ], + [ + "BAaCB", + "BBb", + 7 + ], + [ + "BAaCB", + "aABACA", + 7 + ], + [ + "BAaCaA", + "acB", + 9 + ], + [ + "BAaCabCCa", + "b", + 16 + ], + [ + "BAaCbAC", + "bA", + 10 + ], + [ + "BAaCbB", + "aCcbbAAA", + 13 + ], + [ + "BAaCcc", + "bc", + 9 + ], + [ + "BAaaACaA", + "Ccbcaa", + 12 + ], + [ + "BAaaCCb", + "bCBC", + 11 + ], + [ + "BAab", + "c", + 8 + ], + [ + "BAab", + "ccaba", + 6 + ], + [ + "BAabAbBB", + "ABaBaaBa", + 10 + ], + [ + "BAabCA", + "Cb", + 10 + ], + [ + "BAabCCA", + "CCbBcb", + 11 + ], + [ + "BAac", + "bBbcaca", + 8 + ], + [ + "BAacBb", + "cABAca", + 9 + ], + [ + "BAacbBbCb", + "bBAca", + 13 + ], + [ + "BAacbaBC", + "ABCbcaCAc", + 12 + ], + [ + "BAaccAba", + "BAbBbCA", + 11 + ], + [ + "BAb", + "Aa", + 4 + ], + [ + "BAb", + "AbaccbCbC", + 14 + ], + [ + "BAb", + "BaCa", + 5 + ], + [ + "BAb", + "CCaBA", + 8 + ], + [ + "BAb", + "CbCb", + 5 + ], + [ + "BAb", + "caAAC", + 8 + ], + [ + "BAb", + "ccCAAAABC", + 15 + ], + [ + "BAbABaBbC", + "CAAcAb", + 11 + ], + [ + "BAbACcA", + "aBaaCcc", + 8 + ], + [ + "BAbAa", + "ABbCbabac", + 11 + ], + [ + "BAbAa", + "c", + 10 + ], + [ + "BAbAc", + "cBc", + 7 + ], + [ + "BAbAcABa", + "ac", + 13 + ], + [ + "BAbAcbB", + "aCAcBB", + 6 + ], + [ + "BAbBA", + "BcaCBcaBa", + 11 + ], + [ + "BAbBAB", + "ABBCCb", + 8 + ], + [ + "BAbBBaB", + "abaA", + 9 + ], + [ + "BAbBCc", + "aaAcAcAAC", + 14 + ], + [ + "BAbBc", + "ABcAAABb", + 10 + ], + [ + "BAbCCbBC", + "bc", + 13 + ], + [ + "BAbCbBacB", + "acBca", + 12 + ], + [ + "BAbCc", + "BBbcBAab", + 11 + ], + [ + "BAbCcB", + "CbacAaaa", + 14 + ], + [ + "BAbCcBB", + "ccaBBcACC", + 14 + ], + [ + "BAba", + "Bc", + 6 + ], + [ + "BAbaBCAB", + "bbCbBa", + 11 + ], + [ + "BAbaBbBc", + "baAC", + 11 + ], + [ + "BAbaCc", + "C", + 10 + ], + [ + "BAbabca", + "cBabaCb", + 8 + ], + [ + "BAbacCaa", + "CCa", + 11 + ], + [ + "BAbb", + "baBaBaB", + 9 + ], + [ + "BAbbBAA", + "ACbcccc", + 12 + ], + [ + "BAbc", + "B", + 6 + ], + [ + "BAbc", + "bABCB", + 5 + ], + [ + "BAbc", + "bcBAb", + 6 + ], + [ + "BAbcAcA", + "ccA", + 8 + ], + [ + "BAbcaBab", + "CaACACbcB", + 13 + ], + [ + "BAbccAcB", + "BA", + 12 + ], + [ + "BAbccaBA", + "CCCcaa", + 10 + ], + [ + "BAc", + "AAAccAa", + 10 + ], + [ + "BAc", + "Bbc", + 2 + ], + [ + "BAc", + "ba", + 4 + ], + [ + "BAcA", + "Ac", + 4 + ], + [ + "BAcAA", + "acbCAA", + 7 + ], + [ + "BAcAACc", + "accA", + 9 + ], + [ + "BAcAAb", + "AbC", + 10 + ], + [ + "BAcAB", + "aAacCcbac", + 13 + ], + [ + "BAcACCb", + "cccBC", + 10 + ], + [ + "BAcACcBA", + "BCAbccA", + 7 + ], + [ + "BAcAcC", + "aAcBb", + 8 + ], + [ + "BAcBa", + "CCAbBCc", + 10 + ], + [ + "BAcBcba", + "aaa", + 11 + ], + [ + "BAcCBCbaA", + "bCb", + 13 + ], + [ + "BAcCC", + "ACCaC", + 5 + ], + [ + "BAcCCBAbA", + "b", + 16 + ], + [ + "BAcCaB", + "cCBBCaa", + 10 + ], + [ + "BAcCbC", + "CAB", + 9 + ], + [ + "BAcCbaC", + "CCBBaCabB", + 14 + ], + [ + "BAcCbc", + "Cb", + 8 + ], + [ + "BAcCcAACa", + "aacaCaA", + 11 + ], + [ + "BAcaBBBc", + "a", + 14 + ], + [ + "BAcaBc", + "CAbaa", + 8 + ], + [ + "BAcaC", + "cAcaCA", + 4 + ], + [ + "BAcaab", + "ACbA", + 8 + ], + [ + "BAcab", + "BaCbca", + 7 + ], + [ + "BAcbA", + "AbA", + 4 + ], + [ + "BAcbA", + "bACBCbbCA", + 10 + ], + [ + "BAcbAcCB", + "ac", + 13 + ], + [ + "BAcbBCC", + "bBaba", + 11 + ], + [ + "BAcbCC", + "c", + 10 + ], + [ + "BAcbCc", + "B", + 10 + ], + [ + "BAcbabcB", + "aAa", + 12 + ], + [ + "BAcbbba", + "Cb", + 11 + ], + [ + "BAcbcABbA", + "baABcBCa", + 10 + ], + [ + "BAccAAA", + "AaaC", + 10 + ], + [ + "BAccAAca", + "BBCbbCcab", + 11 + ], + [ + "BAccAbCB", + "Cba", + 13 + ], + [ + "BAccCAb", + "cCBcCcac", + 11 + ], + [ + "BAccCAbC", + "BCabCBA", + 11 + ], + [ + "BAccCCcA", + "CbbBaCB", + 14 + ], + [ + "BAccCcCB", + "bcCAB", + 9 + ], + [ + "BAcca", + "cBcCBBcbC", + 13 + ], + [ + "BAccaAaC", + "cbBcAaA", + 10 + ], + [ + "BAcccCbb", + "Bb", + 12 + ], + [ + "BB", + "A", + 4 + ], + [ + "BB", + "AACBAacBB", + 14 + ], + [ + "BB", + "ABaA", + 6 + ], + [ + "BB", + "ACbbCcc", + 12 + ], + [ + "BB", + "AbAABC", + 9 + ], + [ + "BB", + "AbbbBBa", + 10 + ], + [ + "BB", + "BC", + 2 + ], + [ + "BB", + "Ba", + 2 + ], + [ + "BB", + "BbcAaACB", + 12 + ], + [ + "BB", + "CAcaACbBb", + 15 + ], + [ + "BB", + "CBabcc", + 9 + ], + [ + "BB", + "CaCBb", + 7 + ], + [ + "BB", + "CaaAAaAAc", + 18 + ], + [ + "BB", + "Cab", + 5 + ], + [ + "BB", + "Cb", + 3 + ], + [ + "BB", + "CbAAC", + 9 + ], + [ + "BB", + "CbcbCcBc", + 13 + ], + [ + "BB", + "Ccccc", + 10 + ], + [ + "BB", + "a", + 4 + ], + [ + "BB", + "aAAbcc", + 11 + ], + [ + "BB", + "aACBABa", + 10 + ], + [ + "BB", + "aACbBCaac", + 15 + ], + [ + "BB", + "aAcCCb", + 11 + ], + [ + "BB", + "aCACcBC", + 12 + ], + [ + "BB", + "aCa", + 6 + ], + [ + "BB", + "aa", + 4 + ], + [ + "BB", + "bAABCCabC", + 15 + ], + [ + "BB", + "bABBCb", + 8 + ], + [ + "BB", + "bBacaAb", + 11 + ], + [ + "BB", + "bc", + 3 + ], + [ + "BB", + "cBBcCBaAa", + 14 + ], + [ + "BB", + "cCaAaBc", + 12 + ], + [ + "BB", + "cCb", + 5 + ], + [ + "BB", + "cCc", + 6 + ], + [ + "BB", + "caBcCA", + 10 + ], + [ + "BB", + "cac", + 6 + ], + [ + "BB", + "cbb", + 4 + ], + [ + "BB", + "ccaC", + 8 + ], + [ + "BBA", + "BB", + 2 + ], + [ + "BBA", + "BCCaaAb", + 10 + ], + [ + "BBA", + "Bb", + 3 + ], + [ + "BBA", + "Bba", + 2 + ], + [ + "BBA", + "CBbBab", + 7 + ], + [ + "BBA", + "aaBbAc", + 7 + ], + [ + "BBA", + "ab", + 5 + ], + [ + "BBA", + "bAAaBCbA", + 11 + ], + [ + "BBA", + "cbcBbC", + 9 + ], + [ + "BBAACb", + "BBaBbb", + 5 + ], + [ + "BBAAb", + "abaBbac", + 10 + ], + [ + "BBAAbbCc", + "a", + 15 + ], + [ + "BBAAcAb", + "cCBCaBCA", + 12 + ], + [ + "BBAAcbba", + "aCACbcCc", + 13 + ], + [ + "BBABA", + "bbccbbb", + 11 + ], + [ + "BBABACCCB", + "c", + 17 + ], + [ + "BBABBAca", + "aCCAAcCA", + 13 + ], + [ + "BBABBaBA", + "CaAaaa", + 11 + ], + [ + "BBABBaaBB", + "CccbccAc", + 16 + ], + [ + "BBABa", + "b", + 9 + ], + [ + "BBABcC", + "aCAA", + 10 + ], + [ + "BBABccb", + "C", + 13 + ], + [ + "BBAC", + "bBCAcBaC", + 9 + ], + [ + "BBACB", + "bAb", + 6 + ], + [ + "BBACC", + "CBccc", + 6 + ], + [ + "BBACC", + "aCBBBB", + 10 + ], + [ + "BBACaBC", + "C", + 12 + ], + [ + "BBACcCbBa", + "CCCcCC", + 12 + ], + [ + "BBAbA", + "AbCaCcB", + 12 + ], + [ + "BBAbCcacC", + "aBaacBcb", + 11 + ], + [ + "BBAba", + "BCbBcB", + 9 + ], + [ + "BBAbcB", + "BBc", + 6 + ], + [ + "BBAbcBBaA", + "bCcAB", + 13 + ], + [ + "BBAbcC", + "BacA", + 7 + ], + [ + "BBAcA", + "bBcaAacbb", + 11 + ], + [ + "BBAcC", + "cC", + 6 + ], + [ + "BBB", + "BaBbB", + 4 + ], + [ + "BBB", + "Bbcbc", + 6 + ], + [ + "BBB", + "CC", + 6 + ], + [ + "BBB", + "CCCAbc", + 11 + ], + [ + "BBB", + "CcbcBc", + 9 + ], + [ + "BBB", + "aaAbb", + 8 + ], + [ + "BBBAAA", + "AA", + 8 + ], + [ + "BBBAAAcB", + "BAcAcCCA", + 11 + ], + [ + "BBBACc", + "AaBCBb", + 10 + ], + [ + "BBBAbAaAB", + "aAcBABA", + 13 + ], + [ + "BBBAccBbC", + "ccbCbAb", + 14 + ], + [ + "BBBB", + "baABcbb", + 9 + ], + [ + "BBBBCCacA", + "bbCCc", + 10 + ], + [ + "BBBBcCA", + "bBAabcB", + 10 + ], + [ + "BBBBccCCC", + "C", + 16 + ], + [ + "BBBCABbb", + "cAAaAB", + 12 + ], + [ + "BBBCab", + "abBACbBc", + 10 + ], + [ + "BBBa", + "CCabbCcaB", + 14 + ], + [ + "BBBa", + "cAa", + 6 + ], + [ + "BBBaCA", + "AAbbaaACB", + 12 + ], + [ + "BBBaaBb", + "cBcaac", + 8 + ], + [ + "BBBab", + "bAa", + 7 + ], + [ + "BBBac", + "aaCcCBcAB", + 15 + ], + [ + "BBBb", + "B", + 6 + ], + [ + "BBBbCCb", + "BbBaCc", + 6 + ], + [ + "BBBba", + "BCaC", + 8 + ], + [ + "BBBbcBcCA", + "BbBB", + 11 + ], + [ + "BBBbccc", + "A", + 14 + ], + [ + "BBBc", + "cCAba", + 9 + ], + [ + "BBBcAB", + "AbCAAbc", + 10 + ], + [ + "BBBcBAa", + "AbBCCa", + 8 + ], + [ + "BBBcBabbB", + "aCC", + 16 + ], + [ + "BBBcbBA", + "AbACCCbCb", + 14 + ], + [ + "BBBcc", + "CCbbabCb", + 12 + ], + [ + "BBBccBaaB", + "BcCB", + 11 + ], + [ + "BBC", + "CaAAAaCbB", + 16 + ], + [ + "BBC", + "Cbcbcc", + 9 + ], + [ + "BBC", + "abBBacA", + 9 + ], + [ + "BBC", + "b", + 5 + ], + [ + "BBC", + "bCBAA", + 7 + ], + [ + "BBC", + "bcCaAbb", + 11 + ], + [ + "BBC", + "cba", + 5 + ], + [ + "BBCA", + "BAcCC", + 6 + ], + [ + "BBCAbbbc", + "BAa", + 12 + ], + [ + "BBCAcb", + "Ca", + 9 + ], + [ + "BBCBb", + "aac", + 9 + ], + [ + "BBCBbc", + "CaaBB", + 9 + ], + [ + "BBCBcaBb", + "ccCcCbBC", + 11 + ], + [ + "BBCBcb", + "CBcCBcacC", + 10 + ], + [ + "BBCC", + "C", + 6 + ], + [ + "BBCCBC", + "aCbbA", + 9 + ], + [ + "BBCCBab", + "cBCaaC", + 8 + ], + [ + "BBCCCbaCB", + "AAA", + 17 + ], + [ + "BBCCaBbB", + "BaBAcCbC", + 11 + ], + [ + "BBCCccBCB", + "bCaaCA", + 13 + ], + [ + "BBCa", + "aB", + 6 + ], + [ + "BBCaa", + "AccACcAAC", + 14 + ], + [ + "BBCabCCBB", + "BcAcCaCC", + 12 + ], + [ + "BBCbB", + "BBb", + 4 + ], + [ + "BBCbB", + "CB", + 6 + ], + [ + "BBCbB", + "caABAb", + 10 + ], + [ + "BBCbc", + "BAAbcaaBc", + 11 + ], + [ + "BBCc", + "BabAb", + 7 + ], + [ + "BBCc", + "cbabab", + 10 + ], + [ + "BBCcbACcB", + "Ab", + 15 + ], + [ + "BBCccCAba", + "aCcCCBAb", + 9 + ], + [ + "BBa", + "AcBcBAb", + 9 + ], + [ + "BBa", + "Ccb", + 6 + ], + [ + "BBa", + "aCCcbCAc", + 14 + ], + [ + "BBa", + "bBaCBa", + 6 + ], + [ + "BBa", + "cbAcBBaA", + 10 + ], + [ + "BBaA", + "bAAaBAAAB", + 12 + ], + [ + "BBaAAccbb", + "CABB", + 14 + ], + [ + "BBaACBaB", + "cbcC", + 13 + ], + [ + "BBaAab", + "BCB", + 9 + ], + [ + "BBaAcAAcb", + "cbCBBCAcb", + 11 + ], + [ + "BBaAcB", + "ACbAcb", + 7 + ], + [ + "BBaBbcB", + "C", + 13 + ], + [ + "BBaCB", + "cC", + 8 + ], + [ + "BBaCCA", + "ABAcc", + 7 + ], + [ + "BBaCccb", + "Cbcbb", + 9 + ], + [ + "BBaa", + "ba", + 5 + ], + [ + "BBaaCCBA", + "AbCbC", + 12 + ], + [ + "BBaaCca", + "aaBBcbAB", + 13 + ], + [ + "BBaaa", + "B", + 8 + ], + [ + "BBaab", + "bbAcbB", + 7 + ], + [ + "BBaabcA", + "BACBAC", + 10 + ], + [ + "BBaacbcaB", + "Abacab", + 10 + ], + [ + "BBaacc", + "C", + 11 + ], + [ + "BBabBa", + "BbBBcAACB", + 13 + ], + [ + "BBabcBab", + "abB", + 10 + ], + [ + "BBabcbb", + "BbbCbA", + 6 + ], + [ + "BBac", + "cBAB", + 5 + ], + [ + "BBacAcaAa", + "Bba", + 13 + ], + [ + "BBacCaBBa", + "aa", + 14 + ], + [ + "BBacCc", + "bcaBA", + 9 + ], + [ + "BBacaABc", + "Cbbaac", + 10 + ], + [ + "BBacb", + "AbbaCBCb", + 9 + ], + [ + "BBacb", + "abCACCBBA", + 14 + ], + [ + "BBb", + "BAcaAaca", + 14 + ], + [ + "BBb", + "BBa", + 2 + ], + [ + "BBb", + "CAcBCAAc", + 14 + ], + [ + "BBb", + "aBACcCCC", + 14 + ], + [ + "BBb", + "acbCc", + 8 + ], + [ + "BBbA", + "ca", + 7 + ], + [ + "BBbAACb", + "ACCbb", + 10 + ], + [ + "BBbABAaAB", + "cAbaCba", + 13 + ], + [ + "BBbABbac", + "cAB", + 12 + ], + [ + "BBbAabbCA", + "A", + 16 + ], + [ + "BBbAbcB", + "AcAAcbABa", + 12 + ], + [ + "BBbAcaAB", + "cBB", + 12 + ], + [ + "BBbAcc", + "bBAb", + 7 + ], + [ + "BBbB", + "ccABABc", + 10 + ], + [ + "BBbBB", + "a", + 10 + ], + [ + "BBbBBbba", + "aACbb", + 12 + ], + [ + "BBbBBcacc", + "AcAa", + 15 + ], + [ + "BBbBCbBc", + "BbABC", + 9 + ], + [ + "BBbBaa", + "bbBbbbaAb", + 9 + ], + [ + "BBbCCCCbc", + "ccaAB", + 15 + ], + [ + "BBbCCcbAc", + "bABcac", + 11 + ], + [ + "BBbCbcb", + "Ab", + 12 + ], + [ + "BBba", + "a", + 6 + ], + [ + "BBbaBc", + "ac", + 8 + ], + [ + "BBbab", + "AcAB", + 8 + ], + [ + "BBbabb", + "CCbAa", + 9 + ], + [ + "BBbabbab", + "bCBBbaA", + 9 + ], + [ + "BBbb", + "BA", + 6 + ], + [ + "BBbbACc", + "A", + 12 + ], + [ + "BBbbCCBB", + "AaCcBAAA", + 15 + ], + [ + "BBbcABBbC", + "AaC", + 14 + ], + [ + "BBbcB", + "ACbA", + 8 + ], + [ + "BBbcCac", + "cbb", + 11 + ], + [ + "BBbccCCBB", + "BbaBcb", + 12 + ], + [ + "BBc", + "ABCbAA", + 9 + ], + [ + "BBc", + "BbbABAACA", + 13 + ], + [ + "BBc", + "BcccAbBaC", + 13 + ], + [ + "BBc", + "aBaCccA", + 10 + ], + [ + "BBc", + "aC", + 5 + ], + [ + "BBc", + "aCacBbCCa", + 14 + ], + [ + "BBcAAA", + "Acbc", + 10 + ], + [ + "BBcAAac", + "acCcAbc", + 9 + ], + [ + "BBcABAA", + "BbBaABaC", + 7 + ], + [ + "BBcB", + "AAacBC", + 8 + ], + [ + "BBcB", + "aAaabB", + 10 + ], + [ + "BBcB", + "acb", + 5 + ], + [ + "BBcB", + "bAcAAbac", + 12 + ], + [ + "BBcBACa", + "CBACA", + 6 + ], + [ + "BBcBCB", + "c", + 10 + ], + [ + "BBcBbCBA", + "cBaaAca", + 12 + ], + [ + "BBcBbcA", + "bBbca", + 6 + ], + [ + "BBcC", + "AcAcAcCc", + 12 + ], + [ + "BBcCBCac", + "ababc", + 12 + ], + [ + "BBcCC", + "ccB", + 7 + ], + [ + "BBcCCabAA", + "BCC", + 12 + ], + [ + "BBcCCcab", + "bCcc", + 10 + ], + [ + "BBcCa", + "BBAA", + 5 + ], + [ + "BBcCcb", + "BCb", + 6 + ], + [ + "BBca", + "b", + 7 + ], + [ + "BBcaA", + "AaCCAbCCC", + 15 + ], + [ + "BBcaA", + "b", + 9 + ], + [ + "BBcaACbB", + "AbCb", + 11 + ], + [ + "BBcaC", + "CCccCCCC", + 12 + ], + [ + "BBcaa", + "aBaa", + 4 + ], + [ + "BBcaa", + "bAAAC", + 8 + ], + [ + "BBcaa", + "ccCCcABA", + 12 + ], + [ + "BBcaaCBB", + "BbCcbC", + 10 + ], + [ + "BBcab", + "aaBc", + 8 + ], + [ + "BBcbA", + "BcBabbA", + 6 + ], + [ + "BBcbaA", + "caBbCcaa", + 9 + ], + [ + "BBcbbaB", + "ccCbbAccB", + 10 + ], + [ + "BBcbbabC", + "BB", + 12 + ], + [ + "BBcc", + "AcbAAB", + 11 + ], + [ + "BBcc", + "CCcBccBbC", + 12 + ], + [ + "BBccAb", + "aCACbAC", + 11 + ], + [ + "BBccB", + "BcB", + 4 + ], + [ + "BBccc", + "BBAbCAcbB", + 11 + ], + [ + "BBcccCAAB", + "ABABBAca", + 14 + ], + [ + "BC", + "A", + 4 + ], + [ + "BC", + "AAcba", + 9 + ], + [ + "BC", + "AC", + 2 + ], + [ + "BC", + "ACBACCA", + 10 + ], + [ + "BC", + "AaA", + 6 + ], + [ + "BC", + "AaCABABAb", + 16 + ], + [ + "BC", + "Ac", + 3 + ], + [ + "BC", + "AcCCcc", + 10 + ], + [ + "BC", + "B", + 2 + ], + [ + "BC", + "BAbC", + 4 + ], + [ + "BC", + "BC", + 0 + ], + [ + "BC", + "BCCCC", + 6 + ], + [ + "BC", + "BbAaaBAbb", + 16 + ], + [ + "BC", + "BbB", + 4 + ], + [ + "BC", + "BcB", + 3 + ], + [ + "BC", + "C", + 2 + ], + [ + "BC", + "CA", + 4 + ], + [ + "BC", + "CaaaCAcaC", + 16 + ], + [ + "BC", + "CbCC", + 5 + ], + [ + "BC", + "CcC", + 4 + ], + [ + "BC", + "CcCCCab", + 12 + ], + [ + "BC", + "CcaAbbbcb", + 16 + ], + [ + "BC", + "CccAb", + 9 + ], + [ + "BC", + "aAA", + 6 + ], + [ + "BC", + "aAbbcbac", + 14 + ], + [ + "BC", + "aCbAaAbBB", + 16 + ], + [ + "BC", + "abbba", + 9 + ], + [ + "BC", + "acAACAC", + 12 + ], + [ + "BC", + "acbCA", + 7 + ], + [ + "BC", + "acccbAAB", + 15 + ], + [ + "BC", + "bAABa", + 8 + ], + [ + "BC", + "bBBAcBbCC", + 14 + ], + [ + "BC", + "bC", + 1 + ], + [ + "BC", + "bCaCaCaa", + 13 + ], + [ + "BC", + "bCbaCa", + 9 + ], + [ + "BC", + "bCbaaaAAC", + 15 + ], + [ + "BC", + "babCAbca", + 13 + ], + [ + "BC", + "babbBBaB", + 14 + ], + [ + "BC", + "bbCA", + 5 + ], + [ + "BC", + "c", + 3 + ], + [ + "BC", + "cAAB", + 8 + ], + [ + "BC", + "cABCBCAB", + 12 + ], + [ + "BC", + "cBaACA", + 8 + ], + [ + "BC", + "cBbaAcB", + 11 + ], + [ + "BC", + "cCCBb", + 8 + ], + [ + "BC", + "cb", + 4 + ], + [ + "BC", + "cbBBB", + 8 + ], + [ + "BC", + "cba", + 5 + ], + [ + "BC", + "cbaB", + 7 + ], + [ + "BC", + "cbaCbBAC", + 12 + ], + [ + "BC", + "cbbCabA", + 11 + ], + [ + "BC", + "ccAACb", + 10 + ], + [ + "BC", + "ccccbb", + 11 + ], + [ + "BCA", + "A", + 4 + ], + [ + "BCA", + "AbcCbCaA", + 11 + ], + [ + "BCA", + "abccbBCC", + 12 + ], + [ + "BCAABABCB", + "abBbBaB", + 11 + ], + [ + "BCAABc", + "bBACcBa", + 9 + ], + [ + "BCAAbBc", + "AaABC", + 8 + ], + [ + "BCAAbbbc", + "A", + 14 + ], + [ + "BCAAcbb", + "CAaCAcBbC", + 9 + ], + [ + "BCAAccAa", + "Aaaa", + 10 + ], + [ + "BCABBA", + "AbBba", + 8 + ], + [ + "BCABBBAa", + "bCAbBA", + 6 + ], + [ + "BCABa", + "b", + 9 + ], + [ + "BCABcB", + "bcAAbCb", + 7 + ], + [ + "BCABcCCc", + "CACcbBAc", + 10 + ], + [ + "BCABccC", + "B", + 12 + ], + [ + "BCABccaB", + "cAaCbBCc", + 13 + ], + [ + "BCAC", + "CAcCB", + 6 + ], + [ + "BCACBaACB", + "aaCaC", + 11 + ], + [ + "BCACBaba", + "BbAaAbc", + 9 + ], + [ + "BCACBb", + "aCbCA", + 8 + ], + [ + "BCACb", + "CAABCa", + 8 + ], + [ + "BCACcABBB", + "C", + 16 + ], + [ + "BCACcCAC", + "aBcAaaB", + 12 + ], + [ + "BCACcb", + "AC", + 8 + ], + [ + "BCAa", + "A", + 6 + ], + [ + "BCAa", + "Cc", + 6 + ], + [ + "BCAacBCB", + "CaCC", + 9 + ], + [ + "BCAbBAbAc", + "aBcbB", + 13 + ], + [ + "BCAbBaCB", + "caCba", + 11 + ], + [ + "BCAbCB", + "ccBcBCC", + 10 + ], + [ + "BCAbaCC", + "aB", + 12 + ], + [ + "BCAbbAcBA", + "A", + 16 + ], + [ + "BCAbbBA", + "BBAAAbac", + 10 + ], + [ + "BCAbc", + "Cb", + 6 + ], + [ + "BCAbcaBCC", + "ccBacBbA", + 13 + ], + [ + "BCAbccbb", + "bAcaCCbAB", + 12 + ], + [ + "BCAc", + "BaBb", + 6 + ], + [ + "BCAcC", + "Ccc", + 5 + ], + [ + "BCAcCabcc", + "CBC", + 14 + ], + [ + "BCAcabbBc", + "bcbC", + 12 + ], + [ + "BCB", + "caa", + 6 + ], + [ + "BCB", + "ccB", + 3 + ], + [ + "BCBA", + "B", + 6 + ], + [ + "BCBA", + "bAB", + 5 + ], + [ + "BCBAACcc", + "aBB", + 14 + ], + [ + "BCBACbAbA", + "ccABAa", + 11 + ], + [ + "BCBACbCb", + "cBA", + 11 + ], + [ + "BCBAaBcA", + "baC", + 12 + ], + [ + "BCBAabB", + "Bcb", + 9 + ], + [ + "BCBAb", + "CccbcCcBb", + 13 + ], + [ + "BCBAcbbC", + "AccaABA", + 13 + ], + [ + "BCBB", + "A", + 8 + ], + [ + "BCBBA", + "ACAC", + 8 + ], + [ + "BCBBACa", + "AbbAA", + 9 + ], + [ + "BCBBbCbC", + "Ccb", + 11 + ], + [ + "BCBBbab", + "cCAccAbb", + 11 + ], + [ + "BCBBcCa", + "BCCCBbA", + 9 + ], + [ + "BCBBcaCBA", + "CbBCCBacA", + 10 + ], + [ + "BCBBccB", + "B", + 12 + ], + [ + "BCBC", + "CbaBa", + 7 + ], + [ + "BCBC", + "cabAcCaCc", + 13 + ], + [ + "BCBCAaB", + "CAcb", + 9 + ], + [ + "BCBCBaAA", + "b", + 15 + ], + [ + "BCBCBbbc", + "CBBA", + 10 + ], + [ + "BCBCbbBC", + "CACcaACaB", + 14 + ], + [ + "BCBCc", + "aBAA", + 8 + ], + [ + "BCBaACb", + "aCB", + 9 + ], + [ + "BCBaAcb", + "AaC", + 11 + ], + [ + "BCBaC", + "BC", + 6 + ], + [ + "BCBaCCabc", + "aAcbC", + 12 + ], + [ + "BCBb", + "AaaBabaAa", + 14 + ], + [ + "BCBbAABB", + "A", + 14 + ], + [ + "BCBbBCaA", + "B", + 14 + ], + [ + "BCBbc", + "AbBba", + 6 + ], + [ + "BCBbcbBC", + "ca", + 14 + ], + [ + "BCBcB", + "bbC", + 7 + ], + [ + "BCBcaACa", + "bbCaabC", + 10 + ], + [ + "BCBcabB", + "aaBaaaAac", + 14 + ], + [ + "BCC", + "AabbC", + 7 + ], + [ + "BCC", + "AbbBBa", + 10 + ], + [ + "BCC", + "CCBcABb", + 11 + ], + [ + "BCCA", + "bcbbc", + 8 + ], + [ + "BCCA", + "cBBbacAc", + 11 + ], + [ + "BCCAAbbC", + "ccCB", + 12 + ], + [ + "BCCABc", + "c", + 10 + ], + [ + "BCCAaba", + "CAbB", + 8 + ], + [ + "BCCB", + "cBca", + 7 + ], + [ + "BCCBCC", + "ACCBaa", + 6 + ], + [ + "BCCBbcAAA", + "aaaCCB", + 16 + ], + [ + "BCCCAbA", + "CabCcbc", + 10 + ], + [ + "BCCCCAB", + "BC", + 10 + ], + [ + "BCCCCBAB", + "cABCcc", + 13 + ], + [ + "BCCCb", + "cCCAc", + 6 + ], + [ + "BCCaAcbB", + "Cabccaa", + 12 + ], + [ + "BCCaB", + "cAaAcAa", + 12 + ], + [ + "BCCaBABCc", + "a", + 16 + ], + [ + "BCCaCBCAA", + "cBbCaccaA", + 9 + ], + [ + "BCCac", + "CbC", + 7 + ], + [ + "BCCbAc", + "AcCAaBcCc", + 12 + ], + [ + "BCCbCbaB", + "caa", + 13 + ], + [ + "BCCbaBBbC", + "baBAB", + 11 + ], + [ + "BCCbb", + "aAAcc", + 10 + ], + [ + "BCCbbb", + "BCaB", + 7 + ], + [ + "BCCbc", + "BBaAbbBCC", + 13 + ], + [ + "BCCbc", + "caBaAbbC", + 11 + ], + [ + "BCCcaAccC", + "bacbC", + 11 + ], + [ + "BCCcbAcBa", + "CA", + 14 + ], + [ + "BCCcbaBc", + "CcCcCAba", + 9 + ], + [ + "BCCccbaC", + "C", + 14 + ], + [ + "BCa", + "CBbbAac", + 10 + ], + [ + "BCa", + "aAbCCb", + 9 + ], + [ + "BCa", + "bbcAB", + 7 + ], + [ + "BCa", + "c", + 5 + ], + [ + "BCaABBaAB", + "acCcBAC", + 13 + ], + [ + "BCaAa", + "AC", + 8 + ], + [ + "BCaAaCac", + "aaAB", + 11 + ], + [ + "BCaAba", + "a", + 10 + ], + [ + "BCaAcAbC", + "B", + 14 + ], + [ + "BCaBAC", + "bCAcCAaB", + 10 + ], + [ + "BCaBcCB", + "BaAA", + 10 + ], + [ + "BCaCAc", + "CBAaBc", + 8 + ], + [ + "BCaCCCcc", + "ccbaBCaC", + 12 + ], + [ + "BCaCbbbc", + "aaAAa", + 14 + ], + [ + "BCaa", + "bc", + 6 + ], + [ + "BCaaAbaB", + "ccCA", + 13 + ], + [ + "BCaaab", + "cAbBBa", + 11 + ], + [ + "BCaaabC", + "Bbbcb", + 10 + ], + [ + "BCaabcbA", + "BabcCAb", + 8 + ], + [ + "BCabaB", + "BaBAbcB", + 7 + ], + [ + "BCabacC", + "a", + 12 + ], + [ + "BCabbbABB", + "BBCcABb", + 10 + ], + [ + "BCabbcCCC", + "ABcCAcbc", + 13 + ], + [ + "BCabcaAAA", + "Baa", + 12 + ], + [ + "BCacBBAAB", + "aBC", + 14 + ], + [ + "BCacBBbB", + "CBCB", + 10 + ], + [ + "BCacCB", + "bB", + 9 + ], + [ + "BCacCba", + "BaBbaAAba", + 10 + ], + [ + "BCb", + "BBa", + 4 + ], + [ + "BCb", + "bBCCa", + 6 + ], + [ + "BCb", + "bCAAAAC", + 11 + ], + [ + "BCbA", + "Bccc", + 5 + ], + [ + "BCbAAC", + "aA", + 9 + ], + [ + "BCbAcbcCB", + "cbBcba", + 11 + ], + [ + "BCbBCacaC", + "AACB", + 16 + ], + [ + "BCbBa", + "cbbBC", + 6 + ], + [ + "BCbBaa", + "aCAAbACc", + 12 + ], + [ + "BCbBca", + "bBaB", + 8 + ], + [ + "BCbCA", + "cB", + 8 + ], + [ + "BCbCccA", + "aaABcCAB", + 11 + ], + [ + "BCbaAABaa", + "AA", + 14 + ], + [ + "BCbaBAb", + "cAAAcbbaA", + 15 + ], + [ + "BCbaCbBAc", + "CBCcabcAb", + 10 + ], + [ + "BCbaaCCaa", + "cCbac", + 11 + ], + [ + "BCbaabbBC", + "abcCBbB", + 11 + ], + [ + "BCbaccCC", + "bbBc", + 11 + ], + [ + "BCbbc", + "AcCbBaACc", + 11 + ], + [ + "BCbbcbbB", + "AbbCca", + 11 + ], + [ + "BCbc", + "cbcCCcBAA", + 13 + ], + [ + "BCbcBbaC", + "babCBCACb", + 9 + ], + [ + "BCbcaACBB", + "aab", + 14 + ], + [ + "BCbccccB", + "Ca", + 14 + ], + [ + "BCc", + "AAaCBcAbc", + 13 + ], + [ + "BCc", + "AcBbBbcba", + 14 + ], + [ + "BCc", + "CAcB", + 6 + ], + [ + "BCc", + "bABBC", + 7 + ], + [ + "BCcA", + "Aac", + 6 + ], + [ + "BCcA", + "bbbCc", + 7 + ], + [ + "BCcACaB", + "CBcbcaBAA", + 11 + ], + [ + "BCcACaCca", + "cca", + 12 + ], + [ + "BCcAcb", + "bbcacbb", + 6 + ], + [ + "BCcBBAccb", + "cBB", + 12 + ], + [ + "BCcBBacB", + "B", + 14 + ], + [ + "BCcBBc", + "ca", + 10 + ], + [ + "BCcBac", + "Cb", + 9 + ], + [ + "BCcBbBAb", + "BBcBBcA", + 7 + ], + [ + "BCcBbBCc", + "A", + 16 + ], + [ + "BCcBc", + "a", + 10 + ], + [ + "BCcCB", + "CABB", + 6 + ], + [ + "BCcCC", + "baB", + 9 + ], + [ + "BCcCcaaB", + "CAaa", + 10 + ], + [ + "BCca", + "aBcCcA", + 5 + ], + [ + "BCcaAc", + "aaAAA", + 9 + ], + [ + "BCcaBbAb", + "A", + 14 + ], + [ + "BCcab", + "CA", + 7 + ], + [ + "BCcacCbcc", + "CBcabaBCC", + 11 + ], + [ + "BCcb", + "CCbBACCcc", + 12 + ], + [ + "BCcb", + "Ca", + 6 + ], + [ + "BCcb", + "bC", + 5 + ], + [ + "BCcbAc", + "B", + 10 + ], + [ + "BCcbAcBAA", + "AacbBc", + 12 + ], + [ + "BCcbBac", + "Aaa", + 12 + ], + [ + "BCcbaC", + "cB", + 9 + ], + [ + "BCcbc", + "BBa", + 7 + ], + [ + "BCccAac", + "ABB", + 12 + ], + [ + "BCccBb", + "Cc", + 8 + ], + [ + "BCccCC", + "BBA", + 10 + ], + [ + "Ba", + "AAACAbbb", + 15 + ], + [ + "Ba", + "AAaBBbBaa", + 14 + ], + [ + "Ba", + "ABBaAabBa", + 14 + ], + [ + "Ba", + "AaccaB", + 10 + ], + [ + "Ba", + "AcABCBc", + 12 + ], + [ + "Ba", + "AcB", + 6 + ], + [ + "Ba", + "AcaAcb", + 10 + ], + [ + "Ba", + "B", + 2 + ], + [ + "Ba", + "BAcBc", + 7 + ], + [ + "Ba", + "Ba", + 0 + ], + [ + "Ba", + "BcAACc", + 9 + ], + [ + "Ba", + "BcCa", + 4 + ], + [ + "Ba", + "BcbBb", + 8 + ], + [ + "Ba", + "C", + 4 + ], + [ + "Ba", + "CABbaBcb", + 12 + ], + [ + "Ba", + "CBBAAB", + 9 + ], + [ + "Ba", + "CC", + 4 + ], + [ + "Ba", + "CCCcABBC", + 14 + ], + [ + "Ba", + "CbCbCa", + 9 + ], + [ + "Ba", + "Cc", + 4 + ], + [ + "Ba", + "a", + 2 + ], + [ + "Ba", + "aA", + 3 + ], + [ + "Ba", + "aB", + 4 + ], + [ + "Ba", + "aCB", + 6 + ], + [ + "Ba", + "aCbCa", + 7 + ], + [ + "Ba", + "acBbb", + 8 + ], + [ + "Ba", + "b", + 3 + ], + [ + "Ba", + "bcBCAbcCB", + 15 + ], + [ + "Ba", + "c", + 4 + ], + [ + "Ba", + "cAaAABbCB", + 16 + ], + [ + "Ba", + "cBBa", + 4 + ], + [ + "Ba", + "cbBaCAb", + 10 + ], + [ + "Ba", + "ccBcACA", + 11 + ], + [ + "Ba", + "ccC", + 6 + ], + [ + "BaA", + "CACaA", + 6 + ], + [ + "BaA", + "CBAbbaca", + 11 + ], + [ + "BaA", + "aaBB", + 6 + ], + [ + "BaA", + "bA", + 3 + ], + [ + "BaA", + "baACAbcA", + 11 + ], + [ + "BaA", + "cbc", + 6 + ], + [ + "BaA", + "ccBAAB", + 7 + ], + [ + "BaAAA", + "BB", + 8 + ], + [ + "BaAAa", + "ca", + 8 + ], + [ + "BaAAaCBaA", + "ACCC", + 14 + ], + [ + "BaAAcCA", + "abCCBA", + 9 + ], + [ + "BaAAcc", + "aaAAbac", + 6 + ], + [ + "BaAAccaCA", + "CcABcBCc", + 12 + ], + [ + "BaAB", + "BBAB", + 2 + ], + [ + "BaAB", + "ac", + 6 + ], + [ + "BaAB", + "bBB", + 5 + ], + [ + "BaABAACBA", + "bAb", + 14 + ], + [ + "BaABCaACb", + "bCbabAaBb", + 13 + ], + [ + "BaABa", + "abC", + 7 + ], + [ + "BaABcbab", + "cAaca", + 10 + ], + [ + "BaACAcCc", + "BC", + 12 + ], + [ + "BaACB", + "bcAa", + 7 + ], + [ + "BaACBAbAC", + "Bac", + 13 + ], + [ + "BaACaCbC", + "AACACCC", + 6 + ], + [ + "BaAa", + "BBCC", + 6 + ], + [ + "BaAa", + "BcbccbCC", + 14 + ], + [ + "BaAa", + "aAbB", + 6 + ], + [ + "BaAaAaAB", + "Ccab", + 13 + ], + [ + "BaAaaAAb", + "ABBCBAcB", + 13 + ], + [ + "BaAacA", + "bACCCb", + 9 + ], + [ + "BaAb", + "AbCBcCba", + 12 + ], + [ + "BaAbCBa", + "CCCcAb", + 13 + ], + [ + "BaAbab", + "aAbaBCc", + 7 + ], + [ + "BaAbcCCB", + "CBcA", + 13 + ], + [ + "BaAcAB", + "BabCCCaC", + 10 + ], + [ + "BaAcAa", + "abaCCCBAA", + 11 + ], + [ + "BaAcAbbC", + "ABaBBAC", + 10 + ], + [ + "BaAcB", + "CBAACbCa", + 9 + ], + [ + "BaAcCbb", + "Abb", + 8 + ], + [ + "BaAcCbca", + "BcCbCAAcB", + 12 + ], + [ + "BaAcbcb", + "c", + 12 + ], + [ + "BaB", + "CACAb", + 8 + ], + [ + "BaB", + "aCACaB", + 8 + ], + [ + "BaB", + "bc", + 5 + ], + [ + "BaB", + "cBBB", + 4 + ], + [ + "BaB", + "cCacaaB", + 10 + ], + [ + "BaBA", + "cABACbbA", + 10 + ], + [ + "BaBAA", + "bbAacbA", + 9 + ], + [ + "BaBAB", + "acAaABBA", + 11 + ], + [ + "BaBABabC", + "C", + 14 + ], + [ + "BaBACA", + "ACAcbbccb", + 15 + ], + [ + "BaBAc", + "BaBABaaC", + 7 + ], + [ + "BaBB", + "aBBCaA", + 8 + ], + [ + "BaBBaABA", + "AaabaABb", + 7 + ], + [ + "BaBBb", + "BC", + 8 + ], + [ + "BaBBc", + "C", + 9 + ], + [ + "BaBBcAaAc", + "C", + 17 + ], + [ + "BaBBcbcb", + "bbabb", + 10 + ], + [ + "BaBCAbab", + "A", + 14 + ], + [ + "BaBCBC", + "BA", + 9 + ], + [ + "BaBCaCac", + "cACc", + 10 + ], + [ + "BaBCc", + "cBcCbAab", + 13 + ], + [ + "BaBa", + "bBBABAabb", + 11 + ], + [ + "BaBa", + "bCAbaAbCb", + 13 + ], + [ + "BaBaBB", + "C", + 12 + ], + [ + "BaBb", + "CC", + 8 + ], + [ + "BaBb", + "bbAbCcbBc", + 13 + ], + [ + "BaBbABA", + "ababcCAc", + 11 + ], + [ + "BaBbBb", + "cCAAb", + 10 + ], + [ + "BaBbC", + "BBACac", + 8 + ], + [ + "BaBbabbCb", + "b", + 16 + ], + [ + "BaBc", + "CB", + 6 + ], + [ + "BaBcACac", + "AbCaBA", + 11 + ], + [ + "BaBcB", + "AaabaaBAa", + 13 + ], + [ + "BaBcBbbAa", + "BCACcab", + 13 + ], + [ + "BaBcCA", + "CbCACA", + 8 + ], + [ + "BaBcCA", + "bCa", + 8 + ], + [ + "BaBcaCCbB", + "BCC", + 12 + ], + [ + "BaBcacC", + "ACB", + 12 + ], + [ + "BaC", + "ABAbc", + 6 + ], + [ + "BaC", + "ABbb", + 6 + ], + [ + "BaC", + "ACa", + 5 + ], + [ + "BaC", + "Aaba", + 6 + ], + [ + "BaC", + "BACccaaBA", + 13 + ], + [ + "BaC", + "BC", + 2 + ], + [ + "BaC", + "Bccb", + 5 + ], + [ + "BaC", + "a", + 4 + ], + [ + "BaC", + "bCbbBcB", + 12 + ], + [ + "BaC", + "baBcbC", + 7 + ], + [ + "BaC", + "cBAabACAa", + 12 + ], + [ + "BaC", + "cBaBAaCc", + 10 + ], + [ + "BaCAA", + "cbbcBBbb", + 14 + ], + [ + "BaCAAbbB", + "BAcB", + 10 + ], + [ + "BaCAB", + "cC", + 8 + ], + [ + "BaCABCB", + "bB", + 11 + ], + [ + "BaCABccaB", + "CAacBCCA", + 12 + ], + [ + "BaCAaAc", + "bCa", + 9 + ], + [ + "BaCB", + "B", + 6 + ], + [ + "BaCBa", + "BbAbaBC", + 9 + ], + [ + "BaCBaCcCC", + "aCCAc", + 11 + ], + [ + "BaCBbCB", + "acB", + 9 + ], + [ + "BaCBc", + "ABCB", + 6 + ], + [ + "BaCBcBC", + "cc", + 11 + ], + [ + "BaCCAcAb", + "Bab", + 10 + ], + [ + "BaCCC", + "CcBCabAAa", + 14 + ], + [ + "BaCCCAcb", + "bbcAaA", + 12 + ], + [ + "BaCCCbb", + "bCCaaCb", + 9 + ], + [ + "BaCCbAA", + "acCBcBB", + 10 + ], + [ + "BaCCc", + "Ca", + 8 + ], + [ + "BaCCcCcc", + "baAbcaCc", + 8 + ], + [ + "BaCa", + "bbAba", + 6 + ], + [ + "BaCaAAaca", + "CCbCb", + 15 + ], + [ + "BaCaCCABa", + "bCaC", + 11 + ], + [ + "BaCb", + "bbaA", + 7 + ], + [ + "BaCb", + "cABC", + 7 + ], + [ + "BaCbAB", + "BAcbaAC", + 6 + ], + [ + "BaCbBA", + "bcAacBaa", + 10 + ], + [ + "BaCbBCaa", + "acBCAAcA", + 11 + ], + [ + "BaCbBcbB", + "bc", + 12 + ], + [ + "BaCbbbBaa", + "CcCAcCCC", + 16 + ], + [ + "BaCc", + "Bc", + 4 + ], + [ + "BaCc", + "CCBcbAAA", + 13 + ], + [ + "BaCcBbAb", + "BcaAaBa", + 11 + ], + [ + "BaCcCcab", + "abBAcBA", + 12 + ], + [ + "BaCcCcbAc", + "BacCAaaaA", + 11 + ], + [ + "BaCcaAabB", + "BBc", + 14 + ], + [ + "BaCcaBAa", + "AaCb", + 11 + ], + [ + "BaCccaaaA", + "cBacBCA", + 12 + ], + [ + "Baa", + "A", + 5 + ], + [ + "Baa", + "AcccabBa", + 12 + ], + [ + "Baa", + "BaaBCABcB", + 12 + ], + [ + "Baa", + "CAAa", + 5 + ], + [ + "Baa", + "CBBcBcC", + 12 + ], + [ + "Baa", + "CCABBacBb", + 14 + ], + [ + "Baa", + "CbABbAcbb", + 15 + ], + [ + "Baa", + "CbCaAbc", + 10 + ], + [ + "Baa", + "bBaBbabAc", + 12 + ], + [ + "Baa", + "bBccbbaAC", + 13 + ], + [ + "Baa", + "bcAbaAACA", + 14 + ], + [ + "BaaA", + "CaBBc", + 8 + ], + [ + "BaaA", + "baBabC", + 7 + ], + [ + "BaaABa", + "bCbcaa", + 9 + ], + [ + "BaaACcAAc", + "bccAaa", + 11 + ], + [ + "BaaAaCc", + "cB", + 13 + ], + [ + "BaaB", + "C", + 8 + ], + [ + "BaaB", + "cAa", + 5 + ], + [ + "BaaBAbAb", + "baccCC", + 13 + ], + [ + "BaaBBcA", + "ccC", + 12 + ], + [ + "BaaC", + "bCb", + 7 + ], + [ + "BaaC", + "cacAcCBcC", + 13 + ], + [ + "BaaCACAaB", + "cAaCabab", + 9 + ], + [ + "BaaCBCBBc", + "ac", + 14 + ], + [ + "BaaCbAC", + "AbCAbca", + 11 + ], + [ + "BaaCcCa", + "cBACb", + 11 + ], + [ + "BaaaBcCab", + "BaBbbbAaC", + 11 + ], + [ + "BaaaC", + "accb", + 8 + ], + [ + "Baaaa", + "B", + 8 + ], + [ + "Baaaa", + "CaA", + 7 + ], + [ + "BaaababB", + "bCAcBCB", + 11 + ], + [ + "BaaacbA", + "aBCba", + 8 + ], + [ + "Baab", + "cCAAcBa", + 11 + ], + [ + "Baab", + "ccaAACcAC", + 15 + ], + [ + "BaabA", + "b", + 8 + ], + [ + "BaabAA", + "A", + 10 + ], + [ + "BaabBAcC", + "aaBCaab", + 10 + ], + [ + "BaabBcc", + "cCCAaCbc", + 12 + ], + [ + "BaabCBCC", + "CcCaB", + 14 + ], + [ + "BaabCa", + "cAaAB", + 9 + ], + [ + "BaabCb", + "CA", + 10 + ], + [ + "Baabacaa", + "bAcbccB", + 10 + ], + [ + "Baabb", + "bBbAbbA", + 7 + ], + [ + "BaabbAaA", + "BBA", + 11 + ], + [ + "BaabcAb", + "aBaC", + 10 + ], + [ + "Baac", + "AaCacBCA", + 10 + ], + [ + "Baac", + "CcBaBAb", + 9 + ], + [ + "Baac", + "a", + 6 + ], + [ + "Baac", + "aaAB", + 5 + ], + [ + "Baac", + "cCcBC", + 9 + ], + [ + "Baac", + "ccCb", + 8 + ], + [ + "BaacCABbA", + "cA", + 14 + ], + [ + "Bab", + "BaCABaCa", + 11 + ], + [ + "Bab", + "C", + 6 + ], + [ + "Bab", + "a", + 4 + ], + [ + "Bab", + "acabAacac", + 14 + ], + [ + "Bab", + "bbCaccBaB", + 13 + ], + [ + "BabA", + "a", + 6 + ], + [ + "BabA", + "cbAc", + 6 + ], + [ + "BabAAccaB", + "abb", + 13 + ], + [ + "BabACA", + "b", + 10 + ], + [ + "BabAaC", + "baCCBcC", + 9 + ], + [ + "BabAb", + "Aa", + 8 + ], + [ + "BabAbACA", + "CBAaCaaa", + 12 + ], + [ + "BabAbCA", + "CccAab", + 12 + ], + [ + "BabBBAaCa", + "AcCAccAB", + 15 + ], + [ + "BabBa", + "ABbACcCcb", + 15 + ], + [ + "BabBcA", + "ACC", + 10 + ], + [ + "BabBcBcA", + "acbCABcB", + 10 + ], + [ + "BabC", + "aABb", + 6 + ], + [ + "BabCaBca", + "AA", + 14 + ], + [ + "Baba", + "BaBCbCBB", + 10 + ], + [ + "BabaBaAA", + "AaB", + 11 + ], + [ + "BabacAbAb", + "cCaA", + 14 + ], + [ + "Babb", + "CcAa", + 8 + ], + [ + "Babb", + "aaACcbc", + 10 + ], + [ + "BabbA", + "CaCb", + 6 + ], + [ + "BabbAaaBA", + "BbCcACC", + 13 + ], + [ + "BabbAccb", + "cacBB", + 11 + ], + [ + "BabbBcBA", + "cAabCbba", + 11 + ], + [ + "BabbCBb", + "aCCcBcB", + 10 + ], + [ + "BabbCCbCA", + "AbAcBa", + 12 + ], + [ + "BabbcBAAa", + "aCacA", + 12 + ], + [ + "BabcBAbcc", + "CabA", + 12 + ], + [ + "BabcCbCA", + "cbC", + 10 + ], + [ + "BabcaC", + "ABB", + 10 + ], + [ + "Babcac", + "bcccAbBC", + 11 + ], + [ + "Bac", + "BBcaBcC", + 8 + ], + [ + "Bac", + "CbcAbAbB", + 14 + ], + [ + "Bac", + "bacBAccb", + 11 + ], + [ + "Bac", + "bbACab", + 9 + ], + [ + "BacAa", + "bBCb", + 8 + ], + [ + "BacAaaCaB", + "ccaaAb", + 10 + ], + [ + "BacAb", + "aBBaBa", + 9 + ], + [ + "BacAbA", + "caAaBbCAb", + 11 + ], + [ + "BacBBa", + "AbBBAAA", + 10 + ], + [ + "BacBCAB", + "cCBaBCc", + 10 + ], + [ + "BacBab", + "CbBABcB", + 10 + ], + [ + "BacCAaBAB", + "ccAb", + 12 + ], + [ + "BacCBBCc", + "B", + 14 + ], + [ + "BacCCaA", + "bcaBA", + 9 + ], + [ + "BacCCcbB", + "cCbaaCBB", + 12 + ], + [ + "BacCa", + "cCBBB", + 10 + ], + [ + "BacCab", + "bA", + 10 + ], + [ + "BacCabcAc", + "CCbBC", + 12 + ], + [ + "BacCccBa", + "ABCBA", + 10 + ], + [ + "BacaB", + "bbac", + 7 + ], + [ + "BacaC", + "AAC", + 6 + ], + [ + "BacaCaBB", + "bB", + 13 + ], + [ + "BacaCbA", + "caBCAa", + 9 + ], + [ + "BacbB", + "CcaACc", + 10 + ], + [ + "BacbC", + "AAabcbbCB", + 10 + ], + [ + "BacbCbBca", + "cCcCC", + 13 + ], + [ + "BacbbCaAa", + "aCACaC", + 11 + ], + [ + "Bacc", + "b", + 7 + ], + [ + "BaccACa", + "B", + 12 + ], + [ + "BaccAaacb", + "A", + 16 + ], + [ + "BaccBcCBB", + "acb", + 13 + ], + [ + "BaccCB", + "BaC", + 6 + ], + [ + "Bacca", + "Ac", + 7 + ], + [ + "BaccaCC", + "CcbA", + 11 + ], + [ + "Baccb", + "aCc", + 5 + ], + [ + "Baccba", + "cbaaBcbc", + 9 + ], + [ + "Bb", + "AAABBB", + 9 + ], + [ + "Bb", + "AAccaCAaa", + 18 + ], + [ + "Bb", + "AaA", + 6 + ], + [ + "Bb", + "AaAAc", + 10 + ], + [ + "Bb", + "B", + 2 + ], + [ + "Bb", + "BACBbABA", + 12 + ], + [ + "Bb", + "BBaBb", + 6 + ], + [ + "Bb", + "BacCBA", + 9 + ], + [ + "Bb", + "BbCBCABAC", + 14 + ], + [ + "Bb", + "Bba", + 2 + ], + [ + "Bb", + "BcBAACA", + 11 + ], + [ + "Bb", + "CC", + 4 + ], + [ + "Bb", + "CcaaBa", + 10 + ], + [ + "Bb", + "a", + 4 + ], + [ + "Bb", + "aAbbb", + 7 + ], + [ + "Bb", + "aBa", + 4 + ], + [ + "Bb", + "aBbcCbAAC", + 14 + ], + [ + "Bb", + "aCCAB", + 9 + ], + [ + "Bb", + "aCccacCB", + 15 + ], + [ + "Bb", + "aacA", + 8 + ], + [ + "Bb", + "abBaBbAa", + 12 + ], + [ + "Bb", + "b", + 2 + ], + [ + "Bb", + "bAcCbc", + 9 + ], + [ + "Bb", + "bBaCBc", + 9 + ], + [ + "Bb", + "bBbBCccc", + 12 + ], + [ + "Bb", + "bCCc", + 7 + ], + [ + "Bb", + "bCaBcC", + 10 + ], + [ + "Bb", + "bCcbbc", + 9 + ], + [ + "Bb", + "baB", + 4 + ], + [ + "Bb", + "bc", + 3 + ], + [ + "Bb", + "bcCaacCC", + 15 + ], + [ + "Bb", + "bcaBccAcb", + 14 + ], + [ + "Bb", + "cab", + 4 + ], + [ + "Bb", + "cbAACCBb", + 12 + ], + [ + "Bb", + "cbabCcbb", + 13 + ], + [ + "Bb", + "cc", + 4 + ], + [ + "BbA", + "BCaAcABab", + 14 + ], + [ + "BbA", + "C", + 6 + ], + [ + "BbA", + "aacCbAc", + 10 + ], + [ + "BbA", + "cbCcbaAAA", + 13 + ], + [ + "BbAAaA", + "AbbBccC", + 11 + ], + [ + "BbAAaA", + "bBc", + 10 + ], + [ + "BbABB", + "BBAACAa", + 9 + ], + [ + "BbABBbAa", + "acaCCbbcB", + 14 + ], + [ + "BbABC", + "c", + 9 + ], + [ + "BbABa", + "accBbBcBb", + 12 + ], + [ + "BbABaacaA", + "b", + 16 + ], + [ + "BbAC", + "CaCCBcAa", + 12 + ], + [ + "BbAC", + "caAcaab", + 11 + ], + [ + "BbACAbcB", + "aaaAB", + 11 + ], + [ + "BbAa", + "ACcA", + 7 + ], + [ + "BbAa", + "cCA", + 6 + ], + [ + "BbAaAaaa", + "cBbbcCB", + 14 + ], + [ + "BbAaCab", + "cA", + 12 + ], + [ + "BbAaa", + "Bbbcacaa", + 7 + ], + [ + "BbAac", + "b", + 8 + ], + [ + "BbAb", + "CccCbabaC", + 13 + ], + [ + "BbAbC", + "CABA", + 7 + ], + [ + "BbAbC", + "ccA", + 8 + ], + [ + "BbAbCab", + "bcabABC", + 10 + ], + [ + "BbAbCcBab", + "CAaAbcbAC", + 12 + ], + [ + "BbAbCcaAC", + "ABbcCa", + 11 + ], + [ + "BbAbbcbb", + "B", + 14 + ], + [ + "BbAbc", + "aABB", + 7 + ], + [ + "BbAcaaaa", + "bBccaac", + 8 + ], + [ + "BbAcbca", + "acCCcbBCB", + 13 + ], + [ + "BbB", + "ACbcc", + 8 + ], + [ + "BbB", + "Acaca", + 10 + ], + [ + "BbB", + "bBcb", + 5 + ], + [ + "BbBA", + "CA", + 6 + ], + [ + "BbBABCcA", + "aaC", + 13 + ], + [ + "BbBAaBa", + "b", + 12 + ], + [ + "BbBAb", + "aaCCcb", + 10 + ], + [ + "BbBAbABAc", + "cBbbBCcB", + 12 + ], + [ + "BbBBCbca", + "cbBcCbC", + 7 + ], + [ + "BbBBa", + "cC", + 10 + ], + [ + "BbBBaBBba", + "bAC", + 15 + ], + [ + "BbBBabAb", + "cbB", + 12 + ], + [ + "BbBC", + "cbbbcaA", + 9 + ], + [ + "BbBCAbb", + "baCCbBbb", + 9 + ], + [ + "BbBCbAb", + "BbCcBbbac", + 9 + ], + [ + "BbBa", + "aCaaaA", + 10 + ], + [ + "BbBa", + "caCcb", + 10 + ], + [ + "BbBaC", + "BA", + 7 + ], + [ + "BbBaCbCcB", + "baAbCbaCc", + 11 + ], + [ + "BbBaaCBbc", + "bcAAAbC", + 11 + ], + [ + "BbBacBCca", + "c", + 16 + ], + [ + "BbBbA", + "BbaaA", + 4 + ], + [ + "BbBbBAb", + "CbcCbAaCc", + 13 + ], + [ + "BbBbBa", + "A", + 11 + ], + [ + "BbBbBbC", + "cBbacbBa", + 10 + ], + [ + "BbBbbbBAb", + "AabCcBa", + 13 + ], + [ + "BbBcBc", + "bcaaC", + 9 + ], + [ + "BbBcaAC", + "cB", + 12 + ], + [ + "BbBcabAa", + "BaBAaACc", + 10 + ], + [ + "BbBcbbC", + "bCBAabbaa", + 11 + ], + [ + "BbC", + "A", + 6 + ], + [ + "BbC", + "Cc", + 5 + ], + [ + "BbC", + "aAAAc", + 9 + ], + [ + "BbC", + "aAAbca", + 9 + ], + [ + "BbC", + "bAaBabC", + 8 + ], + [ + "BbC", + "bBCcCa", + 8 + ], + [ + "BbC", + "baCACBbc", + 11 + ], + [ + "BbC", + "bcBccBcBa", + 14 + ], + [ + "BbCAACcac", + "AcCbB", + 14 + ], + [ + "BbCAACcb", + "b", + 14 + ], + [ + "BbCAaCaC", + "BBc", + 12 + ], + [ + "BbCAbc", + "aaa", + 11 + ], + [ + "BbCAcCaCC", + "CCcB", + 13 + ], + [ + "BbCAcaab", + "BCbACaABc", + 9 + ], + [ + "BbCBCB", + "bAAccbCc", + 11 + ], + [ + "BbCBCbAc", + "CcACA", + 11 + ], + [ + "BbCCAAab", + "ccCCC", + 12 + ], + [ + "BbCCABABa", + "Acaab", + 14 + ], + [ + "BbCCBBb", + "aacCb", + 9 + ], + [ + "BbCCCBCC", + "BCA", + 12 + ], + [ + "BbCCa", + "aaaCAc", + 9 + ], + [ + "BbCCcCcCc", + "AaAAA", + 18 + ], + [ + "BbCCcbc", + "BaaBCc", + 9 + ], + [ + "BbCa", + "aCC", + 6 + ], + [ + "BbCaB", + "A", + 9 + ], + [ + "BbCaBAA", + "AbAABc", + 9 + ], + [ + "BbCaCbACB", + "AAA", + 15 + ], + [ + "BbCaCcC", + "aAAcA", + 11 + ], + [ + "BbCaCcaC", + "A", + 15 + ], + [ + "BbCbC", + "bAACAAcAC", + 13 + ], + [ + "BbCbCCb", + "AbBAA", + 11 + ], + [ + "BbCbaAB", + "C", + 12 + ], + [ + "BbCbaB", + "aAcC", + 11 + ], + [ + "BbCbaBB", + "Cabb", + 8 + ], + [ + "BbCbbBc", + "b", + 12 + ], + [ + "BbCbbb", + "cCcAcBAcA", + 16 + ], + [ + "BbCbcc", + "AAACbaaAa", + 14 + ], + [ + "BbCc", + "A", + 8 + ], + [ + "BbCc", + "aac", + 6 + ], + [ + "BbCcCACB", + "cB", + 12 + ], + [ + "BbCcaBBC", + "CB", + 12 + ], + [ + "BbCccBCB", + "cCcbBb", + 9 + ], + [ + "Bba", + "ABBBcACb", + 12 + ], + [ + "Bba", + "AbAcAbCcA", + 14 + ], + [ + "Bba", + "CaBCAaaaB", + 14 + ], + [ + "Bba", + "CacBBCBA", + 12 + ], + [ + "Bba", + "aBAcbCC", + 10 + ], + [ + "Bba", + "aCCcAaAc", + 14 + ], + [ + "Bba", + "abcA", + 5 + ], + [ + "Bba", + "bcCa", + 5 + ], + [ + "BbaAB", + "BbB", + 4 + ], + [ + "BbaABacc", + "bccbc", + 11 + ], + [ + "BbaAbBCAA", + "caAcCbc", + 12 + ], + [ + "BbaAcAb", + "bacACCbC", + 9 + ], + [ + "BbaB", + "aBbAaCb", + 7 + ], + [ + "BbaB", + "bBbBAbBC", + 9 + ], + [ + "BbaBCB", + "bcA", + 9 + ], + [ + "BbaBcbacc", + "CCBAC", + 14 + ], + [ + "BbaC", + "C", + 6 + ], + [ + "BbaCBC", + "C", + 10 + ], + [ + "BbaCCCb", + "Cca", + 11 + ], + [ + "BbaCa", + "AcCC", + 8 + ], + [ + "BbaCa", + "ccbA", + 9 + ], + [ + "BbaCcBba", + "ACb", + 11 + ], + [ + "BbaCcC", + "cbCCAAbcc", + 11 + ], + [ + "Bbaa", + "abbaAA", + 6 + ], + [ + "BbaaAbAA", + "Acc", + 14 + ], + [ + "BbaaBAb", + "CBbaCbaBB", + 9 + ], + [ + "BbaacA", + "ccAbCabAa", + 12 + ], + [ + "BbaacBcbC", + "cabbCaC", + 12 + ], + [ + "Bbab", + "BCBb", + 4 + ], + [ + "BbabA", + "Cbc", + 8 + ], + [ + "BbabBc", + "AcA", + 11 + ], + [ + "BbabC", + "ab", + 6 + ], + [ + "BbabCcBA", + "AabACBc", + 9 + ], + [ + "Bbaba", + "AAa", + 7 + ], + [ + "BbabbBb", + "b", + 12 + ], + [ + "Bbac", + "bbb", + 5 + ], + [ + "BbacB", + "CBcBB", + 7 + ], + [ + "BbacCc", + "Cb", + 10 + ], + [ + "Bbacaa", + "AaAaac", + 8 + ], + [ + "Bbb", + "ACCCCc", + 12 + ], + [ + "Bbb", + "BCABAa", + 9 + ], + [ + "Bbb", + "BabbbBcCA", + 12 + ], + [ + "Bbb", + "acaCCaa", + 14 + ], + [ + "Bbb", + "bAAcBa", + 10 + ], + [ + "Bbb", + "ccacA", + 10 + ], + [ + "BbbA", + "ACccA", + 8 + ], + [ + "BbbAAB", + "baBAb", + 7 + ], + [ + "BbbABccc", + "AbaABca", + 8 + ], + [ + "BbbAC", + "bcAaBBBca", + 14 + ], + [ + "BbbAaAba", + "a", + 14 + ], + [ + "BbbB", + "Bcc", + 6 + ], + [ + "BbbBCCA", + "cBBb", + 11 + ], + [ + "BbbBCba", + "BA", + 11 + ], + [ + "BbbBcaa", + "b", + 12 + ], + [ + "BbbCAaA", + "cbbBaBaCA", + 9 + ], + [ + "BbbCAb", + "AACC", + 10 + ], + [ + "BbbCAc", + "cbaB", + 9 + ], + [ + "BbbCBcac", + "bAbaBCba", + 10 + ], + [ + "BbbCCB", + "C", + 10 + ], + [ + "BbbCCBAc", + "cbbBcCCAC", + 8 + ], + [ + "Bbba", + "AAaAB", + 9 + ], + [ + "Bbba", + "abAc", + 6 + ], + [ + "BbbaAC", + "aBABcAAaB", + 12 + ], + [ + "BbbaC", + "AbBaaAaA", + 11 + ], + [ + "BbbaabCCA", + "CbcAb", + 13 + ], + [ + "BbbacCbb", + "AaccA", + 11 + ], + [ + "BbbbCAaA", + "cACCaCcAC", + 15 + ], + [ + "BbbbbAc", + "AbbcCb", + 10 + ], + [ + "BbbbcA", + "AaCcBabb", + 14 + ], + [ + "BbbbcbbA", + "bAA", + 12 + ], + [ + "Bbbc", + "CbccaAc", + 10 + ], + [ + "BbbcABb", + "bbbcc", + 7 + ], + [ + "BbbcB", + "bbacbbc", + 8 + ], + [ + "BbbcbAcbB", + "aCaCbaAc", + 13 + ], + [ + "Bbbcbcab", + "caCaAAbc", + 14 + ], + [ + "BbcA", + "CBaA", + 5 + ], + [ + "BbcA", + "CBcAB", + 5 + ], + [ + "BbcABcB", + "AcA", + 10 + ], + [ + "BbcACB", + "BaaCCBBC", + 10 + ], + [ + "BbcACCcB", + "bcbbaaBba", + 14 + ], + [ + "BbcAbCa", + "CbbaCba", + 9 + ], + [ + "BbcAcaB", + "Aca", + 8 + ], + [ + "BbcAccCab", + "abCCaA", + 11 + ], + [ + "BbcB", + "aACCccCaA", + 16 + ], + [ + "BbcBbB", + "baacAca", + 11 + ], + [ + "BbcBbbaC", + "Ab", + 14 + ], + [ + "BbcC", + "AccAcaBaC", + 14 + ], + [ + "BbcCB", + "bBca", + 6 + ], + [ + "BbcCBaB", + "AcCcaCbb", + 11 + ], + [ + "BbcCaab", + "cACaC", + 10 + ], + [ + "BbcaBbCCb", + "acBBcc", + 11 + ], + [ + "BbcaCcaa", + "AbcccaBB", + 9 + ], + [ + "BbcaaACb", + "A", + 14 + ], + [ + "BbcbACAa", + "a", + 14 + ], + [ + "BbcbBCCA", + "AcaCB", + 12 + ], + [ + "BbcbCcCCc", + "a", + 18 + ], + [ + "Bbcbaa", + "a", + 10 + ], + [ + "BbcbbbBab", + "aaBcBcCB", + 14 + ], + [ + "BbcbccB", + "bAACb", + 10 + ], + [ + "Bbcc", + "caAACBBb", + 15 + ], + [ + "BbccBcb", + "BCAbccb", + 8 + ], + [ + "BbccC", + "CaaAC", + 8 + ], + [ + "Bbcca", + "bBcb", + 6 + ], + [ + "BbccccCC", + "aAbcc", + 12 + ], + [ + "Bc", + "A", + 4 + ], + [ + "Bc", + "AB", + 4 + ], + [ + "Bc", + "ABAccAcC", + 12 + ], + [ + "Bc", + "ABBbBBbb", + 14 + ], + [ + "Bc", + "AaA", + 6 + ], + [ + "Bc", + "AaaBaCcCc", + 14 + ], + [ + "Bc", + "AabBBC", + 9 + ], + [ + "Bc", + "Aac", + 4 + ], + [ + "Bc", + "Aba", + 5 + ], + [ + "Bc", + "Abccbabbc", + 15 + ], + [ + "Bc", + "AcAbBC", + 9 + ], + [ + "Bc", + "B", + 2 + ], + [ + "Bc", + "BACaACBC", + 13 + ], + [ + "Bc", + "BBcBCbCB", + 12 + ], + [ + "Bc", + "BcBAAAaA", + 12 + ], + [ + "Bc", + "BcaaABCcc", + 14 + ], + [ + "Bc", + "C", + 3 + ], + [ + "Bc", + "CBCccCbaA", + 14 + ], + [ + "Bc", + "CCaBABaBA", + 16 + ], + [ + "Bc", + "CaBCBbBbc", + 14 + ], + [ + "Bc", + "CbaBCbb", + 11 + ], + [ + "Bc", + "a", + 4 + ], + [ + "Bc", + "aC", + 3 + ], + [ + "Bc", + "abAbBBcc", + 12 + ], + [ + "Bc", + "abaCAABA", + 14 + ], + [ + "Bc", + "abaabAbc", + 13 + ], + [ + "Bc", + "abcbBBB", + 11 + ], + [ + "Bc", + "ac", + 2 + ], + [ + "Bc", + "acCCcb", + 10 + ], + [ + "Bc", + "acCacaaAa", + 16 + ], + [ + "Bc", + "ba", + 3 + ], + [ + "Bc", + "cC", + 3 + ], + [ + "Bc", + "cb", + 4 + ], + [ + "Bc", + "cbACCabca", + 15 + ], + [ + "BcA", + "AC", + 5 + ], + [ + "BcA", + "BAaB", + 5 + ], + [ + "BcA", + "BBc", + 4 + ], + [ + "BcA", + "CBababB", + 11 + ], + [ + "BcA", + "CcB", + 4 + ], + [ + "BcA", + "CcCb", + 6 + ], + [ + "BcA", + "a", + 5 + ], + [ + "BcA", + "bAcab", + 6 + ], + [ + "BcA", + "bBAbb", + 7 + ], + [ + "BcA", + "bbbc", + 7 + ], + [ + "BcA", + "c", + 4 + ], + [ + "BcAABaB", + "bACcAc", + 10 + ], + [ + "BcAAaA", + "BcCAbaBb", + 8 + ], + [ + "BcAB", + "aBCCcACc", + 10 + ], + [ + "BcABAc", + "BaAa", + 7 + ], + [ + "BcABaAaA", + "aCCaCcb", + 13 + ], + [ + "BcABaa", + "CaaBBaa", + 7 + ], + [ + "BcAC", + "BCAbcbCAa", + 11 + ], + [ + "BcACAA", + "aCb", + 9 + ], + [ + "BcACB", + "bCcC", + 6 + ], + [ + "BcACBaBCa", + "BCcBAbACc", + 10 + ], + [ + "BcACC", + "aa", + 9 + ], + [ + "BcAa", + "Cb", + 7 + ], + [ + "BcAaA", + "CBBc", + 9 + ], + [ + "BcAaA", + "abBbBBcB", + 14 + ], + [ + "BcAaACA", + "cbCABAaCb", + 10 + ], + [ + "BcAaCCBB", + "cBbCaBbA", + 11 + ], + [ + "BcAaCbB", + "ACB", + 8 + ], + [ + "BcAaaaC", + "cC", + 10 + ], + [ + "BcAb", + "BB", + 5 + ], + [ + "BcAb", + "CC", + 7 + ], + [ + "BcAbAbCac", + "bab", + 13 + ], + [ + "BcAbB", + "B", + 8 + ], + [ + "BcAbabBA", + "acb", + 12 + ], + [ + "BcAbabBBB", + "BA", + 14 + ], + [ + "BcAbabC", + "BBbaCAB", + 10 + ], + [ + "BcAbbcC", + "AaAcbC", + 8 + ], + [ + "BcAbc", + "BAC", + 5 + ], + [ + "BcAbc", + "BbbcbBabB", + 11 + ], + [ + "BcAbcAAC", + "A", + 14 + ], + [ + "BcAc", + "bC", + 6 + ], + [ + "BcAcAaACb", + "aAbBBB", + 14 + ], + [ + "BcAcB", + "caaAbbccB", + 12 + ], + [ + "BcAcaccb", + "cbAbAb", + 11 + ], + [ + "BcAcba", + "aA", + 10 + ], + [ + "BcAcc", + "BCaCBcAcC", + 9 + ], + [ + "BcB", + "AcCCAC", + 10 + ], + [ + "BcB", + "BBAcaAaB", + 10 + ], + [ + "BcB", + "BabAcacCA", + 14 + ], + [ + "BcB", + "aaBcAb", + 7 + ], + [ + "BcB", + "abcC", + 5 + ], + [ + "BcB", + "bcBBCbab", + 11 + ], + [ + "BcB", + "cAAc", + 8 + ], + [ + "BcB", + "ca", + 4 + ], + [ + "BcB", + "caBaaAAb", + 13 + ], + [ + "BcBA", + "CAabC", + 9 + ], + [ + "BcBA", + "baaC", + 7 + ], + [ + "BcBAAc", + "cBBaaabBB", + 14 + ], + [ + "BcBAB", + "aCaAaBb", + 9 + ], + [ + "BcBABCB", + "aaB", + 11 + ], + [ + "BcBAccAc", + "c", + 14 + ], + [ + "BcBBBA", + "ACc", + 11 + ], + [ + "BcBBC", + "cCABb", + 7 + ], + [ + "BcBBbb", + "bbBAa", + 8 + ], + [ + "BcBBbcAaA", + "CA", + 15 + ], + [ + "BcBC", + "c", + 6 + ], + [ + "BcBCA", + "cAaCC", + 8 + ], + [ + "BcBCAAAcc", + "abc", + 15 + ], + [ + "BcBCBBC", + "BbC", + 9 + ], + [ + "BcBCbAc", + "cBBCaC", + 8 + ], + [ + "BcBCcbccc", + "BcBC", + 10 + ], + [ + "BcBCccAa", + "acb", + 13 + ], + [ + "BcBa", + "aCB", + 5 + ], + [ + "BcBaAcAAc", + "bccBBBcBc", + 11 + ], + [ + "BcBaC", + "acBbcABAa", + 11 + ], + [ + "BcBab", + "CbCACC", + 10 + ], + [ + "BcBb", + "acAABAA", + 10 + ], + [ + "BcBbA", + "Ccba", + 5 + ], + [ + "BcBbAbABB", + "a", + 17 + ], + [ + "BcBbbCAa", + "baACcBCcC", + 14 + ], + [ + "BcBbbCa", + "AcCBAa", + 9 + ], + [ + "BcBbc", + "CcABb", + 6 + ], + [ + "BcBc", + "cBBcc", + 6 + ], + [ + "BcBcAbbc", + "babC", + 11 + ], + [ + "BcBcBc", + "cAAc", + 8 + ], + [ + "BcC", + "ABabcbC", + 8 + ], + [ + "BcC", + "Ac", + 4 + ], + [ + "BcC", + "C", + 4 + ], + [ + "BcC", + "acbcaAaa", + 13 + ], + [ + "BcC", + "bAbB", + 7 + ], + [ + "BcCA", + "ccaBaaAac", + 14 + ], + [ + "BcCAABBB", + "BCabBB", + 6 + ], + [ + "BcCAaAC", + "acCaB", + 8 + ], + [ + "BcCAaBc", + "Bcab", + 7 + ], + [ + "BcCAbB", + "ACaccCB", + 10 + ], + [ + "BcCAbaACc", + "aCAAcCBC", + 12 + ], + [ + "BcCAbcbA", + "bccAbCC", + 7 + ], + [ + "BcCAcA", + "BbB", + 10 + ], + [ + "BcCBABA", + "accb", + 10 + ], + [ + "BcCBAaC", + "b", + 13 + ], + [ + "BcCBbabcc", + "cCb", + 12 + ], + [ + "BcCBc", + "ba", + 9 + ], + [ + "BcCBcaAcc", + "B", + 16 + ], + [ + "BcCBcaCbC", + "CA", + 15 + ], + [ + "BcCCAA", + "caaA", + 7 + ], + [ + "BcCCBaaa", + "AaaCBb", + 12 + ], + [ + "BcCCCAA", + "b", + 13 + ], + [ + "BcCCaaaA", + "BccaAabBa", + 9 + ], + [ + "BcCCbCac", + "AcAa", + 12 + ], + [ + "BcCa", + "AB", + 8 + ], + [ + "BcCa", + "cB", + 6 + ], + [ + "BcCaACC", + "cbACaA", + 9 + ], + [ + "BcCaACCc", + "aaaCb", + 11 + ], + [ + "BcCaBbCAC", + "AbaAc", + 12 + ], + [ + "BcCaBc", + "CCAAB", + 8 + ], + [ + "BcCaCacc", + "CaCbbbc", + 10 + ], + [ + "BcCaaC", + "AcC", + 8 + ], + [ + "BcCb", + "aBacB", + 6 + ], + [ + "BcCbAcCb", + "CAA", + 12 + ], + [ + "BcCbCCCa", + "CBCC", + 9 + ], + [ + "BcCbaBabc", + "abcbB", + 13 + ], + [ + "BcCbbb", + "ccBCb", + 6 + ], + [ + "BcCc", + "bBb", + 7 + ], + [ + "BcCcBBb", + "aCCC", + 10 + ], + [ + "BcCcBcAb", + "aacbBbC", + 13 + ], + [ + "BcCca", + "CCcCaaB", + 8 + ], + [ + "Bca", + "AcbCBab", + 10 + ], + [ + "Bca", + "Bb", + 4 + ], + [ + "Bca", + "Bcc", + 2 + ], + [ + "Bca", + "CAAbA", + 9 + ], + [ + "Bca", + "CcBc", + 6 + ], + [ + "Bca", + "aAAccCBB", + 14 + ], + [ + "Bca", + "aCbbBBcCb", + 14 + ], + [ + "Bca", + "ac", + 4 + ], + [ + "Bca", + "c", + 4 + ], + [ + "BcaAAbACa", + "cAaacBB", + 13 + ], + [ + "BcaAaC", + "B", + 10 + ], + [ + "BcaB", + "A", + 7 + ], + [ + "BcaB", + "ABC", + 7 + ], + [ + "BcaB", + "AcAacA", + 8 + ], + [ + "BcaB", + "CAba", + 7 + ], + [ + "BcaB", + "cc", + 6 + ], + [ + "BcaBACC", + "aabAcbb", + 10 + ], + [ + "BcaBACbA", + "cB", + 12 + ], + [ + "BcaBAc", + "CAcBaCC", + 10 + ], + [ + "BcaBb", + "bABA", + 6 + ], + [ + "BcaBcab", + "aAaA", + 10 + ], + [ + "BcaC", + "abbAb", + 8 + ], + [ + "BcaC", + "ba", + 5 + ], + [ + "BcaC", + "ccaCBCB", + 8 + ], + [ + "BcaCBAbA", + "BA", + 12 + ], + [ + "BcaCC", + "CAbBbB", + 12 + ], + [ + "BcaCCbb", + "bbb", + 9 + ], + [ + "BcaCc", + "AaCABAACA", + 13 + ], + [ + "Bcaa", + "C", + 7 + ], + [ + "Bcaa", + "CbBABaa", + 8 + ], + [ + "Bcaa", + "cbbBcc", + 10 + ], + [ + "BcaaAc", + "AcaCCb", + 8 + ], + [ + "BcaaBBa", + "bBBCAAb", + 12 + ], + [ + "BcaaBcB", + "cCBbbAAcA", + 13 + ], + [ + "Bcaaba", + "ACbcA", + 10 + ], + [ + "Bcaabc", + "Bba", + 8 + ], + [ + "BcaacbcC", + "CBBBbCCA", + 12 + ], + [ + "Bcab", + "AcABabB", + 8 + ], + [ + "Bcab", + "abA", + 6 + ], + [ + "BcabB", + "BcbCc", + 6 + ], + [ + "BcabBB", + "BbAbbbA", + 7 + ], + [ + "BcabCA", + "b", + 10 + ], + [ + "BcabCac", + "BbAAaca", + 9 + ], + [ + "Bcaba", + "aCcbA", + 6 + ], + [ + "BcabaABA", + "CAbB", + 10 + ], + [ + "Bcac", + "CcCAbaaa", + 12 + ], + [ + "Bcac", + "ccc", + 4 + ], + [ + "BcacAC", + "abBc", + 9 + ], + [ + "BcacAaca", + "acbAbc", + 10 + ], + [ + "BcacCB", + "cbabacC", + 9 + ], + [ + "BcacaBC", + "ACCac", + 9 + ], + [ + "BcacabbA", + "Bcb", + 10 + ], + [ + "Bcacc", + "b", + 9 + ], + [ + "Bcb", + "AaAcacaB", + 13 + ], + [ + "Bcb", + "Cc", + 4 + ], + [ + "Bcb", + "aBBC", + 6 + ], + [ + "BcbAACc", + "aBBcA", + 11 + ], + [ + "BcbAAb", + "ab", + 9 + ], + [ + "BcbAC", + "AcC", + 6 + ], + [ + "BcbAaaacc", + "cc", + 14 + ], + [ + "BcbB", + "BbcbBbBC", + 8 + ], + [ + "BcbB", + "aB", + 6 + ], + [ + "BcbBcB", + "bCbb", + 7 + ], + [ + "BcbCA", + "bCc", + 6 + ], + [ + "BcbCAAba", + "CCaa", + 10 + ], + [ + "BcbCBCA", + "BcBa", + 7 + ], + [ + "BcbCC", + "b", + 8 + ], + [ + "BcbCCcc", + "Abb", + 12 + ], + [ + "BcbCabC", + "A", + 13 + ], + [ + "BcbCcB", + "cbaccCa", + 9 + ], + [ + "Bcba", + "ACa", + 5 + ], + [ + "Bcbb", + "baaAa", + 9 + ], + [ + "BcbbA", + "BBb", + 5 + ], + [ + "BcbbC", + "ccaBAABCC", + 12 + ], + [ + "BcbcA", + "bcBcAAcB", + 8 + ], + [ + "BcbcB", + "Ccc", + 6 + ], + [ + "Bcc", + "Ab", + 6 + ], + [ + "Bcc", + "BCAbacBc", + 10 + ], + [ + "Bcc", + "aacb", + 6 + ], + [ + "Bcc", + "baAa", + 7 + ], + [ + "BccABAbcA", + "Aba", + 13 + ], + [ + "BccACA", + "aa", + 10 + ], + [ + "BccAcAbbC", + "caC", + 13 + ], + [ + "BccBA", + "BACCAC", + 7 + ], + [ + "BccBAAbb", + "aac", + 14 + ], + [ + "BccBCbAA", + "BBCCC", + 10 + ], + [ + "BccBaAaa", + "AACAbbbbB", + 16 + ], + [ + "BccBac", + "CCabACa", + 10 + ], + [ + "BccC", + "ac", + 6 + ], + [ + "BccC", + "bCA", + 6 + ], + [ + "BccCa", + "caaBBaaB", + 14 + ], + [ + "BccCab", + "Cbcbac", + 8 + ], + [ + "BccCacBC", + "BBbA", + 13 + ], + [ + "BccCcA", + "BcCBCAB", + 6 + ], + [ + "Bcca", + "AAb", + 8 + ], + [ + "BccaA", + "cCC", + 7 + ], + [ + "BccaA", + "ccc", + 6 + ], + [ + "BccaBbB", + "AA", + 13 + ], + [ + "Bccac", + "CcbaCCa", + 9 + ], + [ + "Bccb", + "AcbC", + 6 + ], + [ + "BccbB", + "bbccA", + 7 + ], + [ + "BccbBCAA", + "AA", + 12 + ], + [ + "BccbBaCbb", + "CbcBBCAA", + 11 + ], + [ + "BccbacAAc", + "CAac", + 12 + ], + [ + "BccbbACa", + "acCAbCAc", + 10 + ], + [ + "BcccAC", + "cccBbBaac", + 12 + ], + [ + "BcccBB", + "bABCc", + 10 + ], + [ + "BcccBBb", + "Cbacbaa", + 11 + ], + [ + "C", + "A", + 2 + ], + [ + "C", + "AAA", + 6 + ], + [ + "C", + "AAAb", + 8 + ], + [ + "C", + "AAB", + 6 + ], + [ + "C", + "AAacba", + 11 + ], + [ + "C", + "AAbb", + 8 + ], + [ + "C", + "ABA", + 6 + ], + [ + "C", + "ABAB", + 8 + ], + [ + "C", + "ABAcBAabA", + 17 + ], + [ + "C", + "ABCB", + 6 + ], + [ + "C", + "ABCbbbBAC", + 16 + ], + [ + "C", + "ABabc", + 9 + ], + [ + "C", + "ACCCcAcAa", + 16 + ], + [ + "C", + "ACc", + 4 + ], + [ + "C", + "ACcbaABc", + 14 + ], + [ + "C", + "AaAAa", + 10 + ], + [ + "C", + "AaAa", + 8 + ], + [ + "C", + "AaAbcaBb", + 15 + ], + [ + "C", + "AabbbC", + 10 + ], + [ + "C", + "AacCCABaB", + 16 + ], + [ + "C", + "AacaaaB", + 13 + ], + [ + "C", + "Ab", + 4 + ], + [ + "C", + "AbBbBACab", + 16 + ], + [ + "C", + "AbBcCcBAb", + 16 + ], + [ + "C", + "AbC", + 4 + ], + [ + "C", + "AbCCaCbc", + 14 + ], + [ + "C", + "Abb", + 6 + ], + [ + "C", + "AbbCcBb", + 12 + ], + [ + "C", + "Acbc", + 7 + ], + [ + "C", + "B", + 2 + ], + [ + "C", + "BAAbAbCa", + 14 + ], + [ + "C", + "BAAc", + 7 + ], + [ + "C", + "BACcBbAcB", + 16 + ], + [ + "C", + "BBBaAcB", + 13 + ], + [ + "C", + "BBacaaA", + 13 + ], + [ + "C", + "BC", + 2 + ], + [ + "C", + "BCCbA", + 8 + ], + [ + "C", + "BCba", + 6 + ], + [ + "C", + "Ba", + 4 + ], + [ + "C", + "BaA", + 6 + ], + [ + "C", + "BaBCCBcb", + 14 + ], + [ + "C", + "BaBcbbCBA", + 16 + ], + [ + "C", + "BaaC", + 6 + ], + [ + "C", + "BabbcCBa", + 14 + ], + [ + "C", + "BacccCB", + 12 + ], + [ + "C", + "BbABc", + 9 + ], + [ + "C", + "BbAaAAC", + 12 + ], + [ + "C", + "BbBBcc", + 11 + ], + [ + "C", + "BbCBCB", + 10 + ], + [ + "C", + "BbcCCbAC", + 14 + ], + [ + "C", + "BcB", + 5 + ], + [ + "C", + "BcBBBbAaa", + 17 + ], + [ + "C", + "BcCAcacAB", + 16 + ], + [ + "C", + "BcCB", + 6 + ], + [ + "C", + "BcacCaB", + 12 + ], + [ + "C", + "BccAaa", + 11 + ], + [ + "C", + "BccaAa", + 11 + ], + [ + "C", + "C", + 0 + ], + [ + "C", + "CA", + 2 + ], + [ + "C", + "CAAbCa", + 10 + ], + [ + "C", + "CABBB", + 8 + ], + [ + "C", + "CAaAa", + 8 + ], + [ + "C", + "CAbAABb", + 12 + ], + [ + "C", + "CBBCaABbB", + 16 + ], + [ + "C", + "CBaacB", + 10 + ], + [ + "C", + "CBc", + 4 + ], + [ + "C", + "CC", + 2 + ], + [ + "C", + "CCA", + 4 + ], + [ + "C", + "CCBbccA", + 12 + ], + [ + "C", + "CCc", + 4 + ], + [ + "C", + "CCcbbCBCc", + 16 + ], + [ + "C", + "CCcc", + 6 + ], + [ + "C", + "CCccCaCa", + 14 + ], + [ + "C", + "Ca", + 2 + ], + [ + "C", + "CaA", + 4 + ], + [ + "C", + "Caab", + 6 + ], + [ + "C", + "Cacaacba", + 14 + ], + [ + "C", + "Cb", + 2 + ], + [ + "C", + "CbaCBcAb", + 14 + ], + [ + "C", + "CbbBCbC", + 12 + ], + [ + "C", + "Cc", + 2 + ], + [ + "C", + "CcAcCA", + 10 + ], + [ + "C", + "CcBBCbBB", + 14 + ], + [ + "C", + "CcCBBbB", + 12 + ], + [ + "C", + "a", + 2 + ], + [ + "C", + "aA", + 4 + ], + [ + "C", + "aAABBb", + 12 + ], + [ + "C", + "aACBaca", + 12 + ], + [ + "C", + "aAaCB", + 8 + ], + [ + "C", + "aAaaBcaB", + 15 + ], + [ + "C", + "aAabb", + 10 + ], + [ + "C", + "aAccAABB", + 15 + ], + [ + "C", + "aBAaa", + 10 + ], + [ + "C", + "aBbab", + 10 + ], + [ + "C", + "aCBccCbBc", + 16 + ], + [ + "C", + "aCCBcbcBc", + 16 + ], + [ + "C", + "aCCC", + 6 + ], + [ + "C", + "aCcB", + 6 + ], + [ + "C", + "aCcccA", + 10 + ], + [ + "C", + "aa", + 4 + ], + [ + "C", + "aaBA", + 8 + ], + [ + "C", + "aaBAbA", + 12 + ], + [ + "C", + "aaBabBB", + 14 + ], + [ + "C", + "aaCAC", + 8 + ], + [ + "C", + "aaCBb", + 8 + ], + [ + "C", + "aaaBcBBc", + 15 + ], + [ + "C", + "aaab", + 8 + ], + [ + "C", + "aab", + 6 + ], + [ + "C", + "aacCCabb", + 14 + ], + [ + "C", + "abBbAcaCc", + 16 + ], + [ + "C", + "abbbAaaC", + 14 + ], + [ + "C", + "abcBBB", + 11 + ], + [ + "C", + "ac", + 3 + ], + [ + "C", + "b", + 2 + ], + [ + "C", + "bAAAccb", + 13 + ], + [ + "C", + "bAAaCBaCa", + 16 + ], + [ + "C", + "bAaABACCb", + 16 + ], + [ + "C", + "bAbAcCAc", + 14 + ], + [ + "C", + "bBABA", + 10 + ], + [ + "C", + "bBB", + 6 + ], + [ + "C", + "bBacA", + 9 + ], + [ + "C", + "bBcbbCabb", + 16 + ], + [ + "C", + "bC", + 2 + ], + [ + "C", + "bCcAcACba", + 16 + ], + [ + "C", + "ba", + 4 + ], + [ + "C", + "baAA", + 8 + ], + [ + "C", + "baAba", + 10 + ], + [ + "C", + "baCABab", + 12 + ], + [ + "C", + "baaA", + 8 + ], + [ + "C", + "baaB", + 8 + ], + [ + "C", + "baaCbCb", + 12 + ], + [ + "C", + "bbABBCA", + 12 + ], + [ + "C", + "bbABcCb", + 12 + ], + [ + "C", + "bbCab", + 8 + ], + [ + "C", + "bbacCaabC", + 16 + ], + [ + "C", + "bbbcaAb", + 13 + ], + [ + "C", + "bc", + 3 + ], + [ + "C", + "bcAca", + 9 + ], + [ + "C", + "bcBAABAAC", + 16 + ], + [ + "C", + "bcBcA", + 9 + ], + [ + "C", + "bcC", + 4 + ], + [ + "C", + "bcCAb", + 8 + ], + [ + "C", + "bcaAb", + 9 + ], + [ + "C", + "bcacBAC", + 12 + ], + [ + "C", + "bcb", + 5 + ], + [ + "C", + "bcbBba", + 11 + ], + [ + "C", + "bcbacaAA", + 15 + ], + [ + "C", + "bccC", + 6 + ], + [ + "C", + "bccccCA", + 12 + ], + [ + "C", + "c", + 1 + ], + [ + "C", + "cAc", + 5 + ], + [ + "C", + "cAcBCbCb", + 14 + ], + [ + "C", + "cAcaABCA", + 14 + ], + [ + "C", + "cBAA", + 7 + ], + [ + "C", + "cBBB", + 7 + ], + [ + "C", + "cBc", + 5 + ], + [ + "C", + "cBccbAA", + 13 + ], + [ + "C", + "cC", + 2 + ], + [ + "C", + "cCBAAB", + 10 + ], + [ + "C", + "cCaACAAC", + 14 + ], + [ + "C", + "cCbA", + 6 + ], + [ + "C", + "cCbbABa", + 12 + ], + [ + "C", + "cCcabCbBb", + 16 + ], + [ + "C", + "ca", + 3 + ], + [ + "C", + "caCACCCaB", + 16 + ], + [ + "C", + "cabCa", + 8 + ], + [ + "C", + "cacACaBB", + 14 + ], + [ + "C", + "cacBaACc", + 14 + ], + [ + "C", + "cbACabc", + 12 + ], + [ + "C", + "cbCCB", + 8 + ], + [ + "C", + "cbcC", + 6 + ], + [ + "C", + "cc", + 3 + ], + [ + "C", + "ccBAbBBC", + 14 + ], + [ + "C", + "ccBaC", + 8 + ], + [ + "C", + "ccaCbbCbb", + 16 + ], + [ + "C", + "ccabC", + 8 + ], + [ + "C", + "ccbBbCCc", + 14 + ], + [ + "CA", + "A", + 2 + ], + [ + "CA", + "AAa", + 4 + ], + [ + "CA", + "Aaacbb", + 11 + ], + [ + "CA", + "AcC", + 5 + ], + [ + "CA", + "BBaB", + 7 + ], + [ + "CA", + "BcAcbBC", + 11 + ], + [ + "CA", + "C", + 2 + ], + [ + "CA", + "CBCAa", + 6 + ], + [ + "CA", + "CacbbBaa", + 13 + ], + [ + "CA", + "CcBcBAB", + 10 + ], + [ + "CA", + "CcbCaBB", + 11 + ], + [ + "CA", + "a", + 3 + ], + [ + "CA", + "aAABAaC", + 12 + ], + [ + "CA", + "aABBa", + 8 + ], + [ + "CA", + "abbCC", + 8 + ], + [ + "CA", + "acbb", + 7 + ], + [ + "CA", + "bAbAAcbA", + 13 + ], + [ + "CA", + "bAcBcACC", + 13 + ], + [ + "CA", + "bCBaBBaB", + 13 + ], + [ + "CA", + "bbbB", + 8 + ], + [ + "CA", + "cAaaaA", + 9 + ], + [ + "CA", + "caCBCcaaA", + 14 + ], + [ + "CAA", + "CCbc", + 6 + ], + [ + "CAA", + "CbCcba", + 9 + ], + [ + "CAA", + "bb", + 6 + ], + [ + "CAA", + "c", + 5 + ], + [ + "CAA", + "cACAaa", + 7 + ], + [ + "CAA", + "cAaabbacA", + 13 + ], + [ + "CAAA", + "bb", + 8 + ], + [ + "CAAAAAcCB", + "bC", + 16 + ], + [ + "CAAAB", + "ba", + 9 + ], + [ + "CAAABaBAc", + "CaaC", + 12 + ], + [ + "CAAACa", + "AAcbAAc", + 9 + ], + [ + "CAAACaAC", + "aABBcbcBa", + 15 + ], + [ + "CAAAaBAa", + "BCBc", + 14 + ], + [ + "CAAAba", + "CacBaB", + 8 + ], + [ + "CAAAbb", + "cCaCb", + 8 + ], + [ + "CAAB", + "CbcCbBBA", + 12 + ], + [ + "CAABAAcBC", + "bccb", + 14 + ], + [ + "CAABAAcbB", + "ABBa", + 13 + ], + [ + "CAABCaaBa", + "aBCACcBca", + 12 + ], + [ + "CAABCcAAa", + "ccCB", + 15 + ], + [ + "CAABbaA", + "AbBaAac", + 10 + ], + [ + "CAAC", + "cacABc", + 7 + ], + [ + "CAACAAC", + "Ab", + 12 + ], + [ + "CAACAbca", + "Bb", + 14 + ], + [ + "CAACCAc", + "CAAB", + 8 + ], + [ + "CAACb", + "CA", + 6 + ], + [ + "CAAa", + "cBCC", + 7 + ], + [ + "CAAaBaAC", + "AaccBBB", + 13 + ], + [ + "CAAaaA", + "CaAaACca", + 7 + ], + [ + "CAAab", + "b", + 8 + ], + [ + "CAAabac", + "Accbbc", + 8 + ], + [ + "CAAbCbCcC", + "B", + 17 + ], + [ + "CAAbb", + "caC", + 8 + ], + [ + "CAAbbAbb", + "BC", + 15 + ], + [ + "CAAcBB", + "aCBCbAAb", + 13 + ], + [ + "CAAccAcC", + "abA", + 13 + ], + [ + "CAB", + "ABabCcc", + 12 + ], + [ + "CAB", + "ABccbC", + 10 + ], + [ + "CAB", + "CABba", + 4 + ], + [ + "CAB", + "CcbB", + 4 + ], + [ + "CAB", + "aababa", + 10 + ], + [ + "CAB", + "bC", + 6 + ], + [ + "CAB", + "cAbbABAac", + 13 + ], + [ + "CABA", + "CaabCCc", + 10 + ], + [ + "CABAAa", + "abC", + 10 + ], + [ + "CABACacA", + "cAbaaABC", + 10 + ], + [ + "CABACcA", + "B", + 12 + ], + [ + "CABAa", + "aac", + 8 + ], + [ + "CABAcBa", + "b", + 13 + ], + [ + "CABBAa", + "bbBcabcC", + 13 + ], + [ + "CABBBAa", + "B", + 12 + ], + [ + "CABBBCaa", + "ACb", + 12 + ], + [ + "CABBBb", + "cacaAACa", + 14 + ], + [ + "CABC", + "cCbacA", + 9 + ], + [ + "CABCAcaC", + "B", + 14 + ], + [ + "CABa", + "B", + 6 + ], + [ + "CABaCc", + "BCaaaAAcb", + 11 + ], + [ + "CABab", + "baB", + 6 + ], + [ + "CABacBA", + "BaACb", + 10 + ], + [ + "CABb", + "bCcBaCba", + 10 + ], + [ + "CABbABcBA", + "aBaAccabA", + 10 + ], + [ + "CABbbC", + "CbACCAcc", + 11 + ], + [ + "CABcAaAb", + "bb", + 13 + ], + [ + "CABcaa", + "C", + 10 + ], + [ + "CABcaa", + "aCaBABAab", + 10 + ], + [ + "CABcabCAa", + "AcbaBcCA", + 11 + ], + [ + "CABcbCAc", + "ABAcc", + 9 + ], + [ + "CABcbbA", + "BBbcA", + 8 + ], + [ + "CABcbcacA", + "cb", + 14 + ], + [ + "CAC", + "aCAAaABb", + 12 + ], + [ + "CAC", + "abCCACaBc", + 12 + ], + [ + "CAC", + "bbcbB", + 9 + ], + [ + "CAC", + "caBAa", + 7 + ], + [ + "CAC", + "ccBaBcb", + 11 + ], + [ + "CACAACccb", + "bc", + 16 + ], + [ + "CACABBA", + "cCACAcCcC", + 10 + ], + [ + "CACACAcBB", + "aBAACCc", + 12 + ], + [ + "CACAabc", + "cbAaBbbbB", + 13 + ], + [ + "CACAcaAC", + "ACcACc", + 8 + ], + [ + "CACAcbC", + "Cc", + 10 + ], + [ + "CACB", + "Cbc", + 5 + ], + [ + "CACBb", + "C", + 8 + ], + [ + "CACC", + "bCa", + 6 + ], + [ + "CACCAAB", + "bACabAC", + 8 + ], + [ + "CACCAb", + "abBBB", + 10 + ], + [ + "CACCCBA", + "cabaac", + 12 + ], + [ + "CACCc", + "ba", + 9 + ], + [ + "CACaAcc", + "acaBbCbb", + 13 + ], + [ + "CACaCBBc", + "a", + 14 + ], + [ + "CACaabcBb", + "aCabba", + 10 + ], + [ + "CACacaABb", + "b", + 16 + ], + [ + "CACb", + "ABbb", + 6 + ], + [ + "CACb", + "AabbaCa", + 11 + ], + [ + "CACbA", + "bCbbC", + 8 + ], + [ + "CACbaCB", + "caacaaC", + 9 + ], + [ + "CACbaaCa", + "bBacacB", + 12 + ], + [ + "CACbbBBc", + "Bc", + 12 + ], + [ + "CACbc", + "Cc", + 6 + ], + [ + "CACbcAcac", + "cCAcA", + 10 + ], + [ + "CACbcba", + "caABaCb", + 10 + ], + [ + "CACcBabCc", + "baAbbaBB", + 13 + ], + [ + "CACcCacC", + "ABcC", + 10 + ], + [ + "CACccCAC", + "B", + 16 + ], + [ + "CAa", + "Ab", + 4 + ], + [ + "CAa", + "CabcCc", + 9 + ], + [ + "CAa", + "aaCAbaBc", + 10 + ], + [ + "CAa", + "bABABaCA", + 12 + ], + [ + "CAa", + "bBAaB", + 6 + ], + [ + "CAa", + "bca", + 4 + ], + [ + "CAa", + "cbC", + 5 + ], + [ + "CAaAAaA", + "abAbbcbaC", + 14 + ], + [ + "CAaAAbaaB", + "CAcBB", + 11 + ], + [ + "CAaAcb", + "bBCBB", + 11 + ], + [ + "CAaBAA", + "AacAcBABB", + 11 + ], + [ + "CAaBB", + "Cc", + 8 + ], + [ + "CAaBBACa", + "CAaacBccC", + 9 + ], + [ + "CAaBC", + "b", + 9 + ], + [ + "CAaBbbaBA", + "BBB", + 13 + ], + [ + "CAaC", + "AaBCacAba", + 14 + ], + [ + "CAaC", + "BcccCbBb", + 13 + ], + [ + "CAaCBbcab", + "CbC", + 13 + ], + [ + "CAaCc", + "AA", + 7 + ], + [ + "CAaCcabB", + "cBABCb", + 11 + ], + [ + "CAaCccCc", + "A", + 14 + ], + [ + "CAaa", + "bcABBaAb", + 10 + ], + [ + "CAaa", + "cbabABAC", + 12 + ], + [ + "CAaaB", + "b", + 9 + ], + [ + "CAaabBcC", + "a", + 14 + ], + [ + "CAaabbCac", + "bAC", + 14 + ], + [ + "CAaabcaB", + "cabCacbaA", + 12 + ], + [ + "CAabABbAa", + "bcbaCa", + 13 + ], + [ + "CAabac", + "baaABbB", + 10 + ], + [ + "CAabb", + "b", + 8 + ], + [ + "CAabb", + "cACACBaBB", + 10 + ], + [ + "CAac", + "aaB", + 5 + ], + [ + "CAac", + "cccBB", + 9 + ], + [ + "CAacAB", + "a", + 10 + ], + [ + "CAaccC", + "cacbc", + 6 + ], + [ + "CAb", + "ACCCAcaA", + 12 + ], + [ + "CAb", + "Aca", + 6 + ], + [ + "CAb", + "BCcBBAA", + 10 + ], + [ + "CAb", + "C", + 4 + ], + [ + "CAb", + "CCAcbAB", + 8 + ], + [ + "CAb", + "CcCbCBC", + 10 + ], + [ + "CAb", + "acAc", + 5 + ], + [ + "CAb", + "bab", + 3 + ], + [ + "CAb", + "cA", + 3 + ], + [ + "CAbAAaAA", + "abc", + 13 + ], + [ + "CAbAc", + "ABBCCB", + 10 + ], + [ + "CAbB", + "acC", + 7 + ], + [ + "CAbBBBB", + "BCcaBbabB", + 10 + ], + [ + "CAbBCCBAC", + "baA", + 14 + ], + [ + "CAbBab", + "cbABcBc", + 10 + ], + [ + "CAbBc", + "bBcAcCA", + 11 + ], + [ + "CAbBc", + "bCAcbba", + 7 + ], + [ + "CAbC", + "AaAc", + 6 + ], + [ + "CAbC", + "cBAC", + 5 + ], + [ + "CAbCBaBb", + "cAbcBa", + 6 + ], + [ + "CAbCCC", + "c", + 11 + ], + [ + "CAbCabbA", + "BbAABACba", + 12 + ], + [ + "CAbCcc", + "babBA", + 9 + ], + [ + "CAba", + "abbB", + 6 + ], + [ + "CAbaAbBBC", + "CbBBAbB", + 9 + ], + [ + "CAbaAcCCC", + "AcbB", + 14 + ], + [ + "CAbaBb", + "A", + 10 + ], + [ + "CAbaa", + "cc", + 9 + ], + [ + "CAbacbba", + "cBCccabA", + 10 + ], + [ + "CAbbAA", + "BAAaCbC", + 12 + ], + [ + "CAbbAAcC", + "CBBACbBCB", + 12 + ], + [ + "CAbbBCcB", + "Abca", + 10 + ], + [ + "CAbbBbC", + "ABcaca", + 11 + ], + [ + "CAbbbAC", + "bcB", + 11 + ], + [ + "CAbbcCABA", + "CbB", + 12 + ], + [ + "CAbc", + "B", + 7 + ], + [ + "CAbcA", + "CAcaccACb", + 10 + ], + [ + "CAbcACCB", + "BB", + 13 + ], + [ + "CAbcBAa", + "bccBACB", + 10 + ], + [ + "CAbcCca", + "cAc", + 9 + ], + [ + "CAbcaBbca", + "ccaacBaaa", + 12 + ], + [ + "CAc", + "AAcacbcC", + 12 + ], + [ + "CAc", + "AbbAbbcc", + 12 + ], + [ + "CAc", + "BAB", + 4 + ], + [ + "CAc", + "ab", + 5 + ], + [ + "CAc", + "b", + 6 + ], + [ + "CAc", + "bbaaac", + 9 + ], + [ + "CAcAaCcaC", + "AAa", + 12 + ], + [ + "CAcAbaaA", + "ccBcBc", + 12 + ], + [ + "CAcAcC", + "BAbCb", + 9 + ], + [ + "CAcAca", + "CCbb", + 9 + ], + [ + "CAcAcbbAc", + "Cca", + 13 + ], + [ + "CAcB", + "cBcaaCcB", + 10 + ], + [ + "CAcBbCccb", + "BBAbAbAB", + 15 + ], + [ + "CAcBbbAaA", + "aACbbCbaa", + 9 + ], + [ + "CAcBbcbCa", + "bcBc", + 12 + ], + [ + "CAcBcBC", + "abCaCb", + 11 + ], + [ + "CAcC", + "CBcB", + 4 + ], + [ + "CAcCACCA", + "cAAa", + 10 + ], + [ + "CAcCaCBCC", + "aac", + 14 + ], + [ + "CAca", + "AaBACbAab", + 13 + ], + [ + "CAcaABcab", + "aCCbC", + 14 + ], + [ + "CAcaaa", + "bbccA", + 9 + ], + [ + "CAcaacBB", + "c", + 14 + ], + [ + "CAcb", + "B", + 7 + ], + [ + "CAcb", + "aBCBAb", + 8 + ], + [ + "CAcbBA", + "bBAaba", + 9 + ], + [ + "CAcbBB", + "CCcCBA", + 6 + ], + [ + "CAcbBacb", + "AbbbB", + 10 + ], + [ + "CAcbCCaaC", + "bccB", + 14 + ], + [ + "CAcbCbc", + "bAcCA", + 8 + ], + [ + "CAcbbabC", + "abAccCaac", + 11 + ], + [ + "CAcbcA", + "BBca", + 8 + ], + [ + "CAcbcB", + "Ab", + 8 + ], + [ + "CAcc", + "b", + 8 + ], + [ + "CAccAaAcc", + "bccbAB", + 12 + ], + [ + "CAccBaAC", + "abbAAaB", + 13 + ], + [ + "CAccBaaCc", + "BCAb", + 15 + ], + [ + "CAccBbA", + "bcBbBcBc", + 13 + ], + [ + "CAccac", + "aAc", + 8 + ], + [ + "CB", + "A", + 4 + ], + [ + "CB", + "ABac", + 6 + ], + [ + "CB", + "AC", + 4 + ], + [ + "CB", + "ACbbcbb", + 11 + ], + [ + "CB", + "ACcCCBAC", + 12 + ], + [ + "CB", + "AaAAcBc", + 11 + ], + [ + "CB", + "AaBCab", + 9 + ], + [ + "CB", + "BCc", + 4 + ], + [ + "CB", + "BaCaB", + 6 + ], + [ + "CB", + "BccbcabCB", + 14 + ], + [ + "CB", + "C", + 2 + ], + [ + "CB", + "CAAAb", + 7 + ], + [ + "CB", + "CCba", + 5 + ], + [ + "CB", + "CaAcA", + 8 + ], + [ + "CB", + "CcCaAccb", + 13 + ], + [ + "CB", + "a", + 4 + ], + [ + "CB", + "aAa", + 6 + ], + [ + "CB", + "aBCBaBbC", + 12 + ], + [ + "CB", + "aCbcAc", + 9 + ], + [ + "CB", + "ac", + 4 + ], + [ + "CB", + "bAa", + 6 + ], + [ + "CB", + "bBAAbcb", + 12 + ], + [ + "CB", + "bCB", + 2 + ], + [ + "CB", + "bCaCCcaCA", + 16 + ], + [ + "CB", + "ba", + 4 + ], + [ + "CB", + "baBCcCc", + 12 + ], + [ + "CB", + "bbcbCB", + 8 + ], + [ + "CB", + "bcaab", + 8 + ], + [ + "CB", + "c", + 3 + ], + [ + "CB", + "cACca", + 8 + ], + [ + "CB", + "cBCbAB", + 8 + ], + [ + "CB", + "cCB", + 2 + ], + [ + "CB", + "cbb", + 4 + ], + [ + "CB", + "cbbBbACCA", + 15 + ], + [ + "CBA", + "ba", + 4 + ], + [ + "CBA", + "cbcBb", + 7 + ], + [ + "CBAA", + "ABBaBcB", + 11 + ], + [ + "CBAA", + "Ba", + 5 + ], + [ + "CBAA", + "bcc", + 7 + ], + [ + "CBAABa", + "BAaBA", + 4 + ], + [ + "CBAAC", + "CBAac", + 2 + ], + [ + "CBAAa", + "cccbAb", + 9 + ], + [ + "CBAAaac", + "bcAAb", + 10 + ], + [ + "CBAAbCc", + "bbaABBB", + 9 + ], + [ + "CBAAbbBC", + "CbBAaAc", + 10 + ], + [ + "CBAAc", + "AAA", + 6 + ], + [ + "CBAAc", + "bCbBbAAaC", + 9 + ], + [ + "CBAB", + "A", + 6 + ], + [ + "CBABAbcBA", + "b", + 16 + ], + [ + "CBABAcBc", + "cAb", + 12 + ], + [ + "CBABCacb", + "aCCbbBABA", + 14 + ], + [ + "CBABaa", + "cBbcCcc", + 11 + ], + [ + "CBABbbCa", + "BbAaA", + 11 + ], + [ + "CBABbcCCC", + "cCAC", + 12 + ], + [ + "CBABc", + "cCc", + 7 + ], + [ + "CBABccBbc", + "caAaaACbb", + 13 + ], + [ + "CBACAA", + "CCc", + 8 + ], + [ + "CBACAcC", + "aCbbc", + 10 + ], + [ + "CBACa", + "BACaBBaB", + 10 + ], + [ + "CBACbcB", + "a", + 13 + ], + [ + "CBACc", + "baCCCA", + 9 + ], + [ + "CBACcAccA", + "aAb", + 15 + ], + [ + "CBAaAC", + "ccbC", + 9 + ], + [ + "CBAaBaC", + "bCccccCb", + 14 + ], + [ + "CBAaCB", + "acabB", + 8 + ], + [ + "CBAaCa", + "Cabb", + 8 + ], + [ + "CBAaCc", + "cBBBBBaC", + 11 + ], + [ + "CBAabb", + "bbCabaBa", + 10 + ], + [ + "CBAacCa", + "Bccbacb", + 11 + ], + [ + "CBAb", + "cCAcbc", + 7 + ], + [ + "CBAbCcaB", + "aC", + 13 + ], + [ + "CBAba", + "CbbabA", + 5 + ], + [ + "CBAbabb", + "BABa", + 7 + ], + [ + "CBAbba", + "ba", + 8 + ], + [ + "CBAcAAbcb", + "BBBBBbABA", + 15 + ], + [ + "CBAcC", + "acbabBA", + 11 + ], + [ + "CBAccB", + "cb", + 9 + ], + [ + "CBAccab", + "cbB", + 11 + ], + [ + "CBB", + "Aa", + 6 + ], + [ + "CBB", + "BbAaC", + 9 + ], + [ + "CBB", + "CB", + 2 + ], + [ + "CBB", + "CCA", + 4 + ], + [ + "CBB", + "CcbCb", + 6 + ], + [ + "CBB", + "baBB", + 4 + ], + [ + "CBB", + "cAcBBccA", + 11 + ], + [ + "CBB", + "cBccaB", + 7 + ], + [ + "CBBABB", + "BbBb", + 6 + ], + [ + "CBBABC", + "AABcaac", + 10 + ], + [ + "CBBAbACb", + "CCBCbAbcB", + 8 + ], + [ + "CBBBA", + "bB", + 7 + ], + [ + "CBBBBaAC", + "ca", + 13 + ], + [ + "CBBBBbbcC", + "BaAbCaB", + 14 + ], + [ + "CBBBb", + "bCbaBBAb", + 7 + ], + [ + "CBBBbCbcA", + "ABCCcABc", + 13 + ], + [ + "CBBC", + "ACaca", + 8 + ], + [ + "CBBC", + "cB", + 5 + ], + [ + "CBBCAAB", + "b", + 13 + ], + [ + "CBBCAb", + "CBA", + 6 + ], + [ + "CBBCCAB", + "AbCa", + 10 + ], + [ + "CBBCCa", + "c", + 11 + ], + [ + "CBBCabAa", + "Cca", + 11 + ], + [ + "CBBaCc", + "CbbA", + 7 + ], + [ + "CBBab", + "acBCcA", + 9 + ], + [ + "CBBabb", + "BBCcBb", + 7 + ], + [ + "CBBacBacB", + "caCCccBc", + 12 + ], + [ + "CBBbAb", + "Bbab", + 5 + ], + [ + "CBBba", + "bcCcb", + 9 + ], + [ + "CBBbaAcbc", + "ABcABaAAc", + 11 + ], + [ + "CBBbbbabc", + "baAaBC", + 12 + ], + [ + "CBBbcaaC", + "bABABABB", + 13 + ], + [ + "CBBc", + "abCABc", + 6 + ], + [ + "CBBcACB", + "abBbC", + 9 + ], + [ + "CBBcBcc", + "A", + 14 + ], + [ + "CBBcbA", + "ccbBAca", + 9 + ], + [ + "CBBcbaBc", + "C", + 14 + ], + [ + "CBBcbaC", + "bBcAAbaaC", + 9 + ], + [ + "CBBccBCCB", + "bacCC", + 11 + ], + [ + "CBBccc", + "aBabc", + 8 + ], + [ + "CBC", + "ACB", + 4 + ], + [ + "CBC", + "CAbCabB", + 9 + ], + [ + "CBC", + "aCaAaAC", + 10 + ], + [ + "CBCAA", + "C", + 8 + ], + [ + "CBCAABa", + "BBcCbBa", + 7 + ], + [ + "CBCAACB", + "bBBcAAB", + 7 + ], + [ + "CBCACAa", + "ABbA", + 10 + ], + [ + "CBCAaCA", + "BbaAbac", + 10 + ], + [ + "CBCAacCc", + "cCb", + 12 + ], + [ + "CBCB", + "aAAaA", + 10 + ], + [ + "CBCBBA", + "acc", + 11 + ], + [ + "CBCBBCAA", + "ABC", + 12 + ], + [ + "CBCBC", + "aBccbCB", + 8 + ], + [ + "CBCBCC", + "BAbc", + 8 + ], + [ + "CBCC", + "CbaaA", + 7 + ], + [ + "CBCCBC", + "aACAA", + 10 + ], + [ + "CBCCBCcCb", + "Ba", + 16 + ], + [ + "CBCCCB", + "cacbAbbaA", + 15 + ], + [ + "CBCCCbaB", + "cacAbc", + 12 + ], + [ + "CBCCacb", + "a", + 12 + ], + [ + "CBCCbcc", + "BbbBcbCBc", + 11 + ], + [ + "CBCCcCbA", + "CBaAa", + 11 + ], + [ + "CBCa", + "aaAbbabA", + 13 + ], + [ + "CBCa", + "b", + 7 + ], + [ + "CBCaA", + "ab", + 8 + ], + [ + "CBCaAaBaa", + "acBbAa", + 12 + ], + [ + "CBCaB", + "caa", + 7 + ], + [ + "CBCacBBBB", + "BcabACCb", + 12 + ], + [ + "CBCb", + "AabACCa", + 11 + ], + [ + "CBCb", + "aABc", + 7 + ], + [ + "CBCbBa", + "abaCaB", + 9 + ], + [ + "CBCbbc", + "CcBCBCcbA", + 9 + ], + [ + "CBCbccaA", + "AbCbbCba", + 9 + ], + [ + "CBCc", + "bbcCBBAcb", + 12 + ], + [ + "CBCcB", + "BAa", + 8 + ], + [ + "CBCcBbb", + "ccaCBbA", + 8 + ], + [ + "CBCcccacB", + "BA", + 15 + ], + [ + "CBa", + "ACaba", + 5 + ], + [ + "CBa", + "CAaB", + 4 + ], + [ + "CBa", + "CBBCccc", + 10 + ], + [ + "CBa", + "CacAccB", + 11 + ], + [ + "CBa", + "c", + 5 + ], + [ + "CBaAAa", + "caCcaBAA", + 9 + ], + [ + "CBaAC", + "CBb", + 6 + ], + [ + "CBaAbaaAA", + "CbbcC", + 13 + ], + [ + "CBaB", + "aabBAbbC", + 12 + ], + [ + "CBaBBAa", + "AaAcA", + 10 + ], + [ + "CBaBCABC", + "AAA", + 13 + ], + [ + "CBaBaCcB", + "cBaAbBAAa", + 12 + ], + [ + "CBaBaa", + "AAB", + 9 + ], + [ + "CBaCAbC", + "BbCaCC", + 7 + ], + [ + "CBaCBba", + "bcABB", + 10 + ], + [ + "CBaCCAB", + "cBcBAcA", + 10 + ], + [ + "CBaCabccB", + "Bba", + 14 + ], + [ + "CBaaA", + "AacbaC", + 10 + ], + [ + "CBaaAcac", + "aacbcbACc", + 13 + ], + [ + "CBaaB", + "CbaAcB", + 4 + ], + [ + "CBaaBc", + "Ba", + 8 + ], + [ + "CBaaCaCa", + "c", + 15 + ], + [ + "CBaaaBB", + "B", + 12 + ], + [ + "CBaab", + "BaabBcba", + 10 + ], + [ + "CBaab", + "bBB", + 7 + ], + [ + "CBaabAB", + "CBCC", + 10 + ], + [ + "CBaacACCC", + "a", + 16 + ], + [ + "CBab", + "CB", + 4 + ], + [ + "CBab", + "aBcc", + 6 + ], + [ + "CBabACCaA", + "A", + 16 + ], + [ + "CBabCbbaC", + "AcbAc", + 12 + ], + [ + "CBacA", + "acBCCaCB", + 10 + ], + [ + "CBacaCBCB", + "aB", + 14 + ], + [ + "CBacbacB", + "CaBa", + 9 + ], + [ + "CBb", + "Cbb", + 1 + ], + [ + "CBb", + "a", + 6 + ], + [ + "CBb", + "bBbcc", + 6 + ], + [ + "CBb", + "bCaaaA", + 10 + ], + [ + "CBbA", + "bAaCbBC", + 10 + ], + [ + "CBbAAa", + "aabB", + 10 + ], + [ + "CBbAB", + "A", + 8 + ], + [ + "CBbAB", + "bbb", + 6 + ], + [ + "CBbACca", + "CbCAcB", + 7 + ], + [ + "CBbACcbC", + "bCcbBAb", + 12 + ], + [ + "CBbBB", + "C", + 8 + ], + [ + "CBbBB", + "CBCBcCBa", + 8 + ], + [ + "CBbBBCaBB", + "AbAca", + 13 + ], + [ + "CBbCA", + "aca", + 8 + ], + [ + "CBbCCB", + "BAbC", + 8 + ], + [ + "CBbCCCa", + "Ca", + 10 + ], + [ + "CBbCCb", + "CACbBBb", + 8 + ], + [ + "CBbCbbBc", + "ABaA", + 14 + ], + [ + "CBbaAcAAc", + "ccAACB", + 12 + ], + [ + "CBbaAca", + "bB", + 12 + ], + [ + "CBbaB", + "B", + 8 + ], + [ + "CBbaBBCaC", + "baaCcA", + 12 + ], + [ + "CBbaC", + "c", + 9 + ], + [ + "CBbaCa", + "cbbcAa", + 6 + ], + [ + "CBbaCbB", + "AcCcACbA", + 10 + ], + [ + "CBbabC", + "abB", + 8 + ], + [ + "CBbb", + "C", + 6 + ], + [ + "CBbb", + "a", + 8 + ], + [ + "CBbbbaB", + "B", + 12 + ], + [ + "CBbc", + "BaAABc", + 9 + ], + [ + "CBbcBAAB", + "cAbCAA", + 8 + ], + [ + "CBbcbb", + "cBCaC", + 8 + ], + [ + "CBc", + "Bcab", + 6 + ], + [ + "CBc", + "CBAAacc", + 8 + ], + [ + "CBc", + "abaCa", + 8 + ], + [ + "CBc", + "cAabccaaA", + 14 + ], + [ + "CBcA", + "CCA", + 3 + ], + [ + "CBcAAaccC", + "abBcAbaBC", + 10 + ], + [ + "CBcAaCCCb", + "aB", + 15 + ], + [ + "CBcAbAA", + "BabCcAAc", + 11 + ], + [ + "CBcAcB", + "CbbAAA", + 7 + ], + [ + "CBcB", + "a", + 8 + ], + [ + "CBcB", + "bcCBCCcbb", + 11 + ], + [ + "CBcBA", + "cBbCb", + 7 + ], + [ + "CBcBBABcc", + "bbBcabA", + 13 + ], + [ + "CBcBC", + "cAbCAAbcA", + 13 + ], + [ + "CBcBaaACB", + "cCc", + 14 + ], + [ + "CBcBb", + "c", + 8 + ], + [ + "CBcC", + "bCBBbBa", + 10 + ], + [ + "CBcC", + "c", + 6 + ], + [ + "CBcCC", + "aB", + 8 + ], + [ + "CBca", + "cC", + 6 + ], + [ + "CBcaAa", + "A", + 10 + ], + [ + "CBcaAba", + "AaAAaaCaA", + 13 + ], + [ + "CBcaBCc", + "AcBcb", + 9 + ], + [ + "CBcabbbba", + "bCCBc", + 15 + ], + [ + "CBcacCbCC", + "bCAaab", + 13 + ], + [ + "CBcb", + "Acb", + 4 + ], + [ + "CBcb", + "CbcABCA", + 8 + ], + [ + "CBcb", + "cBAac", + 7 + ], + [ + "CBcbCbc", + "cBBaBc", + 7 + ], + [ + "CBcbCcaBc", + "BAACAaC", + 11 + ], + [ + "CBcba", + "abCA", + 7 + ], + [ + "CBcbab", + "ABBabBC", + 9 + ], + [ + "CBcbbaC", + "ABcCa", + 8 + ], + [ + "CBcbcAAA", + "aaAbb", + 14 + ], + [ + "CBcbcbC", + "c", + 12 + ], + [ + "CBccaC", + "CAAa", + 8 + ], + [ + "CBccaCaaa", + "ccbBabcBB", + 15 + ], + [ + "CBccac", + "aB", + 10 + ], + [ + "CBccbaAbb", + "bBaacaC", + 14 + ], + [ + "CBccbbc", + "ACaAaCB", + 13 + ], + [ + "CC", + "AA", + 4 + ], + [ + "CC", + "AAaacAc", + 12 + ], + [ + "CC", + "ACACbCABB", + 14 + ], + [ + "CC", + "ACBaCAb", + 10 + ], + [ + "CC", + "ACaaB", + 8 + ], + [ + "CC", + "ACcCAaabb", + 14 + ], + [ + "CC", + "AacCBBc", + 11 + ], + [ + "CC", + "BaAACABCC", + 14 + ], + [ + "CC", + "BaBcaCbb", + 13 + ], + [ + "CC", + "Bc", + 3 + ], + [ + "CC", + "CBC", + 2 + ], + [ + "CC", + "CCAAAbab", + 12 + ], + [ + "CC", + "CCc", + 2 + ], + [ + "CC", + "Cb", + 2 + ], + [ + "CC", + "CbbBb", + 8 + ], + [ + "CC", + "CcAc", + 5 + ], + [ + "CC", + "a", + 4 + ], + [ + "CC", + "aACcC", + 6 + ], + [ + "CC", + "aBC", + 4 + ], + [ + "CC", + "aBbc", + 7 + ], + [ + "CC", + "aa", + 4 + ], + [ + "CC", + "bA", + 4 + ], + [ + "CC", + "c", + 3 + ], + [ + "CC", + "cBBB", + 7 + ], + [ + "CC", + "cBcCbBcab", + 15 + ], + [ + "CC", + "cCabBBC", + 10 + ], + [ + "CC", + "cCbBB", + 7 + ], + [ + "CCA", + "A", + 4 + ], + [ + "CCA", + "BaaabCA", + 10 + ], + [ + "CCA", + "CBaCacAB", + 10 + ], + [ + "CCA", + "aba", + 5 + ], + [ + "CCA", + "bb", + 6 + ], + [ + "CCAA", + "ABBCA", + 8 + ], + [ + "CCAA", + "BcCbBA", + 7 + ], + [ + "CCAA", + "babAabAA", + 12 + ], + [ + "CCAA", + "cAcC", + 7 + ], + [ + "CCAABbAAc", + "CA", + 14 + ], + [ + "CCAABc", + "BacACaaB", + 11 + ], + [ + "CCAACAbaa", + "BA", + 16 + ], + [ + "CCAAaB", + "CaCCcCa", + 10 + ], + [ + "CCAAbabbc", + "cc", + 15 + ], + [ + "CCAAcCCcA", + "ABcACaBc", + 13 + ], + [ + "CCAAcb", + "C", + 10 + ], + [ + "CCAB", + "bbc", + 8 + ], + [ + "CCABAAB", + "BCABbccB", + 8 + ], + [ + "CCABBCcbB", + "CabB", + 11 + ], + [ + "CCABCCAaa", + "CBCc", + 11 + ], + [ + "CCABb", + "Bcc", + 9 + ], + [ + "CCABcCBAa", + "bbBa", + 13 + ], + [ + "CCABcaC", + "caCc", + 10 + ], + [ + "CCABcbBaC", + "cAAaAAaC", + 11 + ], + [ + "CCAC", + "aBAccBA", + 11 + ], + [ + "CCACb", + "BABcBc", + 10 + ], + [ + "CCACbACc", + "Aabbbac", + 11 + ], + [ + "CCACcaCB", + "ABbCACbB", + 11 + ], + [ + "CCAa", + "aACCbaaac", + 11 + ], + [ + "CCAb", + "ACCBba", + 6 + ], + [ + "CCAbBcABA", + "cAaCBc", + 12 + ], + [ + "CCAbBcb", + "baCB", + 10 + ], + [ + "CCAbCAb", + "BaCCaa", + 10 + ], + [ + "CCAbaC", + "BBbcaa", + 10 + ], + [ + "CCAbaCBa", + "bcccA", + 12 + ], + [ + "CCAcAB", + "ccAAbCa", + 9 + ], + [ + "CCAcACA", + "acBA", + 9 + ], + [ + "CCAcBAa", + "aCacBaBAA", + 8 + ], + [ + "CCAcC", + "BbcBbC", + 9 + ], + [ + "CCAcCB", + "cBcaBBBA", + 11 + ], + [ + "CCAcaC", + "CcaB", + 6 + ], + [ + "CCAcaaca", + "cC", + 13 + ], + [ + "CCAcacccc", + "cAcabcB", + 9 + ], + [ + "CCAcbCb", + "ACCa", + 9 + ], + [ + "CCAcbbCBc", + "CcAbBCa", + 8 + ], + [ + "CCB", + "ACbaAACcB", + 12 + ], + [ + "CCB", + "Cc", + 3 + ], + [ + "CCB", + "abaAB", + 8 + ], + [ + "CCB", + "baCac", + 8 + ], + [ + "CCBA", + "Aaaaa", + 9 + ], + [ + "CCBAA", + "a", + 9 + ], + [ + "CCBABcc", + "BCABb", + 8 + ], + [ + "CCBAC", + "bCCcaCAc", + 9 + ], + [ + "CCBAbAC", + "bCA", + 10 + ], + [ + "CCBAc", + "BC", + 7 + ], + [ + "CCBAcaacb", + "aCCAA", + 13 + ], + [ + "CCBBCBccb", + "BBAa", + 14 + ], + [ + "CCBBbB", + "CbcAACa", + 11 + ], + [ + "CCBBccC", + "c", + 12 + ], + [ + "CCBC", + "CBCaABac", + 9 + ], + [ + "CCBCAaAA", + "CaC", + 12 + ], + [ + "CCBCBCcc", + "bcCccbAbb", + 13 + ], + [ + "CCBCb", + "c", + 9 + ], + [ + "CCBaAaB", + "bACAC", + 11 + ], + [ + "CCBaAaB", + "cbcCBca", + 11 + ], + [ + "CCBaAcba", + "BaaaCAA", + 11 + ], + [ + "CCBaBbbBC", + "a", + 16 + ], + [ + "CCBaCcAa", + "ccBbACCb", + 10 + ], + [ + "CCBbAAAB", + "CCcaBabc", + 11 + ], + [ + "CCBbACc", + "bbbaacBb", + 12 + ], + [ + "CCBbB", + "cBBBACC", + 10 + ], + [ + "CCBbBC", + "bAcCCab", + 12 + ], + [ + "CCBbabCB", + "bCcaB", + 10 + ], + [ + "CCBbca", + "bc", + 8 + ], + [ + "CCBcB", + "ACbbCa", + 8 + ], + [ + "CCBca", + "BacCaaAA", + 12 + ], + [ + "CCBcbbC", + "cB", + 11 + ], + [ + "CCC", + "CcaB", + 5 + ], + [ + "CCC", + "baaaC", + 8 + ], + [ + "CCCAABC", + "CC", + 10 + ], + [ + "CCCAbbBCb", + "cBBaaBab", + 12 + ], + [ + "CCCAc", + "BaccCaB", + 9 + ], + [ + "CCCBAbcc", + "accAb", + 10 + ], + [ + "CCCBBcab", + "ACCA", + 11 + ], + [ + "CCCBCaAcC", + "aaCcAbAa", + 14 + ], + [ + "CCCBbbbC", + "aCb", + 12 + ], + [ + "CCCBcBBaa", + "aBACAbAA", + 14 + ], + [ + "CCCBccaB", + "ccBcc", + 8 + ], + [ + "CCCC", + "bBcAaAbaC", + 15 + ], + [ + "CCCCA", + "BBACa", + 7 + ], + [ + "CCCCA", + "bAcAbbC", + 13 + ], + [ + "CCCCA", + "cccAC", + 7 + ], + [ + "CCCCAbaa", + "CaBaccBB", + 14 + ], + [ + "CCCCBC", + "ABbBc", + 9 + ], + [ + "CCCCCa", + "BCACA", + 7 + ], + [ + "CCCCaBCA", + "Bacbcab", + 13 + ], + [ + "CCCCbaC", + "b", + 12 + ], + [ + "CCCCbbba", + "BAbcAbcBb", + 14 + ], + [ + "CCCCcA", + "bbCCbbc", + 10 + ], + [ + "CCCCcBAC", + "acACBcC", + 9 + ], + [ + "CCCa", + "bAb", + 8 + ], + [ + "CCCaABacb", + "bacBBcAA", + 14 + ], + [ + "CCCaCcA", + "bAcAC", + 10 + ], + [ + "CCCaCcbBA", + "bAbc", + 15 + ], + [ + "CCCaaCaBA", + "AbAbBCb", + 15 + ], + [ + "CCCabaaab", + "cAbca", + 12 + ], + [ + "CCCacacb", + "CAcCBcA", + 10 + ], + [ + "CCCb", + "C", + 6 + ], + [ + "CCCbBBB", + "A", + 14 + ], + [ + "CCCba", + "BbAcaC", + 10 + ], + [ + "CCCbbAA", + "a", + 13 + ], + [ + "CCCbbaA", + "cCB", + 10 + ], + [ + "CCCbbcc", + "BCA", + 12 + ], + [ + "CCCc", + "CBbBBaBBa", + 16 + ], + [ + "CCCcBBba", + "CcBbcAa", + 9 + ], + [ + "CCCcBaA", + "CCCBAAAcA", + 9 + ], + [ + "CCa", + "Ca", + 2 + ], + [ + "CCa", + "CbabbAAcA", + 14 + ], + [ + "CCa", + "bbbCBA", + 9 + ], + [ + "CCa", + "cCAcbAbCC", + 14 + ], + [ + "CCaA", + "c", + 7 + ], + [ + "CCaAA", + "BBACcB", + 11 + ], + [ + "CCaAAb", + "cBa", + 9 + ], + [ + "CCaABbBaA", + "CcACab", + 11 + ], + [ + "CCaAcb", + "ABbBCaCa", + 13 + ], + [ + "CCaBAcbAC", + "CBbc", + 11 + ], + [ + "CCaBBA", + "bAbBB", + 8 + ], + [ + "CCaCAAbA", + "AA", + 12 + ], + [ + "CCaCACBcb", + "caC", + 13 + ], + [ + "CCaCAaA", + "BCAaCaa", + 7 + ], + [ + "CCaCB", + "CAAA", + 7 + ], + [ + "CCaCBcAC", + "bcCa", + 12 + ], + [ + "CCaCCC", + "CACcBa", + 8 + ], + [ + "CCaCaCc", + "BcCba", + 11 + ], + [ + "CCaCaCcBA", + "a", + 16 + ], + [ + "CCaCabaAa", + "CcccAacAC", + 11 + ], + [ + "CCaCb", + "bAcaCbCAb", + 11 + ], + [ + "CCaCbaaaC", + "CaCBCBBc", + 10 + ], + [ + "CCaaBbbA", + "BAAc", + 14 + ], + [ + "CCaaCbCab", + "aBbB", + 13 + ], + [ + "CCaaaaccC", + "AABcca", + 12 + ], + [ + "CCaacBa", + "a", + 12 + ], + [ + "CCabA", + "acbCAAbb", + 10 + ], + [ + "CCabA", + "bbaacCA", + 10 + ], + [ + "CCabCAac", + "ABABA", + 12 + ], + [ + "CCabcCbc", + "BCbc", + 9 + ], + [ + "CCac", + "a", + 6 + ], + [ + "CCacAac", + "bbBbaC", + 11 + ], + [ + "CCacAbCcb", + "bCbBa", + 14 + ], + [ + "CCacBca", + "C", + 12 + ], + [ + "CCacCb", + "cBAC", + 8 + ], + [ + "CCacab", + "Aa", + 9 + ], + [ + "CCacbb", + "CAb", + 7 + ], + [ + "CCacbcB", + "Cca", + 9 + ], + [ + "CCb", + "BAbBAaB", + 12 + ], + [ + "CCb", + "CAAAbca", + 10 + ], + [ + "CCb", + "bAc", + 6 + ], + [ + "CCb", + "bcabBaB", + 11 + ], + [ + "CCb", + "cbCcaAaac", + 15 + ], + [ + "CCbA", + "AABAC", + 7 + ], + [ + "CCbA", + "BbBCabCaa", + 13 + ], + [ + "CCbAAa", + "BcABbC", + 11 + ], + [ + "CCbABCC", + "a", + 13 + ], + [ + "CCbACCBa", + "BbbaBbC", + 12 + ], + [ + "CCbAaaA", + "aB", + 12 + ], + [ + "CCbAbC", + "cAacBCa", + 10 + ], + [ + "CCbAbbBB", + "abcaA", + 13 + ], + [ + "CCbB", + "Aa", + 8 + ], + [ + "CCbB", + "cbaBCBBA", + 10 + ], + [ + "CCbBBB", + "CACCacCBc", + 12 + ], + [ + "CCbBCC", + "BbCAbcAA", + 12 + ], + [ + "CCbBbaBa", + "BcbccCAc", + 13 + ], + [ + "CCbCBCbB", + "cCbbB", + 7 + ], + [ + "CCbCbA", + "ABACcA", + 8 + ], + [ + "CCbCbcacC", + "bBC", + 13 + ], + [ + "CCba", + "aBaAcAaCC", + 15 + ], + [ + "CCba", + "caCAcc", + 9 + ], + [ + "CCba", + "cbaCcba", + 7 + ], + [ + "CCbaB", + "Ba", + 7 + ], + [ + "CCbaBB", + "CCaccA", + 8 + ], + [ + "CCbaCC", + "aBbcaa", + 10 + ], + [ + "CCbaaBcAB", + "a", + 16 + ], + [ + "CCbaba", + "ACbaBAAb", + 8 + ], + [ + "CCbb", + "aBbacACBa", + 14 + ], + [ + "CCbbACcA", + "CBabaAA", + 9 + ], + [ + "CCbbAabCa", + "cAABb", + 13 + ], + [ + "CCbbBabb", + "aBBcc", + 13 + ], + [ + "CCbbaBC", + "cBC", + 9 + ], + [ + "CCbbca", + "bAC", + 9 + ], + [ + "CCbbcaCBA", + "CCaAaBBAB", + 10 + ], + [ + "CCbcAac", + "a", + 12 + ], + [ + "CCbcBC", + "aabbAc", + 9 + ], + [ + "CCbcBca", + "B", + 12 + ], + [ + "CCbcCAc", + "Bb", + 12 + ], + [ + "CCbcb", + "cBaC", + 8 + ], + [ + "CCbcc", + "aBaccBcB", + 11 + ], + [ + "CCc", + "A", + 6 + ], + [ + "CCc", + "Ac", + 4 + ], + [ + "CCc", + "Bc", + 4 + ], + [ + "CCc", + "Cacbb", + 6 + ], + [ + "CCc", + "bCcbAbbAB", + 14 + ], + [ + "CCcAC", + "CABCA", + 7 + ], + [ + "CCcACBCC", + "B", + 14 + ], + [ + "CCcACc", + "cACCCA", + 8 + ], + [ + "CCcAaaba", + "CCCBcABca", + 9 + ], + [ + "CCcAc", + "abaaaCCc", + 13 + ], + [ + "CCcB", + "aCAaBc", + 8 + ], + [ + "CCcBAB", + "CacAbbcbB", + 11 + ], + [ + "CCcBAcC", + "bB", + 12 + ], + [ + "CCcBbAb", + "aBbC", + 10 + ], + [ + "CCcBcaB", + "cBbb", + 9 + ], + [ + "CCcCaaAC", + "CAAbccC", + 12 + ], + [ + "CCcCb", + "B", + 9 + ], + [ + "CCcCbacba", + "AAa", + 15 + ], + [ + "CCcCcABB", + "cAcBabacb", + 13 + ], + [ + "CCcCcccAB", + "BAaACCCAB", + 11 + ], + [ + "CCca", + "Acc", + 5 + ], + [ + "CCca", + "a", + 6 + ], + [ + "CCcaBCabB", + "cAabc", + 11 + ], + [ + "CCcaC", + "bbCACAA", + 10 + ], + [ + "CCcaCca", + "CabacBb", + 9 + ], + [ + "CCcaaBaB", + "ccaAabb", + 9 + ], + [ + "CCcaaabbc", + "BCaCC", + 13 + ], + [ + "CCcabA", + "bCCAAcaBC", + 9 + ], + [ + "CCcacbB", + "Babb", + 9 + ], + [ + "CCcb", + "C", + 6 + ], + [ + "CCcbB", + "abB", + 6 + ], + [ + "CCcbBBC", + "aAAaCCCc", + 14 + ], + [ + "CCcbC", + "ACcBBBBc", + 10 + ], + [ + "CCcbC", + "a", + 10 + ], + [ + "CCcbCACab", + "Accba", + 11 + ], + [ + "CCcbcaaaA", + "ccaaAbaaB", + 12 + ], + [ + "CCccAAB", + "CCaaa", + 8 + ], + [ + "CCccB", + "AACBAbC", + 11 + ], + [ + "CCcca", + "baAaCccaa", + 10 + ], + [ + "CCccaAA", + "b", + 14 + ], + [ + "CCccbb", + "babC", + 10 + ], + [ + "Ca", + "ABCCb", + 8 + ], + [ + "Ca", + "AaCcCBaab", + 14 + ], + [ + "Ca", + "Aac", + 4 + ], + [ + "Ca", + "BAAABca", + 11 + ], + [ + "Ca", + "BACaCCb", + 10 + ], + [ + "Ca", + "BAc", + 5 + ], + [ + "Ca", + "BBAA", + 7 + ], + [ + "Ca", + "BCB", + 4 + ], + [ + "Ca", + "BCBbBaAC", + 12 + ], + [ + "Ca", + "BaCCAcBAa", + 14 + ], + [ + "Ca", + "BabB", + 6 + ], + [ + "Ca", + "BababbBb", + 14 + ], + [ + "Ca", + "BbCB", + 6 + ], + [ + "Ca", + "Bbb", + 6 + ], + [ + "Ca", + "CAbc", + 5 + ], + [ + "Ca", + "CBAbac", + 8 + ], + [ + "Ca", + "CBB", + 4 + ], + [ + "Ca", + "CBaA", + 4 + ], + [ + "Ca", + "CCAB", + 5 + ], + [ + "Ca", + "CCaCBaaA", + 12 + ], + [ + "Ca", + "CCbaAA", + 8 + ], + [ + "Ca", + "CCbb", + 6 + ], + [ + "Ca", + "Cb", + 2 + ], + [ + "Ca", + "aACCba", + 8 + ], + [ + "Ca", + "aB", + 4 + ], + [ + "Ca", + "aBBA", + 7 + ], + [ + "Ca", + "aac", + 4 + ], + [ + "Ca", + "acBacBcAA", + 15 + ], + [ + "Ca", + "b", + 4 + ], + [ + "Ca", + "bAbBbbAa", + 14 + ], + [ + "Ca", + "bBCA", + 5 + ], + [ + "Ca", + "bbBAAAa", + 12 + ], + [ + "Ca", + "c", + 3 + ], + [ + "Ca", + "cCBCBbAAa", + 14 + ], + [ + "Ca", + "caBabaBc", + 13 + ], + [ + "Ca", + "ccCaCCC", + 10 + ], + [ + "CaA", + "BcBcAb", + 9 + ], + [ + "CaA", + "CCBBA", + 6 + ], + [ + "CaA", + "aBa", + 5 + ], + [ + "CaA", + "aBcbcb", + 11 + ], + [ + "CaA", + "bBcCBcbcc", + 16 + ], + [ + "CaA", + "bCABC", + 7 + ], + [ + "CaA", + "bCcBaAaA", + 10 + ], + [ + "CaA", + "c", + 5 + ], + [ + "CaAA", + "bacCbbA", + 10 + ], + [ + "CaAABbc", + "c", + 12 + ], + [ + "CaAAC", + "c", + 9 + ], + [ + "CaAACB", + "bB", + 10 + ], + [ + "CaAAa", + "AcCbA", + 9 + ], + [ + "CaAAbcCa", + "a", + 14 + ], + [ + "CaAB", + "BCaCaCB", + 7 + ], + [ + "CaAB", + "Ba", + 6 + ], + [ + "CaAB", + "bCb", + 7 + ], + [ + "CaABBc", + "b", + 11 + ], + [ + "CaABCBA", + "bBb", + 11 + ], + [ + "CaABa", + "B", + 8 + ], + [ + "CaABbACB", + "BA", + 12 + ], + [ + "CaABbC", + "AAacAc", + 9 + ], + [ + "CaAC", + "BBCbCcaaC", + 11 + ], + [ + "CaAC", + "aCAABab", + 9 + ], + [ + "CaAC", + "acCBbcbA", + 13 + ], + [ + "CaACB", + "B", + 8 + ], + [ + "CaACbacC", + "BAbabAAB", + 12 + ], + [ + "CaACbc", + "CBA", + 8 + ], + [ + "CaACcBACc", + "aAcc", + 10 + ], + [ + "CaAa", + "Bababa", + 7 + ], + [ + "CaAa", + "ccAC", + 5 + ], + [ + "CaAaAC", + "ACa", + 9 + ], + [ + "CaAaACCc", + "BaabbBCbC", + 12 + ], + [ + "CaAaBbB", + "cbAb", + 9 + ], + [ + "CaAaa", + "cAAACBa", + 7 + ], + [ + "CaAab", + "BBbcbaa", + 12 + ], + [ + "CaAabcABB", + "ACcBacC", + 14 + ], + [ + "CaAbC", + "bC", + 6 + ], + [ + "CaAbbBa", + "c", + 13 + ], + [ + "CaAc", + "Ac", + 4 + ], + [ + "CaAc", + "abB", + 6 + ], + [ + "CaAcCAb", + "cABCaAA", + 9 + ], + [ + "CaAcCa", + "bBabcCCC", + 10 + ], + [ + "CaAca", + "bcAcBAABA", + 13 + ], + [ + "CaAcb", + "aBbACB", + 8 + ], + [ + "CaAcc", + "ACc", + 5 + ], + [ + "CaB", + "B", + 4 + ], + [ + "CaB", + "C", + 4 + ], + [ + "CaB", + "acbCAcC", + 11 + ], + [ + "CaB", + "bbAaAaBB", + 12 + ], + [ + "CaB", + "cabbb", + 6 + ], + [ + "CaBA", + "cbcAB", + 7 + ], + [ + "CaBAAB", + "BBAC", + 8 + ], + [ + "CaBAAB", + "a", + 10 + ], + [ + "CaBAAaBB", + "AACB", + 10 + ], + [ + "CaBAbCb", + "baA", + 10 + ], + [ + "CaBAcBCcb", + "A", + 16 + ], + [ + "CaBAcc", + "AACCaA", + 11 + ], + [ + "CaBAcc", + "bAcBbA", + 11 + ], + [ + "CaBB", + "aCCBbcaba", + 13 + ], + [ + "CaBB", + "babABcb", + 9 + ], + [ + "CaBBBa", + "Cc", + 10 + ], + [ + "CaBBBbBB", + "CAAaC", + 13 + ], + [ + "CaBBCccC", + "bAac", + 13 + ], + [ + "CaBBaA", + "a", + 10 + ], + [ + "CaBBabBcc", + "b", + 16 + ], + [ + "CaBBcC", + "BA", + 10 + ], + [ + "CaBBccac", + "accCBA", + 11 + ], + [ + "CaBC", + "CaaacC", + 6 + ], + [ + "CaBCACabA", + "CbcABbc", + 10 + ], + [ + "CaBCBbC", + "ccbBbaC", + 8 + ], + [ + "CaBCCcaCc", + "CaC", + 12 + ], + [ + "CaBaaBcA", + "C", + 14 + ], + [ + "CaBacBc", + "c", + 12 + ], + [ + "CaBba", + "bbcCaAa", + 10 + ], + [ + "CaBbac", + "A", + 11 + ], + [ + "CaBcAc", + "CAAab", + 8 + ], + [ + "CaBcBAbB", + "BABCCca", + 12 + ], + [ + "CaBcaA", + "bcC", + 9 + ], + [ + "CaBccaAc", + "bBa", + 12 + ], + [ + "CaC", + "aC", + 2 + ], + [ + "CaCA", + "bcBA", + 6 + ], + [ + "CaCAAbCcB", + "aBCc", + 11 + ], + [ + "CaCABCcbA", + "bB", + 16 + ], + [ + "CaCACCaA", + "BCBBaaBCA", + 13 + ], + [ + "CaCAbBA", + "bCBb", + 10 + ], + [ + "CaCB", + "AB", + 5 + ], + [ + "CaCB", + "bAb", + 6 + ], + [ + "CaCBa", + "ACabCC", + 8 + ], + [ + "CaCBa", + "abBaa", + 6 + ], + [ + "CaCBaaC", + "bcACBa", + 8 + ], + [ + "CaCBbBBb", + "bab", + 12 + ], + [ + "CaCBc", + "cAC", + 6 + ], + [ + "CaCCbB", + "babA", + 8 + ], + [ + "CaCCbc", + "BAbcCcBB", + 11 + ], + [ + "CaCa", + "Aab", + 6 + ], + [ + "CaCa", + "CCccAab", + 9 + ], + [ + "CaCa", + "CcbcAAC", + 10 + ], + [ + "CaCa", + "abCCa", + 6 + ], + [ + "CaCaAB", + "aBb", + 9 + ], + [ + "CaCb", + "bCab", + 4 + ], + [ + "CaCbBcCCC", + "CaBBab", + 11 + ], + [ + "CaCbbCAcb", + "aABcAc", + 10 + ], + [ + "CaCbbaB", + "ABB", + 10 + ], + [ + "CaCc", + "A", + 7 + ], + [ + "CaCc", + "ccBbc", + 7 + ], + [ + "CaCcAAb", + "baCBCB", + 9 + ], + [ + "CaCcB", + "AA", + 9 + ], + [ + "CaCcBa", + "cAc", + 8 + ], + [ + "CaCcaa", + "CABabbB", + 11 + ], + [ + "CaCcbBA", + "CAbccCaa", + 9 + ], + [ + "Caa", + "Acc", + 6 + ], + [ + "Caa", + "BAcBcBCbb", + 16 + ], + [ + "Caa", + "abbAb", + 9 + ], + [ + "CaaABcBab", + "acACccaCa", + 12 + ], + [ + "CaaAaAa", + "bbaabAc", + 9 + ], + [ + "CaaAaAaba", + "aaCBc", + 13 + ], + [ + "CaaAbCcAb", + "bc", + 14 + ], + [ + "CaaBAab", + "CcC", + 12 + ], + [ + "CaaBcB", + "Caaa", + 6 + ], + [ + "CaaC", + "AAbBaC", + 7 + ], + [ + "CaaCA", + "A", + 8 + ], + [ + "CaaCbCB", + "c", + 13 + ], + [ + "Caaa", + "BBaBcA", + 9 + ], + [ + "CaaaCabaC", + "CAa", + 13 + ], + [ + "Caaab", + "a", + 8 + ], + [ + "CaaabAbc", + "ACc", + 12 + ], + [ + "CaaabCbB", + "ABcB", + 11 + ], + [ + "Caaabcc", + "babAaAC", + 10 + ], + [ + "Caaac", + "AAbbccabb", + 15 + ], + [ + "Caab", + "BacAc", + 7 + ], + [ + "CaacAaCb", + "AbccbacB", + 10 + ], + [ + "CaacCb", + "acbcCABBB", + 13 + ], + [ + "Caacaccbc", + "bCcbB", + 13 + ], + [ + "CaacccACC", + "baBCAaCA", + 12 + ], + [ + "Cab", + "AbBCbcBbc", + 14 + ], + [ + "Cab", + "AcC", + 6 + ], + [ + "Cab", + "BCA", + 5 + ], + [ + "Cab", + "BaB", + 3 + ], + [ + "Cab", + "c", + 5 + ], + [ + "CabA", + "b", + 6 + ], + [ + "CabAabA", + "cbCaBBb", + 10 + ], + [ + "CabAbcCB", + "acbCa", + 10 + ], + [ + "CabB", + "AACcCBcab", + 14 + ], + [ + "CabB", + "BabB", + 2 + ], + [ + "CabB", + "Ccba", + 4 + ], + [ + "CabBCa", + "AaCaab", + 10 + ], + [ + "CabBacbC", + "C", + 14 + ], + [ + "CabBbab", + "Bc", + 12 + ], + [ + "CabBbc", + "BbBCbcBca", + 12 + ], + [ + "CabBcC", + "AaAcCAC", + 9 + ], + [ + "CabCB", + "AaCBCab", + 8 + ], + [ + "CabCaAABb", + "BbaB", + 12 + ], + [ + "CabCb", + "BcCbacbb", + 10 + ], + [ + "Caba", + "AA", + 6 + ], + [ + "Caba", + "CBbBBbCC", + 12 + ], + [ + "CabaAAcbc", + "aA", + 14 + ], + [ + "CabaAaab", + "Bccb", + 13 + ], + [ + "CabaBCc", + "acBcBb", + 11 + ], + [ + "CabaCAC", + "bAaa", + 10 + ], + [ + "CababAAcB", + "a", + 16 + ], + [ + "Cabb", + "aBbABaA", + 11 + ], + [ + "CabbAAABB", + "ccA", + 15 + ], + [ + "CabbACc", + "ABCCca", + 10 + ], + [ + "CabbB", + "BabCaAC", + 10 + ], + [ + "CabbB", + "CbBbAccbc", + 12 + ], + [ + "CabbCaa", + "bbaBbcacC", + 10 + ], + [ + "CabbaAba", + "CABaCBAbA", + 9 + ], + [ + "CabbbAACB", + "Babac", + 12 + ], + [ + "CabcB", + "aBAbaA", + 9 + ], + [ + "CabcBaC", + "Cac", + 8 + ], + [ + "CabcaABb", + "cBBc", + 12 + ], + [ + "CabcaBcB", + "bAABcbCA", + 12 + ], + [ + "Cabcb", + "Ba", + 8 + ], + [ + "Cabccb", + "BBBA", + 11 + ], + [ + "Cac", + "A", + 5 + ], + [ + "Cac", + "BAcb", + 5 + ], + [ + "Cac", + "BCcCCac", + 8 + ], + [ + "Cac", + "Bc", + 4 + ], + [ + "Cac", + "CBaacCcCb", + 12 + ], + [ + "Cac", + "cC", + 4 + ], + [ + "Cac", + "cbACbC", + 9 + ], + [ + "CacA", + "BaBabBAA", + 12 + ], + [ + "CacA", + "CacbC", + 4 + ], + [ + "CacAb", + "acCAb", + 4 + ], + [ + "CacAcAa", + "ACbcC", + 10 + ], + [ + "CacAcBc", + "caABbAAAA", + 13 + ], + [ + "CacBBBC", + "B", + 12 + ], + [ + "CacBCa", + "CcbcBA", + 7 + ], + [ + "CacBaCbca", + "aaBaaaBc", + 11 + ], + [ + "CacBbbB", + "CaCbbaBbb", + 7 + ], + [ + "CacBc", + "bBbAC", + 9 + ], + [ + "CacC", + "AcC", + 3 + ], + [ + "CacCbaAcc", + "bCaAaCB", + 13 + ], + [ + "CacaAc", + "aAbC", + 8 + ], + [ + "Cacab", + "AaBCAa", + 8 + ], + [ + "Cacab", + "c", + 8 + ], + [ + "CacacC", + "AABCCAA", + 12 + ], + [ + "Cacb", + "ac", + 4 + ], + [ + "CacbB", + "BCbcBaa", + 9 + ], + [ + "CacbC", + "bBbCaBBB", + 11 + ], + [ + "CacbC", + "cCAAcCa", + 9 + ], + [ + "CacbCAccB", + "AAaBBcbBc", + 14 + ], + [ + "Cacc", + "AACc", + 4 + ], + [ + "CaccAC", + "BabBAaC", + 8 + ], + [ + "CaccBca", + "aCbb", + 10 + ], + [ + "CaccaAbbC", + "BBbC", + 13 + ], + [ + "CaccaCCa", + "cc", + 12 + ], + [ + "Cb", + "A", + 4 + ], + [ + "Cb", + "AACB", + 5 + ], + [ + "Cb", + "AACCbcBc", + 12 + ], + [ + "Cb", + "ABcAcaCcC", + 16 + ], + [ + "Cb", + "ACCBAaCaA", + 15 + ], + [ + "Cb", + "AaBCBCc", + 11 + ], + [ + "Cb", + "Aaa", + 6 + ], + [ + "Cb", + "AacabCcB", + 13 + ], + [ + "Cb", + "Ac", + 4 + ], + [ + "Cb", + "BABB", + 7 + ], + [ + "Cb", + "BBcAabC", + 11 + ], + [ + "Cb", + "Ba", + 4 + ], + [ + "Cb", + "BaaB", + 7 + ], + [ + "Cb", + "BbCaabCCC", + 14 + ], + [ + "Cb", + "CA", + 2 + ], + [ + "Cb", + "CCcBaAB", + 11 + ], + [ + "Cb", + "Cbb", + 2 + ], + [ + "Cb", + "CcBccBacC", + 15 + ], + [ + "Cb", + "aBcaCb", + 8 + ], + [ + "Cb", + "aCBCcAACA", + 15 + ], + [ + "Cb", + "aaAbc", + 8 + ], + [ + "Cb", + "aaCBBaB", + 11 + ], + [ + "Cb", + "aaaB", + 7 + ], + [ + "Cb", + "abBaC", + 8 + ], + [ + "Cb", + "abaaaCABA", + 15 + ], + [ + "Cb", + "acBbAAca", + 13 + ], + [ + "Cb", + "acbbabbCC", + 15 + ], + [ + "Cb", + "bcCCBA", + 9 + ], + [ + "Cb", + "c", + 3 + ], + [ + "Cb", + "cAbcbCA", + 11 + ], + [ + "Cb", + "cAcCbBA", + 10 + ], + [ + "Cb", + "cB", + 2 + ], + [ + "Cb", + "cBcB", + 6 + ], + [ + "Cb", + "caacb", + 7 + ], + [ + "Cb", + "cbCBBbacA", + 14 + ], + [ + "Cb", + "cbcbccA", + 11 + ], + [ + "CbA", + "AAC", + 6 + ], + [ + "CbA", + "BBCBaCC", + 10 + ], + [ + "CbA", + "BBcBB", + 8 + ], + [ + "CbA", + "baaA", + 6 + ], + [ + "CbA", + "c", + 5 + ], + [ + "CbA", + "caBAbA", + 7 + ], + [ + "CbAABaAC", + "A", + 14 + ], + [ + "CbAACACcC", + "ba", + 15 + ], + [ + "CbAACa", + "AaCaAccab", + 11 + ], + [ + "CbAAaAB", + "BCaBCcaaC", + 12 + ], + [ + "CbAAb", + "bacAabaAB", + 11 + ], + [ + "CbAAcAb", + "caC", + 11 + ], + [ + "CbAAcC", + "ABbcaCa", + 10 + ], + [ + "CbABACcaB", + "Babb", + 14 + ], + [ + "CbABC", + "b", + 8 + ], + [ + "CbABaBaAC", + "acaC", + 12 + ], + [ + "CbAC", + "A", + 6 + ], + [ + "CbAC", + "c", + 7 + ], + [ + "CbACaB", + "aBcA", + 9 + ], + [ + "CbACb", + "bcABcCC", + 10 + ], + [ + "CbACc", + "BbabcaBCA", + 13 + ], + [ + "CbACcABba", + "baABAcBc", + 12 + ], + [ + "CbAaAaaa", + "ACbBACbbc", + 13 + ], + [ + "CbAaabbC", + "A", + 14 + ], + [ + "CbAacB", + "c", + 10 + ], + [ + "CbAacBB", + "CacbBBbBA", + 12 + ], + [ + "CbAb", + "baBac", + 8 + ], + [ + "CbAbBaC", + "aCAaACb", + 11 + ], + [ + "CbAba", + "CbaA", + 4 + ], + [ + "CbAbb", + "Bc", + 9 + ], + [ + "CbAc", + "a", + 7 + ], + [ + "CbAcAC", + "bcbCB", + 8 + ], + [ + "CbAcB", + "aac", + 7 + ], + [ + "CbAcBCcaa", + "ccABcacAc", + 11 + ], + [ + "CbAcCb", + "AC", + 8 + ], + [ + "CbAcaAAA", + "accCbbACC", + 15 + ], + [ + "CbAcc", + "AABbcBBc", + 11 + ], + [ + "CbB", + "ABcCCBb", + 10 + ], + [ + "CbB", + "B", + 4 + ], + [ + "CbB", + "BB", + 3 + ], + [ + "CbB", + "BBb", + 4 + ], + [ + "CbB", + "ababacC", + 11 + ], + [ + "CbB", + "bAaaABc", + 12 + ], + [ + "CbB", + "cCb", + 4 + ], + [ + "CbBABACb", + "BCcBAA", + 10 + ], + [ + "CbBABBaA", + "BacaabAc", + 13 + ], + [ + "CbBAb", + "cB", + 7 + ], + [ + "CbBB", + "CcBCBCcAC", + 12 + ], + [ + "CbBBB", + "BCCcb", + 9 + ], + [ + "CbBBaC", + "ab", + 10 + ], + [ + "CbBBcCCBb", + "B", + 16 + ], + [ + "CbBCCbbB", + "cC", + 13 + ], + [ + "CbBa", + "a", + 6 + ], + [ + "CbBa", + "aAb", + 7 + ], + [ + "CbBabA", + "CcCB", + 9 + ], + [ + "CbBb", + "aBccCBA", + 11 + ], + [ + "CbBbC", + "CCCbbC", + 5 + ], + [ + "CbBbbba", + "BaCCABCcC", + 15 + ], + [ + "CbBbc", + "C", + 8 + ], + [ + "CbBc", + "aAaAAbBA", + 12 + ], + [ + "CbBcB", + "b", + 8 + ], + [ + "CbC", + "AcacbAB", + 11 + ], + [ + "CbC", + "BCAc", + 5 + ], + [ + "CbC", + "Bc", + 4 + ], + [ + "CbC", + "CbB", + 2 + ], + [ + "CbC", + "b", + 4 + ], + [ + "CbCAAbb", + "bAAaC", + 8 + ], + [ + "CbCABcaC", + "aCcAACB", + 12 + ], + [ + "CbCACA", + "baAac", + 8 + ], + [ + "CbCAa", + "cCbabBb", + 10 + ], + [ + "CbCB", + "BAcbcAba", + 11 + ], + [ + "CbCBBb", + "cAbACcA", + 11 + ], + [ + "CbCBC", + "cacCccCb", + 11 + ], + [ + "CbCBCAB", + "bBBcC", + 9 + ], + [ + "CbCBcCAaa", + "aAAaAa", + 14 + ], + [ + "CbCCCc", + "BcBCaba", + 10 + ], + [ + "CbCCbAccA", + "cCbBB", + 13 + ], + [ + "CbCCcCCaB", + "bcaaab", + 11 + ], + [ + "CbCa", + "cBBaCacA", + 10 + ], + [ + "CbCaAaB", + "acaa", + 9 + ], + [ + "CbCaB", + "ACbaa", + 6 + ], + [ + "CbCaB", + "AcbAa", + 7 + ], + [ + "CbCaBCb", + "bcA", + 10 + ], + [ + "CbCaa", + "ABCBCcAb", + 10 + ], + [ + "CbCaa", + "ba", + 6 + ], + [ + "CbCaaaC", + "bAcBcBaAa", + 12 + ], + [ + "CbCb", + "Bbc", + 5 + ], + [ + "CbCbaBa", + "AbacBbabc", + 10 + ], + [ + "CbCbcC", + "Ca", + 10 + ], + [ + "CbCc", + "ACC", + 5 + ], + [ + "CbCc", + "Cabbb", + 6 + ], + [ + "CbCcAaBaA", + "cbC", + 13 + ], + [ + "CbCcAcAc", + "AcBaCaAC", + 11 + ], + [ + "CbCcBAb", + "c", + 12 + ], + [ + "CbCcBC", + "CacBbCAc", + 10 + ], + [ + "CbCcBac", + "AAbAC", + 11 + ], + [ + "Cba", + "ABBBbaab", + 12 + ], + [ + "Cba", + "AcbAbB", + 8 + ], + [ + "Cba", + "C", + 4 + ], + [ + "Cba", + "CCCbbbC", + 10 + ], + [ + "Cba", + "CCaaAa", + 8 + ], + [ + "Cba", + "CcBCCAAAA", + 14 + ], + [ + "Cba", + "aABbaC", + 8 + ], + [ + "CbaA", + "CAbCBaB", + 8 + ], + [ + "CbaA", + "CBb", + 5 + ], + [ + "CbaABAC", + "aBCBCBc", + 12 + ], + [ + "CbaAaBCaB", + "AcCcB", + 12 + ], + [ + "CbaAcBb", + "C", + 12 + ], + [ + "CbaAcc", + "acaCaaccA", + 10 + ], + [ + "CbaBA", + "ab", + 7 + ], + [ + "CbaBBcBaB", + "bB", + 14 + ], + [ + "CbaBa", + "CBC", + 6 + ], + [ + "CbaBb", + "CCCbcB", + 8 + ], + [ + "CbaBba", + "BC", + 10 + ], + [ + "CbaBcAcbC", + "cc", + 14 + ], + [ + "CbaC", + "B", + 7 + ], + [ + "CbaCA", + "BAbaAacA", + 9 + ], + [ + "CbaCABBb", + "cAB", + 11 + ], + [ + "CbaCABcbA", + "BbaCbC", + 10 + ], + [ + "CbaCAaCc", + "a", + 14 + ], + [ + "CbaCAcCba", + "BCcaB", + 12 + ], + [ + "CbaCbCA", + "ccBBAcBc", + 12 + ], + [ + "CbaaA", + "BA", + 7 + ], + [ + "CbaaBA", + "AcccAAaac", + 14 + ], + [ + "CbabAACaC", + "cABaCcbB", + 13 + ], + [ + "CbabACa", + "A", + 12 + ], + [ + "CbabAac", + "aaaB", + 9 + ], + [ + "CbabAcC", + "cbb", + 9 + ], + [ + "CbabBBBcc", + "c", + 16 + ], + [ + "CbabBCCab", + "bB", + 14 + ], + [ + "CbabC", + "CacBB", + 7 + ], + [ + "CbabbBbb", + "BaAABCC", + 11 + ], + [ + "Cbabc", + "aACbC", + 7 + ], + [ + "CbabcB", + "CBcbAcb", + 6 + ], + [ + "CbacAab", + "c", + 12 + ], + [ + "CbacCAB", + "cCC", + 10 + ], + [ + "CbacCCb", + "caaC", + 9 + ], + [ + "CbacCaCAB", + "Cbbba", + 12 + ], + [ + "Cbacaca", + "BACAc", + 8 + ], + [ + "Cbb", + "Ababcb", + 8 + ], + [ + "Cbb", + "Bb", + 3 + ], + [ + "Cbb", + "CACbbBCb", + 10 + ], + [ + "Cbb", + "CBaABccaA", + 14 + ], + [ + "Cbb", + "abcb", + 4 + ], + [ + "Cbb", + "bACBBCCaa", + 14 + ], + [ + "Cbb", + "caCCACBaB", + 14 + ], + [ + "Cbb", + "cbAcABac", + 12 + ], + [ + "CbbA", + "cAACAA", + 9 + ], + [ + "CbbAACbC", + "ccaABC", + 9 + ], + [ + "CbbABCCA", + "CBCABCA", + 5 + ], + [ + "CbbAb", + "B", + 9 + ], + [ + "CbbAbbac", + "bCBbca", + 10 + ], + [ + "CbbAcaCbC", + "CAbBbcAc", + 11 + ], + [ + "CbbB", + "A", + 8 + ], + [ + "CbbB", + "C", + 6 + ], + [ + "CbbBA", + "BBCabAB", + 10 + ], + [ + "CbbBAbcA", + "CcCCAaBb", + 12 + ], + [ + "CbbBAcCba", + "BBbbCaBA", + 11 + ], + [ + "CbbBaBcB", + "cCabACB", + 10 + ], + [ + "CbbCCacBc", + "cbbAcacab", + 8 + ], + [ + "CbbaAacC", + "bcbcbbaBa", + 13 + ], + [ + "CbbaCBAb", + "aBCBBcC", + 13 + ], + [ + "CbbbBb", + "BA", + 10 + ], + [ + "CbbbaA", + "aacCccBbB", + 15 + ], + [ + "CbbbaACba", + "aCBba", + 12 + ], + [ + "Cbbbab", + "AABAbbc", + 11 + ], + [ + "Cbbc", + "bcaAb", + 9 + ], + [ + "Cbbc", + "cba", + 5 + ], + [ + "CbbcBcAc", + "BbC", + 12 + ], + [ + "CbbcCBacB", + "AaC", + 15 + ], + [ + "Cbbcbb", + "bBaBCBA", + 10 + ], + [ + "CbbcbcabC", + "AcBcBcba", + 10 + ], + [ + "Cbbcc", + "B", + 9 + ], + [ + "Cbbcc", + "CcbA", + 6 + ], + [ + "CbbccBAaB", + "cCA", + 13 + ], + [ + "Cbbccc", + "BcA", + 9 + ], + [ + "Cbc", + "A", + 6 + ], + [ + "Cbc", + "BAa", + 6 + ], + [ + "Cbc", + "BaabcacC", + 12 + ], + [ + "Cbc", + "CBbAc", + 4 + ], + [ + "Cbc", + "aCCbab", + 8 + ], + [ + "Cbc", + "baB", + 6 + ], + [ + "Cbc", + "bcB", + 4 + ], + [ + "Cbc", + "caACbaC", + 9 + ], + [ + "Cbc", + "cbabc", + 5 + ], + [ + "CbcAB", + "AabCABAb", + 9 + ], + [ + "CbcAaaBa", + "aACA", + 12 + ], + [ + "CbcB", + "CBcC", + 3 + ], + [ + "CbcBCbB", + "CAAacC", + 11 + ], + [ + "CbcBb", + "aaCACAAcC", + 15 + ], + [ + "CbcBcb", + "AabcC", + 9 + ], + [ + "CbcBcbC", + "aCa", + 13 + ], + [ + "CbcCAAc", + "aaBBbbc", + 12 + ], + [ + "CbcCAB", + "bbaCCcc", + 9 + ], + [ + "CbcCB", + "c", + 8 + ], + [ + "CbcCBB", + "aB", + 10 + ], + [ + "CbcCCa", + "BB", + 11 + ], + [ + "CbcCcA", + "aCaacCaAa", + 10 + ], + [ + "Cbca", + "cABAAaaA", + 12 + ], + [ + "CbcaC", + "bCcabCa", + 8 + ], + [ + "Cbcb", + "AA", + 8 + ], + [ + "Cbcb", + "AaCc", + 7 + ], + [ + "Cbcb", + "CbBAa", + 6 + ], + [ + "CbcbA", + "bccbACcC", + 10 + ], + [ + "CbcbB", + "aC", + 9 + ], + [ + "CbcbBCBC", + "cBB", + 10 + ], + [ + "CbcbC", + "a", + 10 + ], + [ + "Cbcbb", + "cccAB", + 6 + ], + [ + "Cbcbcbc", + "CbaccAcCC", + 9 + ], + [ + "Cbcc", + "BbAcAabc", + 10 + ], + [ + "Cbcc", + "bbBBA", + 8 + ], + [ + "CbccCAcBA", + "acCA", + 12 + ], + [ + "CbccaACc", + "AC", + 12 + ], + [ + "Cc", + "AAbABC", + 11 + ], + [ + "Cc", + "AAcbCAca", + 12 + ], + [ + "Cc", + "ABaC", + 7 + ], + [ + "Cc", + "AC", + 3 + ], + [ + "Cc", + "ACCcCa", + 8 + ], + [ + "Cc", + "AaCCC", + 7 + ], + [ + "Cc", + "BBCBCbbb", + 13 + ], + [ + "Cc", + "BbAbcC", + 10 + ], + [ + "Cc", + "Bc", + 2 + ], + [ + "Cc", + "Bccba", + 7 + ], + [ + "Cc", + "CABACbAcB", + 14 + ], + [ + "Cc", + "CAaCbCA", + 11 + ], + [ + "Cc", + "CCCCAaC", + 11 + ], + [ + "Cc", + "CCbCaAb", + 11 + ], + [ + "Cc", + "Ccb", + 2 + ], + [ + "Cc", + "a", + 4 + ], + [ + "Cc", + "aAABCBacb", + 14 + ], + [ + "Cc", + "aAAccbC", + 11 + ], + [ + "Cc", + "aBBCbc", + 8 + ], + [ + "Cc", + "aCAcaCca", + 12 + ], + [ + "Cc", + "bB", + 4 + ], + [ + "Cc", + "baABAABbC", + 17 + ], + [ + "Cc", + "bbacA", + 8 + ], + [ + "Cc", + "bc", + 2 + ], + [ + "Cc", + "c", + 2 + ], + [ + "Cc", + "cAaAAbc", + 11 + ], + [ + "Cc", + "cBbbBbcA", + 13 + ], + [ + "Cc", + "ca", + 3 + ], + [ + "Cc", + "ccAC", + 5 + ], + [ + "Cc", + "ccCb", + 5 + ], + [ + "CcA", + "BbcbaAB", + 10 + ], + [ + "CcA", + "aCA", + 3 + ], + [ + "CcA", + "bAAbca", + 9 + ], + [ + "CcA", + "bBccA", + 5 + ], + [ + "CcA", + "bCCBb", + 7 + ], + [ + "CcA", + "cBAbaC", + 9 + ], + [ + "CcAA", + "bcACbc", + 8 + ], + [ + "CcAAAAC", + "abCa", + 12 + ], + [ + "CcAAAB", + "bBAbaC", + 9 + ], + [ + "CcAAAcCb", + "cAcBcBBC", + 11 + ], + [ + "CcAABaC", + "BbC", + 10 + ], + [ + "CcAABbc", + "BCaAbab", + 9 + ], + [ + "CcAACB", + "b", + 11 + ], + [ + "CcAAaC", + "CAbaab", + 7 + ], + [ + "CcAB", + "BbcCBc", + 8 + ], + [ + "CcAB", + "accAaa", + 7 + ], + [ + "CcABACACb", + "abBBbCAA", + 12 + ], + [ + "CcABBccA", + "cc", + 12 + ], + [ + "CcABb", + "a", + 9 + ], + [ + "CcABbabBA", + "cCA", + 14 + ], + [ + "CcABcAaa", + "Ba", + 12 + ], + [ + "CcACAbc", + "AbBB", + 11 + ], + [ + "CcACbaCA", + "abbBaBbBa", + 16 + ], + [ + "CcACcCAa", + "AaB", + 13 + ], + [ + "CcAa", + "aAbBCCc", + 13 + ], + [ + "CcAa", + "ccBC", + 5 + ], + [ + "CcAaA", + "cbcC", + 8 + ], + [ + "CcAaB", + "babCBbCAC", + 15 + ], + [ + "CcAaCABA", + "cbaBaCCCb", + 12 + ], + [ + "CcAaCcbcB", + "aBbaCAAC", + 13 + ], + [ + "CcAac", + "Cabaac", + 5 + ], + [ + "CcAacBAaC", + "bCACB", + 12 + ], + [ + "CcAb", + "b", + 6 + ], + [ + "CcAbBcBaa", + "CBc", + 12 + ], + [ + "CcAbaaA", + "cCa", + 10 + ], + [ + "CcAbcaB", + "bcA", + 9 + ], + [ + "CcAc", + "AAaaABABA", + 16 + ], + [ + "CcAcAB", + "aabAabCcb", + 14 + ], + [ + "CcAcCcC", + "cACbbac", + 10 + ], + [ + "CcAcCcc", + "A", + 12 + ], + [ + "CcB", + "AbcBBCAac", + 14 + ], + [ + "CcB", + "Ac", + 4 + ], + [ + "CcB", + "Ccb", + 1 + ], + [ + "CcB", + "ba", + 6 + ], + [ + "CcB", + "cab", + 4 + ], + [ + "CcB", + "cbc", + 5 + ], + [ + "CcBABc", + "cAAC", + 7 + ], + [ + "CcBACb", + "ac", + 10 + ], + [ + "CcBAaAa", + "aCCcB", + 12 + ], + [ + "CcBB", + "bab", + 7 + ], + [ + "CcBBA", + "B", + 8 + ], + [ + "CcBBAb", + "aBCAAc", + 10 + ], + [ + "CcBBCAAC", + "A", + 14 + ], + [ + "CcBBbac", + "Bb", + 10 + ], + [ + "CcBCBaa", + "bbbbB", + 11 + ], + [ + "CcBCCaAbC", + "aAaCaCA", + 14 + ], + [ + "CcBCCbABb", + "BbBCbccaC", + 14 + ], + [ + "CcBCaacCB", + "CAbCcbA", + 11 + ], + [ + "CcBCc", + "C", + 8 + ], + [ + "CcBCc", + "cBcba", + 7 + ], + [ + "CcBCccbb", + "abaAAAa", + 15 + ], + [ + "CcBaBb", + "BAabCcBcB", + 12 + ], + [ + "CcBaa", + "abBac", + 6 + ], + [ + "CcBabaabc", + "bCB", + 15 + ], + [ + "CcBacBC", + "aa", + 12 + ], + [ + "CcBb", + "AAB", + 6 + ], + [ + "CcBb", + "BaAcbA", + 9 + ], + [ + "CcBbC", + "A", + 10 + ], + [ + "CcBbaCbb", + "abcBCCBab", + 11 + ], + [ + "CcBbbaB", + "baCb", + 11 + ], + [ + "CcBc", + "aBabCbbcB", + 13 + ], + [ + "CcBc", + "cabcACa", + 10 + ], + [ + "CcBcABAC", + "AAC", + 10 + ], + [ + "CcBcBCBaa", + "CBA", + 13 + ], + [ + "CcC", + "CBAacacBa", + 13 + ], + [ + "CcC", + "CBbcac", + 7 + ], + [ + "CcCAA", + "cB", + 8 + ], + [ + "CcCABC", + "ACA", + 8 + ], + [ + "CcCACCb", + "CbAbCccC", + 11 + ], + [ + "CcCAaCAaB", + "ABbAAaBb", + 12 + ], + [ + "CcCAbB", + "abb", + 8 + ], + [ + "CcCAbCBc", + "cbaCBaB", + 11 + ], + [ + "CcCB", + "ABbCBAc", + 10 + ], + [ + "CcCB", + "bcaabaccc", + 14 + ], + [ + "CcCB", + "cbBaC", + 8 + ], + [ + "CcCBA", + "CbAbcb", + 9 + ], + [ + "CcCBCcCA", + "BbCcaa", + 10 + ], + [ + "CcCBb", + "aBBC", + 8 + ], + [ + "CcCBc", + "BCBb", + 6 + ], + [ + "CcCC", + "b", + 8 + ], + [ + "CcCCAB", + "CCbB", + 6 + ], + [ + "CcCCBACCa", + "ABAABAAAb", + 14 + ], + [ + "CcCCacbB", + "aACA", + 13 + ], + [ + "CcCaA", + "baa", + 7 + ], + [ + "CcCaaaaA", + "bCbbACC", + 13 + ], + [ + "CcCacAB", + "BCCBacCcb", + 10 + ], + [ + "CcCacbC", + "ACBabB", + 9 + ], + [ + "CcCbB", + "BABCbb", + 7 + ], + [ + "CcCbCA", + "aBcA", + 8 + ], + [ + "CcCbCbBbc", + "ccabB", + 11 + ], + [ + "CcCba", + "BCb", + 6 + ], + [ + "CcCbaAbB", + "aBbcaCB", + 11 + ], + [ + "CcCbcaC", + "CcBbaCbCb", + 9 + ], + [ + "CcCc", + "cBAACa", + 9 + ], + [ + "CcCcAB", + "aCBbA", + 9 + ], + [ + "CcCcAc", + "baBacaB", + 11 + ], + [ + "CcCcBB", + "bcbBbcAbB", + 11 + ], + [ + "CcCcCCAb", + "BCBBaABab", + 13 + ], + [ + "CcCca", + "bCaBAB", + 10 + ], + [ + "CcCcaB", + "aAacCCb", + 10 + ], + [ + "CcCcbCb", + "BBBCBaCC", + 12 + ], + [ + "CcCcbCb", + "cC", + 10 + ], + [ + "CcCccCbbc", + "cabBaCB", + 14 + ], + [ + "Cca", + "AbbaBABCA", + 16 + ], + [ + "Cca", + "AcacBcc", + 10 + ], + [ + "Cca", + "a", + 4 + ], + [ + "Cca", + "b", + 6 + ], + [ + "Cca", + "bAbaCBB", + 12 + ], + [ + "CcaAB", + "B", + 8 + ], + [ + "CcaABA", + "a", + 10 + ], + [ + "CcaAC", + "BaCbAbaAa", + 12 + ], + [ + "CcaACB", + "BcBbAAA", + 10 + ], + [ + "CcaACCA", + "bCacCB", + 8 + ], + [ + "CcaAa", + "cCC", + 8 + ], + [ + "CcaAbCCC", + "AbCBCb", + 10 + ], + [ + "CcaAcb", + "bcBAa", + 8 + ], + [ + "CcaAcc", + "babAAAcbB", + 13 + ], + [ + "CcaB", + "BbaCbBbCB", + 14 + ], + [ + "CcaBA", + "ACCCABCBC", + 12 + ], + [ + "CcaBaBC", + "bacAbAab", + 11 + ], + [ + "CcaBaa", + "A", + 11 + ], + [ + "CcaBcBAB", + "Ac", + 13 + ], + [ + "CcaBcC", + "A", + 11 + ], + [ + "CcaCAaabB", + "CABCacccB", + 11 + ], + [ + "CcaCCAAA", + "BCAaCCcc", + 10 + ], + [ + "CcaCa", + "BAa", + 7 + ], + [ + "CcaCabAcb", + "BaaaBAC", + 10 + ], + [ + "CcaCacbba", + "bccAB", + 13 + ], + [ + "CcaCbbA", + "CcB", + 9 + ], + [ + "CcaCcBc", + "cbaCa", + 9 + ], + [ + "Ccaa", + "AabAcaC", + 10 + ], + [ + "CcaaA", + "aaCAA", + 7 + ], + [ + "CcaaAAbc", + "aABCaCacc", + 13 + ], + [ + "CcaaBC", + "abBCaC", + 10 + ], + [ + "Ccaaa", + "cc", + 7 + ], + [ + "CcaaaAB", + "bc", + 12 + ], + [ + "Ccaaaa", + "ABbbbb", + 12 + ], + [ + "Ccaaabccc", + "cA", + 15 + ], + [ + "CcaabbCCA", + "Bbc", + 14 + ], + [ + "Ccab", + "AC", + 7 + ], + [ + "Ccab", + "Cba", + 4 + ], + [ + "Ccab", + "abBAaBB", + 11 + ], + [ + "Ccab", + "abbBCaBb", + 11 + ], + [ + "CcabACcb", + "cCAaC", + 10 + ], + [ + "Ccac", + "cbCCA", + 8 + ], + [ + "CcacB", + "cCBbaCB", + 7 + ], + [ + "CcacBabBC", + "CaBBaB", + 8 + ], + [ + "CcacC", + "AbbacBa", + 10 + ], + [ + "CcacCABB", + "ba", + 14 + ], + [ + "CcacCaA", + "CaAC", + 8 + ], + [ + "CcacaBB", + "B", + 12 + ], + [ + "CcacbC", + "cCb", + 7 + ], + [ + "Ccb", + "AcbABaCC", + 12 + ], + [ + "Ccb", + "CAA", + 4 + ], + [ + "Ccb", + "CbAcC", + 6 + ], + [ + "Ccb", + "c", + 4 + ], + [ + "CcbA", + "BccAc", + 6 + ], + [ + "CcbA", + "aabCBb", + 10 + ], + [ + "CcbA", + "bABb", + 7 + ], + [ + "CcbAACA", + "bcc", + 11 + ], + [ + "CcbAACB", + "acBBAcac", + 10 + ], + [ + "CcbAAaA", + "ccBCaCa", + 8 + ], + [ + "CcbACBA", + "A", + 12 + ], + [ + "CcbACC", + "bbaC", + 7 + ], + [ + "CcbAaBcAA", + "bAcac", + 11 + ], + [ + "CcbAc", + "AcbbBBBa", + 12 + ], + [ + "CcbBAbCcC", + "AAb", + 14 + ], + [ + "CcbBaCC", + "ABcA", + 11 + ], + [ + "CcbBac", + "BCAAA", + 10 + ], + [ + "CcbBbBBA", + "AbB", + 12 + ], + [ + "CcbBbbbbb", + "bb", + 14 + ], + [ + "CcbBc", + "cBAcacB", + 11 + ], + [ + "CcbBcAC", + "BbCcAbcbB", + 11 + ], + [ + "CcbBcaA", + "bbcca", + 8 + ], + [ + "CcbBcc", + "bbcc", + 5 + ], + [ + "CcbCA", + "a", + 9 + ], + [ + "CcbCA", + "aabAA", + 6 + ], + [ + "CcbCbB", + "CACab", + 7 + ], + [ + "CcbCbCA", + "BcaCaCAb", + 8 + ], + [ + "CcbCc", + "AC", + 8 + ], + [ + "CcbCc", + "cBbbc", + 5 + ], + [ + "CcbCcC", + "c", + 10 + ], + [ + "CcbaccBCb", + "bbCBA", + 13 + ], + [ + "CcbbABb", + "CbCbacB", + 8 + ], + [ + "CcbbaAbbB", + "bc", + 16 + ], + [ + "Ccbbb", + "CBAcACB", + 9 + ], + [ + "CcbbbC", + "cBacabCb", + 11 + ], + [ + "CcbbbCbc", + "BbCAaBaB", + 15 + ], + [ + "CcbbcABBa", + "BcAcCcBCB", + 13 + ], + [ + "Ccbc", + "ABAaaBAb", + 15 + ], + [ + "Ccc", + "B", + 6 + ], + [ + "Ccc", + "BABa", + 8 + ], + [ + "Ccc", + "BcaBAc", + 8 + ], + [ + "Ccc", + "CBB", + 4 + ], + [ + "Ccc", + "CC", + 3 + ], + [ + "Ccc", + "aaaaCC", + 10 + ], + [ + "Ccc", + "ac", + 4 + ], + [ + "Ccc", + "bb", + 6 + ], + [ + "CccABA", + "AAbBcA", + 10 + ], + [ + "CccACCB", + "AcbaC", + 9 + ], + [ + "CccAaB", + "baCaBcCa", + 12 + ], + [ + "CccAb", + "aABBc", + 10 + ], + [ + "CccAcbbca", + "c", + 16 + ], + [ + "CccBBBcB", + "bBbbCa", + 11 + ], + [ + "CccBBbC", + "Bba", + 10 + ], + [ + "CccBa", + "B", + 8 + ], + [ + "CccBa", + "caBA", + 5 + ], + [ + "CccBaaAB", + "C", + 14 + ], + [ + "CccBbBCb", + "a", + 16 + ], + [ + "CccBbca", + "BacAbCBbC", + 12 + ], + [ + "CccCAa", + "CcBcBCCc", + 8 + ], + [ + "CccCCa", + "Ba", + 10 + ], + [ + "CccCa", + "aA", + 9 + ], + [ + "CccCb", + "baA", + 10 + ], + [ + "Ccca", + "A", + 7 + ], + [ + "CccaABbBb", + "aAcB", + 12 + ], + [ + "CccaBBCb", + "BBbaaCCC", + 12 + ], + [ + "Cccaa", + "BbbC", + 10 + ], + [ + "CccacCBb", + "ccBa", + 10 + ], + [ + "CccbABBbb", + "B", + 16 + ], + [ + "Cccbbc", + "CCcBcBa", + 7 + ], + [ + "Cccc", + "BaCbb", + 9 + ], + [ + "CcccAB", + "aCBAB", + 7 + ], + [ + "CcccAbbA", + "BCBcBc", + 12 + ], + [ + "CcccBacc", + "BCAcB", + 11 + ], + [ + "CcccBcCB", + "cCAb", + 12 + ], + [ + "a", + "AA", + 3 + ], + [ + "a", + "AABaCbca", + 14 + ], + [ + "a", + "AACaBBAC", + 14 + ], + [ + "a", + "ABCaa", + 8 + ], + [ + "a", + "ABaaBCCb", + 14 + ], + [ + "a", + "ABab", + 6 + ], + [ + "a", + "ABcB", + 7 + ], + [ + "a", + "ACbcCBCB", + 15 + ], + [ + "a", + "ACbcaA", + 10 + ], + [ + "a", + "AaAA", + 6 + ], + [ + "a", + "AaABacaAA", + 16 + ], + [ + "a", + "AaAbBca", + 12 + ], + [ + "a", + "AabBCaab", + 14 + ], + [ + "a", + "AabCbCb", + 12 + ], + [ + "a", + "AaccB", + 8 + ], + [ + "a", + "Ab", + 3 + ], + [ + "a", + "AbBBaB", + 10 + ], + [ + "a", + "AbCb", + 7 + ], + [ + "a", + "AbCc", + 7 + ], + [ + "a", + "AbbbBacAa", + 16 + ], + [ + "a", + "AbcCaCbac", + 16 + ], + [ + "a", + "AcABaA", + 10 + ], + [ + "a", + "AcACCA", + 11 + ], + [ + "a", + "AcCbc", + 9 + ], + [ + "a", + "AcaB", + 6 + ], + [ + "a", + "B", + 2 + ], + [ + "a", + "BA", + 3 + ], + [ + "a", + "BABAAcBBc", + 17 + ], + [ + "a", + "BABaBa", + 10 + ], + [ + "a", + "BAC", + 5 + ], + [ + "a", + "BAaAbAc", + 12 + ], + [ + "a", + "BAabccCBc", + 16 + ], + [ + "a", + "BAbaaa", + 10 + ], + [ + "a", + "BAbb", + 7 + ], + [ + "a", + "BBAcbBB", + 13 + ], + [ + "a", + "BBBaCab", + 12 + ], + [ + "a", + "BBC", + 6 + ], + [ + "a", + "BBaCbBAC", + 14 + ], + [ + "a", + "BBcca", + 8 + ], + [ + "a", + "BCA", + 5 + ], + [ + "a", + "BCBab", + 8 + ], + [ + "a", + "BaAAAcAbc", + 16 + ], + [ + "a", + "BaAcABBC", + 14 + ], + [ + "a", + "BaBcaC", + 10 + ], + [ + "a", + "BaC", + 4 + ], + [ + "a", + "BaabBAabb", + 16 + ], + [ + "a", + "BbCaCa", + 10 + ], + [ + "a", + "BbcACCA", + 13 + ], + [ + "a", + "Bbcba", + 8 + ], + [ + "a", + "BcAb", + 7 + ], + [ + "a", + "BcBABC", + 11 + ], + [ + "a", + "BcBaAacC", + 14 + ], + [ + "a", + "Bca", + 4 + ], + [ + "a", + "Bcabba", + 10 + ], + [ + "a", + "BccCbbAb", + 15 + ], + [ + "a", + "C", + 2 + ], + [ + "a", + "CA", + 3 + ], + [ + "a", + "CABAcBbc", + 15 + ], + [ + "a", + "CABCB", + 9 + ], + [ + "a", + "CAbC", + 7 + ], + [ + "a", + "CAba", + 6 + ], + [ + "a", + "CAcCAa", + 10 + ], + [ + "a", + "CAcc", + 7 + ], + [ + "a", + "CBA", + 5 + ], + [ + "a", + "CBABB", + 9 + ], + [ + "a", + "CBAa", + 6 + ], + [ + "a", + "CBBCcB", + 12 + ], + [ + "a", + "CBBcA", + 9 + ], + [ + "a", + "CBaCAC", + 10 + ], + [ + "a", + "CBbaCCbC", + 14 + ], + [ + "a", + "CCBc", + 8 + ], + [ + "a", + "CCcaC", + 8 + ], + [ + "a", + "Ca", + 2 + ], + [ + "a", + "CaAaC", + 8 + ], + [ + "a", + "CaBacbb", + 12 + ], + [ + "a", + "CaabacC", + 12 + ], + [ + "a", + "CbBc", + 8 + ], + [ + "a", + "CbbcAB", + 11 + ], + [ + "a", + "CcBBaaCc", + 14 + ], + [ + "a", + "CcBbabBAc", + 16 + ], + [ + "a", + "CcaACcB", + 12 + ], + [ + "a", + "Ccca", + 6 + ], + [ + "a", + "a", + 0 + ], + [ + "a", + "aA", + 2 + ], + [ + "a", + "aAACAbCC", + 14 + ], + [ + "a", + "aACABcAb", + 14 + ], + [ + "a", + "aAbaB", + 8 + ], + [ + "a", + "aBB", + 4 + ], + [ + "a", + "aBBCb", + 8 + ], + [ + "a", + "aBaCbb", + 10 + ], + [ + "a", + "aBb", + 4 + ], + [ + "a", + "aC", + 2 + ], + [ + "a", + "aCCCCcab", + 14 + ], + [ + "a", + "aCaBBABa", + 14 + ], + [ + "a", + "aCaC", + 6 + ], + [ + "a", + "aCb", + 4 + ], + [ + "a", + "aCcBaAa", + 12 + ], + [ + "a", + "aa", + 2 + ], + [ + "a", + "aaBbC", + 8 + ], + [ + "a", + "aaCA", + 6 + ], + [ + "a", + "ab", + 2 + ], + [ + "a", + "abACBBAcC", + 16 + ], + [ + "a", + "abBbBba", + 12 + ], + [ + "a", + "abCaAaCbC", + 16 + ], + [ + "a", + "aba", + 4 + ], + [ + "a", + "abcac", + 8 + ], + [ + "a", + "acAcBAbaB", + 16 + ], + [ + "a", + "acBcAA", + 10 + ], + [ + "a", + "accCCCc", + 12 + ], + [ + "a", + "b", + 2 + ], + [ + "a", + "bA", + 3 + ], + [ + "a", + "bAAaB", + 8 + ], + [ + "a", + "bABBa", + 8 + ], + [ + "a", + "bACca", + 8 + ], + [ + "a", + "bAbAccb", + 13 + ], + [ + "a", + "bAccbcaAB", + 16 + ], + [ + "a", + "bBAca", + 8 + ], + [ + "a", + "bBBC", + 8 + ], + [ + "a", + "bBBCaccC", + 14 + ], + [ + "a", + "bBCb", + 8 + ], + [ + "a", + "bBbC", + 8 + ], + [ + "a", + "bBbCABa", + 12 + ], + [ + "a", + "bC", + 4 + ], + [ + "a", + "bCBacAcC", + 14 + ], + [ + "a", + "bCC", + 6 + ], + [ + "a", + "bCCbaccA", + 14 + ], + [ + "a", + "bCbA", + 7 + ], + [ + "a", + "bCbBab", + 10 + ], + [ + "a", + "bCcaCbc", + 12 + ], + [ + "a", + "bCcaaCbB", + 14 + ], + [ + "a", + "ba", + 2 + ], + [ + "a", + "baa", + 4 + ], + [ + "a", + "baacacaba", + 16 + ], + [ + "a", + "babcA", + 8 + ], + [ + "a", + "babcCAA", + 12 + ], + [ + "a", + "bb", + 4 + ], + [ + "a", + "bbAc", + 7 + ], + [ + "a", + "bbB", + 6 + ], + [ + "a", + "bbBA", + 7 + ], + [ + "a", + "bbBBcaBc", + 14 + ], + [ + "a", + "bbBbAaAAc", + 16 + ], + [ + "a", + "bbCCaACb", + 14 + ], + [ + "a", + "bbCaca", + 10 + ], + [ + "a", + "bbaC", + 6 + ], + [ + "a", + "bbbAcAB", + 13 + ], + [ + "a", + "bbbBAABC", + 15 + ], + [ + "a", + "bbcCBcB", + 14 + ], + [ + "a", + "bcAca", + 8 + ], + [ + "a", + "bcAcacCB", + 14 + ], + [ + "a", + "bcaAcBAbC", + 16 + ], + [ + "a", + "bcb", + 6 + ], + [ + "a", + "bcc", + 6 + ], + [ + "a", + "c", + 2 + ], + [ + "a", + "cAC", + 5 + ], + [ + "a", + "cACBACca", + 14 + ], + [ + "a", + "cACaCa", + 10 + ], + [ + "a", + "cAa", + 4 + ], + [ + "a", + "cBAaa", + 8 + ], + [ + "a", + "cBbBbab", + 12 + ], + [ + "a", + "cC", + 4 + ], + [ + "a", + "cCBA", + 7 + ], + [ + "a", + "cCCa", + 6 + ], + [ + "a", + "cCCbaa", + 10 + ], + [ + "a", + "cCaCcb", + 10 + ], + [ + "a", + "cCacac", + 10 + ], + [ + "a", + "cCcBbCBAa", + 16 + ], + [ + "a", + "cabbcaBBc", + 16 + ], + [ + "a", + "cb", + 4 + ], + [ + "a", + "cbAcAab", + 12 + ], + [ + "a", + "cbAcCB", + 11 + ], + [ + "a", + "cbBaC", + 8 + ], + [ + "a", + "cbCcbC", + 12 + ], + [ + "a", + "cbaCbbBb", + 14 + ], + [ + "a", + "cbbAaCA", + 12 + ], + [ + "a", + "ccACCaBAa", + 16 + ], + [ + "a", + "ccACbaC", + 12 + ], + [ + "a", + "ccAbAC", + 11 + ], + [ + "a", + "ccAbbaBA", + 14 + ], + [ + "a", + "ccCBaCcB", + 14 + ], + [ + "a", + "ccac", + 6 + ], + [ + "aA", + "AAc", + 3 + ], + [ + "aA", + "ABcACbCcb", + 15 + ], + [ + "aA", + "ACcbCBA", + 11 + ], + [ + "aA", + "AacACCa", + 10 + ], + [ + "aA", + "B", + 4 + ], + [ + "aA", + "BabBBcCbC", + 16 + ], + [ + "aA", + "Babb", + 6 + ], + [ + "aA", + "BcAcB", + 8 + ], + [ + "aA", + "CAacB", + 8 + ], + [ + "aA", + "CBABBaAB", + 12 + ], + [ + "aA", + "CaBbbbA", + 10 + ], + [ + "aA", + "CcAabB", + 10 + ], + [ + "aA", + "CcaAb", + 6 + ], + [ + "aA", + "a", + 2 + ], + [ + "aA", + "aCAcAb", + 8 + ], + [ + "aA", + "aCBb", + 6 + ], + [ + "aA", + "aCacaAA", + 10 + ], + [ + "aA", + "aaACBacA", + 12 + ], + [ + "aA", + "aaC", + 3 + ], + [ + "aA", + "abbAaBC", + 10 + ], + [ + "aA", + "abbBBbc", + 12 + ], + [ + "aA", + "bAc", + 4 + ], + [ + "aA", + "bB", + 4 + ], + [ + "aA", + "bBCBC", + 10 + ], + [ + "aA", + "baCBAbCa", + 12 + ], + [ + "aA", + "cABBaA", + 8 + ], + [ + "aA", + "cBc", + 6 + ], + [ + "aA", + "cabbabbA", + 12 + ], + [ + "aA", + "ccbcB", + 10 + ], + [ + "aAA", + "aACbBCCb", + 12 + ], + [ + "aAA", + "ac", + 4 + ], + [ + "aAA", + "bAc", + 4 + ], + [ + "aAAA", + "AaAC", + 4 + ], + [ + "aAAAA", + "c", + 10 + ], + [ + "aAAAAC", + "CbaaCCBBa", + 14 + ], + [ + "aAAAAaAA", + "cbAabBb", + 13 + ], + [ + "aAAABb", + "BABBaB", + 9 + ], + [ + "aAAAC", + "bC", + 8 + ], + [ + "aAAAaAb", + "AAC", + 10 + ], + [ + "aAAAabBca", + "AB", + 14 + ], + [ + "aAAAcCbCB", + "CcBbABBB", + 15 + ], + [ + "aAAB", + "A", + 6 + ], + [ + "aAAB", + "bcabAb", + 7 + ], + [ + "aAAB", + "c", + 8 + ], + [ + "aAAB", + "cCAB", + 4 + ], + [ + "aAABCcCcC", + "CbBBCAB", + 14 + ], + [ + "aAABbBACb", + "aACb", + 10 + ], + [ + "aAACC", + "ccbbaBA", + 13 + ], + [ + "aAACaCa", + "ACbabAc", + 11 + ], + [ + "aAAaAAaa", + "ACBcbbcaA", + 14 + ], + [ + "aAAaaaB", + "BABbaaAbA", + 10 + ], + [ + "aAAabaAbA", + "bcCBbaBB", + 13 + ], + [ + "aAAacaaC", + "a", + 14 + ], + [ + "aAAb", + "aCAA", + 4 + ], + [ + "aAAbBbaA", + "BaaaAbb", + 11 + ], + [ + "aAAbCbCcC", + "cBC", + 14 + ], + [ + "aAAbbA", + "bcbbaBa", + 10 + ], + [ + "aAAc", + "AccBbB", + 10 + ], + [ + "aAAcA", + "BBBABa", + 9 + ], + [ + "aAAcA", + "bb", + 10 + ], + [ + "aAAcAA", + "aCAA", + 5 + ], + [ + "aAAcAa", + "CbCAa", + 7 + ], + [ + "aAAcAaa", + "bAAACb", + 8 + ], + [ + "aAAcB", + "AbcACA", + 8 + ], + [ + "aAAcBBba", + "BcaAcACb", + 11 + ], + [ + "aAAcCCbCB", + "C", + 16 + ], + [ + "aAAcCaCc", + "caACAaAa", + 10 + ], + [ + "aAAcCb", + "bbAbA", + 10 + ], + [ + "aAAcabaab", + "cAACAbb", + 8 + ], + [ + "aAAcbACab", + "bCcAaBbCC", + 15 + ], + [ + "aAAcc", + "aaAC", + 4 + ], + [ + "aAB", + "AAaAcCaa", + 12 + ], + [ + "aAB", + "AbCBB", + 7 + ], + [ + "aAB", + "AcaAB", + 4 + ], + [ + "aAB", + "CAbaA", + 7 + ], + [ + "aAB", + "CCBAcbaCC", + 15 + ], + [ + "aAB", + "aBcbbB", + 8 + ], + [ + "aAB", + "aCCcaBCC", + 11 + ], + [ + "aAB", + "bcbccABCA", + 14 + ], + [ + "aABA", + "cCac", + 8 + ], + [ + "aABAB", + "AaaBBcCA", + 11 + ], + [ + "aABACAa", + "CcBBbA", + 10 + ], + [ + "aABAaA", + "C", + 12 + ], + [ + "aABAb", + "BbBCC", + 8 + ], + [ + "aABAb", + "ca", + 9 + ], + [ + "aABAbab", + "a", + 12 + ], + [ + "aABAc", + "AabAabaB", + 10 + ], + [ + "aABAcCbbA", + "aB", + 14 + ], + [ + "aABB", + "CCAaaccbA", + 14 + ], + [ + "aABB", + "aCac", + 6 + ], + [ + "aABB", + "cb", + 7 + ], + [ + "aABBBBCc", + "cBAcbb", + 13 + ], + [ + "aABBBBa", + "CaBaCCBB", + 11 + ], + [ + "aABBCc", + "cc", + 9 + ], + [ + "aABBacCA", + "BBbacBc", + 9 + ], + [ + "aABBbA", + "aCBbC", + 6 + ], + [ + "aABBbaB", + "CbbBCbacb", + 10 + ], + [ + "aABCAa", + "bBbC", + 9 + ], + [ + "aABCB", + "cAB", + 6 + ], + [ + "aABCCcbB", + "CBbaCcbc", + 9 + ], + [ + "aABCaca", + "Bb", + 12 + ], + [ + "aABCbCba", + "CabccBaB", + 11 + ], + [ + "aABaBA", + "BC", + 10 + ], + [ + "aABaBbAAA", + "B", + 16 + ], + [ + "aABb", + "BC", + 6 + ], + [ + "aABbAa", + "bCbBcC", + 10 + ], + [ + "aABbBbCca", + "ABCCBAbAc", + 12 + ], + [ + "aABbaA", + "bcBC", + 10 + ], + [ + "aABbac", + "AbBbABAAb", + 12 + ], + [ + "aABbccca", + "BcaA", + 11 + ], + [ + "aABcACB", + "A", + 12 + ], + [ + "aABccB", + "A", + 10 + ], + [ + "aAC", + "BA", + 4 + ], + [ + "aAC", + "CAbbaab", + 11 + ], + [ + "aAC", + "CbC", + 4 + ], + [ + "aAC", + "b", + 6 + ], + [ + "aAC", + "bACCbC", + 8 + ], + [ + "aAC", + "bcaBacc", + 10 + ], + [ + "aACABAcCa", + "ccCB", + 13 + ], + [ + "aACBA", + "Aa", + 7 + ], + [ + "aACBACA", + "BaCBa", + 8 + ], + [ + "aACBBcBC", + "A", + 14 + ], + [ + "aACCA", + "Cb", + 8 + ], + [ + "aACCAAb", + "Bca", + 12 + ], + [ + "aACCBc", + "AcbAaCB", + 9 + ], + [ + "aACCa", + "ACccABA", + 10 + ], + [ + "aACCbAA", + "AAaa", + 9 + ], + [ + "aACCc", + "BBcc", + 7 + ], + [ + "aACCc", + "cbaBAC", + 10 + ], + [ + "aACaaA", + "bcACaCbA", + 8 + ], + [ + "aACacACa", + "aaBccaB", + 10 + ], + [ + "aACacCb", + "C", + 12 + ], + [ + "aACaccCAC", + "cC", + 14 + ], + [ + "aACbAC", + "AB", + 9 + ], + [ + "aACbBBcb", + "b", + 14 + ], + [ + "aACbbbaBC", + "aBBACCB", + 13 + ], + [ + "aACcaBb", + "ABabA", + 9 + ], + [ + "aACcbCa", + "b", + 12 + ], + [ + "aAa", + "BbBb", + 8 + ], + [ + "aAa", + "CBCBAabb", + 12 + ], + [ + "aAa", + "Cc", + 6 + ], + [ + "aAa", + "bCaaCBcAa", + 12 + ], + [ + "aAa", + "bc", + 6 + ], + [ + "aAaA", + "b", + 8 + ], + [ + "aAaAcc", + "B", + 12 + ], + [ + "aAaAccAb", + "BCAbabcAA", + 11 + ], + [ + "aAaBBCb", + "Cbbc", + 11 + ], + [ + "aAaBaBBBc", + "cAcCCCA", + 16 + ], + [ + "aAaBaBa", + "bBbBc", + 10 + ], + [ + "aAaCB", + "cCc", + 8 + ], + [ + "aAaCCCc", + "bbcBabaAA", + 16 + ], + [ + "aAaCaaAc", + "BCaA", + 10 + ], + [ + "aAaa", + "bb", + 8 + ], + [ + "aAaaAcCA", + "cBbcccB", + 13 + ], + [ + "aAaaBbbb", + "bCca", + 14 + ], + [ + "aAaaC", + "aCAC", + 5 + ], + [ + "aAaaCBa", + "aaCBCc", + 8 + ], + [ + "aAaaaA", + "aBACbaBAC", + 10 + ], + [ + "aAaabBcb", + "AcCAcBA", + 12 + ], + [ + "aAab", + "C", + 8 + ], + [ + "aAab", + "bCaB", + 5 + ], + [ + "aAab", + "bbaacCCB", + 12 + ], + [ + "aAabC", + "ccbBa", + 9 + ], + [ + "aAabCAc", + "aBCb", + 9 + ], + [ + "aAabCCBaa", + "bBC", + 14 + ], + [ + "aAabbbbB", + "CBAACBCCb", + 13 + ], + [ + "aAabbcCaA", + "A", + 16 + ], + [ + "aAac", + "cCBbCAaBB", + 14 + ], + [ + "aAacB", + "cAcbcBa", + 8 + ], + [ + "aAacBcCBa", + "cba", + 13 + ], + [ + "aAb", + "A", + 4 + ], + [ + "aAb", + "a", + 4 + ], + [ + "aAb", + "b", + 4 + ], + [ + "aAbA", + "bccaaaCAB", + 13 + ], + [ + "aAbABAA", + "bCBAcabBb", + 14 + ], + [ + "aAbAC", + "cACcCa", + 8 + ], + [ + "aAbACaBAA", + "CB", + 14 + ], + [ + "aAbAb", + "cBBabc", + 8 + ], + [ + "aAbAcCb", + "c", + 12 + ], + [ + "aAbBB", + "AC", + 8 + ], + [ + "aAbBaBcAA", + "C", + 17 + ], + [ + "aAbCAcbCC", + "BAAaA", + 14 + ], + [ + "aAbCBA", + "aCBaCABc", + 9 + ], + [ + "aAbCCACCb", + "AbcacbAb", + 11 + ], + [ + "aAbCCC", + "Aca", + 9 + ], + [ + "aAbCa", + "bABc", + 6 + ], + [ + "aAbCbCa", + "AabbBCbA", + 8 + ], + [ + "aAbCbbaba", + "CcBbccaB", + 14 + ], + [ + "aAbCc", + "cCa", + 8 + ], + [ + "aAba", + "BbcbcCBcC", + 16 + ], + [ + "aAbaBA", + "aBAAAA", + 7 + ], + [ + "aAbaBBba", + "Cb", + 14 + ], + [ + "aAbaCAA", + "cAB", + 11 + ], + [ + "aAbaaBA", + "bcCbaccBA", + 10 + ], + [ + "aAbb", + "bBBaACCBC", + 13 + ], + [ + "aAbbABabC", + "cbACbB", + 12 + ], + [ + "aAbbBab", + "caaA", + 11 + ], + [ + "aAbbCAA", + "BBbBcbA", + 8 + ], + [ + "aAbbCbCCa", + "AAB", + 14 + ], + [ + "aAbbCbcb", + "CBc", + 11 + ], + [ + "aAbbaB", + "a", + 10 + ], + [ + "aAbbacAb", + "BccBb", + 11 + ], + [ + "aAbbcbA", + "A", + 12 + ], + [ + "aAbcCaA", + "CCc", + 11 + ], + [ + "aAbcaABCA", + "BCAcbCab", + 13 + ], + [ + "aAbcaAa", + "CCababB", + 11 + ], + [ + "aAbcbbB", + "baba", + 10 + ], + [ + "aAc", + "aBbBCbac", + 11 + ], + [ + "aAc", + "abbAbaC", + 9 + ], + [ + "aAcA", + "A", + 6 + ], + [ + "aAcA", + "ACABBCB", + 10 + ], + [ + "aAcAAb", + "ACC", + 9 + ], + [ + "aAcAAbB", + "cAbbBaCBb", + 13 + ], + [ + "aAcAabacA", + "aCbBcA", + 9 + ], + [ + "aAcAacaba", + "caACb", + 11 + ], + [ + "aAcAbaCac", + "bBc", + 14 + ], + [ + "aAcAcAbaB", + "bcCCa", + 13 + ], + [ + "aAcB", + "aaaCC", + 6 + ], + [ + "aAcB", + "caC", + 6 + ], + [ + "aAcBACBB", + "a", + 14 + ], + [ + "aAcBC", + "aCca", + 6 + ], + [ + "aAcBbABB", + "AA", + 12 + ], + [ + "aAcBbAaBC", + "BbCbaCcaC", + 14 + ], + [ + "aAcCAaC", + "b", + 14 + ], + [ + "aAcCCcAc", + "baabCBAaA", + 12 + ], + [ + "aAcCccBB", + "AaAa", + 14 + ], + [ + "aAcaAaB", + "AcC", + 10 + ], + [ + "aAcaBaA", + "ACcaaA", + 5 + ], + [ + "aAcaaac", + "BaABaBaBA", + 10 + ], + [ + "aAcb", + "AABbA", + 5 + ], + [ + "aAcb", + "aABC", + 4 + ], + [ + "aAcbA", + "cbcAAC", + 8 + ], + [ + "aAcbBb", + "CbcccCBcC", + 14 + ], + [ + "aAcbBcca", + "A", + 14 + ], + [ + "aAcba", + "acBcBBBAc", + 12 + ], + [ + "aAcba", + "b", + 8 + ], + [ + "aAcc", + "CACC", + 4 + ], + [ + "aAccac", + "ACABCBBAC", + 12 + ], + [ + "aAccbCaba", + "BCBbBc", + 14 + ], + [ + "aB", + "A", + 3 + ], + [ + "aB", + "AA", + 3 + ], + [ + "aB", + "AB", + 1 + ], + [ + "aB", + "ABAb", + 5 + ], + [ + "aB", + "ACcb", + 6 + ], + [ + "aB", + "Aabaaa", + 9 + ], + [ + "aB", + "AccabABB", + 12 + ], + [ + "aB", + "B", + 2 + ], + [ + "aB", + "BBcbB", + 8 + ], + [ + "aB", + "BCc", + 6 + ], + [ + "aB", + "Bca", + 6 + ], + [ + "aB", + "C", + 4 + ], + [ + "aB", + "CAAaa", + 8 + ], + [ + "aB", + "CbccACC", + 13 + ], + [ + "aB", + "Cc", + 4 + ], + [ + "aB", + "CcAcCC", + 11 + ], + [ + "aB", + "aCbBBc", + 8 + ], + [ + "aB", + "aaAbCb", + 9 + ], + [ + "aB", + "aaaAb", + 7 + ], + [ + "aB", + "aabCACc", + 11 + ], + [ + "aB", + "abAC", + 5 + ], + [ + "aB", + "bB", + 2 + ], + [ + "aB", + "bBB", + 4 + ], + [ + "aB", + "bb", + 3 + ], + [ + "aB", + "bbbca", + 9 + ], + [ + "aB", + "bbc", + 5 + ], + [ + "aB", + "bc", + 4 + ], + [ + "aB", + "bcb", + 5 + ], + [ + "aB", + "cB", + 2 + ], + [ + "aB", + "cCC", + 6 + ], + [ + "aB", + "cc", + 4 + ], + [ + "aBA", + "BAaAaaCBc", + 14 + ], + [ + "aBAAA", + "CBCAbbcAA", + 10 + ], + [ + "aBAAB", + "BacBABcAc", + 10 + ], + [ + "aBAAaB", + "caAc", + 9 + ], + [ + "aBAAacaa", + "acabBBcBC", + 13 + ], + [ + "aBAAbCcB", + "BCB", + 10 + ], + [ + "aBAAcbCc", + "cBCBBcAAB", + 14 + ], + [ + "aBAB", + "aaCc", + 6 + ], + [ + "aBAB", + "bbaAbA", + 8 + ], + [ + "aBABa", + "bacAa", + 6 + ], + [ + "aBABaABc", + "AAaCCC", + 10 + ], + [ + "aBABcaABA", + "CBcbB", + 12 + ], + [ + "aBACC", + "a", + 8 + ], + [ + "aBACa", + "c", + 9 + ], + [ + "aBACba", + "C", + 10 + ], + [ + "aBACcAA", + "B", + 12 + ], + [ + "aBAa", + "aaB", + 5 + ], + [ + "aBAaC", + "cCACbbBb", + 14 + ], + [ + "aBAabaAB", + "cacCbb", + 13 + ], + [ + "aBAabba", + "AaBABbCBc", + 9 + ], + [ + "aBAacCbbb", + "aBaCaAc", + 10 + ], + [ + "aBAacc", + "aAaAAcABC", + 10 + ], + [ + "aBAb", + "aBBbAac", + 8 + ], + [ + "aBAbAC", + "aABAbCAc", + 5 + ], + [ + "aBAbaaab", + "CCbbAaba", + 11 + ], + [ + "aBAbbB", + "aCacbAB", + 7 + ], + [ + "aBAbbcbb", + "bcBAb", + 11 + ], + [ + "aBAcABbb", + "Ca", + 14 + ], + [ + "aBAcBa", + "CbBcCaa", + 9 + ], + [ + "aBAcBbC", + "aaAaBac", + 7 + ], + [ + "aBAca", + "AACACCcAa", + 11 + ], + [ + "aBAcabBA", + "BBACb", + 9 + ], + [ + "aBAcba", + "bBaaCcB", + 10 + ], + [ + "aBAccCaba", + "CAcabBBbC", + 14 + ], + [ + "aBAcca", + "ABAABbCa", + 8 + ], + [ + "aBB", + "AaAbaAaBb", + 13 + ], + [ + "aBB", + "AaCaB", + 6 + ], + [ + "aBB", + "Acbc", + 6 + ], + [ + "aBB", + "aC", + 4 + ], + [ + "aBB", + "aa", + 4 + ], + [ + "aBB", + "bbCAAaBBB", + 12 + ], + [ + "aBBA", + "BAAc", + 6 + ], + [ + "aBBABAaAA", + "AbCAcbAA", + 10 + ], + [ + "aBBABaaaa", + "bCC", + 17 + ], + [ + "aBBABca", + "bA", + 11 + ], + [ + "aBBACC", + "caaCB", + 9 + ], + [ + "aBBAc", + "aCAA", + 6 + ], + [ + "aBBB", + "AcBcBa", + 7 + ], + [ + "aBBBA", + "CcbaAB", + 9 + ], + [ + "aBBBABAB", + "BBA", + 10 + ], + [ + "aBBBACB", + "Aa", + 12 + ], + [ + "aBBBAaA", + "bB", + 11 + ], + [ + "aBBBB", + "AaBb", + 6 + ], + [ + "aBBBCCBbb", + "BCBca", + 12 + ], + [ + "aBBBaBaAa", + "cCCB", + 16 + ], + [ + "aBBC", + "AbabA", + 7 + ], + [ + "aBBC", + "CcbcBBCb", + 10 + ], + [ + "aBBC", + "cCbbBa", + 9 + ], + [ + "aBBCBac", + "AbacacaCC", + 12 + ], + [ + "aBBCBbab", + "bb", + 12 + ], + [ + "aBBCaCCAB", + "ccBAcA", + 12 + ], + [ + "aBBCbAb", + "cACACb", + 10 + ], + [ + "aBBCbB", + "aCabbA", + 8 + ], + [ + "aBBCcabCb", + "CCacAacc", + 14 + ], + [ + "aBBaB", + "BCaccaa", + 10 + ], + [ + "aBBaB", + "bACCbA", + 11 + ], + [ + "aBBaCCab", + "CBcAbcC", + 12 + ], + [ + "aBBaa", + "a", + 8 + ], + [ + "aBBabAb", + "bACbcAa", + 11 + ], + [ + "aBBac", + "BbAa", + 6 + ], + [ + "aBBacABac", + "CbCbc", + 13 + ], + [ + "aBBb", + "BCAaBa", + 9 + ], + [ + "aBBbA", + "aaa", + 7 + ], + [ + "aBBbB", + "bbBaba", + 7 + ], + [ + "aBBbba", + "bCCcacbB", + 14 + ], + [ + "aBBc", + "BccbaCCac", + 14 + ], + [ + "aBBcABB", + "BBcAbCBAB", + 8 + ], + [ + "aBBcBAab", + "CcCBBA", + 12 + ], + [ + "aBBcBBA", + "cC", + 12 + ], + [ + "aBBcBcb", + "BBBca", + 6 + ], + [ + "aBBcaB", + "AbBAa", + 6 + ], + [ + "aBBccB", + "abcac", + 7 + ], + [ + "aBBcca", + "bABb", + 10 + ], + [ + "aBBcccbCB", + "bCcab", + 12 + ], + [ + "aBC", + "AABCBaAAC", + 13 + ], + [ + "aBC", + "CcaCAB", + 10 + ], + [ + "aBC", + "aACCc", + 6 + ], + [ + "aBC", + "aaaCcCcB", + 12 + ], + [ + "aBC", + "bABBAa", + 9 + ], + [ + "aBC", + "bC", + 3 + ], + [ + "aBC", + "baCCa", + 6 + ], + [ + "aBC", + "bc", + 4 + ], + [ + "aBCA", + "AbbcbAb", + 9 + ], + [ + "aBCA", + "CBaAa", + 6 + ], + [ + "aBCAa", + "BbCCAbAAb", + 12 + ], + [ + "aBCAcBAa", + "BC", + 12 + ], + [ + "aBCAcBCAC", + "AABaCbBcA", + 12 + ], + [ + "aBCAccBCB", + "b", + 17 + ], + [ + "aBCBA", + "b", + 9 + ], + [ + "aBCBBCa", + "aCCAaa", + 8 + ], + [ + "aBCBC", + "bCccB", + 8 + ], + [ + "aBCBC", + "bbB", + 7 + ], + [ + "aBCBabb", + "a", + 12 + ], + [ + "aBCCcc", + "caAAc", + 10 + ], + [ + "aBCaB", + "cB", + 7 + ], + [ + "aBCaCa", + "aCA", + 7 + ], + [ + "aBCaCbC", + "BcaaBaABA", + 13 + ], + [ + "aBCab", + "cAacAcCaA", + 12 + ], + [ + "aBCababA", + "ccbABc", + 11 + ], + [ + "aBCac", + "CbCBbaAB", + 11 + ], + [ + "aBCb", + "acabaC", + 8 + ], + [ + "aBCbb", + "C", + 8 + ], + [ + "aBCbbB", + "bCcBb", + 7 + ], + [ + "aBCbcCBc", + "cBaCAc", + 10 + ], + [ + "aBCc", + "bABcbCa", + 9 + ], + [ + "aBCcAc", + "cCAaaAc", + 10 + ], + [ + "aBCcAcAC", + "BCcBaca", + 8 + ], + [ + "aBCcCBaa", + "b", + 15 + ], + [ + "aBCcCBbcC", + "ba", + 16 + ], + [ + "aBCcaBAaC", + "bBbcaCC", + 10 + ], + [ + "aBa", + "cBCbb", + 8 + ], + [ + "aBa", + "caB", + 4 + ], + [ + "aBaA", + "caBAC", + 5 + ], + [ + "aBaAaAcC", + "CAbBbbabc", + 13 + ], + [ + "aBaAcCBBA", + "AcAcc", + 12 + ], + [ + "aBaAcCC", + "Bc", + 10 + ], + [ + "aBaB", + "CBBbc", + 7 + ], + [ + "aBaB", + "bBAaA", + 6 + ], + [ + "aBaBC", + "CBbcaaBA", + 10 + ], + [ + "aBaBbA", + "CCabBBAaC", + 11 + ], + [ + "aBaBbCcc", + "aB", + 12 + ], + [ + "aBaBc", + "CcCAb", + 10 + ], + [ + "aBaC", + "A", + 7 + ], + [ + "aBaC", + "aa", + 4 + ], + [ + "aBaC", + "accAbAC", + 8 + ], + [ + "aBaCCAb", + "cbBC", + 11 + ], + [ + "aBaCaA", + "Aa", + 9 + ], + [ + "aBaCaC", + "CbaCccAc", + 9 + ], + [ + "aBaCaabAc", + "bCcACb", + 13 + ], + [ + "aBaCba", + "baB", + 8 + ], + [ + "aBaa", + "CBaBAABbB", + 12 + ], + [ + "aBaa", + "Cb", + 7 + ], + [ + "aBaaA", + "aAAaABCB", + 9 + ], + [ + "aBaabC", + "bCBbAabAC", + 9 + ], + [ + "aBaabCba", + "bCCaB", + 12 + ], + [ + "aBaabaB", + "AA", + 12 + ], + [ + "aBaacBbca", + "cCc", + 14 + ], + [ + "aBabACAA", + "acABb", + 12 + ], + [ + "aBabBcb", + "bAbA", + 10 + ], + [ + "aBabbaBbc", + "cbaccAb", + 12 + ], + [ + "aBac", + "c", + 6 + ], + [ + "aBacAAcA", + "aaCB", + 11 + ], + [ + "aBacBB", + "cb", + 9 + ], + [ + "aBacC", + "ACCCcAb", + 11 + ], + [ + "aBacCB", + "abccAac", + 9 + ], + [ + "aBaccCAa", + "aBcacaaCb", + 10 + ], + [ + "aBb", + "BCBAabbac", + 13 + ], + [ + "aBb", + "Ccb", + 4 + ], + [ + "aBb", + "aaac", + 6 + ], + [ + "aBb", + "bbcbbbAaC", + 15 + ], + [ + "aBb", + "cbCaBb", + 6 + ], + [ + "aBb", + "cbaB", + 6 + ], + [ + "aBbA", + "bbaaAbab", + 11 + ], + [ + "aBbACC", + "cCcccBCC", + 12 + ], + [ + "aBbAcCBCA", + "cCBab", + 12 + ], + [ + "aBbB", + "BacA", + 8 + ], + [ + "aBbB", + "aCcCb", + 7 + ], + [ + "aBbBA", + "aAcC", + 8 + ], + [ + "aBbBB", + "aBCc", + 6 + ], + [ + "aBbBCbBAa", + "Ac", + 16 + ], + [ + "aBbBa", + "bAa", + 6 + ], + [ + "aBbBbAbC", + "Abc", + 11 + ], + [ + "aBbBbaBA", + "AbbBCccC", + 10 + ], + [ + "aBbBbcBcb", + "abaBAAAAB", + 12 + ], + [ + "aBbC", + "bCbBAcBc", + 12 + ], + [ + "aBbCABBA", + "Caa", + 12 + ], + [ + "aBbCACaCb", + "A", + 16 + ], + [ + "aBbCBCaBC", + "aCcc", + 12 + ], + [ + "aBbCaa", + "cbAC", + 9 + ], + [ + "aBbCbbbBA", + "aA", + 14 + ], + [ + "aBbCbcCAb", + "BcAC", + 12 + ], + [ + "aBbCc", + "AcACCCba", + 12 + ], + [ + "aBba", + "BcAcCBB", + 12 + ], + [ + "aBbaAACBA", + "BacacbaC", + 12 + ], + [ + "aBbaAB", + "bbCc", + 9 + ], + [ + "aBbaBcC", + "c", + 12 + ], + [ + "aBbaCcbC", + "bbbbcab", + 10 + ], + [ + "aBbaaCcaA", + "bBABBAbCc", + 13 + ], + [ + "aBbabCc", + "CaCB", + 10 + ], + [ + "aBbb", + "Bb", + 4 + ], + [ + "aBbb", + "cccAbB", + 9 + ], + [ + "aBbbA", + "AAC", + 9 + ], + [ + "aBbbAB", + "C", + 12 + ], + [ + "aBbbCab", + "AaCBacaba", + 10 + ], + [ + "aBbbbBA", + "BcbbBBA", + 5 + ], + [ + "aBbcCBaCc", + "C", + 16 + ], + [ + "aBbcCba", + "BbAcaBac", + 9 + ], + [ + "aBc", + "A", + 5 + ], + [ + "aBc", + "Bac", + 4 + ], + [ + "aBc", + "bCCc", + 6 + ], + [ + "aBc", + "baC", + 5 + ], + [ + "aBcAA", + "ABc", + 5 + ], + [ + "aBcAABabC", + "cab", + 12 + ], + [ + "aBcAaAccc", + "BacacaA", + 12 + ], + [ + "aBcAabAA", + "aBcB", + 9 + ], + [ + "aBcAc", + "bCCbbCc", + 11 + ], + [ + "aBcB", + "c", + 6 + ], + [ + "aBcBBBA", + "BbBBaAAab", + 12 + ], + [ + "aBcBBCAbb", + "AAA", + 15 + ], + [ + "aBcBaa", + "bbB", + 9 + ], + [ + "aBcBbbCb", + "cAcBCca", + 11 + ], + [ + "aBcC", + "CCAAA", + 10 + ], + [ + "aBcCABCc", + "BCbbcC", + 9 + ], + [ + "aBcCBbAc", + "cAbABaAa", + 12 + ], + [ + "aBcCCbA", + "cbA", + 8 + ], + [ + "aBcCcbaAC", + "aBBbBaB", + 11 + ], + [ + "aBca", + "BacbCCcB", + 11 + ], + [ + "aBca", + "CBAcCcCA", + 11 + ], + [ + "aBcaCC", + "c", + 10 + ], + [ + "aBcaaBB", + "BAbBaACbc", + 12 + ], + [ + "aBcbABAAa", + "bCCc", + 16 + ], + [ + "aBcbCAb", + "abA", + 8 + ], + [ + "aBcba", + "cAbCC", + 9 + ], + [ + "aBccABa", + "baBbCAAB", + 9 + ], + [ + "aBccAbac", + "CAaaCbb", + 14 + ], + [ + "aBccacCBa", + "ccbc", + 12 + ], + [ + "aBcccC", + "CccbACAcc", + 12 + ], + [ + "aC", + "AABacca", + 11 + ], + [ + "aC", + "ABABACC", + 11 + ], + [ + "aC", + "AcaBa", + 8 + ], + [ + "aC", + "AcaCBcaCB", + 14 + ], + [ + "aC", + "BBbbBcA", + 13 + ], + [ + "aC", + "BCABB", + 8 + ], + [ + "aC", + "Ba", + 4 + ], + [ + "aC", + "BaACBc", + 8 + ], + [ + "aC", + "BacccCb", + 10 + ], + [ + "aC", + "BcACaaCa", + 12 + ], + [ + "aC", + "BcB", + 5 + ], + [ + "aC", + "CAAcA", + 8 + ], + [ + "aC", + "CBbB", + 8 + ], + [ + "aC", + "CCA", + 4 + ], + [ + "aC", + "CaAA", + 6 + ], + [ + "aC", + "a", + 2 + ], + [ + "aC", + "aACaBBaB", + 12 + ], + [ + "aC", + "abCBcb", + 8 + ], + [ + "aC", + "abcabC", + 8 + ], + [ + "aC", + "bA", + 4 + ], + [ + "aC", + "bABAabc", + 11 + ], + [ + "aC", + "bBAAbCAcB", + 15 + ], + [ + "aC", + "bBaaaA", + 10 + ], + [ + "aC", + "bCBA", + 6 + ], + [ + "aC", + "baaaCC", + 8 + ], + [ + "aC", + "babcC", + 6 + ], + [ + "aC", + "bbc", + 5 + ], + [ + "aC", + "caCbAcaCc", + 14 + ], + [ + "aC", + "cbCaCaB", + 10 + ], + [ + "aCA", + "BCcBBaBc", + 13 + ], + [ + "aCA", + "CAACacC", + 10 + ], + [ + "aCA", + "bAaaC", + 8 + ], + [ + "aCA", + "babAaaBaC", + 14 + ], + [ + "aCA", + "baccbBBC", + 13 + ], + [ + "aCA", + "cBCc", + 6 + ], + [ + "aCAAA", + "aB", + 8 + ], + [ + "aCAAAaAba", + "BAbB", + 14 + ], + [ + "aCAABBBBb", + "BBABB", + 11 + ], + [ + "aCAACBcA", + "aA", + 12 + ], + [ + "aCAAaaa", + "AcbacaACb", + 12 + ], + [ + "aCAAbCBbA", + "cBc", + 15 + ], + [ + "aCAAcbC", + "CAaAcCcCc", + 10 + ], + [ + "aCAB", + "AbabAb", + 7 + ], + [ + "aCAB", + "BA", + 6 + ], + [ + "aCAB", + "CBAC", + 6 + ], + [ + "aCABAcBac", + "CCBCcbCC", + 10 + ], + [ + "aCABBC", + "ABb", + 7 + ], + [ + "aCABaAaC", + "BCaaABcC", + 9 + ], + [ + "aCABaBca", + "c", + 14 + ], + [ + "aCABaa", + "C", + 10 + ], + [ + "aCACACAC", + "baAbACC", + 8 + ], + [ + "aCACBBC", + "aCACBaAac", + 7 + ], + [ + "aCACBaaA", + "acCcCB", + 10 + ], + [ + "aCACCca", + "aBA", + 10 + ], + [ + "aCACa", + "baBbABB", + 10 + ], + [ + "aCACcbaa", + "CbAbBCBb", + 14 + ], + [ + "aCAa", + "bBCCcc", + 10 + ], + [ + "aCAaCba", + "AabAc", + 9 + ], + [ + "aCAab", + "CCCcCCAA", + 13 + ], + [ + "aCAacCAAa", + "abAcBacA", + 10 + ], + [ + "aCAb", + "Aaac", + 6 + ], + [ + "aCAbCC", + "bca", + 9 + ], + [ + "aCAbCC", + "cCABABac", + 10 + ], + [ + "aCAbCaCca", + "cACA", + 12 + ], + [ + "aCAbaBab", + "BABbA", + 11 + ], + [ + "aCAbca", + "B", + 11 + ], + [ + "aCAcBbbC", + "acaAbACAB", + 12 + ], + [ + "aCAcaCB", + "CbC", + 10 + ], + [ + "aCAcacc", + "aA", + 10 + ], + [ + "aCAcbA", + "aa", + 9 + ], + [ + "aCAcbabB", + "Aabbca", + 12 + ], + [ + "aCAccCa", + "AaBca", + 8 + ], + [ + "aCB", + "A", + 5 + ], + [ + "aCB", + "aAaCbBcA", + 10 + ], + [ + "aCB", + "aBABAaccA", + 14 + ], + [ + "aCB", + "aBcAb", + 6 + ], + [ + "aCB", + "abCbBA", + 6 + ], + [ + "aCB", + "b", + 5 + ], + [ + "aCB", + "cCcaBbc", + 10 + ], + [ + "aCBA", + "BCcCccBA", + 10 + ], + [ + "aCBA", + "cCCbcA", + 7 + ], + [ + "aCBAabBa", + "aA", + 12 + ], + [ + "aCBAb", + "B", + 8 + ], + [ + "aCBAbb", + "c", + 11 + ], + [ + "aCBB", + "bAb", + 7 + ], + [ + "aCBBAAB", + "bcbCAAAbc", + 11 + ], + [ + "aCBBBAab", + "CBcBbBcb", + 9 + ], + [ + "aCBBCcC", + "aBaCAa", + 8 + ], + [ + "aCBBabca", + "bCaaC", + 11 + ], + [ + "aCBBbb", + "cb", + 9 + ], + [ + "aCBBcBBC", + "c", + 14 + ], + [ + "aCBCCa", + "AaaABcA", + 10 + ], + [ + "aCBCc", + "bacBbaaaA", + 13 + ], + [ + "aCBa", + "cAA", + 6 + ], + [ + "aCBaABA", + "ba", + 11 + ], + [ + "aCBaAC", + "a", + 10 + ], + [ + "aCBaacBc", + "cacacCBB", + 10 + ], + [ + "aCBb", + "Ba", + 6 + ], + [ + "aCBb", + "CaAc", + 8 + ], + [ + "aCBb", + "CaBb", + 4 + ], + [ + "aCBbABbA", + "CbBcaA", + 10 + ], + [ + "aCBbACC", + "cAaBBC", + 10 + ], + [ + "aCBbBAcBB", + "aabBbCcaB", + 9 + ], + [ + "aCBbBc", + "aBabCbbaC", + 10 + ], + [ + "aCBbcccA", + "cCA", + 11 + ], + [ + "aCBc", + "ABAAaC", + 10 + ], + [ + "aCBc", + "BCcc", + 4 + ], + [ + "aCBcB", + "bBCCAC", + 10 + ], + [ + "aCBcaC", + "A", + 11 + ], + [ + "aCC", + "AB", + 5 + ], + [ + "aCC", + "Ac", + 4 + ], + [ + "aCC", + "abABbCBc", + 11 + ], + [ + "aCC", + "cBAcBCcb", + 12 + ], + [ + "aCC", + "cCCcBaa", + 10 + ], + [ + "aCCAA", + "C", + 8 + ], + [ + "aCCAB", + "bbCB", + 6 + ], + [ + "aCCABabA", + "aCa", + 10 + ], + [ + "aCCAcCbA", + "cBbCc", + 13 + ], + [ + "aCCAccAA", + "CB", + 14 + ], + [ + "aCCBBB", + "cccacc", + 10 + ], + [ + "aCCBCcA", + "aAc", + 10 + ], + [ + "aCCBCcCC", + "acBCbA", + 9 + ], + [ + "aCCC", + "ACbCcBa", + 8 + ], + [ + "aCCCBAC", + "AB", + 11 + ], + [ + "aCCCBCBa", + "a", + 14 + ], + [ + "aCCCBaAAa", + "CcBb", + 13 + ], + [ + "aCCCCB", + "cCABAcbA", + 12 + ], + [ + "aCCCCbCc", + "B", + 15 + ], + [ + "aCCCCcCb", + "AAB", + 14 + ], + [ + "aCCCab", + "BAaBcaC", + 10 + ], + [ + "aCCCc", + "aBabBBaa", + 14 + ], + [ + "aCCaA", + "aAAbb", + 8 + ], + [ + "aCCaA", + "cAA", + 6 + ], + [ + "aCCaBCcb", + "BAcc", + 12 + ], + [ + "aCCaC", + "CcacABac", + 10 + ], + [ + "aCCbBBbCB", + "baAcABCC", + 13 + ], + [ + "aCCbbAC", + "BAcbcB", + 11 + ], + [ + "aCCbbbaaB", + "abbC", + 12 + ], + [ + "aCCc", + "bAa", + 8 + ], + [ + "aCCc", + "cbaB", + 8 + ], + [ + "aCCcABBCB", + "bbC", + 14 + ], + [ + "aCCcBBABA", + "bABaacb", + 15 + ], + [ + "aCCcBCCBc", + "a", + 16 + ], + [ + "aCCcbaa", + "B", + 13 + ], + [ + "aCCccBBa", + "baAB", + 14 + ], + [ + "aCa", + "B", + 6 + ], + [ + "aCa", + "BCcC", + 6 + ], + [ + "aCa", + "bbbbCBA", + 11 + ], + [ + "aCaAAACa", + "AcCAA", + 10 + ], + [ + "aCaAAb", + "BCBccaB", + 10 + ], + [ + "aCaABBc", + "aCAbcbB", + 8 + ], + [ + "aCaABbAb", + "aBc", + 12 + ], + [ + "aCaAb", + "aCc", + 6 + ], + [ + "aCaAcCBb", + "baCcbb", + 9 + ], + [ + "aCaAcaC", + "BBCcCcbc", + 11 + ], + [ + "aCaB", + "BacaaAcBA", + 11 + ], + [ + "aCaB", + "C", + 6 + ], + [ + "aCaBAC", + "ab", + 9 + ], + [ + "aCaBBa", + "B", + 10 + ], + [ + "aCaBCB", + "a", + 10 + ], + [ + "aCaBCCB", + "cAccc", + 10 + ], + [ + "aCaBa", + "aC", + 6 + ], + [ + "aCaBacB", + "AAbcaB", + 9 + ], + [ + "aCaC", + "BBcc", + 7 + ], + [ + "aCaC", + "CAAaCAB", + 9 + ], + [ + "aCaC", + "accBcAAbA", + 14 + ], + [ + "aCaCAAac", + "CcCAB", + 10 + ], + [ + "aCaCBaaBb", + "CC", + 14 + ], + [ + "aCaCacAba", + "cbaAbBB", + 13 + ], + [ + "aCaCccca", + "CbACAc", + 11 + ], + [ + "aCaa", + "BAbB", + 8 + ], + [ + "aCaaC", + "ABacC", + 5 + ], + [ + "aCaac", + "AcabAC", + 6 + ], + [ + "aCaacB", + "CA", + 9 + ], + [ + "aCaacacbC", + "b", + 16 + ], + [ + "aCab", + "AcccBcB", + 11 + ], + [ + "aCab", + "BaaacBbbA", + 12 + ], + [ + "aCabBacCB", + "AAc", + 14 + ], + [ + "aCabCBBB", + "CBBcBbBBB", + 10 + ], + [ + "aCabCbbb", + "CBCCCcA", + 12 + ], + [ + "aCabaA", + "bABbaB", + 8 + ], + [ + "aCabbbCA", + "Ba", + 14 + ], + [ + "aCabcb", + "bBBb", + 9 + ], + [ + "aCacA", + "BbAB", + 9 + ], + [ + "aCacCa", + "baABcBcAb", + 12 + ], + [ + "aCacCcAaC", + "CbAbBa", + 14 + ], + [ + "aCacbC", + "CcbABcb", + 10 + ], + [ + "aCb", + "AaBaAc", + 10 + ], + [ + "aCb", + "BB", + 5 + ], + [ + "aCb", + "a", + 4 + ], + [ + "aCb", + "cCbBC", + 6 + ], + [ + "aCbA", + "CcCccBc", + 11 + ], + [ + "aCbA", + "bBaC", + 8 + ], + [ + "aCbAa", + "AABbbcCAC", + 13 + ], + [ + "aCbBAA", + "BcCC", + 11 + ], + [ + "aCbBAB", + "bcCBb", + 8 + ], + [ + "aCbBB", + "B", + 8 + ], + [ + "aCbBCaB", + "aCcAcaAbB", + 9 + ], + [ + "aCbBb", + "CBbA", + 6 + ], + [ + "aCbCBB", + "CAaACaA", + 11 + ], + [ + "aCbCBc", + "ABaBAcAcC", + 13 + ], + [ + "aCbCcCBCB", + "CBbc", + 13 + ], + [ + "aCba", + "aCba", + 0 + ], + [ + "aCbaa", + "BacbBccb", + 11 + ], + [ + "aCbb", + "bBcCBAAcc", + 15 + ], + [ + "aCbbCCCB", + "AaAC", + 13 + ], + [ + "aCbbaBAa", + "BbB", + 11 + ], + [ + "aCbbc", + "BBCAb", + 8 + ], + [ + "aCbbcAcB", + "accCaaB", + 9 + ], + [ + "aCbca", + "AbAc", + 7 + ], + [ + "aCbcb", + "cBcacaa", + 11 + ], + [ + "aCbcc", + "cBCbBAbB", + 12 + ], + [ + "aCbcca", + "CBbCaaCC", + 11 + ], + [ + "aCbccb", + "cAAab", + 9 + ], + [ + "aCc", + "AaAbC", + 7 + ], + [ + "aCc", + "BCbb", + 6 + ], + [ + "aCc", + "CCABBCAa", + 13 + ], + [ + "aCc", + "aAB", + 4 + ], + [ + "aCc", + "bbAcb", + 8 + ], + [ + "aCc", + "bbCcccb", + 10 + ], + [ + "aCc", + "caCAC", + 5 + ], + [ + "aCcA", + "a", + 6 + ], + [ + "aCcA", + "aC", + 4 + ], + [ + "aCcA", + "aaAAaaCBa", + 13 + ], + [ + "aCcA", + "cABb", + 8 + ], + [ + "aCcAAA", + "AbaBACBC", + 13 + ], + [ + "aCcABAc", + "BC", + 11 + ], + [ + "aCcABCB", + "b", + 13 + ], + [ + "aCcACA", + "baCcaaAa", + 7 + ], + [ + "aCcAaAba", + "aCAca", + 8 + ], + [ + "aCcAbB", + "cBCAB", + 7 + ], + [ + "aCcB", + "CCbcBaBBb", + 12 + ], + [ + "aCcBbCAC", + "CACbBb", + 11 + ], + [ + "aCcCC", + "A", + 9 + ], + [ + "aCcCCa", + "CcCabCc", + 8 + ], + [ + "aCcCabC", + "BcACaABCC", + 10 + ], + [ + "aCcCcAaA", + "baaAacBAb", + 13 + ], + [ + "aCcCca", + "cBCbCCAcb", + 11 + ], + [ + "aCcaAABb", + "BCACAAb", + 8 + ], + [ + "aCcaCAA", + "AabCbBBAC", + 12 + ], + [ + "aCcacbabC", + "a", + 16 + ], + [ + "aCcbAb", + "CbbcbaCAB", + 11 + ], + [ + "aCcbB", + "aA", + 8 + ], + [ + "aCcbBbAcC", + "bBBc", + 11 + ], + [ + "aCcbaCbca", + "bcBCCcbC", + 12 + ], + [ + "aCcbb", + "ccAabbABa", + 13 + ], + [ + "aCcbbaccb", + "AaCaCaCC", + 12 + ], + [ + "aCcbcBBA", + "CaBccABCa", + 11 + ], + [ + "aCcbcb", + "AcaacBCc", + 10 + ], + [ + "aCcc", + "baCACCa", + 8 + ], + [ + "aCccAaBa", + "BAaBcB", + 12 + ], + [ + "aCccAb", + "bBbaAcCC", + 13 + ], + [ + "aCccBB", + "CCa", + 9 + ], + [ + "aCccaaABC", + "CcBac", + 11 + ], + [ + "aCcccAaba", + "ccBbaA", + 11 + ], + [ + "aa", + "AACcaACB", + 13 + ], + [ + "aa", + "AcBCa", + 7 + ], + [ + "aa", + "Bbaba", + 6 + ], + [ + "aa", + "Bbc", + 6 + ], + [ + "aa", + "BcaBA", + 7 + ], + [ + "aa", + "C", + 4 + ], + [ + "aa", + "CBcC", + 8 + ], + [ + "aa", + "CbB", + 6 + ], + [ + "aa", + "CbBC", + 8 + ], + [ + "aa", + "a", + 2 + ], + [ + "aa", + "aABACBBb", + 13 + ], + [ + "aa", + "aBC", + 4 + ], + [ + "aa", + "aBcaaCAC", + 12 + ], + [ + "aa", + "aCbbAaaCa", + 14 + ], + [ + "aa", + "aaAaA", + 6 + ], + [ + "aa", + "aaAbcb", + 8 + ], + [ + "aa", + "aabCb", + 6 + ], + [ + "aa", + "abCBc", + 8 + ], + [ + "aa", + "abCbAb", + 9 + ], + [ + "aa", + "acAAbAAB", + 13 + ], + [ + "aa", + "bAaB", + 5 + ], + [ + "aa", + "bB", + 4 + ], + [ + "aa", + "bBAaBCA", + 11 + ], + [ + "aa", + "bCaaBbCA", + 12 + ], + [ + "aa", + "baCCBCBB", + 14 + ], + [ + "aa", + "bbAabBcCc", + 15 + ], + [ + "aa", + "bbcAC", + 9 + ], + [ + "aa", + "cAaabc", + 8 + ], + [ + "aa", + "cB", + 4 + ], + [ + "aa", + "cBB", + 6 + ], + [ + "aa", + "cBcBAAbA", + 14 + ], + [ + "aa", + "cCAB", + 7 + ], + [ + "aa", + "cCB", + 6 + ], + [ + "aa", + "caccAcB", + 11 + ], + [ + "aa", + "cb", + 4 + ], + [ + "aa", + "cbbcCB", + 12 + ], + [ + "aaA", + "A", + 4 + ], + [ + "aaA", + "ACBACBC", + 11 + ], + [ + "aaA", + "bCCA", + 6 + ], + [ + "aaA", + "bcaaAB", + 6 + ], + [ + "aaAA", + "aab", + 4 + ], + [ + "aaAAaaAaB", + "BAA", + 14 + ], + [ + "aaAAbbAC", + "cCbBbCAab", + 14 + ], + [ + "aaAAcC", + "cabbCa", + 9 + ], + [ + "aaAB", + "cAa", + 6 + ], + [ + "aaAB", + "cCaBCcB", + 10 + ], + [ + "aaABAbAC", + "CCAB", + 12 + ], + [ + "aaABAbb", + "CC", + 14 + ], + [ + "aaABB", + "Ccb", + 9 + ], + [ + "aaABCC", + "acABACB", + 6 + ], + [ + "aaABCb", + "CABbAaa", + 12 + ], + [ + "aaABaaA", + "CaaaBBabc", + 9 + ], + [ + "aaABbbCbc", + "B", + 16 + ], + [ + "aaAC", + "Ac", + 5 + ], + [ + "aaAC", + "bccBBBb", + 14 + ], + [ + "aaACa", + "cbAAaCB", + 9 + ], + [ + "aaAaAcbBC", + "A", + 16 + ], + [ + "aaAaaaAb", + "bcBc", + 16 + ], + [ + "aaAabBCbc", + "B", + 16 + ], + [ + "aaAabCaAa", + "BbbbcA", + 13 + ], + [ + "aaAabbbaC", + "bbbCaAbC", + 14 + ], + [ + "aaAac", + "cBCCc", + 8 + ], + [ + "aaAbaBbBa", + "baaCCa", + 12 + ], + [ + "aaAbcbBa", + "BbBbaaC", + 12 + ], + [ + "aaAc", + "bbCBca", + 10 + ], + [ + "aaAccCbC", + "BBa", + 15 + ], + [ + "aaB", + "bAAa", + 6 + ], + [ + "aaB", + "cccCAcAaC", + 15 + ], + [ + "aaBA", + "ABccb", + 9 + ], + [ + "aaBA", + "aca", + 5 + ], + [ + "aaBABCc", + "Aaa", + 10 + ], + [ + "aaBABaCc", + "acBaac", + 7 + ], + [ + "aaBABbCAc", + "cCb", + 16 + ], + [ + "aaBB", + "BbbBbcAB", + 12 + ], + [ + "aaBB", + "bAaAaAB", + 8 + ], + [ + "aaBB", + "bBabBA", + 7 + ], + [ + "aaBBa", + "caaB", + 6 + ], + [ + "aaBC", + "BacaAB", + 8 + ], + [ + "aaBCAaaaB", + "aaACA", + 10 + ], + [ + "aaBCC", + "BAAaBb", + 9 + ], + [ + "aaBCCa", + "CA", + 9 + ], + [ + "aaBCCbAac", + "AcaaBacc", + 13 + ], + [ + "aaBa", + "BabbcC", + 9 + ], + [ + "aaBaAaCa", + "aBbcAcAb", + 11 + ], + [ + "aaBaC", + "bcCAbac", + 9 + ], + [ + "aaBaCc", + "BCAaCCb", + 9 + ], + [ + "aaBaa", + "AAb", + 7 + ], + [ + "aaBaa", + "ccba", + 7 + ], + [ + "aaBaaAcBA", + "aCcBCAc", + 12 + ], + [ + "aaBabACBC", + "CCCc", + 15 + ], + [ + "aaBabbBA", + "aAbB", + 9 + ], + [ + "aaBacaB", + "BCABCCCbc", + 13 + ], + [ + "aaBbAaBA", + "BAc", + 12 + ], + [ + "aaBbb", + "aA", + 7 + ], + [ + "aaBbcA", + "CBcb", + 8 + ], + [ + "aaBbcbb", + "C", + 13 + ], + [ + "aaBcBaBa", + "aaBaaaB", + 6 + ], + [ + "aaBccACb", + "bCCBccC", + 10 + ], + [ + "aaC", + "ABcAca", + 9 + ], + [ + "aaC", + "BAbaCaa", + 9 + ], + [ + "aaC", + "CaCbcCc", + 10 + ], + [ + "aaC", + "Cc", + 5 + ], + [ + "aaC", + "aCa", + 4 + ], + [ + "aaC", + "caBBCb", + 8 + ], + [ + "aaCA", + "B", + 8 + ], + [ + "aaCAA", + "BcbBC", + 10 + ], + [ + "aaCABbb", + "CCcbBAb", + 9 + ], + [ + "aaCACa", + "Bb", + 12 + ], + [ + "aaCAcbc", + "AaaAAa", + 9 + ], + [ + "aaCAccaAB", + "CcCABcA", + 10 + ], + [ + "aaCC", + "B", + 8 + ], + [ + "aaCCC", + "ABAcC", + 6 + ], + [ + "aaCCCc", + "cCAaaAbAb", + 14 + ], + [ + "aaCCa", + "CAA", + 7 + ], + [ + "aaCCbaCaB", + "cCCcCAccC", + 13 + ], + [ + "aaCCcbCA", + "acAcb", + 9 + ], + [ + "aaCa", + "aCBca", + 5 + ], + [ + "aaCa", + "cAAca", + 5 + ], + [ + "aaCaABa", + "ba", + 11 + ], + [ + "aaCaABbc", + "B", + 14 + ], + [ + "aaCaBaA", + "aBcAa", + 8 + ], + [ + "aaCaa", + "Ac", + 8 + ], + [ + "aaCacA", + "CbabcA", + 8 + ], + [ + "aaCacAAb", + "CcCAc", + 10 + ], + [ + "aaCacaBC", + "BBaCcA", + 11 + ], + [ + "aaCacaba", + "ACbc", + 11 + ], + [ + "aaCbAAB", + "ABc", + 12 + ], + [ + "aaCbabb", + "Bc", + 13 + ], + [ + "aaCbabc", + "C", + 12 + ], + [ + "aaCbbAAc", + "BaBa", + 12 + ], + [ + "aaCcAcc", + "aC", + 10 + ], + [ + "aaCcaBcB", + "ccAaAbaBC", + 12 + ], + [ + "aaCcaC", + "AAABCccC", + 8 + ], + [ + "aaCccbAaa", + "B", + 17 + ], + [ + "aaa", + "ABAbCbC", + 12 + ], + [ + "aaa", + "abABCcbA", + 12 + ], + [ + "aaa", + "abaC", + 4 + ], + [ + "aaa", + "baa", + 2 + ], + [ + "aaa", + "cCbC", + 8 + ], + [ + "aaaA", + "BaCacbbc", + 12 + ], + [ + "aaaA", + "aaaabAC", + 6 + ], + [ + "aaaAAb", + "abCC", + 10 + ], + [ + "aaaAAcb", + "cbABcb", + 8 + ], + [ + "aaaABb", + "BBCCbBaba", + 14 + ], + [ + "aaaACcA", + "aaa", + 8 + ], + [ + "aaaAac", + "CCAaC", + 7 + ], + [ + "aaaAb", + "ACc", + 9 + ], + [ + "aaaB", + "b", + 7 + ], + [ + "aaaBBB", + "CcACCaCB", + 13 + ], + [ + "aaaBCAbBc", + "baCaab", + 12 + ], + [ + "aaaBaBCAb", + "BaBccAb", + 9 + ], + [ + "aaaBbAC", + "baBCAc", + 7 + ], + [ + "aaaBbBA", + "a", + 12 + ], + [ + "aaaC", + "aca", + 4 + ], + [ + "aaaCAAcAA", + "cCacb", + 13 + ], + [ + "aaaCBacCc", + "aA", + 15 + ], + [ + "aaaCaBcCC", + "ACAbBb", + 13 + ], + [ + "aaaCaaC", + "C", + 12 + ], + [ + "aaaCaaCb", + "bC", + 14 + ], + [ + "aaaCb", + "bcBbaB", + 11 + ], + [ + "aaaCbC", + "AabAc", + 8 + ], + [ + "aaaCcB", + "A", + 11 + ], + [ + "aaaa", + "CacBC", + 8 + ], + [ + "aaaaB", + "aCBcbC", + 9 + ], + [ + "aaaaBBCc", + "aCcCcaab", + 14 + ], + [ + "aaaaBCc", + "bcbaB", + 10 + ], + [ + "aaaaC", + "CBb", + 10 + ], + [ + "aaabCBaAB", + "cbBccA", + 14 + ], + [ + "aaac", + "BAaB", + 5 + ], + [ + "aaacCCB", + "aaAaacA", + 8 + ], + [ + "aab", + "CcCcaACB", + 12 + ], + [ + "aab", + "ab", + 2 + ], + [ + "aab", + "b", + 4 + ], + [ + "aab", + "bBb", + 4 + ], + [ + "aab", + "ccbCc", + 8 + ], + [ + "aabAA", + "CBCcBcac", + 14 + ], + [ + "aabACB", + "AACA", + 7 + ], + [ + "aabACB", + "Ca", + 10 + ], + [ + "aabAacba", + "bCbcBC", + 11 + ], + [ + "aabAbBc", + "AbCaCcCB", + 13 + ], + [ + "aabBAA", + "CbaACAbAA", + 10 + ], + [ + "aabBBcB", + "CbACCCc", + 13 + ], + [ + "aabCAAc", + "CBaA", + 10 + ], + [ + "aabCAcB", + "BBCA", + 9 + ], + [ + "aabaCc", + "Acab", + 9 + ], + [ + "aabb", + "a", + 6 + ], + [ + "aabbA", + "bA", + 6 + ], + [ + "aabbCAA", + "AaAAAbbC", + 11 + ], + [ + "aabbacA", + "AbC", + 10 + ], + [ + "aabbcABba", + "AC", + 16 + ], + [ + "aabc", + "A", + 7 + ], + [ + "aabc", + "Baab", + 4 + ], + [ + "aabcA", + "cabBcCc", + 8 + ], + [ + "aabcBcB", + "Ab", + 11 + ], + [ + "aabcaAA", + "abccacA", + 6 + ], + [ + "aabcbBc", + "BaCaaaA", + 12 + ], + [ + "aabcbaaac", + "BbCbccCc", + 11 + ], + [ + "aac", + "BCC", + 5 + ], + [ + "aac", + "BbCaCBbBc", + 14 + ], + [ + "aac", + "C", + 5 + ], + [ + "aac", + "a", + 4 + ], + [ + "aacA", + "CABCabaa", + 12 + ], + [ + "aacAaCCA", + "CBCbB", + 13 + ], + [ + "aacAaCCAb", + "BBCAB", + 13 + ], + [ + "aacAcb", + "baAacaCAB", + 9 + ], + [ + "aacB", + "ABcCcBAca", + 13 + ], + [ + "aacB", + "CACAABc", + 10 + ], + [ + "aacB", + "c", + 6 + ], + [ + "aacBAabc", + "caCBa", + 9 + ], + [ + "aacBc", + "aBCaCbAc", + 8 + ], + [ + "aacC", + "Ba", + 6 + ], + [ + "aacC", + "Bc", + 6 + ], + [ + "aacC", + "CAbBAbCaA", + 14 + ], + [ + "aacCCb", + "ccBAc", + 10 + ], + [ + "aacCc", + "CaB", + 8 + ], + [ + "aacaA", + "Bbaa", + 7 + ], + [ + "aacaa", + "cCB", + 8 + ], + [ + "aacaaCbBc", + "BCab", + 13 + ], + [ + "aacabaBA", + "cbbA", + 9 + ], + [ + "aacac", + "ABBCabcc", + 10 + ], + [ + "aacacAaB", + "aAbbA", + 11 + ], + [ + "aacb", + "BCcAb", + 6 + ], + [ + "aacbAAC", + "BbabBAC", + 8 + ], + [ + "aacbAcA", + "acbccC", + 6 + ], + [ + "aacbCABAC", + "AAbaCAbbA", + 11 + ], + [ + "aacbb", + "BBAbAC", + 10 + ], + [ + "aacc", + "acACBAa", + 10 + ], + [ + "aaccAaABA", + "BAbBacAC", + 14 + ], + [ + "aacccAccB", + "BBCAb", + 14 + ], + [ + "ab", + "ABca", + 6 + ], + [ + "ab", + "ACA", + 5 + ], + [ + "ab", + "AaB", + 3 + ], + [ + "ab", + "B", + 3 + ], + [ + "ab", + "BAabAa", + 8 + ], + [ + "ab", + "BAacbb", + 8 + ], + [ + "ab", + "Ba", + 4 + ], + [ + "ab", + "BbaBBa", + 9 + ], + [ + "ab", + "CACABaC", + 12 + ], + [ + "ab", + "CCbaA", + 8 + ], + [ + "ab", + "CbBACbc", + 11 + ], + [ + "ab", + "CbcbcbB", + 12 + ], + [ + "ab", + "CcB", + 5 + ], + [ + "ab", + "CcacBC", + 9 + ], + [ + "ab", + "aBBAbbaB", + 12 + ], + [ + "ab", + "aBCbBCACa", + 14 + ], + [ + "ab", + "abAbbc", + 8 + ], + [ + "ab", + "abB", + 2 + ], + [ + "ab", + "bAbCcBAaA", + 15 + ], + [ + "ab", + "baBcBa", + 9 + ], + [ + "ab", + "bb", + 2 + ], + [ + "ab", + "c", + 4 + ], + [ + "ab", + "cAAabacc", + 12 + ], + [ + "ab", + "cABcCCb", + 11 + ], + [ + "ab", + "cCbbbCa", + 12 + ], + [ + "ab", + "cbcb", + 6 + ], + [ + "ab", + "ccb", + 4 + ], + [ + "ab", + "cccaaCAA", + 14 + ], + [ + "abA", + "AaacB", + 8 + ], + [ + "abA", + "BAB", + 5 + ], + [ + "abA", + "abca", + 3 + ], + [ + "abA", + "bAAcC", + 8 + ], + [ + "abA", + "bBbaa", + 7 + ], + [ + "abA", + "bbbAcabb", + 12 + ], + [ + "abA", + "cAbCCcbb", + 13 + ], + [ + "abA", + "cBaaC", + 8 + ], + [ + "abAAB", + "BAbACC", + 7 + ], + [ + "abAAcaCa", + "c", + 14 + ], + [ + "abAB", + "AaCBBbb", + 10 + ], + [ + "abABAA", + "aBABbaabA", + 8 + ], + [ + "abABcAaC", + "aCbAcb", + 10 + ], + [ + "abABcb", + "b", + 10 + ], + [ + "abAC", + "BAC", + 3 + ], + [ + "abACAC", + "CBCaaCcA", + 12 + ], + [ + "abACC", + "BbCbBb", + 10 + ], + [ + "abACCBBa", + "abb", + 11 + ], + [ + "abACCaABb", + "aAcbb", + 10 + ], + [ + "abACb", + "Ca", + 8 + ], + [ + "abACbBAaA", + "cAAcCaCaB", + 13 + ], + [ + "abACccA", + "bBaCBC", + 9 + ], + [ + "abAaAaCCC", + "cACCbAbCC", + 13 + ], + [ + "abAaBAAC", + "ABca", + 11 + ], + [ + "abAacCCaa", + "acbCAC", + 11 + ], + [ + "abAbAcCc", + "b", + 14 + ], + [ + "abAbbBC", + "CAbbBbBb", + 8 + ], + [ + "abAc", + "bC", + 5 + ], + [ + "abAcBBbBA", + "CabccbcaA", + 11 + ], + [ + "abAccAbba", + "caCACCC", + 14 + ], + [ + "abAccBA", + "ACAbbABaa", + 12 + ], + [ + "abAccCbBa", + "cbccBbBac", + 8 + ], + [ + "abB", + "BAAA", + 7 + ], + [ + "abB", + "BACbb", + 6 + ], + [ + "abB", + "BcaBabA", + 10 + ], + [ + "abB", + "a", + 4 + ], + [ + "abB", + "cbBaACaAB", + 14 + ], + [ + "abBA", + "AACBCAbA", + 11 + ], + [ + "abBAA", + "bA", + 6 + ], + [ + "abBAAcaA", + "AACCC", + 11 + ], + [ + "abBAAcbb", + "bCCcbb", + 8 + ], + [ + "abBAB", + "aa", + 7 + ], + [ + "abBABBA", + "BBCBccbaA", + 12 + ], + [ + "abBAaBa", + "bbaBCcbc", + 11 + ], + [ + "abBAaCacb", + "bbaca", + 10 + ], + [ + "abBAaCcc", + "ccCACB", + 12 + ], + [ + "abBAc", + "bB", + 6 + ], + [ + "abBAc", + "bBB", + 6 + ], + [ + "abBB", + "BbaBbCbb", + 10 + ], + [ + "abBBCc", + "b", + 10 + ], + [ + "abBBaAcBc", + "bbCaB", + 11 + ], + [ + "abBBaBbCc", + "Cac", + 14 + ], + [ + "abBBac", + "BAc", + 7 + ], + [ + "abBBb", + "A", + 9 + ], + [ + "abBBb", + "ACAAc", + 9 + ], + [ + "abBBbB", + "b", + 10 + ], + [ + "abBCACBBc", + "B", + 16 + ], + [ + "abBCBAB", + "cCA", + 10 + ], + [ + "abBCCb", + "AbaCcCcA", + 9 + ], + [ + "abBCCcc", + "BcBCCbCbb", + 11 + ], + [ + "abBCac", + "cCcbACcC", + 11 + ], + [ + "abBCcCbA", + "bC", + 12 + ], + [ + "abBa", + "cbabba", + 5 + ], + [ + "abBaA", + "CA", + 8 + ], + [ + "abBaAAc", + "BB", + 11 + ], + [ + "abBaBcabA", + "BBBAabAba", + 10 + ], + [ + "abBaCbB", + "CaCaacbC", + 9 + ], + [ + "abBabAb", + "Aacb", + 9 + ], + [ + "abBacbc", + "cAccCaaa", + 15 + ], + [ + "abBacca", + "bAACac", + 10 + ], + [ + "abBb", + "ABCaACb", + 10 + ], + [ + "abBb", + "BAABc", + 7 + ], + [ + "abBb", + "c", + 8 + ], + [ + "abBb", + "cAB", + 6 + ], + [ + "abBbBB", + "Aaccb", + 10 + ], + [ + "abBbC", + "aaccbac", + 9 + ], + [ + "abBbCBBa", + "C", + 14 + ], + [ + "abBbb", + "BBA", + 7 + ], + [ + "abBbba", + "CBbAAb", + 9 + ], + [ + "abBc", + "AABBCcBcc", + 12 + ], + [ + "abBc", + "bcbbCABca", + 12 + ], + [ + "abBcB", + "CbCaCca", + 10 + ], + [ + "abBcBBCA", + "BCCCacAac", + 15 + ], + [ + "abBcaBa", + "bcBCCc", + 11 + ], + [ + "abC", + "ACAbb", + 7 + ], + [ + "abC", + "Cc", + 5 + ], + [ + "abC", + "aAabBb", + 8 + ], + [ + "abC", + "b", + 4 + ], + [ + "abC", + "bccBAC", + 9 + ], + [ + "abC", + "bccabCBc", + 10 + ], + [ + "abC", + "cBA", + 5 + ], + [ + "abC", + "cCB", + 6 + ], + [ + "abCA", + "Acb", + 6 + ], + [ + "abCA", + "cc", + 7 + ], + [ + "abCAA", + "BAcbCCBc", + 11 + ], + [ + "abCAAcbCB", + "acCabB", + 9 + ], + [ + "abCAaA", + "AcbaAB", + 8 + ], + [ + "abCB", + "BABBbAABA", + 13 + ], + [ + "abCBB", + "Bb", + 7 + ], + [ + "abCBCB", + "baCaaa", + 10 + ], + [ + "abCC", + "CA", + 6 + ], + [ + "abCC", + "CCcCAcaA", + 13 + ], + [ + "abCCAacb", + "babaA", + 12 + ], + [ + "abCCBB", + "baB", + 8 + ], + [ + "abCCBBC", + "aAc", + 11 + ], + [ + "abCCCBaAC", + "CCBbCbBA", + 13 + ], + [ + "abCCaAca", + "bBCBCaC", + 10 + ], + [ + "abCCbBBaA", + "Ab", + 15 + ], + [ + "abCCc", + "BcbBabBc", + 12 + ], + [ + "abCCcAcBB", + "BaAAAaAB", + 13 + ], + [ + "abCa", + "ABA", + 5 + ], + [ + "abCaBC", + "bCCaCaA", + 10 + ], + [ + "abCaC", + "acc", + 6 + ], + [ + "abCaCAbB", + "aCaba", + 8 + ], + [ + "abCabA", + "ACba", + 6 + ], + [ + "abCabbccb", + "CcAcA", + 14 + ], + [ + "abCacaaC", + "aC", + 12 + ], + [ + "abCb", + "cBCBaA", + 8 + ], + [ + "abCbBCcAa", + "a", + 16 + ], + [ + "abCbaCC", + "CAabaabBB", + 14 + ], + [ + "abCbbba", + "CcbBCBAA", + 12 + ], + [ + "abCc", + "Ca", + 6 + ], + [ + "abCcAbbC", + "B", + 15 + ], + [ + "abCcCCC", + "BbAaca", + 11 + ], + [ + "abCcCc", + "ACacA", + 8 + ], + [ + "abCcaA", + "aca", + 6 + ], + [ + "abCcaABB", + "AbcBb", + 8 + ], + [ + "aba", + "CBb", + 5 + ], + [ + "aba", + "CBbbaAb", + 10 + ], + [ + "aba", + "aCccA", + 7 + ], + [ + "aba", + "acaB", + 4 + ], + [ + "aba", + "bcCCa", + 8 + ], + [ + "aba", + "cBB", + 5 + ], + [ + "abaAAA", + "cAbB", + 10 + ], + [ + "abaACCcC", + "abacCBA", + 7 + ], + [ + "abaAaccC", + "CCaacc", + 8 + ], + [ + "abaAbb", + "a", + 10 + ], + [ + "abaBCABc", + "aCcccB", + 11 + ], + [ + "abaBaCca", + "aAcAbaB", + 12 + ], + [ + "abaC", + "Bba", + 4 + ], + [ + "abaCACccC", + "BBBBB", + 17 + ], + [ + "abaCBABaB", + "abacbacc", + 9 + ], + [ + "abaCCbcA", + "AcBBc", + 11 + ], + [ + "abaCbB", + "cC", + 10 + ], + [ + "abaCbaCB", + "AAcC", + 11 + ], + [ + "abaCbaa", + "aCCaCCA", + 9 + ], + [ + "abaaACcB", + "cBBCBBAbC", + 16 + ], + [ + "abab", + "CcaCC", + 8 + ], + [ + "abab", + "aCAAaaaB", + 11 + ], + [ + "abab", + "acBbA", + 6 + ], + [ + "ababA", + "CBBC", + 8 + ], + [ + "ababACcC", + "BC", + 13 + ], + [ + "ababCBBbB", + "CbC", + 14 + ], + [ + "ababa", + "CABCcCcb", + 14 + ], + [ + "ababcCb", + "aCAbCc", + 7 + ], + [ + "abacA", + "ABb", + 8 + ], + [ + "abacABc", + "babCCAbb", + 8 + ], + [ + "abacAc", + "BacbCaaB", + 11 + ], + [ + "abacBBa", + "CbCAa", + 9 + ], + [ + "abacBbaCC", + "a", + 16 + ], + [ + "abacCb", + "b", + 10 + ], + [ + "abaca", + "cAB", + 9 + ], + [ + "abacaCbBc", + "bACcACB", + 10 + ], + [ + "abaccABb", + "cBcCc", + 12 + ], + [ + "abaccaAcA", + "B", + 17 + ], + [ + "abacccc", + "Cba", + 10 + ], + [ + "abb", + "B", + 5 + ], + [ + "abb", + "CbBBAc", + 9 + ], + [ + "abb", + "aC", + 4 + ], + [ + "abb", + "bbbcaca", + 10 + ], + [ + "abbAAABBb", + "CbCcB", + 14 + ], + [ + "abbAcB", + "BbaaBc", + 8 + ], + [ + "abbBBCcB", + "aaa", + 14 + ], + [ + "abbBbAbcc", + "c", + 16 + ], + [ + "abbBbbbcC", + "aBbBaB", + 10 + ], + [ + "abbCBA", + "aA", + 8 + ], + [ + "abbCBA", + "bb", + 8 + ], + [ + "abbCBabac", + "CBAB", + 12 + ], + [ + "abbCaBB", + "Ab", + 11 + ], + [ + "abbCaBC", + "aBcc", + 9 + ], + [ + "abbCbbBB", + "cbbaaca", + 12 + ], + [ + "abbCc", + "bC", + 6 + ], + [ + "abbaA", + "BabaAAaBb", + 11 + ], + [ + "abbaBaaBc", + "CAcBbc", + 13 + ], + [ + "abbaBbc", + "aABbAcc", + 8 + ], + [ + "abbaCcba", + "Cba", + 10 + ], + [ + "abbbA", + "ACAcc", + 9 + ], + [ + "abbbBAbAA", + "aCACcAbA", + 10 + ], + [ + "abbbCCCaC", + "acBCBABcC", + 13 + ], + [ + "abbbb", + "cCcbBcb", + 9 + ], + [ + "abbbc", + "C", + 9 + ], + [ + "abbbca", + "BBAcBbAB", + 12 + ], + [ + "abbcABB", + "ac", + 10 + ], + [ + "abbcB", + "ABbcCB", + 4 + ], + [ + "abbcBac", + "bACca", + 9 + ], + [ + "abbccAa", + "AcC", + 10 + ], + [ + "abbccb", + "cbCb", + 7 + ], + [ + "abc", + "AbC", + 2 + ], + [ + "abc", + "BAAb", + 7 + ], + [ + "abc", + "C", + 5 + ], + [ + "abc", + "aB", + 3 + ], + [ + "abcAA", + "CAAabC", + 11 + ], + [ + "abcAaaccb", + "cAcAAcbcA", + 11 + ], + [ + "abcAbB", + "AbcCacc", + 8 + ], + [ + "abcAcaB", + "acBcBb", + 7 + ], + [ + "abcAcbbb", + "CaABc", + 13 + ], + [ + "abcB", + "AaCcAbCa", + 11 + ], + [ + "abcB", + "bbab", + 5 + ], + [ + "abcBaBb", + "cBBa", + 8 + ], + [ + "abcBacc", + "ACBa", + 8 + ], + [ + "abcBb", + "BBbcccBB", + 9 + ], + [ + "abcBbBAb", + "cB", + 12 + ], + [ + "abcC", + "BCc", + 5 + ], + [ + "abcCAB", + "CbCcC", + 8 + ], + [ + "abcCBAc", + "ACCBaA", + 7 + ], + [ + "abcCaBcCB", + "AAba", + 15 + ], + [ + "abcCbBCA", + "Ba", + 13 + ], + [ + "abca", + "cbaccAA", + 9 + ], + [ + "abcaCB", + "CCaaAB", + 8 + ], + [ + "abcb", + "a", + 6 + ], + [ + "abcbbC", + "BBc", + 9 + ], + [ + "abcbbbcb", + "b", + 14 + ], + [ + "abccC", + "bbcBab", + 8 + ], + [ + "abccCBabC", + "AbABaaabc", + 10 + ], + [ + "abccCaB", + "Bbaa", + 10 + ], + [ + "abccCcAa", + "BCbb", + 13 + ], + [ + "abccaB", + "aCABaba", + 9 + ], + [ + "abccaC", + "ABbCB", + 9 + ], + [ + "abccaCcBB", + "AAB", + 14 + ], + [ + "abccbCC", + "BAc", + 11 + ], + [ + "ac", + "A", + 3 + ], + [ + "ac", + "AAaCcbBa", + 12 + ], + [ + "ac", + "AAcCbbCca", + 15 + ], + [ + "ac", + "ACAcCa", + 9 + ], + [ + "ac", + "ACCBbAcCc", + 15 + ], + [ + "ac", + "B", + 4 + ], + [ + "ac", + "BAab", + 6 + ], + [ + "ac", + "BCCBbccb", + 14 + ], + [ + "ac", + "BCc", + 4 + ], + [ + "ac", + "BaBbbAA", + 12 + ], + [ + "ac", + "BcCACbB", + 12 + ], + [ + "ac", + "CBA", + 6 + ], + [ + "ac", + "CccBcaB", + 12 + ], + [ + "ac", + "aB", + 2 + ], + [ + "ac", + "aBBCacBbC", + 14 + ], + [ + "ac", + "aC", + 1 + ], + [ + "ac", + "aCcCC", + 6 + ], + [ + "ac", + "aaCaCaca", + 12 + ], + [ + "ac", + "ab", + 2 + ], + [ + "ac", + "acacCAbBA", + 14 + ], + [ + "ac", + "bACaaCCCC", + 15 + ], + [ + "ac", + "bAbaCCcBC", + 14 + ], + [ + "ac", + "bCCaAaa", + 12 + ], + [ + "ac", + "cBAcc", + 7 + ], + [ + "acA", + "AaCCAaabc", + 13 + ], + [ + "acA", + "aABBBACc", + 12 + ], + [ + "acA", + "ac", + 2 + ], + [ + "acA", + "cBcBb", + 8 + ], + [ + "acAA", + "bc", + 6 + ], + [ + "acAAABBa", + "cbcC", + 13 + ], + [ + "acAACBA", + "BcbaCbbA", + 8 + ], + [ + "acAB", + "ccbAAAa", + 10 + ], + [ + "acABCCA", + "BCcABBAa", + 9 + ], + [ + "acABc", + "BBcABbCba", + 11 + ], + [ + "acAC", + "A", + 6 + ], + [ + "acACCB", + "AAcBCba", + 9 + ], + [ + "acAaaAcba", + "BabCcbCbb", + 15 + ], + [ + "acAaaaBc", + "BacCBc", + 10 + ], + [ + "acAabACa", + "acaCB", + 8 + ], + [ + "acAabBbA", + "cabCb", + 8 + ], + [ + "acAacCc", + "BBCC", + 11 + ], + [ + "acAb", + "cc", + 6 + ], + [ + "acAbabcBa", + "ABABcaB", + 11 + ], + [ + "acAc", + "ABa", + 6 + ], + [ + "acAc", + "CcBCaa", + 9 + ], + [ + "acAc", + "aBbCaB", + 8 + ], + [ + "acAcBCCa", + "BaB", + 13 + ], + [ + "acAcCAc", + "cAbab", + 9 + ], + [ + "acAcaC", + "B", + 12 + ], + [ + "acAcabB", + "baaacbB", + 7 + ], + [ + "acAcbcAC", + "ccaCbCcc", + 8 + ], + [ + "acB", + "ABcAcBAcb", + 13 + ], + [ + "acB", + "acb", + 1 + ], + [ + "acB", + "bCccA", + 8 + ], + [ + "acB", + "cbabb", + 7 + ], + [ + "acBA", + "BcAaBCBAA", + 11 + ], + [ + "acBAcc", + "AAabb", + 10 + ], + [ + "acBB", + "AaaAbB", + 7 + ], + [ + "acBB", + "cA", + 6 + ], + [ + "acBBAb", + "bCcAbBCAC", + 11 + ], + [ + "acBBAbacB", + "aaCBB", + 12 + ], + [ + "acBBBbAcb", + "BAa", + 14 + ], + [ + "acBBCC", + "ccAbcBbCb", + 10 + ], + [ + "acBBCc", + "bcCaAbAa", + 13 + ], + [ + "acBBbBa", + "Cba", + 9 + ], + [ + "acBBcCC", + "ABbb", + 10 + ], + [ + "acBCBcabA", + "caCbca", + 9 + ], + [ + "acBCCbab", + "ccA", + 12 + ], + [ + "acBCa", + "BabbAcb", + 10 + ], + [ + "acBa", + "AC", + 6 + ], + [ + "acBaA", + "ABBCC", + 7 + ], + [ + "acBaAacc", + "bbab", + 13 + ], + [ + "acBaBCab", + "ac", + 12 + ], + [ + "acBaBaC", + "bbccbac", + 10 + ], + [ + "acBacCbAc", + "bBBACbaAA", + 11 + ], + [ + "acBb", + "CA", + 7 + ], + [ + "acBb", + "bCBAAB", + 8 + ], + [ + "acBbAc", + "aaaBCA", + 8 + ], + [ + "acBbCca", + "acA", + 9 + ], + [ + "acBcCcaB", + "CC", + 13 + ], + [ + "acBcabcAC", + "Aac", + 13 + ], + [ + "acC", + "AABcbaC", + 9 + ], + [ + "acC", + "AcBAaC", + 7 + ], + [ + "acC", + "CabBabaBC", + 14 + ], + [ + "acC", + "b", + 6 + ], + [ + "acC", + "baBCBCbAC", + 13 + ], + [ + "acC", + "baaCBCBC", + 11 + ], + [ + "acCA", + "C", + 6 + ], + [ + "acCA", + "aabBCaaaC", + 13 + ], + [ + "acCAAaCB", + "ba", + 14 + ], + [ + "acCAB", + "BccCcCbB", + 10 + ], + [ + "acCAa", + "c", + 8 + ], + [ + "acCAabBcc", + "Bb", + 16 + ], + [ + "acCAb", + "abB", + 7 + ], + [ + "acCAcc", + "cccCCacCC", + 10 + ], + [ + "acCB", + "B", + 6 + ], + [ + "acCBAcb", + "acaBcA", + 6 + ], + [ + "acCBBA", + "caccBbabC", + 9 + ], + [ + "acCBBb", + "aCbc", + 7 + ], + [ + "acCBCbaBC", + "bCabBc", + 11 + ], + [ + "acCBaaAc", + "BAAABCA", + 13 + ], + [ + "acCC", + "BAB", + 8 + ], + [ + "acCCABBb", + "Bbcca", + 13 + ], + [ + "acCCCaAb", + "acCCbAcca", + 9 + ], + [ + "acCCab", + "aB", + 9 + ], + [ + "acCCbA", + "CCAbCbBA", + 9 + ], + [ + "acCCbBcc", + "aAAaA", + 14 + ], + [ + "acCCcaC", + "AcbBabcCb", + 13 + ], + [ + "acCCcab", + "ccab", + 6 + ], + [ + "acCa", + "aaAcAbBbB", + 14 + ], + [ + "acCaAA", + "BAbcAcbC", + 13 + ], + [ + "acCaABcbb", + "A", + 16 + ], + [ + "acCaC", + "abBACBCB", + 10 + ], + [ + "acCaCa", + "aBa", + 8 + ], + [ + "acCb", + "aACBa", + 5 + ], + [ + "acCbBBa", + "BbbACCccb", + 15 + ], + [ + "acCbCCCBb", + "B", + 16 + ], + [ + "acCbbBB", + "bcca", + 11 + ], + [ + "acCc", + "A", + 7 + ], + [ + "acCc", + "AABBa", + 9 + ], + [ + "acCcA", + "CBBcaBCCA", + 11 + ], + [ + "acCcAcB", + "b", + 13 + ], + [ + "acCcB", + "BBCCBA", + 7 + ], + [ + "acCcaAA", + "b", + 14 + ], + [ + "acCcacB", + "cbAccBcb", + 10 + ], + [ + "acCcc", + "AC", + 7 + ], + [ + "aca", + "ACAB", + 5 + ], + [ + "aca", + "AaAc", + 6 + ], + [ + "aca", + "cAAbacBCa", + 12 + ], + [ + "aca", + "cbCCabAaB", + 14 + ], + [ + "acaA", + "C", + 7 + ], + [ + "acaA", + "aCbcACABa", + 11 + ], + [ + "acaAAAbc", + "B", + 15 + ], + [ + "acaABAcA", + "Cacca", + 10 + ], + [ + "acaAcb", + "cbc", + 8 + ], + [ + "acaBA", + "baBCbCBBC", + 13 + ], + [ + "acaBcacBc", + "b", + 17 + ], + [ + "acaBccaC", + "C", + 14 + ], + [ + "acaC", + "bccCAccA", + 12 + ], + [ + "acaCAaBB", + "Bc", + 14 + ], + [ + "acaCBBB", + "A", + 13 + ], + [ + "acaCaA", + "BCB", + 10 + ], + [ + "acaCaC", + "c", + 10 + ], + [ + "acaCbC", + "acaabCaa", + 6 + ], + [ + "acaCcaAB", + "ABAaaaba", + 12 + ], + [ + "acaCcbcB", + "CcbACBBc", + 10 + ], + [ + "acaCcbcc", + "C", + 14 + ], + [ + "acaa", + "AabBa", + 6 + ], + [ + "acaaBAA", + "cBBbaAB", + 10 + ], + [ + "acaaCC", + "cAACA", + 6 + ], + [ + "acaaaCCA", + "AaC", + 11 + ], + [ + "acaacAbB", + "bCbb", + 12 + ], + [ + "acaaca", + "cBACccCa", + 11 + ], + [ + "acaacb", + "ccCbBca", + 10 + ], + [ + "acabCb", + "ccaCbA", + 6 + ], + [ + "acabaBCbB", + "cab", + 12 + ], + [ + "acabcA", + "AB", + 10 + ], + [ + "acacA", + "bcBACcaa", + 10 + ], + [ + "acacbA", + "A", + 10 + ], + [ + "acacbABa", + "bCbcBa", + 9 + ], + [ + "acacbBa", + "BAbA", + 10 + ], + [ + "acb", + "AabAbA", + 8 + ], + [ + "acb", + "BCCa", + 7 + ], + [ + "acb", + "cBCB", + 6 + ], + [ + "acbA", + "AcBCbCa", + 8 + ], + [ + "acbA", + "aAaBCAB", + 9 + ], + [ + "acbAA", + "bc", + 8 + ], + [ + "acbACbbA", + "a", + 14 + ], + [ + "acbAbacc", + "caAcB", + 10 + ], + [ + "acbB", + "aBAb", + 5 + ], + [ + "acbBBC", + "caB", + 8 + ], + [ + "acbBaAAb", + "bbBcABBaC", + 13 + ], + [ + "acbBaC", + "CaA", + 9 + ], + [ + "acbBc", + "abB", + 4 + ], + [ + "acbC", + "ABABaBbca", + 13 + ], + [ + "acbC", + "bbBbcaaA", + 13 + ], + [ + "acbCA", + "A", + 8 + ], + [ + "acbCA", + "cBb", + 7 + ], + [ + "acbCBb", + "acAbCCaBc", + 8 + ], + [ + "acbCaaAaB", + "CaCc", + 14 + ], + [ + "acbCabC", + "cBACbcBC", + 10 + ], + [ + "acbaBaA", + "BBcA", + 9 + ], + [ + "acbabAa", + "CaAbcbc", + 10 + ], + [ + "acbabbaB", + "c", + 14 + ], + [ + "acbb", + "AAa", + 7 + ], + [ + "acbb", + "AbCaBCcBA", + 13 + ], + [ + "acbb", + "BbAca", + 9 + ], + [ + "acbb", + "CBaCBcCbA", + 12 + ], + [ + "acbbA", + "AcCAAbc", + 9 + ], + [ + "acbbAbA", + "CCCaccab", + 13 + ], + [ + "acbbcABBB", + "BcCBbb", + 11 + ], + [ + "acbc", + "aBAbB", + 6 + ], + [ + "acbcAa", + "BaCC", + 10 + ], + [ + "acbcBbc", + "B", + 12 + ], + [ + "acbcCAC", + "ACaAab", + 11 + ], + [ + "acbcCab", + "BAb", + 10 + ], + [ + "acbcaacbc", + "CbccCCBcb", + 11 + ], + [ + "acbcbbcc", + "CcAbaCCbb", + 13 + ], + [ + "acbccACA", + "b", + 14 + ], + [ + "acbccBcB", + "CCcc", + 10 + ], + [ + "acbccCB", + "bbbaaCAAB", + 12 + ], + [ + "acc", + "C", + 5 + ], + [ + "acc", + "bAac", + 5 + ], + [ + "accA", + "CBBaA", + 8 + ], + [ + "accAA", + "C", + 9 + ], + [ + "accABbb", + "cBbAAbaC", + 12 + ], + [ + "accAac", + "CCcacb", + 7 + ], + [ + "accAb", + "bcbAbB", + 6 + ], + [ + "accAcbAa", + "B", + 15 + ], + [ + "accB", + "bBbAb", + 9 + ], + [ + "accBC", + "bCCCCab", + 10 + ], + [ + "accBbcCaa", + "aaCcaBACB", + 12 + ], + [ + "accC", + "CCcbBc", + 8 + ], + [ + "accC", + "aa", + 6 + ], + [ + "accCAcACa", + "AABbCCc", + 14 + ], + [ + "accCCaCB", + "aCBba", + 11 + ], + [ + "accCCcA", + "cBbA", + 10 + ], + [ + "accCaB", + "aBaB", + 6 + ], + [ + "accCbbC", + "cBBcaa", + 12 + ], + [ + "acca", + "BBCAcbaba", + 13 + ], + [ + "acca", + "BBcCC", + 7 + ], + [ + "accaACAAc", + "cbbCABA", + 12 + ], + [ + "accaaAcAb", + "ccB", + 13 + ], + [ + "accaaC", + "CbA", + 10 + ], + [ + "accab", + "AAaAcA", + 9 + ], + [ + "accabbcB", + "aa", + 12 + ], + [ + "accac", + "C", + 9 + ], + [ + "accb", + "CBCAcCaBB", + 13 + ], + [ + "accbAA", + "Ba", + 10 + ], + [ + "accbAa", + "Ca", + 9 + ], + [ + "accbBac", + "caC", + 9 + ], + [ + "accbCcBAc", + "cbA", + 12 + ], + [ + "accbaAc", + "ACAaCAAA", + 11 + ], + [ + "accbb", + "CCcC", + 7 + ], + [ + "acccAB", + "cb", + 9 + ], + [ + "acccC", + "baaaaB", + 10 + ], + [ + "acccaAaB", + "C", + 15 + ], + [ + "acccc", + "cAAC", + 7 + ], + [ + "b", + "A", + 2 + ], + [ + "b", + "AAbAaCb", + 12 + ], + [ + "b", + "ABBBC", + 9 + ], + [ + "b", + "ABbCCBC", + 12 + ], + [ + "b", + "ABc", + 5 + ], + [ + "b", + "ABcba", + 8 + ], + [ + "b", + "ACAAC", + 10 + ], + [ + "b", + "ACBbAcabc", + 16 + ], + [ + "b", + "ACBbCBcCC", + 16 + ], + [ + "b", + "ACCaA", + 10 + ], + [ + "b", + "Aa", + 4 + ], + [ + "b", + "AaAbBCA", + 12 + ], + [ + "b", + "Aac", + 6 + ], + [ + "b", + "AacaBc", + 11 + ], + [ + "b", + "AbaC", + 6 + ], + [ + "b", + "Abcba", + 8 + ], + [ + "b", + "Ac", + 4 + ], + [ + "b", + "AcCbB", + 8 + ], + [ + "b", + "AcCbBca", + 12 + ], + [ + "b", + "AcaaCaAa", + 16 + ], + [ + "b", + "B", + 1 + ], + [ + "b", + "BBA", + 5 + ], + [ + "b", + "BBaaabB", + 12 + ], + [ + "b", + "BBbaBcba", + 14 + ], + [ + "b", + "BCBaC", + 9 + ], + [ + "b", + "BCcAABb", + 12 + ], + [ + "b", + "Ba", + 3 + ], + [ + "b", + "BaC", + 5 + ], + [ + "b", + "BaCbBc", + 10 + ], + [ + "b", + "Bac", + 5 + ], + [ + "b", + "BacBAc", + 11 + ], + [ + "b", + "Bb", + 2 + ], + [ + "b", + "BbA", + 4 + ], + [ + "b", + "BbBacbb", + 12 + ], + [ + "b", + "BbacaCc", + 12 + ], + [ + "b", + "BbbcAcAab", + 16 + ], + [ + "b", + "Bc", + 3 + ], + [ + "b", + "BcBA", + 7 + ], + [ + "b", + "BcBCAAaCB", + 17 + ], + [ + "b", + "BcC", + 5 + ], + [ + "b", + "BcCa", + 7 + ], + [ + "b", + "C", + 2 + ], + [ + "b", + "CAB", + 5 + ], + [ + "b", + "CACCBca", + 13 + ], + [ + "b", + "CBABaBAB", + 15 + ], + [ + "b", + "CBCCa", + 9 + ], + [ + "b", + "CBCCcC", + 11 + ], + [ + "b", + "CBCcaBBAB", + 17 + ], + [ + "b", + "CBaBaaCbB", + 16 + ], + [ + "b", + "CBaabA", + 10 + ], + [ + "b", + "CCBABBcC", + 15 + ], + [ + "b", + "CCC", + 6 + ], + [ + "b", + "CCbCA", + 8 + ], + [ + "b", + "Ca", + 4 + ], + [ + "b", + "CaCBcA", + 11 + ], + [ + "b", + "Cabacc", + 10 + ], + [ + "b", + "CabccCBCB", + 16 + ], + [ + "b", + "CacAbAAac", + 16 + ], + [ + "b", + "CbA", + 4 + ], + [ + "b", + "CbcBbA", + 10 + ], + [ + "b", + "Cc", + 4 + ], + [ + "b", + "CcAABbA", + 12 + ], + [ + "b", + "CcabBB", + 10 + ], + [ + "b", + "CcacCcAcC", + 18 + ], + [ + "b", + "CcbCACB", + 12 + ], + [ + "b", + "Ccbc", + 6 + ], + [ + "b", + "a", + 2 + ], + [ + "b", + "aA", + 4 + ], + [ + "b", + "aABBCcC", + 13 + ], + [ + "b", + "aABccbaCc", + 16 + ], + [ + "b", + "aACCCCba", + 14 + ], + [ + "b", + "aACCa", + 10 + ], + [ + "b", + "aAaBA", + 9 + ], + [ + "b", + "aAacBab", + 12 + ], + [ + "b", + "aB", + 3 + ], + [ + "b", + "aBCAac", + 11 + ], + [ + "b", + "aBCBC", + 9 + ], + [ + "b", + "aBCbacab", + 14 + ], + [ + "b", + "aBaCa", + 9 + ], + [ + "b", + "aBc", + 5 + ], + [ + "b", + "aC", + 4 + ], + [ + "b", + "aCBA", + 7 + ], + [ + "b", + "aCCa", + 8 + ], + [ + "b", + "aa", + 4 + ], + [ + "b", + "aabCCBca", + 14 + ], + [ + "b", + "aabbAb", + 10 + ], + [ + "b", + "aabbcC", + 10 + ], + [ + "b", + "ab", + 2 + ], + [ + "b", + "abB", + 4 + ], + [ + "b", + "abBBcb", + 10 + ], + [ + "b", + "abCCBCA", + 12 + ], + [ + "b", + "abcACcaa", + 14 + ], + [ + "b", + "abcBccCa", + 14 + ], + [ + "b", + "abca", + 6 + ], + [ + "b", + "ac", + 4 + ], + [ + "b", + "acACCaAca", + 18 + ], + [ + "b", + "acC", + 6 + ], + [ + "b", + "aca", + 6 + ], + [ + "b", + "acaabCC", + 12 + ], + [ + "b", + "b", + 0 + ], + [ + "b", + "bACAbB", + 10 + ], + [ + "b", + "bBAccb", + 10 + ], + [ + "b", + "bBBC", + 6 + ], + [ + "b", + "bBbaAA", + 10 + ], + [ + "b", + "bC", + 2 + ], + [ + "b", + "bCA", + 4 + ], + [ + "b", + "bCBCAbaCA", + 16 + ], + [ + "b", + "bCCbA", + 8 + ], + [ + "b", + "bCaAC", + 8 + ], + [ + "b", + "bCaCAB", + 10 + ], + [ + "b", + "bCabBB", + 10 + ], + [ + "b", + "bCbBbcA", + 12 + ], + [ + "b", + "bCcbAb", + 10 + ], + [ + "b", + "baBACBaaB", + 16 + ], + [ + "b", + "baCCbBC", + 12 + ], + [ + "b", + "baabBABb", + 14 + ], + [ + "b", + "baabbaCBB", + 16 + ], + [ + "b", + "baaccc", + 10 + ], + [ + "b", + "babBAcb", + 12 + ], + [ + "b", + "bb", + 2 + ], + [ + "b", + "bcBACbaBb", + 16 + ], + [ + "b", + "bcCa", + 6 + ], + [ + "b", + "bcCcAcbc", + 14 + ], + [ + "b", + "c", + 2 + ], + [ + "b", + "cABCaB", + 11 + ], + [ + "b", + "cAC", + 6 + ], + [ + "b", + "cAbBbBcc", + 14 + ], + [ + "b", + "cAbaBABBc", + 16 + ], + [ + "b", + "cAbaCBAa", + 14 + ], + [ + "b", + "cBAAAcaA", + 15 + ], + [ + "b", + "cBBcbAabb", + 16 + ], + [ + "b", + "cBCCAcb", + 12 + ], + [ + "b", + "cBCCa", + 9 + ], + [ + "b", + "cBCaCAc", + 13 + ], + [ + "b", + "cBbaBbcB", + 14 + ], + [ + "b", + "cBbbBaAa", + 14 + ], + [ + "b", + "cCAACba", + 12 + ], + [ + "b", + "cCaccAaCb", + 16 + ], + [ + "b", + "cCcbA", + 8 + ], + [ + "b", + "caA", + 6 + ], + [ + "b", + "caAb", + 6 + ], + [ + "b", + "caAccaCbb", + 16 + ], + [ + "b", + "caB", + 5 + ], + [ + "b", + "cabBbcA", + 12 + ], + [ + "b", + "cacbbBAb", + 14 + ], + [ + "b", + "cb", + 2 + ], + [ + "b", + "cbAa", + 6 + ], + [ + "b", + "cbAaCa", + 10 + ], + [ + "b", + "cbcBAcCbA", + 16 + ], + [ + "b", + "ccCaacc", + 14 + ], + [ + "b", + "ccCbaaaa", + 14 + ], + [ + "b", + "ccaC", + 8 + ], + [ + "b", + "ccbbcb", + 10 + ], + [ + "bA", + "AAAcACAbA", + 14 + ], + [ + "bA", + "AAbB", + 6 + ], + [ + "bA", + "ABaC", + 6 + ], + [ + "bA", + "ACBbbA", + 8 + ], + [ + "bA", + "ACBbccB", + 12 + ], + [ + "bA", + "ACbbBB", + 10 + ], + [ + "bA", + "Accc", + 8 + ], + [ + "bA", + "BAcCabc", + 11 + ], + [ + "bA", + "BCCcccB", + 13 + ], + [ + "bA", + "BabcCBCaa", + 15 + ], + [ + "bA", + "BbCaCBca", + 13 + ], + [ + "bA", + "BbbcbCCB", + 14 + ], + [ + "bA", + "Bbca", + 5 + ], + [ + "bA", + "C", + 4 + ], + [ + "bA", + "CAbABbBC", + 12 + ], + [ + "bA", + "CB", + 4 + ], + [ + "bA", + "CBCBa", + 8 + ], + [ + "bA", + "CbAaAaB", + 10 + ], + [ + "bA", + "CbcAAc", + 8 + ], + [ + "bA", + "CcAAcbcBC", + 16 + ], + [ + "bA", + "aAc", + 4 + ], + [ + "bA", + "aBCCcAcb", + 13 + ], + [ + "bA", + "aCb", + 6 + ], + [ + "bA", + "aCcbbc", + 10 + ], + [ + "bA", + "bAbcaAA", + 10 + ], + [ + "bA", + "bAc", + 2 + ], + [ + "bA", + "ba", + 1 + ], + [ + "bA", + "bb", + 2 + ], + [ + "bA", + "cAcCABaAb", + 15 + ], + [ + "bA", + "cCAABbBb", + 14 + ], + [ + "bA", + "cCC", + 6 + ], + [ + "bA", + "cabc", + 6 + ], + [ + "bA", + "ccCbcC", + 10 + ], + [ + "bAA", + "AabBB", + 8 + ], + [ + "bAA", + "BBAAaBCbC", + 13 + ], + [ + "bAA", + "C", + 6 + ], + [ + "bAA", + "CBaBcBb", + 12 + ], + [ + "bAA", + "CCBAc", + 7 + ], + [ + "bAA", + "abBBBAA", + 8 + ], + [ + "bAA", + "baacAbb", + 9 + ], + [ + "bAA", + "bcbBccAb", + 12 + ], + [ + "bAAA", + "C", + 8 + ], + [ + "bAAA", + "bBAAC", + 4 + ], + [ + "bAAAA", + "c", + 10 + ], + [ + "bAAAAbaCa", + "abacbC", + 12 + ], + [ + "bAAACbbb", + "Aaa", + 12 + ], + [ + "bAAACccC", + "CC", + 12 + ], + [ + "bAAAacAc", + "caC", + 12 + ], + [ + "bAAAbABC", + "CBCbBa", + 12 + ], + [ + "bAAB", + "bC", + 6 + ], + [ + "bAABaCA", + "A", + 12 + ], + [ + "bAABb", + "CaBBB", + 6 + ], + [ + "bAABcbbB", + "CbACCB", + 11 + ], + [ + "bAAC", + "AabbbaBA", + 13 + ], + [ + "bAAC", + "Acb", + 6 + ], + [ + "bAAC", + "aaB", + 6 + ], + [ + "bAACcACbc", + "Aaa", + 14 + ], + [ + "bAAa", + "AaABbabC", + 11 + ], + [ + "bAAa", + "bCAbbaa", + 7 + ], + [ + "bAAaCba", + "bAca", + 7 + ], + [ + "bAAaaaa", + "BC", + 13 + ], + [ + "bAAbAab", + "CBcA", + 12 + ], + [ + "bAAbCa", + "C", + 10 + ], + [ + "bAAbb", + "A", + 8 + ], + [ + "bAAc", + "CCAbca", + 8 + ], + [ + "bAAc", + "cCBAba", + 9 + ], + [ + "bAAcA", + "bbc", + 6 + ], + [ + "bAAccABbb", + "aAc", + 13 + ], + [ + "bAAccaCC", + "A", + 14 + ], + [ + "bAB", + "ACBcB", + 7 + ], + [ + "bAB", + "CbAA", + 4 + ], + [ + "bAB", + "bbABC", + 4 + ], + [ + "bABAC", + "BCaabaCBC", + 12 + ], + [ + "bABACCCB", + "abB", + 12 + ], + [ + "bABAaB", + "cCCCBbc", + 13 + ], + [ + "bABAaCBBA", + "BAbA", + 11 + ], + [ + "bABAaba", + "A", + 12 + ], + [ + "bABAba", + "BBBAccBA", + 9 + ], + [ + "bABAbbCbB", + "bA", + 14 + ], + [ + "bABAcCCb", + "abCaB", + 11 + ], + [ + "bABBCCC", + "bbCbBc", + 10 + ], + [ + "bABBa", + "bA", + 6 + ], + [ + "bABBcAc", + "bAC", + 9 + ], + [ + "bABC", + "AbBca", + 7 + ], + [ + "bABCBcAc", + "cBCAA", + 10 + ], + [ + "bABCC", + "aBCa", + 5 + ], + [ + "bABCCbbbC", + "cABACBBa", + 10 + ], + [ + "bABCaBCa", + "CaBbB", + 10 + ], + [ + "bABCbaB", + "ACCaCBc", + 10 + ], + [ + "bABa", + "BA", + 5 + ], + [ + "bABa", + "BAB", + 3 + ], + [ + "bABaCBBAa", + "Aa", + 14 + ], + [ + "bABb", + "acA", + 7 + ], + [ + "bABb", + "ccCA", + 8 + ], + [ + "bABbAB", + "ABCBCACc", + 11 + ], + [ + "bABbAC", + "bcBaCcAb", + 10 + ], + [ + "bABbBCB", + "cb", + 12 + ], + [ + "bABbaB", + "cAcAbbCAb", + 11 + ], + [ + "bABbaBAA", + "C", + 16 + ], + [ + "bABbbABBB", + "cAcb", + 14 + ], + [ + "bABbbbC", + "a", + 13 + ], + [ + "bABbcCab", + "ccccaa", + 11 + ], + [ + "bAC", + "AcAbc", + 7 + ], + [ + "bAC", + "bCcbAabb", + 12 + ], + [ + "bACA", + "ACaAAAaC", + 12 + ], + [ + "bACA", + "CAc", + 5 + ], + [ + "bACA", + "c", + 7 + ], + [ + "bACACAAa", + "cbBbC", + 14 + ], + [ + "bACAb", + "Cbc", + 8 + ], + [ + "bACAcc", + "BacBcAB", + 9 + ], + [ + "bACB", + "cBccC", + 8 + ], + [ + "bACBAC", + "BCCABaC", + 6 + ], + [ + "bACBBaA", + "bBACB", + 8 + ], + [ + "bACBCbb", + "b", + 12 + ], + [ + "bACBa", + "BCC", + 7 + ], + [ + "bACBaAcAb", + "C", + 16 + ], + [ + "bACBabABB", + "aCA", + 13 + ], + [ + "bACBcB", + "accBbaCcC", + 13 + ], + [ + "bACCaCcBb", + "aBaBcb", + 11 + ], + [ + "bACaBC", + "bA", + 8 + ], + [ + "bACaCCBAB", + "aaBacb", + 13 + ], + [ + "bACaCcC", + "aBCac", + 8 + ], + [ + "bACab", + "aBcBcAB", + 10 + ], + [ + "bACac", + "Bc", + 7 + ], + [ + "bACac", + "cBAacCAcB", + 10 + ], + [ + "bACbAA", + "B", + 11 + ], + [ + "bACbBbc", + "CbcAcBcA", + 11 + ], + [ + "bACc", + "bcA", + 5 + ], + [ + "bACc", + "cCb", + 6 + ], + [ + "bACcABb", + "BaC", + 10 + ], + [ + "bACcCaaC", + "AAbAbb", + 13 + ], + [ + "bAa", + "AaaACbAcc", + 14 + ], + [ + "bAa", + "AcAabb", + 8 + ], + [ + "bAa", + "bCbBCABBA", + 13 + ], + [ + "bAaA", + "aACcbaB", + 10 + ], + [ + "bAaAA", + "BacbCbBaa", + 14 + ], + [ + "bAaAAAa", + "cabAbA", + 9 + ], + [ + "bAaABAAC", + "AB", + 12 + ], + [ + "bAaAcA", + "cbC", + 11 + ], + [ + "bAaB", + "B", + 6 + ], + [ + "bAaB", + "acCCbb", + 11 + ], + [ + "bAaBAA", + "a", + 10 + ], + [ + "bAaBAcac", + "AABcaa", + 7 + ], + [ + "bAaBC", + "CBcaaaBa", + 10 + ], + [ + "bAaBa", + "C", + 10 + ], + [ + "bAaBaCBAB", + "CCbCCC", + 15 + ], + [ + "bAaBb", + "bCAA", + 7 + ], + [ + "bAaBbBc", + "AC", + 11 + ], + [ + "bAaBbc", + "cbbcAaab", + 10 + ], + [ + "bAaBc", + "a", + 8 + ], + [ + "bAaBc", + "cbCCBBbcc", + 12 + ], + [ + "bAaC", + "ABA", + 6 + ], + [ + "bAaC", + "BAaACAB", + 7 + ], + [ + "bAaCCa", + "CbCBB", + 10 + ], + [ + "bAaCa", + "bCBaABcbB", + 13 + ], + [ + "bAaCab", + "caBC", + 9 + ], + [ + "bAaa", + "AAcCbAC", + 11 + ], + [ + "bAaa", + "bBAAb", + 5 + ], + [ + "bAaaA", + "AbA", + 6 + ], + [ + "bAaaB", + "CABBC", + 8 + ], + [ + "bAaaB", + "bABBaC", + 6 + ], + [ + "bAaabaAc", + "cBaa", + 12 + ], + [ + "bAab", + "CcC", + 8 + ], + [ + "bAab", + "bAc", + 4 + ], + [ + "bAabAbC", + "A", + 12 + ], + [ + "bAabBACA", + "cCca", + 14 + ], + [ + "bAabBBCb", + "CbaCbA", + 12 + ], + [ + "bAabCAB", + "aA", + 10 + ], + [ + "bAabb", + "AaacAAA", + 11 + ], + [ + "bAabbC", + "babAb", + 6 + ], + [ + "bAabcA", + "bA", + 8 + ], + [ + "bAabcbc", + "BaAabcAaa", + 9 + ], + [ + "bAabccAa", + "aCbaB", + 12 + ], + [ + "bAac", + "ccACbbAA", + 13 + ], + [ + "bAacA", + "BBaACC", + 8 + ], + [ + "bAacAb", + "bacccBCc", + 10 + ], + [ + "bAacAbBca", + "C", + 17 + ], + [ + "bAacC", + "bbaAb", + 6 + ], + [ + "bAaccCB", + "c", + 12 + ], + [ + "bAb", + "ABCCAACCA", + 15 + ], + [ + "bAb", + "CCBAA", + 7 + ], + [ + "bAbACaC", + "bABcCAb", + 6 + ], + [ + "bAbAaC", + "BAbbA", + 6 + ], + [ + "bAbAabcab", + "CAabcBa", + 10 + ], + [ + "bAbAbcA", + "CAABBca", + 8 + ], + [ + "bAbBC", + "AACcbCca", + 11 + ], + [ + "bAbBCbaB", + "acacab", + 11 + ], + [ + "bAbBaCBcb", + "BaA", + 14 + ], + [ + "bAbBbbBbb", + "cAaacAC", + 16 + ], + [ + "bAbCAABaB", + "ACcBAccB", + 11 + ], + [ + "bAbCbCcCA", + "aBB", + 15 + ], + [ + "bAbCcB", + "aCAbA", + 10 + ], + [ + "bAba", + "CaAAb", + 8 + ], + [ + "bAbaCC", + "Bba", + 7 + ], + [ + "bAbab", + "CbCAcBcB", + 10 + ], + [ + "bAbb", + "acAbCBb", + 8 + ], + [ + "bAbb", + "b", + 6 + ], + [ + "bAbb", + "bAaAcBBab", + 11 + ], + [ + "bAbbB", + "AaACcBacC", + 14 + ], + [ + "bAbbaa", + "cCBC", + 11 + ], + [ + "bAbbbbBc", + "cABcBBC", + 9 + ], + [ + "bAbbbc", + "aCA", + 11 + ], + [ + "bAbc", + "Accbacc", + 9 + ], + [ + "bAbcBB", + "A", + 10 + ], + [ + "bAbcCaA", + "bACaCAcbC", + 11 + ], + [ + "bAbcCab", + "ABC", + 9 + ], + [ + "bAbcCbAA", + "BcBb", + 11 + ], + [ + "bAbcbA", + "CBCBCac", + 11 + ], + [ + "bAc", + "aaC", + 4 + ], + [ + "bAcA", + "bb", + 6 + ], + [ + "bAcAABA", + "aAAbca", + 9 + ], + [ + "bAcAAbA", + "BABabc", + 8 + ], + [ + "bAcAAbb", + "aC", + 12 + ], + [ + "bAcAbc", + "CAAcaaBa", + 10 + ], + [ + "bAcAc", + "BaC", + 7 + ], + [ + "bAcB", + "bcBC", + 4 + ], + [ + "bAcB", + "bccaA", + 6 + ], + [ + "bAcBAaaCa", + "aABCccaBa", + 12 + ], + [ + "bAcBAbBcC", + "B", + 16 + ], + [ + "bAcBBBABa", + "caA", + 14 + ], + [ + "bAcBCCbac", + "accBBAB", + 12 + ], + [ + "bAcBabbC", + "ca", + 12 + ], + [ + "bAcBbAb", + "cbaBA", + 9 + ], + [ + "bAcBbaA", + "AaBaaA", + 6 + ], + [ + "bAcC", + "Acac", + 5 + ], + [ + "bAcC", + "bba", + 6 + ], + [ + "bAcCAa", + "C", + 10 + ], + [ + "bAcCaCc", + "abbCcb", + 11 + ], + [ + "bAcCb", + "Bbcacac", + 9 + ], + [ + "bAcCbACCB", + "aA", + 15 + ], + [ + "bAcCcACA", + "ABCAaBB", + 11 + ], + [ + "bAcaAbA", + "baCCbBca", + 10 + ], + [ + "bAcac", + "BBbAbCccA", + 11 + ], + [ + "bAcb", + "aa", + 7 + ], + [ + "bAcb", + "cAbbb", + 6 + ], + [ + "bAcbAbBAC", + "CbBc", + 12 + ], + [ + "bAcbBbcb", + "cCcBBCaa", + 11 + ], + [ + "bAcc", + "aCcABC", + 9 + ], + [ + "bAccA", + "ccBaaCA", + 9 + ], + [ + "bAccCabB", + "aABCAAaAA", + 13 + ], + [ + "bAccCbb", + "BaAAcB", + 10 + ], + [ + "bAcca", + "CBbcBBBba", + 13 + ], + [ + "bAccaACaa", + "CCcBCaA", + 10 + ], + [ + "bAccaCCA", + "aABAABBCb", + 13 + ], + [ + "bAcccAC", + "ABC", + 10 + ], + [ + "bAcccAbaA", + "CBcCAbcC", + 11 + ], + [ + "bAcccaB", + "BccACBBC", + 10 + ], + [ + "bB", + "ACaAbC", + 10 + ], + [ + "bB", + "BCbCb", + 7 + ], + [ + "bB", + "Baa", + 5 + ], + [ + "bB", + "BbbbBAb", + 10 + ], + [ + "bB", + "Bcba", + 6 + ], + [ + "bB", + "CAAcBb", + 10 + ], + [ + "bB", + "CbbC", + 5 + ], + [ + "bB", + "aACCab", + 11 + ], + [ + "bB", + "aBaccb", + 10 + ], + [ + "bB", + "aBbC", + 6 + ], + [ + "bB", + "aCACcaA", + 14 + ], + [ + "bB", + "aaAABaCCc", + 16 + ], + [ + "bB", + "ac", + 4 + ], + [ + "bB", + "acACccAac", + 18 + ], + [ + "bB", + "bAAacb", + 9 + ], + [ + "bB", + "bBCccbcC", + 12 + ], + [ + "bB", + "bBbbcb", + 8 + ], + [ + "bB", + "bCbBAAbCc", + 14 + ], + [ + "bB", + "ba", + 2 + ], + [ + "bB", + "baAbcC", + 9 + ], + [ + "bB", + "bcBbACaa", + 12 + ], + [ + "bB", + "c", + 4 + ], + [ + "bB", + "cBCcc", + 8 + ], + [ + "bB", + "cCBa", + 6 + ], + [ + "bB", + "caBc", + 6 + ], + [ + "bB", + "caCCACb", + 13 + ], + [ + "bBA", + "AB", + 4 + ], + [ + "bBA", + "B", + 4 + ], + [ + "bBA", + "abBCbccC", + 12 + ], + [ + "bBA", + "bCaaa", + 7 + ], + [ + "bBA", + "cBB", + 4 + ], + [ + "bBAA", + "cAb", + 6 + ], + [ + "bBAAba", + "C", + 12 + ], + [ + "bBAAcb", + "BCcBABB", + 10 + ], + [ + "bBAB", + "ccaa", + 7 + ], + [ + "bBABbBc", + "Bb", + 10 + ], + [ + "bBAC", + "aCBb", + 8 + ], + [ + "bBACA", + "bbcaBB", + 8 + ], + [ + "bBACBA", + "CA", + 8 + ], + [ + "bBACBABc", + "ca", + 14 + ], + [ + "bBACCbCB", + "B", + 14 + ], + [ + "bBACbaC", + "aabAbaCC", + 9 + ], + [ + "bBAa", + "CBBbBaa", + 7 + ], + [ + "bBAa", + "CabC", + 8 + ], + [ + "bBAa", + "cCcCCCA", + 13 + ], + [ + "bBAaBAcB", + "CbCaaAbAA", + 12 + ], + [ + "bBAaBcAaB", + "ACcb", + 13 + ], + [ + "bBAaC", + "acBaAcC", + 8 + ], + [ + "bBAaCB", + "bcBbCBBca", + 12 + ], + [ + "bBAaCc", + "Aca", + 9 + ], + [ + "bBAac", + "AcccCbBc", + 14 + ], + [ + "bBAacA", + "aBCbaAAA", + 10 + ], + [ + "bBAbCA", + "cBAaaCACb", + 10 + ], + [ + "bBAba", + "B", + 8 + ], + [ + "bBAbac", + "cBbAaccb", + 10 + ], + [ + "bBAc", + "Bc", + 4 + ], + [ + "bBAcAbca", + "baB", + 12 + ], + [ + "bBAcBA", + "aAa", + 9 + ], + [ + "bBAcC", + "abbBbCBc", + 10 + ], + [ + "bBAcC", + "c", + 8 + ], + [ + "bBAca", + "Ba", + 6 + ], + [ + "bBAca", + "b", + 8 + ], + [ + "bBAca", + "c", + 8 + ], + [ + "bBB", + "ABACC", + 8 + ], + [ + "bBB", + "AcaBacAc", + 14 + ], + [ + "bBB", + "BCCBCB", + 7 + ], + [ + "bBB", + "Cba", + 5 + ], + [ + "bBB", + "bACbcbAc", + 12 + ], + [ + "bBBABBb", + "Cbab", + 10 + ], + [ + "bBBAa", + "c", + 10 + ], + [ + "bBBBB", + "AacCA", + 10 + ], + [ + "bBBBBAa", + "AbbBAB", + 8 + ], + [ + "bBBBCb", + "B", + 10 + ], + [ + "bBBBabC", + "abBacCCBA", + 13 + ], + [ + "bBBBc", + "AB", + 8 + ], + [ + "bBBC", + "B", + 6 + ], + [ + "bBBC", + "abAbBBcab", + 11 + ], + [ + "bBBCABbB", + "caaCC", + 14 + ], + [ + "bBBCAbB", + "BcBCBCcBc", + 10 + ], + [ + "bBBa", + "abbCAA", + 8 + ], + [ + "bBBaB", + "cacCCbAA", + 14 + ], + [ + "bBBaC", + "Bcc", + 7 + ], + [ + "bBBaaBC", + "bcbcbBba", + 11 + ], + [ + "bBBaaBb", + "a", + 12 + ], + [ + "bBBaabc", + "caaBba", + 10 + ], + [ + "bBBabac", + "aaAA", + 11 + ], + [ + "bBBb", + "Accaab", + 10 + ], + [ + "bBBb", + "aAacAbca", + 14 + ], + [ + "bBBbAcBB", + "BBAbBAb", + 9 + ], + [ + "bBBbBbbbB", + "cc", + 18 + ], + [ + "bBBbCa", + "BcC", + 8 + ], + [ + "bBBbaB", + "caAaaC", + 10 + ], + [ + "bBBbaBbCa", + "a", + 16 + ], + [ + "bBBbacabB", + "Ba", + 14 + ], + [ + "bBBbcc", + "bcA", + 8 + ], + [ + "bBBc", + "ABBbACc", + 8 + ], + [ + "bBBc", + "BAAb", + 7 + ], + [ + "bBBcA", + "caB", + 8 + ], + [ + "bBBcaca", + "CBBBbABcb", + 10 + ], + [ + "bBC", + "AB", + 4 + ], + [ + "bBC", + "aaCaCAcBc", + 15 + ], + [ + "bBC", + "bcaBACB", + 8 + ], + [ + "bBC", + "cAB", + 6 + ], + [ + "bBC", + "cBaCcbca", + 12 + ], + [ + "bBCA", + "AAc", + 7 + ], + [ + "bBCA", + "bCCACBc", + 8 + ], + [ + "bBCA", + "babCCBAC", + 9 + ], + [ + "bBCA", + "cBaabcA", + 9 + ], + [ + "bBCAB", + "ACcBBBBab", + 13 + ], + [ + "bBCABBA", + "BCabbCAB", + 9 + ], + [ + "bBCAbAb", + "caAbA", + 8 + ], + [ + "bBCAbBba", + "CbbBbbC", + 10 + ], + [ + "bBCAcBcCA", + "B", + 16 + ], + [ + "bBCBa", + "cbAAB", + 8 + ], + [ + "bBCBaBCaa", + "bA", + 15 + ], + [ + "bBCBaC", + "aABCAca", + 10 + ], + [ + "bBCBabBC", + "cCAc", + 12 + ], + [ + "bBCC", + "baAbacaA", + 12 + ], + [ + "bBCCA", + "aa", + 9 + ], + [ + "bBCCCCABc", + "babacAA", + 13 + ], + [ + "bBCCCb", + "ACc", + 9 + ], + [ + "bBCCbAb", + "a", + 13 + ], + [ + "bBCaABB", + "CbACac", + 10 + ], + [ + "bBCaCCC", + "ABccBC", + 8 + ], + [ + "bBCaabcAA", + "CBABCC", + 13 + ], + [ + "bBCac", + "BA", + 7 + ], + [ + "bBCacbCA", + "BaCBcCBC", + 10 + ], + [ + "bBCb", + "bBcCA", + 4 + ], + [ + "bBCbAAaAC", + "CCbCCA", + 12 + ], + [ + "bBCbBa", + "AbBaACCB", + 10 + ], + [ + "bBCbb", + "aCcaC", + 9 + ], + [ + "bBCc", + "ccB", + 7 + ], + [ + "bBCcaAAa", + "caabAbC", + 13 + ], + [ + "bBa", + "Bba", + 2 + ], + [ + "bBa", + "b", + 4 + ], + [ + "bBa", + "bBcAca", + 6 + ], + [ + "bBa", + "bCA", + 3 + ], + [ + "bBa", + "cACaAbBa", + 10 + ], + [ + "bBa", + "ccBcbcAcc", + 15 + ], + [ + "bBaABCcC", + "ABA", + 12 + ], + [ + "bBaACBaB", + "BCBBABbb", + 10 + ], + [ + "bBaAaA", + "Bb", + 10 + ], + [ + "bBaAaBc", + "BAbcaACBc", + 8 + ], + [ + "bBaAaC", + "cCBACaaA", + 10 + ], + [ + "bBaAb", + "bACbbacAB", + 10 + ], + [ + "bBaBCAAaa", + "CACBAc", + 13 + ], + [ + "bBaBCCcA", + "bb", + 13 + ], + [ + "bBaBCaAaB", + "bCAbCbbB", + 10 + ], + [ + "bBaBCcBcB", + "cabcc", + 11 + ], + [ + "bBaBa", + "BC", + 8 + ], + [ + "bBaBbAbAB", + "aBAAbCCBA", + 12 + ], + [ + "bBaBbb", + "BaCAbbb", + 7 + ], + [ + "bBaC", + "BAaAcb", + 8 + ], + [ + "bBaCbcC", + "bA", + 11 + ], + [ + "bBaCcAA", + "cAbb", + 12 + ], + [ + "bBaaBb", + "Caa", + 8 + ], + [ + "bBaaBcBbb", + "cABAaA", + 15 + ], + [ + "bBaaCABa", + "bcbaBcbC", + 11 + ], + [ + "bBaaCa", + "bAAC", + 6 + ], + [ + "bBaabbbbc", + "cbA", + 16 + ], + [ + "bBaacaC", + "bccaBC", + 8 + ], + [ + "bBabAcBA", + "ccaAbA", + 9 + ], + [ + "bBabB", + "BabcBBB", + 8 + ], + [ + "bBabC", + "ABc", + 7 + ], + [ + "bBabaAC", + "ccaCb", + 12 + ], + [ + "bBac", + "AbaAcAaB", + 11 + ], + [ + "bBac", + "BBCc", + 3 + ], + [ + "bBacbBcb", + "bCbc", + 9 + ], + [ + "bBb", + "AA", + 6 + ], + [ + "bBb", + "AbCaacc", + 12 + ], + [ + "bBb", + "CaaCCCaA", + 16 + ], + [ + "bBb", + "Ccac", + 8 + ], + [ + "bBb", + "a", + 6 + ], + [ + "bBb", + "aCC", + 6 + ], + [ + "bBb", + "baAC", + 6 + ], + [ + "bBb", + "cBA", + 4 + ], + [ + "bBb", + "caBaCBa", + 11 + ], + [ + "bBbA", + "C", + 8 + ], + [ + "bBbA", + "CBcBAA", + 7 + ], + [ + "bBbA", + "caBBABaBa", + 13 + ], + [ + "bBbAAa", + "aabbb", + 10 + ], + [ + "bBbB", + "AcbAA", + 8 + ], + [ + "bBbB", + "a", + 8 + ], + [ + "bBbBBaBAc", + "c", + 16 + ], + [ + "bBbBBba", + "Bbc", + 10 + ], + [ + "bBbBb", + "B", + 8 + ], + [ + "bBbCA", + "abBBcBBbc", + 12 + ], + [ + "bBbCCca", + "aCaCBCB", + 11 + ], + [ + "bBba", + "aAA", + 7 + ], + [ + "bBba", + "abB", + 6 + ], + [ + "bBbaA", + "cBCBCcCCB", + 15 + ], + [ + "bBbaC", + "bc", + 7 + ], + [ + "bBbaCba", + "aBBccAaB", + 10 + ], + [ + "bBbabBAC", + "bCBa", + 11 + ], + [ + "bBbacbBCA", + "BA", + 14 + ], + [ + "bBbbCA", + "bACbBAa", + 8 + ], + [ + "bBbbbc", + "c", + 10 + ], + [ + "bBbcAAba", + "cC", + 14 + ], + [ + "bBbcBBCa", + "b", + 14 + ], + [ + "bBbcCC", + "aacCBb", + 10 + ], + [ + "bBbcCC", + "acabCCb", + 9 + ], + [ + "bBbcbA", + "BcBCabB", + 9 + ], + [ + "bBbcbA", + "cBaCcCbB", + 10 + ], + [ + "bBbcbBa", + "BbA", + 9 + ], + [ + "bBc", + "A", + 6 + ], + [ + "bBc", + "ACA", + 6 + ], + [ + "bBc", + "CC", + 5 + ], + [ + "bBc", + "bCbA", + 5 + ], + [ + "bBc", + "bbcA", + 3 + ], + [ + "bBcA", + "BaCba", + 7 + ], + [ + "bBcAACbB", + "bCba", + 10 + ], + [ + "bBcABCb", + "BAca", + 9 + ], + [ + "bBcAa", + "Ca", + 7 + ], + [ + "bBcAcBabB", + "ccaCAb", + 11 + ], + [ + "bBcAccBAc", + "cAc", + 12 + ], + [ + "bBcB", + "Ca", + 7 + ], + [ + "bBcBAbB", + "A", + 12 + ], + [ + "bBcBAca", + "BcbC", + 8 + ], + [ + "bBcBc", + "C", + 9 + ], + [ + "bBcCCbcb", + "CAAcacCaC", + 14 + ], + [ + "bBcCaAb", + "CbbbCa", + 9 + ], + [ + "bBcCbAAa", + "c", + 14 + ], + [ + "bBcaaaCAC", + "ACBbc", + 16 + ], + [ + "bBcb", + "bCCac", + 7 + ], + [ + "bBcba", + "bba", + 4 + ], + [ + "bBcbaB", + "BaCCbc", + 10 + ], + [ + "bBcbaBAbB", + "AAb", + 13 + ], + [ + "bBcbaBbAB", + "c", + 16 + ], + [ + "bBcc", + "CcBABA", + 10 + ], + [ + "bBcc", + "aAc", + 6 + ], + [ + "bBccACBbA", + "CaCCCB", + 12 + ], + [ + "bBccBc", + "Caac", + 9 + ], + [ + "bBccC", + "bAcc", + 4 + ], + [ + "bBccb", + "bccAbBbC", + 10 + ], + [ + "bBccb", + "caBAA", + 10 + ], + [ + "bBccbBbCb", + "AAAbbaBA", + 15 + ], + [ + "bBccbBccC", + "c", + 16 + ], + [ + "bBccbb", + "AaABa", + 11 + ], + [ + "bBcccB", + "bcCAca", + 7 + ], + [ + "bC", + "A", + 4 + ], + [ + "bC", + "ACBBaBa", + 12 + ], + [ + "bC", + "Abc", + 3 + ], + [ + "bC", + "BAAcb", + 8 + ], + [ + "bC", + "BAa", + 5 + ], + [ + "bC", + "BAcaBCAcc", + 15 + ], + [ + "bC", + "BCbcCA", + 8 + ], + [ + "bC", + "BacAcb", + 10 + ], + [ + "bC", + "CC", + 2 + ], + [ + "bC", + "CbBcAbcc", + 13 + ], + [ + "bC", + "aBaCA", + 7 + ], + [ + "bC", + "aCCbCABBB", + 14 + ], + [ + "bC", + "aaBBCAA", + 11 + ], + [ + "bC", + "aaCbaAcB", + 13 + ], + [ + "bC", + "acCcbcB", + 11 + ], + [ + "bC", + "b", + 2 + ], + [ + "bC", + "bBBBC", + 6 + ], + [ + "bC", + "bBb", + 4 + ], + [ + "bC", + "bC", + 0 + ], + [ + "bC", + "baAAcb", + 9 + ], + [ + "bC", + "bac", + 3 + ], + [ + "bC", + "bbBb", + 6 + ], + [ + "bC", + "c", + 3 + ], + [ + "bC", + "cABAac", + 10 + ], + [ + "bC", + "cABcACACa", + 15 + ], + [ + "bC", + "cAaCb", + 8 + ], + [ + "bC", + "cBbB", + 6 + ], + [ + "bC", + "cBcCbcc", + 11 + ], + [ + "bC", + "cBcCcAa", + 11 + ], + [ + "bC", + "cccCBcaba", + 16 + ], + [ + "bCA", + "BbCaCc", + 7 + ], + [ + "bCA", + "ac", + 5 + ], + [ + "bCA", + "bCB", + 2 + ], + [ + "bCA", + "ba", + 3 + ], + [ + "bCA", + "cbcbAc", + 7 + ], + [ + "bCAAA", + "Cc", + 8 + ], + [ + "bCAAA", + "cBabbA", + 9 + ], + [ + "bCAAABc", + "Aabab", + 11 + ], + [ + "bCAABaCbc", + "Cab", + 12 + ], + [ + "bCAABccA", + "AaacCBBcB", + 13 + ], + [ + "bCAAC", + "bBAaCcc", + 7 + ], + [ + "bCAACaCa", + "CcAACaC", + 5 + ], + [ + "bCAAaBbCA", + "CbaAcB", + 13 + ], + [ + "bCAB", + "bAAA", + 4 + ], + [ + "bCABB", + "bA", + 6 + ], + [ + "bCABBCAA", + "bBCbcCc", + 11 + ], + [ + "bCABBcB", + "bBbACbaBb", + 11 + ], + [ + "bCABa", + "AaAa", + 6 + ], + [ + "bCABaBAcc", + "CBbaCCba", + 13 + ], + [ + "bCAC", + "ABCcc", + 6 + ], + [ + "bCAC", + "caCa", + 6 + ], + [ + "bCAC", + "cbCcb", + 6 + ], + [ + "bCACBA", + "cbac", + 10 + ], + [ + "bCACBB", + "Bcb", + 9 + ], + [ + "bCACa", + "c", + 9 + ], + [ + "bCACaaC", + "Cacaaa", + 6 + ], + [ + "bCACaaa", + "cC", + 11 + ], + [ + "bCACb", + "B", + 9 + ], + [ + "bCACbA", + "Cb", + 8 + ], + [ + "bCAaCB", + "aCAbcCbB", + 8 + ], + [ + "bCAaCbac", + "a", + 14 + ], + [ + "bCAaccaCC", + "b", + 16 + ], + [ + "bCAbAAcA", + "bBBCAabAc", + 10 + ], + [ + "bCAbab", + "ca", + 9 + ], + [ + "bCAbb", + "CBAcBAcBB", + 12 + ], + [ + "bCAc", + "BaCAaaBa", + 11 + ], + [ + "bCAcBA", + "CBBcCCA", + 10 + ], + [ + "bCAcC", + "BbaccaCA", + 10 + ], + [ + "bCAcC", + "BcA", + 6 + ], + [ + "bCAcc", + "cbCAB", + 6 + ], + [ + "bCB", + "CCabaC", + 9 + ], + [ + "bCB", + "abaaAbbAC", + 15 + ], + [ + "bCB", + "bCAca", + 6 + ], + [ + "bCB", + "cBAB", + 5 + ], + [ + "bCBA", + "BccBbcAA", + 10 + ], + [ + "bCBAAa", + "c", + 11 + ], + [ + "bCBBBCbc", + "CAbbbB", + 10 + ], + [ + "bCBBBcB", + "BBaBCBbC", + 10 + ], + [ + "bCBBa", + "CccaaC", + 9 + ], + [ + "bCBBbCc", + "bBaAB", + 10 + ], + [ + "bCBC", + "AbaCcaCB", + 10 + ], + [ + "bCBC", + "CcbaCaA", + 10 + ], + [ + "bCBC", + "aCAbcbCC", + 10 + ], + [ + "bCBCAB", + "C", + 10 + ], + [ + "bCBCACBb", + "bBacBCaA", + 11 + ], + [ + "bCBCBcbc", + "bA", + 14 + ], + [ + "bCBCaAc", + "a", + 12 + ], + [ + "bCBCbC", + "A", + 12 + ], + [ + "bCBa", + "Ba", + 4 + ], + [ + "bCBaAb", + "CABCCcb", + 10 + ], + [ + "bCBaabC", + "ACb", + 10 + ], + [ + "bCBabCa", + "cAbaccCC", + 11 + ], + [ + "bCBacABab", + "ccAacAaCc", + 11 + ], + [ + "bCBacaAB", + "ACbABB", + 10 + ], + [ + "bCBb", + "aaAbAbbC", + 11 + ], + [ + "bCBb", + "cBabcA", + 9 + ], + [ + "bCBb", + "cBcccaA", + 12 + ], + [ + "bCBbAaAb", + "BabA", + 11 + ], + [ + "bCBbAac", + "CBcca", + 8 + ], + [ + "bCBbAcC", + "CBbBbb", + 8 + ], + [ + "bCBbC", + "CA", + 8 + ], + [ + "bCBbaCCA", + "BAAab", + 13 + ], + [ + "bCBbabb", + "BcCBA", + 10 + ], + [ + "bCBbbCb", + "ABcbAba", + 10 + ], + [ + "bCBc", + "bbBACc", + 6 + ], + [ + "bCBcB", + "bCAbccACb", + 10 + ], + [ + "bCBcBBc", + "b", + 12 + ], + [ + "bCBca", + "cAABaCCa", + 11 + ], + [ + "bCBcabA", + "CAcbbcBcB", + 14 + ], + [ + "bCBcba", + "ABAcbc", + 8 + ], + [ + "bCBcccbC", + "Cbbbc", + 10 + ], + [ + "bCC", + "A", + 6 + ], + [ + "bCC", + "ABBbCCC", + 8 + ], + [ + "bCC", + "AaC", + 4 + ], + [ + "bCC", + "BB", + 5 + ], + [ + "bCC", + "a", + 6 + ], + [ + "bCC", + "aCbBaaCB", + 12 + ], + [ + "bCC", + "b", + 4 + ], + [ + "bCC", + "bbBaCaCAc", + 12 + ], + [ + "bCC", + "cB", + 5 + ], + [ + "bCCAACA", + "bc", + 11 + ], + [ + "bCCAAbAa", + "aC", + 14 + ], + [ + "bCCACBb", + "BcAA", + 10 + ], + [ + "bCCAc", + "bcBCABabC", + 10 + ], + [ + "bCCBACAa", + "cCB", + 11 + ], + [ + "bCCBC", + "CbbbACC", + 10 + ], + [ + "bCCBaBa", + "BC", + 11 + ], + [ + "bCCBbBAA", + "ACBbbBc", + 9 + ], + [ + "bCCCABcb", + "BaBbbAb", + 12 + ], + [ + "bCCCa", + "aA", + 9 + ], + [ + "bCCCbccc", + "aCAA", + 14 + ], + [ + "bCCa", + "AabcB", + 9 + ], + [ + "bCCa", + "BccBa", + 5 + ], + [ + "bCCa", + "bCACAaBb", + 8 + ], + [ + "bCCaA", + "cbAbaAA", + 8 + ], + [ + "bCCaAbBB", + "CcC", + 13 + ], + [ + "bCCaBa", + "AcCabCAc", + 9 + ], + [ + "bCCaCc", + "abAcCA", + 9 + ], + [ + "bCCaa", + "cA", + 8 + ], + [ + "bCCaaCaa", + "cbcc", + 14 + ], + [ + "bCCab", + "B", + 9 + ], + [ + "bCCaccbbB", + "cC", + 15 + ], + [ + "bCCb", + "cBBaBB", + 10 + ], + [ + "bCCbA", + "bcBC", + 6 + ], + [ + "bCCbACBBB", + "CA", + 14 + ], + [ + "bCCbB", + "aaBcCbAA", + 10 + ], + [ + "bCCbCc", + "aACbC", + 6 + ], + [ + "bCCbcA", + "caACc", + 10 + ], + [ + "bCCcAcAB", + "aCAB", + 10 + ], + [ + "bCCcc", + "aACCcacB", + 8 + ], + [ + "bCCccC", + "aabAb", + 12 + ], + [ + "bCa", + "Cb", + 4 + ], + [ + "bCa", + "aBbb", + 7 + ], + [ + "bCa", + "bBACAbba", + 10 + ], + [ + "bCa", + "baba", + 4 + ], + [ + "bCa", + "cbacb", + 7 + ], + [ + "bCa", + "ccaCaCCc", + 12 + ], + [ + "bCaA", + "AABbbA", + 9 + ], + [ + "bCaA", + "CBc", + 6 + ], + [ + "bCaAC", + "ACaaABaCa", + 10 + ], + [ + "bCaBAc", + "bbbBcbcAc", + 10 + ], + [ + "bCaBBBA", + "caCcBBCcB", + 12 + ], + [ + "bCaBBC", + "cacbBC", + 6 + ], + [ + "bCaBbCAC", + "aaCAcCAbC", + 11 + ], + [ + "bCaCAabc", + "bBaB", + 11 + ], + [ + "bCaCAcaC", + "bcccaa", + 8 + ], + [ + "bCaCCC", + "cAbabbACA", + 14 + ], + [ + "bCaCcB", + "ABbbcCABC", + 12 + ], + [ + "bCaCcac", + "CBbCAA", + 10 + ], + [ + "bCaa", + "a", + 6 + ], + [ + "bCaa", + "aBC", + 7 + ], + [ + "bCaabBC", + "CCABcA", + 10 + ], + [ + "bCabAacbC", + "BAB", + 14 + ], + [ + "bCabCc", + "CA", + 9 + ], + [ + "bCabaAAB", + "A", + 14 + ], + [ + "bCabbAacb", + "Cba", + 12 + ], + [ + "bCabbC", + "CAacA", + 9 + ], + [ + "bCac", + "C", + 6 + ], + [ + "bCac", + "cC", + 6 + ], + [ + "bCacAbBa", + "a", + 14 + ], + [ + "bCacBA", + "abB", + 8 + ], + [ + "bCacCcB", + "aAabBBbC", + 13 + ], + [ + "bCaccBAa", + "CB", + 12 + ], + [ + "bCb", + "aCBc", + 5 + ], + [ + "bCb", + "ab", + 4 + ], + [ + "bCb", + "ccA", + 5 + ], + [ + "bCbA", + "ab", + 6 + ], + [ + "bCbAAAB", + "AccbcBaB", + 10 + ], + [ + "bCbAB", + "BcBB", + 5 + ], + [ + "bCbACcbc", + "b", + 14 + ], + [ + "bCbAa", + "acCBABB", + 9 + ], + [ + "bCbAbcBc", + "b", + 14 + ], + [ + "bCbB", + "b", + 6 + ], + [ + "bCbBabC", + "cbacBCaBc", + 10 + ], + [ + "bCbBacaA", + "aBAaBCaa", + 11 + ], + [ + "bCbBbbbC", + "a", + 16 + ], + [ + "bCbBbcAb", + "ba", + 13 + ], + [ + "bCbCAbB", + "CABBbb", + 9 + ], + [ + "bCbCCCAcb", + "a", + 17 + ], + [ + "bCbCbb", + "AAACCCB", + 11 + ], + [ + "bCbCccc", + "abbAbC", + 11 + ], + [ + "bCbaACBbb", + "bCCccaa", + 13 + ], + [ + "bCbaAc", + "BA", + 9 + ], + [ + "bCbaaBc", + "CbAAcaBc", + 7 + ], + [ + "bCbac", + "aAcBABbaA", + 13 + ], + [ + "bCbac", + "b", + 8 + ], + [ + "bCbacABa", + "cCaac", + 10 + ], + [ + "bCbb", + "bbCBabAC", + 9 + ], + [ + "bCbbb", + "AcBc", + 8 + ], + [ + "bCbbba", + "AaBbc", + 9 + ], + [ + "bCbc", + "ABb", + 6 + ], + [ + "bCbc", + "CCb", + 4 + ], + [ + "bCbcB", + "AbAab", + 9 + ], + [ + "bCbcCBA", + "BCbBacC", + 9 + ], + [ + "bCbcCC", + "BbbABA", + 9 + ], + [ + "bCbcCbAC", + "ccccC", + 10 + ], + [ + "bCbca", + "bcbBCBa", + 6 + ], + [ + "bCbcaAAAA", + "A", + 16 + ], + [ + "bCbcaca", + "bBBAcc", + 8 + ], + [ + "bCbcbbBbC", + "CaC", + 14 + ], + [ + "bCc", + "BabBBCb", + 10 + ], + [ + "bCc", + "CCBcAA", + 8 + ], + [ + "bCc", + "CCCcCBcC", + 12 + ], + [ + "bCc", + "aaAABCCaB", + 14 + ], + [ + "bCc", + "aabbbaaB", + 14 + ], + [ + "bCc", + "bccB", + 3 + ], + [ + "bCcABC", + "aAcBcCC", + 10 + ], + [ + "bCcACCBa", + "cac", + 12 + ], + [ + "bCcACCaC", + "AbcaC", + 9 + ], + [ + "bCcB", + "BBB", + 5 + ], + [ + "bCcBA", + "CcAbcCbaA", + 11 + ], + [ + "bCcBB", + "cBb", + 5 + ], + [ + "bCcC", + "ACBaB", + 8 + ], + [ + "bCcCb", + "ccbBac", + 10 + ], + [ + "bCcCcCCCB", + "BCAaAa", + 15 + ], + [ + "bCca", + "CCaaaBbc", + 12 + ], + [ + "bCcaA", + "cACB", + 9 + ], + [ + "bCcaBbac", + "bBa", + 10 + ], + [ + "bCcaCc", + "A", + 11 + ], + [ + "bCcaCcC", + "bcCB", + 8 + ], + [ + "bCcaaa", + "B", + 11 + ], + [ + "bCcaabCB", + "bbAbcaAA", + 13 + ], + [ + "bCcacBCA", + "aACBccC", + 11 + ], + [ + "bCcbAaBBc", + "c", + 16 + ], + [ + "bCcbCCbb", + "bBbacaC", + 11 + ], + [ + "bCcbbaCab", + "BC", + 15 + ], + [ + "bCcbbc", + "bBBCB", + 9 + ], + [ + "bCcbc", + "acBCAcc", + 9 + ], + [ + "bCcc", + "CAbacbA", + 10 + ], + [ + "bCccbbbc", + "bBABAaBAc", + 13 + ], + [ + "ba", + "ABbbC", + 8 + ], + [ + "ba", + "BA", + 2 + ], + [ + "ba", + "BAABBb", + 10 + ], + [ + "ba", + "BacAAbA", + 11 + ], + [ + "ba", + "BbAaaCACc", + 14 + ], + [ + "ba", + "BcCAAC", + 10 + ], + [ + "ba", + "Bcc", + 5 + ], + [ + "ba", + "CCccCCa", + 12 + ], + [ + "ba", + "CaAbAb", + 9 + ], + [ + "ba", + "Cba", + 2 + ], + [ + "ba", + "Cca", + 4 + ], + [ + "ba", + "Ccac", + 6 + ], + [ + "ba", + "a", + 2 + ], + [ + "ba", + "aBABA", + 8 + ], + [ + "ba", + "aBaABB", + 9 + ], + [ + "ba", + "aCcaCbAbB", + 15 + ], + [ + "ba", + "bBC", + 4 + ], + [ + "ba", + "bBCC", + 6 + ], + [ + "ba", + "baABc", + 6 + ], + [ + "ba", + "baCAbB", + 8 + ], + [ + "ba", + "cA", + 3 + ], + [ + "ba", + "cABA", + 6 + ], + [ + "ba", + "cBbCCaB", + 10 + ], + [ + "ba", + "cBc", + 5 + ], + [ + "ba", + "cCCBcC", + 11 + ], + [ + "ba", + "caBBCAca", + 13 + ], + [ + "ba", + "cbBbb", + 8 + ], + [ + "ba", + "ccb", + 6 + ], + [ + "baA", + "AbAAaCaa", + 11 + ], + [ + "baA", + "B", + 5 + ], + [ + "baA", + "BBB", + 5 + ], + [ + "baA", + "a", + 4 + ], + [ + "baA", + "aCaaB", + 7 + ], + [ + "baA", + "cAaBCBaCB", + 15 + ], + [ + "baA", + "cBBcccca", + 14 + ], + [ + "baA", + "ccABbC", + 10 + ], + [ + "baAA", + "BBAaCacBC", + 14 + ], + [ + "baAA", + "cbbbCcbac", + 15 + ], + [ + "baAAA", + "CCcC", + 10 + ], + [ + "baAAABbC", + "BcACCbBa", + 11 + ], + [ + "baAAAbAC", + "caBb", + 12 + ], + [ + "baAAa", + "cACaAB", + 8 + ], + [ + "baAAc", + "bC", + 7 + ], + [ + "baAAcCa", + "CCABACcBC", + 12 + ], + [ + "baABBcc", + "cbcaaABc", + 9 + ], + [ + "baABCaCA", + "CABCbCAC", + 8 + ], + [ + "baABaBaAA", + "CAabb", + 13 + ], + [ + "baABbAcC", + "BcCBCCC", + 10 + ], + [ + "baAC", + "bCbAbBCA", + 10 + ], + [ + "baACCCcaA", + "Cb", + 16 + ], + [ + "baACca", + "bBcB", + 8 + ], + [ + "baAa", + "AbAab", + 6 + ], + [ + "baAaCAcc", + "acAbB", + 11 + ], + [ + "baAbCAc", + "baAacAac", + 5 + ], + [ + "baAbaAaba", + "cBA", + 15 + ], + [ + "baAbabAb", + "CC", + 16 + ], + [ + "baAcABAC", + "aabCBbBcB", + 13 + ], + [ + "baAcB", + "bbcb", + 5 + ], + [ + "baAcCcaaa", + "ccAA", + 12 + ], + [ + "baAca", + "aaAcCc", + 6 + ], + [ + "baAcaA", + "C", + 11 + ], + [ + "baAcab", + "B", + 11 + ], + [ + "baAcc", + "AbacACCCb", + 10 + ], + [ + "baB", + "BbccbbBbC", + 14 + ], + [ + "baB", + "acbAB", + 5 + ], + [ + "baB", + "accCa", + 10 + ], + [ + "baB", + "cA", + 5 + ], + [ + "baB", + "ca", + 4 + ], + [ + "baB", + "ccBACC", + 10 + ], + [ + "baBA", + "aa", + 5 + ], + [ + "baBAC", + "aA", + 6 + ], + [ + "baBAbccc", + "BCBaC", + 11 + ], + [ + "baBB", + "bCCaAca", + 10 + ], + [ + "baBB", + "cacbb", + 6 + ], + [ + "baBBC", + "BbBAA", + 7 + ], + [ + "baBBCAAc", + "bBaabAccc", + 11 + ], + [ + "baBBCcBCa", + "ABbBca", + 9 + ], + [ + "baBBaa", + "BCABAa", + 6 + ], + [ + "baBBbAb", + "bACa", + 10 + ], + [ + "baBBbCbBC", + "cBABabC", + 11 + ], + [ + "baBBcaBcC", + "CCCb", + 16 + ], + [ + "baBBcb", + "BBCbCCb", + 9 + ], + [ + "baBCcbbA", + "BBacCC", + 11 + ], + [ + "baBa", + "aA", + 5 + ], + [ + "baBa", + "bBbcAAb", + 10 + ], + [ + "baBa", + "cCbbbcBC", + 12 + ], + [ + "baBaABBb", + "bBcB", + 10 + ], + [ + "baBaaC", + "A", + 11 + ], + [ + "baBaaC", + "bBbAcc", + 7 + ], + [ + "baBbC", + "ACAc", + 8 + ], + [ + "baBbcCbaC", + "C", + 16 + ], + [ + "baBc", + "BAAbCa", + 8 + ], + [ + "baBcAAC", + "aBAAbACa", + 8 + ], + [ + "baBcC", + "Abc", + 6 + ], + [ + "baBcCCBBA", + "bbacBaaaC", + 14 + ], + [ + "baBcCCBb", + "Bccacb", + 9 + ], + [ + "baBcaAc", + "bc", + 10 + ], + [ + "baBcbccA", + "bCCa", + 11 + ], + [ + "baBccBC", + "C", + 12 + ], + [ + "baBccccb", + "AAbbaBCb", + 11 + ], + [ + "baC", + "AABBAb", + 10 + ], + [ + "baC", + "AB", + 5 + ], + [ + "baC", + "BBa", + 5 + ], + [ + "baC", + "CAaCCcbb", + 12 + ], + [ + "baC", + "CC", + 4 + ], + [ + "baC", + "caBcB", + 7 + ], + [ + "baCA", + "Bc", + 6 + ], + [ + "baCACBCac", + "a", + 16 + ], + [ + "baCAaAaBa", + "bcBcCab", + 12 + ], + [ + "baCAbc", + "CCc", + 8 + ], + [ + "baCB", + "B", + 6 + ], + [ + "baCBACbBa", + "b", + 16 + ], + [ + "baCBC", + "CAAcaCaB", + 12 + ], + [ + "baCBbCB", + "abc", + 9 + ], + [ + "baCCCCBB", + "b", + 14 + ], + [ + "baCCCcC", + "bbcAcABac", + 13 + ], + [ + "baCCbAB", + "CbBAC", + 9 + ], + [ + "baCCc", + "BcACCa", + 6 + ], + [ + "baCCc", + "ab", + 8 + ], + [ + "baCa", + "BAabaACcC", + 12 + ], + [ + "baCa", + "CCAABc", + 11 + ], + [ + "baCaAAB", + "aCB", + 8 + ], + [ + "baCaCa", + "caC", + 7 + ], + [ + "baCaCcbAb", + "bCB", + 13 + ], + [ + "baCb", + "CAbA", + 7 + ], + [ + "baCbCAB", + "aCBccCcC", + 11 + ], + [ + "baCbCC", + "ACCbA", + 8 + ], + [ + "baCbbCb", + "bACAc", + 8 + ], + [ + "baCbc", + "aaAbAb", + 8 + ], + [ + "baCbcACBc", + "CACcBb", + 11 + ], + [ + "baCc", + "BbcaaB", + 8 + ], + [ + "baCcA", + "bbbBcB", + 8 + ], + [ + "baCcaaC", + "cCCA", + 10 + ], + [ + "baCcb", + "BaCacAa", + 7 + ], + [ + "baa", + "ACbBca", + 8 + ], + [ + "baa", + "BaC", + 3 + ], + [ + "baaABBcBb", + "ABcacAC", + 14 + ], + [ + "baaAC", + "aCAb", + 6 + ], + [ + "baaAaBB", + "ccABBac", + 12 + ], + [ + "baaAb", + "bAcBabC", + 8 + ], + [ + "baaAcA", + "B", + 11 + ], + [ + "baaBAA", + "CbabaCCAA", + 8 + ], + [ + "baaBAAabB", + "cCB", + 16 + ], + [ + "baaBBBb", + "aC", + 12 + ], + [ + "baaBabb", + "cAaB", + 9 + ], + [ + "baaBb", + "CBbaBAbC", + 9 + ], + [ + "baaBcaa", + "CcCCbb", + 13 + ], + [ + "baaCCcAB", + "cCA", + 11 + ], + [ + "baaCaac", + "aCAaCCbA", + 11 + ], + [ + "baaCbA", + "ccBAAcC", + 12 + ], + [ + "baaa", + "CaCbCb", + 10 + ], + [ + "baaa", + "bBbBAAC", + 10 + ], + [ + "baaaAc", + "CBBbBBB", + 13 + ], + [ + "baaaCA", + "aab", + 8 + ], + [ + "baaaaabB", + "BCbbccA", + 15 + ], + [ + "baaacac", + "ABa", + 11 + ], + [ + "baab", + "aABbABC", + 11 + ], + [ + "baabA", + "cACC", + 9 + ], + [ + "baabaBaab", + "aCcA", + 15 + ], + [ + "baac", + "ACBbca", + 10 + ], + [ + "baacACa", + "bccCB", + 8 + ], + [ + "baacBbA", + "AaaCCbaaA", + 9 + ], + [ + "baacCc", + "CACBAA", + 11 + ], + [ + "baacaCcb", + "BBbbbAaBA", + 16 + ], + [ + "baacabBAA", + "aaaaBaB", + 9 + ], + [ + "bab", + "Cc", + 6 + ], + [ + "bab", + "CcBC", + 7 + ], + [ + "bab", + "a", + 4 + ], + [ + "bab", + "aabbAaBca", + 13 + ], + [ + "babA", + "AB", + 6 + ], + [ + "babA", + "bCb", + 4 + ], + [ + "babA", + "cccABCc", + 12 + ], + [ + "babAAaBC", + "Cb", + 14 + ], + [ + "babAaAA", + "bc", + 12 + ], + [ + "babAaBA", + "BbcBAbC", + 10 + ], + [ + "babBBB", + "b", + 10 + ], + [ + "babBa", + "BB", + 7 + ], + [ + "babBbAbAC", + "CbabB", + 12 + ], + [ + "babC", + "BCB", + 6 + ], + [ + "babC", + "CABB", + 6 + ], + [ + "babCABaa", + "BbcCAab", + 9 + ], + [ + "babCB", + "bcCCaABBC", + 12 + ], + [ + "babCBb", + "AAcbb", + 7 + ], + [ + "babCCCc", + "cCAbbca", + 12 + ], + [ + "babCCa", + "c", + 11 + ], + [ + "babCabCab", + "caac", + 13 + ], + [ + "babCbcc", + "AaAAcA", + 10 + ], + [ + "baba", + "abBcbAc", + 9 + ], + [ + "babaBA", + "CbcBbBabB", + 11 + ], + [ + "babaC", + "CbAaAA", + 8 + ], + [ + "babaCBaa", + "BbCa", + 9 + ], + [ + "babaa", + "C", + 10 + ], + [ + "babaaCBCC", + "BbaaAc", + 10 + ], + [ + "babb", + "AcB", + 6 + ], + [ + "babbA", + "BabaAAaB", + 9 + ], + [ + "babbCaaCB", + "cCaAAaBc", + 15 + ], + [ + "babbCbC", + "AA", + 13 + ], + [ + "babbCc", + "acbACaB", + 10 + ], + [ + "babbbbA", + "acA", + 10 + ], + [ + "babbcccAA", + "bAA", + 12 + ], + [ + "babcacA", + "c", + 12 + ], + [ + "bac", + "CBC", + 5 + ], + [ + "bac", + "CcBc", + 6 + ], + [ + "bac", + "Ccbca", + 8 + ], + [ + "bac", + "aacAc", + 6 + ], + [ + "bac", + "ba", + 2 + ], + [ + "bacABcBc", + "ABccc", + 8 + ], + [ + "bacAbca", + "aBCACc", + 9 + ], + [ + "bacBCbBb", + "ccAbcABA", + 12 + ], + [ + "bacBCc", + "cBcBB", + 8 + ], + [ + "bacBaBc", + "AcbcAcA", + 10 + ], + [ + "bacC", + "bbAbaCAB", + 11 + ], + [ + "bacCACCA", + "b", + 14 + ], + [ + "bacCAa", + "b", + 10 + ], + [ + "bacCCCccC", + "CCBbcacA", + 13 + ], + [ + "bacCbaBcB", + "Cab", + 13 + ], + [ + "bacCcBC", + "aBcbcccB", + 10 + ], + [ + "bacaCC", + "BAaAbcAC", + 10 + ], + [ + "bacaCcA", + "BcBAc", + 9 + ], + [ + "bacabaAA", + "AAACCBaC", + 13 + ], + [ + "bacacBa", + "BCAAaAA", + 11 + ], + [ + "bacbABaB", + "bCABBAc", + 10 + ], + [ + "bacbCAbbb", + "BaA", + 13 + ], + [ + "bacc", + "aAcAA", + 7 + ], + [ + "baccAA", + "C", + 11 + ], + [ + "baccAa", + "abCCB", + 9 + ], + [ + "baccBAA", + "ccCCbcCC", + 13 + ], + [ + "baccBBc", + "CAb", + 12 + ], + [ + "baccBbBaa", + "AbcaCcbb", + 12 + ], + [ + "baccCaCA", + "CAccb", + 11 + ], + [ + "baccaBc", + "AccABCbCC", + 11 + ], + [ + "baccccCB", + "cC", + 12 + ], + [ + "bb", + "A", + 4 + ], + [ + "bb", + "AABcCbCB", + 13 + ], + [ + "bb", + "AC", + 4 + ], + [ + "bb", + "Aabc", + 6 + ], + [ + "bb", + "AbC", + 4 + ], + [ + "bb", + "AbCC", + 6 + ], + [ + "bb", + "AbCCbbB", + 10 + ], + [ + "bb", + "Acaa", + 8 + ], + [ + "bb", + "B", + 3 + ], + [ + "bb", + "BAbcaB", + 9 + ], + [ + "bb", + "BCAC", + 7 + ], + [ + "bb", + "Bbccc", + 7 + ], + [ + "bb", + "CC", + 4 + ], + [ + "bb", + "a", + 4 + ], + [ + "bb", + "aBcCcc", + 11 + ], + [ + "bb", + "aaBBCc", + 10 + ], + [ + "bb", + "acCc", + 8 + ], + [ + "bb", + "accBa", + 9 + ], + [ + "bb", + "bA", + 2 + ], + [ + "bb", + "bAc", + 4 + ], + [ + "bb", + "bCbAcbaC", + 12 + ], + [ + "bb", + "baAB", + 5 + ], + [ + "bb", + "cAbBAbC", + 10 + ], + [ + "bb", + "cB", + 3 + ], + [ + "bb", + "cBC", + 5 + ], + [ + "bb", + "cbAacCaca", + 16 + ], + [ + "bb", + "cbBbABC", + 10 + ], + [ + "bbA", + "ABC", + 5 + ], + [ + "bbA", + "BBCabAA", + 9 + ], + [ + "bbA", + "BcCC", + 7 + ], + [ + "bbA", + "CB", + 5 + ], + [ + "bbA", + "bBbaababa", + 13 + ], + [ + "bbA", + "cCabBCAc", + 11 + ], + [ + "bbAA", + "B", + 7 + ], + [ + "bbAA", + "CC", + 8 + ], + [ + "bbAAaBb", + "AcC", + 12 + ], + [ + "bbAAb", + "BBBaaACAb", + 10 + ], + [ + "bbAAc", + "bBaCb", + 6 + ], + [ + "bbAAcAca", + "CCbBaccCB", + 12 + ], + [ + "bbAAcBca", + "bcA", + 11 + ], + [ + "bbAAcbCb", + "bAabCBAAC", + 12 + ], + [ + "bbAB", + "AaABCCB", + 10 + ], + [ + "bbAB", + "AbabABcC", + 8 + ], + [ + "bbAB", + "cBb", + 6 + ], + [ + "bbABACAbC", + "Ccabbc", + 13 + ], + [ + "bbABBC", + "CaAA", + 10 + ], + [ + "bbABCBA", + "ACb", + 9 + ], + [ + "bbABCBCbc", + "b", + 16 + ], + [ + "bbABab", + "CAcaba", + 8 + ], + [ + "bbABc", + "Bac", + 6 + ], + [ + "bbABcBBc", + "Aa", + 14 + ], + [ + "bbABcb", + "c", + 10 + ], + [ + "bbACABB", + "acC", + 12 + ], + [ + "bbACCcCbb", + "CCcC", + 10 + ], + [ + "bbAa", + "CbCaC", + 6 + ], + [ + "bbAa", + "cBcBBC", + 10 + ], + [ + "bbAaC", + "bBcCcAB", + 10 + ], + [ + "bbAaCaBAB", + "aabBc", + 13 + ], + [ + "bbAabBcca", + "BbaabB", + 8 + ], + [ + "bbAaccbAb", + "aCbBAAc", + 14 + ], + [ + "bbAb", + "B", + 7 + ], + [ + "bbAb", + "baaCABAa", + 11 + ], + [ + "bbAb", + "caAABCaac", + 15 + ], + [ + "bbAbAcaCA", + "cacab", + 13 + ], + [ + "bbAbB", + "ccAaCc", + 10 + ], + [ + "bbAbBc", + "AbcAbaBa", + 8 + ], + [ + "bbAbC", + "BBa", + 7 + ], + [ + "bbAbC", + "BcAcaCaaa", + 13 + ], + [ + "bbAbcBA", + "cAbbcBC", + 8 + ], + [ + "bbAc", + "bB", + 5 + ], + [ + "bbAcBabb", + "b", + 14 + ], + [ + "bbAcCaAC", + "CccacCABB", + 12 + ], + [ + "bbAcaA", + "caCabBaAB", + 13 + ], + [ + "bbAcabA", + "bBcbCb", + 9 + ], + [ + "bbB", + "Ac", + 6 + ], + [ + "bbB", + "aCbba", + 6 + ], + [ + "bbB", + "cAcbbBb", + 8 + ], + [ + "bbBA", + "B", + 6 + ], + [ + "bbBACc", + "AcCCBa", + 12 + ], + [ + "bbBAab", + "caAaBCbCb", + 14 + ], + [ + "bbBAbaa", + "aa", + 10 + ], + [ + "bbBBA", + "A", + 8 + ], + [ + "bbBBaaC", + "aCB", + 12 + ], + [ + "bbBBbc", + "ab", + 10 + ], + [ + "bbBCCCAbA", + "aAcCBBc", + 14 + ], + [ + "bbBCCaa", + "AACaAbAA", + 14 + ], + [ + "bbBCaaAC", + "bBAc", + 9 + ], + [ + "bbBCcbcbc", + "BBBaCcbBc", + 7 + ], + [ + "bbBa", + "BBcbc", + 7 + ], + [ + "bbBa", + "Cc", + 8 + ], + [ + "bbBaAcBaC", + "Bcc", + 13 + ], + [ + "bbBaCacbC", + "BAAaBcCa", + 13 + ], + [ + "bbBbA", + "Bbca", + 6 + ], + [ + "bbBbB", + "bBCaCbABa", + 11 + ], + [ + "bbBbBc", + "ABbBbc", + 5 + ], + [ + "bbBbCcBa", + "ba", + 12 + ], + [ + "bbBbaaaBB", + "C", + 18 + ], + [ + "bbBbabc", + "ABACBBacC", + 11 + ], + [ + "bbBbbcCA", + "AaabaCabb", + 15 + ], + [ + "bbBbc", + "Bab", + 7 + ], + [ + "bbBc", + "AaCcBCbCb", + 15 + ], + [ + "bbBcBCA", + "acaba", + 11 + ], + [ + "bbBcCc", + "BAc", + 8 + ], + [ + "bbBcab", + "cAabaC", + 10 + ], + [ + "bbBcbAba", + "b", + 14 + ], + [ + "bbBccBaCB", + "AcbAaCc", + 12 + ], + [ + "bbC", + "A", + 6 + ], + [ + "bbC", + "AAccbCBAA", + 14 + ], + [ + "bbC", + "BCAC", + 5 + ], + [ + "bbC", + "BacBCA", + 8 + ], + [ + "bbC", + "acBbCB", + 7 + ], + [ + "bbCAAb", + "aBAAcAc", + 9 + ], + [ + "bbCABbc", + "aCa", + 11 + ], + [ + "bbCACA", + "cBc", + 10 + ], + [ + "bbCAaBb", + "babcacCA", + 10 + ], + [ + "bbCAaa", + "cBaBbCa", + 11 + ], + [ + "bbCBCca", + "bC", + 10 + ], + [ + "bbCBacAB", + "aC", + 13 + ], + [ + "bbCBcBBcb", + "bCCCaa", + 13 + ], + [ + "bbCC", + "cAbBccA", + 9 + ], + [ + "bbCCAA", + "b", + 10 + ], + [ + "bbCCCBc", + "CCBAcbab", + 14 + ], + [ + "bbCCaccaA", + "ba", + 14 + ], + [ + "bbCCbBA", + "A", + 12 + ], + [ + "bbCCcABa", + "CBBbC", + 13 + ], + [ + "bbCCcCc", + "BbaabbaCc", + 11 + ], + [ + "bbCa", + "BC", + 5 + ], + [ + "bbCa", + "abBbA", + 6 + ], + [ + "bbCaAB", + "CCACcabAC", + 12 + ], + [ + "bbCaBabbC", + "CaBABbacC", + 10 + ], + [ + "bbCaaC", + "BbaBCcbCA", + 11 + ], + [ + "bbCaaCA", + "BcBBB", + 12 + ], + [ + "bbCabA", + "BaBBA", + 8 + ], + [ + "bbCabcAA", + "bc", + 12 + ], + [ + "bbCbAaBaA", + "CbAaAAc", + 9 + ], + [ + "bbCbCB", + "AaBB", + 9 + ], + [ + "bbCbaACb", + "Abbc", + 11 + ], + [ + "bbCbcaBA", + "AB", + 13 + ], + [ + "bbCc", + "aBaC", + 6 + ], + [ + "bbCcAA", + "ccaBAabBA", + 14 + ], + [ + "bbCcBaA", + "aAbCCabAb", + 11 + ], + [ + "bbCcaABc", + "a", + 14 + ], + [ + "bbCcc", + "BBAAA", + 8 + ], + [ + "bbCccBCCa", + "cacaCc", + 12 + ], + [ + "bba", + "ABBcccabc", + 14 + ], + [ + "bba", + "Bb", + 3 + ], + [ + "bba", + "C", + 6 + ], + [ + "bba", + "CBACA", + 8 + ], + [ + "bba", + "aCCAABCcb", + 17 + ], + [ + "bba", + "bbba", + 2 + ], + [ + "bbaA", + "CaCcCbb", + 14 + ], + [ + "bbaACCB", + "bAcAccABC", + 10 + ], + [ + "bbaAaaacc", + "CbaACB", + 11 + ], + [ + "bbaAcBA", + "cBbcaa", + 10 + ], + [ + "bbaB", + "Acc", + 8 + ], + [ + "bbaBAccC", + "cBBAb", + 11 + ], + [ + "bbaBBCc", + "C", + 12 + ], + [ + "bbaBCaAb", + "cCbA", + 12 + ], + [ + "bbaBaAc", + "cABCaA", + 9 + ], + [ + "bbaBbCbCb", + "aBccbBC", + 11 + ], + [ + "bbaBbaAbC", + "acaccca", + 15 + ], + [ + "bbaBc", + "bAbbCc", + 6 + ], + [ + "bbaCbCB", + "CCCA", + 10 + ], + [ + "bbaCbbC", + "c", + 13 + ], + [ + "bbaCc", + "CbCaBAaC", + 11 + ], + [ + "bbaCcBccb", + "C", + 16 + ], + [ + "bbab", + "ACB", + 7 + ], + [ + "bbab", + "CbbCbCbcC", + 12 + ], + [ + "bbabAbca", + "cBbbAB", + 10 + ], + [ + "bbabBcc", + "CAa", + 12 + ], + [ + "bbabC", + "abBAaAba", + 9 + ], + [ + "bbabC", + "cBb", + 7 + ], + [ + "bbabc", + "AAccbABAc", + 12 + ], + [ + "bbacC", + "aabaacA", + 8 + ], + [ + "bbacacb", + "acbCBaAcC", + 12 + ], + [ + "bbacccaa", + "AbBABACaa", + 9 + ], + [ + "bbb", + "ABC", + 5 + ], + [ + "bbb", + "C", + 6 + ], + [ + "bbb", + "aCBc", + 7 + ], + [ + "bbbA", + "bccbbcCCB", + 12 + ], + [ + "bbbABA", + "a", + 11 + ], + [ + "bbbACCCa", + "CBbcC", + 10 + ], + [ + "bbbAaBB", + "B", + 12 + ], + [ + "bbbAaCac", + "cCc", + 12 + ], + [ + "bbbAcbcC", + "aBBACacb", + 9 + ], + [ + "bbbB", + "ABAc", + 7 + ], + [ + "bbbB", + "AbABcABAB", + 12 + ], + [ + "bbbB", + "BB", + 5 + ], + [ + "bbbB", + "aC", + 8 + ], + [ + "bbbB", + "cCCcBcbCb", + 14 + ], + [ + "bbbBBBBCb", + "BcaBa", + 14 + ], + [ + "bbbBbA", + "bbA", + 6 + ], + [ + "bbbBbCBcB", + "bbcBcCC", + 9 + ], + [ + "bbbCa", + "CCB", + 8 + ], + [ + "bbbCccAA", + "bBAa", + 10 + ], + [ + "bbbaABaac", + "abaCbCB", + 13 + ], + [ + "bbbaAa", + "b", + 10 + ], + [ + "bbbaB", + "AC", + 9 + ], + [ + "bbbaa", + "CBBccC", + 10 + ], + [ + "bbbaaBba", + "Baa", + 11 + ], + [ + "bbbaacbb", + "cBbaC", + 10 + ], + [ + "bbbacBbBc", + "bcbcbCCC", + 10 + ], + [ + "bbbb", + "AbaACaC", + 12 + ], + [ + "bbbbbAB", + "aaAaCb", + 13 + ], + [ + "bbbbc", + "BBbC", + 5 + ], + [ + "bbbcAB", + "aBAbBBa", + 11 + ], + [ + "bbbcAcCAC", + "AaBbcCCcb", + 12 + ], + [ + "bbbcB", + "bcCc", + 6 + ], + [ + "bbbcBa", + "CAAccB", + 10 + ], + [ + "bbbcCB", + "aAbBABa", + 10 + ], + [ + "bbbca", + "cBbcabCC", + 9 + ], + [ + "bbbcbBAbc", + "AAacbcc", + 12 + ], + [ + "bbbcbcbc", + "Cbbaac", + 10 + ], + [ + "bbc", + "ACBaABaCC", + 15 + ], + [ + "bbc", + "BcCBaBcCc", + 14 + ], + [ + "bbc", + "CcB", + 6 + ], + [ + "bbc", + "bCCcBAac", + 11 + ], + [ + "bbc", + "c", + 4 + ], + [ + "bbcA", + "AAC", + 7 + ], + [ + "bbcACCca", + "bAABA", + 11 + ], + [ + "bbcAbBa", + "CaaA", + 11 + ], + [ + "bbcAbca", + "CCCCc", + 11 + ], + [ + "bbcAcbBab", + "CBacCca", + 12 + ], + [ + "bbcB", + "BaAbbccBb", + 10 + ], + [ + "bbcBAa", + "baaacc", + 10 + ], + [ + "bbcBCa", + "CaBabc", + 11 + ], + [ + "bbcCA", + "CAb", + 8 + ], + [ + "bbcCBACB", + "bcBBCaBc", + 10 + ], + [ + "bbcCBbAA", + "CcAc", + 12 + ], + [ + "bbcCC", + "BcbCc", + 6 + ], + [ + "bbcCCcB", + "b", + 12 + ], + [ + "bbca", + "AbbcaAcCa", + 10 + ], + [ + "bbca", + "acaBbbB", + 11 + ], + [ + "bbcaACCab", + "aACBab", + 8 + ], + [ + "bbcaAb", + "b", + 10 + ], + [ + "bbcaCab", + "B", + 13 + ], + [ + "bbcaaBCA", + "BCaaC", + 8 + ], + [ + "bbcaacCC", + "bCCcBACB", + 11 + ], + [ + "bbcab", + "bABaa", + 6 + ], + [ + "bbcabAB", + "BcC", + 11 + ], + [ + "bbcb", + "abAA", + 6 + ], + [ + "bbcbB", + "bCbAab", + 7 + ], + [ + "bbcbBccAa", + "bA", + 14 + ], + [ + "bbcbCcAB", + "cacaCCaBA", + 10 + ], + [ + "bbcc", + "B", + 7 + ], + [ + "bbcc", + "CcBBaABa", + 14 + ], + [ + "bbccAcBCB", + "CbacCAaB", + 11 + ], + [ + "bbccC", + "bac", + 6 + ], + [ + "bbccCa", + "baacc", + 7 + ], + [ + "bbccCcA", + "CbbbC", + 10 + ], + [ + "bbccaca", + "bb", + 10 + ], + [ + "bbccb", + "ABCA", + 8 + ], + [ + "bbccbB", + "Cbccbcb", + 5 + ], + [ + "bbccbBB", + "cbCB", + 8 + ], + [ + "bc", + "ACcCb", + 8 + ], + [ + "bc", + "Aa", + 4 + ], + [ + "bc", + "Ac", + 2 + ], + [ + "bc", + "BBAA", + 7 + ], + [ + "bc", + "BcA", + 3 + ], + [ + "bc", + "BcbBaCaCB", + 15 + ], + [ + "bc", + "CACcCBc", + 11 + ], + [ + "bc", + "CBBaAccB", + 13 + ], + [ + "bc", + "CaBa", + 7 + ], + [ + "bc", + "CcCaaABa", + 14 + ], + [ + "bc", + "a", + 4 + ], + [ + "bc", + "aAA", + 6 + ], + [ + "bc", + "aACBcB", + 9 + ], + [ + "bc", + "aBacc", + 7 + ], + [ + "bc", + "aBbAa", + 8 + ], + [ + "bc", + "acb", + 4 + ], + [ + "bc", + "b", + 2 + ], + [ + "bc", + "bA", + 2 + ], + [ + "bc", + "bBCcbA", + 8 + ], + [ + "bc", + "c", + 2 + ], + [ + "bc", + "cBb", + 5 + ], + [ + "bc", + "caaabc", + 8 + ], + [ + "bc", + "ccAB", + 6 + ], + [ + "bcA", + "ABbA", + 5 + ], + [ + "bcA", + "BBB", + 5 + ], + [ + "bcA", + "aabaAAB", + 10 + ], + [ + "bcA", + "acacbc", + 9 + ], + [ + "bcA", + "cbaACAB", + 9 + ], + [ + "bcAA", + "BaCc", + 7 + ], + [ + "bcAABAab", + "CB", + 13 + ], + [ + "bcAABbbBa", + "ABcccc", + 14 + ], + [ + "bcAABcb", + "c", + 12 + ], + [ + "bcAAbc", + "B", + 11 + ], + [ + "bcAB", + "a", + 7 + ], + [ + "bcAB", + "bcB", + 2 + ], + [ + "bcABAABcB", + "Cc", + 15 + ], + [ + "bcABAbBC", + "c", + 14 + ], + [ + "bcABAcB", + "bcCBCAbCa", + 9 + ], + [ + "bcAC", + "AAaC", + 5 + ], + [ + "bcACABab", + "c", + 14 + ], + [ + "bcACBbBaC", + "baaAbBbB", + 10 + ], + [ + "bcACa", + "bbaAcCBB", + 10 + ], + [ + "bcACbCa", + "aaaBBAbC", + 13 + ], + [ + "bcAa", + "BC", + 6 + ], + [ + "bcAa", + "b", + 6 + ], + [ + "bcAaAabA", + "abBB", + 13 + ], + [ + "bcAaBABA", + "CABac", + 10 + ], + [ + "bcAaBAaC", + "AaC", + 10 + ], + [ + "bcAaBCc", + "ca", + 10 + ], + [ + "bcAaaC", + "cbA", + 9 + ], + [ + "bcAabc", + "BAABb", + 7 + ], + [ + "bcAb", + "BcbbbA", + 7 + ], + [ + "bcAbAAAAb", + "abCBaAABc", + 11 + ], + [ + "bcAbACaB", + "cCaCAC", + 10 + ], + [ + "bcAbacAbc", + "BccaBBCbb", + 12 + ], + [ + "bcAc", + "BCBcaBCaB", + 13 + ], + [ + "bcAca", + "A", + 8 + ], + [ + "bcAcba", + "CcAc", + 6 + ], + [ + "bcAcbccB", + "Abbac", + 10 + ], + [ + "bcAccA", + "bbabbAcC", + 11 + ], + [ + "bcAccab", + "CCACcbcC", + 10 + ], + [ + "bcB", + "AaCbCccbb", + 13 + ], + [ + "bcB", + "BaAACbA", + 11 + ], + [ + "bcB", + "CAAABA", + 10 + ], + [ + "bcB", + "aaAaBccC", + 13 + ], + [ + "bcB", + "bAAAACCA", + 13 + ], + [ + "bcB", + "cAbcb", + 5 + ], + [ + "bcBA", + "bBBAb", + 4 + ], + [ + "bcBAAc", + "BccA", + 7 + ], + [ + "bcBACabcB", + "abBA", + 14 + ], + [ + "bcBAab", + "baaaBbcc", + 11 + ], + [ + "bcBAcAC", + "aCCC", + 10 + ], + [ + "bcBBC", + "c", + 8 + ], + [ + "bcBBCbAbA", + "bcCCb", + 10 + ], + [ + "bcBBaA", + "ABCBb", + 9 + ], + [ + "bcBBabABb", + "BcbaBBBCa", + 11 + ], + [ + "bcBBbB", + "bbbCC", + 8 + ], + [ + "bcBCAaaaB", + "CC", + 15 + ], + [ + "bcBCBC", + "aCB", + 8 + ], + [ + "bcBCCAB", + "ABCbc", + 10 + ], + [ + "bcBCCB", + "cAb", + 9 + ], + [ + "bcBCCcbA", + "c", + 14 + ], + [ + "bcBCa", + "CBccAbA", + 10 + ], + [ + "bcBa", + "abaBbcaba", + 11 + ], + [ + "bcBaBB", + "CB", + 9 + ], + [ + "bcBaCc", + "aaCBa", + 9 + ], + [ + "bcBaa", + "BcBB", + 5 + ], + [ + "bcBabcbc", + "accAbcB", + 8 + ], + [ + "bcBac", + "BB", + 7 + ], + [ + "bcBbAB", + "aCAbA", + 7 + ], + [ + "bcBbACCB", + "BAbcCc", + 10 + ], + [ + "bcBbACCac", + "CB", + 15 + ], + [ + "bcBbBCB", + "BcCbb", + 8 + ], + [ + "bcBbbAcac", + "ACbccac", + 9 + ], + [ + "bcBbc", + "caC", + 7 + ], + [ + "bcBc", + "A", + 8 + ], + [ + "bcBcaa", + "BbbCAaBB", + 10 + ], + [ + "bcBccBCBA", + "ABaCCAba", + 13 + ], + [ + "bcBccbcC", + "aC", + 14 + ], + [ + "bcC", + "ACabb", + 9 + ], + [ + "bcC", + "Ac", + 4 + ], + [ + "bcC", + "CACac", + 8 + ], + [ + "bcC", + "CAaCbCbb", + 13 + ], + [ + "bcC", + "CacBAbbac", + 15 + ], + [ + "bcC", + "a", + 6 + ], + [ + "bcC", + "abBBcB", + 8 + ], + [ + "bcC", + "acaAAaCbb", + 14 + ], + [ + "bcC", + "bBCaBBC", + 9 + ], + [ + "bcC", + "bbbCCABb", + 11 + ], + [ + "bcC", + "cBBBBCac", + 13 + ], + [ + "bcC", + "cCAAb", + 8 + ], + [ + "bcC", + "ccBcB", + 7 + ], + [ + "bcCAAA", + "CCCBbBAC", + 11 + ], + [ + "bcCAaA", + "AbCabC", + 9 + ], + [ + "bcCAb", + "CbBccBC", + 9 + ], + [ + "bcCAcAa", + "cB", + 12 + ], + [ + "bcCAcbC", + "AcAAbc", + 7 + ], + [ + "bcCB", + "a", + 8 + ], + [ + "bcCBAB", + "AaBAcB", + 8 + ], + [ + "bcCBBcb", + "CaCbaa", + 11 + ], + [ + "bcCBC", + "cb", + 7 + ], + [ + "bcCBaCAAc", + "aBb", + 16 + ], + [ + "bcCBaCb", + "aaaacC", + 11 + ], + [ + "bcCCAbB", + "BBcCAcA", + 8 + ], + [ + "bcCCa", + "BACbBaAcC", + 13 + ], + [ + "bcCCaa", + "cBcC", + 9 + ], + [ + "bcCCcbA", + "AAaAcCCA", + 12 + ], + [ + "bcCa", + "bCCC", + 3 + ], + [ + "bcCaaAB", + "cAAc", + 9 + ], + [ + "bcCaacC", + "BbcaccCCB", + 10 + ], + [ + "bcCab", + "BcCABbCAC", + 10 + ], + [ + "bcCacAA", + "CcbB", + 10 + ], + [ + "bcCacCaa", + "ABc", + 14 + ], + [ + "bcCacba", + "Bc", + 11 + ], + [ + "bcCb", + "aCbcBbCc", + 10 + ], + [ + "bcCbB", + "bAbCc", + 8 + ], + [ + "bcCbBCbaB", + "BC", + 14 + ], + [ + "bcCbaa", + "BbAACBAaC", + 10 + ], + [ + "bcCbbc", + "baAA", + 10 + ], + [ + "bcCc", + "AAA", + 8 + ], + [ + "bcCcBB", + "BaAccBC", + 8 + ], + [ + "bcCcaCCca", + "AaCc", + 12 + ], + [ + "bcCcbAAc", + "Ca", + 13 + ], + [ + "bca", + "AB", + 6 + ], + [ + "bca", + "AcaaBC", + 8 + ], + [ + "bca", + "CACBbcC", + 10 + ], + [ + "bca", + "bccb", + 4 + ], + [ + "bcaA", + "aBaCBBAa", + 12 + ], + [ + "bcaAAbCbC", + "CCcAA", + 13 + ], + [ + "bcaABAa", + "Ac", + 12 + ], + [ + "bcaACb", + "bAbCaCB", + 8 + ], + [ + "bcaAa", + "BbCcc", + 9 + ], + [ + "bcaAaaAC", + "acaaABc", + 8 + ], + [ + "bcaAba", + "BabBAaccb", + 14 + ], + [ + "bcaB", + "bCBCBAA", + 9 + ], + [ + "bcaBBAC", + "Cb", + 12 + ], + [ + "bcaCA", + "ACA", + 5 + ], + [ + "bcaCA", + "aB", + 8 + ], + [ + "bcaCAABcB", + "bBAbCcbc", + 12 + ], + [ + "bcaCB", + "AbaACbaC", + 10 + ], + [ + "bcaCBa", + "BaAbAB", + 9 + ], + [ + "bcaCa", + "cCbccbA", + 9 + ], + [ + "bcaCbBA", + "bcBabAb", + 8 + ], + [ + "bcaCbCbaA", + "bbCBb", + 11 + ], + [ + "bcaCcB", + "cAab", + 8 + ], + [ + "bcaa", + "CC", + 7 + ], + [ + "bcaa", + "aaBA", + 7 + ], + [ + "bcaaA", + "BAAacaAba", + 11 + ], + [ + "bcaaABBA", + "baa", + 10 + ], + [ + "bcaaAcbC", + "aBACAcaab", + 13 + ], + [ + "bcaaBaAb", + "b", + 14 + ], + [ + "bcaacb", + "acCb", + 7 + ], + [ + "bcab", + "a", + 6 + ], + [ + "bcab", + "cCAabCBCb", + 13 + ], + [ + "bcabAA", + "BAAcca", + 9 + ], + [ + "bcabC", + "Aac", + 7 + ], + [ + "bcabb", + "aAaA", + 8 + ], + [ + "bcac", + "CCAAbCbC", + 12 + ], + [ + "bcb", + "A", + 6 + ], + [ + "bcb", + "aBabCcB", + 9 + ], + [ + "bcb", + "abACACc", + 11 + ], + [ + "bcbA", + "AcbAcbCaB", + 11 + ], + [ + "bcbAAA", + "a", + 11 + ], + [ + "bcbAAAB", + "a", + 13 + ], + [ + "bcbACB", + "CBbcbCca", + 9 + ], + [ + "bcbACCA", + "AabaACAcB", + 11 + ], + [ + "bcbACCC", + "c", + 12 + ], + [ + "bcbAbCbB", + "caA", + 12 + ], + [ + "bcbAc", + "BACCccbCb", + 13 + ], + [ + "bcbBA", + "baaaa", + 7 + ], + [ + "bcbBAABCa", + "cBAcaa", + 10 + ], + [ + "bcbCAaAC", + "bB", + 13 + ], + [ + "bcbCAc", + "caccbaABC", + 11 + ], + [ + "bcbCB", + "c", + 8 + ], + [ + "bcbCcCa", + "CCCbACb", + 11 + ], + [ + "bcbaAACb", + "aBAcA", + 11 + ], + [ + "bcbaBBB", + "AA", + 13 + ], + [ + "bcbaccb", + "ACACCB", + 9 + ], + [ + "bcbb", + "cBcACA", + 9 + ], + [ + "bcbb", + "cCCBaaA", + 12 + ], + [ + "bcbbABC", + "CAAaa", + 11 + ], + [ + "bcbbB", + "ABB", + 7 + ], + [ + "bcbbBc", + "cCc", + 8 + ], + [ + "bcbbCBabA", + "cCccbccBA", + 12 + ], + [ + "bcbc", + "AAA", + 8 + ], + [ + "bcbc", + "Ca", + 7 + ], + [ + "bcbcAC", + "bBAaaacb", + 12 + ], + [ + "bcc", + "C", + 5 + ], + [ + "bcc", + "CaACa", + 9 + ], + [ + "bcc", + "bACb", + 5 + ], + [ + "bcc", + "bbcCcAa", + 8 + ], + [ + "bccA", + "C", + 7 + ], + [ + "bccA", + "aAb", + 8 + ], + [ + "bccA", + "ab", + 8 + ], + [ + "bccABAba", + "acacC", + 13 + ], + [ + "bccAC", + "BbbBcA", + 8 + ], + [ + "bccAbaA", + "aAc", + 12 + ], + [ + "bccAbcbcb", + "CbbcbbA", + 11 + ], + [ + "bccB", + "BcacaCB", + 7 + ], + [ + "bccB", + "cAcb", + 5 + ], + [ + "bccBABc", + "bAacbb", + 10 + ], + [ + "bccBBB", + "aAbbbbC", + 11 + ], + [ + "bccBBCbBa", + "bbbaabCbB", + 11 + ], + [ + "bccBBc", + "cCcbac", + 6 + ], + [ + "bccBBccA", + "bB", + 12 + ], + [ + "bccBCCAC", + "bABBCAabC", + 9 + ], + [ + "bccBCCBc", + "ACBaa", + 13 + ], + [ + "bccBa", + "CAcbB", + 7 + ], + [ + "bccBbA", + "aBCcBBBC", + 9 + ], + [ + "bccCA", + "BaBAAba", + 11 + ], + [ + "bccCAbbB", + "ccC", + 10 + ], + [ + "bccCBab", + "c", + 12 + ], + [ + "bccCCAaBB", + "bBa", + 14 + ], + [ + "bccCaBCC", + "Bb", + 14 + ], + [ + "bcca", + "AaAaabA", + 12 + ], + [ + "bccaCBb", + "bAbcabA", + 9 + ], + [ + "bccaCCC", + "CCBCBbAAA", + 16 + ], + [ + "bccaa", + "C", + 9 + ], + [ + "bccaab", + "cAcc", + 9 + ], + [ + "bccbAbab", + "b", + 14 + ], + [ + "bccbBCcCA", + "B", + 16 + ], + [ + "bccbBb", + "ccba", + 6 + ], + [ + "bccbC", + "bBC", + 5 + ], + [ + "bccbbCC", + "bBccA", + 9 + ], + [ + "bccbbbCB", + "BbcABC", + 10 + ], + [ + "bccbccAc", + "bBC", + 12 + ], + [ + "bccc", + "ACcca", + 5 + ], + [ + "bcccAA", + "bCBAbca", + 10 + ], + [ + "bcccAaBca", + "BaC", + 14 + ], + [ + "bcccBBCaA", + "bcAcaCcb", + 10 + ], + [ + "bcccC", + "aAAaa", + 10 + ], + [ + "bcccCCCbc", + "Bac", + 15 + ], + [ + "c", + "A", + 2 + ], + [ + "c", + "AA", + 4 + ], + [ + "c", + "AABacBC", + 12 + ], + [ + "c", + "AAbBBaBB", + 16 + ], + [ + "c", + "AB", + 4 + ], + [ + "c", + "ABA", + 6 + ], + [ + "c", + "ABBaCCBBB", + 17 + ], + [ + "c", + "ABBbBBCBA", + 17 + ], + [ + "c", + "ABbCb", + 9 + ], + [ + "c", + "ABbaaba", + 14 + ], + [ + "c", + "AC", + 3 + ], + [ + "c", + "ACABa", + 9 + ], + [ + "c", + "ACCB", + 7 + ], + [ + "c", + "ACCcbCCbC", + 16 + ], + [ + "c", + "ACbBBC", + 11 + ], + [ + "c", + "Aa", + 4 + ], + [ + "c", + "AaABA", + 10 + ], + [ + "c", + "Aaa", + 6 + ], + [ + "c", + "AaaaBbBC", + 15 + ], + [ + "c", + "AaabCAb", + 13 + ], + [ + "c", + "Ab", + 4 + ], + [ + "c", + "AbaCAAA", + 13 + ], + [ + "c", + "AcCACaAA", + 14 + ], + [ + "c", + "AcCCBAcaB", + 16 + ], + [ + "c", + "Acb", + 4 + ], + [ + "c", + "AcccbCacB", + 16 + ], + [ + "c", + "B", + 2 + ], + [ + "c", + "BA", + 4 + ], + [ + "c", + "BAAAAbB", + 14 + ], + [ + "c", + "BACA", + 7 + ], + [ + "c", + "BACbAC", + 11 + ], + [ + "c", + "BAbBbAc", + 12 + ], + [ + "c", + "BAbb", + 8 + ], + [ + "c", + "BAcBb", + 8 + ], + [ + "c", + "BB", + 4 + ], + [ + "c", + "BBAACAb", + 13 + ], + [ + "c", + "BBABBC", + 11 + ], + [ + "c", + "BBBcBccc", + 14 + ], + [ + "c", + "BBbbc", + 8 + ], + [ + "c", + "BBbcbbac", + 14 + ], + [ + "c", + "BBcBc", + 8 + ], + [ + "c", + "BC", + 3 + ], + [ + "c", + "BCA", + 5 + ], + [ + "c", + "BCAAcBC", + 12 + ], + [ + "c", + "BCAbCb", + 11 + ], + [ + "c", + "BCBc", + 6 + ], + [ + "c", + "BCa", + 5 + ], + [ + "c", + "BCcbaB", + 10 + ], + [ + "c", + "Ba", + 4 + ], + [ + "c", + "BaAaaA", + 12 + ], + [ + "c", + "BaBacca", + 12 + ], + [ + "c", + "BaCCBaCAC", + 17 + ], + [ + "c", + "BaaBcAcBb", + 16 + ], + [ + "c", + "BaaccC", + 10 + ], + [ + "c", + "BabCcAAcA", + 16 + ], + [ + "c", + "BbABABaBC", + 17 + ], + [ + "c", + "BbCa", + 7 + ], + [ + "c", + "BbaAacbb", + 14 + ], + [ + "c", + "BbaCAAcBa", + 16 + ], + [ + "c", + "BbcBb", + 8 + ], + [ + "c", + "Bbcc", + 6 + ], + [ + "c", + "Bc", + 2 + ], + [ + "c", + "BcBa", + 6 + ], + [ + "c", + "Bcb", + 4 + ], + [ + "c", + "Bcccb", + 8 + ], + [ + "c", + "C", + 1 + ], + [ + "c", + "CB", + 3 + ], + [ + "c", + "CBABBC", + 11 + ], + [ + "c", + "CBAcCA", + 10 + ], + [ + "c", + "CBBAbbA", + 13 + ], + [ + "c", + "CBCBb", + 9 + ], + [ + "c", + "CBCaBa", + 11 + ], + [ + "c", + "CBb", + 5 + ], + [ + "c", + "CCCBaaCB", + 15 + ], + [ + "c", + "CCCCCC", + 11 + ], + [ + "c", + "Ca", + 3 + ], + [ + "c", + "CaAb", + 7 + ], + [ + "c", + "CaCa", + 7 + ], + [ + "c", + "Cab", + 5 + ], + [ + "c", + "CabC", + 7 + ], + [ + "c", + "CbAC", + 7 + ], + [ + "c", + "CbabCAaAc", + 16 + ], + [ + "c", + "CcAABA", + 10 + ], + [ + "c", + "CccaaAa", + 12 + ], + [ + "c", + "a", + 2 + ], + [ + "c", + "aAAa", + 8 + ], + [ + "c", + "aAAc", + 6 + ], + [ + "c", + "aACbcB", + 10 + ], + [ + "c", + "aAbACcCA", + 14 + ], + [ + "c", + "aAbab", + 10 + ], + [ + "c", + "aB", + 4 + ], + [ + "c", + "aBAC", + 7 + ], + [ + "c", + "aBBbbc", + 10 + ], + [ + "c", + "aBaaA", + 10 + ], + [ + "c", + "aBb", + 6 + ], + [ + "c", + "aBcABcCCb", + 16 + ], + [ + "c", + "aBcBBCBbc", + 16 + ], + [ + "c", + "aCa", + 5 + ], + [ + "c", + "aa", + 4 + ], + [ + "c", + "aaCBCbC", + 13 + ], + [ + "c", + "aabcBAAcc", + 16 + ], + [ + "c", + "aabcBcA", + 12 + ], + [ + "c", + "aacABB", + 10 + ], + [ + "c", + "aacb", + 6 + ], + [ + "c", + "aaccAca", + 12 + ], + [ + "c", + "ab", + 4 + ], + [ + "c", + "abAa", + 8 + ], + [ + "c", + "abCAcC", + 10 + ], + [ + "c", + "abCCAB", + 11 + ], + [ + "c", + "abCc", + 6 + ], + [ + "c", + "ac", + 2 + ], + [ + "c", + "accbaBBAB", + 16 + ], + [ + "c", + "b", + 2 + ], + [ + "c", + "bAAccBAa", + 14 + ], + [ + "c", + "bAaBAbcCc", + 16 + ], + [ + "c", + "bAcacAbb", + 14 + ], + [ + "c", + "bBAaCa", + 11 + ], + [ + "c", + "bBAcaCaca", + 16 + ], + [ + "c", + "bBBCbaB", + 13 + ], + [ + "c", + "bBBa", + 8 + ], + [ + "c", + "bBab", + 8 + ], + [ + "c", + "bBcCbcABC", + 16 + ], + [ + "c", + "bBcCca", + 10 + ], + [ + "c", + "bCBC", + 7 + ], + [ + "c", + "bCC", + 5 + ], + [ + "c", + "bCCAbcBBa", + 16 + ], + [ + "c", + "bCCa", + 7 + ], + [ + "c", + "bCabaBC", + 13 + ], + [ + "c", + "bCc", + 4 + ], + [ + "c", + "bCcA", + 6 + ], + [ + "c", + "baaAB", + 10 + ], + [ + "c", + "baaABBC", + 13 + ], + [ + "c", + "baaAccba", + 14 + ], + [ + "c", + "bbBbbBBa", + 16 + ], + [ + "c", + "bbCccAAC", + 14 + ], + [ + "c", + "bc", + 2 + ], + [ + "c", + "bcAbC", + 8 + ], + [ + "c", + "bcBAcAcB", + 14 + ], + [ + "c", + "bcbBbCcb", + 14 + ], + [ + "c", + "bccAAa", + 10 + ], + [ + "c", + "c", + 0 + ], + [ + "c", + "cAABBb", + 10 + ], + [ + "c", + "cAACa", + 8 + ], + [ + "c", + "cABc", + 6 + ], + [ + "c", + "cAaCBc", + 10 + ], + [ + "c", + "cAacbCCA", + 14 + ], + [ + "c", + "cBCCAbA", + 12 + ], + [ + "c", + "cBacAc", + 10 + ], + [ + "c", + "cBcCBb", + 10 + ], + [ + "c", + "cCAB", + 6 + ], + [ + "c", + "cCCbbBBcA", + 16 + ], + [ + "c", + "cCcaBbcba", + 16 + ], + [ + "c", + "ca", + 2 + ], + [ + "c", + "caC", + 4 + ], + [ + "c", + "caa", + 4 + ], + [ + "c", + "cabA", + 6 + ], + [ + "c", + "cb", + 2 + ], + [ + "c", + "cbCaBBab", + 14 + ], + [ + "c", + "cbCbAa", + 10 + ], + [ + "c", + "cbbBbCcC", + 14 + ], + [ + "c", + "cbcaAAC", + 12 + ], + [ + "c", + "cc", + 2 + ], + [ + "c", + "ccB", + 4 + ], + [ + "c", + "ccCBaBAC", + 14 + ], + [ + "c", + "ccc", + 4 + ], + [ + "cA", + "A", + 2 + ], + [ + "cA", + "AAbaCB", + 10 + ], + [ + "cA", + "AC", + 4 + ], + [ + "cA", + "Ac", + 4 + ], + [ + "cA", + "Acc", + 4 + ], + [ + "cA", + "BABCB", + 8 + ], + [ + "cA", + "BBc", + 6 + ], + [ + "cA", + "BaaBCbA", + 11 + ], + [ + "cA", + "Bbb", + 6 + ], + [ + "cA", + "BbbAAccB", + 14 + ], + [ + "cA", + "Bc", + 4 + ], + [ + "cA", + "C", + 3 + ], + [ + "cA", + "CAaCAABb", + 13 + ], + [ + "cA", + "CAaacAcc", + 12 + ], + [ + "cA", + "CbaAccc", + 11 + ], + [ + "cA", + "Cbbb", + 7 + ], + [ + "cA", + "CcC", + 4 + ], + [ + "cA", + "aB", + 4 + ], + [ + "cA", + "aC", + 4 + ], + [ + "cA", + "ab", + 4 + ], + [ + "cA", + "abAAcc", + 10 + ], + [ + "cA", + "abC", + 6 + ], + [ + "cA", + "bBCAbCa", + 11 + ], + [ + "cA", + "bCbbBCAC", + 13 + ], + [ + "cA", + "bCcCBcCA", + 12 + ], + [ + "cA", + "bcaCcbC", + 11 + ], + [ + "cA", + "cABaBCb", + 10 + ], + [ + "cA", + "cBaAB", + 6 + ], + [ + "cA", + "cCBababA", + 12 + ], + [ + "cA", + "ccCBbBab", + 13 + ], + [ + "cA", + "cca", + 3 + ], + [ + "cAA", + "AaaCaBcCb", + 16 + ], + [ + "cAA", + "AbBC", + 8 + ], + [ + "cAA", + "a", + 5 + ], + [ + "cAA", + "cb", + 4 + ], + [ + "cAAA", + "cBaC", + 5 + ], + [ + "cAAAA", + "bcA", + 8 + ], + [ + "cAAAC", + "aBAaCcCca", + 13 + ], + [ + "cAAAacbCB", + "BBaACbA", + 12 + ], + [ + "cAAAbabc", + "BCAacBCBc", + 10 + ], + [ + "cAAAbbc", + "AAbb", + 6 + ], + [ + "cAAAcB", + "bbAB", + 8 + ], + [ + "cAAB", + "ABCaCbCbC", + 15 + ], + [ + "cAAB", + "Aab", + 4 + ], + [ + "cAABaBAa", + "bAaBaBA", + 5 + ], + [ + "cAAC", + "CAB", + 5 + ], + [ + "cAACA", + "CaABCCbAb", + 10 + ], + [ + "cAACAC", + "BC", + 10 + ], + [ + "cAACaCc", + "AcabA", + 9 + ], + [ + "cAACb", + "BCAcca", + 8 + ], + [ + "cAACbABCc", + "CCbAB", + 9 + ], + [ + "cAACbb", + "aAaC", + 7 + ], + [ + "cAACcAA", + "bAaCcacb", + 8 + ], + [ + "cAAa", + "caABcbBAB", + 12 + ], + [ + "cAAaB", + "BBaAb", + 7 + ], + [ + "cAAaBAAA", + "aCb", + 14 + ], + [ + "cAAaCbCc", + "CC", + 12 + ], + [ + "cAAaba", + "bcb", + 10 + ], + [ + "cAAabcCCA", + "aAa", + 13 + ], + [ + "cAAbB", + "AAcaBaa", + 10 + ], + [ + "cAAbBA", + "caCcABAB", + 9 + ], + [ + "cAAbBBaCa", + "CabcB", + 12 + ], + [ + "cAAbC", + "BAbbb", + 6 + ], + [ + "cAAba", + "CCBAabaAB", + 10 + ], + [ + "cAAc", + "bCcCCB", + 10 + ], + [ + "cAAcABCcb", + "BCBB", + 13 + ], + [ + "cAAcB", + "ca", + 7 + ], + [ + "cAAcCCAc", + "Cb", + 14 + ], + [ + "cAAcaabB", + "A", + 14 + ], + [ + "cAAccaaB", + "BBbbAcBc", + 15 + ], + [ + "cAB", + "B", + 4 + ], + [ + "cAB", + "BCAAacb", + 10 + ], + [ + "cAB", + "CaCbCca", + 11 + ], + [ + "cAB", + "CbacbCcbB", + 14 + ], + [ + "cAB", + "b", + 5 + ], + [ + "cAB", + "baabbCA", + 12 + ], + [ + "cAB", + "cbbaBbCb", + 11 + ], + [ + "cAB", + "cccBBCBC", + 12 + ], + [ + "cAB", + "cccCCCCb", + 13 + ], + [ + "cABA", + "CA", + 5 + ], + [ + "cABAABc", + "acabCCb", + 11 + ], + [ + "cABABAACA", + "cBaBCcaa", + 10 + ], + [ + "cABAa", + "c", + 8 + ], + [ + "cABAcaBb", + "BCBaBCBc", + 11 + ], + [ + "cABBAaCac", + "aAacACCcc", + 10 + ], + [ + "cABBCaBbc", + "bBAaBcACC", + 13 + ], + [ + "cABBc", + "B", + 8 + ], + [ + "cABBcacb", + "bBcCcCAA", + 13 + ], + [ + "cABC", + "B", + 6 + ], + [ + "cABCAB", + "bAcb", + 8 + ], + [ + "cABCAc", + "cBCBa", + 6 + ], + [ + "cABCAca", + "ABaCCCbcc", + 12 + ], + [ + "cABCBbbCA", + "ABBccc", + 11 + ], + [ + "cABCa", + "CaA", + 7 + ], + [ + "cABaA", + "aAAbaBb", + 9 + ], + [ + "cABaAaA", + "BAB", + 10 + ], + [ + "cABaBAC", + "acCa", + 12 + ], + [ + "cABaCAbbA", + "A", + 16 + ], + [ + "cABac", + "BaCc", + 6 + ], + [ + "cABbACA", + "BbccCBCBc", + 15 + ], + [ + "cABba", + "AAC", + 8 + ], + [ + "cABc", + "AaccB", + 7 + ], + [ + "cABcABc", + "cAcBBca", + 6 + ], + [ + "cABcBcb", + "cbBCa", + 8 + ], + [ + "cABcb", + "Cac", + 6 + ], + [ + "cABcba", + "BAab", + 8 + ], + [ + "cAC", + "BCaCAbaCa", + 13 + ], + [ + "cAC", + "C", + 4 + ], + [ + "cAC", + "CABbA", + 7 + ], + [ + "cAC", + "CAcABbA", + 10 + ], + [ + "cAC", + "bAa", + 4 + ], + [ + "cAC", + "cBBac", + 6 + ], + [ + "cACAACCbc", + "CAcABb", + 10 + ], + [ + "cACABcACC", + "CAc", + 12 + ], + [ + "cACACbC", + "BbCcAa", + 11 + ], + [ + "cACAabC", + "BbcbBcAAa", + 14 + ], + [ + "cACBCaC", + "C", + 12 + ], + [ + "cACBCcCBb", + "bBaaBaCbC", + 14 + ], + [ + "cACBaaB", + "bccBcBaB", + 9 + ], + [ + "cACCBBcb", + "Ba", + 14 + ], + [ + "cACCaa", + "aBcCaab", + 7 + ], + [ + "cACCc", + "ccAa", + 7 + ], + [ + "cACa", + "aBBcB", + 9 + ], + [ + "cACa", + "cAbCCA", + 5 + ], + [ + "cACaB", + "cAbbaBB", + 6 + ], + [ + "cACac", + "cBCBbbbB", + 12 + ], + [ + "cACbCBB", + "bBbAC", + 12 + ], + [ + "cACbaCc", + "AacCACBaB", + 11 + ], + [ + "cACbaba", + "acAACBcCC", + 11 + ], + [ + "cACbbC", + "Cba", + 8 + ], + [ + "cACbbb", + "ccacBccbA", + 11 + ], + [ + "cACbcb", + "b", + 10 + ], + [ + "cACc", + "Cc", + 4 + ], + [ + "cACc", + "bAba", + 6 + ], + [ + "cACcA", + "Caccc", + 5 + ], + [ + "cACcAcc", + "bbB", + 14 + ], + [ + "cACca", + "acabb", + 9 + ], + [ + "cACcaA", + "bB", + 12 + ], + [ + "cACccAacA", + "bcCBabCc", + 14 + ], + [ + "cAa", + "BacbCAbcA", + 13 + ], + [ + "cAa", + "Bbcb", + 8 + ], + [ + "cAa", + "C", + 5 + ], + [ + "cAa", + "aCBcCAcc", + 12 + ], + [ + "cAa", + "aCacc", + 8 + ], + [ + "cAa", + "caBcA", + 6 + ], + [ + "cAa", + "cacAbaAb", + 10 + ], + [ + "cAa", + "ccccAcaBC", + 12 + ], + [ + "cAaA", + "CbbaAaba", + 10 + ], + [ + "cAaAA", + "CaCbcbab", + 13 + ], + [ + "cAaAA", + "acAc", + 7 + ], + [ + "cAaAABAcb", + "bAba", + 14 + ], + [ + "cAaACBaa", + "cbBabcaac", + 11 + ], + [ + "cAaACc", + "ccbBB", + 10 + ], + [ + "cAaAaaB", + "CBCbBccBa", + 15 + ], + [ + "cAaAc", + "ABCACcb", + 10 + ], + [ + "cAaB", + "C", + 7 + ], + [ + "cAaB", + "aBaBA", + 6 + ], + [ + "cAaBCBbAA", + "aAc", + 14 + ], + [ + "cAaBaA", + "a", + 10 + ], + [ + "cAaC", + "BcbAbbCb", + 10 + ], + [ + "cAaC", + "CbB", + 7 + ], + [ + "cAaCAc", + "ac", + 8 + ], + [ + "cAaCaAc", + "bBBBbaC", + 12 + ], + [ + "cAaCaC", + "ABBa", + 8 + ], + [ + "cAaCc", + "c", + 8 + ], + [ + "cAaaAAA", + "BBCAa", + 11 + ], + [ + "cAaaaBCA", + "AcABc", + 10 + ], + [ + "cAaaacAB", + "aAbCB", + 10 + ], + [ + "cAaaacaa", + "ABB", + 14 + ], + [ + "cAaacB", + "AaCBbACB", + 10 + ], + [ + "cAaaca", + "bAbbc", + 8 + ], + [ + "cAabACa", + "bcaabaaAb", + 9 + ], + [ + "cAabCA", + "CbACAAcb", + 11 + ], + [ + "cAaba", + "a", + 8 + ], + [ + "cAabcacaa", + "aA", + 15 + ], + [ + "cAacAaBBC", + "bBaBAbcaC", + 12 + ], + [ + "cAaca", + "AcacAA", + 7 + ], + [ + "cAaca", + "BcCcBBBA", + 13 + ], + [ + "cAacc", + "BBCaCA", + 9 + ], + [ + "cAacc", + "a", + 8 + ], + [ + "cAacccAb", + "ccbbBACA", + 13 + ], + [ + "cAb", + "B", + 5 + ], + [ + "cAb", + "BAbABAC", + 10 + ], + [ + "cAb", + "BBAAc", + 8 + ], + [ + "cAb", + "CBABCa", + 8 + ], + [ + "cAb", + "CbBBaA", + 10 + ], + [ + "cAb", + "caBACCa", + 10 + ], + [ + "cAbA", + "Cacc", + 6 + ], + [ + "cAbA", + "aAAACA", + 8 + ], + [ + "cAbABbab", + "aCA", + 13 + ], + [ + "cAbAC", + "BAAc", + 5 + ], + [ + "cAbACB", + "bAcCC", + 8 + ], + [ + "cAbACcCaa", + "cBa", + 13 + ], + [ + "cAbAb", + "acBC", + 9 + ], + [ + "cAbAbA", + "bACaC", + 9 + ], + [ + "cAbAbAAAa", + "A", + 16 + ], + [ + "cAbBB", + "AbaaC", + 8 + ], + [ + "cAbBaAAAA", + "BabaaBAa", + 9 + ], + [ + "cAbBaB", + "AcB", + 8 + ], + [ + "cAbaBbBC", + "a", + 14 + ], + [ + "cAbab", + "Ba", + 7 + ], + [ + "cAbabb", + "bC", + 10 + ], + [ + "cAbbB", + "aBBcaAA", + 13 + ], + [ + "cAbbBCAcB", + "aabbaC", + 11 + ], + [ + "cAbbBaca", + "CbCAcBaC", + 12 + ], + [ + "cAbbBbcC", + "CB", + 13 + ], + [ + "cAbbb", + "cCbaBAAAc", + 13 + ], + [ + "cAbcAcBA", + "AcA", + 10 + ], + [ + "cAbcaCccC", + "ABbAbbcB", + 12 + ], + [ + "cAbcbB", + "AAABaac", + 11 + ], + [ + "cAbccBCBc", + "AAACAcbAc", + 12 + ], + [ + "cAc", + "AbBCcaBB", + 13 + ], + [ + "cAc", + "BCCcCaBac", + 13 + ], + [ + "cAc", + "CB", + 5 + ], + [ + "cAc", + "bBb", + 6 + ], + [ + "cAc", + "bCaCaCb", + 11 + ], + [ + "cAc", + "bcb", + 6 + ], + [ + "cAc", + "cAAcaa", + 6 + ], + [ + "cAcA", + "CaaB", + 6 + ], + [ + "cAcAA", + "cbAcBbB", + 8 + ], + [ + "cAcABAAc", + "aABaBBc", + 9 + ], + [ + "cAcACcBb", + "cacbCccC", + 7 + ], + [ + "cAcAb", + "aBbAA", + 8 + ], + [ + "cAcAcAcCc", + "caaAAcbc", + 7 + ], + [ + "cAcAcCB", + "ccbcbBbC", + 10 + ], + [ + "cAcBBaBCb", + "C", + 16 + ], + [ + "cAcBCb", + "abCbAAB", + 11 + ], + [ + "cAcBCcBba", + "A", + 16 + ], + [ + "cAcBbA", + "aBabBACbB", + 13 + ], + [ + "cAcBbB", + "ABBcacBBA", + 10 + ], + [ + "cAcCAB", + "CBBbc", + 11 + ], + [ + "cAcCBCa", + "CCA", + 9 + ], + [ + "cAcCBcBBa", + "CacACBBBB", + 8 + ], + [ + "cAcCCBCBA", + "ccCcbcbc", + 8 + ], + [ + "cAcCbCcAB", + "caC", + 13 + ], + [ + "cAcCcbaaA", + "CcBaa", + 9 + ], + [ + "cAca", + "BAcbCbC", + 10 + ], + [ + "cAcaAa", + "caAAaab", + 7 + ], + [ + "cAcaBAAC", + "BBB", + 14 + ], + [ + "cAcaaa", + "BaBaBC", + 9 + ], + [ + "cAcaaca", + "aaCBA", + 10 + ], + [ + "cAcabCbCB", + "BacBcbABb", + 11 + ], + [ + "cAcabaB", + "Cc", + 11 + ], + [ + "cAcac", + "acbA", + 7 + ], + [ + "cAcbABCBB", + "aABc", + 12 + ], + [ + "cAcbBCBac", + "bCbAAacB", + 13 + ], + [ + "cAcbbccAc", + "AABAaBbCb", + 16 + ], + [ + "cAcc", + "aCa", + 6 + ], + [ + "cAcc", + "bCAAcaCC", + 10 + ], + [ + "cAcc", + "cc", + 4 + ], + [ + "cAccCB", + "aAABca", + 9 + ], + [ + "cAccaBCAb", + "BBcBCCAbb", + 12 + ], + [ + "cAccaaABa", + "bCAcB", + 13 + ], + [ + "cAcccAA", + "bCAb", + 11 + ], + [ + "cAcccaCaA", + "abaB", + 14 + ], + [ + "cAcccacab", + "BbCCbaB", + 13 + ], + [ + "cB", + "AbAB", + 6 + ], + [ + "cB", + "AbBbCA", + 10 + ], + [ + "cB", + "B", + 2 + ], + [ + "cB", + "BACbBc", + 9 + ], + [ + "cB", + "BAcB", + 4 + ], + [ + "cB", + "BBaBaaccC", + 16 + ], + [ + "cB", + "BcAaA", + 8 + ], + [ + "cB", + "C", + 3 + ], + [ + "cB", + "CAA", + 5 + ], + [ + "cB", + "CAAA", + 7 + ], + [ + "cB", + "CAacabCCC", + 15 + ], + [ + "cB", + "CBBB", + 5 + ], + [ + "cB", + "CCBCABaaA", + 15 + ], + [ + "cB", + "Cc", + 3 + ], + [ + "cB", + "CcBAc", + 6 + ], + [ + "cB", + "a", + 4 + ], + [ + "cB", + "aACCba", + 10 + ], + [ + "cB", + "aacbcC", + 9 + ], + [ + "cB", + "acaaAABB", + 12 + ], + [ + "cB", + "b", + 3 + ], + [ + "cB", + "ba", + 4 + ], + [ + "cB", + "baacB", + 6 + ], + [ + "cB", + "bc", + 4 + ], + [ + "cB", + "cABAbCBc", + 12 + ], + [ + "cB", + "cCAB", + 4 + ], + [ + "cB", + "caAAbbBC", + 12 + ], + [ + "cB", + "caBAAa", + 8 + ], + [ + "cBA", + "Ac", + 6 + ], + [ + "cBA", + "CB", + 3 + ], + [ + "cBA", + "a", + 5 + ], + [ + "cBA", + "ac", + 6 + ], + [ + "cBA", + "b", + 5 + ], + [ + "cBA", + "bbaBac", + 9 + ], + [ + "cBA", + "cAaabbab", + 12 + ], + [ + "cBAA", + "AAB", + 6 + ], + [ + "cBAA", + "aCabbA", + 8 + ], + [ + "cBAAB", + "CCa", + 8 + ], + [ + "cBAABa", + "bA", + 9 + ], + [ + "cBAABccc", + "caBcbAAa", + 13 + ], + [ + "cBAAbCcC", + "Bcc", + 11 + ], + [ + "cBAAcAbAC", + "bBaacb", + 10 + ], + [ + "cBAB", + "cBBcaCCb", + 10 + ], + [ + "cBABaBCc", + "BAABc", + 7 + ], + [ + "cBABaac", + "baCbbb", + 12 + ], + [ + "cBABbBAaA", + "c", + 16 + ], + [ + "cBABba", + "AaAccABac", + 12 + ], + [ + "cBABca", + "aBcB", + 7 + ], + [ + "cBACBAAcA", + "BBCbCCBb", + 13 + ], + [ + "cBACa", + "cbaabBBcA", + 12 + ], + [ + "cBACc", + "cBbBaCb", + 7 + ], + [ + "cBACcBBC", + "AbaaBbcC", + 11 + ], + [ + "cBACcbCaa", + "ab", + 15 + ], + [ + "cBAa", + "cCCBaAc", + 8 + ], + [ + "cBAaBcaB", + "b", + 15 + ], + [ + "cBAacbBa", + "aaBb", + 11 + ], + [ + "cBAbCaBA", + "ccaB", + 9 + ], + [ + "cBAba", + "B", + 8 + ], + [ + "cBAbaa", + "CaccCBA", + 12 + ], + [ + "cBAbb", + "ca", + 7 + ], + [ + "cBAbbCaCc", + "aaCA", + 13 + ], + [ + "cBAbca", + "aaACbA", + 9 + ], + [ + "cBAc", + "BA", + 4 + ], + [ + "cBAc", + "aCCcbbbcC", + 13 + ], + [ + "cBAcAb", + "BCabCbcc", + 13 + ], + [ + "cBAcAbaa", + "AAC", + 12 + ], + [ + "cBAcBBc", + "cCcaaa", + 10 + ], + [ + "cBAcCCb", + "cCcAc", + 9 + ], + [ + "cBAcb", + "CaAAACba", + 10 + ], + [ + "cBB", + "BacacBcCA", + 14 + ], + [ + "cBB", + "Bc", + 4 + ], + [ + "cBB", + "bAACA", + 10 + ], + [ + "cBB", + "bCbBBC", + 7 + ], + [ + "cBBA", + "AcAAcABa", + 11 + ], + [ + "cBBA", + "Cca", + 6 + ], + [ + "cBBABC", + "bCcbaAB", + 9 + ], + [ + "cBBABC", + "cCCcBcBc", + 9 + ], + [ + "cBBAac", + "CbbbcB", + 9 + ], + [ + "cBBBABBA", + "AAAbAAAB", + 13 + ], + [ + "cBBBCA", + "caacccAbA", + 13 + ], + [ + "cBBBCacAB", + "Accab", + 13 + ], + [ + "cBBBcbA", + "cB", + 10 + ], + [ + "cBBC", + "acaC", + 6 + ], + [ + "cBBCBaCbA", + "CBcBaAc", + 10 + ], + [ + "cBBCCAca", + "ABCcCa", + 8 + ], + [ + "cBBCb", + "cBBbaaC", + 8 + ], + [ + "cBBCbB", + "aCbBaCaB", + 8 + ], + [ + "cBBaBaAac", + "C", + 17 + ], + [ + "cBBaaCbBb", + "baCCBa", + 11 + ], + [ + "cBBabaAc", + "b", + 14 + ], + [ + "cBBac", + "ba", + 7 + ], + [ + "cBBacC", + "aBcCAC", + 8 + ], + [ + "cBBbAaabA", + "aaA", + 12 + ], + [ + "cBBbB", + "BCcAACb", + 11 + ], + [ + "cBBbBaBcA", + "bbCCCc", + 13 + ], + [ + "cBBbCbc", + "ACccCBaCB", + 13 + ], + [ + "cBBbbaBcb", + "Cc", + 15 + ], + [ + "cBBbbbb", + "acBbaBca", + 10 + ], + [ + "cBBbbcAC", + "bCaBbbcbB", + 9 + ], + [ + "cBBbbcacb", + "BcCcaaBA", + 13 + ], + [ + "cBBbca", + "BbA", + 7 + ], + [ + "cBBcAccA", + "AcbbAC", + 11 + ], + [ + "cBBcBb", + "BaCb", + 7 + ], + [ + "cBBcaBcB", + "Aa", + 14 + ], + [ + "cBBcbC", + "bcCBacb", + 8 + ], + [ + "cBC", + "cACacBc", + 9 + ], + [ + "cBC", + "cCa", + 4 + ], + [ + "cBCA", + "C", + 6 + ], + [ + "cBCACaCaC", + "ccBBBCaac", + 9 + ], + [ + "cBCAaac", + "cB", + 10 + ], + [ + "cBCAacA", + "aaAcA", + 8 + ], + [ + "cBCAcCccC", + "cbB", + 15 + ], + [ + "cBCAcbC", + "CcAbCbbaA", + 13 + ], + [ + "cBCB", + "bbabCAAbB", + 13 + ], + [ + "cBCBCbCa", + "bcCAaCCa", + 10 + ], + [ + "cBCBacA", + "AcbBaA", + 7 + ], + [ + "cBCBbCBa", + "c", + 14 + ], + [ + "cBCCABcC", + "Baa", + 13 + ], + [ + "cBCCB", + "a", + 10 + ], + [ + "cBCCBcaBa", + "AcAAba", + 13 + ], + [ + "cBCCC", + "A", + 10 + ], + [ + "cBCCcBc", + "ccaBCB", + 9 + ], + [ + "cBCaB", + "BBbAA", + 7 + ], + [ + "cBCab", + "aaABbC", + 10 + ], + [ + "cBCacA", + "abcbAbAa", + 11 + ], + [ + "cBCb", + "aCbCc", + 6 + ], + [ + "cBCb", + "b", + 6 + ], + [ + "cBCb", + "cAA", + 6 + ], + [ + "cBCbCAc", + "ACacAB", + 9 + ], + [ + "cBCbCca", + "aaB", + 13 + ], + [ + "cBCbabA", + "bbBbABB", + 9 + ], + [ + "cBCbbBBbc", + "aCaBBbbb", + 10 + ], + [ + "cBCbcCC", + "ACBbBBc", + 10 + ], + [ + "cBCc", + "AcaCBCb", + 8 + ], + [ + "cBCcAbcac", + "aBcac", + 10 + ], + [ + "cBCcbccaa", + "bBbCaBB", + 13 + ], + [ + "cBa", + "b", + 5 + ], + [ + "cBa", + "bAAaA", + 8 + ], + [ + "cBaAA", + "baaCbca", + 11 + ], + [ + "cBaAAB", + "BcbB", + 8 + ], + [ + "cBaAACacA", + "bBa", + 14 + ], + [ + "cBaABacb", + "ACb", + 11 + ], + [ + "cBaB", + "BabB", + 4 + ], + [ + "cBaB", + "CBBBC", + 5 + ], + [ + "cBaBBAB", + "B", + 12 + ], + [ + "cBaBBCc", + "BacCACa", + 10 + ], + [ + "cBaBaABBB", + "bcc", + 17 + ], + [ + "cBaBbCBC", + "cAAB", + 11 + ], + [ + "cBaBc", + "bbC", + 7 + ], + [ + "cBaC", + "BacB", + 5 + ], + [ + "cBaC", + "bA", + 6 + ], + [ + "cBaCA", + "CAcabbb", + 11 + ], + [ + "cBaCAbCC", + "B", + 14 + ], + [ + "cBaCAccbc", + "bbccAcCBB", + 10 + ], + [ + "cBaCCC", + "ab", + 10 + ], + [ + "cBaCaBC", + "Cb", + 11 + ], + [ + "cBaCab", + "BC", + 8 + ], + [ + "cBaa", + "BAab", + 5 + ], + [ + "cBaaA", + "Bb", + 8 + ], + [ + "cBaaCabBb", + "aCACcCbbb", + 11 + ], + [ + "cBaaaBBac", + "bcaAbBcC", + 10 + ], + [ + "cBaab", + "acAacAbCc", + 11 + ], + [ + "cBab", + "ACCAB", + 7 + ], + [ + "cBabB", + "C", + 9 + ], + [ + "cBabBCaca", + "C", + 16 + ], + [ + "cBabBcab", + "CbcAAAa", + 12 + ], + [ + "cBabCaA", + "aaAbAaac", + 10 + ], + [ + "cBabbBCBb", + "C", + 16 + ], + [ + "cBac", + "A", + 7 + ], + [ + "cBacCAB", + "B", + 12 + ], + [ + "cBacabC", + "aAAaB", + 10 + ], + [ + "cBacac", + "c", + 10 + ], + [ + "cBb", + "BbbA", + 5 + ], + [ + "cBb", + "CAbcC", + 7 + ], + [ + "cBb", + "acAB", + 5 + ], + [ + "cBbACBB", + "bCCCAbbC", + 12 + ], + [ + "cBbACC", + "ACa", + 8 + ], + [ + "cBbAcabB", + "aA", + 14 + ], + [ + "cBbC", + "abAabbbc", + 12 + ], + [ + "cBbCAACc", + "bBB", + 13 + ], + [ + "cBbCAB", + "cbCb", + 5 + ], + [ + "cBbCAa", + "cacaBBAb", + 11 + ], + [ + "cBbCAaA", + "AB", + 12 + ], + [ + "cBbCAb", + "bC", + 8 + ], + [ + "cBbCBAAA", + "AbBbc", + 12 + ], + [ + "cBbCCC", + "BCba", + 8 + ], + [ + "cBbCc", + "ccaCBA", + 8 + ], + [ + "cBbCccaC", + "bA", + 13 + ], + [ + "cBba", + "cb", + 4 + ], + [ + "cBbaACaa", + "cC", + 12 + ], + [ + "cBbaCbc", + "ccaaca", + 9 + ], + [ + "cBbaaac", + "b", + 12 + ], + [ + "cBbaab", + "BbbBcC", + 9 + ], + [ + "cBbaccBA", + "c", + 14 + ], + [ + "cBbb", + "CCcCaa", + 10 + ], + [ + "cBbb", + "abCb", + 5 + ], + [ + "cBbbA", + "A", + 8 + ], + [ + "cBbbA", + "B", + 8 + ], + [ + "cBbbBAAb", + "AAaa", + 13 + ], + [ + "cBbbBBacb", + "cCaCCcAac", + 14 + ], + [ + "cBbbBCaa", + "AaBc", + 13 + ], + [ + "cBbbCa", + "CB", + 9 + ], + [ + "cBbbcBB", + "bAACBBb", + 10 + ], + [ + "cBbcBaCBC", + "abA", + 15 + ], + [ + "cBbcCAC", + "b", + 12 + ], + [ + "cBbcCb", + "caBBbb", + 7 + ], + [ + "cBbcaBAAc", + "bB", + 14 + ], + [ + "cBbcbAAb", + "aba", + 13 + ], + [ + "cBbcbcBB", + "AccaA", + 12 + ], + [ + "cBbccCcc", + "aaCBabcBB", + 15 + ], + [ + "cBbccb", + "caaABcBb", + 9 + ], + [ + "cBc", + "BCaAAAbB", + 14 + ], + [ + "cBc", + "CAAC", + 6 + ], + [ + "cBc", + "aAc", + 4 + ], + [ + "cBc", + "aBaAAc", + 8 + ], + [ + "cBc", + "aabbAc", + 9 + ], + [ + "cBc", + "aac", + 4 + ], + [ + "cBc", + "c", + 4 + ], + [ + "cBcA", + "bC", + 6 + ], + [ + "cBcAAbbcb", + "BAbb", + 10 + ], + [ + "cBcACAA", + "a", + 13 + ], + [ + "cBcACb", + "Bc", + 8 + ], + [ + "cBcAaACbc", + "abbB", + 14 + ], + [ + "cBcBaaC", + "AbC", + 11 + ], + [ + "cBcBbCC", + "aBbCaba", + 11 + ], + [ + "cBcBbCbbA", + "cBa", + 13 + ], + [ + "cBcBbb", + "Acb", + 8 + ], + [ + "cBcCaaAcb", + "baccACCCc", + 13 + ], + [ + "cBcCbcCa", + "aCa", + 12 + ], + [ + "cBcCccaAa", + "BCaCCabbA", + 12 + ], + [ + "cBcaAaC", + "bACBCAB", + 12 + ], + [ + "cBcaAbBCb", + "baCbbaa", + 12 + ], + [ + "cBcaAbc", + "aa", + 11 + ], + [ + "cBcaAcaaA", + "CACbcC", + 14 + ], + [ + "cBcaBcBc", + "aBbBCACc", + 11 + ], + [ + "cBcaCcCA", + "Bcc", + 10 + ], + [ + "cBcabC", + "bAAAabb", + 10 + ], + [ + "cBcbACbBB", + "ACBc", + 12 + ], + [ + "cBcbBAbAC", + "A", + 16 + ], + [ + "cBcbC", + "AAbBcCa", + 10 + ], + [ + "cBcbcaCb", + "cCbcCB", + 6 + ], + [ + "cBcc", + "bAcAcaaba", + 14 + ], + [ + "cBcc", + "cacc", + 2 + ], + [ + "cBccaAac", + "aab", + 12 + ], + [ + "cBccaBCB", + "Caa", + 13 + ], + [ + "cBccacbCA", + "bBCBAca", + 11 + ], + [ + "cBccbc", + "CAbA", + 9 + ], + [ + "cBcccCAC", + "BA", + 12 + ], + [ + "cC", + "A", + 4 + ], + [ + "cC", + "ABCCCa", + 9 + ], + [ + "cC", + "AbAacCAc", + 12 + ], + [ + "cC", + "AccAAABc", + 13 + ], + [ + "cC", + "BBAabcC", + 10 + ], + [ + "cC", + "BBc", + 5 + ], + [ + "cC", + "BBcaACaA", + 12 + ], + [ + "cC", + "BCABBCAaC", + 15 + ], + [ + "cC", + "BaAbcaBc", + 13 + ], + [ + "cC", + "BaBaccb", + 11 + ], + [ + "cC", + "CBA", + 5 + ], + [ + "cC", + "CacCac", + 8 + ], + [ + "cC", + "CcACcacbB", + 14 + ], + [ + "cC", + "CcBbb", + 8 + ], + [ + "cC", + "aACbbCAB", + 13 + ], + [ + "cC", + "aBABCBbc", + 14 + ], + [ + "cC", + "aCCcAAca", + 13 + ], + [ + "cC", + "aaBaBbAA", + 16 + ], + [ + "cC", + "acAb", + 6 + ], + [ + "cC", + "b", + 4 + ], + [ + "cC", + "bA", + 4 + ], + [ + "cC", + "bACBaA", + 10 + ], + [ + "cC", + "bacAcbc", + 11 + ], + [ + "cC", + "bcaCBaB", + 10 + ], + [ + "cC", + "c", + 2 + ], + [ + "cC", + "cA", + 2 + ], + [ + "cC", + "cABAc", + 7 + ], + [ + "cC", + "cAbc", + 5 + ], + [ + "cC", + "cBA", + 4 + ], + [ + "cC", + "cBCAccaCb", + 14 + ], + [ + "cC", + "cabcBCB", + 10 + ], + [ + "cC", + "cccaBa", + 9 + ], + [ + "cCA", + "c", + 4 + ], + [ + "cCAABb", + "ACbaBC", + 7 + ], + [ + "cCAACb", + "bbC", + 10 + ], + [ + "cCAAacBb", + "a", + 14 + ], + [ + "cCAAc", + "ABbCcbBb", + 14 + ], + [ + "cCAAc", + "AC", + 7 + ], + [ + "cCAB", + "AAaCAABab", + 12 + ], + [ + "cCABbAb", + "Ab", + 10 + ], + [ + "cCABbaBaA", + "aacC", + 15 + ], + [ + "cCAC", + "bCbbbbAC", + 10 + ], + [ + "cCACAb", + "AbC", + 10 + ], + [ + "cCACCc", + "cccbAabc", + 9 + ], + [ + "cCACc", + "BbAcaB", + 9 + ], + [ + "cCAa", + "CBA", + 5 + ], + [ + "cCAaabBbA", + "bCCCcacb", + 13 + ], + [ + "cCAac", + "BBA", + 8 + ], + [ + "cCAacBCc", + "CCBBaA", + 11 + ], + [ + "cCAacCCbA", + "bCACCa", + 9 + ], + [ + "cCAbA", + "aBBcaccbA", + 11 + ], + [ + "cCAbABC", + "bbACCaACB", + 13 + ], + [ + "cCAbACcc", + "AbBAccbb", + 11 + ], + [ + "cCAbCacAA", + "BcABBAC", + 12 + ], + [ + "cCAbbaA", + "CcACabA", + 8 + ], + [ + "cCAbcA", + "BABABC", + 10 + ], + [ + "cCAcAcbaB", + "BccBaCC", + 13 + ], + [ + "cCAcCAB", + "bcccCbbab", + 11 + ], + [ + "cCAcaabBA", + "bBcbCCBa", + 13 + ], + [ + "cCAcbBBa", + "AaBca", + 10 + ], + [ + "cCAcbcB", + "c", + 12 + ], + [ + "cCB", + "BBCAbba", + 11 + ], + [ + "cCB", + "BCcab", + 7 + ], + [ + "cCB", + "CC", + 3 + ], + [ + "cCB", + "CbBa", + 5 + ], + [ + "cCB", + "a", + 6 + ], + [ + "cCB", + "aC", + 4 + ], + [ + "cCBA", + "abcA", + 6 + ], + [ + "cCBACb", + "abBccaC", + 11 + ], + [ + "cCBAbCCa", + "a", + 14 + ], + [ + "cCBAbaC", + "aAbaAa", + 10 + ], + [ + "cCBAcCB", + "CbaCB", + 6 + ], + [ + "cCBBAb", + "cBcaC", + 7 + ], + [ + "cCBBBc", + "Cc", + 8 + ], + [ + "cCBBaa", + "CBC", + 8 + ], + [ + "cCBCBAc", + "ABCBCBbCB", + 9 + ], + [ + "cCBCa", + "AcacaBCAc", + 10 + ], + [ + "cCBCbB", + "Cc", + 9 + ], + [ + "cCBCcbB", + "cCBaAaBc", + 8 + ], + [ + "cCBaAac", + "C", + 12 + ], + [ + "cCBaCc", + "CcbBBbB", + 10 + ], + [ + "cCBac", + "bb", + 9 + ], + [ + "cCBbAC", + "abAbC", + 8 + ], + [ + "cCBbAaabb", + "BCc", + 16 + ], + [ + "cCBbAcCAC", + "acBCCbA", + 12 + ], + [ + "cCBbAccB", + "abA", + 12 + ], + [ + "cCBbbB", + "bbaaCCBbB", + 11 + ], + [ + "cCBc", + "ABbacCc", + 10 + ], + [ + "cCBc", + "cAcBb", + 5 + ], + [ + "cCBcABc", + "ac", + 11 + ], + [ + "cCBcACBa", + "cACcB", + 10 + ], + [ + "cCBcACCa", + "BACAAaa", + 11 + ], + [ + "cCBca", + "cbCacC", + 6 + ], + [ + "cCBcb", + "BCbAABAba", + 12 + ], + [ + "cCBcbCaCb", + "cbBCa", + 10 + ], + [ + "cCC", + "BbacaAb", + 12 + ], + [ + "cCC", + "CB", + 4 + ], + [ + "cCC", + "accaCCCcb", + 12 + ], + [ + "cCC", + "bAbcCcbcb", + 13 + ], + [ + "cCC", + "bB", + 6 + ], + [ + "cCC", + "bCBbABBCc", + 14 + ], + [ + "cCC", + "baAAb", + 10 + ], + [ + "cCC", + "cABBc", + 7 + ], + [ + "cCC", + "cCCbaac", + 8 + ], + [ + "cCCAbbbaa", + "BccccA", + 15 + ], + [ + "cCCAc", + "ccAbbb", + 9 + ], + [ + "cCCBBaBC", + "bcaA", + 13 + ], + [ + "cCCBCAaA", + "baB", + 13 + ], + [ + "cCCBc", + "bAccaAcB", + 11 + ], + [ + "cCCCC", + "cBC", + 6 + ], + [ + "cCCCaA", + "cCbB", + 8 + ], + [ + "cCCCaac", + "BCAcCb", + 11 + ], + [ + "cCCCbA", + "CcBBBBb", + 11 + ], + [ + "cCCCbb", + "ABccCcA", + 10 + ], + [ + "cCCCbbbAa", + "cA", + 14 + ], + [ + "cCCa", + "AccBc", + 7 + ], + [ + "cCCaA", + "BcACCA", + 6 + ], + [ + "cCCaAAAC", + "aBbcC", + 12 + ], + [ + "cCCaCB", + "CaaAcbCAB", + 12 + ], + [ + "cCCaccA", + "bc", + 12 + ], + [ + "cCCaccAC", + "abAACcCa", + 12 + ], + [ + "cCCb", + "C", + 6 + ], + [ + "cCCb", + "cAcBa", + 6 + ], + [ + "cCCbBCBab", + "CCcaca", + 11 + ], + [ + "cCCbb", + "BCBbbcA", + 8 + ], + [ + "cCCbc", + "bCCC", + 5 + ], + [ + "cCCbcbabA", + "aaCCc", + 14 + ], + [ + "cCCcABBB", + "aBBbABcb", + 11 + ], + [ + "cCCcCCcAa", + "bBCab", + 15 + ], + [ + "cCCcaaC", + "aBC", + 10 + ], + [ + "cCa", + "BacAaCAcA", + 13 + ], + [ + "cCa", + "C", + 4 + ], + [ + "cCa", + "CAACAAaC", + 11 + ], + [ + "cCa", + "aBBcbc", + 10 + ], + [ + "cCa", + "aCBab", + 6 + ], + [ + "cCa", + "aaCCAAAb", + 12 + ], + [ + "cCa", + "bBAcCcB", + 10 + ], + [ + "cCa", + "cBBcaCB", + 9 + ], + [ + "cCaA", + "CCaca", + 4 + ], + [ + "cCaA", + "cBcccC", + 9 + ], + [ + "cCaAAACA", + "cBBbacc", + 12 + ], + [ + "cCaAAacCc", + "cbCaBcA", + 12 + ], + [ + "cCaABCAAA", + "A", + 16 + ], + [ + "cCaAb", + "aBaAB", + 5 + ], + [ + "cCaAbAABA", + "CCabcAAbb", + 8 + ], + [ + "cCaAc", + "ABAbbBBB", + 15 + ], + [ + "cCaAcACaa", + "caaBcBc", + 11 + ], + [ + "cCaAcCBca", + "ABcc", + 12 + ], + [ + "cCaAcbA", + "aBCBcCCba", + 12 + ], + [ + "cCaB", + "ABABAbBBc", + 15 + ], + [ + "cCaBBaAb", + "aA", + 12 + ], + [ + "cCaBBaCAC", + "bC", + 15 + ], + [ + "cCaBBba", + "aa", + 10 + ], + [ + "cCaBCbb", + "BcaCB", + 8 + ], + [ + "cCaBb", + "Ac", + 9 + ], + [ + "cCaC", + "AC", + 5 + ], + [ + "cCaCA", + "BBBbbCAC", + 12 + ], + [ + "cCaCBBBCb", + "B", + 16 + ], + [ + "cCaCCB", + "BcBac", + 9 + ], + [ + "cCaCaB", + "AbcA", + 10 + ], + [ + "cCaCaaaA", + "abcCcc", + 14 + ], + [ + "cCaCc", + "aA", + 8 + ], + [ + "cCaa", + "CcCbcbA", + 9 + ], + [ + "cCaaBCb", + "A", + 13 + ], + [ + "cCaab", + "a", + 8 + ], + [ + "cCabB", + "AbbA", + 8 + ], + [ + "cCabB", + "AcaaACCb", + 11 + ], + [ + "cCabC", + "aBcB", + 8 + ], + [ + "cCabaBC", + "aB", + 10 + ], + [ + "cCabc", + "cabcccAB", + 10 + ], + [ + "cCabcBa", + "abccAaAB", + 12 + ], + [ + "cCac", + "AacBAaA", + 10 + ], + [ + "cCacacaa", + "CACbAbcC", + 13 + ], + [ + "cCacba", + "aAbAbBAc", + 13 + ], + [ + "cCb", + "AccbcbcB", + 11 + ], + [ + "cCb", + "BaC", + 6 + ], + [ + "cCb", + "BabCcAA", + 12 + ], + [ + "cCb", + "aCaBbBbC", + 12 + ], + [ + "cCb", + "accCcBAbA", + 12 + ], + [ + "cCb", + "cC", + 2 + ], + [ + "cCbAB", + "bcaac", + 8 + ], + [ + "cCbAB", + "cca", + 6 + ], + [ + "cCbAc", + "baB", + 7 + ], + [ + "cCbAcaB", + "AaBB", + 10 + ], + [ + "cCbBAc", + "bbBBBCa", + 10 + ], + [ + "cCbBBAbC", + "BCa", + 13 + ], + [ + "cCbBa", + "AAcCCaAB", + 11 + ], + [ + "cCbBacc", + "aBAbCAc", + 11 + ], + [ + "cCbBb", + "aacaBa", + 9 + ], + [ + "cCbBb", + "baAAacaCA", + 17 + ], + [ + "cCbBbc", + "acaAbC", + 8 + ], + [ + "cCbC", + "B", + 7 + ], + [ + "cCbC", + "CcBaA", + 7 + ], + [ + "cCbC", + "aC", + 6 + ], + [ + "cCbCCbCaA", + "acBBbCcC", + 12 + ], + [ + "cCbCaCBa", + "aBBAAbaA", + 13 + ], + [ + "cCbCac", + "CBAB", + 8 + ], + [ + "cCbCcaCc", + "cAbbAab", + 10 + ], + [ + "cCbCcbcbA", + "cbb", + 12 + ], + [ + "cCbaACaB", + "AB", + 12 + ], + [ + "cCbaAcaa", + "BCcCcb", + 12 + ], + [ + "cCbaB", + "aCCbc", + 7 + ], + [ + "cCbbAaaba", + "CccBCA", + 14 + ], + [ + "cCbbAbBC", + "acaAcBC", + 9 + ], + [ + "cCbbBC", + "bca", + 10 + ], + [ + "cCbbCB", + "AaBb", + 9 + ], + [ + "cCbbCBc", + "aBBAbba", + 12 + ], + [ + "cCbbCaA", + "A", + 12 + ], + [ + "cCbbabAC", + "B", + 15 + ], + [ + "cCbbccCb", + "bAcCc", + 10 + ], + [ + "cCbcABAa", + "ABaACa", + 11 + ], + [ + "cCbcB", + "bBBcbbA", + 10 + ], + [ + "cCbcbc", + "Aa", + 12 + ], + [ + "cCbccbB", + "abaaBc", + 11 + ], + [ + "cCbccbbaC", + "aCBAcBB", + 11 + ], + [ + "cCc", + "ABcAcB", + 8 + ], + [ + "cCc", + "BbaaC", + 9 + ], + [ + "cCc", + "CAbAabcAc", + 14 + ], + [ + "cCc", + "CccC", + 4 + ], + [ + "cCcA", + "CBaCbc", + 9 + ], + [ + "cCcAAC", + "cCbaCa", + 7 + ], + [ + "cCcAAbbcB", + "A", + 16 + ], + [ + "cCcAB", + "BCCa", + 6 + ], + [ + "cCcACAaCB", + "cccb", + 12 + ], + [ + "cCcAbbBbc", + "CBbaAb", + 12 + ], + [ + "cCcAcAa", + "c", + 12 + ], + [ + "cCcBC", + "CBBAbBAcC", + 13 + ], + [ + "cCcBCcbcb", + "C", + 16 + ], + [ + "cCcC", + "aAcbBCb", + 10 + ], + [ + "cCcCAb", + "bAaCcaCCB", + 11 + ], + [ + "cCcCaCaCB", + "AC", + 15 + ], + [ + "cCcCcB", + "b", + 11 + ], + [ + "cCcaAbCC", + "cAAaCC", + 7 + ], + [ + "cCcaBA", + "C", + 10 + ], + [ + "cCcaBBB", + "BCaCCcB", + 10 + ], + [ + "cCcaC", + "CCAcbCcCc", + 11 + ], + [ + "cCcaCa", + "AAcb", + 10 + ], + [ + "cCcaabba", + "A", + 15 + ], + [ + "cCcabc", + "bc", + 8 + ], + [ + "cCcb", + "BBaAbbaAb", + 16 + ], + [ + "cCcbAbcb", + "AcCbcAAA", + 12 + ], + [ + "cCcbBCCBC", + "cC", + 14 + ], + [ + "cCcbCCB", + "BAbABC", + 12 + ], + [ + "cCcbCaaC", + "cbbcccbca", + 12 + ], + [ + "cCcbaCca", + "baBCABcC", + 13 + ], + [ + "cCcbaba", + "cCBBA", + 7 + ], + [ + "cCcc", + "a", + 8 + ], + [ + "cCccBaa", + "CBcBA", + 7 + ], + [ + "cCccCaCbA", + "caABbAcB", + 13 + ], + [ + "cCccaA", + "abb", + 12 + ], + [ + "cCccbA", + "BBabb", + 10 + ], + [ + "cCccbB", + "abAcB", + 8 + ], + [ + "cCcccAAb", + "aa", + 14 + ], + [ + "cCcccC", + "CBcBaAAc", + 12 + ], + [ + "cCcccCA", + "bcCACb", + 9 + ], + [ + "ca", + "AC", + 4 + ], + [ + "ca", + "ACA", + 4 + ], + [ + "ca", + "ACACb", + 8 + ], + [ + "ca", + "ACa", + 3 + ], + [ + "ca", + "Aaaa", + 6 + ], + [ + "ca", + "BAacabbab", + 14 + ], + [ + "ca", + "BB", + 4 + ], + [ + "ca", + "BBcaAbBcb", + 14 + ], + [ + "ca", + "BacCBC", + 10 + ], + [ + "ca", + "BbA", + 5 + ], + [ + "ca", + "BbBbBC", + 12 + ], + [ + "ca", + "BbCACC", + 10 + ], + [ + "ca", + "Bcbc", + 6 + ], + [ + "ca", + "BccA", + 5 + ], + [ + "ca", + "C", + 3 + ], + [ + "ca", + "CA", + 2 + ], + [ + "ca", + "CAC", + 4 + ], + [ + "ca", + "CCcbBaaab", + 14 + ], + [ + "ca", + "CbCaAaB", + 11 + ], + [ + "ca", + "a", + 2 + ], + [ + "ca", + "aBAA", + 7 + ], + [ + "ca", + "aC", + 4 + ], + [ + "ca", + "aaAbcACCc", + 15 + ], + [ + "ca", + "acccCcBc", + 14 + ], + [ + "ca", + "bAAaCCAc", + 14 + ], + [ + "ca", + "bBcAABbbB", + 15 + ], + [ + "ca", + "bbb", + 6 + ], + [ + "ca", + "cBC", + 4 + ], + [ + "ca", + "cCbba", + 6 + ], + [ + "ca", + "ccBBaba", + 10 + ], + [ + "caA", + "B", + 6 + ], + [ + "caA", + "CcCcAA", + 7 + ], + [ + "caA", + "aCAbCCCA", + 12 + ], + [ + "caA", + "aCcCbbAAC", + 13 + ], + [ + "caA", + "bBbac", + 8 + ], + [ + "caA", + "bCACCACC", + 12 + ], + [ + "caA", + "bbaA", + 4 + ], + [ + "caA", + "bbbBA", + 8 + ], + [ + "caA", + "cbAacAbbc", + 12 + ], + [ + "caAA", + "bAbaa", + 7 + ], + [ + "caAAAB", + "ab", + 9 + ], + [ + "caAAAcaA", + "CacaAcA", + 6 + ], + [ + "caAACbc", + "CBBCABbbb", + 13 + ], + [ + "caAB", + "A", + 6 + ], + [ + "caAB", + "BCAcbbB", + 10 + ], + [ + "caAB", + "CAaAab", + 6 + ], + [ + "caABabc", + "ACbbCCC", + 12 + ], + [ + "caABb", + "AaCaBC", + 7 + ], + [ + "caAC", + "CbCcB", + 8 + ], + [ + "caAC", + "bBBBCCBA", + 14 + ], + [ + "caACABAA", + "aa", + 13 + ], + [ + "caACBa", + "BbbBcAc", + 13 + ], + [ + "caACCBAaa", + "bbAcA", + 13 + ], + [ + "caACCac", + "a", + 12 + ], + [ + "caAa", + "abBcaB", + 10 + ], + [ + "caAa", + "acaCcBc", + 10 + ], + [ + "caAaBaBc", + "bcbCa", + 14 + ], + [ + "caAaa", + "ac", + 8 + ], + [ + "caAaaaaa", + "ccc", + 14 + ], + [ + "caAac", + "ACcACAbc", + 9 + ], + [ + "caAbAAcBb", + "c", + 16 + ], + [ + "caAbAcACB", + "CBCCaAaaB", + 13 + ], + [ + "caAbBBAbC", + "bacC", + 13 + ], + [ + "caAbBCb", + "bbaaaCc", + 11 + ], + [ + "caAbbBa", + "bAC", + 12 + ], + [ + "caAbbb", + "bbCACabaC", + 13 + ], + [ + "caAc", + "baCBB", + 8 + ], + [ + "caAcCc", + "ACc", + 6 + ], + [ + "caAcbbaCB", + "cbcBc", + 12 + ], + [ + "caAcc", + "BBbabc", + 9 + ], + [ + "caAcccaAb", + "Acab", + 10 + ], + [ + "caB", + "CbAcacAa", + 12 + ], + [ + "caB", + "ccBA", + 4 + ], + [ + "caBAA", + "aCbc", + 8 + ], + [ + "caBABbbC", + "CB", + 13 + ], + [ + "caBAabAcC", + "aCA", + 14 + ], + [ + "caBAbAAc", + "bcCBBa", + 12 + ], + [ + "caBAbaAb", + "ba", + 12 + ], + [ + "caBAcB", + "BaaaBA", + 9 + ], + [ + "caBBA", + "Bc", + 8 + ], + [ + "caBBA", + "CacB", + 5 + ], + [ + "caBBaBAB", + "acAbaa", + 11 + ], + [ + "caBBbaaA", + "bB", + 13 + ], + [ + "caBC", + "CBaaBaAa", + 11 + ], + [ + "caBCBaBC", + "aABaB", + 8 + ], + [ + "caBCac", + "b", + 11 + ], + [ + "caBCc", + "CBCabB", + 9 + ], + [ + "caBa", + "CaBabAC", + 7 + ], + [ + "caBa", + "CcbccA", + 9 + ], + [ + "caBaB", + "BcA", + 8 + ], + [ + "caBaCAb", + "AacCAA", + 8 + ], + [ + "caBaCc", + "cCCA", + 8 + ], + [ + "caBb", + "AaCbCAAa", + 12 + ], + [ + "caBb", + "BCBC", + 6 + ], + [ + "caBb", + "b", + 6 + ], + [ + "caBbCaa", + "caCCbb", + 8 + ], + [ + "caBbCbbBB", + "aBCBCabca", + 11 + ], + [ + "caBbCcBC", + "cccBaB", + 11 + ], + [ + "caBbac", + "bac", + 6 + ], + [ + "caBbbB", + "BcBBA", + 9 + ], + [ + "caBbbcBa", + "b", + 14 + ], + [ + "caBc", + "bA", + 7 + ], + [ + "caBc", + "bBA", + 6 + ], + [ + "caBc", + "cc", + 4 + ], + [ + "caBcAA", + "ccacac", + 7 + ], + [ + "caBcacCb", + "bBc", + 12 + ], + [ + "caC", + "BCbb", + 7 + ], + [ + "caC", + "BbBcA", + 9 + ], + [ + "caC", + "babCacB", + 10 + ], + [ + "caC", + "bb", + 6 + ], + [ + "caC", + "cCbAaa", + 8 + ], + [ + "caCAB", + "CBA", + 7 + ], + [ + "caCAC", + "AcaaCaacc", + 10 + ], + [ + "caCAb", + "BaC", + 6 + ], + [ + "caCAccca", + "bACc", + 11 + ], + [ + "caCBA", + "aBBBBcA", + 10 + ], + [ + "caCBC", + "BcBBabA", + 11 + ], + [ + "caCBC", + "ac", + 7 + ], + [ + "caCBba", + "cBA", + 7 + ], + [ + "caCBbaBB", + "a", + 14 + ], + [ + "caCBbc", + "A", + 11 + ], + [ + "caCC", + "CaBC", + 3 + ], + [ + "caCCAa", + "Baabb", + 10 + ], + [ + "caCCAcaa", + "aC", + 12 + ], + [ + "caCCC", + "bCBaAAbC", + 11 + ], + [ + "caCCaa", + "acabCacA", + 7 + ], + [ + "caCCbCc", + "aCBcC", + 7 + ], + [ + "caCCcc", + "cbaCAacc", + 6 + ], + [ + "caCaBB", + "ccbBaBA", + 8 + ], + [ + "caCaBbcAA", + "baCcAB", + 10 + ], + [ + "caCaCAaaC", + "ABB", + 16 + ], + [ + "caCabcBa", + "CAcCABcc", + 10 + ], + [ + "caCb", + "BcAcABAB", + 11 + ], + [ + "caCb", + "bAbBCb", + 7 + ], + [ + "caCbAAcb", + "aaBbAB", + 9 + ], + [ + "caCbCBBb", + "A", + 15 + ], + [ + "caCbbC", + "cCcc", + 7 + ], + [ + "caCbbcbC", + "CBAAbCC", + 10 + ], + [ + "caCbc", + "B", + 9 + ], + [ + "caCcCaaB", + "AacCbcca", + 11 + ], + [ + "caa", + "CCAcAcaab", + 12 + ], + [ + "caa", + "b", + 6 + ], + [ + "caa", + "bAB", + 5 + ], + [ + "caa", + "bacAa", + 5 + ], + [ + "caaA", + "BaCbcC", + 10 + ], + [ + "caaAABaac", + "AC", + 15 + ], + [ + "caaACA", + "cB", + 10 + ], + [ + "caaAa", + "CaBaAbcB", + 9 + ], + [ + "caaAa", + "bbC", + 10 + ], + [ + "caaAbbc", + "Aa", + 11 + ], + [ + "caaB", + "bAc", + 7 + ], + [ + "caaB", + "cB", + 4 + ], + [ + "caaBA", + "C", + 9 + ], + [ + "caaBAabC", + "BACB", + 11 + ], + [ + "caaBCC", + "Ab", + 10 + ], + [ + "caaBCc", + "CCb", + 9 + ], + [ + "caaCCAa", + "bCccbA", + 11 + ], + [ + "caaCaBcBb", + "aCabaa", + 11 + ], + [ + "caaCbaB", + "CCc", + 11 + ], + [ + "caaCc", + "b", + 10 + ], + [ + "caaCcc", + "cbA", + 9 + ], + [ + "caaa", + "AcCc", + 8 + ], + [ + "caaa", + "bCabaCaa", + 9 + ], + [ + "caaaCb", + "AabC", + 7 + ], + [ + "caaaaC", + "CaaBCCaC", + 7 + ], + [ + "caaab", + "BCC", + 10 + ], + [ + "caaac", + "AaBbACcBa", + 13 + ], + [ + "caab", + "C", + 7 + ], + [ + "caabACbb", + "bb", + 12 + ], + [ + "caabB", + "AbaCbac", + 10 + ], + [ + "caabaABA", + "cbacccaA", + 10 + ], + [ + "caabcbcBB", + "abaAAaC", + 14 + ], + [ + "caac", + "ABb", + 7 + ], + [ + "caacAABaB", + "CbBcbaB", + 10 + ], + [ + "caacaccC", + "BAaccaBA", + 11 + ], + [ + "caacbaAc", + "Abccbc", + 10 + ], + [ + "cab", + "CB", + 4 + ], + [ + "cab", + "a", + 4 + ], + [ + "cab", + "abCCb", + 7 + ], + [ + "cab", + "bAaaBBA", + 11 + ], + [ + "cab", + "bBbCABC", + 11 + ], + [ + "cabAA", + "c", + 8 + ], + [ + "cabACCCCb", + "b", + 16 + ], + [ + "cabACc", + "bBBAb", + 9 + ], + [ + "cabBAaaB", + "BbCCBaBc", + 12 + ], + [ + "cabBC", + "A", + 9 + ], + [ + "cabBCa", + "C", + 10 + ], + [ + "cabBCcBbA", + "BbCbAAaAb", + 16 + ], + [ + "cabBaA", + "cCa", + 8 + ], + [ + "cabC", + "BBCabBCa", + 9 + ], + [ + "cabC", + "BCBb", + 7 + ], + [ + "cabC", + "Baccb", + 7 + ], + [ + "cabCCAcC", + "cCcA", + 9 + ], + [ + "cabCCaBca", + "BCbBc", + 11 + ], + [ + "cabCaba", + "a", + 12 + ], + [ + "cabCb", + "cB", + 7 + ], + [ + "cabCcbB", + "BBbAcBaac", + 13 + ], + [ + "cabaBBb", + "AbC", + 11 + ], + [ + "cabaa", + "ccBCAbAB", + 10 + ], + [ + "cababBBaB", + "AcBCAC", + 14 + ], + [ + "cabac", + "BCa", + 8 + ], + [ + "cabb", + "CACcCcac", + 14 + ], + [ + "cabb", + "a", + 6 + ], + [ + "cabbBBA", + "CCab", + 11 + ], + [ + "cabbBc", + "aCccAAcc", + 12 + ], + [ + "cabbbACA", + "bcaCC", + 11 + ], + [ + "cabc", + "BCBcBca", + 10 + ], + [ + "cabc", + "CaaBBAABA", + 14 + ], + [ + "cabcBCc", + "BABAC", + 10 + ], + [ + "cabca", + "aAaC", + 8 + ], + [ + "cac", + "BBbaabba", + 14 + ], + [ + "cac", + "bb", + 6 + ], + [ + "cac", + "bcBa", + 6 + ], + [ + "cac", + "cBaaBa", + 8 + ], + [ + "cacABBaB", + "BaBAabBbA", + 11 + ], + [ + "cacAaA", + "bc", + 10 + ], + [ + "cacAaaaBb", + "Aba", + 14 + ], + [ + "cacAbbcCB", + "AcCcAaBC", + 11 + ], + [ + "cacAc", + "cAcaAB", + 5 + ], + [ + "cacB", + "BCcbAAcbB", + 11 + ], + [ + "cacB", + "c", + 6 + ], + [ + "cacBAA", + "BbbCCab", + 12 + ], + [ + "cacBAc", + "bbaBB", + 10 + ], + [ + "cacBaAa", + "aBBBCbbbA", + 15 + ], + [ + "cacBab", + "AC", + 10 + ], + [ + "cacCCaB", + "ABCc", + 10 + ], + [ + "caca", + "bCbbAa", + 9 + ], + [ + "cacaAbAAA", + "bc", + 16 + ], + [ + "cacaAcc", + "bc", + 12 + ], + [ + "cacaBc", + "BaabCbbB", + 12 + ], + [ + "cacaaBc", + "caAacCAAa", + 11 + ], + [ + "cacaabBCa", + "AACaccAc", + 13 + ], + [ + "cacacBAbC", + "C", + 16 + ], + [ + "cacaca", + "aB", + 10 + ], + [ + "cacbAAaCa", + "b", + 16 + ], + [ + "cacbB", + "AbBaCB", + 9 + ], + [ + "cacbCcbcB", + "cc", + 14 + ], + [ + "cacbc", + "BbAACAAC", + 13 + ], + [ + "cacc", + "CAccbBacC", + 11 + ], + [ + "caccA", + "ccc", + 4 + ], + [ + "caccbc", + "ab", + 8 + ], + [ + "cb", + "AAaBCAa", + 13 + ], + [ + "cb", + "AAaC", + 8 + ], + [ + "cb", + "ABAcbc", + 8 + ], + [ + "cb", + "ABccA", + 8 + ], + [ + "cb", + "ACABcb", + 8 + ], + [ + "cb", + "Aa", + 4 + ], + [ + "cb", + "AbBAaB", + 10 + ], + [ + "cb", + "BCcbbACB", + 12 + ], + [ + "cb", + "BabCaAAB", + 14 + ], + [ + "cb", + "BbBCACCBb", + 15 + ], + [ + "cb", + "C", + 3 + ], + [ + "cb", + "CAAbCCB", + 11 + ], + [ + "cb", + "CABBCa", + 10 + ], + [ + "cb", + "CCACAAB", + 12 + ], + [ + "cb", + "aBcA", + 6 + ], + [ + "cb", + "aCBAaabaa", + 15 + ], + [ + "cb", + "aCBaacAac", + 16 + ], + [ + "cb", + "aCC", + 5 + ], + [ + "cb", + "aaBcCC", + 10 + ], + [ + "cb", + "acBAC", + 7 + ], + [ + "cb", + "bCBcaCbA", + 12 + ], + [ + "cb", + "bcCCC", + 8 + ], + [ + "cb", + "cBCaBCC", + 11 + ], + [ + "cb", + "cCabBBabA", + 14 + ], + [ + "cb", + "cb", + 0 + ], + [ + "cb", + "cccCa", + 8 + ], + [ + "cbA", + "AaAaB", + 8 + ], + [ + "cbA", + "AcACCa", + 9 + ], + [ + "cbA", + "BbCBABAA", + 12 + ], + [ + "cbA", + "aBcCCAAca", + 14 + ], + [ + "cbA", + "aaab", + 7 + ], + [ + "cbAA", + "BAbBc", + 8 + ], + [ + "cbAAaBcc", + "cABABCbb", + 10 + ], + [ + "cbAAcB", + "a", + 11 + ], + [ + "cbAAcC", + "cacC", + 5 + ], + [ + "cbAB", + "CAABa", + 5 + ], + [ + "cbABBb", + "acBA", + 9 + ], + [ + "cbABc", + "cbcAaCb", + 7 + ], + [ + "cbAC", + "C", + 6 + ], + [ + "cbACAbc", + "aABCAbA", + 8 + ], + [ + "cbACcAC", + "bbcAcbB", + 10 + ], + [ + "cbACcBBC", + "cABbcbbaB", + 12 + ], + [ + "cbACcb", + "cabbaAC", + 10 + ], + [ + "cbAaB", + "babCC", + 9 + ], + [ + "cbAaBc", + "Acc", + 8 + ], + [ + "cbAaBcCA", + "C", + 14 + ], + [ + "cbAaCBbB", + "A", + 14 + ], + [ + "cbAabcC", + "BBBCAc", + 11 + ], + [ + "cbAbAaBbc", + "bC", + 15 + ], + [ + "cbAbBBAA", + "bcaBbAc", + 9 + ], + [ + "cbAbCBA", + "acABcaC", + 10 + ], + [ + "cbAbCBBB", + "AAaaa", + 14 + ], + [ + "cbAbCaA", + "cbAcBB", + 7 + ], + [ + "cbAbaCc", + "BACabcaa", + 11 + ], + [ + "cbAbcCA", + "ccC", + 8 + ], + [ + "cbAbcaB", + "cc", + 10 + ], + [ + "cbAbcbAbB", + "AccBbbcA", + 13 + ], + [ + "cbAbcbb", + "caCaAB", + 10 + ], + [ + "cbAc", + "BABcCB", + 9 + ], + [ + "cbAc", + "bacb", + 5 + ], + [ + "cbAcCBb", + "ABac", + 10 + ], + [ + "cbAcbcccB", + "CCC", + 15 + ], + [ + "cbB", + "Aaa", + 6 + ], + [ + "cbB", + "CbC", + 3 + ], + [ + "cbB", + "caCaB", + 6 + ], + [ + "cbBA", + "BcBBccBA", + 9 + ], + [ + "cbBA", + "aCcbB", + 6 + ], + [ + "cbBAAc", + "bcABA", + 8 + ], + [ + "cbBAB", + "AbcBc", + 8 + ], + [ + "cbBABc", + "Cbba", + 7 + ], + [ + "cbBACACa", + "aA", + 13 + ], + [ + "cbBACBccA", + "Ca", + 15 + ], + [ + "cbBAba", + "AcAca", + 8 + ], + [ + "cbBAbb", + "CbaaC", + 8 + ], + [ + "cbBB", + "cAb", + 5 + ], + [ + "cbBB", + "cAba", + 5 + ], + [ + "cbBBbB", + "BBBBcaA", + 9 + ], + [ + "cbBBbca", + "cACABCb", + 10 + ], + [ + "cbBBcACBb", + "AACbBbbb", + 13 + ], + [ + "cbBCCaA", + "AccCcBc", + 11 + ], + [ + "cbBCacA", + "cB", + 10 + ], + [ + "cbBCb", + "CAAbBA", + 9 + ], + [ + "cbBa", + "aaCC", + 8 + ], + [ + "cbBa", + "cBaB", + 4 + ], + [ + "cbBa", + "cccB", + 6 + ], + [ + "cbBaBcAc", + "Aab", + 13 + ], + [ + "cbBaCAC", + "CCcCCc", + 10 + ], + [ + "cbBac", + "c", + 8 + ], + [ + "cbBacA", + "bCaaaBaa", + 12 + ], + [ + "cbBb", + "AABA", + 6 + ], + [ + "cbBb", + "CCaa", + 7 + ], + [ + "cbBbAbB", + "cC", + 12 + ], + [ + "cbBbCACCC", + "Ccc", + 14 + ], + [ + "cbBba", + "ccb", + 6 + ], + [ + "cbBbbb", + "BccCbaAAB", + 13 + ], + [ + "cbBc", + "A", + 8 + ], + [ + "cbBcCAa", + "acab", + 11 + ], + [ + "cbBcCCbAA", + "caAbaCaBc", + 14 + ], + [ + "cbBcaCB", + "bA", + 11 + ], + [ + "cbBcbaccC", + "CaAACBAAA", + 16 + ], + [ + "cbBcbc", + "ABBBAAc", + 9 + ], + [ + "cbBcc", + "CACaBC", + 10 + ], + [ + "cbC", + "AcABa", + 7 + ], + [ + "cbC", + "bCCBBa", + 10 + ], + [ + "cbCAbaAa", + "ccBCaC", + 11 + ], + [ + "cbCB", + "AABCCaaA", + 13 + ], + [ + "cbCBABAAb", + "a", + 17 + ], + [ + "cbCBAcacb", + "CAa", + 12 + ], + [ + "cbCBC", + "cbcaCaaba", + 11 + ], + [ + "cbCBccbcc", + "BcCbA", + 11 + ], + [ + "cbCC", + "B", + 7 + ], + [ + "cbCCBBCB", + "baBaCbC", + 11 + ], + [ + "cbCCBccBb", + "BaAaC", + 16 + ], + [ + "cbCCC", + "AACACB", + 8 + ], + [ + "cbCCbABBB", + "CcaABC", + 11 + ], + [ + "cbCCbBac", + "CAaA", + 12 + ], + [ + "cbCa", + "CBA", + 5 + ], + [ + "cbCa", + "bbcacb", + 7 + ], + [ + "cbCaB", + "cbBaCb", + 5 + ], + [ + "cbCbAaCCa", + "ACAAb", + 13 + ], + [ + "cbCbaC", + "BACcBC", + 8 + ], + [ + "cbCbaCcaC", + "AaaaBC", + 14 + ], + [ + "cbCbb", + "A", + 10 + ], + [ + "cbCbbCAAc", + "caccc", + 12 + ], + [ + "cbCbcC", + "B", + 11 + ], + [ + "cbCcAAcA", + "AcaAaCcCa", + 13 + ], + [ + "cbCcCAc", + "babCC", + 9 + ], + [ + "cbCcCB", + "BCABA", + 9 + ], + [ + "cbCcCbA", + "cB", + 11 + ], + [ + "cbCcb", + "AacBB", + 8 + ], + [ + "cbCcbca", + "BCB", + 10 + ], + [ + "cbCccca", + "AAA", + 13 + ], + [ + "cba", + "A", + 5 + ], + [ + "cba", + "b", + 4 + ], + [ + "cba", + "bBCaaCc", + 11 + ], + [ + "cba", + "cAAbc", + 6 + ], + [ + "cba", + "caABABbab", + 12 + ], + [ + "cba", + "ccAB", + 5 + ], + [ + "cbaAa", + "cBbbcB", + 8 + ], + [ + "cbaAc", + "cAAc", + 3 + ], + [ + "cbaBACBAc", + "a", + 16 + ], + [ + "cbaBCAAC", + "BAAcCc", + 12 + ], + [ + "cbaBCbbcC", + "BcAaabac", + 12 + ], + [ + "cbaBbCa", + "BBACcA", + 10 + ], + [ + "cbaC", + "BBCaACabc", + 13 + ], + [ + "cbaC", + "aaA", + 6 + ], + [ + "cbaCABA", + "BbAaBccBC", + 11 + ], + [ + "cbaCCA", + "cbCABA", + 6 + ], + [ + "cbaCCCa", + "a", + 12 + ], + [ + "cbaCacac", + "AcBBbAA", + 13 + ], + [ + "cbaCcaA", + "C", + 12 + ], + [ + "cbaa", + "aaBcCBcBa", + 13 + ], + [ + "cbaaA", + "cBaa", + 3 + ], + [ + "cbaabCcC", + "bB", + 13 + ], + [ + "cbabAA", + "Bc", + 11 + ], + [ + "cbabBbc", + "AbcacAC", + 11 + ], + [ + "cbabC", + "CBbaAa", + 7 + ], + [ + "cbabbC", + "aCacAcBAC", + 13 + ], + [ + "cbac", + "cCbBcACa", + 10 + ], + [ + "cbacAAAA", + "BcAbcAbc", + 12 + ], + [ + "cbacAAacc", + "ab", + 16 + ], + [ + "cbacAC", + "BaaABAbC", + 10 + ], + [ + "cbacACa", + "AcBbcBaC", + 10 + ], + [ + "cbacB", + "CaBAa", + 9 + ], + [ + "cbacCCab", + "Acbc", + 12 + ], + [ + "cbacCabBB", + "CCcc", + 14 + ], + [ + "cbb", + "BBbB", + 5 + ], + [ + "cbb", + "CcAaAC", + 10 + ], + [ + "cbb", + "bBcABAcCC", + 15 + ], + [ + "cbb", + "cbccAbA", + 8 + ], + [ + "cbbABaCBa", + "Ca", + 14 + ], + [ + "cbbAa", + "aBBcAa", + 6 + ], + [ + "cbbAaC", + "cbc", + 7 + ], + [ + "cbbAbB", + "BABaBA", + 9 + ], + [ + "cbbAbaaB", + "CCababBa", + 10 + ], + [ + "cbbBAC", + "AacCcb", + 12 + ], + [ + "cbbBbA", + "AbCAACc", + 12 + ], + [ + "cbbBbb", + "b", + 10 + ], + [ + "cbbBbbbCA", + "bBB", + 13 + ], + [ + "cbbBcBbBb", + "BaABc", + 14 + ], + [ + "cbbBcC", + "C", + 10 + ], + [ + "cbbCAaB", + "A", + 12 + ], + [ + "cbbCbC", + "cBaCCABb", + 10 + ], + [ + "cbbCcbA", + "baCBaBab", + 12 + ], + [ + "cbbaCA", + "aCAbbbCcA", + 9 + ], + [ + "cbbaCb", + "ABaCaB", + 8 + ], + [ + "cbbaaC", + "BcAAbAba", + 11 + ], + [ + "cbbabc", + "BaAaacCAc", + 14 + ], + [ + "cbbacB", + "b", + 10 + ], + [ + "cbbb", + "CC", + 7 + ], + [ + "cbbb", + "bBcCaCAC", + 14 + ], + [ + "cbbbB", + "abacb", + 7 + ], + [ + "cbbbBBcb", + "cA", + 14 + ], + [ + "cbbbaBbC", + "CbAABAC", + 8 + ], + [ + "cbbbc", + "c", + 8 + ], + [ + "cbbc", + "aCBAcAc", + 10 + ], + [ + "cbbc", + "abBBCAB", + 10 + ], + [ + "cbbcBC", + "BAB", + 9 + ], + [ + "cbbcBcCCb", + "bc", + 14 + ], + [ + "cbc", + "AACAAbCCB", + 14 + ], + [ + "cbc", + "BcbaA", + 6 + ], + [ + "cbc", + "CbBbACB", + 10 + ], + [ + "cbc", + "b", + 4 + ], + [ + "cbc", + "cBCcBaC", + 9 + ], + [ + "cbcA", + "ABBAcC", + 9 + ], + [ + "cbcAA", + "c", + 8 + ], + [ + "cbcACAabb", + "bccBcbAaA", + 13 + ], + [ + "cbcAaAAb", + "BBccBbCA", + 13 + ], + [ + "cbcAb", + "CCCbbbcba", + 13 + ], + [ + "cbcB", + "Aba", + 6 + ], + [ + "cbcB", + "bCaaaAba", + 14 + ], + [ + "cbcBacB", + "acbB", + 9 + ], + [ + "cbcBbb", + "cBa", + 8 + ], + [ + "cbcBcc", + "bbCcA", + 7 + ], + [ + "cbcC", + "aABacCCC", + 11 + ], + [ + "cbcCA", + "bBAaba", + 10 + ], + [ + "cbcCBcbc", + "acBa", + 12 + ], + [ + "cbcCcBa", + "CbbACa", + 8 + ], + [ + "cbcaB", + "bCaAAc", + 9 + ], + [ + "cbcabBAac", + "bcBCbCBb", + 13 + ], + [ + "cbcb", + "bba", + 6 + ], + [ + "cbcbCCA", + "AaaCCabcc", + 15 + ], + [ + "cbcbaCBb", + "BccCAb", + 9 + ], + [ + "cbcbbC", + "BAaa", + 11 + ], + [ + "cbcbcaCC", + "BaBbbB", + 14 + ], + [ + "cbcccaCc", + "acAAAa", + 13 + ], + [ + "cc", + "AAAbBbC", + 13 + ], + [ + "cc", + "ABBaccbbB", + 14 + ], + [ + "cc", + "ABa", + 6 + ], + [ + "cc", + "ABaA", + 8 + ], + [ + "cc", + "BAbbAab", + 14 + ], + [ + "cc", + "BAbc", + 6 + ], + [ + "cc", + "BBacCb", + 9 + ], + [ + "cc", + "BCbaB", + 9 + ], + [ + "cc", + "BaBcBAAc", + 12 + ], + [ + "cc", + "BaC", + 5 + ], + [ + "cc", + "Bbca", + 6 + ], + [ + "cc", + "CAbbcb", + 9 + ], + [ + "cc", + "CCAcCb", + 9 + ], + [ + "cc", + "Ccb", + 3 + ], + [ + "cc", + "aAaBCaA", + 13 + ], + [ + "cc", + "aB", + 4 + ], + [ + "cc", + "aBA", + 6 + ], + [ + "cc", + "acCcCabA", + 12 + ], + [ + "cc", + "b", + 4 + ], + [ + "cc", + "bACABABA", + 15 + ], + [ + "cc", + "baCaAAAc", + 13 + ], + [ + "cc", + "bacAbacB", + 12 + ], + [ + "cc", + "bcbA", + 6 + ], + [ + "cc", + "cABcAA", + 8 + ], + [ + "cc", + "cACac", + 6 + ], + [ + "cc", + "cAbba", + 8 + ], + [ + "cc", + "cB", + 2 + ], + [ + "cc", + "cCac", + 4 + ], + [ + "cc", + "cCbbAcaA", + 12 + ], + [ + "cc", + "cb", + 2 + ], + [ + "cc", + "ccBc", + 4 + ], + [ + "cc", + "ccCab", + 6 + ], + [ + "ccA", + "AcCccAcc", + 10 + ], + [ + "ccA", + "CBAaC", + 7 + ], + [ + "ccA", + "b", + 6 + ], + [ + "ccAABB", + "ccCBBbC", + 7 + ], + [ + "ccAAb", + "BaABC", + 8 + ], + [ + "ccAAbaA", + "BaA", + 9 + ], + [ + "ccAAbbbaB", + "AABBCc", + 12 + ], + [ + "ccAB", + "BcA", + 4 + ], + [ + "ccABA", + "BcBBcbBA", + 8 + ], + [ + "ccABBAA", + "bCCac", + 12 + ], + [ + "ccABcAA", + "AABBaBaA", + 11 + ], + [ + "ccAC", + "CAACBCaCA", + 13 + ], + [ + "ccAC", + "bA", + 6 + ], + [ + "ccACAAcb", + "AbabCa", + 12 + ], + [ + "ccACABbAc", + "BCbAb", + 12 + ], + [ + "ccACB", + "CBbabcAC", + 11 + ], + [ + "ccACBAaBa", + "ca", + 14 + ], + [ + "ccACBca", + "Cb", + 11 + ], + [ + "ccACC", + "CcaAba", + 7 + ], + [ + "ccACC", + "aCc", + 6 + ], + [ + "ccACaABcb", + "CBBCCABCc", + 10 + ], + [ + "ccACaBbAC", + "cBaAaB", + 11 + ], + [ + "ccACcAAB", + "AbCbaCAbb", + 13 + ], + [ + "ccACcbb", + "abCcBCb", + 9 + ], + [ + "ccAa", + "bca", + 4 + ], + [ + "ccAa", + "c", + 6 + ], + [ + "ccAaACB", + "BCabaaA", + 11 + ], + [ + "ccAaAbccA", + "AAbAAb", + 12 + ], + [ + "ccAaC", + "bAaaACAB", + 11 + ], + [ + "ccAcAC", + "c", + 10 + ], + [ + "ccAcAb", + "AbABBCbBA", + 14 + ], + [ + "ccAcb", + "bcAb", + 4 + ], + [ + "ccAcccc", + "ccCca", + 7 + ], + [ + "ccB", + "B", + 4 + ], + [ + "ccB", + "CcBAB", + 5 + ], + [ + "ccB", + "aAa", + 6 + ], + [ + "ccB", + "b", + 5 + ], + [ + "ccB", + "cAaAbaa", + 11 + ], + [ + "ccB", + "cBbCACaAB", + 13 + ], + [ + "ccBA", + "B", + 6 + ], + [ + "ccBA", + "CAac", + 7 + ], + [ + "ccBACbca", + "Abb", + 12 + ], + [ + "ccBAc", + "baaaCaaB", + 14 + ], + [ + "ccBB", + "BcC", + 6 + ], + [ + "ccBBA", + "BbACCaA", + 11 + ], + [ + "ccBBbAa", + "b", + 12 + ], + [ + "ccBBbb", + "cBbBb", + 4 + ], + [ + "ccBBbcC", + "CAbacA", + 10 + ], + [ + "ccBC", + "AaBAA", + 8 + ], + [ + "ccBC", + "Baba", + 7 + ], + [ + "ccBC", + "b", + 7 + ], + [ + "ccBC", + "cbba", + 5 + ], + [ + "ccBCAaBc", + "bBCCCAA", + 12 + ], + [ + "ccBCAbC", + "abC", + 9 + ], + [ + "ccBCBBcac", + "BCabBA", + 12 + ], + [ + "ccBCC", + "AbbC", + 7 + ], + [ + "ccBCCCa", + "BaCaB", + 10 + ], + [ + "ccBCCaBcB", + "AcC", + 14 + ], + [ + "ccBCCc", + "aBb", + 10 + ], + [ + "ccBCbBcC", + "ca", + 14 + ], + [ + "ccBCcCaA", + "bcbBAcaBA", + 10 + ], + [ + "ccBa", + "ACCaABcCa", + 12 + ], + [ + "ccBaC", + "AC", + 7 + ], + [ + "ccBaaAa", + "Cc", + 11 + ], + [ + "ccBab", + "BACC", + 9 + ], + [ + "ccBabcaBA", + "CBbc", + 11 + ], + [ + "ccBacCAbB", + "cCCcA", + 11 + ], + [ + "ccBbAABB", + "ccb", + 10 + ], + [ + "ccBbAaB", + "Cc", + 11 + ], + [ + "ccBbaCAb", + "Bcc", + 13 + ], + [ + "ccBbab", + "cCbBc", + 7 + ], + [ + "ccBbbbcB", + "Aacaaa", + 16 + ], + [ + "ccBcb", + "bbcACCb", + 9 + ], + [ + "ccC", + "Ab", + 6 + ], + [ + "ccC", + "CBcCaAbAc", + 13 + ], + [ + "ccC", + "aaCB", + 6 + ], + [ + "ccC", + "bBBAA", + 10 + ], + [ + "ccCAA", + "aCC", + 7 + ], + [ + "ccCAcCB", + "baAAbBac", + 14 + ], + [ + "ccCBAa", + "AABbcA", + 10 + ], + [ + "ccCBCc", + "caBcB", + 7 + ], + [ + "ccCBbC", + "BbbA", + 9 + ], + [ + "ccCC", + "A", + 8 + ], + [ + "ccCC", + "CCaBcACBC", + 11 + ], + [ + "ccCC", + "aab", + 8 + ], + [ + "ccCCAaa", + "B", + 14 + ], + [ + "ccCCBAaaC", + "Bb", + 16 + ], + [ + "ccCCBbCaA", + "AcACCaB", + 10 + ], + [ + "ccCCCaaCb", + "BaAbBB", + 16 + ], + [ + "ccCCacA", + "ACAAa", + 10 + ], + [ + "ccCa", + "acbBa", + 6 + ], + [ + "ccCaa", + "aCBCa", + 7 + ], + [ + "ccCab", + "CCAb", + 4 + ], + [ + "ccCbBB", + "AAcabCa", + 10 + ], + [ + "ccCba", + "aacAbCBb", + 11 + ], + [ + "ccCbbCBA", + "AaCBcAb", + 12 + ], + [ + "ccCbc", + "aCbBCcb", + 10 + ], + [ + "ccCbcCcA", + "aAA", + 14 + ], + [ + "ccCbcaaAC", + "abB", + 16 + ], + [ + "ccCcAbCA", + "AB", + 13 + ], + [ + "ccCcAccA", + "CCABcCCbc", + 13 + ], + [ + "ccCcBaA", + "caC", + 10 + ], + [ + "ccCcBbc", + "aaacAca", + 12 + ], + [ + "ccCcBcC", + "CBCCCBAA", + 9 + ], + [ + "ccCcabcb", + "baAb", + 12 + ], + [ + "ccCccbABc", + "b", + 16 + ], + [ + "cca", + "ABc", + 6 + ], + [ + "cca", + "aa", + 4 + ], + [ + "cca", + "bACA", + 6 + ], + [ + "ccaA", + "AcBa", + 5 + ], + [ + "ccaA", + "Ca", + 5 + ], + [ + "ccaABaccb", + "AAaaCBb", + 10 + ], + [ + "ccaACAC", + "BAc", + 11 + ], + [ + "ccaAba", + "Ccb", + 7 + ], + [ + "ccaAc", + "B", + 10 + ], + [ + "ccaAcCB", + "ccBB", + 8 + ], + [ + "ccaB", + "BbcB", + 6 + ], + [ + "ccaBC", + "CbbbB", + 8 + ], + [ + "ccaCA", + "ABBbb", + 10 + ], + [ + "ccaCAB", + "cCbcb", + 7 + ], + [ + "ccaCAcAB", + "acbb", + 11 + ], + [ + "ccaCAcBb", + "ccCbb", + 7 + ], + [ + "ccaCCCcCC", + "AACAc", + 13 + ], + [ + "ccaCaABb", + "bA", + 14 + ], + [ + "ccaCc", + "babb", + 8 + ], + [ + "ccaCcAAaB", + "BcAAaB", + 8 + ], + [ + "ccaCcB", + "B", + 10 + ], + [ + "ccaaBCB", + "AAA", + 12 + ], + [ + "ccaaaa", + "Aa", + 9 + ], + [ + "ccaab", + "acbbC", + 8 + ], + [ + "ccaac", + "BCBBb", + 9 + ], + [ + "ccab", + "C", + 7 + ], + [ + "ccab", + "aabBBcABa", + 14 + ], + [ + "ccabaB", + "CACba", + 7 + ], + [ + "ccabaCa", + "ccAac", + 6 + ], + [ + "ccababcA", + "abc", + 10 + ], + [ + "ccacAbBBB", + "Cb", + 15 + ], + [ + "ccacb", + "cbCA", + 7 + ], + [ + "ccb", + "A", + 6 + ], + [ + "ccb", + "Aa", + 6 + ], + [ + "ccb", + "Aca", + 4 + ], + [ + "ccb", + "acBAcb", + 6 + ], + [ + "ccb", + "acBccbAcA", + 12 + ], + [ + "ccbA", + "ba", + 5 + ], + [ + "ccbAAA", + "BAaca", + 9 + ], + [ + "ccbAACAc", + "CaaCBcBAa", + 14 + ], + [ + "ccbABAA", + "BBaccbb", + 13 + ], + [ + "ccbACa", + "cabACc", + 4 + ], + [ + "ccbAaCA", + "cCccaCCA", + 7 + ], + [ + "ccbAb", + "bbbCaACa", + 12 + ], + [ + "ccbAbA", + "cbcaBb", + 8 + ], + [ + "ccbAbBB", + "cBcbA", + 8 + ], + [ + "ccbAcC", + "AbBCcaacB", + 12 + ], + [ + "ccbBbcb", + "bCbCAC", + 10 + ], + [ + "ccbC", + "ACccBAc", + 8 + ], + [ + "ccbC", + "CB", + 6 + ], + [ + "ccbC", + "aCAA", + 7 + ], + [ + "ccbCC", + "AcCcCcb", + 8 + ], + [ + "ccbCa", + "bcBBcb", + 8 + ], + [ + "ccbCaACca", + "BBcaA", + 12 + ], + [ + "ccbCbbB", + "b", + 12 + ], + [ + "ccba", + "CAbbBc", + 9 + ], + [ + "ccba", + "Caa", + 5 + ], + [ + "ccba", + "bA", + 5 + ], + [ + "ccba", + "cbc", + 4 + ], + [ + "ccbabbC", + "AB", + 12 + ], + [ + "ccbbBbAb", + "CBc", + 13 + ], + [ + "ccbbabB", + "bCcaCa", + 11 + ], + [ + "ccbbcB", + "ACbcaaA", + 11 + ], + [ + "ccbbccCAC", + "CcccBcBC", + 10 + ], + [ + "ccbcABBCb", + "aAcAacC", + 12 + ], + [ + "ccbcAbBbc", + "a", + 17 + ], + [ + "ccbcB", + "CBaCAAcBc", + 12 + ], + [ + "ccbcBBAbB", + "cBccCc", + 13 + ], + [ + "ccbcCaab", + "cCaAAB", + 10 + ], + [ + "ccbcCbcB", + "CCCa", + 12 + ], + [ + "ccbcba", + "CA", + 10 + ], + [ + "ccc", + "AcBcbBcb", + 10 + ], + [ + "ccc", + "BbcCbB", + 9 + ], + [ + "ccc", + "CACABCbb", + 13 + ], + [ + "ccc", + "ac", + 4 + ], + [ + "ccc", + "baAABCbcc", + 13 + ], + [ + "ccc", + "c", + 4 + ], + [ + "ccc", + "cabACBAbB", + 15 + ], + [ + "cccA", + "cbBAbbB", + 10 + ], + [ + "cccAAA", + "AcB", + 10 + ], + [ + "cccAABCcA", + "ba", + 16 + ], + [ + "cccAC", + "ABCaa", + 8 + ], + [ + "cccAaccc", + "bcCC", + 12 + ], + [ + "cccAbC", + "cBbCAb", + 7 + ], + [ + "cccB", + "bACBcb", + 8 + ], + [ + "cccB", + "c", + 6 + ], + [ + "cccBAA", + "cbB", + 8 + ], + [ + "cccBAbb", + "bCCacb", + 9 + ], + [ + "cccBBAC", + "bbbcB", + 12 + ], + [ + "cccBBCc", + "CAaaAb", + 13 + ], + [ + "cccC", + "ACbB", + 7 + ], + [ + "cccC", + "bbbA", + 8 + ], + [ + "cccCabBA", + "AaBc", + 12 + ], + [ + "cccCbbcc", + "CcC", + 11 + ], + [ + "cccCccaC", + "b", + 16 + ], + [ + "ccca", + "cCcCAa", + 5 + ], + [ + "cccaAb", + "Abb", + 9 + ], + [ + "cccaCbA", + "cBcCBBbaA", + 9 + ], + [ + "cccaaa", + "BaABcbcca", + 14 + ], + [ + "cccacB", + "abBB", + 10 + ], + [ + "cccb", + "AABc", + 8 + ], + [ + "cccb", + "CbBAAbA", + 11 + ], + [ + "cccbABcc", + "a", + 15 + ], + [ + "cccbB", + "bcCAcaaba", + 11 + ], + [ + "cccbaBC", + "cbACAac", + 10 + ], + [ + "cccbabBb", + "ACc", + 13 + ], + [ + "cccbbA", + "bbcAc", + 10 + ], + [ + "cccbcaCC", + "AbCACBcCb", + 13 + ], + [ + "cccbcaaaC", + "baCcCc", + 14 + ], + [ + "ccccBa", + "abcbaaCbA", + 13 + ], + [ + "ccccCBcCA", + "Cbbab", + 15 + ], + [ + "ccccCCc", + "aabB", + 14 + ], + [ + "ccccaCA", + "Cb", + 12 + ], + [ + "cccccb", + "a", + 12 + ], + [ + "ccccccAcc", + "AB", + 16 + ] +] \ No newline at end of file diff --git a/Lib/test/libregrtest/cmdline.py b/Lib/test/libregrtest/cmdline.py index ebe57920..d1a590d8 100644 --- a/Lib/test/libregrtest/cmdline.py +++ b/Lib/test/libregrtest/cmdline.py @@ -107,6 +107,8 @@ resources to test. Currently only the following are defined: cpu - Used for certain CPU-heavy tests. + walltime - Long running but not CPU-bound tests. + subprocess Run all tests for the subprocess module. urlfetch - It is okay to download files required on testing. @@ -129,7 +131,7 @@ Pattern examples: ALL_RESOURCES = ('audio', 'curses', 'largefile', 'network', - 'decimal', 'cpu', 'subprocess', 'urlfetch', 'gui') + 'decimal', 'cpu', 'subprocess', 'urlfetch', 'gui', 'walltime') # Other resources excluded from --use=all: # @@ -156,7 +158,7 @@ class Namespace(argparse.Namespace): self.coverdir = 'coverage' self.runleaks = False self.huntrleaks = False - self.verbose2 = False + self.rerun = False self.verbose3 = False self.print_slow = False self.random_seed = None @@ -213,8 +215,10 @@ def _create_parser(): group = parser.add_argument_group('Verbosity') group.add_argument('-v', '--verbose', action='count', help='run tests in verbose mode with output to stdout') - group.add_argument('-w', '--verbose2', action='store_true', + group.add_argument('-w', '--rerun', action='store_true', help='re-run failed tests in verbose mode') + group.add_argument('--verbose2', action='store_true', dest='rerun', + help='deprecated alias to --rerun') group.add_argument('-W', '--verbose3', action='store_true', help='display test output on failure') group.add_argument('-q', '--quiet', action='store_true', @@ -309,6 +313,9 @@ def _create_parser(): group.add_argument('--fail-env-changed', action='store_true', help='if a test file alters the environment, mark ' 'the test as failed') + group.add_argument('--fail-rerun', action='store_true', + help='if a test failed and then passed when re-run, ' + 'mark the tests as failed') group.add_argument('--junit-xml', dest='xmlpath', metavar='FILENAME', help='writes JUnit-style XML results to the specified ' @@ -380,7 +387,7 @@ def _parse_args(args, **kwargs): ns.python = shlex.split(ns.python) if ns.failfast and not (ns.verbose or ns.verbose3): parser.error("-G/--failfast needs either -v or -W") - if ns.pgo and (ns.verbose or ns.verbose2 or ns.verbose3): + if ns.pgo and (ns.verbose or ns.rerun or ns.verbose3): parser.error("--pgo/-v don't go together!") if ns.pgo_extended: ns.pgo = True # pgo_extended implies pgo diff --git a/Lib/test/libregrtest/main.py b/Lib/test/libregrtest/main.py index 655e4d2e..ab03647c 100644 --- a/Lib/test/libregrtest/main.py +++ b/Lib/test/libregrtest/main.py @@ -11,14 +11,14 @@ import time import unittest from test.libregrtest.cmdline import _parse_args from test.libregrtest.runtest import ( - findtests, runtest, get_abs_module, is_failed, - STDTESTS, NOTTESTS, PROGRESS_MIN_TIME, - Passed, Failed, EnvChanged, Skipped, ResourceDenied, Interrupted, - ChildError, DidNotRun) + findtests, split_test_packages, runtest, abs_module_name, + PROGRESS_MIN_TIME, State, MatchTestsDict, RunTests) from test.libregrtest.setup import setup_tests from test.libregrtest.pgo import setup_pgo_tests -from test.libregrtest.utils import removepy, count, format_duration, printlist +from test.libregrtest.utils import (strip_py_suffix, count, format_duration, + printlist, get_build_info) from test import support +from test.support import TestStats from test.support import os_helper from test.support import threading_helper @@ -28,6 +28,12 @@ from test.support import threading_helper # Must be smaller than buildbot "1200 seconds without output" limit. EXIT_TIMEOUT = 120.0 +EXITCODE_BAD_TEST = 2 +EXITCODE_ENV_CHANGED = 3 +EXITCODE_NO_TESTS_RAN = 4 +EXITCODE_RERUN_FAIL = 5 +EXITCODE_INTERRUPTED = 130 + class Regrtest: """Execute a test suite. @@ -59,18 +65,22 @@ class Regrtest: # tests self.tests = [] self.selected = [] + self.all_runtests: list[RunTests] = [] # test results - self.good = [] - self.bad = [] - self.skipped = [] - self.resource_denieds = [] - self.environment_changed = [] - self.run_no_tests = [] - self.need_rerun = [] - self.rerun = [] - self.first_result = None + self.good: list[str] = [] + self.bad: list[str] = [] + self.rerun_bad: list[str] = [] + self.skipped: list[str] = [] + self.resource_denied: list[str] = [] + self.environment_changed: list[str] = [] + self.run_no_tests: list[str] = [] + self.rerun: list[str] = [] + + self.need_rerun: list[TestResult] = [] + self.first_state: str | None = None self.interrupted = False + self.total_stats = TestStats() # used by --slow self.test_times = [] @@ -79,8 +89,8 @@ class Regrtest: self.tracer = None # used to display the progress bar "[ 3/100]" - self.start_time = time.monotonic() - self.test_count = '' + self.start_time = time.perf_counter() + self.test_count_text = '' self.test_count_width = 1 # used by --single @@ -93,41 +103,42 @@ class Regrtest: # misc self.win_load_tracker = None self.tmp_dir = None - self.worker_test_name = None def get_executed(self): return (set(self.good) | set(self.bad) | set(self.skipped) - | set(self.resource_denieds) | set(self.environment_changed) + | set(self.resource_denied) | set(self.environment_changed) | set(self.run_no_tests)) def accumulate_result(self, result, rerun=False): - test_name = result.name - - if not isinstance(result, (ChildError, Interrupted)) and not rerun: - self.test_times.append((result.duration_sec, test_name)) - - if isinstance(result, Passed): - self.good.append(test_name) - elif isinstance(result, ResourceDenied): - self.skipped.append(test_name) - self.resource_denieds.append(test_name) - elif isinstance(result, Skipped): - self.skipped.append(test_name) - elif isinstance(result, EnvChanged): - self.environment_changed.append(test_name) - elif isinstance(result, Failed): - if not rerun: - self.bad.append(test_name) - self.need_rerun.append(result) - elif isinstance(result, DidNotRun): - self.run_no_tests.append(test_name) - elif isinstance(result, Interrupted): - self.interrupted = True - else: - raise ValueError("invalid test result: %r" % result) - - if rerun and not isinstance(result, (Failed, Interrupted)): - self.bad.remove(test_name) + fail_env_changed = self.ns.fail_env_changed + test_name = result.test_name + + match result.state: + case State.PASSED: + self.good.append(test_name) + case State.ENV_CHANGED: + self.environment_changed.append(test_name) + case State.SKIPPED: + self.skipped.append(test_name) + case State.RESOURCE_DENIED: + self.resource_denied.append(test_name) + case State.INTERRUPTED: + self.interrupted = True + case State.DID_NOT_RUN: + self.run_no_tests.append(test_name) + case _: + if result.is_failed(fail_env_changed): + self.bad.append(test_name) + self.need_rerun.append(result) + else: + raise ValueError(f"invalid test state: {result.state!r}") + + if result.has_meaningful_duration() and not rerun: + self.test_times.append((result.duration, test_name)) + if result.stats is not None: + self.total_stats.accumulate(result.stats) + if rerun: + self.rerun.append(test_name) xml_data = result.xml_data if xml_data: @@ -148,7 +159,7 @@ class Regrtest: line = f"load avg: {load_avg:.2f} {line}" # add the timestamp prefix: "0:01:05 " - test_time = time.monotonic() - self.start_time + test_time = time.perf_counter() - self.start_time mins, secs = divmod(int(test_time), 60) hours, mins = divmod(mins, 60) @@ -161,13 +172,15 @@ class Regrtest: print(line, flush=True) def display_progress(self, test_index, text): - if self.ns.quiet: + quiet = self.ns.quiet + pgo = self.ns.pgo + if quiet: return # "[ 51/405/1] test_tcl passed" - line = f"{test_index:{self.test_count_width}}{self.test_count}" + line = f"{test_index:{self.test_count_width}}{self.test_count_text}" fails = len(self.bad) + len(self.environment_changed) - if fails and not self.ns.pgo: + if fails and not pgo: line = f"{line}/{fails}" self.log(f"[{line}] {text}") @@ -177,15 +190,7 @@ class Regrtest: if ns.xmlpath: support.junit_xml_list = self.testsuite_xml = [] - worker_args = ns.worker_args - if worker_args is not None: - from test.libregrtest.runtest_mp import parse_worker_args - ns, test_name = parse_worker_args(ns.worker_args) - ns.worker_args = worker_args - self.worker_test_name = test_name - - # Strip .py extensions. - removepy(ns.args) + strip_py_suffix(ns.args) if ns.huntrleaks: warmup, repetitions, _ = ns.huntrleaks @@ -202,9 +207,18 @@ class Regrtest: self.ns = ns def find_tests(self, tests): + ns = self.ns + single = ns.single + fromfile = ns.fromfile + pgo = ns.pgo + exclude = ns.exclude + test_dir = ns.testdir + starting_test = ns.start + randomize = ns.randomize + self.tests = tests - if self.ns.single: + if single: self.next_single_filename = os.path.join(self.tmp_dir, 'pynexttest') try: with open(self.next_single_filename, 'r') as fp: @@ -213,12 +227,12 @@ class Regrtest: except OSError: pass - if self.ns.fromfile: + if fromfile: self.tests = [] # regex to match 'test_builtin' in line: # '0:00:00 [ 4/400] test_builtin -- test_dict took 1 sec' regex = re.compile(r'\btest_[a-zA-Z0-9_]+\b') - with open(os.path.join(os_helper.SAVEDCWD, self.ns.fromfile)) as fp: + with open(os.path.join(os_helper.SAVEDCWD, fromfile)) as fp: for line in fp: line = line.split('#', 1)[0] line = line.strip() @@ -226,33 +240,30 @@ class Regrtest: if match is not None: self.tests.append(match.group()) - removepy(self.tests) + strip_py_suffix(self.tests) - if self.ns.pgo: + if pgo: # add default PGO tests if no tests are specified - setup_pgo_tests(self.ns) - - stdtests = STDTESTS[:] - nottests = NOTTESTS.copy() - if self.ns.exclude: - for arg in self.ns.args: - if arg in stdtests: - stdtests.remove(arg) - nottests.add(arg) - self.ns.args = [] - - # if testdir is set, then we are not running the python tests suite, so - # don't add default tests to be executed or skipped (pass empty values) - if self.ns.testdir: - alltests = findtests(self.ns.testdir, list(), set()) - else: - alltests = findtests(self.ns.testdir, stdtests, nottests) + setup_pgo_tests(ns) + + exclude_tests = set() + if exclude: + for arg in ns.args: + exclude_tests.add(arg) + ns.args = [] - if not self.ns.fromfile: - self.selected = self.tests or self.ns.args or alltests + alltests = findtests(testdir=test_dir, exclude=exclude_tests) + + if not fromfile: + self.selected = self.tests or ns.args + if self.selected: + self.selected = split_test_packages(self.selected) + else: + self.selected = alltests else: self.selected = self.tests - if self.ns.single: + + if single: self.selected = self.selected[:1] try: pos = alltests.index(self.selected[0]) @@ -261,17 +272,17 @@ class Regrtest: pass # Remove all the selected tests that precede start if it's set. - if self.ns.start: + if starting_test: try: - del self.selected[:self.selected.index(self.ns.start)] + del self.selected[:self.selected.index(starting_test)] except ValueError: - print("Couldn't find starting test (%s), using all tests" - % self.ns.start, file=sys.stderr) + print(f"Cannot find starting test: {starting_test}") + sys.exit(1) - if self.ns.randomize: - if self.ns.random_seed is None: - self.ns.random_seed = random.randrange(10000000) - random.seed(self.ns.random_seed) + if randomize: + if ns.random_seed is None: + ns.random_seed = random.randrange(10000000) + random.seed(ns.random_seed) random.shuffle(self.selected) def list_tests(self): @@ -289,25 +300,63 @@ class Regrtest: print(test.id()) def list_cases(self): + ns = self.ns + test_dir = ns.testdir support.verbose = False - support.set_match_tests(self.ns.match_tests, self.ns.ignore_tests) + support.set_match_tests(ns.match_tests, ns.ignore_tests) + skipped = [] for test_name in self.selected: - abstest = get_abs_module(self.ns, test_name) + module_name = abs_module_name(test_name, test_dir) try: - suite = unittest.defaultTestLoader.loadTestsFromName(abstest) + suite = unittest.defaultTestLoader.loadTestsFromName(module_name) self._list_cases(suite) except unittest.SkipTest: - self.skipped.append(test_name) + skipped.append(test_name) - if self.skipped: - print(file=sys.stderr) - print(count(len(self.skipped), "test"), "skipped:", file=sys.stderr) - printlist(self.skipped, file=sys.stderr) + if skipped: + sys.stdout.flush() + stderr = sys.stderr + print(file=stderr) + print(count(len(skipped), "test"), "skipped:", file=stderr) + printlist(skipped, file=stderr) - def rerun_failed_tests(self): - self.log() + def get_rerun_match(self, rerun_list) -> MatchTestsDict: + rerun_match_tests = {} + for result in rerun_list: + match_tests = result.get_rerun_match_tests() + # ignore empty match list + if match_tests: + rerun_match_tests[result.test_name] = match_tests + return rerun_match_tests + + def _rerun_failed_tests(self, need_rerun): + # Configure the runner to re-run tests + ns = self.ns + ns.verbose = True + ns.failfast = False + ns.verbose3 = False + ns.forever = False + if ns.use_mp is None: + ns.use_mp = 1 + + # Get tests to re-run + tests = [result.test_name for result in need_rerun] + match_tests = self.get_rerun_match(need_rerun) + self.set_tests(tests) + + # Clear previously failed tests + self.rerun_bad.extend(self.bad) + self.bad.clear() + self.need_rerun.clear() + # Re-run failed tests + self.log(f"Re-running {len(tests)} failed tests in verbose mode in subprocesses") + runtests = RunTests(tests, match_tests=match_tests, rerun=True) + self.all_runtests.append(runtests) + self._run_tests_mp(runtests) + + def rerun_failed_tests(self, need_rerun): if self.ns.python: # Temp patch for https://github.com/python/cpython/issues/94052 self.log( @@ -316,41 +365,10 @@ class Regrtest: ) return - self.ns.verbose = True - self.ns.failfast = False - self.ns.verbose3 = False - - self.first_result = self.get_tests_result() + self.first_state = self.get_tests_state() - self.log("Re-running failed tests in verbose mode") - rerun_list = list(self.need_rerun) - self.need_rerun.clear() - for result in rerun_list: - test_name = result.name - self.rerun.append(test_name) - - errors = result.errors or [] - failures = result.failures or [] - error_names = [test_full_name.split(" ")[0] for (test_full_name, *_) in errors] - failure_names = [test_full_name.split(" ")[0] for (test_full_name, *_) in failures] - self.ns.verbose = True - orig_match_tests = self.ns.match_tests - if errors or failures: - if self.ns.match_tests is None: - self.ns.match_tests = [] - self.ns.match_tests.extend(error_names) - self.ns.match_tests.extend(failure_names) - matching = "matching: " + ", ".join(self.ns.match_tests) - self.log(f"Re-running {test_name} in verbose mode ({matching})") - else: - self.log(f"Re-running {test_name} in verbose mode") - result = runtest(self.ns, test_name) - self.ns.match_tests = orig_match_tests - - self.accumulate_result(result, rerun=True) - - if isinstance(result, Interrupted): - break + print() + self._rerun_failed_tests(need_rerun) if self.bad: print(count(len(self.bad), 'test'), "failed again:") @@ -359,12 +377,16 @@ class Regrtest: self.display_result() def display_result(self): + pgo = self.ns.pgo + quiet = self.ns.quiet + print_slow = self.ns.print_slow + # If running the test suite for PGO then no one cares about results. - if self.ns.pgo: + if pgo: return print() - print("== Tests result: %s ==" % self.get_tests_result()) + print("== Tests result: %s ==" % self.get_tests_state()) if self.interrupted: print("Test suite interrupted by signal SIGINT.") @@ -375,7 +397,7 @@ class Regrtest: print(count(len(omitted), "test"), "omitted:") printlist(omitted) - if self.good and not self.ns.quiet: + if self.good and not quiet: print() if (not self.bad and not self.skipped @@ -384,7 +406,7 @@ class Regrtest: print("All", end=' ') print(count(len(self.good), "test"), "OK.") - if self.ns.print_slow: + if print_slow: self.test_times.sort(reverse=True) print() print("10 slowest tests:") @@ -402,11 +424,16 @@ class Regrtest: count(len(self.environment_changed), "test"))) printlist(self.environment_changed) - if self.skipped and not self.ns.quiet: + if self.skipped and not quiet: print() print(count(len(self.skipped), "test"), "skipped:") printlist(self.skipped) + if self.resource_denied and not quiet: + print() + print(count(len(self.resource_denied), "test"), "skipped (resource denied):") + printlist(self.resource_denied) + if self.rerun: print() print("%s:" % count(len(self.rerun), "re-run test")) @@ -417,91 +444,125 @@ class Regrtest: print(count(len(self.run_no_tests), "test"), "run no tests:") printlist(self.run_no_tests) - def run_tests_sequential(self): - if self.ns.trace: + def run_test(self, test_index, test_name, previous_test, save_modules): + text = test_name + if previous_test: + text = '%s -- %s' % (text, previous_test) + self.display_progress(test_index, text) + + if self.tracer: + # If we're tracing code coverage, then we don't exit with status + # if on a false return value from main. + cmd = ('result = runtest(self.ns, test_name); ' + 'self.accumulate_result(result)') + ns = dict(locals()) + self.tracer.runctx(cmd, globals=globals(), locals=ns) + result = ns['result'] + else: + result = runtest(self.ns, test_name) + self.accumulate_result(result) + + # Unload the newly imported modules (best effort finalization) + for module in sys.modules.keys(): + if module not in save_modules and module.startswith("test."): + support.unload(module) + + return result + + def run_tests_sequentially(self, runtests): + ns = self.ns + coverage = ns.trace + fail_fast = ns.failfast + fail_env_changed = ns.fail_env_changed + timeout = ns.timeout + + if coverage: import trace self.tracer = trace.Trace(trace=False, count=True) save_modules = sys.modules.keys() msg = "Run tests sequentially" - if self.ns.timeout: - msg += " (timeout: %s)" % format_duration(self.ns.timeout) + if timeout: + msg += " (timeout: %s)" % format_duration(timeout) self.log(msg) previous_test = None - for test_index, test_name in enumerate(self.tests, 1): - start_time = time.monotonic() - - text = test_name - if previous_test: - text = '%s -- %s' % (text, previous_test) - self.display_progress(test_index, text) - - if self.tracer: - # If we're tracing code coverage, then we don't exit with status - # if on a false return value from main. - cmd = ('result = runtest(self.ns, test_name); ' - 'self.accumulate_result(result)') - ns = dict(locals()) - self.tracer.runctx(cmd, globals=globals(), locals=ns) - result = ns['result'] - else: - result = runtest(self.ns, test_name) - self.accumulate_result(result) + tests_iter = runtests.iter_tests() + for test_index, test_name in enumerate(tests_iter, 1): + start_time = time.perf_counter() - if isinstance(result, Interrupted): + result = self.run_test(test_index, test_name, + previous_test, save_modules) + + if result.must_stop(fail_fast, fail_env_changed): break previous_test = str(result) - test_time = time.monotonic() - start_time + test_time = time.perf_counter() - start_time if test_time >= PROGRESS_MIN_TIME: previous_test = "%s in %s" % (previous_test, format_duration(test_time)) - elif isinstance(result, Passed): + elif result.state == State.PASSED: # be quiet: say nothing if the test passed shortly previous_test = None - # Unload the newly imported modules (best effort finalization) - for module in sys.modules.keys(): - if module not in save_modules and module.startswith("test."): - support.unload(module) - - if self.ns.failfast and is_failed(result, self.ns): - break - if previous_test: print(previous_test) - def _test_forever(self, tests): - while True: - for test_name in tests: - yield test_name - if self.bad: - return - if self.ns.fail_env_changed and self.environment_changed: - return - def display_header(self): # Print basic platform information print("==", platform.python_implementation(), *sys.version.split()) print("==", platform.platform(aliased=True), "%s-endian" % sys.byteorder) + print("== Python build:", ' '.join(get_build_info())) print("== cwd:", os.getcwd()) cpu_count = os.cpu_count() if cpu_count: print("== CPU count:", cpu_count) print("== encodings: locale=%s, FS=%s" % (locale.getencoding(), sys.getfilesystemencoding())) + self.display_sanitizers() + + def display_sanitizers(self): + # This makes it easier to remember what to set in your local + # environment when trying to reproduce a sanitizer failure. + asan = support.check_sanitizer(address=True) + msan = support.check_sanitizer(memory=True) + ubsan = support.check_sanitizer(ub=True) + sanitizers = [] + if asan: + sanitizers.append("address") + if msan: + sanitizers.append("memory") + if ubsan: + sanitizers.append("undefined behavior") + if not sanitizers: + return + + print(f"== sanitizers: {', '.join(sanitizers)}") + for sanitizer, env_var in ( + (asan, "ASAN_OPTIONS"), + (msan, "MSAN_OPTIONS"), + (ubsan, "UBSAN_OPTIONS"), + ): + options= os.environ.get(env_var) + if sanitizer and options is not None: + print(f"== {env_var}={options!r}") + + def no_tests_run(self): + return not any((self.good, self.bad, self.skipped, self.interrupted, + self.environment_changed)) + + def get_tests_state(self): + fail_env_changed = self.ns.fail_env_changed - def get_tests_result(self): result = [] if self.bad: result.append("FAILURE") - elif self.ns.fail_env_changed and self.environment_changed: + elif fail_env_changed and self.environment_changed: result.append("ENV CHANGED") - elif not any((self.good, self.bad, self.skipped, self.interrupted, - self.environment_changed)): - result.append("NO TEST RUN") + elif self.no_tests_run(): + result.append("NO TESTS RAN") if self.interrupted: result.append("INTERRUPTED") @@ -510,10 +571,40 @@ class Regrtest: result.append("SUCCESS") result = ', '.join(result) - if self.first_result: - result = '%s then %s' % (self.first_result, result) + if self.first_state: + result = '%s then %s' % (self.first_state, result) return result + def _run_tests_mp(self, runtests: RunTests) -> None: + from test.libregrtest.runtest_mp import run_tests_multiprocess + # If we're on windows and this is the parent runner (not a worker), + # track the load average. + if sys.platform == 'win32': + from test.libregrtest.win_utils import WindowsLoadTracker + + try: + self.win_load_tracker = WindowsLoadTracker() + except PermissionError as error: + # Standard accounts may not have access to the performance + # counters. + print(f'Failed to create WindowsLoadTracker: {error}') + + try: + run_tests_multiprocess(self, runtests) + finally: + if self.win_load_tracker is not None: + self.win_load_tracker.close() + self.win_load_tracker = None + + def set_tests(self, tests): + self.tests = tests + if self.ns.forever: + self.test_count_text = '' + self.test_count_width = 3 + else: + self.test_count_text = '/{}'.format(len(self.tests)) + self.test_count_width = len(self.test_count_text) - 1 + def run_tests(self): # For a partial run, we do not need to clutter the output. if (self.ns.header @@ -531,37 +622,14 @@ class Regrtest: if self.ns.randomize: print("Using random seed", self.ns.random_seed) - if self.ns.forever: - self.tests = self._test_forever(list(self.selected)) - self.test_count = '' - self.test_count_width = 3 - else: - self.tests = iter(self.selected) - self.test_count = '/{}'.format(len(self.selected)) - self.test_count_width = len(self.test_count) - 1 - + tests = self.selected + self.set_tests(tests) + runtests = RunTests(tests, forever=self.ns.forever) + self.all_runtests.append(runtests) if self.ns.use_mp: - from test.libregrtest.runtest_mp import run_tests_multiprocess - # If we're on windows and this is the parent runner (not a worker), - # track the load average. - if sys.platform == 'win32' and self.worker_test_name is None: - from test.libregrtest.win_utils import WindowsLoadTracker - - try: - self.win_load_tracker = WindowsLoadTracker() - except PermissionError as error: - # Standard accounts may not have access to the performance - # counters. - print(f'Failed to create WindowsLoadTracker: {error}') - - try: - run_tests_multiprocess(self) - finally: - if self.win_load_tracker is not None: - self.win_load_tracker.close() - self.win_load_tracker = None + self._run_tests_mp(runtests) else: - self.run_tests_sequential() + self.run_tests_sequentially(runtests) def finalize(self): if self.next_single_filename: @@ -576,13 +644,62 @@ class Regrtest: r.write_results(show_missing=True, summary=True, coverdir=self.ns.coverdir) + if self.ns.runleaks: + os.system("leaks %d" % os.getpid()) + + self.save_xml_result() + + def display_summary(self): + duration = time.perf_counter() - self.start_time + first_runtests = self.all_runtests[0] + # the second runtests (re-run failed tests) disables forever, + # use the first runtests + forever = first_runtests.forever + filtered = bool(self.ns.match_tests) or bool(self.ns.ignore_tests) + + # Total duration print() - duration = time.monotonic() - self.start_time print("Total duration: %s" % format_duration(duration)) - print("Tests result: %s" % self.get_tests_result()) - if self.ns.runleaks: - os.system("leaks %d" % os.getpid()) + # Total tests + total = self.total_stats + text = f'run={total.tests_run:,}' + if filtered: + text = f"{text} (filtered)" + stats = [text] + if total.failures: + stats.append(f'failures={total.failures:,}') + if total.skipped: + stats.append(f'skipped={total.skipped:,}') + print(f"Total tests: {' '.join(stats)}") + + # Total test files + all_tests = [self.good, self.bad, self.rerun, + self.skipped, + self.environment_changed, self.run_no_tests] + run = sum(map(len, all_tests)) + text = f'run={run}' + if not forever: + ntest = len(first_runtests.tests) + text = f"{text}/{ntest}" + if filtered: + text = f"{text} (filtered)" + report = [text] + for name, tests in ( + ('failed', self.bad), + ('env_changed', self.environment_changed), + ('skipped', self.skipped), + ('resource_denied', self.resource_denied), + ('rerun', self.rerun), + ('run_no_tests', self.run_no_tests), + ): + if tests: + report.append(f'{name}={len(tests)}') + print(f"Total test files: {' '.join(report)}") + + # Result + result = self.get_tests_state() + print(f"Result: {result}") def save_xml_result(self): if not self.ns.xmlpath and not self.testsuite_xml: @@ -641,6 +758,9 @@ class Regrtest: self.tmp_dir = os.path.abspath(self.tmp_dir) + def is_worker(self): + return (self.ns.worker_args is not None) + def create_temp_dir(self): os.makedirs(self.tmp_dir, exist_ok=True) @@ -653,7 +773,8 @@ class Regrtest: nounce = random.randint(0, 1_000_000) else: nounce = os.getpid() - if self.worker_test_name is not None: + + if self.is_worker(): test_cwd = 'test_python_worker_{}'.format(nounce) else: test_cwd = 'test_python_{}'.format(nounce) @@ -716,46 +837,53 @@ class Regrtest: return None + def get_exitcode(self): + exitcode = 0 + if self.bad: + exitcode = EXITCODE_BAD_TEST + elif self.interrupted: + exitcode = EXITCODE_INTERRUPTED + elif self.ns.fail_env_changed and self.environment_changed: + exitcode = EXITCODE_ENV_CHANGED + elif self.no_tests_run(): + exitcode = EXITCODE_NO_TESTS_RAN + elif self.rerun and self.ns.fail_rerun: + exitcode = EXITCODE_RERUN_FAIL + return exitcode + + def action_run_tests(self): + self.run_tests() + self.display_result() + + need_rerun = self.need_rerun + if self.ns.rerun and need_rerun: + self.rerun_failed_tests(need_rerun) + + self.display_summary() + self.finalize() + def _main(self, tests, kwargs): - if self.worker_test_name is not None: + if self.is_worker(): from test.libregrtest.runtest_mp import run_tests_worker - run_tests_worker(self.ns, self.worker_test_name) + run_tests_worker(self.ns.worker_args) + return if self.ns.wait: input("Press any key to continue...") - support.PGO = self.ns.pgo - support.PGO_EXTENDED = self.ns.pgo_extended - setup_tests(self.ns) - self.find_tests(tests) + exitcode = 0 if self.ns.list_tests: self.list_tests() - sys.exit(0) - - if self.ns.list_cases: + elif self.ns.list_cases: self.list_cases() - sys.exit(0) - - self.run_tests() - self.display_result() - - if self.ns.verbose2 and self.bad: - self.rerun_failed_tests() - - self.finalize() - - self.save_xml_result() + else: + self.action_run_tests() + exitcode = self.get_exitcode() - if self.bad: - sys.exit(2) - if self.interrupted: - sys.exit(130) - if self.ns.fail_env_changed and self.environment_changed: - sys.exit(3) - sys.exit(0) + sys.exit(exitcode) def main(tests=None, **kwargs): diff --git a/Lib/test/libregrtest/refleak.py b/Lib/test/libregrtest/refleak.py index a0538cbb..206802b6 100644 --- a/Lib/test/libregrtest/refleak.py +++ b/Lib/test/libregrtest/refleak.py @@ -73,28 +73,33 @@ def dash_R(ns, test_name, test_func): fd_deltas = [0] * repcount getallocatedblocks = sys.getallocatedblocks gettotalrefcount = sys.gettotalrefcount - _getquickenedcount = sys._getquickenedcount + getunicodeinternedsize = sys.getunicodeinternedsize fd_count = os_helper.fd_count # initialize variables to make pyflakes quiet - rc_before = alloc_before = fd_before = 0 + rc_before = alloc_before = fd_before = interned_before = 0 if not ns.quiet: print("beginning", repcount, "repetitions", file=sys.stderr) print(("1234567890"*(repcount//10 + 1))[:repcount], file=sys.stderr, flush=True) + results = None dash_R_cleanup(fs, ps, pic, zdc, abcs) support.gc_collect() for i in rep_range: - test_func() + results = test_func() dash_R_cleanup(fs, ps, pic, zdc, abcs) support.gc_collect() - # Read memory statistics immediately after the garbage collection - alloc_after = getallocatedblocks() - _getquickenedcount() - rc_after = gettotalrefcount() + # Read memory statistics immediately after the garbage collection. + # Also, readjust the reference counts and alloc blocks by ignoring + # any strings that might have been interned during test_func. These + # strings will be deallocated at runtime shutdown + interned_after = getunicodeinternedsize() + alloc_after = getallocatedblocks() - interned_after + rc_after = gettotalrefcount() - interned_after * 2 fd_after = fd_count() if not ns.quiet: @@ -107,6 +112,7 @@ def dash_R(ns, test_name, test_func): alloc_before = alloc_after rc_before = rc_after fd_before = fd_after + interned_before = interned_after if not ns.quiet: print(file=sys.stderr) @@ -146,7 +152,7 @@ def dash_R(ns, test_name, test_func): print(msg, file=refrep) refrep.flush() failed = True - return failed + return (failed, results) def dash_R_cleanup(fs, ps, pic, zdc, abcs): @@ -168,6 +174,7 @@ def dash_R_cleanup(fs, ps, pic, zdc, abcs): zipimport._zip_directory_cache.update(zdc) # Clear ABC registries, restoring previously saved ABC registries. + # ignore deprecation warning for collections.abc.ByteString abs_classes = [getattr(collections.abc, a) for a in collections.abc.__all__] abs_classes = filter(isabstract, abs_classes) for abc in abs_classes: diff --git a/Lib/test/libregrtest/runtest.py b/Lib/test/libregrtest/runtest.py index 62cf1a3f..16ae0419 100644 --- a/Lib/test/libregrtest/runtest.py +++ b/Lib/test/libregrtest/runtest.py @@ -1,5 +1,6 @@ +import dataclasses +import doctest import faulthandler -import functools import gc import importlib import io @@ -10,6 +11,7 @@ import traceback import unittest from test import support +from test.support import TestStats from test.support import os_helper from test.support import threading_helper from test.libregrtest.cmdline import Namespace @@ -17,181 +19,298 @@ from test.libregrtest.save_env import saved_test_environment from test.libregrtest.utils import clear_caches, format_duration, print_warning +MatchTests = list[str] +MatchTestsDict = dict[str, MatchTests] + + +# Avoid enum.Enum to reduce the number of imports when tests are run +class State: + PASSED = "PASSED" + FAILED = "FAILED" + SKIPPED = "SKIPPED" + UNCAUGHT_EXC = "UNCAUGHT_EXC" + REFLEAK = "REFLEAK" + ENV_CHANGED = "ENV_CHANGED" + RESOURCE_DENIED = "RESOURCE_DENIED" + INTERRUPTED = "INTERRUPTED" + MULTIPROCESSING_ERROR = "MULTIPROCESSING_ERROR" + DID_NOT_RUN = "DID_NOT_RUN" + TIMEOUT = "TIMEOUT" + + @staticmethod + def is_failed(state): + return state in { + State.FAILED, + State.UNCAUGHT_EXC, + State.REFLEAK, + State.MULTIPROCESSING_ERROR, + State.TIMEOUT} + + @staticmethod + def has_meaningful_duration(state): + # Consider that the duration is meaningless for these cases. + # For example, if a whole test file is skipped, its duration + # is unlikely to be the duration of executing its tests, + # but just the duration to execute code which skips the test. + return state not in { + State.SKIPPED, + State.RESOURCE_DENIED, + State.INTERRUPTED, + State.MULTIPROCESSING_ERROR, + State.DID_NOT_RUN} + + @staticmethod + def must_stop(state): + return state in { + State.INTERRUPTED, + State.MULTIPROCESSING_ERROR} + + +# gh-90681: When rerunning tests, we might need to rerun the whole +# class or module suite if some its life-cycle hooks fail. +# Test level hooks are not affected. +_TEST_LIFECYCLE_HOOKS = frozenset(( + 'setUpClass', 'tearDownClass', + 'setUpModule', 'tearDownModule', +)) + +def normalize_test_name(test_full_name, *, is_error=False): + short_name = test_full_name.split(" ")[0] + if is_error and short_name in _TEST_LIFECYCLE_HOOKS: + if test_full_name.startswith(('setUpModule (', 'tearDownModule (')): + # if setUpModule() or tearDownModule() failed, don't filter + # tests with the test file name, don't use use filters. + return None + + # This means that we have a failure in a life-cycle hook, + # we need to rerun the whole module or class suite. + # Basically the error looks like this: + # ERROR: setUpClass (test.test_reg_ex.RegTest) + # or + # ERROR: setUpModule (test.test_reg_ex) + # So, we need to parse the class / module name. + lpar = test_full_name.index('(') + rpar = test_full_name.index(')') + return test_full_name[lpar + 1: rpar].split('.')[-1] + return short_name + + +@dataclasses.dataclass(slots=True) class TestResult: - def __init__( - self, - name: str, - duration_sec: float = 0.0, - xml_data: list[str] | None = None, - ) -> None: - self.name = name - self.duration_sec = duration_sec - self.xml_data = xml_data - - def __str__(self) -> str: - return f"{self.name} finished" - - -class Passed(TestResult): - def __str__(self) -> str: - return f"{self.name} passed" - - -class Failed(TestResult): - def __init__( - self, - name: str, - duration_sec: float = 0.0, - xml_data: list[str] | None = None, - errors: list[tuple[str, str]] | None = None, - failures: list[tuple[str, str]] | None = None, - ) -> None: - super().__init__(name, duration_sec=duration_sec, xml_data=xml_data) - self.errors = errors - self.failures = failures - - def __str__(self) -> str: + test_name: str + state: str | None = None + # Test duration in seconds + duration: float | None = None + xml_data: list[str] | None = None + stats: TestStats | None = None + + # errors and failures copied from support.TestFailedWithDetails + errors: list[tuple[str, str]] | None = None + failures: list[tuple[str, str]] | None = None + + def is_failed(self, fail_env_changed: bool) -> bool: + if self.state == State.ENV_CHANGED: + return fail_env_changed + return State.is_failed(self.state) + + def _format_failed(self): if self.errors and self.failures: le = len(self.errors) lf = len(self.failures) error_s = "error" + ("s" if le > 1 else "") failure_s = "failure" + ("s" if lf > 1 else "") - return f"{self.name} failed ({le} {error_s}, {lf} {failure_s})" + return f"{self.test_name} failed ({le} {error_s}, {lf} {failure_s})" if self.errors: le = len(self.errors) error_s = "error" + ("s" if le > 1 else "") - return f"{self.name} failed ({le} {error_s})" + return f"{self.test_name} failed ({le} {error_s})" if self.failures: lf = len(self.failures) failure_s = "failure" + ("s" if lf > 1 else "") - return f"{self.name} failed ({lf} {failure_s})" - - return f"{self.name} failed" - - -class UncaughtException(Failed): - def __str__(self) -> str: - return f"{self.name} failed (uncaught exception)" - - -class EnvChanged(Failed): - def __str__(self) -> str: - return f"{self.name} failed (env changed)" - - -class RefLeak(Failed): - def __str__(self) -> str: - return f"{self.name} failed (reference leak)" - - -class Skipped(TestResult): - def __str__(self) -> str: - return f"{self.name} skipped" - - -class ResourceDenied(Skipped): - def __str__(self) -> str: - return f"{self.name} skipped (resource denied)" - - -class Interrupted(TestResult): - def __str__(self) -> str: - return f"{self.name} interrupted" - - -class ChildError(Failed): - def __str__(self) -> str: - return f"{self.name} crashed" + return f"{self.test_name} failed ({lf} {failure_s})" + return f"{self.test_name} failed" -class DidNotRun(TestResult): def __str__(self) -> str: - return f"{self.name} ran no tests" - + match self.state: + case State.PASSED: + return f"{self.test_name} passed" + case State.FAILED: + return self._format_failed() + case State.SKIPPED: + return f"{self.test_name} skipped" + case State.UNCAUGHT_EXC: + return f"{self.test_name} failed (uncaught exception)" + case State.REFLEAK: + return f"{self.test_name} failed (reference leak)" + case State.ENV_CHANGED: + return f"{self.test_name} failed (env changed)" + case State.RESOURCE_DENIED: + return f"{self.test_name} skipped (resource denied)" + case State.INTERRUPTED: + return f"{self.test_name} interrupted" + case State.MULTIPROCESSING_ERROR: + return f"{self.test_name} process crashed" + case State.DID_NOT_RUN: + return f"{self.test_name} ran no tests" + case State.TIMEOUT: + return f"{self.test_name} timed out ({format_duration(self.duration)})" + case _: + raise ValueError("unknown result state: {state!r}") + + def has_meaningful_duration(self): + return State.has_meaningful_duration(self.state) + + def set_env_changed(self): + if self.state is None or self.state == State.PASSED: + self.state = State.ENV_CHANGED + + def must_stop(self, fail_fast: bool, fail_env_changed: bool) -> bool: + if State.must_stop(self.state): + return True + if fail_fast and self.is_failed(fail_env_changed): + return True + return False + + def get_rerun_match_tests(self): + match_tests = [] + + errors = self.errors or [] + failures = self.failures or [] + for error_list, is_error in ( + (errors, True), + (failures, False), + ): + for full_name, *_ in error_list: + match_name = normalize_test_name(full_name, is_error=is_error) + if match_name is None: + # 'setUpModule (test.test_sys)': don't filter tests + return None + if not match_name: + error_type = "ERROR" if is_error else "FAIL" + print_warning(f"rerun failed to parse {error_type} test name: " + f"{full_name!r}: don't filter tests") + return None + match_tests.append(match_name) + + return match_tests + + +@dataclasses.dataclass(slots=True, frozen=True) +class RunTests: + tests: list[str] + match_tests: MatchTestsDict | None = None + rerun: bool = False + forever: bool = False + + def get_match_tests(self, test_name) -> MatchTests | None: + if self.match_tests is not None: + return self.match_tests.get(test_name, None) + else: + return None -class Timeout(Failed): - def __str__(self) -> str: - return f"{self.name} timed out ({format_duration(self.duration_sec)})" + def iter_tests(self): + tests = tuple(self.tests) + if self.forever: + while True: + yield from tests + else: + yield from tests # Minimum duration of a test to display its duration or to mention that # the test is running in background PROGRESS_MIN_TIME = 30.0 # seconds -# small set of tests to determine if we have a basically functioning interpreter -# (i.e. if any of these fail, then anything else is likely to follow) -STDTESTS = [ - 'test_grammar', - 'test_opcodes', - 'test_dict', - 'test_builtin', - 'test_exceptions', - 'test_types', - 'test_unittest', - 'test_doctest', - 'test_doctest2', - 'test_support' -] - -# set of tests that we don't want to be executed when using regrtest -NOTTESTS = set() - +#If these test directories are encountered recurse into them and treat each +# test_ .py or dir as a separate test module. This can increase parallelism. +# Beware this can't generally be done for any directory with sub-tests as the +# __init__.py may do things which alter what tests are to be run. -# Storage of uncollectable objects -FOUND_GARBAGE = [] - - -def is_failed(result: TestResult, ns: Namespace) -> bool: - if isinstance(result, EnvChanged): - return ns.fail_env_changed - return isinstance(result, Failed) +SPLITTESTDIRS = { + "test_asyncio", + "test_concurrent_futures", + "test_multiprocessing_fork", + "test_multiprocessing_forkserver", + "test_multiprocessing_spawn", +} def findtestdir(path=None): return path or os.path.dirname(os.path.dirname(__file__)) or os.curdir -def findtests(testdir=None, stdtests=STDTESTS, nottests=NOTTESTS): +def findtests(*, testdir=None, exclude=(), + split_test_dirs=SPLITTESTDIRS, base_mod=""): """Return a list of all applicable test modules.""" testdir = findtestdir(testdir) - names = os.listdir(testdir) tests = [] - others = set(stdtests) | nottests - for name in names: + for name in os.listdir(testdir): mod, ext = os.path.splitext(name) - if mod[:5] == "test_" and ext in (".py", "") and mod not in others: - tests.append(mod) - return stdtests + sorted(tests) + if (not mod.startswith("test_")) or (mod in exclude): + continue + if mod in split_test_dirs: + subdir = os.path.join(testdir, mod) + mod = f"{base_mod or 'test'}.{mod}" + tests.extend(findtests(testdir=subdir, exclude=exclude, + split_test_dirs=split_test_dirs, base_mod=mod)) + elif ext in (".py", ""): + tests.append(f"{base_mod}.{mod}" if base_mod else mod) + return sorted(tests) + + +def split_test_packages(tests, *, testdir=None, exclude=(), + split_test_dirs=SPLITTESTDIRS): + testdir = findtestdir(testdir) + splitted = [] + for name in tests: + if name in split_test_dirs: + subdir = os.path.join(testdir, name) + splitted.extend(findtests(testdir=subdir, exclude=exclude, + split_test_dirs=split_test_dirs, + base_mod=name)) + else: + splitted.append(name) + return splitted -def get_abs_module(ns: Namespace, test_name: str) -> str: - if test_name.startswith('test.') or ns.testdir: +def abs_module_name(test_name: str, test_dir: str | None) -> str: + if test_name.startswith('test.') or test_dir: return test_name else: # Import it from the test package return 'test.' + test_name -def _runtest(ns: Namespace, test_name: str) -> TestResult: - # Handle faulthandler timeout, capture stdout+stderr, XML serialization - # and measure time. +def setup_support(ns: Namespace): + support.PGO = ns.pgo + support.PGO_EXTENDED = ns.pgo_extended + support.set_match_tests(ns.match_tests, ns.ignore_tests) + support.failfast = ns.failfast + support.verbose = ns.verbose + if ns.xmlpath: + support.junit_xml_list = [] + else: + support.junit_xml_list = None + +def _runtest(result: TestResult, ns: Namespace) -> None: + # Capture stdout and stderr, set faulthandler timeout, + # and create JUnit XML report. + verbose = ns.verbose output_on_failure = ns.verbose3 + timeout = ns.timeout use_timeout = ( - ns.timeout is not None and threading_helper.can_start_thread + timeout is not None and threading_helper.can_start_thread ) if use_timeout: - faulthandler.dump_traceback_later(ns.timeout, exit=True) + faulthandler.dump_traceback_later(timeout, exit=True) - start_time = time.perf_counter() try: - support.set_match_tests(ns.match_tests, ns.ignore_tests) - support.junit_xml_list = xml_list = [] if ns.xmlpath else None - if ns.failfast: - support.failfast = True + setup_support(ns) if output_on_failure: support.verbose = True @@ -211,9 +330,9 @@ def _runtest(ns: Namespace, test_name: str) -> TestResult: # warnings will be written to sys.stderr below. print_warning.orig_stderr = stream - result = _runtest_inner(ns, test_name, - display_failure=False) - if not isinstance(result, Passed): + _runtest_env_changed_exc(result, ns, display_failure=False) + # Ignore output if the test passed successfully + if result.state != State.PASSED: output = stream.getvalue() finally: sys.stdout = orig_stdout @@ -225,20 +344,14 @@ def _runtest(ns: Namespace, test_name: str) -> TestResult: sys.stderr.flush() else: # Tell tests to be moderately quiet - support.verbose = ns.verbose - - result = _runtest_inner(ns, test_name, - display_failure=not ns.verbose) + support.verbose = verbose + _runtest_env_changed_exc(result, ns, display_failure=not verbose) + xml_list = support.junit_xml_list if xml_list: import xml.etree.ElementTree as ET - result.xml_data = [ - ET.tostring(x).decode('us-ascii') - for x in xml_list - ] - - result.duration_sec = time.perf_counter() - start_time - return result + result.xml_data = [ET.tostring(x).decode('us-ascii') + for x in xml_list] finally: if use_timeout: faulthandler.cancel_dump_traceback_later() @@ -251,66 +364,91 @@ def runtest(ns: Namespace, test_name: str) -> TestResult: ns -- regrtest namespace of options test_name -- the name of the test - Returns a TestResult sub-class depending on the kind of result received. + Returns a TestResult. If ns.xmlpath is not None, xml_data is a list containing each generated testsuite element. """ + start_time = time.perf_counter() + result = TestResult(test_name) try: - return _runtest(ns, test_name) + _runtest(result, ns) except: if not ns.pgo: msg = traceback.format_exc() print(f"test {test_name} crashed -- {msg}", file=sys.stderr, flush=True) - return Failed(test_name) + result.state = State.UNCAUGHT_EXC + result.duration = time.perf_counter() - start_time + return result -def _test_module(the_module): +def run_unittest(test_mod): loader = unittest.TestLoader() - tests = loader.loadTestsFromModule(the_module) + tests = loader.loadTestsFromModule(test_mod) for error in loader.errors: print(error, file=sys.stderr) if loader.errors: raise Exception("errors while loading tests") - support.run_unittest(tests) + return support.run_unittest(tests) def save_env(ns: Namespace, test_name: str): return saved_test_environment(test_name, ns.verbose, ns.quiet, pgo=ns.pgo) -def _runtest_inner2(ns: Namespace, test_name: str) -> bool: - # Load the test function, run the test function, handle huntrleaks - # to detect leaks. +def regrtest_runner(result, test_func, ns) -> None: + # Run test_func(), collect statistics, and detect reference and memory + # leaks. + if ns.huntrleaks: + from test.libregrtest.refleak import dash_R + refleak, test_result = dash_R(ns, result.test_name, test_func) + else: + test_result = test_func() + refleak = False - abstest = get_abs_module(ns, test_name) + if refleak: + result.state = State.REFLEAK - # remove the module from sys.module to reload it if it was already imported - try: - del sys.modules[abstest] - except KeyError: - pass + match test_result: + case TestStats(): + stats = test_result + case unittest.TestResult(): + stats = TestStats.from_unittest(test_result) + case doctest.TestResults(): + stats = TestStats.from_doctest(test_result) + case None: + print_warning(f"{result.test_name} test runner returned None: {test_func}") + stats = None + case _: + print_warning(f"Unknown test result type: {type(test_result)}") + stats = None - the_module = importlib.import_module(abstest) + result.stats = stats + + +# Storage of uncollectable objects +FOUND_GARBAGE = [] - if ns.huntrleaks: - from test.libregrtest.refleak import dash_R - # If the test has a test_main, that will run the appropriate - # tests. If not, use normal unittest test loading. - test_runner = getattr(the_module, "test_main", None) - if test_runner is None: - test_runner = functools.partial(_test_module, the_module) +def _load_run_test(result: TestResult, ns: Namespace) -> None: + # Load the test function, run the test function. + module_name = abs_module_name(result.test_name, ns.testdir) + + # Remove the module from sys.module to reload it if it was already imported + sys.modules.pop(module_name, None) + + test_mod = importlib.import_module(module_name) + + if hasattr(test_mod, "test_main"): + # https://github.com/python/cpython/issues/89392 + raise Exception(f"Module {result.test_name} defines test_main() which is no longer supported by regrtest") + def test_func(): + return run_unittest(test_mod) try: - with save_env(ns, test_name): - if ns.huntrleaks: - # Return True if the test leaked references - refleak = dash_R(ns, test_name, test_runner) - else: - test_runner() - refleak = False + with save_env(ns, result.test_name): + regrtest_runner(result, test_func, ns) finally: # First kill any dangling references to open files etc. # This can also issue some ResourceWarnings which would otherwise get @@ -318,12 +456,12 @@ def _runtest_inner2(ns: Namespace, test_name: str) -> bool: # failures. support.gc_collect() - cleanup_test_droppings(test_name, ns.verbose) + remove_testfn(result.test_name, ns.verbose) if gc.garbage: support.environment_altered = True - print_warning(f"{test_name} created {len(gc.garbage)} " - f"uncollectable object(s).") + print_warning(f"{result.test_name} created {len(gc.garbage)} " + f"uncollectable object(s)") # move the uncollectable objects somewhere, # so we don't see them again @@ -332,12 +470,9 @@ def _runtest_inner2(ns: Namespace, test_name: str) -> bool: support.reap_children() - return refleak - -def _runtest_inner( - ns: Namespace, test_name: str, display_failure: bool = True -) -> TestResult: +def _runtest_env_changed_exc(result: TestResult, ns: Namespace, + display_failure: bool = True) -> None: # Detect environment changes, handle exceptions. # Reset the environment_altered flag to detect if a test altered @@ -347,80 +482,94 @@ def _runtest_inner( if ns.pgo: display_failure = False + test_name = result.test_name try: clear_caches() support.gc_collect() with save_env(ns, test_name): - refleak = _runtest_inner2(ns, test_name) + _load_run_test(result, ns) except support.ResourceDenied as msg: if not ns.quiet and not ns.pgo: print(f"{test_name} skipped -- {msg}", flush=True) - return ResourceDenied(test_name) + result.state = State.RESOURCE_DENIED + return except unittest.SkipTest as msg: if not ns.quiet and not ns.pgo: print(f"{test_name} skipped -- {msg}", flush=True) - return Skipped(test_name) + result.state = State.SKIPPED + return except support.TestFailedWithDetails as exc: msg = f"test {test_name} failed" if display_failure: msg = f"{msg} -- {exc}" print(msg, file=sys.stderr, flush=True) - return Failed(test_name, errors=exc.errors, failures=exc.failures) + result.state = State.FAILED + result.errors = exc.errors + result.failures = exc.failures + result.stats = exc.stats + return except support.TestFailed as exc: msg = f"test {test_name} failed" if display_failure: msg = f"{msg} -- {exc}" print(msg, file=sys.stderr, flush=True) - return Failed(test_name) + result.state = State.FAILED + result.stats = exc.stats + return except support.TestDidNotRun: - return DidNotRun(test_name) + result.state = State.DID_NOT_RUN + return except KeyboardInterrupt: print() - return Interrupted(test_name) + result.state = State.INTERRUPTED + return except: if not ns.pgo: msg = traceback.format_exc() print(f"test {test_name} crashed -- {msg}", file=sys.stderr, flush=True) - return UncaughtException(test_name) + result.state = State.UNCAUGHT_EXC + return - if refleak: - return RefLeak(test_name) if support.environment_altered: - return EnvChanged(test_name) - return Passed(test_name) - - -def cleanup_test_droppings(test_name: str, verbose: int) -> None: - # Try to clean up junk commonly left behind. While tests shouldn't leave - # any files or directories behind, when a test fails that can be tedious - # for it to arrange. The consequences can be especially nasty on Windows, - # since if a test leaves a file open, it cannot be deleted by name (while - # there's nothing we can do about that here either, we can display the - # name of the offending test, which is a real help). - for name in (os_helper.TESTFN,): - if not os.path.exists(name): - continue + result.set_env_changed() + # Don't override the state if it was already set (REFLEAK or ENV_CHANGED) + if result.state is None: + result.state = State.PASSED + + +def remove_testfn(test_name: str, verbose: int) -> None: + # Try to clean up os_helper.TESTFN if left behind. + # + # While tests shouldn't leave any files or directories behind, when a test + # fails that can be tedious for it to arrange. The consequences can be + # especially nasty on Windows, since if a test leaves a file open, it + # cannot be deleted by name (while there's nothing we can do about that + # here either, we can display the name of the offending test, which is a + # real help). + name = os_helper.TESTFN + if not os.path.exists(name): + return + + if os.path.isdir(name): + import shutil + kind, nuker = "directory", shutil.rmtree + elif os.path.isfile(name): + kind, nuker = "file", os.unlink + else: + raise RuntimeError(f"os.path says {name!r} exists but is neither " + f"directory nor file") - if os.path.isdir(name): - import shutil - kind, nuker = "directory", shutil.rmtree - elif os.path.isfile(name): - kind, nuker = "file", os.unlink - else: - raise RuntimeError(f"os.path says {name!r} exists but is neither " - f"directory nor file") - - if verbose: - print_warning(f"{test_name} left behind {kind} {name!r}") - support.environment_altered = True - - try: - import stat - # fix possible permissions problems that might prevent cleanup - os.chmod(name, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO) - nuker(name) - except Exception as exc: - print_warning(f"{test_name} left behind {kind} {name!r} " - f"and it couldn't be removed: {exc}") + if verbose: + print_warning(f"{test_name} left behind {kind} {name!r}") + support.environment_altered = True + + try: + import stat + # fix possible permissions problems that might prevent cleanup + os.chmod(name, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO) + nuker(name) + except Exception as exc: + print_warning(f"{test_name} left behind {kind} {name!r} " + f"and it couldn't be removed: {exc}") diff --git a/Lib/test/libregrtest/runtest_mp.py b/Lib/test/libregrtest/runtest_mp.py index c6a4dae2..60089554 100644 --- a/Lib/test/libregrtest/runtest_mp.py +++ b/Lib/test/libregrtest/runtest_mp.py @@ -1,6 +1,7 @@ +import dataclasses import faulthandler import json -import os +import os.path import queue import signal import subprocess @@ -13,11 +14,13 @@ from typing import NamedTuple, NoReturn, Literal, Any, TextIO from test import support from test.support import os_helper +from test.support import TestStats from test.libregrtest.cmdline import Namespace from test.libregrtest.main import Regrtest from test.libregrtest.runtest import ( - runtest, is_failed, TestResult, Interrupted, Timeout, ChildError, PROGRESS_MIN_TIME) + runtest, TestResult, State, PROGRESS_MIN_TIME, + MatchTests, RunTests) from test.libregrtest.setup import setup_tests from test.libregrtest.utils import format_duration, print_warning @@ -41,26 +44,54 @@ JOIN_TIMEOUT = 30.0 # seconds USE_PROCESS_GROUP = (hasattr(os, "setsid") and hasattr(os, "killpg")) -def must_stop(result: TestResult, ns: Namespace) -> bool: - if isinstance(result, Interrupted): - return True - if ns.failfast and is_failed(result, ns): - return True - return False +@dataclasses.dataclass(slots=True) +class WorkerJob: + test_name: str + namespace: Namespace + rerun: bool = False + match_tests: MatchTests | None = None -def parse_worker_args(worker_args) -> tuple[Namespace, str]: - ns_dict, test_name = json.loads(worker_args) - ns = Namespace(**ns_dict) - return (ns, test_name) +class _EncodeWorkerJob(json.JSONEncoder): + def default(self, o: Any) -> dict[str, Any]: + match o: + case WorkerJob(): + result = dataclasses.asdict(o) + result["__worker_job__"] = True + return result + case Namespace(): + result = vars(o) + result["__namespace__"] = True + return result + case _: + return super().default(o) + + +def _decode_worker_job(d: dict[str, Any]) -> WorkerJob | dict[str, Any]: + if "__worker_job__" in d: + d.pop('__worker_job__') + return WorkerJob(**d) + if "__namespace__" in d: + d.pop('__namespace__') + return Namespace(**d) + else: + return d + +def _parse_worker_args(worker_json: str) -> tuple[Namespace, str]: + return json.loads(worker_json, + object_hook=_decode_worker_job) -def run_test_in_subprocess(testname: str, ns: Namespace, stdout_fh: TextIO) -> subprocess.Popen: - ns_dict = vars(ns) - worker_args = (ns_dict, testname) - worker_args = json.dumps(worker_args) - if ns.python is not None: - executable = ns.python + +def run_test_in_subprocess(worker_job: WorkerJob, + output_file: TextIO, + tmp_dir: str | None = None) -> subprocess.Popen: + ns = worker_job.namespace + python = ns.python + worker_args = json.dumps(worker_job, cls=_EncodeWorkerJob) + + if python is not None: + executable = python else: executable = [sys.executable] cmd = [*executable, *support.args_from_interpreter_flags(), @@ -68,13 +99,20 @@ def run_test_in_subprocess(testname: str, ns: Namespace, stdout_fh: TextIO) -> s '-m', 'test.regrtest', '--worker-args', worker_args] + env = dict(os.environ) + if tmp_dir is not None: + env['TMPDIR'] = tmp_dir + env['TEMP'] = tmp_dir + env['TMP'] = tmp_dir + # Running the child from the same working directory as regrtest's original # invocation ensures that TEMPDIR for the child is the same when # sysconfig.is_python_build() is true. See issue 15300. kw = dict( - stdout=stdout_fh, + env=env, + stdout=output_file, # bpo-45410: Write stderr into stdout to keep messages order - stderr=stdout_fh, + stderr=output_file, text=True, close_fds=(os.name != 'nt'), cwd=os_helper.SAVEDCWD, @@ -84,11 +122,27 @@ def run_test_in_subprocess(testname: str, ns: Namespace, stdout_fh: TextIO) -> s return subprocess.Popen(cmd, **kw) -def run_tests_worker(ns: Namespace, test_name: str) -> NoReturn: +def run_tests_worker(worker_json: str) -> NoReturn: + worker_job = _parse_worker_args(worker_json) + ns = worker_job.namespace + test_name = worker_job.test_name + rerun = worker_job.rerun + match_tests = worker_job.match_tests + setup_tests(ns) - result = runtest(ns, test_name) + if rerun: + if match_tests: + matching = "matching: " + ", ".join(match_tests) + print(f"Re-running {test_name} in verbose mode ({matching})", flush=True) + else: + print(f"Re-running {test_name} in verbose mode", flush=True) + ns.verbose = True + if match_tests is not None: + ns.match_tests = match_tests + + result = runtest(ns, test_name) print() # Force a newline (just in case) # Serialize TestResult as dict in JSON @@ -122,8 +176,8 @@ class MultiprocessIterator: class MultiprocessResult(NamedTuple): result: TestResult # bpo-45410: stderr is written into stdout to keep messages order - stdout: str - error_msg: str + worker_stdout: str | None = None + err_msg: str | None = None ExcStr = str @@ -138,11 +192,13 @@ class TestWorkerProcess(threading.Thread): def __init__(self, worker_id: int, runner: "MultiprocessTestRunner") -> None: super().__init__() self.worker_id = worker_id + self.runtests = runner.runtests self.pending = runner.pending self.output = runner.output self.ns = runner.ns self.timeout = runner.worker_timeout self.regrtest = runner.regrtest + self.rerun = runner.rerun self.current_test_name = None self.start_time = None self._popen = None @@ -201,18 +257,16 @@ class TestWorkerProcess(threading.Thread): def mp_result_error( self, test_result: TestResult, - stdout: str = '', + stdout: str | None = None, err_msg=None ) -> MultiprocessResult: - test_result.duration_sec = time.monotonic() - self.start_time return MultiprocessResult(test_result, stdout, err_msg) - def _run_process(self, test_name: str, stdout_fh: TextIO) -> int: - self.start_time = time.monotonic() - - self.current_test_name = test_name + def _run_process(self, worker_job, output_file: TextIO, + tmp_dir: str | None = None) -> int: + self.current_test_name = worker_job.test_name try: - popen = run_test_in_subprocess(test_name, self.ns, stdout_fh) + popen = run_test_in_subprocess(worker_job, output_file, tmp_dir) self._killed = False self._popen = popen @@ -269,40 +323,80 @@ class TestWorkerProcess(threading.Thread): encoding = locale.getencoding() else: encoding = sys.stdout.encoding + + match_tests = self.runtests.get_match_tests(test_name) + # gh-94026: Write stdout+stderr to a tempfile as workaround for # non-blocking pipes on Emscripten with NodeJS. - with tempfile.TemporaryFile('w+', encoding=encoding) as stdout_fh: + with tempfile.TemporaryFile('w+', encoding=encoding) as stdout_file: + worker_job = WorkerJob(test_name, + namespace=self.ns, + rerun=self.rerun, + match_tests=match_tests) # gh-93353: Check for leaked temporary files in the parent process, # since the deletion of temporary files can happen late during # Python finalization: too late for libregrtest. - retcode = self._run_process(test_name, stdout_fh) - stdout_fh.seek(0) - stdout = stdout_fh.read().strip() + if not support.is_wasi: + # Don't check for leaked temporary files and directories if Python is + # run on WASI. WASI don't pass environment variables like TMPDIR to + # worker processes. + tmp_dir = tempfile.mkdtemp(prefix="test_python_") + tmp_dir = os.path.abspath(tmp_dir) + try: + retcode = self._run_process(worker_job, stdout_file, tmp_dir) + finally: + tmp_files = os.listdir(tmp_dir) + os_helper.rmtree(tmp_dir) + else: + retcode = self._run_process(worker_job, stdout_file) + tmp_files = () + stdout_file.seek(0) + + try: + stdout = stdout_file.read().strip() + except Exception as exc: + # gh-101634: Catch UnicodeDecodeError if stdout cannot be + # decoded from encoding + err_msg = f"Cannot read process stdout: {exc}" + result = TestResult(test_name, state=State.MULTIPROCESSING_ERROR) + return self.mp_result_error(result, err_msg=err_msg) if retcode is None: - return self.mp_result_error(Timeout(test_name), stdout) + result = TestResult(test_name, state=State.TIMEOUT) + return self.mp_result_error(result, stdout) err_msg = None if retcode != 0: err_msg = "Exit code %s" % retcode else: - stdout, _, result = stdout.rpartition("\n") + stdout, _, worker_json = stdout.rpartition("\n") stdout = stdout.rstrip() - if not result: + if not worker_json: err_msg = "Failed to parse worker stdout" else: try: # deserialize run_tests_worker() output - result = json.loads(result, object_hook=decode_test_result) + result = json.loads(worker_json, + object_hook=decode_test_result) except Exception as exc: err_msg = "Failed to parse worker JSON: %s" % exc - if err_msg is not None: - return self.mp_result_error(ChildError(test_name), stdout, err_msg) + if err_msg: + result = TestResult(test_name, state=State.MULTIPROCESSING_ERROR) + return self.mp_result_error(result, stdout, err_msg) - return MultiprocessResult(result, stdout, err_msg) + if tmp_files: + msg = (f'\n\n' + f'Warning -- {test_name} leaked temporary files ' + f'({len(tmp_files)}): {", ".join(sorted(tmp_files))}') + stdout += msg + result.set_env_changed() + + return MultiprocessResult(result, stdout) def run(self) -> None: + fail_fast = self.ns.failfast + fail_env_changed = self.ns.fail_env_changed while not self._stopped: try: try: @@ -310,10 +404,12 @@ class TestWorkerProcess(threading.Thread): except StopIteration: break + self.start_time = time.monotonic() mp_result = self._runtest(test_name) + mp_result.result.duration = time.monotonic() - self.start_time self.output.put((False, mp_result)) - if must_stop(mp_result.result, self.ns): + if mp_result.result.must_stop(fail_fast, fail_env_changed): break except ExitThread: break @@ -369,29 +465,36 @@ def get_running(workers: list[TestWorkerProcess]) -> list[TestWorkerProcess]: class MultiprocessTestRunner: - def __init__(self, regrtest: Regrtest) -> None: + def __init__(self, regrtest: Regrtest, runtests: RunTests) -> None: + ns = regrtest.ns + timeout = ns.timeout + self.regrtest = regrtest + self.runtests = runtests + self.rerun = runtests.rerun self.log = self.regrtest.log - self.ns = regrtest.ns + self.ns = ns self.output: queue.Queue[QueueOutput] = queue.Queue() - self.pending = MultiprocessIterator(self.regrtest.tests) - if self.ns.timeout is not None: + tests_iter = runtests.iter_tests() + self.pending = MultiprocessIterator(tests_iter) + if timeout is not None: # Rely on faulthandler to kill a worker process. This timouet is # when faulthandler fails to kill a worker process. Give a maximum # of 5 minutes to faulthandler to kill the worker. - self.worker_timeout = min(self.ns.timeout * 1.5, - self.ns.timeout + 5 * 60) + self.worker_timeout = min(timeout * 1.5, timeout + 5 * 60) else: self.worker_timeout = None self.workers = None def start_workers(self) -> None: + use_mp = self.ns.use_mp + timeout = self.ns.timeout self.workers = [TestWorkerProcess(index, self) - for index in range(1, self.ns.use_mp + 1)] + for index in range(1, use_mp + 1)] msg = f"Run tests in parallel using {len(self.workers)} child processes" - if self.ns.timeout: + if timeout: msg += (" (timeout: %s, worker timeout: %s)" - % (format_duration(self.ns.timeout), + % (format_duration(timeout), format_duration(self.worker_timeout))) self.log(msg) for worker in self.workers: @@ -405,6 +508,7 @@ class MultiprocessTestRunner: worker.wait_stopped(start_time) def _get_result(self) -> QueueOutput | None: + pgo = self.ns.pgo use_faulthandler = (self.ns.timeout is not None) timeout = PROGRESS_UPDATE @@ -423,7 +527,7 @@ class MultiprocessTestRunner: # display progress running = get_running(self.workers) - if running and not self.ns.pgo: + if running and not pgo: self.log('running: %s' % ', '.join(running)) # all worker threads are done: consume pending results @@ -434,40 +538,46 @@ class MultiprocessTestRunner: def display_result(self, mp_result: MultiprocessResult) -> None: result = mp_result.result + pgo = self.ns.pgo text = str(result) - if mp_result.error_msg is not None: - # CHILD_ERROR - text += ' (%s)' % mp_result.error_msg - elif (result.duration_sec >= PROGRESS_MIN_TIME and not self.ns.pgo): - text += ' (%s)' % format_duration(result.duration_sec) + if mp_result.err_msg: + # MULTIPROCESSING_ERROR + text += ' (%s)' % mp_result.err_msg + elif (result.duration >= PROGRESS_MIN_TIME and not pgo): + text += ' (%s)' % format_duration(result.duration) running = get_running(self.workers) - if running and not self.ns.pgo: + if running and not pgo: text += ' -- running: %s' % ', '.join(running) self.regrtest.display_progress(self.test_index, text) def _process_result(self, item: QueueOutput) -> bool: """Returns True if test runner must stop.""" + rerun = self.runtests.rerun if item[0]: # Thread got an exception format_exc = item[1] print_warning(f"regrtest worker thread failed: {format_exc}") - return True + result = TestResult("<regrtest worker>", state=State.MULTIPROCESSING_ERROR) + self.regrtest.accumulate_result(result, rerun=rerun) + return result self.test_index += 1 mp_result = item[1] - self.regrtest.accumulate_result(mp_result.result) + result = mp_result.result + self.regrtest.accumulate_result(result, rerun=rerun) self.display_result(mp_result) - if mp_result.stdout: - print(mp_result.stdout, flush=True) - - if must_stop(mp_result.result, self.ns): - return True + if mp_result.worker_stdout: + print(mp_result.worker_stdout, flush=True) - return False + return result def run_tests(self) -> None: + fail_fast = self.ns.failfast + fail_env_changed = self.ns.fail_env_changed + timeout = self.ns.timeout + self.start_workers() self.test_index = 0 @@ -477,14 +587,14 @@ class MultiprocessTestRunner: if item is None: break - stop = self._process_result(item) - if stop: + result = self._process_result(item) + if result.must_stop(fail_fast, fail_env_changed): break except KeyboardInterrupt: print() self.regrtest.interrupted = True finally: - if self.ns.timeout is not None: + if timeout is not None: faulthandler.cancel_dump_traceback_later() # Always ensure that all worker processes are no longer @@ -493,8 +603,8 @@ class MultiprocessTestRunner: self.stop_workers() -def run_tests_multiprocess(regrtest: Regrtest) -> None: - MultiprocessTestRunner(regrtest).run_tests() +def run_tests_multiprocess(regrtest: Regrtest, runtests: RunTests) -> None: + MultiprocessTestRunner(regrtest, runtests).run_tests() class EncodeTestResult(json.JSONEncoder): @@ -502,7 +612,7 @@ class EncodeTestResult(json.JSONEncoder): def default(self, o: Any) -> dict[str, Any]: if isinstance(o, TestResult): - result = vars(o) + result = dataclasses.asdict(o) result["__test_result__"] = o.__class__.__name__ return result @@ -515,19 +625,7 @@ def decode_test_result(d: dict[str, Any]) -> TestResult | dict[str, Any]: if "__test_result__" not in d: return d - cls_name = d.pop("__test_result__") - for cls in get_all_test_result_classes(): - if cls.__name__ == cls_name: - return cls(**d) - - -def get_all_test_result_classes() -> set[type[TestResult]]: - prev_count = 0 - classes = {TestResult} - while len(classes) > prev_count: - prev_count = len(classes) - to_add = [] - for cls in classes: - to_add.extend(cls.__subclasses__()) - classes.update(to_add) - return classes + d.pop('__test_result__') + if d['stats'] is not None: + d['stats'] = TestStats(**d['stats']) + return TestResult(**d) diff --git a/Lib/test/libregrtest/save_env.py b/Lib/test/libregrtest/save_env.py index 60c9be24..164fe980 100644 --- a/Lib/test/libregrtest/save_env.py +++ b/Lib/test/libregrtest/save_env.py @@ -23,7 +23,7 @@ class SkipTestEnvironment(Exception): class saved_test_environment: """Save bits of the test environment and restore them at block exit. - with saved_test_environment(testname, verbose, quiet): + with saved_test_environment(test_name, verbose, quiet): #stuff Unless quiet is True, a warning is printed to stderr if any of @@ -34,8 +34,8 @@ class saved_test_environment: items is also printed. """ - def __init__(self, testname, verbose=0, quiet=False, *, pgo=False): - self.testname = testname + def __init__(self, test_name, verbose=0, quiet=False, *, pgo=False): + self.test_name = test_name self.verbose = verbose self.quiet = quiet self.pgo = pgo @@ -161,11 +161,11 @@ class saved_test_environment: warnings.filters[:] = saved_filters[2] def get_asyncore_socket_map(self): - asyncore = sys.modules.get('asyncore') + asyncore = sys.modules.get('test.support.asyncore') # XXX Making a copy keeps objects alive until __exit__ gets called. return asyncore and asyncore.socket_map.copy() or {} def restore_asyncore_socket_map(self, saved_map): - asyncore = sys.modules.get('asyncore') + asyncore = sys.modules.get('test.support.asyncore') if asyncore is not None: asyncore.close_all(ignore_all=True) asyncore.socket_map.update(saved_map) @@ -257,8 +257,10 @@ class saved_test_environment: sysconfig._INSTALL_SCHEMES.update(saved[2]) def get_files(self): + # XXX: Maybe add an allow-list here? return sorted(fn + ('/' if os.path.isdir(fn) else '') - for fn in os.listdir()) + for fn in os.listdir() + if not fn.startswith(".hypothesis")) def restore_files(self, saved_value): fn = os_helper.TESTFN if fn not in saved_value and (fn + '/') not in saved_value: @@ -321,7 +323,7 @@ class saved_test_environment: restore(original) if not self.quiet and not self.pgo: print_warning( - f"{name} was modified by {self.testname}\n" + f"{name} was modified by {self.test_name}\n" f" Before: {original}\n" f" After: {current} ") return False diff --git a/Lib/test/libregrtest/setup.py b/Lib/test/libregrtest/setup.py index c097d6d5..b76bece7 100644 --- a/Lib/test/libregrtest/setup.py +++ b/Lib/test/libregrtest/setup.py @@ -141,7 +141,7 @@ def _adjust_resource_limits(): """Adjust the system resource limits (ulimit) if needed.""" try: import resource - from resource import RLIMIT_NOFILE, RLIM_INFINITY + from resource import RLIMIT_NOFILE except ImportError: return fd_limit, max_fds = resource.getrlimit(RLIMIT_NOFILE) diff --git a/Lib/test/libregrtest/utils.py b/Lib/test/libregrtest/utils.py index 8578a028..5e16b1ae 100644 --- a/Lib/test/libregrtest/utils.py +++ b/Lib/test/libregrtest/utils.py @@ -1,6 +1,7 @@ import math import os.path import sys +import sysconfig import textwrap from test import support @@ -30,7 +31,7 @@ def format_duration(seconds): return ' '.join(parts) -def removepy(names): +def strip_py_suffix(names: list[str]): if not names: return for idx, name in enumerate(names): @@ -124,15 +125,6 @@ def clear_caches(): if stream is not None: stream.flush() - # Clear assorted module caches. - # Don't worry about resetting the cache if the module is not loaded - try: - distutils_dir_util = sys.modules['distutils.dir_util'] - except KeyError: - pass - else: - distutils_dir_util._path_created.clear() - try: re = sys.modules['re'] except KeyError: @@ -210,3 +202,101 @@ def clear_caches(): else: for f in typing._cleanups: f() + + try: + fractions = sys.modules['fractions'] + except KeyError: + pass + else: + fractions._hash_algorithm.cache_clear() + + try: + inspect = sys.modules['inspect'] + except KeyError: + pass + else: + inspect._shadowed_dict_from_mro_tuple.cache_clear() + + +def get_build_info(): + # Get most important configure and build options as a list of strings. + # Example: ['debug', 'ASAN+MSAN'] or ['release', 'LTO+PGO']. + + config_args = sysconfig.get_config_var('CONFIG_ARGS') or '' + cflags = sysconfig.get_config_var('PY_CFLAGS') or '' + cflags_nodist = sysconfig.get_config_var('PY_CFLAGS_NODIST') or '' + ldflags_nodist = sysconfig.get_config_var('PY_LDFLAGS_NODIST') or '' + + build = [] + if hasattr(sys, 'gettotalrefcount'): + # --with-pydebug + build.append('debug') + + if '-DNDEBUG' in (cflags + cflags_nodist): + build.append('without_assert') + else: + build.append('release') + + if '--with-assertions' in config_args: + build.append('with_assert') + elif '-DNDEBUG' not in (cflags + cflags_nodist): + build.append('with_assert') + + # --enable-framework=name + framework = sysconfig.get_config_var('PYTHONFRAMEWORK') + if framework: + build.append(f'framework={framework}') + + # --enable-shared + shared = int(sysconfig.get_config_var('PY_ENABLE_SHARED') or '0') + if shared: + build.append('shared') + + # --with-lto + optimizations = [] + if '-flto=thin' in ldflags_nodist: + optimizations.append('ThinLTO') + elif '-flto' in ldflags_nodist: + optimizations.append('LTO') + + # --enable-optimizations + pgo_options = ( + # GCC + '-fprofile-use', + # clang: -fprofile-instr-use=code.profclangd + '-fprofile-instr-use', + # ICC + "-prof-use", + ) + if any(option in cflags_nodist for option in pgo_options): + optimizations.append('PGO') + if optimizations: + build.append('+'.join(optimizations)) + + # --with-address-sanitizer + sanitizers = [] + if support.check_sanitizer(address=True): + sanitizers.append("ASAN") + # --with-memory-sanitizer + if support.check_sanitizer(memory=True): + sanitizers.append("MSAN") + # --with-undefined-behavior-sanitizer + if support.check_sanitizer(ub=True): + sanitizers.append("UBSAN") + if sanitizers: + build.append('+'.join(sanitizers)) + + # --with-trace-refs + if hasattr(sys, 'getobjects'): + build.append("TraceRefs") + # --enable-pystats + if hasattr(sys, '_stats_on'): + build.append("pystats") + # --with-valgrind + if sysconfig.get_config_var('WITH_VALGRIND'): + build.append("valgrind") + # --with-dtrace + if sysconfig.get_config_var('WITH_DTRACE'): + build.append("dtrace") + + return build diff --git a/Lib/test/list_tests.py b/Lib/test/list_tests.py index f7eea88c..b1ef3325 100644 --- a/Lib/test/list_tests.py +++ b/Lib/test/list_tests.py @@ -3,11 +3,10 @@ Tests common to list and UserList.UserList """ import sys -import os from functools import cmp_to_key -from test import support, seq_tests -from test.support import ALWAYS_EQ, NEVER_EQ +from test import seq_tests +from test.support import ALWAYS_EQ, NEVER_EQ, C_RECURSION_LIMIT class CommonTest(seq_tests.CommonTest): @@ -62,7 +61,7 @@ class CommonTest(seq_tests.CommonTest): def test_repr_deep(self): a = self.type2test([]) - for i in range(sys.getrecursionlimit() + 100): + for i in range(C_RECURSION_LIMIT + 1): a = self.type2test([a]) self.assertRaises(RecursionError, repr, a) diff --git a/Lib/test/lock_tests.py b/Lib/test/lock_tests.py index f16c7ed9..a4f52cb2 100644 --- a/Lib/test/lock_tests.py +++ b/Lib/test/lock_tests.py @@ -2,7 +2,6 @@ Various tests for synchronization primitives. """ -import os import gc import sys import time diff --git a/Lib/test/mapping_tests.py b/Lib/test/mapping_tests.py index 613206a0..5492bbf8 100644 --- a/Lib/test/mapping_tests.py +++ b/Lib/test/mapping_tests.py @@ -2,6 +2,7 @@ import unittest import collections import sys +from test.support import C_RECURSION_LIMIT class BasicTestMappingProtocol(unittest.TestCase): @@ -624,7 +625,7 @@ class TestHashMappingProtocol(TestMappingProtocol): def test_repr_deep(self): d = self._empty_mapping() - for i in range(sys.getrecursionlimit() + 100): + for i in range(C_RECURSION_LIMIT + 1): d0 = d d = self._empty_mapping() d[1] = d0 diff --git a/Lib/test/memory_watchdog.py b/Lib/test/memory_watchdog.py index 88cca8d3..fee062ec 100644 --- a/Lib/test/memory_watchdog.py +++ b/Lib/test/memory_watchdog.py @@ -5,20 +5,13 @@ and print it out, until terminated.""" # If the process crashes, reading from the /proc entry will fail with ESRCH. -import os import sys import time +from test.support import get_pagesize -try: - page_size = os.sysconf('SC_PAGESIZE') -except (ValueError, AttributeError): - try: - page_size = os.sysconf('SC_PAGE_SIZE') - except (ValueError, AttributeError): - page_size = 4096 - while True: + page_size = get_pagesize() sys.stdin.seek(0) statm = sys.stdin.read() data = int(statm.split()[5]) diff --git a/Lib/test/mock_socket.py b/Lib/test/mock_socket.py index c7abddcf..b85b955d 100644 --- a/Lib/test/mock_socket.py +++ b/Lib/test/mock_socket.py @@ -1,4 +1,4 @@ -"""Mock socket module used by the smtpd and smtplib tests. +"""Mock socket module used by the smtplib tests. """ # imported for _GLOBAL_DEFAULT_TIMEOUT @@ -33,7 +33,7 @@ class MockFile: class MockSocket: - """Mock socket object used by smtpd and smtplib tests. + """Mock socket object used by the smtplib tests. """ def __init__(self, family=None): global _reply_data diff --git a/Lib/test/mod_generics_cache.py b/Lib/test/mod_generics_cache.py index 9d8b56cf..6c1ee2fe 100644 --- a/Lib/test/mod_generics_cache.py +++ b/Lib/test/mod_generics_cache.py @@ -1,6 +1,6 @@ """Module for testing the behavior of generics across different modules.""" -from typing import TypeVar, Generic, Optional +from typing import TypeVar, Generic, Optional, TypeAliasType default_a: Optional['A'] = None default_b: Optional['B'] = None @@ -19,3 +19,6 @@ class B(Generic[T]): my_inner_a1: 'B.A' my_inner_a2: A my_outer_a: 'A' # unless somebody calls get_type_hints with localns=B.__dict__ + +type Alias = int +OldStyle = TypeAliasType("OldStyle", int) diff --git a/Lib/test/pickletester.py b/Lib/test/pickletester.py index 6e87370c..a687fe06 100644 --- a/Lib/test/pickletester.py +++ b/Lib/test/pickletester.py @@ -2576,6 +2576,7 @@ class AbstractPickleTests: self.assertLess(pos - frameless_start, self.FRAME_SIZE_MIN) @support.skip_if_pgo_task + @support.requires_resource('cpu') def test_framing_many_objects(self): obj = list(range(10**5)) for proto in range(4, pickle.HIGHEST_PROTOCOL + 1): diff --git a/Lib/test/profilee.py b/Lib/test/profilee.py index 6ad2c839..b6a090a2 100644 --- a/Lib/test/profilee.py +++ b/Lib/test/profilee.py @@ -79,7 +79,7 @@ def helper1(): TICKS += 19 lst = [] lst.append(42) # 0 - sys.exc_info() # 0 + sys.exception() # 0 def helper2_indirect(): helper2() # 50 diff --git a/Lib/test/pydocfodder.py b/Lib/test/pydocfodder.py index 2530320a..d0750e5a 100644 --- a/Lib/test/pydocfodder.py +++ b/Lib/test/pydocfodder.py @@ -2,85 +2,7 @@ import types -class A_classic: - "A classic class." - def A_method(self): - "Method defined in A." - def AB_method(self): - "Method defined in A and B." - def AC_method(self): - "Method defined in A and C." - def AD_method(self): - "Method defined in A and D." - def ABC_method(self): - "Method defined in A, B and C." - def ABD_method(self): - "Method defined in A, B and D." - def ACD_method(self): - "Method defined in A, C and D." - def ABCD_method(self): - "Method defined in A, B, C and D." - - -class B_classic(A_classic): - "A classic class, derived from A_classic." - def AB_method(self): - "Method defined in A and B." - def ABC_method(self): - "Method defined in A, B and C." - def ABD_method(self): - "Method defined in A, B and D." - def ABCD_method(self): - "Method defined in A, B, C and D." - def B_method(self): - "Method defined in B." - def BC_method(self): - "Method defined in B and C." - def BD_method(self): - "Method defined in B and D." - def BCD_method(self): - "Method defined in B, C and D." - -class C_classic(A_classic): - "A classic class, derived from A_classic." - def AC_method(self): - "Method defined in A and C." - def ABC_method(self): - "Method defined in A, B and C." - def ACD_method(self): - "Method defined in A, C and D." - def ABCD_method(self): - "Method defined in A, B, C and D." - def BC_method(self): - "Method defined in B and C." - def BCD_method(self): - "Method defined in B, C and D." - def C_method(self): - "Method defined in C." - def CD_method(self): - "Method defined in C and D." - -class D_classic(B_classic, C_classic): - "A classic class, derived from B_classic and C_classic." - def AD_method(self): - "Method defined in A and D." - def ABD_method(self): - "Method defined in A, B and D." - def ACD_method(self): - "Method defined in A, C and D." - def ABCD_method(self): - "Method defined in A, B, C and D." - def BD_method(self): - "Method defined in B and D." - def BCD_method(self): - "Method defined in B, C and D." - def CD_method(self): - "Method defined in C and D." - def D_method(self): - "Method defined in D." - - -class A_new(object): +class A_new: "A new-style class." def A_method(self): diff --git a/Lib/test/pythoninfo.py b/Lib/test/pythoninfo.py index 61fd734d..8d7fb9f4 100644 --- a/Lib/test/pythoninfo.py +++ b/Lib/test/pythoninfo.py @@ -112,6 +112,7 @@ def collect_sys(info_add): call_func(info_add, 'sys.androidapilevel', sys, 'getandroidapilevel') call_func(info_add, 'sys.windowsversion', sys, 'getwindowsversion') + call_func(info_add, 'sys.getrecursionlimit', sys, 'getrecursionlimit') encoding = sys.getfilesystemencoding() if hasattr(sys, 'getfilesystemencodeerrors'): @@ -163,6 +164,26 @@ def collect_platform(info_add): if libc_ver: info_add('platform.libc_ver', libc_ver) + try: + os_release = platform.freedesktop_os_release() + except OSError: + pass + else: + for key in ( + 'ID', + 'NAME', + 'PRETTY_NAME' + 'VARIANT', + 'VARIANT_ID', + 'VERSION', + 'VERSION_CODENAME', + 'VERSION_ID', + ): + if key not in os_release: + continue + info_add(f'platform.freedesktop_os_release[{key}]', + os_release[key]) + def collect_locale(info_add): import locale @@ -602,7 +623,7 @@ def collect_sqlite(info_add): except ImportError: return - attributes = ('version', 'sqlite_version') + attributes = ('sqlite_version',) copy_attributes(info_add, sqlite3, 'sqlite3.%s', attributes) @@ -912,7 +933,6 @@ def dump_info(info, file=None): for key, value in infos: value = value.replace("\n", " ") print("%s: %s" % (key, value)) - print() def main(): @@ -921,6 +941,7 @@ def main(): dump_info(info) if error: + print() print("Collection failed: exit with error", file=sys.stderr) sys.exit(1) diff --git a/Lib/test/setuptools-67.6.1-py3-none-any.whl b/Lib/test/setuptools-67.6.1-py3-none-any.whl new file mode 100644 index 0000000000000000000000000000000000000000..4b7ffd2e49e15596fc20cdc693164b30dd978f1c GIT binary patch literal 1089263 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∋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 nPzGxR`H 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®i`)IDV zY4f#T37xO&h;~?43egYr45y)qXjepePh8t-yHleXV!rF`fu3?7(XI%x3h|6=#1aak z+kA~aXpc@$(8Q_H6a6o#YfKVpIlJI*gtBxxoz&<AI&^)H<WZ6dmOm9$vF53#g#YA@ z2`+gjoqH2mBF9C`>asNwZ#hBf7iiBby(f1U=9yvDQ@!3n+4F1+>*!mixE6jsW{A$p zmHm{jiQdnLZ9nz7G2s~-<`d>u$<=5Q_5U$VR(&>_v=L2Srr&D{1zv4uhrf9b@mm}G z-rvVv^ITeEb3G+@u(Y3Kjm&9#s%^84_U3!)<qFRvmW!AMU9{GUHj`Ys`WYKyN5bDN zXZ5wN*(Rk)r}1*LTDT%!EnIW{soq9IvIVsKRR_m%uPfm``LYW%f0mw0CR3AYvNq)r zT?Yo|c|fa1VBmek{lW6My(EpvuW|mNXAM?X`54KGCccMZT`TTWG)8Ur)a+7L#cnni z=QO$RnXwC4ne|d?O)0fM3v)M-<Q(dsoz^(+drr_hrL=~SmP&as?mwV9(0{#7)Inoq z^+&VXHfqxa+2laJq<Xb?D$NmtfzC)YH!w$VF6!6j7tT34jUS?ZJKqo3;7<#p^K74= zV=VN=vC4Pj0(}bfCu!XNyoob4{r0~c<?+(o!uLU{AN^W<<N6l<o4$k24`{zXcVn{+ z^8K;IbvDc!@TXtKu-pgl{`RhDI)fZ0*=Y~W^MSJ|t}dMS?zw)Km&(79`U6?<lpGH{ zwDNC7vE1E6M@IZ_H{Jn%qj&80%-rQ=@fMu52I#%p?|x`kKc&yO`;lG8jV!^>qG}pf z{d%*h_=cv&FGZ(2NCq^~nm7TQv%6>R`e=^ofqdwF`BslK>aV=PAnNIh74>Wls;7<T zi}IYH-zE1vvI}LFQu+;$Tj_n2bHinS9)F+sAM9!lOU9b5BmPRPb$y**F@{v$(;cB> zczy?s**^kf_=kT4#t?jD0QNr?mE#N-%1W8<Lx0|I44n&U-I!KnR5;?kVR<gvT-Ggf z-|V-Q{u~#{qzlZnw$0Hj7iUDQ{dWz)^V<BG=5>w~nAgwBq4OI1gO~bwXlhWo#3#NY zHS{#{a^rZp>&MDX36z^f<r4qk>%}g35igh0c)7$+m_%!X%BQn)>P0!Ztfanea~i#$ zO8tIJ@Qb&>FZ?aw7tQ|`zj$WH7{7Qs62Hjlh|Di^zWOVTUsMslxHFtzP+ua`HPHX+ z#GwAO(Eg`TUhvZ<ssp@LuM=yE+F&KQo44sa@eAaet?`Q^k~Y_<ES+Cm*bzF{zDd9D z4Vr7I^!@xpr8yNryy8$WuNdn~IIjrwWk2T?DM7p<MequGSMUn@P2U5&B87OxPdTsn z3-O8+jaU3Rgjb~0^hb;JcnER`@rv_Q{;V)w@!b$!k@9cximoSrOT1!6Q`dE|#4Bzf zUNPYcUU6RI6<^bM1#n(bPb6M3NWZIzSKz!0S}mbxID4Mg_{9W`Ut}r)ezBVP1;%ji zQ$f5!A3rMZ`(fiZ_y>RU$-f82?>F@QJk1%*6Ua^^Lyqx^3kIbu^|(Jz8RHXoTgqb0 zWlcx?SMZ7TvfvY2`u&wZ?e~ZBiO(>fOQpbko+?G2&*v}uQ_<FQ^eN^uv&uLV(|SBY za|3Cssh{ZoHpVvfFIHTA(<Ijy5o@0Kojse?Zl!sj6HV<R{!>k7GuT8fi(#%ejiLM7 zSBVFSHphpxIX1w9<ni}xowrR4ZzHAgHd5Zlsg3AE1MvmKZ-$LB&f7{SOK?)#&@QiC z^__q%R21`cu#q`98$yS$;ptYJ*<iMKrvVe29VjYx3_{<Kb7Nymu9VL0;_~Qo3(b|& zM6(wyEbXgGD4*SLW_L&Cv+;pG8ph`{I-kATI1~qs1LDM^EpZafLzy{#Y)C3QOl$af zYOC!y_1C%T#m#;?FT_&a>sQGYB{b(uakpD)qD*B=_OJxRVs4^z$e7SCA7`yL$e7Og zGYeqjyqo08ep+j7hNNzkXP?f7a%dd0_cXR7Ny3+^|AN2LE31Xj8-stGjcK(ZmKnEg zU(8(lqJ+(Wf9-Xykr%FR?-9v&=P{4JnZ40+6ZA6s-+c4U$hbZHE}h3bTBi9c@_2a? z+ZpxufUdgpJ)!Ro*O~7&u%U*;ii<SID-q)nx``jsx<=d&Jr>6hwf!el_RxExJm^i} zH@=4GbMif*A4eU(c~9uWj|bhGR7SH+3!)K6Vb3`B021z_3ZbLgbCl#q?OxR$Wm}p_ zJlA=>iWpzzR>@LEXIvMLy*CxO?X1>8<Fq7^dA>qxd{H#~Q>>26^TI|DF^zT`tTo<w zoxm_FoQk!e5bq|wQmWm_JNbSa*)Bkf)3DtlnOx3(wXkvYhA}&_OBaOQLjNaz9$Qev z=$kw%7;6Ie6w$)|o5v%&C~O^S5nnOf#vp*#A!wplwY%jwxx%UW#PjxB1GK??i1InL z9r`R4cxGBm$kQ5DBki9rG#I#z<_6t{0&PdUKG;!k+;5IeM9&wA=fX}^*i^wkZD3k4 zk6nc}2k!RwhTtTH<4x%I-CqqEOZ!q_<1czIaBn*v-EfzCn`Q%`->>5yr2M_WJ`?F( z*nQ~lbaBkOB=>WEe{+4J$j@U;(td;(SC~Wm{W^PMaNU7&?Xx1L*G&$|kFxbTO+Uk# z)wHBv!`JxyQ7x_|V_g55Pip{okPR6usYtuu0X|KnzPw6(2~YD-8oir%Wju`W^|ig* z;U_Zzcu^dO!$&;gBJqViB%57+H(=l3d6(yN{cZczdDNqq{T=tvf04q5pu^5KvIDTa zzC`mTtvY4%@HE9W{1I!1zI_hnm2B%anGUsZoZT!oR6_fuUA7GlOk$P21{?9vw83+- z4Y=2p0^>s1?CSAUGv%T~hyk^H@1~Ys?!THg2>kFtImLZKPII@?Z`d9Fz>wCBJ1*L9 z4y>y_QP5cJC@4*4@LSmlpIp@0_zB)qecNenm5dhmCap@@tk=1m+7hVOHdZfu7EV%K zh~>Uew(`1`NJ-toN2aq7_pdZJ3#*6h1-DaOp?yfZqAb1L3uV#n+vV}wePvnJh-G~i z8l0te4D-B6gSg-C)qH{HehS_96RmNFsM9|CGvueuYQqKELv|Wcx`Cexe0670_&dpC z@BH>M?m&|UWrN<QWH&HT(5HtD$>a73m@AtSH@0A&y+Lc^l11gXmcT>2Ky~}6?ovtP ze_sl(Kb6<tdD)+f7$v;T{2d#Q4R~dHMgBg@k9tgUQup9pYP;89>jwYrrgs*~sob{q zF<KAsi+W-jbN%sqYy|6p<P#t0mkRwq_46XptdQD_G`zDi=$#!w@1RV?Ivt_<ucQ2U zAGFvxl^qzoi?vh!1D9woopHqf(jN_~Zzav|X<>G1J--*ekT|cw4%W0v-B`4m4b7#s z2$`#hXlh?Ae9dy0T3C&^H<WKC?g2*U^=6w`Vs-Vy1@5daTZv?H<V;ozoYmJA<Pc9X zY58Yx*_^qMH;3L?LV2_49mE}h9fXPAL4JPcw3fMc{yq@*;?FM$|KzLjv8}%saWF2< z!yaRF+{)?6YGJ1cA3vXLaPWI5IofeSj&Ym<*2GilMvmo6GMJqu)g;k5D{0F{+hd3+ z0$lYt)l;%e^*AKN_<~F$@bDnV6(_8-9VI#D2*0OEb-Z%i-#kM5+Da{U?ON=`_4ONr zG4a+t^Gx}t;o=>CLHJ#qqkb$0*1AF1UlzSDY;g~2xOk0}zDdKygU!o93-I~V90HeL zv`gUNr8<5J91Szeh2I2taWMYB@FxRq(j*7&oA$jYWTQJwEVt0`_56JL+-*pyd6VS& zTWIbCmjT?p@b^91`zvBt9xxHwo(iSGr}h6gTK~_^3&jQW|KsYofW0#72yI((5GG)t zeJ*O>7D><|n)g510hv~hS$ke)c{**D9M^nF5a%}nCScDYj^A63n4gVd&l~9Z8;68n z@<N)IxJPBbzxv(@`hupwO9`$I=XuokB9(WH<KBkHIelf!M<2fV9P<%47&PZE@Hua! zxgSMxSG40S&HaX#{mpa+@f@dl@*&B?L@W0PRIgWN9uc23&B0^LZey-#ei5&+EkZm- z;cxv~#Q3Pe{N?%&g)D=0BV=36J`(;|_Z4&OyCzAT=_Cf6KwbVH!yMumT0B<MJYfs@ zHR^+YmYK!`F4#|igY|^^2lyD`uK%rf0`ki``i|HGu<MhaQGNZ0@e8{_?L33MlVsgZ zI6ucEtDX-yZH$~Yi03+$ttrQOt=}kOD!lYgaIA^#!ah)83$A7#IKCay&M`YA#2dw( zxxe1j&i%J5n2-B!Z!;7k{-%}tbVu{^j{hd+^B<K8V_*K?`E&Oj`ak+}%LaZHXn9k_ zvE}|TuQ8YRk5sNbLVKoZ7!K)?+w&*1XIc=3LwLU6_M}H>5BK*?aX<Pd$NkJx_}z-) z>YuIp`pN?SHN!`X3(rv+Y(Js@(0}8OeTC+8{{B0ljTV!W-hKBS-PX1H3ViodG;TV! zE9Q@Ty1H`4=hT%YQ6m0X>1vkXr0=({UT3SO??`jf_XbHRgD&P_s)P3019LC?cLw9o z^--Bqg67$K2Zb%YiQD5d*lKNOL$~-$@K0Yoc7Ee{1XtMcMZk4~UkApo?eG3(;B#%{ zzpd{7euvxfTkF@b7fNK<BN83Anp}@keVrfQ;uE&^NpAh@&(DblwiEf1Dc{mAe{+Kt zr~dmVMf?T4hj-d812;ju2ia*0ofW{}j~)!gUx|#PAKH&$tsjV6Sp{4k@N4SB+Xn+Q zYdR?O5%3k+O=mjT*^*q~J9k-N8Rlrd42VrKK)+!}=hSeeM&Sb`S-VrBM4SuEts0U= zXb%In=gt=ohGGCId|a^Cq_}-OVh*CdM-3uYGTONDxIT|U`xi;K!*&M6`3S>d9{P*e z4@qX}I0x)h9{0o=V!xM1ZAToB0mJxsId&<T%iq98Qk=sayJ;)e^Ca^)xy_eFOdrJV zIL-GZ#CuC_Lc9>|yx$Y9FVgo<=n*#3J6EiaWVK+1RW10xt`B|xph=&HwNf55?s0sr zY)`~mDfavMzOaxfgI+pI{FC-HS<@lXX9T^|D`WGE$1b4xg?aUbpz?=%MftENs?^HI zzJv1heJPpyCy704n@8|y^E%bnmZBDzs+SZr(x*b7nOZ-A+qEp39Z162?%&u)#_*D+ zvATsak4=+%q(a1-L)}kN8pg11np%f3>+`pU#Pxs=hy6*`uB0)K@^zBQCNht`QyQ^b zna@7j+Q?&_2GRZX-wIiq(|=L6tDdo;B@-K4IG-@x;3}fu*VAu&0(<E;?fZm@tt}4` zZ8C|6eG_NwIJJ&sj=XM3Eqp5qc&i0-zDDb1P-32X$O<v7EeoLMF{LNkC7IiZ!G;OG zg3h?fiT2eZ?P1+cD`85aeUDt*A46wdO7k)yw<}U?SvH+FV3#sOvY1cFu@2aK-JYNp z#!X=rWxxUUX}+H(R=eey;>TZ$!o5js%^Ln0GdPg>!<N5FQa9H4>vXn1Ze*@5qm9~S zs9i+oq%JE<v`n%%{LC~c(>Vz?hB&viNjYU@)Suf;tPbUu#<99i#3yDX!yH`)INRUX z@4~NDtM*EaqH0y`8KbC8wMA`e)!r+KqP2-ts#a?hReRNnw)Tv@NfBa)#0n8_{_m6A zZ*s?T?n&->o^#H<=YEdP-`+MhqIXa8ltGE1BTr)v>IuDtRsKj57qzQFQ5+}B?|D-4 za7uAZ@{5)~{%;=r3EzkjS^Ay>_u8Ur+>Xv|+G>u#y_7xhDiD^7H|^zrtoM|@`gv6H zJ!shPlxc^sR}R#v!&bBGX17~9)ND9-Pm_}$i_mP&L43I~ldCBAE>Xh*sopW$db}&V z_=?A0n&nU(-r@KDx$_^k|0rdE|6=o;x%+1J@zJgG5d|u>gWp#RDnDY~))Sdr-x;~* z&?-5aDRCqu3@UG-FU<ip&4(5l2=M$}_e`0%Q%A+p6Sv6=j^AcfBA|SwbIQpLSZJ%S zXE>YuO<N@AikLg&B`Wx=z|l#GQwF={KbNMP;#Mx)*;#t0_C515Doxo|#!}ri0Tqp9 z8w{H(g(ec0b@0~-6KL*h$8egp&^*9N=ai#eP?u&P5K;&iT^JHDAOvdu?f#Lt!4!x= zMPlB9W0b=UuB#`mCnerVusOb4|M8<#=DXO)FYVAR=Bk|h{xUz|q2MLLTg~e1WeeN# zq36UmB^^=lPBUn;QZ}?x;mq^0KaMewy~D=S{FAY1V8K;>%t5p1IOuSdQQZb%Cx5+~ zuOHH0?OYhQth?_kV1x%HyFThXqC^h-S~>hDc7MUjb(ZLLHu_?&gK0oo$ZoBR)k*=l zZN)fp05N+ZY&eeA+>S_uoKPuQ7n+|AF9zuq`<~)6&qh=DGhV?A%x;8XZVl24Xvgk$ zsHQsodi^=e>EVnL_U^Tn;-cf#-}uC8Eo1W_(Hf*`LF4gtqKA2}?}eUNMFZj+G_N2m zMk#w``wDAyiqj0l_~IN`M`%_YI{%ra+F1mbUU?n|96?Tfj~n-(3Vop?AD~}q6%Y^o z*Zf9eBl3=rv!50ZdkSfUFkd_KG(te-Bl(jnffD)Ed(h6ZfImjV4HFdc)No>-bAE`E z72SHc*U(!1w=J8qa9Alb^7Jfc^98)^fOcc73*IstZg$+$+77!X2EBB0(p&$$FeoC^ z;c&2MrmXrDaaI*y9h>^%L5J~X$>FyeT^qD=e_*+eEkXxbF7-+(qrl*e^X=<c1OxQ` z(T~r4ztE?;uDbdSqlVAR<8EW++1*<hmdd|bwv3Ylj+F+{DGYtug4q-BzI_cl2^$^P zQqs*>srmQD9~5u@x^3ae4|ntZTzuTkcWlnzBm1K`m|~$oe;*_wl-!jDDUaI;Q6FTf zV3uxKp2(;T?fgF7X7feQ6|@;JJiD{?#__-Mb^SQLA9ri1AxdmXf^qTU`b7!GMG1xD zd`&YMO(kfv3Hedeq70EG=ST0>m;j3@Z*%iyoeUG5S>x#EGP+r$<;1^~2t=ON7$c<X z+MJ&chJG{`${e%wa(q@lEF$U5ZV}7x*)aL{^(5vy(~|ZZHnz|*peNyUy?J5G<j3{* zAd&0{G*i<z^ph^mPv?2+1=NCr9@~p^COqaVMxNT}%f`+hvA9K+cj!CsoD~}-k{4W^ zw{=w=5{3_6KO72`$g#BhGB;+@J7h5%+4ODXnfgl8gPGrp`VIa?9=menyx1yckMvs} z>N&m*7Zn6(xNN7*Et|1B(|(!j1nJ}7D>vbrC3lDYhHiFC(#=I19{&a!o*ad-YInU8 zfYO4S3&*lKuzA6m53s{687TF~lud)9<-<{R=T?a~u~se|G@OP^CxJH|K9L*_g($=1 zHI7Fv#ZN(01@?^=wp}|HeQUH=MSpzqQ7Q!-8-ST(*k#`_Oz=RN3U~jhD@3xbR`Amw zbSYCv6IL;O33KsL^j=7yN&Xjx*Q`HFi~TeY47cuEdp)l*PHzdf-p?^Utaomljgwe1 z<5*d9<tT{hgZDSoSvKH=YRsF*h|jSI>GKCm#Z04}ccH4n&B8h&4P$8K+u*O$e|geW zIm{hlIS&MpdTDkMl{)^!T3H9k_c~wHSlxoaox#5=_+m4MFUb!sh8cn~ANu>#aL~2R zw5^*TTx<4S6d^TdYN6+&(*Zv}efQ>c8~mJnqC3U^%C03sTD@A<_2)>4)*S;==>4Jn z3z>jI8iI74!7&VDX(iCw#bw`gPpNDMP}y-;>jU6r($`6<>74HhfCD-|nhiCKq{Y3Y z)Vf!bF~qI+vA9sFysaRb|MDKea(Zr&?jdSju=#aN5i#rNEp(&!GP?aJprA+WBB$#l zpIaW$GyL(K%v2#fsT6a6)2{)5c$wGP<7_%d$(DIW-gLpA73ZMy>?ojYclA1o=)(kg zzewHS1JRid;q4O`Tc^5%6PmkUZ}(Usv*QL*7~XWo(zkZcCgL_N155?==@<2?=;KmM z`xyEL=)qa1{lWKNWP$O&jc<4@xS%c?Xs^Bh&0}r`UgD1yUifbz_nTLg8;W2qT>ko| zP0sh7dDU_yH?$o-W}_k=xDE;{=vuwums-euK@KrAZ@qIg@K6C_I5WWtX@0lubF36m zDx`^<i1tD8^)E>oyVgI6aVu^xCnsj>U>@sk>&aBaub`ocziahwiRRVa@#BE1?UoEM zx|j+LNQbt)DM_piY}7I7U6_8XZyjIf=}d-C>=~K3jOoZpO;mLRRX%ZqNbfiIMeey~ zuw({unr!6`ar~*XEl~Wk`mIHY%LeWJe0Yh!=S$~f)lqw?>;_YRx{+bnS4eq1HLQ{M zBk5p4H$Ncw=kn`|(T3wY7l6LWw!#U?Rx3fnyRF$$|NnN1aEd9)D7pPiC<Fb86fM6{ zlA@@7wT{(GC&dIc4#jh5i;)8wc~kk+oN?5;Lm1n4%HY~?ZRc)Bn4!T3n<E8xo{}sS zJ!TtEW*DRQ!C!OR2I2MfxZub?%>KTi>7%Oy0;8}*L2B;$8sh1Lpb3or&&LI<Y@yKK zlN0o{u$?pZZ?Yw(YXf1`jzuoGI_U_LH>EXgm%{Fn7L|iHMzLgoHn+4KIx5LMikN?n z<H;0da10CJf~+Rx8MvCEFPlaBLf~K6q+CFAw$GdO<d{Clued>d+xiZ-Y&6UM6_7TZ zp|&kz`<A(iuPV*OX2n`Qx%hVFG3fZq#eWOlPC2V||8nzmo%89|_|yZX-z56U91UJo z`(D`syoIV%zgTgSEgyzG?i;v8Tz%N>GdIOtlzfZg$Z4nk>`j2bVy^ehf*@tblqvBB zPzJK1<)=)?p!HZbpMT``R^<L64gUh~%skor7CELbPwem;`TO;}KNIn5pPj{$fWepi z7gi5SLiHL}bc#}{4v+mzj{Vy*M}tE*%tE6xl~YTD^kybYUAA2nm*q2+vrE;(L+_p5 zEaL0%i0#bDSm!biCEk_CSZeK7r_Q+MXrmNHaGy>Cxsf0KflY$pq9)!UIE|3Ze_&R+ zK_U8$o;&Dztw)$Z<NVxpE^A44$965hw+WgtX|k1u&xS<UMxHG&h<Ml=y@}4uWXf=w zop>5G!D6V+KJ0I;p_uxyJABo&CFR@;Xm3S(P1eL3uC)f;tG5kb8+#jvKLpiq0U~z< z<Lv9}`8FedN@j+W?XPD9PDGyXA1lZuP1^PjA3qZqfB*Ig4I-zcQ6Pa%|5ZUc6nQuN zgVqFnMg6mU3G$Oq)dDr9=Qs_X@DrYW2;qBs$pVIiAQwrt$9TxK^{{?@uRhP*-r$8? zQGrbDc<q@HhR0Y8Tj-u2p4xBdn6&b_OS6-EFQmB(_#TsvyTf1cYpBT=pP%I#33PW- zo?X5KgtdMdRpAlQ*A0_=<WZQ}#Pdjhd?FK8A~m5%>pJx83rj*ttk-Seo!s(oy8FfA zMJK)M*@pyUU7{_M<kla|UKyW)H-8ktYVb&>K_S{sK<upaVH7Fo>0&VOb{Ls+0h!#+ z7A5&w9-aN%10beY;yGILB53>?wiSN+3brc#r|H4dc%HS<;BN|Hx^wpn_gapXEb4*x z;h@Pgi+_Xi4fP^u!-W+#L!6V!sPAyb+ALbJ{Pgj8mfmhbQGHF^c@W9EYB=LN)MvCp z`b{!T+<L%N!lk2<S;sKQ!xZuPMdpo?4;}yMOh|j&a%D?ncyot}bRa7n|Ay{~)m;&* zms4wz8b*{f?^HAD{=4~uVYZc-`FwOq&M)1P34%NeSwUYyk$#uD*LXzs#&EWTA9^Kw zi5(8&m>3TO6NsAKkM~VX$X-Z4;R0DFXI!)F8?*+=7fQd|M-dltKLjr1KH|0)fzXWI z{M@EhHgGZUq-p8f{x#!rj!@H0i1nkx`n8r!60icG4ytq0+@^cwX28}v40|4A`$eOL z>dYiMjMW=RsU-6^U@Wvq4Nvn}0jkY`={ccVa2i}$$U|c!CY{TIjxpEwSHjC4F64To z&(`hUIAWvNd6hY|Lnc3oJR5iWZ`sI$y5n@0u95)>GQbsvSW?KJx$C0~8jE}tR5}*Z zl0D$oc$B>c$|LYw;Lo~!{rZImXX!1F9qGWiG6N2#Zw9$Pjrpl*Gi)ZpD$*6E07ZV( zdHhesIpAld82#7XD@<ff(hZZ9A9uG#J#tKyvIShOr#>Pj6X0HRL)cbNmk$@M#Lvum zeOp{g9i8i*G9i^@6XvV(qGIl6EN?uA_ot=#x<@+vT`7un6AO{smsec+-9J*y*TUkA zVj{kF+5b0`#9ouxof_q*DqUEaGRL+vt@o}kTAg!SA<7k=H<MH|PT)9Xy|Z09sraFP z(WRr@(?rFT)3$;3$c6oUOe(%C|E=cvM2?gGcD>iS|F^56yK0MCi?L@vmtp|##E71! zpZE?Vc85)sBX_$kfADTSTdcVc7yE|by;Xcw7&pWEHsR~l3)_5`k9C>vsZAJad2g?8 z*tg3+P(E2~YHb|x2!efU4f-H2Ot$R&*O{xB^OkGrP5vACABYBhk%7l~0Hrgp;!Y8k z8?6Q(+X1fo`SUg|5}&H3x9-?!zC_4pG^Z{|)ht1bL_JJ^86s7FcHu=(-uKs%<wQJu z{oL!qU<WiF<WvLMT3cy(b`D4mC?@(TKg2ez{xfZ_nlg0>8*AFC@%)u^K_vp)kz>Jn z2|NSK{RfVn>Ck(9cGIZp6MT_&-<tU!^X=<jk_v29WPd~rSr;~{N)V6SDFQ?2_8yQ0 zX5ZiFeXsx0mi`UmbJO1d54%K;R#B%Xjr5gXcf2p$50sciM^>Uw3)hQFmy6uCC6F#k zneRvTTqGE`kVl)$^v>`1T|znMl4lZT?(Ws{67G3uEsosUm!{ooGArY3bO}K4k*|JC zBA)06(s0MuI9JFae;o^Vlp+umnrhUz;3rj9|Ha5&-W?YF7|RzCmgA!6Qvc>!>E^fL z$&Z%7N6<QJ$k9i6ulB%~RxGTlAyYjj0mpg1Vt>J{p#DeH?`v>&Pl6cczA#!j6tCJZ zRXuSEw4Gg1bhmgE_ww|u&vuJxJUguc0;0I|V2!5q@&Nd={a83l@Rc5dNP-*reEPS8 zYj-N!vTS9<{b)_Nj+mSvhI;YRM)4DSFe!;xPOr9))A^L0VZi>~0_($7>BF_K)XpF9 zRx9yQgXMC!#r)oox3f~%?e4Y2c1`6K(I?H3A$ez-`v!&rN01ucbKJ52IsEuHdYfu% zUK4BzemM)^3^+DVneETnJi|2(_J%?sNwUXR&nl}vY0+f%6$n%V`Y6!j1=ZYVW5};o z>IO)`3%nHSSn+CJ3N<zBcXZ_iw9%!hiP>g@s-7YCS~NpffJ5C%x1^GVPPDONiuQLt z#?sR<^DNK;RhB-OMFsy?d-sUPzBqE#w);+Z8y!u9{gx)2+K1AfZ*4a=Ahv+#g4Tle z6}K5+?OFH3?w(j7I-vTn*3V~PidsM|-4Vqz$46bBvBt5@ygRgL9)8|d65(O>r4PTD zYXL_O*JfioxgK}bfV*$T^3s)Zt;D%#SVsRM_u;e`C()0g>(qE@ub{z0t-=u{%kCq- zcCR}i_G7FV_kkKp%Sv+m-p!>&vCp`oZ(@`P^_F+SYaFWGn+c`{rEmWH9Z4`(%-bA1 zLTP;&x0fpUVU@kZ5Hqm#w0u8#m?3>qPF79SP^M+-yL*CeURw6M7o~DfC2p;s`aCF% z4j&(7i0L_Cb4S>1uO~@ceAmr$m6=!JQ1#p%`0KUpitx#n@QBi%|NcJMmC54A8!?@) zPfT<&hd#SY#R-ac4hy^e_@Y^2|At3lZ<%4(K<4RB&e0tt;Zc1|nrX1edS&Y4S@I#? z)EHiv+UOAMlMg4hsXzVgwn=L9TIe9klNFJ^oh2rONNA_RvYB55rQjUIutunpIs$tN zPEsJn4|6gQTqF!l*CRG2$_xc346l5Hkqv!<k)e^V`Ar9coy`f)SuvvP?@+&dqK-2M zir#`#68riGf!yhRgD8i$zLk2)*8H;r!I6o(j@!;d!D)$N89q^orGvlBdn=!Y%{wmf zB@~FP3pp-beI7<SF5%2-!b5?Sr&(;MywuqtlroAlwV4Z(tcdmL^-=>|2G=NR^CL0` zaH+`1cBT*+Yh_<4-wpZRFfN$d3Udq8$~#m6d%9%38@YdV1N+1iWDZ8O+FqSjQ3Aqu zX2}*8V+iu7k*AQChIeK`<RL&$F;qtj{Amj_UIj&Ecn6KdKC9`N3Q0Uut5OGiRAk5B z$OmEBQ)f5GV0~2m3Wpb@F9q16w4XG|z!qiM>$#IZ#1b2zJ5T{zWjbJ^3?Jwd2)WLL zQDBd>53WPZh$sEbB0AFY`sGXD-zG2g1z)SQjc408Ty*7Cz5Mq&u5Fm96l6PIC|NYg z*q@dC!ZMp0a0~xN&b*=jtzOe}yl8WA3lkOJAMoeyebK&ty7$!SlN&X~zk-7^M_d|< z7xl_{&@bN5HI6jo?p7K|nd^(vvr;0Z*jT*!Xea35u#fNa56!)q6Da6uW9W`ckVR6% z;pCAfnp#~kPp<cb2FX*nKj1Me7ZHkE{3=xcxZYh8KP*uO%Ya``NT#^(fmv^0BM#%D z5wz#W-?q8NS^B?<fo<*<w5>XrW%3)iUVI})I}SWGNScGOSjq*OII+?2le_W%H)W7D z?x<~C>deYnUO22WVy}DFXQ8>s{`1zVc|*j-k#}v&=N7IA#c1y745#6`iTS)F$|=Da zJ?BjIsSy>(pWvk9&*8Sd2?_J<Hb!_;23_Cp#A)AeN5a&mOlCaOYYi4jg5U3_kCco) zSqM?mcRH~t<ADWfe7c32eL0Yl=89<fGVUU0UM||$g&Opo>vnpoH%8YrJYO$B(OiLI z{6iRIHMvGZlZXgG@wZNM!tZv}4Jc3UMIoOHf42m+fd5#jir;6|%n|3Tx<UK_aXhM8 z7>(HHt+zCSW-VT`)s|mx&Ly&rNeN3Q4Bg`GyO*v`+J_ESYT>Bz+0xK^54~A?>+1YV zkJV=NY%+vTfv7=Ly;^pRPN<)H?<tn#ykp%lrK-s1m+I3p9@$mKpzQQB8b9RDVmh_1 zzxQ;c`fDghrB?g&mOuIPKW}!*hEP7#G2#^T_9>&cdSqV=%VB>`A7!%!j$^(Hh(-UX zp#N%pbAv6hNzcMS(<#%0YTv<k;SW1s(du}-B|asF(lpku<cV@tS}EF+TbDV$phk!b zpTqLteS{VZK8#{oTbqE3q(wzI9?HG<_h3&^zSE_COV)7q&37#~U;MWeJ6ob@JTQ1H zc&Vwf>UZ@AY?0J=HwYP&uRRTFI%zt(vHb}(*w?ss74-Mok8naqx+t1pwptBZZxXI( z?6fhM^;)>o9kbiCFm{8Om<Xa)tWla7IH!M_FR;GrNYG{t*Xa#<6p0slI$CWK9FCfG zWbM{|@tog>mYzVxUtUPHbtTq!M>c$WK2PS?N}FLI>6+?ry0wEMaGahqG1^8PO4+sG z-Hu=ZfR_vVz!s<CQ~S<l&6F5J_{f+7zwGseR}~mI!P^FWBR08sKs{P|ch}s{#{2x= zM`7Z>jN$t{D|#Hc?*2DNY-gz?N2xv}S=?)o(Ac3*{g4#4{~vo$*}jEC&Lg@mI$on0 zewD!6-%I8IxL0;89nig4AlnLkmzM@0MiI~gm>ljtG>^qSxyG9{F?LD(*XGnjAGp7* zVzpeh`>tDx1q#~4-S|!cVhWpLLXnkeiD%Z6^1-WjC_lr~WguuAXN^)Tuat!W?Ab^c zy5-o$*dJ)t1v)pn0e-!hEzO@A4|7;|=ql(2nC@#y^0w09XxV9#Y{e-pkH(3N`k7rp z>|7Yv@i9bVHyP5BYk*e$=i5gF=Ymdy0&?zw!x8SmsL8a>>=ibngC|GpAmZZ=MtF&e zu+a0@u>rLzu_BK;zg=e#o_@<WIQL>CCCT&|Mvfw>pX)w}Sh|b<+~dvLpk8woeKkUG z0Z@xeDm{V>BMk~}a|?d$3$Ip|>@c~nA5}9{Ni^LykG=iQhj0H{9@6A;vuKK^i}?D= zHH4_>{<}`apyP9&HrX~-Xv=?t;IhEbAJz1MQuyz_TI1l2p|^3;n{ZUSj@7nZBwLH< z5Xh|S<$qG~`Cq7&v+oKLo$+KdpDiSQF_X=JJ_)M}-KW_q*X?e1KSZ)I80fB{u@#H3 z=ml<J`n3rT7fQ!CS25rxvlYuQ>(}0JY-l}>L1~TSdmK}R;HalhFW=}F;e3knMC&G2 z&hO@H%O!W`*FrL)4IAXwe|mci?$XmLkJ~*Z!)o)-S{6wSJ%q^!J!zMUHp~=VT<1Kb zs)9KGnJ(m;BzK(Ty|d2OZ78w8S9$C2_C}o`ohY}nGk>=sz;JTR&ntJi3eoW9g|7;G zuH=Zc+*4s`-VyMZ0mo52s$&{hOrC%&)6keu*Z$L=nFDT)*wE}HfpkNI+~>kgl4&ei z&)qfId&<lYVTK{x!h?57XiV6Fxb+fN@lO`+<vcP}iE(#Np<|`7pX!-wsgG{hE3Mge zlXug{CdH1#io_1uTV|=g<fT?iRON_ZNsuKsPLKr{$9#TYrj?uY`GboJNs4Gq2eIKd zj>NmEVgcRny4kwrySrkkVwJm{o;hkCUY$Qjz3YC|&C+f5Or((780MnV@IT2TNue7Z zJ1rzu|Nkc{W;oG!$*sxrgRY3yf!2X8AeQ`Dn5#F@6BY9RROLxbIdzX!-e2U=<mu(& z=U$+5cAW2T&|}Z0TJKXdd7SMr%0th|^pukSic42&llC!lDu5QDeYd-@){Dh+)Ytpo zHs4KD`i6=$*#+{M$<u5n|KGA}H-@=Qz7hn@Uq8tDWZ;y&_ck;>;h~c#@4CMG^AD2d znp)KQXxh%-;z=v4y#B(zW?R2#LSmzUDBeNtYGHwunkYr9?}=~IZ=ZZ1NC-wfy%pse z@&J}YPLxRcXqY4YP%7X#bv3{CM~9S9HjZ}}d;%02^2__Itj!AeQxd56S2Xi;v3&Ga z?}4z|r(B9_6AjO3+L}+n2Bk;a=BcGc^-h^$x)`)Du$191ww~-GonUy3a7GrI#$jXP z^Pi*dH|pb#^q)|C4Q1(ZE0pz#9tcimfld3x2b)F=*4xgg;H2VaUrhFd+)b=7f;mo+ za$!WH3-~s_@P1nV??2Vcgxpc!{GY+*=jgE4a6uKXA2A@MNdev5AX;rPX)pU(#x3T; z{OlJjlcs=#T_6WQ>vR1UUG~akKW&ZcV*=vtm;mE7Ib9=546(c<g@aJk88n@`_$}l9 zxuG+b@FWhGEw^?eti%)rDf~7QiW2J14piJiB=fEP4EYhvxtE1ts*bw$`z;HZx5+pT zYT3hrIEOQ<PR@Qa5+facQlHZkH*IV$q;7`CcjEgde_StbUN-{|rri$0|NV&pj6zW3 zjW8wnL0tQZp>pHuwsZbSxaT@9N7^gokBO1lOUoCn(`}VM!C@MXuTB!gI@;Ginc7s$ z<1g5~;ElWc3(J_j`OAYa%<TT+HS9JJd~SU8M;!<xq9%E%v|yZ|qxk_7_@wiwG?duW z@*QUbJvos<LT3qAG$7(JPOP)Z@_hdcL~IX^`!7Catmbv)r&T(Sg{HQujvwlM26@$; z-*n&3dddWLZf^p1@;f}YmrK1m%ZRthspA2P51qDZR(U-+LoD{n7PVlk6)oy+dIs83 zB_%l`30Y<m?%Ag$)TKgh^Vq#yMoOlYfHR)1>5a3WmH`;Z^})q;+t4*|5#(t}IKN9T zu+49n{pE>>Pb;){*t{M+oR=keZQyiWF?3yB6V8;&y(P|cdAlH}V&yGP9j?q6my0wt z<wd*QH15Z@nhN{EiNzYDv+w--@f~4GzR*tPyK=}<SC!FO{$Wzn3k7Uoe|;(rV&;hg z+n9>_LYMPnaxo@@TBB!tAt^y>2O6ViBd>VTmml7xAm5WL>W5f)(nu2}UpTDdrW{gW zLw)p2Ly8-Hx$`9znb=N7YSLQyyZfM62c?u+k%EKRH!>#TAYQ4D(3cZa{djo8BNP~D zecu;;%8`(3W9CMh-1&bba{zcQly-knDtiizs;8#%gBDJ_2Z^^no*-V}M@8lq@(_S8 z_zCNPR+YwqDj;SlK@kulg+1zbOEG+AodACDKgNK%N?5^u_7p>n1NBjKh<<-5ub1X1 z`lCocnn$3G1&veT!z%obt?Yn@*vpiPR7%+!&$vywU>bl(%NRw55Gm{MXl_Hb5FwNk zsxsA?*OUjL0Z7iZK{To6!${6iNB<&swJMa8G}(Tt43{alm)gqB7WSdt*rlj;dMr~S zlC=fv!2wLs;^~Z7qzQT048&F~LHpZ$!niwA7b!!6NFIgE|0>yw6d^R8K-4=@QEGvt zoUNUzLMfYRuq*Av{>#IQ*|qcEyRdd(H3&;2wNM;h@B;gHVPINPgUgC?e+(BwT{*Ft z8B4bWOhv}GGvS}3PWrvn57Yq(?X37mP_?Cz^Zou;{aU=Hyt7;|RVan82<fGSl|_-G zj+U-dVd(uN@GUPd6n#h-Z$bAWJO1s;N`L9$siyL$W*O`qQiash8MRJF8WT#YIb%s( zS){Iz_KsBKz#@A~+@%7RkHlRishHv}c$vL#y@(?Hjet}1O#iMCAi4c!$Q>*{%7f&j znR1&R{5iTwlAzK4B9bsElH4<tJW7UJh70&%DH$w@wM4O@@crwlVX0!O)(Mus@4iwZ zd7H|lg^=N;LDScCxX_>;lW0|>2B`z0z>>b4Sib)B6iQiD30@kF{G@g%5{cD*T#Isl zhb0gtMJfTLLe&n={U>#VO>I8JrV1f@u&G)+FcrYZb`h)@YB^;$1*Yk#BKq&c_$W^6 zU=z=aSjY389THMaafH;_BZ80G{BNArN;j$e#i>_;X-E%E(K1$;Dj?Z1LGe~geyNt{ zzippLSM+vjTSzD>L{Z6?#t^1}s~}Yx6_v1|0HDBUWdJZl0)`Oyig5s2-gv=HqgAB| zAbB`_z=#v{QR;387)4GRR~9HrVgf5}7EbzH^%a>Z7)qV>O{Sj+9StxGAEmD$=Hl+Y z<-EAo`3b^$_D}aG1sh75w^QnMcTgYyJL3xoMn5IPxPC8GWOV+*-(K(b0P~ps2rjKO z5lfc3;njP-Cn|rloIZ6KZIy_hxGXrXv4cya0#Sj9nBU$Mo6fzyxxtXVhq`oGaa(^C zCPWjnKDuz1n}yT&qEGBL%)~nwL)dm&?(aJHhV^LHu;}(352z?5rbJE;#coT8=aH?; z8N=_0Q=FJ3hgPX{Seb=q8p>y`s~xCaW!WmceSZ3cr`b+ksCS4#xA^jbi(YHY`{|6Y zEB*q%g||Zm&6f<H8nhC%=`aq4DF<$)vAa7*6DQAqJOYYYT^Gk!oUU_|sVa=Wy3(G2 z97y^!LJR$sKJjOQjMH*@j?=XxyX)WY_H&?^Y6$~r%1l0u;ZGqdu;96F?1PeH=`y+v z!o`s2;7Qt&=y#yNCk!oS2$8X-(2aH0*~rm=1iS$6#7sd=_}~n|xf!4n-N)!t?^Osi zubYzxjdzT*6x-0c%AE0Pe`v!~C2_tu^l%4c^BD0svv1$+!LE$zW8~wVbS^8eHyR<4 zZ#yMxl>~Gzgy|REs{EDQn1WimwS^uxfQ+D}pDC^C*Vffvry$?Ph8m{tY&@9NJ;>Ne z6<O#(n8t2j<(^inz@JU|rM(nuqI4~s@^muB45Y2F+AEc6pZLcI;x5S+#h&Wdtv@hE zmZuen(d{a|+F>^E$r^iEP7ofa_7km-(iNV?fClV4u0rR>S8_`ePEP%@^bY<KS8cTF z26kLO`DoDw4Pu9ACk@ks<IND-|BNkxZbk}qN8JUt*-gv(#D{8+K5q6ax(mK>;&}6A zKN8#Q5ItuQmzI}QhPjV&SB%TLptNwt?K=Mr)KwepP4{`xR&(^HfQ04`ZP6bV^9Fmz zT_G?6KLbO}+v=eEz`k3Ts_icHLcJ1XC*hmU>kq>yF7$2XJ)7?aqvPitBT?ad?Um_C zZ9Zu$!v;QSNO1-HV(Pr0^}Cqgq1IKMo%xnxN;9$BpSVugzt0M58-6!cdk<*(>YHty zeybO#WfYcOt8^9W^qb=^(*7smDDAoiTdKW3FmwisY2pf(Sj7*ALw)aT=Opek2AN+< zC^?bM+r3fgFzd{veVJ^XR%!=^+Dr&e<FLMoS<^vHC=ma=?BF1)*fi(~@?W4Mo_rT% z#WrgWH@Wr8M3F`>1?!kUtQ1vJ05r0h8U1r5sjMO<jlEM^z=x;P1sTj3gbIc;g~w+A z6F>^Tuk#A85%=Q@Xus0bFSdU@r!PLWJt`&d_pryeemy^$2+8k(r8k~&lq+kx$NW1E z%?3yR<m@AxLI^H6d(zI5oky4)rw!B*qRyDdpi=Dn7^H$K4HWr#u}`!O;dPyHRML-^ zX8<id@>0o<A+Y$;V3|`*dC$12HHdexp(r5t8Ta*_5DBchWdv`c*ZKuFa$q+GEQV!4 z38awJ@98Wr=>5`rf`=y!DuA^6xBJL50|Zk9;vb;E%ijf>DF*S;Ch)3056c8!WtyK_ z@c2avyjwfGF5oXyhTnDKr%L+A>@4W@z=znF7RcM(SmQ@%;?ML-q29vwl%dpW^r_nD z)pR1k5jEdG)S|pq&>oH|1dI4~xN}MXH^6!P+D%p48X<I8HWZMnS{=?AavKZj&q)Er zwUgm@m-4k(!?Q?wkAkF04O===X8ppr(de^>sKzDhevqbTO68<e5rK=O2ob*^DZtfJ z6?nnoZM@JDpg+hjj0;U8?xtovydTjXxwy`<UiwQZ1=O=2vDCL8L7*c2VxVsr7iff3 zktONXbdnl_VJ~>YVOg-N)ar^*<I&mq`*i{1Y#F#K&o}e(Zk&U7qHMkUa{J8<0^!fB z5`|w_p=Ibnx_e#+*#>)x5KO{4Qt?3uUp3GdstnU0J|^iXnN(cBbNIoR4_HfU(7b#V z>js$fsYMeF7yAYQ{7J|{U{piyS}7>X-AWm_@rq<(;0eD)7M+cve4#|t?hN53cfcc? z#N6t7TmU|Lod9Ru5m;;<```;@7d32xeIwg2<TcH=&9#|D4V}t8E6gpZu6NwsA+3V5 z2mD|pe4QZy>y83*UIe1#Gpbcb&-4!=jNrWN>Iwlnf>ugSDsGnoJ~|qHl$zuVFG|A* z{kx>~HO^1Y#i;+gWWpNfM=vFSImK+6Xugqeu=ek!AYr-H6}T%2sz>4f$=PH9N8|>9 zDx+tthe*bTuV9JhS?5F?MZ+^5gc{&uu8r0qL=cSB5gsg1ts>cE)!O|9B%8AK5F+Z7 z0U}Le@$XW&&KN4zoaJt#Cpw4+r(vR2FW+K~N70?uD7+#F1>>$(C*H!6qpU@<_S;<5 z<T^dkm+q}xUaE2hKpccV*dp(d;Zq_P_BqNTRf`*aChw5yr8auDe+W^Q&k!TAHhu_^ z(SC#m6^ipB|F>xiK(+K&v?!&{dWZ2`Q#1=;&q#uMnY?2JPuYz*J3;Vxso)hz;)Ps0 zmG21_G=vf405(n4f=nCiBufp4u0DiFb+tf@;I~M|bm7LS8osC>ugnI=2(WK>S_ARQ zTp87xqi4q22qAU+vLy&5jRF@iBC}paVKs7#2(M8AkNO-LT#=u??8ac<qQFQdBzpRT z?`>Z=#^uf|aKqwP2RIQKm5XUxyKE>lN`~d|)b>k|ECevn_5oI+f21Fm;>;_ilAl1} zBUwyCDPbfl`h`^ge*gT{JPBke%?iO*f~Q{}m;m?3cDh*7b?Z;yBYYD4I|k0}%i)P) zsl7J6l`q1)^Xa=K-d;HBplN!u22rC!!QN2Ofle00-7?I*TH<lI&TmN8Z*RBX5I`Uh zWIk9>+4WHO)b=b%<VDCH{AFD*jldINleI(IW|Dgczeb%zTW5~wd|V~6SZB6m51MWK zB}V+<I#25{F?5NcyE4tjH=oZZ5F~qB%f1PaAv)rqcdjt@lPh0%+wCv%ip^0`F1B>& zm&OF_sON=3&S6l^AN*p;h4?|*4k9@7tzoZe|FJnYp1TcWf4>aqRyxd;&toOyEt*A9 zYWQhDe*$uAG*4AgNhN%6Bn|l_pL>L!wOM<=@0Ze7XkyOWCGK@O)g{5aAXY@$Ko%Ja z{ov#b_w(yT&B>#LmjDZpUiz`)uCi+yWWqaFoXn^5+S`+Q&GjZ;A(9|N)ko#&)dX0Z zg;ma;U-DUW9$!<(SE`c@a?W|(ZZUscP#N^41Uny^V~n+F0=T4Za=R-{@oaa^C=gB@ zmU!^DFRdo*U6-78UAEIY=2~YTl!ptaCMkfgVq$8L;v%WX&bx1Qi+zUTI}d}j!P)&S z;Wa0~@bI_0A6O@XyJzYN8})6ytT&gq)9Z;$!x9g#hko0{_(A3_YV@(dCS}wau-D^7 z*n&6VurG)_i6ZdWG^e}L{<=nIiEk70-&&wH5Dx#Vb$>JjhR!{E-ekR>a%{IdO+65v z`xG)4n%sH)<e-{n-JqQ44p|gzq_D6FBrkT}{ZEl%G=v(Q_s|G##@|fl(ml&a0GDrF zzb;o?36DfnM65=j)dljK_e~QKf1}pL(&wGChXF$x*QdDLuh|j0PF~E(6i`nlgqTwt zMS-EEY_<3ECB~_I_bZTYJmQpcuH@8iB{g8ao%e}i4cr|Po?Q&Ih&kKsnxWbXUd!+? zrEMnbk<q;%EhV0L-M|%W7IA7Odi3)vwxp<b#2qZ5qI0~A5&LsFwjkE&qyG~rxkYxQ zoPLDP+wfu*Tf#xE8Ke=0kPQT#T^Nm0?kVcyu9n5oO3RK*zH8T4p8>58cRQp5w->$S zJDjE;=X-WsrnYpnd0p)<A1BJA;}YYmIs79@Sr9%iR6lVHe|r=JIgmS#xN0-e4RwJp zwa4l=uzN6{fop#4=eTx-CbDr9e)e`Q$W+%w8-zF`YG;nK|3-BTo@Wid4%}@qxLhp) zHQ~K6x33n!jlPIzWybXFq#GX1h~yFI>hHx~yujcPGaMNRo<nTQw1;>*O}llTg%j>} zkq6e-IxlJ=w_dbYy*p@P=5J)fPfWFe6AXUw4vI><!K!dGZEYegWYN)6b06#w?H~-% zuvgzz@^m54|L415i)0|k2Ga_KdbCaCz?%S^UoXxn-&|67S=;7%*5CgnP<P1++4@aa zK!tBAP~K=MxzzEJ1vy$x**a$FEuuV|s-_ke>>!Pd-$MIFn3d&zeY<7{3O^5XI^6oZ zUICTxC<ySy<38@}m@}_HtJ@LL<&&e)Y189j(Cc#etRCd$<t&u&ZL-}UuP@ImV7AP# zU{}7gBy2AoH90B<YVZpgxVPRjD=#YDbaOZ0*Y?q|lHatF^b$Pq?Kw^-;i}T=yW>vv z=_v&2XL51Ubhs-+L$I5hFp%(XQx+zG{|;YnP1o!s?NN0;erF}4ta<RRYBUsc-ZZKJ z%a_}5@zVLs)<_^nim_sT!U~SY;iZ=&f*_o0r&xQAjtv8b6zeb*er4i!Aad4`LzkMt zdJ#y-Z!5I$AEZVG7GUrqKk%hA2ai~nrt6O<Wq<%LbG|vzGHJwqX8J3_9qv+_1v!49 zpb-<9rK3M-i$RLM*j16iIQs9|i<y9Hzblgt!+?tgj!7><G8&#_akZ0w6<>^T{tRO} zHE-HEDvA52THYD%bDaljsQ%pitxL!=?NlfHL@Q=RsqXQ5a@xV9_2s`}2(Gr)N2WdV zS0~gJTH4DS((G1R&{9ND+r+v;I?Li|ftTX`1|jF)iknKVx7>0s53iP)F~sfFpN{(L z6cEV)`er`87Q@M%07H{yE%fFTG4P_~=x@;U*^e-VOIZ?dw9%v)YaqnU1G~jIiFr)) z4qnRMW@X(EBR&Bip#2o~4{&>_)rElbooteAln?fE^oMEh%*8uXL(dnB`arVT=SGzw z27jzFvjD7<wPzD|D_(x+4#3EiBzRamVrLy;#}^0nNJ<+I!hwGla7BmxV076h$H{19 zao5lj^F!}y+k0(Ix7oTm*fSKJ*VlNdMbj@00=W;22US3!lW96$Fd1S)|5e!ZA30?3 zv`M~K_L+M~caP3${)DQDuwf^}@A@DNDW-6&-Bov{1#nkD&zXeeAdy>FeN)P*Lthp@ zqC>+2%0rikS`^D@#@!d26{A<{^ZY}pa5gPcl;I$j>6lFlZ1Q@S(PXxufT4pB>9H>7 zk;8u4q&WY2x_v8#dPWJ-TiH?Lg}aa*{qZU5FCa0wy6G)dBH;LU`-|xyrJcCIp34G( zSxJ#m4<ktawd!)4AHaAdBmjD~YSk$~Wo1G?5um2lUj~_M^%TII%9`Y)nEYFjxv)J> zKwE@5E_EEG&V{kHZi2VWPOVQV6+j5>`}1RuYHGj#BdmU$8Ge<7C{U2UP*ZinVp(}- z;Ioq9{|1WF9h7xiC2MC-gwP>q=e%77AxKD8#w`5&opE=8vq;gGXyndaoN~M0me|pL z*s&rY+__5vgfz3BJE4}as@CoJ^=>w03}RBziN_z;c1H^2_I0t#KopcnmpW&?E{{K% zLR${9&CnM?{NVxr<|7jF;k->(Vq(>%L2!}Ff8{<DK?QpyEzp(nA6m>1A`aVliC`4@ zEcfv3-m%|$cfj3gXVA#~0`J*vABD#hu;7+Q^;=O2?m~rugjVp`)J3cMHk`@J@nQ?Y zD2Ax4Z<=q%yVhAW+wK*$eJ4m_w}xHy`?BDR^_L$Hr|G{7dp=UAd%D`-YchZ{e;B04 z+g4f%!Pe|tj#(v7^*6O?DHFm%0@1`*5=54hJyS>(jP>)_W@}31xPz!>2T|()TYN4e z)sy6qhao)iafH_G#+@p)0jj}`E{D2#CypfXzVKa&b<ST7+{y4hS_jg!Fv<a1$+;Cf zwXY#Pac2~-5|cVS7Q#j^juXW!LJA7TvFiORe<vlBnvsR_btCwH=d-Xt!lQ>+yGvYi z!RL8NTnU0c95WI6e7nJ_6qcc-cg>Hl4TG=X?F>B@?0m0J$ZX!`DIKa`bJN70<+8O2 z8(v+ZVOhymn{uFH+>eG21<^D__-0?g{z6cl`*ZKm#WN`vg}V+szFB}RRx97dpvz>X zR);P2^|c40;CECO7N)!(^33rg^%7@nXAiTaIKs|RSzT_4o10W#9*SeGM*?j?7!#-F zbh#@k{;cV^bG0;9f&cp4*mVF~Xc5R*ZEh578>=3$3t5-J{MbHDmhmzB3y)v5SOH(H zojP`f^4|xXstSxGpD^$9!bHLAf1DLym-UMgaUumhP@k>UnM_d%#${3Hb^P}_FgkzO z>(g>jZF*VL9_Ri}(U1jsl9F$zD>22d;6v%KH+W{+Lh5MrW&t!<P5j@QGd&309#jft zjPVSq+-3h3Mged+Ss+$h=la{fJKwyDr^i&~9Q7ETEh+7`YpZJ}w#oT>pb<#;+%`<t zZr|_4#5D(Ad*SKTcHV%$_?%hZiin!*%P{$$(1!Z;BL(tKBY!8HZm)#E3-Wf>g`h56 z!CVsJSnhIk^rv)Q7<FrTjGa&Em%rmN0H3Oh74MyX;u(2<T|?{s>X#K{L+Imup+!_x zb{{bOv0KvaK`Ofkh8iN`g=$+b+?m;Ud8#ZZI$Yelzw-HVz%ObI7N~$0<xo7$;&brh zuZ}|oiaHN6ho3HxA`H)#wJy7o89>C$PsRBV{4@JF{cVxCr>l2Om-hm~hr<v7{|@uN z_%vk{;i!d!H)e3m3g$@?r-2H@i^*zt0|Hzn{NQg~$yrGQ;QVh&dd_^3-88S)vXaw* z#}J~I>B?d6SS02(%>ve~cK3=hEMIAs1Z}xqxSumaoV#eQ_5;nsFAYXwD1HDMkmC-x zKGt!44_?!NfhF6P%j2&B<*mkKhCzpoz*NcaL&;Q~TNfQt)tJFQeKSrW*rg(cj!;E; z!!zUFj&DgF1?vg=dtbeD?nQ(cxyaI~Ez)uS<fVI~@j#;@C$2C6SZJh~PP<Y0@S&x; z8jt@&Nqhdg9)8SsJ>0nMJnEmDwMjkPYgK$OLnNE{0pW8kS<rYBa30%m@Q=4rfvEB( z=pKDW9uL{Z$#^6-I+&XfjaLh1ZleWc3q5-l`XRPT;bW{PkdjUYD%8*-ZaMxv45*Ql zvn8umt)KI6xMW8w7R?>u($^?(;EY{Wyzpb0@AQ$hGGPs+gxq52VLhfZdS6c~AdoEZ zC#L!Iu8;ZS@DWNL{+6bA7J6g8wbWl(8j4edAF-^4a8dhRXxp>)v*#ijXTzmPI{a_f zF!KvtO#JzC{AD3wH2d-y9MgBjbA1wb`!gbjNArLXYwv+63^j&7x%%3_egS-d&*rCV zyjucHSanN^={bz|EQmdyQKi#fRxgOh@)jk>wr}XtEqBRC$AY_xiwX&uKn?%!j_uE% zG1cp^1n`0>&kXUR`>r@)tp?HUpFopP#)*~}T%+eSj5|vI@$7hbZ=JqNikc3RY{k<W zejg;V+3egDn=jTBTV^%Y{nsHnpAOflp!E!ie?vE|^`?MvQj0I%Y&T5jS=3rtEL_0z z-7|&QG7mwfRLNX=V@{=ie#TI{xY#!yA7cSM%{&*qRK!RzEuFq2px^7(u*9jU5+Q7m z!pIj9%m%#XUq_o1f=cd5SPG9ey+p<OzR>AIxBNHT4KIZy-;ILKClV4a^(Gmr%xZBX zTFfp68N=b5nRMA-Hvaatf-Dv#I|;{2#U@>uE^k_|4^14xE1ZZ)rTzgl<&xq)LxICr zf~x5t!Zav4_=V)q-z-!n)UF$x>Ebjh7<wERqAMA`_w&sgnZYvcD<hYyBLV)AU-=X^ zp*YKE{*&l#Lcr<$k$!GWL4j>{kzCW)@<}o0sV_F6XN#+09*LV*amEEPo`|VEw&vzK z94^T1LRA00YpYw_<~m+1FTYtqJ-vN<vS-z<NUDHz;IT-h#Qct5<kuMbccEmG_1XE` zja~(*A!dEB&jd5;mmI*wNj`h?N{P6l#Z^j3t!Da#)k&85LlYdBh;fr|0#wO0>|QDz z*|18|2!rvvuU{odZfc0ZuGTJ}=?_eJcJ_f3jB&&5&-Tj?UXLsf^zjTzyGYp-T;Z}m zxa2r>(=U#OV@>LuX8+!9f^3(6QRoC%R5vb4@)}mLo}E_tk8sZ01cV)>zSZADB#X)@ z`Ib6e2`L4Ze=l{(zu1X}8F~$lB`&sA?!Ipk{Boz{039z;FC}z3EkYoOD=lzq;sQZE z>|b{7>qAez?~qlqN_80Q3wLt+)$zB4E%|}q?i0h=Cqv+ow1@hA`=y;6#X04y>3+LG zMbLWJpV`~$+vlo54<?jS{rcTqsY2G+aot0jtrWI=_mdBtZp!oJ#P!_sHM|hue0&NJ z#iw>?{<8n&PpCM?3vh0FnpVw*Z@;e~=gZBaXw#cN_Kd(fsl8+RFY#=Y){Av&^S@&8 zJL|`z(VFznr5l!Qb$^UI?um%@MTqo3ETSCjUrbDJ-$NfsIG-8B!-{--9qlBah{@_L zJx&8MNSo{JrhXh(sTNK=p!^wK^E~|XuU9pqviWA35Tno5!bNsTTn8t=pZLtT3CdbO zNSfo|;NP5mz#wfg3|j(zM!JjV-}}4AO1t^BN&VW?dnK$Vp0Rvj4Uz>E2gL}L$W(|L zlYd+uz*64N8ClaH|5zLR?!Wr34Z=V7*PbgHs!PuAJsx?|2~tzjXC=9bk~cQ~lGH(3 zv?%G_b68}3dCzBk$~IGpdzs-G<tJcnA|fEcIK}J@JWuO<w}{tR2*fFKqe`EJ|E~DX zLeF2i4S3Ay$C*mjvEb7^a~jLaP%*34sd$%9cHR0PdNn7=b;u3aK2}GJU!}ZZ{8jC( zDPHAc$-7)#^hzUwaJ<uXYotr>_{YZ#q)q2{nL980YLv1^p2)=SAqWM90OjZ#fSZmJ z9f=j(R6@W(cZRcYK|>_+xhAcGhB#=!(1M({&VlQkp}2I8pX(~=up^<&WPKib*pYSK zVd`Lb4po90Mu1%*<n$dcrmp{3Cn;h^$DSG=Znvw^`fwB%?P43^E61hdHOV?Q8FB9w z9jbU2QY7e1PK%T%q{zWnLUJP#3@7`sA<1fcAIjAC3>#{VNVt9;XG*Px=4VD$Tfb(K zR6ne&C&npuRKHrj9S|QA(l(>gwy7ppR7*5@p19+$)E!)7oG}{#K4$zIZN>dFYK{pS zR&F~pkq14n<8_hEn7p^h!}e$@&p*b{=KMY_Br3D|<J*^6QMOU=q-AdQ1NG)e;pjnt zlOh1D!`pju$sn?=&+?YS@ehH0aAc@3Y&`PhY19%mP-JI1eeP8$@F(RUuUJe9{oz25 zEVh;PfV(>s2BK+MqO9Y*i4A<lHyzbi9znTtF}<hI!(jhjmO|adLz>RxEk&(oOmWpC zu_CgG4^>B5wZJ{yvw#B8t?9Ys;MRO=$f^7D^&Q$bn?{Fd?*?&0U?bB7JGjXqbc=m( zbWS<v&rFCtc!s(<N_kOZv>`51Hm(~GazRwDq_O`G5wyWn#tzO9GKcHbdewl#26v2X z?huXdx7sc}VTmbAU6>$J-6f9%q!x0X#)WpPS?ARlF6k`p6aNL8%&N>EYX2rg4|<T- zE#*NAIP`I5?74l`DQ(s<r#*`D6S8$pxcx$e(M`}FS%WdZ$gP}V<`~<~b}FA6Yn8EM z$d|mg!9h=^+-{uy*>#jhV<P1DkDC1ivX|gl$~M2nFrw+Rk$bQkAvD?Ttk`6#6q?&s zJY&7PUzdBtajM~MFvhEf1I{03`~DndCQFFEbaEDo;hRu`Y;jOR;L)Ye;}5k*r(ZMB z;)Sr{um(fmFe$kpZ_-4F^Ah9WXP!)Bu^l75zQ(95m|K@EI2Qi*Jmrw;ToL@EcK=^{ zG25e^e!@Sfk2|HP*8wAV|B%_X%@5kvL3#2c^<>^SCCE)Yu_TXD{>16(`LQz;z=5OS z&LJLNPUajg6H5!a@Xx0Y?rs0<j7Wmw`YIwYCpQ(-yUPrL@pCb+t%i0pXaZX4dOwJ6 z`K5^ol3{OvcdAz}*%$sRW>X$vaprBX0*-4%_TBn{j0?OKvM2w!s8S8-E|&876uM%* znUIts<|_1DS}IZ>-QSx>Z?vLidi2T8)TJ%Xl(lqak1vJk{Lp9Tx0Jh-+OJmOqsPQ7 zt_zPtIp1-q!CznU6$*dP7(<o3A_Luc*@qm+@4mecwjZw=$BN&2Ytt12t55h-Mc<=H zfZtn(=`fDjOsJo{yJ*j;*uGR44>Y1{GR>_LzPeFhv&#F#6vWQIHSJ$;Fg-!@A#@A^ z@z4Ecr%!uIJzh~!o$4ff9JPA$D(-UrHjb<iZo;K)b}fDg2_(TIu{he2Qk9QW$9=us zaTa*-Ecks49{tCv+~f9zUZpPAH}fYkHa#h$a-V|XZVBsGhOz!t2pWnGzil{ndLw+r z0&xh!R63t`o~&H(+TjwJX1n$JgcC%T-`R^D@j5W3>xo_few+`#Og|R=QUA~y9HU77 z`~Lt~K&QWTv6IG|mYJGm72h&JU(W!c=R;?iAf?TjX*I>W99EstmTEOQ$jibcla0Qv z&=eq?u*_t0(dUHC$TB%{^d?7IrX#~>OMy69HW#GoM$3rLayTF!mOMF?+#C=(TYP&W z1d{VKbXJbjWy+Xs0bQI_EBcKjhxp$>F)P91bm<@ov4w%Ab8Kc&!PE)aDJDC8Z3LvE zCD)6&xr`21mVL4<Epr}RwM+G7m6}J$)Cn^aCnO9XHaL~O9QRP@OqX?zZMnq;*%2d+ zpI~&lCO91Q-Lyk#c>#Qr;D6u779sGR8ZQWeZ_?N-@b_;F7bZ}v$X=pB$ZH`9CgU>s z%QXmD6mqRMZ*&yKi!TM0Cz~HS(`a#;B!j?tRiO6H%z&mzO|aOYnUBgs=8;3pUa8D9 zFqddG5Aqc~gSamD6tG>_%iES1guoY|Jr>4a=i&Fm3W1s;!IJEt58z)eZ<7hx^XT}6 zF9eB8O?8N=9wG78Oee-6O~JlAkN(1rg;4e8k?AzO=sh`h6ImQO6Wm3t2#m0kB=3e| zAtYUtVi4psJ_MZ0&YD#xeixgL+<o=7h_j{6vRiDT&yy`-vn8+a(C?C06i_C4#S4^) zS-%yMkZDXsi-`5#68wf22q_N<c()4h<-$a8Qqd-4mH2(4#o-j|EatFI3`;a+yO>2D z44LeNaxJOim|#pdksZ_$aq)UWo~72BK4BXDzDKl=o^}}06f!N#>avW>ahYak&a<SN z;>|_}xfsU3&d!wNBvu@AY|AW;OdEY)EmM@X%yzN8uO#YB`%{2muF+wk@70}0rcz0O zFCJmONz>65ok!o?=YM4kZ6iYBd7H<%AYyWs%j6U-p-}i+e0rA4p5>zTRI##Cr>8N$ zxP@~1RiA00U6j7QrU3eFmeWi_$7Q9ZnH=DU(|9SfzzrbMG|@vSfw4sVKGVb+zXR(( ze#iRH@t4Q2!c)=D4J71)yVQr$4qp-vI^&{vwKRhIU!#jc{jXW>p!q8PGS>eehwvAN zLUx4U!P8Sa^7ldhSB^_~aPB4%5fL&u#ab_05959i=nwxD-)QM{?RBYtw_JW`yIwiI zww&3cb~~;U7W~C};Z=^jj+lREhVg$9|9^g{u6i)J`l`pjT($p|<LWPNVDhWKSm58Q z_rLo1|J^TS$N%GQA}B(GP6fqqrZB9@S<@4FDL%-f03SH9`UT$~6t(xdMf5`a-9^WW z)K|%W^+kqS#8>`i{5Zr{A^t~&jfLIF=Y>s$3$7YpdvAgGZAKV;j@^AsO%@$nd~Dd| z@jq@j>AL_|ruVXx4LEK$^#AAJeR!O}d{6ZM@8MwlT*UM0MLhpz<&)q8dR@Yg0#O4d z0qOzGbe$gX0AMa)17Iy+%ugWi2y#FxpbO9rxDs$L;3hzNL$eOh4OmaHGo%Of0r~*x z5Br+{YXP%c1hTRV%mn}qk%Z&|D!anD3eX4Wz6kksgK)seo9SAWhv;r*`v~#@X9)ci zO+5(tne<cmz#(EFT-%qBC_s8Iauo5A2Ec6KdHv{b_<h9NkKP~lkvhO!2sig<;cmdT zpjUH$`rCCM(GMUbl5#*Ft^YuppHXNTNS}>l6tsirGl`5s?jV+*cMyGMPO`!mP1mq| z#4wmXbIC_q0DDtA457bSY!sRh^)a+uH!;Ux`N-)#(*lJhG-)`!XY3>S!|Agze54jI zmgX~p#m`5q2Yi$233$EGC@4qLXKNS*_eiE^-AMXu2_I44Mt{?0Qd9$$2qs0+D9}%l zrid9s;~PS}V`zLIQH>>}r_iL(Y3Of(8ii&+>(2s-y@Nh8=B$txN1vUQridNK^7D?P z&$=)QI+#$5hj{u4^jSWs3i<=^-oVv5$WM_h)J&nzU;w*KrRzXOL771BFc^hAz*hvY zcOpX-Tq!=SNKxd@0y_cL&!y#^73g*4^@=k>{(SmuFQZ_G;qO+^zj`4pFIh0(MV~oz zR*1TrK8pzKzX<#R%Fi``UsJt|v|N)SGMSM6P(N)7t)C&Z2Cyy2^U|oDj6xG&K5$Pu zA>j&>B5E=9hh(7|aE9WXg8smADJ>uHIiXRZ%%ts{EaU=KL%M1^eKyot!M&8`mn<|O z#yG@x;R$XBeYRDypmMT&vz;_QlcGuFje^caNa!!1H{c1HUl#O3T90Kg2Lx<cMxVuS zMu^O&&$#lDq-^@E7$33cfW0A|Y6a~l20^=mKJ&vU_*T$zeMEZ?Av&5bpc%0K9{Q+* zG)3Mj@MFOe(sZxrZ-U`Iny*1ob01wJ@zM9pi+)BQxIp#SyP3b+-Aw;_5sgC3YUZa& ztC=5p0CS<72EYS=>NSMa0OmbF$k%{14->K-(C`TO0r+jxqi{{}E7W%_=n0s=4*VTZ zwVpnU>5R|>*h2Gp66z<I!}L!<y3q5j8lENOd*OUY-E*Lq;(SQc^Mss+`qXVEWFe%d z4;rZmJs(<K1mg<u*kbx@IiJu3_zkpE1DuztA-uVSJ~IO9RSJ3nuLoQmaxO$)M&q9q zRONIdEsQVQ>6)8S@NB1hN?;s8Y}roZB`drYFz!LT+)DaPpR<bCDi%K<un+X>+81g6 z2Y+~pKC=YIkC*89WeIV=O#4%^(EKv>hh)L9gJJy++HcMZNw3iM1UtRL;`?5u{(Dx) ze~spMR-g|IIRWK1&<BUW`03dR<0N3->$H4>qWN{&FOmiC8#KOAh<ua&<`?`C@K2K7 z%KaAegSuVNk0G7vZQ72>Leksx*$-!hmba-t7=)-=C|5YE@a_gbf_T|`2-yKx57_wv z^s~K$9H!+1{zUV6mp%*4r)YSWriXt29<{qc(efUvularGZxAo34(0+h{ysuJr{(Qq zeyiKh#$ES*=705w>VJTJLM)+qAJXyQbA|aMIEO>|o`Zz!6w*SHJ_dgf(nGQj6EXtA zwVx0&8!+}$@E=90!rZ{d>E;I34!Wb%uE~P-7`88<0pfd)!+8!+_Zf5nKsU^1HUO$l zgT9nE!ugHH`<#%yfYo1s|NaK`X`<tnQ9;hr_Ji>Oa0G<se+B&%Q27lZe?a{DZ&*8P zzoq+ZVB7+1gz%Ujz+dP%{Ucq&hV$$%P(GmHS2|ud!a%^r-~1NZP6ol(LdP8#4==Fu zOXP2G9)|ejcWTcxMI>E2r}_Lz?Qc>TF4A!b##@*jL<>+pTwOm-{S9yi*k3IOke^X# z2Bht7R?xhl|Am1Z^r~(pi08jpr9iqvxEC-7(yPM-@RvrR7H}vXHzEWWmraUVKqG|5 zw4wPY3vNIyq^kq;0J_@>;<!}@nEE?g1AmV8FTlgVV>`h)7_hdpKu#+xZ9H9|&jL3` z3M5=e3AJ~HHu?kdycyC1X7_-(1)x_AeE=}3mq0?P{1$->0<`xPNCk|4>L`J12Ois> z>Y1WY4iLoib}ryfu$y+E0R0%oalpe6Pd^Au52%c$_4EneXj(6$LOGb)<Fud$jQkVg z3=zOD;rtv!@vPt-O6}Gtv<wr-LXbC&6v!CBTpj2G7&BQA$5|cV^+JlmFhzj=dRmB_ z3i?3%<R?IVAYQdzAe#UUGvGU*dA0!O<#QpbIfCdvIzZ?@ikP_qc~@v`rArdTev}XR zF4*5NAAAndCEY2A<C=Ma0R9j2iv_g2vx@A60-OiHp8%CG@ABR)i1Uf4MYMg4LK2_} z^r{8Ci|S_*#Ph!oFcRXME!1A;Ldar49B1+Xe}?vVTLtI}FurC8;`uz%CXf*{ekRmA z^b1A4QxNAn)h>a|hH$#Su@>fCbe|%D`3>DuxDb%;OM2{Qw*P@*Dq=1o-K#a|SGE`6 zfnV8rJ`GPmZbhDlyc)3{u^Ex>zo6yQ{Q{IHA<{K$SHK$e|MQ0%`UO-cyD+!VQ|K+M zF03i6Eo><C!PQbjk*}z!sJVy~tBTddF~!<qeX*g~UhFQ;EA|vu7uOco7yF8vi%E&9 zL|qb7qAk&v7)tCV?vlI`Pf2x2ZApEJuLRDlrK(bOX-uiMR9|W+wU@d}^GZFX)upwi z^`*Yj=2Eg%wN<?}W~+9qeyd@teXDzG-d4}n>aDd~>$m#0Hg6?fl~?VJ@oK$#ufc2g zy1jW`kGI-e>#g_tyv<&+O|?zEEoPf`n|_;Nn|+&mTi!O$w(4!Q+v>OZwl!}fWvViD zSxlL>OkZXwvzNKc^2$7A)n&D1^<_T#;G#T1{4EmGrUmp-f<}>`Q`FX2&`Jk-C4pvU z&@Fds{#GyORs-7AZ8dB&LwVUyVlI@K52bpc+!`pk4$5wT(wm_C7W%MR5BM(FS?!7P z#CT#oT93}7_au1?9<#^p$@aKCxt=^vzK0Yj3seP>1?qyRf|!EX0&Rh=KwpqlU??yb z*bA}?+y%J>c?J0eo&s+{bwN!*Z9!c@eL+Kkub`=*xuB(h6e<f<g^`8o!l=TS!q`G> zp{`J0Xecxn+6%J_-O$Q;h4}$3T~}C-t=(MMQb>xFMXI96B6U$zQA|;6k+w)zq%TS; zG8CDM>_yo{?xNhHyrTRfPm#B%x~Qh8p`xjxr9xR5Ss7IsTdAu|sx((-SLRmcS9&XJ zD(fm6Dw`@>DwS1{RZ&&3Rl2IADsxqKRc=*&mA9&<s;;V`s;R1_ic~|N1luS*kzk!z zuuKwIB^xY~@9}zSJawK1Pm`y`qXfG|flYK^4>Q;z7wq5#8`MGlo1pGWsCN|9Syz|@ z^`#!25B02pIyON4S_+j=vnZ&Q4r*kE+T=n_yikj}q6YBumLg?wWN}n+Y_YC5sn}ec zU7TB-U+gWeDXuGSC~hilDOQ$5mPD1rmgq{7O3WqMCAlT}CEk*nlDd+HlBSZD5@l&* zX;f)!sjf7s)Lfcfnp>J*>MgA)tt)LPZ34eif=^M8(t$Ubw`QX+)qo#0Y;D@wvQ_Dg z^hSAOy*h7_*X+&q=6dtJUT=-J&fDN^^0s)D+ak9`ZHwKe+m-}=mkmCb5B^pIzSaPK z*0N1m7FiZm7F(t(ODZ#$WtZia<(GNOYRc-$8p@i=TFR8=k>ye4vE{n*q;hk4c6n}j zez~{2ro67ap}eWQrCdoLVq43`gMU?TYc3<@s&aLCOu4pPUv4P3m%GdJ%01=P<+bJY z<-YRfa<W~uUA;YKyLP*NyJ5S1yL)@ycF*?e?X}zMxBIp?ZzmP13Ux(Hg|<RpVW_ZI zxGVB1JQdXywH5UhzKZ4wQmLv`SH@IoEA^FzN_(ZdGOyB8SzTFMSzqa^Y_23#sw#C= zOqI4uUuCGWSGlY5sytQIRkc<1Rlcfb`ry!dfjytvqw=Vsw`!rM8lacDp@(`r)t*{U zy~pQihQ6wTei{RPR1f{r4t+BZ`eilr$$IFI&CnNB&<|sv57HiJhu)V5J+B&iT|M-; zX6S7y=xH&~%k<F0?9jXNpl4MV)fUym$otP8ccDH$L0r2rL!C)8`>yp6@plt+KUW^~ zla|6r=pjkaH&`F1<G&U>P7gj8INHg_x_`^L>p#c;`1n6iO9KQH000080H<wyR`rH@ zX?~0V0000101^NI0CQz@b#QcVZ)|ffV{B<IWq4)my?=aE#nm``H+z%ZB%9m?HV`Dh z0zuKBqDwT(Ca^Kt5R~ACl?@S+;3Lv?OD%?b0Urqj@2<_wu$8vj+Nat|vEK)u+UK!P zL9i9vC71xB@}nvUwNax^T&l6eWFc$rd(Pb5Bw(NS>HF9F{_%zn_s85bGiT16bLO0x zGqctA?%<3Z$MNuA(>QKFr~f&*|NXBE{^v~nV-B|`<IQRN4U6BLc8~AD_11Mw-~Ue2 zec!X*f8Rq7eP6Qv%LCRX`626r4_Pbj_E^97{nZcLl%1VfkSL?hGvuFq>kfPJ|Gd7a zeF}U2k-ZY`&o!snC&Jyh%3`;(d#YVz_i^^`vAe;Z5BH@H-tWWwSL5h*aol2qk&C@V zYDVxj8nO%-9Cr*}mgs4p&4i0N(I{*^KBsV8Y9dea&N&S_vEUEr*1`Z0cKAMgV}G+R zaontbf|mc=Uu)l0ebS|)@<09EBt5W6f_weZ1VY$W{z@1t$E~`lY4v^5eeht_%jBlR z|F^D$gL<7e>0sR9LM+dqm)ZL*xbQ#UqW}Nz{|kRLq@q9wxeaZCGjLSC<XPq|JXA|) zsNzPW-{7X}GdWH<EZ8*LIklp|+`&x`tuqAwwxu?j7WxI|CyNX6+W4%Jm9lYR)LJrK zz9y(`G1vN6dg(Tn*JK>9X&q@RE2AkkjogFK<66_oD;<B?+zy~Q4Ah$h1#HZX9cj}$ zDh*si{ffHwZ5K?ywL4qJmT|VjYM?-XH!s;!kO%i#@+!NxrIWV<VQE}wbpcmaa<j~L zlxZv541uuxRVYwk0%moGwilQ|nrlM$6j+vqDhe#_TKcnWtklx7xj^8=;PcQJcr>jP z13!mH$bcDZLQk@cdY;hY0!xjTHb6#rw?gI-$`u}J+019H3{~)1a%NRa@k%Kd@qr3W zjzdiu9UO;=@|S+DcBCvQJs-5lQhEsp;5YbqsFG>|khPaR1NyV!yW30mWFWG$qLY(Q zX90>mk=|M_eTsdy5NIY4q>*$q*pAZ_z;oMSq+k2-<ezdufIhAzn+x(u=V<KxyqgBG z=CuX0SZC*}^_*HP9!z(W0d-|TKK(aFFH<lqjTH~xZCF@CTUiPp49j1%i3?j77vu+y zO5YI=o?J@5m;5B9E1L_<oV2(NibOUkkDdlLnb_ZMkjL7>cH}Df!ii6Yk;6_72G2=m z4>CoWpfklq+d1f%d`|jB8`RL6QyKj+J^-AB!A%4>NSKv?1s=0>q;Z;yBQCB|o%<Nz zbh~(P!cuzHl*9=du+Xs3O*>7)4QN>aOmLf~X~2S(M&LbQ`*ygKL+ojoewzz;P9D3H zvzBpCP==p#Yq?yPliQEVxE<)b+!pp%xS=g3Y!Cdm!2dkx^L%$FB%;vJHR-Hr(3f+@ zIXOtquYhDN*9-+g{VRbvc;wZ*rGAe6GvL+j2M`m00KWOY-5)wRIt9ihCG2$5OGaH# z!^+|1?LYz^1k>c#ma5r^sg^5X$xv#DFL2jrxx8LVx~~OFiS8$S0p^4DC78p)m?N}^ zOYjE)1}HrA3bxU4Hnc8f%Z;Ju*$@uc<`KR%w8^0BgEq4>a0>XTv&`{ENJ=wo{s2q! z8@zN@8cHnn9f2B`(MPi&Z|7AKbdZ(*0f}vyhkAure!n!t-|RaKIoxzn7SlEbg#SH| z4zfj!Blr~_s&rfoZB93A?r3Zvuh*|gcG$KHc`2jyhXvk9puh?@ABPeK_0;$|>?SSO z0#rfa9E}qQv<0<><In~R)YnpclVn0+M)`F_Hh$T`bb+NRL65d717?ho+*uz1#j|I_ zRW+|6xpVNLif_xl6&}26RJVZr>*toXR%O!kJt)V}f69<1&xP{x+`c@3qw|f4{+*b@ zI3`qSYyct0R)By{%Rm9g2DaDgt=V2+MXlwfKmRT0$<V9(Y}6II+jLc8z%tBLPDkf@ zbDIEik=b%7Q%Y^Qlr2a7DWHrnv(Ew*FNJ2&doq&(f9p=3wMM{et_hnGD98uk=gj!5 z*Q!2QPyn~qK*21XumbA0=?2tq!9ftLIY4DAG_C;jS;1vUhygY#=-i+tXL)^H(9J!2 zfrcL7Hq$clV!>=^S%@!0W#mNt^ofzFJ5>U0RDMa*)U?--V*p2`gLnLOOFq$nL#)K| z%2GOmeP0ODjo$`0f66MRrqS8hr!Ti$qca<1`XV+u(>I$xRbDNa3rKMFooU#+D<l_= zmqaQsVH=)jGUxRjM^XHVA<<P2=_obs$Bd(TYkm4~Z$X6?5K;jOGu140)5qhQ=B8mJ z(stHrAWS2w@C74zbbe;lgB*i4sG(E8(KM*3-EZ>s_5ljNnhF*5t8%w3OzH*42jWv< zM~7^s4oL6h#sfND{G;tt*l3{~(R$v5M9{*riNQ*LR_g^1{S`E&PL<>R<tC@R(L-;T z4DU)zlO`##A!$505xJa7jwl~ajeMA9G(Gj)4P{(3^_8bV#`?<&w#wHd=tKmykRy>x zsY=(>NLQMX59xsW8KASEMari;r(B8I^$E<XyEVJqEzj`K#W0YNSjc5|do|hQq5qu& zoaXBG)Y7-u5R>2OiVuO>rWvS>T;24qP(-^X3v@BIqJ2MSF5}vFh8<;`*KcV+rMDjq z`)Hb@qdA>)?7}a|TtBe_c-^j73sJGlQ~bPFEy8c~U$6L(>c3`rL%Z$ND_CwcbtfjP zrW7S&RSxmnE}^2?{JDRq0U*o(QA-X*VyT1=V%y1O<+G`g&(a8=jwBL*;5hcAsJB4& zJGNa~2N^cM)o2Shw9|i|0rp7g98lhzluFl4gW;hF>!R-=I_*STMlN`XEU@-DdYh(i z8(IZ*Z@h-QRmg}QG1t(~KqqZmVnR2iE}E%ySiM?q9w@nndc6SR5|o&wdAt%fyXhYb zkbtIbRXRL?xJ*je>ejQ2<X|m#M4G0SvI_IItukp_HLWlL4P^!WYzE7&=gl9Lw^~px zS)kPBafv((N#FkfUZXq^2OZ{$yP@M*hZg8s(iH5M^X#s;G>+bv&*3nfNteR|sgA1x zm_A2G%$?&PWhRuD;3?@rTNrE*0nEbj+b*NFY|2qeTW??l?s;G)j!u`9%Y4%<180>F zjgqPGWNW(8X;69$azF5Kmtc(G%?!6=%16dXPl}Xw@wZTLrVjTx!a)U%?QrFj@(ROn zZSbfV_%ZUhhnxl7VHxN^mm3B~vz!IRh`}JdMz3p2Q#uUEI;BD|X>Zmc<xj|2fRpc2 zJ~m3@M!*2#b|q?%|AuDsiiXDafldUM#wQCA15d-do+^K?7b58&AzS~71|45@g3`%j zoxl2{HZ-(_q!~{ry_)S184qgk1<qjDCY=wQl4b|`r6~i4fD<{%gm+Gp533WRdD}k1 zsRMY*fhUeV@wQW}R4_=OT$3%Vrt5Xc{m=+8xKX#X7}l(}H91d{Et+hG&h~5A-PV~X z-+4)HsPWj&d27}Bn7v+*nn|_E@rImkuQ$sNM^oV@`R(-<Ovsa0VM3l%XRpu41gm^E zCRn8^dwqdC-(EjUo)3a!3p<OaNNH7-j`ofHE%WEeMUFS5Ym{cQQGD!cXoNonknn3Y zbmp~8A6Kff5S@Uz4|Td?IDqt^pA4B&S|?(8npz)+5|@bw)7<n7AYTWZX{?NnZ%Zq= zS;{V1DP@%0BnzNd!E)JRs4Si$|JgAp%>=xqNu;yTCD>hg8=Bp$TA&4ekrBYGHVe@V z;<7l}p{6|Iio?U54wum6f(A+xSw8CqS2ABdmGpejS}_1-09Po-?eeS*GeCjH5u$)D z)ggL9@D&T$S||&4*}8EJ2q%<|WZl5(vgmJl`dhyKX4T&c^tV~~M$hD7NrF7yKfb|( zf9f2%GEa9(I-)n&>tpgK{^@lfpOI+3cNo>91q>0rFet|sZfsa_G^sA~2F^}8x*tV# z#*rFe5K?Wy6nG)kz$b|pz!^T82hL0iD_zE<vgl-EV?lkpBO7(HoN}?fXA>%rgckFX zuR1DCsL}7IMYjUaRtltQt(rrseCiUO<T$d|O)BH0u_Sx@HK6#b*2(Gg#7zK~Mk;wn z>W+!<aXf)c!`}s3aUGV!Lu$WsU5ac`s@A1IC5C7w5ujuzj~_c4>JRZc8p;La_E2>% zU4!D_>Q(l?2t8uhGA`umb^8Tu$M@$lYa(hUEk{skR14xhzDns5TAJgWluoK+%6;p; zNsvq_r3IkR<gw5|lD!HV0KjDcT;C491C$nodg|&DBBflgf=t=#P4Z-#Hv#M}{L@Ec z`rP=Wi4d)Z!k~A~dsP=zU0pa7dk}3`m%G!|4FzuPbX~XuGmU3%jajSiCcT@|iL0wM zFUsINbk$rOM4|D?-eua|L+Z`Jb8@;Z-1BcxK&>*!H_4$#<3Vl1Lm=T$ahq8Q^GbvV z^|N$dO<b;SbAJQRCG%>&k#BEv55e=b^J<3VX>D!|p3U=s6|xjpoVPc}n+`=6h%Y-e z@#RHYv=W|%;AtpY0#Dz-(>Kvu;VBMJ@#rkQwy4-<hEgo^#>i%8ndXYy>*GxqfGGiM z@nueYIioNV{X4_I_B9GxwN}e5fDsEwtL0kZVOuArZqrtM&T$*j)BK<@L2UZH+c?$* zf1Ha$c`NWFefUN&w^3ngC!mWHfW8VasrAwzf39yXyu!dZOMg$rs!r4=b*4a%V2`r; zX9L7>zd-+<j|Kufi20)|h2CfuNrM7Xpf0d&Wud7zX$5$hHjIiO3uclNJPI%;8H}mv zLJ~$P-BXAo<wPIeX>PHu-ZELum{dpaz8zY#3QS>N723l)8LL5=clb8d!TX!g{{2q) z(#aQ8Ai(_qpp@>%V(X+yK761DZr95-fxnxA?k=X<!oa?HKJ(X*=~WA8W`X8l(~yH~ z=gRGqi@{0~1Fz%AGkGpNx4F!}M$1WQHi1+BEE2frMJ%414cSOcZ9Ws!q)l4UZcL08 zVq&i<pI4i^Rk=&~f`@0vKvOO4girP~>2L6Ir*<2S6rwFke_x1dKzlDy=x<qSqOe~U zGI6yxcgv}ESC^E7Wj3DyxnVVs<}=Y>`PM=6_pe48G=k|`=i7wu629M!?@5bxDmoI) zW=@`^vL-^iORfQ2vD@RI-k|OHSrXvG4E)eeKN^SL1$G!t7$9K#5c3i0hf@uh`nzPR zKC?id9ZGl-227woOuP~eoP`_E>H^c;0R{}+GY_wKjlt{B*>iwh*B0Y7^>(~|0X^;e zd<HZp_Xea!!7k+Xh9o0ZKvPn{rd?^%1>%KU5>h~~`$pGJev5AocJ|w2fn}=i<+wHW zRGeOxi+7g5ZQFi)!I^#ex>vFc__;L?KTlNlOK{KGV748#w^Dc%pNgo}-BDh7pc`6F zy$cw7!RV7uA42}5%8h71LV}srvxHLAx4>BR!)*N0Echo;M;v7=cMb^HuIHEyUdnO1 zN}wHdY-s{Ypt%S|)p?1849a5y)cPm9<4l;Feg!UG-OfD7xho$oZmr0S(=$aTEX(?L zMs?s7rMa7v!HT#Q`hnKLC3+KaT_6I<P^-^_<M+!V)TZs^0ZLrwN5SVId@)=SECec; zz72iVPPfkod*yjZ8<u!4^@tqjrUKFg(c4T<AOc~lqgUopAJ8y+cf$KBu$Ht`9<Us! zG~vXkyu?!*DhXDhlr7-?gv$Z4)k8DJq34(m6df0;wD?nCR8`ZKtCe{$@<p@B0(Fa^ z&Q}}q)CL~>l9Vy%d^S2)L{q@$NotyAfs?KS3{6lKmMcy4QZW~_>Kc>w1t7F0k5jJY zlr;iZ2YLF-Oin3Hc?2>QXp8twS!7IWie?aB4o6Mm!ElY6esUu=5F9Sqn32}5rHyFB zabQNYxdg4+ME9aHny*1gpfk39mPDq1p~>k1P;yqfRoN<V@@yC-3~ABAHltQ8khf_w z<SU1a@;LeqkW(qXK^Do|FD;;}u|R0b)^{3KBnsPhVbkzj)a$A%4x^t**S)o*8BO0% z=y{L;b?+X$9ypKJ;C^=PW!K~EO4;=UyN22I2wdrm0ZjwPsEAgJNuSylcH<vCoukim zA9x7>IVqC_UqtI@)w*wR3gAd4$Msi&r{CbEPGI`FKca&^%H2m#pY%qCQklEImwE9i z<QVhye>B?HM@Ros>L_17g&aahUkrW+s9`(mI4cHF%G$=Mp)-hisEb`+g=_0mU&1wT zN(@W|e9Dyr2*9b&9)_E^Jqyy>4$ZcfEZ;arJa|Yv*s>gkMWsu$^@FR?ZwreD1CdRT z<WG;p_&PQCBxG|$#2@@F1C&fb@UOQ5bO<R2<lVuD%t*JFk#sL3=3YkRy-3WS4Ui4$ zQK(hAQ=vxbHiZh(%&ICW7v98REl#(G5MJoHYxtS(Sup%;=&|AC9D8m-U!h?5Q%X-B zJhxoFL7ojRk>1Z_YuquU9zblw&?RBG#DQlqspm7Cm}lMp-EgLO@K~rqIH9vc&vE#q z?!}h%L<GIqYp*VrvSNSDie)tD`6(-qUR59~<xy73B57I6WuH{ha(S(k*K&EI7`$Id zwughKo_i3?u~r^mo=5~q)qAVQK8(M)=f>e@YtJ;Cs5h3}CQoj8)G$|`P@c@%GMse? zEXWcY1Gtp|{00GVsvrUI7X(->2HwH@gJR%Kyni1Cf4s|L-~iq?iGjU%UoHlImyYB? zZU_ZYxZL8)hunH6)8|XrXwVi!&a0EAlMo7CXzv;J5j1t1v0Se<5EcW^gBHI6;xT~e zsZQ4!CAM08f`VQY1CQYJUCbjs@pleivGWyLCYgbGmcxIcs!9z07>2W!L)Ok9vLd>Y zI``{@a@tvUhMw(%E1RoQpY3LH{v7MaDoE*MeT8$9J->n10j4140DZ+Edi<mMN##a= zmNQ2_5ylJ3B~4C!1!)XiqXU|erIP%k9>BWA!0&nRb%*4volk;tP=lCA*tL_XALb8l z<*}_m_4ffMXzL?|5ixKbl#OlvC4T&N71A7W-@>@thwTgnvB~aG5Y>X4em0M}6EHMQ z?PQt`D~XP4TNrO;fSn8u6ZMQbRy{>f5lJ7G0Y``AAXU8MEorV^H@01TjZ;GiEm?kE zc<5woR3mzg$T3U{;C%DW9mDN)(*`tqd)~rH`Pe$~i9y!kALGPt>;ZB6t1SIH;t%Jd z`4oFldRU1)B+XJ{-xq_=!MA=^eT$B^fD<+MC3*wrBbSlehjFIw-Huj-7`XYers>(N zl4%VIBIB)5)1rd@sHTk&rsx0gNl|m^Rb-;S$Pxx3C}U#a1zayoC$+rNDfGO9!}yq% z%iob7(AkNRx6aO<x1{OnU>j2&yWq=~1%&bCwvKuOT6t5lK$;obg1SWw4*g`-38n5u zP9<lenR>yP-PVtNBB;Su{IoEx2Dgt0rN(qJ$dSgX(1`%4&oL0p;Q>==c|I6Pr8xbm zogfFWUCQD7ZJ(ipNmgBG<h(?Q9<69Kg6HVqb#*NV5Y_L<`M|`ZfL0+;&(tK4<3@Q* zqEDca<+|W`dW>jNv8G_RsUaMcqXi0GF9u$YGxiRs*ylJlylg=6M2PFStNPr`G{S=b z*~S3)nvUR~Q8HVD?=XJGaR^rpdR#-S)66K)cVWq$e1F6$<>{2^kATS|zP2zP<xzNk z4u;IaI3^l@4wlrZ5uizqcehU1%sV>Pj~O_loZ<%FA8A}d7<K?hyia0sitU`j`kHGt zjbevu6sCa(m>#;4HArVxyPP(SAsv!0>cfe~lu9tXH4Q&YHxkzHpD%TLYH15FwGx@5 zT(YarG6so}_qU`O88usTmP8MPTo(&FDiesI-eZ~7y-ZN=LkpU`)ncC`c{L`xgk3uf zbDYuni`GDTn$zicOYSRVOn5RDoy8Q^j;j<_G<{J^F(;)W?AJQ1UXgMDWeF(062*jJ zvD+!#`T|l*%Fw&&#%SJdL-M6CnzcJc8l%5h_3lHe5jJWUKHJ5vn5wgZNuHoF<1WOc z*W<U+bzd`^Ut=Z+IWY1u6v9I3hOd*E1#pt}Cte;~>+#Rg;pk0z3CaOfS)5L9X-zP^ z<zL9&QNzZ*G%bV=Zhu<H)dxEEX?Ur0SJG`o2`wwnva>|Vs_lJx1dr-I`c)qi2Xk|E z^4@5^!mKw9*pBspJAuhD0IN$FZkv<1N{Fj90r6O00$0=*oHS0`iw~4XBjGnJt&Xq( zx6RnfMr91^AfYE2ZIG$kPV{^T?fnOqtgaAAb-b~`_T~zjc0tpQw(t1-1}7Jt<>V$^ z@8lkV|F6UU6YzgLq*oMzxp<Gyjh^NMpgV1v+8htLo^flrPVn>+E|lNtw}N3Tr=b(! z=oACEnzswBTeWBhTtlrmo<!$#IC)MHv<_!#rn*V!a29YK&Y77V&THYdxWhRY*9J*8 z=Gzv*9F9oS@iq45x5Pjua+~V}mW^I8DGn{?L%c(EbsuDaLz`2`P^YVl$>R#dhkllt z@Y%eix+`R2#<pruQV}6*Xa~dShEW(Ps|2oPRY6M<C1q7Hm&9p|@m<HErc;`$%U+84 zH$NLqBkW0epo<G?TfRqJ-9!L8LGmh>hNPM{BS^qqy9GI`M$0YHr=?1W+(kNY0qE1I zkx$c%bM^Hu$jGT_(3zFI?>TTwLX{>rZMi{5UJPJtnpP=5)#Zw-o3}T2ZT^Yv9Jz=k z6tM!*(7nh)_ad!j3EvWJ>Zs(m1<%Q;{{H3BOwwM(W_`n7L!T96ghNaL{w)t`(t_Gy z+~%tDXCh&hSc;6LIHMU#%qa8lD2!nB`Sl5s-VPW=GZC&cZHReygGO;XIxrgRa4mN( zlnegx81RYF1y3*vxKi}~l;rda&M@2h9Ubyydccra-Aqiax(vfpt4889k6Me{<py_p z*jb!q9PKPBzc~XV4d?MM4h7G{lOJ67sh=<@jiZpyViG&&8+{5PID1&DsUhY_KE>>X zXaD@ou)o8+jWye!im_Yh0=qqXgx!LN+3h!BcKaQQ<}*()fhI0KRLys?nhc;B6aHuj z4KT7Ou3J@|45<k`7w%-pBI|+*h9@m|IZ)5fkuzHEJs57m5Qpw_>k%m?=v={{LVIq3 z?(ks=TJGX5HUnCP9b6qp>7GSVy7f8GA|x8UHZQT>Qm=JE_W!`_^*#TcobUkRg8Rw8 zc?QTSjVn_w-PrV1sOoRZr7;_G{MpNa=KP!I$0G4lD^Tcj>KsQVg=a*Ruu$JlpP9%e ziPH8vEoEFgq_tBunN*=CnG&-K^dp>hsTOKffj)*4N~D**ieBd&=;!0dkNZyC?&MZ$ zMTyuMv%0px9D@IaT^?^O>+M@yaog)|^#Q8MG2)6RxJz}#LayG`Xh{KwRrjt|v+=R6 zv9VzV`J}!kx#XFc*w54F7S;>4A}q6(q;<G7P-%V4T7J}w5|vGs@W!`oreb>bQ^0wN ziBt;u`%!#%3H?rfjTjt{>Z#fsT1Hh*oUAb6DnRuGWpGGp3@ze9{0g%8aZ9M;akJ{` z1!;H1f=49_d5;!A7eJ+kV0g20>q6p+kuy-M{8mddDDDE3?9nKA6DW8Y3iD_sL!nP^ zT{|F-t&JW9%5JmYzy5n&^7TsTcD8nF_2Hc=(~`kmB3UN*4NJ9LOjiyIq}oI~=diVH z`*M>s)~8eCG&w?#>B*!zrdFA*MydUiD^dExCv1&|R0+_!ddT@l>=?VpBnFnkL!#I> zs0^Qa^0nktTdl1hXE|TTs$z9PO}@^adJnMdhN)hC@gVd#t{FJ=L?fsL(u<Q-$4F=6 z@C-c^g44NdWy_U{CE+soKV4S)Rb?eg8q{$@q-NV)Ch4CnE%L3>%!vYDzjXvPDAD}S zmUuuf(Qopt!_oLXbhTw6*e}USX#jfBD3|+rI+0II`g`enx8gjbs~bb`ylxu9*Wr2d zEH-c6&B?a|PSH%rnQFw@aW9atNV*<X_$po7jHgzts#nWhi8_X!7(}0{j{X8t+x=$W z4#Z|r9H-jV`fk60{uB#R>*Ic7quSi%D8&Gg=2|ik`80(^f*3pOc~S-8`kf|465Z5a znuwe+YOZcYvuvKlzzCnFhdWe2wJb%On?}FE$$vedBtLCo^p{shwxlww4D|Mt;dLDk z&L5IW6FJiIq0x4(<x-05d_h2a)eh2JOXe5GU<99C>-N$IE<x#T`hyC#K;h_=MaUNj zKO!n!->8+QXu7h*WL4hK8X=>yhKF&xfwZp}wL}!`movN+HCJ8qW-r~W>9g9YIFL=n zxmqVwYw^-}3|-|xsHbk=Ox>h#Vsh7S@x6rPybLZanp)jz^Lc1Y1vUl@FN|C2a<GUS zF{D5xj1VFIC3~^dkRYfRno;o=TqCfZx<g$SPtfuuQf2CoDALXLWr94$P47g^kmyr@ z=+TMxW<j>}M^dmqZccoXjTx@<P%A}$t}+_10l#%6I^rcSt!9<9Cp%y)V<^D@ogf*B z>pXq*vfdNF<JeN0flkG8ak&J<;kD&BDPHpRVi*|=@{|z&brn3R#mv^w<|v(cw0T;> z*f3QpLj{{pfhEz{(5@6PNVF}!BASOxM(*$)#5CwhFlxprTX=(%U8|k0r6+(Hlxu;x zI)rUQzFe@|&NIkHw#t`*kh0OOogVrAX~T+POGBIcIszx-Z9wqOVBa)c!oFDuont#^ zpNyg+=g~bd)cL2-l)U6JP0Pnf9pH%2T!yfHio}!7=tKTInt|&ZB<2{DMfy7MK__Qo z^U%>6e<rQtbm6g2k!Lev)KbZ+6GEO)ONTHoePTElNL(~aogYoFr5_KDS{6%+Lw^iA zA(PHZ&^}>xh4iK=^Er8(n@-oc6l{tyRQd>)ac&z9fr3`Yu+_d88?tSh<LwPM`MZ|e zP7QqJaG55Bo$^$w4J7fY#XtIk0kp6zws6lo=*|CEwTXPC%7SA+Hro0tnVwLFx;8$T zR9tr{9isASuPWpEvLkgJByPMNRMKKZ3^)+gCJGg5vt$b!v4!>Bj=xG{;B&2q-gb_e zb&kKv_j&z7Qi-ibgXjz-F1DApK#FAZ(jQM{c90lsV#_~f^eWt1vI#vdoQDTqHvtA{ z&DFI-_G|_xrRgvP>>X%hJF_Erz>qZK5E|)8Un71QjtYrD*Bxubt&p;Hp&2h$yv)Ii z6EAMOtisE>&}%q9vq(Ncpd=W|^{@vl)+PL$#B7%fFDsvkc!M#c1Pl#wQu%1Bx~$J} zOd4Bwtj0~(qj3$xxJw|*`huq<m(gV|JOqY@EliqYq`L3of8f&nO#^>bI-%fROa_d5 zF}WA|l`JzGj})F*>gQ_c7FHH^MFJh*fxLd;fz|!+0fv?};;cxgtDE^+GjPp~BU~vA zxM3-?bTZzIws3pG@W(~P;f1ztx(13!23F+R!X7Z%RaYP2>3L>3IZ}lCZQRd3b8q2E zX==^0wy^kX{8~@dWf#=yUKTzMNy{KlY{h^p4zIkFLsx2SVl5S_L_NCVXgmEmB<;eu zHNZp<rC_6g?Od(nqLgZ{H*K`iMc^d+$Jeol4&YCLo?xE0g><lpPv~&q_I7Dv8#k|A z8s|@Gv^Sf?$8n{+HLbEEZC)j*wvdS94ar$NQ7QpH1*o;m1d1W<xV-+6HgoIvN@sDN zOx-nfJE;9O5aN=XC3DG2$+XbXY+CPSJ3d%8R~}R}Hmax3ZxdQ`Sk_)WoankXVcr|k zw3bUZNqGz+za#CY$^^7|1RCErjDdb@&7*6fE&k~}Q-BVwQ$|M&v3ME*<7vj9*EI2E zwCwuYmRSP#7$(b8*jo8mU<{&SBn?K!%y5~JszKJR&VLk9<LB8jI@mXi?#f|v{S_bl z9Nl(hIyW4~#sY2@FlX-yr*79v(_uWwei5&^yYV{tdAt@qhu6|);JRje?h$s&ewE!O zKh18bPqN$09qe}FcDOzBL~3|Cy4u{XJ?zf!+7I^-c$0_mJ=g^UMQ17p&*-l0#E-l7 zOe^C$Q+LBP1AVmA7pLLZguAIS=WS<zJ)R%-*>=SM2!^`5LHz45Gy~l?-=A5q3Oa8} zDFSdn5(6zn7+=QK-rLdk8=r^vOVbs~OA{2DEt#sAK<(#olgj?F?25BN?fb{@%$4@m zl3t&|fU`59%KTb4EqoU=SXkV5ghbRWJgz5iF-1N!XGKC=%)kBZZ(qTojs?o+7rylx zW^A(<TFuV8<$=)Sli~Fs$I=8yTOtoMHY7VHKlO^G+1gN$UPi}s1Fz-!0Qc80A5K~f zvH`6%kcxuubaXcLwFSQb(2gJ`SOa0{rqHurUPk^qBED>N9N9R&FyeHFp3KJYe(O@| zdxt5Z@-}06AS|B&T5d3ff^o<KwYi~Y1az}NjEOF&?3@SEAr<s>?eOPX$mF4y??Cpd zNC3n~1F#hp2J{XCDnP1jcVRXC5rdS|vN&zBxovwY78@Od_E9b-SuqI;YTcfO<cbO% z0rtRQQx8VHIu$#E-B8Z2*sAXJ?3p};*H9n_KO0Yk?zJj|6E~V#7Uw`MCtD6#qoQ(o z;>H|IutLJ;)>d=W*uimSj<=f*;k+F>_IIB_#~ze&F)HP^dtoqqIum`0oh-_3;W}xu zvUM#dO&}Y6V2=uZEB)pBXmWJW&w9}u$fg$u(8L2(4j`)B?I>cQdbfcyaSb>j>vY3k z)NLXu-AjLP5v^_nQWyFNgNAGXx^`p|kmB~w=nsk94HfL~AGS9@;dr2XP~$xR9=HyZ zj~4*<4GqatI#clx>89mwf`W?c<B}_(TB0S&&^Pkf(I66lM9(QhaSYw-B~E_iWArfQ zO$P^>O>=gPC_C%7LkVhG+yM-${c5w|7?N{fG~b8*OStD*+@gV71MK^so`~^MKf;>9 zD+$jj#f_XzpKa6VH@HBt&VV6oJ?wckE^+Pa1OeX6C<neSZtieVU_d4pm}J9kBPeU3 z@_g{dT2DcRr|!Ucs7HBqy~)0eijT*jik9Xtpvbpz3PS#}EhlhP3}6(o_;Mu(%h8_y z!(CBK*(o&3x}liw9-RZuLFo6p^}dPT&{m1D&$Gmr=VP1)kgTh%<w^J`R5&I>X@-T4 z*oM!+3aG4X0W<I<^qc1D0!vtF?&6_<rXJD>sCAa3r^M0kfOY9lQ_D@Ea&t(12Fkg2 z4Y{RkjXI~y>AX|ENG{U%aIJSAutLjX<7D3Hh-~PGvbW%3!CYMQD4+7m5H?T{oQvd3 zq@1T?(UmMWsU9I}RM!g$m8EN{M^RHnciW4wkHz5fAvSwBJa>KPJ4^^HzU3$c$NmOi ztGhJ%L^=urcuf?QGHLWde^VJJ-@vde=fyxRb_4EgqK|!vGI1t&P7G8+;w!B<=5O?o z!Hd69W^f)Hm~hdh4vfw&G#1g?Ao6)_gKt<u#*j*1sV*aKdVen(s|`L6DMhK!-s`Vi zmm&r~#|5rbluUyd{0qiRXH%&!DSqYruJh17QZDT3Vt3Q7?gF%0z|vJ>sm<m!WO2E9 zjcRh8fMjQsvM;5`0L|HLi}UhZTU#gKhaUX{N<%YftUS~(t*txq@Y|;vlh|Rj$1zDB zM*KgJ5b9)1^JwoSr5TslqH_S*zx^FWIXV+PLhH6cJ(q_{n2V-fK(iUAY%zYUi^E{5 z#~`g;DSfGsMcMklp<WiSmx>7nHZY9#%O8IglfW)(m%d+GH5m%`k;h-cpz(I8!Ja4I zOCH~^zfFKQ@Ky%D0Q6qQT+~s<0%jlIa|OWrBLMF>5kPwx%cF-z()WGAytBu{dd3RK z=p>IHhPNA$McwqL06-o;4$sUqFYI(vg(aOxyveLE%uoGaFxw_{@XyF0>7}jt(1;24 zrx7a|{OLc<2OV-dEoXIxwzxZ80tO{)+Zx*eTp^7i>3~8Opa6X_1%d31aj?M_@*~OV zm<*P?RxQY#UK#^-uWKBRnF2x<A<NZ*G}mhHk{@7m(Oz@o%l^?Xdq%&6M_xjW!)QIK zqm@C7iEqlIaa=_z=acX43=b#(8=Q(oLh1-Qh(=Ho12{o}s3F(=zlK)B3ewqF-yYPY z+X2qzC374D(yUswm`0E*VZ@u{r7jlO#?|4F_w+UTkXMJYPdXdGk-@Qc6RMf}dq6N| zvki9oSX;Rc?6fT~*5=b(OkTG(G2q^KS|4yX^x%MNqL1|^BtBHRmXu=DJbjSOSa)9` zZxH}(W_n5PPE0CkMFD^&MJ=dP-i0<y+u1Tn4?UaU)<0_RYA4`>Kw5CiMfAFZ(#KBD zn+%VZv%K`7Q~Eqqo^SQXqa&pS7AXz75u65e_Br~4k%@x;XI01lhpI20Ojf<)|E_8+ zHvs7@=s!`fmW%b0UZChCt;jqRNcMofSTGFGiU1uA?Zaq|2ek4K(!nCWPbk^=1?=?1 z_Z+ByJKEvdtbm?Bf*?WXK8>CG_-C4S75cyia}j;$CQwzKl`D7jI60jA*<yhf6zIex zld(nGY4vfWK5L~0V=25NNz^UtIvz(?s=VXzyD(g$v(kqu6cp=2UnF>f4Jo57srfie zm}vDE`t%2JnbgX)I6<=$IR~D#4Qr_(K5D)v7Zp(kw4fc(16-l_B2*H{d$a$RoOjcw zaJ3>N3W?DlVb&9j!b^O(WD8!&?<vmp)}dg`^XiaVkp)SLOIUTRxAXj*m%fhTQ>W!V ziR4_uYie3F!%G{0-|KAsP}2@b$36BeK6)z}T)j*-%yi5NCL0aye!&+;%9}n-Ol6A! zw17xufgT7v1`8vVv-LNl{x(;C`<k-168-Hn{mrSroz>qe^tU(kw<`VZfd00!6uS}= zUc>|-SJ#E)n7qXY+TxnpQFgGV4|=t9D;-7iTD_P4{eqsxf*Q80g}gIr=|!;f>l{qb zCCfIADHW5lfRmvREjFr<DICTLU5Dk;MW1LIN&xG=4N=x>@NA;~XtD>t&7ePdi_IpY z!fn7+s3PP>U-)CDbA5a8zRNTdCDpf^y_ofv=h%ydy(py!0eMlNcA)@C<CRhb<fLq+ z)WRNc7iPgulu1^^PL!k0RLr>gZYMbA2*vX1qP#01b7BBTQC)!Ds71uUpO9H!KY@$I zn4OLr#76{Rm{KEqXXP=mM`G%7&G4lkUuFX?tBk(b!zO<o@GY-F)@B8i4l-8Vl~fB= zN$x)V$uM`%y^^~#2b0`A3Ay{T!K=9&CzsOcj|b6DNP5J$hKM1_)s!AR1|`=Ep>hMW z!8VG-MfKfC;y!+PR95SSNV6cIQveE&t+l)9!f}Zy?y+qy!JpFVinZ2X>Tq4gji|Px zt@W`E*CnnDO7a`Dbrx+Mj~hK}LavxQglS+d+=gDO6*r|6yZX=p>O}|07LHoPeXjTn zm#L+>kImQgqEj`zuLvW@y>w$2jzA_-X{y`(m^^_Ne}u*yP93vljw4#n&CrzHPAQvC zW}l|x81*rDbGr@Fc(sAwZ59JRK(=2ZC|yHpj#`O@DP3PGM^fM!Ak_N!3oI0VHvL(9 zB5+<ZQPQ3an$N~rqZdSd%K@<SL5#E?s5GJ1QL9IW;s&z$p(=x#Lzd(f#uhmS)g}Cv z$+ftPjh<(_CrsepMXQw~R;U%1S{@<QCJe@yguxi&Nkr+IN=`;D>tWYVU9rWQw@Ma& zipNt!ZveGB;}9?wvdm1VwXIrc6{6!oqt=F80;}$O!`0cF<5EU~PEjG*r;RHbk~FRX ze^bD<4i+=x$p5All|cs14=UP(rZ3<kDjT7hek1)?CtCtDh=I9!!h=qoA|QR+$D->H zn1l}JAUYvppbQ6^b)dlhWC5$g^O_YnxR%Z-P98;&t#1@R^8uUBWGA2;w9mxN-CRd% z>9u9(O<Qyga;<MUl;ayrVVhEJPnIAi!{VRR%ka`4<Zzr5a4gwS?4|#T!SY`?j2(XC zD|2U+alU(?kisK1ZraZ{5{JhzwtgLr8oh{Uiml)01~^YGHQ#m>syFH|#1+@(zP=p@ z1whfFtAK<=d(2h?=bHs3)zUMi`p&;w{e6k(mNSkIqylA7lcxGPCMk2j!Sb}*=<67_ z@78YfXt_`0;Dl46K<c6SI_;%gc=>9+PWPz^y36BzNOF2TC~JLTXDS=_h9{M46C0e4 z^`nl$?M>)@#_1pXbxq?K5FbNBn0!$9*HAgH#Q3I-we+3&Y{PyzU+0LeuiDQ5KS030 zLYQLfQ%I+=)6v-^0;|R8`VSL(!^VdenjzK6QtK0`(k+p}6lmPj^qsFEWfvmBwsd}t ztFuZ6@1?J@4-6%jP=|B4iCJK;p9d4QvkNiw(x>#;I939KhG9C@pSQfBUAdOSZT4Uw zQ5>cp0P@rD5q%8+>xvEOw$as#PTK&mo&M@ba;hI;_W=OLAq||Vt3p4)yT7Z?$sNQ? zEr~fg){7)PvGcBzcMLUs#dNH9KSe0|zd+U6w9r0hKI`R<J{AdD2Sm_jHBkUKp4?cU z*d}F=c-$>V%1VrpZN+Sh)R(qXiA_>fdE%3Y$f5dC+vATXm(563iSdZIugv1{iu)c; zvz@99RS0>({tc5zvx!uh9G99h$a2AW)-l+Wd5037<#@M=GOAxuoL-)P$R`Yd<gr+n zow!=$#&d^;16*RZ*WJU>EGmnj!Y3bY>!LTX>2&mbmH}QjvaMeF7q`9;1YaD)SrDO9 z2TmwmhU5y&sF)Z%Xhh#JWw4!M>o=_Fqr$ap;cw>vqiq)8O>56Xk6V$;otvPx@r)@> zMANSf_@X~60hw6`u<gF=6_D*ZoJrh;I-@<QC%tsl*SdMA&%_Y#%AHbv8FOdJF^}CY z<&ZPqJ!euPCgb~#H=4fqZrEfz<T$cku-j#xL=vkLnLv6NZW3E%aRyo$OqER-)(1HC ze9jU;k$%7itW|1t3<e2x$tqICE0+W@hz=>q_Cdv@bS+*_8ZSBCYcBZiQ4`s+Qdw;m z-~;<S89(1){3{^jIKBBJQXeN^`K>PfA&^kc=&W3g0v~NC-I09XhVM&Cf0TR=;QRd2 zpCsSe(FQk_hLZ1(;ro=*Cz9`v<9kl&kMTVn-rLZk+OXO$Xs7GcEvuvH*vJ~~G;zi1 z)XG&bBCTjljzbtSR}AFdRe~2MUMgmljXJ7=WFxV?b~i7H<g4%Yn~bucgiVf)rVG$? zW3|xWh^$Y=&nYN2S`n5(-~Wnv7gk>tGQ*wk563H<fl*Hx%-XtG$|ddol)A!*G#&m6 z@PBn-M6RIgFXH4Y+g>WO<5lj%;R#XPiI?aqZR1LEn(Z_sy-J5b(xUg0c7=*ki9*w) z!YXjKe|R=I?UWp+ENAsW=06W2dOPtF9e)tpyb~|c%!AnKop?zsUApP`uh9PKs<VZa z<}TojGmvU`b;;>45d8ghO|!eY(L?CyLZ2p#@r8qelnITKQk6koo<!~jF8Z^&a22G> zPIC8ZwfaQo!qwXurwQ^+Iyb4+=SenWs9bzC9<x`UZ=Oi1&m&{iu2d_=2%77B^c>yN z%Qh>F^60RXsoKWX9&K4yU34N)mNcKis2vH{)b9B!b^-f#C1PWUD~VMaah*^XuC|5g zg)>QYj2yA}3KrP4{L0sr?A34f`LJ`pcP6RwO>8Igb1-;<){owtSo#GL+K!e^VEQ9M zA}Iaan!E5FoEJg&1g}~KZoC4SRU@@)MfgHDf2mIzh-{LeF0r^<-_G=Ql5e?f#VpG0 z24$1kC>Ic?rPP}GlZjGp=`_6MlupN6dMW4pxj{~)<;--)a|L`qY;-2p=4|2NnaWgJ z1#Xs?6ycs#7*X&56=cunpd(63CBs55RWPI&PwZ+-3xws*{rtjO+Hw}zxvowv#T~2Q z{k@@=;ECShrAsjk?M!*g{L(t<7Qewmm!4%a$~cHE@p{~J^G)BfxTdp}FAI!e#)~*J z|BA-SqehT1WhOpy%5~s*JwH61S_je&a*6fRzn~n<%wtesn0D(rmQ<TPwy;-CCx0i) zOr1D=44f`V87QnSfmg=?cel)+E}Ly(yDR>O>Ee^&O0=m<wDjO9NoY%JO}Rr|W@?)v zzTEDvq*Ff9`)8b%j(b5t_g0(Q(lnQ;)ldl)Ky`t0(ydB!oReQ@8MI2NErS{Iub?Ep z;|`5&9fp>PfgV7kEv>{V@g*5@T4nU&lIX|m1J1ItJ+2ve`VJy!)(p0D<+h{Il*+P} z`75PMi0!rg5d)ZNxFl@~RT^4~r^9&A8_l+bZRemFcwC+<ezGTcR2sX8Ri3i)4rtI( z`73M-^r5tj;V1wKca>yF3xnsRQt@Ee4Zt&~{X@Nx*==diJiT#R`bbNo*>rpY#0VeY z(=t<Kj~9axPD$w<DI8J^GnjjF7~cyGD-c$(a++ayfy%^=Y_U&9CIlWlOu^7(2D=Xg z!Ru+Ayq3kWpt-&i_f@M!v!HYFSP^Jjah_~c<v3XuM^o412{rf8OpNDsVSr&N)Vg5( zous-Ce4+JskXYoiln^gEB2Blssq!u}P#qVg>l4|HL$zKk;OIBW0;+c5o@<ruzXqQY zV-ZIJ33jdn#1MZFnLRkgYdeSW67o&jyBORgnL1MuLXQ&BXP%VUCOOlevV0eQh^Fc# zfY%em0TSb(^sH<E$Fo>T=NkJ|DaYwtW6zT>>9@a=qL-j3kH=Hk={Xs5x@$ci)zzoH ztGZ%9m7Cr4g?E@)ibudq^MHRI1H-uwpm6d5Ral(ve-|NO*shP)YPm0>+t40esl-ww z9vbkNmb;tHJUT9l0Spl;o+4#pfW;tQ`U^XpZm5gi@eUJwK-c8ea-WABEOH3y^VZTA z^dk-uA24z=Nj4NP(B8nCKHR$G)^hjbYzamy;W1aJ<D9!NENb`w5;L<1l?P%>a6GlI zE&0^>r$6CQ#EwoWJJ>E|44l}7kqFUMUhGFL_c+!m$8B;<%RPcxu2-MQ!24l#$Fozk z+%Uqq`fRRVTd!k4PCs}zlpM_pUX;^GN2JS~)vL15=z(|DBCMdHam9#Lfq}{*<xeH& z3{W?-aQ@ALgKe^C%BP>61dXbP^&<#<=wu==EP73HCp6J_W`Jid9;`6%N|&>tzFlwe z5rgfhJ#`aMMju#)?dQb>{6K`A;#AOPP$Ia_xkOKpzhs9HC*rS?=Pw%AkxhvMo0Lf6 zxF$-<;*j&!K(|!z0z0s2+zV(}Nh#4cLuGhM9$y$~50woKKYcU&6i+-2uW;jxitQYj ztY*hW+2R=7VAfBBNm28FnVAR3-i?Z&VK9ugb;Bguc>*JlhR*_WpGd?XMZLI5uez76 z-_OFS?aM7<@EIs$4RKjsK{s@bBeLN(kX;dK%BuBvY4INB#Zl=5_QwrK><8hIaQecy zzNpT)5OUq>7~D9UF2dTU57&O`ZB{$Li-AWpT?MRK_f60DFoY;g$3Cr-$uonQISOVX zuJ2ZxYCN@Gzadm@sqv`wCT$(B<)W-YMvJ}PBnBJwxPQkR(gD>FeI=<B{#6X(h5{5f z+(P0Q6d!MdJ2vaSKd@%?+?@;+zbbTSGdqOCG9oL9vx4UBW3f%b6_HFcaf9bS3}9mJ z>??_Le~x?cc+;$~JPSJ6jK>dRup>Ex=YYYzm$VP8hV&z(1MkL@(S`855>oIOHGnzU zbMoBD&rhDoIx6=KTqL~!WdVqa0`tJ9#*<As4uIPzG>Hy?-H@@Q5I#)0r@&%62TuY# znFih;IHSDJkz?dEIg9l)95Qpt%oYsgXXlT4YoRX0%z~#fE?erZsqtAK9NsgLJjoM^ zTdmGy5>Qbv2izloo^6{*)|r%{A@C3HDVVEV9s-^B_YF6N=57eB{DYZfsZ}QBQJ#~J zvnT^nF3^-)IF6laiZ2#;iN3V@2_|OB;k-r+m_>Ok<8hgeh3H8(b^>FSU^_y8y;lPY z`|`APzz=3^orTWV!wc&f3^YSc*^iRjz6^>H$o1O8`P##I+QYMGZUPW2wq@R05BVI2 zb=xVNP}5GXVA1uTldnj`Z=j8HQ2)T!qwrnRK4pudwRmcauM_A}Lw{Doam){2M%ESx zOKUW#z(V&V4tO~vaDJ1o6>Z&ZZ=$W+jdSphA{K`_-Otm*e@?6o07GV78HSpi^9a3( z3w=C&?exg{85E)nb%{Sf@7_~ON>{T8Fx2!IGQ17fo~F>Zqsf`2>V3$6J5l$;peW}A z`z0Q90Y=@qqxrZUE6YngiCEq7V4fN(^|;xQnEm%Ko<Y9JZ)&iovS`;_Wb9w}C9G*c zsOM3{ddYFzZ9^BbTO(;-5w&>fqX<TA$44TP8<-QY8wuk(&gQqF^c<WAorGxg97hh3 z@u)$Qhu;4-ChfzGTY6Zp82pJr-!a(D$k2vUn>^ikT3^-j(A!v8yQ>T1Z-0pvfKKs6 zXc*_ECk^9NjBzgV($6w<%EO>{9Vw4jfrFYtI`EjSZaNS2yoY{@>us(s$Zbkt%!wxq zRl&fPX6vt1Wz%q!G0xhJga_+oTCXni(-|B_fppQ=^u1`w9>0m%rd^zT%cw5ELOml} zC;rU#*+s_!ae!#h=-nq7TQqkEH8J=aTHks!@@y~VFS6bdgQxIdnmxzB?`-ap*N$ws zXgr1lON%yQUK~m26FQLO(>p5qFvH~A2!My}O)$b-Fa5>ebvBp^y|Lj<FD3X+%a4up zH|;!zGk0^~+JjpcApdwe{n+T;AE%D8-5;bgdMYukh6b$TjSaK>UA9xpF(}-;KA-*# zz!FELVbN4RnjHAc#Q&-`g97^sk0{Jyr*q-1LUINVyrZFSbZ-j$D2wBR_2$Bhz}&{a zdg$`s=|RbzBXI`cUIV-ATnm@)9<>;cM8}Y2LZREV?J}Oc-;|+*Enw<KhkZsE9Wc_l z%#34oEg33&1UMod`BEfrKX{bKqZPIrDv*U>%*a`!R>#4+5QC@TgC~@K3mK;_>m%N{ zx-3SP^}+Dgf5;$9k<0v@%H;(cjQ$1plDl}vU4ncEE^oCcm#yn3l4GZ%p~Wfu!0Bl# z_g4&M$TI+eX%nOQp*y>VzdW-a<4)jX8h)(fNxg}91hRrB)p28WpL#Ek9u-`d3aUo{ zv~VS3RIT+f<zs_d-zNs2z}OTy1}Tw2-oF5N@~#HQ2OCnz2gd4{o(r-&-i4HR9q&sG zc%IwCyyIa(b{u3l4_enxAa9)hV&L6r65zYo$jj3ZsavAggzoBM>3ei+@e{-MVV;#D zkVQNm3CKz$iv)Fv07Q-&(Z6i&0}spbequ4Fx;JDxN$LPv!1W=3UIJGEu8t*wys8a| z(poJJMOxtji8!;RS>)s#a*UDnbQCJhn8=<Pbu0E)WaLG!XFz5k>nNx?9^U`R-aiio z7~UCRmBrOGwPH>j%qmR~gBNkU+{}z`eFBJNZ^livMX%yADsI<_d?*^LOn*Y#!BYbc z3j5BoB+AZk3+$CR&H6{>`PRc+vRp_Vsw&qXtIRErlyh>1vWg#KDas~6lOI62h2imC zmIR~Zm0Pe9Y>wZ6%}Flud*PAL;xQL$LRFR;H~m{7GcIw5JOg#4BJ2iU`JP~5(y>co z`;3KMn68#0ifn#x=O%ap?+r86g74NV&sD<a?}jaItqAkgj@BlQPIlncCM6Yfne|+| znDF&mj11m)xC{@TyF#~C;;xBKKkwtLZ1UQS#{r&UUvPibSZ#y3c64i_zfhJ4nmS+I z!fUBm1*tTH$xJ$uYpyjlOo#=rxF0ry&lxou!{xzn^Ci;$V3<j9U=B(#@V_f|uj&+3 zC$EHsJLNt<PX?LK75PjwK4S7=k0y}8*b1EM!QlST&$xA<1eV1emp7J^V})-=dQ72( z<}#%!rYWr#aDP&0M;vad8SY<#_H@R3@zu?DworJ$msG50k^Ba@)?g#2Vq{3@Zj)NY zt7SsyPIwU1GG1Bz%L*1w^6D><U)n0m+l~xH0%45cUs5g`GdA&z#XuxKA2>D5Es*xn zar`D-o1yDruEiCI_X=x3qfLl>E|OzcX|z6acN~VPMUJmRo9%HjRjoFI|117*8GP+; z2Q`Nqu8n8G1b@Q8_Oiw!mw3>DG3C;N4Qc)bbvRw#$U7PZxm?$8m#pirK{<<s78{s? z+kp!1T3x|SRU%!ZKR&bLDjj#X0Hvw;z>}?l`Un{6=EAoO)p4AU5r6m_6vXB@ZmH4u zyF-g_i7OgYca5aJFO)y1)|){=V*YxwS|_M?@u*Sm65#5n6Xe>q#p$3$#-SET=M~Mm zKEI`T9BPrbM{AK##f}Q{cGSwgnL~G9r91)*X-H1WxtUFE#X}Xh##KRGY>0z?TZR)) z>K$>l;?`JC3EDg1o??s#4&mB4=<@5K<Ru36u6SsrEe<^u8RD0~=m81J5NlFHzbg(M zz?7pL$Ir<RKpe;2!vo3?4k&Md%9GNP^v)R>P?oR(CG8&)8wM1h_eQ2{HwsWH>RZ`t zl;f(7&v1p+eIe6V<Pjt#h9yJZyWlD$Mm8X8T2eWu@rY1<LOH+n8Y9t{NI5$r>sv@x zrjwU+jr#b=Fj<$3BCE@+8r6!tINRbk!r+#jOaW92ppuNKs9}`I1m(kC7@&bWJ&S+` zy|v9*%3Ip$FO=$-7R?5>Q;uo2{?ni1FrCfx-dV5<JUnsCSQeWxl=YsRskB?vdckp~ zi8{{6TghZB_<w*o3ovKp6;W`B1a4H$UdVY%B4@@G-_F9fvvMwd4#WM=sLW!<>8uPi zBj`M~_3tjTY9QrirC5_bQ71Db%gw|LDo42tb`ROkC`2~zsF+cW_`EG&&jOQl!c|oe zdlJta%@rp<!sR3-!bd+tZS!r(U%aEjrp<Uu9-Al_3iVqXL2n*i7(5Dk6F}~{#FNZI zuzS8rumgzu7UT%WfEZwY;GMkVPC;G?vc$Nt`C9Te3Q9b*xfpm(t-mm1Wov~B|A$1` zMyfBsz&|Z3Ivb=%2iwkuL>+qC#32!K$XU3cQGH?BU3|h&h(SF9`Bz?jgog^rzoKFg z10iNMBsud=K?Q&s1W;>)1YQj~XJ!pWfGd$Xn`g8%XK`{CV?B_XFEbpYm^7ZTxwQg~ z1^~$(VbF|6(dG)h+L~ZcW)z+NBI9;YWWl3SmYS(99)m&;x=`*lo<zBZq+3C(`$$gc z5raBEcvQZ|F&W2MAUD`r%pQ=_m6@2NAHE*CgCAjX76T1qukwZleo8*wdr;HZ9?HZy z7^Mf9-JI1Py`#U<q)4}W>8y5Kr8q+m&%%(6KfH<?iKEvg&ZlWkg_3}oEAwI4&2-bZ zBIrA8$yc|S*x<o7^BqBl?q^tXbvLf@;<?<=(NBe8K%Pu*J(yfu(>HVe@qoS_aYT!n z@CZc7goT02`)>f)?xjC{PWR`$Y*l)+Z_GA?yu*&s?0#<8E#BXK4K%FyhS6Jzh|A=) z^{c_TpWw+G#q2r<u6EhXq^Bnhyu%LpI=cG+b6kITV0d1Uk!k!ejy(s{n6uq1kj_Xf zHIz7HB~AZP0b^&|@`99eCkEBMv!M9aXRm{6%U}vFP#EMnFbEBt#5IL$=>jMbFq%VW zTvgR?Uu9MGltVo%dT0zD!mH09-9J%3+Zi6;{ap9z0?&dllC=JcbiPFl?7)o&QJi^q zuC*PtS6M>Ae850_GU6s_+T3(CWc>v9l656EjjRHAfMcnW5I83W+_+&W_dME#&oXMU z0&HP5Sc3F&nZ?KNNX3IhDn7vzw6J{v@GZZC8@jRxYqc%haw!wnMuJ!@0ir0Iia9B_ z%{{kuSzl}Q*Ld=cKLt-firyt2jJWB07j(~Y9tmNcg>M+E&7i9tN5sc}gQiwWDCqnI z&mW^Dv-F=Di6u_ME7uqz(Mf)TM+XAeeiTfI*OzepsiEq=8owbFLYNx2wila~$gR&J z>Hz{PA%mX_vDUi1h$9JNqX-A&(*t{uaM$Dcb}TaqAtM<h_Pr&HT*zGF_FOy%?f|x* z69c&0bGS^vVN{_VuD<Lm3O<47*BwAegSh=|c+rAbzQ)RB^SmVni7!c!r-}P)wxes5 zAs}_6yj)?(q^NtbeR?-10GDbkjn2f=@YgsPk;I@6>tThaB=D53_h&D6tL!_C6^sUU zFg%JG9&^|U9A-PKPkihWIMhAYVQhL%+c+Jj^&W99$x$oB;+`BM@)xoIurl!HYsjp+ z6ta#0jtk;KOoF?rfxE0m{9O>8lSl}YmET}hTp{C)P_PQFj%xFIJ9(;vVT9MVv1Kin zGi9@mUk8`%)VsFToOsxFfc5k^j%zwZ&gi8Sp21$3jlJU0Q*<dA>5V%Wz6fDpO>?x1 z+vl+~thA7|!~rt#815wR!EHafV1USr!IL-*gH5VV8Qr7`)})eu)TB!C6#J_8rMPcw zS=kx|nl)Zw%}ViSuUMnzIh_itJ|%Hmqne%0ZH#Azuzh>~`S$&b;oI%I*N|lGQSDoR z?Ze+XWDVMkAm45X%4yXlO>4lml;~}NMi}<ugYhlalpMVc#ts9M7ySw?Fm~uI*bQp0 z=`{@P^DV=lcnkGLL0&^4EVnSi&WUuBh}-MKt#Jv#J>&R54E!u1WURTQy|BX_3KU`H ze<Z+?$+#B*9Up9cBWlv;o^;NKl$E1fuM0GzK_(uzwgBn~VOIRP18pyYXmf^(&DDvi z{058S^t@M=uN=TMPF|}VU@+2+{?rCLlTg`0$L~w7cF`&Oa3qQ@NJ#H=oV<<Rl3*gH z@12sU%Ti16HOzM|pzpqn`SUUV2k@v^*&@A(FhmL&6E&`2=QlM_-!It?H?xo8a7|xk zE6BL$Hi`aP&r5&s@^HXz!g+;(ymNT{Z5n+90MugII1Hx`>7VV@gJq7gpB@V3vlTef ztDj3ovc!XnZ{d{>4bp3FYA?`_9wEm5iaESN8b7l3a#JjE6nA%YJdN)irVP(2Mcd-) zNpc^2VLv;h6tFWv%swH8@&6-j8%O`JcXXTn1KV`Y(LUU!Yv_-M0oVj1y(ZC^6MADx zu5645jmcq+>2TAvGxWnXNP2%o8Z_n>#HDLG3k%KdPHb68a09f;sMdGe>$|0i^p?GB zo24pH%Lsb^pn*Twn`q##XAB=dqwjyk-~Gs^@9r6%7G=gn!=B`{s2?XK9T(+m=zm`Y zGf#(!rrKqp3E5~q3pwwl-e(Z0zEGuRuM?#FD!WVAm?^$&?ytz4%*(y_8%NOY!mpN) zj?s&N!?x$}VM)uh(Z}C|--RIwV7B3p#o%(L8Grr)2K=7SK(8dvPnbe8_FS=g`Qtw% zPfrM=9)i4l>y+qGwj??zPidV(&-~$v4Eoxhr3ZfrjjeZHpvo^2>z#s}3-VU0VVL@^ zO#O#g@VBazW{ZYic!w;uiLHWj;k-Absdvg3qt^_-3U^AWTD3*~0#Puw<~bdw#UL&L z7Ei^K%Pj`ED71-%WDhk>3Arw~i7PI?%(>~D*Ak(%f>s^3%klLe;SbKlcY|}@&goUl z_u}t8#S9zfg*K-Rsm&HBW13!ug_UvP;7A!3yKI3nTqg2%VYLPKlk=@pqkQYiG_ANk zhQa!MxOnP!FK53o0|eUl-&d^2I{!PdB0B<1I-;w|k;1o>ODUVHLz@yPOc{;BgWpC0 znqk>(kn&rn(tDsxa>Reba@Bz4PQc(0+-{vSx|S<`VaA2Qq+=B-Y%BiDUpNl8BW?mV zANhe4%cw2ZUR(qJ%04-O9#FBzgR%3z)t@`{9}@IvxxI<qUur3WL~}<4hIFQ467GY8 zp4&1VPuFmn7ZvA8g46Ma+^-x3*02;tsvIs$v%#slEIR`%ek4T<yoik1E(V@Q7QuiL zT$y4&gJhKjl7_!3<Fb;X3oPQxUSEJ=Ar^3WP?Gr9Su~&~TlMG@G4KQ=Y$?~*GX|ji zrrSdm3xrbqY2c0H=np}($zeykl;6o6KMt0|7&kR_<945RDWj7^8Yy8xb@ieC=(E@N ziGlgJnL(5L^rdV3bqTA!6Xs*o8%4b=o<#>>A$ISQBjA8L-q5#x54cQNwRF9`K3@#5 zt+Cbl;uHUlu?liNNY3b-Jv;FG8(Un7<rqZY9;(Plpg*3z4eE~cffV~Y(-3{7Lx^7E zrgwgPbqh!@M(hJ%84GC{sUz8k(>)&i^(fxsiKgj@AfN{u$Hslt74zy_s39-?FFmTL zuBVQ5O`lrdi#n0@jzx6|S9BHoX)7yR@4JBej?o94hJEa^ih*-X^<$I)5EJ{2&bPAV zKA<_Y;LoIpGJ*oN-AS^r;2<cbzh@uh-cqW>x;7R=Ba>8lWg1W=?iiH*(wWYv(#fbY z_oHu7C5FGz3xIo|v7TBQ{;_^GtsJXmz1w$Xjl8WtIunQ!azQKd+_gv?`2r11#XY2| z+zVI_d@!kh24trp+|U=jCP~VXC<iT<GXDp7Ny<Q4#(s~}NUmPM%w%`vVUX%4EU6>( zKo`boqXj{)`|0ojkRyk_O#3N@D9wULO)g;ATu~dHg-2!`w*I3iiJF=bLEqU5qNhvy zC1~b6j61URS9+POd$rtHQp}4GFgo|D_^(zy{;M@9zj)jM%5Nu^kYCCr<TnqPBAqcs z-iZ8Kv2)E#eoZ6to0pVd{5`KNCEK)KP20M0?r7OPHTB!F>+bqiAD;=HlO7E53*3Ir zLqFKTdbrk;_}w)Fs|h!_AcJ{W|HO25_t2x4buN#}wtf^2hCHx${uM33U-c?W{9Yup z3>P|}7pEXon}MlK*ckfYWc`=?@<0U7tH=nWI0AYtw~wvy!q;>!{q(=sZspJe7lylk z)|3CB`=>vN-Cw}E|66@Op2b7t|D(S5CiZ7;!?Ah;PdEG*9>gNhhuGaj*RZ>pHn6*e zdf7dXF2Vb4bRm1S(go~ZKyPRFS@dRhpG~i0_c?SbyU(Q)*gc<$>|RXM*}a5n|A`nn zwGB?%_n(+lK`*d-742sC#q>P8yXl|V{T_Op-IvqD?7ot|%I>S^9(G?%Uu1V5eV*Od z(r4Ix9etABCAyv6H_-sQZ>F0QD7=gl_Vgi4eHkZU>HX{xPm!R@+2eK=)WIH6DbqXH z<CFM!JA1@mA)vF_BL;WTY3%ViHlf8H@%OfA7JJ-{j~uIecEc414oXEN&5_DZP5?dd zm*27dt-K?3aU$i7|Es-k0f@3n8-C{kj5s=DqM@RWiDqF&p$3f9APizTI^1Oyb%a5f zxHY`5ml7QuXc^vSGb_`!t;{a=ZQIvg^0M7PT=2Gv=@u1RSZuz0!&kTxU?KBA&pGc5 zGbpa#zkT2C|NT4oc;5G1pL2Q7d7g8g^E||7y+S+BIGJ8;KZHI*GTFi>DYXIVVwz`Y zE^2MSa?z)n`h;i$R*F95)F)IMutxMTQJ*kvK%VHcjQVJ_0R^H@9K|MFJFiH@Cc+mR zpf-p+EXud?6-w<78zu>RUMFOuBa+hlx4-U@l3TzN@>E_E>iU##j-JTM7cS#a^z@tB z(KW#flYkhME#oc$^{K826@G%*5bJsuU2pr{%E49;rLW<KM>>m{T4^w92s|uN{Zbz8 zx`?7Y$K2p=ub0#YlAuP3YOg%J{2RU==F3&S`?)YH`jO5ziKXGE>Z#PpeSVe7*ypL# zpFEWFaXv$>Jxd<X5V99(-e4ed7ec+JK)qZOyswI7J~XeiCKRg76M9tz<fp}mB<J#u zjVQ=BMM&K@*bdt~SEFd7pBTh%wm*JvzvjU&($nY@pwZ6|!SJNmhQWrOAY6QHuz>n& zTz@(#n%-9Q9ws823wUX)gqs76Iy2TJ;bsK4vy<xub!@zpn*g3;VofqmZLgQx56gqw zxes}FR9(aNNp)x1>~)fc-or%VEVNb%eFfQEfDVF0t-XhlkYr!Z=OF;|KLx&xnExLj z|M%?mQdf-!AJkca>=!E5t5ERu{25uJb^yMZKGim)C@U`$OQ=&lmQcrMW!f*O>|d+2 z1FKeZidCy~I%ZGwnh+gV-yyYsDYIWzSZ}}diaY%2^e1%8cE0KN7;5j3Tb1@Une3=L zyt-h!j&X-O^DrD-0baLng#TU!I0`Twn>VO7Nm8>&Qkx`&d}|g-?Ts>f6UqIgH+LA9 z-nb-|#NH^iH%T$ptAjYuI52P#!zKxa*7)Y}065VAkpQy*GytIhY5>I(Xm$N(?T*C9 z+rbsU6~OHTw-ekhaJ#_m2DcmBK5+ZM?FYBtDM$W>k#))X#KL$tR=NmaBfw+mqlb1p z*03Eh^nIqa7k%)%^lcGn4o_SsdsjamZHt`{KG+GPu3UPhAIk08f#vpo0xkXG4pLuF zpIoMW5`lfv{RHU~jJ#bA|IGq00@NnSrk|-<B(r}*TJKxZdcX0>8gUcj4EEJG5R>#m zjZe(&KJg&ZV4r;>vww>ytG3}K0{^^U2Imcc-vPV}a0K8az&U^mJ4oMzL0gA`8wzeH zxFO(%fU5>q4XzSgCAbQ372wLjmHYP%Z6oGM=x=~ffZ0#_^i7fsu=eQ-^6uXczJ7jv z=kxvF*nG>o$waI4OtcrBNp7E+HYEiQjUXP-UBD-1Wdc<ygp7giJPqVr6E{XE-0Rt@ z;hXr6UH1c_<23ZAkP89hnDc~UgNS1(ZHfwEjlzn(NQ0jyYWhWk)N~`snHVXzX|AA( z?u>pEp0R`!%)-s9Wst&t%8iy0xi)bZD@<Va(jB_LyyV59k^iWp`RXmYk6t2Mbnm|8 zzeSh$65aJVdi^arZl>@w&ESzC8OUe`_Tz5;uxo`;C{z1y<c0akQNK<|Kea>O>d0tw zO%(3%<|fR0iEih$5)E6P9WSB<Ro}{Iv<W+25;whmrS@)mQ9F1<+D4f0GA{WBg(Dt! z5=Pk<D-})gp%~;E121xCd<X=A7tYvxyuxmhGY*N*Zd7KLu=WtWgJzH0P7YFARMkIY zP@t$AZ*n~+N;|5mZXZ;E(S3=iz(6)TM1t4--Z%(#l83jW|6a_-{Si<))U%m*J|%i? zqn^Jbp1VZP;)8f|^+h5o#)cF;N3%By8N~lN@ZW>~0p+qRW->-&7a4`$9>i<m_{Mh$ zuO1{?r}}{0nqBQ?XAv%9g458KVo^E`ohcTH(fu)a1@`E>CESQggBtarx?=V`Me~g` z3b_aAN!$!nozo8wVS9Gbz_CUlNel$`pr3@h=V3L4IikPXhkt+wJ~zTC5rDThPHmoI zzbxINv|pBSA$!marE3;(9HYp~B;lqP{SQQ+eZh0~O2vhf@vDe=k=!26!IR}LJSWR7 zFZiD<ukogIrFm2VM_c4V#%mr4;Sh3B2PK5rk$ic-{hJY}+D^uE-ZN$tZ%27qb(&X< zOnx4jWxi3k`~uO3gHi@uJLEh4RdQ!lDm?D+o<<KfA<+}C9q3X?CabUn3sJb0CItV1 zXc$pg#tTY#%%)L*Yo#Y+{~h)tIJr|VcZdeOyjCQL^(J1|Z!uC+J=ClP8o7ww=6NHA zEe7peSQu(%VjRQh9B;Q1D;Q|@;u?k}EHdFrt=moKXZYqai1@r>H?iC+WZuFsIi5@7 zL*@PNCRY)X`=gEuzo{nj{%YPhE0s5frwSps!X8mvCGL-x7!t$P8Ai)MfqM7Qy9-8V zVz`{%eTP`H@a_WMT5z+m_RZn5-E5$i4WGUK4(HtUyz;k>CE-fEwy^oPa)!H^-djlg ztwLDLh!3bM+I0ZY7B91l7Z;-H@_6!Ixk-*VaB4n9$)_q~QWRVOsaiu?$~#X%Z@Wf{ z4`{0%rK1w$jt7+)DaPg5IoT@?%NcjGcfP{CG6n8tzg<O+V)14WUe%I1BDKBTY~jpv z{xTlf&yml-R?)}!?7()k;4XSa2rPgVA=1sq;Q#Qg4ZNW<t#%69;MpRvAEJh^Z^qqU z)&2&H!YG&z;h8`uHHQ5Jx%jfbL3KdB(B6iVZ$RzTMXn~>4|i~Zc0;Jt6=3@zf|G$K zuMdHV^05cR{nM(2<RM)3c#MSD@VMRfLnJ$*Ngsmt(p+<EgBEOLM=e-Ryih&7YZ^SD z=`L5Wy-&@Jh3MR95=*{dIVWF)Mf@7k!THb~^<gg;qS}8#bwIhar(Vt~RPUd#cSO1- z_14RvJoc{I6SfYM?eYZh-ypMhXzcaJw1$xK34pXBM&EC}m6L0aub&35a$@{<I<F61 zwok!ni2h<3Ffq7TxK{8v{i=V@36Xu`$mz$b^Y7!$t9^2A(mn|nXK$0TBPuIUuYzsE z2&iR54A;MYrV#max4TClDxnH*SZJz#w@U>+QVX*jCNo(h5m`Z_ds0U<`m?g$oPNI! z<n{foP*0r5A$>b|J0Hj(@1z_PfQHGrpn{E)V8BU?!Y{9gmzz%d|9%91W%H=v`4#!| z!|*GizaX@6$n%t6*#)oLXTg8z02_aCgZv8S{<rxRg2S-<ikQa_P^JLT2G9b~3~&^n z4&dM~ek^_k3*+5b=`es<01KY~pWs(se8J1F7+)BcUwQd?(kB>s`|sen1%P?sZ}2NG zzHp=b3d#4s#IJ~Xr-QQ+AP=AjfCbnLPzCVJ3qKaWLfhyq`2QflQGnJLek6XyyE&GX zDZD2aEtDAd5RPB~sIwj$?)pi%k@f*87uKUol(6H0wAg|2NfN$KaLB1KG&U?#sF2em zX2p4O#2idH4tkW3DSU#`Iae_p*^NM^qdoy;mhgw2c>fH@Bto%K%?wCoo!#jp6yV%R zSq|$?-vjiYUCnXi?IaAt{X6{`h7X^<VWEI<xj!#48YzSmqBbCxO8EBa>m8D>-6`@5 zq*(?Vnom;hv$Iq7DcFg)wLEsW+g+Kj>?LX&vK@hFCOb*KYRI){LbL(l8Z+-L+)rF) zk7K9AGXq?J@Fgr&d+>!EAi=r=i&I&q)6j)tW(GwH^hXHok9GDqOf2O-9XzHu?I0Ou zW?BMJ9t@?z6vj;VIQ4m=#FEIhj3T*TcC#;KIy1UbjTkY-Jx)n-Wu5t`q=L$FJhvJ5 z;+q06OL8Ipt05PMwU^j&F*#~h9X$oLTjO2ZfT&~n4n<TQQs{(r?Go}fd#(d>Q)#52 zeAWKZ5Y1QpHEOCmju*UD`vZ-_S4YI-;0jclUGoN+KqOmc#2D0@HBleN<S0~6A5Mkt zNXfK}AXj!f2{#O}fgCcZwIqpE6TM2pPU3C&LazUs$z5J@M$nOs-TVEMo}0(M$lw@^ zC8~r-Nx0l8AZv@nzcf`fMsoe$E12M6OwSF7h68-ozZ554zCJpsuD5ymQU1sbrpxWt z9<>JZ_1RDHj6)vYa0hai)r_mdYw;wjx^8ne{RGNW$OtDx+aoTbf-!Di0ONR`sQ3$& zg>zHv0>i4&9x*pI&C=~sq*=am$<i!6?s1{WWCS_F0%0|GjTf%$@bb$6PkID<yau4? z2CMc&X4d8v+EE0DG`=3c_>0a3R6sRIGz!?*qk|7>9?FJCdUTLYjyS=p7qg1R!(d@o z215I~#t9n+vDgZaj!>$wVQ_C9XNpiEcL$v*l6Uyb6rRibw}_2&jSKp+dPI&37jD@> zq;M5G{BQSff5OYpNqNzDObyOc5fITMk<0h`nLiYj@kD(Vvr56u2cB#BZmOFB-zN^5 z9xOd1YC}Vz9Cwn!GpR%pae;PrGRd4u`HJ(XGcj6eq=sy8+HpOB+~8+`2b2=J%k5(i z=jy6D6D62dwEPoVun((|_k<`i?MAaqBZdEXhTg>`SBFqk5BzrTqP(l4qQ&mkshoHv zgrEB!W{c-%c;^B4iR8p5fGB?JQrS^Bt|tlFcBOrbg5hESLnCGs^;rTm1@Q|TYzwjp zfCUFQa#~$7Xbq%xg;_*Mr4?8p=PG3ytvF`NPD-OSu{Y{m+xUtWo@;{w#v%3%B*E8> z5Y0Z?9YGPT9|(ljYzvTe0k>_hXm@j)7Ij3pshv;Z@f~iDQgqhjRKDkDSCb!8d6-n{ zaQV$cY-`%<bdbpP=lTl)j*50V7EasGPpv=i>9EE`g<O&)G+v?2D!<m^F=IR4vmPmA z?Q{<s7*Gx_1=MnDfn1Hk5en3$=^oclCA)|bu3!un)}V<pdQ2+W;B!nm*H<JRX1`E} zz6DsLG>5*KXEGi7Rv0W<(EWy!j*2!%#W}5Bsj6B{_MA}9ztbS3pbG2BbW&qi*((GI zw;Yvz;&g`FJr58sJ<qi^>CfTF2c{Nhx)x#Pdqg2ilD2otipl|UcAe%-oG+eT-zg9q zgGYd%h!)ST@5lm1vlWu!k+i~nmPZ{Pz|(f1V5?Esh@$@x-B%_BW!fs*V=CI&7N>kZ ziX*fO0}qj1gG^Lf?3*1RyOqy5sr`bTj0J_IVGNYWqN^VSuW{tG0gp8qUt=oHaUn=Y zcw-TK*aevuiLi3JIAj2w2#8`FjHGSC3*~LXj3>x<)8-lpBht+V@P=lG1ku~@8Ig5p zbDHbCN81Jt`^;}WP@u4zN>)GV*vR_qj!!S6P^#z~<ncXn*-g7yfgdQ>hb$CYK~mRu z1i1p8KS#ncUsW0iuv88IWoqERRgt0*r)6lwDGQA_tp=~sd>#B(Vub(JuYv!zltI8c zH0)H0hMhK`VW+KSPI5}@G4HgOhcbOEJcT(bx&aNMh(^gb?B<W63C`mY$Dt<Z_?v#> z&y4(-yPt<e`IP<qR);~*US!8cT*S-rx4OL+n+!trF?Iu=gLl<rXCuxyGCE}~5y1a; z@mwcg(FGAMy^N-y(zK_!dA*<5>(vfJyQd}EA<UqVfd{0{XoqhgLf>voO(B-JXbG-~ z-e%*^03&ee6&~=FkxWq&9#*lN>=KcsJeb~$P+jyFF;r8nM>%R$)t`tQ6QOUa%H3`h z3YsJQiuV_SoX2~VlXxi$+)3Elu^Z<FJhNm^5Z*q9Q?H*TlnhDUQ+ri%zR|Ttq@^YU zxsgT0Qf1_30!B;p*dftEy;S=dq#KRGBD{S8_3TpZ528Nvh^7JcBDX=!Du9ZUYrEJ# zMsz{$hkSQe35817`<NI`!A%uT*81<Frc(?_rChhha7wndvO<k-8_urE>F7ZHtb<h1 zeo7UsLTy1tqeTY)3LqC<!4k3`9(Eoz3ITE2KnUPWejaij$iN^4K(yuWDWjC}ppQqV zaU3cZ!!)Qwj7X>CW}y!Dn0XrTVAF&~8QBuLpT?-}VRb}RS1clCI!LrpyKXfKnFq=I zvwi{}Xj>2+$Bn@zHVP#&uf{WbqZ|$Kac3!4!^5f@Epc@Nchii^?RO4Xae{<JPY{*j z4z8bUC~H5*?c_#iLI;MAU+svd+F@^UkQRjbtpoKZI-+>JQrn2TFF<<|X(4z!4s9re zxW!%NMs~STc=G_N99U$5mFM*$x`8T#{BIU+b9gi(2vZy=ppNtB?J!wo8HFQl)Yx33 zM>lQJPelc`w9IG+ca@3|ivyRgAmO>keU`3JoK}^nLHeg<M8gKLy`=rTJRQDN&kkP* zt{|vB?$K9}=oWB$ZxmnY(JpOolMwA5l_$x5pFFe!H%>*(&r~Bc-_Y?KK|`<~q<P+T zO^wuVi=>5DBXxgG&Xq>}0Fw>mWoV6u!bj!Q{f+u7UggwsXGWhzmYRYGY?<ydg0N6Y zbTWqH2}~)@AAJ(letjQ1Lbcy;xxP&?vffWQHGV5T`&(%+!Hhh{8jvxpP#%c??N9b= zkcXcc++G{R-WpuTPPaEo>`ju`3)aBcuQo`fU&l7VQv*CT#<l@p-XY=6L>-H5V@IH7 zAGcN7`w3sa!pqy^BqYu|%2I4rHInGuSbtWk;~hd^;+!<$r~Z@5o=1n7lWIs3CHu!r zG9_tGt)D2gKI)%1k0y5A$LqUM+&KhLNfEzppbK$Mam|NzMLz&Vfdna<G9~hL!Y|}R z?YFjpQxBQaRQ9@oVTHXtv&R(=Pvucm4YN}gABUeeDw7L>5p1TbIu31%+nAZ@K8uH? zjcht<9e38y<-8v}5+IE0Gg{p4doUJ^ocT^*$c@5z(foSFm>8~~C2H5=@z@1Qus6xE z5N?k+Ln2+)gAp_s!PP~M3YLVcM;^u9c5Vc`%X`lsRx@e6=S4M4dEp^4`gC4)b_E1^ z_$*h@Vp}xB2I{Jhao;V5fgMqw>|J$c`;vEft{CO!Kjkk16%C(uOxzm0s~K&P97G{T z_}+{__lygt+`O_W0D}qh?k}{A-b84*LcL`sG&0{Hl+p<X*5FX>$6Kbr$Db;!Kz_M7 z+mR9Ky2%bRd&QS9xKK#N{=Iv1H$Muqv0s*|sxIUAe_B;_kz6L%X^(Or0W%R(fx?8N zQO$-S42puq=3`a$vsiA18m)mZ@8BRaZL{j}Vks(jRBw@6WUdZMdxm-JP_ea$=50WP zO08{ZYRakqhW)tKD5?68ZLS>|tFX#rkFWo=P6v(139k2IDnhqJV{Ej}r0cjzN)1$D zs&8p30jP%B5s*+3dtCJ>3$>()&$~`hflVYH)oH-(0~R0QmFRQYFH}`-7=s@mWn2B( z79EvUzJ#*MbDfEk6xyZ@V}+ThTlfebaSqCAzPz8FWct#yZPfA*s^n2s?SpJlX%89f ztw_m+(Iem;3|>FNuOJktN-s9mpRtc@S?E*#e6jrT!mFs1xWC%X{=`otc-mDc(0x3J zco)iWlk7d^vNxmGIf4+C<P9fs2Q68`3(Z6@x=q-LYTEQI*&T0_tvcX@D}2SGNxxIE z=rH_vM_eLo0<aChO#-K+<-%Aa*379#Vd&OO6fV63BemF%graq;r^q=VMhJxn?IePd zDB;BjZq(iMS~co!dJs=6;afnCFO;wYYQhmv%r)d#6&h@Gny>-lX9*8glk@CGr}?Ot zH2+QEHKb18C?ry+d<M*N8X|j21y708=^Aos8G0?LQ=cii5VGJiaEd;A)fC<2oub!Q z`p>chwqd5|r-n??AHftIGbC|6P3(Gr7&KSI+At1h-&AoHy_@JwSG(?Wm%$?1h2E*2 zi5dvQ%Vd(pIeL=th0SyDeWTO0NPfAdp_K!L5JN0pDA6DQA6P37S`f!huBu}vcqph( z_{N9;Oi<q^?QKC?YVaNAQ!>qG@n{V8G>p@vm>_n9y<V=f$1q%Prp_Wa3Wv5)ef2Os zqvBi32*Cn#x@)vi$i-Wes8JrZs-yaK&NVHN*Z2D@q#;yn(~;8+)txMKZS`-+ja$9@ zLM54eWEPYGlyaISE>pN!My;zmDmsCL*CE3gRTsTlLR7c*?ZGN&1HzCH4Ho7>Pwgc> z4cr>+yzrRGgd`0UqArso`uhcLtEZ(sx=Lem`c&1ssOquDD^XN~X2E{$2&L({u@J<P zAPo&_aD>wKcW_;R>F*-Y1aZHx7B#E(X@AJxoEkHQUFw|szI(n<1PzxBg>aLIY9VL| zM<^jc`6M~Mb}e$wJs2~E>mpho?<==h<XNJw-Y+UC5!t|IxRw$;zhqDkYK64-3+E!K zwn_Ead`LsoxT@^90b{ht#k6}pX;oD>;mVTH?^GUij6szh28Ck+sU)`1MxN`pNHT?^ zZ@|QytuqSEHmYF@ntLVCt#66`S;ECXiDQf%MP)vBZ>A)zp^tBhXq4$YYeIFspG-Q| zduIC46j&K&(cN>E-O%k8`YSxNVV00xNt*=E1^R^tD#;;5Hngd}yQ2U}V(^{k^@R^O zZ9vrSC|;C9rX!vlqYLUca9k#33a`KA#rqZr$jlOSLlG7pp$IpLk}WyDvk18|H{DE1 z#T$j(EFrnVf1EaNzG}7rMA%H8>&D&4Sd`2cP{~$ywkuw>|4dKf-IL|)L|v^q_AGm^ z>cBD8{txTVD@GoVF(|o_$*#$&17~6~l<X*7zG}Y$!t-GcX#y9+M`JNJd$`Qe{)JwB zNAGUW9X+6roeSM78ayga^TL5js0B(Wjc);>nosx0)w1JigHa~-1be#b7@Hyr+qy=! zWbqC4U#T-kw(!9ppk7qIp6`u1A?uP|wqJCkiqz9ljrPOx%JZltl?$6el%<|UN5Uy8 zzed)AJF;r^3bf<5us^neoexvdx3OQbw^p^Y7f^DyfgJ~4t>6_1UgumpSFNTvFC2h$ z;9Q|jKRWIi&A3BL=(h~APkt8WkT)Lj@0+=gc;^sJ^hEXx-k{W;U|V<zd_5mVhq9;A zQc{JnD#BY1c6=Bt8F;j08CdSncRDiKwOueB=RP9te?Q`TQdR>5E0%s~vqC$M9F^TF z#5{t#=)%-NWXMMMYY%(XO{4^fhj&?5?c~=c%Tbp^h;Zp)lFKI#dx~>eD!(VJz0r}= zr9G>vQa~;}^-@)}TTa)ddunyz(z@op8vTIk{kmj}Jev(m=0@{}dz<%3VBY_7z>%Rw zyI}B1q4H!Jz)cf=O3NyK*fS5(Pvg5ybS<09A3h^E3~Ft?RR#nqa>EaACd4XE-BW~l z4|{puIP$0vTc?1WYo-yin43|7h02jQdKOAF98o*cN6+R}vQs_r@?@5+T^wM$9LyHs zan`yT1+UV%4eBO+7n076iK7F8qjLt>rM#+k$><pvF##jq>xpQq7?40@DUCcM7^nt} zITK?}z?dOES;}avnZaqe^NP2@_#pS(K=-)W=jr|VM{s#D2-*{>$I4`QZ%(cH={oca zk{G(2iGlJS#-^%5y^&BZ(B9*bgg(KJ;tk!lm|!lzrjWa2Hq8%wPB+ZtvIa+v+M(~# zwy5kV$q6iDtz^MORn?pDvS1XetdS+eL*tS=co08Xd$jy!XS~D~9n1yCV@RVc*u_D+ zyNca<wS}Q<y;JY@$J=v23{QHXy&3jCdSN-44Y5_YgV{rkvQd0ct-)QhBrw1=Lz~mh z1(JXlEfR|xmTl;xmUDzUA>ML`pMZN^cuRf}p0kbPgJ|t_SVyTVpjHC7^9>RDZtMW4 zqpBKfh;4|w3=h<ftU9(aFrfo2Q2-;L+J6jamp=K{u~4{m^aHB>BXzbzZBtO%M5rCB z+J9X2z5`!@3mYZ0ZSbrOu7~4+pOMR2TsrT72~PmJyCx-I^N8B9ys9RB^o#`5b?SMW znGn(9x~aEiw?&dlXrY0#q-MZWMdWm!Av^0ZD!VO=sB)l_+{NmG#+&O=T3NjT&(95= zF!y(B^-8>l^7g}ITe;KTH=wHKC8WPP?9}CNjyeVl>(lizAVRtvOU6gK8evq7hEb7k zzy7drlb%<r4k+^Nmtkalj9bd~%cEFTzGGxUf=&mW-|;&#cDn5K1KRrXDb8dm$#s;y z4rqL}C77Jq<1iw6o%Cv{I8dZ`$!@rTvVshh49`HBm2a=;3ub>~8MQp$A;ZDahl2$l zF2lnNKBzG<aAvUUb{srGG;%c=Jp<Ur&wfbSnEESdCJEjlgvwuCp}fk;j+XZX;t(1w zbt&?BhQx{>cRM?XaY2HeC14fVPy2-Po=%?U@Bp!+5NYJTVpVna0CFCk9V-Wjc{Mbm zWl<M&;V$5}oR5sd>l~fAf5!RF+^DC?Px1IP!A1%Y^1bosF5NfmwPYOn#A8F0afqQZ z4u=R=U{Fsw77r8n-88pQ&TH)UEu%2?E4rJ3LJ-mZnh~~K_R);+CF`yBf3TR(wT`ux za-vK`;a5JJgORWv_2|_$H1O`oX{*T@Xwo<1<P1zSJHnCE(x`W<UBOLyloe!Za@<aR zn^91WA~vi%RMCf4k&IIxM2&~lN4YV*^^7iv;R0gxZLHj8aNE#Ank=FLPbce$GAwpc zGCL=kohjVIl5^zIZeb$pcYA+tIlaA)n^lgCKG%evdIhV1oEgaZn<hP4a@65*Qy;Gn zv8d4w%sl|N155@`+XWrBC#Is0Q2Jf2DdKeQ8Yj;FE~U6;;5F(l_@;gj88g!lAHq!o zZ9OqHzg5dd!umg3+r&<d!%Y}qb|FO^139Uxb<n^~`c9JBo$w&Xhnes|%9$L8n6s)l zCJ>x8+QX`96-^+a-*6LTT|<y2K)U?fw!5co+t##g+qOAv+qP}nwl!_r*ok<j-B(ek zs^fRaip<K)sbCH;w)($s3eW_l0oSZS11y-JgqUWzG2P`0b8vF^k|4@z18Z<P_p1tz z{>jm0r#q#0LDbrWar6qIPv?BBI3hmF13M2x>T0=}nG{(Kp4jiJs=pZW5&ukqy4N6w za=&v-Dtuko)-0CWg`^{Jobml~!bfqMx2?fEm1r_jX8)p?YD8jiCAo}}bi$7@m4+`T zxMD?~IXXdbJ2B{Ej@&U5wK%O;-GaW+KZ0d+;<5!&xSb*Wo`#)UQU4J(UM$Rx5VD|m zu!Dj_FtAa8UTwxe2UZ`4wavByr32z%LBsUwVR&&`su*DZ%lY*J<PBNBpQ^Kqo(4CW zca;X(Jgkc*J9AgO&lX)hVn1x!lb~&6uOu4D`&4)NgZ&%4DK5!pjHo%+)l87l3$4I| zUvP6s2GJ0xb;4Zvd<dJM=`Tua=U=Z^TZidu_KuU)f0?=5Jr8xqC^l$cD4cu2!P|9; z(-^w2B<cNo|Kh$Zdg6+1yM9{4Zool_fC3P1rFeooO)IIF+;wVgJW((h2J&3Tf1fHa zA3T!T@MdC$4n}s<#>@ve!E{NSWhV8EV;P?Op0Q8Fc>+ORoqlbW($7kCU;zFsqQjEL z@AhQ%&8?_tRk$hLsdhSqtT^{EUccZL0hjgp<=a+K0dgojP_F-{MOQ^f^uT$b;q{b^ z2!}?89~;vDDgL<!pyI-3+2yUrk9Z`jsxlpvYOLZy#UbO_&+8BW2F*=|Y+_KvSRj{x zW_oDQLK*G81&xPy5m`}@Yd}3Yc6{W$KV!QvMB+~@6_VtG2p(4Pt`=uy5`25bjnAOX zw$fFYe0LB&y64{cIp2JED_HYRi7kdQ$?q;iqo<O*N4CW4%Krq)l2>+4j(7wxlo3q} zI52Vmxy5G(BJ#as^o5R4yo({(U5kfMi5%>3G_XLY6w$!rC_92B{gl8TN;Et$kF#QD zK`5Y;mGE~JNt{o|6r-Z$=1{l5DN21BR(7`if(3t@7nDHzbuFS!+NJ8yYS8EEYgJ^} zhACcMalyUha`MMo&lZkPw=is`eL&_9y+FV0fXHfGK>Q{uc2A%z<);Nx8e5`-N%spe zdMR2YtXc8|49B88VE}{YA%}Qyd*nE~_m!i5N*aCEH)<=P+ZW*O_@UIBO3)M~)Vrw+ zu!^jh*AsOgJ6s?j8~ev<P>BzW7blAb6~imVvg6iI?a&0jy3Vu^9UfPw%3<7j0Q&N@ za5VH?b#}uWg;UdZ8NLoCXndH0`Rtvbf;_~^h}f`A)s?AglVcxi<10u#D;!!8r$*;> z*vyzVbV@3c_qj$<@s=V@2@o?H@fqu{1n$s<kKoTwzLsCT>Z>5Gy(Zms5W3fH1C!pL zPX-;SJO<gf-j;iV{2gV6pq+bLs@PCD!Cr&CRZMJ&RLCd1%+7C*ZQu~kAL(-}NU!Fl zE3|afbl_kL@<EQrJ}e88>O-{Hz$66;ggoR(K1U){myo60zxrF|Rl5NCoVH#=XsfjV zXi7@kBc<+D!*W_C#7iLrx#O*hB(1FCmYPn#(?!}e<yL<%PA0n^JrHgC-l7~I`CW$) z%EdNLXj!}e5YXe$jT*t^+)nGn6dV{|5Wc-`(RLN|g3%D(@+I34qZm=Gr_M~EXsv^5 zCLz#U=fp0`2~hBDQHK>P#uM4O;Kin0r1-_d16s}+Of>N&1Z}!NUU@o+&euH0d?=e{ zN$hE&BOvN5E84xaeJx&=;bKmQVnJu#Cq9NnxFTdif1RSH>f9<g5kXu-DU=NMp*0QS zG)RdH9rd|{CZ}_IWy~1gJxTU#iB#+sQGOpMXvBAj%0+$79N!D!I2pf4duc6l;SQXh zh>KMg5<E?oNG@NFz+Ql!e>UpS(Q|3~H(Wf7tH5gEr6S|Ed0I6zCUk5MjNA<YXHtmi z-m&7ihNVM3{>o%#aEZ{3?O<nHubfQ-^6-{AG<H;<(@2ly%kf^d;}vOTmYscm065oe zFuU(rI`R5jXZ>SzfYz+)i#5k|BxsC~IFW~dH_TsApr<G?pWp5pgfLp1T>dzeL+GB6 zNRHW!n@>5<q16aBA%>Iq(l|v|t>67_*+QMHryovTW#AfOLQqRn7WcNN{%4`MSlb*> zJ7nIfd*iyV75Z}pfy9XR*)uMQ4_SDgo?tqZ`Xz+EqCP_Ig)wqGUd8Dm_2;ze3@Lf& zY-q0xqI4j5o$*(~cP-T34z`YQe}*I2n3I3!*9j!i=CXViuaec0P)7_SYuH3xz~*!7 zDl)b(HL&q%Yo-=&^h(rt_SW13Cuo|zQ~3$php-01;9UyY$ET%-)6LN<&4Epj&a|l8 z{{53Jbq!sMYxL2u;Hs_2JmON>d&9QrP%c%MeyF8W2rg{BXuaIFISYn_PF@PssSmCc z>bd3;6>B0)bO5b%v*7ZrbR+h5sMQ#ycMW|kc9btt7?{S7)Ef)z*%uGC3udpufE6SB zr~jPxZvgZ<a8pH=5->HHpy*29qzFuci!sKvP|pvnR>n=X!ETU)gmnaGBI!KJn*Z<L zgR6s`)QbsiREy=i$)>3H*P+^NIy~#qA`^GWIQ!Cp2(fn08aTaKnm;D`j}wfJboLfZ zQ!O^PXS^X51k@1MF~AK|F=WMWBM=wBmoE3-q2F!i0=PK`>}YdJpNZ}vd1M*e{t5HB z&Sd|hXo!zuvU+G4-M2N0${}RTR<VzGLzlA(Okt(X1Z(^=pj`K|9)0ef$vj|JTi-a0 zk+c7rnhDD);2&T%AdFERe)>z9##gWSYUc-`Lca{S_l+*YFA`icLYGdh8O!=mSGje{ zSHn{&6)-De<dY`_h2{;ePG=u}1VyTYl--5V7}R2sLZoa`qxK0FK{+Yy6B7!_xo0t8 zwGL?pXbU3A@HX(@5{+Iua_I!b{hk5K-xVth=|DrU;t%vNZDN?bOwYM>tekZ&e~2e$ z$dmsioqJ;!1U98H|1?4UR?7i<62=ieI5&bLq}w8n`(Egc-;^TQ_pqELD>f6aLf5R& zhGR0Ed1$VffG`nKT#SN_1L3CF=7YNfZ1d+E3Uv2OAYj0LBl#qoPH*aAJF6RIOpGTZ zXrjN)<3(w<9vKn(Z+qyeqoX11_Pe?ii8%ZffskBe11{P$BWJd|;v!{N7s$Bu<H6I( zEnXuSx?)-q(js;emR(Rh63IRYREZb*TwxpNK0m%&=Szg$1HkIVyNi~tsD`+x(MYm| zxM`4vbU`dezUP1fe`r=LVV@{3cPU=*F`ya5g|Sk#-))_4v|fohcn<e)!M)QdTtrCH zaYls$_NuwiNY1{xEMk7{AR<hc&fuobCTYa6b%Sl<pv{7zAZj2tmq0?xzXo<s%s?}= zM^x1=GR8>m?mY$4hkG_V@rje_Tw6)Ps0#=xYKUmZd;b`qkjQ4`e?B6;|4mbA{(HSn z$FyF|{Zs_1AXbbi?x5d$3nGKayLV-idqKNMN^2PJoPs244yhsij+=NlEYyNLI(=Ye z7eV9Rj#Xh`AI|_dFQ^b0Jk+WOsZA*7u1J%IWqFu2M_JD%6#g=hB|0FZ$eIuG9b`-{ z-!!??6dE5Z(JAJf>o=0UdC($~n3DO&SWJmAG;f@ph$y!)?ZpxGO#AV}J6Bod2Ofnw z@KFvYOVO6hjw8Ovn=aCJTDi87^bC?MuHJl<O-3>$4>QY=4~t2EMy)e!kQ4$uRIcQp zgT8D)0F*)x2Lp-Zk0r9`3QQuAcR(OpLgKQtL`6CgywuiT-o#K|W)C1v=qr))QYCl# zSb2Vipm(*}i1)wHf(>ibbp(pX`vXEK>o=Ju_j;r|ntydjnLM8+Cfgo!Nu?~C#x9~> zZn=zP#t3xP|A<6et?;qBP4Yo;7mL*<HRKPdS=kruxyIdwvhHlhGWWp1C-^V~aKJIB zJi>^M7i{y`rraK4|FD`YWK<@J{9bOy3l!~uL7*ki`%Kf1CqfHyXyAdyPc>bRQMlr- z+Spx9be}cm<fiR$mA=$)&9eM?p~zfCEmU*-n{{W~1k6oER=P_njGsO@hmY@-Vx@jn znyk3%myIHYUtPe+shs=Kh^%njs<hTKR(bDqOpv@R@{ePc538t1!z3Y8N70%e8#ebN z&=hay4D@OC^NP~;QSp+GkHv~(Vb*KbJ7Oyv*SJa-<qcmLcPvB7l=os*rUGniG<SV> z0UP?H@!xagtleW^2nKoEq;FIN{n%|FrqNTw{F5Y3?pDNK`JD%^_L%3<YPkH(ZWnT1 z$1Pn^5BJidGKnB!+KnqfMi~)u2A6?_ez!eIMg(90@#f}Nb&vlMULk;Ip%Nra&x@0m z7bl}2K|xJ`f*xlN0zP(%$V@@dn}$s4sc{A3JmYsA6Jjr)*&&k|@u!>hZ?{kWwf|_f zHGMy3M^vg|#((^Mk@@T?aYO!WN80RpgywFQAOcbE-ba6w`L2d9JYDf~*<0FUmevZu z2GRuT0fGcAV1@n1e<1s_0>A(WAWHxqm|O6^PQd8D>kc5)uQ+%DYyy-%;9G{iLI5`) z2VxDu9y$*!4>u1&z&F@n37`Zp1rh<F0ek(Y&Fe$-;Q+({d=RJLn7se;IJV&9AmiZm zfy#i_;BR^QG66RrEFeuF&LE(jSf)gM*8X1GWm@qDE5JzrYjAhiJyQQ&z%Ouf@K@wK z90FMJ4-LRP;3aX|@@F?#9`_;B9hdn92-nH7J;p+}`XQwIAtYv<RnSc(!&}K9o>Oix z#d0NGBih4=uyUMsn%U~Ux_CH)$;zUpy~|s+&aO+la(yVnXOM+?0_$~@B*{_KBO^g^ zYBVddXV2_k=ke!20#CF9ik7^l5HROTQ_C2vg8WJUqlF2HF?<li;dW+C)0DQ5;kH7K z6)la?Ns`TgW0j}Ck~pJ&nqf)SxQQedwNXefr!<}tsNY<wG}K`H$)>oDS+c#T=pzyW z8E`$+auiJ*R8qx}XEz_f?|}%5IJ_#HjSfMP;YH-PDb}C71neSq%;Ahc)?1^rXcL_M zQh!Wo#6o%hLVtd5lV_Povox&(2~Om4X*@*CB1|M6MNZ2mN#5g<dcwaWyT7;$4vOl= zl}ap2wwZXnN2avQwq3o3F1e4lusl|`6`W3{d&#-TR67Z-cRrl&U{H{sBq9?qc7OVi z2Nz66l9rktqo%5k*7-H+naq~YSxcJRJ&r$Jz=BgCA|s?EC-E9m8n@ozaM*c2$BrXt zwZ_>Rdq6vv)HT%yGOBOC0flCY>BYA{$Yc@iIGQv_IVp(VDAV5#i4hZtRi?}x7N%^A z%0uxdqI|P=qN2s^X)6=Sb-}}?(d(A9&6b#^sLr<U2__a6OAvbLO~X<cZ(U5`ldyM@ zsqpVbGqF(_+*BMrB1Tly)KpWf^}!6r(9%a4hA6O7D6frG?QK!R`RdA+frJ|RD<tMT zCKzZn%^6jhEWz?-mCIR^=r$QB)-+6+6VnWJQtC={Qi`vKzE<reS=7|j%|c=8%2neK zhmlg%reh#@krG*)s9F(vOJ#f9EO&p*?c-VrZSIhB=|gELXjaoECZ~t3BH1kNIjjuE zxn!V>n|Gv*&{9wvf=dbpLM5L2&oJ?OkVM8|DOs)BU2bdEl_xZO9I^{FrYs389V|Fu zTzuwW+l^eRjvZ?t`BJ@QYRbzXVg95DWnGWa($W#<URQBDMOL+1+_xuaFO-1FEfOe_ z9#thzn&jW##)6WeqhU!0H(jgWbk^@2KG0Dft)Q7tOiH(#E@(3Vq(yz<jyHAP;4J9v zwx^pO6c;VL8o~UXEhK6@W};g|AzH<0K%9g=!C}Tw25(|U>}!IixV|Y+(_~CgwW8c+ zUC!I`>zu`V;Yu?3tvejqZn(~l4LX?MEqi<BCLBu&`r!w1NRSwJwhSKhbTk7OpR?!W zIlL0XmotBK7{8y$9w?t(D7#M5S22#?htM|1y6Rzja4;Fyn0j`pM%vB9vkWm^gROz8 zpgcIB@qS_Zy}BZy9HpzHh~SHMdY_8fvGNb4Pu3IsqAWiUgGUQkFK?>@#V8QEwEK0f z4W$+X*Vg|??0YXCI+kW|p-&f}OHE73mRg61^Y=Fb&Z@D_sKJn<UC*J{M5sj6FhUFL zi8j4v8knq|GbnRZKEtY}rf$ZpB@>JUEea7)*HwLxtS2Ttrr~TlbEpR3;(?1=xq1i` zsVxCQN|HTk3+5<7;&Dx8G4M|`i)PjDA_#w{3LHv4xe&AV*RI8rb*NeByEikw+1L*r zyB81NffJ9=*@r~F*#Nf9!WKy!nz05kn^@b%U{KJ$2yGo5I7rdo8&NIT>N;lI*fvuQ z{hlz94fA1Y0W6KytZd@LeGS_3@_F*0HZ;_m@~X$Jct01R9oHe>)A!#xxUNrnO!AVe zAC(;=xqeZSx%}gB-)|+m#}DM){rqy8)BGK8KTy7EFBbhjkC1V&-`l6NcA(<mKSk`X z>>R+~JH5RsexEP_{JZSCbvQK*>UKXbIMp}$-J$Q|kb~xxTc))YzK^A>F`D0uC$o6F z-$OCvxt^XU%$=_M9}g$Kcb_oy*B%x(leJy%8$GK(SE+WN=hJ?E7puK*S2sI5etUcQ zyS)$BUN?U7YJP3|WBAyaF?ig*2Z#7_*|vNS`|D1A@27uL<oLd-o@R6X=3T!hYd3!G zpTP3}@@r@RyiK?2VElNNe{|;T^i1yl%=wx0eYr7<3^Mbu4<UXPUi`$;{q$xN;_`jw z7JMZp8bwALIjs5{-0!h#8Tsde<Fob0GGbm&O?En=<QGSQhlH~u=3u^Z48Su>Nv(S2 zrUJDF#abLQt^CEBt^PZq5z?MZP2{nK(8SbnXR;!+mB^4*)m|n`Fy6H?5zeytRf2pE zd8GfHMt>acVZfILQM4K4q3<ajX_3Z)GO6((O%h9DMd%?(zgKlspqKJ5!jz_`$mwzX zA8zn0aLlvTr=c$zct?dgFk}Id>1`Q}1FKd!3u8+`8a>WZuxq7OHv<sr+~W*Ka1kK2 z45`fiI>lGAq@*~Q48`^=T4RD7nroWrs&_EvjEgUp{@&&#cNj+wL_vka1Q7Wn<OQ$A zKL=0=Pv-;ugJ8})l{|;M=)Cg0;ky03)H>_4hNwq-Q~2Ai*Xwn;jK&mWkndrSAsr|a z8{nD(j^?JM;!30Y-TH=u028NHcv7SEV=w(;T2Lm}m*&3(k0>1{BC8MI4rMd+pQmxR zZlxcgxsOnOJ|Qt4b|HSRMtu7)$7h(^JU_SjM}BA*_&Yo#pQ{`DlVWN(r4K8NkU62$ zrPn(be;v+x_6NyFFVfOpFG_oj=AZ69_rEVn{p`=42K`KaRc&_i&C&`VB$vR4@FsA1 zdreI~)6cT!&iWP@^?Z%r?z>gZF}hXXBGlp}_)Sy&*zfwn=~NqCYx{h?@0eoo@pjaU zuFCn{lw6eRX?lF!a<{&PB3#Yhme%HecbnDV=k%Pszvj9R^LwAVy$xBh{POejR$;g1 zl-lXy!vhPg)tikUb&-BIu~V2b-|Dh8s(JfZO`q6xD@mZzFs5VFlBwbhxK1LiTOs=L zbb_ivi$)wdI1>i8P4to_kUZ2V5n?M}%1~8rs2P)1`+aOd7Lb)3Hm~pT>86p9{xr_A zuAHC->OAO{R+-NdOU*=%hMu095iyPUq4Ybp^A>7FsD)uwImwjlBhbIqIefio$2<Aw z<xl%uR3j#tP>!lGxaI+Rd0WQl$&m)s3=s0Ja1xVrro5&$EL19Liol&t81*!He$rsa zZlp(1y~h&DJI*3O&spZg)D$qbWkZ8D7Bbk~6okM$YWjL5Vz*e%^?LV1%U*B%J!d7F z=K9}snpp};0+XXN_G939u<(2iM+Qa}_%%43&v<7Cj{*<cR@>}#%b;_^Rh_u7CaCpy z!!)(xaZ@EM&MkdiqS;3RBhvn%Fctl80-Y#cf1J$Yu3^%4RVPL)u&17H0U!6zMFt!1 zz<2|pI@XjkxYsT4HRFs3=!da1po!3SwVZ3GkOsi+kW$je?Yh?ja;P2Xu<a!r{^jnY zMXhr~Vh5&qrrDv!+=?+QBkuxfaS4xu72@y38z8gUl9xEVaQbm6YHFJN?N5JDm?ea3 z>ymnRPoTlpn5eHx;55>~qA|mYLycgM;~?Nf*6t;L?qL}Adeh_E=7)g!ccwFl_hp7C zi5!WSAqg1cNkxuEm&AE%QcyDqI^2}GO?2yv$AK+~VTbq0%28w%S!}G_pi3$Gpqt99 zC~bGcoaEvLQ7lp%e=ZYUa?GL(3%9C!eS&9Mv@gli7Z~2o#S>gUo<5I!lJYQW`o1m< z$G10A>Zq&QVku<U5++TV)9`X8JFTKrPwX%xZzDmi)6<tAyH_8<4p2Y*utmWU7EbT{ z++R*WqfjZ=yaOMk<qFu3TvHX&LJAh`9NY}C^YcUp__I70N|`3Vv_|TSVtnfx(gZ&5 zy-fpT4roGyN0=>OrHM?)D%Z6(rTy^xI=~zr&wiv6n-LKx4$>hW%cY*A{PD-AflbRr zQlS54z?vS*vB>N+c)#;0agAl`f9WsZPyN25L2XJgnm)Q))y4mL`Z#%879H}^39l9Z z^M2muK6_?a4)J4u78|zN>-+QJC)K;s{cr(=Px1}%FLk0NqGySb8c6<o3H{SAm;N}I z$tj1C5=Dncc<`c>B0sDk-24=*77Y|A&%08{SuD)94wG$x+`20bT_-uMR`U@D#6A)7 zlwamCm%L{*@&@XlQ$aeB>b*4FHYLrkMcp<2G!};%8<6(Tj$w*f8D^D-xl4ASP1&(I zWZ#LYOM3hV1E7F<;&JB_8#X&>=usQ~4I%O=8@`Vpxt}lCM9X7yY~iGr`bPhbfbp#t z&9D9Xvy<z&h7Y$2`|%N4@KyK~!tb27KWG>6V|4e;==akb3v~DL^D0k)3E`ZkT;q;~ zUd6h}W|K+w-un*b^3o-=J%O<?*Md^GX-Is{7pB+yve=zra9{l^uSV8+x2OO0uAmeD zAlJA2t2lg0PZwENlhONI>p6~m2{-xvtU``;>RgUCcgM%&vynEpRmU`~vt=$x^he_5 z8hPmUr>5QOW9SwCNoPPintG%1`4d{3tK>opSIJdjbSY?<xsyy$wDQzYuX7l`rrIYk zrmC2{f0*?{)ZPJ3%|8;~;Q|a-BXSpjaTbYfKN{GHtX*U=(4P&k{aNKQC2AAv%LctR z+9RrtgSbYuN9oUow%yco4oX>rpo?j2-EbMAO2giY4&!NacU^u;j_I#0h133JUA=cu zaw=gj$LnO||A?`mkVd~UKB%kzp`Lf+rnA5(2V@Q54x0y_2i*r=hm;4K2hb<=M<T$| z2NGcE)AkqlU;k%I8~|bg82qy)68<wMlKTJ3yQ!Tc2Mp+0e6rbV0WyGM09`P*=zWs_ zdSD)iI$V8b0jxgAH~n0r+?js1U_QUgmR>lmVZ8=(TC<tByFXV&Q0|Vv%u{w0ekRm~ zXPtBlK9)wB@AeXQr)JWh9}Dcl-AhWRZO^Z7e1F;b2x2^bMQQ@FJRG$1iV>Ajz2Ntd z`!LJYN%|B4T@-&MP$uO&+(Cp74=|TFgV{HKp#4*MZ$KFUs9*F1fPW<l5zb?BWZyhz zksU75czu%o&i?s-PksRMQXrtH0000IP-^3?N-c>ulM4g@G=l&D=>JZgOq^Zpo$c(b zo#>5C?DbrnEv)J6J%SadZ3`I?dmd05&jJWcJp7YAFJUh8d6iXI0)V=#tgWosCpK@^ z$e@g=(FhGL-+Yg85UkBklMxsxt~PVF7^?-QXB+{-W(R-A*g7gIa`uG20S1bAhrERl zON~!JW1z!D^m7_+Z)bB5=LU$j{Y$|^`3H^nO?Kzp!?_gtENs$4fvma4sOd4FY$A(b zCNf%2EPW}392;IZ?ZkTD35<vFfp)$s1hclSUcz4(vIFpr$Yu_d72v;^EM+ti5C1R` zmjOX`LO~N74;<1@nzk_H1ChSYFeSRJJVL3HXuZl1HpKG~cz|;Ir^xg2c+zM`%5g|- zHif-s>dsS%LiEX^My4dAP?lnmUeB1(DO9K_B{*+dy}VIpTQDK8VZYvGwYG*Ahbr6$ zt1ZRrrqSNmk*7EBATBd?;++Q<hj2zehzyg>B(aPzTxC!-^7K<uZTsOYtOD7b7{siu z<?MeMt!vu9RQEHLu{i!_UigkAQLU~t@Y%(O-d!G@POVa_i_S#PCSLqOu*EyasIdBq zXg3~y6WR_(aFc#Q`0tTg<aithLI40>XaK;!{XZi$u{C!3H_>W!J-badM8B8PJw@jP zATgWV7L(hSCYeZp1v1I@Ts1YQWWg^s<nnlB<eSBtm?Du0)eSgx{Fbo8uilUCY>!O| zldzq0FgL#z<ujZO*xX{&5Z<&9j6sRvCqo75b>wO3T`WqR?0%FIk(K%T6x+5n#Gls~ z%IV@;P!0IeL6vFI<kp6BoED<g-jiCo9i5z<?5-AkyBfN04$f9TUA<4wr}H6Z%&_=* z!}>9&4HggCmBYV*eZ7YfU&~Iz31|{T->>ZkBYsEviEPT4JmAA<v@#r8-oQO3!p&qk z>+vQ&_V)JDT*Ih%mbRFT38=hwR4iMz~3dl;hRSi_M!{&xcHbu?6}i99EPnLKh= z<F|5+CAvt0TJ~Vj`WtmrFEd*4{Zi}=Cb-*mE(uj+k4qdD);@G#JXOV(<@NZJg~P8& ztKT8^GPeox3Rf^gT7=O)4lMD1%U6Z98+SuqXCl(f8tCn=EEc*ekAjfXVpHJBq&?)a zfV>mE_mWN|=8(U#k35D6?>$!B&{%0~j3scg>HbVbuwGMslMmHh6P_`sQ|8eB0Y^Ne zE`uVyL^-Gk;Ehb|hj{x=SA$6;W}21!KmbyZ)xKB8=UayIkgSqSM`4<!NjnJ_i_qWS zWA@1GSo&p7-jZXP@ERF(+Ee2(p3X3x^0=KJA9}i+YXo8x;1w{0-N4RG2|em38#!F& zJQwQSNCwf}hIX&}Yt1@FJxGne8sFhJ1J+$XzGo)4rEL>Eg}dO#NR^m|l3bSw@e<N} zE0~hV3J6i1CCwgaJJ6-SOt=}A$q{Q|MHgW>T9&?y`#@CO;)baJt(QXeNS&7J^~(0; zzs@#>148&EOyyrb{L7#y@?%JiFBfMymId6Z_Zf{73q(KM8;?;*%6WlcAbNuI=Iwxh zm#wX_ogmoO(`dx-phAb6cqwrg3|{55lwxIceIV-q5~f)pCz!L8)A$uL*$588mPxcT z(Lumi`!v}JZLN!cV9y0M19=-^Bys0j<xDL>oWiD$_<*%0Qj7pbM*{USA*=OVs#j82 z>BlF{Y?XD9=^0;iY<H`f<20V+3YMegU;Bb2<&P;|&J6UbUXX1w&C{ija=(!ZtmsG| z4~#z<)mwK%iB~BPY6|v>@9`{tJ{S?%7r!*yO?Uj;R?POdD8}sNI}CAA&`^%hlkaFC zjdN<(NBii&F-{`a(!zC3YL|YBFy842?uacz@IJ#z67zzId|06E^1>T5=!bMj2kgU^ zfTQisTKuOPBzT>d^#(rE-}tqt^2#gb&8n`Z*rK-@kE+UDQPtf+XhQI=EKfArI9?mo z8OlI0K_xw8PM{5{0&KL#$eg1FF_;yC09`-?1mU@I67^shgzv;FZxq$m0AA0;A;#yc z11ej9`Px`{!juWRmw!DmbjPrjz`z}lIV8c=vFYqqbAtc$cQhV8;wc~r_IGUoo6#FA zM&AkW%)fvx8s|zReKGB9|6;ipv?&G-DW0`<j4``@C8;qvI?MJydCYrnq(NRnJ06XF z5JY!;8`B~332Qy3iwkBbmcLgn+`ZP*Qw<LCRNlXkO)j){fLh_`$6G<E9q*e!wfebw zeNCc4JGfBstxE2<0-ae#f!&C;M(dcqrt`KUW~*47dNPbISE@Beimkcfbzf9zL*4t4 zhbKr(%iZ$!p*YZ5q}BDJrf<Et=>hEvmtwDy`kFoYZmy;GIC!HZTp2YI*U+9W#)sNu zRn|2$Cv#BZb%MnpmGX5hJmiRVoj4`M)1%qY_yYU8-QYZsnDz%&I54&Z4}VdkVvVNP zm)Qkfd)|Gb52o;Rfygj8Knf7f=(zhZirTgYc*v}IXo*v?bKI1tmlipB(l7$P`(=&P zmey?YXUr7(rmIjeow$hHDhN9krmI=i0Qz-d57B*s2*tkzSS^>IdqNDJi;Ne?0@=_n z`yxUV4uRas;SnrfKm6BN5s-(xaG5&&3$?gIHV6l?h`}xy$DckTD-%CIU$-R;=hyJN zcst!ayulldLtz2PXmuS1N3>)~KJ0m{4MJcF?fLY7tS=l+&0V9Hd=GzZFv(`5Yz?ru z-C^U8+J``d3p+WpxMNK~+gB&<H3P#6q=t=!#v0)^On5v2nwJ3-B`E2Wuz*0`B3W8J z(tdV<hrx%_sdfmt-o{chjL}*k!r9v0!S%?KS&V#*zJ7+%4PkB1i0b|k=y;$_1CJTq z0U%$kVj{>C+_>0UW{l{%*0SkC>>hFy3dLIDZCA!w3-;H3-;3D3!$nl?>NJ;I{1ASZ zE@FfLjl1-RIY(FjhJ+qKiI;EVZDOY$qhsn17aWDrkDmlwRZ80ZH;^g{jXbg-hAb{} zn{t6$5_^;R<ycsrOh*Xzud3$SO$2;CfB-q#v0A^riju3KQH^f;fF4&K6@VrR&L4ry zdZ!7x9S_08v$9c85`3&UYUDbTELSko_{=rn6prp&V*S?GEzL<9?3v1v1G_%wE%_!M zA9NJ8X%2cFgBd#E)-8X27XQv>4C*J*_}Dx1fYddt`<CV#=)XbRBn`^U2NM9$Qv?7o z{s*)zoQ&*TO&mS`!FIRyw&UjShMp58X+aENROpCCevB<e*Y1XHhhYcpdPP1hDq5&O zVQ3^sea1ZFnn{%tLPw7r+uXy)*-zj+8nZ+dQgo=P$Hzx!zwO1vLW+o->kiLM7g0LZ z;E4<F^=r{?bi3zm8J%#O?u}%{@G8x4vPru}IPdUP7wQNqdbbLHHc`?JoPV5yjuwp@ zE{{~1Fx<bomDS~rwXn{rEs11VGWtB`F2v~?8%wZ5{if>@dCw}!ZtYbQja`i8-^x#_ z1M(WJR>l6R+@xxa<A=&371MH))_OM`=44Fzy~!SGARpD%n&rmJ20v5M#TFO2c|dWq zT*eiX5zu76oeRSI2-O;7hMiD>7(jj8(0B-a%i?VVwXIE5fyy;$NTm!()qW!iy%r$8 zus19;2xqXkn1YRX=GtT`&gcsP`zpS_?DGHY_WFJ6y&|0U%0*V3^4dI?@K<S<>wQ=0 z0q2@MQh0Z5v$x{B5Rq`?4iap8=dgW%(6)H#W*NY+_jxC~tb6MSR9^dtQ8$H{Jfxai zld7_o38=WW)%9mU$Ki)5yD(|>=drJ6!>X>+#^kTA2!OjNnZ89Utm-MW@DlRT^o0h$ zK=o73B`M}O@*{5(ULB?UZlJP@ELjvXgzAq2!5UV%f<dOCdQ%xbJmwBBFlVA{k=Y(F zbZxjg?@&G#tR}l?*@<ugg9Mc-!M~{WC?V<HO?q1B8k+rV8t=$#sH5NMQ}dm_!f9gp z;vsvc`}sb8`#i`z!PxEb{%WP<^;A8?_49;^GLh=Tdx0Yv+|>=BeJH(Y06)7=y}@C* zt~#_!?Hqaht`9s(9Fq0?XE7I-uXuwqH;#bZM5m@4LMr>>|CgC@_d%a4o#wQ;!l1X3 zxs!?d!&)nd<gd*xrXWq`gc`tMhF${*EFsuO#qXiAJ$gE{Sv}aw3r;6u>&TJ5$C)ef z=)bw7Dt_b`-ao^Yge+->H{mSQK#7%f?F{L_{?2(5C?n@dmsWM8J>El%Snir=Vfy`S z7Puxibhc^;#gcX%@7`W+De@h$0b^a;gl3F(08YdZ4GuXasnd|%+$XD*4;km%0qW9F zNNSO<kJKkx1+zX<r;T#UC>j11SrF8Ie_Gb{`e8SWtM5)GnFilMod>X?Vny?yZiIKB zoSi@h8>-sIFbR)xxsr|Opn54#M<HbyF0cfwix1B?4iHVko~b72<TpJkO@jFl)LWE= zC)2DdIT&WlfQoaaYxwuCo^5pno9G0zENbpdbVp1_4wXhZ)g>7Ww@R~UBgr*rG{^F4 zMb}TFrprMF?}Ky<#U<JcL>uKYQ?OwrJgp)q%+~Dc1u*v4nwuPY!E>#2QklWfb@0|t z=DCz?hp40AngstmE_ast`EmPw^JCQddOv%Qkj?&1DLG>m$7~AIKYEKS<?reE6p^xg z$1t>}2I^E(rQxu*Hp@=6wCok2n3uGn5IE-Gb-g+CiV!kIpBihiU|1Cor6P`wk&7vv z;t$7Dh~43Q`$OV8cVP<$ggVlOr;Py#XA@^m3a#3Z5M8AjHV%jm!3*{vF>cyb6iQn) z`NdOXWv`<zf*I@)bDnnWmnBOB_XSGKL?Sjb-Q3$t*;kIKrOag2f1p}^_0@oKUb2%+ z?b&UW(ExxQr=XbH)GS{F2gaO>wjntnN-lrB3sozv*i2<2ym=reS2ugWP7FW}3LQgh zi*B*q01haq>K`ksmG?@!@$zHxgtFk;TR-A=LwrM~Fkh<tN5x9?c@hE+{7-vnkq+?G zHI6i_h!n4{kH6rF6;XL>!Zhm2IdoTDpp7kvJP9-nnzcGibd)-cq-aJM;2hHM{t(PD zp!jKOp5bMr*dEYMV^iQ#=VPZ6i`16D7MikASKIwQB?HG-6j<S*;=os}l|!=kF3e(8 z4j2$mf;{&}X$)S^b=Aip<=EUWDCr@Tc{hb2Gv^D~_n$B2#XK7%(99Et`s|l=(pGU? z+2{7W8HQ#|bCqsMbU)SiZ9<5Wi!%=M+H+vZMR;0FxL}nayIwSSeJJr?!_ePZ%Fn{H zIwz3fCwyIqk2&FK0RHT|=<u@0`(2aMYO}35dKbc)wJlb)Exr&5VjS#{_)AQ{iWtb- zLn~!2Gc-^XHs-MR7*$wQ2`PK(WSTEDIx1_n@TaG5Dk)qkjX0FFAJo7R+;6;@?b5i| zjMIvjOh2eN1YDw;X3L?{+1dJW3i3h;m3RuiRRTIRr0$xJ+KyKy=e$Z#L%H?*6IqC! z9&aF**g=8ai%2AI@y^gt1YVEgP9Cb=hRZe)Je!fNAm`-q-qIDfYh`xtYWa!8{SUK$ z>sVtxBTm|kCqyl_>jjzqS2<n9+6*t&qs37k3=h#m%V852EO#cu$yP$Z%-*#l7LK7L zn^F{G!g$_Gyt|hcOHSpLrp3TLY=MimQOs)e46Jw`AFw%$>n)_`S|~$R)rA(T7;5&# z&bRktp)rN<r(hagMfNX~bRXWMjHyT7!=DGt$oFC>D~{UWEX$*4d{Z;Mv4si!sL~S+ z7~N_MH?%8t%Fh!X3|Jvf3JqX;hXRTHn9+wPyxfb^KX^xfC4z*Wy24-R;B<X^AbXP= z<^xdg!2<#m0)UCbq%FQ%*YU7+4rZ?Mz<-6S_~<zx0I0SM(M*39frTQy@=7&yivL_2 z7a(d08e=8;Fo;mW5<T$!jyX+gJ<EcANP7O4ZbjfPHOruNWR@St;Nd+r&k)W3@w&Vj zgbocv123KR^u8uVgiCHK{C@nFx$F02a+)1zr}>1(fA@AWt33<MxXkp7EBX@pN$Ly1 zT0`g`qE9<T_MoX-fSX~1Ich*op7%sf&Y<06m3(=oX2<@i=NtmL-)3vho#qF<dXt03 z!4;4knSh6!R`jghbHkITTDN+-r@%8NyT>7c;Mh+yG8b<#`e_9kFhaX7%)0Fau!Nvw z%DJ;D;W~scJ*zalB=wZ9j2+@0AJ+zFMHGrWOH>6O%Y=g|L1E|^0BzXwW?&P;W4-wW z31B_kRzkKMT=#J8(gmhUIU_?$%i{to4UIUPx&-s~69svawlVkBr1L#ICLp3G!g%^U zS#aN5bKdo$^3-#4Nw?-#KV1P%xa6lg{;}ufo2Y`Lv4ZnsK(4a-gZH>Wc=)Kb9xA9b zZiYr28)%vp2#=>A$$*(hJ@NgLCn)TWB<={2SuLP0I>yo#+v(qWYX!3@JBN%~%fArM z5sdGUUakcsi#gy$Iy0o_z|fyA?R_HyhArfGsjlqS+&Uk*vX1PMpf`}(GR9l(-#m+k zS#<sR49xf3{+cs0ITE5X5c6i5+1wf+J~g<*G|m<}J+s!Bw=dI5`|uv~*4{^esXWDB zIH&ESRHfQ*Z*zGmqqSvlXw42v*s6B+`TnmpKEA3o6D;$Lff~JY%ITMIQ+Pf!I3-s= zn7w`nNqE2yeo?|zc9R2IDN>f+YjDghqi-Av`iY>{$bA~H2|1VcF0hjpfZzbZ&-))2 z4f^<S?8;1!N=zI_+@PkX`;xGLik7K{cucXSI5J;;?ka`WKHubqr}*1Ch*wP7`q{je z)gg%y;ojJlHzYJ5_odhT*Dtzih)_@Ni+*LD>QVVK!6Z+T$45rPsWz`;?OwCYCwrII zG9bI)J|x4Z3V3%@eawJAqgrpvS}r~=@p^yGov-L_M)H8c(p2Eh_ei~S!y_9b>3a~R zV6+1s04hf-v%bLO3O^-n$OYgY7Lgbw8GD3nd15*7ZZ1xm1IKww-Mm)0ZDF$n^I45_ z_4Qy(#&tGz&;W*?sPfeP8i5m%jf1d3IZD!63x?2*!<s3M)dLs@v|=Q&AlKLOGGrS| zV>6bqX4VE6s%Ur9bGoj*b{e^SUVZhD&_Qh(LGqaEOPD{UQ>b?S$u~eJ0yCa|n2X`R z)buf#%rb)L>ihgvuh4QzmuO2Ns6Fj4_V?-&@l~fq4)GsEzl15Qr6f>R$*cuVWJx|S zu&iCZ==1UMlz(|v+eU&LU9`{BE>6|gP$FJP)Ma{U7;Lan4==LQGxjXeW~=MSMD>>9 zFpPW<aqA0;rSPf6;&dkCOp$qgb+No(bZjqB5j&OEsGj5`V80Wfl60;2*%}8cd>ig7 zXwpzHg1B2#jwC?^{HVG=hDmmSR`-gb-+RLJ)T^UAbA_;hY4-!aLx87oY`n}kqr(7u zhY{)X5SaIzTud9r7ae52<4I$|D)thf29+ck%u-CB+CbB4NUz*6-iF8;LNE`W7q!e3 zA2w0rcLq5wK-5hYr~kQzL3rjB%op%r*kP4No0W|RgbX9R8dcF?$r<A*tCjNj^*a%* zyLy#Mf|B@iRSAS?1?e***wWiEM1!%Z%Bw!`QP<srM1rDMOotBu?*{a7ZkBXVI;$6Q zcnG<oj<%1mTlJL_23JCRsjlS;fBdn|e5Kg?bwT@z$-<)!s^aq3oj3k$H7{eIP1)&r z|F3~AFE&JMtHFCa4|!Qyf>eIcoieOVDo*go2g{I7wXvZV1u{iy*OlhR7|`56$-0NV zG6zAl17_)DwCo3D_;F)VV0Hmlag#LwEW3tTo#?c-QD?pWNFF^Hexgmg0@<<qxPcJ# z6TPX3x<xUy9LwsoozTvj6f?8CpWdpfcCaE8EroTC%p8`%r}GXvjs`bX=x=tVWS@)? zDJZTvuv(W;8&#it6yC&=X5Y$-;B~z@O{JqpA2Op(M3aMOQ%e(x!(OC*8{!d!7?j+N zWmuiV7*2XMgGPO@357m12{UU!Qz9OwfWGQ=@^<VL=R6XE3d5a8>6e5+b{Upol87Wl zr)23h^y9u#*s9qS*I|xP;*CLNB8E<T?k2H{Qahu*=WnmlJC<|9{8bflZ-Zeid5xPc zwK7jBS&K<9_MxwIcpxcP(f$JXkx|8xec{eJACi_NA>>mCLkQY$DL6Ut`+U;HTU3P9 zDG2Ifr*9D^b4!ln6)(S6;j7V-V!eR4#u}^bq>?W3Mtd{|t~ofYt}Cp5{vj=GGMi21 zEb5Bwmi5vaT{r>8+`prbhDix}NX~skd|Ja%Qdp~N@yq90FOh%d=aLZKxOpBc$|DA> zt!949am8Q)PdmU@VefyX$vLfr@SAi?s5!Q824$dh*9143LO1Xz!RsIpR9Mf4*dJ1m zFaxh!Ea{=fwj+HtPnr~2uTW#D=x_cq3ZG9A8>qx&6Xo4QdDsL7`ISAl{4Kf<RioAi z!d-E_?-2iLzsLA>AvZR{07BBqavDrnwaBJv>_%ejxaKB$T!;BLad-fNk^hym70vb; zE6uQRbxl`o6gL#<qwc(3jNIm&EJpt&mLuN2D~yn>qfFPQleTNeCKYirRU@tOKAj1H ztY?@I+k-eZ#AauQX6eqQiD6;Un?_%PD-Gi{a8aqB`j6*lKhEF6RIoo+Y``t43b2@% zvnX?TKK6StMWyek3D2MT8H%>Z+#Tqc8Xt<K2L%G-z>`q%KUtL?_Q2z1=1~ii$+?bb z_#sVv@QZ=G_<V*z2<EM!j%~a+<<}2M<^eeH_U8uuFyH#GDJt)(q9BGND#3fKb-|Ss z9V0pg7*@}$jd?occ`LY=yulMIU3R#GOj3uqYx#<u)$r-Xojdu|&U_x(fBZggxBlK8 zd0L~7aHFg!eNDCnxoce|ySol5DQvaDg#e24xhW%u-Qzx>C>+iqE&FVMsUfGmu}`0W zy9QCP_$E9O_TjoLUdNu1=SG9ut|I^kl;HaNkCKnc*u{ix_e)e7Tmfw^72Nd#1qLdq zq%9331ly)2dvd2H&Z;12z4t#B?3-47?7)bB!F~qh{BSz|D%it3o3EqCLlEd;{|19h zYVW(~`zH*E@1m<aOrW0zV_KIg7dH&>nrq#ZwZLYLrby~E@{|grY#cK)_#eM%1+y)3 zUgsf_H5oF4<Nb_3$LvMEl0O_T3{8m!AzvWRXIzFj!n!g_h`P7~=^BR924v5mpoA-- z1n+4&$mv(_*j_}e^%c6&F%1xzceMui(5iTgLENjmtR@seQM`2s!!eNyBdQNB^~a!~ z2AAZG#8cKe`Z2<1c=(GFL$e_tVTIojZis^<rr}0@3qeCTJ1un}C?lD3!yWIN&M!}A z$#K+S+QGE2o%{hF{o^YQ;df_$c(~f+)9p~P1ph3q!t2Jy(CWr#H2HuUJDN6TZy;}2 zb0(+&A#o2udIhro3UxGC@a<xMrGSi03_P%q3qNLAl}O(r7RA|Y%Hm|Et>ge>c(#iK z97bt^miZk1s>uWO#ez$OhGv`1?R8QWq;H{el4u~6x+sSQw6)Enh?H5hSiH&?P`%Mt zPy<BS!(4X~^UX)_fgjvztgLaBKPv6b@bH=zl0<J6uh1|vKGoR`OVL|-%^V@#-j;UZ zLYwyT-2EJZ6Tp7uF^~x1ug?{7<pAVBbSts9+3ai!JZGVl@s4fg?tpowf!{|2$=;US zF2YN?;YlCGv%e18<Hx{6*76#7m6WAquvOOSTOA8)wr`wMgqnPf9e<-dx{4yR;TC{y zE~NeF%n}<6U&(2d4>OIv-*aA><Sj$?xkqn)*SWN7q@;gI&QF15s6@<CQ@K>?^f$ot z6cm1&VMscBCR1L6+?JMT*6ln|AgQtxLVXx*V(G>8br8>Y3Ea>~hVj(zAl)-=1~&&! z*YoJr%vapMk{nIv-&1=OTA)(y-I1_tNahOnN!##^C>uO|lC{JnFZz8*BbTwUTe$G5 z|5xWAlM_=4lLLP)r?e?P)S6xzP0NmG02>CX&Cpmd_|)m>>Tb{X_x1&aGSOGcLIH7` z+!=Gxw|s^5<>%^T*gVUO7_(uLao>wmi+Sfsg_cr{2Lb1?=R&X+Mqkt+B781z)L7<Z zBoFyLBwjT++iF&*8&GcVEW^JqRH`nTIoICE<==4dT)@IpF|pG_F{KA<>(>r;f5uW9 zXB05r&nyc}?llBHsJg-ej;fcih_#&U9%+$IPJB+#sYbXwCo#7=AuPL~bCClx2|fQk zB>gTab4tBS#tFjDn;Ke?_cQo~KEHd$bbVNOlum1H$P1xa)|{9C|Gx1vD|ZmGLqdtM zU*@ZL1lVEbEtp)!bD#|%w)2OIO8j=aBvW8q3mByGdp(VnvS>X{Ap)1ZxI@v}up4<O zlOE15t5f$P8T9ygcj)IP^Wogj^W{+Vftwd{h7<DdnB9oDJ==rCl%Z5P^}!IX|J`UH zFm5HvstDnV=31_k$DxWXx~wkVhbqzTrGE<gX?6FhEykzk_w|$?Ut0i+BCgTlUEt?u z(o_1Dc$z`(<dTJ}$Dgo-{4>6o{GB}E9F5O@28S{OT;b0v^$DSQKyO|Q!Bmo;IIfu( z`Ysjy8I9x0;5MLqM<1jEil4ez+?&qaOq$vdD8r@8AL;P2Mb&=LV&ERbe%U_KG`SIT z!M{2WL3Qz-cFv?hcR$b+yloLIX`Q=h0B~@lf`0u8ceT_svhI|(Su5k$(&+FZ275xg ztBRktz6<5&(;$ge!^T@JhyGd^uDv$ukaj8syt}k5&84dGXd5XFhH?}rz3XD@trJIY zM$_Fz3mp6{Zd=tfG}33e%V%0kd<!K#u8nL1PA}(moi~Y06sGIfZoR9KjrIb*08*?x zfgiwMagoKCuCD?H_U!;K$Gs68Zdnf(C=N%dlDIx&d2XfBd4q9K@eU{+|6+)D@}$EL zTekUB6G-uD>V`viS#*U3?p85ia(Gme7LsJ^#oRh?hGOFV+q8O-U1Pm};Ysa(;3|x< z*?v20yX8GwmGC{su05@PlfU@1m^Y979M<|Q;fFf~$KlgGLKCJD?dwD?LSwevD)yDg z*n=0d?KR^xWTPs&%FoWA+>hS<VXd%d<>j_txBPnNAE^~eXEVmk+BE#pJJ+$7+)VkP zruS(Dt`wR4X{KrW8lvHjJiS`z5)J~&+-mD)^9`(igQ#xT$P3HU#xn1k8<+%i#V0Z^ zEy5AqD3o2V7sVHNs6=ZgJleZ1mFii@ynVpI3-gg{^I|6O^~#L3e(eXM>WhT`c&B!9 zq~INg{|%>3*g*qVosQiB#QStT<0KECIRCB1vl2#$+<!c-?9GW*`p=-pja<vHY7n90 z?C{#6`aElTC>SNH668w}6CTpOW3d74j(ugRs{K-Ey~@SIhyWzuRlj$5HF4v^8-jt5 z^LKGqQm6#F<Ji$0)u%&(dy+wxL*Of@JPpm?g_)QXyTZ{amzW~bhk@wyN3g1XL8CQV zJ`@37sCTi+QKxHENnBaoua1N?<?GEi?*fH^Fz0R=>Sbgd3~Am4`L|q3Wo+UP#D6Om zw`dQ<ee?i8OalOb{QndS=YL|wk<W+I=Ggq+%{w(>hc>`XVr@r^PC-)Z<Tbvm!8hw_ znygr*ACWT&G5(+AK}t>M=lAhsm4hjNf9;#v!L7PZ6p)_tf9pD@fMWHcKs+WP@zG-W z$;PGSqOwF*4gtPmy2aw7$nvrEx@1vLtGJi-c->`vMa9R~ceQgm-Ew-C)E{E)f=-Y9 zWH2;xWWYJcHf1pMl@?sTk@DiGzru!X#^{rO9`|&!htn#<Mcur7#`UCQY0=E@d!ODQ zTt$Q4Ho|F{eNz|Xa<k!j#iTaEMJaa>rpCF)cE&j#+7DCm8G6HRC4{8=eNM0SDCL4S z0~^1JTB&o>rnUN<%XfFzI-u))`^A5Q#-n+7o@%x6usSgJ=KJkk<L<C_Hs|x|wb<D} z>lp)nZ1wg*ptV)E5^Uw>akE%6xznY$3Vi{inUeO6&0o@^2HIPxs-l?-vb<=c#R9IW z^qupc=&Cn!snqA*S{(XMlGmaAzFk%eK1V-NWnVLpDKLfyRkEpuv6~z=@qkzEDAr!2 zQ>jb=L&c;_xAVt`VK(eIsHySYDHqZKGNM+Q%^Pm1t#b?1)U}rgJ;Yf~oot|Yf%^Ka zws<HHG|)|gJQmCO4_W85C0MX!(X?&bwr$(CZQHhO+qUhjv~5&6yY5@x?k_k`d&G`7 zYt1RrTvCzkrd(I;pAMtj98$^Rb0`n^sl)D}yE=W^MV(N)|F_^QyR1)zy^H1EtFb!J z7Y*GC04b|VJ=IXmt5E~+&sMhW))(|fl|9>)AT7qBC~ymNEDs@r{L4|}!|d$9WfTX1 z1bTjnXtm$%ka^YZR<_ZWit8RAuKEuRCy&IwaV9T1-TJEj{d{n+kXRc<lM8&1XS-^& zl`5d$#q(Th3Ae)0J^-1alE=zC+LhhZKk8BTQM%1zi{xdQJQ~4h@=wua(rR59CGSBb z+i?wLpd}!B2Hdb(iLX!LdmF-WlU%KO(AX(d8VrTXtFQFDxg=Jay!qsGnc6l%0`4V1 z&|8Ed28R;gZ+A<wUn;*;c^OR5yzst)t@DW+s2}4c5rZ3RbWF^M)ee5qb3WPA-90@q zL#E8`y^P#0k3Unm7UZfR8+SM0K=vtAf4yqwNdG!I0X!E5%POgw(Yh~O0K|S*kQgBI zch6Q`bsnBs7?icD`Ljh94lZdt4P^=b^X>70W#8DUN4Dot>W@nKdw)Q3vyFnCSsJp& zT-t(<nY8nPczC(;n+2M6p*F$Ts@Eiv?{cpB{T)Ll#5^$kqO~+v?{>~WuyT0BiPC)X zF_2$H8a39CPU=<e5aHFF{P}DpS$Gep)Dphl&&^3SzJ3{S6v23hNC8#iKh4~){goV0 z6Dwu=){E?fNpM^oqPjxH#}2*>bba|;a6)@!0DpmX#!J3DzzSIelsjoKL5LGL3(5j! zSIIS!&33uycyV6wzqTi)AOuJ-9fZ{R#g172Q&$hI{hBN%*R`?m4FhQ*xj~cV?OYE< zd=QYJQ~ItC+Az~l`dJD8Kj><`a{MhWgtI9MxGX^uCn>6Y7PF2CY;7U@MzVt7G{p1Z zARi-^lzvXJSlWCm4S%i{fotdH{1IiEL@riaD{tyGmc=D);JhKlhxU~l_kzzK>`HI? zPBqC*Dw0(!Quod)dV`59FW+SC^G6qY1G=L_5GkRZVg69oSp{wYXtk_605>_(qXAfy z{zzSK=;LU!;#2K?p!m31S6Subwacz!9H}mZwN;^2U5;zVL}-H&kIP3qyQHWGMBLC5 z70KD08J`ye0BsSfsVZ%h$h%i6g5_atEUrJqA%3{zS9N6tDf+{4rP9e&W0`mbCHi;a z)&Vk_w3ADj>|EL#6LkjDhJ!F_NC8FCoi&Xb>AK@sce`C}Id*S)j~|;?$5-NeB+e)v zxrd--#gSPR@Bkp)Uljf&mW)IrM8a<n;S2>R*KlsC)vv{s(4klq*Vc7aC$y=qg$+*5 zYpm9*drDg=NtaeTl@D|ng9yToZ%d+qyKrRew3wfaDM`*WmTc6x5gV;k3X>wSBXp+E zfBkQ&MoBMVrmJr39T=<AT8JeBl9SqJ?m8T4@Hc3edd2mB9}I5+hbjTEXq`X?8eBTl zd%RzsR}CM<0Nv?OY@9!%kA1b(2IT$6Q<H6AHcQmjYYL90V7nxoYtxc1yusx<gKRNr z7S&U`#!QcP)&1X&);lQ?u6vE{EArPHE=kM<hNVYP)gM>kPyiQ1U?|Q3=z34IuCTn6 zguu%SR>3cU5kB-D&zge40&ME-4IV0z>!0jr*)YNnx<YRxb=n8!R%ho=3?Gl<;qedX z6XFHTH!5w~tX~Kx@qC#_$LHgJ9}Y9iKH?z~?)|^p`)A_y`TRqP+bBOnT9W!O6~(Tt z<hN0Gq@zF@JeFtX1*B#*b{tRX+7gv3ZJheKWp3U1SCfzZ4%5&)=xUxr)r@}Z*h&O$ zWE3*w!ddl-cA1(jit&<1p|}uSHJ6!bRYMzbsW_qoR_RJ}ZtB((WZ-QkGEJ4l*;gZ+ zv?JbloYKZ=zN;4@41kuK_?&n7R-u33?fc|$K?^Wad}gW=icw(qqQs1+P>K#ZNcAyr z!KXE2&1+IZF|EYA!V&;SBd_Tf=mL}J3t~u_&?r36KFnagE^p;cQe@tv&bs^cp~Ghf zfv6$<)WVr?2;*^{0QfNu!tO+Cv);`XWvpazg(5KHSojD+^zfgX>A)MZ>9XTmp0lE@ z>N@sj4gQoeT;O0VWfl7e$PI#lFAIJv%@ds$`LQfL?zI##F_V@Os*5thW`u8|xSNuf zrvW{Jb=ynDx~gBXGApmB#zE1=P!ri!1`x^DupL1FilZ|H4Onn`AM`F-g#*jdzh-$D zyXsrl4p&yY25w#UF>!?}Z=OTRk=Jx`AtIjzO~~Yao@(=Up_`szfws4(p{iA4VFK)Y zbJE*kWfpXaFWUS6ddt(os6GkJIEeZ;<7O+!+djM_)A9L(kGg((8_M;b{`1bf6xvIN zFD6Jl&*X+b6g65(ke<yqkQj)v+8N3wB0Zf|l*}4Y;mM-VriO82QRfA@$K^onj;LSd zUw-1&tr%L$w-j-}LLXP@xm8RM#!Rl1C+rP@tS-P|h^#`V)DDzNfRaR<mq$alcAyCR zc!E_eCe6)hEOk$b-O&wONu!~v5k8uGMBHP|BW#?ziTutZtsulXFlLaR**0(Cy;Flr z0EdbfE{L|ydUj~G{x&FV@l7Ud9vjSDRy7|x&WksmvJWnXTPU}*cDj)-xe|k0XNtE^ zezR>}8_2ts$+IV5HPo<8?`Yu?@d}I-3qf_+yTNhn*_W4Cbe1p?lsj1wshrlK>EymU z#>^E^1Ochm+6i>hcw2+ex*ln0TPN=pYzv<-sUcbuXfK}^TS0;7-K9}&t~za;4FovV z$j-V8u=5-X3%MLrs47%kNgGtlh;eHx$5$j?xPVZ%s$nA_GEBEzAjm3iHw$7{(qzcw z9lMLiE&k=7CC;j%j{Q1g29@va+S*M;ci>w@jLta;Y7n|yEK_tA*+D%mm9E$3Sg2%U zl>#aVGurfY$Cx4uNgQq}Gxb*&7=@t%GrEXFDU<8&Lvzsq(W0eFgPa#lS}2Q;I5Pn_ znl@n~K#PHegWW$xZ69t1HCp4XgWSS|k!#fh0xk5|%?iGznN^nObH@F%Ii+4Qg|T>l z)ai9^=P40{kKgYZc~&35EO$@}v{N~X%OYpKgTFki2{bZv3kw)2<p+_K9Yo8N&}=Ix zeDb8A<zz@8keo3C=34k~<rFGLgla0~&0x8s!%?Ai1|so@U<17*z#paBz<BG;004GD z&8xrW;yesH>2e|iel5Ow5FittJ<G1glY2s#&@N4i?%Q(<hsWWTigQctvBInP0PL!A z`3_dA6~GHpxxxb>Xz9z<f6jj4eP?CYm~kDqVU<ST;}BXa@`Zy_mKV4m@=(VdENxZF zu$iLe9&_o-xJQFa0vpRE25;OI>aB73lg{=sCUN{}4tbzY<)Yj#T}d3Yhz{P~a3kyF zyXYc?4_2rG6DBWhiGaSbGncweWSk%;Led-WT@cF(NHYk6-ZbLHay&Qj8MI4kLUt@- z4udIpOqj@(-PBvsj7*iv?R2Ja9LMeelwoc9HI9vWB{E3g{nb%M*H@4qJ~*Q*d+b_t zSzTpobxEYoE5rAgE-(3-xbUg_Y01?&>`>I04`~EbKjL_t5ab)e%a>?;xjcQhR=8HD zIA90#yon{j&%O|E*sc#F*)oaR1U>U<b6IV94*GZVW3wAAwczZeE0`bNe8M6g=Za<! z1_d+PA6^OeKF??5HJ}bI-dI$1N|2Ho6aV5<cQU@gxlJ}n%jx*}VgduA@)tGUud&)N zGqe<kn^_71Gpc~RuR_}~o{uoF%6Wlpm8pO9lMG|-!Oyb+^TFpZTF$&^S2G|<t6MMI zmbH3;hg!$u$m=bjlQq#5us}z|SIjWXs32d=m7LhPc@kdBR=iyt(LHbH$L(Nd2%{f1 zg8`u*F)bxFB0@<$32y!NJBXD|@;AkYWQA{ZZE4=j1;|z8SH9JNY+Nc`S>~wUKz~ek zS(hoHs0YzGbb9ZyegX5Q?J&-uB}u|cnZ0lOrwcJpB+Ox9{&&Qo(=OV5EhdMn;@>Z- z#jlZXTbG6&Gp9#?%(yw`k6@I}YOms=PXQJFXuI&RY;BTT1-F9fC0(t&4Kc7_+z2^E zb7+?PuOQ9?3$xj&y~YB-pzQ%kc;~bUk3EE?TrPBm*7*fEJ}pu_0@LTAipvP{^l8z} zL$P{s_*J_@r#qH?-|cigpw?rNwW_&b+Lq;$X$K1a;_(nF8|e!074Pe2!a(!VH;Jy` z=pUNS9It&LX5A5|gs8TgwsbF+z#s8WE1$Wg&5;vMPescqSc)~Og{zNI(X}#uUH{DQ zl;PiH`g@NcYdQauxa>8hUL#JONAliiv1yD>LlL*_cN`YajjbU)HiO3RE!#ofZ7qBp zlsw*JihJqTU=gQw8nrU!^by}I&--hUS1m$zK*!K>M!~_w$jso+5xq~1cic^+d)kQ& zXcLoeDFFKtKZmGrBdMU^(F?0kKy-De2`#$OY5Uazso>^%we`~hrF`GOL+3tYQ<yUP z&jj=3=Y&P6C52S!<o9i5{TS12MMDqWZbHbxKT(*77b@dRa1YvDBFtDvFQHYfc#&wZ zH|GM(!vb4{<3pRWNk!^FD%Nf{Lau)zK|d0SEmvbZWGJ8)<z{vF04AVxx9vMLZ6x3o zS2wu;u02w>S-1h#bqRV4z6EF%mzay?^-@=}X7*9J)Oz^JbZ1>5r?93RFsMNy(lA}@ zsjQ>du|P>=0!8vO$gjd&zcCLQ0Q3R{!v-bPRby{iUPxi!;TeF!?Jz7ZAZ5C;g}R)w zh8hwX#ubZSO>>syJP7n_=9WX?eG*IoGe&12zX^uiBA}IENwH%lTDhd###$sI7*)9j z`io2FicakyoMzn$dxJ9QngAMA0^~6I@*GwrB>)LjNkwzen(d}C8cl1+p&^6=0JX0L zBxUlJ-?bv+Xw;et9_|$8k={Yviiw3V+D`2E48OKaHfb!N{N0}!ezDvfkbQ~)sw4TR zhT&mML)Cg3F@s9hazVpVi}{dnHhKb^DcVmoTkAfsqjm!n3t!1>&TG8DLV(_69(aOM z1&hx+S*=(i%Y!Ea&IzwB&vG4-XYh)u0H0wr?lYz%<JlwNme8$CF%ly=h$l=eZ`x#g zT?R+Qo3Q5`wXRaMfSR)EYaYdTR-<)Mwdo}V$ZIwMpIW%x2!@$d=w(TMCcSJrQ34)w z`Qq84Q3hqq^CU3$Ejy*munt;W9u{2-5Ya6EC|4N~?irFxd4D+XT(3zpH&tkmU)0rk zfk0Yh)+um62$E<po4|ls3eaZbowX1u)81-G5Jwsc3E&Wc5Xr7WsoTZph5gh?@$glT zuS%gvJg*dh6Nh9ukRM|F7I2uLGx5cyeWNpp+$5+&Uk^HPVdw_nFxdWS6PdfQVyP-m zmdrBIP_%9Pj!jK!!7|#0kwgV61V?I<p{2qfF$zd4s$dn2OyizCRXb)8IL8hw=3MTO zl2FB%E^j-l22)^ZlKofI6!aYE#gxlInxEDTcH~&E8Je(NQz5QKy4}ec3YeG<+x`q_ z?!ZmK{}Yc$p20`%5K^_&D9iH4Rr!h;aKE_OH1v#4R-4j5B?e58L>h^c<@q9bB^Q`< zw2Z7sijCGF<$ILqu=aC-3PwOaViQ%D$MqC0@e{gY_lW1ZI(ACb0e|Zt$rT(NXNA`H zknw1lNR4#bbsfRnmE)3Ntl?M;Fq?+EcyRc-rj2_*U~EnsbZKq@((8myfu_#jVrbY> zApovLL-J$*EAOJs0+M5x(8}!$-6W*Q)PBydu0%&bwty$XWbr`6&Vm*^iiK9ZX%l%h zlh2gI9Z5BLXxs|K1?Stz@XD_MeETNdb)uAhbor?L&d<aB>wD`kJl)>k<NISZ+kHL{ zjXtl}`|J6kd%U5_uLWyPPd)3IK{GwO+0;`4%!S%fdEFdVDiL(i`^sxc0Fb<e{htw- zk>$_e@Iwfu{n}G{B-$qlOM<Rcpv$99wWG8IeYEWA0Sfuvc9kA$T(#ku&G9Yi{Is+N zQX2!SmYW$_bzvImwQKaz)HJv_#PT)3raf4!pk=!58hIUk)u?DwWkRgNO|N2$G2fQz z6<+#*-km)_%q1NTM@yxxTW{*n-=SWr7vT4pBfsZ|2HzTD?;iF*(1EPs);D2s7kUV; zyQx&8e4XbbQVR0z(+iiZ;(aUTGZ7{Gdxj7`<~*KyPqcu0@3^IO*vR3XmaDHLxxg5= zJv~R2848ubuCOH&ra9nax%kCQ&8l!x*sPV=Q#lj0n!jXd>qrA(7P8<3o1!!Zic|Rp z8Z7{6H4FlqhElIaO&EG9>Ql_=fGB&5_J@7BFkjtZ0AIV!>N)VgN95f~2;{h$aZbCA zF0i3g63;;$0ZgBK^$z)L;9zcUqLsR7nyT(DFhT3B(M7gddhMC^*|uzp^5lj74F&kQ zmpqfeE~{#RRzaAg9#1E1$zk?_yu6&S1Pc04<QOBBcm2>-$;?EZJs7vIFtgVqryI-| zS+RJJ;I~ya+;Pz3K}mc>%3C?`KE6zzYMI;jI|0Z(p9|xF%KCU@>cQc4j7gD%V-tds zE`n=G5ohB+rZd3zlSF4WP=ecStEg71@%s4WnI|osY{j!9RpB5S4S30KVKmTJv=qWs z$f%1N)G=IQXsC*#YOC*cs4sA&aYhp*G+x~y-jd?Y{L1g1c|GkyVA`BAKR?&ATSw~j zPd~!Hd<LyUY%|K&2)Nu7acMfDpEJZG+8GxixaWaqsCGcG{K0w<8G{0ff!LR*H2cs9 z^Ch3nW@!~qPYZD)5d<Sf4UzDsfausbj$TfI(68Ay2sz0>q|sMMa_%oWG$m+k$R#cN zn}{lc5o}~)>T69y^wy`A2x`V^;N283rdEWDYE#mO3;~#0ueRT)aD;7!zKgk~!vgC7 zJ2;4MiCX8TuZi2MWNs}Y?%G~fM1BGr9{rY9#zskhrm&Yo2bHeFoHLYAqzN7;bjxK; zqthfD2Brx3**m!03R3AVq(yE_AOC$7n*@0lcJ?Z3QvCgOvc2ifoy8H1U{2ieMG0T{ z06cB<1qU7QqDD}TC?bK+2;1D#7##%oh}JS!$4_~80So>~JJA*NiiIJ2E954D#=Xt_ zW(CMY{L?NlK{U)Q>$w7<7#Y;8MT5fqZ}@pF^)^g$OS~I0XSn)XX5NN->c?<1&6h}m z3p(EpS}{mY254=vHm2ZLK0&^L`?NMMcfqh^ZFz;e$Z;Ow<7Z|zYk4&q3T(0H7{MS2 zV`d1t6hz@_FDn!Wv*J8XNhPCVn;%8)ei`=nP9pG>z1AmCZ_3|^pbPQJH_FoDxcIim z@|AqNKHxa-iJwt)i(3utzr6*`|0weJW5mM~`!FFFx#MC^g(vhE_5&(^J*aF|gZr*d z(r^_F^~JaO7oSZqkfXMAl9#z|zu~_9xS~UlFFg>j^A{!9<^=`(?aYG)*6==D&#ewu z9^7TIj=GUI5#ND%J!0`6dtq_e(j?vbbEg7xIpj#q7%ZB(dH&&RC?*o93U2h0+K0gb zB+bb>vTIOn7;i8)_i=Ut8l4@}Y^rIo)$cth<@KK4t;$hE8GWB-h1<wkfy3p1Z6TY$ zMCm`=todM}VPA9%ZS-ki#Hq)AM{b5o`8Bq6C84EN9(OBH1vl2bFMp~&5FR>PUIh?l z?u1)ot^5AAw)}N8#IN~I+-Ft<Ao8APoM~-B<>A{{ws2rUvsGR(DJF_m`zLvXy&7%^ zKr?!UX;I;li#+#o{Py_5&4nA5{(TU5c{E=C8p`l7YLJkEr`Bq4tOE??@||i8RBb52 z$c4H&Zs<gGFSS-cOKCT6Y?wF`euidpD;*=q$wH=7b?;V#`IGbu>aK_A;M;wK?4jd+ z%z|iT0PGqS2BdmLC|L3c2tgL<W|+3{EsWiH=NBMcv5_E#c>6S)$yt!miRkYbhy4a% zA*zmD_<9}fhpAu0$q6E=qZyLSwLdq}7PA{RKm5Iv7nu;Mou-}m)W+~haF^&V-;w1% z6p2KGpxPm3F%F^p&Wj%;50{)gskxb#`upSA{&`P+<jcqDduP?9^tI6QdL?+#AuzIv z@G0uoHSFW-D2SS|F3{O^RJMU1a=yzYK%fK>Z^W*>r$btYV6^qXg{r=EN1B9|=wy9g znIE=vg1Clr=twjw55ANj2h2Nv7V&)LMy+$xa(|MK!nPK-X)*37(TCzu&UqeIrAL(D zYgM(C^WkX&4&h6w`<iPh8z5I91P*_JIM7lP7_<h6U@nx~dCxHF_Z*TGLL;M?wwa%D zOD3so?zGF7`d4NV-Q$!sBVQPHSYzW2XH8MDMm9jZTNKf;#$Y<Chc6*T*xZ}RMVGxI z(=}rq7#?hKya@PXpl=({84$^5mdPCeER>rvmMa`uFaZlLra61yfwVnBNkBxM0qTv< z0K*($)2DL$asZtvVml%QQ#U8z7iaNC2m=KD&6b0kJKAHsOlAYsR4?2Nt*Mp_W%<QM z14DQ}BVlV$M4c{{Uo74A{NrMu!!^y3SX#$~D9ciYfg@Q`o>ZO9<K;+BKClNReqA*G zh?3~S#WPR7Jd#2+7a4knG6DQy=1uTy7lJ~_#mZZz<iHen*e|0`ec569R_l3Of|23T zTe>@pu7`sT=2t236x`S6C|a0{^`8u68zy75Vw>5Cc4Dm5*|RF&IGgrvpOa`e51{+n z%ar$Op<diP?SL4V@A`(WB|gyud&8yX?con+j49CSbo!!PFV$KMb=_fjWTlkzz%08V z^40_}(hGSxxS|W(w@t41gTt!PU(caA<vC!^2gY-+p0fN)&EvIa*Si8^w%LL`t(8Nt zs7MS#S8qs8&nHjGS-V!N*f}O$g~iz0QX!WLn3uHKqU5*TxJOPN0sHntAMh*q(Fd@A z(>>A)Mn({FEeA~T?eLc94W$J_`ACXRh6S?kpSQ{8baMIKJU-#y=jX}l^<N&pcl3{+ z$5n0*Nqzj^``h~Z-JWkET;4s1=7mI(hb-8p`e+12{5F9fp`(-w`sF|sjKy>@z>&~V z_dVb7j`#6Q!W3k(nJx3(!Jen*CqS)v{h3Fnuj6O{mp48O@}e};g9behcnX!kE%!6I zni<eYOD_6}^EF`Ev5Wl>Fms}{21&i8Un$S_Kl@4W_Em9C8wY;}DWuZ6hDly7M7x9r z!;22vk)@r@$9**hC9}jIRlf+no;?-4`1I1Wa~KaskqlV`_-t0(wb0J$M~<CXZi~5E zy(Q&_C2n>!`};D3{QymIbMLx(FuCCqYfcu}4i-N=-}IN6)#G`~0@P}K$o>r9iG9lM zJ4Bs;3`-i+wlpPGp>-KxB)L0bHHm_2*lUYomlJ=ussUBLCEDwhtr|BZ{xc)sT$K*r zBR}Ecg4<I!*Ui}hJ8B~;<k(RTS+;ijif-uJ*&{lw#rBv_jqX;!TQTDM$8v@k&pVn% z@`{&d?7v%bSU)fuK<<zG7th==|EBgIYk}{bS6S&t7YQ7o?Y6ugEP~P_s&?00nT3zD zC2O16u<_<_5SUWodNxliO1}Hf`F;veUYvW3Z9$*w?T@hWLNNs&Ad0L45NLe5V77SE zVd>1oFX{GY{SuZ|Y@~5mTVzJK`-i|l1`6^X6x-b{AFma&l}{(ddBje_Bjgtb)!X8< zbSdE4Rzzy1(w=#+h<5g#gPSWT6&DZ)l2>D@7mc?a7L?`SZqX#^=9r;^wkvqO1?3<| z2R#l;>*hBe5!?swHmLS03ya(jXHu0ed(_#)7y)=}SYLGBvgGBVPB(Q^q_GhL;>pe@ zDGq@Wu$`3NiU`J~K_}$90}F=m1=3eca{E{#8(+@%9)sq297dhVk>Ws|Gk@+6V?}OG zc7d(uqQQ?{0)(CUn1ljnda?jx#%tnR6E--?KAng~S;=<F@t!d{cEtT7C$)A#Q)LDl zO7@oVh$Dk>I-Ui(-Xy)z$tj%zTuizhzsGBei^*5rLzwDz8+gf&-}5cza>s6|2wqUc z2Gp*4MjFOwXnJ$PwD43h9=o5KG|oNR>ZGu6Y3%<iytQF+b>y+8ys+rDv5R(BE3Zxd zySMaXTM_`=rbgx2yZfPOT++=O9jL(b^X;^Ck_8QTF#q)7$2-HPVH3uaQX)FJWHAZt z$~<ku;><m;)~Ga#SQy2p6QL8SW#i(HSI{EVb1~0TPLyd!BmgfFD@S~KrOi36M6ERU zItC0WW+YoW0y=Nr4eh(JXJok;=I((XDU*ZmgxZlfD?xqAQTcKENVFNSU-j8|Z>B-m zD)~QCDhO5lbQ60&C~|2@frN=&p*?<}yofIFq=Hf^z`k-z$@mp$>tv}0U7v{9muIY` zA4VgH#&|Qy=~sj+{CU&>>2M2VxP?La6I$p7=Kgw64o2d+i7@AjsNferUiADoL7aOS z7K4DH0Jf~JkC*E5@=j+nRgRbcVjJEG*|ULtjDQ7{)*Yn?mZ>V7jI+t^bUcX;d-WiY zWhVqdSX+Cc;qw9Yqi$*V=${y{0XjV+YO6HBauE?II3UK6tQ7|8Ydm1$M0sQUKzUy= zThcy7@(9K%VS6|&i!?Uq<b~#xqMH8JY5JyJrC{Bx;b+&VDq<y}kX3&EhgBM9_Vu<5 z+GU3@SJH)e1zQQ+W(r#M5@5XJn?D^F{4De|I_bHZwiMmLxzMYyBoo~363;!IYh0fE zq2^C692KM%12*l|d&eIi3VD(cHTAOyi+bIMK<0uLdCChNBd@?NX_-i(z)v}R4!Y{g zXABGmOk|oebI%O(`1IMG8Zkz&3^8$K^dtzXaJHO+ZO>d!>LTIvH@+=ehNf(%LjT*m zY!!y6vS$oL@_%V2kze+HNLcBsE*4|vIcCGUum)|8A*Q<hIQtlIkDvsB7to)hz`i|4 zA)TGRISmmFknE$1+ej~}rNkl>u=Xi4*!*19I4Hp*O3Nn}{x>jI&7`jo&2|=FFYc;> zkLVD0Mn`s#eh_Hrm!op-^GgqwX-K&^F(%Q`YdoevM#owf@g>1wtmcUOwgKd3rQZ<3 zyt%NgOkIv!k(k!-P||PuQDNq7-0U?(Z$u14?djTDu*`g0WnB~UkbK_mLdE8Z5Ts(l z&ihmJT-3l4ATf*e2IO5@Iu_Lj&+TwD{=c;*4y6(Q7(0i*k+J%O=xhoFPkm1izap0p zPL@SjGnwR^#6v(E`o-u+57Wk8AGfQ~cRQ*;_Ghsp(wC!i1jdI#ap$M!Gx2dEg&^9^ zy4^KeFo3J>zo!tp@IWs%9ggkJGa%Guyps^qg6or)3E1NV!j3guQe@i^(m9IN47Mzg zUz5YiU1#Tt=8rAp;(LZ6kmjy}*A)Gg^dUG_oDF!4HT3~~#tjU{RXe2nBsipwa#}wI zx{qR3Els#Wi(;~W&C!Ce)BMVl>oe_pY2Li<h=~&Bqf9EUf+9pF9Rp|lRNGXWuaa83 zfZh#Md3o6E@B5_dPb2)@bss!4#gTVE<K+m#xoOg+6`ljY+WvOY)}!q?-sFNq3?*W$ zRixU66f}k>#)^5!7)&6{5dVd`&AF|HZFm{yidzZLYm^vBMCyZ&K1ym<!XS>-1Wya) z;=ijghSR@0d|1I=Wxb+?`prUq;5F|XY%D`QD?l#IIGQE0c_YZ74@M%ik|TFv--+Fb zs2?zvDNnLl?{=QKi^nuN|JZNhtrnOsc2*e;UJ8Y5?CHUtY(`S+j4taeQQ#&YL@`h) z1ctJ)S-@m>72&y`u$rCR+aQbEbii^ESBD1tbQ^X_dLvPO$7z0U(Y0s7%RKL-^Tf!{ zL*a~b7vKaolsIu4vkCR#A8F1GVwh=2cZ?2pqa8tF-Z{{Gbhs2Ok`WU3KH9qQH#bV$ z!e5R01iBQkaDmXCb0J0pm}0PN*}hbj#wCkFu97n^3)LX#<B(;5fl}dJYJr$2XtQH^ zh+vO4$gI49kpGF`e4aTuO<8Oh-xiZ7z#MJmO00@W<zHqPUGcI6E=(xj<pPvH#OQg* zLCO)^NC@5~%(kUJxD*m}_C2hsS(B@%RGRFq{~5pQZ!J{fBBS~vYUzWZ=`-K+etDoC ze+vK0;r~{vPVil2-$$1=8<Zr-6?QLQIFNt?&Joa6?FIw0_qmBIB>9j{ZoCg&>kGe~ zXae)*NKX)dWisPBG)5@k``K~JMmI#j6%9H;mGfx3p?^n;1v$DEZa3h_GRYzidA%nT z^mg%BMCrK?q$RL8OIoy#{y3$h{?gPL=8L}7^Av40X}#7b<&n^<DEb?S92b!}dKIaT zUGL`o`gZXj^eZ7O;<@8h(IpKKDwW=o=8qKz8Fl9`RhOwGrFP}ZD&ya20##QZ6>DVm zLrwvlh0WM(X(V&1x_IU(oN>n3j8ORWcFuu$|0@5g@Px3>s`+6&%FT<F_?2KV*C6VZ zcJX_=RkcK44fls9N9o@`I!A%ca-HFu?hPlUL(vZ#x8?~Z=gWa=2aZD(SS+V`UpUc; z0et-FB9SCa6+~stKRBoq7R~{e9CAM(>sYj<Qct!EgJ}RAhdE5uT+<^6Lo5&nIvCZp z77N*=s4-L^dXdPLmma9qw(ikn32<>3j6#8SuFJhq5!M0Njizu2g4CHj!v=!1;>Ns- zCpoi57GjH8RpuCdwh}qK`p`RgycnO?r4tI)7UHYY#b;!QxME-1QiX)RrGV*uz`ncg z2T{+wb89WVzrRsz54+lz=Q^P?>iRy2lGH(A6iijg0WR_kwsodb7m&Po$E|J6tJBF6 z$1|=+TiHTRXn46Yd@^$7mB$0aFyR;BE4=(sB*rqf-z$0aiA~T;-(4&29!E^qdFGV# zT9=b`CnGS-^UCQ-&rxuTjGYqOgj*cunpr4r%L9_iCv!t{X7y{DISux9K~9hwVeBcI zqgskK#K(Lph$~3n!IodaJ}a(CXhQ3U_*|PMt1g^y+~49=&g+*mP5(4Nq?&f2ARi`b zMm>u44`IQrGq#d|BN^MnWCJsdi8379)n%L?5rlQg!f(HO$@0qGF3Q>+=>QxlD{0kP zbb>oH72L@Q7?Q!ZxMLhzaJxZG0M#gG@dMI%vjlb7Pga5-jU-fV8@tE|i`&M7&*m`1 zfel#hFjrkTiz}rv$1EZdZm1s$qu2L6$*VWERd#`b+Uj#Y={zM|+WGqw{X)>Q8hVO4 zgSK{xT+WWpA6|<|TdUyC`KdraC7rl7&YgD8d4hMSf5gFecAPwddOg+A$Gl+|F9g}E zg-_b+e&G#Hm!F>vA~F+c7`OlNI}OdFf6d+uE1o%m=C(M(guge2H!As$rO$!r-4^}! zv%6iuJe?dqPxZ=<DNfP;wo)gnuirP<m8d6}CcD5+F)mj8eJo`^p~YOVI^OD-h{54B z-aXt54U1$DLK2xv>JWBGF_4An(q;+G#JR28CZ5#Soav+tQ+H}!1@2==XSOCn%Ajm! z2}%Gp!9G7HW`CZLMeaYeL+3eK)&n@8ZTYa<liB0H!X(sTcwOIr?kI$o_kFnXMiP;) zAujjvwj&tQ>q!Zgl*dl0TSTqhsNjQek%)#Edz|1pwsQdgxr&r!ewsFMn!pMs`vl^} zjkt%#_;T(!E1`P9dJ^EUU=p(DJJ6#SmPAhSPRrScnw(sHkXCh`SN~FOF~-_bW-nRS z?zo+JQCoil)%o2Uc>V0)ncDt^zkgb2!Z409phIT=-W&NU918V3iYKa}6I0LMEHp1~ zSAv*)Cmq72viW4QD5`kCo8`#<HtS}I9XzL#6}oUNJ}sr}e^P^WgPi9(FEA}0@pN2D zY8%nNmSysF881@s+?<dIT<P>3qWfyUZ1zzWGPldr_q(M_ynLWblvDAWwk=``A=>Eo zs;{v8$p1sFRXe&xeL3E5QeV;itbL7oqwtgFEjq~1q`uN|w?!?LIiWchKEF%t6=l|- zP80OL_8!$q9U4}&E!Vs!;LL(O(tQ<Q_RV;+c<Oji8@H}no=hj$;vC`l*+4S5(1a<a z@;e8fIQzso7xK=JcaN?har(=U*WhxKSu$1TDiw1KF%w`EuM>6XBxK`>u*s%_GU(l3 zcQwjcbMfxM^~NvG57;AVB8{=ij>B^zVHSIXcyM((k(^|FJ5t%>9ye>?RF~>4K_Cir z0(7+FGLe<iFb-@tS*isOWl&F&Ss>I74c1aX-BXcFGL3DZ!T%v6r_~kR`myibsMHUS zuSkXLLrn<`c^~8E#s?2aX{NXS20|YmLC(K1?|$16>2<A-QB2<#EZVqbd(K6m({tjc zQw@tD!tQjv4_D}q$H*b(h=h@K$$T|RFY6v^X)C`whY0?BAsO{8`%j#8xLeAa$p{)Q zNf}Y+4L=lIfPIFj3I~V6CT(LM|8LT%rbxaaLgAC+F;+pV_sZodcXp^deL+4sg_eN^ zi3ajYlVBz29EzgT-*(eYi7!d($y~q-LR`w7V`iO)(L|7oFc<^Y(sKH-(fG(utD4cL zFCri!m4<9a-OSd*v`PN5xBPvoQ}X3Xl}@N*NI`?hBWhI^4{rLaWXWizG@8HDQP`NP z;~DNocmr?B$`rm5=dZAD95>CVkna=F-MFvOE#l47xb#rS)~6-}J7xt@FX-43`5uG$ zHxmyYIvzwD4a0_0o_O&3`XaEcJe>H(CT(`J->4Y_?}#VXTU>km+t7ev3_vulI>+kW zF8ZQ{SsW)J-1BlMkk9uE#nEycJ`NxSlycoA&e&h46zV)sH7+i!Fy$b;8$97}+F^w; z{k;0M^IFv-la|r8EgpXj6mOYzR4n=XF>UGFP-nOo9A4`(s6Vf1ZLY{hfZNItMEqeb zCoX1>eplzM<=Vi+`Gj8uM?!R*{7Oco3kCXbBsx$6PPZ+w89lBWp!bt5oi-jGfWn7h zJ_!2?L&|Hl^A;oVHw6scelTE-vDp&_0)HeAN?zkFmZ1e3bcFas)j`gP`@+qrJtR~z zp<f4<T}pCZq+{%kCaJ^y{N%yc-*QAF1fTJgcq?!xAc)#*f(*s9$A!O$Vk@Vz1Hb2a zqh)!`Y}qm(e{fKnC6TDwH+}pH*S0zpU61)#kIpDoT}LgK&S_x$bnvGxGAUz8kE2wW zvTCr{=?U`qzap7YLEW<xr7t3)yDbvf{lXj%F|UIh4LgF(Cw3rjboZ9&7tx~R#t4*m zl|+^vs5OTcjRO1<fya5mwHfV|#RbeVs!wqpHXf?+8T&l<=RUBDzFPz-Jz!@^wmFQ% zE*#F00Qfe}wn9m?<??#cV6@>dq(1fAT&T(CHogCKLS%1aLoRgf03<V*&#LxOcp5?m z)A>V?PuZ{Ut)DF%d0elK!`<f#+g*bxLA^(D>g*?4*rWuxIHO!g?Z9uk)h;#w6GRNl z3LS@^>u;(uX;3R&126rdy*{Fw8SUL$^LUEotZ}xFw@;5P=mj3iuG&3FjBmY$xW(36 z6bAbobZPIG%;*8agn|uAi%2%%DrD*$%VjrbmMviQNNnENyyEa2fSKI1k2|(+Qe5A- z_F*xVekx~)ABn;D%-0mX-;^u@HN_xDqUwa~J@4GZnx`aXjMjEUnC>}t!z+fQRUr59 zMo5N5;IA%~NQcWP*)M*<{yXnqJm&aV^^X!+00{u_AAaQjB1M`yIoUh?hbkDWCTow) zj?nw04wE9Sq(QX+#LF^48V8Lbp)e>ZFKVc`t!YU_*GbUX_Hy?*v9l^gby!CqHge!? zzw4tAJxb(s`RBMdmKts_ykdpxjl7ZrsUO2G*#o^YT4(W9LYafL?~-ObRf`5qYITrZ zMN&o=2}f%ABcURk1oz^><@KM?ll^%>+K)57CrC2S%63F*DU$Lg6KfMRm-VFiW#^+^ z-(T_ai1DG;UaQe3-SK?b|6MJAjJ~dT_2!=P>+R7rqN|l_3{yop=R^OW;`3H-V`hLq zw37ey#1BgOFP)>qpScbf#45h&*KzkTVUf;ZYs2Bn52Y@Pu!v@X7xRlL%=9^+)jyXi zp9?b`ZirEy`)nS=^{QV~V!pG^Ou?2>%6lD_gWTiM(F!l=+#J8xdUpX=1w6ic4Dy4Y zhHn$cW~7d$bFV{!;LZG1@mzC@ECp3~CxO_%BdA_oi*;1y_VNPk&kLO-vcDHQcTxA@ zv`ft?s><fP-=;Q!y>cz<@-o_H;)UaLQuA%;R22H7m}RqOTpKnLM7G?GkqxYD*~(Da zv#_ExRNmKwqc;-qHK4UN#ncVvjcHiE=j)4Uh0+9VYj0lFvxIl0&`EzGQZ(+p@(IZ; zCN-sa5skJE<sN<yxk}ECjq|(NB=a`#ptmy-(}~oJi_5)g3T5svR+&1G;+UzO;#u*E zZD`M0wBS6cB-|(2HHOISFY)4iWNqgIUGJ*$6VEOJDJ(iSWzd1TMKDtDY>+g4pC{lN zxlK;y4#M2WEyUAYRnLRN6UdgH@^lAdINUn_Whsa)NCAI+IO1p>Uri?M@+G#;4|HS2 zrW@}2TVu{h%Ug3ujt@HuO$OW&?sQ2t)dxi}sdbnkQ9Y)scdE{X1jPv<?hVUzDOsT^ zD#sS+!b_Yr0W(@U`Z%-Z$O4m;frf;y%#qs`qRN~xDc;>IF>M(%;ShK>3nChZod9QK zQ9yX!TfaWb{qgo{&--N9k>ZoMcD!?DgVEn};bg93?tlcM&k9C?ZAT@jGQ6@|`R_)r z$(=?FuWi5q@1gSLju<;PFAK0YP#@vJ7e>-zSB%1lYSlCk82UydPXPQA#poNIJ<SqQ zP?DkhQh~>c{zA`yvUn%hKH8SmmJo%Tl6%bR^cz0TyfV$>&`ZJ}ugcn;3VrlOTZ)K^ zzit(I585NcdL1QxHE=zkcx*(&<xqvnE)O!H)Gvw#h!sr_ct)!e+pq}!K`FoZM*r{G zcIAbiNreCaSpUZh{Xg_EQx6wYJ7-IKyMN=|s$px7-HG^9r!RO8CGjuVSOESUOb@5P z;dW3Y5#$WVxsOm&v6DFBmA;*%Gfnkz^a(TRn`pBK7_J6Elu18)z&y``qqG{^sHc%t z@n*esIfSj;Sy!ks*RH2ZM?J$}V?k;i>ubuw>%An0$(w0YTPdoB{VgG$2zEPhR%=&6 z|EeNKmYmc^v^PyY6<xfC&8x2?3&OX2!Q%5P($}ix(?|>1ipp-7Kv9B*EyY$jBUdIO z%*jRVNNeUO^;-DXVY#Ym=HQG5=I<*;`tiIw5eF~+riM%1-=~j7PrU9&A09(Y8x@Va zkM+%ljds!3r6Alk^grjF1!K`$_n-*i^H>+#CM^H_jBx-2JZx$xWng7i#Z)Kp$pPlh zEzd9jW9M>Y@3!dpF1aAaepnAR_#FdOqM;|Edo1`fIipv=okLZyoP?puUh0YGn1oi! zZK$Tn43E=#oQlaSa&NuQLTafFWv!r*wN(cD1q(qGPrC~WP^G<?Gj=IyuNY%s-d8W( z7WfM9-=EjH*6rFaUw*x4Pr;9$Pk<KmlU3vxaE$u(tu>IfO6j?SgCHJNEMazWLl#J8 z(B+amlU1SRQst0|aH)SxT4`Q04B|I$==JUR`L_K(GWfrI+}(etZ-%{kB`~(H49XJX z7`UzD<~68p^|YWE$Fr6SnT3uvxMMWyiEAH_DfDzKj_B!vBujI_QvmA>coO6i{FK(t zvs(0<SQ9EB-{GKJd4PP)IZ#0e>S8=$YKERCru<u>v`2Mbn=G(ogxG&?zhtqylHAC1 z+JhReC#Lmmv_X=wxzD}SXbvnCTS<$eW^o%Y4i#@3mRF@HrjlYCghBGrqs?p}h=28r z;`MyumK3nyMIoePbq;O5Q2l(RQJiz_w+HEBGscy7kUZ50i}NB74Z}Hk2d>kWl{AdI zNb>MsLo^-|0;={w1mM&&uF!h8ADY$XVJJdI2@_wb#baBL{OFPp#j-1jjls-?cw&?T zi9=*MG^4Vor%OHFynfjk=U0p}%h(-KZ|Ze~L;q9(?Z!J>PCDQwm_CcBA*2Lb8doxK z*Z#<wG66e1v6c18$#TA1Da3JZV1`g`7Vd~QM)Q~a7}#(E@rb2ADs7@y6vsMTYlQLw znTao<eKriu{@tkDNEV4BLpX(;1Z?`iX&<%LBOpU<q?a~3_2(n<@As94%q5nu^*m6w zF-<>gzy~GFH)bYYuN1rjvL4M>H%vqxGVa!+kY{CRfe<%#+4m?~=0Gpf4dZO8VCaID zWDrQ8H(JRIWI#NY@kD<KH=fQ8I$@#g3P&_75p<FuiGHcFptfADd8ep87=P~Opw8_0 ze72lgkrf<As)n}+eiLQeb7`{ij#A0^wgLcx)q?%(hjzyp?OS$Mt`vH|d@B>3s2PR4 z505}SbE-d<S&bj6)??V!lIl%~Jr<52!+=V}A}L9xXoo18ik`?d@%3}Y-LiTm{>`_A z1v{EcQhQ)%AKz4htAuvF_dz?tFOkWwVs2Lh)6}5jqVyxU15Wf*;wXXM6jCgaJAsy` z-Wpi(c-z0Lmr6g~pL?F_rNzD<nA*1aiJa{lAaEhmJa2%NWGvSuJ1kk5B|NB-iB+{r zlMBR@22$xe2ga02>>6dtW`q<)QlsLYlsy^moJ*o_YELGxqcW9?3$EP5%=d9r?@a?2 zJa4j5a4YRp2TS2J)<NG!=;7cC3zxg1G;!{?$6;`nnWuyET_pZM1;%!0kR5;L6|LhN zN(1J$*pKCBs}fiZ<T|8LvV4ppFD~0`)d}qIFk;4(RcIT8w@@?uQx%W83?&ZB_Ux@< zi1ejTU^)zQ4q4kH_%Ksv>|+Q?ex<oP6MG{U>=%NP1&4dI1Q}J7W)obLcO4Y(t4eL* zQvRcB{tO$=V9e$%S-fdqh+Ic;t6{Hj+gssn#LSHeiBG4}NR&oj0tDxG4V|B6t^5iF zwE*sbNpM=Sg*df004ZCL13k*s6aOj4Hb&&KK@G7fP<js2XEKO6L9X-sDkYPuMj=Nx zUwcf`V=sIFXO*5k)-QyJY(l+1pvvwaP6h2Q$0<kLm`*3crF<6M-)kocd+`YR8Yx-B zQNAsC1ggIwC*x$QE7@zUNT8ovzxTI5X^KMlP%i!L?lGxfVAlvL$X7PK3Mquzr#_N! zmv|K8a0tSI1KT=JWzzjdIi0OTgyh*|^?jw%)V)>uY(TB5Dzv2HNqFpr^K6*QX;|>i z4v%Pd<Z`C40z2;I3nP_x*Ue~@wD`UkGhyG#IYeoNqIyb)t;!h#TVt@=mehS`7W~VM z2C=+)2}S*CVhb~Fm_zsL<*C<WJ!Gxg2-J9QI9*osZhdD+jS79FsoSPhJ^9*MDqZ{M zDT*+!*X?<}pw>Jh4t^PC9a3ezBkboST+|;Lo`0xWYECoh%vpTZjq*^I5*I+)aj+?{ zK6-rE=<DYJlpEf+<|?bggq6eJ(17%iB$geS?+g1#<#=F1t^V&O=Jie}*n|Op#7S}z zQ7GjVY{TB>=7{x!#{|~$OnEu(zJ~{*CQS2I*tJjM3&R%}0P%u?_fg!j^Y-Wy3)^3^ zvu!AWxPi-Ep0_7tL7-?lf1Mh!Hz9sGQo8lA?-?d|b_)-LOJ|Rg&WqBL4e45)S+D4Q zcw$p%s6Q6Hwh5TS*@>m9f8dKYXlE%$n9MDu6E6nmS8{v1cwauKcMvWQN&`We_~aNi z7Pa}--Z5gx*BZ<e29Tv6T(3ajMtB$s_ZaX4oBbp}66~wL{*2cnGrOgWn`>lo64WgM z6XuLo(}T^5v1}UX{eESJdMDMKrZKtDGGfI2K!zSR%pIl_;?}JTZk)B+oEn~XI5YAT zeG`+teWjwe^gHipR*Ki5(A*4}-ne;?9}F;#<t@v<l2Tg}+)m=u{Q~{>CbQeFnY{%H z004>n|60lBHugsUmY5q2S?7P`^M7{~n-gHtbwgWouZNhi<p+*roFuQLR}yQI2%XFd zN(I0IiJAJl!{`E%sfXu<i^8r95;yd2d-pvcJQ%P^ZoNVS>X7m(J(>=Wpx9H?by+Zc z>(Xj4jN_NCKrcvVV&?GD8uj~y^Cq-=wog{+r0%3ha+Lv5JzJ<A$$gwt*zu}{A!mc4 zfbh@ocJ=gi2LAlu5!G+l=oyH<GtoexwBraMGDMNuK>kQAtU$o`jQiEDG%PFBJd&{T zQVqu3bV;V{#;UAY1DNE%2WJOBU_3m96Pwsz%Ony|I@_9I*5%U3ub`R}?8-NGoPOif zA;foi{y*=`m$4`z0;8#H5E!_iZsNeG!3HBd7AZjk3|;;yH|R-r5Q2r6=mis3P=cu% zs`e>%=bqEmMCMHjX4qz}zA~6S_3dx4C!jVWqxp<9IvNc#ZBQv@O4#~sI_dk*&_D|S zm1`N!YJzhpl9x#rX!_RR&>AcWdF5>U7q(Wdy?ayPkA|2JfO2NXVFb&$0L#uz0){Gc zRG8L6Y@&v?KH{3fw1%Rbp+U*Ky3)5G0=8(m@|pv?KdE$pU_XTXnXRvuERT?UwBAI+ zKpdk(6W|+ZIYAAp)j~PH<lp)-T<a?%&B>HFoP~AaV}~)-ufo;;OyGV|F;Lrzxc~A; zm=)%IU^=y~!VXeE&8a3*gpARGGOpDL*7~~iZ>O)t3)@3MNe0xWGRLWyp)$3Ry2Zh2 zyBXPzjKsW2EcWaC5DXZ2fJ(gDsnsL^#ys?yS+yI;^Pdd_nFa)Y&(MSOQ0^<PRr0)F zIK$w9Zkrx0^gdwleSH9;h|uUNqbicQiuMx;)FoOAGZ!mkl)oKBg@xiDFLRwbw}L0O zBFK(TuFT9lQ<vupRne|}`In2^^xSNQkCx3sg2ZyvHEAlgA;IjnJVlq~VaB^^|A3N} z(LY}<=E0Kycq9+Nm<%PPX*vkbp-P33GGrT#S?p(&lMR@uV8^7%H02`{7>_W_2^U94 zH%B|NTvI?ogRS{viGO7{$AGx!0DTo3!?m~Jv^@Iddgex?<v*i4L;0xi*yl@$RiOGu zRW&{pCuzb`)17<tHS1V}f_|$yBdF>~l8$F&fUKsh3C8q`Lr%nwvz&@4FdoW8124C2 zWa%jM3V2O3FjZPt_e|#0kTEFmM1s7joXeZ2xr|RZ>sp<jCY@MhnX*{jzMbUCSiHqn zH_J`S3#(*zHrI%21lLutGWfMKD&z*80Hbg!=?)Pusm5;GpDl8&Xq0!OhE`)_V0+;V zcPv!E1;S@E4@m~jd5OU<fx<8B^>6unB*f_v<l@_O*P9}P?9#LlfvwZ!bbN1N3hqDC zy(z6dofobdGTp+3G4@!1DJu$FaSbm5+&r7cc&x@}zK}{0AUg=x$d-?1a5Y~$+Kg*! z=@mN6URQ)$lKgo0zLWZ7#x&Ve>kSVBRPXKnEWh&#m-i29_2{)q$|PG$8m<02t?j5k zfb&P9EQRv|uU8cP$;@})Vl#XBR^fgG96f{_QxP>s{j;`p<g|gdFoUuthd+37RJpN_ z&iqm2*fG4jI2*UFvbe~u_;*%XVtjRb;d@x!Vq87gGu-6dK1aK-UCYaPOGRayg`4xW zj1R|$&D;TF4UxHF&ErbOkG<2@t63Yr8F1z1?8%oA2{#inH*Kz^>9~sOB91at8P9UJ ztBz{8vM`1h^)iLXo|0%@Tzul!0(<QB$R|>3d*oXOUO{%3rF`k~a~S=C8K}mMH8QAW z<D18m)D}1oe;OS;B+9a9dUXNB&`Vy$*7Dk3@3_qkLSa>vOF%^}?JTq>*Iu(bH5W(l z73#nm1bRhFxKGw&J6CBZ_L;5h?_v0g%yNZw6}9)<T7B3?&EoQJO(bgScX(%-dL=Bc z3*gHf#%lIOd7f~$4Xz&tSx+H8n)0Ez*t{>znlb21xIBBZ${auYs4m%!VRIJ#R=Qw( z;n0Ko1ON9?fbjlBIUn=yrRskGRzRu00096M0001UWps6LbZ>8Lb1!FgX)QA{E@gOS z?7e?{RK>YCd^UTsIY~A-3v3`jfB-?!prT7O>n5-<*$|cB#+6+nB*BU_ZfQ%yIe=FJ z!Lw^~GHj)--s)|=m5Y8ay|?$)w(`SPaF@`82+A*ifKVH2)QO84OH3BB<h;)_XEzDh z``*5PegApklXK3@JTvpm%=0|+JTuSCRzJ9dGjbfq!=I*c+<s2~=j8tPe-!?*XZ#_X zdnNtNnfnb(-kkYB<D={I*EN0r+f5IBH~-;>zW2TFOZne=B)>`iUjC!s%dfc4lmFfC zuYTm_tgMWJL>WDv@R=8G`)`u``(gh(WEcDX4H<&>wB};+BD@c-x{(Cf+d+QE-Zznx z?7fKWg!lcAKHP};|0i7CE{<DbFmi_9lA2^(H)k|t8qzuL4G1jN<0f1O4+~4wdjY>w zI4(7jC;8@_2EEht<Q4{qup{r07yGy1635N`2m17X``6lk&DeD7sQgd=Zk8U|B*FXh zt^`8ZR{m<3e2!anbJOaFq=z`JF<&o}n+1PwT@45II&ap&xWk25o<T3O?;CL8f4oKi z|G)p6|7u7@fe>;V+5~5yOTOe;<}EzrBQ#WTlhJQ*(@hy1ryLe+n(drgQDEudW`))n zf}d~kMNOffV}7!vAh(UrELkZV7f16;X30~6+7^q?ztT&$vAkyEpiS#At*nfu*fjD0 zLQiNll~+3cyty4fvl*y22@2R)8ahm~Iw}oZecg)M_H7r;K&?Al#+Pxn!)l;FfRLBG zQjiO8A9;<v+tSGKKv<d(T3x`EmE0op9c9|eHbWpRe-#Q8n1M*$q3s10VAGn=0|nOm zLlp&9w~ziT3oEs@Y%UNuG58`h20qOz#lUm$2^lbBP3UQsQO^@vQeds|(t5}U;e5zE z+H-}6S~l~UD?=50rkqjLQoK^iL42S>v*S=xdI!g0r2M6y^Np4TrRRb4y`Nr!4)7Zq zd8m@|AdyHP`v&yqLAu*ZUr9$~=SHU`p*|3RS@DbX`MmTQmTV=^Oz4mX(ot_aMpFRK zZHKY{+K(mwDHjA7V;|XEkViVlV(;hOv<=E6YYXPG!Om0bIJH<jnC2#f>dJyV`Y)`% z%)ziUUOaf8VQ~#@Wifm(EPv4^E^b{?kQeBZzAYX+c|ZMbGD%8PHWyepX-OLtiDXh9 zJq=_sd7#}OkGF;GNL7%+iBE@-!cGna&q)>!5=EJy6U9Z_IT)BcPWpKp)X<t;8T|=< z0GyS<O$IoKn45qF8nbqoIL*Zo7gwn+cmi;`Lp(U?etOoN#0eU(*s$15JIx~vXjueA zaJ!~yK!Vl=pgkb_c6gIR>}#a|HW%=mJbovaU&cW}>3+_w<#63jZa)g)cIe;bwy?j# z4Q(-Fd*IIsf4MN`dG1b#M5du@(pb}AEay*fauA(Y0nu8H1qy=tR|0YHNUOQ``#JXC zfKRs{K+FIF_~te4{?N(M*)Sg|VW*o88+AqvD~Ff2Ll^MCm}b9rznX=ZYB>Uy45fzn z0(Xs;!|SD_HMT%0(fx!kz<kiY1aVjyafI&X67)fU016Miifwe94XsPra#QF<HiZMW zxrA>GZ8GTcpv~e8oC134EOQ(UNhZVQ53n@9!Aoy4A;;3jBT(Zq`gkVf?YxGA4zlt; zAh9iXqFf=?-`*eMZ)rRXIo$N_OeSp#2>)B?I>;6^j^bB%sM2vUv^mYNxuc<;{Hbn5 za=^A-$W0k5KdcZUfr5N^HFC&dP*07Y!(q~Ltk5gSoMUkUhPI;Aa2(oTh5A~GZ<fr+ z%*elv$i^=_m@KeXCHkYS%77VTBxmklp~ti4!Be%6ocZ{!;=QU{0PtKGO!{xHAoIeY zDZ`q)fFaVD3t)7qF)^q&q%blGRT}Govk`UR>UrtN)!3?bpWcM03-aN0zn3ofH3-Mh zYy3PE5amRd9|kPLlElyH=v;4U6M!c&S}tWssV$eX<fuQTgTZ1kjn=<nZ!gbCGP{jr z@z|6c0iHX}*pBT5c>vj#Wx;@6J9KRUyjr&x%te$QC=l+40%xJ@rL9B2Rr8^N1vOsi z=(+Uz%McL*tW*%VK~2u|Hg>}p_oDLY0a7zBBfl<~2Q3Wog(!)fD4aewGFhieAc`t4 zX_{(!9mxfdR62OaU$)F(^Z=xvPxwE$>1+nF7`Pjghc<u0>Zj(hIa$(|Tc+T>#m z8=L9M=1-K@3Kjq!TwSLLdvAs00umI6RA7dA;FT8{&v_e<AuB#>NQ~Ng9jk`@m~qU& ztxp>nIFwO1@gkGn@2;Uw#x>1N!`M&TS;L`k8c>8U8qK5A^G*w}Gs!Z;6Xxd{ns-Ih zpt3_2&Tnq)>jykKW<YHNs@!7>lRClif%r_=(IMy4Z$W$~HxY31;y?P?bT(xuN3`BI zAreHfY-X_1+iIQQp}&Oo)T(lPpxo?~H+pEzGzcp(O`592hNX$*MC5WRIih?xBl4li zXny8}8_T$8>Z{KJqYac5Y?W_7(8&mDB}XEcQkCu*k#3Wb59xsW8KASEMarW`reBSj zJAqksk7k#9<k=p&9%d5~3%M+AuO^#4^lUazoU6y<qhGUmCa=>K9|qY?(@`Y3dZ-B+ z+pft1U4pG>-_Kdfxb~f4M;Yh!TkBEs?MJmeYI1Zmr;(0bn1V!hFdx8ccfD4K(p{eJ z2Zk-eH2Tt2390@m%j?^1r(VT!qp3SFS~aIAk$mM4zwHuAo6Vp3hwA~t0uVlOC=yF0 zd=T4CE-RnTh<s`yd>VF<03D7KP>OmhWWQ_MrFD>D^IHwJaD6*HH5-(Y()lphoRms` zJ`?7MBCLz1%*199Z5g@XC9=TU=jdyiwQYD6)V*;Ed8?3hdc;yg$Ik&8T53icr8b(O zbmV)roLrD}^>umy#3d*(Yx6`UY;n_%3$O#t+p2VU0CAa>aK2m5GMa<6+!1M-QOYXJ z-L}fCZPm2G2sD%xbZ9oquIJ4glebz>E?J?}<_U>B49TDV58yS*BXN*vuDBZp9tU(| zfi5-8!2vnf?uttjXlovab8!aU3Lm68t_q<4bm<HOoMy&(FL+9N)D{LEL;$sL;<n2u zIGeJS($*VU-}XK;2WO{C%4NRk*1@yNhepX<c(OH3=`<+426+HTxLYtr@MVG58_Hje zk=_)^bn!o-;0zt^GlYW*8rtE>C-@aP+!yQ;13y9X_K>q6JFJ5pXmZ2EXpu9a7%>=x zVD$PnlhR>G)+rT&N_&eADSu4P0-XGi@{v)RFbW0`cPLSV{5h)4E9x8C2Rjj5nwTs^ z3_J^AJy!lqFGSK4A=|);dL3VNlG4dzoxl8pHaxtAn2aZsKFxNBOaw9bE6!lpCY=wQ zlI8^lr0Ii)fCxFsjBiep537@+x!eAVO9$|k4PPAl;%%o`si2TRxn^5fP1Ea;2cQvR zaHFniF|64@YjUn8TQ%7N<LuXPq}_9nwR4k%P~)+k^ZL}fn7vMrnn|_Uaa2yT*IDEr zL{s4<`R#R9jL4N&VMMM}Yp=`0h<y1zjL4U&>~#h5LVMj@c_HwOE$l3wE}5z-9qk(j zS{B|Z7dehfQ<P?lQGDWSXoNonknn3YblG)G9#^We5S@g%4|Td?IDzz{eGHjWS|?+9 znpzi!5|@bwO>Qbcrdl9MV`X$=o2ld$DXV0qlwNYPEPzObnQDunvUs}uwqr<|19(eQ zNoS!;u)A_MG`m@~&=>SP>i~<|EJV|Z%j#%{nsSLN4j=b8Ttbrz8YoR>`SLfolKJxJ zi+Vn2tr+-EK(SDc+vT|%W`pdEBSZmxLWk%LK`IuqwNMu9a{k6Oz?V=ucIyUKmsJnt z>Y+S6l&^;h^w3-kQGPO(B*+u}6YD+rPn}O&b9JMnBYLB~E+&8MpH&O28Hwh3M^L>~ zz!1?3gK}))hWZs<NlB4Acy?;neq`0zM{0mTNVOGXAV8{tP7(pY84@jnXQqagZevnT zbh3%DpswAKh2mIFx!B&j8)ZjAfO*MR9hGJj<`2_HZUdUF6iC%tHJem5s!Ms2?Z{d; zwTzR-ldSDiK;~DilhY`73&5F3CGSYxF&Ppk638@?E>P)uEQg2K0q43D*{W2nOMyxZ z(F`I$$xa><JL>BW@j4pH1*G;+bst@W?BMEC_Jan;8MaIax%%9G0o(D*1x%ZWT1d+g z6dKinxR0+=x`meJI47l%>X`D-x+{q;Q%Y$8$TN97G>~Mif(8I^835O{gY5vN1)-kW z+5}4}7xICp>~&^&8m*WFsu%v#Ct`YRVp2PZRzqPhI_JHri>j_}oP|AzwyWFS>FR+3 zw|2TN+=ZF$VrGp+tL`Cvo6?A@yEQk;;5>B40-Qgg@yXF;g55*vEWvYfnl0S>FHnF_ z8RDDd(Btu-w&8og;ZSj#MG5mtga`3+|D82)xw_4L1-?t}thplJ(dHh8@9XZY8J1_Z zxi$E<+zF(Rskq|2y*b`=D7r}8>(s=(cWco~_!@?<;b;kbU4gGF(c9oF4qx%;T)noa z*k*xJtapx+EzUB{6}Q*Ln=SxR0@mVQPTZSb7>WLk;qQB$f>iZsIR!9TLDy<I`S7u= z6Jxh&t3Knnjc93p(2(eC`uy!28-mXk;4Iz>G)Z^f1o}1#Ozi{=aRRWh0<>zqG{~RR zxB&HWEoZJCPQ|KD)Fox6K#$;vvij!%#4*1>XQ86j4j+s1#wZDW(M)230#cwZ&~0U* zsV}Jjc$qYeiogpNk{#><n3D{~+;kxcqm;f<h%@EnMtoCOu`b>+Sj`w!OSj$utyu-C zaAOtf!#f$NL78_o?yiOK6=?r{C!}=p1r-SJFaRi}`?1(sX=)>W(9iGC%Qb_&n}X&p z#@fO_zPXK-uOSn)f@BuxLTnmRknLQ#eOfUnNMhhmIP*+f0N-sc%fF%0q%@nssDB<i zxaikd{QP;4jl|UEGeJ$-q!sPP$f+!{PnFNB%{{8zt$e}5w_~u$M+XZ*s+pwEA#jg& zJN>E<)lm9jA&LR*y+onsSZt!Ow+b1%+M9diRJ*HN%EmIA&j8=B8c6e*=r0@BLG$;o z#y)5Ot+lps6NV)W--qF(GCKneiDnBY&sA9yq1|hz0IoRfaS(6Nc1)H8Nbq1nJI%JD zb%6th3kC?-KFkb+x{+7|#{O3_R$p15&+B0fLInL$B1kkZy?7%kTwYr100oBj+=<VP z<M7$VzF%R_UlilB=ni~NM?&~)HZ;d|BlbqYE~NJQBq3EmQw(w{-EPwv;_R&nE}++6 z(WR4rdE<N>?4j|xDH9L5o&^?I00izIZcv-!`>P-1xHa}vTx*t#cb33w+kOn-GQWKN ztC<E&hWQ7QCoB6UcxP|0*t+a5Q}`60iKx{*Q6t(&=gK|w_##GhFel~F<w&*k`I}Iq zga`{=%p!civ@pHXSQaKU3;wC}x;Qdk&U`>>*9$oGH48azR|zzZZZAzh36w)9YIGzb z(&?9A<kfoUzhgY8{%LOdXN;lSpc?~qhb5D^ulh*T=+CIFaeEuFO;q?BSf#FRw1q&k zm=0q@UGRW@h!zpo1tO4iwfa05gZqk5$hMP5C~=*K97=N!hgl4mWhOillm(JGIsx<_ zgiJ*3X9I8?#<iV(2@UDp1hFI1!Am_NTJqn)o<jcIOn(JPfwu1GlX;XK^f?xGLU<LF ztflhM5rdUxTtt<ZdVHahU=?!YBJPj4WgzE!Xx0QYFw>x)Cxj}k{uG#jRnu~{G8bma zXck$dZV}XlYJIL+&x84rG7fFj2Iq=s3YbPosnjfR()EC$8LGl^rO948AqOPz8ngBV zAhafzQ?BEbH3C-)c?QbNPRXP^2AK-9yZKF-WL#^CW)Sy=qh|47xW-L;Z^8zGT_zjT zP3@X#RC-PTm7~oiXw_!A2L;zc4N3y}vh~v>G6RdvP7i>Rv(jzKR)Le}!Hi-sMGM=E zTD3rq(`Lw54jJVM^d0C<rT9i!B*$M~L|0>h(3Gw3)UQYsw(Y{Ek#(y-sjfK8lxAH{ z`$#jY$)V7Tz%A;YSMYh@JU)Z_*|U#5kFh6Z&lBt!X3rz=q=N&R2KG}CtrnA}w=L|( zfAn;=zAAp;WdP))3=;e`YErA#UBQ)tBN-ewP-%9`^<L@(Ua0*8+VNvn1#m%t^hJhK z*{Z-EX6&bsH`tQEkH;<v;CjHN)G<o}DdZ5Y2Z+IMLvPr+9B0Kq9elM-P(x=B^H4W? zz6Q_MXTF4I;FK7c0r-?F2M~Z$pFa#QaeF4jwH=z5U$T7TIPu^i@nFkxm_n6q(KY~P z$$%{^9t=b_L6ko&660&t;M0)J5fOj*U+Ex_3WAw7fDU2LLHF)poy@v!59`uBtTXqp zPTqr^*}DO<K|Ko1m+n!hQMz5Bf;6Y9O3Hzd81&)Nd<fx%-g`&B`QAk%--ccruIaJw z7PKo0Mv_u`bK$$?@{RI5FrV~sCR^i<Vf6rFBZe*sBP9+#k5Rp!;vzm9{_lh{#Di~y zDufd{IrJWbBy|tAtT!U)#a?%9v6L12Z>(6>2fhEy3Z&N*$Vz#fm2$VVtmSf}RMB#I zt(4nxd7~J7SV*>qgRkBP5X`Ywo>-oU1WwgQtJgk)zoqx4k?;K8nYgHLEV*5t*7CSv zfjp@^nYCpk>o91WB{l|d8v}R=0dPej0q|!8SS<$L!S|zL;7xpg9~1?A%VOXFzBh@1 zJ@{TO2L3Azy9cQu6h!87i+c~b^+BdWDVrnOf=GF_(kv1}#tZF1%A+rW1aC8z>(vIr zV&FxP?pHxP0T8{_X*!|AR*O$jkc(pAF<k14dBmsw#$gZ#U!i4^1&C)k{0UW6V(=$0 z%e5TJ?+hX-qS>iazur+!I~&f>^ZoE-OIqslJ&ey^VB=T?F`aCzaQ(9PB?t~O0Wlx? zR}A9nz?gATxv|M|#%K~@w4hwl<kVNOkAZ4*Kns#ol77?!ShpDXEf03_u$;N`X%G%- z5F-hDb~5q9Z0D^!wiSB)eZUFY`dDE^3|tRoW1IgK6Tex7G+*4eIPPx5c7}r3WOpct zV!=)CbuiNdrluL4OwwT`(Ftvf<E;#^lfhx6o>9lDw+JdCX(K!U6S9L;@s78o1$y1s zcJXyi4I#8-eXj7($=H}i^cj(2m=yRJK6maIX|J0eLKV69EnLfwtrMRbVgvpWE)vHc z5x2j_;=e8aXaTBPu}7sJD6#KJbCuZl#o!B&Ho&TH(a{!gQRkt=XyCHtGIGZV&h*Y= zR4&B8EtfS-&z3Kl*N`9*-Wt^u74%QlG}<w}|A$Yqnp3YL18qwdF&IG}69d1(y~Q-* z<CRXK_Z^(Z$F*Gkw)}`rPON)t?d*GtNf!s(nDE#IDO(m1Mwi<<>I|q6&dLOCW@HQE z79}{0lSS_+bq`W1ITOv$3&!lW0UQ%S4Yp#^;<y^zKFX9DlgYqG8mmI@1c-fsfnW}g zTPs?g2YOf;F4}4*$N_AZayW0>r^sPazRomqZlXkwR<s(y$Lrv=wJiq_)o;srK*VE! zRw2;mGm=1#o8)ncF@Z*w>x}2=HKLxynu5cohHz4j7ASPR7}y(U<Q-6P%yDkmYe4oy zi0ip)#@xar!lMA$#sK)5j^NwKnXSQh7(L@WggXqqs0+fNS&*Uc#gaSufk?iTtM|-6 z1XLdJ^~LchkIeHNC^C!V7-@VCG^tagKvNy>Zk@E5cXX^DH+V)l#SOkc+PDNW>;Q^* zpTy)8+c|}eHP>t&Lk?3ECV>Z;9J-n`NM~ldY?{fC4#^kw=|p2fB^cgn!er?t!W#bE z{cews_J9qcMCL1(?CSH3Kw{+mEhZ!D&DQLt(E}mZ#lnut1Y#)nSY~w(W7LOm-<iDC zVxKR0HO9MyJv$8ZozaDNuYq`z)9H9i?k{9Scrq59%LLYrYXnv_?e3OhPD(}CuXR|x zBIN+`67={=WD|zPZl`qHuduhIbbY99istS%Bm;%f%-t!{I6aWB4<Gg#VY7DO^WE%; zu{s%;<w+V-?m~=vJ^p;U?rUb1X-own2SyV^AuN<`_&S+c0E1fp;^px^kAJ=nM{m|k zP!6ET;`IKO)&#>_zD4$onKt&Bv=Dx{{icwsA7t#a5U6xl(vOQ0QdXX8XOU9Aw&&SV zJgWQYSN+&In47DW_eAp)roCxEc5DRP2~6Gqu-b&;wmFHbgt+D>AfD(?;EM8slO||; z@Pi7dB)r7pY6+Wg+l;MjRz?>P5_+2T4H9+RiQW&Py?;lO)deD{jyKfX-dsW7k7`<1 z`;Li)PHxf-PHr*$y##+>!CxHy?z+**t%EfG1C7hkDt!cGrwy&Ikn0x-t2ALm`JMiJ zP>dflp%LNe6a%>Pw+ppfwP*)CL#;TUMCW%nc}@|u4rgkHx=HA87H}QTIT;<!>mXR% z;aq_Gh$IX1ZHr(IN2KZ48hi6wVju&l&2<9HMuUwMhnDjp-l4jB4l=;u%_(HK)78!R zaRuT-qp1m-%}c7gLuRIIs|F<%5y}tkU>Myv1|wyaz_qL@Xi1`^tSaV`IE^#D>p0YO zN&{oG6!UL>K58QDOL?T53u;@wOI$rf06jtSDwl?(nl>YFz`eT#IkQH~aq3H0B}DEf z9k@^Q$&AP+CgTEqTMROCstE?Ol5czg%#u*0*-ZmC>d1=$^k35|1*p1QarN-_=I+fu zwVfjuv4kR4fC<fuOf)Y{Elc^9Xj4Zezb$x9PW2Bgk7kheDz-u#{u;)t1ic|*3eazP zP?Hw<MsQo8E}VlMtHe@dEX5g3S7Jt)hfiS?t1oUybm<*{Q8WYLI!(jOx*IZz+tGm0 z*nn#}#ZWHT$K$THw!xI552qxTYH&5$HsI)xr_lq3#3pEB8P;VOS%x(dr)A8R-7Ytn z(<8>>T;o_{QF-YM%ru<Gza$hq4`1kQaIuGRX&jk+F5}qwY*I9<!FeN6O${+a@)@Qt zJpcBU5qpPO8*8>d6JxK?1@?OW2zvz&v)4;u_WCbm&0jpl7@D~FP&MDlYBGRiOxU9# zRKUpHab2tGWJpcoxo{^#7D*RGFnnn_%W=hrBWJXn2hcTxAr8am*1cEEFt~z0g;w7N z!_kN(XgN!|*=lJO4sdlGxjX(Ta<{%-T7;cOZ_G{X&D3e#kUbl-*Y*A`x!?hv3+5;P z<{9WtX+oKD>87TyLRFtDm&R?(_Gc}JKIh*&KOQ?jwE~$wyVh}JYIt@;2@7@Y^o7Z6 z>BzL-X)WX0A+DW<l2H|UlsU1gK>vzsG1WqiD$plznThn#*U;*m59567*s(^g*vYNd ziV}V{7IkfbB?Nzk-5#%xjrOgsxb07F^%1JcG2)6Rs7rOlLax5ms7V2ZRrjq{v+%RF zp`m^S`M9oT)En&BvBX9|uD-soUa%Emxjtg*aA_dc`kBW3xCOZ?i!9}h$8F|f`m0X> z@1<r^Dd^$nFzgZroctOwI1xouwI#HSs-8GmVa8p9>I=%yu+$K`n+x$P$dV_mp^7Ih zs;dt;-W3aWNmlY64cy9cP^lpp-t64En7Cr(4Ad&W)zS>Yy8yX+EDF~pQ1CJo?xYhL z3jKNu+W~QGakLA1cbom;_22E5Z%|6Nv%TK@MtoCcX3`l<B+CT9;eIU#<CVh#sW#K= zZ)Mxy_T^@2e52kYr^yj|qaIDFV``Q8T9khJ@zp3PAG19jQYAp^4$SAcKj7flJ!Ua* zKYS#LJxbq!q~1I&x!mTn4dANi9IPr<8`R|M?Wqp{*>0HO)i)bLPvRbfLyt6qXdr#K zVD$#+Y#3S5heB}qm+gePQn4i5G5?3lYQLteL`f@joDivbc9&WD2TO~5qclsRz&W;2 z)SyJmKU(4ey+pscaTCtSr_tP&h2VfBE2RM#MWbBq=jmiVu}R>ici3>P(ba=4dtNtP zj=_<2_Dr_U-owdv08Y^i$eC)y)pRd(VUctLit$yt#F<F*u&O>SXC=xRdTa>os#^Lp zh;8><8lOdMTyb2QSL=HG2KvufkXje_8ynQ-ZbvElk~I6sVC0h&<}_mLu;)q@gd1?0 z6-ji{H%b#uHb%|WqiEL6a~T-nO}b}91ysvov;`)51vd+H-;+Gk;^@C#>jYz9SQ+RY zDI@zp9$Z5tm1c6J<wK+GT+5{t+4(C0byhoYvyUt+jKM5E&*%2ihb}?sZu)5j+t6@y z$|B?ogdY=??kj4gIhv*{HRmfwwFbzjtl?qqt|#p)#%w7C2jp}wMd?)=y~Rs6qlCj9 zES$_{;CihSs<nD)EQaRt3Kzf)o~fN0PAu^Ht&RJ!I|sn5MRlu3Z9Wf;sldj7@`d{X z-45oQBZd^HgmpxSf7xCv)h9aC3(c7PXWUb;ow`e17Eko$%cROY5K*LC?8^jsoSWW* zm|>?+hfa@9wl@p1bs&<0<8ezONj9dt&O@yfZMw>6zy|czofwFh!M<gcv?m8(JR>N< z0D~YIiR(Pwcv&Bb|KixzoPo~3a&dbF*x~i%xG-Mw^%5)Yi%bvkUsu7GTFmqfZNAc( zOPgmV6b^HxGF-6v6lfC-_3cUlgGBw}E24SGG^7siL5zcu1jS~8vV}KDSw8KwkDdTx zP_6^w>JYXKH|BuucAh~tuwB7)gp`eL?eu8+C-o~vv<+>+pAb0dngfj2jbroRB^;Z@ zFgUhz_G!o}axQ%ZraS+1nv$E`)^UG?y#o{xTEGytPnUSo8U3C=m!{+12Z=d`WRXUI z4mvqATZ@j?_%moNr!$Xzx;&3{hL1}5dPm5Ud~}%Yn~;%Qz;V$`bzwBkM?V@GvyGNy zhrh*e5Hjf8MBgVguaMp}Wg#a|aMM{jm4aR|j#m5?cX)0e@s@&C16^@+b&O5hHqCK- z!_EHg<+f9UUpZXnsbQx)gANTQ@$un5stlr*WwnKS-$9H1H`QkHl`0F4LD^^<sAO_N z8SdWrXi{+9t8|FUCw;1n`_Ycnbr8An4iHI85HX-Y6q{AI>(VUQ!Uk+%U6120(l|)= zd8p|eQ|%mokstE<g`^N$jY`oOh+JYXZGjlc=A}QG!E_-p*u?gQENEG{wPX`|UAPtx zv~C6rP@}7DhwNDlPBQ5*q@6wsZER<H1P>UJW}HGJy=iO2FT+tG;dr`ZjkpzJwl22d zBOf30@!`aW8y~Ciu`cvFuF>2rpCC{YOy#<p1QzQOo+B~a<-*I#ry{;!&L{yzgPc_U zx>a4)?|4HRU-(9io32L%8>VrWK$i6fPf0GL%Tjm<6b)OLG{;DF|Hc2nt^S(_|Dtq4 z!F?DF824dxAB-zmW-%TqJaNCDtD#$1SvV94bbto(kp@-`KmtrHYs9&cPFD}Jw`SvJ z97niPm~g{VM(H$s8ExVAgz~RE(!-7H!1d5?K@mwuj9gpT1B$!q>IXbMzgSL=6ydoX z_w&Dau<)cbqvm;ASo}9kt)uF)3u<*Ab2o>mWsoPfV$c<bATMRpl^R=IONA;?j;`ox zr_VvuF7$H)Omx=^HVfF!`5YIeRC}FyV?K3(q3oYn%RE4UJ_UM=S>IOD!JI>3z=7J^ zrO9pFo$b;De@cVB*(^SZJL|2c$_~?=m89BAB95byvv{&p0=5eD)-p2)hPdPM`p4QV ztrIJq#kn$d*U$?f_S=AoOKy=YB`YQKVn?%iy_cO3VcA@{P|^6P9>1_nXw7C>`*ioC z>)V7ok4iIJF5N8UGKjnm)6JC$Xv-)xhBu6Zacj+`jnEeVtlsI+53SS3dKfYP8v*@q zJ^_Xi_o8Ok-?q#ec)&1Cp3e5x#{*#y6+LgzlV-Ndg1s7K!|MEd9yorUZM%bh!}?u0 zY^l2{!OzicSI2WBZg0riA1`7C-&Ka)u9s)Qe312PeCF)N=d>5`S@Z%vOMd~+HQRHJ zuvgY=>^1FK_DX%4z2@v-ubZ~R>laU@hG(I<&Fy-Hz4=}H;T-~t@-T*j-7ryfrgHF& zCfiO--1W-LGOjaqH$2nPPD}muOiWFfoGLTmb_Uqz`4PKqS8OKwDAV5n``4l?2byq= zZ!_l>G~kp{1mK`c43r>DWBRogTvz)|FGBmJSqkN)Nea!9%vFq`_VakCW&e2g<OO_= z<C!__^^v|tg8^4)LX~+wHywHhBv@G7cZ5XLEj;ciZ!t$cv}8s?TP*+ipa1zPPIb)3 zKCket*D+(8)zE5j-X{-+o}323gB*(!Aa1EV*ifGwn7q`hwr72zAia#n=>}fQX$0I~ z$9%YOF~lac)<7yUzSGg!)ZZ5T0zf;07?B?cOE-s}|MD`@-w|=I(Q#zs#KMTv9eO$o z)BXAP)8coS5GrpomIuP}8R*Lm=1?#WS)evI)Qo^`=D6_~Xi>Iv9*Bonkk`JEWFKVm z&<D$ryebj^@v#7GSA_u;F`xqMwe2pfW*}mavRjszrdisyr(&_uai|~VU{pRvK|!tC zP1s#gp(DUP@T5W0!Khd7#m-<4l=DlrvwH*kCePqA6v)P8<B8CN`O47bjpmjm*-*>L zmP7ebQMo*MV>U+QL&RtKt(K^<gX78^$D0n}+8rAAGtQuK4?@|ALiuPPOoq>9piQxp zdF3r$CrwkfuH~djWMd=fqk=!5e(!x$IXdV^eW(s((Tjtq;(;g!5LNDR6fxJn+rgNa z0!GL>UGW!nok&Xa(jQ(#ts8;V#f^kPLpA_iJGu}^@tA1zM?~&{3ic0-=o=t#JTN>c zaisUabeMLm0H|+xSf1XQil5kTTFxdYsJJdJxe}r!TA~bJk;jh(kpLumP8p7)t6v{+ z@}r5-!<aV>3~090*)b~Y^1ta$;A6fAFs%-#&4OcC&W721AKEYB-skaD2c9CZ?|*hO z`d9rJYX++%JiinVd^UZ$O`}(ElVY6#UEX@x_iEhc+SdsTyqWbJ*t&Qg#6^Js8DC(O z4bPb%uZ7C<&>A}h6`r~a*P<Th)%9lkGAce9gDP5@zkni-;}V4YWm|TjOAMgbvADMq zn5C=t|8Q3oGwu|sWj#>Lce>_-aS;0LZhdT`H?~!xuk>7T??UwTfG+E9Yk3+Hg$l<s zD9y0g5!>(?XaSX#EuaRTgmKec-Jl68&D}f{(9}yh0kzI@w3ImdZO|_LCbirgDz}8x zUqCqzt|7OUtx@NfIi2^&7s*BX9`5(<15#*NVw}c19gz(KQ1%wwFj#;aALY|u9mWO< zg7a?q5-I2Dcr+!;&8kO;8rAheLS*TZ>T#4*(cShU9Ah!Ke3-2uj;vo#d51B9wQ&_P zLC5EiTHUSDr_zuSz-po>lu1J)j5n2W0S*+)a$XGha2W6;6n)}L<cTxEb7G(pB42IA zIe%j#8M^qAGMn?@#Dp6!wV-r%qq2zF29eKe8yZJAWE`n%EY*3$O&{(<WwpN1LrRe= zwD$%o*QJQT&v26~6*<!&2LFsc)>%~QPqJS*zw11-kCY3$y4l;jtET|97SME+SZcFn z4OvodS)-a=Cm`Axr7Wcs37|QvZAorkYisKyOz71UkQ<soV&$TQX>Hw+i)o)|jAKX8 zp1?SH1o8jCj!>szoJV^v$<4UU7M%~se*QOP<>(x=2=liM>A5^q!d%pF0o7()wvF<* z91c`Qw?JIGQu=Zs^UC#Kp<d?Tmx>VvHZhE~%b$D=qd+ffm%d+GH4O@HBu~DKPUh`W zy**cckUY6x4^4s)SSv$c0D5~d7yWq|bFh8#m8$^W9|b640NP$Gj~*J0-}eQx&YleG z87m;8lRSACLN_6ay6Hay0D1Bld^6R&u+vQy7Ih*Kl38JxpZdRGx=rZd+ejg4rLB3; zh)MQm5i1$&>8YUJXm`+ZR%d97yVE70W5Twru^m7a(m0X^C}aW(Fc#Ah$leeK9c(c_ z8l8sGpt)<+g52q)F(CKah7rFh=*S`@IUjJdPkWdA5Sxqoni~WA#|B;*8wigELJcEm zJ+7mbPK=2(<?%S~B$e~Ya67{T3cv=ZVv!I#iVmU?)WiTTP#|hZb^q7Us$W4m8|vDF znsf)A>+_QNjzMXzPc5bqq)M3arh2K1Ik$1OIORP%MW6C&k@rbwJs2`L*S4UTY3K#U zn8(iK>2q!6I?&U$z+9V0b1-_{+Qfu=<&-|*Hud6!Yo<^1B{)7*xt5fompy%yty=e7 z#cvS+ZDw*w?nx{vX+;5mCPghMQ{II(%-q>BRd+v|<kl0lceN9cAdnV3q7l9Rp!AWG z^CsP?<xDSKcuHS~%57Zz(OA!Ffq7PgYy_hLjeU;(aCD*I|6A4Z|Do#klgX-g{J&ML z<pdy}9TG^?tL0$5qz`&@s#au~16}rrzF{x|(24*Z_3a~QO$4-Z5z@gt#7`($m;!ow zB0U@G-;R2C7Av6l55Pz;xG&(~KJlrhU4uT50gvdzFoCG*tX#RH*U919&lW4Rpg`|T zG7Vd#omQX3-e;}UU@nC)c8R)WUB{DXN|kp!c`v$5bXGQ^2nE6Vy)P0p!KRe4n$$v^ zCd{<@3w`;6xXfzhT3n#niIfB1+J?1krE_GxCkF*lDzu;-&;wkd_#zY%NPF`>Pp-S^ zOSoDQb_$8nA7j=NtcRC2;<hbVCBLP()?15=ai>>@)QYUwrMQh%%SJob&w1&ekbP>k zoTsrnm-3owil%#MJ<xltZ2)T80r7YypZQa7MTM)6@rH$dc%1P@eY;<1Jc2zhe3Dqo z76YgOk;(#eWdP*{3nP{D^pH^xEzm<>Qx+=GL!as)rye@1hbr{YQ9V?phYskWm8Ce8 z81ZY2fbQzPkerjZG=j94;v1s}Yx<<;qg&~iKKJRP^zRq+IOf=}Wi8~L?V}ejqpLGx zbji9+V?xEOEaGG+M2n3nWIBhwLf2!t)b+8ZAqTMG+Yn`=2H$4tk0wX(n*{psTWmEE z1#Ug=LKPu3Hikc9GPm&+eD5;PK~8Pl%>ouZ@B#~1SwJa82*`^JwF?<Yny8c_ASY!h zrB?QV2Q~|KB2Tg+b|N2jreemY?{k7-j!-PG&dR$IJSPTl7S$QpjZ#Dm{1J)unG?8S zjM?dgA^b!DhAB0&Fe{I-J$9zf*9>3!(PcK_vdZYMd)ea8BaN*!NZPD`(ji8wyOLs| zDoNd^KOUj(1y@sd#!!;Fry_NKI&>{{<Kj{p{mBs82}z3>_Yl!7xth}F-hh(pgiyJG z>0ld0;-dQLC2=3WJSwYoLZn#`&?o?b$M)OZ^xr2Wmbk~axdeYot1H%8cd5g58PBZR zx?1aE9j;4U8I<HVXzQ%nIv&r2)`VO!cL?L$bj$5%wdUg?mSR^w8bEz$0NKJ(tGLe< zpY1ZYH21Uhnm#nDM$RFj_qdm?@5UL(Oe)Q_yPuFJ(FK1+We%5)**3=!t@jpa%5JBW zMJKbQSvW_11lHVcgEUdC=XYDgzz>n^mkLVvu$rw_Vqr@6m&%b8_y!2IF8(X#4nL2s zZBIDQOJ=&NJ?S`~g{ww_ML&!H<UHMpTOyTav^spccPJh>TNtV`sM%y`Zei?h$B?>| z-!jdIr`~9Ze)a^+yJ)p?Bp+(Ut(M0~wHX~UrlLc}L=sWDXONST%ew3JGgqC)=JO@1 zKgHvzp=}^`XCDH>LXw#SwYF6YtwMAnNK{|QC9vw=yfImwy*VzWC;BNWB*(O2MSZf5 zYrx(VaIb^;%{cO|w4yLb$Mr!)o7D6LJVa$9G}CXS?>pHRm_ZCI&?CB>dXE72Z6A-O zLtrWzoI_}Yh=DSkXx4!M`=b@K4$tfPK*2t`qd0keL6&}|{Ou3edM3Lu<)D2Io&)DP zQcJHZLu=ZqOOWdtmqR&?Ln$bRmX4GlCSBuq=w$#$WOJMoa4gwS?4|Fc!~7QxV~5}P z>VmmtT;l^!Na2whH}&4Z*7Bf;akc>+jcUD!Xo_v1(G74OA6<9*HK^X8!w^?oTkxmt z&`|(%@3laDqCJ*;1J^hgO7hX-h5AXs+x-0r50^8J52ONRNRwvxImRgqu3&lE?Q{+x zUF+6v_h>oK;^c%&qR`d#i}b#iav)HXI2JP_(eLuaM(lEW0|;w<V`m1N_eK_#eTf56 zZw#P}!sAeAe#Yq^26Rc|7!;pCMVNe0_?J*Quf+JKjXqkmh@I^(=W89Y^;P?s8&hn3 z3h6X<Iy##~AhkGM|6$@R*~HLd3&c8EY+WK&x-~MC0*!l?zVkK2>_Q~i5zw!3cUI}( zz4SGfz)*4twYY|xSOxa_c~DV1yAeY#eMa|>V<j+Xn5I+xxy$R@mFqY>k&l-w;57XZ zbU)p3MBf9zx?;n+ZglOYQ!@az)9)WiF7+eqJ^(;pq`@<_RcI%8_jmU@xr6xdk(i@n zy-3m$C-pjc$8ghEOvZZmQ-q@b3zW~Mh4wk~*eG}OGjGsZ=mc$U69s@{$uszg6I2F? z$J2GBti%}ER?JRMeQ7(DI6qaDD?WXQ9IE?<zX)!JRFxQyi2KT{9<R9X2PWGoU#LRJ z4GwIWN}A22%Ivt*lunil#<Py0ri{Ck@Lb2cO_cTeRmJJ$`G*@VgTQ&r-(@H67P;}B zq7f&TnC(yQ5swy?c~Rk)emd$#ww#WZ&oaR4CUy!;PjTxTL6G7g&VmS?F?d4hHY9go z#`wkPP9yqJDueA5+rME=ALFuR3x6{QC~flrZ|XS@Bc6{`?%V{mO=LuIBARx!(-$2q z0iIb4u<ebdD<IqTxRSUFWk!2aPI~F8uXXiMUx^{!l{=-pGG@+_H#~N`lugcj=bTxI zn2ql{jy8Sqov_(>$Z=%7V7JRWi6nL>GN9{Wx=9?Z#T95}C{;G2Yaig$`x%P>LHYrk zuvV$nF_<LOrK?C4uUrzuAR443s}U+DrEBqd(s;@7UUR{By3AzDN@cZOfCQF24U_LO z{sj<noZkFbQWqzn`K>Pf5p<!P-dVXC89rKHx+59hhT)~9KTd`N7+zTV(`1-kg>Z9e zC>eeN!_!NjN`{}raCYfWFq{VAHq@v#to94q=~{Km>S!7^vPL^iT(MfUauv)-D;kpX z5W3A3LwD~g!G{wc6?4nR+-gCxu(Q2(H!q3gtM3e$jk2JG&5n+y3($09wNUSftWU+{ z6l5E%2+N@Ff5ohe{6;qtL*@G;{t9Pc)>DQuw=R)#NV`9!wlE^if<FQNRu@L(3cCIx zF21tks4}~W<sqD&5XGJNh_2E$t|X^v9Wxn}4uP1W50Z9;ic*O}O;TYM7~5@Ulgm!Y zdCGEDpJe{~AfmSuAJK^ivCTX25zRP=t=@@`#MY&oPW+0UF|4(PmF8}sj582xcXi8Y zFcBR3lcw2SJ!m0xbfZlZMjyi=LCS!}NvX;ZFHa@+0TsQiE?x!kvXk7mTCG0Oxp?(< zMrne4vrbKF^?8!T2r37I#y9NM=bI;!>hnlgzLjdlI6-rrkDjAj`q+VmF%}(`GDF+A z+M_M&u8mHHo+Zs^&}&D+J+%k^f<wU4u10JeaV4=b5!VTI@oHO`(lbeMj1;ltDiYYW z{OaIJ7W7*h*WutkdL}9I&Ftj!3ov<t)Q{eh*!qPov~`tEV)7$GBFO#Qn!7O!#*3g^ zg4b*Vueb`CRim|QMHrx)ztk5EM7Bs!o7mi~YiDvhNw?g#V&>&`qq50jlnaQ{TAH8w z)5%g!=}dfOm(IdhS}Esz4v*fJGu0jMA!t0<;7shzv9(B?KkRJ162ZXMB1JDG=D~yC z0yC-2RFc0@z)dSK?g~m~$?3K(u(zPGm&CncpuLZDYz>u_(bE8$R@r6>gypZ9`I}q_ zO{Kk`X_}W5;b~c@5U+AU>VE;oxujGwEcVg>dM)DxVl4Y-etxl!&OD3UQd_H*=Hl&Z znsihz!4tj9OFii2cBZ^#VQH;&tKZ<E7tgQ-Yn&sOdOdF1eDgOHy4T-ki~>`n@ggq# zzpAnF=!?iebMTW>t_Q>J#gWz8S`a3{_E<mN!k}^)6zIJ@x(FxL7LP6LRny4d$TD*$ zu1*6Z2~s-B0++z66M%VI7S56_wy@n5|NSiS>2M{g>?K-S@RTI9nOalsQkR+Ari**q z-Iet95A_b6przq)QxNUd<~Eb&GPfEkp#rEba89~SX^wO9uUdxkrPP+8borN165nx` z#v!dj%fvu0pn+p2@g?c9sWN(TY4jtOfQz{77;QS<1B3`#G=uG2xveXjQd!oraHVt! zvAu2}VgOALcf8G^N<&NWESPTkqFJ`E?Hn`%Z|`%(Pxc18r15vN%2QU}1r6$wzrwb_ z7)r|+jsl=?Z%MkeICxGf6%U5p06d$%->o+?tIY(>(;KIyjkYwJMfW8@jF13H%gmL% zUi5W1C8c$waM)v*!P1+}*h;8hfv`$Grx`}}zs&3g8T+&Zbw5Huk7f2iBk-Bm(>iS} zbCW@9U?&p2S~M317jHR%wiV~fMpcfJWpUJ`J)Tf=Kg~dwVHf%@mO`zI*55;_`@z&& ze;0{GK1~Vnq9f9DyPFog%k*EzMd^k_cH^+miv@IDNfuDG3$OH2i|~3cFj>*nanw&? z=Q=<P@duW91y_)5=g=KPzFB)0eWxUIXDUMIPAK}qmJ-_}XZTZ=@4|#=s$K#ZRY9D8 z(cMbV%Jc)g5|(tXvCojQoz6A(T=|mz`Wq>F8H)0FJcXT}lQE~;=kchne(hb=6@y;6 z#ZB*dhiScdBh5??nEx@*%liQe*EUc>#%b-l2mx9_UEHVT{2Hy2_UK9_mLl=cfG4z^ z-E3jgaZwDQ2U78LDFgjChVU^^*x__TUG$^38RG-GX0Mj>BIIC>Nl>5HNB={&dJ_rg z7@F)hWH6W<fHoWPbd+1m*^i4c=nRDyZlMTu?n1Atk^4|AOyN`>i803U_+DT7iSv(t z#G8>Fol;h?T}mH3u?rm?qN}_(j#|z!tW%EL<d~Lo1chjyzEFbi!|aV$xoA0Igmd-V zTz$4a$Do{c@IELxni;$(r;(0Gw<WVrWuDiA@2W*uL4CuDQKbd_phdd#WO7LYML#<+ zuvu`ha~w^1RDsmQ$pHkRnI{u|XVEFi!`4JU`~il)c(B62E8Wiex^}(AM+~+ud+H|W z8GYUw)z6m{@PiR{t5iXoL5bi#>QX&I{*qmWobc~T-Un%5S4br;kWwOv>!T<si$l)a z0zFc}uh<1r6Mlt?o0JlLGgPKwErpTxP}%Uv*Oig4c;ahh2OU>zZ0A5Fwm2@zR>#l= zi+)2*ikb`5%q&b6HY$RK&NkZC4O8jEC(y%b<Zhx1#}ocdQ7;|@tnQ;9?PKoR_T^SF z_zNgw4RKjtMKgDeBeLOkU|tbw%Jg}>bocL>l}Ifoa6oQk%gyjfIDO+?-?V3B2)S-^ z3~ii8KR%8wNF%j>Pp=)|#lT~lE(2DryVCnzbWt+t*qb^TLo=8;V_+uZ{&BUr#^dw) z4WVjljYq9BYwLI|2bmQzTJ3daF<7skEpQx_4ycCct4XQwPht=cEg-+)F%`#<_+$gT zu~{d7$C}l9U(yx*8rP)F>{1ZxD6=H)F8YtX%y&w-%2R3%9wPm_4pPiqel>9q(J?Px zx0)H2=fWUc;M<JOl;jNFO9t;g(muEv;*XFHd>c<j7sK~Th{0>!0On-x$#W+^J9#Fv zOYR@MNcsTE3J?_qmcdVqC!4Yz0Jl+S5*+}$A$@5fBussvz-l`OUjlrY2j3q&qrA_N zH^^yn7VD`$WZ{%KEqGLb-G}P+L0yQM6|W>+cE7u(rt#%RN6uv=Zx)5(R;zOu2UHZy z2lES{=h-Hcb!KIF80^mn3Kl4rhe7E5ZNtr>1sg&ue{Ug~YL!`eoaf|Y%!`4P3pC|c zj$^m1V!#T4=*z30Vr-@y&TT-4T;#_x9=8FR3!r3U_efR=wj*@>9u0c9F;`m$^kC7} zS?NOEeX)+gKr_^o{m8lP%h)ZJH)ub|(|(Yv{a`N5NdSUIxXkPGkk4>lx1GWTJMH8O z=Dq(J`HDpR2HG$m1rVfmLAs`W!Zuxfc#BM<&+p`F=+A06j@kLk$l3zo{u<B|t@M?| zg)@f)yr^;q>eAERL|wWE*Z3Vp%+Ga}pQo$ePV7B+=|h=UySXOURBm_^HxhZ;aC&rq z4hm6*yTu>k>Vd~cN>?)vGZgjck~|alwx-kXN0Td82lgWU?L^@Zv!a|G9FTaB1?bi1 zj^^Q!uS`%W6TZL`K|eKA>VCPSX9C_se+l_!zq#I?%DicFkg)ISPiX6aQ19c2^=C)% zL=XLly&6dSim25~ry>|Vest91xt<vrFJs5>$JqKgl%9?2tWyz<-eX81GTwS<_D~~k z8};tP!(qDHuo(QQK|ht)!@8jjmri*)>9oFU=ApMUw|Q4L`uF}TssMVA-;J7aZdy_^ zPDLN;A}{?kUGI6A^{yx7@hUKYQ%DD1`_)751Uc`apWuF;s~d8gQy6jLjYm~5vzcrI zm8xtW@nXhR!BO{Pz0CY;%lu?Ehh8S#^mYBbTXMv2X3A+dC*L||2(VDk=+TU~*;&5m zc<3DHG-!0yNk$gUJz$pvUq|&@_jaD=r7!-CjgA;Rg*W23-vGO|xm#X4dZ1&d3p>md zZNR)Zlh8sPNNUsvD*6M4$u|)I3*MU`gauye&?}N=z-VlE(@P66O#jj~I^Oi*H*jU} z7)15r(Fn*tksj<Cd%EO%UF>uT>5QIAEZd<5>o~e$uD{!MYB@TcTh`}M6~Gc#w_(wA zTvu}DFB5-LZ2<xH6<(Q`$!-h7lZ)gGUcg5~S9Eg<3@NMQgY}lei$L7Qzj)}8U+YfK zouhsXV7>#n>|6_v?{ry>N224%GNI6I-gX&(0iY>e30pzejgHu)Fgu_pb(sa{Y9ARc zd<-Ze9{Exv#~<zD@%o1Ch6*Ghm@~5PR;%M+UWmcdkl+dB-AX2?%le5ot}cs_W&JR{ z4IDDaQsgp!k8*j@2BUw`gXCV`ajziXh1+K>%H{m^lgS&WqoE}!{NU-CEB99nr^~Ye zftiz|d7*o{M^b*VAN^V&(S(V$JgGAik3d%Nq&jY_?pGh=(WHXs{etQd04>}p8B=Rr zO!>&5*7b|Qr_lFBjzLUhi1#l7n!LB(@xg`^@`15Brssm}j&~vEUB~-UJ>D<(1K#li zL3SKuI1lBopG1zH{$lXmnG)c;#K_At5vg0FQ$qK4v-nqZY%z)9`vabpB9OazyrPhm zNbVNYr2=$v)QARVb3d3^j`tIrMb&*F^GQ+*&;ss10rXOM3h;C+735WI&?&9e;&7xD zKClz#v^0yHoK4<f-Fi9-m8MT-->i2l_E)6mMsHw17U<S7P_;aS|G>hZg#rxkbkNG; zs!6Sw9|yHc6U5*}oG&*s?OR`9B3Ya9;BL`txJ`@4fg&G@#wzn4QFrjvfQ7=+S(ZfE z>284qiPNGdDlfJk=91+?>~K}N{#j*dd90k1)0I{HFpE((37Y%}@-0k{@3JVEC9gi> zl^}CW12QK$NbiM5LQBS7s0meBYuxnnLZ)2eDSQU%NJZEUyz*Va%D7{f#LhAcyD(lY zMHJck<IYX+1?C%O@`3TzCofRKmhXhEZmkIO`Nm2UM<=^fYm<_Sxh#6FU5xn#tVRak zc(@EN!n;bgR^k9vK&ro~j7~q_$mO%eaSL8gc!s6m`K|HV28(ZOYok9`mI|7>P~F07 zsaOT6w1CP?I+A<3H8qTh1<<&EU;(2uYBYw+gW={&r2Ww_<Kn=4<YJ(ISL{L6DX30f z2@Chg{eGSdF{3N;sc3x6+=wHZKn8s`aIpsu4}^Zktpg#jEbh3xv7Ee7cs$Z;4lTBn zDOE8|X}y5wpF%t0@KP=C{t~38Gv0?mH{aPp;R6GySkK+^QLwE+M@~i0lhA!;wTf5E zgwQ?kA*f}%vie^un7hhr|BCd|R$1P5WH=HC;|YPK<+3q-6VFHtSn{*MQ#0KHX&-w| zz^qF%G(9Xn+~Ihyum&XBq{wF?dE*+1)=%z>!!&ib<EzkSdz{Qrt1Vyvi$7WhsRQjG z=I~Ir@hqs|PdV6G*?8m<4>B;OTw1ij<X=>a%kd4oqd}0%b@_HFfBh8Xvsh?}feE-B zDB!Ns1>6iJ(mgiu7dx(zarX&Onu;Gh*(#`yfue3He9KTB#|0VjM=v2GHplVEj>g{? zT5@Y#(U`bvAa(trydkyD0s<2A*ICqBLA{qpiE^(1Pe-jF``VVIffSj5QY4L6wEXpX zEzJ{9iX0y+MM4!jD#-C@K1;KN?z={K1Q^l~o#b;1Tic3<DsGFbg1W>I2l=)PSDw_n z;%dchvECBYcf!5J=x-dty?K!3H$cft4eGt|&`MhzMk+GQFNN6yB9vj)r1}9@90q_1 zM>&qk$pq*e$9*Fc$}mnSZ-K~@Ov(Pv9-UB@vI)iXcRL#<6zK1bOxSJ|pj4E%vc)LJ zRUMy^3ak4==C8<O*p=w^40-Q`r;wQ0pj%Bz;cVg&p}d4}e(QDCMPFji*;%)~h26?z z^3v`xiI0tR>(VjZ>awUtwIVmpju4I#xOFEJ0M!DBBx5Q{7$q`E`LGWrXrNBd-9Uq0 zUvsANmUj9Jr8=fXvw-ZBH#FP8>CbSQ&SG-!Ea(Luo;YSNi_IR+d{53$+O2Ax;5gGn z9cSdNWEvLyKfs&?n6vVVD40Y7HzsEv<h(VJGySTxvygUH&Y>^hae^}{)0lBRD;?Dc zdM7(tc&|k@kaCMstVtiM(-@NF7GeRBqg)2Phiqp(L^kiJm|czd9G7okj!$~WRaFps z63=YS6(>K&?J6b0M?Xbr^G(iQvZKPL&3;QBpC}j#_2)N$-0WH$>;kz7AP-#PNk$>) zJzpir0oZ*DQiNkr3@|(J9^P?}Ag=^oV$|4t9XXDS5)W-I2AWgrF3eupTA{+<uqfL| z^#z#tXJ$s{0r%)&+u4+;L(iN%EJ6-B6E{q%FU-7`Pbdm8s7E0G#H)|-P$Bsz6bxb@ z#MFi)W!@vG08oPfYK@S<t6rzf%;5-7B@$=z?3U(CPR?Yc2VC=Ix?>EH#?v>qR-n=V zAX%dXn*KQIT%p%m69meXqSIfb-vNRw*d=AE8S0X8$n+o!<v!y{<ZFn!4cNM$WQQIz zs0)K#@)XB3oM)lCLDypXfSjhx!6^M6_|RSaD3LQCYnXeLqZ-&Ld9>!Brm-`ciMuw= z9$<QNW_$Fmfl9L?-QlH24&gS%8G3jwx`f>K8Xi=RUZ1!Fr#Tf$0%ESrgK0Md)b$A3 z4qNinEoL@(u)~5U(4ey&M3?*?+(X8D!eOAF3B!aujlOjtxp$`@7WL{V;C6x;uUVAL zSQwbRw?hf-UYhxWZqIqyuJ>5mm>oEIhh5cK`@)D>yuW7(G_3f>u}77N%j~rcsKEsv z<Lw^B>^UEvcG<$Xr`H75VTXJ@tvJ98*BcLvEG)8a`rT_u9D5I%n6cd~kj_XfHI%r> z#iakffw8k~c|pp#6GQ5rxlnxT^Vh?(Whe!AC=Bv^n1lvT;-<oN^c<837|o}zzjk$1 zi}k8{%b_0Toiq+F1=d%P9-ge<H4UHde5PA<f#-o4iD{rBjc*YHJMdrw!KHWST3eUB z${Gsh0S4mJ5jQbu3)0k3{>OM$tvhijWfi~!9E+8Nz&SDC#sg6~=TR?wp7j<hz!p}6 zCD>msi}>VSsd!mQ#m9I{7q%||w&l0+z*r_>t+s_*E@j~6NDzx9&?(BMVou6wb1!IJ z*56wFHQuh{Pr+N3qW6jiBX0WM1>JJIlZ3F&!lTA&3&?865%I~FP}NEa1)U$`9cQ#; zuKw#MvBZsg<r+gII@NFR=s;lFkAVsC`WCT2HB{YS<2Qst2vg(M_F%ITx%E{<-2q`G zWbkt#)>^k0aU?-(6yc!zbjKm=xEt^eJ(ih-kdTZK`<@ckT}WKw_8h!x?f|x*69agf zbfiqcVN9VNuKuj63O<2%<Q+grgSh=T1hgQQud#C3I&X<V;!9HGnc_a1t!s@k3|$>5 zFIN~cDe4|<pFYe9!22~8N9W7|GkA@Ib&?ot#ClkvDG5BK8~j<z-6~6`v4XL{4u(fD z!(%?X;lpBQ^@&eh0)x8udh~tIZkwRPv_2p%AlYh#SlpX!MEXJ!08$3}d>x5Z=R!6R zKyg9biAhjbHBeW+5r3jYrz8@>XyqlWiYsKa5einp(@||%Zzs=`FpTioHomOoa)xZt z@$2BSochqVS`r`I4zQ7)z;R87$Qiwq!ZSE3^Keu=dW_B`qoZ*b!xte8tZ9yRar>Pt z4l6BWEpY%(Jb@?Gd+}J2&KSV*V(=s`!(fxDQ^q!_f;Fk+?=`8CJi}7;u@v`>FDqN4 zK(i()tXV1ktQBk2T&GiE)u$w0YgCKVxsB1xFt%^cKi<A?8NS)R2MtNm9@D->*gpKt zMb@Cr2=dK_AfHxU(zJSPONrhVXoO)8ei+|kP07~VVC*n3e$k)M0%M2Xg54nYnqEiO z!Nz6ylXIcIDDZ12gyj}S*j<!v5^;MQ@#tNGanCqD5CcC;Fd1tuX)o+>hXO^I`R_5X zWH#<WK*tALk4DY<+LKQC5VLY@>ve`^eUO1yx-Eh_LYNhQenH!VAlm$qVsrG)R9?cO zI6d#x<tqm;j+56a2N;ZWlRvfI&Nx)I(%<b(Zg<f??8TWVx+uZD2XXN>dTWA+n7nsN zqRvY##Z#E=TtJ&x{yfb8Pw=Vavt4>KVTcqmB5GK{?ue?VXP###=q!zWI9&(!vMprX zb(=~T>Urtx5p<HqD@^2_BO7otX$~S;Oo#R);S%>h?9rWZy4bHEh4R=I9O={VJ|mgp z!6moy%7+H&bvLya=vSK%<3PoH-XKjJ-Fvw?rr*`&>WNOI&yG|<U)Y0{qHb~RA~_G} zuwOt@3fP?^mPShq+O~VoNZTgR`}T}&(|=%_&N<pg+BAjUJOaQL80p?u^v0af8&h(1 zV?=07Hfv0Wo35R$U*18|1}aR@m|GE-?pe(3G^ZzVBql)(F1(DruE$>2BTc4nzQT@i zsseral@av*P6KD}Ni^`^W{+HNqo1$E-yzAPO|OhBi!x>6^6!(&qJCVIbX=6D(52VF zysN`RQ|+?Qgk-dkxwQAuj-Mk^{h><DUMom>Rd$!KF+<#I8K}sZ#>;*9b4$?f!mpN+ zj<K77Bf96vWlYPovDfi~-Gx30ptj+U*Wh-h1%HkMCj8z{L9Qh4XP8c3`u$bAmpA`D zc{@WG<q+iMTc=06*p}#!JiT=~m9EZk<#)O!g+I>5_B$`oi~o|??-b-5;5VO!Zt%M@ z^dE-7pUqO5tr}Y49kSRawhGS0cOI2y+#_F%P8kUb_eiN)wN?HCQ82dVIvuCQAZ`H` z&%oQ!tp>R$w28TV4>wH@xh}YgD=zNk-1Nl3gzK)LRmbgeeEnbX2XNxM!8mW{^s40t z@u#O^h7EUyHk*dkW-F92Q!m5H%Gf@p469wXLK!YIIbK+8#q;WX>x?Mhy3(W-*TwKK zKtFDt`rXUfZ{9!$d46}*j_mp0CU#^;fk{VnH91oFmU1a&b9HD_0)^>gQAqzL3eXJe zZiAH9I)nB>ndFH7#^tI3%bkSYA$XiSdu%ON{o;)aomIyxRM=Mh=Rb2C9(T+IG9UfH z7VDTJ++N%R|H?isfEG}($AiB4jjKO%>OXAg(Q^6{r_0n*1c~O1@eJuq#V9;y2P3y- z7T(_BvfN#qD+x}=QF%b=0@AP+MyebxYqP<rx~w|`%z-3D4E!1ivt10lh$Mm@CAc%i zewHa;7KjOd<;ImyiY_pZGJ9PC`h{4*;6YB}|HQlvH922*KM?~@LBy7FeLrIm%5S<O zRIx}X#h)nNID!5MSeqPnv`cxN+_7VzIgE2ta}ORTYM0VGIqV}PEU2!2lpp=}x_&XR z5D!aea=*THjlXu0ub;H}2<1jmA9HBY0hkNlyW|KM;EtpE(ego;8LO6Vu-D~@0e1AZ zI!}D+-_ch=&I8UFo3nQZrXStnN^Hj<`u0#odIJ54^f-t+(hpqh?=&I$N{0}g;->d} zbZrYrAD##Rz%u63GFnG+3}<;f_-j_Y#}hT_h#;T`8^`8-)fMyVN3<a?{f+KcRNGt2 zhNfSw>qD8yM#rkUgsX-MrBZ%A+wZ%8=bF(5oQY%X$`=FYnCM3@1L#Z~H@YyNZTCT+ zLkr#}MU-_Y^tL<MEzCOziW%tL2f4SDDzWa3#n8xPue>@FdL`}{lK$M8#(Jfb^$MQ2 zxu#cQ_?y81_zE=E<D>I`qThcj$9!yb`>(E%w+%$+K<9*9(288Q4?9P`KtnU|jH)X4 z0oH>bOdXgF*=Yz53`VCUyK>aaLCc}c{sCH&(y=d}{Vgsdx%vPzv)z@8POw21)e(B6 z8~wmhgP=cqX5^B|(Mx51{0#ai&4o`*E@0SPRU4g)S8^TB|9f5%H8rD*zOxlrPv`ba z(9Ap0@yIq%>1Dj`)pBA<HZMZJ=z?n;z*=<&u+}91;&lqhznxryfAMGB8UN-2QKT`V z$Q|Y1d>mX0<6rYA|K=w77k^)DOUX8^Pt&$;Trie*PtEuy@4CCcF~(<t=cGqN{35rX z^U$R`*a-VPiQj=Uu$u4y4HB4#jZaJ`cMt8ltW$YZwhbV2Fyw)}^R8+M{>oTc;-@Q_ zX1Le^qc|Oj+5$vv#>UV`r|CZ`m<ud;UPVF}LlH1)IsI&p7gE!_^vU0_)6k(uE{qKS zvp@Yi!~c_?;_w%+;s3_iPh|cOd4F&0y@~Um+i<Slz|)Dp!HZr5n$6y3YGQ8-9sX~8 zTj>CM=h83meLMY>1@q}&*t>wf$KG@4arT}^JK1|aeVx4*(0%NkM}NcK#q{6VyM+Go zzY#;Hw!ulCW>FP%J9}5r0DCW?o7vk<CH8)Ru4V7#bTxagq$}Bb6@7rcSJNfz-AF6g zdo3+t?{#zmdrNd4dvBrz?7f-hB~aLl3-&Y{WB1|$EH$!Eyrts*Y42MAqPng{&wPLp z2WO0^sHkH^V}daxr~yWrK^Vlu(Ln^{D(VP>F!IZAj-OO?a3EzknMTd0CQXx=Uu~17 z>22aCX%Y|%{^}>1ghZQQ!c7hxnqVb>3E{l8_C7Prpjhu~?(Kc|b#S@Q+26H4XYaN4 zUVAN}_c!>6a^}Kc$s<n6!e`|1QGEQ6Jffuo;RJa^;Vz+pJU)w$`^Y2O{}x^*k9!Ga z{TnQM=BfaNhU^?ZSRX_*Gr&Ah`5SV7R;dqKB>Ai-J{wf}Ip&Gd)p_(8l*v{;Rjm(N zCZ)NX=AzXHEth<zQJ-*q&`QZ?6!nSF2d$BOWYi~8ACxcoeEkaX(dmN<C7(YNpAAv^ zImHq-$6xWo2B-}p5Q_q?e5G3d-Np$*;;#tV=!&8Ae$!sBl-xX?kf+Mp2+zm->A3N% za{dwyWlz7V8&MlNKNW~U#S-o^P@me`2%&o~5?5&L?~><@fLlM<3X=FW{P0L;AyX$0 zMGb_9WSW<iQJzaE%5zi%e`kZNE|>&0$u!R^qbk1Q8(_X%<-eZ`vtj`0e3MifeyZL| z748kF)TLi~EA_sYaz4gqYV~Ky;~7HsBF!5LMDBd3*CeQyXPoa<wZxC+mDff<m3cz1 zYJmK-nUUmN-o6P1`6dZp{c@lkwtKH$(MCT$fZvf{2H=<O!!O3$=;NT#&k)J*)P%-? zh8`!l{R(Kf#`UTbk|}Ui&mkhRIggho$hcY1sM8ZHGHzOE8#}Q<&?Y3wxpCk*GQpzY zw9W>l^N=#MjeCz5W9u7tOsGH8>a3SF_8cM-XAyOB=qt$POXwg-bfM=E5|Zo-1v~^` z{wKk=3G@FW<o~v_LGG#b;)6Odko`i%eU&P{fj^^Y()Ys`)2rEz6lK*FVwrWa*D~vv z>@4S(8s`@pegCS}oNCqT-1eE{eI`vuH?+&0pDCPIRQB60zbHmM*0$5Y?BJW<#879u z(yn&4DilY=sG8m#21bl>cVRfVo6uFkf3pFW15Cx{4XI0&)h>|LrOF}S+68iFlfv0d zazEkA9mb_EE{P>`Hp!jMa*XxT01h+`3|z#pS%#st{&}1S=LkSOzyW~Q0QLer3$S}9 zT7my*n=9qvHgE-S1#mmS?EtqE+)i-2!0iIJ7u;TO`@rpUE0Mop6rGA*sW4u|O7{V% zb{Uw+T_}eP?Rd0t2V&^|OlvRs;CJcYBG4S(xNi2&K0Ml%Iw5MH6T-f~{9+%J>v#mq z?fD2=I_42lUvHmWp?wmKeNw%P^a)1Z@hChW0B8lMOI1ugQ@cRn{ED>R*QE9S-7jmz zO^P$nS6@L)(hIeIF?aaIgGd8?_Lai<HKMH9j<*N`^PUaPJb)B{MF7hHRs!S$Y<z_D zO(e8+B)AdaMt~a*ZaBDFaJAs7!BvB+0#^mD5?p0q-_SPN0srp?*bDH7NBsIGRRLK0 z^#yqk><53pfWGtl{%>r)<wY{ls=X8KC3mXmH`Au4<Dn761G)?N#Oy4fN`>%|(4D7% zoNMMr3PI0%w`%xi{zK2bK<Kzled**zz-Z<oq1YheC`y~6!dbJ>^BmIPr-&&4$u>6K zNOGsdC>^@*Q3ZHr9}3Ud!V6<?^U4D$oF_%J)X23;yI7IJQ_s;Ix~k`VI5hDew4c6u zi_ZQW*`iziT;LX6>mIu6bL9G4blh~|PMX2kK^Z(lGjJXg`9q!+W}#dgxRDnbAV>Wx zLi%Z4#tW{@R?m3h=pNs8-kCjgJMRL~;N{)%B3f3B7x>IpVb*ifrq^$@zD+M`YmZ3V z2nV0XCEuiSCE-p&m~)|8)tnT8L7tKDqI4&PLlAi3jLj#hoE9bHlKJgMWn~NUgY=G@ zGjRtwNNv&7{FFg~qAt8C_LL;;sHwhfK*dJaWujsO+3au`UMF010P3WSYD53$F&ps% zpmeC`Y2x{)<asmoe4TjimOR4_;LX@)iKrMGUicKv-Yk5xAN`*K|2_C0P%ca2Ct@^q zfmz5nfY;9Pjqemv4-l<Zy+CfwtP$B6go_yGHua|4)NWHpx=m&lKLoGfZey2>8&+k~ zqP|s6{GLZ?zA<J&ae$u0O+(c@eee*uXEzNTWfs2JPXmEH=p*6c9IU2rQu5dO@edHe z@5VVL0`U6A$t{zdSL9pO&MOKod=Hw%^vocRD~!BM5MF&I@IZ9#Gv2dTDlTlsuj2h@ z$nE4@JX!wKd$P<v6L_-R_q6Y1Im4@JIL@XNzIn+jAskL_>Y#)$JDjiRbAB}pRp%*q z&UeO);_WCetIhC<ktr`Cv&=UMk3B>5?Vywa*9Q4EzDVxG$_263cN#s|OhtFl4xmeA zS**$yDx7^AC1ihnm}oFj*~SR3z+(=L0$eLS8T+rWQNbzQMx{$K66Uj1K`cb^hCZ8_ znggPyGtiL6udBRo#CXPlEe#t(O<9a)7=!DLHezW5O>11kc!f<Nl+=kLouA>G%Ov9S zyPqJIgoUh|879|zDSfcK|6SxNLRw$!5#i<<BJZ!|%`=wr=BTA;8y5{2TqW+0ml#r_ zw3%jGf8n!F48FTycBe!s>D_vWH3RQ1;H?FbO>l0BnklludNyk2hTGk<H}LA;yB0;M z@!G<c-zynzEWNjo@_UuAkdYox7qw?UqAgvPmo6^E*5~u&y=t=(ap1Ikx|(0Aj!#!{ zL8NMp8R>653cc+aE<NyA)_p2hveLC)otbW4o|Bui;*gRNPy6O8+$&SzZuYclauka< zgYd4F+!dqm;bsaYPX)?&eDibi88|9?8NVIa_7>bluMCF;urge}<tY3gwXKmib!5~{ zLOVZOWzK`tF!xy8{nhMiw5iMjTEc@k)HwG}a`9zfqh`NyzOxl4-=Mn53p~w^?{4RU zou&x6C&=+#G^YSh-WU!O<wN&L`={0O$wQRp;dmLb6LOp5yBKy@voRcPvUz6Lh0NQ; zhRs_}yionTX9_%^c`#3?vscTFg6P}`5=%L6Ij3BJMf?uY!TC^(eXoZL*X%p4*{@#Q z-JoPuns<&n+haTvdKwf^9(!lqaYwtwab+C%Z&Wzjb<T#PdQ*7CI6ztzZ|t+*!YTE~ zHcWw6B{4=kl{ZE#*{kAoL_e|um>66vJS+IzKFx1)!xbO7a{I9A{5yE_YOj);uvf+< zI$P!Ju&PSb+u+zZ3~Cu2&-HDXE}VE$6uXTPGOAFAg{JBgJsR+l+nD7rnJJox$O;<v zle^;3pH=ka_62kxZ|w6#c;mzj>f3?a|3C)$Cgu1bG?dPT6mFUT15RcZUjAOX+;k%F z_XF@NTf&CsR~~(O2!3VnF9>b?!qb#rnSt&B@M{B5J$-}x3g-Uz`4xi0ko=022M^9B zfO3FBfHeTi0n7ktPybN-3KqtTSm{>)4gj2Z`oDu;iFww?ue3fhB)>BI8PX>hc}EI7 z7Xs{f=I`(;82iTf6_W3NieHiPZUY=T0J;GB0F>aZ1_%eZ<=G#KU!iSefdA6~mID+& z`vdVSzRj`hEa7dXWC6vzhj0Y_K%I3vaMw@94R`j-xyWuqii{ltq{S|jPm=Myf=fva zuCb9>LZy-(F{>_;Bj!-banPfLEa4-R&bf-=$Y}yH9Tf_wvjxlJc>fH@Bto%K%@0Ur zl|Ak!6maX~l;s%lxc>qAPp{@Un8yjj@Wo?+3`6N-H!Ktor3~aHMj(Z7T+%k=(Fpuw z*E=Nde@x;RNV5zyG@q*8>trYGRk7o7Yx(!PMX{<t-9ywu<hX*-6nCm})u4OPglGf8 zHGa-(xSzPhnaEB`V*0rt;WJpO_TURSK!SA#7N_zox2Y4w%uK3u=#OyPAM2cnm{`tz zJa9~L%0)8F%CZHaJQzxasmxj8XzfL!B$LRsgpu5@i0pG&?##}mW{j9Fj#iUgS$6>{ z!Jx7n>Mghz-yDQlk{j`#54t$4zs!z~&(*TpxJjrz8}Hf%#U3qisbcGqLMN<ir*Q7a z-s`~JWEv@?K(lWIMDtg#jhgU|;SF!izF@QP`C;iexDu6e*S<m~5ZTsg@h0sSUF>`D zxhl<Lhn7Njq-WWNkt@3$gd2v~Kn|I-dXmJhi(4gQC-4q@A=iJc<Ss8cBWTaT?tT0b z@6BU>WN-{75LHE_BwX%PkhM(~Sem8=BYEER2_|?M({ufjVFJJPFWrroua8Wq?>Rm7 z2!D7Q(<zGjBlb|fA?Hz^aVeu3Z%6L3hViufEUIMJ)Nje5pFl-A8R2ATd&NaGFvgwp zU>whp6pNuUa&D4SU|22MJmyAa*t$Hb4BIyzMTV_g936p7Mu;mi7*=!77~zRsK7M)6 zF0WvZ&%hMjVAUVb%HFa<A4YJ<;2ZFZzvP}r1yn;M!-GxT2Kb=nplo=ISI61J=;N$* zA*)(A1Qt$pFto2{v@mJ_iwW@Pil7=B2KLr*ric*4oph#X+vzt`cyI6DEH%<KZs;o- z5IHVNcxNY(!hK<9;Pw8QJAM3|oR^H#?7(@d83Mc#xqMH6iA71-Pwe^lRVr>S@LavS zsd5H<A3tE;P;*eywuVAEVyenJsl*U*fi`v`$(&00O7o~YB~ERohH`M)`N>Y?2G0W? zP|AUyiGKEWuCA&(MTTi5%R&)_uVFQqos!73h-ROL3w1xEcX7$pAr#dEzxdshcXd^^ zI7NfTjaNeW*>7XEcz%X=9&n#XNqmBcV!2L@6NTftQ=x5FI=8AAE*>!K#LQ#QCqq*Z zzsP~MAe#VKaF8qaf=2<Zfz+-rg9xcy02au-N}WL~j+wF(GH6YlO$N_)zOseqTA_e9 za8YR_3BG88XwDI0G)1(bKNwoGHAvA3+_tl_P2@H&Xpa`DEm7f)U7}a%I%{#O-wv?d z$&ai$L@ITtV(cLMoz8j#B=Y>Z;maUbWg8s}r<@ljH(c~~SW}8hDa#g`zNgKqyw>8; z@G#!99xn7eCJq=dP!B8x)H-aTQj5Y7D%8~}j_#w9UBt*&C<Y5_&;%MiCcS@y-!bWI zf01;U{UTh(7GRAsT*lKpljSmAfWeXt-ETVKs%&*tp3@uEn(EbL&k5}axJ^Pjs>q&5 zCpC7Jvr>?8%TcK)PG`8?b06_C^4x`H<2fApz|`VQ*CI@Rn`mT7)%R>&QPoe*t~1;z zbEUKEI|O3G@GuY*anjlK?b*O+UVx-{B&`z9@~FfEc-nRpY&8p;Q1l<7`^%)DOj~7J zd}SNk;#ST@afCLZ^nS8ykcCQ-{j&pPxAD0r^q;a5v7pEdjDZqaboGPaHLl!N;ISs+ zYkcK7E*$9yUo3(TJ1@&76Z#&Oh76z+4N=Skk@U@Yp}bZ2;|}uOw0efah!oi%-gMd} zL-aPDC$bK$Zfm{oX!~sz`z&BRP@%A!M$s_g=<tS|_K&ZiP^#n`;`KdzMWo%V!Vi?| zMHULJENL6sLp;ImpCe&epeYLmSgeKrvUKp@su;;g)Dkojm5oNCR)berfdT$2HN$@! z*1&&T%OPML8jdPM!%-X2aMZSPH#sHtnvZ&(hcf*vNJY9Ty8sQMiAK#gKEWSBGoQzz zk3mh)2{bLmpBerkcP|f%@=52#Z7!3bzr>D;zJ!<MZxMYKp-e)}QFbGri+9x&XQR)! zGCLG4(ZK(9@>~aB*$ELYzksHuGW4goIXxda8?-J{o3|y}Ak3svfCr?`Y=dtg+Sq1Z znocZz(Goo4ea*(70Y>2Ri#*_~Aeo}3J*;9E*(D-Nc__UZp}7<&VyLBRk8-t|>i3Bp z6QOUq?4pQ5L9>K~e4r5InL4j>5+7xOI|<v`pTKzm&n(&Fgtw39v>Rp!p@Wj|x;i=E z<XI!pQWJsP$R=W`3UV_6qosK5oamumntcq?jb>p1-oAi(c53#8P@g$O(|~q?XwtGO zpyHJJPWDgHosj!M|J_wWp%V5!KAux?lZC>%z+Kc%7r~HJ%5zIRr)DoyRci5V<JncY z?d?!Z)&Nzsk5WaeP+gGOY*WC$LdeBXxQOhBM_xpgLO`505&}4jpM#tSGB8L15N-T> z$|+?$;N#VqoQRsmFb!%EBho2(*{I_^evS@2*bJdbLAHeMr7>!{Sp(74m4Jv@4iIhE zo?Fa9)&VmAY#7G}JLbhDawD;c%|fZdr}E6%q(no1+*!)i@UZH}$vj=a-L&9xyAztk z79xDPgQzTbaeZV%S^o)cCpSS8PQ&mqt6gza`|PW=qy=GqYu}EmY%Fh7>zi=*1!zwq zEd+1Jpbdp^QQB2*VwanRS5e1K?*bdFJd=v)2C4$`A1nN^)~gvoc(WD-)N%g24JNB> zvv9bT8nbKi>b_O|L{gAT%ZzhzSE&dIcHz<$BFuZ(Z|RD_X;qCHs(Z?ah7DrdN&iX3 zGWb%xJAC1|f}sAm=`SMDE#UTE7+>YpUhQm^5$zsTC&+%EGNK(fP9@FKRO2+?*!~nj zLvS9TdER+Vjn{8Tq=ir8bzg1n_f5urCI`sN*MH)r@KO17Uz72BpYm&^JG0lOSelLp zY*}JCL0G6FIv=C(1f~q<k6xK(pRt!6rrBq@($K0J-VmVt8ow34{jCg`V1^%MO~@El zs`n@T{@?cLkcXch+Ey3B-V$2RPIWfPoXxU?FYUnzpKp}Qzes3?r$%^cN@xYXyj{kf zi9MRo$__)#KB8UT^AX>$!pGa=BqYr{TS~E6wMe3KqXJo}_O}RuiF48$4+c&ui4P7j zC)JW9YW7cAWJ=PX+%R6)G$=7c6MOFAja?}291f_YOJ6t8g*c~p=0dxoAAqV*h7?V? z8u>cm7fPa5T;IrP2Tf@jXMO*W!rtE5<9jbp<yC|Yvr{&oh@UrVlM8_nY^AF@4sDxg z&dL(c;$dkMy9~9O-(E|X^FHuMhA^(zY!k)1F&2!Rxo%*{&B8^=#Czq)c&?8nde<&u zIw--}ti(dNJ<<$`bXhk>sK*GNPI6SRC`vp02=2CX!{A-nbMcUt$>_N#sbR{G3Rlpl zi;A-=Ajr#Sc|sOC;utpAP;->~W+4ph=!P`ksx#A{yu)+FSdssjzXVh?eA@AeYw)gS zoK1EBg&5&`GXvc-I*M}h>gFH}Cd_-F&@y@xq2)^L*6Gm5e4|iCCm2|RBlI6`odh5M zQeg%1%cpZ(nGv3woG`Ojeg=aJg;bp1id(w)FwDkzMXss7g5UosP4y*mncSd1!hHbD zM0_O*6OKSN8>UDo3Kp9WH8oFSxtUtDIKI4{gUs}&H4m4_QM;pdtJ0?Mv{TwM(rf36 ztwS_#1tL^#Z$(p9ZsS+%hjnII^?U5;y5R{byE5U}hTj<s(1@Jic{{!`Vrv}6M(a<8 z_M7C?02ZeDnx+zfYN#6q2~`QlG!Ft{Cep+gJtwKaCK8X@4B++wix2Qh^f~>fnraco z;JZlK)|}sJpt8!BQC4}jJ7t1O-@I{@FdcOlAI2lj0a?u#_R*6}f10+HS~fzJJeumg zkS!|hA%pz_QnHcs2zVER*N^Zkhybe6hfU3S_QzZ2`;|XeDu0ad5-L6Js}b3M3lIsO zauo`69}gnli89<IdvCeySoAta5TcU2QAF;bC0lsrG!cw$6&^=5ZN`?I_BY5@9dN>x z{$kOj->F!1B!0ZZE)zBZ*aqMxfm70Rk*pbO<~E`*^o1-GF1;NiwKxw)p!KXr$vGfK zh=2%fB!ZeK`Naq#>TX(4gSwm6<B27F3&`<B5OzRII0A~fjvT8(gN?`##zOpTVPp+C z&u(&CkN8OQn~Sa?bsAYjq)z!vnB{at_LK^q5~<TQ<kT|aT2iNeQ}joLfN&;G(Pyuk zqMLnF^i5TPv+R?OA*Sd@2Tjo*z!d$yBQS9;P3*ak7);l~+Atbt-=)$ldKb~luJzm_ zmct_2iQY@S6EzTqSI8ubbMyq^#}4no_l-{168Ytsf>sn%LOijkp+<uPd~lsIWL_dW zvAUie=cS-N;+vv_FhN7Fyr%_eseyNxPsuc&&7-l|Q!q|b<3reC&IYBy8P9M%Sq7WZ zEaYsb`tV_TM$NajVZz7IX`T^gArEg&qQ-jE+K%eoInR_}-q`22kcLySO;>IgRCl8A z(6+#a4BzJ47b?x-W3r(Ppp-LgiCMx}1-0Jps_Xy~-hd2aY<=8n8PVO^y9cYF4~j%W zG*p-aJ@q{CY2?;m=S9U&BqV915PO9j(cdeK+~#d*ud>qk++I!1ZmN3hjw%$@pjoh= zxFTqJZWIKClOP=pYIH@=_IGiefa&YeXyUj}Sc|Gvd-dPtY*`vViCyfT{f;<SP(#Dz zKq1@&qFM-A!WBUXP(D?Oubm6rvk$~i;yQ`e$9pPlHf6S?tan=#B_bQyOwVG1=VuHm zLamhdeCl2x*Eee(nhR-&9#@SMH(<;*rIa?=n^seO6Rs?oeQxyu*GN>^VN$uqkxF74 zZQ{8;n=Fgy&obl~%tE<?YS@D2UI}#TYm$GqaOr(%jIm)<=5x*#O46Eo`R3>*g|VYH z!qD^4grhxYrXER$m2n2$J=Zu*U81nN(n}j=3s)SpN$^~tPw+U%Aw>?fsj;iQ5J_V2 zec$H`A8<y$q}@@vD2Gf(5;;Z}w6EZ}OwAI0^_mawn;{@8TQCepxcbKw;buv)CD(rz zAy?)e$tR`ajY4jQ(6%LToEC4nYPJAG*essw!rjOOl*|`U$yQE|CrPvKOn1s%6P4_E zL!CC^Ec+wP{-c_G?=@Uh4L=rdQgg%8JQFqh&%|e{*)T(aW}gbe3t$du1{cFeU@>F8 zT;_<tLa)A~cbE5$9?-|``QnO3uZq+BD4-JRfD+2!TY#wMmwDxC+0k{OC=+{}Jym^_ zO_zjiJ;PhF`NoFNwOPYk_|SJzFDl=__rxAobSkbmFNvrk^;B$=^N_OYB5FzHBBv2$ zsb|rVajL2>khS0ruUfqVb#u?}OK4>0!c_Ei!sqNQ)otvTD7o9njs~v_;1vvB=RA+E zT1|1D-w)})`JOs`=!nx!;|?vM-!jQQ`B|7l(taG+H>V%)%^|wD@$9F(Nv%K5w(v6e zdftnRU{7YGFBL{<2yZ#i@sY4(;L(z;f4R%p;mT~&cfxcmJ|OLXKj42-Rtp3xmVSAQ zN<W7jmE9t|{{Zfy3vWH(Lxya0C;O0TPY;p~@3ODj$*)UOqArPW;bEE!=PS-*tNNC( z_GVXZr~a&_S_QduH^?<LqLQvlch?!B<n^a}YmNPyck0t@${aQ_jT^xq>N&kv2J`-B z{jN+c+8u*W3biNG0B(vfm6kQ^0q;CWKaHK6=~_0MKXgWLnY8)_y8;MQ<c7y@A;c<9 z-IIhfn|(a*N90i@wN4>9*UTVhH@Bby3ymvf#0->ZIIMLo8!?mDC{A`KDbrZCZeft) zN+?^5$64!YRlLR^nzYTvP9&Y1Qbq)Y#^v_2i+N4mq7l<DVlqbjkvF2FvR?*~<uvlN zP@ozx=5&lX4r7M<WvQUCriW(W&MV#q<3q&R!Q$wd7wP@^ALH_367<J450xwM-ketR zlXd79A~SWmQ-YP<j6+k6dLyA+puNW+34NRm<4s+T_)sp$p;CGj4&8TrZWqktibhwi z)@AI}w`iOw$q6iDoowECP4%nrGB1o(*D8{epmE6^JcysBKT<K)og{O_g>s=u7}BH& z^>EPco)XchwK0^fcN@h(yuAm+@MHwqn_=&v7nal5a7U#W${uV|gz+JDCb4!=aFA!3 zKDUbtCIQddWHu34G3cWfqDEdzyp<3?8TY#Imiz)dXB*9j(ApcYj&e^>oeXg28>5X~ z*a1*SO%2u%+Yomd?yDPKeRNZBayweO07gKw?<mkNy~=H)pm6($`!xH88yp8)C!w^7 zP&Z1m@0jKt7rp`)7A9=j=v^B;4<rFUqg1qb488#ql?-%uZF<m_VRfT;P3^J~(~?ow zsrPMqa&(L5rk<83Y_g?<7V1AsY6eVIbZ*xfva=4OvdhLuDhE2qU93)MyxCr*l~Xq2 z`MIeB=Ke0dQH}RdG9Mt@${o($eoYN8BmLFxq%J=;_9!f@k2NTO2<db!8WZDbf>AL7 zMn!@1`olsbJ+Ia5R~0y~z{vOzx0Ib%!dOj#Yj|?9!2q4#{yG^uoz8}SeM7}0cbc5! z8s@AA8eeM*C1>_HjEG(*qgE~r6ggh98)~4eAOj`SJ5Xj6I4gTY*?+f%EiZ5>aIo~^ zV8Mqg@Gy-JX-Wy69_qOb2Tur%Tth}rKeq9c?~yj9{wkVDvTq2X@>fp;uW_>@l-<EN zght3cssf%Nv7*V{&URwFkYHyET1EELIL>!ES;^r6VtWzN$h{?+nw);*JUZG}_7n4M zXr#-gE$qczK%VoHaWHap=Dv;dpSe*_Q-J32DMBPEK#=?5(OtSa_F6Iyz0$EE$~eSR z8Ha;}D==v%98H1={3J_qd!6+e(|ye>O#YniW}py6T%cxztylasBWz`T)qarVbFE{o zzp#=_MA7Gdn}ad19(5bF4m2R|%5AO9?Qb@o#>p9&Xm*$@x24G_YCWONMwAs~YI8-m zvDGYS!ibG5FI7}(m&iEn0n~U{bA%h&)4&))7%nK@*vcv$CeeWw*c8!?csf~6lwq+8 z(%4yP>~!I51vy6^Aqx8{0&ef$Q$cU<<7SmBv)41OyFtaOAZG@0{;JuCmLd&!+|<h( z!);o$Gjlh<Z2%Jiv`)dm?TN4KC6s=rXOc9XdqzvMzeg>t8F-Dl6TYc8A!BChp@X<- zpl=|i?6>LJ7+C*j>YLfgiMR;^%r2xzWFRL^jR6|C+1Nocy8|AS_%IzFNI4S|5p!0P z$OMD4Mt?|CqoE08^c!x5xe%woW_Ao8rUG&r=w4F<OoJg1f^qg5*qf?MUGSu=GC_4^ zjMLPq{1u8Gu!>=oU3+!jaFr(<@+Io9UfQc=L#VG-c>W?W2G%Qb;{}`D+t4OE4wwjt zL1qFxS4qSjeVpZ}{&kV-a2rp<%m<uwFOInni8*SKD*<{E?IhJtJp%J=G>jb?JFUvv zi=!EnLn=snjfAuLxkKG~==aW|=kG^p=-=LtTjA}jk|AbPM;lN#Xd{>McQZg+X1nhv zn;vac6iR=Ydreq<Kh_qda6Qk%LI5k7Ni=wd;SzvDQ-!hT3bQ{!tt$L!Jg5IQhz}<= z0&^N#gL7aRbR3nTw%Dt}$vM6}%As@An!a~fzfY?*iB!>IcLOZ@zk`thEhJ~}x5=HS z#B3<$d6i^7P|!DX<Ae{&MX@Rll{&E|2yOpJ6x+Xr?-tkWKC?KtHn&gM^^KP`AMdE_ z8_xkREIa`#)m-7(V3HXO&PJe{<_f7Q@B8n&jUpfr0|>l}U*bW=00XU3i`Vs9r#5pz z!%SL_Vwe#%BTjABH?S#*IK0?f6Bz?IH^ZBpzRBsEk|B0<lnghq$=EORjK!~A2IHKJ zgJIw&_b6cc=rL;X`_xpwfqFlUqQR9bXlnM7Wv}-j88{7z_~B}*_md9^r-F_822D*h ziPHhg;)9!sY_NR82p|A9#5j9{G&KdN@$wyGf2^3Msh$omX_}g);4~Wru^%1s6}FEj z%ECxv#GN23%<w~Oa|ZFa1w6dg9W~WI#a333&C9vM9bKe}NdQNd3^}_V28gESH;`*p zrSSDz?=oBt*1Y`!<HHk=!SQzagKNp*gHrPoG`=R4f8e-OzNR`^B-A~2KlKDOps1Ri zh;k4yry@*4@v+2y_>UV05kLJ9KZO@cr8|;*Q+qyCEfMR=MP}IK5M_DrfR;0q@F#tc zM2bnIL7pd|c@TAJN&>W_o6YW&L{e!K^6;j2Kzc=Qd}YVB^DxMd3`nZra3{hlQFW@j zO#P0F+hSBh#XxFR+t9A9zZl~9Y+LBDT2)-`_uLft0#xh-Omqzy7^Op{<16Wu!k;38 zX$zTDHuyebX<D%<a8{}M5@#AJBoIlD90#bdpO=tt_}b;bEHPI&^)YTk?*0zq&E-$} zRf5bWF69VG0j@2)FyaczKbA-WIo&R<6;Jt8^lWgVFs#J8RMUljXR(icw8NT>S~v`J zvBo9S4J)v#mmVJ)FL>AHo5<1f1${p|PdHeNGLxQnW4q(IRyI1GyTDF_bsHx<Q(J%# zi#tU{YQwb&zc^3Ua>#smiPxT1dO98jb1J~mS{!%;{MYq99Ph;g;7<s4XiK(F5)v1- z5Uu#(cy8N5W^ky9$|e^wgK#$P<2!{)JbU1J1+I+js`5>%26pL)TEy7%sQTtRPAB}w z`al-D#8-a%MHx|-a{-St8`<}H+!Q+nT=wxS+sbSq97qt`9YB)^p=xqc1z#Jr;d7ZP zsJA6#3yEJ#1~xBq71_eVC#khK1@1-twS;ays|hBWYW#`|*)9W<l`X7q9JHzP+aiJ$ z-STN^7!<mbhPpS(p=zE`asc17K@LTkIz`*8ETM3?WWsl525vjy{e>K&ZNG!8qm*Ln z6V~)g6kBKeSrX7EJpKelIS5fsD3QWZsRxnwdYeYeG7AR|4MM7~P(ry+NXJZi6_vd? z!Uh{XL+*g7Ho8aA2~<SKWYo*uCB{J2?1OXJM{_|7Mndi|sTLY%Ntd#!va1zRRvz|D z5_C4~Z!HhZ4X1XgF!H0{d+UO4#U(`cE{E8|MU+;QP~{;5)_lk*baw1{iN6PO%az+D zJl=%X_XIL0yE0J?3!6hGPoPpCXhJPQQ;*?veMMxGh)9Swx^u#}n%X94m~AQ;3J?AP zp58)oC<D#R&8CvG)Z#)Pte0bjydvLj!}20*9rAS(#oSm58jQem#@-rnOXxPG{<2-k zH+s-O10DFnD=&NJNOtZMSo)^mZD(t`H=g1p0!JmJk~|>3jq#y?dd6eV6JA!hjIA6O z#0?idDD)B{<T_`U=WYFW+wR{2#a67(7@+O9{n3A&Lc2BS`*Xag23f~I3Dk^g+7r+L zQxCZ^yKoY`RoLjuUf5PRU{S#p47g6^y2yD>H$A<At`soS@PMK|BD_)iN8Y{CETUNT zW-J&>&<djq{g@(;36I^#_Mvp!6}~u;9OPiJl1)yvSqLhWWXmTEed)E?C&`Lpu|!rI z<GRD?j+b1Dt&XWnijvo7YxZqcYTl`@`VvX4Grd*cA$h}^!37U?KDbECOh*^!mr3XX z<&x-FsC4k5?nQS-)s1v~R^>P*s~zdNCD3=f<CxqdI4sI-p0I%s#}r2m?)GybgvH5i z#4eb|)T17D1LJ2ok%+j$)cco$z^T_>K)yBGnB|^OJ}e(48db#niS&IG(gTic_%49U zg2`|+8YI?k9RpOzR-jdtoElg$87i^{UM5cXMFH7`a~1^7u)_;{GwiD{E{RbwcbY72 z92?Zc==cVB_hi{pR%N-3yEDwfxrLAmx0@%skw`gSW~1Gy@Zs^N{np0MCO3Q*9Jg|$ zk_%p(2D5D|e0mR|D#)t-yJCSXbE3&=zG;1Zkh5M{;4&W5?61dD{B?!&6#oRCA!vza zH=tyUC){aD_m&u?E4O!RJYIK}XzBse+;wJU_aQB(svQZ_S%@d7cAOJ9Cu47tvsoF> z^=>%^nZ)Ia>`cfh_B|X!&VEIulJEB@Y>L(T4=dG>LM6^m0(?AeFb(1!qhPaQlevu- zV7=RoYIRVV5}lDc2|b}EJOmxSB6ouC6?S3`pvJ?pg?p?hIk4PWsR9lnLwF$_jYJ}O zg2xFHaZBt1kSi#nX+-u1UX++!Zigor(kQtQ^!otSP+!2q+7Do!86h0b_fAiExz%sF zH2BF8m{2GVrq6da!2;&4?0oUXf)`z;b3~lPWoqS3;V;<aF5?lt7h20C;Q4B9hb#B+ zDv#DI-1Ufv#*opbBp;FkOG^hVHZJajaI64tfwn^b1cUEXpg>_b&Gz9V%**%RoV^3c zM?9K@%E7St!^hrZB_I^WaQD;YWZhc2^|6*nkR04agq{}UxGGP_=XT&pO^5KpE+jM2 zi#MLbd(1XiNMTY&Olwi9y$MD}h>Q;=nC_WJkK&Srj)z6@dFgEqU@gwY+v39C3JB@! znv~;;Xt&CV^pPuquROws@N<!5xCH2@wr3K3U~NEM%&1fGosKJs?BpyVVi&nI-sWB; zlaZ3#vsErrTiu9+<J<*Q#b|2rM8_?cv9~)m$rHF+9Geu0+!Pp5X5r5}NzxXeD}(qj zOzSeXC>k7biR?+<*b;4Q<GFK+URPzkXEJGwS0I6zn8ceaj17`BX|pD%Zu}(f&x*>^ zC>s`Mm3oASPLv_~cq9WU@T1OgO%fho>+7ATv8|yAXb-g)5l-kZ+01y|%s1g-+6i-( zu<gx3OMc@TN;uptj02Q#RKVcy%ryg7$TQwl3kRoi`%-<r13Iu1(liC@Qgiqa=no)2 zh1ykO?Ib=XKKC5eb&Mk5&<LlZkEGM~Q5;Fn61pMZ=*l+8TG7K-p7YG*jrCAh@op$s z2IZbPIH=swzH-;2h@OOQ{A8{vKKC%Uj;}n8ZJM1W{A_T_^Q%e9!Zn{87zmdi7!>{% z4ab2w2?i!a`E>uFD7$GCMGs7h@C6F`7*0_;DYbTzG%RtC_x^nBnThkrQD_HJKOI7D zKB0bK2=%RA75k?Z!u@GJfdz>&j}ksvL-zX)uL)cw7OnBE5}7?l^%Y$D&ypoIPU3aO zczK=Qu0aOTxdw?E&y2lV?&iHRc2c)dEoUQyZEJ9(;C7H;S>xONIOD(IAlU~Kh}#5H zMW1kCfn+z2n<3n>CU8yJzxpaAk+Joj`(csp#6!z*C_g6H<VXc!oNTYc$Hm!oBQ^UD zY4-JYr`$bJ$xcbC8<}vH9j)2-Ez0IK#~an$Xm^r`W?;kObNf6B^ijA>eMt#txyIE2 zS}Bcv*EzBD(<&ODOZB-wDU)P=I|OEdPvz(I0V=DR9ABuR5KVOnF-StNCbp=Ni_w2a zw2*SMgvqM|+vAt3u4)e|@-YpPW)*1mX+)EjoYkIL(48WmsDv7^$#r9)QbEwxp5+Y} zRS@gFg5k&T#FoFb03sCV%e8hj{D0HN-~vT?xMwarkFm$V{}CH+1E2ApD9wI6gO_(F zP1Leskb`R?Zi?(b>QQL+AHzI&4p$2Z873Ol6ayauMm|$rcas-~>;W8TRDwbpK_QKx zkVa5QBPgU16w+=81<dCpH>Ci+nqeq?UE=|AGH~pWg>FK<vsIpk0iE6f^W{}?gj26^ zH_I!(iJWG=^Qic@SDg*Ao{yYg%j%5k@8PXk78k<e0l%DY?pu8nHLDK(J@qZa8~`{8 z&<4;AFan6gD1dnY%K!=i$^o_m>;QNU;B|l|fDZuL0Qvy5eUJ{o0I&+c4zL~IrvOg^ zyaezLzy|=W0387R0P61<CIVnOKn#EZAPZnEfF0mTfY$*|0DJ+^2Qa1|$^y6xU=hGd z06V}#0J{NR0@w%81keJ|0ni6<lgKbP1Iz|U1y~MX1K0pi4e%(yuL0f!I0n!H@E3qS zfG8lPV*m^QOUdSN;IAXXz<icuVDj%XF#XGc7+z!Wh28fX1M`b<hO5#PSc;0R`8u{t zx6aDytec8hU0zwfRaamyE76tP%kr!h6|+M9<K@|{7S`$?rkhs5z&|Frj4RI9m6l;X z);#nDKT9ck6cm-_>&%<k!m?5l$g!5S#a4)dItHdrDJLPbAcP_BzI0{f)>0Dd_KG}v zQ8_!SeDg*q$8H2f%@hNMDPby@Jf@7XGgkPU#pE-^@W(JSm{Nu#&$p7g&M4)Ii|HdC z1O#IfY8gc^6D-#%jYeY-{^rCmW)fK!XI>tnV(yNK$u@^TC3U#IGpaR(Yv9K)o60xA zPX#fU5Jsf}M+JZQ%Iuwz1f85j%8|(x%Anv7)v(av>aY<S?Z}%(g^wOHHe%fP36T>g zP1a4hd1}<O>9@?d^|t7lx6isG=FYofXU~~?cU*jeeqQ2_?lC0IPfjtWE=XH=?|q9* zi<g+wmu4)>%*tM#^KUCw=B`@3#<Dgq-&(M)u*kN)xTLhK{C;}{%Wc@WY4Za=-cq@B z8`;)1mSUHh%Zf@_s~yJzV}$Xu82(?x#4>k5i>1KRB7$#<H85^!aYd@#YDG80%4S)L zIr6-~?>VWsxGWFT+PPA;sKlzX+U;d_9m9k{=Pp~cBqM|R;471{aPb1aS0-hNDQV&2 z0iUIFV`68Ag(j8iEam0JMR^vs2!>3dr9xL?fnjL@f0nhDl(RS#i_0u9Bnz#&WSzI{ z;-a;7i+!`M2<mLNTl3iB&9g$y#a2s&6$W-GYsq6t3cuWMsnAt$<>h5|2(em9bOnHX z09rt$ze$<h3VFa|35hd{VoULh4GX<pmo$I|2YH(^7B2Gpa@fM63Z12*!dkMnc(X2_ zvlo@F)0IM28>}=|QE3rdWGOCsfMg%K4CBK$f+$%brEV>^4&HT}%Q(9~uCsItSsg?z zDXU<iuIsIkJ66YTt>B8`b1Bf}S&ECXFlZ^n>Gr&`l5+Ct&bTA5*nX?7fGf=-ZA$R8 z3?Nln!P>bz7Ag<_NMK5FvB^?I>yGul3+qij@6s}EU7@a`+>&P{%>@I%QXJ4={_S<= zp!V|B-AX%e=`z~hY#|_BR+?v>b>r>f#VrQQz?=}jfdcZS@VnwLoGT@>P9O?}R!cd> z7USK0ojPtTDjU>q1L@`tnXZD(zfQV2n68|I+HWYbvz(=Ppo6d{Nkoh{d&vA(mzCnQ zeFroY&fa8V_2qwOd|<uFe2RTt2JiXS4Mll=aiuo0ZYqcG21X3FjQ_Waaqb=zrv!#w z5nBjrLOzay^@HON-7Zq1d<$!V=wY<W2Y>W->;0Uy0t>>CvQ+xWp&~Fll@yiYLR5tP zjl-QQ<tnfNH(GwcPaf(J6F+1ftfkOvWu+z7QWj!k+_)j*TI}mMj9B5zmwZnJFp07F z!ItBk>q85(!0C;SV1_Xj<=M+B$_iLrRuQRXa&)w>Jr>bP595VG>{+vBG4o)3UT24@ zm0BPISGvBmY-8z<pj;`55xZ$hXsDS+OVCO50B|bx!=>km@T`=cANPB9!?Q|y{;A*d z!+y^@{GNCEJ@4{+e#GxN*x`84QRRRIS@EFb!R?OlpdeV0Yieo$p_mwl*-;Ct>x^6C z%-IfDZ(&h3oAK(6Zib`Q0jU^RmJ16DRjQCp<>ed8%LCTqfBjIm+~B_%zQ3!(uKr5{ zO6huk)z|n7j8WzHC%eHv|Mc7a{^U3K=S{2oXE*=<fZx@9TKL~R0%QY!H~I@00kVNV z`3?RJjDUai@9)(g|H9$V|II(_hN~>qJMjHR>pM{I!9Fs=FgmKXJF9CR{7J2=j(^Dg z(}#EL-1W$#k3Igg-A_FE^QV6C^fS-ydG7faUVQ17dw=!omtXnKtG|8icmMwT*WcK; z|G>dF-}=Mb@4Q>zaH#R{ADfzw96fgY#Gg){I(_E7v*+Ib;KP=WK0bfp&!2qSdhxT* z+y3K=FNOBMcsl<2)z_Vu{&u<Ro9>?8E8l+C_kF+k4>LqVGdwrM5dE|3|IaS}znmc* zI{be``=_NPl$0dkt^vd3!*8a}1V0@<Y=$3WGTo7%f5&D*OPNg!lVl=1G4OGO9cC7n zZSXxW0d5H&GpyyT*E5M*$5pTlb1zp+^0*ghWptCu?M1jJVY1ls@cMqLb*-I~XtsMT zrQ{LH!Td2_%oFp%d@v74w;A)m^q3aYFc}t>v*%k#9;x;s^0cgwvsXxd+1C70tMsyr zqfe%?QsR-pNv?&(w3rU#V?2z5;S4bO(jH4TuwrE!Ggv|xqkm?F)xKn{4S0Zs0~9mv zctF@9O9h*hhg_w(teh(+e)OGY!<ZmP%R1})vQ0@$W`=QT>|L``7A+z;LD7H#AOiRR zT8JHKAE+|a92x-H0h$9^1sVt12$~973>yx9$x9Y5$y^r2%mSVl-@W@uv(}Pqz`rD) zxGSNo&A?TZEG;Wz>FSvF53H<sKzO>#fRd;T6UQ*G6*0`SPh2}LN*kejPIA5P7a|M+ z;YS9A|6yuic&%Ufx6=$vKLR}0gL_VT#_)&y;uX#@FvW8W*TrL$J}~_Bpzw=>!cPne zU!Q33)%ET~!;s~4{^<I6Of?K0Zb~vRMM>9BpS$4tct+oM{q#RyeEsl0n+NLF;rHA! zDBd$m2f|)nI&^zja{|lr&u91w12cKW(BZidW*HP-KPdkLs{+IQ`!#K~fmyx!`t?0% z8#+C@$BM6?{^aKCr~jnt`r+?x4-6mNpRYf5{q&~Y*AH*obA9|*yc8Hd`1_o)mxkjn z_m_qt%enCC_3`LEbp3k%{Fs4RdBs;0GX^)YTbXPA{&lwUkDaY7l`XKATJ09rnoM`h zl39DPaf7uK){G_yWAPLs8Mn*5ClRH}Y)cWFT4v8EDqUA>r7I-!7?VuSOr&VAO#W7p zVP*X?O|z8d7X$t94d!Yp%jb%%sYS)s#g-B)#QvBu;%<Dhy@)N!vlM4o$^Ib2bjcT4 zEgP&?`F}f*3(Yti<~wCZu@z{Fo8{7~o|K<&CpZVm{0~#gF>P{LNeLueR8$JZ&%+e3 z^xIjk92ff}rW3KJIVYEK*cv~gaq_7rv@GU=HCVQ}+{(NQlufafy$aF0mCL-lc)k|= zH7TF7+o6@co@vU=(n6ARzHw6?5L=KKGA9QVla+wWkij3w7gnTL*K+IDS?y-1E_U6Q zGKoeZTVODn<Y`t*IXUEDo+HonKw~Ar#EeyD{wQCFJ%AgW*8GK~d3I|F83hgg{y>Fz z{WCCaQnHz0!m(wR7)|)x3fN>>ii`5em;nli`H^y&-&x8$e3MR7?!jl@iAy5B5fr<y z?ftNS)vvvlksZ~AK;!&OnGJ1C#t_pjUsPtvm$nFDG`$HpdpExa^+-}_enxpwDectz zWLThaV23k<#ZwFzzV&46UlqVC8X`qDQ?1M{%C{yLTI|cpOt@n_e=}=k4qZDR7_Bdm zexP3s!&sDAbZ?xrK#n4vv)VVCt#(3qmgdnx2)%8?wq910w_X~RFJC>Dpm8$DSS94& zvLg7tD#$p6C+11TQnom=bR$ry%&!OrORcm!R(UaydZ(IxCG`7+o_*Z!9X>q3dA=;Q zn5!tnyytTT1y(zZ?Jwkul1-L!T21JQ$qHXvEGzRi5F_}<g0?WwZwue>Yl3vifj$tY zos4O62tz+n=1UwWSi0{h?`2Y>4Cr;>Xqe>UvI=Q-U>>5QMZ!OcdD5>oOE|WiV@VwY zVr4VI_~rS1^P8nv4hv0UG8mXd$}M)QueMo%K7e%#;^^1^Sr&T{9#kYT_ZgQiHZB6b zAio%xrc%XH7}sPlGw;(h`AZ7u`*isLmxA?!ncX}0B(YG?T8_0=Bwc%b{MYZF|ErHq z^0_j9kp}J6aq(W!)lv_E;qo64w}1Wq_x~1uVR-9z<K9jA3-H%Cc8Wg(`WgV`JsqL{ z_xa*DMHw~km{dqEo}uA&Pm~BmQ9v}Tf@1t304PtYlH6gE8!Ckj_X`^%rA1dG<*Swa zMgrU<0s2po{O3sTNz!|=^lp~YES3B-BsW{iKSwINSn|h>6&(Ofw8XZ(UBWe3itmtc zu9DpCQn*tJua@$`3wJ1r^R)E7N5ba?sk~oG{`)2TPD<e)O5qV9v@N`C=52F-m-$cn z4;B8OjXzZQ|K6W=$R7>Y4f*@0qWy#YhCXzl;X`kV|8w#FA%FkBj{)iT|M*ZS91V1s zT&a2i7OXYfH*cRJ`M>ljb@#kT-KuABmj}3$tq$Vuh4>B6fBd{|h<vO1scVqjH*PR~ zlH~4#_@|z0du}}QAI}NTtr$B0t$WB5>S{{=c-6-`X7$ImkMFuV{@IpKTCXt7om*+j z;=j^8yJRW+ziRH@F+S-BeU~v;<BIm7y}v?_f$99(z?5GyFtw3M%<l12u_?OP*P`^p zwY66;khSy#xVUCN3ofqVDsb^5zVM}iti`W@i}Xb;xTC;b2`<t!QQ(dPx9<xBGalT- z;7$PdA#jma$Om^4xGCUH2DkM;41|{03oeec*V+uk3YQk#O^7_Wcy`tKxq-p2rxjcr zY!|@A&CnCzuG)QLfb<vAQJ62*$;)0~``DoGcV9Lzj{@ufcnF{tpc=pdunC|Xpb%gs zfEgeSU>-mmz-)jRfSCX@0HOeN0FeL@0O0^y05yOTp!aXkCji3VX#7@iTL4Z290vFU zz-s_606Yuu6u=IEEdb>J!;}Mkj(s`{+Z6izp<DkxY?FRzl69I{gT@cGlP>6yam*0E z!Tgn@oTl%*ME9r78Ow%BdP6^R%0HI=G}KEwiH>WppZ_y{<NeZ@$FZmfz?m1v1zP4n z#jNK5E(45&ip2md2EdCc-ZTjerHeN*L@tg&9Zz_Z{BHnwx$+JG6F~9*0s`>w$*IT( z{S?yAo4&Zqz~lq01X$K(xN7|TA5cpJ1QY-O00;o5ZG2YP4y*KwnE(I)CIJ8y0001U zWps6LbZ>8Lb1!FgX)QK1E@gOS?7e$<RMpimekL=MOm3V67zj5RU{ExQ(eaWnQ0I_| zo{@>hii(PgjUra8G&u*b0w$h`&15^3wzk#Qw$|$Ft<_g+xhf_Ea)EFOiriG<eGelT zK$CDizqQt$NhT5czTfY8zW+WRGH0KCU3>4f*KM!8Pw8#TC95P!Huy75Nm?a|e?IAd z{<j<c28~@aNP0Vc%eYmR;FfVS=iOiFT2S%OeHC{<=qkVaXFq#LbN%FASB3sF*Zn_p z`LDmx_25JI+&eitJHs8XW5S&;{OP`{Hnk-Fe8=8wxrf4=Tc*Hs?}FJa<?wv?!RuOz z>3LVngY*ovq|@{Embvi!@%`oVuzUixvJy$U=W&}f;!So#BCb=KAZ4bcOVWq%GGD~C z<-<>o=(0tMhf^fUjz3c0Q(9mVgCvrx5`_|vAHMesO14~!G%0!T=2#?0#{XiF|EGVQ zlC(VK?8%e0dlzf)Jo!N!And!Xe;yY=Gr8iPyS2Mv{?8Y6N*BQ2-v0S~@PD$%CVg=^ z7KAYwhV@wn=BuB)KxCvoLSLmUc#ix*KHvXAPygS){|o=r@NBn34bOMysA0{Wr-qlf zUCK=5Cgo<;_{J4vpQ=Wy>8TH}lWTDDj=ZjRw@3Wx7B%v)sg}3!GMHCSm*-%x{M#mJ zyc(Hh39`-_bJ@M}*ea}Fkym70Saoc+ZZn%==T#jWue)lxmJRi@rnhFRY%@E}e+o6I z*8TZiP1f0}*%(XlbU`88g{rv`UIX5PwZ-O=RZwVfQlZO5A(hQ{t18pnWhz_Zp4DU> z-&AaoR5sh~3$P~D*x*v`RPIn_H?}4IVSn>(QLDe11B*aq_ICzDe$NIq9CDXY%pR3B z$ScxSc0AOo4Oy<5^;O3%)@@Bbb9S90)T$p+BOy1EieTgkw=V^sez#AJ%ybt3XlmH+ zcJb?TfkG^C7f5o=>k<Whv*pm=ak&3O;ccSuU??mGU5!9N7;(ze-L9G~s@bYqTdIm? z>kbIQQ*(+`Z%ajH6ZC{4^;lB1*bor-Ai&lP)#IG-{n?U4)43W~E`K5e0egz_#RexO zRAK^qUs;83Dr-?$4_}*!!Df{`AqLFT#vKSTd)8fr@6{V{WbbNB8t=2?7Y;XdHOLOA z>_nu@K?nxj;N3u{J*LWzD&eJ)ye<>as>Jh!8qVYQLUT3sno}O@mmp<^1<-_-QKa4} zugHg2U+AEAyH8%Xg%^s<_L7<}w1BVb6e41CY!8IS>%)9q%@%!-rydgJr|Nx|9`v)0 zcC*IR1_xO)qS{v8mX3(l?J=>+=Y6%4Rlwsv_RI20B1==Mq?jdApu7YoqA3u*tO*O9 z3&8U?a|n#w<q3G7%MtKac>zhTF-?<@b^tz~0f%AKCe^g+gIV@t<1A85tLE_RFr8O? z1e6=+4YE(_L-zRi=ODg!K&q!6M|6)G3Az{fBiGFH><GW(?j$PUhbG}?7XHlPA37u{ zatkc->?Z&;z?%j0AeZSpv=32sHsl2aTM&f0RV?7cX)VN`f)Y<_31BXJ-_r`OlMv-B zRP?od)Zt0|xE-<0`PwJ=Q0MRp8v=&-(<2f7Af$ISGJr#6L3f$4$qd_n2ep{ayY?ZX z1+n?32yWBqPgMJNQSF6^YDb-=+K}k*!1%T^<LfPmtAY|n1*WdW?gZGWKsg6o^?t0f zBY?56yn>M%EK5gT%cgD;8IQakFdHDrZ*32Hw=DT8P`(L<g^x`mINLs!q*AsK7FCdS z@WFCo%|p$iTBtK}zqzy^$ZVek%C|s~-$9XpwT*u{2;ralNt{TSjkIR`)+iKPvV8y^ z1=t2cAwVGNr0>RCl$#Yqh*>E_0M};s62Jl^NbHCo$xyKT7|{=9l>{C3w3^Q2dy?r= zfmo;!f7Zo_P6evBVPT#;R;ntTtmRP2CddvH%e#J2tcj)q%2G+s4k*j)Q$EIlz@p)6 zOlJ4MYxtTpz6&H!w%h12_3?b0RZvKvV$KsE#V2+;Kp82vMvqwp)hd9efD#B)_#bYR zhWMB_AhEnfjl7eE>1;EfQQMbYH8-i|deytDQkGYwgz7cN)C|owHCvB1rASCIDO1Gx z=to#JN>|)Hh!*ff0Q^>hB%Ud3VfHeJ2rCYGh5cFx)hb!oe>Y~i6shR3<FL8~i7!;y zZXoo0;W1qBTm{T^@n{M)winkH5LWEtolq`Pk`m3PCf;_JK^B-zcQE{dTg6#|ej@uQ ziClQ)8V9o3NQnj6aRc$NEr?U&drZ?fZ3%>J?f?wCW0^}e8Xe|Vm1Xi&NK=hw2gazz zAqz}FkNy?S20zeknrj6uX?6s>`!Q|lIC*S{<b?ps`h+(_7Qnlt3`@Q?fUrZ;0#>y- z4Kr&O1lR`v4qx*kjDscK&%I(IgKQ&T2$^VnW5Y_=#(3t3PvYRTaOH$)23fqrOmtXf zVuF$VAi5&^31`qcMtoN8QtrI#_GAL6GUxrHEfUMV3w{-%k<lJ%08qXR7P;yOhJAU# zu<E+;W?1d8)?t#4dG@iRtWouDmVa08ZPd@>%g>dhW)gOhLbwE(^X%}n^8cDBNk)qq zbt0ZYk@pit?l^0a%6O5_B*gD~+zU7&^YX51@_cg5?}$8Y<6ljHOg*M{fzfjs@U9$I z_9nIAm^~P=H=l2jjL*iZ5A2u~unq+*&z_iJkz%<J7@dLg56}+#^N^`)df}t`M66{b z*5bq^!5Y+t9=q`=6mNy%S@m5?VU;$XzdrG7;BEkA&Dd&skLnj7V5LKFg_g25BJ?xe z^DuIb6CyiRwhNY;G!#06k^jOWK^9gB)aOo`7d2uJ+bvR~??$Am%s$&|k=8<fB;skS zP_>HLy^V6P5kMu(4%>?$3%8w%aM`o-p?i?k4Wa^wTj4RIG4bn(l-PNJNK9Kb5>aZg zrxnm`6tt#>hgwu)eSvB;0J_I48i;rH^^iOECH5iW91NLCBC0h2<T&D-H^~BcULPN( z0JE*fp$f90mVj~G)H31sv}P}@*`cR4r<?``88GXy`hXF&=<gt<+u*{^BCqDZ1cj<< znj2Lg&CYYr!^zFQ8X*N%9c_SawTZDH#+*GLL@m|3r(y~WRA(B7cQ2X@d_!IJ+N<>M z0yV!~?LMG39JdleM6Zejb94Aq&|~E_59G<Q3^g*Nz;xdD0Z9W0h^XH<HdJMMm&!&% z4j+`9`&!67u`joP8wTZ5D>lEW;z|JJUIL|MQNFz9=XtW4zbOfx?&v^Z-he(s%|-*% z{QmpBQVG@zP%M?@H5GXT$KxU+f$(Z?#yGt9xP3xC=6}BcM{PIG?WiJ%(3~7pd7Nu4 zlXr~=Bn!HIVL*t+-ahpIH+OD=egXOij2=hDjq-{efz_7yzkvKkJ4E{`&QZJf7@wwT zslogPHJk&&b}4HK7#&vy8ltIsk$6di7ps;#ckbNf%hhl$VpYIw)xRqRcrt2pRkI;r zw&-1r@>rjQnc#n*`j|9Yk}3-@fA|KFFmA|!av(U}up9n5pgcS{{B^=#kG?zh)LfEp zRk<-2{-6Z>h$0Z!jXzWfo*aKV@ux@M-dUC9mZCEODbL*hAlp-#S+BWa3cJ>)X_M-J z{ngrX<<RFiIOckQTuXx#{i|43fHgL%VH<RCJ&bKiz~GLGa|5f*)AVmy&<e84_JDE3 zEcLVpR!d?it4nLzwbp=9?~p?b>Wo((>Z^Wn=!;r+uBOLd?^hdm4&~B*5|6rB<hU{Z zdQD#rUp(qEk>is1>%`s+W8*PHM1~ykD%VWKWs3c=Zc;rvV6Jm2O1c`-v<#T7+FZyI zI}H7ERg6fUpzsZOFybyusQenb<f0)+kIy-lsCPh=r6P@HJ$4jZXp7@-3Cn}^7G$l8 z@p+HZCE0?kT^ph>pQE(A%+|d-Xl(}?7o5-@C~v%$4b4$maSl@*s&$5=OR>sYmb^l- z8XcYL(>TzcO##+Q*d2Waq#{~NrAz@{1qtmu4BhLe00=&YGBikYlY-%(+f|CP=6V(6 zX`V8PauzlU{U8W=@@~5M7NMAdbZC52fSmVbNpRk$Y2h3L+0e72lpSN6!ZY0qRPS*u zBj`P%%R%pYO<ql`^&Ql0;q`FPyGhSdi=J{XhiLsXSmg1r_F>R_KqNhfNzEb&!`j-Q z_cM|7-<b3dk%VFGIng_|zi^0_Nt$pYik63~yi@cG0Sav#%&Ap=%!|_C>J&-HQqb1` zXlO%#%y@RFkw+{s2j;aZwZl}@IFDe3!?k-+McX?GGXd;&v_cH8vrfHO%bq%0OP@Mf z2YzuhW>X^%pzc;UMBk=*4`>$$VFV@yLE6gS7A$&#dM7{rYI4)t_|sIY%1&X+$Fb$% zDnM|9>g}!w!boW2f^2KN0vv;dKkqHPh2KtvVNkR(HUAT}=vf+zh1a3BfqWHnweia# zSL|Y{OU>Vpxu~K^l&iNcxwkHxQajY`sgM2|a<NS@8xYS0LC}lPUW20pfUaMNLxccl zC*}=fhGQdx64SL1D!NI+8V4n&X(81On4wSPcaA|Ey9cDgwJ22d$rGT$SByqkDK;38 zWEa02GOiwvtlj~#38*iN0W}Lylq0R>&N~|W^fC>VS>qc}Ye0@ZF2sJ79Y%4mN>F#T zdv|~}l#be0I$<}2fhUxX+JTxX(AuE8uyn$9ifvXg7KCzK8j}JP3j<a<s$PXyV8*)? zqr-~o{oa#8IiG|2)I0#K?5-a$m?Zw<&AuOi(sR{@hMc+G4W_B59Bot^T63a*>&NSx zlssTyJLH<jP`$YPa+F|-fe0+GCkbqb%4%0pXa>;UY<nj1-*#;nt3nfZjeSWvG~(dt z9?Sx8+RGh~qo~-SjUqx)OWCq-!ffgM!1+|Y1CzR_h7{dtP@a^g;yhRuN9Bi7j>?Z( zl6fe>>NBP-8iAu+zDEb}?6-q}DX+B6GCCZwn^9wMd3Nw~$$$ZBqp>Or@>-S+L&ohQ z0S*MhE3c3wKieIH@>OX4^2;kn&jPaOs9NGKl(Z}?T3|ef;G9wj03XRuFcX3{5&c4F z=D?5vZl#P$;8q`63E7noA4#%x>?XCQRr?U<oF={iEpCJ&sN_JAX1}`-pnepd>U1pl z7f>UN`R+ms+r2mgtqcWCARv-1R{%orqgRl4Z)}+JALR>_0dx@2f<TwoCRidenz413 z>2*WXflW+Vuit_!>N-$7uT{GnP*u`Dy*4s5eQxz<raZU$c#piOU1b*F3h6-P^o=B8 z0P6{?N$}o<z=1l=pmj&Uvp!JMs5Jnfp87@=(AU^)HimX+=Y_ho32MWE90-qs@bGw8 zhH$0`+Cp7=Ef!16wTtcH*B8;0xvnHZ^`EC;WC|{U1!_uh2~jmWlJbMd`s*!dh&kFS z1hNqzIX<+7%!Q`&P(0GcHk;e~;}y2G5+(proZBE9#IHtliB`DqMTF;$#V`n=l@}2K zxJ4|U<7B3_V$CU7FDS9z{S^msl@?$tcL}~GvZInh1)!GUAVI>)%0%2qG20U*qsb-P zlFF*aw7PRpiP@v&K~EorFwgLkCBT7z{|qB8pF(==FE-;Ndj>rCGUymIbsN0zhw<cf zMVK~bEM=MIf=6u7nL1!hn}E%M6cfoFiFN;Z3N<Dpj<+h2vJ}&q0`b_V0evOfh^Cvo zWH#<AVI6F*pB<y|<ilV*mmAaml5LSJa_A&PHQVd(1w#JXiH}0CW}jTMjYw&B)fj-l zb1{ZHQH&@6c;(PvMdIz4IE)f|$Z#EGT?hlP9ggpXs`0IZ%)P4jbVU~5KN+$XrRgcL zuP|b^%4EK4GRgJ45uf2S^L?l{6YE_k65#baP}}(%laVtW)$Ktq*Px-J*yBm6coy_F z7zZR)1GAB}iDu&<U>1Mp6dGWh=_2YlM!f=2%h4vBAqM6YFeG@@&uz9Z%M#<E0HJX3 zFCakyKAr^y;AuK1G^6wdqrU+80kSGzFRKFNAz~E$>1mX|Aq-PyiOz;Mq)`6IbW8Ml zN@^o3J4CVd(P<bX)&yUDQQXkJn;)2l!Oi^n_;b)u@vMu#|04d}F-1JP3ghpE)Xhf$ z1^G`dBE|UYW4+oP$$P@IsaAjUT!J8)&fA*+HCC10CP{OP>|gB!zV#Ee+&<z%9J<Rt zgm=~2R9%SMs#>OJUs#ADvFlc6reFy*FFCf*ScTMZ(4wR`w`X6`(`a&)f7h6Z%jr#q zHY%Wv_i$8Tv|leKgTT0=X<5MdbUR;t8IYjSI8(p8G)|28zfV99XI-4g`B?_#d=hiw zMkl|cHz&iK=Kuj;&YzPp|HB!pM`1!LB$&=w8)=jt1|6MODHN`O%J>prJTIZh-s4co z{nO%6=@``vQ2=e*30&=38f)SI#!M|!CCL|B;+`+B1UXq*ja#68xnxt2)uSl5mEU&| z%Jm?w*6h=<SQB6u-vd9fk*vpfhlT{$JEW|F$Tq$e(UmpF?5j*N83_?Dz;4eAuu4~e zeSTL$Z|Cn#7fL{MFd-V*xn{vaoR_DD7r4;o)sH@uvWFd|Y+Qi-ys$L?>n_DMw-m*x z13?y*Yd(@_4<@X(1jD}VML&`s&nLs^oms57C+O{vAA1SstN0{_jXy!yc*G{jA(Si) zuSFXHB#tb+Y-hmQY;FhgQHzMNtWv37DwS70*r87Xn%A9&H18Zh+CvcHuUt+vZ_pZH zY2RWxcR@6pVN>Ed093Y(zds!lulBJUZKdU<w1Y7T-X{gDyU4D-g=m54WQ{OUA3|mm zMB&C9?~f{f8vPN>x~D!iH^3ftc@75h&7#Q*XF|7f*o^Oj-cKujB)V65h3Y+4k)?Wj zD$|s%5}QlE*zihPI`qohqfLknN9)&O=-Hc=KseP8<4|gCR?O|@Mrvtt#eWmPxMAXh zxhe>-2jE$$!h9u@j0F8&;?5!aBT9#y%V^K$<EG<S$e}+Vy48P!R@?dl)w^4_0sKSw z>mp_j#w?=7O#9E$EK+xI9?D^Qc`!0@2bylmdjiJPlaijl8l3?6wS!^s!nTuWQ31wQ z>>}ASY$aQ4xY!M%Vr)c!Wu0s;c4L9&Vh27z7=>J!)id%^a^o9Lv6KWaVz>o_TMe{R z1q`-;NSeInCwU;??X4UQsw!^)B350VXC5+5qudRMIsyL5bEE;XLD%#=7^&SL85+OH zfmN-TQtVt~y2D(Yt+JF_hiazCD;i=Bd0i|2>O!)U>b7)iEXB0OYpU6?EI4p42Wt+n zV*%F5_WJ6gs2s5meRW&R&AbLM!nn%RY&H8H{W{*C`N&c<5Fh)=1q13+x_k(#s8nT9 zEh}IwCXg+;u`2-zPhF`bT7qWIK{?sn2rcQu`7{_&qwoSfS0ulA6*pnY0svdi0s!q@ zC#&hz-)t9~I9*4j#3oKlirDwsgHrE26n$U?E)KBmr7Vhjdw$jdkC}ef2@l%x!@WO# z&r#DX@$3kA_v#A&J0PED-$2ot%))%-AW15GR;co_3Tk65E_NZiqfPr1h_i~Z&Fm`9 z^93W>&u%kKxn_+dc+=o)5|tJKxQe$~n}kN`3BmGu$XK}z4KyvFb&W+Ucj*K5vr4U@ z)~aF<!ZU(wJ!C0^EHK`MkLu@R>2t932r`VXM{9UPk6l>ApK8ETUDFGzG==XPboRc) zvd`WZg*8VnNkhFA2IaW6(pPt}f_q~#-9G&BD-86<r^qy-OgSKj4y1}*MYNeHYtfLc zn$3#$h#D5;Tz;Y@6*qM{rp{V4Se4gpoG!0>!qEvMVSFmbtP0ztmakXKTh++W7D#$3 zBj-CwYB+9#wq~<Uig$+`dKkblq9C}{I^uzg6M<MFX>TI%Tq5uXXx2Dpk!z+xzy}Q* zJ@?2@E`!A@hpJL=?I>~xwKAipSPpH+5$GwALz5}y8aXtP0yk<88a=b*&=>S}n>O6& zxmyl7>8)H2As>jUHYCX<Qoz{g2zb|P7prU*1omp@D)O2yGUfNA%E8ZozEy^VBY%B+ zPjoPpz|ky=I%wl+OzB~$=dcxquzN!RbPm>$yylzC0J}pf@pdb$X*KF>vcCb_fIK-4 z>;@Xwp`Aq4s_Y+=b(k<NdPMp`U413B3rpmcr9HSUSRa>!{H3gs|G`J|u0S8gK&7*Y z&<#=QN_ybUk8ic1c!_7}87&2nahn{|d{rA=iqYmPfys}jE9|Hoxd=C?)}><h2WZ^y zm7j20F>v3qZAQ=ia_BG({?FvlzbWvL9Qq>#7HIbxJ(Y6kd!P?Sk1mJWD0;D6vlA*> zbsmCuquDaoUzDq*gR+<ckn7*7`J2`DW3h2CGB_efzNHa~Wtc7g!dwk#Xai<DoWB_e zg+Iy&Iux96l;l;Yl_I@RNSG=Keev)d+YL>Acd$T-+;F7U?=FqqsE}lYX?`q}9-9_m zOKJM~h0_v4D2EoG#C5yDrP=3(uZ*RHuS|?-bUw~B43&_PfSam_DRM;`KC&t^O5@lR zn@qEYbqs}HpO#iCzgN-|8xHdaj~t3iEiH$zt%Q~I(0g{Ncl}aFpnEsM<`5NUP{kG2 z5>^k>v(%xiqq)sgj4!%Nyhlsq>yP?@k<G#FADFxMa2a>+9@RQw6AY57u&s)@Rq<|m z)DCrPE+7r8J^*XB`!L9Mk?93SPth`~Vr{Oqs^;d{cJ%haDwOvCYt8&d)ojG}(_viw zvVm3=M6vWLZ-E@jq<!hlCL}dk3!<o->4SV#r|#30IFLng0F~;~=t{Kgd?m8(4zkQ_ z;}7E=C{Ta0)S@g38U*W(r7G+GE{R16y43RH5{)Jhfm3RE7v@K5#mmMC++XZRA0&|1 zghj9kEn~Qg{W4MS_x-^1T;_I#o%GaKe~q>jZH(XB2?7MmE`_SOgX#g1NJVwuQ%}&3 z^!Dh(AjbsE@s%q%N0s*?-9eLs)?8o@*H0m&!Qt^2&2-O_Yi8gW;bdNd1LvqrLkzqK z=BsOiMa#jLe9{>}cv54z5SyY=7FUeJG$Qw$iF|ZkzUKDlcSCv>uv_S=FUU3m%XRS& zx=oWJZ~%fByNeI)A$)ac!{OJ~uRsC+I~0Jb{hs<FAUB%s?OFD7mBsu(NXWmSK1Fy3 zpn$Hd!qskWQ;m%&eEQVHiqJ1*!h#A^T{}0({O);i5T2mo{I}i2j1}*3{UriFHh~_% zlhE5HHli1zT{vv_i0n|04{BdB5~0?H_Uq=sF3N&D4p9WD^AOr&&mf=@oJ?hcS)tSc zt8q3k-F?k47{t$z0|KY3aUU~Hf8kTTZ1V}hHvdL!lQm&POMGko&;hgyKI?W_X^Vb) ze2YF|*98O#Xj9;Ko|X^4^R;aFU8Mh>=ydGKs;lPf8OTN9H7iyHgd!)p2o@3qT+yFF zpe~JQ)zmBWp;eDsF4G68Mso^9MX!hCsUC{Iv^V}cIeI0=-vgWzpFncY!zU2hvG@ea zIvk&i<&ca|;CE^8L=H8Z(AFof*h2h@_gsN~kKQJ29BqNqJ|&2feCqe62?GUC`=%U{ zLn&mRPR=mudzy*pGeFCsw-@LmN|;W|5(ttU`2$3ku<q!S@GOpGtw4tDk7(-l=u%2K z64et0$0%{?2$PN?ogBICG!2fedv{C*Y?v9zs>1RSzq%bWM5l<NE=_^o3ECy_o3D+B z-;1;%@LM3)<cS&_Q8`{!G*tvF(Nkyvfw4`C9z8`-DbWL`#NaHzpIP`b6Mxha_8Ig+ zFm_UHe{4_Q06^*46*t$;1HSJoe4CIdx~Pk6BfUE70uZzp=LN%aT)hJC@;ILc&F&T8 zlFQf3LghO0lNQ_w*>A_am)#{EGvIC39Vm`Il0y3Y?;I9j!foMf4b9|sDH9D!yDN)J zY9Da~j7(E$Do)QR2|tnr5ryzllmS0eFs2M*f&rs(7Kqu`Cl{`0WZCCJ1aRFY?w`n^ z08KTlWoTOtdCAFho=q(;2w1;gD*>Y{%9De6M6JA=<w%4y!^=;Cc1C?b_{R$Pp#trG zP|r>?`$kAstQ*4icOVdmFwyp&O63QDD^=x%RcD4gz-*`cz~0F051~qEHhUYFgaA>- z%z@Wf8UTaw3Nsb&{$<Nl<430U0Q{cT?giynvS@eW!vTwl4Kkg<w}l8F2$p}1K4u_% z0}mZr`oI?;w!47{q@v>yh)j|KvVtQ3Q<k#^jW2xf1)^k{0=zCOMzgdN$z*c?73U_0 z_r#LNN*L4%q+`GOz`j|kb<ECGbeQm(s1bTkYpGQ;996MLn~ELP3M?!WS+vpc{VKp8 zv&8$g>~Arh&;LspF46ntS{%|6GD-jTU!wUd)v!liQE&95=vbRCmTvS|bsGd7YGg(n z*2!^L?PhUSEC;t0CSzW;*@|u-in&2WtAc5jpSS@{+1bNV(M{3yFI2%|R>+U0n&rY& z1FC1`qyT%Qpp=yt_L=~C_iAfe^@;p~l(X(@TxAja8dj!^7F)NV4`$nYB=V)H{-y(P z2TCrW)u93NSoIVZ%i53p4Xu?Ri{w}YZ^CD<^JbapY<^4VE{+tzo_)Yopml!gQ6Wuu z5vD>SWW*=ukd%O-SwVEVi^~aAEo;Pgm#3AlhSD(?vK(#~(ut_Q@BL+3GU6Sj=ixR9 z_hmE^;=^J`(sbs&g_csb+jN?5ip8&*&Trl%yI)q#KHU*fQ+Us1m~|_}uEAPps#m>9 zTn9(y_Os~kpk+rvI9b<)GWwnX>rvSe?#mP19vOrVgTlO7DCp={hkJwO_Si()VdlnV z*x}g&^Pp-u@AMB{dW{VQWJdt5y7LP}kpOG=M|=)%hL&&E2dvwTo{K7uM3jR@Pwt}B zRiK<ojnxf)+}cMJFpdpU<g4o&)u$EaZ?H8Ad*31fte&n$>|cKgBW_cT`W$itp!8dk z(l;m4hf;d)K8z<R&r7{|!g+jT9ug_%lV8TSae|Su91u9Xi2UJ{UO%TZ*hSFM_^`3X zM04joo?iEzNk#VCzL%thE;OaLyn&?quN;H}zjw^^?{N-J$k&|mp3+;AtRH|;eVZM9 z_DpDOK_2i2moS=PgGXRCfiaonn1*w~?@#S*`hp_+eo(0wj>o1;`!(JC9W|}U*PK+m zC-wT|#+Tsi^+ABvt+T_>MO#e-gNm}*7Vhfn`^9RFsR0zX3MjV1x_cd=_)8oLg`hYJ zP<*F&zth+K4^W)lSJ~4=h<reS@ei_32{U&hf4T36z_cAr05hc@FmE4C0Q0@#{a#<2 z?3vyu5WCl{7<bdIyis^bH^6G@G11k)bXL7iYjilj5jS9P0ndG%tePi4Aq-o4ZGL_G zS2T<Tp03Ds7XDL^43<akwBmB|j=5}zMOu1)u>5mi!w#!Oy4IN5A!%jTvaF6SCC|`u z_*)*~FPUmKK~-+!#Ly*|K<0fQf?+P<jrQk%(&kl@i2Rf*Ci<9;Spn}e4EN`f*@(@> zo+NJ;{&foZFN$TXLI2S&VRmDGUj!FZ@^Iq!xUExD^sBm+JO`SyuV6*_59idF%P!)h z(E*s<nB!;7(D~0m$pPs^X2p4-`iEts<5ajfFP3J^$a5K6A>WJ~qufEwYUop+*?(`c z&sPu_MjFRcSg{NFPienVvm=8zM_yB&H>lD{dq*IuLz92^N)oWhdNS4~_JOpx%{dsp z$DP;b_v2@WOFUnQDZu_O_n35M!`Nner@fwQk>tqZD7ut?3xm7NLNmc7?WfnWp}cE4 z%)}hFjo0lm&E=4Or-jCu(-d8<7^f}zP+o-81DNVW;GceI+#MTLQq!dmgG?zfk0V90 zBKx~>J5goMJgQ~r0jPNOE<BHb0FeS9rU{K#ST_{;PK=v4J`rU10ITZtC215cN-5+U z*Efea2zg@t1|t*y(Lv{#%mDkyc*J4RC#vO5Bny~LDu~lSAYbi7CX@wiFOv@%Pg@li zLG-^qL)P7x0|J3}_mal=Rt4E{aUKC4Uwq}N<;|+KK47>vpp>xh%=A-@j2YK~4PA5_ zR?JSQ>`Jw!OB-c8>ab`qxv*llzltea`4aR{G0sDW?Htv6YRL!j9qugZL8|F|=~V$6 z9uWBa%*JK1JlbF14;ihkDueEs6Z2k`q=Dl^1V%02vraghP0J)h#c-ZCLXslajp2M) zV$*F{2V(sR)e7>*MK|q7)5DTeurO?_DfY-}JPXMi$qk<9k<2H<OEVo4gi*PT3_^S^ z{45vc^owa45UZbd3A%#eD%{#T+S6OKE0z-o&psu^(lPZXCkPL-7w$*tKz${#oCi+I z9gRtQ{^fhr$g~&m9Eo+GYE0cP>A4&&Z_p%&8o9jv6NEZzf8WA{vHIfW_*l^*67ESj z2bZGX+4K&z`>^V5u5@#iJnsiecv-Yx*-g7rcc}6k#{~M+n5yjW!8L1kEJ8EOUyj2l zmpOo<o6ZYf5ls6cW7_YJqbfcEU9R65OJlQHt=Xr&)ojIzW3S>%s(49|?t(tQfdTRm zGEsnB4xJzncF3V4VjGa{LFblnN}Ut}*$C}glIq<hKmHD>WVc#sElt)bcw~>YmqO1K zrK(5*(GeHKY1#Na<f=<i&Gl#-Ypj|g>0bs|E8krxNmYdxYeT9EXKRB*=E?`fQ9yLU znS+BkA~rala$}u^%ByAr)UHP{%RJ0-Nu33t%AYz}8z0X)smVGSJ^2zv^9B};Tw_ta zO$&3HN?`E+8&rq2=!6!_ZL%T;PT+sWDB3I-Fkc`Ty$M=;f)D;c!0XQ+e7G;vPCBc? zjw!5@_v{hgQj`4hihW9GiFJ%V7M8Y?Jg8Jwi}Y-|ywY~-geIieNZ1J<dcCDU_>P-f z5P~vnd=@$);GDActX)}cqp5BIfQe4FwIw3SktBMXpn<4&P~Z5iSH>MeQFwQNI#ElL znjJZW3+JW(LOFNL;%|l8FpHe#XNvP#v-qw`DSm*=SmG{|GzAYD!n9%qexYL&h*OHV zM+;P@@Q^3~;zH0}hW4*ns9MYcouLNmij7Zf#em{&`&Ot7^lH?@u-bopi1xe=P%ZY` z4+<S(xyV2J5c;%S3X$okOxQ1kkRZkO_T8e{c@W+b4=*sCZ@q|z44#F2f}6ZPNt}23 z&5OdH=M@}*rSM`*TX+zOU53c__#{l24GC+~6B@_WFOtTAz@9}ehJ`X37T7uqsXpk& z>Dj^WYe$>VJ~gs5M~TcxRpgb8{_q_(_;bKt*4(470Y&;T9y`iERc9M3(AYR+(T}K+ z$QY<;4fe6lR#a;N>{g8fm~!?##6JIzDm#tL%3ZzNhYKj?FbmjlhCw&n{DLH{#p-bz zdYXkc7a?UqZHieBtJ&LF@qL}&eRC6xr3;UD-5fh#UU7>BP`lpmUB76UlD|E`>aUFi zZ41!<<t-O~csm_FN~uc=)$8xGtFuVCL<89ZL=|?m4b&-tDgci)epD6BMtD5-Pgjwi z>yscKyE%&-e=r~9L1!T0?o0<9StBe})Wz<ZdgdZ21B)nh03}{(@>Jnzfe@&`+CZi5 zvRbsPs`Q+?&`@j-_Z_S$+Tf~m7sf!*+G-rBSXxuHKsuNVbA7;QOu<tp`g^gfkQ-b# z1_t7<O2p?fdPXdAKz)(vu2`0WZ-byNU>5`GG1o&)-uEl$)Gf`Br;Yz+r%C1ooWuT} zAn`Mw=uh-9o#5?BxPx8|d{7&r8mn+qO2T6>PotA*>}RV{+2q|l#4i6T98Ym*ykjzf z5o&(qAfr1CtEmrz1>B5B0U4e8Ytiid<WZz&_D}IZU-*}+#A<v0W3j>tIt|G}$SB%C z+qOzt`wSO<d>57^I$9_&RQQ~VGpguW+V+8I8WVROLjCu|X?<d|z3Grx(WcY)e1az4 zm`oF6CB}(U`ru~!v%NV7LC)9*#)*^qP$II;_NsUq^Vwo+&)|ld@Ip=Ab4SRaXW<Xx ztA%{dj_?3_lk8(X-bOte#W6dGW6?Z1+<no<AE7s;%3=YwQ9<W;si;s6oreOewJl)% z2HiP~WA=(@waHK6Rwkabt~R3-CU2>gpsn8ZH&7WG<<QrXu+Nb8d}%zgi6XBXjV2$Y zDtyEi(5{x*!gpr*i-5Sxk4NI9_}s$T?sK(^3TIigN%D$9d4+269$Vzh-v)JFIR*f# z%CH5j9|ZE-^zQ+%l)^myeKm6RIjc`2^Km!=)(w=#uCrA~Uw~zyO){c3ZL|^1)^ZeY z8;Ev|v5~86Hry>;g?qcPtW`D#9_d<@3vc18v;5(?j+ixkr$db_%K<XC8aGIQzC}B5 zXvQ4+26|kx61O>9%;<*$dv;YDdZW#M5Jq;)BX}0rdQe$|T&*<XKbV8w1BH3oC55+I zv<u}Gx$+9d;@!RoH%l%Zqtsay>j#R%g0ZF6Ht+U@-{4MZ;Rt;j9^)vrepH(OfxZ?7 zuKHW-8$znNjc;vQp7CwAmW76ak!wZY){4HZ6@6PveY-PDjoh3Qh%7m1qfW^y(~!u` zMKj6z6dbpMBsArH~D5Et>5cCkTHMeJ>Zuh--Kj5cr-&_IL$wVvD3$hygM$UFTn zxadIoTL*7`*5NI-$)P7<#8$g-J8AYI60<>sL(B9M;yk|>%d|yVMOnTCr8Mltv;M4& zJJ77pIApGIQ|4b`=1#+6>LcSXpee22iTg-x+8}=NThm1Q@x(WF;+p@9$ZfTBJx&hh za!oqa(q(Vi3rkL}L4`q(g4*xUtF71;wr9l9jm#0Y+bNJ0wo4e;h32+k#D2>^0U?gt zmyS@&H_0pgGjirC;gDJj+{j#ySz@1wtkuU6O_mOaY<2z-qo>z~EUpWBGkuC`W3`FP ze(6ZHd|O>;1oBSIRge$4NUe;00xNv@9_)Z*>bW3uXY3LEwDY0RPc=N|*ly81(TT<* z(D{6HKspyj;GZ90=8rTyoXEd`ap$*ugSrWdkukdmhV@$oz0-Ov3ZR0Np`JR6^wc}Z zW@k*xMv+?|y80A4aUO=>W_$NxL9j@JpES@0p|a{pG*x@hPWLd#EtROicpJ0_Rc4Ug z7vk?W3MGBE%9x8HTD4(D5o$MHLJ)>E@Zuj~H7u`xjuA;Y_K@Q#!%Dd&DgOI|7&Z#x zja`F{O^3unjHr$x5#jBWhp7<t9^ricHvX=NL)Q&_eO<g_HT-!Io<(+Ry9*^C;5Z|V z)p(-}!gaToV8IMr$IOvOW|4~pWWO6_yrOG5wZSTru`e0e7dtP-e8!_a$O+l?j-(V1 zr8K)pwt5$@^XStRkvl~PA4ItsRswLe>cptp1c$434S3HR@LtgGJ)+DK+rw(aN%B`w zStqif98kG1ONvD`76XjHQpy}jadZgHqJxfJjlJ$Ps&FhUWJg1-jU1AUR<qM@N$&@w z-{R;8q<GI8@LtgGJsHTsKLpZm$@l?~6gLn^zom8#p=U#~4Qnr!P;mUG23c;<yF<Ge zkJhnG{Exr^N+EG<0A422mhTiiQxma2`yuXPZHLu(oG4#ol1(e_Lmj1-b|++>A43T( zuUF<7#9Jx-X?%_4uO`*|^tUMZL|8o$Mdu%&tNdm<)3RG+`1nwg)Uti6kXm}}m*&Kc z&qz`mh^Xeowa?I51_-TwCVozjWzXG(=6h4iHl3JmWY2^MliYO8gJREf;PHlt{f56I zHLZRQ+HY1yBf>XVW0x@0RE?V?#ZA@S_<+opZKuqudWma3b%_~*7)x<#<%E8S9%WK` zcx}BfG~l+L{jVQlC59LU8VsI;p2woZo`YgbqaazA5HOq0CjjqQ_A;n|^_b44r+W>} zYDBfHL4N?Q@PxHT^RVn2u`RaUbUsgcH$&_&koUgBjWy?gVVp6;VTP@-H2!Rq1T2tw z9;dv?`vLJe|GC*~NpeKg9DdQ3q$#3xL7vOKf-xN+3E-|9VA9kmW}cynx5?sdmUwfC zw|U}iuy|V_-fZG+v3TpE?lGcj6!E2qcur6w<8Oj^+4&ZT7qjupgEU7>$lEASL%}h` zXoo|QIa`y&>{R|cj#EJeulpu3jeb!@Vj8u4Gy)wx0WEu{Z3kwgjf9Hs!=u&S9&M0u zm4s&*f#x3Toz@ieAqH-B1sBs>IKbA-@7@MXsO<n*nCAdz`6o?L<{waPj(i}D?kY{O zP>gT=s&}3*Vc8FS5TEBYzb9MiIp~G5na)#~&UL@<ooC@qoW?hwBmt>!Zy;HHo}-o@ zV+T+-@CDd*{zeN3Dv`S^O7#g`6^qD%;)`2Q<dwFEqj*?_b<>_^!)b?4Ua^(`$Qjot z5g1?X+hkhs)xP5n<GKpD>yS+NBiCADLol{h#D*!BZBpr|`Am0VFm9A!%23i;6&ryi z^j1)1g|>RIfXs2j3jOX`Lcu7DD;S>o*hr9N+zTdb1odN9+^$m=*I{tWc20mj(BHqG zWWt<;FMn7~5Db87FJJMgX|fr4YI$c@!(;kz{>kSkc;Gn&+FAg4`Z5&58hlzdUr%Xd z?)uDQb~RYE5#dK1T@5*MC`^mLILG+(v>LXCXXLTsJV-M-zBO7>!o_*7kYoA9+_SFN z869Zq#C3g+=$Rnq-amvkIY<m@$K8iw+7*#QsEe?C+zrWpAV-Z%w?HGT*lo6WzYP~V zmW}YUjZl2uIHV)7TZ~p0KoGqOy|Yi7+63eDY3&>kqgB=f9I5^*be@en{<h9ity$}1 zX@H=4&CpN9;nIeCcCf9WY^QK19+Ck>l|$ds#_WuoI+(OtOKjM?mbg+?09n~aUQA7U zPsueKA*Z|ojaRfP*!;d-AXk6CeGt#*yIpjpRY5Rvd2KsXam=$Xz?!@cEfZ}u^*P3g z;T4DBM>ak{!5r^g<R%&>dMrXF7g66#C4|W~rWG}zxE#8h6hai5<<K8V4w{w+%98T# zP`Vt)p802-uWbRglZUPl7h?^ySMq)P=>XKR{pga08m6bU$$qGVRO1Q1p$0F3s$PDU zEM7Yx+nN(du{~$2u#PIsei?G|KMqDi2dvnhsSB@$$lqdQ&0vxl9{Y@7oIw=_3qMh) zlWKlDmo7g`)fbb)f_><-Xw}$>v?_4fS+d$NYk8x{R%)%kp81;`eB{}(@BD;D;WvN6 zQOI#w=$4h*B3J_@tG`1BP3J?uCTj^&u1m>p<U+N4pK67P41VI^Z{{LMGe2>Nn$cpU z1{vsbz?kg6Nto7!KtDe&(BGLjmm_9(ke4Q08y=s3I^Cy_F{TAKz+{8KkMqo50NN<_ zQ2vM;r%88W(1F^>wR!w|+FYS?V$0B=61KnpCD}hW&{q9E-5x2<i>2cEilqBU2JU(F zUGsOCKiVX=N*GkYe}rC<tOH&(e7(4vD0;xVL4HiQ3HAi?PX;3oIReHhhx{0x>B0Tw zN9ib9XTZC$a^@O3FydXW%G0;2*6pfydqpnhd9MSRx$14yM}p|K50qw?>iw|dYE1h( z_R8C+6{!uTRgH}9K^MipbW#6~et~Ul<xkQpq|R_~LnLjdq))IqzF}jpMJY+c>VJzG z`9%;Nz)jKa-DZmz<0Kg@GNzc!ztg6^c(${eNj?e5<wl8eL;p|9H3GALFM|dEO+d20 zH<Q2mz33!e&-ATDkM-XK?svaY!)kG8&!JiI1aP@JRkgNw>Z^<Jte&2=MjX()Ay0m) z{%B)cuw0o6Ya+;Y1g#B<ywW$cL|!>7_1Z{K$}6ear=7!Y$O1{cB7-Ro>w1v1D`W*t z$_<lByqhaN!xn@PpJ*S(GRPW&k?gnrj0ZSc6MNC)OY<9mM`KJa3TJqVmHFHad~El2 zqr(yx+b8wThX?19)ozcAPd2kXCh^A#rTC2&;!c|Ec2tO;_>QLi{7>SE>ru`=ldYW{ zVaNE*-wWe9;%}oIsw3&Y7NxRax&0M7soY*PMH_-H-^ThJwV}hNS{o2wqjU*S;<eHS zxvT;9e!%;_94aPXr|FJTtn&&ye_-_3_3U8yHir`Nos3QtQ5NBaIGh@NjU1`N|H22m z)@B@Y$Tghca5}f3_&j6_+66b2vQ2((`_c;n4WHUTf=5slG$S|Ul!j+pdRX??ZIIjk zCHz`jAm@_3)l+^YN%d?kU7L~BY~a&C?!K^k%5q3a#8qS5PpYT<Iw=kpZ|u72DZfpM ztHHP_)l(u#ad=Nb?A+=pPbS5oCqQg)^_1UWT!x54`HB4&Lv%VoF}H^au2>ok4lIQ* z4Mg<w)4~*XmVJus8&KU3Xa86{ZWNE1AJNtd;C;3N!RS**5Eo`AyTBxlHnKhBy0F00 z#oCPnDRKzSP!xDxiU+C^f#npi%AsFUz^0WN2U4{QjpG*WF8<Wsgb7C-r}euT>(xEN zQrS-4o)cf9`w6q3gGa(EeL?h9VJ`cVNPDVZ+OI^~B9XQrIW4C1XR&Xrlav~4<pIK? z<)l!sO@O_zO_Ee}s|_vs4LQBYx*l%><^5hO?U*eE)_vq|M=86|9UBYHcJ8HSqkEH@ z<;91Q^m8EW7Cp^VAMKLxQiFqfh7u{Y^79)(TLm@40iACJYQ5Yz;n0Q|Co;8M<AhDi z3gRh1KTPC;*d;->jxLa)yCIGL!mtF{^&x(?0uiG5ar}J(QNvC}FtLbb<2h~CPUjHp zmQ9G`xER#(P2`#IICbB+r^O-cdIc<dcPmu!K401i1So8C19)iw-UT2XyoVU*-LGe} z-;-PWHpSc-v$M_c@b1?#5N<obtq%@{30BCO<_{Bep8CYO%|ejDeLp<2nZ0KZpdvg! z?e{dkDKwp_b#&ncokkxyZ8)xuOj-@5voVaDu>1VD$0Y8$D2&(l${s0kFB++**-t|R z|JS#Ic;?WN2|U`-ckVLjo-vhKstf5vZN9NM&!$ggKG!st{kJ1D=d^M77&L7>KGLR1 zzGp0YD*xqin92S$80hPpBnSPWw!fV*?$K8?ZQ;jwjEdh9L&O}T(hZLGwNH@9q00W< zRbJPk^eV5Ud0-OGukw!9(>?VyCa@mXBd^Hh3qK{^AhzKfW80@fb_mp2L-qR6{)+us z{56efhw)T00I`G47L3`~M$QQ!@{GbY0;nKOodz7Y8C8$dblK)?tA$$lI&zJLBq+Qo z@n5v{)B}9v);3}C0#Y<40%3&zUMyXohA-113oKf(T7GDa*hk*N7h}<I8kVU*e^-=0 zTX<^zS>(<;K8RnoSl*;sVTdICd1z@u8<{=$d%H1p;*d5%>+_^$`}g~LExl**F95`N z3GbMATonA{W~8MS+|WOxUt*t(H{U&{lpPMR9>us9nb&84WlFO}c$)0cfIO!Jj13OY zL7cZ-n74zz72{#*V1gKr72(ykXkkdJv(~1mX0yD)gDG42-}cj_4jGt%?&0myMgj5o zr?2X?OG|~{bp3CbC%x$!Q;Oj!DNh$(flJqq0rqJ2DsQ?@H!vNh_{~IqzR(<j@KiT~ zr<ken{ooj8GaIVBv$ZY+`HIjceN0W4Hb{*WTdE4jLp5x7EE8v;rVCN9vppKiHCwU$ z)TXrAc(MdQu4&a{h#uPYHC?)6s!O|OYPwbo19GLju7z(vr2z_z!V~Frh`7`@EEw-* zER)V#nT;4nV_-H$Z#6|RXh(`?j}A4_sQHCv4;XGY<V-!&mA}c7D(yYeVTm~EckL0V zzw2w%WTsW^?9=B|wyVir@gb3zvJj%y7^Ej^c-kN74wij5vXX8^mwNQdpwmHwp}n_O zzl+L7Ir3mUWQqUAs@}tuv(@q-D!s?d${W<k(8H>?y+TDJt^EVBf}s0_!HBK1uU_(f zjn{e~Z6?w6OVjqZpggeIQ|}Lt*#=>9k?-fiBK&90;$Q1y*}vO~)bon~`$&ms?i9t_ zreA70-=hwrexhYH+aKI1)=zAl>HOY6x$3T+;<%)LE65Q$<Hup~Ome{ck?u5|kM@=) zmN$g>?1{Plq6yky)p{BN=jq*vz#(*)EX1DzHUEU#4&1WQv%?>`-r{LRcg9JW<T9P( zvC?v`c)!sUq#7UYAa0I8UeZ?umZJ(htw87|#V;-R%D{668}v-vGW_!gC|G}o^xwJB zK+u|EmENsdI`m$y2@=JA(Ma?_4o$%$ONB1H`>r0IdQbe>ncoO%dU+?-86aSKu*ZX_ z;@MC^R3dNKCcJJE2wM9&M4?Qlk1B7DPZX-QFk5pFUFXrBB`Q_qHUvBbP>M7^^q?s; zNF|NFFX-z8y2@9$AtBneH2dieSHRd*Bl-U7_#N%U2koQ&P3+!XAgS+N`uzTjp2<hG zvRTVgySJl%(7#d2jo)GN^<zQ{hu{Z~5eE)<_L<IEN#VC2BU1zlDI(%ej|m_C!XW4f zs|4Od%!J+QDo?z*pm%=|m|HMB=2ve6&UC*Ip(ox>DEwzo%98H`tNvy;bhy-0Uy2?q zfEjq9)g=D=>o9Etro{`#?|Y<y1i2;;@AAnBG&dj<k2&IbmiJ{A^(W4c7{^ZQ+5Et^ zgv~GZ<C@mRlfBs?82rj}$-C3J{C(PjNj8}=+j@DO-{CMie6jKTwQXl|PNb_&>bJ(t zvW0P5M8ZddU+}N^-CyX<mh8PY5x<ggCZDzV^<HfQeLXtf`u|(gf4GkgZ-m>UzJkY@ zHF@sxI$RZ@9ok(lr|Cxns}lEV_1)E_vYb-Zg05yk>n62(N5In_nDD;FRaVvm<!%6u zc1`>$ts)3t91oAfE4D;1Bh;m@24ZLdAqRd>)9)$zJxRYO==V7N9;4qL<m#8a6~89i zq84Sp1Bx*4EFpi*_2ZG6n{Fl(xaXiarb1U*?bL?^y&D$}QoUQWl<@gLyk5Xg!<*Ge zHv`o@cwBy=o40R?`!XhbF`{VY;$O9)D`V^-HGU|S%-DS9n@9=(zm=i~hRQWt(Ehkm z93Cap)Ld`F!l3H?9tfoO)WYl_YZh1AJo_pr=;d1w4e<*id=><m<SU#n?B9JB?j)~= zIq30#brnNhi>7k-mbfqG4}mQLV5u@Wq|%m8UxjqEvo=-revH1ZNKE1xzdkL{Dq(q# zeuxoq^L_Xq^ibFgn{eoXW(v@@Py48}q2bwqH`x;(Hl4v`pe1b7h82l&at$67#WsHv zw#I&CIzvm5)%-%P>BdHWI6g~Wf$=GBJ8K7LZSL*heFNdX86*09Ha``{!NNvk;xl+- z*AIOH_5j!JShVClA>y^Fa>+5kvs<^)o9^P}Ajhvh2dC+hXu{-p7cIi<%eK-rmUxV# zVF_9FPz}AX$ezCyH&Ib?z2PXyec7?sc*W*~12(^}H;8;{FwZ}V=RY_1`F0Q3Q~!a# zENu+4V+dgeiWzvfVC<)O?_V1K4PZuWwrU*jSX2x^KDi~qHiY^?00)s}ec1=|Lq+yQ zkWVW^nE!l)V9r;K6CDe2ho3Wu;csm^JAC|io8qTeUVem5uT0y7r&nS-`I1D!lOn-Q z3E1tm1Nu~e?$dkmqDqh}FF_~3YdX~KqXBPy<ph2?Rx@r%vSA@UmNQz(BYavweq%Qp z#T<OhL}8&u4!xB(o=zADv|+0EL}f1C{~5_j!$D}|xi4Yrfa5Fu_H7G{ZD#x^$prp- zD}ph*KNxiMa6^k}W;VyJrc)eK_^CG9Fl0SkzCh?O-ex*x!Y9$?Sazs2HbiAJCXs6e z|9CUvY563{D9@9G7?JQm@AXFw#sLCopfpTEO{@I7dc5eH4{PnUz6{i?@&Pc`96J{P z^J%HZ-FZ?hkH7u`8L~HXCmzY{!BGB-m=7E7HwLbxyL46+jDnti@>ATM=m4?fg?~s1 zmsl61cn*5Z62?(!D&GSO)mMV|j03s-I+e61eKP+Q05h(T-`8@6*`#4y+ANGkZ>QqY zI)T^NMeHX*!3i{+wkyWhW3Oddok2jEveF04SxTKI7y44VeA`ch+LS`dlSNNg*v9Vd zFI%+bN|#@DxU_7~4z`)Lxc+z!UEKI>H)6OPI!tFR?axB}*D_ltWKVNc$)UZtuhT4S z@R6A)%GK5r(YIG@Mq|=Y1R}t)WcjH^)A{<t!teJ5C<Q7+I_Pt9=np9<vN1@4ZU#XV z$4i7tY7WYwMJXs~fh7Mf?owms8iQo%neMW>%o0%bj%BEkiyWINZl|QkPc<pVlHp~N z=2GhX!-KU!_Z{Mc3$=dtY{j?-k`T<<u>fB6w3+&*T^3*))%?bQb%Tn#XTREJ5nRhJ zisDx`F28{GrRC5<OapClbmH=`_bDeIn#gdIMIcsTT*^e3cGP5MqqOQzZ~zchC)p*c zDlVcIFNWdfI5<LGApdv7Pc@Q#9^N#_vKmks3KIM{qJFl~bbho*jOcVI#7-#rC#_4| zzM}c=p!@`?x-@Vlpst4Akowi?tDTQ`5M;NtO0@G7^hZj*!!~-WH=R}Sy1zn08%&L5 z$s?xU?E@9{UPK;3p%i_%ywVC&G1utHn2R@U;3TL<V@gt%E98|pM)S@^K96^m)ch8! zY)%2lv=MB}Tv!2q9!MnXi_K<ih&3wt8x-$G`7sL+CRlC3AnLWaaav=_HLI+ML~`gC zc<0RtyIgZG1o)L36Cx`QLNJ^c-F?zD>#S7NY`&HSzsDowa`0N_hfuRWjqdot+G8)8 z&Y=tOV+66^)BE25jbCd)gwN`v^#KUK2|c>^1=u%)j@xN?0aZ`pS43{i_LI#y^0wQR zMu&_yiXK#+TZel5#;F;4X6-P=Y*O)m1Kt&$ioxn*<`7A$*iQ5kMF}kKXHEY6dH`Wk z3%ZYLc>4zQf%XaUW)RGiSY4*`eVxojms{~@XS@bAzfBNN^x`3c;9W*gTaLL`Ru zI-qD#;eIh%$9_kjqZ=Jgr^q!QBziU;dPb$r*0)RKmC!k3V+x{xF3$}QQ;en*mHry& zZ*Dl1UaOCt#%^vrb2pXd|3x>y(F9Ij3qYT>t9wuVpsTp$A6*ae)TisvVVVv^)3=L& z<|R5axnF0pKvK4dUaY6Tx$)QP<1Yi%t!PPJ>Ex!7-$DluaDCqd^|OZ6=zIN4{(8@j z_8vbd0ttA<sxQ@W06MWpRRA2G`|Mlz<y)cuS(v*7{S&fXO?_lQ_2)N<5!qWw6Q5}X zj_mh#J^F6U0rghmbi%9rWDB4_J0*Gx^g;2Sk{?UO(Rkw|+5xg;;x1ID_-2af{AIjK zJSObf7k%<1V#x6d!jQ+Xy3IUiJ=Cxa&)Y@pwHuRof=|m-s;0U}${{>}$6s#1<w!Se zz6(LaB}G+;&p#zT`Gvd?{g$0C3cuyrQKZHq^Xz|Nci)~2@%H4K<x5xxe(tM$4?6UZ z<~Kt#9y46XFKXy@SOG4H`0O#g`{gJ8hKBhuYd3(jZHSMf90lHqOfwjn_6|fFUyW5C z=$bWy*}CO*!2*ZzsYTD{r|V6ubyt0&R=SKfNqRW=9`WPYgD^bbgIu*7E9mkUI4oLj z3EL20J0St@2Vy-jCx5cH9{vK=3~~zIy#quLM3D0-9h#eW*5;Op=1>ZmhvL|Rez%+_ zWFZ=^_=ji;)beA7d0HRB2iGSL4O#&~KB~oU%Xz0g--rYAJPpi#m36B$Fcbd{(Z=Uv z@&1eevwa5xlSczHk#Bsj7sP=A)!ubtNPfY#@z30N_7aMA`SV~%@*!%58yjgcoqzc` zIWA<F&Zia-{Y~-g1Np$o!|x#p=RfIf!q|*Ar2c3k-S<9$2hQI1o$GqXM;zJ(OiJ35 zFY8ka+&tyIGZ`wx{om_IW?qPr_Ab2h`3M<@&|R$Rd7;x5D#jxYNgq)K%LS-Fv8k!# z)|EIvGDVHtXyP}byvG-1$}3W)!w8JAq5uA7HGdNfqME;l$_kA(Q4VWLKwlQW3pk43 zojA)m{jw5N<?-f7`WC^SQtuXhP(b|b)LqbtAHkb89NrcV#zecn_WT$x^={O!f)GFT z?iqA?@<if;-$k9CzSJge9(iC=fK?XYCYCs{&&2gj;)_r7{uUn>+R4~lQuKgBcLmwD zAZy~Ya)IE1KB{VO_8X(WtA=Un!|RY8(y23L%0_K69X*T1&g~zah0$6nc`|$%@Sf6B z0et*Qig%}6W4B-flQG$}=(h$VccZa0=>5E6q`YDfIcD+m@D3`_x*e*yRrMaN{7PXP z@|!>kzM!P`LO1{J9n)Nc)`oD70JYz=u=UZSq&Ne-pgNwiEWBQgX!)mAb{gu!R%Fpi zLsM@n+fbYOiZ$goLnAJK?d0BiLClG(<EzSW<K=0n+Fv_A-;90aug&N8zjFr7Ud+j| zwP==wYUI$}r-kVv0b;a_A{s!b1&KCg$*pSS=RbsR+*#nu2l#mB+Wuo8hivgX`4jNc zD8$pAJ2fEfNxWv*cT*CXo})(4;VpbenHtt-so|w_Kr8yyUy=N8RKq2Ce&%$qlcaSi zM5jyHo?y5%#~&^M_IM<GlLPSCANiT-_wLfK4@T_Oi;yX9StC9sC+sOpkfF|h5FG`z ztP-}<AHHbEyOI<eWjcQ}AK9$4@m;dp`(^)!{;>1k@1ovxM~<JBF7SJ|ExTM{tpSud zxA+PRwTysuqj#Hr*l0Bs){x(z<Zo2G4NEip5!K=kmoA8<0yhtrK*<l~&}>vxyu0Mk zjrb8YM8hglU0x)Q&ThZ=YduY6RzI6#>;5w?lu~GiwT;@*3%T)`L$U5OoiEHs|BW8M z7gUL<sB*3C6gFg8S@-eB=%<HY+g*0MI0hc*?#2nO2+oKEugZbdy=bx;QDoKIu*gd8 z${n5jw%I}l#gBigAUB7;gfVMQYiq*;hdl34@1{$dKU_dZ{xMTME+ZJ2AS=nC{V@R7 zpES-VAHae4Hpn5oQjgsv(WO0TR%E4)5?t%ergQ%TbU;`w?^L{<a%ddYc@tg;`B_G# zm(`%XPVs{5lLje}<4Lp_L3wg|WhIM6Jqp_qmzJJ{`l9=&Q0KBaiIebMGz2#Q?YV-6 z;DR3v!7aDPhX6O=y}Pxs%~tCE5I*9dDQ<V!9q=YbpfLx5j9CL1xm){LZ-)R7x<LX} zebbo|9|7$u(GdVAO#1*^<98MncpLQ0-eHMlCwfJlf#Ecr*Z-70au%7<=`XrOw{z=S zl&7wbzkR<3h;CDK3#o(MLH4!Z+l@OofJO_3`op?|y^H8oW9q38$rjrbww2Fw;TUr~ zKZNFl<>XehbTLjN9@d(Q>t$asQo4X`XWQu3dpew2;}Z5QZ==?V(+&d=Wc5&CZx+*O z`6;4i3n0JE@7=7Yu@g}|4FX|-n#+C?fCYpW!duaQ1f+dL)kT-7ky~Lp_AJWi!)4X@ z9GFxiUw11`%;z*QxTiQVJ~27GD%R`t-8U<xHr$uDdG^JO(((r3`2EOJxF2|jEe<tI z7P>-A!fhu3_O<r|5i7BQcwzIHvB_exU<7P1O*kcNmx7lp0ao)z$HIIpg@g`IJzhcX z?@7$fB!1s&(~ON1rQ>a3X&9oQSP`GiLq}h9MLdefwYKuhp#<<9yf^fu=0JbM39E(O zs5DRYY~kbnh+PDF$bcR)pofurT?zT^4Bx0(fF^o6_YXXHkHUJm1QoE5dlf<SZ10t` zWjFxnI9>>e=z2m2=2<BI`6b#%odmDXQMqRJq4>t|anl4LWL{hdnUmx=z5sZB4)FWD zxZ}9kJxF$qLfT#cv>oWXt^#d`KH1-TCPCXBewH0v6?Y2q>?>uRes(;_qLD=wM5Jjj z8R*>m&z}o;wwcZq_u*Mo%@Lk96w1Y}Fr7>0Vq&&^Rf2+V^@p>&S0egtl|$zWJd{IY zD6mbgL4P`?&+{JD)9|)Zw!qeX$6}bbS*5IL)DD5yKywL4th-F-h4&$Hclf=Z3u>gi zODH{0T@}aKM*$%g-8uvBol9W$<q1NQ(VI&qdh_+oy(G5)IIFmSx0mF;$OXxT4rcko zlaS=bta!5t=48YiHXv@J3o?K9*NEN(Hj!brmG*?=RCwWB8YgFvmCo^_>+ml6ro^JT zC`1cNaz0R!*H)nT7OkZTzjpz&1^v_=I55DHhV~yPJh3@`bo>r<5E^gtHfe5{A_M`5 zMju7sWut}h7$DdcM5(i6P8?JP0cnd<?N9F|D(5|c%VHZp2Z3pVMc}|iF!~R)2z;;z zKxhWUiQJo$ya@WQfjPZvz$dO(<0pSlYv8%~8hAOe;e>0TkPcFatrtOj#kCINb~W~) za4493iV%O`iHUxn<d`#HN4DSh@6`Nu`LVwU|4c{4-S}~yEAR+JW}Ph~V78Fh+SQPv z$#WS*7(8J_=xVTO*&@nDF*f`hU_;cd-yi~3ZKw+ADkah<0Xy+)fu-obhhK)n?*T#^ z)Bt`VkUkeTSNu!Bm-M|rAn}#cvBDsmnc=_>(WzmjBZ!{~Wd4j!jP0TC1}dFF{AS<> z(Ad~0o`g!SZ@F5195>`E{=LeD8&-L?3^~uA;Zv&{kTe1q->B75%(2Qx<C7)Y3(Ae@ zLHzJwkOebxFe(pT134I%hjA{9n}lB^#P|-3=NK;lGg~mWGe}=0d^J$bv4uc&4?biA zffQdVTz#6r9ngRHTOP2s44fd<Y)#A&O^|9tQ<5f$CJ5qey_1xfpt8ORGNKL~QyMr+ z-vp(J36heU_+QSCKcfeG+zB<~1c9`FLk`Bmzzr46D2`w_SKmp~Q)v$9FU=27qeWtV zU@oeXr%B9DL(=>N<L%-2_Tcz-VjRafoP+?!xDJfljd9xnE}9{nz8i8do*)wwgwve+ zpXO%`Y9@Got^*cKpKoHo!BgK72Wj}JHz|<EzY_r$kBPt}{+S3A@I4gB<n1ED$6G`| z<?o3=8DAj+v-m$nU=Dvl1m^KSi9jL$jR-8@VG&r&tKRHAb;mUkMzYE0i7=86K3jy5 ztnjiodk^JtzX;PE*o7jD?3Z6C!pNt&ON5bE^PwV)<c2#$812dY<bP9mH-<Y!xC6sq zh%mZ%^W7qh-yY{}B8=BN@OlwOy@<ap!gx@MzbwLZ$og3k#-qA?xd`JiULF!*I()rY zgz41ud=bWT*L;o$qbmiUDZ+U8nyVs=wsb!AziA^`_>$JNYSa7XIbHQ;pZ^?vx^@_q znBjn!u_DGMVsaqHDPoSik*JAq2AN|L&g4PH@BT^|Ti+0<0x<_f%t{e631T`#%!?uh zICA!fBIdUurVwJ<L`=1a@j=Xb5%Z9UQ6XlPh`Hm9zU~R1lY$^?#g1m9k;s9||3ZJQ zh5zFpXTR{N{x!Pr$=FbEdn4X!mEL#JPR$P8uGHqn-c#zNfLTxEJyeed4K#*evJA=m zx_=~Yn0gMl^uK#yDP_A$Yg+X|s`%MKmY=H-yx|DmU`(|8Ytv)A7f|be0Cac~ph4Ci zWa~l1H}yQF&KfWqmD-emxgMaqkPc`ch`9&EXJNdSN}n?R0-Ls$)Mh}#a?M=)f+|*( z>96(Yno7i17JItMB60n-c*mj-iqFo9ew|@}XS{ZHxbJ#38SYjwmP)N9kTjSFaCip6 zSf(VJjQtx1Ytw)7|DjLuAqyELKEO9+y?(Qppj#5(-ur5KpZm{%&+u(d`V8NDeV^Y8 zT6f_0_lV7l5AZd|<iyAKJoU&lmjCa+!N-!m+;;}}i3^U$E)1Q!yv{PkmZ4uLBnXJp z55-xVJ{E6hlSO(~T*5evU-uhTj}<S6Oexxx&>z(cIc`^(0!ta#lpcg&4hD1dX%NiA zV4gmizI+QZ%ogNZ3I6$~MEOw(5$6zc(3l}UtsVbkS-Gm*qROoxY>U>D&sLSAGK4N} zg`f`h;1^*~bj{@#z0zkJZZTuGFgj)HcTdI75}?(2&g~=@7Gm}xrgOw?wCj=1TKJ_< zG}cNNHZ+1}@)B;|$3Jo&|9W@TJr2hyG<g;N(8v6LvrjRGzy5N3pQ7gFWH`whFE%P( zM0@<0!T&%G`iwMSqhiQE&b(1^A;0Nm+Bul~^4WF{{OHJmL-KPNuo>C?b}9z<?o|Ad zY=}LvVf>4idbcW$y@YkEVy^<XlvLInyMTX2(R}SoXKS+kzeJN~-K`Mk6imBB$4~c& z&q^IdK=Dgb=oVzm$aBO$9~Bz{FE;$n6hzP#J$>r5m~J{%dvAj6vy&(MGEi4l(Cy*? z9#MRD9l0$4@)V7E`xSJ)qSIoLY;!((B!p)re17E66XX)${BVAJ!{Xjs$OlypRg!h) z|7-6};G#ORh4JbIXqu%P1qIhm#KeTCxFplq8oQ;5jW&h|D#>I4p%EfNr@2=#aX}jr z@yd)zoGg<?vpbW_#4nSmaS{hy5O<QeO*To)a!H#=7Pmyb|8uJ9HVr~1?>F<ldH?rK z<Mq^Dr>ag>ovJ!@s#$hzrI$fppaBlJ>cR@Cp0^3JnD;fzyFBRarrv|Nw~={|40>Nr zy_K2FJMcDcs2>CO;Y>-Ra0P^Jn@dA03CDP_9dFZnY??pdG80zd=hm}3gJGxEQ+<2w z>zSx)q1$#`xD#W%_%;>JI=Y^gRDSerc1^SPj4%;%8K)d^F?FQuO$G<O;ZMbG>7JIO z{+83I^G7*^+camOGibzc)0VFj0yjdcr8K*P!f1Ko+w9KCFr|g>=?nt@TeyEOc`)}k z&^syYp~fNW@jX56VRlOUv+!{82o0e=66QteVfJJqKPsg6Woma<S^Vd<OJe-zbz&bW zEb$4bhfz|P8DL$E5p6?c(+fQw`6NHjPL8PlLas~wD*5B*dyMe?bG$?KVhW2Vzr++4 zN6aGpS?qmO!FSsiE2*BuWhd8%p$4PhJW7a0Ff!ewml_pC7I(7(8{eb}`@ni8Yz_p| z3U^^EAb~0gb7t_P7Sv=#*-&vAHe^jQrpq+j+3`3!6-A;G2%)MH>4`g~a9j*42^yXX zEYZKoRqu;GR?l8~|GB##*>1iJcQt27pJYk0JpTc_itx3d&#DtiR_z(_TKU!IdaSM; z&(amQi?pF?6?`=_+Tp*TU9=bePhPsyv2q0Ja7-PeWY*uQai~uK_oH-&FJ{m?H}dGM zNUY!#=#|Ny0Y*R5CcVqwYCvMLuS`Knovjjk4FaE~5X1Zjw1IGZr$P*8{*b+CMGo%x z_%CSKs|$#R>9-RZZsIU}$wDwV-ojQ2SgUPSLQJ(S4_y$Cz*Ua7@I@n3xOc%UCSqu@ z7lsOhP$FP4SA*g(S<-66am>3wCyui}IHhJpHv{mU;yBZw7b5MZt^56LseyiuvkfS2 zDqL5eu@)W2CoRyyTF~FP+hN;R*~fpt;IN(dT`B5qd*%=DAJF4%x_&NYul-DuK}-T$ zrYYm&F-qW8hw0S|y7Rmm9()@&u^^0I90>nw#BoxSzf~(3mf@y*^#Z6e@oL+}`9tK> z~AFq}Ze?_%sLo07F>j`dg09@kx@O`TbH2L{jz+Ox;IIlY8=VNj4H?AAqHkGt4? zxGu+u_tA$8)Qi>F_r^42&}Zf;{Yvkoh1q}!N5%3n(^u15YrExJRJqkqp5VN6P(B&P zcmd&77z0l{4<wGA5RU~T?KPWmIVKuy=f#0%?D-m@ul#lx*EoW=;5T4g+je0Pr1N|j zAN42ZsK?Y_-=ZE<gFg!0yYa02Aigx`z*F-2gv#fsu*ROOxgX?BYH}tSP~a^ZX3Zn( z*qM0np~K+aZFV;&$TzSPdoI;by^eDWv(|+k-R}-E3y)A{;q&K^Sy-tu3nwxgF95SJ z{EO#8m<8wOBt)#?>UDJLChK~dy8EnU_!a=}gTg4Y04XqTAqw2?zeFV(V&%8j1~H@T z!Q)|ElwrqOn#EIVd&=T3Plp`U^H<SR8DqfTZ*(O3fh!QM1cN~s0Bb+9d<4jJSz+SY zpXfybnDl`Mz$eN1-0we$dRd42iK<&M+dtvThj51kpYRrnVVIUt$pT(<h?d`p!WxS? z!dw(n&6~kh1xm&^sm2#3@~0$Z-$G@OYEiX`f5QF;sZP2T)a&rgbbnf0>>v8ZgVd$} zEnVaRoB6#ad|j!lG$7kBwPsUfGC49rY8OOYPN_jj*pf}z)!xO}sRD7k!W<9sdrDt# z#w#auGZSTN-dsleN6GeX?muRu$UwXLp!H#)m)o{eh_PF*6$ewH|6;rYz}uy)gLBIU zf@M+=@5uKqW2gP8DA_L#rSkHojS<ClI(s*V+!Vn-2hX522NcD&(^T^$VF;%>rMhT3 z1fSO|Np;x1U6dka>ZP5Ks_AzPZfVz+NOd!po$d%X^N6;cVlP+WGK}o9wflzItrZ&K zN{Kqy*(vo{rOPq-5WM{#{*-#Tpc{PY3zSrFj<prT1Na`)na%c;DKiAPNG`pS@cA?p z=Qq{j{mH=d`%q?McUuj6qM7M8=vJ@5`@pi4+G4I=M@VG>3|_AK;bYd(V?Y0wgHZs- zHCM@Vp}?ZcKR!YcC-^7aU5y$(u7*W%BCM^2Xs9qTiRv8*M8A0&LD-vT=v}TqOrw&Y z5VvkX1T1g+$i1HoGW5fqq(WJ|_jRMkJ%}$w74WRI#Vmy}xN<I4Y(8AVBYf#69P}EM zF#5cX<h)3jkk4d5H&GGn{t16wis)X`3ElqPpo?tNxh#tCMJQ~vPN5hVJQ2ir{uA9` z%*IfDZz(~Z&cevo2BQV;0Mtj>Vs<<Ys9)nM1nwoK<!Q_(^sP@=-8G(ZnhhvjBI(V6 z>tq8@srC0gUS&G{IA7b)Ij9Fco48Ev7>{Q@9TcXTDhZ#nlQI9IG0{XEQ-5=$y!9Ep z3Qz4x(9y>5=YviGi+J`}|96M{s5r+&Gq&+z7`ST{!8}!Re~#>2l37W3X$s+j@ga)o zQ7fd2Yo`Y~q&0BhsqSh3QZbud%FvQ2MAg@S*}D$*OnetbI+-!%3_ffgEe~18G}=3) z9c`!)@69M$H{i-%d`NcHhu!rQPQP|j{S$aBU8qcv2Ap%D2ruEv)KaHN`g81QDVOb- z$&c5B&ZHYOrdrf`;J***!^VpJBqmH9EFI4)9c-XDL^<od8k8g*7SJi_yq@N+McL0Y zEVz<TlgUzs?oRECz#eeXLP4O3P2lCO8{)1Hdl`nNsVRWx=I5jlTjXb@5w5cVSU_er zUeu%9c%wYgt&^o)jjdr$o$N%>oIsKb-}l1uV1iKaVo0RTLLZYlX{vn+Cx%_TPEeOo z8(t}*uXfc>X_iZop6Hn^4DW)g@F-w0^hx@_a*IDq3nt*0qFZnmpVm`jWxpo7fw=1| zP4-BmKR+53o9EFK0!JFZ48zIRRd^8Pf%qQA+}$X{*U;oN7&O4YxGrL~IZVzAPU#ee zW^I@DG(J(klaKz3l1q?+yd4kJv$c^Fw)?)|96JoBHH(8Ptlgpqwz$ced=*TB-(*t8 ziM}UdWY_$j(6WJh7*0`r?&B=nKKqQEP7e|@z4264R#^Uh>WOlyTY3Yx)-$9l@M#TL zFP^PiOsK?=^p#UO@2b1QVB2G==}j*!%t%xca$P7FWU4_0ZvMrIKv7im6Z{<bBKY;( zyPA88_wLG|lPNIuijeP+F4QWf-~0iiKureEgk82~(*qCFgxrzAbK$a{&V>(JJLFJM z++jQycbG=sR@tQ}^;Md{BN@^@x3rxL-5d;&xmn>t2?OLjDsZH1X!{lJw$I!Xl$40w zMex)bg(aviB*^0L?m~J~Y%d-r-&~1Pb%p_Q=$t&AO0RLDv<|+NVyZ#DGRt;Wut~L4 zJum9q!2eRQk)0?FvmMr+C^tcGvE4tJzH7!_YR{C;v>|KcOj}IE>pG%_M5B^KTyA2@ zWGodv;4%wnovHjQeuUp`-X%=xHUWk<<(7;rZ>B4|@llj%K1&y43J&5~<~j`uaV$&w zi0PVG`zXJ~l$DC-&req2&Wp#@A#MC?Dtm!9uqPSY7Jd&?w;LazXb{F{m^K<Sm2HlC z$KO!5y58Y$w1AUK*~VRTxW$S4-Np>m*yyzF7WO(*b~~g-+{Ep=rl$OtdiSyo_rz-s zQBrapL%!-t#0-{p6Xc>bJuameKFpWWUDzxnPI}&tdpTQO%P6%jc!OyquZkz)kl_1b z@<2sR<F-yBnQqg@ET+j$*6Ltc!KEjG)RdiaJAIJ431u(^1JIe?c1$>!a;&?B;C6MX za~Th*-Zh@!LAnu9b*p%_EI!<0aaTU1D70*Wfp`*dh+jxuuvgB55j0?c2=XJB)UgE8 zb}^<K{u@Rdn{{k^&wDGCr^E~Ub|)jE`V5?a!j9ZeH*8#7Ka>=+^M1~QN8>_42v-tp z8I(DH{xXj%Gl;5Ns`LFr|AhHW$=Se(D-e7u%tJAzL9VocH-dw3mz<)f!{bZ{G5~`> zeNMrK%RrJ|xt)oNus3){%lD$)wrhSOxKxi%n;@E4Q_3Id=z<^|wR{CyP*qsH)2iuM zXNF#p?DoB)RJs&EspvQH97DD~j+1u-$^+87b63glKgbVU>Jl%LxBh0eqO@(K%ciSo z5%gSJT<sYaeTe+T&qRL}q6hB90>2%+g-AucigBZ|b{kBP8oK$ItVL0(VdV<fnIgu^ z=?@04i(0`bC8DyRrcCJ&M&0^3z2tSd9+iaOVh8&`(7{AM<^xvbj7LM>VF}Upmdf;J za5mUWS#(%l$%_S8gi;mYm9y!!H2)U1Ta}12VKx)lIVj)%G8PHEaXWT7*Ctx!Z`CkG zJj?M2)wEG>ZNszOpcIxfIbVG}U{~8Ggx}v%_rq?GPSGbd8ZV+A(*5#A%KQj}?JHhM z#%T<djiP?8rkZ3_wMDkz=10IH_gT%Wk}rB7STzfVq1mz#7NmAo+pDOj<j^}dV=2|Q zE^tE)_ZD^Pb|Pv-mu`t?wUYjKc4u%j>e)P}F>PcKgc#GtRms@Z8(R%gjonC_xujS4 z%Pc#*m%Yu$q==<&aka|E$V{mXCV%;yk2a*3WWD`zt*C9UvQbbRClB~-j|0o7--HMO zbwp=ljTbeqG`g1kM8}%Vh_K7Q&_KlAZkPd)T#nMYC!B6GJM_{m(W>rND>8v@>40Oi z#?1CThEdU}$Z*<MSNR(*^{lNGh3-N%w&Ge+zND!7$;#OB(T+vR#^I%%>ebNEa|y~X z?^i;19_S#*%I`$HY5A3eJrj|sLAHX<-Y)4Nr4ISi-!L{b8##-6LlbhN2<m=%&e|~z z`zO*8O{Nqu=3RL&E#blhwhaLzSCpK*n$>?cp^69@rnR>!s@k?ZoFDSp!$UNh{M~PH z=^glVUl+a*H+QJWp%gat9+fGC@%n9)y>LqJ*3BSN!hWDR$6u*D`3G6jd1qaQ-VM}K zx7d(TU#QsLqk`ntOynZ>VPUwk6*eDCq=I!uhjb_d8bcFEQWDNjfR2!`AegHETov%l z@1d}8T|)k9%(#9Xp@N7@Zl$v1yBsO|{09_kq7a#>+hN-)o{|noO(~5|U9+=}g_UYI z&?wtc{JhykqjZG-P7UAStfK(~@sOU=c3^Q6Q1%P-X~m{RKR8f>;H!WW!k6$-Y}+C6 zW2f{dDjI4FpfpmfQz}KdT_F-OGu6I~+_SA2*K6C`Zr7n@#}c}DyO~<{EiuyRvdvDP ztC?Y@Y;x=bS}p#Nl8*K-Hfw$FS?}oMs?X>n?7`PSb~;v?#u<EJ<6N5g2KMqt;B$JH zwhgZlr#*#5S&~9yu2N(AA*QM3UZ94K$a{I@PqX;W53+t863GiD;4-q^Y5U$(a}qj6 zW{}-pQltvVGwJXdQ&BoxWzai><f)QI;LNWd&N*`dB{m_sry#jq;ap1m`>kw7f})#L z7Q2ZGZGKM!d+{a&tCB1f6F)>*Tp_6B;ox}ow8{^(#p|*3?rsb8;`k0J)LmFdbJSw| zK#P&rN&a+HPwR|1*L9LV6_#?@)86bHl8I~vOVS~JD$ERGmto*5g#DrNrs1?8!XRme zUdn=ga{#8<Q2&|ZRl(CBzddplGT75P90skT!l*JGYkqP|0Vj0Ds7xu`DP_kyq31fK z7Z}~1K)MabOA`)hkNlf&v69<uO{N-x4~E-z2p)I6TIo^?KF1vtO?~5AwVbA!cQ3G2 z4+P#oi*%$@(3MO<p^H7Yb5LF)0Uz@;jRXH00(y+gyD4j9R(iVJ#nB=QuR7$~R3TS0 zCXy!MI%K~*O5(z<!*H=NvWzY^tX&oxJ<7OpIq$?WEIAWy<+84wWn5ic$W@i>UQL^D zZ-;RA)*pYVjB6KM)ajNY^A1k7(%he$Y`5{rc7pus13jPr-QV+MOQjWYzTK+Mw{+2B zm$J>Z?}`aj9azVd`$v2%<wnVFa547->Xh4czI~j%w`i6VA5gVFv@JyLq}%zohk8i_ zCdWKuW@n*}F<(<*0*CYwUbRb>H{FjnO4Jh5t6IF+`)h%)zM@TYMV9Sz6RJ`oTP6^u z>-aBvCQOZw$YtV|ILeIUC4`z+kn*f08kcnarTcKUy67;i+2yibe-3OS;Q5V1+L>uP zjh*OpU<N*Ut~9vQMu?}ChM;=F_y_nZ0<|fNgWse(m$QJdP_ss}yq`X6A3@a$`gg+I zoIx<$XYRU@$O3!mIeXppOYTD*XQ$cGhr{-@kmgPsz7QORRJr&pyH0ku{Ccfg$8?i6 zsFx=-^h$4r?V^C<<;STWOWANgm0cJ}GuSCKx$A~O(u1&sNi4({wKPN&5Ai&NfEqb@ zFIL+(fRyl%ONzyn&?QI84tJr9JjX=nNmOoNpZvEolmhy>qzFg#qA)Unscm&wZx17; znnx*yP<Z;X3qBWp{X>{?$|Y1CefBssGhUoth1x~kY4ae)a$2!xU8qk$p7H>0?Oha# z-Dzc~i7*hz@ie5R!Pndyp*!K`yV68GMcGw&R8<Uy8u408e!7Ds#aQmeTj{j0_ds=E zDHjDQ0hNdjRN8!~Q?0J(G|8$P5x64*70V-I4%jW$o;_YaS!>&6T7@SL?!tzSY}~d6 zlfN8y87V<P*D<jiOf|T2b`>6U*CjUtwKf|dU8v?Y3vmMnTHRE$l2fSW4Zd)2;REU0 zYZRvOZKqI%z9(K+lq_J_rGu{eY_04%#;75_OJ9)JQb~oQsA4|lkV}`F>~*fV)}?HN zl4P1P4l4=$Zoty)6l48+6}i-}9?syXdZLz9a};KH1T26nOeK$B#KCr-yo0&4y?8Nr zM^@FB!?e-}H_78)XH$8-OCt~16ukR3+*LnQL&ue7x&CMm3&zi?G5judMcqjWPUrlx zAwM>3(u=~gis{vU+sC3)esp>0_&^y1K0f?u8LDa$E<Y&mbS{cVZz#!@<}-+csa`~x zuJ&le!<{y8c9}Lt726I7V@w<IRAZnX2vgZ^w~i4WGi}tFHtlZw#1PeNI}h_-eYz5O z%e1M{c21zmGIvt5sTKx^?r?HJtrt__OuUnfYW@Nd<F*MgE~OFQO%=Z%w@uW$*tVB4 zG;cH^%Ft)&|Id%cj;6}gtX$UPB(b)d%hU`;@z}$--P7WdwAfh9)m9>Ghv4$^UaEi% z%Kw@1=sc(M0G;P}3-w#L3L72LF=SQ7;-rbX5R>HVmhm%n-7@u<sBLfrJy3@}bP5(Q zwy-rdc%XiQKKtJ8hJW=jNe&>l#!F%TF9uJQR()HYt|54^zS23$upT(rO%Rq%UGw|O zyQ}HZ_p{Z(S?7=7EuFF*hkga7^;%Qya!lNIRCw39a?vQOV>5kLRjW8!6o+Z+K|C!> zK<U{iX*<=_^RoZMCAaidporU_cqibn9dno_9RpHmtme$jF0sFSU3G9<#6gYN_uD2Q z0;?z&K{q)y@`fY$L_&<iPNmGIN;R}h?z-Dk?W!eHI_%ht=O}pY?_%e*E8VG)j&aSV zn%@%Cbj);JJ62>7HIl=>M{(%h&#a%JanzTbb*^xxMmonS!fZ7Fq>u(F2)Edd3t20S z!Fam&UAWC!at@=U0qz=cL`a-*7-t~FN$QBhBAkb)7-yW?Fvu^YI<a3zkK#P)woz=W z{~%7dg}KS8wxgz1+w`bV00-j-HtFdb6JsVSitZ~&z8%xSVpp4L7J?t3qczpwY6jXY z)=|Bf7{!Qccd9`j2&*niHT>i%gbC-PEa~%1-A*cr<+jNt|2PfT#^YG2PafaTRAa=0 z>2W)S82bEbrm~|gz_)npE~Ob}{>uKD_0D8Xwbdv_X8Lz%+ZbEd+V(a;C}4ZAfT$*A z1C1O#iU}z|a=f_jrP7yEj7mb<NNTz-4ORt$2t~}kQBgt*=n}51ev2k#6t1?fNKx}x z$*vKuaE^)$OwP1@B%0J<Vpx;T7#PFJiK|3{R;N0O)j*Kb7ZVgkFyWhiVIP1I(uN|t zZAHm;({fz61qO%WVQ2NJ4MbvH(dv-`j+C#F5KOhW^K3h1s*!P>OAk&nQ;wg}Rf~p9 z-SM{9D2IPEVD|s0Uz!NW`g()6Lw6KLyh+x#h<U7r2q$1*oMhTsqd^-~NxZCCtj;qI z|30PdK~zcAVB01dT!q_Qx?_PmJJ*v9vhx3^T>(8{QQS(MT2bH%m6YcHQ72yJIu27x zITncLm38+03}99Y-<3zd2TKHCTiw!Il*4zVeDsd&l=cGOg6#a5cc}&$eppgF0<}Z| z%6*iC(&1D~-2IF2IWs`|GkU!mMmXDcSAAIJctx4Qk+z$Dw@deR-J(=i8&;U@=oakC zLTs@kZ3gLqc&F8mAC?96?7uHaxTa0|<YNChpxq1&s%qLPn2YJ75?V^0^ofG{$(Mqp zt1V75Q_|Jbbpev@kKK{(<{;_f76GQkX}9kPO0ls@!s6>_r>#X5B}l)f8q`Y(<h07x zm4<Jkg)2^D=?YVe>rz&-OR{RlNXX#yW@o1~HJKH;spA5(kj~>fB_)Ox*Y$?g25Udp zu5CE6zyPX~E8YRl$jA`-X`G@2GfxOatL`Vzy)K1{0@}VbE&nr;{gvI4eKf0SR<)G! zX|t*X0<D7AiTBHgXv<%?<TN=ycSt(|rAoq#6x^2zgTa5~y+MfyCpDsgQQM%4xFb7H z40B3f2L6n4%i!0B4|D=6evRDkUOHWUzfg@E%BkQD>BxnuXlz~xGtXtMdyso~;KcbA z*F7^p-nbB@uIm!z`h}sAYzg#cy6q>^s!wq`nb3bRPP|7b-F)em&T_H$0gJJVel|F3 z?q^i)9lEjGLPgm|$hR+~%3`ix*db@uN&TQawTfxX!*g6|yMrAbnI36?rGJV%h{Zlz z6;uz{C3Xyp9ViD*G~r`Kp;Ggc&NwZo;KzyQ4Tr&}5*7R$3na*Yt_n85_9{%8sjl&V zOx2@aL;WGY2da9)_NfK`K*0}xzsp@`PjuC}3^O_%oFh{>Msd7e?Z74c`@8Jx6Tzjv zLQ_}uB<}eiqd8V>$f(&T80xAvJ2sjF5x}8)oh#2G<C-h~A(pDri0?`RABl=$+VX|T zmvFX;*dvH&T(&4V7gg#Cx(wqFxY><6hu8rc97CG%n627&P{>W$FO0M87e>jiFQEF4 zq7-@Mg3DCS&^(}C*3PHfL_dY&pmr{hgwm~o0dgde<JXSAA<rAoIi(+=KepoN^cLNd zZ8Hnk;eSK$za;$6<Uem0C8zC2>7Z#%W5Dc?ngdY|X<r~*+8@wL2c@PhkR<A_a1Gfe z+%y4KQ-XB@zT7QbJAvS{#DgZ_ejD1L6A4#MAmKQA+O`S(+eRuVBylnjhti`YV0;_7 zw}8$e$xuZG$J^KpC=`-iIcR0r)n&jywOm<~jGJHUs~z<j%b@R4p^<DTpIzwVFm3s| zAN+U9?BA`Y?uZv86<ujWKZ6?9B1E9Qe;^7hW`TMRpq_H(hp09bFST4DXU<ovdhmRt zGo%4I9;=qLt)pVCHB@haQ$pQo(kd<=z6f>Jx|8!^CdD*|?V_>}xPDU-W)EW<O?mYF zvszpcze$@~+BKxn)+nY^F2G*XE~H(aDxi6GFio1K3+b~&V?q-ZZLY#7cm43xg`|sq z=}gJFli<~xOG?7sSJCP30iZ^C68tAw+xF?XpzfuibmGWj>Bv<-m(G<m9qE`nL1f~A zc}l{}tLfVvFUf5J)*8-!f#2hzA>2`Yz#fS7pVNtYFdA?vmM2BYL-Fwhn%RB9%-C8P za&#KMqZwk(&J}_In2M<G@v&ArRyHNORydR0rdoUqC!^+!scsu`IyFBCRZ>)jv;*0z z7bEFWoD(Z6NiM=eNK}qaglxd&^t&*mx1rEtREXHBeZ`_=yL|XN1r|4AVl`O$iE+sP zIw8u|2=?q^BjkYHP|k>C4jX78C>E%V=1uJHwcm<nXxQ8#jd<DPo7jLhs$FUt(l~+G z0fQ+MPzqJJ4r~C1f=x?=6tDqE2AiJHH$(J99JXQ&9fbme-_$@a!z6%wdO24-&zueF zFvU8(sRnTYB62#QtC(tE!Cen&*HENA+(fgRYVdVwG*%0X5Hy%-AJ9-{@&2WBi{#|| zSpP-+e5?Or7%Xk^%ysK3nggpM>69Y{mNOO_w%JsRmsxi~Ei0E`=EU2wwEm%XmhPrU z@Ir%HUFGON)qgGu*1MApgYxWeamrPgmL}Y_wjlM)g)!54>aTwzVw|(ye#yC_h9c62 zkCEUrj?M{}6ks{}A#DM7A?N#oN9WQ{Z6~mxh?Y2nqTrAY$qz+v4W#Gsg#=!SZAe5a zmR=SjV6&Z?e-G4#>HZ7&GWtcm>4C2(+N^ZXG%M_7?~j=yjk~Iul~A<O?G~&S#NP3i zj%EOCBSeN`>z&S&o$|B|yv*|;tWI{?K41C)UmX-i*;l^8W*^!G?A4zyy}TRP4P^$a ztFU)x;lxbIy%Xr9x+u=Nv{5!Uv_=@5aaO!s;1;i-6GZ<Wx|Z8uu!Ir|kOoSEIcnNX zHIEQ>>J9z=&LL13XL9!C0~gix5*)ms_!b>oX($P|3}M#{#2b`^!&lHj={qm(zx79L zQdBVZTv!&>n+K>&sxC@2T!LnO7M4hDlkjC#Eao0s%=2n7_d~9FBkpECnT$Iwu4OxL zCh4LRQQA?LO{af%oy$VCx##&^#}t45hg9uS?QVzZcMYgnc$jSQ_Nevv`U=JsF*&xH z<Z2qI!Qhna=jeGa%E%1EBHQUqu?H_X;lRQ)-_A#dryYX0{6Nw~NW+U>u0qr{h4(CX zVd;VYEv#gZYjW8`I`{_kD3}UNQTbtDhN-3Yj1VnX0!DSI^pXU`2VV28J3H=LXGtwU z6<p2qRr2JD9=DKgFXvlGGjP}FFuk&d&6h`o?=vNQGeSOSU?bfTH<EyxJ^1<_y(uDp z8OA8XjyFPz@8Q#fd^<JqyT$6APdo}ryzFq`OcuNJDYdzzZ!>KNpd}tD?|eYeu>ttX zJce&uUsN7u9VNV%X*(hua7o%sTa(b_w5AG;TL4l(t-o%^kn@2x+cJ{U?S7YZPA-lO zu7zz)rrIZ|;gYGAuFC6YrJ<PD^pkwUwuxO<K(`TVap&}?t3FSM8;PgNx!7HksRk8G zK(m#NC4|4<A#TI*tEuyrE?_V3n~NJqJGm0^uNry?_5z+9)i2QoVgNTG3}u*fxcv%z zF;Gf<&PaJJy-<1pOM4ZJIp$~_hymTRget|M4|5)nPg7-c$EZY%T=q0AfxA9G47Y%X zmj?@3bAYZLR574UjXj_hi)cZzS3Zpe9vdN_E>o1OlrNl;HM3qn-d#U5dp2WEyjhYy z*@bTq9*|2Kd)OrY+ubO{j=R;jL{W(de0ljy0j_IL8enOR8$8~{Zv+O(^<`LXtiQ20 zN1d?t>dQ)p3H*SCv7Khxq`oXy)Q2dmx}K%{%zZt6!QiVg3U2mI)=1yVjoa8BAyR!d zxM}fKTlwW}Y=9RgxTKF<DaTy4<EGy<61>8)ZV*xzUc9ZJ1-LZR1J9qR@*ld>I7;3& zH@MTdX)ZFCJw8Qr7rooH1y>7@>3q6n(dv}8XWEXtq{A7etX<&z>a%qE5Tad=F-(^9 z4}2gmhLru*FfmHbnX7VTcoP{WKZt|xaVrU@2V$E8DK_Ipf|~)yz>LLrPz`T~Ay8AJ zI#1`KGWP@WZhWBxImXu^;@M-a{)+4Dany&1+8u|=U)`-{BrA6-OgaB|{b3T;VE|K2 ztU}etWzxh;gNdJ|FA=t#z0~y_f?rmbzJty-?I52~&9eXQkd<&?x>Gs`iK1{OAokY* zC?1R93`)ZM{_LeTeobA1c!7PvYwDz&bbC#`(^Y`bHxk^1Fpv-2Jr8?Vv%}vyI1^@| ztho(&Q>5s<lU6!4)|*TlZ`T;K4UT0e=t{=4wZ-wykIR0ftX>{KT=k*G8RYqfAp|zh zf)E%y*Q9E<#!x*)((i>?k64$1ome%2)GqGJsk=6i2sVvjX~3-dN29;STAfk*ff%tF z^9q<8XW#GNFqFWeB@B_kk{S42K_)(WLuro_!qgH)+1!V&)1<K1U@=ywQQx3(<K#dO z5prgPE~8uNGFob@pR9M*&w=&kS?9`Au$t}dKd%vDm&7@2`<6sdIhr>#S+GvE%STG+ z9?GjFp~Jkoqk!w@opWH~2X>e$q_A4Wa}H~j29|S8#KK*^_-hFvs%mO{df|}_Nb~k& zuQX6!Mt74E%5Z@qj6}t<g?qYkJo*OUi3|pyn7zs#SjT*b7X-I!@Lb}a0l2NQiAo?c z8S~=CR$aY2QD0oQD)}|aeeRaOC_&0)yJnOXydU}K<8_HHu5Zp=_<^h5rO&L-)#;ba za!b2Vr&j&IC3BIKV1R6JaJDTA_?awS{C3C6Nrv@i(YQjBDQR7G+CYSTMViZRRG`RI z^~p8^)e+Jdl7n;HDPgq3_F*t5r^$W7Y5Q_XUx&1VN5_aXzN`^XI=0fo)7&}ORaYgW zA{%IeIxF6|%f>+fxfH6V8z((_Ng8sqYFNuy>6Hm8w}Z?MyX)udixMqL!iBy_Ypb}j zy;eC7s0?b>h}zQhkYB*(zo-@Q8Oxd3in7mkN=#uA1$z`F;cOrEIv(mXrvuf8=v4R? zwFM&SnU76I0Tc+OBpgY^M=Y7}DdS9cBoeA?!6eTt4nBy2yF<%%w1zT<xEE*7nQ{3Y z3MuT0DZzUhRbc)7byz!RP**T8b0rz|#o8=jQ|h#)O=0(6hda)YadF)w!^*IQ*I~1s zTQSLq>N@J^#=se@s8pOnt!NsHkN-&*m^8sr6yNu6H`FhR(6}TW%*LWD?c&0)v=QW* zVtiaP0==%p8^ZEZPjCuZ<53T*kQr*zF_i-)^qDPS3mosUnS8MSTpv^I%1*mSY)ZEk zLW2kxzC@n-2xHr<j{5O>Z02lW!+^&e1Ma$W+~FHj&23bXLk4^w1>&&~y?7xq>WlPh zDZX?`30rPM=IV%;B0v8iCXKI#y-3}f#J-u5$$vnR$IZc$=wD&M+HeOcL;B_~6P(u3 z!myQE;PuCC7Y56({SIR%%!Q~K^<`n2%)*_n`e^e?jbmJs_)&&*I<s(pV5Hr8k48wX zUZ@=>UTeKoCk}Pg-=udHHoJ6tWG_qM8k&L-9+p{n0GzE!!X5|89DU?S+3D1^;-RPA zl_nD5YE~m@G#Xu_mbj$``E(fNQ>Ig)%(OA$-<`TI9sGuf{9zI2dQl4<tR$vF3FTiG z<JfivN+>rM2Al08Fhb$^F=M2bE}qBI3!fWs13ML~!wEb=D!wF;ijTAwu?NocGo`_9 ziRw+Gr_Wa0R&gOms@Y80toW`E<=$F=Xqn`BYhVU$05(B)jEQg1S2SnRlle@kFMUpZ zuPfy}m+pxC#-<)vwrHN1h2FEkhc%&k|K6mtU~<ZKEcRazV|<J@uPI$2O*&xMCc5w? z0hGngNP)IO{>`OJcrp(tq3~lIv_E;3){;y2lN)P)szdtFO$qEh44QH@Q`c9%Vp9)X zX;nVrltpBT-iFv|V5K~VNr{`CY0%?LwGYt+_3ijr0`?DFZoMZT*w{moL-Q#|e_LP9 z(I1p2zR^R_AMfIw2K&m@RH+4x5ZhCP-55dlQvhEALGC^_(>4*+a{tPu?85)082>En zA_s&pc_1e#tGn*{c|q5RA|@&4hQVnJjHxi=!PvH<^P>0H>^^v^^ghn@!{xgR*zL?o z1?rrCnF4cpW<K3;&px~DJkW}`S4lY5n`yV~qa+ONMc3;XU%rR|N#JUjrmk485eA;w zt`!pHhywNSME)>8xEc5^<r`r6*NxmqP(l0{MZUwyq~&gq*J6Wq`;N~WccF|$HwqF0 zOK~}Bb);3HsK*idMwXUvWeSCzL_KDhHb%LmcP5>2Y6j|sq4)-FRLyRoSL3G!)5gZA z7Tb4XA6NZ-N&vMxqY~kt0^zoAT_)#G5VU5u*kE;c)pO2YXbcrR*~jEP4BhCU?{b&i zZQDup57Xy*)SKej>8ieb)Ck|3z6?nPSkCSRjwplP-2O-$FAH~d7Ln-?p<8(;d(Eut zt#T?kNFPPFT@?O?b)g)9f<bj8L3KFn))X<USlS<$YTBqPZu|r|hV8{s&BYGeRI@J@ zL9Yc7#SY!n_`o%2>*Ko;LE?h`=-4k1Z`#yImG+y3$VsM+s}cv&`x<?LxWTy}%VH#E zaTv3RD28eWzv8GCNG6A6k;AgcVOiv`EOJ;DIW&uHAz7@USrpse5w9(_?H3|lD0G*s z@Y0)Vp5bq~1r@HZ28aF){#LEhY`<J*efPJo@IJv<loXS&u2(Yk`VHb4m$Ez4wp-9! z<HR4Vac+~d5g58o3Q$AziTO{O-F5NFZls4SR4tvGoajzz$udoP&*PQ`3`N~2S+@5o z`xHBteM;K1>YqUElnxj|!BuQ`OAr@%c)-cL9p(I)xYk!N_~pyn(&$~T)H}A@XYhrr zpB||Y!N{Zn*Ay~kd?6u_N0Hu<46?QQGCy{`@UCtm6=qrRhOCtEBd+$P_&xGdX=<pB zf_F)%Pj|V;<fS8rcP-UK);V{&lKf=$<!I3fw7DA(8spX3T`=hq@wb;pl%vuw$38SB z)Y6#U%dBCz7rLfVg1?XyumSvwy@Wn|K5F)5jR27|#(c2MiZ78nOl!8YhsQ%>L-W~X zowZX;beFQS<?6<6ob&nmxl=yu>h^|$%j<=DJX+9Wz0e!X3pz){jMz1=I}18xWv9h; z65&_=#V+KN3TJ@R9^7VRo0l)%+0EvqPMTqt_Q<a_(6sD#Y$yNukp_Id41OPS_#KCa zcn14%IGRHjhxr^<akz@ZH5|Uk;p-eWad?cwFE~8Mp&^06J{*qVa1w_zIrMS3n#1Qg z+|1#-9Dc#!84k657>wnxABV{trgAum!|5E(=FrRG5)M~z_!x(O=5Py#O&lKK@DhiK zeR+NyPT?@0!+SYg&EeA=ZsxF=!;d*U$6<IPuRjilaX6ksH;1!1^l@0j;UgTb=Wq*$ zO&lKL@G}m7<j|PJ>yyJ_9FF7A&7r_yHHWJ?e3rw1^sDMe=nco!ISj79i$OyPgI#~k zuQ2!9`*-iJ{)!7q%REIEp~5o9BUn6DrGllfqR3+@_EpTYczqRxp32G*#?WwuK2L$* z3H7rKtt9Y|{?aSNvLZ`)1*YXGw5ZM`y`UT&i%ZLkEZGZ%l8SN~KokmQmw6zVk%t>{ zg_rt{0AFVB6u-jjDW{=_R~Gt8y}}6Z!Ua5EUj`tb&9EY59;qaSq=NW}2mVHoB2or_ z&_1M`h}3)yYp-&#tn8YO`UuB=P+?}G3n$@PvpypuBMg7nr;=<M!D7wMi!hL1rKZlx zhQZll!Fin+@=NmJ2My(|f}a6GkO*Qh05HH`gn_4TwrXg5Y~WC%)#<~+BMgzosOXqj zlR2(e@A!m1eG`-V^&c>B&|u3IR}M)Ydezm#uDLely5S>6rj8mtX6*Gh{K}d(&NhC+ zjT7yTN$Jjvn<l$5r%ZKcO}jb!mgzaUGiJ`pyY;qT-+srPcjXt%E-dmC&nYRrdv4jh z@(S-gzDhxyzo2U2z4t9zyksdoe#W0qEEh`Wc`P2Eufk^`B!)LguKVVk9Og=$ax$k) z4zUvF%~_7jX&o-pZ%7?8Hpb{Ew-k82Wu=7$LMb$LNkOG$UICC*0k{i-XP#F;QYxz` z0Fo;4Skf(O{$-`JeFeUSmeTUV3ZKtYD3mQ6VazV`6jXYEFw2F4LV?BzN&V_dOQq=b zR`|fjQ!vj`3<a21;qyQmV4O$8j8Myi_>GA%4!1Zu&=4W*tei}D2;~bUrInU~%1Y0? z*<}kYMWU~?e2%3YlA7;fp-Rh3h0=nu(tBz0##{^!w2dfvAf{!uI0x*Og%zSN6xR`! zOu+&{=T%e+P}aE~NF9sg^HhpuK;Ffc!h*6g%nWJ@aT;D&G0#i8-msB{Wxi`H#bS9O zty79;K?hRhm4Z(!6rk|%k9s=G%CZVdS=q7Nqp{qyYnE4tb4o0g-hx68t*){P$hK33 zh1S=oF7*{GyN5O2^jucoLJ1&UQC{d7@yqKYG@n$=2U9~FJ2ENa_>Z=tzgSL3jLvA3 zcnZ8MB@FkgpDE{p(uyu^*AefA9^+LCML!eodW`24p$6uc`UJ6{tfP^zHEBQ$H@3(0 z@2V)rp?4%y7LLGlPz<I&Dy?(5=@^LZT><tY&-~Itk6Mc?Jg+BDl^6OCP!85kXrEQX z{i;j2c|d}tLJ5rTMMx2IL*rohp6iE4Dk=~PI<la@7)A<R2Lqqy9??^YnIZ*E=bax4 zCwP4GO3QJADMcE<ZXlM6l~}0@3jT#d0hA{-t;h0s%AqAI%IA5?1zsKuZ|yOBfp3n8 zfh&Wh$MCej6~iDWV2Acrl$HxY^e`D5{up(`lC!kXS5a9}ELdii($c1<qy+25%?3pb zXN1rrMvNfiVg8-tgCdp}Kmf6PZh6Im@*5#v9wh^t?h2zZn*|$Z;dtTtDJrCW27+B5 zVt=HIy&mj_5c_Ys*niu_zPgM3!7lcPy4WA?Vh^vbzQ1}|HB6Mc`>XF?UL7A61~YJN zZ7m?4np&M*y#i*_VOLwTXH~=e3X^blHtxAuhE=bqhFAoq;gXUPgCU~I>s{dWUN-;! zzy7ma_BSl}ce&r?e=gvRe(tZPo4?K>mWBLje&Jte{N*8k+F$sm#<l#rtN(w%@A5V+ z`M*s8nvTC;`s+jinvOs1FZ}DEfPePyAC({f;^8mU7V7tli_FX2+5St*+fnYWE}Blu z!Rlqp{WZ1sKd_>1rL?O4H@{u|;6o3u`Q0OrKKA(UpLp`Ar`N7~=Go_-f8oWK*8ky; zFTe7qKfk)+|Gf5>*WcK<Y4e*~{`%J2TmRP3xNZB6olU!%ckkJ|Z~uXVE$_Vh-l4-s zjvo8_`yYJx(Z|PIKl${;XP<xZrQG&a;N;ieoNE8}yYGKEedg@B^FRJ{;o>FbpI!j< zyukTI3!r~@`TyPd|F<tdd-neyQU5O2xOwx&RjS(*qzHc3S+d|~LBm4$QTME@kwrx# znI$`m5JwgZ@AMSH8qwoZ<4>!Y-^qS6tjN%s<M9frheMnrRtkhn5zA<LQ-B9Y=<xbV zagQRaz*ktp<KN_&?GrigN5dABQ!C_)d13mPHl~T`VOkJ>A*O}tV0?^2atZ{|S5!dL zxye_`O|ZT%5q*_G8zHkiMdh9lhg^}_vMS1{V~)sSfq>~?e2jzPFbw+Bc#}QqUd$|5 z239P{5h(MG?lUSqzME&?4Qr0f4zAq6^8<f(L8ag*#8qu}g;(?j-I*Ipj$}c~1#>); zDymq_895o#$BZ7~bh}x2zyr_$tN=N{5l}^pY5hT!K+Qk}K|MirL9IdMK^;O>LXBd@ z!Y}>iX*bWvO(r8?{f%~YKWfBmnhdzlE28jrp5H=P&CHu#Q6cm=@pk%Y21S!WLKGQP zWF&)fBgvq#1~O=Lzt+T-J`G8O!${27)g(r<iiAV?HxCAy1EyRPgYJXDeE@aGt+Dn5 zLJssHBsoGu?Pz|sFR;(l4v`MI2-%U@*?mAb8369_;BF|I(%H|TC5GJTozhLRgp*j! zR1(o1)~fSrQxTt3Eg^9O!pMNxi4A?c3HkA<gtVqGh2E=@2)VT%A@)ysS(A(;X{?DP zO;2d=-5S?oYKZYh=SO90!nGvar%lzwYf1cT=2VSIPfTOOiD`6{S7X!@Bbbe&!@Y3> zjATHOi3}JUO9uE7+xxV}xAbZ-d)55DznYK>!wAV!^TTvUYqKMJMUY-aiKN%qzND8X zo<w;Wjwmawy_S&JYgznP!R-{79|U;srwnQ=(Zo^|M=ZI(GeEu;-+*@3I`LkOIh>e< z2x12O%%h_lG?7{oIXWy=lV~7`MeyZDkVNoH91UUP4J01i;=wH*+~P-@y-C+Zk-lS# zNMFru#M~a+8r@=SFnA;K!?RgiHv@u^mKb8$kwh#)BH+;%aOguUnqDNSy>DwmOGjP5 zJ`NU8<Cyt&yvh=(Baxc7h&GkiyAVl|Apa!DKMC?r8lBLfNi+hU@B!T=0^I?gv_3UP zE!KBx9G0&r63S;F=IPN5YF=w65z;pu)`+~G<1qal(U3<J<Y5f9uUf~yb`tUoe6RBG zSAuyfe8<&xN-&TF0luOLk^s0RjE-xFyWFis&HuTZ2sr`YIW<15TO-tMB-AaKr$ZS` zKtDxMKu1Pm@&O%1Ye}>wjwB@`ExZo2@E4$k4U`tJuD!6XjH9#`L1|6RtJgF_=E4_$ zg5{Mo80umy@Nd43*24JKU_C$`2mqnpk^mQ|iy+?1rW0bz=}0S%(PygaA2kd5GJL~T z{}9?&>+)mpZ-eh99_A95hvpGdtj6iBC%vHzy+@mZahBgo$c9@x;_L+Tg<Ct~u(~o6 zQ?7}aUW2;oYao3A|Gv2ZA+5fndwXdc9g2cBF+zKQd3szcEpKR9M<=xQZix%hNo+nL z2jN?)=A+jTJ<v`hhibUVv!TDix9$XkUHu;ix2I+^Gs3vOM!?SuxS2>_U+?y~R#Qt% zLsYQM?8St<2VW!4m!>znBfZ=?gcQQ}(Fq1M1Ea}6pxuE$Lj!?^20~c|j!tUr+X8(g zl#ZrD-Ow_}K$(HwbD^!lJ;?{*3>snpoY{C~plwFW9HAu<nkR^+S2)m|ne=)s)*F)_ zoz2pXgmeuoT{YhHa4#LVrfaj~=r|Zj{Z-tL&L`v(_!N~MM*`ks@6ip^6zjShLoEHF zzWN(U|DssZe{2ltKfP}|Yb8@K&FH0sOn`61XPk!O!b#lNXc9LaYt@*qh8tWB^#xyF z9**H0O^go#&U7p>!&qX1u_TrxKE%e7q~S3cgN1m=zc;j3FVZ_b_BCU>p*6fk-=O6< z<^^dm4$2F3_->RpX;jShLj*G!4C8%&NU!ghUcT7&=vHHkp+PO1H5d=*7Q#^4jn$Ia z(Z<w&ROXG3LO*)6qs*E<M$!jx?*r-d@%3sox5PF?d!zDM`@O+wBo1iA3^ZbbI*%m- zA7V5TNBc_*lrNg}o!&X06Ke@EtP80#-sh8g15Iw@bGq6$dhznW7_H8KY)pav1!G}S zQE==Ijww@Lfbj{w47KfO_*h1xfDh1Sr?Gh6i-bH3-<>>sJeYUBM930ur+Cd~cnw4Q z)lnHq>G3df#<WMZMz%yWgn9M(x>U98yejUqIb04n(6JlF37~I2Rs_d{cm71kn|~(c z(NG%7jU&c)!}%Nu>tv|kc&K0C1=u*A8x8dlMaS`^WaIUH#>8#wicOG?kPd-{5~s(v zceJ9B_qP~G2hw^7`!Uq%vz_@6W9mQdD<_)>8MG^eZmuwrE5;^~E57U3p4i%_CBC7T zH!k0-@-*3T@j4R!tl4YI?-+j$9)$51z73%?F&+4y?#H3_j&Z1iE;M0U5;j&tGy@{Z z0N?{dN|GG~<wzO=^I_Lk%Vs=VRdCLPI?j!Ox{fCC51GBGaUEL%#dsdwPI~<PM_z)# z|Hw-)`0tjN$k9yplzV&yf+wAwh@}g@vW)qja#)A$0zUzz0@5prJVD6-pMF+Bsc=(; zFQ>G8PML?TM9Cv0oys-vV6dosU6<n#LK1Zqloyr3`u#MfnpIIGmU(U}E%Qt(nCF4e zACQc4!Q)H!l?tVW1!XxNdj3bqH(Ix+V7})v_a8e_VF?32H&UNd=7F{Rm0G@fb`%x) zD9+)UP~nDqFm8Iqym=7OU0M#=kH;9W#P$iI7Z=qI^0aQcP&T7{0j!oYs>lym7M4$X zg@|=?Ba2bQ90~b5ritarUFh|Y2IBOTd4$W*w&`=#^SNMszD%(ZeLkpj)zPh=QC>n* zhTIE1UW^Qh3%LC;L=U+1=-r~ttaN&2i*x39eA!TVY{<1(mYM8ml@$s45xTi6D&~sb zoA_ZXGyv|CJcvH&1zth)Ax#LLDuH~d;rj~oSPVuRt;<v3y~*c+l0Qq$j<T|fLUIQ! zOEy*^$wjjx9p<}utgD+dve5iK;5W0Nth9*IRKXk%ISMV0A_3WWz6T|E6Zd99>~_sf zWtETs#1cKkfwmmgHW6(UjdR#SAsD_IQmeW2bTt!7eItfvsFEl2v!Hb-4U%@PyP}|o z9}_xIcY0><aJ)+!I?9W3yrt!g4BQ&bJfq{ZGe<y42O$4O+IKGVAXz=cm_=6TXO$Lt z(n|__xfNM>l00dl;33<)PY0;|kF?&Q)FHb-Fg{aP))%37>uwP}zJ=Ky9}QAo$jBFJ z^=@pF+|t6ioSt8~oC=}BawwJ4t(n|X=%<yG!ofuTK=YaIVU=0SdKByH(8`a7*rAgG zCh1V~Vr2=&pClF+dwf9oty*__78HRN32Hq_7c6&fg<2Wp)6h^*ZaeFFXv4k+@zOiH z;7X6uD;3IM-I<(3`oP>(vLY|D`hylG#7WZ2Dk}L%LRK@%;P^Yp6CtI!SrojYfMxuB zr%<zq5&LDxh;T0-5iwH-$ssV{cnf@<U}<M|b^)wELL5WddS-#I6onQXWNOCrX&LS@ zqem2#l@U^+n-26$375Rj;uPIn%<NZbJ9ZASe1z;(M<#~=8O;_2Po;zW%YLmHOb)B7 zz0)a)`5&i)JhtW^hUy$%`(FtEpWlCe|M^}18~yC@;g7@mYX2RUcZ&}x%I()MdDmdy z`hnTozh{su7*?u{Jtp~2{V<O{q@#c9I7FEmRAz-2v+#}tzBq;#=ux~M??f0ljO5VB z{h~tr`tZ02O*~yQcZ-9s7yr=x3hsVAw>!8!o!hf{oax*>hr?Ms{abn7W!xPPK`ex= z`v<`1<G6<N@YNjWWgIT&{(kOX!_&bhJ5b#AX>Nap<MTYv?<MZOiQ{*G`yb{0i4m+W z)H(~T_pa^mbH9Ie`2TAB|L*kvtMUKy`|tRfd;BqfOOL;QE873EU(do9%)e*hfPXLE z|H|M0>om~i_y2d27^dFa(9`MXd6?kymoHp?1^0gOID^l;z~HjAtrrm5msC@@9>O<1 z_x^L19+F>ni9tJuZ~VgW4h}a$_=C@W_G~}$`Lpt~zwSBxCC^aPEx?f6^8TIgTgYAS z-~ImR%fr8S?Bmw+gp69kV*YT6@lmKt813m@!vEizXY9i}uiO5o`D@6}*G2Z|?&G&# zVD($A;r==XTT&U!=J~2|Rl7=;3U3$nr}DvhKl1xx+&+xkBf0(Dd1hDH;(Tsbm%hWe zJx&dOj@f&0dkeSs=Js{mp2+Pb+@8ekc5d&-?FMe|ucmjF*#~g@dTt-Y?JKx_Ft=N{ z-NNni8D>}eW&3Gnzf!F?Zm&}D;dWK-DV5vrRnzD83*4T_?P_HkxIOWSe=WrI1Fi$s z5!N<cw<1(}`HuI?>@Y?LZVp`>Iytm+IG#f*hp8M6<IuvPnM1<i4|)b=4nO0tmBSA? zJjUT64qG_f$6+&vJ2-6M@GTBEbGU)SbsVnYa8;M|YdBoQp}=7Yhxr_4b7<$#%HdcJ zhjD1;kZ>5O@7$l&{y3sbd)RruE}QhPflK*M9WT^8Rb15drTVM(GQak3**K7$lS}@Y zU$*m~i{Hxewv6e1eCley#MkF4#2@x~8+^zCV1LEOkMOlAe0}(P`0)5L6~1Zk&C_(G zi}A)0wwA?PqNq6ab@=cdtMA}5L)ek<Wx-eWzhr^*kL1a<U4A<LQ{!91`FOzLFb*vo z{;%7!gaP$S_^QG+q#fX`Frlphb3VYAdo%Y901v@e6r~}pz47dskXOLn4Df6CelTb{ z$xDXHQzE<zCcz&dJi=Gu`w+|sH^H|L%m@#|_ZFDX0h|Yu;&_N#1@JbQ5KCe;c#oU- z`!gJB0G{CPpP`)30A`K{c=rGnrVQZ2+`I<hVIC$ICd^HPnHgmQ4i9EwjsaBQ8*kFk zN%RGnD2o7x^#E@e0{s}=y#SMvS=<2te-Gax2=gSs>xaS^3}(YsV7`ilu>!n@n+1R? zx%qj3N8wuq;g11~yPA;4z#I>7J2&qDIPDtXufe<m;Hhg^+;)JwQ=ksPeILM&Q+T@o zTs9o$O=yc6fHPo_91G?=fc5Y>!Mqya(Ge`2V*sxi3G*blUkC7y@a2Q~6@U-Ipdo;H z4Zvj+03S?q0(<)o>t_eRwi{s%0QZvs@0kc~7pWm{0sL?x!w2C7ZbmrC&hm8v++b&U zAspj?IA9(N@J()h3!rlnqbr2V;ERUzYXFV~hC3e22>%4%IvB(@06d${(mx0Aq!aLj zFy{a+&ww_<xBw$=V)<GC8YUC68r%`OC$l<7_!E59(SS3+>6xrtxd0Es*8=7X0L@ca zJs`YoD$oYF-wyDbsVx0=fbV4ij{xq60Ir?})2LBHq2*>qGYB8O1;!U}f9w{j*MK-N z48YAftlkigp25l}%p_#*OjgEy03EYXrw;T}fVHz&_!R)h<w5@i_wfK5@>sbLewN4k z3&13pNSYzc0Dw>3#@yEd`~xhPE`a+h0MqV(I)^mJ11z`;@CI`cz?be~d94Td)m<#^ zNr2zxL)(D+4*;VISeR&l&H{!5!bRMS@HK9>&xZDeuMGP&z?a}#h3Ny_F`K2+4DgX6 zR<}C<UOxxMA8^kGSPS2WU|tPy+Z=|^4uD}LEUp2dg_{vRUc&Ny65!ra*1r1yJ~0={ z4q=`I_)r=2BcOpb0B<UXHUhH?;2QYs=niml1@M+&&IecnUmlou0373Gv@sUoLN9CU zMF6*R^SXP0{wtv@5FX)<N)~<}z~usK>l%QwL}tzd_#J#+2>%1X#q$|`Rs%c(-x@HV z12}UD&<&XL0M;#qIsx-4fNQIv9b+J0fVVA!HUe`Iz^EE13z(w;X4V1zG5CTQA)mrm z4d%}PPFn?Z3Fd5oe}``~nDMRB*oT0Az-$JX_Ymuw2*2j;?En`(4CMv<7XiFw4KwEg z+{w))z>HjcgtY}SG{1Tb`WM8t0+b$O?YIhH_3vSh0yDyv-?O?x*yjmmP6oIWzC;Mq z3~<WR(B5En16=ep3xm+QmgR*odmXq#7=#b3V|lFr_~bKC&tOIv^BnMyfTsoE!RHw5 zwE$f7JgmJS3_|h(pDzHu2;XDi-U9ICOHdEkF91$l4`U64u>;)sN5B)z170R%_$w^^ zRDjYeES*&VcfEpIdo`%Pgy{an=vEK#g+DQRSP$@nKf{;>VLn8-0p@5hBmDLM0a^re z5x|+R0X|^P12}pUtRImk0lvM7wPORo!<(7;7{C>80nQKx;n}wsy`2O2&D(75OWq1R z<W`1f6~MDQ0e>)`19<l?C?nuj2Jr5KP}gV%cxwyL2bgaM_-zYo_a6X?@3FbH3ZVHg z;0*2vUp&mq2yp%p=qF&V0=Vf2%Xc$C|K9;;>>~j4KL(lrGs5<dS^5Y+I?iyG0lxeR ztLJurH+~BA1nq+NGVrd%D(o+xvO5ol03U>pa5KVJxf$VMZbsStbKHy&W!lk<a5y(3 zyos9;-o?!*cfORH5kAb#DF5Ba%?MFG8*xLZaCd|#ON;IZM{qO33~ok<@~s#i;R0?( z8P`X-8Q}&V9^nP}vd#ZXnE(I${>#7r4^T@31QY-O00;o5ZG2W%_nk;c`~Uy|8Ug?q z0001UWps6LbZ>8Lb1!FgX)R%LZ8kJ6Wq4)my?b1g*PTCpp6B5*Gk|gj@iK!ZDU3-P z6%^XEJYX)MX|n?9_OiQxrrQCMHbm3L+!)Qai(%Vll+;$gT{LOC%w)5hY%uGzO@+AI zFUD;*YLi}G?FyQ7LDE)ZRK|$&d%w?l9%dLY$?o?1`~C6z@^XA`=kht{e9q@~KId~j z_UXrkA%sZ6FB%nMzfgasc<;Xn{N}j7KS%UCe^R_(yX_~%jlR~6o_p^7!sqU7x!bd$ z<@2Ba!Y0r9&wB2?@AID4&wFmVy}@($7w-J*^%)titE@79@xmtx|JTne*4n?WAAWev z-^%Mp);Q($#x;-2Yvr0=nWl2>Ag&kp|LfXs;`-AkKeFb4yxzFxtMdBcHBaDLisx_3 z>xbmEzIB6-<=e3T$<0FC8A=wn{NPVp?02WdVv(lLSt#z&raI#BQv8>xx<nJ!y)Hxw z{}ZvR_!C`qqWs*v#m;13W<F256^~!mL`i(--k^)xw76#z&nbZM_nKJnE@P7U2TfFH zaWDLuxL?0=`s+7+_Wn({Hhx}H0I}^!)6;l_Xukg5J6krPr+)nvRi@~|b(1zNor!<f zt7O6~A~2}fh3lmm=?1R9M<tYPL|a8Vt||J=^6vfYU0>KBWZT&X!hvh{jC3_uZsGs^ zd$+&nYH=h>6OS*`&B&Pz%MPDO6_Ej>={5U1znxAsBm91P!wrYsde%6QyAk;UOy~9( zuMQiTA&f{a(@#FA1t;+h!__nSV0AFQEdFJpJfKA&6Xm%@=6E&AVw%YZe-xZF@ZS0^ zVOp%x$+~aVf=-9%5#pmii!bk#Awr&X?c>^lJs;QcGw^Hji!*<pA{sUEmwyX1&2+Y| zuW&e>-9mG}=FQJuFfT7F<Er9C^9yq`(@U>O_)F*?v!gfNEIyE77K;qRIrXf0raf0{ zqB8az|1B<GT%K5Zk<M$aDULWaSGVX8x8dDwiT%bu$AG`SNjSz&X`-?2(#<<clf@Zx zZ|`mY7L7L6WSZNzPDJ<3mM{LVHp6^t5Bl6uEsl&Dj>9#=aoFtWx~=ZgEju`ti9cCK zu~kQ|xxMC{Xg~XR>A7el>#o85;M>tgyWZ%d;)wAb|IrQ0pL*-0A%Y`mS`hCfuJCuZ z;rqdJpV5LBHt4}fyAgb6V^VPP!DQf!7TEYFX7IjGRtLY-Toc^vTOEAxo|}R#C1%7F zRltv%k@hC!S&h6kD5E-fw&BNp|EJ2d`^ym8;ZC8CA9RVvgPQ0s7XC<+N1Q?1LW_0L zxL#zg^mw8f&7K1p>xE;bN8n!YUaVX!%t~A<-)&6Te@3!s<aI-mXe{>lBQ-)hbI=ft zRq5tiAd!uoxHe<VJ)YyYU4>t<>5mjQ`y<Vs-rMfPuSV!+7Gr$Y>o=?f3D5N;na?av zuYTsL+?r>uS+M$<Vxb47@+668)~9RF+?lIC^Op;ZXExv)^RK^*{Njd{tb^sQ7bPn_ zdvL#p_nwuWdvJdb?+baKj{EfgY1{b+*t&~P_fD`+4cu=<pFW9li!;TM4fuIH%_!fK z@g&MGcHkX;9)Wklqw2ZTRI&b&yW&dquwPGF{mXtXKD~Q_{c9vm@81FRZ?Vu&pLrXv zSMhp!=S1=89TOYy-0Tsz@p>n&?5`)$Uvtsdfd2^ln0<}DJi>lw|J!-l$LwqNIs4x3 z>nG9ItY?E&C(C~leO~NG8}ak(!Mi<t=UG_{+OPpX&pmi|58oB8EcW1?N4~>Yi1hz% zpG6O9M@X~JHt4{A1M?sW^C21YA|+TX%*co#B4>f?ZyQ?ZoS}!#8%F2^eksxD&S4`b zG-Bl9IWKh5$PYDOuHAvT_NSO@pTb=G4CdOOW3CCzHI^alJabLpxc}(6%j)@^jkloA zn^E^ofMGRYsR@#I0Jgw;;g6nV-oHLwl)ZuS%_OmEuQgYmyw=>_G*ETs-+)hhHkr3+ zeI1`)EUsC!SQBO6HAUdNZ$7l0^li_k<5S<Bj7H1x?Z}`m{+IY>^T)-4;*X2Idp@t@ zTa821gKi!+ll<L;iDNR7y5;bbSDE*}Bt%(p5_k^g;G5BC0pFcqS?G7>5tpiWFi$F^ z#bgLqz;i)~h%f^uR#gG_mjEB1vhdJ`{crG&<9^aG4#&4ae<zCi9zFbBVRSR^YP505 zrPVv)+wxK*S_XP@rUft+J1qPLzKj^!;qNAChvU<(pNN)$U+3->qMxwWT#U;0^dWCN z{1TSbM`fEAM^qXSi8ivHyO8!bXgh?%qw!;g@u}FFrpAY3W2*MO#rCCx#_hR>?OLYV z6*o3}?m0g7-X510IW8V+Ty9X~k}m4M3%Wr#S?_m~RG&|c5!(A?u31qNjZTfx7~q^c zCnG)0<#eQ`BqtfDnDAAZGsZ!}c~|^6#KF6j;~)$*4yHX0H|>aroqahq4mO>!;QB6j zOMKcB@#6rPpNvc&hp90D9P;~w`tF~Ijlq8;jKMk=WT%ZE96!C{@m-YNR$KB`=1(_m zUzTDXse)`(rDu-sjmCI*{9hB=byuNiT)jwS`h4pvHaHxIn}s{ZA4>-NO0F90b8E)9 zwm>wl$r$)mDSoEr93M{YEfQDxKh1KDzcMFE@MF4Rz_1~G;8zZ$Ylb{CE!|D#{u2DA z(m9aMIZHaUzXZP-@Bi5K0M|?K>*RZ;OG3Kj|L@_s5*+r}|5xk1VtrOQSIqx@>-nGd z&wI4{zgo_JcRZ!+t4n#}NIdRi9yT@s=Zitp;@`Iz>V1pKbEXZvAJ+iq)!lF49yB=~ z_7Ttrypwa;^S1mR*q~3JdsmucS88+oeD3<`<NXi)V%Lv0-SuZ{zH;I_LvLE|sRy2Y zPy~OSDtdCj_ra`s77KqpG@$SZc=Uegb7vnkgSOu1(8RN1OUV>}zC71G0j5@t_m2y0 zO&Ij5tWSv3jyyA>u^g@HH4m<rQ>!PG%>IMmImjI+=IX)M3yk1z-ATc>L4(gy&Var! z3RwYlM-1Te2}{m+9dgD^S)%9MgOt<%)sp>x7?b@UG=h{feELA;81hV@EFa(~SvXLE z^2$A0&S6dSAH6k2^tcTXK94l0AhZH9PBZf40=@$L^0GybANiUW4OC>~egJvz%O9wC z!VqP{MxHkV?@W9z!1IB7wGPUVJt-pV0%-4n$3%yQG3?UCy?h_lMaPAL-XgaqI`(Dv z7WF)$<-Co&CyZS0mNb9;FyyA&FGY90R#Vo^`d_^iEqgUzRJ@L|64Turm+m;yI1Mvg zk}R@HA2xS5&>nBH2&{b2J5dfk%J!VhinU`nOSOZ2(-(=B4;%ABkq6`To`0FOKhL3m z`ec9RP3y~*THfKI2iy%#)a}U-0q8|X&m@bUPbK;5FCb4u7nNsIL_ordKKLEx!8g$k zmgVk<_1PToJNGux(SknfWjef%wK*r`K$|yOZN49Erk#QJeHf3|Qp7qR-hFX0TF$&b zNyr;{N9ElNScZ*)P-lv$oUP5oUx|<LI^=^%!7%biA1yipJbuNIVMfp{??vF$JBIGn zJ^uQU4SIm|mbg8-;ibwkJjeIZD4we{$9O5)b_(|;8rmKf9he)9RnY&TTOX;?T;sKv z>#W1IB_qK1vz67C?5{7ux22lva4p`|wl1w0!h6oGVWcfvAbK!=yuB%6SuyG}@xB~$ znB{7N8G#c>vjlUB@AEW~3;2(YY;XmJ(O(PQqGuHMIfI^VKJW9WXD8qTjDRU;95QaB zgdcdEG;hrVN%KDTK(Ph4rp=LXQ>GtAzCUDQerR(3zv3#M6R6e9$T;5DInA(76Or0w z1C^~#5%w(;l_L!zFx>76%mHk~wdWy^v;s#)F@8>z@fgO^K^R^X9kdm>&bTX_fTI;{ ze|^K8z{w5SXj@8P1aygGem~~+=xX42l0g6eSmGM=g2owX(I0m+Ez+FAJN9+0)z@`s zw`?o&LKbVR9XVc6=M+cyEaX_G1UPO_S>sqTdAvg6H2Nb6eQ*+R#OlcpT!(pa7FW&@ zKl=Rxc;3qXN4oQ9^GWpACp58-W5f3U?-Xm?TIK{u`}SQ{<MwyJ{j&vTm^5rc&q;H1 znmeFS1aeRw=@@B5Ci<~#i3oT=(}3?C8Gv`+ViDMgxw7Xg=7a;^dGG&<nAm}~vL6h* ziy|%GG5sCLf7VKW>GJgSm}imQ7?%;y57zhjd8CE@`dv26+FZb#AL_DTegH5JN&1mL zjeeA9`G+%{BFmkMd5b!)MV)D>V%=k3HYaK|rgtTzcO7<W8ENRttoCHF?(pSkIs0=D z=+ChvyT3AI-K0Nvf?v&6?+Vn*I`0NQW<TYj&KHn(E805z(u(fEdou!eAn#*ao8ASE zoU|2yV;}nE4!|*XOa!7iB3$*b2##(5u0E_mclOs;J*)?-9yWq*ysvsVDd={Jh$DmV zlY><)A`Cs`w5PZ-FuFp7C5_2~t}JN@_+P4s$ahXNGIme|Qqk5F{Khb@$te3O{Ky-1 zK|Cr5*>s3JnEk%e9*^quz}1(@OUc_r?&wl8JO;jucBncrH;3m+9-Ynn@?EleNBoU1 zv)C?kFg=iIl}UO$oMVPTCj<9gjP88r!9;tS&8Od;-@iE--RS_oe?!_5azbd=cJh3o zng7H&b?02s;{c3qAv(l!{-Sspfb@Iv!2{BM>|0<)oSGS4df%e#lA-pAHsD8{<~Z!t zv~IIl9BBrOltU&T98_>YZn5*SjX%R&{6|gnJd`VXg1ADS@P06lGLZ-~-%;R(V}WSs z1Mgp^6DG((d$qu)k+v7VKJr;zl<&cPSX2BLX&@7=3j8O^-eaZPj^A%`)s^MdBAu2a zdj1B_NALrWC>Iu-XDyj&7|;Kt(FPuC?{@hdYmfc@1m17P@6BA=;RoaR+>e6i(nQ3z zx3f)Ow%SwzJ)OMuz-m#+`ICcp=YT7Ht~FtIvgl}biAEpVRzm*ka)pDyh2rA00C7UJ zfPVn~X0&72?XRx^UMT!?1(?pGfiFOAs<rYO_+Ezl{?+8oIo@BOzKyECA-|cCK27xZ zT5#2Z-fYCXKL9Tzetx7{&J*H(wUkl)N1OGk*FG1Qe+WAC*RA}Vzs-2}2H?9BX>xAF z_yHE+nfC<J1NV<&ZodLN4}27O$T7dy8W+e_WsMk%pCT`LE&J;SD3>rhNsp2Cb5`0> z^1Rh%CC0M+M>#6Z<byBuol7$#XB%GXv&XO+>3OZvRGObyX~Q`jD>Z&UMIBFoE+>xb zuaKu%7iFVHb_lZj>Bp)|0%@49wUbRl;H~@CPCAEzpi{uP+)l_Iw1qK^{4QeO4}92o z6}(_yJnqPOA?*h-{5pj?YM1#cIqypGy;SQes#{i4c>?f#PM_*uiL0#h^*r^i%X;^D zq=}%+_&KNW5anBSK+ZkgwYasCed#kqIr$dmS0m?%pJNaDGs@-JmXg4lJT*7u^I%Ef zmOPb)b!CvgQRhH9(zsH5cY%($N=49%p9}OCgBBtFb}cTgv|&2ipy1kr=U)kXeyRBp zs_U*NZa@}+{AO-;Yp!-J8T{%aX4pG;ZFgFzs~+-A*sZ0tS3}OIU4}H*IXXrFf0}R} zE=8J>QggFIb9TF0M4&VS_sRaF*OoeVhcFMDwDfV>#OgB4aA$R?lqqT<Cpk4|8lNA< z^P0UPa1MQlwj6E47_zM{w6*qX$WvlsC7)?GVtbP0I-H`*YHVMcLFaPRoa!0Cym;Q~ zO9yboJ=r@%yojec@%dyr-~#iPS~LrDyPUXtPoBczw@|Jpfo{q1jw?s<pNyNOT^V%c zIqCufpi_jMGLZ-4_aAsB&Nb`3yW-2T%XkxW1K-aK=k$JhCSJW5!z;{t$S<FCLx!!! zxJmj^tOcTTMZ`IId}tWF)<d2Pen&c0s%e2yj0<GCA<2s|cbyNJ$4WKF%QEi>;7?O| zJ#pWM!NaD~3{Foow!{pNgO`rxm=V_&=gVWrQ>!^&c4%oYJ6|-nQ@-xf#3vovwq4L0 zBV$HMh<y$D8+7{M6n@fPz5L1J*L`cL5G$-J$Jm~`st>y4RnCv<Qb~JDs<nWE#r>My zPxAYg(m*2rbV1+RmgGN5UJRTKVNOSYdy+Rhwa$M6&5OkM_o&kG!_*6gq37D~r5#`- zW*?BxgR$pk@zI~D@!YR)3;jbmX;@x0$V@tZl${_qL0)n%v*e*Ic3aT*w?meBigQxj zTdRRKXLS`#J~$*{`+fo)lX>^5yyO?mzegASXxHW-=D1sPwiiPtblhl$Ij3C%CEazH z*HxI;)J^SqP2Ils%V=+<=m>JIMmPsWnP=LZi}jD>{UaYy<IoZthiUW=^I!+?wA2uV z;9X(DvIX_{ig2GLI;hXJE;hrpx+pBs9BUy*c7Pr=g5MNEzig*IDH3Se8coV9ksT>! z<YU(Tw=kzRY`lBele}Y|Fu$cu$pg@P<L3C|4lSK?^zriI^gvFr2srR_YkA`}s1vgC zvzs6*_k+I<eY6@pnKD|{Yku(GPCaiNI%Xr`P_o}k)8&rDdaA8@TK;(T(2g|>8JV&i zam=<?+4TyIa&t^3veJi#4Ko~{UgCA>8im)XF}$8(Cs@Mypy<s7!w8N3r5PNjOuNX8 zOkiBcK?hvgyu*FEqSemL=Js-JUiaAY>dM+Iapdha#4*wFX{~FQBh?HaO7{~N+Xfw? zaiUubGGDLmXs^kXwCmaVBU%77``H)j%eseB%y84{lJQ4VMB|W4-7n^SwizBx7G*<o zOewc{(4Qy0W@Pc|lI{^BEkv5PXd=3^IeB6gY3$wLTMo3pbdD$_?hO+6&R0i3llq&V zoE!M}KLJfAAI3YvK>3TZ7{`Np&ahD!qWr~rX)`<v`sR^!<%BL>i0<V36G&sA4(jM{ zEH)#r=bMpYr13=+osA$J+cl27Y%^^`Z1-05!@sIE4JlKOW}A_}$M+ocX|JB%zBLv4 zxRLJt2lNMYHSbWe>W3xl2dBD!33Q)*o1)FXw^{OKe?1h8vVTOLzr*jD`la1{$k$ne zzC_#moa%lt?#Hssa9@_1le7hlrQ<n6Jwvu{gf5!Z37O#JWVCS%aCB<v?IWNgY{wAu zf;O<Me{q-(kiMj$4P9s($76Jj2p`IzeKjpa`muO*Y4=ai4{RUHVjr-aUftP#%5Zv5 zPDC3OZ#~%e&Jr^+o1Vq_9Z&auC8o=0si^<EaqocVJr`$@&+PnmI?TtO--sA*pN-${ zg)Hw+68&RIq7Zad_K`;1DpYiAFZ$l$fo#L?np4s-hata5hCqv*$x=5hb3ljF21~m| zt{KTkom^+9oe;WexJ&b_bmD!P#-HdXf6sAF=?2f*y1_8$1#vQwf7<lVW36G??aZd! z=NExQc{`o&_r%^qX6hf6JpMxgw{VP`z=3rOL~dfg(f<j$P`{n;^9z(*nMeoEqpYDK zIZv0hC^~+$Lg`M=Iy8NX*U9G=oxH+3fb{lz+RP55i03%RpGXq>WV$VSz)l05WjoUW zmhwE5Js)Ljnc#o8r`~6$rz~dYc^>^L<uK%<j0kx-+xLJ7pToNxLD|59Z+bnFr?L*t z@$>~&*~O|2v@3e#xa5Uq<qvW4q2!r^x#XG8mQ=_3fc-A!iLg6KEaN&VpK~w{HY`kM z!@VaCZjZE;h}>im)0JnFZ_lE<W{w5Q=h~1gcW<nI+8=yHs=P$`Hjb~oA_i|%uxp0Q z3q7@7dwWa0Y(L<FPW4Ldr*4<!K*r0e`_$ZUB7Cv=^`hc8Ipi}joH_RC+r!5|lUZLb z>LaXq#YUh2x&`fZ!OO>on(GU8v(6!;MLp{deR^(q1=m5WIxavSRpW4Qs=gmCP=0)G z7)hbm!Ou<_dguiB8SzM?zB>y%5(jm0=Bh&T;sxY8ZzNNGZM=0MZE#XA4C@PN7xC9O z5_fd1yDCXMmz&kQ>n!l026Mko3{*NnlQ+pZop%_t;fxDojB+c>k+(KUm2(<+WhN<J zP@C$n58``Yil}_vB?5*a`h6$|9bPs9*n0s}b9Up!6QIo{c+a(h(ggz*b+mipd+9>j zZw4yeFDf2M8!pG)&bRndw6QDAU++U5=+nTL0NbcOP+5Y0Kc(j!o+|%hw6V7JYz51& z!<FT~fHu+oh`eRA`3o&p?)pfyaVS}p%QP&TWxgC&X3fORGN<xih&Fa2uXvYnoEj&{ zDe>b(Kc2IO?!6;R^q1k+z1$3TYU0coWOwM>XGU?QOj!+iqwAXLAmpDjr{p{JtqI>+ z=JH$3tlzfG;kVVZe%qTN8cRVR&ST8k?k>y)u7SLU_HT<u_wk*3OmuLqG!6aNn<37S z2V+iqNzdCcKmKV!3>Sz8pli9S<r-n0#L;2!(h;P26=hPNM4tZJ@IxCbx%R}m3z5D6 zKaS0?;qb0lsO)q@iv}t{$jZ_zn>F!*_&~g%jLmVR@9PC4U;4ZL0(CIY=w!6~o4^gf zi}qXK?;JB?7{Fo87%v5G*s%QoaGir3L|uIw(ryzfE%fMqt|LS-zJACz!`XLS+<-oi zWkF6lsjIRMU5J&{hqC-dW@G^U)CF1dpk5%;1kW=~flSkjG~}ChIR~wBww;TW^9`ig zR%F4lC<Y60%c=Bn+4tmw4GUuPdCmegpC$fH$sjTOa|%_aBPmv<(_y_!k9(JCy~~Yz zS7^Ok5PKJ+v)`AvTm{{K1Umc(WZ4r1BI4t^i(5n-pee6^Ktx7CpPG>7gj+N~rmu8( z{70j=;)?I1^F^c+-;ln6@8vtl@x6FA^}JL>J}B*PKb|HJC_ZdV=Sh)NB^Pf=ct4pM zNtBo5`<AM}wC63c=V|M&&@bY6(`ld7Aw;>uRCXSBhUjQT`6bVF6>&`n_#74wn>*Id z7d;cy?^8vD^28R5735#qRQLJFi>$QG_+}!lo$gCkI-jyJ(bk?TdF&QtvsqQ05g>oh z$8QtLDRTOcRwA9v-<n?%f!{AwWdtwZvLlplZa>ymGBNr<>qK2~(e9;rDBB4g540WQ z+PE3KbRXu>Yh0gNuLU6Q0B1m$zpm@YT(arfboo}T)k@h5@X+SsN`uT%?Aoo?7pBWq z54c6oeT$R~LcW+|!3^Gc8hTTtxy?7R5ovheiu(}wrDsqCOpM(|z(ZJmb~#!;fbYxD zFUM1q-6K(Mk>ft7WCSrlTar8Weq`o*B`+)6BIq#au@UNrj_ARB`JLq-nPIIv_#xZ= zUcHlcWLu7%ZpXJ}rqkQqnl?^b0@rGN7}qXM%~kg2JgIloL{?069^?3S>X~OS#~Qoz znn<Va7{@!QTTs>}442%bRU&jB(&kw9ML+WY9_2ofqDOY<dSr!Vdmo!`+qws**}4g5 zlS6b+R%=QZ9XA!;_5k^8Q<>toCD1LLU)9!~T1Z>CtBrbgl4ZxVZ7Eaq<c1p3gniCt zEdcyKN_oj~ZB4{6S$&MQ)pYO?-vW`7ewB!z|LUPXg&Y;iF6H@!`M@69b|3>eDnuBv zL%AQizSr?mQQepI`6JL9O9n+&+Cq`j`G)BDD*G=lBh9%`WG%%z$5mz|jdTfD@+&9m zpbz0T=rGPd5n&hJ*Ct~Ou8QrQcrSP}EO;}JXO4t7BXm1(Iu7QG1933lj<N{zQpdmV zYW?!u-P9RN0GkVN--c_i1$S5890~We7ToCxaE}7+;Jd&*o7`|7@&bK0h!3j(GjWzU z@iFLb;HBBn*CWn6GfdlY$+C3X{>$XMWHWLI^m{Mvhm8Vn_-fHZ*?Nz}JCibL);7=~ z_RTkOb)u{)=t0!0ArobF>iO+UCzYKik;lv?hrSIs=?8M&g7cgO=iQo+{B8s=aLsx? z{UUUwbH(b)Z6CjE)is+u6|X0t{Lb~F60$&l$yH|1_dOAuZ_!G}pI3*6lwJ+pVQ#=# zY6e?FBAA2kON&KM3usHT4n9>2S_qoryb1KjB_gMaxvpbIT53e#9o)C#z9hIh+$S8X z9GZK%mvla8gxl83^|H`R{o_Tzs|C-oKWN828{HXQoqfb!56k5`FZlRYjDZg{Ee~^V z80j>;KLi@n_Py#LZP-kEtwxy4$XbmyU^C*yZ)^#8KvWM#*NSlTVA4c%b@Ie1)D=A_ zHb*z&-7&2)TBS##tM$m}t$Jkqc_SFzkreI{ik1zpu8ABkqQ8Y%$uzW!oHBraXrpuU zqU<`fjqAPiuiAOFq9=eqF#J|@=eZoxl<FXLdAq$Ov`0S-_#nR%zT32cN(W@OG01bH zhSOW6rAzya1M)uK`5-^1B|$%f%;&Sx{%$_#<3iA&JZ)W-meJPCdB1R=f@xbZU%W`y zG^k`g@8t0c-Va2fOW<1*%D*<NYnLx?prUJ`kiIyC?K;4f4w(L7n;F6ThC_#Z6;)4Y z9nhm2p9Y-i3uO9+)?fPW4@L`CO{E#pq<>4g1F$(D-{3hdvujr$+ITnSs8f!^KxG@{ z*gUo=-TU`v+!b%4ZQHE6r`s2P6tgX3EYCyk-vJtOVxC$f-2t4t4|4!|M7Rcgf^sO= z`=j6~0`2?GBDszorc8@|+4nQ#^COS6>ugi{4D)a;gFa4Nr`k40MB-_;Ew9{xvAz#w z$+gfKcHx*EoNzU-tciG1M1N9>wf38W@j^Xa$<XcYy-CuH)_aq}RZh{dXO7a*a|crb zo%JHzdA$hViMo*{(B?J6t$^oL`oyZcQU)u#wisEUiw#w+S_gI0F33sFE#k=1c@H0Z zEL#NbZf)C7xHAa%^`K1|8EIa8Tid#6e>=+UEEXMHOYK}JIv__iI@3gEN!`;GB~FLj zS0?u{*mgCCDDRpVla*J`lX`u2ynUXwgw97&N_~%{mUik|WoNxsS#I&(pP-x@aNiqL zzG5v$m2VTqd8Zfe+n^(i8m_~juiL$vt9xy+2()L5$X#2S_TRNqg#S%Utn@86!>5e& zwQYEIYKxY)E*D|0dy-Cden^Citn!KTEhnVEWx<uo^`TtSW*_pAH~BtfhD#xHw&Hml z`3T!`$Sj5h|6F@rcp@stPWo%5XqCJ#JsU0O_;73z$8+RNw6PiE_5#ZM`~5!}{P{1( zf1ijSKHvv%s-I<H9QR!x*Uw{xs-N!%9EoL{v*1cg0<JvvN5mELov6f>E?mc4({V-m z?4h3yTKF;=iI%mX-t|v{H$0gY*qAJOK16w8791(F`uHZ~{opJ(!aX*n|3e%pvT$VH ze*;Gpeuydjc+<j<qB#8ctc4$aZ_UJyZSR5~)o&^Mh@VH#{PT+gul-`|O-IsTrF#qd z0y2~PtDsN3KBMNWd!LZ>*A4ouQKq_q>+1`br?Zdc{i5a0se7?JW$J$Za%1Y=z1(?& zvi&964LP2~&4mfJ_B`St@U<CZn<yXgJ>{byaJdEd_b!RaMn12Sjat1*Hj;Kn@9cKR zM7e}@5l>jwILk_r{!o&Kul;57{XQ*=yQf)Z{g7e7@gA_PeIKyNaRgsd;|Tc}eQ;}G zoc&MDP01VHPdi$yc2v#Uj+SZdpx=!>cfOMZ`DPYau8M=@c)^unv0-ompQ`3*a=n*p z-(Bg2tHx*(xmJXKPCG5enYO2@N=^DMGmS5;aFtV2X&iC&9klAB?UU=vCE(XpL9OG> z6w&C%uj*>Z2f)j!Wm<>H>pHDt56Z0Ct95W4(3uWdkp8H9l|O0;W%hItp+C+?P-Y#j zAEsTE`reHqTuHiy`<1+=E4iWRC!%9e=0!P&g!I2&qp9_vreCTxX8G-iO4o*OCD7Gf zD35hrMSE+DwocMT%ri%lXlzXqpDek0Xjh*hR+egtZuHUL8*{$uIjapvG^y)V{YKf) zs>ZYqu7eHH*B$AoqaMR`%<^fOYU^{;+q%sfFWNhtH^%0Iy{@BWZuMw!cKCN2zniu9 z9=~rE#Ky1T|Bm1PYvY&bpD1}gXn`wPTi5g(z?}m*GY9<iQ=$D%9oGb&ib{H}viQum zG0w%-y=jP^Mb`Zw-ct@D|8r^!B;Tvn2%jqBOS<%z$Zf^<lDuT;KUkv8Tkb<T4e8FK zy<F$kfFEz;Ubp<_oOt%(d+XxV(g}<2y>0Qj+6>TDy}EKJU6kL2a;3kECN`%D|53M7 zRCZ-0H9)Q`>zbD$>!ZIv$M!BER{D~ay{{`-ll0k<1e&*6R4zr{yU{nNpvUx4k7=PE z<7(S0?Enhy>#csDBdj#&N2Ukwc6}UlF{Fv|F~H(T0qm`%6$e_h4(d$@lC=)UTz@@v z5=WZ9e(YB0hWOqNoN8TZhR+#kUSGW#?oD2FZ>i>3Tc+i$CEjfS9p)YkjkbBv<2T=l z?o8w{)V<<(%s$Cew7fL(6t?+J=)kI+JTG+;mU9W?C&wehkoilTdIR<Bsrph>eXpQC z8yBjPhh>*&6RYG{BhMl9Ng|8~-%&on@ji3$b}Wo-^vlFe>&j>Q$LII^yEsewxz_c< zyOb4QznG<dF-x98p+cqP&QiY-_b%JY|6cR1D+_ci`^xiflNOtI2SjY%t=D7o?xcA4 zdG{^tk2mk~t$8<;rsiF3+W)`iT?KG@ws|z6zrT4@5;u>+`um$l^WVoj+HB$R<^(+E z^ZWf>oF)BS>w4i`%8IW)aUN~9=0Ref_<59AzY+It<~)kYvQs*fbGpuS-<GC{bDHSy zhiu!A>-vwHVamPDx*1u1F}icpH6jw!&COC*(xg8_y$>>R>BCwBd2L9D$7{8MfDh^F zaJBcS@EvgDFy-gg`WUZ`AB*^P2)Xx@^BrSLpZvBD#pdT44SHfqwZwJeF!B5laT@c@ zo7Gj+1|5&Ec!AHP7w&H>Ja!?Cd!gFrw+U%zzpTA4IZJ~s-Mn54yb_7-lzR@CZ@JXz z_t|!G-}TB)?z}H~9d*c7q%TRXiEvH1MC;nc_Fkz^@7dCHsRiYo&JmNSdtXvqnMo)U zb9A4McP%J$!+K{R+4?qSI6_O3YP%OB&F2=I(iZx5nh1XuZTd^}$EYD9UvOg{5dSg9 ziT|{NfG(7`a6Rc7Goq2#*?qN8_0<S<7c0-UxU{ceeA}*}jdh^16Z)y0ZVl}bXrEIn zlKs!`zN;;{?FrCf`k?7bZbP4~>V*7i=WU<kuWyIW<J`O;+s@1VOYI5!mwXmZ(AP13 zT}jGef-zZU>SOV^*^RMd|4Y1-dl9%NYWg^A*wS=A$6-rcf7|1rqmS=oKh$V}^YcWH zN4IcW*DASQ9Y5aJV!UT7-?!y>MHlzp$vF|j5w<HHPiE+uv#f8(Ig0jOFf{Kc(Wa*B zL`TV7(O8#ByG>}yZnNnn5#YMTO3;5N_=YcAu5Xk%0aGhrDg{jC!0%O*gROVvTbe3X z;F)>ZXUzWzE5B+N^3QDB{dp+oYN-dzpc(hO6Uxii;>w$a#^fZVx6{(sF42y2-<IC} zDbg-Bqn!QU0NmS<zl1y!d7lsyFO&jLxrTGj$U98B@tBxcDaQo!mgSTH7pu{hF0MCY zjE+u3cRm4}kZ^1+%4S~DspE?oQ>oB<Lax!|glKagG4ev!1J?}chmhxuBCpK1FtuTf zGGx8-uk>A`Y)DmuYF&}ft`zB8b)*$I0NPZ^w9;;2;XYw==f-rrU**JnuM*dqp4%FD z?z{Lq|J~=ln`n=`5*^xves_Xi3<I}`Tf`~!L1U{i9jDs7{_tZu<~!#Gcr5#gu=(l- zHsgM?oHI`jRN}tUo+CE=f5?f!ABuzDp3iT-^@lgd@Ha8`=2#+M;<~_Nv%uaB*t=Y} zmO90=*&ES@EtvCu#%fCz%gVK`q8;eZ?g>S^G5@%KWFKVs$4dtD16}yG0$0Mh_YsUa z#+74v%kQH**}kc?;7>9wu1v=?dyob+*4uRjel@kuovZW+2lNQ;@%_dk(erz*wK+r< zeVu=Y^3xtNchEn+ZSs~KL)94p$L6+));x22y3>F3+T!%xlu!O%a|XKJ7^oa#%mOR# zmGUgL@;r?^zH?^fC}hLO<NAJW&P;ofO>bPnjMVKlgKo_^PM`kT7PFE#TPqYk)`^%M ztrqvRLkOf{9IyB^ET`7VHB}L)bBc(3*1&Us+iAFGy*^ESZ`ES!xryt7NpEsp(Bk*? z)s@iC<vgO@_9scA@jlEQ?g4!28pbv9AB`F!Oj<p%g!W|-c&rfg+7RU@3^RN}pJ_jw zUANPvZkH0L+p#>#j9-CH!1`@}@9Im@#{4+DVvc1)U5_*^*O>3SuH?A7SkGOS?=pGb z;qjSkii!R7{qgDj#QmOjKXKjrz52;4lzTm8KdlFxiS5o$X!qb`w9ysUZt5UxGxM?C zb~_w#?fBL#?U>bHRQmnt-m``g>PZr1hcKVL5+_~b(xwD_<32~O*EzM^G}?h`AwPP6 zPdhO`-CDtT-m;y$xQ2cs@aJV+;U0AM?mFO_e0EyTPU{(Ec1=dh59kHslm}(IK-;KK zv7VsrNNbgAf>-iioZSy9VkCuD7+lX3A@J+a1lmP^1g>p9ovqe38P8+lrHXEQeKV>T zj{B2EV-a8&qAx=JKt-a>d&u%vC^ba?Anw1mP}#iqf@XURwFbH)TjIW20}YCfLE6D) z@qHMI^L=1h!>RuI2Nurm`#_qp%Yw1^ooJ)|Jag@Ic7G^)|I~>bBRKMPEjU~tA|sp& z*)jUGBwMYEk*3r{qy5}pK9ZUgq>tMeW34<T0%K1l2S-ohdXV=i!IOp-II&s-zG?yP z$vS$TzHmcv`vZQc=F4Yvz+^}mes>CU=3w>_j?FoY4R9_*oSQI`LuUcg>NuD#XHnPp zXa5;sYD7Pk1FjK_E$7a6FGP3#T<?4<y2IH29hZ4Add#?=KBUmvDgk39eGx_h_qhf= zI1D&P|5T4e=hG)ADHv_1e?rPcbam=P)X+9Zci_1}uZ-S~G!1&>{1Op4dono~eLg8X zHlg<V-jO2uzoCnjJ(}3J5p#98p(fIwZTTu7&(Ou_3}1yK(P+WweDFmrSH}KXku<TY z_oWr%CqNrc;~Ra2dw@$DArH}qnQLiwdg4@{p4;s{<E|im>$!w6vA%Kd4ePhRZ;yjx zHlK+V=tKIex?9UDnC~m^kzV>$9Lx?phOxS^VKv6DCaCC#!Y3za*-OcyzbRA57>OUx z6i0rFc3hh-j%48XOqK|Q&K$20nIce(-{0W54Lqa^@95*py|GV27HbEc>7s7KcPJ;6 zJW%-<XiOKbOvgA$Pdf)Hp9T-<a;kLI=$Fzg#v7S4eh_@1O4G+dI~&u4cDSu|q#`8s z1eIT=m9a^5_CI4-G}``RrKg)JNM}lin<~f$N?&QJ@IikfpDi6|s;I@i(41?zr?y0x zm34UbXpXgK@SLdkJc)5E72<G7>u`l5S5(lpQ<Ef)Y>h_uy#&0i#XaVH{|Uq4rM=|O zPAMP0nR-XO-=FY~a{t?(SBE!&{?~#}^y*2{CO^b|XLZ#P=Px(j@6i@!$LnYF!Bc3* zq3;m)sQw1eqjG;xl3b^zug+}w98R?ljIlkqXP&k+;=!v6xDPJguTa@+ru!Mr=4U0m z^e1U4RP=V^9MRvVQ<pUYO<LMGb<P24`>);)oNo7X{Q&Q`V2m8xYo9Lq^FSZ>;d&rn zoFNYad{TztntVyMI3i;yrHC`uo|x><;Qg1tU%!|lBDu+CxOcJW*y4naHYfs1t97Yc zR-ug2YT`tijAzIFLUk@t_{D6s7ikDMXX1CrsrI?~fkWG@d-^EWS@-m9aa#9p8~NU1 z;B-l*zrGAV>SRNij1%FnUrb(x>n8lDlhxwdh~EO*3~}wrRDPF-QsU}MiK{OquD+C5 zeS5hFEz4iupQU`Thj9H_mXi7VP-cIo+Rsvpca8Xg*3%C0irSZ#C->!z7`a~Vb=;#@ zz4pay%9WrI=%2)N+?T^NUqZir&)R1<8&3`hG4NIVzJ}k|@p~M<?f8N34)p6{U>|<O z7vi-5KaBHl#<Q4uCVq1rcO3718IVKrL^k(Ld#`(WR}=Jhd#|O;ml5xm7}L9ED}(wB z%UOYPHd=e+DMQ8Dn-iM8FKlocp0i9B%1m?k>+4WnE9isc+C#e>n(Jj%kAh{ITrxj4 zCnmtVBH(pyL&g_4T7oNKI<NLyguVzGaSVDMeVrL&tP3&-{iycF#R$72$zLyJUqi|9 zPL#2Oe)(@5udw%^Jc0Wjoib*gH#tk~%bby3?K_d_Azua<4{YZp$YNWSFUNsvM280Y z%Cwztxn)c(q&t#FxUBsx^rc{0_tgr<t`yFDN5}!1&Ug-^4pA20rV_xgGfnE;0mx7h zma|l@2`XIeS~O6x1~QM_OM$t`wo@Nkqls0of~Iz*3{=WEU@9({+`DmrKBwpx?$=!N zu+{(qTZS^$VSM|)WVJ88?cQj#+>d%8qm?}Y*~#q}9Z7|C()V{Qcn90tjC_7;&&|Hf zSpTukEA?S~9ZYu!?I#SKvwVLR-#&qF$I&k()_eAcl;6PPXT)2Zw(srIcJ3)$uS<D( zdyVDu>u|obs|xSIiyBKG(sz%}^@ONTGOm~>Lv%9^(#Pj2T1<cJFK0^sNh>D1|LC;+ zZd3k&FWP&8y!WMvvc43tjyz%v{r}6kF*&UV_s4MGfU@#DqUUYQg)Lh}V5>*@ey2eH z?!xmS#&j4<rObPJMda29`-idSpwpJ`!1vc7uSKI;@FZkU$%CwYg4af)JJ0`hb#SqK z&JX<%&zv{8kj4Ia?ld3vqqn17JMc{3xUF;YyICg7Q+}g4p?Sy)o*~!58PDM`VA*sg zRqkz|AN9+OW%A3pVXjBnzK)~^+ZHMx)w7IU1AbaA`!6@d@5^zIPRu>UI1eaC#xetc zBhUAJ)tsOVG6Y$Gb+w{w=8?3-s&_H++x56JrOaEeeB}>L^My=^hw^yWH{?Eye%p`e z1-Iz=iO1r%zzgV}+3D80T9(>tD&JAwk+gHKi1@!Dq>d_MLs>X+d9G}mH<A8bfzO9H z4^9Dgww?O6`<&<~P2NV^^HjVv8IO*!=rsRP5BlTjISS5WNur-I7Pp~{ZAp|xb3?81 z`Lx`_1(e~=sXYS45(f%GyXRPY4>ZbEx%Ar(J(7Vo8lwDFUF}sN%{h#=ybU>-erfbu zep~GU?jHu7`WNEP*UX7Nj1Aj8Fjwk8M}IU|j=@ph|6s1_liBzkV@?^;rlW9`=^Oq4 zeIdb)#<9-%mKn*Re=7A}wAqf;#W-D7IoXg8Lz)_k`s*-`c@LR8?lWXO`J>zu`xkR$ z{Js!qd;fY}#=-L1<-CqQU>SD)g&q}OPp!}8h62T^ZGVmS_|Rs@B^B2vN#aLtXv^G~ z|7qg>j6}Zb*o(FZQ|<|&?_7hX+7;iocPI31>s%F2VLCn~l>6=XF85Cp%59jf+&FqE z`+jdyfNK&a_co<W?Oi%bS!pTg0p>;74qkz8OgFn+KD|8F{e9*Ej{Ou@_1=uk2D3K- z=4(hhnf}|er(cwiz9^xMmoKZhCGl|m^CDU1D^Ac=NyCbh8E^3n=XQ>^ZC9&qR??@3 zdw5FK9@?@hi<fdg#M|JZ!-mrvnWN&Cl4tSv7X5s-s5K?uB2)Uwcgel6mj3b{^nr7< zMC2WIE))Up<mzJwbZz|nqmS+4{Q4r=zEg;2`>hxrqX{uQSbwLUKdwb*-*b_;pUaLx z->K(H{P_mTz7J);Iu##8$+MJY{opxFr&&7T?D0qr#QDf8JH_*AA6ED`9!39Ch1`=7 zj(QUHq?zlyoV%|wR@(ZTD@RjAIeoh%-Y-iII466%Xdmj*RcyMTF3LHclsDHx)|9+6 zNd4a>+g2y#*u%Rhvv$SBG_YvVRJ=2mFZL$OHB9I}a-V{Hr=<k$(Sc`HeJH=2<!FOx zfo-^Ys?!301H6{+v~=}uBrWjQe3uf-BjdcSPp<58nbKFysfo%&8j@tFxCSVz5VA|V z9RtXYL!svD52y6r6MwCjt~V4s|0m<|kjJhNw1vp^?aI*t5gBVxafZg07(vFNqu<@w zQ%32@jUsU3Daa9!Cx&kofz9ZL(E_=)TSmLcRQx@Zsax^E66^$Czen2lI)*8G7}+7m zGW6q%X4qToXn>5X+N&i^?GKgD)k${D0xLE`j+b#G<hSA^D{g}N7LTvgX|%mXQhwps zm26RIsh6KX`-t<*BWPQZF*)Z4DA%YykHNq>b(XSjLQEIR2gEPt*<*iiiRFu*3liUg zF+Gj`IaW-*`YpD<j`jSo<+H=@4_NV;?0N8SjMWv4>0j-P4}$qX-NSk9;ay(nVUJn$ zd`=g+x>c?(A<h$!ZeM9eOn!YmUF}mQKalhB)jG9)WbKPgjQ8QlG}pQB%e<E|r27U_ z?*Eqg)_ou#ta)t5TbmnK&&%nt{m|0p0{&i=X?AdKUss(GNT0lA$DBNKd*9}}CQ_aL zqlb!9cY8<7%B61%RNk)5%a;D59<#%PYl#UMHqX76ap9^&b;lOGtJUT$FBws5fI*b; z^3|!kYu^x+8PZm-z7eOXo7K(}*?dlk`)229LY^;3|MbUYyuNmM-&Ic<(g_-}P3);J z!Ox?070s?M7@>VRicao;Ov+f1?4R6`g_sAqAt1pk&(DSax0v)@@%lqGF1fFaIt%UJ zgEcP6WB+-HjAa<%e%rHvdk<*scig142WQZ0IR+ic0ZE6faZux?=EO<NZQ?%ngVSE! zg>>{e9sN7K^xx$^?wN7$IB##s5j~E+)!{WrTPl4A-1pXL+lo3<#4?V>M$93`Bb0l8 zTq+(wAU!tjx1}rDO0L~(UZi}|HTQBypCQ*exbE>X<9&=c!{ot<@`s#1E!E*zdlYP> zCDg^f7+2Rat1gFy%dRcSjO*BCPCB~|Suq_M&meyNQI;P_4$Q{)680a5-EJih&lgks zkHe-r7RPd?d^dYJ8CE%)<I1`Iisj7o$6);4QQ%7k=)!gBqW>4@zjWx*LFxaW{&Fzc zjC6xWeBwIN1w1>=$j7bwkKuY;%NXCwSbtjn;hf3UJAj90oTmS1$(9|voLbJ)t|b4_ zJ0Le5&~wI@&?c%ehHjpWXMDpFC5MwIJ&*owgj{)FHg(Lr5YsWu2jbF%kR~@(^nYzm zPItOom&y%&bxvM4{R{tK%n9{rbEf1Y!Zix{2xHRU4!!5iFN+Dr=%lTZc}Kx}x1n7w z(7-jIe=-IG+kD;2yVjy@hcyvlI(}!mI;1(pSf|$?+LeayL&YKh9x1;swbC*j%W|R& zrd^73wN{$6WR<21X=*ixEGu~3&@MYono~q98$$M#;ylbA4=uLt$hELEl+|v<6sSUZ zzruLlhI(7A@odF-eho0(aotbVc&3OWRT<*BMm*Q1h{lMK9=d@3pFrR41~2MaEROW* zdE-wRaxD#XW!^aC`$i}7ehc)(S5+NZfxI?9BQN8cC+l3Qsk*pU?m~JW>i!tg9?%NL z`MehQ&Dtj~4qu8kUNAC3=kS{_(tzJ-p%cm`{T$absk1G`*t5(bC1*vhwbw$q&l7zs z*IBtY)hTsW$s4W|w`+ubWyy22CEN6tbZr>)R>~(9ZR6S(<r&H^wHA$AAZc7|T$-)^ zmOl9o?vqvYcdz1SGVZg(BZ3Zxf-QbsZ>ru@J$T~a^m@kt$LI%Q@)PSGzs$P-#g+#k z*SKg8dZpw=BVzBDiqo-PVH<y;^r}}VtG*hY9+NqqpMUexmE$$Dt{l0q8Ty(_(VT(B z>biJ|x_<tmT90{cGFHxPahuo&2j7hD<i3zA#i>08c-vlH%~-o#v?tYq?%J_*>BrcN zZ$AS}U3#XB4Mse9GL3S0X2AEdF%=8sO8P9zZ+>BQ<O$^Ie8Gsw=kKqM1o-@Y`TT72 zTen8O%ICLI)${pVBis0VJ{D_aw)Rnm6V>wrnn((KaIxC|a;120qg=zb;(*tJR{h-^ z<#Ujt?CDeGd~B9-;@k5DuJNWrS3nt-F7vpp%WzIIo>Ym`j*E6>ezJL?8p|(eDke4g z$*zT0;wM+8M;B@1gAREC<-bFH548PnT`~UpDVOB0+uv=T(x&OV94-6P%h7)FC<m^z zi4RRi%j|O}p1D!<j3oQ(&&inlIicW<<QF+1f0EeuDt^_eD&12zDmzy>-q~lC_~Lvu z%e9=td*-OKHC}UC_94r@k&ZE!`)@EFdbK;ScMjJCazjv{diJ>Jcajsb-$gl2F1aW1 z=o2mxm~^RFyNuc8%Dm%Zp8ttm)Rza730EF;;htR&-6-QK_uDq68@VSxS(KkN=7$(x zNZDMAyrxiaabIeeY(s8By!_n5`FVsRKg4!?#~F(&l8e6Po&ja!%je$z&|eY$BvHO! z&+lI4Qo2xXi#sq6c<_yS>2Ds|OM6^_II<aOP3V#e#=KAtU=*4t>&X{^UOj(&@8zhZ z(}OPBaQ)l4PQKX1xZm?b^Dy3Q2irj2KF4YY)9<rr$@4B{2Y3kmJexi6_EWS65^w)8 z-jCW#JH;??j4{aGMmv+^aBRS-aO?%ZVn(C=o!OMRMdMpe8SgmEHR+R}u~Fdd2}27& zyNLv>{g?Ff9WF2<UnN|?Pkwt0_uOMU3OY?62$naxN<>Cedy7D?E5}Z1fzhY5z}ScJ zZZ&k^gPKLh9l=rRzx*w6m7ZL!p>OrTNP`v_J}Cm^C(^%{@tx<Jk$X@N%O6Hv{~NH5 z9@NRF!mRJNfQhktxo2%;3GcPw8#&vG7{hmr=^i$Mv}H1uFV8JtJYSw&z?i-~4`K9q z5gt8jZq}tOG&jUE4o3e|+f1K`(N5fN(B*ju&r$ArsxJ68<2$Vo5!!jSNq<5eT?G9F z^0_}<#`7qbv_=yFD>h*^%eD0G#~EjK_;xcgvLO~rm_EqED?qD0<7fQ8=cJzw(+<Y; z-r*0RZTyxz^IM6cjgQC2Z2T<xiDkZLd9!@W0gli&g#F7iq!=fASjruakZf~Y+P6_o zFXWPegmUaQ(;mk$j1nG<702<CGloMEr^5FvwMHz<nXMj{@%y+k#^cHuby{mC(x?2$ zG@k<FQp|3CVQ%93f*JWaZJQe7NI-A2_WAOjdQ-!?zYa4VWjkcTH)}Ei8PJ`5leZk} z+U%45nWe=UQjdO2*)@+qu0E0zjqWS?+M`FQe;!0zu69n3g~Yv<zK@CqXNDt<G|8JK zvhMhZd5m-aA%~2MzOOJY57%s#B2QYT2=E+;yR@9{-$5p2JoW}%^#3Q|N&#H8fNS)A z-$WhYy1qDN_rC+KuM5wrFSL3qhVpop6~+_yT-&3ce;?%kCdMTPouZ8m?XIkY9ML&P zoMAjO-|{Z0D>#w9Gfz}N<~Xtqd1yOkzpb$J0}uM@u@ohD=4onu<gc8um`oSunvq1i zKVv#l<}`&mM`Zbw-Fdp*)jp$xF@VZwV}H_=ar>G9Z#(Mfd{R_)KB5JIr;(3aJiq~( z%stpXeR}#PE4|6{JTg@OGKPDz3ovWFMT|u}R?xePSNePTkd|=(JgF$pMfp{1{w?Uw z^mUcoP_gu9$@lJ?r`A=#5cVa`#jP0Er{ww3W|%%4t$^=<?i_E0jvo)>N(;t47dwxA z_zExv^_egVU6kMH;<}B~n+Vs}0T=B-sAHc^uYQGga6En4G2LM1dZ2Yi2imjA5#u2r zblB@TFHMUl(w8H`2MX|;PhVSq{TmpwB<Oi34NabNu@`f559IoP*3?;1{YckWV1}R1 zF~i(L--BQ4Bjye-eV{4-Rc8cBfy-&YZTdrdi_>=30jEpmxwC6W)VUq`3q%iqDZ9-f z*Ga>_Qv2_`zl_@Wl<3F#BU{J!j-f8Q9?E;Hw^tXHtdsSzUdw;NTZ+29BLkJEvL{yF zmn#Z8^}IIP=%|<Q>>cqA<os+=KAI!<lD1V#+fDZJRz1&Em1TB(2>tO%{OE&IQce3> z*1fdplx$J=^ie9&s^vZX5_SO&>P{=P9Pc0KC)P~gdxy)NoG$I`-^6$7#)P-im3gmc z4t+rfDn~PJSoLa(8Fq=jdMDRs@S8VR6!xX)**rU9SniE_wx0J~^K^;*^1e7-#qb_Y z6J?BxOj|Z%COb*{^F&8+nrP&F2O}+8Pyb)ES)F-R;C(R3IxFGj>IcpmJBp;ADcZ@t za63fDFk@k)iw^qcL04{Pd`-5Gv1DqL9hK{@-qH_%_9cmaJ?`CAACR)gb8PdmR5gFN zza{vHyMgDuIzA$@4@G<H?fBR)r^fJ<do;(6t8c~1_l&k*S?(OG+~&!s>`VIU#Mhf* ze}^94K)*rsZI0D$`YEs<*-w;-Mp4Ho-Zxllo)O${#QhFUoo90n{j~R`vhMYI?pl@| zxk|}X{z$Yj7i68WztX4Hie8%4&vrKX@8ACu`l6XC{_ukX3F~9F9^(jcp3zUFD@ELU z4)c(7^ylaw+7{Uk`hKw;+_&-|`VNyOyed_lbwuB<eo?rx7x>jIeW>@>E1P0py^4MD zZ2dM@VYV+tgsZg7j#1i+H|I&buF{fZA601%855;SOYfjx8FhC0Gtf4gE!2K|`UO{M zxoW?^R;c#-YYXJ{6BbO_sWNVujL}9Ig4TWq+DuzrpgA>Y3viV_Mx0{@UQ#hw4(M8k zU&is(Wek=YtGvr8s*UtvaLW1MY$rXXZPRDznzhz=mRNN$)`v3_^YD9GX=lC&_lSy> z)SDdIg5~tp>DTUGRhudbdv%B0cSqWAF%sQ5kgVu}yV#U_6J?&3c`{F~X0DVri>x)_ zF{8xm)$(0!qGFZYYm+U)joJ+>efeg%jcwObmbao_@Q!e;mbsk$?$s78Z<|9{npgU= znWk`gYc`*KGM`gRm3ewZiS?YkoNek69_u+tekb0&A0LF}z&Y;IBi_yCSK6v*>a(P& zq^CCRE|s!U+HQvvvJ7Z=r{-vDNfM1~lPXqPG+=w_HA)AfEXj4XpU5#nzh&rhY>%a= z`A;7;uIoTY*=(J==l!$+onVQ%S)R}3{PY8Za{rd}%kh5Diu)%nM;l{vJja`Hjhf@; zWNhx){OrWs7lW@CXu;pQV|L+Fv_V<1hZeWC?O%0SosSefDBdN0>i4JCs-vAoko+Xt znG_@p(WTI5$Uin{m9#lrFbwa6k>rgS$=-`bir08Ex|4oHr7!l@JFJ-h(zoa-wTFj3 zLGixTi;<2p^hw}2)9~E1S<_j*iL-rU|BM_|v7Ej=8QuBz61n%FEXT6t{TBM_8^%2E z>qepXBxqT@?wn!S+ebH4SE@D8+>oAX%Yi?hm9EWhFWGP5li@vYt-D9iKg068tYqlR zNnYxk2hsnha6MOr`Ea!v9N!=UYn+g)Qp7Uf)gsvD6x^TG_~DePv)knUwrUHHE}=cy zMWP4vLdINY-`<drmgm?x48>30lK$HM`ct=>VUFDpzVqA2j$2Ac*FuMMZ}d7fkv+QF z43B+A%0Nd?F45%v_nS3`*T*#^E!onI=1JY?o%WkcUr)QKlxq%A;Qb)x#Mmk`oDN!B zl1!eR-p-g&XEm|X&cAZA$YvQg8}q%a<GfphSr5j+YnN-6M_#*4_lNB{$@$26Y0t@c znW~*WWRMLhTiNFi{VZAZ^rPM9-Ev*~w4>ODzd+VQpC|>F9>1>Z{W0>*R<A8vF@K^w z*GfNxIDPNfTha2@P!9Kc?*R;yB`61sZWyS{(~6c8hbdRY-Yr~CI(-iJw9(OTt8t!! z<KJi(wcyyVi{*r6VuPrRr%n9M{dN_A<uT-0EBmQk>Qkk~>AS1m5S1%5$4Zv{(q(yG zsCOUmoX`CR@jTD_Ir{1W5BZMk{t_=A)g)e?Tuu8?j&}slHhz9`Qtc^~evm@N1OFZ6 znupCDuL9;Ebh|Xb;Q|aLfQ9gltsbac3wZkQt@VwWuyT*#wsYv$>V`F5#(n_JP1CsM z;9AplPE@)LXB%bAjauPK_6^HP#EYfqk5-P2Hh;Mf{V@dj(J5s`$XSr%b|hQ)IHl_= ze2B;K!3RV(aofgI;;4<Eq`Sn;MBJ&c@aA1%0=^I?_VN7~-*m>py+R(2t0&LaafYsF zSDl>>{b<T=Tia>wIE3-20FD%({CULV2frkB1k$I{C26}q3?2J~<-6-HRd`tfcpc!; zQjWlVn;W!5bGg2u>)l)zr=9Q|=p@&!*Skbx5P7RwMaO_cH1?&4KvlVrG6VF)%5#wC zZY0iY`Ep+h?Y?$Bb(&m@IjSpp<!GLk*UdciRb@We&(&&N<QcKh!^j5||C}$!#7q)p z^gD6jYPXH;BG0CcqX|5lJ^`nIe@&%oO`3C)atzZmt#?dR(r&~va0y$p-guFIU_2iy z-QwFSPJWU1x~tS#xvYn2DW4I3KHKHePwN2sX!V7tJiBJ99%*yAVO6c>mi`6o-&!M< zrx~&~`S~Avywj(~J3Vf^A$Ppjc&DiGw#S;|zBP^GZEogx4?EG9u4&`Fnd5fzwDFGB z!}0F2#=AB)-kU4mWxQ(=#=ALLjW_q;+HGUI;>VjZRWo&kQYBXhQSayn#AepTJfuZl z<f$7|I52kmK;=?AxBkw?iS*qZ`;s%FlJfqQaH814iM}ODj!RF#iS!swY~JWnII-k> zJWiy)8&1ePK0WuabFzAeXS2KE-EiZ*)^TV%n2<7w5xQt3h0a`-ex5Ss;s)aWBMNuQ zfjhatoqYP;Jg{kEKHBi|;`zJl-WaGXg`Vv==;_X3i~!8}Rxz=P`WnaYF!y_au9kv! zUrU|i&{#z&WVu$n>xE9<y#13Gc}}D6a#O|MB#W$)L!<P6F1wp+Lr4=uzBJ@PIprzP z&1;jVY>(N}_Q-t@kSjO_8*8rZ=6<1C^d0#G&;H_ge+=W<j(OAz-H<j+!r#h$b;%+i z+ko-y%}}x4W_-g~Z>+xdFm<R=BYiDnt}K>oBn4jjH*C}k*YfPsH!$9>gCFp0E_t>o z<k#18c{b@xnc|<oUta;8XI*ZQ(=P6JHylP?eVAXZ;B{Wj;iA6g$m%VsgRIqhPWcL6 zdHzq|NAr$*TI?zB^U&cbtDl3u-04zlA3;N{kvxZMiDjGRy3_N?6RV`0v+mY#r|xK9 z4F2c?4v=oxG=%hn<F9aazQom2hFA$5I{N_f9HL*3RsOdOWy6@S{Oi311#<l;ds<#0 zR((AVj;&VS6uF+2=T$O!jyG4WD>0^pcWr_4y{C@*MJxRyab;8*F}vP7ZuHx1`$cA* z7eBQ9ExaS>$K&X)J03ERvCsa@s^`wQda^atUmWYR<7od0k7yiH^XBmnvA@uFh3K=o z2RBd9=I;7H#_qLf_tWm_eRh*o{%uyDfzjvQu}G9HUF29*9F6wZ=F#sPy4F*A@H3cq zovF&#zcWqk)5wEdy}~Nv!$!<@bY2%d$57VW=u6t4xo6|m%c-mS9?=?T7o+{6Y*|+k zb(|xqvAr)pR(*K%Y=MXz#69;NUv0!}`GvT5Xz~nSn-|ij$J@3T^VDjqb4kW-&pZ)f z+u3f;%V>cJUw}@=dCED;HK5ut#bf`f$b7()EYC)k{&}NF%d*y@9%~QQI+nQ<bNU@a zl<^y%y}wg@T;_*<&H2-&OJ7x)-_FZElld{{N9gZr=RXsdpK(vFkYDCKLwjw$cllzu zzN%o5ZFNe!sw-)N^5iRymgE4}d8A+Jqv~u_?x&LNf;`P}<G%M+`gd%JrIkDma`#q@ zk9`Ig^<P<L939z%aXnjLM!4^L?5Ud4vSddZb!N)yvdrp)GB>IiV|JON(1U1WaAn=` zz)&i5HSo_|&6yTIc5KgM&WV-VfX{?io_~n>^qtGq$4(f|5X)j;eD1Q`Yviq#@{(D} z*iU`vn>QgVj6t3r$1kd<k7I5(dcpgfS``m&f{aj2doj;4(bC6Hi0QJyngrRvsX4pb zG_jdypNxaYR3Xo!lhH<L<06g$W~qmPZ&DBQX$6u`mVr+)7Q={Kr_T324_)PF-0PCi zr|w(@PrDwQ<9}iGGvj&kIoI+VboZ;6T)Ec1yc=~z+nAO%2hKavD3|j4l0Kqqbu~X5 z;>w?++qCLm-h+={*{@?TPxR0)RA^?{`Owt5!{dqT4$Af~*Z5X`$g*+JU-g4=@X$U& zedMjY+5JLnf2v{34d}6wpX6EXS{PRjeXoQeY2)Lhjr3{XiZLgAHf-^Fw3N{;_||}y zjnZ$*FiNGrRE~&nPMp9z8UY@^D9_Oqxfe85Z&Zub`+d#s&$#^$)Atv6Kb5cSWzb6> z=NQr+z7XYwLe*UVmE&4lyqdPDRlP2S6SZ0m&pKF1|DC#gMJKuDcMI-2bum6XNgs(^ zZw;O$Ud8GEVlp~o{>rl)kp3e2xeN1aHvPDcx;pUqdCL#~DXVSq=i?@>N78p98tv^G zjUMmf8Zv~=+<3nvuEFtqxly$7IW5K~?$VUsHEr7KLF<vOk})91(9ShN9IkC0t0>7+ z`}T{I#E~u0=srzT>3F_)t#y{zr!{r1T;dtNcKuuDsq-9JS74qzSLn23SxvZBI9Br9 z*k<<c+tHl^B6Ah!&B_71r+vN(_!G3w)=}$p&t|`4?X$kbcmp%`6TfK96-}PoLHXxP zjAJQeY>J*=p#DO@dp+)-0IW|iW~EE4<K9_EG}_2DUE<!)ejDAnS?Bqg{`%j~H6z!h zia?n$P<gj5B5xWQp&`wTY+EE6T)%9+|7B6Q^6w!#_Cto`y7pa2!#?bNL3E7j?&TM< zyNY<vGj+HQ(fbdI&RvT<Wyr(ykTXMsjW!gn1+=7y#y3Ihx@xRg`d6#{NnJ0Ab@W;9 zdPG<6KWn}J3vHd;uYEc8zUx24x;i^{4EGIcN+$a%>g-0{jI#%t7m1I-IjqhM>>!W7 z3$pz_z)tvnr>S@pZY@K`BfuE-upfU7dU6-~Nyhv{nVYQkIM5cB!~CrO4(rSym-E%4 zwR`jC|FPP|xLS-E?bh<zbzG0@u6D}%yt=ft547@J4RvO5?rV$l<~yYhW=2+N1>SVP zn`^=QYx;t5JsJ0JGghf=Ypy&4<qe_Qx);}<YlW+5o8GL8$ZYoKR-T6?)V{S6<x5b% zO!6SwHVeG9mS4~)WP*PevH9~Q&>Y}ewmb(1<?qxSE8k!F&&n7H?=x*S;{*OF=GJ*5 zf9;j*@QL}zJ4sh(m#3%GS?+fkHT>Hh&VgM#PwP>hPy3Lzo97mi?(TW(CK;D-1>+0K zGsTsTPk%ec)sT8U{T_HOC%!pA6Ph(i2SW=Bm46z`VEV4h$A_4QcHV)@(SGu@2gLL} z&xy2>JV^ZH-Op=!+ls$)KDMS2`XXdx;8}mpud5?DI?u_R9v9(t=zwZHAwQ&i;bU<U z68*mWtoRF3PyR_Ph67_SG)zYK%~sZ54M%qp-dWdCl}vLwZO|QHynx#tHjj0kdH9&K zwSB)^INLd=89Sh9pXlJZ-;Ucr?`~G}YmcVljyq24>$nHZh37+<yJldUJWFgF%JF4E zj&1erpKbrg4XN_%$9<BXk2nHyo$+zCrj?^fe+C&N=$iO+N33*y5n!6x&JQSxOE0W) zF>*7`7tV}NXO$a&4zcPdp1T@5XW912p>HA2hqHNMFv>pmAEmC;0Ntxs&l%q;d4eu^ z!tHNFcfOfpM!K9Twp4S9I6|7$Zuw31>S^PBv}<Uzp`~{_KWkRjMGIE>^fVcNvrTs% zHj(a1^Dh3ZWxIV(0Y=QJeUL@uo@CZH%(z(iZLs(?&!1jw@#OEvwdX$E$M2~cN4v++ z?o*H<Zv$`dge*ikuB&yt!UrDD7`Z&>jAw}wC#K$8=Zumj0FREW!S^*h15bm_@lJFf z%h@aGu_j|K375bAB-c9t&o=;rP2<+#o-)F(CEvE`#uUHy+PwFiib>`@`+9WeDEhk% zeAY4OmHk<z<+gGEB4b`~ZBfPSX}jO6<+(Wa#Q!$SmSx8ie7F8il%oKHmpJgKnq&2^ z*?u^2cu!xT#XO&uwB*c9+%x^GV=&qFm6SBhqja}vXHXYdbAkOpKe*{}C1$fryl9`9 zdAeXrN?-)?@WriqVBSOKG14aL*Ao~^`p@@+9(99Wx2f1GFMB{sr2j{TXvA;dalLR{ zIOTf9E6y!f2MC)BWsWV?g6+6}uq7$*vs=vlXCK%!!SZBm6Z%9#4xx>xeDkIWU2LhZ zwa%&@w)P8C9)8{s` B&3eFLt-HDZOp|)9Pwut+aNvZM$CnEl&bWtsKN5StK3DC@ zm*oI1hkfpILR}nF+Cz>3|3>HJcGI`dIoUfzm}yHrg?F`+O+yWn&LMkGR~LC%RPF_p z<*Wd_V@s=p?30#>XrtYCvRp;m<v!1m9HmDO+h=)eqW>{{W{jJ<x%0YRn(Jk+1;<?J zccRLqZ!xc}ar=^(o<58Yj8U4F_VQ9IpW;_nKAS#qKLz_xf38YiwZSS$*H&kWfZu@Z zrf@B^LbKWv$E)a9um|;%Ke0bSUkc;*RnR};YAYU5Jl@Otif>f)Ro@t3U7Tm@th%^Q zA+avIj>Nqc?`EH-E(016lJ#x5(cZi6Rk(Cx;5=x<Y7cl4%H(<36UyHp^p24lx*o7Z zkiJrnhh?6GW%R>l<Ufu1q2C%sp*M^|@9RbZ_-wwHv8mPhhPg6!uE(f)jda$I-##v+ zZU>x5k#jjdubq$hp?r6*Y_pwp{6?())IOrd5AC8Zbm_9{)0|nx&z3D@>}^S7QsVX& zUpbD1tgrebs=k(wNdC?G{A}mtskkw5_2pXi<#-u$AjPh)C1u*)>i9Zm)VIZ|Z*QzV z;9mW|{8#ELez*Fj%b%)GRb5=?Qhoc;0P7t<z28&o-l6ho^-jh7k~U|?KuERgu1>M` zn5%Dg{WIf$O!xbxpPK6Lk50$m76pq5zWk^K%N?`80@=@N<Kr}VMv`rKyf$5$JwC(x zoL?ge@M%?3^UJT#oL`@~{KubPIrjV-{A0|oS@5B{O1AOb)EHDLd_emaTX<MD3m!6N zHsK>K+GnpFU7+HPB#wU&Jld-{$*W)Ce$CqIq`+-S{-aHrW1O*n-hA|Lb}`n`+AoU< z+Aq0h)wXHO2Dj7^mH*S}9PmT(#d7fIP2m5{Uoj^@ockqz=la!U#dABix+m<o9ka!N zo{p!=rbs*H0s8+!?*GGF(L=va2%4u~!0-725gw8;U>)sHJR18_WPHR4=-&HiR}Ib; zkrFF*tD`(a#uH{5fi%BfpnTSvRqV4Y`c~Wdc}_HBv}bFJW9NO_`Mx(9-N}3RFIP<T z=a^xhE&Cso!2sXyreZH$=^V`2&xQWnNOWf#W7}B!OiPnQf2kdF7H~5*aY?esrXMM7 zfK|yw_wxJ@r~b*6K5JhA&p=~-DR0_&leGq(cW>EX8TU-KnQOjnYCnOBKdo7Dd*{d) zSlLcI`;q6?5w)*=MqCs*KDOVT)fTt1`F>@tvYq9qn9Zk4G=KPua~$2zbMKO#KfWi4 z>nLWV4`UPJ-e%ynGp?<*+RV062RI}?xhfuB#uVV$lp(Y~h_>{htfx1Kz|){3eIF2! z;8K+TLEJ+I$Jj>t3Pj|oM@8UCLksME3N#*bbvJl1^s55el^>CDdVV}(-0ZbCY4^3` zjL`PGLB$!N9V!~tOKG>6E!IdsV~woF_!Owv(xdauuqUgl$lgzz7;nBc-yS>F2aG+- zJ{UI8Z`Yf_TrF)aZDNf3)0r*8*Wvxgpkwmf39h4jf1c>Uw|1_HwAG71-DFc&skUHw z-K3+d&yqKV<(KQT>T)=BxhHfgJ@t?2>ECr<t2}Skipj|K+GmXO+~H>G8FoF_rO9&z zB#i~kw=R%2*C}1d-iIE)zm;^Ncb2%VQ)O~qQ(m{9=cUNF_08yyA6&w`LYvY`{Mo7> z(p>TF>U>0SUrU0XlW4EqZ`0{#9b43XGU|YGt?KX0&3*Lo_#ozPvgpqxeu}@U&&v{l zUYFUi<Da$_kteUS<^<Op`d=#RCcVlZ+))IgUB)@W^=p=2P@F8!v7hJkAN7NVl731* za))@1Hj<!jRt7b(a+@ezHEPjR#y9j`zGa8wLEi*$XS=s}-tKK%n<gOtb52xpy-CJG z#18_?x=&0-%ju^zo2~4<__EaVELi95H6+ci0L-M(AA-E@0^A?Y^w)obKFWY;^a0<* zA;7ev*tHw5MZ8WCXi64mXfOAjpbg^xVej4JqPng<@O|bCaApQjV0btv16mUpW6~%f zG;KI&(t@N9k-VCR7;lq7lHTGYkt7Dt+ZLq{C)$$WZPC~VOp?}AOq`~vXxbD*l14Bl zO?oS6jDx6=D9UJXe(SsUIn2Ysr1$=Q|NZ!U_{_{c`|QWsd#}Cr+G~B+q*>0x!cXBb z`h;E+_Z;BKm6EVSS0!<;kV&7}e$i*hB(UAGQ(5q>RJ3$mx4#9LkCR#A$`t0q8fqA; z&o=8rocrS#x0M%ZQ)VF^9=<<H`H=^0;ySP>p=ZpleR#w+i3u$Ccvgdc_Kyf$t8wig zg63-<wMmT^*nnu?oAF#Hl=mH4AHSl1_<bPHJ@EmbuE2Z@@CUTXO7zDZsa(2Z1ostN z=$*Qyxg*Ot9?Qg`c|m*YmGG?W_3Q;Fd`}n~f<0T3R1baU2IxC!A-@eB=9u1-h3Gvu zK=1kbses<|P+|nVCkxeke)*!m`AT|EeQ)fGk=ki*>&RrxH%+srLjK?R0vIo${dr}K zC!7`bB<`~&*71%>*a_0vI&X)GV|mt=aXq)pbvV#h4$$7<c%`*Go7;YyIqnqXBYE)@ zmnPS7|L%Lz*(Q^)S+2=^q22~rH~SZ=09Qb$zpoK^;=(=+SfaJME(bBK!*w|`=^ff< z3W2q7eY%Jng8HYKNPaQ0njiCf4Y|6EV}5d6`=O&Tt+o%Te%;rM`nw75bOO7J-rK!5 zd+-S2bVqj<LN}I4Y4G2L-YNKf(2-G@dO1g^oGlmpdGB8EHwW7;0rMRFw?8jy_MDgN zpWsWlHAFx5CrxK5xsOa^wY2vPVGMxljxoVnUnsCtxo;+Xi$F6yUV!&8^$)uZ${?_C zc3cSP27&7U`F92%Gou^vno|2XZWp)LM}MF@#yakwrq&)Ny80&w9L|S`z6%8wtj9i) z)jSl<D*pQdbf>BZwg|u~RE%sV_h%TDYxWs9j^5C(Z0ZHH7h|vc#aH(Fn|~ZcCzU?E zM>Kt1Qn<eEFCp|=L2X!R#Qb1|@FNxRU6=>^Bk&(#b8?L23LOIy;{=Q&)cxNUZl@*e zML+fD>HPr>`-DC{#Q)Lmm1_1}@Q>S%YpEZ1T?ptpQ!WTy=bQduJi^F$c?of2SaUwd z&8m;@rI5pd_R>m{p=QQK!qFSwKHy@kunz#nN9BB)*CY$RHIZb3`LJtXZ!53N^8sgr ziFL_wM|9i`WuodSp>^<O%3n91`5?o^eMbG^{rZ6F*Zq;9H_MWMGpYK1q2U7hV*kDJ z{uUdcQzp>~_zKFW0!u{sG=L@2#rU~tyCMl35taJ0fyM)M{xhu3(Z^mE@+UA_XnuR` zjN5#8r_tJ>H2U-b3k&{Q1KW%_oNoP7c$^0>$uGcY9=KY>XSHNA&k<k)T*q)fu-#Og z>H@Dge1zoHjRFIPWPjiB37r1CePuMS!E>^27U@;cE!Il4c+d2GnSa{%OTO>XJ_cL^ zU>fxA5M^!Um^GL0hnl?D0sKYq*98}ZpHC>Ri6(bbnSI*~?QNRfRXgXg)Q5EVgNS~i z|K8uqIVPqGT{rcsND}j;Pd2#=fe}M|gB7U0{0oAIu$iiFw*LKk)%QjHd!Fi>sehkN z^IiX*qx!DazkfybeL??TO!G$n-e2s?pzj>3?9~9S&T`NO=Yk{Jxq#BX<PTu#gzLd@ z-mj-MfIA?p3DZO_Kl1f}^v_xokC42%k=Dd=j!By2&WniOdYK+#L%1CX$pPE9te?w$ zcW|D#{-V%D0Phn%WP4<8XVe4xR^)@-`Aru&7Hh6lTi-+bVb7Kk@eZCJpfdvW<u_au z_gKBOrz4gI_SyW4u&rQuS~)$l;O|T6=efVJ)qSIO_w^dR!`qr=2+_G6;C;2a!{v&` z^Wt7In7-8h?e$u}K*x(0gf3IRQ&8#5g+A45eVRaR*+R0q-lu92SHz9yy;`55wLbll z+Ly@pERvhFK56CjjA~d#=d~E7Caq5{dS{0=R>9+R=lRR=h(FIb{q4eMkJI}XLdPjT z!Z_`}Alg?IG)`|^2py-c3!&q5;F5Uf?s3K`(ijEX0V%k%%CfocrE)R9**XL7mlh|2 z`_;WnbgS3So50h={bD%2R4~8U0URZbK3FG9F2GKU<d5}+u~=kd@^%QHlHB^bt1<wy zB52+9mwHTX^E^fHv&4C2g1|bwa@>2ZynUZt-doBz<z3+(PT<o>?*1~^6)`vbl6RBL z3fT#mNVtnbe5Hev*}@BQjH6>qt8MT9kX(K(OYoB{>7{zhM*=cJ+=!47UVsf6aL;@z zdhMh3A>fsGH>;jwvd!U_nNMI5Sh=nF5joB6wFvATVTYOQ{=L92&qaHFNo8$~6?)aX z9Bfl&66@&7U`e#^lsl@@7nT)E2^Pi*?Xj%zNz}_mUPR1Z*xsTIILme!Sh;NqODeUe zFU+695=QFkdul0tQO+%&q({@4f%@?n<%dpaA3d|bseV$B(AokWX?C<I>k(iio0*Gb zv^@A7b6j=e;mT^Ue<Q|uwk*mpy{SG~8qGQkC|m05f$rrY9^(gjrS&uDxpVs77SmVQ z!Wny5!czKNbd=RpaUYBni<y3xOk@jSyKDFgOF|#AKE0_Iw!6=a`t$FTN9G(MdV*FH z^|;1#KES>G$@Kd22dOQMuz{Kc8>l!wKOP&l7hvAkNvV7ewNiau$5{eoiAIvmOhlh5 zN%&|uhYkT-B*8gkFF@Ph<g%fN1&nd{?c4t5<#ThJymVfAK8nZJtSPBZUs#>^bc>0` z1Lc7B57PM^bHF5}bt|&c4UB5X*2WfmB9?O73yn5s6f0b`b;8hQdS_6Mbz2boWOaQ{ zN!-2`*mRlOO`8>Jn~CVOj`Gw=v4iN(B9}CTyz62`-r#(wAHEOBdy{GY1q;Ve9zS16 z(C<2G5BS7*GP}^(kAJ5b$?yNH9OY;<vjo^Hn5n)>NgZ7z83%{CJSfq5O?J<_{=Zsq zcCC+Q30QCEX}!rdwh4afNAFTS9}?e&zv3EtZr{mj22)#GFgC~EZEa~YAa1CoyF{`y z0gsSLNljY~>sq#@1=bPlACApX#oD8CK9o}(;y%La5H>kU9N#*U-?`u;;eOQmIobd` zgBs`FR-0)$tu5-0{nea7><zF}B>v$TmZLZiq4RIWSI-Cdg>+u<3vP=Q!56t-j^StT zU;oqJoKN$c){h5$2PTX|vNoaKhqz6vh->Q%i)(9$0#2vdt<vX{G-vVtAnhlA#GKtJ z^u@rvXyVx8A|8@6ipnAx)rnZL+S+zd`Aes;f-ZyFW7;#j$sWUAm`$`^Z%87Vr!_&Z zHT4DACCQB~pyTbs{$^m*R1&{<1ooJU;353JK#xl*?jJmHB<nxKM)FU}ab=H26aRHd zHP!Gfi)LwUtFt$oMk{-r=FY+ytD}-0TwP|N`ChI_v6dh2G^IPuls|{@{B6dd{PD<d z;Q5i)8P5tEO|h2eqm(jdBJdI7EY3t$SY#1+84BwxwC@pmulrzMWMr<d61~Q=Gr{`U zI1UC{{JR2=!2bQg1rOYR|NWu%XaU^|#<id31@0ArA>2&!V+M`0n`n|oeC82}<(3d_ z>{3cKe8xk@evhN6gy#67s@Vl;#G~|QXur<;!81W$@TO~Ij&Yf%(;w$*jDad_F3X!4 zx8KNJLGN%qcLeOcY$>T5&oQU^xQ{)_UVryDuhMW|R_x7gI%E(rGsnZd6Z6sPrZw(5 z^>=|Kuo3ZMg67$JF;6^=hLL=)tdt=ZkXgFz(F4yk+E(zpnaFLc+?(4Z%1?5?OJ%Ql zLfxqI>l^-l<*~&23%BXJT(2#7nHPRF#J^y#L+hH~NrQjkj^hZ)3Pr0~yYOjDcD%>e ze~e>)n#RYL1o#+yqA+IAS71zM(|SHcyepN)yvtzf-eVAJX<4e^VZhayEcRU7=`1Kp zVAp?P>#dKzE+Jl$sd_zhwkd)hb%*T*N9WL)i~6S5CH$|f?z>4A<h+ocUp2-HCpko{ z;XuB>ToU@j@$}xhjFy9#<q6Dn9JnrYt^&^AGmPs=3+ttTjEUIFZ9*qh2>UYoWIA0! zwnV%*Dg*M&%v$@xZ&2U<llaL%19LrVif_86wt571%ExJMbcV!AiS0&x-X9X*rS&|6 z@_HLE{<7OZ@8q8i_&^>SXRS^<D9#J#7KP$_K_>xUyW77EIV)wogXER6>F>5IC%I%T zVkt}|8F5al4SM(!li8+vndQMI$Vqu2`#31?EtI!4OUN{knc+tPd|v2|m8^GL5R2I% zS=KKiSqt~O{=LGtv@5Y}z3CNEMwu3)ua4xj!I)NCrNk0(&rau89)oH&Y`CdjFB^I3 z7`M+eavrdpiS&|B{V(ZvQRfzg->-(=8$%X8soPP~7!DF0hvjI*0NVNVa6r#kF)Z|q z#MiAAet*Xd`Zv=5ZlhGQ1^mY<Ex;WD_E|bxS745PO-`Hh9Ifw0O&*3FStIp(u|^x% zdA&h$tBGVqVDcipUXw8!N0;{=m$MyZ)b~osKC5xGu2&+ud`N9OLh}^*^LuDcBOa4? z;!VA=l*dc*f}cJ1NlHSiZTEjkH4j4eG*Y{2ZOhQc-BxOA41K0aHP9`3XTZ)O)^U#H zaOfG20NYsOaj<phljGc{KJ_<$iSq8=B-M0A(YsFx9G|gw<p}S_h<8uYT7q773-JwL zO@dDVAM!Be<@ybJuPc@N8B-Z44$dPeo%4sQ1%JS~G?RF~K}xnX5`SnQ{!pC~kZ<7Q zew5l`#F}5LuX&-5Uqtm=K4(8SjPf|YuJAkg;CKSbLG$75v;6#;h<VD=#GPXBxiWjA z;8!^lnWvQY`IgDR1Hk<{E6l+st$hdaZCXn{&6aut?&RBv2jsjk&u5m@KNLykK|PK} zxLyptJ4OHSH^X-a{{NUyH)y}Na(z~kdq2&O0&D2q>E-roq4&xkX?Fe2XqJn-S7~MP zJr)?OTc@~iwnqJS?HTaI__IAzTyEGyBxv{V3Cy!pzi)l2z8rq+TV-+IT=uQ{a_z3w z5v(5;>l$bFH9hzE==`q5c`6^~_#7PDSONavGUlQ-a_npPIsj{_YN{49JsNS;*OVi_ zFDRDbc=yuiFV=s^{qS@XzaIu2vqrT0;cty|KTP%FjyTl*`_DWsF5fHOL_FLvOjrlE z!=A=mCy9Pe$n}!3rVH397TpdQu{*71*l!O~+R`VKB*Z4=alQXBuxcO8C)#%k=TX1T z#IQoYMV#NL{6gFf_$dv#Pm+N=;6uchYQGaldob6#avb4u$YJ|Tfw_Ts>|LnVGOE|R zR+AZG!p=aiGS{Uyuy-I%tXLm*CJo*vbS``?;CElMn6tt9!*IM$4S)GEEXnt1T?J!F zmV*}>)Y|c|B;U~TLpQa5MBE*I9xTZ%0W8TvU`a-f)n(Q0MN%DeqXL+cC1F1CC(rns z<IjqFqpR8Yn37wyw&MK$n{nD22~$!H!j#n88QwlyQ~+DDl-tu7fUSNRwq!U4=x6wm zyK$}?p)wDi3GhDG8L=1EV7!Tc;+~n#NIrj^p*<Ns-Xu4c$gE=_u&-mp-Rzlp=(pk? z{u<5KGFJGf$?)A%ec-F$+kses3Sz@;isHIa;4mw0_)T_c{_`u0EU)V)>WFjHzw^xP zbKBeLES5bwZ=;oXY4#NO)h4-3qw{*}q~yVqYuB|*0!B9dKQFP4rQcUa#yc}A(xj#z zQ5loyzZG#KF8M1Ei?Cmw#O1=Lj`*8Fj~BK0dYM>nR6jo7kGD1f*Bh}2&dWA8a27wH zcCCRd!cd<ftUg0Gjf<;PPVM&6x;R38%%b{%-P3UfXJeL!Gr}X)xg(pV0>e6aFjY!z zY8drbq{x9-esO2frX+WpAtex7g7OZpUEh)_{FFL6f1r-Yl<z#9H~jPrv3Gg=zcXAP z>$sBNZY0@pQ?ITkj~xG0#CkxVQ{29w*x#Z3PvP<YymGGFZ%_tF2CmR$=16k4*I;c* z<L9q5jvfB9PlUbcS?ZsVg(lHnp2l^E|ABr*vph+*b{`>n!uMzky?-yIXHt6AGip2Z zso1kB4gBtHC*l>7+|^U}3GUX!e)A&bhwjyc`&g2%tDa%)@M)vHr`t;N&BRVW*-C3% zK@74Bb-g%0AT9`S#Z}?s((`Lh<7D?X`b4}+q;278Nshl_ZN^%gDyOn`Q*25T*Pjy~ zcnbB>d6oE#4{_{FSyXp4Ut{H`$C2l+>&2Pn<&Ze+KCELJkM-Tydo23}rn&G1+cAmV z!SPyXZYr;^1>7HTr|_eyx~i*XA7gXG+9TQ$P3*J{VLg~Af6;*OCq^7t+$YictvG_d zkF8&;8*#IqgAO&Q>^7X!sBEeuKSz^AOx&;B+U>84p)p}K{yL={ao>qQ_&6@#5<{Uc zrm<z(dvuPCiGaViMBAt2$oPAh_sBDbzZag51>x_>k?{8<e&&B=fZOKzqQrToMjwN| zq{fyK?iU>+eE-%OT)GX+2+<GvBIq!}>2tm2KXWhD-F21Po+ByUb7)TSKGzxBp@;X^ zMYa29GoOE(RCwgwfIUM<|Hsi)>ivI}<`VLZ^*=mcaQ~Ac^k1g_&z4;iVBb9h_lb1= zOZr(0*Bf~>9g?xL(201U9-&uLl+Hrf2%^toU0U74!Uw=HoAz+;HXV~N+5JB>w>bT> z1pWGnepuriAL6_}@Aau_yNP)745E$SVBvF(_{V9v|BEg)F12Z~l-i9oH_aw&rnqiC zsQka`<@f7$_o8g?lDQ%ejp?605$loGi0f~!`<s2!z<=h^I-1)q<Q%~ZC50OqvfLni z>~ogOWg6(U;E#uWzXWHLAX%nBmt_o^EF*>H8yyPhNTDC)@5bY9o@820Ryp;VvPz00 zRc4!jQ;;KMl@P!Ey;R4MAt9?IYqq@Lhg}!_6+*^P#*r~n9FiO&W4sL+<9Gxa<6M}% zmM#ZBK=k#mHSHH;B5bBXvx>*n-e)o)CrB<GFC@I(n|PZMn~U4q_ncX1;Jo6@Lb)9= z68zJo!b$J`@A!o8lm8>1;CJ<s>oHo_90z}`$(8$hsGJ<Gcfh`Qj`qbDHJgyR#!%at z;>FyKZ$q+_;o4&0*zO&4uIrdebow7EyI06!R{G6jL8_GY(2z)nPhR$rI4|kt-SQoy z>si`Qny8!;RL*+I=xUt4r_DLNp{*71_25s7`9SG)s~g%7k7^I4-7zG5{H#M`F(G*@ zqw!+j=y@_F9%t}$u<c5})+YEBtcw=qIB$l1IrFX4VkDK(?<&o1s4D1;)d^j%QQT7m zpU>?Z;yJ#seM>yY!LuKT=lUdmr@SY_Wq&We27KBi{7yEoh74D<{=GQECF|db&Vh6G zn7-Q4C+w_x)*SRV)7gAO(bF*=;7|c?3;N`2`pwruLkvF`(|YCjr6JE2$AsL&^L&Zy z`mI4_K;BEDIXj-dR*w}O>D&(9v++KG6^r?S`S7QGJg(<y3(?<6bE$PM8);3Hd^z;I zbuSw+OG(|WDa=z+wY-36y}+5m3NViA?l-!eG*>K=soP9>omEwc*S-MQ8E!vpg7<{s zsnGhi2wCGl_hEfc#yQtr8LfJ<X?+1VrPB;dBlyT`d|tDQW@eVFaC;<@-9=mjeiq(F z^Ugy2&wH0zIJk`!4&23DIE$a4e2yr!5PTl_pl@v|&DP#CS69({*)!Dw?<IfUcc^~o z;y&CK>yoJ-u(i+9<Yr4W+w=gQQ~Kh>V&BniMwee^9wYsRZIU5V<ZG~n=Tk!SsUqJa zl<z-@Zor5;MfD*bL>%QgM&*7)@9dkdt{Nb@r)ussO=VRN6l5<}IaYP{VpfQGIlvU{ z+5OtHbpDKEFjARiRo8KRImC*1p2p(Gqy9XcJ8-T6oluwa`_cmYcYt?6bAL5kuyk&A z(|1YsDqRdbp~<sK7K<2>&L{)VmmQQ(<Vl}ZCCLfMcP+h#y5qTSCAKO4J4W1>Cj3aN z|M^e-c{I+hi(SOyEQqBXNxvEt>ve*mJ%2J=$Zcwg?=2MeT#o5};TMf_okHv06s3Ad zrmog)IMSe7yScvSgR?^3KSO)^F!3+EW4M{-Ila?Da}M{IyA8~P^URalIk7dGT@P&4 z?9+jBtCh!pNpkN#9XR_0^OD=(8*@ao$$WEU9!K;AhPaQ>^L6~39pG>6R4$K|3wzZh z;fI@iGxH53X}qw%)Z?Hv4L#T%+HZs7sI_Ufd5EJHZWmTV^3!b>{IKy9Hi%SKsZa8~ z8Dd`>iuth4J<p@p30o29e;enESn?acs`{pIf7$x-Um4gY{DzGJ;-mm09&uKjmqg#4 zmjZqFiul2tr}LPenx3(m`n`kR-}qJLtGcA|?n?pQje52V9JevsrC=RI&M7^9(wN=V zhQ?+0!d4pl@rESg%{r}}W*+PIbdEH|#oMwc&E>p`wLf{z-+Wl;MH83I6>A;(ag0af zvW&uTTX(&#l5^aCXoEz1!SjA$UnrjcDR7=j7yNBb7uOMU+nI+o%rI*rkF9$;r8tXY zR#>9zdv0B=_O?A?*=(wMcvq2Rtyaw%Zbh<&TS0uW)u2?XCXFu^3%*!?BU=c*Sg+7o zS<3@kbKuL@5$~?E(dU;~E$u&^I^yBLz6U*9sV(1Qz!(eSu`<7}<hE2>qFC-qzCR?7 z?GL%s7q6^(R%m78?m{w>tdy=64x|%5Ho(71Ekrz!84|~duP))(r<Ss%)E5i=x6NN# zPz{?^DPvaKd<XW4gle4ci3evB55_q!hv%y*C>oV(;6u?iKc`>`(E$5H0<{}?Dye?` zJct+q`$Rmm)5_Cd^C&S~KbZ(T&PRA3Qpfrrckw;$?HDP`1zz|QN_!1BA~gPOv!XW- z#wkrpsqIUl*QLIoPqg-`+o&I3r*`d*GS<w6d^rCh-u89i&648q&YxL;{Lf>|DE~e> z`!1zE9VfmE9{3jZIi9{_ZmoER<$%ur8pZu$eGmHb;4J3qrf2bTeb1YT)D}nlX3z=z zyS>)AYTb0U3UqR5_I+`}7Oouk55M`FzxjMR>@f86htPqv{opCSm%^5!@%v8^KU2!= z(?!hofeMl#rgzzBZO^f{(K(FPFzCZ=*n3;}dx+_f{my3oy$W;cp!klyDcU|=N#FH7 z8-9aXY)WDY_h;4R7yCiv<#k8VnV#A-@I&Y=#oP#Q*KulB3AL-yAlfw{s6Bl_?I{gv zPY&joE;m3v(%XjitV-iPKIj|t1>U3|!ltO^qog0SRFTZ|HR3OR;`7I3#m(E@A82=^ zxb-}bq>RaC+=n@ubr3JC9i+7anPWh<xRtN4B(A@j*||#SuPhvw5BE3KQRXJ6q}F!P ze0NI8-6j+933>+HoA7g*ZfB3N{vGj}6go>CG=L|jxTl^Gc9p;+?jZh)`!M}|*!&9| zoxuCQ^z(aO!~@{?f>y3uNOCJ5`<wOO(Ess1W+~eFH`yI*TN&Bj=gM(heX``Bj62Iu z1@={}PdDuKcs#=t>O+eAQYPEPbs#buGA7-2p)!e8Y^F86qFMFXVmb?H!k_j&qxy)) zY4=rD_iwe>dn=lmZ<CSj{2Ar>2Yhi`xDQRo+C%>4%mmhfGW2(gW%2G)LGR*R`^O0^ z7kWM13#>ayv}zW5y-sR3-mjQI<J`i}9y|4Xb(C*Qi>Cjhe0Z+Ji~0`4asM4(s+`gd z>}Wc}cL>`>g~todPUG>y^0=*E)%k*=VOH~nN$R7Rw{1UBM-T(2&0y_L9-X%lXAXQH zp3vC6QXY8;<z~yQqyEvABTrGikJ7%^NZ(1;=vWt@+(dlX2fsXESn=ODH~IZL1M!Nj zZevs+7V!_M3@eqFqG62u{L#D-;Nsb0SnjZ#+`Sd})+~8&S`6%9K7F!?<d?nCBK|ST z8ZrjTT0v!<jiSC&y(lYXHERcrJw}$R>v@B9ySY+IcfDD}s+@6B$ZcATN1RKo(8o5I z#a?7NLE~Zs%~HBeQd$$%(;}JGEE=*G^vmm8kS9@KW#zqiGT>Vy<hW$_*QsqL?n9dF zo{v6jI-qAyUM};^J*CTh<NM-8(yhMtrmpV}#YMmwr&o)?8ID`vG;sgup5r3cX-CPA z)e-p2cX7-?nrrm^!xLh?R~T6b^vwHcKK&eb8QkW>6k_vnE1ku*L~HRs>AlXSvq!l8 z{}jG2AIYS5@1rudQl1wFsh>0tt7y)(kNSE0WYKr`!EyA*t<=Y^LD5g<j~xFE`>~bI z&d{@AU8Y3U_c)(Wd)b1N%^ct6Y(ses@gDe@w)K>9e|M5qYH$zS-edA?yCnP#jhgS} zM8>foFN=4^_kF4d`YSWlk(p)QJfC=2=^lei#KN$L;++NY^PkhZy;OIvBxEwQ7yK_d zOLnDFS=6Ql?UxR9RhFl21|RIAytt#^N9~*K$C*mIBa6Tn$8A@CXuAUTQi*QFs4`uz z`Wy+Wugs)+2HD6Q$n(Xg_!)!SU|}CsHG7cIbJXQ{Zjy<{OCkC4gzzg^PV*0I5@$h0 zUDLC|pfmwDp`Li+%Dv2WyM!}T{gW^5W&8Vt4w{cs42{#SHTDt6tGj<-9BC`RyI{9r z@~W4nPA+(97X8niT%aUONo*^hT+p@G(Ns!fNORI*_p!nvl3^jgwNaUN$vT)NV)pbb zJt=$^#*Ytv`T7C=TyVRGISvSyiMOZFm~~wedlvjdcTSaDyD86N?f&W;CxxtjIetPg z-Tth{{Bi6yt2Ilg>|YV>bgb1yCoo?H-NV}qUIJg+yE(>Hea~(>W6>US8vE8j`PV$V z>6|))%1fCS=jwWN`3SYS12%+D0;}xN*}%2fxk(ab)c6JO!9BB=-Ze>5!a#Wp)`$x} zVTdzg5_;9sk#J=*vn-p-h$dA*Yar76(6M697)RzbYJTMKA-~TkaL{pX%BS*^sr*zb zzl-*mG{iBPnzq@Itojy3u@@woJFXA>&2}T52Mog2sxF#w8z;n7#d#!>&o!4b7As>I zGkkqf`IzG<KR20iY|Wd3=s)KK?v{l7Fy6fRTy*Ilk1l^6^Q%5iGIlc6Lkot-@kD$? zjAxy}P_v%;X{B-e`TNU9@@2L&3w|T-(-;CLi}I8#5Mx%lAjY%ue%nIWEp4JaZA4Qu zwaG;9&Y(7NzfHtLq|dXL_}!l)(%izFf0yR`Sz41F6M)f>%JD855A(Z#{CK{nS%nO{ zC!hnzbCLn_$DZ{Ep6w)lvWeCRaJm|?p8_*EZeL6Cq$CU484GM)YNv(h2Yl?3+6PCf zvf?&#{Ufzm{~bsCVkV6huo%I^ft~Ua*E3wsZ!zB%MupC`y+Ly=Jnlj&kGqh{F|OCi zEFYNgh%*b!^Rw^&-{u_lGLFAO^$=fs67y~!)#cFU-ERg1^X}=vuz44O-;epfYZ%c# z(%#t=R1Wl0nTA0BaZY(g5*X3r%~?Hm4xLx>E2;m`xv$j9UL90+0pE{B405!I&%<|U zzhaGC{)c^Yw$x}VdB^05WXH8pA(;)>qtbL&Wjx8x@xmVvdySvUu1ut~#6a2wq@_?= zN+4|*X*No;1=3C<ErZfB0%?Otn@VX@18E;2?J7#UDv;KXw0ug-52XDQX<wqWF9p)x zMcR#&c4Hu|2WfLDZEhg#O{9I5(!Lr<gB%0D;KuoZv{wf;ztM5<#5lcVPOt5pUL;FF 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%0AaCsRM0n%G4C>o~+y6iY`6lJ~AT*TDg%oa@00T~D z7GC~dy4-Xk@b?4oD_g>b=2sqldI)}H?=J{#{KC_eUzvgK0q|=BP(6Kv{0ip&_xTlq z!;t)nlm`#aCV+B)LVz^@%K^*)X;1%9{0bJvi&*Jb01g10c>2GCUx|6v$FH<LGbFz< z`x(+F7<oquJQo7&c;@f$D;WF6_!W}xe~Mp`@@@khIsm!=`T&&Rtp*4OxaHX&ieI5^ zWPtzE0G0z3Kl=mmE56OK>@4AJrDOrcyoYcE{Xm^{J8;)e#tnD&%elyILyC+Y1Ej?+ zluwfJy@E?g4X&|~Swf|f9x<yfk|X9&%5l)6ge>7Bl+L+|;mBzMG948PsIvvj<9PoJ z$Rt9sQOyrXWtBbdClqk&<CNtX@wop1`cJRsIGD!?!|=spfeb_GV>c`m5Ty*{B}O2H za9q+h<k1NHW7j(*?|)3<7f7=VG&G;8-s@y1?NzbkaclYayG608K;1*sLgcuD(G+*8 za@C-F(S&FN!Zm)*Yq+1d#F@xWN@DuCAmKAus`lUuIY5GS2NtLDEVro>#mr2qbm)(8 z+8^tjiI`Z<eLQeXamqz9%*wI_p*$E$g{jP0;%Mzfq9l{ZwS<w}uZZk(S?<ivrDlwn zE{;}{Tv>MkD#4(#9O^B&7vCI&S&|#^pAWh?tiQ~Tj?dMy+PF!mJsa=Z2E`sNaH(SJ zkwPb|Yo~DT$KLC}++-Rlq(HN81Vr;!uZ^1Uj^Pb&&Awo>@cCisIJgp(a@W2>CJ@=y zY4IlQ7G3On@wqC^V~3VPccf?8hLJ0~9fTW(*gy`Mw0e@nu8UhGV<+$qd?D9=t>i8* zIU{J#!R~$h5%0}oe`IhBCJ<Fcq$FJKRFJhz7Fe351|xai^a&<-8Pjw9l3@bB^)KCx zm#>dZsP8#F^$34>8q+C?`XlyGz9HvPo^dIo8gEDLvWD@r`z)$t*VJ#xp`SoSIvL?) zXnVy)G%&`U^I#m$kra!eGIDN`Q(#yv+C1h)W!SnrstnsV9z}+&TO1vMOh$++G8k5K z&lur}T|Rz!&n~ZEkI%pq-C)%p&&uAiLLWwO$lx3Bi@)TaM+H<vB*TME-3Iue=AdkN zj916m#OUL!b|I@;I0P0>buhHAXS6VC0E-Fm=!&2k8wU2)ai)k6#GQ1eXxr&GQ+RLh z-z+uKHE!rD8W1@yN_b}{k-~jpXW;eznLB;_oSc`8)9k=`su=>j61jX&fQdy(*-z~G z_*E)yF7RBvyQy*pd>=nx-cWN;(zb>|Iby2HJE_DFae+2=BFUUe`AYMsJ0(tSriOBG z+WE;&<Oa_J9#G1GpNW3<cCN0fJ4J?RCCfq)g|A^Xn4OZyw1{S(h6{B+qjz!1)gcts z1Hbs)ly`Miwm3zD#*J4(_}On`ws?MqcOGz`NJ)Hxh+?@;jT43Ax>KQTS30+<7%m<# z?8MAt&nH7u5WmQQwji4TSa6Ul_ku?Ot%208FoOuGTmTlxy-J-yD~_466EbK`oJ|JL zcD}NO=USnFH*isDBniG~f@sbWVl+jxp+6W}vo%Q33EZ}`vQ6YRFKCYzsV!0Aj$NWx z={jq1tKSZ=-N}!vIz%dUsAB9O`<>2u10?eNx#7zoS7jR=3#XhHCpTR5c34x2N-4`0 zn!cyas=U_X(eN<dvmP$=JSGkpFi;OH1=Kohp;C*&5h~QxDUR-=l3m2eS11MxYtRH5 zJtn<>gWoafY=4n-nEfJL#ui|WGF-;fJd@=zUVy=p4c%`#;i_zPRi4uu)tc(nWX}oh z2)Io`I;zN?NGCORm9tWiam!JuC{Aa%-E$xDGV<JoX5%>=`M}iTOxGezf17AzN!9mk zT~XCf&aN}uDRZT>>pKKu!|*T=6mino_3hcfXkLJ%cqFY7&+@3m19;kY6l^sMn^5#0 zqWjCFpiEn3TYP03+u~NvMR9~Sq4a*TYmkLXk^Qp+WVi9TC-k4P6S1Jk42*#iS#<S- z;5Dw?R^YKF;%j{6IW8RO2wyCM4?8c*CKLJ|mWB+V6Ae+!1CjL2c%i&i_~Q=p-L!g! z!-y2wAl`J^B}4Q!o+q*nt!`_*?`ZpN7W*t<Jy4;rn?}(v;pp&&oc52epirvh8{+jn zd_|<)tilhJ>qQm{tt@F9+Cx0S?w=!JS)eHk23V|x|FU%O->MkNNYoNE5|xccqE>@f zS%CrmD>cJ^8`i*oTgxF}9U6`*L&H%U(QwqZayL08_L`4+o`*91EJ#JVD!Tv;qKQV$ zH$K51K{KDnqK`pM&<Qjx#h)4eA$Knii}Fe5#ceK=puc3DQ+TGqmWBV=w$ZU|b!^+V zZ6_Vuwr$%+$F^-xpSw9Tw^f(Bo^RDxd+qfO#YFT3rykiM`Jm@Z3r;Jz{>qJXTS7G} zoNZ&`Mx~wa`*FS3hR|DsLZa*SFDYSqEN$cDCE&zqqEpIjC0!?+DpK@^D4MYjvLjqy zHPy|KrSX|Z<~i`09?1m~-Mx?G*{vi@FDT)yGQ?OTC6@A_=*G%#N2M?<E4GYvY|c1; z3CBgrx9hkp2owC>7#!lAhj^IIRqKdMU=qL$wXvSt=K(ZJvvv^N8hg@&V+xrclyK9* z#kq5+@oQcYC17)m%&;8Vkr}A4*!?Q&G+#Hv2X-Oa)BtF^$KTV{@;O94ms5Dr-!;Je zAAdD(Kj~feS#CZ%?&J5*mWp6L@-rV_j*>%S$UsM*&R<!K{y60cCn=s%Q+j0;%R8Hc zHI??OD|zW<fJ#%WqDZB@PTZQcQeUs&*sy$C*ySHFUEyRwfh;y;V2;S#pezU`25}%n zn@_I^N)w*lgQfJWu#8~_I7_5o3zQyfWe2>zG4MRAu=x_dTY|5P87(_BK<1Z{{lhfi z5p7m-w59}?ftY@*F-IY|kB3Pef7ORi3ziR*-cPL+2@CmcYD_HM)}4=x^XT+#HSIcf zqGSxA6MMG@mC?94_!tXm{6N`~v;Rhs9lT|%)NxS$xU6h00yFTn+KH*Orm<7L$h3a} zGnXT#1+^Q^gA1`&SXZ$%Ow9~YQy7)K0miA~NsKrHuK>O$p#H31uEhH7-iQwN*WtSh zj;zwU(Y`GiyV2_Yyhr6rSTRm&GRnz8tsD}{b#DQUc*<+l?ku9uLM0lz!fPTd6wYu% z;zweb=~c0t+k3AqFz>tVjGlO&cK2BqQ}1X=_sTjM=?Y(ke9SkOsQ`~%mUMbS`G93- z^&9oKkUf5$$F_$|^opH$QHb1ui=NH(i_C~G8N}G+ir;?mt-_m&UgDis?!8qpcjHQl zdPWR{wT2<*Z}l=_E`q{a&=S~_Slx8f-1=0!k~OoAg}DmsZN$7!>|V6quWHyd{ZIlE znK4Y&iWl;)@15tfxIel0>#7(7+sK-;vMy}nS<?-{^jG~*xpqmDz2fGfrK0YZlICDN zT{<J#;k+4h6YxUQd<8n&4@f(81EU)UBqY<^T9Wk|&Ef@4g}@r+&#jOF;Z6%U2;j0* z;Rx`I<Vy)8md|n;#*z!Un+&?EEEJ4FC|=il(K-~@xbS5~QhMxjAsnUd$AX;&1pXEB zp{O$L*l%2W7?K65+B;(w5Hc3nW<Ec01KZnc2VV4YM=HT^jY@2}VY%#<i7)|3*2R@v z@HUy|GZV<O`vw*$ov_UrJGxS-4}7=cp$s)E)+ocBjObBW?Y8=3(*q*oLtaN??lrNb zo-1^QTonClRYQVpybG}5&Km5ZWuuTevX07i6q4MZkk>6vgS$FwPIqxB<EQNu<pvY6 z&}ws~kr9p5gkzIt9)jpx`<QI2@=i$~rbMupr=cu670ipdU4u@;>hV8my`ai0-s^Ya zR<|{#Su(DG5X?O<W{@prt_a76^J79-vMH~;IVMk({3FS$<+Hgl??QP|a!mE0UylT~ z*`NeJiUwf!lci4D=}0-5SqzP8zTiPHA<9`h5n3Iu3{xW>A~oebfjd8xGEbzA>6>}{ z13rK$VQ*4slo$b4oDy*gX!J}3R#rK~_H@lAj-IaUpsB}FR)o|sh0a3P%7v2KCZ%=e z1*?;YY9SUoFk)p}I}s&S+XJ=BKQ5*kPhOX29eYqzolJYHp*vWxb75J#9^5@lhE}*E zq8D<Z&zXmR0q7;~870X6mSs5LP%2QPEC|2`WD7$WyyWG5WXQ4Wu)EJdkqEbvkDOnn z8J0*RyPe`|%UL^?c?}b(3aTD0+$MpNJ6#S*40tXW1S7v@fHbBtp63&#{W4mTHQ5A{ zc{0ws<7la_h=RU=6&vCoA>A>8R$_0d!vGZve`KaTo=3G#K9c#>sQjXCk*RpEE0Nax zU=X2l9MPbi2@r_4!<jZoyzJU9)gQUU5DOBz6ojwyNVVLLS&*V^(eTAsZAMbEp4rD# z@$3hZzYXV$cFNVANqoBo=}_2!R>6140+be<;;XQ%j@b$r9z$qQ>ALZLHFF?{<vmr2 zjdK!;hWSI<kOXE>ybVJVpWAB62X$mFAB2;7!;IaDAi4@jaR5iO$KX~921Sn{jtG8Q z8yLfJ&e}R^#lDI^WJcByxnOGu7s<X!ryV&9KPN%wAeS$)9{y$8*HkR^ReBT)@wX?F zoj0q^D9H3tdX!NKXuM2}Au2f)gOHgg=tKSL`NiNsCv({ziz&S_u+D&Owo|-7<B2gp zS@X2{D`k*)J$zfL8-*1yRBenT(&-U&ZxsHf|K%Ty7y0cdJx~=@S&*l`EMGJT#M?fb z$yk?|yS^g_@1!`7Z$Gmjh~c+TZC5FnMR|Z*n%p=`?sQ@Oni7Mo(t*&b!M~^1eymx0 zUJdZf1)4+a()U{fPtobt7K4G&Ig1=5Qz8UAnSv3|zw0sQTb#2=`rE4~t#P4B^)hO< z7|L!1w{tChp|Cs08yHm6`$i4<uz5+$*5Mih>R`>=*A<rl<ZXXgBWs^cORV{=^-hS& zJcI~gK^EmS5Z))AJB!0*{S%R4IT8|!B1Eqc-1!~qsLf*=i`s^T*G*lSY1<0V%NQ!u zr96$g+%{r!Pg_*bkVHZ}I7?@dxo0<rZ2z;1dGq}?IrYd26|bkABWn$8{&1bkoUa%T zHF=@IBLSjK&;m_J%>lIEkn(&g;kDT?n~exVa{FB2%cEXY)@&v%MOAKEXr#nAYtplZ zfhT6LRD#t>FW%?6ge&Y;_!%%3Vfbp%DD3)EY{f}zYniG_J}5Ob={~kkKr7<PYX*w# zBk_`kI5zw3e3>+nr?X6lm{Wr7L6)n5$GT9?7gh;=E%s+V7E$#E%EwMK=#mQ=o^Qve zWFhs1Yy)!-^TCC@W+nI%f0F+p2Y6RFWONGZIv1pHOkvb;n<Q?v^W<(h#)w4Vo674e zyAdS}Z+&)7U<m9*dyBRdIw<}~iy?E0Vl>t6wn<MT`#xnL++-3FQfo25inhIvqVAbW zG?1?Np%bYc<ByXU??(&ThR(H++GnBLwOh6TgjZ>DE(W&7K$E60<i}NIW5^{MZ=~HO zbWoBn-G#E*_GmtSO@9|=_}s8+E5q@l+bKE?F7lwTe#{P;Rje@x1(@bS55VZdTYzH> zis>^Nb!#7o^$FJY6uPCp#Nf}3Ucc=}h}K3dep2KipZg<E>}vU!9jAI6S+32y<Wrz{ zW$~)`B*~-(+wcx*HN1_4&NgcdYQ4_6DbQ2x^t}w>t2tBEaL|XB5kDzgCqBeAoD*A0 z91)iynUtH&$2(M1(8o3J!q;kc1G_lQ-bk4npA0BJx(u9L(k|Itrc$(TjKzT0!tA2K z>Ynh#)@sT)<m@1v^}XeA`J9F=${xVe=I=0#^Sx=L2`%{IuCkXB+)fj9wB22nc1cw8 z&$Qe!y?Sm(M(WF%7SW@LT0q)y&fUe=8Sl;~RQt70uI^1(FS-pl)9?{q`SI`iDXPMN zQm6QOL`w4i!A;&G?)m{-7r@x@?h1ukJClFJS;!$Iz~3~~u8-GBDHYI#+wU1<z?@Le z7*)Qf)IFQ3*_M7+m1u&sJF}0mvKA!NNV%<G6&ya5dRaw(Ww@O$T2J7zF-7C_6P$B) ztARg!n|;+t)2`zM$w4=hF9K{M7?M+1FM)1&#QCGMGtV^HGWnfF?bDmy!8?H=l@CKl z?TCh`WVaH7nKONOZp021NSkGeI9H|!P1#%XfMKGkO@?5T%sHxDXmJ=5S14p%$tf4r zTWk&D4kRhGqDD0?ELFNj2s4_dM`TH|GZjTaLq?9C8zVhrwhE9I84Q_3KjYa83LEsm z<BwSGo8<Gb8IGN!IN^;#KTOK=>P!BZ?#@tegC7VDt@ZDpremCay%8MT8zMiBvLYl? z-)?8AJ|w!FVh}UCbSMQTZ$$|yMSK3r*Usx6C4}<Hf;*7WiFuW$8_QSpM1|jS^R~s9 zI*brit64U={M%}tMKKOVW0Y;Z?Jo0FdCNo}rLsbmkeKH%j>i+0Tf(o%xSUPmG!){P zFM+vG1o>n?cb$VgU)Ic+RPBZ{EYQ^rF?4GTx}IrplaG<IxN0v}j5&dCtr&bq<U&^O zs$d^ymciE=2}1@nyKc;eq|SI+h+ZJ7E7g^Z$dC2Xahvi9%wvW#{bz0+r!K}(PCgsf z{sgBmT4xnVUQ7mV8F2&A4ePoRN7u($$=;D$vjZS1(0D^JN7p@JQ<!J}5%$6I5sHHg zp+%nG6fVy$*?5z7jEB(!jDb#Oy>_aD!-GHq#9ye~<PO^dgpv&F>}KORmtx>j=q_{B zfV7yPuu}eF<LT%ec~X*-LT=qq9E^U>FJ%cXt>SFEg4NInU)V4?B2ERtHKtP~Yu>e{ zTb!)Kw*S^%4s!fW*R2r!BF{uXxG{k@v+XMbNB`?<>AHxHpY54~rYe?|!XNU?nHC%6 zz#>qA5m;0t;Ng8xkc78(=~4}iqqcAC6|prbTWvsHCcw(wv7sN3z4Oh5#hpD9>gyvk zOyZW2b%=dj1%a(+1w(4~%n=o)OJ1l-2Zze3+kj)4S49Xyy2veWipoLlCA8+(8bV8N zPibHGxUb*;hx(Qw8o@#mDhL0(9S%YcGFn?mRF1#pF7YOwt>l|3L!!YBGXGvp4z$*x z@gIb;pCedwjJE<fhp4__d~3$luq#gA3`SGrd68qrjZ0&E56I99X<@9JG$SL+_mGEc zUF{j=!N$C3vV`_>SVth|A<==s(fPP1`XRSnK~Bm4_>NMLgi;{xV}D+!gX>w73BG%w zo@jz&ND1ptP%t%v1v#!vAk-&`l%rSn6V{^7G>!Ck*0pIKqOf+JX>hgLC(AEu6Q3pD zxI?FEqw3ze1Zm;<6W`1r#yWf#oMw0y!kY=3>gg*xww#f1tTc1iH0svkaSBV`{Atl7 zG-FFAk=FVp8uNj$Xc~GIWy{ntjw_(Q?&?m#IBSc2n1Yye6x*v4RCr|b0qCo!^U>~H z8gfYn^)L&o8Wxw%d)8o_V)#VRA5_4$H#<td?QRZClc^h5m}@$J4_6SHfjfRztc9fz z!?|z%ox~Zm(QIONV(+s7pa3<=_V-<d*Itq)`Ied`uw;9QN;US1(N<%*M|Ys~l(Q2V znV#ndwOQoZ5tdxGo~>c3|CpU;u8oJcL4i!s6^R=YlFLK`VYjWV{$}a~!B2W+z{3~k zL_tAvQcWBK4Qdqi6IUwChcbS|u?=lUEbTLOg(WBfcEmo_RRWa`B0>ywc*b7MtdQ2Z zEvjPr?P3zO__zEMEdswT!XR14%Vpa>nH=|?^t?`Yz0yRetX9?io0t)NncDFHEOTpP zj*J^V4KnPvDKL+k#1NiO)=}BFOZ<gBj@;lBM3yssOgln2r)4}fkSFpL$&wr|@Pjo= z6do3L^~8E)Ay%RgmAF@QaN}FM(3Z#P%S^$^jhMyh&UUQU-c?lsk*Ts6jy${huhe@t zW&thJ&KvSfd>ds{NxyV28Fe52W%Ocu-q}Gx0Cl<qi+kuEvcHg0Nc{<PBmeJes!t1^ z(jT@k1adZDCv43iCw(ku+~oY0)yjc!&K{nLe5bz|J#Ol~a+R#%%JYV9AT%GnLGeJe zBxX0Q<JqM{))dDc$;N#0bL>tB!3Yx~^;Gc5T=is-Hb3J3vI9bH&{r<`8aZ0oTIE)s zqElH3ZptokW`XEwcz~#vwD;EZ6R==sMDsF_q06amK5jari3t%wAiE;<_J5B6K&llZ zSDrLW*_?h4N^8a%rXjKZlC@c8ucHj-=vvi6!2;o6AI!|^89&QRAaZq1f@QBCU!{MD z8m`p=Kgfy-GT0@5q0oOnWwgBe_^aF-;K?6d(4S0gZuy*GQu{)P#Q_)ox@TGOl869R z8W{Z!E+fMlz6dnAACwtxUFSUrNeEyY;_wP$VFfF@yT>!~t4b>=&w>Ak3(F|pWx)Zf zC&0T$Yl$VF7!Wra$|j_qx)ri^0>5hm<LO$)V_o7OR#lCgo@^h$(<us<0Enf)a(3c_ zhm{<&$62Wq-#%&GFloatcYOgL45GyL-?_d8S&i=nDL$aE^pGX{?Y1fRlyLontn#|@ zKY_C3m1SgyIU+Ka5=#r+)erf;#^OLA@qZ!mhhRt+b0>H!dGRUJB3(>~n64font0s$ zr!XholKaF7M@SU?&LPk9Ky<N?1a2zKoW4#HR<uC9zb$bS@D#E0HW_VsU>J*q6|dN} zCm*0vaH;5&{)&m*FjN*A7O+&=n5(Jo#oT|j);g`%RMEbE*+hK>R=xz4c80^kEEXz0 zpgv0)$R!T4fJs+od*w5<(5$DlS1o@>Hp8YOL6nHag($1bO^vgAT|erhVN~OIVzd>y z{)XS5K9YM^37jIMJA#w|s-f*-*oU6rPZ0;^+@h;NlY3Ksw6-r`s2b{2UJUUwtB>_* z8qA2+<bZXqA0b_Yqpqt=#V5d~cV9Wq9Gkxf^Wo=~<4})cO3ZOH>O5#yW#h`}?2`?4 z!6D~S((*@)<Q5UJ9BhW_<&ax;9P@S$U&&GR<iZDYqUxL1#B~S#TzTTdy%`4Cm4kFO zmuitiM#gACtbW~dx7`plwJ!^wAj4n^vS+(K;0}@G@!ItStBJa-xR<E}cRdT!99n%S zdq3uuCI1|K7eMbEQuF-~!BR+d0*YnES$px=MCAt4e!ipGn6M_o6-V5_6G(*2w{%nl z)5B@rb4sTwYb7;?3D=VXXQOvQTN@Z4FK^}myB7Is4z}g1gd)qZ{EUEEqXS7yrmeEW zZ7P4*APz*^y0@^vMD0in?O>nCx6F}u1ne~Zh8Ica64|Jt$+vGa9&j@Sx8>gZ3c)R~ z=?$tXOftMcS$>p4)iV3gK%OJ#`34o?gjA5Fh#ycWhlqdi%oLquf`NdC6RfC}7i^ak zAC>k*OYY_z0LS4Ky7n(;>kylVQWhRH{yVuvIwG)i8RWDk=JXpzRPdUi939(CBDJBS zp%P6|75`Zp*_rLqjuv4GuGF=h;l6Ok>mtx@m{j<g?$7F=NRn!j{1FkzviBIJv+Jct zcrS$GWby_n&vx+g3n&wLCzApkOr{W-T%IC<xgf2eQtY0ykBD(%n0Odlhtoi7#yXjK znhg~uG{QGf&bFW<1<3T&bV)+v-+e)Xs#K$pF5(^A!FytByn7dv;Z1dD?5IAck!@@T zsZ+M%?*^T5cF#Eh5WLp`YI?5|ao1}U_4krp8#Aj8_MClEU@_971Rlbk=(~J>&k>_p z6kXM}sA^n{Avg>^ibrJPLoTz_6Pqu$jq4rYVb!Wx%)G1CuX(?0!A{oG52vm&aE(y` zsJ~H`>nL+TN(k*to%YCGDyyfHx~r-j`U?GMux+wO9b+D{?7ZE9HK+`WxBdlu#9ay> zV%yydGzIEUrZkvRbI^q_Uund#P_bKM&-u<9XgwV9xQF`n2{N+H8jw^;#*^f*K4;Bq z<l_;B^}?z+2OWcFF{#=S)iLE#5eX}1R?jx7mfPjE@5mC>%-t$GL>_|~{a^^Ld~M=W z(qb5=sS>BaM+v9uWzM(x*CKABOVQ5Wsz)4Tm3U|Eq;qba2WgwXIA|tpa_RyQM^VM# zuAiNVf``X#hUn5p{ubi9f*hD}#)q{H{QXD`>?>c<73g98*Urt6=c6GY#a0>m41e@N zT>y!(ex>uD3>>#-!6sR@#RE|uQ_WLJ&caq_#G+~d*CmsE6#-fcaY6^3sT+jxX1=Us zpbJ-EbjzTz#l`tMbovVJ{$jkQsA|$4-N`&P&>j*8)0#=%886PMYg)Kfe!F*9`n5bV zOUCYvj@#;3lmMff1>R^w?d^$>Pc>HY-Dwy=<5Vzi*<<136W6G#vCD+Ncv(BD^yw1v zi24JXLu4Lq%ARK&MZRev`I3TJOx@~c#iQ$%Vtx*^xcP4``-O<Mv;q%mQ6r4J%ry&z zgWSk2p-}^C_Q{qLJbmaW;!=8y@|hP`XvSBhIN|1n!a8E<9f5i&PLOm)4%nN=h5>FL zzfix?FtI%vL%(|?+R{Zn9XUIm3yL?Nj0Y62huAIf2F=wFE^lP8A;hbSg0pT@qZ}BX zSje3SFIt$`BXAT7#X;&4IF6d4z(V*LLN_T*$Mz37<^n}K;^PNkNnWpSa2-KE2a5=I z=0#S{y?x29gXMJ`DNUXNzGT*otsnTf=F<CaI1odp#7Q`7$i(tUW{-aLknRAf2Sam` zWcSU|_7C;TEmiC?&E`{B*ht)b2?;?0h?Eor4IABcuzeN4E}%v52Q=tLIZwcVWBPgT z*VN?8PF6R_m>5q+@I-&z+u-Q75h)?+i2cjrk@1#h$5VZZcpUDgNN^7NVH=g)=!xsD zgv_7Y0Xh=q`AGJhL9Zz`b#VhlQE4lMif$-T(Xc24vb5`TvDp2DkeELrcOGXp@cOhf z!yEepJJ674ml;V15$3HE;g9jufwepXe{P-PjoUy^OIys4ee`Vvbf(Ib?y_U3!!HkM zhzv2>S+<XLNfP4|HXBvwl(e?Of)6&ql!whN?}SHbQ|nu~*~U@Yv~V*~!#7be6-@VL zxg{3R^QePf8Kf_mS}3q_9l|dqwpWpDtPk3qB6QVEy3Lp@qSOcj($j`AsiWW$SS%XJ z%4|PLu4f}A7AbJh&5}KX|Hvj0y}OfuP~H~KILIL5>s?%Am)2M3LzyEqV<5?%GOSIx zZ%wi98LUG&rPN(b|CaJSz?S6Lq>TbevRCfgy`5qOQ5$34R)&Enb^K8D=>g%YLs?(} zyHIp`MLb0y<PTX_F}xz-BjbC)U2=&c-kpOiEr=~zd{)4fm__a&+BuzI8`GR0RLgmo zI*NXhSG%*NPzOKC;p8aWobPd5DGbXAw*54&q2zmEXpO1miMGkeCjGRwpLnR0m>6Kq z#leJ3CBQ`eMu!^>;DiDv6Ml34$)o7BKovodj<^Mbe#ewm;HGSLO<<vMh<*9?zDy5) z7*jBZP~^uGwB^h9)rWkl)<yd$MH~3C;QKf9%M^>ury=zG0bdKHO^RN9SB;#`EBb_{ z{XUyO$|}3>GUD!$y;JiWe7+q#9D6pZTl4z3o5@wNRe{#*SFnwhebKIKoW91v#uvvy z?=ImQ1WMQjsFFyoy+MF6du%4rW<8m`%v$d|6={6^Q_hD${PmE~qyq&%+3KM<m_e3x z?ZD{pn#(WN4|t2`C)d(VUWIX4i3*%_`xLzDwHMlnW7bierA>3UgfLV6!F{I>9_UAf zHfbLTD6{sFB_K`8XrC3%`o~2o>|Cj*c7Do4V_$Ai(*U`nlSd$`%5+@4vV24t7br$? z!8)>*viQh(Ke47b$Hw6CN|23%)XEx51gd*RxCB!)^Jfd;#FVV19F4hb;@q-e?D}yR zqkP5RbIUnLa2P6x7u|t-qqjpTy-fgO)YHjkSJqFz#gScL5sx-AI-c12(Y_xf96ONQ zyBvyXU!I^;H*%T34F+*RR>Zaum;C1n=FbF!JnrynFpyYe|2R7!1i+$vN;+<d7=JE- zaLtti1+jk<Md!td%8UP^C_+MAu!RJhIw4^%2J~bYQ26K^068+*U&e*l3U)WD<b(oc zZv#CXsW=8J)jF_GQul^unRY*vy|$`l!!_i@X6a3yN1fm7RcoMQ4D18-X4ze9`Jl2^ z!hiEV(GKDQIH2ah=inHC!-gpQJ^nc=p@AlVT0kxV?(n-V{$&0Lfc1Y)nI@k&_&z`# zbRT>j-tIrE6L1&kEqosYpc;S&_yU~YV37gq{|m422O@;gr}f9%mGEByk_C7J%|S4f z5KI8K!RRCPNdmb0gaDmDy1=UtbD(p;bN_bj6UP|XL8idP!PMdPK~@3saJLkFwLsgT z9N=@nw;29>{uG48MgUlV)cCReZtbsuKJOG`{rekchOfy0OkJbfkgXRSkcUWz(8>i= z^@xb-H?9`x)|rX(s>}#=9bJtc6*YZ&>iOi2$@?lav_`?NgQK--^yPDcl1$b9K7O+H zDC(J&<P-zGWu8Ycekn>%RMh0-i>b`Dfd)n7vHFzeVb!oeF7OgrN^+t`!eFAC9%qxI zWkuwR=LjAz1y1ft?*~zeQCm>qX;hF<N&~7io|33~X4Tis;X~%(+ffGQG{w+gv#kjo zGZaS=k!Qc~K|zgBEU`owP-s@DqD74mzmJC)Op!G(%yjV!46kFt$Jzb}kh-+>FjugK zSnZB7WKOX6%YiYbA&M3Qi-GyQPF!XufM#b2PsER-P2}w&F4fKLo!22@UyWsohQ#7C zvl(u_LdBzy%Ph;ZdszN$I%}P3dulmNZ=LP<bv)B)Xf~Vf<)-Z&=&QRQd(B8PEho!Z zLMN`}e&Z7<9hsW8m}*KhIW?i1^I%7<dR(K~J<`BNzoS`KQ#aPq(^k|}_37&cHfgik zX7K>RzpdErg0r^FnqrumF&QDLQHeJSY!rOgi21EIG{ofgJF>WMkvPyUf|bG6(m|wR z%Tk1WaKcn0g7dzs?}oFyt&Ij@alKu!rEI98asA4~6>l*3_X(X=6Uncj_g(75diy)z zUNth4a7v54eW2W8CnH0%KOtnv=QKx0!y+E&Es&wo`Ne{2h5-f^Kz=FBDM^hSsF9O2 z3?wks9md(Mm-_|Hu8}^CHIV1lty&MO`_qkr)5EG#A!y*Plvd+L641SycI9&__D4r1 zu8{SblFnfM-V*6s&>nq8P~psxhEjKta4_9EsVx5B5FVLK=ydlVj;jL&(AmWW1DXvj z?u~T0jTp%_i^+njI8`jF3KmFO#*}oP{>B6yum^+effO1<#kRDq@Y^n#lN_D=HI2?N z8hFCAl$HAVH5b)!+^VCt)w>aUPLy*;8WEB84Ca(WXU|;?36A$?Gi|?WSA8pM{HdpZ z*+||t!4j%y_OG||pi?3Ii0ex_)Q>9)U&K81z+A}i-7GNK>g3lHY$lkIPJ@B;DdNuQ ze_y$r<UQXnZAo(5oiVL%TN4rLsAiaDyBu8Y4by^8_GKaV1_0j|-*)aZWKokg$`V3{ zs7i4TqaSSfWOLclP~rTw135c}Pp=7_?v?G}OsmNXTDPNUXv`{h&kL#}mk^F(_Zs_D zOHJNy@_}GMo!K@vd^++o^VaVk_m1$<0l#@$h7<Adbtq<Qu%-HQ11<{N67|y>;c$(Q zS_&GfgQNv%CCC>O_!M-2utld>;0<FHaB9#r3E}tXdhwOj3=A_6-=O?HmQT#Uos62i zFQ^>+6+M_ueMD6U#IEVvCx?HIh{A7-S5-V`Wl~JKtcY%CwAn^<pm}-05v9I2nd&VE z#t>fr+MjZebs+@P*mo8kqaVtMcC<E0H36-zql#2+;^^E|%ZolQfp8Eac&X87%J`t~ zqigo3B3Y9VSgoU{$=c{FHcy)}9I4Yn(!4BPRBBG*5nxaCG+2BRep{84L-69|I@l=b z`CY#AFz7qW{h8zT&U<t3<vVo4xw_{*r*PyCrg4{d(0>(kn@6Y~Z)Ir-$WO!kv!(!3 zc@d?xKeYz0ZfBstmU(v`Z5vv+3{;M(o&o~{qf!wkb996=ISI0S;P)lpy1Cnn)ze!! zSo19fB6;TNx3uyK6QywULf+ZW|MR%<^?k_xdLmQ#VaERR<G-`yqxrhS3v3MH$Nmn3 z3Dgk4{|5IB7v=BwcyqHv@H4PC`!mgd8CprR#C`iEdciG!)6d5=z`#|}!d+>F|0z*j z8RIwhwfM*Fa`S1dFqZebaZ8Tp?V;57?vZ)++T;2SL)ZH()ywbcB318gy0X{j%I)X- zV`XQx^{20&edm2}<EBe%$G+_DmLM}D7MIucb0}B#UnAtWyYXcEXLm3qmXFVGZ#LI^ z-Se(-cH{dXl0M|Q*PZM8eQ6~-_1m@mBJ(<Dn|jB0<;AD>6@gh;h?$3d2=S}&;%Aob zr#FiTkL%M<_@lI#G%1N>w+3kNaL}$~29zI<&pMRAh-oW6*KgERP%2#pHqn@vhw;`S z7|#?v)#jF$9>^AofVt|ZYK1vmYgDBU)`?zC`o0ar+{8I?;!32A+@N9g;r89P!lgPp z(Y(crw)hZfqW_aoZwlpMz?%U<ycO%A?=cO1kpT-mrSU{d9KZaT_`azsu2D_gcWwDo zvGTDYs!*<^L2*C6U!o>txG4?(z=$U*Xb+a*Z2@13t<KN{hgn?^v(V2pWU0rv8qVE6 z1O%1&+Ff9kSPCpN>5q1CdsP-Sx$k4P>0lb6*d*7*XM>D{v}ve=#idT8B04QG$M5-n z5)1qa&<w+~ASh${i;E3d2g(4^1jB|{hs=Q1gvEjP9hX9<AJ;}7o&wIn*y;X|Xk1RP z?&~GVZKKYwn(k9cqM@ZWIy+B$MyRTC7jW;G^iL>*MHywNMPr<5l+)&>lf=pQl6CC9 z!61eO+7km0`7yB6cdyoaZC!+w<_G3k3G$Nl9J&4TxsNu($S~{#yE1H)#K-XYn0Ff) zG$02Ht(R+lyYzG|JQ#Q6{C)cFF3k#yXDi9XAR@6Mm)p7f?k>9H_VviG=lyldp9yik zy!W!nM6t~*1u>wj%jN8)?gTvfFl+V-4Z`d(Jh#`5Xo`iZ%TMtGQVBfx^}%Y>9H7zt z{{F;kj>E;<F&a^u`+azPQTkJK{=Ro(ivUZonOn>6`t?|{wSr)`;pFqF)`g16_xh35 zkQ#bG|B@O?G}(T8{&aWB>-^>U{h1b^;W4a+$_&n4ua$1~{q53nADdlGlT2HeqIreB zoFVNtm7w8O?-10Cx*SCYX>^B5jMX~XO^#GNVJ(G}scAY(L8YT+T}(~#fSD*gBVA-( zC;hD&Z(#DpB-5C5i~;g>3wLZuHTlmeQ7$sPJe-0|J@lQ%xNqy-&>coQ(THlMKK@NO z=sb?0L5owR_U6YO2Q$rqbIffbT90NPk$JRGk&~2bN6rB;{)wP8!D!>CApu3At*i_^ zJUfV5_qd@^gNyM&Qi4)n%1NH;u!_xJ;Ba3~-b8a8$g1AbzB$nalO$80+zmb7nLOFm z>E46>$x4~qxRIaSontXEwIG<_)Z?IpkEj)g$wUr;nwacA8P`uRhM`)dzT$YXtZ`*p zM(4Vf$`me2q@~Z0acJ>RB{&cDbAHV}3K)_04@Ie%epBd$@%rOrEq{g-d$?LbVS&MY ze+z`Te=#%IC^n=U4Ah&XV9LC1La!SClezoxG$81(w|K|&9gPVd??hRp>wdGHa4F&* zB-GBjtFJo0rP}V4c)X<$frC%!bT}KC5yVAWJ!RAJ)D}nsmTo8xFZN!DCvim!Ur`SQ z%B#O0#_D+v`hS>%hLvD3d!CFh_0algu!%+3l&YubCR)ibG%qJ7q}z;m{Ftpw;B~kO zFstd~eDn0+2Gx@^ob9rj1Y(G@8`s%0tN$^3Q;z3<Lw4H?w&<!Rwd!Ig)9dl3<T)^n zsgoY=G!Vb`P>pefkRMA7E4FYnI{%U{pQ?ofm#S{!R`p<v^DNEqC4Kw|$?@5|!Q<oU z^XQ>zPOGFC>N;@(15@RWx}rafOpr-&)RZ|5ABWb{qM?3ZL;UqR8rZ@xX9u%$YZd4` z9>9lKnjK}~2r0y`a4dyOuHJD&abu!b2z%<XYo2zv-vDjls*hh#C^Enw?y*qICdJW` zWh8+IVratL|9bT1^N?Ar0S_Z%$b^|DJVEPPS=*u!z~}D*vwynsqk-;)gs)7(_=1&6 z$3_R-L)eR%R-!nph`D0Sz<jgF@+Jj+`r-TrNd2eE>08_{B=z!hnla6)BsyL`pDQ=H zKb5hv_w7u6@!(fW4tKiqONs~qd-nv0t$ttMFF)vh2JRPb2ir1lFt;llt`Yno@7RDN zUcCIDm$!Wm5iHi5G-YwRocui(xg<zo1p$_-K*LWW0EJvd!lpq24pj);3k=S$ViC1p zN0rH+qQILZ{|xc*pC{rs5({1pkG3fbG|8XLB<xxf{9;s{>i473Xm|kWrlFQ@odH($ zh?_Y3nuN_O#Wp4A+LZf#7&nTDho;9Kv4In?@-98e?+?;XS;;*D$vq^ZCfY8WV;d*G z)Hk_z1hntmXny6_pY2@NF#@<1xVMkeg0G;jP(J6pJt4b@AE&!-BEO&BSfI0)pI3Pb zTsY@6?Q%~b^eWa3cDr2Sx86remzOT_tqL>yREW03YWV%@kXN`_zt1k)Fz?Fua;vya zc3TGDgv0Bg*U}s-FI%1mf?259YD})5YOgVrb4$q|_oY!T)2Gpv*ng(X@3j;;&02=3 zY%Pn4{oV!MPGic?Ud!ukM!qu$pHxP*gNWz+?q0#zfV0o_z9c;+hUR#Qsp~uCddiN~ zm4e5?=4Lg9xaLRDwl-6K7`mE0D*L-%J-5XHRl~LZk&hy@ZH0Y0P;?6{3cE2Ntv4_r z%=nvwyRv{6BKvsNF$g#0Hp*RD@YW}O*x-~^7`m9om37!5=v4GgnJ}I<ch{x2_JID{ zQZ#K`YmC0(={c0$nspx||3{1kg*5u*@kw3%kJY>zH$66nSm1v@kdS%kdDwkGbx?V@ zd5Hh!Y_SO8^zj97`>g#j{nG)=fC7LsARd4O*aK(+SpAXnUhL+`0RubcpQ`p+09g=R z@K=yND*!!!2j&*F58j^^a0D1k0`ZCQ;ey#fegDkY`r)%q^tDKE$<PQIL1;;&JB@dk zLhSATOfJkSx#<#qDV@fe43+d0;&=MjllW%&E5#iiV^y2`!|Z$TwU9PiUk1^ajxh?R zc`PtobpoIRi3*Mw2GD@_MN)3FK*1JAvNH+O#r(#Tb5H!V1Gu-}!vjzR?tXxQZ*RuS z#~{8?7iKei+9vxBL8?I2mrdF%KR*fNr9ePY0RR9bpwz}&HIR23N(ur17)1d9F#fGN znK--HJKNb=JJDO%IyoCyTbnr2*?Uy0>)CCvA^N?P5-vcDXI8P{w75_LJ6mN9^ktY@ zbf7~5hosD~VQ4A~Q^oXtU5iT=T#{S}J;bdZZry!<U(*@tl&{wnD?h~B=O)|opPA|| zQ9*3wT6e~RFE0s-oA=te>qIz~i$!WyYY;VAM8##iS(T@7vs3<UuHX(#eD;<cjd7h% zYFDU8RlHk=q!YX5vWacPzWy9MGX*2uh@^iU)-wiEW<A`5R58`vNV!HyD`}w5eiYWj zoi=Bo((i8waW|*>)Im>2J*tlRh&?Do8q5s}3bH8A#KzQ-xkOV!8#nZakQqJ}sC6Wp z*DOJo&dkV4A+AItLYFpIupFGk4a7h$c$}S+i~dJyyns^Fkucb=FW%Jz(R>On!n8?_ zQ^y;LF_6n*_XHx-GkFjlBMv%ZD%m9!_gT^MmL!QP44EXQ27;zo6<nHP%C|WiQ}kW# zqf+R0-ea5y_q8aWBY19m5L^}oiont!B>hVnLNh}DRvqjWH_FesWJAF`nVURe{FwtY zeu7-p0P@g)=M=Z?2x02dkFR*1Q-s9Y1Z3BE?;4I(rlMq2&F~zU?SHuOjBa!EB8gf> zDV1lq|CC~(&<BbRGZu~S(>cxWmpQ#{UVX@mij{5Q%A?G@RrZcPm}tRJP9EL)*Z`Jn z*lZD|m6?bKgmLW+SByn&+)VDgH@nm^K$QVAHDN=p)|7(xAsLe!Az>IW0OfjZCADlV z4F8)*IpHMks6tyj9;b+-rwT`$Cd3KjOlaZu4X^eQ?5WAgUBP+2)lTCrXb2nHhxiZv zc+0Pb8fCZ7u<nnqB_babY!p$A7YTR$yS-W?F1~D^FNUvc&X>UHlw!fIz<b@l6-DX| zthILe%XW~F&Pqg80`UyL?H58go|bnEG?9W;(hnkR;5g?~KheRQx~IMW@}d%_r55Ss zRF(*fP2mhehu8`TbdBctYZe$!x#?olLkAe;?eo@x6?dA}qrOhOUGijRXG`~*=F)!~ z{tJSB{dlnU<n$e!f^LaV(oG_&E}KIvL&VG`D#JvB1S8W49M3AioZcK#Fc)O8Rp1)1 zvrMc;1?MRkBE|yZa|-ZhzqD`&uBgMA<fxBgw{a6#N%%Ung(XOl|1077NItMmuTfZz zKgM}FyFBiqm%{b*z7K`T!f^hHy!Ik)b2&KE7`7Ku_-f{PcQPusC}z%e0f8SIDlGQ9 z9pg5RwRxy@R{5*~odoK%2H!z<Oq5*>=;>)`uNk9o&rkP!11kr7w`FB~>(^I+kBPU7 zvyBbhjFt|!MiE$N2Yeqmr#1dwQvff4ll6tWmrhU#90GXwz8F>(hb3QH7;AeV;#w7A zb$bzlLuzd>9p|i?KvMn9nL+<$;7?O;q*oLPBdsj_S@ndo3Ji@J)qa}_4W{JWqdaIo z$dPiMc*X<MF9Dk~;A?=~hL%?=lIfC6<{2sC08v)9e!_vhy4?Ze4EIzOwQ@;nN-a#& zyCorBsoEpQVKmXLxH^l5*eebUg(P_Jym8<x$~-7Nd6*=&O-^3W!-kIHMu^0evEo14 zufh$~#%}XsZErh#x9Nq`Db!#7BQz7?s07*odehlOvn~h($qyeazCrP@qcnLWQr?#~ z3`t6Xbg_CENeH>xnq0I^xlRQ`Qc%JAVH!bcVjE8G+?+-|-R=>|d_tz7xFNq3E!_KN z_*W<vsAZ%B223chk5I)6TA?SqIv4-OTu(M3Ordvw9GtU^1jMC#{oVr|)Z_$=d1-08 zjXuvSnQlDI?ONgTX>b~DN+Z;jhdv>Al{TK@8}mcTnJxAW=&`VDecp9O@n4v+>0A1q zjhl!*m&=)HDXmGq!?c2*mBLsbQAYC!Z72pO*m~U^*Ud%u6Ge`hvH-f2=IX1V*&|oa zJ*zN~l{TCm7p9udue`*LhgED?`nEkUedm}P-`mu?K5`I;arx2gPV@KgFJo8NcSdZ4 zoh`3x694)n+)Si8^@kj<E|nj5ed(W+KXfo!wt!8XsE+LM?{0fo+|-ikJVD4?RCtl3 z*N-3#_6-f9B;PAU{QyO3Wg8JOSEi2i2hK6}w4@TzS%O9ohu03Cw*0XO?<0UJYg5oT z+>WKTe0m*oe(qhz@MC98Hs><~h`Coyh0Sb>s4<)Ch}fct1}j+_bM7YJXAV=9E|t|y zoj&pD@l&U(xSwz0`?u9LKp~V&fgHih`X961?gU;nXXc36MAo5zE(ZK8_r76h5qJM| zk^sZ3vGGOh61n?=uxMa9fj-}cDEo;Ls9m#UNRZos4k?j9N8#Y)+hzajWw}8~mnyaS z(4!OjXyMzeaKjEE$RqFTPl8q;M6pL+r`V!xaZ}^S^}iS^TXvCB*9rL0z(AG-=~`=2 zeJJxLL3;Z;g9n?98hF2pl@(sj)x(yG`dSwy55rjd{rtQ}9IAO&@my)_=teMQiYGE& zOnBJCB!k5>yuW^*cXfqWvELy7t-nl4qnH^$000dL0Pr7G{$KiQZQx>SWd2WlRTTSe zF9;F49?&Wu^~D@%yRArm`ju3k)`i3Lacd)h`nhh}^>&6isxM&b8kxDHIC0_kYcsO( z14Kb;VWR&<QXzo=-8d?ISSZ#&M9%nQj|s=aP6u?gLNW9&c}b$GK$iUBrs|`76|d%~ z>u?XmkPA&l?T>L|PHGV~y&EYIZGh2E<w>?Uz1F1`Y}tdTxhtAp&6?XHL~Wd1lx=Cg zFbSrZ5cnSC_+*K7(o8@sU<VmmTN+ISd^b#Y^-LcPY@j-~cdOjF`u#Wo4ZA`J1S&jP zeJo+NW_<3#aELf5FVkJoOHkG_YYL_oX~T$Uaj{~ZKEG3EOj1&0*W<G;Sv5n#nMWsW z$>y!)zfGBw9u>_=Xk7JgTaD;;ZBUFF9x;A8znL64BT-)mIV2!`D@9N&$I{@GF)6cJ ziOs+NVL=z{W_F*-hg;3<>9(GCZC@8HeDAo;j!paopA5az=Zx&&$~}0?f>8CKguVL6 zLgt_8>;KCgU`oK`H04*wuDHFNzV<2Xa|qGT|BOWBjQ3fjo>gln;tllQwcPMVRiOn2 z0Omje0JQ&8OFJ_&3tO{)#SBrFvD;vP?fy`+Un82)hummRL-;sn)4wp#sy8Z7Z>m;F z0S=cnK>fHWwB~Hy81xo5zmF#-$gS#3d;m3oOwW<F8HA$F(2KUhw#j@`ITPTuKmmnl zSnq@fEmA+Z#DmvJp{z2n!@IgEZq3T_s>)L9tb~2N6Yp+icnj`l#=h9S@=kdDx*nZg z$(${hJ+iLO+&0QtV9%U>{V{-_3KxK{TLe8*j#CZb>0llaCk)w+O`o4FeGgcN6hbi# zzL4mvRfXU%q@G>((Em8x(x6s0a-8m&a3Pm?FN-b#x@K**(%oHU#&PtoNN)LE;w)W^ zo`3D(j#??vR?7>L{2SpYBsBL>!BvmUug5C_73fUskj`&lBlu9_TPrb@t|UMA2(tWd zGuu$v5iz;;04QCTd71igY}?!4LfDRs<>c6aAtUngO&({=K<nF^l3h4h@X4#embNT~ z8Bw4@#fkRQQMntt#j1`R5o+httaG^I*pDz(ZOH^VZ?b&oZG)xji)~fT#P-r<BlB#9 zVb4r3Yqh<rYsFJi?MB?di?}12phkQ3Vtjo|@`|$G1r)84s<c$s?%~nP{~kgmla372 zg~lg9*2HDoVsq-Pl!t+*UuI#oKcJf?)Zi|6McQ3;PyZ#|>>S|<hPhE%vWVx9vtGye zrLC;`5iscB*bW~2%AB=oWLVw_KclKupBi;3DV~ygnwb||y?a^8T<JVAGg1+LWSftl zF!=%e_xa*^#cQ1e2LLpX|KGR5#?IEt#N*%bidMJz&qe+FTCbm!f`q=Jp=n$mbovkR zv_I@5cF|TuJ_V>|fel>}MO>23&B{#-s>p&v2b#G}WLN7+j+a7gOpK{pgO@S)f|63L zM=P<T1a{4|e%sv9C8X_?`-YTB*tW$F>!!M6Kj`N@d3T;ErOJh0rp_!`{n6Z#sARsG z6sgvJ4s;J@Z#01lb>?pd`XTPE#&uBkG%U|j6IB)EunJ<e!%4M^i|Nqv?D_zE8P8$% zzjX=PlQVPJT^h{p6hEe~*$TIg60VMf6nEymE>WznO5A4cmu0)A?8J;#s|m`~;Cxi+ zD}uB1W}x4@M816fb`^`uGl7;R60~I_a($pZRs}?$b#<$2+-?X26Y0sHG)skK%H#P~ zkXL<PybQ$L_te241RJbMQ$`Ab5W9diM<Q`@IE7_8AciU?7G8}|#EsvW+mW}@wUp*U z2rM>OXS=xxo37Xl7SK37O9w>up<PJ8uZ46&Np6s=R1FnS>>1%EKu9dtl-h>b4(I-w zfZrM_=ouAM<6<LY>uI`rIXN|L8VHdMDOVP~7iSh@59MG&xjA2t=Uvjbp{qQ56WhQl zKvJMq{bVAu51j2C#A5J6zfx&FnMVRCX^sy`o~+Qf#F1Jl2`v0+FuAnYtH#?6uEfEK zjt=HP$REbF9b2*UH3buXcjxO&S9u#$n#iWjU1H5s{+gAzxKF*CC@t*(wZVWRb^l2C zq~msDial_d>9mIjJI|6U_p2@Hk0_vyzz?WMRpS1QEWHKXttu_PUN<uTojsROCyNka zup|%SOokk+OfuX9^oK=sYu%K!BjMaN_((D{iI}1)FHFZVvFdMOQZnvEqML<}97dl@ z6^j_^O1^);e=n0K%-`uofmLgKAgjnbXzWS$#L}55vv@=A`>bQiF>8E^&2zLeUTB7D zN*2WYykIxueswV(**R<7vS0VaQ0fZszTH8td2zJtk`l>5Gr@4Df5(6;VK;2}-tDDZ z<ae4TqqrkO1-Aq-@&!=67(MCGsB29&487VSxZ3?r#eo8pTMjE5)$F#lcc-)I@*96a zP;Jwadcb&i>%>I{cIC|SM0q&^RTvSDu)l7w?(%EEQcF7l=tj{&@gU(JS4AbuRco%) zRRX}}$o0;i$bg~|vh6sOotr~)I#Ys7gb0a39r(!Y5Qa`?pzoa+=v9c_9n=}XN0A&1 zHP0pdDO~9uXtCaT{!$4nIKhPJQ)}MHHiDQ76zbipc=UGm`n2IUYV`EJ9c>Zx`c&ZC zUh{i*eLe2&(a-T|ILfNTsFz9H4f|_XX_}e~!A*;e#$H(qM(v2L<b4}x*9fF?{)NuV z(_thXr@Pat9~~z?vQ;)x{hh8Zvk>Jte%CYTdVqOxJMvO5WWtD70$#GM#z*e6JMyCh z<UD3bu04Yef*}LOgtZ^K=}36$FZp;o>Bj0UqYa(aD*3(9AJ!2=61P~fl-V(mK4rl8 z0RfR<?L{Gy{NeHBBN|d}lDVwfUsm}(suJ>K{epg(w+D4^KCQ+P--R5g)S6#0?>n|j zY8fRsc2BdEjz%J-ybr={DC)AL-sRwQv)ZyQe@SVN!g}IWL|xTAhxzDEOX?{&-8r9w zLfaMXv9RmVKZX`mUD2Y2YK^9>VMqGt%u{WzwYlMim$FDXfH(vR&xm~HOxfLh!E*)c z0c8_i%P}Rgs%+q=&d^p}yxO*A!ip_%Dtb>=2h<9)E`u_Qk-ihRK&#J$2;jv{t<~#W zT()Ji;Y$yJt8en+#1~}@2r4wDZ~wBebMKtVgj3-Hche2T>dP7M%@Iq9kg&ZsOKOlD zL|!Eo9dTuie6wemAb$S5%{Z|+WZ1)jZ@Qx-U<Zlach(+~zj8SLF!{hup6ik&XU&WF zHL;ZI50<idrzt_38u~f@1i;kJ%~I#p?UfC;zuaNnYbL6T_^Z7XlxNAal(y&fa{QFi zMMqynGXemW+*Ukjt{sBWz-(Epgkq6iE#1>OgutxHHDHd@${xNLZ+1h!jKF&pZqI`; z2uCNzC4JE~%xd>{l|!>}fxnJ!-=<&3gpcHi>+glvG%%e*xwOb9Csekb1|fHsnNC#P zP>V#Z^c=Q-3amrQY<!@SnzgafBXyGt94zj;UOLf8o<?aei&C&dN(%8>^>|J^`t8xM zJa~TEgm><kXwu2l*>m)KRAyHsQ4fzsqH<#8L4rPaZoI#=#>v6`^&<}D!5~lRk+ndK z|Bt!KGs=4swLV<cv7<GKlD^P$ETGU}%RDa3yeoEsrcZEf^6>U5tJ1hVB(5z=)s*uE z^WWl!tUA|JN(unLv;hGB^zVOPlx>_`js8jB6|a@khG@dh6Lp<3C!rB`im`^Pa%Hy* zg-7B2gRsVU_L*S-A%%emFf2e(@#uc1w)0=YvpzU+*&ipBQDqvaEHO7Zx!w}5Im>3Y z7_$c!jZh<Ut*H}<4DLh{7e3+N8OGxzZZieedve*^i>0!0Q^)fx(#&>72Rd2W!v!$T zDLYqoJdM6=QG>QOp1oIg9Jh?VUk}6?G1-eG>83L?%g<7!K3|@-7uq*hu6X>}E>pZ8 zZ-%&}M>DmO*=M=kTcSpv#yCa?kHiyM>3#>Vi!||vNl6Y3k>-35nmQtHV7$){<}7eh zi?sO`NkamM=v6bKEQJc+*`#+PBr>M(EPJyF9%H$r>F#XN4c@rLIuPK!V*~B4+k?F# zg?{7;n=S>`!1jA`=YXG~ZyHn-aEYuxD{m~=;p7kHxgd5^LpuuiC7g;PJY(p;^ot3n z4igy#8pjGPjzcUmim-ynU>=6EJUtnN(nhvvBnI<w<^0>j3U@H}7=$B&{m(^N;sxB- zWK#Y#x{h*k*l+3;x@T#d&>8*O{-TOlyv@o<3PT;4qyX~_U8FJAVarC4upjT_@Z~|b z!BrpsBz86(cL$O}d#z`Ne&eW1nj;)lN!7QRv+w^q%fyGB3E=PT;(q@h0D(Y$zpvq! z{?SR_IdDEEaj1XO`*Lz}^zoEh7#qC*)O+)O_~A|Om*bB|<{{p{>GzNN!;?>+PDKN1 zA+R}sB?<C2Fzd!RoH)Z-whXp+hZCURa2eqCYIhjGz<i%?@(bwm!h7ws<VrrLK7y&e z`Ay3i`N1X91NjxZ=IKp=^ksMhvocb6pMYcEg*R>aEq?fSRTR5gv$WNRy?N!Q;Xv-x z0oyuk=M4JS{lQu9RZH);)iuqAlbsyBIduL<ee&z4U-x#0FLvN}*@+2<@Hz<Rx$~)i zgp6FEmjW-RF;Tj!(0deS`H=5qK!2-v2-{3uI+6uIqhdr9zmXHg#s2bwWD)0LVZ=wH zviK~!&N3L%eqQDU-H+nM?987o!Zu6=JHDfJwBaT`qcrp{wWqKVm$XZ85;@Ds(Z7cM z|EA|8Q`!uaPIW{h>;%6gSp*nQriq`omz_?fEeE+xND<gw=k#XIel<*pACzcOya+2_ zA~t;9e;j~1Vwj01+FF`NR$Fw{WtPtvC8#s!7;_)%zI=6ueaTqzgyzkh*7i%L9k4+r zWLOArWs4~&l?jl3nOsKkxwFi!F2XbfDb0v>JaJ;sK5>@&(<!Vm@aiHScR5Nhbg>Ou zY|>L0SWpt$vxYEdo;dz8iN+w~;}A85pGMOgC%EwAbDS9gnk?cVhmM?T2%YB~=cHj# z2A{{EH9(tQgbV?u;W7X*ClI(S2A~x@L<4{6M^k@<`fqgO0L`N~%4sRi`pi;b4Vgk= z7>8p|ECGWlNpO#G+3KB#dAs#FP0mw)_7)Z)Lp!0<>Nv2Wt!-M2x1$L`g(Kc7TeQtX zNFOMw*9$Jf;BuHO^7$fff7SRE^?n=Y=sGQnwbO#Hjybw1{-MyW)zL+1>ltW0VBA*u z@jQhd(-63;@>LrCzKCEk-^4f8?^-H&o+{$K9`H91B8JC3k4!QTi0pwaw$5n3Cg~-J zn6dZk;n6h!on;18z{*PV8ytnRfscIh88?uj@puvBH06)Vx8FM6I1G|;*bZa(0Stc7 znvDW%$LykmR+gurm|GnWf0?&6rPEecw?};Vnf=8D9~azR=Sv*nEQd5#Srl5hi8Bzf z2L2A9pY;%dH;e0N8u=-qPBw7Ct4zFO^XddbyliY(X5IMw{>|yI|M{plJpD90`SS7f z_yd|Ve^3V(*3;c*Kf3bC(4UR>cIi3%P@ktWe2PExr>r&mW#dn?TwVHU2J~#B^)}4r zVQ_cbXQ;`4qa3Gp%OC}v9?e3{OydSF!Gb1$iBbi@<rqWk1Ou6xf0YA%V>~5oUgHo% zUxdSD6h|lukgzjb8VRq!RvR-!k_oO7Er5+YuO<Iwjc9lF8OQzjV`)dJA01MCPxrQW zfAo4Mr#0PMvj6t(mN%YGTZK_ku|~L?a6U~&+H-Z$@JkQ>X$yQ&4+aa+b<6PJG+l(9 zug|u>$^K$5AJf?7o%=pXE*Eo?^<rfd)E8CaTTKz8sV}>Ug*2KuDhQ<&bs6ezx4b^q zg<z|pFWwegJmVtOqiYdra%&rSP=4o){9ISR%p-2g7Pm`J-m#z%=z47={=8$@a@vCO z@#WMCK})g=ObA%NAy^dmDYpQT*5Psg^vmh-`#!p$!~WsB7Vds-x>QK<hqlDvS9sIp zDonvnb(UzAYhR;NL#_vXr3~wVmov*0PW-d9f?bVZw+e85RrvP`?0y6itQ?l`4#k7d z+>fW7sJp4HFEQGSXu9I;j?PDlyI3{Sz!<Bs(X?6IU^aH1FP!Ir)B5Ajmh;D-&JRCe z#KiRwE_8<q$`okp`z_1IfY^aDVgK~-)0fktl{84)MLv19y*CYAX^X&~hJl07)r^o@ z8^rN5Y<E9&W+Q^V89-C;1%M0!cbLNi0u|iSVWAy(F5?{1lDLH}B})zqu9RQ4rx7?1 zb3e_=D`>k1Zijl{b7WswJ1?70qZ}Uq|7xNXV;<x~$_f9J;zDwBK`a3Jt2@6L79x~O z)o<uRN-;omWqS{LaH+78P@tb+u>#wT6|vyyVnG?CMYxIxW_X>azBxoH;<s9C7+dy3 z8D^V-xlVBo+y)C^3ve+@QkZx8?1Nhr<}eEVsRWMkPl?z*FnB7dcj~7AxZ|h61;~;B z=p#Ho=J6^+(XSW)Q%NsCl*FQ6Hk~)qEB_`VfQ7JR%+@PpY;~*i1*#R+>b6>Oi&Qq) z&|jP*)I&B7@+kb)#l_g_=-W`}4@(beEFc9BT(`tFZ^mPAk8|*rGZcO3Xv+bd8G7#L zBoi;f>D)PAMB|X!0NL0Q`PA*|0<24)+<9OH(97U#CDSErrCj%^HywsA>=ZN$fxSR$ z!>T6f4aszhI4B-9F&BOTB9aCWARQo>9`Hu?b?ckleFfi<ZsU!Gh`@1MOUBuOsX;;i zO{Wh_89_r@H#uzqH<<w<a8THqvpE_iu5l;*A<VBWZ+r45LUW#m;9{pNc0&H_*mLDz z1+F-(5RyOsI86e7stKi8HcqZ$^mTFatE($-CM_`7y3fV8&-qe&em1}Uk7#`GWL!+A z#K{g0oS(d{lGQvR7811bP)oMm$OkW?<NU*Uwp|ULZ8~oONg@{v*To@@-|X#5$%8SN zFdT;zV`7X@aF#w0Fd07uaKLhLUU^%dq1DGE5BK3;N0I~N_hk_cVmrLBPAfwQl0OA9 zI{yms6okcam4HeKj+U#9qB~$_O6b@kZf5~}gF=}LpB?X&V;Y6dphRz6DZ-D=rJ@*? z7K3l2n>q|Pon8VhVeVx%r^)`Q@e29>Ijsvw$NAVtCA}J<h`1MdKHq=-+`sg_S@wJx zusL>K6;ukRI;U-Km03-p7JdnmzC<p43AQ(GgRFiDw_E#;Ya2t^T2GwUJFk8+<3W+- zIy_K|R`6f}Hp_9S4WhOct<nG$wA4@P;!0((R7@gfEM}(hLS1j(?O8CNKO5nk&*(7Y zxyvnNA)Y}XwK?!zw4OKE;h9i>$MGc5HBxVprYQB%!s5#RjiUTBkh)9~0@+tGEKq8# zU{k0t1Pq2@Fkh4+z%I9vlXR$d2lE<KtB{QhD$>eB3_K5q?JS&5m=0F73_kSm8BC(d zR&JuVSvX7tYxubT6hTWlOHTM8v^0-0gFpyB%w7`6_db6y8C69?`KLlk0y@{_b1|NA zR&Fs#RKLpKxCR-5`hfkh|81j;Pm~R>U+=AgQo113oENBpNQA!5iydba<(aoKb|YY7 z4ZZ4Mx1w1r2c2FQ@ifFuuvTN_c*pOKowhfu=wSev@%#nYjL_!bEy$RV@+#P`7Ochg z7f0?6+SJh`3eZKJBvWvG6?98Gzd%_-n}e`l#h)YQx+HGUrgH~~kg#^d?%+f!^dO*7 zGu(i}ti_Nb*jgQwzFB+kNs@r1A27B9aRE995CZat0&{0B=+voO-%_lC0B&0so$%um zbja?}X~C&r9fK1EM}das5uRi&sNHh+ax_Mf8IAZZRcXNG*#Glgfy`=r#~0>d7|$R} zoAO<0h=y!e^fqxF8cUhNbig@5!F4uP>tU~Z<uoy`fj7R0GadBRg%Z)&AzX&Bs$ojJ zqK$@pMGScloZ~7wyUd>^SoA2UWV|64d^|4f85vECCwK_j3YxKFFRP5HVNnBniFqnq zrM5+WQH;F70ByVhaNQ8ujt|jM`Hfr6C*gSn6uqfh&9>~uG(;a`3_n@V#@4go(jj)- z*X;I!(CX6`3yZ`-$)?5xFwBf=s|jJ0E>}8DQomP|=4zVN<dx~eDG79TD_ujmY_88E zz(H$av&vP!s?N@{E*<8d$aTX|_qv<zL>Z(`47+OjgloeqyUx}@r+?jlTx{rMkk(9H z3D{`>iQSi4291zIm;0>u>U&`ZYXJxW05u4$wOVKW?~PNx4yRxU+i%EXOO4k{iL*T_ zim7`TE)S#S;H>vHNf`vzT_yuD!)$!H8j2XrdR%#-&7E0sxnkkA)iL4mx#vQ!JU(g# zJ8BEjEt1i#%o&II<a%{ny^lwy&RbN$S4n#LSHctkd;1%}V@Fji>}8Z^L)2F*${G=W zeFy!V6YTfcJ5hyTATlDy3>GDvAxXkb13FPQ+4qLP4IUFmv4VBR6Wk@Pjm><_B(Fu9 z<@-@er!!5GOT}?S=b+s6Et<d-{i%cPp4T8w#^K&BTH=KfJ&(LnV2n=dq;>B8nq2Me zzS#K)eO)65yP|vmY-u(_SCLOHEuCWWO(`QwT~(}(u`DR2Z;{rZ6Mu|AtM>F?WrY!e zYF|pBr|(2+%i1feCs?Qi0=R~0NT-jb0u0#%tC>v2BC<g+O|npH(ZeTdlNp{S=%Pw~ zhs$%pw;VMge?vcy8L{ED!W#S->lJuo4tM*4m}Hh=iAAUDY;`5l#%hbU%>6t5WUE@> zc}%tqU@k_m)>hmCbC&|ib&#)tf%sT!FU+T*)-Fcm_%7#6@t=z@y<v4B*X>cUb1@BI zO)Tc%T5Atsmw-AjfP#6HS~ZV`5och6s_@zSRLNH7u?t;<At|%>&Z^-W`|d&tao=5y z9u(VHeOmV2!OmV{sD>(a6sf^d70lK(KM^gQfBIz;1W_8{89c+2n-UR|rc`9d$VC}M zX>^WDkU2fTZrbzV*-~`p!{MT5rSp7{zYA1on4FoBM8L{JC-k!$R*;!SnScz4en^?K z+UXv9%1-kbft6y8a%1&7OBYmNHNB{W1iGrv>~RTgIlFvu4p5qvgA^$SDYWML_Y}n7 zE#Z$1{o6|{{v9r}Ar+a5mXwn@XMm3V+{XsE*5bI6Ez1$xc1ZiP{`SkKUGR?85+Q#Y zoyVd`_N*_y(g9#2i-{SY7&+3l5qpe@Y}ktBjIsmup-lMTKw_>;LDkxpHTLUU%nQZr zCvj{qF<Vum>idYWDB-UgtLH<8rM?LCyh?noPTFcWK^=WbOET~d*_`-sKPI)3fF*Ug z3ZyDhxe9Nm+{B{{l(20=qHG3cRI}R_Ls5FZT=WXzZd+$tU_{h!D@jF)Ik>WIg@xRh zDOu%+Gd_V4w88>{jaxN>mI0_9O1ThimO<AkepjL<%43!6nOK>xg*p|cRadw)Md>Op ziIUTi(beT}tWwcBG8Pb5jjfVdxwg$^G&@KbnH77sz~>pyA%>sB0$MUfP;I`GO26D) zR{N%Yd>*#hAQnT4-y0z6@;%Iw!=g2%3bw`sV<M83)K<!ZN4zc=j3l$ohaZ;B#1k6@ zC)g*XNm(P$pTokz)>Du9EF|CreM}mN<v|KO8u}%nlyUi{3nY^|EeWQyBAK{6V&QBm zW_?;nC3c5IVJE6t@2%ecfLj`eFr%%`{<9xk`sZOb7#?$DFl((W*R=F&{LpGhRp4jL z*(N6z{-6zEKC$EUAgm6YKmIKAoPdg#J`Hqb=B|yUTOe7HRTqAC5srt<>O2tlaI`g8 z6b-kcMA~!?we;uk8ph4oF2M38v+B|D<&{MRwF)S3>yhUV46P!tf?VFD978bB)T&sv zY{X(Mc$$YE-doZld%G$*vB6NSKh=oE+%~Y9i-Fwg<|Im>JKHXX!?H9C=*VJQDsp-4 zc95Z1GX%)Ib?JKq2ps{;>TDN1s?&2@19dL8`s$Wzgxzl&2GX6NL6wQ}KRV?`2d7NU zaT2m>brg6$tkGGoGMHdAA|M9`JOTHtH=rEP0j8t7osJ2NevaOc+<NGBVd1U;Nx?cS zIdAA^L)y0DdDZ5Vq|`~mZ5Q`jhiY3GxH@RIozZnbOxpxJ;BpzwDZ{_aca;1bWf_(d z0j)>=*kQuYuKLR|y0UlviIYSDIMx@*xbPb)WZ^&S!@xeq(dfE`LI%RKXf~fllL%ZP zT|%~J{=btHY`Zv71<GpCLs4K*jRFd%{DB-5!jvgq*K<9_t$a?Zqr%6XulqaSI@ZI4 zvp$c*A4auqn9VYml_YBiIJNDeP6={4ocMTuhSp@vA08-&C?)UTS}9vC5#eY&!Rip1 ze#CfFbFoiBS>%aB$!by_3kQUXEGFQYP#|S&f?7@H1e0Bfgfnjd<f{<|++KV@>k{_X zTtcl9=>FGF2yv2b=U{>ZMgcow(4P&b;kh5&7~E>(oe21uW#`t4A474Io>Sk<^@gcB z73o!oSQ1hayBhMpPXg3}r6cjPKG~A@PknL7!^1j%H<e1rgvc5jY!mF?G{b;7<;;V^ zq=*3ORf-7c@=BP8hS0%R1)NF=zfeQvxsND~l+R6eNp<(tK%h#u0!Oi0LWC^2ZB$Y4 zssQLOMmR7Fq4fZ6s^%%Q3*GZpL&Yx?Q=v$f5}c#q(hwLTp&HmM#{->YVv5ocdLk?* zOca5OelY@m^e~>q#$exfOk6>v5yOkXXQ#Yy29x4A9*5T^qoTxa+RhO&pz#Kh?#euk z5~}aP4R!zf=`Ly~t=BsP;I-9MPwPxirD++q12UsU1)Xc2fh9s^)<cC<r)F&Tl(d<c z0LI|<DR8LbUvQ|DohJvQd@67z@Uj*;0UbhX%CAC@htS2r3c47;v#Dc#u+$%4a{I4Y zb_S-R6oCcQl`K&iPkvYt?6RR*nJ?y3DiE(6E!PD-tNNo-oGSM7D{l)=V)ndk_G8O0 z)g5Z*3#Qt`Vk8>k)$K!U+lF|}fO&oU5IgoEw%HKdbwe1755*9OA|Jz=pj9x+dq2z9 zW|k>*Zp;%FR;Y6{m<EAOHN+WFV^UnBUC5FGp+maIW*Uv$iswPch{^B%zSH|@YuiAK z!iv?K;$IOKz9)37I1R6z_V!MPER^HlJ{&b5*#jEA+4z##A8x@qTusR&iHd|M+X{++ z6BWKjV`rKKWnr#l{lN+>SxrSn#Y-qlG7ttVgf|5jSlvJ=NQ66qM!4->OOb5Brjz&h zQ0WFetAyrim7P4>vQlIX{bsO$I01%umt&Pkbt;Y{tqx!~-VoF;0(87B%XDPff9uom zm?^-nrUB#dsv3!E$eD~bIkPC?->>`dkC(ENQqS#ttF-3pk(QEH2U;c|V^TJ7WrVTS z;$i{qYWz^%r8l;mT1fhj@0-Z5S?-0%w~%d6?CZY*y=qCLW)qubPywwP$$+gOy6XEu zs3Yorn{GXPcSLs{;gK<hj+?93Q1*Y=SQni#vCZ#%4D+|w{C0F{)+4brC)42JSF9pR zi)Q=v#Y^oQUIFi_7EW1MDZO{Mv~NVE;eo7_E`tKr6*J%|Y1cG$IRy_{5DP|e#G;Z^ z)EpMt^x8QPV)7YL>dBZ$#r8y70L=>j%LQN0w6OgqO9{YJpLvpH5oJnAitF(Wcq~$L zlw<l;jKZ=2AfW5EzntnR%%$lvndVM+40VAR9px~jp`@`-Q?Vl6aB)+faZ?1`wKEoG zG%z*IE_$cz+<;2V)h&Pkvnz&U35^aTZa+1UXj8+r#)=rkn&v1P*u=@({)L~;*9^11 z-F$>7t8VdVrB^Alcm{oZMZn<grq#7K`^B8jJn4kY9aeK}Bi5HVLPO1;_D)VUd;S)3 z$$k!Wd}up;lWtQ3^MhAHtmJab-aK8W4SpVZdD|>>VUPq&2I}d0B<gA1l1XKM07$0& zT+NHH+3@8(T$G92a)BuSxYz;PTYQHa<6l$FjhLjd2dprQbHcB({A+o`)ooyNi6v1= ziec?iCc(@P93o<Sh#<D@A43>hly<k>UGJ5*gZl@6+2+5v1}=r?d!pr@Xt`%;`BJoe zDO$cX<T%vt)>~I-WuazRo$nldsI@)}5e41kXc9+2L2`ewgq7@mNoiQ17dvY$(Tkl? zlz)eFZFUkexzgy*QscX-Cy3w<B)INlo>JqYPQ=V(q%gAu1n8@*%HHl;tFpKIe`!^U zd&9oVy3p;AP1c3Wf;;V)M^ZYP{-u1*agq<?P@ZXK?H4;%`CZ2NPTcs{!I)l^CUCU0 zVdX4%+t_Lu_$8DL$gY+ig){DBbWg)rhK1tAY=jjh6W;K}4svdTYm(NrT?k!2$k9b3 zTt#$QsVq>|;9NaOzikgf(<fuJo{8LY6tN~uXM!~F^ITkF<f=l_)R|2$0Fg;FRTEU1 z1)X=@U1PYT-KOHaqT6FInrw$?6f1C-U{l?4gl0Vp#J=8(try!rxjao=+|-B}ZO-2g zu!+koHa^=6F!k)SneNw>lVMjJ0`T!(ZoR5pomv{`b<IFq<$;(iGN(6Imyh||^E8}9 z*TvP*W&Y)17fLkdUL?6b$XXH48D=+wQK*)lQz}&B{Y!z9%I5k)8B}ReNT}&62EDmg z5>IbfSD;8rx6zMo_!!h}UDd7yN45GLyrmuH8Pcrfk~Tqj?ICUl@dXnIxEI24TjbqP zD7|{_lgYGUwv1woP6tzgjq`d$h72=-+Kd3|B~;=!&R=nOowqf7*qbxt9_RJ1N5xIv z)gssvdEvdh?OPUlmIXmgi5ZPW3C=>6?>q0K5hefy)5SRK;`R6!)B@aIqzC6cx=&fW ziHz<YE8g2l2~oyb@d{_Kq3}*$aUXt=M)TYW=ss_{g4vJ#=?!Hi7elCM2H=E5=Zlnw zDXG468eOur=l7U@^*rwz-JsufS|BKalwNN(X0KAAOLtin7Hi>oD-{JdxDNL&<-hE0 za&&Qf*YOv5G7fQUDIQd1Qq&8>jI$^<&H5pVquFBif41hhkh9e*fwfxRu0n)^E#viL z>UC>vx>HzhMCHF~U3Z)JEw#(AT~VJdEQlh*uBvWX65rp|h0;Vxn3B)`5nqrSv9qcb zYD0DX)hH(xzOA|X>b8<zOETQU=E-x~a~)oD$5m6{*Gb8`8wNog24{Ub3|l9cpS}C9 zX)&$I!#3O8^7t%ud&z8;#IFX&hes~@(c*6cL9Opu<$Mh{<1l0Sx#nX<ahS-C7R4cB zrwTV6g=ydo*zZTzc^H$atkkxhhFQ+e*xYZ{u}(vO#z;H(9Hvwz6NBgyn6A@}MdlT> z6@qbQQO@&#Wz;-qo(7<uz0t(q>Iw`<qc`I!+!#M7kKdxyVVbu`8bFNtfGlUGhMs1? z!Eig(cydj*)O~aM{=?heKz6U8ADBfc=%o85pd9uADQMV$FIU@u%Dt=A9al{@xOEV9 z6L+dY#RY0qHioiJrmq_c8g+ldaDxnM{hDva-rY7MRT!Rxljh7s@B&bi5F}#|eisJ% zyFF`GNvl|aaLN)43Y2QMVROxhRC{Q(n8|x#vPeE8AH$J(85N;*))TeVZYcvKxFs=X z%bb{FQKIsyZ85Tzn5c9rl{XXkPwnvk9L1H5)3I;I1KV~)yH}2No9gd0f{}Kn0+KO& zRgr}kiF`e1J9S4<Jop8k{PubeL9DxZuX1^{`cX#O+kKL`wU|^!sh}o-d{Qf|JEcNv z1Ne9Y_unew8lF~<^KOH3RY*<wVjX><%DQD0cGUI}mp|0cCQm-~8>)3Rt?+wDUQ@KS zk=C`D&PHint_Cpa-}+Ts!>nM08fm9>23RN!qufa?l*`7Kd}ceMQ;c=FPqM{~XCAUK zx*CFZb@Zv<%&JzohxdF)-eEJ`M#xAQzgEd@<T^peNJI*GCOrSkJ)gSutg(u<h96kR z6_(X}VWRBox^^ZgV1ANi7k(Pj$qnmja47Io>9?3Q?}In(<Vv?1Hha&4uXm796v%y8 zH*Inor=2J!o-)&j8v$SKwu7m3O>}(9IYW`<wJt#=!CD!JF$ADe1T=bTym|03T;!>* zv-T>Ctj<y44xF#vZ!J^uOANq#2y-8AK(czhMm8km#5K-d;g1%{Zg1uhzUnab1H3K9 z1$yCs)>*6r7QZ$bZUvw}hB+Rx;`<e0<QU)RxQy}}@7F6|naViOdehsMK}MA57I*dD zWRC&{nGFh4ZK}RO;4cIJ*~W_nTk79eoH5RZHbDc3HSn)gIrGpCmV`g!cjl2EAlpvA zqq2Cs9u7P}a301XkUU9O#!2?Lt7~0xN5F01-U!*amZA~n5T@9K-iW0QaTA5paji(< zlT`2TusJ(T<G1#Rt>*tJ12x2eRYute8^ul=jhHSGt7A4r3e(hnm$Z(lyUI&!?=QGb z1!cIx^ojuo(_PKc<h#*sH8;6ZwqTHu<doeDr|4#&HkFcjZo`{bKs*r@Mr^c_onK`h zWtwss+P-0`+xpn#u42@#eba!$`rqXRV=CXM^DcrkZ$f*K9uDLl43OM>04lH$gR$2W zSc?l_XexGTP7mt#h|zRwM$*^YqR8dVLXg))Ki^(A(9WgYzXv}UjEdb{@R%AFZRA~Y zKk3B|kAj-Mq<3MUimHlj`6@?);;M5=m01mgVt~J9yfSE|5S#K2MK+M}{ff#pP9l7) zRVqplZ;OuUY4nD~|Kg*T7bqQNMzINiz1=1N;7di;24HWuV#n47^;mVp;k$;RJ#;Hd zWgg${Y(<o>3rV5WtlTPU)(E*7rIRuzdc)v43`CgB5dO0-L$eT>VHF<XjQQRdVHJw< zodi^^JMqd+4@YZdf?)Ci%TaRhK3}|>;?Ym(`}%3$S^u<u`19Z}oKKUR8l*q;f5s%e z)zGG<&QW|G#Sa=yt+0qKZ(0%96+_zS-@(er>vB2eO4pJ#w4lugW>tM>npwMV&pxf1 zj9y%I!PafSij_ygr)z6b4pn%_At)(Ro|Q_tswa4>I3}CUn=!tUESuiMPH)rsL2Qkm z{VWQcUNV~lU3Kgj08cFtU~GnlGo3I|R~sw;a{A%@FX43lD@e2KB3aR%#a<3}b40&K z<!sx{T(?TN@@;yKTg9Yi-+$?yoHo?jwj$!cTw26k^t0hO%wC#obK8dacR4&@J`ID0 zeCP5pRy`2I1#G78ZR__4$75@)p5;)@xE#gFnvvYv`BA`+g32ppr?uMZZnXX$5d{0? z0cB#{DU85w{b+dC$HOum1#ACNiXqe)6BX_eG%R0fQj<2tm-{3fiwJs?^r@6HOG@3- zXe4e^nojS(igy`^>99OZ{PASG<-v5NJKxq2svaURr@Mr-`rc#heGOE^6J}1}$KwcZ z{VkSLey6$S<dIfvsh+`>Vnh^80X8ZbEBedpj#8KBQlsfSU`ywAwB#*TtfY)sx#Ns= zlUsb|vn#bnA-n!~dP9XJ8P-Vo8TYGoHdLYI2Y&KVS6*VQ!hrV}mtxm~W|VlT_OFiU zCUF=fX{ec6+5pt2AQ-;af)nQ(6|eNScO7;Yv2w{bBL`kfBP-D5a}=bauuMC{douQ* zhhoFBGL9de?JdhG|EAMVW+AaJOVx~G<u>!u+uO9;qO0$)z>f`_D9%;0y2D`7IJ($K z)eD=5oLzyq`Q224=CWD&<wGh{h!M5KUEZ%-fMO`O!vY}F{qT(Y3|F<Yhr=*l@=_r7 z_7}FjYfCNFIx>9WPUAvKHq*W{0zzrP9_J1_yP?uZc_kIJ#!9w%quh(itAG@+jo88W zBuQY+bn-F-<A50z<fgED+}qMLS?xX{hwGf8ieS}#A~j>ZeyTaytY<m+^ljDdY=ujk z8w_I;5z*XUWn4i#>65GkOgX7#^-lbpVD%1~-?e(TN}zQmD%&WGM72;Ee{0OD%@C4E zH6fntq-69r-5ET!>uwBcquuI+6I5$}JnPYK+yf(;4cd#OlxAJ%EUiJ8M$1k;c(AKM zk8&)i33z1cuf`-54$(};N~#*2m2ox9nLzUvN@^LD%~yARGn6WQ$c?XW@{JvO|FZi6 z11R}AD!Vdm&R%bZ_3QL_h!$ohl)Od1{|lT+d{dXPAfDZ@fLInq@ibw#44TiLhx2Ff zKNtk`3TgHdDzMO4W)Oep7(6Sy+c^3ib$@uB`*Gft_Fg24p7V<&3weKp10NQi1K8gt zus!xVG{Q=}4lPbfzNJsaKv^<fhRv^qFu(Zz$VS4#mDAT|-|7c{)?j@U<H-nuwxD+B zeAAhL|Ca+Nl`yPgj;=ysF$WjG5gxAU5FaAN+NB|sFnqj}L#Qvf=CAd0JN(68oE58O za;15TnQ)hg!PU3CAXmyMDTNL;I}Fk$_mM@ovrdOyvq~>gq^OEcD4q_cj%IqFQ|n1) z-h>f6pUv}|7I-goXU1Ya$D3euZ?pMpokUl*2_>5RPj=@=7`IipEAco^YWDgyb)e41 z{{m1;0|XQR000O8r)_*zaBU$LP6Pk|6$}6X7ytkOb7gdOaCC2PY;!MeVQpn|aA9L* zb1raswN^`y>n0T5=T{(C5zujws_JfTHKQ)7R$Wx8s=J$x5EJ8s4h95xGWqvCfNku| zqrHn}lLWr=`p$!+24{UlHtc$D2h^z$$Eb8bs$6J$+)Y1Kls;Ok!)~|hwTMv~bX!l^ z;Utt{Nexej;!#UL9<&Gn{boWGT1)?Vw?ptT!95+he2Jg|f0zF;7f-m{cCtsRNN^(t z8JsxCK!Vgg{hSe#4v<cVj2~s>867xapTrU1bU~^f85@&8l};Zo<LJ$D)GIBMxfT`2 zY+z2r6AMm5KrfM0TTyuUB9y)oMmLjBONa|3AKNjyF$N}_lcpoHSXBg!Gi7>9nu#=J zj%Xj67QKO0Mh5V75N>hK@M1aLwJB!0TN9CCoxgBDnk^gOAfeCV5)kNs^hJr{Nfr~p z$TMVH83d9DBsYQ@iiTtyeT&}Z?5yGmSqPg{rtvvqibO#D)|sB2J&>NY&bpV{7|p*| z$N!zositPN@&!l;HJu+8T21kva<I=IBpB5D1d*#kS!h^0e-(W(SbQ&tA~w}V9GnJD z$bxUC9uF7Db-cKgatkh1z)1u?^r_eY!=9xN${L=cKzE4z(4tRt4R<Tb|F+7IJ@M8? z3VOfY6KHknH~3;-t4ENVO$pN>&dUww1TPqtMii!Rx%a-zAPy&}BY)Wll1-kP;mUlo zy-uMIwi~q!EXW8+5TlL|8<0wUdkx<@JW29AA%l|#@-BSwmHhz({-R7LJ?r7C$h~Lp zerCK=KGh0w^np@ZQS`&W2W0)%Mx1Mf{hkqD;P-s<j@4#Jg+a2V`v;mi9vJ7HIzYPC z7BJ^26wYxAz;&vL%bf?qXmFDTH;+>{BTEZ4WkB{|EzPoJTFkGD^v$cj-~*Ufo9@6v zHUr+ltLMpzlY0nPcxfW_4=vggNSp2wF9XFJM?}}D2puDIo~R^HbUwjI6{yIg>DfXG zo?ZiV!2Io+t6onX^iHSeL?uw~Q{um;tmoPugbw#Oz`%owzz<t}>xUw1ZBa^HRSjJV zG{n(qnUY#YC&3J_CS`JI^9pAl>wRW)ex?elQe7=&4q5=X7G(|rolJVTiJ7=;cRhWJ z%y!PMtlhjeS2BCe9R3lP2~~wD+M_}qq38zTzYM<0#PzOmm6WD|$zCQfbhPa96NzjO zFRWfNUEeN%S1O*43sq?w^XhR-@v{ZKSS?NTYUXE)WZKY3T@4ZqSxL@wfWc6L`UzSg zs>2}T$#yl&1x~hAv3B-X^_*+CHrC`@i!Mq+7E{+9EX*|nxeAGacoK1y_l#zBN4UGY zE82jAWocabPOxB)?64|@BmtdC@-;=bxB1^a78te*08d{a^H7Dp_))$YQL48v6<@9Q zy23zh$^zO}UI`blrIs>cyA9<d=B$J6nAhT;VXe~EErF8d*F^Y#X?-sp%%n7zQkv!Q zm<K2Q`b8m$Lj6DO{sB-+0|XQR000O8r)_*z0r$pI4lMux0-FE;8vp<Rb7gdOaCC2P zY;!MgVPk7yXJub$Ze(S6E^v9(eQS5yMzY{{{R#|qJpgPHvJ@vfql9)GTTXn&vAure zv9gAOh$e|K2rvLBnRa}C`>jVmfhMJ7X3yE>If*HvAJx^>_3px8FnGCn`7}t&EXeX& zOxs|UPT!|<5oFa>SyXA3m-A#W80_uk%T-mkL9=Pp*Ghk@h5D9Py5VBo=7s*Nn!XpU z`s*TX#8>y!UyHO^6#0c7q7`*pRfQh?Dy>TZL;pRk%2_^NrFA1}Jx04M%=dPcOp9EU zdct*GzzhlX>HJoU-`1k(wiI<;)qAtLS_ZRqIVE@k1y7x>8iNqgu2&2%HDA4-PioOr z>v}45muN45&!Zns9{uCR+c%TPPhY<o(oc``rmgb}Kvh-pFW)_V{_xeWR+F--muZoI z6q8ljF8H_CFW$a-bYe9+DKGQ7DwnWk{$ZAv*(9?@Z}|5nory`AE`{~yrKlS{e_Ksv zc_B=bSAZa(4KwuPlb=qWy?ANQ{{8pXUxZ~dXv}y)Sdbz#PKs*YdBRxN4IZoCPpr)- zmuWj)s3vWlmQ9hif}fhbNUjz_6sp<J_(!ja_yCkvCd;Z86HRog%eu^gE+zt(Aw;>i zw}*>-^6KIDKb|~)6O4i8lWDbF0ji=p{HK`D$I<EN;pqRQqmOq-f1f0G{&IFF{;x3J z`{C8elTLd$P>Wj3-Zi(!@ZV`TIC~JC{xclh51<b`9AfLI@!rc{Up}4u`1nh=J0ZCa zzexieWITYbgMI9HAHID9U%oj=@4qYGHFw@c&?tIv+~#c|#seG)58Hqq#-SXDM>+lH zgR?vD9vr7rq?U2BsIDf<?90EV%hlIeK8GU$3xt)WquJS~FOELLbnuv_f|26Ax38W} zUIT^yc;Z4E0$T1QjFq!bN5jwYaVXc9&|dDH{PO1H`Rk`Ip1+2kgQQLCWd1Rre=j~B z(U&0kn6Kd5{No^LRz==M@!sBKk`~2e0-a82CE-ivT~EtQd<dBqLplOgGnrNO1kSel znQ8O_pH8lFU@uLp9_1y_!m1W6AD@a&3p_l78DGD6^pBG_lQ&O)Jb`lzGar5lzqZR& zfuI}OI{0MK*+iX%$>ekJa?>uVa>Q)r;L~a|S*HK0>d%9{HL$Y@fM2#S7LA$A@aVU^ z;i~00{Pa2b^f^=yZv#h8)C74stKy+W<YS9H0m}9=F_Y)BHphCB*7K-YiD`VyETG=- z7oraspe}7Lz-*K|P&4siDpqaqQ(CMAoz)<10$~l2=8fna=SV-r&)|9025A5^G=$Nh zA@KVE+0Zb6(JW8{ob@=kRS$w&0f8`#^+<6*M_f4TboMyHy_BnjbM}hY7NI;Et~L^j zG0qu1uSzk*|G}v6_o`}|{Gt#6uniI5FeDXmprX1GHS8Jwn9v^)!$ia4#=*ewFYqa7 zMdMok=P~jb50i*8Yp(Kk5rsHW7#l45n!vKYIO;Z3Q%jIek4J}h&zz?cl#sfI`jIH~ z91R@0)|q9r+Q7LT9e&lBiI=D58vU>1(Y>=>pnUa5L2;KmN|)JJ_inJ{dt2w>A#Sv6 zZYr04bobv|`qB1XutAasu1`FYtU=V!Iae$#g8w97D})|~wAGyi{@??P?O5nf7jT%6 zP1HO%>J``--~`^+3<D5-^=1giDV;BwA<@u#)}q`w%HP&iD<T|8GU)Iij88|0XR)Gh zo-G)|idj1X_~#-iMH`X=%HzUQrFw?PL9ieE^2;y5uj}diy$(`uHvf^CKim(4obh_> z4Cbs8e^4Xr!>%93{Y_EL<%V=b4B~kh04CEcZPPKa5Y2IZ%|(&n79x*fGz7Mm7E~Ai z0yVq|+655DGM_I%TNc29)_|c@@<`-7Uf{i?!RjDPhw~r?Y<P=mn&P|+G!Ljix2SzX zU}HyxO*N}&!;0BBu=OOC@R4d9+sup}xd+OI(kq5tsevCxHV&1{>uSA<4r8+dAZjpb zL?+6q7(3dxGfwANcNW~=WQ{cSg)v7e^S{0EI8qi=r5;l4HlR%X<VcD69F-%R8>(iK zoF)6YcZSCaXIuew2~w%9890pTWQHSsa<Gw^XdmD#HUY`9H9We==j&?Sn7t$HbXAE{ z+vrJ9WZw*<@!2kLuNK91;Id6HW^*7?&mE#HK@Xv3N#0CQg#~Cp>PH<CQ7bv?t<7m> zFSJj(YOQ0v=w6dmT_IHv?T;BQ`=@>fslv#%j$vni_JgP8v=+!oS9M<1c?-LU+!;2# zNjzZaQ>0A2;7)Mpj%)C^bDuhr8-(AaFX~XYWuep4;Jn+WMhWtUwh+&rcgJqXRSX## z_$;O(A+=3)4Ymg-`@x%f;~e@bK;yH-&1r%NPvVfQ8_<5+X(D@R#tm(eppBj6D206_ zLwk>I)Z+-j2+VwHe0FnG?L45is5~WhQ(7x!HZ3v_M^zq&NV^_(^HHsh{}G0o25NN0 zQYENf-mX#N`d>7JAZDs2A%#O>!hWW}-(xc1CGViVU3gU#M<<&t2kS)Iz93D7)NIe7 z?R!y*I&B4UewRH5)eKPMQYX&Oh6xyE;uy*7TtRq_hm3Ivre`abf!VZ8wGNs^wT3O4 zf^kkGoS!=`v802~`1~9<Cr3R8AP0t&!rp@U2fwrxz?-w$3Bnz$Lh%>1qCH3B)rUZ; zZlh4^eaH_C{zyWk<tD0yR8Hz}wRxAlOWtMw1^V7fntOQQXz<gc<FnWnc>ot7fZ0;E zUS14oj<gIKQeH+Q04Fa30JtL__9Qz%=N#?CD!+uD5ll+@9s%Fb6FRMA&f;GZ_(b*x z9S?Z5^#BcS{BxGq4S7(PJm4ZlNV9yNw~1yaw6;1e=Wv>V0njRA*U;pZug*@756?gn z(g0l<cmeW*wQ^C|D)kDs!;H&IW_8Lh4*Swi)4l!$_A~icmCHd-k5^~$)`zQO`=NDm z%vbBNIY;KJ^;jJzhr6reEPaHR==W$M^b?x{NB{m@rz<=v=t0I^Vk$u5PD}E0r^v&a zHR#Q>UATpCP}W7u2Y?&UP^4&~H<EGL$jNE1rNq{U;#=}iGeGnM0*k+`L>=8u>p56> zw{O3{!f$cU)6?;M(lEVVa$jW^IX0l>)ycEIuk)Me^q=?7Zog}4QM_wD-5nm@{XAA* zjQ2CRe|9IPmhpYd35v^lCFbG-5icO_hc`by3)*xZps))<7<4><Js5x)*)n|rm!WQZ zd*3>HM7u_warXVD#iYo~_YGS=t8{J&nkRThY3xO{6!>gFyn}vHCh8!d{&=9yvB~+6 zw+FWm47EmY34$&?*JS`mN)QU%;K-U4Kd>%bII5|ZRntVVwM_+byhgOqGF?S*q!Lo< zshjdYDLyz1<Ji%ZLbV#wk!dUd&Dh-P*S=w<!AFO-fgb?gYCm=T5Ohij*BGzK#I(vp z<Qi{^vT#P+W0)@*eA6!O{{V0YFL4`&0sZh;f=m{%1p?>>q&m(80Z9NlybYfJWgLtS zU8t4$N~>!`T7zi7L5A2NcAEN)*MEE2d(#3$U+|~`@m#i#7GnBd)GkAL7?kUxzz7&N z38vhJnFr7|$j8P=_*ps?ghy(IBq{s3+=9-85LwiSVg~95@Z<LuI@Q$pc>>K)@?jHH z8<0t}kQNkJNW8sl*+*JXgU2!F3AfBdt2g5Y(o_2+El|my1vCJwFS8UwM>}Q)?RzcE z^tHeMk6bPPfyzAaQDpLB8$h7W=+?}6(9?o0c#^*tAngfWwI>k*9=MiDv%YBByafi8 z;TAFC)Wo}yCyC<+7*tY5<PwT@0k+85JP{)rEsP$#{01Q-)$@L{NDqI9{~aCO!+*Z` z8~t<i<yZL6mxo8cFS9S>aoFiEKCD2q7TNvNbTq@Tj*2D42FsHP*lX=%BJr%JME^eb zwh)bN65Rw~*Wde1<WoFgrMQZ8%h+wIW<jr*{3?YbAre%KMU@%)M<)b2%%%lMIpa{J z-2glTgI!P2`xZ&dV?zfq?i^ND*w{y>`&<6G?S5JGly?0PeHWWW)9%EUcu;%{R+30! zQ0&a>hQpaW-0Zq(<a3xMx_#T?Wm!H2O)<U^Yteg}KtDJE5jVJ=Q^?6p|AqL#G0G@L z7qUYEf9B*bn>nCRJqT`fD6|WR8Y_Z+hLPLh$jA!N8y(}JYq93oQd$Djv}}SaaY2Ht zVb7=~@EV7G>%-=t)~K;GFw!?DGi|$Sjt>r2n^m4v_57g8VUglsU|KJ#rftSicsm?g ziu5#{T&&Bi5Nv_!-$6~xXPZgW6l3JG<^ijW=1))^nMqg#uwId}qT#pH%+7h%OMrbb z-|qy2gTd)B5wZT&@-`iWmT!Z`LBy6K!*-}9eERG@o(XbMY<n!TV<x;Q{pTPgs;j0G z0RLT@C#bFIgoPoa83ezKf;;21)dT^>&~^v@YK4}(;UzMC1-S`6GBlB9>ewNTxfbla zL_<3->2N6<vN1ZS9sk9TlhG03c*?bCc1Z?-Pv{?b;$tVh11$F+VI?S)f&Ap@FF&3f zyAgf#d`?BvP#7Og@V2S~L~;R#COW)lOdYGCL;)#ZFln8GSu-XrB0gsS)Nko=@aXS% z4{hmtg60Aqd}8GR8PVG1q>kZ`%z<UPxe$72Fvo1+4eS-EG%r20hn<mZRo9*P>UBSb z|D6F9kZNO1ha;LyjL4N_hKwbGwA)R`iMGt|TKI%#*e)dW0{)FW5wN(YGE<Mf$}E8< zxS-#pdhdaH3s}ygGI6n<M}sF6DnqmEIJngeSeozIIAYL&q1x!jzwN!U8G#E6t(Yt? zI`LV?C#;Em7(^P&sxoYY5_M<P_tI&*P7C7ed)=+ujfEayUMjHg)McTwDjK{Jl+<V8 z=0?NgLRK{(3KW?oIw;`S1=JX=ZV;5M#Xn>|jJD7yuM53=w;I@#TMfF%UZXuH`Dug4 zh!CJ+oqw_Pr(kSYp9!$iB)8lZU|bS8!#4N7-7s%3oRF4N5ix_%X@AKNZ{ED5Bo&S) z%@Q=&P_MXm_t3K=jMs;2*xa(s*_p*lCJF=~X9+0=+YwEh?mN#RT8yETZ!pdRb`Lmj zG6(BFl;+&1-K<1748ky0=6}a}Po_l$ie}6lkFzC*pk07aN79t+0GQWKB9ei3f)z(v zq^J%+Gfo{f`;Vke4Qqfl>S>!6=Gnjo=Fx!|<5MzKD)@pnVUEPHX@OKgSqiRFOa*G| zq|0P(w5xsIvLBpq>fs^<R#1XmS)j;kfyXz^8VD6cc3vL#JIZ#L#z9R+hoRG^&p6#) z&W=tf1q1e#ABU8P<R4d}n7ka)p`bw?uzVjF#A^aDzifBtbR1InL2l|XUr4Lr;Mgw5 zhCPxae()^g&<=&50%xV+xXK?N$T>zX+8TE_#3@70q>9n4bMNlGuI@sZawewnET^B* zntGCv^@mwG1P0!KHKCLTOPx~3NA)4u!e^oa+0u0BUxke*(XEMQrH{>H(sM*<al{X$ zESr^HF>TMFMn|uGje~1VgBQ@nPK(B(>I4V2;3!vTBBU1zD*(AbW0Zk7Jht^5C%=-R zCXv2+%sIj#;~{Z9OGYc*!XF_l9dhw#6+LZW3-Wdda!n6X7F$~6EN#=GM+FFONAEIF zG7gXkX)hXmI2604v?pv6+DlXYFurMwi)e=v;qWZ>TJerlVcWKofBCNDK;L&86@CLL zjd~qT3YrUAD_;W~A{e+m(Vzr-@*;1OVsmh`sGly&U)f%TW11IDoV+VdA6Hl-E;|tW zazzp3j;QZ5Rixvlo$KBDeC!SpEh_w#<TTV&E9VxVi>O+Y<zL+3cTT?{O0+#X&f znS+q7H~j-ehmR7n>ZbRQ`uL7pSL9K{PU6l8!3kpz)`{qKwmWfJeFPjN4b8IRZHSb3 zv=?b-cEIXTXY(C=ZXBa&Ri{@tm}t5x0Pg^>u5yI><tCt3UBM)@6(V<x1LWP%h?+zP z7$o*EQppccdK~p&AP=ufD*={X&CC3w$i5C%>vFfcgh=AWQV#Y+vRYn*BZyVXTmR06 z7j<&nIPP0yi3+A#Jl*Pgn^)TJW@4Yv(Ml-jAFz(8PTnV^2}ueh&TZlNQVK`5q}z&E z2r{=eWUp4LuN;v@q<TJoG5PV~n@2xPUY|UF^Yl4|6|JOcYX@;-aM~SOgO@4xW-yzg zvI?|>@Fkn_Vo#BPx=PCNnU#d<#@|e2oal`-JWfpI==I^*9|d-wap~d_h%PPj7D$yu z4to|Y{eJZxg@C>cBtz$S&kU@b*=*kriWGz$OU7}EB|z*z6e*a95lo^a+%Wj`IX*>% z^{gDZLhIfUc7z`GF93o^OJhCG63!jnbubtx`lHYc+e-~+ywJ@zit8#@Dq~ZrbE$I3 zk_M^6HFC8h`71Q|lS*~Z%cc>^2kK8n5#6)hyO`0R5XJqTO%_A7^A03rI*PJc*Md@V zBvL5y%~<JSL#5ulpL;2KFp&9S4GfE3we>|IM&#o{^#i%SP0)>Rix9h)dB*M(4->%+ zDaF-9I(BXn`8Si;l*9Sgz`>k0CjZ)(do3sK$!p3mx5V{o6B->I2lM*KE`?|F@T1mu z2UN&?yoPqG8Qp3^ydI-=GwyZto2B@nZAV|##J*G1cMuwd!C7nfRI3|oNwdCiRih$Z zUSw&oJPyoFwp-2qGW!x%Ft~rK!K-DsjHM#)VerK;IEshv9$Rdo54L6v-KY~m4!Uhe z4aWQeOtS~&mlZlV^sqr>+C{*!amz5!tJ1D;lCKS?=%~iz!iO^=?=NM^z|ELN+VibL z1IOTlIxDmOZg(<v=vIXj9FdNqYh0L^z|eT;tfNBnblV(WuhmiIwIfe03ggj>h)tkh zuT9^hC;e&xNQ?)uXCsuO-jbnK01;2E8deAI^o=m@&h`fk?%16`hHKdePf$$zeX*`= zL$8}X%6qZtv5hB)g^Luk7b+5;npglsDzk6LQQ8T%o&5bDhWlrfkLw~shoH_+1dR&% zs!au@qLLPn%rep95v+;+ngE&!aZWglQdZj==PJRHN0Z8Rvn33JDDEo3`*e5$kphSe zm~)S&78rZWRL)8!8a$V3eLHr=CCTanEZeeAi^G7tk3}JBJ8fAH2WmD6)UGSop>PL9 zHind$fPGFoxH#(_aMjvs*gx=A0`yiF3h=_L5{*d|U~h`EY_<qGqjGf54&e=H;5d=^ z^JC7!Gv(4uFzhaIEt6}8R?2ZZTWv|%QJFZDt?MQ->}sD_X#$LcVKDef<{P171Q0?^ zoAr|RMf&(v?sxY*s$q39Lst)+t$OZR{DA$oF3HO74^3FU_Es$|5TNZOO98<%*k5-9 z7PariIZ@k!zn2gCjX}pytD`gw-jVHT@$Ld*Cs;k9Q((JiP;R+f`!LIbbNu;SonT}a ze8#VG<hyvEMaV!Yt&-W5XzY!)*o{{<_Oa*$<z;}0EUy_xQ7CAT78vc=1cNy~t8nK; zA7e7=*l`uoO{!YiacILAL{A6Gi@fm-)bW&)1MxWQD|^s%dz4mAop$Sg;6}K+<%^nN z$SasvL5fifQesUk2^M<gN2JSD?Z<w-6d;6&>Z=^pZ6Fs>tFSHLsl|Oqu3qolwFEPi z%dEr56+`Z4BBFLf)Iqmpv$Z-kioB2$L?W3d!Dxh(J7P~+C;D$guq%qJFfw#{#2q<d zvO*O7QN9`AIlzk}{(V?3MV144ijAcx_XYDVy-F^mFLMxtD-i<qW2QJN&V@+fKq7QZ zZO)o8>24_f&svcjVuGF2J4_md(JY8n)ds6XBGPn}6wR|!#xUxf^74$5`OCa%RstkT zwiTEy2Oc%y{@pnPE~!a9P=knbLd?7m;=#77atH-0+gr3#pSp~ufkniMQ7f-D7Dd4D zIGkvgrk|m6kQ_n>b~@QP_8^XW&b`iu_Du!JkC3GsjZOAJ_5K2t`}1?FKm^|Cq03i8 zW-aK@l-b8=E(gU@4|+7z*i_XA!~LW*Ar~R*y$4E_?pB1*BSm>45|RvZQo2b<{vJPw zaS{YiXYx`H_Op$A>Zj~Kc4#A4ux`4ZpOejvppGPPFf=Bv6C}gHc2<&{LiVu|*mDFe zQ~WZ)E(<Vn=V)Alftv;Z{ACV!I6o)nF~EGiQ<SJdlPy@bPPtCmwr$(CZQHhO+qP|= zvTf^D_rt92f9B3ZyngG8j9i%!J0kbCi+QPm8CkIoE+2K9v_RTbmQk`?ETA}%&becz zZSEgy2lyVk#Gz8N!8;T2nX=mAJfQ9{Q4R6JVP92AKqgf0EU!#gN3=|33r<8aSFl;c z7y+)DP`ZyvBiLkHZxJA%=;AY6MXeuf!W?H#gCiqd7}E;Dnroveh3;ZaCho>4bAo(n z`IR*(PJ5CL9W9`6oKrA2Z#SCN0nR}=ekZSXEMif|4VTRZgh%OzX?Ln{YR=1$S)F6h zT)bW%?&_+r<z)<fxk*;VL0~QTi)gd7s1#H`aumXo|DCjqjp&(yF|O$wl%s>|GDyBt zbUtXpC~de5V7I1cTXZ2w`iMq|cKERK=4}qw<|r?7N+tT(nC`_Hw-8hCjLkd_^*G4{ zROu5Nd7N0y#0&G?Y@^}5)4B!bH>mIKlbaDT{a9>m>z-c|T!zRV)j0v_D?Eb(7bsT` zn|!Npn*PGkd6r#N{o*L%+)z$v5{jCay>I%e?>Du>$DqhxfpG$wM(TCa{9y@3AtPT+ zvixz4v=3AjuWr6lgY3&c!f1YpnrgM;F4+nx51C#Ky><!2`t?tvzn!@EDmRcg!9VHX z+E`naj_i8(c3mN_Af13cA9hft#xXGQK~H5@m_}(aZtX0l@DFl|Tw=>#$_<7(gnD8W z%fX<hYUIQN{yW)dE^?}v>MY2O=0&>EYdmRaEHrHQLDQKHdms%7K+iCQqt+e_@0uit z4jZx7{Mu6nCXFzUI``$4vf6^{7(GIOphm~)@x5X*au)H6zELPOK@l1(blu_ZRDvKh z7>Nemisw}~pBUs(%ejWpc?<}#lBk)Ig)605Vz2aD0eCH5Xpi~z;TjlMIeIzga`F9c zYG@QscGgkhS&MiWkK8uEc%<pk)rI<$V1+?|<Y<VM=ziv6alBDp-d1=9J<1h4djjp_ z)O3}ixs=439vbZ<p*02UtM*wclpk+66^mmXDm>BcwF;CGsvzuxQ^7&2h{>AXco{&F zP_1_)gS$X@bq;6mHM2FV`OzK~iJv5R^b}d4X;dfnT^P?9v6fXt5<y@E4odHU=G1UH z7YXTe^z?l2-ZkYJSrlmfqW8`7=z_A*6_Qtst`UC-Y}D@jNby8W(u^xCQ2fp9f?8lR zJa?4RHC(~d(Cw76l9MBi$Gc6a0)k0Osn@6uv7eFgAGvP|o_-x?2=M0v)U^TyA0|V` z1f>>B9w^0*gCPkk|Ju#x?n0!u(6xf<z0v2;&58PWlkH7p?b;q6C*av04T|EdJO5`P zv7!JOSo<9+VSUf(OzJ_ntL?AKKR!P5_9oW3kAIu~nU%AklQ8vI!ha`*ZN~&*XBpgf zEyN&V00uWYDlgwy14~74vB0RIy0ME88I#v|$GuN(P6YtU(4!B1ed{!%@UD``HT1p1 zwS(?J8QUL$xw%1kE75t$XDsj?P><FWR(}kbDl}eOF2#^^3*(Y}9K)aY$I9yTaJWC- zPLChd@^d06u->X6rHF)lt0>V4M`TPSPOO!qKZD+n0V%Un(cZfdZs9ff!4gj!c_|j< zO~RxY4k?UK6)S+nQ1=R)Y>@R2Y*T!M-?7CBj@FKh5!O$GbeedEaL?;u=Vd3iVTsQ% z!$da(9vVoQrbpLi2XbS+%cc-2VVqpIyU?2KgU=qA-!vI_>x$j2>kQ9TI4qZIjhR^g zmPX|r_Ges9(60SOE6(#iIh3ZYg*wh+IFCJqNMX`wtxcjW=b_fI*X<IcKDUI&-eXbp z{iR43f3))&x1Zw686ZwGPPNbEkp>uDd8G0Vt#2grqQW-B{gsC{Y4J>@Lx?b)n<4bP zn;y<zz&sR1;?_m28ii|j1zyLSG^}GdxIc9WkASfZG11C39V(U=1dgcS<~1Eq6nvP2 zK|hcqaP}%WY`K?jZW&LNB;hX|UR(rv7sF-Al_|TF;hmWUK4YFLDWeLR4;D3_)Vr*s zG;_?N-Vp$Ex4An@APj2XRye}W3tdqgU53FcC-9tJTrX^MRCy}4n(haneZSH$M;>tJ zlesTWQ85RNJ!srhm>RY8j3zK|WGAKLil+rmwPXl*ehIH&)aPKOcw)4T7Gj=Zz${>$ zG6KZch$_Td_vWX3ZK`5F@q@@Ty_EA9@(fs_XV!p|nJ<Ga1ZENa45v-rz>Os9?90SY z)u54l=cF#YmJ5^y5<JvWtmo8`Bx?)=o~Zsx4d8(La(;fqCo|SA7q&RqpphT1jAI!z zU)H0%pYH5z!9NCT4%<bW8Ww9ooTuu%*Gr^gYzmtoYGV|mRhHs=qB(kg`+kTVpTld7 zcdcJ*BIh|<br}5{Yr>Mb9Y)TiKzbZ*kFb26`j*@t7n0N;E_2OY>`AetlJ{8ko->PF z-SAeOG;u)3cKO3Bx9aW>bbMvtH!2Ub?|8BJWnNQW{poyc&@$!nm%A|k(IbZ2-v$8O zzoj<cz>D1}^tLE@ESPE$K4~=W0J3!6Kvq)-@<f@MqG!{l(jF@JwtA2MAAZytqxV21 zbc*ej)$%AjapnRyaIf4kqDoV*llWV~9kgN8i{9cD4RA7mu(OR3V5YS-{c@!7H8U); z|JM5PS^sQrxbo9_4vb9RDMM^`dG%u#b+|iEI2rkLT}hYFj`!@=?xqT*vP`1_G$4-1 zd0u|r0hztNa@3#&H!}5KWy)5N@EqX>HcPlS1A;S;ZvL(_vsG!+<ldv^lr=*^(LVhK zZW@|Rq&BuokfK!rhH_yo-V)UoVg^^CkZ0(mgi<Y{<Eu(jr!^W*;RiBr5*VZ4Ohr2T zf~FitSmoCMu1kh~ru)Vmy|}f_<Y1aixr`ZU#NjRmLLzkp3w1xkan@ihm-*dPnVeur zrW+i9xR&Z4T&*8shw>7NA11`lfJVi<Kx~E4n8U}}s9bBdrt*_cCeN*ss}A>&oY)_L zzhtPdxWYgQp>S8lde|oXf_RJ4(?o8Kat13!Nx|Roa=;iIO~=4)Xx9Xo?n1s5SqpMK z0@31=uBbm`G(Sv#ZG~8l!`z*821S=E#gxR+RzrdRQuo9eg%1@jb6U%vsk~=iAaA@0 zz=YGkfC9eiPvc7=b|kI))*Q>zegfY89!UQT;O8U~=va8WJwth=2eegUuq^4)(R0U) z1X2$Uxg~;-0y|H+$SHf6Yiby-ozWbpEActzJawP}S8TKIKU$3VZ9r3<bqCwXx_rW7 zIL%V^8*FL$h*9<^4QM9g0xYvu4JXCjoJ=FrE{VYSB~{5ASO>Cgb6Pi#14UW0;46)E zd2<<G4SWXc(H=5sf}zCSLN8aNI0vQ`iThfTli4^nh5NEIlp8X@uQ}}D)0<1OEE{r$ zo<S!q6g>8}lr3HM|E1mQ+&5lKp^s68EM;1@65C7-%xpI;w{+7JXGJl;j7G3p=Yydu z>VO^de+A7umcM2x(Abv5Q*%9z^18eN+yiVfINng9Am5R3%ZNRS7y1#;ENV0PJRASf zqd}ajqMa(1Ot#;;NGxQ}o5)_-V}0Bg^rGG;W9vkU3V7|Ov`=3oyJ_HjB@jrM^|=t$ zt$La1CO(4Ss_5C|I(OWv&Y6+f%E~W?U$?B7Q#~I}K^xQddt3HvEv9LZBwja$>+(`u z#%o(F@872}e34hY@k(}%)A@P)M+PwMF-#j_t*0iX-S_XLpUw^1Vq^B-tY1$_M81*5 zI_(ojx1>QW>Lk?7brNPF^IUbl<W!l(!i&m^0yP8Id%j{JIQR<jsy2pmm5%76HJR<- zHwLr%8YSqJY#-=Nx>sv4=9?DA!)x~aeHk_=-7h@Z7SO4Ff1o2il?*eqR}JV`1H*oS z@~nSzN{w^0LXEs;1`gbcUXH}g!>Q^bTp6r00opAlH$kHy$ImQH^|0Mkr%)wBAy7kx zyuXLDi#<Y=2pdo+MI9bK2VhMF2PP%6O3aU`7s<BzEgxRdwvNNcNRY5Cv~psRB#Ty` zU-`(Ud@ev}#tQLbqL*Z-#U)$j{It~_Pj;(l#20l3R&CcDPYeiFuwr2WAQt!*cKui8 zQ6908Gx%9CR42iOCe!@Ad1=JUp~D8<o3w>Jd%gCm+ORJ(pb7mX?_;E^yKKP|oDlqX z+P{Ap;2fknXYNu7u4xB)!M2jbBtO+A927E)%@!M)-{jtZJ+-E4+U(Y!?he%7RdC;Y zj#~3ChnjZ|=XUNP8~D7{m{5dmOVT#ypb=~d>2PQ_!nNf*--QWRw5nGvISL}WHJ#K( z!e@f7^rr)~@%@FbV8zQ6>uX%C0H*vJ48Di->Agh@cUIcXJm+B?B`&K+jIE|S>hQdZ zbin;h)kz9nx&Xm4a3t|>MPh-Rq5p!@+j-nT*e)lvgxUfYd;{M+>DzdBYjFPj_*<bq z@JcgxT>M}cxOXP3?w|<yhM54g&6{}y*SG6+3*2Mm&q9Fo{}_S{GQ&G<CHssg7i3Hh zK)8e>Z|ziYG&XZK-#wEUzhrE8-&1*de)MC~j1Sd*@2+0v?*$O+FOutI2%at2=xs5| zE9TfH4MZ(^rK9q<>qKzmUSDO7!fx|xg~6MbMw{c)nh-oQJXmI3-bo?NVRFz0K>hr^ z64i75`rdogPKhyr7nPm49_r2Q>6C~Oy}h~s*8>t{ee&R=uw&laYnw?P8d?t6&a^6( z**eNr`9ngd-=DT;6%3JC$?Bq>+^F%8B9sjGl9p3PFZggwLT-?w3-t<?eV85g@p7{{ zIBzSSFvk;oP7N*YkT;Pgx81*WNXMRF+x9C42fuO7jd1X~r@MG`Zux#-@VT}7{ruf^ zj5%!#);rz@r$8h#-6AqG0|QA4)q7c()AXj`rxkYCdoW0Ah$Nor^jG~xdUM6-gLCp$ z5hdLs{4;Iq&`~=?26jPw_Si(aHvMze`l@=lBrWXb%S^`5Hpr0_VI|>Rt1=M#MB1v` zw28V-waFM6dg#X);wK0v(b=GTU}U<u7_GM3o&1YGoCg^F-f;vzdD!tHGIXL0s#pNm zq?e1fWReyQjkov9;{7Wzc9FJW^6cI>R#0cS5sDU_5Z&vhO@3TdNsM?HW(%1zCteeh z=+E{%xqgR=_5y#{Eh3YDz)A-YnA8L(f7xEUx0`BfF3tJrt&Nnca7X04;W%jA+3qeJ zuFN~Fb}B7VY0Z)iuJ^N^#Qc{^g^^8%qy9rZ7NtG_QU5(|x=moZx$c%EO-~1DX8NBF zq;d+SbJSLD95B(#cx4oO<`77TCT4U(CvdLn3oLIg6?*S!Y%?;-d-(?0#jfQlRHOYe zkKW^G6N^x|rDH$5$qSGzcK&$9Gr9zZD-Y$cnM^ot+YE(4SYT$IRq85@-JJ1S8(`Qm zwb(r=a3E!wRZrm#M*o|1TfRPLU#{@=Ta}`a$jk%HcpYS63|jxSwnF!dx#OcnQDyeY zlli1?{D7)N)iacz&xG$5jE3kw>gJ>z`9oOsL0?>=*Xulwb8FH!bk&=jmL#5M9jlB} zrCcE*7;m`H*Y6SK<wG}Ib}qw=`OJB5?zq2O$Ki`M2opv(H46-cqDrqjNeGmHttO|s z7!{qVWyT588GD3h-fGJzd@D9gP~)M1;N}LXi^C>_r`UP0rpBi(?AYgvGf9grnP=0@ zQ6&s}x~RbMf+F0pd0qA~CHF~%qbwPQM^39-GadpV+XuxLi&AvdFrsO@5}}-^hN}@S zo@WJ{i!;PjR{A#MJLo1CTbhEA-9lemj^N8qWuaI)tHWXSKB+dv1LgihXlV`bkzERr z1*nwiGVLLw7R0+j5@#u3VBq(#u^5#_E5vF%ClzMUsU6F5V;yYfmeGg3kO8pLnfTH9 z=F@_Eklmgwm>p-NEa^BsOtNn{?Havk|57`K)FlsmJ`r)zjgN<+DiOrRy^zOT1bq}C zBj^_N6i%e6pDT+n6CzjHwp(AX?v}BoS1rd3E0P*Ul@3(eA)V#9V`}D{AI~CJl@PVH zB9LiUb*zlqlf4}v6TYG;M=heg8nXoH`tzzJj0^ScjQnb+vY7k7=e4)3V2}{{R08}G ztw!Wt6?+S=Z%6w|!4vMKZ!vb3C5|B)oEao9A=xD2Ow^;@H#C7kYfQB(?2mckpa?nZ z0SlJuso(dDJkdMTabL%XMcL8L{a)(^mHN#_TPgOP?FtS0@?<Ejw?m&V{Nzf7O{1og z`jgxciWL41`&DhOjpi+CXMtGWYHt8M(?`syo;V-aB=Hq^f+wHXRK(pz8-m`uJ?#j; zMEqQ-@~Obq{lne-^SMnFhlTq_2M64UlZsfAJ^i}Ry%>a!g~gpUm=aV)D6`Ps10+&@ zIb}$&?!IYr2~N9e9U4q$AJ-ynJb+R*w6^DzR}*fZozE<xNUzvJ8>FH_ZB4=Nw<;P9 zWDgQ`8RmK~W^)w(Z-Q`pvatG}Ws5`ycpiI!s`35&@ab-VPaN_hEUH)ohr`=83!Bz* z@NrL0ja8sQ3qdccPR4*|w2bT^n;N0=O}NDO$Vkl|WtbBo_S8)ga28IY+U!ivu*ogj zZ8KvzW{k)SaO<CXrb_JsBGOSvM)^ZYY~W$vgukiDi^LPRn{)PZ@e;DF?{%1eICee{ z{+ONB!E2FAx3kQ}byhhj4F<o4%_f0|Uet6tD0&JsAsOGl4;T7ob)|Q?zaNZ8w%YEG zUFB)9HGU2jrJotK8)9BF_r6a0PAfm(7*SYW_7+S8snECMmp&Or<0>gCDfu4vaEa%u z(=*8oJH4(u=Xb<>wqSjA-sewss$`{7u)lo2A7|(a(kCj`pl)J5OG;#41m90fe<OgZ zLz5uzw`OtLhTlCZb#vBw5_pbxNN+Y0nk31IJSNNiO*|<Hc4Q4~C9XPJ7L<kJ^`WV- zGSu!_OBmY!JWuLkK;O6rs=!Dd<c08rFjK;oQ*`=9qWON<<@u3RK0%@Z8AQV{RiW#^ zeNMgMcpT#D;SbvS0Rx@$P7iy8JOwb><prBN^vfmSx%MS^-KGBmjji*1F-ZrHgzyJK zAHlsalVucPjaoPQFn}v%gAXK5u_-_+!rtoUgaM=droSEAmbu8!c;DXg6r{?4N0zH# zP4<Uit))(^Xco`<I6Ut5#|ghS)UX^QwzV^R3=2c9RXtL^&+t-})fIXrx~?OXZRzQ{ zoC8%qsaHoD^8EP^DT^4DIU&E_@#&{u`;Vs_cJ7Q!hPKvr`cA(y)W%WLP{8;w!7uE> zDcRBBWKQ$KXxzbUhG0M(5>a#8J<8-T&(w%+ytt!TLh&EaT|i}BwSKyH$mtbWema=O z!=|pd1mYr`oeH~6G2^RzE~&`Y<4t?k1nKQ}f;-B=s})WKo*O@5sV*t;tdQo(z?qf; z4mm}<oG#tgaA@ZK@c;V(ihTBEX)Zhf01VszOSHjJ-^R$m_P@ryr!hZbH(TCZe^9c3 zr5w)9&LRo~{VD$vty1$n^c^)+LBIh~&zmkc6eT2J(~kZ0+<d$ukdL28X6iHA`N$oP z-h2_%t}!=TsaKl>f0x8uTT;4AcaQ~tX|oF4x1>D3bW}F9)JV4GnFYgu6=`NJD^v0` z8P_)uO2=D!uD#ykxf}Y{b`)4eN=*NIyt1YUuHa0EWY(PY7`+#0*49j-_@l6*K+pJ; zj@>(?&&{f4LyBY3PF=C76ps3=PIx7*c<-V;sa>E!qv=exA&vDl@xrCy#cO!mFcsG- z?r6p8oP2rSMF~n(t$c^?9(_Y=7G^)JpjS<nJQul#)|ux$Rq)a*LD7T6+NgpvjdjRA zMX(YHpKhk{j97xeyqA>fOl(3vRvdu)N}oBskd$hiG0^9k!RgzeP<^QW5u*B5@lB_D zzGoVYjK|}S6_uI$LuIimB(LhC<$}UcVX3zZ_B=kEQM?~GhLDQB6Bk3=NqvDryPS~h z43>))R;a(_#Zx-FI>h=6d*6V}Dc{_LRJl3@BozSKM@7V%P#NY^s1&AStDDux7X#cJ zaPt`Rs*q0Q7mRky4`l1!HP@hpNu{12mi|S-=%as@51u|kSm_FjSdCAs9xD{|D*Bhr zC)$2Ej1*dLC$?Ld==dT=^;1P`ziQtz-od>yw%AM}H~f`|^|x-__VqRVC6yBsS8fHi z=o+s>KA9&hb$sPOEtq0<`>TnDVzzLHjKF>86U2m7Wd`Jn)%xnoLu2yvWnccXOBSJ3 zbh;i^&qerzd3qAru@P}V=$C7qg(h_?sUueHwY^V_lzdLahG^%9=X}dU0RT?YbD#-m zsf<-K*lyn4-IkIKP<*@2_)mow8{cuykb$#*%p6swuY(jfQ^xup{qvyO3|s+JL!XXQ z4LWdV9n5cYy;pDv4rH2tb6lbZ*;DfjVL-LGjffSJhsb3IjKN!hULO~K77ra@RL%@* z%9xPIky5>L551nF4_exsSgLNqvsOsgN9nY!AsfK8BwqCT5SvWZ(+UKNP4h8GO$j3V zzAqLE!JJc_UMAAdzkc1U9|0gQg)l0JTXZ(9K1ww{c6OnEa4q~?RcX-+utj2-B(V)- zzc004B2XNGSr~*mWe+{!1T{nK$OVR<M-T4{sf<4jybz=YS`HYBr(Ypr2icvhRcs0i zGptl!0BfwzTs9u`Ajmf>Uo?c3NkV*x%Hzr*Z`*HW+@Getbc1XS+8RZ}5KdS<fgtdo zhp{Hmb;GXlooyVNII<G_ehq;AA0~)K0XU|}081z+3Zsk>i6l$eSQu=!zf<3GO(ypV z>|cSkl(y7DkV@umbj0^Ly6|Fz;v_K%+iwG?;ug|A3IOAMP+*puC>?Fdy}9RqnIxPI zWCfW#CUVTucCLovcpWG8rY}Vk(4c&=JnJ6PXXC{d5&u~B1w3PMJpr5|Ct|ttO~tT| zxFt3mw`;s>osX}!<w+Z&i__C1QRY}1PNsewgOT_~f!oYbkjUAuAtUrOCHv(~0gV*T zZL`b=X-VpkFYzxog5TpSaoY`5Rg2@L2U>y+*=pCH#Jw~D>o03xOs!WzC9?AZ)|ES| zu!<tllXZoxpj~vqtrq(qzt;;6KI^$i!zm5t0O0t6xIXDz1RRAL#!*yAp)XTV`vT6c zS%VvrAG_NCK!LJ`QN6UhJWWc|zb}JxMx)FrxwOmALn(+rNKO!>)v*fHf%|@Kw%UN6 zGY2%-1!@cfib>&A>@31iDRDI4i9I608`&CES?DKz+7*8nc_+*F;A2XNS(Y4QY=b?; zYP&k_C@s()D!}v^q^W}`CNKq$2|o0(f9HG}LdZPrYKb_&IY#M}yCYoa#?7O5(f>#| z1F2k8vAi|YRQTX5p|FwO!yIDK4uk`n(&y}wo_<>ft~=m*9t@j_zz0?&L!#TLr1@x8 z$X3}^IyJB#u9vR@XGcNP>i0Ro2E|*hf+u^)8<ce*No82H0x-mQh|Q;Y{S-S|m-Xp( zc|1R#OtPLmRX*a*=4uCM@h%A9Cdq6OtPa)z`%7KzDpI6f)h<y>up)5iy(Tg*ON3#G zKsy1{GgtG6z3zqLf+39(DWq}Jvk%>Ve&V=oByCyCr!({N6MMx9>)8tjr%!XYoVUCC z*i>H!hVFd=WEmetQ2tI20I|9LOA^Ku6>l=qrQPOTd8!uI`y}3_2<<QcVQ=V^3sU8X z60b)^{NxTI51YtA(6(D_cf7H&$8l?Y_uEr%g{|<;K6{4dYTRNA+v?P4juMnnVU6o) z=@BNr^iTw#inp%VZ-s-H->X6Ni`c&x+q}FW2qmouv{nW$hZwpA-|_mQCL$qVnyYC~ z=2``1GH!;r<a=8ETZNMEuR4=2Rgglsp8+klNZj^Ou&@@9BG`7KUqN4&#J>P&kB@_i z<Se7*X$GO+(8-XNbV^02oN0iTdAd=GB<CP#fdcN)@_3gKwd!3(@?|&8c7Se83guOI z?tD~HxUfJ_sy=h6r6_8S19YHYa0byKHO-+-%W#)mpr`LUsJQe75F3nJb`9hG`ZqaO zKliK~{w>72xDlGbsVRakz(HY*#i#4?4&Kz@FGQ@^4rR8x`HWl{_a`VjyfMKVq{(rU zE;`FcOTD8^;Ml2by`NuM$sc8$RIk>FX04vmm!Lp}8*&fYfrMl=w#%h$3>eC#`mV7J zwqhFl44oi~goN0DJu+$6uCgq{CtYttRxPb^`Tn2dGQ1>RfxB?99(Z~n=#4@ul%uM5 zO12^T4J9<#qQ{05&N9Bb8tn#M&gBlEsio7vnU=*5*EJY^aNDUEme?}guCU8_Ami!} zffnqQ<5MrM2e}$#S#h@09p}7T3LC<A{^Bx9_U#shc9O2d7+vmN==eHw#^<&LkGz!< zJ>23qJZ1vRK@=O~2_L8zo3H3lDrGf~1h_4n5gtUGXW&W@_(;rU3ERe@n3(O1-Sla+ z7c;$6ZY&Y*fm1vAi-GJbbvXkW?neg>91LlCQ+yAo>@b)igJ296M6fL+xvM3V7xJWb zY%k~LceR!L-ySxzD-we+FntViv2Bo3GCww<(VF8B8N#03PzMDXqE`FUSKgBk;T+qg z1NS<d5JEleFMr8&zgwA`SUuo6pVkASjMs8Q+i(CByh2n*kxC$!Zs;vSz_MIAwR%n8 zC2ql}Uu@{+puwSr*LAFR1nB+}-~fXyz@~tqyG17X1~tZAIPoA03bt{_#@fcpM|+WD z!CS)gWWmOMDaZ9`<q48MgXJ=Jt-$*uyF!<nY%$~cxVe51q9WddLR2X=cJ#OYB45xo zCBhTN{?PPy9NC{fz9`{kr|Nz$m>(Go87W@s-ugeAgR6@FqHfs_<C$iO99J@Asrygb zKzPv%yU(UEB0t@Co^uTyfb0ix3kDH=0sKRd@Tfw7pYYS_H{tkBqgHUwD60Fnv$pj9 z5M_7jNwaT|ZH{%oLH<<`<A+zrAZVjmab{Bp7Qzq2ztZ|J<QfDTj`9MG<TRFAWD&*I zt=7{Wk^YXog3{eq4+@rZwT9n^EBpu$`HL<Y1pZl;6@Ql5pLjY6=}9y!w;~5Od64?& z#=L*v`J)eilr-2$1$;(a?uMD1>g#mdVIF*tD4CW7Id&@t3!oAx^QWVB9aAz5ojZ5{ zrb3qtINS=x!Uey1zZnXLB_JkroX#%hI3|~M{Xrq^27hleQG{PNuYj??Q>s-I_Dz&U zLT+g&N5cxgTj&hp58;xy)b+Mj?WbX<;tKP|hgJ@&KMat9T%v9LS1~iPwRUb*hEc_i z0n{1WTt)qjW8}Ijl}8YE)0o~lVf!Z)nKiaF!p2}<PmC#$8K6APv$AT+^R~LjTWx7- zZEbF^#~aw>ga)z6K(uc!RhH9%#F0F_z8t5gG$9~-MAcK8*cDgF7p~&g1arh1;R@OO z(GwxknDx9@9O$Xw)|!b>fYrZ<!t-=o)R94=;E|B<2n-lUh`(4QR7`9V8fH#OZKv&> zkN|@qAz-57QT-NiW9Us_<`EdxBSz_bN3a(y_4LI{*bN2Ad+SvTKqbTbz*RQk7i(hx z_W9Lh-qiY~we;2?jFcy&9_Tg1ZI3bmv|P!5QF@*!M0RkhEZQgA5NmiL`rDRt*2p$) zDfkG7J8t>Y8foEq&;^;aj<c2FGpSDO@o}4Pw<<;N_yAsiql?($^Vw%;D;?v#)fCF< z*lz5Gu^8Fx6tDNn^~|#L(LPj8YZTx`$gJJNlRFfdgcct)W0c}Vx`<^q%EX;O-CcY7 zMcvcOtWA++>cOz-hF~wy{*0A%QM5C7?iF2H&fZ>thRh7i8+uMFeHW&21u&~<Nlpwk zqgbI>eFm4++L^-wuhx`3lcm)<IZL^<XwUjngPKkvrg_xe71r{Pe14P^S>i(^eiU`2 zEew!#j?n(kdrK$D2dw%|dNAi>uZSu%$*bYodSw5e?Yn2*F0elWDtY@`e=tgSxy~-( zMOOB+|3GI1t3$0$j6rWYn}dTSIid%0W;o8u%E|uikPS_n^ks%WAKB~>>{jnzqV*8N zu3PsyECaR%9I=}NoNYGkFI(fQUE%kkxr7~3$=*?Ww^M1&$t@qF2D3Ncv6bomP(#qm z9=-!;Fu=@@#uKT|)%QP~(~D5F8hIpxp5uQ2K%+;WTz9-(d2^DU_T<T*3xwp)9?Ag6 zLDIg`yE{F6ywkrQ9};_eF)TruQD=jZy8FF=4jlc5^IUAUtd0rY=YKd6PIb491wKGN zWCg{k6|*;=$2I1l_avX!9FzN~V^A4<lY2Tnp6*X{*D4>+*E=a+-R|F?jwVfSkIt5l z5-nf5dOSYv$$fNs+`i7w$Cqgx9YF;LJJo02J-Z8|$UklKd*D0}v%ndg$PPp4JHc#_ zF9?s8#)ySQ^ZKVnk+`+^LGGH1G{4?=vhrLeg_lQqa@uYLk$X*X8@0dB2pN84?~y** zxOZ1&y$M{U$GuyQS_ytNb|=KAAT7aoPSso!%s)R6Vw8cmlLd+g-Sn^3v>cqhbo@)H zB{@nb>=AW048>Xyfw(RrY!pd&9D*Iz{1=&3&rx(E@554iHLdX~3wr~>IuAsL3gDf! z1>Nas&pa$BFFmg0B^{H6>FFAvt{_hb2kAR@__EIU&EfiMFxSZSFP+KpjsW~#Z*)s^ z2#N@I^;d1=2my-$NwK)NByIO(#g1sI{6z2&v-E?3FYYt|Qk_-zhSR<&HeNNp3CQcA zYy%!zkV8g7%k%zv*T{-qkp%YNB*J1Y4TFRqT7TZ=TUSz>{QSpr?nOl0%EDg^V&m7a ze(irqYC0M^nA<twkr^4gkkdF>+gWi>^+OHN!GP_4<PhL3fU)4}?dqSx1>*0A?3O2G zv=?YvZkET|22W=ReAE6wO%${nE$5p@cFa5<v0J*7p06F(9d9QHq>c!)TL+>a@tq># zV{wySjX?u$_C~sLs~rR&WUYTtQ`nM}jxqk5!u9G$cP_<cV%0h$u7dHl`o)<8>zVF_ z@x<V@bNH~{<Mt<DSV+1eo9`#+gM&-@d;;)EbpJP8QO4NRWAW=$#IK?Le>wNxZYiqR zIm5&(Jv~Ch*+1UR!@9uT!$8z4$Ssr6h)J(dEdVkkL^422>^~qnDl$j5?H@!cKua=4 zDnuR}pjhpl`|YQ<gT4t9-`)K^2VFnoQyzXR79KAjKF{zFE_S~|P-NOYrpUvn8VCIk zg+eeT%2=OYHPh-}HPioiN$+f9ZfI*{tn2J#ZuMV;9?1&awgYqsTMv{n`T#|JQ55xn z=SeCS>G8>0eHLt@&+SRy?>dN~L38;}dXg`9*Kgg6ClhL5vK)-;#}Ud!n{k~TWDz8{ zU7mrf3!Jxb*oSEt<D66aKRudN1z3?hY?a8l$FhIM=0VL$$LkBKq=|OdLae;08d{mM zx`_;DE0%WHGD|wAnf$@(&h$L5G%x6?GELQGXN&tC>(!)B4l;NLV&&s;<nJg4BlLF& zY^s@E#KzhEAd5l*nF4uN;tEWtRq`c~t>OKj`RdtXGF>HSG(mXCQ=s?Cc<X}^g!8W^ z6HA!9#ar#z#WSMjD(MXEOZIBcAkYkX|G|FvwlpPO@a@3`kPSdw9sObd^t<~9n=#$5 z2BE>sonD|7dECHo0TA~ON<-<aOrIGx!V}fiCDzP2MbguDyPF;JbGRTR4S(g3z75|H zuHQnQzb9d-h(j>sW4*E>9F~lX%eV@*9I@&SDB|v*0BnWYrB#V_yD+#wmkr!+2|<MS ze{U)=4q!ID-^~>AYyTl!>SFBRXl`rs8!$=AiCN{j$k{3CF<Of8aVZ7AI%Ee$Nkm0N zNyPRxi3p17He^3Mo*t^^GB!qDS{|K#)EYi`in4s2EDZ$>xrE$Y#j2X|WR3VN4Y`6{ zs1m=0wJ15->B*T%+F8XDp#RuOcF0dp#!vtNdH4VTNdJ4EyP6prTmAk}vAVV6CJW+s zjjq2ujbKAE{h4=%cwtG8$hh%FTMkp=RMQzf0;EP5`LB%9rbFq^m&=_1B2h6B_v{); z{?>30Pp4nX<WVQ~Niji%b%usThZYSQbp5F5z>8GUx3C$Fvv%qPEwXhoD75p-(vrkK zW~rOcfWz-I9j0Ki&ef_KrryQkH5%05suv<OiB^rIh<)Atv6?oS%!IRoln)v1VdqUX zSQyJ68GfQv6l*n?=^7ztVcRyPf|{<b*6U>Q1-f##bDp0jyy=>x)B-q);TKs)j7Toc zk%|sP49a0{S<03Zr0=Tj8}(#GALrzViZbq#>L9YBgr9k+@t3Xz3t<JK4TfP;V*2!} zp<mjX8L3SuW=U<b1&<H=dbO^PS(67v5BqNm!4(ABrF?(c15kflNb|d$*R!KUkriC` zlIV?{`Py6()3)=jm#vR1pC=}IEPE@S^_GIEEsy&pDrWGTD;<E%i0@(WjVg5gaZis< z${#?9sw$4Go~^F$m)Tw`#12!AO={G#SK8DQUMq#yhl96B>G%8nBTTxZ?me}V@@5|C zgR<W~1!+Y`GKQ-Bulz`|)P@?F9c--PLsrT72h@cAop<U*Q<8N?z18Recc&sk|C6xx zol*QlKv7yrO`MyJ0-+2}<`-_9D;AKh2{rm?__qDRAH+mOXJwpS*%8&Ekl3SYxsbx3 zPkVw#8M1~G57iSs$Xe%0JZZmHyw;W|=FVfeDXep-72#qgQ$8&=NKe4~f2B+93at$U zz9Sh>WWwuxK&g}k<U=4oZ)QXw--vzw6_X!qZ_rtRDVtFd$x{nj0IoGmJZuMrWFE>p zb_4j=;B*BYKp|O@_x<!<cpW6TSc{=3fQ4c+lGj|pn~viAQGY@`0I>Hbp>U<vR6rcp zxe6kh3tFo#nH(Z^V=Y?i0Kx%@$O0sE_J7)t&fGar|JCu8Z=rUx5h|DfyW?8QKMh0> z;ele37Oh++FIo)%4J}+ptf23NR4CVlY=}SB?z_X_uh7?O*!?Baywpx28b7(n_HExL zM3s-LSiy$x1+GSRh;FJ&e}h4Qm5{;_(-DM-U$o29XIIrwk^(lWGEu8`&Erq+GB?sp zM*|L~frsb_l5vymXkpAw)lT_R`MRb!3r%ROus+?H79*?f7{A!G_!4RH+C?luX3{wD zi}9sba)bZJBLf+rxFcBZ8FbuV)5cT`37c#UcvK%-qyg07oEOxM^V7Qr5iJG9hbJl{ zwON12ga_BzbVF`z%`Z`p3DCscqi7~rz705ceU6xbsIr~i+fxU(azB^ph0rxsZ3p3~ z4#$%*LC=}D<+m>Jhp~rChsvr5Ah2J~pRCqR{ShCXZH);=uHM$IepY@*<RGS67F^79 z5)wTs4wt0f2x8S%ef>T<sX2;Jev2=3mYNO;`8ka%>5u!`#gZZ7sl*pU*)eV)L$6Le zrW8>jXm^71<{`nNy?{R1nk)a6u|-L<lMml<(Mtlq?Wa*6$n854YSx*E{Z27pOg+-0 zcb=`*X5f|h$Ov3+G_RHBS%?T!px|~u3n6y@wGU}UhQcXZfqX;8f<J00WLHR|67WH= zgnb(zm%mW%-GHQVM+~f%thi0^cDihX3Xs+546&>!Rc#*30lKB<9IL$KCL4YB)W+ph zT-BJP3I&hc-%_r`3_|ZMmwsfnlf(XhEC(F8=etO@+Z-caqS3&tiBB0qRUASfVDLCm zr)K;&?)S{<`(&M$)%*rS2!Rqb!Z)EN+<atX)vcD{)%{5bG8}Cp@o!Ul$SjWXummPC zXgYB3KC>^HHeuJ$5eibiSjmxs)?_``w*p%lR-jTHnYL9)gG|BWfaI%ZD8y^gB-0?i zBoDo4Npi*MODZc=7hE4i1Bo)cW5}(lxqOC)8ZFAYdo#rdiX~@rS0%j5bR*QE$)FD; zyRH++$Ays>d7cLrY|;Ad>LjfwSz~I!>oE}<;dlV3ib2<h0=_8Ij(ZkugR>yU|IiGX zKq8!qc9a+sg9A<O)4`$>R*hO{MaIfb^Eo`r5Z+7kH9$erf*7JoS5pY6(mxD@G8m^X zRgiJ*8~LJRIye<$M%yte3#KE{OlfIzez4d}A8Ufdft^;!u|&~rApTB!mMpq2TXS1@ zo#DWNkN6?WDMO*l#Xt#E(0k%vzZYs+z;EFV-mql)uVmfecW4+ri!F<O{WMg|0{dbx za9KawJkqUMGyGM2H=;G$x}~_bAD2Gg+HN_dzlt=`cwtrBU{hkEyKLZMIoaYkv0pmh zzto*~+IJSyukkHw$Blnn_yjh2sL`vVa{zbOKW}9OXMw4ToN8lUgAqB!o~;26!rx+! zJ}-sg*yvxZ8m!D@`-gi0$}-%{=(>pnTf$Cyjv0qYU`@vO9>N1e<lBIA^<^aWBKuBu z!Ws+q44Oz-P`q=G6nH@Ncb=Z>c{`we!A~-8e{MdL6YG!}ry;-B&k$^FBYyfH6!!QB zUPz0Q*vYdxzz5Ns(-3}zepKkPU~Yc_@+N9Jd5+LR!%S4!oNZ|&Gu~51?O-+y|Bfn; zyKE&F21B(ajRh>>57;C~t=Fwp!~`o{-=rl3BGK@b1t0torBe}~oqSjowR9I2ay)g= z2u}CZ@_hcnB~4n&xyR&TtC4y{MYra=W`>Q*;1+v{fBFW~8WN}&(K_`u<;X4P0G?XD zieVTSTtJ~LtP&m$o@MSsjeSR_M6jqpR>yNy_?FH}@RDNR)LJ8^a`Fk-F>j#u^l0q3 zE#uhJs1d9vpIWPEX<_H6$gxG4kg25pYkdg+$XbKn=gTgvYm3aNB+S2=jpaXIC|H;6 znV_<dlQ~vi!b_{FJ1+&QnXD(XGdo$av67>ww7!p5KFooJ#~SR;&g^Z5IH<;DXgGY! z8(9jaI@oXa+&XDGPeJPSaJqu`>cCQ*-1fK&^U^izrROg*bcyMm^{izW?y)gjF}!O0 zi_3<9cRhLUGO@+kIr=?LCFk6AS~Szv)o1%L>rFA(p@k{D(eD3>zjekgxzdDq;U5Ow zYcwU4!Nkg!A3YZS_}OBKBQtH>Ss$qFk}Yg6k3MI%!*DSZ&srSqclM5WcHV`IBh&RA zfV=94#hKfF$YlES!jD<T@RM!^vOH{6T#$un*&Um;QNbI5n`_*kjXwg8Ylf>nWR(Z< zz9QV9{cK<Ea?y8-fzD!fhl=hU#|blfaJV+1I8|J@@pNoYB`0$Pj=LS%DLrEe#fb43 zE}AFL+{Y4nWO#ct_vXUe*#++PG}i6#nV}C3GU>)6UFpd&yfJM~p@G{Q#YDw*bF$&} znFYj3Q@WG49RDeS@WO&=E$n;0@%>~4BsCd966QeUc$zUE``|q3^BE;S5vN1<drVp! zc!EqUrE(<Yb-c{P=XP1hWX|V(Ubmb#hr6^)1Xa8~gX7Bx*~!5UeyR0yu|wjd)=vs{ zeKORyfw!ybodhRKXD^=d?LBOZ1&$romwg6RkWVEv_%L%9nEPho_**vf0n6Md!u50I z-0+I~zZ2!l4SQSX-}+_-2mk>4KeEzaiZEMOM_or}J3Cv4|LSu)EA(3o@F8@cP?qRO z2_Z(ymEkGLm*Z(H?bDAKDWD~8Ik_&J?zkqVsmxy+n})n>cV%Oz6bT^yGUvy~h3li^ zi^MVFL}<AOjG8h|xamE?&V>s1ifLw}=o@I<GWi|15HL}y*%K*{un+k(z<Zm$-77Zd zFLN9VFNFs0nrZDtkaWCVIG-#`_y?Z~Q;9G>o!Q;Zn=wszMuRx@0U;BB=ZZCWi$DmF z%GL3SL8K4)1#xYPjAuy1_xY1uamEnvvPIY?$x}ISB7{FA=M#{$Idss@)@)uqWks}5 z!d&8wBlqL@-wHiPW2#Iu<T*xERJrLWKX5gwCtH8@F_>vQ{pv&<*SXZ_0r-y5#at0e z#MsX^-{ftMLbc@BmD>?2gFd`mc{Ez=ERSv;S$xK3Ej`TTfm;+FIrw0lS@GP3WKLVK zyst@hwXVByshf$MEZIlD=Q{h8>U>*#(C<{Z#z0fNs!kp;1~+4Odm@nsGf^La|L=G? zJhK+>|HjGmH)g+u#Q%f>bdAg%o&LKRrPckVcQbd=)%}f`vYfQ!5FbqUY%RoPekUFZ zw;KW%gvTw#cBnb&M&06gT+#CTg|+KM0Dhck!pl9sp+5bbFt)OqV8IOgjVUtm%=S*- z@okfHi)RZpf0UK*C|E|K<BXBJQ{4t&j^e(pTYro|NE~6(L#hP4=!`kLKmB9k-`K~< z%#yt}Bu=aWDJtr&1Jb18piME0MEQk5@8tK~E>APp>rp-^;0KHq^m>TremWhobbo6; zz$r$^lRu4TGmHME$odK(4HPckf|~KT>@twC(Y<ib&NtN!I<dUmsDZ7LFO?9I-olU- z*Z(p7kV-B!1`G}W(1Z*C@GGwTe_J3!TPrJLL#N+D@V~h@)z)J+S&+SRYw;4mC;h3W z5<t=W_%)f}`C0MAKNuijG)hLKjO2;S)BpB=dd_wit;A;nSV!{_#=Gjm(H6ot*XtaX zP$^$Gm;XzLlN44w+D>cGoYPsK4=7Jg-d<~LY%DFPJI3P?r*uq&Eefx^6n3#sNnK#S zE1dcAq<xqbFVB_@)nII&Zqzl>zBqSr_a?dZyg!8e`O;zA|5Jj%IlZ)CaTK&8N!wyU zdvl9_C;QLbnN}(o`(P=I%~-tk9d2LPS~<U}!hyI8upY5)#?(~m;r;2N%$B?EB_xR0 z!5gq}HFYv6m~`{Wn1ZN>mu9q!6}tU(Ofq#b`l>wob6%vpB8WBcv65a?h1DiksIw-8 zlp4K`9QV*TcX^(8vRJLwJw8kkaPig;gMSHpvkXH;sb7C6lkNe<AfYZu(r5C`S_WD3 z^HSX|s_1s$5DCY=NYNjC7Lwn^09h*AOYpHbe$N2$K+|nZ=gWd(*|DEHzmkuUB_<+8 z*QEj>6ZUD!B#})SwZ6g~o`wTmNINb%oa1k$mm#H1N6`L1XWf*W;u?l?*5jm21!8xp za<V8C_Vp2t6tYNv=G%}3H0NR<F5t?r<s&l-gVu8y^-`B`TZ^&WdM9?h;#?XroY3H) zC{}QsyK7i6-sc{PXrC`}>>V{rD*+SG#`2*}Hb6|JX3UPn%n3r|nupQ6)T_R#vOAC| zBT{0R<UB}RQaY#-FyhUGG~$>E)wx^cp#j&14&}Na&euQt&TGzE$?uJbCLfRlK!?mR z{j&0H7_TiQ<t{M~q<<vGrq!l4DQGdl=|QrG>_{g?=&_*<6!NjTg1^AE%d^*T!V}i< zeH`O>b_k_HH5isk_kC&~xQ9hph$GMeG$>9~5Y(!pw99!h)lKFj^WdQby6||`#+()M zTFhf%D4U#fQrGELph%sE1HuOO`T%)_GrRCt3H5$d$my_xEzdi+7G}EZIr+hG$7oyZ zE9-XUW~ui(ufqyo@rpY0CW5fxtP2>E=Pfr{1``IPK`>EwGHx61p-CMoi&X7y@Ge$j zH^L*AlhptjAc%8ob?!f0=5bk2LAOx`Q!6j{-tIHXa8d-ggnje@p}Rsoh_~uZd)i+i zE^KJt+=pjRKE3*9Q}f4xMBs5Y`w3G%GC7sQ3z*~v-2)3f7n3;s?R-KO3z*nAjm6Z; zAg;<<Hpu;g<PZ^Xifr6+21+i4>xvw|LPsJC%~6fXDGr#khY#@~dqr8=S;*tGazK|& zBtRX_u(02Ynl%974YtSNmi!kvnHM~9nkR<!?49RpU5Jw;0ffaJfz#(AY&lD%5uU&` zp#1qJK^s}Hsukb3darpJAfe%=#T#%jzX2f%T9~4Vz=3D0CzONjr3tK<nuK=88s;3R zgLEPv>P`8+`3v(Q!_~_au<>I4M!N#zInlU;^bY6GbBa|tA!32WFo-vFpm)s8OEcs? z0WnGcCa@QdNx=Ssq^5XfiVhO{o`Eu}-~uofLQanJNlTMq&oSJX{6>_vd4$j)_H<%1 z@rh;vsc$t+?qqsOVPtGfDXjfHeDZ?WK{NqV{R2s#%dK&WB+`5Hg)bX_e%buwWW3L{ zf^4HdD+X%Yj06}%0onXoLB%X9+2oXVquc=Jf`s}GsUA&BB|ZsM?jGcZ%{Ak_6yW+C zrW3V=7MP`_Ch4!TR-B<}!<OpWz8Tj(5bT>Z+~mp4?Sq8kjtZ6YjpoYzc%9;@>~oYr z?$NQbTBW!5aiH2;j^S<_J9A<cMKIFAC{b!<4h9E*_HUf{s+(>~a83VaHnw^%^l%mF zic6J~6k4-Tw%}TuGh?3S&3FC$O{~{Im`X?Ze2qCF2k6_r<QQdJb3fxaiVYoDATIpl zJoA<w@nw<hBJgAXSQ6_muiv$PyH+2gD}{0LuCzPC1gVKDmr?Au))uoXBRP1Ak4^Ys zq$GL++#>cT91CN0(|(X|lTyAo6XuDjwwVFKoYkviXctCU*!9FZ4298^HGP|wAl8M{ z)8u%C-mx_;NdRHfG?K2Ju|V*RSr^a~^r}v#*Oh<HZ6rpK=I1PC&8JS5y`cKBD)Fhs zY&9%8#$PjfKB_c#Z%z7`j&8Ueaww1_Pggh?6NvA`3Nz4Z1=KcnkpOa)8N|R#Q_=UR z;`ytJeiQ{3+o?~=zX{(Zc7wlDdh>P5SJ1f3qt-b6v5l^}@_8G<CQ3XXvNlmgZLS%s zS^6;T3IDpea7~IH^eQ{nJ|yiQ%8$0CsHRBtI*Km@>5Dmq3Hf_C`NkWv6FAI7^TeM? zmj!s$0iP-31#!!MH{UAd2E77av$K~JAW|6i`y>5yA@03|$;GUi&pPW4{|J@?^(9Uq z>M1820lF;a&iPy0|D9$W!N}In|K6UNzi9^H|NRy<akepZvbFth_}f{o(`Jwk=HC+v zxM>|Wh)x6zsKq06hYJjdD8<r70w04IZ*PGW8@2)*Vt?Uve%+xEkZ*Ki5mO`mF@UUj ze=0F&vA*an6IW*B!&u52mZDR(!B-@Id5QV?7e9+Ci=9AR%AZ8NhKEZUh@L2P9t6pJ z{7yW&ZRq6k*in0-5`-hFYth?x(TbQ4a82z>(@ud6o(=hMpBMGaR_--B${crCMSR%u z#>=uw8d)}t_d^HlUfT`p{N{jO()lt9XVK=d@nnOqq@Pn2$<2KdYoGt<!El3+P!s*G z1m&;&N22^c6E7=U)8C|P^1mTv`LS_X+1V+{ll^_524pLJukObsL|i<^W--A;=>I^6 zwLdsT{tK+W`8ASX`yVZy|M_`qeM4JE-T!Cs)H#M9Y6uTT_;>KsrG@Sh060h3Y8gLI z8PRxSGj@1bE^VA7SN8iOUx`6ANzpF^i*f-9U<O=k)<AeFMKS+$9fU(8z2y+c?2Y&V zsSf^Q!)?^&1w9zLEy>JsEKAN(Y34rDg}LU2ZfR%1m@Kiua$a`Ah&`&wA>Bgfn*Ub* z6L){Mb?-lhW@i!k`PtBZac-&qe@`4;4FAgyb1P$q-xV9?vUJ>JOW1j$v~w~RCuYc= zB4j+E+^Hd?M7mk4pHxXme`-@hh7^w?SCEWrac=*7xv&8s;!}uW<kXymZwV4D?3}mt zbHE~%5mHYUr})$(wkagjtxilr3+!i`ouC^B;q3O}#i>001I?IHwL-3Ie@c_cW%!nr zEIBifP8LZ=q0XHqY)&?$mxFf66ds{<_>j;oD}+*V*-*7lWV*xUd)Lj2E~WoX5nGwm zC`2~|$Tz#YsjWb>{vr7nTym5OR#NBnvbD?LPacD8T{P{0*`QFf&WW)2#gRG8#m>C| zKu7>FhUKXcgYSY9qFkq}>l^T>Jy;<2bH3O_f~i%D{z(@Zi=S6c$y_~5AtsLDhcHhd zvyS~M4Zlq48wK(utgL-JgQ@+D0LuYDnI7%~h8-*b9Rc1r>SfptMT*-|!&v2TLYl@c z=&p)Y2pxKO;4%Oz{b9RN*ykr90lf|?9UEXv*WP$U<TaMwKFs_{YZmsAYuj{PI$g+- zfG^^*mG<EuG-pYWgua_eru4Iv&bl#x3lE`W{7|8@+WXTGz^zwby1Xq*laDq*P=Mzc z^Nk|1dxJJ!02Vq}wsF71em$K-%KyXHIW}nmgje((+qP}nwr$(CZQIzfJ+oumJGQMI zBb&;XBvr{@=&G*9bI!ddF1UoQ1ri_$Px^8<UZRNN?jKx{kdgh9XDYx}ExDvDmpbkx zz3?lGt*B=!aA=x$v;gN|-?#^c<ygWQ3~xqX)!N8pd%ZhmO`0pzD5yx0tWzsF(^L&D zE=*WsehVOI2}hj$Uax2cLYM~-eh%Luc+|PiX0|#1{hW#48ZU<>-n*a7Z*-hoI0X5i zzakDf#vCX}Y&7?EgWU&vA9ii@zVt4tQm1wqZW#gs1il9vPs5O;Cxf)XFgi1F@f&|k z#HS*f5g7VldcVN=IZ`5?qIM;G^_rSxi~~fl80Qn-YP3D$nK2J7=H}T=y(&|KF?ij> z|HcMqs3kSFdyPswc?jyUBu)yh1MRImmNUsiTNWlID-c%q&x1p>kU(X_Z=n1JdT(SG z7HB7N$00I(HDK3anW$R%V65$cfQi*)ZXvfn4DvSzLvW~BHJ!DWdUHzhPK%kC8#orI z;KSh8oG&YY>>o*?gzHZ9u_ENQ4kr_Q<DD5=?8bxVF+sb)N1|Yhl;g0mw|4&!@<}vB zyLBa2v)=yUGGypYLA^k?q4*%mArU_z|6`Yo!m2eP^OIW#{9X7$;5!H=hc@kX{}oA8 zfX5C4mZ{aRf^DZ%M)p2J+CAei-?JOtO$J#rcT2WC=8|Z7hHjQwPWi_rvC*@%0eC(R zmq$5qLCo5`-;+x*`}vMt!MI@nOF|DehIG5Z63ZM$7Yiv{Lo2jg8YzD5?W)7H+7X1b z*)-|6P!?7(6_ij;dmRxhpfHL3Y#wBAlTk{<ah2qWuD=a57syGaE0<td(CUP2g!h?^ zg-qTn{sP!|s(G_?oQ1%)>@*kStr$|He&7oF_IoTt#A1BDQ-D!cE7X*p4y=FsCpoI2 zB~Vg;F}IL_ZlD^%ORcVYk-b&}k80Wbg-L<AUPBzI1j(gsSOne`j|Ls>b!4x7DTo8t zEjw2aHc|Ba$t~!X&T~>o)u$WgdyX3D{Oq#k{;yoYUWo!Izxh1x^RKfp-!<}|?_&=g z#PL6Sx9om-(#({lyb^gEz=U<hO&BA;YDaB8Xy%G>NoqkX*kU#SriD&>f)#0^<d5O} z?6rJTI$q(fu~OM{#~fxrX=DVA9$LUL4<zvco9s?8tkgg)q)-Auj6DP;lDO(GQrV#+ z;C($+$*lIKJ8d7YjopRp+93nzwBV-{5ledyzRd9D76T*Q?MsJCP=!xX<Q)wIH@%-6 zRXV|rXnmjY8~X+8`ZWz`KkK#5EuW0ozV=#Mn+=HlS_ngBf;C>HXKO~yZoMDZ3A;Z} zL;T%))t~5Bt9Gh^A>ol4DlRcMk)sgl1P#}3{Vk~8szY_PJHzl(y?_x&)14DT^<-o@ zGL~R$yX6TGU#`MRuO)Qk-|X6Oe4_<nWp+q7P+1|JPZvo;`l$tw(@msi&;v>#0~k&# zn?)4M$l^M2`;45XjK_I)>BX=h4NF|yy}7+P_yxM)xAYVP#|sSd8dU;9rpLcB7XwSu zfdzqZ!E_&JM4iJ=1IK;HdiGDzH6&;m+d62%$r&#FL2?+8d}ZhlxNey@d>z+Q+uPbJ zFXQ?zc~`M!wk^?`e@9=7O~0vzd|x#vuss*78+;FfGU#o-M<FL4AM|UUID5N3+goQ3 zWZGt)svrBlj7+6=li0Ct2M+-wdC=j!6-EuiB8{#SOYHGlK9hM3jWN01NG9$Pk(`A` zo}vr_%zamB!|3W~F!=S98jbytv-%UU8RQ7TwIjr&g5pl`J4CRfu1VF^&STuNQ`Z2( zD~0gM!BW^_O@D<8=&k`*w1*I(0E`aS#RC9aIi9yPMNpD~_zIR7FVr7xa1m<L9CRp* z)_x^hiVq~afq~~hwBl=&55{st#N7Vis&WxROCUa(yN1YgWHxcE8m+QdhjgKGfnxRs zQC?~nT>~-yWnX_zzoArkV<@OKWzxtFg?qD1yQ2-Rt5-e!t+PZ-Z%A2A6ff;GYH_*@ zqp1C3x%6E#N%B4jQC~EJKdv>X6$xpSa;qf5fkeX-<6vUO=yic_^bO0cA*yA6MZ57B zp{-)lemgf#;7Lc_r4FF^(v<-po5yWg4rE!_h1B%{CSG@S5F|Pl(j8l;-*|1v^rGjz z%%!&YHumt`A))%Qk5yJ1rXNB%{<TX+CBBDZ{dAR50ft&*GcTKmp6Is%Hv=7&uBwQm zQ&Am1A;H^)%{M8HcnU>h$VeZ%J#Ymiom2)26LD})hhIr!7O77fgv^|$)~9aWEu<zY zybq=_!3NV_4qqZLGUQr-JMY_fTMp1HH|-A6xILMCV$}F(7>zMjET&lxFsj_OSCs3& zmo4u&=ZFpIGDeih2D%EVD|)hlcuoqF$7|(_0Yo99;I@=xI?j)ZsX2o-dNE~UzEvg% zxO&Ub(vpioQuM1l+d<H^-|!bfH$Z_w@=-lNXU0nC&!rWLWkw<$<GPU0gU0Za&p?rt z(ZF{K9MGz{CIMj5v5}nsR!iG|LAMz*RlyNzs)onts<-S>WJGd#azVh{C^c_^ytaaW zkm}@JIZEZAH-nk&f$#~ByOY#{pV2B1ywXN7Ck1uoxAejZC5aZo(aLIAGZl!Tkv{z( zNE+l<fPtO&6qSK(1dFAzQ(~RJ9K*i_xrVaMQ77iImrli;aaNfTBh1EoVyA5JV-^7A z(!<GdWhaK2ln+&rrm`hbDd~iPh!^;d8EH2l?#J&*KDAw|m-ZH*y*S^se;$6me&g%8 z5}~nGsI|L<<wX~_2lDMPynxJue$FQv*P{Bu=AqPZGSZ{3+S^bxi=d%SBq))9B*zrT zWy(D?!{^OywD8*O*TWFWp-_h)(9ydcHz(B6TPEoNEASCl{cMmFip6P$gC+Qg4_j>n z1&y+o64qy_wRb8Eql6(zD#KuNQ%?9r;{nrlg9cG}auXOSGl5`u-}w$77^4XKhY|oe zg4%^AAg*8!5%%TRk*_W-myVtXzD9s`K$q)*J^Dg3T6LosQKM8Q@`yya<3L6hF^yCV zto~LNhF&@f5R!&pyJSS8E_ua~icBpHch_{zr|mEFRHCk!gz#T0RQ7T7rSEKt?xqSA zsC=gO>GzD)O0Bh=1McX>j^aXxCSnIeM1{sr^hvK)7MoNPQ5w)C!5*e+kOxY?WKvWt zMg^7XNzGyZdve8iT`sQCkZLf_4L%Hm8I_oC%$}1NavM&KsU!H~Mq)UVPKi|QF%PR$ z7Ftu)BJ1u1PU#2v?h!G7yP<D)M44bEDp^Q)he#|Vd+67<4!TAOpN{txpu<eKkY+DV zA8J#_)IC^IZ+;qxD8q}S#Usuvwh$i#n=A?$V~e_jI#j8Iid_qnNQU_8OWu#-oQ7RF zH0iHuDmrx4QHIvTm-^xgZRld*fiZB4{EGJOeCJ9H`K_wnk29xl_qtw3Ma`4~`XlQE zXirfM*D|#`YBU@N3lGl5f~$3#g_3R6_+91YxLrdrf-mRepw@3%G~MIW-#1w6PLH4c zYZl(+%EY>v^SnK)Tp-C8yG=5yNXRBo9#dBCS8R~#?-UKplr~dTwlm5q8H`L(ZY60q zlQgL|aFMELi<MPSTOY^C8b1H${=4EZc_gh6rSbm#$%gV?cS9k~R>GPtM0HF^`Zi!n z9l#_5h~-;la5Z;0|BW3FZ8d3SGeO!*B1kL;;gwYA3UDk!TvUBEa%~v(B#i3vBOK;S ztl#DC&{2!K0xXRGrD9pVv%6n6Q27ek{4Y$iWhLTC7hvY*d!1zBdltzq=a(kl84RxI z{hf7=r`w_Sr`uDMcaNuM%ZH2Yxu>_M@!$BokSvAB#KLXMWm@GczUUs=@(EpbKa$*X zk!IEBl!_Ir*Whhdyb42N8E1#>hcOf9N7qkxra#wMY<aR{0^Qq{aCQm6g3}_t&jx)w zT<47PAR{bnfHze?3U-2CK7YQ>+#3aX1G#wdF$o9;Ro)$rZlTM{urm$e<RnXrQ|q3M z9`Iyto<CaGIkhG`c=1s>qw0KttLTl^NS_75Ne3)0Ao#c)c6}Sb$gId86N3$v46i8$ z6o(#5LmCt)TBZay9>XS2nVqOMKMNB}#TPl7?Ns2QQydW(DJ6SXE4vhjRszq?w*)Xn z8R7LH3ldROfd;`Y&Yu?tcL(is%kwt^*rEbl1`s6~_#%)vf(1H*7Qc)kC4PN&cVCI< z8zL65d~DbIs%n=cgk9>A)Jv0S{qik29Ufx`D7aDEDB!n>uQ%TXHAXY33l-uRED?!N z!JJm4T_cCsUaw+V&$?&Ewotd96G=3G7VPum{5*YzwL;ABV$orVPLv?al2gIhaH|uo z!s*1BgKu6CQ*nCkumX_8Fa=*h*8P1NE~doRm#`k$=8T(H)_BnR+R3Kkk92;E<CmMn zlIEPc+0qK)uLhlzfK?jJNjjODG8w75sFv_qBWZ--v}y7T5+fx{&cZ^{|G@+uh``F9 zHA!|T<U2zQF)>OUaqKy9cH8DzM)(t1d3qyOmxj53zLDE<lB7Ah^K4ifG&*qb$s{S> zg)+*7c7p0Bjs`){RmSrnIcAZZl+a;75goY(w-?#2!T5IryDXmIp4jxqu50Jg;%jTj z0;0se$X-baR-c|~V05F0w<=NP{@Zy<X7WunKm3lbFU8RENmw7cPT|<q4TEzX1b7LO z7aD#fu6I!l3d%?wpsR&0KgsWp^-KDl5K24FPWefve5S=nFP{{P8qJob-~G8fDP*)h z^2$$=hp`s>8l$N0qwrt}ndU(fp<b6)c2+*G?hV7_s4{@5^J*6wWsH9-_4k74v<oS) zX$y<v<&4ZAX4^UaW1T9x9~>j=@3}R#=Fy6QQ}4^|=^H<*t^zu5Q#=AKF(w9CAI3JA z-x_gUH3oiBe@$lIRYu;KoOU+A`z-KZolkD)8zs+`)u^+Uq}rVxY7`>gS)mEsSb?14 z<eS<n3UsT_bYxZrbI9UC9wXG3O~a*sETqE6w7M{hE{S#aNdFpDoW-AIJz~Em9(zoq zFvi6nL2GvP6O%5H0jMX#*Mn0AE;_Y4LezBqiYXR0uNyXu$&~-tAa*{)Zl9AIpt5)q zT0TP-$SrgoBr&h8B^%+Dks7+*#HdZpK9zNimemsbiiFVD8v8gR*<ry+Z{z(|tM)kB zjvk$7U5rnCcX$^=D2Nx*41xij@Q_GG{#5SI5Z>m2VD^p$;`baRujjBbuE>Xc*D_%1 zCt_oHFY4!R5viSm_V(f)^%*@oY9IhW2|jz~Y)*m3g1~-oFIwug<KpoDAc?HS7myyy zC<=4C&mO2!V=sLEsoQeXDBzKB-3ao~V<ns!R%kFNXxv9(Ea`nIC4i<xSWBZuE)i%n zp4<4{VgkIh;yxkNAjin<MY6#o529Lgwo(VpanrifvHy(auDVTJDZp)8Dk|UDc2r$v zm;>5^qJ-9qO@%jnM~0BCvO`XlBw^upQs~PCo75h^aju(}P9=d-YFLDD@$guXq1nom zEUxf==jBW={tZ~a_#4Xxm}q<d{3+z;E>uz2zTp$>gjy|CFb<)J1WI4z@w8m4rBU=O zu45IP>8G6B=JDa!_E3VpUjJi9ww8>ks12b0x~%VO;^`S~9w#CfoO}PnAY<(^vYNO2 zf}Te)XrutT<~+mPaBV0x(Q8fZUE@5)IjFgO?>$*i4DlYvwF&JGm*?bz*_8Gdo63hc zQ=`^n%9jIt1e1H4&L%aY&0XeAgbFB>PyARWW`G^ZSF}-7nqt`X_jOLMcNDih6h7wQ z?R{LYpsji{@7K$U4rMB|bgy<h_Xhdl9R2906*~xch&&CR-HFZH--~N3Egt5J?NB2R z4FVQ8b^G~-Y5CnVeDr;qM!vD>u?uQkFS{m`2R%bCwsM5F?zyh|cR^}h^qrxn#T$6p z2e<ewZzDCmy;o)xaX5r)onJHII1W+kvgh2uAI{ZES(hB(*0loGe=kW;E+LO6S&3@= zHi8otwMRN>EF2y#-_}Q53nr0r(8w@e32wtSvFUBxhtPXk(y!`VElCU5a{f*W@2wL! zYSl_wMeN{~DyMNj{L!i~bS+kZf~1vBqP+WSpCvkV(wczI_yyhG(;M-p6-^Zg8IR6P zdX&r*Sdszj;5w7OCiVvQ8-oYVfv{va#c>>#JvB4Cvs1Q(tCt{-i+Q~py_7rYX}wI| ziQ~cDB6s=}_qKd-#Gc53UuggyN<-q7&aovFQ;PDH1>~PF4;(F1$sq00T*%hiIPyhB zVt>5ysO~S$hVt(-kQ$9&Kes#xHv10cHQdNR`cKZX>qAfcMXQCY&Rr9;zVek6FwTR7 z&LDrBj{;^1YS{#3yuzG9yg^bwj?J?=J<i-Zij7o<#>ZU!rrI-IVrs!Q^o0^u^f4+= z@qE>ITf5QPUxsQNm(pW_`!|e1Sycm;#n?XL`Qd*j-e`bzMWuiI{w|)4w00>+ta{_V z@R3;yXH*4y@s0-8!X^#GXj~0A*TX5bJJgaZx;RG=C_<nFq(h|YW$#Wq>l0Kt-)$g$ zQfs(1XRmK{WY>@R=VJJK2XwPz5xv+1N389Z^&(mL7l*mgPw^*ufPIj@&U($z?{^3l z_d7e~q$Mv%?K(AhWFV4B$#4ItUNtj(qe%^5L%xh{!Q~bJjL!b`uZFjCKmp!8a%>rG z5`c;6x0e|j>Htg-Q2Mdt8w?|fx*2h<%N?uXdrHq)-xLqb{VZ57(0*tAAQ)vZ2X3Q6 zL4>&NrqVCD!TXh<hR)uy((cjDM`av-L)BbrkVp7oz)v8DhZmAbUP*C#K_py!FKjdu ze&E^LKB#gm1glWA7)jj4i<YVCMUQ$nJs5tZ%pD+ljGu?%Wvq&gTIP|5^MwChUS{&X zUC(!24Elf_`=ISu@?IyJ>i6Ut@_mt0&K@dg+^@v?yB=hNfJ#B2;5(7=3-+C?YSBmk z*v<Hmh`$UZdrHySyPw~4-iJ9}R(KfIZ_++j1*?kh=T||O!Zt!qBwxj$;L9kM0+4qL zf3)*DR0xJMyq>xjtoa_%_@ToYS#48I*2>m|;jz1ypFg~DHv~&$GEXwYwX-aiN9Zr9 z-@FD+Uxib+*~MV$p@6oFHIlO^NVwdvydqC;$YK#xK;Wh5^K+)}F-4rC4@BO*U_|tM zCix6ufw6dng#&}GSx!J-$yw30@f9bZd(3N`zIt=yjeqsj=Ccuc=lU>T#ta-03Eqa= zLiKdjBT>)m`1gz1bzwgNzId)^4GveLNyXilj5zT08h<5n@{Tk!XE5*ZTS$t{{`@aG zq`g)`+UXx-?)wi7`M==@BWDv!EBF5r7yk3>T}vxrQykg<wEnEjC{fmO&?(;?me2E= z$-O}Wc5DJ0A2t<zJ=r^g7>k_?+w0GdUv-s&^s*-`s3xDJDS?}t+Fy+_&Ul*2aHqsp zYEJ|E<2=m+9n>%2UFUzDRcomswm2iJc5{>ZcS7tq=IG6>HDSi*{U2!cHfhasO-mtO zthR6cs+$Nkdd)^Kn@z;=hm^_P@#1PNH=B5ykG(-sBh#F{n`{?_#g=CX7)T)rSfKdh z#K<pYXW;H)B^iFZ&)!*C7BJ6qZAeO`>!`pQob(Pg2N^HLr8DMP7q7jI)n_BJs!bG! zYn|J6V-dAkx~tct^8F@+tTP@Tle6~2^Vc}NJT$#}dq)My8&7(I)=L3lsC0Mb6~ozd zMxLEXYS1jiOEmk2J26IA`-NN~ow&U>q9F|b^2A{?7S9*BYWU15BUwRi``MoLR7MmO zOxXf_JvPpy*j7OzEzYg7EO#jXayUV<X4^Wm3K6nEUgfxFVhAyG`a7ZEO`)xs@j7IL z#}yfglf83wpACH+UI{;a7r3wA>ol?w<u7KVX&6T#AHO3BlUSH_Uk0XX5937kb6R*5 z8?;K(=AYJFAWZq&-ZgG>6dMq}>3*Q|N$l*@GfhA;I&QQ|PpJ7hmWrh@A^u}Y<G~T3 zoMYrfO;n=t&q&qlN+X{F%aR(lE5O^3Wv8IlVV*<sabpvYY4r!rU=Rg*e`0st33%JH z*(Y@v)8DDuG6=_@C;A1U4n#UQuC|TV+TcDKJ(IAAB;P=FD~+M33L20<q1}Ty)NC!4 z5TWcrLR!+(HwcGOVF!_^a)PL)2G8q2PmWh8FN+K{Y`CxM9Bxg?`Yn`3oUi^xyaDMI zOE1@aQid_DL98vti*Ug29JyoR`=PC6`XNwg^fNOi^R(3Ar#;&i4)Y+EUy|k5u;J*^ z>`jMQo>9fcz+v@h`jJ0k7zV%=biATkh*RRkgkZpfl~A^Pmv}w+V?Ag!{BX7_+-;@6 ze9AcsNT0?J^$Xzk{ltd6>}x}lq=#1L`n=sUJlRpC7g9&>cVLY38|ok$Ox1V%T2HjS zr+O=%xeKke>1Fb8E+kv?Tzb@-1!ZWLT{f10=rw2Ca=&@%Z};rOa+)=Vk|CW&IU=?P zmKZ1#v5VGmQnW%pLZMGH?0fJ=P0d#35Rqs;K<gfoO6F0W5igyE-VmN;-Gf%)wj^RN z+QY~cY&Hy6z8yTJaa;!dV&zi$RESX|mT(Y0`xsFTkesc=12~}!>Hb??HL!1D`~Gb! zN$N+cg-`QmQ@l}O0uC(>Q2|ELMo1Z(Sn?QE?HqeX2*G!()QUef)?wDjjP#1XS7-tG zs7+e!Ru3DE!2pf}Ewa5TkfBbRq~!440Cs<HAy6`;<|uomvi5mWL~-??ggrbcQ1e?7 zl#Y&)dEGr9|5e<YIm7VhSIiCV_Iudtg?aL{gj?xm%BJs-*l8$leaqP}zKY^&Q5G&= z$F#42f<dvTCr&xN&C{G|6d0$VBK^B6>8}|WTksAQk*SX_$Gkv@nR!Z^j$D;n4<URk zH181y_p|mCORZ@M7~vOI_&RM)=m0YG#FgDlj=cwlxR2kZ3a;9>j>yPj3}Dyja$$@8 znDQQbPl^2Q_8DW~>>IzBc%ZZ#_U5e$Cn;(5l<gRD2n<M7Qqp)_vuy}&mq_@Khn6r} zkqwGcd37jMy#0C92&rtdCNL#>y-0;o2RjozAunZXQ)h|0xBwY?dqQm2|2&!B-;a+3 z@`^dNfVqQa6<c&cxON|S>pd3ZxDLTRaKtMNFwrnjaD2=W@v^m(Aw8WqLB_C<6A#^0 zU$vN6E6R~N!b}0Z-z9oXIBqL4u8zNLmjT#;08flMoy6VuBA{4VC|0^5*@7U^$etQO zJDAquaKU(|ItD2=l>l@VPmvv&w12FN9)z)WRzF^*mNucQ>#mgvpDR;X4naqzAe)XB zPD-{Y4kg5dv=1#C6l)I%c`H%U-blQE7l;o!d$nd21sU=*7Dg^OqV2pEFfvk1!QXq3 z0r#Hg7f$X1ZMO!!u`d66oyVvkzsN0K#MJVCpzkTw6vfrySOQ{MW=YmY8_Cx8S}G7o zys{k;X!!3yZ<J`b%)x40WN$ao!E7(<z04l=^2A^iWHnvcXR8i(>OIspCEDEB#K!?S zs9*7FGL<E}Vh#_eMtZz`ajZ^8#zt@*UdFscjqt04p9K`b>VdW(_v@-X;vLb`a)5%H z33>5+`B~O%`qi-K;VfL+XgpyNI=3KowHv$|qKMbrF;k_p?dCHe0gC)60#!$&lCoFQ z?)J=1iy0O({M$p`o?VRi(UtDwoT>JJfWP|>Ga9nyTW?=$u+9|bxNkk7yM)to1peLu zZ{&=~{?B`ql254wne*7_K)j^vl+OFdu4Mj<=S<pS=Loqr91{^g_GT!B)cudY^i5i5 zpMT?uMsGUjeOPFC7eMin^0$Lj6YteTWgpczYwS_i^a-x=)jQ;6uJ=^g{BgI&EqhB# zV2@3i7F=^#ePf65>rRVbaXEP-`RgOdamUrIKs_i=dg^tvYoAz;Ll)|u!ip|dzti`9 zxl*4o)h_V+XRI1QpnDcVbw%@4zk&7Y^!SSVujlsa4wkO%GM-EW)yRhhXhqXj%PPK@ zB*v|%l)!9KR{$zi#Y+_Y=PZ&JD%?K<j91lthEC!JX&JE`F|X0<-=OuWlxQAYx&wje zm)`rx-n}!;<YpPzg=Wm1P}#{#3tp{~TRnJrhGmc3p9*|Q*FR(IkYgupLCLFv_5c^i z88|me1kjT6Ezh(EInx*>rZZR?Sf1Z5z^l_WR%m!!2dsjzw-<N_fAiw_;y-59iPvfi zKHBgYi7sZF4EXRK(Bf`1I@(x&gV$PZpF3Wk`<4rA%YK8IRIZ`A0vVeP_-r=9(qMQ+ zUs+XyC~|F1m=E`1!;5!XRH2mVPAQWhZ_@dlBdjC3HO=3FmHgnZP7AJUzL=X#0yVDE z>-({nyqo|npz~?3*D6K9jOB=?iojqN<W8nrj^k^9KWcY3puHqZDK+rb@VhpVw&>X3 z@1(<35IAZ>DGJGM7!u_XUtQ}Q^BwXDN(b2jFoCO<a}r_2$7J-J0C9n$6=1*?)+N!c zJrZP;;uWsP;I2CA%DZDh=P^+O6(hHuHQF7)vNMvdg69oXx2&Fp(6HOJoIer3qs(79 zfHuqEKHDLBgMn}7h676n%tlJTJ%?bc-<6!D70w3dI&LK3p7Ja@^IA019tU^k)x*|X zfaIMA^N>L+ig}LQ?dw|!gV}eP+<MgQeS3NsmIW=tI7Fmv`oFq0%kWb9%SHC&ftlW$ z*ZD6vVs?H*@W{Ph%)j5EQvWP;4#(iJ<C%@y@cEbse{J>oj>$c*nLd}G7S2GK#rv~) zAN;)ab0r?Wzs1Si7Rtucc^B;cO(wAC4XAx!^W6pzX<orvz8X{H+4mmOjcPf_dsn;b z^W4Q<Ue2z~y>Kd~ytS=(>{<n9S*7Ft73jMtJk50-nbJA=S{@Z-zcuvd?%Bar{P<r4 z`f%YO0wEFr5XANW-C2!I93B4~F4C%F<FF~d`p=YPN>fVQn3vvpTJkocZL@DXvu}fP zS0N2Ff<)y?E<dToU2NJZ{_!htF%QSpKO(hTC9sXk<#IXMa?q#Gs9coWtdOm5mr^4$ z)320WjTw>CVr`^ud2Op{?vQk_zp9oT4pa0>o6t3uDwz~c<ypWjjco6#JS;`pHcm2a zT#eDwdIW}%+2Zvf-%`39aqiTmr62ANSv2Y2O!4%aEPa*mqIA^~HO8^Yg6<)5G^>5C zieyQ;j3^D!$OF(aETMm#HK<n`&t0mhO@;1V*xR@xt98$$@&jn)KYD9a1Ow`uWJfyn zQH%-reG#>^c5IR=eWVhtu`H2d{y6L`tV}^f*{B)Q<dmewW{)<RSlKiDMGHJ*&M+ei z<4?6qhpxp=N*@bm+6po+R9t6|CAUuoi71tI0*d>6s}|JSRdS&rtgG+;^ZaGp2>3nO zg;eHV5bvb7*X!N5wqi!V+Eh1{eJ<@V6xKiI5r0~bZ}t$4F8aAO_>$kFzB$l-u=DY* z;$*M~9dP^41T4a1+3L)Hx-x65wANZNBW~SEMPnJZ-!hsBS9HNiXth2H$KOP&tO19C z_6qID_Q<K(>OOsieBiXMIS=XlT+DC*N&*p$6x$L6L}GCtCdfhgM{A$#*;A*RS2H`e z+vK#R+uXCKAWB50$rsX9S(1gu4J#uK)=+347H#{f&IqagqW0gR!h`=KRog~d^sA}X zD*(9gvaIOd1D$LB>~|-Ol2@bQ1oG}qkKZLFjytQqUe;r}45gFulsL8!=#A5oO{O_$ zjQDDzfD{IP#hD8w)sU3;2!*dl6=RifwU5}XYe9lG4=g$eV$O-GloK8Bfso;jUSvQ^ z7m{}JT?k&+Rgv(NpccShOK4H~g4og!^kQ2(@})yV=TC>UdsAUyx2J+A=@l?wTXNiU zb9hts!VxW!juWFDN-^x@&vA(KjGZ@BYoVjo86|p3oT9Hik(BA-J87(tiLKO!d$6r6 zIYUa&wvLYCt=2J-d>C^m|1bg~LN5*}5XRkWzw(1h5k3Vb8zbI_h$yNuoTSU}I)rdZ z2gO@dJ0szV<n3(XbA2C|bYJa?$X1jHHb)~Qj8$o#DYBt<rmz!<X3@B;jU-t^F--SV zE#?L}kX6vXjs<Tz`w%zet#u7GHoq*;q<#X%{2zXP<JOT&i9G;qZVur!)q!quZDQ*^ zXy@=>6}~;JRc*i#`gCn^eo8oc7d{cU=;u17&W@^mzzsoCf89MP<J~wLS&poo1kK%W z9p`YXtc7~17JE<-&*}W6O@PJ=?W=Y`Ey&m+5-V>bHE0=XP8_vr^LnVZdADRgnVk$> zy@4oktwK&0-Pyl}T2FI0P?JS<M!agb_HFyCwspB`vGy=tHZD$s@jz}=@%GLnvNPDI zZng}yE!@=|cMIcOZW}6>4KZsR42mL}EK1M6+BZZg^XwH&QRJ|i=RrX#s-|t{uwXLq zJV7pTEv99SSx5cd)xnI3!t?O-gl{KgNRC{-IYMcLJ(@*lhgobo+Vgw$UOc{hZg!eq zB)mV62qYyt*_(S_kKYERICHx_M*@9!w_h;TYNyZk%AIyEB#`HrgJ;O+^f52qCZV%e zei~VFyBIq=WB2<*dEe^=ods%v?)h4P4eX8r@Pwx!5%ZQP|3ANfclLzJ)kUq$*68}5 zDAaqV;}8wdO&T1~I6a<X{BQ^|U-UJyt$cxGURBw#N6OYqNxoxv<t~@u^Qnp@w^o)O zA8Pn|oO!+gMvLRA7Nak}JRAKqf}xf&A|p(b-WB+KjOL@q1&LEfBZw*_`_qN#?~OLA zVo75<TY{k5S4J1AKsZQ+mV;gxu-#N$D&iEb`)j)t^5YYo;Ua~AvMJoY7u|Fhpo|=| zK=~M3S&n{V@A0jTm2<((U0NW>nQMRZOXeeyYe3;AMzz*p28XWW@)r_x2$SPM4sLah ztacAjzh#bBA^oIM#Gm~l)Gg%kG*T`-+y_mWMehp)A*p7dRC~WPq;u@QFVk<<aD)-z z)rTts&dAY<7^}`|mUw6tW(~2_KYHo00vii*#6MqA4|a48JoE;=fr$Sg)YcwoO)^+~ zslv9!+Wsd@C^)|g+fxM^x$@O5AcRI~3DWnZb7wBDl?^&pW0A7+?URoqa^95o0I$X< zDbKvq2FUhAB4WP4QTo)*k|gDh1qF-Pxe&?d9`1qd?-Zpdi$Xu({(_u=HkM%58yO?+ z(X+RC7@v})W$-voo{<qPc5ctUY9;2LF`_b_`|JPR!mS=j{|U-5yg~IuamJCH;z5ci zDk}X%^}U{s=!r3?yt9|aX>N%y!&bh4An|LwIyjaD7667fRn%mTq8K9iOwv!k8$S?t zo!nU=_XyX_6$COCv$&>eB!{xt=n)|=eu2d(5mty;w1AF80?MVXHB6mFbRTl}DJw-t zFFa8%RV(>zv4_dp(=2#dx`lD^LzMU+gf6;Q!dkhfiZAh$`zRXEe~i2iMCvsC*4v?W z!Ufh8iB>lMt2l}v=x<sa!$@t}4BjE`#fr17jXy1yZ=BrrSedq~P!m3)1u=AIDdwUb z`Tz&vF7AMn8cD?TU9OkGeD!Y4;MRuYoBi{3bI=@j^Kdw@#m<g<ZY1wu0nbhB5J3=W z43ig!>cbod!Kti7dqenbC6B<Bv8)UsQeBTGl6g^54*%DsmBV5ieN7YU0CIAuB{GHk zeLi8ZWKC?$ms^H~Cz1~5zb5VKe_a-pV{uvyM1!;R_z=~4-u~NWqHMV;FTB3MUIaA+ z23WS^+qRUC*?aqj_2HjIwpk+FpkF0vs1NM}c}hm+v3*Ybr6mQ?(j<D4Ahnw$a(Pgu z{N-xx@$8|&LyuGA#nqGWdTY!67RUZG?XVfBjH;?+@7gg9we&d;%wd#u=_=43z`W?I zL6j^R{8Xonz|v{*47ZJ+d=xqbi9}e9D$comoKCq?$rtE5d>J_u>EjaA1P)JByXosc z^b-fKK1<_0*uOEWA4x%2lC5};@R6uOS<Z^U450oPucc|J<F9j=MiTqgJ29PSelkpp ztvOL*Gm>Q=58WaDV%*o<7QidaKzmO&w?9|4vpqDtz{wC;BW3{;8x>T%Z(()YG=%qd z1gq5%S20;w-lruCmx(xg2`vXyQsU6l!!a<nF3~f*b*hS;QEWX<I?TQ2iN6Vd>Rs!I z4lmC)k+HEa`aQ-MOIl+$H7E?4%o!_2FJibF_<6cLE_L_$eY~&4o{!K^0?8d<k}|~a z_Q00!?`n0=<tpTHWYyDc>&p$ryfwU8S(<P@GLmyh_pQZ!UTkA@rUFS8jt(&UAd$wJ z=1C_z*%;eBOG2Tb`P+$1L{709Jj5|WeXE|GL&QggC6A-|0*4_q#GndQPA?(pnN>ki zL^JK=WK=@2$O@S?;3NnKb8n0N17@y0JX?Vm>ozewXozuhqtpL_JcMXV8+jWlR{gr+ zop<(77S#g{1?m>`y-v)Z^Xa6JTv^f}*y(+H>HYy#=_Irdf=R82^BiPr^-6MT=sw6s z?E7~A{r0!r(2g6AC{PsCgH0^9Y`O*8bj>4#1gR@VVjHMhlGZ9J$|b#{UZ)v5rc5Bp zF|xC^WyZ9w7ApXM9xW<!sA1vZjBGr0OpTLX!42rMLwrPeUmw}>g2Ji0v%2Jrg0aOc zGh~_yPIkqfqVifwjoR!TqHX1XBFH5Y#fPt%*_4ryDQwk9ZRb8Otfro$H<y`*6l4y% zF?$KJKs)s$VmgazN<g0o$MAA^^3JR0s)wxk1=GG@OWPbv@7=dWP+*mkTXE{NKJHa+ zG9!?^>(2Gkd*VGHm6t_$A;=s?OUBxsPm(5`#AzZ?^o|jF*IK-IOQ@}P3+h6aZRKAP zMPHlH)7?liHLEeq0Dt<(*Es`;WK@k+aK+_GHvRsblYMsR-5msWf1u!gXzfNyT*(`F z6?B{s5_3l7v?{!kbmy9A3Qk)P<QfG1J${r<%|IR7)=**kyBTn8r5Z4uwdzv&_^g*3 zZLiN`!KwSS_~&A}tuVZkb6+;P4sgnDE%42-$0L;eIHah(RnMT~aFQh`3I7hsU}?+~ zSz(JS;pBA)wa!fK7oQGPF?PUgQ`TaFgi(!|agvyzu5{@&B6k;4sEOVp?gZkzIyqC6 zmIq&VeudF{(-)I0YYmA`Q8bk}7yWa)cfc9}yurd)RrE||xS>(y?Zgq1b@s2^#lPNs z=_2sDL~~Z@e81EQ699ZfbL~Q?vcOB-jd=9ZO`G<-6l_H51?s$ISwg5_EYCp?2ebT? zTqd~m6$5rL$sKOetcA@hv$4rqSW;D!uDu?K3V}I6DE$2V_Lf9xXyxVb2zG@1@+q?$ zudP{*nJoJ`bR;v`h7i}b4QwJMS}m|QddD0mm1Hb;!p%PDR7>K7cIC^LEYq)HYpwI% z=^2MYWDwE0djxDLt{}-yQ~BXfp<fSC8d-3-<K!xuNbT!mpkvbJn3+i}4jt76gme=* zhFfS|d&SZiNI84bYkL=m&bJ4-QT=098(xzXxxy5O13ey15pMh*ZNFADglE0SH>)u` z4&AS?B-`wrch<FY!>1%7`POrA#9oJT0<66f7SZbN$_!fiEg<M5(oPuk4oIH5tMC)V zK4s29<yq-TxeDj<<IgTbR4z@Zw@fx!GR3?4XXG$RkPgUkuQ@*qc@gBOR)0kfg>#2V zo766NXpt^P9BoQ78|$q1A0$@Ok-P5&!!ch=7HIC2Z9M5u?ff$E46J}@I||7VZtu=3 zPEX8wqfvg~KDdSwr3-(QE`3a+rI{Pk!(_-Anx*8u-Ow|%SF6S~hZt>1p@ml`O?rmF zmGK`IQTRM|Hp6kHPGcf*P5ed3781#uZaeCP+qe!sGBFUc(7I_^E$Mj>Lk>@p?HB3< zbx0e5{Ou+t#~J9juv|(u{>}Jj2iLS<er<w7p2aWL(D;LT!FPm&Ekx_-1B)|}e(a)$ z3E4GndV$WEUCj82&FmcawW;y|4j{iDC(hQPs}X7SEXc6#rUZN{IJ?#}+lt`qD}Q_H z!^lEDvp6f1n1G1C&DG_ih5piZRZMZ_MD*{C6?ayVn%e>6>R2m4<o=0rZq+|BKLYD{ zqoYM48lU~>ivlgeK0|B$$E_?Xw$1oQlcJ`>Q6}TJ1IeX{&9dIGbzH)|{?}oo3p{;_ zBF&5q8)%S3qSX3d+ldub_nr+DxMXgoduMC(JMMMP)dVD*rF3AI40aTthgW=V88-F& zUBcX}(xx|g)uIi@hVPe|#DjvI5*}KKCQ}zzZjiGatFndCYnJTy+L>jBvU?8}V)L!- zR|2RLp2aD5=19cPcO63EbcFW~?XF<t`ABYHg;qo740+gc$_Gm)1*-Q+XmJ8_tA``g zgty&9P<b<h=r+kcv}fi#+N<GFF>?!;*I4|QF$vs@a*=%O2d1+Qq`QU0IqwRM07wCm zB&cW?p)ZRe^L-pyTc6XX8846)78Vj1CQJKgk)9H8zn?fX_cp&b2nenK4Vi`87l)HE z%7`yEj@|)2b`~YZ?n)4w2rhu>H-YD1g1v{|J3xL>R^7$JpO<VAM<>I7mZOt)*x$Gr zw&KsO1KzX)e^S1tph7u0fs_m`y@hfz3ndN~w(M%(ZCWG6eOh9)jhO`2d~Q}LVZpBl zD<jhB@hk!ZuMkn*VUK^3U8m}j9!gQ3YO{eI-Au^f{eU&1dsY{49_{o`^_wj*`hp4n ztiFAsckI<q;(|qTZNjO2K~}pK{^tTO9Fgb3bOItj7lZ5mX8OuO-~Y6^jMib>rda?0 zkX`_Q`2UoP{=1HI?Puq*HM+3p@eOUNRW~9%m3F+Wc2OFU(M-0vFw&;mnD#2IWEa#= z3xxtx15{Jtr~G~Ur=Eomkj^0OT<Jq!GfW&LG$*Uj_fLSbWv7{}+kG)xseSm@&NeyO zN<qPp-8DDaC8OVyXfZ`vopM!txk-DQ5>w+MrEjK}@uZ<ufNHO@3jgCMrS(#`ZQ9AR z&PvDURjEh15fY)w?$%@ntx;><ygnh-xy@!*;2I$xVE5@zyR>WH)JA_fb#r98#J*{I zywPUWExJ=q0rffF(KoCi<NY9~WsoDVyZpz^MI``@<3Z%BchVd4$NgfvU9R!PfX)<g zo4&i!4fZLbXH5{n=2PClKIg?gPN7UlsqOybQg7AZT&6unfAwax^>V6h{kAmBZ}YmU z$>68S!CQkC<z?XbL%&-~W2USv#6Uq_-V^8xS)fE~klUBPbvlmLxo5QJbJGtZ4o|p# zYjt2M*iaAGaHWZwmS@0un_7y$zKgtbva8gljedYD^^0h|>${4o%XGIBxR;zT&*yf7 zijd;zT>=w6ws|_G$q_5|psFT@G>4omUxrHcvgtG05K#7_1=l<gG;V~y%%|+2uEuHr z^jr#zE#0+q4S;Of%1{Fe%{1jzd~J1}sI&8T_v#xgy5`x->2;Wb(S#uWp^F7}j0((w z>$m4dz~hWvF!$!-35kEOHs}By2kmFKI|rPxPi>CYOd|7lS+e*>As_(<P0}aD`4oon z8xXbBxVek6f@36>W%e&DQRd)?f)02i>@~yaQ)Ygl^#H48+)f!IOof1MBfa9U=AJoh z0<_L(y*P_b?c4=bNfZUy4asEO>-Y|nOk1=Y0I!krK{Bv1^r(|E0ol`Tdzar0E-t$3 zvgqp`BQ|iuN-xLZcP?Nv6-d($Y7B*Scn3TXTEhferfv!yqD)C!dnGodw3!P1>H@ch zKuyq5d*xU4py*6nYR~utAfQIvx{rEGZpUKB;>)?8vAm&|P?q&>-e$jGn8zA{fjHcD zxHD5vH%d1RAY+da34qJHt)JC|YBcfE9~g-HfZWlcJKP}@;DDfk)EUL3WK&xsNUw1n z^F%HH*~s?C4nl&pe?MHA6a=LK3;3ukAK8Jlk?1diSafbM23o|b=f&edO~`=SOLw^$ zPEq*nTWCV`{zu38z9Ix-U((YF4@NVx`~v@XC@UaTDP<168Vx;F?xY8Hy}z;m(g_kw zBdE}@V3Qq^OArn~2%4Bw1u*&UJ_DW%3WCcy5owf;UY%+gUFBEXr-E@H+5GCr_XF~; z_R1!i(m%I)K55sPk#LAw2QcV!V$EP}7RqSeT=ejHVJW?pQwZYc0UtvJGX|8RmdBYa zW`v{xc|e1(lp?_Fj{0@gVuZnn=pvrliBg)wMe2;^g-Y|Ob~@-)u9}Fzu;}g(^Ke=@ z271}ON^bNi$e^0rq|Lkvv-$%+g6{ms0sJ}pFHZ+JuLOOs;rcbOnHrCDNMh{}LE*_a z;Nn0a7tcILW`rokNUsEzzp$;qku01DB}KIU#a19A#^XtMf|~=6qg)2F5<#L}#RH63 zx@$K08rIAatnop$UU1D$!BPaQgXBZW7Z4<S&U~=z_V7jsp~rJ#J^euPey#ba6WlE% z7s<&1Q+*J313>4U%>^?F;S?t+Fvz4pQ~f)nPcGYfdM>Plcv;XIA}PlW<$2n*W7F|N z3nYKRefsz*{(F1)@6$Al<c|}S%V<huf;%nCVzh6t#?dnUFsZ;*ZZH8itaqSuVN=$V z%!1Je$M1Ekg<CVURAlF_r7lMX1)20dKLOE5*d(Y}KJ(28w^GKI?39r8&%woJ_CrN= z$<m}52zU<6*=!<@EiZ#m#}V7WC{MY8ldqOl55yW1jc!pI#x9T(>v8^JHaN|vpnOd8 za{6YAl{0L>E78rL&4FPJTHWx9i0%)PN>w8iNW_GJ_!e7fB)#77z2<+aGY@S}6>sR6 zj0{NBG`%%30pMZhv~7j&|7D!>h2z9+J$lh7REVB<86zU<22K`X@iNqb=qOno7pyKF zN)s&cfXwKH@cC*3f~qs<l549E{A_x6F3=m)?#5>$Of2Hpc4*F<*B@a2x50sIH`zYe zHMoaXgp6LxZky&dWH1Or1UsDH*s2J==T%ZNHhRa(=@eZO-bu?>l5YBg-3%j-0q-Z! z!+QG<O^Q!>O=-tEAc%lbxb|ZR7Fg92#_f8;yBm@4Cm7-Yk-AVpXiHIol0K_pelj6u zo#W<tV7|>@St7sA%^5&`bQp3*H7LDU5|9gs=iA{}Y#`+R>BR0C(YGPSoZ!rK`ZJP% z&nKrp^tK$|_npzjJvsp}0_Bmxq0=36E``I}zllAGmj`h#yww6*w6yK(?B?<b9hCAN zxsez9p4Nc$Fgemh-Wn!GlpAQ>WOKw2*bli@{S@}+23uy{ig{G=8}QN0+b=^xp@i$+ zQG=i)XU{gzlg6-GjYZ&a(!P=Ua~e;npV9hK98apgyw?}Q?2zf5YoFYkPb?jG(}j7J z+iE<?wMJG|jOzwgLrv3Hbjhd(NhWbu90XcdJgpXHMt3+XMQVX_B%f%qoD!<+*;cP6 zL7Cw|EdRmuAq$Hy{0=%PCCGkZ)0G{%$PArTxF=F79*~JN(+5-HQN@EqLzw|V7Xo*+ ztPr)KL`T@I=C>XA6p4FQ>=9!$6A4`tVxbrenO7wDSd%zZDryW2`A#EaxKUfvkB3>$ zWu>EH8e2vx!A6LLJfhOBPg1)K(-`ml4_YV7y+o=I26O9zY4m$Skq8NKPftj8-j+&v zcnL-zSP1wy9f6)cri@o0UL$`Y3V|f}117n@-1s?yQQ<>#qB?{bu6yxnSeycQ+4qE> zY39`-L1CB7d+T9($L7XqSs7;J_j`!jdr2ftiZt;@K|t`<2z-B+CAkowuL9jHGljd4 z&o0~Vp0<f4S6_4FL9a?A{_G{{yO(1mjxmUQ&iN*nmh#8tz`(V^KouA6fNG3H>-9sw z##=r|4qHx{E08acL6piuT8`ZFDLyoiGpc)D@2@dAq9&6_7wZ{vNm8TPpI#KJ46TiI zpuzG~pMNkPzJ>wu5QHbA9~n65#*~NeB<exck9(E_Zbwou5(pA}jtL8F{^*%}Ka8r# z6SZjaxR&CL%AN@gj3<O3bIeT70tC}(b}t*&IsXpJ0s`^;KK{7f8LXQd|AiPD(#$&~ z9Ax%-dyk+9pt>yXJO?;o+NJ?iFgntXIw`{=jVY7kk_ty-v({qg6PX9h)Dk@>2LwBO zo)qTkWC8>k`9wT6kX*G3!I4+%#*si6Hve5FK_2wffVQvZ?VRV5aT;nl`?Wftd#||E zm#>>}$ykxW!FG5E#zqQaX!~vgqw5$yb5>R>shvUvIs#+8)?x;J>TFpFcq>*0olDY8 zciFH{N-e!3;k<Y0oA2?(n?fH$CPo@$Bi-T4&v8Sd-*kb;TQ&q!N3g)9WA+za=imt4 z0-Nz(`McXhsY!MCan^j+EQiW{cT!+3VKMDKj{YLN@+>mVkcr`04yjo3^^mKW4BP$k zKN)&Ohg{QJ1@654m%rW9Wk*Gn*JOSQ+r?67nB=T0<_aeHm0MJ$W&B$3ETVWum`ex! ziAYyi2s7dVN4wEc=n0WTq1+zliHO$=X_UEA8g8hCM+15nen+Pbfx=B{A0uF=9$fZe z(K2XhK!evx*tGdro~8HlMnOnHg(_zACdHBS`IItDS;{tM`N!rJ?%e#hek{NCmcqdO zk%NX!@k#|BPBsuwU<IP7!ud7w@v!8;^Ef8D@^Bt3d+fSeUN;JGfaw;l;kdEfb2Y2T z(b_<8)}56o@SWDRMkd`Z5|Lp}dqJ<v>>Sk2@Ikl#E^y}S(9ylu!;|SexhD>*VKl;B z<e$;3#08xf;wIAG8m5NIZpVI^!c0y1B0xdTt*HzIqZ&HM9AV3WXZ<VI6)L0k?>^xH z4<`&{Z_vR5vp_IkXR&M}k#5#i6=8M%udy=6@q`FG7DxzZhrM;`<Vlqnlm0k#2rk!Y z+i+5(@#HaHb7bYPluz(FV85<@pi+g535&yezEB|#hk{-cd`VN}JHQ_xj30V&wM>!3 z0_gFI`-4ov2h03?U2Ym15#&`lF{dZmte~Evbp`)#&aCtJR?cKwOxgk21%nawK#C4M zN7z^gxe6=}9n1NfE84eWt2(C?q;px4GK-fVDBZDWA5sd@{M;qQa@ZHxLx;kc0o`*$ z<yh|RV|H;53)RA1^Ff08wsk_ZLtQ#1)l$Y-{GB-~QkQ0$G_d*z#^+p6hHHsC_9^&M zsvE2qOQJ&Nqy0**aTj>=H1VZoZ$uHogUjD@06S;aC}RdgUXrGCl?^1@mz$TuG9g~S z?`?#7K`MfIH<PzSJ;#dPEC0SsQy<v5gB>&npvU-;B+Tg)%5UJ;260U=aSta%8{%th z^fXgtr&44TlqMS-Wi}_oWt1ArIB_C9<a53eer4I|D8qg2w1+m<-b$}t;7$1XZ1H`< zl6li`6YaS3$2isxOlUZJGgQeZ)OTwXS(@;ORRNWhFJJsPS0)PX#ru>Z0fK4p4M)fB zq3hi$Xp$he^Xb7r-!e)7(|7NM3@Vo)fA$E+LcEfyy!jpkgF)AU6efN+25+blHdvW_ zKcV1h+5xDFzRcmvv=KeboOcrz6I+Uv+RG2n%u)kWI4%3I-E_Yl9EPb_Bm2HETl^&Z zN$^|@Fkip>tdSE39#M?1X>^)XRdU3?odybCh?pvQmZ-U)6s*ua=K~Kf*)sF2m@Nq> z?XmNxa=?woWg~<yQK}R<M|aOJ9v22zDmBbrey@7}Y9Jx6v{*@1?LI0pn$BmF+R(+& z<a_TO!WaoFcrZl@JJYHGOiI4I;|?$EDHAiP{g&nBG_!80)8ILNY34PiGF_6L-TdUV zNkk!Cf=77NSYAdR2!1RyKL{inBK?H2bXJNzib8oh^$qr~ZF7hg9Wk!vXK*{oZD&OX z9LP_P-!uIQ0u=j%^`L<XozN$dgE+6T@TI$5+2x?J8@Y~`2#baAzkzi0EvIapU5-TH zp+vTa$UYUU(EX0}tX7LD=j#jsG^!TPfADpVJ)!_x7H!+Maogr?+qP}nwr$(CZQHhO z%$<*Kk~e>$QaP2J+IuY_-iC8n<Jd5_k#QjR+IQzA<|%7nCk#u55dZsL<0coQVUb7* zec6^sGflFVDCU7ydWKMZZYL%PDj6$<VD$t>uxX-TlJV%q0wGNPaR25zWa6!`18zOC zS5+fn1F?1aw=i7bsHUrV`k}f+X%zV+*IC#WJl0(5v>}wE{x^6Y*abvw^*OtmwqP1A zE>tIp=lVM6#%Q-gICFGsmf<M+VSrW*`6k*88mLi<{IlSg=W^k<xVig*lD|&fn{XT} zRl&(jl<7C5W>+q$F|TPw@4b29gLVTcL(Ji_3(v73#x}(Z<ushlPe8Sx@2=33?%RS^ zrlHPvP$#rs_&0Mqh+Ur+xBNUydW&<F*4DgttcFnB66wg|sv!&_LLUUA>}%m!N&(27 zDZfTYxHeT8u*;e!jLn@MUfrb{zFEs?@&9ZGf^`X<StQY)aY2Oms2XJOvxxyNOu|U4 zQtsg9IO|nB2IR}DmS~d!f<J}<oNvQnd?MIe>e<TE$9S)GMv;Go>c3T9m%v&#P!b-2 z>P)MdFiqYLTWL)qA*F}%br%{$t?Kod>!e+9A{)djoc@?$M&QME(+ce3D!Jj9A~!;< zK{pBtELjD5h7;M~6pS0QRR1AIA!(aQDDTT~sftB&Ekrz%^?4)_<Da_KPoFEm!dq)M zg-P5mI@%A_y2DcGAqj<8Uo>t0*gMD9Y92gS&`si<>&WJ&-Q$(;;u|Dy51EF_^ZS;W zB|Ce#_1t6PmJR&$=Qu@R!gZC5#yK#r=$SU)e9sY7)}KsI;vi+=v`>>hAQ7iO_c2EF zH9{cEyXOz>9@(yW8Uv5it4PJhs|~q6lmqX@IvMoh&hyyw5oHabZ+loGz@?OnA|y!s zxMT<qa1C96ZG0Ah+vJ!f8&a~nzmLkOR6Lg1>Ky0=O-VnqX|-`#`Yf(oCG=`biAs86 zk2!loGqL``dV@*qiObul>TxQ+c4#A9J7G8U39l#mL<+ISFuOyFi>2#Cr9|F23>BpS z(CYHWVmm%V!UdOl22KMxK$UL{Yh^RzvE6_F3!?<cRiMtKzdooKHTD+NkQy;T3d|Vg z2wA{1oBot$?WM?>2c*m1m-W0V%b<Ob@%sGg{7wj;W9HM=<v)x;eqaYr@1ngpI==a? z&f{xZp1~QFD!}9Q3G>Q+pE&u3jJIXIYZpnFQzYHQ`&UnhPADjaIOT~yR?Td02kkmD zp$;I<^b_~gS`2|e3|W4gObQ!E7Rfe?f$|Vku7*z!CA9PiNxW$oCeSntDzh0&Ziom7 zKE!`DxA1Y!@u%M_&W6)BhrQFevb_Wi1zUrw&dPTjIUI08m7#9$P&7Q_6$H~8d1-U? z6NbIrRmGjLg|CVsV+{XclwdOjM@Ow7u2{2XD*|HOK(;mWut)`uxH(x|WSlRs91<d> z6-G~kX>cMvYgarT?-&F=g+`4e`Jc3VTV1m2uq$-m<%)X1|E2)W(bKe^EFo%Z-2T%_ zTM+Z!ZCWk49l<b?*zPEGRNSJ`UtiC5cRMAAA*YO1FM=F;NLMF~qB5h1=E#Qr_|FLk z$34FiN`5i1f)0*wuyym0lfDtc43gT`w)|4)sPfVSF+G~%tF{|5?-bDuig(r<Ou#HP zR!ERrQtYzG1E%oHv)J=CX?b*&sG@-$wTI+L0OF^e!{&DyZrK=sKJn>+RMIo4O};J5 zqRRp(AxH439yEtOS8D!r;F7_yLpV5u{cMJ)KRE4kkoGnE4--bH&oB9ini?HvgN-Qv z!CDT~jkfZ+KHgV)T02hNZH=VeVvLaJ?|X`wmDfZqzPVqHhm`-nBI`5wK-jB|i7QdR zjMi8Z6Xx2ye}0$i_~~vh(JJAkB+uVAtoRlUN4=R5w8*`FEb5JwsUH_?Qh97r406_x zGV!egr{Ml!G>A*jdfX*^IIN#{v3Ym)c>jS2-@GH09HVi#hEuk{pJ#7{x#hBkLJ!w6 z8dS$t@h!;W@^83dJt|DGcrKhpCP?ezVX^ryUQ2X{^%BJ<b^<*vGV`+4QHHN@%J~3A z|EAA{=dqWTBWu^%6BHp2=GP`4?D)bd=6?Sbk*B{|O$_GeTS2_%S__b$)+(EgV?UM> zJ~^YAc#nG6nUA88$%w~NmOXNyKT&C<c#rZu^nYO$jZ9k&4)pPw&88Z5Mzrq9;Om4T zEZqgkn%*I(MhKpWr7&VM25DM$2^Rit5VQe{hI*=b2hzfnzyVj%S-j7`aej5H=sF2F zSv?CE;%Is!zWn<*2U{gaKNiFIF$?=SBa&w65!9D*m5yYkShBk(f_QWEV)9pEvG|Q6 z#dBuP<XL7@`&1umz@_`uqbIJuqsO#;0@Y|nIpsCD$OA>Y1c{GHdkqJ1JnS;w;)L7L zE#D7m+{=cpo#!U8pbM=&DQP?`5oY)0>f?n!6UCULsVo9GQhH=h%%BVgL`{#-CpL}* z29Yhhs&iR>&&rrNEIVjB4F%AZnvUXWc%M?E(5p6GGc>h4Q;3d)lIxi!y~ewD%2-Lv zH0tj@kJ_m>eNhL5mzi}$B)d91JvrzJ$$zCGGeCZT3ru{t>@;I;VFl%{g?=SO3=I@= zV(#-(+yFP81!CjJaM@x@IZ?-p=2%1zeEyl6OgpFn)U1?TEk#ji!GF5em%^WuFlAr} zMD3O=uC!0!xz(Zf`_*%b>ZD&o=1Y`z!ho`)U*Ed+aJ(_!nx3&BB-Fcz!doa=)6IC< zxRvGpQ_j1Anpsvbx}F>e%W#xlH;*{PbT9oDxx)Hoot9vLx(^F300wWZWONtN0!_~o z!215wS#k+Z7m97l>Gg!zW`mcT#1iwMz?v<;^<YRWsq09>*NAPi(Qu2Kyi&OI_lGfI zkOZTnr_W5x+*@Fgj57)#r4b&;1An=c#S>s&pO95ss?Uc)9s#SY{)t6qy&d8G#O+0i z=!5;$iv{yf>=tw;FJUmqK@tLeXP57xYwW!wa`Xo>7O*xFnv@K$f8F#16i&7|pt#my zx$?X{Rk;hX#_-$Ju4qM*rqj>)u6QR5MbLZ6AB~tK2XXE=P*@Z7^t@R9a`+YLv{4>4 z(q-hz2dqj?L|cs9>ILM{Hs$bVa8F0E;1x9ksgkm64uU<|u8amdKI6foxqV1YkPCnM zBOxZ9Apxi^PCM>Hb`xgQbUFjL)_3sY5TZCYi&>*8u*1s<*cnd8ahNCL!h6K?RX9k@ zDand}Gk-IfB!)>*8LO;i5Z?6kpjfaCLa39Th}W$+@o^>fk$k0NF%<K$3pI@d5>ZtC zR3ig8cxG#N^@nyU1Z?&<ut3lx9f9PX6eXggap9GkhrV<cJoAyaTB%eQOz%OHlp?K) zxEZ`rc5SX)q%6)_Ol$1fBOFMZS^0n_G&UCZ`>hA@vqi>GF)hk7k}|Bu@iV<~q2shR zi>O)w<ZR^(9s<f|;{c<<AycUkm+D%lEPGp&hNfU!5(RVFt07__6D|)o=^0Bi?@XM@ z+lr&sg=_-BL)!+OP?A&20z+ZhgFzuDH!=u7#|m;iUImKQTK_hO$v>Q|W2=IrK6$!U z(%FBiV~9@*4?`57T58~2vPjm1X>^&Tj~g;l3${DipS?NFUGgl{<Vm*mJ?E83hW|`f zTIdBB@1td%qOr4HTj_jpEl?KJ8(K4#TA!q4&j^(hEP{28psf;!%b=p4JMj;etwmi} z%k>LVcI@vD4YLUtbjVYp1Ta&*N3rA$`<@X?Nbp@EgZ%_KUONQ`e(b?VGbj+7_u?t{ zY8gDJhAJ_j?FGKc&L4UH##rtf4B((mUrm42Iaz7jC9@jU($2b+fqrfUafQ#-HK-;6 zM<QBooz*Mq9&F8;1eR(rWCk<7T)4~Wv?n<V?Tl>@mB=!p6QM;|jpYe@<)u~Ls@wCg z9iQ8HJ@cI4aG|K$+qjOD?TtR~J<i~iH}8H<aOq#hJ|YDwk2DMZl`VcJ<X_UV%$7Hh zn8FZon9@*OK5m${V5T$6wJ?*|n7DG?h%Y5r8D+5|U4=(a8}?9A7RF%!29`CnbCyy> zBE9eIB*S;$WSeNbrx%|nJsWNhjz@N1&3T;H65Oo>N9Q_@qaOa=M5)$yP$9{ds*;vi z%x_9OAKAGrGORT>PGdQKoG$UY;O!VhjKzu-PHu*@LDb3!Awuw@^;VV4zMfxB+lcW7 zp?)?qYOGfuYi_B<xeeWA_wjo?kG-zkC_uLdI|mNsJZG5#?8_pxRP>7}csuZN)|J`& zi@}_`#uQj;3oH~<y*&d8d>b8*aVgj6v^N@UQ04Gq!trp}#Y@%@W8ibj^MZPKg3aj# zTB+c;Uskhg%h%6#w~Z=#PO^~!OQo`JF*>qI9l}W5U3hV8mJtjF#PvsxlIN~7i4r(X z{O|knzk5Etjh|i55PlBr&n<6zJCo>em?$J!9j3Qb&zo9w*I+gq2lSq&K!i=Mvsu;> zD9TmK$)S^ToFnRu&pT`e7YnXe8J~&R?nT&vNGYd5ROhq&T|Fx2w2k72#o_sa6L`&5 z{hcpgfgVfl64*URN=GIkH|GuSgH<-vfEV={GwXK|Ru9FMdyq0y-wiIT5Y;l1)*){! zYH8MHLwks^@>P8Mt!^7$SqbyxHD~bb%lUW}4bHj9hc1!^R4cZsG?6NENYE(}pG)t( zTA+FPc{>6&$aXv|7${Sku_fMuH`@VVIJfktpT|BkEcg)K_w7qow@0h@=fKzd{Xlfi znyLJFiYa%Ub+_x|KsNXH+&5FC;c4q)GPlR;{$zBv_w7W|3Nb=1-JxaaHeM|avno6^ z+%FsI1Zj2~m*a7Z`~8a^l`C_@0y}tWPDm?q_emDIC%(A;X4{3$jX{Z6F~0rtGQO;4 z{a+-kLg#1w!x%NRWK=*kH^J48nG%`uGAdu50nw>$SFu4IlPfdHA!k%KZ@fBH3uOP& zP*z?TeoNR{n8Y_KB0MX9ew)SPECZM*8@p%*hc4Q3;tu!330+#nRe7YdMT8LiwX!JF zR7fD#ecU+_mmOfj*oAIRI$$M#$wsd|!_c_Qq@Lk~XzH%qxnG~i*UaWlD2=@`OdK{C zB-InBw8Os+lyo^drb<=XaT;sPXzo)S#LjwTC}xHTT)T|YU(0rgf!{H|-)tI=j0i=H zvIVe2#tMsq&0Z|smADMdkCzaZ%g+CURKr*>&8u+~qyQ~Ntt^YbQSk*kD`-&-MN<R= zvTfJj40#}z9U~j3+y!U;!>MTMW}@vnm<oze4bPj}w~SH#wBUjOtQ*G=6F0V)2QT@X zSQDCxhe<M+y58a<*2)iOZLstY|M8BgbL~)%hR{4+B?wqmH6e@dmjOLy)-zxB8={^Y zh2`JeqN~xqS1kxzVMB(LZ8NHvLkC0K5Z3dnXHubB)NP#rRCURohOklqFdXzFKZdYy z)|SVFC7c3lm%Qbmh8QOq7}^DZc+=@_gbY7gO4>iM*;D*2rmHuF2XV-4;_KG%g(KRX z-kTh~4qorDwm4G5prnWH7OCPSXqi!B9lxYi3hgp?GL1=(<vo@ks``exJxZF-&dO#Q z6tuxdh<Y83>nl61NT4okTkOo*!zIU@X~m;eQ-)y09yh-&<gsgs2@K}fu3z_>MU`vf zY9iGlYHSFYq!uYfgJMu6e23*tj~sM2UJL-Z0a5dhaiVPZY7Q3#Y>DHMfp0n5g>Sf` zIN;OMMAAJA2<lI?)bd|jRdR0iX(j;S&0KNdKi5j%g=v1>=bm?c@>8R0zij5Zn-weY zMV5D)w7<np-?7Boy}1H{Nhdu-oCH23#i)(Hoas1)qr{*10yTzft%#JQLOz-<?Uj4o zOrZlex#$#r0ZgGj7Ea@TRy_EU%Y^aJehlQH*jj&}3KX5tu3<rVU<r4uZm<$fDSWB{ zAT&vT7IaqI$4(w5iGVp(n#C2TuT407^T&}CS+dErMKot9<d#G+^VmZnkv`F<Nl}zP zJWq=p!%qO=@wwpNPTcy%iE++7+6;C6YTM-#9TlEBB|BS^J|~TTre3K(9Q68PNj#5U z0BDXH=;BU)mdf+U;Y$&%-8Rh?&vWQ*csdUAtKpI;I~=_k=tIjJBZ=O%zFlc{C<$`k z=u<rGC2u4NcduiwE*l+ea1pEa(ruRPD9FV8-idZ%pZdciaoz>!Kq?0zRe!gI;d5>O z`&DriualykAn}2xH70At5hVby4a^T7<JT6N#K`3y>Vv1p1rr4R?mmC<qGJC0+I4Ac z!+kgwmVmRu3KW`C7=#BVT=M|Kt+a?BYXO0t?>Y6l86X?2Zmqpm2W>Pd_6OWCH_fq& zX6AX|>_bg644N*;B7*y->UbKC7?^7S3C$ZLi))#xqctsz>|Q0}SI-V}Fw;i}1=|1j z3QO<lD5~}#TIA5n=bW%SW0G-|{(LrLSJ&{U=*@eN>jsBLVCY?mFnlvoEDaj{-qg!T zv?ldN<qdi#2f+`lAdQBhJ>|#G`4if=Aq`{dyHdkzD39wd6y^%BRDQPy+xN|{G2`S> zx?YNvq<Q9hqq=1k!+fXM4e*Q+Vi#m~GwU#(*3lz0_Q(o~V3t$ZtP$Js!!yaJkPV3l z`5Y>y(UO%42CE$<?MR8k{Y9MZ(-KxTLH2C&Z73SggcIrk1zwJ{5eEfp`j7W+((u8% zl*CTK&<%En9<F<Lzu6`TOve_>=BxD168413yoB4nXYOD_G~){pf|OGy;NnBnE#bof znZoW=N7}lJdg||aN#EQI@5yHp%ZYA1LVnqsJ=7eVf?W41Un6yHyQc^AQM4J;bF zCva~9iW!G2J0OrLp*u;M;~5LIw%sKY8&NecAZQ}qCM=rB-P@uxXM!?nm`;P1G|!-$ zfCPIX`WtZ5<7(of!(eOuNvFl`{;%vEnzr0cBYI<^qSWMW7DBSu0%UZSn!2?w&wUqz z2d?7jy#9Qg9K@pbE5#4k+vNR%0Y-nJ=-udNu+}*Aq59pnQNr@``Qtwv)2NG)R){6T zX%AMz31w}@jEP2co2y)wkl?MYctBUABG7E?62QR}XC@zqyTemu)y38|Fj)IyhxOx5 zF}9+khr`}ZYEBe4ObIw6^&k{7lVZvK*O>m!<M`qdLyPf5d29>aVE@rR;YIm)Y_m+- zyBVD5w-+xtG6Uw$P~;~?U}2*xBJ9o4lIS8`=p;(sI`F^_Q=TTB70&w78fn+(Ri}Qn z;sysv?6B>CjP=PwJ%V`iBdA+w55TE*{iKn_;yk8B*F_H1*~B(p5yRmV==%GC6!pgT ziI1Q{%2Guh2}}FyV@B2(7E{L|6TcvDKaP08->`ZTJlJQl!6}<FOI>si(%O3!!z+v` zucMgRb@hj2lL76Hje6nlII(bnkNXQVDZ!T>w!xUGZ^aB1|JTLN+}FL-_!6MND!t{H z%x+mJBEg3qCpM_}67$M~bO5mg(ZC0}YP`WNcClkTU-(jSq1V?sPj-bJqh#Lx&iTZ~ z-}tHwa<yr5{f-DK#8MAM3o4L~uugF8;h{pfQFEcjAB}lCYp(Wt^??t@dCML>trJHn zu=gTOfBWE7Yy++c>+XMNC*?GW9=>s<6pe95eTCaH@Aqy5dTh32qI6z!-tiz%gLfh? zH(wq+LQapiZlc+99(xnMaz?VF8nR%0!Y%Qmqmq*QM_HdC&>(k_TeuIY?K+0dhnC~* z_&gNa@xFXh1K0$&q&*KA&jyLcuvPnvWcWellSb+nLHkblWqt2LTRO|6%h|f;MGep= zd?iVE^^Dz~&rlRPy(_!+&R~&4AzcaP*$5|3v=7!F+z!UN$Ks?2Bu?SfrOK!A7h>+t z>F}Jb#P*sn5l_x&9q-HM_S+*2NKux0(Lz*PFpQ$&VoWNC&WaqdQchH4PiiXSvH9vx zy`?cl4#h7gxAM*H4lu^)UGNl9JZB#Tx=@sprrJt0xz)lX8EC4OGU>xSzQ}`mX-|<Q z^NKJv;!SfHnc{p+76L?9Hu$2R7R0R5n%d@8J27fTe_gnZl(*b`y?a@F!7*}O&Gg!c zRw0otTU)*WXzU@75f?qDMSV=|b3*g0tpH7wbJx@xamvl_5H8^AOQ>Iwx2+J=zXp_s zNKEm!N?N&0YTaXTQ~V!|kA=Yfd>UC~S$i!WH;V#&lvead3_`HXPh^3m#uCqxw+l4W zViz{c8<A-(rqR~B%J9p&;2+pDi_h&OS%H>0>>l<vs%K5IEsk!@v>+;B;1l0Z=bR!Z zdH`STDU~T!itMIzvY<cINA(;v;Rf_!z6t60#KN<`VwJg>4KZd3d0Z+=6x#J;^yG5` z4WnbRQFgzdm7Mp&W(5Kc{ZW&Y9TFcE<(aHJ5(NIvy5x$pS=xp^#5dv3k8$^wRNgiT z+kjwNyyNe?i@QHJuDzeOqcTU`Z3ROTDfUjbfxhZ&mLBv)vL0iPEi5y#=URuLIl#(k z$&+JO?u=UCpx-KhskmP07l*<IwG&}Td;$2QUnQ5`vhL)|e1_?zst`Mg8zd6!;`R)% zyP+3D8HV>v`Jd5!=?^BqmimOswcBOVFT?1E)qJtQyNXWbDoLioQCz*S++uxBM-hq* z5GR51CzhK5C0X{Rjm3C0{ksvsWJ!Z`_;WzIuHQcftgRTU442loH{L46P%aHNrR}HQ zf}me#pK`HBwja;6WO&`{FHVyI-6LDBusy*Hi6*Rmj<L006YC9r{9|xI;%$GX;iZia zIiiuW7-}hQ3*o!69c(`ef6Z!HANQw4w<8(vF3uZrJ8WK*)S~2CuKPZV*l*qy8;g`3 z+Y83TpkQIT7aO19q9%C&=y&5~hPO<*MvDy*I$)n4Ch2y(aIg926ETcoIB$|#>`Oc@ z;r{uj_$!+`*a$UwXA@*QdRNZ4N8{8i&bJr{I;GxFXqplWiwup<R0Cfo%Vcu85zSJ! z&-@;(>!t9xJ9_e&7EI2TLUy419HFPZkoOF_W<>VR?CcPggBLT|1tiUxwxdCPtf@s) z)HM;HPjgxG8l>SDXq(uf-jA5ySvTj={>F8JOymHZBa0UQOSdKC&*4^mw!<@-jg9Xf z*iVpQllz;xnEu4-QGRZ~T*J-MEmFW&iST!Fm13X_SqIr9cb#0C{3RTzy2<sFoAU~7 zEoEW`AR!mM?_vUQ{|3%QRnM+6cJgRSXT4F-U${lhcngP8(mBkBXfFt23mak{P&{xm z0dI|?d(5&h)3XArYEFpA?R~#lmNj-I)hpPPUf=-M;uc^&aQ>6gb18}oKS;3MB4ZD^ zx8CBJd&s24RRqaHk0Hxp%^5^BRq&@t`Jy<>;13J0mf|$$s=`T@^DTOcc|s=xxqsB} zrETL!j(iyv$>`*gQ*yzR1J&p-A>xLnoY+ilkJY_3c6qE15{5X`G3Li};0wGSx9@sq z%xlk?CN^iYt3SlC;VGinxc1#4s}A?@4c{kHgi6E?a(r$;VSFX^>}<27HNFRq&;D+f zs9@nMyP<xOu@lEi8ZMD3kIS$|D^ZOU_aFSfxy-s|c-KRwT<zzvC9XC^IsKBu?&f|_ z6j4~+DY9wYT`<r|k)Ne+#uFR_NNL9w{aiKLA=n>z4fjInMup4(;K1numL0wqhZjnU zWLGUO4YpO=5B;R%?&JWGF@(;a)xBo?2YHUQ9;fs%IPis4Xyi~KkywYrO3cbRhfI6_ zmb#=UAYtgai=3jB@*Hr*^XjYk6?HT`$P@zy!28wrY|yi4o`QC}DQY!E>rdmkl2gbM zI$S<i{dH1;d_D}Pft}e?&M1%QPZNIdJEXl5V;=zX_s_1j3FsY@;-T5}BHx>{CJEXl zivafSkDIeM+<vz0-$xKf+k&BX{_%!GBtHg-@57O|y{%zi1?E&q<QNG)`YVU3@p}Y3 zwm_aG`~tqQE-GySgQbL^(<vK6YwPRl$(1gqKGW)bH$^|H$PrEVbY||MybeyxX!UQL z(mo&O<YbSSBc>hd>=SHLsYP!<Ia>d+sS+fL#ZZF}#0!TuNwChspEwz;qV!CK_8*li z=RVO{oQa7+S>wZkxEPI@RWtBv2;d^ctk<e<SC$?_4Z9j(2@8Y4$N_6n>-NHkyu@u> zAl>$i+2@6im~O25157IY3~j9+r=6|2-HD!CKtpgN)a@W<bkE?d$K?kN=@J*cX%?LY zzN=#J=U17BC{I=;E+8QdUEh8Nzg&17Uyvs&!iyYEq02=<y5(`ryINom?-_x&F~(%6 z;w8xWZrcK76z8=zOTw`-!=9c?Xz0KP3ygY>R`jYYGpT@)tj751wi01hYsEMq%0E#( zIm|Z6Twp2I4*{=@lpKGkw&~r@#&w%vCePn$Sb<oU!8Z{ad#1fq{;29HSu;s4h;1>A z6P&EcKp}C89~NXUk#$VxVEp5x%!Hjp3oBTtmv-L7A1rUv(aKS5hByR+_Cs74d>{ve zV7VsZWOU<^PZzlq+(^t+6C584`|dT^Xh>_Zw4k!4wIoJq539BE-#8e$d0Rja_HyU4 z*4BgnL-v}O>cI(mx0~dPDL4Qk#Et_2xi<Nry)~#Q6q(U0`ZJE!(0fkpQc!B<7_~C@ z%Z+L`aeS=3?O^~d31Mqhh;SeH;*&E`$VO>8>ZAcL&2z`#7<iOFsD0DGv4QgPYQP0@ zXB42H{1Km){O$LcPVnw-Nz;V^h)AFEb+VP7L<sCbGraT$i%8X^-U$JXS~)^}=1@!N z_v$4@K+eQrnvut&TVc|Rl~Sv<Xb=Fey<}zi9lkDlfX78vAEGWae?BZ~S67Dz&(iqF z)xyJP6g&iyHklbYm%3=`{=NXRGMW(&zv)B55K8rM3O&j!A`L5GTp0$l@|oJc5gLI4 zneNn5-wl8uPVO+qx*?=N|GMe4$->nEv{*iX&e~1)+G^U7ket<_O>AVl`&EUGN-Xmh z4bM^^rQX_QJ~(2=E}U4m;Jmt{E%3jKaUPPeI+NSM>D^kitRU)U7RAoV$&Vy2cIYg2 zlT@Hd1+ceAqEUucbZd-zXmwN=t|EPdF7KMmeS_D5B6vikaJ1mozRsc^v)@M~gD$UL zkGjaxZHIB5FZ;5BI(u2y_oxe;K9$yb;6tz2Ozq|^CJ6pRoV7Si73BzYbdQI<+M~n> z(@fhhCc#jM%2Id<V5WN#)l<_?fD-9DZY6h!@#dvEaF=nSae;4jZU9|{Eyd6|88Tor z-(2KoKaD0$5sc*EZH2hs7DA7zSN}KB=sl>3vZ@*Q(tqnHaydf+p{r-Fz`n$JZ0iNo zP}Y2@4W-toMl5#Ksu7@+V6SRGsK~_Ey%-Wx$(MM#;^H+!il6F!pavAqDV31;nURxw zaoCW@GyKx|MFc=danJtIZjx1iUIzfoZD`$JZQb!kTdY3f9IcdPm+UXskqGHjVx))# zexSf8<;pW)tE>Nb)?vlrr%xT1ySVDSmSjFVWcT|KDxz}|;0#%-*R8Zb=CFbh_x3`| ztY=3=Y7wlcrGL((4%K5aC)BvO?fHZe>{$N1n(}zx+0xUPooK6la}j5Yjwo)riCJ{f zpr`Kh4GC8N;t}tg4~j=~UoTJRVMNCnsr^3a#RfmAy@J7Pg1y1plraHi77i$A!CjRQ z(4VEzm?F~i+cN5Qd0$3Nrs&7VqjRRA2J~VDXgdggxr(0Ct1DPjLWRlJToF~b=#Dol zr$hwbm#6I3V0#!wAcb0Ira#I&1G8pAbg|K4qAbpp2$O@NLocycpv4?FFMe>HeUE6p zSD8B}4kHL|{OiShjM^WGx@>S%0otq%rWPUOC@}!%eU>!|QnrA70yav7A0ziMamgCJ z?dX&<u&hS!@z7?fZ81`yhr=-YT?PcfIx3VY5lu`g;oR7`|H${dMaB&;<kV;!ePti9 z4mDmh4AWJO6o-_H#}K(&o0t=KXOO#X%sB0{_MkKfVv^|$J~8i9ZYJ}p^sy1a@{lue z`>)t37+eZK29K?wSie3SK6IimZUPu{cP=U#Y0#8wc%9}4UcEB#VJXi98)TPc1rB1Q zXyhjFYCZCd_w#4rjay<Ih8LLyAdQmsm(i1)&iz@zHlUf^(oU<gI?={tSH9j++F0)_ zNhpJmgSYX#{3!vuyh}um<HUIpqLBEd^d&I~F=d}OY!(Xr6$e6pBb3Lo$AyWH-!hAU zB@J9utTV_sDrx!N7jKz3X9zL1bZlLvpK~fP#LN*JY}kP!Ocl>(I8f}6`!XYQRiVN; zGvc{V*JuxjN0qXFuA)ky98)ipQ8f44;Mye}YQy^u^a$;wz<-A=LjNFbvR2aJ&a{zk zmd|m5D;N{V>6^ntDct-$7BWNnGN3d!bTe|y3g@RFA?3Kq*&6}Z+?i;-mGTvgE{PkF zFcIU~c;JDWfRAv%6{)>9RbjhVPn$R1ZZs0{Va8__KgTkg0uq^r(~Zg7aZx?Yo}#M? zUyF4L@o{_b{Xe3i!6Y4xC{zG|VPOCOod4bhvNrlh2HfV_jM)@vxP3(RHp58jYQo_K zP1CFUR|EqFHa#S8sRK;llZ>Yc$BZCZI~t2v{q?z6VN1aJyVi=Tr%BXVSy^$pvn-QP zR5e8pr)<qST;A3Go^Oj^p@7YT)9kUGBjc`EQ7{udel}0bmf>6Jy}4LOgi|~%y*zga zPzQ7NaKOWRHZ7e%!p62-Zu!Zd9$Bxe`C7gDqPdL+r|j6)zW#bGZtb+&+AaU^pxHUJ zX;Zdw^4E(3_!_}08<6%prT4m0V{)~NE@nCKTlpfUXZ(wXx{3>qjg3vJsqW}Sq#yju zt(i$M7kw~^p?F6XmVoCN&XIwm^}G9KS;jIEq0B{=4o4WfSf_mc>|3p}YaB2bx<A`b z5%o$5TCws3PY>abpQA#%yvf!x4S=QIT02$@pJ@E*1>tR_m+GM4oARXsDUJOsN!^KO zAHNS$RTsFCBy8n#hZKsHHIxyovW}|nS#^|FwPG+ksStCFCazyS37E31-5v*xcI;Td z7mq3=H_#vB2C}vnR{$2pPP99)ovc`8dlIqId4R^|gyyB2f~UY6ItJ4ql%)O&3Ix0< z%$baM1J-QKBb`EMYbiJYmyR+2LxEm`N}1(-b^^O<F-E&oze=#ApuRqtm12$cWlKKF z!2RhS&bT^bi^laTCIh)0EoxW!9Vf*Lu%RA(NPw|!PwR1zwrzHR?AeF!yie1%9(xRc z!xukeV3IP!pFWK1xQQCuc-pkLuXfIZFkv|8+yre+9VA2npo3s?;1f%PKnpoz=u5x3 zKG(pY-NdC-KEQfmb}+d;?!_T!W0DejqU%wx;^U%FLrs&eYAH*de{u`3?8;}zH>4|? z{)pGri(Oc6_W}hzH!4A?hzbWH4fpMmVj9pXxw{8NWu|5q0W!HK{lbI_24IBrJh=TM zI3xU)a3u&8cN_Bd_|1+DQnVmXw<Y&-&qN~$_~1KrK194Ik+5Jsy>V8>1b|E}7%3hY z?`GioH!$|>gGVfo?TcUJuSuw*mT`UuTU0fQIuXpVVA@I|{JZtFs}01EJDW1!NrJZr z@6EGj0Bn&p1jAwiX8?t*C9Rf)4LZWPn`OHxa8cB-+wkal`NXQm$1_jsjur|*!|=Gy znh@tcx$+6BYh>jpZW{dx{V97@|K`eDz1<m)8BdTU*1ltejAJAzzHGv3uWC1_a_V#? zz-D!-XA@ph>~}*p9P=oI+Szx~p<LtV@rJyCp!uk}xnXr?fY2;=u#<hv$cQ&x205TH z{h$z>>CA1}b)+=CIi|Bn<vKjEF8XORVj_DgVF5s;O{FvPr%)W_`HC7<Xnr5V>!3oB z?Q&h8Mkq*=Qx@v5zfS}0FdydkfrPO>7)W`gEt)}f+ci-&ubAr3ES`GxKurl`*q7VL z^fmLQ=tE7NyUq*%>Az<F*jF2mCS`Q#fl4g!*WGDRR6evVS_9Z>-Ee+u?%ae!Av<cs zko7=Tt;lKFBWEMCEMbbELlC~z>5aR&Wmpu+V?*s#+*b_!%{Ikz`Gbx5;jC~798CCy z`>pg<M4v!HyKY-AW+MJZA`Np?S&71hf!h7DxvF&!pOU2%%$o9b=USS0(#mL74REPL zxVu)ZLEkQsFtJ2+ZpHYbd)wo*FPwAZBFC(9#Bz0EnX-~egp{sBX>NT9>{}q44}mw; zrgD3YFz)vC5uqL1{X18eUwX|7NjR*vqS?>@sC_vvK@XP!{U~do7Mjh4&;Yr&v^E?O zf0@&SAQS}nRA^q$8e9>)G%;b`;cf;2!H@YS!31*H$o!J_Mk2HQ_D;$Gm!d2I%FH?? z1v&s-4yi!*FC+s{{eZM!s4nJWHL54>+e(c2%Yv!ubb|oa4hF^GAc5lBbGY~2fZeMc z=Y)@FJB#vh_t`{bSTM&3z$DaiCVm=%<w%q&9fPF=Qs<IbM)5YU`QgtjTQ!+`oIQ6y zkbQpMP3zK7_%9N)z@~Oo@dc)%Re<XSZbAfr0~#!0*VV%6;IX>+oXs}y)?u`w`LNgY zAuI#d+lo)S=wRoeTAWpvm+j;$*|HF-ezAxRR1NQ2cm=(7^wTbnLR@h$G8UZFx&U6u z_Zd3G1d_E(0DxH#nBSK$OZqiDFL!eEaqeLTFqv|iViDXNni75h%p5p_k*w~4?A=#2 zjtD4)-2lUO=er;#AG&j_!2EUAAfLR?<yW;YK*9l{F?PYiR~=#Q7^WCdWYSsv=JRgi zCLD$KhHTjaj$%O5awC!a)5RfcVBNe?iH?b07(v%V<;tJ>k@JEy+EJDQVX$xahcV=8 zz^gQ~0PZ>W@}}x>3Df!8w0-*Nk%?$_uIvKk&*H^f$Gq+RJLmPRM9JuuqX8pY;XEad zy`V<*NMr<trjoDVT@V8W?KbH~YDjw7q+S<m_T5J--X*f-*q_0-K>LvYHR5(UG^)9f zr~f{rA{5vJlns{mg5bRo+u85s+=X{^Dwgv}8n!xh_(cOvfyDWVw}gK{14oJgbL9{q zn!rHwcH@oog!c)vvTOQP^zZ2e3tet&;ZOKHCr`7jH9la)$Tn_^G#Rkw3k`3g(jj+4 ze_bwD`<S<WY_~NQBScWGQEzn!nax{ora~<mQM>Lpc~yaD4rnA2EB45jehI9%CF4E8 z17g%o8<tAVtKtd?{mngAOhQ!xRx!!Wzqp}|=ZEAAUPkwF2&Up{TLLwpv*D(0m=Y&w zuC`hx2M`Db#oBBhQOdIKF9etWF<%dq!~^tG7Lzc+1wrSff7SjQcr=M*!>J4cq*s=} zuY9kPOp^vT=WVBIU^~MJI$h#~!rWoisK<Hdaki<!<puyTfL!I(To?|`r4xfLWK1-U z5Z1dm$fA$wbxjRnY~)TiVHnEa@(&|~Q2?!FSX>R7@L3ULmLmi;-2;3`iJmf*4gscM zS~a!K%<0FMDKfq*HY|>Yq@*@+df7!li%w%6PJ*r+C$`2s2)V(})-f8z+L<EMjwO3z zoK1r0lGJ4b_ftes_K+I3X)|nYs6N7X<i9vQ;yL+>!=}J6V1kjTp@1N?=48e(t}#YN z<e2==tBMx%wh%_BAUljSegillORgRjh>9_vo<SG6QxL&R>87)1pz<yeoaFB~SWfz7 zdCgZsi2}=jP~&#~I(Zw^iX@*0g0TQiYtu2tSi_G1zX3{-C7D-d^Czser64dD1%wn< z@y03jl>&7eyB-e%g@`Mv)SX>l4A`Ftyuya?aV$ED0r&)5lmZfqy2Ad0KR*~z#jJ|g z%?Pddw^!6;@_tG9AwwMXI_AQ#530&`msFf!G_he2kMRe3L>*uRzm*yMt^M2Y0Am@y zNTd}5Z@lwwvYHDAK8!#b56gLVA=FBvFjYmY3~_Xq`352tjuaq>B@A~U^C$nRtHYmW z_s8$uU9e>+Jg?HNDv-4s3R`PuUd1?BoBAs8N`2VA28I&xqHmcVE4^Q=KrMA)t_<OL zuCLTnI^V%H=61=G`(2PHx>kC2tf2*NSZ#Nwu07NgQheV2r`X&CSk%MNWYQdh+En** zBj~|^c1SN&H%AmVX3%mx4{vCds$04mg}BFb_&=p2@%&(m=XeYgXa=BEj5_wceEE&+ z)LCmCQ=X=DMhC^ECke9Q2BXokUPstOjb2%gP`E(K8~ySCe>wLc1_A8Qna&gm>geUz zNz3u^s`SyIjmFfcePi1lh$afW7(>fpd_K2#eLi;i4))%`eyYq+rXi|xccMeBSAo&F zht#xu`%)=`Pbu89@`c{33JM6S%T)w@YQ4*@{k%R;wm)-sdf$6pHStO_Ln~~@k2?al znk&`x#I4h}7cJ-xZYH`RI2szCNLnzZ$n6QdV33;i8(2R*m_;>_i$8uf(M?s4b1S|i zzjFbr+1W?d;%40I`CR!A-Ea6Y`$ZL-eab8PE5#iM=X!oOL)vHgD=uP`w=-J)>ageU zJvzylbEHkwZ!jqhtDSmd0IYu;id)vv1>c0?z*o@Xrn0@0o-sz)FU$4)hA{5K$mWFn z7+5bL4+~Sk$YMb`VKt<w)oSgBlU$9ZQ(|^tT&d%$th_x<;9WyfFD|2Q@^MT9w<L-X zsnGR-XU8t*NrTHTXUKCdmdkQNVEvRydkvwKOC`CMe+~rO>2Ev^IaBE!LnCwU4ItVV zBEj0V6AE}^iA_*DgOV9WD%Ji$YaD#@lh?hvU)7)L=Y?wvlCJQOuD2}FLLxNQfgZri zf@-u9;6Kha`|jvijfbE5Lp5!+AVMgc_but1TmBg2-K}xW0L`>*P!A_TA-V%Pob?_K zOPxws9(l?v`H6{b+(3CgDr;^R0<7cX?5F(me81Sc!lXOP6<}<b^i9W)S1Gp`fW+jJ z4y@=BSp7*mx1JO_iO2%{F@pAwasy@pP)5bWEC%Y;VI{miI(0lilzP`lvQ}nXpq4>g ze%JIAi^PPg#*_0R=;bpDe(d&kE%VF2yw0Pir(}=YE>G8>JKcz$R@wcw{B<m>v@9cM zPQVht>kFX$#uS)~`CC+j?*&49O%MU-(g6Wq=+n>7jth3r>r2v0^Z3TAjDuFD2F+6o zIC-&h30rRoN<mV0w%eDTRP2sRO<$c(ORY9azVfoT16<x$qs*Q&U+A<CxV<Iio&wzg za(V04!72=9+|#Z52k;lNdURIlkvw6{Wbg3zDfh%gPXyR!#ZePF1`=r8c)HZJn}uQt zqHQ~u$JC#<v>_f*H-Y{L4>zKqN>M%PuFv}$zUqvU5UA`PRzZ>QL1n++kJuVk|JoUi zR(a1-`uqxY@F7e)pNxXqLa$eRP#l@l45Yo?0_gBsLrfbGvhn<3zpWf*H4r(HBm<Br zJ7XfQzUhw!;l77V<!A9JNUHKLMz=50>Rb9CHd?qY=^Y4BJsJ@^8Hvv)N5R&Wo&g3+ zuT3WSwvv;U_2Kazz=LCdqv=A`1Osm>#|as|r#U-kwglT>ivx4^8$>}28T)ihuR-&; z0uG`6H=9wBt%ssKqYnektUh(#!_!ULS`Q|=sFCkbwMr?RF(VHg<fbeRcKcQG6_Yz^ zu8CuBX!(c4P-%0)Er$3oQwcI}0Z?n2YQfWqB@?o1w=7HMe^wh69C@3wry@VGcfatK zq^;W51D_g+yTqp~@#|EoJV_3vHG72RwDysR{Xw9@4=t>(y8DuFS=yla1uVg2rA>LT zvk9NSg(!o<T(|@#)?KzOk%5cn$~^0wuRVDo46|fPbrA}VtMFYvA|5g_9Ig(h-}*-y zu6WEiMN~rSQex&{?@(2TBjTHfP(TGpLX(jd)@vm6coLMbv4Bhllve3wol^s<tv$d7 zpQMHe<IOh>t^O(7oap!qWk5v1BDVIJ`!v)B-nMRBxTre%QxYS!sQ^|d+92~TG=)J% zp(zGv8N>0$Vw1~?u8zhMC;skDjR5t}oGl|UD3c(76updylbxyc-k+wquDCgUPfI%- z=Q|RmQqIY-n$$QRn7Ry4Vq@Y73O?~0NDG`DD}))ySU{J5>YmIu`%^P`v|35lL0-W0 zohMgW$kANn*?*(-q}e-ifZV0pK;$toUy`0s+Vj@QN?tk3kUMF#OMOAT_Z=+O!H!WF zoe6T5yq2{YEo`k;dya7ZI>`vQOd^xzAi-~XpcF^@4n@AygT5h_+K_sqq^XN|V<dC- z&~USFzv0u4ut&Y?nJ$d<JI6mw3mDtf6K3}i=u>QXJ`!hi5|+-828h#rruqRqC;ikq z2UX638zXJ4fw?}r?}z|DfAF%UtMMO9(lBhn$u1PMl|2&gwJIv@XR-I%cixzG?gB*i ztP1d+#)|_qZ%RoPXTtiRjv(vk@+~4fsJW?Kf&D_{X%J-zG<NT7p?7q;26{y3Itlo0 zB+}Wd&A^jB;)gd&bKvmGR+0ll+Bmk=@nFhiar#YCfIJD%9ZXMnuhd-7FxDRv&tqg) zck^IH*W>>YBu93D?#ugJ@%@6`Vg^&A_MDfaSyC5zi~Mee9<yGj4+ueX?Diz5!jaw` zDs!;D9xW4%R%awjLkT|uY5AOtqQBQr+<M_Uv-PuZz#r8m&o=30ch<@i#nY|lIt{gt z@cR==J*DQ1{!PA?C0E^MUEgo#y0Grg)_6#tGt<;Qgvf>qWh0C`qs+#27o0aqa7<7a zDQn2!)P7)#&|z}t<*m^yg1p2?7>p(R14~VOhNmPIZGkrqN~m-}%2h>0jvaq@e9n~? zUi~j`8|}sggcf;BOT7ZPFM<xII6JxM=)7)QSs=Ns5!~Y9EYv2qxIGU?w#&1rSkP_l z{w?ae)TXF*?9;=6^E3USXR6w;-}}G2(P21IyZf}mvMEMJDeZsFF+I4G(Q@r%&obtj zlMCLVsiYs-P8<Zb2=VUdgl8Hm16KY>iF#f~B0)jANj-5rmBY|x=z6m2C)@dpOIE2H z%|;39_8c>@dbbOC-T&lnfY<cDFMt|DOQyi9J;kQT+?G_>u;93NxGQ-EJa0+lGMJT2 z&aNQJDG!@<fp!ZIim_Ti&bzXQR|Xu!Xl49@n#s!KKmvO{Nbv?lvIlLW)Xx3|602x+ zNcXfTWB5WOpCvViaM^U}o5)`?z}ok1IURYX!zI|gIQvxcH=-NBKFTy^zB`N$!-E#E zAD4=oJOMC~#YdO=qGxz={R*Hc>`fKMG;hColiGV1XpOG%y2R~iukE;=`lZ7tbR`f* zolu@}U01+HwgZGh^4LD*zZUNZLj~7^L&_#og>~t=W06Uc=Q+b?hClJasIZ`Vo^9z( zwZwBH+Z#0O<yufWvx&PQ;1Aq@@NbiOJf@<)xOwG-T9!=<z+q;S(L069SzuUHa79<l zNIXi>D4eY^Q~9j%DghPLu>csTz~`2DzoMH8zQWDC!;-eDJ01ZudS5`nlo_2YllBjm zFG_$4DqBPdm*CzE1${|?-v#S5_+scs#cXq!u-@G%55kBjIV$&G0&|V8+fO*f()0@Q z-iJ+Bb>7b579|0nK;4-sw}uu9leJqoF>?38`BMu(!$!$<pNU`fSFJLGR#@So>1WGX zEVh+bxly!vZIjAfhORx0*AlvxPQ|m-byCX3)_=SJcI+fJca1d^*F&Y8|7LOe)_PfO zU}au=lr5iHbIH?Mxmt;eL#yRg@%Z=O8iU?XU_kbl1)$Gk=O*_M7N02Vug4pb+S;a2 zaQU4|V$(w~jjsVg6Q=At9Oznp@VYNa#t#q1cPQ@HudkIDbgL2eKb0=qUzQQp<lwL2 z2Cb+aPQG^<#uF_}39LHqC|cFRyMGT8NCGRjLcdpZMyra7^9tK9{C^Ui2+lGT`#}K! z=#T*b@c;W3*Ve|w{C|D)$!fc{o2&>vtGfN|5F~&x2|Xxj{#;J#k*H%>gVGErHTrc( z#*XpA(M5+I+OMs*F+`*j30cbU_EJ0E9iKPo=i^2R_QkIm=#=F#sHx@%Q^jrvn2JKS znCbYZw`i@c2Caq0A`1bOEG*c%Wd_f#3DD*#3c3;He75Ceo^P>gRs)j6YdwqQO3dCx z*eM{1<0N~X5@OOpP!1F>0GcOWit^=YBrdl6@U159HYtG`jN-28iFIV){k66`JwI-* zbveEQvSYCRs$Os@(Xf?%shFQ0ko2-rln%%UZgYDCY6qi~0Qg4Yu2wGj0Z?9lA=3AM z&8!fXNSwkVu1vX@^ax%f^Cvwl!`!Kd`QxkE5opHHQlL%7?6r=&^iDv-_OjHv(szB` zUhR6{Kw^S4tEpHzJ2q5<^U~#|g0{3!tppbjmE8(HK5kr>1nNB`8zlbJ1al31c*-+& zN<?OB(o>!NYA9tyBE1nxHipTfv>>qUCj}w>NWC-=5WUW)Vosj-%rQCSs~|ft?8$OH z%c0IWP^4Gv1;Y@`qws~MDT8t+c<KI2VIWWUSQs4WhSE35Rc^e|37|x!^n8=QsUTR9 zT*59|rq{%OiPaOeA~wlu(RZi%=??;%SGGcejgN~F1C(c`Rr7+<5x)j|R})N(8Ke9_ zizLj2a7J+hqaci|JcrclNoajYhfDU<D7PXoz$%M`7q=%0YJV!+;maq+l-d*9?Ri9= zoTith)o*)EI7L*xUTTUJf<MT9AIA=Ve|E|$I?(87>lO-z(vzWJ30UIsxI4sYHJ%kA z(TOqdrO$%CCBG{TF$w6zDSQc=9=)7irf$#8Nj*cIjb@#4m<NJ>^ZW1Guc8;qOe$PW zCJFD04o^mxdn<&&HvMz0qf>(1^0gLjl(Po@OAJA?NPZ7Ma1uB(f%qlDVGIKsKq6se zZ{(|8Q1(Z(CnF=|5nF8-g-vflx^VQLf>NZxp#mC6BS6g!lIe9?$nHFCIWIb9ljh;M z-v%XJFrU)j0J>vL?wDND-jGX3>Ii##dpQj9MC2#pE+U<=<5+!Y!F6pWEO`UJLwZ=P zC2BuYjBy|Ke<<fJXRIrn(UhbccvzUP#4*yd;%wI3OfO;8H{5)l7M|hdE@{--^6*s2 zS>YT9*H1G`)XYIEh@X))uov`q8Lcm|O5NSSK+!;MDq}UdRfry2U4FlGlh4D}K3cEc zIMI<(v9SNpG#wh5B!Bkh3@|!%Q)@XdwyT6l*?=7Ak<2}Z6@WSkio1Rn*w1h^95#h> zw4p>N9Kf5EmBgbRPVW!`u){q$@6+3>OtU!s?G`mUyub2KYNoa+Z&>UkM8;q*jEIed z7K;G^VGtplF@5QSwqhR<fL7u{qSUwQ(@zbDvM`X$t*aon4kDYD_XrSX!|ZQ(j=V-S zYIhRk*Jncz`E3mi<p?K{Vhr(X!tobqhi7<iYx}#qRmZ;$767hhYnLtE8}EfZoB4su zn?)s!=&|18py;Ak6tlmEXRse)2$>c2cMHS7a}+AvG8$_+urBuPuId9*LuTu~Rn4C` zzvW>8M>_}iu3(Iw*R^RkP&*-u04}=gKH~)!-@d{z2<xJrM+jcOtK?JkU*eM4W)Fs_ zW!vXviXKDerNtNSl5NxQ0}q*Lwiod{QJyU#yikvo9_j;Xck{xW{IPG|=ekD!rQxtA zN2klogj04zA)cY_B8{ol+)<{`aiz5vs0e#!1CYz2EU=kJC2Fh5gYOFM?q0`4m{uM{ zHrK7SE8w51EY`OQ1iQ|8m%zusCtXbw<QMn;;kbflzC<%=K1@t`q8;31+&qdw^o70r zJ8G-4OB0c<{iJEnm&vslx2>$lGUy)}-g%9q+uN<x*LL$0Gp{kQ^_0wtz<wJGytLy~ z%F|MKDbLvCz$rSgk$8jN4*oO0!8(4v)-kVn_nQR%2lzjyKb(?W-yjSCKr;yd0Pg=Y z{T+<|&Hic)>%`3##DA&;|Nr6Z9HKOfmTmo~?Mj=K&Pv<1Ds9`gZQHhO+qP{x^VMy< zG2VG&+|$_o*p0pRiWy(bc|J@`xnvjbeX-@r5Pemg#$q)rvySi#hd@LK#T~B;xHlX+ z_}TUXf)v<q6E9}967cKQulvw_Su;wWFe=jGeQbAjGpkgm_U0njTYo3PQiN+l{^Ebm zS1Py9XVtF=wB|7IP}-a6+XE%l1|w|AZ#b4$8K<%JJo?M)NL7cuUcXX|x^|a45irZI zN^yZDbX934hB$>@-PnGy(uPQ9Zi3cc)u?2IAOUuEP_1kO5l_7#(a9to@Iz~HmT8Yo zc=4?p`~_5!6BziQ2F95!ROH+q6y-#f4|E%LC}lbS_f5Y|lNQa>Qcu&>zT~cs6`_2o z$M@-!z^$lxU>jSa)BS5ocIO>^T-`v+HGu~7GpgAm!o(+vk>xC6Y*ms?zr@1m<hZNW zgSS(gx_a<Mp#VQ18Uk$Eo{YW@1fo%2e7uP7b|Sg8dTgL=mTylL<=|sQxAJz`gQ)Y* zl}rry+uq}Vi;Z?M<6?+*6a3fd?=E<dh@pJ)UK3%$><E{Nv*wB@RX6(A)X^b7dGK#t zlI=V_Z!W<1u8)Ex5VFPsa5jATwNOE3f(Pkyxso!`@ZO*njqI%>S81{wL~0AcAbeGa zZzbFLH-S2c+y+9Fd0(%s2cL)U{fnuRYA3e&I-H>|yd9PLJ9!mL0LscrVeHv$=C#PB zMMF}jHL<y);Mj>Hc5FcERbtn(0TYeR=i~EGOHH3CVCN+Q2*H^++vwYx{Vv)Ftu~|s zWw)bdkn^(yzxRaqj`vF}`@{v3%>ad6TS=YDbk5{AIO*0TEGXj4K4*)sMK~Izm<Ml- zsZqf)E2x*v(}^w3gUoY?CskJe%a~@md7pGMs%4@{J`19|COA6S<;yaY1XFvp5b;a< z;3{bBRaM#8fQD0S%q|+$<TMC{Mh%;36#zmQV;uccwRPJuX!B{@-}(pO8-%{ZWca3% z+q<)b*ZGkvBWh3q<?1{v5@~cnA5E*8uCvRBJQ9!kZ(pxvf3-G!b<Yyg8PmiqGbm?a zEoS^4bw9`6H`IJVC&;|8dH{o~h5J)yZ6eO`Sa)PZJ;hdOM4GTaAwD6>V&OU>?M^q~ z7Q5O4!PsILh#_R#jBSK`8)svEv^>>RcWDO1FpYe~Bz;au!^C`Pq4#~|)iRPNl=Svp z?s=GYn2+_Kb5I=6!f;)^QIAIn_L`RIZ?8HxI-hQ5YpVBZS-Gr1bw!~zX~1y}V7qoI z2yYw9ZA=PU`-X_WUDF+VBj-oyDRcUWh3zQVRwNI5__K(9y=W=T&8}RsembMx`~hUm zn~_BXyc0~<9qVPY^)3=h1=+?sfqi#BqvI`HLEughvnHs^J&v+{5?HhuIt~do%JT%V zbv*=i<BU8Kb{k8ss*whV3`PO(?&BNTUa<tx1!f&shqln?Wb{N_2(bzS{KcxftmV~? zL>l{V*&<5Kz4HwVK)9i>1#PQ0bf=*{I>V!Q-CH<XWD2YF!k<9mr>95wDoGBdY0jmT z3JMAOYnP#dB_D?XgPBi;vW`2B+Gma37hX%ng3N)w-e_J6*h5+*m9mv^h!898pIvXE zUU%*u{*0SC8^_?rSDq+5`R@QkUDAb?()EJm1Na1hOP(Irz`61%Zm}M#ub*nB3_>Tr z-4$un;aJ*9keiFTL9+3edsG<5Z+5zKbquDv!{d=J;bNXdXxqR(T`;pKC2e9b;lbE0 zJ<2cvjDzQ1f!$YhEU*nJSS-@$4x8J-JKI5PO6f6RYsSN-YQaKTyTH9+yJ|^OM!r{O zU@F*(W>7wUTE){#7}12v0&ovsI{FdhD)2f6)J`Pg7l;c5hV1kwG+SFDwM$@d`pHZj zwB-0Z-CzA&17J&jxdb8YF`TiPuu=GbRj(o`e6RfwRKMAL=UbP<D41?_)iXlU*fn_B zlT3HLgX#x$o=}Gai4GS}cT53eIPi-nYW+^-hd4p8>?(#3-@K?EV3qlzG}?_NxkJqD z1e#{Id_I5imXCC400D%<cYyx&kT~{i13T~#Z6SZGX<)p_A9xo?WBz-oBo48^kYv3y zfq##EU-iL4=;08<lkkyF>A!Rj&3++5`=_M~#InM*67u?@ei_Da#~*;uSAcZ9#inSI z(@m!2Gk(O9ENTN=Yyw@=GdzI{23z8vj+;_v>8tD5_=jQkZNqL?9G&7*7PpiKX1Ew% zmtlovdHwq(d@$_#8(9y+_8gL`?4#DAZRCocR%?oMTv+5W4KYxTTs>j9bN{LVB^w<K zO;Z$$v~bXDh(;heXUCm5@?Ek-u1ND249r)X+!8zmIks+}7%O+Cl!2Ys(aMy)QHY1p z%kdS+pK*3ine5D{!j_>8Nqv94p6GaL^CV*Ik>HsUdMjwHvA*`_)n=e^Wtg?uRo1T@ zhC+jKi0Bz+Iw&$!KT?E0K$$ijX6|cTLe#Pt{q|Lr$$$Qpluaj5I_@(~Hj`>lC+ZrK z<{jkQG2iO-D^lbmll68+0`BnmYV4`p?Ti0qExw(YEu$>82TqQ#o%F9|ZJ+zE*!%;Z z(2v(M&HWMC37iPfHIr?-$WXYedb~Jh#c6)-C}pkTEia=mV;I_R$?<bGqv$~j!FdT> z3TQ3xOjCM~KytsJB6P=X-Bn0i6f*UmQh(hO15Jr;at!1EemLmuE`s&sp$B;z%Iw01 z*wzN4S>glY0?=dlxc4fX<T=bnS!SlJ88<NGm@}3KV?(zb)<c97*wpBePR3N4qe(wu z&7!eUm+e0%cHR2N-M|)%PPW19P|qEqJ+2f;@`=9*83f`W<2HeRR>$xAj#6I6xn3=p z)N`2n;>C;}QYap;X{+bKsttGpol{vj2JwgPy(C4Yt*34rU6@{fMz%;0hP<{<=xPJ! zXr9ej{~q@)`~vpFp0=IiD%HiKZSED3j^!(Ufc}ler!})e12c4dRG$%>&_h~HXtFkx zxve>uFF4oz@-kQU@&c5*jt_m0H1D6a_@w*qYg=Y~o+so&7~GBf`wHsqgU<jT%Jk|1 zjVvYk@?uHc3d2m2e?GWbL!Flh+;py3h=blrrWVGJ{O3nHt660IoRb>ua`q{QpB_}6 zS6pdAXq<N^8XZU^KGQx}=X2noy&G8mZSGwAtu}`6+lv$24Y5)C_k~#APPR<^VxK}u zyNL<+M}zm5JFWaQ&bbR!OCTgbb&^btI>?2ODdjz3wGIg-l53=!Br+2H^$i(~hWLJm zpnV}4idihvY!PYibfe_eO0+3vJv}*MvDdmwS=OEaoVm^olnt-|wmc(D@C#+HI%ksa z3oCMFQHEa7N8Bk-HFhQGvS^fp+JTUlF)6(fDf8y+K2BL&(U90v2O&n}hzDIf`*!3P ziT;usw^?8zNs>8V<}?J{5u>)4gf#}wX+W=pmmI03&qa`sdwY6izWJ(;07er+)TnuF zyx@Y6-Zxns!$#pB;RU}Xn}qKEG-N(=lSTkf{CJi;NpqxJoNgYHjjnspk)Eaa-3hv2 z>YzO~jKu7XvLiTNbGNHc;#00jb{LmcCu?JD!`wnCwxqK4mJ+e{9m05GUUZJR+_=$; z3p8d=d>?&@7;r{_=ig5Dl+oCjw!%ea0_zfBYF7Siu2J_*_sKR{Od>t;wKSVL4`wH$ z$UIqd$#!p%5dvVO?`c-+>*K_MOLpVWR@~}|P&7rPt5!Zqn&@+-?YK`rwGbN@ki;2L zH~qn`JaVQ7diG@fO%e=V&H{z@qt_a*6UIk5a`mF9W2TgS>F~@^6_GV)y>K0JOt?>` zb~vB@IF*YB&3C#$4kOgbB7mnB{b$<=TbpET!?&)%a=48^_^Xu`m?r&88r8RM8N6n2 zsas}ZpPN~G!f!YajGtD@QZfqYS%xu@TVVWCFfIdB*qIz!cJcdw=O{vCmuP_mwbKYl zOIWW{gh`LGMj@ijFmmJ-QpK9#A9w;*+@>y$&u*YxO!oj+in63|YRSLlDo3W%w<C5& zlq7G_VWvA;<q$-urA-s`9)=g25c`wW+Z!*hSJ-&#OYi!)MrfLyND1TXj5lr>`)2_f z2~e`$FNgo6QQ>anAf2!t7PvoA0hs2Y70|qs1Yx_`;B4Z3j-Dh7Vzvq%UlH}e@Z53z zTZsFrIwQVtZr`2c;%q>!+)r#eRji*Bk#s8dlb8LW6NNgkQryPWx5^Q4>4*W<HADCI zUL}|O&avm&cHkly<71*(6l3okS~=~HYt+jtdFAgiIMOg&m{xY%O1_k-Jm8M2iV(~% zgZ$>6T=53Ad$kY#xxHvY+eroSsUE@C7C-6X5_OsMFH`qtzWZ;xmgosT1`+y|6W=iZ z+5HIfbT%9y004=!008;_-u<|lxR_c0zn<np>K-v0EX_YVIsQs=V%w|ZlZ9I>0l1ga zU2SUw(#4|%Q^G8><|OWw(bUlSzhaOMJ9c*VBnvOs8inbqk)$l+PjIpa9>@yFDXG>F zyp$#yS9Na6i^&I@tIW5jjCq~*4V3K1-r-FCX-Dd5YRZdki7?5G?3!gaQk82P#qGE$ zj~SggR`<n~AUKt%TCx>pr)Lu_mP61GM5}a4is4yOm>$awoyour(m5(onMl16<!#&C zTp5;uS1d|(dOUSi+NY)5T2-n<4>TrinP%FU-^}`E-j>2+Cuh{*`D>Ny=6}q3oHo4^ zJXlpjoo|9!nR}Xeo!wS^J2R^|>qw!RvdGz*&45@tTgL`xTLgI*BIbeW9r{~fK>X5! zEIemUM=$fWRGzpB^cwtKvQBa842N&uLby+Uw{*G+z@Y8D$~tY=2)8^P;~4o!A*98% z<-Nwa)FVfcz7-(G|5T2k?e<u4+U9IA>8}`)j?@s{(3|8o2rM$wnGRmPD{X5&pu2Hq zOx0I?syeFC3{K6~!>}eTdu~}=^OW^GwvA|ae!C5IOUiD}o(&`<I6U(xn|5=C@lwO9 z<hWPJb}g0co#*J}WMz6z;F;FmcoFTm3U%|c13!0xc^n3KUHEZx06V+u_sPh5w)VK& zmi!(8%;4;nA-rZGxVppM=7DfM0QI~8%|run^ksS<fbh)w0<hD&*X={cA%ac++`v1T zN_1CaX&d7|xbM1enJ6@^!7^T^zo-+&zqO?Y^zm4PyOX!of8dOhtyhnGRI?hC*0;Bx z-&@a=Gk=)v*yL7qXx3Ncm3su4s61hpa7j7Bg7<YS&ddGSJm6U$178y)aovPV&kxaQ z*Q}2C6pi(a%kFq)kHFj`E)yI>m)|^}L~m75GfV=DFFl3{q-wk9n<gx@X;1%~9z9>$ z?YJy0&01(+BRO{Bw;v<c;hFd~b+Rt<yoTmHeEl-g7N7PebE`-rao->}2;xe8Xj~rc zNv77<(GWS+WFS769A%@bkkKbz*;T+MM?6+x{tZFr=3`5yo?1C&2b!y^-|KHyCK`Zq z-#$FYYy>vbC+XZ|^1~zYxYIk=H}=Aj%GGw|CYTYO_<gEM4`n32YbaXueu5vRN$HP> z%$fG|ku3PDE}E$>{g+CQ@uoFGf;=TtOMQq9b!f$yr}Z(b8^i@$Cf&t)HN^{)m*W@^ zlKs1z?856))2BLKY@5N5n4u;Begy0@S@zUma5PwoeWJYhyn#BdQ=3k#ry7x!RtBwd z&~D%LjLH@rBO_)#+|^$(qXd2v!0`u!DJP0R*Tt772`5d6rVbs~KTf@};=(dva-?Wg zQvJSSk0SuxOv<+|N30`SwcJynfZHU8r(rO+82^EM30a)XQIzt4wUxLlTnTwiY(_bS z?&o7|;WB6K=;6V)c^$I|Z7;dss>x$Yv0bldw>~T`-L_jPID}0Kx)WXS#F3Gi1x?pu z$bll=LG^vk%!*3Pb{FBr5^j1GmFOLS4}4$?pGi2KF$l5kn1P<<YuD?5VFnudH9*7@ z0UQ$e)cL0BlrO&boZ#Bz?-5lKL6n`TV&~yu`PSiL{`K{7_lw)v2V@|S8!(NCqhh** zZe{c6Tqc?ih3v|3%1RfU?U?}^GX(ug6x^d}Egj$1X*i*?JE0%i7psK>Hc^<$XKmKd zgNsM>hJ3cMfw&9_MhzD0GS6^Pw?GmM#U_!%GcpYj(4!Mrn?8Y=A?kG8mxVgTTJnLu zxF)G%MiHTu+3u5Mcx?WTc<$}+zR5&y{KJSOZ+FIC>Ty|5i-eM{w{cz9dh{nO9$2Ht zFYZC(aMO^xR{SV<RI9F&f^z$n69Np|K`+DxaxwjprH4O=k-$*GRi!#j$Pq+g8(j(- zVX7wJQXbREh)@F87i|9^n8lY1heXlluJ}g7?R&S684+HEqVddczyH%Jq}|)r`TllK z5W>JBi#VI&-f+-9V>&h_RXJfWodU*{{fS-d#&G5#9^e!&=rI$4C+<f_@~hzD9L--j zjJT+4R0paF9C)96amObzX_PKK!WPfFt+nh;R9h#LCc4#{^r@pF!w~P?CL#B2NFMo2 zOT>YW5(|Yz9?1>3vX}~OHp9D*V6L+x`CKK%q^g%}>86>qARbTpkWi$TBP{Or1FU3G zy!lNAD$XBc9>;b*QP*FpY_F3<Uig4e_t#>ny3Bqf)o4kvDz5D70+!_MJhfaaYUq<B zDFuP5K-0*wxrvU~laep#sM(e{xr=0n%(kd;1Je9}5h~`MkR%d?o>wZwEZGS+wGXBz z7{j8VItS+S#U|*5NM&d8XJ#vD1uCMY30vN4N&HaJMcyagF#PdmCpyZiR|U}Pv$h=` zop2@lh+HWu1o=;m;Xz`GrWf+-@|>-y<ZT6MiZ;$%J3$xF5~}=FBzV|oA87q&L`wc0 zS>^!`NA-pO*kawhUVY$>LVe=c*R#apf_M@>5$BUKRhvuZpttWB@4t~wPzA%qTXU8a zhFP5Ki?P7NH`2T^rAZ-%>J@iUY`h{rXpKfF8j*h!Wb;6cCUa-`lXl;V9FSWk=6I5D zhwPaw@-(0Pw#V@?#4M5_P8Kz*2RzyaeZ%4l-$?Xj_2=ufJChg#UW$>hH<tXM)qQN* zU!^}r_Nl)?M;$NbOyL;S1-qMlYyURRjPWIxOSAfyA?_c=atI>Ag>Pk@S{G^qdfszs z$0(gBk0wZ=P?waE3K<-Zd;~}KF$q7$3%g~vxz)P79$rK6b7FT9?hjy4M@5G?Y(K`Z ziv&RT7!nnHU$sjxSBqG**EeTrJ?g0Q;?F>*Ec(jvED@NK;P;_{*9vM+rD<vuNq7C< z1&S9Da#agRnp1NHvhy|@;>nh6>``4Q4<#Hq#C+w7e_@}qCoR$wBx%Unf?D|nAr}dl zfOc-=?t`6cMZ=COf;m*X`-dX$gy%;iD-{ILJLTsk%enaBu&5Ba`;&wwh-IK>x7hk` z-?l52?K(n0N@eD9LFCB?y#q82@!CD}!KK1=4&AEgyLr<B7d;}2DX@v303j<&qS8Un z`~7(b_mm;{M6m!#f#yOkt~|^SPzRge^;H#kj3IS%)dZXF4SK7PE}phrE1i4eRP$ss zkxY~Wq`XAr7&ZOZRyQj0%wedx#)9I<JWlGb92^86i}6KfXsy8Sv%(PfcJ^U61^78% zx94{iKm2eqqz~wC!r+gGTe2xN+nv!opkiUaU%}@)W)*QnTqJpg$BHz!y*YUwYu7dI z3_G1w<z5V|y46V<iPZ(*`5tsva6*gnE*a?Jc3a-zeV;Egj|}OjFnz>AOj6?1#*@*P z+V{s5`#(0To>;W8L}D&4@dgIl>}z%IYw;rANPIRYruVeIUTcxY<HXPvMiGw40eyHu zY=NNpOKJ$5VRZHdn-pxN75V3TjHE=+=OQ$mhV<v#Fi0aH3gTDM4BV}C=`XMtB;_s2 z9q|Q$@scFJJkIZXkBE7BxZSkBdcTYJ)c<~-$9@lgf4?lCq(cX?FzwYxK&^T`UvF`; z_(_=F?q6=$IKEB3dugDC9#vg~MZ%MwHqDJubPGNqAY)gc%_+RI;D81)O*&RN1^S(u z4qu$@7~WP-u4IsiGM@FNS{|;}%6Rst8I;Ml3K(UK0|R&I#Ig`nUJ$JQIVZw1WO|g} z*V?4nE>LWahC3d%b@^MJh>gz_JKBJ^H|LlsB_HLNt7CwrQf*+)QIvJxc9{}o|A*36 zv9|bAEdy1FuY0eT_WXSKu?!OXZ6KbupoW!uEMZf=XdYPN=24%Vs%&{*Y$Lc{&FBt$ z&K^5E7G=zPzV}^W{X$0Pg<#ufw!eKOS@JnQ9;}8?iWYp)3+Ffh+WSp|SNp_&UBR&` zD{j;BNB^&;)zYzrN~ta;4hSlB)M+!A5o~Onxx*L`d!#i{sdn`E=c7$LET&^-xB3t~ zg5D^#H=U-&WLN<=YD9+`BxYMcknePsmq7o%XIy48^p`)}Q|JO0$9c6Jtb&e+aP1>` z;@W#jFW>h)`h<j-H@(^ul;TNwn}g1UyepM($1Ml1=J~QL(hP4*D$k5@gNH$L$gD+W zSyi44<-^p7#Dvz2xC1t;*KC}Wd%y_Yp|+H^%jX<6`-23@w@+K*`#m!Vurev*2g7fA ztyeQ0c~&F;5iD`bYU(o55dECW!|(*Zr1nD1cCw|Qq`t@KLl;e(&u@(=Ue~lc&YM5p z1503AnxD@w5xm5krw<(8x5vEAw7SN;sU9p^MXGP5=dr*k-5&u1)MLgmTF~X5=jI51 zSKW9PyPz+~q=kev9{wRQ^%S$`Vlb?feRzfDhD>6se;**rSP;{mJvcJlR8k6O_Q|k9 zw6(kE3JSyfCO1+le%EYsc|XS+%O?+b9V?-vz2GfGsGq<qH{<htPzS>!pI!+gLVw|z z=da&7`UQ4^Fs$3ZK=K=*>533ye-$)Gl~gE|%f2MpSI5^+<bfUb1zq<quGMAB5kj9O zIEh=xujrec`9e_(GT1158riN))an(lqZT@^_#a`nKjtFpPP;)D3b|j`qq*M$vB}G< zumj~(n3e%k?tkwV&LQQ=i$7lL4;1WEm}CGkkHjlel7|O4ZUpuNhZI>ikOTky$_=zW zd{H>X+HfXv{yTM9WPSqaFoLed6N4B)xg;LbHNtrJdLLs;@tJNOh!U=<V71|1BQEHm zq|MO<=?D>?Fu#`2Z}bRaj2vYt8m-MoHG!zAtcDgP>nC+BBn(BJznlJy)n0)r)1^-G zl=y9s3&zl+x)L4Ok!w!PTH0?#J~a%5+3=XI$3{8MGS0+|tW0;hNi4&{qp)~-seG2y z*P0L~-wpt7h^k5#v%M}K9-n6EY2{~e`fZ%Cx^?uB2Bq;Hx*Nz<4`GwU^`uifx<eqP z)B>!(8<sVwavrYO0-2OZ5#da-beSXYR}X6}AAGn^d^#+034#FzByXz<O|Kl=&LaHu z8sn7P|3R<1Uox5tp&^3YMi?o*GJ{@{yOp1)ILmz=joMMdnWM|6QxTj}E_zZUlAhUW zS=v`n%i9a7!d?oEzU_C>V{rc#=(3XFm{;gd-QPvAlK9=Q%_9pJt)RGo1Q~d40+u2P z*87z43&PKlN8=IhH8obp7WKkE@=DuNR|A5)NDl0(I3qT4Nc}lUiHk%@`?Mr)H@Q*M z>%Ss9!7!`;ne9dNi;T6~aiaGT?+J0!Eq}=o$)xz))#Ef*nY9iUi(0VZBNdhF^6QUh z#H;gW9FFq{5)X^fU15XF7S8K*`FcyG>`1p&VyQUgyZ@-l2b~U(Jj`9m*I-+a!!BeH z2w}2s#M!Jt7b<=vXLHP7eOs)`N8}*H>cU&m3DMkSalc;>e?7nZ0R5*>pi?YH>hw<_ zi1_#5{jWlSp^?7R|1dIIQFYM$e|`zScn*PuP>Ox`3R5E6T5w7h%^bqHQH)s>`Pk%Y zq%`2Lg&bto6QLT&*y=P^UxaLTwYz+@BFNhIk!OIT#T5E6Fhwfx=dxV{=eM;}c?Whv zs+ybR&+H>D2rXZxX>hB?CpjQrh|f&vEox5U|7XGD@5~o3pa6g}8~{N0UkbL>adI@X z{8w|9inPrJ8)Dam$|NPZA$oM(mVy6cqZUC(KHtU`o<D&u$vPQP+`o?U!l%dPADiNg z^UDIXjyT~4&Sbk&Z@k_z@gYE^N`tlDXJ1zMj@6sWCwD5>q9)S0kv=)|{9U<vv_gi1 zuKoL6jcpC_S$s=O3xCwov_Sm~IuCnYo$=Ay(^)d#$(Y$+VUwmwMY(ykVhrx78e^}d zS0LhfH&G+SNbMKopsMUJDz*iOx}-&vQzG6^n(QOGDes+%usoB!p!#)@78~PgdJN&E z^81lAzbnvl#bdzI;T3_nRcZJIW&98D3{s95`*~!Np;1&Vl7k6WlRR6{4iv6$IiyAv zBxVO7VMWfMa3M(th4dayVek^@eC<_hlVvA}{8J_#C5xmkNy_n0z_tW-KL*7L&{2h) zFW1Z%H5+_j<6WF}mLl?YU33q<^%hKz#)v~9b@Aohg!ZmlqNZ2*cAH{){B~67{@R^K zuvT{;SA~XdblZnq;BS7U*_avo*XOUZhnJ6;oc$Hti3^Y|ddiydNCdaF1G_c+1fwvg z`pQ(>--|J3_>a!0OCk|Re?4Wp<eX!KNYzt}PNO+K3D?o@Jy6<39O5=|af-^&l^d%p z>tJZ|ACnbHgu4nLN9G~9fT%+G^-QcPld4(U_h{m7OWFBxezlk#VhTnOP;jl^kR<x_ zqp<I%qlRHg#SI9BjmzYAS)k|k$_=4uDw`k=$TQx>dw0P2%qTkiTI0>ft#6GFB&-&X z*{!kW+u$mp1zKIc88@n2L*+&&x1z=We4MQ@R^cr=LL3_~a8G2x!>_ZUq|HJ#ogI2i zOfV>GV{L<YVgvV^Nl0QmZaQ5f_}!8G8wN#0o6RqC%!OW{Iyxg+6g8%vJISH;b)mDW z^xvEV+(qfn@p=7-4D}T3_qt^@_8#dKYGw>6mBoxY@;hQXVXtl7ZmT&HhYJ7XOS*1~ z+#w#a5V_)GTR;v|=qH7hP!4~!y|q8-j>v5+um_jmU%RAejl8+WmSU$_xK9&0Jy&YN z>pGIW(F6Nn>o#d%NPEiQ<%N7$cB+)VV>s>>V_89bMSt5K&xmVWOBu5gELRKLQX{8~ z3~{$@t@5hjMoJZ&FayTDxFywvkicTZ;y68#ldU>^LKQ%3V>ZVfkr|(L7WS-Z_6&EK z`Q?YW5xRHC=xx9vE5x+x+Uh_PuH)Fi-)-M6^NrAmG7;{1xHBSDpb9j!C14`^tv*dG zboLixQ|w3u+8>zrZZr@Cg)Ib4*GJoM@1X6MwpShm-B~w;t3xk>>e`Tyn9?u64EO9Z ziGg6H!IC}VL|cy5+!q;!?&RRVB<i!$VN{=~YfX0AuKDp0&RKe;iyvO#n$w9=<wWn_ z-V*RQ)Y4+OqRlAHd0lLqe}+63U%nb^p^UwE#9Jcn{840V%Yx#PK>Z=j@r1N~W0UsN zm(U1hQdRQjH2DVRS-QA+k0K2YdNvO~)*vE$HL()Y6-Z~ed{Mplhd%#0e#tQ4?QqYA z;_$L};QR@~R#Z>_IKPgL*VzulOv27Vn1I7^=Q7l*oPAs>05d@_@&LxWBFN8SV$2Xg zP&^{ZB5bIjfEyX^PIP4L%4i_$nZmI=RN9w;{&b037iwd?roPPeE9eZj(;H;3*tlqE zPrO^pj%k>msbFkY;z~*|!F~BK6bsfHMY-qw&r|d5L$UA-8UP6W2SWarQ`5};|DKvj zYF0MbtjPa}m_ABK=N2uSD-ifTcH4*!mcAp&>)AtJfFGfpx`ck0jh21YssHDThq2go z21$nrL0u;&&h!N1fJy0*eVT;<X9Y~cQM=Y$$<RLUtIkHjs`JwDdHcVR+LrvpB<pqo zb*(GVz@_2kDrJ#T%9|e^=nYDv`Xl=`)zkVi4JvaKp0ehu^P%P{$+$g-Ev&trPpnB- z6}2VhdRM`kg}pZoEpqSUl$vmNbhLv5{W}56L*ts&#V7ehgs8?3HY61l0TqGcHZqmK zDzHMs0!sS=B{!9$`g&E(Ut~dON~a1c^Zj*uSN02(C$BLZ?ca7Z8lN9G3W?(wZ2{!X zqZ<cG8%p_=4o#|a*Hqd?_IAI!y)~%O+Sb84DAmdng>R}aRBE(~_T`%{)=N7w5}B%U z&#pPzQ1^pM&v_54UXN^6SYiC|1E0~CsSe366G7GbY^-3{C@P{DTp6eTHtT}jH1`w9 z6*Pf89*O346Re92sur~n5n&VO!AVxs0}(}9<#C~gbZuX%sg)TXk+5iOP!5)_Tnq_y zp=PvOMBQVPP>d1lGHW(?kWZ>E*(eAeGaVR8sf;=0v3X3pD5fZ)o3lw9;~d5{4VkB~ zQ!G@~ke_;g{H^4av=*-$LdzebTGFqo97d9^N30wz86L{NifskgtBtLua#A`Ce<qiN z;@qtOhK(~OCvu3Ix|nu{NV-}NucFq4f|5NqHQ>y>J=L1@YBx_vy65Mgj|GBEJB8(I zQpOHLXpxa1+s}%+RmU~m@WH>rGwm7sPX8h$wXL1yKw1xXlE;rc#R|Vz-~*IvL9-&K z^(i#ebo8I~$MC;W!URaStdS>u#M)ggglNgv7!i^+?QVA>_E1JhBlSybCD%G`U6uZY zayUHl5K1Q1BX+9<GB<!)>~{1WJY>P}$C1fpG$XR38yao{?u5Ig<s{LUZaS=`*~e}E zc-Q)%Q8PXzEo$sEn70u3hsojb5^yCE&gySfM(aTSCI{kEgtuis%}x8p`C~B1{|4*9 z4Vy{`wN4m_gdGE8QT2Q;Ul1?HR~p_<S$bK4rNvRIZ)dFpX?8X5vAPnZ_|g#ibIKGh zDn1~R4~!WZPa_)YAq;`qG;R>J0hLa8`R5%ekJ1@Xxs}3$oY}zHPhl0W1gXArpt<UK ztrEG%dH2Rs$Wl26Ub6{oKV{a5BF`jIN0nVyo@)eLYguB6^ElpwDJ7n*eB2H`9gOoO zeoln>W{8CoN*r>^?ID1FO`!`oIrbBX78xWp3N}9aTM!=$F+Vevu6z#xea{3>!pQI} zo}t=|Zq&h$7;bLmiM!m}S<LA17)+;p`4qj5+f>rN4-Pf}Qdsd$K%{_~M@v=t+{LX@ z-e<?aa}4yU)^p3D?_DH)J_}jn5FVid<0y-O)@)MQ9>UOg$o#(l5<2^0jc`JNd&j;4 z)y4^W9#m6D3h^e>83=d%Ql%Q6LKy27|18;Q7<zWoRPA1-4N0y(1qxED`RXy&pbI-8 zN^z9W=j*goHfHX#7@BiEIQ18Y1R`u}`L0)3JKcy<hK7L84Vqp_Z{y$*=xg@w9#QUu zT$}+(L5HQhZeIs~Q!f%c_;-o>=P<pt@#I6P@0;NB@xN6rd>)3?82~r?k}&TT7z<)f zQgO~vF#PZ4{)E7Pv3RFwn-w>Q)1nOW&72Q!=f^zk71r;Ln`8`YzMRJogR=GC?1rCs zp>~B=mIHbMr+8JNEF%^;4Ue=&#`@o|{F#dV`51Fe^#ATz!fT>>5s+JaN4ZF*Kya^e zgPbDO9eMoZGdv<Na<x4RX5#N{f(7LxzZT`eDAy?K<$4J1H_!W(m{w}oC_gwZkJwao z1s)?C?RN(KD$ihT5Ls7ODX}>5!hWVA$H~yX{~Rzf;l3uw5qgS>zLtVTb#j{yTH;P0 zX8KlI-3%8F%~>bLljFwq^Hme&B#BwVv;|nO@fBfb<^PEi0ujvLp&Qfy^g%m@MO50d z37dkEMtOqO!m3ZqA_SORuFA>t^9%rf$+mC$Hr-<Q$N}ps#F21Mxy3N{t)N&^hrq*9 z)#mX>D&d7hi7Z`a9dnbLg9Luv0F8dTAe-k~M^_U~Px2OTwSH$|U+@4(*>3Tc!Y7W5 zpJ&Z|&kxJklL@X7j<46dPSbJlf_sA19XNyBCD9AQ1LDNG0nCE!#wfL+y2e6d2~uMb z?gwIOpcTYA8b7^{2ViBa_Z8W(@b9gZ46Na`wK>3r4OSQ}v`tby$x9Dm5*3)U6#QBl z^x}ftu}UENL9b$PMfnU&T6!Qgg(Pi)I1tP!DFGtnb-I*?jTelT{2Xm`7*1s9A<A#w zXKQ3pf{I{kYy9DMH<s+=HG_189Wb%5a`<mzOt=Ll9trODFx-Q|9FkG7`B$EJtk<Gy zj$Em_h+Ecr9B{g#NbIXZjiNd~EwrV(3q}VSJF5!jbJOc_2W2oGrd6R>;GtO$?pM@z z^TeM*D7zkr(snaQMoqyS%@?B9^yrwF$X#T7<mg<XcweS-z3%HhN*&d)R%{87T-^vU zH)uG+GUpadOd+Cq2hk3o1Me&J<AwYKC5#&-i;i$Rk8&XIv~D!!9Qp8k9mH4B`PQVf zXSC?IDRqt!jOhWL-+4O^)76A8Zik5QRbNcb2d&Z>>^qWhD`q5pFJ^nm<vJ}G2+ep* z=wv{A2lt7ba`{KW$9ye8HoSCjwxe45r-*}o;spVRsjwWA^j)N>!Bt;<Uj0A8LAU$V zOR&&ir6cap1;qkB+50qa&9Rc9(91~(%xUa>1q1x0unk-_srRjinuoG8ROS&43F9@6 zH2oh-_<^Wu{qP9wx+CT+=nrKR&q@JmtCy8H*z!}Z+?(-L%!?HJ<Q2_i>2@ZOc?j)D zH#^>ZbM@-ciw_1P;%n2R9NZBBvJKK_TjA$ZZ+wnslss|X_QQHkUzvjHo2kUr-u44B zkSZLP?)l&QuLGD&X)g5F%&_Jq?Vimb2l#;^u{>=9t%!xWFeq$i9Ca4DTqY-Rxy;-j z%`xL^EeV4Am`FT~*>O;a>~zOiXKyYJ?=IVE6r^0J=_`(}j_W$_(H>Zf6F^-!lP17# znuv75$7`irm~lT4_1P1ygfmSl7c%H?=8DJ77KoJn_LTiO#=9Lqe}zGS1#oMWjJ{4y zmPsxU_^<>^(W7OM=2_ZY5{Aq<ZJezqu6D=8mD-%f(iGz**Lt#zeXdhcusWW9Ir_^% z8ckM3ZOU|^hxKf5QK{W84s3_y8RIk}nfbU^{#XqLWcf!Bhx`umsfq6QX%Tr8zA0}9 z>kBsuXc&k~Y_i|+V&-ax+fle};qm)yEtt1!F&uZK-MP@YycSe3p)>W#C;tP3d9>%( z19?xPvJsf>^`j&;>ovcOn_uFFp*n&CR8Ts@$2U7f3~cjbyn1xF4a<;Ib7Sz%+{5pV zG%s{OFS_AHGu8qfcXosF8f{cRuS1dDX2{io@E8R4$2~rLLD9zj_u8WL<w~@~?wbbB z_#S`r<B-`Ulv<8dyS~%!M??d1$W@i3Gxa9u7q)|DfSgw%LbQnur<}txMgGrMrPz-5 zoET|{2LXIcz~)HT@y!rNL2YL5<h_ia!3}gK1o1yiPU0O8j40umQP5@Eobq0c_O&@n zXGm~2lzlH|W~GJo#c@mgQh-@-u@hdK%-gn}wdLi&SZW6C=l`R|k3xC9*_i-<?}7hD zjT@RdIQ~->uDmQ<Hb(1qUA~|L8+Zsz#MZMn5!&vRp4pmB_N71BntwBP;L(7@Nkbt) z{Q;1t-Q9gZSE;zDuwo^0nao^!w~mL20=L6_l~%hb#fTIrtvP>GZ#Fu7UL77<Defdv zEf{Yljb#rM6nFZ*I3>}r3UA0XY*g60B{3VXq%Qx(W!+q^_!>5(TKYchPh2u`uA^h! z8mKq#&~Kox2&oQJo01hNnERjn_a*6+rjX@t^^P4Z1D_4lt)=45S|8era>g8vCqqRY z?S2T^W$CV|$!2oaw9d8kW*XWl;2rAaqv6a<$Em$Xk^p=&dkrR3M{C*1lA<-IHA(k> zW|rr{8*AWeYR~P}0AMd;>sn!pyvVXMhmL$3=T>-7L#%E$;fW;ohsHK3Ztq|VIy$oZ zD<^pxgb2xnr9ZlueF(3YqV7yn?Zu_*(sOA;#nrTXagIWv%>(!2)HUeE?Gzd9>BhCJ zT3+%i8D`6sDL${?A3<g*L(^ii0LQeqr{oeUhdP&-oSxSOS>EhS&x9_<lw-x^rM2<O ziE+arWR>RDRSaI5)#0n=Qe`!zUb3l%%K;^*iZx@UEu)=p2OZ~Q4L}gavOq+oX#<gm z$7wYHSBKZ@iRd4Gk+N1^eNPMWSZ>o0MWGz({9$gC?ySZNyli-(zlKzqFX$W6Nxv3l z2Ct@JJs~}JYoaG))D#FJM>B=;{s*>a)rJFy2-sS0NSDMYqSjnB=$%7jB?><U2P|`r zl4?223^H=k(VM7;diTM^cgNw?1A>j+`u^vwF7@l;?9wMQ<|sw9!AB?4hx3i@?eOpr zbU3b0r0E0v83oPOQ_=F-IK4`;L2Yk^%zw@T11F0$)!z#AgR<uC1RH}UTObuayCA>v zRRu$JIbCZGFkQ)TF3};cgASoOlwvD0J|*JU*6XHJ8@`ICTrg^DxHd$Xi{r5Rqp$cq zL2b@~bmhw6!sqO}`WUj-J8HM{Q6QSzcUy-7-!|I*1&@Zk(lZXw&^^5Um}XKLf;U6W zT!+1r6glH_49V(a4xs7Pc@s={)AvI_hgq@S&=yFToAG>?ZTM`^xTbSk)?WIUf>!bS z%`-)-_X&xJwJz&9CW^%N>H<&RK+}HLvSWR2ROg49)+%CKdn{l*JiFMF`_Cb@=i{@Q zehcqdToxc7Dg%MtD+w|93_?hxtKH@Nm=)%e+*Pi3a`<MorD>u<npFtnpwth2Oyg;k z!WiCkE6rvD!R0>NewhnZ$=^$RNv0lMN1JYSk+<Tp4cD8lOY)rCsMf(aft>7-1jOVN zsQaCimLqrb!bZ-PAl(Kc6SxZHs2jmp25Z?0n@<IlH!xQ<K1|&)<#%@3y$*=Ujk)C- zN#N4BsUV#J-Co3<LPvBn`fd}o<+`o+qf1kofc!dnN8{xL`#Y%Z>m;eTjW|Wz9xyV2 zz_yW`qT*V-P8GO(O=o(6bL0{r{64?zTh&P7n5evFy>oevmW-YPDxxq~rmJ2?2xQ1x zB0v_VnVNpM*2LZ$3@9_FebLZ8b)8+gWlsa`E1g7kBS)0<1t&ob<`-gO%(-3hmtmHb zza{DLmjz-0bL4BD9JQ{7otlh-?^Z=}pLPkM=u*cdkik~dL`Hl4JW0uT&tFw_j~5iw zoQFZu0F^fmB~NSIo3n}lA!y_?d+FFJHXIk8D1I?sN&EvSG+P34RcWDPfoDDe-W@vP z!k)rc;KguYsSpth_ZMZ{)i1_2LU)4b(9{H}Qr!Yb`11i@5c}?4RE@bRIQJ%FBMUzz z9%Bum5H+EL;TZ0UA367Aty2I!_-he%qxlLtf^sMlCy}d6ie0(IqxDMO)o65ZO)A^y zRlas<b*)`;7Ob=sB_PmQsH&(I=@!KeLFZQNi-1d5s5(i*4fxZqJCQtV-e3d3At41v zx<X#ieRl}DP|?T;4v|l}DuF|DiV2XA2?JLFzwQeP(hf9t0nSJNc;(VH6*Lx{)4JN1 zG1GMJY$+w)b=J!#*^P*7U3`+3DgXs%>Z?09CRmorlpeTNE$25QGE&fN=qOn}s>0Mn z?M~9#W$gm0v%hpt5-~t5yrz;I+qwLFt($quvaLJNnmijg@V;I^poh~H2!HzkinCY3 zL`6&{6>@os5Z(3U+IJ6aWl29qX9CI%5kh|W%lp|QzZZo{V03LjhsNIbamKc^=ZNy% z^KSU8h9Czw%A4CwWCkZX%lH6|T!bfM4|wwOAk)?mMlo|Yb<0iA$zTXZaMSl+mikTj z5wmwN$pCci3FXAu)qo}lqVy0@tq&FA?{H)=wipOx(o`+QoA8PJhr%KF4EMh1OO_!$ zfX;x~`WFroX0P8bR$qic1<L|RY`){$E#F9`tPIX>7!45QmOqe#Z9PX_&-W~s_1iWq zWig*2-{bfuKZIF77|*oN1f;BXI-1083uGc=HO7TYxL4!uI(6zm3E|6N+p(n<@%Sn> ziXgW&ArMHuYz&CVZ7Ew_B7XCqPD(re=Ef{lP-NJAPCa`uUxBz5xA8n!Tx}~j(b0ng zFvjgR@i0#d9X<1BSFv4C^MR6$6e+o9kAGk}C#WP9gFEPyTz1`h?`|_1(g2~S|IB0t zMe|<dBi72*9);y<O<VwdEG~k;<Fk48v&Fw>7}_m<>7hwDk~6T1dQ=$e`5=MCI5%76 z%SSAop60rpUkNV9Zb)%d3CO{XuJopK!zVh1^ZjFuy6Cr5`q%wKbJnVfM=<YpV(k;^ z#SS}6%rJf4Ur#*+FkYbCtcC7zbE;r#!|sPA%SHu&v-NpsSUqqMBirg~gvd|2A%B72 zsga<`DO8O<40(eKb(rMV>FtCNgg6xn&gKxv_hN#}TRVS-5XQmj|4aFX(VfU(HpSOk zX*6kVPf$#k|C-rn@_4?9!Rv?uIKRPyZ!v$6mh&aGNn3=Mq+w@_1)gvayy7xo$Ezcq zr%ONp^OH}QNx8Am>TZb#flLiu><(FrHiN*#M#+wrt?knj-eJj%8V#wV$6=|?EUK!4 z;pA~}#eWmD#^mJB?`q`9`L?6Nf*JbP+s9tYsVURnt0iNfZlM0r2=++lu2+R+s9n3} zyA{H5u9efVUjU=rqB%j4zgS~|i02~jbdP%iK3V>wr1MFvQbCLi>oe=K3zcAl*&0w! zJ2xIdF53=N9kIel`wg^j9C4iIslrsHwkn&?1qHpUSuhz^|H6fiotavAtD1+HG5?@R zCp6QhL^NGLvIm1Wi%!0fV-(YmPGWpfVz?Qw)XQ$S0*Z7yOaZ>Ahu|boyjBpFJ^KM4 z<iJ38o&X4`ORWm89vy~sHV3OMt5p|yY*vodb=_JbA^wPH+8UEMsOw=iJ?Ui961{hu z8c!`d|2j(YS5UT$?dJz%(c3!j3T{%jO`=r99aRB4L<IPS*n(!~*S9fXlPK7d=z&J) zc)x*JAtvub>L0P0Wja&?#z0+_2`Y8)O^-=Bboy+3^$k=TCM#Et>H`y=I-pF;L)=<Z z&=@XD$k1yJ?_7~B?}g{;rDv@huXuDi-S75hY_jRTA0NM9m^gb7S~7k&B6{pYmT-)B zJKRR+2A{JJN!!<Kwgj;Jd$s!`XHpiNT(dYDT$L0!Kl}4yUl!$-lkZXq-t1iEj!y6_ zM=kB^xVPT&`o8E65F9I^4ltq$*3H<ri0)w6VMs587_Ne=7Zj0hU>C~4-R?IqKz>jz z&|5E10Z`g$;D#_C{41#@9wBXVUj!ERgIB&1mtIvNJ)+@A6-D|HsuVJKxhGW9D#hjL zy_43$?^QBmWoX#R<NkKgLam}N<7>=xMZq!Um|&pYH`qwQTOD4J$I)0<gXJxh{a>fd z^P;$gMfsL-Vg+4VzUpm`C0jnu=7(d71o^0#yj#7|&4+t_QL71Nc(VMRAO~Zf$XD8n z{cS6YJPabUK%-D`mkIf8fzm@X>n)ZlK);Bl-Aqqz@4*fKZG($(TxE=uoGidnK(3cn zDvAHGHlplz&<1hTU|B|_{E%~*CQ<J<A#R|(M{Pk!cNIAlm!6#Fe8MY9Q%4`EsY3d- zMvr8}mPA9JI@=GCx#HMD#@0I;GGyN{HOyo#hv$bz@SBy7d7oXi&tEEtkUqC)@XFSi zwh+#jtT#l0Ppzkzp%U53ycqSvus0fKNUiQ5EV?>{=Qg&rM<N-jCnt`vbSXNYIzkz0 zEYL%Q$_E-@5IDS<ES754r0+WEQu3KJsuo&P%qcb}At8-b$O6mYjBCmnVq~?Bf>9AH z==2cmGEr^`bzI6+U-)$UGdvXhua{OY#jlyN;tJ|;=3c)H)HhaL*jk7}vE9~MPDk}U zdzR2e2i`wmC&-SGXtMCc!#J|f(Vkf_X8)Y`XzJ!+r73X2TkVrAThT<zH2iUllM{C0 zpWo`MRsNY(br097SY!#{;vld+DH9tjC!Fjj99_Yp50#p!4{&6k!W0q{xi7dPEVpNa zfjVk<=7%VsM2bEKCL-ovn|6SWNvLYp4u$R)s|u6!86cD=onSTa#K!PlgzX0m&}k9O zCDC;Ip~&BK5nDk&;=OROmGRvsBFt9k<H8Y7cso}T5FdnzZ3&S{MB(zg*irpuEvB3U zHZbZ;YNO9^H=+5qZl_<9?a~YdeR-ScwV3UR-$H<?m@Cn?8IK4S7d^j1wS==YxzBoA z#0`qPq2ZM7qNAEWwc8B<r0e?u(TT1Kv{O|l4dg7wH`B0xOz(!89=eCy8+cVX4Mene zce4aL9yM>&tWe*9R7{>#vfcc<NFM?v8=)E2WRIj9DJUx;X0spnDg!Y|&z3x}2!@Q( zl+*b}NZyszH%J1^?~)4zo;7=MSc)6)#9DC7HN6C)nJ|<F3D2+!45bLIUDzJ^I&It3 zVLQ~cEwqLewJ<m%dXxEyplD;ET#oEx_{pP%9Z&yufOC|GfkSEy!RzGlnip!ij;fFC zc|}wxD6hQ2bfi>yMoYO?K_Swb)&UXKbNs1Mi?ag~78t0<4Xam*c&6wt1BtDy%3gy9 zp^e3pzVrB5Z9$eB4A0WxA8HkkrNcU8H|OjI!pk9+7A34!McD()0n{nTrRG7beC2n` zXD5S?^GPA^ErC;n8kk4qR2^U%_g7J=(odV<|6<smFwz;LEnw)fOJ0UMM*};1-Q>Ou z64BiOh_@0_Bej36`ye0rX)bsJrn<;!Sy~Bc!s<ViV<<$ABRH589g7csO(@Q48!*j# zqwBS4_2Py16fYzWD5wStFOzp^9DEg1wfwPQ!YLE;O9tIEjaP@vuAOPMlFW=!JQ|gj z%G6qw{nOQproXl8JxD+}3lO}*CIM-TTcVywfc9m%7P~JJ6tMf<II{s6h$?q0H$5jh zk9jdX{8|E@%J1Aphs8%>P}vgmx=-o<%O_QiCbfq+lYsNG0#)sZh+s=eFd02_mNfHn zI0US8D-EKnQ%E90C^cSVOBb0bD5$ZDbQxYvxV7@NfdL!*c@Bu<hFO8*mI=gaGi<nM zX8`#W+|=ibZnPJjjRJ#xk7_(cUt?fI**u$sGl2pz0C(^7U(P*#?_JF~oll_7^xnfk zoX8#$kP;cX8pnw?(ZgSS!aGsrsrS0+t7=cjtPhwnWslZ4(84!*l4)3|Cybm9A^V~I zQta_k2;}0!e2tiVknh#xUwLT3C2RPO2*sQQ&s)y6$?0!aARPf;4L9|3HB02`#)LB8 zz50uBFtQKHPE1VZiXD*9NYt6}M~*mA5{a#q<QT^;{1!sw1di}|uYch3k*V=)a}u}U z?ZPg70agGA2x@Qs8Tvh4pQsRCuFo!(FK*5)56|Q7*%%PqegyvO97=np61fj1kJ;#Y zh+p13!+D$N;vg4MFe&`hd=3ofW9Y`xadCsHPNjr*9emxYXs(5=r1XNKJ83HxA5b2} zz*ZPhp02a2Y(zU<%!Wbhi$moQq_GLh$zrBdtL&3)!hJZTp2+g+&OOZ3kEPdsJZ6IZ zV$*}I`o9O||1v_@3Co-1nfmqV!Dvo`(H^Tk=dES<>bzX427m?!b{x-R?kJTUmK88= zX##Tt?X?LLT4v7N11)y?Huz-u`|EIV4xAF<3NZ)ngkk>p!gwBL?72UI<aOyV8+&+0 zQa?NhVnvDYVr^p)zDQ^rAYsz5(E5iTu!CF#bn^RkK<tIzk^kYrm0~q|DaUwAQs}S$ z14eKVJNsIb73e5tEg7k(R5kgVZGF9X6I=8Yy0OQCp0Iu}u5$qeRe}YDX#Gk48nQ9w z{>9DIHI_nGw8yUE%elm*I;qM4yC1W|vWi~ho4O*Yti54Q%!(RQ#|0->H$i)q3LS^S z<g3AfXbf|hPr>Qeg7^Ux*;V_%pv9us@YoXQx&;5(`vh0s9<h{fczO8?M#qdIDDChT z5mcg1wo&yGq%+4WmiGV{(Dn%@@%VP^8a)KiAZ`%;G43P&|KaN#yEB2dBplmz$4)x7 zZQHhO+qSKaZR?F~+fF*1o{x9dy7L>(TKk-{tLiD@b61+Oy+)ijBibTzNBM#hk?Ro# zlpRK*mUukcuY&1o!bIe<zAUo_;e5`Q*v0+$xxp((Suoi#x3Vucs5B2MYVZ%cogfIX zi;22rq!9uf8UyIh@B?{QhiLP(JNZygSj0c(hXla%-?YZ3;7xjL#q;M-mA8l)2#U>k zk5jg<HV}q(v9~_mY!?4cJ6ez|0Zb^nWe(%EK*Yet7R8*Xx^PDKoVdoa=M$2#(a01( z6#*i6EQK@%vc8H|Gb{p!Tf(@}wn)GJ8bMQ;RuV%q_3B0a;tleFRS}6x3z`8@9PL}d z>pq$t;59IAcoPn`i9sz2x?OYVWY^pX(4%ksUhP_khy}nvK~T1A8wJjH{}TvZ3}lul zVH_3jP7||}Z572uqP1NJM&zpn`=R`+Cgq#m9aC7lKd|dddToF8Qm4t2UIUrO2X<|k z^dmnpMD_jfCJ26iyK}x<t>G2dVAyro<M3eGEq!r5u#9`BNT&UQAWlpM8cQ;15>zUP zORA59P5_Kq<exyXH>zlN*g9HLH|n-sp;v8kezX48zMAft0Tq(R4j!ZYjNqLFmWw0^ za0ER1FPXBIjb#~5cov;fdrc$$=337Q>t~x;r-OOqqL}dA$Zr>>>4lV(&Fu^QiBlXy zzwIB}G8FaW(?=52q$RH>Xtzd~17@DYYY$(i>@QV30v$YJ8%#PX5IENdl?xK#o^7&k zVyxloO5caZn|V+sxG8(fE8TRTqZ~fcu~*RtLU50zK&cV??t7Tn^4S<58sG~+LELr+ z{Q-@jr>{t*HOVpR1e+cz{F-P$>`?P8xZ>4iJU*C0)%k6LXoA&HE`blbniy9)%b0f< z!2sj+xnF<Sy*-iZTqj8nbapuZn10JotM~b^zr8rp#9rs`@%PZ8h}0h!7Sl1evV3Rk zkS29CPk>d;$E5WwE$>{^bE1QYtz`g}*Su5PTU`{Qb67S2B49s=p^v+`k72=bAbwDF zpESj!DEMo_6pa}SCA13i7Mb_P3e?&kGomXi0LMoh^&XzUnwY-RSeEjD?mjP_@p;sT z39x==eWYJ`I=q82o85U+bh@*(hDrFLU0LbziK6hJZ((;ex?inOsDL6T#qv@&oAZt* zX`WnnL@LN-bg(5W*FvTwx2WlmP*fo(E((}L<k0Fo8b>J>E*m+&oZ6=CR>(V1oNhSh z*baISjU}y9YYpa+%wqhSku<h0NRWe`_(7=dxy)DsuP_OGL@ZGSQp-&kJ!1Qveb{$L zMHZ!wd;qWgKA&-U61I^AXCKwSASRMY>JsdKdT=9*iyDC!{b`XuS84D{c`Wxv?j1VH zZX%2`<`BzJ73#B@LLQMQDUpl|LltRI@1&qt<SLnq^Psezt6Ss|okJWcLtnvfkY~bP z6u<;?h1EdiP~u3#q$)SDj`UW;m;+Jv@F};ONBVpsmlD%_)!UPR$A8$W`LKZC`e{Lw zkGOfyDJ<cjX|9IUN}4#lj1=iVR~xYxHqQuyG&ZU%WU1~SJoRl!N>bd7S3uaKYP8{u zf%cNF-q&>sWPyMCdQP<X1vJ+T8em=X37>mRDxJu-tye~*TyND_5!HAVjV>@!=^y&O z+XO<Ig!*m<#8t`L=e`5c8%$N|^WmTXNf=|;(m+3%$ZAHWzmTjgcc?yJt;dvKXjTD> z`9}LLiAT{*pWO;;i{d9&Sn3}V5UfJVGirz<hsS>s-y{<;jg(3kp<u(csDdU3bO|0K zKSlg?ff(q!9yb^^Pqp|G4T2#lo-+j5O6FGtzrqa`Xol@vTzoXFCnRbj^EN`<nw>mt zZ2Bf$qpREvYbi>PvuaQFTLlpYvR=VqF%Q&2V(&!5u@+mgiQj?}h=7xFJ%nLpu+Uh6 zJou{^4Rq!RN1A1g@m<u-xO8#l9e!U+$Ym=};Rz(Ts(LBq?P!G1Mv}x$MCG|*yI0h% z3Br+5^U2r??uEPcN=pJQ{&4!3hvmpv@Dm;vP;wK<TBPWaG=?W>Ds=C?+abisa6y5h zJnZ<S1OsC{iC;nenv?KReE@CDxNBemAD(IOw5ZxJltBX~rR6uT*EYa70#+)y!CSQL z&5sLnrhLvPn1twL8dEkz=BG*vsH)a3U^5Lg&E-LZb_o=o=hDV54>9<YOU5M0Gl@bU zO(*6xBu2GLLWq`mmC|WIC%#SWhYdr@|G}Iz>P{Q2=!WK%;YudK<ItT^Lq!RqrK5$P zDT(__oo*IT`%K4qO<hcl4U^;wo;_F|-@eCms==pl_U>gnu0dhCG-x1tJFQ#_)~*8C z_2d#kI1k@Ubd3MOiB{knI?_W+CwO6~Hb4!ox~0}aWdDmq7Y1%HeDnbJ#n9$)ys2_a z>Q@iWIU1#Ey3N++&#jWD>!iWuQ@Y(gDKoSb!Rt|r3H#=IQ*<`xGcu#T52j?xofk+P z=C8aFzVpgq@P%l}VKWSwRMvt}zhV`MO096&Z<xLVZoGSa$H38-<5~ILo*A?CL-F-C zK`mnkwhBFj--U>L%qwtOc5P;=D5uw%PgshW^Y8J`5hRfv(3W(Bi(x~ggJz96KApma zFad4GdU;eWmmSkK?E#ODT27Qqpk!7`S;QFI)Tkg{SC=2;AI#G#K`Gj4hVAtd7*-rS zuT*7!DsD(rS0K4#Bj|_ax2ZB`Pe}}9`0K}!?Upf4r+p6CU>e3pn=)<g&;+EYuqV0{ z74A?Q&6$nxtN1Uo!NQ$sD;`m4z9}hj_r93YytLieqKgqzB?#lvPTCQah(X@N8&4GG zYY8rZYeELh0)J`k0UYhs=@vxJydbpf_a^NqES~*JbZ!SWfo>ds-LtP}dx^tjneWgR zD@>3Y)X}t#hgZ5C3?cO5;1?^jGz?C0+?i}T%+HguWf=FSuiMD!nt+S#h9oN>a~^z2 z)UWm0J<5T*EG^TL)5L17q@$}6p^gGEFoWQ{K~jyzCE;)Ixho6wii&)w4Llqr`gnuO zqy1!K1;Gf|E;=RFfNxd~YANoDlArVSY6hB_C9BSe`C41`RlvAjA7?FG*&0n(Q9z0( zs4_-7w?slqO;WoH$j7S~d*A}(3`<!gbBju#_1hL+PM5yOXIrtT#99#1-QBZxlWEPj zSJ;{|9rDy`b*DL}<VHE@Q)+X?m%P~Nz=31i?LIue+pdD?=_x^Uz=k4~p|mC>TA}st zRI#!A#$ij*x}GNdWfPFmUMEL#5AO0g{?4e1-mOV#wX$Y8vQkzl9?LsNQFj({3Di-E zI9!X~L|h}MG+x`w6~GhPvaets6=AH_lc-GFnF^c~3zf6|P62%&qgsy-i@}_vYuELJ zL^a>8uvcR6v-;2xqkWgZin?$;qZ&648Rv>*hlAB(F+;eRdYByXEgiq~emLuWQ*k>? z6#0ah;6b|)Qlxjh(-7!5B_*!&iO9@)e0*TqynQ!nU6NP>>DiX5H0iVa3i%vE#c0zt z1$XH^zwhMnN}N;-iH`>*e@U2^oFB|9MFI7)S?O-t*;FmX{8Hd**eJEaqPTV!o}xn- z^BuEHVcRCw6N1ZTfQNbw5@h3rv(`paHL>VT;826SEV2NUlI)YLXs==|Dz*9<PgxNZ zYpib&XBoF?D1Y3O=8;*kA~K_9ZUv`J6n~|C1;BScsPbIPlY)WGclDsBERm%z-Wo?w z${E8!0yv9(n$h-YZCKj1Qs?f_CzWdGI)i#^S9M+!Vft!~n|tvv{BB2@uUhiY8E{zU zW4{(0Q2v^r(S3Ze;e}VV((lVg&V5wPZ5~VtHgFHp$Af@)4V4mETOD(jo*^3A%K{ZC zDe{(T+Iw0ByKZtA{SLx^lS_NPVaS7H%fEG}F;Ik|5t7xL{=hCp*Mg{UjtP1;VZIp% zqvxoWF7X-Q#FjojV^t-{WngrhNaB`ZASB@|=TV-H?NXDBr_CR($S3c2-nPVnk(d{P zMCAvp9G8dsvB(XnfOVgCM-qnpJ(2fiX^0;`rvNkfyGmsaUr=b>0wW#T4>2<0<$7&z zUWjZAx*U#}PEFTR4h=1e`@#7)wL6`T%2o^~x&w0fN^*fMWG6!shP^(zAhZCKuOobh zyX3&i^rcuk@bPft^2gakx4yQ<+G=0kC9PaX-%TnNxm?9(^W^cl&zA);I$bw&=Z*>- zDF!`eLSWC)YA-&SZoVU6pemw)V~Zp*?9J;_Tc=8&NbBqu#aZK@Q4A*kIZE`P;9kWy zUfKFdpsdxWtB^kyjIH$}gD!Y;pmzMr(L8t(^RwMo*RuZm@2%Nw-nq1kWi*ck1{Rkc zt18O0cUU^hxG;eALYibB-<|{R%B9pUBNHzswwpLu^mS#KdH6lX!Y5Mv?!7_T`d<_c z5CmA-lVzA#(weq26>|WY3*6A1?6~Z6CZAT8M&0d=a2G_bP{mk5e$-C=QUM8KW+|T6 z@xnh@=O<HS(+gI0wX2vZEUKld#jMSkG;l}82TggNT5J}SrJ%;*04w_gJ9ph_WW@90 zb(_=nv@S+S?V;TmjJusOMVUuQeq|5B_2g<~s~p1YBy+w(Dk_t1^Y{;$^9D1iQ{+ht zZ^z$i#C(A^4uSBEq4%CR>?z-IQ)Q}|Ux5==wNpwLN(hjowgp<tCA$tiY)aYIwRFET zQB2Q{%5W_T?8Bk9sDBJb+cq@1kanV%N-x|U$or}bcMX>4>JY-PX#nQ{*Pk%Z8nWdz zfWk%yVc7yL#5N=x*Tw*rn*l1WrGEdoFAc5(W53d&VC$>Z9%4LZ@d}-;6BKfaouP3I zbp<AMAEksA58&rFZa1YyR-w^5P-^uL-3lYe&wlI6fk^QmPK*lACG*;@60#U51&-Q+ z=Y*6UWd;@FNu#HykQ$5HIeyd6A1q?~lrr(JF;9ZgR|4JKLPLUAy7IBDHoR_?2Gj;_ z6Pb;8-wn*bUSZEE*L<lttI>1ggK91_I|<q_dLC?1-j_tFO?{n+Aw%<;rCU1P7u$`Q zQ2tdT)|gAWeR-Vu+P;Mu%HY<8&*z?})Jx!JQpR9!s@#D+WAvtS&)2@4bgNru^6;>g zUn9CuJYK~<oIO5rVdlYAw<2tQN0hr9^m>)fnh-|NIuaJtML-tq@hogkOmnxCaP-r` z-9ZGp@JW#s`&B<;r>-cRhG^x3NX(mA(QyjCQc2(|t_hb2pAXQxAxPlDB4n5#^G|#} zq76;?bI-!V;Ii8r3TG#iWO<C<QIDhCQWIqQJuk(6#>RY#(SoM~Sg=lw;n2xEG?7N* z2Q50Qta>ag3vA=s#*%B}y?G_NAJHtb2U;#6e_97TpkP1b<B5yx=(V3Ym<E%Cr_l|I zqEs#gRva@99b$zC(Xir4Jt|W~n+JHd&$11{!Y+51`-j#JlF>30C)vF4)o2osJR_In z?*}4Ohxhm<{RwjOlhH}TuA+|4g13$N*TN=T!FEDdC`wVgv+CUc2<5^I_X+ztgLgDI z55g1|pWl|!Z~PKms5B{Plw(y88S^FTE*93$DYWlZP*=zMd8=E_)&JG_n-R=4zTjK3 zc;~Pey>M4<Wd4$5CS46eRaQ%z)Hq616%$uk*G*k9g*UMUgx5rAeVXfl%1>akA`ngK zOHDPNDL!&4;G|!g=$TGH2ez@lL}b{(H9}yp;d$IvHX_d;n404G%}bFgENx0aksSa; zY4&`fNf}lz|62JRTnTF*E*LkeiqGT3t|Ti~I1!ibnqrD*w%eLX+7kPvrrgtB8HQdm z66T#g-cPti=!dx#Cw3;N?n7D!NQ#Q3s9Xn@Go;Nn0bQ$!RF!;Ps!wzXAwI3L$WiZo z_Fzd{WAD8mY4Ai?(4aNoA+&RxBSiO<4V-%o385ST2UOlEVju=F^U7E$QNPmc2e|Ml z_**>jik&|a3rX9@QB$^Scl-g(!PbGF1{BEW2Tn{Z-g)W3>J|O7G%M+dvEygd5J8rw zUG6-2V1<M2g>QA-{7SwHrZ+ID4i@Ekc%{ddoI<luglcAIi18Z!ZQ`#|@F5J#XZ;~U zv_)n0XA~sn$rtevbnuU8zwwY+BT`ahA##X=0o?CFXH<m#c?4M={M~cR`3I1eRbN)t zfA~v(sNOJY%763vcvUep0Vibh8C|7N9$qN*2uigbk@eq4(TrJ>V{qc65s4e3>b*+C z%zj5c7a8mOWbNRWzgK0!85aYajJc2F__uaLcbI?G3Z?zLe^SA&R8Us-e&AOA%V+uA zVJN}&pN@uVJ~=4%T6F2zX<2^XRQWw&$NKNIr{$w%nqa}5NL<GV$`JPh1s0le)M?O( zzZ>Nq!@EoWFzIXfU1W4Fb14D{Tq{Sxo_<Ll@5tY{9)LajssNz6)Fzo;p;GW7oUS{w zrD8M^Z9Aa-l5mz&rGrE9MU@}0x@b&TVd+}cT*Uz-ue2>qJ_7M7kt)LPLW`y0p37RJ zlyt~rS-Bm2nUo=|(%z}AzA!0FKiWmfy861j(!_~)CHa*yRO!gx=Bj))eDtKY30aT* zHC$~=l>JJks!v_Fdk?CvK1pX5<h4-JGb;sPXE>>R_Ztj~Y8Ho?+&({`V3u>PJaq1c zD<@ARmwhOR_8ab)!(l>Lxwo5JcB}f@!!Al(weTaUr}mzh$sLv!mDOBIgnIFbu@|9a zjJDBF0jnw1WZ?*z`(%^><P)Uqk9)0kKI4SgQuab}1W4lc5<1^mm48q8CP&O>-*2X$ zPg9okqEL{zUqyV`O}yU35Z8K9zvwV%^Jy`RpYMA!MOQKbl<SR#RpJskA<jLdbD%Z= zaDpvfi7x3CyV2d;Do%N&{Jv;MF-B<^sztsuJr%ycGzq&8*hTz?UDvvncc%h5^Pps- zACfXn#o9=r*x;1afPTGKqlQHZFO&C)Oo&QINh!o(hLT6+$|3I;kBozGqP-&sC6`au zgYVJF%PonC0fC@1zqTwp3dd3u$~6jNX^wWuZ;_-u<8-NuM;$NSB!+$FB>ULc&J-OV zZ95bd2fV`BQ4Ojv?e_jq=p=f}ASK}}%K2p=mqlrxzW_qhA`{eev8VjrkIgFXQb&GD ziDm88!triocraO=jW&wvKS&q!CO>q&>-(lxxoM6Wc-Je#I}%0QJW;SDhV9s#<}L?> z9gw-dLTMX&DNVroQ!68y{*2cBu(%^nqlKd!**e{h?pf;?(dGv|{R&N0)(0Ib-E#)) zh!W-q<-dY%I`J8JaAr>r?Pe84g(IH+yA<y@y`pNFo75a|MtO90DQiezlx0Y`zTapB zA?`fpt&UWPPV4WLPqnW9LY9Qau}JqrS7e7t6vn#m(0}cS5amT}-IXenN}RxuqYUsH zIw2_ul1(N0XeFeYxc6_ft7(;Kmp?Ca0Jlf>4pVnlZ|pk6e*Y>A>P)h85loA2ZNVw5 zDhs~Xe(zF>-NfZRvQZ$S$GFc`l<)~u?C{7<J~=klt4BjP1|1Q%X;M&YJaR46j|U~L zE=yMXa0xz4Y#uyded@9XQK}%#eFF0L60HxG*U;D*<GR)*IL9yM7<GBOQD1_XYMj*{ z=OF8P{0kU{Zg7KQD@%c3>ImNlgY{E{aeT-5$XY(r;_R~!KYn2L&+iHIl;>o8d-}UA z{Aa542<tqNbTOmX2#uhs7th)O$t2JkNpl9m$n!&YWfIn&p8~-#%=MEmHGo#i|9&c; zqG}ZXSr9<^x$v{%*j^I*;k#j4@MO5<m@V^A4JvnOsQ;Qs>@@N6#_XipM9^Gb=oF;s zO?chvogM%v`XsD@%;T`&I#?lGXRP$yF1Fg~p*|t{Z5PvbJCAavvAD+u8-t9dytiJg zae1ep<tmsT@}fM<B6XwTQ=O8XTDhl0O5;#j65`|-WvWqjVK<rT?1>i>ZbbGcmCg%u z%TzbHy$uozlBs>K^uaOGb;4ReSYKJ6Z3KgaO;RXhgT^mHR)P`{8iH#(HmZ&Le927G z12Gy?RWp0es1o#H_mX$id7Vo=Hgi3)6pi~Seh=!IA&H5ikww`s?{1I|jVFKYBfNdo zYaKjQ_bzNbBnJg-J^X&txQrAPe|%b)Y=0#9;xIKzm?B#fbuTrmt8*8&vrB_DYEmCt zK^I3g1yPIk6VvE+MMF1Ib3ru8gB!JTdIwkUHWAH+;I9yb#}hS2Jb0GU{DTG+awESL zuNalTQQgm$)IC1j=w*FpDCkfNJ(uv`sW6(fHm)~?Y~a#4aB<oTW0Y$FCA*K#x99P= z+wtM1Ja8QU1t!BPNh#=&#r(9+_Yl6X(v+k1#oN+KZgfd$6CRgMY2-P-e^->t-lKfg zAZ+$1dW&?me&D*q$r8WD*I>t;lB7$s)O$_|%+Uhn0-Ujbq7f>zuEHT|N4H+2yEHYr zvzrWYs7?RZF=ysK$=n+_JKO2HfLUAk`uOtKPKD*bA?K&ROl(E)N%Y5s#@2k7FS=T{ z(IVJN+HejEwm<bE74b8_Ci)-D6+mYBFzK8K#+Jq8ggwE;C;UD14rdMt=38EJ#-R4i zs?guW_!|N<G2SNTj`$%Z|HBC3OHbKUsPjBy?V}J4Qr#k(Rr4vba*nx7YjbCKKqVhp zR;m&_gfB7^5Gh6heJHQ0JFy3^KG!-OVfqqZGiL{^2Hs=NDDokl+STYDG@Q(kL#wK6 zac%okTTlNrmJB37&4tASG)F}+LIk37TGpn<)l~ZFz&7K#B?=@sGGU8Q)Y!OVh)EE- zg`_rfn6-wqU?ol0&tsWo;H%E&vjx4=gbZc=NQeRyR;`iJ&|#R-#y=+AR9#7xfBz&B zE(;W|V%2Xaz06D20zMwq2c1zUoSM+v2mIyB80e`Gq(*Pg7UQM%JtJWvsjJa*23a;8 zaxXZz>x6*7muC#CNu0>1`{J9!Bd8>69@}wO<u}S)dbF(PJesU0-ao6=pj$j@!Y$*; z&V%gM;4pK3NdK{4LUDhGB!_`#23D;Og%ey63pCN>5SU0zjJ&=>S>U@Gk<Jefi0(rc ze80@n^I4tKTv$ZzpTaf$mttAgmx=`;qMw7|=sJG0?+Qh!31AntsQAjd#F>OIq;sg~ z9IV-Rf5|dhUdr|YhUTl<GLQ%-$M)9tEk&91uHrJ7?m{2}QY%u02wuH^Wcw7AoROqI z|NJ{6K~+tJu!Fs=rZbYjzzQ^nJ&p^isDy1oYzuQX7us_?avJectjD_Ic0Idxh-?of zWhgMM?G+Rb9DJQHr%Nlm2{uMSN>_&BSq=>+7<|8f4wj=4{rw(&?#s(>^}GGvFGfBJ zl$M|ZtF}rL16JeTNWLgwo9HHE{Sf@sJwC!L7vw*9Uu5sfRq$5gRXjB28f)n>L2qs1 zqWn&rRG)-t{~?Qj!XW!^C<va#>y%W3h*sOsAv$OW*L{<FeDB#lz7GABi%~#hZfuiv zo|x0Gh!I^4LA)6w>7?g$Be^A_p?pBM=e;Er!8EUG{}$ylN>rooin_~G9&u^bC=#!I zOKYn-o$(eg;MaK`L*jaZb%`f)8w{ku_o80m`TT+qLFkXTbE_{DJs5!aW@|6RfZ+`v zt8rjmu842;16uLo0NXTrFaQl-X$@8P05LIH8r3%*vTCpzQc<&2PQfJ@X)PADqtBpN zXMnYt`c)+F0h~F532z$Pwi-Jznp7JDg2exFn5ct|MmqPod3*Q$vg+^ob#l5|TzJ8= z#lngJv-}H33~;!YB$qv%fenEid{m)T^YeM{<ABy9yI8CY%<FcK`CWhLboA2kC!mm6 zl6C)IDe7Sp&%fOGT0vzfP74B}`dl%1oHh&O@*%D^KBk+WFc;Y(30!Y}xC4GEjKIU9 z2iy=EmFO}Gkol7xmQ7X^6%0oIaQ3Ykx4<)2LAiyXxAq%<bM|qX+SDE@o&yHAx)Lc_ z0A4_Qa#Kl!GD{#ICwyPI6SE&|9@wLMN8OOKx(au|S*M&ziffKu2~;Q7HT^VOo`A%T zE8-7%_ocFgCtGqOJqw4VD3LI@+|~VOL!Rr8L%u0z^F%Un2+5ll2fZzO=KN8H1cQ0@ zbM{$LN7zj<Q_!tY4L9dvZntfQ>o%LId4zkSZKx-vE>I_RaS;N)vGRew{m;W89DM!D zj;SL&o0&0;i!;k87+ee!i=-HAnAt5#S%~?EtU@jAn-7TpR*;)1wSsNHPVO<k@0;NZ zq&-1)LHsxZUxSmMn~!!wb56;Le~Nqg$xNttWc&~aT$BAQ5)kSyaP>QK6^nn$pA;(* zIjMf9tX!|^>F>XK%D?-1k#|>^J##LHs7bUZs9fzG6g_Z9JC>=;{f#+1E+6Yu^LXn6 zC?@Rc0w><f<hadDdA3VmfmZ=k*NJ=0bO@Mc1KYMJ+&gaR)c$jrf=g|y#j{&K0LvF_ z9RI&9Fm+xA_K4e8ST!jG182O8PxDLhI*vfR*9DvTbeBu`hQg5CJm|KXn^Ka#-Nj=v z%>X@qv*+NRA1hU}UB$ImgY?rh=%1&Xy4HNLl|nnM&6%v{2gF_fz5w$PIhfeFHj=O@ zwSjpH3tE52PA|5sxC{qQgEZ?w86&faugr(Xo~*yx0E%TLj=U;NW2k=SS+-}kH)Dc5 z4}E5wppTjKKMo3X+a0s*JMSo1ent;hd|$g9qZL3L8*D3N;4b#^9p#-TX4P`_%G^ho zOu^po!2VTCxogA^&D0=|*z&KKH7i8O-WSQqKZjzH*@6P3w-JG>X<N?J+H2bjy(CCm zEjU0&^LXEwf%R+^z*xnz`exLa6h+I6hD<j5O?-|vAzQ@D(h{?|z8$(y1DDie?;mQy zJ+}nHTWmAPh8Nzyf#TfDS4d07^cf4FtgKST72^a%pouN)B|jDG5Lx&AYG;)$faro& zF>1)S#<mEk9XasSWWM5Ke_P=SIhFiCftA}Zt~-8hw)c^d5Xi`DqUw_&^F^wvN@;Vj z&8oz~&9K6Zp}*i`X%s-0iIq|R7UihQSWX<UTxM+WU`z=#6oav_D(K8mW>KMY#1mzs z6NAN_%UK<C#(RdMEq^5=$A7w=ZC95QgsO$*gKc84$D4)K+;RBnh*-0~4!)Ni-bh`! zz~mg2{bzU(maX0*S0g&x)dyF1{YySh{My9Zw@U3ZVzkp>VIsS)i24z|Dns=!Sz)CP zfE5%^16039KEn`w`bV;Ds37l6L$9*NTe)t?ke!zMsHxv6*5p0dGxwsB*04?vXokj4 z93)-6Us!;UsxxmEobJL>R+(L^Y)1#zid^$%zU@wKg{eEPu@(<7u%s&#fypk<V&vWN z^6_zf_2?iHY1d}uf7<_NHs9n&;~n*1PZ2o6|JPGw>f~ha<oqvnl&U`AbjbFPXF`K? zY~U%juth;3eqW-LYEot-f1Cj_Q5KQ`rlCRmc>CBXXmwA_#kUUT<$deQ&XYe&gK892 z25tSY^Oqsp_wi<41r3cibxHKlMuAG9G)iv-zfxZecDa+96>UZ8>zsIBVeIhShC}tw zP3kIn0*vCO)W^l}qx_`CvgI$?Oq}cVi(16QjZF&FROlwOB)hDEUZs{t>hjEBOZiFk z_|ek2qoZ*(8q&+Upek3Z0~^837HXGLsnu4fKC2iqEIVaswy?`*8@E1YW4egSpjyS~ z!z|7Y&uiW4mCF_;+fyHvUnf4937#r5#Pq!PuMDuh+8q6jyPO$X+eIEJaLGN9+^qZp z%<2*$%J>L&9VLIg`11c@s~YEt@C;L$My{dOo=-Ce5o>pfwQlj8D$p6Y3PTBGlXLHv z5pMK4zl0~JXJ(D@NqpKmEx@8ifdy<kl&DD}#x3a3-})VGul_cGp|a}`3c%HtA|H$} zk3t%Wu|l&Q1oY2{VB>y2I-$GcdBr47V@h;66J>y0If8m9lZvtD|4s!iX?0H<mXrlk zX=w~uP_UC2VT_%B$|_av3L(TO+0zoVI?b9~`{N;r4~81z$}p-$S0H3dJD3<zO_WA@ zW8RKcyl+)&N^4|iL#lt7RJQjwwdnG|)JH>HuDP`6Zu|H<U8&B>7Vw?_=S@>b-!U<C zvy1`#@2LIn@Gly77PCo9C_4`M!XXo+{o^`Mmda(RgatL9Bm4GQg}6Bh=kkKK<T)Qk z<%hloUSnX14TjN5Lv#}%U%skbewcHiA0<WF)q|tnTN$cHnuiGFz_(&~Y(sA)bWx5V zJqM|a%iJR(1gZ3_sL+(tT@_jV(9uY@GutJytXpM5fiV5i$S4$XtR{jvD56yEQqynY zsDolz#@VBV^-ji8s22mmls!^Ho?#yjB;}a>GX2oFEQosE3v$JAhkJ-bxsV2lM2g1R zITEy25w|-My+(ZE%s&lUgNRpPQD=<`UW+5gu)4Hl#>riZ5h*UO28Jz*@y!>yMzMwY zo<IQ^h=?oK{1WUBXqyB^#NNrtp4e{k>KUV+`}h*=hcs=$Mu9PTM-LYF<f;03wnHc+ z?FO8N1lbY=6&Cd&0;e>05y^>q#=upTOQ6r*;a@%)@l2q@2-Ezj4{c)N674-X&%5Ju z>(v!lIx^$DV-;Ielfv>8x0*uRdunw3GJ4ck2OT{&hlWlF7^^ZAw?AjzZZXkFB9Ip& z)8y3w(@%^r>`oH+bx%C`%^Nn2sr)hDRFro46`#KrLmhY{lT4$HI<>d&?pLgrco&8% zY{CW-P=mJIOv3rs{VFV-9KX$+69AHNZF1h7EDJslI0xua?TP$!2#5`(F<rFvxiSpW z@j!J3(8Suxh&`GU-mp>L0vG%;CqD9YO)QM9rv1G5tHCpm9RsfDkcf5sEq*s7@G|-c z1DN74P6Y$|@fUXrxcLm`@~6cK2$y>KdIU^dI^K`>?0i;lD-=jS0l<=cA62Y;YUX5q zk6?_cEWN2SpgA&V8RWmS+qg3d_#>e0J-Kc9Z2A1AaJZu#!Zx|L;?H`X@O2)@dQcAB zmAiL)DCXd9KtXkaz6P!1+aUUm^+#Ps`qui#M(${9eLdXwrbcjq!#smevjMR)y0iB5 zj$qOCL;ftwjM_T<(#KuLh30)S#J;GS7mTQxnj-xv)6T-fy?~kjo8iQ7@WUbhM~5Q# z2fil$uY@R54;NEAXG?p#e<QU=OWS@^48w1=E@OdGhK$MCQ@iDg_>#>QLsXkZvMaz4 zio}UjR@6}i!BR7O+JE;pXaA0T(oX9NB0_Zfc<WXL39Pc!RP|y??4nntW0^c(#*ca` zS1uL(SS-^1vr~e}@>)hkt+a>*1TsnJcWS$z+t*X2#qF((mTCJRXG2xZYw+C7bT*hE z1EzmUB$bq5jX&2o@#^0VIdaT{Z87a|@x4L?CP3Wa(c6$lx;QzNh8mYNW<OTM@Rb{r zy!jwbp>)IIr7W}ncZX_!p0;SoO?48RpaQ_&m(j{VRLI91;X)3b*&q=vl#@uw1j1;c zSmUBap`&soJG0;R9^&YfY~LWpRJw0ibIuqBTtJ|8c8NE)$$)#YngnWxiacM0h7Jq^ zg2p%q!kYffI|WQxEENYxtEy2YR6*1*s@kMDiB9B{{-7X1QnO)di5IJ7(ZVTEx{k@( zj5H((fjJgvhpCr8DmSSEefYDXoW+qrH7zQ(n?w*q?GFn|!njF;n)-$v&qU#jvTjAm zR2=D0(9sgAXJMHDJVTkp0EA{Du(SAFN?q}U$$`o0+LjOT9irRg>|`2}rBNf?-UQCH z)OceEuo{^*_1QfJ^!_QnHz^WpAgQ=n5^|JI<q|eCY_JXKRz{DODyi_e1k8aNJ@beH z0*VhXk)|QA#akbvnRfB43RPTLP+UlJ(d3uvyVzw2JdUA+y_5DNk0L$+UY*bpiW?&) z#^v8mJye@lk+e;S$L6^^4$uZkwbEg<VX7CV^+{GRM_01uC>%<8CuKfhb(&l%$cp}T zC*j$+rhGyi33k@{rj*3x^goqRU`VG2qls>t0@DSC#1r_I0VHZ@)XAl0n}$IX7#X?? z28J^0{ZNRsN?c1#eQ<5pDQ~E^&c46Z%GM(124&dP)vis61W%iRn~1|SZnzeYk@>z_ z$tDLS<4f``GX=)8BHQ|U|Eh%~=FQ*$c_Ybi)L!Y4d6lBx&F#bT01p9QkTauDH%*FG z4c9n-*{8Av%#2YtLL#E{m!x|Z%hvraS8fTA=cRN%buODbf{I{}!k7p%?3(KqJOgQv z12d$Xs2z6`?(hsOvnq9NS(_+fkP%vIn#pWW)?D`cnMEX5UsMLU{K#Q}+QSr*R2T=4 z^0j3Vk2e8Fr>oZo$h2rVjyg`P(VvGc90kqjV7bEPbYtoFBPj|i0)#DJ5!>ykqbTbO zlqk@JG^eF2{OVW;RA)*cF>lmBkDlZCA#yfyAOcS=tZRs*IYE0)3=kDDV|$smUQzxy z^<P3g<;ZC#-oqDZZ<9EZ;taSR%+kYZ;{7!Ga&R<DE6SW|D_)G=ZcaloETuSf2SgH0 zHY@gzVR4fk!RghOiUHLOpsC8eVf>)F0d)i5LE!P5afff3pE<az7mLW00UraYYRsUR zRtIpcFdYnlU4gOSl81qfd!9!V@A^hpQoI1KY?IMaLH;nE6~|W;bh${4ESAQToTlRL z_N$Gs3ea>Z?N`l<96LCYOzPx{StZ*}Skf28UdlF(yey6h&gE<$Tvk`Pt|U-i>;_d` z^O;NBS^~xGseu;BAy$w#>&AQ>T+<gd9)jvWhr)BN?Ey4Qmr?y{J;#o9sPu_Pk*yb( z>Mr;bzPi^)U^Ref6V@<eIcZoBNugs!8uMi;vrZ?nk)K~7QWg>=yhGH}S{(+KB0<!x zDxi-Dvh!)!)7X(-$9uN5GYVYd_Z`2{zU8P|E^_~s_|mg)#tD^hCT$#7TI#kg6qYpA zk8LlQAg*FOBUde}_#zT?Q%@n3AbepDf6Y<Rw|f#sDe$viID_+aY-=4?8Dx*6$IK+v zAsxqELP)V|;j!T`ma~$JBk_@<_XVNE7kkiy<XV&dl$SeTp#AEhyb`R#G~*|b*FqhD zE(++vp-#P@P>s<`#L{9Hnz(sylgKB2;ZSZ-_k1tdvc@gaSZu@bZ$nlfe{>BkdTe&H z{mp7FgkK4TfID?}danE)FkiGBIb4UM6%?nOp{e9nM0DASN~h(E^jb3BW38h+n~(ZW z8C+P%fa8?|of4nOV%KyBqN!}E+B>P9t=)DY5z#nWa25FT*wNK5w{my@-sUNexm>vd zDX%jqjrjyowKtPNKtEh}G|uE&+8r-g>sPjevXv$(dTuW!)F?t58srO8{zuROxM!{E z5ZD%DO!=aF?u65Xl496MP_08F<d1+#s}(Z@JJ@wz^k`FDd0VQbjHz1JG7UDQ_x6E# z{j%(Lv9`jpfp3i+7T!78#e9#Q1`h9B$W8LL-5HJz+l&t}o?8}CaEm%zTF)~=T0YM@ zfdt?dsme5xQssDa3(sjEeTJg^QB8A(vw7Kd5xdh3F>Hx*1SJ*cYl_BNRj{J3kV+U! zXW<@Dwv^D~4Y^1ZRv$c=4F`$B-XDPIBEQ86!?Cc_g5Hw*%~<3UI#*adfi9B|9>{wc z*X|zKC2QNW@4dOUIJbNAZ0OiW2YS!m_Vq8KK}Eo#NP_9bE4XEkEEe~Aan!yGp2J(K z>aA8iA6)F}!K0TKuXBqza$g|9=Uu4oG-~X6wq9+kik`ouS)A@QBF0n0Csx}m$$3M1 zrkLAhgVpBgD1yrOF%k=SMP&I)ZI{!>x(|DAwv5dK-@Stg!JJpF6z61IrMoIQ|L<Kq zq~b%C_v$;Pj^5BtwbTo>?S7hllZofz-OlR_yFFq0ls(V+nRn5M1LV`;ZfL&Bf!AFp zX)g|VzVCS3f;e#gX>nhTk0kMe0<L_qOP`LgGGR_KqVOp|`$HH5_|5MV!{-CX@1y3E zqon+1=;!!zUkw;nT{J{Qq%msP6Ff2sq+sXLp*2JN_0f}rEt)nT{N*yaA%Wj;P5qXM z#LQx$*N!GPqJD;Zex74P$leF&X#d`P#O!r=!#=g#`b--$)A>+rcI|dIs~i;9V~;4` z)KP4C)bwty_^sx3UEb}jsR5&-EoxwX!~nESOM6q#kNQ+-IoCmXLt*S7%|Y>au-`j0 zXswH=3K@Q0$8SErl$KCa$W%{nr$_RcQv1T{{tOjiSPY{jZRZlCulEJV{c*hfdfNv* z7pBoO(-GtJjHnoU&FB0lgSV&+W>6xV+S@jb1rQnmP12K9U<B7lce-V-#h*e}TqOu~ zU)q#cCxRw=a3Y<q2Zdg@Wkj_eoZ$M{64!Xsm5j)U$<Ac`XIXiRiaX)$1&t?j^G(#; zJUW)FXr{GIhQ7<-qN_SH*!heOV@ULL!_?8{>yL8c7}^)tHWlN2ZG{T|jYBy;GX?TG zuP@>UWAGq`{59?D;~I2|=JU*4AK8t4ID1za_H~68j3?HZf&m%h<~ZE6Ql8lvGV+mH ztZ!}sq3>n4QZgfmeco;qhg-b*?>9~llqvZDhB~~VAi%6*FUMx#!vw0M3K{so&C(qs zjumIzUkYX(<KkOk=V`$$XC{hVzAM=KA%5aj-+F*TO#^n1xv+oo#WD;wRd^l2qtcEt z`>__qVrDc415f<<)XQm5(t6E|<uz%wZQ<sNbzKxN%NT|z*LK{14g(>0XU-W<Qk<Aj zw_{y{Q}AB(5zv;Q^OK3UnoUbxIb0Vt%`@L+OHRS~q5)(*(CK(nSTKa=o_l4MAg250 zSIL>4?1&r@L-7thgHbi~K_NG9u={fh)vJmdtrJYkl=sxlg1G2;4!hwg!e;c}>&nOl zT0<x~?thVdo(={vfg=ndFFw}8a0vo#Zo8MKS+(la-twpkF&4A9wLIWO!(LBEZ?EHm zN_!`iK2JV>Pp{z~*b4dXoZY;G&;+X`Br_}#p2>)$cjG?y{MXl;#aND_+>b8UvO}S6 zr0i|GlW=%Q(K_*S-Ue^o^Qca1M{^P{|Kse`zI<SCQ}ZZV0t6vTKu=It?@Jwpg-{`- z@>}2mHb;V>qs#c1;ym|JR$6#VEmM*fo$v5iH9HCLg78(VCIM~rF=GGMJDyI}0_EAi zJ(aH}4um6vU4Fp%?AXBt_-PDT>JD(<J@nZzbr5tg4)`ADIcq>3`WPTa){jdLs7KeN z2Ej1qvj_T{mVB+_@TAqx+FhCXRizv4aT6IuuH^k2*w!_BMSgk3wO{AqmS-!vS48dX z?`DYLkc_UM8^(v_>RV)325-OCB8xw@{w_bv(_4AX$0_7qoa?1OSTAfpSWf|^7sQan zIA8b^Bg;>bo-TTRn8n;Nf7DQ)&|hYa&XuQjxhhB(rh@nTDUI1h4gEudpQ;$IN@*vx z#!+9B&;8yK@roy(#-c%m_k7DgCG_mo)Tl7WNl$(AmcDOu-v9i$M;gF2<1Eu#27V#~ zz#*3pa1pUG9So^%!Zzm*u&=#01?SKCFMTGBv&4_IQhB)~Ar%h8?fJ-W-Q>gW+@H|| zicYdO#`9x&iq_?v6%Q}sWYf_=f^?v)kO+76N;THX@%S{0ouN~bqI7bj$tI&pZ6nps z6(!(Ie}Dhy)@ma*mv9Ol2<TE22#D;z{<6#r?TkJ3%}rhG9sZY?)5Bw(yvdfd`%Git zsY`0B$ZCAMVwS3^q<2exzdR!OuiECq%v==>T5>7@OgMprhVSR~(vAlzVQI=EnJe`g z8(E-u{??9#H-ENCr&Tu_)2Tzc>Zy7CQElnk=EXR9iPc_XA)<Ct!+TGrRWg-Kc613( zEvklw1CETY8rLz~TxVf8_g_3`s``s|qOp5gG!@NeEV<RXU1u80d-6z-g$~rC25C7D zm?MMiUxi}2^O}4=Ipofq3A2}k9Vho)5rhg3(C>eh9480UO7rO0)uMoEHu<OnFd!^x z+_ju0urNU9-kmi?GH*@=4WNY6Gg|_|qXo!+v&Dg+A=uQFm~8f-+sNpHS$=cfhcAEn zp>b4rJh{0KMe9U+XxcujqDw5rW+GdRCF#7d5BJ?)*7-XyIQsh>U?v}L)--mtNzYqP z+_&!$gJRJJYy~XG3#&YT2VPGId6!fgnjj!Iut!>hLibS$&_)P|$drTz1CDCCmA@8L zxta#p{|p>t+`m%QZGwZ8dAjZ#(Ipk4HJa-8{rwFT&;_i|$*>pEd_)@os-uW0IqB$B z51kehddma#^Y{Jw)geHe)cTncM1UnP-7}E|46%VsL;)$u7laVm(L_hDl+ZwRG97RX z7Yb3)QYrYfQUhI^^tPIQ|DzMGU;9*td9QzPS*~bM4kC~-kxmKXIWR>2wu<^UJb>2_ zp&sh|Gu6Vti26nKo2EW_nx<D?OCXy}G;h2EITifygDe|V)w9db1&~cQ=gk+qj+@1? z;q+a1H#BDP1@-ea<kNvFo7r60^ffpXn&4TU2`wV_$G|pOrBT501r1URrWX<?jiW>} z>dER+cLo<aL1-=BBUI-VOa~?boNQfDe)F{%fD`JaNzR_*h7dRpdqhvjE)6>e`+|Ov zpR|K+iAy=AyF#L{fh0E23@&H`H3N*1BS2ti+<IB1f}PaOTWQNTA5#JDo`Dh~B(JrW zR4O^rDnT;=upMBA4`fs_3eb!*;2U?!5Y;AvLGaEPY5zsUn!twe5T*s4ly*yt;wYmO z9u(M&FMWnkW)Ue8+)u-{YJGwcp@35x3r%S@au1gT?qwQa)FKTt0k3cVBt7bG(=<`t zy=@~j5xp(+%XpDop!ykC@!rDpRne-}j3Fz~BiwS8g)o1F3WN*YU<m2574(C4z@;Ar zGQewU@~9-@DJYQkR%Eq)v*avAnbCRRs(`^}DGZj3<OSEsqu67n7Na1SwH;#koXg4J zsK2X9{4c~y*sWyKt&{+E42i<TI@qf~pKv?)Wq)9Zmx3wJ$JWpg?OR8%adAc<dd-VK z#!~`|<c8B7aH_$;BsjQGiV8&n+C-p0onp5R9@Bs+dNT}kbB2JPW;C^M`jYVd1Y;=L zUNBw=uO3Dy8Hi(lpfd4Ab9%LxG&kt6(Rmbj2FmN@R3Q3UARgs2!IY4aG$wU*zh+`A z=mGl~d9$<9P;Jhfm?6S=FgTd@E3sOH_+rF-Sio9%yc?DVzfce6Z&-t->jz?Gpuur& zxN`#m`jQEOxuzQ=su32I_Z(j+Hz6<@44Y)~w{a;3aC*l>tT07sg$oNZoLi2t^>5B4 zLi~Qwfwkb+(c>^@LMp6<Cy16QFL;)26WYLx4Ps6M5nWhlBH>$-xio}IIgdBoI3y5T z2s1(qUX*roJt~R_nHP^L4rt=HVrvMdKoErYc|!|GL%r?9WGiSM3)gg|m<g^sZ}4Gq z;2d}(eg~324tq<IBpueDMl61?DuXJ#h&nHj8!;qN0zjC>IV!aWROu*2SOQTXdw3)} zB=!D;Zfe^JBI>K(1&Sw?j9PCwE`!NxWMF$PY!xJ^#wOit1|4ENp3rQ&c&H4=vH>7% z0N6XXn(F)dp6YKrnY`4qm8R*UiB}grkb@}o49eYnTxNWDpE%+!P*@Vx@7^$?O5d*7 z7A3_%ZIA<tHmG^^Y&q)|p^%8R4;poS$Hv0~F$}}ZAaWMNTV#cgW&;pS0;69#4(b<x z<&ozW)*xQ9JtubhdgypBh*im^3)!4TrFM!VQ!n|RP0e`8nJwpR;a3ERMOR_a_qi25 z-z-wd>uf0>A$tP96C7#>fAu5FE|3?R(3>ykI}r$H{4sloQD}Z%T+R?CK6;$t_d-Tt zm$b!611k4lRpzG@Gz|`|IVdrpB}k_kM{~ah8-H<R@Xpng9gfEpVw2sM)+E5`2Pb42 zpFeLI?+~PHl4+xGY=TR}eba(2yS+O0@Iz-L#<D8C;-74*gfR!Am<p@dT1eH)VSwSw zdCH;2ASUIY2Ll=ImnelR!xK5(1^_da&?T@L3enwiek=?^_bg2)w#j<!oyX3=Fe4eu zf?7|;?M2{I7qnS2bk5SqWGfMDWVUa#NwbK&1QCm{IzroZr5GMbbBDDY<ug|H>MNdi z=NHtxL7#epkMhl~p-N_T7&%vuyyd<?6a^g5p3IZRP|%75(N4{ujd@tH@Zcux{d|~2 z?O=b{QiLokpFaA8oYc^8^&WJGh9IE}$zQeT9hRl+CYv3TiY-(&D1|%6?S<w%EsD>_ zgV5D}A6k}#Yu<8RU2iDHY?}XuwuDxL%|azdb>)*I3mc8k`%MT1fgAC*b%&}7M(Ln9 z5qHm1AADkW3rb<M3OTpVKWLOPhDgZ|)A$7$*R#%kV1}n6LKD+KeJ|Z;RQK)Vc>b{O zO_3HR%-(TE3Ls>48?u_jR6)zPDMdI5OJPa;s16~XxSsg)X2W@xYRnJ`9xr1c2CL)7 zq!N*}Idq=@3WwPz50`oyUo6f@5L@llPpI}?a)vlWq?ZX5@MraEWbK6zglke^U-b4n zT$xS`a|h}7DDKxiFfN@}04i=ADCs8;fjAm<nuRPudQ^-uquz<>pXeJtu<HehASY@a z#Xw@)F-Y>R&)o|5NgVC2%QRxOtD)kPV!9$LYL3YEjhF4p6UVx7#>xV3yoC=U(22;W z8FkbKTVh&nqWOEt;qS@3pFFz}c=sBAst=e%YAtA^4}z&BOzW4=8h=59Q=ZAa62l55 zx;^O77mx8d&fYWvE`D^FK%l3XkQ=5bKW=1N_^pyzBtx%IritQCY~uLx{*ZuxZE-O1 zYbwINvMgRdeEBA`vEjd@kR(M1i`8!rI1{Kf!KqcHGOH+kc>Cetlp;Pds)NB$%`5!* zo@7Fg^QIs|heqHLF=lV2z}`0iNbKO%6$;}(D;*y(XHII&hJ@R6)c&RC2|P*GHh0ST z4C+a1A%ot$hfwJ|hAeE<qh@Po^uI+uGRmuHKVAzNEvt*LcaN2Wc6@4Qz92hPFK*W= zTa}^GnOrJBwjER0Wwzjc5KK0Fy>m2)Y75{wALr%y0*Xu$DJV#X;)tmY(S?zIJx%Os zts9n1_TBDAjl~gyjU9XjO^`%1NxZb!{Z965_$2vlft9%Xxe33+g(o_t3kYasj0KfW z{hPl<fIr+r05EAZ@}8+tQXqH?T-3|_zYUWY&<6!u`hNQ=YHxu@tqFt)=qvDOFo@55 z#&R&lp&zEufHt8M`gq$_MGbiYi;{}R6`la0h;_y)0|i8sp!-b(z#w=~Ev&*5R(z3n z91CZnVvQw1QP{vHs9@3I?ejkDVZhFpwu2WPkRjOQV*c$H<rlMWz=Oeq(e#h(39+Ey zrJVo7|GH^k3Zmsd^b$r*LF)$R5;{<FJx=qRPemitam?apfV;O|TTz%Z?sH<POfb(m zCd6bQ&<3Y>pDH`ri}G6r*X9b=1`O(mneR{QUBFbLAnW4wkjxfUL$-a}0**OF!JQ^{ zS~E!CYtN_Q9~vnLG-iO*!N^^P_8><@-CT8#c(nI?`LTdJgC5yGHmd>4t^)4izBqph zc7TOgXA2zEKgWAXOn!D!O@AHJAYl<1bxcJhQvWSBGE#<th^ul7OP~xfCnD~{3W!|V zE{j%=kDkPnN;Fg#UUAO>dioaeZIxWDHd7a^nsr1r{aZ<0QMj+5oa56=VZCsh7WHm| zlJ~8rFFyinQ*(HHURVbsF_)kl-KJO+JVlZ{V=-R|1UCe%pJHh;t%J}Bi=JARe$mhZ zXqv<H9oe)oF7LJO-06)4?VtawtKc?JIK@)`g%|s}@E8CN$QP}J*@|m@(P*8vRB1?u z6~-93C_UkbOl}%5Lh9$h1YSBaNmCZbxX`A0b=OnPu&Y5L7b|}62N5M0fqmstM=QuV z=d1+v0fiNo6sk!ALofG`oEuj%OmyaLREN5J*g$+L{~x~2DM*y4$<}S#wr%%m+qP}< zv~AnAZJf4k+qQ2{+?a=dB4(Z|Dxw~8SM1DOYkdc9*<o7FJ@$1Pyep@J2StKck-syH z8gF3RafQHJ3*|+YxdjYL(9Lo~PN`9>H%4UXUb28U9TsGbKrWhl&>2+zqJ8@Q)xJmR zvN{j0hc@D?w5qKfzVq8QrGucGyxqWDi<oC>I&d$*7lSp!FKQ$^b<%zeSe_PHuWUz) zf{MoCK5f*gs4G}aIQ=f$r75Z0DRYE7`Y1;p8(f)ew9aA{8lDS^%YNj1ZLT-Ycx-s2 zEnF{Z!#?9IY^<9gJ+w=rfTFb-r=vq*0LSm|7~3=%aYU@G*sebaHmII(1NmMboOP_{ zrV^NpwOZB@chlBCIa5RS?sGP^P%5s*88w25w((%XB^wpCAT6wAST$Ow)!05#PkSYm zWorwb+P7PLd1FbJ;MV;VDxfo0+D=`}VbJH>DNf2lRA{;Gf0xB#>|V*cbC}kypZ7ku zWlr3-5UmtrpWV)M@4zrR`=Kh~VBvZEIbVhY^)8BkCAX`s18c{^QImD~imo5Lp*XUw z7vVW|1y&bum+fbAJWjxu&Q|MwjuE@DYdcWlNSqj;3<Wx4<W_xu2^&zM#?f-JRuNgT z$0Czl_(A{p`@!mfB9X00I0G*6E>1<5h7rrv2zn>8^P@&}sq(vs^GK2iq<8&VfmuWp z>apEoG%y(43a#zzwD`)~YN@UMJvzOD38o%Do*vC&7b-Li9eh}ZAh+PJ9Q5Ax`K05V z+7_<X`VM~!C$pms-xPAHn?TIM-q*c-=tJP5dmDtYhiodLl0Cx=cs-?=^(8iE-@^pJ zKA_8+gN#x!0o0mP<4hxY09@QfU2#j(cH=cDWe56Eh^(OzbpsZJW0!00E3|#l$u9|& z{wXh87e#Teq^K~CWY_UI*k$LH9|UjjFQygVX_bpl?IfZcOD@X+aYtGx4A^m0L!B*F zcsdfNoyRQyBnLKT1KqiQhG>}t-u0m~ADM`Z42JaF<GCSVoJdG?*3#`=(4ZhJEfUyD z#&go=0~J@+X(WEV_$7B7mcn6-&Po$gA?lzim0<}IA;>UNM!C%ar#)t1r801xF*0^j zqbSJ_1@mB+=#*1*AVr~C12~>OrQ`NzxGHWv-oL~NsaAk1T)LK27YQmwi9X}l{c8)G zPWbW>aF@C9B|+6}0vinvP6D*ymoSDst7cg#d9Ra{HHk#G56j1)U9b!)m`r?RU<wZe z)fZ2_HYHJH0|9w+ut1?&iUMQ!Ufk&yM>|&0q(SWy*MVr;Btpr0QeS1J6U>IVYI_QM zC4;>EZiJpvjFVu|IQ7D)6>jC@sIzbU*=<PdxcQpNT~i6~4J%3cRPaUGTwkx^^Iay- z_Y3mAmX7#KY<6P%@FkkbJZ`rH4HPKxCOZNS{30l(*GSE}${pt*Z&(Vpb9QX=M7KcI z_RUUTGqWS1SFQWn6ZJ2NHN6h@8?PesC`UT?dVAPSHSlv^1;}9Q2x?=W_cz-57zma~ zr6|%194mWt!8zTY%XpF5ONxi61@h&@95iQ8j?_qw1hui*LdzV92qz4-z(Ljhk1u!Y z0LJ%gOeV#HSFote%XcRTlZd@ZKj=0viq7y>3@2zvgvnS8)PWD<7oZ9#io+4zvi0{K zF~$fyKJg7IIjv@5`Mq6f*VfMq37@S2ApEFoNpqefyp4N%MqA%qA6Lj8Cf(H?GjFi* zxQ(KM(CJRj7zNsDDX-@o7)5w&X>gXPGND3Cx_uTKC=Z4tHuj#_h2@4hjE#r2qqXN? z@yzOH?h=k3l+faq8k377Wi}hb5M!c^5Ll)E#r0xyW>MNvJhKt!n$>ZDS|h8@6H%>r znbnlvO{^XJjgR}=G41mwzb3kE3=%Hpp|yEeJli{DeCU1s(H#Id`N^|FZX0{>>r4P8 zwfRoyL+F|$@caYD_O!q`ns0y2qF;-Toz-Z+x}VkUlVnsuN5NFRt8F*Q>VV=bHIBp( zPyjkdP1>$L%x=nV_od!RS_Nw<;EYDoJ1bryyd^B|L~=+;W|eb1a;fNLt(8m5oiWbJ z$%0RiSC{3-NDq@vp)2?Yn$`dvD><+8Qna$2h9rsVDhT1<=ia+U3i%X$h8rpsTYMh? z?k6LfNt_x=1<+JH45D2a-Q}yXICE2%b&qyG%_Wwi?>dVWYjH+<qAd<f%M028)j=&h zqpM7__}(ZZzIRaC2F_|94O!44*Z0TmL5ED63I&!hp;&V^Vyi`F81~^~o;RtHw_10p zz@>d*Af@sEegOa9XJ*sZFx%<bcZmW}MxmvEh^Ra$Bevo?ZwIW<>GTlpo&7AIJf<4N zma2V-F!$UMnBsw@pYca{6;W>idy(ZUjo}c(ITPu88BI3sjtk5T>_GL3?R#UR;G_(B zHyvOnYAyJgWWH)trv+6*+R?_UV!em2%p2sa0EK1#5%}WciG5;oGdi*!h6My8^)ZAf z&%o=3NMX(e0+T-->q*fT&G>H}D57YAMX?edstE)vB=*QeCMS8Tt8bD;V*MoceAm%! zgdM{f2R5VAIJ&(MSw~DV8I$eA%5kT-<OEYPpqx?F-Iz{;3Ds>&^c;n=77_Rf1_$Fx zyI)Gng~l~pxj-e?5A{edMV#~*Jsq$Wh|X3Q6$&?ahV_y0%HzlW81nwU1d_4U%tG9x zT=p&A%yH;|pzjScbt^#)KA%G0i&&r0w%!mQ>ws;=YUd^lUtm=$ZGPT3(yXjex`Ad| zUq1qVwVMl-Uw1g@lk84A2NqGcj<=s1xbI(XC$3BTVmoPArEM9yJLKo(&{nID1QFI1 zh<^H~6AvKSah3zl8GtD-z2USgYAZf_Kgn-=3}CIVuE0<8%^OaBMEtFnXfZx|@?aHI zO(GU!cYN!kzA8VwfZZII%keHy6}2J`SGOjdE^mhMdSztF1a>iILOHf<i+F8oNfNp? zY!AuU_<g27S>09%ZGC*u)@ZvjP#9Mk#<>TG_b7(YgN(?Ox>_`5JAO5PrUsR&_yW=S zU&N@W8ltw>2i4D<rDgTq23iXa)xG5oVL#CHDEO`1cLA#ivwI8n!F+PZKqjwo{4cm` zR#=WE-kz8mXoLcA;&Jwlh5~p)d+B#?@ab`E6%O&Io4I`w4DcMILIx1*s9mszauisy zaHhWD|8pD+3Ic%K`3o3AA^5*UH>MWWCjU(s>ejHb!){0Y`XvmFLx?VnOKPK>Ete;P zUC=C3BmiU@W9wsMEW(&L@M2j?#GtZ{`rfps9`cZ^$+m2;2AJa=9v!vUI&mJ{wJlDw z>#Etd%>Ke9C+1FZzgK*y(PVVoZ7j*rhM^i&RXug|AeEp)cO)S*4owU1+<CChme$qj zqp)eKG{VyxmetAk4}QfQZfW-cx<dx3$?cMX_MBL_ca~}uvJ+br-0ZTD3$HE*!8IbP zX;04yXt{@LrwKPCl~mJ%rD`Rrr3Nr1W=iq2#k7qJx71WRdLt*codqMW>6wz~4HYd{ z7c+%(Wy;VFYc;`@>y_)B;f+JeNz-yeT^ck=-OlfP=a+}|uZ0{Qk0-r{rGhx&>z_n& zL#@7lotcncfkk%&6K*E}uv3~v$hr_QNlfGhH(!g@S*IgCFcc<G`%w2ix=~@sCj2oi z1w|~x8+h!gsuD<fjm0%?l>r8$m!kAFL4b>0$LsUFBlWAD&WdMaK>rk-tuhem(qz7` zLpCC4*iB$UXV`T+8UocBD|tBFzjB2ZsfmhD>Q?iPX^knyV@YYGu69<n`bcDqH3w}; z*r1s#sVGTgep2lZ_loUDvjdP`&e2M^)H9g?JIKfByWq_ShM%ae)25F^!umxZLFGk` z!5lMI{^Lq2rW!DW<_AY7f`@wHulBvUdQPH$w)Jcr6YLjZ;-0y84SQFo$h&)o4WunX zw&ci-cIu-`bTG)M2om!^qic}M-D}PL6Ke*Mocw6O%IdUzzkTnu2(=6ybZAZc<yi7Z zuqjht?#+I$JG-v1T|-HU<u<7Q;;)<IiS4s!LwYA|N`<2Cm0bdGP3sshXSdGH2AO(- z%|JlIl$}u~FRdpxC4#74cj7i3o0KGqolRj+pKh3xb)1*I=p6Ui(AkXzuO|0#{zum% z9q>H9b}ES>F}Q1_OO4n|p`dH70+ABP=nW(Y{doC{8V6Hlja7ws>6d)T)g||HRhc{i z`I|n;?6#cT)u{Yt2bX7_VSM{*z~fP5vx@8*wo7<dq-X2Htkq)WW0OXz{a2&dUd;R` zrpcT=Hnk^~*7{YkjU^TivJzFwy?nW_!>?pOii%b-X}#hfw&W`XunSI&Q2GE`Gu2tJ ziZ--hIlm36vVJavP%Rt7y|VcZn*LgfJ`MZtTaUSxZlgs!28ERoWUIsUze#EoAPhM( z_1c^hffc};f^$Lpcn-8=B+Mz(Uh6e+oE0{Yo}DF*8c=n$$*wUR)7lH`@$l9ueVBes zDE1gmCRk!9(ZZ<F&H6NkIudfzsS9O(5QU>i4f&vroz9g-4<obE^bpFYsFPB1CJOo= z0VWWTb;S1&mC+Ry=FPk4S6B<?G=hw?nOFeR8)ICU9V~H@21B#VotQlbC)&4#don6O zsIg4=%W1*Z@$vMgK=CGQveq&}KFtX$l1-Ng#$ZFSHIAC(a|5?A!LxsP;Dns7cu0AX z_aT$^l{t>aI0-zZ4M#}KqA(B0i&|`xi_%ty(#PcB1qw_`rg@;F&yhiQ4A+tiao-U{ z4dfe5>8iiZ;>ek$SqjuE_A?fDVPDu*L#XPB980mwsX1#AfY1$Cx>2Bcf`4cM@{ye& zHMVaTg_JpC>v}84u;@+vow-qA#VJ0NU?Y5y10zgZdBGhzl4)QdGRtuan&3oD=CNDx zj*P)qj=T_s!S?n<luy8qu(gQCy&H$M;?z#)Dc4I8o$X(%yfHRW&kM%PjfcX4k8Pa< zFQtLdOZBG$;^>n6Tr+vtn1%>GAxN^Rz#=sz`5Dzl_4l4w+T2HDFrmlYB<?<5ZW8Sk z)sXY}W6={(Q4ee~tJ$cE$)5W}42SwHfVFanY2vyhOdmnoc3vu%BCz8XwT0O`YZz@4 zwQtJIDlx~P|BTRuhTElRqwei@h$=`U>T;ig7D{gjJAxR_2(2tn?s;tV{Q3F{re$1S zMHPZbw-5?@qkcA^C&SvV^hQe%6BKS>=W{mQ^T<4;7T(tTK@gEPcOF&Y{FTv(ELtWi zLOJZ8N=dtRh;}GjT^A}TO(b^sn=5*GJ{?~jJ+z|J>q(!To47r_XVKBopAuCemdhL7 zuQT?|mX93vMwLfFk4g9u5&zxolUCG)z(m0t6NmMzuXpEvZ3?(ot&}BJ-pgJFlIs({ ztNM#1?w<9~I2RvPO73*lc6>h#l&z4g)Je2pzj<eFE1w|RZ)wf44l%IfdimxjQ=AxF zYPN4Ynk+ABFzVsNipd-gPe_C(ZvoN2T@~BSX$p=h2bmS)y%wkaZy8Ty3hc6px9T)k z=TkW6mC%}tVZpb8R?B{6m~Xs7qB_6E&bV00L1<>Rz{@9LJgeJM6@rn8K&=w3WZ>_O zMpH9rKiTv&9JU2Mn-2Y?F-+0z%`4?MIFCUf%tDg&s#O=*@s}f}cjO3+hvzB)xx+3Z zYQ6FnS!Xl-i6K(LC)S#o4XcMj8B0J+h@z>x+C{9iQc3<kdrBGck!;1F1_cU>z*-cX z;${ZYR#xm{g4D>RWZCdQc@OC50U3CP>+{)T7KXJX5MV65^?7^o4gV%?eWcFMR-M6m zs!x);V5CzlHAsd2Ia`|e2QU%YbY4eCGZl*@ZDRhYa|lRj?=&DIP*EEi>;fDUCXQG> z9Cs)M=lgMH@1L0Brk~c7Y1}#leB|$Euyc+>+T*sNXuZ;q;0k4L7+F@6Xd<*X7Lu0~ zJCgH-$_C`d68(Z_rW;YQ^B7+F8^+G$1=wa#yuj~}0?Sne=MCAj+z5iw*qT5-q?yQn zt4uj+ITP3<%_lVkJufec-vc@q>Gf)Ih@~VbheV2?^5IO`GoS)a!7yRo^!aeZGV=D+ z!DytO1C_133op$(3T*2XG$U+j96w4GYxukJUL!6aLOJ*-5`LEwFcI~G>W78;9iMS< zH_ugkP}Vm<i2QQ`Z(xr|Kcn5Tocd^|iZQVY4}G+h;t-R?70bT6w!S8LbA6<x-Kt$y z19sfKKH+b@6{N9U>`(4>807)iH6Z|3H&zo$eDppg$D59KkU5)Ld`zCUREuEV!b|s$ zs=?x`JtsouarRbO+;mIPbOEB9>`p#*r@$k1zW=a(1Ow0=;lS#4qImv3Tk}t)Uk+)< zz3Tq8-W9CuEBdu|qAAlwJ0tE>P1m=uy(nMR7#pI;mlid=9UUcvY35q{;EqLgCFn<W z-K%1)l{?0<ZvR7scN7}saIg4M(dIavEOq|E3(UEElpiRZ6!<soR(BBn^m_Iq)b3}$ z>l?KEbzU!I1@y`ddE7iB?cZr*a6Q)cQ01)1URkc*PJJt!Z%UADD^Hh+x}@-YxEA?x zLhpl9GAK*Qb>0(*<#R>&3D6rTR<A=uas_V46)5_}rPI+=mn(i?M{X4x>VmHdrZdo8 zI_H+}WuL!i_=^=@%Uy5C|H1V+mxS<n&$h$t4c%j&DaW{(k=65SO9u>8KB6RLHjc&H z^>XR6tg@glbT~U0c-3!kuHm)`SGbww^s0+5*Dr2Bv81L#Q$zXVvb*p_6F%C<q#mZ! z%ThttcFAEEAB8(1FhvjmmLPJ{24QHVL)Z2R8|#dAMy*nM^2=p>Ax`e#NfFOAE5zak z|Gpalk9|+X`02#kxi>MG^Fe?8A4&)Z2Lc>XcmRMz*8hvG`CnIG>;KOUn!>h<-C(=# z^aVW-A>=H5GW`n*w>5nBlu-m*V-vtL3pAD^AoZA`qv0qq7K3=$yEA!9INz|6*<xV{ z5-toI`fxlMhY1%NyeP9Vsu+9HfI`{@3pS(Nof14-r2+Ab5#sA-kdmr>5!I}TVy#Qv zQc-K-GW1$yiya^g;#rAZk8@k0->8}bDoCI>b>0q$0Ut83r%#YtsmWTkd@TX_!cv>k zHHQA(Tzy|sBgKm`snTt1M3TA|>!DK}Y*|9RO>=3MuUy>(?0)+CmolX?fqfs*XS(B# zT!mP9ND8Z!qQu1e2%+ylpMl`Gn}!Yy#;0$DeK6}J+TC{5dg44HytT4HmBLS*111=_ zwvI;Jv4vFItC^}5qVrgCx!SZ3VIGvLY|XSEyF~zp0XdG65pTANJlWPg85*ola(Z3V zTnNi3Sot|T2Q*CH2D83ZW7Nw4a(lGFn7JRzhnC9K6DlZGtI&w^1p-Mo1thnw!Zyv; zUlWpmADe=oy+Y&>EeqglQT`9A-oFHo%A_(ZbyKo9qlC3|<k7VRHOHlb5~#>Q+G~en z)-pvFL$OyI6$lX!|2wK}ad|<iA&fL@H1ndabx#~qUMBs4$<edLuoeU-w(N09wgrm{ z5zd*_kV?yYC7p1Xp6T_<GpJ*B7N(BdFuAm@3QJHf1+^<A3=vAsfib_05FO}xL0-DC zSW})}u*G0Fd4kZsKIxQ(Gjma<VOcEefA&YOg&+6t4F`gersrfDvYS@?&vdr*&avRt z@S?O(b>$M(BYD#99e}Z!!Sc8@{61(qih7{x{ID~(#8Ub^0+8n={HWuc9t$cOGwx$} zf8J**Z`3WLQmwK7c#^>9cDcWuA0^`JO2cNAEh{deo`Gyd%}6pDJ|qOz2IiKdZBh~B zF{27^4oMVjg`yAg+~)D)MLTEh&fJFMV2vU_+vue1CYa|-0S;?`ID-8}Q85@IBGkW> zTnSQu76sTczH135e{r@p)#3m~T!p$7P9zTehV;q_1WTGE#EWQU0$(FO&4y#`%I7JS zz2P8;a2`{mOoI$LsR!c&hCeOCh=$XwP37f)D9B)=ZR1H?nwG53``CA|`q7-A>fSKG z@=)O!@*7W4JSm{@AZ2(hDCoa??@%z*s2ythZ9{{Gxs*w&?3!#DCl#zU?N^b5%Bnc7 zg}o$<#qQ1}ix99E_~|Z_vdu1ahh=BP7(*TL7~V8>8^%bm`qESHP=x+s&NywtGcwf= zUq=u88L4ZeqAh_l)Et*ofA}}z*ChkX2-6fgAi82vs%IPJZJ4LK(|PGNeB+D^Lv?&p zj_WKy=gbfZWt>XZFh0?OATf+|x6GGuYLDgBL=0C#udECZ&t~|tcH#|4Mc2#`CtbvA z{t25nqu&`s0`RHb_>q$T@cZj|0JrABgI_aCDa1=rz!BzR?1pR1ab_m6TF(=Xa-N~5 z<Ax8&qD#R%1gf5Qq!k2o32aT8<Kqj6;=hCc29dy|jxaGkbbRX+d4G#0>Q?mH&cjfv zsE!G{o<1~MMGrC?HR(&f0pEVu6%s~k+eDlTSBy*x#4g8gS#nXaqatT4>Lj*ad}~3H zfxaj`7CK%M8WTmE$GB9dRyh&8zy?AIX|MQ>)~mDY?Q+8tJ~zWyqsZp(gBE3kW|LX2 zA;9;~0z%R;0Z8i7WT~=DWnQHw*dxggqReIU@DLsAHVGn&P^{u4!C^6qDra#>-9^#0 zePt5{h5;lU0!4^7*J7ivAv<V@QSEzRCcSg58Xf}XnG%GQ<_{i#_}O<YtEcOS3<;~X z$4&hC#atF3|0%H@Ou@!7fyp9<eVQYcZJonw{JXr}9h}4lLE-Vf1M}G04+L=qae5-t z2Lk0dC8dE74bZe}g?Qvo{;_mo><^vLiEJ2&LPZE0tQJOcl3dS*K(2}s$E@rKnT~*( zRr)4)sE!c(a;Z`$@lkClH;iODAOt-Ua*0o45I&~eb!yaF%(U4-3ql0G1W(Tog=*WD zq0?tEuqV1Oh2ETTS%Py79(;=-MX<|=yB-S7Z&g|A0sDkrIF4IMb?;~g>MuC38}8`v zF~!)f-WE%a-r0wrFrf?ZiTfSUE1pG7y1WWR(P|q=R}~h@PP|s?AIL1a)-M-x*A2jK z?nr*cRWgh5xv=)p-78)TzIB+U>(RWmdmKPxgejSghwxr1e{Ivv3ijhH`=LhpQn%o# zf<MQk5%3Fk5B~RI@{ck5#k9`tW^cwGCIghRC<*+sJ|On&ATPDui#z<U@}6CJEdefP z)!9Y|19rx<(TWu>j<1-Q3{u(sU-Bc_R>eh|>_+y3TBSt+U*3wc-sX{Q-Iv#o?(GP^ z#VPO+TPnHO5bK}<aa<M6y`oI*X_jGbR!<mj7raT5Y=EPFuLeDkYopbqy%7wuvJK`g ztB&5pz3y?TP;i<Cdc-i6dU-f?C4L3`UEqkfQ?DwyuR0BWK(J=SaSH(*H3~gyt@x|T zS7MYN*pJohku3i@_~v0Zo9U#tZs9Gfp)&FFawN5Vn<N;R&;j%&gs0|8>M6yvq7BmA z<c;elOXH3oi4`81GTBFWaddr$kPwhC{aUKGXJz&c#oas2cqfW&CFwBH80E5^+%@|( z7jc7LG0gAf@nIHRmfuxmws8uO9PMda+#k~CC>Dc>4s$7o{)A46P^d|gH!g=k6&IHZ zHKJ7c%46snepo>P9b3n!{4bV4L97e=O%PdLx&;ouA^J4Bc3u6YC>Woi`;I}bTv3@F zV7UgIII-K?v&hC=6O~2mFI0g!9^nV#nY9J<gX!qpNex5iv^HeS6r#?&zuPHO6hg-` zOV_S=14R7vR;V~3@v`CPds}yw+$`YPU>H!v8N;_Ua3V3lX3RDA_EE;}JcOK1a5V|_ z8e45Wk!XPHxPPKR=Y`$0Ez3)hm#;aL*|k|uCl{6MA3A&@tY@G5s=Qu6f+4sdkKGRn z-Nf;+q2TMNXM`IO3l_j~xJ(I`7-Nr58~W0hYnxXMCOs0>6qXGL2Ar}A1+=`3@v`M{ zyBC2A50JPdpKU1qu7cnkx-8ji%rVjyn$$lH2Br|gPWgz4{ox(rEmG(LB6hCM4-oXT z7$T&B`C8w%3Gr+P!bOQ+m~CfYDOCiQ&SU_@*UqyyJMN-@+3T-YV!vv)0O}DYPPq=l zG7&W3F^Zkbl0LB|e)2CIL4KZ~?*)KwPY!J-*00gF*2brKw9(wR;>%Ud&WJWLOnKa? zLgUZ89h11yCp|K>M3;5@z5KJ*<1|EG`vlGfIBE%s4Yu`G8woWXY9TmkI5oK4a{IPO zyQ$!maic%z3Cv)8z2v}WAfM?IN}J4KpLsC~FIXLdKU(&y^oTob=g{`jBR8RsQxWdv zNqn3LkEDL=8CDkrUp>zPhuvDg&TR7LE-0K{xz6Yxuo#r$LlYpRC$6Ge%h%mO8;#G2 za@2Ohxin-#N7>(G14?9*cWbXw6U{x#{1qWQnIGg_y}#F=&fRax9lvsA`82Ra=NhOl zJX?79GF$L|36ssXJ0W)-z2+g!*~#4ITm254X5uiYy*%U7;R&<>L7D}`4K_OLt7K7< zp~O75WW0ClKiwH|7lGz4pq4N{j3fyVqOl?MwVHz}sXaZ*S9XSmCkcB&W9#ZFA!U-6 z&{)p=C5?Cn;H*mG@YYy6FZPDf@l0}<(uj|b>azZGD}!-1g#=**FCu`6Ik0y-8mB!D zGC3<WDH3g)jAy!6I|9n-1Ixf=<ZbW{%{!cPmjRM!OkMQ*8@jYe@1-;GuZY#DD>ay# z>xuDv+<nh!cCNre^?m;m<`R-3hzH`&^7*;6U<P5&>wYBt59@Q#>+fkirU<&uQS;#4 zYIjHWd~tJxExM1mUcs>38?v07k5U`tmzBcYoNaJRHBUjppeGa<D%7I(<}qVFkxvU> ztMpdzF&tNjfVAowVzEOVl7=9*f=KJy#E*Hm%ypIq<75^-fxP#ZGv?0j74TOZ1p-3N z+3Gj*OGh)zenZz-5&&VGUY2S2u%v(jiZ}q|Vpe>6-)DkztaB>CTQgtrWekRI>F`Yi z%vhhRT+Oi2J^yYlTWtU&!Q~{lc<U!^*)DF)<i+1j*kU&DwW@EPZBoNp>aNglAX5S$ z79W;49*fMADT&qBhgQx<JqW`oJ<**lFfCXD+)5%y#!lf%-@RiOzC*IRZU1Q9y^}A$ zo#*EBV!sQwObZ{usfk7J!(p=WR^SmZC~{qez@|R3P#OSf#dJ;ZIeV6(K}0K{k(2VU zsR4eEKtOV=KwVFu?!pK3DLJd#s4_Pk%K;i#fryLXNqT6v&mTqIFzVG3Y5*jYNuwzB z-^WgH-bI(0LredP_&ciT^pvt8xumuM!kzj?v22h;^%x$8e2h%>Ru0senFeGl#=s0H z63bu6q<;W+{Z=@s4c$_f^ZELv#L^dCA;2WB9^B^tNyXUeXJtc0Fwj{3RcwJ^jE2ez z)^cn}bPl+(5paLrLW2;Uy^fcF$(b<HJQM@CXw3SL-%}7T6c#Suspnsa#@1;}Wel6! z%S(|^3}n6flNCiHlhl{U5wsGMp)m?|C9!)$zhYGucRKqye~$-p6TaN4C`sO+YG^P` z{P8tc=iH<=w|+8&<N|UKD-2S-PHyqqC{Gtq6bq#~PD-f)IVu*f?^o~4qY2PiZXqWV z!{pk!MnwY4*ZX%iyPYWIKIRr~cRz(Oqe*|(Xl$p!#ju#t#zFG1LFkKj^XQq5%uUx$ zSf7|*{mivO7$L)(*XCy4bjXwa>Q!M*u*JAw{((bV8nC5IKf>vIOeCYIbX{#CBBnz- z8?aP+H=Si^5Nvd|xt}|&N4CXW-UKQa<iI$0dy5J(#TrufGtv)l^{#j;-84!951LWW zg$SsRQ5P_usddKOhy=z$q6HJvZ%4oU$YuZ8-eKZf-(+TV+CW?l8i%}$FCH*#!&E$? z;2sJIc>4#%I|MwC0*$}PHNjapVX6REzbQ5o=2$CN8|zx>A`c$%qW8sOOJ|C&w<KVS zpgk`#^cxw?j>Au!&aFTcVJt?tkz=0Z*H+YhnO_=7@E0<oQ1SlyE7NYf+xNxC3;joS zldzbTaRx`1MlX0T+?rm#svZ1v5&SP!5NH>V#Q@@$m|vVPbC*-1FTMqD!t;ZV#nopX zxuW<N-+%6(IAu7xVSoSt>OlYiaQ;_2g0-F5uL~hqsXt<a;lC0zLLQNX7;I#V7mFz~ zX@l!JgHm`clg%$7j48z%Qa`=L8V<~L#?KEu4m=)M9-7o?R>8U~XRrh|z%+Ssf)si{ z@#(Ng!?^MSORtct_-dtwpD}`%lFF(B3vFhI$^z%9wD~b0zm2(R`&R+LgQg2<)&epZ zEDdzRc(F_}tX`?I@@JV<xi<vI3PUz(33zTrHv(rF2QWG}zF!}ZE2!nt4WBRez8Qgy zMswIdLSZ5aH?Ch|KVYO8J9j>}FPT_|qK3XzwtJ$GNbov1a~MjbZOp<U>fJ{$|LA7s zJFyJ4wg=T~g5;Z}2hG8dEblVj+B=FrEIXFhi|Ke7@Q-jk#a^e$j^U6-=txH`QQj~( z7qK}SM|(PhUsw!H_*fTMp6*$J;)gQiq!(CU0<)egE34d|br-btvWx6csrRZSWy!~# z7ou$sOtUFP^k6#|Iy)9B|8W+uz-Py5%;OQ~`Atmpa|C_F3X*#!RSKMa1c7<$5))_h z#thdRH@+Ih5*un~qO$LKEW7wc##OQeWqwzlCBmjG_8e-j6Q6+gfg^OQAYF^Hj%S?g zxj~@KzD^qug(ZZ4Eo~0ZXV1|_IwthDBhotd1T^hgA}PaU^yX$4C)lUk+GkpJ36gm{ ziU^Cb!@?*DI3vrP@ktj35bY2$PT`K$ER5kD)ODT>eS-dH6(tgO)+79823)!T0FeE! zRb=DjYQ$+|XJh|6(sBH)rzKu1Cv5hFoj2;b#W#+ovUnP^?r<E^V)1)TbYATe8Z$Z7 z`VbuXEOU;5>`;=Lm7lK;?7m&bJQ6#vzb;jh())AfELdNHz~`==4vMNS$wej{^mgQY z()Vvf5*~ABmnRyiq#9$gA?P0;4eosfQKSzd<0m*3l_WFje@vF58qKv;MOez!7t&<r z%V@Y4y7Iut$BITLyfo`0i>eBfU@N&~9b3AapS)MkvV;;n@O}foCB_io0r*1n+$30y z(1omD%rO3>?DWE~?c8U`0OVT$6;t-ckV&a7M~dhwvsmT~`wh|3OZGJi3+G!UF#esk z95*Q4xN_yPx-^PcMx9x8AKShwPzNgT$PgT&$=JNbnAkZn@_YDQx`OUG|Cu;Z7~8%_ zA=f>knbsH_#sNUReDQ(_1O^Z-BU@wT-feY!7ht8nfA<t+p?YQARi*iu#VGv+4OT_w zbGr>1_^R@6fE@p%kUQzRa@8@+h8`8at1cgi#LKytOQlS$1XS9&DZ~RR0vKo>I-&h5 zdMGe%U^@lazT}^~yv>n=tMBil^Gy{+Mew#=ln`Z*j7hA2qVA06`*1upWnDZ4yU=;C zP9i%{=;807Hi=cp(5oE2RY@U|ta!{&D-0g2A)MDq0IcW6Wqm>D4J&u8&i32Hco69) zN2CL%6HFI%G#PF)e)vT5aS_qeht?jo&{+b7U+YW~BNdCu?DLUq$Y{j!0d|rF<hUwn z2ohY&boZ{;7S4o?{kMBmBtAUKI?+W}_5<P<qSFq9#F;lH#)wH`cEa2HN9*=dt%s+} ztkbc_Kq=@cRD(AZze5$RtRs>Fbg@d4s=!m5T}O;&;jHWH>DEq&0yQYfMV;fFfyavv zrzzrvugllh-BWhyYW<+`tNUPXZ2Nnoa6w4!<e+=+)}F)D*VR?l>CYB7Uk3+{HxHNh z6RtksBwj_ZS!ZVzc($JH%OIBE7EcF#qObik@`lg%=aDOUIur6gIM}w5!KLqau6w~j zU0b`T#0Zf{kqn3qc=hx~?rA2vRidc}Yy_4DzWV_ZdMI5w$NG;YHnRhwak56h!1x>Y zS^(P$W^Dnqv7XwV!uoC6O3aA$C~xTowH<|{A^XRP?OTLn4d+k-Re%4t(%84H${StV z++)U{MTku~LomTzFV7a#o-`<*Knpl{A8#fM+WvgCH%R&LhfYO5E?ypArYr=kUdjT_ z-igRe+t5<d9Sz=MK89$%fOkn}0hXJ3k0yO~FUlr=O8tO8RdknMQCs_}l<~NSt>#R7 zkr5pLQQKFCY*gbEG6N3EPlA2Kwfsa3I4zrT``}=j1x!I#Gx72IH{hS1eV#8ny;vd- zuS;&c`r|SB4I&`w`+jT?yIAH^6=eXz;q7&Lt2bTT+uZosxzTjb^v~M|Enm`)aT~^= zU}vxy4X})ONs;t{)2XthLXtWD!U$3jTqsGqf)>7mCA$h$=KS+(i_S$(^+uDW!s3<~ z(({f059RuH0O=n<Y(Da}u?j^2d88JFl@L&qK<^<OB>*a5tJ(k;S~dm?kREWvaT@x8 z|6;YrUy(AjS(`<Y0Dve&70yA!^3sF?`3wLTa-CLN9cGhWp0pu_PBkOip-8UUfo!&+ zK@{^)*Xg5o`(g;^Wt)QqvA-}UX+(sjMG#I6GKN3#))FYwZH3}NIHs7llkkCOrDUQ( zd~8{JuT4iCPei6{_-Q|Horq@>Ey)om0$G|?&ICa2n87r+)r&_6#m#bt`lA~Ut-Vvb zXQ3%g-Dp&cH4x37G92BWNPKw>zV?mhb@}#r0f{eJvY+RZObD#=I{3Te{l7FRn;l1> z6~B%Ve$Z+BHZC7h?fQW@mi+Vn`Ke5RuFwdy{PKx@wb^+Ge1!2#bppew6r3bOVh?vk zFm*ORlH(|qqPAv@y}9j%f$c>Ik9DbKj2M$xRV-;#$H)KxNTd}NL;%wlf{>>x*M2GD zg+cqU>j7g4N2p7@2Al|-r>M>jn>DG2_zfT<S_03Y9bRydl8m%YlIGd@KOFJG3>WXw zs+{5ciMZSJexPkQ&=$;Cq#BCRq5@+JXZ)P*V9|9rRou#fY=w$LHWE<At&HqBlnAb! zETO@O@<6O1x_L;(Tq=?@r=5Ccn5WvVKg8~;&z%fpsM?UO@Xf~y0FUZqWbo4(#7o_) zeB*wD7M^h^eb~p7EB(`NEJ4j0ULC8U9dsPw4!q@t=4*Pe_OB#<1LVNg)>MG<=?1{g z1?G7~Gt`B?kp}()q`0ecotGc>69Y4q!ywFctk#%27{oiap<35)<}@k~2Wi0Yf$^E* z&91_<0{5MZ0#@2_U-R^Bk&<jRiA@Rp394R4E}=VWJjf1l9<ak8?lq#ZVXW7-pg^ew zRJ*nhKsY+gXuziC$|PmA>qZD@6qY3(uo1LkVi-Zc1S{0s&`a}(YwFV?t?B2~6@57- z2~s?GE-B1$fh`Jo0ik4jZht#`JzMzMdC{`~)U9a9%z@O-)D4}*DAIe~Hg!!hM4xwD zB|NOn`@jiWYR)4;=LQYDHj@OldeTrCZTa~PjNya@SYOb+#a%2zYrinY;=JTB2HG60 zDo16%WQ{;J<d3`T)o?ZyJjQ~%gC)4v^tY>Uk=~_u1=MJKR5Xi?5R^2A>H)wFOL(MK zkg~qgQ=jkqvxijMFl>s7fZ(`t8-N&l*VOJE5ky=)*Cj<gOsYIQDF<yXym44@bCMcB z9%+5-B!QhhF6E%zYQGPTJwVq549lxEg=s`v4F)t2DyS4T=DB)B9=K&PQCkN-wI<dJ z#o;Q1kSGfA&Ii~$8j&&A*M!S?EC|zpKoN{cef0#Hc`h(@rau38lr<`pJa^@ya6}JW zhSip*tO@b3m`cQeT0vImcQ=JwivYyR>oNP>t&jqi_&pp}gkc5XIb{SGSGNGhoM?1z zIzT;Egg!wd%9*MdKb?L70?k|c#O%sC?IH<OXUxl0^nxp%cV2oDBZ9UnsPT#H=&Q;< z8}b9vSE>Y-x?PJD)%6?b^cI}snIPIInDSXitW}Vsha2cStTwb9(H4+~wb295(^7o~ ziQTJEt;UC^VM89vmGTf~?8Ye&u|yfNZ^FWaAXTQ}{(4JlKiYm>wU5d;!Y!&YKPpxN zm*E<IB=;1L40&WF_K8PsyD9+q*poJQNER7Iml%O@y+p3EAw&c+-~D3zmkPh%evhaS zR8`&399uBFXWKEH5LA?~uNm~+my)`t*B*b1AT;ijg6{qfz#uHfZ;wan{M(?&r05yl zWE?Sq(Ku;#T_Dx9?{P=jhz`<b&XKW+j7K>|p#%Ti@2d)+K12?IG*`wLTKHQ@A9>0! zDU%cA)Nu^X-AU<(J+MA+*!6;9D)(>x%<UMM2|Rzkx#kw6{HB`~0IcDlJO-dQnhOYm zmqB*OcUH|p4+{$c#?`-f`jjdZf4)f*k)f|y602!djS4gh?^d8nfGkJ0Pp%5n7e>hT z8~VfkYuqRrW#-v4tgtgu_w)QCE3VC=A}A}4l%j2zcE`OotL_JKLL+dQh9ZF?V9cJ0 z(jbpWXd&7b$8ky;bT_c`Kmu)yAE_-0FF})3SV)G1xoQhK`38$u9goLQnC$FM$l(L; zi^4DiA`F`mQf63Ek@^gLc!rG`aUUfNDm2SRqFz){f{5oy@=6*^e_-wyNKij8bQ@az z)tI>O(AaoDNQYeG-<^zicSTb<%s<^s7;)XG_*Wc4Si_rk#<W-<_jtu%a^%Tn_A73V zh;keQcmXXgezpgnnQ(M*8jy}LTvI-Ly+;Bv*uRE7Dw=9$L2*@icZ_!fsx%`>Cl*}# z3KR%H#}=|kK98W>J#cJThCWG&O|@d2(XXn!0&lRdVt^k7{aWqT9=CG?ni?xru)w0C zP4*C3;#6bRtT^Hqs4kR{CV(zq%Sl6y;Ifo9oYM5q(nf0s<3j$Hd%-9`T?9^?2@4Bc z*=phCAu^Ry&MDFUu**eD)I89X7<}_+o<ZM&#$wK<ZcbPf5Q(MwofbL2{G6vN*$cQC z)~|P^OTA?XXSI09xMidJ=UYWBvg@F1nv7X&mymCP6KtF?@2`kwx-2u&tVhVWIZ3=g z8LFac9BCy7R^I9Ib;FE~g{~3GuQUA~zX)qc<#vbOF~uZXm8h%uv~mOluAbNjJ_IdC zP{j!LIUj7UIkwJ^@vroh4SJw<Ko6HX>E#EGGlu4djIH1+T%@yCA$W}zddbi?GUb*M zo;GtDzy|(lpCamsOS6?AkEfgY(nG=R%FBkQfFJg#tshlBPCz|pEpr2UR3D?fj`EI( zKFH%*ZXeQjL|zOAF$$qJstc=eMPG11@#~O<`CAqx9%8`^rKaS~k<zk@Fh(;n)C?4p zk%tt^v+Lh+rvCR9hR63CM~F{ykfjuwEOBlNco%sxO~e)k%>ye;n|#F29qdMMl%uok z`q*{#{q4Rz{`eu%jN6j-V|Zzb$5TD~dtL43jBr|Uvp|dli;e8}LHHI_`x*-`goV-O zj3N&UCKaXdu6(K`GBI$~DCx}*zUcOsEn2x!iiouc09@=f-lByOAH6#*BPAmf@R@cw z$6N851uvXplau}1uiMj0Wt=~4@etNstv}x|a`Dw=-UOYP0^Y>AH0C`PZ=Jbj$o#>T zz{V_4nMsWail+7*3+94AmC33ty*+d-u0ie0O3tmbD<b{XN(&j*tXL%0viZqkoC#tI zypy2kE=8HodKjD{)zn0p?O>||NzE|&%VnSac1NUdW(th3m>;X|!DosANIA3}Vqxm= zg~6XWa_3N>j8&4c(N^*tPepxIY;jtx5;SB5%mpN6VUs52Ffd>N_<N=}L)ywT>A%h` zYv_A(MxTuP=<wtsbV+%96&#>L9EH?>&4^R57~s4_GG30se8ywm(1n&Em^MkMiOT#L z+!%k!h!B%}8AMA`mz|i+gp&P*v`JbO27n!uMQG&LSktgT_0Nm4>b>&=8QDuGFM#U) zK~|21<FaN%MV+$08g<*xcP6MrigY>xDMEZ}&<yszyi~Z%g($P+9bb)es*Yo313mlo zj)w>XhryAUq~R7~?bB2>sba570vxU)@PcK4gP=;GGyWaFsP?GobkcCURU-?b`!|Ik zC?VI@f3TBHMS-ZYuN}+ubcrTUq%}!ozsXCx&tlV$u#V4~cfFMKl#@I|BHAYb$3k&- zrf>5xYY*e-;%3!nSO*))HBbxS4rFp%ui4FCjLf!WGE$Oxd5Gf_on$VorYz3i3Wx{C zOS&KtdcC5&a%`?Ns*T=&{1*Q=Vcu6g5guLMax=`GfpQ90_M?M+*k;+Oq`32PJtq<e z6P8&+L{Rob#*n;|b)GpszeeX7Oc`dSvY7hFla=@;VWmBAxAF644sPSe;3AlDhLfV! z82DqrC&I7!hF>vWUFqJ4=^znXCJd=`fSA8a@|Xw4r3k78OI>V!sey6W$Sq;lkO0TY zAB=_UH?2gfgpU1l^-sy?xKMATw`jRtG%^KJPI6Np1F?xhA-6faZGQu;dLr_AI?!>& zM!PMUl_-CBF$o<gwh46v1R(yVqP(+q02zp9B#M!A5iLvq19m`k7j@z+nCWpkzKKOn zMUQV-8#XqCQQ&Tck>a7rZ04{=0#?P1{NmsY*fuW*R*o+R9~Yis$%VQ5tyQYMEfKY< zl`~r>`GA4fgF3aQ{ym+*D(IF(gy76AG|q-=^i_FaS{V^5NLrkL5<Lcue0`B0bL2cx zdyY!&5+cwlV$$U$0QCtXgRVg`k|?sYg2HN3W&i$2*PD*BO=D(q^l-tDyGURF7$q5X z#fdVnTg3)q3ahK=TRia5bk8OlUaxo!h*Hx2ClMVDL}?W_51H2$fYMs(I2h(^Is3YY z=(y?Xu>Q^A?vfj|eO}c849h-kYN?yw_=PD2c$(ygvQdCij{diD@YoP(HCIU>8(3bL zdhtYxk%@S46zKCXei`ifUCy$#_U~5sUIEbVeB)dkI0ahLzQIX}9$VX*elj<%-jv>- z0ntLd<qml@oS{%{Cpz(50Azh0kPl9iO`)bQ>O9)>_NUY!7GKD6_XI79LBDZJbyN}y z5jeVVVPWnIXx0SY_oYTPOQ9?_g&~!<X}$&q;PJ1C6=rpVCyNPgYT>LJ>)qu+d;z)D z$wd*HkE-!Mo`FveUvQM%5WuP^U~c-50`E3pRR9eKJWc=%XCk7mda@Z(mZXNL)IY-r znmK>SE;5&+-CaCc{w;5qU0yKgF7@2%lZZIrvlDPY{lm4QOKRqy<Rv%;3*+>xTcIYX zIwQe8Br)znv`+S0ZT@L0iI9VhsD(^HFwh;B?W4;;UtFV0VawJmXPQ!|Y*(s^Uj2K8 zoOQe`Z{|HL>&@UYIo|1P+z))RvuwNQst#?pSX|plG;jCffD;rjfl=8}a^wlMPKGuO z1Tg&CNscK+*9Cam(3*Z^;gemc)8-+1ymveX`1No{`sHNrY5zJA+RH^W0d6NeXC1Vz z3BemxdQS6<mW%T`fk-cR=le6H<;8$>y5Zu<^yfoF57N`TLymYyFBJQyc2xZJ+u?p) zI%{}=rGrk4XrBPW&E88oh!Miwx#Q>i_VD)6>&E@$agsn~<LbjA^=oKg@0mX%Ar>w* zoX9QOIuAvtK4mMr>?*)$xF<r@#=0(6e=7h>L7+Uk_S0PN5B?7v*s-`smoikNJVFNs zymo{!BhX(IAw~}!+VcpXCuxKB;pYdDfOwXs^T(^LAxDDXR{2AwjA%mYsJLekv~E~Q zo!LHl)j~EYCX8r}WOw~Fg1wihXis~M=D>(OMu+f$h=05K7?nz*%~C+vZIi}95>L?s zs)_{iXcYV{Es1CFsuyhlR#|yZ^m^KekY;Z{QD_Fu^3CuN-%jN-)`j(LQcGssAcy7= z29JPkpGfNC#2wphXY1a6HI56xbS(j~e}KQy9h|UM;;jXod&R%Pg_|4xHL6FLmZGSr zoyaqEfn%+EqF53b5k&*QM+i)SBCtCM`&A9bwc<-=Ntb3V@<n+>LyFmA`&W8gah~Fx zqO@RshRS9-OXVaR!+EA6iiEAh=5*3N6CKEb5UP%dd5OHv5eM15s;1*FBlaG<I_yB= z;2OYWI2e)-rIgY^J^1oL{UN{8!ybwFi+vz&u>inIe?MypP7Rbo0{ukaAKTFv7eL|d z91H=-9Xww!bZm=yh89;D!m5Fa=uU{Ux@|*qao=#SJd87Dl7cm_QIgfRK2-P-1yM^@ z*g%_Lok4x0FFf`|EHZ+6ucq4v=wOUwFe|T|&udRsDr5p@0j_A*?CA&H!+!uy|E1t( zv?AEKkO9*YEQ;38NM%R?)>ytjvVB}+CSqX$X(Orm74!_PifsX}L*-6IGO$}p&Nkee zSV%1Xlmu-$6a*1*4qEO8sgs>HEo2+Rzm({>TMF;9Jj$L>%Tz@9W?STUcZ;FJ)AcTu zvcePVv0<r=tl(n5`@jttqNxY{v{=Md@e7y=m?fAE6b?pCb_R;TJy+z%KnGCE(()8k zB=uOgWx`H+)|x|=8vjFMJht9XD$;BF;59GurYemWzxhnKUnq|*7x-RAoA+q)>VtoV z+QWzQK4u+r6BCI~NsAJ&fP)C~ZN;kX@g|~9A9+d#O=p4w66m8y(AO%(3#O{gMxj&P zg}>mV0eZFMab{rh>23{Uz7cZ0MXFaFy|O4y!xO)_gD#hvMvdtC&iI`5#Ab@2d(9Z7 zMy50lH~dxTNU~(n*2-;Vn>Qp`QoF8WSoM!Rh39!uC_;X#khsD^)ba1aRI3SclHy%8 zsy)Laxx6iQxK+*{JBs+17*JB@!X$*Qa)A}VwELa2L#FW>&auKCIr*(SvO?j!);XeP z5y`A<we9j%@6JvMbO{)E5Rn`v;}Z&=yCM)_3e9N+4Mc{B5u<bc$`5N}v)h044Ym@e z?a>0BuUZ2=wynDD^()3`A4OAF91FMAxlgwX36M?+kg0v2yG1iW4nUibd>{?V(1~|p zAfFJmc85-HnqYhhgYcjs1ul*a&Y)n?GE#5UJ^+JYYYV}(sVIUxx>yY<K2nD@IJhCX zKgju~e8LIW8D1j(Q2>MQC#7xPx-|H=pnSgldc&B^YZAJ6u3^U%&Fs3x$LvFomL7B6 zNoMd@Le!sCT4V<iWQvS6WlQT0`qD;A_SBcIzho_yTU6_&h+rN%yo`>JKr!+`;_QZ^ za!MebXnevG2${i3^ctrX4hu!AXhnpVPMOEgjdl(HNTh9f^UrDvN4^9`?xLpF`infa zGwaSN4@JQD21<Cmv`)wtT%n=Bc0@d#=3DtXt+y$of7l|qrvmft50?XPa5+<4-8QaT zSE6yqgmeSponb4SX&7Z?zTXwquH~nJ3G#dIHfd_zHD(h%;PlC}w91d-Imt9-=-4Vf zh`{Vd*F91u2b@sa(d0wSB=`r&uA<UHH3w99o`R1;b?B?^+xNxv0E&y4re@K2=KpRO z6D^hLP7Zj!cA)dZ7SAGP&}D-=FM3^^kFah3n!{`;+A?qH-8s$D%=T#}`nzGm!1UJO z>r^X*sW%L)YzmQmoff{G;Wg9YMWXYHm=?ji+KnU<)x|Jw?(ShOK)FeSsooKtv`cwd z-gBscdAh0Z5r5DO{E*3OWz<GRyblH9T<D=}xd+Ni!SG-&hfjz0;$Hi5?0g*kMyYih z1uv3iL;%-|vU<R6(dk__O~Li*yiyFJ(eP#QMLo3sTVW$FhDqXax0nf<u1#@@!dq=n z3}W60#GX}FZ|wAV-RNw5IpIdZ)ttt4VzVid{Hs@CQFUR{U`yEbO>gdH_Q~2YAm<>E zE>>s=L|RCL=?HEhe-G+ccw;(d9AdY!8)I22z6{-!qZjeGNufnm<_>Magbc@o9tTOl z`x@5XV55$?MevHu9d6s#J3^y*JDY++#z0I;blHEGt`(&o*Wy6HYU@23LbY3m;>P<( zn99*RNQyqE-~gJi-RROchj7HtpI;j2*hQ9b@kq&=x1?ev*b5vh<<ahP#5v!PW>?HH zAcs(TCcc{WYO`cf;r9RdI)@-pfF@hFZQHhOTeof7wr$(CecQHe+jhVE&+5%Y%q(i3 zi;Aeq%yZ7S+x&H%I_KooEPZ!@q^ohqap?IGgsR#!uzh$m8B-_^9s7@ahyN`EV;6lc zO`avL!E|gwDzCbre&#g_Wklxb$YM9Ap(U96ccF0icxENV3#1V!u{lFEP$>-A)#;YS zjzV?kfZ7b!W`S?ndsJ2i&HGCh*8QEJ_0aRcEav__Jxae=Q=km6lMMTU7G=VTbkjsr zWOd93`-w|B1k?2(B_zNXay!5|t(X#n{>`rw1IY>To125rbVJ&F0jGk~R?tCb3b3>u z7Bjr|I33S5fqsVocfK`JLO<dT%E;{0%nm%+@>+nXXXMZ`2W-1*Nst{%#J3e777PcX zkSoeVlzwNe(TtB39y5zJU<4d76YddcG2p(AbwSzRQvqhW%+pBFi-#3uTaz|`-vL90 zVjZEYvao_Xuea;xtE2;Ad!ruWmD(_uOzjm!PhWLDbcS<7!T21u8d3tK_dX+Z@Edl_ z?xy$SI1grpM-(b^T|#{E<oLEcAiBWT;SVqJCR$Qr<^)I{?7-zway1H8Unq`ET+knd z3l*jUXi=33qax8)T2MH*HA2ZCh}Ps_Pmxa)sTcNpuA^Mv+^sG_G!}G4#8C|uT30sq zQ<H3)FejI9m|1Ujk5<LBEG1&WsOvPppGSE5z$k;aZ&m*2iQ#UKPqVr%LO{YA?6rmI z$AHp4rfFm`TagTGg&U3x_yagaCD^eO07N}9qdv7Uej3+WSi)vS=HMb@H4L1f(G+fp zS6gBX7TD)zEvh%;+o!YX{kyMeM0d*aaM~$voU?H3{vh3g!@KN$tB+@fVM}1tYLE`i z!|rBp%SHj_&J#ycLootD0l6r*dXbT=aIR*TnM^bNvq&16btqSgIdvYEH1yT1r!u&o zhwsU>0|4{Z=CmKWiLv=u+eZ>It&R+$*3~rbVbC_EuFN<bBmQ9j0pwk3gkUR=bOnsU zd4-5DfX<i7jylq}w<v<}Q&iV8hj!`NLx7jh!JaN1f=X64-83*zA@+KT9erw=-5|!_ z$ic4ATnGjO<+A0zPJi4IxA{cf`$qN}DL=Qqt6qNa;xVms_h#zKc64~8z513y_eGf3 zt}xKE0@y^5E$(EWoG~4y3`+rdmT22^*K2d2-m-uuQP~MihOYO#9@YdCRl9<$n8`6d znI-OlkrNhtd&lKBtfbj=Rx1TIc$4uo1Z8h?f}KR*TNqkaaHyW9;Y@y^LjVMgKLFWq zGsi^<eattoYz`CHwDb5UBa^j;!VAz*qC&H9N*mIBgI4IlLn^#M;++RZiLkd}GCYw~ z)6+7A^VAx?X&p%gsXq6vCcuoPF(y0r{SaU~ZppZsC-e+F61DAWo$6HMW5_(kZFLWm zS^|Aj>3;eYUt73+#A-eZODB(^j0(g1QJid5JU1gO*Q2ZhbKB>$q#X2B&AK!ehx49o zApH4%1Ub!~2&B$rHwNYBuU-9yK9`;5uEZI8{IqBXPx%*NZ}UHAb$8!Bv2Ticp!$Y? z%HAGd(&Pyxh%SHu0;ltS-VaNm-^=(|?962TF|Eu_y+%h}Rd(gw1X<65ZhIyy;4u1H zGOLTlUd3B7DtRMz<nty@`E6UH{_es79<^{I_zl@oC^#KxN#={#veS-)q(S@zb#0`+ z6IIAwYBunF>v-0x@1NyvFBfe8ankeE8-{GZ<G=NOEGYx08%#WuC6%?0TJ!BD5M#(C ze5@_=BR*W-*jc?gv2a%-L4{Xk4hV>4UBchFTiE8tuI)?^BX!O>BB3Pbku8cob$Neo zlOoA?`atG*ilsHL>0Gk=eA;?U<jY!F7y0riJ+WiVcoh|T6lvn*PxvljYt;itX1TJ( z!~cG;z5Svct}lqVcN5$IXMzXveh^)?-I~Dd_xg0?VFe^}SJ~1OS&j<0dUjd#u$W#K zf`{6Cd>$ohs0bBv<Ctdi>^Tsr9Jj6K$#5g_5XcVC)@1QnR@Q%vNIL>X^!V|D<rzEd zVE{J7D*?k<Sd%2x0TQH!66?Qd%FTVw?&!N&NONI8fcM>{xItQh-|lkyTz~aGy3D-} z60cT9_s2rWwKrpW8IBHFywZtB4KO_17WIYC77J^Nb+GV-dL|DWNe#d2$&RO|2$yJJ zn+Pr)5`V!#nRa3c^K@qGTrf_}Qu^tqAVrQBaH&`*KBp*s|I2xCE*f@!_fWsb{&w;W z&C^Ug*D(bma{apJB)uxi!u|s`+i^>%Wlj8G+HVhXn4W7*?<R7vC%}tr*eQ7c)No~S zB{Q4X?+H6{?!#KYV1!KUq5RM2b@sMPZi<33X6$PfJ8O1290LbpF3gFQ=Ao&kofw>} zMlD%y%wckX2uQc+lqqfByDA1E;K9ZG6%;zodJ$*ZNmM;Im|pl>hsv5(JbgJdBR8%I zK6g`8>(g*hyW)z6m1Byho3<v;{P@u}Jy|zSNE%7Nt=ZPooz}I>>plLt%SWgIg24Sh zaTKtz4LY}&005ZU|5s4ze>5fkzobO__s<qb<FC&T6z`)Fa}x|$V$Bs^#g+<?@gOZo zB%$67Z1N=Y3IiP8rkRI-N6q)Ho||+dsTNpc)?c+*mo`l6ie<}|PX6tW0}ox4C`Xl% zh`Y1{SGLJikL<g`)y>%jrszNYawB;!ugjN+(0|bAAA{*Rz3C2VOxCkgpl1duD5C6D z8!H*INDC0UJyaC}lH65|iL%nJ{?Moz42&F8MKbrEdg#`*_4A=SXgnm#u3kl>4`cP1 zNdn=c?O%n8zy0uJjZk_`?%x7&M63-HX@v%MpF*~(nbJ(CkCoy;pk7(Afu8sS7(H^t z96V*>-f68<VJAlsY3b01w*=}1p+r8{{{xnoh>j0wp5<vgU((Si<pb$ZHIhCCj8`Mb z_~1O{<GSXTc(~7+g{kWs_wq{*Adxh(^iX<W+QlALJga#Y{oquVRyi!xU=uq}FA_wQ z38o(2nVSZY{9OszH>*RR8epMt$LRN~UAKCnlL5I6KzJ!v+&<<AndS9du69tY=I~M9 zx^t<YB62rN<v(35<COP1z8w6#NYd+GFo9cKM$%m(U4nl6EMw4c_zTiqIg#&vam&Kg zjn|uZ-(@Vmgi1y9sp_(Da~5@KfXBT%+t{q;bA}?Ug%Xo#6QGdP^S(o4Em=xs897Qz zRAo+E)>>^WNJ;y(LCWAQVDZI~V-|D)%eQ03N&d3toBkpl>R3^VEGLoe!7|G8S9iip zI~)N@rIJQ}1E^xMS@DUaYhR`s3eI^TF{fq{G#wY=fofj}_PtzE?=@CX?^&WA!Q5Yx zT9^SnL2ng9wb!v(z1!V3t}%JwQxE=^5v(6pv*`M;Z13>x&YS1rt^N1@>+5b16!n72 z$-DFSgoDGQ>G$Vs(15()kp1v}pM!&+w>#dX&+@t1;^98bc#ip+GYT}yUH48yJ&;y( zlM?9z(uhSAx_!!apPmvKzM3X>-CHGa&BrzMPQf0m7N{7)2qdyKuvf6zi9n7|Fgyj% zDBh<-|D6lIjrtTQCQ1WQejcK(Nk#D4Okn9XIY4<TU|fkRWTkdB>Mc8&3V<-YAH^~n z;|phk5OCFDCSWv~bPlPrQ0le5E3OuFQiItSuv^}~GW~Iez(x*~SMOpY#QIh^bwa}h zCYVfZ!E|62_rs-4pd;U;oLZA-&xu$=;n9O&9jl>zWkinbE+bIgwvv6+H(gk-uwPb( z*EFkc-F9~GV=eiNRx>or7;CtxRYuaySVb?hm0faR!5-2H@f6*BjFvvxlyn`J-aMW4 z-0#&s|M>g*m7fV`EhOP;Jv`+ydv#El?MWUEArU<CEl%DLbIG_cB2lwGdu9k=5~eP{ z{yCMy%iNxrwOy6AK#cW(nZSJ-usLN|z`r|~U1O*laa?Wz^l#X4pK7s&<Sl-D8i1#Q z=biz#t~43`BE~uQkr3O;9yW|^Ts{#uBp?yq&MASpu6a*C8n^>injixLPsSj^y^wzf z#)|TNckj?dA>Pl0aAH8?WF4?hn;If`9Wg)E#gi9^Oe(aK>Rylp+B1@OxHFh*ufp>N zGBhM?jU$E0U(+IZ<lA2G*`Yb3SrYbgsCf|g4$I|4E>)M2E6cQcThM1f_vaD+k$!`_ zNvJG6DQh~xhvOz(Ket$G3aVCZt8tIKm$+gr-f-wSisd0P76;By!5Mn~>p?4e`aX-< z2?!|IzZNn0MXWc)DG!ZRMn7SLQEs49)qkto@42+<BF9z&_8_(i8I_GSELc`D5gF>G z6t3#7$o<NU;&p0b;C)%KQRZXjPp)fwFW0$-0IU7zAFey1$l7`Bq8LI0?8TXa(CGCq zQI-A%LD+OgB7-afz*L{b@$RmB+(X54iTF}*^ruqWANfl}V;RIC0s@x$V=F~Fx&s1) z@&Q_>2L^yUBcd^Wl(=FKfoisRv;u*r67~UdgFEPsr}1%T64L<cIZv+td|)9M!J>%s zeg(&*qH2rc2zTZ5)y>l9#xd}S4u;}))nIB3#QjB|<$VeST3(r5Ma7w)t&fF$pz8*0 zF<Itd;sl;4zVVW8k)f3xHrsdY@DQHId$4~q7cm#cj?|Q~XEx*>Bv+pt_`H6d-1U9+ zUaGFgIa&bQRKYH7Oq?M%x#Y26;AO?^rXJj=E1h773^nKl{1bG*9RA687K#D0=_~&R zI-6ua0<K<jGIM9XhSk0a@QlGlse#$dfHq)l!vbJw&?p+pSzZT_NGc$XMRli`e~DXP zeX{EG3mVXf3Nc9nUYI9!gkRQVj0#wzo@qblsh9FVN{NRi2@|rc)d!wGSw%`7Xo?^R z)6=|<L-6VmjacKxv}4vrRWI~r!WNvcCxBKn2bSzH-Ri1ke`6vFs1GOYZm9xt14Sp5 z^+U4r_dzsw=(x{F|J>DN-Q<mxI@yq*qZucBd}rmcig0sbdg@xq4^;cP(9|Mm`$p=K z(AKbTjmlHgm>L6_LAmWOzp4o>7b+jH*4)Yd`wsM;LDu!n8&a`tJu#XIhDeZ!lpO?z zgaq!)skiC`3dVe8D8`e@uk$PD&}ZX~R8T@r?M<&WZ1^@~RJ<V`FVf$`N@#WqSMYl5 zr!@sz>9n!05i|r6gxzdT14gYro@@h>i(Ec`5Qa1WL&nKU569F1S+P?9tR^WbN`+er zT8{$*fXi-9PWSgBHEL(!qW+3x>$_7{O;*Xe-p(_3;W{YVW=zJG&0KKnIG=8%MyYva zvin|lfJjUf9Bp8D2`{jx-PE}OD$UwTF{$mbGEwSuv2+RqF8cgnj{x9yDyUqcYaj-$ zg?Lm0hBN~iN+TNE%rID2)r!XX{4t67I#7G3!B>n;I15vouuXN87V}I4B0#ZN^tQ~( zD?Ji!_0b*k0jF&EryexF$XHYv&YqVBmoG+!>@Bd*hvP|t5c#=RKiJo`bAs>vu+u@r z*wSqb3Q~rwfUsGQ1_&pnIRe?cTVLF?=>}O5tiEWK-hk36c`kQ(CuzWHCYNMmk|Xft zI?v?SCTB2^_NiWJJEh|*P!lTw^eE1DdS|+tuCJey(y8&_^wx|+|H9+`3f0q>DrbJy z12tyx*;@h8IiD$^XD=zlpV&RPp^`o|RpcvZ5hMX*dsrBgWCuYk1T-gm#XRb6>6OUj zW@Zk6F?D=J`rgwf70dx^@Um_2I><LeR$#hSb7I>=3D@G86l$fp*>t5e$wn|yu}&9H zB|1HXHqdFzV0XyfOpPj>9-?OrFVJvb$<AO3;S203&TNjBJBvoaZ13Fzh_8<eECyr= z3OYd+f7^+WCuj(UL5o%;Dzhhz&>qhT)O#ECa{-i8LhNGg0m!Kdzzh`{H0!+i4}fS+ zmR2f%>Z|&j?4=QXGz<XTQtjQm=engb9y`D6XK|RHai{m&?`}GsW=d4l3X{)6B>qY~ zAAp+xzwYed4DpGIatQ#Rsl=c?B7+#VWEBtyf+QZX7B~sYNHQbWG<L1;E$bJPrvBc{ zkwV{)BtZS5v&Ay&kCuP9>M?mB^cB<QP@^<|_R1k37~>-fL{iD9P?3c*#|zEnzdy|P zG7cb_OZi}SAFR%{W(K7hdv$JNG*l~s4N~{y2)X^-%<N4QjH}0L%PPZ_nUzZt5Fl7g zlhrE7V(idGr)^Rj_5IB=sxhk@jGH4KLEFDyjhLJ4Z$Q~kf5aj1Krqz!Nrw+y5X&1i zROPJoAMcK``vzhD{rvX##FmvK&_IM;)oVcSW%MJ*PO4X@Q830ieBO&@cg`SyqpgU= z1?uIF(bwMgR>j{cbuf}^2uqEt37OL?=wsTm_zF!&pi<9L=A>>f<3uVlTwyXLL@cC@ za<2Bwz3=Z2&fKG^1pw>M3Hbo@2NpNm89+ke2MEGTM&_rDO2R>h;?BOnc4+z~tw@|h zW!Ke&;H49ppkQzxsLXIkn#m+a28zS$(2uEc<HuUMDD4oCC+h*sR`7B#$+B44uV*3O z7-OyC|GlI%EGeX=xS&v$#py2Ix(lZ!hfZ4f*hLb4g}8!yh5F55zwV(cd%#A~{#(_2 zB0&cdpFUbAFnO_C>&)}oXVp~sY#2WhpPt-Fp~Q4^7Owxm)hl8GMIzB8{Rs`hn)2SP zxLVHGN>$5;jLS7rY8wmXis!LSGfOH48!A2a_Qfn#;hAv0T7^ZHK{8Q83xb9g@#;kR zUB2N!hU!a20H$8{*l0m~p5EYX*MU@ni|obSgv)}pJ%2X9s+K(SfjPakR4h%Ps@f~r zgp&AF&o8Z|e^va}&Rwg|$ovcoJ2VL_kp`ZdZuD0(BUHZGcFoarJ$_bcY^QcY)%^SZ zl%PH7VwG#qvK%~$un@ZF!u=JrT-cRsBKbRmKx&uASLP=Nca}Fxf0n1$Gsh2(4+ppF z`&HuiOtDUIu!wpimC-C#Y&(5_&f?g^$7$dDuZyfp&>6k_eII}SAc*g7>|OS`3WnR2 zZa=K~)msqt{q1tMA(b!mK+=s800URD2Ok|J!4UQr$A6iHmxtrm?&93}wBP7;lnJoa zzA`UQJt~?mc~EhR=ECt%W2OT%_`Ay%FWZA7`e5D}CN{uJ22a(s4H&scBWoL*1FL0$ zp9$sC*1C3DEl^h>d{ATOZTSW5KpCtU5Zm@V(D)SgY~}t3%>hruAs|4%mFiJN((hUJ zx4!?SiD!fZZxL?!hlF1*F1a_cUDTwHL4V{+M$d76ci;ua@GN)EW0bOaq&hA?gB3YF zulbdE&&WH>y-n{E24dzo77cpY$S9pMzZsYgl~qI^S&dqAuA(3zkR%WC7A!OVdS`i| zONEQ-Kuc~ZG-;a}X`g5kut+jqEKf(|E-#`KCCZ)(eLd7VE*xi?F@oKYS(av>&?a%) zc0gNSjhuz_t6mA;X1BM0X9BmKBNoJGP}#$~!<<lRi%g=UIoQ$D6BRMjO+nZ^Dr?zT zmkKffe!{;3FkUNhqCWrYim1!wPsG7{Hu6CLTODJ;1`V+XYuh1QSCA*C5#Vna9%ah1 zL7fxEJk`beT&lcL{JlI0q4+4NH|^UVV!xVa6=IrgV7*+;HF4>Svc#2@X+`LCwop>Y zv0pBzn&x3#i;>B8XpPHeq`A%ak~zFW(85*TKHlc<<V>wen3YrQQ-iO8x?nTkGkC_1 zMVB%GUKBfj0zU9xOMtUR2*R_2{Fmv03oSCK(b4dt_Nlf|myzM9YHJVlusqgAq81ER z?E#+wE(|F1SK<8QH3Prp9%=^hQUtLS5!THjvC|6?ap7j-<2FrJF`8M#*@y&9RX>}C zZ7UbBNg+b%y>>@)4zQ;3mC>J<YP(}x3kVxY&FA7*Z0AEcVoyuih%zN6L!2j50^-Q) z;_}>j3y>*XNR(}8DLWt)o2@T>V{#1_YYc};@H|*3@MYH{k^=h_90oca17+wh>EyO4 zq8%_DY^Ht;GD%nRafNfM^W4hobI<!h5d>C9n9TY8;J_8V`T;2ks70W&36-SwoNt6= z^|@BaFIrmuflXJY@y14YYz-l9j$(`nTfHfsX1n1l#7P@^10E?>Kdfc(2LG3|pLf2A zNq&Buzr)t8yVmIVCbTR;k1&`Z-&Uy3mUMhb-ADU6T<PV_v#4_lV1T}|7i@Qf#fImW zYeeNJ-9884_ZLbW%9!}zBmRvx7c&|U(>w0MZ9`wkq~AUrX1h3$yNYoQ`09REfaMiu z%n6SgJaHYF{0{vN395B5on$b4o>98RHlC|ji8iRUtt6GqnaLUB;#y1FFw0M+H364Y z;AM**xXuiVlp3}{L$KnwTY@1F4g~pFv=WE4xEnWp&Qd@LheR@U$AP1BCgnHoExEMo zo0bt9NTe?_7Psw=HrE%W+Q|$!D9!G{vvlSzV1|+m1>xDkib#weJ!Fy_olOe&$!wl? z=mlC#p3?*Ryjvv(x^2>Ka@G(afd8ZuH5DzmUKhP?Rd{@~S@k6UY{tj8amHq1<vDj@ z#;H9*W;kSk_?XY2wefYJZ;B+gRC6dXe`G`KYmV{<nwvdu$OJ6o`L^G<L<y%4hw59N z+6-?h_XqFZ`57Z?-}HsUtS;Ok0|1Ub?BpRov$gpUpnqPte@w2lNVAWY_Cx2e<gRlT zD>@3)c{Sx+$t^2Ne9QszWTBZ{Q50hv4y~?n#l_e=GcWtDKOAnje!y5SlnBMc!xUB_ z?f~Y~c*@yjmKKsDYN=use1eG{$`zQ~s{&b$TLM9*zAr8N_dY{3g2<%%2I?c*PVRm3 z9bG9b%=S(FHEl}&NgVP}_vou$gTOy*6Is0|{!wDb0Msrtz0EgbhKaXwg$P%yXgwN7 zHp}qoUp_e4uQpmcUBVDiM8>9l9rZ3;zz~3OpLcsKDrK9!=a4LQd*dE1{_M71TV=8H zL`ZkzxHl7H5+|Ak!m7TjX4r`4Pq(KuQ<@ycBgBp*Jzz@3-Cva^EGitXl?cm^`AR$k zMW1^2x{?Y+qNe|l!sAg4+}^J_60A&Gq<(!OQ8@Z3j;DDX3OlX%-Cj+&Wxpt-i+g4+ zKezC~R{~;b7%@4*1@-T@EeEw)iP3ECQ{5o^@mX8<?kZX#bM{~cq4jyyY5w$z#YN0Y zAH?O^GQ!%=t?1*@TWSv#tjXk|OHt(Iu6|1BPMzn=i;&;UbTbv*J`rqr2A5@DVxa+} z3tQc!f$zn+@#}Jbe0iHoa6fC_Ao<flpxQw;3bbqNRtL+y)qbZKNvmng<(GMSJ6s1# zo&u}P#nIp;bg6bpY6@?yMY))9JpyaVRda5G@5{-}+q+hDHRrkR-y~_Gvhk?oX4I5R zmW4K$<=1z}zOkFn43&(oycy~&C%~|QBC=1wBGmw3{<KY$OM7RJKU4k!)}|6W3Lm^B zg;Q!JtKv_aL2K+kMQTDcmb#C{zEEPLNqMdJLvN~U*1wue#=uO<blras1vjN0-)5mu zIpCQW<1%1C>z271rS15Q6sBz|-f#$77KMX#R1V3QsC;H^5}LKt<k_aat<P;?ajsZq zGGK;4DoL<U{Bxm+;UX8HdbZW5H;r}8?hXd@%Ex_h0lvwigjAmWPg=fT4or55#}|Uj zs&erhSd`RsSkzYh09G|4;t->~VW{d%?!~P(Z4w111$FA2xBw01>aaS}a}0ajrj=*~ zlS&(1CS;rK9^6@U3)Q)NEEQva|2bg0k>G$7g((k!_h3!h<6{&`1o9#_c4U}N@(^6k zmAz;u6ib*@w}APBcb=4oy^;#O3j;+3QFuW;6xiP2lWBv^@_aQt?BxioP)v5z#{!S! z{jj1=Z&{*ef7oa#?*_0lugkM>8NLGV(|=Oxu_|9Ri{^FLxUKhUJzB`hy76q0TJcFO zsFOla-#VC$>K%JpvGgx*D&+=hO2I?Zhal#aUrpOT31i~A9T6Tm2rfWNMtk=1Px=v3 zADUL#B2GQ1sebn^sLwjtW8fHZE&hhXa<!RV3SoI>Bb)1JoF}}j=zxLGLB*shvbPI- z_+WdvoE6j;9!tytc4H0hxr9&2+>%sE=L>PJDJPxWC}Lz58nVT;|2Kg8KDc)E*&p|L zr}(ro9ny?fp7EGzO^W=KIqH~T(@JjlC0dQb0{8Z9^$YATrVo|8k77)~BrqHv#cKK3 zeUFMuBJGcs_rDb8pd;!8Dket@i?n?y!Sj&r4dhO@#LCSl57Aq$)s|Syf5xu$PPV=3 z00_3zh^;~>*;e#Wn1qT3mqK-UX2)y^l?UYBqFq@^EF&le7soUlm=_M<E(ekKm5s+M zkEBSP`IO=fBpW7+i4(OoUo9%ed~_ljE%4$Q_t41br9@rSh;sPw3LmET>rW(f>5n_$ zB4!p<VOG_pX2KkYvTD0`UPVjIbGe*#9QfI5%Qwx>9;mrK1(5_@nqMNh+d}hryI8;Y zcL<-MC{~b59Xf^Ous!zU_?(|Q{eB-OdwAn~0qy?a=fpl0Q2x<c7pR#{I3KEyto>yq zQ@w;>yFng|+B`b9^z=dxGRt!W6BLlt)lXSqp>5I(F>9ya&J<X~(jO<9G!RN2@#<`; z>iih0iK1dXZhx*N9E)gxOevkUdWUz1X?#K(7k2}j^b$HM!S`}spSw-Vd)fEvKi}-d zztM{hYC2>`zm=Pn4=jSem80iBEId3Gq`kH59*)63ZfJW^s+vyw{w|oRGH%;e-{(b6 zqyNsCY-_&aDwQ^&V|)dCA*LNJ31uzJF`?pFrwvu()9_)Qsa0gBI=+(O|1N;8tmIya z4shC%e_jHPUm^!)Juiyp)9pr*RnVvn{V0r8%QeyyHNz9xbs~#sH@7bTl+3s2Nw&Ia z?lO``!9dEa_D?!XS576fa&6nI5Co_Gdbo$c1tyUB1*~bUTXP>^pkS(<v@6EKEUUEN z3xf|^e&dOUU5;~8rm9dz$6X)g)Wc%ObIFD$<_hOk<U;tE)RNSk6S483I9`UeIA^bW zYCii0UMrB!tNaEfu(#|#ffpwpv>pX+K9hs=Xha;U8_lRCCE;bD|7OXHE%Ckt>J0^4 zavRk+tuLmwC>HCViS2i37l6JrTJM3JBq8gcM3!Keks-5_F+czxx`RE}=VjyT>Koo7 z1%uT8Y!V8@5OKSp!5^OQk|VBI7<d6qWzK(U;PGAOm`--XO;onu@)`?tRcTEk>l4@+ zvtC6Aa`bQ4`&H2+3dgyHjLB)EEr|Kh&>J!ZxqArJ5@Dh2t%8R^rf8ub`ic4}?{vu& zIr+wR7ubADisTUy)uXmnQ4;k3yyKE3abX8NxwRFRx!E58D|;eQ68@xmib0V-?dQ?Z ztpo4*^l)o??fvgAWFU$~M8ALT<Mn@s_<waF+j}r`{AXii@E@?AOKd;XfB=lh?I&sh zIkXFZ-(T?FLJ(Plg1^{_%2bm-e{Dfqz)x8WLeo0tK`>Sl%$g~sd5mQ-Ed046LbJgT zG9gnwl7iA?@az^*h|Cx<um#X<!#;zBS|v6@d|xYeE1PvAVCk?gXcCVn&6HjEt815x zDti7UF9U7-w%kDe_xdY^p^O{=0Ra5|`SJhH`v1#B{a^K)D9J|s$CCf41~X2`R{SH8 zxdu7yfDR@78lOs+Y-nuNg|?P>7u}ZSrzeWt1vxKBykmaS{jSi>3Jjb>p@1*H328eu z2QEm^07z&OajU(s#&XfEeLKL;sL%}Gm$PntavfCaAi&|3&z2do01_3JmUn!=dU*Jn zCJOUnEJ}oWKUP`f(JE)hq&+5W1`O}*IM6@XAgqwY^btrLGN1QU_v>RCD^3k+bOu;w zdBE>&swH>x-eFnRs#qs51~O`<58S=i*&V3^lp}at)d_W?TK~tQ!L(ma#rxPQgZ4V< zNX3C$)xqXtD7T%JtAf7uLMG*CxU{y-BiA-k$WZf$Y1^Oyc~d8~q)@}Ar<O{)MD(G! z(ijPQbMea}%S>;pC08PD)=gB*HW*7$$zxF_jly@Z-%aU!q>mk9ReEdzA~<#N%jh+( z0iKuxNB>^S!s2J1sC^qe?Z#G6fYn|+3YXBiu&(%SaAOd@i1F=zq<4p1c&i400sxf3 z0s!FsuQ$%g-oVZF-(?$C)3MuRL-ARyYj<K88$c<tP=s;X537c4<*TMmti?b;0i#u9 z(~4M<n21$;>b>2Oz8G})-~nzReR#O@&Gs6bGHp`g-1SiT8)7vqNInj3^-`G(_a!GZ z5%fqCQn?tSCU#1Y-zfGeT_Jr3_A)@V$Z2l1Pi>SnIn>gqkU|y83TF>w8BoVv(nioM zXb)Y(szr^ZfF-EY)-e<y#MLHIYh`Bcc_3Nh+>r|3c-FPHl;}OMorBW4)*wp#70ZrP zui{maG>_42engZpZ7NxqxuOn#bM_(5%u@hAA41YkfUPcJ72|?%y8ATVDR_pR8EIOw z<-FN{aq`;x8;*Rr0dx44P9jN34WU7s$rJ}zJ^sF|0_SDHJ~F=Cgd^ppy(za?wDh^m zU1ZV<(hgwrgDUO*z1dU+au=ky?fT)MgvgmJm`Z?iQp_MrTyM-e0zi3_b3%BpiKj2Y zL;OHP0j|f@T(SlA_Zq9hM_pF3bbefFXaHo<P}}SGin->ba0tn$f`(h8v48o2*-(nD z0f|r+bmFf8K6*W$p+I7Ob3hOW90l-|pusd~8oHE<ig~P@<Hfh!Q++gRBca%PtB_~h z`l)~SHObUCHBHi)W!~`>apUkLnF}(?NcfY{1+KErpqS7p2|E~~Yi5vIA1D_E`C~fi zh&jc0Ry_1O0Tlio0%0_aEqEF+Ets1V7~x{iz!gLzAVL+giw}vjHqv1a>RCUsGMGw2 zN-11UYAurau=2ck<p6alsIbO4cU8anRW=a<1yiCQJ%!9e6ANfs%PCO<MVRa<@F2op zgtH`OSW!hKdT#RZ1veX+XVA>!qvW)7qD76j_rxbLcX_-=rUq0g;=LL5s`6Xuh>9x< zNa~&R4?5_IzF2Jvos9RjH)tl0ShALdL|JCG;iI7``gb1~{_|6EV=NmoqUOL+EHw3a z*bxY(2D2Tn{1N<nGTPS6Mn-$>TMLw4$OvCCi1?NwGRm*5c2GGg<$G)ApEI=X;6cj} z9%KoXoLFurwU|**pVx_()#uAsx8G|1?X8_|pI_VW^AEPLnx{)Klo8%)-d5J0f>u)C zjdc{RpQFTgNza*5dFCL4?L2PbijM&59XxT6LV!%UvAh0eCMZ@5h9491m8c*E--7~g zh1`sGsKo$679`g4_?oa+w}O3;bIFG65%J}N$HVFa2u?)U(p`8g58p=TmC1p&yel_b zQw_TP&DV7zXZh%x0(E`Mt?%RI;5ZEmE;%@!bK)=jE;vhhxL{lUIKp<ed;Z+ExKCT} zDGlqx{f($q@v5^GL{c8ynm>tDe7MP?s7%)4fdMo7G83l~$?I13JBdv5Jl}Gw9P3cj z=IbXAlrO|JL;X)Ges^;}(ada@J|FuZhk55_JP@`SYPD%TOA_?+o0<=j;Y$axaVZrt zWs`qQbpN#Sppo0gr1ffg;A9q?&UL?Mu;nv!x#yaCXU{^Ok>hCZEwFqBJjm+$Mw9}V zc;Y7)L6qY0q;4?x4=#JF7tZ8Nki^xJjce&|&I$uLwelvUlnI_W5h0wOh0LR_c<_1o zw2|FuxK@f6?4PdUb@-p=7+0R&NiONQ&&<rzm-b<*FbBRm(!H#~58@tKjK+)E_`QJ6 z$y(9rb$vY_Pm*>qay>gMW~eJ+h0Ap*%3$fep9SL27C~kv<#LJW%Vw_N6R#(^D<h9l z$=>g!#kLOM(YkWtobiQKqL-#o;`N<WU1n9D(dg}dh;hD<mZr<gFH3+^sjVe`hAF!d zJbGVMDj;{Zv^Jy1$<4G#VtX@6&2Hl0x%Dr~)Zn4s1`g&^E)bpGt9r-RBYR2y?p~EU z@@;+Z>tCr&tU7zZRA%bda18tc{P*Yf_We>Z2@L??PV)akFF1KP8QIyITKp#fXPf8S zX_GCr_p+{!;ym8cm`wK8w)Up8Nn>=~lwFp`!BKYg*`5$7QR5GZbi8YG&d=>D9{>^o z<?!^@^j0=k3?-1e`|bX|&%WT}`&Sp8U6V3o28oo_eDZ<!s&<-azNiw~rS;-U<M@P- z@o;B#+Y=7t{f#E1P6dgU+4$70JN2bZtz$_@SBge#9Fa;2m6Aivkxl9?$de_2K*}Uo z0F*{C9|H4W&6JjZQwn#3QlYABPK8!Vq^jAlX{(~_RFPpiGtH4IZ7M{R|7nJ;NQdj( zxOTKHGbcd)pr~_^>zjDEnMEcc5tBIERwdCN(ZZolS|o4Sc*{MF+DQ#?rp#&I>ZVe~ z5cTWW5CnQlfoBzx+|>s$+Tq;`bJy08nKiLI{+d75A5Ai?iW+u3S<|PF>ol9HCa~pJ zpUTvq#cmrO#!J`#4DqWTt(ns+E*+=|m6wfRnH~3>3`I7L+IiTic?M1AmfR|T>v|<8 zXaSgD856WpJ;2KnHAh7?%Ga-sMZJF(-{lWPKpeEMD|K+d2}r`#n=PBV#v|ReN^NQl zwJ~|Kc>7qFBh}R?Qh?m@dqKe3P^%%TQ)(x~=tJm+>1nI+h!)wP(wv}~k^rJ+cXPYl z-vP;JU4l`>K@o!B31_sHEpvRdr)K!Fb4J4cR>o09*!=eL{N?x*`Au1xxb=&ZG>>OT zX4uEkbjT}+Hv~^GZ2@9i<u(Sqj_UjZ-4QvECG?$&Z0=gz;-)5f3cLo;f4EX5{FON! zJuMr1e!ACD_5M~)el8cZUHpA(gAlV^hKL7DSR%c0w*+a>jN<$kW^lXP1y;E8b$#`u z6Ky=>07oE)+NPm{Hp+~m4a`OM<h5}ug?#SwI%$!v7L_s4VyMs1q!ZuTA2U=3KLrdU zoB$Q}_@R#m9k?hToChA%AwmSbL~E(V$}J+glC?QWu6CdaWQB5de58qnji9nbU5zD} zz;U+`xYrk``7L6lLal)7|67`>6|ja!0QIEcm=;Qa+oW70nr*SB!11SgvQ<tQ1|;k} zutESgz;Cy*v<CXV))w_3#)-|Jr`m>IzOfR8f=#5Bs;RIaTx0I8m16>GdyGddwRS9M z)=LdIRIEvaqTOHY3EH2?7o6Wd&!1C=S*&p_#MFM*MTdrnz$)jMN<03kX1+L_q1|6m zr5@!A;n;-eQ9qz7+@Rv%(lJUKsMC0HseNcJWoICLH9vx<Ho%fH69EHZlJtR47xyHS zq=>*B$F?_R7DPDlZwInETdn~j;O~Xlt_jWKAsuxg@JWDbGN1#{Mx%M)A*SH3Q=QyB zwIZM<Q7zI&@^)fVez%AYWa^o#B-2!O$K(UfG5QKpO?%Z?U!ram76>p&ww`D#Od(g{ z@^NVick?CK310`;I|rh{Yc2jww`S5v|7vwIM$angBf7<U18ND$5ur3A`-i3N3%&0L zc@sg%$67ELxBA(zwG^#Km-8k@HnpzqYHa~BZ4-8f$9zRi?cqH_?>X%iz>l#W{_gse zC?MjCVrGE>XNt!{ppO~o5U-z&2^=5RSU*=9whha0tTjV?Dk>H0j$A{5!4j-LCU6R> z<W8X%#0I>xK$#X(d`{!oJjQlkkt%3Cj)}lQD_OTt?3NOW3Gm+8GveZCxhV4oGP7<y zeW1plTdth}hW&-LrZxOfEx}qQF)be%<>hd*e9A^tcetbDJBc-Z*tcc~RoC1aE}@rF zn8Yu*VoU+7Yw`u9b0YITtSu_w(hji{12gr=zn3%}VyuBvN4TMz8{u%B>7mhDDpq?E zYgQyh(ZzEBuy63@tW4BbO4i5pLvza3%nH;i9~d0cfr&-pu-}s{4!HL6NBY5z>MPJ4 zqN5XI84jiWn?M}^DTv;v-(CU&0Iqi|o>(#$J$q3sA4IT2=tGvw9?|oC$M=g>j2Q%s zgj_ETu<&xZG%<V}gg(3^`13cise?fUJ_C1zqLMRn&3CDO9cTgUS_0C5xgAJ^f~r>Q zC$J!3&Gs3s){T4^0f4yP#zhIl&=Xm9l#LRiD@wYHjs9K9!);SSOD%30s*8^}p|S`R zz5%c**XmqFmm$)`jPc=%HY&%M7u{&#Q&<Pc0>t1OugV4{kORr|RI#z)Bm~yL3nii6 zPa*yF^Rc{$#ON3=)!_dBwstBNDRfQ{`<?<T=GA}6cS<OzVFvTE`kXU?_zApW>yfg9 zyR`c!!lEW!5I%`8e@$iXZu?RHhE!Ai)Vjtd62OpFALROvw*@|?<>M=GZ=oFHo&kc& zG~*FP(Txcf4Og_S8QuT~?C9X&cozh5Ua<sS_WfkQjvs{r%Wd$sKB)oH1|6ElvjT5Y z_5&1I$9558WMedlwuPzzu7C|qT?joRx-(Z$nPYfy8?RQBokX}(>iszzGlxMdr*e5| zcmzWDb<ZrE5m|#sZaolSkKm8EyDWK|9Ufzm=fVwWaOxr7q<<x8JQ3y4Z^s4JTyFH_ zz!|hk^0*WC3a0l~U!+i&oeNE)p#jI>iD{w-oo%*lyAt6DK%#0HxToPt!8K5yb*=lO zLvkUcr=?{iX89D56M*iI4xi&MZGpc8LOn9f0k6Z2EwB{eq(gq^Nk?JRU-~G92$k>E zPv<0N{*#ElZr%(B8}}Ae3qBcgeR^+y1>|~Tf*+N{J~{|Jv=(6@i35&V<9`m-=MG9= z2I8FTtY800vX^UkDm^G|9KJm5hJacXr|+9s4X9-@Qbb!RgE#Mh<-_(GHHe{aC?|f< zt$N8Oem(A8Qaprc>f4Bu4bTT;V$2b1Oe}apv?Lc;E4^J$q8W2>X>^zvIGKtaZzG$4 z@5UV3kNOU0fi?qI3q6;9e%td2w>5Ggc0C4pn2(wcMqM({XTfL{{>`q^DmRz2+pF}a zp13BnT5&UeMBKreMh_>b_)Q2zk;y#`L3Ovnlfmu{XqyD%zJ2-mP(_so&v4~=ZM6@O zgG~cg^EyyaExM&UH#mEDbKNJF<N#=|eSQb)CTWqqP7mZ@G647i!gcy`QSCM_FXtD< zTZr1za!DP-Ik$}fH+v-%0<<YRz{+E+6cmP*fhwNhaR*PpodpxN&x*V-V`JOb-I{}4 zkIU(r7_R0EpP_tF3Z5Ar2c%Z&$rN01|DE#2LAe<LIIuj5TduNT!$tq8)u27S=Z{PJ zS;*?E;wtv<eC5U>*A)F!SVo8!V|I}B+SA@uLR_yB0-7o5JRDo(>#5?fMg&AQ<&ill ze%VTz_Z<t<I|ve2c$x4Vkto$AN-quLzzM556zQcm``z_Niep%et2np`(J!ZH1@onL zkR~8fB6f$OXAef0Tlf=2m(%?Fl|4LmbSD@Ct7#|qi*o=>K6x=`)_hcupuVtY86QuT z8STf})DgYx9C=iZEJQqSJPy6#Pah)=n@POI3@kwCZl^;*kR<<p%aAaU@NFNx!GQLT zZy+68KCd|U4eXj_`DW1eoOO_Yk}^!jqaO*^_mue_Aj7fuDsqXzqOHm5RY*|}EKx+m z{3U@wr<;|p(xkvG@s8nRN!0IgQkCM16IbwktF69LVJ+5q;B~Corv#6L82nUI>)5NJ z5`eK8Ro&HPu{;27A9Fqpq@1aboTbZ6!hVpj;*K=B#1J1Z!N6yQKi*O>lY0B&?RsJY zI2hJ?!krxdi3BqHw1z#77uyL<{IY9AgvA|5(dowN8!s4MFIFh4s))zH@%L9@!jfO> zGK;A_0gWhgZ&@GyR$Cok|BpOeE<>l0#P8$3Zr(jFCC0Fhz{2H^ZIfR``XH-H*o%Qf zbf8*t?}U-V$8=I%b*ry#A|o!gHgpte;ZRb?;ve8>#Ii%bz(?S8b_hOMNI+*lz4$OK z&DExf%@|ou4ijp3l#zYHm0*1zs679{JCNRhT0vki)i`S8PN8&s88(At%K9U*7eZTC z)F?GA7!^cR3iTaB^!V1l)#-7qRh1Q!TvaYkOU7EPC$TxV<*M#`NpJ$~2~05VPK12n zfm^EU1WD>_?NC9n!Z4V?47W05e=D14?P1*Ea_O+#X+RBb(jhXak--LSe((mpsZKlk zWndaJwp<*uC@W8pk`myCkAcYx#byNSr5S%|C#u2n07}Hr(u2>0oNw5Gh_Y;fSu~HW zqzn~8BJ+ic%sMz<3p#eRVE`~fMBM+LZCoWEi>K`du6Y9hp<O+Fb;r9n!gBNW2m6!t zLIs2LPi`q2yg~N~cH2uQgZb|UDPar^K$9ami97zleVJwq#>#$Y$Shc)sP^`{zn+Ap z{c?EW^>(}=<n_Goe;rpfwe=66YXtT^3p!NrkAxC8DU!FbX3pW!^+es9mpwbu+p3w@ zGaMs4J$_;_Nv8h1#^Hn0Qy}4YNw2BA?hYi%b}g&Z0y@_!j(gEI;`zpbJJGIfc$rx2 z#P2<^sKf1ezcF||A1pWZ>PGM6>U#fPU9Ugxf2z%v?do~|UL5NkM7`4Y?PIm_dU5+Q zXFJc+14>{R@~Oxe^M`awBe~*QKO?|(U`biV(LvULC(Kq%SGFHxN-_~P!!x*Z@($N1 z4)9esv8aH8(-pIk;2&f>mPPD;0lse^bhQ`J+H$<e9lx8$i^4&e1me5Y(K)FQ6dt@; z5_q*X&C0322!DZe;5j0TX?rkus^S40<zES1j(iZv&(6XZsi+7y>x;k}T?ySo7%pq$ z<V>%(_#cno9?8L<8DMsib8a6JBlh{lfju!+1A64;5;U|xo)|#Aog=*9_gk~9-F@Sg zGg9yGO17g7E#sG&d7gDsV!?}N3XJ0vimd=k2L1>G<eflf9BXk2fcgJf)1U|ocE*ZS zx$7p9N#s~BRn6^CTPX9bh;kY2OA7xygy600ue?BtYMuN5QFYd@gNa7Ywd-VDDY3X! z%xHGn2AHEHC-%xP8-@kWY7HyJrQpQe(4A~S{;Xeh@A7%UidJMOxZ!r?tR6_5U??{U zkYsjxv*(dq2p{J;8`AM(eoYBd;?IT{$w!3u>c2loUw;P7CaGk+TvdjUWUVgxI_sQv za*U@`0$pvO55ml@6O$uh%IV}sc~J677(yP6_llznTYtP~J0ry7`yHB9Hn$$3XZ))l z0ZT?~h_{u}FYdK=$*_wD<%joZgRnM=O;)*Q*(yjG9Je|&1y%=z!?V1PTU%AK2J>)o zx>iE18C4tS+$79GK~N$$E0Q_i0&;G)<WM@Q`~v!Dj04QztNaW;6GsU~NA0xQ9}wh_ zx3qzB-b7xEDj?q=);at%o%rxi%B*>_e(Xu=Ndwn49+;3TjqEM3`)WK`MrXGyX3$X? z@m{fpl9@1Ot0Oe=Wx7d|hQS1cu0NDWb!?|k`?$mqdlB7%W`;Oz=*3S`JFioj5_3H0 ziKjbJ<j2eXF`DxJd32Wbb}@fo_I(Wbg)gQ@r%ylRJ_jn$lL>J5IG8thha@)eM*W!P z@7?jXj{E8CcxC4m`os5HGAgCkPUm@^G1IHA(J1rzOCa5h|ChP79FSG!b84jcc5fK^ zZRTH71K3#S85LPQsB9B5PjOHr-xJ8rerK36c@WxD7z!k-NAWSjZY_6$V7YoM#wK+x zqFUN%JWpEAe)#kOrto&{_K|7mqw)&dwebVmy{`lsZT7hz4(P0*rU(l&V7EV@^1ftC zF3PEJyzys&8pCa|d%dvH)m2c$WtmXuzRwnXAL~j1qa%jRWnGn!;iv+?$>`EXL<aUd z75pF%9v@8GGtcZ_mbB*2d%QLGMB{4Px++Zh$wo7Se}Q%a0}RY5{COi(EXJs3XiFL> z8H8>3Ndsz8#5U3(p^nCUaN8kD2qo1Q{T5kJqfnkNf-Pv_IRgLse80QI@1VZnholgg zf4U7kfTS0FEYx=~#Ef4ga9QYXO;P03GOZK_TM1x5*bdSpK&O@qM5Q%0Tpn!s2^NU4 z(=~+`^A}K3uX{gS)O?d%$Ll+Fpdl&pWh}{GH8&HVA_L%^%*+Dt7a*BkP-TcJOr|3= zS_}KgXvBdLmK!^W-0*tooTvVy1;|>oR3D3VBd~@1i^?NQf&fZ4vs<kG%T>@Abb}OB zXGumDUNAVS%Z(&mdxLO%ZJYN4Av2%86j64r;soc7qYd<4mv*;SWbTpeZ6gD%G@Aei zn2S;eE_>QDPkAmb&TCJ7u~!fmTk~Kisa)D@MC9#R;HR58?__1^-P-1lmf^};EX8ab z!-O)XQsBp%D9q0aLAb_H9hfbeQFX7}s1zAn^>_;gtYl$r`@on3%WU@Rd(4O{ypvkV zfh`b>>l;u|nKkG4=lf-RfU`ZzxGnMoW88-`yr@uoKhzh2?Xm@&WG=#s(ma$>dFs*J zp?Mjr5m&50Z6`pk>zYYg8dI#;1@{*tb~ZP@P+qY~6uMdfr-400;H|dikr~Cj@2>l& z(3~4)_pVhqxO2iR4pq7xnb)Sc7v>Sag`9SN+C_m^S9ujah2Brndq1Pm{ji`{xPks2 zFvu)4{;v0%@i>dnz-xN;nj2YybQK0K(ZZhNs!a<W)pCpu&$L++VE39M4$_{m>AhVt zj|xiF6Hbf!klGC{Y6C}|0RACF;Eg40X9?JK#2aE<E;7_x26L}?oSnor{`&UdzUh?H z){P7kw;HuJkHwUMEaFZ+mV%$G@){)w2not}H+Gplu~?~%Q_!<)ai^(G@gK7#D~#&r zn~8bEv%uXIllM=Yn(r?Ih}kI4Ww{13l)LFh0Kc7r>i0xFN}y~qfB*HE`PRnD`fe?y z&KA2I-X5ON-sri{7-e#J7{Nc#UknQK8H?#BeN7srNjY3vnj>m8m<=~>cvIOYv6}GH z+Jt=-G7MBJHZdkvU^N9!<-H}&gmG+b^?lD(nw>k?FhnOIoHZLMHVV`|17`G)M$U%& z_%6X~hx#C;VJ7A$W7;QKjbNztCEU!0&`3!tbcxE<@$+_n&L#oSXxkf)EPx@<TuCo? zPf^epY4yYe?*fU1JH%h3&_m7*0PL+$L|-bgt`bf%F=om>Bxt}6Js_*#{9tG6D|KH@ zp5aT~P3d^qoL`f++^TP^_Emb}gvMhkot$J31Ly-FXy*R(bgOD<uxJ=gLYD#U`NY=k zTs~b0Cs?;DVTY4NIt${_m!}x&8=MuMA14`|g^Oj{(&>kGxWzR@Yv}<+9}0(o`0Uvr z>$^{H{|k+EsFQ$&5A02T9#MqnH{4Q9)`1drQ_0>L83B>X{p>wCu)&i#I=Vnxlk;5a zMmM-r5wQNLgo;*afCvT&uPW5gCPb=oyTf`E(Lop;M$%E*LRqutOOYOL@UEq9XiD6K z_m|vVJHX3ysv?;{m0O95?HIm7yRyG9N$&VY0|xo@!ou7EORZ-YG=EN=P_B0zl)!Cp zjja2wn}{zggh;UgIxTo;>=I;a){d$*UKnf;Gx|7nd^u@*NeS2keG&`^%QMA-STU~L z`nr)-Qsovu`P2)HFwQ*a59OS|NH%XT^gd^szsbixx*yO<-lcw|#?GvQ;B71&%I%j? zNoYEhd>5Po;Vw<^BN#&w_bOd4r5Uzl@1g|uh7dTK@wH+0uRdF4at9Q<x+s4{o9NVg zBZfz}0~&qZ6FJJMW=y%j0o!0l<O^niKxb6ZS4OVBI8X|1g1_y=g1O&f0g~i@*rU5; z^I#ttedz`K?<4K>zjoH*|Bz~|^#9jL+u6k3S?@nwwSOb+7EP_V%@I`JT|LH?f&AuF zWo}V?szHcM0>Nk$SH$A$AR8L7BZ<PaOht}jlY)ORVYeA=jxO_Sv>H4ldQPVk?OrF$ z8Pg^)AKM!@lM-87xt4cjw28=*{GmGcA7Z?yuEZ6(;dg}-@CJJR{qCj0rI<=LCbdGw zKy!#f1G~&1>!Gde%ms4|m9!A^BjDDfM%96<|Hs!kHfI8aSv0n7d*Wnb+qP{R6Wg|v ziQd?@ZQHiJQ~P0ScdK@PM0Y>keeXHJw&(XQG*5bm#~v!}z-LZ1va)f_DT|2gs^#dp zQo7-BC5w-Ngb~hbc!O%kh#0i^$+|OU4Ov<D9?Y(!mqXi|n~V(!FH<qSh!x)$WJ#09 z02;#Hspq0`+&;XQ46uXBpkx1ms@C*WXyg$wbxg<9cH%Zz&?YLn{8k-J>FjYi?AUuj zEyF2ACh$b#rmo7<pIr_1`-kCjGJx=8T>-Pmc;woZO!A}vK4&jU0-*_=vxY$(+B0y6 zrgOh_Y$Juq9rALYR%ypo2sBle^fF&W=~4!EMw->unX11f_?9r@W2zhx1pbc{25m9@ zw}I8%VtwVQJ%@PFB{XDp$SZ7P*c3+}O&`wFb}!jzWikCCw7Ea81q*w7xvc7#ZSgXD zCsm!gTWV7-1GA&bR3F+bc{ymwyirXfz_bXAj+iZ$F>td1bRrabDKh84rFE4#4PBbd z#d{OrMZHM5T5Td%aOcwkbpBDLn%Zhc6ECCfXj4(b(^t)Fl}Zkw&g50Ewla&_Mb_;; zyoTVbMP0AwaGGMH=CqV7&b7re3d-jB*29h?W&Z#nML)(+A%*S`9^)<BgO%re|C=uE zd<nN`DN%Rk=iz#~e4Bo=dnINy^8kbIS-RqEm+*Xj5q7?BnW(v5fX0~RE)P2^{<O;k zXAH-i(N;B_u5yyE@MU6~4-=ek@>mZZ4Hi$Go`<Wdn9G>P)3oxO)*jP3HNSDYo*oN^ zDwH}wef8NTP<)TU17M3{mUhU|Nl!HmjwY<B*92a<9lsaWEfRJeC{Y{27Q<blGIU>J z9)U+f1Sc>G<GfsGDl#h7z;^2<v0wFZK|C02dW5oR69YW4POWh5hLDl`N>-sJxLQ*6 zo9xLjo5uP;H?ZiDuYa^d=!%TTEr`l?DeROT!Pc#bleryeD1RVjjfsK|+GQH%Q$pxX z8f7&>px6I-a2AmuV%myaD+bI!GiDhWo&}CSe04uUC3eMm{76pCZP1LP!g#>3n#>6~ z>|BkwJ223~a?JzhX^>bMkPgH|MDigLu43TjL)#?6!KcXxnJ~QKAOz(z1I2rI^b(6H z<OsQRS$v3j?qNm0FL&+mxg~N;rXK<3g~a1`McTf=`lecnLNbG+F9rf{${Z;-GpxwW zx`E;-5`p`zS&UG32jxd!L4(pJ?6HYV63<iX2U)LK2#!FO=+|}2O>Mf>;at-W7EV?@ zNCwqPJ>4`{5kF;QhX$b;9}+>Pk)qC;5q_*pmGI9Ekm2kQET<XziT4vS6~_T37;hH8 zCcXa*e<6Ql8w41$RxPF|@}fYtJhQnyUW*cpG{jF*i=gZ0MztJ#SU6buc9qk7GFjq{ zde9$U@1-V%9kkIDCn?oJj|31Y_n_&J<C}uoYR?by)G?H23b3}D-2#h_Q8oFA{ko^P z;5Z_uDtA%ri>-2v-qlg2GN&IlL_@0ufNrpt+@)a6VlkUCK{1Q@A%dt}ffL>44jwyj zO5-curL+|boRR~KVQ+p(?YdqyhRB$vF!&8N(<w4r97jU8>7>Kg=S<kk$6F{!jpINz zrHJ^<Yacocd1bJAn&IbXo!XbtxQFjK)p4YL2$S-mgk=|Y;4o1b+X&ukl2g2p6N1|m zQV~`om0^Q3qXr7<{+9Fe0NoD5dy)G5rNwwrT5dzCN1K!eefFJoO6T#-<EckEv+$HN z0MGVlWOO_2X|U{>>;2-5CcU{+L~MC|bE2lot#0j8{<tpkuAo4BX@J<Osm{$Yldr|R zNN-}?AT5<HVNNh!C8}jNHPSWJ|3=wYSEI3<02LV@<)M()P_F2(_>qbm)krI-n!0k7 z3Nup$?C+W)naQFPVzhu#eA0S}VaU5l6E4g*<SS#sY4a5%r~fD{Ly|l1<ht!W<5fH# zNB;Db2U3gjy+RND+?ZZwvs~18YIUJ4@&^^Hh@%LGt_&h2wsZzKPq<3aaq$Wtg?SaG zvI=SsU*QRa6x@+S;E3{V$*a~5o@MQ=um-Da-u|wFjkHSuO2FaD2Yn*d@QVBMXP~e} zkeK`rdIU8BZ<k5{ien(iem>DVDVLPU4~!+Xy^i91y88(ie?^pYmS(x(T)l+R^j#8f z)0zxVF+VDDXN8<MIZLmo&uxWVhOy}V`RPlI5tIzWJ?t>ULvwY3nAmSxFFC8!<>rx9 z8Sv1%nVaqJSF$E?v5w}e*t+c7Af5S^SH6xglAuHh$$(3k^#-ZY{8}r^N>ZwR;bCV> zOmf73F6}Q$XCWBtKVLP<eD70CF5w7#k86r5GqivIycB@yt9cN5e4M^x!1C1A(^!Zm z41Q-CAl`#coo9B)4Tr@apSf3oyS-WnPb9g+dm-+2TbwUWD(1EtpGD=Xe=dG`&+TwO z2FmeP>z9ZIWed;Xuh`WnBOFwhzX)(Go<0rzJ~AgKXyimaBwb0vU!3740L?H-uRpcy zo4^#!O3p1j2W$^BKsvo(%nmmZV!FJq{_>fjdE|3${2+grq~@AKCL7{DvDwpXdnn2; zzkT6}e#KGHnLw3od#Avd8ML7`i+cQvQcO*Pa&)$dp8J{yzQ}e}t`r4~_G~$$1H@0K zCLa|;gmoY*V}6H4B^!?%0A}A!0ap+FEo0F!i72nFEcx4g0+stu3Ot_1Pmoe|nDw^U zCy#UF^(1x#ZKAS=%xj3S2Z~O=^9hvk1{zTqiWSE_a<nh;Y*0<dGaxJQm2;1=a<kRK z$h^IXkSb0Nvkf`|Z`n#5KjnbV@@p<jILJ#Ls9qoT2F*|B%kp?c{gLS6SZ%RW4CzwU z8MRKfcX|QnnuI17a&da96>%ASRWykl)i@A+oL*S7EZNB&(i@O>DsMIM9I?s^|5Ep4 zv@&gR;T#ic%J*RP7MP?k*tOCysBQ$|WFYA&nYD8$_UGs1gh9#vEu<b#UM@RM+|FAp z#<Di7reMT~dm+-ny08v$EJkaXnQS*mBp?RkUD;AgI{}a|W=5~>hO-+W$R9+{6(;SS ztFZAp9Mf5L2`4)&@(&m+AL-gR&41;Wd^Xyi*}(bA9+A_<tiu8#_U%jK0pvB5-~l1s zU{iUGVwZl?u_jY<qAHG4>;`<Eh@zPHnA)b>>Xv5VpQEocak&mhMS7N+=8GfH*lKwV zFKodKW}Sg2#Ip_aa3IJa(=&@0)?+^=!Kwhy1|Nj4dG7<{K&)mlv1`kd%vjo(H_Nm2 zL7B-?)KKzkq>~@{3|*fLN<&DgW`DW>KwBUz`LoE@Wjr7o&ak{>E+DEm4=!uyVdLBs zsa@JeTeVYdF59!abv_ifohhUm$8ZbSv%%G$%`Uc(FJK$3&jQ1x#_$UndY{~Ehe@Rj z&vuHt52yiJ)g&50wD;>A=LPjC^*1ctPema-C?TWM5B*4gHi(wr74{xZwj0uq@iahk zCFjUq)WtfdN(F_SLWP!9-3CK%L=4e(r=W3pIO%YzKH*+>td-*66CBl#1sZZvZJqaf z_B{^EoTa77&K%&}G^$oZRcZIk)<3=>Txk1yBQtKch8y56;-tBPISSmityJMF=2+)) z&nPfkHmR>5U>q!sDx!6@jCA8n;7jBS@BTe@Jn1fPxBkx)6%1(hy%m(}NWtAm@5P$( z<}0^gA^rvPkcC{3RG^5Hl`_dXvKRF)Lx^1CO|Hi9#|ZX?<yGCGVvemO&dli#O?=d1 zXrp8jLpz8BJeC;ocOe(oM6#^Xi(_*>;86z0Fa*qpQW$WntV+4!ye_BZA&#iFKLmMq zh|Y8MWrIh0eVC`w<sw{B3FrchENoYen_8ncxP_qDep)nt#`xz$q|u`;N>2X6b<YYm zan1KuX1h3wM;utEZH@|fUkgDPrYk<k4m`vj)q6UH%zsX~Tg%;)>6gcw*gt9@WDSik z+@nooT_abY27$MZYw(-9uMFsm^1K>XSHQf!DRs(W3~bx`>BaG;URl$$va!<zzry9- zxE`Nmy<)EMOi;Xdi5zv!u-`@?QoRZ|T#m=qt?Ydun3XGWch|@;_-)E+w8nP`9V6)8 zZ`I=_3K(M6^XfOXb`;P~Nw2x;J1k)OZ4E1f->UNIaBGGK0cc3KdwSY;*+R=Y-oi1T zKFecpgw0k*UtNyqbdZ0O6s%4%^+uT=SQO{U2hrzDVVcaXr2rKZ>aHcX;}cHB{4&R^ zS0ilcIYf|{D}}+x0mXwl!e)e26;Q;eyLR(F+eq7++H9GoB!lTEMQo-}e%Vd@)%30M z&US3VzNefuH_D*6|A<8L`D#I5Xs#E<qwv7J2QEsD-Qr`^e41(|NzIcWa(V(=r4sHa z0zT%QMzdg3;#S_Nu2T`~^|Z;t<ilp}*<@V-&y4BwAn5K(#zDeh$+d~8MfH5~dMC>n z+VhQM#=5HMw9(-)2y}Mt9&E4>mluJ#K>zKUY$^7;Z_@*R`i=4SQQ<Wm=PMUXqpeE^ z0<^~ey~;Kz_MFRFxP|O|{F1=A$g%4py&m2)IY@pMh{}F}(NAUy1D4Eu)sgQr59jX3 z{9iv8-qBL!fnYKN=Cx6@Xa<R{-t0wj+h1aIPsh;__43*IYz(ofVn>WF`l8Q^Fz&WU zqekb-Mro1obw2$1K!ifEu;@Oeaxq|Bfc?ytgD9{<!^E+LM>vr9D&6d^ssd~`CzJ0I zPZg}?Q+NDKB}-XX&LouaIm_JQvZHYL$!p8?MI$^Nr6=CHde~fDvMbL*<c$3^%X7hO z)scT%{-)EOZBJnI?Ma+(r?R`Cm*nabQhet=%}N?A<0F-i=fH`~S%2ewOyU)7uxkU1 z6^G1!PKG!Kc|8I*Wlv+4IO#(!(rUtmOM?AC{EW|-K*rD8`M^c%@cHSQw0eq3N#?Cz zWZw!sVborH&=%{nLpq==&jjSK<odIl-`f6)I661U9s>>$d1PSr5v6_sS(m88u)i8S z3&2nO*OJ7i@C~)naZgj?J;U}d$yo=EG_qU>zU@Epo|{Y3NvVPl`X}!HyoRe95<xBg z)1%z+{C_$uS366O|IRKN;{LC68TCS9CG~ilZH@D`<BJldEXzqr4oAjB^o8QTbQzK| zSQ?S7rTevC&kF$%%4h9`i~9*{QaZ^k0m1eQXzuZYCxz?QBJ+x*@~Choz=zsdamox6 zP}WAvTHzk(<6jpA%RM}wZH><|?b1+UUcy$1TkYOy#;s@4Hp>#6yE39w!jp%Z8&VzD zW>7m%a7^o@3FX$e*>BD=+->BYt0vVTV`IQ-{8GPNH#8A=GxYR^KZEOdAa5P{J&4GW zKru=(l_kSS=aF))LGdeL8IUN%q8q7VX9D{O0Rc^sb`dErH|C7>aEzB1_%grO#NC)Z zw)#FA$O^AfMpJU6cib77&Jo^N{)TgmeVbffp9&D@W(*T<ATw<;il|>iYmr&$OtqBG z=z*yL8L`7im9lP|j)U-1xC0Rg92IUnKnIc|mQrqJ9O$#*%bPKC(gy&{q&g^lYzTkN zb#ET+?{<%BsWd6I<xa7stTzO^=9km3Ia%+R7wQz4wciPC2I*zismX5{RQND$L>j58 z6;`UyH0ohLTRsr59qDPv6arL=@iWt=ar6T4^!5}cY0W;al&UxWonQoXC92iU2#7rG zE%`-KHSv12Fx;1A`nHD!)aDK5mj@$pmtS%i+EXy#sF?s1(VUh`{vb{&VlrQbpJ7MX z37N{QtNUDaaG-kG>6Z7IOTAk8m}<=;!H`~*p`0?1Rf9fX&Sh>@uuKJ}XVf0>3Sd#; zrqQFEB@Ru>=q|yAw9Gr1&n93zzW{aIzqDeX-fde;7!$FeL}esjM>bn%28g=|+15b1 zK3~s4l(`iv_U-l<W2(v?Eb+PQ{y=o)W*O}a(bDB;;zGa&x#r-bY;`gLbQm&r@r`h7 z8VwslTcAvQ=2#Iyn7jz{;iMq>u)vYkO9UEyaW<f#<(XO&GX9~x1neA}<*9&Fxp?VD zyji)R2(kb?$aJxWp}+{+!0Y=m&*rd~K>>}TGDnzo^4s)c1FT&~_*PL@N=^_dJc<JY zs`_+bOFU5>cn3?x1&DKeTOH0sxPsT%!*+E|&_wYQ{V`YJP6hBX-0CoT+*?*tC4!ut zT8mlDkt(f#!p_<J3;z`5Y@n2e<q(Jd+fGvP0-}(j(J~I^VvG+gaf9DTvsy%K4_?4> z0{-q{o@ODW@eaSDV>h`~yh<~9Sgd*u$ZgPgoVRS)pz0t6fs7rL<&kno3GYffL4Haj zP1v#o{SANV9@pzd?9<D<Xqxaaw+nuLfJ%VLe4SLJ&owUZ&7T7Ufy3Dna^eS8-|u4~ z6HN>5(*Q62BFVr`#Dmcwr1X8+a_56y0Y)^!sJ!c8ZDktmzsO3Ljg8Jvi>Xev)}&2f zO@G_}lz%nP@*1U}oP*hB9SKm{4mja5FMWh>E^`6lvrnsR!@x>NuwE%;N9N`?cNXAa z$9pu)Yq7s}Kg|q$0J?$#wj7s*oDaz1XoX2`W^S07d~5~f?Kq1{m>3Ag((im59nW4d z;Pj4x0VT*3nTNo0N+kPhQ;c3nERdsC5B5@)lEU9c%j{n&fmZ%@fbx5mtSm-pBDEem zAok=lmxmD5c(&jT4;ss^QcCZx3*m}A9n(F*kv8*%lr0d{#sguv8$)|iMSHGMv(nWk zXwrP=u!&Z%ON9P;SK9?GsAAID)&4%aCqk+qY^y>FOAV<24GCgxu06pMqI*i}F{W;3 zB2AsY+vDY&9F)%7JzhphsI=Eq4N2xPSZoli8x-c65o}#{7fP&ylpNe!uavuEmV3Y= zyG3lI&Nf(bfOk=(sf@{^YK}NCFjau2PyX~TY4?)LNUIF=xD-@;c=|dJhsBov3?U*@ zIdt+T3xd4~xP0ncH{IhCND7Ka^(qd^YA`ErG{m?UelJ)(e7f_)S~^<1vJXWy>k+k$ z5l%7tdiNLJrJM7B?)D=svF=g)Z8pm*|0TA}jNKIN?Ldx?Zr<DkE~_pfk_m7@$B77U z{<Mc|-O4YBfoJOT6sjedNIqZ_Fb#DGvC)~?a6@uNVi~>B)%JE|)DrKIYfPcXjHMxv z$L79u7-baOI{&(rP6=Q|+j~rf+1|M8Ln=Bw4-D7L#%>S!wV)w1pk-Bcmk`BX4la;M zpxEVHR`OPBsYsNAu-+&~2a?Qycc>^Bc5v3kCuC`O#j(d33gfo4f0i?=sg>l}9naTz z(DdYW)`dbCCVd;$W10G11(SMJi4`Rml2FIwlD5o<yWhJOTM0wP%)V4K)`}LB)`h`h z?eNy|vpXB<>nD5I-W5b!7h>A6xpfzwnbY<Z!$f#IT-gK&$_Hv&T)XL0w&k3^5!o0+ zz@r>J&7lv`i6twx(X?;gy+3v`CN%tWBBH)m%zp&km}fj(8DJSS?^@ljZu?X;=Ko~u zaM=36f`dZA9)#X`bBZby5sH<h<5s{a!@E*8$kk)n(qVXS&f~zG?rz+mj>e-wz*@sK z1!wCBcSDdIoxWRVuyMNMEb;eRUX7SdmxTxHv89aWGXkg5y@-joi7G)?s|wb^>2h2B ztpjBa!fHgE_~=cp4H5VqxC+T7-;A)(*U05%@VWz6<dRa&g-<R=@fUau{L6lk7<h@v zZzA#g`ec|6@KlO`mwyt$>^qMa(TeYRuo?T}b{S(GMZ~?o>XE&jMIEMMY6QMCyx8fL z6GO#x3^%ZSe$`>u_q>GH?NiV*n>4`-#Zf%>ck0ZMd;S=B>DJ5+END#Y1f?HCEb7m~ zTC$pKikB}4p5of#uf^wwZb+sR*PyiLXuA|aHAXCucAD5Q&dzl{#uERgufDPkT(X;9 zLp*U`&^hSb*2+qj!hm=nI#b8E^fFRM?XvR#P5(CSl3x~5Jm&p<X9s1sci_OArR(k! zmxIJNqZ_Y0gvk;R%0eX5L_Hb?DEqQK5r24iW95z7`M5>RSF$()`o@nGjoy{TJLL0| zM=Zs93N^W}d64nPT{<}*C}?NT0)vt~5R%5wvW=H<+3<QDojqU?VB+M@;UK(Fr_K*M z9NBV&j2z7q?f>ey0O2#qxrD+wCmw3VdMI4o{@!cQz8ov2#BeE7#vO{2Ts4!Qhaj=^ zi+a*IJ?C2GPjUTTCuq1h=Lir^`|O6Q`sZe&QdX41FWSGG()-6Kc7|?C@$1Iv&n|o5 zomLWd;y67uhQnZ@!Cs7{t|CBGp?7=U;{;*gHarPBP#4PeV9}a1utF?9HP*Sq<i2yz zMLk;vTFJ8`5d4upHimgtGG291wAdX_z^et`q9KwI%(3VRip4^lIGud^WNpsu8TYI! zE-1LcF9bv5rL-B2LCj6Ru*@$_Pv+I6Z3eU735%QMi@+QpO$Zw4RtbxNa%?T)HxUEF z=KV|Yc*?A%5(i9n9##yQYtj65eg(`QZ$5tpghoqI1(J5VB4(6ffTC1sdP@tc++I=g z`WESvgVzf^bU6itoV&1{Xk4_g%liXH6V_J5Io+S+4`z=LtI+j&as<k1J4_s<b=Ve+ z1to`+B;r)xQty%+0H-s|(W{ugi7io*q^dKgYp_~$3o)Bv%-##IyX(X_-G;jz&Ah*X zaO)stF00;*cud_s2{i5lqjKgsdos-N#Zvmf@y|;@^pF^Jt3f4+6}!zdf4es3@$blD zUfwYZUhhUssjwAt!<$yb@Sqy(o~5-J7p=nZz(k%Jp_pw$Wln)i6uiJ-E?Dq5ge71; zn-jROUk`XzbG!d?r17rADT{nIdKyJ@>}7dN;k#a;Aw=L(e~BwDdM&8`qZ;MIiG{^A zrwH+Z=&cxb8lZyp3j)OM4fjO@N8X7EC+djW;7es~WRG%U8^0>%qbH8@8VdVJR;j~@ z{SphcL1D#X){7QA1xOK17JTW2(ay$-z-1PA<3N*QTV<||X4_UZd49_KU*$Ndgl3rY z%k>}KNHkeq3WGPXly1KI2~t>dn`X$RGN7jFPj5iXIHZ%YaEoLr%d?6bowguQwJjrv z&tD+yqI7zp_jC$aWW=Q#bkf(igF9blF&<-el93MEYq{~e#xOYvqWUF)G3*P3_Ep}& zDrmgxO2iq&u4d$D%WKA%5EpWz8`?_67~^Rct$tyS)*}fqBs-cp_iJt+9+Oi!fS%7E z*So#1s2c|Tm^FJh-)W(&siqI`wSUb1y+(e?iqrQ?Gd3Y;|6JkUBlwh*&h185ly7Hy zjQA3wj+orv=&iqRrWZR28W8z)2)H=5`}U@EqU>;7j&{885sFO3llj9-4)$0R?Raol z5c!{TFFpfs+XE4o(@XxQ&~E$Y5Lws4;n>^_(z8+g1t(0lJodS~bTfk0+cr(ec4_cd z`o1KaAlGO<I?>NC<Q>R<p)6M(&GsZ#DcTU;A5!MWP;}quf9ULT>;vP#5?c?q%_JEz z=Sgy+oRI^Q^pyGhtcmHw*oLs0<lqup&HDSc?}QN8%hp<5o95Lds|@lm@#x|@Lfz;1 zf&;D9;5k^};On>-vib~g+E2~QoW4ZQ?!(=ydJ5+vGM4+7;lQ-$`x9k1;Jv2Em*B%Q z47#xPL@IAzygd}11*<^y8mr-H(J9}KQe6++(qcN({r#Tx!}H}%I8<Fd(Qq`6haxyv zk1k1kPCi(Hmi&i03eHXIS_(0^t|y;ohDFgi!*9&g&F<E>tx83?diR4}-_QG<yk_t0 zjhfGUHqC@Lb1rAWjI>O#)H*7^z6RHUm!;`mA)Rfss0z31TLOgbMW1J4vZ0No<Qo%F zw5B2vhwe%@(i%p}F<1!Gd=2^U_7lIC1<?b@w5|K-#R?{7Yx#;j|0)D&t>mf===4XJ zRQOGe-Y~6XV))go0lzh^u5)4YptJ&+=iT%*ez$6?NDJlx;JWVcXkAzsbGk|^gO9XR za`^ifj+4opDd$t2;egtH!K<f#;5w)du^mp8ORTJ+LT`&uzZ%_-PEvcXLPGgUK8i}9 z@(QjE@jyuc@AJ_->kkYHgQB;Eh<5Y_x0If-TqUDV{BiUm4ZG>y?tFCI9G~;e8P{rM zGidR3^T(ky=jSYZ&C2ZM@3=zT0=db7@e-&-b3+g^p8X?n{`_b&Wl!b+^2-s7d=EG& z?C>5nj!e|L8zM?yUz`SeJBt0dhvJ{4kti5m-OFqMe+&t7PA*kRR$_B3hOvOcL~pDU zwM`99!{TY!N(UZ2>3xDs_iyGkfAA_-wmh!fXKH>wka2ssaosixgaxP?an=PCO0R8I zVYYD*ijeF94Ibd5=2gOuyBplv4n$!KYgeWZc(o7soTw|>!Q-?^t$0Yu=|JzfAuhNb z#dxpJW{;Pwi)5yJjy|oweM+_NJ)Isu2eVuR;mNy)^!n4XEnAAGz?gXns9<5C)xudg zARv+AI~ex9YaNL8j#GODIIH!$*lZH<ML0=pC|^ReQ+I_(FHx1p+V~9HG3bWr5>E=9 zxJStJFfSyGo!R3;_ig2-@Q;2O0}e@=uAULX8q}&`Ukcal_P55BkRSHHpDNoeM($#9 zv&{p(I@K9|Hdr0OV4;nKk_AWdVRH|_eQXiP9O>m4Aq&wOHgBL3<&bx1GN-LCn}v@3 z1}_YrZ721TS7#tJWOyW|;@Gj46X9p-aNT(M8kpdnJ*2Oi!UX`*z$IP#G_!9flR94R zrM|u);jNY4>~?;ZA0}{`Rrkg_ercUo@j@Tm$hh$|dIH~e+B>q`z<2CNScJ7<6k)ro z_*Ma${S$Pmbjg+m)g2gEpmo8OQwYGo_bbT(F8g-eCU^)F7mXWoLLh~&FgDu)kxKxG zt=%=+k|C#GB4cF@S?iv*xnW}#D^G?U579y(9P_L)>QHT#XU+Iey17eR^BZau*T3Q9 z^UuhPaB7&`i+w#-oMN;wA-fqqR)VFIar80@xo9PaZfV>idZ7C4#*U;NDV<b>&flUY zpwmEm-cfNzN0tk`iOPzkSw25mJ->P8)~=9nI${l_U*%2e#o%qtH{bfKIJ4K(m3B;& z7gByCY>{<79p3hzRFOQ*Vy9wHi0TKa<TPBHKP$dzKA+CXV2q+RDkK7Q+Z;(edgu71 zaa>HmC{m!kk`z=e@8&ifdTBxtnEHe(w2JD(`tBnKJK%<wI7hkhWW_Nckcmf7$H(q; zih05`eUi7>?Jt&ho)MU2PiRyL_8!8m{$8Azvm<+P$El(fdw=_wc<3gWPXF0}mE1Y_ zFzP`e+OsiyH|~m;jtywH!bM`@XpkGA3K;?_>vfneGn)l*c3QBlMJ~yz@Dp2}u-H)3 zsGY6p1?ypUx4_g}&ZVvah1iguWjqU`ttBuycnE=3aK=sOqVl&b(mUF)ABm<YCGYAD ztt$G{Gd<g;V%`N6E#M7~$Caw~(kH=&QYb;*--`=f7-rC`Vs$y;LRriNI|!WU1RuJe z%G+?m$Wgd4`M!E-3QR@V45;yJ+LV?}K#Om>(Sk#~^sM9&vjypv3!*9qbIlCxtLZ`c z7pL-ocVPrF`;@+2e4??LT_7n6De`+CmpAr;1qq@1@=<^~1Pu(9k2usHSN;C!SF~5% zG2Si58n)(j+e)&9JPbjCx=EbA>*-GWdo6z%0#O1%CR!6U<B4p1X*==y*BE?4H1m10 zx$@Cw{Z+)?%iD-~Q*?#}SE1#IY46K%Q|RMk3XHj?QqsD=phMCt@jb>WGMXNUiQmp% zF*<RWuBnTj;e!;?Duvn8QR)hC+Pu<V2$op;06ehF2!S5Y6vFz8f^6>ce>YCKMowqc z{vpj9#DIYC|4&?itBa-0zhq91&PUP)TjKXWlzDIiy;7{m%xaqobKBZh<rU9)B8RDW z(q)XfDjKw9t1vPQVJdpw&&x+UE|FklE{CEj&mSQ8{5*a3UNFJ<Bi98sPsNePo3XJM z&z$o@2`Srkt+|Fy&N5f+5?Q-(EjkPuYQ!m7Jv$ZWBvu-hcKQLast2(nQ)4-q@)XSj z^6%X|sVz#HyX*XB3Ts&15lTU%?CishobuVQAG9|q3WL1NbzRkU-6h!&#f}cQrV1Ir zMYXBVErYUh^+WY<hTil-K2A+_vkD_!)e^wf>3PIKf1K!irEHUrRL#lPgC8Ew*Q$-X zXTe)aapKul;x;!|@wW9#^)~s(eAh1ShmmG_jCbrrQc{vk&5{`V1g<jsL{5$nYX^to zD{{l>jq_HcYB|aT<eqQtS^d~bTXn{srM9X^K3<H*SHrSL(uz!fgyL_pgk8assf(=Y zx5Di+v_+*Rs|OO{EU6${^aT0wXiJ$E+jPB@8ZEV?)+|o_Y(QGN5dR;&W7%A^A;B|t zZsm*0qDV(8aJNHpg5%<MWI!lF-2Mz5@t0PbRUSM0I2v~H1e-@yMdp*UU(idAQU&km z68C8>vn{GN4u5)Af07KQR}$+W7ifvuY@eRvv4&bvGqeiM&k{|@Z4!lk9q(X$<saEA zWA0~Wh83}|mPmrBC37{m=9KaS<~1u<&+`6y=nwa2A1v}EH;nl}-atpgeAzjh)okCC zGNIO)32-kyFDyBw&&MQw`G*Dh{vGYZlN((Vpn_w2ka=v^q(#XEm4xyW8k=%a4xFvU zN0(}ekCSxqf+U<4w?WR}`2H<_M)*Fo!ZnXBp@Z}Nx!-Yl29F2ik#AQBaeSzjT%;lw z)8}&ABUn9(hb5a+bJJcFTefL(8Ai<4+ts{Lgt#BN<M;OyC;I$8ZGYZu-VWULyTQ1( z5sq=X-!2z!1Hqv}(&M%Tb1~IgH{jTdUgAAoa?#IUyTk+R-!X35D=5lqX%dp@^-s`Q z5fBS+OEKem{OSimQW<)DBYNU`puMrR+~8M6zJj-9GOWh=-#c@?Vz5ZZFLIgW8~*l_ z(CVj=6+M|j<Fh<vksn5k{Rj}l`I3a}TRvB)O<S#Cfa9V5QX(|&{<*(v!0e&*^Lqar zYMJrX_<lTcMuNUtpp^Ifyk6_+_In3a8-|6edQGENDbczo%3uecx$z5e9pF#MQ!AlG zsPi&XvBa6Iq%y+9VhhnE9~xA;)+;CtdCqaj%A~anX)a~Yt0C6T!-snKH;spY_*tSK z+MIT|j^F0AuL}xbDQhgLL4*6R!dg7}lWe+T?$&ywf(55jfH6%*{$b)MFn&s3dk)|M z3V~)LB0>Jz?$xODx#Z|a(G@n_pY1$ydgCfDH1;uoM-bl84IG{omW3Iw>a}_se7}w_ zq~wGppa_AS5LlgDz-?NgDQ^Vxljsd?OEUp8TCHXXm02&`8$DZ?<SkvH2FJ5avj4r{ z73ZdqZidCAZVMf*@e4FjH5YihYza6(MAN+<ywgz1z$Ld5rmVlkdbc{ez|3}?W(mzX zU#upnFeJ_n3OSr)DK(DkB0s{k%;5vnCV<<JzIkMHMpmLbs<2s^;ZgZXS?LfPDZFQW z8ig&Go9F2w=pPfBtcI9!_hOawrLl5D3YL*f3^WJhSOCxYzM)lTHYa3e5aXVD&@B$D zEcyJC)>mXeu~gEt?%v_oXGpIr`Y#A?0`jQ^K)@4@&iuL!$t<-tX*m6F^t~zK<$I_) z0bo+RdlRs?tt8ByKX0FBs1^OUXn?Awm0voI#lp#Jzy-hM1A3=yJ78@IovN(t0orA{ z<=<Xou#rB-F%YTi7n8e81^C06(!a{f>^Vs5)lbZwpHAQ1xion*fK6k#qx~12Yd4p1 zE%qF|9$|k_0C7tq2JadnR#_|B^|HYa2eIV6jt(^lSU>lo%k|uD1Ui09OST(A>V2;T z%)#fmPOzEYe{lC(_H<JYiCA(HMC%VpPYuGbf*5|0IVO<KJ$B#KQQx64BDL8xls(Z4 zCI{B9GKxsjZKJ0nt;w(1spt1a&O~Y*{YF8=48J^8KSfVru_L!*I=(AnL@-}*6Dx=7 z46ff1c|_dnCe6cdXD<*DhX}Jd_~@k4u$QzQ6Oq<{|Ln)nq)FX5tukoj2~A6;4M!o4 z|ASP&f2HMHFEy|2;lu%TUvTL`BsIp=k)2507JQpen+3P_fv9D^yCPKzZ3zS~pHzvD zS5_CF16ZKh`EBwbLqq*M20W(OF)#?m_1Q4F<9`tbqNl9{NeeNlZ#hEK*nnKh$mmBg zSR*z4OC9HP8EtqJp3HKgKFWd<a#@=_FPA_4(^-k#QJp`*&ybgtBBexUHX0+DSo$GT zxk8VC{=Bz?1S4}CBCHa_4}wgY>`68cu7MG2FUSW@jL_qC8xTu+qm^XuHsjk;*U`h( z!B;X9y2QW?Q`Q7?vqXFsH4I#uq-q=4JO?b(vM@$^AN9a5O4y0KoPXc|R8F_s9Lnz; zmovpvI|j1pT7WJSPBs?vG55w+{fJSQTxB!a^B(RQ51Ne2<-`0(qUzu$y)*jSS$v#K z4ssdLPDU@9zIkeD3U{e{^JY}dH<%uRSS=s!Q0cylC{RTranRH_hsH^<@sbV8h1UF3 zV;h@4`frsPFh1EaZ|Q(24x0aM_{dhe%pSMS7o79V+Dshs9%#Q?#lRLtHoU+9o4T6X z99EcwxMuF+jX&e@eBSSy@yy8JU5QzIkp$#+rPl}1FC0Y*a!^sl?`|gE<9KmCCyeZ8 zYkW&YtO-SF{b0kWpJ1-2DZ4tVmk^kuPegD{gOM}qs+s#@;?Im{rZsG;*NC~2EOXbv zXO0Fl_t;-o(>SUd=t3H>tGn6<0PXUqmt0+h)BLf<{Gf-Ec>38!S2-xOB991>4HrFq zbhA{fOACBGWxaHCrn10Kh}LNcyXOu@w5K_5wnTRF7otOMbsaQ>eH|s$$ez6Rk?Zq> zJ<>)~;b!KpmX_jKl!d|drgenB6PzrUiDFyGNqaqBdy!uXgoL(sH6}XYdl$t6K(TYZ zIZB!VkJ1@VQ)npvUTedT^zcbiS=$yJycVYj>ZAqK%{yq2*V|pmk?wyJPw|`Jj!QGh zp1A_b5sHNV9(Hv2u+auS<<tb9|1RI-D~dL6v45Zyg4J1AvT=LT@3J~)FBcn)>oy&4 zF8Stv?^P!y<x{Q5(ag^CxqmCgq(5?~Bqe?<z6NYK&)P#JOR5keZ;-pfTY!z`v5rN; zMq;nXNsNfQg>;TMvXF6ZkFn+9ZoaNl#EL(4wd*dyql2A8osas5+=#h;5xNdh953p= zAIbib3Qi{$V2!4ea8wgqL(QhWC+Zg+O^lEM0h5N3ssezm<wORy5Pj08!+R(7Tn{H~ zXOAe~Lg1UoAkc<<4GKpAw}t2R!T}}ES{Y348g2(S9pvw5n=#tJ<K?Kw6LZ7o@Jg)1 zuXXQsCUl)7V@q-B`4bj0393rMGN5HmjD7?o?7i*A3V13JK$wDMIJP)NU4EW9Lyu&A zGG@mNADJhb3h{=UD()=#;kIxCfJ73|l8Mj5S6CX_f|4^dY17sCb2un@V7$3G>yN6{ z2Hz>iSnqQ*7LD6v-4dd0qp*$sPSaA4^#Zx~w!6ls)s#EURa7o9sjuP1@NAC+7XMXv zz|}=V%>N2mTD1fvN+10Ca}~R!PXBfOVzNn8SiHqUGVN+E{;3&ezter>epkYLMbDMj z<^4kMg8r!s+^6cFe?<f6SNDskP8_n=r~h{MyrQ4R$kX4+3vuQ~2wpLiyZ)XlzGp0b zs=j>&D>&aCYNuq<g=2Z!4HxIL9t1VP=}piTV60r@uVa|KH^(mY<EP45Fww=XW6nWI z!l(DlVhxO(gwCseU{3?)Z&wI7IxT-6x4qa(BuH3R5{g(dQAXh^rjwLB*cF@?QYMb+ zs-McteI97&Ud#6x2ZuIDB0K1;+q1MpXkr1Fn$o>>#4u$DU29U}+O`nu0tO${2|KC- z&vmc8{IiZg`f93x8TL5kQqlPRZz{Yr=dKs(kKLas9_%`u-V>kM?p%s?I4%#Y7WmrQ z#BHyUlM=ry3@i+3yk}+yEBtyuSpT4JRxCaF0BR&$!hr{Hb#DwbNjCdzd|(8zzOMGq zcYxAYeqPR1c{=37W4%po&X6HCNl(4N_G}bX>UbV#zrfXT+m-k_4H8Q<(9IEt&EEfR z`kS|Csp=q*Eg33(*|AunP|hJy%on2M7>Hu3JdI|5W4^JqFh#G#8Nd>%VZo)$UI*44 z33!g>a9~y~m{4vd`ewI*HQ`u*#+e$%4#^yWSHp}&FfSx_I4MJH@eyZrR7&b8=Z5=l zY7Ej?FMQR)a%X9bUu`+ZE@1hzIB&>7=_I?;aRu%Vws8yX)>P3em#Gvat=Mfy#5d{M zt;`?{Ei@2UW|34Kd8`t%zr$x&b5KZfMVP$<2~0m#;7#*Wvy}uk*=wFwipD6TslrB? zW^-;8if?O3A$+b)Hsw7Vxt_KK)~4D#C^cv0bHcAwT9(KvTbw95(VvlnrQSQ$6+U(t z9Ts5QDcHuCsUBrzh0fb8*xBuKxY_wyl!<>xg6bQz;9BfZnJsI@6J`D>uLffS?LRoa z9ISBn5Hyj_9U){r1`>Nk!S8~@Y<Dkj2Ex;19c6qQB5y3J@pp3!KT5qUgF;?X$9#3> zt(>f;$=S?(Jv{$qHS{!9hlx}4(cFk5q0OU~)VX}PCeHh;B^Q_v?~)!B5P>3NZ`=JI z1Z!};kjzkh(2p7T0pB_kP5Z7YXLeMIrXHVb;N<PEV#|)9p7}Uj{Tg-GUuM@aPkof! z@z-iNgM`k+XuFdrQlAz7lUE&c1+}4t;p=zw1b)zOa6<>d20&Evdc+kz2B<QjS?M^y z5L4d^A8d@6f8-KY$ezkAkC0X6Sx`7eU6LQTW@aPNjmTCtalvOzvD?sAagGLgq^#fD zlA~z+uZ)))^YO;>>SUPl+mk$rHL1ZNn{KU2uw4YUpZAZ#oRqyuip?lvB6FtFF>E7h zac>9}xOJ~kj(a<EImI$({@y@<<ibXeZ+MtTjeV_0ls3!oy`Ydj=aRik<R(j@6iT6K zQ-Dg#({W<@1f{ha)MlFb=tjjrz174-1A$&^b{hq%)MW<SIC9dHR%uK&HKXl-As#9< zV|7V<Q(~ok+^TWGsDrRUC>z82<1k87Li{ssQsKs~04DLkYmiiuXr54*TYG^P=GgFc zC`bZ{2M{7zOQuWBK53#PF*g>^gDNaSGj$;*<^8$AIzuaMXp|i#8B1d8jT_1mIn%w| z(_AhUDdPH18C#XjcXNjji{fA-RMn%KX??DM0C$6G1o}7t^rG9X-!y0HIJRVQZgyVC zCYst1R%#m$-NVxTepJU~g4yHa`bvBh+g5E{3yC2u`G!8N5Fw~HL{B{`40B)XnB|Vt zZXlfrEGRT|RbT?2suWI=Y?>Yeag4q{L-rA-A>vF%d(rmS`gj9+kvkU{OZ4@`AnmIy zV7M}xn#we9UB0nd-!c~2G|9!a4<K4Hz=?$7ZIT<zwF0e^9yx7xy$Rlxv=3pe<sndw zP2eKyhw}|dcUnU&oS@)A;A?m$F(M}`Y=x2<`mOuGzZl6~vr_${sZL-1<t0hqOAjVV zzvcqzKX!r;5=-G?MNYjbC_JL%1)PrbHBD0Me<1UvLu9v?^p<mEKt19zO^eU3fX8jC zzKMh_d1jgqAhRh2sQ}$iluni)mwvEzDj@LlrAXSwPgRON=C04R{l@kDtv)Z&ft#h@ z@X^pFUzMh*=NXr+&Xcw=&9bgtEx&Qx#W%lp6p}-l%=}xlK)E#HnK71^W5AibE80Cw zrDRmziOaoHXP+4TJxv-Q?6Tx=Ds#F_{oeQHU+J;6(5U<x=nVa#A{XyWrw(HeEQT<6 zG0*0t99~*w&xu)3fQKqPWR4Io>Pb1hqLIBO%$^fGQ${rd+Uol}#Hp7|HrwBYd=bq- z4DZ&THq_ADRuFayB(6#B-r|mL0ULLOJHCyDFG_Mk3tI}Vw(dkWa70ng%=t<-Eap*c zmv~kEENAGcw4ceZ#G5p>-4<$~fqMqsf<-ugK1l8TKt^)54toQOz}8q)|68;B7z+3z zK1b@G2}ycNcwU}LaP+=~;layAV9RKWFDuw5vDTuSWNk0AlG3T&p8A=ap=bf|*OiU< zvz%&jCH2Px<zZ;a>Ni6NAFhyXMw*n`a4I$_pnd!STXs>ug`J_A3903o^Xk@}<fhP% z(j~3NZ3G!<Ff32uQdS#E9=tmmks8W%CR+5t0#xHTF994XP9P8VrL$;>aMdYK3W*ql zGH=47mV#zM5IEZ}zDTnfW<CL|*)g6P`DsyQ`Y$h#dnM>5vdD<J84edl|FSCH@nq?H zs2a4+n#R=~?+Khm#0&<q1*s2tI(gAAzcDi0L9=!2hS73%n9d28q(f2OhT<3nDkv0E zw<g!P1(R*1{DtCFQhv|1s!R@GebYG7c^C`h<RqSUSm<}`YI%k7A%b3u(@NN>yg#>! z@Pk*iMid#mt5T&&j$5=5U0!S0jF}3r?sE^kQ^SUrU3nEElXexnb}$&N^NP^wW5r$R zo-H2`dkIcQ*nT_0-Eerx4+^Q`xv7jjI_3Z1$#{tQY00zNbQ*JZ5Pu&V%p@ii%m315 zBI0R~NU+i*%`!DT4yWr8r!V`^*lZEnqrKDE%gbgbDzJ1}vCk)<Eroy>4P@Z8tX|A6 zgNIEO4Y5c=SckYnqLs9RiKA5@HS*CIV;<5&)D?W(9=ouzfMfPiQjcPsC>VO1QUA5D zSUIy&F>WXYpN*jE_%Ll578>(xRU$ufVGC@o$lZ8Qo1W%9=uQgzGD|lOI>4XE`fafF zrs#Lqj{;~{ES6hQDr{2m`Z|xaRBIQ13-s}Y{_JxCe#aWUt^c)}4cOK0sN4;=$Gq&5 zSfcR3%(1T%A;P8q=42o93I_{AI8UT3@1S<h?LFA4tC~Ji#z_jQ--1}*PBh<%aq`WW zamtyxTI3+yhw*QW!y@o><y-4`cwXVRxa4PTJUp1U<nc}81*hl1E3Y_W$^n55ZTxz) zV?J=2o{^o(QOTw6Sq*q?oZ@2PrZISof_d%>Ta5A|(evvgmod~pB!*95yD36zn8(kX zDJCQts7TslhphWyDj+152V>I%RG_9=z4goup1K2k-;OW?Fb?Tk&k;s!V|oehFYb1A zzQSf7*HuuH&rPbbKy_qfr`PL;9{#Z$Ts1RPH*$srP%^E;Ov47}ar@;fe>v$ay!Ce$ z^nS%PBfrk)$PAdAp(%5y67W3TV&|aJz_i>6k)s17BlJ59NUPIv^8V;!ywOyaTEqxO z{MtbJ4Op+#262GDnw}kldqn};Hu5s6_d{J9$W4c7pOygAHY((WE#7J-+oTLD@*iXr zjKTNb9hdyTRd&%;cTrm*IE0Kg6bLuTcn&^u-nv`EDu7H2-JMyQ<O>`n^Xa6^6ZFOH zkJ>FBazj1zuqU@}sqkGHc9~RkgOo?;z*S<#LQt|?58+zg3^)RNP&XwCTR+_eNl`l1 zRpZSnk5hGs!D!$&_oD<2*a$M#P4z_-mW+(8AcoGWRF0yT<+nPlceVO0wbYR}wKij( z<R;tWJxk0@%8lQGxf8dwBpvs*+ZO5~-65n7Mga~${qA_yANh<C!+0W8ACV^bBk9WU zhB7<=DUA?zjTBk52Q#Q#o%=6aF$*{e|GI$uO$~?Zp6y-@k&A^yyNmf(>oK68_qW5M zcrZSP$Gx6~K}GvWM7(;7!>K<qM#jaa9w@j|^MXg-wgx6=hNgxP9E0_%mj<3-!TahL z653PmZ(F~!P7+)|`;{8U;`riIzt2?Aan+ymibeK!M)!~OCvnszhFHGsLfb>fU)LLo zo=OJB=6}Q;GjsLm2y}H8#xNmZMil4lz(`^L+C&?PCw#gYjP#z=+y@$z{($#^K^r*; z5Q+y_A5MU}FSGDj$v_U@*Dnb(1ZkdHWu-y99vKMECqIs8`{a-4XuQ&ha36Xy@%ceb zG|Rf%ipmtzRV%(x0M7JVr{f7ik~7vbr|w>+5U#$_End>ALYbto5He91%{=3z^$EN^ zV$+I#poM8w`QEN$PA01z`FdZ{THlaFp29-0P$q3wNT27~(7k&P_Oc1|ZV^%&GwZ~< zYaqX30li68rz<I8bZvT>FYnIfpMv4N1KvxG>ZOD{9k)wz&h>kD$|D%x-bZxKorG|D ztw4^QHsYoZcAasQ8R5pWF`{jM+4T6^kL>RkjDg)Ww;Hos3ww{))@hK`pi(TUpVo%U zG9BZrv!TG9j}-SZ<XE1nqm65g5V17?_}0U=rAs?gS;{L^yIjvExhBi*48qU20N3}m zfiP)K4WzA8vW2BNaf*nan3{i^;SERNCD=T+%ga<XZ~WtD#R#l|x{#aPcX-cMW8NQ? zd)Hg@Ya;X?MJ4;AdzM3qu&Xd`p~qkpOycwIQ%}|Pq{~m@<U((OwwXmA^z|CpE%QHK zlz=f8Gs>U;#c%F;*R<n71_DZB1_C1bKR;yLOr4x9?f;YDtYw>o+mi6z-2<}6B|1+s zLZ+@H_p9b6Tf}`$h5jTGzoXg&A2u6U(&A()C}XQQ>GOqW3&@O7*oj=9&q8;3`VuHc ztY`1cPDf8CQY5Rr+|{bPRXt@+lprN6O8QUh)VPW%O-;;bX5+F4s$KYKmQ4{&&W(u9 z;R{v}KTaJTjp7aZv9EL43)b_F=)A%5O`S+FJA4d^-;h@O^0-LnxOvN%xkoEjjM$FK zP?uaXvLj7Q-%UGG3e7LmTK`enDn3XtnMj>A=*G{G#5=w8cmIT;=kzU0vO#xmRchip zzfBc%iBd>Kezbnp^z+p2S>FemHjJIXkJj&P<Rnj$ZxuALHhvLIO#9kd!`e(^DR-q{ zi(cbQ3`8;x`1K{V;q!N)@R_%R*5njL;{<962IQvBAf&%UdxjuY6QBZ(6l>`u%BeE+ z%1FpLjbst;O|#l17f=>R6HI%0C0y7J+y`&D0a8{2(tZpJVqN7lRBF7#0J3_z4!0mi zpjrF<%w&7cY0*AX)Af73D;$(SkJSqgdrVO066y(+3KOx;6tcHqw&T^^kY($5jheb9 zH)2#fz_zqP3T4RvD~%r1XIUOjj4djp-S!{)#z-*DIP!u8l}nXs8qJDtGzw;gY6u4A zxTQrV$wbJsT>m=)B+Q6<H$3%7D%1;e3r!_QH6yi9UaAg7^WrPUTCJOqe*W}d4}pG= ztYDga(h_ERlK+sn;;733Teo7GNk(mTjy$4fp)a9@0p&Tw?w~Xrr5TC1`tc8FsxiDD zrI4CO8tbp_W%X)tt^jsSOw6CTF41eIq_)lSa}vd6F(R0T?un?dKRNLcBQ`rpXTKlD z?r)_<UNLU|6=sFpl*!q5RAVw>(j|5H*EM+-<k!#9>=xy$AZy<S8&{{WCM5>@?kZo< zC(3md@$Gzfn4W`*7YNf05my(d%HUi3#nA|Fs3_jP%E@qC!Ah<c1S?nzbOoH$T4E!& z&<}r}AR-|aj7VjXaO8*VI_Qn|2_=h*qk3ehTrS4Es+@IeR+JHhOfH~?>-HIz?@L)$ zm1uE=F=AIoS)-M(v6sbM-Gs6wG`2PE^frD+mNbjdFsof4t<O?}1|E_n?A(C!$CrDs zQHm9BWVE(G_&u0&yfrFw?Z<vNZ7CzkMy}#gTz~wNMV=Pe6A;$OGo8zSRuJDr-5etP zC1pTz5+wItFU>>D!2D$EmR{<TvR5nE0_(5KG};5(FH_l4Y5Vu$L1@JMy}>`cpa_O< zT7Mic=QY)#S#y^x9B}az4H8j2Pg>(^MLxqstwD;xuGaatHR22BoV4Wi=cKS3UT$mq z8ZYTC-WsVJIVwJ?@f%I&52t~U4+;fD;i?ac;-B9J`$^&Zzc9c9G~(*}kvI^MaX!&B z{AXAP%Yj}DpN|=VY<-7=5syhm3S$3*v3Fq71X!Z9+qP}n?ze5*oVIP-wr$(CZFAb3 z#<ae<8}V(#-iXCtsHm#UIC=6stoRS1ksd#sA4O8001!gL4`_UTE`!qeSy>AhC|R42 z4sr^H+lWpFhd^WELK<AY8zs>eKG7~Tb3Z(4o;~JfiU>n(O^(*54Dog<zcY;a;|RM$ zVL}z<XI~(F;eyIJ##^Ba2Nq(*oHH>k%Pl<Mmu9w0e(`*XM|~#@{4Ix-{Xq!eM5Ea4 zN$YaVC75H^V%FR#O3jP`sK9zK1ThmX<`)&rWh5W3PwD9fCVmYBgf^R5UJFkMEC4yw z>LH6vK9li$rN?#*Hg_twbkZ0fTxKX=j)BE+NBbl`$+PISzIhBW{g#jP!#}0fG`#3S zFue5@qxqSoD)J+C;b8vxE`9;{7{Xea-SRjOH5N>2q0O(rS43*UTGp11spIBcZ$zD> zx<sa1-mvKQfP*0@6U&p<^RBEzqK&8zkOeF%9L=H`cESx>mlDb#r8FN)f>;6-fW09- z6D2$XWX=k!H|%2x=AWrSqc&hi>hV2C@{q$>_&9P_Pl6>D{MY8dyUNPxy%7&p;&?V= za)S#(9cjH}8yISDi+lX@U9OX#72aN%%&A0@rL;uwG)HoC7ms;7GfbB7WH8EAqynl- zDkKSg2a*Y;GnklFoMtT%1T3aT%x4{TsO7m555o-s(Vqxv6c^-H1Kr%6L+*agz{aZ5 znHD10CB$+pg~CBtOEdVPPOh)b)+w%MPx!(dng1@YDD;4JQ1i!m$npJ{EeDl8xE-_U zwXG9oKj>Uzar(s;n||p0cW2LKzkS-*t22pee3DN{t4|k|VbG16sK%mwky;B3MrYK? z(|xO~2u9seK&Z5~h(?`e2$p{ibOtDq!<t#eWuvT?QJaln>UQC6NknJcKnkQ*U~#Mm zT#Zs?gpE#lmB{_-+Yf~R#eCV(xa3B7q<_|TcScWYw)^dA^Fs`k&(9fS|5v{KenkKB z^!ony?Ms>^xa39|QZE`A5I=TlIl-IDwb<wD@yKwl;HN8)Uxhd-ngvDivNYPULH2{> zXV+=z@&#G)U9=SiOYU-g5=Lg?2hSaR{(1oi`2LJki-@1Pd>U(GR^&PBgE56Zgv+0` zC7whB&pkWQ-GR3OA#NebyvTM+4^Pe;utMeH@BL>%Nj}u%QJVpi?rxP#!w=*U%H8el z(QfQqlH@=ez=Tyi(P;^>tQi)o>}-WFhRx&6C4M=t@0NUR0e9Tk;)n1#9oVPqT7GYb zK0p0Jd@0+FjAKKmGuzj4^C1{i%J*-lsr%tay@sUWmpEA>UTFd^=rE*ohphaQ*0<g2 zQ5F+5Ttr2iuEEOdmU(7EV?qX=P=PiucUD36;1Kar0yzTa#cWRg%;V?ff?x060&lCa zr(-{b3fE2iC%fiRdG8ye>4OUc`p8!8{}Kzw;2}DG#}YI>oT})8ZD%oh8^qbNV0B-+ z`BJ|;<{dUm^x`)U7G!uB=tu9M%e<;m*g^J{IiE1SaG7!0yUyz1$U2FinLcdw9${@W z$JB?J)Zt+>@|k_I@pC@%)t;{#2Oo;ytaEtVq6YL%`K>l1HFX(5kzC9Aw|nuN_sKs; z_o4sDw1A|xGdM;aNFeL@Wi*yw<Yc%wKLv7Af;*>$GYaHwF+PPo4O2x5fqdq(kb~l$ zrqqxEhdu;`BCm@jNJpSnV)_5d5kLI|(0tcR-!N%gc0848$_G9}N(SqiN<mAgt5$)Z z>OqWHN<_Y?kg-`EJ1K$ws6d6sh}xbRlT1lR@$q*&jFn<z{BnMp%knn1EV0s=zcSXp z*v-rS1-;7W@a8N(oe6}l#q7b(-$}F#Hn>%;7(<Cw>NaZ5K?T=h?S&wCq%=NSmvov} z1x9^yWi>@#tykx-e!fI&a=eyqgh6+juNKNR;H#u8ykY9HwMBK=^_(3wR(bVTlC)s? z&o|s-rZyXSAZAt620Y7K{c4=IR3st6S;ZUcZ!qD7ofH!Syu@45^Kz^NYN=AM%bNG= zho;tu*dsmAN#~}Ff$tLv*W0enb+KPyO{19`Y^o7M#ic2UPLT-0;&sMW6{<KCL3qHP zgmk4uW&r;L&#!kSy9r+??e+Emp$HY>s43OI1>cYz6Ij^V%FN|4WovCosvP$R!}oAE z9B%Y`DnxBTV@q=@mO4TXx5^g3MkR6`9w5oiUcn%Cma<U2%9d7gio8Tj{{+Snq%qD| zFBF0|4G}<M&(}=_#W|Sl$V08$^f@C1os`P?LxzUiSwFL4Pq*yIkO>~gR=v0T7Wy;A z`^T1-PZ-~H(L*p*K(;1PmV7dPMV2Sk8O0!Zj>?f?DbY!BItm?Lb(oXM#w5#Y!It_4 zBM+|`(U&2C?R98drouwb7I2$q*9`&D?;uxu=Ze)Hx273hyF^ijiiPRJCcoGW2I(qM zWD`kj%2eGO&#Y*B<XdYDSY~(aCEEt37zT6;AL0jYe+MQDvb^7F?@+5fDk+$m^sa@Z zLBQapQQ<M4&rEZ>mrl%TwX$T9WNq20!QHkIiI`qBjRX!R#$8DR0$4t9=$6&M%;4P6 zEPO=E%G?sM=!^c1HMwBl3uV*i-%YXU#npX_F&B*+PXr!S)&O<l>WsC)zikg-#>0^s zU9eOOcM>w6;uDi^CSXvl+T0*gN7zLlA@B&J#?)d~en~YQ@GOx(e3EGM+!~0|c3$R5 za2T_9*7A1#ehXa|A#z)Q#)0>to3EL425S7w7{Wdg5wbI3v)o6s{KdFE;_?9+7RfrN z0p8wqw5dD1G=;6~;ZxdO6hv>*_76pt8<(w`B)<6(Gewr#brZ-!x*cTcKq->wdN#Fg z@Ymh=`tYQ>#6}rW%=J8hE>Q}$Zu2;@#p6JSx1k3Atw3R|lS3?TB9|Wu#nu@9YAW)G zFiP1Lm&FvC1l6HOg=;)J_IMk8br-*IZatP35Crc&KRiXY@y?O@s#*z=x;*{S$90?z z(C)JFJ_Aw}YaT{Wt!sPnLYPCF0P41aTc3}laRzN;)!RlwK%u-ez}tujtD_bPj<R)} zuEfsHOg`P)1Vqf3qTh9XUZo^s+zLkr`(-KUurM1toxz;%nL3xEEH$2HrplfnKS3vT z$j~zI_!U?6(m?~o+{g0bC`K7o#{6CNbN715w%Ut57$i!1lp=o$HXSKJD$U3M9Wv70 z-e7OtG4pATu;;r`1GTQ>-Z0Ljpsf`d_<P`k7K7Tmtd2E|Iy@$2U({&5EF|FmqRH;y zO25oqs`Jz<t-{FKC*wMe8B3+=q^CiSfO{c|X~<J{WG1`+LsorB<d?wq<CfEqdKdWM zL0ij4BuYy~iMoY<h{e-}=O(PH)w*bgE{e<Nu3+kQI#fZy?*wNwPd^=e&=%p&l*XE) zv`-9E=f)_(@y1Ymy4q|`dI`P}1OzFaG<Cy;N<pf54YxxO%487UqQ$euVFyh}$fZ_l zyH9K9M9zUi10o(<7d%w|v<6)OZ6>jZ$rkaW<*tETu1=}ro@Df1yHa@*;o|Mc9Jd>2 zBJAYEs}rla+eCm15x2{ZE+}Sv?;MpOWmLbRB|~PRiGI?ORTip3cbnTf&YGLi%~ul( zbYudF>8>)XAz-!;8YZ?;Eb7)yj*P#|T_ozI>P4xyLQtgbW96jP1oV8YSZ2}%mLc&| zJ*6dJFUeJW0PSy->MOyE7YVKB-)w8ch5vNJn1kNgeJQa{?hji|f*a<zy+-)U9XrP9 zU`NTJ1GNaD$El;U4H>KHugu>7z`-BwfYtI_AYqAvrL$DKYF2ktnu$O?_9^nV6lm{H zjI;hD$SHT;VG0&d=D9iYv_9vhvkA7%SW-?a;$}lbM8*C5eUfpD1ukP@GOMuTa&2){ zTuLZ{oQ53V@LDoq#oqQ+3Jc2K>pnfP=}?>fZ+h*TAcgsTcW3=xFKl{0RQln&>Izv* zV(QQJ)<vYxu8V2C4IA%HkJd{stBCrP=Nf%*Je3w30|P@)cf`TBQ8Ou89nu-(`Xev1 zC)6mm&TdPac)s_MTwPeQ%$Q!d!G?h8v^oH5jl3!V0N?yij|G#jJQFlpc=<)oW*9WZ zMy)#Efr+Ik8^J}`0gWVAXT1*`mKbL-V!>n4)(YXWVpl!3B8uvdX@B~8?*4rLi|yvm zGN8-f%~Ap5h_~E0j2DV4yxUX~dk5`yx6L*7pBmOi!$NRaKj7rVmj7#=$W-OM%R#D} zHl_iiT}(5pG#Oa`#*6C)QU{T+O`vO9A-8=uqCLK5O5zbe4>OA8$V+$|hm7cP;;(Os z)ejd=zjY)EvYh#{cTvg4F|sSgu5s|KupWLKZOrcP_P_WY#b%h2^4_2~uJ;8$9<t$f zCI)aPi)~k3Vt@?@XY_f+0z&`VMt2PP3QV3-GYjv~hf47!MqB)Mfa0Cv#~X(t*Nwpy z$S&U|I8T+{PtonHW33n0S9N?wAD(LAaIe89>i@bTPk?NcdI<ppq=p6rME!qLUL2fE zO)P&Ix%?-vu2yr~4wn<jcU?o41G?pEBE*!EF{qRX3Wo@hK8Rvg<d;T~8?|S4uc_3e z+vT^ndDsrD=_GU1M1XsG`r%9_EFw18V7+P6BwEcB4vp4Ti)Jt#3X?RhSG~!nS{=F# z`b#RfYOC~;CJy-43YTEC5E580Tm96QU@b&-*NjkrwZn4Ocaw4}n<+mQoE7{26rCKP z1H6n&Ys6H)G!y2E$R}6aU+;JEeKg-UpueXB0ArxQAo_uhFILDE6@)D3{q%72@w#|G z9U{LAHG~5n;epL2gWmlp^&%!o!a(BViy;ccB_QL7Q4%VT3VsUXQP-)gZHZD^O~-Dp z6j7t1cZ-gbr*LPs-2K$Oxtn~k>w?pWyusS#bEr-tW{F~TaW5nW8L16C{ZkABeQLo1 z^hw-BxWEWQmf+kphwfM%j&;AVpSrmcntFrQB9AjD;WKvT+?<6vqW~6lv%xNZvNWQh zj!uwKS3os6zGXF*Y#LSNo3<(brMzy64<VD;A|wJRaFx>W)xq*)4Lo-RnlDV2o{F2G zP)+=^V62y(EgjzW!^5r-J1J~WlT-QU(^^R%^GWm&6N1z&RH<Aw5`k1}mTvxSfdQR+ zn|DOqji56K;H*^`;ZLV}K3Ec~mzbGoo$EC_#jen6_GgxT{%`G-_}C0?kDUqMLl&&f zclz^G$=U(j`+~`lT~5a}e@@rd=(G(-Fg;EuEfb!4dsUM7gelyi4V}EWgI}0{BgHtW z2Md0`*B|Mabn``~rX+wKwI&*i25bVvqP|^&psH)<DBDs%!;n?7X+p|a1(*d9hcswq zm}{5XsL9f@q@sZT%QKc6tdVReGI@E(Xx(MBom%9g_PM5UUv<d2zO9oM-nuk})20k5 znkY;aZXBJ>1+9wF-wX%q;!zQBI=Y2%aBV}c28$SlUTHNJgT1gt5GT{RDKKNL0p&q) zQlhdDQEaty%R-w0nP^xUOEh|pca&osW|?TNZ89!qdQJCQIG6=ykoeeX9XlK8`soJ> z<ktAs@?8hIF%j#la<5_ntd~c}Vfmc~cb4Vw@!k;w+K0nJ_<=n`zg<+Ah!q+YPHIow z#3aWWn!S~k*h+F;gVGGx4DzX96MJDpmQ18Fl>k&`h=JK5O9w{dQfz{i?-R%SyolwG zm)>y?MmzT)p<;dQZ9z$ChIvP=1N}S|StGQaCqU@O5N$*>GNrQ45H@Gs)nvS5<ya99 z`f6r{epqv*9JCLct8k8AyV}rJj3Q$rl~6`{7Dp1+tGX;$4V>nNtj=I4(&yR*n-FLw z{WZn#0>fd|u=j9czK-;8%vhRW9aoML6zW<SenDL$20VMTpy`w~n5r`H<chW#<VdU= zGj7YrA*q8->gj{>ngA#^oi0sT)0Pu@m4~3L8HkAfDe@LjT(E-=jr_R4r~#t&s)5Zy z6S5yM4qJY?nAO>nVzmvsmCqiH?6!OR_AAs9aS{zqok)NAJ%gIo5-GF71>w63NM7_8 zFc}(T0(gpOyrI_3CqIPCbICr9r1EJ7;uqfe7Hf-2e=Ki&cx4Yu`$vZ6f|Plf`J_R9 zH1AnE;)~v>$4R{Eg^KW;XpMRr1fT<q+h9Z0nu?F{{7J+u_Uh~$0M|LJ(QMwGd-j{5 zS7L8sxQsyXyKuq%`SqJ7>(>zH{q$t1Kp0XX*GQs4R&x;9GYMeefwr)kI;BDYPF%>P zb3R9XtytD+u*G_wl)useGaIk%q$&TsqD$seKdyKV@_F?VH*&x@ZvYnR{tg^fbY<LF zm|s^ID_uMSF_IUe1$aD37$x+4TJTe^4BYCOz9@{!W1vP)DA#BY;VzZEKLweY$T?d% z%$pe#XP9oxNu;K~W!BZFkG(ckbOv=dl!mC*CiE271v^Q8IwS*JC+k3?P94TLT+_~& zC;0w0Yg#9(UKwB{rSWEA{R|e-CwB8;WH0*yUcnpEXw8^yJmOr;Pi!4{H}R`Jv2)Fk z={y-2I&+;9i?u&B^pdc<``baLa6h+yw=>J(=yw6Cx|R~Xm|KI0<eTP_G|Ddb03jy{ zZDvBuLgnv;Qm0FfonPT4o2Xn}A{dQM606qI%PTD)7$!?a?j75$)*1Wi2J3d-_I=_p zqAngN_Z>)xeC3ipce5|gV8&k)`d_qRuIdcPH1nXdsX=!baPCWG&i8feUa$0iXW%|6 z&u4E6KTQ>u1s^0f#WIB6#He}}-o(zxV)gldZWFZ|*C67+w`wmgZs@t&ye`>4C?phq zrpWw%4}s;5vo-T~SnU9o)U58<v+#>4U8d7<J9o*4mLrzpgEwm<zIMHSj{lbE93Oy3 zxqB~Ju*7lkLjL?$v@10T^x^csLRt3@5c<C_nE$}0wnla)j0Oglc9t#%2LB4CUIM>0 zC^KA``wz?^oR)N$Y~ez!%dLLY;^tIt#3%AL<ZOSu%8`TnR^Is9bacyFoJ=mQ4EM%w zeu(lF&MnwDFpjV&Jg%4l0JNu-E;mGkxgc@{s!*jZWOML5K}nv_X+f*{RL09H)>{B! z0Dg$asQViaemu<9b$I6J%|3?VlI`rX#`+KpqP2?6nW{{>I+O?`LT&K`#4Jg1b>xB) zgHA8>-Imel?bLA$K1*yYRX+^_;m=^lCZct6vVUv-gg(!V6bS&~x%&2hZ6Q<?)bpc3 zfPm!xwGsd3H$cv&F0KwP_VzZ;j0Pr_&MyDiqj6^ZpC@AGWMpgVZtrAm@IUFVxvFyZ z+e~o(=&2Tc6A;SgA`19sh8qhajB*Wb;YL_+T4kuUO(v2~0Hl+DWOnmp@?k{-y2$wW z_>>7IxM0SZew$2csCBj3oQY60I|XUm32lu8+>N9j<faBuT4m-w59uHz{9r-VR*txh zUi>sK-PG74d24Qh4T}2MGs7ENfjTv6b;&=TBa};Q*ycX)N_c3BD2jCHilPtW0SD(I zA3wsAUxwDJ46k;vF!ss3$~fwS>e=Z}Xxa)JjurTSx5fnNt%g*EI0`r>r2<alw|SG2 ze!Gd^8b3}>%W)XiEYP4<t$3W+67G%D`$T27EoifZH_;@Og<#CsgcjM7+0Tf(T=7=P zO1+_%m{5=j%YjR)A2iuz+Ga#jsXuZ$q_e`dz~22qOoUG{me_OUji2l)X82&fL93?~ z;xuY`L@v7jez^E(|2Q3H(V@#H#E4fglCT?K7k5Q}pqB0YyIZkmpW>FAX2d!+tkdRE zjjkD^3w2wRrn9}P8Y>(1FQ!+4viqlob|GOYSaFRxk~8nUCGIJ>o+S&$DDJ7t7bx5- zAAa3r{cSGJg#*R&P4bM>zGN_lCyw~FZ)lvGz`!&^=kTCxEbJF;gLzZk{a1QR^@y<J zCYnQ`Q|~FwY2ay5ijC>~w0ope)k(GmJ!g^Ii}GJ?w^=Z{j9-|F{3HlR{t75I_`EU5 zN-y<KCLKLq*Wt%f)-R1d(XqjFLRQ~N7h|ij(SFMD#jL{ic05d9?4$^8489!jBayBd zW-d!g%FYx@sFyDw-QN*tZo}^_!z?&TK#tZ#7-Sp*alHup^8MO6jaOoMbB#~3&_!Q? z@j*8R8?_Es5ifnuchVjQ){D=^(@O{cHJAL3Nk{trcdd!g|4#u@|NqrC{?Bdy_tHx> zb^gPb^?R)+LIX=;(&^=cm?mhe6KiyX&jJR=z=EJ(WWmf_k)(-J`A3(<i%Jodnv0@G ztetf}<lgUGQbI%5%^tg#Ht*!atDtJ4C!oi;Lv$TQkj0Xl$xGzSiyuiNrijZY>oi_r z5}s^3OeJ>LVW{A##hfU6!zd|{Y^I9Bfc2{=Wf8UdxsXgfC|Zdgm7fHi9Do^(ApKt2 zJCKs4u56)ngV<GFxh~=Pj5;y(|E?U1zNuUfIM?qpF;n4P95q&Iz+d$C+&OT!a!Jys zhx!cM<cxw9p;?eQiCci2qV1~1a?Bwstg^vVP7<wFlZl9^@m^O-Z#I??^V=Hu5`10j z8Etldu~>ZMIbA=oyFuI`J`CExGP!w;jSjJ+Cy+F6smr8FB6EUVM}8kfPCs#{-f+@i z*8A}FeYMIhQ@5_oU@n)7)no!UgQt_vdEuU$`R?Cru97c8M1>3IKC11DQihV$SE_}U z7Q|UuAp@U}g`EN~1g~900LoEM<<s`C%e1s2B`34AGkr_b*vUa^NDNkoAKM`=(Q4H} zvD+ZNQF@-tJPa@4b+cq%lI)-Wfhz=qpUpAmqsJ0V5{X31fSwkd$CUtm?Qdxhb+NVZ zGiZcV*XzHf<_B<iMbe^~dkwnOb<FZdsIbw@m(b6%1pus)>lS5gw`y85*Yz@5#QL|C zXX}p1pMl;eL0X7Bg|L5vFvf%^U_pA5b{yH^>6a9@xRZvkjalhJdkx@<rz{Gcz@`)N zQULSXXazblWE#RWQt;|ClUbvL4ndFPa-?>Wr1Qj1m@dF11^SAp{4x+~WW+O2Svw_) zN6kj1oweG^3hE{G9dnMRH{^2c!Q$Nmg_mEC1!e@VJqr+LB0<@8og;C@&wY^JfAR{| zj@lF8BaPZriJ>ql<jLgs8;PO}vy6F+2GN{C0q~y}@d@ive6#=h0TAops!5Io;l0W} zzl%l|PC;Psk@i}97Nb2IWcQ!z!Z9+W+FV9*pKj#1PrT&MHm1*PG}~3%!sbRPG1GMz z;o)Jr&9Smal5yI&5OT<Jd@<5<XhRG$v|I&!HjZC}`J(S$^XL*64r4p~CD@L{6|c3t zv9Z>GTp=!5zLABT)<fK^_>082{7v&aL4w*i_>$NhSoeBU<7A>b3JRh^q^g)~W67bH zGT$ChcmIQ^%N8$Feh$CwL<4btqOPv$*h^-Q{!3uLPiyG+Y}yGdW+>m#gG5%cLVIRD z7#5E?E7k{lUFli;13K9#swlR19@E>O$n}SIF?ZS(!YgEukHY*rLlxlWQksn1O}9Yp z+OR{X26%B_0m-^>m3r9MbtX0B(P|_W6krx39ffgdJKu}bs53)e&q#gZB|!do&^Bw3 z4wBDT&B-zL<aoLH=$z!Cu7>Q@x#&6h{61Kn!sd^UKdaG?nSg7hwS-=SIU5M(3?2>o zi;$*TX@&gA87L}u_O8$nYs6PZ<+f_aL70dwAM-xK^%~2D#=UiSpS^=(FpCW|G4}b+ z7)J}YRllpeB|V?+EJ~xjt<65j<8*@A_CZYwK1|*cx0S>etDSxVzi)%ezH?i5uq!Qv zPTMf2=ng2ddyx;PIB*x@o*(*2i1}47%tf=sKUDm{Jk4yMh)6U>#e*L@0G^2VMpn}M zdlV?XuztY;>KdQR-*CAuv*{RYJ-UyvgMn><N$-@4P9B<;)yagJ?MQo)J|;PN)Q<>D zYgoUfK7w$uD_`FbUTj(mg^i|wDcSsjj4F60H#SP`ob|)I;Szi(*Gri~*<5k-<C<|& zY)OV5zd;MGzKluxf@H=7g1mkMf*9izLc*b)c}zvYH*>bja^*s{4sI{RRt!Sr3ZX}E zdF_hnmB1O|Zf1XD5)fKmg?^fq>nTr(YWEop!&`s%&<Uyore5T2GILY7*n_YE-9`Vc ze2jB@o!@}i@B-x4Yk@K7*xe-HB<dTi6r1sq(%usSg#yj{$8r9Ne{t4rb@qhxN*y_2 zj;C{Qq3_BOasP67!&joBcgp6TjsFAS-zop2(E=%uM23uss3;xE$=|oaJXZRZg@8L} zzNSDL<P0lF90OwYtx*C5Ylq28Bb_#oZSy-(etBW+Q}NAhgL`^7CTzeaV3re@y`l69 zSYIvzp+upakW-5==b?>9#s4N(tDOkJR}d656886i_VH~@wgK-cQfZU7d`rFfj#S0e z>nE_sytbFGT-fxa=kX`kjro<9x<K*=F#pTJ7Xq(<swj0Wsgowq0p|KHV?axZE}c=> zK+eHEAc0ivHD*<CA(%S28l6x1z&K$Y<!0&n4x${RV%>pyQz^EeFgFxDXx$u&?YG8> zl`jEqi&5}v@N#|GE(k;JWUl{z!F}O6Cp?4xk=eOXfPiTKug&5AsGtTWuC~ViLt(PD z-{FA!_UjjR#@!fW(0^qY1i=046NmNt+CvL@m))&=(ugPJ>coCNBzrf~PQeD5KyM}~ zsQF0<l~tSQtV1}8k#p<f9-R(-Rq%hS?8c-I+r566{xjJ1F3#ixexamj0jy7FbefJT z0&op;OvxrTjL>p76U$H_*;4qsdrgaitmXl+TTFYbb#dko*cpk}KsMKqem(&ZknmJ5 zZi)+0loYGC^n8PjZg-}srki$@48f{lQoYuxJq<AJ1p)8%0=$Ysq7A{n!O94D?6fNx zg!Z7+7+ukHPs}S~K{i-_|EVZY4-k)F-w04vzA$9wJ|`6TQ%{D_^|va%$$pd?#F5>6 zb3I?k@;O!|7gX8ZX=&`xuASFS*P5fd?>?LE&J8Xf;#nzj@b7z`sR|ol!@=kN!EoB6 z0CUo5rNGLPo;|Cto$!KMx4?dp|MflZ6#hFMn@CYt&yfaPg48ht*UU|5F`rJONNwti z@0hKKvYcz@<r9SKOS<WALTCcBGG*VuX@D#;|KBFaP;XmJS{|ZCGc6lkwuQ$=R`+Z1 zbnNa(NkzJQe#BI^PAP{r>zu$v`TT&tl4xPo{Jg%60+6pyCw?qxor9Rn{~+88d_ZvR zXp!uB;p_xUEyUPtF|j@9y&OHHG^7d<2N}UAPq7bchI6BFAA3(0v^B);`GeWzGnwx} z`q<*Z50{?pgEBK!8SI^YNW=8hOQQah1j{VN_8FBgw7_69WU|ya7^0G(Sph!_1ydIx z#gE_=Vb}Vd^9<;`D|P0*$in<q+N?7J5O#A}#yrh+r@3M4V(I{rY}BmStA=kmD+Wv^ zU)&duFh6;rxdeF*d?W~OfkUo1X(Rr2?4JiU2YJaj;y`EZ;rG~;Z&tkS35dM-Isksj zb-?R1N~<goM)NO(QqI@uRRHPT=DJUUHs7gx2l5mz%O!lT@%QOI1+7UTQ;_=+Y)C6C zyxtWo1OGG5oNS?k9f>SmDT|8Eyp0s4Vr4{|<}!xTUj~fc4kFKDH@aOE1wJ{m)|Ks+ zMqrqvNq!Dr1BW<^^>5@Yc}L8|@km5nRI+wF^>Zdql@EwvLUB*6S%^hGDY}w6D$HsH z<>yfw(bEW?bf<KpKZ_e7mMiSv31bVR6h+(KU_ygGSeZl1$PmNd0oAssOP=VMIC+*d z|NL-yHHp4<8zPK^o7g|IkchT!%@bzZs799g2-~=F<)!-~MSb@LzX--+wK-$($LJeK z81NY)9N!(n!Nq3t(2aEKTFX>PTHnbRvssB$A%EKVF3bt48}|$B7-xC%Z<YHBZ-NT! z62a?tjBqOo4V9EAXzN21b9>f~2Vwtw#h-dLNlS4j+7@{ip{oV10#HsR>b&yV?#!My z+|-NgO%px&w;?1+M*UiSI;)sv>O;QhKOe)sLh#2!1qL2bnA9kAgXc85l{S|=jNWw# zRpfa50NK}l_httDY6ktL0JUhgxak>(KjzmwEMvD0YUAr@MdN{w8CHaa72l$+-uZ@f zoRye-D5#7ZeX?K!X{2qiY7ARfnO8V@vc8G48-WbcW{l2Kb&ypd{99gMyS|UPJ1Hq= zkN%Yo67uMCjc1)z;<=Fep!w9c7;HC;1)>JZ8ryA#xQR#NcQ@!p%b#KBFc4}sokb<r zy9uG8Q%=QR4EswCi_I{uBNcKn%-BiOR~#?tFdw)tl-xdxck)FJyD)eq6D#`E;^}4M z06C%b?8X39OVU>vi4mGQqdeRU&C9>*osn7uKt|79JrTjIx?jEcoca1^(T|~Qx>;vE z{b!c;oP`a6WCB-Fh@ght^lAP+oAb#x<qj#1zgW?eEAwLx>Au&LYBrZEtYceu-sk&M zy8Zu4`50wGskr~gY5!6K0;2hU{K}miZ2$9<^I1D@b0zJ6(ITDcmNXSTW_49P#hEiE zb2WE5<E67^=2mZv7EwtaWsqP4Y-kyNUa#zc$OMB@nj)<z$U$Spix+=m;yB@%Bd4qB zjY@GxH_cMWVm5PgfQ$8Ub9uB+qV^qHsx?{7ZsLMZ??6nLI^jJP1%;!VW1in>Wv+^i zU~|kLv(dFdLK%!WW95~enw)XX4GQ&4HWwM2^3O-p9hq*n*ksphc{()EHNj^C2ZEb7 zy|-qly3)V(=vVe}Quh1(mHR_?90DoXa@k9N6a~3aBj}-IB3Ajg7Zf7jtdh{F<PA)y z%xvBhMSZ$vW8?20h?maCB!0Zfho~H4bZnCgHs^D_2l~mjRc`4ZJfn1men6WJI++$I zya6HtLJ=9A%-VGn<vS~P(K}{OOjL&YP+TS{CylIS{c~=hoX}g>iC6-%4>Tx1h18F) z@!^|~?!A%M)Ld(-d}dGpSYfc3hPDl^W5^<oORv!rpE8wM>O!`Re(Vg_Pq#pin3KnX zq}bF&SyN-O2izdcHE1ZiQ3g`cfTu<tv&S$la_V*4^efl)vdP$aZYoFOf#nQ#D7MCn z*-@J$3{$8hpy`%mN349%auO2dsmoY~iynG56a_{&lO>#+fS?3>sW>Zr=Jml|KqmRd zPZc_GE4a~9vo<l$83%|=wPykr;m7!jhYrIpg`R6EOuMkOdRn~|SYp7J`J=R%uy*=w z4wKX^c^f5U<-VJ#DnlEjP1IE>0H&E9veTM`6_ZV{dfTCoALI>__ARQsXJB~sh)E*J zxFyzB0%jMQ#Sj5K%EhGu=mIhH>3Y6@>^<6zh>h6_gdznU5tB}*37w5-yCf(f1q()a z_#>lNBDUvH?Kk5P4PQ_pw*2jMGAeatT9Wc()m)~c7!Qu%tnwVDi=sxRSc4B?gi$+_ zmWSL2+=|Rs$>G1!Rt%Dh{i`1|&0|mmqZk-giJ|Dq0bDwD*UYtv=%~uIhBR`STuE?b zuISWiY6y(1T))=wh#uBxcAy$615}j`76Hr@C#Y%8c_RhOCS5a}B|$3ZaWi91QTAoo zp*bExl!*+S@<IN%r7s&RI~1-{Z+tOpZ3Ep^m4!F~Cm8UMSEBVN1nEMObF)ZZ7TAN$ zC16)AakbM7jjSF!lOiQ7!QyWXbtva&7^PMm!PxS$hkgh+lJkXb=912RNcIbaRC+C4 zEvK`-i##^t5z_@6QY?puGo_tJ*MwKs_K=^b*9FwS2S8vjdvNzN$@RfLX}3A=Z~ECU zgkOjlI=9ML@Y&_P!14<<$T;Xnh&Heh+B%^lC~<RLVRqFoOJDju&sy<d7G?;|hhKAS z-hZ&&44S%r1jVIk^fG+H2~+DNd35Q81lUp-IJghTT|XkU!CD`B#Nh-8AE*DsGa}2D znVFMIJNyDh)O>aGxNH|Jo|MH0Mmds;L&t@UtC+KZ-6gA-3Gv(!MZ-hWM4+Qh$FYG7 zv|IV36ygdHA@*`N5R_+xBC$$@<JgCe)g4>?2a3mK4C8yRB=EZcnG~zpGn3p<7BbOR zxM2py%BRutEchT;?tSS<+XPM(l_0_fGzldX`nUQUXB8@&5^P>D*dtp|rR?@I4azO8 z7qA7J-8vt7bs|C$#{>I$r@@09!c*5egIsnOdIbZ5JWCEBg?=z{?AKLd9jQ_b7WO{X zP&Kk%NEoi3af9nO3$(`REh;=Dr9`q+63`O_;haC>US8kdn_uDJ!ksO1V*|)xsjgJN zZRFw-B{Gt>2lb;f7s8QT{;d@icwGc*9iDaiN*y%xlX2*<@%23HQ}UxR(oyMaD!Pyv zHxgC1%{5)2;333tiC}X>#hXU^L=JpO%q0xb!}kK=(q*w5{ZNTFDaH}GaLvAtPI6DL zTNDefv!MW~Y|Nc}d-#7n-#*V0MDTJH9ss<&9Q<CGV1tuMv)s)I{rz3Ncm#(45Yi}1 z41f2_&Oa<CS)tbaz|4{65s4tNbjt-S$^p4wMBkrSQAo@E5=k;y&$tMaSIfy7=KDU9 zb^~I%cK!jH-;PcXw>LknPrr0Tf_-BP@=;uHht~)}>8I`ngyN5Ah}p%c*`WlBTy+D{ zD`D#zBmVkcuV6i|aX^8fV&k^ENtqqUu7cSC)h|#K3Ar&`y1Zr%FGPl6!@NnKq@HPo zeOSoRUx;_u;;{yFF<augQWn{!(k@0yy~EUu!b?~MBzc31$;>PQneumgv}9{rw#WS~ z5x|=e#rG(s=8`u;@js1H(4R~$l|4O#{7JFYmJY&Sw#(jS8g!t92Ui%`qJCspt26b% zjBzPOhNmJmx<a3fJoGz^f_nvZ22E^C=>1}^Bw{B*+z$&0Qso^s;j<){3yEuEKnB{x zuAFOhg>9ljVvetEkNj2Bi`K508NeV-<eKP;c%KpnEXghaAzbAFCup(A3`NA6z`FS{ zs2l?d6f{NwU%UYfGK2FQ3HTr&C*ojo4i~*H*1;c52vvUb6_Z^lAPcH1|4%$5f!6{y z@C5;o=iV|jBdAlYx1J@2WUW*N?>IrMWB|s9bhF~?EYpfn%Gh4%pmZEB*n#5|CVWYU z5s)`&e<FqmZpjyWCR@glsl>jJLnK+7vlJDank+*G(Hr$p$H`hZ;rymqYX^2hA;^=j zt5zU~LI}~&8Ma6F78k8~MsD6$>S*Qq;)$UNvokmMZ+Zo*-NI4V7H5CcGBd{Z)0q8- zin<}sA$Y^Q6pXQqVN;eL)9jg}Nd^*e&F$>j2h+!V1|;A9UigBOtFk&PY0&#_s!AEA zLmEsQvvpYxko`#-J|2pEjy`7zXg0f7I<hFRL01@pZJclW<TENL1m_r7#u>146k=XF ze7A~;3#6T0<y|up#;&kOUJtxbYJBL#+C1~stj@mreT9XXg)##^IHxyeRJ=kP!EEq} z#oZKd^9E4^D`z&>2yBmZ;Qnfm#1MwwNu?j%%@lnN?;BOtDO_RlWuJA`m=x>E#S%5d z`?29{P1QVL!)0$i`aoJ>26ny49`3*EYc?IM*tk3J1`C)Md&~rB*XP5Jn9k=2nd|3V z`h3CQ)k77J6e`nc7C^xJA&y6KEgnWGOBB>Mae?3&cx5e(4sp82k|X4qPi#kd7b0@l zaaT}KW5y0-n7B*xdESnXm$M(JJ0=gd>bq*UCG}S!bwv2HcR;om&~&Igh$y5{bb2Tk zCeM!S)i#D^Mse6Op-+Y>=1Y`fhaLb1sK=?{+y(fREQWUDu2F=GsVBl?)IT}q?vSRj z!Bsa4zaSRRC~CIo_@bLYmUAcFHhN3L45dhe%Z6DGAu5F8NLopT1w@@;OFPFwjW>oa z>mKC|mu>f;>;46Q2g191QMR0E--WI2T=ybzen0zFxH`y5e}6tHSkf7;3zZ)9+Ub|0 z8x-WyUCoBE5#n>!I+c#-81@9NDoRN~GDAvfkp&pd4ju%M$c4t=OXk19!Tmw)@$(3Z zQ_Zw(nYMNm;Da=h(I~wc^5V$8QP-t$+K`y6<T51Ops3q`+<;?!!Cn-_?~e1uh3?3@ zpuJSZ;W=^2@`aAyxcc#W(OutFO);gJz;jT~V?CFlBZaECo@A<%z}L`5P$X_=T@`Vl zwZILcHC#0YUk`Eu-)GZ;w1|?0Z@8!#FR~Nb{R(h+<?E$zUwUwA&@!=#nUUK^-_k9f zd|U}g+v$^tCrBRf{8?blgf*fU@OyK4_<KT{H64FWS$_e$%a;Jm@6YJ<J9;#13LC&! zSA!f66JBP+d=a~<v3!&X*C-Y!$x`o9=Whcesg8}V5-73N<uT!{L0fDE+o#J<FEf5Y zEzA0W?fYhc)iKr60j{B=0wsxvj_;aI3!Pg;D4rcN*T36LGQ0VQS1e;pPNBZmD2Js! zQwPQ{pb0~fR=6N~3=c1GQ|q<CB@%>P@@Y@pB+11#^>iaNDm1;IRxT4nO{;|GX}@?P zyp4op=~^jGWi=a(?Zz0*o`Icj=ocbtSKYcM!CnBbLU!e&g>PHiZhm~-R^dj?0c;() zu4yGghYA}0GiVb9^d@&16aZBouC#UceVvAGr#ew(gRuEB2KjmQf=TNa?HIV5M+voi zBkgz+44Oa}aR;(7_~P2Rxd#64y})FeA`vFLngl*(n=1HrDC}D+#{5Oc0bIf8s*AZw z!CA{c$S-ITlpc089{lChsD;a*b+GpsU;ZR@+;gIPLK^lJ(>Z1MaKmsiGXuAltx#SW z;h(V_ut`vF@`hd7*7D_P5CiXai-DbS%b`6<)IW<Ve*@G<3F`#b^@2G9i%aqTst=1Y zxw~s&qXJyKt3&YX8eUncjFF3q^`KYiK_5R9=K*?u;!gwt_C6pBrc|>a{Yh;O`Y^av z+ZB=ArpeV7%8k70H_6R++GP2UW!>V@(X_TMkR?hdUU)AM)jFIF>W{{zYE*C~M*uCD z&91p3Vcu$5N0rDrW}?*vrAD8Rb1ikpNK$JnaG9Ff9TaaMa?$pT0@RFNP2B*u1x0); zSqQqCHu^soa>ToGGi(HVq?3r>hrM*6<Mk|beikY?rpQJFP~sNDKVv!AE(h{$3DjU6 z^lS$bt*`ehz`y4dH%$?KNaD=`Bel=`12axwJ&<1!52W?V>T0GirjEV`T}%8pXWMi3 zXO=BOGVyDD+c&LtI1Zgnh!6=D*IAlrc)~UF>@q@R=Tf<o7pQ{R#q$US+O2h0@5F4C z@-(-iOjcImP;uYN*I%zs9tQQjt4t7r>%IANZtW|)Fxn|!DGoBp98EKc>15*UNdi!r ztcK#^H=_v>#z0-8fZm>-ssVlDs={=!<d5Jd=-^I+L*%Q&$(oo%6G#q2*eZ_2kG!^Y z3mrCc=hg9zxRM8~vrtHa=<2T2n*`)qo2T6J;!M1?dQS|a&U;~wB+@@6SDs|7YvA*+ z)CO6fN?Xm=G%i81=Rj!JwwF@)W|t!zurb*xuem|?^2o=O`_iMpK9>SD4=)dJE@*Zc zcDun0rtlZRW64-VZA%gVa<`&{E2}HpZi0_?|HRcaki<-th)4*ku!dd7E4|}dFO-GF zCUc!7RxO`d&X1STdza6Cb_KX<@p*g*!4Bjw64a;)oW4A<x8Yi`*2tuwxh9VQS>;bO z;eObRaoR;)isXlqNRe4!T>(DWxUdAeIUOB3(s)n?rH)<YE>7ddB#_npwuhiY0TPr% z1afNJaZlM^^1)R-AYVZYaXxhG04d~jU{O8Y!ATRNtK(@H_rrf|R8ahRCnijbVG34X zhFL<AJ2s3=dC@)y5g0ypXE?T2eU4DVS4EGuqnj|;y=l!LBP+scm!122ar2<q`DCV} zgZw1c8-&9e6(}7IL-`>40YHGv>Ny*h$*{a}SNuIdISAXBVuZ~BwyZR_7aAbp@UIiR z+YI;5z4+rO{%@C7%Ml+#D>rIAC_ew^d0Bzc)YY#;*Qo}Y*gZ4qG~gC|Z%E`5XqJ8G zw|xS`x2MzJ{22YOQ!x(2^8=Y+x)Dy*hO$x;u}jv0D6^Q;?C_QjD5fD#J*8f@j?zyG z*^NVAB$HC<cgTzqe<lV8oJB+}1bx3KPh<-0nAaq@hLs%kjo}f#XQXLqk@TXc>=A>- z(y?KeX!3}oNXR!#(;i?>yUx_}8nn~ocI&uzcAFKZ(F-{WLZrdLEX+<isQdHnsOlv5 z9&ZeL3N@fg%m2`zxvqq>v4$QtO%HAwre)w@UE`A_Nf|L4tSdq&qwo)WTlQS0Rd)JA zRBD(7|D2whZe0eN`ix_eE_8$zy$^CI*D6pd;Uh^+sS4sK)pEQfGH)csileW9RqziQ zXsG!;KVS6dr?Qyjn~q*u>ZY-mvmR=*bV5kG9(;g=L8=!&+qXoE&w=khkrPo3RJ;&G zF7^4Q>*|VD;zZO`oQN3EUEJR*ReJSeHHpc_OWoslGbAmL8rW4!L>V=DmE=<<;RwZd z(cAsb(tD~sYyz}BiCog&HRRw;hJ;c&$j=sj_{x$1U}ZJB##fVwoGH(cFEU+U;jUp4 zD1`sSb&&@MgxE=7p^t43FocLpFrgp04?Lr;ZBE$Y>j|J-M34Onx;um)Vbwe(+v_f< za-=%HsBq8RO|K~02pi&Mx<)cS_*z5GJkhDE@`<5}kEEr8M~snFx|pmi>-b2lNn5kS zGy98;H_P~18nkm@4!`|1{E^q{o1tdJobB(+oK^louv1-s`wBH@iT8lU=`(^x31YSZ z$GPD*ESy!mCR8wl1G`h7q0~Fk1cQmCnvI7)7G7RlNs+(Q01np#ed`HKa}~F6`s~Ws zxmuj{V!XP8*HWnJAvF;5CLNao=LtDnVjr9Qp)6?Q6^bT>)29^G@}P~=u2+#KI?!In ztT3`$d{OshL~G?Vug0#_uBSKPzQwp=>rwvY>fE?@@wT8FX>G~rJjtnwg1~~Ku0}kJ zsXa<JY3F$;=e3Dd8vqTVQ=N9*)8o%&{EApNMX^M8aLsZt4AeAPl06mho-m}TtG@9h z`!Oeq`pmk~JFJZ<RWD!9Ia*G_jROq^H6Axfm9oh`k83+H5E2Nb>g}9Kj^-`ZmBhrX z(#($G(l+|Xe(>*dPxK0p7qPuJsOjMDn%iC0A$q_dPuxcHo$?h2x@SeGYT7sOZhk4P z4BgrFDVjxJfsz>8B|=y=(^$30J(N*7lXUhI)d=DA0)MYlw)!FdE?8L|!F@n&L}P*= zSIQ9Xd-t6s5=OjYxm~(Sg<bRCy!<Qe9iiZx83jo%h}>}k_9@<$0e$SAF|6hfLyWsv z_2(@(4q?D)YI+e!OJK-cfOKt;WY52Z7eHwz-{S2L-30-i8D#&**;6yE93+W6^ColZ zKvcTBVd%_c4MK*Jl1&~qe(m%!uGXc`^=J6Q$`-LW=KxRj0Ei(1=Cs8{cxw~+)y^!e z6xn9r&r0kq1;ZfvAnY;eUtfxRn)ZkF$Q5gznpn&VZCMvN_h|4(-4wlu{Qk+`4?Z<{ zz#Qd9(gaK#mHYBb4#eO6_uycsBWPw0QBF~z(gF<TF<;Kjn=@?WWT0G*wrh<y;iZ@6 z-{I$PMId-Jzl_OOalkPN0iSVQXkJ7h3>f2&H;0qi2RGfz$?<mH&mTJ5G)yR*SJfh) z5nYP11Q&k_RU1YA`1|o(Lb>}YX$43qs6XQ@S<)i*B3H>fO?8!)sN@FsIv&|!i({jg zzQvdfe;QBn)LbXiM9E}3<{GO!#I$fiZIE@Mw}fmHvsN{7(#nN5u2l|gr^Uq?rX847 zS|WZ=J+q!3=CM3)mBktho7zN3tt0xI3$(+1`szmzPG?9n=58G;-(3=k1RqUR>d6vZ zS@3Ql3vg(l_P_ASf{l;>-aqI_5%Oo#sulLjs^e$dIDNw_p3(ek4K;ezujrX;hWt{6 z1+0WHcYi069H)`GGwil9TsU=g0?MwH{QW-23nCSHWG^9UTz2WL>ZRqeiwUnqpm)BL zTvrQr54Dq8-c(kqp65;G8(glng6WOY#W2d-YjawO?5j+|6A&ZI_1OMJd+^&3(mWH( zTH;N~NJ~RRd!LdkvI=&4H1%0!wB3=i3Cug<y?X`uvDEwo31i5WaaM#L!6YXey_QM! zD<(|_0E^2MW$%@-p0)>m^NG+RFRC2COO}%b&!upu*1#_|U+C3_`X2Ndb%uS6+z<kS zE82>tbC)J)WlpMpJ-ZvHB+0Hj<Lh$h8RB2F9O|MX$Pq3iX{m)c24M?f(RxOliGF@2 zR}fit%D0m3#<Ed_mb!i|l|U|{DuEsx{I_GUFfuZ3?VpKg;s4D<<Z5YS@=r5Q)!hGQ zB0}<eH5jCZA}dVW`co^!YAE^I5N<olRD&pHw18sEnkpGvlH(!v^Sb*GPB!J#1Z80r zJ>Grn?!J$oOC~kjdI4|mqBYr8TEx)KZ-2RZx!z{2IUTY%f`|2vbRua5u8eY$Or}-q zu`Oj90l2tVx?Gi?OiL-yWIo#8>y$H!q$W>Ahz^bw;2AD`1IG*|>qB(%HsjC}nU$|{ zYt>%0k$4sY*bEfMamrrM^=lz}1c4e6Q$>_&sJqnxqiMjeW^Ejs?K#$Wm~|=dcuCnw z8H+*jvbeH9GQ5Z~sW)d~Np&oQamXFTJZDwLwtTSJeA*ZsC3CAr)3080=z&h$Qx4jf zoJFaLSD^+z@z_faw?|c}B-PKex%3)0#7O(42h|3<H)a7D5Nq0_*+QKK9&PV+wN+rc z^$6DAYL2@1cnLq;LlfGMYDK8mwEmtgG6mvp5@VTw-QvvXPhvuls*yyw@H}M)pOGBk z#N)ueVIVqE78D4MNY@TpX=rO6<iN7|q+qTxDLaE+SeO@HNShUs>E4Vc6Adfi5<aRK zsAfM@6!Z-*1(w47l>&xkKhZje>V&UmkY*rAg_gvxA3E*~?bu|(vQo_LN+(`coDd6d zeLd#AL-p4Uw#Z3hD9imz-_E>Y&1U<~k@Q=t2YrYD9(5}XPqm>Qe~!&FpoGY6o*+66 zmJen0Byx4=Dynb`ziQOpXFG&Rt_pDM9jMzbQXSR~C*6Mo)GCSVZK7uXyUj6luI%8t zV?aA3_I}We88fU>p7{;-9MYfFy6sv%c#APkr%jn7CW^W@CZL1VV-nQ53zjZKMht2` zV*?%yqflZB_t`rlUw(~sFGf$;>?{aZ9`~COmV$LQE0<E)=f3)i2Uo_Uy>Ju`MI(c~ zK^S-kCqdXQ6+~FjJwk@ZPJS{_SRk;-U6H_Yxj8bg1`{4sIUR|8^ePLw$(1{DB?e59 z9WP72??kU4QU`XrDC9Vnk}OYO48g;A(|NLJL{UX1`uF-j*><UFHfa<+o1@{8!jHe~ zzNuBQ+|O|W95?w%c3=SN9kG|#{ci7*>$k9aRPOl}O;04&<#hnF5PVb3VsoyB$$>(; zJSjAZvw(xrG^8AhrMHA)B{RIa*I2BCywrPFlJWQ}zmt&2>lO<g`$q9&QbK-w(t61$ z&SfjaQ3iE(CT+2)BAKhD-ZwCeSOyya6%ge#i&0*AEsK#~Ld5_AjP^`@U|7IOK8@oQ z3zi|TppPa=L2bn~>Bpz&S4Uz1UvES7b#Iu=P2KOy*ypPtEitEscgr4^Lyp*7bvn~j zv>Ip&x2y21pSb^9V}c0lo9rDb1m3Qfp3qhz!>5(Lkm|m_h_`d7qEvELG!a0ANNjEa zMt8fmpdtMzM1o@owFqSFNZNv1LpfP)5~>^0=_aAA^(rX0d<{ucJXQf07r`HkO=^^; zYNIhp0FpnRm{0r)(?p6#oO_fYZjz=AwiMB)?6eQM|1lQdEQ~`|?scH|PSF0DlBB<~ zG53%ndDsjM;q;w6PbUZp80goVxvj-Ln#dyzOfC=J!AUdiA8*J}5}BD!zc8BHR}|im zo%V)O<+u{CcHjC;Vpe#V$HCPe{9%G9w!rK2AvRV|=+-Sty|`H+5SMcX^7AxI7+``V zoq(c@A@|C1P{scL7(0h8QM4f2rfu`2ZQHhO+qP}nwr$(CZ9DVbdcEq^FYL~av0}!W zx-YOQyjzC>9pv}rt?;Yeq1kQB01QW_GMu_TIpvN7+*2eKrxnV&{ttw~0@jzBkSX;6 z47Nv6#8Yz;chzILV}zSdyKuQHhq4_AnATeqhitR=4<!0H?p`WaFTz1xOx>d~z3GY2 z;Ts$K9o0|3!%P%s-#l|2CPN07?z6A#Il`xTgX>>MZfI*R9y(?AWBiI?kg#E|u(2n3 zcDue2&(fDf>|B_V-DRnp@+<Al``*mcAae$>b`L^mc5yR~Hg<1?h8oOo{7Q_LsfF`g zbjDl8nt=v<tI1;&U+N9B@qG@ZEjQmHHGG&b1LM2EJa&lqUIXh)DaS|YrJf9V3w7gp zJ@szZ<$$imKobU9?|c6FCkcK2Rybe&x-<n0f&Qjo=7yD_D8p(?6Frm=t19OMPqgeC z@&*E%u;Csu*wObp?m1eUz}W{e?mtI5_7dF2_5zG#d0|&y_%>A?H9y>x+7J$h!ArJ4 zI8MHeg8r5W<AGrCpQw&wVk4Hi3Pa6jwyYuP>s0CvADBa7#u4do)*MkJ+N542wDs1_ z3~?!{S%BB*7umO271@cOQp%z;_^KB~uY@iJacV3vCyR5=@!j@pxkE0$&~Y;wbR2*N z0tmB5C!}Or@lUay8h<wJ&VS(ln;ef|xoKL40002__kV(e{^w`ZGqSe$A2{en!zONv z73ud@Z-AWKxJ|R=d<-S3aQzAp5UxYWD{P7YLR%7R>sqo{ws`gB=Q9g45{YCZ3lu9~ z&k_V%i});Nj+?1Ck+>q+rAMh{Mrw&!QO#qas&g}~g_1R^O-4%ycvIs*7XKHCG|D+M zCDOozG#l|-Tm0evWk^l$KVg)y+eUkmv!F(Sv&I{$@_Ps<Yw4vGg0XNJ6pBqVzl0$0 zeDz^qAISG9zZTBs`-Mj$an{Ufi~HX%kEB3DP<m4H;nXJkR|!3Mb0yG1MQh0AEDqdZ zUymccHd%{}Nf_@6y2H72P+&JxIhh^Z;jOIsQSePytI~fjK6}N#`a*)dICfy&DdruD z#MR8`9urtxFUzR{Hl_i{OCzHrG;v#C0za79OC^A#44Zl=2-O1@;3tm&Uac4g9ABb4 zjhR>CT9ekCOU%PCQdb@_0=AaBmIM6&mzytCcAqvgtOaw3e2$WW4SP&IIWK>R-?20x zkUHy(fvQM1wfJnDd%;c%CbH64vU75dzCR1#iEuP)x=x|IEMBs(1thtl#n0rjhccfK z(MpFC0F+H!o<dd;M`SE7yTO%UxgdE3fcvh2EB9eql)36Gi_vwUe-eHMH+=s*K*S6q zu$D0!I)J#s7j(6SXF)C9jIM>{BR@vpc3s01^NDwj_)HUOpUzpb(93#c{T<0)1K`7% z@zg$S>t@Fa#5b@=kFYvpX6JsZ2n0oIWl@vP=)l#^Azs&?8t%9I;g#TCJ?v3|;Emxu z+vKOcJt5p-id=^_*41M`fL7wYANIWA3Dr(C@@5el?e7;a%Zcx=P3la`!kKj4n1TT= zGiA6fDIN7CGZe}+2~9)mW)r4PnUf<`m46;b9QI2r)IF@xk+fexB%o#?Y)v##@nPw$ z4OGKBZ~0jg$$4HZJV2h{U&Cn`h;Ejt1gpQvR<kox60&31Cz)ujMZR({IKgP!+0~4I z=KHKb7hNH6$$p<?wmWV>N^0w6<Y#_PYd#QiM_;rMid8^)jC`6(eK`S>WegoXBSVNn zRg;~_GT<lQ(ISrr*3BUKV5TfEPq^r5lkUn46L(ZMvNz629DqRw+%p?2ePo3Re;x3g z%oZF<4prfj$c4^^Qpy7~r^|x1qb44{7V0U}(9sLgc6|wPM-c1H<i~AD=o(pE^k{bU ztNEP-P2gA{q=-7K$%9(Q7EUt!n_Q)>SC&n5(O9QLOaZbTXEgED%Orzf&yz%4a7_f- zWc$rl??HS;gKGYBezhUgT%}$oIP!(c;gYeR5Kg|*06<g$gw$6i+gQpX$z+&|l6~Q) zD<^SDL6gXwfQ{;5%{JfNG`w>DK*Ud#ITen+6gYd9Wi)W(QAdGsBpU5>el$TnV+s!* zX*A5FAX~F^OTzTAW@(zdzVx<IoxuE^w(>6Q{!N0lXJbp24eqwwd~(&S7&g+$#<cS9 zmW&+lO{lJ!%y4sdO;{Afqe)t1S|L{(u}A#8WuysG91f3nw6gp`NOq0HTJ12NOsCDO zVD??Zc1yFPron@1XF{+mN+YUMg9<x8ny3{kOA(0b#a9q5R5LF;PI2;7T$B@0k+L`M zyy)sBkzroK)+ukJ2=1#uc8v8Gd=fe1C^R@ut6}oYcw4FuD{c4EnOPdt%qa=_NaHCO zTk6_cf|PO?nezq@o{w<=zb_Ah9q5bPer4artWeKi9O?>I8H{3@<e`&g(v^xw2(q){ zfW@RkEQE|KlTw67dAUZ^-bAkP)_|;jp{B_Aghp`s0cF6cd@pu+R;32_vFSC2nyV>h zxO(UQ<gpap7)%Nib{{lv5ii`M-v5u5Vp_-v<jbX&;K=q~k#(hxJmH@CvuJdQ@SRYM zr9zj5;hZ*9Nae$LkuK<4&%FMo|23xA6gg@qsc@;T+1vAo5Zjd*SEN+Q<*@{>ep6-F z`ASB?HrC(n?z`1YoUH$K5D7v#wQazmFNW80nURQAsx3<UU4jyNZC0*%gBUjg>56qE z6#fqfsJI&X>d!WL2-n{X``A!>Jx9U*Uzq!Z7NS5L!NmF!D3e>8^){&jy^uF{W3fNE zIWNCNFo_^Ji(>d3_OQpw=ycSk1F&jPsTtS9rLK3^=qr<GkT4XOAC=JSh;01}<F%7D zlTYea#PDPq_ng+PS`F3ilWA?~BkRBTHEnBduAxyyW+S!4E2Pq&0!3LehCI99))4ER z8ns(h-cr4?;`mdgo3g~{lXTV~QTDy>B!fk>`=0ofY1sr{gC#b$pJeo1i0h*qVWLuC z22B#K2t6CZUi=8W-j8>nIP@;g0st!#lb1WUc_1t;pVA$YEP6Z&^<7ooroCM)!yBU2 z<@C;4oJ8OH@kV^ZY5QDo&(dAep21(P;Ha46WOsW=Sh-Hlteg6R*3ffw_+_3Q)&43H zKcCJ!O&lwS+P6sA54<$v=EKVd&)s>3$SIR3u^db6f6|~{^hVhnam{_A+fOWqD_Z{O z%x^`=<i|{(r!qtaOPM$}yQM?oom!=0>Wnz#;V5XBOw;4#+?wd)-%Q6dge;+gD3SC_ z!?ax~3`Jr_Cxx<sk8$GE++7Xsl#UBI^mjx2G&mn}2~+LlXHPDuge^de><&PSEwR_0 zX)icvzrh1|z(H37uNnX7>B(@NrY+E0C)_23d_iet85tVp56z#{EO8s{cb{fT+EVwJ z*^&Fc>kobu-T#==SkRWV!)e&&faQ#?bnM}8_c&nE=3=j(7tsSnbsSv;crMcaBO^)I z=r6!i<Foh3sn>>wqEdEuAFvF$$zb(X@nQOPVbgaF5X8rR4nJLa*0>z*{<Pr7UU%ne zl~t8KdM|xDMRMlU2aa+$mS$RgrN5)fF`#Gl>t&tK@-K2$4pDV_<C}lF(Eb)L+a4+z zpxbbtRju0_iDiPJtkLTymmW+ALV}DhZc45vlROL2RsKeqFnfg5@eLdJ$_EB^x5TI0 zcPk96n!@4h?i41<VoiwA1HSqG_i$9vAq*}+1ONc<^?$<c{{L`f;{HGPM>9VE;dY{} z`~O`U25aj1GeGhszRa3SDyb!$L|js~PP&qAyts4VFBBsL0DuFKIF+9E?LD2lu^E#v zsdQB<O9Sqdb;;$q<?&`qlbWo+e-%`Id9T>Ei71^;`KY8pKX|x5pBr{nji@pU<-x2G zdX#LER@f$!HttbtwCM=WRhcIBQ!PBJY;kY4p7f&mB-Xs@fY)CN{YODsBA75XPh?nZ z%q9MI?yQ+8RwI~ep#_Q0=5l)&XA+m)$<>v97&Cf2mv7!~+WJ3a0b(t$DDqf%z0@FI zYWbbx)pWUL9oNsx5<fm*%IWqX>8!c-cxLcO?iZ>3xU%)5%r;C+`#kBweC50x!t~!( zYC1QJx^mf~S-Gg71LHeW?a8db7~t0LyR;}IY2SPm?5O&oN2TC6r&<r!uj7VZwQ6if z#=06*bFrR~MO}?xb+V19mamqq)7Z0CIuP9ox2-$h_?9u0wu-iJtYOn>tpk`FI+}d% z&hHi4zEtm5UDxJb!|i?3Y3l<TOW1kl<G(zPy`9~m?dA0H`8}VLbJ)O0khEtOUnc1R zNJ%6l-_YNU)Sg2T_hF67Zn`*%luPbr|JuVDYewMY<M+I+cbpgOdFri&eeAu8=+sc1 zPcX~Omvs=#f%2*Yxa0twoH+6|(*E?}MSbkao&A|TNcecL{{58IHT4}opfA<^iE;Wo zpDR$Tjw88wT76l2N;?;dYxKyc+iUR^w(^1ibXP|8$}uCGCBhQlD?V4%5?Y3(NSA9k zzM`-%7^?1@fqgXBW?~zg*s7`KsKeU0rOUd%7agDF`GI-2e$B8zAo)W+4ZN0+Umn+D z)hY!0=YLcSPvGE37MDOi*GsVp0tL!kj8IoNCQ#vT9fGl9pzV@g6>8w3@f*%FX`sq1 z-l?&zn?YxFkJ2GU<B%2@+(!W^w%x$Sq&<%>eB1&gX$w^)o)@g&bh@so@N**}DaywY zgVZRD4zzV$8K&!@w;B4Hzjaur5kCo|R9W#j6A4EIw@_YsYE(n`0eF+>Yf%DV4h4fs z-KzDfE6cD@qirY)Xd^=Shsu9m0fje|v<wYzYMNt2M1@#K!8F!|SwdF<Bf{E&DrBqx zhbXDhys>BDq?eOr1o5Lm5NFBOPylfnEQhL&UkXk7@z5h0P^z(sx#zQALu$4&G&_=2 z);fn1W%OkZTvGDW9pYwc@tbEdbGu2%tIe0z)xPN@HG383)Wkb71Li2H?-&ext<>KI zw=@E}rf+7n;j;idvOr|21fXb|Z#){#7BjT?@2a@WjB7xxyX0H+LjfXSaojwj>lYb& z<d@acysqv*CKrdJ<IBcN;D3_{`XewJ!iTQh!)(o7asxCRac3~5-q_zLV%y1tI6Xqr z4QSAg*punsihHE+vAe>ZF{cDVEJIR52umhnQozV9j`?ur5XT8P0qel7-6wKhd&#p| zR>>vCJtOd8V&l^voJep2JAwSNEhL6fBU0o@N@0pi88ha9`hzv>AQlq@2j6Yh_V-aT z8mrIKz&q`)Bh7Eg;l_Vr`zk8CIW0p2?0OyXq?6B#YeKuat+e>?rBMxZ_+JCZ)bABk zhn2`||6)Q^0lB}kdu$_f+PGwCDB<MUtnh!O+?Q#7DAlmSYASf5n;*G-5d^v-n8Q|w zpjdX@sSaknB4h7~?679_Qi=dAHUWpzhbzxnzWr;BR_UP|!2x&!+@<>-A=gz|D*vzY zP!|Pv9ECW*N+CJl*y4|j-l+8WU0P8UQ&^@hK65sHti&E%eG8~9B?ODrdBS0@U+MDe zsK=*5XCB)X2m<v~4#6_m|7#vlD6phvj}TySlU(7hK<Cyzyy#(3?1=r-(CM8Jiz^wV zIo6F;E_7aEDrNSQpWp2ZtfVw9@6>d*Fh${6wXmE@Ke4M*vjEjUJt0OsiIIT<GNz7f zH<a!TJ2><&i`^8lg4(lBpsw699u*qJoEE}8T05=S3M9Z!MQVPK+5!aQp&u9mKPfsa zSzNOKFY;y<nZJVZ)jWbKc>Qj;QWGyZ(jd!${hIqbU%J*xL1|2{-l%Dhwt&Ju%#)1l zMXKwW*uqcE=CleoyyaMC%O5Q}UgzbvEQ&9H7<n;6Nl<x`l6iKn6p<hQ)gp?Re543w zhE=E77eYY2Cm|V$A{Zj@om%y)Kz)_>D`1piC$f<kw^&@CRN|WdFcw1D<!_kMb|WxB zg}HT+k&%TVx$tdE5DT6bP$$Zht?=_cMG-0|tl+S<+)_Jr*90Lw7kqyf!zVhN@=l~D z^%lVQer_A-f{eNHD{}`@8LXkLJZzk=vy9Gi^V}*z(EV*X2<p|KVS)Zfx7i9BMNgrg zTCk{2yjOG&gM#Vzm7bSWVMcuI)U@DO*1MCRXMs&vc7ZK(!-y{7T~v?SpK?r(&}$TN zEe@viB&<g*{J3A&cvC2;$>L8Hhs><c?^S!qu?Q>z^3EP*hzRih2u)HY)e}H10rAFT zQhGB)e8yPslCSi^RlK8=;0Lw2S$)+TUef|`Krir3RB1kKzekXXbzyHvH4?ib<9DbP z5tek}v^fJ-nDutQ0eHzsj8uKg0OX<}{;o&H@mR9Ei1}A~tmqhAnYM=kVM*7@a!Yl5 zUU(nv<Ar(yH(hqW3sefG3MV^FmdXQEA`^4Gsl&F9i+cGBS;(UU)g@?cW4T%Eo3|R7 z#l%FXMmAS2h{xV|^Ig=vkWRRA34s3jA&EyBw3b~RZAQ`<upP6rX9+ykf^W);zCLvN z-CfCxi%uRk;K*CcWvI7Y#0lD#`CKpB=>5yH{_EvOmv~N(*Y9^xV6|XQVS=vTS63}B zsSe`e18Msy<mDTBYCLL3mboO;=~qgNCF8%DbSK97vijUojsW4LPdXnDA~d20i&?oL zqW|4vPtklJP@Xxg*j7!SUCYPwaeskMJwmY`?IdpWOs-nRH1vI2W}fQ+Aycl-pX+HY zjlNXW*&rJ3N+J*p(=)(%(;CfuL7i8I(?{H>NJz<yjkbzKf>z-fRnz(EShl$TUWO|l zJ%H7<u@kKdo4HBBv|eMS4K4a#vkcA5`K~beKs`tRAC56Q0{<PhJU8GS)|5fEgU!|8 z$;5p3I}(abh`PTpu7O?G2f3FQeURB(Lt7><Hs8^c>gYlmsq~GgS!I4Y-z_@Nq(}-U z#7zhscU!6TooDl3z}2diK!cQ2lRLmJB>lG+TwV{MP>gi|Z`(%)*uS++$qyvbPXU2- z641<muy_Ay(S{f~b!e?6GKo!?iYPGNKK|7UC1_s!T)2z={lPwj5{&E|BmM>ejz|SE zEg%MR7AlYr7vR~ens-hGgA#6uUSJMz07-R}+;+h6phyLe_-l8x#tj=4|6#YXAi=v@ z_IP%X@)ivG<Zg?nFN(*2#7ufa2`-Ur#Fc#IP-PUO&eOHIalG?f3yZ2hcHZ10)(+r~ zx&c1o!t8dV@J{qUu=&JSGBmY^&^#ol>-9XFVDp;M-tH;beuF0e(g6Pe;dq)DZ~%Lh zI-suYmYo>J!{c}%vSIY()HaoS7!Rtbf3c=Yc15CYysaC6k-o`e$PfafqU7h&0hw?P z3Hgwku!Gq`@5F{5tN5@0*n8dLL|dJDL>gCU@cF?+!Z+RP|7j+1!Ovt5j@riZvRh-? zlLP|j?oU@Ry$lJk=fw}MMe(P`m^SVLvPir*A`e`o8M1L%{gXF<kK1WJ@bDKT*2Nn> zAKp*MHm6ZzPH#w=MVm(45f_8-zeijZ%1i*DT}VP7`!yM;yxQrZH4n!Ie49ZBmK&1; zRi+?EPt12Qpx~6y8Yw`P9DI_<=PmA^2?l2b!Q#^L4HVFHKC%!JPc8Tv4UnYg0`>(* zDodpB0XK8c`-V8#C3m3*CM)@5V{`kwU$5Qh@@5i??D{+|xFk}sDM@y07ECTy3><z> zpSz}>M!xRk{wq_FEc@$|-+#}hqwDo@d6-oz`jac)2R4Ov&f+<hC3!T?iu2)GP+IPC zAdHs^fIa8O?48zkY{iCnopbpw@pa>4*91epPKHn387lm(*J*8$L1V1%534mMcznM^ z$SrFxeg?;(^~nXg$D^mwSKB(24lJdHwycG7QsEqH1sGzZ|MOsWV|&klRGiOS)Ri-{ z5ca$(zZr`@V;G8%{h$v2hwn+UE%)0xo>E&>W&w$bq3=;yvu|G{iEBWP6u7OrS*`C! z-OMpAxQ|xOuuZbIZ+i^*Yo3W1CI(tHgU1R4Oi$|1bsMoEpgV^B)Ini>!z+(0!OalC zpm&c<KNu8jp4S+i5ybu{`wbh6rB5{s%WrQcx&cgjdTLIQ!vMx9%K9K}bcx$Qd!1W8 z0%Rr9QtO%SWh!ULX=phntx&cH9Lm3B0^%*Lf5H1ed(8}Pa|exBsqQpQh1WSWzFjR8 zP>HE6o{RI>jnqZ(;iPcKVZa!?j;cae_>s9G3{R{iouIS;h&e3kJn0}nd-*y842Mrx z;bzWXX~tSnrW?(bV<1bwIo^^yOu1n#dMGyG20h#%(U{CGRuCuo&!fy*t=JrjW?lNL z+LD@`bVE@tY{Zlz6bLV?wO2x^+V+;8OVJbyL97J?{vR{@1a%VnH}#*+Z{WKc3NCeB zRsj4RIRAK%(TkBmNZQR6`>OpI8pOM?JE4E?sB|g)VZ-OLrBm49lINH^O%<vkL<!U> z4Elf8^h^%zx57HaYT#N_g2QhQxW#5IXl<1K3ymBu_p}G1c=z?P;GM6C$0q%I0a4@> zPBENxVol&-X`pfNrXPUlp#<ajj^@)xad78V7Tx(D*?vFVQ9s-D;^QM97#^p|vRLt1 zcDck@ZF2Bgm8em9lV{+4T(SPPaK9X$0mmIqbpfd6eSL^EmRuo`a~u=@Tb*h&&&&)m z?{pYd>d6W=tk}!>24#xqOJX~bGVeDKQ<dN?W-@=t|Hwi^Qk<L$?)kT7{*1cV-eMRh z!TeboHHyGyR5wD<DOjVFbTwh_Q=7Pm&WY&=>@3lrCPS_C4%(bq8i&sI0<8Q?lPzdl z!asYhWPiZ;=54{>gVy|`8DytUn>^{u4v>z!45lgz{!91aGZ6x_<llYMQD*%7M#(pT z*+vG;8$U5iP>*}hJy>hhTj40M{Z@8>JHR`xZ*3#N=-F=l16U-vIY1DlAP{(DF7cX` zVxio#S&bNUu+o_qLqWY9_XvMPVA+_=EamuV(4+XH3du~?K>*OuoKNO3)Fh26SqVnj zg&ozbtAP@!f*NbOyACEgaWT^Dv{|y2^CI@mm{P?0F>TUoMd=KCjq3n&fIX^KegSwq z<ym@Q!PAIF=+X9(aGP7aX+o0d^;N8m^c?*+Xn3t5VEv==VKH{7Y|gE6amGcBHgge~ z64#dv*-946BaTWU)ofjaHqCgW6b=1Bllm#fPN<vQ3rJz_JbUkxu?fuizoCX4r}nVh zqy;+KXomYRJsC*XzI$z295K979%q0IBuvb3{t;C}6XKuBlyqMWfQbZRJN`v9D(;86 zmhX9LGfcBxg0|jHLYd&{#{CPFHP11zp>-QmOw^*+A7e%iI~*c0rZ}H3(5Kh8Eubc5 zHytl61Ae$WD9n>$#*YkW8!flUagfn+Nso*Yti#ei1_6@Wb$ena&3_FKJE5J~Z$kxW z0`}wOGOd&6tbkh?<iba#&7HCWn~5>Xjj%*djH(n-B0I-9SJ4?%j*4X(X=MLp*v|6@ zctD>)p+anJ>y9@`Xq>KY0PJmTQ*41WYs<ab;pGp`dTgu{^wB&LHQdBBS}xM6M7)7m zY~D5re3BiJ;YcId=KV24^75ui6?b1<QCS%egtvU194f$yIOIP!em*J2m+^1)$WA%e z@|zW&mrlX46&g`4DZ^X?k%!)+%%ZCHG+5ruB3#EK=sB-nt^Tb6wF;2Esgdu!ep;Et zzOM9;ZIEY_9i-PsG@PR>`YcN&8eKX&wvP5$3k%Wm$p@S4*o;U4lKeFU0l`a|>QQb> z80WGw)!^$wT(ipaw`SM`n-kRMm1pdtv+oJV@g2|jYoQ4Qv2gEfq)znXs%xDW%!1Q> zsq(A&J78Ig;f@$3Dn|=55Gm^w@Vh08(jnnxdc~>nBGaUE<kSy#>b7+Hd{cf)o;msv z-FL#oA0sV=`2<{E(WQv=lHQ2|J`HGNnFv&TdLZP;?Civ|+h(HsJUf(}w`0jkfS=Dw z^aoFc;NVv4b!%h$1rZ<fvkTLEfoAz~0OqTLdZBha2%4cNz+)uBce98dPonyXQb@OY zmRjEy<L(tU^)Y>8C>`TcojZk2hoacxTUH9rSzek6xaby01p4yl^)#l?^pc5yaD(wo z_u#DmSm;;4rKN`Hs4)D6XGQ9B_`(}E?al@_RXWFa@G=YDznjtZQv#mW=Bk@%p*BI3 zQ^sIU?Pa``D5SOc`Jx*|6+2lgxI&`3)MWO}3<nz7x9Lfd&xtdbZ35NK`~OzfK=AsT z{GT`wZfV?qq0A`qVoM-#_wR9gmtSi?mw^KVbMERYz-UEJ9JIpuHaPk5`QR5qw2r2S zd5RjdHkKmV9Jyy25Kn@=XGCXOYJ_y5F}SW>kgE9dNazeZrG0!$;??pZcC)|24}1|M zm-+JctlrDz##@lcRwLzP6VHyUUfP5}`7Y|>=6FZM@}K40qQem_;tu3PnZ(V9C8)lP zUM5<1=Oc#0F{@w<yWT^}9psiG2eMo$U>GGLQqjMYqHha`AiNeK?72C<-Iv0-d{+5E z!LGZ?^CLF7*{n%r_;Hyrxgh766b7t?vzOydd#_zGMrmC)f9kj30S#jl-$a7Mgo3jZ zjQ-IJs)5$3ndPXW=tIEC$|F`;^P(K$Cv*^sVTl4LR$}n0J*<sb-pA(NKjY%Oka%3H zHc}OSUsZ-pc>k<0|H*t^fr@4z-n0W2MZ!|p2gAG~$9D(8F)O>)g6TaUPeOh|88p^L z%|sK!(iODL)v?ydpHZXX*X}VCFpD?wc6ilFdy{{R&vKH8;a29Kgp?@C;~_~j(A*&> zU)zpTtWWuu>J~A;!+|8Me*atiOv6~#c0L?B6wkIgm~$z>(n9wYZ6qG-?K$T^*&L|y z+V>J4kXAELd{Ajx7{T}RIe*<9hCx9{t=jo_%}?*yNI~Me)B$Rf;gmziK1+s-S?#WI zK%{raP+LTI=F@)5Z>rN`<0HFfTXV$gk?tt~OEmUr>UsMkixT^|;tn^(^WM7kIacVL zi#?0!Jbo5}^DO+!C1OBq3=B_(1pd0C(`0#@@b-1miq)tto-`=9<fXnCaJk9SxCBEM z!1Jej<6W3n0V!IIEC^tPAiRRl86sX8D>9JX4h0s^LDs$_x9Et?9q3#B{2{XxRgj+f z$o;pZj5u|oW{(V2Uo^vL7<5tI$YR|8FHCZ|MD8&|jd+?4;S>ejh%>5GzcBrzTumWP z7*TMR-%RMAJD1qa#4+Aqw*Tue)W5L_zTb>f?K*yFC-p05PRjP8^LSHGZ1u@;`{HD4 zd`!$41v+g)t?5LVlQzcozYuj>1o#98A!Lt}Oy(wa5ScI}=X8aY`vOhHM~&hlNTjJO z$W4TPLmH?NU1u2|u0UCw>Y^YuW#4Jb_5hC5zQH8qRvvQb=4~TbNW_h>-0eZ>EiW{S z|Kf5dH%slZE7}r%Wd8!jZ?Z+Gva?s-q&H)@XNx=;fez`{^b3vY#N^$wU)iEA={Cbg z2|p!=<j}z!)3?SSxFdFT0ej92l7sFDL-qTs6>v>#aKSLjEOS+dF$aFJX;fy;85tC~ z1;rmoM@356^+Qh#571?>(;6FbBPmYKO-B~|%7TQtcId1C{(;KcFsxyQpxE+s!!V~h zc#mid=gv}Z)ApHgvC!vG=Sa@tCfoJu%|s-*;{+}lx;8IEP<F`}bL?{gcV{6;aTwcc zfB0J)p;erlJYAh}PqXmUtHO=>d)E!|=2A={bhPlULQLaO7)dPFEC!DN%L?z4W2n8B ziP{^lV*;~3as<;wX64Mbv|`q{(G~f&4>M2Qwx+eTGC$9}@YB}I&Cu+xEudu*St21E z!%Od$%{37<yzE}_0YhLa=R`Trfn_4zJA1oI0)8l8R<By_w8apyeK)Op?|kgZgpYA; z$va-gf*sO+u%#ZX(c)3;lFa|)>Rn_z=KecPO9R`6KK{b?nZ0GBZXh-q3!;XJnEK6B zH`MyOfY-z=a_uCKw_Ue|LLvg>2S*K8<P$KVq!8BajKeWP#>@7mdfu$4eA_|JD!hv; zyNPT>w-};ia^GDZ2^HD*e796wKt6%cj<(-iG7^uu=~WT8TBG#zv;ONm3|#xb1O|SF z6_Mr_kZ8E|{fUkdC?^K*=+@+%3$<93onz=y_0jwMkK;fCg@st$ce&IZ1C{NBeFvgj zigi6l#vq*LZNxb8ROI7UlG<VyNz%tR|7@87Ax#4cmTP^&RscVYp~lrxse-|=xxvRY zgBcy-<T_1wD?mdCL9<qqmA6#$a<qwsP8?Zs&uEt*s_WyHJU>Zx7r+5{k8nuphWS6j z?^R*?$Nt+PgFQ=E_@<B)c$K3e_5LE)Ik;<xK)4rR3B#bb@ysN=3D#0Y5fI>Ow{mJj z^P?*-fh9<Q2>xJL`O;e-Z&$m;#EowZPOKLU*&Q;(zw4jV9KR$XPZc)hiK#m9g<)Sf z_B9)D=Id}R4DUa&tF*gB!$0C%BNLC?rc0CZp}xc*8#KXKLIqf0`-qC@sK|gfm&3IA zXRXyVRHI<&Em}$>x_yai=}yO(<2yg%?5fx@aw^tihF*M+a^zPe)Je`~V+IDqK5zqz z?~ZMTi{6{$HxUPY<nnkFlA6-#`HeB_7)@#<aATJxuywP&pW^*JhtP}|PSx(bygKJ* zF538Vh`~@#MiX%PZjdFHkFP=7itOCdYdX2@U{Oh%I6%8S#Lfu``O~x?Yd^}iv#~3y ztfeN-c<ixnUY>+PRUSoXTqZ<WRPL&n|5h1wOnBEywj3<-n+2>0mS-q!ws^~^T%A^t z$&udLV9G^p8Fdy`NHwB-m2tup)+x%|SyX%wuWt9n3`I|jom#|>oZUVIe6Lny^%Ao| zkWDS0zRsp9!>0*qoD!nqQVcRtOa%QW<GLo!I9@qc=MoInNq_;q+cX5tQH?VlNFvtR zb{U}!u`{Jf@RCCtJMVWj_Ux=VE{NMcPm<0|L*Sjw>mulQXIUOEUP<pgv!0`Ktr-e^ z89#8{npm1db#Kz%N2bD<MCqVW(BFU4V9c1p-pmUWoeah(TKLkC5=yAbedh)~6_&cP zwG&x05KzB>Am{VXsRfXlwI0kqbPd)Z1QfChy>U*y7jqNM6eLp!#Ef9pSE@w)Oz++r zQ|?RfoF?ubFG=)O+h)nw?IW8Qo9NCdhlBFZ`D7GjZp6<khNTmPt~|qiQzA>OY;RXn zMqWPOBK>F>==y!MmIE#bmenNH99Qnrfp+#-c60eW@B(-Uu<9U{>I8_X&G893B%}Rg z$b_`qiB9*gQTE9d-Uu}_gygTYVsih9O_ZWWt`p**H>+%^y^WjVWc4l>(vEC2os~cS zmY939aZIomZFskYk~-U>Y)5R2_XOYS8vvNc<EEE>XOb>FwLA}ZxeAWY@x*QbRN7u- zkW4a8I{RQ#Pd)JX4gB-qjR;;`i}53KZRGr&(nE-gqezUnH;q=Oeqe|&{Z8kqCZBC` zq4rzZENzMEZD((3OBU@FtMfQ8JbPm$L_C7l*gFTS1Dn|Umwz+S`nBSsX!H(3{YJ4Q zO#B|jHmc%d2SYgNc$N@O_u~=V{QwprpDFU*Mf{}qmf&CgpVcPIjP#bfD37Y2=(yta z7yrB}=rcPL6A|27QYOKO0)81nSPyi>!@9%jcpiKMBZiXNB@7KU{!q_lWTvlh(vY<h zJ~CDXR|1qo3Dj@{Cwnvms8(DxA9ip{c|)vjAvkDL5o}n6$fbZsZfH0bpq>(wcpzT| zVd2{QA`ERmDif^SdQaiMuo?TIN3ISriRTiguj_FYz)y~3Huq3C_fpTZVM}Yue*Mde z<;N(Uj}m?5UWq!FSCcx@^0B-&w(=}8>lJQM<gfB*tA5yQwN>nj|JJK_u<G{b7LL<- z{3W@%tEW_&!kTDKiRNL0;U>Yd!hq-a^88kRAs7c(!S0|*{dHKW5_s*8S%&Fjr-rzK zZQb)U8sXN=nywmdK=eIZ&iG4yb}bro8;_m~5;y8dZYt61M`f1m&uY*mfE$#y3H`Q$ zg9^QZ)IG2HEER5?to_Sddt^sQnEV%4L>SzOmuaoNMMilYVtkl%tnk*Rm%4LenSFk? zm}X)E64e_Vye@UJlG;UUpN0tbmcoC^tNE!q8p`_t-MfJ+If+5w{RA(llcw{$BY#jp z8s?Bo2X(q`*6H^tY~%}1udnx=0~R?D$D&9yYqG~6{`Z!hp?bZe$*TI2KY@C5PytsZ zZsHmh-LWAx_$Z$yQnk8V94V-8Z|OnyRu)*UfqYwnG|k6CeS~*_vXfJLU+z_ZhKkq6 z)VXj#dx^!sA?g4zJ(3y0%-cz7sL=2~^N=*fM%C051s>;<F+1gSpPUJp)*bfb86G52 z!@QbU#_BGouXX&oeeftL?ym-4cnMu8YR~TrvHX_Wnc9<`-<wz6-wXZq=TVuQo8j6N zmZHa&&Hdd6llkv+xEf0zSeDm6bLz|*b9*Qa&F890$MFOtnq!o?3Kim!@#K*&hk(QW zfQ~IT@b6SvC(Nd))C=w$k|}4vIY|aa=X8Kl(Tw?3Y>yy3Zm3aQ#g~VZ-UT^h`iHAj zt2zb~NoEQ0=-c}Puah;-eV|#GuMY3?-N+PbcHaiZ!T5u?M3gKbA9CWa(c}w8bSj@* z6EmkRL39&?x6K=4Hzt+__ihpcZ}PC2U|O-`RWqZAspXGD4c*n3aP5<##hk4SNy!~l zaFymEEM(Kz5fxwezq2Nd_`e8+Lq~XCl7Huc4oyh1fUxdyhzRO@PilaIrR&zvY_}GZ zIZeYu1^sc>cAwcccD!baz2(0#5Ru+T3k^0UEzLm7;-<zgRTL~cwPSnkOCi-ux!usU zuvTdUDJlX>A{mu<C-Lk`e1BwX;c(8)$+c=U2{<m4mKPtFiVHNYKQ{7p;0gtdP`%E2 zQ#CFJ&N1yZ80MvyaAcK(2S<+%$5^B2l--{B&ue7C9r+w_!zQxMTVn}VqVEFNI#F|t z%Z86*e57=}uyjBBWYAf>ejGBtL>{jnFIV+a=T~?Va~Ve=5knD7gr$f4A@k`q7sJ8j zj6f5!ddhC41J1)z+}S+*Vr4ol0?0cu!3ua%^_UC5y#JXVeMV+u<rlMAP1aP$$5`?< zt)Ub9Dc?l~(x%j+s@%@f?Bw)bF0ojCt5wk1?X(}xcfil@%ck1)a&%{(G3oK5hZZSk zzvH4&-2<O<^L2W8xO$E~@gLhm5v^5g6j$UgC8xda^J|W!kwzn>KFWx|>&i>W-Ws8x z<vjt?x?Fz`KmNW?Pnh8mr&3gsV9uzmdIE~TMUkN^s@m@8d~=nerKUbWjJ{9Y?PE0m z<XQYaEhr&FE!*+<6Ae;?v&pmq$#07-)Ia)xh7Upm?KW52+%NQg4N?AWo-$lK=`&&T zIlJ1-`zChNUh<ZIepyYqJaWn+*Y46ZfjoFG$vaWlQprwQt;i08pskNNgTteR@VS%F zUq<{uqlC7-D-k&epjAUFEd-^a_`HyKb%Wj70c6wG{=S9X{nyOt{rCD4HnMVZ5w>Qx z_rrf?wjVGKQ}#|SrtC^U{cku7Dke6_>Ptt-97Wq0T5hk~^X>I;<?#8^(81&P>}e|5 zcA5{n@A|nu<!a>%_}AX^^{48o%K6g-Cob+3xpa%taj8MsllU2dPVeXAd*>^v&2CXX zB3j}m8C<YSC+HU?+wpy8Iu7zo^V)1l><{*TgE(;nz86aW)fZ;)|6dxv4gWugWAE`F zhtr~Ele9JZKbBHM;S?x;m`BxG??k)1Nz|zZD%oR6XSZ5SyN1wy{RnCZd<=P%q)9(H zw>jw3m@cZVG5E#A^oxs&wK6ZTs+CIH6YuOTS=-73`+c9D4cx8T-Pp6LsylciGPuG# zlB~BtAEVI5>F9~{j26wB+S<(_c4;Q;;t#2xwU#beS?0dUCS3bH*siK7Q!F@ZU>s>d zIfFhm=NTdfnIYmCp{a>42ive;Twdxly*?W*fxe85_o@sn*dH;5nXQC5uNQB`fmZC> z8TR+5%gf5k_T*`6wl!^3yE+VSOM<Ej60~(#t)K2f2fn&>_u!as_uRMpefs4wS@Bf0 zA$QZK{P2Oor1Db(PIP=WV%KEDO*mm`pcbu9M81y1SFB?9q!j9^gS?cSSd_F7iv%EF zEz}YrfMn)CX?xd@rWdzX1)KrD6utty)v0Vg_?~`}FkYbt8l@~WHdn2vP`s{>St5hK zLAlT`&gMUadcePdul+F8yJLNHj+Up~iw+!;r_`FgK7$$hfm|_?y_c^%wf-DAlb_!y zdlXpUoq@cyc8ht=y#cIHA7US$HqG@15TIeoM7^NLA-kJeE-M`<dUEyBn>&r&-8b_Q zax5@!Xpa9>Y|unmTqV~#^v;2AwY@qd6)U&q=5)6PS9qYYAr61eE>Ec&8h@ROq#O0E zc4w(>__jiPX@yqJ3y0u+mVDq<K$Yc&e;4k%SW_~*rz^mH=y5z-tKO$^@aAR5PDQ`i zt~Y%2rYL*_5txRmNHSY|G~g7cHw|G2HguL;i)>1XsOF+ygp#l?&E6D}bK>W5h72WC zUuROU;0#LaBlS!zT|^=9Mi5WAbJ0P7fP313_Y09W!n)z<4_7Q#{&3h>r6rUT<1=xZ zVOhmM@-5FhCL_Gw!~c+yu8+iQ4h}7u_Zg@@&ibyGT0Np=xq4ol!+@?o00}Wfz3pSi z$m}*XaEx`|g%zcD2v@lDXJ*JbewE&_2Wo6os+W=4!IQLnXLz38dp*emj@KhI0i(Km z_U57=mA8cGFF2doqI*4tzAn2#H8C(f2`uG%gv@#4fRt#i&p?g#B5J8Nu1J)7Se3d1 z=yXwPv%dfx+lxcKB#(2EQ~T#}#w~JZ(Lv7IX{DbiP!~|dJMk4<XMUeZ)8Y8MFJRI0 zC;`9b{?gpU3KII)n0N4lf@uY+6^RXmdmE*2WA}x)25O~VOO5qK^=czYTBXN$VaVt< z<oJGqJGqh!H*Tk$9Sx3%{Y&D`bJ9`A#o*u9LL2V>o_D<LztQ$%oL|5h3<+<lmIFDg z$O$k2SQu_TAdUc~Zo-I)^KlcG6##<-x44o;;RefNalsetNe2co>)_)_=X(K!>w#&U z4u7npVWQ<UuDRKRNf(>}xWZXBN9WTalXC@X@689vSC{bl<(ioA1ckSnQ?R5!Tnh)B zBaG5g$N(o4B4<|4B+$x(6mnl}TFkt0K=X(XXbA7(Ic0z&oe(dzm|bceS<MZQx^>}s zir-Xk4w<Fl>DLJi4$!N~n)gk6(!1bw|Hdo?J%Gy#=3|dNA0|*E$@me-;Svxuov&Y? zghMpJ@Klwx(%=G10Aq}>0M>Ab)m481Ya}huX@Y;`_Ix#`6qL)s)~mQ9Wd_#6eimA| z*B8CB<1<1{M0+vzM8FPFc_;*>;5%RuY%byh*A*g`@ll$&V~_9!<R$G7k?Tz3KP8|q z6QgBq)&RNj{^3vYK=^C#3->n~Bwzc#M?(TEg_x=0$p+1oAdH<^oHv7JSc_G4Sc1-* zC>o#23&zc+GN;?fR|7500df~2%M0U@WF!W*l=1NMXEjT~wA5~kixD5U)@{Yv_#Ee) zKr#rf`IP8b=Nbg0<_l&9W`M1m&z!O7DeZSeB3%yl;4$E~m*<^{aBJKhA1X89)8%3a zR4m9uT8?|5X~n=eWr+;zj~!7v(Kp?yN72Mq^8c}|g&<c2d1D9Lkn8;6djd8{sc$Er zWM(MJqMCjwHiY{TAWr`@j`z#u3#Y1oV_9NdZ10A6JR?%b1b)v9@rP@{OtR*a@O+Vc z8I;F+Floby2@kEVd3#j-w95|zvY2kgKCd9je+1^Iu>iTfifSng5C(1I6K{Uon16k{ z_+F*`bGwEXav&P3&3Up;LKSKLgfHwHQ><6OhdTrv9acCfGzECCT})wvWnS`12~-VD z<&TDX26<;&GlJT`lNq1Zv$!BhL_}U6U%#l97(ED*f1=U^^X(XE+1*V@RoPvj45ch~ zwOL6oIOuGDf;bw7CGF~+EowL^jBqq4Q2(B5;c7Fl6tbhx7!Et*^HT^;wc%XNk~l$z zlI!PXk|A{30Xs2!XuyV;7kq-LtlZ*S7X9ovfdixYS4_}$6d6ealg{HP7!^AE94qw9 z7WBHU4-xaI(t4;*<vqIIYpi5R9wJ%h?kEIpbDzh}$T=rqo*j>h7s4{YNJ$^xG#FPX zQXgT5>OLgxxzAL>6sQ4#=V{OumO@H^tGia;1eoa34B7$M9r%jc;Jfua=`WG)+O=<Z z51j(nqY6YS*0i8{Xy>s6UW$`Z@@Q_A7J-8Z{<vq9G{e-^esr3dV^k*BKBLH?xfTvB z!?bywZ8{oYdWx)WgMo`&HJXChVDFBvMBiip1viVjaX3gEm1`t&IA$~=ImoDJSt@l3 zIGAPUK_((hKi*>-_%JBJ7+HQA4!SN6D-S%KFGKD|BV8)oR;&w7VMKsmN}`83oyviV zOcGl%0p1(v0<K?GiB-A@*q+f8Abm8F7#aGjZLRH9`0SiCZt-su>VQ8xRx{-SDWxhg zAy4(E6xbKU{N(W1dZ6Z^J)<oLkNE*OJ$>FXvcz~nZqVL7bc-F(gM2jNuFJfZ_TrCx zRynaOf+!Cg-~<8V$!cZ0L#MAJDh7|Q<@`F_y`#8V(Mq3P7Eam{)QnGzif-e}AQ)=j z7hnCq%WdD#zp?}OKC!E;w~U%QdcGo?M-T$kD}wiST$<5dyKTJmOBcf{vY0&-nrO4- zAPoOHoFIT;ZVl=K$5F+4z*x6?=wmo?u|COp%z6@g%aVLe4b-A|6*-{R&a?fsbJ+Mp zV&$hoSp<6xwG_Dui26Q*uv797JjQ#FGOMIwSF_XtO~%wJN;^of*6Y*DW~=l~FKfJ} zxOH{On<|FP0!LJ+dWZhlby6&^0eI%d2pXsyyfOfZWZ2hcz9C+vV|)F~VI~@MzO*0X z2rAZVH7^C8^nN@;aWM$puj?Iy?74FB%k{>fef3nlGKuG=H7A0d06={%kS|>CwT>MJ z+LH%=SWt0@b?}eQBq58pa$i#EMaf5S&JEA=FytdHdxkb67gH($Z3D{zP0nMBl6{Rj z$3UET8b+%+C)E}u7w&y}=Gq}cqMEx*I$L~1(F%Z?{xe>=sCmlaJG)Kb1?Nk>4C0P< z`BzC(eDnh9_*Lx&HQK6(>_3P#;`6;!i!Gkc{vIS{cV_c4BRmzZbY$?n-QuEUyXWfE zO<_t-yEgal)*ZvJe+w)G{Q2$8p6b6xU3eRJz1_5mstD)*EC5RYC^&Hjf3r!{5|DtF zYamOD>%7(B?b|+TOG<0Op0_8pMhsKCv{YAtNDzY`fwE5FaNTe+(KvA_AhA~+=WW?( z@aO&KL}Wh;{3go;V=kpH#EW{<{~%vDwPLN4gp>Y7<=M9HWxp>6{hd)&uIdG#G4NfY z-B5`~i6;P@OlqxqKcE)99R!`R_g)&{l@>u<IvD|$;=NS^R80cV(UY02L(cLRtBvSV zYw9rSXVy)S3Iz%%&>Ey2sp^#2Q|H_ft8hFx<Y0BGfF`O<9ykP#wb04oci13FF(+)5 zC(zk)pBk1eeCm-S?T2}8NScq4Y|vLLZ0nBgFX7CK^57T^$~@q}R0I>dj(y#*9{_Ga z@jJT_=f6uDDm$?urEH#Fud*?&wSP<AXt`78%sRWV`XGdl{f?lQCk=ybV+yjks2TL% z;$VO<u{fbU7c@lGRtgGNm2y;N)=p1SHmfCfD0TL_ME0e^aXa)@5U2<#2-uWG7d=>^ zcDSIHm-~${nqd}-k6~k6KlwsP$eZB_Zov=?Zd7+hCSv}h!CcyPj^k537p{~_4;!g> zV-FVZk(bF^?dn8@Fh8nXgq-&~EP}nQJPW8IHwbD5FlQTsTV95NBD07M>V84`dr(3d z!4Zd;#Xx_q2L7(4d`lX~@5(303~h}R`eguLn%7EjLQK;{ju3hm&SUML=57FYMD)Ku z2X-L`+{`=yQ`i?k1Yf@~ZBDdd#eUrrDfV-58z^`WYCR0D!j57Q1b?6cmjRa#JO2w1 zkp}AWvFz`>S(^%pzoj4FsIv!C-!G~clf2EqRZ(GI-ycLBQSFrmN+6fdh7N%R2wj4Q zLybu@D8!1K)e^KGpcjMpOe7kf1j_!-YPI0M@Hq*!PX5�#d|!I2eS0z?8+?twq%g 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 n z?O7r<E{G$Zgzj-fD}jow^#K`PyX5?<_L{ou;_M@8TT6AiB`J-)=U}`1k2^=bqPHop zFUXpTW{Q*hw2V-J<;+0Ctor2cfXJU&B?e5gFmJ|E6ICf(aGa-d0p@TRGePXgRUo#2 zpShqK^$I_w50h)KbCqbdVj@OBQG-HLw=;5jHPIJ0wnx+10NYpZfd;!?xPLm5hME-t zaa{*9Gzy2*EVCFy&=qvgT-YPXUwa@YsCwJvuTDdlH-56kWI?;82Lj68Wapnzy&|A0 zFW@<7YgBeorFrF9O5Rz#IO`v~nHt?JKJ#f$>{eE(vNHxz(Mw3&4lA0OLBt|j>f00k zRBi4ht~8Pb_t{E2XN+zkHgyq7QIRPi$ci<;d*z}|<L|1nl<I?-y{vnPD5QR6ga$|X z{3A3NtQM($8;*nxps})pAo+PXGMt8Z3fUQc3GVt5lpQmIC#`r@+8S#4##KKn-28o4 zn?KevjJa$>#L=o!eOf#C^pVWR#gw#ZFvrB7z~WIJK|*oIqHsW_1yYI)aanc{PhqG9 zpq?0t>?y396!;j?1bBy#X+Wkhez<I*wFS%zI9SI^&QLf)0AVO%as70Cz&JzBA{1z_ z<+v{3N?=51>)ALhPwy@a@ti<v`_Wz7-b%WnT`$*pE+SJOIky`~pLL0O{%A?Y5N4MB z)JNCx*jLvakb|<TLN4dQq>EF@@sNGtlm85h!oSv4rBlR9C}s##MmAk9@m+4Gc3JXv zvs!*^bgf4vTScOWxJZydwFc&>!!`XwQVUFglZO!i75^>&+kgT$_n7z{{0<xrIKgQU z*#>A?1`I}Q*l%@7Qyry%0h`a06MC)*NqnKc2i%vu0mk#6A+~?B_Hqp|jKNvUoK|vs zdl*Xo1&`RdX4G0aBHscY2tP?-u#K%*WGZWW_kHg*h9s)LZ8tZ=ip10uhEo%`D@ATU zT%OA@^5d+Q!DlI1v>8IHu4DhH$j%=qG5Atc+NNK3@aThcTK8{PY$Y$Vzzdo3l@E65 zDEX&I@o3p>En}b@<d-o1cQRmrk`34M`FyFl|I3h&)3Yl`yGTcfR#JNRG<0Vw%5KCJ zu8%>IpwQy>!^WF|Xpy+OFCLB8KImh85E`Ee^<Al4O=CvY;;1iNh%tZ%Z+L2u*C$}` z{D7Q3X)PcdAf`&`^pdnrzNFE5Lh^`yw8u$~pg<UzkAv6c>eO*>K>qqqL7Lf+FngM; z5jyn`MA24oDdhb{m7kMTGc*GQR16+dwFi287r+6;V~(WP=Ivq+V;8~eWlrBnN77tp ze+p-t$0Y%)0W?VV$||q^whxIhUtRJl;->x!234fHaCF)hHSmf_rCIC6a^z2hB)48> zhG{A@|1m&uFkNuzY7OEY%7fm|Pp>^T-}gc-1rs7fe!CwrPMP1n%|lN6hQJp4MXKAN zd1&$O_jBJ&U#l*k-m4ec<5Oh(OJqKAata{vvJ3o&Oew0X2usBKX6e=xbHSbjIGc(x z^7EY4xI4Td^pSZkPMwzAb0UCtcMA_Ok8m4Qm!~c~&|hIg5dgP=24c>PMQs%)x3`A8 z3wtlS`J=JoUzDNFc8>s$<r@9~pO`(o-It{E=-9YQmB*OBg;%n!%jo$N_8Yo&mxu8< zn=)s?>NbrrB!<}#LDKMq=YWoTvPp1<bScaHu#5ijCukIh<a@v*paN$bqsXx*7tw=S zlilReSA4Aq6sZ5>cEAX?ckG&tlAydzhRpz;lzFP2d~1nBi*aGrK6;9ka)8@pA+(Hc zxs?3c4eOjs*Yp7WE$4Vr-PTB@?oZ=F$EON#9+4y!<X;v2yw9Dqe!a6r=SGDhh;WLt z33GeAGP20)*giakZZBik>tzic!SjG4*@U7n(s3A?Q8KcMv{L~9@l|Up=l7y055R(} zu2F?Y=Av~gDaPU93H<C0xnPqB*s5Xv;XQ}atYm@RsI+`+60e(MV%<o=0Tv-Ra}A++ zsur@cyR|^zZV($mgT^{Hzxh$X!TWp!G8AW!155BjWz8~Zdh#q4OdRGqDn~%rp&C{g zcbZ!wz02e$+MWF~nkf;>NkCmQh2Udjph`yc^-gXE5!M^k4n>qqoC%o4mS(MCH`h79 z4&EM9_>odvU6DIp&@o!wOvX?;)yeWY|D`lw?a6VVts>BB@ULy?PgWA@mTPsw3`UtP z46E?XHs0rD9`Qq-k-gQ<5`RrH^4H~$$Hft1p!nun5TV!Z%s?w^Ea6L?DHG^!+Ep=` zAz5MKC3}^axpoIYlTqTBIq>kGHnN@QyYT4|xzS*S*i4PX(YD=>_Leok54`M_^MTHP zUJh{Ij#5u`??J*X3bLo;0U9xXL(pRpbs#;&mLCQhQ~7j0UmxG#<@9)coZfHuM{;xY zxH~v}KTq*X$!|~Y&IS_2N~_l;yK^!|w-3d{@H%QCn+!PRr1`D3yp8*r(xebbX!}!} z3{urZQz1-%^%(kNYb|S7simpA|MKpz>r1WrhAmS=xKb7&zF!Mjlnt6@EYuC#Rkc`M zBSY$3yfM3YqDLK8;e+tFb|q9pb`<}Xlu+fCEoURwPx_Ux-ryil$hIJ1mzkEE&=A<b zYwn=;_&hRF4Lt1mW~1{F-NYXuiwu}}DMB<|0z;m6user#_j|f=xSN50i=*6_&sMJH zUSkwn*$l;4ETQ*7|202KLY{z+Le-aM7juwsX~2@_c7^T#!Fa4<yQ)LiHy>MCC7KG9 zBK7$q2(kxHPvWbpe4FD7T}BsAl8SfOV%AftXd{h9dP~+I7f|2|G!0%0WnK|ihL5^Z zkd}j+u*2~AflR*$I^B3X%MZbMQW|sXE=%DDmx0msLZLg2MnC}BgtH}9ZN=pxB8^T; zN|DVl3hUA%>$wPT<cxPO>eTsy%N#<glKH&d#zWEw1x~LS*VsURVa|l)EAS<&|KNPn zqa7TyZE5Mrke-J?NM2nZE`M+w6BpOR1TZONenWU@{{EM8P>Mf@<P8$w%F4yd>A!DL z*du&OPvb`ee_~~AOP-C_ejFM4XX|9ILi^I>JT>#A!)<;Q4;Mdn)cBu<=heII@r3Z| z%TusYl%=d}9P-UMIklT_3{@HbFgg8am$>833xVucHjht{BJ301<wX~8iY;H4No+&Z zvFvWoe`>l!7OshkU%wdwss9E}>}dQe>3#)WF}F_Q25Z9219e^2-}rF_rv`UN$u`I6 z5e_vS!_+G&JZt<&qF=Y$h(p9f^TVm{mkV1j1OSOCH@gb%lrYi4xl=o4a)^Kel&{&; zWbylBx5;xN#MjgF^Qrpk*Z7q#{V)GUHLRFm5QIOVGX<Ro8Z#Qh!c0yaX6&2ET7I_Y zDo7xGODgWxnKfq7v$=yB+E?wzqt7ahCg+4cDROceYN=1Ur-+|Eq@hRzO$Q#kqDX|H zle&-Q3NDnq>KNO}s6EU%&TsjhtpW)}C-B}8$SkvBZns$7RscAa0Eu`b^*@3!?N%ff zOP4G#UW*G3@_f^o?>VmC>!x1<u@5y?oI?2=$*r`1KhVGr?#{&ELLtnAW@>9{pt_Cr zXS3#Y7H}JNg)7n3V0?C?ww+C2xoW7ESp}1{R(HKsVYM0jNFgDXisD$BFe1VFpj&v5 zp@JZmFMw;;n}J}O!m278jxCp|=BVd?GAuN*a~F7S07n_%a=!#)t>r)DnNKHP*nZxQ zUp5|}HePzVKVSDG`=zK>L%iP$@XJE0s=heJaQU!()E5$~Y}|E(74q<`fu8Lw8BBXv zSYo}Ea}Q5b<$Qk{G}nqqfWo2=iLG4Yv2;mk@dP8dqkxhymoL>_a+6g;P8bVyu^uAz zK}Ryx(h;H-nG_@PS(WYMU5mL}V4>+OXd>UMHUbC+FRj)RVg{pL+#8^3P-<`|;JJH% zL1kh)XCkU*i25qChj`d`uzLlZ64T5n3(}=wHkw=5)J*3)s3rg(d$~4grY{sJSptqU zrmm%Y3{7fHz<oKl;dQ3$pM)0@=CP2f1A$5Uq@((EDM!enG*$;{^QL2PG~kSrx!^8W z2nIo)AzgA{Rel1#-tSx4YVG*Eq{rW->LO^1Jg5kHripZVkBI){-jWCDR4suZ4o_o9 z<UNp3Ty$bV$zG~99u@>79v(Of$?Q%qIei8F5h!(~`T*9dy%?6iCB;B@VzuiF(qs!L zC>PRpNiTuMw(H10j=fQD;-+^sfkSdN{S=@JJ{@wj2jsrVtT{X#;eYD;hE?f1FEP`) zw%efq3NvWJl?1rtg4=NOeb{@Oy1}0<geZpF>E~P@A?+@YZkL`2=?1)deokIG`37ir z^|yI<T9MJo=6Mc|ej#{u1mHM*%~|ObGH^Wv=HccBKm}GB0zwnkcceZ%#=7#FUcqu| zuH$iac8!tSm@b9w>%+{ZpHDT@aW&O%{{slcXRNZHJ4L-6fYE!n51REkCZYg!>sfk9 zQza5%d{)<ljR7ykg~ja92$oE<^-HHEUW6G4TnawuIOx<Vyt-R+JZS_cES6n^E*KTO zormeov|f3LiSGkXH#qGCIueu+BD!mG8~|M=_`=RD=`WSA+Dw0fwF=ES%{+)C0;b@v zM2W(B4A@Os971+Bd0a7m#AicoZN}iFlK~Xv!u{C+grLJ%nWI~`<Zl<P>c%lSO%Fjs z%@be6M@Vk?8;Ug+Ln<uu#LJlSWpT(x9@h#f2cBDMhZq%4O=#yK7|k4-!DzqMtv420 z6ZjPe?uA9`8JFfFII&%NgbwntVxEs`8umt%{nTPXm9y0N?J))}t36n7r^U+C2*pOP z5upe(ht?0p1%zh<Vgh1B!G=BnT92IBQC0qi_X=%54>pSZ3_r5cecLu5ntCtjc$$lZ zD6Cr^(HVA6p}dhf>_pxC{IQW*>(liGFsnepcK~&-G|%_A+zR*Fjx{jYK=<*da=ccX zX(AT6Ha&bmu;J+Vb=L|!>w=xrb<@K+W-KZ1Fh50;9mml&fK~WJSSLJP@U8%GbC$9# z(6j)ni4x4T6z!o8=y406DQEU5P^Jy#Qr)dneo|*g7ufu@54V`Oc;rF3l;VToyNgR2 zD^64E<J%G_&#}b*2bG!Qa~~+Lq-gXX<=><;l&GH|Bj$<))`;<Aj_aVC1)jw6tZWI> zAq})(JGEtW5%`!X9*ZzwgaHUfav1-Zl|V=$V!4Shnt13c5~AC*p)rYKb7Fq{IhVA5 zLY3&>){TN1(7k3SLy+|hEZk~q-QI)LnV*R9QjV#~0W)Zr1^Q(-1POn1wau3Im=M7( z(}U-U)E&pe#{ZPkSQM0PO7aRkn@xt*bm$vYTsJnPI9Ey*&naGyUM0rhHFDkRp>S)c zA3M(_IkA>xAXi&Q-ujfy)t!5U)<r_l@S#z<PbeOhdv2GuV764knaZpdfrT-HnN6v| zy6GYmd&);3RpDKV=?{Xgp0L8@tFIhtLqLlZ;Z1GGHFaTv#IYFT`9WuQgoM+QWQ3{o zhjINih$?^ZVuwQ&>8yL2H843{GdzS$KB$0n+_|I(F-ZEw*I?bjHWdbE5u~(1iJLW) zT^bYc7?dgoblq$9u4nUu8n)P}yTn~mq*3M43^lj=7#aXEzG}8KqyXiz%y5(CNtduz zm>(r;(=BNY<Aip3y^z&clBn}K2X+;=+wIc@o~UDVGJaeV<ljfAEX|=B%y!|qq5ktf z;L=4W5YCWZ-NtViw+aqCPJ9L&Ml(-|D=G_~H~lD$(d#T<53(ee7v=@fM2zgJ0g!F` zXx}v2o`r#4FZS;Kd#*?a1LO(LIEFwbYQk5F5#`Mdun~Lo?RW4Z<IG1Sm@F)l73)Sc z=yg864XzQtnh&NkXq>mJ|Fl{Z(4<SeN3eTv&7L9-YP!n~+{}Vfu}zJX8JQxv_&M0} z8Ml>Mgb*h*%EHu$yU|I!oo%BdA5x*6j=o4L&L+jspydV!qON2R*T6inv(IWkEtJ`0 z2E$a2m4x5mF#~O<@Q3G~#!nT3DiR0{Wl8}x?a^OpI{JEOjmR&++PV!b*6?t+8MI6` zOZp#GC41+HQE`~9F-A%Xb0H1hg&5_UHB1v${O*^4B2@bIhCvuI2m$=(**}IU1_2|@ z2owS(C5rSHT>@>>h++>g{>Tm;q+IaR*Lr`95)6VfQEC!y^BwD%8{?4Sa)rTMinI#U zVdg6HU3&y3!ld9N@rbHIqKbb^0-ux70NHnl>swsvwLmDe8IbvxpZcbb1SO`cncwVY zr;p65oBK&VlhQ>e4?ds!<$Pa*M`QlM2Q6-x)YsOYmV<g|ps3zn9inKPg#Fu_nkK#G zEW=eRfV0Dc?hr{Y`yAijF_$o^ihGgn`v415*dA%Fzt2F(<0=X;QV0trL*bv00+Y1P z@$|_QY>UhUqN1zxW(}XzEC2Y@Q4<y}o0-bs@ZMNOS|JS#9vM8q>7W8ruzOJs0RbvP z|BWi*)-ik!`&nfkz>;l%!Ip_S(VNkv=i=oWjUbP(A&0oAPXHxGs)Ov;jeqno)F9)Q z%&xYT;dg4q9l1r=`Rna{L(~FqSx%-JEH_g{;Z4Etf7#e?s;J5OF9Iw&Q}Z<w!Y3FG z@^wOhm-WC#1zcNW2^2zWRBrh6TfNhT7TwID3ZpFOPR}(lGt9|vGb`hdA7sd0HS^^4 zt3wHknwmPNRlGQ`5_5gOHFO=xzOl-ic+bSYMr?O?7#K0vQ(WgPg>N}4tK9laG}^GP z3{qRd`Ob6Zhn#5}XRWC-EKkp-9|oUvf}&W{%1bge0Ax2Ybvir>)LIH;S=h*$i%Fca zNP9b<<1@Hq6_YX`F=)d<R4`^mz=}<rQbBeadrSc;rAU-2>M&-6-xPZ(E^w*ko&5C@ z2^arq(+&710X4?L1d*)^l)+l+I^58Ng*Q~SRFV^WLfA@5K4mv%%*V-a*NTKJV(I~& zV@i@;Z~|TY{L4{%A_LeSg4D7<PB~U5DL5S$ISFq^AUVtB&kcm}MmT`8%ho;BQbpP? zDS@_+N~=@O`h=vT61<*Ly5bc9<}SX;<oGo1o~k{$AJ||G4mG_|{}ddAJ~x2rF2#N4 zNY>pN^?ygc>;=RZhfleA&acGpjn4VCK*lQWz}4{!{sCn8yAYV>QAZSP>`X~Vjt<8y z>=fCd5@V%Uz0e2IuG%h~5KN5?QV_Nb8N699F>5Hs1-4k#SU(|ML85<dl@A7;-H!~Q zL{vSRhf1DbXVeUbX^lAn7jd|@IeL<(tGx_LX*}=am4m}o<rv;x(sAq}Ps$eP9tF!l z#~k|w^){Yd)WM^EOgBPhT}3u0c7-+AkCoHOl6@dOd0Cz^MOBU_-+&c@6K&E=;i1aS zjL0`7d2%}p8H?Y5Yc10Xy*4(d?1{dd)@+gTAc&(rdWi<J&JuVjUGKOJNr;GD8X6Zj zjjf};NsWSV+0c=}Q|bOWLH2|Ngabo)OG4YGDbdQqWda48Ip}PbFY$^O&k20tXw`bD zQhK?rvy1vY$(1K^HbmjQ*KJ7@wHn{9Z(rmB)SC!H&>Jkr@CN3#W+=l})DTg69o}mq z$=*|nGo0H*3F7r$gYd5P%P!9^y`CVEb@WsWlv_^;@P40m%JFe<v^_G@<ae*F<tK<o zcSJSE1P>@s0PQb#(}>PNbhc12dqHv<;>BY(DB)zNA-XBOrPdYJCuqY(Cakr`Yh1{m zgts<_ror-8=ym7}vE;0BQagD&?6Q2Wd#?!x`b}E30ATeUx$zIn)iu{(u_Ysh*Grp( zaj_|I=$Wysd~SuV4F9Sd-fjN`eKQOVpO1-?I^>W6Z_V>>E2}I+<q#=)&O-6OPj}D* z+YV?Lwft%JTD<LIjLMH7;*BgJLsbsWds1OYzO3Kw(t5UmmY50>{yL}#PM{(_861M} zl_^h51z7ciba!=}DTmk4jWmPyem-?Fy~SySx)~_{f`^N)(fsqw^}JeXvAQGcDm4}E zdJ(bnU<np`Rj_JX=Ga85l=~6qSd}uBh@o{+Q%C2D^5M$^=>?XVPwWL2zQcq_BgktM z9}jUAcc37yoQi=f7Dd97f}h~<SnD9>q(b~p2j{tRLFwT+X5BJl3yuV)pf2zlBkqN- zfJ!Tjlt9J7uF%i-Uev9V3upt~L*)^{$o#UAbbuV&tF_bekVWf+V$QXxf7KVpi>tK) zmOXD|8Z;2(#%+ix-?kv>F7k94LbwIRaJS5g93be%KTZaf^<+I}Cv}QIKjd7S)!Tuj z+U=s%hI6&FgS~~XyXOs|F>_~6jp*9y)!Xloa4nVRbK3{hKQOLs0<>|x-YmL)^8pzr z@94D!b30hRa`e;r&bEvysrl#wVo58zVvsFC$Fnz1=dCXP3F%D4p}N>JazY#>e%ogJ z*H}Cbz6r*<(O|E<%J<Xr)GV5I7)0mwvvwv|h>01t5>@||8wb5@29%Ckt9>`A&IRBE z<i~l>jGOxDtWFJocXE-Ooh>MZ+$<Rr!DPdgWe(+QM(^kKgi7%z;YM&tABB*S;e%e~ zX3nX~km#YDd(mo$ppWv|liS*-PI<ipGQ;u_A7Xb0PwslN9yug(FU_Eoql^hgIZ2QU z>T0{Z{Fg*Ip(ecsUivV*%b2fl+Ef_ykRMLz$n*BR1j2;8fT<rm{s_h_o*UH{6DMle zgEGs)vgO|hyRdbHa3kIB#SvMpu?o?duI(g9@_sgij*sw6)Vn6K6G);Xh2+!rb@lu; z5!+fD7g-WX3Klu;<M|PPSJ0G*u_pV{`;h-)_~+q1w_UdAJ{1^|qa%t%hPoDC^WhOP zD+5F|NuCD(y2zez!|+rD*z1V2GA#nf1QnL#W8^UOPz-4bn4NZet-)ANb@d9MMC!0V zd+5}uexbqtaVfI{hvJ(5s#tBL!H5eTX4>N~z!L8!@mT+B>r|`w@CoN*LN;_uU_y2{ zRin8?sM?^5b$Gu|=kPkt6NubH@{bwu99t<<q5iP--tFk!Ocotz`1wTBE-CP<2cTet zZCmYKmrnK>LM=sO{N1f0l>ZNDQY*~~97B$C7yo+UEoTw7Zjv)jCcKqG@`T56j!BC& zu@W#b+hR#+K{ZMt?Y@fjK7vLj()LE2(M;Y`K$I<30#CVCj*;FR@kkAqE%LB#KgkCu z+nXiYSc!{!yF8calrWC-%0*o=taBe1+Bs~{-RnB~U?h0w835iUq29x=rFPgZz+~C@ zeCT@TF+le%z`GSzaUCS8-W?9;iz>vW9sib?b1%t`lXn>%>}UW#UVXmwljb=3JwwW{ z6nmsdMx`R(QKZ~=heG`|oTw!w`*IW(sl1D|MlBFsb6q(T3ohxh#4C;o%SaYeVQT>m z$|_iyT+qB<?qSFB2p5%rU=kpAehjxe2hBrBK@)v^ed$PxA~=#({xe{{gzq!94Cyl? zS#w$$)~JP*VmnV8Sm1iL(r6OvpY;^ItjdVg)sQq50*04!7#t>aCf$8gg+$|t9STDN zMKq#z_mI+ik61(MoFnjdMUt+$Edq_;<?E`9Mt%kYz=ki=g}q1;Sm(Te@T9L&roXi$ zIQiy;<Zc}$EcML}rz=x%I|#&$Y(xOrQQun2Eryjkq86=P^@u`Mo@iq><uxSi=Qc}O z>MrBcEf@xcMZw2|gaFCGj6)M+6Mo~GVS`iLaOr*s*f&1}O@er#)Kp#i-hu5%lfUc_ z+21Nz^;3{58}6Te5L`Cm=uW+>Uc89`a0m~wM8aq*$l>s2QHTe*z?qS|FHGpQI<A$@ zi4KC5ig(CxrL5W`aACR@rc?1by@D_TZ|th*hTm3Qk%8#f_m<>TDP_jpw5+?(PW)MB zgoW0C^l3<sDIG3O!PJsd$ke@1vECGLMSauizSW>&b?)B_-BC6DENqSyc4-~vH3;sQ zMFd=Aq6*9{o7>df6fS`nTM;z_56@P)aDQDv8=S@kK0erUTe|0KF~RQPSwe4eTi18$ zP`ltZ?XEpsS>ON_ahJ}P_*J`1ESl%ae*q#T>d}g5>o*tt%0^H@F2!a|m$fD^w5fwH z6n9T(o!6jTf~sgTV@2{Pu+Anus7UR#?(si;tsAO~sk~T!Q|)oZlZc4`bK*FQ8L>nw z8-|ko7k20RP>fHr8AFDFq96WZFxZXlbrao$&POMg<*!tGE<<-bju6XtngEZhvJ9oV z1nxFBrBNJ`2jQoFq$nmZja*bGq%J*sN*lSIN_{AMh-PPuC8%{@rm3CtdiPa3e~!j# zJ+;(fC_xj4wQvD@=E2{G2@JbLK~}=h^JArKv6%?OWTC_n39aQ@Y0V<+pfbB|zt<+X zEtNY6i!Dz#wpeU|lm0si4U@0E)P?wyI`V!0*Z71LE%NE&7#Z0FjzP5QK)`0$F|O7E zneH89LM{CW`Q0raVm~Xf?LAw4BHb1+3D-=u==&Av^-^9#TQAG2+`e0`GpF*34qS$z z46A`>trG$C9Nkj8D`%pPGW!O<nflQOVr#Ih=cOn<i-11ZnbLkhpC5eSU4;a~an=|B zg6qL&yJpo_X!vOPe*?rlV#kkne-~4PaQ_?2D`$IaI|Jk2c5gK1#@`LrXB|EN;!+_? zDaIHh@@h_x(IMGQvicDhSN!=XFcLyY><DAP*_e#Go*NDT0idEwVI~KV-OU@n0D`nb z?F!L5K{Aczt@%H48SQ1}yy;nX7XdaJ<s=H&qTA~HNLXQUqhvPm;>OS7GL7_3Q(+Yl z&5@Awj?c~+(m=axdmHUY5z6yE2gzS8`G1ve7wIA`yN-`M8jzM!ij*5pMv8b6pwblM z=@(8$swOM4Fv~<y_z4g%Z$czY@(o%mG%ypX8}Soe+1OG`1(o}SD$C<01?H`Q<4Iup zig~W8^2-Om-V0Pasc_dJF;tzD>0MJ#)N1vxD>VQ#7CIV~V9^uD4*3TXeiZvyRe=AF zm52gJ@OE;9k3DsyijmJ41q}PD%+g<m373ESf_*6Q?@*{ryd{!bG^R*&DP>kjQ`P(Q z7hA91?LFxErqj$!@8r_y>3MZ>e7QAxIetGsz8`1MjJ87h%hgTErEus44h3*%Fo`51 zDO?n(<AXE4sV7@wVS}{g_kJ?s05kG4{iW{-w9K2wd%>$pLRFSD44}V{;>xz#=SWQ7 zU8l@bpAE4Xm!fj9Z6cx*CNJ=-A8MGVK(gnq2zPyDdMjeQMGj7=onRo#U-Z=%Q0>%5 zDsQ#MhP;zre&V!NVGH99r8%%{<rj|e-PY|UbwNKGix-!hFYsjrDpgTo(B!3fxWyS{ z?QePI&_dMxJ7m%KV}M4JP^I3iIv6YWK==xWqqeR|y7dQv66UKA3&&M0+-oL&Q`uFj z&lpx2@yXsk%0)enNt55jgFJf-jZ@U)N_F=Jf5nE+34Brw*fuTDq}b!kqyH5#Nvfq) zP`ED?Y#hb(#oBaJ3-Wbc0j$>Ul$Kb_9zRHS7CK(#D56$CVG5;6<iVt?vTc+|ZXWGg zFK+RrTU`hob5t&WE8rBvpG&rJ*To9|pT09`TgBkCz$x2H;jH0>z`!~fl@DAUGsPtF zrDQgLd(u7}D|6ohSo9@<Kc!`#El1M4A$S#vge#VA9g9ALz`E)&R;{Du2$)W_t2XP_ z9Ud?jnkPmryz*Sqz^c>HZJk5?;#2QQM=}O_d}}B^vNfi<GGn#4R<d;RKB<3Fy(&Q; z29Mzwr@#UW%Of&Tyswned7zvx^S8hv9-2{)34Wr7>qHPpulhu(5sL7q19jT%^8DGs zDdYUYHZUF3eAw@33FpWzRb|gvR_FKAZ8@?7ex8oR>H6%aOqO%o?a7j7Kk0lmw5-$; zdcE~P3o{w1l1TCpdmw-s)v4+*h$wnJ@N_`Ulyb|dX_9%IjV>s|D@ar&<!)-saJS%- zq9CBX<f40cfa1_X0HN4@BFw1V07$NE=X)9IoCCCMq+pgvUF}&qN!B;SMu{~zp1BWg z8vtkO8>jO{9}AkS{<^F;4Zg~`gG>lsXOUsF=qE}qP)US7>x9ASC~G^?1uWKM&a>50 z9r&c!nIVT4X9m9avb8CbJr%8~y1sv1C|_9+JFsYqp!DB*EkP6Yv{N?d84$BhirM*g z07a28m{B1#rPbjsS_;+$aDb#f3YlvR;q)A8oIg6WAS?A;>iw&`kE^I<{((-$Hb8i& z7OP^JNWen;sA_oxyJzD$TwM}uYlZ+lk_`m`ZZ1heb1!Ie-2BO$;?=phx}L@6$IU>W zL5_`>(-L9rG#l75mqJSgiYlt86RcN=pJxE4dD#o99r10<uv-!*nvoz_D@ZGIPQ7KN zJAKVsLbJfQvCB2Q$u7uc!l=@p$~H)yEEX|3T@kd`@?b&o9azE5pmzGvI`pP`kfFoV zjxj04BKVHHm=~-wWn+7@&kcZ>`oi|o`%(AA(6$w{TFVR*9T4(WqJB;Ok#Y9<vv>$_ z@ceZ7>$isRog5ejsN6;j&Fv5#)YzU|b0fgD<4=X{J_cMkSVfV>FQUE90;tT()zH>2 z!?W+4LuxqM2j!b~vCU=Il3R>@>p87iUk)gGIl2jEa<O7>F3@X-^(~&n-Rf6uxBge# z5dS1ewf&Rew`|&XUyy5ayr38{87g@*BO{b(x1>pq_o=!JhA(MlimlNxb$jz5Zn`|k zwHY5H^ic9w+(s4kY=?2dMfOY%(DM`|u9+Q+gtl<d;%O1bLcCc%;`!$5YcVTP-{5Jn zN<N;_M*MxIEym6z{I&)A<+F%-St%d;>1TZvafTa3cWp{*2vl5%CD}<o7KXlad`6ar zZ{!&0K_HVcSsmlSlmtmNc=Tib4_oID9ZIyO(b%?a+qP}r*tT<HJGrrK+qP}ncBkL$ z_3BzRtuv@e)j9wEzKyU!i&O+9#&&frK3*!k=E_z>cmP^Z=5jN{^%s|@Ko5T&9<mgR z>Hfx0z^mE}_XUVic2Za!1xR~3tJ+Jz)*to*N;KRYqZ3E9f_D<KS)L;ZVO$ex#h=Ha zw3Eio&DktFs~pKzl0}$aIv?{qOpcntft=i0<IIz56j5JGPjQTyxjq{2B46&!B7s?- zT0B=Bmfq2782$ubE?{d~N7J9xR!>i72cc%9P&IJ!wjXo4b7sSB#V_;g`}k{veT7~w zCMWCbd*q|RO}&I(E*l@eF9&^OCPpr1D>cmX3_*IJXHfsh8tt!;>xW=$@9ELLXCVMC zh_GQEv2%=lr<C4RE?$<t$afV)xtEMB<65nAZubW@s7ykzua)3^jV#j4?tW3I^X(5# znT?C`cXTc^Iv~sgq0Fz&Rw0jlmxZ9&25QLa6{rv-6grx<YY;*JYe1_g)OSqUncJC{ z)>Q@yW2^XJky)zGxw7X~nZfZqX<2{xwHH1VZNMZV0Jdep5Z=HpJExDY$HmCU3{ZA& zVeh2tpPCHtqchAP)Ej_uBvjdo)LO7?fm(xp{}}}A0AX8TLKu1npEDllVmmA)e?&YO z2I(ukJIXW!@0!zo$eT09Bo^FyrPvFY=NAv64*OY3Mrfwp%j@jZ6`uqHPnqL2I=r6s z6Cka$0lXj>i_wRdpyT)5Wq$>6Sv4_6;}tx>)*2WUI}B@qwy=3(NmiI}BA7}kxg410 z7COIV6hTMSOCnJ6vL)~!1Cjw^UU2b%<WW&J*BgH$E_7Yyb(Y+v9S(HG;w>V<a<E~5 zj$y@V{@0ET-g~||eGI(*kwGO8_CIm(En{uK&((lJb=dU<e<Og?Fq}?^K3>V5krsvB z?rzugx%`h{Ft2BVCN46XIsUIp(y3>~u2$c;Vs!aaqE70yIIgbt_SW@>@}pSNDh+5y zXZKf(C&lLA6`5X_FlW2%xt5PJ944Yh%s=KMRi4WHtN0#X7saG6l0G`6C?Dm+c4N3g z#-A*7$YiO)rzT@RRC;2H5U}?<heMK;lEZ`5FG=|~ruHWtiZ(WD-@mi6ehtXP!x!u4 zFkzl!_&3knj2w@SPyYW#0)EMEfL}EKKi98p2EfV0*~Q-3&d%D2Uf<Qk*4WOGUjMgb z!@^l#|M%Yz`2U3CMFyyV|NUB3vA6*M2><`5?HqrD@FvFkzYG5^Fr|HAhuwzwQ{D47 z4pBskT?mJ~OHZLh;$|t=ZACb<86QTl*p)K!#OE}nBPCep`(+viU;0`&A*+ysu(pbn z6KDGKcx=j@2d`^vt!G>$iKq<$H8H{gZKa%w=~-F#&V=gLq3IZvT9mB5hypb+*$|X2 z;vdyxZY%1MEy;cPW*sXy73Z%`;`-4XMnCm$k*EVPlA4`q!Q4*UU;ap(XKGOzb|8vz ztF#A}tvcB}DvT<qXR_+Us@76>(pB#Cl2yl%?K@qyL&%TNQYsJFs3;C^YEh~%Ygp~n z+9m`3E}t1C%t)Q^HFKDg<h5doz1(DqihPLxWu6&x)&B4UB3V#tjl)}+8R<d0CXDD^ zjT$i+KJv>{-6pW+nNusTwJ3U{j>dTXLAp2@yvX?0$f06GJBx8Q6U`*r_8Bw%C#7v^ z7w5Z!4ZCjb&bK>p*J+e&w|l4f$TRagfG!G+9*y47S8G=;ylAm-jeufw3gALk%9I{C zR%{Bw&#z(>Yia>ArXDcJEpwCHZvn5|dX@4BRB8l983n{sER<nn@4>XcW@WQRe#DMH zs5E+!uOU@XRVfvqSKS&qjC!g?I?K8Gk)#@>5KImZk(Qfz^A17gq@v%gKv7#z#*hjw ziRc?Rf`S+IL}ki=y_E;7=g%ixA0{L2n)g{itAxSOt8uM*=-Pv{GJ5DP=>&BcBD7;T z_Ke`%af}^D7SS{ukRmknEbM9_mc!cvZ74G!9drgvS&iGh5<x)Wig-Ynh`D1j)bWJo zdk&Na%><sc$ub!0@hB<!aoK#%bd7jInp(TH6<nzf@nO_Rnjj<L9#sbX{*1LCC}B9^ zaD^Kcz}Yv=-t5r53K8XWPHcJf>3{oC!!p96Y18f&WqX|hf&h#mVBkttoK#iuvPF~@ z7K#CuIgX?}_$=qm0Bv4<(MrS$N9*dmIM{R^w{T~65o$Iy^?Q7;@b~Un3~z5d2B&vV zI^!j+;N%zz+*zXi81xW4=qiQ`^F`Vta3E&JPBU~JoWTOqfDU>xLuZ(~14{7u+Djad zAo4~PSS4x*%~I=kX0~K<N>mO*NMpe(kUl$!2`GhZ^a@tz{s34ChQoNfff<5{9<t=k z=KJGT#23sWR-)2f^4<lr=g0+e&cIc3kje&CWWV4ItO6sMlkhx|I?z&iuTnrDG7}`> zLqwPt5djN>l<El&GE-!*iu-jKsy|*z0jF<z5B?Il%}lbGmt!e7pFn_#Vv6m9IwI4P z@#90w!t2?*jT!V~C1y-VMGM?EpR3jv`+|X_K)O0fMGDvuix^^5jpaaJh~BYHBSE^m zIizsRqq_WR(S>Te7_M3v0>+hFGzwJ<<M~P8%eGy3P-F+(QF<|0?UNvzkx`5}4BjHk zuwMV14HnzQFxC<F!eA?B=a5{}aRIdv#6i_Kte>yOQcE6)5h98=-BpqF3JDpD1}x!S zeW!J{5$a75<W6HEr)=jLh?OwO;BBnEF6glzT9cd-x<wv}Ngv`0qbWl)qo`idLr_I_ zXC2l*km#n<dK_9c)p<M>MKEmVtR@WWa?L?ptI&hFkjjt(FP{F+-EJmG3tV}HZ6=|~ z4euyTj$DEvqq4wNHKYB~$BLY$u~D%Wod{=Fxy)h<dcxDN*t<Z93xXs%-%#Nvj0nYN z;=&jWxc{Of*GHisvoG5EPCx3=z82ySrXO!OAv|)x?aq>dmK+bDsAFwafI&20_(k<{ zf*m>M#t2kt<A`{~YJxnG*NWE>XHBc#;ttj>s~aQA#@n@SoS!lC5DCovX^&P7H~JCi zFFHl*2N1}X4hJXzb)do+<J6!={}GaR(Rt9Qv7+hwQ)CMvm97?toI~-p@XACMlh85h z1{yc8g>zSmxEN5Z-!m!7j~)15W!O2y+qjc5POOewZV|On4pq@u4#{lgBgFew-j{3) zqAVntx6d@o41)E!HB}1HiociU)i+TI&Y9NODzP|mt{r*fQ}5|?CC|X35TJtZ9JaP0 zb^t>A(i5DHt0wYFB=ShQ%v_$KtTfTICa2AZ_&mSdw>E)CBTk1WS=+9U29b{mDt1aD zxq=R;PZpk1z)5iw>T`=wRBT>TP_AA6Cg8yzavFouUCoe{a-#AC639znSX0ujRVBv; zl>EO(`42LpM-#`^@&;Xjmuy)3NcUv)#k=inN#RPtsV1;=9|<tB_4+3{?YE}`xt-41 zOz>S+FG6WWX_<JjO9P*=DHbz8E{D=BG(MVQ@9okne9$E@d|-VT*P5!FX_67J<mzH{ z@~&WnL`|G{FFnKRk>FJx0%Yt=;k-P=n)apN-||`Ch5{RJq-IhHhX5codj9dmpZAj8 zG<7k2<aNe;%3lwzO$7q|Ep%Y9_C9Zu-okZ~RL~E3#D@vx5<S0U^i|edDa3*)9%l)2 zzfPuI0k{%}LMF3LkiiK9(!vd5n`AdAtO4guq`o;lT*P01C`=I&3C$<dp5ER^;YzC> z!lzy_?S~H%1C8XVwU9UQMA)V*!<(Ze(S=<Xg2ZO1#Y8K#?nt@ALZj}<k8j>r)JvRM zw$cYV(u$ZFm|NH@FQ()XO7j|LG6_|a?;7+7Qv71i&ia(GQjJCC`qPs%R3%f(ng*HL zHmV|oCJtwkIJwQm4tTatL~F>=1Cu?+F6E^Sv5u1Qh3Tobc}|vhk^%%TqHB1t&-2wO zEUkE%V|cP_{6%2?uYQ)kK$b_5!<ns63d9&0@116=o*z@+Ju0>Y_Jks&cHQfIX(U_% z9xksxUJ4xUwRTR0NEPPnLeR>MssSsV@!3YuY{{%2(a|w(BOm3p-ef_8!(Db<W*bn? zN;HLLtUyu)%>v(ri`rshEXgEa3th4hc4N-#Z`BU@_BBWt?J(EM3O(#fui3ZCX26=V zGjN#?W|D>l-%SiYX7{&zp_dYIB3iIv99qz{-)jLa&UnDwcGGE#Es^U*iBbA=VTn2* z&vyOFu35YAt3`8P=T!<XsQAVsv{K)M(WYX0`g67epI`{@h3<MnZ-p(jXK@R>6roR5 zZEVq=D}$P6YxlxFDQL@jr>%j$kI*96dl%_85=Fc>R7=XR15VCd@0nf<?vP+LJMaCI zj+31;E<e!epKlh(4f0#{Y39=W0=efPX}shQbdMpA-on=@)&9jjPUj{7(sEe0;$OHN z*GJc!{?u7es0nXwaVfjN1u+FgMd|>i-4!|fk1_Sr5*FIliie`F6y~flJ$vFzT83jQ z)=O$o+_1bxklXU6o1lUsmH?jiQ;tCUhK}w$t5;$%8&+=x2So)nRW0g(FKVkuER^o* zxqlN%u4(ujtTMBgJpV)d)edVu5;2>_GZ9%aZHs4rcizVGvFW;1_qwSpFs&CXLRz(8 zB-#{XOOy`%0<GeP-BXEMyBdYldok^wR-%GCP<7~Nw%0Yi`kr~NJDUMkhP}oXm7D%G z0;^pKc1IT|;Iq5N7Z5@yunnitV(t<@kQ%@^;ces1K4j}n*w#S12y4ic8Vap6Xfd0o z=x|30KW73bG&pUE&P&bfQqIN%(!=%Dh+R^{V?i*!1)dgbP%97Jm6?)wwp$MowAacJ zM4YAhIuZQ@(&zX&8&JcOdwRqVPhXy<uqPV(ldmiv4xi^cyg|7fSYu6xa%;MyzakU% zP0!fx%3J7mcr1hI0QS=aWB+pR2n@~cu(IV#6*7&;A^jI`jqE0`Ix)$(WVhB7u0XhU zednVa6nbHYYmx5(vGtUOZJ52}jsm(O?>f%9RH^-efqA<qjA6H|l-&bEX-B}6ez@?U zb}D<xgqw!6fg33c85WpcU`s|9iUFl+4k3(wyZ=1lA0S^}6rU!$g#XBz=N`9;OIx=} z?=c3bMHpnWcervp@!jRE;w5y!JLyjv-&O;wU{ejB<^V~KJ|H(zK>^cZ6KM^{jFM>S z_B)$wvyWl<Uv;q6HQFCBs-=!DK}|2?d}B-!*WzAN?k-$t9ZP}6hqvfpT<Glbl~XTQ zOr(t%Lesp^`P_5}E_TDLHXPJ#2(q@pKja*s<SYn16K`)TvjaXj5p3yHG%DB0gLSBs z>#bj&DP)P*#oMm@l^b>PQ9>naz`BADZ8kau=KE-^A!~&vyfW85^qj~gF729SC-6$M zdh$!B_WOGOhsYv!cT-2b(V41A^F+(myrNnwXeVV|^SR(`7*OyuAEG3EhW$7Quh8*e zCU=5|fS2z|tTQkpz{0C_ha&6qSM38{p-b^W@i9i_Tfe9Ee$48%-HzPFGSwuX%B1rY zq<ugaNw-Q1O0Tpq%1PUusBq<gvx}kh^LX3Krvl|Hb@#E<7j}-ok|QO88&6#?C5+T( z@0wg?6)LreaypD{G1nPVZQBq%q};m&l$E$f0YsgH676+5@5Ct3qP^bdbwif^^6E_8 zYun*|#T!<cQWy91arQ%@OUecm`tvo&Me)f+;wjQ3baaI>Zh%0fnF0G4MLavB&C`6j z-?GG;=$>qQ-mxcYeq|4O>%;Yi*KB}ui|pvV%Io<b8Q=5IiqPyZA&EuO!3OU;D=<Fa zb+85Ah`;#f4{XP`oZIa<>(@0Bry0KeA!_0nuI3xa_iRa8LhzvrSd%HKOzzKW>N4G5 zH^OI=mTS?l+u5nE*p(@ABbq1bKXe2*$p_mPtO9?%UT6frB?Jvh{|N(uKTLStnnShA z@3NfVA^Q2A0!|B=uHTrHimK8?-8;M0q)7vYv4}eqX00}-{%mjHE?yJWwoYs>E(>%e z?>4ig!8;QRLEJ=Y4<K|S8Vc)z2O384$WkG%x$j{+9R;J-G=CI`2J%Thfdqc6ij3yb z8`NyS>1fnyPJ9Zi-*YO=x)=jO++vL=?nxqT>w9L)kyB~s$|$heZGOfp*30MT_@@L~ z1T#CJoN!(c^}puMGAi^u`BQVl^!Q)M-$`G}_i^HEot^sq_ole|=Z_4$5CDLU3LpUa z|G%wu_OQ3GHPbh7cQ&zgvaqxL->SDOpWo!O7}BoW7gVLQD#;3q5$D>JSjT$A0f(mg z{vay#TE{{eMH~oerKCTgz=Tfnb&Ed#@f<UTe=f<110r>ugh8=caY;!@M@a{{ZuNbB z#QvBw{ZY+=cb!DBYPy-p?wmx@q`D-cx<{U0Dz<XLdgc73q1_FECtFPdk>}UG%VTN} zAEuZE7=MF%o|MRpUQbl@J`>eSVtqsdRWy2}tO|*`#~oW*G(hi|iI&){{%;i)WzVr# zt~1LFpliH3r!!+Z-G2RVrgP!Uq>(Oho(-%j3E=$1MT=DNzFVrE$tRVDt$_D*6@v>6 z*XTz4CLupaF=oL!I|t9l8|~|X<J^xYiVs&z9?Z+@j7RAx_L=C_JIh!yUQVA>6$ZdS zWK6G~0@>FC!H4Ia+9w13O(|A=Pka$a%&3yn7ag5+dHg=-fEUXRNmbp0Mc*vy-8_Nj zzJh`d>0g{G)WO6FSS8+>Nxi=&C8onzh?JQmleFoaF>*9(b?shPSC=MJ?64*u9lD2V z4B&Y&e})<`UN23S+9S+x$j%vR7a-5$aQS>Ic=SfSPO=!Ra-eADN=g298tnxOyVg+! z9~zd}&XH!nESh8!9SFhJ+nEWI4|lhL^K(h0BSzIeksg_UtP(6pdxjwY?vXi9v)zc% zMgWoA1PNDwhr1$*$6U^hzVID(A$KK~csXcsozJy$rvy_k?B@o$&3wgRcR9ONoCLtP zvrN&(yJN!1oQoZ%Sw?o*v%D?v8SVL0V#PM><kOI6nz5>6YYE_|&rV<6=j2O)yH-_z zX*J^R6apGpWi1rN5tiUiFGW0@K79hlx_bsmg*i{i6FZ(TyjtoVN!k35&{;)edl09b zp@!>1s}$Wm5LybICr(!R(XA<L(wjz=p=@gfk!~?6jTnI@&9YYv#5X0Kr|=W^41zh> z&xN>tk-*veh?U4CHb6OkrzD!w7j8Vnjw*Pz&s}HKdm|Qa44XnUe@DauRW^-`^31p_ zn~x@AP6a;-Y0imgclG>amDEM28v3vbAi5{2*`27NxF=@GT7|m_ca#x$zr2WB_ymSd z@ZO=-A=vv#>e$T1;P=0g3(+T18se|h55p9cF&RFg#xrow`*K6rMWx=!xr9I$wAk&K zeZ)zE29zzzf2PI`M-$d5oh<;}GYKPaI2dTN<H2+vG=WQ?%-jpKGe?WvlT?BbJH=rR z5BD91Qd4walL0RD_p1Q&QF1?Y0OV&(cfL#?aSQH1uSw?a%@PMne6OCk=*7v2KTq#N zuWvniJU_=rZu$cQ4exk)%Y9+4S(-o2KSX82wMr9Te?)d3h`J=0zapD~1Qb=Tb71Y? z`pB3(-y!<+hD~%-MRU}r5ftKn1a#_3UNgU^ybzNx&&Z*s6GvWe@>UDoCvYwtp`OiU zq%VVfy#XumpG%2mDh?72vtVdS)^~RNj8dI|GVxxWboSbtJJeh-)oVffJ}Jofn4a`I zV^b?c9i1D=TU88NSOyS=;yzMQFHr(d@AzdQ-K6I_ABR3H>if4Jy)@zWhl|;3b0xZW zuL}lm>GTSjHyiHHk=i@QCz6H%FCCnJXYMB_JH;k0<=8yj{Oobn^Fu`GBWFMrfh@{> zzJmVY<L2sU|Co2CVjv!t(QymDU_}s<B8wsIoDX~<FKsZ65`SPe>)tztyYoUUqAFkt z!BHaq=?*BcZhjjy>RX`{GUmgyD6T48ua<^TW1)&zjVUN#R|l}aA?+F~{|kXip9CP- zLlr4TLAT@Vw~)!DrnpuJB)IJT1U#6es#GxV_CR>Dk-Q|dO|HEIOp6BdB6mI8&Gr9y z^dj#9w82{oF^GEZhD?4JL;WC|8}fxh{g6ccpwz2GR=ouQNmuB&Z3UN@u}Df23cZZ* zF&oij>V&yn1VGkD)cI5j{4&u}ZToO+Y$;(kfmY)0JA1=Jn*d^qmk6IxVi*z?p{Aa$ zj2qV>2M#btyF#v5!$*vK*Zwzm7s3yK(cu5@dokiHf~TzWiu#M>H3#S-5UjmdAv6Bm zHyK@e01I_wzzk3O5lu0^5~|7d(_{c;$0*LIC@z;~J`zt<;}472<txIUKz~_#3p8Wd z`6YZBlaZMWs45e}QaEf<;TPr`-3`2eI8ISLDCNumA~2mp!#?Lt?4XcRuiQu6by?Mu zkJYg~fjU556QI4AO!U{u`!mMdIkR|jC8i7j3sN8{HEpH-4FwsI6_DBcN+J)Kh8#VD z62Nc&e$n`8Q^<J+fH`aHMUXRUL#ocUtERoTrG_6)--mm@9u6jm*UPa)a$QT2*q8!g zow`Afyphp<l!ITxm(_*L0l{yZht7M4*_G4%{ZizOACF=eZ!oA2m@c376$AUds*YMY z;VQXxVqmq6m>c$W_^~hn0L5PH1;G$ON4_kevF5BI)ohixfF>|n#`!){w6B}y8C;Sl z_`G%T5Zs^}x#fnOUe>9F8Bjav(4`Df3=2BiiKmfi_rW#;!CF!BpQEL7jA-0}(-}Ws zFV=@QPG$p8D9jJbjb(p+9s+`HN@~;_$?F)#7c4*?gV6I;)lA&nC*Tig#;0ad*bPW+ zk+|-WgN1>DhGSWiMeIhPM92IE@tq(f%f;%lw|0U*_|b6-M7nuG=kn@65q+x!b{M)e z_mZ6gT?X;;cafo2G;LVw)OC;@05JK&ai3{(wJ}?qmYLWzOSRY)Z8yvkq3TxzJ-KZt zRh$GP8IBugkab%E%A@+nT?<yB`3SX<m3>p1^enagH{4-ysa5spXs0i<LNGQkTfXp? z=90e6S{O>v^qzHfiWC|umZh%I03Axa?{qbKM2TY1dQ2VAOtgp)*$$Iktnxw<eN+$` zQXz*->Wo&%Yin@@V%%;=cWv<_Kkxrc9J_jmLe6abu5Ggl3uh86<c3*v+Qpijo2NHb zTP^5W?G*@B7;^D`rDSh1_JAG9aFPqPq88v#mqVTnvZe(oHYqRkD6r>FPn-w+eo^lK z`VN_F>H~;bmR>QV#R87EE6IJVnFQ=$d%3NXb<^Ra!n_`BkY+BjAYZ<{NP78}F*b|! zf5YI-E?>G;acx{~1`Edcnj!tQ6}RTm8BqU{9Z__s)@#cE%5q%WO2I38@vbWS%Flba zaa}vWDB*Q^7C8%^Wkz7}3*?Y2;t{r!ry2uD1*{{eA_{em06-vaa54S;(F9CSZlJG8 zAOwEDA&<D(V=7htPC(E>A9O<pyn)eddMK}*k&(pFZ42@W-`|Bza9Pq3bK)1)U>yEk zw#89hyZ~zhs3$OxOWB>czeN#4<b!^Hy6Rz5@M5&Mi$36~e<}k6!CwU`*2^_PXd0Zm z|7fSAO9fgoS<ew-MJdV}V=E*<Cb)-KlbZsrl&6Wi@G3{2v!x$ji&%%4vA1h0R1!%8 z8?oP87Y%VEW-pY<skm|{FgY7xZ^ZioiOkE+6|Nt-swPgjD6q2%_|NFK+&R*@a5pWm zESI`3lUh{+k3V2Zl=USHnjnalKjx~*m^WhW+iBD#aczgrtsbg4&#v8`IzHy`OubLI zAFYGb=H<b=-b!0KG|zc09H1Dr7LctVj>XWKp%*S4KQ_d?>*$KyJGa;IN#f5ePaKJ1 zFm$4?t4i`WlRhPO@$PjG*|LZN*>HEW6i~b~&3K~PDkyeWORdu8|N8=x$lM%Q`UMsV zb>gZQymjl9N0@YrJGBGl)QO;<czJHU&oo)&SN+Om{`k<{7Z-^?e7O_%Gm;z=EuS zz?OP>Sz`PCG1lH|UP9jiSM##r;$D&mwxo5zb6YZj)73t%Ei;)Hv{nh_1lYEZmxC?k zv!QL^`4tom-$*cI0>GwtKWmXJu$DmsZ^F!Vz#+sBz>SwU);Yc|0FX<%B$L3Qg~l&y z*l$#Ze<@bW0UiyT$pP!z85lC@Bohd!ES2-TpB6x$u6Qy575X*iui!Jz#@=RfQ1ZV| zBo5TlnW7_p$TiXu6;bc0v5v^L_;FxNjZ7LzKZ+Uo&T$_sWs8>Z=BD6jG0X-M&Y&0F zl!`%5^1u34wKzM5E1~Ft#rCC@r{gwE#sv_uJ}AnufAk4A*BDTQ55lpPF@PYe40e|( zG=Mh{E}E+;SIqi3z`F!QM5KD)RfBi+m7DsKn8CP0Nr97THA%#vz6Tlc=%ING%*JJ; zog9XT8A_zH#sYYl_jH3peCsE;{qb3wfXB-$Nh<+Cz&Lo%?SUzipXvx>1~Dssd5+3S zKZ-n_%f1sqE_r&N%RcBJvz!?5idoSvMd13P%E=$7{fh0HUOYVw4Ho8al2($v$ZPQ# z>o$88X~>zYV1<2v<qNXl<mIfWc&bG*`s<2gy8VPDf-usgHuTuoahA*LGx=TOCw5Z} zHio4jdcQBKr?Z=%+sBqu_quh~QM++T8UgxeL}(P|(b;b1i9G3$IH!fXC>RF^6$z+@ zXCI19<wc7ay{-;p3B$eF6-}A0&w4x9rs*-;pD8G6pj}IQ9{N#mq9MXvZZ7b+5?FN* zLTXMdYO{JP>R9R_r=S-}es;}5%b^7upa<Pk_uf}ZiQSL54FL_-UxMuJ(WX^*lR>m2 z2&_g>y<9OWd-TL3t~I_AILw;le)sY*Cs64RV@r+ioc%yXF1hm!q`dl=$E5JFehyoF z-D8C607@*4$ejY9h$CpNbqQ-9@EkuD5zKeq1dolCDNf>+GM%xaEyhz1C#D#G7EHPh zn#i6h0bQUEYR&Blr7#?W=J(~a<(sluYd-xv!k6G{wRr{dOY&<6H@s^t-r-;sjT*Om z1!H+mg6={ftz1ue(gNcX4U3s4s9=t~JVgw-1d{d`A;Vqy5<K5od6pb<b)D18*fNJr z#wi%#xCqE;np)40N(K3(4GVy{RfVA9LQQtNk1D*~0JQB81khk^`|VztAnRf@4omZO z03J+?8#x4hvB<dUaT&Q%+DSA}i+1IW#2d{GhGU%4EW`ZvV6@kOO<8_8n*xoa*9K8| z82}<8OdtF+!=UhL;_gZ|@(AJf*a+7?%vp&YE4$6m93cGcRig@_hPix1g>wSkyyd{S zU-xV?vJpO}#RiyVUa*m4rA4M!M8cHR2oUeNvixqpR%6=s+0c>+6cv6(#Re?7b-kPP zb({U1((8NZjeIx$&xby}yq@>RJ?#5N)^qkqB<RS(VnNxb{LHXI*$oPXDs(MW=%1zB zFKRk^mtc1DkTY0LkqDfFx6oqJ&nICa=Gl3E{%)$utxU{uiSoLb5Uhj8q`z{f>}d*A zChp=;X@lchZ4A#*3k4&gW`|GyAi$Q~U|s?>MXDebnA+^iH<A7&r6m-_Cl0;o4nqGl z^UP*_^2;D`X`cnQn``b=DBHX1VBoo9i|Xz`5xn(X!hu*u3R=dBFX6%Fh<z!q+Rjy@ zIbX(vU<kwoK1EgcPd|7UFNepUa@Lhi+kM@Ka~ERP2XWz}K=E`*?>30i4rag%EG&)_ z%X{r`IgWYM3v7dg@ATR=alh9!IDprcEaR$)3&h{T^-`t`Y6pM2LKYRp=)V<FCG+7l z(*I1}mz^~i0NgY4sU6-lLbD5N9XC7?DF*A70qG47Y3u1nB!X5NHu{R)Suc;+$tf^& z%|{{}o0q#IoF+{`?!#<J4Jj=yp+$Dnt*;Eq!=Uz*?H&XOpUFylM>1z>W|RYy8E##& zyoX0AIrKvSD>|$LAVJ}eP;s?ln@OfY1l0!YfTS<9apdDlj@!k)G8rW{+iv%iv!I=1 zozsYd<-S<(|LnJ!NvoQPi8<y9-<v0>&0!@S=W7|!Fff8NEhVhnlB5kg2Z`Y6&JksI zqarwAN{x_M|JLjVxQal&=ZVLG&-HLt;tgm@Ur9;09ye-H$9Rfv14=-i8S9dgX7hL` zM3M8)r)bF)U>T82pCXjbq>s|^gx&i`>V5nr7{=0R=r^p22e{0_+r6Vwy*BMo8_1=t zj;~fB)JgPwJ2my-WqU#43(AAD;tV2qnoIsv3-(ue!BNPOqanJ?o(-y9M~s%w4q-aF zpRcH(AGB@T?^G@BROg@-!}(JWra|HCJyD4%5~A7vx1s_t3M3Q%s(f%0hoTn<nr3u^ z!Z)?VGQRe8Y&#|L5jULo-;QC*^vNvZ-lZ$TovmU*s4R<i4ccKn%fgl>4F{4bq;A$8 z*9499(2+#!S`Xw04LstUofILona$B5Tpyagm;7lb1_y{}*6@+yY+EYTlgkoVj`kta z@(J4%Pzw1c$8?3=@`7{;`9FF>IwgTdUImz7tcC`~c$tSt7~?;{wT%v+wcSf0^Xdqu z7iSwIpVka2@pS<ZHbz3N3mmAy{0@YP;2fn&UoYZOOQr-+y&s6I9QJz%Q706CfjGNN zKbLMvZZk<T3yu@z%{Q4fXwHa4;FhUz9PDIIT=+Gv5W)I?$BJ<?g7@xerl)Wv`dC25 z`n+66tO6EBM&$AutnM%{6AwVka%9b@tA%t-2+tg=Y)29&5HHCXw}Ic2V0tzT<LnA) zR3Q)s3*ox~u&pe9o{r1mm-5ZrbuEL#86$@H0qldkH-@M})pzX<`sKLKiMoA6%oH!5 zT@#Rg<JW0Y{(Gdda4E<Gzgcu#SAB*96zJXG`q8GpU4B$N_?YaSk=i%B8EoYKcr(xu zk*pt^cV3xvs`YqNAONbADElbycV%oHm1E4#8!RAm+%4G{g`WFtxjK)t$Vsfn*gIv+ zn$_jep=Tx@fCaU?QXoaTsrJ!*Vhwa<Twhpi4>q>~VNk*2RUxZj)ELy8uuCu)l-mOv zYFxat#YCZ{K{teU=od6!nxyy$m?%Q?7#4>F@ndJ~%>t<V3O9c4!6p6?_L&UOV5~^o zvNM)8tl-ckD0x`h=IyhvzMXAsmC<3r$6Tgk1H!siF{IKlE3+e~agI{D8HC%HD@DIH zG_n{W>3E?tfCiB?9%WgI?w<grGI!m^XQQ{iPq~O$duk!|p2#O6Iv80t@F{k(J4^Oj zZbU-4qI6Sm&tzM^T1xkF245<rlGuU;W<S*T6jZA&BVq+yW=K$aTrZ@?D)K%Tfk!rb zLWx<s^5s8vUehv+Qv%%nSK*g%6{49~se@lw!aKO6SY0m2Vm&d5??9Yk-Jq!17_pr3 z960$1j8Ss+4H6`v&U%ZIzsHl1_hj#aaH=IN@+AtM8h<Gqi&TYW<p_u^3u>%tZyQ9@ z8r(<LiLAXv|C;Kex4C?*1<-Wp(3hh$BQslT)hX-}a~gYV+zbTwbGCWE(qA;2a{|NS z_~4CY1xyX+4Xu^8FNkBtUX_WUdBm^_Gk227rpJp)L083@D5czq&f{c)_S3;4*zY&l z$y`irOzG@3EO}}Baxt5IK~{@!-ryci5LjqXDLG0P=nl+A^~bUZhq}@RCYU;#hc)V) zchZjD-3lKiO5x_t*4VeuXZ}T>0!{WV0Q@=7P`Ak*ajf)=Ew+U7pqQJUU_!`}reI?T z)juy360{L>lpFzOEtO*GWMD`qTx1qg8m3W~34dSN{K)_;ci$)z_Y(-~%gbe%N*TB6 za<rAJX?tKdgB2;n{1UZkzp!Aes+=r%vM$m$tRro2Dt2n7h}T^$4H#9u3yWkX3n_vn zM=s?m2VyO~*-#!^N58#(lKD4#z_Ia2u0&&|rnM1cHQ)ivveE*nlMoPdY)sMqgNRkJ zB^ak53_9{!j~}7e7TULO<|PnmUTT{Mhm%rQ)b1ec;PaHj_IB>}ys%?KpfZmhre}%n zt)}K6w<@EozNOf8-dz1$FyjLqS91nE>B_nI?nAJUjTTRpeza!f;+`L}gzCc_fl0-= zQktk)iy8f-L3bDj`x=M}1))?gGP!IxH%Zvm8=R(h6(!>e-|#3FDl}Pm(#2Is7Yemk zE&WF>G#pfjln3UlIWzFnHEr0F$o@<@$YGfdfFtZ&M&g~BGU3(6D4hG186<=(SX*)F zefSP@%=Ij#y||XTW3@<+;Cq&H_6$S>F~HzMd%l{rpiNU~K)waihLfa{8_S%rTsQBq z#a4BZ{)+AFrsqeFLk6zbNX!tfyTZ|crqMT!*&{7llzpmu-7{NrF=1Ir$xI1|@d+DB zWz9Jdi%b&Imf0n_QW0C3_xxht=NaRE>sf1te@STB7YoC1{lWXjvuaT7L9+ZUw5d^V zf%rnD8f#T<@QMzq(}-INl{QwdB-(7d;p2&+9iUKOIfd$SV|Vy>MsDR@9y?g-&1gyY zPPhZN2U186VQ|rRGdV<zL)X#+Z<s6vX7$B$XaXk(gx~oUpvyb%y+N3Am!8pA<Hm#- zsFFKSBHNTmOma*}FZZojy>Ef!>PS>2YN9GISy5xHtiZoowA8&z>Vp&4YqR_4H;Px$ zCHi(An#PQQN+R>+%B;s&$dW;~%-oxV*z;^dCbj#BdVi+4=$B3Z_731vFGo`<v0b!e zdYI7cs9JP)`jsuG1zQGytVeIkhLaZY?%lX<E38P%h-ETYoUk1ripp18JN|Bf!5|jY z!fDjpcr2CP+m11}wkr07P3lgk>gnBS^3zqps@|yEay8cU8JYIz3!TE2+f6szOh%1u z?g6jXtgW$TZ5aR2Sl_1LR$Jc}BQOu!KU)!sLe2u{!S_U0<i^%C7F$Qm7`d0BM+5#d zg#pZ}<;n`y?ga?JP>Xx#Tbd$tc7x{Auw^cmtE@=!8PWL^q-;T)XebcjjM3xbx#;s} zRoL0I#!VXCaDo&(R0d4%*gt%P+k%RmmgD7kTO3452ihGeg*OMvN9I(}7LOI)d|x$J zmJ(+Dst7Sf>|zNfXz;tqS&LukqwOHYcW_~!@+fIQjGW#P2yza9slBPS`Dh^tfNB;# z%cIoT3)oq#t!^j(&-Cg5k8(IqxXkrj*N;dzjG@AadGDj%29*kDj4lHTpci(0?yjSe zoaBpPorF5+`1zLSCO!+GkX>fAf+1T{ybb6R?%(jtY&1>TZ>2y-LmCP82Kau9@ygci z&Zme<7A;NiRXDqcLK)E2Wa|t7BMO;#9e@j326|+5XZ)5$5^;u_^b4F~vGT7P&78|T z)uKXsME-0E7)_Bxf|0^bozL+_F?|{CP2AFUld&?8KY_V95){JeQb8+yz#^V{%D6qR z^uD!=hJ1H?*W32cfqCz*O3~p;XBs_c6q9FGsiXeI3T*=gAx04&wPA>0*OsWr0=8zD z1#>L!nhYJ*b#YfPueMa#^e@e&E>9v6FXlx9GiuVhfv|11)lN{~YVi8_)6IDQxxa7C zv~AqLzMl;-n}XIj|1nxdnvvw)E(1pEc$I{Sq1p2*NEivr5EoQhDI8?wW3@P*ktH?d zO@-@2jz4Mx;odcDkS2E&LN6Wh3ydpZebL9Uq3~}gheov7FN9LToO-!6htoxq&^X4u zGXUBCkr{VOgXV^Bsc&A7{WruNxWCmHkClEaPtV_quLX|Zh$dv7KB)G0b-45AAIPk! z@}oP>(A!e4HvoMHF3+VcCls)ecBA3#Fh<T;A_}rm9B3qyd+3$r0Fmr&<!0|;F5k~! zrz=+sAJ_AxNlU}MK0!!ARTqx&M}QF}D)*~uAZ3S$Vu*<Uv+$`H>36pf0XM$P46lf8 zM#e1|`$j&ZU$lGw);l%~)nF_i{-NBGUd6*kuXZ=mM211WH?t}iy{17aU`-4Htjnd4 zSx)Fxq+>NMvJ3=$E&|8A^@9f3la#d^)Y9WVEpD}^->L&T!z1I^Z4891?JPm^LLOb# z<|DSvyPDNPeR%sr!GLMiN1h$U0^1p#%N)Vz8ic)-!%_aTmDExw@8IbU-OyNg6dW!W zikhuy&?el_8sd~}$W9aHQ6n11WxEYsy4TFaJSDaCi4JMcR}>BGn+8`bLsDds6In_M z4-LGg2A>343a(?V^JMS6)v<mZrmEi&3yqdfG2~5B2<g9z)EnSLI55~U-wh=&%cpen z`1<to!{Be|45-}a^1GNVEy<ffP>EgDD0L8zsDE|)HR*)yCJW<|RYatSQap+hv))>i zs^f}}f!rNna9RrL6{6!(x|blPrPzf$>JD*__tcjq9m}9OCi3rYk^!mF^vaV;ds_$) zhNB1GeDuKVl7OipxBv)w4^wP<N{1FcBEZ{_;(E?uq-9xcK6>Op!M0?&k@SA}xXt*v z(_Y?6P+xD#gaeq);64?xdY{|vyC8kwbI=*km^Znt5s{i_rlNRP7M5Jq$|fI39s|YU z_oOm6UR^wyp{^Djv4Io$G0KD!981DTqRJun%^5t8ny~(hZh;_ftEhT>T`lOXPwG3b zA8B2@f9KytohiwRceM)>iNKh|_xGqt{d3=#=tL^Jm?|q7z9nZsf#_45p9^w_k)z65 z+hqctKQ8}rgfS%3+o-%jMGi+I-t4`H)Qr97<J@iO5%1o4*R72BeQb>6TyC$-h{^MD zp{QpbX?D|@Yj4-wQ>nq#fv=WSbpA`T-iV#BY>=Q)IAq=6ej8gL_j`*XSl{MQpS_F5 zr&Cw;T*5Iy)4S?+6Hv82H$!gWw0hP3#{rMwfmkjPAs5FxH%9~=K)BYD-BvjKbD62} zzT`SiM%`v$I`&}!)b9L~ma+|T$?y(YGnsc2*bBwd<xsufPtNjE2)_TlgXJ%JOyb@i z+?N4}^|RcExFqX;PEUt8m_8Y6sB(~})_XT|mdN}a&8O7p@1TD81XS2&w>(CYw-;Vu z&DxvhwgSoBrAW!F@%Sk$I5OHc2;lYg)8~ad-g}wIon10!SZtKfhlJn-6sqBSOq`&` z?y>)!9bew5)J3BV#*d55h+$(DA*0BvoHWnKxZYnS-0|tzIIixaIM<NpXiSteX^`B$ zO#fvcq<^c@K%<D9kOdGR>844HHT0zkq=icAwq<u9qF-)UJMo#ZfkgzL)~!o&lQ49r zT-RzvR+GEEizw76(>4(*@XcSd0AyD=J(1MXM9VeUjW-*QQ#XszpLlZv`nqSrq*Ay$ z!`EYz;nfe&z&<h6T%nZLgs6JAA%dIDBdU3SVBYbv)k$7!ilzc0!`3e5#oS@eACbN7 z46xiGRDwL;Ncv)WZ>j^aPZkqvLxC31ogR8U+ZH2#12xa9&~d#`BYt5TbUkG2&-g@k z+H<@&B<d38!a`3e$|@=KqBqhQnVWKOP=I5rsVu@=I2(x2L@#1_@7Gb?)`@!;G9-+- z$r7oP<XN(RxGXBDxis353OAiVX$lKWh;r%!NlZvKh7`rPQmK>)rT%ablQkX*cl-Qq zx+aHPX!RE3{hGoEI<l#%aL0aMmxdED+MFTh#}LKTFfiZa8R+J^e@nNs(>&$&vJ~w} zg2Zz9r04G8!vX~9Lhr{;HX2Xf?D6TPx<QwHzCAAZhy$NIcXVAYrh8tV8n1pJ!f{+g z${DQ4TBwImN(tCLn=X~eOO*!8t5A!wQ&h*^2M94A!nO~mGlbovUmSweGxiFUp$hn} z+BR1H%DZNHS8Cax9YC3scBG8(X_e1sg20;M(w>%X;?XX+-dt33126>0hKU1g%Px8j zx`J~n0E-B|OtquwSS;T{!>3S6G6oT(xnLg)UkoGS#;!l-gj|LeC39gEzt>Al_Sw4K zwZc9<@kxc<0m?MM-~9H~?lMwX=QLXluDUaEu&6fjtmbj;6Pgdp!tCdWqADLU_lfZB z7%`R6w^KlpttXaz3n1QkZHGDK60K+~KHNwZ^G@xtoYRL@K<ws+bGoAFSrSUe*Azrv zxA#YOjd>I4I=hWGO#fL*RIt5;gmvc6sHVJgJ8GtK0ziM`G9Z_cHRx$lBR~d(#=t#U z@o~H$4b!1LHio%>R7a*W_y|T2s@5d2oh1d;#HVfP-XHvPe~_;o5@96AZCES-_f=N_ zj+?)7g2Phdx3A^oA}mm7fIHv|l~h4$bf0KESG)c9dSWx0=$vIYSE3faRe!8&OjRFT zo%`%TM;5(hsi@efs2!1-$C;c1QBhv`=Oun*aA8ZoQZ;zNsl{igtU!vQ5lSv~I|UH4 zr|~(wzzAhCx&Q6SSUAxqA4+2{gv<b)`IC6`NEKUV6b|<9*LyW=2y!Pek;W8D2DGe* zQo%D$zsJ#L44Ut?l)*vFl$3EI4Mj0hkQz3vnr0C7)EXB$og0`{CZ~G#9kcK?4pXnd za4F!)FPTU~u7{S~`qn$Zw_VYF5R>iLw9=BwH=LiP`UExs{ORTw5_Z43Bl~nmlusB! zOh@Leb}qyw&f4QOhpbh9V!M5z{4BD(?Q)AhY1oDxhuQHv0QlDm@C_ZzpMpxxxWt?j zcuM_yT7A}>PCBVrz<B$O(cZur(v2{9u+2j|UM}8FUB)a6dKjO24^RLM=mLWxuNWKf zCWr`O176;TC2oXAsO!2l&&MuYH`)E9nfyoPFB}jP(e^uXU~SPPh+*(vnef#xA~&EA zoFaUHXeWP&T^PyxfH~C@tOM>J1`7lLBDn8jGtAsAcMLNjQ^b`@C{_V9=c&FSeSFxb zEpY~0E<}c06aXw&katFMaCOz37(P;Ozo-|13oQ4+uoA;(okPTXZ`X|1OQTs-4_}8X zAzg#`GoGSZpk(7Oq+u{^@mp6--6b6wD}yy|lP6-TU7@C;&69KE<BrT%d?N^Man}v= zrfiydi^t2S3Brp{Nham*Mu-sHjKz3HK7lNSa4YapDnuI@TcZU|DQ-Gjc{lxAQm<Hk zyf0e&x$JqSEv(~rxU^+&ibN3(vlD)bl<*jjQ>OllXpOq?1ZfV3@Kup))k0j^JA&!y zAxedPnl!xm9(l=Gz6-@{<jy_@)wzu1W1z0_@~uuqg>q!dY(zk(CCR_ovY52<Es$AN z=+cj#ruZaOOpnjxix8CZx{@|2tuDhwFGxF;4Vp?cY>&uXU``pP%xN*SRg0*)nTi44 zEv%!>kJeJ0W;LQ&Vjw<~0<Do3+oVjR3aHOy?6n`}_C&h<8vMX~FQX`>(wUjt0*g*` zv#iiNEv%>AWl^}cf1VqWaXFfC?P~*L!j0NFnub*Mt_1tPQe}#&ePPO}=Mr5{czpJ^ zgYs;ox4Gt?LZ0MSCdpg59{XMtA>94C^<Pfvp%2y-5u=eS1>SZ|R}I>KL8T4r3l&zp zRS}}6Ze_Uwtsk=si+QfU-b3nWu`0hW!rrb5bC%)$L!L9#GRuKr(KGqe8eN=#t&35| z`y+o94*>i2>}#P8a$$J}i*N-vPp3w|4S+@?00SPCid*90Q6W76YaV#vMuPx0A1C|A znymmj<<8Lo3O{Y2*z^^m3=XfyFOP?lwpTfU8%I28E*3L%$<Tixs#=i7$E;{#3MyW) zZzEV+JEK|hC07Fj4b|dB!;H*8T?0oyP8)?Vbur`#sr%4L5!*z@(N#ufkO4j+!6EOP zI7m`A{24;r1V~N3zmk_I;E!hbKzf`2n~X<8)ca~s_YdQg2)86jSWM+Cuw&uiE6!}L zIY0A=;%US!8tuj5v=}3)i}^TpdO&!L-<VvPkc1CTSEXl=(sZeRpLpqRR>oZBgI*^< z9?r>M`fiplOh}0x(j*O835VI0Hy{w!I3Ck(b8E^GUvA9(1L60VGt95IR~U2|VMNt_ z%$SCZ72}k4EuD>TSO$3*bG%-s>jljp`bJ#d(4Kl}G{X71xMTSc#Jbu2mV4e)O6iE& zr`lY!2?_L5`00LB2NO?;B&#JrgpgZWFom)A*WJfM>rgp`XixFU16PGY&QpBZZ%do* zjsOzLKdCxq)j)i01z-9{)j~WUaY8fv`6alSQMB2Vags$%OCYO#ZU3qmDeQ(YgvinP zZka`!+&g@hLDNwW!F{C^O)A}3z%L&ZrwDFDS1{994V>8L@iVr!erdo-2aodGy*bTU z?R9iCtNssOoy}%eQ&}+8JKyT+(8c9JY-+=Hb1VpXQl1_yNo}bfN7Y_-4SyFBk5$2K zl)4B!0}la}`u6yO7L|=c=I9-PnnIRM7{0>o_mTn#ujEN*ELGHSO*<v1`Q$Ntjo1<A zJ>1CpXduI*==66+B&pb-vqXZ)I=G9X;l)@4qR7JIYxT7;w`lBtn${S1WxmC@n`mz; zpGt2nn)wv5U)1)q1_u3*31PC7-jbP|@Mwm}W}q`Cs7i4PeR-vJ+eU#>5hXxt)`Vc7 zvvcU!VB+d_1#_6+Q)Zn-_j}fj05RHw&Y|ztYV&MC&+W>qezSR!)l2SOrAb|!eWM0R zkQ7PqGx>>9x_{Vp(Mb`$4Ff~sMWd?z{xjZv%&bbg!WrcG#g$5XrX@VjJw`<ir0sUc zlEw0MhOv)5J6l6(`rwx|xhywO@`HetP2+pt;G_&>K(+R3i@y{fQF~{npQe@6aY+Y4 z81faw8U{u7y+R=d8xgDqM@+q!RQKHxO}wSOXyi~8NQAbC(S#}!mn5&~QPODP$!ZCC znb!HXaO8+aVwsG?uYK?KcV>Lu5qW)OcuAy{(i6*b(Sf~;@0197g1w_9e*(H!EI@+{ z1kT2`4y{t$4oskEN_WqCCTsFR!lc?{tpy7SlIb=%~F1{KI07`uWrLDP`23!A0Y zm?f}BiLQJP!a7(Sxw_q4KwPV_6F^{qI1FN|Q)A7Xl_4MiVoI?scB%BY4*8w?(5VSW zZR{r_kOXxZf@uLc6$=Yxb%B=4sEzR!nCSl=)&T<PF@-af)WXd%GW2Vhg3Xsmm2dq) z7BnE{^R%bre(n2<#qBL8=2IZ-FpE32yJ<{NK7(hE60Q{|KWAU5Xs5LY2bzwaaXTC_ z*)%3|<>2@=<mmLYvL%k|iqgz9icI}<`F^FS5k`R0jq8~1R9W_gX`5*!TuG9Ua)3#x zd036It|kRF$H+(PY_+YSignQmc>d{35?}Nl!NlAb^Ns1#AL7L__xDjjh4iX}mq(}B zF2R~C`-W2a>w?H+YZXV=yS%ceL1h!!!M6F~7c_^l*ROjLyrQvaQoLQQ@-vrY^5}^e zlfWQdavlUsl4#|;NhCw2^)I4mE*#XopqjfioOG+Fx_6^=wE3|XzCoUJkVd;<AQMYp z4m2gYDj}N(SUkwl=WNN<fK;Kf(XAo3NQic+_H2k`m{?6m>O50}Bo@3WNUNv1TvHYn z+BTgjO<{ykMI-|!P{D>LURGE!yr?iC=JWA9&Pz$az~;V3u+i*(!4rRS_k?Cbp=h6) zF1KVQ^#S}s-*{ePIF~<F$=!=U0uH|LKW0M$h6ZFh9YDH<g|x<`PntkAeF0&rJJ$l3 zdcZ4JW-nPOCuScwUANgit~}Y>l8fl~Iwi~Mi*I`$9bhK^hFCZ0nr;hCeKw)odbYMR z?gq<<?!$c+d_=`Q$)9Z4eA_}P1fb2v%f{>gksf)4FtwVH$aOpTHM}P1?A_961fiEw zJ~iq|<<x~8fQRs+0N^3|m;7<TYa($YiZ{uh;%I~kPBEIEku(*sqVyU}U!}FMb#*0S zJO~&h+~P!cW^tAnb94cxh5;j_{)(TBSl%DfefI8{#eHs_4#*U`BqCUHq&SF!;9Hd= zC}*Vd*68T!2J~$hp0aT@;K}djEqQ)NcxzZk5{dvZIP*&e)Jdneh{+hXd*R@2R_MlY z<as5XN}h)Bl{TGV;M`jO7mjZj$Bo5YHupb_ol~zUz_z8At-Wm9wr$(CZQHhOTYK5I zZQHoJJKag2&V9H^J=71VnweE|jBnt;X6mvQa+2A~$u-k}&c{NAxpyIYWX>6QB9OZy z^eh0&Tmzz?rR9(7D6H^JQKr@bS{&`O{lky2E*Ef^DZnq3d?)BMw|L9jbudUNOg}|| zn}^agXL*-hiOifaXvt51g$?{LpxFMMAV5zWeRk<2V%e`$NXz6f9*tRpbSQ6xQ9y1x zBsv_}qBdImT^W$<EsUO?Tqev3Oa$?S-NhcWz>YHhV>fo0{LGu$?6wy<VjxAH9bg+? zFcv-RsH^-6tm=hk0n?lM#O5DKkcA7JVba|zN?FiQ)pa03-d`mHL)8{DadPqHE!IKI zu8U?K&XQUa&eHRUfHngON4eKZ)H7$H%U(5EenYg#BK9~_6S>6jX>bdZ;5MZ&tkd(^ zZ*w@<W#b-;K2X1N6JLPM5WG1XL^twp{j&9<gERht|FCas=UNoNMILcyy7o4cv(OI% zH!nqtGeWRJoS1M)A@3r^Q|13ou*V4tDO`X|vF$Xw!iwy*^C#k6Y<NByXH%o*1N46I zVgrEB6AwQsW0@2ym=Y-ylbdyZDI6q=B-y<0BK7n&jXVQ3*YXcsX;FGL11z%@E9Jtk z^LS)({$w>RN;cb9R*!I{tB59BUABY(Ee10m-MLyyp!J~-0}tG*OzEQYwV@_vT(0g7 z-pJ<rAX_9I863anj&}aoHYi?r_(=!MHh7}RV}LKJTY&lH9{v6xbFd8wHiPg&{?7N2 z7a$Z#B6gJn*O6Bu>fu{Ok3+Ave11wQGfQ@o|F)%!O(U?-sI7>;VW;t>)WM2W8`Ks^ zP4!%9MIQc&#gRm^Oeo5%ol7z`#=jlZ=;tIeGqZ%~TctmDQ)*cya@jV-=y83^{JGJ{ zQpL$pzj#^X%n!APp<^G^ORUML#dc+T^2qUH3V;lUd4E03__o}v*|r6e@DqiWI=Qhd z*~V{IwHRapLea8AO;)X{Ua*|@0wrfgw>rYU^A(v4{{|s-h|uT|kIF7nY8jk+;a#W4 zNN|?0=sFX|PoQTJZvgSRC;-%dTegVkj3j93{o#O6D`0W=zA6i0z0Ek2fU`ftQz}Ca zEdEq3M#V!7G+F^s<sJNyMEF{PBZQHC>{(o7($*@(d+Wov;i=B)6^cjZ;g<ty0B+M% z{$Uh96`d4=_}nP7)YCgyGRH2@GP7^e#6YX(XEH1^G(#k#DwDXgl~r0(jIAu{O=mS< z5ujpt;NVQ=@bq?P#perD`dZO1xKFdtJ9XsoMx0TO@T4J-&%&4jW~<1LkyR3u&RTm~ z?}JoldN$ypo7V2#hwL|l-M7Rsa`1c>&(4LE6)-|%N}k>JMc*;Wl@#LJM%(L<p@i=- z(e4((!(GYINQj_P^gGLBP~={3x2cpv%+k@SAoBh<a{41%A)Qdh>AJqu#xMnE2Sd6w zLOla{`7AbLoe9c^8RMUK@-9eDP@GwcVKtKM6v9$wJ@{Hh(I1;^>*}%B%J6y81*SIt zQ3B{JG8#kbOVn#n_X6&FWrP*t^PyEtA7Nc5Wtd|#ZOJiNHtJT~7CNglUcZl&KNBhk zJ<sZGD>Mn4x0(3H+TIPMKLQquhiouHBzJD-WN0^L<Iu*S0(`^TR-h#n)-t8?gifN= z<S+iX@9Qhj<`Macn9aa4ip6I?t<z!Z^)*>zbL=Ypx46bzs|rx-{d>VJoeU`jI??43 z)xX*p5$)^w&O+YSF`1Eut0R<xh>s&~JFt2XH1YvD3GS<jQ^})4yVl~=xkKy&SAvGE z)koKCB2PA_qbef(qzYLmmlFx^ozM2s_>pQl(U^pi5J}@?v$D#X8qvXr%P?)2yv-9O zU7u>12)Xwpi@{Q)a5Y~wX`Ua)SlkV-4C$d3#;g%TzM|<c{R~u+wk}p}VL%meDopF; zw&}H6Z6m)|+E7-M5V25A<loECLzEJ1!8SE3>!2QrLHqI&uM@;{bO_A%pRB64Jm<?* zcTrLtxjs5;0G7a#Pn@7zSJOiH*szBvg`Awmc|ZqJAyV_&tq>&z?<GL9RSCMt@~;jc zt9mWNJ%C#6y-}qDLeJ3}28yl#8e(F5U;@5FLLE~qAAKl*3s>dz@FRSu=-xTG@P;w4 z{rI}BZ#jG@M@*D!2HFssr0X+gsA>PJ?qspdCclv_Ep}dymL!=+1~JB%;Stg-vXOpg zvJhE|cU1gK<C1`$b4tQFK-b<W@}WTpXN(Xx!0b{*Bg1}BaJX5%`>a^6c4hXDmE;<R zPAQstx}ZG_`!(0>srbcB>DDz#z`Y4KfV=Mx_pE)~^xp5IQ`K5Q7j#UCFE*@;vf1pc z7(bih#on=aPjmfLj1;oz;gLh2FLK<oh_v1%bf%3ibC>A7BBT=&5{~a)G0lCS&Q@8# zKE%xa7=)ZIECNlJ;};&+^nOR(aHg0k8D-hB97E~7Ym<6gLcZqDy)~=u5n6pE-Nz#l zRrp^~Cz5Tk1K!H@InSOQCd{!z#$2-2EMZQj=wHIUD@lXE>-<!B2(Khle{|PbPDQO& zmqkv-=#F<>s_iWZhMm0E+M3^O8E2Hst&X0~TRr1-oi4w08u1<%`i~BNGl<1ymDtsa zX*7>$ipeE5OgJBCL$vsCTB!9*ATYoLG{_QO$US+zVN{+-)-HQ2nO*OBcUd|{)Xn4P zhcj}ep&6}nKma9}#lL+n#`=4VE|nPiKZNWB>TR02_L`|fXrUJf*lji`Uv1K<XBYG? zK`d;L4grt~Mx29ALQXB%<(M<ej$Qf^G0QhM5F8jf(cB|;;<1n5uU~0M#;IQ`e2PP> zU~byQsVHHS5XlpcrF(823R3Y+wVaFml|jTsh|Ex#1{TzNSEo#B%nW>Rg-Gd(ZK1%i zqbm#0hC%WH)$k?s{)Y|~6i9Hd1dz=dstzp}lx?ttbPu%jfB%pKbwD+9j|j;4i7J6f zw?LURTt=2!p3#)eMM%)dtWgZS{>zi2Gm?gjX<gt4467X*TVRU|M6ePrrHUA3nf1hU z7_&(5$zeGU+iE%|5s%V~r{DMRc<t;E^{i=M#os&izeN+F41M9!9tT{E>L9quozCm* zu@d!b180E;;cxf-EIahCC|wOFO5j!#IIBfdS5p&E0wgn&?^Ns#u6Zp#mB|g>L(srV z9_39&fLuHHZ9~(Xy7(q?TffTYl%{C59mjEMfDD2uan4`LZ;@EbG_Ezk|EDBNF7--K z4mcKF1zvcLu#Mt!-|1SFDfdSmy`OMB@!ASeww+CWDC}eaA@!dcp$j+fyF0!L?ue!n zEix2Hh}Vmu$LGyDk3f_x&EwFbsu8@Mv%Cyb5F9Ne@z|<$Ss2+yAx^+1-ua^Oh%zx= z5?_B?Xuki*b@)J9i@%JudaJ1GlvnY}CGh%PChXlC|II=GwN^z{TjHpPdx$h-{}s}v zRz&cl0qEviX|3_GXx)@zFL&BZ)mjC>gry1)yqd|sak`i>u(`4$$7LS^m0!1*494h< zG1=kjY2EKF?8SS!gfX*sTB%~_;xg4zjtB2zqQA<`eDXRpktsNFRA_-oDH^pzuT!-i z)mWzAIEX7cGTcu(5m|+IHS9m}Z2B}FaAeuTRGB4i#Z+(V;9s{}tg7wWv%m3lr_dX; zSg(j3uy*7M_}MhO(lh1SK<0^7(*~SG)5f|s%aAm!KE%R0;HoI`JgdACA(pZQ53Q9< z<kST7NBsaDaf15PyMY-3i*5xKyw&=wX$Y+}sOpmed_)%42De*i0Uc8eWXOg?bcYQo zWFMxXZ%!PlMnunntFh3knIAxXt?|dlS1?6yb{7xH<iuC^RDw)7*B4W(C%vVbpFsVs z!b@33NuBd^9zbG*%E`;3;NvS}p^d2)7a?8m5QinL>1Pds+9iyZ7@k|U%`gIUG>#I< zPRWMSLlC4@im||QCNl#zYENz!@6D=Pe^q=#51tkZhBoT3x%;a)v=VVnep|KeQ#XX* zt8z;P&4Au{tF&|j0aabQu?OpJW}<1;`*7`<e;nJqb*4yy*;Qhe;!od6c1p={>Sfbo z^W12;weck8ZV)n8kHeqTv;wSgGhxUV-;{d9__w%g<;C@O+n}n~l)76lEP>5E+~%?H z_n+~M>0Cq(eoF|%(;1x3v+@_~u8{4U-Z9%_V?IiE_|L%uBbhU&xB9U0W_J_vBAHwl ztgxq#KzQrAVgN_R4S-vr5NWroWr&#TAKmck8#N{|4_Ajxsg=+HHveulGwXrQNH$HB z`Bk5VeIZ1%K!y&T@I{mHQ{OAXdoxR(D1&7k0k@y%3Q2)&0MUdJzB(kNm8BE0ezQ#f zeUnTFT#aaVN`M{{!}(N$8-cy4l9S`U9U3tmly}f6C3quMQ*{1Zy_h)@W7sJrojg-c ziB(}Ed!i?*P#mjAJ&!~fs@bhf6MYBN++|5nS3OB{=QCc7qs6v0x#|NG=@f)v^szeB zK@KN;y7bb-?=mP6LH5DVRLYm(<ZcEQ@{H&Ol7b93iB!s0m}n7K37OfN0x;k>B%t)t zJ7TvOuB`0~<P3ay0r=z}h=@XG+Vv!mI3kTb8FqrzDse0&1Ee6^#U11PFY#9&A*ZuY zeDZopRA?7EMI2(hkwzoz<6qXjC;6cr&$07x6*rD1#^VcyDE>5W&IJtp?*V^UeZ|vL zAulduJq~l#;ufrwRv2r~bbv(-t?lft@t~ri=2D-tp#-R*A_R^HTXtylc(_8JuGyQY z47iNUq1Z3DqL4}b9}F<B!VxcDI1vL|dhE~@(8arV4rN|GcvY~43LbboRtF`zGv>C9 z75sewhxMgW9bpv#wTe}B;0dUc8xegoZV5epEBD4iomivo`n$dX8h=hPRG{)XISxDL zK;Lxbb4rpwh?14wPRS%7=nM#3(w&rvZL^$2et5F##b0cM+>gOx4v?3OG#()YQHHlH z=pcG5ruggqIeALhjCfT!4eeFA274sj`LU|?Yjm_6fQ;|?6xHg!0f2Izlw({lMoIxd z0nVinK;un81fb3r<(zTrLHD^+5|J9F1-*ctD#a-?nf<o1sj}lzE(udq$4ZjkH6C$- zzl_{eiUge?qi_1r?jG;7M&?9q>_iwJNpeL$abx^{m0^;{ax^KxVcnqovsV&PW!6bf zc~E#uUmbhb=WI_O@ONMhalxaleL9~l?N{rYbc7psV~>lFM%peCECF9@ZQ{Du9foRj z=`C9(k(Z4v;h$Ho3`y=Y=Z^)Ryb*ZtglEC$AOH9E{Sn{uM?qwEMc$^>h$Z8+EtHdQ z3=RHaILP}RUyu9$Zby^ptmU$i4tCOIXbyMkc_hm;E5@*$A#;|o1J)rE1Qc8wZ9?(C z6#mkM)9^<)a;MSNJQiCPbLg=@^7*4Wh7$qHX5mE89WyWhx#tOFL0T+97vG@ac^F<k zEy#(WSgz!{&#r=kqDFxfvD6uMzuH;Pnc0~!r8RoIjYO4XZ{leKfGrb<|7@A7kKRzT z%*bBT0yGdkUcF)z6K&t<*Cn?hpF3_+Ol(;x-nu=VrE~Y;WG3Dm!hmk~2mx1tRyjKZ zwm~$c8MS}oUSUciwcA2V!G_e%XGh<4b$eDMQLf(FY=9QX^2eTFk8T+~5(lUA!^p28 zUUo`>Y!Scg0+jo(sDIg_0smas`tpVQN;Yc51~LqHN~>Y_9cb<C=PX?Z8|*CKU^;Wg zxe#&Ke{E6cRmyV?n_Uus!?CHA1Zr#d1d%Sa@ndvi&m-3Zsyrudv6NBsKwiPm=%57L z6dZ-&0IwfxMBxo>!Y$us(G;KLD$ZTbfg&yS?v9%z#0A_$F;mEh384Y5Ji@Hp%#Td? zQQF$>H!{Ox4~#v=W-cn8*0;|A$|@;~%Yc|;H?>Pwn5=oslYGhjqd_XHE&N;u*L%8# zm9^uG!0x6UW{=Z%Ok3Ric%QT~TYMiICq17bv@vyY_HtAgj~`w;jRU+o8;yBn)v_<r z7NC@XYf@vUxZ+V=Cv}nQ{lRVzA5u^Oem~r0e;;5jQgs_Vkjm@Qk1NP3LG7e>xl>?X zSB5m(fmrUB6YsDd(>xKs?JA|OSx18G;mSh%-BbUi*KNtk807I>ay@}7l_5c6*l(wR z63Q*(D^KURcCYl)nwR7&SjCrHkqQsv@+#@2?=lqc{5bAW3i@W4l7)AQO1fZ5f|a4c zPEyB3Bhj1^_~(|lUNS-QK%rw71DpPWaT=3Ss*JV5<}l?}qcn8xo!Bjr*ag6lTr2SM zScJ0kS|}pSlBt;^jff&*F7Jdb92%bv>BoJY<9wt9yT9ZS_rZ4}f?iNn>FtLQ2W{}5 z=x40)1{GoR^?qA7%VXK8a4W3Y(XdTiQlMfLtA>S9sd0$Jk;WNRGu(8g;7jwGmX~Im zQkl>ca_<4BE6#6|T3a<y<4dy<rcS-=S!fWDBR0HH<G?t8+?3K+XAjmHZ_jWnV1j+3 z1oOB6v)VgVBi-4he7?H)Tgvd|6}8zVciXb#GRYjhhPl<|1E+_#>tPc$y*k_*VCnXh z3A{Pj`UJj_3I^y=6Jab|(WN*&NII9IoZZprxhwFr{Ypj`n{U<xA_Q^Bk(<_V5jK91 zL-mkO@7+TmxjRe&N+)UhO}QhD*mQqes>q8i*kTKA<JC824fGSBaQ0()f9{DK64RE) z-Ew0*-Q&ex_YpE%<yp4MW)`a5nxh?3Xa9kdt+n3jYj>)eySC}(VcEoSBXIWt45<rO zA+GZ|C_fq0x11tu>4cmZ{rS^+DKR$_99j4a|DQ|=!Epz67bpOLbNqj}#Q&Zt;b~!S z{|_V4qH!6!*^csaTec_br!I@!(GNsJUmjE{Q3fG@1u|R+&8%)t9)ampgeB~0nr#@s zEA0Dn{vz>#lUPWu;o2#{WzNRxVauHscRJU2v!TnhUR(UV)FR32qJ0|{BG*V|LK0f1 z7^T~0QxY1|ZPV<&kTMmD;_{S59PX;xSbTgW@FdwPLz&fR;-^2~#_;)l;yHY$_F@BT zphDsZi#VJezS)b=L%uViT_;=;Tmq-M9*ff4p;<yvSIIm)5cce4uKOE4ESOAv?M{bT zL)bWa-qqR3`1>Qm8y@OlMCq0M7FRATvm_09=RgCMiUV8YCL36jz8xhx#~Y-1qFmo< z>^XZqpOj+Y^?ZR+RlJbUW|U(S^=xY7%2&;V?ip$eJ#a1F(Zes9Y{D-^Y3M59eiAX8 zI7JRt_AH3^VJaOeTq$`%DCv;|UGiD<>^!AAa@E!PCyM}K@%vYfm|G1!(u260ph-U4 zX+zu(5pl8+A@kpu*t)eu;mO2jy+jyed`5VJ-N~$}0leg@FyfYa@er59*1|(+4Sx5k zRJXOi@NW@v3dw`i6Nzc&WTebmr=%s8RpqQ8a+s_?A^C1F)Nc`hY2Q(su)j28LG$}C zlR7EZ%FBZ;Yxe;7-NL=LBuXPS0ZeST<vO;o(vUO`<MtyD@2umM9j}9xh$0TSm8Q%; za9O%z_M|B5t7_3RlF6~nljC4z>$m$^;-m`T-q2|xa4R8+Gje)LF$Dn`b2)PiIM<kz z$8d_F-9~3sFshwN9bs7iIG?dwke`{E=kyk5hFyouMwBRy=YB7M3{}Jjg)zK;2vZ2- z6uC3<G!b7S*TaQBLITl~Zhh!#V52p6@%x=vNk^&&%~LPUR3v1OlD~bQzM)FiB|Z-| z`wh_Pkr(!kFdxnV_Hy^*9ugCk$zh4TNwJXRQp4%um9fcYQ>?Vx6;T#+)MPKYG&-4s z^6@MaHm*a}#2#@d0xEg<MG?K^7$>0&_h|%Z>MO^iV-iUnsAzF>V&+ta<~|4<SHO%v zR)bv?xIiOp3XciCi8%g;m)b{qPy=usB>F3)Q#5!DX<j%zgtYh=p%N)E+&V24B|%8@ zmR+LA@=nPJ(a%`XC;s|cOVbGt_*(7Ybn^-4F8pR~a*eWJQ-F_pw%7b^S^&Kz%N2pm zLRM$yvG+7zBzYbA!*#*zY=>+6D)pbJ^5hsn<Laub7&lrw(K=V1UDqCBdKjeXwD(3X z2bc-~s?3|vG0GS+ARw+mW5(nv`B;bJifR+~%!nYp@?@D`@baqrc}R4}<R9Nb+pG)m zRo72*$+u9dZ?&MB_GAzON3(!QiV&W;z9=-BH$kn{?~S5%g`_1Lg3{7{Qe%m;$a%z3 z5OvbkOj^VvGL+NoBYDqeR!#dmgcK!rTO4*R^_ddg4rNv8e;FGxJBZ9(n6&D%TpG%w z7^r%JluE%yZn^Pf1hOJ^EF1n;`NMgiz1OqEK^4Q!nsobxVSV$UdSHDKOLRqBzXu>M zxw&}#wYuzsh%huzFTf+j^Jtx$Se<$GUxkTy3Looo08;qiv0(+`N|N>`2?3P-k%<@p z%A3-5ST8>iAeL)w<F|=vq!J*v3b^0Re*}cw9o5pK7-ghH@D`SGq_~d@7p*Vm7QIAY zdn1}Kqz{+7p&fYL8PIJ%SQmefUWCaFoP>{03fa&fi8ZORz1IwHF8EV~&I!Ui9ej9H z&mlbidjGuA<^6{IGUT3-;Z*y%Uak|<h<<nr@*Pu<UM}(&ym<rb+D}&$SS0b`w8-Du z=15uGDn;aANQ(~n>;5|6ERe+UbmBSQZDa?P0wz7gl)i`L5zVx|19|x7cCST(f-#uf zLAD!RYA$Kz9*2nA$G7mjdNC0kB{NNE-vLu@dW*V=EeoJ+rcV`(ezcZY<OB=nNxDIA z&27Oe^yF^{(cDeU;Ms@~<#<5R%Ul3!LRuo~Jaj)_ho0j`#EZ0sl!Ojqm?ceQwshdi z2;eiO3!;(?$?+_lLEgY)O>Y6*uG7a1t&<$U2<0tXZb_nXR(_+aCzAB040xNZ`dK<e zWk`}A0aFgW2U0FR9@Fy~X$dc`G1cm^lI3aSfnVehvytBi{<#aKMC$ZV(sY^0JozVr zgR0N#yo4;%P>H?%{K5ayHI`M73K2cr(PS&>EqJ%!hnYV`w&){)ZJPGUAL2o8nW&S$ zIK@)mR_V(xS9xjCHvq`(wB&jlhw`hD;Z$fGy1I$Qc6AfW3q>xo0~v91bA4;?a(c|~ z=pJ9oS4Di$iHe1zI-`FF=w=<C??ayf*Bu`S_fA#`nbbq1Ir_~}1BYI4b6a`_afCg@ zt#M!c*pMn6MjPTRznaquwcPuGnxzqMqQ!_<T|_07vDo5g)caoCuC4`iiV@8G!Cuda zu-Sd$8=b0kilNKOCz4c}y2f<N&hfO~YTwcM7rZlfPRQ5>>urrc!!7E#+YUHuid(`5 zb;$A=(5Va+WOYjdi_;1L5!MX>9Dl#ofas6Q6%G8;hlO<|UH_3kZG^@GYIL~}p-o7~ zI}gU5WMDcu&vS_AlWa*RZD*lJYd*{Lxr%fUEyUVl2aoarA%Q;SsLbBe0|J}m<B^3E zoM9_k0dSgD_6Ltc*xkAbk%@Eu!BlcQBKDFYmA`jnIN{?RXX7iK=kS}yv+Sl}ZT^xF zHP^?xxP|Gy=UO@%0n?b!76utI03C-gNUdJ6l{o+gEew&xu6b&71?^3A*akB@Sdo|^ z)J8sJecnCL-C&@fm*>J~7x!lLl|dLZX5dx+<K_kY>0!ww7bEPvB3qkadQ+JB))p4I zTdD5*+ib3{btV@vB|WigPx|9@(9SPA&P8+>pb5-EG#3X}Ny?G}F#ehCx_}~esW2R* zE=*x(sVWXn5X%dP)%ER{v>Ey}&m)N|W3ygtzQlc<U9L?GSj;`T)*iGaBnpbhRzsR* zH2o9o(2|L#%Ffdv-Gj;-QAFy*X~C?}iw)iOYrNg{goA9VuHVcxyD%vWRL{D9aVP@H zg<R_WsVZ4LRf)y*yOFS<S1?8XG#R#NKai8=Laz)82HLXTQ+AmDNv|qHCw-~Ir2ux{ zX={#4gFTCE%KC-{NcuTA{<H#eFy8a|;VKGtu}Z}08zY7?%E`5yPRlRk3)w&A)<mWK z5tPaPOkh`_-HeS%eL!ij4oPjZYC4pD%!6JVeiuemY+w?auE>CjA#_4M&JcTq7JPG% zc$GIoKh7LV1UE|qL?Ic>OwaPv{;~v~oiEbS8I9QCbLJR{-n$l^#?fh7TGky<yVFRJ z+GjAUh4pp?-_6a}Kl37fJ_w;_r%Oy*m<;X;dbiB%wBc_8%<MjG$P^trWwcu)wS7Q$ zva+%tbO=V%qGxl=sYV8EP&jFSiGov>Etl7!2Srk#m{04HXvkkQ`Md_L=6Kp6vm3Oy zyJvD!)v=5;vb^_~@O>&i8`!!ki^y12eP3p|jG&BD`&riWG{un1$60G!%^Gw$v%jU@ z7Xbx#W}v+<f8#ipbG<6vkw3iI-bwbBq;j2`KK{REmGvy;s2m#rAkYi|fZ@MyRxNDo z?Hrx0Ee!Q+Oq>mj4V(@BUr_imkCoHbzkB#jg+QqSa76M%sYe@KkwiGon?{pCLU9Vu z3_Wx+lUQF55FA$CBKgbnoz4a(C3#PR(n);-#KgnHv(59JY0zPlWgDLPlYb<aBcB&} zEa{{DjJGuEyNYMsX^Lf{L5%mU&|2e3(<-7-L1)9Dt#YjBW1~5bBD7d>8}!Dm?G|$5 zrQ__Pp=YVgYSe?7S-Jo}A>cd{)OtP{#~vx#TtV4@IZ=88Pn-!g*{zO718|0>(2F7j z_;+Kw$WM<&3jlxfMAdKk_ER>TFVci0H%f*<b@0)Vg}QLD@JgBtq+o*#{Lfc6X4S=K zqi&R~!0u!xUS#C~-F5BuvCTZJ380)JsMxGp01$Isrb{oSs+u9-($#0Tt!2T6m1Fsf zh>OmZr)Mk#U10<5ZX6*Rp8kg5QYDeB-ZKY{>TRUdJtA%mbnyh1yF!E#F=d+`3rj6B zb@9bwoXuv0E+Y_Mv+iS^_h$8|q`M8{9_2FJ=#WFYY-0f*8NOB<C~iU9U@a(^LY*(I zmwH5+NEAHUJRMD~mI4ko_7TS%=WJ2ZSu_MLUs$P52X=!<cRH^T@)A}Y>CU0r^qmjW z$|ai4>KW~2AHYkKE)VkaT>k-^3D22XRwLra<O){HvBD=eL@m<oXd_dPLkUKRQ~qEj zP;P{vI~kpYOSaiLLq9t=x3?DwAqTCv3EncSI8p25-Z5Z{W|U0wslP(*KUoxOBh!zw zA$k|*26nF{GcpSmkXZiSF6~FKPE+Sv<SgP%QmYUT!_^b{+X^0Ge^?YUYB~TijybHI zyLExYU1*4A^)vGM>tZ>XZJfCZp(e`FtBeO^deD?}Fv%Y9-&T<x#OR~L(YSL^d#ZYC zn?AD~@|B49%vaEXv~;t4CW#*|bh7>#3LY^NK_<=!uLe&9x<YsnmVq`d|0!4Ku>f}M z6&bRXdsrSQ{PCbHOqzoELH(jIT4L*BG8k>JxT!7AACSoEtB<~H7qP+x3FRO}34rj= zK-4^sw0LJdL|We55CKJ*=M#g#_*AfkK`kLi1mCw1h|NJ|{5i0n^$t^+5BzZm_i`Ub zttgf|!9ot51_l?gi=4|krJ4D<aFHjrgAicwsX?c*>%nn%3)KQjOQdleIq@;~wgtn> z#?i_^A2c$?Wh7JHH=-^R53-F)^@w1|u%#(+Vx;9j-QtQxtPsUsv5sH`4MK+_5fD$* z*0e7WJfU01Ygby9h2{~3@yJ^g+m6bZOa^Nyp^k@AY;-6tEv4Ft%;Io8vc_e?Kpa}Y zL{ni^QstF46%P3@;+9g0@|<?{{pJX4c8d!~Y(mRkntz5*=h9XT+ZrK19XK@!Z`3jc zK*@~Va8H`Nyiq4+L;V|eR9{O7<D|DK@E|^Owd7~=Y_u*#Wh){sMcWs}9971C4LJ|! zyoGLig8L|@bFT88Be;8Qe~Bhaum)eQz_pIgA&XUS@>L+1Jd?kH7_ilZk;_ok_=P`+ zFC6uHtADV9jvIrAH%(e!v<rNolRJ<HOTQq_B8XGvXiD%k%^!f;ij=luioyE*Vh{`T z?w%X1MqY?Z_29yrj8ON5U6ynNV{V;{Y^|D;%8?>)+kE#f%DCnqL&r8EY#s&nO2M4b zGtc(F!{TCZ{Jflh1wi0s-Rjj{p2)rK!k06P16f^}EFiF0^1u9H_^6{_7?dNxw2Aax z<8xujA(59`bo;11C!m{9Hc8fm<{ibfGjK5VEjt1d{Eqjhxbzd2yP%>^E{0l{lENt3 zBy6A|RFOOcGzFjyVWQy2xeGYRDrU34ZgSR0&M{n>P_tToaP=^;t}U+BX+RbAfw6l> z&Lu0Go<m5PAU46xV@r#SC)fmq(Slf?>gPK(o)r%JOqwpbstn9O54~QUH>*qjG?sRC zueKSg*h-d~`o($TIox{1(K!bCGd70UK&(VdQ!F%sH)-FdOA!N=-y)Abno+<k3{0(U zv(ttaM9uK~xef=32>->)<@%!4;#_I*M%|o7Kx7+`o1p@lEar&vpiZX2rFmg>ln3uC z9ed0fljreou}klXO8T4QJ37e6`+3dD^-KC)^A~FqHg+GdRgk-y^?Wy5buI9Z*Vm?o z>uZ~n?PFbov8Gl552!ZnXyuu|;L*f>Xa{QfR_Yk!7}|F&Ze(1uW5^&9HR!4u$rZ`w z!vhqv)nYgB^9S5g>Bt#*<JlCvw&84VK8vuJnOu_TJD0W4I*le6M&SGxXz6;vNGJ!> zqbO*-`6d8QpPy((C#nj`J8}+TlxDsozep;OiQRfMFrqPnPt-;E+1Q`}<;ds)%O<nR zvNqKLp(^x7#?)is4uda#Asl!C0Cte3p(}AOo1O&m8&wraJ!M=AllMty@9BhNJ+rz- zT9B&VN-0&zw4y0q-;bdjHI~-h3COLiY93P8Dda1gkqYdZSS}fO(ia9Ul7h7lX%V1e zRZ1~kAs$<PZY5572`+TMp+C4@Vy^Ia*c>sX;yRq#Fus>b_uZ-q-9HHIG|0R@jszSu z=H^5!AuR1NS5X)<k40wY2{U!G8zB*-%UHO$1T{*$$r(YEdMhCnPa6_NDRSF7yX?BY z^uZKZp|?ZNW*`}TpbG3}s<8mJ34wz2skePZLz}CfI9P;~{e}}Tk>_u)L596kP$R+* z$6(+L_>T^nN{aKn-RkZTG#V1F6kQ=ndcJ#!e4+R)ijcLvV2vPaXn+J!lx|>;7aDbz z;bzxDIiJ=^>Xq1ngGM019|gI9{iUh$uQ^#-n<bgWp=zDJOIl7URKUzz_jUh|to3Ht zJ?R3werB5;*Ho%~m$wav*M1o3YJnC*m*3v<kM*B6tdR9XVq=pnH~?t$+1FGip?!b2 zX>af>ndD4GN)bjh2Jwk~rmyha3S+iBF$LB+K-KpE>F%^|FH}nWRAuD~8hmq(Frhfk z%J%SR^NHDJ+m|1;jO{p7doXOQi+Q&#ao?8x@K?QmA05W1^0UD(*W;{HKreM?6^#Du zl~$kP-2n{}O15o>{u}{Ua~PGtw}!0#mtdx>4Yw(od)I%R^HTJE7(vR)8o+~xPm(mC z%u_N&;at^3{8*xJdZno&O95{y<iJ)f3=iA>-Bm_Wg`fu5FG0G}<fm#z_3}y#Pe~?X zFCRf-1<z>O$9W@YTlMQ7e6WS4l{b<mxGIBY<nb)nmr!0?aZ!;$hSZ306jF@Y#dJGY ze+h5x2-ol(7@1EZ)5LgITxr9eyrI~PSb+3*skOEZqaAsz(S75|xRXg%ESoO=KilKG z0fiusf>iQET&&#lwY}hxVF=KR5{bj6C~F<^TK#k)w~j`q5KQwYnlx=IOQzQl*nWnh zYwF#sqGS*}jQG-lT@`fyu-~%BNapsDJsnAJ++o-X7gY6!zIq|Jbh7Aw<smr4RL2<5 zB}d|83FN2=Il!3xQ^v~~TIxpz((3}m6gHgg)aUKIgFK&7ipIf=Tm6iAT(wDZG}1?! z$|OkHnq$`}E)|}ozK`%uG>|glW@SfZvkfn>^ECgEq_2xQ7lOgNn)i(lys$eKcw3Tv zhRxfS!bfpFS*_&f$R0SXVSlr<l85fA?tE8*`7{$x`(s@SyD8u)K6Ui#p$xN@kG!Fb zJ}JSYI3ILHh|se+Z_ymqVaotzO2#6ilWzSP5jt8CxMbH3NQ<-sS`dIBoRp+?l7@VQ z@Fe*gCgv9=bL&3iHp-rj=Lzx%?@rxzjqhxbPco{L5SREy+}op4AMsZyJztAF)&voa z&rh`<auVw8i=9=#l?pXMUossx4|!7M<%uuPpm+O36l19Qafh?Lh~pm8l{R&*SRFRN zJ9@f6TzMzzS_K$M(%N7UICT^tL_)>LsbhUC9_Y5K^N~TT73zv1BwQSv4a-svK~l9~ zhM6A9a_N{MDfKgneQ-ud!qGy~usra9wKlRR0f3i@Cj8fQ=^LI|iQ<{~7tANRPV4Qm z9IB0VMGSa@GT2DGE6KOyh?l|@=Ll*7S#j<JmqK9#=a@0*4k!eTY)FkgNEaDL9h<&y z3W~=~4bc^TDIKyDca(&QlQz?wwL&z>P%<_)fr$1=bF-)*0EKpoJ=V7e(KTCgAYvQE zF?0dDhthItje2-1{FgtXWt74`G}%B2awK=cuTt@!39Op}>T#ey{0;DN9wx=Vnk%ZH zv97V*Bt|yMw800A*7gCwV%ZxZ$7aj7!3K*uqv2``U+6L+BJXx*IC#$lZ-?+gT*ZQb zixa!#ixsLnD53<)pSqV<1edBX3R)w}#o<pv9;{qHTBmI%i@Q%6(dq9WxaOcgqV!l7 zQimN?3$$8>M@5Hc6#jXs;wH0G;ky3HlVfpuyiEwd;?nwEhJvOxi=++Sm~`TJrL6xf zWauiVv~2e|$>39mtwQ;Khuy%io*_vY<nn~+{{Hp5fNHaLQAu_YwUlQNI%sg+RUVRu zNnVcdtgO)-cI)so0#AF{XdjN3W&^Pq26?W5Y_h5m)bg)$y5DC25J1>#K=kSqolkZM zCs4byksYNZ&Xyt5mo3n_T*KUWP%*uOZS@N;hD+GFBMlhC$8p?XzFt0O!m4Wl2m#E5 z5dxh-tjb>xwGwGSt=Ii5@twK=$=ytNY`$dTX>QrVrO3Vt5H#YQp<7M1;e%0=Z!kYm z5uUl8Q_eTilApM0K^t6PZO>xN<=h7X<1!DeItb!dS#g5#X9bx#cQ#>qnMY(2nid6C zBr?rj<@IsE^!ZHtJNIVguA<7sDH_?V7YNc?)qr!DMz_Q3^Ye7AR2Lc|8MBpI#`kUi zbXaxkcdxk<5MkI^e<m=lJiNAe6G{rSj#Zzd=;7QFJ9K>fXCu_u^O-&iFKh>xgcXYz z3BbSiZyb-P+{&M~Wuv;pDBjN?o4x?XFcoy|0S|2qFTnWZ@TPfjq8yW$5zJ&&9}4P4 zgHYsHri=Sx+Tj`9$X@VX$#QG#wT#||)9J`TmnAzDtcynDFQ_U_?^GBqzx8ahQqMew z=0^_a2TUuh$_My{nb#s!;Zh6YDAyE&i55!08ZciBNxRZ6QcfT)DFVn(Fv4%4RM=k& zXGH)r36oWUS@%p;d)h}q0p7OtxkkXLpk$sMjmCIy(D1-o8@wkEYa$67b@hPQDpOF6 z=ou$+aCn&=96#MC-)iw_y1QXeOnOT;h8;2sK7}9>@K#EEQFAMFiHr#9e|Yb8y1Klk z+8_cA`~Ar*y`RhHCN#TvY;5o(!JL77QHNBX%9yE9E3K<J8U9gsHUSy$U<ZE4xM02( zNOqsdrOksJX8{g`&;T!ufkj~WqWn*j#3_*Au?VF8OwqA+jZprAnn-ElHy)9p^N{l5 zU+jxWaedofT*MIgXJx&YSJA}DV*4?gebrEWxhaZR{1{J4<14b}_~mGxy)ke?#BGy+ zQ73V9{k+p1Ndrxvnm_Jz_~!-S#<uuo#1$(?FIM{4zE<E7g4?eni6$}NYJGuI^qV)E zDLw?JxcA0f^P-={)~wNWnX|agHtYL{WX%20m9-*DJ%tY!KwI6t5%sKGh@e-6?A7<; z7iZsVFitnqQ^Yk1uT#hv_`F|F@ANb6*|f?`+-09j83_P@z6dN9nJtz>w8hnTNwmL1 zg-&fjuRWQlNI2_6Vu7b`wgX1>m@is>6Cm(q)K$m3uSqJ;U~5T;E2f0$+wQ^;?ve`! z5T{6T{9R)n@t>wws)Y5Sk$w9jOPKsn2b#@1c6OC`0TM`|f9VeBSJQ|P8vV#+0>f4; z>0!a#Lf_|(ya_|eu5zpr0A9Of+kmK<(48#${|*{5<CHzw6XA`d!iVUv5vh;w8KhJt zk^o{sX(0dE)GqIE159kM9AVKKg*|hefDHc-T4!Nl1$4OB*&pZEa`j?v<wsWT;Zi@O zb0Cj)Dk4YZJus4bmqPHB%4^e4i1KU^a>8U)P)V!8KgfmvrGC2<CgDYHxex6)2s%OK z|6}984c8vp(;HM!g|m4zjF9Oy5(`eJK&%!z=`L>*E{plqX(wVLgTbNDCxNfVgk3r* z$hSa|lGW;m?m687M)zaeK*Hgn{Aau>f&?)v@6B5MYJj+>b0&i{GK0JP0(~svN0@`L z3^pbRW`&kHz{QJ8z>%8=te?G+u{3wF2m$PfRF-$#&b0;j$9zGbOVKfQ(zn!ok&HMd zFSo3hL%2EmmngExZqILsZpIgUkevazgi*6}ganxE#hlv}h1NqBrKa4S=VRj`lJCfA z_qS?ChyF!qxL%4u8ycfgG`~IL&J`9uJH<I?V$~l+En|0aRLrTQ|CamXWw){CZ7bq{ zjA5h98v+$XB(!z{9yx=038o1jaQ|<Yf*`&*QX@6xZG6H4JnrZGmK--@r&(GyocF`9 z1pw8UelMg`_rn*^I!ml5>CGRlzi=a50a!JWs>3!a0MW6V59=li9IDzARAC0##&1m3 zD}I?nr45;wyy=BH%J0Rg&Sg>1W=q7!`fXU*tO|baHqzB#$&#xqtJ;J0KwRN!JH_r> z6zd;&z)MPz8wzh|<_|Ji@wdcmU`uzU@*=OrF_)1qjRVGb0gEMzJ(PXCeb;iY^_4nL z4Dbs5Q?(RQi-ifRDfJyw<_B{X45ND~X6%GIf&&f(11?4;Zwd!9A=Q{8N;$e+`gt#c zXt9J0z*9^DO!3QbM+$dlnjlpN*Qs?TTD?%*BYoadGi6{u-6f4^bJ*zaq!E4Jt^Jm0 zlJSLRxW%zmVCjle_NcdW5S^A07qsLbq)t1cN6LnX;KNH;wGmi|+*kc19Eu&uLNVqP zYmw@YJ)j^z2S9@(5SIsre?O8v=LnhBrX-?u4n>Od$(8Ko;5;$sQlY7mFv%#55@*nZ z$W?eB)qPFK^G+sfXYij=W0^$dl&V$EmLmKpGBXFbtPM@Jqx;pb#zD{Lc}mq>a76g> z5nWRrCmokr#ALXVwIcsGYVCN&r=9hQ7can72h{ybvx5B8P6>>;Uz6@hlU>osHp%c) zKab#`kar={;{l|_x+)#4MHzjdZ)kXV)YJ|tPy9R2B9kv&iKnGJnX$Y?!Ripa4cs4# z!aX>sbT|1V6eTM45Lm{Gvnlauu3y;^P)dPBjhon}Lrh2R!QH}qtPdLx;|?%13nRj6 zW{MG~2a?eDrO?{Z=BS#~<irGBR>FqlEjHySxZ2{5>>!8sx)r{$Xw}Fx#w@d4qEMyp zCO=F1hn&6_Y{J!0myAI8I03~cMoKjGE$Hd$hoh{f;g9V|aH^6~B;#K4Dj1G0cRFh; z_dHE_qBzsKi``sy=8ajX-p-nvsk8=Qj!{(K9S>PKEg;6<=pkx775_|LB|E*J!aq$X zP5RVjNWbgN46Ouw*)%wZ)-?;Ls8c5MMcZ@rowIjTB&^JK#q?oT$o6GYx{B$ro(F7B zxnJ}_Wns8z2FU;(w9bpNiX3H{<vjlF1sz6}R-}a4G2|UoVXaG$Z8=jAev-sLEg6u~ zB4V5HXn$m){}!JwA$23UY-9=N83QMaGQC2v(k23;tX+;KPR_~<@2v%Rhg$<FWjcqa z0K%E$6uzm?T<-tj$#`LdEKicRwZOD;Q@ff1V4v*+0$m`E1=GiP#a5mp!U_{1Zw(s) zx6@m+f6)XqEUU}3C83R4riGu~@awR981pqlGG~j&@4L^34hRUTQ~J~GfwJOWGqicY zOd=eh%vz_)rLq6qF}q(G(`J}nx1-f!C?kop23g`)vIizloZ0GBbx%eliM$hL)~-la z07+|(s_N4+G~`x;653i<5i=P|N%o$8e=}Bb_!#%IaaGyVhCsLLUcK5@RV;jdX-#aQ za*s0rZDWgzfCc&*K_=9_3yJ{WYyWbppTBN}`GUhv{w&T$%O0Z>vnPti<57x^FF5ME z?Cey5>6F}rmnPx%FTU99bT@y6k2ASh#Y?obwk9I(u38uOHb=;PWxt|ZF^15|B8b|2 zS<P}>(a32Xn0p=|6H3R;X%kqi-oyu>D-u0(Qx3RNrrn@+%1;V_PfIwKF6SU5h-~3F z#ju1jM%tOOp>_$HUCVX<O;dY<I~7X(Edlp%gQcZn39Jq^&Y=A8r(JH+9bB#Z<>JYs zuS`ZIIp^jeL70SJ9j{N9XBcM1+X_mB9p&Fyg$8_X?yvbe=Mjnc#nZOF)<v>XpYIk{ zjcJTh)KnnVNlF(C5``NCM56d(j*2O;#?FAql#hqjATb0~ikMZsG`@e1gr(O5!^nMb z&vRn)eNhcMxRZ72G^%v`VBO{=!K^7IW8_u105USs)G(OM1Dcm@h}&a@u{ox6sHZzj ziNnRH*St@NmN$z=pptxBaAIsTnF-T~h!e*guO(buZ(65ct{!x&c21<A>r(zr($g=- zxN6jC>{m)z-IKrf#2g4Oc1q&?KKEyoUMw?_SDoh2VfSG#>T;SBI#h&N_V{za<J;)> zsbhfpP7?>(B@d{(r$<&qtVCSqx@QXs!{HD%BDXjtGA~=g2=g4QkK)o)M9e+Md7wDJ z@55>~Ba<R>?BN+<yGixD$`U+A!-%#x+BiHuj!~bpue0B@U?L%hxX#4Kp*gQs)rCzU zb%TEQ{yID<o}X^^=drlVE&feYKt(`WXI6PYpuQ4a*&69<^pW&@DkhrF^XU;~Ou9qR zJeq!<A@`yx7BbcyZ)m>gsuvDiy@9Wj>HxZ*C+PXgwTvsU0vL`}e)&L(;IPNSfO>xz z4cICZrfyX{C|M~{Ld{yex`+@@+GP{6-_@L?|0I5BrMrKs*?#9TxBL=M6EQG=Zh?UL zYUpRanO95~n@a8}U1#7YQEMZ4q7*CxvwmDSHNwrY|M3~Ze+!ND&d$TQ=IogP8dY5< z_X2Of;SUt98q-Os2)x<xbU_aV2axb35}glOM2PDawe5zbRtye>Y!#eng0$Rxi{z=n z4mV4VAgh?0yWofXkn;pvc6`0Mk)ryy++J`>;xIy5Sl`&fnHh+@{nOhe2s2HF`R zmjsWBzc2K?g3H~*)Z8y`$<7Rsfkc*MUs}sIDXYf1kjA&Kx$1Y$8tAxZQ0O=@t9u#8 zYQvOX&biLZ3@LK7m*K9#zD=V0C%55~RoJ}LOHxlDGy-9Ms<7I@9`oF)6|TLilj3$A z-GqG|-}&>$-<Qj8GBQxIcl+b~1qtz9hv3y!ZK#1ZnQ|+Bdqi#Z5*q>y130?uPqAua zI#g&$Ay^!8da3p@A4UOPx5Uz3%SO!WoUmz>!eM}OnjET5y1vq8I4687NnZ(V7wYS> zr4xZy#AIF-rG-mUw3MpR*RclPO~rAiKTC(d{IPznBVsFdPy6Jn9G_4LM@;C_h&qxz zVU$l^f|zB!o^&B!HE`VIczpxoSQvJ?yDOHf!M&}#e$!ve*(8tyetGx=25Ej-`_-da zU=9j*i|_9+7Oh*EsNEKEXJEQW_y>~9iDqb#D)Ts3NqoS8e)fWYZFd!b4B<?+;iLv9 zb=Tp9gG1n%y@;ZM6veLWA?P~t>tvOfLRr-jXyRhm>`iKBHm1Ed?s$@8Af*9Q+|r0Y z_<OU*(yEa19(b|Mje0<+FulQ_7g|bbuxIz0WbG0b?q>%}Xnz47RNYE=O&d5{y&eHn z8G3Gpm!ED-(g4>ABr3SVVH(UYuNr0mkh%(GkCK=@v3d5S7f1)uC3fPnWZn~?%(2@N zWe*(-@*maI+<}UTvC~YG7>FgEO|N4$_8<HGfd5mY2b&9Feh&-)kO~O^!1zBOd;Xh# z+B=&#{;vqA5S2~aLskTzRW+Dwa0v}9neNSNLjM3DS5)&?RAYrF0xa@qX4m!t@zmn0 zw_C1aVyRwcl0fxr47gLrlXx{v4Dd-!R9OlGq8$j<DREl0uAcsz$^EEJ^wKUK)##{d zL92DBB6AC6P>q|K{Fb+J;fUjGjjQI6O6JY;XH`3=>F7ggVFhO}Xi&v>E~*yMxlk%# z+5RWP4_ikE2|xb8tQs#x#2wSL+rq6d=qBEnYL_%&{wgWbN4!IP%x?vYe(0OMszivR zvHYs>@yrNJ8hdCG%OFrEb)X~?>vjZv^frh*doP=4Mpi7A9n=~MwTIi2T2WgZs$9@o zg{e>p(nV+Nl4MJQ^p?Al3Y|u^@#>UPwSFZP=+TzG?$&g^!xhC=RGlO}di~Dbw`Db- zZnD3do9`&IKIq=#^FxP5*KJ}|Ae_xfplvtF!!i1{71Az>W=nF^TSs-9v%dwpj}I)n zIsMO3OjpUnG(SpCkC9P1fF1lq8SExcJuA4;>ax0%rVT082g3muy}P9fzkbY^A-i(D zIyVsjdJQz(g!UQ_VCp(r{SFsg=ET~1yM1-HyJlQy`$a<}M;${lxnv>rMwtM;oq?<P zhiE3(0g6e7#M5AK3pwMN7+LW;naiEU`HA><H;c}DWH8_vu!H-FT#jZ6)T8z@Q;`Rp ze11D`bpi;wdB<{NlFYES-#huHTh0f>HrRRZ`WETt)YY{X4_44;X0Sjm%FH5z0Off$ z0A3Pd`k&QWP0r|_P&g4)I&Z#Ack|CPbbJf^PG%dljPCAd<a_&oP^3Oe_aaC$6=hju z$$cOFN2zZB=B7LqZ&x6rj6qsZLf~+pCHn&Xc#lvxMWppjZGUx4$$~hp%=5&?^vy=o z`jcy)K-^lwR{7J$f1O|R`M_CTNWr9%X(6LCZg%N2sf41%;h|k_UJkzooi7yRP6CL< zyhe~K%Rcu;nY_M)Mg#`5ID0uUhX^#p$dI>*Qc`518HViP@b+Y!ibVqTc&Kj?FXr9( zs+frpj%3^kifggm9Mp2(etgy6!S*w4LJW_6pRNO<En*s_6Ws$^>9s!_hYnAOpPRX| zi$|5#I?Wy5bg)F!?Z4H(nk8{tt-|v=60JA^*q&JbXn9)@oa(8A`T737xGZqbekHh% zBM~@tHQ@;8T%lJ!_J+Y2T3UQ7=q&)7GrMFzXD|{3X3%M;Bd(vt=5ZrGy?Jiq*xbT1 z9L>&{A}pHQCR5mW!(`pq24$2mI7dYIt+Cy=3k}b$@FWquPX%uTYZL__RQD0*&IPc? zEhhDO+2)9Z=@3o0MfjDt4P%6fdELo|ZFvv=g8pX#d9JMh_Xh+3IQ<u?&hkGmAVzl9 z)+R>I|0hPyCQ(M}i5_9}_8VD<hdG6$-5p7rJ6x@2QgOue;>2TtSh}>(*E6ZL8U;3) zl<D_<TFP(~T|FOuMuCp?O<83b6b4)LEiBq+4h!#}d9~6l9g&-Uo~)O>vkZ`o?6noG zCBd?3O{TSt4dqB>_4&&WJD6J?Fso0#QJWqgkZ=*p1CZlSbdo-x0Qw1jFbYHnL^?(` z24r=c;rubGH)8I|6_>b@pXR|rs&{E-M2+7xz`=Tcm4**Hb{~5CcNdRYQZv@}<FbNL z^ihoE%k)Z77^2)on5SR1-0W!6e1h5tb>X+ie^K^LQMN_NmYFwg+qP}nwr%64ZQHhO z8#is-v~8oa`gM=4s*kSs&KT!>o{zoOo)I%*#thMWQa30aw)G^(Y@JfXb_1~QQzINx z4Qa;uP_+peh}wjb$<$|w9txqbp^7Ce*-FSgu3=3xh`)Z53bk3>(4qU0{RtnY4%KRN zFso8Kv74sNypd#0ANv^Y*yCf!IOQemP8u@x{a7908Lm?vY@xBlrTWvuA_u}1ZWdsI z*LR)w7mBGwqRDo;$1@`$<x0+~%HCSn`r9owkN<Y0gocPUN<T3{2n+y#{(o|$HueVp z*m&=vGH$y;58wSx1v=fYcm{6n2#$%*AJ{_SXpWc{iW?!AS6n}pL8y`7Sm5IwD&!F# zhzUxa*x2=K8h=sc0Qj*(#>k^dGBDp}%b32{EMHNxi|R97^yL3FbwuxZk=&8mA%gbJ z!-XVmw0ME`8<=fV+K*Stj1xRC*#m^*X4*cW7G@m)&g)~CW8W5Fx{tH|YzW32D0;16 zpWW<+JE(ciUPWiY!Av9$s@xbI)}n%vq~ew(?`huLH-ib3kf;l=eSU;Mz{UY0U3rdN zk92e4G|88bVwb0B6`d@=fj{D+3IcF9pDtY01zlJsZ+R)`^J;xrNS%mUxX}PSw-`>A z_U$BDIZ%J32j6*eixBw2`ev>mS(h5wvCia9>!~B$K==U8bli=%Ns@N;)26~w*b-V@ zJ+dQuGqT~}J*z>M;5?~W+znRfnmNv8`HFAE2%~p`Cg!kC*0lgbT^_POIYtJNK!-YL zloj{d!X35|J&(yFa1bP&<=osi4_59`N%fnHFw5J0rk{(FsZ@t!;XGv~OZ?7&T2EaH z&L<F=o@L?JiXqihytxDl;l^;&N#qb?B6os`NJYp_#3u(E8P-DBqKnyjPE&=2K5q0# zw+2LOtFxTV2bxQE25SWd*BZjChBb^j)Xdy7;Jy$~f`uw+UA)N^YWb;zLKb0RZY)+F zcY4R*EXgt@SjCoUA*#7MKWwGG_A^&n$vy?LA(8%Dbi<wW;eNsa8X&VR1K`sTvnt2g z!ErgRH~ubI4=&rVL@@8XHs~6BW3$CGi_z+qp;8u9E8)}eac1hvLyMPoVwWB6gYBXA zbo=CikI1}z!f388=Yz)2e7L!O`EPh($xL@-5@KnmqXC!|&-#H2;{A|%SS*CH%R}B< zloeU)@|2@AF%6SZ&yMg}>+7mp;1D<eP5%HvRdofvdwm4;MFP*98X8d4jT~x=Tg-?v z#{G-<-?6T8=}8cDq)0_)b4}wZh~uJVLHFVi9>EtD2cHIDT=2kXMe@U{Wr<S`D_>XM zJ3d>GWWP}q(=($BQWWCFo`Q2I_~2%Qwtn$NZG;WZ=IZF^#y;mgxcrgLbEWH?Xt;Cu zh2lCCfF=?@!W5E&Lnj~zb?vG^`VH`}m>bJ!XJG{l03Zhi0KoL$e?d)MY>k}l?5zKh zwMDDS*zL1JcOR?4UlL4P@404PqLRlI1Oh&>I;8_XrA@FZRT^pOO4ufRK1wOxiLF~R z@Gz&4C&YRYljyXLc-)Ml{*?|LuCa2olRh+UTqC)tD&G~+NX~SQ>*Lg!f!q{`?qMEg zRr?(-p-wHJy3ws-6X|+C#oX4G3;3y{tvz<VO&l=cDgf67xYE40@!QDd9y+Hbuufjr z-`054m@dszlcP2RTZa?LDVOOOBG*k|YO&cOk7O*^r^Z09KqMa6%P+KLzWr$lA<IJq ztO9{aM=8&xy}r$o=IQ|u%DnpafYD2V`3v0Gv$Xm?sJ2496(F*w5yn$Zm%5$S=|wIS z<~0l*4;L4|Hp%Jc@g>+-NOYe05U>7FA86(CD*VAA;|OVdOkl5Won}`>MJM;_D~_Mg z0<-I*#eaKyTnJjgTeu2baVV2|<S%oFc4+q_{u%}pnCWE25k_L?2AlYg!*bx4fu&O4 z_}djL{)=dPY7wNTvdn~{B*CC!x8+^aiZFkOFnPS3wd$K0x1Foe?{Et4gVnb=^)i~v zqMa}uLKF)t@@f)xq=a2|Y)S)$g~-735&1^tY^wLfd8&w(@`DsbOl2<^@2CjQAa(s< zWtBbA;X7pMVg1No$Zg$cMR5&{O<fXSZ(eteOye`8<9gdY$FH2&-CrUt&U%UR6#?J{ z$jIW}#ci=q>!~*n%uxx>_>>ylJT$|~%y6CyD%J-mfyteG1QeVY=ypgWNqYARIk;Zx z&=6eC#9R>r+?jBv+CyGG<??G1GQwUK=!P6p7^@dLs<LvxuWl-ZH+gT+;)0Tg8SSA& zZ}4DZp~KFMStQKgeGA9(Ke9S{t9(^4TkxEc<dHp}J%MSP9qlbE7yCE8&CRG9qBQWG z5M()0@8Yv6c}C?cgHPAJNz2<vp###>Q1Lt=7hNT`nmqb>{RIt52U)T9I25d!S_Yx& z<Bl%q<b$xuQ6E<&Zv`>Sv-_?CTnMy~K}{Cj;~1+jHexYgLc|9gix=hTv4V%5?%s|G z8Gi~H9GU0P(hk|v<@Sa&s}8YR+v}^Zwr-7bmFVXDp&C$Qs)}e8J^xDhpiao*2^A!w z{K&R}3_;ZdC|u$Sa%MVZ5W4Jpk5VTT`UXee`kWhn3qGC1&_)}!%tti|Zj9>$xd~pb zx7P=!89j%rn{5(vKDafk>j4s(v=&8<9y9WmGekzAR_i2~Wn(8S6xLma1fS$XxHsG_ zlqgFEbCATsb&0C+#iO$QIK{K~7ehCjR+#2X*G_I04$I-rTj7i@8Cmf?60cag^jZ7) zM!(v{2MomF&!qftcrkww+(`csaG&*SWOefv&z(@^8$`h2{X6OR^FcFBsqR)AaXy2! z_7(K&dlTX=$L(N@;YRI+LCU&6b`=?RQwWf)j#6^0y^roUL9Wgu8<9+<2^`<KU<kfB zTtqV?fTdpCF-w#Ao$!A;_fV4XRBE@P<L%2XER$pr|2%!qY-*5x{Tt!T;9OnV{K*xO z!T(3tW%0u{|1WkWtH{`8^22xEQ;ALkhJ_V3rH&=g3`@YpS5#O!RT6fE<ZpqhcXY-C zR(w5AQ{#;=$RZhIWM==qKf25$S*QT8P|zxN1ZpTtYKa@q!ZjgeJNc~}fnhE6>KVzv zo6j0%(nn#KZ3G;vKGR!<IG7IREW;~hv|-<e4MklYo;PnU&o_QYMxI@eGr*=vxm+f2 z@EZ?Y8=!5#d2eSrhVp&InI?5IGgHg$S*Wc|y^n=@7t~gcR6)?u`&>-FD(A>D^o>1M z$Uv42E9f&&y{Oz%JnN*?la|RAs|fI_%Oa~*`m_cm?ofWD?{L(iK$6PXVvjvQcF-P< zo*J`Be7E0{hC!~A&=v&Zi#WJu#2{SEG7J;Fwr@(HT$|I0Lz+kb1s%5<=kC6XNnDwP zAvh{ql|1@(%T{fH>X<hETG(bU#yW4gmrxxlu)dlq3#`fPp|{0+VA?csTnF?R*?oGW zuC-9KbBQFZ#YM`I{3)r4wt~JfeI-$s8kHZuNYoyqKNOrd1k8%#HwQWa+SQ;>Q#c&V zSzOY>O&EHd5p9}8FK9J|JG=HB`|#wm5*9(TX1$48Wxk@iatp4yNfA5QXKxP|7%1@i z+a#uW>M(0-Q)B~jM@a>Rx>pN#%wj8G{v3p;Cb|R|Fh>a)^TgPXZN)ZC_$21oeCD5U zp+r0eZqftPoT9&?q*(LPm>C*W69>g?gG&<zEQSqT&mK~D1G33I!7MQ>%sA)Av2-68 z+F#yAQeG2(IYNz$>^lX-O$@yU3vEDYpe$c#@&@CLib}@1MGbHmZ4kX*teZU_Vq7av z-I~A(G?%zyd?U$7l-55mrGvwfIjqMZIJmYs29_+@`gXmmFGZ8P!`>y#Xlps2F2B&9 zKIi*=L~Eh-SoGlj&MkBUx6RK<<z-XVzyk*@fq;1@U)kFaYwwqSy8KEl<g~6lza?jt zy#HDLR@Y!J=a<{0`sOnGZ(F(3FP5<9f5=tzPq3%`?+5yS$kTsfe74eL%mzJl*E?0% zLjphyA3lF1=&DpCZ-DK(6g+y95ZQXNh+4tI+qD!0on7QF8JBwEjKN*|MR(hLaw}Ud zWO|!XUHwCiHq%TN21+5b%`Zf)4uViHB`MhJAa2NaY~HlI<Hy-Kw#9ulvsDuf)tcSM zLsw3UmBe)2WmF+Ql;xSW(pcg)q5jk21M7JI8XOk+loV|ZS)esj(0exhtgHeD6cNB1 zNY2=IRJ0v*OWuST(Nh*Kf&BptA~2#wTKq6Mdz8j*C_6bsgc|!9=FQm$PqZ|`R|h9F z1~$m1ZXgMXWb@1PguxWVQfy4-l*&?&A_{U@%0$t|@cZ=>;?{Oiu_e;PahLDlqGwoS ztQd1o$ULY0^}JbFA9M}?!BK*=3E0^u)j!;yt&ttbbodLqHplHmbc4xnO8Ra{_#T#t zX}RnrHiVccYhS^Kh+BL<U(9^3YUS|E7g{@@2mG@+mycN4jbM07^C_z2p_QMkl%s0_ zsgzRY(M&X&;NB?Wge}XQ>PjdKXx!e{(JMWbfP2G%j!z|LBAw(7XqZJcYi()1=Uv*{ zhuF824IH{QW9#L5Q7Vx#n;;*@)|?Lq2YehJ13DBBPD$T#Gy7=&ng&`4^cUX!+z!c~ z+rj+bza93!nK+E>{ts76R+6&X;D_%ySA(ADca?7q)z%b(>SvLmXe&V$gy`3_8hv72 z*I~eHSMl{WBjG!MC!ZU>v+No5V#+MBV1%lfw_a&!+7v9;B7U*?4K|tL);}2S@%$v( zEvH!iSKhwQ#^e*Vs`3}Z$4h%wt*P7n+6rCd494agYoHy<#*Rxmv8$5?JxE(X#KZC_ z#S4JQDiI05t-C~<*o?e7WrpH{Kt3pgK(yJpyi0L5lne9C__DO?U*U1+qnvUb&~uLd zh7k)e^pw6(f#?r}L5T$P%`hCtjwau^sxDV{)_@FMeX^UQ{qlA&4&RGcBj(#@T5vGo zn{a8j3@i>-paM+yQVi)Eq7?RlEzBTpJ)Xw6<Ff!g>*s)5f`bq*vC15vPQni*{bBpb zZtCgqU)i^*6p}B=q|6TR^F;z0z&rRyy0{UNIanNwWr?Y`s2Y(Tsm7od&MBsK;J9S= z;=&x|3>lAu<^;K7v5AAsb($Pg!?5QJstf&p7~6VK2`<lUvCrWrCMh<-Jm!%x?K(E^ zKcc3bz|Zy6#}tQA;9w^44e!7xUTJ+?`#<>Hsut(Ae^$R5;Z^OO2lfVBtB)}<u!wAr z`PE!AF>-tc$+HFNV_4I;)%4yR?sCFpaPE^hqZ}s>i#~T)zqM8$Xv*lGeBk}-9RhTp zLIeEa`mR6W_<w*f&L-~vVEV}_3UWV8-{-oPeL@JaJc885)4+;tb!Z3h(qCdBsA5c} zW@u;ir=5bZ*X!iEzBE2B`{0kh{nss*FZbGAg~~=?-@IwDB7j+om9bS40;sE5#av3o zm}64v4ihKPt;;Cmkn(4z%nk1+`veFR=yWo9-OC8{$jI4&G4KOc?C6&#BnO6{RN%b* zBp$+8_@vfNf3ChiiKj4-TXa4COLyzLy!NrW)|iS4lML?5EInW)BFQSEfW$3uthAG9 zdqQ9IOj3;3g*7V>&_bM+asfP~s$?XgB&V%X7;V>WE1Smx-QS(*aw9iD)4uV(Irw=F zB+>`Tc4~VZF~0ENjSu*BX_~gbYqs3y=D!fCHub<b;XY1l>cXg0M>`W`$<IblmzK(* z^b2UywX*U}=D61eT%S)jM6K&;C9IM-6mgWH7E2DAk<x5KZa3y>lXV$%fHh+Sm10j@ zc1QlWL0$qoro>!#mG0v$@ek+p5hep20tTiOIL@JW970fIR)CX2>C#8?L-G5gNN(tg zA6A&>TT8fz?8+winaIQ7AcpThTI)X1`)px7&l~yvO?lGmsad~*p$8J2<Mq}#yxQTX zxuS37O?gnUF|jIjAg`&_raRXq<smd9PE;=1bYwS*li8Wifwo-iNgJzls;i>IL2Ud2 zl+C-n=HZHxh{ccO%KId`AX@m_ZSDpnx^cCS20}|P88p?fnx`)7CkfQbGx5p1E-Ga| zqFjb@#_m5;z4G)8fBIx2-uNm0azjdN$>Et#+yilT0-!uD-46JUHjJ?kUxAcCWr6Yd z`t4|8iPkwR&J~Yi2-sDbVz7AYCeqly=C{Pccv-Q;<&6P1KI<t$qn&wz{?P@Liwo@r z6Spz;QZGC>Lb;;iND7R~4DTJ=v`6vSug68?G}*~BUYEr~FfiEhI*Yr)967kso=$qe zhOfmX!zylTqaa6==c8BOyq(qqwPSUJO*|zNU7p#gtuHOb%u#94VF#ZO-l#|Ft(kel z{HJ3oF-jNkUtcCWhk~HRA0U4F0p<VLOmQ@EvU71XGI9FnAu^pf0oVX~c#&tG;UX+% zhOIs>^p+83A&fi(&H3fB)>K7M0o8lG_sI{sVrmGh8|2LeE6BX;XmjeN8^(GjRCv)v zIO|jDV&sBbTffG6Tl6dtrl@H#cJMS_=n4j&Y}5FXxKXR8+#!eN=f#4ri_6m)<9$O% zA`KOc$gf2I+^0?dSJ5K3&8+VthzKDQdc%u5<r*&?aH^@v8;i5xE_gwT3(w-6U#)Ap z)W0J>H2Xt*v+;f$_y!XO8*<JK>({d9N`7oP{V|Gyxb4>0^AEpty#DPO<*aU!IsXK# zG=%>~{{K(U=$|@H-RcUl8?4YiGqvz{i0^S7Csy?URIprmefBsVhMwr4LgA;8nqrK^ zByOPw-`+*WlL?nnPM6g_;)anQ;_)BkOwFobElTqPfi^=a;X;*7CP%9+m{A&wO|;72 zA4n11-#4X4Hc%eBYLPzic5acwhAZ|)tJgFaJ}O<mK5O=>K|WpkZ!~FBuQqs$vzoo0 zgSP>h$fv6eH+fn;^~J(FrV8WSsvOuw0POiF%QQ3~DXcY2K{Grq`Im8jJ(TQ*+6@04 zY`to{VQ+s9qE)2II*m>gN9$szbqT`=Kd67?s@v4W!H)X?K<EPXTug9L)TmpA2vPT* z{{UXUu>r#CFDu;gzpc-N(>z8Gsa!fErc4uQqt-nxKzOhRE55S71=HZ`+_!QuZ%5IZ z1AliX!lWNOx-Up-a}9|4wbO-I(e;dyyhPq*3Z~L;TC8T}I{cX3Ut3A{{7}h6Vo5f@ ziWQ=WbT1L_8fS!G3M3QIlr0$F;91g6-}kjMh2S%%c}gu#yFH0yCw%BHOWd#e{Si4$ zwZ@$g7&ST3&s5W|0JZjOsi7>H*FH18z|FiY+ydOp5-<{g06wQbkUpg?pjB~P?FzTZ z#CttWE^{FoGL-0<NT{kzr{zxJ7CP%Idc!+Jn64lp5;D&%mKM=OmH#kIW|xCC=Ts!F zU39y3ivx|s-8>m^pR;ewrDY?sWF9|qNVDyC1A+VF*tq<~A@+0V()3kHtd60i{sYzS zZ~B3ef`kcD{BnL}ec(is-#zY@HU;d}QF|GL`;15%+D2~8?_R(7Nrb4R$A(4+aDe6w z-;lDsnjDlA<Nw%n-M@#hfr64K_wgH`b4?*%H6k`#>WEG2AC0zq$a0$%+zYgN((1T# zzh%wLgjs?i%KL~i8Wh&Yj`x%?<%G}4`+`W6FbJ@(4ewi3+XMeVF>xy}hKIXrCGi2S zR|$(~5}x6WOjd634flJi*d!&0XpQv>NF4!p1CV{VcQr5TcHcLzQK3>q&F>I75^<E3 zQV!0+Z-(YviCp3zv%H2Q)DE>!goEF5zdSwmUmH2x5xN5c=_C`rBk>YZ9Yg4aPIC39 zv_~J1BlesyLc0R2=B!dX)|irH-w?VH4GE(60w0UZT|};uX;xgZEiRT}O2{<L`0Cl1 zU_3uWn>#=@$y&>%qla6`Zbp&)XP<7}8CCJzd~EC9Rd@&0O6v^*AMu9QQ+Xd~2{)JO zPSJ|70lyy4rna}`xKfSp-c{GIf`zhY9_Q7_2@HSS4fKw-*{X`PT*>F!5X-lrs1tq0 zrnYw7NpAq|g562!=g>8{S&&h7<zv|vrnrgN4A*@hTu-J}pq@iZ@)|BjK?f7q9vH;g zXZLhjaV<eNdDv{3FX1MVf%Fd9F$~th_cz<5*z_>m2Bi`car(~ak#!k)Pz~<FOi$2z z@kq*>J5wvF-i-+4N=wd*f`xr~+C1untYk+CODnx>#Xp+q{8t<{E@hlE(>}iEJe8BC z`x~@#)8Frh|BaUo_V`to{d7kZQ2rak!v6$fKWVp(o$WsoCv}<HjTXee?`rUDP*QL; zv#ck37;OT$aV3!jHgP3mgy7B=zpWe9P(c)XV(!m9O~ua!9TU0js3Qk=y|Or%nmAgP zT_)awA>^vBV4K&9a&d4rvdbwxx3V)T8e6UosWzM+%CYR)n-=LpYv(E~yrfi8eR7(u zq#N-LxEuw(4UaG4lMOg36nt4mSg9VxHg>gEs8lSrLHY&lDu|y_x_H_nwi31yw94IN z`Qq<AfcOfWHP(o<Ww@qgTS>55)Vt=E3bztF;7YyW-6FOxo|G53xNDQHH%EuRGtTsJ ziV8jq>sRMtcN6tY%%o@#F~q3#=#Y8c+}!RyQ`R-ric%Cj!fj;nAbO}Sml!X!DgRoN z@JrfVK=|{-Rls(vDb>UC`0hk29b~!az6SCvX*Dmnz(|<My$d0G-tGnOVZT|Ir&2X< zQak;Qty6CDhoI!r+@=siVHqR0DnnQ`XW{x}%B_#lbX+<WyOSh*?LMn|6KGz}j6*K| z`{f)&Sj$TPCgwsaW@(pGmJYnTh_73cPh)7#<_m<RfqUV-7Fe~@^#U)bu?K(OnWBwa z;JkgVQM?0JTLAXK;BA|9TT%a4zYiZ7B=D$q>~>VaP0(Yt$6VG<m={5op6-Pp^R(U5 zChJ<1oL`z`**dTg)UNe|mSEqOMd>y|^FYoCb}Mx7h_NTohJ{DL`+MKn#qx5sI-N^d zj_`qQ4x<wNX?h<;2^Y=KQbCH&ESUHZ1pr;Q$`khmKH`=r?xE9$Ty47>edVL+#V23( z^p+78&N<)JUV?3|-LQd519mKRt|{tyNiK<doCxHioGMY0n;xW?yk?0dGpxEBPigPX zeG1d?S0n!(Os(Z)0<`ABZfVb6PdU=eq9=WrZ3;kh>5C*$<X2O<{H^x-l0QE<Sj`&D z4KPP=mbqVDB^`c2MIVDnx@(xb#t1f_5||a9ziW-pPIJIJ4zeH61Ce1{;5w-P2x2F~ zgwHTHLaQ&Ujs8J_Z-ASYR6g=&IgB%p!m(P`fYM)yQvR=khMYFYxK%*o>+qO5s342D zXLu}9?;TRnCh}saBopZl;O88riq2`1F4ds8KruUF%m+;PuzijtE0d>a7lLJR#l^4= zgZf7ogPTc)O+t?YbyEL!UFC_s6kNbE3oC9;Ef;ut(kR07jo<y?Z#4w%xLSQMteLI+ zs-y0{7>{T%Pa{MPj^-G#LWLi15I-a;sPvB9ajg|+Zsi?qMqGhh2Ix=H<}Unl*J|?n zx~=miAN6Dckao&sY<Wy=Q0efC?n-Qc!LIV@qJDpM*E&NaRVNf*&{`m3f88!3C_q4_ zkpI)?)Jp=0<WYyTb3F-bZoY{+m3qph+VeBH>=y`lEK5nrYxNttk{{%`)=2kc9y~Af zQ$Fikcyx3h6DYjg+G@B8<{Ko0Y6@9{Uy;f~d4-%7W{ko{BK;8Z6oD;r3DO*qq@ez1 z>P47`n$qMw123j@orW@qvOP8-IBC%LHMLJ-d8rO*T=oO{lMrY@jw@>7XMEyYzVmvJ zrz&Q>f<xsgbQ8mI5@C#^w*DZv-q2{Ft-W?tlQYPeXldwaf37Rn{i#p8_HfV@-1g`5 z>wRuc?NY5U%`f_VFNy3&@`FMVhNG<cjQ7DzDYrVAMSsTm=2z-O>9Uw_;K$-elU0vx zDh(RLlU#p@wn_&maZt40`^|@#G}WfgF4Hc<F4pXd-5};Nnm@wSso9;>g*h@dm14R4 zW963Q(t0XCrUI`rsm>Gp16F3|xF~0bJmP&h-iu3|P>+u!FZF|AXAkWMRH*YSnZLar zKC*`GLu%ugR#}ox55Rn>;l}#BNi&4z?+w-y#Fy`R_Q0N?6SOM!zrL1+;cby_S=GDx z-BPUK-c8rdj$j}<*C+6jc$%~KitwFkX^zJ1$J5Hp84QUzkI+FBk!6qq@c1XJK;9K? zX>npf87l60k%bD}^bC!k(5)w`9U2^XYSb;Lu;?e6+P<6e*5cESVO5c~-4_Rek{TL5 zcKsE0n|5C*__^Hw6lJ6bK!VR?`MQrSz48w@`**{HyiNZy=LWjn5zU<ihWf)~PQW8I z$pVq-e8LRKiTdHOjFxLyG>nk|=mu3~m=#HNy;+_s{~{^DD6wZ9&wMM-heJ98N{*`l zHe(82I%BFk#T89V6l|F_x+1-<hhy24yPKDL6|8E<a7~#_U=U#q%?Z9xuvi2`0}AYC zRi)h0Yi}_jpYEj+k8QUF_e&fp%Mtd3ChM?G1Q2~C&UCcU?z1T|T8jRgQe!(}oN8T3 zC??%i2<+2%HlPhAnq|~a`_LWV-|hlQ@c?5}8}4Bl>829+=v)Kxq#G44s5k~Opm2O{ z9m@}S_RSqn-8X(p_&^J5C$3||{an;NkUX%OlOtAzqOpY)Wi)r!g;)IwBZhp*A`R&q zugxEo;!A_Anh0Wm97S*JmnKLk<!?8fDn(5x3ez3VRFd{&N%iC%Z7GXT1>h>GL~&?U z7kZZODJ0a$-fD}XHhgAG1$o+A9Y@PL$)r3r*d9r=JzoODKl7@}Q%kz1qG~A-J;~Ov zXKlo_u~42xiNsc+TL~UE9hA2*!+ihB?~n~>xki49B{n~O*Z=4d@~>h4zmyTxs@rxO ztnfZ7dJc7X75ccH1a#H)urh%#=<>*-3s(k0__KH8q|%9)5+n}aKc?^sDaIr+ey79C z<DKtUFMne>loPIRrx26AV$IUo7uVT$er!&gWvDzaQdr!$D3&!$9snh)v3c3w;7(1I zRzRzxkFV6Bnq|!Nl4mK2q>|Ofu4dKO$%87GKfYk^CP6;lCWje;-U43O6x0L_6ZGOO zc2K_%T+|0PvHD2Ds^>wOl2AS8qvE|jwRfqVj#d+K1=*q<_xwcK2OVctf=>Uu2!%HX z_6~gVMa`L}gV<nIO%LBIu16lGBbxIC)-XVx%){ANN4a(^-f7r(#mMet`&zg@?s^a+ z79T7RpbdT^{cg*hI~z$d=d<kTS6#AZh3Zwql1(vYuis%_6x|Mok);HvVa@vsD-%ca z=nqb^EC}gl%%HDFV=ErYZclW8Kxw1z;>=aOlh6%wHx`X-zLT?vAIB(PbU-^o2e@WV z*b+#@iANm{rfiFdc;0ooRf(?%sfOGxqCwNQtlrY~kh^W{6B}^iTd?Wr*eUw6pb<5f zQb0(q#d}Q_WI@zAm@|E=fJz!F8g(lbHFyu~!Xg6u8XVJh9Rzuk4~(Yq%Je48F<*(z zdDQngK#}m!*5@z_;e5mZfBM97CUTj)Fzd}racU20sIK16BWU<~E#n#63!?z!W6I=S z+c`I(nOAh93eICeoSM46d=o`6b%>z)0-d^dU(jRV<9hcTBvOX=egF2}+V__nH-QIl z0B<J$!i2oTmc!(DF!vSpPBPuV(-O$bFR0w60R&v%FW`(Czem1YY~VT@GV5f=;MZ(| zzLpg4e8QzlV<cK&^G|Pt#JJtSy6GdnqlsKWSLWOB%xEMwJoB{H;8HYh1W)`Wvdmv> z@ECl$l)yr%%@}L94@t8m8LdO!zCmMq`Qbh_z2e{GDh0{3T4Xla$9Iv`Ilp+7x$+j9 zMmUtUCs^p7Z<vBA&@=_e|CG12`p7F`Dt|F~E*f<VjMu!&i~}_(!G~d`n|*ihy6na} zMhxWGDMia(-ey=vFv&<1qBOA)j>t1_LM+!|fNGrm9xq<0m+y*Uu+Tb`5yA;wCvmt0 z?gcvdYkT307Zd%#ta{T-iutZvSsbgr;Q$tg|9zP-7c>I;1@k^z_SvN2^vg}Ct>Ch< zExBMM!mphiRc@!--NVCcBjjr&U4@#?;NT;5uQ$(v6*)cDFxF@PsfCShngGYY4%r2h zt4v^ZK5RX>boVbfIN=`xJ|0_h))wZ@sh)ppXpY^O!$<rSe4KxP;XhX4{|OZSxufZ# zC}TB958eH)7WNni-0<bs2m09t{j)x>Q;K55CduGzHT}}{U|Y^Lqe??f&+t@2?s~ku zs$9UMX$$?3e>u7ym$IB(1>!KSo-*mBCH}2(R0-4>Rgj`yDQ)y5obyX~Yn9f+ri)p# zjMhVJTSwI<5N}VraalQ`F{)kynE!+^N`xJP3WzC5U4jNE*~kk7jz=KlMkRrv2e)`R z$uP=er|fVAfg@*@Q}}Ors#*7Np4Xt-1~%*}YT%B{wZnqHSNGrfIJCle6Z>!W7ifEg z-`6?C_s8*mkXDOZhqLO==5hw%BPr&kH=^?0LQu?x<U#m|0TZV>MVZ>=a;DBl_pgTa zQQJX5aS0fI3;-uHWftplX%exsT9r(C=5(Kf=Lx%JNPB)%_S9StKgZ>ukisCrdAd&1 z1lb96y64eh5~PH&u>n+0_g&5W<kZ8q4pokG{CY#ZM%RBh`|u|zdRDc7@|^%dprDt+ z!2Jzj+#fpL|C<chDNn{aRtqzqC^+;266^f^--=aWv?i{bKgFtanEx5zTbq~}82$d? zdEKfqKcy=8?sGNizk$WU)IdBapxVSX9;-t0_<x&1Mf4Zu&8KRFA&HxH$;N!Ip(Vz1 z0Xsq$!L(4vU)}GI9E>+C_Vcb(PMd742?wEgcwGi;u-Y-cI=n;o*JXd!X$8t8te>Q; zoZt-&$4Xiz4^|5ivBDhPWU9jE{?*DK0?NSlNtR6eyu{<!oU{7!u6~+RW>D8i?yzZ= zOn5HvDsrlW4!QQmAJ)=&gxQ*Nf?ZCR8wYFZU?aIM{FX>iRu>A+?pI{5Qk-ViBIeIk zGg=;=4x0{P=^YAv(FrB(MmXv}vUj>~+b?xb;}d!V;Vas=`dUn+v#wUJPBM3BeuJFH z4OZwAi<F-PwaM^TUe3=;O+>;<gi|jBEHyaSHbcAr-4|5Bz{DV<h0b}}qJBD$s+g;h zR+zzdFx&Clj$+a9eEn!tl^1>Y<T|Q8hvfx-f@g7^UwaNx_>owOn)EfipN#=%{nkzV z%lR*7g<_!GDzz_XmGOR}zzWvksjI(L0`_It&gdJ(k4e_pOq(HV$w#w(gE9Sk@Fcb* zW4iPf43>cV-he4wnYA4^9S)kn4PXf2OJ}wJEKzHV9eP3=BuTuAyg>j)WH!EjQ@&sD zFE85qd-`|*qN3smSOQ`|uzevI>IXnD_%Ue8)c1K$%UM_(s4e-`ns{2An2^tg7%|wY z`>!3kxrdidhV`Py2PnLkey`w`R#;YWO%~6Iq;3GubkotDm}!VDH84ewGM7-x=G$xu zgZC6I{)=vG&~+O96DGZY{KQdCFYp*a;6_niMe$7EI_E83)g0@7D0+Vk2OiY{ELu=% zqge~(077S(D4M`m4lYn24b{3vXG_+kFO!ms=izkQr$y;w3&&Lkj1m}?NuOA2!9Hw$ z4;nl@4%Ag<#!KqrlP~V-8(fw0c1WlrDhJ2)PLHR1W?IIni?$&gMNZB8FyKocjYE!! zYu)F1gA&t>SP0tCQ0|guXg&$}3cJ~Z@6bo}r5JNn0t{m0Ldk3+H0Dd&)iFf7I66N_ zaijNTB`2z!S-i$7K2)vzENTf1n(n0{nvN$^?xlzwhACMPTQZ4F*r@aAjU#{;Kc|tW zb6W=oH0PXEH3}Z*1rcA5u#oY+9J(*4UkR+EE~4R8=;0|fn(AUk=V8lSm*}v&Ve+uT z3sIR8?z{GLzdqIsD6BN*bG%`bi{wuw!??O>TKEODH1Y}l#KPSN_oleAbV)U`j5Ftv zw{Gq7{t_H*L7$pi(zC7iI<V4j>khf+_ZGgAokV2letr(`)ouIxAtRiwcU=_VP+&ZN zv5<_2E#_68a4~?y9!4~!XoPbm9gF>(@mw`yn2K8vso2F4jBHEZpGkx~<A_7n%|xOf zONN#s{~n0VF7&~cl8%6{NekB!R3XbM{}!d{fo{;{gX8*vrrldk!@G_)5h3>GoYWJ` z<Z+wh1DAcn`2Z(jgY_g}_K^5cfMo_W6IC`N+(M=4=vhH8Z&4v*j%=%iS(`&Lh0P6l zTivSkF-F$q-B~)`0y7St;GLuQn(+|HCDAQ9C@B&0A&u=FETS0M78h$*_z+}-!a6pv z?6xU7GcRY?b<cgSe3}?egHc)*0pYRdNWYFzJ_RtI-jBc4Z{XVe4JsHmmXoSyFy8yG zx$#EReXca<kFEz90D$H{HKYGu7&I_6`hm$y_5Xs&pK{n$|C6A?HB{SJiMSsRGlU|L z00J;0N%V>|u>wi?)Z4b3DY;})^_1;;LFrLlK8fSe)G?OiQZ=jWSeH6^ud;_a2fgh1 zL<m^5^Qh!uWZ+!0eW@yoTY<03LKfn!B+Go3?Ka6CYV1T;fX`u*#E{k}ptf0t@WoC) z$)3)6lC5#`&E0&}EQ=*LqRa}rijXRH{>zz3H{1HDpj!CL-}Gm2(|UE|^r{MKB&}PE zSHP+(X+S*w6#bNN^{c2ZFr(9#wVApVTE4=hf`sLW(^nT5*}F)Z4zljwkLPwT`cB>O zFLv$PTL;S+8tm~>Py<rz=0ub-rPcPDO`_YCh(V_y`+_My>*kw{jUx<Esjo@O<GO{F zy%tIM=yvg)p=3~nt7w!%jpN*>rZ>aTdZD+T0X*Zj4h31MK_-N;e}rh1k0?RYy#NDb ze>iesZsv#a4c&n2AtzJ?GdgQRKm(0IxSQO6kZ+McGV>(ZwjwdEN`$!~#2Mbj6aEVQ zwIEKWaL&^YyaP18yPwIf*;A-j7wbor85utzm_EV^bDj&2YfAx`n9u+%&vM=B)PQ+D z%bgE5_j}V(s}&_qX4b9=(?JmzQ5X5TP(a;SL7y2b6vIvMMJ4zvDu|-Bg3=&+pttyG zq@uHsh~Z$dE|EZ&(2Elx;GB_iXcWmG)k%WikDc}@sHUtvi^Bb3(~x>ez<@ch@0%1t zGP=Kj*$>R*bcbVNsM8AGez)aYDNs>p?H*QOE;@m5RFpRrnQOtnbu_dBnToUBu<$6s zzi*d{33QIMKpAv_A8V<1AZ&W{&<;!899n3fT5A*)B<3~fosVz+LAe)9i0X!UUnzRE z6_Mi*_UW{-?(qSBwQz6rd<71KKKL<db`N*+{Vt$wI%Yr7MZY0l=H)w+l=;vO(n^U? z?f?}#|GJ%xWc~bpde7=`mHT3sy6-oRFhgP-Gs&~BhitRSyE~zk(e9(EdhSLCIVVvM zPJVt7=;Q!7m*WFQwa}`DAdTFRV|CXcCKAp(hX?n=xmi6{FnE2=Fp9r#M%^>>z~CDk zhzdq$iyMAuy0EOQNVal{hL0osA<}o&iXc#boIf%QCvnlEnQ5#&fQ6Q1j9#sD&-yIH zg8&cZZqxmmB%R_w^H$cbv-+U7f{>EA;mNsy$KJ*0>2bBK-&Ef=pE>ZjZw!pUD=W3n zY#!O$3NZxjx{C2gkzGB)W~JajF0Ig4kSS%jZ&3#DAF_3{>Wr}JTFE*P=HelE?NEx8 zX4!;Kh)1IaB^uS|)h6%WKF1hj@U@oY0z+)!u9RVhb;1h;H+4StKnXrr^)@3*HhGEC zD}Q%yMbSk`zasfVB~}UQrjE)i!5U<gO`%{8z-r=ok#QsDr*~DYM}AAi&ARQ#N1yL| zpWbvcNN4&fkorN>Mru$oVAFc^kW48}Yy>??v?yx(eh<QsU3|^sP&e0K8pIoqvyNOq z*ASc_RN)9VpbGmFyY4|Wo>Z8WTB6K7RmDP@_+d)Ov=J2jVZP7N)G*PGgU&p*;u4{& zww_Z?aepk%xIz%{pVCGya}emcT+TfiSTmTmnUr#Fca6csoQ`z_3=R<VlClk0A;6Tn zl726Sm)U=DxveZl@$N;j;Xs~O@G&K6r*KfuD*iRo&~q79P&w>Xu%$Ln(U_)p>;nz+ zy1<Z$>#PdZK1Xb!Y8*)M|LTW0KRY{T)3iD2pZB31&k}u1?!zXW$iE{g&!39itw{xa zFJd>85&NXVr3`^OUsp`XPjZJf&|DS1JS38VF_=A3A>|frQrGim1!e(b&ZZr285Azc z7Q=yg{Q_=<%XgL(y149&1%1cJntI<VW%kz}&dqtCKb%-S#Vek`iRD_B8xl_Dz7#7= zzruFYY8rBz1d`>E5eQrY{(E@B=H;d?*UOqE6TsC&{JBO@sxXjW3)^r*aEphs$2swS z0t5647p2Dy8$<iMi#Ei$9lOPAQgG<wv=I5zIa@aE=3S3rZ+$4N_YC%6ZvOqqqos@c zZc5!$V4W1ReNW-cGu13BNW<+#9Hl&~7bR+46eU(?z;M50Vc6|5pD&a74_SPU*p(nN zliamn_X~@n*ri1Pp-3;NDugDO>l*dfuYV0oDpCeB?mrp)=l?8&cQi3D{;%=IOVz)z zo6PXO+r0zpyhH7@{$@pz_{l<k<_aqAeg#=<>6;zLKMI#CR^{hjrv0ICw${jr6|BmI zt&#NCsTDg@>Wyjj8OlOrWnIimR!8o$AU^W;*w_*vs;>G>86%lVNY?B~Z<JWc(|!-5 zq)0kX8sGE$AkR8jezEq6rZC)KpOn9F=2nesi?j4l)$O4TS6n1iyZsKrHacIgA-kgi z*VU%RVPw2$wKg!QXQ>T$AQ<g|1e8bM+7!Fkohgu8e*6+Kx@dOQ_`O3pve~CLAal?h ziYbaxdMTU!maftmidkC=p)pXBh@J>eD)QJ~Nzk>9A1!&GrlQS>#R<A{v$xcM+qSLu z*K9_Az5uHF!PBs?K~b$4?bOW}y3GkAwuRZzw0B-%pe$;s!Ra1pkf4_s?gwBS6-_$w z*{!@M+U`?k5YVop7XiIodGrK{$#mdle?`zE7}7$je&a10k7_DCQ_ASI7xK|)_U%R4 zK}8ndB%BO15>BeQG|i3?L5}VP9}ftY3WIQaKGSa0Uo23Y&4{fYKR8DaSi8hM*ZE0< zNtxD#I%6ogw!dt_P6}mo;d;g$4^#YsrmyU)514Me)_<AMG)lL3ZVEu27dQ!18_~<u zT@gqr#DDWX_j$coDJq(;{tJ7di=SH$W^^4yg1?+MmAP#qCJauakjKljDIE_F)qP2z zK!#)UKxUsbX3G<U*D60>sI<e-O0YyUd>0(rpUtu+nr)tSES=}HU{Dtbk0-WaA$;33 z-I>HO8TZ<wrt1nBBM+90Qb~5PYM@6HHxlElPr`1BnKH)M=o<?(eQB;pX-+{C(Ci1e zD3A#pKT{;SAYh3d33HbmK7silLXN@!`BWHKqLy@$Cq?aw1F^r7-6nDl2d06eP6gTm zwycN^wjekKobIB|4AN-H5b99QQ7Z_t0>t!(M~o-n^|<=Pos-MWY~&j}k!~p&hH<#m zzI1V<4SOVzwLyh}o?NU`){}rGxR`&(e-8d6#alU4`bO@f-xy3U+^%_u7bXi<N%L%R z<3pRQAev53GP0P_)mrOo$g^;XU&ybe#ORSYx@&x1RRlKf6(t_1lYxZ0Dh?_q_#WTy z*oYcQ^Q)*`wUTFtP|4x8Crm9^&|Pjybdr;3-uN`5&qX=)y+7BY11jCF0gm`JY~TEk z`wfehkq7(Rm;k29%k|lnzt1NXYsp;>9<rT9MR9?_T~=y0>IBKaJ$0sbZNEyMRetw7 zRHuO`$DCemh%<RP{0qei(-WqrAtn_Oi={?r&@8Te+hJQ827BFlUs?^l>b)Vz6HT*@ zGqP9&Ul5FaAFNj#d!gynp0zoYfCH6I#EtRzm)PNVLF14O-=C4NC12MijZM;VXVtx> z0og{zx#)#>TPy;_E$c=&=eIN)I@qM<Q&S#JcR%~s->lc=Y7SrDmm4cx0uxIn0APl! zgNd)y2Z}MRW096pIzEUMp%&mih1bD?SHXbYJ<ZXr*DiHx2CY>W2jAQMxtsm}KJjyc zcNnJqQ(%JsS*P+JNAmt(cJ1_IS#53dkACydxX+Ii_@}@GzSi#=kG{&nAKLsk0t8(? zkE%{c0l0~VOw(pO@xb}@xsX`vD{LWFn{e`Af#{Xosa_oztEQY9zYy55%%NJGfS6)< zvZ4q~6H$U-^e?e`o=abarnn6LR0j!?Pw<vzm?B6pGRoX�J8o-PyYU0b_WLay{_ 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 Dj683- literal 0 HcmV?d00001 diff --git a/Lib/test/shadowed_super.py b/Lib/test/shadowed_super.py new file mode 100644 index 00000000..2a62f667 --- /dev/null +++ b/Lib/test/shadowed_super.py @@ -0,0 +1,7 @@ +class super: + msg = "truly super" + + +class C: + def method(self): + return super().msg diff --git a/Lib/test/signalinterproctester.py b/Lib/test/signalinterproctester.py index bc60b747..cdcd92a8 100644 --- a/Lib/test/signalinterproctester.py +++ b/Lib/test/signalinterproctester.py @@ -28,16 +28,15 @@ class InterProcessSignalTests(unittest.TestCase): # (if set) child.wait() - timeout = support.SHORT_TIMEOUT - deadline = time.monotonic() + timeout - - while time.monotonic() < deadline: + start_time = time.monotonic() + for _ in support.busy_retry(support.SHORT_TIMEOUT, error=False): if self.got_signals[signame]: return signal.pause() - - self.fail('signal %s not received after %s seconds' - % (signame, timeout)) + else: + dt = time.monotonic() - start_time + self.fail('signal %s not received after %.1f seconds' + % (signame, dt)) def subprocess_send_signal(self, pid, signame): code = 'import os, signal; os.kill(%s, signal.%s)' % (pid, signame) diff --git a/Lib/smtpd.py b/Lib/test/smtpd.py similarity index 98% rename from Lib/smtpd.py rename to Lib/test/smtpd.py index b23579f1..6052232e 100755 --- a/Lib/smtpd.py +++ b/Lib/test/smtpd.py @@ -77,26 +77,14 @@ import getopt import time import socket import collections -from warnings import _deprecated, warn +from test.support import asyncore, asynchat +from warnings import warn from email._header_value_parser import get_addr_spec, get_angle_addr __all__ = [ "SMTPChannel", "SMTPServer", "DebuggingServer", "PureProxy", ] -_DEPRECATION_MSG = ('The {name} module is deprecated and unmaintained and will ' - 'be removed in Python {remove}. Please see aiosmtpd ' - '(https://aiosmtpd.readthedocs.io/) for the recommended ' - 'replacement.') -_deprecated(__name__, _DEPRECATION_MSG, remove=(3, 12)) - - -# These are imported after the above warning so that users get the correct -# deprecation warning. -import asyncore -import asynchat - - program = sys.argv[0] __version__ = 'Python SMTP proxy version 0.3' diff --git a/Lib/test/string_tests.py b/Lib/test/string_tests.py index d69edd7b..709cac7a 100644 --- a/Lib/test/string_tests.py +++ b/Lib/test/string_tests.py @@ -341,6 +341,42 @@ class BaseTest: self.checkequal(reference_find(p, text), text, 'find', p) + def test_find_many_lengths(self): + haystack_repeats = [a * 10**e for e in range(6) for a in (1,2,5)] + haystacks = [(n, self.fixtype("abcab"*n + "da")) for n in haystack_repeats] + + needle_repeats = [a * 10**e for e in range(6) for a in (1, 3)] + needles = [(m, self.fixtype("abcab"*m + "da")) for m in needle_repeats] + + for n, haystack1 in haystacks: + haystack2 = haystack1[:-1] + for m, needle in needles: + answer1 = 5 * (n - m) if m <= n else -1 + self.assertEqual(haystack1.find(needle), answer1, msg=(n,m)) + self.assertEqual(haystack2.find(needle), -1, msg=(n,m)) + + def test_adaptive_find(self): + # This would be very slow for the naive algorithm, + # but str.find() should be O(n + m). + for N in 1000, 10_000, 100_000, 1_000_000: + A, B = 'a' * N, 'b' * N + haystack = A + A + B + A + A + needle = A + B + B + A + self.checkequal(-1, haystack, 'find', needle) + self.checkequal(0, haystack, 'count', needle) + self.checkequal(len(haystack), haystack + needle, 'find', needle) + self.checkequal(1, haystack + needle, 'count', needle) + + def test_find_with_memory(self): + # Test the "Skip with memory" path in the two-way algorithm. + for N in 1000, 3000, 10_000, 30_000: + needle = 'ab' * N + haystack = ('ab'*(N-1) + 'b') * 2 + self.checkequal(-1, haystack, 'find', needle) + self.checkequal(0, haystack, 'count', needle) + self.checkequal(len(haystack), haystack + needle, 'find', needle) + self.checkequal(1, haystack + needle, 'count', needle) + def test_find_shift_table_overflow(self): """When the table of 8-bit shifts overflows.""" N = 2**8 + 100 @@ -723,6 +759,18 @@ class BaseTest: self.checkraises(TypeError, 'hello', 'replace', 42, 'h') self.checkraises(TypeError, 'hello', 'replace', 'h', 42) + def test_replace_uses_two_way_maxcount(self): + # Test that maxcount works in _two_way_count in fastsearch.h + A, B = "A"*1000, "B"*1000 + AABAA = A + A + B + A + A + ABBA = A + B + B + A + self.checkequal(AABAA + ABBA, + AABAA + ABBA, 'replace', ABBA, "ccc", 0) + self.checkequal(AABAA + "ccc", + AABAA + ABBA, 'replace', ABBA, "ccc", 1) + self.checkequal(AABAA + "ccc", + AABAA + ABBA, 'replace', ABBA, "ccc", 2) + @unittest.skipIf(sys.maxsize > (1 << 32) or struct.calcsize('P') != 4, 'only applies to 32-bit platforms') def test_replace_overflow(self): diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index c33f90d8..b6350e4e 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -4,13 +4,16 @@ if __name__ != 'test.support': raise ImportError('support must be imported from the test package') import contextlib +import dataclasses import functools import getpass +import opcode import os import re import stat import sys import sysconfig +import textwrap import time import types import unittest @@ -19,11 +22,6 @@ import warnings from .testresult import get_test_runner -try: - from _testcapi import unicode_legacy_string -except ImportError: - unicode_legacy_string = None - __all__ = [ # globals "PIPE_MAX_SIZE", "verbose", "max_memuse", "use_resources", "failfast", @@ -36,7 +34,7 @@ __all__ = [ "is_resource_enabled", "requires", "requires_freebsd_version", "requires_linux_version", "requires_mac_ver", "check_syntax_error", - "BasicTestRunner", "run_unittest", "run_doctest", + "run_unittest", "run_doctest", "requires_gzip", "requires_bz2", "requires_lzma", "bigmemtest", "bigaddrspacetest", "cpython_only", "get_attribute", "requires_IEEE_754", "requires_zlib", @@ -46,9 +44,12 @@ __all__ = [ "anticipate_failure", "load_package_tests", "detect_api_mismatch", "check__all__", "skip_if_buggy_ucrt_strfptime", "check_disallow_instantiation", "check_sanitizer", "skip_if_sanitizer", + "requires_limited_api", "requires_specialization", # sys "is_jython", "is_android", "is_emscripten", "is_wasi", "check_impl_detail", "unix_shell", "setswitchinterval", + # os + "get_pagesize", # network "open_urlresource", # processes @@ -59,6 +60,8 @@ __all__ = [ "run_with_tz", "PGO", "missing_compiler_executable", "ALWAYS_EQ", "NEVER_EQ", "LARGEST", "SMALLEST", "LOOPBACK_TIMEOUT", "INTERNET_TIMEOUT", "SHORT_TIMEOUT", "LONG_TIMEOUT", + "Py_DEBUG", "EXCEEDS_RECURSION_LIMIT", "C_RECURSION_LIMIT", + "skip_on_s390x", ] @@ -116,17 +119,20 @@ class Error(Exception): class TestFailed(Error): """Test failed.""" + def __init__(self, msg, *args, stats=None): + self.msg = msg + self.stats = stats + super().__init__(msg, *args) + + def __str__(self): + return self.msg class TestFailedWithDetails(TestFailed): """Test failed.""" - def __init__(self, msg, errors, failures): - self.msg = msg + def __init__(self, msg, errors, failures, stats): self.errors = errors self.failures = failures - super().__init__(msg, errors, failures) - - def __str__(self): - return self.msg + super().__init__(msg, errors, failures, stats=stats) class TestDidNotRun(Error): """Test did not run any subtests.""" @@ -408,7 +414,7 @@ def check_sanitizer(*, address=False, memory=False, ub=False): ) address_sanitizer = ( '-fsanitize=address' in _cflags or - '--with-memory-sanitizer' in _config_args + '--with-address-sanitizer' in _config_args ) ub_sanitizer = ( '-fsanitize=undefined' in _cflags or @@ -500,9 +506,16 @@ def has_no_debug_ranges(): def requires_debug_ranges(reason='requires co_positions / debug_ranges'): return unittest.skipIf(has_no_debug_ranges(), reason) -requires_legacy_unicode_capi = unittest.skipUnless(unicode_legacy_string, - 'requires legacy Unicode C API') +def requires_legacy_unicode_capi(): + try: + from _testcapi import unicode_legacy_string + except ImportError: + unicode_legacy_string = None + + return unittest.skipUnless(unicode_legacy_string, + 'requires legacy Unicode C API') +# Is not actually used in tests, but is kept for compatibility. is_jython = sys.platform.startswith('java') is_android = hasattr(sys, 'getandroidapilevel') @@ -578,7 +591,8 @@ def darwin_malloc_err_warning(test_name): msg = ' NOTICE ' detail = (f'{test_name} may generate "malloc can\'t allocate region"\n' 'warnings on macOS systems. This behavior is known. Do not\n' - 'report a bug unless tests are also failing. See bpo-40928.') + 'report a bug unless tests are also failing.\n' + 'See https://github.com/python/cpython/issues/85100') padding, _ = shutil.get_terminal_size() print(msg.center(padding, '-')) @@ -612,6 +626,14 @@ def sortdict(dict): withcommas = ", ".join(reprpairs) return "{%s}" % withcommas + +def run_code(code: str) -> dict[str, object]: + """Run a piece of code after dedenting it, and return its global namespace.""" + ns = {} + exec(textwrap.dedent(code), ns) + return ns + + def check_syntax_error(testcase, statement, errtext='', *, lineno=None, offset=None): with testcase.assertRaisesRegex(SyntaxError, errtext) as cm: compile(statement, '<test string>', 'exec') @@ -734,8 +756,6 @@ def gc_collect(): """ import gc gc.collect() - if is_jython: - time.sleep(0.1) gc.collect() gc.collect() @@ -990,12 +1010,6 @@ def bigaddrspacetest(f): #======================================================================= # unittest integration. -class BasicTestRunner: - def run(self, test): - result = unittest.TestResult() - test(result) - return result - def _id(obj): return obj @@ -1074,6 +1088,18 @@ def refcount_test(test): return no_tracing(cpython_only(test)) +def requires_limited_api(test): + try: + import _testcapi + except ImportError: + return unittest.skip('needs _testcapi module')(test) + return unittest.skipUnless( + _testcapi.LIMITED_API_AVAILABLE, 'needs Limited API support')(test) + +def requires_specialization(test): + return unittest.skipUnless( + opcode.ENABLE_SPECIALIZATION, "requires specialization")(test) + def _filter_suite(suite, pred): """Recursively filter test cases in a suite based on a predicate.""" newtests = [] @@ -1086,6 +1112,29 @@ def _filter_suite(suite, pred): newtests.append(test) suite._tests = newtests +@dataclasses.dataclass(slots=True) +class TestStats: + tests_run: int = 0 + failures: int = 0 + skipped: int = 0 + + @staticmethod + def from_unittest(result): + return TestStats(result.testsRun, + len(result.failures), + len(result.skipped)) + + @staticmethod + def from_doctest(results): + return TestStats(results.attempted, + results.failed) + + def accumulate(self, stats): + self.tests_run += stats.tests_run + self.failures += stats.failures + self.skipped += stats.skipped + + def _run_suite(suite): """Run tests from a unittest.TestSuite-derived class.""" runner = get_test_runner(sys.stdout, @@ -1097,9 +1146,10 @@ def _run_suite(suite): if junit_xml_list is not None: junit_xml_list.append(result.get_xml_element()) - if not result.testsRun and not result.skipped: + if not result.testsRun and not result.skipped and not result.errors: raise TestDidNotRun if not result.wasSuccessful(): + stats = TestStats.from_unittest(result) if len(result.errors) == 1 and not result.failures: err = result.errors[0][1] elif len(result.failures) == 1 and not result.errors: @@ -1109,7 +1159,8 @@ def _run_suite(suite): if not verbose: err += "; run in verbose mode for details" errors = [(str(tc), exc_str) for tc, exc_str in result.errors] failures = [(str(tc), exc_str) for tc, exc_str in result.failures] - raise TestFailedWithDetails(err, errors, failures) + raise TestFailedWithDetails(err, errors, failures, stats=stats) + return result # By default, don't filter tests @@ -1140,7 +1191,6 @@ def _is_full_match_test(pattern): def set_match_tests(accept_patterns=None, ignore_patterns=None): global _match_test_func, _accept_test_patterns, _ignore_test_patterns - if accept_patterns is None: accept_patterns = () if ignore_patterns is None: @@ -1218,7 +1268,7 @@ def run_unittest(*classes): else: suite.addTest(loader.loadTestsFromTestCase(cls)) _filter_suite(suite, match_test) - _run_suite(suite) + return _run_suite(suite) #======================================================================= # Check for the presence of docstrings. @@ -1258,13 +1308,18 @@ def run_doctest(module, verbosity=None, optionflags=0): else: verbosity = None - f, t = doctest.testmod(module, verbose=verbosity, optionflags=optionflags) - if f: - raise TestFailed("%d of %d doctests failed" % (f, t)) + results = doctest.testmod(module, + verbose=verbosity, + optionflags=optionflags) + if results.failed: + stats = TestStats.from_doctest(results) + raise TestFailed(f"{results.failed} of {results.attempted} " + f"doctests failed", + stats=stats) if verbose: print('doctest (%s) ... %d tests with zero failures' % - (module.__name__, t)) - return f, t + (module.__name__, results.attempted)) + return results #======================================================================= @@ -1788,6 +1843,25 @@ def run_in_subinterp(code): Run code in a subinterpreter. Raise unittest.SkipTest if the tracemalloc module is enabled. """ + _check_tracemalloc() + import _testcapi + return _testcapi.run_in_subinterp(code) + + +def run_in_subinterp_with_config(code, *, own_gil=None, **config): + """ + Run code in a subinterpreter. Raise unittest.SkipTest if the tracemalloc + module is enabled. + """ + _check_tracemalloc() + import _testcapi + if own_gil is not None: + assert 'gil' not in config, (own_gil, config) + config['gil'] = 2 if own_gil else 1 + return _testcapi.run_in_subinterp_with_config(code, **config) + + +def _check_tracemalloc(): # Issue #10915, #15751: PyGILState_*() functions don't work with # sub-interpreters, the tracemalloc module uses these functions internally try: @@ -1799,8 +1873,6 @@ def run_in_subinterp(code): raise unittest.SkipTest("run_in_subinterp() cannot be used " "if tracemalloc module is tracing " "memory allocations") - import _testcapi - return _testcapi.run_in_subinterp(code) def check_free_after_iterating(test, iter, cls, args=()): @@ -1831,15 +1903,16 @@ def missing_compiler_executable(cmd_names=[]): missing. """ - # TODO (PEP 632): alternate check without using distutils - from distutils import ccompiler, sysconfig, spawn, errors + from setuptools._distutils import ccompiler, sysconfig, spawn + from setuptools import errors + compiler = ccompiler.new_compiler() sysconfig.customize_compiler(compiler) if compiler.compiler_type == "msvc": # MSVC has no executables, so check whether initialization succeeds try: compiler.initialize() - except errors.DistutilsPlatformError: + except errors.PlatformError: return "msvc" for name in compiler.executables: if cmd_names and name not in cmd_names: @@ -1870,6 +1943,18 @@ def setswitchinterval(interval): return sys.setswitchinterval(interval) +def get_pagesize(): + """Get size of a page in bytes.""" + try: + page_size = os.sysconf('SC_PAGESIZE') + except (ValueError, AttributeError): + try: + page_size = os.sysconf('SC_PAGE_SIZE') + except (ValueError, AttributeError): + page_size = 4096 + return page_size + + @contextlib.contextmanager def disable_faulthandler(): import faulthandler @@ -2087,31 +2172,26 @@ def wait_process(pid, *, exitcode, timeout=None): if timeout is None: timeout = LONG_TIMEOUT - t0 = time.monotonic() - sleep = 0.001 - max_sleep = 0.1 - while True: + + start_time = time.monotonic() + for _ in sleeping_retry(timeout, error=False): pid2, status = os.waitpid(pid, os.WNOHANG) if pid2 != 0: break - # process is still running - - dt = time.monotonic() - t0 - if dt > timeout: - try: - os.kill(pid, signal.SIGKILL) - os.waitpid(pid, 0) - except OSError: - # Ignore errors like ChildProcessError or PermissionError - pass - - raise AssertionError(f"process {pid} is still running " - f"after {dt:.1f} seconds") + # rety: the process is still running + else: + try: + os.kill(pid, signal.SIGKILL) + os.waitpid(pid, 0) + except OSError: + # Ignore errors like ChildProcessError or PermissionError + pass - sleep = min(sleep * 2, max_sleep) - time.sleep(sleep) + dt = time.monotonic() - start_time + raise AssertionError(f"process {pid} is still running " + f"after {dt:.1f} seconds") else: - # Windows implementation + # Windows implementation: don't support timeout :-( pid2, status = os.waitpid(pid, 0) exitcode2 = os.waitstatus_to_exitcode(status) @@ -2163,20 +2243,61 @@ def check_disallow_instantiation(testcase, tp, *args, **kwds): msg = f"cannot create '{re.escape(qualname)}' instances" testcase.assertRaisesRegex(TypeError, msg, tp, *args, **kwds) +def get_recursion_depth(): + """Get the recursion depth of the caller function. + + In the __main__ module, at the module level, it should be 1. + """ + try: + import _testinternalcapi + depth = _testinternalcapi.get_recursion_depth() + except (ImportError, RecursionError) as exc: + # sys._getframe() + frame.f_back implementation. + try: + depth = 0 + frame = sys._getframe() + while frame is not None: + depth += 1 + frame = frame.f_back + finally: + # Break any reference cycles. + frame = None + + # Ignore get_recursion_depth() frame. + return max(depth - 1, 1) + +def get_recursion_available(): + """Get the number of available frames before RecursionError. + + It depends on the current recursion depth of the caller function and + sys.getrecursionlimit(). + """ + limit = sys.getrecursionlimit() + depth = get_recursion_depth() + return limit - depth + @contextlib.contextmanager -def infinite_recursion(max_depth=75): +def set_recursion_limit(limit): + """Temporarily change the recursion limit.""" + original_limit = sys.getrecursionlimit() + try: + sys.setrecursionlimit(limit) + yield + finally: + sys.setrecursionlimit(original_limit) + +def infinite_recursion(max_depth=100): """Set a lower limit for tests that interact with infinite recursions (e.g test_ast.ASTHelpers_Test.test_recursion_direct) since on some debug windows builds, due to not enough functions being inlined the stack size might not handle the default recursion limit (1000). See bpo-11105 for details.""" - - original_depth = sys.getrecursionlimit() - try: - sys.setrecursionlimit(max_depth) - yield - finally: - sys.setrecursionlimit(original_depth) + if max_depth < 3: + raise ValueError("max_depth must be at least 3, got {max_depth}") + depth = get_recursion_depth() + depth = max(depth - 1, 1) # Ignore infinite_recursion() frame. + limit = depth + max_depth + return set_recursion_limit(limit) def ignore_deprecations_from(module: str, *, like: str) -> object: token = object() @@ -2225,6 +2346,180 @@ def requires_venv_with_pip(): return unittest.skipUnless(ctypes, 'venv: pip requires ctypes') +@functools.cache +def _findwheel(pkgname): + """Try to find a wheel with the package specified as pkgname. + + If set, the wheels are searched for in WHEEL_PKG_DIR (see ensurepip). + Otherwise, they are searched for in the test directory. + """ + wheel_dir = sysconfig.get_config_var('WHEEL_PKG_DIR') or TEST_HOME_DIR + filenames = os.listdir(wheel_dir) + filenames = sorted(filenames, reverse=True) # approximate "newest" first + for filename in filenames: + # filename is like 'setuptools-67.6.1-py3-none-any.whl' + if not filename.endswith(".whl"): + continue + prefix = pkgname + '-' + if filename.startswith(prefix): + return os.path.join(wheel_dir, filename) + raise FileNotFoundError(f"No wheel for {pkgname} found in {wheel_dir}") + + +# Context manager that creates a virtual environment, install setuptools and wheel in it +# and returns the path to the venv directory and the path to the python executable +@contextlib.contextmanager +def setup_venv_with_pip_setuptools_wheel(venv_dir): + import subprocess + from .os_helper import temp_cwd + + with temp_cwd() as temp_dir: + # Create virtual environment to get setuptools + cmd = [sys.executable, '-X', 'dev', '-m', 'venv', venv_dir] + if verbose: + print() + print('Run:', ' '.join(cmd)) + subprocess.run(cmd, check=True) + + venv = os.path.join(temp_dir, venv_dir) + + # Get the Python executable of the venv + python_exe = os.path.basename(sys.executable) + if sys.platform == 'win32': + python = os.path.join(venv, 'Scripts', python_exe) + else: + python = os.path.join(venv, 'bin', python_exe) + + cmd = [python, '-X', 'dev', + '-m', 'pip', 'install', + _findwheel('setuptools'), + _findwheel('wheel')] + if verbose: + print() + print('Run:', ' '.join(cmd)) + subprocess.run(cmd, check=True) + + yield python + + +# True if Python is built with the Py_DEBUG macro defined: if +# Python is built in debug mode (./configure --with-pydebug). +Py_DEBUG = hasattr(sys, 'gettotalrefcount') + + +def late_deletion(obj): + """ + Keep a Python alive as long as possible. + + Create a reference cycle and store the cycle in an object deleted late in + Python finalization. Try to keep the object alive until the very last + garbage collection. + + The function keeps a strong reference by design. It should be called in a + subprocess to not mark a test as "leaking a reference". + """ + + # Late CPython finalization: + # - finalize_interp_clear() + # - _PyInterpreterState_Clear(): Clear PyInterpreterState members + # (ex: codec_search_path, before_forkers) + # - clear os.register_at_fork() callbacks + # - clear codecs.register() callbacks + + ref_cycle = [obj] + ref_cycle.append(ref_cycle) + + # Store a reference in PyInterpreterState.codec_search_path + import codecs + def search_func(encoding): + return None + search_func.reference = ref_cycle + codecs.register(search_func) + + if hasattr(os, 'register_at_fork'): + # Store a reference in PyInterpreterState.before_forkers + def atfork_func(): + pass + atfork_func.reference = ref_cycle + os.register_at_fork(before=atfork_func) + + +def busy_retry(timeout, err_msg=None, /, *, error=True): + """ + Run the loop body until "break" stops the loop. + + After *timeout* seconds, raise an AssertionError if *error* is true, + or just stop if *error is false. + + Example: + + for _ in support.busy_retry(support.SHORT_TIMEOUT): + if check(): + break + + Example of error=False usage: + + for _ in support.busy_retry(support.SHORT_TIMEOUT, error=False): + if check(): + break + else: + raise RuntimeError('my custom error') + + """ + if timeout <= 0: + raise ValueError("timeout must be greater than zero") + + start_time = time.monotonic() + deadline = start_time + timeout + + while True: + yield + + if time.monotonic() >= deadline: + break + + if error: + dt = time.monotonic() - start_time + msg = f"timeout ({dt:.1f} seconds)" + if err_msg: + msg = f"{msg}: {err_msg}" + raise AssertionError(msg) + + +def sleeping_retry(timeout, err_msg=None, /, + *, init_delay=0.010, max_delay=1.0, error=True): + """ + Wait strategy that applies exponential backoff. + + Run the loop body until "break" stops the loop. Sleep at each loop + iteration, but not at the first iteration. The sleep delay is doubled at + each iteration (up to *max_delay* seconds). + + See busy_retry() documentation for the parameters usage. + + Example raising an exception after SHORT_TIMEOUT seconds: + + for _ in support.sleeping_retry(support.SHORT_TIMEOUT): + if check(): + break + + Example of error=False usage: + + for _ in support.sleeping_retry(support.SHORT_TIMEOUT, error=False): + if check(): + break + else: + raise RuntimeError('my custom error') + """ + + delay = init_delay + for _ in busy_retry(timeout, err_msg, error=error): + yield + + time.sleep(delay) + delay = min(delay * 2, max_delay) + + @contextlib.contextmanager def adjust_int_max_str_digits(max_digits): """Temporarily change the integer string conversion length limit.""" @@ -2234,3 +2529,13 @@ def adjust_int_max_str_digits(max_digits): yield finally: sys.set_int_max_str_digits(current) + +#For recursion tests, easily exceeds default recursion limit +EXCEEDS_RECURSION_LIMIT = 5000 + +# The default C recursion limit (from Include/cpython/pystate.h). +C_RECURSION_LIMIT = 1500 + +#Windows doesn't have os.uname() but it doesn't support s390x. +skip_on_s390x = unittest.skipIf(hasattr(os, 'uname') and os.uname().machine == 's390x', + 'skipped on s390x') diff --git a/Lib/test/support/_hypothesis_stubs/__init__.py b/Lib/test/support/_hypothesis_stubs/__init__.py new file mode 100644 index 00000000..6ba5bb81 --- /dev/null +++ b/Lib/test/support/_hypothesis_stubs/__init__.py @@ -0,0 +1,111 @@ +from enum import Enum +import functools +import unittest + +__all__ = [ + "given", + "example", + "assume", + "reject", + "register_random", + "strategies", + "HealthCheck", + "settings", + "Verbosity", +] + +from . import strategies + + +def given(*_args, **_kwargs): + def decorator(f): + if examples := getattr(f, "_examples", []): + + @functools.wraps(f) + def test_function(self): + for example_args, example_kwargs in examples: + with self.subTest(*example_args, **example_kwargs): + f(self, *example_args, **example_kwargs) + + else: + # If we have found no examples, we must skip the test. If @example + # is applied after @given, it will re-wrap the test to remove the + # skip decorator. + test_function = unittest.skip( + "Hypothesis required for property test with no " + + "specified examples" + )(f) + + test_function._given = True + return test_function + + return decorator + + +def example(*args, **kwargs): + if bool(args) == bool(kwargs): + raise ValueError("Must specify exactly one of *args or **kwargs") + + def decorator(f): + base_func = getattr(f, "__wrapped__", f) + if not hasattr(base_func, "_examples"): + base_func._examples = [] + + base_func._examples.append((args, kwargs)) + + if getattr(f, "_given", False): + # If the given decorator is below all the example decorators, + # it would be erroneously skipped, so we need to re-wrap the new + # base function. + f = given()(base_func) + + return f + + return decorator + + +def assume(condition): + if not condition: + raise unittest.SkipTest("Unsatisfied assumption") + return True + + +def reject(): + assume(False) + + +def register_random(*args, **kwargs): + pass # pragma: no cover + + +def settings(*args, **kwargs): + return lambda f: f # pragma: nocover + + +class HealthCheck(Enum): + data_too_large = 1 + filter_too_much = 2 + too_slow = 3 + return_value = 5 + large_base_example = 7 + not_a_test_method = 8 + + @classmethod + def all(cls): + return list(cls) + + +class Verbosity(Enum): + quiet = 0 + normal = 1 + verbose = 2 + debug = 3 + + +class Phase(Enum): + explicit = 0 + reuse = 1 + generate = 2 + target = 3 + shrink = 4 + explain = 5 diff --git a/Lib/test/support/_hypothesis_stubs/_helpers.py b/Lib/test/support/_hypothesis_stubs/_helpers.py new file mode 100644 index 00000000..3f6244e4 --- /dev/null +++ b/Lib/test/support/_hypothesis_stubs/_helpers.py @@ -0,0 +1,43 @@ +# Stub out only the subset of the interface that we actually use in our tests. +class StubClass: + def __init__(self, *args, **kwargs): + self.__stub_args = args + self.__stub_kwargs = kwargs + self.__repr = None + + def _with_repr(self, new_repr): + new_obj = self.__class__(*self.__stub_args, **self.__stub_kwargs) + new_obj.__repr = new_repr + return new_obj + + def __repr__(self): + if self.__repr is not None: + return self.__repr + + argstr = ", ".join(self.__stub_args) + kwargstr = ", ".join(f"{kw}={val}" for kw, val in self.__stub_kwargs.items()) + + in_parens = argstr + if kwargstr: + in_parens += ", " + kwargstr + + return f"{self.__class__.__qualname__}({in_parens})" + + +def stub_factory(klass, name, *, with_repr=None, _seen={}): + if (klass, name) not in _seen: + + class Stub(klass): + def __init__(self, *args, **kwargs): + super().__init__() + self.__stub_args = args + self.__stub_kwargs = kwargs + + Stub.__name__ = name + Stub.__qualname__ = name + if with_repr is not None: + Stub._repr = None + + _seen.setdefault((klass, name, with_repr), Stub) + + return _seen[(klass, name, with_repr)] diff --git a/Lib/test/support/_hypothesis_stubs/strategies.py b/Lib/test/support/_hypothesis_stubs/strategies.py new file mode 100644 index 00000000..d2b885d4 --- /dev/null +++ b/Lib/test/support/_hypothesis_stubs/strategies.py @@ -0,0 +1,91 @@ +import functools + +from ._helpers import StubClass, stub_factory + + +class StubStrategy(StubClass): + def __make_trailing_repr(self, transformation_name, func): + func_name = func.__name__ or repr(func) + return f"{self!r}.{transformation_name}({func_name})" + + def map(self, pack): + return self._with_repr(self.__make_trailing_repr("map", pack)) + + def flatmap(self, expand): + return self._with_repr(self.__make_trailing_repr("flatmap", expand)) + + def filter(self, condition): + return self._with_repr(self.__make_trailing_repr("filter", condition)) + + def __or__(self, other): + new_repr = f"one_of({self!r}, {other!r})" + return self._with_repr(new_repr) + + +_STRATEGIES = { + "binary", + "booleans", + "builds", + "characters", + "complex_numbers", + "composite", + "data", + "dates", + "datetimes", + "decimals", + "deferred", + "dictionaries", + "emails", + "fixed_dictionaries", + "floats", + "fractions", + "from_regex", + "from_type", + "frozensets", + "functions", + "integers", + "iterables", + "just", + "lists", + "none", + "nothing", + "one_of", + "permutations", + "random_module", + "randoms", + "recursive", + "register_type_strategy", + "runner", + "sampled_from", + "sets", + "shared", + "slices", + "timedeltas", + "times", + "text", + "tuples", + "uuids", +} + +__all__ = sorted(_STRATEGIES) + + +def composite(f): + strategy = stub_factory(StubStrategy, f.__name__) + + @functools.wraps(f) + def inner(*args, **kwargs): + return strategy(*args, **kwargs) + + return inner + + +def __getattr__(name): + if name not in _STRATEGIES: + raise AttributeError(f"Unknown attribute {name}") + + return stub_factory(StubStrategy, f"hypothesis.strategies.{name}") + + +def __dir__(): + return __all__ diff --git a/Lib/test/support/ast_helper.py b/Lib/test/support/ast_helper.py new file mode 100644 index 00000000..8a0415b6 --- /dev/null +++ b/Lib/test/support/ast_helper.py @@ -0,0 +1,43 @@ +import ast + +class ASTTestMixin: + """Test mixing to have basic assertions for AST nodes.""" + + def assertASTEqual(self, ast1, ast2): + # Ensure the comparisons start at an AST node + self.assertIsInstance(ast1, ast.AST) + self.assertIsInstance(ast2, ast.AST) + + # An AST comparison routine modeled after ast.dump(), but + # instead of string building, it traverses the two trees + # in lock-step. + def traverse_compare(a, b, missing=object()): + if type(a) is not type(b): + self.fail(f"{type(a)!r} is not {type(b)!r}") + if isinstance(a, ast.AST): + for field in a._fields: + value1 = getattr(a, field, missing) + value2 = getattr(b, field, missing) + # Singletons are equal by definition, so further + # testing can be skipped. + if value1 is not value2: + traverse_compare(value1, value2) + elif isinstance(a, list): + try: + for node1, node2 in zip(a, b, strict=True): + traverse_compare(node1, node2) + except ValueError: + # Attempt a "pretty" error ala assertSequenceEqual() + len1 = len(a) + len2 = len(b) + if len1 > len2: + what = "First" + diff = len1 - len2 + else: + what = "Second" + diff = len2 - len1 + msg = f"{what} list contains {diff} additional elements." + raise self.failureException(msg) from None + elif a != b: + self.fail(f"{a!r} != {b!r}") + traverse_compare(ast1, ast2) diff --git a/Lib/asynchat.py b/Lib/test/support/asynchat.py similarity index 97% rename from Lib/asynchat.py rename to Lib/test/support/asynchat.py index bed797e9..38c47a1f 100644 --- a/Lib/asynchat.py +++ b/Lib/test/support/asynchat.py @@ -1,3 +1,8 @@ +# TODO: This module was deprecated and removed from CPython 3.12 +# Now it is a test-only helper. Any attempts to rewrite exising tests that +# are using this module and remove it completely are appreciated! +# See: https://github.com/python/cpython/issues/72719 + # -*- Mode: Python; tab-width: 4 -*- # Id: asynchat.py,v 2.26 2000/09/07 22:29:26 rushing Exp # Author: Sam Rushing <rushing@nightmare.com> @@ -45,15 +50,10 @@ command will be accumulated (using your own 'collect_incoming_data' method) up to the terminator, and then control will be returned to you - by calling your self.found_terminator() method. """ -import asyncore -from collections import deque -from warnings import _deprecated - -_DEPRECATION_MSG = ('The {name} module is deprecated and will be removed in ' - 'Python {remove}. The recommended replacement is asyncio') -_deprecated(__name__, _DEPRECATION_MSG, remove=(3, 12)) +from collections import deque +from test.support import asyncore class async_chat(asyncore.dispatcher): diff --git a/Lib/asyncore.py b/Lib/test/support/asyncore.py similarity index 98% rename from Lib/asyncore.py rename to Lib/test/support/asyncore.py index 57c86871..b397aca5 100644 --- a/Lib/asyncore.py +++ b/Lib/test/support/asyncore.py @@ -1,3 +1,8 @@ +# TODO: This module was deprecated and removed from CPython 3.12 +# Now it is a test-only helper. Any attempts to rewrite exising tests that +# are using this module and remove it completely are appreciated! +# See: https://github.com/python/cpython/issues/72719 + # -*- Mode: Python -*- # Id: asyncore.py,v 2.51 2000/09/07 22:29:26 rushing Exp # Author: Sam Rushing <rushing@nightmare.com> @@ -57,10 +62,6 @@ from errno import EALREADY, EINPROGRESS, EWOULDBLOCK, ECONNRESET, EINVAL, \ ENOTCONN, ESHUTDOWN, EISCONN, EBADF, ECONNABORTED, EPIPE, EAGAIN, \ errorcode -_DEPRECATION_MSG = ('The {name} module is deprecated and will be removed in ' - 'Python {remove}. The recommended replacement is asyncio') -warnings._deprecated(__name__, _DEPRECATION_MSG, remove=(3, 12)) - _DISCONNECTED = frozenset({ECONNRESET, ENOTCONN, ESHUTDOWN, ECONNABORTED, EPIPE, EBADF}) @@ -536,10 +537,11 @@ class dispatcher_with_send(dispatcher): # --------------------------------------------------------------------------- def compact_traceback(): - t, v, tb = sys.exc_info() - tbinfo = [] + exc = sys.exception() + tb = exc.__traceback__ if not tb: # Must have a traceback raise AssertionError("traceback does not exist") + tbinfo = [] while tb: tbinfo.append(( tb.tb_frame.f_code.co_filename, @@ -553,7 +555,7 @@ def compact_traceback(): file, function, line = tbinfo[-1] info = ' '.join(['[%s|%s|%s]' % x for x in tbinfo]) - return (file, function, line), t, v, info + return (file, function, line), type(exc), exc, info def close_all(map=None, ignore_all=False): if map is None: diff --git a/Lib/test/support/bytecode_helper.py b/Lib/test/support/bytecode_helper.py index 471d4a68..388d1266 100644 --- a/Lib/test/support/bytecode_helper.py +++ b/Lib/test/support/bytecode_helper.py @@ -3,6 +3,7 @@ import unittest import dis import io +from _testinternalcapi import compiler_codegen, optimize_cfg, assemble_code_object _UNSPECIFIED = object() @@ -16,6 +17,7 @@ class BytecodeTestCase(unittest.TestCase): def assertInBytecode(self, x, opname, argval=_UNSPECIFIED): """Returns instr if opname is found, otherwise throws AssertionError""" + self.assertIn(opname, dis.opmap) for instr in dis.get_instructions(x): if instr.opname == opname: if argval is _UNSPECIFIED or instr.argval == argval: @@ -30,6 +32,7 @@ class BytecodeTestCase(unittest.TestCase): def assertNotInBytecode(self, x, opname, argval=_UNSPECIFIED): """Throws AssertionError if opname is found""" + self.assertIn(opname, dis.opmap) for instr in dis.get_instructions(x): if instr.opname == opname: disassembly = self.get_disassembly_as_string(x) @@ -40,3 +43,101 @@ class BytecodeTestCase(unittest.TestCase): msg = '(%s,%r) occurs in bytecode:\n%s' msg = msg % (opname, argval, disassembly) self.fail(msg) + +class CompilationStepTestCase(unittest.TestCase): + + HAS_ARG = set(dis.hasarg) + HAS_TARGET = set(dis.hasjrel + dis.hasjabs + dis.hasexc) + HAS_ARG_OR_TARGET = HAS_ARG.union(HAS_TARGET) + + class Label: + pass + + def assertInstructionsMatch(self, actual_, expected_): + # get two lists where each entry is a label or + # an instruction tuple. Normalize the labels to the + # instruction count of the target, and compare the lists. + + self.assertIsInstance(actual_, list) + self.assertIsInstance(expected_, list) + + actual = self.normalize_insts(actual_) + expected = self.normalize_insts(expected_) + self.assertEqual(len(actual), len(expected)) + + # compare instructions + for act, exp in zip(actual, expected): + if isinstance(act, int): + self.assertEqual(exp, act) + continue + self.assertIsInstance(exp, tuple) + self.assertIsInstance(act, tuple) + # crop comparison to the provided expected values + if len(act) > len(exp): + act = act[:len(exp)] + self.assertEqual(exp, act) + + def resolveAndRemoveLabels(self, insts): + idx = 0 + res = [] + for item in insts: + assert isinstance(item, (self.Label, tuple)) + if isinstance(item, self.Label): + item.value = idx + else: + idx += 1 + res.append(item) + + return res + + def normalize_insts(self, insts): + """ Map labels to instruction index. + Map opcodes to opnames. + """ + insts = self.resolveAndRemoveLabels(insts) + res = [] + for item in insts: + assert isinstance(item, tuple) + opcode, oparg, *loc = item + opcode = dis.opmap.get(opcode, opcode) + if isinstance(oparg, self.Label): + arg = oparg.value + else: + arg = oparg if opcode in self.HAS_ARG else None + opcode = dis.opname[opcode] + res.append((opcode, arg, *loc)) + return res + + def complete_insts_info(self, insts): + # fill in omitted fields in location, and oparg 0 for ops with no arg. + res = [] + for item in insts: + assert isinstance(item, tuple) + inst = list(item) + opcode = dis.opmap[inst[0]] + oparg = inst[1] + loc = inst[2:] + [-1] * (6 - len(inst)) + res.append((opcode, oparg, *loc)) + return res + + +class CodegenTestCase(CompilationStepTestCase): + + def generate_code(self, ast): + insts, _ = compiler_codegen(ast, "my_file.py", 0) + return insts + + +class CfgOptimizationTestCase(CompilationStepTestCase): + + def get_optimized(self, insts, consts, nlocals=0): + insts = self.normalize_insts(insts) + insts = self.complete_insts_info(insts) + insts = optimize_cfg(insts, consts, nlocals) + return insts, consts + +class AssemblerTestCase(CompilationStepTestCase): + + def get_code_object(self, filename, insts, metadata): + co = assemble_code_object(filename, insts, metadata) + return co diff --git a/Lib/test/support/hypothesis_helper.py b/Lib/test/support/hypothesis_helper.py new file mode 100644 index 00000000..db93eea5 --- /dev/null +++ b/Lib/test/support/hypothesis_helper.py @@ -0,0 +1,38 @@ +import os + +try: + import hypothesis +except ImportError: + from . import _hypothesis_stubs as hypothesis +else: + # When using the real Hypothesis, we'll configure it to ignore occasional + # slow tests (avoiding flakiness from random VM slowness in CI). + hypothesis.settings.register_profile( + "slow-is-ok", + deadline=None, + suppress_health_check=[ + hypothesis.HealthCheck.too_slow, + hypothesis.HealthCheck.differing_executors, + ], + ) + hypothesis.settings.load_profile("slow-is-ok") + + # For local development, we'll write to the default on-local-disk database + # of failing examples, and also use a pull-through cache to automatically + # replay any failing examples discovered in CI. For details on how this + # works, see https://hypothesis.readthedocs.io/en/latest/database.html + if "CI" not in os.environ: + from hypothesis.database import ( + GitHubArtifactDatabase, + MultiplexedDatabase, + ReadOnlyDatabase, + ) + + hypothesis.settings.register_profile( + "cpython-local-dev", + database=MultiplexedDatabase( + hypothesis.settings.default.database, + ReadOnlyDatabase(GitHubArtifactDatabase("python", "cpython")), + ), + ) + hypothesis.settings.load_profile("cpython-local-dev") diff --git a/Lib/test/support/import_helper.py b/Lib/test/support/import_helper.py index 5201dc84..67f18e53 100644 --- a/Lib/test/support/import_helper.py +++ b/Lib/test/support/import_helper.py @@ -105,6 +105,26 @@ def frozen_modules(enabled=True): _imp._override_frozen_modules_for_tests(0) +@contextlib.contextmanager +def multi_interp_extensions_check(enabled=True): + """Force legacy modules to be allowed in subinterpreters (or not). + + ("legacy" == single-phase init) + + This only applies to modules that haven't been imported yet. + It overrides the PyInterpreterConfig.check_multi_interp_extensions + setting (see support.run_in_subinterp_with_config() and + _xxsubinterpreters.create()). + + Also see importlib.utils.allowing_all_extensions(). + """ + old = _imp._override_multi_interp_extensions_check(1 if enabled else -1) + try: + yield + finally: + _imp._override_multi_interp_extensions_check(old) + + def import_fresh_module(name, fresh=(), blocked=(), *, deprecated=False, usefrozen=False, @@ -246,3 +266,11 @@ def modules_cleanup(oldmodules): # do currently). Implicitly imported *real* modules should be left alone # (see issue 10556). sys.modules.update(oldmodules) + + +def mock_register_at_fork(func): + # bpo-30599: Mock os.register_at_fork() when importing the random module, + # since this function doesn't allow to unregister callbacks and would leak + # memory. + from unittest import mock + return mock.patch('os.register_at_fork', create=True)(func) diff --git a/Lib/test/support/interpreters.py b/Lib/test/support/interpreters.py index 2935708f..5c484d11 100644 --- a/Lib/test/support/interpreters.py +++ b/Lib/test/support/interpreters.py @@ -2,11 +2,12 @@ import time import _xxsubinterpreters as _interpreters +import _xxinterpchannels as _channels # aliases: -from _xxsubinterpreters import ( +from _xxsubinterpreters import is_shareable, RunFailedError +from _xxinterpchannels import ( ChannelError, ChannelNotFoundError, ChannelEmptyError, - is_shareable, ) @@ -102,7 +103,7 @@ def create_channel(): The channel may be used to pass data safely between interpreters. """ - cid = _interpreters.channel_create() + cid = _channels.create() recv, send = RecvChannel(cid), SendChannel(cid) return recv, send @@ -110,14 +111,14 @@ def create_channel(): def list_all_channels(): """Return a list of (recv, send) for all open channels.""" return [(RecvChannel(cid), SendChannel(cid)) - for cid in _interpreters.channel_list_all()] + for cid in _channels.list_all()] class _ChannelEnd: """The base class for RecvChannel and SendChannel.""" def __init__(self, id): - if not isinstance(id, (int, _interpreters.ChannelID)): + if not isinstance(id, (int, _channels.ChannelID)): raise TypeError(f'id must be an int, got {id!r}') self._id = id @@ -152,10 +153,10 @@ class RecvChannel(_ChannelEnd): This blocks until an object has been sent, if none have been sent already. """ - obj = _interpreters.channel_recv(self._id, _sentinel) + obj = _channels.recv(self._id, _sentinel) while obj is _sentinel: time.sleep(_delay) - obj = _interpreters.channel_recv(self._id, _sentinel) + obj = _channels.recv(self._id, _sentinel) return obj def recv_nowait(self, default=_NOT_SET): @@ -166,9 +167,9 @@ class RecvChannel(_ChannelEnd): is the same as recv(). """ if default is _NOT_SET: - return _interpreters.channel_recv(self._id) + return _channels.recv(self._id) else: - return _interpreters.channel_recv(self._id, default) + return _channels.recv(self._id, default) class SendChannel(_ChannelEnd): @@ -179,7 +180,7 @@ class SendChannel(_ChannelEnd): This blocks until the object is received. """ - _interpreters.channel_send(self._id, obj) + _channels.send(self._id, obj) # XXX We are missing a low-level channel_send_wait(). # See bpo-32604 and gh-19829. # Until that shows up we fake it: @@ -194,4 +195,4 @@ class SendChannel(_ChannelEnd): # XXX Note that at the moment channel_send() only ever returns # None. This should be fixed when channel_send_wait() is added. # See bpo-32604 and gh-19829. - return _interpreters.channel_send(self._id, obj) + return _channels.send(self._id, obj) diff --git a/Lib/test/support/os_helper.py b/Lib/test/support/os_helper.py index f599cc75..821a4b1f 100644 --- a/Lib/test/support/os_helper.py +++ b/Lib/test/support/os_helper.py @@ -4,6 +4,7 @@ import errno import os import re import stat +import string import sys import time import unittest @@ -11,11 +12,7 @@ import warnings # Filename used for testing -if os.name == 'java': - # Jython disallows @ in module names - TESTFN_ASCII = '$test' -else: - TESTFN_ASCII = '@test' +TESTFN_ASCII = '@test' # Disambiguate TESTFN for parallel testing, while letting it remain a valid # module name. @@ -141,6 +138,11 @@ for name in ( try: name.decode(sys.getfilesystemencoding()) except UnicodeDecodeError: + try: + name.decode(sys.getfilesystemencoding(), + sys.getfilesystemencodeerrors()) + except UnicodeDecodeError: + continue TESTFN_UNDECODABLE = os.fsencode(TESTFN_ASCII) + name break @@ -567,7 +569,7 @@ def fs_is_case_insensitive(directory): class FakePath: - """Simple implementing of the path protocol. + """Simple implementation of the path protocol. """ def __init__(self, path): self.path = path @@ -715,3 +717,37 @@ class EnvironmentVarGuard(collections.abc.MutableMapping): else: self._environ[k] = v os.environ = self._environ + + +try: + import ctypes + kernel32 = ctypes.WinDLL('kernel32', use_last_error=True) + + ERROR_FILE_NOT_FOUND = 2 + DDD_REMOVE_DEFINITION = 2 + DDD_EXACT_MATCH_ON_REMOVE = 4 + DDD_NO_BROADCAST_SYSTEM = 8 +except (ImportError, AttributeError): + def subst_drive(path): + raise unittest.SkipTest('ctypes or kernel32 is not available') +else: + @contextlib.contextmanager + def subst_drive(path): + """Temporarily yield a substitute drive for a given path.""" + for c in reversed(string.ascii_uppercase): + drive = f'{c}:' + if (not kernel32.QueryDosDeviceW(drive, None, 0) and + ctypes.get_last_error() == ERROR_FILE_NOT_FOUND): + break + else: + raise unittest.SkipTest('no available logical drive') + if not kernel32.DefineDosDeviceW( + DDD_NO_BROADCAST_SYSTEM, drive, path): + raise ctypes.WinError(ctypes.get_last_error()) + try: + yield drive + finally: + if not kernel32.DefineDosDeviceW( + DDD_REMOVE_DEFINITION | DDD_EXACT_MATCH_ON_REMOVE, + drive, path): + raise ctypes.WinError(ctypes.get_last_error()) diff --git a/Lib/test/support/socket_helper.py b/Lib/test/support/socket_helper.py index 42b2a933..e85d912c 100644 --- a/Lib/test/support/socket_helper.py +++ b/Lib/test/support/socket_helper.py @@ -1,8 +1,11 @@ import contextlib import errno +import os.path import socket -import unittest import sys +import subprocess +import tempfile +import unittest from .. import support from . import warnings_helper @@ -61,7 +64,7 @@ def find_unused_port(family=socket.AF_INET, socktype=socket.SOCK_STREAM): http://bugs.python.org/issue2550 for more info. The following site also has a very thorough description about the implications of both REUSEADDR and EXCLUSIVEADDRUSE on Windows: - http://msdn2.microsoft.com/en-us/library/ms740621(VS.85).aspx) + https://learn.microsoft.com/windows/win32/winsock/using-so-reuseaddr-and-so-exclusiveaddruse XXX: although this approach is a vast improvement on previous attempts to elicit unused ports, it rests heavily on the assumption that the ephemeral @@ -270,3 +273,73 @@ def transient_internet(resource_name, *, timeout=_NOT_SET, errnos=()): # __cause__ or __context__? finally: socket.setdefaulttimeout(old_timeout) + + +def create_unix_domain_name(): + """ + Create a UNIX domain name: socket.bind() argument of a AF_UNIX socket. + + Return a path relative to the current directory to get a short path + (around 27 ASCII characters). + """ + return tempfile.mktemp(prefix="test_python_", suffix='.sock', + dir=os.path.curdir) + + +# consider that sysctl values should not change while tests are running +_sysctl_cache = {} + +def _get_sysctl(name): + """Get a sysctl value as an integer.""" + try: + return _sysctl_cache[name] + except KeyError: + pass + + # At least Linux and FreeBSD support the "-n" option + cmd = ['sysctl', '-n', name] + proc = subprocess.run(cmd, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + text=True) + if proc.returncode: + support.print_warning(f'{' '.join(cmd)!r} command failed with ' + f'exit code {proc.returncode}') + # cache the error to only log the warning once + _sysctl_cache[name] = None + return None + output = proc.stdout + + # Parse '0\n' to get '0' + try: + value = int(output.strip()) + except Exception as exc: + support.print_warning(f'Failed to parse {' '.join(cmd)!r} ' + f'command output {output!r}: {exc!r}') + # cache the error to only log the warning once + _sysctl_cache[name] = None + return None + + _sysctl_cache[name] = value + return value + + +def tcp_blackhole(): + if not sys.platform.startswith('freebsd'): + return False + + # gh-109015: test if FreeBSD TCP blackhole is enabled + value = _get_sysctl('net.inet.tcp.blackhole') + if value is None: + # don't skip if we fail to get the sysctl value + return False + return (value != 0) + + +def skip_if_tcp_blackhole(test): + """Decorator skipping test if TCP blackhole is enabled.""" + skip_if = unittest.skipIf( + tcp_blackhole(), + "TCP blackhole is enabled (sysctl net.inet.tcp.blackhole)" + ) + return skip_if(test) diff --git a/Lib/test/support/testcase.py b/Lib/test/support/testcase.py new file mode 100644 index 00000000..1e4363b1 --- /dev/null +++ b/Lib/test/support/testcase.py @@ -0,0 +1,25 @@ +class ExceptionIsLikeMixin: + def assertExceptionIsLike(self, exc, template): + """ + Passes when the provided `exc` matches the structure of `template`. + Individual exceptions don't have to be the same objects or even pass + an equality test: they only need to be the same type and contain equal + `exc_obj.args`. + """ + if exc is None and template is None: + return + + if template is None: + self.fail(f"unexpected exception: {exc}") + + if exc is None: + self.fail(f"expected an exception like {template!r}, got None") + + if not isinstance(exc, ExceptionGroup): + self.assertEqual(exc.__class__, template.__class__) + self.assertEqual(exc.args[0], template.args[0]) + else: + self.assertEqual(exc.message, template.message) + self.assertEqual(len(exc.exceptions), len(template.exceptions)) + for e, t in zip(exc.exceptions, template.exceptions): + self.assertExceptionIsLike(e, t) diff --git a/Lib/test/support/testresult.py b/Lib/test/support/testresult.py index 2cd1366c..de23fdd5 100644 --- a/Lib/test/support/testresult.py +++ b/Lib/test/support/testresult.py @@ -8,6 +8,7 @@ import sys import time import traceback import unittest +from test import support class RegressionTestResult(unittest.TextTestResult): USE_XML = False @@ -18,10 +19,13 @@ class RegressionTestResult(unittest.TextTestResult): self.buffer = True if self.USE_XML: from xml.etree import ElementTree as ET - from datetime import datetime + from datetime import datetime, UTC self.__ET = ET self.__suite = ET.Element('testsuite') - self.__suite.set('start', datetime.utcnow().isoformat(' ')) + self.__suite.set('start', + datetime.now(UTC) + .replace(tzinfo=None) + .isoformat(' ')) self.__e = None self.__start_time = None @@ -109,6 +113,8 @@ class RegressionTestResult(unittest.TextTestResult): def addFailure(self, test, err): self._add_result(test, True, failure=self.__makeErrorDict(*err)) super().addFailure(test, err) + if support.failfast: + self.stop() def addSkip(self, test, reason): self._add_result(test, skipped=reason) diff --git a/Lib/test/support/threading_helper.py b/Lib/test/support/threading_helper.py index 26cbc6f4..7f16050f 100644 --- a/Lib/test/support/threading_helper.py +++ b/Lib/test/support/threading_helper.py @@ -88,19 +88,17 @@ def wait_threads_exit(timeout=None): yield finally: start_time = time.monotonic() - deadline = start_time + timeout - while True: + for _ in support.sleeping_retry(timeout, error=False): + support.gc_collect() count = _thread._count() if count <= old_count: break - if time.monotonic() > deadline: - dt = time.monotonic() - start_time - msg = (f"wait_threads() failed to cleanup {count - old_count} " - f"threads after {dt:.1f} seconds " - f"(count: {count}, old count: {old_count})") - raise AssertionError(msg) - time.sleep(0.010) - support.gc_collect() + else: + dt = time.monotonic() - start_time + msg = (f"wait_threads() failed to cleanup {count - old_count} " + f"threads after {dt:.1f} seconds " + f"(count: {count}, old count: {old_count})") + raise AssertionError(msg) def join_thread(thread, timeout=None): @@ -117,7 +115,11 @@ def join_thread(thread, timeout=None): @contextlib.contextmanager def start_threads(threads, unlock=None): - import faulthandler + try: + import faulthandler + except ImportError: + # It isn't supported on subinterpreters yet. + faulthandler = None threads = list(threads) started = [] try: @@ -149,7 +151,8 @@ def start_threads(threads, unlock=None): finally: started = [t for t in started if t.is_alive()] if started: - faulthandler.dump_traceback(sys.stdout) + if faulthandler is not None: + faulthandler.dump_traceback(sys.stdout) raise AssertionError('Unable to join %d threads' % len(started)) diff --git a/Lib/test/support/warnings_helper.py b/Lib/test/support/warnings_helper.py index 28e96f88..c1bf0562 100644 --- a/Lib/test/support/warnings_helper.py +++ b/Lib/test/support/warnings_helper.py @@ -44,7 +44,7 @@ def check_syntax_warning(testcase, statement, errtext='', def ignore_warnings(*, category): - """Decorator to suppress deprecation warnings. + """Decorator to suppress warnings. Use of context managers to hide warnings make diffs more noisy and tools like 'git blame' less useful. diff --git a/Lib/test/test___all__.py b/Lib/test/test___all__.py index 1ec83cb0..ecf73b3a 100644 --- a/Lib/test/test___all__.py +++ b/Lib/test/test___all__.py @@ -100,10 +100,9 @@ class AllTest(unittest.TestCase): '__future__', ]) - if not sys.platform.startswith('java'): - # In case _socket fails to build, make this test fail more gracefully - # than an AttributeError somewhere deep in CGIHTTPServer. - import _socket + # In case _socket fails to build, make this test fail more gracefully + # than an AttributeError somewhere deep in CGIHTTPServer. + import _socket ignored = [] failed_imports = [] diff --git a/Lib/test/test__opcode.py b/Lib/test/test__opcode.py index 2a4c0d2e..7640c6fb 100644 --- a/Lib/test/test__opcode.py +++ b/Lib/test/test__opcode.py @@ -18,9 +18,12 @@ class OpcodeTests(unittest.TestCase): self.assertRaises(ValueError, stack_effect, dis.opmap['BUILD_SLICE']) self.assertRaises(ValueError, stack_effect, dis.opmap['POP_TOP'], 0) # All defined opcodes + has_arg = dis.hasarg for name, code in filter(lambda item: item[0] not in dis.deoptmap, dis.opmap.items()): + if code >= opcode.MIN_INSTRUMENTED_OPCODE: + continue with self.subTest(opname=name): - if code < dis.HAVE_ARGUMENT: + if code not in has_arg: stack_effect(code) self.assertRaises(ValueError, stack_effect, code, 0) else: @@ -33,23 +36,23 @@ class OpcodeTests(unittest.TestCase): self.assertRaises(ValueError, stack_effect, code, 0) def test_stack_effect_jump(self): - JUMP_IF_TRUE_OR_POP = dis.opmap['JUMP_IF_TRUE_OR_POP'] - self.assertEqual(stack_effect(JUMP_IF_TRUE_OR_POP, 0), 0) - self.assertEqual(stack_effect(JUMP_IF_TRUE_OR_POP, 0, jump=True), 0) - self.assertEqual(stack_effect(JUMP_IF_TRUE_OR_POP, 0, jump=False), -1) FOR_ITER = dis.opmap['FOR_ITER'] self.assertEqual(stack_effect(FOR_ITER, 0), 1) - self.assertEqual(stack_effect(FOR_ITER, 0, jump=True), -1) + self.assertEqual(stack_effect(FOR_ITER, 0, jump=True), 1) self.assertEqual(stack_effect(FOR_ITER, 0, jump=False), 1) JUMP_FORWARD = dis.opmap['JUMP_FORWARD'] self.assertEqual(stack_effect(JUMP_FORWARD, 0), 0) self.assertEqual(stack_effect(JUMP_FORWARD, 0, jump=True), 0) self.assertEqual(stack_effect(JUMP_FORWARD, 0, jump=False), 0) # All defined opcodes + has_arg = dis.hasarg + has_exc = dis.hasexc has_jump = dis.hasjabs + dis.hasjrel for name, code in filter(lambda item: item[0] not in dis.deoptmap, dis.opmap.items()): + if code >= opcode.MIN_INSTRUMENTED_OPCODE: + continue with self.subTest(opname=name): - if code < dis.HAVE_ARGUMENT: + if code not in has_arg: common = stack_effect(code) jump = stack_effect(code, jump=True) nojump = stack_effect(code, jump=False) @@ -57,7 +60,7 @@ class OpcodeTests(unittest.TestCase): common = stack_effect(code, 0) jump = stack_effect(code, 0, jump=True) nojump = stack_effect(code, 0, jump=False) - if code in has_jump: + if code in has_jump or code in has_exc: self.assertEqual(common, max(jump, nojump)) else: self.assertEqual(jump, common) @@ -66,12 +69,12 @@ class OpcodeTests(unittest.TestCase): class SpecializationStatsTests(unittest.TestCase): def test_specialization_stats(self): - stat_names = opcode._specialization_stats - + stat_names = ["success", "failure", "hit", "deferred", "miss", "deopt"] specialized_opcodes = [ - op[:-len("_ADAPTIVE")].lower() for - op in opcode._specialized_instructions - if op.endswith("_ADAPTIVE")] + op.lower() + for op in opcode._specializations + if opcode._inline_cache_entries[opcode.opmap[op]] + ] self.assertIn('load_attr', specialized_opcodes) self.assertIn('binary_subscr', specialized_opcodes) diff --git a/Lib/test/test__xxinterpchannels.py b/Lib/test/test__xxinterpchannels.py new file mode 100644 index 00000000..750cd99b --- /dev/null +++ b/Lib/test/test__xxinterpchannels.py @@ -0,0 +1,1558 @@ +from collections import namedtuple +import contextlib +import sys +from textwrap import dedent +import threading +import time +import unittest + +from test.support import import_helper + +from test.test__xxsubinterpreters import ( + interpreters, + _run_output, + clean_up_interpreters, +) + + +channels = import_helper.import_module('_xxinterpchannels') + + +################################## +# helpers + +#@contextmanager +#def run_threaded(id, source, **shared): +# def run(): +# run_interp(id, source, **shared) +# t = threading.Thread(target=run) +# t.start() +# yield +# t.join() + + +def run_interp(id, source, **shared): + _run_interp(id, source, shared) + + +def _run_interp(id, source, shared, _mainns={}): + source = dedent(source) + main = interpreters.get_main() + if main == id: + if interpreters.get_current() != main: + raise RuntimeError + # XXX Run a func? + exec(source, _mainns) + else: + interpreters.run_string(id, source, shared) + + +class Interpreter(namedtuple('Interpreter', 'name id')): + + @classmethod + def from_raw(cls, raw): + if isinstance(raw, cls): + return raw + elif isinstance(raw, str): + return cls(raw) + else: + raise NotImplementedError + + def __new__(cls, name=None, id=None): + main = interpreters.get_main() + if id == main: + if not name: + name = 'main' + elif name != 'main': + raise ValueError( + 'name mismatch (expected "main", got "{}")'.format(name)) + id = main + elif id is not None: + if not name: + name = 'interp' + elif name == 'main': + raise ValueError('name mismatch (unexpected "main")') + if not isinstance(id, interpreters.InterpreterID): + id = interpreters.InterpreterID(id) + elif not name or name == 'main': + name = 'main' + id = main + else: + id = interpreters.create() + self = super().__new__(cls, name, id) + return self + + +# XXX expect_channel_closed() is unnecessary once we improve exc propagation. + +@contextlib.contextmanager +def expect_channel_closed(): + try: + yield + except channels.ChannelClosedError: + pass + else: + assert False, 'channel not closed' + + +class ChannelAction(namedtuple('ChannelAction', 'action end interp')): + + def __new__(cls, action, end=None, interp=None): + if not end: + end = 'both' + if not interp: + interp = 'main' + self = super().__new__(cls, action, end, interp) + return self + + def __init__(self, *args, **kwargs): + if self.action == 'use': + if self.end not in ('same', 'opposite', 'send', 'recv'): + raise ValueError(self.end) + elif self.action in ('close', 'force-close'): + if self.end not in ('both', 'same', 'opposite', 'send', 'recv'): + raise ValueError(self.end) + else: + raise ValueError(self.action) + if self.interp not in ('main', 'same', 'other', 'extra'): + raise ValueError(self.interp) + + def resolve_end(self, end): + if self.end == 'same': + return end + elif self.end == 'opposite': + return 'recv' if end == 'send' else 'send' + else: + return self.end + + def resolve_interp(self, interp, other, extra): + if self.interp == 'same': + return interp + elif self.interp == 'other': + if other is None: + raise RuntimeError + return other + elif self.interp == 'extra': + if extra is None: + raise RuntimeError + return extra + elif self.interp == 'main': + if interp.name == 'main': + return interp + elif other and other.name == 'main': + return other + else: + raise RuntimeError + # Per __init__(), there aren't any others. + + +class ChannelState(namedtuple('ChannelState', 'pending closed')): + + def __new__(cls, pending=0, *, closed=False): + self = super().__new__(cls, pending, closed) + return self + + def incr(self): + return type(self)(self.pending + 1, closed=self.closed) + + def decr(self): + return type(self)(self.pending - 1, closed=self.closed) + + def close(self, *, force=True): + if self.closed: + if not force or self.pending == 0: + return self + return type(self)(0 if force else self.pending, closed=True) + + +def run_action(cid, action, end, state, *, hideclosed=True): + if state.closed: + if action == 'use' and end == 'recv' and state.pending: + expectfail = False + else: + expectfail = True + else: + expectfail = False + + try: + result = _run_action(cid, action, end, state) + except channels.ChannelClosedError: + if not hideclosed and not expectfail: + raise + result = state.close() + else: + if expectfail: + raise ... # XXX + return result + + +def _run_action(cid, action, end, state): + if action == 'use': + if end == 'send': + channels.send(cid, b'spam') + return state.incr() + elif end == 'recv': + if not state.pending: + try: + channels.recv(cid) + except channels.ChannelEmptyError: + return state + else: + raise Exception('expected ChannelEmptyError') + else: + channels.recv(cid) + return state.decr() + else: + raise ValueError(end) + elif action == 'close': + kwargs = {} + if end in ('recv', 'send'): + kwargs[end] = True + channels.close(cid, **kwargs) + return state.close() + elif action == 'force-close': + kwargs = { + 'force': True, + } + if end in ('recv', 'send'): + kwargs[end] = True + channels.close(cid, **kwargs) + return state.close(force=True) + else: + raise ValueError(action) + + +def clean_up_channels(): + for cid in channels.list_all(): + try: + channels.destroy(cid) + except channels.ChannelNotFoundError: + pass # already destroyed + + +class TestBase(unittest.TestCase): + + def tearDown(self): + clean_up_channels() + clean_up_interpreters() + + +################################## +# channel tests + +class ChannelIDTests(TestBase): + + def test_default_kwargs(self): + cid = channels._channel_id(10, force=True) + + self.assertEqual(int(cid), 10) + self.assertEqual(cid.end, 'both') + + def test_with_kwargs(self): + cid = channels._channel_id(10, send=True, force=True) + self.assertEqual(cid.end, 'send') + + cid = channels._channel_id(10, send=True, recv=False, force=True) + self.assertEqual(cid.end, 'send') + + cid = channels._channel_id(10, recv=True, force=True) + self.assertEqual(cid.end, 'recv') + + cid = channels._channel_id(10, recv=True, send=False, force=True) + self.assertEqual(cid.end, 'recv') + + cid = channels._channel_id(10, send=True, recv=True, force=True) + self.assertEqual(cid.end, 'both') + + def test_coerce_id(self): + class Int(str): + def __index__(self): + return 10 + + cid = channels._channel_id(Int(), force=True) + self.assertEqual(int(cid), 10) + + def test_bad_id(self): + self.assertRaises(TypeError, channels._channel_id, object()) + self.assertRaises(TypeError, channels._channel_id, 10.0) + self.assertRaises(TypeError, channels._channel_id, '10') + self.assertRaises(TypeError, channels._channel_id, b'10') + self.assertRaises(ValueError, channels._channel_id, -1) + self.assertRaises(OverflowError, channels._channel_id, 2**64) + + def test_bad_kwargs(self): + with self.assertRaises(ValueError): + channels._channel_id(10, send=False, recv=False) + + def test_does_not_exist(self): + cid = channels.create() + with self.assertRaises(channels.ChannelNotFoundError): + channels._channel_id(int(cid) + 1) # unforced + + def test_str(self): + cid = channels._channel_id(10, force=True) + self.assertEqual(str(cid), '10') + + def test_repr(self): + cid = channels._channel_id(10, force=True) + self.assertEqual(repr(cid), 'ChannelID(10)') + + cid = channels._channel_id(10, send=True, force=True) + self.assertEqual(repr(cid), 'ChannelID(10, send=True)') + + cid = channels._channel_id(10, recv=True, force=True) + self.assertEqual(repr(cid), 'ChannelID(10, recv=True)') + + cid = channels._channel_id(10, send=True, recv=True, force=True) + self.assertEqual(repr(cid), 'ChannelID(10)') + + def test_equality(self): + cid1 = channels.create() + cid2 = channels._channel_id(int(cid1)) + cid3 = channels.create() + + self.assertTrue(cid1 == cid1) + self.assertTrue(cid1 == cid2) + self.assertTrue(cid1 == int(cid1)) + self.assertTrue(int(cid1) == cid1) + self.assertTrue(cid1 == float(int(cid1))) + self.assertTrue(float(int(cid1)) == cid1) + self.assertFalse(cid1 == float(int(cid1)) + 0.1) + self.assertFalse(cid1 == str(int(cid1))) + self.assertFalse(cid1 == 2**1000) + self.assertFalse(cid1 == float('inf')) + self.assertFalse(cid1 == 'spam') + self.assertFalse(cid1 == cid3) + + self.assertFalse(cid1 != cid1) + self.assertFalse(cid1 != cid2) + self.assertTrue(cid1 != cid3) + + def test_shareable(self): + chan = channels.create() + + obj = channels.create() + channels.send(chan, obj) + got = channels.recv(chan) + + self.assertEqual(got, obj) + self.assertIs(type(got), type(obj)) + # XXX Check the following in the channel tests? + #self.assertIsNot(got, obj) + + +class ChannelTests(TestBase): + + def test_create_cid(self): + cid = channels.create() + self.assertIsInstance(cid, channels.ChannelID) + + def test_sequential_ids(self): + before = channels.list_all() + id1 = channels.create() + id2 = channels.create() + id3 = channels.create() + after = channels.list_all() + + self.assertEqual(id2, int(id1) + 1) + self.assertEqual(id3, int(id2) + 1) + self.assertEqual(set(after) - set(before), {id1, id2, id3}) + + def test_ids_global(self): + id1 = interpreters.create() + out = _run_output(id1, dedent(""" + import _xxinterpchannels as _channels + cid = _channels.create() + print(cid) + """)) + cid1 = int(out.strip()) + + id2 = interpreters.create() + out = _run_output(id2, dedent(""" + import _xxinterpchannels as _channels + cid = _channels.create() + print(cid) + """)) + cid2 = int(out.strip()) + + self.assertEqual(cid2, int(cid1) + 1) + + def test_channel_list_interpreters_none(self): + """Test listing interpreters for a channel with no associations.""" + # Test for channel with no associated interpreters. + cid = channels.create() + send_interps = channels.list_interpreters(cid, send=True) + recv_interps = channels.list_interpreters(cid, send=False) + self.assertEqual(send_interps, []) + self.assertEqual(recv_interps, []) + + def test_channel_list_interpreters_basic(self): + """Test basic listing channel interpreters.""" + interp0 = interpreters.get_main() + cid = channels.create() + channels.send(cid, "send") + # Test for a channel that has one end associated to an interpreter. + send_interps = channels.list_interpreters(cid, send=True) + recv_interps = channels.list_interpreters(cid, send=False) + self.assertEqual(send_interps, [interp0]) + self.assertEqual(recv_interps, []) + + interp1 = interpreters.create() + _run_output(interp1, dedent(f""" + import _xxinterpchannels as _channels + obj = _channels.recv({cid}) + """)) + # Test for channel that has both ends associated to an interpreter. + send_interps = channels.list_interpreters(cid, send=True) + recv_interps = channels.list_interpreters(cid, send=False) + self.assertEqual(send_interps, [interp0]) + self.assertEqual(recv_interps, [interp1]) + + def test_channel_list_interpreters_multiple(self): + """Test listing interpreters for a channel with many associations.""" + interp0 = interpreters.get_main() + interp1 = interpreters.create() + interp2 = interpreters.create() + interp3 = interpreters.create() + cid = channels.create() + + channels.send(cid, "send") + _run_output(interp1, dedent(f""" + import _xxinterpchannels as _channels + _channels.send({cid}, "send") + """)) + _run_output(interp2, dedent(f""" + import _xxinterpchannels as _channels + obj = _channels.recv({cid}) + """)) + _run_output(interp3, dedent(f""" + import _xxinterpchannels as _channels + obj = _channels.recv({cid}) + """)) + send_interps = channels.list_interpreters(cid, send=True) + recv_interps = channels.list_interpreters(cid, send=False) + self.assertEqual(set(send_interps), {interp0, interp1}) + self.assertEqual(set(recv_interps), {interp2, interp3}) + + def test_channel_list_interpreters_destroyed(self): + """Test listing channel interpreters with a destroyed interpreter.""" + interp0 = interpreters.get_main() + interp1 = interpreters.create() + cid = channels.create() + channels.send(cid, "send") + _run_output(interp1, dedent(f""" + import _xxinterpchannels as _channels + obj = _channels.recv({cid}) + """)) + # Should be one interpreter associated with each end. + send_interps = channels.list_interpreters(cid, send=True) + recv_interps = channels.list_interpreters(cid, send=False) + self.assertEqual(send_interps, [interp0]) + self.assertEqual(recv_interps, [interp1]) + + interpreters.destroy(interp1) + # Destroyed interpreter should not be listed. + send_interps = channels.list_interpreters(cid, send=True) + recv_interps = channels.list_interpreters(cid, send=False) + self.assertEqual(send_interps, [interp0]) + self.assertEqual(recv_interps, []) + + def test_channel_list_interpreters_released(self): + """Test listing channel interpreters with a released channel.""" + # Set up one channel with main interpreter on the send end and two + # subinterpreters on the receive end. + interp0 = interpreters.get_main() + interp1 = interpreters.create() + interp2 = interpreters.create() + cid = channels.create() + channels.send(cid, "data") + _run_output(interp1, dedent(f""" + import _xxinterpchannels as _channels + obj = _channels.recv({cid}) + """)) + channels.send(cid, "data") + _run_output(interp2, dedent(f""" + import _xxinterpchannels as _channels + obj = _channels.recv({cid}) + """)) + # Check the setup. + send_interps = channels.list_interpreters(cid, send=True) + recv_interps = channels.list_interpreters(cid, send=False) + self.assertEqual(len(send_interps), 1) + self.assertEqual(len(recv_interps), 2) + + # Release the main interpreter from the send end. + channels.release(cid, send=True) + # Send end should have no associated interpreters. + send_interps = channels.list_interpreters(cid, send=True) + recv_interps = channels.list_interpreters(cid, send=False) + self.assertEqual(len(send_interps), 0) + self.assertEqual(len(recv_interps), 2) + + # Release one of the subinterpreters from the receive end. + _run_output(interp2, dedent(f""" + import _xxinterpchannels as _channels + _channels.release({cid}) + """)) + # Receive end should have the released interpreter removed. + send_interps = channels.list_interpreters(cid, send=True) + recv_interps = channels.list_interpreters(cid, send=False) + self.assertEqual(len(send_interps), 0) + self.assertEqual(recv_interps, [interp1]) + + def test_channel_list_interpreters_closed(self): + """Test listing channel interpreters with a closed channel.""" + interp0 = interpreters.get_main() + interp1 = interpreters.create() + cid = channels.create() + # Put something in the channel so that it's not empty. + channels.send(cid, "send") + + # Check initial state. + send_interps = channels.list_interpreters(cid, send=True) + recv_interps = channels.list_interpreters(cid, send=False) + self.assertEqual(len(send_interps), 1) + self.assertEqual(len(recv_interps), 0) + + # Force close the channel. + channels.close(cid, force=True) + # Both ends should raise an error. + with self.assertRaises(channels.ChannelClosedError): + channels.list_interpreters(cid, send=True) + with self.assertRaises(channels.ChannelClosedError): + channels.list_interpreters(cid, send=False) + + def test_channel_list_interpreters_closed_send_end(self): + """Test listing channel interpreters with a channel's send end closed.""" + interp0 = interpreters.get_main() + interp1 = interpreters.create() + cid = channels.create() + # Put something in the channel so that it's not empty. + channels.send(cid, "send") + + # Check initial state. + send_interps = channels.list_interpreters(cid, send=True) + recv_interps = channels.list_interpreters(cid, send=False) + self.assertEqual(len(send_interps), 1) + self.assertEqual(len(recv_interps), 0) + + # Close the send end of the channel. + channels.close(cid, send=True) + # Send end should raise an error. + with self.assertRaises(channels.ChannelClosedError): + channels.list_interpreters(cid, send=True) + # Receive end should not be closed (since channel is not empty). + recv_interps = channels.list_interpreters(cid, send=False) + self.assertEqual(len(recv_interps), 0) + + # Close the receive end of the channel from a subinterpreter. + _run_output(interp1, dedent(f""" + import _xxinterpchannels as _channels + _channels.close({cid}, force=True) + """)) + return + # Both ends should raise an error. + with self.assertRaises(channels.ChannelClosedError): + channels.list_interpreters(cid, send=True) + with self.assertRaises(channels.ChannelClosedError): + channels.list_interpreters(cid, send=False) + + #################### + + def test_send_recv_main(self): + cid = channels.create() + orig = b'spam' + channels.send(cid, orig) + obj = channels.recv(cid) + + self.assertEqual(obj, orig) + self.assertIsNot(obj, orig) + + def test_send_recv_same_interpreter(self): + id1 = interpreters.create() + out = _run_output(id1, dedent(""" + import _xxinterpchannels as _channels + cid = _channels.create() + orig = b'spam' + _channels.send(cid, orig) + obj = _channels.recv(cid) + assert obj is not orig + assert obj == orig + """)) + + def test_send_recv_different_interpreters(self): + cid = channels.create() + id1 = interpreters.create() + out = _run_output(id1, dedent(f""" + import _xxinterpchannels as _channels + _channels.send({cid}, b'spam') + """)) + obj = channels.recv(cid) + + self.assertEqual(obj, b'spam') + + def test_send_recv_different_threads(self): + cid = channels.create() + + def f(): + while True: + try: + obj = channels.recv(cid) + break + except channels.ChannelEmptyError: + time.sleep(0.1) + channels.send(cid, obj) + t = threading.Thread(target=f) + t.start() + + channels.send(cid, b'spam') + t.join() + obj = channels.recv(cid) + + self.assertEqual(obj, b'spam') + + def test_send_recv_different_interpreters_and_threads(self): + cid = channels.create() + id1 = interpreters.create() + out = None + + def f(): + nonlocal out + out = _run_output(id1, dedent(f""" + import time + import _xxinterpchannels as _channels + while True: + try: + obj = _channels.recv({cid}) + break + except _channels.ChannelEmptyError: + time.sleep(0.1) + assert(obj == b'spam') + _channels.send({cid}, b'eggs') + """)) + t = threading.Thread(target=f) + t.start() + + channels.send(cid, b'spam') + t.join() + obj = channels.recv(cid) + + self.assertEqual(obj, b'eggs') + + def test_send_not_found(self): + with self.assertRaises(channels.ChannelNotFoundError): + channels.send(10, b'spam') + + def test_recv_not_found(self): + with self.assertRaises(channels.ChannelNotFoundError): + channels.recv(10) + + def test_recv_empty(self): + cid = channels.create() + with self.assertRaises(channels.ChannelEmptyError): + channels.recv(cid) + + def test_recv_default(self): + default = object() + cid = channels.create() + obj1 = channels.recv(cid, default) + channels.send(cid, None) + channels.send(cid, 1) + channels.send(cid, b'spam') + channels.send(cid, b'eggs') + obj2 = channels.recv(cid, default) + obj3 = channels.recv(cid, default) + obj4 = channels.recv(cid) + obj5 = channels.recv(cid, default) + obj6 = channels.recv(cid, default) + + self.assertIs(obj1, default) + self.assertIs(obj2, None) + self.assertEqual(obj3, 1) + self.assertEqual(obj4, b'spam') + self.assertEqual(obj5, b'eggs') + self.assertIs(obj6, default) + + def test_recv_sending_interp_destroyed(self): + with self.subTest('closed'): + cid1 = channels.create() + interp = interpreters.create() + interpreters.run_string(interp, dedent(f""" + import _xxinterpchannels as _channels + _channels.send({cid1}, b'spam') + """)) + interpreters.destroy(interp) + + with self.assertRaisesRegex(RuntimeError, + f'channel {cid1} is closed'): + channels.recv(cid1) + del cid1 + with self.subTest('still open'): + cid2 = channels.create() + interp = interpreters.create() + interpreters.run_string(interp, dedent(f""" + import _xxinterpchannels as _channels + _channels.send({cid2}, b'spam') + """)) + channels.send(cid2, b'eggs') + interpreters.destroy(interp) + + channels.recv(cid2) + with self.assertRaisesRegex(RuntimeError, + f'channel {cid2} is empty'): + channels.recv(cid2) + del cid2 + + def test_allowed_types(self): + cid = channels.create() + objects = [ + None, + 'spam', + b'spam', + 42, + ] + for obj in objects: + with self.subTest(obj): + channels.send(cid, obj) + got = channels.recv(cid) + + self.assertEqual(got, obj) + self.assertIs(type(got), type(obj)) + # XXX Check the following? + #self.assertIsNot(got, obj) + # XXX What about between interpreters? + + def test_run_string_arg_unresolved(self): + cid = channels.create() + interp = interpreters.create() + + out = _run_output(interp, dedent(""" + import _xxinterpchannels as _channels + print(cid.end) + _channels.send(cid, b'spam') + """), + dict(cid=cid.send)) + obj = channels.recv(cid) + + self.assertEqual(obj, b'spam') + self.assertEqual(out.strip(), 'send') + + # XXX For now there is no high-level channel into which the + # sent channel ID can be converted... + # Note: this test caused crashes on some buildbots (bpo-33615). + @unittest.skip('disabled until high-level channels exist') + def test_run_string_arg_resolved(self): + cid = channels.create() + cid = channels._channel_id(cid, _resolve=True) + interp = interpreters.create() + + out = _run_output(interp, dedent(""" + import _xxinterpchannels as _channels + print(chan.id.end) + _channels.send(chan.id, b'spam') + """), + dict(chan=cid.send)) + obj = channels.recv(cid) + + self.assertEqual(obj, b'spam') + self.assertEqual(out.strip(), 'send') + + # close + + def test_close_single_user(self): + cid = channels.create() + channels.send(cid, b'spam') + channels.recv(cid) + channels.close(cid) + + with self.assertRaises(channels.ChannelClosedError): + channels.send(cid, b'eggs') + with self.assertRaises(channels.ChannelClosedError): + channels.recv(cid) + + def test_close_multiple_users(self): + cid = channels.create() + id1 = interpreters.create() + id2 = interpreters.create() + interpreters.run_string(id1, dedent(f""" + import _xxinterpchannels as _channels + _channels.send({cid}, b'spam') + """)) + interpreters.run_string(id2, dedent(f""" + import _xxinterpchannels as _channels + _channels.recv({cid}) + """)) + channels.close(cid) + with self.assertRaises(interpreters.RunFailedError) as cm: + interpreters.run_string(id1, dedent(f""" + _channels.send({cid}, b'spam') + """)) + self.assertIn('ChannelClosedError', str(cm.exception)) + with self.assertRaises(interpreters.RunFailedError) as cm: + interpreters.run_string(id2, dedent(f""" + _channels.send({cid}, b'spam') + """)) + self.assertIn('ChannelClosedError', str(cm.exception)) + + def test_close_multiple_times(self): + cid = channels.create() + channels.send(cid, b'spam') + channels.recv(cid) + channels.close(cid) + + with self.assertRaises(channels.ChannelClosedError): + channels.close(cid) + + def test_close_empty(self): + tests = [ + (False, False), + (True, False), + (False, True), + (True, True), + ] + for send, recv in tests: + with self.subTest((send, recv)): + cid = channels.create() + channels.send(cid, b'spam') + channels.recv(cid) + channels.close(cid, send=send, recv=recv) + + with self.assertRaises(channels.ChannelClosedError): + channels.send(cid, b'eggs') + with self.assertRaises(channels.ChannelClosedError): + channels.recv(cid) + + def test_close_defaults_with_unused_items(self): + cid = channels.create() + channels.send(cid, b'spam') + channels.send(cid, b'ham') + + with self.assertRaises(channels.ChannelNotEmptyError): + channels.close(cid) + channels.recv(cid) + channels.send(cid, b'eggs') + + def test_close_recv_with_unused_items_unforced(self): + cid = channels.create() + channels.send(cid, b'spam') + channels.send(cid, b'ham') + + with self.assertRaises(channels.ChannelNotEmptyError): + channels.close(cid, recv=True) + channels.recv(cid) + channels.send(cid, b'eggs') + channels.recv(cid) + channels.recv(cid) + channels.close(cid, recv=True) + + def test_close_send_with_unused_items_unforced(self): + cid = channels.create() + channels.send(cid, b'spam') + channels.send(cid, b'ham') + channels.close(cid, send=True) + + with self.assertRaises(channels.ChannelClosedError): + channels.send(cid, b'eggs') + channels.recv(cid) + channels.recv(cid) + with self.assertRaises(channels.ChannelClosedError): + channels.recv(cid) + + def test_close_both_with_unused_items_unforced(self): + cid = channels.create() + channels.send(cid, b'spam') + channels.send(cid, b'ham') + + with self.assertRaises(channels.ChannelNotEmptyError): + channels.close(cid, recv=True, send=True) + channels.recv(cid) + channels.send(cid, b'eggs') + channels.recv(cid) + channels.recv(cid) + channels.close(cid, recv=True) + + def test_close_recv_with_unused_items_forced(self): + cid = channels.create() + channels.send(cid, b'spam') + channels.send(cid, b'ham') + channels.close(cid, recv=True, force=True) + + with self.assertRaises(channels.ChannelClosedError): + channels.send(cid, b'eggs') + with self.assertRaises(channels.ChannelClosedError): + channels.recv(cid) + + def test_close_send_with_unused_items_forced(self): + cid = channels.create() + channels.send(cid, b'spam') + channels.send(cid, b'ham') + channels.close(cid, send=True, force=True) + + with self.assertRaises(channels.ChannelClosedError): + channels.send(cid, b'eggs') + with self.assertRaises(channels.ChannelClosedError): + channels.recv(cid) + + def test_close_both_with_unused_items_forced(self): + cid = channels.create() + channels.send(cid, b'spam') + channels.send(cid, b'ham') + channels.close(cid, send=True, recv=True, force=True) + + with self.assertRaises(channels.ChannelClosedError): + channels.send(cid, b'eggs') + with self.assertRaises(channels.ChannelClosedError): + channels.recv(cid) + + def test_close_never_used(self): + cid = channels.create() + channels.close(cid) + + with self.assertRaises(channels.ChannelClosedError): + channels.send(cid, b'spam') + with self.assertRaises(channels.ChannelClosedError): + channels.recv(cid) + + def test_close_by_unassociated_interp(self): + cid = channels.create() + channels.send(cid, b'spam') + interp = interpreters.create() + interpreters.run_string(interp, dedent(f""" + import _xxinterpchannels as _channels + _channels.close({cid}, force=True) + """)) + with self.assertRaises(channels.ChannelClosedError): + channels.recv(cid) + with self.assertRaises(channels.ChannelClosedError): + channels.close(cid) + + def test_close_used_multiple_times_by_single_user(self): + cid = channels.create() + channels.send(cid, b'spam') + channels.send(cid, b'spam') + channels.send(cid, b'spam') + channels.recv(cid) + channels.close(cid, force=True) + + with self.assertRaises(channels.ChannelClosedError): + channels.send(cid, b'eggs') + with self.assertRaises(channels.ChannelClosedError): + channels.recv(cid) + + def test_channel_list_interpreters_invalid_channel(self): + cid = channels.create() + # Test for invalid channel ID. + with self.assertRaises(channels.ChannelNotFoundError): + channels.list_interpreters(1000, send=True) + + channels.close(cid) + # Test for a channel that has been closed. + with self.assertRaises(channels.ChannelClosedError): + channels.list_interpreters(cid, send=True) + + def test_channel_list_interpreters_invalid_args(self): + # Tests for invalid arguments passed to the API. + cid = channels.create() + with self.assertRaises(TypeError): + channels.list_interpreters(cid) + + +class ChannelReleaseTests(TestBase): + + # XXX Add more test coverage a la the tests for close(). + + """ + - main / interp / other + - run in: current thread / new thread / other thread / different threads + - end / opposite + - force / no force + - used / not used (associated / not associated) + - empty / emptied / never emptied / partly emptied + - closed / not closed + - released / not released + - creator (interp) / other + - associated interpreter not running + - associated interpreter destroyed + """ + + """ + use + pre-release + release + after + check + """ + + """ + release in: main, interp1 + creator: same, other (incl. interp2) + + use: None,send,recv,send/recv in None,same,other(incl. interp2),same+other(incl. interp2),all + pre-release: None,send,recv,both in None,same,other(incl. interp2),same+other(incl. interp2),all + pre-release forced: None,send,recv,both in None,same,other(incl. interp2),same+other(incl. interp2),all + + release: same + release forced: same + + use after: None,send,recv,send/recv in None,same,other(incl. interp2),same+other(incl. interp2),all + release after: None,send,recv,send/recv in None,same,other(incl. interp2),same+other(incl. interp2),all + check released: send/recv for same/other(incl. interp2) + check closed: send/recv for same/other(incl. interp2) + """ + + def test_single_user(self): + cid = channels.create() + channels.send(cid, b'spam') + channels.recv(cid) + channels.release(cid, send=True, recv=True) + + with self.assertRaises(channels.ChannelClosedError): + channels.send(cid, b'eggs') + with self.assertRaises(channels.ChannelClosedError): + channels.recv(cid) + + def test_multiple_users(self): + cid = channels.create() + id1 = interpreters.create() + id2 = interpreters.create() + interpreters.run_string(id1, dedent(f""" + import _xxinterpchannels as _channels + _channels.send({cid}, b'spam') + """)) + out = _run_output(id2, dedent(f""" + import _xxinterpchannels as _channels + obj = _channels.recv({cid}) + _channels.release({cid}) + print(repr(obj)) + """)) + interpreters.run_string(id1, dedent(f""" + _channels.release({cid}) + """)) + + self.assertEqual(out.strip(), "b'spam'") + + def test_no_kwargs(self): + cid = channels.create() + channels.send(cid, b'spam') + channels.recv(cid) + channels.release(cid) + + with self.assertRaises(channels.ChannelClosedError): + channels.send(cid, b'eggs') + with self.assertRaises(channels.ChannelClosedError): + channels.recv(cid) + + def test_multiple_times(self): + cid = channels.create() + channels.send(cid, b'spam') + channels.recv(cid) + channels.release(cid, send=True, recv=True) + + with self.assertRaises(channels.ChannelClosedError): + channels.release(cid, send=True, recv=True) + + def test_with_unused_items(self): + cid = channels.create() + channels.send(cid, b'spam') + channels.send(cid, b'ham') + channels.release(cid, send=True, recv=True) + + with self.assertRaises(channels.ChannelClosedError): + channels.recv(cid) + + def test_never_used(self): + cid = channels.create() + channels.release(cid) + + with self.assertRaises(channels.ChannelClosedError): + channels.send(cid, b'spam') + with self.assertRaises(channels.ChannelClosedError): + channels.recv(cid) + + def test_by_unassociated_interp(self): + cid = channels.create() + channels.send(cid, b'spam') + interp = interpreters.create() + interpreters.run_string(interp, dedent(f""" + import _xxinterpchannels as _channels + _channels.release({cid}) + """)) + obj = channels.recv(cid) + channels.release(cid) + + with self.assertRaises(channels.ChannelClosedError): + channels.send(cid, b'eggs') + self.assertEqual(obj, b'spam') + + def test_close_if_unassociated(self): + # XXX Something's not right with this test... + cid = channels.create() + interp = interpreters.create() + interpreters.run_string(interp, dedent(f""" + import _xxinterpchannels as _channels + obj = _channels.send({cid}, b'spam') + _channels.release({cid}) + """)) + + with self.assertRaises(channels.ChannelClosedError): + channels.recv(cid) + + def test_partially(self): + # XXX Is partial close too weird/confusing? + cid = channels.create() + channels.send(cid, None) + channels.recv(cid) + channels.send(cid, b'spam') + channels.release(cid, send=True) + obj = channels.recv(cid) + + self.assertEqual(obj, b'spam') + + def test_used_multiple_times_by_single_user(self): + cid = channels.create() + channels.send(cid, b'spam') + channels.send(cid, b'spam') + channels.send(cid, b'spam') + channels.recv(cid) + channels.release(cid, send=True, recv=True) + + with self.assertRaises(channels.ChannelClosedError): + channels.send(cid, b'eggs') + with self.assertRaises(channels.ChannelClosedError): + channels.recv(cid) + + +class ChannelCloseFixture(namedtuple('ChannelCloseFixture', + 'end interp other extra creator')): + + # Set this to True to avoid creating interpreters, e.g. when + # scanning through test permutations without running them. + QUICK = False + + def __new__(cls, end, interp, other, extra, creator): + assert end in ('send', 'recv') + if cls.QUICK: + known = {} + else: + interp = Interpreter.from_raw(interp) + other = Interpreter.from_raw(other) + extra = Interpreter.from_raw(extra) + known = { + interp.name: interp, + other.name: other, + extra.name: extra, + } + if not creator: + creator = 'same' + self = super().__new__(cls, end, interp, other, extra, creator) + self._prepped = set() + self._state = ChannelState() + self._known = known + return self + + @property + def state(self): + return self._state + + @property + def cid(self): + try: + return self._cid + except AttributeError: + creator = self._get_interpreter(self.creator) + self._cid = self._new_channel(creator) + return self._cid + + def get_interpreter(self, interp): + interp = self._get_interpreter(interp) + self._prep_interpreter(interp) + return interp + + def expect_closed_error(self, end=None): + if end is None: + end = self.end + if end == 'recv' and self.state.closed == 'send': + return False + return bool(self.state.closed) + + def prep_interpreter(self, interp): + self._prep_interpreter(interp) + + def record_action(self, action, result): + self._state = result + + def clean_up(self): + clean_up_interpreters() + clean_up_channels() + + # internal methods + + def _new_channel(self, creator): + if creator.name == 'main': + return channels.create() + else: + ch = channels.create() + run_interp(creator.id, f""" + import _xxsubinterpreters + cid = _xxsubchannels.create() + # We purposefully send back an int to avoid tying the + # channel to the other interpreter. + _xxsubchannels.send({ch}, int(cid)) + del _xxsubinterpreters + """) + self._cid = channels.recv(ch) + return self._cid + + def _get_interpreter(self, interp): + if interp in ('same', 'interp'): + return self.interp + elif interp == 'other': + return self.other + elif interp == 'extra': + return self.extra + else: + name = interp + try: + interp = self._known[name] + except KeyError: + interp = self._known[name] = Interpreter(name) + return interp + + def _prep_interpreter(self, interp): + if interp.id in self._prepped: + return + self._prepped.add(interp.id) + if interp.name == 'main': + return + run_interp(interp.id, f""" + import _xxinterpchannels as channels + import test.test__xxinterpchannels as helpers + ChannelState = helpers.ChannelState + try: + cid + except NameError: + cid = channels._channel_id({self.cid}) + """) + + +@unittest.skip('these tests take several hours to run') +class ExhaustiveChannelTests(TestBase): + + """ + - main / interp / other + - run in: current thread / new thread / other thread / different threads + - end / opposite + - force / no force + - used / not used (associated / not associated) + - empty / emptied / never emptied / partly emptied + - closed / not closed + - released / not released + - creator (interp) / other + - associated interpreter not running + - associated interpreter destroyed + + - close after unbound + """ + + """ + use + pre-close + close + after + check + """ + + """ + close in: main, interp1 + creator: same, other, extra + + use: None,send,recv,send/recv in None,same,other,same+other,all + pre-close: None,send,recv in None,same,other,same+other,all + pre-close forced: None,send,recv in None,same,other,same+other,all + + close: same + close forced: same + + use after: None,send,recv,send/recv in None,same,other,extra,same+other,all + close after: None,send,recv,send/recv in None,same,other,extra,same+other,all + check closed: send/recv for same/other(incl. interp2) + """ + + def iter_action_sets(self): + # - used / not used (associated / not associated) + # - empty / emptied / never emptied / partly emptied + # - closed / not closed + # - released / not released + + # never used + yield [] + + # only pre-closed (and possible used after) + for closeactions in self._iter_close_action_sets('same', 'other'): + yield closeactions + for postactions in self._iter_post_close_action_sets(): + yield closeactions + postactions + for closeactions in self._iter_close_action_sets('other', 'extra'): + yield closeactions + for postactions in self._iter_post_close_action_sets(): + yield closeactions + postactions + + # used + for useactions in self._iter_use_action_sets('same', 'other'): + yield useactions + for closeactions in self._iter_close_action_sets('same', 'other'): + actions = useactions + closeactions + yield actions + for postactions in self._iter_post_close_action_sets(): + yield actions + postactions + for closeactions in self._iter_close_action_sets('other', 'extra'): + actions = useactions + closeactions + yield actions + for postactions in self._iter_post_close_action_sets(): + yield actions + postactions + for useactions in self._iter_use_action_sets('other', 'extra'): + yield useactions + for closeactions in self._iter_close_action_sets('same', 'other'): + actions = useactions + closeactions + yield actions + for postactions in self._iter_post_close_action_sets(): + yield actions + postactions + for closeactions in self._iter_close_action_sets('other', 'extra'): + actions = useactions + closeactions + yield actions + for postactions in self._iter_post_close_action_sets(): + yield actions + postactions + + def _iter_use_action_sets(self, interp1, interp2): + interps = (interp1, interp2) + + # only recv end used + yield [ + ChannelAction('use', 'recv', interp1), + ] + yield [ + ChannelAction('use', 'recv', interp2), + ] + yield [ + ChannelAction('use', 'recv', interp1), + ChannelAction('use', 'recv', interp2), + ] + + # never emptied + yield [ + ChannelAction('use', 'send', interp1), + ] + yield [ + ChannelAction('use', 'send', interp2), + ] + yield [ + ChannelAction('use', 'send', interp1), + ChannelAction('use', 'send', interp2), + ] + + # partially emptied + for interp1 in interps: + for interp2 in interps: + for interp3 in interps: + yield [ + ChannelAction('use', 'send', interp1), + ChannelAction('use', 'send', interp2), + ChannelAction('use', 'recv', interp3), + ] + + # fully emptied + for interp1 in interps: + for interp2 in interps: + for interp3 in interps: + for interp4 in interps: + yield [ + ChannelAction('use', 'send', interp1), + ChannelAction('use', 'send', interp2), + ChannelAction('use', 'recv', interp3), + ChannelAction('use', 'recv', interp4), + ] + + def _iter_close_action_sets(self, interp1, interp2): + ends = ('recv', 'send') + interps = (interp1, interp2) + for force in (True, False): + op = 'force-close' if force else 'close' + for interp in interps: + for end in ends: + yield [ + ChannelAction(op, end, interp), + ] + for recvop in ('close', 'force-close'): + for sendop in ('close', 'force-close'): + for recv in interps: + for send in interps: + yield [ + ChannelAction(recvop, 'recv', recv), + ChannelAction(sendop, 'send', send), + ] + + def _iter_post_close_action_sets(self): + for interp in ('same', 'extra', 'other'): + yield [ + ChannelAction('use', 'recv', interp), + ] + yield [ + ChannelAction('use', 'send', interp), + ] + + def run_actions(self, fix, actions): + for action in actions: + self.run_action(fix, action) + + def run_action(self, fix, action, *, hideclosed=True): + end = action.resolve_end(fix.end) + interp = action.resolve_interp(fix.interp, fix.other, fix.extra) + fix.prep_interpreter(interp) + if interp.name == 'main': + result = run_action( + fix.cid, + action.action, + end, + fix.state, + hideclosed=hideclosed, + ) + fix.record_action(action, result) + else: + _cid = channels.create() + run_interp(interp.id, f""" + result = helpers.run_action( + {fix.cid}, + {repr(action.action)}, + {repr(end)}, + {repr(fix.state)}, + hideclosed={hideclosed}, + ) + channels.send({_cid}, result.pending.to_bytes(1, 'little')) + channels.send({_cid}, b'X' if result.closed else b'') + """) + result = ChannelState( + pending=int.from_bytes(channels.recv(_cid), 'little'), + closed=bool(channels.recv(_cid)), + ) + fix.record_action(action, result) + + def iter_fixtures(self): + # XXX threads? + interpreters = [ + ('main', 'interp', 'extra'), + ('interp', 'main', 'extra'), + ('interp1', 'interp2', 'extra'), + ('interp1', 'interp2', 'main'), + ] + for interp, other, extra in interpreters: + for creator in ('same', 'other', 'creator'): + for end in ('send', 'recv'): + yield ChannelCloseFixture(end, interp, other, extra, creator) + + def _close(self, fix, *, force): + op = 'force-close' if force else 'close' + close = ChannelAction(op, fix.end, 'same') + if not fix.expect_closed_error(): + self.run_action(fix, close, hideclosed=False) + else: + with self.assertRaises(channels.ChannelClosedError): + self.run_action(fix, close, hideclosed=False) + + def _assert_closed_in_interp(self, fix, interp=None): + if interp is None or interp.name == 'main': + with self.assertRaises(channels.ChannelClosedError): + channels.recv(fix.cid) + with self.assertRaises(channels.ChannelClosedError): + channels.send(fix.cid, b'spam') + with self.assertRaises(channels.ChannelClosedError): + channels.close(fix.cid) + with self.assertRaises(channels.ChannelClosedError): + channels.close(fix.cid, force=True) + else: + run_interp(interp.id, """ + with helpers.expect_channel_closed(): + channels.recv(cid) + """) + run_interp(interp.id, """ + with helpers.expect_channel_closed(): + channels.send(cid, b'spam') + """) + run_interp(interp.id, """ + with helpers.expect_channel_closed(): + channels.close(cid) + """) + run_interp(interp.id, """ + with helpers.expect_channel_closed(): + channels.close(cid, force=True) + """) + + def _assert_closed(self, fix): + self.assertTrue(fix.state.closed) + + for _ in range(fix.state.pending): + channels.recv(fix.cid) + self._assert_closed_in_interp(fix) + + for interp in ('same', 'other'): + interp = fix.get_interpreter(interp) + if interp.name == 'main': + continue + self._assert_closed_in_interp(fix, interp) + + interp = fix.get_interpreter('fresh') + self._assert_closed_in_interp(fix, interp) + + def _iter_close_tests(self, verbose=False): + i = 0 + for actions in self.iter_action_sets(): + print() + for fix in self.iter_fixtures(): + i += 1 + if i > 1000: + return + if verbose: + if (i - 1) % 6 == 0: + print() + print(i, fix, '({} actions)'.format(len(actions))) + else: + if (i - 1) % 6 == 0: + print(' ', end='') + print('.', end=''); sys.stdout.flush() + yield i, fix, actions + if verbose: + print('---') + print() + + # This is useful for scanning through the possible tests. + def _skim_close_tests(self): + ChannelCloseFixture.QUICK = True + for i, fix, actions in self._iter_close_tests(): + pass + + def test_close(self): + for i, fix, actions in self._iter_close_tests(): + with self.subTest('{} {} {}'.format(i, fix, actions)): + fix.prep_interpreter(fix.interp) + self.run_actions(fix, actions) + + self._close(fix, force=False) + + self._assert_closed(fix) + # XXX Things slow down if we have too many interpreters. + fix.clean_up() + + def test_force_close(self): + for i, fix, actions in self._iter_close_tests(): + with self.subTest('{} {} {}'.format(i, fix, actions)): + fix.prep_interpreter(fix.interp) + self.run_actions(fix, actions) + + self._close(fix, force=True) + + self._assert_closed(fix) + # XXX Things slow down if we have too many interpreters. + fix.clean_up() + + +if __name__ == '__main__': + unittest.main() diff --git a/Lib/test/test__xxsubinterpreters.py b/Lib/test/test__xxsubinterpreters.py index 5d0ed9ea..1ee18774 100644 --- a/Lib/test/test__xxsubinterpreters.py +++ b/Lib/test/test__xxsubinterpreters.py @@ -1,4 +1,3 @@ -from collections import namedtuple import contextlib import itertools import os @@ -6,9 +5,9 @@ import pickle import sys from textwrap import dedent import threading -import time import unittest +import _testcapi from test import support from test.support import import_helper from test.support import script_helper @@ -45,12 +44,11 @@ def _wait_for_interp_to_run(interp, timeout=None): # run subinterpreter eariler than the main thread in multiprocess. if timeout is None: timeout = support.SHORT_TIMEOUT - start_time = time.monotonic() - deadline = start_time + timeout - while not interpreters.is_running(interp): - if time.monotonic() > deadline: - raise RuntimeError('interp is not running') - time.sleep(0.010) + for _ in support.sleeping_retry(timeout, error=False): + if interpreters.is_running(interp): + break + else: + raise RuntimeError('interp is not running') @contextlib.contextmanager @@ -74,207 +72,6 @@ def _running(interp): t.join() -#@contextmanager -#def run_threaded(id, source, **shared): -# def run(): -# run_interp(id, source, **shared) -# t = threading.Thread(target=run) -# t.start() -# yield -# t.join() - - -def run_interp(id, source, **shared): - _run_interp(id, source, shared) - - -def _run_interp(id, source, shared, _mainns={}): - source = dedent(source) - main = interpreters.get_main() - if main == id: - if interpreters.get_current() != main: - raise RuntimeError - # XXX Run a func? - exec(source, _mainns) - else: - interpreters.run_string(id, source, shared) - - -class Interpreter(namedtuple('Interpreter', 'name id')): - - @classmethod - def from_raw(cls, raw): - if isinstance(raw, cls): - return raw - elif isinstance(raw, str): - return cls(raw) - else: - raise NotImplementedError - - def __new__(cls, name=None, id=None): - main = interpreters.get_main() - if id == main: - if not name: - name = 'main' - elif name != 'main': - raise ValueError( - 'name mismatch (expected "main", got "{}")'.format(name)) - id = main - elif id is not None: - if not name: - name = 'interp' - elif name == 'main': - raise ValueError('name mismatch (unexpected "main")') - if not isinstance(id, interpreters.InterpreterID): - id = interpreters.InterpreterID(id) - elif not name or name == 'main': - name = 'main' - id = main - else: - id = interpreters.create() - self = super().__new__(cls, name, id) - return self - - -# XXX expect_channel_closed() is unnecessary once we improve exc propagation. - -@contextlib.contextmanager -def expect_channel_closed(): - try: - yield - except interpreters.ChannelClosedError: - pass - else: - assert False, 'channel not closed' - - -class ChannelAction(namedtuple('ChannelAction', 'action end interp')): - - def __new__(cls, action, end=None, interp=None): - if not end: - end = 'both' - if not interp: - interp = 'main' - self = super().__new__(cls, action, end, interp) - return self - - def __init__(self, *args, **kwargs): - if self.action == 'use': - if self.end not in ('same', 'opposite', 'send', 'recv'): - raise ValueError(self.end) - elif self.action in ('close', 'force-close'): - if self.end not in ('both', 'same', 'opposite', 'send', 'recv'): - raise ValueError(self.end) - else: - raise ValueError(self.action) - if self.interp not in ('main', 'same', 'other', 'extra'): - raise ValueError(self.interp) - - def resolve_end(self, end): - if self.end == 'same': - return end - elif self.end == 'opposite': - return 'recv' if end == 'send' else 'send' - else: - return self.end - - def resolve_interp(self, interp, other, extra): - if self.interp == 'same': - return interp - elif self.interp == 'other': - if other is None: - raise RuntimeError - return other - elif self.interp == 'extra': - if extra is None: - raise RuntimeError - return extra - elif self.interp == 'main': - if interp.name == 'main': - return interp - elif other and other.name == 'main': - return other - else: - raise RuntimeError - # Per __init__(), there aren't any others. - - -class ChannelState(namedtuple('ChannelState', 'pending closed')): - - def __new__(cls, pending=0, *, closed=False): - self = super().__new__(cls, pending, closed) - return self - - def incr(self): - return type(self)(self.pending + 1, closed=self.closed) - - def decr(self): - return type(self)(self.pending - 1, closed=self.closed) - - def close(self, *, force=True): - if self.closed: - if not force or self.pending == 0: - return self - return type(self)(0 if force else self.pending, closed=True) - - -def run_action(cid, action, end, state, *, hideclosed=True): - if state.closed: - if action == 'use' and end == 'recv' and state.pending: - expectfail = False - else: - expectfail = True - else: - expectfail = False - - try: - result = _run_action(cid, action, end, state) - except interpreters.ChannelClosedError: - if not hideclosed and not expectfail: - raise - result = state.close() - else: - if expectfail: - raise ... # XXX - return result - - -def _run_action(cid, action, end, state): - if action == 'use': - if end == 'send': - interpreters.channel_send(cid, b'spam') - return state.incr() - elif end == 'recv': - if not state.pending: - try: - interpreters.channel_recv(cid) - except interpreters.ChannelEmptyError: - return state - else: - raise Exception('expected ChannelEmptyError') - else: - interpreters.channel_recv(cid) - return state.decr() - else: - raise ValueError(end) - elif action == 'close': - kwargs = {} - if end in ('recv', 'send'): - kwargs[end] = True - interpreters.channel_close(cid, **kwargs) - return state.close() - elif action == 'force-close': - kwargs = { - 'force': True, - } - if end in ('recv', 'send'): - kwargs[end] = True - interpreters.channel_close(cid, **kwargs) - return state.close(force=True) - else: - raise ValueError(action) - - def clean_up_interpreters(): for id in interpreters.list_all(): if id == 0: # main @@ -285,19 +82,10 @@ def clean_up_interpreters(): pass # already destroyed -def clean_up_channels(): - for cid in interpreters.channel_list_all(): - try: - interpreters.channel_destroy(cid) - except interpreters.ChannelNotFoundError: - pass # already destroyed - - class TestBase(unittest.TestCase): def tearDown(self): clean_up_interpreters() - clean_up_channels() ################################## @@ -355,30 +143,20 @@ class IsShareableTests(unittest.TestCase): class ShareableTypeTests(unittest.TestCase): - def setUp(self): - super().setUp() - self.cid = interpreters.channel_create() - - def tearDown(self): - interpreters.channel_destroy(self.cid) - super().tearDown() - def _assert_values(self, values): for obj in values: with self.subTest(obj): - interpreters.channel_send(self.cid, obj) - got = interpreters.channel_recv(self.cid) + xid = _testcapi.get_crossinterp_data(obj) + got = _testcapi.restore_crossinterp_data(xid) self.assertEqual(got, obj) self.assertIs(type(got), type(obj)) - # XXX Check the following in the channel tests? - #self.assertIsNot(got, obj) def test_singletons(self): for obj in [None]: with self.subTest(obj): - interpreters.channel_send(self.cid, obj) - got = interpreters.channel_recv(self.cid) + xid = _testcapi.get_crossinterp_data(obj) + got = _testcapi.restore_crossinterp_data(xid) # XXX What about between interpreters? self.assertIs(got, obj) @@ -387,7 +165,6 @@ class ShareableTypeTests(unittest.TestCase): self._assert_values([ b'spam', 9999, - self.cid, ]) def test_bytes(self): @@ -410,7 +187,16 @@ class ShareableTypeTests(unittest.TestCase): for i in ints: with self.subTest(i): with self.assertRaises(OverflowError): - interpreters.channel_send(self.cid, i) + _testcapi.get_crossinterp_data(i) + + +class ModuleTests(TestBase): + + def test_import_in_interpreter(self): + _run_output( + interpreters.create(), + 'import _xxsubinterpreters as _interpreters', + ) ################################## @@ -548,7 +334,7 @@ class InterpreterIDTests(TestBase): self.assertRaises(OverflowError, interpreters.InterpreterID, 2**64) def test_does_not_exist(self): - id = interpreters.channel_create() + id = interpreters.create() with self.assertRaises(RuntimeError): interpreters.InterpreterID(int(id) + 1) # unforced @@ -802,7 +588,7 @@ class RunStringTests(TestBase): self.assertEqual(out, 'it worked!') def test_create_thread(self): - subinterp = interpreters.create(isolated=False) + subinterp = interpreters.create() script, file = _captured_script(""" import threading def f(): @@ -818,6 +604,77 @@ class RunStringTests(TestBase): self.assertEqual(out, 'it worked!') + def test_create_daemon_thread(self): + with self.subTest('isolated'): + expected = 'spam spam spam spam spam' + subinterp = interpreters.create(isolated=True) + script, file = _captured_script(f""" + import threading + def f(): + print('it worked!', end='') + + try: + t = threading.Thread(target=f, daemon=True) + t.start() + t.join() + except RuntimeError: + print('{expected}', end='') + """) + with file: + interpreters.run_string(subinterp, script) + out = file.read() + + self.assertEqual(out, expected) + + with self.subTest('not isolated'): + subinterp = interpreters.create(isolated=False) + script, file = _captured_script(""" + import threading + def f(): + print('it worked!', end='') + + t = threading.Thread(target=f, daemon=True) + t.start() + t.join() + """) + with file: + interpreters.run_string(subinterp, script) + out = file.read() + + self.assertEqual(out, 'it worked!') + + def test_shareable_types(self): + interp = interpreters.create() + objects = [ + None, + 'spam', + b'spam', + 42, + ] + for obj in objects: + with self.subTest(obj): + interpreters.run_string( + interp, + f'assert(obj == {obj!r})', + shared=dict(obj=obj), + ) + + def test_os_exec(self): + expected = 'spam spam spam spam spam' + subinterp = interpreters.create() + script, file = _captured_script(f""" + import os, sys + try: + os.execl(sys.executable) + except RuntimeError: + print('{expected}', end='') + """) + with file: + interpreters.run_string(subinterp, script) + out = file.read() + + self.assertEqual(out, expected) + @support.requires_fork() def test_fork(self): import tempfile @@ -941,7 +798,7 @@ class RunStringTests(TestBase): """)) shared = {'spam': b'ham'} - script = dedent(f""" + script = dedent(""" ns2 = dict(vars()) del ns2['__builtins__'] """) @@ -1045,7 +902,7 @@ class RunStringTests(TestBase): # XXX Fix this test! @unittest.skip('blocking forever') def test_still_running_at_exit(self): - script = dedent(f""" + script = dedent(""" from textwrap import dedent import threading import _xxsubinterpreters as _interpreters @@ -1068,1260 +925,5 @@ class RunStringTests(TestBase): self.assertEqual(retcode, 0) -################################## -# channel tests - -class ChannelIDTests(TestBase): - - def test_default_kwargs(self): - cid = interpreters._channel_id(10, force=True) - - self.assertEqual(int(cid), 10) - self.assertEqual(cid.end, 'both') - - def test_with_kwargs(self): - cid = interpreters._channel_id(10, send=True, force=True) - self.assertEqual(cid.end, 'send') - - cid = interpreters._channel_id(10, send=True, recv=False, force=True) - self.assertEqual(cid.end, 'send') - - cid = interpreters._channel_id(10, recv=True, force=True) - self.assertEqual(cid.end, 'recv') - - cid = interpreters._channel_id(10, recv=True, send=False, force=True) - self.assertEqual(cid.end, 'recv') - - cid = interpreters._channel_id(10, send=True, recv=True, force=True) - self.assertEqual(cid.end, 'both') - - def test_coerce_id(self): - class Int(str): - def __index__(self): - return 10 - - cid = interpreters._channel_id(Int(), force=True) - self.assertEqual(int(cid), 10) - - def test_bad_id(self): - self.assertRaises(TypeError, interpreters._channel_id, object()) - self.assertRaises(TypeError, interpreters._channel_id, 10.0) - self.assertRaises(TypeError, interpreters._channel_id, '10') - self.assertRaises(TypeError, interpreters._channel_id, b'10') - self.assertRaises(ValueError, interpreters._channel_id, -1) - self.assertRaises(OverflowError, interpreters._channel_id, 2**64) - - def test_bad_kwargs(self): - with self.assertRaises(ValueError): - interpreters._channel_id(10, send=False, recv=False) - - def test_does_not_exist(self): - cid = interpreters.channel_create() - with self.assertRaises(interpreters.ChannelNotFoundError): - interpreters._channel_id(int(cid) + 1) # unforced - - def test_str(self): - cid = interpreters._channel_id(10, force=True) - self.assertEqual(str(cid), '10') - - def test_repr(self): - cid = interpreters._channel_id(10, force=True) - self.assertEqual(repr(cid), 'ChannelID(10)') - - cid = interpreters._channel_id(10, send=True, force=True) - self.assertEqual(repr(cid), 'ChannelID(10, send=True)') - - cid = interpreters._channel_id(10, recv=True, force=True) - self.assertEqual(repr(cid), 'ChannelID(10, recv=True)') - - cid = interpreters._channel_id(10, send=True, recv=True, force=True) - self.assertEqual(repr(cid), 'ChannelID(10)') - - def test_equality(self): - cid1 = interpreters.channel_create() - cid2 = interpreters._channel_id(int(cid1)) - cid3 = interpreters.channel_create() - - self.assertTrue(cid1 == cid1) - self.assertTrue(cid1 == cid2) - self.assertTrue(cid1 == int(cid1)) - self.assertTrue(int(cid1) == cid1) - self.assertTrue(cid1 == float(int(cid1))) - self.assertTrue(float(int(cid1)) == cid1) - self.assertFalse(cid1 == float(int(cid1)) + 0.1) - self.assertFalse(cid1 == str(int(cid1))) - self.assertFalse(cid1 == 2**1000) - self.assertFalse(cid1 == float('inf')) - self.assertFalse(cid1 == 'spam') - self.assertFalse(cid1 == cid3) - - self.assertFalse(cid1 != cid1) - self.assertFalse(cid1 != cid2) - self.assertTrue(cid1 != cid3) - - -class ChannelTests(TestBase): - - def test_create_cid(self): - cid = interpreters.channel_create() - self.assertIsInstance(cid, interpreters.ChannelID) - - def test_sequential_ids(self): - before = interpreters.channel_list_all() - id1 = interpreters.channel_create() - id2 = interpreters.channel_create() - id3 = interpreters.channel_create() - after = interpreters.channel_list_all() - - self.assertEqual(id2, int(id1) + 1) - self.assertEqual(id3, int(id2) + 1) - self.assertEqual(set(after) - set(before), {id1, id2, id3}) - - def test_ids_global(self): - id1 = interpreters.create() - out = _run_output(id1, dedent(""" - import _xxsubinterpreters as _interpreters - cid = _interpreters.channel_create() - print(cid) - """)) - cid1 = int(out.strip()) - - id2 = interpreters.create() - out = _run_output(id2, dedent(""" - import _xxsubinterpreters as _interpreters - cid = _interpreters.channel_create() - print(cid) - """)) - cid2 = int(out.strip()) - - self.assertEqual(cid2, int(cid1) + 1) - - def test_channel_list_interpreters_none(self): - """Test listing interpreters for a channel with no associations.""" - # Test for channel with no associated interpreters. - cid = interpreters.channel_create() - send_interps = interpreters.channel_list_interpreters(cid, send=True) - recv_interps = interpreters.channel_list_interpreters(cid, send=False) - self.assertEqual(send_interps, []) - self.assertEqual(recv_interps, []) - - def test_channel_list_interpreters_basic(self): - """Test basic listing channel interpreters.""" - interp0 = interpreters.get_main() - cid = interpreters.channel_create() - interpreters.channel_send(cid, "send") - # Test for a channel that has one end associated to an interpreter. - send_interps = interpreters.channel_list_interpreters(cid, send=True) - recv_interps = interpreters.channel_list_interpreters(cid, send=False) - self.assertEqual(send_interps, [interp0]) - self.assertEqual(recv_interps, []) - - interp1 = interpreters.create() - _run_output(interp1, dedent(f""" - import _xxsubinterpreters as _interpreters - obj = _interpreters.channel_recv({cid}) - """)) - # Test for channel that has both ends associated to an interpreter. - send_interps = interpreters.channel_list_interpreters(cid, send=True) - recv_interps = interpreters.channel_list_interpreters(cid, send=False) - self.assertEqual(send_interps, [interp0]) - self.assertEqual(recv_interps, [interp1]) - - def test_channel_list_interpreters_multiple(self): - """Test listing interpreters for a channel with many associations.""" - interp0 = interpreters.get_main() - interp1 = interpreters.create() - interp2 = interpreters.create() - interp3 = interpreters.create() - cid = interpreters.channel_create() - - interpreters.channel_send(cid, "send") - _run_output(interp1, dedent(f""" - import _xxsubinterpreters as _interpreters - _interpreters.channel_send({cid}, "send") - """)) - _run_output(interp2, dedent(f""" - import _xxsubinterpreters as _interpreters - obj = _interpreters.channel_recv({cid}) - """)) - _run_output(interp3, dedent(f""" - import _xxsubinterpreters as _interpreters - obj = _interpreters.channel_recv({cid}) - """)) - send_interps = interpreters.channel_list_interpreters(cid, send=True) - recv_interps = interpreters.channel_list_interpreters(cid, send=False) - self.assertEqual(set(send_interps), {interp0, interp1}) - self.assertEqual(set(recv_interps), {interp2, interp3}) - - def test_channel_list_interpreters_destroyed(self): - """Test listing channel interpreters with a destroyed interpreter.""" - interp0 = interpreters.get_main() - interp1 = interpreters.create() - cid = interpreters.channel_create() - interpreters.channel_send(cid, "send") - _run_output(interp1, dedent(f""" - import _xxsubinterpreters as _interpreters - obj = _interpreters.channel_recv({cid}) - """)) - # Should be one interpreter associated with each end. - send_interps = interpreters.channel_list_interpreters(cid, send=True) - recv_interps = interpreters.channel_list_interpreters(cid, send=False) - self.assertEqual(send_interps, [interp0]) - self.assertEqual(recv_interps, [interp1]) - - interpreters.destroy(interp1) - # Destroyed interpreter should not be listed. - send_interps = interpreters.channel_list_interpreters(cid, send=True) - recv_interps = interpreters.channel_list_interpreters(cid, send=False) - self.assertEqual(send_interps, [interp0]) - self.assertEqual(recv_interps, []) - - def test_channel_list_interpreters_released(self): - """Test listing channel interpreters with a released channel.""" - # Set up one channel with main interpreter on the send end and two - # subinterpreters on the receive end. - interp0 = interpreters.get_main() - interp1 = interpreters.create() - interp2 = interpreters.create() - cid = interpreters.channel_create() - interpreters.channel_send(cid, "data") - _run_output(interp1, dedent(f""" - import _xxsubinterpreters as _interpreters - obj = _interpreters.channel_recv({cid}) - """)) - interpreters.channel_send(cid, "data") - _run_output(interp2, dedent(f""" - import _xxsubinterpreters as _interpreters - obj = _interpreters.channel_recv({cid}) - """)) - # Check the setup. - send_interps = interpreters.channel_list_interpreters(cid, send=True) - recv_interps = interpreters.channel_list_interpreters(cid, send=False) - self.assertEqual(len(send_interps), 1) - self.assertEqual(len(recv_interps), 2) - - # Release the main interpreter from the send end. - interpreters.channel_release(cid, send=True) - # Send end should have no associated interpreters. - send_interps = interpreters.channel_list_interpreters(cid, send=True) - recv_interps = interpreters.channel_list_interpreters(cid, send=False) - self.assertEqual(len(send_interps), 0) - self.assertEqual(len(recv_interps), 2) - - # Release one of the subinterpreters from the receive end. - _run_output(interp2, dedent(f""" - import _xxsubinterpreters as _interpreters - _interpreters.channel_release({cid}) - """)) - # Receive end should have the released interpreter removed. - send_interps = interpreters.channel_list_interpreters(cid, send=True) - recv_interps = interpreters.channel_list_interpreters(cid, send=False) - self.assertEqual(len(send_interps), 0) - self.assertEqual(recv_interps, [interp1]) - - def test_channel_list_interpreters_closed(self): - """Test listing channel interpreters with a closed channel.""" - interp0 = interpreters.get_main() - interp1 = interpreters.create() - cid = interpreters.channel_create() - # Put something in the channel so that it's not empty. - interpreters.channel_send(cid, "send") - - # Check initial state. - send_interps = interpreters.channel_list_interpreters(cid, send=True) - recv_interps = interpreters.channel_list_interpreters(cid, send=False) - self.assertEqual(len(send_interps), 1) - self.assertEqual(len(recv_interps), 0) - - # Force close the channel. - interpreters.channel_close(cid, force=True) - # Both ends should raise an error. - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_list_interpreters(cid, send=True) - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_list_interpreters(cid, send=False) - - def test_channel_list_interpreters_closed_send_end(self): - """Test listing channel interpreters with a channel's send end closed.""" - interp0 = interpreters.get_main() - interp1 = interpreters.create() - cid = interpreters.channel_create() - # Put something in the channel so that it's not empty. - interpreters.channel_send(cid, "send") - - # Check initial state. - send_interps = interpreters.channel_list_interpreters(cid, send=True) - recv_interps = interpreters.channel_list_interpreters(cid, send=False) - self.assertEqual(len(send_interps), 1) - self.assertEqual(len(recv_interps), 0) - - # Close the send end of the channel. - interpreters.channel_close(cid, send=True) - # Send end should raise an error. - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_list_interpreters(cid, send=True) - # Receive end should not be closed (since channel is not empty). - recv_interps = interpreters.channel_list_interpreters(cid, send=False) - self.assertEqual(len(recv_interps), 0) - - # Close the receive end of the channel from a subinterpreter. - _run_output(interp1, dedent(f""" - import _xxsubinterpreters as _interpreters - _interpreters.channel_close({cid}, force=True) - """)) - # Both ends should raise an error. - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_list_interpreters(cid, send=True) - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_list_interpreters(cid, send=False) - - #################### - - def test_send_recv_main(self): - cid = interpreters.channel_create() - orig = b'spam' - interpreters.channel_send(cid, orig) - obj = interpreters.channel_recv(cid) - - self.assertEqual(obj, orig) - self.assertIsNot(obj, orig) - - def test_send_recv_same_interpreter(self): - id1 = interpreters.create() - out = _run_output(id1, dedent(""" - import _xxsubinterpreters as _interpreters - cid = _interpreters.channel_create() - orig = b'spam' - _interpreters.channel_send(cid, orig) - obj = _interpreters.channel_recv(cid) - assert obj is not orig - assert obj == orig - """)) - - def test_send_recv_different_interpreters(self): - cid = interpreters.channel_create() - id1 = interpreters.create() - out = _run_output(id1, dedent(f""" - import _xxsubinterpreters as _interpreters - _interpreters.channel_send({cid}, b'spam') - """)) - obj = interpreters.channel_recv(cid) - - self.assertEqual(obj, b'spam') - - def test_send_recv_different_threads(self): - cid = interpreters.channel_create() - - def f(): - while True: - try: - obj = interpreters.channel_recv(cid) - break - except interpreters.ChannelEmptyError: - time.sleep(0.1) - interpreters.channel_send(cid, obj) - t = threading.Thread(target=f) - t.start() - - interpreters.channel_send(cid, b'spam') - t.join() - obj = interpreters.channel_recv(cid) - - self.assertEqual(obj, b'spam') - - def test_send_recv_different_interpreters_and_threads(self): - cid = interpreters.channel_create() - id1 = interpreters.create() - out = None - - def f(): - nonlocal out - out = _run_output(id1, dedent(f""" - import time - import _xxsubinterpreters as _interpreters - while True: - try: - obj = _interpreters.channel_recv({cid}) - break - except _interpreters.ChannelEmptyError: - time.sleep(0.1) - assert(obj == b'spam') - _interpreters.channel_send({cid}, b'eggs') - """)) - t = threading.Thread(target=f) - t.start() - - interpreters.channel_send(cid, b'spam') - t.join() - obj = interpreters.channel_recv(cid) - - self.assertEqual(obj, b'eggs') - - def test_send_not_found(self): - with self.assertRaises(interpreters.ChannelNotFoundError): - interpreters.channel_send(10, b'spam') - - def test_recv_not_found(self): - with self.assertRaises(interpreters.ChannelNotFoundError): - interpreters.channel_recv(10) - - def test_recv_empty(self): - cid = interpreters.channel_create() - with self.assertRaises(interpreters.ChannelEmptyError): - interpreters.channel_recv(cid) - - def test_recv_default(self): - default = object() - cid = interpreters.channel_create() - obj1 = interpreters.channel_recv(cid, default) - interpreters.channel_send(cid, None) - interpreters.channel_send(cid, 1) - interpreters.channel_send(cid, b'spam') - interpreters.channel_send(cid, b'eggs') - obj2 = interpreters.channel_recv(cid, default) - obj3 = interpreters.channel_recv(cid, default) - obj4 = interpreters.channel_recv(cid) - obj5 = interpreters.channel_recv(cid, default) - obj6 = interpreters.channel_recv(cid, default) - - self.assertIs(obj1, default) - self.assertIs(obj2, None) - self.assertEqual(obj3, 1) - self.assertEqual(obj4, b'spam') - self.assertEqual(obj5, b'eggs') - self.assertIs(obj6, default) - - def test_run_string_arg_unresolved(self): - cid = interpreters.channel_create() - interp = interpreters.create() - - out = _run_output(interp, dedent(""" - import _xxsubinterpreters as _interpreters - print(cid.end) - _interpreters.channel_send(cid, b'spam') - """), - dict(cid=cid.send)) - obj = interpreters.channel_recv(cid) - - self.assertEqual(obj, b'spam') - self.assertEqual(out.strip(), 'send') - - # XXX For now there is no high-level channel into which the - # sent channel ID can be converted... - # Note: this test caused crashes on some buildbots (bpo-33615). - @unittest.skip('disabled until high-level channels exist') - def test_run_string_arg_resolved(self): - cid = interpreters.channel_create() - cid = interpreters._channel_id(cid, _resolve=True) - interp = interpreters.create() - - out = _run_output(interp, dedent(""" - import _xxsubinterpreters as _interpreters - print(chan.id.end) - _interpreters.channel_send(chan.id, b'spam') - """), - dict(chan=cid.send)) - obj = interpreters.channel_recv(cid) - - self.assertEqual(obj, b'spam') - self.assertEqual(out.strip(), 'send') - - # close - - def test_close_single_user(self): - cid = interpreters.channel_create() - interpreters.channel_send(cid, b'spam') - interpreters.channel_recv(cid) - interpreters.channel_close(cid) - - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_send(cid, b'eggs') - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_recv(cid) - - def test_close_multiple_users(self): - cid = interpreters.channel_create() - id1 = interpreters.create() - id2 = interpreters.create() - interpreters.run_string(id1, dedent(f""" - import _xxsubinterpreters as _interpreters - _interpreters.channel_send({cid}, b'spam') - """)) - interpreters.run_string(id2, dedent(f""" - import _xxsubinterpreters as _interpreters - _interpreters.channel_recv({cid}) - """)) - interpreters.channel_close(cid) - with self.assertRaises(interpreters.RunFailedError) as cm: - interpreters.run_string(id1, dedent(f""" - _interpreters.channel_send({cid}, b'spam') - """)) - self.assertIn('ChannelClosedError', str(cm.exception)) - with self.assertRaises(interpreters.RunFailedError) as cm: - interpreters.run_string(id2, dedent(f""" - _interpreters.channel_send({cid}, b'spam') - """)) - self.assertIn('ChannelClosedError', str(cm.exception)) - - def test_close_multiple_times(self): - cid = interpreters.channel_create() - interpreters.channel_send(cid, b'spam') - interpreters.channel_recv(cid) - interpreters.channel_close(cid) - - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_close(cid) - - def test_close_empty(self): - tests = [ - (False, False), - (True, False), - (False, True), - (True, True), - ] - for send, recv in tests: - with self.subTest((send, recv)): - cid = interpreters.channel_create() - interpreters.channel_send(cid, b'spam') - interpreters.channel_recv(cid) - interpreters.channel_close(cid, send=send, recv=recv) - - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_send(cid, b'eggs') - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_recv(cid) - - def test_close_defaults_with_unused_items(self): - cid = interpreters.channel_create() - interpreters.channel_send(cid, b'spam') - interpreters.channel_send(cid, b'ham') - - with self.assertRaises(interpreters.ChannelNotEmptyError): - interpreters.channel_close(cid) - interpreters.channel_recv(cid) - interpreters.channel_send(cid, b'eggs') - - def test_close_recv_with_unused_items_unforced(self): - cid = interpreters.channel_create() - interpreters.channel_send(cid, b'spam') - interpreters.channel_send(cid, b'ham') - - with self.assertRaises(interpreters.ChannelNotEmptyError): - interpreters.channel_close(cid, recv=True) - interpreters.channel_recv(cid) - interpreters.channel_send(cid, b'eggs') - interpreters.channel_recv(cid) - interpreters.channel_recv(cid) - interpreters.channel_close(cid, recv=True) - - def test_close_send_with_unused_items_unforced(self): - cid = interpreters.channel_create() - interpreters.channel_send(cid, b'spam') - interpreters.channel_send(cid, b'ham') - interpreters.channel_close(cid, send=True) - - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_send(cid, b'eggs') - interpreters.channel_recv(cid) - interpreters.channel_recv(cid) - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_recv(cid) - - def test_close_both_with_unused_items_unforced(self): - cid = interpreters.channel_create() - interpreters.channel_send(cid, b'spam') - interpreters.channel_send(cid, b'ham') - - with self.assertRaises(interpreters.ChannelNotEmptyError): - interpreters.channel_close(cid, recv=True, send=True) - interpreters.channel_recv(cid) - interpreters.channel_send(cid, b'eggs') - interpreters.channel_recv(cid) - interpreters.channel_recv(cid) - interpreters.channel_close(cid, recv=True) - - def test_close_recv_with_unused_items_forced(self): - cid = interpreters.channel_create() - interpreters.channel_send(cid, b'spam') - interpreters.channel_send(cid, b'ham') - interpreters.channel_close(cid, recv=True, force=True) - - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_send(cid, b'eggs') - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_recv(cid) - - def test_close_send_with_unused_items_forced(self): - cid = interpreters.channel_create() - interpreters.channel_send(cid, b'spam') - interpreters.channel_send(cid, b'ham') - interpreters.channel_close(cid, send=True, force=True) - - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_send(cid, b'eggs') - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_recv(cid) - - def test_close_both_with_unused_items_forced(self): - cid = interpreters.channel_create() - interpreters.channel_send(cid, b'spam') - interpreters.channel_send(cid, b'ham') - interpreters.channel_close(cid, send=True, recv=True, force=True) - - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_send(cid, b'eggs') - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_recv(cid) - - def test_close_never_used(self): - cid = interpreters.channel_create() - interpreters.channel_close(cid) - - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_send(cid, b'spam') - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_recv(cid) - - def test_close_by_unassociated_interp(self): - cid = interpreters.channel_create() - interpreters.channel_send(cid, b'spam') - interp = interpreters.create() - interpreters.run_string(interp, dedent(f""" - import _xxsubinterpreters as _interpreters - _interpreters.channel_close({cid}, force=True) - """)) - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_recv(cid) - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_close(cid) - - def test_close_used_multiple_times_by_single_user(self): - cid = interpreters.channel_create() - interpreters.channel_send(cid, b'spam') - interpreters.channel_send(cid, b'spam') - interpreters.channel_send(cid, b'spam') - interpreters.channel_recv(cid) - interpreters.channel_close(cid, force=True) - - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_send(cid, b'eggs') - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_recv(cid) - - def test_channel_list_interpreters_invalid_channel(self): - cid = interpreters.channel_create() - # Test for invalid channel ID. - with self.assertRaises(interpreters.ChannelNotFoundError): - interpreters.channel_list_interpreters(1000, send=True) - - interpreters.channel_close(cid) - # Test for a channel that has been closed. - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_list_interpreters(cid, send=True) - - def test_channel_list_interpreters_invalid_args(self): - # Tests for invalid arguments passed to the API. - cid = interpreters.channel_create() - with self.assertRaises(TypeError): - interpreters.channel_list_interpreters(cid) - - -class ChannelReleaseTests(TestBase): - - # XXX Add more test coverage a la the tests for close(). - - """ - - main / interp / other - - run in: current thread / new thread / other thread / different threads - - end / opposite - - force / no force - - used / not used (associated / not associated) - - empty / emptied / never emptied / partly emptied - - closed / not closed - - released / not released - - creator (interp) / other - - associated interpreter not running - - associated interpreter destroyed - """ - - """ - use - pre-release - release - after - check - """ - - """ - release in: main, interp1 - creator: same, other (incl. interp2) - - use: None,send,recv,send/recv in None,same,other(incl. interp2),same+other(incl. interp2),all - pre-release: None,send,recv,both in None,same,other(incl. interp2),same+other(incl. interp2),all - pre-release forced: None,send,recv,both in None,same,other(incl. interp2),same+other(incl. interp2),all - - release: same - release forced: same - - use after: None,send,recv,send/recv in None,same,other(incl. interp2),same+other(incl. interp2),all - release after: None,send,recv,send/recv in None,same,other(incl. interp2),same+other(incl. interp2),all - check released: send/recv for same/other(incl. interp2) - check closed: send/recv for same/other(incl. interp2) - """ - - def test_single_user(self): - cid = interpreters.channel_create() - interpreters.channel_send(cid, b'spam') - interpreters.channel_recv(cid) - interpreters.channel_release(cid, send=True, recv=True) - - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_send(cid, b'eggs') - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_recv(cid) - - def test_multiple_users(self): - cid = interpreters.channel_create() - id1 = interpreters.create() - id2 = interpreters.create() - interpreters.run_string(id1, dedent(f""" - import _xxsubinterpreters as _interpreters - _interpreters.channel_send({cid}, b'spam') - """)) - out = _run_output(id2, dedent(f""" - import _xxsubinterpreters as _interpreters - obj = _interpreters.channel_recv({cid}) - _interpreters.channel_release({cid}) - print(repr(obj)) - """)) - interpreters.run_string(id1, dedent(f""" - _interpreters.channel_release({cid}) - """)) - - self.assertEqual(out.strip(), "b'spam'") - - def test_no_kwargs(self): - cid = interpreters.channel_create() - interpreters.channel_send(cid, b'spam') - interpreters.channel_recv(cid) - interpreters.channel_release(cid) - - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_send(cid, b'eggs') - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_recv(cid) - - def test_multiple_times(self): - cid = interpreters.channel_create() - interpreters.channel_send(cid, b'spam') - interpreters.channel_recv(cid) - interpreters.channel_release(cid, send=True, recv=True) - - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_release(cid, send=True, recv=True) - - def test_with_unused_items(self): - cid = interpreters.channel_create() - interpreters.channel_send(cid, b'spam') - interpreters.channel_send(cid, b'ham') - interpreters.channel_release(cid, send=True, recv=True) - - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_recv(cid) - - def test_never_used(self): - cid = interpreters.channel_create() - interpreters.channel_release(cid) - - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_send(cid, b'spam') - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_recv(cid) - - def test_by_unassociated_interp(self): - cid = interpreters.channel_create() - interpreters.channel_send(cid, b'spam') - interp = interpreters.create() - interpreters.run_string(interp, dedent(f""" - import _xxsubinterpreters as _interpreters - _interpreters.channel_release({cid}) - """)) - obj = interpreters.channel_recv(cid) - interpreters.channel_release(cid) - - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_send(cid, b'eggs') - self.assertEqual(obj, b'spam') - - def test_close_if_unassociated(self): - # XXX Something's not right with this test... - cid = interpreters.channel_create() - interp = interpreters.create() - interpreters.run_string(interp, dedent(f""" - import _xxsubinterpreters as _interpreters - obj = _interpreters.channel_send({cid}, b'spam') - _interpreters.channel_release({cid}) - """)) - - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_recv(cid) - - def test_partially(self): - # XXX Is partial close too weird/confusing? - cid = interpreters.channel_create() - interpreters.channel_send(cid, None) - interpreters.channel_recv(cid) - interpreters.channel_send(cid, b'spam') - interpreters.channel_release(cid, send=True) - obj = interpreters.channel_recv(cid) - - self.assertEqual(obj, b'spam') - - def test_used_multiple_times_by_single_user(self): - cid = interpreters.channel_create() - interpreters.channel_send(cid, b'spam') - interpreters.channel_send(cid, b'spam') - interpreters.channel_send(cid, b'spam') - interpreters.channel_recv(cid) - interpreters.channel_release(cid, send=True, recv=True) - - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_send(cid, b'eggs') - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_recv(cid) - - -class ChannelCloseFixture(namedtuple('ChannelCloseFixture', - 'end interp other extra creator')): - - # Set this to True to avoid creating interpreters, e.g. when - # scanning through test permutations without running them. - QUICK = False - - def __new__(cls, end, interp, other, extra, creator): - assert end in ('send', 'recv') - if cls.QUICK: - known = {} - else: - interp = Interpreter.from_raw(interp) - other = Interpreter.from_raw(other) - extra = Interpreter.from_raw(extra) - known = { - interp.name: interp, - other.name: other, - extra.name: extra, - } - if not creator: - creator = 'same' - self = super().__new__(cls, end, interp, other, extra, creator) - self._prepped = set() - self._state = ChannelState() - self._known = known - return self - - @property - def state(self): - return self._state - - @property - def cid(self): - try: - return self._cid - except AttributeError: - creator = self._get_interpreter(self.creator) - self._cid = self._new_channel(creator) - return self._cid - - def get_interpreter(self, interp): - interp = self._get_interpreter(interp) - self._prep_interpreter(interp) - return interp - - def expect_closed_error(self, end=None): - if end is None: - end = self.end - if end == 'recv' and self.state.closed == 'send': - return False - return bool(self.state.closed) - - def prep_interpreter(self, interp): - self._prep_interpreter(interp) - - def record_action(self, action, result): - self._state = result - - def clean_up(self): - clean_up_interpreters() - clean_up_channels() - - # internal methods - - def _new_channel(self, creator): - if creator.name == 'main': - return interpreters.channel_create() - else: - ch = interpreters.channel_create() - run_interp(creator.id, f""" - import _xxsubinterpreters - cid = _xxsubinterpreters.channel_create() - # We purposefully send back an int to avoid tying the - # channel to the other interpreter. - _xxsubinterpreters.channel_send({ch}, int(cid)) - del _xxsubinterpreters - """) - self._cid = interpreters.channel_recv(ch) - return self._cid - - def _get_interpreter(self, interp): - if interp in ('same', 'interp'): - return self.interp - elif interp == 'other': - return self.other - elif interp == 'extra': - return self.extra - else: - name = interp - try: - interp = self._known[name] - except KeyError: - interp = self._known[name] = Interpreter(name) - return interp - - def _prep_interpreter(self, interp): - if interp.id in self._prepped: - return - self._prepped.add(interp.id) - if interp.name == 'main': - return - run_interp(interp.id, f""" - import _xxsubinterpreters as interpreters - import test.test__xxsubinterpreters as helpers - ChannelState = helpers.ChannelState - try: - cid - except NameError: - cid = interpreters._channel_id({self.cid}) - """) - - -@unittest.skip('these tests take several hours to run') -class ExhaustiveChannelTests(TestBase): - - """ - - main / interp / other - - run in: current thread / new thread / other thread / different threads - - end / opposite - - force / no force - - used / not used (associated / not associated) - - empty / emptied / never emptied / partly emptied - - closed / not closed - - released / not released - - creator (interp) / other - - associated interpreter not running - - associated interpreter destroyed - - - close after unbound - """ - - """ - use - pre-close - close - after - check - """ - - """ - close in: main, interp1 - creator: same, other, extra - - use: None,send,recv,send/recv in None,same,other,same+other,all - pre-close: None,send,recv in None,same,other,same+other,all - pre-close forced: None,send,recv in None,same,other,same+other,all - - close: same - close forced: same - - use after: None,send,recv,send/recv in None,same,other,extra,same+other,all - close after: None,send,recv,send/recv in None,same,other,extra,same+other,all - check closed: send/recv for same/other(incl. interp2) - """ - - def iter_action_sets(self): - # - used / not used (associated / not associated) - # - empty / emptied / never emptied / partly emptied - # - closed / not closed - # - released / not released - - # never used - yield [] - - # only pre-closed (and possible used after) - for closeactions in self._iter_close_action_sets('same', 'other'): - yield closeactions - for postactions in self._iter_post_close_action_sets(): - yield closeactions + postactions - for closeactions in self._iter_close_action_sets('other', 'extra'): - yield closeactions - for postactions in self._iter_post_close_action_sets(): - yield closeactions + postactions - - # used - for useactions in self._iter_use_action_sets('same', 'other'): - yield useactions - for closeactions in self._iter_close_action_sets('same', 'other'): - actions = useactions + closeactions - yield actions - for postactions in self._iter_post_close_action_sets(): - yield actions + postactions - for closeactions in self._iter_close_action_sets('other', 'extra'): - actions = useactions + closeactions - yield actions - for postactions in self._iter_post_close_action_sets(): - yield actions + postactions - for useactions in self._iter_use_action_sets('other', 'extra'): - yield useactions - for closeactions in self._iter_close_action_sets('same', 'other'): - actions = useactions + closeactions - yield actions - for postactions in self._iter_post_close_action_sets(): - yield actions + postactions - for closeactions in self._iter_close_action_sets('other', 'extra'): - actions = useactions + closeactions - yield actions - for postactions in self._iter_post_close_action_sets(): - yield actions + postactions - - def _iter_use_action_sets(self, interp1, interp2): - interps = (interp1, interp2) - - # only recv end used - yield [ - ChannelAction('use', 'recv', interp1), - ] - yield [ - ChannelAction('use', 'recv', interp2), - ] - yield [ - ChannelAction('use', 'recv', interp1), - ChannelAction('use', 'recv', interp2), - ] - - # never emptied - yield [ - ChannelAction('use', 'send', interp1), - ] - yield [ - ChannelAction('use', 'send', interp2), - ] - yield [ - ChannelAction('use', 'send', interp1), - ChannelAction('use', 'send', interp2), - ] - - # partially emptied - for interp1 in interps: - for interp2 in interps: - for interp3 in interps: - yield [ - ChannelAction('use', 'send', interp1), - ChannelAction('use', 'send', interp2), - ChannelAction('use', 'recv', interp3), - ] - - # fully emptied - for interp1 in interps: - for interp2 in interps: - for interp3 in interps: - for interp4 in interps: - yield [ - ChannelAction('use', 'send', interp1), - ChannelAction('use', 'send', interp2), - ChannelAction('use', 'recv', interp3), - ChannelAction('use', 'recv', interp4), - ] - - def _iter_close_action_sets(self, interp1, interp2): - ends = ('recv', 'send') - interps = (interp1, interp2) - for force in (True, False): - op = 'force-close' if force else 'close' - for interp in interps: - for end in ends: - yield [ - ChannelAction(op, end, interp), - ] - for recvop in ('close', 'force-close'): - for sendop in ('close', 'force-close'): - for recv in interps: - for send in interps: - yield [ - ChannelAction(recvop, 'recv', recv), - ChannelAction(sendop, 'send', send), - ] - - def _iter_post_close_action_sets(self): - for interp in ('same', 'extra', 'other'): - yield [ - ChannelAction('use', 'recv', interp), - ] - yield [ - ChannelAction('use', 'send', interp), - ] - - def run_actions(self, fix, actions): - for action in actions: - self.run_action(fix, action) - - def run_action(self, fix, action, *, hideclosed=True): - end = action.resolve_end(fix.end) - interp = action.resolve_interp(fix.interp, fix.other, fix.extra) - fix.prep_interpreter(interp) - if interp.name == 'main': - result = run_action( - fix.cid, - action.action, - end, - fix.state, - hideclosed=hideclosed, - ) - fix.record_action(action, result) - else: - _cid = interpreters.channel_create() - run_interp(interp.id, f""" - result = helpers.run_action( - {fix.cid}, - {repr(action.action)}, - {repr(end)}, - {repr(fix.state)}, - hideclosed={hideclosed}, - ) - interpreters.channel_send({_cid}, result.pending.to_bytes(1, 'little')) - interpreters.channel_send({_cid}, b'X' if result.closed else b'') - """) - result = ChannelState( - pending=int.from_bytes(interpreters.channel_recv(_cid), 'little'), - closed=bool(interpreters.channel_recv(_cid)), - ) - fix.record_action(action, result) - - def iter_fixtures(self): - # XXX threads? - interpreters = [ - ('main', 'interp', 'extra'), - ('interp', 'main', 'extra'), - ('interp1', 'interp2', 'extra'), - ('interp1', 'interp2', 'main'), - ] - for interp, other, extra in interpreters: - for creator in ('same', 'other', 'creator'): - for end in ('send', 'recv'): - yield ChannelCloseFixture(end, interp, other, extra, creator) - - def _close(self, fix, *, force): - op = 'force-close' if force else 'close' - close = ChannelAction(op, fix.end, 'same') - if not fix.expect_closed_error(): - self.run_action(fix, close, hideclosed=False) - else: - with self.assertRaises(interpreters.ChannelClosedError): - self.run_action(fix, close, hideclosed=False) - - def _assert_closed_in_interp(self, fix, interp=None): - if interp is None or interp.name == 'main': - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_recv(fix.cid) - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_send(fix.cid, b'spam') - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_close(fix.cid) - with self.assertRaises(interpreters.ChannelClosedError): - interpreters.channel_close(fix.cid, force=True) - else: - run_interp(interp.id, f""" - with helpers.expect_channel_closed(): - interpreters.channel_recv(cid) - """) - run_interp(interp.id, f""" - with helpers.expect_channel_closed(): - interpreters.channel_send(cid, b'spam') - """) - run_interp(interp.id, f""" - with helpers.expect_channel_closed(): - interpreters.channel_close(cid) - """) - run_interp(interp.id, f""" - with helpers.expect_channel_closed(): - interpreters.channel_close(cid, force=True) - """) - - def _assert_closed(self, fix): - self.assertTrue(fix.state.closed) - - for _ in range(fix.state.pending): - interpreters.channel_recv(fix.cid) - self._assert_closed_in_interp(fix) - - for interp in ('same', 'other'): - interp = fix.get_interpreter(interp) - if interp.name == 'main': - continue - self._assert_closed_in_interp(fix, interp) - - interp = fix.get_interpreter('fresh') - self._assert_closed_in_interp(fix, interp) - - def _iter_close_tests(self, verbose=False): - i = 0 - for actions in self.iter_action_sets(): - print() - for fix in self.iter_fixtures(): - i += 1 - if i > 1000: - return - if verbose: - if (i - 1) % 6 == 0: - print() - print(i, fix, '({} actions)'.format(len(actions))) - else: - if (i - 1) % 6 == 0: - print(' ', end='') - print('.', end=''); sys.stdout.flush() - yield i, fix, actions - if verbose: - print('---') - print() - - # This is useful for scanning through the possible tests. - def _skim_close_tests(self): - ChannelCloseFixture.QUICK = True - for i, fix, actions in self._iter_close_tests(): - pass - - def test_close(self): - for i, fix, actions in self._iter_close_tests(): - with self.subTest('{} {} {}'.format(i, fix, actions)): - fix.prep_interpreter(fix.interp) - self.run_actions(fix, actions) - - self._close(fix, force=False) - - self._assert_closed(fix) - # XXX Things slow down if we have too many interpreters. - fix.clean_up() - - def test_force_close(self): - for i, fix, actions in self._iter_close_tests(): - with self.subTest('{} {} {}'.format(i, fix, actions)): - fix.prep_interpreter(fix.interp) - self.run_actions(fix, actions) - - self._close(fix, force=True) - - self._assert_closed(fix) - # XXX Things slow down if we have too many interpreters. - fix.clean_up() - - if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_abc.py b/Lib/test/test_abc.py index 1e7a0351..5ce57cc2 100644 --- a/Lib/test/test_abc.py +++ b/Lib/test/test_abc.py @@ -154,7 +154,7 @@ def test_factory(abc_ABCMeta, abc_get_cache_token): @abc.abstractmethod def method_one(self): pass - msg = r"class C with abstract method method_one" + msg = r"class C without an implementation for abstract method 'method_one'" self.assertRaisesRegex(TypeError, msg, C) def test_object_new_with_many_abstractmethods(self): @@ -165,7 +165,7 @@ def test_factory(abc_ABCMeta, abc_get_cache_token): @abc.abstractmethod def method_two(self): pass - msg = r"class C with abstract methods method_one, method_two" + msg = r"class C without an implementation for abstract methods 'method_one', 'method_two'" self.assertRaisesRegex(TypeError, msg, C) def test_abstractmethod_integration(self): @@ -448,15 +448,16 @@ def test_factory(abc_ABCMeta, abc_get_cache_token): # Also check that issubclass() propagates exceptions raised by # __subclasses__. + class CustomError(Exception): ... exc_msg = "exception from __subclasses__" def raise_exc(): - raise Exception(exc_msg) + raise CustomError(exc_msg) class S(metaclass=abc_ABCMeta): __subclasses__ = raise_exc - with self.assertRaisesRegex(Exception, exc_msg): + with self.assertRaisesRegex(CustomError, exc_msg): issubclass(int, S) def test_subclasshook(self): @@ -535,7 +536,7 @@ def test_factory(abc_ABCMeta, abc_get_cache_token): A.foo = updated_foo abc.update_abstractmethods(A) self.assertEqual(A.__abstractmethods__, {'foo', 'bar'}) - msg = "class A with abstract methods bar, foo" + msg = "class A without an implementation for abstract methods 'bar', 'foo'" self.assertRaisesRegex(TypeError, msg, A) def test_update_implementation(self): @@ -547,7 +548,7 @@ def test_factory(abc_ABCMeta, abc_get_cache_token): class B(A): pass - msg = "class B with abstract method foo" + msg = "class B without an implementation for abstract method 'foo'" self.assertRaisesRegex(TypeError, msg, B) self.assertEqual(B.__abstractmethods__, {'foo'}) @@ -605,7 +606,7 @@ def test_factory(abc_ABCMeta, abc_get_cache_token): abc.update_abstractmethods(B) - msg = "class B with abstract method foo" + msg = "class B without an implementation for abstract method 'foo'" self.assertRaisesRegex(TypeError, msg, B) def test_update_layered_implementation(self): @@ -627,7 +628,7 @@ def test_factory(abc_ABCMeta, abc_get_cache_token): abc.update_abstractmethods(C) - msg = "class C with abstract method foo" + msg = "class C without an implementation for abstract method 'foo'" self.assertRaisesRegex(TypeError, msg, C) def test_update_multi_inheritance(self): diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py index 1acecbb8..3a62a16c 100644 --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -1,5 +1,7 @@ # Author: Steven J. Bethard <steven.bethard@gmail.com>. +import contextlib +import functools import inspect import io import operator @@ -35,6 +37,35 @@ class StdIOBuffer(io.TextIOWrapper): return self.buffer.raw.getvalue().decode('utf-8') +class StdStreamTest(unittest.TestCase): + + def test_skip_invalid_stderr(self): + parser = argparse.ArgumentParser() + with ( + contextlib.redirect_stderr(None), + mock.patch('argparse._sys.exit') + ): + parser.exit(status=0, message='foo') + + def test_skip_invalid_stdout(self): + parser = argparse.ArgumentParser() + for func in ( + parser.print_usage, + parser.print_help, + functools.partial(parser.parse_args, ['-h']) + ): + with ( + self.subTest(func=func), + contextlib.redirect_stdout(None), + # argparse uses stderr as a fallback + StdIOBuffer() as mocked_stderr, + contextlib.redirect_stderr(mocked_stderr), + mock.patch('argparse._sys.exit'), + ): + func() + self.assertRegex(mocked_stderr.getvalue(), r'usage:') + + class TestCase(unittest.TestCase): def setUp(self): @@ -734,6 +765,49 @@ class TestBooleanOptionalAction(ParserTestCase): self.assertIn("got an unexpected keyword argument 'const'", str(cm.exception)) + def test_deprecated_init_kw(self): + # See gh-92248 + parser = argparse.ArgumentParser() + + with self.assertWarns(DeprecationWarning): + parser.add_argument( + '-a', + action=argparse.BooleanOptionalAction, + type=None, + ) + with self.assertWarns(DeprecationWarning): + parser.add_argument( + '-b', + action=argparse.BooleanOptionalAction, + type=bool, + ) + + with self.assertWarns(DeprecationWarning): + parser.add_argument( + '-c', + action=argparse.BooleanOptionalAction, + metavar=None, + ) + with self.assertWarns(DeprecationWarning): + parser.add_argument( + '-d', + action=argparse.BooleanOptionalAction, + metavar='d', + ) + + with self.assertWarns(DeprecationWarning): + parser.add_argument( + '-e', + action=argparse.BooleanOptionalAction, + choices=None, + ) + with self.assertWarns(DeprecationWarning): + parser.add_argument( + '-f', + action=argparse.BooleanOptionalAction, + choices=(), + ) + class TestBooleanOptionalActionRequired(ParserTestCase): """Tests BooleanOptionalAction required""" @@ -1505,14 +1579,15 @@ class TestArgumentsFromFile(TempDirMixin, ParserTestCase): def setUp(self): super(TestArgumentsFromFile, self).setUp() file_texts = [ - ('hello', 'hello world!\n'), - ('recursive', '-a\n' - 'A\n' - '@hello'), - ('invalid', '@no-such-path\n'), + ('hello', os.fsencode(self.hello) + b'\n'), + ('recursive', b'-a\n' + b'A\n' + b'@hello'), + ('invalid', b'@no-such-path\n'), + ('undecodable', self.undecodable + b'\n'), ] for path, text in file_texts: - with open(path, 'w', encoding="utf-8") as file: + with open(path, 'wb') as file: file.write(text) parser_signature = Sig(fromfile_prefix_chars='@') @@ -1522,15 +1597,25 @@ class TestArgumentsFromFile(TempDirMixin, ParserTestCase): Sig('y', nargs='+'), ] failures = ['', '-b', 'X', '@invalid', '@missing'] + hello = 'hello world!' + os_helper.FS_NONASCII successes = [ ('X Y', NS(a=None, x='X', y=['Y'])), ('X -a A Y Z', NS(a='A', x='X', y=['Y', 'Z'])), - ('@hello X', NS(a=None, x='hello world!', y=['X'])), - ('X @hello', NS(a=None, x='X', y=['hello world!'])), - ('-a B @recursive Y Z', NS(a='A', x='hello world!', y=['Y', 'Z'])), - ('X @recursive Z -a B', NS(a='B', x='X', y=['hello world!', 'Z'])), + ('@hello X', NS(a=None, x=hello, y=['X'])), + ('X @hello', NS(a=None, x='X', y=[hello])), + ('-a B @recursive Y Z', NS(a='A', x=hello, y=['Y', 'Z'])), + ('X @recursive Z -a B', NS(a='B', x='X', y=[hello, 'Z'])), (["-a", "", "X", "Y"], NS(a='', x='X', y=['Y'])), ] + if os_helper.TESTFN_UNDECODABLE: + undecodable = os_helper.TESTFN_UNDECODABLE.lstrip(b'@') + decoded_undecodable = os.fsdecode(undecodable) + successes += [ + ('@undecodable X', NS(a=None, x=decoded_undecodable, y=['X'])), + ('X @undecodable', NS(a=None, x='X', y=[decoded_undecodable])), + ] + else: + undecodable = b'' class TestArgumentsFromFileConverter(TempDirMixin, ParserTestCase): @@ -1539,10 +1624,10 @@ class TestArgumentsFromFileConverter(TempDirMixin, ParserTestCase): def setUp(self): super(TestArgumentsFromFileConverter, self).setUp() file_texts = [ - ('hello', 'hello world!\n'), + ('hello', b'hello world!\n'), ] for path, text in file_texts: - with open(path, 'w', encoding="utf-8") as file: + with open(path, 'wb') as file: file.write(text) class FromFileConverterArgumentParser(ErrorRaisingArgumentParser): @@ -3753,6 +3838,28 @@ class TestHelpUsage(HelpTestCase): version = '' +class TestHelpUsageWithParentheses(HelpTestCase): + parser_signature = Sig(prog='PROG') + argument_signatures = [ + Sig('positional', metavar='(example) positional'), + Sig('-p', '--optional', metavar='{1 (option A), 2 (option B)}'), + ] + + usage = '''\ + usage: PROG [-h] [-p {1 (option A), 2 (option B)}] (example) positional + ''' + help = usage + '''\ + + positional arguments: + (example) positional + + options: + -h, --help show this help message and exit + -p {1 (option A), 2 (option B)}, --optional {1 (option A), 2 (option B)} + ''' + version = '' + + class TestHelpOnlyUserGroups(HelpTestCase): """Test basic usage messages""" @@ -5219,6 +5326,13 @@ class TestParseKnownArgs(TestCase): self.assertEqual(NS(v=3, spam=True, badger="B"), args) self.assertEqual(["C", "--foo", "4"], extras) + def test_zero_or_more_optional(self): + parser = argparse.ArgumentParser() + parser.add_argument('x', nargs='*', choices=('x', 'y')) + args = parser.parse_args([]) + self.assertEqual(NS(x=[]), args) + + # =========================== # parse_intermixed_args tests # =========================== diff --git a/Lib/test/test_ast.py b/Lib/test/test_ast.py index b4ec1fef..3ba7cf7b 100644 --- a/Lib/test/test_ast.py +++ b/Lib/test/test_ast.py @@ -3,14 +3,20 @@ import builtins import dis import enum import os +import re import sys +import textwrap import types import unittest import warnings import weakref +from functools import partial from textwrap import dedent from test import support +from test.support.import_helper import import_fresh_module +from test.support import os_helper, script_helper +from test.support.ast_helper import ASTTestMixin def to_tuple(t): if t is None or isinstance(t, (str, int, complex)) or t is Ellipsis: @@ -177,7 +183,22 @@ exec_tests = [ "def f(a=1, /, b=2, *, c): pass", "def f(a=1, /, b=2, *, c=4, **kwargs): pass", "def f(a=1, /, b=2, *, c, **kwargs): pass", - + # Type aliases + "type X = int", + "type X[T] = int", + "type X[T, *Ts, **P] = (T, Ts, P)", + "type X[T: int, *Ts, **P] = (T, Ts, P)", + "type X[T: (int, str), *Ts, **P] = (T, Ts, P)", + # Generic classes + "class X[T]: pass", + "class X[T, *Ts, **P]: pass", + "class X[T: int, *Ts, **P]: pass", + "class X[T: (int, str), *Ts, **P]: pass", + # Generic functions + "def f[T](): pass", + "def f[T, *Ts, **P](): pass", + "def f[T: int, *Ts, **P](): pass", + "def f[T: (int, str), *Ts, **P](): pass", ] # These are compiled through "single" @@ -258,13 +279,13 @@ eval_tests = [ "()", # Combination "a.b.c.d(a.b[1:2])", - ] # TODO: expr_context, slice, boolop, operator, unaryop, cmpop, comprehension # excepthandler, arguments, keywords, alias class AST_Tests(unittest.TestCase): + maxDiff = None def _is_ast_node(self, name, node): if not isinstance(node, type): @@ -433,16 +454,42 @@ class AST_Tests(unittest.TestCase): self.assertTrue(issubclass(ast.comprehension, ast.AST)) self.assertTrue(issubclass(ast.Gt, ast.AST)) + def test_import_deprecated(self): + ast = import_fresh_module('ast') + depr_regex = ( + r'ast\.{} is deprecated and will be removed in Python 3.14; ' + r'use ast\.Constant instead' + ) + for name in 'Num', 'Str', 'Bytes', 'NameConstant', 'Ellipsis': + with self.assertWarnsRegex(DeprecationWarning, depr_regex.format(name)): + getattr(ast, name) + + def test_field_attr_existence_deprecated(self): + with warnings.catch_warnings(): + warnings.filterwarnings('ignore', '', DeprecationWarning) + from ast import Num, Str, Bytes, NameConstant, Ellipsis + + for name in ('Num', 'Str', 'Bytes', 'NameConstant', 'Ellipsis'): + item = getattr(ast, name) + if self._is_ast_node(name, item): + with self.subTest(item): + with self.assertWarns(DeprecationWarning): + x = item() + if isinstance(x, ast.AST): + self.assertIs(type(x._fields), tuple) + def test_field_attr_existence(self): for name, item in ast.__dict__.items(): + # These emit DeprecationWarnings + if name in {'Num', 'Str', 'Bytes', 'NameConstant', 'Ellipsis'}: + continue + # constructor has a different signature + if name == 'Index': + continue if self._is_ast_node(name, item): - if name == 'Index': - # Index(value) just returns value now. - # The argument is required. - continue x = item() if isinstance(x, ast.AST): - self.assertEqual(type(x._fields), tuple) + self.assertIs(type(x._fields), tuple) def test_arguments(self): x = ast.arguments() @@ -457,25 +504,108 @@ class AST_Tests(unittest.TestCase): self.assertEqual(x.args, 2) self.assertEqual(x.vararg, 3) + def test_field_attr_writable_deprecated(self): + with warnings.catch_warnings(): + warnings.filterwarnings('ignore', '', DeprecationWarning) + x = ast.Num() + # We can assign to _fields + x._fields = 666 + self.assertEqual(x._fields, 666) + def test_field_attr_writable(self): - x = ast.Num() + x = ast.Constant() # We can assign to _fields x._fields = 666 self.assertEqual(x._fields, 666) + def test_classattrs_deprecated(self): + with warnings.catch_warnings(): + warnings.filterwarnings('ignore', '', DeprecationWarning) + from ast import Num, Str, Bytes, NameConstant, Ellipsis + + with warnings.catch_warnings(record=True) as wlog: + warnings.filterwarnings('always', '', DeprecationWarning) + x = ast.Num() + self.assertEqual(x._fields, ('value', 'kind')) + + with self.assertRaises(AttributeError): + x.value + + with self.assertRaises(AttributeError): + x.n + + x = ast.Num(42) + self.assertEqual(x.value, 42) + self.assertEqual(x.n, 42) + + with self.assertRaises(AttributeError): + x.lineno + + with self.assertRaises(AttributeError): + x.foobar + + x = ast.Num(lineno=2) + self.assertEqual(x.lineno, 2) + + x = ast.Num(42, lineno=0) + self.assertEqual(x.lineno, 0) + self.assertEqual(x._fields, ('value', 'kind')) + self.assertEqual(x.value, 42) + self.assertEqual(x.n, 42) + + self.assertRaises(TypeError, ast.Num, 1, None, 2) + self.assertRaises(TypeError, ast.Num, 1, None, 2, lineno=0) + + # Arbitrary keyword arguments are supported + self.assertEqual(ast.Num(1, foo='bar').foo, 'bar') + + with self.assertRaisesRegex(TypeError, "Num got multiple values for argument 'n'"): + ast.Num(1, n=2) + + self.assertEqual(ast.Num(42).n, 42) + self.assertEqual(ast.Num(4.25).n, 4.25) + self.assertEqual(ast.Num(4.25j).n, 4.25j) + self.assertEqual(ast.Str('42').s, '42') + self.assertEqual(ast.Bytes(b'42').s, b'42') + self.assertIs(ast.NameConstant(True).value, True) + self.assertIs(ast.NameConstant(False).value, False) + self.assertIs(ast.NameConstant(None).value, None) + + self.assertEqual([str(w.message) for w in wlog], [ + 'ast.Num is deprecated and will be removed in Python 3.14; use ast.Constant instead', + 'Attribute n is deprecated and will be removed in Python 3.14; use value instead', + 'ast.Num is deprecated and will be removed in Python 3.14; use ast.Constant instead', + 'Attribute n is deprecated and will be removed in Python 3.14; use value instead', + 'ast.Num is deprecated and will be removed in Python 3.14; use ast.Constant instead', + 'ast.Num is deprecated and will be removed in Python 3.14; use ast.Constant instead', + 'Attribute n is deprecated and will be removed in Python 3.14; use value instead', + 'ast.Num is deprecated and will be removed in Python 3.14; use ast.Constant instead', + 'ast.Num is deprecated and will be removed in Python 3.14; use ast.Constant instead', + 'ast.Num is deprecated and will be removed in Python 3.14; use ast.Constant instead', + 'ast.Num is deprecated and will be removed in Python 3.14; use ast.Constant instead', + 'Attribute n is deprecated and will be removed in Python 3.14; use value instead', + 'ast.Num is deprecated and will be removed in Python 3.14; use ast.Constant instead', + 'Attribute n is deprecated and will be removed in Python 3.14; use value instead', + 'ast.Num is deprecated and will be removed in Python 3.14; use ast.Constant instead', + 'Attribute n is deprecated and will be removed in Python 3.14; use value instead', + 'ast.Str is deprecated and will be removed in Python 3.14; use ast.Constant instead', + 'Attribute s is deprecated and will be removed in Python 3.14; use value instead', + 'ast.Bytes is deprecated and will be removed in Python 3.14; use ast.Constant instead', + 'Attribute s is deprecated and will be removed in Python 3.14; use value instead', + 'ast.NameConstant is deprecated and will be removed in Python 3.14; use ast.Constant instead', + 'ast.NameConstant is deprecated and will be removed in Python 3.14; use ast.Constant instead', + 'ast.NameConstant is deprecated and will be removed in Python 3.14; use ast.Constant instead', + ]) + def test_classattrs(self): - x = ast.Num() + x = ast.Constant() self.assertEqual(x._fields, ('value', 'kind')) with self.assertRaises(AttributeError): x.value - with self.assertRaises(AttributeError): - x.n - - x = ast.Num(42) + x = ast.Constant(42) self.assertEqual(x.value, 42) - self.assertEqual(x.n, 42) with self.assertRaises(AttributeError): x.lineno @@ -483,36 +613,23 @@ class AST_Tests(unittest.TestCase): with self.assertRaises(AttributeError): x.foobar - x = ast.Num(lineno=2) + x = ast.Constant(lineno=2) self.assertEqual(x.lineno, 2) - x = ast.Num(42, lineno=0) + x = ast.Constant(42, lineno=0) self.assertEqual(x.lineno, 0) self.assertEqual(x._fields, ('value', 'kind')) self.assertEqual(x.value, 42) - self.assertEqual(x.n, 42) - self.assertRaises(TypeError, ast.Num, 1, None, 2) - self.assertRaises(TypeError, ast.Num, 1, None, 2, lineno=0) + self.assertRaises(TypeError, ast.Constant, 1, None, 2) + self.assertRaises(TypeError, ast.Constant, 1, None, 2, lineno=0) # Arbitrary keyword arguments are supported self.assertEqual(ast.Constant(1, foo='bar').foo, 'bar') - self.assertEqual(ast.Num(1, foo='bar').foo, 'bar') - with self.assertRaisesRegex(TypeError, "Num got multiple values for argument 'n'"): - ast.Num(1, n=2) with self.assertRaisesRegex(TypeError, "Constant got multiple values for argument 'value'"): ast.Constant(1, value=2) - self.assertEqual(ast.Num(42).n, 42) - self.assertEqual(ast.Num(4.25).n, 4.25) - self.assertEqual(ast.Num(4.25j).n, 4.25j) - self.assertEqual(ast.Str('42').s, '42') - self.assertEqual(ast.Bytes(b'42').s, b'42') - self.assertIs(ast.NameConstant(True).value, True) - self.assertIs(ast.NameConstant(False).value, False) - self.assertIs(ast.NameConstant(None).value, None) - self.assertEqual(ast.Constant(42).value, 42) self.assertEqual(ast.Constant(4.25).value, 4.25) self.assertEqual(ast.Constant(4.25j).value, 4.25j) @@ -524,85 +641,211 @@ class AST_Tests(unittest.TestCase): self.assertIs(ast.Constant(...).value, ...) def test_realtype(self): - self.assertEqual(type(ast.Num(42)), ast.Constant) - self.assertEqual(type(ast.Num(4.25)), ast.Constant) - self.assertEqual(type(ast.Num(4.25j)), ast.Constant) - self.assertEqual(type(ast.Str('42')), ast.Constant) - self.assertEqual(type(ast.Bytes(b'42')), ast.Constant) - self.assertEqual(type(ast.NameConstant(True)), ast.Constant) - self.assertEqual(type(ast.NameConstant(False)), ast.Constant) - self.assertEqual(type(ast.NameConstant(None)), ast.Constant) - self.assertEqual(type(ast.Ellipsis()), ast.Constant) + with warnings.catch_warnings(): + warnings.filterwarnings('ignore', '', DeprecationWarning) + from ast import Num, Str, Bytes, NameConstant, Ellipsis + + with warnings.catch_warnings(record=True) as wlog: + warnings.filterwarnings('always', '', DeprecationWarning) + self.assertIs(type(ast.Num(42)), ast.Constant) + self.assertIs(type(ast.Num(4.25)), ast.Constant) + self.assertIs(type(ast.Num(4.25j)), ast.Constant) + self.assertIs(type(ast.Str('42')), ast.Constant) + self.assertIs(type(ast.Bytes(b'42')), ast.Constant) + self.assertIs(type(ast.NameConstant(True)), ast.Constant) + self.assertIs(type(ast.NameConstant(False)), ast.Constant) + self.assertIs(type(ast.NameConstant(None)), ast.Constant) + self.assertIs(type(ast.Ellipsis()), ast.Constant) + + self.assertEqual([str(w.message) for w in wlog], [ + 'ast.Num is deprecated and will be removed in Python 3.14; use ast.Constant instead', + 'ast.Num is deprecated and will be removed in Python 3.14; use ast.Constant instead', + 'ast.Num is deprecated and will be removed in Python 3.14; use ast.Constant instead', + 'ast.Str is deprecated and will be removed in Python 3.14; use ast.Constant instead', + 'ast.Bytes is deprecated and will be removed in Python 3.14; use ast.Constant instead', + 'ast.NameConstant is deprecated and will be removed in Python 3.14; use ast.Constant instead', + 'ast.NameConstant is deprecated and will be removed in Python 3.14; use ast.Constant instead', + 'ast.NameConstant is deprecated and will be removed in Python 3.14; use ast.Constant instead', + 'ast.Ellipsis is deprecated and will be removed in Python 3.14; use ast.Constant instead', + ]) def test_isinstance(self): - self.assertTrue(isinstance(ast.Num(42), ast.Num)) - self.assertTrue(isinstance(ast.Num(4.2), ast.Num)) - self.assertTrue(isinstance(ast.Num(4.2j), ast.Num)) - self.assertTrue(isinstance(ast.Str('42'), ast.Str)) - self.assertTrue(isinstance(ast.Bytes(b'42'), ast.Bytes)) - self.assertTrue(isinstance(ast.NameConstant(True), ast.NameConstant)) - self.assertTrue(isinstance(ast.NameConstant(False), ast.NameConstant)) - self.assertTrue(isinstance(ast.NameConstant(None), ast.NameConstant)) - self.assertTrue(isinstance(ast.Ellipsis(), ast.Ellipsis)) - - self.assertTrue(isinstance(ast.Constant(42), ast.Num)) - self.assertTrue(isinstance(ast.Constant(4.2), ast.Num)) - self.assertTrue(isinstance(ast.Constant(4.2j), ast.Num)) - self.assertTrue(isinstance(ast.Constant('42'), ast.Str)) - self.assertTrue(isinstance(ast.Constant(b'42'), ast.Bytes)) - self.assertTrue(isinstance(ast.Constant(True), ast.NameConstant)) - self.assertTrue(isinstance(ast.Constant(False), ast.NameConstant)) - self.assertTrue(isinstance(ast.Constant(None), ast.NameConstant)) - self.assertTrue(isinstance(ast.Constant(...), ast.Ellipsis)) - - self.assertFalse(isinstance(ast.Str('42'), ast.Num)) - self.assertFalse(isinstance(ast.Num(42), ast.Str)) - self.assertFalse(isinstance(ast.Str('42'), ast.Bytes)) - self.assertFalse(isinstance(ast.Num(42), ast.NameConstant)) - self.assertFalse(isinstance(ast.Num(42), ast.Ellipsis)) - self.assertFalse(isinstance(ast.NameConstant(True), ast.Num)) - self.assertFalse(isinstance(ast.NameConstant(False), ast.Num)) - - self.assertFalse(isinstance(ast.Constant('42'), ast.Num)) - self.assertFalse(isinstance(ast.Constant(42), ast.Str)) - self.assertFalse(isinstance(ast.Constant('42'), ast.Bytes)) - self.assertFalse(isinstance(ast.Constant(42), ast.NameConstant)) - self.assertFalse(isinstance(ast.Constant(42), ast.Ellipsis)) - self.assertFalse(isinstance(ast.Constant(True), ast.Num)) - self.assertFalse(isinstance(ast.Constant(False), ast.Num)) - - self.assertFalse(isinstance(ast.Constant(), ast.Num)) - self.assertFalse(isinstance(ast.Constant(), ast.Str)) - self.assertFalse(isinstance(ast.Constant(), ast.Bytes)) - self.assertFalse(isinstance(ast.Constant(), ast.NameConstant)) - self.assertFalse(isinstance(ast.Constant(), ast.Ellipsis)) + from ast import Constant + + with warnings.catch_warnings(): + warnings.filterwarnings('ignore', '', DeprecationWarning) + from ast import Num, Str, Bytes, NameConstant, Ellipsis + + cls_depr_msg = ( + 'ast.{} is deprecated and will be removed in Python 3.14; ' + 'use ast.Constant instead' + ) + + assertNumDeprecated = partial( + self.assertWarnsRegex, DeprecationWarning, cls_depr_msg.format("Num") + ) + assertStrDeprecated = partial( + self.assertWarnsRegex, DeprecationWarning, cls_depr_msg.format("Str") + ) + assertBytesDeprecated = partial( + self.assertWarnsRegex, DeprecationWarning, cls_depr_msg.format("Bytes") + ) + assertNameConstantDeprecated = partial( + self.assertWarnsRegex, + DeprecationWarning, + cls_depr_msg.format("NameConstant") + ) + assertEllipsisDeprecated = partial( + self.assertWarnsRegex, DeprecationWarning, cls_depr_msg.format("Ellipsis") + ) + + for arg in 42, 4.2, 4.2j: + with self.subTest(arg=arg): + with assertNumDeprecated(): + n = Num(arg) + with assertNumDeprecated(): + self.assertIsInstance(n, Num) + + with assertStrDeprecated(): + s = Str('42') + with assertStrDeprecated(): + self.assertIsInstance(s, Str) + + with assertBytesDeprecated(): + b = Bytes(b'42') + with assertBytesDeprecated(): + self.assertIsInstance(b, Bytes) + + for arg in True, False, None: + with self.subTest(arg=arg): + with assertNameConstantDeprecated(): + n = NameConstant(arg) + with assertNameConstantDeprecated(): + self.assertIsInstance(n, NameConstant) + + with assertEllipsisDeprecated(): + e = Ellipsis() + with assertEllipsisDeprecated(): + self.assertIsInstance(e, Ellipsis) + + for arg in 42, 4.2, 4.2j: + with self.subTest(arg=arg): + with assertNumDeprecated(): + self.assertIsInstance(Constant(arg), Num) + + with assertStrDeprecated(): + self.assertIsInstance(Constant('42'), Str) + + with assertBytesDeprecated(): + self.assertIsInstance(Constant(b'42'), Bytes) + + for arg in True, False, None: + with self.subTest(arg=arg): + with assertNameConstantDeprecated(): + self.assertIsInstance(Constant(arg), NameConstant) + + with assertEllipsisDeprecated(): + self.assertIsInstance(Constant(...), Ellipsis) + + with assertStrDeprecated(): + s = Str('42') + assertNumDeprecated(self.assertNotIsInstance, s, Num) + assertBytesDeprecated(self.assertNotIsInstance, s, Bytes) + + with assertNumDeprecated(): + n = Num(42) + assertStrDeprecated(self.assertNotIsInstance, n, Str) + assertNameConstantDeprecated(self.assertNotIsInstance, n, NameConstant) + assertEllipsisDeprecated(self.assertNotIsInstance, n, Ellipsis) + + with assertNameConstantDeprecated(): + n = NameConstant(True) + with assertNumDeprecated(): + self.assertNotIsInstance(n, Num) + + with assertNameConstantDeprecated(): + n = NameConstant(False) + with assertNumDeprecated(): + self.assertNotIsInstance(n, Num) + + for arg in '42', True, False: + with self.subTest(arg=arg): + with assertNumDeprecated(): + self.assertNotIsInstance(Constant(arg), Num) + + assertStrDeprecated(self.assertNotIsInstance, Constant(42), Str) + assertBytesDeprecated(self.assertNotIsInstance, Constant('42'), Bytes) + assertNameConstantDeprecated(self.assertNotIsInstance, Constant(42), NameConstant) + assertEllipsisDeprecated(self.assertNotIsInstance, Constant(42), Ellipsis) + assertNumDeprecated(self.assertNotIsInstance, Constant(), Num) + assertStrDeprecated(self.assertNotIsInstance, Constant(), Str) + assertBytesDeprecated(self.assertNotIsInstance, Constant(), Bytes) + assertNameConstantDeprecated(self.assertNotIsInstance, Constant(), NameConstant) + assertEllipsisDeprecated(self.assertNotIsInstance, Constant(), Ellipsis) class S(str): pass - self.assertTrue(isinstance(ast.Constant(S('42')), ast.Str)) - self.assertFalse(isinstance(ast.Constant(S('42')), ast.Num)) + with assertStrDeprecated(): + self.assertIsInstance(Constant(S('42')), Str) + with assertNumDeprecated(): + self.assertNotIsInstance(Constant(S('42')), Num) + + def test_constant_subclasses_deprecated(self): + with warnings.catch_warnings(): + warnings.filterwarnings('ignore', '', DeprecationWarning) + from ast import Num + + with warnings.catch_warnings(record=True) as wlog: + warnings.filterwarnings('always', '', DeprecationWarning) + class N(ast.Num): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.z = 'spam' + class N2(ast.Num): + pass + + n = N(42) + self.assertEqual(n.n, 42) + self.assertEqual(n.z, 'spam') + self.assertIs(type(n), N) + self.assertIsInstance(n, N) + self.assertIsInstance(n, ast.Num) + self.assertNotIsInstance(n, N2) + self.assertNotIsInstance(ast.Num(42), N) + n = N(n=42) + self.assertEqual(n.n, 42) + self.assertIs(type(n), N) + + self.assertEqual([str(w.message) for w in wlog], [ + 'Attribute n is deprecated and will be removed in Python 3.14; use value instead', + 'Attribute n is deprecated and will be removed in Python 3.14; use value instead', + 'ast.Num is deprecated and will be removed in Python 3.14; use ast.Constant instead', + 'ast.Num is deprecated and will be removed in Python 3.14; use ast.Constant instead', + 'Attribute n is deprecated and will be removed in Python 3.14; use value instead', + 'Attribute n is deprecated and will be removed in Python 3.14; use value instead', + ]) - def test_subclasses(self): - class N(ast.Num): + def test_constant_subclasses(self): + class N(ast.Constant): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.z = 'spam' - class N2(ast.Num): + class N2(ast.Constant): pass n = N(42) - self.assertEqual(n.n, 42) + self.assertEqual(n.value, 42) self.assertEqual(n.z, 'spam') self.assertEqual(type(n), N) self.assertTrue(isinstance(n, N)) - self.assertTrue(isinstance(n, ast.Num)) + self.assertTrue(isinstance(n, ast.Constant)) self.assertFalse(isinstance(n, N2)) - self.assertFalse(isinstance(ast.Num(42), N)) - n = N(n=42) - self.assertEqual(n.n, 42) + self.assertFalse(isinstance(ast.Constant(42), N)) + n = N(value=42) + self.assertEqual(n.value, 42) self.assertEqual(type(n), N) def test_module(self): - body = [ast.Num(42)] + body = [ast.Constant(42)] x = ast.Module(body, []) self.assertEqual(x.body, body) @@ -615,8 +858,8 @@ class AST_Tests(unittest.TestCase): x.foobarbaz = 5 self.assertEqual(x.foobarbaz, 5) - n1 = ast.Num(1) - n3 = ast.Num(3) + n1 = ast.Constant(1) + n3 = ast.Constant(3) addop = ast.Add() x = ast.BinOp(n1, addop, n3) self.assertEqual(x.left, n1) @@ -657,18 +900,11 @@ class AST_Tests(unittest.TestCase): def test_pickling(self): import pickle - mods = [pickle] - try: - import cPickle - mods.append(cPickle) - except ImportError: - pass - protocols = [0, 1, 2] - for mod in mods: - for protocol in protocols: - for ast in (compile(i, "?", "exec", 0x400) for i in exec_tests): - ast2 = mod.loads(mod.dumps(ast, protocol)) - self.assertEqual(to_tuple(ast2), to_tuple(ast)) + + for protocol in range(pickle.HIGHEST_PROTOCOL + 1): + for ast in (compile(i, "?", "exec", 0x400) for i in exec_tests): + ast2 = pickle.loads(pickle.dumps(ast, protocol)) + self.assertEqual(to_tuple(ast2), to_tuple(ast)) def test_invalid_sum(self): pos = dict(lineno=2, col_offset=3) @@ -779,11 +1015,6 @@ class AST_Tests(unittest.TestCase): ast.parse('with (CtxManager() as example): ...', feature_version=(3, 8)) ast.parse('with CtxManager() as example: ...', feature_version=(3, 8)) - def test_debug_f_string_feature_version(self): - ast.parse('f"{x=}"', feature_version=(3, 8)) - with self.assertRaises(SyntaxError): - ast.parse('f"{x=}"', feature_version=(3, 7)) - def test_assignment_expression_feature_version(self): ast.parse('(x := 0)', feature_version=(3, 8)) with self.assertRaises(SyntaxError): @@ -798,6 +1029,24 @@ class AST_Tests(unittest.TestCase): with self.assertRaises(SyntaxError): ast.parse(code, feature_version=(3, 10)) + def test_type_params_feature_version(self): + samples = [ + "type X = int", + "class X[T]: pass", + "def f[T](): pass", + ] + for sample in samples: + with self.subTest(sample): + ast.parse(sample) + with self.assertRaises(SyntaxError): + ast.parse(sample, feature_version=(3, 11)) + + def test_invalid_major_feature_version(self): + with self.assertRaises(ValueError): + ast.parse('pass', feature_version=(2, 7)) + with self.assertRaises(ValueError): + ast.parse('pass', feature_version=(4, 0)) + def test_constant_as_name(self): for constant in "True", "False", "None": expr = ast.Expression(ast.Name(constant, ast.Load())) @@ -835,11 +1084,12 @@ class AST_Tests(unittest.TestCase): return self enum._test_simple_enum(_Precedence, ast._Precedence) + @unittest.skipIf(support.is_wasi, "exhausts limited stack on WASI") @support.cpython_only def test_ast_recursion_limit(self): - fail_depth = sys.getrecursionlimit() * 3 - crash_depth = sys.getrecursionlimit() * 300 - success_depth = int(fail_depth * 0.75) + fail_depth = support.EXCEEDS_RECURSION_LIMIT + crash_depth = 100_000 + success_depth = 1200 def check_limit(prefix, repeated): expect_ok = prefix + repeated * success_depth @@ -857,6 +1107,36 @@ class AST_Tests(unittest.TestCase): check_limit("a", "[0]") check_limit("a", "*a") + def test_null_bytes(self): + with self.assertRaises(SyntaxError, + msg="source code string cannot contain null bytes"): + ast.parse("a\0b") + + def assert_none_check(self, node: type[ast.AST], attr: str, source: str) -> None: + with self.subTest(f"{node.__name__}.{attr}"): + tree = ast.parse(source) + found = 0 + for child in ast.walk(tree): + if isinstance(child, node): + setattr(child, attr, None) + found += 1 + self.assertEqual(found, 1) + e = re.escape(f"field '{attr}' is required for {node.__name__}") + with self.assertRaisesRegex(ValueError, f"^{e}$"): + compile(tree, "<test>", "exec") + + def test_none_checks(self) -> None: + tests = [ + (ast.alias, "name", "import spam as SPAM"), + (ast.arg, "arg", "def spam(SPAM): spam"), + (ast.comprehension, "target", "[spam for SPAM in spam]"), + (ast.comprehension, "iter", "[spam for spam in SPAM]"), + (ast.keyword, "value", "spam(**SPAM)"), + (ast.match_case, "pattern", "match spam:\n case SPAM: spam"), + (ast.withitem, "context_expr", "with SPAM: spam"), + ] + for node, attr, source in tests: + self.assert_none_check(node, attr, source) class ASTHelpers_Test(unittest.TestCase): maxDiff = None @@ -987,7 +1267,7 @@ Module( def test_copy_location(self): src = ast.parse('1 + 1', mode='eval') - src.body.right = ast.copy_location(ast.Num(2), src.body.right) + src.body.right = ast.copy_location(ast.Constant(2), src.body.right) self.assertEqual(ast.dump(src, include_attributes=True), 'Expression(body=BinOp(left=Constant(value=1, lineno=1, col_offset=0, ' 'end_lineno=1, end_col_offset=1), op=Add(), right=Constant(value=2, ' @@ -1004,7 +1284,7 @@ Module( def test_fix_missing_locations(self): src = ast.parse('write("spam")') src.body.append(ast.Expr(ast.Call(ast.Name('spam', ast.Load()), - [ast.Str('eggs')], []))) + [ast.Constant('eggs')], []))) self.assertEqual(src, ast.fix_missing_locations(src)) self.maxDiff = None self.assertEqual(ast.dump(src, include_attributes=True), @@ -1317,9 +1597,9 @@ class ASTValidatorTests(unittest.TestCase): check(arguments(args=args), "must have Load context") check(arguments(posonlyargs=args), "must have Load context") check(arguments(kwonlyargs=args), "must have Load context") - check(arguments(defaults=[ast.Num(3)]), + check(arguments(defaults=[ast.Constant(3)]), "more positional defaults than args") - check(arguments(kw_defaults=[ast.Num(4)]), + check(arguments(kw_defaults=[ast.Constant(4)]), "length of kwonlyargs is not the same as kw_defaults") args = [ast.arg("x", ast.Name("x", ast.Load()))] check(arguments(args=args, defaults=[ast.Name("x", ast.Store())]), @@ -1332,20 +1612,43 @@ class ASTValidatorTests(unittest.TestCase): def test_funcdef(self): a = ast.arguments([], [], None, [], [], None, []) - f = ast.FunctionDef("x", a, [], [], None) + f = ast.FunctionDef("x", a, [], [], None, None, []) self.stmt(f, "empty body on FunctionDef") - f = ast.FunctionDef("x", a, [ast.Pass()], [ast.Name("x", ast.Store())], - None) + f = ast.FunctionDef("x", a, [ast.Pass()], [ast.Name("x", ast.Store())], None, None, []) self.stmt(f, "must have Load context") f = ast.FunctionDef("x", a, [ast.Pass()], [], - ast.Name("x", ast.Store())) + ast.Name("x", ast.Store()), None, []) self.stmt(f, "must have Load context") + f = ast.FunctionDef("x", ast.arguments(), [ast.Pass()]) + self.stmt(f) def fac(args): - return ast.FunctionDef("x", args, [ast.Pass()], [], None) + return ast.FunctionDef("x", args, [ast.Pass()], [], None, None, []) self._check_arguments(fac, self.stmt) + def test_funcdef_pattern_matching(self): + # gh-104799: New fields on FunctionDef should be added at the end + def matcher(node): + match node: + case ast.FunctionDef("foo", ast.arguments(args=[ast.arg("bar")]), + [ast.Pass()], + [ast.Name("capybara", ast.Load())], + ast.Name("pacarana", ast.Load())): + return True + case _: + return False + + code = """ + @capybara + def foo(bar) -> pacarana: + pass + """ + source = ast.parse(textwrap.dedent(code)) + funcdef = source.body[0] + self.assertIsInstance(funcdef, ast.FunctionDef) + self.assertTrue(matcher(funcdef)) + def test_classdef(self): - def cls(bases=None, keywords=None, body=None, decorator_list=None): + def cls(bases=None, keywords=None, body=None, decorator_list=None, type_params=None): if bases is None: bases = [] if keywords is None: @@ -1354,8 +1657,10 @@ class ASTValidatorTests(unittest.TestCase): body = [ast.Pass()] if decorator_list is None: decorator_list = [] + if type_params is None: + type_params = [] return ast.ClassDef("myclass", bases, keywords, - body, decorator_list) + body, decorator_list, type_params) self.stmt(cls(bases=[ast.Name("x", ast.Store())]), "must have Load context") self.stmt(cls(keywords=[ast.keyword("x", ast.Name("x", ast.Store()))]), @@ -1372,9 +1677,9 @@ class ASTValidatorTests(unittest.TestCase): "must have Del context") def test_assign(self): - self.stmt(ast.Assign([], ast.Num(3)), "empty targets on Assign") - self.stmt(ast.Assign([None], ast.Num(3)), "None disallowed") - self.stmt(ast.Assign([ast.Name("x", ast.Load())], ast.Num(3)), + self.stmt(ast.Assign([], ast.Constant(3)), "empty targets on Assign") + self.stmt(ast.Assign([None], ast.Constant(3)), "None disallowed") + self.stmt(ast.Assign([ast.Name("x", ast.Load())], ast.Constant(3)), "must have Store context") self.stmt(ast.Assign([ast.Name("x", ast.Store())], ast.Name("y", ast.Store())), @@ -1402,39 +1707,39 @@ class ASTValidatorTests(unittest.TestCase): self.stmt(ast.For(x, y, [p], [e]), "must have Load context") def test_while(self): - self.stmt(ast.While(ast.Num(3), [], []), "empty body on While") + self.stmt(ast.While(ast.Constant(3), [], []), "empty body on While") self.stmt(ast.While(ast.Name("x", ast.Store()), [ast.Pass()], []), "must have Load context") - self.stmt(ast.While(ast.Num(3), [ast.Pass()], + self.stmt(ast.While(ast.Constant(3), [ast.Pass()], [ast.Expr(ast.Name("x", ast.Store()))]), "must have Load context") def test_if(self): - self.stmt(ast.If(ast.Num(3), [], []), "empty body on If") + self.stmt(ast.If(ast.Constant(3), [], []), "empty body on If") i = ast.If(ast.Name("x", ast.Store()), [ast.Pass()], []) self.stmt(i, "must have Load context") - i = ast.If(ast.Num(3), [ast.Expr(ast.Name("x", ast.Store()))], []) + i = ast.If(ast.Constant(3), [ast.Expr(ast.Name("x", ast.Store()))], []) self.stmt(i, "must have Load context") - i = ast.If(ast.Num(3), [ast.Pass()], + i = ast.If(ast.Constant(3), [ast.Pass()], [ast.Expr(ast.Name("x", ast.Store()))]) self.stmt(i, "must have Load context") def test_with(self): p = ast.Pass() self.stmt(ast.With([], [p]), "empty items on With") - i = ast.withitem(ast.Num(3), None) + i = ast.withitem(ast.Constant(3), None) self.stmt(ast.With([i], []), "empty body on With") i = ast.withitem(ast.Name("x", ast.Store()), None) self.stmt(ast.With([i], [p]), "must have Load context") - i = ast.withitem(ast.Num(3), ast.Name("x", ast.Load())) + i = ast.withitem(ast.Constant(3), ast.Name("x", ast.Load())) self.stmt(ast.With([i], [p]), "must have Store context") def test_raise(self): - r = ast.Raise(None, ast.Num(3)) + r = ast.Raise(None, ast.Constant(3)) self.stmt(r, "Raise with cause but no exception") r = ast.Raise(ast.Name("x", ast.Store()), None) self.stmt(r, "must have Load context") - r = ast.Raise(ast.Num(4), ast.Name("x", ast.Store())) + r = ast.Raise(ast.Constant(4), ast.Name("x", ast.Store())) self.stmt(r, "must have Load context") def test_try(self): @@ -1505,11 +1810,11 @@ class ASTValidatorTests(unittest.TestCase): def test_boolop(self): b = ast.BoolOp(ast.And(), []) self.expr(b, "less than 2 values") - b = ast.BoolOp(ast.And(), [ast.Num(3)]) + b = ast.BoolOp(ast.And(), [ast.Constant(3)]) self.expr(b, "less than 2 values") - b = ast.BoolOp(ast.And(), [ast.Num(4), None]) + b = ast.BoolOp(ast.And(), [ast.Constant(4), None]) self.expr(b, "None disallowed") - b = ast.BoolOp(ast.And(), [ast.Num(4), ast.Name("x", ast.Store())]) + b = ast.BoolOp(ast.And(), [ast.Constant(4), ast.Name("x", ast.Store())]) self.expr(b, "must have Load context") def test_unaryop(self): @@ -1597,11 +1902,11 @@ class ASTValidatorTests(unittest.TestCase): left = ast.Name("x", ast.Load()) comp = ast.Compare(left, [ast.In()], []) self.expr(comp, "no comparators") - comp = ast.Compare(left, [ast.In()], [ast.Num(4), ast.Num(5)]) + comp = ast.Compare(left, [ast.In()], [ast.Constant(4), ast.Constant(5)]) self.expr(comp, "different number of comparators and operands") - comp = ast.Compare(ast.Num("blah"), [ast.In()], [left]) + comp = ast.Compare(ast.Constant("blah"), [ast.In()], [left]) self.expr(comp) - comp = ast.Compare(left, [ast.In()], [ast.Num("blah")]) + comp = ast.Compare(left, [ast.In()], [ast.Constant("blah")]) self.expr(comp) def test_call(self): @@ -1617,23 +1922,37 @@ class ASTValidatorTests(unittest.TestCase): self.expr(call, "must have Load context") def test_num(self): - class subint(int): - pass - class subfloat(float): - pass - class subcomplex(complex): - pass - for obj in "0", "hello": - self.expr(ast.Num(obj)) - for obj in subint(), subfloat(), subcomplex(): - self.expr(ast.Num(obj), "invalid type", exc=TypeError) + with warnings.catch_warnings(record=True) as wlog: + warnings.filterwarnings('ignore', '', DeprecationWarning) + from ast import Num + + with warnings.catch_warnings(record=True) as wlog: + warnings.filterwarnings('always', '', DeprecationWarning) + class subint(int): + pass + class subfloat(float): + pass + class subcomplex(complex): + pass + for obj in "0", "hello": + self.expr(ast.Num(obj)) + for obj in subint(), subfloat(), subcomplex(): + self.expr(ast.Num(obj), "invalid type", exc=TypeError) + + self.assertEqual([str(w.message) for w in wlog], [ + 'ast.Num is deprecated and will be removed in Python 3.14; use ast.Constant instead', + 'ast.Num is deprecated and will be removed in Python 3.14; use ast.Constant instead', + 'ast.Num is deprecated and will be removed in Python 3.14; use ast.Constant instead', + 'ast.Num is deprecated and will be removed in Python 3.14; use ast.Constant instead', + 'ast.Num is deprecated and will be removed in Python 3.14; use ast.Constant instead', + ]) def test_attribute(self): attr = ast.Attribute(ast.Name("x", ast.Store()), "y", ast.Load()) self.expr(attr, "must have Load context") def test_subscript(self): - sub = ast.Subscript(ast.Name("x", ast.Store()), ast.Num(3), + sub = ast.Subscript(ast.Name("x", ast.Store()), ast.Constant(3), ast.Load()) self.expr(sub, "must have Load context") x = ast.Name("x", ast.Load()) @@ -1653,7 +1972,7 @@ class ASTValidatorTests(unittest.TestCase): def test_starred(self): left = ast.List([ast.Starred(ast.Name("x", ast.Load()), ast.Store())], ast.Store()) - assign = ast.Assign([left], ast.Num(4)) + assign = ast.Assign([left], ast.Constant(4)) self.stmt(assign, "must have Store context") def _sequence(self, fac): @@ -1668,8 +1987,19 @@ class ASTValidatorTests(unittest.TestCase): self._sequence(ast.Tuple) def test_nameconstant(self): - self.expr(ast.NameConstant(4)) + with warnings.catch_warnings(record=True) as wlog: + warnings.filterwarnings('ignore', '', DeprecationWarning) + from ast import NameConstant + with warnings.catch_warnings(record=True) as wlog: + warnings.filterwarnings('always', '', DeprecationWarning) + self.expr(ast.NameConstant(4)) + + self.assertEqual([str(w.message) for w in wlog], [ + 'ast.NameConstant is deprecated and will be removed in Python 3.14; use ast.Constant instead', + ]) + + @support.requires_resource('cpu') def test_stdlib_validates(self): stdlib = os.path.dirname(ast.__file__) tests = [fn for fn in os.listdir(stdlib) if fn.endswith(".py")] @@ -1786,6 +2116,12 @@ class ASTValidatorTests(unittest.TestCase): kwd_attrs=[], kwd_patterns=[ast.MatchStar()] ), + ast.MatchClass( + constant_true, # invalid name + patterns=[], + kwd_attrs=['True'], + kwd_patterns=[pattern_1] + ), ast.MatchSequence( [ ast.MatchStar("True") @@ -1896,7 +2232,7 @@ class ConstantTests(unittest.TestCase): co = compile(tree, '<string>', 'exec') consts = [] for instr in dis.get_instructions(co): - if instr.opname == 'LOAD_CONST': + if instr.opname == 'LOAD_CONST' or instr.opname == 'RETURN_CONST': consts.append(instr.argval) return consts @@ -2293,6 +2629,17 @@ class EndPositionTests(unittest.TestCase): cdef = ast.parse(s).body[0] self.assertEqual(ast.get_source_segment(s, cdef.body[0], padded=True), s_method) + def test_source_segment_newlines(self): + s = 'def f():\n pass\ndef g():\r pass\r\ndef h():\r\n pass\r\n' + f, g, h = ast.parse(s).body + self._check_content(s, f, 'def f():\n pass') + self._check_content(s, g, 'def g():\r pass') + self._check_content(s, h, 'def h():\r\n pass') + + s = 'def f():\n a = 1\r b = 2\r\n c = 3\n' + f = ast.parse(s).body[0] + self._check_content(s, f, s.rstrip()) + def test_source_segment_missing_info(self): s = 'v = 1\r\nw = 1\nx = 1\n\ry = 1\r\n' v, w, x, y = ast.parse(s).body @@ -2305,9 +2652,10 @@ class EndPositionTests(unittest.TestCase): self.assertIsNone(ast.get_source_segment(s, x)) self.assertIsNone(ast.get_source_segment(s, y)) -class NodeVisitorTests(unittest.TestCase): +class BaseNodeVisitorCases: + # Both `NodeVisitor` and `NodeTranformer` must raise these warnings: def test_old_constant_nodes(self): - class Visitor(ast.NodeVisitor): + class Visitor(self.visitor_class): def visit_Num(self, node): log.append((node.lineno, 'Num', node.n)) def visit_Str(self, node): @@ -2345,16 +2693,143 @@ class NodeVisitorTests(unittest.TestCase): ]) self.assertEqual([str(w.message) for w in wlog], [ 'visit_Num is deprecated; add visit_Constant', + 'Attribute n is deprecated and will be removed in Python 3.14; use value instead', 'visit_Num is deprecated; add visit_Constant', + 'Attribute n is deprecated and will be removed in Python 3.14; use value instead', 'visit_Num is deprecated; add visit_Constant', + 'Attribute n is deprecated and will be removed in Python 3.14; use value instead', 'visit_Str is deprecated; add visit_Constant', + 'Attribute s is deprecated and will be removed in Python 3.14; use value instead', 'visit_Bytes is deprecated; add visit_Constant', + 'Attribute s is deprecated and will be removed in Python 3.14; use value instead', 'visit_NameConstant is deprecated; add visit_Constant', 'visit_NameConstant is deprecated; add visit_Constant', 'visit_Ellipsis is deprecated; add visit_Constant', ]) +class NodeVisitorTests(BaseNodeVisitorCases, unittest.TestCase): + visitor_class = ast.NodeVisitor + + +class NodeTransformerTests(ASTTestMixin, BaseNodeVisitorCases, unittest.TestCase): + visitor_class = ast.NodeTransformer + + def assertASTTransformation(self, tranformer_class, + initial_code, expected_code): + initial_ast = ast.parse(dedent(initial_code)) + expected_ast = ast.parse(dedent(expected_code)) + + tranformer = tranformer_class() + result_ast = ast.fix_missing_locations(tranformer.visit(initial_ast)) + + self.assertASTEqual(result_ast, expected_ast) + + def test_node_remove_single(self): + code = 'def func(arg) -> SomeType: ...' + expected = 'def func(arg): ...' + + # Since `FunctionDef.returns` is defined as a single value, we test + # the `if isinstance(old_value, AST):` branch here. + class SomeTypeRemover(ast.NodeTransformer): + def visit_Name(self, node: ast.Name): + self.generic_visit(node) + if node.id == 'SomeType': + return None + return node + + self.assertASTTransformation(SomeTypeRemover, code, expected) + + def test_node_remove_from_list(self): + code = """ + def func(arg): + print(arg) + yield arg + """ + expected = """ + def func(arg): + print(arg) + """ + + # Since `FunctionDef.body` is defined as a list, we test + # the `if isinstance(old_value, list):` branch here. + class YieldRemover(ast.NodeTransformer): + def visit_Expr(self, node: ast.Expr): + self.generic_visit(node) + if isinstance(node.value, ast.Yield): + return None # Remove `yield` from a function + return node + + self.assertASTTransformation(YieldRemover, code, expected) + + def test_node_return_list(self): + code = """ + class DSL(Base, kw1=True): ... + """ + expected = """ + class DSL(Base, kw1=True, kw2=True, kw3=False): ... + """ + + class ExtendKeywords(ast.NodeTransformer): + def visit_keyword(self, node: ast.keyword): + self.generic_visit(node) + if node.arg == 'kw1': + return [ + node, + ast.keyword('kw2', ast.Constant(True)), + ast.keyword('kw3', ast.Constant(False)), + ] + return node + + self.assertASTTransformation(ExtendKeywords, code, expected) + + def test_node_mutate(self): + code = """ + def func(arg): + print(arg) + """ + expected = """ + def func(arg): + log(arg) + """ + + class PrintToLog(ast.NodeTransformer): + def visit_Call(self, node: ast.Call): + self.generic_visit(node) + if isinstance(node.func, ast.Name) and node.func.id == 'print': + node.func.id = 'log' + return node + + self.assertASTTransformation(PrintToLog, code, expected) + + def test_node_replace(self): + code = """ + def func(arg): + print(arg) + """ + expected = """ + def func(arg): + logger.log(arg, debug=True) + """ + + class PrintToLog(ast.NodeTransformer): + def visit_Call(self, node: ast.Call): + self.generic_visit(node) + if isinstance(node.func, ast.Name) and node.func.id == 'print': + return ast.Call( + func=ast.Attribute( + ast.Name('logger', ctx=ast.Load()), + attr='log', + ctx=ast.Load(), + ), + args=node.args, + keywords=[ast.keyword('debug', ast.Constant(True))], + ) + return node + + self.assertASTTransformation(PrintToLog, code, expected) + + @support.cpython_only class ModuleStateTests(unittest.TestCase): # bpo-41194, bpo-41261, bpo-41631: The _ast module uses a global state. @@ -2437,6 +2912,25 @@ class ModuleStateTests(unittest.TestCase): self.assertEqual(res, 0) +class ASTMainTests(unittest.TestCase): + # Tests `ast.main()` function. + + def test_cli_file_input(self): + code = "print(1, 2, 3)" + expected = ast.dump(ast.parse(code), indent=3) + + with os_helper.temp_dir() as tmp_dir: + filename = os.path.join(tmp_dir, "test_module.py") + with open(filename, 'w', encoding='utf-8') as f: + f.write(code) + res, _ = script_helper.run_python_until_end("-m", "ast", filename) + + self.assertEqual(res.err, b"") + self.assertEqual(expected.splitlines(), + res.out.decode("utf8").splitlines()) + self.assertEqual(res.rc, 0) + + def main(): if __name__ != '__main__': return @@ -2456,23 +2950,23 @@ def main(): exec_results = [ ('Module', [('Expr', (1, 0, 1, 4), ('Constant', (1, 0, 1, 4), None, None))], []), ('Module', [('Expr', (1, 0, 1, 18), ('Constant', (1, 0, 1, 18), 'module docstring', None))], []), -('Module', [('FunctionDef', (1, 0, 1, 13), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (1, 9, 1, 13))], [], None, None)], []), -('Module', [('FunctionDef', (1, 0, 1, 29), 'f', ('arguments', [], [], None, [], [], None, []), [('Expr', (1, 9, 1, 29), ('Constant', (1, 9, 1, 29), 'function docstring', None))], [], None, None)], []), -('Module', [('FunctionDef', (1, 0, 1, 14), 'f', ('arguments', [], [('arg', (1, 6, 1, 7), 'a', None, None)], None, [], [], None, []), [('Pass', (1, 10, 1, 14))], [], None, None)], []), -('Module', [('FunctionDef', (1, 0, 1, 16), 'f', ('arguments', [], [('arg', (1, 6, 1, 7), 'a', None, None)], None, [], [], None, [('Constant', (1, 8, 1, 9), 0, None)]), [('Pass', (1, 12, 1, 16))], [], None, None)], []), -('Module', [('FunctionDef', (1, 0, 1, 18), 'f', ('arguments', [], [], ('arg', (1, 7, 1, 11), 'args', None, None), [], [], None, []), [('Pass', (1, 14, 1, 18))], [], None, None)], []), -('Module', [('FunctionDef', (1, 0, 1, 23), 'f', ('arguments', [], [], ('arg', (1, 7, 1, 16), 'args', ('Starred', (1, 13, 1, 16), ('Name', (1, 14, 1, 16), 'Ts', ('Load',)), ('Load',)), None), [], [], None, []), [('Pass', (1, 19, 1, 23))], [], None, None)], []), -('Module', [('FunctionDef', (1, 0, 1, 36), 'f', ('arguments', [], [], ('arg', (1, 7, 1, 29), 'args', ('Starred', (1, 13, 1, 29), ('Subscript', (1, 14, 1, 29), ('Name', (1, 14, 1, 19), 'tuple', ('Load',)), ('Tuple', (1, 20, 1, 28), [('Name', (1, 20, 1, 23), 'int', ('Load',)), ('Constant', (1, 25, 1, 28), Ellipsis, None)], ('Load',)), ('Load',)), ('Load',)), None), [], [], None, []), [('Pass', (1, 32, 1, 36))], [], None, None)], []), -('Module', [('FunctionDef', (1, 0, 1, 36), 'f', ('arguments', [], [], ('arg', (1, 7, 1, 29), 'args', ('Starred', (1, 13, 1, 29), ('Subscript', (1, 14, 1, 29), ('Name', (1, 14, 1, 19), 'tuple', ('Load',)), ('Tuple', (1, 20, 1, 28), [('Name', (1, 20, 1, 23), 'int', ('Load',)), ('Starred', (1, 25, 1, 28), ('Name', (1, 26, 1, 28), 'Ts', ('Load',)), ('Load',))], ('Load',)), ('Load',)), ('Load',)), None), [], [], None, []), [('Pass', (1, 32, 1, 36))], [], None, None)], []), -('Module', [('FunctionDef', (1, 0, 1, 21), 'f', ('arguments', [], [], None, [], [], ('arg', (1, 8, 1, 14), 'kwargs', None, None), []), [('Pass', (1, 17, 1, 21))], [], None, None)], []), -('Module', [('FunctionDef', (1, 0, 1, 71), 'f', ('arguments', [], [('arg', (1, 6, 1, 7), 'a', None, None), ('arg', (1, 9, 1, 10), 'b', None, None), ('arg', (1, 14, 1, 15), 'c', None, None), ('arg', (1, 22, 1, 23), 'd', None, None), ('arg', (1, 28, 1, 29), 'e', None, None)], ('arg', (1, 35, 1, 39), 'args', None, None), [('arg', (1, 41, 1, 42), 'f', None, None)], [('Constant', (1, 43, 1, 45), 42, None)], ('arg', (1, 49, 1, 55), 'kwargs', None, None), [('Constant', (1, 11, 1, 12), 1, None), ('Constant', (1, 16, 1, 20), None, None), ('List', (1, 24, 1, 26), [], ('Load',)), ('Dict', (1, 30, 1, 32), [], [])]), [('Expr', (1, 58, 1, 71), ('Constant', (1, 58, 1, 71), 'doc for f()', None))], [], None, None)], []), -('Module', [('FunctionDef', (1, 0, 1, 27), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (1, 23, 1, 27))], [], ('Subscript', (1, 11, 1, 21), ('Name', (1, 11, 1, 16), 'tuple', ('Load',)), ('Tuple', (1, 17, 1, 20), [('Starred', (1, 17, 1, 20), ('Name', (1, 18, 1, 20), 'Ts', ('Load',)), ('Load',))], ('Load',)), ('Load',)), None)], []), -('Module', [('FunctionDef', (1, 0, 1, 32), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (1, 28, 1, 32))], [], ('Subscript', (1, 11, 1, 26), ('Name', (1, 11, 1, 16), 'tuple', ('Load',)), ('Tuple', (1, 17, 1, 25), [('Name', (1, 17, 1, 20), 'int', ('Load',)), ('Starred', (1, 22, 1, 25), ('Name', (1, 23, 1, 25), 'Ts', ('Load',)), ('Load',))], ('Load',)), ('Load',)), None)], []), -('Module', [('FunctionDef', (1, 0, 1, 45), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (1, 41, 1, 45))], [], ('Subscript', (1, 11, 1, 39), ('Name', (1, 11, 1, 16), 'tuple', ('Load',)), ('Tuple', (1, 17, 1, 38), [('Name', (1, 17, 1, 20), 'int', ('Load',)), ('Starred', (1, 22, 1, 38), ('Subscript', (1, 23, 1, 38), ('Name', (1, 23, 1, 28), 'tuple', ('Load',)), ('Tuple', (1, 29, 1, 37), [('Name', (1, 29, 1, 32), 'int', ('Load',)), ('Constant', (1, 34, 1, 37), Ellipsis, None)], ('Load',)), ('Load',)), ('Load',))], ('Load',)), ('Load',)), None)], []), -('Module', [('ClassDef', (1, 0, 1, 12), 'C', [], [], [('Pass', (1, 8, 1, 12))], [])], []), -('Module', [('ClassDef', (1, 0, 1, 32), 'C', [], [], [('Expr', (1, 9, 1, 32), ('Constant', (1, 9, 1, 32), 'docstring for class C', None))], [])], []), -('Module', [('ClassDef', (1, 0, 1, 21), 'C', [('Name', (1, 8, 1, 14), 'object', ('Load',))], [], [('Pass', (1, 17, 1, 21))], [])], []), -('Module', [('FunctionDef', (1, 0, 1, 16), 'f', ('arguments', [], [], None, [], [], None, []), [('Return', (1, 8, 1, 16), ('Constant', (1, 15, 1, 16), 1, None))], [], None, None)], []), +('Module', [('FunctionDef', (1, 0, 1, 13), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (1, 9, 1, 13))], [], None, None, [])], []), +('Module', [('FunctionDef', (1, 0, 1, 29), 'f', ('arguments', [], [], None, [], [], None, []), [('Expr', (1, 9, 1, 29), ('Constant', (1, 9, 1, 29), 'function docstring', None))], [], None, None, [])], []), +('Module', [('FunctionDef', (1, 0, 1, 14), 'f', ('arguments', [], [('arg', (1, 6, 1, 7), 'a', None, None)], None, [], [], None, []), [('Pass', (1, 10, 1, 14))], [], None, None, [])], []), +('Module', [('FunctionDef', (1, 0, 1, 16), 'f', ('arguments', [], [('arg', (1, 6, 1, 7), 'a', None, None)], None, [], [], None, [('Constant', (1, 8, 1, 9), 0, None)]), [('Pass', (1, 12, 1, 16))], [], None, None, [])], []), +('Module', [('FunctionDef', (1, 0, 1, 18), 'f', ('arguments', [], [], ('arg', (1, 7, 1, 11), 'args', None, None), [], [], None, []), [('Pass', (1, 14, 1, 18))], [], None, None, [])], []), +('Module', [('FunctionDef', (1, 0, 1, 23), 'f', ('arguments', [], [], ('arg', (1, 7, 1, 16), 'args', ('Starred', (1, 13, 1, 16), ('Name', (1, 14, 1, 16), 'Ts', ('Load',)), ('Load',)), None), [], [], None, []), [('Pass', (1, 19, 1, 23))], [], None, None, [])], []), +('Module', [('FunctionDef', (1, 0, 1, 36), 'f', ('arguments', [], [], ('arg', (1, 7, 1, 29), 'args', ('Starred', (1, 13, 1, 29), ('Subscript', (1, 14, 1, 29), ('Name', (1, 14, 1, 19), 'tuple', ('Load',)), ('Tuple', (1, 20, 1, 28), [('Name', (1, 20, 1, 23), 'int', ('Load',)), ('Constant', (1, 25, 1, 28), Ellipsis, None)], ('Load',)), ('Load',)), ('Load',)), None), [], [], None, []), [('Pass', (1, 32, 1, 36))], [], None, None, [])], []), +('Module', [('FunctionDef', (1, 0, 1, 36), 'f', ('arguments', [], [], ('arg', (1, 7, 1, 29), 'args', ('Starred', (1, 13, 1, 29), ('Subscript', (1, 14, 1, 29), ('Name', (1, 14, 1, 19), 'tuple', ('Load',)), ('Tuple', (1, 20, 1, 28), [('Name', (1, 20, 1, 23), 'int', ('Load',)), ('Starred', (1, 25, 1, 28), ('Name', (1, 26, 1, 28), 'Ts', ('Load',)), ('Load',))], ('Load',)), ('Load',)), ('Load',)), None), [], [], None, []), [('Pass', (1, 32, 1, 36))], [], None, None, [])], []), +('Module', [('FunctionDef', (1, 0, 1, 21), 'f', ('arguments', [], [], None, [], [], ('arg', (1, 8, 1, 14), 'kwargs', None, None), []), [('Pass', (1, 17, 1, 21))], [], None, None, [])], []), +('Module', [('FunctionDef', (1, 0, 1, 71), 'f', ('arguments', [], [('arg', (1, 6, 1, 7), 'a', None, None), ('arg', (1, 9, 1, 10), 'b', None, None), ('arg', (1, 14, 1, 15), 'c', None, None), ('arg', (1, 22, 1, 23), 'd', None, None), ('arg', (1, 28, 1, 29), 'e', None, None)], ('arg', (1, 35, 1, 39), 'args', None, None), [('arg', (1, 41, 1, 42), 'f', None, None)], [('Constant', (1, 43, 1, 45), 42, None)], ('arg', (1, 49, 1, 55), 'kwargs', None, None), [('Constant', (1, 11, 1, 12), 1, None), ('Constant', (1, 16, 1, 20), None, None), ('List', (1, 24, 1, 26), [], ('Load',)), ('Dict', (1, 30, 1, 32), [], [])]), [('Expr', (1, 58, 1, 71), ('Constant', (1, 58, 1, 71), 'doc for f()', None))], [], None, None, [])], []), +('Module', [('FunctionDef', (1, 0, 1, 27), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (1, 23, 1, 27))], [], ('Subscript', (1, 11, 1, 21), ('Name', (1, 11, 1, 16), 'tuple', ('Load',)), ('Tuple', (1, 17, 1, 20), [('Starred', (1, 17, 1, 20), ('Name', (1, 18, 1, 20), 'Ts', ('Load',)), ('Load',))], ('Load',)), ('Load',)), None, [])], []), +('Module', [('FunctionDef', (1, 0, 1, 32), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (1, 28, 1, 32))], [], ('Subscript', (1, 11, 1, 26), ('Name', (1, 11, 1, 16), 'tuple', ('Load',)), ('Tuple', (1, 17, 1, 25), [('Name', (1, 17, 1, 20), 'int', ('Load',)), ('Starred', (1, 22, 1, 25), ('Name', (1, 23, 1, 25), 'Ts', ('Load',)), ('Load',))], ('Load',)), ('Load',)), None, [])], []), +('Module', [('FunctionDef', (1, 0, 1, 45), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (1, 41, 1, 45))], [], ('Subscript', (1, 11, 1, 39), ('Name', (1, 11, 1, 16), 'tuple', ('Load',)), ('Tuple', (1, 17, 1, 38), [('Name', (1, 17, 1, 20), 'int', ('Load',)), ('Starred', (1, 22, 1, 38), ('Subscript', (1, 23, 1, 38), ('Name', (1, 23, 1, 28), 'tuple', ('Load',)), ('Tuple', (1, 29, 1, 37), [('Name', (1, 29, 1, 32), 'int', ('Load',)), ('Constant', (1, 34, 1, 37), Ellipsis, None)], ('Load',)), ('Load',)), ('Load',))], ('Load',)), ('Load',)), None, [])], []), +('Module', [('ClassDef', (1, 0, 1, 12), 'C', [], [], [('Pass', (1, 8, 1, 12))], [], [])], []), +('Module', [('ClassDef', (1, 0, 1, 32), 'C', [], [], [('Expr', (1, 9, 1, 32), ('Constant', (1, 9, 1, 32), 'docstring for class C', None))], [], [])], []), +('Module', [('ClassDef', (1, 0, 1, 21), 'C', [('Name', (1, 8, 1, 14), 'object', ('Load',))], [], [('Pass', (1, 17, 1, 21))], [], [])], []), +('Module', [('FunctionDef', (1, 0, 1, 16), 'f', ('arguments', [], [], None, [], [], None, []), [('Return', (1, 8, 1, 16), ('Constant', (1, 15, 1, 16), 1, None))], [], None, None, [])], []), ('Module', [('Delete', (1, 0, 1, 5), [('Name', (1, 4, 1, 5), 'v', ('Del',))])], []), ('Module', [('Assign', (1, 0, 1, 5), [('Name', (1, 0, 1, 1), 'v', ('Store',))], ('Constant', (1, 4, 1, 5), 1, None), None)], []), ('Module', [('Assign', (1, 0, 1, 7), [('Tuple', (1, 0, 1, 3), [('Name', (1, 0, 1, 1), 'a', ('Store',)), ('Name', (1, 2, 1, 3), 'b', ('Store',))], ('Store',))], ('Name', (1, 6, 1, 7), 'c', ('Load',)), None)], []), @@ -2509,28 +3003,41 @@ exec_results = [ ('Module', [('Expr', (1, 0, 1, 20), ('DictComp', (1, 0, 1, 20), ('Name', (1, 1, 1, 2), 'a', ('Load',)), ('Name', (1, 5, 1, 6), 'b', ('Load',)), [('comprehension', ('Tuple', (1, 11, 1, 14), [('Name', (1, 11, 1, 12), 'v', ('Store',)), ('Name', (1, 13, 1, 14), 'w', ('Store',))], ('Store',)), ('Name', (1, 18, 1, 19), 'x', ('Load',)), [], 0)]))], []), ('Module', [('Expr', (1, 0, 1, 19), ('SetComp', (1, 0, 1, 19), ('Name', (1, 1, 1, 2), 'r', ('Load',)), [('comprehension', ('Name', (1, 7, 1, 8), 'l', ('Store',)), ('Name', (1, 12, 1, 13), 'x', ('Load',)), [('Name', (1, 17, 1, 18), 'g', ('Load',))], 0)]))], []), ('Module', [('Expr', (1, 0, 1, 16), ('SetComp', (1, 0, 1, 16), ('Name', (1, 1, 1, 2), 'r', ('Load',)), [('comprehension', ('Tuple', (1, 7, 1, 10), [('Name', (1, 7, 1, 8), 'l', ('Store',)), ('Name', (1, 9, 1, 10), 'm', ('Store',))], ('Store',)), ('Name', (1, 14, 1, 15), 'x', ('Load',)), [], 0)]))], []), -('Module', [('AsyncFunctionDef', (1, 0, 3, 18), 'f', ('arguments', [], [], None, [], [], None, []), [('Expr', (2, 1, 2, 17), ('Constant', (2, 1, 2, 17), 'async function', None)), ('Expr', (3, 1, 3, 18), ('Await', (3, 1, 3, 18), ('Call', (3, 7, 3, 18), ('Name', (3, 7, 3, 16), 'something', ('Load',)), [], [])))], [], None, None)], []), -('Module', [('AsyncFunctionDef', (1, 0, 3, 8), 'f', ('arguments', [], [], None, [], [], None, []), [('AsyncFor', (2, 1, 3, 8), ('Name', (2, 11, 2, 12), 'e', ('Store',)), ('Name', (2, 16, 2, 17), 'i', ('Load',)), [('Expr', (2, 19, 2, 20), ('Constant', (2, 19, 2, 20), 1, None))], [('Expr', (3, 7, 3, 8), ('Constant', (3, 7, 3, 8), 2, None))], None)], [], None, None)], []), -('Module', [('AsyncFunctionDef', (1, 0, 2, 21), 'f', ('arguments', [], [], None, [], [], None, []), [('AsyncWith', (2, 1, 2, 21), [('withitem', ('Name', (2, 12, 2, 13), 'a', ('Load',)), ('Name', (2, 17, 2, 18), 'b', ('Store',)))], [('Expr', (2, 20, 2, 21), ('Constant', (2, 20, 2, 21), 1, None))], None)], [], None, None)], []), +('Module', [('AsyncFunctionDef', (1, 0, 3, 18), 'f', ('arguments', [], [], None, [], [], None, []), [('Expr', (2, 1, 2, 17), ('Constant', (2, 1, 2, 17), 'async function', None)), ('Expr', (3, 1, 3, 18), ('Await', (3, 1, 3, 18), ('Call', (3, 7, 3, 18), ('Name', (3, 7, 3, 16), 'something', ('Load',)), [], [])))], [], None, None, [])], []), +('Module', [('AsyncFunctionDef', (1, 0, 3, 8), 'f', ('arguments', [], [], None, [], [], None, []), [('AsyncFor', (2, 1, 3, 8), ('Name', (2, 11, 2, 12), 'e', ('Store',)), ('Name', (2, 16, 2, 17), 'i', ('Load',)), [('Expr', (2, 19, 2, 20), ('Constant', (2, 19, 2, 20), 1, None))], [('Expr', (3, 7, 3, 8), ('Constant', (3, 7, 3, 8), 2, None))], None)], [], None, None, [])], []), +('Module', [('AsyncFunctionDef', (1, 0, 2, 21), 'f', ('arguments', [], [], None, [], [], None, []), [('AsyncWith', (2, 1, 2, 21), [('withitem', ('Name', (2, 12, 2, 13), 'a', ('Load',)), ('Name', (2, 17, 2, 18), 'b', ('Store',)))], [('Expr', (2, 20, 2, 21), ('Constant', (2, 20, 2, 21), 1, None))], None)], [], None, None, [])], []), ('Module', [('Expr', (1, 0, 1, 14), ('Dict', (1, 0, 1, 14), [None, ('Constant', (1, 10, 1, 11), 2, None)], [('Dict', (1, 3, 1, 8), [('Constant', (1, 4, 1, 5), 1, None)], [('Constant', (1, 6, 1, 7), 2, None)]), ('Constant', (1, 12, 1, 13), 3, None)]))], []), ('Module', [('Expr', (1, 0, 1, 12), ('Set', (1, 0, 1, 12), [('Starred', (1, 1, 1, 8), ('Set', (1, 2, 1, 8), [('Constant', (1, 3, 1, 4), 1, None), ('Constant', (1, 6, 1, 7), 2, None)]), ('Load',)), ('Constant', (1, 10, 1, 11), 3, None)]))], []), -('Module', [('AsyncFunctionDef', (1, 0, 2, 21), 'f', ('arguments', [], [], None, [], [], None, []), [('Expr', (2, 1, 2, 21), ('ListComp', (2, 1, 2, 21), ('Name', (2, 2, 2, 3), 'i', ('Load',)), [('comprehension', ('Name', (2, 14, 2, 15), 'b', ('Store',)), ('Name', (2, 19, 2, 20), 'c', ('Load',)), [], 1)]))], [], None, None)], []), -('Module', [('FunctionDef', (4, 0, 4, 13), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (4, 9, 4, 13))], [('Name', (1, 1, 1, 6), 'deco1', ('Load',)), ('Call', (2, 1, 2, 8), ('Name', (2, 1, 2, 6), 'deco2', ('Load',)), [], []), ('Call', (3, 1, 3, 9), ('Name', (3, 1, 3, 6), 'deco3', ('Load',)), [('Constant', (3, 7, 3, 8), 1, None)], [])], None, None)], []), -('Module', [('AsyncFunctionDef', (4, 0, 4, 19), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (4, 15, 4, 19))], [('Name', (1, 1, 1, 6), 'deco1', ('Load',)), ('Call', (2, 1, 2, 8), ('Name', (2, 1, 2, 6), 'deco2', ('Load',)), [], []), ('Call', (3, 1, 3, 9), ('Name', (3, 1, 3, 6), 'deco3', ('Load',)), [('Constant', (3, 7, 3, 8), 1, None)], [])], None, None)], []), -('Module', [('ClassDef', (4, 0, 4, 13), 'C', [], [], [('Pass', (4, 9, 4, 13))], [('Name', (1, 1, 1, 6), 'deco1', ('Load',)), ('Call', (2, 1, 2, 8), ('Name', (2, 1, 2, 6), 'deco2', ('Load',)), [], []), ('Call', (3, 1, 3, 9), ('Name', (3, 1, 3, 6), 'deco3', ('Load',)), [('Constant', (3, 7, 3, 8), 1, None)], [])])], []), -('Module', [('FunctionDef', (2, 0, 2, 13), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (2, 9, 2, 13))], [('Call', (1, 1, 1, 19), ('Name', (1, 1, 1, 5), 'deco', ('Load',)), [('GeneratorExp', (1, 5, 1, 19), ('Name', (1, 6, 1, 7), 'a', ('Load',)), [('comprehension', ('Name', (1, 12, 1, 13), 'a', ('Store',)), ('Name', (1, 17, 1, 18), 'b', ('Load',)), [], 0)])], [])], None, None)], []), -('Module', [('FunctionDef', (2, 0, 2, 13), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (2, 9, 2, 13))], [('Attribute', (1, 1, 1, 6), ('Attribute', (1, 1, 1, 4), ('Name', (1, 1, 1, 2), 'a', ('Load',)), 'b', ('Load',)), 'c', ('Load',))], None, None)], []), +('Module', [('AsyncFunctionDef', (1, 0, 2, 21), 'f', ('arguments', [], [], None, [], [], None, []), [('Expr', (2, 1, 2, 21), ('ListComp', (2, 1, 2, 21), ('Name', (2, 2, 2, 3), 'i', ('Load',)), [('comprehension', ('Name', (2, 14, 2, 15), 'b', ('Store',)), ('Name', (2, 19, 2, 20), 'c', ('Load',)), [], 1)]))], [], None, None, [])], []), +('Module', [('FunctionDef', (4, 0, 4, 13), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (4, 9, 4, 13))], [('Name', (1, 1, 1, 6), 'deco1', ('Load',)), ('Call', (2, 1, 2, 8), ('Name', (2, 1, 2, 6), 'deco2', ('Load',)), [], []), ('Call', (3, 1, 3, 9), ('Name', (3, 1, 3, 6), 'deco3', ('Load',)), [('Constant', (3, 7, 3, 8), 1, None)], [])], None, None, [])], []), +('Module', [('AsyncFunctionDef', (4, 0, 4, 19), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (4, 15, 4, 19))], [('Name', (1, 1, 1, 6), 'deco1', ('Load',)), ('Call', (2, 1, 2, 8), ('Name', (2, 1, 2, 6), 'deco2', ('Load',)), [], []), ('Call', (3, 1, 3, 9), ('Name', (3, 1, 3, 6), 'deco3', ('Load',)), [('Constant', (3, 7, 3, 8), 1, None)], [])], None, None, [])], []), +('Module', [('ClassDef', (4, 0, 4, 13), 'C', [], [], [('Pass', (4, 9, 4, 13))], [('Name', (1, 1, 1, 6), 'deco1', ('Load',)), ('Call', (2, 1, 2, 8), ('Name', (2, 1, 2, 6), 'deco2', ('Load',)), [], []), ('Call', (3, 1, 3, 9), ('Name', (3, 1, 3, 6), 'deco3', ('Load',)), [('Constant', (3, 7, 3, 8), 1, None)], [])], [])], []), +('Module', [('FunctionDef', (2, 0, 2, 13), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (2, 9, 2, 13))], [('Call', (1, 1, 1, 19), ('Name', (1, 1, 1, 5), 'deco', ('Load',)), [('GeneratorExp', (1, 5, 1, 19), ('Name', (1, 6, 1, 7), 'a', ('Load',)), [('comprehension', ('Name', (1, 12, 1, 13), 'a', ('Store',)), ('Name', (1, 17, 1, 18), 'b', ('Load',)), [], 0)])], [])], None, None, [])], []), +('Module', [('FunctionDef', (2, 0, 2, 13), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (2, 9, 2, 13))], [('Attribute', (1, 1, 1, 6), ('Attribute', (1, 1, 1, 4), ('Name', (1, 1, 1, 2), 'a', ('Load',)), 'b', ('Load',)), 'c', ('Load',))], None, None, [])], []), ('Module', [('Expr', (1, 0, 1, 8), ('NamedExpr', (1, 1, 1, 7), ('Name', (1, 1, 1, 2), 'a', ('Store',)), ('Constant', (1, 6, 1, 7), 1, None)))], []), -('Module', [('FunctionDef', (1, 0, 1, 18), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [], None, [], [], None, []), [('Pass', (1, 14, 1, 18))], [], None, None)], []), -('Module', [('FunctionDef', (1, 0, 1, 26), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [('arg', (1, 12, 1, 13), 'c', None, None), ('arg', (1, 15, 1, 16), 'd', None, None), ('arg', (1, 18, 1, 19), 'e', None, None)], None, [], [], None, []), [('Pass', (1, 22, 1, 26))], [], None, None)], []), -('Module', [('FunctionDef', (1, 0, 1, 29), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [('arg', (1, 12, 1, 13), 'c', None, None)], None, [('arg', (1, 18, 1, 19), 'd', None, None), ('arg', (1, 21, 1, 22), 'e', None, None)], [None, None], None, []), [('Pass', (1, 25, 1, 29))], [], None, None)], []), -('Module', [('FunctionDef', (1, 0, 1, 39), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [('arg', (1, 12, 1, 13), 'c', None, None)], None, [('arg', (1, 18, 1, 19), 'd', None, None), ('arg', (1, 21, 1, 22), 'e', None, None)], [None, None], ('arg', (1, 26, 1, 32), 'kwargs', None, None), []), [('Pass', (1, 35, 1, 39))], [], None, None)], []), -('Module', [('FunctionDef', (1, 0, 1, 20), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [], None, [], [], None, [('Constant', (1, 8, 1, 9), 1, None)]), [('Pass', (1, 16, 1, 20))], [], None, None)], []), -('Module', [('FunctionDef', (1, 0, 1, 29), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [('arg', (1, 14, 1, 15), 'b', None, None), ('arg', (1, 19, 1, 20), 'c', None, None)], None, [], [], None, [('Constant', (1, 8, 1, 9), 1, None), ('Constant', (1, 16, 1, 17), 2, None), ('Constant', (1, 21, 1, 22), 4, None)]), [('Pass', (1, 25, 1, 29))], [], None, None)], []), -('Module', [('FunctionDef', (1, 0, 1, 32), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [('arg', (1, 14, 1, 15), 'b', None, None)], None, [('arg', (1, 22, 1, 23), 'c', None, None)], [('Constant', (1, 24, 1, 25), 4, None)], None, [('Constant', (1, 8, 1, 9), 1, None), ('Constant', (1, 16, 1, 17), 2, None)]), [('Pass', (1, 28, 1, 32))], [], None, None)], []), -('Module', [('FunctionDef', (1, 0, 1, 30), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [('arg', (1, 14, 1, 15), 'b', None, None)], None, [('arg', (1, 22, 1, 23), 'c', None, None)], [None], None, [('Constant', (1, 8, 1, 9), 1, None), ('Constant', (1, 16, 1, 17), 2, None)]), [('Pass', (1, 26, 1, 30))], [], None, None)], []), -('Module', [('FunctionDef', (1, 0, 1, 42), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [('arg', (1, 14, 1, 15), 'b', None, None)], None, [('arg', (1, 22, 1, 23), 'c', None, None)], [('Constant', (1, 24, 1, 25), 4, None)], ('arg', (1, 29, 1, 35), 'kwargs', None, None), [('Constant', (1, 8, 1, 9), 1, None), ('Constant', (1, 16, 1, 17), 2, None)]), [('Pass', (1, 38, 1, 42))], [], None, None)], []), -('Module', [('FunctionDef', (1, 0, 1, 40), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [('arg', (1, 14, 1, 15), 'b', None, None)], None, [('arg', (1, 22, 1, 23), 'c', None, None)], [None], ('arg', (1, 27, 1, 33), 'kwargs', None, None), [('Constant', (1, 8, 1, 9), 1, None), ('Constant', (1, 16, 1, 17), 2, None)]), [('Pass', (1, 36, 1, 40))], [], None, None)], []), +('Module', [('FunctionDef', (1, 0, 1, 18), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [], None, [], [], None, []), [('Pass', (1, 14, 1, 18))], [], None, None, [])], []), +('Module', [('FunctionDef', (1, 0, 1, 26), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [('arg', (1, 12, 1, 13), 'c', None, None), ('arg', (1, 15, 1, 16), 'd', None, None), ('arg', (1, 18, 1, 19), 'e', None, None)], None, [], [], None, []), [('Pass', (1, 22, 1, 26))], [], None, None, [])], []), +('Module', [('FunctionDef', (1, 0, 1, 29), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [('arg', (1, 12, 1, 13), 'c', None, None)], None, [('arg', (1, 18, 1, 19), 'd', None, None), ('arg', (1, 21, 1, 22), 'e', None, None)], [None, None], None, []), [('Pass', (1, 25, 1, 29))], [], None, None, [])], []), +('Module', [('FunctionDef', (1, 0, 1, 39), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [('arg', (1, 12, 1, 13), 'c', None, None)], None, [('arg', (1, 18, 1, 19), 'd', None, None), ('arg', (1, 21, 1, 22), 'e', None, None)], [None, None], ('arg', (1, 26, 1, 32), 'kwargs', None, None), []), [('Pass', (1, 35, 1, 39))], [], None, None, [])], []), +('Module', [('FunctionDef', (1, 0, 1, 20), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [], None, [], [], None, [('Constant', (1, 8, 1, 9), 1, None)]), [('Pass', (1, 16, 1, 20))], [], None, None, [])], []), +('Module', [('FunctionDef', (1, 0, 1, 29), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [('arg', (1, 14, 1, 15), 'b', None, None), ('arg', (1, 19, 1, 20), 'c', None, None)], None, [], [], None, [('Constant', (1, 8, 1, 9), 1, None), ('Constant', (1, 16, 1, 17), 2, None), ('Constant', (1, 21, 1, 22), 4, None)]), [('Pass', (1, 25, 1, 29))], [], None, None, [])], []), +('Module', [('FunctionDef', (1, 0, 1, 32), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [('arg', (1, 14, 1, 15), 'b', None, None)], None, [('arg', (1, 22, 1, 23), 'c', None, None)], [('Constant', (1, 24, 1, 25), 4, None)], None, [('Constant', (1, 8, 1, 9), 1, None), ('Constant', (1, 16, 1, 17), 2, None)]), [('Pass', (1, 28, 1, 32))], [], None, None, [])], []), +('Module', [('FunctionDef', (1, 0, 1, 30), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [('arg', (1, 14, 1, 15), 'b', None, None)], None, [('arg', (1, 22, 1, 23), 'c', None, None)], [None], None, [('Constant', (1, 8, 1, 9), 1, None), ('Constant', (1, 16, 1, 17), 2, None)]), [('Pass', (1, 26, 1, 30))], [], None, None, [])], []), +('Module', [('FunctionDef', (1, 0, 1, 42), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [('arg', (1, 14, 1, 15), 'b', None, None)], None, [('arg', (1, 22, 1, 23), 'c', None, None)], [('Constant', (1, 24, 1, 25), 4, None)], ('arg', (1, 29, 1, 35), 'kwargs', None, None), [('Constant', (1, 8, 1, 9), 1, None), ('Constant', (1, 16, 1, 17), 2, None)]), [('Pass', (1, 38, 1, 42))], [], None, None, [])], []), +('Module', [('FunctionDef', (1, 0, 1, 40), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [('arg', (1, 14, 1, 15), 'b', None, None)], None, [('arg', (1, 22, 1, 23), 'c', None, None)], [None], ('arg', (1, 27, 1, 33), 'kwargs', None, None), [('Constant', (1, 8, 1, 9), 1, None), ('Constant', (1, 16, 1, 17), 2, None)]), [('Pass', (1, 36, 1, 40))], [], None, None, [])], []), +('Module', [('TypeAlias', (1, 0, 1, 12), ('Name', (1, 5, 1, 6), 'X', ('Store',)), [], ('Name', (1, 9, 1, 12), 'int', ('Load',)))], []), +('Module', [('TypeAlias', (1, 0, 1, 15), ('Name', (1, 5, 1, 6), 'X', ('Store',)), [('TypeVar', (1, 7, 1, 8), 'T', None)], ('Name', (1, 12, 1, 15), 'int', ('Load',)))], []), +('Module', [('TypeAlias', (1, 0, 1, 32), ('Name', (1, 5, 1, 6), 'X', ('Store',)), [('TypeVar', (1, 7, 1, 8), 'T', None), ('TypeVarTuple', (1, 10, 1, 13), 'Ts'), ('ParamSpec', (1, 15, 1, 18), 'P')], ('Tuple', (1, 22, 1, 32), [('Name', (1, 23, 1, 24), 'T', ('Load',)), ('Name', (1, 26, 1, 28), 'Ts', ('Load',)), ('Name', (1, 30, 1, 31), 'P', ('Load',))], ('Load',)))], []), +('Module', [('TypeAlias', (1, 0, 1, 37), ('Name', (1, 5, 1, 6), 'X', ('Store',)), [('TypeVar', (1, 7, 1, 13), 'T', ('Name', (1, 10, 1, 13), 'int', ('Load',))), ('TypeVarTuple', (1, 15, 1, 18), 'Ts'), ('ParamSpec', (1, 20, 1, 23), 'P')], ('Tuple', (1, 27, 1, 37), [('Name', (1, 28, 1, 29), 'T', ('Load',)), ('Name', (1, 31, 1, 33), 'Ts', ('Load',)), ('Name', (1, 35, 1, 36), 'P', ('Load',))], ('Load',)))], []), +('Module', [('TypeAlias', (1, 0, 1, 44), ('Name', (1, 5, 1, 6), 'X', ('Store',)), [('TypeVar', (1, 7, 1, 20), 'T', ('Tuple', (1, 10, 1, 20), [('Name', (1, 11, 1, 14), 'int', ('Load',)), ('Name', (1, 16, 1, 19), 'str', ('Load',))], ('Load',))), ('TypeVarTuple', (1, 22, 1, 25), 'Ts'), ('ParamSpec', (1, 27, 1, 30), 'P')], ('Tuple', (1, 34, 1, 44), [('Name', (1, 35, 1, 36), 'T', ('Load',)), ('Name', (1, 38, 1, 40), 'Ts', ('Load',)), ('Name', (1, 42, 1, 43), 'P', ('Load',))], ('Load',)))], []), +('Module', [('ClassDef', (1, 0, 1, 16), 'X', [], [], [('Pass', (1, 12, 1, 16))], [], [('TypeVar', (1, 8, 1, 9), 'T', None)])], []), +('Module', [('ClassDef', (1, 0, 1, 26), 'X', [], [], [('Pass', (1, 22, 1, 26))], [], [('TypeVar', (1, 8, 1, 9), 'T', None), ('TypeVarTuple', (1, 11, 1, 14), 'Ts'), ('ParamSpec', (1, 16, 1, 19), 'P')])], []), +('Module', [('ClassDef', (1, 0, 1, 31), 'X', [], [], [('Pass', (1, 27, 1, 31))], [], [('TypeVar', (1, 8, 1, 14), 'T', ('Name', (1, 11, 1, 14), 'int', ('Load',))), ('TypeVarTuple', (1, 16, 1, 19), 'Ts'), ('ParamSpec', (1, 21, 1, 24), 'P')])], []), +('Module', [('ClassDef', (1, 0, 1, 38), 'X', [], [], [('Pass', (1, 34, 1, 38))], [], [('TypeVar', (1, 8, 1, 21), 'T', ('Tuple', (1, 11, 1, 21), [('Name', (1, 12, 1, 15), 'int', ('Load',)), ('Name', (1, 17, 1, 20), 'str', ('Load',))], ('Load',))), ('TypeVarTuple', (1, 23, 1, 26), 'Ts'), ('ParamSpec', (1, 28, 1, 31), 'P')])], []), +('Module', [('FunctionDef', (1, 0, 1, 16), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (1, 12, 1, 16))], [], None, None, [('TypeVar', (1, 6, 1, 7), 'T', None)])], []), +('Module', [('FunctionDef', (1, 0, 1, 26), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (1, 22, 1, 26))], [], None, None, [('TypeVar', (1, 6, 1, 7), 'T', None), ('TypeVarTuple', (1, 9, 1, 12), 'Ts'), ('ParamSpec', (1, 14, 1, 17), 'P')])], []), +('Module', [('FunctionDef', (1, 0, 1, 31), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (1, 27, 1, 31))], [], None, None, [('TypeVar', (1, 6, 1, 12), 'T', ('Name', (1, 9, 1, 12), 'int', ('Load',))), ('TypeVarTuple', (1, 14, 1, 17), 'Ts'), ('ParamSpec', (1, 19, 1, 22), 'P')])], []), +('Module', [('FunctionDef', (1, 0, 1, 38), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (1, 34, 1, 38))], [], None, None, [('TypeVar', (1, 6, 1, 19), 'T', ('Tuple', (1, 9, 1, 19), [('Name', (1, 10, 1, 13), 'int', ('Load',)), ('Name', (1, 15, 1, 18), 'str', ('Load',))], ('Load',))), ('TypeVarTuple', (1, 21, 1, 24), 'Ts'), ('ParamSpec', (1, 26, 1, 29), 'P')])], []), ] single_results = [ ('Interactive', [('Expr', (1, 0, 1, 3), ('BinOp', (1, 0, 1, 3), ('Constant', (1, 0, 1, 1), 1, None), ('Add',), ('Constant', (1, 2, 1, 3), 2, None)))]), diff --git a/Lib/test/test_asyncgen.py b/Lib/test/test_asyncgen.py index fb22f411..9a934378 100644 --- a/Lib/test/test_asyncgen.py +++ b/Lib/test/test_asyncgen.py @@ -377,6 +377,26 @@ class AsyncGenTest(unittest.TestCase): self.compare_generators(sync_gen_wrapper(), async_gen_wrapper()) + def test_async_gen_exception_12(self): + async def gen(): + await anext(me) + yield 123 + + me = gen() + ai = me.__aiter__() + an = ai.__anext__() + + with self.assertRaisesRegex(RuntimeError, + r'anext\(\): asynchronous generator is already running'): + an.__next__() + + def test_async_gen_3_arg_deprecation_warning(self): + async def gen(): + yield 123 + + with self.assertWarns(DeprecationWarning): + gen().athrow(GeneratorExit, GeneratorExit(), None) + def test_async_gen_api_01(self): async def gen(): yield 123 @@ -650,7 +670,7 @@ class AsyncGenAsyncioTest(unittest.TestCase): agen = agenfn() with contextlib.closing(anext(agen, "default").__await__()) as g: self.assertEqual(g.send(None), 1) - self.assertEqual(g.throw(MyError, MyError(), None), 2) + self.assertEqual(g.throw(MyError()), 2) try: g.send(None) except StopIteration as e: @@ -663,9 +683,9 @@ class AsyncGenAsyncioTest(unittest.TestCase): agen = agenfn() with contextlib.closing(anext(agen, "default").__await__()) as g: self.assertEqual(g.send(None), 1) - self.assertEqual(g.throw(MyError, MyError(), None), 2) + self.assertEqual(g.throw(MyError()), 2) with self.assertRaises(MyError): - g.throw(MyError, MyError(), None) + g.throw(MyError()) def test3(anext): agen = agenfn() @@ -692,9 +712,9 @@ class AsyncGenAsyncioTest(unittest.TestCase): agen = agenfn() with contextlib.closing(anext(agen, "default").__await__()) as g: self.assertEqual(g.send(None), 10) - self.assertEqual(g.throw(MyError, MyError(), None), 20) + self.assertEqual(g.throw(MyError()), 20) with self.assertRaisesRegex(MyError, 'val'): - g.throw(MyError, MyError('val'), None) + g.throw(MyError('val')) def test5(anext): @types.coroutine @@ -713,7 +733,7 @@ class AsyncGenAsyncioTest(unittest.TestCase): with contextlib.closing(anext(agen, "default").__await__()) as g: self.assertEqual(g.send(None), 10) with self.assertRaisesRegex(StopIteration, 'default'): - g.throw(MyError, MyError(), None) + g.throw(MyError()) def test6(anext): @types.coroutine @@ -728,7 +748,7 @@ class AsyncGenAsyncioTest(unittest.TestCase): agen = agenfn() with contextlib.closing(anext(agen, "default").__await__()) as g: with self.assertRaises(MyError): - g.throw(MyError, MyError(), None) + g.throw(MyError()) def run_test(test): with self.subTest('pure-Python anext()'): @@ -1037,8 +1057,7 @@ class AsyncGenAsyncioTest(unittest.TestCase): while True: yield 1 finally: - await asyncio.sleep(0.01) - await asyncio.sleep(0.01) + await asyncio.sleep(0) DONE = 1 async def run(): @@ -1048,7 +1067,10 @@ class AsyncGenAsyncioTest(unittest.TestCase): del g gc_collect() # For PyPy or other GCs. - await asyncio.sleep(0.1) + # Starts running the aclose task + await asyncio.sleep(0) + # For asyncio.sleep(0) in finally block + await asyncio.sleep(0) self.loop.run_until_complete(run()) self.assertEqual(DONE, 1) diff --git a/Lib/test/test_asynchat.py b/Lib/test/test_asynchat.py deleted file mode 100644 index 9d08bd02..00000000 --- a/Lib/test/test_asynchat.py +++ /dev/null @@ -1,293 +0,0 @@ -# test asynchat - -from test import support -from test.support import socket_helper -from test.support import threading_helper -from test.support import warnings_helper - -import errno -import socket -import sys -import threading -import time -import unittest -import unittest.mock - - -asynchat = warnings_helper.import_deprecated('asynchat') -asyncore = warnings_helper.import_deprecated('asyncore') - -support.requires_working_socket(module=True) - -HOST = socket_helper.HOST -SERVER_QUIT = b'QUIT\n' - - -class echo_server(threading.Thread): - # parameter to determine the number of bytes passed back to the - # client each send - chunk_size = 1 - - def __init__(self, event): - threading.Thread.__init__(self) - self.event = event - self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - self.port = socket_helper.bind_port(self.sock) - # This will be set if the client wants us to wait before echoing - # data back. - self.start_resend_event = None - - def run(self): - self.sock.listen() - self.event.set() - conn, client = self.sock.accept() - self.buffer = b"" - # collect data until quit message is seen - while SERVER_QUIT not in self.buffer: - data = conn.recv(1) - if not data: - break - self.buffer = self.buffer + data - - # remove the SERVER_QUIT message - self.buffer = self.buffer.replace(SERVER_QUIT, b'') - - if self.start_resend_event: - self.start_resend_event.wait() - - # re-send entire set of collected data - try: - # this may fail on some tests, such as test_close_when_done, - # since the client closes the channel when it's done sending - while self.buffer: - n = conn.send(self.buffer[:self.chunk_size]) - time.sleep(0.001) - self.buffer = self.buffer[n:] - except: - pass - - conn.close() - self.sock.close() - -class echo_client(asynchat.async_chat): - - def __init__(self, terminator, server_port): - asynchat.async_chat.__init__(self) - self.contents = [] - self.create_socket(socket.AF_INET, socket.SOCK_STREAM) - self.connect((HOST, server_port)) - self.set_terminator(terminator) - self.buffer = b"" - - def handle_connect(self): - pass - - if sys.platform == 'darwin': - # select.poll returns a select.POLLHUP at the end of the tests - # on darwin, so just ignore it - def handle_expt(self): - pass - - def collect_incoming_data(self, data): - self.buffer += data - - def found_terminator(self): - self.contents.append(self.buffer) - self.buffer = b"" - -def start_echo_server(): - event = threading.Event() - s = echo_server(event) - s.start() - event.wait() - event.clear() - time.sleep(0.01) # Give server time to start accepting. - return s, event - - -class TestAsynchat(unittest.TestCase): - usepoll = False - - def setUp(self): - self._threads = threading_helper.threading_setup() - - def tearDown(self): - threading_helper.threading_cleanup(*self._threads) - - def line_terminator_check(self, term, server_chunk): - event = threading.Event() - s = echo_server(event) - s.chunk_size = server_chunk - s.start() - event.wait() - event.clear() - time.sleep(0.01) # Give server time to start accepting. - c = echo_client(term, s.port) - c.push(b"hello ") - c.push(b"world" + term) - c.push(b"I'm not dead yet!" + term) - c.push(SERVER_QUIT) - asyncore.loop(use_poll=self.usepoll, count=300, timeout=.01) - threading_helper.join_thread(s) - - self.assertEqual(c.contents, [b"hello world", b"I'm not dead yet!"]) - - # the line terminator tests below check receiving variously-sized - # chunks back from the server in order to exercise all branches of - # async_chat.handle_read - - def test_line_terminator1(self): - # test one-character terminator - for l in (1, 2, 3): - self.line_terminator_check(b'\n', l) - - def test_line_terminator2(self): - # test two-character terminator - for l in (1, 2, 3): - self.line_terminator_check(b'\r\n', l) - - def test_line_terminator3(self): - # test three-character terminator - for l in (1, 2, 3): - self.line_terminator_check(b'qqq', l) - - def numeric_terminator_check(self, termlen): - # Try reading a fixed number of bytes - s, event = start_echo_server() - c = echo_client(termlen, s.port) - data = b"hello world, I'm not dead yet!\n" - c.push(data) - c.push(SERVER_QUIT) - asyncore.loop(use_poll=self.usepoll, count=300, timeout=.01) - threading_helper.join_thread(s) - - self.assertEqual(c.contents, [data[:termlen]]) - - def test_numeric_terminator1(self): - # check that ints & longs both work (since type is - # explicitly checked in async_chat.handle_read) - self.numeric_terminator_check(1) - - def test_numeric_terminator2(self): - self.numeric_terminator_check(6) - - def test_none_terminator(self): - # Try reading a fixed number of bytes - s, event = start_echo_server() - c = echo_client(None, s.port) - data = b"hello world, I'm not dead yet!\n" - c.push(data) - c.push(SERVER_QUIT) - asyncore.loop(use_poll=self.usepoll, count=300, timeout=.01) - threading_helper.join_thread(s) - - self.assertEqual(c.contents, []) - self.assertEqual(c.buffer, data) - - def test_simple_producer(self): - s, event = start_echo_server() - c = echo_client(b'\n', s.port) - data = b"hello world\nI'm not dead yet!\n" - p = asynchat.simple_producer(data+SERVER_QUIT, buffer_size=8) - c.push_with_producer(p) - asyncore.loop(use_poll=self.usepoll, count=300, timeout=.01) - threading_helper.join_thread(s) - - self.assertEqual(c.contents, [b"hello world", b"I'm not dead yet!"]) - - def test_string_producer(self): - s, event = start_echo_server() - c = echo_client(b'\n', s.port) - data = b"hello world\nI'm not dead yet!\n" - c.push_with_producer(data+SERVER_QUIT) - asyncore.loop(use_poll=self.usepoll, count=300, timeout=.01) - threading_helper.join_thread(s) - - self.assertEqual(c.contents, [b"hello world", b"I'm not dead yet!"]) - - def test_empty_line(self): - # checks that empty lines are handled correctly - s, event = start_echo_server() - c = echo_client(b'\n', s.port) - c.push(b"hello world\n\nI'm not dead yet!\n") - c.push(SERVER_QUIT) - asyncore.loop(use_poll=self.usepoll, count=300, timeout=.01) - threading_helper.join_thread(s) - - self.assertEqual(c.contents, - [b"hello world", b"", b"I'm not dead yet!"]) - - def test_close_when_done(self): - s, event = start_echo_server() - s.start_resend_event = threading.Event() - c = echo_client(b'\n', s.port) - c.push(b"hello world\nI'm not dead yet!\n") - c.push(SERVER_QUIT) - c.close_when_done() - asyncore.loop(use_poll=self.usepoll, count=300, timeout=.01) - - # Only allow the server to start echoing data back to the client after - # the client has closed its connection. This prevents a race condition - # where the server echoes all of its data before we can check that it - # got any down below. - s.start_resend_event.set() - threading_helper.join_thread(s) - - self.assertEqual(c.contents, []) - # the server might have been able to send a byte or two back, but this - # at least checks that it received something and didn't just fail - # (which could still result in the client not having received anything) - self.assertGreater(len(s.buffer), 0) - - def test_push(self): - # Issue #12523: push() should raise a TypeError if it doesn't get - # a bytes string - s, event = start_echo_server() - c = echo_client(b'\n', s.port) - data = b'bytes\n' - c.push(data) - c.push(bytearray(data)) - c.push(memoryview(data)) - self.assertRaises(TypeError, c.push, 10) - self.assertRaises(TypeError, c.push, 'unicode') - c.push(SERVER_QUIT) - asyncore.loop(use_poll=self.usepoll, count=300, timeout=.01) - threading_helper.join_thread(s) - self.assertEqual(c.contents, [b'bytes', b'bytes', b'bytes']) - - -class TestAsynchat_WithPoll(TestAsynchat): - usepoll = True - - -class TestAsynchatMocked(unittest.TestCase): - def test_blockingioerror(self): - # Issue #16133: handle_read() must ignore BlockingIOError - sock = unittest.mock.Mock() - sock.recv.side_effect = BlockingIOError(errno.EAGAIN) - - dispatcher = asynchat.async_chat() - dispatcher.set_socket(sock) - self.addCleanup(dispatcher.del_channel) - - with unittest.mock.patch.object(dispatcher, 'handle_error') as error: - dispatcher.handle_read() - self.assertFalse(error.called) - - -class TestHelperFunctions(unittest.TestCase): - def test_find_prefix_at_end(self): - self.assertEqual(asynchat.find_prefix_at_end("qwerty\r", "\r\n"), 1) - self.assertEqual(asynchat.find_prefix_at_end("qwertydkjf", "\r\n"), 0) - - -class TestNotConnected(unittest.TestCase): - def test_disallow_negative_terminator(self): - # Issue #11259 - client = asynchat.async_chat() - self.assertRaises(ValueError, client.set_terminator, -1) - - - -if __name__ == "__main__": - unittest.main() diff --git a/Lib/test/test_asyncio/test_base_events.py b/Lib/test/test_asyncio/test_base_events.py index 6ba602dd..3b4026cb 100644 --- a/Lib/test/test_asyncio/test_base_events.py +++ b/Lib/test/test_asyncio/test_base_events.py @@ -861,20 +861,15 @@ class BaseEventLoopTests(test_utils.TestCase): self.loop._process_events = mock.Mock() - try: + with self.assertRaises(KeyboardInterrupt): self.loop.run_until_complete(raise_keyboard_interrupt()) - except KeyboardInterrupt: - pass def func(): self.loop.stop() func.called = True func.called = False - try: - self.loop.call_soon(func) - self.loop.run_forever() - except KeyboardInterrupt: - pass + self.loop.call_soon(self.loop.call_soon, func) + self.loop.run_forever() self.assertTrue(func.called) def test_single_selecter_event_callback_after_stopping(self): @@ -1109,6 +1104,15 @@ class BaseEventLoopWithSelectorTests(test_utils.TestCase): self.assertEqual(str(cm.exception), 'Multiple exceptions: err1, err2') + idx = -1 + coro = self.loop.create_connection(MyProto, 'example.com', 80, all_errors=True) + with self.assertRaises(ExceptionGroup) as cm: + self.loop.run_until_complete(coro) + + self.assertIsInstance(cm.exception, ExceptionGroup) + for e in cm.exception.exceptions: + self.assertIsInstance(e, OSError) + @patch_socket def test_create_connection_timeout(self, m_socket): # Ensure that the socket is closed on timeout @@ -1228,6 +1232,14 @@ class BaseEventLoopWithSelectorTests(test_utils.TestCase): self.assertRaises( OSError, self.loop.run_until_complete, coro) + coro = self.loop.create_connection(MyProto, 'example.com', 80, all_errors=True) + with self.assertRaises(ExceptionGroup) as cm: + self.loop.run_until_complete(coro) + + self.assertIsInstance(cm.exception, ExceptionGroup) + self.assertEqual(len(cm.exception.exceptions), 1) + self.assertIsInstance(cm.exception.exceptions[0], OSError) + def test_create_connection_multiple(self): async def getaddrinfo(*args, **kw): return [(2, 1, 6, '', ('0.0.0.1', 80)), @@ -1245,6 +1257,15 @@ class BaseEventLoopWithSelectorTests(test_utils.TestCase): with self.assertRaises(OSError): self.loop.run_until_complete(coro) + coro = self.loop.create_connection( + MyProto, 'example.com', 80, family=socket.AF_INET, all_errors=True) + with self.assertRaises(ExceptionGroup) as cm: + self.loop.run_until_complete(coro) + + self.assertIsInstance(cm.exception, ExceptionGroup) + for e in cm.exception.exceptions: + self.assertIsInstance(e, OSError) + @patch_socket def test_create_connection_multiple_errors_local_addr(self, m_socket): @@ -1276,6 +1297,16 @@ class BaseEventLoopWithSelectorTests(test_utils.TestCase): self.assertTrue(str(cm.exception).startswith('Multiple exceptions: ')) self.assertTrue(m_socket.socket.return_value.close.called) + coro = self.loop.create_connection( + MyProto, 'example.com', 80, family=socket.AF_INET, + local_addr=(None, 8080), all_errors=True) + with self.assertRaises(ExceptionGroup) as cm: + self.loop.run_until_complete(coro) + + self.assertIsInstance(cm.exception, ExceptionGroup) + for e in cm.exception.exceptions: + self.assertIsInstance(e, OSError) + def _test_create_connection_ip_addr(self, m_socket, allow_inet_pton): # Test the fallback code, even if this system has inet_pton. if not allow_inet_pton: @@ -2016,11 +2047,11 @@ class BaseLoopSockSendfileTests(test_utils.TestCase): def cleanup(): server.close() - self.run_loop(server.wait_closed()) sock.close() if proto.transport is not None: proto.transport.close() self.run_loop(proto.wait_closed()) + self.run_loop(server.wait_closed()) self.addCleanup(cleanup) diff --git a/Lib/test/test_asyncio/test_eager_task_factory.py b/Lib/test/test_asyncio/test_eager_task_factory.py new file mode 100644 index 00000000..34688873 --- /dev/null +++ b/Lib/test/test_asyncio/test_eager_task_factory.py @@ -0,0 +1,361 @@ +"""Tests for base_events.py""" + +import asyncio +import contextvars +import gc +import time +import unittest + +from types import GenericAlias +from unittest import mock +from asyncio import base_events +from asyncio import tasks +from test.test_asyncio import utils as test_utils +from test.test_asyncio.test_tasks import get_innermost_context +from test.support.script_helper import assert_python_ok + +MOCK_ANY = mock.ANY + + +def tearDownModule(): + asyncio.set_event_loop_policy(None) + + +class EagerTaskFactoryLoopTests: + + Task = None + + def run_coro(self, coro): + """ + Helper method to run the `coro` coroutine in the test event loop. + It helps with making sure the event loop is running before starting + to execute `coro`. This is important for testing the eager step + functionality, since an eager step is taken only if the event loop + is already running. + """ + + async def coro_runner(): + self.assertTrue(asyncio.get_event_loop().is_running()) + return await coro + + return self.loop.run_until_complete(coro) + + def setUp(self): + super().setUp() + self.loop = asyncio.new_event_loop() + self.eager_task_factory = asyncio.create_eager_task_factory(self.Task) + self.loop.set_task_factory(self.eager_task_factory) + self.set_event_loop(self.loop) + + def test_eager_task_factory_set(self): + self.assertIsNotNone(self.eager_task_factory) + self.assertIs(self.loop.get_task_factory(), self.eager_task_factory) + + async def noop(): pass + + async def run(): + t = self.loop.create_task(noop()) + self.assertIsInstance(t, self.Task) + await t + + self.run_coro(run()) + + def test_await_future_during_eager_step(self): + + async def set_result(fut, val): + fut.set_result(val) + + async def run(): + fut = self.loop.create_future() + t = self.loop.create_task(set_result(fut, 'my message')) + # assert the eager step completed the task + self.assertTrue(t.done()) + return await fut + + self.assertEqual(self.run_coro(run()), 'my message') + + def test_eager_completion(self): + + async def coro(): + return 'hello' + + async def run(): + t = self.loop.create_task(coro()) + # assert the eager step completed the task + self.assertTrue(t.done()) + return await t + + self.assertEqual(self.run_coro(run()), 'hello') + + def test_block_after_eager_step(self): + + async def coro(): + await asyncio.sleep(0.1) + return 'finished after blocking' + + async def run(): + t = self.loop.create_task(coro()) + self.assertFalse(t.done()) + result = await t + self.assertTrue(t.done()) + return result + + self.assertEqual(self.run_coro(run()), 'finished after blocking') + + def test_cancellation_after_eager_completion(self): + + async def coro(): + return 'finished without blocking' + + async def run(): + t = self.loop.create_task(coro()) + t.cancel() + result = await t + # finished task can't be cancelled + self.assertFalse(t.cancelled()) + return result + + self.assertEqual(self.run_coro(run()), 'finished without blocking') + + def test_cancellation_after_eager_step_blocks(self): + + async def coro(): + await asyncio.sleep(0.1) + return 'finished after blocking' + + async def run(): + t = self.loop.create_task(coro()) + t.cancel('cancellation message') + self.assertGreater(t.cancelling(), 0) + result = await t + + with self.assertRaises(asyncio.CancelledError) as cm: + self.run_coro(run()) + + self.assertEqual('cancellation message', cm.exception.args[0]) + + def test_current_task(self): + captured_current_task = None + + async def coro(): + nonlocal captured_current_task + captured_current_task = asyncio.current_task() + # verify the task before and after blocking is identical + await asyncio.sleep(0.1) + self.assertIs(asyncio.current_task(), captured_current_task) + + async def run(): + t = self.loop.create_task(coro()) + self.assertIs(captured_current_task, t) + await t + + self.run_coro(run()) + captured_current_task = None + + def test_all_tasks_with_eager_completion(self): + captured_all_tasks = None + + async def coro(): + nonlocal captured_all_tasks + captured_all_tasks = asyncio.all_tasks() + + async def run(): + t = self.loop.create_task(coro()) + self.assertIn(t, captured_all_tasks) + self.assertNotIn(t, asyncio.all_tasks()) + + self.run_coro(run()) + + def test_all_tasks_with_blocking(self): + captured_eager_all_tasks = None + + async def coro(fut1, fut2): + nonlocal captured_eager_all_tasks + captured_eager_all_tasks = asyncio.all_tasks() + await fut1 + fut2.set_result(None) + + async def run(): + fut1 = self.loop.create_future() + fut2 = self.loop.create_future() + t = self.loop.create_task(coro(fut1, fut2)) + self.assertIn(t, captured_eager_all_tasks) + self.assertIn(t, asyncio.all_tasks()) + fut1.set_result(None) + await fut2 + self.assertNotIn(t, asyncio.all_tasks()) + + self.run_coro(run()) + + def test_context_vars(self): + cv = contextvars.ContextVar('cv', default=0) + + coro_first_step_ran = False + coro_second_step_ran = False + + async def coro(): + nonlocal coro_first_step_ran + nonlocal coro_second_step_ran + self.assertEqual(cv.get(), 1) + cv.set(2) + self.assertEqual(cv.get(), 2) + coro_first_step_ran = True + await asyncio.sleep(0.1) + self.assertEqual(cv.get(), 2) + cv.set(3) + self.assertEqual(cv.get(), 3) + coro_second_step_ran = True + + async def run(): + cv.set(1) + t = self.loop.create_task(coro()) + self.assertTrue(coro_first_step_ran) + self.assertFalse(coro_second_step_ran) + self.assertEqual(cv.get(), 1) + await t + self.assertTrue(coro_second_step_ran) + self.assertEqual(cv.get(), 1) + + self.run_coro(run()) + + +class PyEagerTaskFactoryLoopTests(EagerTaskFactoryLoopTests, test_utils.TestCase): + Task = tasks._PyTask + + +@unittest.skipUnless(hasattr(tasks, '_CTask'), + 'requires the C _asyncio module') +class CEagerTaskFactoryLoopTests(EagerTaskFactoryLoopTests, test_utils.TestCase): + Task = getattr(tasks, '_CTask', None) + + def test_issue105987(self): + code = """if 1: + from _asyncio import _swap_current_task + + class DummyTask: + pass + + class DummyLoop: + pass + + l = DummyLoop() + _swap_current_task(l, DummyTask()) + t = _swap_current_task(l, None) + """ + + _, out, err = assert_python_ok("-c", code) + self.assertFalse(err) + +class AsyncTaskCounter: + def __init__(self, loop, *, task_class, eager): + self.suspense_count = 0 + self.task_count = 0 + + def CountingTask(*args, eager_start=False, **kwargs): + if not eager_start: + self.task_count += 1 + kwargs["eager_start"] = eager_start + return task_class(*args, **kwargs) + + if eager: + factory = asyncio.create_eager_task_factory(CountingTask) + else: + def factory(loop, coro, **kwargs): + return CountingTask(coro, loop=loop, **kwargs) + loop.set_task_factory(factory) + + def get(self): + return self.task_count + + +async def awaitable_chain(depth): + if depth == 0: + return 0 + return 1 + await awaitable_chain(depth - 1) + + +async def recursive_taskgroups(width, depth): + if depth == 0: + return + + async with asyncio.TaskGroup() as tg: + futures = [ + tg.create_task(recursive_taskgroups(width, depth - 1)) + for _ in range(width) + ] + + +async def recursive_gather(width, depth): + if depth == 0: + return + + await asyncio.gather( + *[recursive_gather(width, depth - 1) for _ in range(width)] + ) + + +class BaseTaskCountingTests: + + Task = None + eager = None + expected_task_count = None + + def setUp(self): + super().setUp() + self.loop = asyncio.new_event_loop() + self.counter = AsyncTaskCounter(self.loop, task_class=self.Task, eager=self.eager) + self.set_event_loop(self.loop) + + def test_awaitables_chain(self): + observed_depth = self.loop.run_until_complete(awaitable_chain(100)) + self.assertEqual(observed_depth, 100) + self.assertEqual(self.counter.get(), 0 if self.eager else 1) + + def test_recursive_taskgroups(self): + num_tasks = self.loop.run_until_complete(recursive_taskgroups(5, 4)) + self.assertEqual(self.counter.get(), self.expected_task_count) + + def test_recursive_gather(self): + self.loop.run_until_complete(recursive_gather(5, 4)) + self.assertEqual(self.counter.get(), self.expected_task_count) + + +class BaseNonEagerTaskFactoryTests(BaseTaskCountingTests): + eager = False + expected_task_count = 781 # 1 + 5 + 5^2 + 5^3 + 5^4 + + +class BaseEagerTaskFactoryTests(BaseTaskCountingTests): + eager = True + expected_task_count = 0 + + +class NonEagerTests(BaseNonEagerTaskFactoryTests, test_utils.TestCase): + Task = asyncio.Task + + +class EagerTests(BaseEagerTaskFactoryTests, test_utils.TestCase): + Task = asyncio.Task + + +class NonEagerPyTaskTests(BaseNonEagerTaskFactoryTests, test_utils.TestCase): + Task = tasks._PyTask + + +class EagerPyTaskTests(BaseEagerTaskFactoryTests, test_utils.TestCase): + Task = tasks._PyTask + + +@unittest.skipUnless(hasattr(tasks, '_CTask'), + 'requires the C _asyncio module') +class NonEagerCTaskTests(BaseNonEagerTaskFactoryTests, test_utils.TestCase): + Task = getattr(tasks, '_CTask', None) + + +@unittest.skipUnless(hasattr(tasks, '_CTask'), + 'requires the C _asyncio module') +class EagerCTaskTests(BaseEagerTaskFactoryTests, test_utils.TestCase): + Task = getattr(tasks, '_CTask', None) + +if __name__ == '__main__': + unittest.main() diff --git a/Lib/test/test_asyncio/test_events.py b/Lib/test/test_asyncio/test_events.py index 5728d252..1647d230 100644 --- a/Lib/test/test_asyncio/test_events.py +++ b/Lib/test/test_asyncio/test_events.py @@ -4,6 +4,7 @@ import collections.abc import concurrent.futures import functools import io +import multiprocessing import os import platform import re @@ -22,15 +23,15 @@ import errno import unittest from unittest import mock import weakref - +import warnings if sys.platform not in ('win32', 'vxworks'): import tty import asyncio from asyncio import coroutines from asyncio import events -from asyncio import proactor_events from asyncio import selector_events +from multiprocessing.util import _cleanup_tests as multiprocessing_cleanup_tests from test.test_asyncio import utils as test_utils from test import support from test.support import socket_helper @@ -671,6 +672,7 @@ class EventLoopTestsMixin: self.assertEqual(port, expected) tr.close() + @socket_helper.skip_if_tcp_blackhole def test_create_connection_local_addr_skip_different_family(self): # See https://github.com/python/cpython/issues/86508 port1 = socket_helper.find_unused_port() @@ -692,6 +694,7 @@ class EventLoopTestsMixin: with self.assertRaises(OSError): self.loop.run_until_complete(f) + @socket_helper.skip_if_tcp_blackhole def test_create_connection_local_addr_nomatch_family(self): # See https://github.com/python/cpython/issues/86508 port1 = socket_helper.find_unused_port() @@ -865,6 +868,29 @@ class EventLoopTestsMixin: # close server server.close() + def test_create_server_trsock(self): + proto = MyProto(self.loop) + f = self.loop.create_server(lambda: proto, '0.0.0.0', 0) + server = self.loop.run_until_complete(f) + self.assertEqual(len(server.sockets), 1) + sock = server.sockets[0] + self.assertIsInstance(sock, asyncio.trsock.TransportSocket) + host, port = sock.getsockname() + self.assertEqual(host, '0.0.0.0') + dup = sock.dup() + self.addCleanup(dup.close) + self.assertIsInstance(dup, socket.socket) + self.assertFalse(sock.get_inheritable()) + with self.assertRaises(ValueError): + sock.settimeout(1) + sock.settimeout(0) + self.assertEqual(sock.gettimeout(), 0) + with self.assertRaises(ValueError): + sock.setblocking(True) + sock.setblocking(False) + server.close() + + @unittest.skipUnless(hasattr(socket, 'SO_REUSEPORT'), 'No SO_REUSEPORT') def test_create_server_reuse_port(self): proto = MyProto(self.loop) @@ -1248,6 +1274,7 @@ class EventLoopTestsMixin: server.close() + @socket_helper.skip_if_tcp_blackhole def test_server_close(self): f = self.loop.create_server(MyProto, '0.0.0.0', 0) server = self.loop.run_until_complete(f) @@ -2097,12 +2124,16 @@ else: class UnixEventLoopTestsMixin(EventLoopTestsMixin): def setUp(self): super().setUp() - watcher = asyncio.SafeChildWatcher() - watcher.attach_loop(self.loop) - asyncio.set_child_watcher(watcher) + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + watcher = asyncio.SafeChildWatcher() + watcher.attach_loop(self.loop) + asyncio.set_child_watcher(watcher) def tearDown(self): - asyncio.set_child_watcher(None) + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + asyncio.set_child_watcher(None) super().tearDown() @@ -2588,7 +2619,9 @@ class PolicyTests(unittest.TestCase): def test_get_event_loop(self): policy = asyncio.DefaultEventLoopPolicy() self.assertIsNone(policy._local._loop) - loop = policy.get_event_loop() + with self.assertWarns(DeprecationWarning) as cm: + loop = policy.get_event_loop() + self.assertEqual(cm.filename, __file__) self.assertIsInstance(loop, asyncio.AbstractEventLoop) self.assertIs(policy._local._loop, loop) @@ -2602,8 +2635,10 @@ class PolicyTests(unittest.TestCase): policy, "set_event_loop", wraps=policy.set_event_loop) as m_set_event_loop: - loop = policy.get_event_loop() + with self.assertWarns(DeprecationWarning) as cm: + loop = policy.get_event_loop() self.addCleanup(loop.close) + self.assertEqual(cm.filename, __file__) # policy._local._loop must be set through .set_event_loop() # (the unix DefaultEventLoopPolicy needs this call to attach @@ -2695,14 +2730,18 @@ class GetEventLoopTestsMixin: asyncio.set_event_loop(self.loop) if sys.platform != 'win32': - watcher = asyncio.SafeChildWatcher() - watcher.attach_loop(self.loop) - asyncio.set_child_watcher(watcher) + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + watcher = asyncio.SafeChildWatcher() + watcher.attach_loop(self.loop) + asyncio.set_child_watcher(watcher) def tearDown(self): try: if sys.platform != 'win32': - asyncio.set_child_watcher(None) + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + asyncio.set_child_watcher(None) super().tearDown() finally: @@ -2727,8 +2766,16 @@ class GetEventLoopTestsMixin: # multiprocessing.synchronize module cannot be imported. support.skip_if_broken_multiprocessing_synchronize() + self.addCleanup(multiprocessing_cleanup_tests) + async def main(): - pool = concurrent.futures.ProcessPoolExecutor() + if multiprocessing.get_start_method() == 'fork': + # Avoid 'fork' DeprecationWarning. + mp_context = multiprocessing.get_context('forkserver') + else: + mp_context = None + pool = concurrent.futures.ProcessPoolExecutor( + mp_context=mp_context) result = await self.loop.run_in_executor( pool, _test_get_event_loop_new_process__sub_proc) pool.shutdown() @@ -2792,8 +2839,10 @@ class GetEventLoopTestsMixin: loop = asyncio.new_event_loop() self.addCleanup(loop.close) - loop2 = asyncio.get_event_loop() + with self.assertWarns(DeprecationWarning) as cm: + loop2 = asyncio.get_event_loop() self.addCleanup(loop2.close) + self.assertEqual(cm.filename, __file__) asyncio.set_event_loop(None) with self.assertRaisesRegex(RuntimeError, 'no current'): asyncio.get_event_loop() diff --git a/Lib/test/test_asyncio/test_futures.py b/Lib/test/test_asyncio/test_futures.py index c6aad824..2184b209 100644 --- a/Lib/test/test_asyncio/test_futures.py +++ b/Lib/test/test_asyncio/test_futures.py @@ -10,6 +10,7 @@ from unittest import mock from types import GenericAlias import asyncio from asyncio import futures +import warnings from test.test_asyncio import utils as test_utils from test import support @@ -156,7 +157,7 @@ class BaseFutureTests: self.assertIs(f.get_loop(), self.loop) def test_constructor_use_global_loop(self): - # Deprecated in 3.10, undeprecated in 3.11.1 + # Deprecated in 3.10, undeprecated in 3.12 asyncio.set_event_loop(self.loop) self.addCleanup(asyncio.set_event_loop, None) f = self._new_future() @@ -511,7 +512,7 @@ class BaseFutureTests: ex.shutdown(wait=True) def test_wrap_future_use_global_loop(self): - # Deprecated in 3.10, undeprecated in 3.11.1 + # Deprecated in 3.10, undeprecated in 3.12 asyncio.set_event_loop(self.loop) self.addCleanup(asyncio.set_event_loop, None) def run(arg): @@ -603,12 +604,16 @@ class BaseFutureTests: def test_future_iter_throw(self): fut = self._new_future(loop=self.loop) fi = iter(fut) - self.assertRaises(TypeError, fi.throw, - Exception, Exception("elephant"), 32) - self.assertRaises(TypeError, fi.throw, - Exception("elephant"), Exception("elephant")) - # https://github.com/python/cpython/issues/101326 - self.assertRaises(ValueError, fi.throw, ValueError, None, None) + with self.assertWarns(DeprecationWarning): + self.assertRaises(Exception, fi.throw, Exception, Exception("zebra"), None) + with warnings.catch_warnings(): + warnings.filterwarnings("ignore", category=DeprecationWarning) + self.assertRaises(TypeError, fi.throw, + Exception, Exception("elephant"), 32) + self.assertRaises(TypeError, fi.throw, + Exception("elephant"), Exception("elephant")) + # https://github.com/python/cpython/issues/101326 + self.assertRaises(ValueError, fi.throw, ValueError, None, None) self.assertRaises(TypeError, fi.throw, list) def test_future_del_collect(self): diff --git a/Lib/test/test_asyncio/test_futures2.py b/Lib/test/test_asyncio/test_futures2.py index 71279b69..b7cfffb7 100644 --- a/Lib/test/test_asyncio/test_futures2.py +++ b/Lib/test/test_asyncio/test_futures2.py @@ -1,5 +1,6 @@ # IsolatedAsyncioTestCase based tests import asyncio +import contextvars import traceback import unittest from asyncio import tasks @@ -27,6 +28,46 @@ class FutureTests: else: self.fail('TypeError was not raised') + async def test_task_exc_handler_correct_context(self): + # see https://github.com/python/cpython/issues/96704 + name = contextvars.ContextVar('name', default='foo') + exc_handler_called = False + + def exc_handler(*args): + self.assertEqual(name.get(), 'bar') + nonlocal exc_handler_called + exc_handler_called = True + + async def task(): + name.set('bar') + 1/0 + + loop = asyncio.get_running_loop() + loop.set_exception_handler(exc_handler) + self.cls(task()) + await asyncio.sleep(0) + self.assertTrue(exc_handler_called) + + async def test_handle_exc_handler_correct_context(self): + # see https://github.com/python/cpython/issues/96704 + name = contextvars.ContextVar('name', default='foo') + exc_handler_called = False + + def exc_handler(*args): + self.assertEqual(name.get(), 'bar') + nonlocal exc_handler_called + exc_handler_called = True + + def callback(): + name.set('bar') + 1/0 + + loop = asyncio.get_running_loop() + loop.set_exception_handler(exc_handler) + loop.call_soon(callback) + await asyncio.sleep(0) + self.assertTrue(exc_handler_called) + @unittest.skipUnless(hasattr(tasks, '_CTask'), 'requires the C _asyncio module') class CFutureTests(FutureTests, unittest.IsolatedAsyncioTestCase): @@ -45,10 +86,9 @@ class FutureReprTests(unittest.IsolatedAsyncioTestCase): async def func(): return asyncio.all_tasks() - # The repr() call should not raise RecursiveError at first. - # The check for returned string is not very reliable but - # exact comparison for the whole string is even weaker. - self.assertIn('...', repr(await asyncio.wait_for(func(), timeout=10))) + # The repr() call should not raise RecursionError at first. + waiter = await asyncio.wait_for(asyncio.Task(func()),timeout=10) + self.assertIn('...', repr(waiter)) if __name__ == '__main__': diff --git a/Lib/test/test_asyncio/test_locks.py b/Lib/test/test_asyncio/test_locks.py index c20ec94c..f6c6a282 100644 --- a/Lib/test/test_asyncio/test_locks.py +++ b/Lib/test/test_asyncio/test_locks.py @@ -1370,7 +1370,7 @@ class BarrierTests(unittest.IsolatedAsyncioTestCase): # catch here waiting tasks results1.append(True) else: - # here drained task ouside the barrier + # here drained task outside the barrier if rest_of_tasks == barrier._count: # tasks outside the barrier await barrier.reset() @@ -1476,7 +1476,7 @@ class BarrierTests(unittest.IsolatedAsyncioTestCase): # last task exited from barrier await barrier.reset() - # wit here to reach the `parties` + # wait here to reach the `parties` await barrier.wait() else: try: diff --git a/Lib/test/test_asyncio/test_pep492.py b/Lib/test/test_asyncio/test_pep492.py index f833f788..dc25a469 100644 --- a/Lib/test/test_asyncio/test_pep492.py +++ b/Lib/test/test_asyncio/test_pep492.py @@ -119,6 +119,12 @@ class CoroutineTests(BaseTest): self.assertTrue(asyncio.iscoroutine(FakeCoro())) + def test_iscoroutine_generator(self): + def foo(): yield + + self.assertFalse(asyncio.iscoroutine(foo())) + + def test_iscoroutinefunction(self): async def foo(): pass self.assertTrue(asyncio.iscoroutinefunction(foo)) diff --git a/Lib/test/test_asyncio/test_proactor_events.py b/Lib/test/test_asyncio/test_proactor_events.py index ae30185c..c42856e5 100644 --- a/Lib/test/test_asyncio/test_proactor_events.py +++ b/Lib/test/test_asyncio/test_proactor_events.py @@ -75,7 +75,10 @@ class ProactorSocketTransportTests(test_utils.TestCase): called_buf = bytearray(self.buffer_size) called_buf[:len(buf)] = buf self.loop._proactor.recv_into.assert_called_with(self.sock, called_buf) - self.protocol.data_received.assert_called_with(bytearray(buf)) + self.protocol.data_received.assert_called_with(buf) + # assert_called_with maps bytearray and bytes to the same thing so check manually + # regression test for https://github.com/python/cpython/issues/99941 + self.assertIsInstance(self.protocol.data_received.call_args.args[0], bytes) @unittest.skipIf(sys.flags.optimize, "Assertions are disabled in optimized mode") def test_loop_reading_no_data(self): @@ -444,6 +447,19 @@ class ProactorSocketTransportTests(test_utils.TestCase): self.assertFalse(tr.is_reading()) + def test_pause_reading_connection_made(self): + tr = self.socket_transport() + self.protocol.connection_made.side_effect = lambda _: tr.pause_reading() + test_utils.run_briefly(self.loop) + self.assertFalse(tr.is_reading()) + self.loop.assert_no_reader(7) + + tr.resume_reading() + self.assertTrue(tr.is_reading()) + + tr.close() + self.assertFalse(tr.is_reading()) + def pause_writing_transport(self, high): tr = self.socket_transport() diff --git a/Lib/test/test_asyncio/test_runners.py b/Lib/test/test_asyncio/test_runners.py index 4e3acb97..0a1ad070 100644 --- a/Lib/test/test_asyncio/test_runners.py +++ b/Lib/test/test_asyncio/test_runners.py @@ -1,7 +1,6 @@ import _thread import asyncio import contextvars -import gc import re import signal import threading @@ -102,11 +101,14 @@ class RunTests(BaseTest): loop = asyncio.get_event_loop() self.assertIs(loop.get_debug(), expected) - asyncio.run(main(False)) + asyncio.run(main(False), debug=False) asyncio.run(main(True), debug=True) with mock.patch('asyncio.coroutines._is_debug_mode', lambda: True): asyncio.run(main(True)) asyncio.run(main(False), debug=False) + with mock.patch('asyncio.coroutines._is_debug_mode', lambda: False): + asyncio.run(main(True), debug=True) + asyncio.run(main(False)) def test_asyncio_run_from_running_loop(self): async def main(): @@ -258,6 +260,16 @@ class RunTests(BaseTest): with self.assertRaises(asyncio.CancelledError): asyncio.run(main()) + def test_asyncio_run_loop_factory(self): + factory = mock.Mock() + loop = factory.return_value = self.new_loop() + + async def main(): + self.assertEqual(asyncio.get_running_loop(), loop) + + asyncio.run(main(), loop_factory=factory) + factory.assert_called_once_with() + class RunnerTests(BaseTest): @@ -438,9 +450,9 @@ class RunnerTests(BaseTest): with asyncio.Runner() as runner: with self.assertRaises(asyncio.CancelledError): runner.run(coro()) - + def test_signal_install_not_supported_ok(self): - # signal.signal() can throw if the "main thread" doensn't have signals enabled + # signal.signal() can throw if the "main thread" doesn't have signals enabled assert threading.current_thread() is threading.main_thread() async def coro(): diff --git a/Lib/test/test_asyncio/test_selector_events.py b/Lib/test/test_asyncio/test_selector_events.py index 22dcfb23..47693ea4 100644 --- a/Lib/test/test_asyncio/test_selector_events.py +++ b/Lib/test/test_asyncio/test_selector_events.py @@ -1,23 +1,25 @@ """Tests for selector_events.py""" -import sys +import collections import selectors import socket +import sys import unittest +from asyncio import selector_events from unittest import mock + try: import ssl except ImportError: ssl = None import asyncio -from asyncio.selector_events import BaseSelectorEventLoop -from asyncio.selector_events import _SelectorTransport -from asyncio.selector_events import _SelectorSocketTransport -from asyncio.selector_events import _SelectorDatagramTransport +from asyncio.selector_events import (BaseSelectorEventLoop, + _SelectorDatagramTransport, + _SelectorSocketTransport, + _SelectorTransport) from test.test_asyncio import utils as test_utils - MOCK_ANY = mock.ANY @@ -37,7 +39,10 @@ class TestBaseSelectorEventLoop(BaseSelectorEventLoop): def list_to_buffer(l=()): - return bytearray().join(l) + buffer = collections.deque() + buffer.extend((memoryview(i) for i in l)) + return buffer + def close_transport(transport): @@ -61,8 +66,10 @@ class BaseSelectorEventLoopTests(test_utils.TestCase): def test_make_socket_transport(self): m = mock.Mock() self.loop.add_reader = mock.Mock() + self.loop._ensure_fd_no_transport = mock.Mock() transport = self.loop._make_socket_transport(m, asyncio.Protocol()) self.assertIsInstance(transport, _SelectorSocketTransport) + self.assertEqual(self.loop._ensure_fd_no_transport.call_count, 1) # Calling repr() must not fail when the event loop is closed self.loop.close() @@ -78,8 +85,10 @@ class BaseSelectorEventLoopTests(test_utils.TestCase): self.loop.add_writer = mock.Mock() self.loop.remove_reader = mock.Mock() self.loop.remove_writer = mock.Mock() + self.loop._ensure_fd_no_transport = mock.Mock() with self.assertRaises(RuntimeError): self.loop._make_ssl_transport(m, m, m, m) + self.assertEqual(self.loop._ensure_fd_no_transport.call_count, 1) def test_close(self): class EventLoop(BaseSelectorEventLoop): @@ -489,9 +498,13 @@ class SelectorSocketTransportTests(test_utils.TestCase): self.sock = mock.Mock(socket.socket) self.sock_fd = self.sock.fileno.return_value = 7 - def socket_transport(self, waiter=None): + def socket_transport(self, waiter=None, sendmsg=False): transport = _SelectorSocketTransport(self.loop, self.sock, self.protocol, waiter=waiter) + if sendmsg: + transport._write_ready = transport._write_sendmsg + else: + transport._write_ready = transport._write_send self.addCleanup(close_transport, transport) return transport @@ -534,6 +547,22 @@ class SelectorSocketTransportTests(test_utils.TestCase): self.assertFalse(tr.is_reading()) self.loop.assert_no_reader(7) + def test_pause_reading_connection_made(self): + tr = self.socket_transport() + self.protocol.connection_made.side_effect = lambda _: tr.pause_reading() + test_utils.run_briefly(self.loop) + self.assertFalse(tr.is_reading()) + self.loop.assert_no_reader(7) + + tr.resume_reading() + self.assertTrue(tr.is_reading()) + self.loop.assert_reader(7, tr._read_ready) + + tr.close() + self.assertFalse(tr.is_reading()) + self.loop.assert_no_reader(7) + + def test_read_eof_received_error(self): transport = self.socket_transport() transport.close = mock.Mock() @@ -660,14 +689,14 @@ class SelectorSocketTransportTests(test_utils.TestCase): def test_write_no_data(self): transport = self.socket_transport() - transport._buffer.extend(b'data') + transport._buffer.append(memoryview(b'data')) transport.write(b'') self.assertFalse(self.sock.send.called) self.assertEqual(list_to_buffer([b'data']), transport._buffer) def test_write_buffer(self): transport = self.socket_transport() - transport._buffer.extend(b'data1') + transport._buffer.append(b'data1') transport.write(b'data2') self.assertFalse(self.sock.send.called) self.assertEqual(list_to_buffer([b'data1', b'data2']), @@ -725,6 +754,119 @@ class SelectorSocketTransportTests(test_utils.TestCase): self.loop.assert_writer(7, transport._write_ready) self.assertEqual(list_to_buffer([b'data']), transport._buffer) + def test_write_sendmsg_no_data(self): + self.sock.sendmsg = mock.Mock() + self.sock.sendmsg.return_value = 0 + transport = self.socket_transport(sendmsg=True) + transport._buffer.append(memoryview(b'data')) + transport.write(b'') + self.assertFalse(self.sock.sendmsg.called) + self.assertEqual(list_to_buffer([b'data']), transport._buffer) + + @unittest.skipUnless(selector_events._HAS_SENDMSG, 'no sendmsg') + def test_writelines_sendmsg_full(self): + data = memoryview(b'data') + self.sock.sendmsg = mock.Mock() + self.sock.sendmsg.return_value = len(data) + + transport = self.socket_transport(sendmsg=True) + transport.writelines([data]) + self.assertTrue(self.sock.sendmsg.called) + self.assertFalse(self.loop.writers) + + @unittest.skipUnless(selector_events._HAS_SENDMSG, 'no sendmsg') + def test_writelines_sendmsg_partial(self): + data = memoryview(b'data') + self.sock.sendmsg = mock.Mock() + self.sock.sendmsg.return_value = 2 + + transport = self.socket_transport(sendmsg=True) + transport.writelines([data]) + self.assertTrue(self.sock.sendmsg.called) + self.assertTrue(self.loop.writers) + + def test_writelines_send_full(self): + data = memoryview(b'data') + self.sock.send.return_value = len(data) + self.sock.send.fileno.return_value = 7 + + transport = self.socket_transport() + transport.writelines([data]) + self.assertTrue(self.sock.send.called) + self.assertFalse(self.loop.writers) + + def test_writelines_send_partial(self): + data = memoryview(b'data') + self.sock.send.return_value = 2 + self.sock.send.fileno.return_value = 7 + + transport = self.socket_transport() + transport.writelines([data]) + self.assertTrue(self.sock.send.called) + self.assertTrue(self.loop.writers) + + @unittest.skipUnless(selector_events._HAS_SENDMSG, 'no sendmsg') + def test_write_sendmsg_full(self): + data = memoryview(b'data') + self.sock.sendmsg = mock.Mock() + self.sock.sendmsg.return_value = len(data) + + transport = self.socket_transport(sendmsg=True) + transport._buffer.append(data) + self.loop._add_writer(7, transport._write_ready) + transport._write_ready() + self.assertTrue(self.sock.sendmsg.called) + self.assertFalse(self.loop.writers) + + @unittest.skipUnless(selector_events._HAS_SENDMSG, 'no sendmsg') + def test_write_sendmsg_partial(self): + + data = memoryview(b'data') + self.sock.sendmsg = mock.Mock() + # Sent partial data + self.sock.sendmsg.return_value = 2 + + transport = self.socket_transport(sendmsg=True) + transport._buffer.append(data) + self.loop._add_writer(7, transport._write_ready) + transport._write_ready() + self.assertTrue(self.sock.sendmsg.called) + self.assertTrue(self.loop.writers) + self.assertEqual(list_to_buffer([b'ta']), transport._buffer) + + @unittest.skipUnless(selector_events._HAS_SENDMSG, 'no sendmsg') + def test_write_sendmsg_half_buffer(self): + data = [memoryview(b'data1'), memoryview(b'data2')] + self.sock.sendmsg = mock.Mock() + # Sent partial data + self.sock.sendmsg.return_value = 2 + + transport = self.socket_transport(sendmsg=True) + transport._buffer.extend(data) + self.loop._add_writer(7, transport._write_ready) + transport._write_ready() + self.assertTrue(self.sock.sendmsg.called) + self.assertTrue(self.loop.writers) + self.assertEqual(list_to_buffer([b'ta1', b'data2']), transport._buffer) + + @unittest.skipUnless(selector_events._HAS_SENDMSG, 'no sendmsg') + def test_write_sendmsg_OSError(self): + data = memoryview(b'data') + self.sock.sendmsg = mock.Mock() + err = self.sock.sendmsg.side_effect = OSError() + + transport = self.socket_transport(sendmsg=True) + transport._fatal_error = mock.Mock() + transport._buffer.extend(data) + # Calls _fatal_error and clears the buffer + transport._write_ready() + self.assertTrue(self.sock.sendmsg.called) + self.assertFalse(self.loop.writers) + self.assertEqual(list_to_buffer([]), transport._buffer) + transport._fatal_error.assert_called_with( + err, + 'Fatal write error on socket transport') + @mock.patch('asyncio.selector_events.logger') def test_write_exception(self, m_log): err = self.sock.send.side_effect = OSError() @@ -764,19 +906,19 @@ class SelectorSocketTransportTests(test_utils.TestCase): self.sock.send.return_value = len(data) transport = self.socket_transport() - transport._buffer.extend(data) + transport._buffer.append(data) self.loop._add_writer(7, transport._write_ready) transport._write_ready() self.assertTrue(self.sock.send.called) self.assertFalse(self.loop.writers) def test_write_ready_closing(self): - data = b'data' + data = memoryview(b'data') self.sock.send.return_value = len(data) transport = self.socket_transport() transport._closing = True - transport._buffer.extend(data) + transport._buffer.append(data) self.loop._add_writer(7, transport._write_ready) transport._write_ready() self.assertTrue(self.sock.send.called) @@ -791,11 +933,11 @@ class SelectorSocketTransportTests(test_utils.TestCase): self.assertRaises(AssertionError, transport._write_ready) def test_write_ready_partial(self): - data = b'data' + data = memoryview(b'data') self.sock.send.return_value = 2 transport = self.socket_transport() - transport._buffer.extend(data) + transport._buffer.append(data) self.loop._add_writer(7, transport._write_ready) transport._write_ready() self.loop.assert_writer(7, transport._write_ready) @@ -806,7 +948,7 @@ class SelectorSocketTransportTests(test_utils.TestCase): self.sock.send.return_value = 0 transport = self.socket_transport() - transport._buffer.extend(data) + transport._buffer.append(data) self.loop._add_writer(7, transport._write_ready) transport._write_ready() self.loop.assert_writer(7, transport._write_ready) @@ -816,12 +958,13 @@ class SelectorSocketTransportTests(test_utils.TestCase): self.sock.send.side_effect = BlockingIOError transport = self.socket_transport() - transport._buffer = list_to_buffer([b'data1', b'data2']) + buffer = list_to_buffer([b'data1', b'data2']) + transport._buffer = buffer self.loop._add_writer(7, transport._write_ready) transport._write_ready() self.loop.assert_writer(7, transport._write_ready) - self.assertEqual(list_to_buffer([b'data1data2']), transport._buffer) + self.assertEqual(buffer, transport._buffer) def test_write_ready_exception(self): err = self.sock.send.side_effect = OSError() @@ -1077,6 +1220,10 @@ class SelectorDatagramTransportTests(test_utils.TestCase): self.protocol.datagram_received.assert_called_with( b'data', ('0.0.0.0', 1234)) + def test_transport_inheritance(self): + transport = self.datagram_transport() + self.assertIsInstance(transport, asyncio.DatagramTransport) + def test_read_ready_tryagain(self): transport = self.datagram_transport() diff --git a/Lib/test/test_asyncio/test_server.py b/Lib/test/test_asyncio/test_server.py index 860d62d5..06d8b60f 100644 --- a/Lib/test/test_asyncio/test_server.py +++ b/Lib/test/test_asyncio/test_server.py @@ -120,6 +120,33 @@ class SelectorStartServerTests(BaseStartServer, unittest.TestCase): self.loop.run_until_complete(srv.serve_forever()) +class TestServer2(unittest.IsolatedAsyncioTestCase): + + async def test_wait_closed(self): + async def serve(*args): + pass + + srv = await asyncio.start_server(serve, socket_helper.HOSTv4, 0) + + # active count = 0 + task1 = asyncio.create_task(srv.wait_closed()) + await asyncio.sleep(0) + self.assertTrue(task1.done()) + + # active count != 0 + srv._attach() + task2 = asyncio.create_task(srv.wait_closed()) + await asyncio.sleep(0) + self.assertFalse(task2.done()) + + srv.close() + await asyncio.sleep(0) + self.assertFalse(task2.done()) + + srv._detach() + await task2 + + @unittest.skipUnless(hasattr(asyncio, 'ProactorEventLoop'), 'Windows only') class ProactorStartServerTests(BaseStartServer, unittest.TestCase): diff --git a/Lib/test/test_asyncio/test_sock_lowlevel.py b/Lib/test/test_asyncio/test_sock_lowlevel.py index db47616d..075113cb 100644 --- a/Lib/test/test_asyncio/test_sock_lowlevel.py +++ b/Lib/test/test_asyncio/test_sock_lowlevel.py @@ -5,11 +5,15 @@ import unittest from asyncio import proactor_events from itertools import cycle, islice -from unittest.mock import patch, Mock +from unittest.mock import Mock from test.test_asyncio import utils as test_utils from test import support from test.support import socket_helper +if socket_helper.tcp_blackhole(): + raise unittest.SkipTest('Not relevant to ProactorEventLoop') + + def tearDownModule(): asyncio.set_event_loop_policy(None) diff --git a/Lib/test/test_asyncio/test_ssl.py b/Lib/test/test_asyncio/test_ssl.py index aaf3c371..e9cc7356 100644 --- a/Lib/test/test_asyncio/test_ssl.py +++ b/Lib/test/test_asyncio/test_ssl.py @@ -1,5 +1,4 @@ import asyncio -import asyncio.sslproto import contextlib import gc import logging diff --git a/Lib/test/test_asyncio/test_sslproto.py b/Lib/test/test_asyncio/test_sslproto.py index 52a45f1c..37d01533 100644 --- a/Lib/test/test_asyncio/test_sslproto.py +++ b/Lib/test/test_asyncio/test_sslproto.py @@ -5,6 +5,7 @@ import socket import unittest import weakref from test import support +from test.support import socket_helper from unittest import mock try: import ssl @@ -350,6 +351,7 @@ class BaseStartTLS(func_tests.FunctionalTestCaseMixin): support.gc_collect() self.assertIsNone(client_context()) + @socket_helper.skip_if_tcp_blackhole def test_start_tls_client_buf_proto_1(self): HELLO_MSG = b'1' * self.PAYLOAD_SIZE @@ -502,6 +504,7 @@ class BaseStartTLS(func_tests.FunctionalTestCaseMixin): asyncio.wait_for(client(srv.addr), timeout=support.SHORT_TIMEOUT)) + @socket_helper.skip_if_tcp_blackhole def test_start_tls_server_1(self): HELLO_MSG = b'1' * self.PAYLOAD_SIZE ANSWER = b'answer' diff --git a/Lib/test/test_asyncio/test_streams.py b/Lib/test/test_asyncio/test_streams.py index 95fc7a15..7f9dc621 100644 --- a/Lib/test/test_asyncio/test_streams.py +++ b/Lib/test/test_asyncio/test_streams.py @@ -9,6 +9,7 @@ import sys import threading import unittest from unittest import mock +import warnings from test.support import socket_helper try: import ssl @@ -791,11 +792,14 @@ os.close(fd) protocol = asyncio.StreamReaderProtocol(reader, loop=self.loop) transport, _ = self.loop.run_until_complete( self.loop.connect_read_pipe(lambda: protocol, pipe)) - - watcher = asyncio.SafeChildWatcher() + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + watcher = asyncio.SafeChildWatcher() watcher.attach_loop(self.loop) try: - asyncio.set_child_watcher(watcher) + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + asyncio.set_child_watcher(watcher) create = asyncio.create_subprocess_exec( *args, pass_fds={wfd}, @@ -803,7 +807,9 @@ os.close(fd) proc = self.loop.run_until_complete(create) self.loop.run_until_complete(proc.wait()) finally: - asyncio.set_child_watcher(None) + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + asyncio.set_child_watcher(None) os.close(wfd) data = self.loop.run_until_complete(reader.read(-1)) @@ -825,7 +831,7 @@ os.close(fd) def test_streamreader_constructor_use_global_loop(self): # asyncio issue #184: Ensure that StreamReaderProtocol constructor # retrieves the current loop if the loop parameter is not set - # Deprecated in 3.10, undeprecated in 3.11.1 + # Deprecated in 3.10, undeprecated in 3.12 self.addCleanup(asyncio.set_event_loop, None) asyncio.set_event_loop(self.loop) reader = asyncio.StreamReader() @@ -849,7 +855,7 @@ os.close(fd) def test_streamreaderprotocol_constructor_use_global_loop(self): # asyncio issue #184: Ensure that StreamReaderProtocol constructor # retrieves the current loop if the loop parameter is not set - # Deprecated in 3.10, undeprecated in 3.11.1 + # Deprecated in 3.10, undeprecated in 3.12 self.addCleanup(asyncio.set_event_loop, None) asyncio.set_event_loop(self.loop) reader = mock.Mock() diff --git a/Lib/test/test_asyncio/test_subprocess.py b/Lib/test/test_asyncio/test_subprocess.py index bea2314a..eeeca40c 100644 --- a/Lib/test/test_asyncio/test_subprocess.py +++ b/Lib/test/test_asyncio/test_subprocess.py @@ -1,5 +1,4 @@ import os -import shutil import signal import sys import unittest @@ -152,6 +151,24 @@ class SubprocessMixin: self.assertEqual(exitcode, 0) self.assertEqual(stdout, b'some data') + def test_communicate_none_input(self): + args = PROGRAM_CAT + + async def run(): + proc = await asyncio.create_subprocess_exec( + *args, + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + ) + stdout, stderr = await proc.communicate() + return proc.returncode, stdout + + task = run() + task = asyncio.wait_for(task, support.LONG_TIMEOUT) + exitcode, stdout = self.loop.run_until_complete(task) + self.assertEqual(exitcode, 0) + self.assertEqual(stdout, b'') + def test_shell(self): proc = self.loop.run_until_complete( asyncio.create_subprocess_shell('exit 7') @@ -585,7 +602,9 @@ class SubprocessMixin: # manually to avoid a warning when the watcher is detached. if (sys.platform != 'win32' and isinstance(self, SubprocessFastWatcherTests)): - asyncio.get_child_watcher()._callbacks.clear() + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + asyncio.get_child_watcher()._callbacks.clear() async def _test_popen_error(self, stdin): if sys.platform == 'win32': @@ -684,6 +703,90 @@ class SubprocessMixin: self.assertIsNone(self.loop.run_until_complete(execute())) + async def check_stdout_output(self, coro, output): + proc = await coro + stdout, _ = await proc.communicate() + self.assertEqual(stdout, output) + self.assertEqual(proc.returncode, 0) + task = asyncio.create_task(proc.wait()) + await asyncio.sleep(0) + self.assertEqual(task.result(), proc.returncode) + + def test_create_subprocess_env_shell(self) -> None: + async def main() -> None: + cmd = f'''{sys.executable} -c "import os, sys; sys.stdout.write(os.getenv('FOO'))"''' + env = os.environ.copy() + env["FOO"] = "bar" + proc = await asyncio.create_subprocess_shell( + cmd, env=env, stdout=subprocess.PIPE + ) + return proc + + self.loop.run_until_complete(self.check_stdout_output(main(), b'bar')) + + def test_create_subprocess_env_exec(self) -> None: + async def main() -> None: + cmd = [sys.executable, "-c", + "import os, sys; sys.stdout.write(os.getenv('FOO'))"] + env = os.environ.copy() + env["FOO"] = "baz" + proc = await asyncio.create_subprocess_exec( + *cmd, env=env, stdout=subprocess.PIPE + ) + return proc + + self.loop.run_until_complete(self.check_stdout_output(main(), b'baz')) + + + def test_subprocess_concurrent_wait(self) -> None: + async def main() -> None: + proc = await asyncio.create_subprocess_exec( + *PROGRAM_CAT, + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + ) + stdout, _ = await proc.communicate(b'some data') + self.assertEqual(stdout, b"some data") + self.assertEqual(proc.returncode, 0) + self.assertEqual(await asyncio.gather(*[proc.wait() for _ in range(10)]), + [proc.returncode] * 10) + + self.loop.run_until_complete(main()) + + def test_subprocess_consistent_callbacks(self): + events = [] + class MyProtocol(asyncio.SubprocessProtocol): + def __init__(self, exit_future: asyncio.Future) -> None: + self.exit_future = exit_future + + def pipe_data_received(self, fd, data) -> None: + events.append(('pipe_data_received', fd, data)) + + def pipe_connection_lost(self, fd, exc) -> None: + events.append('pipe_connection_lost') + + def process_exited(self) -> None: + events.append('process_exited') + self.exit_future.set_result(True) + + async def main() -> None: + loop = asyncio.get_running_loop() + exit_future = asyncio.Future() + code = 'import sys; sys.stdout.write("stdout"); sys.stderr.write("stderr")' + transport, _ = await loop.subprocess_exec(lambda: MyProtocol(exit_future), + sys.executable, '-c', code, stdin=None) + await exit_future + transport.close() + self.assertEqual(events, [ + ('pipe_data_received', 1, b'stdout'), + ('pipe_data_received', 2, b'stderr'), + 'pipe_connection_lost', + 'pipe_connection_lost', + 'process_exited', + ]) + + self.loop.run_until_complete(main()) + def test_subprocess_communicate_stdout(self): # See https://github.com/python/cpython/issues/100133 async def get_command_stdout(cmd, *args): @@ -714,65 +817,64 @@ if sys.platform != 'win32': self.loop = policy.new_event_loop() self.set_event_loop(self.loop) - watcher = self.Watcher() + watcher = self._get_watcher() watcher.attach_loop(self.loop) - policy.set_child_watcher(watcher) + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + policy.set_child_watcher(watcher) def tearDown(self): super().tearDown() policy = asyncio.get_event_loop_policy() - watcher = policy.get_child_watcher() - policy.set_child_watcher(None) + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + watcher = policy.get_child_watcher() + policy.set_child_watcher(None) watcher.attach_loop(None) watcher.close() class SubprocessThreadedWatcherTests(SubprocessWatcherMixin, test_utils.TestCase): - Watcher = unix_events.ThreadedChildWatcher - - @unittest.skip("bpo-38323: MultiLoopChildWatcher has a race condition \ - and these tests can hang the test suite") - class SubprocessMultiLoopWatcherTests(SubprocessWatcherMixin, - test_utils.TestCase): - - Watcher = unix_events.MultiLoopChildWatcher + def _get_watcher(self): + return unix_events.ThreadedChildWatcher() class SubprocessSafeWatcherTests(SubprocessWatcherMixin, test_utils.TestCase): - Watcher = unix_events.SafeChildWatcher + def _get_watcher(self): + with self.assertWarns(DeprecationWarning): + return unix_events.SafeChildWatcher() + + class MultiLoopChildWatcherTests(test_utils.TestCase): + + def test_warns(self): + with self.assertWarns(DeprecationWarning): + unix_events.MultiLoopChildWatcher() class SubprocessFastWatcherTests(SubprocessWatcherMixin, test_utils.TestCase): - Watcher = unix_events.FastChildWatcher - - def has_pidfd_support(): - if not hasattr(os, 'pidfd_open'): - return False - try: - os.close(os.pidfd_open(os.getpid())) - except OSError: - return False - return True + def _get_watcher(self): + with self.assertWarns(DeprecationWarning): + return unix_events.FastChildWatcher() @unittest.skipUnless( - has_pidfd_support(), + unix_events.can_use_pidfd(), "operating system does not support pidfds", ) class SubprocessPidfdWatcherTests(SubprocessWatcherMixin, test_utils.TestCase): - Watcher = unix_events.PidfdChildWatcher + + def _get_watcher(self): + return unix_events.PidfdChildWatcher() class GenericWatcherTests(test_utils.TestCase): def test_create_subprocess_fails_with_inactive_watcher(self): - watcher = mock.create_autospec( - asyncio.AbstractChildWatcher, - **{"__enter__.return_value.is_active.return_value": False} - ) + watcher = mock.create_autospec(asyncio.AbstractChildWatcher) + watcher.is_active.return_value = False async def execute(): asyncio.set_child_watcher(watcher) @@ -784,13 +886,45 @@ if sys.platform != 'win32': watcher.add_child_handler.assert_not_called() with asyncio.Runner(loop_factory=asyncio.new_event_loop) as runner: - self.assertIsNone(runner.run(execute())) + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + self.assertIsNone(runner.run(execute())) self.assertListEqual(watcher.mock_calls, [ mock.call.__enter__(), - mock.call.__enter__().is_active(), + mock.call.is_active(), mock.call.__exit__(RuntimeError, mock.ANY, mock.ANY), - ]) + ], watcher.mock_calls) + + @unittest.skipUnless( + unix_events.can_use_pidfd(), + "operating system does not support pidfds", + ) + def test_create_subprocess_with_pidfd(self): + async def in_thread(): + proc = await asyncio.create_subprocess_exec( + *PROGRAM_CAT, + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + ) + stdout, stderr = await proc.communicate(b"some data") + return proc.returncode, stdout + + async def main(): + # asyncio.Runner did not call asyncio.set_event_loop() + with self.assertRaises(RuntimeError): + asyncio.get_event_loop_policy().get_event_loop() + return await asyncio.to_thread(asyncio.run, in_thread()) + with self.assertWarns(DeprecationWarning): + asyncio.set_child_watcher(asyncio.PidfdChildWatcher()) + try: + with asyncio.Runner(loop_factory=asyncio.new_event_loop) as runner: + returncode, stdout = runner.run(main()) + self.assertEqual(returncode, 0) + self.assertEqual(stdout, b'some data') + finally: + with self.assertWarns(DeprecationWarning): + asyncio.set_child_watcher(None) else: # Windows class SubprocessProactorTests(SubprocessMixin, test_utils.TestCase): diff --git a/Lib/test/test_asyncio/test_tasks.py b/Lib/test/test_asyncio/test_tasks.py index 9900e307..6e8a51ce 100644 --- a/Lib/test/test_asyncio/test_tasks.py +++ b/Lib/test/test_asyncio/test_tasks.py @@ -1,22 +1,19 @@ """Tests for tasks.py.""" import collections -import contextlib import contextvars -import functools import gc import io import random import re import sys -import textwrap import traceback +import types import unittest from unittest import mock from types import GenericAlias import asyncio -from asyncio import coroutines from asyncio import futures from asyncio import tasks from test.test_asyncio import utils as test_utils @@ -211,7 +208,7 @@ class BaseTaskTests: self.assertTrue(t.done()) self.assertEqual(t.result(), 'ok') - # Deprecated in 3.10, undeprecated in 3.11.1 + # Deprecated in 3.10, undeprecated in 3.12 asyncio.set_event_loop(self.loop) self.addCleanup(asyncio.set_event_loop, None) t = asyncio.ensure_future(notmuch()) @@ -278,6 +275,20 @@ class BaseTaskTests: loop.run_until_complete(fut) self.assertEqual(fut.result(), 'ok') + def test_ensure_future_task_awaitable(self): + class Aw: + def __await__(self): + return asyncio.sleep(0, result='ok').__await__() + + loop = asyncio.new_event_loop() + self.set_event_loop(loop) + task = asyncio.ensure_future(Aw(), loop=loop) + loop.run_until_complete(task) + self.assertTrue(task.done()) + self.assertEqual(task.result(), 'ok') + self.assertIsInstance(task.get_coro(), types.CoroutineType) + loop.close() + def test_ensure_future_neither(self): with self.assertRaises(TypeError): asyncio.ensure_future('ok') @@ -388,6 +399,18 @@ class BaseTaskTests: self.loop.run_until_complete(t1) self.loop.run_until_complete(t2) + def test_task_set_name_pylong(self): + # test that setting the task name to a PyLong explicitly doesn't + # incorrectly trigger the deferred name formatting logic + async def notmuch(): + return 123 + + t = self.new_task(self.loop, notmuch(), name=987654321) + self.assertEqual(t.get_name(), '987654321') + t.set_name(123456789) + self.assertEqual(t.get_name(), '123456789') + self.loop.run_until_complete(t) + def test_task_repr_name_not_str(self): async def notmuch(): return 123 @@ -595,7 +618,7 @@ class BaseTaskTests: if ( timed_out and task.uncancel() == 0 - and sys.exc_info()[0] is asyncio.CancelledError + and type(sys.exception()) is asyncio.CancelledError ): # Note the five rules that are needed here to satisfy proper # uncancellation: @@ -1362,6 +1385,22 @@ class BaseTaskTests: self.assertEqual(res, 42) self.assertAlmostEqual(0.15, loop.time()) + + def test_wait_generator(self): + async def func(a): + return a + + loop = self.new_test_loop() + + async def main(): + tasks = (self.new_task(loop, func(i)) for i in range(10)) + done, pending = await asyncio.wait(tasks, return_when=asyncio.ALL_COMPLETED) + self.assertEqual(len(done), 10) + self.assertEqual(len(pending), 0) + + loop.run_until_complete(main()) + + def test_as_completed(self): def gen(): @@ -1978,7 +2017,7 @@ class BaseTaskTests: self.assertEqual(res, 42) def test_shield_coroutine_use_global_loop(self): - # Deprecated in 3.10, undeprecated in 3.11.1 + # Deprecated in 3.10, undeprecated in 3.12 async def coro(): return 42 @@ -2096,8 +2135,8 @@ class BaseTaskTests: async def create(): # The indirection fut->child_coro is needed since otherwise the # gathering task is done at the same time as the child future - def child_coro(): - return (yield from fut) + async def child_coro(): + return await fut gather_future = asyncio.gather(child_coro()) return asyncio.ensure_future(gather_future) gather_task = loop.run_until_complete(create()) @@ -2439,6 +2478,17 @@ class BaseTaskTests: finally: loop.close() + def test_get_context(self): + loop = asyncio.new_event_loop() + coro = coroutine_function() + context = contextvars.copy_context() + try: + task = self.new_task(loop, coro, context=context) + loop.run_until_complete(task) + self.assertIs(task.get_context(), context) + finally: + loop.close() + def add_subclass_tests(cls): BaseTask = cls.Task @@ -2797,6 +2847,7 @@ class CIntrospectionTests(test_utils.TestCase, BaseTaskIntrospectionTests): class BaseCurrentLoopTests: + current_task = None def setUp(self): super().setUp() @@ -2807,33 +2858,39 @@ class BaseCurrentLoopTests: raise NotImplementedError def test_current_task_no_running_loop(self): - self.assertIsNone(asyncio.current_task(loop=self.loop)) + self.assertIsNone(self.current_task(loop=self.loop)) def test_current_task_no_running_loop_implicit(self): with self.assertRaisesRegex(RuntimeError, 'no running event loop'): - asyncio.current_task() + self.current_task() def test_current_task_with_implicit_loop(self): async def coro(): - self.assertIs(asyncio.current_task(loop=self.loop), task) + self.assertIs(self.current_task(loop=self.loop), task) - self.assertIs(asyncio.current_task(None), task) - self.assertIs(asyncio.current_task(), task) + self.assertIs(self.current_task(None), task) + self.assertIs(self.current_task(), task) task = self.new_task(coro()) self.loop.run_until_complete(task) - self.assertIsNone(asyncio.current_task(loop=self.loop)) + self.assertIsNone(self.current_task(loop=self.loop)) class PyCurrentLoopTests(BaseCurrentLoopTests, test_utils.TestCase): + current_task = staticmethod(tasks._py_current_task) def new_task(self, coro): return tasks._PyTask(coro, loop=self.loop) -@unittest.skipUnless(hasattr(tasks, '_CTask'), +@unittest.skipUnless(hasattr(tasks, '_CTask') and + hasattr(tasks, '_c_current_task'), 'requires the C _asyncio module') class CCurrentLoopTests(BaseCurrentLoopTests, test_utils.TestCase): + if hasattr(tasks, '_c_current_task'): + current_task = staticmethod(tasks._c_current_task) + else: + current_task = None def new_task(self, coro): return getattr(tasks, '_CTask')(coro, loop=self.loop) @@ -2988,7 +3045,7 @@ class FutureGatherTests(GatherTestsBase, test_utils.TestCase): self.assertEqual(fut.result(), []) def test_constructor_empty_sequence_use_global_loop(self): - # Deprecated in 3.10, undeprecated in 3.11.1 + # Deprecated in 3.10, undeprecated in 3.12 asyncio.set_event_loop(self.one_loop) self.addCleanup(asyncio.set_event_loop, None) fut = asyncio.gather() @@ -3094,7 +3151,7 @@ class CoroutineGatherTests(GatherTestsBase, test_utils.TestCase): self.one_loop.run_until_complete(fut) def test_constructor_use_global_loop(self): - # Deprecated in 3.10, undeprecated in 3.11.1 + # Deprecated in 3.10, undeprecated in 3.12 async def coro(): return 'abc' asyncio.set_event_loop(self.other_loop) diff --git a/Lib/test/test_asyncio/test_timeouts.py b/Lib/test/test_asyncio/test_timeouts.py index 3a542970..8b6b9a1f 100644 --- a/Lib/test/test_asyncio/test_timeouts.py +++ b/Lib/test/test_asyncio/test_timeouts.py @@ -4,7 +4,6 @@ import unittest import time import asyncio -from asyncio import tasks def tearDownModule(): @@ -248,6 +247,36 @@ class TimeoutTests(unittest.IsolatedAsyncioTestCase): async with asyncio.timeout(0.01): await asyncio.sleep(10) + async def test_timeout_after_cancellation(self): + try: + asyncio.current_task().cancel() + await asyncio.sleep(1) # work which will be cancelled + except asyncio.CancelledError: + pass + finally: + with self.assertRaises(TimeoutError): + async with asyncio.timeout(0.0): + await asyncio.sleep(1) # some cleanup + + async def test_cancel_in_timeout_after_cancellation(self): + try: + asyncio.current_task().cancel() + await asyncio.sleep(1) # work which will be cancelled + except asyncio.CancelledError: + pass + finally: + with self.assertRaises(asyncio.CancelledError): + async with asyncio.timeout(1.0): + asyncio.current_task().cancel() + await asyncio.sleep(2) # some cleanup + + async def test_timeout_exception_cause (self): + with self.assertRaises(asyncio.TimeoutError) as exc: + async with asyncio.timeout(0): + await asyncio.sleep(1) + cause = exc.exception.__cause__ + assert isinstance(cause, asyncio.CancelledError) + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_asyncio/test_unix_events.py b/Lib/test/test_asyncio/test_unix_events.py index 01c1214c..cdf3eaac 100644 --- a/Lib/test/test_asyncio/test_unix_events.py +++ b/Lib/test/test_asyncio/test_unix_events.py @@ -3,18 +3,21 @@ import contextlib import errno import io +import multiprocessing import os import pathlib import signal import socket import stat import sys -import tempfile import threading import unittest from unittest import mock +import warnings from test.support import os_helper from test.support import socket_helper +from test.support import wait_process +from test.support import hashlib_helper if sys.platform == 'win32': raise unittest.SkipTest('UNIX only') @@ -315,11 +318,15 @@ class SelectorEventLoopUnixSocketTests(test_utils.TestCase): self.loop.run_until_complete(coro) def test_create_unix_server_existing_path_nonsock(self): - with tempfile.NamedTemporaryFile() as file: - coro = self.loop.create_unix_server(lambda: None, file.name) - with self.assertRaisesRegex(OSError, - 'Address.*is already in use'): - self.loop.run_until_complete(coro) + path = test_utils.gen_unix_socket_path() + self.addCleanup(os_helper.unlink, path) + # create the file + open(path, "wb").close() + + coro = self.loop.create_unix_server(lambda: None, path) + with self.assertRaisesRegex(OSError, + 'Address.*is already in use'): + self.loop.run_until_complete(coro) def test_create_unix_server_ssl_bool(self): coro = self.loop.create_unix_server(lambda: None, path='spam', @@ -356,20 +363,18 @@ class SelectorEventLoopUnixSocketTests(test_utils.TestCase): 'no socket.SOCK_NONBLOCK (linux only)') @socket_helper.skip_unless_bind_unix_socket def test_create_unix_server_path_stream_bittype(self): - sock = socket.socket( - socket.AF_UNIX, socket.SOCK_STREAM | socket.SOCK_NONBLOCK) - with tempfile.NamedTemporaryFile() as file: - fn = file.name - try: - with sock: - sock.bind(fn) - coro = self.loop.create_unix_server(lambda: None, path=None, - sock=sock) - srv = self.loop.run_until_complete(coro) - srv.close() - self.loop.run_until_complete(srv.wait_closed()) - finally: - os.unlink(fn) + fn = test_utils.gen_unix_socket_path() + self.addCleanup(os_helper.unlink, fn) + + sock = socket.socket(socket.AF_UNIX, + socket.SOCK_STREAM | socket.SOCK_NONBLOCK) + with sock: + sock.bind(fn) + coro = self.loop.create_unix_server(lambda: None, path=None, + sock=sock) + srv = self.loop.run_until_complete(coro) + srv.close() + self.loop.run_until_complete(srv.wait_closed()) def test_create_unix_server_ssl_timeout_with_plain_sock(self): coro = self.loop.create_unix_server(lambda: None, path='spam', @@ -1106,6 +1111,11 @@ class UnixWritePipeTransportTests(test_utils.TestCase): class AbstractChildWatcherTests(unittest.TestCase): + def test_warns_on_subclassing(self): + with self.assertWarns(DeprecationWarning): + class MyWatcher(asyncio.AbstractChildWatcher): + pass + def test_not_implemented(self): f = mock.Mock() watcher = asyncio.AbstractChildWatcher() @@ -1685,12 +1695,16 @@ class ChildWatcherTestsMixin: class SafeChildWatcherTests (ChildWatcherTestsMixin, test_utils.TestCase): def create_watcher(self): - return asyncio.SafeChildWatcher() + with warnings.catch_warnings(): + warnings.simplefilter("ignore", DeprecationWarning) + return asyncio.SafeChildWatcher() class FastChildWatcherTests (ChildWatcherTestsMixin, test_utils.TestCase): def create_watcher(self): - return asyncio.FastChildWatcher() + with warnings.catch_warnings(): + warnings.simplefilter("ignore", DeprecationWarning) + return asyncio.FastChildWatcher() class PolicyTests(unittest.TestCase): @@ -1698,24 +1712,40 @@ class PolicyTests(unittest.TestCase): def create_policy(self): return asyncio.DefaultEventLoopPolicy() - def test_get_default_child_watcher(self): + @mock.patch('asyncio.unix_events.can_use_pidfd') + def test_get_default_child_watcher(self, m_can_use_pidfd): + m_can_use_pidfd.return_value = False policy = self.create_policy() self.assertIsNone(policy._watcher) - - watcher = policy.get_child_watcher() + with self.assertWarns(DeprecationWarning): + watcher = policy.get_child_watcher() self.assertIsInstance(watcher, asyncio.ThreadedChildWatcher) self.assertIs(policy._watcher, watcher) + with self.assertWarns(DeprecationWarning): + self.assertIs(watcher, policy.get_child_watcher()) - self.assertIs(watcher, policy.get_child_watcher()) + m_can_use_pidfd.return_value = True + policy = self.create_policy() + self.assertIsNone(policy._watcher) + with self.assertWarns(DeprecationWarning): + watcher = policy.get_child_watcher() + self.assertIsInstance(watcher, asyncio.PidfdChildWatcher) + + self.assertIs(policy._watcher, watcher) + with self.assertWarns(DeprecationWarning): + self.assertIs(watcher, policy.get_child_watcher()) def test_get_child_watcher_after_set(self): policy = self.create_policy() - watcher = asyncio.FastChildWatcher() + with warnings.catch_warnings(): + warnings.simplefilter("ignore", DeprecationWarning) + watcher = asyncio.FastChildWatcher() + policy.set_child_watcher(watcher) - policy.set_child_watcher(watcher) self.assertIs(policy._watcher, watcher) - self.assertIs(watcher, policy.get_child_watcher()) + with self.assertWarns(DeprecationWarning): + self.assertIs(watcher, policy.get_child_watcher()) def test_get_child_watcher_thread(self): @@ -1724,7 +1754,9 @@ class PolicyTests(unittest.TestCase): self.assertIsInstance(policy.get_event_loop(), asyncio.AbstractEventLoop) - watcher = policy.get_child_watcher() + with warnings.catch_warnings(): + warnings.simplefilter("ignore", DeprecationWarning) + watcher = policy.get_child_watcher() self.assertIsInstance(watcher, asyncio.SafeChildWatcher) self.assertIsNone(watcher._loop) @@ -1732,7 +1764,9 @@ class PolicyTests(unittest.TestCase): policy.get_event_loop().close() policy = self.create_policy() - policy.set_child_watcher(asyncio.SafeChildWatcher()) + with warnings.catch_warnings(): + warnings.simplefilter("ignore", DeprecationWarning) + policy.set_child_watcher(asyncio.SafeChildWatcher()) th = threading.Thread(target=f) th.start() @@ -1745,8 +1779,10 @@ class PolicyTests(unittest.TestCase): # Explicitly setup SafeChildWatcher, # default ThreadedChildWatcher has no _loop property - watcher = asyncio.SafeChildWatcher() - policy.set_child_watcher(watcher) + with warnings.catch_warnings(): + warnings.simplefilter("ignore", DeprecationWarning) + watcher = asyncio.SafeChildWatcher() + policy.set_child_watcher(watcher) watcher.attach_loop(loop) self.assertIs(watcher._loop, loop) @@ -1834,5 +1870,105 @@ class TestFunctional(unittest.TestCase): wsock.close() +@unittest.skipUnless(hasattr(os, 'fork'), 'requires os.fork()') +class TestFork(unittest.IsolatedAsyncioTestCase): + + async def test_fork_not_share_event_loop(self): + # The forked process should not share the event loop with the parent + loop = asyncio.get_running_loop() + r, w = os.pipe() + self.addCleanup(os.close, r) + self.addCleanup(os.close, w) + pid = os.fork() + if pid == 0: + # child + try: + with self.assertWarns(DeprecationWarning): + loop = asyncio.get_event_loop_policy().get_event_loop() + os.write(w, b'LOOP:' + str(id(loop)).encode()) + except RuntimeError: + os.write(w, b'NO LOOP') + except BaseException as e: + os.write(w, b'ERROR:' + ascii(e).encode()) + finally: + os._exit(0) + else: + # parent + result = os.read(r, 100) + self.assertEqual(result[:5], b'LOOP:', result) + self.assertNotEqual(int(result[5:]), id(loop)) + wait_process(pid, exitcode=0) + + @hashlib_helper.requires_hashdigest('md5') + def test_fork_signal_handling(self): + # Sending signal to the forked process should not affect the parent + # process + ctx = multiprocessing.get_context('fork') + manager = ctx.Manager() + self.addCleanup(manager.shutdown) + child_started = manager.Event() + child_handled = manager.Event() + parent_handled = manager.Event() + + def child_main(): + signal.signal(signal.SIGTERM, lambda *args: child_handled.set()) + child_started.set() + + async def main(): + loop = asyncio.get_running_loop() + loop.add_signal_handler(signal.SIGTERM, lambda *args: parent_handled.set()) + + process = ctx.Process(target=child_main) + process.start() + child_started.wait() + os.kill(process.pid, signal.SIGTERM) + process.join() + + async def func(): + await asyncio.sleep(0.1) + return 42 + + # Test parent's loop is still functional + self.assertEqual(await asyncio.create_task(func()), 42) + + asyncio.run(main()) + + self.assertFalse(parent_handled.is_set()) + self.assertTrue(child_handled.is_set()) + + @hashlib_helper.requires_hashdigest('md5') + def test_fork_asyncio_run(self): + ctx = multiprocessing.get_context('fork') + manager = ctx.Manager() + self.addCleanup(manager.shutdown) + result = manager.Value('i', 0) + + async def child_main(): + await asyncio.sleep(0.1) + result.value = 42 + + process = ctx.Process(target=lambda: asyncio.run(child_main())) + process.start() + process.join() + + self.assertEqual(result.value, 42) + + @hashlib_helper.requires_hashdigest('md5') + def test_fork_asyncio_subprocess(self): + ctx = multiprocessing.get_context('fork') + manager = ctx.Manager() + self.addCleanup(manager.shutdown) + result = manager.Value('i', 1) + + async def child_main(): + proc = await asyncio.create_subprocess_exec(sys.executable, '-c', 'pass') + result.value = await proc.wait() + + process = ctx.Process(target=lambda: asyncio.run(child_main())) + process.start() + process.join() + + self.assertEqual(result.value, 0) + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_asyncio/test_waitfor.py b/Lib/test/test_asyncio/test_waitfor.py index 45498fa0..d5c02ba4 100644 --- a/Lib/test/test_asyncio/test_waitfor.py +++ b/Lib/test/test_asyncio/test_waitfor.py @@ -159,7 +159,7 @@ class AsyncioWaitForTest(unittest.IsolatedAsyncioTestCase): fut = loop.create_future() task = asyncio.wait_for(fut, timeout=0.2) - loop.call_later(0.1, fut.set_result, "ok") + loop.call_soon(fut.set_result, "ok") res = await task self.assertEqual(res, "ok") @@ -237,33 +237,6 @@ class AsyncioWaitForTest(unittest.IsolatedAsyncioTestCase): with self.assertRaises(FooException): await foo() - async def test_wait_for_self_cancellation(self): - async def inner(): - try: - await asyncio.sleep(0.3) - except asyncio.CancelledError: - try: - await asyncio.sleep(0.3) - except asyncio.CancelledError: - await asyncio.sleep(0.3) - - return 42 - - inner_task = asyncio.create_task(inner()) - - wait = asyncio.wait_for(inner_task, timeout=0.1) - - # Test that wait_for itself is properly cancellable - # even when the initial task holds up the initial cancellation. - task = asyncio.create_task(wait) - await asyncio.sleep(0.2) - task.cancel() - - with self.assertRaises(asyncio.CancelledError): - await task - - self.assertEqual(await inner_task, 42) - async def _test_cancel_wait_for(self, timeout): loop = asyncio.get_running_loop() @@ -289,6 +262,106 @@ class AsyncioWaitForTest(unittest.IsolatedAsyncioTestCase): async def test_cancel_wait_for(self): await self._test_cancel_wait_for(60.0) + async def test_wait_for_cancel_suppressed(self): + # GH-86296: Supressing CancelledError is discouraged + # but if a task subpresses CancelledError and returns a value, + # `wait_for` should return the value instead of raising CancelledError. + # This is the same behavior as `asyncio.timeout`. + + async def return_42(): + try: + await asyncio.sleep(10) + except asyncio.CancelledError: + return 42 + + res = await asyncio.wait_for(return_42(), timeout=0.1) + self.assertEqual(res, 42) + + + async def test_wait_for_issue86296(self): + # GH-86296: The task should get cancelled and not run to completion. + # inner completes in one cycle of the event loop so it + # completes before the task is cancelled. + + async def inner(): + return 'done' + + inner_task = asyncio.create_task(inner()) + reached_end = False + + async def wait_for_coro(): + await asyncio.wait_for(inner_task, timeout=100) + await asyncio.sleep(1) + nonlocal reached_end + reached_end = True + + task = asyncio.create_task(wait_for_coro()) + self.assertFalse(task.done()) + # Run the task + await asyncio.sleep(0) + task.cancel() + with self.assertRaises(asyncio.CancelledError): + await task + self.assertTrue(inner_task.done()) + self.assertEqual(await inner_task, 'done') + self.assertFalse(reached_end) + + +class WaitForShieldTests(unittest.IsolatedAsyncioTestCase): + + async def test_zero_timeout(self): + # `asyncio.shield` creates a new task which wraps the passed in + # awaitable and shields it from cancellation so with timeout=0 + # the task returned by `asyncio.shield` aka shielded_task gets + # cancelled immediately and the task wrapped by it is scheduled + # to run. + + async def coro(): + await asyncio.sleep(0.01) + return 'done' + + task = asyncio.create_task(coro()) + with self.assertRaises(asyncio.TimeoutError): + shielded_task = asyncio.shield(task) + await asyncio.wait_for(shielded_task, timeout=0) + + # Task is running in background + self.assertFalse(task.done()) + self.assertFalse(task.cancelled()) + self.assertTrue(shielded_task.cancelled()) + + # Wait for the task to complete + await asyncio.sleep(0.1) + self.assertTrue(task.done()) + + + async def test_none_timeout(self): + # With timeout=None the timeout is disabled so it + # runs till completion. + async def coro(): + await asyncio.sleep(0.1) + return 'done' + + task = asyncio.create_task(coro()) + await asyncio.wait_for(asyncio.shield(task), timeout=None) + + self.assertTrue(task.done()) + self.assertEqual(await task, "done") + + async def test_shielded_timeout(self): + # shield prevents the task from being cancelled. + async def coro(): + await asyncio.sleep(0.1) + return 'done' + + task = asyncio.create_task(coro()) + with self.assertRaises(asyncio.TimeoutError): + await asyncio.wait_for(asyncio.shield(task), timeout=0.01) + + self.assertFalse(task.done()) + self.assertFalse(task.cancelled()) + self.assertEqual(await task, "done") + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_asyncio/utils.py b/Lib/test/test_asyncio/utils.py index c32494d4..6dee5bb3 100644 --- a/Lib/test/test_asyncio/utils.py +++ b/Lib/test/test_asyncio/utils.py @@ -11,12 +11,10 @@ import selectors import socket import socketserver import sys -import tempfile import threading -import time import unittest import weakref - +import warnings from unittest import mock from http.server import HTTPServer @@ -34,6 +32,7 @@ from asyncio import futures from asyncio import tasks from asyncio.log import logger from test import support +from test.support import socket_helper from test.support import threading_helper @@ -109,13 +108,14 @@ def run_briefly(loop): def run_until(loop, pred, timeout=support.SHORT_TIMEOUT): - deadline = time.monotonic() + timeout - while not pred(): - if timeout is not None: - timeout = deadline - time.monotonic() - if timeout <= 0: - raise futures.TimeoutError() - loop.run_until_complete(tasks.sleep(0.001)) + delay = 0.001 + for _ in support.busy_retry(timeout, error=False): + if pred(): + break + loop.run_until_complete(tasks.sleep(delay)) + delay = max(delay * 2, 1.0) + else: + raise futures.TimeoutError() def run_once(loop): @@ -250,8 +250,7 @@ if hasattr(socket, 'AF_UNIX'): def gen_unix_socket_path(): - with tempfile.NamedTemporaryFile() as file: - return file.name + return socket_helper.create_unix_domain_name() @contextlib.contextmanager @@ -545,7 +544,9 @@ class TestCase(unittest.TestCase): policy = support.maybe_get_event_loop_policy() if policy is not None: try: - watcher = policy.get_child_watcher() + with warnings.catch_warnings(): + warnings.simplefilter('ignore', DeprecationWarning) + watcher = policy.get_child_watcher() except NotImplementedError: # watcher is not implemented by EventLoopPolicy, e.g. Windows pass @@ -576,7 +577,7 @@ class TestCase(unittest.TestCase): # Detect CPython bug #23353: ensure that yield/yield-from is not used # in an except block of a generator - self.assertEqual(sys.exc_info(), (None, None, None)) + self.assertIsNone(sys.exception()) self.doCleanups() threading_helper.threading_cleanup(*self._thread_cleanup) diff --git a/Lib/test/test_asyncore.py b/Lib/test/test_asyncore.py deleted file mode 100644 index 98ccd3a9..00000000 --- a/Lib/test/test_asyncore.py +++ /dev/null @@ -1,840 +0,0 @@ -import unittest -import select -import os -import socket -import sys -import time -import errno -import struct -import threading - -from test import support -from test.support import os_helper -from test.support import socket_helper -from test.support import threading_helper -from test.support import warnings_helper -from io import BytesIO - -if support.PGO: - raise unittest.SkipTest("test is not helpful for PGO") - -support.requires_working_socket(module=True) - -asyncore = warnings_helper.import_deprecated('asyncore') - - -HAS_UNIX_SOCKETS = hasattr(socket, 'AF_UNIX') - -class dummysocket: - def __init__(self): - self.closed = False - - def close(self): - self.closed = True - - def fileno(self): - return 42 - -class dummychannel: - def __init__(self): - self.socket = dummysocket() - - def close(self): - self.socket.close() - -class exitingdummy: - def __init__(self): - pass - - def handle_read_event(self): - raise asyncore.ExitNow() - - handle_write_event = handle_read_event - handle_close = handle_read_event - handle_expt_event = handle_read_event - -class crashingdummy: - def __init__(self): - self.error_handled = False - - def handle_read_event(self): - raise Exception() - - handle_write_event = handle_read_event - handle_close = handle_read_event - handle_expt_event = handle_read_event - - def handle_error(self): - self.error_handled = True - -# used when testing senders; just collects what it gets until newline is sent -def capture_server(evt, buf, serv): - try: - serv.listen() - conn, addr = serv.accept() - except TimeoutError: - pass - else: - n = 200 - start = time.monotonic() - while n > 0 and time.monotonic() - start < 3.0: - r, w, e = select.select([conn], [], [], 0.1) - if r: - n -= 1 - data = conn.recv(10) - # keep everything except for the newline terminator - buf.write(data.replace(b'\n', b'')) - if b'\n' in data: - break - time.sleep(0.01) - - conn.close() - finally: - serv.close() - evt.set() - -def bind_af_aware(sock, addr): - """Helper function to bind a socket according to its family.""" - if HAS_UNIX_SOCKETS and sock.family == socket.AF_UNIX: - # Make sure the path doesn't exist. - os_helper.unlink(addr) - socket_helper.bind_unix_socket(sock, addr) - else: - sock.bind(addr) - - -class HelperFunctionTests(unittest.TestCase): - def test_readwriteexc(self): - # Check exception handling behavior of read, write and _exception - - # check that ExitNow exceptions in the object handler method - # bubbles all the way up through asyncore read/write/_exception calls - tr1 = exitingdummy() - self.assertRaises(asyncore.ExitNow, asyncore.read, tr1) - self.assertRaises(asyncore.ExitNow, asyncore.write, tr1) - self.assertRaises(asyncore.ExitNow, asyncore._exception, tr1) - - # check that an exception other than ExitNow in the object handler - # method causes the handle_error method to get called - tr2 = crashingdummy() - asyncore.read(tr2) - self.assertEqual(tr2.error_handled, True) - - tr2 = crashingdummy() - asyncore.write(tr2) - self.assertEqual(tr2.error_handled, True) - - tr2 = crashingdummy() - asyncore._exception(tr2) - self.assertEqual(tr2.error_handled, True) - - # asyncore.readwrite uses constants in the select module that - # are not present in Windows systems (see this thread: - # http://mail.python.org/pipermail/python-list/2001-October/109973.html) - # These constants should be present as long as poll is available - - @unittest.skipUnless(hasattr(select, 'poll'), 'select.poll required') - def test_readwrite(self): - # Check that correct methods are called by readwrite() - - attributes = ('read', 'expt', 'write', 'closed', 'error_handled') - - expected = ( - (select.POLLIN, 'read'), - (select.POLLPRI, 'expt'), - (select.POLLOUT, 'write'), - (select.POLLERR, 'closed'), - (select.POLLHUP, 'closed'), - (select.POLLNVAL, 'closed'), - ) - - class testobj: - def __init__(self): - self.read = False - self.write = False - self.closed = False - self.expt = False - self.error_handled = False - - def handle_read_event(self): - self.read = True - - def handle_write_event(self): - self.write = True - - def handle_close(self): - self.closed = True - - def handle_expt_event(self): - self.expt = True - - def handle_error(self): - self.error_handled = True - - for flag, expectedattr in expected: - tobj = testobj() - self.assertEqual(getattr(tobj, expectedattr), False) - asyncore.readwrite(tobj, flag) - - # Only the attribute modified by the routine we expect to be - # called should be True. - for attr in attributes: - self.assertEqual(getattr(tobj, attr), attr==expectedattr) - - # check that ExitNow exceptions in the object handler method - # bubbles all the way up through asyncore readwrite call - tr1 = exitingdummy() - self.assertRaises(asyncore.ExitNow, asyncore.readwrite, tr1, flag) - - # check that an exception other than ExitNow in the object handler - # method causes the handle_error method to get called - tr2 = crashingdummy() - self.assertEqual(tr2.error_handled, False) - asyncore.readwrite(tr2, flag) - self.assertEqual(tr2.error_handled, True) - - def test_closeall(self): - self.closeall_check(False) - - def test_closeall_default(self): - self.closeall_check(True) - - def closeall_check(self, usedefault): - # Check that close_all() closes everything in a given map - - l = [] - testmap = {} - for i in range(10): - c = dummychannel() - l.append(c) - self.assertEqual(c.socket.closed, False) - testmap[i] = c - - if usedefault: - socketmap = asyncore.socket_map - try: - asyncore.socket_map = testmap - asyncore.close_all() - finally: - testmap, asyncore.socket_map = asyncore.socket_map, socketmap - else: - asyncore.close_all(testmap) - - self.assertEqual(len(testmap), 0) - - for c in l: - self.assertEqual(c.socket.closed, True) - - def test_compact_traceback(self): - try: - raise Exception("I don't like spam!") - except: - real_t, real_v, real_tb = sys.exc_info() - r = asyncore.compact_traceback() - else: - self.fail("Expected exception") - - (f, function, line), t, v, info = r - self.assertEqual(os.path.split(f)[-1], 'test_asyncore.py') - self.assertEqual(function, 'test_compact_traceback') - self.assertEqual(t, real_t) - self.assertEqual(v, real_v) - self.assertEqual(info, '[%s|%s|%s]' % (f, function, line)) - - -class DispatcherTests(unittest.TestCase): - def setUp(self): - pass - - def tearDown(self): - asyncore.close_all() - - def test_basic(self): - d = asyncore.dispatcher() - self.assertEqual(d.readable(), True) - self.assertEqual(d.writable(), True) - - def test_repr(self): - d = asyncore.dispatcher() - self.assertEqual(repr(d), '<asyncore.dispatcher at %#x>' % id(d)) - - def test_log(self): - d = asyncore.dispatcher() - - # capture output of dispatcher.log() (to stderr) - l1 = "Lovely spam! Wonderful spam!" - l2 = "I don't like spam!" - with support.captured_stderr() as stderr: - d.log(l1) - d.log(l2) - - lines = stderr.getvalue().splitlines() - self.assertEqual(lines, ['log: %s' % l1, 'log: %s' % l2]) - - def test_log_info(self): - d = asyncore.dispatcher() - - # capture output of dispatcher.log_info() (to stdout via print) - l1 = "Have you got anything without spam?" - l2 = "Why can't she have egg bacon spam and sausage?" - l3 = "THAT'S got spam in it!" - with support.captured_stdout() as stdout: - d.log_info(l1, 'EGGS') - d.log_info(l2) - d.log_info(l3, 'SPAM') - - lines = stdout.getvalue().splitlines() - expected = ['EGGS: %s' % l1, 'info: %s' % l2, 'SPAM: %s' % l3] - self.assertEqual(lines, expected) - - def test_unhandled(self): - d = asyncore.dispatcher() - d.ignore_log_types = () - - # capture output of dispatcher.log_info() (to stdout via print) - with support.captured_stdout() as stdout: - d.handle_expt() - d.handle_read() - d.handle_write() - d.handle_connect() - - lines = stdout.getvalue().splitlines() - expected = ['warning: unhandled incoming priority event', - 'warning: unhandled read event', - 'warning: unhandled write event', - 'warning: unhandled connect event'] - self.assertEqual(lines, expected) - - def test_strerror(self): - # refers to bug #8573 - err = asyncore._strerror(errno.EPERM) - if hasattr(os, 'strerror'): - self.assertEqual(err, os.strerror(errno.EPERM)) - err = asyncore._strerror(-1) - self.assertTrue(err != "") - - -class dispatcherwithsend_noread(asyncore.dispatcher_with_send): - def readable(self): - return False - - def handle_connect(self): - pass - - -class DispatcherWithSendTests(unittest.TestCase): - def setUp(self): - pass - - def tearDown(self): - asyncore.close_all() - - @threading_helper.reap_threads - def test_send(self): - evt = threading.Event() - sock = socket.socket() - sock.settimeout(3) - port = socket_helper.bind_port(sock) - - cap = BytesIO() - args = (evt, cap, sock) - t = threading.Thread(target=capture_server, args=args) - t.start() - try: - # wait a little longer for the server to initialize (it sometimes - # refuses connections on slow machines without this wait) - time.sleep(0.2) - - data = b"Suppose there isn't a 16-ton weight?" - d = dispatcherwithsend_noread() - d.create_socket() - d.connect((socket_helper.HOST, port)) - - # give time for socket to connect - time.sleep(0.1) - - d.send(data) - d.send(data) - d.send(b'\n') - - n = 1000 - while d.out_buffer and n > 0: - asyncore.poll() - n -= 1 - - evt.wait() - - self.assertEqual(cap.getvalue(), data*2) - finally: - threading_helper.join_thread(t) - - -@unittest.skipUnless(hasattr(asyncore, 'file_wrapper'), - 'asyncore.file_wrapper required') -class FileWrapperTest(unittest.TestCase): - def setUp(self): - self.d = b"It's not dead, it's sleeping!" - with open(os_helper.TESTFN, 'wb') as file: - file.write(self.d) - - def tearDown(self): - os_helper.unlink(os_helper.TESTFN) - - def test_recv(self): - fd = os.open(os_helper.TESTFN, os.O_RDONLY) - w = asyncore.file_wrapper(fd) - os.close(fd) - - self.assertNotEqual(w.fd, fd) - self.assertNotEqual(w.fileno(), fd) - self.assertEqual(w.recv(13), b"It's not dead") - self.assertEqual(w.read(6), b", it's") - w.close() - self.assertRaises(OSError, w.read, 1) - - def test_send(self): - d1 = b"Come again?" - d2 = b"I want to buy some cheese." - fd = os.open(os_helper.TESTFN, os.O_WRONLY | os.O_APPEND) - w = asyncore.file_wrapper(fd) - os.close(fd) - - w.write(d1) - w.send(d2) - w.close() - with open(os_helper.TESTFN, 'rb') as file: - self.assertEqual(file.read(), self.d + d1 + d2) - - @unittest.skipUnless(hasattr(asyncore, 'file_dispatcher'), - 'asyncore.file_dispatcher required') - def test_dispatcher(self): - fd = os.open(os_helper.TESTFN, os.O_RDONLY) - data = [] - class FileDispatcher(asyncore.file_dispatcher): - def handle_read(self): - data.append(self.recv(29)) - s = FileDispatcher(fd) - os.close(fd) - asyncore.loop(timeout=0.01, use_poll=True, count=2) - self.assertEqual(b"".join(data), self.d) - - def test_resource_warning(self): - # Issue #11453 - fd = os.open(os_helper.TESTFN, os.O_RDONLY) - f = asyncore.file_wrapper(fd) - - os.close(fd) - with warnings_helper.check_warnings(('', ResourceWarning)): - f = None - support.gc_collect() - - def test_close_twice(self): - fd = os.open(os_helper.TESTFN, os.O_RDONLY) - f = asyncore.file_wrapper(fd) - os.close(fd) - - os.close(f.fd) # file_wrapper dupped fd - with self.assertRaises(OSError): - f.close() - - self.assertEqual(f.fd, -1) - # calling close twice should not fail - f.close() - - -class BaseTestHandler(asyncore.dispatcher): - - def __init__(self, sock=None): - asyncore.dispatcher.__init__(self, sock) - self.flag = False - - def handle_accept(self): - raise Exception("handle_accept not supposed to be called") - - def handle_accepted(self): - raise Exception("handle_accepted not supposed to be called") - - def handle_connect(self): - raise Exception("handle_connect not supposed to be called") - - def handle_expt(self): - raise Exception("handle_expt not supposed to be called") - - def handle_close(self): - raise Exception("handle_close not supposed to be called") - - def handle_error(self): - raise - - -class BaseServer(asyncore.dispatcher): - """A server which listens on an address and dispatches the - connection to a handler. - """ - - def __init__(self, family, addr, handler=BaseTestHandler): - asyncore.dispatcher.__init__(self) - self.create_socket(family) - self.set_reuse_addr() - bind_af_aware(self.socket, addr) - self.listen(5) - self.handler = handler - - @property - def address(self): - return self.socket.getsockname() - - def handle_accepted(self, sock, addr): - self.handler(sock) - - def handle_error(self): - raise - - -class BaseClient(BaseTestHandler): - - def __init__(self, family, address): - BaseTestHandler.__init__(self) - self.create_socket(family) - self.connect(address) - - def handle_connect(self): - pass - - -class BaseTestAPI: - - def tearDown(self): - asyncore.close_all(ignore_all=True) - - def loop_waiting_for_flag(self, instance, timeout=5): - timeout = float(timeout) / 100 - count = 100 - while asyncore.socket_map and count > 0: - asyncore.loop(timeout=0.01, count=1, use_poll=self.use_poll) - if instance.flag: - return - count -= 1 - time.sleep(timeout) - self.fail("flag not set") - - def test_handle_connect(self): - # make sure handle_connect is called on connect() - - class TestClient(BaseClient): - def handle_connect(self): - self.flag = True - - server = BaseServer(self.family, self.addr) - client = TestClient(self.family, server.address) - self.loop_waiting_for_flag(client) - - def test_handle_accept(self): - # make sure handle_accept() is called when a client connects - - class TestListener(BaseTestHandler): - - def __init__(self, family, addr): - BaseTestHandler.__init__(self) - self.create_socket(family) - bind_af_aware(self.socket, addr) - self.listen(5) - self.address = self.socket.getsockname() - - def handle_accept(self): - self.flag = True - - server = TestListener(self.family, self.addr) - client = BaseClient(self.family, server.address) - self.loop_waiting_for_flag(server) - - def test_handle_accepted(self): - # make sure handle_accepted() is called when a client connects - - class TestListener(BaseTestHandler): - - def __init__(self, family, addr): - BaseTestHandler.__init__(self) - self.create_socket(family) - bind_af_aware(self.socket, addr) - self.listen(5) - self.address = self.socket.getsockname() - - def handle_accept(self): - asyncore.dispatcher.handle_accept(self) - - def handle_accepted(self, sock, addr): - sock.close() - self.flag = True - - server = TestListener(self.family, self.addr) - client = BaseClient(self.family, server.address) - self.loop_waiting_for_flag(server) - - - def test_handle_read(self): - # make sure handle_read is called on data received - - class TestClient(BaseClient): - def handle_read(self): - self.flag = True - - class TestHandler(BaseTestHandler): - def __init__(self, conn): - BaseTestHandler.__init__(self, conn) - self.send(b'x' * 1024) - - server = BaseServer(self.family, self.addr, TestHandler) - client = TestClient(self.family, server.address) - self.loop_waiting_for_flag(client) - - def test_handle_write(self): - # make sure handle_write is called - - class TestClient(BaseClient): - def handle_write(self): - self.flag = True - - server = BaseServer(self.family, self.addr) - client = TestClient(self.family, server.address) - self.loop_waiting_for_flag(client) - - def test_handle_close(self): - # make sure handle_close is called when the other end closes - # the connection - - class TestClient(BaseClient): - - def handle_read(self): - # in order to make handle_close be called we are supposed - # to make at least one recv() call - self.recv(1024) - - def handle_close(self): - self.flag = True - self.close() - - class TestHandler(BaseTestHandler): - def __init__(self, conn): - BaseTestHandler.__init__(self, conn) - self.close() - - server = BaseServer(self.family, self.addr, TestHandler) - client = TestClient(self.family, server.address) - self.loop_waiting_for_flag(client) - - def test_handle_close_after_conn_broken(self): - # Check that ECONNRESET/EPIPE is correctly handled (issues #5661 and - # #11265). - - data = b'\0' * 128 - - class TestClient(BaseClient): - - def handle_write(self): - self.send(data) - - def handle_close(self): - self.flag = True - self.close() - - def handle_expt(self): - self.flag = True - self.close() - - class TestHandler(BaseTestHandler): - - def handle_read(self): - self.recv(len(data)) - self.close() - - def writable(self): - return False - - server = BaseServer(self.family, self.addr, TestHandler) - client = TestClient(self.family, server.address) - self.loop_waiting_for_flag(client) - - @unittest.skipIf(sys.platform.startswith("sunos"), - "OOB support is broken on Solaris") - def test_handle_expt(self): - # Make sure handle_expt is called on OOB data received. - # Note: this might fail on some platforms as OOB data is - # tenuously supported and rarely used. - if HAS_UNIX_SOCKETS and self.family == socket.AF_UNIX: - self.skipTest("Not applicable to AF_UNIX sockets.") - - if sys.platform == "darwin" and self.use_poll: - self.skipTest("poll may fail on macOS; see issue #28087") - - class TestClient(BaseClient): - def handle_expt(self): - self.socket.recv(1024, socket.MSG_OOB) - self.flag = True - - class TestHandler(BaseTestHandler): - def __init__(self, conn): - BaseTestHandler.__init__(self, conn) - self.socket.send(bytes(chr(244), 'latin-1'), socket.MSG_OOB) - - server = BaseServer(self.family, self.addr, TestHandler) - client = TestClient(self.family, server.address) - self.loop_waiting_for_flag(client) - - def test_handle_error(self): - - class TestClient(BaseClient): - def handle_write(self): - 1.0 / 0 - def handle_error(self): - self.flag = True - try: - raise - except ZeroDivisionError: - pass - else: - raise Exception("exception not raised") - - server = BaseServer(self.family, self.addr) - client = TestClient(self.family, server.address) - self.loop_waiting_for_flag(client) - - def test_connection_attributes(self): - server = BaseServer(self.family, self.addr) - client = BaseClient(self.family, server.address) - - # we start disconnected - self.assertFalse(server.connected) - self.assertTrue(server.accepting) - # this can't be taken for granted across all platforms - #self.assertFalse(client.connected) - self.assertFalse(client.accepting) - - # execute some loops so that client connects to server - asyncore.loop(timeout=0.01, use_poll=self.use_poll, count=100) - self.assertFalse(server.connected) - self.assertTrue(server.accepting) - self.assertTrue(client.connected) - self.assertFalse(client.accepting) - - # disconnect the client - client.close() - self.assertFalse(server.connected) - self.assertTrue(server.accepting) - self.assertFalse(client.connected) - self.assertFalse(client.accepting) - - # stop serving - server.close() - self.assertFalse(server.connected) - self.assertFalse(server.accepting) - - def test_create_socket(self): - s = asyncore.dispatcher() - s.create_socket(self.family) - self.assertEqual(s.socket.type, socket.SOCK_STREAM) - self.assertEqual(s.socket.family, self.family) - self.assertEqual(s.socket.gettimeout(), 0) - self.assertFalse(s.socket.get_inheritable()) - - def test_bind(self): - if HAS_UNIX_SOCKETS and self.family == socket.AF_UNIX: - self.skipTest("Not applicable to AF_UNIX sockets.") - s1 = asyncore.dispatcher() - s1.create_socket(self.family) - s1.bind(self.addr) - s1.listen(5) - port = s1.socket.getsockname()[1] - - s2 = asyncore.dispatcher() - s2.create_socket(self.family) - # EADDRINUSE indicates the socket was correctly bound - self.assertRaises(OSError, s2.bind, (self.addr[0], port)) - - def test_set_reuse_addr(self): - if HAS_UNIX_SOCKETS and self.family == socket.AF_UNIX: - self.skipTest("Not applicable to AF_UNIX sockets.") - - with socket.socket(self.family) as sock: - try: - sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - except OSError: - unittest.skip("SO_REUSEADDR not supported on this platform") - else: - # if SO_REUSEADDR succeeded for sock we expect asyncore - # to do the same - s = asyncore.dispatcher(socket.socket(self.family)) - self.assertFalse(s.socket.getsockopt(socket.SOL_SOCKET, - socket.SO_REUSEADDR)) - s.socket.close() - s.create_socket(self.family) - s.set_reuse_addr() - self.assertTrue(s.socket.getsockopt(socket.SOL_SOCKET, - socket.SO_REUSEADDR)) - - @threading_helper.reap_threads - def test_quick_connect(self): - # see: http://bugs.python.org/issue10340 - if self.family not in (socket.AF_INET, getattr(socket, "AF_INET6", object())): - self.skipTest("test specific to AF_INET and AF_INET6") - - server = BaseServer(self.family, self.addr) - # run the thread 500 ms: the socket should be connected in 200 ms - t = threading.Thread(target=lambda: asyncore.loop(timeout=0.1, - count=5)) - t.start() - try: - with socket.socket(self.family, socket.SOCK_STREAM) as s: - s.settimeout(.2) - s.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER, - struct.pack('ii', 1, 0)) - - try: - s.connect(server.address) - except OSError: - pass - finally: - threading_helper.join_thread(t) - -class TestAPI_UseIPv4Sockets(BaseTestAPI): - family = socket.AF_INET - addr = (socket_helper.HOST, 0) - -@unittest.skipUnless(socket_helper.IPV6_ENABLED, 'IPv6 support required') -class TestAPI_UseIPv6Sockets(BaseTestAPI): - family = socket.AF_INET6 - addr = (socket_helper.HOSTv6, 0) - -@unittest.skipUnless(HAS_UNIX_SOCKETS, 'Unix sockets required') -class TestAPI_UseUnixSockets(BaseTestAPI): - if HAS_UNIX_SOCKETS: - family = socket.AF_UNIX - addr = os_helper.TESTFN - - def tearDown(self): - os_helper.unlink(self.addr) - BaseTestAPI.tearDown(self) - -class TestAPI_UseIPv4Select(TestAPI_UseIPv4Sockets, unittest.TestCase): - use_poll = False - -@unittest.skipUnless(hasattr(select, 'poll'), 'select.poll required') -class TestAPI_UseIPv4Poll(TestAPI_UseIPv4Sockets, unittest.TestCase): - use_poll = True - -class TestAPI_UseIPv6Select(TestAPI_UseIPv6Sockets, unittest.TestCase): - use_poll = False - -@unittest.skipUnless(hasattr(select, 'poll'), 'select.poll required') -class TestAPI_UseIPv6Poll(TestAPI_UseIPv6Sockets, unittest.TestCase): - use_poll = True - -class TestAPI_UseUnixSocketsSelect(TestAPI_UseUnixSockets, unittest.TestCase): - use_poll = False - -@unittest.skipUnless(hasattr(select, 'poll'), 'select.poll required') -class TestAPI_UseUnixSocketsPoll(TestAPI_UseUnixSockets, unittest.TestCase): - use_poll = True - -if __name__ == "__main__": - unittest.main() diff --git a/Lib/test/test_atexit.py b/Lib/test/test_atexit.py index 7ac063cf..913b7556 100644 --- a/Lib/test/test_atexit.py +++ b/Lib/test/test_atexit.py @@ -1,6 +1,5 @@ import atexit import os -import sys import textwrap import unittest from test import support diff --git a/Lib/test/test_audit.py b/Lib/test/test_audit.py index 75e96f06..b12ffa5d 100644 --- a/Lib/test/test_audit.py +++ b/Lib/test/test_audit.py @@ -186,6 +186,48 @@ class AuditTest(unittest.TestCase): self.assertEqual(actual, expected) + def test_sys_getframemodulename(self): + returncode, events, stderr = self.run_python("test_sys_getframemodulename") + if returncode: + self.fail(stderr) + + if support.verbose: + print(*events, sep='\n') + actual = [(ev[0], ev[2]) for ev in events] + expected = [("sys._getframemodulename", "0")] + + self.assertEqual(actual, expected) + + + def test_threading(self): + returncode, events, stderr = self.run_python("test_threading") + if returncode: + self.fail(stderr) + + if support.verbose: + print(*events, sep='\n') + actual = [(ev[0], ev[2]) for ev in events] + expected = [ + ("_thread.start_new_thread", "(<test_func>, (), None)"), + ("test.test_func", "()"), + ] + + self.assertEqual(actual, expected) + + + def test_wmi_exec_query(self): + import_helper.import_module("_wmi") + returncode, events, stderr = self.run_python("test_wmi_exec_query") + if returncode: + self.fail(stderr) + + if support.verbose: + print(*events, sep='\n') + actual = [(ev[0], ev[2]) for ev in events] + expected = [("_wmi.exec_query", "SELECT * FROM Win32_OperatingSystem")] + + self.assertEqual(actual, expected) + def test_syslog(self): syslog = import_helper.import_module("syslog") @@ -215,5 +257,18 @@ class AuditTest(unittest.TestCase): self.fail(stderr) + def test_sys_monitoring_register_callback(self): + returncode, events, stderr = self.run_python("test_sys_monitoring_register_callback") + if returncode: + self.fail(stderr) + + if support.verbose: + print(*events, sep='\n') + actual = [(ev[0], ev[2]) for ev in events] + expected = [("sys.monitoring.register_callback", "(None,)")] + + self.assertEqual(actual, expected) + + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_base64.py b/Lib/test/test_base64.py index 217f2945..fa03fa1d 100644 --- a/Lib/test/test_base64.py +++ b/Lib/test/test_base64.py @@ -31,6 +31,8 @@ class LegacyBase64TestCase(unittest.TestCase): b"YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpBQkNE" b"RUZHSElKS0xNTk9QUVJTVFVWV1hZWjAxMjM0\nNT" b"Y3ODkhQCMwXiYqKCk7Ojw+LC4gW117fQ==\n") + eq(base64.encodebytes(b"Aladdin:open sesame"), + b"QWxhZGRpbjpvcGVuIHNlc2FtZQ==\n") # Non-bytes eq(base64.encodebytes(bytearray(b'abc')), b'YWJj\n') eq(base64.encodebytes(memoryview(b'abc')), b'YWJj\n') @@ -50,6 +52,8 @@ class LegacyBase64TestCase(unittest.TestCase): b"ABCDEFGHIJKLMNOPQRSTUVWXYZ" b"0123456789!@#0^&*();:<>,. []{}") eq(base64.decodebytes(b''), b'') + eq(base64.decodebytes(b"QWxhZGRpbjpvcGVuIHNlc2FtZQ==\n"), + b"Aladdin:open sesame") # Non-bytes eq(base64.decodebytes(bytearray(b'YWJj\n')), b'abc') eq(base64.decodebytes(memoryview(b'YWJj\n')), b'abc') @@ -762,14 +766,6 @@ class TestMain(unittest.TestCase): def get_output(self, *args): return script_helper.assert_python_ok('-m', 'base64', *args).out - def test_encode_decode(self): - output = self.get_output('-t') - self.assertSequenceEqual(output.splitlines(), ( - b"b'Aladdin:open sesame'", - br"b'QWxhZGRpbjpvcGVuIHNlc2FtZQ==\n'", - b"b'Aladdin:open sesame'", - )) - def test_encode_file(self): with open(os_helper.TESTFN, 'wb') as fp: fp.write(b'a\xffb\n') diff --git a/Lib/test/test_bdb.py b/Lib/test/test_bdb.py index 87a5ac30..568c88e3 100644 --- a/Lib/test/test_bdb.py +++ b/Lib/test/test_bdb.py @@ -433,8 +433,9 @@ class TracerRun(): not_empty = '' if self.tracer.set_list: not_empty += 'All paired tuples have not been processed, ' - not_empty += ('the last one was number %d' % + not_empty += ('the last one was number %d\n' % self.tracer.expect_set_no) + not_empty += repr(self.tracer.set_list) # Make a BdbNotExpectedError a unittest failure. if type_ is not None and issubclass(BdbNotExpectedError, type_): @@ -1203,5 +1204,12 @@ class IssuesTestCase(BaseTestCase): tracer.runcall(tfunc_import) +class TestRegressions(unittest.TestCase): + def test_format_stack_entry_no_lineno(self): + # See gh-101517 + self.assertIn('Warning: lineno is None', + Bdb().format_stack_entry((sys._getframe(), None))) + + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_bigmem.py b/Lib/test/test_bigmem.py index 859f1539..c9ab1c1d 100644 --- a/Lib/test/test_bigmem.py +++ b/Lib/test/test_bigmem.py @@ -1248,6 +1248,15 @@ class ListTest(unittest.TestCase): self.assertEqual(l[-10:], [5] * 10) +class DictTest(unittest.TestCase): + + @bigmemtest(size=357913941, memuse=160) + def test_dict(self, size): + # https://github.com/python/cpython/issues/102701 + d = dict.fromkeys(range(size)) + d[size] = 1 + + if __name__ == '__main__': if len(sys.argv) > 1: support.set_memlimit(sys.argv[1]) diff --git a/Lib/test/test_binascii.py b/Lib/test/test_binascii.py index 7087d7a4..a2d7d029 100644 --- a/Lib/test/test_binascii.py +++ b/Lib/test/test_binascii.py @@ -4,7 +4,7 @@ import unittest import binascii import array import re -from test.support import bigmemtest, _1G, _4G, warnings_helper +from test.support import bigmemtest, _1G, _4G # Note: "*_hex" functions are aliases for "(un)hexlify" diff --git a/Lib/test/test_bisect.py b/Lib/test/test_bisect.py index ba108221..97204d4c 100644 --- a/Lib/test/test_bisect.py +++ b/Lib/test/test_bisect.py @@ -263,6 +263,34 @@ class TestBisect: for f in (self.module.insort_left, self.module.insort_right): self.assertRaises(TypeError, f, x, y, key = "b") + def test_lt_returns_non_bool(self): + class A: + def __init__(self, val): + self.val = val + def __lt__(self, other): + return "nonempty" if self.val < other.val else "" + + data = [A(i) for i in range(100)] + i1 = self.module.bisect_left(data, A(33)) + i2 = self.module.bisect_right(data, A(33)) + self.assertEqual(i1, 33) + self.assertEqual(i2, 34) + + def test_lt_returns_notimplemented(self): + class A: + def __init__(self, val): + self.val = val + def __lt__(self, other): + return NotImplemented + def __gt__(self, other): + return self.val > other.val + + data = [A(i) for i in range(100)] + i1 = self.module.bisect_left(data, A(40)) + i2 = self.module.bisect_right(data, A(40)) + self.assertEqual(i1, 40) + self.assertEqual(i2, 41) + class TestBisectPython(TestBisect, unittest.TestCase): module = py_bisect diff --git a/Lib/test/test_bool.py b/Lib/test/test_bool.py index f46f21da..34ecb45f 100644 --- a/Lib/test/test_bool.py +++ b/Lib/test/test_bool.py @@ -40,6 +40,12 @@ class BoolTest(unittest.TestCase): self.assertEqual(float(True), 1.0) self.assertIsNot(float(True), True) + def test_complex(self): + self.assertEqual(complex(False), 0j) + self.assertEqual(complex(False), False) + self.assertEqual(complex(True), 1+0j) + self.assertEqual(complex(True), True) + def test_math(self): self.assertEqual(+False, 0) self.assertIsNot(+False, False) @@ -52,8 +58,22 @@ class BoolTest(unittest.TestCase): self.assertEqual(-True, -1) self.assertEqual(abs(True), 1) self.assertIsNot(abs(True), True) - self.assertEqual(~False, -1) - self.assertEqual(~True, -2) + with self.assertWarns(DeprecationWarning): + # We need to put the bool in a variable, because the constant + # ~False is evaluated at compile time due to constant folding; + # consequently the DeprecationWarning would be issued during + # module loading and not during test execution. + false = False + self.assertEqual(~false, -1) + with self.assertWarns(DeprecationWarning): + # also check that the warning is issued in case of constant + # folding at compile time + self.assertEqual(eval("~False"), -1) + with self.assertWarns(DeprecationWarning): + true = True + self.assertEqual(~true, -2) + with self.assertWarns(DeprecationWarning): + self.assertEqual(eval("~True"), -2) self.assertEqual(False+2, 2) self.assertEqual(True+2, 3) @@ -313,6 +333,26 @@ class BoolTest(unittest.TestCase): return -1 self.assertRaises(ValueError, bool, Eggs()) + def test_interpreter_convert_to_bool_raises(self): + class SymbolicBool: + def __bool__(self): + raise TypeError + + class Symbol: + def __gt__(self, other): + return SymbolicBool() + + x = Symbol() + + with self.assertRaises(TypeError): + if x > 0: + msg = "x > 0 was true" + else: + msg = "x > 0 was false" + + # This used to create negative refcounts, see gh-102250 + del x + def test_from_bytes(self): self.assertIs(bool.from_bytes(b'\x00'*8, 'big'), False) self.assertIs(bool.from_bytes(b'abcd', 'little'), True) diff --git a/Lib/test/test_buffer.py b/Lib/test/test_buffer.py index 468c6ea9..aafbb8a9 100644 --- a/Lib/test/test_buffer.py +++ b/Lib/test/test_buffer.py @@ -17,6 +17,7 @@ import contextlib import unittest from test import support from test.support import os_helper +import inspect from itertools import permutations, product from random import randrange, sample, choice import warnings @@ -64,7 +65,7 @@ NATIVE = { '?':0, 'c':0, 'b':0, 'B':0, 'h':0, 'H':0, 'i':0, 'I':0, 'l':0, 'L':0, 'n':0, 'N':0, - 'f':0, 'd':0, 'P':0 + 'e':0, 'f':0, 'd':0, 'P':0 } # NumPy does not have 'n' or 'N': @@ -89,7 +90,8 @@ STANDARD = { 'i':(-(1<<31), 1<<31), 'I':(0, 1<<32), 'l':(-(1<<31), 1<<31), 'L':(0, 1<<32), 'q':(-(1<<63), 1<<63), 'Q':(0, 1<<64), - 'f':(-(1<<63), 1<<63), 'd':(-(1<<1023), 1<<1023) + 'e':(-65519, 65520), 'f':(-(1<<63), 1<<63), + 'd':(-(1<<1023), 1<<1023) } def native_type_range(fmt): @@ -98,6 +100,8 @@ def native_type_range(fmt): lh = (0, 256) elif fmt == '?': lh = (0, 2) + elif fmt == 'e': + lh = (-65519, 65520) elif fmt == 'f': lh = (-(1<<63), 1<<63) elif fmt == 'd': @@ -125,7 +129,10 @@ if struct: for fmt in fmtdict['@']: fmtdict['@'][fmt] = native_type_range(fmt) +# Format codes suppported by the memoryview object MEMORYVIEW = NATIVE.copy() + +# Format codes suppported by array.array ARRAY = NATIVE.copy() for k in NATIVE: if not k in "bBhHiIlLfd": @@ -164,7 +171,7 @@ def randrange_fmt(mode, char, obj): x = b'\x01' if char == '?': x = bool(x) - if char == 'f' or char == 'd': + if char in 'efd': x = struct.pack(char, x) x = struct.unpack(char, x)[0] return x @@ -959,8 +966,10 @@ class TestBufferProtocol(unittest.TestCase): self.assertEqual(m.strides, tuple(strides)) self.assertEqual(m.suboffsets, tuple(suboffsets)) - n = 1 if ndim == 0 else len(lst) - self.assertEqual(len(m), n) + if ndim == 0: + self.assertRaises(TypeError, len, m) + else: + self.assertEqual(len(m), len(lst)) rep = result.tolist() if fmt else result.tobytes() self.assertEqual(rep, lst) @@ -1019,6 +1028,7 @@ class TestBufferProtocol(unittest.TestCase): ndim=ndim, shape=shape, strides=strides, lst=lst, sliced=sliced) + @support.requires_resource('cpu') def test_ndarray_getbuf(self): requests = ( # distinct flags @@ -2246,7 +2256,7 @@ class TestBufferProtocol(unittest.TestCase): ### ### Fortran output: ### --------------- - ### >>> fortran_buf = nd.tostring(order='F') + ### >>> fortran_buf = nd.tobytes(order='F') ### >>> fortran_buf ### b'\x00\x04\x08\x01\x05\t\x02\x06\n\x03\x07\x0b' ### @@ -2289,7 +2299,7 @@ class TestBufferProtocol(unittest.TestCase): self.assertEqual(memoryview(y), memoryview(nd)) if numpy_array: - self.assertEqual(b, na.tostring(order='C')) + self.assertEqual(b, na.tobytes(order='C')) # 'F' request if f == 0: # 'C' to 'F' @@ -2312,7 +2322,7 @@ class TestBufferProtocol(unittest.TestCase): self.assertEqual(memoryview(y), memoryview(nd)) if numpy_array: - self.assertEqual(b, na.tostring(order='F')) + self.assertEqual(b, na.tobytes(order='F')) # 'A' request if f == ND_FORTRAN: @@ -2336,7 +2346,7 @@ class TestBufferProtocol(unittest.TestCase): self.assertEqual(memoryview(y), memoryview(nd)) if numpy_array: - self.assertEqual(b, na.tostring(order='A')) + self.assertEqual(b, na.tobytes(order='A')) # multi-dimensional, non-contiguous input nd = ndarray(list(range(12)), shape=[3, 4], flags=ND_WRITABLE|ND_PIL) @@ -2750,6 +2760,7 @@ class TestBufferProtocol(unittest.TestCase): m = memoryview(ex) iter_roundtrip(ex, m, items, fmt) + @support.requires_resource('cpu') def test_memoryview_cast_1D_ND(self): # Cast between C-contiguous buffers. At least one buffer must # be 1D, at least one format must be 'c', 'b' or 'B'. @@ -4430,5 +4441,329 @@ class TestBufferProtocol(unittest.TestCase): struct.calcsize(format)) +class TestPythonBufferProtocol(unittest.TestCase): + def test_basic(self): + class MyBuffer: + def __buffer__(self, flags): + return memoryview(b"hello") + + mv = memoryview(MyBuffer()) + self.assertEqual(mv.tobytes(), b"hello") + self.assertEqual(bytes(MyBuffer()), b"hello") + + def test_bad_buffer_method(self): + class MustReturnMV: + def __buffer__(self, flags): + return 42 + + self.assertRaises(TypeError, memoryview, MustReturnMV()) + + class NoBytesEither: + def __buffer__(self, flags): + return b"hello" + + self.assertRaises(TypeError, memoryview, NoBytesEither()) + + class WrongArity: + def __buffer__(self): + return memoryview(b"hello") + + self.assertRaises(TypeError, memoryview, WrongArity()) + + def test_release_buffer(self): + class WhatToRelease: + def __init__(self): + self.held = False + self.ba = bytearray(b"hello") + + def __buffer__(self, flags): + if self.held: + raise TypeError("already held") + self.held = True + return memoryview(self.ba) + + def __release_buffer__(self, buffer): + self.held = False + + wr = WhatToRelease() + self.assertFalse(wr.held) + with memoryview(wr) as mv: + self.assertTrue(wr.held) + self.assertEqual(mv.tobytes(), b"hello") + self.assertFalse(wr.held) + + def test_same_buffer_returned(self): + class WhatToRelease: + def __init__(self): + self.held = False + self.ba = bytearray(b"hello") + self.created_mv = None + + def __buffer__(self, flags): + if self.held: + raise TypeError("already held") + self.held = True + self.created_mv = memoryview(self.ba) + return self.created_mv + + def __release_buffer__(self, buffer): + assert buffer is self.created_mv + self.held = False + + wr = WhatToRelease() + self.assertFalse(wr.held) + with memoryview(wr) as mv: + self.assertTrue(wr.held) + self.assertEqual(mv.tobytes(), b"hello") + self.assertFalse(wr.held) + + def test_buffer_flags(self): + class PossiblyMutable: + def __init__(self, data, mutable) -> None: + self._data = bytearray(data) + self._mutable = mutable + + def __buffer__(self, flags): + if flags & inspect.BufferFlags.WRITABLE: + if not self._mutable: + raise RuntimeError("not mutable") + return memoryview(self._data) + else: + return memoryview(bytes(self._data)) + + mutable = PossiblyMutable(b"hello", True) + immutable = PossiblyMutable(b"hello", False) + with memoryview._from_flags(mutable, inspect.BufferFlags.WRITABLE) as mv: + self.assertEqual(mv.tobytes(), b"hello") + mv[0] = ord(b'x') + self.assertEqual(mv.tobytes(), b"xello") + with memoryview._from_flags(mutable, inspect.BufferFlags.SIMPLE) as mv: + self.assertEqual(mv.tobytes(), b"xello") + with self.assertRaises(TypeError): + mv[0] = ord(b'h') + self.assertEqual(mv.tobytes(), b"xello") + with memoryview._from_flags(immutable, inspect.BufferFlags.SIMPLE) as mv: + self.assertEqual(mv.tobytes(), b"hello") + with self.assertRaises(TypeError): + mv[0] = ord(b'x') + self.assertEqual(mv.tobytes(), b"hello") + + with self.assertRaises(RuntimeError): + memoryview._from_flags(immutable, inspect.BufferFlags.WRITABLE) + with memoryview(immutable) as mv: + self.assertEqual(mv.tobytes(), b"hello") + with self.assertRaises(TypeError): + mv[0] = ord(b'x') + self.assertEqual(mv.tobytes(), b"hello") + + def test_call_builtins(self): + ba = bytearray(b"hello") + mv = ba.__buffer__(0) + self.assertEqual(mv.tobytes(), b"hello") + ba.__release_buffer__(mv) + with self.assertRaises(OverflowError): + ba.__buffer__(sys.maxsize + 1) + + @unittest.skipIf(_testcapi is None, "requires _testcapi") + def test_c_buffer(self): + buf = _testcapi.testBuf() + self.assertEqual(buf.references, 0) + mv = buf.__buffer__(0) + self.assertIsInstance(mv, memoryview) + self.assertEqual(mv.tobytes(), b"test") + self.assertEqual(buf.references, 1) + buf.__release_buffer__(mv) + self.assertEqual(buf.references, 0) + with self.assertRaises(ValueError): + mv.tobytes() + # Calling it again doesn't cause issues + with self.assertRaises(ValueError): + buf.__release_buffer__(mv) + self.assertEqual(buf.references, 0) + + def test_inheritance(self): + class A(bytearray): + def __buffer__(self, flags): + return super().__buffer__(flags) + + a = A(b"hello") + mv = memoryview(a) + self.assertEqual(mv.tobytes(), b"hello") + + def test_inheritance_releasebuffer(self): + rb_call_count = 0 + class B(bytearray): + def __buffer__(self, flags): + return super().__buffer__(flags) + def __release_buffer__(self, view): + nonlocal rb_call_count + rb_call_count += 1 + super().__release_buffer__(view) + + b = B(b"hello") + with memoryview(b) as mv: + self.assertEqual(mv.tobytes(), b"hello") + self.assertEqual(rb_call_count, 0) + self.assertEqual(rb_call_count, 1) + + def test_inherit_but_return_something_else(self): + class A(bytearray): + def __buffer__(self, flags): + return memoryview(b"hello") + + a = A(b"hello") + with memoryview(a) as mv: + self.assertEqual(mv.tobytes(), b"hello") + + rb_call_count = 0 + rb_raised = False + class B(bytearray): + def __buffer__(self, flags): + return memoryview(b"hello") + def __release_buffer__(self, view): + nonlocal rb_call_count + rb_call_count += 1 + try: + super().__release_buffer__(view) + except ValueError: + nonlocal rb_raised + rb_raised = True + + b = B(b"hello") + with memoryview(b) as mv: + self.assertEqual(mv.tobytes(), b"hello") + self.assertEqual(rb_call_count, 0) + self.assertEqual(rb_call_count, 1) + self.assertIs(rb_raised, True) + + def test_override_only_release(self): + class C(bytearray): + def __release_buffer__(self, buffer): + super().__release_buffer__(buffer) + + c = C(b"hello") + with memoryview(c) as mv: + self.assertEqual(mv.tobytes(), b"hello") + + def test_release_saves_reference(self): + smuggled_buffer = None + + class C(bytearray): + def __release_buffer__(s, buffer: memoryview): + with self.assertRaises(ValueError): + memoryview(buffer) + with self.assertRaises(ValueError): + buffer.cast("b") + with self.assertRaises(ValueError): + buffer.toreadonly() + with self.assertRaises(ValueError): + buffer[:1] + with self.assertRaises(ValueError): + buffer.__buffer__(0) + nonlocal smuggled_buffer + smuggled_buffer = buffer + self.assertEqual(buffer.tobytes(), b"hello") + super().__release_buffer__(buffer) + + c = C(b"hello") + with memoryview(c) as mv: + self.assertEqual(mv.tobytes(), b"hello") + c.clear() + with self.assertRaises(ValueError): + smuggled_buffer.tobytes() + + def test_release_saves_reference_no_subclassing(self): + ba = bytearray(b"hello") + + class C: + def __buffer__(self, flags): + return memoryview(ba) + + def __release_buffer__(self, buffer): + self.buffer = buffer + + c = C() + with memoryview(c) as mv: + self.assertEqual(mv.tobytes(), b"hello") + self.assertEqual(c.buffer.tobytes(), b"hello") + + with self.assertRaises(BufferError): + ba.clear() + c.buffer.release() + ba.clear() + + def test_multiple_inheritance_buffer_last(self): + class A: + def __buffer__(self, flags): + return memoryview(b"hello A") + + class B(A, bytearray): + def __buffer__(self, flags): + return super().__buffer__(flags) + + b = B(b"hello") + with memoryview(b) as mv: + self.assertEqual(mv.tobytes(), b"hello A") + + class Releaser: + def __release_buffer__(self, buffer): + self.buffer = buffer + + class C(Releaser, bytearray): + def __buffer__(self, flags): + return super().__buffer__(flags) + + c = C(b"hello C") + with memoryview(c) as mv: + self.assertEqual(mv.tobytes(), b"hello C") + c.clear() + with self.assertRaises(ValueError): + c.buffer.tobytes() + + def test_multiple_inheritance_buffer_last_raising(self): + class A: + def __buffer__(self, flags): + raise RuntimeError("should not be called") + + def __release_buffer__(self, buffer): + raise RuntimeError("should not be called") + + class B(bytearray, A): + def __buffer__(self, flags): + return super().__buffer__(flags) + + b = B(b"hello") + with memoryview(b) as mv: + self.assertEqual(mv.tobytes(), b"hello") + + class Releaser: + buffer = None + def __release_buffer__(self, buffer): + self.buffer = buffer + + class C(bytearray, Releaser): + def __buffer__(self, flags): + return super().__buffer__(flags) + + c = C(b"hello") + with memoryview(c) as mv: + self.assertEqual(mv.tobytes(), b"hello") + c.clear() + self.assertIs(c.buffer, None) + + def test_release_buffer_with_exception_set(self): + class A: + def __buffer__(self, flags): + return memoryview(bytes(8)) + def __release_buffer__(self, view): + pass + + b = bytearray(8) + with memoryview(b): + # now b.extend will raise an exception due to exports + with self.assertRaises(BufferError): + b.extend(A()) + + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_bufio.py b/Lib/test/test_bufio.py index 17151b13..dc9a82dc 100644 --- a/Lib/test/test_bufio.py +++ b/Lib/test/test_bufio.py @@ -1,5 +1,4 @@ import unittest -from test import support from test.support import os_helper import io # C implementation. diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py index 6cd72eda..daac1008 100644 --- a/Lib/test/test_builtin.py +++ b/Lib/test/test_builtin.py @@ -9,6 +9,7 @@ import fractions import gc import io import locale +import math import os import pickle import platform @@ -17,6 +18,7 @@ import re import sys import traceback import types +import typing import unittest import warnings from contextlib import ExitStack @@ -27,10 +29,11 @@ from textwrap import dedent from types import AsyncGeneratorType, FunctionType, CellType from operator import neg from test import support -from test.support import (swap_attr, maybe_get_event_loop_policy) +from test.support import (cpython_only, swap_attr, maybe_get_event_loop_policy) from test.support.os_helper import (EnvironmentVarGuard, TESTFN, unlink) from test.support.script_helper import assert_python_ok from test.support.warnings_helper import check_warnings +from test.support import requires_IEEE_754 from unittest.mock import MagicMock, patch try: import pty, signal @@ -38,6 +41,12 @@ except ImportError: pty = signal = None +# Detect evidence of double-rounding: sum() does not always +# get improved accuracy on machines that suffer from double rounding. +x, y = 1e16, 2.9999 # use temporary values to defeat peephole optimizer +HAVE_DOUBLE_ROUNDING = (x + y == 1e16 + 4) + + class Squares: def __init__(self, max): @@ -334,11 +343,10 @@ class BuiltinTest(unittest.TestCase): self.assertRaises(TypeError, compile) self.assertRaises(ValueError, compile, 'print(42)\n', '<string>', 'badmode') self.assertRaises(ValueError, compile, 'print(42)\n', '<string>', 'single', 0xff) - self.assertRaises(ValueError, compile, chr(0), 'f', 'exec') self.assertRaises(TypeError, compile, 'pass', '?', 'exec', mode='eval', source='0', filename='tmp') compile('print("\xe5")\n', '', 'exec') - self.assertRaises(ValueError, compile, chr(0), 'f', 'exec') + self.assertRaises(SyntaxError, compile, chr(0), 'f', 'exec') self.assertRaises(ValueError, compile, str('a = 1'), 'f', 'bad') # test the optimize argument @@ -919,6 +927,17 @@ class BuiltinTest(unittest.TestCase): f2 = filter(filter_char, "abcdeabcde") self.check_iter_pickle(f1, list(f2), proto) + @support.requires_resource('cpu') + def test_filter_dealloc(self): + # Tests recursive deallocation of nested filter objects using the + # thrashcan mechanism. See gh-102356 for more details. + max_iters = 1000000 + i = filter(bool, range(max_iters)) + for _ in range(max_iters): + i = filter(bool, i) + del i + gc.collect() + def test_getattr(self): self.assertTrue(getattr(sys, 'stdout') is sys.stdout) self.assertRaises(TypeError, getattr) @@ -1148,7 +1167,11 @@ class BuiltinTest(unittest.TestCase): max() self.assertRaises(TypeError, max, 42) - self.assertRaises(ValueError, max, ()) + with self.assertRaisesRegex( + ValueError, + r'max\(\) iterable argument is empty' + ): + max(()) class BadSeq: def __getitem__(self, index): raise ValueError @@ -1207,7 +1230,11 @@ class BuiltinTest(unittest.TestCase): min() self.assertRaises(TypeError, min, 42) - self.assertRaises(ValueError, min, ()) + with self.assertRaisesRegex( + ValueError, + r'min\(\) iterable argument is empty' + ): + min(()) class BadSeq: def __getitem__(self, index): raise ValueError @@ -1618,6 +1645,8 @@ class BuiltinTest(unittest.TestCase): self.assertEqual(repr(sum([-0.0])), '0.0') self.assertEqual(repr(sum([-0.0], -0.0)), '-0.0') self.assertEqual(repr(sum([], -0.0)), '-0.0') + self.assertTrue(math.isinf(sum([float("inf"), float("inf")]))) + self.assertTrue(math.isinf(sum([1e308, 1e308]))) self.assertRaises(TypeError, sum) self.assertRaises(TypeError, sum, 42) @@ -1642,6 +1671,14 @@ class BuiltinTest(unittest.TestCase): sum(([x] for x in range(10)), empty) self.assertEqual(empty, []) + @requires_IEEE_754 + @unittest.skipIf(HAVE_DOUBLE_ROUNDING, + "sum accuracy not guaranteed on machines with double rounding") + @support.cpython_only # Other implementations may choose a different algorithm + def test_sum_accuracy(self): + self.assertEqual(sum([0.1] * 10), 1.0) + self.assertEqual(sum([1.0, 10E100, 1.0, -10E100]), 2.0) + def test_type(self): self.assertEqual(type(''), type('123')) self.assertNotEqual(type(''), type(())) @@ -2103,6 +2140,11 @@ class TestBreakpoint(unittest.TestCase): breakpoint() mock.assert_not_called() + def test_runtime_error_when_hook_is_lost(self): + del sys.breakpointhook + with self.assertRaises(RuntimeError): + breakpoint() + @unittest.skipUnless(pty, "the pty and signal modules must be available") class PtyTests(unittest.TestCase): @@ -2223,7 +2265,7 @@ class PtyTests(unittest.TestCase): # the readline implementation. In some cases, the Python readline # callback rlhandler() is called by readline with a string without # non-ASCII characters. Skip tests on non-ASCII characters if the - # readline module is loaded, since test_builtin is not intented to test + # readline module is loaded, since test_builtin is not intended to test # the readline module, but the builtins module. if 'readline' in sys.modules: self.skipTest("the readline module is loaded") @@ -2330,6 +2372,35 @@ class ShutdownTest(unittest.TestCase): self.assertEqual(["before", "after"], out.decode().splitlines()) +@cpython_only +class ImmortalTests(unittest.TestCase): + + if sys.maxsize < (1 << 32): + IMMORTAL_REFCOUNT = (1 << 30) - 1 + else: + IMMORTAL_REFCOUNT = (1 << 32) - 1 + + IMMORTALS = (None, True, False, Ellipsis, NotImplemented, *range(-5, 257)) + + def assert_immortal(self, immortal): + with self.subTest(immortal): + self.assertEqual(sys.getrefcount(immortal), self.IMMORTAL_REFCOUNT) + + def test_immortals(self): + for immortal in self.IMMORTALS: + self.assert_immortal(immortal) + + def test_list_repeat_respect_immortality(self): + refs = list(self.IMMORTALS) * 42 + for immortal in self.IMMORTALS: + self.assert_immortal(immortal) + + def test_tuple_repeat_respect_immortality(self): + refs = tuple(self.IMMORTALS) * 42 + for immortal in self.IMMORTALS: + self.assert_immortal(immortal) + + class TestType(unittest.TestCase): def test_new_type(self): A = type('A', (), {}) @@ -2416,6 +2487,17 @@ class TestType(unittest.TestCase): A.__qualname__ = b'B' self.assertEqual(A.__qualname__, 'D.E') + def test_type_typeparams(self): + class A[T]: + pass + T, = A.__type_params__ + self.assertIsInstance(T, typing.TypeVar) + A.__type_params__ = "whatever" + self.assertEqual(A.__type_params__, "whatever") + with self.assertRaises(TypeError): + del A.__type_params__ + self.assertEqual(A.__type_params__, "whatever") + def test_type_doc(self): for doc in 'x', '\xc4', '\U0001f40d', 'x\x00y', b'x', 42, None: A = type('A', (), {'__doc__': doc}) diff --git a/Lib/test/test_bytes.py b/Lib/test/test_bytes.py index 53ba1ad6..afd506f0 100644 --- a/Lib/test/test_bytes.py +++ b/Lib/test/test_bytes.py @@ -1225,6 +1225,8 @@ class BytesTest(BaseBytesTest, unittest.TestCase): class ByteArrayTest(BaseBytesTest, unittest.TestCase): type2test = bytearray + _testcapi = import_helper.import_module('_testcapi') + def test_getitem_error(self): b = bytearray(b'python') msg = "bytearray indices must be integers or slices" @@ -1317,47 +1319,73 @@ class ByteArrayTest(BaseBytesTest, unittest.TestCase): self.assertEqual(re.findall(br"\w+", b), [by("Hello"), by("world")]) def test_setitem(self): - b = bytearray([1, 2, 3]) - b[1] = 100 - self.assertEqual(b, bytearray([1, 100, 3])) - b[-1] = 200 - self.assertEqual(b, bytearray([1, 100, 200])) - b[0] = Indexable(10) - self.assertEqual(b, bytearray([10, 100, 200])) - try: - b[3] = 0 - self.fail("Didn't raise IndexError") - except IndexError: - pass - try: - b[-10] = 0 - self.fail("Didn't raise IndexError") - except IndexError: - pass - try: - b[0] = 256 - self.fail("Didn't raise ValueError") - except ValueError: - pass - try: - b[0] = Indexable(-1) - self.fail("Didn't raise ValueError") - except ValueError: - pass - try: - b[0] = None - self.fail("Didn't raise TypeError") - except TypeError: - pass + def setitem_as_mapping(b, i, val): + b[i] = val + + def setitem_as_sequence(b, i, val): + self._testcapi.sequence_setitem(b, i, val) + + def do_tests(setitem): + b = bytearray([1, 2, 3]) + setitem(b, 1, 100) + self.assertEqual(b, bytearray([1, 100, 3])) + setitem(b, -1, 200) + self.assertEqual(b, bytearray([1, 100, 200])) + setitem(b, 0, Indexable(10)) + self.assertEqual(b, bytearray([10, 100, 200])) + try: + setitem(b, 3, 0) + self.fail("Didn't raise IndexError") + except IndexError: + pass + try: + setitem(b, -10, 0) + self.fail("Didn't raise IndexError") + except IndexError: + pass + try: + setitem(b, 0, 256) + self.fail("Didn't raise ValueError") + except ValueError: + pass + try: + setitem(b, 0, Indexable(-1)) + self.fail("Didn't raise ValueError") + except ValueError: + pass + try: + setitem(b, 0, object()) + self.fail("Didn't raise TypeError") + except TypeError: + pass + + with self.subTest("tp_as_mapping"): + do_tests(setitem_as_mapping) + + with self.subTest("tp_as_sequence"): + do_tests(setitem_as_sequence) def test_delitem(self): - b = bytearray(range(10)) - del b[0] - self.assertEqual(b, bytearray(range(1, 10))) - del b[-1] - self.assertEqual(b, bytearray(range(1, 9))) - del b[4] - self.assertEqual(b, bytearray([1, 2, 3, 4, 6, 7, 8])) + def del_as_mapping(b, i): + del b[i] + + def del_as_sequence(b, i): + self._testcapi.sequence_delitem(b, i) + + def do_tests(delete): + b = bytearray(range(10)) + delete(b, 0) + self.assertEqual(b, bytearray(range(1, 10))) + delete(b, -1) + self.assertEqual(b, bytearray(range(1, 9))) + delete(b, 4) + self.assertEqual(b, bytearray([1, 2, 3, 4, 6, 7, 8])) + + with self.subTest("tp_as_mapping"): + do_tests(del_as_mapping) + + with self.subTest("tp_as_sequence"): + do_tests(del_as_sequence) def test_setslice(self): b = bytearray(range(10)) @@ -1729,6 +1757,8 @@ class ByteArrayTest(BaseBytesTest, unittest.TestCase): self.assertEqual(b3, b'xcxcxc') def test_mutating_index(self): + # See gh-91153 + class Boom: def __index__(self): b.clear() @@ -1740,10 +1770,9 @@ class ByteArrayTest(BaseBytesTest, unittest.TestCase): b[0] = Boom() with self.subTest("tp_as_sequence"): - _testcapi = import_helper.import_module('_testcapi') b = bytearray(b'Now you see me...') with self.assertRaises(IndexError): - _testcapi.sequence_setitem(b, 0, Boom()) + self._testcapi.sequence_setitem(b, 0, Boom()) class AssortedBytesTest(unittest.TestCase): diff --git a/Lib/test/test_bz2.py b/Lib/test/test_bz2.py index c97ed1ce..1f0b9adc 100644 --- a/Lib/test/test_bz2.py +++ b/Lib/test/test_bz2.py @@ -721,10 +721,10 @@ class BZ2DecompressorTest(BaseTest): @bigmemtest(size=_4G + 100, memuse=3.3) def testDecompress4G(self, size): # "Test BZ2Decompressor.decompress() with >4GiB input" - blocksize = 10 * 1024 * 1024 + blocksize = min(10 * 1024 * 1024, size) block = random.randbytes(blocksize) try: - data = block * (size // blocksize + 1) + data = block * ((size-1) // blocksize + 1) compressed = bz2.compress(data) bz2d = BZ2Decompressor() decompressed = bz2d.decompress(compressed) @@ -844,6 +844,10 @@ class BZ2DecompressorTest(BaseTest): bzd.__init__() self.assertAlmostEqual(gettotalrefcount() - refs_before, 0, delta=10) + def test_uninitialized_BZ2Decompressor_crash(self): + self.assertEqual(BZ2Decompressor.__new__(BZ2Decompressor). + decompress(bytes()), b'') + class CompressDecompressTest(BaseTest): def testCompress(self): diff --git a/Lib/test/test_calendar.py b/Lib/test/test_calendar.py index 3d9dcf12..24e472b5 100644 --- a/Lib/test/test_calendar.py +++ b/Lib/test/test_calendar.py @@ -8,6 +8,7 @@ import locale import sys import datetime import os +import warnings # From https://en.wikipedia.org/wiki/Leap_year_starting_on_Saturday result_0_02_text = """\ @@ -490,6 +491,14 @@ class OutputTestCase(unittest.TestCase): self.assertEqual(out.getvalue().strip(), "1 2 3") class CalendarTestCase(unittest.TestCase): + + def test_deprecation_warning(self): + with self.assertWarnsRegex( + DeprecationWarning, + "The 'January' attribute is deprecated, use 'JANUARY' instead" + ): + calendar.January + def test_isleap(self): # Make sure that the return is right for a few years, and # ensure that the return values are 1 or 0, not just true or @@ -568,11 +577,15 @@ class CalendarTestCase(unittest.TestCase): try: # formatweekday uses different day names based on the available width. cal = calendar.LocaleTextCalendar(locale='en_US') + # For really short widths, the abbreviated name is truncated. + self.assertEqual(cal.formatweekday(0, 1), "M") + self.assertEqual(cal.formatweekday(0, 2), "Mo") # For short widths, a centered, abbreviated name is used. + self.assertEqual(cal.formatweekday(0, 3), "Mon") self.assertEqual(cal.formatweekday(0, 5), " Mon ") - # For really short widths, even the abbreviated name is truncated. - self.assertEqual(cal.formatweekday(0, 2), "Mo") + self.assertEqual(cal.formatweekday(0, 8), " Mon ") # For long widths, the full day name is used. + self.assertEqual(cal.formatweekday(0, 9), " Monday ") self.assertEqual(cal.formatweekday(0, 10), " Monday ") except locale.Error: raise unittest.SkipTest('cannot set the en_US locale') diff --git a/Lib/test/test_call.py b/Lib/test/test_call.py index 0974002a..ec8dc29d 100644 --- a/Lib/test/test_call.py +++ b/Lib/test/test_call.py @@ -1,5 +1,5 @@ import unittest -from test.support import cpython_only +from test.support import cpython_only, requires_limited_api, skip_on_s390x try: import _testcapi except ImportError: @@ -9,6 +9,8 @@ import collections import itertools import gc import contextlib +import sys +import types class BadStr(str): @@ -139,9 +141,9 @@ class CFunctionCallsErrorMessages(unittest.TestCase): itertools.product, 0, repeat=1, foo=2) def test_varargs15_kw(self): - msg = r"^ImportError\(\) takes at most 2 keyword arguments \(3 given\)$" + msg = r"^ImportError\(\) takes at most 3 keyword arguments \(4 given\)$" self.assertRaisesRegex(TypeError, msg, - ImportError, 0, name=1, path=2, foo=3) + ImportError, 0, name=1, path=2, name_from=3, foo=3) def test_varargs16_kw(self): msg = r"^min\(\) takes at most 2 keyword arguments \(3 given\)$" @@ -201,6 +203,37 @@ class CFunctionCallsErrorMessages(unittest.TestCase): msg = r"count\(\) takes no keyword arguments" self.assertRaisesRegex(TypeError, msg, [].count, x=2, y=2) + def test_object_not_callable(self): + msg = r"^'object' object is not callable$" + self.assertRaisesRegex(TypeError, msg, object()) + + def test_module_not_callable_no_suggestion_0(self): + msg = r"^'module' object is not callable$" + self.assertRaisesRegex(TypeError, msg, types.ModuleType("mod")) + + def test_module_not_callable_no_suggestion_1(self): + msg = r"^'module' object is not callable$" + mod = types.ModuleType("mod") + mod.mod = 42 + self.assertRaisesRegex(TypeError, msg, mod) + + def test_module_not_callable_no_suggestion_2(self): + msg = r"^'module' object is not callable$" + mod = types.ModuleType("mod") + del mod.__name__ + self.assertRaisesRegex(TypeError, msg, mod) + + def test_module_not_callable_no_suggestion_3(self): + msg = r"^'module' object is not callable$" + mod = types.ModuleType("mod") + mod.__name__ = 42 + self.assertRaisesRegex(TypeError, msg, mod) + + def test_module_not_callable_suggestion(self): + msg = r"^'module' object is not callable\. Did you mean: 'mod\.mod\(\.\.\.\)'\?$" + mod = types.ModuleType("mod") + mod.mod = lambda: ... + self.assertRaisesRegex(TypeError, msg, mod) class TestCallingConventions(unittest.TestCase): @@ -579,6 +612,9 @@ def testfunction_kw(self, *, kw): return self +ADAPTIVE_WARMUP_DELAY = 2 + + class TestPEP590(unittest.TestCase): def test_method_descriptor_flag(self): @@ -606,9 +642,19 @@ class TestPEP590(unittest.TestCase): self.assertFalse(_testcapi.MethodDescriptorNopGet.__flags__ & Py_TPFLAGS_HAVE_VECTORCALL) self.assertTrue(_testcapi.MethodDescriptor2.__flags__ & Py_TPFLAGS_HAVE_VECTORCALL) - # Mutable heap types should not inherit Py_TPFLAGS_HAVE_VECTORCALL + # Mutable heap types should inherit Py_TPFLAGS_HAVE_VECTORCALL, + # but should lose it when __call__ is overridden class MethodDescriptorHeap(_testcapi.MethodDescriptorBase): pass + self.assertTrue(MethodDescriptorHeap.__flags__ & Py_TPFLAGS_HAVE_VECTORCALL) + MethodDescriptorHeap.__call__ = print + self.assertFalse(MethodDescriptorHeap.__flags__ & Py_TPFLAGS_HAVE_VECTORCALL) + + # Mutable heap types should not inherit Py_TPFLAGS_HAVE_VECTORCALL if + # they define __call__ directly + class MethodDescriptorHeap(_testcapi.MethodDescriptorBase): + def __call__(self): + pass self.assertFalse(MethodDescriptorHeap.__flags__ & Py_TPFLAGS_HAVE_VECTORCALL) def test_vectorcall_override(self): @@ -621,6 +667,58 @@ class TestPEP590(unittest.TestCase): f = _testcapi.MethodDescriptorNopGet() self.assertIs(f(*args), args) + def test_vectorcall_override_on_mutable_class(self): + """Setting __call__ should disable vectorcall""" + TestType = _testcapi.make_vectorcall_class() + instance = TestType() + self.assertEqual(instance(), "tp_call") + instance.set_vectorcall(TestType) + self.assertEqual(instance(), "vectorcall") # assume vectorcall is used + TestType.__call__ = lambda self: "custom" + self.assertEqual(instance(), "custom") + + def test_vectorcall_override_with_subclass(self): + """Setting __call__ on a superclass should disable vectorcall""" + SuperType = _testcapi.make_vectorcall_class() + class DerivedType(SuperType): + pass + + instance = DerivedType() + + # Derived types with its own vectorcall should be unaffected + UnaffectedType1 = _testcapi.make_vectorcall_class(DerivedType) + UnaffectedType2 = _testcapi.make_vectorcall_class(SuperType) + + # Aside: Quickly check that the C helper actually made derived types + self.assertTrue(issubclass(UnaffectedType1, DerivedType)) + self.assertTrue(issubclass(UnaffectedType2, SuperType)) + + # Initial state: tp_call + self.assertEqual(instance(), "tp_call") + self.assertEqual(_testcapi.has_vectorcall_flag(SuperType), True) + self.assertEqual(_testcapi.has_vectorcall_flag(DerivedType), True) + self.assertEqual(_testcapi.has_vectorcall_flag(UnaffectedType1), True) + self.assertEqual(_testcapi.has_vectorcall_flag(UnaffectedType2), True) + + # Setting the vectorcall function + instance.set_vectorcall(SuperType) + + self.assertEqual(instance(), "vectorcall") + self.assertEqual(_testcapi.has_vectorcall_flag(SuperType), True) + self.assertEqual(_testcapi.has_vectorcall_flag(DerivedType), True) + self.assertEqual(_testcapi.has_vectorcall_flag(UnaffectedType1), True) + self.assertEqual(_testcapi.has_vectorcall_flag(UnaffectedType2), True) + + # Setting __call__ should remove vectorcall from all subclasses + SuperType.__call__ = lambda self: "custom" + + self.assertEqual(instance(), "custom") + self.assertEqual(_testcapi.has_vectorcall_flag(SuperType), False) + self.assertEqual(_testcapi.has_vectorcall_flag(DerivedType), False) + self.assertEqual(_testcapi.has_vectorcall_flag(UnaffectedType1), True) + self.assertEqual(_testcapi.has_vectorcall_flag(UnaffectedType2), True) + + def test_vectorcall(self): # Test a bunch of different ways to call objects: # 1. vectorcall using PyVectorcall_Call() @@ -697,6 +795,92 @@ class TestPEP590(unittest.TestCase): self.assertEqual(expected, meth(*args1, **kwargs)) self.assertEqual(expected, wrapped(*args, **kwargs)) + def test_setvectorcall(self): + from _testcapi import function_setvectorcall + def f(num): return num + 1 + assert_equal = self.assertEqual + num = 10 + assert_equal(11, f(num)) + function_setvectorcall(f) + # make sure specializer is triggered by running > 50 times + for _ in range(10 * ADAPTIVE_WARMUP_DELAY): + assert_equal("overridden", f(num)) + + def test_setvectorcall_load_attr_specialization_skip(self): + from _testcapi import function_setvectorcall + + class X: + def __getattribute__(self, attr): + return attr + + assert_equal = self.assertEqual + x = X() + assert_equal("a", x.a) + function_setvectorcall(X.__getattribute__) + # make sure specialization doesn't trigger + # when vectorcall is overridden + for _ in range(ADAPTIVE_WARMUP_DELAY): + assert_equal("overridden", x.a) + + def test_setvectorcall_load_attr_specialization_deopt(self): + from _testcapi import function_setvectorcall + + class X: + def __getattribute__(self, attr): + return attr + + def get_a(x): + return x.a + + assert_equal = self.assertEqual + x = X() + # trigger LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN specialization + for _ in range(ADAPTIVE_WARMUP_DELAY): + assert_equal("a", get_a(x)) + function_setvectorcall(X.__getattribute__) + # make sure specialized LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN + # gets deopted due to overridden vectorcall + for _ in range(ADAPTIVE_WARMUP_DELAY): + assert_equal("overridden", get_a(x)) + + @requires_limited_api + def test_vectorcall_limited_incoming(self): + from _testcapi import pyobject_vectorcall + obj = _testcapi.LimitedVectorCallClass() + self.assertEqual(pyobject_vectorcall(obj, (), ()), "vectorcall called") + + @requires_limited_api + def test_vectorcall_limited_outgoing(self): + from _testcapi import call_vectorcall + + args_captured = [] + kwargs_captured = [] + + def f(*args, **kwargs): + args_captured.append(args) + kwargs_captured.append(kwargs) + return "success" + + self.assertEqual(call_vectorcall(f), "success") + self.assertEqual(args_captured, [("foo",)]) + self.assertEqual(kwargs_captured, [{"baz": "bar"}]) + + @requires_limited_api + def test_vectorcall_limited_outgoing_method(self): + from _testcapi import call_vectorcall_method + + args_captured = [] + kwargs_captured = [] + + class TestInstance: + def f(self, *args, **kwargs): + args_captured.append(args) + kwargs_captured.append(kwargs) + return "success" + + self.assertEqual(call_vectorcall_method(TestInstance()), "success") + self.assertEqual(args_captured, [("foo",)]) + self.assertEqual(kwargs_captured, [{"baz": "bar"}]) class A: def method_two_args(self, x, y): @@ -744,6 +928,55 @@ class TestErrorMessagesUseQualifiedName(unittest.TestCase): with self.check_raises_type_error(msg): A().method_two_args("x", "y", x="oops") +@cpython_only +class TestRecursion(unittest.TestCase): + + @skip_on_s390x + def test_super_deep(self): + + def recurse(n): + if n: + recurse(n-1) + + def py_recurse(n, m): + if n: + py_recurse(n-1, m) + else: + c_py_recurse(m-1) + + def c_recurse(n): + if n: + _testcapi.pyobject_fastcall(c_recurse, (n-1,)) + + def c_py_recurse(m): + if m: + _testcapi.pyobject_fastcall(py_recurse, (1000, m)) + + depth = sys.getrecursionlimit() + sys.setrecursionlimit(100_000) + try: + recurse(90_000) + with self.assertRaises(RecursionError): + recurse(101_000) + c_recurse(100) + with self.assertRaises(RecursionError): + c_recurse(90_000) + c_py_recurse(90) + with self.assertRaises(RecursionError): + c_py_recurse(100_000) + finally: + sys.setrecursionlimit(depth) + +class TestFunctionWithManyArgs(unittest.TestCase): + def test_function_with_many_args(self): + for N in (10, 500, 1000): + with self.subTest(N=N): + args = ",".join([f"a{i}" for i in range(N)]) + src = f"def f({args}) : return a{N//2}" + l = {} + exec(src, {}, l) + self.assertEqual(l['f'](*range(N)), N//2) + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_capi/check_config.py b/Lib/test/test_capi/check_config.py new file mode 100644 index 00000000..eb99ae16 --- /dev/null +++ b/Lib/test/test_capi/check_config.py @@ -0,0 +1,77 @@ +# This script is used by test_misc. + +import _imp +import _testinternalcapi +import json +import os +import sys + + +def import_singlephase(): + assert '_testsinglephase' not in sys.modules + try: + import _testsinglephase + except ImportError: + sys.modules.pop('_testsinglephase', None) + return False + else: + del sys.modules['_testsinglephase'] + return True + + +def check_singlephase(override): + # Check using the default setting. + settings_initial = _testinternalcapi.get_interp_settings() + allowed_initial = import_singlephase() + assert(_testinternalcapi.get_interp_settings() == settings_initial) + + # Apply the override and check. + override_initial = _imp._override_multi_interp_extensions_check(override) + settings_after = _testinternalcapi.get_interp_settings() + allowed_after = import_singlephase() + + # Apply the override again and check. + noop = {} + override_after = _imp._override_multi_interp_extensions_check(override) + settings_noop = _testinternalcapi.get_interp_settings() + if settings_noop != settings_after: + noop['settings_noop'] = settings_noop + allowed_noop = import_singlephase() + if allowed_noop != allowed_after: + noop['allowed_noop'] = allowed_noop + + # Restore the original setting and check. + override_noop = _imp._override_multi_interp_extensions_check(override_initial) + if override_noop != override_after: + noop['override_noop'] = override_noop + settings_restored = _testinternalcapi.get_interp_settings() + allowed_restored = import_singlephase() + + # Restore the original setting again. + override_restored = _imp._override_multi_interp_extensions_check(override_initial) + assert(_testinternalcapi.get_interp_settings() == settings_restored) + + return dict({ + 'requested': override, + 'override__initial': override_initial, + 'override_after': override_after, + 'override_restored': override_restored, + 'settings__initial': settings_initial, + 'settings_after': settings_after, + 'settings_restored': settings_restored, + 'allowed__initial': allowed_initial, + 'allowed_after': allowed_after, + 'allowed_restored': allowed_restored, + }, **noop) + + +def run_singlephase_check(override, outfd): + with os.fdopen(outfd, 'w') as outfile: + sys.stdout = outfile + sys.stderr = outfile + try: + results = check_singlephase(override) + json.dump(results, outfile) + finally: + sys.stdout = sys.__stdout__ + sys.stderr = sys.__stderr__ diff --git a/Lib/test/test_capi/test_abstract.py b/Lib/test/test_capi/test_abstract.py new file mode 100644 index 00000000..116edd8d --- /dev/null +++ b/Lib/test/test_capi/test_abstract.py @@ -0,0 +1,694 @@ +import unittest +import sys +from collections import OrderedDict +from test import support +from test.support import import_helper +import _testcapi + + +NULL = None + +class TestObject: + @property + def evil(self): + raise RuntimeError('do not get evil') + @evil.setter + def evil(self, value): + raise RuntimeError('do not set evil') + @evil.deleter + def evil(self): + raise RuntimeError('do not del evil') + +class ProxyGetItem: + def __init__(self, obj): + self.obj = obj + def __getitem__(self, key): + return self.obj[key] + +class ProxySetItem: + def __init__(self, obj): + self.obj = obj + def __setitem__(self, key, value): + self.obj[key] = value + +class ProxyDelItem: + def __init__(self, obj): + self.obj = obj + def __delitem__(self, key): + del self.obj[key] + +def gen(): + yield 'a' + yield 'b' + yield 'c' + + +class CAPITest(unittest.TestCase): + + def test_object_getattr(self): + xgetattr = _testcapi.object_getattr + obj = TestObject() + obj.a = 11 + setattr(obj, '\U0001f40d', 22) + self.assertEqual(xgetattr(obj, 'a'), 11) + self.assertRaises(AttributeError, xgetattr, obj, 'b') + self.assertEqual(xgetattr(obj, '\U0001f40d'), 22) + + self.assertRaises(RuntimeError, xgetattr, obj, 'evil') + self.assertRaises(TypeError, xgetattr, obj, 1) + # CRASHES xgetattr(obj, NULL) + # CRASHES xgetattr(NULL, 'a') + + def test_object_getattrstring(self): + getattrstring = _testcapi.object_getattrstring + obj = TestObject() + obj.a = 11 + setattr(obj, '\U0001f40d', 22) + self.assertEqual(getattrstring(obj, b'a'), 11) + self.assertRaises(AttributeError, getattrstring, obj, b'b') + self.assertEqual(getattrstring(obj, '\U0001f40d'.encode()), 22) + + self.assertRaises(RuntimeError, getattrstring, obj, b'evil') + self.assertRaises(UnicodeDecodeError, getattrstring, obj, b'\xff') + # CRASHES getattrstring(obj, NULL) + # CRASHES getattrstring(NULL, b'a') + + def test_object_hasattr(self): + xhasattr = _testcapi.object_hasattr + obj = TestObject() + obj.a = 1 + setattr(obj, '\U0001f40d', 2) + self.assertTrue(xhasattr(obj, 'a')) + self.assertFalse(xhasattr(obj, 'b')) + self.assertTrue(xhasattr(obj, '\U0001f40d')) + + self.assertFalse(xhasattr(obj, 'evil')) + self.assertFalse(xhasattr(obj, 1)) + # CRASHES xhasattr(obj, NULL) + # CRASHES xhasattr(NULL, 'a') + + def test_object_hasattrstring(self): + hasattrstring = _testcapi.object_hasattrstring + obj = TestObject() + obj.a = 1 + setattr(obj, '\U0001f40d', 2) + self.assertTrue(hasattrstring(obj, b'a')) + self.assertFalse(hasattrstring(obj, b'b')) + self.assertTrue(hasattrstring(obj, '\U0001f40d'.encode())) + + self.assertFalse(hasattrstring(obj, b'evil')) + self.assertFalse(hasattrstring(obj, b'\xff')) + # CRASHES hasattrstring(obj, NULL) + # CRASHES hasattrstring(NULL, b'a') + + def test_object_setattr(self): + xsetattr = _testcapi.object_setattr + obj = TestObject() + xsetattr(obj, 'a', 5) + self.assertEqual(obj.a, 5) + xsetattr(obj, '\U0001f40d', 8) + self.assertEqual(getattr(obj, '\U0001f40d'), 8) + + # PyObject_SetAttr(obj, attr_name, NULL) removes the attribute + xsetattr(obj, 'a', NULL) + self.assertFalse(hasattr(obj, 'a')) + self.assertRaises(AttributeError, xsetattr, obj, 'b', NULL) + self.assertRaises(RuntimeError, xsetattr, obj, 'evil', NULL) + + self.assertRaises(RuntimeError, xsetattr, obj, 'evil', 'good') + self.assertRaises(AttributeError, xsetattr, 42, 'a', 5) + self.assertRaises(TypeError, xsetattr, obj, 1, 5) + # CRASHES xsetattr(obj, NULL, 5) + # CRASHES xsetattr(NULL, 'a', 5) + + def test_object_setattrstring(self): + setattrstring = _testcapi.object_setattrstring + obj = TestObject() + setattrstring(obj, b'a', 5) + self.assertEqual(obj.a, 5) + setattrstring(obj, '\U0001f40d'.encode(), 8) + self.assertEqual(getattr(obj, '\U0001f40d'), 8) + + # PyObject_SetAttrString(obj, attr_name, NULL) removes the attribute + setattrstring(obj, b'a', NULL) + self.assertFalse(hasattr(obj, 'a')) + self.assertRaises(AttributeError, setattrstring, obj, b'b', NULL) + self.assertRaises(RuntimeError, setattrstring, obj, b'evil', NULL) + + self.assertRaises(RuntimeError, setattrstring, obj, b'evil', 'good') + self.assertRaises(AttributeError, setattrstring, 42, b'a', 5) + self.assertRaises(TypeError, setattrstring, obj, 1, 5) + self.assertRaises(UnicodeDecodeError, setattrstring, obj, b'\xff', 5) + # CRASHES setattrstring(obj, NULL, 5) + # CRASHES setattrstring(NULL, b'a', 5) + + def test_object_delattr(self): + xdelattr = _testcapi.object_delattr + obj = TestObject() + obj.a = 1 + setattr(obj, '\U0001f40d', 2) + xdelattr(obj, 'a') + self.assertFalse(hasattr(obj, 'a')) + self.assertRaises(AttributeError, xdelattr, obj, 'b') + xdelattr(obj, '\U0001f40d') + self.assertFalse(hasattr(obj, '\U0001f40d')) + + self.assertRaises(AttributeError, xdelattr, 42, 'numerator') + self.assertRaises(RuntimeError, xdelattr, obj, 'evil') + self.assertRaises(TypeError, xdelattr, obj, 1) + # CRASHES xdelattr(obj, NULL) + # CRASHES xdelattr(NULL, 'a') + + def test_object_delattrstring(self): + delattrstring = _testcapi.object_delattrstring + obj = TestObject() + obj.a = 1 + setattr(obj, '\U0001f40d', 2) + delattrstring(obj, b'a') + self.assertFalse(hasattr(obj, 'a')) + self.assertRaises(AttributeError, delattrstring, obj, b'b') + delattrstring(obj, '\U0001f40d'.encode()) + self.assertFalse(hasattr(obj, '\U0001f40d')) + + self.assertRaises(AttributeError, delattrstring, 42, b'numerator') + self.assertRaises(RuntimeError, delattrstring, obj, b'evil') + self.assertRaises(UnicodeDecodeError, delattrstring, obj, b'\xff') + # CRASHES delattrstring(obj, NULL) + # CRASHES delattrstring(NULL, b'a') + + + def test_mapping_check(self): + check = _testcapi.mapping_check + self.assertTrue(check({1: 2})) + self.assertTrue(check([1, 2])) + self.assertTrue(check((1, 2))) + self.assertTrue(check('abc')) + self.assertTrue(check(b'abc')) + self.assertFalse(check(42)) + self.assertFalse(check(object())) + self.assertFalse(check(NULL)) + + def test_mapping_size(self): + for size in _testcapi.mapping_size, _testcapi.mapping_length: + self.assertEqual(size({1: 2}), 1) + self.assertEqual(size([1, 2]), 2) + self.assertEqual(size((1, 2)), 2) + self.assertEqual(size('abc'), 3) + self.assertEqual(size(b'abc'), 3) + + self.assertRaises(TypeError, size, 42) + self.assertRaises(TypeError, size, object()) + self.assertRaises(SystemError, size, NULL) + + def test_object_getitem(self): + getitem = _testcapi.object_getitem + dct = {'a': 1, '\U0001f40d': 2} + self.assertEqual(getitem(dct, 'a'), 1) + self.assertRaises(KeyError, getitem, dct, 'b') + self.assertEqual(getitem(dct, '\U0001f40d'), 2) + + dct2 = ProxyGetItem(dct) + self.assertEqual(getitem(dct2, 'a'), 1) + self.assertRaises(KeyError, getitem, dct2, 'b') + + self.assertEqual(getitem(['a', 'b', 'c'], 1), 'b') + + self.assertRaises(TypeError, getitem, 42, 'a') + self.assertRaises(TypeError, getitem, {}, []) # unhashable + self.assertRaises(SystemError, getitem, {}, NULL) + self.assertRaises(IndexError, getitem, [], 1) + self.assertRaises(TypeError, getitem, [], 'a') + self.assertRaises(SystemError, getitem, NULL, 'a') + + def test_mapping_getitemstring(self): + getitemstring = _testcapi.mapping_getitemstring + dct = {'a': 1, '\U0001f40d': 2} + self.assertEqual(getitemstring(dct, b'a'), 1) + self.assertRaises(KeyError, getitemstring, dct, b'b') + self.assertEqual(getitemstring(dct, '\U0001f40d'.encode()), 2) + + dct2 = ProxyGetItem(dct) + self.assertEqual(getitemstring(dct2, b'a'), 1) + self.assertRaises(KeyError, getitemstring, dct2, b'b') + + self.assertRaises(TypeError, getitemstring, 42, b'a') + self.assertRaises(UnicodeDecodeError, getitemstring, {}, b'\xff') + self.assertRaises(SystemError, getitemstring, {}, NULL) + self.assertRaises(TypeError, getitemstring, [], b'a') + self.assertRaises(SystemError, getitemstring, NULL, b'a') + + def test_mapping_haskey(self): + haskey = _testcapi.mapping_haskey + dct = {'a': 1, '\U0001f40d': 2} + self.assertTrue(haskey(dct, 'a')) + self.assertFalse(haskey(dct, 'b')) + self.assertTrue(haskey(dct, '\U0001f40d')) + + dct2 = ProxyGetItem(dct) + self.assertTrue(haskey(dct2, 'a')) + self.assertFalse(haskey(dct2, 'b')) + + self.assertTrue(haskey(['a', 'b', 'c'], 1)) + + self.assertFalse(haskey(42, 'a')) + self.assertFalse(haskey({}, [])) # unhashable + self.assertFalse(haskey({}, NULL)) + self.assertFalse(haskey([], 1)) + self.assertFalse(haskey([], 'a')) + self.assertFalse(haskey(NULL, 'a')) + + def test_mapping_haskeystring(self): + haskeystring = _testcapi.mapping_haskeystring + dct = {'a': 1, '\U0001f40d': 2} + self.assertTrue(haskeystring(dct, b'a')) + self.assertFalse(haskeystring(dct, b'b')) + self.assertTrue(haskeystring(dct, '\U0001f40d'.encode())) + + dct2 = ProxyGetItem(dct) + self.assertTrue(haskeystring(dct2, b'a')) + self.assertFalse(haskeystring(dct2, b'b')) + + self.assertFalse(haskeystring(42, b'a')) + self.assertFalse(haskeystring({}, b'\xff')) + self.assertFalse(haskeystring({}, NULL)) + self.assertFalse(haskeystring([], b'a')) + self.assertFalse(haskeystring(NULL, b'a')) + + def test_object_setitem(self): + setitem = _testcapi.object_setitem + dct = {} + setitem(dct, 'a', 5) + self.assertEqual(dct, {'a': 5}) + setitem(dct, '\U0001f40d', 8) + self.assertEqual(dct, {'a': 5, '\U0001f40d': 8}) + + dct = {} + dct2 = ProxySetItem(dct) + setitem(dct2, 'a', 5) + self.assertEqual(dct, {'a': 5}) + + lst = ['a', 'b', 'c'] + setitem(lst, 1, 'x') + self.assertEqual(lst, ['a', 'x', 'c']) + + self.assertRaises(TypeError, setitem, 42, 'a', 5) + self.assertRaises(TypeError, setitem, {}, [], 5) # unhashable + self.assertRaises(SystemError, setitem, {}, NULL, 5) + self.assertRaises(SystemError, setitem, {}, 'a', NULL) + self.assertRaises(IndexError, setitem, [], 1, 5) + self.assertRaises(TypeError, setitem, [], 'a', 5) + self.assertRaises(TypeError, setitem, (), 1, 5) + self.assertRaises(SystemError, setitem, NULL, 'a', 5) + + def test_mapping_setitemstring(self): + setitemstring = _testcapi.mapping_setitemstring + dct = {} + setitemstring(dct, b'a', 5) + self.assertEqual(dct, {'a': 5}) + setitemstring(dct, '\U0001f40d'.encode(), 8) + self.assertEqual(dct, {'a': 5, '\U0001f40d': 8}) + + dct = {} + dct2 = ProxySetItem(dct) + setitemstring(dct2, b'a', 5) + self.assertEqual(dct, {'a': 5}) + + self.assertRaises(TypeError, setitemstring, 42, b'a', 5) + self.assertRaises(UnicodeDecodeError, setitemstring, {}, b'\xff', 5) + self.assertRaises(SystemError, setitemstring, {}, NULL, 5) + self.assertRaises(SystemError, setitemstring, {}, b'a', NULL) + self.assertRaises(TypeError, setitemstring, [], b'a', 5) + self.assertRaises(SystemError, setitemstring, NULL, b'a', 5) + + def test_object_delitem(self): + for delitem in _testcapi.object_delitem, _testcapi.mapping_delitem: + dct = {'a': 1, 'c': 2, '\U0001f40d': 3} + delitem(dct, 'a') + self.assertEqual(dct, {'c': 2, '\U0001f40d': 3}) + self.assertRaises(KeyError, delitem, dct, 'b') + delitem(dct, '\U0001f40d') + self.assertEqual(dct, {'c': 2}) + + dct = {'a': 1, 'c': 2} + dct2 = ProxyDelItem(dct) + delitem(dct2, 'a') + self.assertEqual(dct, {'c': 2}) + self.assertRaises(KeyError, delitem, dct2, 'b') + + lst = ['a', 'b', 'c'] + delitem(lst, 1) + self.assertEqual(lst, ['a', 'c']) + + self.assertRaises(TypeError, delitem, 42, 'a') + self.assertRaises(TypeError, delitem, {}, []) # unhashable + self.assertRaises(SystemError, delitem, {}, NULL) + self.assertRaises(IndexError, delitem, [], 1) + self.assertRaises(TypeError, delitem, [], 'a') + self.assertRaises(SystemError, delitem, NULL, 'a') + + def test_mapping_delitemstring(self): + delitemstring = _testcapi.mapping_delitemstring + dct = {'a': 1, 'c': 2, '\U0001f40d': 3} + delitemstring(dct, b'a') + self.assertEqual(dct, {'c': 2, '\U0001f40d': 3}) + self.assertRaises(KeyError, delitemstring, dct, b'b') + delitemstring(dct, '\U0001f40d'.encode()) + self.assertEqual(dct, {'c': 2}) + + dct = {'a': 1, 'c': 2} + dct2 = ProxyDelItem(dct) + delitemstring(dct2, b'a') + self.assertEqual(dct, {'c': 2}) + self.assertRaises(KeyError, delitemstring, dct2, b'b') + + self.assertRaises(TypeError, delitemstring, 42, b'a') + self.assertRaises(UnicodeDecodeError, delitemstring, {}, b'\xff') + self.assertRaises(SystemError, delitemstring, {}, NULL) + self.assertRaises(TypeError, delitemstring, [], b'a') + self.assertRaises(SystemError, delitemstring, NULL, b'a') + + def test_mapping_keys_valuesitems(self): + class Mapping1(dict): + def keys(self): + return list(super().keys()) + def values(self): + return list(super().values()) + def items(self): + return list(super().items()) + class Mapping2(dict): + def keys(self): + return tuple(super().keys()) + def values(self): + return tuple(super().values()) + def items(self): + return tuple(super().items()) + dict_obj = {'foo': 1, 'bar': 2, 'spam': 3} + + for mapping in [{}, OrderedDict(), Mapping1(), Mapping2(), + dict_obj, OrderedDict(dict_obj), + Mapping1(dict_obj), Mapping2(dict_obj)]: + self.assertListEqual(_testcapi.mapping_keys(mapping), + list(mapping.keys())) + self.assertListEqual(_testcapi.mapping_values(mapping), + list(mapping.values())) + self.assertListEqual(_testcapi.mapping_items(mapping), + list(mapping.items())) + + def test_mapping_keys_valuesitems_bad_arg(self): + self.assertRaises(AttributeError, _testcapi.mapping_keys, object()) + self.assertRaises(AttributeError, _testcapi.mapping_values, object()) + self.assertRaises(AttributeError, _testcapi.mapping_items, object()) + self.assertRaises(AttributeError, _testcapi.mapping_keys, []) + self.assertRaises(AttributeError, _testcapi.mapping_values, []) + self.assertRaises(AttributeError, _testcapi.mapping_items, []) + self.assertRaises(SystemError, _testcapi.mapping_keys, NULL) + self.assertRaises(SystemError, _testcapi.mapping_values, NULL) + self.assertRaises(SystemError, _testcapi.mapping_items, NULL) + + class BadMapping: + def keys(self): + return None + def values(self): + return None + def items(self): + return None + bad_mapping = BadMapping() + self.assertRaises(TypeError, _testcapi.mapping_keys, bad_mapping) + self.assertRaises(TypeError, _testcapi.mapping_values, bad_mapping) + self.assertRaises(TypeError, _testcapi.mapping_items, bad_mapping) + + def test_sequence_check(self): + check = _testcapi.sequence_check + self.assertFalse(check({1: 2})) + self.assertTrue(check([1, 2])) + self.assertTrue(check((1, 2))) + self.assertTrue(check('abc')) + self.assertTrue(check(b'abc')) + self.assertFalse(check(42)) + self.assertFalse(check(object())) + # CRASHES check(NULL) + + def test_sequence_size(self): + for size in _testcapi.sequence_size, _testcapi.sequence_length: + self.assertEqual(size([1, 2]), 2) + self.assertEqual(size((1, 2)), 2) + self.assertEqual(size('abc'), 3) + self.assertEqual(size(b'abc'), 3) + + self.assertRaises(TypeError, size, {}) + self.assertRaises(TypeError, size, 42) + self.assertRaises(TypeError, size, object()) + self.assertRaises(SystemError, size, NULL) + + def test_sequence_getitem(self): + getitem = _testcapi.sequence_getitem + lst = ['a', 'b', 'c'] + self.assertEqual(getitem(lst, 1), 'b') + self.assertEqual(getitem(lst, -1), 'c') + self.assertRaises(IndexError, getitem, lst, 3) + + self.assertRaises(TypeError, getitem, 42, 1) + self.assertRaises(TypeError, getitem, {}, 1) + self.assertRaises(SystemError, getitem, NULL, 1) + + def test_sequence_concat(self): + concat = _testcapi.sequence_concat + self.assertEqual(concat(['a', 'b'], [1, 2]), ['a', 'b', 1, 2]) + self.assertEqual(concat(('a', 'b'), (1, 2)), ('a', 'b', 1, 2)) + + self.assertRaises(TypeError, concat, [], ()) + self.assertRaises(TypeError, concat, (), []) + self.assertRaises(TypeError, concat, [], 42) + self.assertRaises(TypeError, concat, 42, []) + self.assertRaises(TypeError, concat, 42, 43) + self.assertRaises(SystemError, concat, [], NULL) + self.assertRaises(SystemError, concat, NULL, []) + + def test_sequence_repeat(self): + repeat = _testcapi.sequence_repeat + self.assertEqual(repeat(['a', 'b'], 2), ['a', 'b', 'a', 'b']) + self.assertEqual(repeat(('a', 'b'), 2), ('a', 'b', 'a', 'b')) + self.assertEqual(repeat(['a', 'b'], 0), []) + self.assertEqual(repeat(['a', 'b'], -1), []) + + self.assertRaises(TypeError, repeat, set(), 2) + self.assertRaises(TypeError, repeat, 42, 2) + self.assertRaises(SystemError, repeat, NULL, 2) + + def test_sequence_inplaceconcat(self): + inplaceconcat = _testcapi.sequence_inplaceconcat + lst = ['a', 'b'] + res = inplaceconcat(lst, [1, 2]) + self.assertEqual(res, ['a', 'b', 1, 2]) + self.assertIs(res, lst) + lst = ['a', 'b'] + res = inplaceconcat(lst, (1, 2)) + self.assertEqual(res, ['a', 'b', 1, 2]) + self.assertIs(res, lst) + self.assertEqual(inplaceconcat(('a', 'b'), (1, 2)), ('a', 'b', 1, 2)) + + self.assertRaises(TypeError, inplaceconcat, (), []) + self.assertRaises(TypeError, inplaceconcat, [], 42) + self.assertRaises(TypeError, inplaceconcat, 42, []) + self.assertRaises(TypeError, inplaceconcat, 42, 43) + self.assertRaises(SystemError, inplaceconcat, [], NULL) + self.assertRaises(SystemError, inplaceconcat, NULL, []) + + def test_sequence_inplacerepeat(self): + inplacerepeat = _testcapi.sequence_inplacerepeat + lst = ['a', 'b'] + res = inplacerepeat(lst, 2) + self.assertEqual(res, ['a', 'b', 'a', 'b']) + self.assertIs(res, lst) + self.assertEqual(inplacerepeat(('a', 'b'), 2), ('a', 'b', 'a', 'b')) + self.assertEqual(inplacerepeat(['a', 'b'], 0), []) + self.assertEqual(inplacerepeat(['a', 'b'], -1), []) + + self.assertRaises(TypeError, inplacerepeat, set(), 2) + self.assertRaises(TypeError, inplacerepeat, 42, 2) + self.assertRaises(SystemError, inplacerepeat, NULL, 2) + + def test_sequence_setitem(self): + setitem = _testcapi.sequence_setitem + lst = ['a', 'b', 'c'] + setitem(lst, 1, 'x') + self.assertEqual(lst, ['a', 'x', 'c']) + setitem(lst, -1, 'y') + self.assertEqual(lst, ['a', 'x', 'y']) + + setitem(lst, 0, NULL) + self.assertEqual(lst, ['x', 'y']) + self.assertRaises(IndexError, setitem, lst, 3, 'x') + + self.assertRaises(TypeError, setitem, 42, 1, 'x') + self.assertRaises(TypeError, setitem, {}, 1, 'x') + self.assertRaises(SystemError, setitem, NULL, 1, 'x') + + def test_sequence_delitem(self): + delitem = _testcapi.sequence_delitem + lst = ['a', 'b', 'c'] + delitem(lst, 1) + self.assertEqual(lst, ['a', 'c']) + delitem(lst, -1) + self.assertEqual(lst, ['a']) + self.assertRaises(IndexError, delitem, lst, 3) + + self.assertRaises(TypeError, delitem, 42, 1) + self.assertRaises(TypeError, delitem, {}, 1) + self.assertRaises(SystemError, delitem, NULL, 1) + + def test_sequence_setslice(self): + setslice = _testcapi.sequence_setslice + + # Correct case: + data = [1, 2, 3, 4, 5] + data_copy = data.copy() + + setslice(data, 1, 3, [8, 9]) + data_copy[1:3] = [8, 9] + self.assertEqual(data, data_copy) + self.assertEqual(data, [1, 8, 9, 4, 5]) + + # Custom class: + class Custom: + def __setitem__(self, index, value): + self.index = index + self.value = value + + c = Custom() + setslice(c, 0, 5, 'abc') + self.assertEqual(c.index, slice(0, 5)) + self.assertEqual(c.value, 'abc') + + # Immutable sequences must raise: + bad_seq1 = (1, 2, 3, 4) + self.assertRaises(TypeError, setslice, bad_seq1, 1, 3, (8, 9)) + self.assertEqual(bad_seq1, (1, 2, 3, 4)) + + bad_seq2 = 'abcd' + self.assertRaises(TypeError, setslice, bad_seq2, 1, 3, 'xy') + self.assertEqual(bad_seq2, 'abcd') + + # Not a sequence: + self.assertRaises(TypeError, setslice, object(), 1, 3, 'xy') + self.assertRaises(SystemError, setslice, NULL, 1, 3, 'xy') + + data_copy = data.copy() + setslice(data_copy, 1, 3, NULL) + self.assertEqual(data_copy, [1, 4, 5]) + + def test_sequence_delslice(self): + delslice = _testcapi.sequence_delslice + + # Correct case: + data = [1, 2, 3, 4, 5] + data_copy = data.copy() + + delslice(data, 1, 3) + del data_copy[1:3] + self.assertEqual(data, data_copy) + self.assertEqual(data, [1, 4, 5]) + + # Custom class: + class Custom: + def __delitem__(self, index): + self.index = index + + c = Custom() + delslice(c, 0, 5) + self.assertEqual(c.index, slice(0, 5)) + + # Immutable sequences must raise: + bad_seq1 = (1, 2, 3, 4) + self.assertRaises(TypeError, delslice, bad_seq1, 1, 3) + self.assertEqual(bad_seq1, (1, 2, 3, 4)) + + bad_seq2 = 'abcd' + self.assertRaises(TypeError, delslice, bad_seq2, 1, 3) + self.assertEqual(bad_seq2, 'abcd') + + # Not a sequence: + self.assertRaises(TypeError, delslice, object(), 1, 3) + self.assertRaises(SystemError, delslice, NULL, 1, 3) + + mapping = {1: 'a', 2: 'b', 3: 'c'} + self.assertRaises(KeyError, delslice, mapping, 1, 3) + self.assertEqual(mapping, {1: 'a', 2: 'b', 3: 'c'}) + + def test_sequence_count(self): + count = _testcapi.sequence_count + + lst = ['a', 'b', 'a'] + self.assertEqual(count(lst, 'a'), 2) + self.assertEqual(count(lst, 'c'), 0) + self.assertEqual(count(iter(lst), 'a'), 2) + self.assertEqual(count(iter(lst), 'c'), 0) + self.assertEqual(count({'a': 2}, 'a'), 1) + + self.assertRaises(TypeError, count, 42, 'a') + self.assertRaises(SystemError, count, [], NULL) + self.assertRaises(SystemError, count, [1], NULL) + self.assertRaises(SystemError, count, NULL, 'a') + + def test_sequence_contains(self): + contains = _testcapi.sequence_contains + + lst = ['a', 'b', 'a'] + self.assertEqual(contains(lst, 'a'), 1) + self.assertEqual(contains(lst, 'c'), 0) + self.assertEqual(contains(iter(lst), 'a'), 1) + self.assertEqual(contains(iter(lst), 'c'), 0) + self.assertEqual(contains({'a': 2}, 'a'), 1) + + # XXX Only for empty sequences. Should be SystemError? + self.assertEqual(contains([], NULL), 0) + + self.assertRaises(TypeError, contains, 42, 'a') + self.assertRaises(SystemError, contains, [1], NULL) + # CRASHES contains({}, NULL) + # CRASHES contains(set(), NULL) + # CRASHES contains(NULL, 'a') + + def test_sequence_index(self): + index = _testcapi.sequence_index + + lst = ['a', 'b', 'a'] + self.assertEqual(index(lst, 'a'), 0) + self.assertEqual(index(lst, 'b'), 1) + self.assertRaises(ValueError, index, lst, 'c') + self.assertEqual(index(iter(lst), 'a'), 0) + self.assertEqual(index(iter(lst), 'b'), 1) + self.assertRaises(ValueError, index, iter(lst), 'c') + dct = {'a': 2, 'b': 3} + self.assertEqual(index(dct, 'a'), 0) + self.assertEqual(index(dct, 'b'), 1) + self.assertRaises(ValueError, index, dct, 'c') + + self.assertRaises(TypeError, index, 42, 'a') + self.assertRaises(SystemError, index, [], NULL) + self.assertRaises(SystemError, index, [1], NULL) + self.assertRaises(SystemError, index, NULL, 'a') + + def test_sequence_list(self): + xlist = _testcapi.sequence_list + self.assertEqual(xlist(['a', 'b', 'c']), ['a', 'b', 'c']) + self.assertEqual(xlist(('a', 'b', 'c')), ['a', 'b', 'c']) + self.assertEqual(xlist(iter(['a', 'b', 'c'])), ['a', 'b', 'c']) + self.assertEqual(xlist(gen()), ['a', 'b', 'c']) + + self.assertRaises(TypeError, xlist, 42) + self.assertRaises(SystemError, xlist, NULL) + + def test_sequence_tuple(self): + xtuple = _testcapi.sequence_tuple + self.assertEqual(xtuple(['a', 'b', 'c']), ('a', 'b', 'c')) + self.assertEqual(xtuple(('a', 'b', 'c')), ('a', 'b', 'c')) + self.assertEqual(xtuple(iter(['a', 'b', 'c'])), ('a', 'b', 'c')) + self.assertEqual(xtuple(gen()), ('a', 'b', 'c')) + + self.assertRaises(TypeError, xtuple, 42) + self.assertRaises(SystemError, xtuple, NULL) + + +if __name__ == "__main__": + unittest.main() diff --git a/Lib/test/test_capi/test_codecs.py b/Lib/test/test_capi/test_codecs.py new file mode 100644 index 00000000..682c5697 --- /dev/null +++ b/Lib/test/test_capi/test_codecs.py @@ -0,0 +1,520 @@ +import unittest +import sys +from test.support import import_helper + +_testcapi = import_helper.import_module('_testcapi') + +NULL = None + + +class CAPITest(unittest.TestCase): + # TODO: Test the following functions: + # + # PyUnicode_BuildEncodingMap + # PyUnicode_FSConverter + # PyUnicode_FSDecoder + # PyUnicode_DecodeMBCS + # PyUnicode_DecodeMBCSStateful + # PyUnicode_DecodeCodePageStateful + # PyUnicode_AsMBCSString + # PyUnicode_EncodeCodePage + # PyUnicode_DecodeLocaleAndSize + # PyUnicode_DecodeLocale + # PyUnicode_EncodeLocale + # PyUnicode_DecodeFSDefault + # PyUnicode_DecodeFSDefaultAndSize + # PyUnicode_EncodeFSDefault + + def test_fromencodedobject(self): + """Test PyUnicode_FromEncodedObject()""" + fromencodedobject = _testcapi.unicode_fromencodedobject + + self.assertEqual(fromencodedobject(b'abc', NULL), 'abc') + self.assertEqual(fromencodedobject(b'abc', 'ascii'), 'abc') + b = b'a\xc2\xa1\xe4\xbd\xa0\xf0\x9f\x98\x80' + s = 'a\xa1\u4f60\U0001f600' + self.assertEqual(fromencodedobject(b, NULL), s) + self.assertEqual(fromencodedobject(b, 'utf-8'), s) + self.assertEqual(fromencodedobject(b, 'latin1'), b.decode('latin1')) + self.assertRaises(UnicodeDecodeError, fromencodedobject, b, 'ascii') + self.assertEqual(fromencodedobject(b, 'ascii', 'replace'), + 'a' + '\ufffd'*9) + self.assertEqual(fromencodedobject(bytearray(b), NULL), s) + self.assertEqual(fromencodedobject(bytearray(b), 'utf-8'), s) + self.assertRaises(LookupError, fromencodedobject, b'abc', 'foo') + self.assertRaises(LookupError, fromencodedobject, b, 'ascii', 'foo') + self.assertRaises(TypeError, fromencodedobject, 'abc', NULL) + self.assertRaises(TypeError, fromencodedobject, 'abc', 'ascii') + self.assertRaises(TypeError, fromencodedobject, [], NULL) + self.assertRaises(TypeError, fromencodedobject, [], 'ascii') + self.assertRaises(SystemError, fromencodedobject, NULL, NULL) + self.assertRaises(SystemError, fromencodedobject, NULL, 'ascii') + + def test_decode(self): + """Test PyUnicode_Decode()""" + decode = _testcapi.unicode_decode + + self.assertEqual(decode(b'[\xe2\x82\xac]', 'utf-8'), '[\u20ac]') + self.assertEqual(decode(b'[\xa4]', 'iso8859-15'), '[\u20ac]') + self.assertEqual(decode(b'[\xa4]', 'iso8859-15', 'strict'), '[\u20ac]') + self.assertRaises(UnicodeDecodeError, decode, b'[\xa4]', 'utf-8') + self.assertEqual(decode(b'[\xa4]', 'utf-8', 'replace'), '[\ufffd]') + + self.assertEqual(decode(b'[\xe2\x82\xac]', NULL), '[\u20ac]') + self.assertEqual(decode(b'[\xa4]', NULL, 'replace'), '[\ufffd]') + + self.assertRaises(LookupError, decode, b'\xa4', 'foo') + self.assertRaises(LookupError, decode, b'\xa4', 'utf-8', 'foo') + # TODO: Test PyUnicode_Decode() with NULL as data and + # negative size. + + def test_asencodedstring(self): + """Test PyUnicode_AsEncodedString()""" + asencodedstring = _testcapi.unicode_asencodedstring + + self.assertEqual(asencodedstring('abc', NULL), b'abc') + self.assertEqual(asencodedstring('abc', 'ascii'), b'abc') + s = 'a\xa1\u4f60\U0001f600' + b = b'a\xc2\xa1\xe4\xbd\xa0\xf0\x9f\x98\x80' + self.assertEqual(asencodedstring(s, NULL), b) + self.assertEqual(asencodedstring(s, 'utf-8'), b) + self.assertEqual(asencodedstring('\xa1\xa2', 'latin1'), b'\xa1\xa2') + self.assertRaises(UnicodeEncodeError, asencodedstring, '\xa1\xa2', 'ascii') + self.assertEqual(asencodedstring(s, 'ascii', 'replace'), b'a???') + + self.assertRaises(LookupError, asencodedstring, 'abc', 'foo') + self.assertRaises(LookupError, asencodedstring, s, 'ascii', 'foo') + self.assertRaises(TypeError, asencodedstring, b'abc', NULL) + self.assertRaises(TypeError, asencodedstring, b'abc', 'ascii') + self.assertRaises(TypeError, asencodedstring, [], NULL) + self.assertRaises(TypeError, asencodedstring, [], 'ascii') + # CRASHES asencodedstring(NULL, NULL) + # CRASHES asencodedstring(NULL, 'ascii') + + def test_decodeutf8(self): + """Test PyUnicode_DecodeUTF8()""" + decodeutf8 = _testcapi.unicode_decodeutf8 + + for s in ['abc', '\xa1\xa2', '\u4f60\u597d', 'a\U0001f600']: + b = s.encode('utf-8') + self.assertEqual(decodeutf8(b), s) + self.assertEqual(decodeutf8(b, 'strict'), s) + + self.assertRaises(UnicodeDecodeError, decodeutf8, b'\x80') + self.assertRaises(UnicodeDecodeError, decodeutf8, b'\xc0') + self.assertRaises(UnicodeDecodeError, decodeutf8, b'\xff') + self.assertRaises(UnicodeDecodeError, decodeutf8, b'a\xf0\x9f') + self.assertEqual(decodeutf8(b'a\xf0\x9f', 'replace'), 'a\ufffd') + self.assertEqual(decodeutf8(b'a\xf0\x9fb', 'replace'), 'a\ufffdb') + + self.assertRaises(LookupError, decodeutf8, b'a\x80', 'foo') + # TODO: Test PyUnicode_DecodeUTF8() with NULL as data and + # negative size. + + def test_decodeutf8stateful(self): + """Test PyUnicode_DecodeUTF8Stateful()""" + decodeutf8stateful = _testcapi.unicode_decodeutf8stateful + + for s in ['abc', '\xa1\xa2', '\u4f60\u597d', 'a\U0001f600']: + b = s.encode('utf-8') + self.assertEqual(decodeutf8stateful(b), (s, len(b))) + self.assertEqual(decodeutf8stateful(b, 'strict'), (s, len(b))) + + self.assertRaises(UnicodeDecodeError, decodeutf8stateful, b'\x80') + self.assertRaises(UnicodeDecodeError, decodeutf8stateful, b'\xc0') + self.assertRaises(UnicodeDecodeError, decodeutf8stateful, b'\xff') + self.assertEqual(decodeutf8stateful(b'a\xf0\x9f'), ('a', 1)) + self.assertEqual(decodeutf8stateful(b'a\xf0\x9f', 'replace'), ('a', 1)) + self.assertRaises(UnicodeDecodeError, decodeutf8stateful, b'a\xf0\x9fb') + self.assertEqual(decodeutf8stateful(b'a\xf0\x9fb', 'replace'), ('a\ufffdb', 4)) + + self.assertRaises(LookupError, decodeutf8stateful, b'a\x80', 'foo') + # TODO: Test PyUnicode_DecodeUTF8Stateful() with NULL as data and + # negative size. + # TODO: Test PyUnicode_DecodeUTF8Stateful() with NULL as the address of + # "consumed". + + def test_asutf8string(self): + """Test PyUnicode_AsUTF8String()""" + asutf8string = _testcapi.unicode_asutf8string + + for s in ['abc', '\xa1\xa2', '\u4f60\u597d', 'a\U0001f600']: + self.assertEqual(asutf8string(s), s.encode('utf-8')) + + self.assertRaises(UnicodeEncodeError, asutf8string, '\ud8ff') + self.assertRaises(TypeError, asutf8string, b'abc') + self.assertRaises(TypeError, asutf8string, []) + # CRASHES asutf8string(NULL) + + def test_decodeutf16(self): + """Test PyUnicode_DecodeUTF16()""" + decodeutf16 = _testcapi.unicode_decodeutf16 + + naturalbyteorder = -1 if sys.byteorder == 'little' else 1 + for s in ['abc', '\xa1\xa2', '\u4f60\u597d', 'a\U0001f600']: + b = s.encode('utf-16') + self.assertEqual(decodeutf16(0, b), (naturalbyteorder, s)) + b = s.encode('utf-16le') + self.assertEqual(decodeutf16(-1, b), (-1, s)) + self.assertEqual(decodeutf16(0, b'\xff\xfe'+b), (-1, s)) + b = s.encode('utf-16be') + self.assertEqual(decodeutf16(1, b), (1, s)) + self.assertEqual(decodeutf16(0, b'\xfe\xff'+b), (1, s)) + + self.assertRaises(UnicodeDecodeError, decodeutf16, -1, b'a') + self.assertRaises(UnicodeDecodeError, decodeutf16, 1, b'a') + self.assertRaises(UnicodeDecodeError, decodeutf16, 0, b'\xff\xfea') + self.assertRaises(UnicodeDecodeError, decodeutf16, 0, b'\xfe\xffa') + + self.assertRaises(UnicodeDecodeError, decodeutf16, -1, b'\x00\xde') + self.assertRaises(UnicodeDecodeError, decodeutf16, 1, b'\xde\x00') + self.assertRaises(UnicodeDecodeError, decodeutf16, 0, b'\xde\xde') + self.assertEqual(decodeutf16(-1, b'\x00\xde', 'replace'), (-1, '\ufffd')) + self.assertEqual(decodeutf16(1, b'\xde\x00', 'replace'), (1, '\ufffd')) + self.assertEqual(decodeutf16(0, b'\xde\xde', 'replace'), (0, '\ufffd')) + self.assertEqual(decodeutf16(0, b'\xff\xfe\x00\xde', 'replace'), (-1, '\ufffd')) + self.assertEqual(decodeutf16(0, b'\xfe\xff\xde\x00', 'replace'), (1, '\ufffd')) + + self.assertRaises(UnicodeDecodeError, decodeutf16, -1, b'\x3d\xd8') + self.assertRaises(UnicodeDecodeError, decodeutf16, 1, b'\xd8\x3d') + self.assertRaises(UnicodeDecodeError, decodeutf16, 0, b'\xd8\xd8') + self.assertEqual(decodeutf16(-1, b'\x3d\xd8', 'replace'), (-1, '\ufffd')) + self.assertEqual(decodeutf16(1, b'\xd8\x3d', 'replace'), (1, '\ufffd')) + self.assertEqual(decodeutf16(0, b'\xd8\xd8', 'replace'), (0, '\ufffd')) + self.assertEqual(decodeutf16(0, b'\xff\xfe\x3d\xd8', 'replace'), (-1, '\ufffd')) + self.assertEqual(decodeutf16(0, b'\xfe\xff\xd8\x3d', 'replace'), (1, '\ufffd')) + + self.assertRaises(LookupError, decodeutf16, -1, b'\x00\xde', 'foo') + self.assertRaises(LookupError, decodeutf16, 1, b'\xde\x00', 'foo') + self.assertRaises(LookupError, decodeutf16, 0, b'\xde\xde', 'foo') + # TODO: Test PyUnicode_DecodeUTF16() with NULL as data and + # negative size. + + def test_decodeutf16stateful(self): + """Test PyUnicode_DecodeUTF16Stateful()""" + decodeutf16stateful = _testcapi.unicode_decodeutf16stateful + + naturalbyteorder = -1 if sys.byteorder == 'little' else 1 + for s in ['abc', '\xa1\xa2', '\u4f60\u597d', 'a\U0001f600']: + b = s.encode('utf-16') + self.assertEqual(decodeutf16stateful(0, b), (naturalbyteorder, s, len(b))) + b = s.encode('utf-16le') + self.assertEqual(decodeutf16stateful(-1, b), (-1, s, len(b))) + self.assertEqual(decodeutf16stateful(0, b'\xff\xfe'+b), (-1, s, len(b)+2)) + b = s.encode('utf-16be') + self.assertEqual(decodeutf16stateful(1, b), (1, s, len(b))) + self.assertEqual(decodeutf16stateful(0, b'\xfe\xff'+b), (1, s, len(b)+2)) + + self.assertEqual(decodeutf16stateful(-1, b'\x61\x00\x3d'), (-1, 'a', 2)) + self.assertEqual(decodeutf16stateful(-1, b'\x61\x00\x3d\xd8'), (-1, 'a', 2)) + self.assertEqual(decodeutf16stateful(-1, b'\x61\x00\x3d\xd8\x00'), (-1, 'a', 2)) + self.assertEqual(decodeutf16stateful(1, b'\x00\x61\xd8'), (1, 'a', 2)) + self.assertEqual(decodeutf16stateful(1, b'\x00\x61\xd8\x3d'), (1, 'a', 2)) + self.assertEqual(decodeutf16stateful(1, b'\x00\x61\xd8\x3d\xde'), (1, 'a', 2)) + self.assertEqual(decodeutf16stateful(0, b'\xff\xfe\x61\x00\x3d\xd8\x00'), (-1, 'a', 4)) + self.assertEqual(decodeutf16stateful(0, b'\xfe\xff\x00\x61\xd8\x3d\xde'), (1, 'a', 4)) + + self.assertRaises(UnicodeDecodeError, decodeutf16stateful, -1, b'\x00\xde') + self.assertRaises(UnicodeDecodeError, decodeutf16stateful, 1, b'\xde\x00') + self.assertRaises(UnicodeDecodeError, decodeutf16stateful, 0, b'\xde\xde') + self.assertEqual(decodeutf16stateful(-1, b'\x00\xde', 'replace'), (-1, '\ufffd', 2)) + self.assertEqual(decodeutf16stateful(1, b'\xde\x00', 'replace'), (1, '\ufffd', 2)) + self.assertEqual(decodeutf16stateful(0, b'\xde\xde', 'replace'), (0, '\ufffd', 2)) + self.assertEqual(decodeutf16stateful(0, b'\xff\xfe\x00\xde', 'replace'), (-1, '\ufffd', 4)) + self.assertEqual(decodeutf16stateful(0, b'\xfe\xff\xde\x00', 'replace'), (1, '\ufffd', 4)) + + self.assertRaises(UnicodeDecodeError, decodeutf16stateful, -1, b'\x3d\xd8\x61\x00') + self.assertEqual(decodeutf16stateful(-1, b'\x3d\xd8\x61\x00', 'replace'), (-1, '\ufffda', 4)) + self.assertRaises(UnicodeDecodeError, decodeutf16stateful, 1, b'\xd8\x3d\x00\x61') + self.assertEqual(decodeutf16stateful(1, b'\xd8\x3d\x00\x61', 'replace'), (1, '\ufffda', 4)) + + self.assertRaises(LookupError, decodeutf16stateful, -1, b'\x00\xde', 'foo') + self.assertRaises(LookupError, decodeutf16stateful, 1, b'\xde\x00', 'foo') + self.assertRaises(LookupError, decodeutf16stateful, 0, b'\xde\xde', 'foo') + # TODO: Test PyUnicode_DecodeUTF16Stateful() with NULL as data and + # negative size. + # TODO: Test PyUnicode_DecodeUTF16Stateful() with NULL as the address of + # "consumed". + + def test_asutf16string(self): + """Test PyUnicode_AsUTF16String()""" + asutf16string = _testcapi.unicode_asutf16string + + for s in ['abc', '\xa1\xa2', '\u4f60\u597d', 'a\U0001f600']: + self.assertEqual(asutf16string(s), s.encode('utf-16')) + + self.assertRaises(UnicodeEncodeError, asutf16string, '\ud8ff') + self.assertRaises(TypeError, asutf16string, b'abc') + self.assertRaises(TypeError, asutf16string, []) + # CRASHES asutf16string(NULL) + + def test_decodeutf32(self): + """Test PyUnicode_DecodeUTF8()""" + decodeutf32 = _testcapi.unicode_decodeutf32 + + naturalbyteorder = -1 if sys.byteorder == 'little' else 1 + for s in ['abc', '\xa1\xa2', '\u4f60\u597d', 'a\U0001f600']: + b = s.encode('utf-32') + self.assertEqual(decodeutf32(0, b), (naturalbyteorder, s)) + b = s.encode('utf-32le') + self.assertEqual(decodeutf32(-1, b), (-1, s)) + self.assertEqual(decodeutf32(0, b'\xff\xfe\x00\x00'+b), (-1, s)) + b = s.encode('utf-32be') + self.assertEqual(decodeutf32(1, b), (1, s)) + self.assertEqual(decodeutf32(0, b'\x00\x00\xfe\xff'+b), (1, s)) + + self.assertRaises(UnicodeDecodeError, decodeutf32, -1, b'\x61\x00\x00\x00\x00') + self.assertRaises(UnicodeDecodeError, decodeutf32, 1, b'\x00\x00\x00\x61\x00') + self.assertRaises(UnicodeDecodeError, decodeutf32, 0, b'\xff\xfe\x00\x00\x61\x00\x00\x00\x00') + self.assertRaises(UnicodeDecodeError, decodeutf32, 0, b'\x00\x00\xfe\xff\x00\x00\x00\x61\x00') + + self.assertRaises(UnicodeDecodeError, decodeutf32, -1, b'\xff\xff\xff\xff') + self.assertRaises(UnicodeDecodeError, decodeutf32, 1, b'\xff\xff\xff\xff') + self.assertRaises(UnicodeDecodeError, decodeutf32, 0, b'\xff\xff\xff\xff') + self.assertEqual(decodeutf32(-1, b'\xff\xff\xff\xff', 'replace'), (-1, '\ufffd')) + self.assertEqual(decodeutf32(1, b'\xff\xff\xff\xff', 'replace'), (1, '\ufffd')) + self.assertEqual(decodeutf32(0, b'\xff\xff\xff\xff', 'replace'), (0, '\ufffd')) + self.assertEqual(decodeutf32(0, b'\xff\xfe\x00\x00\xff\xff\xff\xff', 'replace'), (-1, '\ufffd')) + self.assertEqual(decodeutf32(0, b'\x00\x00\xfe\xff\xff\xff\xff\xff', 'replace'), (1, '\ufffd')) + + self.assertRaises(UnicodeDecodeError, decodeutf32, -1, b'\x3d\xd8\x00\x00') + self.assertEqual(decodeutf32(-1, b'\x3d\xd8\x00\x00', 'replace'), (-1, '\ufffd')) + self.assertRaises(UnicodeDecodeError, decodeutf32, 1, b'\x00\x00\xd8\x3d') + self.assertEqual(decodeutf32(1, b'\x00\x00\xd8\x3d', 'replace'), (1, '\ufffd')) + + self.assertRaises(LookupError, decodeutf32, -1, b'\xff\xff\xff\xff', 'foo') + self.assertRaises(LookupError, decodeutf32, 1, b'\xff\xff\xff\xff', 'foo') + self.assertRaises(LookupError, decodeutf32, 0, b'\xff\xff\xff\xff', 'foo') + # TODO: Test PyUnicode_DecodeUTF32() with NULL as data and + # negative size. + + def test_decodeutf32stateful(self): + """Test PyUnicode_DecodeUTF32Stateful()""" + decodeutf32stateful = _testcapi.unicode_decodeutf32stateful + + naturalbyteorder = -1 if sys.byteorder == 'little' else 1 + for s in ['abc', '\xa1\xa2', '\u4f60\u597d', 'a\U0001f600']: + b = s.encode('utf-32') + self.assertEqual(decodeutf32stateful(0, b), (naturalbyteorder, s, len(b))) + b = s.encode('utf-32le') + self.assertEqual(decodeutf32stateful(-1, b), (-1, s, len(b))) + self.assertEqual(decodeutf32stateful(0, b'\xff\xfe\x00\x00'+b), (-1, s, len(b)+4)) + b = s.encode('utf-32be') + self.assertEqual(decodeutf32stateful(1, b), (1, s, len(b))) + self.assertEqual(decodeutf32stateful(0, b'\x00\x00\xfe\xff'+b), (1, s, len(b)+4)) + + self.assertEqual(decodeutf32stateful(-1, b'\x61\x00\x00\x00\x00'), (-1, 'a', 4)) + self.assertEqual(decodeutf32stateful(-1, b'\x61\x00\x00\x00\x00\xf6'), (-1, 'a', 4)) + self.assertEqual(decodeutf32stateful(-1, b'\x61\x00\x00\x00\x00\xf6\x01'), (-1, 'a', 4)) + self.assertEqual(decodeutf32stateful(1, b'\x00\x00\x00\x61\x00'), (1, 'a', 4)) + self.assertEqual(decodeutf32stateful(1, b'\x00\x00\x00\x61\x00\x01'), (1, 'a', 4)) + self.assertEqual(decodeutf32stateful(1, b'\x00\x00\x00\x61\x00\x01\xf6'), (1, 'a', 4)) + self.assertEqual(decodeutf32stateful(0, b'\xff\xfe\x00\x00\x61\x00\x00\x00\x00\xf6\x01'), (-1, 'a', 8)) + self.assertEqual(decodeutf32stateful(0, b'\x00\x00\xfe\xff\x00\x00\x00\x61\x00\x01\xf6'), (1, 'a', 8)) + + for b in b'\xff', b'\xff\xff', b'\xff\xff\xff': + self.assertEqual(decodeutf32stateful(-1, b), (-1, '', 0)) + self.assertEqual(decodeutf32stateful(1, b), (1, '', 0)) + self.assertEqual(decodeutf32stateful(0, b), (0, '', 0)) + self.assertEqual(decodeutf32stateful(0, b'\xff\xfe\x00\x00'+b), (-1, '', 4)) + self.assertEqual(decodeutf32stateful(0, b'\x00\x00\xfe\xff'+b), (1, '', 4)) + self.assertRaises(UnicodeDecodeError, decodeutf32stateful, -1, b'\xff\xff\xff\xff') + self.assertRaises(UnicodeDecodeError, decodeutf32stateful, 1, b'\xff\xff\xff\xff') + self.assertRaises(UnicodeDecodeError, decodeutf32stateful, 0, b'\xff\xff\xff\xff') + self.assertEqual(decodeutf32stateful(-1, b'\xff\xff\xff\xff', 'replace'), (-1, '\ufffd', 4)) + self.assertEqual(decodeutf32stateful(1, b'\xff\xff\xff\xff', 'replace'), (1, '\ufffd', 4)) + self.assertEqual(decodeutf32stateful(0, b'\xff\xff\xff\xff', 'replace'), (0, '\ufffd', 4)) + self.assertEqual(decodeutf32stateful(0, b'\xff\xfe\x00\x00\xff\xff\xff\xff', 'replace'), (-1, '\ufffd', 8)) + self.assertEqual(decodeutf32stateful(0, b'\x00\x00\xfe\xff\xff\xff\xff\xff', 'replace'), (1, '\ufffd', 8)) + + self.assertRaises(UnicodeDecodeError, decodeutf32stateful, -1, b'\x3d\xd8\x00\x00') + self.assertEqual(decodeutf32stateful(-1, b'\x3d\xd8\x00\x00', 'replace'), (-1, '\ufffd', 4)) + self.assertRaises(UnicodeDecodeError, decodeutf32stateful, 1, b'\x00\x00\xd8\x3d') + self.assertEqual(decodeutf32stateful(1, b'\x00\x00\xd8\x3d', 'replace'), (1, '\ufffd', 4)) + + self.assertRaises(LookupError, decodeutf32stateful, -1, b'\xff\xff\xff\xff', 'foo') + self.assertRaises(LookupError, decodeutf32stateful, 1, b'\xff\xff\xff\xff', 'foo') + self.assertRaises(LookupError, decodeutf32stateful, 0, b'\xff\xff\xff\xff', 'foo') + # TODO: Test PyUnicode_DecodeUTF32Stateful() with NULL as data and + # negative size. + # TODO: Test PyUnicode_DecodeUTF32Stateful() with NULL as the address of + # "consumed". + + def test_asutf32string(self): + """Test PyUnicode_AsUTF32String()""" + asutf32string = _testcapi.unicode_asutf32string + + for s in ['abc', '\xa1\xa2', '\u4f60\u597d', 'a\U0001f600']: + self.assertEqual(asutf32string(s), s.encode('utf-32')) + + self.assertRaises(UnicodeEncodeError, asutf32string, '\ud8ff') + self.assertRaises(TypeError, asutf32string, b'abc') + self.assertRaises(TypeError, asutf32string, []) + # CRASHES asutf32string(NULL) + + def test_decodelatin1(self): + """Test PyUnicode_DecodeLatin1()""" + decodelatin1 = _testcapi.unicode_decodelatin1 + + self.assertEqual(decodelatin1(b'abc'), 'abc') + self.assertEqual(decodelatin1(b'abc', 'strict'), 'abc') + self.assertEqual(decodelatin1(b'\xa1\xa2'), '\xa1\xa2') + self.assertEqual(decodelatin1(b'\xa1\xa2', 'strict'), '\xa1\xa2') + # TODO: Test PyUnicode_DecodeLatin1() with NULL as data and + # negative size. + + def test_aslatin1string(self): + """Test PyUnicode_AsLatin1String()""" + aslatin1string = _testcapi.unicode_aslatin1string + + self.assertEqual(aslatin1string('abc'), b'abc') + self.assertEqual(aslatin1string('\xa1\xa2'), b'\xa1\xa2') + + self.assertRaises(UnicodeEncodeError, aslatin1string, '\u4f60') + self.assertRaises(TypeError, aslatin1string, b'abc') + self.assertRaises(TypeError, aslatin1string, []) + # CRASHES aslatin1string(NULL) + + def test_decodeascii(self): + """Test PyUnicode_DecodeASCII()""" + decodeascii = _testcapi.unicode_decodeascii + + self.assertEqual(decodeascii(b'abc'), 'abc') + self.assertEqual(decodeascii(b'abc', 'strict'), 'abc') + + self.assertRaises(UnicodeDecodeError, decodeascii, b'\xff') + self.assertEqual(decodeascii(b'a\xff', 'replace'), 'a\ufffd') + self.assertEqual(decodeascii(b'a\xffb', 'replace'), 'a\ufffdb') + + self.assertRaises(LookupError, decodeascii, b'a\xff', 'foo') + # TODO: Test PyUnicode_DecodeASCII() with NULL as data and + # negative size. + + def test_asasciistring(self): + """Test PyUnicode_AsASCIIString()""" + asasciistring = _testcapi.unicode_asasciistring + + self.assertEqual(asasciistring('abc'), b'abc') + + self.assertRaises(UnicodeEncodeError, asasciistring, '\x80') + self.assertRaises(TypeError, asasciistring, b'abc') + self.assertRaises(TypeError, asasciistring, []) + # CRASHES asasciistring(NULL) + + def test_decodecharmap(self): + """Test PyUnicode_DecodeCharmap()""" + decodecharmap = _testcapi.unicode_decodecharmap + + self.assertEqual(decodecharmap(b'\3\0\7', {0: 'a', 3: 'b', 7: 'c'}), 'bac') + self.assertEqual(decodecharmap(b'\1\0\2', ['a', 'b', 'c']), 'bac') + self.assertEqual(decodecharmap(b'\1\0\2', 'abc'), 'bac') + self.assertEqual(decodecharmap(b'\1\0\2', ['\xa1', '\xa2', '\xa3']), '\xa2\xa1\xa3') + self.assertEqual(decodecharmap(b'\1\0\2', ['\u4f60', '\u597d', '\u4e16']), '\u597d\u4f60\u4e16') + self.assertEqual(decodecharmap(b'\1\0\2', ['\U0001f600', '\U0001f601', '\U0001f602']), '\U0001f601\U0001f600\U0001f602') + + self.assertEqual(decodecharmap(b'\1\0\2', [97, 98, 99]), 'bac') + self.assertEqual(decodecharmap(b'\1\0\2', ['', 'b', 'cd']), 'bcd') + + self.assertRaises(UnicodeDecodeError, decodecharmap, b'\0', {}) + self.assertRaises(UnicodeDecodeError, decodecharmap, b'\0', {0: None}) + self.assertEqual(decodecharmap(b'\1\0\2', [None, 'b', 'c'], 'replace'), 'b\ufffdc') + self.assertEqual(decodecharmap(b'\1\0\2\xff', NULL), '\1\0\2\xff') + self.assertRaises(TypeError, decodecharmap, b'\0', 42) + + # TODO: Test PyUnicode_DecodeCharmap() with NULL as data and + # negative size. + + def test_ascharmapstring(self): + """Test PyUnicode_AsCharmapString()""" + ascharmapstring = _testcapi.unicode_ascharmapstring + + self.assertEqual(ascharmapstring('abc', {97: 3, 98: 0, 99: 7}), b'\3\0\7') + self.assertEqual(ascharmapstring('\xa1\xa2\xa3', {0xa1: 3, 0xa2: 0, 0xa3: 7}), b'\3\0\7') + self.assertEqual(ascharmapstring('\u4f60\u597d\u4e16', {0x4f60: 3, 0x597d: 0, 0x4e16: 7}), b'\3\0\7') + self.assertEqual(ascharmapstring('\U0001f600\U0001f601\U0001f602', {0x1f600: 3, 0x1f601: 0, 0x1f602: 7}), b'\3\0\7') + self.assertEqual(ascharmapstring('abc', {97: 3, 98: b'', 99: b'spam'}), b'\3spam') + + self.assertRaises(UnicodeEncodeError, ascharmapstring, 'a', {}) + self.assertRaises(UnicodeEncodeError, ascharmapstring, 'a', {97: None}) + self.assertRaises(TypeError, ascharmapstring, b'a', {}) + self.assertRaises(TypeError, ascharmapstring, [], {}) + self.assertRaises(TypeError, ascharmapstring, 'a', NULL) + # CRASHES ascharmapstring(NULL, {}) + + def test_decodeunicodeescape(self): + """Test PyUnicode_DecodeUnicodeEscape()""" + decodeunicodeescape = _testcapi.unicode_decodeunicodeescape + + self.assertEqual(decodeunicodeescape(b'abc'), 'abc') + self.assertEqual(decodeunicodeescape(br'\t\n\r\x0b\x0c\x00\\'), '\t\n\r\v\f\0\\') + self.assertEqual(decodeunicodeescape(b'\t\n\r\x0b\x0c\x00'), '\t\n\r\v\f\0') + self.assertEqual(decodeunicodeescape(br'\xa1\xa2'), '\xa1\xa2') + self.assertEqual(decodeunicodeescape(b'\xa1\xa2'), '\xa1\xa2') + self.assertEqual(decodeunicodeescape(br'\u4f60\u597d'), '\u4f60\u597d') + self.assertEqual(decodeunicodeescape(br'\U0001f600'), '\U0001f600') + with self.assertWarns(DeprecationWarning): + self.assertEqual(decodeunicodeescape(br'\z'), r'\z') + + for b in b'\\', br'\xa', br'\u4f6', br'\U0001f60': + self.assertRaises(UnicodeDecodeError, decodeunicodeescape, b) + self.assertRaises(UnicodeDecodeError, decodeunicodeescape, b, 'strict') + self.assertEqual(decodeunicodeescape(br'x\U0001f60', 'replace'), 'x\ufffd') + self.assertEqual(decodeunicodeescape(br'x\U0001f60y', 'replace'), 'x\ufffdy') + + self.assertRaises(LookupError, decodeunicodeescape, b'\\', 'foo') + # TODO: Test PyUnicode_DecodeUnicodeEscape() with NULL as data and + # negative size. + + def test_asunicodeescapestring(self): + """Test PyUnicode_AsUnicodeEscapeString()""" + asunicodeescapestring = _testcapi.unicode_asunicodeescapestring + + self.assertEqual(asunicodeescapestring('abc'), b'abc') + self.assertEqual(asunicodeescapestring('\t\n\r\v\f\0\\'), br'\t\n\r\x0b\x0c\x00\\') + self.assertEqual(asunicodeescapestring('\xa1\xa2'), br'\xa1\xa2') + self.assertEqual(asunicodeescapestring('\u4f60\u597d'), br'\u4f60\u597d') + self.assertEqual(asunicodeescapestring('\U0001f600'), br'\U0001f600') + + self.assertRaises(TypeError, asunicodeescapestring, b'abc') + self.assertRaises(TypeError, asunicodeescapestring, []) + # CRASHES asunicodeescapestring(NULL) + + def test_decoderawunicodeescape(self): + """Test PyUnicode_DecodeRawUnicodeEscape()""" + decoderawunicodeescape = _testcapi.unicode_decoderawunicodeescape + + self.assertEqual(decoderawunicodeescape(b'abc'), 'abc') + self.assertEqual(decoderawunicodeescape(b'\t\n\r\v\f\0\\'), '\t\n\r\v\f\0\\') + self.assertEqual(decoderawunicodeescape(b'\xa1\xa2'), '\xa1\xa2') + self.assertEqual(decoderawunicodeescape(br'\u4f60\u597d'), '\u4f60\u597d') + self.assertEqual(decoderawunicodeescape(br'\U0001f600'), '\U0001f600') + self.assertEqual(decoderawunicodeescape(br'\xa1\xa2'), r'\xa1\xa2') + self.assertEqual(decoderawunicodeescape(br'\z'), r'\z') + + for b in br'\u4f6', br'\U0001f60': + self.assertRaises(UnicodeDecodeError, decoderawunicodeescape, b) + self.assertRaises(UnicodeDecodeError, decoderawunicodeescape, b, 'strict') + self.assertEqual(decoderawunicodeescape(br'x\U0001f60', 'replace'), 'x\ufffd') + self.assertEqual(decoderawunicodeescape(br'x\U0001f60y', 'replace'), 'x\ufffdy') + + self.assertRaises(LookupError, decoderawunicodeescape, br'\U0001f60', 'foo') + # TODO: Test PyUnicode_DecodeRawUnicodeEscape() with NULL as data and + # negative size. + + def test_asrawunicodeescapestring(self): + """Test PyUnicode_AsRawUnicodeEscapeString()""" + asrawunicodeescapestring = _testcapi.unicode_asrawunicodeescapestring + + self.assertEqual(asrawunicodeescapestring('abc'), b'abc') + self.assertEqual(asrawunicodeescapestring('\t\n\r\v\f\0\\'), b'\t\n\r\v\f\0\\') + self.assertEqual(asrawunicodeescapestring('\xa1\xa2'), b'\xa1\xa2') + self.assertEqual(asrawunicodeescapestring('\u4f60\u597d'), br'\u4f60\u597d') + self.assertEqual(asrawunicodeescapestring('\U0001f600'), br'\U0001f600') + + self.assertRaises(TypeError, asrawunicodeescapestring, b'abc') + self.assertRaises(TypeError, asrawunicodeescapestring, []) + # CRASHES asrawunicodeescapestring(NULL) + + +if __name__ == "__main__": + unittest.main() diff --git a/Lib/test/test_capi/test_dict.py b/Lib/test/test_capi/test_dict.py new file mode 100644 index 00000000..0717708f --- /dev/null +++ b/Lib/test/test_capi/test_dict.py @@ -0,0 +1,378 @@ +import unittest +import sys +from collections import OrderedDict, UserDict +from types import MappingProxyType +from test import support +from test.support import import_helper +import _testcapi + + +NULL = None + +class DictSubclass(dict): + def __getitem__(self, key): + raise RuntimeError('do not get evil') + def __setitem__(self, key, value): + raise RuntimeError('do not set evil') + def __delitem__(self, key): + raise RuntimeError('do not del evil') + +def gen(): + yield 'a' + yield 'b' + yield 'c' + + +class CAPITest(unittest.TestCase): + + def test_dict_check(self): + check = _testcapi.dict_check + self.assertTrue(check({1: 2})) + self.assertTrue(check(OrderedDict({1: 2}))) + self.assertFalse(check(UserDict({1: 2}))) + self.assertFalse(check([1, 2])) + self.assertFalse(check(object())) + #self.assertFalse(check(NULL)) + + def test_dict_checkexact(self): + check = _testcapi.dict_checkexact + self.assertTrue(check({1: 2})) + self.assertFalse(check(OrderedDict({1: 2}))) + self.assertFalse(check(UserDict({1: 2}))) + self.assertFalse(check([1, 2])) + self.assertFalse(check(object())) + #self.assertFalse(check(NULL)) + + def test_dict_new(self): + dict_new = _testcapi.dict_new + dct = dict_new() + self.assertEqual(dct, {}) + self.assertIs(type(dct), dict) + dct2 = dict_new() + self.assertIsNot(dct2, dct) + + def test_dictproxy_new(self): + dictproxy_new = _testcapi.dictproxy_new + for dct in {1: 2}, OrderedDict({1: 2}), UserDict({1: 2}): + proxy = dictproxy_new(dct) + self.assertIs(type(proxy), MappingProxyType) + self.assertEqual(proxy, dct) + with self.assertRaises(TypeError): + proxy[1] = 3 + self.assertEqual(proxy[1], 2) + dct[1] = 4 + self.assertEqual(proxy[1], 4) + + self.assertRaises(TypeError, dictproxy_new, []) + self.assertRaises(TypeError, dictproxy_new, 42) + # CRASHES dictproxy_new(NULL) + + def test_dict_copy(self): + copy = _testcapi.dict_copy + for dct in {1: 2}, OrderedDict({1: 2}): + dct_copy = copy(dct) + self.assertIs(type(dct_copy), dict) + self.assertEqual(dct_copy, dct) + + self.assertRaises(SystemError, copy, UserDict()) + self.assertRaises(SystemError, copy, []) + self.assertRaises(SystemError, copy, 42) + self.assertRaises(SystemError, copy, NULL) + + def test_dict_clear(self): + clear = _testcapi.dict_clear + dct = {1: 2} + clear(dct) + self.assertEqual(dct, {}) + + # NOTE: It is not safe to call it with OrderedDict. + + # Has no effect for non-dicts. + dct = UserDict({1: 2}) + clear(dct) + self.assertEqual(dct, {1: 2}) + lst = [1, 2] + clear(lst) + self.assertEqual(lst, [1, 2]) + clear(object()) + + # CRASHES? clear(NULL) + + def test_dict_size(self): + size = _testcapi.dict_size + self.assertEqual(size({1: 2}), 1) + self.assertEqual(size(OrderedDict({1: 2})), 1) + + self.assertRaises(SystemError, size, UserDict()) + self.assertRaises(SystemError, size, []) + self.assertRaises(SystemError, size, 42) + self.assertRaises(SystemError, size, object()) + self.assertRaises(SystemError, size, NULL) + + def test_dict_getitem(self): + getitem = _testcapi.dict_getitem + dct = {'a': 1, '\U0001f40d': 2} + self.assertEqual(getitem(dct, 'a'), 1) + self.assertIs(getitem(dct, 'b'), KeyError) + self.assertEqual(getitem(dct, '\U0001f40d'), 2) + + dct2 = DictSubclass(dct) + self.assertEqual(getitem(dct2, 'a'), 1) + self.assertIs(getitem(dct2, 'b'), KeyError) + + self.assertIs(getitem({}, []), KeyError) # unhashable + self.assertIs(getitem(42, 'a'), KeyError) + self.assertIs(getitem([1], 0), KeyError) + # CRASHES getitem({}, NULL) + # CRASHES getitem(NULL, 'a') + + def test_dict_getitemstring(self): + getitemstring = _testcapi.dict_getitemstring + dct = {'a': 1, '\U0001f40d': 2} + self.assertEqual(getitemstring(dct, b'a'), 1) + self.assertIs(getitemstring(dct, b'b'), KeyError) + self.assertEqual(getitemstring(dct, '\U0001f40d'.encode()), 2) + + dct2 = DictSubclass(dct) + self.assertEqual(getitemstring(dct2, b'a'), 1) + self.assertIs(getitemstring(dct2, b'b'), KeyError) + + self.assertIs(getitemstring({}, b'\xff'), KeyError) + self.assertIs(getitemstring(42, b'a'), KeyError) + self.assertIs(getitemstring([], b'a'), KeyError) + # CRASHES getitemstring({}, NULL) + # CRASHES getitemstring(NULL, b'a') + + def test_dict_getitemwitherror(self): + getitem = _testcapi.dict_getitemwitherror + dct = {'a': 1, '\U0001f40d': 2} + self.assertEqual(getitem(dct, 'a'), 1) + self.assertIs(getitem(dct, 'b'), KeyError) + self.assertEqual(getitem(dct, '\U0001f40d'), 2) + + dct2 = DictSubclass(dct) + self.assertEqual(getitem(dct2, 'a'), 1) + self.assertIs(getitem(dct2, 'b'), KeyError) + + self.assertRaises(SystemError, getitem, 42, 'a') + self.assertRaises(TypeError, getitem, {}, []) # unhashable + self.assertRaises(SystemError, getitem, [], 1) + self.assertRaises(SystemError, getitem, [], 'a') + # CRASHES getitem({}, NULL) + # CRASHES getitem(NULL, 'a') + + def test_dict_contains(self): + contains = _testcapi.dict_contains + dct = {'a': 1, '\U0001f40d': 2} + self.assertTrue(contains(dct, 'a')) + self.assertFalse(contains(dct, 'b')) + self.assertTrue(contains(dct, '\U0001f40d')) + + dct2 = DictSubclass(dct) + self.assertTrue(contains(dct2, 'a')) + self.assertFalse(contains(dct2, 'b')) + + self.assertRaises(TypeError, contains, {}, []) # unhashable + # CRASHES contains({}, NULL) + # CRASHES contains(UserDict(), 'a') + # CRASHES contains(42, 'a') + # CRASHES contains(NULL, 'a') + + def test_dict_setitem(self): + setitem = _testcapi.dict_setitem + dct = {} + setitem(dct, 'a', 5) + self.assertEqual(dct, {'a': 5}) + setitem(dct, '\U0001f40d', 8) + self.assertEqual(dct, {'a': 5, '\U0001f40d': 8}) + + dct2 = DictSubclass() + setitem(dct2, 'a', 5) + self.assertEqual(dct2, {'a': 5}) + + self.assertRaises(TypeError, setitem, {}, [], 5) # unhashable + self.assertRaises(SystemError, setitem, UserDict(), 'a', 5) + self.assertRaises(SystemError, setitem, [1], 0, 5) + self.assertRaises(SystemError, setitem, 42, 'a', 5) + # CRASHES setitem({}, NULL, 5) + # CRASHES setitem({}, 'a', NULL) + # CRASHES setitem(NULL, 'a', 5) + + def test_dict_setitemstring(self): + setitemstring = _testcapi.dict_setitemstring + dct = {} + setitemstring(dct, b'a', 5) + self.assertEqual(dct, {'a': 5}) + setitemstring(dct, '\U0001f40d'.encode(), 8) + self.assertEqual(dct, {'a': 5, '\U0001f40d': 8}) + + dct2 = DictSubclass() + setitemstring(dct2, b'a', 5) + self.assertEqual(dct2, {'a': 5}) + + self.assertRaises(UnicodeDecodeError, setitemstring, {}, b'\xff', 5) + self.assertRaises(SystemError, setitemstring, UserDict(), b'a', 5) + self.assertRaises(SystemError, setitemstring, 42, b'a', 5) + # CRASHES setitemstring({}, NULL, 5) + # CRASHES setitemstring({}, b'a', NULL) + # CRASHES setitemstring(NULL, b'a', 5) + + def test_dict_delitem(self): + delitem = _testcapi.dict_delitem + dct = {'a': 1, 'c': 2, '\U0001f40d': 3} + delitem(dct, 'a') + self.assertEqual(dct, {'c': 2, '\U0001f40d': 3}) + self.assertRaises(KeyError, delitem, dct, 'b') + delitem(dct, '\U0001f40d') + self.assertEqual(dct, {'c': 2}) + + dct2 = DictSubclass({'a': 1, 'c': 2}) + delitem(dct2, 'a') + self.assertEqual(dct2, {'c': 2}) + self.assertRaises(KeyError, delitem, dct2, 'b') + + self.assertRaises(TypeError, delitem, {}, []) # unhashable + self.assertRaises(SystemError, delitem, UserDict({'a': 1}), 'a') + self.assertRaises(SystemError, delitem, [1], 0) + self.assertRaises(SystemError, delitem, 42, 'a') + # CRASHES delitem({}, NULL) + # CRASHES delitem(NULL, 'a') + + def test_dict_delitemstring(self): + delitemstring = _testcapi.dict_delitemstring + dct = {'a': 1, 'c': 2, '\U0001f40d': 3} + delitemstring(dct, b'a') + self.assertEqual(dct, {'c': 2, '\U0001f40d': 3}) + self.assertRaises(KeyError, delitemstring, dct, b'b') + delitemstring(dct, '\U0001f40d'.encode()) + self.assertEqual(dct, {'c': 2}) + + dct2 = DictSubclass({'a': 1, 'c': 2}) + delitemstring(dct2, b'a') + self.assertEqual(dct2, {'c': 2}) + self.assertRaises(KeyError, delitemstring, dct2, b'b') + + self.assertRaises(UnicodeDecodeError, delitemstring, {}, b'\xff') + self.assertRaises(SystemError, delitemstring, UserDict({'a': 1}), b'a') + self.assertRaises(SystemError, delitemstring, 42, b'a') + # CRASHES delitemstring({}, NULL) + # CRASHES delitemstring(NULL, b'a') + + def test_dict_setdefault(self): + setdefault = _testcapi.dict_setdefault + dct = {} + self.assertEqual(setdefault(dct, 'a', 5), 5) + self.assertEqual(dct, {'a': 5}) + self.assertEqual(setdefault(dct, 'a', 8), 5) + self.assertEqual(dct, {'a': 5}) + + dct2 = DictSubclass() + self.assertEqual(setdefault(dct2, 'a', 5), 5) + self.assertEqual(dct2, {'a': 5}) + self.assertEqual(setdefault(dct2, 'a', 8), 5) + self.assertEqual(dct2, {'a': 5}) + + self.assertRaises(TypeError, setdefault, {}, [], 5) # unhashable + self.assertRaises(SystemError, setdefault, UserDict(), 'a', 5) + self.assertRaises(SystemError, setdefault, [1], 0, 5) + self.assertRaises(SystemError, setdefault, 42, 'a', 5) + # CRASHES setdefault({}, NULL, 5) + # CRASHES setdefault({}, 'a', NULL) + # CRASHES setdefault(NULL, 'a', 5) + + def test_mapping_keys_valuesitems(self): + class BadMapping(dict): + def keys(self): + return None + def values(self): + return None + def items(self): + return None + dict_obj = {'foo': 1, 'bar': 2, 'spam': 3} + for mapping in [dict_obj, DictSubclass(dict_obj), BadMapping(dict_obj)]: + self.assertListEqual(_testcapi.dict_keys(mapping), + list(dict_obj.keys())) + self.assertListEqual(_testcapi.dict_values(mapping), + list(dict_obj.values())) + self.assertListEqual(_testcapi.dict_items(mapping), + list(dict_obj.items())) + + def test_dict_keys_valuesitems_bad_arg(self): + for mapping in UserDict(), [], object(): + self.assertRaises(SystemError, _testcapi.dict_keys, mapping) + self.assertRaises(SystemError, _testcapi.dict_values, mapping) + self.assertRaises(SystemError, _testcapi.dict_items, mapping) + + def test_dict_next(self): + dict_next = _testcapi.dict_next + self.assertIsNone(dict_next({}, 0)) + dct = {'a': 1, 'b': 2, 'c': 3} + pos = 0 + pairs = [] + while True: + res = dict_next(dct, pos) + if res is None: + break + rc, pos, key, value = res + self.assertEqual(rc, 1) + pairs.append((key, value)) + self.assertEqual(pairs, list(dct.items())) + + # CRASHES dict_next(NULL, 0) + + def test_dict_update(self): + update = _testcapi.dict_update + for cls1 in dict, DictSubclass: + for cls2 in dict, DictSubclass, UserDict: + dct = cls1({'a': 1, 'b': 2}) + update(dct, cls2({'b': 3, 'c': 4})) + self.assertEqual(dct, {'a': 1, 'b': 3, 'c': 4}) + + self.assertRaises(AttributeError, update, {}, []) + self.assertRaises(AttributeError, update, {}, 42) + self.assertRaises(SystemError, update, UserDict(), {}) + self.assertRaises(SystemError, update, 42, {}) + self.assertRaises(SystemError, update, {}, NULL) + self.assertRaises(SystemError, update, NULL, {}) + + def test_dict_merge(self): + merge = _testcapi.dict_merge + for cls1 in dict, DictSubclass: + for cls2 in dict, DictSubclass, UserDict: + dct = cls1({'a': 1, 'b': 2}) + merge(dct, cls2({'b': 3, 'c': 4}), 0) + self.assertEqual(dct, {'a': 1, 'b': 2, 'c': 4}) + dct = cls1({'a': 1, 'b': 2}) + merge(dct, cls2({'b': 3, 'c': 4}), 1) + self.assertEqual(dct, {'a': 1, 'b': 3, 'c': 4}) + + self.assertRaises(AttributeError, merge, {}, [], 0) + self.assertRaises(AttributeError, merge, {}, 42, 0) + self.assertRaises(SystemError, merge, UserDict(), {}, 0) + self.assertRaises(SystemError, merge, 42, {}, 0) + self.assertRaises(SystemError, merge, {}, NULL, 0) + self.assertRaises(SystemError, merge, NULL, {}, 0) + + def test_dict_mergefromseq2(self): + mergefromseq2 = _testcapi.dict_mergefromseq2 + for cls1 in dict, DictSubclass: + for cls2 in list, iter: + dct = cls1({'a': 1, 'b': 2}) + mergefromseq2(dct, cls2([('b', 3), ('c', 4)]), 0) + self.assertEqual(dct, {'a': 1, 'b': 2, 'c': 4}) + dct = cls1({'a': 1, 'b': 2}) + mergefromseq2(dct, cls2([('b', 3), ('c', 4)]), 1) + self.assertEqual(dct, {'a': 1, 'b': 3, 'c': 4}) + + self.assertRaises(ValueError, mergefromseq2, {}, [(1,)], 0) + self.assertRaises(ValueError, mergefromseq2, {}, [(1, 2, 3)], 0) + self.assertRaises(TypeError, mergefromseq2, {}, [1], 0) + self.assertRaises(TypeError, mergefromseq2, {}, 42, 0) + # CRASHES mergefromseq2(UserDict(), [], 0) + # CRASHES mergefromseq2(42, [], 0) + # CRASHES mergefromseq2({}, NULL, 0) + # CRASHES mergefromseq2(NULL, {}, 0) + + +if __name__ == "__main__": + unittest.main() diff --git a/Lib/test/test_capi/test_exceptions.py b/Lib/test/test_capi/test_exceptions.py new file mode 100644 index 00000000..b96cc792 --- /dev/null +++ b/Lib/test/test_capi/test_exceptions.py @@ -0,0 +1,367 @@ +import errno +import os +import re +import sys +import unittest + +from test import support +from test.support import import_helper +from test.support.os_helper import TESTFN, TESTFN_UNDECODABLE +from test.support.script_helper import assert_python_failure +from test.support.testcase import ExceptionIsLikeMixin + +from .test_misc import decode_stderr + +# Skip this test if the _testcapi module isn't available. +_testcapi = import_helper.import_module('_testcapi') + +NULL = None + +class Test_Exceptions(unittest.TestCase): + + def test_exception(self): + raised_exception = ValueError("5") + new_exc = TypeError("TEST") + try: + raise raised_exception + except ValueError as e: + orig_sys_exception = sys.exception() + orig_exception = _testcapi.set_exception(new_exc) + new_sys_exception = sys.exception() + new_exception = _testcapi.set_exception(orig_exception) + reset_sys_exception = sys.exception() + + self.assertEqual(orig_exception, e) + + self.assertEqual(orig_exception, raised_exception) + self.assertEqual(orig_sys_exception, orig_exception) + self.assertEqual(reset_sys_exception, orig_exception) + self.assertEqual(new_exception, new_exc) + self.assertEqual(new_sys_exception, new_exception) + else: + self.fail("Exception not raised") + + def test_exc_info(self): + raised_exception = ValueError("5") + new_exc = TypeError("TEST") + try: + raise raised_exception + except ValueError as e: + tb = e.__traceback__ + orig_sys_exc_info = sys.exc_info() + orig_exc_info = _testcapi.set_exc_info(new_exc.__class__, new_exc, None) + new_sys_exc_info = sys.exc_info() + new_exc_info = _testcapi.set_exc_info(*orig_exc_info) + reset_sys_exc_info = sys.exc_info() + + self.assertEqual(orig_exc_info[1], e) + + self.assertSequenceEqual(orig_exc_info, (raised_exception.__class__, raised_exception, tb)) + self.assertSequenceEqual(orig_sys_exc_info, orig_exc_info) + self.assertSequenceEqual(reset_sys_exc_info, orig_exc_info) + self.assertSequenceEqual(new_exc_info, (new_exc.__class__, new_exc, None)) + self.assertSequenceEqual(new_sys_exc_info, new_exc_info) + else: + self.assertTrue(False) + + +class Test_FatalError(unittest.TestCase): + + def check_fatal_error(self, code, expected, not_expected=()): + with support.SuppressCrashReport(): + rc, out, err = assert_python_failure('-sSI', '-c', code) + + err = decode_stderr(err) + self.assertIn('Fatal Python error: _testcapi_fatal_error_impl: MESSAGE\n', + err) + + match = re.search(r'^Extension modules:(.*) \(total: ([0-9]+)\)$', + err, re.MULTILINE) + if not match: + self.fail(f"Cannot find 'Extension modules:' in {err!r}") + modules = set(match.group(1).strip().split(', ')) + total = int(match.group(2)) + + for name in expected: + self.assertIn(name, modules) + for name in not_expected: + self.assertNotIn(name, modules) + self.assertEqual(len(modules), total) + + @support.requires_subprocess() + def test_fatal_error(self): + # By default, stdlib extension modules are ignored, + # but not test modules. + expected = ('_testcapi',) + not_expected = ('sys',) + code = 'import _testcapi, sys; _testcapi.fatal_error(b"MESSAGE")' + self.check_fatal_error(code, expected, not_expected) + + # Mark _testcapi as stdlib module, but not sys + expected = ('sys',) + not_expected = ('_testcapi',) + code = """if True: + import _testcapi, sys + sys.stdlib_module_names = frozenset({"_testcapi"}) + _testcapi.fatal_error(b"MESSAGE") + """ + self.check_fatal_error(code, expected) + + +class Test_ErrSetAndRestore(unittest.TestCase): + + def test_err_set_raised(self): + with self.assertRaises(ValueError): + _testcapi.err_set_raised(ValueError()) + v = ValueError() + try: + _testcapi.err_set_raised(v) + except ValueError as ex: + self.assertIs(v, ex) + + def test_err_restore(self): + with self.assertRaises(ValueError): + _testcapi.err_restore(ValueError) + with self.assertRaises(ValueError): + _testcapi.err_restore(ValueError, 1) + with self.assertRaises(ValueError): + _testcapi.err_restore(ValueError, 1, None) + with self.assertRaises(ValueError): + _testcapi.err_restore(ValueError, ValueError()) + try: + _testcapi.err_restore(KeyError, "hi") + except KeyError as k: + self.assertEqual("hi", k.args[0]) + try: + 1/0 + except Exception as e: + tb = e.__traceback__ + with self.assertRaises(ValueError): + _testcapi.err_restore(ValueError, 1, tb) + with self.assertRaises(TypeError): + _testcapi.err_restore(ValueError, 1, 0) + try: + _testcapi.err_restore(ValueError, 1, tb) + except ValueError as v: + self.assertEqual(1, v.args[0]) + self.assertIs(tb, v.__traceback__.tb_next) + + def test_set_object(self): + + # new exception as obj is not an exception + with self.assertRaises(ValueError) as e: + _testcapi.exc_set_object(ValueError, 42) + self.assertEqual(e.exception.args, (42,)) + + # wraps the exception because unrelated types + with self.assertRaises(ValueError) as e: + _testcapi.exc_set_object(ValueError, TypeError(1,2,3)) + wrapped = e.exception.args[0] + self.assertIsInstance(wrapped, TypeError) + self.assertEqual(wrapped.args, (1, 2, 3)) + + # is superclass, so does not wrap + with self.assertRaises(PermissionError) as e: + _testcapi.exc_set_object(OSError, PermissionError(24)) + self.assertEqual(e.exception.args, (24,)) + + class Meta(type): + def __subclasscheck__(cls, sub): + 1/0 + + class Broken(Exception, metaclass=Meta): + pass + + with self.assertRaises(ZeroDivisionError) as e: + _testcapi.exc_set_object(Broken, Broken()) + + def test_set_object_and_fetch(self): + class Broken(Exception): + def __init__(self, *arg): + raise ValueError("Broken __init__") + + exc = _testcapi.exc_set_object_fetch(Broken, 'abcd') + self.assertIsInstance(exc, ValueError) + self.assertEqual(exc.__notes__[0], + "Normalization failed: type=Broken args='abcd'") + + class BadArg: + def __repr__(self): + raise TypeError('Broken arg type') + + exc = _testcapi.exc_set_object_fetch(Broken, BadArg()) + self.assertIsInstance(exc, ValueError) + self.assertEqual(exc.__notes__[0], + 'Normalization failed: type=Broken args=<unknown>') + + def test_set_string(self): + """Test PyErr_SetString()""" + setstring = _testcapi.err_setstring + with self.assertRaises(ZeroDivisionError) as e: + setstring(ZeroDivisionError, b'error') + self.assertEqual(e.exception.args, ('error',)) + with self.assertRaises(ZeroDivisionError) as e: + setstring(ZeroDivisionError, 'помилка'.encode()) + self.assertEqual(e.exception.args, ('помилка',)) + + with self.assertRaises(UnicodeDecodeError): + setstring(ZeroDivisionError, b'\xff') + self.assertRaises(SystemError, setstring, list, b'error') + # CRASHES setstring(ZeroDivisionError, NULL) + # CRASHES setstring(NULL, b'error') + + def test_format(self): + """Test PyErr_Format()""" + import_helper.import_module('ctypes') + from ctypes import pythonapi, py_object, c_char_p, c_int + name = "PyErr_Format" + PyErr_Format = getattr(pythonapi, name) + PyErr_Format.argtypes = (py_object, c_char_p,) + PyErr_Format.restype = py_object + with self.assertRaises(ZeroDivisionError) as e: + PyErr_Format(ZeroDivisionError, b'%s %d', b'error', c_int(42)) + self.assertEqual(e.exception.args, ('error 42',)) + with self.assertRaises(ZeroDivisionError) as e: + PyErr_Format(ZeroDivisionError, b'%s', 'помилка'.encode()) + self.assertEqual(e.exception.args, ('помилка',)) + + with self.assertRaisesRegex(OverflowError, 'not in range'): + PyErr_Format(ZeroDivisionError, b'%c', c_int(-1)) + with self.assertRaisesRegex(ValueError, 'format string'): + PyErr_Format(ZeroDivisionError, b'\xff') + self.assertRaises(SystemError, PyErr_Format, list, b'error') + # CRASHES PyErr_Format(ZeroDivisionError, NULL) + # CRASHES PyErr_Format(py_object(), b'error') + + def test_setfromerrnowithfilename(self): + """Test PyErr_SetFromErrnoWithFilename()""" + setfromerrnowithfilename = _testcapi.err_setfromerrnowithfilename + ENOENT = errno.ENOENT + with self.assertRaises(FileNotFoundError) as e: + setfromerrnowithfilename(ENOENT, OSError, b'file') + self.assertEqual(e.exception.args, + (ENOENT, 'No such file or directory')) + self.assertEqual(e.exception.errno, ENOENT) + self.assertEqual(e.exception.filename, 'file') + + with self.assertRaises(FileNotFoundError) as e: + setfromerrnowithfilename(ENOENT, OSError, os.fsencode(TESTFN)) + self.assertEqual(e.exception.filename, TESTFN) + + if TESTFN_UNDECODABLE: + with self.assertRaises(FileNotFoundError) as e: + setfromerrnowithfilename(ENOENT, OSError, TESTFN_UNDECODABLE) + self.assertEqual(e.exception.filename, + os.fsdecode(TESTFN_UNDECODABLE)) + + with self.assertRaises(FileNotFoundError) as e: + setfromerrnowithfilename(ENOENT, OSError, NULL) + self.assertIsNone(e.exception.filename) + + with self.assertRaises(OSError) as e: + setfromerrnowithfilename(0, OSError, b'file') + self.assertEqual(e.exception.args, (0, 'Error')) + self.assertEqual(e.exception.errno, 0) + self.assertEqual(e.exception.filename, 'file') + + with self.assertRaises(ZeroDivisionError) as e: + setfromerrnowithfilename(ENOENT, ZeroDivisionError, b'file') + self.assertEqual(e.exception.args, + (ENOENT, 'No such file or directory', 'file')) + # CRASHES setfromerrnowithfilename(ENOENT, NULL, b'error') + + +class Test_PyUnstable_Exc_PrepReraiseStar(ExceptionIsLikeMixin, unittest.TestCase): + + def setUp(self): + super().setUp() + try: + raise ExceptionGroup("eg", [TypeError('bad type'), ValueError(42)]) + except ExceptionGroup as e: + self.orig = e + + def test_invalid_args(self): + with self.assertRaisesRegex(TypeError, "orig must be an exception"): + _testcapi.unstable_exc_prep_reraise_star(42, [None]) + + with self.assertRaisesRegex(TypeError, "excs must be a list"): + _testcapi.unstable_exc_prep_reraise_star(self.orig, 42) + + with self.assertRaisesRegex(TypeError, "not an exception"): + _testcapi.unstable_exc_prep_reraise_star(self.orig, [TypeError(42), 42]) + + with self.assertRaisesRegex(ValueError, "orig must be a raised exception"): + _testcapi.unstable_exc_prep_reraise_star(ValueError(42), [TypeError(42)]) + + with self.assertRaisesRegex(ValueError, "orig must be a raised exception"): + _testcapi.unstable_exc_prep_reraise_star(ExceptionGroup("eg", [ValueError(42)]), + [TypeError(42)]) + + + def test_nothing_to_reraise(self): + self.assertEqual( + _testcapi.unstable_exc_prep_reraise_star(self.orig, [None]), None) + + try: + raise ValueError(42) + except ValueError as e: + orig = e + self.assertEqual( + _testcapi.unstable_exc_prep_reraise_star(orig, [None]), None) + + def test_reraise_orig(self): + orig = self.orig + res = _testcapi.unstable_exc_prep_reraise_star(orig, [orig]) + self.assertExceptionIsLike(res, orig) + + def test_raise_orig_parts(self): + orig = self.orig + match, rest = orig.split(TypeError) + + test_cases = [ + ([match, rest], orig), + ([rest, match], orig), + ([match], match), + ([rest], rest), + ([], None), + ] + + for input, expected in test_cases: + with self.subTest(input=input): + res = _testcapi.unstable_exc_prep_reraise_star(orig, input) + self.assertExceptionIsLike(res, expected) + + + def test_raise_with_new_exceptions(self): + orig = self.orig + + match, rest = orig.split(TypeError) + new1 = OSError('bad file') + new2 = RuntimeError('bad runtime') + + test_cases = [ + ([new1, match, rest], ExceptionGroup("", [new1, orig])), + ([match, new1, rest], ExceptionGroup("", [new1, orig])), + ([match, rest, new1], ExceptionGroup("", [new1, orig])), + + ([new1, new2, match, rest], ExceptionGroup("", [new1, new2, orig])), + ([new1, match, new2, rest], ExceptionGroup("", [new1, new2, orig])), + ([new2, rest, match, new1], ExceptionGroup("", [new2, new1, orig])), + ([rest, new2, match, new1], ExceptionGroup("", [new2, new1, orig])), + + + ([new1, new2, rest], ExceptionGroup("", [new1, new2, rest])), + ([new1, match, new2], ExceptionGroup("", [new1, new2, match])), + ([rest, new2, new1], ExceptionGroup("", [new2, new1, rest])), + ([new1, new2], ExceptionGroup("", [new1, new2])), + ([new2, new1], ExceptionGroup("", [new2, new1])), + ] + + for (input, expected) in test_cases: + with self.subTest(input=input): + res = _testcapi.unstable_exc_prep_reraise_star(orig, input) + self.assertExceptionIsLike(res, expected) + + +if __name__ == "__main__": + unittest.main() diff --git a/Lib/test/test_capi/test_getargs.py b/Lib/test/test_capi/test_getargs.py index 552fa213..ec4100e9 100644 --- a/Lib/test/test_capi/test_getargs.py +++ b/Lib/test/test_capi/test_getargs.py @@ -2,7 +2,6 @@ import unittest import math import string import sys -import warnings from test import support from test.support import import_helper from test.support import warnings_helper @@ -1022,7 +1021,7 @@ class String_TestCase(unittest.TestCase): buf = bytearray() self.assertRaises(ValueError, getargs_et_hash, 'abc\xe9', 'latin1', buf) - @support.requires_legacy_unicode_capi + @support.requires_legacy_unicode_capi() def test_u(self): from _testcapi import getargs_u with self.assertWarns(DeprecationWarning): @@ -1037,11 +1036,8 @@ class String_TestCase(unittest.TestCase): self.assertRaises(TypeError, getargs_u, memoryview(b'memoryview')) with self.assertWarns(DeprecationWarning): self.assertRaises(TypeError, getargs_u, None) - with warnings.catch_warnings(): - warnings.simplefilter('error', DeprecationWarning) - self.assertRaises(DeprecationWarning, getargs_u, 'abc\xe9') - @support.requires_legacy_unicode_capi + @support.requires_legacy_unicode_capi() def test_u_hash(self): from _testcapi import getargs_u_hash with self.assertWarns(DeprecationWarning): @@ -1056,11 +1052,8 @@ class String_TestCase(unittest.TestCase): self.assertRaises(TypeError, getargs_u_hash, memoryview(b'memoryview')) with self.assertWarns(DeprecationWarning): self.assertRaises(TypeError, getargs_u_hash, None) - with warnings.catch_warnings(): - warnings.simplefilter('error', DeprecationWarning) - self.assertRaises(DeprecationWarning, getargs_u_hash, 'abc\xe9') - @support.requires_legacy_unicode_capi + @support.requires_legacy_unicode_capi() def test_Z(self): from _testcapi import getargs_Z with self.assertWarns(DeprecationWarning): @@ -1075,11 +1068,8 @@ class String_TestCase(unittest.TestCase): self.assertRaises(TypeError, getargs_Z, memoryview(b'memoryview')) with self.assertWarns(DeprecationWarning): self.assertIsNone(getargs_Z(None)) - with warnings.catch_warnings(): - warnings.simplefilter('error', DeprecationWarning) - self.assertRaises(DeprecationWarning, getargs_Z, 'abc\xe9') - @support.requires_legacy_unicode_capi + @support.requires_legacy_unicode_capi() def test_Z_hash(self): from _testcapi import getargs_Z_hash with self.assertWarns(DeprecationWarning): @@ -1094,9 +1084,6 @@ class String_TestCase(unittest.TestCase): self.assertRaises(TypeError, getargs_Z_hash, memoryview(b'memoryview')) with self.assertWarns(DeprecationWarning): self.assertIsNone(getargs_Z_hash(None)) - with warnings.catch_warnings(): - warnings.simplefilter('error', DeprecationWarning) - self.assertRaises(DeprecationWarning, getargs_Z_hash, 'abc\xe9') def test_gh_99240_clear_args(self): from _testcapi import gh_99240_clear_args @@ -1216,7 +1203,7 @@ class SkipitemTest(unittest.TestCase): dict_b = {'b':1} keywords = ["a", "b"] - supported = ('s#', 's*', 'z#', 'z*', 'u#', 'Z#', 'y#', 'y*', 'w#', 'w*') + supported = ('s#', 's*', 'z#', 'z*', 'y#', 'y*', 'w#', 'w*') for c in string.ascii_letters: for c2 in '#*': f = c + c2 @@ -1309,14 +1296,6 @@ class Test_testcapi(unittest.TestCase): for name in dir(_testcapi) if name.startswith('test_') and name.endswith('_code')) - @warnings_helper.ignore_warnings(category=DeprecationWarning) - def test_u_code(self): - _testcapi.test_u_code() - - @warnings_helper.ignore_warnings(category=DeprecationWarning) - def test_Z_code(self): - _testcapi.test_Z_code() - if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_capi/test_immortal.py b/Lib/test/test_capi/test_immortal.py new file mode 100644 index 00000000..ef5d32b7 --- /dev/null +++ b/Lib/test/test_capi/test_immortal.py @@ -0,0 +1,16 @@ +import unittest +from test.support import import_helper + +_testcapi = import_helper.import_module('_testcapi') + + +class TestCAPI(unittest.TestCase): + def test_immortal_builtins(self): + _testcapi.test_immortal_builtins() + + def test_immortal_small_ints(self): + _testcapi.test_immortal_small_ints() + + +if __name__ == "__main__": + unittest.main() diff --git a/Lib/test/test_capi/test_long.py b/Lib/test/test_capi/test_long.py new file mode 100644 index 00000000..8928fd94 --- /dev/null +++ b/Lib/test/test_capi/test_long.py @@ -0,0 +1,39 @@ +import unittest +import sys + +from test.support import import_helper + +# Skip this test if the _testcapi module isn't available. +_testcapi = import_helper.import_module('_testcapi') + + +class LongTests(unittest.TestCase): + + def test_compact(self): + for n in { + # Edge cases + *(2**n for n in range(66)), + *(-2**n for n in range(66)), + *(2**n - 1 for n in range(66)), + *(-2**n + 1 for n in range(66)), + # Essentially random + *(37**n for n in range(14)), + *(-37**n for n in range(14)), + }: + with self.subTest(n=n): + is_compact, value = _testcapi.call_long_compact_api(n) + if is_compact: + self.assertEqual(n, value) + + def test_compact_known(self): + # Sanity-check some implementation details (we don't guarantee + # that these are/aren't compact) + self.assertEqual(_testcapi.call_long_compact_api(-1), (True, -1)) + self.assertEqual(_testcapi.call_long_compact_api(0), (True, 0)) + self.assertEqual(_testcapi.call_long_compact_api(256), (True, 256)) + self.assertEqual(_testcapi.call_long_compact_api(sys.maxsize), + (False, -1)) + + +if __name__ == "__main__": + unittest.main() diff --git a/Lib/test/test_capi/test_mem.py b/Lib/test/test_capi/test_mem.py new file mode 100644 index 00000000..a9ff410c --- /dev/null +++ b/Lib/test/test_capi/test_mem.py @@ -0,0 +1,169 @@ +import re +import textwrap +import unittest + + +from test import support +from test.support import import_helper, requires_subprocess +from test.support.script_helper import assert_python_failure, assert_python_ok + + +# Skip this test if the _testcapi module isn't available. +_testcapi = import_helper.import_module('_testcapi') + +@requires_subprocess() +class PyMemDebugTests(unittest.TestCase): + PYTHONMALLOC = 'debug' + # '0x04c06e0' or '04C06E0' + PTR_REGEX = r'(?:0x)?[0-9a-fA-F]+' + + def check(self, code): + with support.SuppressCrashReport(): + out = assert_python_failure( + '-c', code, + PYTHONMALLOC=self.PYTHONMALLOC, + # FreeBSD: instruct jemalloc to not fill freed() memory + # with junk byte 0x5a, see JEMALLOC(3) + MALLOC_CONF="junk:false", + ) + stderr = out.err + return stderr.decode('ascii', 'replace') + + def test_buffer_overflow(self): + out = self.check('import _testcapi; _testcapi.pymem_buffer_overflow()') + regex = (r"Debug memory block at address p={ptr}: API 'm'\n" + r" 16 bytes originally requested\n" + r" The [0-9] pad bytes at p-[0-9] are FORBIDDENBYTE, as expected.\n" + r" The [0-9] pad bytes at tail={ptr} are not all FORBIDDENBYTE \(0x[0-9a-f]{{2}}\):\n" + r" at tail\+0: 0x78 \*\*\* OUCH\n" + r" at tail\+1: 0xfd\n" + r" at tail\+2: 0xfd\n" + r" .*\n" + r"( The block was made by call #[0-9]+ to debug malloc/realloc.\n)?" + r" Data at p: cd cd cd .*\n" + r"\n" + r"Enable tracemalloc to get the memory block allocation traceback\n" + r"\n" + r"Fatal Python error: _PyMem_DebugRawFree: bad trailing pad byte") + regex = regex.format(ptr=self.PTR_REGEX) + regex = re.compile(regex, flags=re.DOTALL) + self.assertRegex(out, regex) + + def test_api_misuse(self): + out = self.check('import _testcapi; _testcapi.pymem_api_misuse()') + regex = (r"Debug memory block at address p={ptr}: API 'm'\n" + r" 16 bytes originally requested\n" + r" The [0-9] pad bytes at p-[0-9] are FORBIDDENBYTE, as expected.\n" + r" The [0-9] pad bytes at tail={ptr} are FORBIDDENBYTE, as expected.\n" + r"( The block was made by call #[0-9]+ to debug malloc/realloc.\n)?" + r" Data at p: cd cd cd .*\n" + r"\n" + r"Enable tracemalloc to get the memory block allocation traceback\n" + r"\n" + r"Fatal Python error: _PyMem_DebugRawFree: bad ID: Allocated using API 'm', verified using API 'r'\n") + regex = regex.format(ptr=self.PTR_REGEX) + self.assertRegex(out, regex) + + def check_malloc_without_gil(self, code): + out = self.check(code) + expected = ('Fatal Python error: _PyMem_DebugMalloc: ' + 'Python memory allocator called without holding the GIL') + self.assertIn(expected, out) + + def test_pymem_malloc_without_gil(self): + # Debug hooks must raise an error if PyMem_Malloc() is called + # without holding the GIL + code = 'import _testcapi; _testcapi.pymem_malloc_without_gil()' + self.check_malloc_without_gil(code) + + def test_pyobject_malloc_without_gil(self): + # Debug hooks must raise an error if PyObject_Malloc() is called + # without holding the GIL + code = 'import _testcapi; _testcapi.pyobject_malloc_without_gil()' + self.check_malloc_without_gil(code) + + def check_pyobject_is_freed(self, func_name): + code = textwrap.dedent(f''' + import gc, os, sys, _testcapi + # Disable the GC to avoid crash on GC collection + gc.disable() + try: + _testcapi.{func_name}() + # Exit immediately to avoid a crash while deallocating + # the invalid object + os._exit(0) + except _testcapi.error: + os._exit(1) + ''') + assert_python_ok( + '-c', code, + PYTHONMALLOC=self.PYTHONMALLOC, + MALLOC_CONF="junk:false", + ) + + def test_pyobject_null_is_freed(self): + self.check_pyobject_is_freed('check_pyobject_null_is_freed') + + def test_pyobject_uninitialized_is_freed(self): + self.check_pyobject_is_freed('check_pyobject_uninitialized_is_freed') + + def test_pyobject_forbidden_bytes_is_freed(self): + self.check_pyobject_is_freed('check_pyobject_forbidden_bytes_is_freed') + + def test_pyobject_freed_is_freed(self): + self.check_pyobject_is_freed('check_pyobject_freed_is_freed') + + 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) + lines = out.splitlines() + for i, line in enumerate(lines, 1): + self.assertIn(b'MemoryError', out) + *_, count = line.split(b' ') + count = int(count) + self.assertLessEqual(count, i*5) + self.assertGreaterEqual(count, i*5-2) + + +class PyMemMallocDebugTests(PyMemDebugTests): + PYTHONMALLOC = 'malloc_debug' + + +@unittest.skipUnless(support.with_pymalloc(), 'need pymalloc') +class PyMemPymallocDebugTests(PyMemDebugTests): + PYTHONMALLOC = 'pymalloc_debug' + + +@unittest.skipUnless(support.Py_DEBUG, 'need Py_DEBUG') +class PyMemDefaultTests(PyMemDebugTests): + # test default allocator of Python compiled in debug mode + PYTHONMALLOC = '' + + +if __name__ == "__main__": + unittest.main() diff --git a/Lib/test/test_capi/test_misc.py b/Lib/test/test_capi/test_misc.py index db7a7741..57563558 100644 --- a/Lib/test/test_capi/test_misc.py +++ b/Lib/test/test_capi/test_misc.py @@ -1,27 +1,33 @@ # Run the _testcapi module tests (tests for the Python/C API): by defn, # these are all functions _testcapi exports whose name begins with 'test_'. -from collections import OrderedDict import _thread +from collections import OrderedDict, deque +import contextlib import importlib.machinery import importlib.util +import json import os import pickle +import queue import random -import re import subprocess import sys import textwrap import threading import time +import types import unittest +import warnings import weakref +import operator from test import support from test.support import MISSING_C_DOCSTRINGS from test.support import import_helper from test.support import threading_helper from test.support import warnings_helper -from test.support.script_helper import assert_python_failure, assert_python_ok +from test.support import requires_limited_api +from test.support.script_helper import assert_python_failure, assert_python_ok, run_python_until_end try: import _posixsubprocess except ImportError: @@ -30,20 +36,33 @@ try: import _testmultiphase except ImportError: _testmultiphase = None +try: + import _testsinglephase +except ImportError: + _testsinglephase = None +try: + import _xxsubinterpreters as _interpreters +except ModuleNotFoundError: + _interpreters = None # Skip this test if the _testcapi module isn't available. _testcapi = import_helper.import_module('_testcapi') import _testinternalcapi -# Were we compiled --with-pydebug or with #define Py_DEBUG? -Py_DEBUG = hasattr(sys, 'gettotalrefcount') +NULL = None def decode_stderr(err): return err.decode('utf-8', 'replace').replace('\r', '') +def requires_subinterpreters(meth): + """Decorator to skip a test if subinterpreters are not supported.""" + return unittest.skipIf(_interpreters is None, + 'subinterpreters required')(meth) + + def testfunction(self): """some doc""" return self @@ -68,71 +87,29 @@ class CAPITest(unittest.TestCase): @support.requires_subprocess() def test_no_FatalError_infinite_loop(self): - with support.SuppressCrashReport(): - p = subprocess.Popen([sys.executable, "-c", - 'import _testcapi;' - '_testcapi.crash_no_current_thread()'], - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - (out, err) = p.communicate() + code = textwrap.dedent(""" + import _testcapi + from test import support + + with support.SuppressCrashReport(): + _testcapi.crash_no_current_thread() + """) + + run_result, _cmd_line = run_python_until_end('-c', code) + _rc, out, err = run_result self.assertEqual(out, b'') # This used to cause an infinite loop. - self.assertTrue(err.rstrip().startswith( - b'Fatal Python error: ' - b'PyThreadState_Get: ' - b'the function must be called with the GIL held, ' - b'but the GIL is released ' - b'(the current Python thread state is NULL)'), + msg = ("Fatal Python error: PyThreadState_Get: " + "the function must be called with the GIL held, " + "after Python initialization and before Python finalization, " + "but the GIL is released " + "(the current Python thread state is NULL)").encode() + self.assertTrue(err.rstrip().startswith(msg), err) def test_memoryview_from_NULL_pointer(self): self.assertRaises(ValueError, _testcapi.make_memoryview_from_NULL_pointer) - def test_exception(self): - raised_exception = ValueError("5") - new_exc = TypeError("TEST") - try: - raise raised_exception - except ValueError as e: - orig_sys_exception = sys.exception() - orig_exception = _testcapi.set_exception(new_exc) - new_sys_exception = sys.exception() - new_exception = _testcapi.set_exception(orig_exception) - reset_sys_exception = sys.exception() - - self.assertEqual(orig_exception, e) - - self.assertEqual(orig_exception, raised_exception) - self.assertEqual(orig_sys_exception, orig_exception) - self.assertEqual(reset_sys_exception, orig_exception) - self.assertEqual(new_exception, new_exc) - self.assertEqual(new_sys_exception, new_exception) - else: - self.fail("Exception not raised") - - def test_exc_info(self): - raised_exception = ValueError("5") - new_exc = TypeError("TEST") - try: - raise raised_exception - except ValueError as e: - tb = e.__traceback__ - orig_sys_exc_info = sys.exc_info() - orig_exc_info = _testcapi.set_exc_info(new_exc.__class__, new_exc, None) - new_sys_exc_info = sys.exc_info() - new_exc_info = _testcapi.set_exc_info(*orig_exc_info) - reset_sys_exc_info = sys.exc_info() - - self.assertEqual(orig_exc_info[1], e) - - self.assertSequenceEqual(orig_exc_info, (raised_exception.__class__, raised_exception, tb)) - self.assertSequenceEqual(orig_sys_exc_info, orig_exc_info) - self.assertSequenceEqual(reset_sys_exc_info, orig_exc_info) - self.assertSequenceEqual(new_exc_info, (new_exc.__class__, new_exc, None)) - self.assertSequenceEqual(new_sys_exc_info, new_exc_info) - else: - self.assertTrue(False) - @unittest.skipUnless(_posixsubprocess, '_posixsubprocess required for this test.') def test_seq_bytes_to_charp_array(self): # Issue #15732: crash in _PySequence_BytesToCharpArray() @@ -231,7 +208,7 @@ class CAPITest(unittest.TestCase): def test_return_null_without_error(self): # Issue #23571: A function must not return NULL without setting an # error - if Py_DEBUG: + if support.Py_DEBUG: code = textwrap.dedent(""" import _testcapi from test import support @@ -259,7 +236,7 @@ class CAPITest(unittest.TestCase): def test_return_result_with_error(self): # Issue #23571: A function must not return a result with an error set - if Py_DEBUG: + if support.Py_DEBUG: code = textwrap.dedent(""" import _testcapi from test import support @@ -324,195 +301,39 @@ 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) - lines = out.splitlines() - for i, line in enumerate(lines, 1): - self.assertIn(b'MemoryError', out) - *_, count = line.split(b' ') - count = int(count) - self.assertLessEqual(count, i*5) - self.assertGreaterEqual(count, i*5-2) - - def test_mapping_keys_values_items(self): - class Mapping1(dict): - def keys(self): - return list(super().keys()) - def values(self): - return list(super().values()) - def items(self): - return list(super().items()) - class Mapping2(dict): - def keys(self): - return tuple(super().keys()) - def values(self): - return tuple(super().values()) - def items(self): - return tuple(super().items()) - dict_obj = {'foo': 1, 'bar': 2, 'spam': 3} - - for mapping in [{}, OrderedDict(), Mapping1(), Mapping2(), - dict_obj, OrderedDict(dict_obj), - Mapping1(dict_obj), Mapping2(dict_obj)]: - self.assertListEqual(_testcapi.get_mapping_keys(mapping), - list(mapping.keys())) - self.assertListEqual(_testcapi.get_mapping_values(mapping), - list(mapping.values())) - self.assertListEqual(_testcapi.get_mapping_items(mapping), - list(mapping.items())) - - def test_mapping_keys_values_items_bad_arg(self): - self.assertRaises(AttributeError, _testcapi.get_mapping_keys, None) - self.assertRaises(AttributeError, _testcapi.get_mapping_values, None) - self.assertRaises(AttributeError, _testcapi.get_mapping_items, None) - - class BadMapping: - def keys(self): - return None - def values(self): - return None - def items(self): - return None - bad_mapping = BadMapping() - self.assertRaises(TypeError, _testcapi.get_mapping_keys, bad_mapping) - self.assertRaises(TypeError, _testcapi.get_mapping_values, bad_mapping) - self.assertRaises(TypeError, _testcapi.get_mapping_items, bad_mapping) - - def test_mapping_has_key(self): - dct = {'a': 1} - self.assertTrue(_testcapi.mapping_has_key(dct, 'a')) - self.assertFalse(_testcapi.mapping_has_key(dct, 'b')) - - class SubDict(dict): - pass - - dct2 = SubDict({'a': 1}) - self.assertTrue(_testcapi.mapping_has_key(dct2, 'a')) - self.assertFalse(_testcapi.mapping_has_key(dct2, 'b')) - - def test_sequence_set_slice(self): - # Correct case: - data = [1, 2, 3, 4, 5] - data_copy = data.copy() - - _testcapi.sequence_set_slice(data, 1, 3, [8, 9]) - data_copy[1:3] = [8, 9] - self.assertEqual(data, data_copy) - self.assertEqual(data, [1, 8, 9, 4, 5]) - - # Custom class: - class Custom: - def __setitem__(self, index, value): - self.index = index - self.value = value - - c = Custom() - _testcapi.sequence_set_slice(c, 0, 5, 'abc') - self.assertEqual(c.index, slice(0, 5)) - self.assertEqual(c.value, 'abc') - - # Immutable sequences must raise: - bad_seq1 = (1, 2, 3, 4) - with self.assertRaises(TypeError): - _testcapi.sequence_set_slice(bad_seq1, 1, 3, (8, 9)) - self.assertEqual(bad_seq1, (1, 2, 3, 4)) - - bad_seq2 = 'abcd' - with self.assertRaises(TypeError): - _testcapi.sequence_set_slice(bad_seq2, 1, 3, 'xy') - self.assertEqual(bad_seq2, 'abcd') - - # Not a sequence: - with self.assertRaises(TypeError): - _testcapi.sequence_set_slice(None, 1, 3, 'xy') - - mapping = {1: 'a', 2: 'b', 3: 'c'} - with self.assertRaises(TypeError): - _testcapi.sequence_set_slice(mapping, 1, 3, 'xy') - self.assertEqual(mapping, {1: 'a', 2: 'b', 3: 'c'}) - - def test_sequence_del_slice(self): - # Correct case: - data = [1, 2, 3, 4, 5] - data_copy = data.copy() - - _testcapi.sequence_del_slice(data, 1, 3) - del data_copy[1:3] - self.assertEqual(data, data_copy) - self.assertEqual(data, [1, 4, 5]) - - # Custom class: - class Custom: - def __delitem__(self, index): - self.index = index - - c = Custom() - _testcapi.sequence_del_slice(c, 0, 5) - self.assertEqual(c.index, slice(0, 5)) - - # Immutable sequences must raise: - bad_seq1 = (1, 2, 3, 4) - with self.assertRaises(TypeError): - _testcapi.sequence_del_slice(bad_seq1, 1, 3) - self.assertEqual(bad_seq1, (1, 2, 3, 4)) - - bad_seq2 = 'abcd' - with self.assertRaises(TypeError): - _testcapi.sequence_del_slice(bad_seq2, 1, 3) - self.assertEqual(bad_seq2, 'abcd') - - # Not a sequence: - with self.assertRaises(TypeError): - _testcapi.sequence_del_slice(None, 1, 3) - - mapping = {1: 'a', 2: 'b', 3: 'c'} - with self.assertRaises(TypeError): - _testcapi.sequence_del_slice(mapping, 1, 3) - self.assertEqual(mapping, {1: 'a', 2: 'b', 3: 'c'}) + def check_negative_refcount(self, code): + # bpo-35059: Check that Py_DECREF() reports the correct filename + # when calling _Py_NegativeRefcount() to abort Python. + code = textwrap.dedent(code) + rc, out, err = assert_python_failure('-c', code) + self.assertRegex(err, + br'_testcapimodule\.c:[0-9]+: ' + br'_Py_NegativeRefcount: Assertion failed: ' + br'object has negative ref count') @unittest.skipUnless(hasattr(_testcapi, 'negative_refcount'), - 'need _testcapi.negative_refcount') + 'need _testcapi.negative_refcount()') def test_negative_refcount(self): - # bpo-35059: Check that Py_DECREF() reports the correct filename - # when calling _Py_NegativeRefcount() to abort Python. - code = textwrap.dedent(""" + code = """ import _testcapi from test import support with support.SuppressCrashReport(): _testcapi.negative_refcount() - """) - rc, out, err = assert_python_failure('-c', code) - self.assertRegex(err, - br'_testcapimodule\.c:[0-9]+: ' - br'_Py_NegativeRefcount: Assertion failed: ' - br'object has negative ref count') + """ + self.check_negative_refcount(code) + + @unittest.skipUnless(hasattr(_testcapi, 'decref_freed_object'), + 'need _testcapi.decref_freed_object()') + def test_decref_freed_object(self): + code = """ + import _testcapi + from test import support + + with support.SuppressCrashReport(): + _testcapi.decref_freed_object() + """ + self.check_negative_refcount(code) def test_trashcan_subclass(self): # bpo-35983: Check that the trashcan mechanism for "list" is NOT @@ -609,7 +430,7 @@ class CAPITest(unittest.TestCase): del subclass_instance # Test that setting __class__ modified the reference counts of the types - if Py_DEBUG: + if support.Py_DEBUG: # gh-89373: In debug mode, _Py_Dealloc() keeps a strong reference # to the type while calling tp_dealloc() self.assertEqual(type_refcnt, B.refcnt_in_del) @@ -633,6 +454,30 @@ class CAPITest(unittest.TestCase): inst = _testcapi.HeapCTypeWithDict() self.assertEqual({}, inst.__dict__) + def test_heaptype_with_managed_dict(self): + inst = _testcapi.HeapCTypeWithManagedDict() + inst.foo = 42 + self.assertEqual(inst.foo, 42) + self.assertEqual(inst.__dict__, {"foo": 42}) + + inst = _testcapi.HeapCTypeWithManagedDict() + self.assertEqual({}, inst.__dict__) + + a = _testcapi.HeapCTypeWithManagedDict() + b = _testcapi.HeapCTypeWithManagedDict() + a.b = b + b.a = a + del a, b + + def test_sublclassing_managed_dict(self): + + class C(_testcapi.HeapCTypeWithManagedDict): + pass + + i = C() + i.spam = i + del i + def test_heaptype_with_negative_dict(self): inst = _testcapi.HeapCTypeWithNegativeDict() inst.foo = 42 @@ -649,6 +494,37 @@ class CAPITest(unittest.TestCase): self.assertEqual(ref(), inst) self.assertEqual(inst.weakreflist, ref) + def test_heaptype_with_managed_weakref(self): + inst = _testcapi.HeapCTypeWithManagedWeakref() + ref = weakref.ref(inst) + self.assertEqual(ref(), inst) + + def test_sublclassing_managed_weakref(self): + + class C(_testcapi.HeapCTypeWithManagedWeakref): + pass + + inst = C() + ref = weakref.ref(inst) + self.assertEqual(ref(), inst) + + def test_sublclassing_managed_both(self): + + class C1(_testcapi.HeapCTypeWithManagedWeakref, _testcapi.HeapCTypeWithManagedDict): + pass + + class C2(_testcapi.HeapCTypeWithManagedDict, _testcapi.HeapCTypeWithManagedWeakref): + pass + + for cls in (C1, C2): + inst = cls() + ref = weakref.ref(inst) + self.assertEqual(ref(), inst) + inst.spam = inst + del inst + ref = weakref.ref(cls()) + self.assertIs(ref(), None) + def test_heaptype_with_buffer(self): inst = _testcapi.HeapCTypeWithBuffer() b = bytes(inst) @@ -679,7 +555,7 @@ class CAPITest(unittest.TestCase): del subclass_instance # Test that setting __class__ modified the reference counts of the types - if Py_DEBUG: + if support.Py_DEBUG: # gh-89373: In debug mode, _Py_Dealloc() keeps a strong reference # to the type while calling tp_dealloc() self.assertEqual(type_refcnt, _testcapi.HeapCTypeSubclassWithFinalizer.refcnt_in_del) @@ -701,79 +577,167 @@ class CAPITest(unittest.TestCase): del obj.value self.assertEqual(obj.pvalue, 0) + def test_heaptype_with_custom_metaclass(self): + metaclass = _testcapi.HeapCTypeMetaclass + self.assertTrue(issubclass(metaclass, type)) + + # Class creation from C + t = _testcapi.pytype_fromspec_meta(metaclass) + self.assertIsInstance(t, type) + self.assertEqual(t.__name__, "HeapCTypeViaMetaclass") + self.assertIs(type(t), metaclass) + + # Class creation from Python + t = metaclass("PyClassViaMetaclass", (), {}) + self.assertIsInstance(t, type) + self.assertEqual(t.__name__, "PyClassViaMetaclass") + + def test_heaptype_with_custom_metaclass_null_new(self): + metaclass = _testcapi.HeapCTypeMetaclassNullNew + + self.assertTrue(issubclass(metaclass, type)) + + # Class creation from C + t = _testcapi.pytype_fromspec_meta(metaclass) + self.assertIsInstance(t, type) + self.assertEqual(t.__name__, "HeapCTypeViaMetaclass") + self.assertIs(type(t), metaclass) + + # Class creation from Python + with self.assertRaisesRegex(TypeError, "cannot create .* instances"): + metaclass("PyClassViaMetaclass", (), {}) + + def test_heaptype_with_custom_metaclass_custom_new(self): + metaclass = _testcapi.HeapCTypeMetaclassCustomNew + + self.assertTrue(issubclass(_testcapi.HeapCTypeMetaclassCustomNew, type)) + + msg = "Metaclasses with custom tp_new are not supported." + with self.assertRaisesRegex(TypeError, msg): + t = _testcapi.pytype_fromspec_meta(metaclass) + + def test_heaptype_with_custom_metaclass_deprecation(self): + metaclass = _testcapi.HeapCTypeMetaclassCustomNew + + # gh-103968: a metaclass with custom tp_new is deprecated, but still + # allowed for functions that existed in 3.11 + # (PyType_FromSpecWithBases is used here). + class Base(metaclass=metaclass): + pass + + # Class creation from C + with warnings_helper.check_warnings( + ('.* _testcapi.Subclass .* custom tp_new.*in Python 3.14.*', DeprecationWarning), + ): + sub = _testcapi.make_type_with_base(Base) + self.assertTrue(issubclass(sub, Base)) + self.assertIsInstance(sub, metaclass) + def test_multiple_inheritance_ctypes_with_weakref_or_dict(self): - class Both1(_testcapi.HeapCTypeWithWeakref, _testcapi.HeapCTypeWithDict): + with self.assertRaises(TypeError): + class Both1(_testcapi.HeapCTypeWithWeakref, _testcapi.HeapCTypeWithDict): + pass + with self.assertRaises(TypeError): + class Both2(_testcapi.HeapCTypeWithDict, _testcapi.HeapCTypeWithWeakref): + pass + + def test_multiple_inheritance_ctypes_with_weakref_or_dict_and_other_builtin(self): + + with self.assertRaises(TypeError): + class C1(_testcapi.HeapCTypeWithDict, list): + pass + + with self.assertRaises(TypeError): + class C2(_testcapi.HeapCTypeWithWeakref, list): + pass + + class C3(_testcapi.HeapCTypeWithManagedDict, list): pass - class Both2(_testcapi.HeapCTypeWithDict, _testcapi.HeapCTypeWithWeakref): + class C4(_testcapi.HeapCTypeWithManagedWeakref, list): pass - for cls in (_testcapi.HeapCTypeWithDict, _testcapi.HeapCTypeWithDict2, - _testcapi.HeapCTypeWithWeakref, _testcapi.HeapCTypeWithWeakref2): - for cls2 in (_testcapi.HeapCTypeWithDict, _testcapi.HeapCTypeWithDict2, - _testcapi.HeapCTypeWithWeakref, _testcapi.HeapCTypeWithWeakref2): - if cls is not cls2: - class S(cls, cls2): - pass - class B1(Both1, cls): + inst = C3() + inst.append(0) + str(inst.__dict__) + + inst = C4() + inst.append(0) + str(inst.__weakref__) + + for cls in (_testcapi.HeapCTypeWithManagedDict, _testcapi.HeapCTypeWithManagedWeakref): + for cls2 in (_testcapi.HeapCTypeWithDict, _testcapi.HeapCTypeWithWeakref): + class S(cls, cls2): + pass + class B1(C3, cls): pass - class B2(Both1, cls): + class B2(C4, cls): pass + def test_pytype_fromspec_with_repeated_slots(self): + for variant in range(2): + with self.subTest(variant=variant): + with self.assertRaises(SystemError): + _testcapi.create_type_from_repeated_slots(variant) + + @warnings_helper.ignore_warnings(category=DeprecationWarning) + def test_immutable_type_with_mutable_base(self): + # Add deprecation warning here so it's removed in 3.14 + warnings._deprecated( + 'creating immutable classes with mutable bases', remove=(3, 14)) + + class MutableBase: + def meth(self): + return 'original' + + with self.assertWarns(DeprecationWarning): + ImmutableSubclass = _testcapi.make_immutable_type_with_base( + MutableBase) + instance = ImmutableSubclass() + + self.assertEqual(instance.meth(), 'original') + + # Cannot override the static type's method + with self.assertRaisesRegex( + TypeError, + "cannot set 'meth' attribute of immutable type"): + ImmutableSubclass.meth = lambda self: 'overridden' + self.assertEqual(instance.meth(), 'original') + + # Can change the method on the mutable base + MutableBase.meth = lambda self: 'changed' + self.assertEqual(instance.meth(), 'changed') + def test_pynumber_tobase(self): from _testcapi import pynumber_tobase - self.assertEqual(pynumber_tobase(123, 2), '0b1111011') - self.assertEqual(pynumber_tobase(123, 8), '0o173') - self.assertEqual(pynumber_tobase(123, 10), '123') - self.assertEqual(pynumber_tobase(123, 16), '0x7b') - self.assertEqual(pynumber_tobase(-123, 2), '-0b1111011') - self.assertEqual(pynumber_tobase(-123, 8), '-0o173') - self.assertEqual(pynumber_tobase(-123, 10), '-123') - self.assertEqual(pynumber_tobase(-123, 16), '-0x7b') + small_number = 123 + large_number = 2**64 + class IDX: + def __init__(self, val): + self.val = val + def __index__(self): + return self.val + + test_cases = ((2, '0b1111011', '0b10000000000000000000000000000000000000000000000000000000000000000'), + (8, '0o173', '0o2000000000000000000000'), + (10, '123', '18446744073709551616'), + (16, '0x7b', '0x10000000000000000')) + for base, small_target, large_target in test_cases: + with self.subTest(base=base, st=small_target, lt=large_target): + # Test for small number + self.assertEqual(pynumber_tobase(small_number, base), small_target) + self.assertEqual(pynumber_tobase(-small_number, base), '-' + small_target) + self.assertEqual(pynumber_tobase(IDX(small_number), base), small_target) + # Test for large number(out of range of a longlong,i.e.[-2**63, 2**63-1]) + self.assertEqual(pynumber_tobase(large_number, base), large_target) + self.assertEqual(pynumber_tobase(-large_number, base), '-' + large_target) + self.assertEqual(pynumber_tobase(IDX(large_number), base), large_target) + self.assertRaises(TypeError, pynumber_tobase, IDX(123.0), 10) + self.assertRaises(TypeError, pynumber_tobase, IDX('123'), 10) self.assertRaises(TypeError, pynumber_tobase, 123.0, 10) self.assertRaises(TypeError, pynumber_tobase, '123', 10) self.assertRaises(SystemError, pynumber_tobase, 123, 0) - def check_fatal_error(self, code, expected, not_expected=()): - with support.SuppressCrashReport(): - rc, out, err = assert_python_failure('-sSI', '-c', code) - - err = decode_stderr(err) - self.assertIn('Fatal Python error: test_fatal_error: MESSAGE\n', - err) - - match = re.search(r'^Extension modules:(.*) \(total: ([0-9]+)\)$', - err, re.MULTILINE) - if not match: - self.fail(f"Cannot find 'Extension modules:' in {err!r}") - modules = set(match.group(1).strip().split(', ')) - total = int(match.group(2)) - - for name in expected: - self.assertIn(name, modules) - for name in not_expected: - self.assertNotIn(name, modules) - self.assertEqual(len(modules), total) - - @support.requires_subprocess() - def test_fatal_error(self): - # By default, stdlib extension modules are ignored, - # but not test modules. - expected = ('_testcapi',) - not_expected = ('sys',) - code = 'import _testcapi, sys; _testcapi.fatal_error(b"MESSAGE")' - self.check_fatal_error(code, expected, not_expected) - - # Mark _testcapi as stdlib module, but not sys - expected = ('sys',) - not_expected = ('_testcapi',) - code = textwrap.dedent(''' - import _testcapi, sys - sys.stdlib_module_names = frozenset({"_testcapi"}) - _testcapi.fatal_error(b"MESSAGE") - ''') - self.check_fatal_error(code, expected) - def test_pyobject_repr_from_null(self): s = _testcapi.pyobject_repr_from_null() self.assertEqual(s, '<NULL>') @@ -817,6 +781,20 @@ class CAPITest(unittest.TestCase): with self.subTest(name=name): self.assertTrue(hasattr(ctypes.pythonapi, name)) + def test_clear_managed_dict(self): + + class C: + def __init__(self): + self.a = 1 + + c = C() + _testcapi.clear_managed_dict(c) + self.assertEqual(c.__dict__, {}) + c = C() + self.assertEqual(c.__dict__, {'a':1}) + _testcapi.clear_managed_dict(c) + self.assertEqual(c.__dict__, {}) + def test_eval_get_func_name(self): def function_example(): ... @@ -882,9 +860,356 @@ class CAPITest(unittest.TestCase): with self.assertRaises(SystemError): _testcapi.function_get_module(None) # not a function + def test_function_get_defaults(self): + def some( + pos_only1, pos_only2='p', + /, + zero=0, optional=None, + *, + kw1, + kw2=True, + ): + pass + + defaults = _testcapi.function_get_defaults(some) + self.assertEqual(defaults, ('p', 0, None)) + self.assertEqual(defaults, some.__defaults__) + + with self.assertRaises(SystemError): + _testcapi.function_get_defaults(None) # not a function + + def test_function_set_defaults(self): + def some( + pos_only1, pos_only2='p', + /, + zero=0, optional=None, + *, + kw1, + kw2=True, + ): + pass + + old_defaults = ('p', 0, None) + self.assertEqual(_testcapi.function_get_defaults(some), old_defaults) + self.assertEqual(some.__defaults__, old_defaults) + + with self.assertRaises(SystemError): + _testcapi.function_set_defaults(some, 1) # not tuple or None + self.assertEqual(_testcapi.function_get_defaults(some), old_defaults) + self.assertEqual(some.__defaults__, old_defaults) + + with self.assertRaises(SystemError): + _testcapi.function_set_defaults(1, ()) # not a function + self.assertEqual(_testcapi.function_get_defaults(some), old_defaults) + self.assertEqual(some.__defaults__, old_defaults) + + new_defaults = ('q', 1, None) + _testcapi.function_set_defaults(some, new_defaults) + self.assertEqual(_testcapi.function_get_defaults(some), new_defaults) + self.assertEqual(some.__defaults__, new_defaults) + + # Empty tuple is fine: + new_defaults = () + _testcapi.function_set_defaults(some, new_defaults) + self.assertEqual(_testcapi.function_get_defaults(some), new_defaults) + self.assertEqual(some.__defaults__, new_defaults) + + class tuplesub(tuple): ... # tuple subclasses must work + + new_defaults = tuplesub(((1, 2), ['a', 'b'], None)) + _testcapi.function_set_defaults(some, new_defaults) + self.assertEqual(_testcapi.function_get_defaults(some), new_defaults) + self.assertEqual(some.__defaults__, new_defaults) + + # `None` is special, it sets `defaults` to `NULL`, + # it needs special handling in `_testcapi`: + _testcapi.function_set_defaults(some, None) + self.assertEqual(_testcapi.function_get_defaults(some), None) + self.assertEqual(some.__defaults__, None) + + def test_function_get_kw_defaults(self): + def some( + pos_only1, pos_only2='p', + /, + zero=0, optional=None, + *, + kw1, + kw2=True, + ): + pass + + defaults = _testcapi.function_get_kw_defaults(some) + self.assertEqual(defaults, {'kw2': True}) + self.assertEqual(defaults, some.__kwdefaults__) + + with self.assertRaises(SystemError): + _testcapi.function_get_kw_defaults(None) # not a function + + def test_function_set_kw_defaults(self): + def some( + pos_only1, pos_only2='p', + /, + zero=0, optional=None, + *, + kw1, + kw2=True, + ): + pass + + old_defaults = {'kw2': True} + self.assertEqual(_testcapi.function_get_kw_defaults(some), old_defaults) + self.assertEqual(some.__kwdefaults__, old_defaults) + + with self.assertRaises(SystemError): + _testcapi.function_set_kw_defaults(some, 1) # not dict or None + self.assertEqual(_testcapi.function_get_kw_defaults(some), old_defaults) + self.assertEqual(some.__kwdefaults__, old_defaults) + + with self.assertRaises(SystemError): + _testcapi.function_set_kw_defaults(1, {}) # not a function + self.assertEqual(_testcapi.function_get_kw_defaults(some), old_defaults) + self.assertEqual(some.__kwdefaults__, old_defaults) + + new_defaults = {'kw2': (1, 2, 3)} + _testcapi.function_set_kw_defaults(some, new_defaults) + self.assertEqual(_testcapi.function_get_kw_defaults(some), new_defaults) + self.assertEqual(some.__kwdefaults__, new_defaults) + + # Empty dict is fine: + new_defaults = {} + _testcapi.function_set_kw_defaults(some, new_defaults) + self.assertEqual(_testcapi.function_get_kw_defaults(some), new_defaults) + self.assertEqual(some.__kwdefaults__, new_defaults) + + class dictsub(dict): ... # dict subclasses must work + + new_defaults = dictsub({'kw2': None}) + _testcapi.function_set_kw_defaults(some, new_defaults) + self.assertEqual(_testcapi.function_get_kw_defaults(some), new_defaults) + self.assertEqual(some.__kwdefaults__, new_defaults) + + # `None` is special, it sets `kwdefaults` to `NULL`, + # it needs special handling in `_testcapi`: + _testcapi.function_set_kw_defaults(some, None) + self.assertEqual(_testcapi.function_get_kw_defaults(some), None) + self.assertEqual(some.__kwdefaults__, None) + + def test_unstable_gc_new_with_extra_data(self): + class Data(_testcapi.ObjExtraData): + __slots__ = ('x', 'y') + + d = Data() + d.x = 10 + d.y = 20 + d.extra = 30 + self.assertEqual(d.x, 10) + self.assertEqual(d.y, 20) + self.assertEqual(d.extra, 30) + del d.extra + self.assertIsNone(d.extra) + + def test_sys_getobject(self): + getobject = _testcapi.sys_getobject + + self.assertIs(getobject(b'stdout'), sys.stdout) + with support.swap_attr(sys, '\U0001f40d', 42): + self.assertEqual(getobject('\U0001f40d'.encode()), 42) + + self.assertIs(getobject(b'nonexisting'), AttributeError) + self.assertIs(getobject(b'\xff'), AttributeError) + # CRASHES getobject(NULL) + + def test_sys_setobject(self): + setobject = _testcapi.sys_setobject + + value = ['value'] + value2 = ['value2'] + try: + self.assertEqual(setobject(b'newattr', value), 0) + self.assertIs(sys.newattr, value) + self.assertEqual(setobject(b'newattr', value2), 0) + self.assertIs(sys.newattr, value2) + self.assertEqual(setobject(b'newattr', NULL), 0) + self.assertFalse(hasattr(sys, 'newattr')) + self.assertEqual(setobject(b'newattr', NULL), 0) + finally: + with contextlib.suppress(AttributeError): + del sys.newattr + try: + self.assertEqual(setobject('\U0001f40d'.encode(), value), 0) + self.assertIs(getattr(sys, '\U0001f40d'), value) + self.assertEqual(setobject('\U0001f40d'.encode(), NULL), 0) + self.assertFalse(hasattr(sys, '\U0001f40d')) + finally: + with contextlib.suppress(AttributeError): + delattr(sys, '\U0001f40d') + + with self.assertRaises(UnicodeDecodeError): + setobject(b'\xff', value) + # CRASHES setobject(NULL, value) + + +@requires_limited_api +class TestHeapTypeRelative(unittest.TestCase): + """Test API for extending opaque types (PEP 697)""" + + @requires_limited_api + def test_heaptype_relative_sizes(self): + # Test subclassing using "relative" basicsize, see PEP 697 + def check(extra_base_size, extra_size): + Base, Sub, instance, data_ptr, data_offset, data_size = ( + _testcapi.make_sized_heaptypes( + extra_base_size, -extra_size)) + + # no alignment shenanigans when inheriting directly + if extra_size == 0: + self.assertEqual(Base.__basicsize__, Sub.__basicsize__) + self.assertEqual(data_size, 0) + + else: + # The following offsets should be in increasing order: + offsets = [ + (0, 'start of object'), + (Base.__basicsize__, 'end of base data'), + (data_offset, 'subclass data'), + (data_offset + extra_size, 'end of requested subcls data'), + (data_offset + data_size, 'end of reserved subcls data'), + (Sub.__basicsize__, 'end of object'), + ] + ordered_offsets = sorted(offsets, key=operator.itemgetter(0)) + self.assertEqual( + offsets, ordered_offsets, + msg=f'Offsets not in expected order, got: {ordered_offsets}') + + # end of reserved subcls data == end of object + self.assertEqual(Sub.__basicsize__, data_offset + data_size) + + # we don't reserve (requested + alignment) or more data + self.assertLess(data_size - extra_size, + _testcapi.ALIGNOF_MAX_ALIGN_T) + + # The offsets/sizes we calculated should be aligned. + self.assertEqual(data_offset % _testcapi.ALIGNOF_MAX_ALIGN_T, 0) + self.assertEqual(data_size % _testcapi.ALIGNOF_MAX_ALIGN_T, 0) + + sizes = sorted({0, 1, 2, 3, 4, 7, 8, 123, + object.__basicsize__, + object.__basicsize__-1, + object.__basicsize__+1}) + for extra_base_size in sizes: + for extra_size in sizes: + args = dict(extra_base_size=extra_base_size, + extra_size=extra_size) + with self.subTest(**args): + check(**args) + + def test_HeapCCollection(self): + """Make sure HeapCCollection works properly by itself""" + collection = _testcapi.HeapCCollection(1, 2, 3) + self.assertEqual(list(collection), [1, 2, 3]) + + def test_heaptype_inherit_itemsize(self): + """Test HeapCCollection subclasses work properly""" + sizes = sorted({0, 1, 2, 3, 4, 7, 8, 123, + object.__basicsize__, + object.__basicsize__-1, + object.__basicsize__+1}) + for extra_size in sizes: + with self.subTest(extra_size=extra_size): + Sub = _testcapi.subclass_var_heaptype( + _testcapi.HeapCCollection, -extra_size, 0, 0) + collection = Sub(1, 2, 3) + collection.set_data_to_3s() + + self.assertEqual(list(collection), [1, 2, 3]) + mem = collection.get_data() + self.assertGreaterEqual(len(mem), extra_size) + self.assertTrue(set(mem) <= {3}, f'got {mem!r}') + + def test_heaptype_invalid_inheritance(self): + with self.assertRaises(SystemError, + msg="Cannot extend variable-size class without " + + "Py_TPFLAGS_ITEMS_AT_END"): + _testcapi.subclass_heaptype(int, -8, 0) + + def test_heaptype_relative_members(self): + """Test HeapCCollection subclasses work properly""" + sizes = sorted({0, 1, 2, 3, 4, 7, 8, 123, + object.__basicsize__, + object.__basicsize__-1, + object.__basicsize__+1}) + for extra_base_size in sizes: + for extra_size in sizes: + for offset in sizes: + with self.subTest(extra_base_size=extra_base_size, extra_size=extra_size, offset=offset): + if offset < extra_size: + Sub = _testcapi.make_heaptype_with_member( + extra_base_size, -extra_size, offset, True) + Base = Sub.mro()[1] + instance = Sub() + self.assertEqual(instance.memb, instance.get_memb()) + instance.set_memb(13) + self.assertEqual(instance.memb, instance.get_memb()) + self.assertEqual(instance.get_memb(), 13) + instance.memb = 14 + self.assertEqual(instance.memb, instance.get_memb()) + self.assertEqual(instance.get_memb(), 14) + self.assertGreaterEqual(instance.get_memb_offset(), Base.__basicsize__) + self.assertLess(instance.get_memb_offset(), Sub.__basicsize__) + with self.assertRaises(SystemError): + instance.get_memb_relative() + with self.assertRaises(SystemError): + instance.set_memb_relative(0) + else: + with self.assertRaises(SystemError): + Sub = _testcapi.make_heaptype_with_member( + extra_base_size, -extra_size, offset, True) + with self.assertRaises(SystemError): + Sub = _testcapi.make_heaptype_with_member( + extra_base_size, extra_size, offset, True) + with self.subTest(extra_base_size=extra_base_size, extra_size=extra_size): + with self.assertRaises(SystemError): + Sub = _testcapi.make_heaptype_with_member( + extra_base_size, -extra_size, -1, True) + + def test_heaptype_relative_members_errors(self): + with self.assertRaisesRegex( + SystemError, + r"With Py_RELATIVE_OFFSET, basicsize must be negative"): + _testcapi.make_heaptype_with_member(0, 1234, 0, True) + with self.assertRaisesRegex( + SystemError, r"Member offset out of range \(0\.\.-basicsize\)"): + _testcapi.make_heaptype_with_member(0, -8, 1234, True) + with self.assertRaisesRegex( + SystemError, r"Member offset out of range \(0\.\.-basicsize\)"): + _testcapi.make_heaptype_with_member(0, -8, -1, True) + + Sub = _testcapi.make_heaptype_with_member(0, -8, 0, True) + instance = Sub() + with self.assertRaisesRegex( + SystemError, r"PyMember_GetOne used with Py_RELATIVE_OFFSET"): + instance.get_memb_relative() + with self.assertRaisesRegex( + SystemError, r"PyMember_SetOne used with Py_RELATIVE_OFFSET"): + instance.set_memb_relative(0) + + def test_pyobject_getitemdata_error(self): + """Test PyObject_GetItemData fails on unsupported types""" + with self.assertRaises(TypeError): + # None is not variable-length + _testcapi.pyobject_getitemdata(None) + with self.assertRaises(TypeError): + # int is variable-length, but doesn't have the + # Py_TPFLAGS_ITEMS_AT_END layout (and flag) + _testcapi.pyobject_getitemdata(0) + class TestPendingCalls(unittest.TestCase): + # See the comment in ceval.c (at the "handle_eval_breaker" label) + # about when pending calls get run. This is especially relevant + # here for creating deterministic tests. + def pendingcalls_submit(self, l, n): def callback(): #this function can be interrupted by thread switching so let's @@ -962,6 +1287,395 @@ class TestPendingCalls(unittest.TestCase): self.pendingcalls_submit(l, n) self.pendingcalls_wait(l, n) + def test_gen_get_code(self): + def genf(): yield + gen = genf() + self.assertEqual(_testcapi.gen_get_code(gen), gen.gi_code) + + class PendingTask(types.SimpleNamespace): + + _add_pending = _testinternalcapi.pending_threadfunc + + def __init__(self, req, taskid=None, notify_done=None): + self.id = taskid + self.req = req + self.notify_done = notify_done + + self.creator_tid = threading.get_ident() + self.requester_tid = None + self.runner_tid = None + self.result = None + + def run(self): + assert self.result is None + self.runner_tid = threading.get_ident() + self._run() + if self.notify_done is not None: + self.notify_done() + + def _run(self): + self.result = self.req + + def run_in_pending_call(self, worker_tids): + assert self._add_pending is _testinternalcapi.pending_threadfunc + self.requester_tid = threading.get_ident() + def callback(): + assert self.result is None + # It can be tricky to control which thread handles + # the eval breaker, so we take a naive approach to + # make sure. + if threading.get_ident() not in worker_tids: + self._add_pending(callback, ensure_added=True) + return + self.run() + self._add_pending(callback, ensure_added=True) + + def create_thread(self, worker_tids): + return threading.Thread( + target=self.run_in_pending_call, + args=(worker_tids,), + ) + + def wait_for_result(self): + while self.result is None: + time.sleep(0.01) + + @threading_helper.requires_working_threading() + def test_subthreads_can_handle_pending_calls(self): + payload = 'Spam spam spam spam. Lovely spam! Wonderful spam!' + + task = self.PendingTask(payload) + def do_the_work(): + tid = threading.get_ident() + t = task.create_thread({tid}) + with threading_helper.start_threads([t]): + task.wait_for_result() + t = threading.Thread(target=do_the_work) + with threading_helper.start_threads([t]): + pass + + self.assertEqual(task.result, payload) + + @threading_helper.requires_working_threading() + def test_many_subthreads_can_handle_pending_calls(self): + main_tid = threading.get_ident() + self.assertEqual(threading.main_thread().ident, main_tid) + + # We can't use queue.Queue since it isn't reentrant relative + # to pending calls. + _queue = deque() + _active = deque() + _done_lock = threading.Lock() + def queue_put(task): + _queue.append(task) + _active.append(True) + def queue_get(): + try: + task = _queue.popleft() + except IndexError: + raise queue.Empty + return task + def queue_task_done(): + _active.pop() + if not _active: + try: + _done_lock.release() + except RuntimeError: + assert not _done_lock.locked() + def queue_empty(): + return not _queue + def queue_join(): + _done_lock.acquire() + _done_lock.release() + + tasks = [] + for i in range(20): + task = self.PendingTask( + req=f'request {i}', + taskid=i, + notify_done=queue_task_done, + ) + tasks.append(task) + queue_put(task) + # This will be released once all the tasks have finished. + _done_lock.acquire() + + def add_tasks(worker_tids): + while True: + if done: + return + try: + task = queue_get() + except queue.Empty: + break + task.run_in_pending_call(worker_tids) + + done = False + def run_tasks(): + while not queue_empty(): + if done: + return + time.sleep(0.01) + # Give the worker a chance to handle any remaining pending calls. + while not done: + time.sleep(0.01) + + # Start the workers and wait for them to finish. + worker_threads = [threading.Thread(target=run_tasks) + for _ in range(3)] + with threading_helper.start_threads(worker_threads): + try: + # Add a pending call for each task. + worker_tids = [t.ident for t in worker_threads] + threads = [threading.Thread(target=add_tasks, args=(worker_tids,)) + for _ in range(3)] + with threading_helper.start_threads(threads): + try: + pass + except BaseException: + done = True + raise # re-raise + # Wait for the pending calls to finish. + queue_join() + # Notify the workers that they can stop. + done = True + except BaseException: + done = True + raise # re-raise + runner_tids = [t.runner_tid for t in tasks] + + self.assertNotIn(main_tid, runner_tids) + for task in tasks: + with self.subTest(f'task {task.id}'): + self.assertNotEqual(task.requester_tid, main_tid) + self.assertNotEqual(task.requester_tid, task.runner_tid) + self.assertNotIn(task.requester_tid, runner_tids) + + @requires_subinterpreters + def test_isolated_subinterpreter(self): + # We exercise the most important permutations. + + # This test relies on pending calls getting called + # (eval breaker tripped) at each loop iteration + # and at each call. + + maxtext = 250 + main_interpid = 0 + interpid = _interpreters.create() + _interpreters.run_string(interpid, f"""if True: + import json + import os + import threading + import time + import _testinternalcapi + from test.support import threading_helper + """) + + def create_pipe(): + r, w = os.pipe() + self.addCleanup(lambda: os.close(r)) + self.addCleanup(lambda: os.close(w)) + return r, w + + with self.subTest('add in main, run in subinterpreter'): + r_ready, w_ready = create_pipe() + r_done, w_done= create_pipe() + timeout = time.time() + 30 # seconds + + def do_work(): + _interpreters.run_string(interpid, f"""if True: + # Wait until this interp has handled the pending call. + waiting = False + done = False + def wait(os_read=os.read): + global done, waiting + waiting = True + os_read({r_done}, 1) + done = True + t = threading.Thread(target=wait) + with threading_helper.start_threads([t]): + while not waiting: + pass + os.write({w_ready}, b'\\0') + # Loop to trigger the eval breaker. + while not done: + time.sleep(0.01) + if time.time() > {timeout}: + raise Exception('timed out!') + """) + t = threading.Thread(target=do_work) + with threading_helper.start_threads([t]): + os.read(r_ready, 1) + # Add the pending call and wait for it to finish. + actual = _testinternalcapi.pending_identify(interpid) + # Signal the subinterpreter to stop. + os.write(w_done, b'\0') + + self.assertEqual(actual, int(interpid)) + + with self.subTest('add in main, run in subinterpreter sub-thread'): + r_ready, w_ready = create_pipe() + r_done, w_done= create_pipe() + timeout = time.time() + 30 # seconds + + def do_work(): + _interpreters.run_string(interpid, f"""if True: + waiting = False + done = False + def subthread(): + while not waiting: + pass + os.write({w_ready}, b'\\0') + # Loop to trigger the eval breaker. + while not done: + time.sleep(0.01) + if time.time() > {timeout}: + raise Exception('timed out!') + t = threading.Thread(target=subthread) + with threading_helper.start_threads([t]): + # Wait until this interp has handled the pending call. + waiting = True + os.read({r_done}, 1) + done = True + """) + t = threading.Thread(target=do_work) + with threading_helper.start_threads([t]): + os.read(r_ready, 1) + # Add the pending call and wait for it to finish. + actual = _testinternalcapi.pending_identify(interpid) + # Signal the subinterpreter to stop. + os.write(w_done, b'\0') + + self.assertEqual(actual, int(interpid)) + + with self.subTest('add in subinterpreter, run in main'): + r_ready, w_ready = create_pipe() + r_done, w_done= create_pipe() + r_data, w_data= create_pipe() + timeout = time.time() + 30 # seconds + + def add_job(): + os.read(r_ready, 1) + _interpreters.run_string(interpid, f"""if True: + # Add the pending call and wait for it to finish. + actual = _testinternalcapi.pending_identify({main_interpid}) + # Signal the subinterpreter to stop. + os.write({w_done}, b'\\0') + os.write({w_data}, actual.to_bytes(1, 'little')) + """) + # Wait until this interp has handled the pending call. + waiting = False + done = False + def wait(os_read=os.read): + nonlocal done, waiting + waiting = True + os_read(r_done, 1) + done = True + t1 = threading.Thread(target=add_job) + t2 = threading.Thread(target=wait) + with threading_helper.start_threads([t1, t2]): + while not waiting: + pass + os.write(w_ready, b'\0') + # Loop to trigger the eval breaker. + while not done: + time.sleep(0.01) + if time.time() > timeout: + raise Exception('timed out!') + text = os.read(r_data, 1) + actual = int.from_bytes(text, 'little') + + self.assertEqual(actual, int(main_interpid)) + + with self.subTest('add in subinterpreter, run in sub-thread'): + r_ready, w_ready = create_pipe() + r_done, w_done= create_pipe() + r_data, w_data= create_pipe() + timeout = time.time() + 30 # seconds + + def add_job(): + os.read(r_ready, 1) + _interpreters.run_string(interpid, f"""if True: + # Add the pending call and wait for it to finish. + actual = _testinternalcapi.pending_identify({main_interpid}) + # Signal the subinterpreter to stop. + os.write({w_done}, b'\\0') + os.write({w_data}, actual.to_bytes(1, 'little')) + """) + # Wait until this interp has handled the pending call. + waiting = False + done = False + def wait(os_read=os.read): + nonlocal done, waiting + waiting = True + os_read(r_done, 1) + done = True + def subthread(): + while not waiting: + pass + os.write(w_ready, b'\0') + # Loop to trigger the eval breaker. + while not done: + time.sleep(0.01) + if time.time() > timeout: + raise Exception('timed out!') + t1 = threading.Thread(target=add_job) + t2 = threading.Thread(target=wait) + t3 = threading.Thread(target=subthread) + with threading_helper.start_threads([t1, t2, t3]): + pass + text = os.read(r_data, 1) + actual = int.from_bytes(text, 'little') + + self.assertEqual(actual, int(main_interpid)) + + # XXX We can't use the rest until gh-105716 is fixed. + return + + with self.subTest('add in subinterpreter, run in subinterpreter sub-thread'): + r_ready, w_ready = create_pipe() + r_done, w_done= create_pipe() + r_data, w_data= create_pipe() + timeout = time.time() + 30 # seconds + + def do_work(): + _interpreters.run_string(interpid, f"""if True: + waiting = False + done = False + def subthread(): + while not waiting: + pass + os.write({w_ready}, b'\\0') + # Loop to trigger the eval breaker. + while not done: + time.sleep(0.01) + if time.time() > {timeout}: + raise Exception('timed out!') + t = threading.Thread(target=subthread) + with threading_helper.start_threads([t]): + # Wait until this interp has handled the pending call. + waiting = True + os.read({r_done}, 1) + done = True + """) + t = threading.Thread(target=do_work) + #with threading_helper.start_threads([t]): + t.start() + if True: + os.read(r_ready, 1) + _interpreters.run_string(interpid, f"""if True: + # Add the pending call and wait for it to finish. + actual = _testinternalcapi.pending_identify({interpid}) + # Signal the subinterpreter to stop. + os.write({w_done}, b'\\0') + os.write({w_data}, actual.to_bytes(1, 'little')) + """) + t.join() + text = os.read(r_data, 1) + actual = int.from_bytes(text, 'little') + + self.assertEqual(actual, int(interpid)) + class SubinterpreterTest(unittest.TestCase): @@ -1003,6 +1717,200 @@ class SubinterpreterTest(unittest.TestCase): self.assertEqual(ret, 0) self.assertEqual(pickle.load(f), {'a': '123x', 'b': '123'}) + def test_py_config_isoloated_per_interpreter(self): + # A config change in one interpreter must not leak to out to others. + # + # This test could verify ANY config value, it just happens to have been + # written around the time of int_max_str_digits. Refactoring is okay. + code = """if 1: + import sys, _testinternalcapi + + # Any config value would do, this happens to be the one being + # double checked at the time this test was written. + config = _testinternalcapi.get_config() + config['int_max_str_digits'] = 55555 + _testinternalcapi.set_config(config) + sub_value = _testinternalcapi.get_config()['int_max_str_digits'] + assert sub_value == 55555, sub_value + """ + before_config = _testinternalcapi.get_config() + assert before_config['int_max_str_digits'] != 55555 + self.assertEqual(support.run_in_subinterp(code), 0, + 'subinterp code failure, check stderr.') + after_config = _testinternalcapi.get_config() + self.assertIsNot( + before_config, after_config, + "Expected get_config() to return a new dict on each call") + self.assertEqual(before_config, after_config, + "CAUTION: Tests executed after this may be " + "running under an altered config.") + # try:...finally: calling set_config(before_config) not done + # as that results in sys.argv, sys.path, and sys.warnoptions + # "being modified by test_capi" per test.regrtest. So if this + # test fails, assume that the environment in this process may + # be altered and suspect. + + @unittest.skipUnless(hasattr(os, "pipe"), "requires os.pipe()") + def test_configured_settings(self): + """ + The config with which an interpreter is created corresponds + 1-to-1 with the new interpreter's settings. This test verifies + that they match. + """ + import json + + OBMALLOC = 1<<5 + EXTENSIONS = 1<<8 + THREADS = 1<<10 + DAEMON_THREADS = 1<<11 + FORK = 1<<15 + EXEC = 1<<16 + ALL_FLAGS = (OBMALLOC | FORK | EXEC | THREADS | DAEMON_THREADS + | EXTENSIONS); + + features = [ + 'obmalloc', + 'fork', + 'exec', + 'threads', + 'daemon_threads', + 'extensions', + 'own_gil', + ] + kwlist = [f'allow_{n}' for n in features] + kwlist[0] = 'use_main_obmalloc' + kwlist[-2] = 'check_multi_interp_extensions' + kwlist[-1] = 'own_gil' + + # expected to work + for config, expected in { + (True, True, True, True, True, True, True): + (ALL_FLAGS, True), + (True, False, False, False, False, False, False): + (OBMALLOC, False), + (False, False, False, True, False, True, False): + (THREADS | EXTENSIONS, False), + }.items(): + kwargs = dict(zip(kwlist, config)) + exp_flags, exp_gil = expected + expected = { + 'feature_flags': exp_flags, + 'own_gil': exp_gil, + } + with self.subTest(config): + r, w = os.pipe() + script = textwrap.dedent(f''' + import _testinternalcapi, json, os + settings = _testinternalcapi.get_interp_settings() + with os.fdopen({w}, "w") as stdin: + json.dump(settings, stdin) + ''') + with os.fdopen(r) as stdout: + ret = support.run_in_subinterp_with_config(script, **kwargs) + self.assertEqual(ret, 0) + out = stdout.read() + settings = json.loads(out) + + self.assertEqual(settings, expected) + + # expected to fail + for config in [ + (False, False, False, False, False, False, False), + ]: + kwargs = dict(zip(kwlist, config)) + with self.subTest(config): + script = textwrap.dedent(f''' + import _testinternalcapi + _testinternalcapi.get_interp_settings() + raise NotImplementedError('unreachable') + ''') + with self.assertRaises(RuntimeError): + support.run_in_subinterp_with_config(script, **kwargs) + + @unittest.skipIf(_testsinglephase is None, "test requires _testsinglephase module") + @unittest.skipUnless(hasattr(os, "pipe"), "requires os.pipe()") + def test_overridden_setting_extensions_subinterp_check(self): + """ + PyInterpreterConfig.check_multi_interp_extensions can be overridden + with PyInterpreterState.override_multi_interp_extensions_check. + This verifies that the override works but does not modify + the underlying setting. + """ + import json + + OBMALLOC = 1<<5 + EXTENSIONS = 1<<8 + THREADS = 1<<10 + DAEMON_THREADS = 1<<11 + FORK = 1<<15 + EXEC = 1<<16 + BASE_FLAGS = OBMALLOC | FORK | EXEC | THREADS | DAEMON_THREADS + base_kwargs = { + 'use_main_obmalloc': True, + 'allow_fork': True, + 'allow_exec': True, + 'allow_threads': True, + 'allow_daemon_threads': True, + 'own_gil': False, + } + + def check(enabled, override): + kwargs = dict( + base_kwargs, + check_multi_interp_extensions=enabled, + ) + flags = BASE_FLAGS | EXTENSIONS if enabled else BASE_FLAGS + settings = { + 'feature_flags': flags, + 'own_gil': False, + } + + expected = { + 'requested': override, + 'override__initial': 0, + 'override_after': override, + 'override_restored': 0, + # The override should not affect the config or settings. + 'settings__initial': settings, + 'settings_after': settings, + 'settings_restored': settings, + # These are the most likely values to be wrong. + 'allowed__initial': not enabled, + 'allowed_after': not ((override > 0) if override else enabled), + 'allowed_restored': not enabled, + } + + r, w = os.pipe() + script = textwrap.dedent(f''' + from test.test_capi.check_config import run_singlephase_check + run_singlephase_check({override}, {w}) + ''') + with os.fdopen(r) as stdout: + ret = support.run_in_subinterp_with_config(script, **kwargs) + self.assertEqual(ret, 0) + out = stdout.read() + results = json.loads(out) + + self.assertEqual(results, expected) + + self.maxDiff = None + + # setting: check disabled + with self.subTest('config: check disabled; override: disabled'): + check(False, -1) + with self.subTest('config: check disabled; override: use config'): + check(False, 0) + with self.subTest('config: check disabled; override: enabled'): + check(False, 1) + + # setting: check enabled + with self.subTest('config: check enabled; override: disabled'): + check(True, -1) + with self.subTest('config: check enabled; override: use config'): + check(True, 0) + with self.subTest('config: check enabled; override: enabled'): + check(True, 1) + def test_mutate_exception(self): """ Exceptions saved in global module state get shared between @@ -1049,6 +1957,74 @@ class SubinterpreterTest(unittest.TestCase): self.assertEqual(main_attr_id, subinterp_attr_id) +class BuiltinStaticTypesTests(unittest.TestCase): + + TYPES = [ + object, + type, + int, + str, + dict, + type(None), + bool, + BaseException, + Exception, + Warning, + DeprecationWarning, # Warning subclass + ] + + def test_tp_bases_is_set(self): + # PyTypeObject.tp_bases is documented as public API. + # See https://github.com/python/cpython/issues/105020. + for typeobj in self.TYPES: + with self.subTest(typeobj): + bases = _testcapi.type_get_tp_bases(typeobj) + self.assertIsNot(bases, None) + + def test_tp_mro_is_set(self): + # PyTypeObject.tp_bases is documented as public API. + # See https://github.com/python/cpython/issues/105020. + for typeobj in self.TYPES: + with self.subTest(typeobj): + mro = _testcapi.type_get_tp_mro(typeobj) + self.assertIsNot(mro, None) + + +class TestStaticTypes(unittest.TestCase): + + _has_run = False + + @classmethod + def setUpClass(cls): + # The tests here don't play nice with our approach to refleak + # detection, so we bail out in that case. + if cls._has_run: + raise unittest.SkipTest('these tests do not support re-running') + cls._has_run = True + + @contextlib.contextmanager + def basic_static_type(self, *args): + cls = _testcapi.get_basic_static_type(*args) + yield cls + + def test_pytype_ready_always_sets_tp_type(self): + # The point of this test is to prevent something like + # https://github.com/python/cpython/issues/104614 + # from happening again. + + # First check when tp_base/tp_bases is *not* set before PyType_Ready(). + with self.basic_static_type() as cls: + self.assertIs(cls.__base__, object); + self.assertEqual(cls.__bases__, (object,)); + self.assertIs(type(cls), type(object)); + + # Then check when we *do* set tp_base/tp_bases first. + with self.basic_static_type(object) as cls: + self.assertIs(cls.__base__, object); + self.assertEqual(cls.__bases__, (object,)); + self.assertIs(type(cls), type(object)); + + class TestThreadState(unittest.TestCase): @threading_helper.reap_threads @@ -1077,7 +2053,7 @@ class TestThreadState(unittest.TestCase): @threading_helper.requires_working_threading() def test_gilstate_ensure_no_deadlock(self): # See https://github.com/python/cpython/issues/96071 - code = textwrap.dedent(f""" + code = textwrap.dedent(""" import _testcapi def callback(): @@ -1088,6 +2064,9 @@ class TestThreadState(unittest.TestCase): ret = assert_python_ok('-X', 'tracemalloc', '-c', code) self.assertIn(b'callback called', ret.out) + def test_gilstate_matches_current(self): + _testcapi.test_current_tstate_matches() + class Test_testcapi(unittest.TestCase): locals().update((name, getattr(_testcapi, name)) @@ -1109,124 +2088,6 @@ class Test_testinternalcapi(unittest.TestCase): if name.startswith('test_')) -@support.requires_subprocess() -class PyMemDebugTests(unittest.TestCase): - PYTHONMALLOC = 'debug' - # '0x04c06e0' or '04C06E0' - PTR_REGEX = r'(?:0x)?[0-9a-fA-F]+' - - def check(self, code): - with support.SuppressCrashReport(): - out = assert_python_failure( - '-c', code, - PYTHONMALLOC=self.PYTHONMALLOC, - # FreeBSD: instruct jemalloc to not fill freed() memory - # with junk byte 0x5a, see JEMALLOC(3) - MALLOC_CONF="junk:false", - ) - stderr = out.err - return stderr.decode('ascii', 'replace') - - def test_buffer_overflow(self): - out = self.check('import _testcapi; _testcapi.pymem_buffer_overflow()') - regex = (r"Debug memory block at address p={ptr}: API 'm'\n" - r" 16 bytes originally requested\n" - r" The [0-9] pad bytes at p-[0-9] are FORBIDDENBYTE, as expected.\n" - r" The [0-9] pad bytes at tail={ptr} are not all FORBIDDENBYTE \(0x[0-9a-f]{{2}}\):\n" - r" at tail\+0: 0x78 \*\*\* OUCH\n" - r" at tail\+1: 0xfd\n" - r" at tail\+2: 0xfd\n" - r" .*\n" - r"( The block was made by call #[0-9]+ to debug malloc/realloc.\n)?" - r" Data at p: cd cd cd .*\n" - r"\n" - r"Enable tracemalloc to get the memory block allocation traceback\n" - r"\n" - r"Fatal Python error: _PyMem_DebugRawFree: bad trailing pad byte") - regex = regex.format(ptr=self.PTR_REGEX) - regex = re.compile(regex, flags=re.DOTALL) - self.assertRegex(out, regex) - - def test_api_misuse(self): - out = self.check('import _testcapi; _testcapi.pymem_api_misuse()') - regex = (r"Debug memory block at address p={ptr}: API 'm'\n" - r" 16 bytes originally requested\n" - r" The [0-9] pad bytes at p-[0-9] are FORBIDDENBYTE, as expected.\n" - r" The [0-9] pad bytes at tail={ptr} are FORBIDDENBYTE, as expected.\n" - r"( The block was made by call #[0-9]+ to debug malloc/realloc.\n)?" - r" Data at p: cd cd cd .*\n" - r"\n" - r"Enable tracemalloc to get the memory block allocation traceback\n" - r"\n" - r"Fatal Python error: _PyMem_DebugRawFree: bad ID: Allocated using API 'm', verified using API 'r'\n") - regex = regex.format(ptr=self.PTR_REGEX) - self.assertRegex(out, regex) - - def check_malloc_without_gil(self, code): - out = self.check(code) - expected = ('Fatal Python error: _PyMem_DebugMalloc: ' - 'Python memory allocator called without holding the GIL') - self.assertIn(expected, out) - - def test_pymem_malloc_without_gil(self): - # Debug hooks must raise an error if PyMem_Malloc() is called - # without holding the GIL - code = 'import _testcapi; _testcapi.pymem_malloc_without_gil()' - self.check_malloc_without_gil(code) - - def test_pyobject_malloc_without_gil(self): - # Debug hooks must raise an error if PyObject_Malloc() is called - # without holding the GIL - code = 'import _testcapi; _testcapi.pyobject_malloc_without_gil()' - self.check_malloc_without_gil(code) - - def check_pyobject_is_freed(self, func_name): - code = textwrap.dedent(f''' - import gc, os, sys, _testcapi - # Disable the GC to avoid crash on GC collection - gc.disable() - try: - _testcapi.{func_name}() - # Exit immediately to avoid a crash while deallocating - # the invalid object - os._exit(0) - except _testcapi.error: - os._exit(1) - ''') - assert_python_ok( - '-c', code, - PYTHONMALLOC=self.PYTHONMALLOC, - MALLOC_CONF="junk:false", - ) - - def test_pyobject_null_is_freed(self): - self.check_pyobject_is_freed('check_pyobject_null_is_freed') - - def test_pyobject_uninitialized_is_freed(self): - self.check_pyobject_is_freed('check_pyobject_uninitialized_is_freed') - - def test_pyobject_forbidden_bytes_is_freed(self): - self.check_pyobject_is_freed('check_pyobject_forbidden_bytes_is_freed') - - def test_pyobject_freed_is_freed(self): - self.check_pyobject_is_freed('check_pyobject_freed_is_freed') - - -class PyMemMallocDebugTests(PyMemDebugTests): - PYTHONMALLOC = 'malloc_debug' - - -@unittest.skipUnless(support.with_pymalloc(), 'need pymalloc') -class PyMemPymallocDebugTests(PyMemDebugTests): - PYTHONMALLOC = 'pymalloc_debug' - - -@unittest.skipUnless(Py_DEBUG, 'need Py_DEBUG') -class PyMemDefaultTests(PyMemDebugTests): - # test default allocator of Python compiled in debug mode - PYTHONMALLOC = '' - - @unittest.skipIf(_testmultiphase is None, "test requires _testmultiphase module") class Test_ModuleStateAccess(unittest.TestCase): """Test access to module start (PEP 573)""" @@ -1315,63 +2176,108 @@ class Test_ModuleStateAccess(unittest.TestCase): self.assertIs(Subclass().get_defining_module(), self.module) -class Test_FrameAPI(unittest.TestCase): +class TestInternalFrameApi(unittest.TestCase): - def getframe(self): + @staticmethod + def func(): return sys._getframe() - def getgenframe(self): - yield sys._getframe() - - def test_frame_getters(self): - frame = self.getframe() - self.assertEqual(frame.f_locals, _testcapi.frame_getlocals(frame)) - self.assertIs(frame.f_globals, _testcapi.frame_getglobals(frame)) - self.assertIs(frame.f_builtins, _testcapi.frame_getbuiltins(frame)) - self.assertEqual(frame.f_lasti, _testcapi.frame_getlasti(frame)) - - def test_frame_get_generator(self): - gen = self.getgenframe() - frame = next(gen) - self.assertIs(gen, _testcapi.frame_getgenerator(frame)) - - def test_frame_fback_api(self): - """Test that accessing `f_back` does not cause a segmentation fault on - a frame created with `PyFrame_New` (GH-99110).""" - def dummy(): - pass + def test_code(self): + frame = self.func() + code = _testinternalcapi.iframe_getcode(frame) + self.assertIs(code, self.func.__code__) - frame = _testcapi.frame_new(dummy.__code__, globals(), locals()) - # The following line should not cause a segmentation fault. - self.assertIsNone(frame.f_back) + def test_lasti(self): + frame = self.func() + lasti = _testinternalcapi.iframe_getlasti(frame) + self.assertGreater(lasti, 0) + self.assertLess(lasti, len(self.func.__code__.co_code)) + + def test_line(self): + frame = self.func() + line = _testinternalcapi.iframe_getline(frame) + firstline = self.func.__code__.co_firstlineno + self.assertEqual(line, firstline + 2) SUFFICIENT_TO_DEOPT_AND_SPECIALIZE = 100 class Test_Pep523API(unittest.TestCase): - def do_test(self, func): - calls = [] + def do_test(self, func, names): + actual_calls = [] start = SUFFICIENT_TO_DEOPT_AND_SPECIALIZE count = start + SUFFICIENT_TO_DEOPT_AND_SPECIALIZE - for i in range(count): - if i == start: - _testinternalcapi.set_eval_frame_record(calls) - func() - _testinternalcapi.set_eval_frame_default() - self.assertEqual(len(calls), SUFFICIENT_TO_DEOPT_AND_SPECIALIZE) - for name in calls: - self.assertEqual(name, func.__name__) - - def test_pep523_with_specialization_simple(self): - def func1(): - pass - self.do_test(func1) + try: + for i in range(count): + if i == start: + _testinternalcapi.set_eval_frame_record(actual_calls) + func() + finally: + _testinternalcapi.set_eval_frame_default() + expected_calls = names * SUFFICIENT_TO_DEOPT_AND_SPECIALIZE + self.assertEqual(len(expected_calls), len(actual_calls)) + for expected, actual in zip(expected_calls, actual_calls, strict=True): + self.assertEqual(expected, actual) + + def test_inlined_binary_subscr(self): + class C: + def __getitem__(self, other): + return None + def func(): + C()[42] + names = ["func", "__getitem__"] + self.do_test(func, names) - def test_pep523_with_specialization_with_default(self): - def func2(x=None): + def test_inlined_call(self): + def inner(x=42): + pass + def func(): + inner() + inner(42) + names = ["func", "inner", "inner"] + self.do_test(func, names) + + def test_inlined_call_function_ex(self): + def inner(x): pass - self.do_test(func2) + def func(): + inner(*[42]) + names = ["func", "inner"] + self.do_test(func, names) + + def test_inlined_for_iter(self): + def gen(): + yield 42 + def func(): + for _ in gen(): + pass + names = ["func", "gen", "gen", "gen"] + self.do_test(func, names) + + def test_inlined_load_attr(self): + class C: + @property + def a(self): + return 42 + class D: + def __getattribute__(self, name): + return 42 + def func(): + C().a + D().a + names = ["func", "a", "__getattribute__"] + self.do_test(func, names) + + def test_inlined_send(self): + def inner(): + yield 42 + def outer(): + yield from inner() + def func(): + list(outer()) + names = ["func", "outer", "outer", "inner", "inner", "outer", "inner"] + self.do_test(func, names) if __name__ == "__main__": diff --git a/Lib/test/test_capi/test_structmembers.py b/Lib/test/test_capi/test_structmembers.py index 07d2f623..2cf46b20 100644 --- a/Lib/test/test_capi/test_structmembers.py +++ b/Lib/test/test_capi/test_structmembers.py @@ -4,32 +4,42 @@ from test.support import warnings_helper # Skip this test if the _testcapi module isn't available. import_helper.import_module('_testcapi') -from _testcapi import _test_structmembersType, \ - CHAR_MAX, CHAR_MIN, UCHAR_MAX, \ - SHRT_MAX, SHRT_MIN, USHRT_MAX, \ - INT_MAX, INT_MIN, UINT_MAX, \ - LONG_MAX, LONG_MIN, ULONG_MAX, \ - LLONG_MAX, LLONG_MIN, ULLONG_MAX, \ - PY_SSIZE_T_MAX, PY_SSIZE_T_MIN - -ts=_test_structmembersType(False, # T_BOOL - 1, # T_BYTE - 2, # T_UBYTE - 3, # T_SHORT - 4, # T_USHORT - 5, # T_INT - 6, # T_UINT - 7, # T_LONG - 8, # T_ULONG - 23, # T_PYSSIZET - 9.99999,# T_FLOAT - 10.1010101010, # T_DOUBLE - "hi" # T_STRING_INPLACE - ) - -class ReadWriteTests(unittest.TestCase): +from _testcapi import (_test_structmembersType_OldAPI, + _test_structmembersType_NewAPI, + CHAR_MAX, CHAR_MIN, UCHAR_MAX, + SHRT_MAX, SHRT_MIN, USHRT_MAX, + INT_MAX, INT_MIN, UINT_MAX, + LONG_MAX, LONG_MIN, ULONG_MAX, + LLONG_MAX, LLONG_MIN, ULLONG_MAX, + PY_SSIZE_T_MAX, PY_SSIZE_T_MIN, + ) + +# There are two classes: one using <structmember.h> and another using +# `Py_`-prefixed API. They should behave the same in Python + +def _make_test_object(cls): + return cls(False, # T_BOOL + 1, # T_BYTE + 2, # T_UBYTE + 3, # T_SHORT + 4, # T_USHORT + 5, # T_INT + 6, # T_UINT + 7, # T_LONG + 8, # T_ULONG + 23, # T_PYSSIZET + 9.99999,# T_FLOAT + 10.1010101010, # T_DOUBLE + "hi", # T_STRING_INPLACE + ) + + +class ReadWriteTests: + def setUp(self): + self.ts = _make_test_object(self.cls) def test_bool(self): + ts = self.ts ts.T_BOOL = True self.assertEqual(ts.T_BOOL, True) ts.T_BOOL = False @@ -37,6 +47,7 @@ class ReadWriteTests(unittest.TestCase): self.assertRaises(TypeError, setattr, ts, 'T_BOOL', 1) def test_byte(self): + ts = self.ts ts.T_BYTE = CHAR_MAX self.assertEqual(ts.T_BYTE, CHAR_MAX) ts.T_BYTE = CHAR_MIN @@ -45,6 +56,7 @@ class ReadWriteTests(unittest.TestCase): self.assertEqual(ts.T_UBYTE, UCHAR_MAX) def test_short(self): + ts = self.ts ts.T_SHORT = SHRT_MAX self.assertEqual(ts.T_SHORT, SHRT_MAX) ts.T_SHORT = SHRT_MIN @@ -53,6 +65,7 @@ class ReadWriteTests(unittest.TestCase): self.assertEqual(ts.T_USHORT, USHRT_MAX) def test_int(self): + ts = self.ts ts.T_INT = INT_MAX self.assertEqual(ts.T_INT, INT_MAX) ts.T_INT = INT_MIN @@ -61,6 +74,7 @@ class ReadWriteTests(unittest.TestCase): self.assertEqual(ts.T_UINT, UINT_MAX) def test_long(self): + ts = self.ts ts.T_LONG = LONG_MAX self.assertEqual(ts.T_LONG, LONG_MAX) ts.T_LONG = LONG_MIN @@ -69,13 +83,17 @@ class ReadWriteTests(unittest.TestCase): self.assertEqual(ts.T_ULONG, ULONG_MAX) def test_py_ssize_t(self): + ts = self.ts ts.T_PYSSIZET = PY_SSIZE_T_MAX self.assertEqual(ts.T_PYSSIZET, PY_SSIZE_T_MAX) ts.T_PYSSIZET = PY_SSIZE_T_MIN self.assertEqual(ts.T_PYSSIZET, PY_SSIZE_T_MIN) - @unittest.skipUnless(hasattr(ts, "T_LONGLONG"), "long long not present") def test_longlong(self): + ts = self.ts + if not hasattr(ts, "T_LONGLONG"): + self.skipTest("long long not present") + ts.T_LONGLONG = LLONG_MAX self.assertEqual(ts.T_LONGLONG, LLONG_MAX) ts.T_LONGLONG = LLONG_MIN @@ -91,6 +109,7 @@ class ReadWriteTests(unittest.TestCase): self.assertEqual(ts.T_ULONGLONG, 4) def test_bad_assignments(self): + ts = self.ts integer_attributes = [ 'T_BOOL', 'T_BYTE', 'T_UBYTE', @@ -109,37 +128,57 @@ class ReadWriteTests(unittest.TestCase): self.assertRaises(TypeError, setattr, ts, attr, nonint) def test_inplace_string(self): + ts = self.ts self.assertEqual(ts.T_STRING_INPLACE, "hi") self.assertRaises(TypeError, setattr, ts, "T_STRING_INPLACE", "s") self.assertRaises(TypeError, delattr, ts, "T_STRING_INPLACE") +class ReadWriteTests_OldAPI(ReadWriteTests, unittest.TestCase): + cls = _test_structmembersType_OldAPI + +class ReadWriteTests_NewAPI(ReadWriteTests, unittest.TestCase): + cls = _test_structmembersType_NewAPI -class TestWarnings(unittest.TestCase): +class TestWarnings: + def setUp(self): + self.ts = _make_test_object(self.cls) def test_byte_max(self): + ts = self.ts with warnings_helper.check_warnings(('', RuntimeWarning)): ts.T_BYTE = CHAR_MAX+1 def test_byte_min(self): + ts = self.ts with warnings_helper.check_warnings(('', RuntimeWarning)): ts.T_BYTE = CHAR_MIN-1 def test_ubyte_max(self): + ts = self.ts with warnings_helper.check_warnings(('', RuntimeWarning)): ts.T_UBYTE = UCHAR_MAX+1 def test_short_max(self): + ts = self.ts with warnings_helper.check_warnings(('', RuntimeWarning)): ts.T_SHORT = SHRT_MAX+1 def test_short_min(self): + ts = self.ts with warnings_helper.check_warnings(('', RuntimeWarning)): ts.T_SHORT = SHRT_MIN-1 def test_ushort_max(self): + ts = self.ts with warnings_helper.check_warnings(('', RuntimeWarning)): ts.T_USHORT = USHRT_MAX+1 +class TestWarnings_OldAPI(TestWarnings, unittest.TestCase): + cls = _test_structmembersType_OldAPI + +class TestWarnings_NewAPI(TestWarnings, unittest.TestCase): + cls = _test_structmembersType_NewAPI + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_capi/test_unicode.py b/Lib/test/test_capi/test_unicode.py index 77a180a3..9c766206 100644 --- a/Lib/test/test_capi/test_unicode.py +++ b/Lib/test/test_capi/test_unicode.py @@ -9,16 +9,327 @@ except ImportError: _testcapi = None +NULL = None + +class Str(str): + pass + + class CAPITest(unittest.TestCase): - # Test PyUnicode_FromFormat() + @support.cpython_only + @unittest.skipIf(_testcapi is None, 'need _testcapi module') + def test_new(self): + """Test PyUnicode_New()""" + from _testcapi import unicode_new as new + + for maxchar in 0, 0x61, 0xa1, 0x4f60, 0x1f600, 0x10ffff: + self.assertEqual(new(0, maxchar), '') + self.assertEqual(new(5, maxchar), chr(maxchar)*5) + self.assertEqual(new(0, 0x110000), '') + self.assertRaises(SystemError, new, 5, 0x110000) + self.assertRaises(SystemError, new, -1, 0) + + @support.cpython_only + @unittest.skipIf(_testcapi is None, 'need _testcapi module') + def test_fill(self): + """Test PyUnicode_Fill()""" + from _testcapi import unicode_fill as fill + + strings = [ + # all strings have exactly 5 characters + 'abcde', '\xa1\xa2\xa3\xa4\xa5', + '\u4f60\u597d\u4e16\u754c\uff01', + '\U0001f600\U0001f601\U0001f602\U0001f603\U0001f604' + ] + chars = [0x78, 0xa9, 0x20ac, 0x1f638] + + for idx, fill_char in enumerate(chars): + # wide -> narrow: exceed maxchar limitation + for to in strings[:idx]: + self.assertRaises(ValueError, fill, to, 0, 0, fill_char) + for to in strings[idx:]: + for start in range(7): + for length in range(-1, 7 - start): + filled = max(min(length, 5 - start), 0) + if filled == 5 and to != strings[idx]: + # narrow -> wide + # Tests omitted since this creates invalid strings. + continue + expected = to[:start] + chr(fill_char) * filled + to[start + filled:] + self.assertEqual(fill(to, start, length, fill_char), + (expected, filled)) + + s = strings[0] + self.assertRaises(IndexError, fill, s, -1, 0, 0x78) + self.assertRaises(ValueError, fill, s, 0, 0, 0x110000) + self.assertRaises(SystemError, fill, b'abc', 0, 0, 0x78) + self.assertRaises(SystemError, fill, [], 0, 0, 0x78) + # CRASHES fill(s, 0, NULL, 0, 0) + # CRASHES fill(NULL, 0, 0, 0x78) + # TODO: Test PyUnicode_Fill() with non-modifiable unicode. + + @support.cpython_only + @unittest.skipIf(_testcapi is None, 'need _testcapi module') + def test_writechar(self): + """Test PyUnicode_ReadChar()""" + from _testcapi import unicode_writechar as writechar + + strings = [ + # one string for every kind + 'abc', '\xa1\xa2\xa3', '\u4f60\u597d\u4e16', + '\U0001f600\U0001f601\U0001f602' + ] + # one character for every kind + out of range code + chars = [0x78, 0xa9, 0x20ac, 0x1f638, 0x110000] + for i, s in enumerate(strings): + for j, c in enumerate(chars): + if j <= i: + self.assertEqual(writechar(s, 1, c), + (s[:1] + chr(c) + s[2:], 0)) + else: + self.assertRaises(ValueError, writechar, s, 1, c) + + self.assertRaises(IndexError, writechar, 'abc', 3, 0x78) + self.assertRaises(IndexError, writechar, 'abc', -1, 0x78) + self.assertRaises(TypeError, writechar, b'abc', 0, 0x78) + self.assertRaises(TypeError, writechar, [], 0, 0x78) + # CRASHES writechar(NULL, 0, 0x78) + # TODO: Test PyUnicode_CopyCharacters() with non-modifiable and legacy + # unicode. + + @support.cpython_only + @unittest.skipIf(_testcapi is None, 'need _testcapi module') + def test_resize(self): + """Test PyUnicode_Resize()""" + from _testcapi import unicode_resize as resize + + strings = [ + # all strings have exactly 3 characters + 'abc', '\xa1\xa2\xa3', '\u4f60\u597d\u4e16', + '\U0001f600\U0001f601\U0001f602' + ] + for s in strings: + self.assertEqual(resize(s, 3), (s, 0)) + self.assertEqual(resize(s, 2), (s[:2], 0)) + self.assertEqual(resize(s, 4), (s + '\0', 0)) + self.assertEqual(resize(s, 0), ('', 0)) + self.assertRaises(SystemError, resize, b'abc', 0) + self.assertRaises(SystemError, resize, [], 0) + self.assertRaises(SystemError, resize, NULL, 0) + # TODO: Test PyUnicode_Resize() with non-modifiable and legacy unicode + # and with NULL as the address. + + @support.cpython_only + @unittest.skipIf(_testcapi is None, 'need _testcapi module') + def test_append(self): + """Test PyUnicode_Append()""" + from _testcapi import unicode_append as append + + strings = [ + 'abc', '\xa1\xa2\xa3', '\u4f60\u597d\u4e16', + '\U0001f600\U0001f601\U0001f602' + ] + for left in strings: + left = left[::-1] + for right in strings: + expected = left + right + self.assertEqual(append(left, right), expected) + + self.assertRaises(SystemError, append, 'abc', b'abc') + self.assertRaises(SystemError, append, b'abc', 'abc') + self.assertRaises(SystemError, append, b'abc', b'abc') + self.assertRaises(SystemError, append, 'abc', []) + self.assertRaises(SystemError, append, [], 'abc') + self.assertRaises(SystemError, append, [], []) + self.assertRaises(SystemError, append, NULL, 'abc') + self.assertRaises(SystemError, append, 'abc', NULL) + # TODO: Test PyUnicode_Append() with modifiable unicode + # and with NULL as the address. + # TODO: Check reference counts. + + @support.cpython_only + @unittest.skipIf(_testcapi is None, 'need _testcapi module') + def test_appendanddel(self): + """Test PyUnicode_AppendAndDel()""" + from _testcapi import unicode_appendanddel as appendanddel + + strings = [ + 'abc', '\xa1\xa2\xa3', '\u4f60\u597d\u4e16', + '\U0001f600\U0001f601\U0001f602' + ] + for left in strings: + left = left[::-1] + for right in strings: + self.assertEqual(appendanddel(left, right), left + right) + + self.assertRaises(SystemError, appendanddel, 'abc', b'abc') + self.assertRaises(SystemError, appendanddel, b'abc', 'abc') + self.assertRaises(SystemError, appendanddel, b'abc', b'abc') + self.assertRaises(SystemError, appendanddel, 'abc', []) + self.assertRaises(SystemError, appendanddel, [], 'abc') + self.assertRaises(SystemError, appendanddel, [], []) + self.assertRaises(SystemError, appendanddel, NULL, 'abc') + self.assertRaises(SystemError, appendanddel, 'abc', NULL) + # TODO: Test PyUnicode_AppendAndDel() with modifiable unicode + # and with NULL as the address. + # TODO: Check reference counts. + + @support.cpython_only + @unittest.skipIf(_testcapi is None, 'need _testcapi module') + def test_fromstringandsize(self): + """Test PyUnicode_FromStringAndSize()""" + from _testcapi import unicode_fromstringandsize as fromstringandsize + + self.assertEqual(fromstringandsize(b'abc'), 'abc') + self.assertEqual(fromstringandsize(b'abc', 2), 'ab') + self.assertEqual(fromstringandsize(b'abc\0def'), 'abc\0def') + self.assertEqual(fromstringandsize(b'\xc2\xa1\xc2\xa2'), '\xa1\xa2') + self.assertEqual(fromstringandsize(b'\xe4\xbd\xa0'), '\u4f60') + self.assertEqual(fromstringandsize(b'\xf0\x9f\x98\x80'), '\U0001f600') + self.assertRaises(UnicodeDecodeError, fromstringandsize, b'\xc2\xa1', 1) + self.assertRaises(UnicodeDecodeError, fromstringandsize, b'\xa1', 1) + self.assertEqual(fromstringandsize(b'', 0), '') + self.assertEqual(fromstringandsize(NULL, 0), '') + + self.assertRaises(SystemError, fromstringandsize, b'abc', -1) + # TODO: Test PyUnicode_FromStringAndSize(NULL, size) for size != 0 + + @support.cpython_only + @unittest.skipIf(_testcapi is None, 'need _testcapi module') + def test_fromstring(self): + """Test PyUnicode_FromString()""" + from _testcapi import unicode_fromstring as fromstring + + self.assertEqual(fromstring(b'abc'), 'abc') + self.assertEqual(fromstring(b'\xc2\xa1\xc2\xa2'), '\xa1\xa2') + self.assertEqual(fromstring(b'\xe4\xbd\xa0'), '\u4f60') + self.assertEqual(fromstring(b'\xf0\x9f\x98\x80'), '\U0001f600') + self.assertRaises(UnicodeDecodeError, fromstring, b'\xc2') + self.assertRaises(UnicodeDecodeError, fromstring, b'\xa1') + self.assertEqual(fromstring(b''), '') + + # CRASHES fromstring(NULL) + + @support.cpython_only + @unittest.skipIf(_testcapi is None, 'need _testcapi module') + def test_fromkindanddata(self): + """Test PyUnicode_FromKindAndData()""" + from _testcapi import unicode_fromkindanddata as fromkindanddata + + strings = [ + 'abcde', '\xa1\xa2\xa3\xa4\xa5', + '\u4f60\u597d\u4e16\u754c\uff01', + '\U0001f600\U0001f601\U0001f602\U0001f603\U0001f604' + ] + enc1 = 'latin1' + for s in strings[:2]: + self.assertEqual(fromkindanddata(1, s.encode(enc1)), s) + enc2 = 'utf-16le' if sys.byteorder == 'little' else 'utf-16be' + for s in strings[:3]: + self.assertEqual(fromkindanddata(2, s.encode(enc2)), s) + enc4 = 'utf-32le' if sys.byteorder == 'little' else 'utf-32be' + for s in strings: + self.assertEqual(fromkindanddata(4, s.encode(enc4)), s) + self.assertEqual(fromkindanddata(2, '\U0001f600'.encode(enc2)), + '\ud83d\ude00') + for kind in 1, 2, 4: + self.assertEqual(fromkindanddata(kind, b''), '') + self.assertEqual(fromkindanddata(kind, b'\0'*kind), '\0') + self.assertEqual(fromkindanddata(kind, NULL, 0), '') + + for kind in -1, 0, 3, 5, 8: + self.assertRaises(SystemError, fromkindanddata, kind, b'') + self.assertRaises(ValueError, fromkindanddata, 1, b'abc', -1) + self.assertRaises(ValueError, fromkindanddata, 1, NULL, -1) + # CRASHES fromkindanddata(1, NULL, 1) + # CRASHES fromkindanddata(4, b'\xff\xff\xff\xff') + + @support.cpython_only + @unittest.skipIf(_testcapi is None, 'need _testcapi module') + def test_substring(self): + """Test PyUnicode_Substring()""" + from _testcapi import unicode_substring as substring + + strings = [ + 'ab', 'ab\xa1\xa2', + 'ab\xa1\xa2\u4f60\u597d', + 'ab\xa1\xa2\u4f60\u597d\U0001f600\U0001f601' + ] + for s in strings: + for start in range(0, len(s) + 2): + for end in range(max(start-1, 0), len(s) + 2): + self.assertEqual(substring(s, start, end), s[start:end]) + + self.assertRaises(IndexError, substring, 'abc', -1, 0) + self.assertRaises(IndexError, substring, 'abc', 0, -1) + # CRASHES substring(b'abc', 0, 0) + # CRASHES substring([], 0, 0) + # CRASHES substring(NULL, 0, 0) + + @support.cpython_only + @unittest.skipIf(_testcapi is None, 'need _testcapi module') + def test_getlength(self): + """Test PyUnicode_GetLength()""" + from _testcapi import unicode_getlength as getlength + + for s in ['abc', '\xa1\xa2', '\u4f60\u597d', 'a\U0001f600', + 'a\ud800b\udfffc', '\ud834\udd1e']: + self.assertEqual(getlength(s), len(s)) + + self.assertRaises(TypeError, getlength, b'abc') + self.assertRaises(TypeError, getlength, []) + # CRASHES getlength(NULL) + + @support.cpython_only + @unittest.skipIf(_testcapi is None, 'need _testcapi module') + def test_readchar(self): + """Test PyUnicode_ReadChar()""" + from _testcapi import unicode_readchar as readchar + + for s in ['abc', '\xa1\xa2', '\u4f60\u597d', 'a\U0001f600', + 'a\ud800b\udfffc', '\ud834\udd1e']: + for i, c in enumerate(s): + self.assertEqual(readchar(s, i), ord(c)) + self.assertRaises(IndexError, readchar, s, len(s)) + self.assertRaises(IndexError, readchar, s, -1) + + self.assertRaises(TypeError, readchar, b'abc', 0) + self.assertRaises(TypeError, readchar, [], 0) + # CRASHES readchar(NULL, 0) + + @support.cpython_only + @unittest.skipIf(_testcapi is None, 'need _testcapi module') + def test_fromobject(self): + """Test PyUnicode_FromObject()""" + from _testcapi import unicode_fromobject as fromobject + + for s in ['abc', '\xa1\xa2', '\u4f60\u597d', 'a\U0001f600', + 'a\ud800b\udfffc', '\ud834\udd1e']: + self.assertEqual(fromobject(s), s) + o = Str(s) + s2 = fromobject(o) + self.assertEqual(s2, s) + self.assertIs(type(s2), str) + self.assertIsNot(s2, s) + + self.assertRaises(TypeError, fromobject, b'abc') + self.assertRaises(TypeError, fromobject, []) + # CRASHES fromobject(NULL) + def test_from_format(self): + """Test PyUnicode_FromFormat()""" + # Length modifiers "j" and "t" are not tested here because ctypes does + # not expose types for intmax_t and ptrdiff_t. + # _testcapi.test_string_from_format() has a wider coverage of all + # formats. import_helper.import_module('ctypes') from ctypes import ( c_char_p, pythonapi, py_object, sizeof, c_int, c_long, c_longlong, c_ssize_t, - c_uint, c_ulong, c_ulonglong, c_size_t, c_void_p) + c_uint, c_ulong, c_ulonglong, c_size_t, c_void_p, + sizeof, c_wchar, c_wchar_p) name = "PyUnicode_FromFormat" _PyUnicode_FromFormat = getattr(pythonapi, name) _PyUnicode_FromFormat.argtypes = (c_char_p,) @@ -57,8 +368,6 @@ class CAPITest(unittest.TestCase): b'%c%c', c_int(0x10000), c_int(0x100000)) # test "%" - check_format('%', - b'%') check_format('%', b'%%') check_format('%s', @@ -145,37 +454,28 @@ class CAPITest(unittest.TestCase): check_format("repr= 12", b'repr=%5.2V', None, b'123') - # test integer formats (%i, %d, %u) + # test integer formats (%i, %d, %u, %o, %x, %X) check_format('010', b'%03i', c_int(10)) check_format('0010', b'%0.4i', c_int(10)) - check_format('-123', - b'%i', c_int(-123)) - check_format('-123', - b'%li', c_long(-123)) - check_format('-123', - b'%lli', c_longlong(-123)) - check_format('-123', - b'%zi', c_ssize_t(-123)) - - check_format('-123', - b'%d', c_int(-123)) - check_format('-123', - b'%ld', c_long(-123)) - check_format('-123', - b'%lld', c_longlong(-123)) - check_format('-123', - b'%zd', c_ssize_t(-123)) - - check_format('123', - b'%u', c_uint(123)) - check_format('123', - b'%lu', c_ulong(123)) - check_format('123', - b'%llu', c_ulonglong(123)) - check_format('123', - b'%zu', c_size_t(123)) + for conv, signed, value, expected in [ + (b'i', True, -123, '-123'), + (b'd', True, -123, '-123'), + (b'u', False, 123, '123'), + (b'o', False, 0o123, '123'), + (b'x', False, 0xabc, 'abc'), + (b'X', False, 0xabc, 'ABC'), + ]: + for mod, ctype in [ + (b'', c_int if signed else c_uint), + (b'l', c_long if signed else c_ulong), + (b'll', c_longlong if signed else c_ulonglong), + (b'z', c_ssize_t if signed else c_size_t), + ]: + with self.subTest(format=b'%' + mod + conv): + check_format(expected, + b'%' + mod + conv, ctype(value)) # test long output min_longlong = -(2 ** (8 * sizeof(c_longlong) - 1)) @@ -190,40 +490,144 @@ class CAPITest(unittest.TestCase): PyUnicode_FromFormat(b'%p', c_void_p(-1)) # test padding (width and/or precision) - check_format('123'.rjust(10, '0'), - b'%010i', c_int(123)) - check_format('123'.rjust(100), - b'%100i', c_int(123)) - check_format('123'.rjust(100, '0'), - b'%.100i', c_int(123)) - check_format('123'.rjust(80, '0').rjust(100), - b'%100.80i', c_int(123)) - - check_format('123'.rjust(10, '0'), - b'%010u', c_uint(123)) - check_format('123'.rjust(100), - b'%100u', c_uint(123)) - check_format('123'.rjust(100, '0'), - b'%.100u', c_uint(123)) - check_format('123'.rjust(80, '0').rjust(100), - b'%100.80u', c_uint(123)) - - check_format('123'.rjust(10, '0'), - b'%010x', c_int(0x123)) - check_format('123'.rjust(100), - b'%100x', c_int(0x123)) - check_format('123'.rjust(100, '0'), - b'%.100x', c_int(0x123)) - check_format('123'.rjust(80, '0').rjust(100), - b'%100.80x', c_int(0x123)) + check_format('123', b'%2i', c_int(123)) + check_format(' 123', b'%10i', c_int(123)) + check_format('0000000123', b'%010i', c_int(123)) + check_format('123 ', b'%-10i', c_int(123)) + check_format('123 ', b'%-010i', c_int(123)) + check_format('123', b'%.2i', c_int(123)) + check_format('0000123', b'%.7i', c_int(123)) + check_format(' 123', b'%10.2i', c_int(123)) + check_format(' 0000123', b'%10.7i', c_int(123)) + check_format('0000000123', b'%010.7i', c_int(123)) + check_format('0000123 ', b'%-10.7i', c_int(123)) + check_format('0000123 ', b'%-010.7i', c_int(123)) + + check_format('-123', b'%2i', c_int(-123)) + check_format(' -123', b'%10i', c_int(-123)) + check_format('-000000123', b'%010i', c_int(-123)) + check_format('-123 ', b'%-10i', c_int(-123)) + check_format('-123 ', b'%-010i', c_int(-123)) + check_format('-123', b'%.2i', c_int(-123)) + check_format('-0000123', b'%.7i', c_int(-123)) + check_format(' -123', b'%10.2i', c_int(-123)) + check_format(' -0000123', b'%10.7i', c_int(-123)) + check_format('-000000123', b'%010.7i', c_int(-123)) + check_format('-0000123 ', b'%-10.7i', c_int(-123)) + check_format('-0000123 ', b'%-010.7i', c_int(-123)) + + check_format('123', b'%2u', c_uint(123)) + check_format(' 123', b'%10u', c_uint(123)) + check_format('0000000123', b'%010u', c_uint(123)) + check_format('123 ', b'%-10u', c_uint(123)) + check_format('123 ', b'%-010u', c_uint(123)) + check_format('123', b'%.2u', c_uint(123)) + check_format('0000123', b'%.7u', c_uint(123)) + check_format(' 123', b'%10.2u', c_uint(123)) + check_format(' 0000123', b'%10.7u', c_uint(123)) + check_format('0000000123', b'%010.7u', c_uint(123)) + check_format('0000123 ', b'%-10.7u', c_uint(123)) + check_format('0000123 ', b'%-010.7u', c_uint(123)) + + check_format('123', b'%2o', c_uint(0o123)) + check_format(' 123', b'%10o', c_uint(0o123)) + check_format('0000000123', b'%010o', c_uint(0o123)) + check_format('123 ', b'%-10o', c_uint(0o123)) + check_format('123 ', b'%-010o', c_uint(0o123)) + check_format('123', b'%.2o', c_uint(0o123)) + check_format('0000123', b'%.7o', c_uint(0o123)) + check_format(' 123', b'%10.2o', c_uint(0o123)) + check_format(' 0000123', b'%10.7o', c_uint(0o123)) + check_format('0000000123', b'%010.7o', c_uint(0o123)) + check_format('0000123 ', b'%-10.7o', c_uint(0o123)) + check_format('0000123 ', b'%-010.7o', c_uint(0o123)) + + check_format('abc', b'%2x', c_uint(0xabc)) + check_format(' abc', b'%10x', c_uint(0xabc)) + check_format('0000000abc', b'%010x', c_uint(0xabc)) + check_format('abc ', b'%-10x', c_uint(0xabc)) + check_format('abc ', b'%-010x', c_uint(0xabc)) + check_format('abc', b'%.2x', c_uint(0xabc)) + check_format('0000abc', b'%.7x', c_uint(0xabc)) + check_format(' abc', b'%10.2x', c_uint(0xabc)) + check_format(' 0000abc', b'%10.7x', c_uint(0xabc)) + check_format('0000000abc', b'%010.7x', c_uint(0xabc)) + check_format('0000abc ', b'%-10.7x', c_uint(0xabc)) + check_format('0000abc ', b'%-010.7x', c_uint(0xabc)) + + check_format('ABC', b'%2X', c_uint(0xabc)) + check_format(' ABC', b'%10X', c_uint(0xabc)) + check_format('0000000ABC', b'%010X', c_uint(0xabc)) + check_format('ABC ', b'%-10X', c_uint(0xabc)) + check_format('ABC ', b'%-010X', c_uint(0xabc)) + check_format('ABC', b'%.2X', c_uint(0xabc)) + check_format('0000ABC', b'%.7X', c_uint(0xabc)) + check_format(' ABC', b'%10.2X', c_uint(0xabc)) + check_format(' 0000ABC', b'%10.7X', c_uint(0xabc)) + check_format('0000000ABC', b'%010.7X', c_uint(0xabc)) + check_format('0000ABC ', b'%-10.7X', c_uint(0xabc)) + check_format('0000ABC ', b'%-010.7X', c_uint(0xabc)) # test %A check_format(r"%A:'abc\xe9\uabcd\U0010ffff'", b'%%A:%A', 'abc\xe9\uabcd\U0010ffff') # test %V - check_format('repr=abc', - b'repr=%V', 'abc', b'xyz') + check_format('abc', + b'%V', 'abc', b'xyz') + check_format('xyz', + b'%V', None, b'xyz') + + # test %ls + check_format('abc', b'%ls', c_wchar_p('abc')) + check_format('\u4eba\u6c11', b'%ls', c_wchar_p('\u4eba\u6c11')) + check_format('\U0001f4bb+\U0001f40d', + b'%ls', c_wchar_p('\U0001f4bb+\U0001f40d')) + check_format(' ab', b'%5.2ls', c_wchar_p('abc')) + check_format(' \u4eba\u6c11', b'%5ls', c_wchar_p('\u4eba\u6c11')) + check_format(' \U0001f4bb+\U0001f40d', + b'%5ls', c_wchar_p('\U0001f4bb+\U0001f40d')) + check_format('\u4eba', b'%.1ls', c_wchar_p('\u4eba\u6c11')) + check_format('\U0001f4bb' if sizeof(c_wchar) > 2 else '\ud83d', + b'%.1ls', c_wchar_p('\U0001f4bb+\U0001f40d')) + check_format('\U0001f4bb+' if sizeof(c_wchar) > 2 else '\U0001f4bb', + b'%.2ls', c_wchar_p('\U0001f4bb+\U0001f40d')) + + # test %lV + check_format('abc', + b'%lV', 'abc', c_wchar_p('xyz')) + check_format('xyz', + b'%lV', None, c_wchar_p('xyz')) + check_format('\u4eba\u6c11', + b'%lV', None, c_wchar_p('\u4eba\u6c11')) + check_format('\U0001f4bb+\U0001f40d', + b'%lV', None, c_wchar_p('\U0001f4bb+\U0001f40d')) + check_format(' ab', + b'%5.2lV', None, c_wchar_p('abc')) + check_format(' \u4eba\u6c11', + b'%5lV', None, c_wchar_p('\u4eba\u6c11')) + check_format(' \U0001f4bb+\U0001f40d', + b'%5lV', None, c_wchar_p('\U0001f4bb+\U0001f40d')) + check_format('\u4eba', + b'%.1lV', None, c_wchar_p('\u4eba\u6c11')) + check_format('\U0001f4bb' if sizeof(c_wchar) > 2 else '\ud83d', + b'%.1lV', None, c_wchar_p('\U0001f4bb+\U0001f40d')) + check_format('\U0001f4bb+' if sizeof(c_wchar) > 2 else '\U0001f4bb', + b'%.2lV', None, c_wchar_p('\U0001f4bb+\U0001f40d')) + + # test variable width and precision + check_format(' abc', b'%*s', c_int(5), b'abc') + check_format('ab', b'%.*s', c_int(2), b'abc') + check_format(' ab', b'%*.*s', c_int(5), c_int(2), b'abc') + check_format(' abc', b'%*U', c_int(5), 'abc') + check_format('ab', b'%.*U', c_int(2), 'abc') + check_format(' ab', b'%*.*U', c_int(5), c_int(2), 'abc') + check_format(' ab', b'%*.*V', c_int(5), c_int(2), None, b'abc') + check_format(' ab', b'%*.*lV', c_int(5), c_int(2), + None, c_wchar_p('abc')) + check_format(' 123', b'%*i', c_int(8), c_int(123)) + check_format('00123', b'%.*i', c_int(5), c_int(123)) + check_format(' 00123', b'%*.*i', c_int(8), c_int(5), c_int(123)) # test %p # We cannot test the exact result, @@ -254,30 +658,87 @@ class CAPITest(unittest.TestCase): check_format('repr=abc\ufffd', b'repr=%V', None, b'abc\xff') - # not supported: copy the raw format string. these tests are just here - # to check for crashes and should not be considered as specifications - check_format('%s', - b'%1%s', b'abc') - check_format('%1abc', - b'%1abc') - check_format('%+i', - b'%+i', c_int(10)) - check_format('%.%s', - b'%.%s', b'abc') - # Issue #33817: empty strings check_format('', b'') check_format('', b'%s', b'') - # Test PyUnicode_AsWideChar() + # test invalid format strings. these tests are just here + # to check for crashes and should not be considered as specifications + for fmt in (b'%', b'%0', b'%01', b'%.', b'%.1', + b'%0%s', b'%1%s', b'%.%s', b'%.1%s', b'%1abc', + b'%l', b'%ll', b'%z', b'%lls', b'%zs'): + with self.subTest(fmt=fmt): + self.assertRaisesRegex(SystemError, 'invalid format string', + PyUnicode_FromFormat, fmt, b'abc') + self.assertRaisesRegex(SystemError, 'invalid format string', + PyUnicode_FromFormat, b'%+i', c_int(10)) + + @support.cpython_only + @unittest.skipIf(_testcapi is None, 'need _testcapi module') + def test_interninplace(self): + """Test PyUnicode_InternInPlace()""" + from _testcapi import unicode_interninplace as interninplace + + s = b'abc'.decode() + r = interninplace(s) + self.assertEqual(r, 'abc') + + # CRASHES interninplace(b'abc') + # CRASHES interninplace(NULL) + + @support.cpython_only + @unittest.skipIf(_testcapi is None, 'need _testcapi module') + def test_internfromstring(self): + """Test PyUnicode_InternFromString()""" + from _testcapi import unicode_internfromstring as internfromstring + + self.assertEqual(internfromstring(b'abc'), 'abc') + self.assertEqual(internfromstring(b'\xf0\x9f\x98\x80'), '\U0001f600') + self.assertRaises(UnicodeDecodeError, internfromstring, b'\xc2') + self.assertRaises(UnicodeDecodeError, internfromstring, b'\xa1') + self.assertEqual(internfromstring(b''), '') + + # CRASHES internfromstring(NULL) + + @support.cpython_only + @unittest.skipIf(_testcapi is None, 'need _testcapi module') + def test_fromwidechar(self): + """Test PyUnicode_FromWideChar()""" + from _testcapi import unicode_fromwidechar as fromwidechar + from _testcapi import SIZEOF_WCHAR_T + + if SIZEOF_WCHAR_T == 2: + encoding = 'utf-16le' if sys.byteorder == 'little' else 'utf-16be' + elif SIZEOF_WCHAR_T == 4: + encoding = 'utf-32le' if sys.byteorder == 'little' else 'utf-32be' + + for s in '', 'abc', '\xa1\xa2', '\u4f60', '\U0001f600': + b = s.encode(encoding) + self.assertEqual(fromwidechar(b), s) + self.assertEqual(fromwidechar(b + b'\0'*SIZEOF_WCHAR_T, -1), s) + for s in '\ud83d', '\ude00': + b = s.encode(encoding, 'surrogatepass') + self.assertEqual(fromwidechar(b), s) + self.assertEqual(fromwidechar(b + b'\0'*SIZEOF_WCHAR_T, -1), s) + + self.assertEqual(fromwidechar('abc'.encode(encoding), 2), 'ab') + if SIZEOF_WCHAR_T == 2: + self.assertEqual(fromwidechar('a\U0001f600'.encode(encoding), 2), 'a\ud83d') + + self.assertRaises(SystemError, fromwidechar, b'\0'*SIZEOF_WCHAR_T, -2) + self.assertEqual(fromwidechar(NULL, 0), '') + self.assertRaises(SystemError, fromwidechar, NULL, 1) + self.assertRaises(SystemError, fromwidechar, NULL, -1) + @support.cpython_only @unittest.skipIf(_testcapi is None, 'need _testcapi module') def test_aswidechar(self): + """Test PyUnicode_AsWideChar()""" from _testcapi import unicode_aswidechar - import_helper.import_module('ctypes') - from ctypes import c_wchar, sizeof + from _testcapi import unicode_aswidechar_null + from _testcapi import SIZEOF_WCHAR_T wchar, size = unicode_aswidechar('abcdef', 2) self.assertEqual(size, 2) @@ -286,6 +747,8 @@ class CAPITest(unittest.TestCase): wchar, size = unicode_aswidechar('abc', 3) self.assertEqual(size, 3) self.assertEqual(wchar, 'abc') + self.assertEqual(unicode_aswidechar_null('abc', 10), 4) + self.assertEqual(unicode_aswidechar_null('abc', 0), 4) wchar, size = unicode_aswidechar('abc', 4) self.assertEqual(size, 3) @@ -298,95 +761,446 @@ class CAPITest(unittest.TestCase): wchar, size = unicode_aswidechar('abc\0def', 20) self.assertEqual(size, 7) self.assertEqual(wchar, 'abc\0def\0') + self.assertEqual(unicode_aswidechar_null('abc\0def', 20), 8) nonbmp = chr(0x10ffff) - if sizeof(c_wchar) == 2: - buflen = 3 + if SIZEOF_WCHAR_T == 2: nchar = 2 - else: # sizeof(c_wchar) == 4 - buflen = 2 + else: # SIZEOF_WCHAR_T == 4 nchar = 1 - wchar, size = unicode_aswidechar(nonbmp, buflen) + wchar, size = unicode_aswidechar(nonbmp, 10) self.assertEqual(size, nchar) self.assertEqual(wchar, nonbmp + '\0') + self.assertEqual(unicode_aswidechar_null(nonbmp, 10), nchar + 1) + + self.assertRaises(TypeError, unicode_aswidechar, b'abc', 10) + self.assertRaises(TypeError, unicode_aswidechar, [], 10) + self.assertRaises(SystemError, unicode_aswidechar, NULL, 10) + self.assertRaises(TypeError, unicode_aswidechar_null, b'abc', 10) + self.assertRaises(TypeError, unicode_aswidechar_null, [], 10) + self.assertRaises(SystemError, unicode_aswidechar_null, NULL, 10) - # Test PyUnicode_AsWideCharString() @support.cpython_only @unittest.skipIf(_testcapi is None, 'need _testcapi module') def test_aswidecharstring(self): + """Test PyUnicode_AsWideCharString()""" from _testcapi import unicode_aswidecharstring - import_helper.import_module('ctypes') - from ctypes import c_wchar, sizeof + from _testcapi import unicode_aswidecharstring_null + from _testcapi import SIZEOF_WCHAR_T wchar, size = unicode_aswidecharstring('abc') self.assertEqual(size, 3) self.assertEqual(wchar, 'abc\0') + self.assertEqual(unicode_aswidecharstring_null('abc'), 'abc') wchar, size = unicode_aswidecharstring('abc\0def') self.assertEqual(size, 7) self.assertEqual(wchar, 'abc\0def\0') + self.assertRaises(ValueError, unicode_aswidecharstring_null, 'abc\0def') nonbmp = chr(0x10ffff) - if sizeof(c_wchar) == 2: + if SIZEOF_WCHAR_T == 2: nchar = 2 - else: # sizeof(c_wchar) == 4 + else: # SIZEOF_WCHAR_T == 4 nchar = 1 wchar, size = unicode_aswidecharstring(nonbmp) self.assertEqual(size, nchar) self.assertEqual(wchar, nonbmp + '\0') + self.assertEqual(unicode_aswidecharstring_null(nonbmp), nonbmp) + + self.assertRaises(TypeError, unicode_aswidecharstring, b'abc') + self.assertRaises(TypeError, unicode_aswidecharstring, []) + self.assertRaises(SystemError, unicode_aswidecharstring, NULL) + self.assertRaises(TypeError, unicode_aswidecharstring_null, b'abc') + self.assertRaises(TypeError, unicode_aswidecharstring_null, []) + self.assertRaises(SystemError, unicode_aswidecharstring_null, NULL) - # Test PyUnicode_AsUCS4() @support.cpython_only @unittest.skipIf(_testcapi is None, 'need _testcapi module') def test_asucs4(self): + """Test PyUnicode_AsUCS4()""" from _testcapi import unicode_asucs4 + for s in ['abc', '\xa1\xa2', '\u4f60\u597d', 'a\U0001f600', 'a\ud800b\udfffc', '\ud834\udd1e']: l = len(s) - self.assertEqual(unicode_asucs4(s, l, True), s+'\0') - self.assertEqual(unicode_asucs4(s, l, False), s+'\uffff') - self.assertEqual(unicode_asucs4(s, l+1, True), s+'\0\uffff') - self.assertEqual(unicode_asucs4(s, l+1, False), s+'\0\uffff') - self.assertRaises(SystemError, unicode_asucs4, s, l-1, True) - self.assertRaises(SystemError, unicode_asucs4, s, l-2, False) + self.assertEqual(unicode_asucs4(s, l, 1), s+'\0') + self.assertEqual(unicode_asucs4(s, l, 0), s+'\uffff') + self.assertEqual(unicode_asucs4(s, l+1, 1), s+'\0\uffff') + self.assertEqual(unicode_asucs4(s, l+1, 0), s+'\0\uffff') + self.assertRaises(SystemError, unicode_asucs4, s, l-1, 1) + self.assertRaises(SystemError, unicode_asucs4, s, l-2, 0) s = '\0'.join([s, s]) - self.assertEqual(unicode_asucs4(s, len(s), True), s+'\0') - self.assertEqual(unicode_asucs4(s, len(s), False), s+'\uffff') + self.assertEqual(unicode_asucs4(s, len(s), 1), s+'\0') + self.assertEqual(unicode_asucs4(s, len(s), 0), s+'\uffff') + + # CRASHES unicode_asucs4(b'abc', 1, 0) + # CRASHES unicode_asucs4(b'abc', 1, 1) + # CRASHES unicode_asucs4([], 1, 1) + # CRASHES unicode_asucs4(NULL, 1, 0) + # CRASHES unicode_asucs4(NULL, 1, 1) + + @support.cpython_only + @unittest.skipIf(_testcapi is None, 'need _testcapi module') + def test_asucs4copy(self): + """Test PyUnicode_AsUCS4Copy()""" + from _testcapi import unicode_asucs4copy as asucs4copy + + for s in ['abc', '\xa1\xa2', '\u4f60\u597d', 'a\U0001f600', + 'a\ud800b\udfffc', '\ud834\udd1e']: + self.assertEqual(asucs4copy(s), s+'\0') + s = '\0'.join([s, s]) + self.assertEqual(asucs4copy(s), s+'\0') + + # CRASHES asucs4copy(b'abc') + # CRASHES asucs4copy([]) + # CRASHES asucs4copy(NULL) + + @support.cpython_only + @unittest.skipIf(_testcapi is None, 'need _testcapi module') + def test_fromordinal(self): + """Test PyUnicode_FromOrdinal()""" + from _testcapi import unicode_fromordinal as fromordinal + + self.assertEqual(fromordinal(0x61), 'a') + self.assertEqual(fromordinal(0x20ac), '\u20ac') + self.assertEqual(fromordinal(0x1f600), '\U0001f600') + + self.assertRaises(ValueError, fromordinal, 0x110000) + self.assertRaises(ValueError, fromordinal, -1) - # Test PyUnicode_AsUTF8() @support.cpython_only @unittest.skipIf(_testcapi is None, 'need _testcapi module') def test_asutf8(self): + """Test PyUnicode_AsUTF8()""" from _testcapi import unicode_asutf8 - bmp = '\u0100' - bmp2 = '\uffff' - nonbmp = chr(0x10ffff) + self.assertEqual(unicode_asutf8('abc', 4), b'abc\0') + self.assertEqual(unicode_asutf8('абв', 7), b'\xd0\xb0\xd0\xb1\xd0\xb2\0') + self.assertEqual(unicode_asutf8('\U0001f600', 5), b'\xf0\x9f\x98\x80\0') + self.assertEqual(unicode_asutf8('abc\0def', 8), b'abc\0def\0') - self.assertEqual(unicode_asutf8(bmp), b'\xc4\x80') - self.assertEqual(unicode_asutf8(bmp2), b'\xef\xbf\xbf') - self.assertEqual(unicode_asutf8(nonbmp), b'\xf4\x8f\xbf\xbf') - self.assertRaises(UnicodeEncodeError, unicode_asutf8, 'a\ud800b\udfffc') + self.assertRaises(UnicodeEncodeError, unicode_asutf8, '\ud8ff', 0) + self.assertRaises(TypeError, unicode_asutf8, b'abc', 0) + self.assertRaises(TypeError, unicode_asutf8, [], 0) + # CRASHES unicode_asutf8(NULL, 0) - # Test PyUnicode_AsUTF8AndSize() @support.cpython_only @unittest.skipIf(_testcapi is None, 'need _testcapi module') def test_asutf8andsize(self): + """Test PyUnicode_AsUTF8AndSize()""" from _testcapi import unicode_asutf8andsize + from _testcapi import unicode_asutf8andsize_null - bmp = '\u0100' - bmp2 = '\uffff' - nonbmp = chr(0x10ffff) + self.assertEqual(unicode_asutf8andsize('abc', 4), (b'abc\0', 3)) + self.assertEqual(unicode_asutf8andsize('абв', 7), (b'\xd0\xb0\xd0\xb1\xd0\xb2\0', 6)) + self.assertEqual(unicode_asutf8andsize('\U0001f600', 5), (b'\xf0\x9f\x98\x80\0', 4)) + self.assertEqual(unicode_asutf8andsize('abc\0def', 8), (b'abc\0def\0', 7)) + self.assertEqual(unicode_asutf8andsize_null('abc', 4), b'abc\0') + self.assertEqual(unicode_asutf8andsize_null('abc\0def', 8), b'abc\0def\0') + + self.assertRaises(UnicodeEncodeError, unicode_asutf8andsize, '\ud8ff', 0) + self.assertRaises(TypeError, unicode_asutf8andsize, b'abc', 0) + self.assertRaises(TypeError, unicode_asutf8andsize, [], 0) + # CRASHES unicode_asutf8andsize(NULL, 0) + + @support.cpython_only + @unittest.skipIf(_testcapi is None, 'need _testcapi module') + def test_getdefaultencoding(self): + """Test PyUnicode_GetDefaultEncoding()""" + from _testcapi import unicode_getdefaultencoding as getdefaultencoding + + self.assertEqual(getdefaultencoding(), b'utf-8') + + @support.cpython_only + @unittest.skipIf(_testcapi is None, 'need _testcapi module') + def test_transform_decimal_and_space(self): + """Test _PyUnicode_TransformDecimalAndSpaceToASCII()""" + from _testcapi import unicode_transformdecimalandspacetoascii as transform_decimal + + self.assertEqual(transform_decimal('123'), + '123') + self.assertEqual(transform_decimal('\u0663.\u0661\u0664'), + '3.14') + self.assertEqual(transform_decimal("\N{EM SPACE}3.14\N{EN SPACE}"), + " 3.14 ") + self.assertEqual(transform_decimal('12\u20ac3'), + '12?') + self.assertEqual(transform_decimal(''), '') + + self.assertRaises(SystemError, transform_decimal, b'123') + self.assertRaises(SystemError, transform_decimal, []) + # CRASHES transform_decimal(NULL) + + @support.cpython_only + @unittest.skipIf(_testcapi is None, 'need _testcapi module') + def test_concat(self): + """Test PyUnicode_Concat()""" + from _testcapi import unicode_concat as concat + + self.assertEqual(concat('abc', 'def'), 'abcdef') + self.assertEqual(concat('abc', 'где'), 'abcгде') + self.assertEqual(concat('абв', 'def'), 'абвdef') + self.assertEqual(concat('абв', 'где'), 'абвгде') + self.assertEqual(concat('a\0b', 'c\0d'), 'a\0bc\0d') - self.assertEqual(unicode_asutf8andsize(bmp), (b'\xc4\x80', 2)) - self.assertEqual(unicode_asutf8andsize(bmp2), (b'\xef\xbf\xbf', 3)) - self.assertEqual(unicode_asutf8andsize(nonbmp), (b'\xf4\x8f\xbf\xbf', 4)) - self.assertRaises(UnicodeEncodeError, unicode_asutf8andsize, 'a\ud800b\udfffc') + self.assertRaises(TypeError, concat, b'abc', 'def') + self.assertRaises(TypeError, concat, 'abc', b'def') + self.assertRaises(TypeError, concat, b'abc', b'def') + self.assertRaises(TypeError, concat, [], 'def') + self.assertRaises(TypeError, concat, 'abc', []) + self.assertRaises(TypeError, concat, [], []) + # CRASHES concat(NULL, 'def') + # CRASHES concat('abc', NULL) + + @support.cpython_only + @unittest.skipIf(_testcapi is None, 'need _testcapi module') + def test_split(self): + """Test PyUnicode_Split()""" + from _testcapi import unicode_split as split + + self.assertEqual(split('a|b|c|d', '|'), ['a', 'b', 'c', 'd']) + self.assertEqual(split('a|b|c|d', '|', 2), ['a', 'b', 'c|d']) + self.assertEqual(split('a|b|c|d', '\u20ac'), ['a|b|c|d']) + self.assertEqual(split('a||b|c||d', '||'), ['a', 'b|c', 'd']) + self.assertEqual(split('а|б|в|г', '|'), ['а', 'б', 'в', 'г']) + self.assertEqual(split('абабагаламага', 'а'), + ['', 'б', 'б', 'г', 'л', 'м', 'г', '']) + self.assertEqual(split(' a\tb\nc\rd\ve\f', NULL), + ['a', 'b', 'c', 'd', 'e']) + self.assertEqual(split('a\x85b\xa0c\u1680d\u2000e', NULL), + ['a', 'b', 'c', 'd', 'e']) + + self.assertRaises(ValueError, split, 'a|b|c|d', '') + self.assertRaises(TypeError, split, 'a|b|c|d', ord('|')) + self.assertRaises(TypeError, split, [], '|') + # CRASHES split(NULL, '|') + + @support.cpython_only + @unittest.skipIf(_testcapi is None, 'need _testcapi module') + def test_rsplit(self): + """Test PyUnicode_RSplit()""" + from _testcapi import unicode_rsplit as rsplit + + self.assertEqual(rsplit('a|b|c|d', '|'), ['a', 'b', 'c', 'd']) + self.assertEqual(rsplit('a|b|c|d', '|', 2), ['a|b', 'c', 'd']) + self.assertEqual(rsplit('a|b|c|d', '\u20ac'), ['a|b|c|d']) + self.assertEqual(rsplit('a||b|c||d', '||'), ['a', 'b|c', 'd']) + self.assertEqual(rsplit('а|б|в|г', '|'), ['а', 'б', 'в', 'г']) + self.assertEqual(rsplit('абабагаламага', 'а'), + ['', 'б', 'б', 'г', 'л', 'м', 'г', '']) + self.assertEqual(rsplit('aжbжcжd', 'ж'), ['a', 'b', 'c', 'd']) + self.assertEqual(rsplit(' a\tb\nc\rd\ve\f', NULL), + ['a', 'b', 'c', 'd', 'e']) + self.assertEqual(rsplit('a\x85b\xa0c\u1680d\u2000e', NULL), + ['a', 'b', 'c', 'd', 'e']) + + self.assertRaises(ValueError, rsplit, 'a|b|c|d', '') + self.assertRaises(TypeError, rsplit, 'a|b|c|d', ord('|')) + self.assertRaises(TypeError, rsplit, [], '|') + # CRASHES rsplit(NULL, '|') + + @support.cpython_only + @unittest.skipIf(_testcapi is None, 'need _testcapi module') + def test_partition(self): + """Test PyUnicode_Partition()""" + from _testcapi import unicode_partition as partition + + self.assertEqual(partition('a|b|c', '|'), ('a', '|', 'b|c')) + self.assertEqual(partition('a||b||c', '||'), ('a', '||', 'b||c')) + self.assertEqual(partition('а|б|в', '|'), ('а', '|', 'б|в')) + self.assertEqual(partition('кабан', 'а'), ('к', 'а', 'бан')) + self.assertEqual(partition('aжbжc', 'ж'), ('a', 'ж', 'bжc')) + + self.assertRaises(ValueError, partition, 'a|b|c', '') + self.assertRaises(TypeError, partition, b'a|b|c', '|') + self.assertRaises(TypeError, partition, 'a|b|c', b'|') + self.assertRaises(TypeError, partition, 'a|b|c', ord('|')) + self.assertRaises(TypeError, partition, [], '|') + # CRASHES partition(NULL, '|') + # CRASHES partition('a|b|c', NULL) + + @support.cpython_only + @unittest.skipIf(_testcapi is None, 'need _testcapi module') + def test_rpartition(self): + """Test PyUnicode_RPartition()""" + from _testcapi import unicode_rpartition as rpartition + + self.assertEqual(rpartition('a|b|c', '|'), ('a|b', '|', 'c')) + self.assertEqual(rpartition('a||b||c', '||'), ('a||b', '||', 'c')) + self.assertEqual(rpartition('а|б|в', '|'), ('а|б', '|', 'в')) + self.assertEqual(rpartition('кабан', 'а'), ('каб', 'а', 'н')) + self.assertEqual(rpartition('aжbжc', 'ж'), ('aжb', 'ж', 'c')) + + self.assertRaises(ValueError, rpartition, 'a|b|c', '') + self.assertRaises(TypeError, rpartition, b'a|b|c', '|') + self.assertRaises(TypeError, rpartition, 'a|b|c', b'|') + self.assertRaises(TypeError, rpartition, 'a|b|c', ord('|')) + self.assertRaises(TypeError, rpartition, [], '|') + # CRASHES rpartition(NULL, '|') + # CRASHES rpartition('a|b|c', NULL) + + @support.cpython_only + @unittest.skipIf(_testcapi is None, 'need _testcapi module') + def test_splitlines(self): + """Test PyUnicode_SplitLines()""" + from _testcapi import unicode_splitlines as splitlines + + self.assertEqual(splitlines('a\nb\rc\r\nd'), ['a', 'b', 'c', 'd']) + self.assertEqual(splitlines('a\nb\rc\r\nd', True), + ['a\n', 'b\r', 'c\r\n', 'd']) + self.assertEqual(splitlines('a\x85b\u2028c\u2029d'), + ['a', 'b', 'c', 'd']) + self.assertEqual(splitlines('a\x85b\u2028c\u2029d', True), + ['a\x85', 'b\u2028', 'c\u2029', 'd']) + self.assertEqual(splitlines('а\nб\rв\r\nг'), ['а', 'б', 'в', 'г']) + + self.assertRaises(TypeError, splitlines, b'a\nb\rc\r\nd') + # CRASHES splitlines(NULL) + + @support.cpython_only + @unittest.skipIf(_testcapi is None, 'need _testcapi module') + def test_translate(self): + """Test PyUnicode_Translate()""" + from _testcapi import unicode_translate as translate + + self.assertEqual(translate('abcd', {ord('a'): 'A', ord('b'): ord('B'), ord('c'): '<>'}), 'AB<>d') + self.assertEqual(translate('абвг', {ord('а'): 'А', ord('б'): ord('Б'), ord('в'): '<>'}), 'АБ<>г') + self.assertEqual(translate('abc', {}), 'abc') + self.assertEqual(translate('abc', []), 'abc') + self.assertRaises(UnicodeTranslateError, translate, 'abc', {ord('b'): None}) + self.assertRaises(UnicodeTranslateError, translate, 'abc', {ord('b'): None}, 'strict') + self.assertRaises(LookupError, translate, 'abc', {ord('b'): None}, 'foo') + self.assertEqual(translate('abc', {ord('b'): None}, 'ignore'), 'ac') + self.assertEqual(translate('abc', {ord('b'): None}, 'replace'), 'a\ufffdc') + self.assertEqual(translate('abc', {ord('b'): None}, 'backslashreplace'), r'a\x62c') + # XXX Other error handlers do not support UnicodeTranslateError + self.assertRaises(TypeError, translate, b'abc', []) + self.assertRaises(TypeError, translate, 123, []) + self.assertRaises(TypeError, translate, 'abc', {ord('a'): b'A'}) + self.assertRaises(TypeError, translate, 'abc', 123) + self.assertRaises(TypeError, translate, 'abc', NULL) + self.assertRaises(LookupError, translate, 'abc', {ord('b'): None}, 'foo') + # CRASHES translate(NULL, []) + + @support.cpython_only + @unittest.skipIf(_testcapi is None, 'need _testcapi module') + def test_join(self): + """Test PyUnicode_Join()""" + from _testcapi import unicode_join as join + self.assertEqual(join('|', ['a', 'b', 'c']), 'a|b|c') + self.assertEqual(join('|', ['a', '', 'c']), 'a||c') + self.assertEqual(join('', ['a', 'b', 'c']), 'abc') + self.assertEqual(join(NULL, ['a', 'b', 'c']), 'a b c') + self.assertEqual(join('|', ['а', 'б', 'в']), 'а|б|в') + self.assertEqual(join('ж', ['а', 'б', 'в']), 'ажбжв') + self.assertRaises(TypeError, join, b'|', ['a', 'b', 'c']) + self.assertRaises(TypeError, join, '|', [b'a', b'b', b'c']) + self.assertRaises(TypeError, join, NULL, [b'a', b'b', b'c']) + self.assertRaises(TypeError, join, '|', b'123') + self.assertRaises(TypeError, join, '|', 123) + self.assertRaises(SystemError, join, '|', NULL) + + @support.cpython_only + @unittest.skipIf(_testcapi is None, 'need _testcapi module') + def test_count(self): + """Test PyUnicode_Count()""" + from _testcapi import unicode_count + + for str in "\xa1", "\u8000\u8080", "\ud800\udc02", "\U0001f100\U0001f1f1": + for i, ch in enumerate(str): + self.assertEqual(unicode_count(str, ch, 0, len(str)), 1) + + str = "!>_<!" + self.assertEqual(unicode_count(str, 'z', 0, len(str)), 0) + self.assertEqual(unicode_count(str, '', 0, len(str)), len(str)+1) + # start < end + self.assertEqual(unicode_count(str, '!', 1, len(str)+1), 1) + # start >= end + self.assertEqual(unicode_count(str, '!', 0, 0), 0) + self.assertEqual(unicode_count(str, '!', len(str), 0), 0) + # negative + self.assertEqual(unicode_count(str, '!', -len(str), -1), 1) + # bad arguments + self.assertRaises(TypeError, unicode_count, str, b'!', 0, len(str)) + self.assertRaises(TypeError, unicode_count, b"!>_<!", '!', 0, len(str)) + self.assertRaises(TypeError, unicode_count, str, ord('!'), 0, len(str)) + self.assertRaises(TypeError, unicode_count, [], '!', 0, len(str), 1) + # CRASHES unicode_count(NULL, '!', 0, len(str)) + # CRASHES unicode_count(str, NULL, 0, len(str)) + + @support.cpython_only + @unittest.skipIf(_testcapi is None, 'need _testcapi module') + def test_tailmatch(self): + """Test PyUnicode_Tailmatch()""" + from _testcapi import unicode_tailmatch as tailmatch + + str = 'ababahalamaha' + self.assertEqual(tailmatch(str, 'aba', 0, len(str), -1), 1) + self.assertEqual(tailmatch(str, 'aha', 0, len(str), 1), 1) + + self.assertEqual(tailmatch(str, 'aba', 0, sys.maxsize, -1), 1) + self.assertEqual(tailmatch(str, 'aba', -len(str), sys.maxsize, -1), 1) + self.assertEqual(tailmatch(str, 'aba', -sys.maxsize-1, len(str), -1), 1) + self.assertEqual(tailmatch(str, 'aha', 0, sys.maxsize, 1), 1) + self.assertEqual(tailmatch(str, 'aha', -sys.maxsize-1, len(str), 1), 1) + + self.assertEqual(tailmatch(str, 'z', 0, len(str), 1), 0) + self.assertEqual(tailmatch(str, 'z', 0, len(str), -1), 0) + self.assertEqual(tailmatch(str, '', 0, len(str), 1), 1) + self.assertEqual(tailmatch(str, '', 0, len(str), -1), 1) + + self.assertEqual(tailmatch(str, 'ba', 0, len(str)-1, -1), 0) + self.assertEqual(tailmatch(str, 'ba', 1, len(str)-1, -1), 1) + self.assertEqual(tailmatch(str, 'aba', 1, len(str)-1, -1), 0) + self.assertEqual(tailmatch(str, 'ba', -len(str)+1, -1, -1), 1) + self.assertEqual(tailmatch(str, 'ah', 0, len(str), 1), 0) + self.assertEqual(tailmatch(str, 'ah', 0, len(str)-1, 1), 1) + self.assertEqual(tailmatch(str, 'ah', -len(str), -1, 1), 1) + + # bad arguments + self.assertRaises(TypeError, tailmatch, str, ('aba', 'aha'), 0, len(str), -1) + self.assertRaises(TypeError, tailmatch, str, ('aba', 'aha'), 0, len(str), 1) + # CRASHES tailmatch(NULL, 'aba', 0, len(str), -1) + # CRASHES tailmatch(str, NULL, 0, len(str), -1) + + @support.cpython_only + @unittest.skipIf(_testcapi is None, 'need _testcapi module') + def test_find(self): + """Test PyUnicode_Find()""" + from _testcapi import unicode_find as find + + for str in "\xa1", "\u8000\u8080", "\ud800\udc02", "\U0001f100\U0001f1f1": + for i, ch in enumerate(str): + self.assertEqual(find(str, ch, 0, len(str), 1), i) + self.assertEqual(find(str, ch, 0, len(str), -1), i) + + str = "!>_<!" + self.assertEqual(find(str, 'z', 0, len(str), 1), -1) + self.assertEqual(find(str, 'z', 0, len(str), -1), -1) + self.assertEqual(find(str, '', 0, len(str), 1), 0) + self.assertEqual(find(str, '', 0, len(str), -1), len(str)) + # start < end + self.assertEqual(find(str, '!', 1, len(str)+1, 1), 4) + self.assertEqual(find(str, '!', 1, len(str)+1, -1), 4) + # start >= end + self.assertEqual(find(str, '!', 0, 0, 1), -1) + self.assertEqual(find(str, '!', len(str), 0, 1), -1) + # negative + self.assertEqual(find(str, '!', -len(str), -1, 1), 0) + self.assertEqual(find(str, '!', -len(str), -1, -1), 0) + # bad arguments + self.assertRaises(TypeError, find, str, b'!', 0, len(str), 1) + self.assertRaises(TypeError, find, b"!>_<!", '!', 0, len(str), 1) + self.assertRaises(TypeError, find, str, ord('!'), 0, len(str), 1) + self.assertRaises(TypeError, find, [], '!', 0, len(str), 1) + # CRASHES find(NULL, '!', 0, len(str), 1) + # CRASHES find(str, NULL, 0, len(str), 1) - # Test PyUnicode_FindChar() @support.cpython_only @unittest.skipIf(_testcapi is None, 'need _testcapi module') def test_findchar(self): + """Test PyUnicode_FindChar()""" from _testcapi import unicode_findchar for str in "\xa1", "\u8000\u8080", "\ud800\udc02", "\U0001f100\U0001f1f1": @@ -406,14 +1220,172 @@ class CAPITest(unittest.TestCase): # negative self.assertEqual(unicode_findchar(str, ord('!'), -len(str), -1, 1), 0) self.assertEqual(unicode_findchar(str, ord('!'), -len(str), -1, -1), 0) + # bad arguments + # CRASHES unicode_findchar(b"!>_<!", ord('!'), 0, len(str), 1) + # CRASHES unicode_findchar([], ord('!'), 0, len(str), 1) + # CRASHES unicode_findchar(NULL, ord('!'), 0, len(str), 1), 1) + + @support.cpython_only + @unittest.skipIf(_testcapi is None, 'need _testcapi module') + def test_replace(self): + """Test PyUnicode_Replace()""" + from _testcapi import unicode_replace as replace + + str = 'abracadabra' + self.assertEqual(replace(str, 'a', '='), '=br=c=d=br=') + self.assertEqual(replace(str, 'a', '<>'), '<>br<>c<>d<>br<>') + self.assertEqual(replace(str, 'abra', '='), '=cad=') + self.assertEqual(replace(str, 'a', '=', 2), '=br=cadabra') + self.assertEqual(replace(str, 'a', '=', 0), str) + self.assertEqual(replace(str, 'a', '=', sys.maxsize), '=br=c=d=br=') + self.assertEqual(replace(str, 'z', '='), str) + self.assertEqual(replace(str, '', '='), '=a=b=r=a=c=a=d=a=b=r=a=') + self.assertEqual(replace(str, 'a', 'ж'), 'жbrжcжdжbrж') + self.assertEqual(replace('абабагаламага', 'а', '='), '=б=б=г=л=м=г=') + self.assertEqual(replace('Баден-Баден', 'Баден', 'Baden'), 'Baden-Baden') + # bad arguments + self.assertRaises(TypeError, replace, 'a', 'a', b'=') + self.assertRaises(TypeError, replace, 'a', b'a', '=') + self.assertRaises(TypeError, replace, b'a', 'a', '=') + self.assertRaises(TypeError, replace, 'a', 'a', ord('=')) + self.assertRaises(TypeError, replace, 'a', ord('a'), '=') + self.assertRaises(TypeError, replace, [], 'a', '=') + # CRASHES replace('a', 'a', NULL) + # CRASHES replace('a', NULL, '=') + # CRASHES replace(NULL, 'a', '=') + + @support.cpython_only + @unittest.skipIf(_testcapi is None, 'need _testcapi module') + def test_compare(self): + """Test PyUnicode_Compare()""" + from _testcapi import unicode_compare as compare + + self.assertEqual(compare('abc', 'abc'), 0) + self.assertEqual(compare('abc', 'def'), -1) + self.assertEqual(compare('def', 'abc'), 1) + self.assertEqual(compare('abc', 'abc\0def'), -1) + self.assertEqual(compare('abc\0def', 'abc\0def'), 0) + self.assertEqual(compare('абв', 'abc'), 1) + + self.assertRaises(TypeError, compare, b'abc', 'abc') + self.assertRaises(TypeError, compare, 'abc', b'abc') + self.assertRaises(TypeError, compare, b'abc', b'abc') + self.assertRaises(TypeError, compare, [], 'abc') + self.assertRaises(TypeError, compare, 'abc', []) + self.assertRaises(TypeError, compare, [], []) + # CRASHES compare(NULL, 'abc') + # CRASHES compare('abc', NULL) + + @support.cpython_only + @unittest.skipIf(_testcapi is None, 'need _testcapi module') + def test_comparewithasciistring(self): + """Test PyUnicode_CompareWithASCIIString()""" + from _testcapi import unicode_comparewithasciistring as comparewithasciistring + + self.assertEqual(comparewithasciistring('abc', b'abc'), 0) + self.assertEqual(comparewithasciistring('abc', b'def'), -1) + self.assertEqual(comparewithasciistring('def', b'abc'), 1) + self.assertEqual(comparewithasciistring('abc', b'abc\0def'), 0) + self.assertEqual(comparewithasciistring('abc\0def', b'abc\0def'), 1) + self.assertEqual(comparewithasciistring('абв', b'abc'), 1) + + # CRASHES comparewithasciistring(b'abc', b'abc') + # CRASHES comparewithasciistring([], b'abc') + # CRASHES comparewithasciistring(NULL, b'abc') + + @support.cpython_only + @unittest.skipIf(_testcapi is None, 'need _testcapi module') + def test_richcompare(self): + """Test PyUnicode_RichCompare()""" + from _testcapi import unicode_richcompare as richcompare + + LT, LE, EQ, NE, GT, GE = range(6) + strings = ('abc', 'абв', '\U0001f600', 'abc\0') + for s1 in strings: + for s2 in strings: + self.assertIs(richcompare(s1, s2, LT), s1 < s2) + self.assertIs(richcompare(s1, s2, LE), s1 <= s2) + self.assertIs(richcompare(s1, s2, EQ), s1 == s2) + self.assertIs(richcompare(s1, s2, NE), s1 != s2) + self.assertIs(richcompare(s1, s2, GT), s1 > s2) + self.assertIs(richcompare(s1, s2, GE), s1 >= s2) + + for op in LT, LE, EQ, NE, GT, GE: + self.assertIs(richcompare(b'abc', 'abc', op), NotImplemented) + self.assertIs(richcompare('abc', b'abc', op), NotImplemented) + self.assertIs(richcompare(b'abc', b'abc', op), NotImplemented) + self.assertIs(richcompare([], 'abc', op), NotImplemented) + self.assertIs(richcompare('abc', [], op), NotImplemented) + self.assertIs(richcompare([], [], op), NotImplemented) + + # CRASHES richcompare(NULL, 'abc', op) + # CRASHES richcompare('abc', NULL, op) + + @support.cpython_only + @unittest.skipIf(_testcapi is None, 'need _testcapi module') + def test_format(self): + """Test PyUnicode_Format()""" + from _testcapi import unicode_format as format + + self.assertEqual(format('x=%d!', 42), 'x=42!') + self.assertEqual(format('x=%d!', (42,)), 'x=42!') + self.assertEqual(format('x=%d y=%s!', (42, [])), 'x=42 y=[]!') + + self.assertRaises(SystemError, format, 'x=%d!', NULL) + self.assertRaises(SystemError, format, NULL, 42) + + @support.cpython_only + @unittest.skipIf(_testcapi is None, 'need _testcapi module') + def test_contains(self): + """Test PyUnicode_Contains()""" + from _testcapi import unicode_contains as contains + + self.assertEqual(contains('abcd', ''), 1) + self.assertEqual(contains('abcd', 'b'), 1) + self.assertEqual(contains('abcd', 'x'), 0) + self.assertEqual(contains('abcd', 'ж'), 0) + self.assertEqual(contains('abcd', '\0'), 0) + self.assertEqual(contains('abc\0def', '\0'), 1) + self.assertEqual(contains('abcd', 'bc'), 1) + + self.assertRaises(TypeError, contains, b'abcd', 'b') + self.assertRaises(TypeError, contains, 'abcd', b'b') + self.assertRaises(TypeError, contains, b'abcd', b'b') + self.assertRaises(TypeError, contains, [], 'b') + self.assertRaises(TypeError, contains, 'abcd', ord('b')) + # CRASHES contains(NULL, 'b') + # CRASHES contains('abcd', NULL) + + @support.cpython_only + @unittest.skipIf(_testcapi is None, 'need _testcapi module') + def test_isidentifier(self): + """Test PyUnicode_IsIdentifier()""" + from _testcapi import unicode_isidentifier as isidentifier + + self.assertEqual(isidentifier("a"), 1) + self.assertEqual(isidentifier("b0"), 1) + self.assertEqual(isidentifier("µ"), 1) + self.assertEqual(isidentifier("𝔘𝔫𝔦𝔠𝔬𝔡𝔢"), 1) + + self.assertEqual(isidentifier(""), 0) + self.assertEqual(isidentifier(" "), 0) + self.assertEqual(isidentifier("["), 0) + self.assertEqual(isidentifier("©"), 0) + self.assertEqual(isidentifier("0"), 0) + self.assertEqual(isidentifier("32M"), 0) + + # CRASHES isidentifier(b"a") + # CRASHES isidentifier([]) + # CRASHES isidentifier(NULL) - # Test PyUnicode_CopyCharacters() @support.cpython_only @unittest.skipIf(_testcapi is None, 'need _testcapi module') def test_copycharacters(self): + """Test PyUnicode_CopyCharacters()""" from _testcapi import unicode_copycharacters strings = [ + # all strings have exactly 5 characters 'abcde', '\xa1\xa2\xa3\xa4\xa5', '\u4f60\u597d\u4e16\u754c\uff01', '\U0001f600\U0001f601\U0001f602\U0001f603\U0001f604' @@ -450,6 +1422,10 @@ class CAPITest(unittest.TestCase): self.assertRaises(SystemError, unicode_copycharacters, s, 1, s, 0, 5) self.assertRaises(SystemError, unicode_copycharacters, s, 0, s, 0, -1) self.assertRaises(SystemError, unicode_copycharacters, s, 0, b'', 0, 0) + self.assertRaises(SystemError, unicode_copycharacters, s, 0, [], 0, 0) + # CRASHES unicode_copycharacters(s, 0, NULL, 0, 0) + # TODO: Test PyUnicode_CopyCharacters() with non-unicode and + # non-modifiable unicode as "to". @support.cpython_only @unittest.skipIf(_testcapi is None, 'need _testcapi module') diff --git a/Lib/test/test_capi/test_watchers.py b/Lib/test/test_capi/test_watchers.py new file mode 100644 index 00000000..6b8855ec --- /dev/null +++ b/Lib/test/test_capi/test_watchers.py @@ -0,0 +1,559 @@ +import unittest + +from contextlib import contextmanager, ExitStack +from test.support import catch_unraisable_exception, import_helper + + +# Skip this test if the _testcapi module isn't available. +_testcapi = import_helper.import_module('_testcapi') + + +class TestDictWatchers(unittest.TestCase): + # types of watchers testcapimodule can add: + EVENTS = 0 # appends dict events as strings to global event list + ERROR = 1 # unconditionally sets and signals a RuntimeException + SECOND = 2 # always appends "second" to global event list + + def add_watcher(self, kind=EVENTS): + return _testcapi.add_dict_watcher(kind) + + def clear_watcher(self, watcher_id): + _testcapi.clear_dict_watcher(watcher_id) + + @contextmanager + def watcher(self, kind=EVENTS): + wid = self.add_watcher(kind) + try: + yield wid + finally: + self.clear_watcher(wid) + + def assert_events(self, expected): + actual = _testcapi.get_dict_watcher_events() + self.assertEqual(actual, expected) + + def watch(self, wid, d): + _testcapi.watch_dict(wid, d) + + def unwatch(self, wid, d): + _testcapi.unwatch_dict(wid, d) + + def test_set_new_item(self): + d = {} + with self.watcher() as wid: + self.watch(wid, d) + d["foo"] = "bar" + self.assert_events(["new:foo:bar"]) + + def test_set_existing_item(self): + d = {"foo": "bar"} + with self.watcher() as wid: + self.watch(wid, d) + d["foo"] = "baz" + self.assert_events(["mod:foo:baz"]) + + def test_clone(self): + d = {} + d2 = {"foo": "bar"} + with self.watcher() as wid: + self.watch(wid, d) + d.update(d2) + self.assert_events(["clone"]) + + def test_no_event_if_not_watched(self): + d = {} + with self.watcher() as wid: + d["foo"] = "bar" + self.assert_events([]) + + def test_del(self): + d = {"foo": "bar"} + with self.watcher() as wid: + self.watch(wid, d) + del d["foo"] + self.assert_events(["del:foo"]) + + def test_pop(self): + d = {"foo": "bar"} + with self.watcher() as wid: + self.watch(wid, d) + d.pop("foo") + self.assert_events(["del:foo"]) + + def test_clear(self): + d = {"foo": "bar"} + with self.watcher() as wid: + self.watch(wid, d) + d.clear() + self.assert_events(["clear"]) + + def test_dealloc(self): + d = {"foo": "bar"} + with self.watcher() as wid: + self.watch(wid, d) + del d + self.assert_events(["dealloc"]) + + def test_unwatch(self): + d = {} + with self.watcher() as wid: + self.watch(wid, d) + d["foo"] = "bar" + self.unwatch(wid, d) + d["hmm"] = "baz" + self.assert_events(["new:foo:bar"]) + + def test_error(self): + d = {} + with self.watcher(kind=self.ERROR) as wid: + self.watch(wid, d) + with catch_unraisable_exception() as cm: + d["foo"] = "bar" + self.assertIn( + "PyDict_EVENT_ADDED watcher callback for <dict at", + cm.unraisable.object + ) + self.assertEqual(str(cm.unraisable.exc_value), "boom!") + self.assert_events([]) + + def test_dealloc_error(self): + d = {} + with self.watcher(kind=self.ERROR) as wid: + self.watch(wid, d) + with catch_unraisable_exception() as cm: + del d + self.assertEqual(str(cm.unraisable.exc_value), "boom!") + + def test_two_watchers(self): + d1 = {} + d2 = {} + with self.watcher() as wid1: + with self.watcher(kind=self.SECOND) as wid2: + self.watch(wid1, d1) + self.watch(wid2, d2) + d1["foo"] = "bar" + d2["hmm"] = "baz" + self.assert_events(["new:foo:bar", "second"]) + + def test_watch_non_dict(self): + with self.watcher() as wid: + with self.assertRaisesRegex(ValueError, r"Cannot watch non-dictionary"): + self.watch(wid, 1) + + def test_watch_out_of_range_watcher_id(self): + d = {} + with self.assertRaisesRegex(ValueError, r"Invalid dict watcher ID -1"): + self.watch(-1, d) + with self.assertRaisesRegex(ValueError, r"Invalid dict watcher ID 8"): + self.watch(8, d) # DICT_MAX_WATCHERS = 8 + + def test_watch_unassigned_watcher_id(self): + d = {} + with self.assertRaisesRegex(ValueError, r"No dict watcher set for ID 1"): + self.watch(1, d) + + def test_unwatch_non_dict(self): + with self.watcher() as wid: + with self.assertRaisesRegex(ValueError, r"Cannot watch non-dictionary"): + self.unwatch(wid, 1) + + def test_unwatch_out_of_range_watcher_id(self): + d = {} + with self.assertRaisesRegex(ValueError, r"Invalid dict watcher ID -1"): + self.unwatch(-1, d) + with self.assertRaisesRegex(ValueError, r"Invalid dict watcher ID 8"): + self.unwatch(8, d) # DICT_MAX_WATCHERS = 8 + + def test_unwatch_unassigned_watcher_id(self): + d = {} + with self.assertRaisesRegex(ValueError, r"No dict watcher set for ID 1"): + self.unwatch(1, d) + + def test_clear_out_of_range_watcher_id(self): + with self.assertRaisesRegex(ValueError, r"Invalid dict watcher ID -1"): + self.clear_watcher(-1) + with self.assertRaisesRegex(ValueError, r"Invalid dict watcher ID 8"): + self.clear_watcher(8) # DICT_MAX_WATCHERS = 8 + + def test_clear_unassigned_watcher_id(self): + with self.assertRaisesRegex(ValueError, r"No dict watcher set for ID 1"): + self.clear_watcher(1) + + +class TestTypeWatchers(unittest.TestCase): + # types of watchers testcapimodule can add: + TYPES = 0 # appends modified types to global event list + ERROR = 1 # unconditionally sets and signals a RuntimeException + WRAP = 2 # appends modified type wrapped in list to global event list + + # duplicating the C constant + TYPE_MAX_WATCHERS = 8 + + def add_watcher(self, kind=TYPES): + return _testcapi.add_type_watcher(kind) + + def clear_watcher(self, watcher_id): + _testcapi.clear_type_watcher(watcher_id) + + @contextmanager + def watcher(self, kind=TYPES): + wid = self.add_watcher(kind) + try: + yield wid + finally: + self.clear_watcher(wid) + + def assert_events(self, expected): + actual = _testcapi.get_type_modified_events() + self.assertEqual(actual, expected) + + def watch(self, wid, t): + _testcapi.watch_type(wid, t) + + def unwatch(self, wid, t): + _testcapi.unwatch_type(wid, t) + + def test_watch_type(self): + class C: pass + with self.watcher() as wid: + self.watch(wid, C) + C.foo = "bar" + self.assert_events([C]) + + def test_event_aggregation(self): + class C: pass + with self.watcher() as wid: + self.watch(wid, C) + C.foo = "bar" + C.bar = "baz" + # only one event registered for both modifications + self.assert_events([C]) + + def test_lookup_resets_aggregation(self): + class C: pass + with self.watcher() as wid: + self.watch(wid, C) + C.foo = "bar" + # lookup resets type version tag + self.assertEqual(C.foo, "bar") + C.bar = "baz" + # both events registered + self.assert_events([C, C]) + + def test_unwatch_type(self): + class C: pass + with self.watcher() as wid: + self.watch(wid, C) + C.foo = "bar" + self.assertEqual(C.foo, "bar") + self.assert_events([C]) + self.unwatch(wid, C) + C.bar = "baz" + self.assert_events([C]) + + def test_clear_watcher(self): + class C: pass + # outer watcher is unused, it's just to keep events list alive + with self.watcher() as _: + with self.watcher() as wid: + self.watch(wid, C) + C.foo = "bar" + self.assertEqual(C.foo, "bar") + self.assert_events([C]) + C.bar = "baz" + # Watcher on C has been cleared, no new event + self.assert_events([C]) + + def test_watch_type_subclass(self): + class C: pass + class D(C): pass + with self.watcher() as wid: + self.watch(wid, D) + C.foo = "bar" + self.assert_events([D]) + + def test_error(self): + class C: pass + with self.watcher(kind=self.ERROR) as wid: + self.watch(wid, C) + with catch_unraisable_exception() as cm: + C.foo = "bar" + self.assertIs(cm.unraisable.object, C) + self.assertEqual(str(cm.unraisable.exc_value), "boom!") + self.assert_events([]) + + def test_two_watchers(self): + class C1: pass + class C2: pass + with self.watcher() as wid1: + with self.watcher(kind=self.WRAP) as wid2: + self.assertNotEqual(wid1, wid2) + self.watch(wid1, C1) + self.watch(wid2, C2) + C1.foo = "bar" + C2.hmm = "baz" + self.assert_events([C1, [C2]]) + + def test_all_watchers(self): + class C: pass + with ExitStack() as stack: + last_wid = -1 + # don't make assumptions about how many watchers are already + # registered, just go until we reach the max ID + while last_wid < self.TYPE_MAX_WATCHERS - 1: + last_wid = stack.enter_context(self.watcher()) + self.watch(last_wid, C) + C.foo = "bar" + self.assert_events([C]) + + def test_watch_non_type(self): + with self.watcher() as wid: + with self.assertRaisesRegex(ValueError, r"Cannot watch non-type"): + self.watch(wid, 1) + + def test_watch_out_of_range_watcher_id(self): + class C: pass + with self.assertRaisesRegex(ValueError, r"Invalid type watcher ID -1"): + self.watch(-1, C) + with self.assertRaisesRegex(ValueError, r"Invalid type watcher ID 8"): + self.watch(self.TYPE_MAX_WATCHERS, C) + + def test_watch_unassigned_watcher_id(self): + class C: pass + with self.assertRaisesRegex(ValueError, r"No type watcher set for ID 1"): + self.watch(1, C) + + def test_unwatch_non_type(self): + with self.watcher() as wid: + with self.assertRaisesRegex(ValueError, r"Cannot watch non-type"): + self.unwatch(wid, 1) + + def test_unwatch_out_of_range_watcher_id(self): + class C: pass + with self.assertRaisesRegex(ValueError, r"Invalid type watcher ID -1"): + self.unwatch(-1, C) + with self.assertRaisesRegex(ValueError, r"Invalid type watcher ID 8"): + self.unwatch(self.TYPE_MAX_WATCHERS, C) + + def test_unwatch_unassigned_watcher_id(self): + class C: pass + with self.assertRaisesRegex(ValueError, r"No type watcher set for ID 1"): + self.unwatch(1, C) + + def test_clear_out_of_range_watcher_id(self): + with self.assertRaisesRegex(ValueError, r"Invalid type watcher ID -1"): + self.clear_watcher(-1) + with self.assertRaisesRegex(ValueError, r"Invalid type watcher ID 8"): + self.clear_watcher(self.TYPE_MAX_WATCHERS) + + def test_clear_unassigned_watcher_id(self): + with self.assertRaisesRegex(ValueError, r"No type watcher set for ID 1"): + self.clear_watcher(1) + + def test_no_more_ids_available(self): + with self.assertRaisesRegex(RuntimeError, r"no more type watcher IDs"): + with ExitStack() as stack: + for _ in range(self.TYPE_MAX_WATCHERS + 1): + stack.enter_context(self.watcher()) + + +class TestCodeObjectWatchers(unittest.TestCase): + @contextmanager + def code_watcher(self, which_watcher): + wid = _testcapi.add_code_watcher(which_watcher) + try: + yield wid + finally: + _testcapi.clear_code_watcher(wid) + + def assert_event_counts(self, exp_created_0, exp_destroyed_0, + exp_created_1, exp_destroyed_1): + self.assertEqual( + exp_created_0, _testcapi.get_code_watcher_num_created_events(0)) + self.assertEqual( + exp_destroyed_0, _testcapi.get_code_watcher_num_destroyed_events(0)) + self.assertEqual( + exp_created_1, _testcapi.get_code_watcher_num_created_events(1)) + self.assertEqual( + exp_destroyed_1, _testcapi.get_code_watcher_num_destroyed_events(1)) + + def test_code_object_events_dispatched(self): + # verify that all counts are zero before any watchers are registered + self.assert_event_counts(0, 0, 0, 0) + + # verify that all counts remain zero when a code object is + # created and destroyed with no watchers registered + co1 = _testcapi.code_newempty("test_watchers", "dummy1", 0) + self.assert_event_counts(0, 0, 0, 0) + del co1 + self.assert_event_counts(0, 0, 0, 0) + + # verify counts are as expected when first watcher is registered + with self.code_watcher(0): + self.assert_event_counts(0, 0, 0, 0) + co2 = _testcapi.code_newempty("test_watchers", "dummy2", 0) + self.assert_event_counts(1, 0, 0, 0) + del co2 + self.assert_event_counts(1, 1, 0, 0) + + # again with second watcher registered + with self.code_watcher(1): + self.assert_event_counts(1, 1, 0, 0) + co3 = _testcapi.code_newempty("test_watchers", "dummy3", 0) + self.assert_event_counts(2, 1, 1, 0) + del co3 + self.assert_event_counts(2, 2, 1, 1) + + # verify counts are reset and don't change after both watchers are cleared + co4 = _testcapi.code_newempty("test_watchers", "dummy4", 0) + self.assert_event_counts(0, 0, 0, 0) + del co4 + self.assert_event_counts(0, 0, 0, 0) + + def test_error(self): + with self.code_watcher(2): + with catch_unraisable_exception() as cm: + co = _testcapi.code_newempty("test_watchers", "dummy0", 0) + + self.assertEqual( + cm.unraisable.object, + f"PY_CODE_EVENT_CREATE watcher callback for {co!r}" + ) + self.assertEqual(str(cm.unraisable.exc_value), "boom!") + + def test_dealloc_error(self): + co = _testcapi.code_newempty("test_watchers", "dummy0", 0) + with self.code_watcher(2): + with catch_unraisable_exception() as cm: + del co + + self.assertEqual(str(cm.unraisable.exc_value), "boom!") + + def test_clear_out_of_range_watcher_id(self): + with self.assertRaisesRegex(ValueError, r"Invalid code watcher ID -1"): + _testcapi.clear_code_watcher(-1) + with self.assertRaisesRegex(ValueError, r"Invalid code watcher ID 8"): + _testcapi.clear_code_watcher(8) # CODE_MAX_WATCHERS = 8 + + def test_clear_unassigned_watcher_id(self): + with self.assertRaisesRegex(ValueError, r"No code watcher set for ID 1"): + _testcapi.clear_code_watcher(1) + + def test_allocate_too_many_watchers(self): + with self.assertRaisesRegex(RuntimeError, r"no more code watcher IDs available"): + _testcapi.allocate_too_many_code_watchers() + + +class TestFuncWatchers(unittest.TestCase): + @contextmanager + def add_watcher(self, func): + wid = _testcapi.add_func_watcher(func) + try: + yield + finally: + _testcapi.clear_func_watcher(wid) + + def test_func_events_dispatched(self): + events = [] + def watcher(*args): + events.append(args) + + with self.add_watcher(watcher): + def myfunc(): + pass + self.assertIn((_testcapi.PYFUNC_EVENT_CREATE, myfunc, None), events) + myfunc_id = id(myfunc) + + new_code = self.test_func_events_dispatched.__code__ + myfunc.__code__ = new_code + self.assertIn((_testcapi.PYFUNC_EVENT_MODIFY_CODE, myfunc, new_code), events) + + new_defaults = (123,) + myfunc.__defaults__ = new_defaults + self.assertIn((_testcapi.PYFUNC_EVENT_MODIFY_DEFAULTS, myfunc, new_defaults), events) + + new_defaults = (456,) + _testcapi.set_func_defaults_via_capi(myfunc, new_defaults) + self.assertIn((_testcapi.PYFUNC_EVENT_MODIFY_DEFAULTS, myfunc, new_defaults), events) + + new_kwdefaults = {"self": 123} + myfunc.__kwdefaults__ = new_kwdefaults + self.assertIn((_testcapi.PYFUNC_EVENT_MODIFY_KWDEFAULTS, myfunc, new_kwdefaults), events) + + new_kwdefaults = {"self": 456} + _testcapi.set_func_kwdefaults_via_capi(myfunc, new_kwdefaults) + self.assertIn((_testcapi.PYFUNC_EVENT_MODIFY_KWDEFAULTS, myfunc, new_kwdefaults), events) + + # Clear events reference to func + events = [] + del myfunc + self.assertIn((_testcapi.PYFUNC_EVENT_DESTROY, myfunc_id, None), events) + + def test_multiple_watchers(self): + events0 = [] + def first_watcher(*args): + events0.append(args) + + events1 = [] + def second_watcher(*args): + events1.append(args) + + with self.add_watcher(first_watcher): + with self.add_watcher(second_watcher): + def myfunc(): + pass + + event = (_testcapi.PYFUNC_EVENT_CREATE, myfunc, None) + self.assertIn(event, events0) + self.assertIn(event, events1) + + def test_watcher_raises_error(self): + class MyError(Exception): + pass + + def watcher(*args): + raise MyError("testing 123") + + with self.add_watcher(watcher): + with catch_unraisable_exception() as cm: + def myfunc(): + pass + + self.assertEqual( + cm.unraisable.object, + f"PyFunction_EVENT_CREATE watcher callback for {myfunc!r}" + ) + + def test_dealloc_watcher_raises_error(self): + class MyError(Exception): + pass + + def watcher(*args): + raise MyError("testing 123") + + def myfunc(): + pass + + with self.add_watcher(watcher): + with catch_unraisable_exception() as cm: + del myfunc + + self.assertIsInstance(cm.unraisable.exc_value, MyError) + + def test_clear_out_of_range_watcher_id(self): + with self.assertRaisesRegex(ValueError, r"invalid func watcher ID -1"): + _testcapi.clear_func_watcher(-1) + with self.assertRaisesRegex(ValueError, r"invalid func watcher ID 8"): + _testcapi.clear_func_watcher(8) # FUNC_MAX_WATCHERS = 8 + + def test_clear_unassigned_watcher_id(self): + with self.assertRaisesRegex(ValueError, r"no func watcher set for ID 1"): + _testcapi.clear_func_watcher(1) + + def test_allocate_too_many_watchers(self): + with self.assertRaisesRegex(RuntimeError, r"no more func watcher IDs"): + _testcapi.allocate_too_many_func_watchers() + + +if __name__ == "__main__": + unittest.main() diff --git a/Lib/test/test_check_c_globals.py b/Lib/test/test_check_c_globals.py deleted file mode 100644 index 898807a5..00000000 --- a/Lib/test/test_check_c_globals.py +++ /dev/null @@ -1,29 +0,0 @@ -import unittest -import test.test_tools -from test.support.warnings_helper import save_restore_warnings_filters - -test.test_tools.skip_if_missing('c-analyzer') -with test.test_tools.imports_under_tool('c-analyzer'): - # gh-95349: Save/restore warnings filters to leave them unchanged. - # Importing the c-analyzer imports docutils which imports pkg_resources - # which adds a warnings filter. - with save_restore_warnings_filters(): - from cpython.__main__ import main - - -class ActualChecks(unittest.TestCase): - - # XXX Also run the check in "make check". - #@unittest.expectedFailure - # Failing on one of the buildbots (see https://bugs.python.org/issue36876). - @unittest.skip('activate this once all the globals have been resolved') - def test_check_c_globals(self): - try: - main('check', {}) - except NotImplementedError: - raise unittest.SkipTest('not supported on this host') - - -if __name__ == '__main__': - # Test needs to be a package, so we can do relative imports. - unittest.main() diff --git a/Lib/test/test_class.py b/Lib/test/test_class.py index 91c53b7c..7a159760 100644 --- a/Lib/test/test_class.py +++ b/Lib/test/test_class.py @@ -445,6 +445,20 @@ class ClassTests(unittest.TestCase): del testme.cardinal self.assertCallStack([('__delattr__', (testme, "cardinal"))]) + def testHasAttrString(self): + import sys + from test.support import import_helper + _testcapi = import_helper.import_module('_testcapi') + + class A: + def __init__(self): + self.attr = 1 + + a = A() + self.assertEqual(_testcapi.object_hasattrstring(a, b"attr"), 1) + self.assertEqual(_testcapi.object_hasattrstring(a, b"noattr"), 0) + self.assertIsNone(sys.exception()) + def testDel(self): x = [] diff --git a/Lib/test/test_clinic.py b/Lib/test/test_clinic.py index a84d24a7..520cc513 100644 --- a/Lib/test/test_clinic.py +++ b/Lib/test/test_clinic.py @@ -3,11 +3,15 @@ # Licensed to the PSF under a contributor agreement. from test import support, test_tools -from test.support import import_helper, os_helper +from test.support import os_helper +from test.support import SHORT_TIMEOUT, requires_subprocess +from test.support.os_helper import TESTFN, unlink +from textwrap import dedent from unittest import TestCase import collections import inspect import os.path +import subprocess import sys import unittest @@ -17,6 +21,19 @@ with test_tools.imports_under_tool('clinic'): from clinic import DSLParser +class _ParserBase(TestCase): + maxDiff = None + + def expect_parser_failure(self, parser, _input): + with support.captured_stdout() as stdout: + with self.assertRaises(SystemExit): + parser(_input) + return stdout.getvalue() + + def parse_function_should_fail(self, _input): + return self.expect_parser_failure(self.parse_function, _input) + + class FakeConverter: def __init__(self, name, args): self.name = name @@ -87,7 +104,15 @@ class FakeClinic: _module_and_class = clinic.Clinic._module_and_class -class ClinicWholeFileTest(TestCase): + +class ClinicWholeFileTest(_ParserBase): + def setUp(self): + self.clinic = clinic.Clinic(clinic.CLanguage(None), filename="test.c") + + def expect_failure(self, raw): + _input = dedent(raw).strip() + return self.expect_parser_failure(self.clinic.parse, _input) + def test_eol(self): # regression test: # clinic's block parser didn't recognize @@ -97,15 +122,217 @@ class ClinicWholeFileTest(TestCase): # so it would spit out an end line for you. # and since you really already had one, # the last line of the block got corrupted. - c = clinic.Clinic(clinic.CLanguage(None), filename="file") raw = "/*[clinic]\nfoo\n[clinic]*/" - cooked = c.parse(raw).splitlines() + cooked = self.clinic.parse(raw).splitlines() end_line = cooked[2].rstrip() # this test is redundant, it's just here explicitly to catch # the regression test so we don't forget what it looked like self.assertNotEqual(end_line, "[clinic]*/[clinic]*/") self.assertEqual(end_line, "[clinic]*/") + def test_mangled_marker_line(self): + raw = """ + /*[clinic input] + [clinic start generated code]*/ + /*[clinic end generated code: foo]*/ + """ + msg = ( + 'Error in file "test.c" on line 3:\n' + "Mangled Argument Clinic marker line: '/*[clinic end generated code: foo]*/'\n" + ) + out = self.expect_failure(raw) + self.assertEqual(out, msg) + + def test_checksum_mismatch(self): + raw = """ + /*[clinic input] + [clinic start generated code]*/ + /*[clinic end generated code: output=0123456789abcdef input=fedcba9876543210]*/ + """ + msg = ( + 'Error in file "test.c" on line 3:\n' + 'Checksum mismatch!\n' + 'Expected: 0123456789abcdef\n' + 'Computed: da39a3ee5e6b4b0d\n' + ) + out = self.expect_failure(raw) + self.assertIn(msg, out) + + def test_garbage_after_stop_line(self): + raw = """ + /*[clinic input] + [clinic start generated code]*/foobarfoobar! + """ + msg = ( + 'Error in file "test.c" on line 2:\n' + "Garbage after stop line: 'foobarfoobar!'\n" + ) + out = self.expect_failure(raw) + self.assertEqual(out, msg) + + def test_whitespace_before_stop_line(self): + raw = """ + /*[clinic input] + [clinic start generated code]*/ + """ + msg = ( + 'Error in file "test.c" on line 2:\n' + "Whitespace is not allowed before the stop line: ' [clinic start generated code]*/'\n" + ) + out = self.expect_failure(raw) + self.assertEqual(out, msg) + + def test_parse_with_body_prefix(self): + clang = clinic.CLanguage(None) + clang.body_prefix = "//" + clang.start_line = "//[{dsl_name} start]" + clang.stop_line = "//[{dsl_name} stop]" + cl = clinic.Clinic(clang, filename="test.c") + raw = dedent(""" + //[clinic start] + //module test + //[clinic stop] + """).strip() + out = cl.parse(raw) + expected = dedent(""" + //[clinic start] + //module test + // + //[clinic stop] + /*[clinic end generated code: output=da39a3ee5e6b4b0d input=65fab8adff58cf08]*/ + """).lstrip() # Note, lstrip() because of the newline + self.assertEqual(out, expected) + + def test_cpp_monitor_fail_nested_block_comment(self): + raw = """ + /* start + /* nested + */ + */ + """ + msg = ( + 'Error in file "test.c" on line 2:\n' + 'Nested block comment!\n' + ) + out = self.expect_failure(raw) + self.assertEqual(out, msg) + + def test_cpp_monitor_fail_invalid_format_noarg(self): + raw = """ + #if + a() + #endif + """ + msg = ( + 'Error in file "test.c" on line 1:\n' + 'Invalid format for #if line: no argument!\n' + ) + out = self.expect_failure(raw) + self.assertEqual(out, msg) + + def test_cpp_monitor_fail_invalid_format_toomanyargs(self): + raw = """ + #ifdef A B + a() + #endif + """ + msg = ( + 'Error in file "test.c" on line 1:\n' + 'Invalid format for #ifdef line: should be exactly one argument!\n' + ) + out = self.expect_failure(raw) + self.assertEqual(out, msg) + + def test_cpp_monitor_fail_no_matching_if(self): + raw = '#else' + msg = ( + 'Error in file "test.c" on line 1:\n' + '#else without matching #if / #ifdef / #ifndef!\n' + ) + out = self.expect_failure(raw) + self.assertEqual(out, msg) + + def test_directive_output_unknown_preset(self): + out = self.expect_failure(""" + /*[clinic input] + output preset nosuchpreset + [clinic start generated code]*/ + """) + msg = "Unknown preset 'nosuchpreset'" + self.assertIn(msg, out) + + def test_directive_output_cant_pop(self): + out = self.expect_failure(""" + /*[clinic input] + output pop + [clinic start generated code]*/ + """) + msg = "Can't 'output pop', stack is empty" + self.assertIn(msg, out) + + def test_directive_output_print(self): + raw = dedent(""" + /*[clinic input] + output print 'I told you once.' + [clinic start generated code]*/ + """) + out = self.clinic.parse(raw) + # The generated output will differ for every run, but we can check that + # it starts with the clinic block, we check that it contains all the + # expected fields, and we check that it contains the checksum line. + self.assertTrue(out.startswith(dedent(""" + /*[clinic input] + output print 'I told you once.' + [clinic start generated code]*/ + """))) + fields = { + "cpp_endif", + "cpp_if", + "docstring_definition", + "docstring_prototype", + "impl_definition", + "impl_prototype", + "methoddef_define", + "methoddef_ifndef", + "parser_definition", + "parser_prototype", + } + for field in fields: + with self.subTest(field=field): + self.assertIn(field, out) + last_line = out.rstrip().split("\n")[-1] + self.assertTrue( + last_line.startswith("/*[clinic end generated code: output=") + ) + + def test_unknown_destination_command(self): + out = self.expect_failure(""" + /*[clinic input] + destination buffer nosuchcommand + [clinic start generated code]*/ + """) + msg = "unknown destination command 'nosuchcommand'" + self.assertIn(msg, out) + + def test_no_access_to_members_in_converter_init(self): + out = self.expect_failure(""" + /*[python input] + class Custom_converter(CConverter): + converter = "some_c_function" + def converter_init(self): + self.function.noaccess + [python start generated code]*/ + /*[clinic input] + module test + test.fn + a: Custom + [clinic start generated code]*/ + """) + msg = ( + "Stepped on a land mine, trying to access attribute 'noaccess':\n" + "Don't access members of self.function inside converter_init!" + ) + self.assertIn(msg, out) class ClinicGroupPermuterTest(TestCase): @@ -153,7 +380,7 @@ class ClinicGroupPermuterTest(TestCase): def test_have_left_options_but_required_is_empty(self): def fn(): clinic.permute_optional_groups(['a'], [], []) - self.assertRaises(AssertionError, fn) + self.assertRaises(ValueError, fn) class ClinicLinearFormatTest(TestCase): @@ -170,43 +397,43 @@ class ClinicLinearFormatTest(TestCase): def test_no_substitution(self): self._test(""" abc - """, """ + """, """ abc - """) + """) def test_empty_substitution(self): self._test(""" abc {name} def - """, """ + """, """ abc def - """, name='') + """, name='') def test_single_line_substitution(self): self._test(""" abc {name} def - """, """ + """, """ abc GARGLE def - """, name='GARGLE') + """, name='GARGLE') def test_multiline_substitution(self): self._test(""" abc {name} def - """, """ + """, """ abc bingle bungle def - """, name='bingle\nbungle\n') + """, name='bingle\nbungle\n') class InertParser: def __init__(self, clinic): @@ -239,9 +466,9 @@ class ClinicBlockParserTest(TestCase): def test_round_trip_1(self): self.round_trip(""" - verbatim text here - lah dee dah -""") + verbatim text here + lah dee dah + """) def test_round_trip_2(self): self.round_trip(""" verbatim text here @@ -284,23 +511,39 @@ xyz """) -class ClinicParserTest(TestCase): +class ClinicParserTest(_ParserBase): + def checkDocstring(self, fn, expected): + self.assertTrue(hasattr(fn, "docstring")) + self.assertEqual(fn.docstring.strip(), + dedent(expected).strip()) + def test_trivial(self): parser = DSLParser(FakeClinic()) - block = clinic.Block("module os\nos.access") + block = clinic.Block(""" + module os + os.access + """) parser.parse(block) module, function = block.signatures self.assertEqual("access", function.name) self.assertEqual("os", module.name) def test_ignore_line(self): - block = self.parse("#\nmodule os\nos.access") + block = self.parse(dedent(""" + # + module os + os.access + """)) module, function = block.signatures self.assertEqual("access", function.name) self.assertEqual("os", module.name) def test_param(self): - function = self.parse_function("module os\nos.access\n path: int") + function = self.parse_function(""" + module os + os.access + path: int + """) self.assertEqual("access", function.name) self.assertEqual(2, len(function.parameters)) p = function.parameters['path'] @@ -308,236 +551,296 @@ class ClinicParserTest(TestCase): self.assertIsInstance(p.converter, clinic.int_converter) def test_param_default(self): - function = self.parse_function("module os\nos.access\n follow_symlinks: bool = True") + function = self.parse_function(""" + module os + os.access + follow_symlinks: bool = True + """) p = function.parameters['follow_symlinks'] self.assertEqual(True, p.default) def test_param_with_continuations(self): - function = self.parse_function("module os\nos.access\n follow_symlinks: \\\n bool \\\n =\\\n True") + function = self.parse_function(r""" + module os + os.access + follow_symlinks: \ + bool \ + = \ + True + """) p = function.parameters['follow_symlinks'] self.assertEqual(True, p.default) def test_param_default_expression(self): - function = self.parse_function("module os\nos.access\n follow_symlinks: int(c_default='MAXSIZE') = sys.maxsize") + function = self.parse_function(""" + module os + os.access + follow_symlinks: int(c_default='MAXSIZE') = sys.maxsize + """) p = function.parameters['follow_symlinks'] self.assertEqual(sys.maxsize, p.default) self.assertEqual("MAXSIZE", p.converter.c_default) - s = self.parse_function_should_fail("module os\nos.access\n follow_symlinks: int = sys.maxsize") - self.assertEqual(s, "Error on line 0:\nWhen you specify a named constant ('sys.maxsize') as your default value,\nyou MUST specify a valid c_default.\n") + expected_msg = ( + "Error on line 0:\n" + "When you specify a named constant ('sys.maxsize') as your default value,\n" + "you MUST specify a valid c_default.\n" + ) + out = self.parse_function_should_fail(""" + module os + os.access + follow_symlinks: int = sys.maxsize + """) + self.assertEqual(out, expected_msg) def test_param_no_docstring(self): function = self.parse_function(""" -module os -os.access - follow_symlinks: bool = True - something_else: str = ''""") + module os + os.access + follow_symlinks: bool = True + something_else: str = '' + """) p = function.parameters['follow_symlinks'] self.assertEqual(3, len(function.parameters)) - self.assertIsInstance(function.parameters['something_else'].converter, clinic.str_converter) + conv = function.parameters['something_else'].converter + self.assertIsInstance(conv, clinic.str_converter) def test_param_default_parameters_out_of_order(self): - s = self.parse_function_should_fail(""" -module os -os.access - follow_symlinks: bool = True - something_else: str""") - self.assertEqual(s, """Error on line 0: -Can't have a parameter without a default ('something_else') -after a parameter with a default! -""") + expected_msg = ( + "Error on line 0:\n" + "Can't have a parameter without a default ('something_else')\n" + "after a parameter with a default!\n" + ) + out = self.parse_function_should_fail(""" + module os + os.access + follow_symlinks: bool = True + something_else: str""") + self.assertEqual(out, expected_msg) def disabled_test_converter_arguments(self): - function = self.parse_function("module os\nos.access\n path: path_t(allow_fd=1)") + function = self.parse_function(""" + module os + os.access + path: path_t(allow_fd=1) + """) p = function.parameters['path'] self.assertEqual(1, p.converter.args['allow_fd']) def test_function_docstring(self): function = self.parse_function(""" -module os -os.stat as os_stat_fn + module os + os.stat as os_stat_fn - path: str - Path to be examined + path: str + Path to be examined -Perform a stat system call on the given path.""") - self.assertEqual(""" -stat($module, /, path) --- + Perform a stat system call on the given path. + """) + self.checkDocstring(function, """ + stat($module, /, path) + -- -Perform a stat system call on the given path. + Perform a stat system call on the given path. - path - Path to be examined -""".strip(), function.docstring) + path + Path to be examined + """) def test_explicit_parameters_in_docstring(self): - function = self.parse_function(""" -module foo -foo.bar - x: int - Documentation for x. - y: int + function = self.parse_function(dedent(""" + module foo + foo.bar + x: int + Documentation for x. + y: int -This is the documentation for foo. + This is the documentation for foo. -Okay, we're done here. -""") - self.assertEqual(""" -bar($module, /, x, y) --- + Okay, we're done here. + """)) + self.checkDocstring(function, """ + bar($module, /, x, y) + -- -This is the documentation for foo. + This is the documentation for foo. - x - Documentation for x. + x + Documentation for x. -Okay, we're done here. -""".strip(), function.docstring) + Okay, we're done here. + """) def test_parser_regression_special_character_in_parameter_column_of_docstring_first_line(self): - function = self.parse_function(""" -module os -os.stat - path: str -This/used to break Clinic! -""") - self.assertEqual("stat($module, /, path)\n--\n\nThis/used to break Clinic!", function.docstring) + function = self.parse_function(dedent(""" + module os + os.stat + path: str + This/used to break Clinic! + """)) + self.checkDocstring(function, """ + stat($module, /, path) + -- + + This/used to break Clinic! + """) def test_c_name(self): - function = self.parse_function("module os\nos.stat as os_stat_fn") + function = self.parse_function(""" + module os + os.stat as os_stat_fn + """) self.assertEqual("os_stat_fn", function.c_basename) def test_return_converter(self): - function = self.parse_function("module os\nos.stat -> int") + function = self.parse_function(""" + module os + os.stat -> int + """) self.assertIsInstance(function.return_converter, clinic.int_return_converter) def test_star(self): - function = self.parse_function("module os\nos.access\n *\n follow_symlinks: bool = True") + function = self.parse_function(""" + module os + os.access + * + follow_symlinks: bool = True + """) p = function.parameters['follow_symlinks'] self.assertEqual(inspect.Parameter.KEYWORD_ONLY, p.kind) self.assertEqual(0, p.group) def test_group(self): - function = self.parse_function("module window\nwindow.border\n [\n ls : int\n ]\n /\n") + function = self.parse_function(""" + module window + window.border + [ + ls: int + ] + / + """) p = function.parameters['ls'] self.assertEqual(1, p.group) def test_left_group(self): function = self.parse_function(""" -module curses -curses.addch - [ - y: int - Y-coordinate. - x: int - X-coordinate. - ] - ch: char - Character to add. - [ - attr: long - Attributes for the character. - ] - / -""") - for name, group in ( + module curses + curses.addch + [ + y: int + Y-coordinate. + x: int + X-coordinate. + ] + ch: char + Character to add. + [ + attr: long + Attributes for the character. + ] + / + """) + dataset = ( ('y', -1), ('x', -1), ('ch', 0), ('attr', 1), - ): - p = function.parameters[name] - self.assertEqual(p.group, group) - self.assertEqual(p.kind, inspect.Parameter.POSITIONAL_ONLY) - self.assertEqual(function.docstring.strip(), """ -addch([y, x,] ch, [attr]) - - - y - Y-coordinate. - x - X-coordinate. - ch - Character to add. - attr - Attributes for the character. - """.strip()) + ) + for name, group in dataset: + with self.subTest(name=name, group=group): + p = function.parameters[name] + self.assertEqual(p.group, group) + self.assertEqual(p.kind, inspect.Parameter.POSITIONAL_ONLY) + self.checkDocstring(function, """ + addch([y, x,] ch, [attr]) + + + y + Y-coordinate. + x + X-coordinate. + ch + Character to add. + attr + Attributes for the character. + """) def test_nested_groups(self): function = self.parse_function(""" -module curses -curses.imaginary - [ - [ - y1: int - Y-coordinate. - y2: int - Y-coordinate. - ] - x1: int - X-coordinate. - x2: int - X-coordinate. - ] - ch: char - Character to add. - [ - attr1: long - Attributes for the character. - attr2: long - Attributes for the character. - attr3: long - Attributes for the character. - [ - attr4: long - Attributes for the character. - attr5: long - Attributes for the character. - attr6: long - Attributes for the character. - ] - ] - / -""") - for name, group in ( + module curses + curses.imaginary + [ + [ + y1: int + Y-coordinate. + y2: int + Y-coordinate. + ] + x1: int + X-coordinate. + x2: int + X-coordinate. + ] + ch: char + Character to add. + [ + attr1: long + Attributes for the character. + attr2: long + Attributes for the character. + attr3: long + Attributes for the character. + [ + attr4: long + Attributes for the character. + attr5: long + Attributes for the character. + attr6: long + Attributes for the character. + ] + ] + / + """) + dataset = ( ('y1', -2), ('y2', -2), ('x1', -1), ('x2', -1), ('ch', 0), ('attr1', 1), ('attr2', 1), ('attr3', 1), ('attr4', 2), ('attr5', 2), ('attr6', 2), - ): - p = function.parameters[name] - self.assertEqual(p.group, group) - self.assertEqual(p.kind, inspect.Parameter.POSITIONAL_ONLY) - - self.assertEqual(function.docstring.strip(), """ -imaginary([[y1, y2,] x1, x2,] ch, [attr1, attr2, attr3, [attr4, attr5, - attr6]]) - - - y1 - Y-coordinate. - y2 - Y-coordinate. - x1 - X-coordinate. - x2 - X-coordinate. - ch - Character to add. - attr1 - Attributes for the character. - attr2 - Attributes for the character. - attr3 - Attributes for the character. - attr4 - Attributes for the character. - attr5 - Attributes for the character. - attr6 - Attributes for the character. - """.strip()) + ) + for name, group in dataset: + with self.subTest(name=name, group=group): + p = function.parameters[name] + self.assertEqual(p.group, group) + self.assertEqual(p.kind, inspect.Parameter.POSITIONAL_ONLY) + + self.checkDocstring(function, """ + imaginary([[y1, y2,] x1, x2,] ch, [attr1, attr2, attr3, [attr4, attr5, + attr6]]) + + + y1 + Y-coordinate. + y2 + Y-coordinate. + x1 + X-coordinate. + x2 + X-coordinate. + ch + Character to add. + attr1 + Attributes for the character. + attr2 + Attributes for the character. + attr3 + Attributes for the character. + attr4 + Attributes for the character. + attr5 + Attributes for the character. + attr6 + Attributes for the character. + """) def parse_function_should_fail(self, s): with support.captured_stdout() as stdout: @@ -546,218 +849,295 @@ imaginary([[y1, y2,] x1, x2,] ch, [attr1, attr2, attr3, [attr4, attr5, return stdout.getvalue() def test_disallowed_grouping__two_top_groups_on_left(self): - s = self.parse_function_should_fail(""" -module foo -foo.two_top_groups_on_left - [ - group1 : int - ] - [ - group2 : int - ] - param: int - """) - self.assertEqual(s, - ('Error on line 0:\n' - 'Function two_top_groups_on_left has an unsupported group configuration. (Unexpected state 2.b)\n')) + expected_msg = ( + 'Error on line 0:\n' + 'Function two_top_groups_on_left has an unsupported group ' + 'configuration. (Unexpected state 2.b)\n' + ) + out = self.parse_function_should_fail(""" + module foo + foo.two_top_groups_on_left + [ + group1 : int + ] + [ + group2 : int + ] + param: int + """) + self.assertEqual(out, expected_msg) def test_disallowed_grouping__two_top_groups_on_right(self): - self.parse_function_should_fail(""" -module foo -foo.two_top_groups_on_right - param: int - [ - group1 : int - ] - [ - group2 : int - ] - """) + out = self.parse_function_should_fail(""" + module foo + foo.two_top_groups_on_right + param: int + [ + group1 : int + ] + [ + group2 : int + ] + """) + msg = ( + "Function two_top_groups_on_right has an unsupported group " + "configuration. (Unexpected state 6.b)" + ) + self.assertIn(msg, out) def test_disallowed_grouping__parameter_after_group_on_right(self): - self.parse_function_should_fail(""" -module foo -foo.parameter_after_group_on_right - param: int - [ - [ - group1 : int - ] - group2 : int - ] - """) + out = self.parse_function_should_fail(""" + module foo + foo.parameter_after_group_on_right + param: int + [ + [ + group1 : int + ] + group2 : int + ] + """) + msg = ( + "Function parameter_after_group_on_right has an unsupported group " + "configuration. (Unexpected state 6.a)" + ) + self.assertIn(msg, out) def test_disallowed_grouping__group_after_parameter_on_left(self): - self.parse_function_should_fail(""" -module foo -foo.group_after_parameter_on_left - [ - group2 : int - [ - group1 : int - ] - ] - param: int - """) + out = self.parse_function_should_fail(""" + module foo + foo.group_after_parameter_on_left + [ + group2 : int + [ + group1 : int + ] + ] + param: int + """) + msg = ( + "Function group_after_parameter_on_left has an unsupported group " + "configuration. (Unexpected state 2.b)" + ) + self.assertIn(msg, out) def test_disallowed_grouping__empty_group_on_left(self): - self.parse_function_should_fail(""" -module foo -foo.empty_group - [ - [ - ] - group2 : int - ] - param: int - """) + out = self.parse_function_should_fail(""" + module foo + foo.empty_group + [ + [ + ] + group2 : int + ] + param: int + """) + msg = ( + "Function empty_group has an empty group.\n" + "All groups must contain at least one parameter." + ) + self.assertIn(msg, out) def test_disallowed_grouping__empty_group_on_right(self): - self.parse_function_should_fail(""" -module foo -foo.empty_group - param: int - [ - [ - ] - group2 : int - ] - """) + out = self.parse_function_should_fail(""" + module foo + foo.empty_group + param: int + [ + [ + ] + group2 : int + ] + """) + msg = ( + "Function empty_group has an empty group.\n" + "All groups must contain at least one parameter." + ) + self.assertIn(msg, out) + + def test_disallowed_grouping__no_matching_bracket(self): + out = self.parse_function_should_fail(""" + module foo + foo.empty_group + param: int + ] + group2: int + ] + """) + msg = "Function empty_group has a ] without a matching [." + self.assertIn(msg, out) def test_no_parameters(self): function = self.parse_function(""" -module foo -foo.bar + module foo + foo.bar -Docstring + Docstring -""") + """) self.assertEqual("bar($module, /)\n--\n\nDocstring", function.docstring) self.assertEqual(1, len(function.parameters)) # self! def test_init_with_no_parameters(self): function = self.parse_function(""" -module foo -class foo.Bar "unused" "notneeded" -foo.Bar.__init__ + module foo + class foo.Bar "unused" "notneeded" + foo.Bar.__init__ + + Docstring -Docstring + """, signatures_in_block=3, function_index=2) -""", signatures_in_block=3, function_index=2) # self is not in the signature self.assertEqual("Bar()\n--\n\nDocstring", function.docstring) # but it *is* a parameter self.assertEqual(1, len(function.parameters)) def test_illegal_module_line(self): - self.parse_function_should_fail(""" -module foo -foo.bar => int - / -""") + out = self.parse_function_should_fail(""" + module foo + foo.bar => int + / + """) + msg = "Illegal function name: foo.bar => int" + self.assertIn(msg, out) def test_illegal_c_basename(self): - self.parse_function_should_fail(""" -module foo -foo.bar as 935 - / -""") + out = self.parse_function_should_fail(""" + module foo + foo.bar as 935 + / + """) + msg = "Illegal C basename: 935" + self.assertIn(msg, out) def test_single_star(self): - self.parse_function_should_fail(""" -module foo -foo.bar - * - * -""") - - def test_parameters_required_after_star_without_initial_parameters_or_docstring(self): - self.parse_function_should_fail(""" -module foo -foo.bar - * -""") - - def test_parameters_required_after_star_without_initial_parameters_with_docstring(self): - self.parse_function_should_fail(""" -module foo -foo.bar - * -Docstring here. -""") - - def test_parameters_required_after_star_with_initial_parameters_without_docstring(self): - self.parse_function_should_fail(""" -module foo -foo.bar - this: int - * -""") - - def test_parameters_required_after_star_with_initial_parameters_and_docstring(self): - self.parse_function_should_fail(""" -module foo -foo.bar - this: int - * -Docstring. -""") + out = self.parse_function_should_fail(""" + module foo + foo.bar + * + * + """) + self.assertIn("Function bar uses '*' more than once.", out) + + def test_parameters_required_after_star(self): + dataset = ( + "module foo\nfoo.bar\n *", + "module foo\nfoo.bar\n *\nDocstring here.", + "module foo\nfoo.bar\n this: int\n *", + "module foo\nfoo.bar\n this: int\n *\nDocstring.", + ) + msg = "Function bar specifies '*' without any parameters afterwards." + for block in dataset: + with self.subTest(block=block): + out = self.parse_function_should_fail(block) + self.assertIn(msg, out) def test_single_slash(self): - self.parse_function_should_fail(""" -module foo -foo.bar - / - / -""") + out = self.parse_function_should_fail(""" + module foo + foo.bar + / + / + """) + msg = ( + "Function bar has an unsupported group configuration. " + "(Unexpected state 0.d)" + ) + self.assertIn(msg, out) + + def test_double_slash(self): + out = self.parse_function_should_fail(""" + module foo + foo.bar + a: int + / + b: int + / + """) + msg = "Function bar uses '/' more than once." + self.assertIn(msg, out) def test_mix_star_and_slash(self): - self.parse_function_should_fail(""" -module foo -foo.bar - x: int - y: int - * - z: int - / -""") + out = self.parse_function_should_fail(""" + module foo + foo.bar + x: int + y: int + * + z: int + / + """) + msg = ( + "Function bar mixes keyword-only and positional-only parameters, " + "which is unsupported." + ) + self.assertIn(msg, out) def test_parameters_not_permitted_after_slash_for_now(self): - self.parse_function_should_fail(""" -module foo -foo.bar - / - x: int -""") + out = self.parse_function_should_fail(""" + module foo + foo.bar + / + x: int + """) + msg = ( + "Function bar has an unsupported group configuration. " + "(Unexpected state 0.d)" + ) + self.assertIn(msg, out) def test_parameters_no_more_than_one_vararg(self): - s = self.parse_function_should_fail(""" -module foo -foo.bar - *vararg1: object - *vararg2: object -""") - self.assertEqual(s, "Error on line 0:\nToo many var args\n") + expected_msg = ( + "Error on line 0:\n" + "Too many var args\n" + ) + out = self.parse_function_should_fail(""" + module foo + foo.bar + *vararg1: object + *vararg2: object + """) + self.assertEqual(out, expected_msg) def test_function_not_at_column_0(self): function = self.parse_function(""" - module foo - foo.bar - x: int - Nested docstring here, goeth. - * - y: str - Not at column 0! -""") - self.assertEqual(""" -bar($module, /, x, *, y) --- - -Not at column 0! - - x - Nested docstring here, goeth. -""".strip(), function.docstring) + module foo + foo.bar + x: int + Nested docstring here, goeth. + * + y: str + Not at column 0! + """) + self.checkDocstring(function, """ + bar($module, /, x, *, y) + -- + + Not at column 0! + + x + Nested docstring here, goeth. + """) + + def test_indent_stack_no_tabs(self): + out = self.parse_function_should_fail(""" + module foo + foo.bar + *vararg1: object + \t*vararg2: object + """) + msg = "Tab characters are illegal in the Clinic DSL." + self.assertIn(msg, out) + + def test_indent_stack_illegal_outdent(self): + out = self.parse_function_should_fail(""" + module foo + foo.bar + a: object + b: object + """) + self.assertIn("Illegal outdent", out) def test_directive(self): c = FakeClinic() @@ -771,7 +1151,187 @@ Not at column 0! def test_legacy_converters(self): block = self.parse('module os\nos.access\n path: "s"') module, function = block.signatures - self.assertIsInstance((function.parameters['path']).converter, clinic.str_converter) + conv = (function.parameters['path']).converter + self.assertIsInstance(conv, clinic.str_converter) + + def test_legacy_converters_non_string_constant_annotation(self): + expected_failure_message = ( + "Error on line 0:\n" + "Annotations must be either a name, a function call, or a string.\n" + ) + dataset = ( + 'module os\nos.access\n path: 42', + 'module os\nos.access\n path: 42.42', + 'module os\nos.access\n path: 42j', + 'module os\nos.access\n path: b"42"', + ) + for block in dataset: + with self.subTest(block=block): + out = self.parse_function_should_fail(block) + self.assertEqual(out, expected_failure_message) + + def test_other_bizarre_things_in_annotations_fail(self): + expected_failure_message = ( + "Error on line 0:\n" + "Annotations must be either a name, a function call, or a string.\n" + ) + dataset = ( + 'module os\nos.access\n path: {"some": "dictionary"}', + 'module os\nos.access\n path: ["list", "of", "strings"]', + 'module os\nos.access\n path: (x for x in range(42))', + ) + for block in dataset: + with self.subTest(block=block): + out = self.parse_function_should_fail(block) + self.assertEqual(out, expected_failure_message) + + def test_kwarg_splats_disallowed_in_function_call_annotations(self): + expected_error_msg = ( + "Error on line 0:\n" + "Cannot use a kwarg splat in a function-call annotation\n" + ) + dataset = ( + 'module fo\nfo.barbaz\n o: bool(**{None: "bang!"})', + 'module fo\nfo.barbaz -> bool(**{None: "bang!"})', + 'module fo\nfo.barbaz -> bool(**{"bang": 42})', + 'module fo\nfo.barbaz\n o: bool(**{"bang": None})', + ) + for fn in dataset: + with self.subTest(fn=fn): + out = self.parse_function_should_fail(fn) + self.assertEqual(out, expected_error_msg) + + def test_self_param_placement(self): + expected_error_msg = ( + "Error on line 0:\n" + "A 'self' parameter, if specified, must be the very first thing " + "in the parameter block.\n" + ) + block = """ + module foo + foo.func + a: int + self: self(type="PyObject *") + """ + out = self.parse_function_should_fail(block) + self.assertEqual(out, expected_error_msg) + + def test_self_param_cannot_be_optional(self): + expected_error_msg = ( + "Error on line 0:\n" + "A 'self' parameter cannot be marked optional.\n" + ) + block = """ + module foo + foo.func + self: self(type="PyObject *") = None + """ + out = self.parse_function_should_fail(block) + self.assertEqual(out, expected_error_msg) + + def test_defining_class_param_placement(self): + expected_error_msg = ( + "Error on line 0:\n" + "A 'defining_class' parameter, if specified, must either be the " + "first thing in the parameter block, or come just after 'self'.\n" + ) + block = """ + module foo + foo.func + self: self(type="PyObject *") + a: int + cls: defining_class + """ + out = self.parse_function_should_fail(block) + self.assertEqual(out, expected_error_msg) + + def test_defining_class_param_cannot_be_optional(self): + expected_error_msg = ( + "Error on line 0:\n" + "A 'defining_class' parameter cannot be marked optional.\n" + ) + block = """ + module foo + foo.func + cls: defining_class(type="PyObject *") = None + """ + out = self.parse_function_should_fail(block) + self.assertEqual(out, expected_error_msg) + + def test_slot_methods_cannot_access_defining_class(self): + block = """ + module foo + class Foo "" "" + Foo.__init__ + cls: defining_class + a: object + """ + msg = "Slot methods cannot access their defining class." + with self.assertRaisesRegex(ValueError, msg): + self.parse_function(block) + + def test_new_must_be_a_class_method(self): + expected_error_msg = ( + "Error on line 0:\n" + "__new__ must be a class method!\n" + ) + out = self.parse_function_should_fail(""" + module foo + class Foo "" "" + Foo.__new__ + """) + self.assertEqual(out, expected_error_msg) + + def test_init_must_be_a_normal_method(self): + expected_error_msg = ( + "Error on line 0:\n" + "__init__ must be a normal method, not a class or static method!\n" + ) + out = self.parse_function_should_fail(""" + module foo + class Foo "" "" + @classmethod + Foo.__init__ + """) + self.assertEqual(out, expected_error_msg) + + def test_unused_param(self): + block = self.parse(""" + module foo + foo.func + fn: object + k: float + i: float(unused=True) + / + * + flag: bool(unused=True) = False + """) + sig = block.signatures[1] # Function index == 1 + params = sig.parameters + conv = lambda fn: params[fn].converter + dataset = ( + {"name": "fn", "unused": False}, + {"name": "k", "unused": False}, + {"name": "i", "unused": True}, + {"name": "flag", "unused": True}, + ) + for param in dataset: + name, unused = param.values() + with self.subTest(name=name, unused=unused): + p = conv(name) + # Verify that the unused flag is parsed correctly. + self.assertEqual(unused, p.unused) + + # Now, check that we'll produce correct code. + decl = p.simple_declaration(in_parser=False) + if unused: + self.assertIn("Py_UNUSED", decl) + else: + self.assertNotIn("Py_UNUSED", decl) + + # Make sure the Py_UNUSED macro is not used in the parser body. + parser_decl = p.simple_declaration(in_parser=True) + self.assertNotIn("Py_UNUSED", parser_decl) def parse(self, text): c = FakeClinic() @@ -794,44 +1354,285 @@ Not at column 0! self.assertEqual(repr(clinic.NULL), '<Null>') # test that fail fails + expected = ( + 'Error in file "clown.txt" on line 69:\n' + 'The igloos are melting!\n' + ) with support.captured_stdout() as stdout: with self.assertRaises(SystemExit): - clinic.fail('The igloos are melting!', filename='clown.txt', line_number=69) - self.assertEqual(stdout.getvalue(), 'Error in file "clown.txt" on line 69:\nThe igloos are melting!\n') + clinic.fail('The igloos are melting!', + filename='clown.txt', line_number=69) + actual = stdout.getvalue() + self.assertEqual(actual, expected) class ClinicExternalTest(TestCase): maxDiff = None + clinic_py = os.path.join(test_tools.toolsdir, "clinic", "clinic.py") + + def _do_test(self, *args, expect_success=True): + with subprocess.Popen( + [sys.executable, "-Xutf8", self.clinic_py, *args], + encoding="utf-8", + bufsize=0, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + ) as proc: + proc.wait() + if expect_success and proc.returncode: + self.fail("".join([*proc.stdout, *proc.stderr])) + stdout = proc.stdout.read() + stderr = proc.stderr.read() + # Clinic never writes to stderr. + self.assertEqual(stderr, "") + return stdout + + def expect_success(self, *args): + return self._do_test(*args) + + def expect_failure(self, *args): + return self._do_test(*args, expect_success=False) def test_external(self): - # bpo-42398: Test that the destination file is left unchanged if the - # content does not change. Moreover, check also that the file - # modification time does not change in this case. - source = support.findfile('clinic.test') + CLINIC_TEST = 'clinic.test.c' + source = support.findfile(CLINIC_TEST) with open(source, 'r', encoding='utf-8') as f: orig_contents = f.read() - with os_helper.temp_dir() as tmp_dir: - testfile = os.path.join(tmp_dir, 'clinic.test.c') - with open(testfile, 'w', encoding='utf-8') as f: - f.write(orig_contents) - old_mtime_ns = os.stat(testfile).st_mtime_ns + # Run clinic CLI and verify that it does not complain. + self.addCleanup(unlink, TESTFN) + out = self.expect_success("-f", "-o", TESTFN, source) + self.assertEqual(out, "") - clinic.parse_file(testfile) - - with open(testfile, 'r', encoding='utf-8') as f: - new_contents = f.read() - new_mtime_ns = os.stat(testfile).st_mtime_ns + with open(TESTFN, 'r', encoding='utf-8') as f: + new_contents = f.read() self.assertEqual(new_contents, orig_contents) + + def test_no_change(self): + # bpo-42398: Test that the destination file is left unchanged if the + # content does not change. Moreover, check also that the file + # modification time does not change in this case. + code = dedent(""" + /*[clinic input] + [clinic start generated code]*/ + /*[clinic end generated code: output=da39a3ee5e6b4b0d input=da39a3ee5e6b4b0d]*/ + """) + with os_helper.temp_dir() as tmp_dir: + fn = os.path.join(tmp_dir, "test.c") + with open(fn, "w", encoding="utf-8") as f: + f.write(code) + pre_mtime = os.stat(fn).st_mtime_ns + self.expect_success(fn) + post_mtime = os.stat(fn).st_mtime_ns # Don't change the file modification time # if the content does not change - self.assertEqual(new_mtime_ns, old_mtime_ns) - - -ac_tester = import_helper.import_module('_testclinic') - + self.assertEqual(pre_mtime, post_mtime) + + def test_cli_force(self): + invalid_input = dedent(""" + /*[clinic input] + output preset block + module test + test.fn + a: int + [clinic start generated code]*/ + + const char *hand_edited = "output block is overwritten"; + /*[clinic end generated code: output=bogus input=bogus]*/ + """) + fail_msg = dedent(""" + Checksum mismatch! + Expected: bogus + Computed: 2ed19 + Suggested fix: remove all generated code including the end marker, + or use the '-f' option. + """) + with os_helper.temp_dir() as tmp_dir: + fn = os.path.join(tmp_dir, "test.c") + with open(fn, "w", encoding="utf-8") as f: + f.write(invalid_input) + # First, run the CLI without -f and expect failure. + # Note, we cannot check the entire fail msg, because the path to + # the tmp file will change for every run. + out = self.expect_failure(fn) + self.assertTrue(out.endswith(fail_msg)) + # Then, force regeneration; success expected. + out = self.expect_success("-f", fn) + self.assertEqual(out, "") + # Verify by checking the checksum. + checksum = ( + "/*[clinic end generated code: " + "output=2124c291eb067d76 input=9543a8d2da235301]*/\n" + ) + with open(fn, 'r', encoding='utf-8') as f: + generated = f.read() + self.assertTrue(generated.endswith(checksum)) + + def test_cli_make(self): + c_code = dedent(""" + /*[clinic input] + [clinic start generated code]*/ + """) + py_code = "pass" + c_files = "file1.c", "file2.c" + py_files = "file1.py", "file2.py" + + def create_files(files, srcdir, code): + for fn in files: + path = os.path.join(srcdir, fn) + with open(path, "w", encoding="utf-8") as f: + f.write(code) + with os_helper.temp_dir() as tmp_dir: + # add some folders, some C files and a Python file + create_files(c_files, tmp_dir, c_code) + create_files(py_files, tmp_dir, py_code) + + # create C files in externals/ dir + ext_path = os.path.join(tmp_dir, "externals") + with os_helper.temp_dir(path=ext_path) as externals: + create_files(c_files, externals, c_code) + + # run clinic in verbose mode with --make on tmpdir + out = self.expect_success("-v", "--make", "--srcdir", tmp_dir) + + # expect verbose mode to only mention the C files in tmp_dir + for filename in c_files: + with self.subTest(filename=filename): + path = os.path.join(tmp_dir, filename) + self.assertIn(path, out) + for filename in py_files: + with self.subTest(filename=filename): + path = os.path.join(tmp_dir, filename) + self.assertNotIn(path, out) + # don't expect C files from the externals dir + for filename in c_files: + with self.subTest(filename=filename): + path = os.path.join(ext_path, filename) + self.assertNotIn(path, out) + + def test_cli_verbose(self): + with os_helper.temp_dir() as tmp_dir: + fn = os.path.join(tmp_dir, "test.c") + with open(fn, "w", encoding="utf-8") as f: + f.write("") + out = self.expect_success("-v", fn) + self.assertEqual(out.strip(), fn) + + def test_cli_help(self): + out = self.expect_success("-h") + self.assertIn("usage: clinic.py", out) + + def test_cli_converters(self): + prelude = dedent(""" + Legacy converters: + B C D L O S U Y Z Z# + b c d f h i l p s s# s* u u# w* y y# y* z z# z* + + Converters: + """) + expected_converters = ( + "bool", + "byte", + "char", + "defining_class", + "double", + "fildes", + "float", + "int", + "long", + "long_long", + "object", + "Py_buffer", + "Py_complex", + "Py_ssize_t", + "Py_UNICODE", + "PyByteArrayObject", + "PyBytesObject", + "self", + "short", + "size_t", + "slice_index", + "str", + "unicode", + "unsigned_char", + "unsigned_int", + "unsigned_long", + "unsigned_long_long", + "unsigned_short", + ) + finale = dedent(""" + Return converters: + bool() + double() + float() + init() + int() + long() + Py_ssize_t() + size_t() + unsigned_int() + unsigned_long() + + All converters also accept (c_default=None, py_default=None, annotation=None). + All return converters also accept (py_default=None). + """) + out = self.expect_success("--converters") + # We cannot simply compare the output, because the repr of the *accept* + # param may change (it's a set, thus unordered). So, let's compare the + # start and end of the expected output, and then assert that the + # converters appear lined up in alphabetical order. + self.assertTrue(out.startswith(prelude), out) + self.assertTrue(out.endswith(finale), out) + + out = out.removeprefix(prelude) + out = out.removesuffix(finale) + lines = out.split("\n") + for converter, line in zip(expected_converters, lines): + line = line.lstrip() + with self.subTest(converter=converter): + self.assertTrue( + line.startswith(converter), + f"expected converter {converter!r}, got {line!r}" + ) + + def test_cli_fail_converters_and_filename(self): + out = self.expect_failure("--converters", "test.c") + msg = ( + "Usage error: can't specify --converters " + "and a filename at the same time" + ) + self.assertIn(msg, out) + + def test_cli_fail_no_filename(self): + out = self.expect_failure() + self.assertIn("usage: clinic.py", out) + + def test_cli_fail_output_and_multiple_files(self): + out = self.expect_failure("-o", "out.c", "input.c", "moreinput.c") + msg = "Usage error: can't use -o with multiple filenames" + self.assertIn(msg, out) + + def test_cli_fail_filename_or_output_and_make(self): + for opts in ("-o", "out.c"), ("filename.c",): + with self.subTest(opts=opts): + out = self.expect_failure("--make", *opts) + msg = "Usage error: can't use -o or filenames with --make" + self.assertIn(msg, out) + + def test_cli_fail_make_without_srcdir(self): + out = self.expect_failure("--make", "--srcdir", "") + msg = "Usage error: --srcdir must not be empty with --make" + self.assertIn(msg, out) + + +try: + import _testclinic as ac_tester +except ImportError: + ac_tester = None + +@unittest.skipIf(ac_tester is None, "_testclinic is missing") class ClinicFunctionalTest(unittest.TestCase): locals().update((name, getattr(ac_tester, name)) for name in dir(ac_tester) if name.startswith('test_')) @@ -1284,6 +2085,289 @@ class ClinicFunctionalTest(unittest.TestCase): with self.assertRaisesRegex(TypeError, expected_error): ac_tester.gh_99240_double_free('a', '\0b') + def test_cloned_func_exception_message(self): + incorrect_arg = -1 # f1() and f2() accept a single str + with self.assertRaisesRegex(TypeError, "clone_f1"): + ac_tester.clone_f1(incorrect_arg) + with self.assertRaisesRegex(TypeError, "clone_f2"): + ac_tester.clone_f2(incorrect_arg) + + def test_cloned_func_with_converter_exception_message(self): + for name in "clone_with_conv_f1", "clone_with_conv_f2": + with self.subTest(name=name): + func = getattr(ac_tester, name) + self.assertEqual(func(), name) + + +class PermutationTests(unittest.TestCase): + """Test permutation support functions.""" + + def test_permute_left_option_groups(self): + expected = ( + (), + (3,), + (2, 3), + (1, 2, 3), + ) + data = list(zip([1, 2, 3])) # Generate a list of 1-tuples. + actual = tuple(clinic.permute_left_option_groups(data)) + self.assertEqual(actual, expected) + + def test_permute_right_option_groups(self): + expected = ( + (), + (1,), + (1, 2), + (1, 2, 3), + ) + data = list(zip([1, 2, 3])) # Generate a list of 1-tuples. + actual = tuple(clinic.permute_right_option_groups(data)) + self.assertEqual(actual, expected) + + def test_permute_optional_groups(self): + empty = { + "left": (), "required": (), "right": (), + "expected": ((),), + } + noleft1 = { + "left": (), "required": ("b",), "right": ("c",), + "expected": ( + ("b",), + ("b", "c"), + ), + } + noleft2 = { + "left": (), "required": ("b", "c",), "right": ("d",), + "expected": ( + ("b", "c"), + ("b", "c", "d"), + ), + } + noleft3 = { + "left": (), "required": ("b", "c",), "right": ("d", "e"), + "expected": ( + ("b", "c"), + ("b", "c", "d"), + ("b", "c", "d", "e"), + ), + } + noright1 = { + "left": ("a",), "required": ("b",), "right": (), + "expected": ( + ("b",), + ("a", "b"), + ), + } + noright2 = { + "left": ("a",), "required": ("b", "c"), "right": (), + "expected": ( + ("b", "c"), + ("a", "b", "c"), + ), + } + noright3 = { + "left": ("a", "b"), "required": ("c",), "right": (), + "expected": ( + ("c",), + ("b", "c"), + ("a", "b", "c"), + ), + } + leftandright1 = { + "left": ("a",), "required": ("b",), "right": ("c",), + "expected": ( + ("b",), + ("a", "b"), # Prefer left. + ("a", "b", "c"), + ), + } + leftandright2 = { + "left": ("a", "b"), "required": ("c", "d"), "right": ("e", "f"), + "expected": ( + ("c", "d"), + ("b", "c", "d"), # Prefer left. + ("a", "b", "c", "d"), # Prefer left. + ("a", "b", "c", "d", "e"), + ("a", "b", "c", "d", "e", "f"), + ), + } + dataset = ( + empty, + noleft1, noleft2, noleft3, + noright1, noright2, noright3, + leftandright1, leftandright2, + ) + for params in dataset: + with self.subTest(**params): + left, required, right, expected = params.values() + permutations = clinic.permute_optional_groups(left, required, right) + actual = tuple(permutations) + self.assertEqual(actual, expected) + + +class FormatHelperTests(unittest.TestCase): + + def test_strip_leading_and_trailing_blank_lines(self): + dataset = ( + # Input lines, expected output. + ("a\nb", "a\nb"), + ("a\nb\n", "a\nb"), + ("a\nb ", "a\nb"), + ("\na\nb\n\n", "a\nb"), + ("\n\na\nb\n\n", "a\nb"), + ("\n\na\n\nb\n\n", "a\n\nb"), + # Note, leading whitespace is preserved: + (" a\nb", " a\nb"), + (" a\nb ", " a\nb"), + (" \n \n a\nb \n \n ", " a\nb"), + ) + for lines, expected in dataset: + with self.subTest(lines=lines, expected=expected): + out = clinic.strip_leading_and_trailing_blank_lines(lines) + self.assertEqual(out, expected) + + def test_normalize_snippet(self): + snippet = """ + one + two + three + """ + + # Expected outputs: + zero_indent = ( + "one\n" + "two\n" + "three" + ) + four_indent = ( + " one\n" + " two\n" + " three" + ) + eight_indent = ( + " one\n" + " two\n" + " three" + ) + expected_outputs = {0: zero_indent, 4: four_indent, 8: eight_indent} + for indent, expected in expected_outputs.items(): + with self.subTest(indent=indent): + actual = clinic.normalize_snippet(snippet, indent=indent) + self.assertEqual(actual, expected) + + def test_accumulator(self): + acc = clinic.text_accumulator() + self.assertEqual(acc.output(), "") + acc.append("a") + self.assertEqual(acc.output(), "a") + self.assertEqual(acc.output(), "") + acc.append("b") + self.assertEqual(acc.output(), "b") + self.assertEqual(acc.output(), "") + acc.append("c") + acc.append("d") + self.assertEqual(acc.output(), "cd") + self.assertEqual(acc.output(), "") + + def test_quoted_for_c_string(self): + dataset = ( + # input, expected + (r"abc", r"abc"), + (r"\abc", r"\\abc"), + (r"\a\bc", r"\\a\\bc"), + (r"\a\\bc", r"\\a\\\\bc"), + (r'"abc"', r'\"abc\"'), + (r"'a'", r"\'a\'"), + ) + for line, expected in dataset: + with self.subTest(line=line, expected=expected): + out = clinic.quoted_for_c_string(line) + self.assertEqual(out, expected) + + def test_rstrip_lines(self): + lines = ( + "a \n" + "b\n" + " c\n" + " d \n" + ) + expected = ( + "a\n" + "b\n" + " c\n" + " d\n" + ) + out = clinic.rstrip_lines(lines) + self.assertEqual(out, expected) + + def test_format_escape(self): + line = "{}, {a}" + expected = "{{}}, {{a}}" + out = clinic.format_escape(line) + self.assertEqual(out, expected) + + def test_indent_all_lines(self): + # Blank lines are expected to be unchanged. + self.assertEqual(clinic.indent_all_lines("", prefix="bar"), "") + + lines = ( + "one\n" + "two" # The missing newline is deliberate. + ) + expected = ( + "barone\n" + "bartwo" + ) + out = clinic.indent_all_lines(lines, prefix="bar") + self.assertEqual(out, expected) + + # If last line is empty, expect it to be unchanged. + lines = ( + "\n" + "one\n" + "two\n" + "" + ) + expected = ( + "bar\n" + "barone\n" + "bartwo\n" + "" + ) + out = clinic.indent_all_lines(lines, prefix="bar") + self.assertEqual(out, expected) + + def test_suffix_all_lines(self): + # Blank lines are expected to be unchanged. + self.assertEqual(clinic.suffix_all_lines("", suffix="foo"), "") + + lines = ( + "one\n" + "two" # The missing newline is deliberate. + ) + expected = ( + "onefoo\n" + "twofoo" + ) + out = clinic.suffix_all_lines(lines, suffix="foo") + self.assertEqual(out, expected) + + # If last line is empty, expect it to be unchanged. + lines = ( + "\n" + "one\n" + "two\n" + "" + ) + expected = ( + "foo\n" + "onefoo\n" + "twofoo\n" + "" + ) + out = clinic.suffix_all_lines(lines, suffix="foo") + self.assertEqual(out, expected) + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_cmath.py b/Lib/test/test_cmath.py index 4bdec6d2..57f80d5d 100644 --- a/Lib/test/test_cmath.py +++ b/Lib/test/test_cmath.py @@ -166,6 +166,11 @@ class CMathTests(unittest.TestCase): self.assertEqual(cmath.nan.imag, 0.0) self.assertEqual(cmath.nanj.real, 0.0) self.assertTrue(math.isnan(cmath.nanj.imag)) + # Also check that the sign of all of these is positive: + self.assertEqual(math.copysign(1., cmath.nan.real), 1.) + self.assertEqual(math.copysign(1., cmath.nan.imag), 1.) + self.assertEqual(math.copysign(1., cmath.nanj.real), 1.) + self.assertEqual(math.copysign(1., cmath.nanj.imag), 1.) # Check consistency with reprs. self.assertEqual(repr(cmath.inf), "inf") @@ -192,14 +197,7 @@ class CMathTests(unittest.TestCase): # end up being passed to the cmath functions # usual case: new-style class implementing __complex__ - class MyComplex(object): - def __init__(self, value): - self.value = value - def __complex__(self): - return self.value - - # old-style class implementing __complex__ - class MyComplexOS: + class MyComplex: def __init__(self, value): self.value = value def __complex__(self): @@ -208,18 +206,13 @@ class CMathTests(unittest.TestCase): # classes for which __complex__ raises an exception class SomeException(Exception): pass - class MyComplexException(object): - def __complex__(self): - raise SomeException - class MyComplexExceptionOS: + class MyComplexException: def __complex__(self): raise SomeException # some classes not providing __float__ or __complex__ class NeitherComplexNorFloat(object): pass - class NeitherComplexNorFloatOS: - pass class Index: def __int__(self): return 2 def __index__(self): return 2 @@ -228,48 +221,32 @@ class CMathTests(unittest.TestCase): # other possible combinations of __float__ and __complex__ # that should work - class FloatAndComplex(object): + class FloatAndComplex: def __float__(self): return flt_arg def __complex__(self): return cx_arg - class FloatAndComplexOS: - def __float__(self): - return flt_arg - def __complex__(self): - return cx_arg - class JustFloat(object): - def __float__(self): - return flt_arg - class JustFloatOS: + class JustFloat: def __float__(self): return flt_arg for f in self.test_functions: # usual usage self.assertEqual(f(MyComplex(cx_arg)), f(cx_arg)) - self.assertEqual(f(MyComplexOS(cx_arg)), f(cx_arg)) # other combinations of __float__ and __complex__ self.assertEqual(f(FloatAndComplex()), f(cx_arg)) - self.assertEqual(f(FloatAndComplexOS()), f(cx_arg)) self.assertEqual(f(JustFloat()), f(flt_arg)) - self.assertEqual(f(JustFloatOS()), f(flt_arg)) self.assertEqual(f(Index()), f(int(Index()))) # TypeError should be raised for classes not providing # either __complex__ or __float__, even if they provide - # __int__ or __index__. An old-style class - # currently raises AttributeError instead of a TypeError; - # this could be considered a bug. + # __int__ or __index__: self.assertRaises(TypeError, f, NeitherComplexNorFloat()) self.assertRaises(TypeError, f, MyInt()) - self.assertRaises(Exception, f, NeitherComplexNorFloatOS()) # non-complex return value from __complex__ -> TypeError for bad_complex in non_complexes: self.assertRaises(TypeError, f, MyComplex(bad_complex)) - self.assertRaises(TypeError, f, MyComplexOS(bad_complex)) # exceptions in __complex__ should be propagated correctly self.assertRaises(SomeException, f, MyComplexException()) - self.assertRaises(SomeException, f, MyComplexExceptionOS()) def test_input_type(self): # ints should be acceptable inputs to all cmath @@ -635,6 +612,14 @@ class IsCloseTests(test_math.IsCloseTests): self.assertIsClose(0.001-0.001j, 0.001+0.001j, abs_tol=2e-03) self.assertIsNotClose(0.001-0.001j, 0.001+0.001j, abs_tol=1e-03) + def test_complex_special(self): + self.assertIsNotClose(INF, INF*1j) + self.assertIsNotClose(INF*1j, INF) + self.assertIsNotClose(INF, -INF) + self.assertIsNotClose(-INF, INF) + self.assertIsNotClose(0, INF) + self.assertIsNotClose(0, INF*1j) + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_cmd_line.py b/Lib/test/test_cmd_line.py index 1c33be28..94298003 100644 --- a/Lib/test/test_cmd_line.py +++ b/Lib/test/test_cmd_line.py @@ -18,9 +18,6 @@ from test.support.script_helper import ( if not support.has_subprocess_support: raise unittest.SkipTest("test module requires subprocess") -# Debug build? -Py_DEBUG = hasattr(sys, "gettotalrefcount") - # XXX (ncoghlan): Move to script_helper and make consistent with run_python def _kill_python_and_exit_code(p): @@ -134,7 +131,7 @@ class CmdLineTest(unittest.TestCase): # "-X showrefcount" shows the refcount, but only in debug builds rc, out, err = run_python('-I', '-X', 'showrefcount', '-c', code) self.assertEqual(out.rstrip(), b"{'showrefcount': True}") - if Py_DEBUG: + if support.Py_DEBUG: # bpo-46417: Tolerate negative reference count which can occur # because of bugs in C extensions. This test is only about checking # the showrefcount feature. @@ -696,7 +693,7 @@ class CmdLineTest(unittest.TestCase): code = ("import warnings; " "print(' '.join('%s::%s' % (f[0], f[2].__name__) " "for f in warnings.filters))") - if Py_DEBUG: + if support.Py_DEBUG: expected_filters = "default::Warning" else: expected_filters = ("default::Warning " @@ -768,7 +765,7 @@ class CmdLineTest(unittest.TestCase): expected_filters = ("error::BytesWarning " "once::UserWarning " "always::UserWarning") - if not Py_DEBUG: + if not support.Py_DEBUG: expected_filters += (" " "default::DeprecationWarning " "ignore::DeprecationWarning " @@ -806,10 +803,10 @@ class CmdLineTest(unittest.TestCase): # Test the PYTHONMALLOC environment variable pymalloc = support.with_pymalloc() if pymalloc: - default_name = 'pymalloc_debug' if Py_DEBUG else 'pymalloc' + default_name = 'pymalloc_debug' if support.Py_DEBUG else 'pymalloc' default_name_debug = 'pymalloc_debug' else: - default_name = 'malloc_debug' if Py_DEBUG else 'malloc' + default_name = 'malloc_debug' if support.Py_DEBUG else 'malloc' default_name_debug = 'malloc_debug' tests = [ @@ -885,7 +882,8 @@ class CmdLineTest(unittest.TestCase): return tuple(int(i) for i in out.split()) res = assert_python_ok('-c', code) - self.assertEqual(res2int(res), (-1, sys.get_int_max_str_digits())) + current_max = sys.get_int_max_str_digits() + self.assertEqual(res2int(res), (current_max, current_max)) res = assert_python_ok('-X', 'int_max_str_digits=0', '-c', code) self.assertEqual(res2int(res), (0, 0)) res = assert_python_ok('-X', 'int_max_str_digits=4000', '-c', code) diff --git a/Lib/test/test_cmd_line_script.py b/Lib/test/test_cmd_line_script.py index 4dadbc0b..1b588826 100644 --- a/Lib/test/test_cmd_line_script.py +++ b/Lib/test/test_cmd_line_script.py @@ -636,9 +636,9 @@ class CmdLineTest(unittest.TestCase): self.assertEqual( stderr.splitlines()[-3:], [ - b' foo"""', - b' ^', - b'SyntaxError: f-string: empty expression not allowed', + b' foo = f"""{}', + b' ^', + b'SyntaxError: f-string: valid expression required before \'}\'', ], ) @@ -657,6 +657,31 @@ class CmdLineTest(unittest.TestCase): ], ) + def test_syntaxerror_null_bytes(self): + script = "x = '\0' nothing to see here\n';import os;os.system('echo pwnd')\n" + with os_helper.temp_dir() as script_dir: + script_name = _make_test_script(script_dir, 'script', script) + exitcode, stdout, stderr = assert_python_failure(script_name) + self.assertEqual( + stderr.splitlines()[-2:], + [ b" x = '", + b'SyntaxError: source code cannot contain null bytes' + ], + ) + + def test_syntaxerror_null_bytes_in_multiline_string(self): + scripts = ["\n'''\nmultilinestring\0\n'''", "\nf'''\nmultilinestring\0\n'''"] # Both normal and f-strings + with os_helper.temp_dir() as script_dir: + for script in scripts: + script_name = _make_test_script(script_dir, 'script', script) + _, _, stderr = assert_python_failure(script_name) + self.assertEqual( + stderr.splitlines()[-2:], + [ b" multilinestring", + b'SyntaxError: source code cannot contain null bytes' + ] + ) + def test_consistent_sys_path_for_direct_execution(self): # This test case ensures that the following all give the same # sys.path configuration: @@ -752,7 +777,7 @@ class CmdLineTest(unittest.TestCase): with os_helper.temp_dir() as work_dir: script_name = _make_test_script(work_dir, 'script.py', script) with open(script_name, "r") as fp: - p = spawn_python(f"/dev/fd/{fp.fileno()}", close_fds=False, pass_fds=(0,1,2,fp.fileno())) + p = spawn_python(f"/dev/fd/{fp.fileno()}", close_fds=True, pass_fds=(0,1,2,fp.fileno())) out, err = p.communicate() self.assertEqual(out, b"12345678912345678912345\n") diff --git a/Lib/test/test_code.py b/Lib/test/test_code.py index d3e20129..ca06a39f 100644 --- a/Lib/test/test_code.py +++ b/Lib/test/test_code.py @@ -143,7 +143,7 @@ from test.support import (cpython_only, gc_collect) from test.support.script_helper import assert_python_ok from test.support import threading_helper -from opcode import opmap +from opcode import opmap, opname COPY_FREE_VARS = opmap['COPY_FREE_VARS'] @@ -338,6 +338,28 @@ class CodeTest(unittest.TestCase): new_code = code = func.__code__.replace(co_linetable=b'') self.assertEqual(list(new_code.co_lines()), []) + def test_co_lnotab_is_deprecated(self): # TODO: remove in 3.14 + def func(): + pass + + with self.assertWarns(DeprecationWarning): + func.__code__.co_lnotab + + def test_invalid_bytecode(self): + def foo(): + pass + + # assert that opcode 229 is invalid + self.assertEqual(opname[229], '<229>') + + # change first opcode to 0xeb (=229) + foo.__code__ = foo.__code__.replace( + co_code=b'\xe5' + foo.__code__.co_code[1:]) + + msg = "unknown opcode 229" + with self.assertRaisesRegex(SystemError, msg): + foo() + @requires_debug_ranges() def test_co_positions_artificial_instructions(self): import dis @@ -450,6 +472,32 @@ class CodeTest(unittest.TestCase): self.assertNotEqual(code_b, code_d) self.assertNotEqual(code_c, code_d) + def test_code_hash_uses_firstlineno(self): + c1 = (lambda: 1).__code__ + c2 = (lambda: 1).__code__ + self.assertNotEqual(c1, c2) + self.assertNotEqual(hash(c1), hash(c2)) + c3 = c1.replace(co_firstlineno=17) + self.assertNotEqual(c1, c3) + self.assertNotEqual(hash(c1), hash(c3)) + + def test_code_hash_uses_order(self): + # Swapping posonlyargcount and kwonlyargcount should change the hash. + c = (lambda x, y, *, z=1, w=1: 1).__code__ + self.assertEqual(c.co_argcount, 2) + self.assertEqual(c.co_posonlyargcount, 0) + self.assertEqual(c.co_kwonlyargcount, 2) + swapped = c.replace(co_posonlyargcount=2, co_kwonlyargcount=0) + self.assertNotEqual(c, swapped) + self.assertNotEqual(hash(c), hash(swapped)) + + def test_code_hash_uses_bytecode(self): + c = (lambda x, y: x + y).__code__ + d = (lambda x, y: x * y).__code__ + c1 = c.replace(co_code=d.co_code) + self.assertNotEqual(c, c1) + self.assertNotEqual(hash(c), hash(c1)) + def isinterned(s): return s is sys.intern(('_' + s + '_')[1:-1]) @@ -661,7 +709,8 @@ class CodeLocationTest(unittest.TestCase): def check_lines(self, func): co = func.__code__ - lines1 = list(dedup(l for (_, _, l) in co.co_lines())) + lines1 = [line for _, _, line in co.co_lines()] + self.assertEqual(lines1, list(dedup(lines1))) lines2 = list(lines_from_postions(positions_from_location_table(co))) for l1, l2 in zip(lines1, lines2): self.assertEqual(l1, l2) @@ -681,6 +730,7 @@ class CodeLocationTest(unittest.TestCase): pass PY_CODE_LOCATION_INFO_NO_COLUMNS = 13 f.__code__ = f.__code__.replace( + co_stacksize=1, co_firstlineno=42, co_code=bytes( [ @@ -709,15 +759,15 @@ if check_impl_detail(cpython=True) and ctypes is not None: py = ctypes.pythonapi freefunc = ctypes.CFUNCTYPE(None,ctypes.c_voidp) - RequestCodeExtraIndex = py._PyEval_RequestCodeExtraIndex + RequestCodeExtraIndex = py.PyUnstable_Eval_RequestCodeExtraIndex RequestCodeExtraIndex.argtypes = (freefunc,) RequestCodeExtraIndex.restype = ctypes.c_ssize_t - SetExtra = py._PyCode_SetExtra + SetExtra = py.PyUnstable_Code_SetExtra SetExtra.argtypes = (ctypes.py_object, ctypes.c_ssize_t, ctypes.c_voidp) SetExtra.restype = ctypes.c_int - GetExtra = py._PyCode_GetExtra + GetExtra = py.PyUnstable_Code_GetExtra GetExtra.argtypes = (ctypes.py_object, ctypes.c_ssize_t, ctypes.POINTER(ctypes.c_voidp)) GetExtra.restype = ctypes.c_int diff --git a/Lib/test/test_codecs.py b/Lib/test/test_codecs.py index 934e4bb3..91d7eaf9 100644 --- a/Lib/test/test_codecs.py +++ b/Lib/test/test_codecs.py @@ -9,7 +9,6 @@ from unittest import mock from test import support from test.support import os_helper -from test.support import warnings_helper try: import _testcapi @@ -1554,7 +1553,7 @@ class IDNACodecTest(unittest.TestCase): self.assertEqual("pyth\xf6n.org.".encode("idna"), b"xn--pythn-mua.org.") def test_builtin_decode_length_limit(self): - with self.assertRaisesRegex(UnicodeError, "too long"): + with self.assertRaisesRegex(UnicodeError, "way too long"): (b"xn--016c"+b"a"*1100).decode("idna") with self.assertRaisesRegex(UnicodeError, "too long"): (b"xn--016c"+b"a"*70).decode("idna") @@ -2820,24 +2819,20 @@ class TransformCodecTest(unittest.TestCase): self.assertIsNone(failure.exception.__cause__) @unittest.skipUnless(zlib, "Requires zlib support") - def test_custom_zlib_error_is_wrapped(self): + def test_custom_zlib_error_is_noted(self): # Check zlib codec gives a good error for malformed input - msg = "^decoding with 'zlib_codec' codec failed" - with self.assertRaisesRegex(Exception, msg) as failure: + msg = "decoding with 'zlib_codec' codec failed" + with self.assertRaises(zlib.error) as failure: codecs.decode(b"hello", "zlib_codec") - self.assertIsInstance(failure.exception.__cause__, - type(failure.exception)) + self.assertEqual(msg, failure.exception.__notes__[0]) - def test_custom_hex_error_is_wrapped(self): + def test_custom_hex_error_is_noted(self): # Check hex codec gives a good error for malformed input - msg = "^decoding with 'hex_codec' codec failed" - with self.assertRaisesRegex(Exception, msg) as failure: + import binascii + msg = "decoding with 'hex_codec' codec failed" + with self.assertRaises(binascii.Error) as failure: codecs.decode(b"hello", "hex_codec") - self.assertIsInstance(failure.exception.__cause__, - type(failure.exception)) - - # Unfortunately, the bz2 module throws OSError, which the codec - # machinery currently can't wrap :( + self.assertEqual(msg, failure.exception.__notes__[0]) # Ensure codec aliases from http://bugs.python.org/issue7475 work def test_aliases(self): @@ -2861,11 +2856,8 @@ class TransformCodecTest(unittest.TestCase): self.assertRaises(ValueError, codecs.decode, b"", "uu-codec") -# The codec system tries to wrap exceptions in order to ensure the error -# mentions the operation being performed and the codec involved. We -# currently *only* want this to happen for relatively stateless -# exceptions, where the only significant information they contain is their -# type and a single str argument. +# The codec system tries to add notes to exceptions in order to ensure +# the error mentions the operation being performed and the codec involved. # Use a local codec registry to avoid appearing to leak objects when # registering multiple search functions @@ -2875,10 +2867,10 @@ def _get_test_codec(codec_name): return _TEST_CODECS.get(codec_name) -class ExceptionChainingTest(unittest.TestCase): +class ExceptionNotesTest(unittest.TestCase): def setUp(self): - self.codec_name = 'exception_chaining_test' + self.codec_name = 'exception_notes_test' codecs.register(_get_test_codec) self.addCleanup(codecs.unregister, _get_test_codec) @@ -2902,91 +2894,77 @@ class ExceptionChainingTest(unittest.TestCase): _TEST_CODECS[self.codec_name] = codec_info @contextlib.contextmanager - def assertWrapped(self, operation, exc_type, msg): - full_msg = r"{} with {!r} codec failed \({}: {}\)".format( - operation, self.codec_name, exc_type.__name__, msg) - with self.assertRaisesRegex(exc_type, full_msg) as caught: + def assertNoted(self, operation, exc_type, msg): + full_msg = r"{} with {!r} codec failed".format( + operation, self.codec_name) + with self.assertRaises(exc_type) as caught: yield caught - self.assertIsInstance(caught.exception.__cause__, exc_type) - self.assertIsNotNone(caught.exception.__cause__.__traceback__) + self.assertIn(full_msg, caught.exception.__notes__[0]) + caught.exception.__notes__.clear() def raise_obj(self, *args, **kwds): # Helper to dynamically change the object raised by a test codec raise self.obj_to_raise - def check_wrapped(self, obj_to_raise, msg, exc_type=RuntimeError): + def check_note(self, obj_to_raise, msg, exc_type=RuntimeError): self.obj_to_raise = obj_to_raise self.set_codec(self.raise_obj, self.raise_obj) - with self.assertWrapped("encoding", exc_type, msg): + with self.assertNoted("encoding", exc_type, msg): "str_input".encode(self.codec_name) - with self.assertWrapped("encoding", exc_type, msg): + with self.assertNoted("encoding", exc_type, msg): codecs.encode("str_input", self.codec_name) - with self.assertWrapped("decoding", exc_type, msg): + with self.assertNoted("decoding", exc_type, msg): b"bytes input".decode(self.codec_name) - with self.assertWrapped("decoding", exc_type, msg): + with self.assertNoted("decoding", exc_type, msg): codecs.decode(b"bytes input", self.codec_name) def test_raise_by_type(self): - self.check_wrapped(RuntimeError, "") + self.check_note(RuntimeError, "") def test_raise_by_value(self): - msg = "This should be wrapped" - self.check_wrapped(RuntimeError(msg), msg) + msg = "This should be noted" + self.check_note(RuntimeError(msg), msg) def test_raise_grandchild_subclass_exact_size(self): - msg = "This should be wrapped" + msg = "This should be noted" class MyRuntimeError(RuntimeError): __slots__ = () - self.check_wrapped(MyRuntimeError(msg), msg, MyRuntimeError) + self.check_note(MyRuntimeError(msg), msg, MyRuntimeError) def test_raise_subclass_with_weakref_support(self): - msg = "This should be wrapped" + msg = "This should be noted" class MyRuntimeError(RuntimeError): pass - self.check_wrapped(MyRuntimeError(msg), msg, MyRuntimeError) - - def check_not_wrapped(self, obj_to_raise, msg): - def raise_obj(*args, **kwds): - raise obj_to_raise - self.set_codec(raise_obj, raise_obj) - with self.assertRaisesRegex(RuntimeError, msg): - "str input".encode(self.codec_name) - with self.assertRaisesRegex(RuntimeError, msg): - codecs.encode("str input", self.codec_name) - with self.assertRaisesRegex(RuntimeError, msg): - b"bytes input".decode(self.codec_name) - with self.assertRaisesRegex(RuntimeError, msg): - codecs.decode(b"bytes input", self.codec_name) + self.check_note(MyRuntimeError(msg), msg, MyRuntimeError) - def test_init_override_is_not_wrapped(self): + def test_init_override(self): class CustomInit(RuntimeError): def __init__(self): pass - self.check_not_wrapped(CustomInit, "") + self.check_note(CustomInit, "") - def test_new_override_is_not_wrapped(self): + def test_new_override(self): class CustomNew(RuntimeError): def __new__(cls): return super().__new__(cls) - self.check_not_wrapped(CustomNew, "") + self.check_note(CustomNew, "") - def test_instance_attribute_is_not_wrapped(self): - msg = "This should NOT be wrapped" + def test_instance_attribute(self): + msg = "This should be noted" exc = RuntimeError(msg) exc.attr = 1 - self.check_not_wrapped(exc, "^{}$".format(msg)) + self.check_note(exc, "^{}$".format(msg)) - def test_non_str_arg_is_not_wrapped(self): - self.check_not_wrapped(RuntimeError(1), "1") + def test_non_str_arg(self): + self.check_note(RuntimeError(1), "1") - def test_multiple_args_is_not_wrapped(self): + def test_multiple_args(self): msg_re = r"^\('a', 'b', 'c'\)$" - self.check_not_wrapped(RuntimeError('a', 'b', 'c'), msg_re) + self.check_note(RuntimeError('a', 'b', 'c'), msg_re) # http://bugs.python.org/issue19609 - def test_codec_lookup_failure_not_wrapped(self): + def test_codec_lookup_failure(self): msg = "^unknown encoding: {}$".format(self.codec_name) - # The initial codec lookup should not be wrapped with self.assertRaisesRegex(LookupError, msg): "str input".encode(self.codec_name) with self.assertRaisesRegex(LookupError, msg): diff --git a/Lib/test/test_codeop.py b/Lib/test/test_codeop.py index 133096d2..e3c38226 100644 --- a/Lib/test/test_codeop.py +++ b/Lib/test/test_codeop.py @@ -2,47 +2,18 @@ Test cases for codeop.py Nick Mathewson """ -import sys import unittest import warnings -from test import support from test.support import warnings_helper from codeop import compile_command, PyCF_DONT_IMPLY_DEDENT -import io - -if support.is_jython: - - def unify_callables(d): - for n,v in d.items(): - if hasattr(v, '__call__'): - d[n] = True - return d class CodeopTests(unittest.TestCase): def assertValid(self, str, symbol='single'): '''succeed iff str is a valid piece of code''' - if support.is_jython: - code = compile_command(str, "<input>", symbol) - self.assertTrue(code) - if symbol == "single": - d,r = {},{} - saved_stdout = sys.stdout - sys.stdout = io.StringIO() - try: - exec(code, d) - exec(compile(str,"<input>","single"), r) - finally: - sys.stdout = saved_stdout - elif symbol == 'eval': - ctx = {'a': 2} - d = { 'value': eval(code,ctx) } - r = { 'value': eval(str,ctx) } - self.assertEqual(unify_callables(r),unify_callables(d)) - else: - expected = compile(str, "<input>", symbol, PyCF_DONT_IMPLY_DEDENT) - self.assertEqual(compile_command(str, "<input>", symbol), expected) + expected = compile(str, "<input>", symbol, PyCF_DONT_IMPLY_DEDENT) + self.assertEqual(compile_command(str, "<input>", symbol), expected) def assertIncomplete(self, str, symbol='single'): '''succeed iff str is the start of a valid piece of code''' @@ -62,16 +33,12 @@ class CodeopTests(unittest.TestCase): av = self.assertValid # special case - if not support.is_jython: - self.assertEqual(compile_command(""), - compile("pass", "<input>", 'single', - PyCF_DONT_IMPLY_DEDENT)) - self.assertEqual(compile_command("\n"), - compile("pass", "<input>", 'single', - PyCF_DONT_IMPLY_DEDENT)) - else: - av("") - av("\n") + self.assertEqual(compile_command(""), + compile("pass", "<input>", 'single', + PyCF_DONT_IMPLY_DEDENT)) + self.assertEqual(compile_command("\n"), + compile("pass", "<input>", 'single', + PyCF_DONT_IMPLY_DEDENT)) av("a = 1") av("\na = 1") @@ -310,8 +277,8 @@ class CodeopTests(unittest.TestCase): def test_warning(self): # Test that the warning is only returned once. with warnings_helper.check_warnings( - (".*literal", SyntaxWarning), - (".*invalid", DeprecationWarning), + ('"is" with \'str\' literal', SyntaxWarning), + ("invalid escape sequence", SyntaxWarning), ) as w: compile_command(r"'\e' is 0") self.assertEqual(len(w.warnings), 2) @@ -321,9 +288,9 @@ class CodeopTests(unittest.TestCase): warnings.simplefilter('error', SyntaxWarning) compile_command('1 is 1', symbol='exec') - # Check DeprecationWarning treated as an SyntaxError + # Check SyntaxWarning treated as an SyntaxError with warnings.catch_warnings(), self.assertRaises(SyntaxError): - warnings.simplefilter('error', DeprecationWarning) + warnings.simplefilter('error', SyntaxWarning) compile_command(r"'\e'", symbol='exec') def test_incomplete_warning(self): @@ -337,7 +304,7 @@ class CodeopTests(unittest.TestCase): warnings.simplefilter('always') self.assertInvalid("'\\e' 1") self.assertEqual(len(w), 1) - self.assertEqual(w[0].category, DeprecationWarning) + self.assertEqual(w[0].category, SyntaxWarning) self.assertRegex(str(w[0].message), 'invalid escape sequence') self.assertEqual(w[0].filename, '<input>') diff --git a/Lib/test/test_collections.py b/Lib/test/test_collections.py index 5da446a1..bb8b3525 100644 --- a/Lib/test/test_collections.py +++ b/Lib/test/test_collections.py @@ -25,7 +25,7 @@ from collections.abc import Sized, Container, Callable, Collection from collections.abc import Set, MutableSet from collections.abc import Mapping, MutableMapping, KeysView, ItemsView, ValuesView from collections.abc import Sequence, MutableSequence -from collections.abc import ByteString +from collections.abc import ByteString, Buffer class TestUserObjects(unittest.TestCase): @@ -71,6 +71,14 @@ class TestUserObjects(unittest.TestCase): obj[123] = "abc" self._copy_test(obj) + def test_dict_missing(self): + class A(UserDict): + def __missing__(self, key): + return 456 + self.assertEqual(A()[123], 456) + # get() ignores __missing__ on dict + self.assertIs(A().get(123), None) + ################################################################################ ### ChainMap (helper class for configparser and the string module) @@ -537,7 +545,7 @@ class TestNamedTuple(unittest.TestCase): self.assertEqual(Dot(1)._replace(d=999), (999,)) self.assertEqual(Dot(1)._fields, ('d',)) - n = 5000 + n = support.EXCEEDS_RECURSION_LIMIT names = list(set(''.join([choice(string.ascii_letters) for j in range(10)]) for i in range(n))) n = len(names) @@ -1618,7 +1626,7 @@ class TestCollectionABCs(ABCTestCase): class SetUsingInstanceFromIterable(MutableSet): def __init__(self, values, created_by): if not created_by: - raise ValueError(f'created_by must be specified') + raise ValueError('created_by must be specified') self.created_by = created_by self._values = set(values) @@ -1932,14 +1940,34 @@ class TestCollectionABCs(ABCTestCase): def test_ByteString(self): for sample in [bytes, bytearray]: - self.assertIsInstance(sample(), ByteString) + with self.assertWarns(DeprecationWarning): + self.assertIsInstance(sample(), ByteString) self.assertTrue(issubclass(sample, ByteString)) for sample in [str, list, tuple]: - self.assertNotIsInstance(sample(), ByteString) + with self.assertWarns(DeprecationWarning): + self.assertNotIsInstance(sample(), ByteString) self.assertFalse(issubclass(sample, ByteString)) - self.assertNotIsInstance(memoryview(b""), ByteString) + with self.assertWarns(DeprecationWarning): + self.assertNotIsInstance(memoryview(b""), ByteString) self.assertFalse(issubclass(memoryview, ByteString)) - self.validate_abstract_methods(ByteString, '__getitem__', '__len__') + with self.assertWarns(DeprecationWarning): + self.validate_abstract_methods(ByteString, '__getitem__', '__len__') + + with self.assertWarns(DeprecationWarning): + class X(ByteString): pass + + with self.assertWarns(DeprecationWarning): + # No metaclass conflict + class Z(ByteString, Awaitable): pass + + def test_Buffer(self): + for sample in [bytes, bytearray, memoryview]: + self.assertIsInstance(sample(b"x"), Buffer) + self.assertTrue(issubclass(sample, Buffer)) + for sample in [str, list, tuple]: + self.assertNotIsInstance(sample(), Buffer) + self.assertFalse(issubclass(sample, Buffer)) + self.validate_abstract_methods(Buffer, '__buffer__') def test_MutableSequence(self): for sample in [tuple, str, bytes]: diff --git a/Lib/test/test_colorsys.py b/Lib/test/test_colorsys.py index a24e3adc..74d76294 100644 --- a/Lib/test/test_colorsys.py +++ b/Lib/test/test_colorsys.py @@ -69,6 +69,16 @@ class ColorsysTest(unittest.TestCase): self.assertTripleEqual(hls, colorsys.rgb_to_hls(*rgb)) self.assertTripleEqual(rgb, colorsys.hls_to_rgb(*hls)) + def test_hls_nearwhite(self): # gh-106498 + values = ( + # rgb, hls: these do not work in reverse + ((0.9999999999999999, 1, 1), (0.5, 1.0, 1.0)), + ((1, 0.9999999999999999, 0.9999999999999999), (0.0, 1.0, 1.0)), + ) + for rgb, hls in values: + self.assertTripleEqual(hls, colorsys.rgb_to_hls(*rgb)) + self.assertTripleEqual((1.0, 1.0, 1.0), colorsys.hls_to_rgb(*hls)) + def test_yiq_roundtrip(self): for r in frange(0.0, 1.0, 0.2): for g in frange(0.0, 1.0, 0.2): diff --git a/Lib/test/test_compare.py b/Lib/test/test_compare.py index 2b3faed7..8166b0ee 100644 --- a/Lib/test/test_compare.py +++ b/Lib/test/test_compare.py @@ -1,21 +1,27 @@ +"""Test equality and order comparisons.""" import unittest from test.support import ALWAYS_EQ +from fractions import Fraction +from decimal import Decimal -class Empty: - def __repr__(self): - return '<Empty>' -class Cmp: - def __init__(self,arg): - self.arg = arg +class ComparisonSimpleTest(unittest.TestCase): + """Test equality and order comparisons for some simple cases.""" - def __repr__(self): - return '<Cmp %s>' % self.arg + class Empty: + def __repr__(self): + return '<Empty>' - def __eq__(self, other): - return self.arg == other + class Cmp: + def __init__(self, arg): + self.arg = arg + + def __repr__(self): + return '<Cmp %s>' % self.arg + + def __eq__(self, other): + return self.arg == other -class ComparisonTest(unittest.TestCase): set1 = [2, 2.0, 2, 2+0j, Cmp(2.0)] set2 = [[1], (3,), None, Empty()] candidates = set1 + set2 @@ -32,16 +38,15 @@ class ComparisonTest(unittest.TestCase): # Ensure default comparison compares id() of args L = [] for i in range(10): - L.insert(len(L)//2, Empty()) + L.insert(len(L)//2, self.Empty()) for a in L: for b in L: - self.assertEqual(a == b, id(a) == id(b), - 'a=%r, b=%r' % (a, b)) + self.assertEqual(a == b, a is b, 'a=%r, b=%r' % (a, b)) def test_ne_defaults_to_not_eq(self): - a = Cmp(1) - b = Cmp(1) - c = Cmp(2) + a = self.Cmp(1) + b = self.Cmp(1) + c = self.Cmp(2) self.assertIs(a == b, True) self.assertIs(a != b, False) self.assertIs(a != c, True) @@ -114,5 +119,392 @@ class ComparisonTest(unittest.TestCase): self.assertEqual(ALWAYS_EQ, y) +class ComparisonFullTest(unittest.TestCase): + """Test equality and ordering comparisons for built-in types and + user-defined classes that implement relevant combinations of rich + comparison methods. + """ + + class CompBase: + """Base class for classes with rich comparison methods. + + The "x" attribute should be set to an underlying value to compare. + + Derived classes have a "meth" tuple attribute listing names of + comparison methods implemented. See assert_total_order(). + """ + + # Class without any rich comparison methods. + class CompNone(CompBase): + meth = () + + # Classes with all combinations of value-based equality comparison methods. + class CompEq(CompBase): + meth = ("eq",) + def __eq__(self, other): + return self.x == other.x + + class CompNe(CompBase): + meth = ("ne",) + def __ne__(self, other): + return self.x != other.x + + class CompEqNe(CompBase): + meth = ("eq", "ne") + def __eq__(self, other): + return self.x == other.x + def __ne__(self, other): + return self.x != other.x + + # Classes with all combinations of value-based less/greater-than order + # comparison methods. + class CompLt(CompBase): + meth = ("lt",) + def __lt__(self, other): + return self.x < other.x + + class CompGt(CompBase): + meth = ("gt",) + def __gt__(self, other): + return self.x > other.x + + class CompLtGt(CompBase): + meth = ("lt", "gt") + def __lt__(self, other): + return self.x < other.x + def __gt__(self, other): + return self.x > other.x + + # Classes with all combinations of value-based less/greater-or-equal-than + # order comparison methods + class CompLe(CompBase): + meth = ("le",) + def __le__(self, other): + return self.x <= other.x + + class CompGe(CompBase): + meth = ("ge",) + def __ge__(self, other): + return self.x >= other.x + + class CompLeGe(CompBase): + meth = ("le", "ge") + def __le__(self, other): + return self.x <= other.x + def __ge__(self, other): + return self.x >= other.x + + # It should be sufficient to combine the comparison methods only within + # each group. + all_comp_classes = ( + CompNone, + CompEq, CompNe, CompEqNe, # equal group + CompLt, CompGt, CompLtGt, # less/greater-than group + CompLe, CompGe, CompLeGe) # less/greater-or-equal group + + def create_sorted_instances(self, class_, values): + """Create objects of type `class_` and return them in a list. + + `values` is a list of values that determines the value of data + attribute `x` of each object. + + Objects in the returned list are sorted by their identity. They + assigned values in `values` list order. By assign decreasing + values to objects with increasing identities, testcases can assert + that order comparison is performed by value and not by identity. + """ + + instances = [class_() for __ in range(len(values))] + instances.sort(key=id) + # Assign the provided values to the instances. + for inst, value in zip(instances, values): + inst.x = value + return instances + + def assert_equality_only(self, a, b, equal): + """Assert equality result and that ordering is not implemented. + + a, b: Instances to be tested (of same or different type). + equal: Boolean indicating the expected equality comparison results. + """ + self.assertEqual(a == b, equal) + self.assertEqual(b == a, equal) + self.assertEqual(a != b, not equal) + self.assertEqual(b != a, not equal) + with self.assertRaisesRegex(TypeError, "not supported"): + a < b + with self.assertRaisesRegex(TypeError, "not supported"): + a <= b + with self.assertRaisesRegex(TypeError, "not supported"): + a > b + with self.assertRaisesRegex(TypeError, "not supported"): + a >= b + with self.assertRaisesRegex(TypeError, "not supported"): + b < a + with self.assertRaisesRegex(TypeError, "not supported"): + b <= a + with self.assertRaisesRegex(TypeError, "not supported"): + b > a + with self.assertRaisesRegex(TypeError, "not supported"): + b >= a + + def assert_total_order(self, a, b, comp, a_meth=None, b_meth=None): + """Test total ordering comparison of two instances. + + a, b: Instances to be tested (of same or different type). + + comp: -1, 0, or 1 indicates that the expected order comparison + result for operations that are supported by the classes is + a <, ==, or > b. + + a_meth, b_meth: Either None, indicating that all rich comparison + methods are available, aa for builtins, or the tuple (subset) + of "eq", "ne", "lt", "le", "gt", and "ge" that are available + for the corresponding instance (of a user-defined class). + """ + self.assert_eq_subtest(a, b, comp, a_meth, b_meth) + self.assert_ne_subtest(a, b, comp, a_meth, b_meth) + self.assert_lt_subtest(a, b, comp, a_meth, b_meth) + self.assert_le_subtest(a, b, comp, a_meth, b_meth) + self.assert_gt_subtest(a, b, comp, a_meth, b_meth) + self.assert_ge_subtest(a, b, comp, a_meth, b_meth) + + # The body of each subtest has form: + # + # if value-based comparison methods: + # expect what the testcase defined for a op b and b rop a; + # else: no value-based comparison + # expect default behavior of object for a op b and b rop a. + + def assert_eq_subtest(self, a, b, comp, a_meth, b_meth): + if a_meth is None or "eq" in a_meth or "eq" in b_meth: + self.assertEqual(a == b, comp == 0) + self.assertEqual(b == a, comp == 0) + else: + self.assertEqual(a == b, a is b) + self.assertEqual(b == a, a is b) + + def assert_ne_subtest(self, a, b, comp, a_meth, b_meth): + if a_meth is None or not {"ne", "eq"}.isdisjoint(a_meth + b_meth): + self.assertEqual(a != b, comp != 0) + self.assertEqual(b != a, comp != 0) + else: + self.assertEqual(a != b, a is not b) + self.assertEqual(b != a, a is not b) + + def assert_lt_subtest(self, a, b, comp, a_meth, b_meth): + if a_meth is None or "lt" in a_meth or "gt" in b_meth: + self.assertEqual(a < b, comp < 0) + self.assertEqual(b > a, comp < 0) + else: + with self.assertRaisesRegex(TypeError, "not supported"): + a < b + with self.assertRaisesRegex(TypeError, "not supported"): + b > a + + def assert_le_subtest(self, a, b, comp, a_meth, b_meth): + if a_meth is None or "le" in a_meth or "ge" in b_meth: + self.assertEqual(a <= b, comp <= 0) + self.assertEqual(b >= a, comp <= 0) + else: + with self.assertRaisesRegex(TypeError, "not supported"): + a <= b + with self.assertRaisesRegex(TypeError, "not supported"): + b >= a + + def assert_gt_subtest(self, a, b, comp, a_meth, b_meth): + if a_meth is None or "gt" in a_meth or "lt" in b_meth: + self.assertEqual(a > b, comp > 0) + self.assertEqual(b < a, comp > 0) + else: + with self.assertRaisesRegex(TypeError, "not supported"): + a > b + with self.assertRaisesRegex(TypeError, "not supported"): + b < a + + def assert_ge_subtest(self, a, b, comp, a_meth, b_meth): + if a_meth is None or "ge" in a_meth or "le" in b_meth: + self.assertEqual(a >= b, comp >= 0) + self.assertEqual(b <= a, comp >= 0) + else: + with self.assertRaisesRegex(TypeError, "not supported"): + a >= b + with self.assertRaisesRegex(TypeError, "not supported"): + b <= a + + def test_objects(self): + """Compare instances of type 'object'.""" + a = object() + b = object() + self.assert_equality_only(a, a, True) + self.assert_equality_only(a, b, False) + + def test_comp_classes_same(self): + """Compare same-class instances with comparison methods.""" + + for cls in self.all_comp_classes: + with self.subTest(cls): + instances = self.create_sorted_instances(cls, (1, 2, 1)) + + # Same object. + self.assert_total_order(instances[0], instances[0], 0, + cls.meth, cls.meth) + + # Different objects, same value. + self.assert_total_order(instances[0], instances[2], 0, + cls.meth, cls.meth) + + # Different objects, value ascending for ascending identities. + self.assert_total_order(instances[0], instances[1], -1, + cls.meth, cls.meth) + + # different objects, value descending for ascending identities. + # This is the interesting case to assert that order comparison + # is performed based on the value and not based on the identity. + self.assert_total_order(instances[1], instances[2], +1, + cls.meth, cls.meth) + + def test_comp_classes_different(self): + """Compare different-class instances with comparison methods.""" + + for cls_a in self.all_comp_classes: + for cls_b in self.all_comp_classes: + with self.subTest(a=cls_a, b=cls_b): + a1 = cls_a() + a1.x = 1 + b1 = cls_b() + b1.x = 1 + b2 = cls_b() + b2.x = 2 + + self.assert_total_order( + a1, b1, 0, cls_a.meth, cls_b.meth) + self.assert_total_order( + a1, b2, -1, cls_a.meth, cls_b.meth) + + def test_str_subclass(self): + """Compare instances of str and a subclass.""" + class StrSubclass(str): + pass + + s1 = str("a") + s2 = str("b") + c1 = StrSubclass("a") + c2 = StrSubclass("b") + c3 = StrSubclass("b") + + self.assert_total_order(s1, s1, 0) + self.assert_total_order(s1, s2, -1) + self.assert_total_order(c1, c1, 0) + self.assert_total_order(c1, c2, -1) + self.assert_total_order(c2, c3, 0) + + self.assert_total_order(s1, c2, -1) + self.assert_total_order(s2, c3, 0) + self.assert_total_order(c1, s2, -1) + self.assert_total_order(c2, s2, 0) + + def test_numbers(self): + """Compare number types.""" + + # Same types. + i1 = 1001 + i2 = 1002 + self.assert_total_order(i1, i1, 0) + self.assert_total_order(i1, i2, -1) + + f1 = 1001.0 + f2 = 1001.1 + self.assert_total_order(f1, f1, 0) + self.assert_total_order(f1, f2, -1) + + q1 = Fraction(2002, 2) + q2 = Fraction(2003, 2) + self.assert_total_order(q1, q1, 0) + self.assert_total_order(q1, q2, -1) + + d1 = Decimal('1001.0') + d2 = Decimal('1001.1') + self.assert_total_order(d1, d1, 0) + self.assert_total_order(d1, d2, -1) + + c1 = 1001+0j + c2 = 1001+1j + self.assert_equality_only(c1, c1, True) + self.assert_equality_only(c1, c2, False) + + + # Mixing types. + for n1, n2 in ((i1,f1), (i1,q1), (i1,d1), (f1,q1), (f1,d1), (q1,d1)): + self.assert_total_order(n1, n2, 0) + for n1 in (i1, f1, q1, d1): + self.assert_equality_only(n1, c1, True) + + def test_sequences(self): + """Compare list, tuple, and range.""" + l1 = [1, 2] + l2 = [2, 3] + self.assert_total_order(l1, l1, 0) + self.assert_total_order(l1, l2, -1) + + t1 = (1, 2) + t2 = (2, 3) + self.assert_total_order(t1, t1, 0) + self.assert_total_order(t1, t2, -1) + + r1 = range(1, 2) + r2 = range(2, 2) + self.assert_equality_only(r1, r1, True) + self.assert_equality_only(r1, r2, False) + + self.assert_equality_only(t1, l1, False) + self.assert_equality_only(l1, r1, False) + self.assert_equality_only(r1, t1, False) + + def test_bytes(self): + """Compare bytes and bytearray.""" + bs1 = b'a1' + bs2 = b'b2' + self.assert_total_order(bs1, bs1, 0) + self.assert_total_order(bs1, bs2, -1) + + ba1 = bytearray(b'a1') + ba2 = bytearray(b'b2') + self.assert_total_order(ba1, ba1, 0) + self.assert_total_order(ba1, ba2, -1) + + self.assert_total_order(bs1, ba1, 0) + self.assert_total_order(bs1, ba2, -1) + self.assert_total_order(ba1, bs1, 0) + self.assert_total_order(ba1, bs2, -1) + + def test_sets(self): + """Compare set and frozenset.""" + s1 = {1, 2} + s2 = {1, 2, 3} + self.assert_total_order(s1, s1, 0) + self.assert_total_order(s1, s2, -1) + + f1 = frozenset(s1) + f2 = frozenset(s2) + self.assert_total_order(f1, f1, 0) + self.assert_total_order(f1, f2, -1) + + self.assert_total_order(s1, f1, 0) + self.assert_total_order(s1, f2, -1) + self.assert_total_order(f1, s1, 0) + self.assert_total_order(f1, s2, -1) + + def test_mappings(self): + """ Compare dict. + """ + d1 = {1: "a", 2: "b"} + d2 = {2: "b", 3: "c"} + d3 = {3: "c", 2: "b"} + self.assert_equality_only(d1, d1, True) + self.assert_equality_only(d1, d2, False) + self.assert_equality_only(d2, d3, True) + + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py index 54e90663..e377620a 100644 --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -8,11 +8,12 @@ import _ast import tempfile import types import textwrap +import warnings from test import support -from test.support import script_helper, requires_debug_ranges +from test.support import (script_helper, requires_debug_ranges, + requires_specialization, C_RECURSION_LIMIT) from test.support.os_helper import FakePath - class TestSpecifics(unittest.TestCase): def compile_single(self, source): @@ -108,29 +109,29 @@ class TestSpecifics(unittest.TestCase): exec('z = a', g, d) self.assertEqual(d['z'], 12) + @unittest.skipIf(support.is_wasi, "exhausts limited stack on WASI") def test_extended_arg(self): - # default: 1000 * 2.5 = 2500 repetitions - repeat = int(sys.getrecursionlimit() * 2.5) + repeat = int(C_RECURSION_LIMIT * 0.9) longexpr = 'x = x or ' + '-x' * repeat g = {} - code = ''' -def f(x): - %s - %s - %s - %s - %s - %s - %s - %s - %s - %s - # the expressions above have no effect, x == argument - while x: - x -= 1 - # EXTENDED_ARG/JUMP_ABSOLUTE here - return x -''' % ((longexpr,)*10) + code = textwrap.dedent(''' + def f(x): + %s + %s + %s + %s + %s + %s + %s + %s + %s + %s + # the expressions above have no effect, x == argument + while x: + x -= 1 + # EXTENDED_ARG/JUMP_ABSOLUTE here + return x + ''' % ((longexpr,)*10)) exec(code, g) self.assertEqual(g['f'](5), 0) @@ -146,10 +147,11 @@ def f(x): def test_indentation(self): # testing compile() of indented block w/o trailing newline" - s = """ -if 1: - if 2: - pass""" + s = textwrap.dedent(""" + if 1: + if 2: + pass + """) compile(s, "<string>", "exec") # This test is probably specific to CPython and may not generalize @@ -160,9 +162,8 @@ if 1: s256 = "".join(["\n"] * 256 + ["spam"]) co = compile(s256, 'fn', 'exec') self.assertEqual(co.co_firstlineno, 1) - lines = list(co.co_lines()) - self.assertEqual(lines[0][2], 0) - self.assertEqual(lines[1][2], 257) + lines = [line for _, _, line in co.co_lines()] + self.assertEqual(lines, [0, 257]) def test_literals_with_leading_zeroes(self): for arg in ["077787", "0xj", "0x.", "0e", "090000000000000", @@ -477,6 +478,26 @@ if 1: ast.body = [_ast.BoolOp()] self.assertRaises(TypeError, compile, ast, '<ast>', 'exec') + def test_compile_invalid_typealias(self): + # gh-109341 + m = ast.Module( + body=[ + ast.TypeAlias( + name=ast.Subscript( + value=ast.Name(id="foo", ctx=ast.Load()), + slice=ast.Constant(value="x"), + ctx=ast.Store(), + ), + type_params=[], + value=ast.Name(id="Callable", ctx=ast.Load()), + ) + ], + type_ignores=[], + ) + + with self.assertRaisesRegex(TypeError, "TypeAlias with non-Name name"): + compile(ast.fix_missing_locations(m), "<file>", "exec") + def test_dict_evaluation_order(self): i = 0 @@ -493,9 +514,8 @@ if 1: code = compile('pass', filename, 'exec') self.assertEqual(code.co_filename, 'file.py') for filename in bytearray(b'file.py'), memoryview(b'file.py'): - with self.assertWarns(DeprecationWarning): - code = compile('pass', filename, 'exec') - self.assertEqual(code.co_filename, 'file.py') + with self.assertRaises(TypeError): + compile('pass', filename, 'exec') self.assertRaises(TypeError, compile, 'pass', list(b'file.py'), 'exec') @support.cpython_only @@ -542,7 +562,7 @@ if 1: with open(fn, "wb") as fp: fp.write(src) res = script_helper.run_python_until_end(fn)[0] - self.assertIn(b"Non-UTF-8", res.err) + self.assertIn(b"source code cannot contain null bytes", res.err) def test_yet_more_evil_still_undecodable(self): # Issue #25388 @@ -552,20 +572,17 @@ if 1: with open(fn, "wb") as fp: fp.write(src) res = script_helper.run_python_until_end(fn)[0] - self.assertIn(b"Non-UTF-8", res.err) + self.assertIn(b"source code cannot contain null bytes", res.err) @support.cpython_only + @unittest.skipIf(support.is_wasi, "exhausts limited stack on WASI") def test_compiler_recursion_limit(self): - # Expected limit is sys.getrecursionlimit() * the scaling factor - # in symtable.c (currently 3) - # We expect to fail *at* that limit, because we use up some of - # the stack depth limit in the test suite code - # So we check the expected limit and 75% of that - # XXX (ncoghlan): duplicating the scaling factor here is a little - # ugly. Perhaps it should be exposed somewhere... - fail_depth = sys.getrecursionlimit() * 3 - crash_depth = sys.getrecursionlimit() * 300 - success_depth = int(fail_depth * 0.75) + # Expected limit is C_RECURSION_LIMIT * 2 + # Duplicating the limit here is a little ugly. + # Perhaps it should be exposed somewhere... + fail_depth = C_RECURSION_LIMIT * 2 + 1 + crash_depth = C_RECURSION_LIMIT * 100 + success_depth = int(C_RECURSION_LIMIT * 1.8) def check_limit(prefix, repeated, mode="single"): expect_ok = prefix + repeated * success_depth @@ -588,9 +605,9 @@ if 1: def test_null_terminated(self): # The source code is null-terminated internally, but bytes-like # objects are accepted, which could be not terminated. - with self.assertRaisesRegex(ValueError, "cannot contain null"): + with self.assertRaisesRegex(SyntaxError, "cannot contain null"): compile("123\x00", "<dummy>", "eval") - with self.assertRaisesRegex(ValueError, "cannot contain null"): + with self.assertRaisesRegex(SyntaxError, "cannot contain null"): compile(memoryview(b"123\x00"), "<dummy>", "eval") code = compile(memoryview(b"123\x00")[1:-1], "<dummy>", "eval") self.assertEqual(eval(code), 23) @@ -668,10 +685,56 @@ if 1: self.assertIs(f1.__code__.co_linetable, f2.__code__.co_linetable) + @support.cpython_only + def test_remove_unused_consts(self): + def f(): + "docstring" + if True: + return "used" + else: + return "unused" + + self.assertEqual(f.__code__.co_consts, + ("docstring", "used")) + + @support.cpython_only + def test_remove_unused_consts_no_docstring(self): + # the first item (None for no docstring in this case) is + # always retained. + def f(): + if True: + return "used" + else: + return "unused" + + self.assertEqual(f.__code__.co_consts, + (None, "used")) + + @support.cpython_only + def test_remove_unused_consts_extended_args(self): + N = 1000 + code = ["def f():\n"] + code.append("\ts = ''\n") + code.append("\tfor i in range(1):\n") + for i in range(N): + code.append(f"\t\tif True: s += 't{i}'\n") + code.append(f"\t\tif False: s += 'f{i}'\n") + code.append("\treturn s\n") + + code = "".join(code) + g = {} + eval(compile(code, "file.py", "exec"), g) + exec(code, g) + f = g['f'] + expected = tuple([None, '', 1] + [f't{i}' for i in range(N)]) + self.assertEqual(f.__code__.co_consts, expected) + expected = "".join(expected[3:]) + self.assertEqual(expected, f()) + # Stripping unused constants is not a strict requirement for the # Python semantics, it's a more an implementation detail. @support.cpython_only - def test_strip_unused_consts(self): + def test_strip_unused_None(self): # Python 3.10rc1 appended None to co_consts when None is not used # at all. See bpo-45056. def f1(): @@ -694,7 +757,7 @@ if 1: # RETURN_VALUE opcode. This does not always crash an interpreter. # When you build with the clang memory sanitizer it reliably aborts. self.assertEqual( - 'RETURN_VALUE', + 'RETURN_CONST', list(dis.get_instructions(unused_code_at_end))[-1].opname) def test_dont_merge_constants(self): @@ -741,6 +804,7 @@ if 1: # An implicit test for PyUnicode_FSDecoder(). compile("42", FakePath("test_compile_pathlike"), "single") + @support.requires_resource('cpu') def test_stack_overflow(self): # bpo-31113: Stack overflow when compile a long sequence of # complex statements. @@ -775,10 +839,9 @@ if 1: for func in funcs: opcodes = list(dis.get_instructions(func)) - self.assertLessEqual(len(opcodes), 4) - self.assertEqual('LOAD_CONST', opcodes[-2].opname) - self.assertEqual(None, opcodes[-2].argval) - self.assertEqual('RETURN_VALUE', opcodes[-1].opname) + self.assertLessEqual(len(opcodes), 3) + self.assertEqual('RETURN_CONST', opcodes[-1].opname) + self.assertEqual(None, opcodes[-1].argval) def test_false_while_loop(self): def break_in_while(): @@ -794,10 +857,9 @@ if 1: # Check that we did not raise but we also don't generate bytecode for func in funcs: opcodes = list(dis.get_instructions(func)) - self.assertEqual(3, len(opcodes)) - self.assertEqual('LOAD_CONST', opcodes[1].opname) + self.assertEqual(2, len(opcodes)) + self.assertEqual('RETURN_CONST', opcodes[1].opname) self.assertEqual(None, opcodes[1].argval) - self.assertEqual('RETURN_VALUE', opcodes[2].opname) def test_consts_in_conditionals(self): def and_true(x): @@ -854,7 +916,7 @@ if 1: instructions = [opcode.opname for opcode in opcodes] self.assertNotIn('LOAD_METHOD', instructions) self.assertIn('LOAD_ATTR', instructions) - self.assertIn('PRECALL', instructions) + self.assertIn('CALL', instructions) def test_lineno_procedure_call(self): def call(): @@ -908,9 +970,9 @@ if 1: for func in (no_code1, no_code2): with self.subTest(func=func): code = func.__code__ - lines = list(code.co_lines()) - start, end, line = lines[0] + [(start, end, line)] = code.co_lines() self.assertEqual(start, 0) + self.assertEqual(end, len(code.co_code)) self.assertEqual(line, code.co_firstlineno) def get_code_lines(self, code): @@ -990,6 +1052,20 @@ if 1: code_lines = self.get_code_lines(test.__code__) self.assertEqual(expected_lines, code_lines) + def test_lineno_of_backward_jump(self): + # Issue gh-107901 + def f(): + for i in x: + if y: + pass + + linenos = list(inst.positions.lineno + for inst in dis.get_instructions(f.__code__) + if inst.opname == 'JUMP_BACKWARD') + + self.assertTrue(len(linenos) > 0) + self.assertTrue(all(l is not None for l in linenos)) + def test_big_dict_literal(self): # The compiler has a flushing point in "compiler_dict" that calls compiles # a portion of the dictionary literal when the loop that iterates over the items @@ -1039,12 +1115,47 @@ if 1: for instr in dis.Bytecode(while_not_chained): self.assertNotEqual(instr.opname, "EXTENDED_ARG") + @support.cpython_only + def test_uses_slice_instructions(self): + + def check_op_count(func, op, expected): + actual = 0 + for instr in dis.Bytecode(func): + if instr.opname == op: + actual += 1 + self.assertEqual(actual, expected) + + def load(): + return x[a:b] + x [a:] + x[:b] + x[:] + + def store(): + x[a:b] = y + x [a:] = y + x[:b] = y + x[:] = y + + def long_slice(): + return x[a:b:c] + + def aug(): + x[a:b] += y + + check_op_count(load, "BINARY_SLICE", 4) + check_op_count(load, "BUILD_SLICE", 0) + check_op_count(store, "STORE_SLICE", 4) + check_op_count(store, "BUILD_SLICE", 0) + check_op_count(long_slice, "BUILD_SLICE", 1) + check_op_count(long_slice, "BINARY_SLICE", 0) + check_op_count(aug, "BINARY_SLICE", 1) + check_op_count(aug, "STORE_SLICE", 1) + check_op_count(aug, "BUILD_SLICE", 0) + def test_compare_positions(self): - for opname, op in [ - ("COMPARE_OP", "<"), - ("COMPARE_OP", "<="), - ("COMPARE_OP", ">"), - ("COMPARE_OP", ">="), + for opname_prefix, op in [ + ("COMPARE_", "<"), + ("COMPARE_", "<="), + ("COMPARE_", ">"), + ("COMPARE_", ">="), ("CONTAINS_OP", "in"), ("CONTAINS_OP", "not in"), ("IS_OP", "is"), @@ -1059,11 +1170,77 @@ if 1: actual_positions = [ instruction.positions for instruction in dis.get_instructions(code) - if instruction.opname == opname + if instruction.opname.startswith(opname_prefix) ] with self.subTest(source): self.assertEqual(actual_positions, expected_positions) + def test_if_expression_expression_empty_block(self): + # See regression in gh-99708 + exprs = [ + "assert (False if 1 else True)", + "def f():\n\tif not (False if 1 else True): raise AssertionError", + "def f():\n\tif not (False if 1 else True): return 12", + ] + for expr in exprs: + with self.subTest(expr=expr): + compile(expr, "<single>", "exec") + + def test_multi_line_lambda_as_argument(self): + # See gh-101928 + code = textwrap.dedent(""" + def foo(param, lambda_exp): + pass + + foo(param=0, + lambda_exp=lambda: + 1) + """) + compile(code, "<test>", "exec") + + def test_apply_static_swaps(self): + def f(x, y): + a, a = x, y + return a + self.assertEqual(f("x", "y"), "y") + + def test_apply_static_swaps_2(self): + def f(x, y, z): + a, b, a = x, y, z + return a + self.assertEqual(f("x", "y", "z"), "z") + + def test_apply_static_swaps_3(self): + def f(x, y, z): + a, a, b = x, y, z + return a + self.assertEqual(f("x", "y", "z"), "y") + + def test_duplicated_small_exit_block(self): + # See gh-109627 + def f(): + while element and something: + try: + return something + except: + pass + + def test_cold_block_moved_to_end(self): + # See gh-109719 + def f(): + while name: + try: + break + except: + pass + else: + 1 if 1 else 1 + + def test_remove_empty_basic_block_with_jump_target_label(self): + # See gh-109823 + def f(x): + while x: + 0 if 1 else 0 @requires_debug_ranges() class TestSourcePositions(unittest.TestCase): @@ -1082,7 +1259,7 @@ class TestSourcePositions(unittest.TestCase): class SourceOffsetVisitor(ast.NodeVisitor): def generic_visit(self, node): super().generic_visit(node) - if not isinstance(node, ast.expr) and not isinstance(node, ast.stmt): + if not isinstance(node, (ast.expr, ast.stmt, ast.pattern)): return lines.add(node.lineno) end_lines.add(node.end_lineno) @@ -1150,15 +1327,302 @@ class TestSourcePositions(unittest.TestCase): column=2, end_column=9, occurrence=2) def test_multiline_expression(self): - snippet = """\ -f( - 1, 2, 3, 4 -) -""" + snippet = textwrap.dedent("""\ + f( + 1, 2, 3, 4 + ) + """) compiled_code, _ = self.check_positions_against_ast(snippet) self.assertOpcodeSourcePositionIs(compiled_code, 'CALL', line=1, end_line=3, column=0, end_column=1) + @requires_specialization + def test_multiline_boolean_expression(self): + snippet = textwrap.dedent("""\ + if (a or + (b and not c) or + not ( + d > 0)): + x = 42 + """) + compiled_code, _ = self.check_positions_against_ast(snippet) + # jump if a is true: + self.assertOpcodeSourcePositionIs(compiled_code, 'POP_JUMP_IF_TRUE', + line=1, end_line=1, column=4, end_column=5, occurrence=1) + # jump if b is false: + self.assertOpcodeSourcePositionIs(compiled_code, 'POP_JUMP_IF_FALSE', + line=2, end_line=2, column=5, end_column=6, occurrence=1) + # jump if c is false: + self.assertOpcodeSourcePositionIs(compiled_code, 'POP_JUMP_IF_FALSE', + line=2, end_line=2, column=15, end_column=16, occurrence=2) + # compare d and 0 + self.assertOpcodeSourcePositionIs(compiled_code, 'COMPARE_OP', + line=4, end_line=4, column=8, end_column=13, occurrence=1) + # jump if comparison it True + self.assertOpcodeSourcePositionIs(compiled_code, 'POP_JUMP_IF_TRUE', + line=4, end_line=4, column=8, end_column=13, occurrence=2) + + def test_multiline_assert(self): + snippet = textwrap.dedent("""\ + assert (a > 0 and + bb > 0 and + ccc == 4), "error msg" + """) + compiled_code, _ = self.check_positions_against_ast(snippet) + self.assertOpcodeSourcePositionIs(compiled_code, 'LOAD_ASSERTION_ERROR', + line=1, end_line=3, column=0, end_column=30, occurrence=1) + # The "error msg": + self.assertOpcodeSourcePositionIs(compiled_code, 'LOAD_CONST', + line=3, end_line=3, column=19, end_column=30, occurrence=4) + self.assertOpcodeSourcePositionIs(compiled_code, 'CALL', + line=1, end_line=3, column=0, end_column=30, occurrence=1) + self.assertOpcodeSourcePositionIs(compiled_code, 'RAISE_VARARGS', + line=1, end_line=3, column=0, end_column=30, occurrence=1) + + def test_multiline_generator_expression(self): + snippet = textwrap.dedent("""\ + ((x, + 2*x) + for x + in [1,2,3] if (x > 0 + and x < 100 + and x != 50)) + """) + compiled_code, _ = self.check_positions_against_ast(snippet) + compiled_code = compiled_code.co_consts[0] + self.assertIsInstance(compiled_code, types.CodeType) + self.assertOpcodeSourcePositionIs(compiled_code, 'YIELD_VALUE', + line=1, end_line=2, column=1, end_column=8, occurrence=1) + self.assertOpcodeSourcePositionIs(compiled_code, 'JUMP_BACKWARD', + line=1, end_line=2, column=1, end_column=8, occurrence=1) + self.assertOpcodeSourcePositionIs(compiled_code, 'RETURN_CONST', + line=1, end_line=6, column=0, end_column=32, occurrence=1) + + def test_multiline_async_generator_expression(self): + snippet = textwrap.dedent("""\ + ((x, + 2*x) + async for x + in [1,2,3] if (x > 0 + and x < 100 + and x != 50)) + """) + compiled_code, _ = self.check_positions_against_ast(snippet) + compiled_code = compiled_code.co_consts[0] + self.assertIsInstance(compiled_code, types.CodeType) + self.assertOpcodeSourcePositionIs(compiled_code, 'YIELD_VALUE', + line=1, end_line=2, column=1, end_column=8, occurrence=2) + self.assertOpcodeSourcePositionIs(compiled_code, 'RETURN_CONST', + line=1, end_line=6, column=0, end_column=32, occurrence=1) + + def test_multiline_list_comprehension(self): + snippet = textwrap.dedent("""\ + [(x, + 2*x) + for x + in [1,2,3] if (x > 0 + and x < 100 + and x != 50)] + """) + compiled_code, _ = self.check_positions_against_ast(snippet) + self.assertIsInstance(compiled_code, types.CodeType) + self.assertOpcodeSourcePositionIs(compiled_code, 'LIST_APPEND', + line=1, end_line=2, column=1, end_column=8, occurrence=1) + self.assertOpcodeSourcePositionIs(compiled_code, 'JUMP_BACKWARD', + line=1, end_line=2, column=1, end_column=8, occurrence=1) + + def test_multiline_async_list_comprehension(self): + snippet = textwrap.dedent("""\ + async def f(): + [(x, + 2*x) + async for x + in [1,2,3] if (x > 0 + and x < 100 + and x != 50)] + """) + compiled_code, _ = self.check_positions_against_ast(snippet) + g = {} + eval(compiled_code, g) + compiled_code = g['f'].__code__ + self.assertIsInstance(compiled_code, types.CodeType) + self.assertOpcodeSourcePositionIs(compiled_code, 'LIST_APPEND', + line=2, end_line=3, column=5, end_column=12, occurrence=1) + self.assertOpcodeSourcePositionIs(compiled_code, 'JUMP_BACKWARD', + line=2, end_line=3, column=5, end_column=12, occurrence=1) + self.assertOpcodeSourcePositionIs(compiled_code, 'RETURN_CONST', + line=2, end_line=7, column=4, end_column=36, occurrence=1) + + def test_multiline_set_comprehension(self): + snippet = textwrap.dedent("""\ + {(x, + 2*x) + for x + in [1,2,3] if (x > 0 + and x < 100 + and x != 50)} + """) + compiled_code, _ = self.check_positions_against_ast(snippet) + self.assertIsInstance(compiled_code, types.CodeType) + self.assertOpcodeSourcePositionIs(compiled_code, 'SET_ADD', + line=1, end_line=2, column=1, end_column=8, occurrence=1) + self.assertOpcodeSourcePositionIs(compiled_code, 'JUMP_BACKWARD', + line=1, end_line=2, column=1, end_column=8, occurrence=1) + + def test_multiline_async_set_comprehension(self): + snippet = textwrap.dedent("""\ + async def f(): + {(x, + 2*x) + async for x + in [1,2,3] if (x > 0 + and x < 100 + and x != 50)} + """) + compiled_code, _ = self.check_positions_against_ast(snippet) + g = {} + eval(compiled_code, g) + compiled_code = g['f'].__code__ + self.assertIsInstance(compiled_code, types.CodeType) + self.assertOpcodeSourcePositionIs(compiled_code, 'SET_ADD', + line=2, end_line=3, column=5, end_column=12, occurrence=1) + self.assertOpcodeSourcePositionIs(compiled_code, 'JUMP_BACKWARD', + line=2, end_line=3, column=5, end_column=12, occurrence=1) + self.assertOpcodeSourcePositionIs(compiled_code, 'RETURN_CONST', + line=2, end_line=7, column=4, end_column=36, occurrence=1) + + def test_multiline_dict_comprehension(self): + snippet = textwrap.dedent("""\ + {x: + 2*x + for x + in [1,2,3] if (x > 0 + and x < 100 + and x != 50)} + """) + compiled_code, _ = self.check_positions_against_ast(snippet) + self.assertIsInstance(compiled_code, types.CodeType) + self.assertOpcodeSourcePositionIs(compiled_code, 'MAP_ADD', + line=1, end_line=2, column=1, end_column=7, occurrence=1) + self.assertOpcodeSourcePositionIs(compiled_code, 'JUMP_BACKWARD', + line=1, end_line=2, column=1, end_column=7, occurrence=1) + + def test_multiline_async_dict_comprehension(self): + snippet = textwrap.dedent("""\ + async def f(): + {x: + 2*x + async for x + in [1,2,3] if (x > 0 + and x < 100 + and x != 50)} + """) + compiled_code, _ = self.check_positions_against_ast(snippet) + g = {} + eval(compiled_code, g) + compiled_code = g['f'].__code__ + self.assertIsInstance(compiled_code, types.CodeType) + self.assertOpcodeSourcePositionIs(compiled_code, 'MAP_ADD', + line=2, end_line=3, column=5, end_column=11, occurrence=1) + self.assertOpcodeSourcePositionIs(compiled_code, 'JUMP_BACKWARD', + line=2, end_line=3, column=5, end_column=11, occurrence=1) + self.assertOpcodeSourcePositionIs(compiled_code, 'RETURN_CONST', + line=2, end_line=7, column=4, end_column=36, occurrence=1) + + def test_matchcase_sequence(self): + snippet = textwrap.dedent("""\ + match x: + case a, b: + pass + """) + compiled_code, _ = self.check_positions_against_ast(snippet) + self.assertOpcodeSourcePositionIs(compiled_code, 'MATCH_SEQUENCE', + line=2, end_line=2, column=9, end_column=13, occurrence=1) + self.assertOpcodeSourcePositionIs(compiled_code, 'UNPACK_SEQUENCE', + line=2, end_line=2, column=9, end_column=13, occurrence=1) + self.assertOpcodeSourcePositionIs(compiled_code, 'STORE_NAME', + line=2, end_line=2, column=9, end_column=13, occurrence=1) + self.assertOpcodeSourcePositionIs(compiled_code, 'STORE_NAME', + line=2, end_line=2, column=9, end_column=13, occurrence=2) + + def test_matchcase_sequence_wildcard(self): + snippet = textwrap.dedent("""\ + match x: + case a, *b, c: + pass + """) + compiled_code, _ = self.check_positions_against_ast(snippet) + self.assertOpcodeSourcePositionIs(compiled_code, 'MATCH_SEQUENCE', + line=2, end_line=2, column=9, end_column=17, occurrence=1) + self.assertOpcodeSourcePositionIs(compiled_code, 'UNPACK_EX', + line=2, end_line=2, column=9, end_column=17, occurrence=1) + self.assertOpcodeSourcePositionIs(compiled_code, 'STORE_NAME', + line=2, end_line=2, column=9, end_column=17, occurrence=1) + self.assertOpcodeSourcePositionIs(compiled_code, 'STORE_NAME', + line=2, end_line=2, column=9, end_column=17, occurrence=2) + self.assertOpcodeSourcePositionIs(compiled_code, 'STORE_NAME', + line=2, end_line=2, column=9, end_column=17, occurrence=3) + + def test_matchcase_mapping(self): + snippet = textwrap.dedent("""\ + match x: + case {"a" : a, "b": b}: + pass + """) + compiled_code, _ = self.check_positions_against_ast(snippet) + self.assertOpcodeSourcePositionIs(compiled_code, 'MATCH_MAPPING', + line=2, end_line=2, column=9, end_column=26, occurrence=1) + self.assertOpcodeSourcePositionIs(compiled_code, 'MATCH_KEYS', + line=2, end_line=2, column=9, end_column=26, occurrence=1) + self.assertOpcodeSourcePositionIs(compiled_code, 'STORE_NAME', + line=2, end_line=2, column=9, end_column=26, occurrence=1) + self.assertOpcodeSourcePositionIs(compiled_code, 'STORE_NAME', + line=2, end_line=2, column=9, end_column=26, occurrence=2) + + def test_matchcase_mapping_wildcard(self): + snippet = textwrap.dedent("""\ + match x: + case {"a" : a, "b": b, **c}: + pass + """) + compiled_code, _ = self.check_positions_against_ast(snippet) + self.assertOpcodeSourcePositionIs(compiled_code, 'MATCH_MAPPING', + line=2, end_line=2, column=9, end_column=31, occurrence=1) + self.assertOpcodeSourcePositionIs(compiled_code, 'MATCH_KEYS', + line=2, end_line=2, column=9, end_column=31, occurrence=1) + self.assertOpcodeSourcePositionIs(compiled_code, 'STORE_NAME', + line=2, end_line=2, column=9, end_column=31, occurrence=1) + self.assertOpcodeSourcePositionIs(compiled_code, 'STORE_NAME', + line=2, end_line=2, column=9, end_column=31, occurrence=2) + + def test_matchcase_class(self): + snippet = textwrap.dedent("""\ + match x: + case C(a, b): + pass + """) + compiled_code, _ = self.check_positions_against_ast(snippet) + self.assertOpcodeSourcePositionIs(compiled_code, 'MATCH_CLASS', + line=2, end_line=2, column=9, end_column=16, occurrence=1) + self.assertOpcodeSourcePositionIs(compiled_code, 'UNPACK_SEQUENCE', + line=2, end_line=2, column=9, end_column=16, occurrence=1) + self.assertOpcodeSourcePositionIs(compiled_code, 'STORE_NAME', + line=2, end_line=2, column=9, end_column=16, occurrence=1) + self.assertOpcodeSourcePositionIs(compiled_code, 'STORE_NAME', + line=2, end_line=2, column=9, end_column=16, occurrence=2) + + def test_matchcase_or(self): + snippet = textwrap.dedent("""\ + match x: + case C(1) | C(2): + pass + """) + compiled_code, _ = self.check_positions_against_ast(snippet) + self.assertOpcodeSourcePositionIs(compiled_code, 'MATCH_CLASS', + line=2, end_line=2, column=9, end_column=13, occurrence=1) + self.assertOpcodeSourcePositionIs(compiled_code, 'MATCH_CLASS', + line=2, end_line=2, column=16, end_column=20, occurrence=2) + def test_very_long_line_end_offset(self): # Make sure we get the correct column offset for offsets # too large to store in a byte. @@ -1232,7 +1696,9 @@ f( with self.subTest(body): namespace = {} source = textwrap.dedent(source_template.format(body)) - exec(source, namespace) + with warnings.catch_warnings(): + warnings.simplefilter('ignore', SyntaxWarning) + exec(source, namespace) code = namespace["f"].__code__ self.assertOpcodeSourcePositionIs( code, @@ -1278,7 +1744,7 @@ f( source = "(\n lhs \n . \n rhs \n )()" code = compile(source, "<test>", "exec") self.assertOpcodeSourcePositionIs( - code, "LOAD_METHOD", line=4, end_line=4, column=5, end_column=8 + code, "LOAD_ATTR", line=4, end_line=4, column=5, end_column=8 ) self.assertOpcodeSourcePositionIs( code, "CALL", line=4, end_line=5, column=5, end_column=10 @@ -1309,9 +1775,6 @@ f( for source in [ "lambda: a", "(a for b in c)", - "[a for b in c]", - "{a for b in c}", - "{a: b for c in d}", ]: with self.subTest(source): code = compile(f"{source}, {source}", "<test>", "eval") @@ -1324,6 +1787,13 @@ f( list(code.co_consts[1].co_positions()), ) + def test_load_super_attr(self): + source = "class C:\n def __init__(self):\n super().__init__()" + code = compile(source, "<test>", "exec").co_consts[0].co_consts[1] + self.assertOpcodeSourcePositionIs( + code, "LOAD_GLOBAL", line=3, end_line=3, column=4, end_column=9 + ) + class TestExpressionStackSize(unittest.TestCase): # These tests check that the computed stack size for a code object diff --git a/Lib/test/test_compileall.py b/Lib/test/test_compileall.py index 05154c8f..9cd92ad3 100644 --- a/Lib/test/test_compileall.py +++ b/Lib/test/test_compileall.py @@ -18,6 +18,7 @@ from unittest import mock, skipUnless try: # compileall relies on ProcessPoolExecutor if ProcessPoolExecutor exists # and it can function. + from multiprocessing.util import _cleanup_tests as multiprocessing_cleanup_tests from concurrent.futures import ProcessPoolExecutor from concurrent.futures.process import _check_system_limits _check_system_limits() @@ -54,6 +55,8 @@ class CompileallTestsBase: def setUp(self): self.directory = tempfile.mkdtemp() + self.addCleanup(shutil.rmtree, self.directory) + self.source_path = os.path.join(self.directory, '_test.py') self.bc_path = importlib.util.cache_from_source(self.source_path) with open(self.source_path, 'w', encoding="utf-8") as file: @@ -66,9 +69,6 @@ class CompileallTestsBase: self.source_path3 = os.path.join(self.subdirectory, '_test3.py') shutil.copyfile(self.source_path, self.source_path3) - def tearDown(self): - shutil.rmtree(self.directory) - def add_bad_source_file(self): self.bad_source_path = os.path.join(self.directory, '_test_bad.py') with open(self.bad_source_path, 'w', encoding="utf-8") as file: @@ -307,9 +307,13 @@ class CompileallTestsBase: script_helper.make_script(path, "__init__", "") mods.append(script_helper.make_script(path, "mod", "def fn(): 1/0\nfn()\n")) + + if parallel: + self.addCleanup(multiprocessing_cleanup_tests) compileall.compile_dir( self.directory, quiet=True, ddir=ddir, workers=2 if parallel else 1) + self.assertTrue(mods) for mod in mods: self.assertTrue(mod.startswith(self.directory), mod) @@ -551,6 +555,7 @@ class CommandLineTestsBase: self.assertNotCompiled(self.barfn) @without_source_date_epoch # timestamp invalidation test + @support.requires_resource('cpu') def test_no_args_respects_force_flag(self): bazfn = script_helper.make_script(self.directory, 'baz', '') with self.temporary_pycache_prefix() as env: @@ -568,6 +573,7 @@ class CommandLineTestsBase: mtime2 = os.stat(pycpath).st_mtime self.assertNotEqual(mtime, mtime2) + @support.requires_resource('cpu') def test_no_args_respects_quiet_flag(self): script_helper.make_script(self.directory, 'baz', '') with self.temporary_pycache_prefix() as env: diff --git a/Lib/test/test_compiler_assemble.py b/Lib/test/test_compiler_assemble.py new file mode 100644 index 00000000..3e2a127d --- /dev/null +++ b/Lib/test/test_compiler_assemble.py @@ -0,0 +1,74 @@ + +import ast +import types + +from test.support.bytecode_helper import AssemblerTestCase + + +# Tests for the code-object creation stage of the compiler. + +class IsolatedAssembleTests(AssemblerTestCase): + + def complete_metadata(self, metadata, filename="myfile.py"): + if metadata is None: + metadata = {} + for key in ['name', 'qualname']: + metadata.setdefault(key, key) + for key in ['consts']: + metadata.setdefault(key, []) + for key in ['names', 'varnames', 'cellvars', 'freevars', 'fasthidden']: + metadata.setdefault(key, {}) + for key in ['argcount', 'posonlyargcount', 'kwonlyargcount']: + metadata.setdefault(key, 0) + metadata.setdefault('firstlineno', 1) + metadata.setdefault('filename', filename) + return metadata + + def assemble_test(self, insts, metadata, expected): + metadata = self.complete_metadata(metadata) + insts = self.complete_insts_info(insts) + + co = self.get_code_object(metadata['filename'], insts, metadata) + self.assertIsInstance(co, types.CodeType) + + expected_metadata = {} + for key, value in metadata.items(): + if key == "fasthidden": + # not exposed on code object + continue + if isinstance(value, list): + expected_metadata[key] = tuple(value) + elif isinstance(value, dict): + expected_metadata[key] = tuple(value.keys()) + else: + expected_metadata[key] = value + + for key, value in expected_metadata.items(): + self.assertEqual(getattr(co, "co_" + key), value) + + f = types.FunctionType(co, {}) + for args, res in expected.items(): + self.assertEqual(f(*args), res) + + def test_simple_expr(self): + metadata = { + 'filename' : 'avg.py', + 'name' : 'avg', + 'qualname' : 'stats.avg', + 'consts' : {2 : 0}, + 'argcount' : 2, + 'varnames' : {'x' : 0, 'y' : 1}, + } + + # code for "return (x+y)/2" + insts = [ + ('RESUME', 0), + ('LOAD_FAST', 0, 1), # 'x' + ('LOAD_FAST', 1, 1), # 'y' + ('BINARY_OP', 0, 1), # '+' + ('LOAD_CONST', 0, 1), # 2 + ('BINARY_OP', 11, 1), # '/' + ('RETURN_VALUE', 1), + ] + expected = {(3, 4) : 3.5, (-100, 200) : 50, (10, 18) : 14} + self.assemble_test(insts, metadata, expected) diff --git a/Lib/test/test_compiler_codegen.py b/Lib/test/test_compiler_codegen.py new file mode 100644 index 00000000..ea57df9c --- /dev/null +++ b/Lib/test/test_compiler_codegen.py @@ -0,0 +1,54 @@ + +from test.support.bytecode_helper import CodegenTestCase + +# Tests for the code-generation stage of the compiler. +# Examine the un-optimized code generated from the AST. + +class IsolatedCodeGenTests(CodegenTestCase): + + def codegen_test(self, snippet, expected_insts): + import ast + a = ast.parse(snippet, "my_file.py", "exec"); + insts = self.generate_code(a) + self.assertInstructionsMatch(insts, expected_insts) + + def test_if_expression(self): + snippet = "42 if True else 24" + false_lbl = self.Label() + expected = [ + ('RESUME', 0, 0), + ('LOAD_CONST', 0, 1), + ('POP_JUMP_IF_FALSE', false_lbl := self.Label(), 1), + ('LOAD_CONST', 1, 1), + ('JUMP', exit_lbl := self.Label()), + false_lbl, + ('LOAD_CONST', 2, 1), + exit_lbl, + ('POP_TOP', None), + ('LOAD_CONST', 3), + ('RETURN_VALUE', None), + ] + self.codegen_test(snippet, expected) + + def test_for_loop(self): + snippet = "for x in l:\n\tprint(x)" + false_lbl = self.Label() + expected = [ + ('RESUME', 0, 0), + ('LOAD_NAME', 0, 1), + ('GET_ITER', None, 1), + loop_lbl := self.Label(), + ('FOR_ITER', exit_lbl := self.Label(), 1), + ('STORE_NAME', 1, 1), + ('PUSH_NULL', None, 2), + ('LOAD_NAME', 2, 2), + ('LOAD_NAME', 1, 2), + ('CALL', 1, 2), + ('POP_TOP', None), + ('JUMP', loop_lbl), + exit_lbl, + ('END_FOR', None), + ('LOAD_CONST', 0), + ('RETURN_VALUE', None), + ] + self.codegen_test(snippet, expected) diff --git a/Lib/test/test_complex.py b/Lib/test/test_complex.py index 51ba1515..9180cca6 100644 --- a/Lib/test/test_complex.py +++ b/Lib/test/test_complex.py @@ -529,6 +529,12 @@ class ComplexTest(unittest.TestCase): self.assertFloatsAreIdentical(z.real, x) self.assertFloatsAreIdentical(z.imag, y) + def test_constructor_negative_nans_from_string(self): + self.assertEqual(copysign(1., complex("-nan").real), -1.) + self.assertEqual(copysign(1., complex("-nanj").imag), -1.) + self.assertEqual(copysign(1., complex("-nan-nanj").real), -1.) + self.assertEqual(copysign(1., complex("-nan-nanj").imag), -1.) + def test_underscores(self): # check underscores for lit in VALID_UNDERSCORE_LITERALS: @@ -569,6 +575,7 @@ class ComplexTest(unittest.TestCase): test(complex(NAN, 1), "(nan+1j)") test(complex(1, NAN), "(1+nanj)") test(complex(NAN, NAN), "(nan+nanj)") + test(complex(-NAN, -NAN), "(nan+nanj)") test(complex(0, INF), "infj") test(complex(0, -INF), "-infj") diff --git a/Lib/test/test_concurrent_futures.py b/Lib/test/test_concurrent_futures.py deleted file mode 100644 index 02c2fa06..00000000 --- a/Lib/test/test_concurrent_futures.py +++ /dev/null @@ -1,1626 +0,0 @@ -from test import support -from test.support import import_helper -from test.support import threading_helper - -# Skip tests if _multiprocessing wasn't built. -import_helper.import_module('_multiprocessing') - -from test.support import hashlib_helper -from test.support.script_helper import assert_python_ok - -import contextlib -import itertools -import logging -from logging.handlers import QueueHandler -import os -import queue -import sys -import threading -import time -import unittest -import weakref -from pickle import PicklingError - -from concurrent import futures -from concurrent.futures._base import ( - PENDING, RUNNING, CANCELLED, CANCELLED_AND_NOTIFIED, FINISHED, Future, - BrokenExecutor) -from concurrent.futures.process import BrokenProcessPool, _check_system_limits - -import multiprocessing.process -import multiprocessing.util -import multiprocessing as mp - - -if support.check_sanitizer(address=True, memory=True): - # bpo-46633: Skip the test because it is too slow when Python is built - # with ASAN/MSAN: between 5 and 20 minutes on GitHub Actions. - raise unittest.SkipTest("test too slow on ASAN/MSAN build") - - -def create_future(state=PENDING, exception=None, result=None): - f = Future() - f._state = state - f._exception = exception - f._result = result - return f - - -PENDING_FUTURE = create_future(state=PENDING) -RUNNING_FUTURE = create_future(state=RUNNING) -CANCELLED_FUTURE = create_future(state=CANCELLED) -CANCELLED_AND_NOTIFIED_FUTURE = create_future(state=CANCELLED_AND_NOTIFIED) -EXCEPTION_FUTURE = create_future(state=FINISHED, exception=OSError()) -SUCCESSFUL_FUTURE = create_future(state=FINISHED, result=42) - -INITIALIZER_STATUS = 'uninitialized' - -def mul(x, y): - return x * y - -def capture(*args, **kwargs): - return args, kwargs - -def sleep_and_raise(t): - time.sleep(t) - raise Exception('this is an exception') - -def sleep_and_print(t, msg): - time.sleep(t) - print(msg) - sys.stdout.flush() - -def init(x): - global INITIALIZER_STATUS - INITIALIZER_STATUS = x - -def get_init_status(): - return INITIALIZER_STATUS - -def init_fail(log_queue=None): - if log_queue is not None: - logger = logging.getLogger('concurrent.futures') - logger.addHandler(QueueHandler(log_queue)) - logger.setLevel('CRITICAL') - logger.propagate = False - time.sleep(0.1) # let some futures be scheduled - raise ValueError('error in initializer') - - -class MyObject(object): - def my_method(self): - pass - - -class EventfulGCObj(): - def __init__(self, mgr): - self.event = mgr.Event() - - def __del__(self): - self.event.set() - - -def make_dummy_object(_): - return MyObject() - - -class BaseTestCase(unittest.TestCase): - def setUp(self): - self._thread_key = threading_helper.threading_setup() - - def tearDown(self): - support.reap_children() - threading_helper.threading_cleanup(*self._thread_key) - - -class ExecutorMixin: - worker_count = 5 - executor_kwargs = {} - - def setUp(self): - super().setUp() - - self.t1 = time.monotonic() - if hasattr(self, "ctx"): - self.executor = self.executor_type( - max_workers=self.worker_count, - mp_context=self.get_context(), - **self.executor_kwargs) - else: - self.executor = self.executor_type( - max_workers=self.worker_count, - **self.executor_kwargs) - - def tearDown(self): - self.executor.shutdown(wait=True) - self.executor = None - - dt = time.monotonic() - self.t1 - if support.verbose: - print("%.2fs" % dt, end=' ') - self.assertLess(dt, 300, "synchronization issue: test lasted too long") - - super().tearDown() - - def get_context(self): - return mp.get_context(self.ctx) - - -class ThreadPoolMixin(ExecutorMixin): - executor_type = futures.ThreadPoolExecutor - - -class ProcessPoolForkMixin(ExecutorMixin): - executor_type = futures.ProcessPoolExecutor - ctx = "fork" - - def get_context(self): - try: - _check_system_limits() - except NotImplementedError: - self.skipTest("ProcessPoolExecutor unavailable on this system") - if sys.platform == "win32": - self.skipTest("require unix system") - return super().get_context() - - -class ProcessPoolSpawnMixin(ExecutorMixin): - executor_type = futures.ProcessPoolExecutor - ctx = "spawn" - - def get_context(self): - try: - _check_system_limits() - except NotImplementedError: - self.skipTest("ProcessPoolExecutor unavailable on this system") - return super().get_context() - - -class ProcessPoolForkserverMixin(ExecutorMixin): - executor_type = futures.ProcessPoolExecutor - ctx = "forkserver" - - def get_context(self): - try: - _check_system_limits() - except NotImplementedError: - self.skipTest("ProcessPoolExecutor unavailable on this system") - if sys.platform == "win32": - self.skipTest("require unix system") - return super().get_context() - - -def create_executor_tests(mixin, bases=(BaseTestCase,), - executor_mixins=(ThreadPoolMixin, - ProcessPoolForkMixin, - ProcessPoolForkserverMixin, - ProcessPoolSpawnMixin)): - def strip_mixin(name): - if name.endswith(('Mixin', 'Tests')): - return name[:-5] - elif name.endswith('Test'): - return name[:-4] - else: - return name - - for exe in executor_mixins: - name = ("%s%sTest" - % (strip_mixin(exe.__name__), strip_mixin(mixin.__name__))) - cls = type(name, (mixin,) + (exe,) + bases, {}) - globals()[name] = cls - - -class InitializerMixin(ExecutorMixin): - worker_count = 2 - - def setUp(self): - global INITIALIZER_STATUS - INITIALIZER_STATUS = 'uninitialized' - self.executor_kwargs = dict(initializer=init, - initargs=('initialized',)) - super().setUp() - - def test_initializer(self): - futures = [self.executor.submit(get_init_status) - for _ in range(self.worker_count)] - - for f in futures: - self.assertEqual(f.result(), 'initialized') - - -class FailingInitializerMixin(ExecutorMixin): - worker_count = 2 - - def setUp(self): - if hasattr(self, "ctx"): - # Pass a queue to redirect the child's logging output - self.mp_context = self.get_context() - self.log_queue = self.mp_context.Queue() - self.executor_kwargs = dict(initializer=init_fail, - initargs=(self.log_queue,)) - else: - # In a thread pool, the child shares our logging setup - # (see _assert_logged()) - self.mp_context = None - self.log_queue = None - self.executor_kwargs = dict(initializer=init_fail) - super().setUp() - - def test_initializer(self): - with self._assert_logged('ValueError: error in initializer'): - try: - future = self.executor.submit(get_init_status) - except BrokenExecutor: - # Perhaps the executor is already broken - pass - else: - with self.assertRaises(BrokenExecutor): - future.result() - # At some point, the executor should break - t1 = time.monotonic() - while not self.executor._broken: - if time.monotonic() - t1 > 5: - self.fail("executor not broken after 5 s.") - time.sleep(0.01) - # ... and from this point submit() is guaranteed to fail - with self.assertRaises(BrokenExecutor): - self.executor.submit(get_init_status) - - @contextlib.contextmanager - def _assert_logged(self, msg): - if self.log_queue is not None: - yield - output = [] - try: - while True: - output.append(self.log_queue.get_nowait().getMessage()) - except queue.Empty: - pass - else: - with self.assertLogs('concurrent.futures', 'CRITICAL') as cm: - yield - output = cm.output - self.assertTrue(any(msg in line for line in output), - output) - - -create_executor_tests(InitializerMixin) -create_executor_tests(FailingInitializerMixin) - - -class ExecutorShutdownTest: - def test_run_after_shutdown(self): - self.executor.shutdown() - self.assertRaises(RuntimeError, - self.executor.submit, - pow, 2, 5) - - def test_interpreter_shutdown(self): - # Test the atexit hook for shutdown of worker threads and processes - rc, out, err = assert_python_ok('-c', """if 1: - from concurrent.futures import {executor_type} - from time import sleep - from test.test_concurrent_futures import sleep_and_print - if __name__ == "__main__": - context = '{context}' - if context == "": - t = {executor_type}(5) - else: - from multiprocessing import get_context - context = get_context(context) - t = {executor_type}(5, mp_context=context) - t.submit(sleep_and_print, 1.0, "apple") - """.format(executor_type=self.executor_type.__name__, - context=getattr(self, "ctx", ""))) - # Errors in atexit hooks don't change the process exit code, check - # stderr manually. - self.assertFalse(err) - self.assertEqual(out.strip(), b"apple") - - def test_submit_after_interpreter_shutdown(self): - # Test the atexit hook for shutdown of worker threads and processes - rc, out, err = assert_python_ok('-c', """if 1: - import atexit - @atexit.register - def run_last(): - try: - t.submit(id, None) - except RuntimeError: - print("runtime-error") - raise - from concurrent.futures import {executor_type} - if __name__ == "__main__": - context = '{context}' - if not context: - t = {executor_type}(5) - else: - from multiprocessing import get_context - context = get_context(context) - t = {executor_type}(5, mp_context=context) - t.submit(id, 42).result() - """.format(executor_type=self.executor_type.__name__, - context=getattr(self, "ctx", ""))) - # Errors in atexit hooks don't change the process exit code, check - # stderr manually. - self.assertIn("RuntimeError: cannot schedule new futures", err.decode()) - self.assertEqual(out.strip(), b"runtime-error") - - def test_hang_issue12364(self): - fs = [self.executor.submit(time.sleep, 0.1) for _ in range(50)] - self.executor.shutdown() - for f in fs: - f.result() - - def test_cancel_futures(self): - assert self.worker_count <= 5, "test needs few workers" - fs = [self.executor.submit(time.sleep, .1) for _ in range(50)] - self.executor.shutdown(cancel_futures=True) - # We can't guarantee the exact number of cancellations, but we can - # guarantee that *some* were cancelled. With few workers, many of - # the submitted futures should have been cancelled. - cancelled = [fut for fut in fs if fut.cancelled()] - self.assertGreater(len(cancelled), 20) - - # Ensure the other futures were able to finish. - # Use "not fut.cancelled()" instead of "fut.done()" to include futures - # that may have been left in a pending state. - others = [fut for fut in fs if not fut.cancelled()] - for fut in others: - self.assertTrue(fut.done(), msg=f"{fut._state=}") - self.assertIsNone(fut.exception()) - - # Similar to the number of cancelled futures, we can't guarantee the - # exact number that completed. But, we can guarantee that at least - # one finished. - self.assertGreater(len(others), 0) - - def test_hang_gh83386(self): - """shutdown(wait=False) doesn't hang at exit with running futures. - - See https://github.com/python/cpython/issues/83386. - """ - if self.executor_type == futures.ProcessPoolExecutor: - raise unittest.SkipTest( - "Hangs, see https://github.com/python/cpython/issues/83386") - - rc, out, err = assert_python_ok('-c', """if True: - from concurrent.futures import {executor_type} - from test.test_concurrent_futures import sleep_and_print - if __name__ == "__main__": - if {context!r}: multiprocessing.set_start_method({context!r}) - t = {executor_type}(max_workers=3) - t.submit(sleep_and_print, 1.0, "apple") - t.shutdown(wait=False) - """.format(executor_type=self.executor_type.__name__, - context=getattr(self, 'ctx', None))) - self.assertFalse(err) - self.assertEqual(out.strip(), b"apple") - - -class ThreadPoolShutdownTest(ThreadPoolMixin, ExecutorShutdownTest, BaseTestCase): - def test_threads_terminate(self): - def acquire_lock(lock): - lock.acquire() - - sem = threading.Semaphore(0) - for i in range(3): - self.executor.submit(acquire_lock, sem) - self.assertEqual(len(self.executor._threads), 3) - for i in range(3): - sem.release() - self.executor.shutdown() - for t in self.executor._threads: - t.join() - - def test_context_manager_shutdown(self): - with futures.ThreadPoolExecutor(max_workers=5) as e: - executor = e - self.assertEqual(list(e.map(abs, range(-5, 5))), - [5, 4, 3, 2, 1, 0, 1, 2, 3, 4]) - - for t in executor._threads: - t.join() - - def test_del_shutdown(self): - executor = futures.ThreadPoolExecutor(max_workers=5) - res = executor.map(abs, range(-5, 5)) - threads = executor._threads - del executor - - for t in threads: - t.join() - - # Make sure the results were all computed before the - # executor got shutdown. - assert all([r == abs(v) for r, v in zip(res, range(-5, 5))]) - - def test_shutdown_no_wait(self): - # Ensure that the executor cleans up the threads when calling - # shutdown with wait=False - executor = futures.ThreadPoolExecutor(max_workers=5) - res = executor.map(abs, range(-5, 5)) - threads = executor._threads - executor.shutdown(wait=False) - for t in threads: - t.join() - - # Make sure the results were all computed before the - # executor got shutdown. - assert all([r == abs(v) for r, v in zip(res, range(-5, 5))]) - - - def test_thread_names_assigned(self): - executor = futures.ThreadPoolExecutor( - max_workers=5, thread_name_prefix='SpecialPool') - executor.map(abs, range(-5, 5)) - threads = executor._threads - del executor - support.gc_collect() # For PyPy or other GCs. - - for t in threads: - self.assertRegex(t.name, r'^SpecialPool_[0-4]$') - t.join() - - def test_thread_names_default(self): - executor = futures.ThreadPoolExecutor(max_workers=5) - executor.map(abs, range(-5, 5)) - threads = executor._threads - del executor - support.gc_collect() # For PyPy or other GCs. - - for t in threads: - # Ensure that our default name is reasonably sane and unique when - # no thread_name_prefix was supplied. - self.assertRegex(t.name, r'ThreadPoolExecutor-\d+_[0-4]$') - t.join() - - def test_cancel_futures_wait_false(self): - # Can only be reliably tested for TPE, since PPE often hangs with - # `wait=False` (even without *cancel_futures*). - rc, out, err = assert_python_ok('-c', """if True: - from concurrent.futures import ThreadPoolExecutor - from test.test_concurrent_futures import sleep_and_print - if __name__ == "__main__": - t = ThreadPoolExecutor() - t.submit(sleep_and_print, .1, "apple") - t.shutdown(wait=False, cancel_futures=True) - """) - # Errors in atexit hooks don't change the process exit code, check - # stderr manually. - self.assertFalse(err) - self.assertEqual(out.strip(), b"apple") - - -class ProcessPoolShutdownTest(ExecutorShutdownTest): - def test_processes_terminate(self): - def acquire_lock(lock): - lock.acquire() - - mp_context = self.get_context() - if mp_context.get_start_method(allow_none=False) == "fork": - # fork pre-spawns, not on demand. - expected_num_processes = self.worker_count - else: - expected_num_processes = 3 - - sem = mp_context.Semaphore(0) - for _ in range(3): - self.executor.submit(acquire_lock, sem) - self.assertEqual(len(self.executor._processes), expected_num_processes) - for _ in range(3): - sem.release() - processes = self.executor._processes - self.executor.shutdown() - - for p in processes.values(): - p.join() - - def test_context_manager_shutdown(self): - with futures.ProcessPoolExecutor( - max_workers=5, mp_context=self.get_context()) as e: - processes = e._processes - self.assertEqual(list(e.map(abs, range(-5, 5))), - [5, 4, 3, 2, 1, 0, 1, 2, 3, 4]) - - for p in processes.values(): - p.join() - - def test_del_shutdown(self): - executor = futures.ProcessPoolExecutor( - max_workers=5, mp_context=self.get_context()) - res = executor.map(abs, range(-5, 5)) - executor_manager_thread = executor._executor_manager_thread - processes = executor._processes - call_queue = executor._call_queue - executor_manager_thread = executor._executor_manager_thread - del executor - support.gc_collect() # For PyPy or other GCs. - - # Make sure that all the executor resources were properly cleaned by - # the shutdown process - executor_manager_thread.join() - for p in processes.values(): - p.join() - call_queue.join_thread() - - # Make sure the results were all computed before the - # executor got shutdown. - assert all([r == abs(v) for r, v in zip(res, range(-5, 5))]) - - def test_shutdown_no_wait(self): - # Ensure that the executor cleans up the processes when calling - # shutdown with wait=False - executor = futures.ProcessPoolExecutor( - max_workers=5, mp_context=self.get_context()) - res = executor.map(abs, range(-5, 5)) - processes = executor._processes - call_queue = executor._call_queue - executor_manager_thread = executor._executor_manager_thread - executor.shutdown(wait=False) - - # Make sure that all the executor resources were properly cleaned by - # the shutdown process - executor_manager_thread.join() - for p in processes.values(): - p.join() - call_queue.join_thread() - - # Make sure the results were all computed before the executor got - # shutdown. - assert all([r == abs(v) for r, v in zip(res, range(-5, 5))]) - - -create_executor_tests(ProcessPoolShutdownTest, - executor_mixins=(ProcessPoolForkMixin, - ProcessPoolForkserverMixin, - ProcessPoolSpawnMixin)) - - -class WaitTests: - def test_20369(self): - # See https://bugs.python.org/issue20369 - future = self.executor.submit(time.sleep, 1.5) - done, not_done = futures.wait([future, future], - return_when=futures.ALL_COMPLETED) - self.assertEqual({future}, done) - self.assertEqual(set(), not_done) - - - def test_first_completed(self): - future1 = self.executor.submit(mul, 21, 2) - future2 = self.executor.submit(time.sleep, 1.5) - - done, not_done = futures.wait( - [CANCELLED_FUTURE, future1, future2], - return_when=futures.FIRST_COMPLETED) - - self.assertEqual(set([future1]), done) - self.assertEqual(set([CANCELLED_FUTURE, future2]), not_done) - - def test_first_completed_some_already_completed(self): - future1 = self.executor.submit(time.sleep, 1.5) - - finished, pending = futures.wait( - [CANCELLED_AND_NOTIFIED_FUTURE, SUCCESSFUL_FUTURE, future1], - return_when=futures.FIRST_COMPLETED) - - self.assertEqual( - set([CANCELLED_AND_NOTIFIED_FUTURE, SUCCESSFUL_FUTURE]), - finished) - self.assertEqual(set([future1]), pending) - - def test_first_exception(self): - future1 = self.executor.submit(mul, 2, 21) - future2 = self.executor.submit(sleep_and_raise, 1.5) - future3 = self.executor.submit(time.sleep, 3) - - finished, pending = futures.wait( - [future1, future2, future3], - return_when=futures.FIRST_EXCEPTION) - - self.assertEqual(set([future1, future2]), finished) - self.assertEqual(set([future3]), pending) - - def test_first_exception_some_already_complete(self): - future1 = self.executor.submit(divmod, 21, 0) - future2 = self.executor.submit(time.sleep, 1.5) - - finished, pending = futures.wait( - [SUCCESSFUL_FUTURE, - CANCELLED_FUTURE, - CANCELLED_AND_NOTIFIED_FUTURE, - future1, future2], - return_when=futures.FIRST_EXCEPTION) - - self.assertEqual(set([SUCCESSFUL_FUTURE, - CANCELLED_AND_NOTIFIED_FUTURE, - future1]), finished) - self.assertEqual(set([CANCELLED_FUTURE, future2]), pending) - - def test_first_exception_one_already_failed(self): - future1 = self.executor.submit(time.sleep, 2) - - finished, pending = futures.wait( - [EXCEPTION_FUTURE, future1], - return_when=futures.FIRST_EXCEPTION) - - self.assertEqual(set([EXCEPTION_FUTURE]), finished) - self.assertEqual(set([future1]), pending) - - def test_all_completed(self): - future1 = self.executor.submit(divmod, 2, 0) - future2 = self.executor.submit(mul, 2, 21) - - finished, pending = futures.wait( - [SUCCESSFUL_FUTURE, - CANCELLED_AND_NOTIFIED_FUTURE, - EXCEPTION_FUTURE, - future1, - future2], - return_when=futures.ALL_COMPLETED) - - self.assertEqual(set([SUCCESSFUL_FUTURE, - CANCELLED_AND_NOTIFIED_FUTURE, - EXCEPTION_FUTURE, - future1, - future2]), finished) - self.assertEqual(set(), pending) - - def test_timeout(self): - future1 = self.executor.submit(mul, 6, 7) - future2 = self.executor.submit(time.sleep, 6) - - finished, pending = futures.wait( - [CANCELLED_AND_NOTIFIED_FUTURE, - EXCEPTION_FUTURE, - SUCCESSFUL_FUTURE, - future1, future2], - timeout=5, - return_when=futures.ALL_COMPLETED) - - self.assertEqual(set([CANCELLED_AND_NOTIFIED_FUTURE, - EXCEPTION_FUTURE, - SUCCESSFUL_FUTURE, - future1]), finished) - self.assertEqual(set([future2]), pending) - - -class ThreadPoolWaitTests(ThreadPoolMixin, WaitTests, BaseTestCase): - - def test_pending_calls_race(self): - # Issue #14406: multi-threaded race condition when waiting on all - # futures. - event = threading.Event() - def future_func(): - event.wait() - oldswitchinterval = sys.getswitchinterval() - sys.setswitchinterval(1e-6) - try: - fs = {self.executor.submit(future_func) for i in range(100)} - event.set() - futures.wait(fs, return_when=futures.ALL_COMPLETED) - finally: - sys.setswitchinterval(oldswitchinterval) - - -create_executor_tests(WaitTests, - executor_mixins=(ProcessPoolForkMixin, - ProcessPoolForkserverMixin, - ProcessPoolSpawnMixin)) - - -class AsCompletedTests: - # TODO(brian@sweetapp.com): Should have a test with a non-zero timeout. - def test_no_timeout(self): - future1 = self.executor.submit(mul, 2, 21) - future2 = self.executor.submit(mul, 7, 6) - - completed = set(futures.as_completed( - [CANCELLED_AND_NOTIFIED_FUTURE, - EXCEPTION_FUTURE, - SUCCESSFUL_FUTURE, - future1, future2])) - self.assertEqual(set( - [CANCELLED_AND_NOTIFIED_FUTURE, - EXCEPTION_FUTURE, - SUCCESSFUL_FUTURE, - future1, future2]), - completed) - - def test_zero_timeout(self): - future1 = self.executor.submit(time.sleep, 2) - completed_futures = set() - try: - for future in futures.as_completed( - [CANCELLED_AND_NOTIFIED_FUTURE, - EXCEPTION_FUTURE, - SUCCESSFUL_FUTURE, - future1], - timeout=0): - completed_futures.add(future) - except futures.TimeoutError: - pass - - self.assertEqual(set([CANCELLED_AND_NOTIFIED_FUTURE, - EXCEPTION_FUTURE, - SUCCESSFUL_FUTURE]), - completed_futures) - - def test_duplicate_futures(self): - # Issue 20367. Duplicate futures should not raise exceptions or give - # duplicate responses. - # Issue #31641: accept arbitrary iterables. - future1 = self.executor.submit(time.sleep, 2) - completed = [ - f for f in futures.as_completed(itertools.repeat(future1, 3)) - ] - self.assertEqual(len(completed), 1) - - def test_free_reference_yielded_future(self): - # Issue #14406: Generator should not keep references - # to finished futures. - futures_list = [Future() for _ in range(8)] - futures_list.append(create_future(state=CANCELLED_AND_NOTIFIED)) - futures_list.append(create_future(state=FINISHED, result=42)) - - with self.assertRaises(futures.TimeoutError): - for future in futures.as_completed(futures_list, timeout=0): - futures_list.remove(future) - wr = weakref.ref(future) - del future - support.gc_collect() # For PyPy or other GCs. - self.assertIsNone(wr()) - - futures_list[0].set_result("test") - for future in futures.as_completed(futures_list): - futures_list.remove(future) - wr = weakref.ref(future) - del future - support.gc_collect() # For PyPy or other GCs. - self.assertIsNone(wr()) - if futures_list: - futures_list[0].set_result("test") - - def test_correct_timeout_exception_msg(self): - futures_list = [CANCELLED_AND_NOTIFIED_FUTURE, PENDING_FUTURE, - RUNNING_FUTURE, SUCCESSFUL_FUTURE] - - with self.assertRaises(futures.TimeoutError) as cm: - list(futures.as_completed(futures_list, timeout=0)) - - self.assertEqual(str(cm.exception), '2 (of 4) futures unfinished') - - -create_executor_tests(AsCompletedTests) - - -class ExecutorTest: - # Executor.shutdown() and context manager usage is tested by - # ExecutorShutdownTest. - def test_submit(self): - future = self.executor.submit(pow, 2, 8) - self.assertEqual(256, future.result()) - - def test_submit_keyword(self): - future = self.executor.submit(mul, 2, y=8) - self.assertEqual(16, future.result()) - future = self.executor.submit(capture, 1, self=2, fn=3) - self.assertEqual(future.result(), ((1,), {'self': 2, 'fn': 3})) - with self.assertRaises(TypeError): - self.executor.submit(fn=capture, arg=1) - with self.assertRaises(TypeError): - self.executor.submit(arg=1) - - def test_map(self): - self.assertEqual( - list(self.executor.map(pow, range(10), range(10))), - list(map(pow, range(10), range(10)))) - - self.assertEqual( - list(self.executor.map(pow, range(10), range(10), chunksize=3)), - list(map(pow, range(10), range(10)))) - - def test_map_exception(self): - i = self.executor.map(divmod, [1, 1, 1, 1], [2, 3, 0, 5]) - self.assertEqual(i.__next__(), (0, 1)) - self.assertEqual(i.__next__(), (0, 1)) - self.assertRaises(ZeroDivisionError, i.__next__) - - def test_map_timeout(self): - results = [] - try: - for i in self.executor.map(time.sleep, - [0, 0, 6], - timeout=5): - results.append(i) - except futures.TimeoutError: - pass - else: - self.fail('expected TimeoutError') - - self.assertEqual([None, None], results) - - def test_shutdown_race_issue12456(self): - # Issue #12456: race condition at shutdown where trying to post a - # sentinel in the call queue blocks (the queue is full while processes - # have exited). - self.executor.map(str, [2] * (self.worker_count + 1)) - self.executor.shutdown() - - @support.cpython_only - def test_no_stale_references(self): - # Issue #16284: check that the executors don't unnecessarily hang onto - # references. - my_object = MyObject() - my_object_collected = threading.Event() - my_object_callback = weakref.ref( - my_object, lambda obj: my_object_collected.set()) - # Deliberately discarding the future. - self.executor.submit(my_object.my_method) - del my_object - - collected = my_object_collected.wait(timeout=support.SHORT_TIMEOUT) - self.assertTrue(collected, - "Stale reference not collected within timeout.") - - def test_max_workers_negative(self): - for number in (0, -1): - with self.assertRaisesRegex(ValueError, - "max_workers must be greater " - "than 0"): - self.executor_type(max_workers=number) - - def test_free_reference(self): - # Issue #14406: Result iterator should not keep an internal - # reference to result objects. - for obj in self.executor.map(make_dummy_object, range(10)): - wr = weakref.ref(obj) - del obj - support.gc_collect() # For PyPy or other GCs. - self.assertIsNone(wr()) - - -class ThreadPoolExecutorTest(ThreadPoolMixin, ExecutorTest, BaseTestCase): - def test_map_submits_without_iteration(self): - """Tests verifying issue 11777.""" - finished = [] - def record_finished(n): - finished.append(n) - - self.executor.map(record_finished, range(10)) - self.executor.shutdown(wait=True) - self.assertCountEqual(finished, range(10)) - - def test_default_workers(self): - executor = self.executor_type() - expected = min(32, (os.cpu_count() or 1) + 4) - self.assertEqual(executor._max_workers, expected) - - def test_saturation(self): - executor = self.executor_type(4) - def acquire_lock(lock): - lock.acquire() - - sem = threading.Semaphore(0) - for i in range(15 * executor._max_workers): - executor.submit(acquire_lock, sem) - self.assertEqual(len(executor._threads), executor._max_workers) - for i in range(15 * executor._max_workers): - sem.release() - executor.shutdown(wait=True) - - def test_idle_thread_reuse(self): - executor = self.executor_type() - executor.submit(mul, 21, 2).result() - executor.submit(mul, 6, 7).result() - executor.submit(mul, 3, 14).result() - self.assertEqual(len(executor._threads), 1) - executor.shutdown(wait=True) - - @unittest.skipUnless(hasattr(os, 'register_at_fork'), 'need os.register_at_fork') - def test_hang_global_shutdown_lock(self): - # bpo-45021: _global_shutdown_lock should be reinitialized in the child - # process, otherwise it will never exit - def submit(pool): - pool.submit(submit, pool) - - with futures.ThreadPoolExecutor(1) as pool: - pool.submit(submit, pool) - - for _ in range(50): - with futures.ProcessPoolExecutor(1, mp_context=mp.get_context('fork')) as workers: - workers.submit(tuple) - - def test_executor_map_current_future_cancel(self): - stop_event = threading.Event() - log = [] - - def log_n_wait(ident): - log.append(f"{ident=} started") - try: - stop_event.wait() - finally: - log.append(f"{ident=} stopped") - - with self.executor_type(max_workers=1) as pool: - # submit work to saturate the pool - fut = pool.submit(log_n_wait, ident="first") - try: - with contextlib.closing( - pool.map(log_n_wait, ["second", "third"], timeout=0) - ) as gen: - with self.assertRaises(TimeoutError): - next(gen) - finally: - stop_event.set() - fut.result() - # ident='second' is cancelled as a result of raising a TimeoutError - # ident='third' is cancelled because it remained in the collection of futures - self.assertListEqual(log, ["ident='first' started", "ident='first' stopped"]) - - -class ProcessPoolExecutorTest(ExecutorTest): - - @unittest.skipUnless(sys.platform=='win32', 'Windows-only process limit') - def test_max_workers_too_large(self): - with self.assertRaisesRegex(ValueError, - "max_workers must be <= 61"): - futures.ProcessPoolExecutor(max_workers=62) - - def test_killed_child(self): - # When a child process is abruptly terminated, the whole pool gets - # "broken". - futures = [self.executor.submit(time.sleep, 3)] - # Get one of the processes, and terminate (kill) it - p = next(iter(self.executor._processes.values())) - p.terminate() - for fut in futures: - self.assertRaises(BrokenProcessPool, fut.result) - # Submitting other jobs fails as well. - self.assertRaises(BrokenProcessPool, self.executor.submit, pow, 2, 8) - - def test_map_chunksize(self): - def bad_map(): - list(self.executor.map(pow, range(40), range(40), chunksize=-1)) - - ref = list(map(pow, range(40), range(40))) - self.assertEqual( - list(self.executor.map(pow, range(40), range(40), chunksize=6)), - ref) - self.assertEqual( - list(self.executor.map(pow, range(40), range(40), chunksize=50)), - ref) - self.assertEqual( - list(self.executor.map(pow, range(40), range(40), chunksize=40)), - ref) - self.assertRaises(ValueError, bad_map) - - @classmethod - def _test_traceback(cls): - raise RuntimeError(123) # some comment - - def test_traceback(self): - # We want ensure that the traceback from the child process is - # contained in the traceback raised in the main process. - future = self.executor.submit(self._test_traceback) - with self.assertRaises(Exception) as cm: - future.result() - - exc = cm.exception - self.assertIs(type(exc), RuntimeError) - self.assertEqual(exc.args, (123,)) - cause = exc.__cause__ - self.assertIs(type(cause), futures.process._RemoteTraceback) - self.assertIn('raise RuntimeError(123) # some comment', cause.tb) - - with support.captured_stderr() as f1: - try: - raise exc - except RuntimeError: - sys.excepthook(*sys.exc_info()) - self.assertIn('raise RuntimeError(123) # some comment', - f1.getvalue()) - - @hashlib_helper.requires_hashdigest('md5') - def test_ressources_gced_in_workers(self): - # Ensure that argument for a job are correctly gc-ed after the job - # is finished - mgr = self.get_context().Manager() - obj = EventfulGCObj(mgr) - future = self.executor.submit(id, obj) - future.result() - - self.assertTrue(obj.event.wait(timeout=1)) - - # explicitly destroy the object to ensure that EventfulGCObj.__del__() - # is called while manager is still running. - obj = None - support.gc_collect() - - mgr.shutdown() - mgr.join() - - def test_saturation(self): - executor = self.executor - mp_context = self.get_context() - sem = mp_context.Semaphore(0) - job_count = 15 * executor._max_workers - for _ in range(job_count): - executor.submit(sem.acquire) - self.assertEqual(len(executor._processes), executor._max_workers) - for _ in range(job_count): - sem.release() - - def test_idle_process_reuse_one(self): - executor = self.executor - assert executor._max_workers >= 4 - if self.get_context().get_start_method(allow_none=False) == "fork": - raise unittest.SkipTest("Incompatible with the fork start method.") - executor.submit(mul, 21, 2).result() - executor.submit(mul, 6, 7).result() - executor.submit(mul, 3, 14).result() - self.assertEqual(len(executor._processes), 1) - - def test_idle_process_reuse_multiple(self): - executor = self.executor - assert executor._max_workers <= 5 - if self.get_context().get_start_method(allow_none=False) == "fork": - raise unittest.SkipTest("Incompatible with the fork start method.") - executor.submit(mul, 12, 7).result() - executor.submit(mul, 33, 25) - executor.submit(mul, 25, 26).result() - executor.submit(mul, 18, 29) - executor.submit(mul, 1, 2).result() - executor.submit(mul, 0, 9) - self.assertLessEqual(len(executor._processes), 3) - executor.shutdown() - - def test_max_tasks_per_child(self): - context = self.get_context() - if context.get_start_method(allow_none=False) == "fork": - with self.assertRaises(ValueError): - self.executor_type(1, mp_context=context, max_tasks_per_child=3) - return - # not using self.executor as we need to control construction. - # arguably this could go in another class w/o that mixin. - executor = self.executor_type( - 1, mp_context=context, max_tasks_per_child=3) - f1 = executor.submit(os.getpid) - original_pid = f1.result() - # The worker pid remains the same as the worker could be reused - f2 = executor.submit(os.getpid) - self.assertEqual(f2.result(), original_pid) - self.assertEqual(len(executor._processes), 1) - f3 = executor.submit(os.getpid) - self.assertEqual(f3.result(), original_pid) - - # A new worker is spawned, with a statistically different pid, - # while the previous was reaped. - f4 = executor.submit(os.getpid) - new_pid = f4.result() - self.assertNotEqual(original_pid, new_pid) - self.assertEqual(len(executor._processes), 1) - - executor.shutdown() - - def test_max_tasks_per_child_defaults_to_spawn_context(self): - # not using self.executor as we need to control construction. - # arguably this could go in another class w/o that mixin. - executor = self.executor_type(1, max_tasks_per_child=3) - self.assertEqual(executor._mp_context.get_start_method(), "spawn") - - def test_max_tasks_early_shutdown(self): - context = self.get_context() - if context.get_start_method(allow_none=False) == "fork": - raise unittest.SkipTest("Incompatible with the fork start method.") - # not using self.executor as we need to control construction. - # arguably this could go in another class w/o that mixin. - executor = self.executor_type( - 3, mp_context=context, max_tasks_per_child=1) - futures = [] - for i in range(6): - futures.append(executor.submit(mul, i, i)) - executor.shutdown() - for i, future in enumerate(futures): - self.assertEqual(future.result(), mul(i, i)) - - -create_executor_tests(ProcessPoolExecutorTest, - executor_mixins=(ProcessPoolForkMixin, - ProcessPoolForkserverMixin, - ProcessPoolSpawnMixin)) - -def _crash(delay=None): - """Induces a segfault.""" - if delay: - time.sleep(delay) - import faulthandler - faulthandler.disable() - faulthandler._sigsegv() - - -def _exit(): - """Induces a sys exit with exitcode 1.""" - sys.exit(1) - - -def _raise_error(Err): - """Function that raises an Exception in process.""" - raise Err() - - -def _raise_error_ignore_stderr(Err): - """Function that raises an Exception in process and ignores stderr.""" - import io - sys.stderr = io.StringIO() - raise Err() - - -def _return_instance(cls): - """Function that returns a instance of cls.""" - return cls() - - -class CrashAtPickle(object): - """Bad object that triggers a segfault at pickling time.""" - def __reduce__(self): - _crash() - - -class CrashAtUnpickle(object): - """Bad object that triggers a segfault at unpickling time.""" - def __reduce__(self): - return _crash, () - - -class ExitAtPickle(object): - """Bad object that triggers a process exit at pickling time.""" - def __reduce__(self): - _exit() - - -class ExitAtUnpickle(object): - """Bad object that triggers a process exit at unpickling time.""" - def __reduce__(self): - return _exit, () - - -class ErrorAtPickle(object): - """Bad object that triggers an error at pickling time.""" - def __reduce__(self): - from pickle import PicklingError - raise PicklingError("Error in pickle") - - -class ErrorAtUnpickle(object): - """Bad object that triggers an error at unpickling time.""" - def __reduce__(self): - from pickle import UnpicklingError - return _raise_error_ignore_stderr, (UnpicklingError, ) - - -class ExecutorDeadlockTest: - TIMEOUT = support.SHORT_TIMEOUT - - def _fail_on_deadlock(self, executor): - # If we did not recover before TIMEOUT seconds, consider that the - # executor is in a deadlock state and forcefully clean all its - # composants. - import faulthandler - from tempfile import TemporaryFile - with TemporaryFile(mode="w+") as f: - faulthandler.dump_traceback(file=f) - f.seek(0) - tb = f.read() - for p in executor._processes.values(): - p.terminate() - # This should be safe to call executor.shutdown here as all possible - # deadlocks should have been broken. - executor.shutdown(wait=True) - print(f"\nTraceback:\n {tb}", file=sys.__stderr__) - self.fail(f"Executor deadlock:\n\n{tb}") - - - def _check_crash(self, error, func, *args, ignore_stderr=False): - # test for deadlock caused by crashes in a pool - self.executor.shutdown(wait=True) - - executor = self.executor_type( - max_workers=2, mp_context=self.get_context()) - res = executor.submit(func, *args) - - if ignore_stderr: - cm = support.captured_stderr() - else: - cm = contextlib.nullcontext() - - try: - with self.assertRaises(error): - with cm: - res.result(timeout=self.TIMEOUT) - except futures.TimeoutError: - # If we did not recover before TIMEOUT seconds, - # consider that the executor is in a deadlock state - self._fail_on_deadlock(executor) - executor.shutdown(wait=True) - - def test_error_at_task_pickle(self): - # Check problem occurring while pickling a task in - # the task_handler thread - self._check_crash(PicklingError, id, ErrorAtPickle()) - - def test_exit_at_task_unpickle(self): - # Check problem occurring while unpickling a task on workers - self._check_crash(BrokenProcessPool, id, ExitAtUnpickle()) - - def test_error_at_task_unpickle(self): - # Check problem occurring while unpickling a task on workers - self._check_crash(BrokenProcessPool, id, ErrorAtUnpickle()) - - def test_crash_at_task_unpickle(self): - # Check problem occurring while unpickling a task on workers - self._check_crash(BrokenProcessPool, id, CrashAtUnpickle()) - - def test_crash_during_func_exec_on_worker(self): - # Check problem occurring during func execution on workers - self._check_crash(BrokenProcessPool, _crash) - - def test_exit_during_func_exec_on_worker(self): - # Check problem occurring during func execution on workers - self._check_crash(SystemExit, _exit) - - def test_error_during_func_exec_on_worker(self): - # Check problem occurring during func execution on workers - self._check_crash(RuntimeError, _raise_error, RuntimeError) - - def test_crash_during_result_pickle_on_worker(self): - # Check problem occurring while pickling a task result - # on workers - self._check_crash(BrokenProcessPool, _return_instance, CrashAtPickle) - - def test_exit_during_result_pickle_on_worker(self): - # Check problem occurring while pickling a task result - # on workers - self._check_crash(SystemExit, _return_instance, ExitAtPickle) - - def test_error_during_result_pickle_on_worker(self): - # Check problem occurring while pickling a task result - # on workers - self._check_crash(PicklingError, _return_instance, ErrorAtPickle) - - def test_error_during_result_unpickle_in_result_handler(self): - # Check problem occurring while unpickling a task in - # the result_handler thread - self._check_crash(BrokenProcessPool, - _return_instance, ErrorAtUnpickle, - ignore_stderr=True) - - def test_exit_during_result_unpickle_in_result_handler(self): - # Check problem occurring while unpickling a task in - # the result_handler thread - self._check_crash(BrokenProcessPool, _return_instance, ExitAtUnpickle) - - def test_shutdown_deadlock(self): - # Test that the pool calling shutdown do not cause deadlock - # if a worker fails after the shutdown call. - self.executor.shutdown(wait=True) - with self.executor_type(max_workers=2, - mp_context=self.get_context()) as executor: - self.executor = executor # Allow clean up in fail_on_deadlock - f = executor.submit(_crash, delay=.1) - executor.shutdown(wait=True) - with self.assertRaises(BrokenProcessPool): - f.result() - - def test_shutdown_deadlock_pickle(self): - # Test that the pool calling shutdown with wait=False does not cause - # a deadlock if a task fails at pickle after the shutdown call. - # Reported in bpo-39104. - self.executor.shutdown(wait=True) - with self.executor_type(max_workers=2, - mp_context=self.get_context()) as executor: - self.executor = executor # Allow clean up in fail_on_deadlock - - # Start the executor and get the executor_manager_thread to collect - # the threads and avoid dangling thread that should be cleaned up - # asynchronously. - executor.submit(id, 42).result() - executor_manager = executor._executor_manager_thread - - # Submit a task that fails at pickle and shutdown the executor - # without waiting - f = executor.submit(id, ErrorAtPickle()) - executor.shutdown(wait=False) - with self.assertRaises(PicklingError): - f.result() - - # Make sure the executor is eventually shutdown and do not leave - # dangling threads - executor_manager.join() - - -create_executor_tests(ExecutorDeadlockTest, - executor_mixins=(ProcessPoolForkMixin, - ProcessPoolForkserverMixin, - ProcessPoolSpawnMixin)) - - -class FutureTests(BaseTestCase): - def test_done_callback_with_result(self): - callback_result = None - def fn(callback_future): - nonlocal callback_result - callback_result = callback_future.result() - - f = Future() - f.add_done_callback(fn) - f.set_result(5) - self.assertEqual(5, callback_result) - - def test_done_callback_with_exception(self): - callback_exception = None - def fn(callback_future): - nonlocal callback_exception - callback_exception = callback_future.exception() - - f = Future() - f.add_done_callback(fn) - f.set_exception(Exception('test')) - self.assertEqual(('test',), callback_exception.args) - - def test_done_callback_with_cancel(self): - was_cancelled = None - def fn(callback_future): - nonlocal was_cancelled - was_cancelled = callback_future.cancelled() - - f = Future() - f.add_done_callback(fn) - self.assertTrue(f.cancel()) - self.assertTrue(was_cancelled) - - def test_done_callback_raises(self): - with support.captured_stderr() as stderr: - raising_was_called = False - fn_was_called = False - - def raising_fn(callback_future): - nonlocal raising_was_called - raising_was_called = True - raise Exception('doh!') - - def fn(callback_future): - nonlocal fn_was_called - fn_was_called = True - - f = Future() - f.add_done_callback(raising_fn) - f.add_done_callback(fn) - f.set_result(5) - self.assertTrue(raising_was_called) - self.assertTrue(fn_was_called) - self.assertIn('Exception: doh!', stderr.getvalue()) - - def test_done_callback_already_successful(self): - callback_result = None - def fn(callback_future): - nonlocal callback_result - callback_result = callback_future.result() - - f = Future() - f.set_result(5) - f.add_done_callback(fn) - self.assertEqual(5, callback_result) - - def test_done_callback_already_failed(self): - callback_exception = None - def fn(callback_future): - nonlocal callback_exception - callback_exception = callback_future.exception() - - f = Future() - f.set_exception(Exception('test')) - f.add_done_callback(fn) - self.assertEqual(('test',), callback_exception.args) - - def test_done_callback_already_cancelled(self): - was_cancelled = None - def fn(callback_future): - nonlocal was_cancelled - was_cancelled = callback_future.cancelled() - - f = Future() - self.assertTrue(f.cancel()) - f.add_done_callback(fn) - self.assertTrue(was_cancelled) - - def test_done_callback_raises_already_succeeded(self): - with support.captured_stderr() as stderr: - def raising_fn(callback_future): - raise Exception('doh!') - - f = Future() - - # Set the result first to simulate a future that runs instantly, - # effectively allowing the callback to be run immediately. - f.set_result(5) - f.add_done_callback(raising_fn) - - self.assertIn('exception calling callback for', stderr.getvalue()) - self.assertIn('doh!', stderr.getvalue()) - - - def test_repr(self): - self.assertRegex(repr(PENDING_FUTURE), - '<Future at 0x[0-9a-f]+ state=pending>') - self.assertRegex(repr(RUNNING_FUTURE), - '<Future at 0x[0-9a-f]+ state=running>') - self.assertRegex(repr(CANCELLED_FUTURE), - '<Future at 0x[0-9a-f]+ state=cancelled>') - self.assertRegex(repr(CANCELLED_AND_NOTIFIED_FUTURE), - '<Future at 0x[0-9a-f]+ state=cancelled>') - self.assertRegex( - repr(EXCEPTION_FUTURE), - '<Future at 0x[0-9a-f]+ state=finished raised OSError>') - self.assertRegex( - repr(SUCCESSFUL_FUTURE), - '<Future at 0x[0-9a-f]+ state=finished returned int>') - - - def test_cancel(self): - f1 = create_future(state=PENDING) - f2 = create_future(state=RUNNING) - f3 = create_future(state=CANCELLED) - f4 = create_future(state=CANCELLED_AND_NOTIFIED) - f5 = create_future(state=FINISHED, exception=OSError()) - f6 = create_future(state=FINISHED, result=5) - - self.assertTrue(f1.cancel()) - self.assertEqual(f1._state, CANCELLED) - - self.assertFalse(f2.cancel()) - self.assertEqual(f2._state, RUNNING) - - self.assertTrue(f3.cancel()) - self.assertEqual(f3._state, CANCELLED) - - self.assertTrue(f4.cancel()) - self.assertEqual(f4._state, CANCELLED_AND_NOTIFIED) - - self.assertFalse(f5.cancel()) - self.assertEqual(f5._state, FINISHED) - - self.assertFalse(f6.cancel()) - self.assertEqual(f6._state, FINISHED) - - def test_cancelled(self): - self.assertFalse(PENDING_FUTURE.cancelled()) - self.assertFalse(RUNNING_FUTURE.cancelled()) - self.assertTrue(CANCELLED_FUTURE.cancelled()) - self.assertTrue(CANCELLED_AND_NOTIFIED_FUTURE.cancelled()) - self.assertFalse(EXCEPTION_FUTURE.cancelled()) - self.assertFalse(SUCCESSFUL_FUTURE.cancelled()) - - def test_done(self): - self.assertFalse(PENDING_FUTURE.done()) - self.assertFalse(RUNNING_FUTURE.done()) - self.assertTrue(CANCELLED_FUTURE.done()) - self.assertTrue(CANCELLED_AND_NOTIFIED_FUTURE.done()) - self.assertTrue(EXCEPTION_FUTURE.done()) - self.assertTrue(SUCCESSFUL_FUTURE.done()) - - def test_running(self): - self.assertFalse(PENDING_FUTURE.running()) - self.assertTrue(RUNNING_FUTURE.running()) - self.assertFalse(CANCELLED_FUTURE.running()) - self.assertFalse(CANCELLED_AND_NOTIFIED_FUTURE.running()) - self.assertFalse(EXCEPTION_FUTURE.running()) - self.assertFalse(SUCCESSFUL_FUTURE.running()) - - def test_result_with_timeout(self): - self.assertRaises(futures.TimeoutError, - PENDING_FUTURE.result, timeout=0) - self.assertRaises(futures.TimeoutError, - RUNNING_FUTURE.result, timeout=0) - self.assertRaises(futures.CancelledError, - CANCELLED_FUTURE.result, timeout=0) - self.assertRaises(futures.CancelledError, - CANCELLED_AND_NOTIFIED_FUTURE.result, timeout=0) - self.assertRaises(OSError, EXCEPTION_FUTURE.result, timeout=0) - self.assertEqual(SUCCESSFUL_FUTURE.result(timeout=0), 42) - - def test_result_with_success(self): - # TODO(brian@sweetapp.com): This test is timing dependent. - def notification(): - # Wait until the main thread is waiting for the result. - time.sleep(1) - f1.set_result(42) - - f1 = create_future(state=PENDING) - t = threading.Thread(target=notification) - t.start() - - self.assertEqual(f1.result(timeout=5), 42) - t.join() - - def test_result_with_cancel(self): - # TODO(brian@sweetapp.com): This test is timing dependent. - def notification(): - # Wait until the main thread is waiting for the result. - time.sleep(1) - f1.cancel() - - f1 = create_future(state=PENDING) - t = threading.Thread(target=notification) - t.start() - - self.assertRaises(futures.CancelledError, - f1.result, timeout=support.SHORT_TIMEOUT) - t.join() - - def test_exception_with_timeout(self): - self.assertRaises(futures.TimeoutError, - PENDING_FUTURE.exception, timeout=0) - self.assertRaises(futures.TimeoutError, - RUNNING_FUTURE.exception, timeout=0) - self.assertRaises(futures.CancelledError, - CANCELLED_FUTURE.exception, timeout=0) - self.assertRaises(futures.CancelledError, - CANCELLED_AND_NOTIFIED_FUTURE.exception, timeout=0) - self.assertTrue(isinstance(EXCEPTION_FUTURE.exception(timeout=0), - OSError)) - self.assertEqual(SUCCESSFUL_FUTURE.exception(timeout=0), None) - - def test_exception_with_success(self): - def notification(): - # Wait until the main thread is waiting for the exception. - time.sleep(1) - with f1._condition: - f1._state = FINISHED - f1._exception = OSError() - f1._condition.notify_all() - - f1 = create_future(state=PENDING) - t = threading.Thread(target=notification) - t.start() - - self.assertTrue(isinstance(f1.exception(timeout=support.SHORT_TIMEOUT), OSError)) - t.join() - - def test_multiple_set_result(self): - f = create_future(state=PENDING) - f.set_result(1) - - with self.assertRaisesRegex( - futures.InvalidStateError, - 'FINISHED: <Future at 0x[0-9a-f]+ ' - 'state=finished returned int>' - ): - f.set_result(2) - - self.assertTrue(f.done()) - self.assertEqual(f.result(), 1) - - def test_multiple_set_exception(self): - f = create_future(state=PENDING) - e = ValueError() - f.set_exception(e) - - with self.assertRaisesRegex( - futures.InvalidStateError, - 'FINISHED: <Future at 0x[0-9a-f]+ ' - 'state=finished raised ValueError>' - ): - f.set_exception(Exception()) - - self.assertEqual(f.exception(), e) - - -def setUpModule(): - unittest.addModuleCleanup(multiprocessing.util._cleanup_tests) - thread_info = threading_helper.threading_setup() - unittest.addModuleCleanup(threading_helper.threading_cleanup, *thread_info) - - -if __name__ == "__main__": - unittest.main() diff --git a/Lib/test/test_concurrent_futures/__init__.py b/Lib/test/test_concurrent_futures/__init__.py new file mode 100644 index 00000000..430fa93a --- /dev/null +++ b/Lib/test/test_concurrent_futures/__init__.py @@ -0,0 +1,16 @@ +import os.path +import unittest +from test import support +from test.support import import_helper + +# Skip tests if _multiprocessing wasn't built. +import_helper.import_module('_multiprocessing') + +if support.check_sanitizer(address=True, memory=True): + # gh-90791: Skip the test because it is too slow when Python is built + # with ASAN/MSAN: between 5 and 20 minutes on GitHub Actions. + raise unittest.SkipTest("test too slow on ASAN/MSAN build") + + +def load_tests(*args): + return support.load_package_tests(os.path.dirname(__file__), *args) diff --git a/Lib/test/test_concurrent_futures/executor.py b/Lib/test/test_concurrent_futures/executor.py new file mode 100644 index 00000000..1e7d4344 --- /dev/null +++ b/Lib/test/test_concurrent_futures/executor.py @@ -0,0 +1,108 @@ +import threading +import time +import weakref +from concurrent import futures +from test import support + + +def mul(x, y): + return x * y + +def capture(*args, **kwargs): + return args, kwargs + + +class MyObject(object): + def my_method(self): + pass + + +def make_dummy_object(_): + return MyObject() + + +class ExecutorTest: + # Executor.shutdown() and context manager usage is tested by + # ExecutorShutdownTest. + def test_submit(self): + future = self.executor.submit(pow, 2, 8) + self.assertEqual(256, future.result()) + + def test_submit_keyword(self): + future = self.executor.submit(mul, 2, y=8) + self.assertEqual(16, future.result()) + future = self.executor.submit(capture, 1, self=2, fn=3) + self.assertEqual(future.result(), ((1,), {'self': 2, 'fn': 3})) + with self.assertRaises(TypeError): + self.executor.submit(fn=capture, arg=1) + with self.assertRaises(TypeError): + self.executor.submit(arg=1) + + def test_map(self): + self.assertEqual( + list(self.executor.map(pow, range(10), range(10))), + list(map(pow, range(10), range(10)))) + + self.assertEqual( + list(self.executor.map(pow, range(10), range(10), chunksize=3)), + list(map(pow, range(10), range(10)))) + + def test_map_exception(self): + i = self.executor.map(divmod, [1, 1, 1, 1], [2, 3, 0, 5]) + self.assertEqual(i.__next__(), (0, 1)) + self.assertEqual(i.__next__(), (0, 1)) + self.assertRaises(ZeroDivisionError, i.__next__) + + @support.requires_resource('walltime') + def test_map_timeout(self): + results = [] + try: + for i in self.executor.map(time.sleep, + [0, 0, 6], + timeout=5): + results.append(i) + except futures.TimeoutError: + pass + else: + self.fail('expected TimeoutError') + + self.assertEqual([None, None], results) + + def test_shutdown_race_issue12456(self): + # Issue #12456: race condition at shutdown where trying to post a + # sentinel in the call queue blocks (the queue is full while processes + # have exited). + self.executor.map(str, [2] * (self.worker_count + 1)) + self.executor.shutdown() + + @support.cpython_only + def test_no_stale_references(self): + # Issue #16284: check that the executors don't unnecessarily hang onto + # references. + my_object = MyObject() + my_object_collected = threading.Event() + my_object_callback = weakref.ref( + my_object, lambda obj: my_object_collected.set()) + # Deliberately discarding the future. + self.executor.submit(my_object.my_method) + del my_object + + collected = my_object_collected.wait(timeout=support.SHORT_TIMEOUT) + self.assertTrue(collected, + "Stale reference not collected within timeout.") + + def test_max_workers_negative(self): + for number in (0, -1): + with self.assertRaisesRegex(ValueError, + "max_workers must be greater " + "than 0"): + self.executor_type(max_workers=number) + + def test_free_reference(self): + # Issue #14406: Result iterator should not keep an internal + # reference to result objects. + for obj in self.executor.map(make_dummy_object, range(10)): + wr = weakref.ref(obj) + del obj + support.gc_collect() # For PyPy or other GCs. + self.assertIsNone(wr()) diff --git a/Lib/test/test_concurrent_futures/test_as_completed.py b/Lib/test/test_concurrent_futures/test_as_completed.py new file mode 100644 index 00000000..2b3bec8c --- /dev/null +++ b/Lib/test/test_concurrent_futures/test_as_completed.py @@ -0,0 +1,115 @@ +import itertools +import time +import unittest +import weakref +from concurrent import futures +from concurrent.futures._base import ( + CANCELLED_AND_NOTIFIED, FINISHED, Future) + +from test import support + +from .util import ( + PENDING_FUTURE, RUNNING_FUTURE, + CANCELLED_AND_NOTIFIED_FUTURE, EXCEPTION_FUTURE, SUCCESSFUL_FUTURE, + create_future, create_executor_tests, setup_module) + + +def mul(x, y): + return x * y + + +class AsCompletedTests: + def test_no_timeout(self): + future1 = self.executor.submit(mul, 2, 21) + future2 = self.executor.submit(mul, 7, 6) + + completed = set(futures.as_completed( + [CANCELLED_AND_NOTIFIED_FUTURE, + EXCEPTION_FUTURE, + SUCCESSFUL_FUTURE, + future1, future2])) + self.assertEqual(set( + [CANCELLED_AND_NOTIFIED_FUTURE, + EXCEPTION_FUTURE, + SUCCESSFUL_FUTURE, + future1, future2]), + completed) + + def test_future_times_out(self): + """Test ``futures.as_completed`` timing out before + completing it's final future.""" + already_completed = {CANCELLED_AND_NOTIFIED_FUTURE, + EXCEPTION_FUTURE, + SUCCESSFUL_FUTURE} + + for timeout in (0, 0.01): + with self.subTest(timeout): + + future = self.executor.submit(time.sleep, 0.1) + completed_futures = set() + try: + for f in futures.as_completed( + already_completed | {future}, + timeout + ): + completed_futures.add(f) + except futures.TimeoutError: + pass + + # Check that ``future`` wasn't completed. + self.assertEqual(completed_futures, already_completed) + + def test_duplicate_futures(self): + # Issue 20367. Duplicate futures should not raise exceptions or give + # duplicate responses. + # Issue #31641: accept arbitrary iterables. + future1 = self.executor.submit(time.sleep, 2) + completed = [ + f for f in futures.as_completed(itertools.repeat(future1, 3)) + ] + self.assertEqual(len(completed), 1) + + def test_free_reference_yielded_future(self): + # Issue #14406: Generator should not keep references + # to finished futures. + futures_list = [Future() for _ in range(8)] + futures_list.append(create_future(state=CANCELLED_AND_NOTIFIED)) + futures_list.append(create_future(state=FINISHED, result=42)) + + with self.assertRaises(futures.TimeoutError): + for future in futures.as_completed(futures_list, timeout=0): + futures_list.remove(future) + wr = weakref.ref(future) + del future + support.gc_collect() # For PyPy or other GCs. + self.assertIsNone(wr()) + + futures_list[0].set_result("test") + for future in futures.as_completed(futures_list): + futures_list.remove(future) + wr = weakref.ref(future) + del future + support.gc_collect() # For PyPy or other GCs. + self.assertIsNone(wr()) + if futures_list: + futures_list[0].set_result("test") + + def test_correct_timeout_exception_msg(self): + futures_list = [CANCELLED_AND_NOTIFIED_FUTURE, PENDING_FUTURE, + RUNNING_FUTURE, SUCCESSFUL_FUTURE] + + with self.assertRaises(futures.TimeoutError) as cm: + list(futures.as_completed(futures_list, timeout=0)) + + self.assertEqual(str(cm.exception), '2 (of 4) futures unfinished') + + +create_executor_tests(globals(), AsCompletedTests) + + +def setUpModule(): + setup_module() + + +if __name__ == "__main__": + unittest.main() diff --git a/Lib/test/test_concurrent_futures/test_deadlock.py b/Lib/test/test_concurrent_futures/test_deadlock.py new file mode 100644 index 00000000..6b78b360 --- /dev/null +++ b/Lib/test/test_concurrent_futures/test_deadlock.py @@ -0,0 +1,253 @@ +import contextlib +import sys +import time +import unittest +from pickle import PicklingError +from concurrent import futures +from concurrent.futures.process import BrokenProcessPool + +from test import support + +from .util import ( + create_executor_tests, setup_module, + ProcessPoolForkMixin, ProcessPoolForkserverMixin, ProcessPoolSpawnMixin) + + +def _crash(delay=None): + """Induces a segfault.""" + if delay: + time.sleep(delay) + import faulthandler + faulthandler.disable() + faulthandler._sigsegv() + + +def _crash_with_data(data): + """Induces a segfault with dummy data in input.""" + _crash() + + +def _exit(): + """Induces a sys exit with exitcode 1.""" + sys.exit(1) + + +def _raise_error(Err): + """Function that raises an Exception in process.""" + raise Err() + + +def _raise_error_ignore_stderr(Err): + """Function that raises an Exception in process and ignores stderr.""" + import io + sys.stderr = io.StringIO() + raise Err() + + +def _return_instance(cls): + """Function that returns a instance of cls.""" + return cls() + + +class CrashAtPickle(object): + """Bad object that triggers a segfault at pickling time.""" + def __reduce__(self): + _crash() + + +class CrashAtUnpickle(object): + """Bad object that triggers a segfault at unpickling time.""" + def __reduce__(self): + return _crash, () + + +class ExitAtPickle(object): + """Bad object that triggers a process exit at pickling time.""" + def __reduce__(self): + _exit() + + +class ExitAtUnpickle(object): + """Bad object that triggers a process exit at unpickling time.""" + def __reduce__(self): + return _exit, () + + +class ErrorAtPickle(object): + """Bad object that triggers an error at pickling time.""" + def __reduce__(self): + from pickle import PicklingError + raise PicklingError("Error in pickle") + + +class ErrorAtUnpickle(object): + """Bad object that triggers an error at unpickling time.""" + def __reduce__(self): + from pickle import UnpicklingError + return _raise_error_ignore_stderr, (UnpicklingError, ) + + +class ExecutorDeadlockTest: + TIMEOUT = support.SHORT_TIMEOUT + + def _fail_on_deadlock(self, executor): + # If we did not recover before TIMEOUT seconds, consider that the + # executor is in a deadlock state and forcefully clean all its + # composants. + import faulthandler + from tempfile import TemporaryFile + with TemporaryFile(mode="w+") as f: + faulthandler.dump_traceback(file=f) + f.seek(0) + tb = f.read() + for p in executor._processes.values(): + p.terminate() + # This should be safe to call executor.shutdown here as all possible + # deadlocks should have been broken. + executor.shutdown(wait=True) + print(f"\nTraceback:\n {tb}", file=sys.__stderr__) + self.fail(f"Executor deadlock:\n\n{tb}") + + + def _check_crash(self, error, func, *args, ignore_stderr=False): + # test for deadlock caused by crashes in a pool + self.executor.shutdown(wait=True) + + executor = self.executor_type( + max_workers=2, mp_context=self.get_context()) + res = executor.submit(func, *args) + + if ignore_stderr: + cm = support.captured_stderr() + else: + cm = contextlib.nullcontext() + + try: + with self.assertRaises(error): + with cm: + res.result(timeout=self.TIMEOUT) + except futures.TimeoutError: + # If we did not recover before TIMEOUT seconds, + # consider that the executor is in a deadlock state + self._fail_on_deadlock(executor) + executor.shutdown(wait=True) + + def test_error_at_task_pickle(self): + # Check problem occurring while pickling a task in + # the task_handler thread + self._check_crash(PicklingError, id, ErrorAtPickle()) + + def test_exit_at_task_unpickle(self): + # Check problem occurring while unpickling a task on workers + self._check_crash(BrokenProcessPool, id, ExitAtUnpickle()) + + def test_error_at_task_unpickle(self): + # Check problem occurring while unpickling a task on workers + self._check_crash(BrokenProcessPool, id, ErrorAtUnpickle()) + + def test_crash_at_task_unpickle(self): + # Check problem occurring while unpickling a task on workers + self._check_crash(BrokenProcessPool, id, CrashAtUnpickle()) + + def test_crash_during_func_exec_on_worker(self): + # Check problem occurring during func execution on workers + self._check_crash(BrokenProcessPool, _crash) + + def test_exit_during_func_exec_on_worker(self): + # Check problem occurring during func execution on workers + self._check_crash(SystemExit, _exit) + + def test_error_during_func_exec_on_worker(self): + # Check problem occurring during func execution on workers + self._check_crash(RuntimeError, _raise_error, RuntimeError) + + def test_crash_during_result_pickle_on_worker(self): + # Check problem occurring while pickling a task result + # on workers + self._check_crash(BrokenProcessPool, _return_instance, CrashAtPickle) + + def test_exit_during_result_pickle_on_worker(self): + # Check problem occurring while pickling a task result + # on workers + self._check_crash(SystemExit, _return_instance, ExitAtPickle) + + def test_error_during_result_pickle_on_worker(self): + # Check problem occurring while pickling a task result + # on workers + self._check_crash(PicklingError, _return_instance, ErrorAtPickle) + + def test_error_during_result_unpickle_in_result_handler(self): + # Check problem occurring while unpickling a task in + # the result_handler thread + self._check_crash(BrokenProcessPool, + _return_instance, ErrorAtUnpickle, + ignore_stderr=True) + + def test_exit_during_result_unpickle_in_result_handler(self): + # Check problem occurring while unpickling a task in + # the result_handler thread + self._check_crash(BrokenProcessPool, _return_instance, ExitAtUnpickle) + + def test_shutdown_deadlock(self): + # Test that the pool calling shutdown do not cause deadlock + # if a worker fails after the shutdown call. + self.executor.shutdown(wait=True) + with self.executor_type(max_workers=2, + mp_context=self.get_context()) as executor: + self.executor = executor # Allow clean up in fail_on_deadlock + f = executor.submit(_crash, delay=.1) + executor.shutdown(wait=True) + with self.assertRaises(BrokenProcessPool): + f.result() + + def test_shutdown_deadlock_pickle(self): + # Test that the pool calling shutdown with wait=False does not cause + # a deadlock if a task fails at pickle after the shutdown call. + # Reported in bpo-39104. + self.executor.shutdown(wait=True) + with self.executor_type(max_workers=2, + mp_context=self.get_context()) as executor: + self.executor = executor # Allow clean up in fail_on_deadlock + + # Start the executor and get the executor_manager_thread to collect + # the threads and avoid dangling thread that should be cleaned up + # asynchronously. + executor.submit(id, 42).result() + executor_manager = executor._executor_manager_thread + + # Submit a task that fails at pickle and shutdown the executor + # without waiting + f = executor.submit(id, ErrorAtPickle()) + executor.shutdown(wait=False) + with self.assertRaises(PicklingError): + f.result() + + # Make sure the executor is eventually shutdown and do not leave + # dangling threads + executor_manager.join() + + def test_crash_big_data(self): + # Test that there is a clean exception instad of a deadlock when a + # child process crashes while some data is being written into the + # queue. + # https://github.com/python/cpython/issues/94777 + self.executor.shutdown(wait=True) + data = "a" * support.PIPE_MAX_SIZE + with self.executor_type(max_workers=2, + mp_context=self.get_context()) as executor: + self.executor = executor # Allow clean up in fail_on_deadlock + with self.assertRaises(BrokenProcessPool): + list(executor.map(_crash_with_data, [data] * 10)) + + +create_executor_tests(globals(), ExecutorDeadlockTest, + executor_mixins=(ProcessPoolForkMixin, + ProcessPoolForkserverMixin, + ProcessPoolSpawnMixin)) + +def setUpModule(): + setup_module() + + +if __name__ == "__main__": + unittest.main() diff --git a/Lib/test/test_concurrent_futures/test_future.py b/Lib/test/test_concurrent_futures/test_future.py new file mode 100644 index 00000000..4066ea1e --- /dev/null +++ b/Lib/test/test_concurrent_futures/test_future.py @@ -0,0 +1,291 @@ +import threading +import time +import unittest +from concurrent import futures +from concurrent.futures._base import ( + PENDING, RUNNING, CANCELLED, CANCELLED_AND_NOTIFIED, FINISHED, Future) + +from test import support + +from .util import ( + PENDING_FUTURE, RUNNING_FUTURE, CANCELLED_FUTURE, + CANCELLED_AND_NOTIFIED_FUTURE, EXCEPTION_FUTURE, SUCCESSFUL_FUTURE, + BaseTestCase, create_future, setup_module) + + +class FutureTests(BaseTestCase): + def test_done_callback_with_result(self): + callback_result = None + def fn(callback_future): + nonlocal callback_result + callback_result = callback_future.result() + + f = Future() + f.add_done_callback(fn) + f.set_result(5) + self.assertEqual(5, callback_result) + + def test_done_callback_with_exception(self): + callback_exception = None + def fn(callback_future): + nonlocal callback_exception + callback_exception = callback_future.exception() + + f = Future() + f.add_done_callback(fn) + f.set_exception(Exception('test')) + self.assertEqual(('test',), callback_exception.args) + + def test_done_callback_with_cancel(self): + was_cancelled = None + def fn(callback_future): + nonlocal was_cancelled + was_cancelled = callback_future.cancelled() + + f = Future() + f.add_done_callback(fn) + self.assertTrue(f.cancel()) + self.assertTrue(was_cancelled) + + def test_done_callback_raises(self): + with support.captured_stderr() as stderr: + raising_was_called = False + fn_was_called = False + + def raising_fn(callback_future): + nonlocal raising_was_called + raising_was_called = True + raise Exception('doh!') + + def fn(callback_future): + nonlocal fn_was_called + fn_was_called = True + + f = Future() + f.add_done_callback(raising_fn) + f.add_done_callback(fn) + f.set_result(5) + self.assertTrue(raising_was_called) + self.assertTrue(fn_was_called) + self.assertIn('Exception: doh!', stderr.getvalue()) + + def test_done_callback_already_successful(self): + callback_result = None + def fn(callback_future): + nonlocal callback_result + callback_result = callback_future.result() + + f = Future() + f.set_result(5) + f.add_done_callback(fn) + self.assertEqual(5, callback_result) + + def test_done_callback_already_failed(self): + callback_exception = None + def fn(callback_future): + nonlocal callback_exception + callback_exception = callback_future.exception() + + f = Future() + f.set_exception(Exception('test')) + f.add_done_callback(fn) + self.assertEqual(('test',), callback_exception.args) + + def test_done_callback_already_cancelled(self): + was_cancelled = None + def fn(callback_future): + nonlocal was_cancelled + was_cancelled = callback_future.cancelled() + + f = Future() + self.assertTrue(f.cancel()) + f.add_done_callback(fn) + self.assertTrue(was_cancelled) + + def test_done_callback_raises_already_succeeded(self): + with support.captured_stderr() as stderr: + def raising_fn(callback_future): + raise Exception('doh!') + + f = Future() + + # Set the result first to simulate a future that runs instantly, + # effectively allowing the callback to be run immediately. + f.set_result(5) + f.add_done_callback(raising_fn) + + self.assertIn('exception calling callback for', stderr.getvalue()) + self.assertIn('doh!', stderr.getvalue()) + + + def test_repr(self): + self.assertRegex(repr(PENDING_FUTURE), + '<Future at 0x[0-9a-f]+ state=pending>') + self.assertRegex(repr(RUNNING_FUTURE), + '<Future at 0x[0-9a-f]+ state=running>') + self.assertRegex(repr(CANCELLED_FUTURE), + '<Future at 0x[0-9a-f]+ state=cancelled>') + self.assertRegex(repr(CANCELLED_AND_NOTIFIED_FUTURE), + '<Future at 0x[0-9a-f]+ state=cancelled>') + self.assertRegex( + repr(EXCEPTION_FUTURE), + '<Future at 0x[0-9a-f]+ state=finished raised OSError>') + self.assertRegex( + repr(SUCCESSFUL_FUTURE), + '<Future at 0x[0-9a-f]+ state=finished returned int>') + + def test_cancel(self): + f1 = create_future(state=PENDING) + f2 = create_future(state=RUNNING) + f3 = create_future(state=CANCELLED) + f4 = create_future(state=CANCELLED_AND_NOTIFIED) + f5 = create_future(state=FINISHED, exception=OSError()) + f6 = create_future(state=FINISHED, result=5) + + self.assertTrue(f1.cancel()) + self.assertEqual(f1._state, CANCELLED) + + self.assertFalse(f2.cancel()) + self.assertEqual(f2._state, RUNNING) + + self.assertTrue(f3.cancel()) + self.assertEqual(f3._state, CANCELLED) + + self.assertTrue(f4.cancel()) + self.assertEqual(f4._state, CANCELLED_AND_NOTIFIED) + + self.assertFalse(f5.cancel()) + self.assertEqual(f5._state, FINISHED) + + self.assertFalse(f6.cancel()) + self.assertEqual(f6._state, FINISHED) + + def test_cancelled(self): + self.assertFalse(PENDING_FUTURE.cancelled()) + self.assertFalse(RUNNING_FUTURE.cancelled()) + self.assertTrue(CANCELLED_FUTURE.cancelled()) + self.assertTrue(CANCELLED_AND_NOTIFIED_FUTURE.cancelled()) + self.assertFalse(EXCEPTION_FUTURE.cancelled()) + self.assertFalse(SUCCESSFUL_FUTURE.cancelled()) + + def test_done(self): + self.assertFalse(PENDING_FUTURE.done()) + self.assertFalse(RUNNING_FUTURE.done()) + self.assertTrue(CANCELLED_FUTURE.done()) + self.assertTrue(CANCELLED_AND_NOTIFIED_FUTURE.done()) + self.assertTrue(EXCEPTION_FUTURE.done()) + self.assertTrue(SUCCESSFUL_FUTURE.done()) + + def test_running(self): + self.assertFalse(PENDING_FUTURE.running()) + self.assertTrue(RUNNING_FUTURE.running()) + self.assertFalse(CANCELLED_FUTURE.running()) + self.assertFalse(CANCELLED_AND_NOTIFIED_FUTURE.running()) + self.assertFalse(EXCEPTION_FUTURE.running()) + self.assertFalse(SUCCESSFUL_FUTURE.running()) + + def test_result_with_timeout(self): + self.assertRaises(futures.TimeoutError, + PENDING_FUTURE.result, timeout=0) + self.assertRaises(futures.TimeoutError, + RUNNING_FUTURE.result, timeout=0) + self.assertRaises(futures.CancelledError, + CANCELLED_FUTURE.result, timeout=0) + self.assertRaises(futures.CancelledError, + CANCELLED_AND_NOTIFIED_FUTURE.result, timeout=0) + self.assertRaises(OSError, EXCEPTION_FUTURE.result, timeout=0) + self.assertEqual(SUCCESSFUL_FUTURE.result(timeout=0), 42) + + def test_result_with_success(self): + # TODO(brian@sweetapp.com): This test is timing dependent. + def notification(): + # Wait until the main thread is waiting for the result. + time.sleep(1) + f1.set_result(42) + + f1 = create_future(state=PENDING) + t = threading.Thread(target=notification) + t.start() + + self.assertEqual(f1.result(timeout=5), 42) + t.join() + + def test_result_with_cancel(self): + # TODO(brian@sweetapp.com): This test is timing dependent. + def notification(): + # Wait until the main thread is waiting for the result. + time.sleep(1) + f1.cancel() + + f1 = create_future(state=PENDING) + t = threading.Thread(target=notification) + t.start() + + self.assertRaises(futures.CancelledError, + f1.result, timeout=support.SHORT_TIMEOUT) + t.join() + + def test_exception_with_timeout(self): + self.assertRaises(futures.TimeoutError, + PENDING_FUTURE.exception, timeout=0) + self.assertRaises(futures.TimeoutError, + RUNNING_FUTURE.exception, timeout=0) + self.assertRaises(futures.CancelledError, + CANCELLED_FUTURE.exception, timeout=0) + self.assertRaises(futures.CancelledError, + CANCELLED_AND_NOTIFIED_FUTURE.exception, timeout=0) + self.assertTrue(isinstance(EXCEPTION_FUTURE.exception(timeout=0), + OSError)) + self.assertEqual(SUCCESSFUL_FUTURE.exception(timeout=0), None) + + def test_exception_with_success(self): + def notification(): + # Wait until the main thread is waiting for the exception. + time.sleep(1) + with f1._condition: + f1._state = FINISHED + f1._exception = OSError() + f1._condition.notify_all() + + f1 = create_future(state=PENDING) + t = threading.Thread(target=notification) + t.start() + + self.assertTrue(isinstance(f1.exception(timeout=support.SHORT_TIMEOUT), OSError)) + t.join() + + def test_multiple_set_result(self): + f = create_future(state=PENDING) + f.set_result(1) + + with self.assertRaisesRegex( + futures.InvalidStateError, + 'FINISHED: <Future at 0x[0-9a-f]+ ' + 'state=finished returned int>' + ): + f.set_result(2) + + self.assertTrue(f.done()) + self.assertEqual(f.result(), 1) + + def test_multiple_set_exception(self): + f = create_future(state=PENDING) + e = ValueError() + f.set_exception(e) + + with self.assertRaisesRegex( + futures.InvalidStateError, + 'FINISHED: <Future at 0x[0-9a-f]+ ' + 'state=finished raised ValueError>' + ): + f.set_exception(Exception()) + + self.assertEqual(f.exception(), e) + + +def setUpModule(): + setup_module() + + +if __name__ == "__main__": + unittest.main() diff --git a/Lib/test/test_concurrent_futures/test_init.py b/Lib/test/test_concurrent_futures/test_init.py new file mode 100644 index 00000000..ce01e0ff --- /dev/null +++ b/Lib/test/test_concurrent_futures/test_init.py @@ -0,0 +1,117 @@ +import contextlib +import logging +import queue +import time +import unittest +from concurrent.futures._base import BrokenExecutor +from logging.handlers import QueueHandler + +from test import support + +from .util import ExecutorMixin, create_executor_tests, setup_module + + +INITIALIZER_STATUS = 'uninitialized' + +def init(x): + global INITIALIZER_STATUS + INITIALIZER_STATUS = x + +def get_init_status(): + return INITIALIZER_STATUS + +def init_fail(log_queue=None): + if log_queue is not None: + logger = logging.getLogger('concurrent.futures') + logger.addHandler(QueueHandler(log_queue)) + logger.setLevel('CRITICAL') + logger.propagate = False + time.sleep(0.1) # let some futures be scheduled + raise ValueError('error in initializer') + + +class InitializerMixin(ExecutorMixin): + worker_count = 2 + + def setUp(self): + global INITIALIZER_STATUS + INITIALIZER_STATUS = 'uninitialized' + self.executor_kwargs = dict(initializer=init, + initargs=('initialized',)) + super().setUp() + + def test_initializer(self): + futures = [self.executor.submit(get_init_status) + for _ in range(self.worker_count)] + + for f in futures: + self.assertEqual(f.result(), 'initialized') + + +class FailingInitializerMixin(ExecutorMixin): + worker_count = 2 + + def setUp(self): + if hasattr(self, "ctx"): + # Pass a queue to redirect the child's logging output + self.mp_context = self.get_context() + self.log_queue = self.mp_context.Queue() + self.executor_kwargs = dict(initializer=init_fail, + initargs=(self.log_queue,)) + else: + # In a thread pool, the child shares our logging setup + # (see _assert_logged()) + self.mp_context = None + self.log_queue = None + self.executor_kwargs = dict(initializer=init_fail) + super().setUp() + + def test_initializer(self): + with self._assert_logged('ValueError: error in initializer'): + try: + future = self.executor.submit(get_init_status) + except BrokenExecutor: + # Perhaps the executor is already broken + pass + else: + with self.assertRaises(BrokenExecutor): + future.result() + + # At some point, the executor should break + for _ in support.sleeping_retry(support.SHORT_TIMEOUT, + "executor not broken"): + if self.executor._broken: + break + + # ... and from this point submit() is guaranteed to fail + with self.assertRaises(BrokenExecutor): + self.executor.submit(get_init_status) + + @contextlib.contextmanager + def _assert_logged(self, msg): + if self.log_queue is not None: + yield + output = [] + try: + while True: + output.append(self.log_queue.get_nowait().getMessage()) + except queue.Empty: + pass + else: + with self.assertLogs('concurrent.futures', 'CRITICAL') as cm: + yield + output = cm.output + self.assertTrue(any(msg in line for line in output), + output) + + +create_executor_tests(globals(), InitializerMixin) +create_executor_tests(globals(), FailingInitializerMixin) + + +def setUpModule(): + setup_module() + + +if __name__ == "__main__": + unittest.main() diff --git a/Lib/test/test_concurrent_futures/test_process_pool.py b/Lib/test/test_concurrent_futures/test_process_pool.py new file mode 100644 index 00000000..7763a494 --- /dev/null +++ b/Lib/test/test_concurrent_futures/test_process_pool.py @@ -0,0 +1,202 @@ +import os +import sys +import time +import unittest +from concurrent import futures +from concurrent.futures.process import BrokenProcessPool + +from test import support +from test.support import hashlib_helper + +from .executor import ExecutorTest, mul +from .util import ( + ProcessPoolForkMixin, ProcessPoolForkserverMixin, ProcessPoolSpawnMixin, + create_executor_tests, setup_module) + + +class EventfulGCObj(): + def __init__(self, mgr): + self.event = mgr.Event() + + def __del__(self): + self.event.set() + + +class ProcessPoolExecutorTest(ExecutorTest): + + @unittest.skipUnless(sys.platform=='win32', 'Windows-only process limit') + def test_max_workers_too_large(self): + with self.assertRaisesRegex(ValueError, + "max_workers must be <= 61"): + futures.ProcessPoolExecutor(max_workers=62) + + def test_killed_child(self): + # When a child process is abruptly terminated, the whole pool gets + # "broken". + futures = [self.executor.submit(time.sleep, 3)] + # Get one of the processes, and terminate (kill) it + p = next(iter(self.executor._processes.values())) + p.terminate() + for fut in futures: + self.assertRaises(BrokenProcessPool, fut.result) + # Submitting other jobs fails as well. + self.assertRaises(BrokenProcessPool, self.executor.submit, pow, 2, 8) + + def test_map_chunksize(self): + def bad_map(): + list(self.executor.map(pow, range(40), range(40), chunksize=-1)) + + ref = list(map(pow, range(40), range(40))) + self.assertEqual( + list(self.executor.map(pow, range(40), range(40), chunksize=6)), + ref) + self.assertEqual( + list(self.executor.map(pow, range(40), range(40), chunksize=50)), + ref) + self.assertEqual( + list(self.executor.map(pow, range(40), range(40), chunksize=40)), + ref) + self.assertRaises(ValueError, bad_map) + + @classmethod + def _test_traceback(cls): + raise RuntimeError(123) # some comment + + def test_traceback(self): + # We want ensure that the traceback from the child process is + # contained in the traceback raised in the main process. + future = self.executor.submit(self._test_traceback) + with self.assertRaises(Exception) as cm: + future.result() + + exc = cm.exception + self.assertIs(type(exc), RuntimeError) + self.assertEqual(exc.args, (123,)) + cause = exc.__cause__ + self.assertIs(type(cause), futures.process._RemoteTraceback) + self.assertIn('raise RuntimeError(123) # some comment', cause.tb) + + with support.captured_stderr() as f1: + try: + raise exc + except RuntimeError: + sys.excepthook(*sys.exc_info()) + self.assertIn('raise RuntimeError(123) # some comment', + f1.getvalue()) + + @hashlib_helper.requires_hashdigest('md5') + def test_ressources_gced_in_workers(self): + # Ensure that argument for a job are correctly gc-ed after the job + # is finished + mgr = self.get_context().Manager() + obj = EventfulGCObj(mgr) + future = self.executor.submit(id, obj) + future.result() + + self.assertTrue(obj.event.wait(timeout=1)) + + # explicitly destroy the object to ensure that EventfulGCObj.__del__() + # is called while manager is still running. + obj = None + support.gc_collect() + + mgr.shutdown() + mgr.join() + + def test_saturation(self): + executor = self.executor + mp_context = self.get_context() + sem = mp_context.Semaphore(0) + job_count = 15 * executor._max_workers + for _ in range(job_count): + executor.submit(sem.acquire) + self.assertEqual(len(executor._processes), executor._max_workers) + for _ in range(job_count): + sem.release() + + def test_idle_process_reuse_one(self): + executor = self.executor + assert executor._max_workers >= 4 + if self.get_context().get_start_method(allow_none=False) == "fork": + raise unittest.SkipTest("Incompatible with the fork start method.") + executor.submit(mul, 21, 2).result() + executor.submit(mul, 6, 7).result() + executor.submit(mul, 3, 14).result() + self.assertEqual(len(executor._processes), 1) + + def test_idle_process_reuse_multiple(self): + executor = self.executor + assert executor._max_workers <= 5 + if self.get_context().get_start_method(allow_none=False) == "fork": + raise unittest.SkipTest("Incompatible with the fork start method.") + executor.submit(mul, 12, 7).result() + executor.submit(mul, 33, 25) + executor.submit(mul, 25, 26).result() + executor.submit(mul, 18, 29) + executor.submit(mul, 1, 2).result() + executor.submit(mul, 0, 9) + self.assertLessEqual(len(executor._processes), 3) + executor.shutdown() + + def test_max_tasks_per_child(self): + context = self.get_context() + if context.get_start_method(allow_none=False) == "fork": + with self.assertRaises(ValueError): + self.executor_type(1, mp_context=context, max_tasks_per_child=3) + return + # not using self.executor as we need to control construction. + # arguably this could go in another class w/o that mixin. + executor = self.executor_type( + 1, mp_context=context, max_tasks_per_child=3) + f1 = executor.submit(os.getpid) + original_pid = f1.result() + # The worker pid remains the same as the worker could be reused + f2 = executor.submit(os.getpid) + self.assertEqual(f2.result(), original_pid) + self.assertEqual(len(executor._processes), 1) + f3 = executor.submit(os.getpid) + self.assertEqual(f3.result(), original_pid) + + # A new worker is spawned, with a statistically different pid, + # while the previous was reaped. + f4 = executor.submit(os.getpid) + new_pid = f4.result() + self.assertNotEqual(original_pid, new_pid) + self.assertEqual(len(executor._processes), 1) + + executor.shutdown() + + def test_max_tasks_per_child_defaults_to_spawn_context(self): + # not using self.executor as we need to control construction. + # arguably this could go in another class w/o that mixin. + executor = self.executor_type(1, max_tasks_per_child=3) + self.assertEqual(executor._mp_context.get_start_method(), "spawn") + + def test_max_tasks_early_shutdown(self): + context = self.get_context() + if context.get_start_method(allow_none=False) == "fork": + raise unittest.SkipTest("Incompatible with the fork start method.") + # not using self.executor as we need to control construction. + # arguably this could go in another class w/o that mixin. + executor = self.executor_type( + 3, mp_context=context, max_tasks_per_child=1) + futures = [] + for i in range(6): + futures.append(executor.submit(mul, i, i)) + executor.shutdown() + for i, future in enumerate(futures): + self.assertEqual(future.result(), mul(i, i)) + + +create_executor_tests(globals(), ProcessPoolExecutorTest, + executor_mixins=(ProcessPoolForkMixin, + ProcessPoolForkserverMixin, + ProcessPoolSpawnMixin)) + + +def setUpModule(): + setup_module() + + +if __name__ == "__main__": + unittest.main() diff --git a/Lib/test/test_concurrent_futures/test_shutdown.py b/Lib/test/test_concurrent_futures/test_shutdown.py new file mode 100644 index 00000000..45dab7a7 --- /dev/null +++ b/Lib/test/test_concurrent_futures/test_shutdown.py @@ -0,0 +1,343 @@ +import signal +import sys +import threading +import time +import unittest +from concurrent import futures + +from test import support +from test.support.script_helper import assert_python_ok + +from .util import ( + BaseTestCase, ThreadPoolMixin, ProcessPoolForkMixin, + ProcessPoolForkserverMixin, ProcessPoolSpawnMixin, + create_executor_tests, setup_module) + + +def sleep_and_print(t, msg): + time.sleep(t) + print(msg) + sys.stdout.flush() + + +class ExecutorShutdownTest: + def test_run_after_shutdown(self): + self.executor.shutdown() + self.assertRaises(RuntimeError, + self.executor.submit, + pow, 2, 5) + + def test_interpreter_shutdown(self): + # Test the atexit hook for shutdown of worker threads and processes + rc, out, err = assert_python_ok('-c', """if 1: + from concurrent.futures import {executor_type} + from time import sleep + from test.test_concurrent_futures.test_shutdown import sleep_and_print + if __name__ == "__main__": + context = '{context}' + if context == "": + t = {executor_type}(5) + else: + from multiprocessing import get_context + context = get_context(context) + t = {executor_type}(5, mp_context=context) + t.submit(sleep_and_print, 1.0, "apple") + """.format(executor_type=self.executor_type.__name__, + context=getattr(self, "ctx", ""))) + # Errors in atexit hooks don't change the process exit code, check + # stderr manually. + self.assertFalse(err) + self.assertEqual(out.strip(), b"apple") + + def test_submit_after_interpreter_shutdown(self): + # Test the atexit hook for shutdown of worker threads and processes + rc, out, err = assert_python_ok('-c', """if 1: + import atexit + @atexit.register + def run_last(): + try: + t.submit(id, None) + except RuntimeError: + print("runtime-error") + raise + from concurrent.futures import {executor_type} + if __name__ == "__main__": + context = '{context}' + if not context: + t = {executor_type}(5) + else: + from multiprocessing import get_context + context = get_context(context) + t = {executor_type}(5, mp_context=context) + t.submit(id, 42).result() + """.format(executor_type=self.executor_type.__name__, + context=getattr(self, "ctx", ""))) + # Errors in atexit hooks don't change the process exit code, check + # stderr manually. + self.assertIn("RuntimeError: cannot schedule new futures", err.decode()) + self.assertEqual(out.strip(), b"runtime-error") + + def test_hang_issue12364(self): + fs = [self.executor.submit(time.sleep, 0.1) for _ in range(50)] + self.executor.shutdown() + for f in fs: + f.result() + + def test_cancel_futures(self): + assert self.worker_count <= 5, "test needs few workers" + fs = [self.executor.submit(time.sleep, .1) for _ in range(50)] + self.executor.shutdown(cancel_futures=True) + # We can't guarantee the exact number of cancellations, but we can + # guarantee that *some* were cancelled. With few workers, many of + # the submitted futures should have been cancelled. + cancelled = [fut for fut in fs if fut.cancelled()] + self.assertGreater(len(cancelled), 20) + + # Ensure the other futures were able to finish. + # Use "not fut.cancelled()" instead of "fut.done()" to include futures + # that may have been left in a pending state. + others = [fut for fut in fs if not fut.cancelled()] + for fut in others: + self.assertTrue(fut.done(), msg=f"{fut._state=}") + self.assertIsNone(fut.exception()) + + # Similar to the number of cancelled futures, we can't guarantee the + # exact number that completed. But, we can guarantee that at least + # one finished. + self.assertGreater(len(others), 0) + + def test_hang_gh83386(self): + """shutdown(wait=False) doesn't hang at exit with running futures. + + See https://github.com/python/cpython/issues/83386. + """ + if self.executor_type == futures.ProcessPoolExecutor: + raise unittest.SkipTest( + "Hangs, see https://github.com/python/cpython/issues/83386") + + rc, out, err = assert_python_ok('-c', """if True: + from concurrent.futures import {executor_type} + from test.test_concurrent_futures.test_shutdown import sleep_and_print + if __name__ == "__main__": + if {context!r}: multiprocessing.set_start_method({context!r}) + t = {executor_type}(max_workers=3) + t.submit(sleep_and_print, 1.0, "apple") + t.shutdown(wait=False) + """.format(executor_type=self.executor_type.__name__, + context=getattr(self, 'ctx', None))) + self.assertFalse(err) + self.assertEqual(out.strip(), b"apple") + + def test_hang_gh94440(self): + """shutdown(wait=True) doesn't hang when a future was submitted and + quickly canceled right before shutdown. + + See https://github.com/python/cpython/issues/94440. + """ + if not hasattr(signal, 'alarm'): + raise unittest.SkipTest( + "Tested platform does not support the alarm signal") + + def timeout(_signum, _frame): + raise RuntimeError("timed out waiting for shutdown") + + kwargs = {} + if getattr(self, 'ctx', None): + kwargs['mp_context'] = self.get_context() + executor = self.executor_type(max_workers=1, **kwargs) + executor.submit(int).result() + old_handler = signal.signal(signal.SIGALRM, timeout) + try: + signal.alarm(5) + executor.submit(int).cancel() + executor.shutdown(wait=True) + finally: + signal.alarm(0) + signal.signal(signal.SIGALRM, old_handler) + + +class ThreadPoolShutdownTest(ThreadPoolMixin, ExecutorShutdownTest, BaseTestCase): + def test_threads_terminate(self): + def acquire_lock(lock): + lock.acquire() + + sem = threading.Semaphore(0) + for i in range(3): + self.executor.submit(acquire_lock, sem) + self.assertEqual(len(self.executor._threads), 3) + for i in range(3): + sem.release() + self.executor.shutdown() + for t in self.executor._threads: + t.join() + + def test_context_manager_shutdown(self): + with futures.ThreadPoolExecutor(max_workers=5) as e: + executor = e + self.assertEqual(list(e.map(abs, range(-5, 5))), + [5, 4, 3, 2, 1, 0, 1, 2, 3, 4]) + + for t in executor._threads: + t.join() + + def test_del_shutdown(self): + executor = futures.ThreadPoolExecutor(max_workers=5) + res = executor.map(abs, range(-5, 5)) + threads = executor._threads + del executor + + for t in threads: + t.join() + + # Make sure the results were all computed before the + # executor got shutdown. + assert all([r == abs(v) for r, v in zip(res, range(-5, 5))]) + + def test_shutdown_no_wait(self): + # Ensure that the executor cleans up the threads when calling + # shutdown with wait=False + executor = futures.ThreadPoolExecutor(max_workers=5) + res = executor.map(abs, range(-5, 5)) + threads = executor._threads + executor.shutdown(wait=False) + for t in threads: + t.join() + + # Make sure the results were all computed before the + # executor got shutdown. + assert all([r == abs(v) for r, v in zip(res, range(-5, 5))]) + + + def test_thread_names_assigned(self): + executor = futures.ThreadPoolExecutor( + max_workers=5, thread_name_prefix='SpecialPool') + executor.map(abs, range(-5, 5)) + threads = executor._threads + del executor + support.gc_collect() # For PyPy or other GCs. + + for t in threads: + self.assertRegex(t.name, r'^SpecialPool_[0-4]$') + t.join() + + def test_thread_names_default(self): + executor = futures.ThreadPoolExecutor(max_workers=5) + executor.map(abs, range(-5, 5)) + threads = executor._threads + del executor + support.gc_collect() # For PyPy or other GCs. + + for t in threads: + # Ensure that our default name is reasonably sane and unique when + # no thread_name_prefix was supplied. + self.assertRegex(t.name, r'ThreadPoolExecutor-\d+_[0-4]$') + t.join() + + def test_cancel_futures_wait_false(self): + # Can only be reliably tested for TPE, since PPE often hangs with + # `wait=False` (even without *cancel_futures*). + rc, out, err = assert_python_ok('-c', """if True: + from concurrent.futures import ThreadPoolExecutor + from test.test_concurrent_futures.test_shutdown import sleep_and_print + if __name__ == "__main__": + t = ThreadPoolExecutor() + t.submit(sleep_and_print, .1, "apple") + t.shutdown(wait=False, cancel_futures=True) + """) + # Errors in atexit hooks don't change the process exit code, check + # stderr manually. + self.assertFalse(err) + self.assertEqual(out.strip(), b"apple") + + +class ProcessPoolShutdownTest(ExecutorShutdownTest): + def test_processes_terminate(self): + def acquire_lock(lock): + lock.acquire() + + mp_context = self.get_context() + if mp_context.get_start_method(allow_none=False) == "fork": + # fork pre-spawns, not on demand. + expected_num_processes = self.worker_count + else: + expected_num_processes = 3 + + sem = mp_context.Semaphore(0) + for _ in range(3): + self.executor.submit(acquire_lock, sem) + self.assertEqual(len(self.executor._processes), expected_num_processes) + for _ in range(3): + sem.release() + processes = self.executor._processes + self.executor.shutdown() + + for p in processes.values(): + p.join() + + def test_context_manager_shutdown(self): + with futures.ProcessPoolExecutor( + max_workers=5, mp_context=self.get_context()) as e: + processes = e._processes + self.assertEqual(list(e.map(abs, range(-5, 5))), + [5, 4, 3, 2, 1, 0, 1, 2, 3, 4]) + + for p in processes.values(): + p.join() + + def test_del_shutdown(self): + executor = futures.ProcessPoolExecutor( + max_workers=5, mp_context=self.get_context()) + res = executor.map(abs, range(-5, 5)) + executor_manager_thread = executor._executor_manager_thread + processes = executor._processes + call_queue = executor._call_queue + executor_manager_thread = executor._executor_manager_thread + del executor + support.gc_collect() # For PyPy or other GCs. + + # Make sure that all the executor resources were properly cleaned by + # the shutdown process + executor_manager_thread.join() + for p in processes.values(): + p.join() + call_queue.join_thread() + + # Make sure the results were all computed before the + # executor got shutdown. + assert all([r == abs(v) for r, v in zip(res, range(-5, 5))]) + + def test_shutdown_no_wait(self): + # Ensure that the executor cleans up the processes when calling + # shutdown with wait=False + executor = futures.ProcessPoolExecutor( + max_workers=5, mp_context=self.get_context()) + res = executor.map(abs, range(-5, 5)) + processes = executor._processes + call_queue = executor._call_queue + executor_manager_thread = executor._executor_manager_thread + executor.shutdown(wait=False) + + # Make sure that all the executor resources were properly cleaned by + # the shutdown process + executor_manager_thread.join() + for p in processes.values(): + p.join() + call_queue.join_thread() + + # Make sure the results were all computed before the executor got + # shutdown. + assert all([r == abs(v) for r, v in zip(res, range(-5, 5))]) + + +create_executor_tests(globals(), ProcessPoolShutdownTest, + executor_mixins=(ProcessPoolForkMixin, + ProcessPoolForkserverMixin, + ProcessPoolSpawnMixin)) + + +def setUpModule(): + setup_module() + + +if __name__ == "__main__": + unittest.main() diff --git a/Lib/test/test_concurrent_futures/test_thread_pool.py b/Lib/test/test_concurrent_futures/test_thread_pool.py new file mode 100644 index 00000000..812f989d --- /dev/null +++ b/Lib/test/test_concurrent_futures/test_thread_pool.py @@ -0,0 +1,100 @@ +import contextlib +import multiprocessing as mp +import multiprocessing.process +import multiprocessing.util +import os +import threading +import unittest +from concurrent import futures +from test import support + +from .executor import ExecutorTest, mul +from .util import BaseTestCase, ThreadPoolMixin, setup_module + + +class ThreadPoolExecutorTest(ThreadPoolMixin, ExecutorTest, BaseTestCase): + def test_map_submits_without_iteration(self): + """Tests verifying issue 11777.""" + finished = [] + def record_finished(n): + finished.append(n) + + self.executor.map(record_finished, range(10)) + self.executor.shutdown(wait=True) + self.assertCountEqual(finished, range(10)) + + def test_default_workers(self): + executor = self.executor_type() + expected = min(32, (os.cpu_count() or 1) + 4) + self.assertEqual(executor._max_workers, expected) + + def test_saturation(self): + executor = self.executor_type(4) + def acquire_lock(lock): + lock.acquire() + + sem = threading.Semaphore(0) + for i in range(15 * executor._max_workers): + executor.submit(acquire_lock, sem) + self.assertEqual(len(executor._threads), executor._max_workers) + for i in range(15 * executor._max_workers): + sem.release() + executor.shutdown(wait=True) + + def test_idle_thread_reuse(self): + executor = self.executor_type() + executor.submit(mul, 21, 2).result() + executor.submit(mul, 6, 7).result() + executor.submit(mul, 3, 14).result() + self.assertEqual(len(executor._threads), 1) + executor.shutdown(wait=True) + + @unittest.skipUnless(hasattr(os, 'register_at_fork'), 'need os.register_at_fork') + @support.requires_resource('cpu') + def test_hang_global_shutdown_lock(self): + # bpo-45021: _global_shutdown_lock should be reinitialized in the child + # process, otherwise it will never exit + def submit(pool): + pool.submit(submit, pool) + + with futures.ThreadPoolExecutor(1) as pool: + pool.submit(submit, pool) + + for _ in range(50): + with futures.ProcessPoolExecutor(1, mp_context=mp.get_context('fork')) as workers: + workers.submit(tuple) + + def test_executor_map_current_future_cancel(self): + stop_event = threading.Event() + log = [] + + def log_n_wait(ident): + log.append(f"{ident=} started") + try: + stop_event.wait() + finally: + log.append(f"{ident=} stopped") + + with self.executor_type(max_workers=1) as pool: + # submit work to saturate the pool + fut = pool.submit(log_n_wait, ident="first") + try: + with contextlib.closing( + pool.map(log_n_wait, ["second", "third"], timeout=0) + ) as gen: + with self.assertRaises(TimeoutError): + next(gen) + finally: + stop_event.set() + fut.result() + # ident='second' is cancelled as a result of raising a TimeoutError + # ident='third' is cancelled because it remained in the collection of futures + self.assertListEqual(log, ["ident='first' started", "ident='first' stopped"]) + + +def setUpModule(): + setup_module() + + +if __name__ == "__main__": + unittest.main() diff --git a/Lib/test/test_concurrent_futures/test_wait.py b/Lib/test/test_concurrent_futures/test_wait.py new file mode 100644 index 00000000..3f64ca17 --- /dev/null +++ b/Lib/test/test_concurrent_futures/test_wait.py @@ -0,0 +1,164 @@ +import sys +import threading +import time +import unittest +from concurrent import futures +from test import support + +from .util import ( + CANCELLED_FUTURE, CANCELLED_AND_NOTIFIED_FUTURE, EXCEPTION_FUTURE, + SUCCESSFUL_FUTURE, + create_executor_tests, setup_module, + BaseTestCase, ThreadPoolMixin, + ProcessPoolForkMixin, ProcessPoolForkserverMixin, ProcessPoolSpawnMixin) + + +def mul(x, y): + return x * y + +def sleep_and_raise(t): + time.sleep(t) + raise Exception('this is an exception') + + +class WaitTests: + def test_20369(self): + # See https://bugs.python.org/issue20369 + future = self.executor.submit(time.sleep, 1.5) + done, not_done = futures.wait([future, future], + return_when=futures.ALL_COMPLETED) + self.assertEqual({future}, done) + self.assertEqual(set(), not_done) + + + def test_first_completed(self): + future1 = self.executor.submit(mul, 21, 2) + future2 = self.executor.submit(time.sleep, 1.5) + + done, not_done = futures.wait( + [CANCELLED_FUTURE, future1, future2], + return_when=futures.FIRST_COMPLETED) + + self.assertEqual(set([future1]), done) + self.assertEqual(set([CANCELLED_FUTURE, future2]), not_done) + + def test_first_completed_some_already_completed(self): + future1 = self.executor.submit(time.sleep, 1.5) + + finished, pending = futures.wait( + [CANCELLED_AND_NOTIFIED_FUTURE, SUCCESSFUL_FUTURE, future1], + return_when=futures.FIRST_COMPLETED) + + self.assertEqual( + set([CANCELLED_AND_NOTIFIED_FUTURE, SUCCESSFUL_FUTURE]), + finished) + self.assertEqual(set([future1]), pending) + + @support.requires_resource('walltime') + def test_first_exception(self): + future1 = self.executor.submit(mul, 2, 21) + future2 = self.executor.submit(sleep_and_raise, 1.5) + future3 = self.executor.submit(time.sleep, 3) + + finished, pending = futures.wait( + [future1, future2, future3], + return_when=futures.FIRST_EXCEPTION) + + self.assertEqual(set([future1, future2]), finished) + self.assertEqual(set([future3]), pending) + + def test_first_exception_some_already_complete(self): + future1 = self.executor.submit(divmod, 21, 0) + future2 = self.executor.submit(time.sleep, 1.5) + + finished, pending = futures.wait( + [SUCCESSFUL_FUTURE, + CANCELLED_FUTURE, + CANCELLED_AND_NOTIFIED_FUTURE, + future1, future2], + return_when=futures.FIRST_EXCEPTION) + + self.assertEqual(set([SUCCESSFUL_FUTURE, + CANCELLED_AND_NOTIFIED_FUTURE, + future1]), finished) + self.assertEqual(set([CANCELLED_FUTURE, future2]), pending) + + def test_first_exception_one_already_failed(self): + future1 = self.executor.submit(time.sleep, 2) + + finished, pending = futures.wait( + [EXCEPTION_FUTURE, future1], + return_when=futures.FIRST_EXCEPTION) + + self.assertEqual(set([EXCEPTION_FUTURE]), finished) + self.assertEqual(set([future1]), pending) + + def test_all_completed(self): + future1 = self.executor.submit(divmod, 2, 0) + future2 = self.executor.submit(mul, 2, 21) + + finished, pending = futures.wait( + [SUCCESSFUL_FUTURE, + CANCELLED_AND_NOTIFIED_FUTURE, + EXCEPTION_FUTURE, + future1, + future2], + return_when=futures.ALL_COMPLETED) + + self.assertEqual(set([SUCCESSFUL_FUTURE, + CANCELLED_AND_NOTIFIED_FUTURE, + EXCEPTION_FUTURE, + future1, + future2]), finished) + self.assertEqual(set(), pending) + + @support.requires_resource('walltime') + def test_timeout(self): + future1 = self.executor.submit(mul, 6, 7) + future2 = self.executor.submit(time.sleep, 6) + + finished, pending = futures.wait( + [CANCELLED_AND_NOTIFIED_FUTURE, + EXCEPTION_FUTURE, + SUCCESSFUL_FUTURE, + future1, future2], + timeout=5, + return_when=futures.ALL_COMPLETED) + + self.assertEqual(set([CANCELLED_AND_NOTIFIED_FUTURE, + EXCEPTION_FUTURE, + SUCCESSFUL_FUTURE, + future1]), finished) + self.assertEqual(set([future2]), pending) + + +class ThreadPoolWaitTests(ThreadPoolMixin, WaitTests, BaseTestCase): + + def test_pending_calls_race(self): + # Issue #14406: multi-threaded race condition when waiting on all + # futures. + event = threading.Event() + def future_func(): + event.wait() + oldswitchinterval = sys.getswitchinterval() + sys.setswitchinterval(1e-6) + try: + fs = {self.executor.submit(future_func) for i in range(100)} + event.set() + futures.wait(fs, return_when=futures.ALL_COMPLETED) + finally: + sys.setswitchinterval(oldswitchinterval) + + +create_executor_tests(globals(), WaitTests, + executor_mixins=(ProcessPoolForkMixin, + ProcessPoolForkserverMixin, + ProcessPoolSpawnMixin)) + + +def setUpModule(): + setup_module() + + +if __name__ == "__main__": + unittest.main() diff --git a/Lib/test/test_concurrent_futures/util.py b/Lib/test/test_concurrent_futures/util.py new file mode 100644 index 00000000..dc48bec7 --- /dev/null +++ b/Lib/test/test_concurrent_futures/util.py @@ -0,0 +1,141 @@ +import multiprocessing +import sys +import time +import unittest +from concurrent import futures +from concurrent.futures._base import ( + PENDING, RUNNING, CANCELLED, CANCELLED_AND_NOTIFIED, FINISHED, Future, + ) +from concurrent.futures.process import _check_system_limits + +from test import support +from test.support import threading_helper + + +def create_future(state=PENDING, exception=None, result=None): + f = Future() + f._state = state + f._exception = exception + f._result = result + return f + + +PENDING_FUTURE = create_future(state=PENDING) +RUNNING_FUTURE = create_future(state=RUNNING) +CANCELLED_FUTURE = create_future(state=CANCELLED) +CANCELLED_AND_NOTIFIED_FUTURE = create_future(state=CANCELLED_AND_NOTIFIED) +EXCEPTION_FUTURE = create_future(state=FINISHED, exception=OSError()) +SUCCESSFUL_FUTURE = create_future(state=FINISHED, result=42) + + +class BaseTestCase(unittest.TestCase): + def setUp(self): + self._thread_key = threading_helper.threading_setup() + + def tearDown(self): + support.reap_children() + threading_helper.threading_cleanup(*self._thread_key) + + +class ExecutorMixin: + worker_count = 5 + executor_kwargs = {} + + def setUp(self): + super().setUp() + + self.t1 = time.monotonic() + if hasattr(self, "ctx"): + self.executor = self.executor_type( + max_workers=self.worker_count, + mp_context=self.get_context(), + **self.executor_kwargs) + else: + self.executor = self.executor_type( + max_workers=self.worker_count, + **self.executor_kwargs) + + def tearDown(self): + self.executor.shutdown(wait=True) + self.executor = None + + dt = time.monotonic() - self.t1 + if support.verbose: + print("%.2fs" % dt, end=' ') + self.assertLess(dt, 300, "synchronization issue: test lasted too long") + + super().tearDown() + + def get_context(self): + return multiprocessing.get_context(self.ctx) + + +class ThreadPoolMixin(ExecutorMixin): + executor_type = futures.ThreadPoolExecutor + + +class ProcessPoolForkMixin(ExecutorMixin): + executor_type = futures.ProcessPoolExecutor + ctx = "fork" + + def get_context(self): + try: + _check_system_limits() + except NotImplementedError: + self.skipTest("ProcessPoolExecutor unavailable on this system") + if sys.platform == "win32": + self.skipTest("require unix system") + return super().get_context() + + +class ProcessPoolSpawnMixin(ExecutorMixin): + executor_type = futures.ProcessPoolExecutor + ctx = "spawn" + + def get_context(self): + try: + _check_system_limits() + except NotImplementedError: + self.skipTest("ProcessPoolExecutor unavailable on this system") + return super().get_context() + + +class ProcessPoolForkserverMixin(ExecutorMixin): + executor_type = futures.ProcessPoolExecutor + ctx = "forkserver" + + def get_context(self): + try: + _check_system_limits() + except NotImplementedError: + self.skipTest("ProcessPoolExecutor unavailable on this system") + if sys.platform == "win32": + self.skipTest("require unix system") + return super().get_context() + + +def create_executor_tests(remote_globals, mixin, bases=(BaseTestCase,), + executor_mixins=(ThreadPoolMixin, + ProcessPoolForkMixin, + ProcessPoolForkserverMixin, + ProcessPoolSpawnMixin)): + def strip_mixin(name): + if name.endswith(('Mixin', 'Tests')): + return name[:-5] + elif name.endswith('Test'): + return name[:-4] + else: + return name + + module = remote_globals['__name__'] + for exe in executor_mixins: + name = ("%s%sTest" + % (strip_mixin(exe.__name__), strip_mixin(mixin.__name__))) + cls = type(name, (mixin,) + (exe,) + bases, {'__module__': module}) + remote_globals[name] = cls + + +def setup_module(): + unittest.addModuleCleanup(multiprocessing.util._cleanup_tests) + thread_info = threading_helper.threading_setup() + unittest.addModuleCleanup(threading_helper.threading_cleanup, *thread_info) diff --git a/Lib/test/test_configparser.py b/Lib/test/test_configparser.py index 59c4b275..da17c000 100644 --- a/Lib/test/test_configparser.py +++ b/Lib/test/test_configparser.py @@ -114,7 +114,7 @@ class BasicTestCase(CfgParserTestCaseClass): # The use of spaces in the section names serves as a # regression test for SourceForge bug #583248: - # http://www.python.org/sf/583248 + # https://bugs.python.org/issue583248 # API access eq(cf.get('Foo Bar', 'foo'), 'bar1') @@ -932,7 +932,7 @@ class ConfigParserTestCase(BasicTestCase, unittest.TestCase): ('name', 'value')]) def test_safe_interpolation(self): - # See http://www.python.org/sf/511737 + # See https://bugs.python.org/issue511737 cf = self.fromstring("[section]\n" "option1{eq}xxx\n" "option2{eq}%(option1)s/xxx\n" @@ -1612,23 +1612,12 @@ class CoverageOneHundredTestCase(unittest.TestCase): self.assertEqual(error.section, 'section') def test_parsing_error(self): - with self.assertRaises(ValueError) as cm: + with self.assertRaises(TypeError) as cm: configparser.ParsingError() - self.assertEqual(str(cm.exception), "Required argument `source' not " - "given.") - with self.assertRaises(ValueError) as cm: - configparser.ParsingError(source='source', filename='filename') - self.assertEqual(str(cm.exception), "Cannot specify both `filename' " - "and `source'. Use `source'.") - error = configparser.ParsingError(filename='source') + error = configparser.ParsingError(source='source') + self.assertEqual(error.source, 'source') + error = configparser.ParsingError('source') self.assertEqual(error.source, 'source') - with warnings.catch_warnings(record=True) as w: - warnings.simplefilter("always", DeprecationWarning) - self.assertEqual(error.filename, 'source') - error.filename = 'filename' - self.assertEqual(error.source, 'filename') - for warning in w: - self.assertTrue(warning.category is DeprecationWarning) def test_interpolation_validation(self): parser = configparser.ConfigParser() @@ -1647,27 +1636,6 @@ class CoverageOneHundredTestCase(unittest.TestCase): self.assertEqual(str(cm.exception), "bad interpolation variable " "reference '%(()'") - def test_readfp_deprecation(self): - sio = io.StringIO(""" - [section] - option = value - """) - parser = configparser.ConfigParser() - with warnings.catch_warnings(record=True) as w: - warnings.simplefilter("always", DeprecationWarning) - parser.readfp(sio, filename='StringIO') - for warning in w: - self.assertTrue(warning.category is DeprecationWarning) - self.assertEqual(len(parser), 2) - self.assertEqual(parser['section']['option'], 'value') - - def test_safeconfigparser_deprecation(self): - with warnings.catch_warnings(record=True) as w: - warnings.simplefilter("always", DeprecationWarning) - parser = configparser.SafeConfigParser() - for warning in w: - self.assertTrue(warning.category is DeprecationWarning) - def test_legacyinterpolation_deprecation(self): with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always", DeprecationWarning) @@ -1841,7 +1809,7 @@ class ExceptionPicklingTestCase(unittest.TestCase): self.assertEqual(e1.source, e2.source) self.assertEqual(e1.errors, e2.errors) self.assertEqual(repr(e1), repr(e2)) - e1 = configparser.ParsingError(filename='filename') + e1 = configparser.ParsingError('filename') e1.append(1, 'line1') e1.append(2, 'line2') e1.append(3, 'line3') diff --git a/Lib/test/test_context.py b/Lib/test/test_context.py index b1aece4f..dc685650 100644 --- a/Lib/test/test_context.py +++ b/Lib/test/test_context.py @@ -6,6 +6,7 @@ import random import time import unittest import weakref +from test import support from test.support import threading_helper try: @@ -570,6 +571,7 @@ class HamtTest(unittest.TestCase): self.assertEqual({k.name for k in h.keys()}, {'C', 'D', 'E'}) + @support.requires_resource('cpu') def test_hamt_stress(self): COLLECTION_SIZE = 7000 TEST_ITERS_EVERY = 647 diff --git a/Lib/test/test_contextlib.py b/Lib/test/test_contextlib.py index ec06785b..0f8351ab 100644 --- a/Lib/test/test_contextlib.py +++ b/Lib/test/test_contextlib.py @@ -10,6 +10,7 @@ import unittest from contextlib import * # Tests __all__ from test import support from test.support import os_helper +from test.support.testcase import ExceptionIsLikeMixin import weakref @@ -1148,7 +1149,7 @@ class TestRedirectStderr(TestRedirectStream, unittest.TestCase): orig_stream = "stderr" -class TestSuppress(unittest.TestCase): +class TestSuppress(ExceptionIsLikeMixin, unittest.TestCase): @support.requires_docstrings def test_instance_docs(self): @@ -1202,6 +1203,30 @@ class TestSuppress(unittest.TestCase): 1/0 self.assertTrue(outer_continued) + def test_exception_groups(self): + eg_ve = lambda: ExceptionGroup( + "EG with ValueErrors only", + [ValueError("ve1"), ValueError("ve2"), ValueError("ve3")], + ) + eg_all = lambda: ExceptionGroup( + "EG with many types of exceptions", + [ValueError("ve1"), KeyError("ke1"), ValueError("ve2"), KeyError("ke2")], + ) + with suppress(ValueError): + raise eg_ve() + with suppress(ValueError, KeyError): + raise eg_all() + with self.assertRaises(ExceptionGroup) as eg1: + with suppress(ValueError): + raise eg_all() + self.assertExceptionIsLike( + eg1.exception, + ExceptionGroup( + "EG with many types of exceptions", + [KeyError("ke1"), KeyError("ke2")], + ), + ) + class TestChdir(unittest.TestCase): def make_relative_path(self, *parts): diff --git a/Lib/test/test_copy.py b/Lib/test/test_copy.py index 7b1a927b..826e4682 100644 --- a/Lib/test/test_copy.py +++ b/Lib/test/test_copy.py @@ -91,9 +91,7 @@ class TestCopy(unittest.TestCase): # Type-specific _copy_xxx() methods def test_copy_atomic(self): - class Classic: - pass - class NewStyle(object): + class NewStyle: pass def f(): pass @@ -103,7 +101,7 @@ class TestCopy(unittest.TestCase): 42, 2**100, 3.14, True, False, 1j, "hello", "hello\u1234", f.__code__, b"world", bytes(range(256)), range(10), slice(1, 10, 2), - NewStyle, Classic, max, WithMetaclass, property()] + NewStyle, max, WithMetaclass, property()] for x in tests: self.assertIs(copy.copy(x), x) @@ -356,15 +354,13 @@ class TestCopy(unittest.TestCase): # Type-specific _deepcopy_xxx() methods def test_deepcopy_atomic(self): - class Classic: - pass - class NewStyle(object): + class NewStyle: pass def f(): pass tests = [None, ..., NotImplemented, 42, 2**100, 3.14, True, False, 1j, b"bytes", "hello", "hello\u1234", f.__code__, - NewStyle, range(10), Classic, max, property()] + NewStyle, range(10), max, property()] for x in tests: self.assertIs(copy.deepcopy(x), x) diff --git a/Lib/test/test_copyreg.py b/Lib/test/test_copyreg.py index e3f1cd81..e158c19d 100644 --- a/Lib/test/test_copyreg.py +++ b/Lib/test/test_copyreg.py @@ -6,6 +6,9 @@ from test.pickletester import ExtensionSaver class C: pass +def pickle_C(c): + return C, () + class WithoutSlots(object): pass @@ -32,16 +35,15 @@ class WithInherited(WithSingleString): class CopyRegTestCase(unittest.TestCase): def test_class(self): - self.assertRaises(TypeError, copyreg.pickle, - C, None, None) + copyreg.pickle(C, pickle_C) def test_noncallable_reduce(self): self.assertRaises(TypeError, copyreg.pickle, - type(1), "not a callable") + C, "not a callable") def test_noncallable_constructor(self): self.assertRaises(TypeError, copyreg.pickle, - type(1), int, "not a callable") + C, pickle_C, "not a callable") def test_bool(self): import copy diff --git a/Lib/test/test_coroutines.py b/Lib/test/test_coroutines.py index 93ddbf6e..47145782 100644 --- a/Lib/test/test_coroutines.py +++ b/Lib/test/test_coroutines.py @@ -709,9 +709,16 @@ class CoroutineTest(unittest.TestCase): aw = coro.__await__() next(aw) with self.assertRaises(ZeroDivisionError): - aw.throw(ZeroDivisionError, None, None) + aw.throw(ZeroDivisionError()) self.assertEqual(N, 102) + coro = foo() + aw = coro.__await__() + next(aw) + with self.assertRaises(ZeroDivisionError): + with self.assertWarns(DeprecationWarning): + aw.throw(ZeroDivisionError, ZeroDivisionError(), None) + def test_func_11(self): async def func(): pass coro = func() @@ -2358,15 +2365,15 @@ class OriginTrackingTest(unittest.TestCase): f"coroutine '{corofn.__qualname__}' was never awaited\n", "Coroutine created at (most recent call last)\n", f' File "{a1_filename}", line {a1_lineno}, in a1\n', - f' return corofn() # comment in a1', + " return corofn() # comment in a1", ])) check(2, "".join([ f"coroutine '{corofn.__qualname__}' was never awaited\n", "Coroutine created at (most recent call last)\n", f' File "{a2_filename}", line {a2_lineno}, in a2\n', - f' return a1() # comment in a2\n', + " return a1() # comment in a2\n", f' File "{a1_filename}", line {a1_lineno}, in a1\n', - f' return corofn() # comment in a1', + " return corofn() # comment in a1", ])) finally: diff --git a/Lib/test/test_cppext.py b/Lib/test/test_cppext/__init__.py similarity index 63% rename from Lib/test/test_cppext.py rename to Lib/test/test_cppext/__init__.py index 465894d2..a322f417 100644 --- a/Lib/test/test_cppext.py +++ b/Lib/test/test_cppext/__init__.py @@ -1,6 +1,7 @@ # gh-91321: Build a basic C++ test extension to check that the Python C API is # compatible with C++ and does not emit C++ compiler warnings. import os.path +import shutil import sys import unittest import subprocess @@ -10,16 +11,17 @@ from test.support import os_helper MS_WINDOWS = (sys.platform == 'win32') - - -SETUP_TESTCPPEXT = support.findfile('setup_testcppext.py') +SOURCE = os.path.join(os.path.dirname(__file__), 'extension.cpp') +SETUP = os.path.join(os.path.dirname(__file__), 'setup.py') @support.requires_subprocess() class TestCPPExt(unittest.TestCase): + @support.requires_resource('cpu') def test_build_cpp11(self): self.check_build(False, '_testcpp11ext') + @support.requires_resource('cpu') def test_build_cpp03(self): self.check_build(True, '_testcpp03ext') @@ -34,36 +36,26 @@ class TestCPPExt(unittest.TestCase): # the test uses venv+pip: skip if it's not available @support.requires_venv_with_pip() def check_build(self, std_cpp03, extension_name): - # Build in a temporary directory - with os_helper.temp_cwd(): - self._check_build(std_cpp03, extension_name) - - def _check_build(self, std_cpp03, extension_name): venv_dir = 'env' - verbose = support.verbose + with support.setup_venv_with_pip_setuptools_wheel(venv_dir) as python_exe: + self._check_build(std_cpp03, extension_name, python_exe) - # Create virtual environment to get setuptools - cmd = [sys.executable, '-X', 'dev', '-m', 'venv', venv_dir] - if verbose: - print() - print('Run:', ' '.join(cmd)) - subprocess.run(cmd, check=True) - - # Get the Python executable of the venv - python_exe = 'python' - if sys.executable.endswith('.exe'): - python_exe += '.exe' - if MS_WINDOWS: - python = os.path.join(venv_dir, 'Scripts', python_exe) - else: - python = os.path.join(venv_dir, 'bin', python_exe) + def _check_build(self, std_cpp03, extension_name, python_exe): + pkg_dir = 'pkg' + os.mkdir(pkg_dir) + shutil.copy(SETUP, os.path.join(pkg_dir, os.path.basename(SETUP))) + shutil.copy(SOURCE, os.path.join(pkg_dir, os.path.basename(SOURCE))) def run_cmd(operation, cmd): - if verbose: + env = os.environ.copy() + env['CPYTHON_TEST_CPP_STD'] = 'c++03' if std_cpp03 else 'c++11' + env['CPYTHON_TEST_EXT_NAME'] = extension_name + if support.verbose: print('Run:', ' '.join(cmd)) - subprocess.run(cmd, check=True) + subprocess.run(cmd, check=True, env=env) else: proc = subprocess.run(cmd, + env=env, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True) @@ -72,29 +64,23 @@ class TestCPPExt(unittest.TestCase): self.fail( f"{operation} failed with exit code {proc.returncode}") - # Build the C++ extension - cmd = [python, '-X', 'dev', - SETUP_TESTCPPEXT, 'build_ext', '--verbose'] - if std_cpp03: - cmd.append('-std=c++03') - run_cmd('Build', cmd) - - # Install the C++ extension - cmd = [python, '-X', 'dev', - SETUP_TESTCPPEXT, 'install'] + # Build and install the C++ extension + cmd = [python_exe, '-X', 'dev', + '-m', 'pip', 'install', '--no-build-isolation', + os.path.abspath(pkg_dir)] run_cmd('Install', cmd) # Do a reference run. Until we test that running python # doesn't leak references (gh-94755), run it so one can manually check # -X showrefcount results against this baseline. - cmd = [python, + cmd = [python_exe, '-X', 'dev', '-X', 'showrefcount', '-c', 'pass'] run_cmd('Reference run', cmd) # Import the C++ extension - cmd = [python, + cmd = [python_exe, '-X', 'dev', '-X', 'showrefcount', '-c', f"import {extension_name}"] diff --git a/Lib/test/_testcppext.cpp b/Lib/test/test_cppext/extension.cpp similarity index 98% rename from Lib/test/_testcppext.cpp rename to Lib/test/test_cppext/extension.cpp index 0e381a78..90669b10 100644 --- a/Lib/test/_testcppext.cpp +++ b/Lib/test/test_cppext/extension.cpp @@ -1,5 +1,7 @@ // gh-91321: Very basic C++ test extension to check that the Python C API is // compatible with C++ and does not emit C++ compiler warnings. +// +// The code is only built, not executed. // Always enable assertions #undef NDEBUG @@ -86,7 +88,7 @@ test_api_casts(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args)) // gh-93442: Pass 0 as NULL for PyObject* Py_XINCREF(0); Py_XDECREF(0); -#if _cplusplus >= 201103 +#if __cplusplus >= 201103 // Test nullptr passed as PyObject* Py_XINCREF(nullptr); Py_XDECREF(nullptr); diff --git a/Lib/test/setup_testcppext.py b/Lib/test/test_cppext/setup.py similarity index 59% rename from Lib/test/setup_testcppext.py rename to Lib/test/test_cppext/setup.py index c6b68104..976633bc 100644 --- a/Lib/test/setup_testcppext.py +++ b/Lib/test/test_cppext/setup.py @@ -1,7 +1,9 @@ # gh-91321: Build a basic C++ test extension to check that the Python C API is # compatible with C++ and does not emit C++ compiler warnings. +import os +import shlex import sys -from test import support +import sysconfig from setuptools import setup, Extension @@ -9,7 +11,7 @@ from setuptools import setup, Extension MS_WINDOWS = (sys.platform == 'win32') -SOURCE = support.findfile('_testcppext.cpp') +SOURCE = 'extension.cpp' if not MS_WINDOWS: # C++ compiler flags for GCC and clang CPPFLAGS = [ @@ -25,17 +27,22 @@ else: def main(): cppflags = list(CPPFLAGS) - if '-std=c++03' in sys.argv: - sys.argv.remove('-std=c++03') - std = 'c++03' - name = '_testcpp03ext' - else: - # Python currently targets C++11 - std = 'c++11' - name = '_testcpp11ext' + std = os.environ["CPYTHON_TEST_CPP_STD"] + name = os.environ["CPYTHON_TEST_EXT_NAME"] cppflags = [*CPPFLAGS, f'-std={std}'] + # gh-105776: When "gcc -std=11" is used as the C++ compiler, -std=c11 + # option emits a C++ compiler warning. Remove "-std11" option from the + # CC command. + cmd = (sysconfig.get_config_var('CC') or '') + if cmd is not None: + cmd = shlex.split(cmd) + cmd = [arg for arg in cmd if not arg.startswith('-std=')] + cmd = shlex.join(cmd) + # CC env var overrides sysconfig CC variable in setuptools + os.environ['CC'] = cmd + cpp_ext = Extension( name, sources=[SOURCE], diff --git a/Lib/test/test_cprofile.py b/Lib/test/test_cprofile.py index 4ec76988..3056fe84 100644 --- a/Lib/test/test_cprofile.py +++ b/Lib/test/test_cprofile.py @@ -25,7 +25,6 @@ class CProfileTest(ProfileTest): with support.catch_unraisable_exception() as cm: obj = _lsprof.Profiler(lambda: int) obj.enable() - obj = _lsprof.Profiler(1) obj.disable() obj.clear() @@ -37,10 +36,11 @@ class CProfileTest(ProfileTest): self.addCleanup(prof.disable) prof.enable() - self.assertIs(sys.getprofile(), prof) + self.assertEqual( + sys.monitoring.get_tool(sys.monitoring.PROFILER_ID), "cProfile") prof.disable() - self.assertIs(sys.getprofile(), None) + self.assertIs(sys.monitoring.get_tool(sys.monitoring.PROFILER_ID), None) def test_profile_as_context_manager(self): prof = self.profilerclass() @@ -53,10 +53,39 @@ class CProfileTest(ProfileTest): # profile should be set as the global profiler inside the # with-block - self.assertIs(sys.getprofile(), prof) + self.assertEqual( + sys.monitoring.get_tool(sys.monitoring.PROFILER_ID), "cProfile") # profile shouldn't be set once we leave the with-block. - self.assertIs(sys.getprofile(), None) + self.assertIs(sys.monitoring.get_tool(sys.monitoring.PROFILER_ID), None) + + def test_second_profiler(self): + pr = self.profilerclass() + pr2 = self.profilerclass() + pr.enable() + self.assertRaises(ValueError, pr2.enable) + pr.disable() + + def test_throw(self): + """ + gh-106152 + generator.throw() should trigger a call in cProfile + In the any() call below, there should be two entries for the generator: + * one for the call to __next__ which gets a True and terminates any + * one when the generator is garbage collected which will effectively + do a throw. + """ + pr = self.profilerclass() + pr.enable() + any(a == 1 for a in (1, 2)) + pr.disable() + pr.create_stats() + + for func, (cc, nc, _, _, _) in pr.stats.items(): + if func[2] == "<genexpr>": + self.assertEqual(cc, 2) + self.assertEqual(nc, 2) + class TestCommandLine(unittest.TestCase): def test_sort(self): @@ -100,7 +129,7 @@ profilee.py:88(helper2) <- 6 0.234 0.300 profilee.py:98(subhelper) <- 8 0.064 0.080 profilee.py:88(helper2) {built-in method builtins.hasattr} <- 4 0.000 0.004 profilee.py:73(helper1) 8 0.000 0.008 profilee.py:88(helper2) -{built-in method sys.exc_info} <- 4 0.000 0.000 profilee.py:73(helper1) +{built-in method sys.exception} <- 4 0.000 0.000 profilee.py:73(helper1) {method 'append' of 'list' objects} <- 4 0.000 0.000 profilee.py:73(helper1)""" _ProfileOutput['print_callees'] = """\ <string>:1(<module>) -> 1 0.270 1.000 profilee.py:25(testfunc) diff --git a/Lib/test/test_csv.py b/Lib/test/test_csv.py index 834217bf..bc9961e0 100644 --- a/Lib/test/test_csv.py +++ b/Lib/test/test_csv.py @@ -10,7 +10,7 @@ import csv import gc import pickle from test import support -from test.support import warnings_helper +from test.support import warnings_helper, import_helper, check_disallow_instantiation from itertools import permutations from textwrap import dedent from collections import OrderedDict @@ -187,6 +187,10 @@ class Test_Csv(unittest.TestCase): quoting = csv.QUOTE_ALL) self._write_test(['a\nb',1], '"a\nb","1"', quoting = csv.QUOTE_ALL) + self._write_test(['a','',None,1], '"a","",,1', + quoting = csv.QUOTE_STRINGS) + self._write_test(['a','',None,1], '"a","",,"1"', + quoting = csv.QUOTE_NOTNULL) def test_write_escape(self): self._write_test(['a',1,'p,q'], 'a,1,"p,q"', @@ -278,7 +282,7 @@ class Test_Csv(unittest.TestCase): self.assertRaises(OSError, writer.writerows, BadIterable()) @support.cpython_only - @support.requires_legacy_unicode_capi + @support.requires_legacy_unicode_capi() @warnings_helper.ignore_warnings(category=DeprecationWarning) def test_writerows_legacy_strings(self): import _testcapi @@ -762,6 +766,10 @@ class TestDictFields(unittest.TestCase): dictrow = {'f0': 0, 'f1': 1, 'f2': 2, 'f3': 3} self.assertRaises(ValueError, csv.DictWriter.writerow, writer, dictrow) + # see bpo-44512 (differently cased 'raise' should not result in 'ignore') + writer = csv.DictWriter(fileobj, ['f1', 'f2'], extrasaction="RAISE") + self.assertRaises(ValueError, csv.DictWriter.writerow, writer, dictrow) + def test_write_field_not_in_field_names_ignore(self): fileobj = StringIO() writer = csv.DictWriter(fileobj, ['f1', 'f2'], extrasaction="ignore") @@ -769,6 +777,38 @@ class TestDictFields(unittest.TestCase): csv.DictWriter.writerow(writer, dictrow) self.assertEqual(fileobj.getvalue(), "1,2\r\n") + # bpo-44512 + writer = csv.DictWriter(fileobj, ['f1', 'f2'], extrasaction="IGNORE") + csv.DictWriter.writerow(writer, dictrow) + + def test_dict_reader_fieldnames_accepts_iter(self): + fieldnames = ["a", "b", "c"] + f = StringIO() + reader = csv.DictReader(f, iter(fieldnames)) + self.assertEqual(reader.fieldnames, fieldnames) + + def test_dict_reader_fieldnames_accepts_list(self): + fieldnames = ["a", "b", "c"] + f = StringIO() + reader = csv.DictReader(f, fieldnames) + self.assertEqual(reader.fieldnames, fieldnames) + + def test_dict_writer_fieldnames_rejects_iter(self): + fieldnames = ["a", "b", "c"] + f = StringIO() + writer = csv.DictWriter(f, iter(fieldnames)) + self.assertEqual(writer.fieldnames, fieldnames) + + def test_dict_writer_fieldnames_accepts_list(self): + fieldnames = ["a", "b", "c"] + f = StringIO() + writer = csv.DictWriter(f, fieldnames) + self.assertEqual(writer.fieldnames, fieldnames) + + def test_dict_reader_fieldnames_is_optional(self): + f = StringIO() + reader = csv.DictReader(f, fieldnames=None) + def test_read_dict_fields(self): with TemporaryFile("w+", encoding="utf-8") as fileobj: fileobj.write("1,2,abc\r\n") @@ -1390,5 +1430,12 @@ class MiscTestCase(unittest.TestCase): # issue 44089 class Foo(csv.Error): ... + @support.cpython_only + def test_disallow_instantiation(self): + _csv = import_helper.import_module("_csv") + for tp in _csv.Reader, _csv.Writer: + with self.subTest(tp=tp): + check_disallow_instantiation(self, tp) + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_ctypes.py b/Lib/test/test_ctypes.py deleted file mode 100644 index b0a12c97..00000000 --- a/Lib/test/test_ctypes.py +++ /dev/null @@ -1,10 +0,0 @@ -import unittest -from test.support.import_helper import import_module - - -ctypes_test = import_module('ctypes.test') - -load_tests = ctypes_test.load_tests - -if __name__ == "__main__": - unittest.main() diff --git a/Lib/ctypes/test/__init__.py b/Lib/test/test_ctypes/__init__.py similarity index 100% rename from Lib/ctypes/test/__init__.py rename to Lib/test/test_ctypes/__init__.py diff --git a/Lib/test/test_ctypes/__main__.py b/Lib/test/test_ctypes/__main__.py new file mode 100644 index 00000000..3003d4db --- /dev/null +++ b/Lib/test/test_ctypes/__main__.py @@ -0,0 +1,4 @@ +from test.test_ctypes import load_tests +import unittest + +unittest.main() diff --git a/Lib/ctypes/test/test_anon.py b/Lib/test/test_ctypes/test_anon.py similarity index 100% rename from Lib/ctypes/test/test_anon.py rename to Lib/test/test_ctypes/test_anon.py diff --git a/Lib/ctypes/test/test_array_in_pointer.py b/Lib/test/test_ctypes/test_array_in_pointer.py similarity index 100% rename from Lib/ctypes/test/test_array_in_pointer.py rename to Lib/test/test_ctypes/test_array_in_pointer.py diff --git a/Lib/ctypes/test/test_arrays.py b/Lib/test/test_ctypes/test_arrays.py similarity index 99% rename from Lib/ctypes/test/test_arrays.py rename to Lib/test/test_ctypes/test_arrays.py index 14603b70..415a5785 100644 --- a/Lib/ctypes/test/test_arrays.py +++ b/Lib/test/test_ctypes/test_arrays.py @@ -3,7 +3,7 @@ from test.support import bigmemtest, _2G import sys from ctypes import * -from ctypes.test import need_symbol +from test.test_ctypes import need_symbol formats = "bBhHiIlLqQfd" diff --git a/Lib/ctypes/test/test_as_parameter.py b/Lib/test/test_ctypes/test_as_parameter.py similarity index 98% rename from Lib/ctypes/test/test_as_parameter.py rename to Lib/test/test_ctypes/test_as_parameter.py index 9c39179d..36fec572 100644 --- a/Lib/ctypes/test/test_as_parameter.py +++ b/Lib/test/test_ctypes/test_as_parameter.py @@ -1,6 +1,6 @@ import unittest from ctypes import * -from ctypes.test import need_symbol +from test.test_ctypes import need_symbol import _ctypes_test dll = CDLL(_ctypes_test.__file__) @@ -194,7 +194,7 @@ class BasicWrapTestCase(unittest.TestCase): def test_recursive_as_param(self): from ctypes import c_int - class A(object): + class A: pass a = A() @@ -205,7 +205,7 @@ class BasicWrapTestCase(unittest.TestCase): #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -class AsParamWrapper(object): +class AsParamWrapper: def __init__(self, param): self._as_parameter_ = param @@ -214,7 +214,7 @@ class AsParamWrapperTestCase(BasicWrapTestCase): #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -class AsParamPropertyWrapper(object): +class AsParamPropertyWrapper: def __init__(self, param): self._param = param diff --git a/Lib/ctypes/test/test_bitfields.py b/Lib/test/test_ctypes/test_bitfields.py similarity index 99% rename from Lib/ctypes/test/test_bitfields.py rename to Lib/test/test_ctypes/test_bitfields.py index 66acd62e..dad71a0b 100644 --- a/Lib/ctypes/test/test_bitfields.py +++ b/Lib/test/test_ctypes/test_bitfields.py @@ -1,5 +1,5 @@ from ctypes import * -from ctypes.test import need_symbol +from test.test_ctypes import need_symbol from test import support import unittest import os diff --git a/Lib/ctypes/test/test_buffers.py b/Lib/test/test_ctypes/test_buffers.py similarity index 98% rename from Lib/ctypes/test/test_buffers.py rename to Lib/test/test_ctypes/test_buffers.py index 15782be7..a9be2023 100644 --- a/Lib/ctypes/test/test_buffers.py +++ b/Lib/test/test_ctypes/test_buffers.py @@ -1,5 +1,5 @@ from ctypes import * -from ctypes.test import need_symbol +from test.test_ctypes import need_symbol import unittest class StringBufferTestCase(unittest.TestCase): diff --git a/Lib/ctypes/test/test_bytes.py b/Lib/test/test_ctypes/test_bytes.py similarity index 100% rename from Lib/ctypes/test/test_bytes.py rename to Lib/test/test_ctypes/test_bytes.py diff --git a/Lib/ctypes/test/test_byteswap.py b/Lib/test/test_ctypes/test_byteswap.py similarity index 98% rename from Lib/ctypes/test/test_byteswap.py rename to Lib/test/test_ctypes/test_byteswap.py index 7e98559d..caefb774 100644 --- a/Lib/ctypes/test/test_byteswap.py +++ b/Lib/test/test_ctypes/test_byteswap.py @@ -14,14 +14,6 @@ def bin(s): # For Structures and Unions, these types are created on demand. class Test(unittest.TestCase): - @unittest.skip('test disabled') - def test_X(self): - print(sys.byteorder, file=sys.stderr) - for i in range(32): - bits = BITS() - setattr(bits, "i%s" % i, 1) - dump(bits) - def test_slots(self): class BigPoint(BigEndianStructure): __slots__ = () diff --git a/Lib/ctypes/test/test_callbacks.py b/Lib/test/test_ctypes/test_callbacks.py similarity index 95% rename from Lib/ctypes/test/test_callbacks.py rename to Lib/test/test_ctypes/test_callbacks.py index 8f95a244..a9c6524b 100644 --- a/Lib/ctypes/test/test_callbacks.py +++ b/Lib/test/test_ctypes/test_callbacks.py @@ -3,7 +3,7 @@ import unittest from test import support from ctypes import * -from ctypes.test import need_symbol +from test.test_ctypes import need_symbol from _ctypes import CTYPES_MAX_ARGCOUNT import _ctypes_test @@ -93,14 +93,6 @@ class Callbacks(unittest.TestCase): self.check_type(c_char, b"x") self.check_type(c_char, b"a") - # disabled: would now (correctly) raise a RuntimeWarning about - # a memory leak. A callback function cannot return a non-integral - # C type without causing a memory leak. - @unittest.skip('test disabled') - def test_char_p(self): - self.check_type(c_char_p, "abc") - self.check_type(c_char_p, "def") - def test_pyobject(self): o = () from sys import getrefcount as grc @@ -130,7 +122,7 @@ class Callbacks(unittest.TestCase): def test_issue_7959(self): proto = self.functype.__func__(None) - class X(object): + class X: def func(self): pass def __init__(self): self.v = proto(self.func) @@ -150,6 +142,18 @@ class Callbacks(unittest.TestCase): gc.collect() CFUNCTYPE(None)(lambda x=Nasty(): None) + @need_symbol('WINFUNCTYPE') + def test_i38748_stackCorruption(self): + callback_funcType = WINFUNCTYPE(c_long, c_long, c_longlong) + @callback_funcType + def callback(a, b): + c = a + b + print(f"a={a}, b={b}, c={c}") + return c + dll = cdll[_ctypes_test.__file__] + # With no fix for i38748, the next line will raise OSError and cause the test to fail. + self.assertEqual(dll._test_i38748_runCallback(callback, 5, 10), 15) + @need_symbol('WINFUNCTYPE') class StdcallCallbacks(Callbacks): diff --git a/Lib/ctypes/test/test_cast.py b/Lib/test/test_ctypes/test_cast.py similarity index 98% rename from Lib/ctypes/test/test_cast.py rename to Lib/test/test_ctypes/test_cast.py index 6878f973..7ee23b16 100644 --- a/Lib/ctypes/test/test_cast.py +++ b/Lib/test/test_ctypes/test_cast.py @@ -1,5 +1,5 @@ from ctypes import * -from ctypes.test import need_symbol +from test.test_ctypes import need_symbol import unittest import sys diff --git a/Lib/ctypes/test/test_cfuncs.py b/Lib/test/test_ctypes/test_cfuncs.py similarity index 99% rename from Lib/ctypes/test/test_cfuncs.py rename to Lib/test/test_ctypes/test_cfuncs.py index 09b06840..7cba4b0e 100644 --- a/Lib/ctypes/test/test_cfuncs.py +++ b/Lib/test/test_ctypes/test_cfuncs.py @@ -3,7 +3,7 @@ import unittest from ctypes import * -from ctypes.test import need_symbol +from test.test_ctypes import need_symbol import _ctypes_test diff --git a/Lib/ctypes/test/test_checkretval.py b/Lib/test/test_ctypes/test_checkretval.py similarity index 95% rename from Lib/ctypes/test/test_checkretval.py rename to Lib/test/test_ctypes/test_checkretval.py index e9567dc3..1492099f 100644 --- a/Lib/ctypes/test/test_checkretval.py +++ b/Lib/test/test_ctypes/test_checkretval.py @@ -1,7 +1,7 @@ import unittest from ctypes import * -from ctypes.test import need_symbol +from test.test_ctypes import need_symbol class CHECKED(c_int): def _check_retval_(value): diff --git a/Lib/ctypes/test/test_delattr.py b/Lib/test/test_ctypes/test_delattr.py similarity index 100% rename from Lib/ctypes/test/test_delattr.py rename to Lib/test/test_ctypes/test_delattr.py diff --git a/Lib/ctypes/test/test_errno.py b/Lib/test/test_ctypes/test_errno.py similarity index 100% rename from Lib/ctypes/test/test_errno.py rename to Lib/test/test_ctypes/test_errno.py diff --git a/Lib/ctypes/test/test_find.py b/Lib/test/test_ctypes/test_find.py similarity index 100% rename from Lib/ctypes/test/test_find.py rename to Lib/test/test_ctypes/test_find.py diff --git a/Lib/ctypes/test/test_frombuffer.py b/Lib/test/test_ctypes/test_frombuffer.py similarity index 100% rename from Lib/ctypes/test/test_frombuffer.py rename to Lib/test/test_ctypes/test_frombuffer.py diff --git a/Lib/ctypes/test/test_funcptr.py b/Lib/test/test_ctypes/test_funcptr.py similarity index 100% rename from Lib/ctypes/test/test_funcptr.py rename to Lib/test/test_ctypes/test_funcptr.py diff --git a/Lib/ctypes/test/test_functions.py b/Lib/test/test_ctypes/test_functions.py similarity index 91% rename from Lib/ctypes/test/test_functions.py rename to Lib/test/test_ctypes/test_functions.py index fc571700..703bd2c6 100644 --- a/Lib/ctypes/test/test_functions.py +++ b/Lib/test/test_ctypes/test_functions.py @@ -6,7 +6,7 @@ Later... """ from ctypes import * -from ctypes.test import need_symbol +from test.test_ctypes import need_symbol import sys, unittest try: @@ -54,6 +54,23 @@ class FunctionTestCase(unittest.TestCase): class X(object, Structure): _fields_ = [] + def test_c_char_parm(self): + proto = CFUNCTYPE(c_int, c_char) + def callback(*args): + return 0 + + callback = proto(callback) + + self.assertEqual(callback(b"a"), 0) + + with self.assertRaises(ArgumentError) as cm: + callback(b"abc") + + self.assertEqual(str(cm.exception), + "argument 1: TypeError: one character bytes, " + "bytearray or integer expected") + + @need_symbol('c_wchar') def test_wchar_parm(self): f = dll._testfunc_i_bhilfd @@ -62,6 +79,18 @@ class FunctionTestCase(unittest.TestCase): self.assertEqual(result, 139) self.assertEqual(type(result), int) + with self.assertRaises(ArgumentError) as cm: + f(1, 2, 3, 4, 5.0, 6.0) + self.assertEqual(str(cm.exception), + "argument 2: TypeError: unicode string expected " + "instead of int instance") + + with self.assertRaises(ArgumentError) as cm: + f(1, "abc", 3, 4, 5.0, 6.0) + self.assertEqual(str(cm.exception), + "argument 2: TypeError: one character unicode string " + "expected") + @need_symbol('c_wchar') def test_wchar_result(self): f = dll._testfunc_i_bhilfd @@ -371,7 +400,7 @@ class FunctionTestCase(unittest.TestCase): (9*2, 8*3, 7*4, 6*5, 5*6, 4*7, 3*8, 2*9)) def test_sf1651235(self): - # see https://www.python.org/sf/1651235 + # see https://bugs.python.org/issue1651235 proto = CFUNCTYPE(c_int, RECT, POINT) def callback(*args): diff --git a/Lib/ctypes/test/test_incomplete.py b/Lib/test/test_ctypes/test_incomplete.py similarity index 100% rename from Lib/ctypes/test/test_incomplete.py rename to Lib/test/test_ctypes/test_incomplete.py diff --git a/Lib/ctypes/test/test_init.py b/Lib/test/test_ctypes/test_init.py similarity index 100% rename from Lib/ctypes/test/test_init.py rename to Lib/test/test_ctypes/test_init.py diff --git a/Lib/ctypes/test/test_internals.py b/Lib/test/test_ctypes/test_internals.py similarity index 100% rename from Lib/ctypes/test/test_internals.py rename to Lib/test/test_ctypes/test_internals.py diff --git a/Lib/ctypes/test/test_keeprefs.py b/Lib/test/test_ctypes/test_keeprefs.py similarity index 80% rename from Lib/ctypes/test/test_keeprefs.py rename to Lib/test/test_ctypes/test_keeprefs.py index 94c02573..e20adc76 100644 --- a/Lib/ctypes/test/test_keeprefs.py +++ b/Lib/test/test_ctypes/test_keeprefs.py @@ -93,37 +93,6 @@ class PointerTestCase(unittest.TestCase): x = pointer(i) self.assertEqual(x._objects, {'1': i}) -class DeletePointerTestCase(unittest.TestCase): - @unittest.skip('test disabled') - def test_X(self): - class X(Structure): - _fields_ = [("p", POINTER(c_char_p))] - x = X() - i = c_char_p("abc def") - from sys import getrefcount as grc - print("2?", grc(i)) - x.p = pointer(i) - print("3?", grc(i)) - for i in range(320): - c_int(99) - x.p[0] - print(x.p[0]) -## del x -## print "2?", grc(i) -## del i - import gc - gc.collect() - for i in range(320): - c_int(99) - x.p[0] - print(x.p[0]) - print(x.p.contents) -## print x._objects - - x.p[0] = "spam spam" -## print x.p[0] - print("+" * 42) - print(x._objects) class PointerToStructure(unittest.TestCase): def test(self): diff --git a/Lib/ctypes/test/test_libc.py b/Lib/test/test_ctypes/test_libc.py similarity index 100% rename from Lib/ctypes/test/test_libc.py rename to Lib/test/test_ctypes/test_libc.py diff --git a/Lib/ctypes/test/test_loading.py b/Lib/test/test_ctypes/test_loading.py similarity index 89% rename from Lib/ctypes/test/test_loading.py rename to Lib/test/test_ctypes/test_loading.py index ea892277..f2434926 100644 --- a/Lib/ctypes/test/test_loading.py +++ b/Lib/test/test_ctypes/test_loading.py @@ -28,10 +28,20 @@ class LoaderTest(unittest.TestCase): unknowndll = "xxrandomnamexx" def test_load(self): - if libc_name is None: - self.skipTest('could not find libc') - CDLL(libc_name) - CDLL(os.path.basename(libc_name)) + if libc_name is not None: + test_lib = libc_name + else: + if os.name == "nt": + import _ctypes_test + test_lib = _ctypes_test.__file__ + else: + self.skipTest('could not find library to load') + CDLL(test_lib) + CDLL(os.path.basename(test_lib)) + class CTypesTestPathLikeCls: + def __fspath__(self): + return test_lib + CDLL(CTypesTestPathLikeCls()) self.assertRaises(OSError, CDLL, self.unknowndll) def test_load_version(self): @@ -93,7 +103,7 @@ class LoaderTest(unittest.TestCase): # NOT fit into a 32-bit integer. FreeLibrary must be able # to accept this address. - # These are tests for https://www.python.org/sf/1703286 + # These are tests for https://bugs.python.org/issue1703286 handle = LoadLibrary("advapi32") FreeLibrary(handle) @@ -116,6 +126,12 @@ class LoaderTest(unittest.TestCase): # This is the real test: call the function via 'call_function' self.assertEqual(0, call_function(proc, (None,))) + @unittest.skipUnless(os.name == "nt", + 'test specific to Windows') + def test_load_hasattr(self): + # bpo-34816: shouldn't raise OSError + self.assertFalse(hasattr(windll, 'test')) + @unittest.skipUnless(os.name == "nt", 'test specific to Windows') def test_load_dll_with_flags(self): diff --git a/Lib/ctypes/test/test_macholib.py b/Lib/test/test_ctypes/test_macholib.py similarity index 100% rename from Lib/ctypes/test/test_macholib.py rename to Lib/test/test_ctypes/test_macholib.py diff --git a/Lib/ctypes/test/test_memfunctions.py b/Lib/test/test_ctypes/test_memfunctions.py similarity index 98% rename from Lib/ctypes/test/test_memfunctions.py rename to Lib/test/test_ctypes/test_memfunctions.py index e784b9a7..d5c97352 100644 --- a/Lib/ctypes/test/test_memfunctions.py +++ b/Lib/test/test_ctypes/test_memfunctions.py @@ -2,7 +2,7 @@ import sys from test import support import unittest from ctypes import * -from ctypes.test import need_symbol +from test.test_ctypes import need_symbol class MemFunctionsTest(unittest.TestCase): @unittest.skip('test disabled') diff --git a/Lib/ctypes/test/test_numbers.py b/Lib/test/test_ctypes/test_numbers.py similarity index 75% rename from Lib/ctypes/test/test_numbers.py rename to Lib/test/test_ctypes/test_numbers.py index db500e81..a7696376 100644 --- a/Lib/ctypes/test/test_numbers.py +++ b/Lib/test/test_ctypes/test_numbers.py @@ -82,14 +82,6 @@ class NumberTestCase(unittest.TestCase): self.assertRaises(TypeError, t, "") self.assertRaises(TypeError, t, None) - @unittest.skip('test disabled') - def test_valid_ranges(self): - # invalid values of the correct type - # raise ValueError (not OverflowError) - for t, (l, h) in zip(unsigned_types, unsigned_ranges): - self.assertRaises(ValueError, t, l-1) - self.assertRaises(ValueError, t, h+1) - def test_from_param(self): # the from_param class method attribute always # returns PyCArgObject instances @@ -106,7 +98,7 @@ class NumberTestCase(unittest.TestCase): def test_floats(self): # c_float and c_double can be created from # Python int and float - class FloatLike(object): + class FloatLike: def __float__(self): return 2.0 f = FloatLike() @@ -117,15 +109,15 @@ class NumberTestCase(unittest.TestCase): self.assertEqual(t(f).value, 2.0) def test_integers(self): - class FloatLike(object): + class FloatLike: def __float__(self): return 2.0 f = FloatLike() - class IntLike(object): + class IntLike: def __int__(self): return 2 d = IntLike() - class IndexLike(object): + class IndexLike: def __index__(self): return 2 i = IndexLike() @@ -205,19 +197,6 @@ class NumberTestCase(unittest.TestCase): a[0] = ord('?') self.assertEqual(v.value, b'?') - # array does not support c_bool / 't' - @unittest.skip('test disabled') - def test_bool_from_address(self): - from ctypes import c_bool - from array import array - a = array(c_bool._type_, [True]) - v = t.from_address(a.buffer_info()[0]) - self.assertEqual(v.value, a[0]) - self.assertEqual(type(v) is t) - a[0] = False - self.assertEqual(v.value, a[0]) - self.assertEqual(type(v) is t) - def test_init(self): # c_int() can be initialized from Python's int, and c_int. # Not from c_long or so, which seems strange, abc should @@ -234,62 +213,6 @@ class NumberTestCase(unittest.TestCase): if (hasattr(t, "__ctype_le__")): self.assertRaises(OverflowError, t.__ctype_le__, big_int) - @unittest.skip('test disabled') - def test_perf(self): - check_perf() - -from ctypes import _SimpleCData -class c_int_S(_SimpleCData): - _type_ = "i" - __slots__ = [] - -def run_test(rep, msg, func, arg=None): -## items = [None] * rep - items = range(rep) - from time import perf_counter as clock - if arg is not None: - start = clock() - for i in items: - func(arg); func(arg); func(arg); func(arg); func(arg) - stop = clock() - else: - start = clock() - for i in items: - func(); func(); func(); func(); func() - stop = clock() - print("%15s: %.2f us" % (msg, ((stop-start)*1e6/5/rep))) - -def check_perf(): - # Construct 5 objects - from ctypes import c_int - - REP = 200000 - - run_test(REP, "int()", int) - run_test(REP, "int(999)", int) - run_test(REP, "c_int()", c_int) - run_test(REP, "c_int(999)", c_int) - run_test(REP, "c_int_S()", c_int_S) - run_test(REP, "c_int_S(999)", c_int_S) - -# Python 2.3 -OO, win2k, P4 700 MHz: -# -# int(): 0.87 us -# int(999): 0.87 us -# c_int(): 3.35 us -# c_int(999): 3.34 us -# c_int_S(): 3.23 us -# c_int_S(999): 3.24 us - -# Python 2.2 -OO, win2k, P4 700 MHz: -# -# int(): 0.89 us -# int(999): 0.89 us -# c_int(): 9.99 us -# c_int(999): 10.02 us -# c_int_S(): 9.87 us -# c_int_S(999): 9.85 us if __name__ == '__main__': -## check_perf() unittest.main() diff --git a/Lib/ctypes/test/test_objects.py b/Lib/test/test_ctypes/test_objects.py similarity index 87% rename from Lib/ctypes/test/test_objects.py rename to Lib/test/test_ctypes/test_objects.py index 19e3dc1f..44a3c61a 100644 --- a/Lib/ctypes/test/test_objects.py +++ b/Lib/test/test_ctypes/test_objects.py @@ -42,7 +42,7 @@ The'array' attribute of the 'x' object shares part of the memory buffer of 'x' ('_b_base_' is either None, or the root object owning the memory block): >>> print(x.array._b_base_) # doctest: +ELLIPSIS -<ctypes.test.test_objects.X object at 0x...> +<test.test_ctypes.test_objects.X object at 0x...> >>> >>> x.array[0] = b'spam spam spam' @@ -56,12 +56,12 @@ of 'x' ('_b_base_' is either None, or the root object owning the memory block): import unittest, doctest -import ctypes.test.test_objects +import test.test_ctypes.test_objects class TestCase(unittest.TestCase): def test(self): - failures, tests = doctest.testmod(ctypes.test.test_objects) + failures, tests = doctest.testmod(test.test_ctypes.test_objects) self.assertFalse(failures, 'doctests failed, see output above') if __name__ == '__main__': - doctest.testmod(ctypes.test.test_objects) + doctest.testmod(test.test_ctypes.test_objects) diff --git a/Lib/ctypes/test/test_parameters.py b/Lib/test/test_ctypes/test_parameters.py similarity index 92% rename from Lib/ctypes/test/test_parameters.py rename to Lib/test/test_ctypes/test_parameters.py index 3fdc994e..f5afa76f 100644 --- a/Lib/ctypes/test/test_parameters.py +++ b/Lib/test/test_ctypes/test_parameters.py @@ -1,11 +1,10 @@ import unittest -from ctypes.test import need_symbol +from test.test_ctypes import need_symbol import test.support class SimpleTypesTestCase(unittest.TestCase): def setUp(self): - import ctypes try: from _ctypes import set_conversion_mode except ImportError: @@ -79,6 +78,29 @@ class SimpleTypesTestCase(unittest.TestCase): pa = c_wchar_p.from_param(c_wchar_p("123")) self.assertEqual(type(pa), c_wchar_p) + def test_c_char(self): + from ctypes import c_char + + with self.assertRaises(TypeError) as cm: + c_char.from_param(b"abc") + self.assertEqual(str(cm.exception), + "one character bytes, bytearray or integer expected") + + @need_symbol('c_wchar') + def test_c_wchar(self): + from ctypes import c_wchar + + with self.assertRaises(TypeError) as cm: + c_wchar.from_param("abc") + self.assertEqual(str(cm.exception), + "one character unicode string expected") + + + with self.assertRaises(TypeError) as cm: + c_wchar.from_param(123) + self.assertEqual(str(cm.exception), + "unicode string expected instead of int instance") + def test_int_pointers(self): from ctypes import c_short, c_uint, c_int, c_long, POINTER, pointer LPINT = POINTER(c_int) @@ -145,7 +167,7 @@ class SimpleTypesTestCase(unittest.TestCase): # TypeError: has no from_param method self.assertRaises(TypeError, setattr, func, "argtypes", (object,)) - class Adapter(object): + class Adapter: def from_param(cls, obj): return None @@ -153,7 +175,7 @@ class SimpleTypesTestCase(unittest.TestCase): self.assertEqual(func(None), None) self.assertEqual(func(object()), None) - class Adapter(object): + class Adapter: def from_param(cls, obj): return obj @@ -162,7 +184,7 @@ class SimpleTypesTestCase(unittest.TestCase): self.assertRaises(ArgumentError, func, object()) self.assertEqual(func(c_void_p(42)), 42) - class Adapter(object): + class Adapter: def from_param(cls, obj): raise ValueError(obj) diff --git a/Lib/ctypes/test/test_pep3118.py b/Lib/test/test_ctypes/test_pep3118.py similarity index 84% rename from Lib/ctypes/test/test_pep3118.py rename to Lib/test/test_ctypes/test_pep3118.py index efffc80a..03816174 100644 --- a/Lib/ctypes/test/test_pep3118.py +++ b/Lib/test/test_ctypes/test_pep3118.py @@ -28,7 +28,7 @@ class Test(unittest.TestCase): if shape: self.assertEqual(len(v), shape[0]) else: - self.assertEqual(len(v) * sizeof(itemtp), sizeof(ob)) + self.assertRaises(TypeError, len, v) self.assertEqual(v.itemsize, sizeof(itemtp)) self.assertEqual(v.shape, shape) # XXX Issue #12851: PyCData_NewGetBuffer() must provide strides @@ -39,11 +39,10 @@ class Test(unittest.TestCase): # they are always read/write self.assertFalse(v.readonly) - if v.shape: - n = 1 - for dim in v.shape: - n = n * dim - self.assertEqual(n * v.itemsize, len(v.tobytes())) + n = 1 + for dim in v.shape: + n = n * dim + self.assertEqual(n * v.itemsize, len(v.tobytes())) except: # so that we can see the failing type print(tp) @@ -58,7 +57,7 @@ class Test(unittest.TestCase): if shape: self.assertEqual(len(v), shape[0]) else: - self.assertEqual(len(v) * sizeof(itemtp), sizeof(ob)) + self.assertRaises(TypeError, len, v) self.assertEqual(v.itemsize, sizeof(itemtp)) self.assertEqual(v.shape, shape) # XXX Issue #12851 @@ -67,11 +66,10 @@ class Test(unittest.TestCase): # they are always read/write self.assertFalse(v.readonly) - if v.shape: - n = 1 - for dim in v.shape: - n = n * dim - self.assertEqual(n, len(v)) + n = 1 + for dim in v.shape: + n = n * dim + self.assertEqual(n * v.itemsize, len(v.tobytes())) except: # so that we can see the failing type print(tp) @@ -86,6 +84,20 @@ class PackedPoint(Structure): _pack_ = 2 _fields_ = [("x", c_long), ("y", c_long)] +class PointMidPad(Structure): + _fields_ = [("x", c_byte), ("y", c_uint)] + +class PackedPointMidPad(Structure): + _pack_ = 2 + _fields_ = [("x", c_byte), ("y", c_uint64)] + +class PointEndPad(Structure): + _fields_ = [("x", c_uint), ("y", c_byte)] + +class PackedPointEndPad(Structure): + _pack_ = 2 + _fields_ = [("x", c_uint64), ("y", c_byte)] + class Point2(Structure): pass Point2._fields_ = [("x", c_long), ("y", c_long)] @@ -185,11 +197,14 @@ native_types = [ ## structures and unions - (Point, "T{<l:x:<l:y:}".replace('l', s_long), (), Point), - # packed structures do not implement the pep - (PackedPoint, "B", (), PackedPoint), - (Point2, "T{<l:x:<l:y:}".replace('l', s_long), (), Point2), - (EmptyStruct, "T{}", (), EmptyStruct), + (Point2, "T{<l:x:<l:y:}".replace('l', s_long), (), Point2), + (Point, "T{<l:x:<l:y:}".replace('l', s_long), (), Point), + (PackedPoint, "T{<l:x:<l:y:}".replace('l', s_long), (), PackedPoint), + (PointMidPad, "T{<b:x:3x<I:y:}".replace('I', s_uint), (), PointMidPad), + (PackedPointMidPad, "T{<b:x:x<Q:y:}", (), PackedPointMidPad), + (PointEndPad, "T{<I:x:<b:y:3x}".replace('I', s_uint), (), PointEndPad), + (PackedPointEndPad, "T{<Q:x:<b:y:x}", (), PackedPointEndPad), + (EmptyStruct, "T{}", (), EmptyStruct), # the pep doesn't support unions (aUnion, "B", (), aUnion), # structure with sub-arrays @@ -226,7 +241,7 @@ class LEPoint(LittleEndianStructure): # endian_types = [ (BEPoint, "T{>l:x:>l:y:}".replace('l', s_long), (), BEPoint), - (LEPoint, "T{<l:x:<l:y:}".replace('l', s_long), (), LEPoint), + (LEPoint * 1, "T{<l:x:<l:y:}".replace('l', s_long), (1,), LEPoint), (POINTER(BEPoint), "&T{>l:x:>l:y:}".replace('l', s_long), (), POINTER(BEPoint)), (POINTER(LEPoint), "&T{<l:x:<l:y:}".replace('l', s_long), (), POINTER(LEPoint)), ] diff --git a/Lib/ctypes/test/test_pickling.py b/Lib/test/test_ctypes/test_pickling.py similarity index 100% rename from Lib/ctypes/test/test_pickling.py rename to Lib/test/test_ctypes/test_pickling.py diff --git a/Lib/ctypes/test/test_pointers.py b/Lib/test/test_ctypes/test_pointers.py similarity index 100% rename from Lib/ctypes/test/test_pointers.py rename to Lib/test/test_ctypes/test_pointers.py diff --git a/Lib/ctypes/test/test_prototypes.py b/Lib/test/test_ctypes/test_prototypes.py similarity index 99% rename from Lib/ctypes/test/test_prototypes.py rename to Lib/test/test_ctypes/test_prototypes.py index cd0c649d..bf275614 100644 --- a/Lib/ctypes/test/test_prototypes.py +++ b/Lib/test/test_ctypes/test_prototypes.py @@ -1,5 +1,5 @@ from ctypes import * -from ctypes.test import need_symbol +from test.test_ctypes import need_symbol import unittest # IMPORTANT INFO: diff --git a/Lib/ctypes/test/test_python_api.py b/Lib/test/test_ctypes/test_python_api.py similarity index 97% rename from Lib/ctypes/test/test_python_api.py rename to Lib/test/test_ctypes/test_python_api.py index 49571f97..de8989e2 100644 --- a/Lib/ctypes/test/test_python_api.py +++ b/Lib/test/test_ctypes/test_python_api.py @@ -46,7 +46,8 @@ class PythonAPITestCase(unittest.TestCase): pythonapi.PyLong_AsLong.restype = c_long res = pythonapi.PyLong_AsLong(42) - self.assertEqual(grc(res), ref42 + 1) + # Small int refcnts don't change + self.assertEqual(grc(res), ref42) del res self.assertEqual(grc(42), ref42) diff --git a/Lib/ctypes/test/test_random_things.py b/Lib/test/test_ctypes/test_random_things.py similarity index 100% rename from Lib/ctypes/test/test_random_things.py rename to Lib/test/test_ctypes/test_random_things.py diff --git a/Lib/ctypes/test/test_refcounts.py b/Lib/test/test_ctypes/test_refcounts.py similarity index 100% rename from Lib/ctypes/test/test_refcounts.py rename to Lib/test/test_ctypes/test_refcounts.py diff --git a/Lib/ctypes/test/test_repr.py b/Lib/test/test_ctypes/test_repr.py similarity index 100% rename from Lib/ctypes/test/test_repr.py rename to Lib/test/test_ctypes/test_repr.py diff --git a/Lib/ctypes/test/test_returnfuncptrs.py b/Lib/test/test_ctypes/test_returnfuncptrs.py similarity index 100% rename from Lib/ctypes/test/test_returnfuncptrs.py rename to Lib/test/test_ctypes/test_returnfuncptrs.py diff --git a/Lib/ctypes/test/test_simplesubclasses.py b/Lib/test/test_ctypes/test_simplesubclasses.py similarity index 100% rename from Lib/ctypes/test/test_simplesubclasses.py rename to Lib/test/test_ctypes/test_simplesubclasses.py diff --git a/Lib/ctypes/test/test_sizes.py b/Lib/test/test_ctypes/test_sizes.py similarity index 90% rename from Lib/ctypes/test/test_sizes.py rename to Lib/test/test_ctypes/test_sizes.py index 4ceacbc2..bf8d6ea3 100644 --- a/Lib/ctypes/test/test_sizes.py +++ b/Lib/test/test_ctypes/test_sizes.py @@ -28,6 +28,9 @@ class SizesTestCase(unittest.TestCase): def test_ssize_t(self): self.assertEqual(sizeof(c_void_p), sizeof(c_ssize_t)) + def test_time_t(self): + self.assertEqual(sizeof(c_time_t), SIZEOF_TIME_T) + if __name__ == "__main__": unittest.main() diff --git a/Lib/ctypes/test/test_slicing.py b/Lib/test/test_ctypes/test_slicing.py similarity index 99% rename from Lib/ctypes/test/test_slicing.py rename to Lib/test/test_ctypes/test_slicing.py index a3932f17..b3e68f9a 100644 --- a/Lib/ctypes/test/test_slicing.py +++ b/Lib/test/test_ctypes/test_slicing.py @@ -1,6 +1,6 @@ import unittest from ctypes import * -from ctypes.test import need_symbol +from test.test_ctypes import need_symbol import _ctypes_test diff --git a/Lib/ctypes/test/test_stringptr.py b/Lib/test/test_ctypes/test_stringptr.py similarity index 100% rename from Lib/ctypes/test/test_stringptr.py rename to Lib/test/test_ctypes/test_stringptr.py diff --git a/Lib/ctypes/test/test_strings.py b/Lib/test/test_ctypes/test_strings.py similarity index 99% rename from Lib/ctypes/test/test_strings.py rename to Lib/test/test_ctypes/test_strings.py index 12e20882..a9003be3 100644 --- a/Lib/ctypes/test/test_strings.py +++ b/Lib/test/test_ctypes/test_strings.py @@ -1,6 +1,6 @@ import unittest from ctypes import * -from ctypes.test import need_symbol +from test.test_ctypes import need_symbol class StringArrayTestCase(unittest.TestCase): def test(self): diff --git a/Lib/ctypes/test/test_struct_fields.py b/Lib/test/test_ctypes/test_struct_fields.py similarity index 100% rename from Lib/ctypes/test/test_struct_fields.py rename to Lib/test/test_ctypes/test_struct_fields.py diff --git a/Lib/ctypes/test/test_structures.py b/Lib/test/test_ctypes/test_structures.py similarity index 98% rename from Lib/ctypes/test/test_structures.py rename to Lib/test/test_ctypes/test_structures.py index f95d5a99..a40ce3e8 100644 --- a/Lib/ctypes/test/test_structures.py +++ b/Lib/test/test_ctypes/test_structures.py @@ -2,7 +2,7 @@ import platform import sys import unittest from ctypes import * -from ctypes.test import need_symbol +from test.test_ctypes import need_symbol from struct import calcsize import _ctypes_test from test import support @@ -359,15 +359,6 @@ class StructureTestCase(unittest.TestCase): except Exception as detail: return detail.__class__, str(detail) - @unittest.skip('test disabled') - def test_subclass_creation(self): - meta = type(Structure) - # same as 'class X(Structure): pass' - # fails, since we need either a _fields_ or a _abstract_ attribute - cls, msg = self.get_except(meta, "X", (Structure,), {}) - self.assertEqual((cls, msg), - (AttributeError, "class must define a '_fields_' attribute")) - def test_abstract_class(self): class X(Structure): _abstract_ = "something" diff --git a/Lib/ctypes/test/test_unaligned_structures.py b/Lib/test/test_ctypes/test_unaligned_structures.py similarity index 100% rename from Lib/ctypes/test/test_unaligned_structures.py rename to Lib/test/test_ctypes/test_unaligned_structures.py diff --git a/Lib/ctypes/test/test_unicode.py b/Lib/test/test_ctypes/test_unicode.py similarity index 97% rename from Lib/ctypes/test/test_unicode.py rename to Lib/test/test_ctypes/test_unicode.py index 60c75424..319cb3b1 100644 --- a/Lib/ctypes/test/test_unicode.py +++ b/Lib/test/test_ctypes/test_unicode.py @@ -1,6 +1,6 @@ import unittest import ctypes -from ctypes.test import need_symbol +from test.test_ctypes import need_symbol import _ctypes_test diff --git a/Lib/ctypes/test/test_values.py b/Lib/test/test_ctypes/test_values.py similarity index 100% rename from Lib/ctypes/test/test_values.py rename to Lib/test/test_ctypes/test_values.py diff --git a/Lib/ctypes/test/test_varsize_struct.py b/Lib/test/test_ctypes/test_varsize_struct.py similarity index 100% rename from Lib/ctypes/test/test_varsize_struct.py rename to Lib/test/test_ctypes/test_varsize_struct.py diff --git a/Lib/ctypes/test/test_win32.py b/Lib/test/test_ctypes/test_win32.py similarity index 100% rename from Lib/ctypes/test/test_win32.py rename to Lib/test/test_ctypes/test_win32.py diff --git a/Lib/ctypes/test/test_wintypes.py b/Lib/test/test_ctypes/test_wintypes.py similarity index 67% rename from Lib/ctypes/test/test_wintypes.py rename to Lib/test/test_ctypes/test_wintypes.py index 243d5962..a01b9b1d 100644 --- a/Lib/ctypes/test/test_wintypes.py +++ b/Lib/test/test_ctypes/test_wintypes.py @@ -1,3 +1,6 @@ +# See <https://learn.microsoft.com/en-us/windows/win32/winprog/windows-data-types> +# for reference. + import unittest # also work on POSIX @@ -38,6 +41,22 @@ class WinTypesTest(unittest.TestCase): vb.value = [] self.assertIs(vb.value, False) + def assertIsSigned(self, ctype): + self.assertLess(ctype(-1).value, 0) + + def assertIsUnsigned(self, ctype): + self.assertGreater(ctype(-1).value, 0) + + def test_signedness(self): + for ctype in (wintypes.BYTE, wintypes.WORD, wintypes.DWORD, + wintypes.BOOLEAN, wintypes.UINT, wintypes.ULONG): + with self.subTest(ctype=ctype): + self.assertIsUnsigned(ctype) + + for ctype in (wintypes.BOOL, wintypes.INT, wintypes.LONG): + with self.subTest(ctype=ctype): + self.assertIsSigned(ctype) + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_curses.py b/Lib/test/test_curses.py index b550f4af..31bc108e 100644 --- a/Lib/test/test_curses.py +++ b/Lib/test/test_curses.py @@ -5,6 +5,7 @@ import string import sys import tempfile import unittest +from unittest.mock import MagicMock from test.support import (requires, verbose, SaveSignals, cpython_only, check_disallow_instantiation) @@ -1319,5 +1320,82 @@ def lorem_ipsum(win): for y, line in enumerate(text[:maxy]): win.addstr(y, 0, line[:maxx - (y == maxy - 1)]) + +class TextboxTest(unittest.TestCase): + def setUp(self): + self.mock_win = MagicMock(spec=curses.window) + self.mock_win.getyx.return_value = (1, 1) + self.mock_win.getmaxyx.return_value = (10, 20) + self.textbox = curses.textpad.Textbox(self.mock_win) + + def test_init(self): + """Test textbox initialization.""" + self.mock_win.reset_mock() + tb = curses.textpad.Textbox(self.mock_win) + self.mock_win.getmaxyx.assert_called_once_with() + self.mock_win.keypad.assert_called_once_with(1) + self.assertEqual(tb.insert_mode, False) + self.assertEqual(tb.stripspaces, 1) + self.assertIsNone(tb.lastcmd) + self.mock_win.reset_mock() + + def test_insert(self): + """Test inserting a printable character.""" + self.mock_win.reset_mock() + self.textbox.do_command(ord('a')) + self.mock_win.addch.assert_called_with(ord('a')) + self.textbox.do_command(ord('b')) + self.mock_win.addch.assert_called_with(ord('b')) + self.textbox.do_command(ord('c')) + self.mock_win.addch.assert_called_with(ord('c')) + self.mock_win.reset_mock() + + def test_delete(self): + """Test deleting a character.""" + self.mock_win.reset_mock() + self.textbox.do_command(curses.ascii.BS) + self.textbox.do_command(curses.KEY_BACKSPACE) + self.textbox.do_command(curses.ascii.DEL) + assert self.mock_win.delch.call_count == 3 + self.mock_win.reset_mock() + + def test_move_left(self): + """Test moving the cursor left.""" + self.mock_win.reset_mock() + self.textbox.do_command(curses.KEY_LEFT) + self.mock_win.move.assert_called_with(1, 0) + self.mock_win.reset_mock() + + def test_move_right(self): + """Test moving the cursor right.""" + self.mock_win.reset_mock() + self.textbox.do_command(curses.KEY_RIGHT) + self.mock_win.move.assert_called_with(1, 2) + self.mock_win.reset_mock() + + def test_move_left_and_right(self): + """Test moving the cursor left and then right.""" + self.mock_win.reset_mock() + self.textbox.do_command(curses.KEY_LEFT) + self.mock_win.move.assert_called_with(1, 0) + self.textbox.do_command(curses.KEY_RIGHT) + self.mock_win.move.assert_called_with(1, 2) + self.mock_win.reset_mock() + + def test_move_up(self): + """Test moving the cursor up.""" + self.mock_win.reset_mock() + self.textbox.do_command(curses.KEY_UP) + self.mock_win.move.assert_called_with(0, 1) + self.mock_win.reset_mock() + + def test_move_down(self): + """Test moving the cursor down.""" + self.mock_win.reset_mock() + self.textbox.do_command(curses.KEY_DOWN) + self.mock_win.move.assert_called_with(2, 1) + self.mock_win.reset_mock() + + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_dataclasses.py b/Lib/test/test_dataclasses.py index 9af43771..6669f1c5 100644 --- a/Lib/test/test_dataclasses.py +++ b/Lib/test/test_dataclasses.py @@ -5,16 +5,18 @@ from dataclasses import * import abc +import io import pickle import inspect import builtins import types import weakref +import traceback import unittest from unittest.mock import Mock -from typing import ClassVar, Any, List, Union, Tuple, Dict, Generic, TypeVar, Optional, Protocol +from typing import ClassVar, Any, List, Union, Tuple, Dict, Generic, TypeVar, Optional, Protocol, DefaultDict from typing import get_type_hints -from collections import deque, OrderedDict, namedtuple +from collections import deque, OrderedDict, namedtuple, defaultdict from functools import total_ordering import typing # Needed for the string "typing.ClassVar[int]" to work as an annotation. @@ -86,6 +88,32 @@ class TestCase(unittest.TestCase): self.assertIn(",type=...,", repr(D.__dataclass_fields__["C"])) + def test_dataclass_params_repr(self): + # Even though this is testing an internal implementation detail, + # it's testing a feature we want to make sure is correctly implemented + # for the sake of dataclasses itself + @dataclass(slots=True, frozen=True) + class Some: pass + + repr_output = repr(Some.__dataclass_params__) + expected_output = "_DataclassParams(init=True,repr=True," \ + "eq=True,order=False,unsafe_hash=False,frozen=True," \ + "match_args=True,kw_only=False," \ + "slots=True,weakref_slot=False)" + self.assertEqual(repr_output, expected_output) + + def test_dataclass_params_signature(self): + # Even though this is testing an internal implementation detail, + # it's testing a feature we want to make sure is correctly implemented + # for the sake of dataclasses itself + @dataclass + class Some: pass + + for param in inspect.signature(dataclass).parameters: + if param == 'cls': + continue + self.assertTrue(hasattr(Some.__dataclass_params__, param), msg=param) + def test_named_init_params(self): @dataclass class C: @@ -257,6 +285,23 @@ class TestCase(unittest.TestCase): c = C(5) self.assertEqual(c.BUILTINS, 5) + def test_field_with_special_single_underscore_names(self): + # gh-98886 + + @dataclass + class X: + x: int = field(default_factory=lambda: 111) + _dflt_x: int = field(default_factory=lambda: 222) + + X() + + @dataclass + class Y: + y: int = field(default_factory=lambda: 111) + _HAS_DEFAULT_FACTORY: int = 222 + + assert Y(y=222).y == 222 + def test_field_named_like_builtin(self): # Attribute names can shadow built-in names # since code generation is used. @@ -712,8 +757,8 @@ class TestCase(unittest.TestCase): class Subclass(typ): pass with self.assertRaisesRegex(ValueError, - f"mutable default .*Subclass'>" - ' for field z is not allowed' + "mutable default .*Subclass'>" + " for field z is not allowed" ): @dataclass class Point: @@ -1500,6 +1545,16 @@ class TestCase(unittest.TestCase): with self.assertRaisesRegex(TypeError, 'dataclass type or instance'): fields(C()) + def test_clean_traceback_from_fields_exception(self): + stdout = io.StringIO() + try: + fields(object) + except TypeError as exc: + traceback.print_exception(exc, file=stdout) + printed_traceback = stdout.getvalue() + self.assertNotIn("AttributeError", printed_traceback) + self.assertNotIn("__dataclass_fields__", printed_traceback) + def test_helper_asdict(self): # Basic tests for asdict(), it should return a new dictionary. @dataclass @@ -1677,6 +1732,21 @@ class TestCase(unittest.TestCase): self.assertIsNot(d['f'], t) self.assertEqual(d['f'].my_a(), 6) + def test_helper_asdict_defaultdict(self): + # Ensure asdict() does not throw exceptions when a + # defaultdict is a member of a dataclass + @dataclass + class C: + mp: DefaultDict[str, List] + + dd = defaultdict(list) + dd["x"].append(12) + c = C(mp=dd) + d = asdict(c) + + self.assertEqual(d, {"mp": {"x": [12]}}) + self.assertTrue(d["mp"] is not c.mp) # make sure defaultdict is copied + def test_helper_astuple(self): # Basic tests for astuple(), it should return a new tuple. @dataclass @@ -1804,6 +1874,21 @@ class TestCase(unittest.TestCase): t = astuple(c, tuple_factory=list) self.assertEqual(t, ['outer', T(1, ['inner', T(11, 12, 13)], 2)]) + def test_helper_astuple_defaultdict(self): + # Ensure astuple() does not throw exceptions when a + # defaultdict is a member of a dataclass + @dataclass + class C: + mp: DefaultDict[str, List] + + dd = defaultdict(list) + dd["x"].append(12) + c = C(mp=dd) + t = astuple(c) + + self.assertEqual(t, ({"x": [12]},)) + self.assertTrue(t[0] is not dd) # make sure defaultdict is copied + def test_dynamic_class_creation(self): cls_dict = {'__annotations__': {'x': int, 'y': int}, } @@ -2212,13 +2297,25 @@ class TestDocString(unittest.TestCase): self.assertDocStrEqual(C.__doc__, "C(x:collections.deque=<factory>)") + def test_docstring_with_no_signature(self): + # See https://github.com/python/cpython/issues/103449 + class Meta(type): + __call__ = dict + class Base(metaclass=Meta): + pass + + @dataclass + class C(Base): + pass + + self.assertDocStrEqual(C.__doc__, "C") + class TestInit(unittest.TestCase): def test_base_has_init(self): class B: def __init__(self): self.z = 100 - pass # Make sure that declaring this class doesn't raise an error. # The issue is that we can't override __init__ in our class, @@ -2725,6 +2822,19 @@ class TestFrozen(unittest.TestCase): c.i = 5 self.assertEqual(c.i, 10) + def test_frozen_empty(self): + @dataclass(frozen=True) + class C: + pass + + c = C() + self.assertFalse(hasattr(c, 'i')) + with self.assertRaises(FrozenInstanceError): + c.i = 5 + self.assertFalse(hasattr(c, 'i')) + with self.assertRaises(FrozenInstanceError): + del c.i + def test_inherit(self): @dataclass(frozen=True) class C: @@ -2848,6 +2958,37 @@ class TestFrozen(unittest.TestCase): self.assertEqual(s.y, 10) self.assertEqual(s.cached, True) + with self.assertRaises(FrozenInstanceError): + del s.x + self.assertEqual(s.x, 3) + with self.assertRaises(FrozenInstanceError): + del s.y + self.assertEqual(s.y, 10) + del s.cached + self.assertFalse(hasattr(s, 'cached')) + with self.assertRaises(AttributeError) as cm: + del s.cached + self.assertNotIsInstance(cm.exception, FrozenInstanceError) + + def test_non_frozen_normal_derived_from_empty_frozen(self): + @dataclass(frozen=True) + class D: + pass + + class S(D): + pass + + s = S() + self.assertFalse(hasattr(s, 'x')) + s.x = 5 + self.assertEqual(s.x, 5) + + del s.x + self.assertFalse(hasattr(s, 'x')) + with self.assertRaises(AttributeError) as cm: + del s.x + self.assertNotIsInstance(cm.exception, FrozenInstanceError) + def test_overwriting_frozen(self): # frozen uses __setattr__ and __delattr__. with self.assertRaisesRegex(TypeError, @@ -3043,6 +3184,74 @@ class TestSlots(unittest.TestCase): self.assertIsNot(obj, p) self.assertEqual(obj, p) + @dataclass(frozen=True, slots=True) + class FrozenSlotsGetStateClass: + foo: str + bar: int + + getstate_called: bool = field(default=False, compare=False) + + def __getstate__(self): + object.__setattr__(self, 'getstate_called', True) + return [self.foo, self.bar] + + @dataclass(frozen=True, slots=True) + class FrozenSlotsSetStateClass: + foo: str + bar: int + + setstate_called: bool = field(default=False, compare=False) + + def __setstate__(self, state): + object.__setattr__(self, 'setstate_called', True) + object.__setattr__(self, 'foo', state[0]) + object.__setattr__(self, 'bar', state[1]) + + @dataclass(frozen=True, slots=True) + class FrozenSlotsAllStateClass: + foo: str + bar: int + + getstate_called: bool = field(default=False, compare=False) + setstate_called: bool = field(default=False, compare=False) + + def __getstate__(self): + object.__setattr__(self, 'getstate_called', True) + return [self.foo, self.bar] + + def __setstate__(self, state): + object.__setattr__(self, 'setstate_called', True) + object.__setattr__(self, 'foo', state[0]) + object.__setattr__(self, 'bar', state[1]) + + def test_frozen_slots_pickle_custom_state(self): + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.subTest(proto=proto): + obj = self.FrozenSlotsGetStateClass('a', 1) + dumped = pickle.dumps(obj, protocol=proto) + + self.assertTrue(obj.getstate_called) + self.assertEqual(obj, pickle.loads(dumped)) + + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.subTest(proto=proto): + obj = self.FrozenSlotsSetStateClass('a', 1) + obj2 = pickle.loads(pickle.dumps(obj, protocol=proto)) + + self.assertTrue(obj2.setstate_called) + self.assertEqual(obj, obj2) + + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.subTest(proto=proto): + obj = self.FrozenSlotsAllStateClass('a', 1) + dumped = pickle.dumps(obj, protocol=proto) + + self.assertTrue(obj.getstate_called) + + obj2 = pickle.loads(dumped) + self.assertTrue(obj2.setstate_called) + self.assertEqual(obj, obj2) + def test_slots_with_default_no_init(self): # Originally reported in bpo-44649. @dataclass(slots=True) @@ -3076,6 +3285,8 @@ class TestSlots(unittest.TestCase): with self.assertRaisesRegex(TypeError, "cannot create weak reference"): weakref.ref(a) + with self.assertRaises(AttributeError): + a.__weakref__ def test_slots_weakref(self): @dataclass(slots=True, weakref_slot=True) @@ -3084,7 +3295,9 @@ class TestSlots(unittest.TestCase): self.assertIn("__weakref__", A.__slots__) a = A(1) - weakref.ref(a) + a_ref = weakref.ref(a) + + self.assertIs(a.__weakref__, a_ref) def test_slots_weakref_base_str(self): class Base: @@ -3150,7 +3363,8 @@ class TestSlots(unittest.TestCase): self.assertIn("__weakref__", Base.__slots__) self.assertNotIn("__weakref__", A.__slots__) a = A(1) - weakref.ref(a) + a_ref = weakref.ref(a) + self.assertIs(a.__weakref__, a_ref) def test_weakref_slot_subclass_no_weakref_slot(self): @dataclass(slots=True, weakref_slot=True) @@ -3166,7 +3380,8 @@ class TestSlots(unittest.TestCase): self.assertIn("__weakref__", Base.__slots__) self.assertNotIn("__weakref__", A.__slots__) a = A(1) - weakref.ref(a) + a_ref = weakref.ref(a) + self.assertIs(a.__weakref__, a_ref) def test_weakref_slot_normal_base_weakref_slot(self): class Base: @@ -3181,7 +3396,8 @@ class TestSlots(unittest.TestCase): self.assertIn("__weakref__", Base.__slots__) self.assertNotIn("__weakref__", A.__slots__) a = A(1) - weakref.ref(a) + a_ref = weakref.ref(a) + self.assertIs(a.__weakref__, a_ref) class TestDescriptors(unittest.TestCase): @@ -3520,6 +3736,15 @@ class TestStringAnnotations(unittest.TestCase): 'return': type(None)}) +ByMakeDataClass = make_dataclass('ByMakeDataClass', [('x', int)]) +ManualModuleMakeDataClass = make_dataclass('ManualModuleMakeDataClass', + [('x', int)], + module=__name__) +WrongNameMakeDataclass = make_dataclass('Wrong', [('x', int)]) +WrongModuleMakeDataclass = make_dataclass('WrongModuleMakeDataclass', + [('x', int)], + module='custom') + class TestMakeDataclass(unittest.TestCase): def test_simple(self): C = make_dataclass('C', @@ -3629,6 +3854,36 @@ class TestMakeDataclass(unittest.TestCase): 'y': int, 'z': 'typing.Any'}) + def test_module_attr(self): + self.assertEqual(ByMakeDataClass.__module__, __name__) + self.assertEqual(ByMakeDataClass(1).__module__, __name__) + self.assertEqual(WrongModuleMakeDataclass.__module__, "custom") + Nested = make_dataclass('Nested', []) + self.assertEqual(Nested.__module__, __name__) + self.assertEqual(Nested().__module__, __name__) + + def test_pickle_support(self): + for klass in [ByMakeDataClass, ManualModuleMakeDataClass]: + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.subTest(proto=proto): + self.assertEqual( + pickle.loads(pickle.dumps(klass, proto)), + klass, + ) + self.assertEqual( + pickle.loads(pickle.dumps(klass(1), proto)), + klass(1), + ) + + def test_cannot_be_pickled(self): + for klass in [WrongNameMakeDataclass, WrongModuleMakeDataclass]: + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.subTest(proto=proto): + with self.assertRaises(pickle.PickleError): + pickle.dumps(klass, proto) + with self.assertRaises(pickle.PickleError): + pickle.dumps(klass(1), proto) + def test_invalid_type_specification(self): for bad_field in [(), (1, 2, 3, 4), @@ -3945,7 +4200,7 @@ class TestAbstract(unittest.TestCase): day: 'int' self.assertTrue(inspect.isabstract(Date)) - msg = 'class Date with abstract method foo' + msg = "class Date without an implementation for abstract method 'foo'" self.assertRaisesRegex(TypeError, msg, Date) diff --git a/Lib/test/test_datetime.py b/Lib/test/test_datetime.py index 7f9094fa..3859733a 100644 --- a/Lib/test/test_datetime.py +++ b/Lib/test/test_datetime.py @@ -8,10 +8,12 @@ TESTS = 'test.datetimetester' def load_tests(loader, tests, pattern): try: - pure_tests = import_fresh_module(TESTS, fresh=['datetime', '_strptime'], - blocked=['_datetime']) - fast_tests = import_fresh_module(TESTS, fresh=['datetime', - '_datetime', '_strptime']) + pure_tests = import_fresh_module(TESTS, + fresh=['datetime', '_pydatetime', '_strptime'], + blocked=['_datetime']) + fast_tests = import_fresh_module(TESTS, + fresh=['datetime', '_strptime'], + blocked=['_pydatetime']) finally: # XXX: import_fresh_module() is supposed to leave sys.module cache untouched, # XXX: but it does not, so we have to cleanup ourselves. @@ -42,6 +44,8 @@ def load_tests(loader, tests, pattern): cls_._save_sys_modules = sys.modules.copy() sys.modules[TESTS] = module sys.modules['datetime'] = module.datetime_module + if hasattr(module, '_pydatetime'): + sys.modules['_pydatetime'] = module._pydatetime sys.modules['_strptime'] = module._strptime @classmethod def tearDownClass(cls_): diff --git a/Lib/test/test_dbm_gnu.py b/Lib/test/test_dbm_gnu.py index 4eaa0f47..73602cab 100644 --- a/Lib/test/test_dbm_gnu.py +++ b/Lib/test/test_dbm_gnu.py @@ -118,6 +118,20 @@ class TestGdbm(unittest.TestCase): self.assertEqual(str(cm.exception), "GDBM object has already been closed") + def test_bool_empty(self): + with gdbm.open(filename, 'c') as db: + self.assertFalse(bool(db)) + + def test_bool_not_empty(self): + with gdbm.open(filename, 'c') as db: + db['a'] = 'b' + self.assertTrue(bool(db)) + + def test_bool_on_closed_db_raises(self): + with gdbm.open(filename, 'c') as db: + db['a'] = 'b' + self.assertRaises(gdbm.error, bool, db) + def test_bytes(self): with gdbm.open(filename, 'c') as db: db[b'bytes key \xbd'] = b'bytes value \xbd' diff --git a/Lib/test/test_dbm_ndbm.py b/Lib/test/test_dbm_ndbm.py index e57d9cab..8f37e3cc 100644 --- a/Lib/test/test_dbm_ndbm.py +++ b/Lib/test/test_dbm_ndbm.py @@ -133,6 +133,20 @@ class DbmTestCase(unittest.TestCase): def test_open_with_pathlib_bytes_path(self): dbm.ndbm.open(os_helper.FakePath(os.fsencode(self.filename)), "c").close() + def test_bool_empty(self): + with dbm.ndbm.open(self.filename, 'c') as db: + self.assertFalse(bool(db)) + + def test_bool_not_empty(self): + with dbm.ndbm.open(self.filename, 'c') as db: + db['a'] = 'b' + self.assertTrue(bool(db)) + + def test_bool_on_closed_db_raises(self): + with dbm.ndbm.open(self.filename, 'c') as db: + db['a'] = 'b' + self.assertRaises(dbm.ndbm.error, bool, db) + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_decimal.py b/Lib/test/test_decimal.py index 67ccaab4..4d3ea732 100644 --- a/Lib/test/test_decimal.py +++ b/Lib/test/test_decimal.py @@ -20,7 +20,7 @@ Cowlishaw's tests can be downloaded from: This test module can be called from command line with one parameter (Arithmetic or Behaviour) to test each part, or without parameter to test both parts. If -you're working through IDLE, you can import this test module and call test_main() +you're working through IDLE, you can import this test module and call test() with the corresponding argument. """ @@ -32,7 +32,7 @@ import pickle, copy import unittest import numbers import locale -from test.support import (run_unittest, run_doctest, is_resource_enabled, +from test.support import (is_resource_enabled, requires_IEEE_754, requires_docstrings, requires_legacy_unicode_capi, check_sanitizer) from test.support import (TestFailed, @@ -62,6 +62,7 @@ sys.modules['decimal'] = C fractions = {C:cfractions, P:pfractions} sys.modules['decimal'] = orig_sys_decimal +requires_cdecimal = unittest.skipUnless(C, "test requires C version") # Useful Test Constant Signals = { @@ -99,7 +100,7 @@ RoundingModes = [ ] # Tests are built around these assumed context defaults. -# test_main() restores the original context. +# test() restores the original context. ORIGINAL_CONTEXT = { C: C.getcontext().copy() if C else None, P: P.getcontext().copy() @@ -133,7 +134,7 @@ skip_if_extra_functionality = unittest.skipIf( EXTRA_FUNCTIONALITY, "test requires regular build") -class IBMTestCases(unittest.TestCase): +class IBMTestCases: """Class which tests the Decimal class against the IBM test cases.""" def setUp(self): @@ -488,14 +489,10 @@ class IBMTestCases(unittest.TestCase): def change_clamp(self, clamp): self.context.clamp = clamp -class CIBMTestCases(IBMTestCases): - decimal = C -class PyIBMTestCases(IBMTestCases): - decimal = P # The following classes test the behaviour of Decimal according to PEP 327 -class ExplicitConstructionTest(unittest.TestCase): +class ExplicitConstructionTest: '''Unit tests for Explicit Construction cases of Decimal.''' def test_explicit_empty(self): @@ -590,7 +587,7 @@ class ExplicitConstructionTest(unittest.TestCase): self.assertRaises(InvalidOperation, Decimal, "1_2_\u00003") @cpython_only - @requires_legacy_unicode_capi + @requires_legacy_unicode_capi() @warnings_helper.ignore_warnings(category=DeprecationWarning) def test_from_legacy_strings(self): import _testcapi @@ -838,12 +835,13 @@ class ExplicitConstructionTest(unittest.TestCase): for input, expected in test_values.items(): self.assertEqual(str(Decimal(input)), expected) -class CExplicitConstructionTest(ExplicitConstructionTest): +@requires_cdecimal +class CExplicitConstructionTest(ExplicitConstructionTest, unittest.TestCase): decimal = C -class PyExplicitConstructionTest(ExplicitConstructionTest): +class PyExplicitConstructionTest(ExplicitConstructionTest, unittest.TestCase): decimal = P -class ImplicitConstructionTest(unittest.TestCase): +class ImplicitConstructionTest: '''Unit tests for Implicit Construction cases of Decimal.''' def test_implicit_from_None(self): @@ -920,12 +918,13 @@ class ImplicitConstructionTest(unittest.TestCase): self.assertEqual(eval('Decimal(10)' + sym + 'E()'), '10' + rop + 'str') -class CImplicitConstructionTest(ImplicitConstructionTest): +@requires_cdecimal +class CImplicitConstructionTest(ImplicitConstructionTest, unittest.TestCase): decimal = C -class PyImplicitConstructionTest(ImplicitConstructionTest): +class PyImplicitConstructionTest(ImplicitConstructionTest, unittest.TestCase): decimal = P -class FormatTest(unittest.TestCase): +class FormatTest: '''Unit tests for the format function.''' def test_formatting(self): Decimal = self.decimal.Decimal @@ -1262,12 +1261,13 @@ class FormatTest(unittest.TestCase): a = A.from_float(42) self.assertEqual(self.decimal.Decimal, a.a_type) -class CFormatTest(FormatTest): +@requires_cdecimal +class CFormatTest(FormatTest, unittest.TestCase): decimal = C -class PyFormatTest(FormatTest): +class PyFormatTest(FormatTest, unittest.TestCase): decimal = P -class ArithmeticOperatorsTest(unittest.TestCase): +class ArithmeticOperatorsTest: '''Unit tests for all arithmetic operators, binary and unary.''' def test_addition(self): @@ -1523,14 +1523,17 @@ class ArithmeticOperatorsTest(unittest.TestCase): equality_ops = operator.eq, operator.ne # results when InvalidOperation is not trapped - for x, y in qnan_pairs + snan_pairs: - for op in order_ops + equality_ops: - got = op(x, y) - expected = True if op is operator.ne else False - self.assertIs(expected, got, - "expected {0!r} for operator.{1}({2!r}, {3!r}); " - "got {4!r}".format( - expected, op.__name__, x, y, got)) + with localcontext() as ctx: + ctx.traps[InvalidOperation] = 0 + + for x, y in qnan_pairs + snan_pairs: + for op in order_ops + equality_ops: + got = op(x, y) + expected = True if op is operator.ne else False + self.assertIs(expected, got, + "expected {0!r} for operator.{1}({2!r}, {3!r}); " + "got {4!r}".format( + expected, op.__name__, x, y, got)) # repeat the above, but this time trap the InvalidOperation with localcontext() as ctx: @@ -1562,9 +1565,10 @@ class ArithmeticOperatorsTest(unittest.TestCase): self.assertEqual(Decimal(1).copy_sign(-2), d) self.assertRaises(TypeError, Decimal(1).copy_sign, '-2') -class CArithmeticOperatorsTest(ArithmeticOperatorsTest): +@requires_cdecimal +class CArithmeticOperatorsTest(ArithmeticOperatorsTest, unittest.TestCase): decimal = C -class PyArithmeticOperatorsTest(ArithmeticOperatorsTest): +class PyArithmeticOperatorsTest(ArithmeticOperatorsTest, unittest.TestCase): decimal = P # The following are two functions used to test threading in the next class @@ -1654,7 +1658,7 @@ def thfunc2(cls): @threading_helper.requires_working_threading() -class ThreadingTest(unittest.TestCase): +class ThreadingTest: '''Unit tests for thread local contexts in Decimal.''' # Take care executing this test from IDLE, there's an issue in threading @@ -1699,13 +1703,14 @@ class ThreadingTest(unittest.TestCase): DefaultContext.Emin = save_emin -class CThreadingTest(ThreadingTest): +@requires_cdecimal +class CThreadingTest(ThreadingTest, unittest.TestCase): decimal = C -class PyThreadingTest(ThreadingTest): +class PyThreadingTest(ThreadingTest, unittest.TestCase): decimal = P -class UsabilityTest(unittest.TestCase): +class UsabilityTest: '''Unit tests for Usability cases of Decimal.''' def test_comparison_operators(self): @@ -2521,9 +2526,10 @@ class UsabilityTest(unittest.TestCase): self.assertEqual(Decimal(-12).fma(45, Decimal(67)), Decimal(-12).fma(Decimal(45), Decimal(67))) -class CUsabilityTest(UsabilityTest): +@requires_cdecimal +class CUsabilityTest(UsabilityTest, unittest.TestCase): decimal = C -class PyUsabilityTest(UsabilityTest): +class PyUsabilityTest(UsabilityTest, unittest.TestCase): decimal = P def setUp(self): @@ -2535,7 +2541,7 @@ class PyUsabilityTest(UsabilityTest): sys.set_int_max_str_digits(self._previous_int_limit) super().tearDown() -class PythonAPItests(unittest.TestCase): +class PythonAPItests: def test_abc(self): Decimal = self.decimal.Decimal @@ -2884,12 +2890,13 @@ class PythonAPItests(unittest.TestCase): self.assertTrue(issubclass(decimal.DivisionUndefined, ZeroDivisionError)) self.assertTrue(issubclass(decimal.InvalidContext, InvalidOperation)) -class CPythonAPItests(PythonAPItests): +@requires_cdecimal +class CPythonAPItests(PythonAPItests, unittest.TestCase): decimal = C -class PyPythonAPItests(PythonAPItests): +class PyPythonAPItests(PythonAPItests, unittest.TestCase): decimal = P -class ContextAPItests(unittest.TestCase): +class ContextAPItests: def test_none_args(self): Context = self.decimal.Context @@ -2912,7 +2919,7 @@ class ContextAPItests(unittest.TestCase): Overflow]) @cpython_only - @requires_legacy_unicode_capi + @requires_legacy_unicode_capi() @warnings_helper.ignore_warnings(category=DeprecationWarning) def test_from_legacy_strings(self): import _testcapi @@ -3635,12 +3642,13 @@ class ContextAPItests(unittest.TestCase): self.assertRaises(TypeError, c.to_integral_value, '10') self.assertRaises(TypeError, c.to_integral_value, 10, 'x') -class CContextAPItests(ContextAPItests): +@requires_cdecimal +class CContextAPItests(ContextAPItests, unittest.TestCase): decimal = C -class PyContextAPItests(ContextAPItests): +class PyContextAPItests(ContextAPItests, unittest.TestCase): decimal = P -class ContextWithStatement(unittest.TestCase): +class ContextWithStatement: # Can't do these as docstrings until Python 2.6 # as doctest can't handle __future__ statements @@ -3704,9 +3712,13 @@ class ContextWithStatement(unittest.TestCase): def test_local_context_kwargs_does_not_overwrite_existing_argument(self): ctx = self.decimal.getcontext() - ctx.prec = 28 + orig_prec = ctx.prec with self.decimal.localcontext(prec=10) as ctx2: - self.assertEqual(ctx.prec, 28) + self.assertEqual(ctx2.prec, 10) + self.assertEqual(ctx.prec, orig_prec) + with self.decimal.localcontext(prec=20) as ctx2: + self.assertEqual(ctx2.prec, 20) + self.assertEqual(ctx.prec, orig_prec) def test_nested_with_statements(self): # Use a copy of the supplied context in the block @@ -3800,12 +3812,13 @@ class ContextWithStatement(unittest.TestCase): self.assertEqual(c4.prec, 4) del c4 -class CContextWithStatement(ContextWithStatement): +@requires_cdecimal +class CContextWithStatement(ContextWithStatement, unittest.TestCase): decimal = C -class PyContextWithStatement(ContextWithStatement): +class PyContextWithStatement(ContextWithStatement, unittest.TestCase): decimal = P -class ContextFlags(unittest.TestCase): +class ContextFlags: def test_flags_irrelevant(self): # check that the result (numeric result + flags raised) of an @@ -4072,12 +4085,13 @@ class ContextFlags(unittest.TestCase): self.assertTrue(context.traps[FloatOperation]) self.assertTrue(context.traps[Inexact]) -class CContextFlags(ContextFlags): +@requires_cdecimal +class CContextFlags(ContextFlags, unittest.TestCase): decimal = C -class PyContextFlags(ContextFlags): +class PyContextFlags(ContextFlags, unittest.TestCase): decimal = P -class SpecialContexts(unittest.TestCase): +class SpecialContexts: """Test the context templates.""" def test_context_templates(self): @@ -4157,12 +4171,13 @@ class SpecialContexts(unittest.TestCase): if ex: raise ex -class CSpecialContexts(SpecialContexts): +@requires_cdecimal +class CSpecialContexts(SpecialContexts, unittest.TestCase): decimal = C -class PySpecialContexts(SpecialContexts): +class PySpecialContexts(SpecialContexts, unittest.TestCase): decimal = P -class ContextInputValidation(unittest.TestCase): +class ContextInputValidation: def test_invalid_context(self): Context = self.decimal.Context @@ -4224,12 +4239,13 @@ class ContextInputValidation(unittest.TestCase): self.assertRaises(TypeError, Context, flags=(0,1)) self.assertRaises(TypeError, Context, traps=(1,0)) -class CContextInputValidation(ContextInputValidation): +@requires_cdecimal +class CContextInputValidation(ContextInputValidation, unittest.TestCase): decimal = C -class PyContextInputValidation(ContextInputValidation): +class PyContextInputValidation(ContextInputValidation, unittest.TestCase): decimal = P -class ContextSubclassing(unittest.TestCase): +class ContextSubclassing: def test_context_subclassing(self): decimal = self.decimal @@ -4338,12 +4354,14 @@ class ContextSubclassing(unittest.TestCase): for signal in OrderedSignals[decimal]: self.assertFalse(c.traps[signal]) -class CContextSubclassing(ContextSubclassing): +@requires_cdecimal +class CContextSubclassing(ContextSubclassing, unittest.TestCase): decimal = C -class PyContextSubclassing(ContextSubclassing): +class PyContextSubclassing(ContextSubclassing, unittest.TestCase): decimal = P @skip_if_extra_functionality +@requires_cdecimal class CheckAttributes(unittest.TestCase): def test_module_attributes(self): @@ -4373,7 +4391,7 @@ class CheckAttributes(unittest.TestCase): y = [s for s in dir(C.Decimal(9)) if '__' in s or not s.startswith('_')] self.assertEqual(set(x) - set(y), set()) -class Coverage(unittest.TestCase): +class Coverage: def test_adjusted(self): Decimal = self.decimal.Decimal @@ -4630,9 +4648,10 @@ class Coverage(unittest.TestCase): y = c.copy_sign(x, 1) self.assertEqual(y, -x) -class CCoverage(Coverage): +@requires_cdecimal +class CCoverage(Coverage, unittest.TestCase): decimal = C -class PyCoverage(Coverage): +class PyCoverage(Coverage, unittest.TestCase): decimal = P def setUp(self): @@ -4885,6 +4904,7 @@ class CFunctionality(unittest.TestCase): self.assertEqual(C.DecTraps, C.DecErrors|C.DecOverflow|C.DecUnderflow) +@requires_cdecimal class CWhitebox(unittest.TestCase): """Whitebox testing for _decimal""" @@ -5662,8 +5682,38 @@ class CWhitebox(unittest.TestCase): self.assertEqual(Decimal(400) ** -1, Decimal('0.0025')) + def test_c_signaldict_segfault(self): + # See gh-106263 for details. + SignalDict = type(C.Context().flags) + sd = SignalDict() + err_msg = "invalid signal dict" + + with self.assertRaisesRegex(ValueError, err_msg): + len(sd) + + with self.assertRaisesRegex(ValueError, err_msg): + iter(sd) + + with self.assertRaisesRegex(ValueError, err_msg): + repr(sd) + + with self.assertRaisesRegex(ValueError, err_msg): + sd[C.InvalidOperation] = True + + with self.assertRaisesRegex(ValueError, err_msg): + sd[C.InvalidOperation] + + with self.assertRaisesRegex(ValueError, err_msg): + sd == C.Context().flags + + with self.assertRaisesRegex(ValueError, err_msg): + C.Context().flags == sd + + with self.assertRaisesRegex(ValueError, err_msg): + sd.copy() + @requires_docstrings -@unittest.skipUnless(C, "test requires C version") +@requires_cdecimal class SignatureTest(unittest.TestCase): """Function signatures""" @@ -5799,52 +5849,10 @@ class SignatureTest(unittest.TestCase): doit('Context') -all_tests = [ - CExplicitConstructionTest, PyExplicitConstructionTest, - CImplicitConstructionTest, PyImplicitConstructionTest, - CFormatTest, PyFormatTest, - CArithmeticOperatorsTest, PyArithmeticOperatorsTest, - CThreadingTest, PyThreadingTest, - CUsabilityTest, PyUsabilityTest, - CPythonAPItests, PyPythonAPItests, - CContextAPItests, PyContextAPItests, - CContextWithStatement, PyContextWithStatement, - CContextFlags, PyContextFlags, - CSpecialContexts, PySpecialContexts, - CContextInputValidation, PyContextInputValidation, - CContextSubclassing, PyContextSubclassing, - CCoverage, PyCoverage, - CFunctionality, PyFunctionality, - CWhitebox, PyWhitebox, - CIBMTestCases, PyIBMTestCases, -] - -# Delete C tests if _decimal.so is not present. -if not C: - all_tests = all_tests[1::2] -else: - all_tests.insert(0, CheckAttributes) - all_tests.insert(1, SignatureTest) - - -def test_main(arith=None, verbose=None, todo_tests=None, debug=None): - """ Execute the tests. - - Runs all arithmetic tests if arith is True or if the "decimal" resource - is enabled in regrtest.py - """ - - init(C) - init(P) - global TEST_ALL, DEBUG - TEST_ALL = arith if arith is not None else is_resource_enabled('decimal') - DEBUG = debug - - if todo_tests is None: - test_classes = all_tests - else: - test_classes = [CIBMTestCases, PyIBMTestCases] - +def load_tests(loader, tests, pattern): + if TODO_TESTS is not None: + # Run only Arithmetic tests + tests = loader.suiteClass() # Dynamically build custom test definition for each file in the test # directory and add the definitions to the DecimalTest class. This # procedure insures that new files do not get skipped. @@ -5852,34 +5860,69 @@ def test_main(arith=None, verbose=None, todo_tests=None, debug=None): if '.decTest' not in filename or filename.startswith("."): continue head, tail = filename.split('.') - if todo_tests is not None and head not in todo_tests: + if TODO_TESTS is not None and head not in TODO_TESTS: continue tester = lambda self, f=filename: self.eval_file(directory + f) - setattr(CIBMTestCases, 'test_' + head, tester) - setattr(PyIBMTestCases, 'test_' + head, tester) + setattr(IBMTestCases, 'test_' + head, tester) del filename, head, tail, tester + for prefix, mod in ('C', C), ('Py', P): + if not mod: + continue + test_class = type(prefix + 'IBMTestCases', + (IBMTestCases, unittest.TestCase), + {'decimal': mod}) + tests.addTest(loader.loadTestsFromTestCase(test_class)) + + if TODO_TESTS is None: + from doctest import DocTestSuite, IGNORE_EXCEPTION_DETAIL + for mod in C, P: + if not mod: + continue + def setUp(slf, mod=mod): + sys.modules['decimal'] = mod + def tearDown(slf): + sys.modules['decimal'] = orig_sys_decimal + optionflags = IGNORE_EXCEPTION_DETAIL if mod is C else 0 + sys.modules['decimal'] = mod + tests.addTest(DocTestSuite(mod, setUp=setUp, tearDown=tearDown, + optionflags=optionflags)) + sys.modules['decimal'] = orig_sys_decimal + return tests + +def setUpModule(): + init(C) + init(P) + global TEST_ALL + TEST_ALL = ARITH if ARITH is not None else is_resource_enabled('decimal') + +def tearDownModule(): + if C: C.setcontext(ORIGINAL_CONTEXT[C]) + P.setcontext(ORIGINAL_CONTEXT[P]) + if not C: + warnings.warn('C tests skipped: no module named _decimal.', + UserWarning) + if not orig_sys_decimal is sys.modules['decimal']: + raise TestFailed("Internal error: unbalanced number of changes to " + "sys.modules['decimal'].") + + +ARITH = None +TEST_ALL = True +TODO_TESTS = None +DEBUG = False + +def test(arith=None, verbose=None, todo_tests=None, debug=None): + """ Execute the tests. + Runs all arithmetic tests if arith is True or if the "decimal" resource + is enabled in regrtest.py + """ - try: - run_unittest(*test_classes) - if todo_tests is None: - from doctest import IGNORE_EXCEPTION_DETAIL - savedecimal = sys.modules['decimal'] - if C: - sys.modules['decimal'] = C - run_doctest(C, verbose, optionflags=IGNORE_EXCEPTION_DETAIL) - sys.modules['decimal'] = P - run_doctest(P, verbose) - sys.modules['decimal'] = savedecimal - finally: - if C: C.setcontext(ORIGINAL_CONTEXT[C]) - P.setcontext(ORIGINAL_CONTEXT[P]) - if not C: - warnings.warn('C tests skipped: no module named _decimal.', - UserWarning) - if not orig_sys_decimal is sys.modules['decimal']: - raise TestFailed("Internal error: unbalanced number of changes to " - "sys.modules['decimal'].") + global ARITH, TODO_TESTS, DEBUG + ARITH = arith + TODO_TESTS = todo_tests + DEBUG = debug + unittest.main(__name__, verbosity=2 if verbose else 1, exit=False, argv=[__name__]) if __name__ == '__main__': @@ -5890,8 +5933,8 @@ if __name__ == '__main__': (opt, args) = p.parse_args() if opt.skip: - test_main(arith=False, verbose=True) + test(arith=False, verbose=True) elif args: - test_main(arith=True, verbose=True, todo_tests=args, debug=opt.debug) + test(arith=True, verbose=True, todo_tests=args, debug=opt.debug) else: - test_main(arith=True, verbose=True) + test(arith=True, verbose=True) diff --git a/Lib/test/test_decorators.py b/Lib/test/test_decorators.py index a6baa3ad..4b492178 100644 --- a/Lib/test/test_decorators.py +++ b/Lib/test/test_decorators.py @@ -1,4 +1,3 @@ -from test import support import unittest from types import MethodType diff --git a/Lib/test/test_defaultdict.py b/Lib/test/test_defaultdict.py index 68fc4497..bdbe9b81 100644 --- a/Lib/test/test_defaultdict.py +++ b/Lib/test/test_defaultdict.py @@ -1,9 +1,7 @@ """Unit tests for collections.defaultdict.""" -import os import copy import pickle -import tempfile import unittest from collections import defaultdict diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py index 3145dff8..9d8b1497 100644 --- a/Lib/test/test_descr.py +++ b/Lib/test/test_descr.py @@ -21,6 +21,11 @@ try: except ImportError: _testcapi = None +try: + import xxsubtype +except ImportError: + xxsubtype = None + class OperatorsTest(unittest.TestCase): @@ -299,6 +304,7 @@ class OperatorsTest(unittest.TestCase): self.assertEqual(float.__rsub__(3.0, 1), -2.0) @support.impl_detail("the module 'xxsubtype' is internal") + @unittest.skipIf(xxsubtype is None, "requires xxsubtype module") def test_spam_lists(self): # Testing spamlist operations... import copy, xxsubtype as spam @@ -343,6 +349,7 @@ class OperatorsTest(unittest.TestCase): self.assertEqual(a.getstate(), 42) @support.impl_detail("the module 'xxsubtype' is internal") + @unittest.skipIf(xxsubtype is None, "requires xxsubtype module") def test_spam_dicts(self): # Testing spamdict operations... import copy, xxsubtype as spam @@ -426,7 +433,7 @@ class ClassPropertiesAndMethods(unittest.TestCase): def __getitem__(self, key): return self.get(key, 0) def __setitem__(self_local, key, value): - self.assertIsInstance(key, type(0)) + self.assertIsInstance(key, int) dict.__setitem__(self_local, key, value) def setstate(self, state): self.state = state @@ -838,7 +845,7 @@ class ClassPropertiesAndMethods(unittest.TestCase): ("getattr", "foo"), ("delattr", "foo")]) - # http://python.org/sf/1174712 + # https://bugs.python.org/issue1174712 try: class Module(types.ModuleType, str): pass @@ -871,7 +878,7 @@ class ClassPropertiesAndMethods(unittest.TestCase): self.assertEqual(a.getstate(), 10) class D(dict, C): def __init__(self): - type({}).__init__(self) + dict.__init__(self) C.__init__(self) d = D() self.assertEqual(list(d.keys()), []) @@ -1609,6 +1616,7 @@ order (MRO) for bases """ self.assertAlmostEqual(gettotalrefcount() - refs_before, 0, delta=10) @support.impl_detail("the module 'xxsubtype' is internal") + @unittest.skipIf(xxsubtype is None, "requires xxsubtype module") def test_classmethods_in_c(self): # Testing C-based class methods... import xxsubtype as spam @@ -1692,6 +1700,7 @@ order (MRO) for bases """ self.assertAlmostEqual(gettotalrefcount() - refs_before, 0, delta=10) @support.impl_detail("the module 'xxsubtype' is internal") + @unittest.skipIf(xxsubtype is None, "requires xxsubtype module") def test_staticmethods_in_c(self): # Testing C-based static methods... import xxsubtype as spam @@ -3252,12 +3261,8 @@ order (MRO) for bases """ if otype: otype = otype.__name__ return 'object=%s; type=%s' % (object, otype) - class OldClass: - __doc__ = DocDescr() - class NewClass(object): + class NewClass: __doc__ = DocDescr() - self.assertEqual(OldClass.__doc__, 'object=None; type=OldClass') - self.assertEqual(OldClass().__doc__, 'object=OldClass instance; type=OldClass') self.assertEqual(NewClass.__doc__, 'object=None; type=NewClass') self.assertEqual(NewClass().__doc__, 'object=NewClass instance; type=NewClass') @@ -3297,7 +3302,7 @@ order (MRO) for bases """ cant(True, int) cant(2, bool) o = object() - cant(o, type(1)) + cant(o, int) cant(o, type(None)) del o class G(object): @@ -3572,7 +3577,6 @@ order (MRO) for bases """ def test_str_of_str_subclass(self): # Testing __str__ defined in subclass of str ... import binascii - import io class octetstring(str): def __str__(self): @@ -4453,6 +4457,7 @@ order (MRO) for bases """ o.whatever = Provoker(o) del o + @support.requires_resource('cpu') def test_wrapper_segfault(self): # SF 927248: deeply nested wrappers could cause stack overflow f = lambda:None @@ -4999,6 +5004,32 @@ order (MRO) for bases """ gc.collect() self.assertEqual(Parent.__subclasses__(), []) + def test_attr_raise_through_property(self): + # test case for gh-103272 + class A: + def __getattr__(self, name): + raise ValueError("FOO") + + @property + def foo(self): + return self.__getattr__("asdf") + + with self.assertRaisesRegex(ValueError, "FOO"): + A().foo + + # test case for gh-103551 + class B: + @property + def __getattr__(self, name): + raise ValueError("FOO") + + @property + def foo(self): + raise NotImplementedError("BAR") + + with self.assertRaisesRegex(NotImplementedError, "BAR"): + B().foo + class DictProxyTests(unittest.TestCase): def setUp(self): diff --git a/Lib/test/test_descrtut.py b/Lib/test/test_descrtut.py index 9aefda3d..7796031e 100644 --- a/Lib/test/test_descrtut.py +++ b/Lib/test/test_descrtut.py @@ -9,7 +9,6 @@ # deterministic. from test.support import sortdict -import pprint import doctest import unittest @@ -167,6 +166,7 @@ For instance of built-in types, x.__class__ is now the same as type(x): You can get the information from the list type: + >>> import pprint >>> pprint.pprint(dir(list)) # like list.__dict__.keys(), but sorted ['__add__', '__class__', diff --git a/Lib/test/test_dict.py b/Lib/test/test_dict.py index 5b8baaf9..fbc6ce82 100644 --- a/Lib/test/test_dict.py +++ b/Lib/test/test_dict.py @@ -8,7 +8,7 @@ import sys import unittest import weakref from test import support -from test.support import import_helper +from test.support import import_helper, C_RECURSION_LIMIT class DictTest(unittest.TestCase): @@ -596,7 +596,7 @@ class DictTest(unittest.TestCase): def test_repr_deep(self): d = {} - for i in range(sys.getrecursionlimit() + 100): + for i in range(C_RECURSION_LIMIT + 1): d = {1: d} self.assertRaises(RecursionError, repr, d) @@ -1094,6 +1094,21 @@ class DictTest(unittest.TestCase): d.update(o.__dict__) self.assertEqual(list(d), ["c", "b", "a"]) + @support.cpython_only + def test_splittable_to_generic_combinedtable(self): + """split table must be correctly resized and converted to generic combined table""" + class C: + pass + + a = C() + a.x = 1 + d = a.__dict__ + before_resize = sys.getsizeof(d) + d[2] = 2 # split table is resized to a generic combined table + + self.assertGreater(sys.getsizeof(d), before_resize) + self.assertEqual(list(d), ['x', 2]) + def test_iterator_pickling(self): for proto in range(pickle.HIGHEST_PROTOCOL + 1): data = {1:"a", 2:"b", 3:"c"} diff --git a/Lib/test/test_dictviews.py b/Lib/test/test_dictviews.py index dae93740..2bd9d6ee 100644 --- a/Lib/test/test_dictviews.py +++ b/Lib/test/test_dictviews.py @@ -3,6 +3,7 @@ import copy import pickle import sys import unittest +from test.support import C_RECURSION_LIMIT class DictSetTest(unittest.TestCase): @@ -170,6 +171,10 @@ class DictSetTest(unittest.TestCase): {('a', 1), ('b', 2)}) self.assertEqual(d1.items() & set(d2.items()), {('b', 2)}) self.assertEqual(d1.items() & set(d3.items()), set()) + self.assertEqual(d1.items() & (("a", 1), ("b", 2)), + {('a', 1), ('b', 2)}) + self.assertEqual(d1.items() & (("a", 2), ("b", 2)), {('b', 2)}) + self.assertEqual(d1.items() & (("d", 4), ("e", 5)), set()) self.assertEqual(d1.items() | d1.items(), {('a', 1), ('b', 2)}) @@ -183,12 +188,23 @@ class DictSetTest(unittest.TestCase): {('a', 1), ('a', 2), ('b', 2)}) self.assertEqual(d1.items() | set(d3.items()), {('a', 1), ('b', 2), ('d', 4), ('e', 5)}) + self.assertEqual(d1.items() | (('a', 1), ('b', 2)), + {('a', 1), ('b', 2)}) + self.assertEqual(d1.items() | (('a', 2), ('b', 2)), + {('a', 1), ('a', 2), ('b', 2)}) + self.assertEqual(d1.items() | (('d', 4), ('e', 5)), + {('a', 1), ('b', 2), ('d', 4), ('e', 5)}) self.assertEqual(d1.items() ^ d1.items(), set()) self.assertEqual(d1.items() ^ d2.items(), {('a', 1), ('a', 2)}) self.assertEqual(d1.items() ^ d3.items(), {('a', 1), ('b', 2), ('d', 4), ('e', 5)}) + self.assertEqual(d1.items() ^ (('a', 1), ('b', 2)), set()) + self.assertEqual(d1.items() ^ (("a", 2), ("b", 2)), + {('a', 1), ('a', 2)}) + self.assertEqual(d1.items() ^ (("d", 4), ("e", 5)), + {('a', 1), ('b', 2), ('d', 4), ('e', 5)}) self.assertEqual(d1.items() - d1.items(), set()) self.assertEqual(d1.items() - d2.items(), {('a', 1)}) @@ -196,6 +212,9 @@ class DictSetTest(unittest.TestCase): self.assertEqual(d1.items() - set(d1.items()), set()) self.assertEqual(d1.items() - set(d2.items()), {('a', 1)}) self.assertEqual(d1.items() - set(d3.items()), {('a', 1), ('b', 2)}) + self.assertEqual(d1.items() - (('a', 1), ('b', 2)), set()) + self.assertEqual(d1.items() - (("a", 2), ("b", 2)), {('a', 1)}) + self.assertEqual(d1.items() - (("d", 4), ("e", 5)), {('a', 1), ('b', 2)}) self.assertFalse(d1.items().isdisjoint(d1.items())) self.assertFalse(d1.items().isdisjoint(d2.items())) @@ -261,7 +280,7 @@ class DictSetTest(unittest.TestCase): def test_deeply_nested_repr(self): d = {} - for i in range(sys.getrecursionlimit() + 100): + for i in range(C_RECURSION_LIMIT//2 + 100): d = {42: d.values()} self.assertRaises(RecursionError, repr, d) diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py index 6a0a2d92..c90702a4 100644 --- a/Lib/test/test_dis.py +++ b/Lib/test/test_dis.py @@ -7,7 +7,8 @@ import re import sys import types import unittest -from test.support import captured_stdout, requires_debug_ranges, cpython_only +from test.support import (captured_stdout, requires_debug_ranges, + requires_specialization, cpython_only) from test.support.bytecode_helper import BytecodeTestCase import opcode @@ -45,22 +46,20 @@ dis_c_instance_method = """\ %3d LOAD_FAST 1 (x) LOAD_CONST 1 (1) - COMPARE_OP 2 (==) + COMPARE_OP 40 (==) LOAD_FAST 0 (self) STORE_ATTR 0 (x) - LOAD_CONST 0 (None) - RETURN_VALUE + RETURN_CONST 0 (None) """ % (_C.__init__.__code__.co_firstlineno, _C.__init__.__code__.co_firstlineno + 1,) dis_c_instance_method_bytes = """\ RESUME 0 LOAD_FAST 1 LOAD_CONST 1 - COMPARE_OP 2 (==) + COMPARE_OP 40 (==) LOAD_FAST 0 STORE_ATTR 0 - LOAD_CONST 0 - RETURN_VALUE + RETURN_CONST 0 """ dis_c_class_method = """\ @@ -68,11 +67,10 @@ dis_c_class_method = """\ %3d LOAD_FAST 1 (x) LOAD_CONST 1 (1) - COMPARE_OP 2 (==) + COMPARE_OP 40 (==) LOAD_FAST 0 (cls) STORE_ATTR 0 (x) - LOAD_CONST 0 (None) - RETURN_VALUE + RETURN_CONST 0 (None) """ % (_C.cm.__code__.co_firstlineno, _C.cm.__code__.co_firstlineno + 2,) dis_c_static_method = """\ @@ -80,10 +78,9 @@ dis_c_static_method = """\ %3d LOAD_FAST 0 (x) LOAD_CONST 1 (1) - COMPARE_OP 2 (==) + COMPARE_OP 40 (==) STORE_FAST 0 (x) - LOAD_CONST 0 (None) - RETURN_VALUE + RETURN_CONST 0 (None) """ % (_C.sm.__code__.co_firstlineno, _C.sm.__code__.co_firstlineno + 2,) # Class disassembling info has an extra newline at end. @@ -107,12 +104,10 @@ dis_f = """\ %3d LOAD_GLOBAL 1 (NULL + print) LOAD_FAST 0 (a) - PRECALL 1 CALL 1 POP_TOP -%3d LOAD_CONST 1 (1) - RETURN_VALUE +%3d RETURN_CONST 1 (1) """ % (_f.__code__.co_firstlineno, _f.__code__.co_firstlineno + 1, _f.__code__.co_firstlineno + 2) @@ -122,11 +117,9 @@ dis_f_co_code = """\ RESUME 0 LOAD_GLOBAL 1 LOAD_FAST 0 - PRECALL 1 CALL 1 POP_TOP - LOAD_CONST 1 - RETURN_VALUE + RETURN_CONST 1 """ @@ -143,16 +136,15 @@ dis_bug708901 = """\ %3d LOAD_CONST 2 (10) -%3d PRECALL 2 - CALL 2 +%3d CALL 2 GET_ITER - >> FOR_ITER 2 (to 40) + >> FOR_ITER 2 (to 34) STORE_FAST 0 (res) -%3d JUMP_BACKWARD 3 (to 34) +%3d JUMP_BACKWARD 4 (to 26) -%3d >> LOAD_CONST 0 (None) - RETURN_VALUE +%3d >> END_FOR + RETURN_CONST 0 (None) """ % (bug708901.__code__.co_firstlineno, bug708901.__code__.co_firstlineno + 1, bug708901.__code__.co_firstlineno + 2, @@ -162,7 +154,7 @@ dis_bug708901 = """\ def bug1333982(x=[]): - assert 0, ([s for s in x] + + assert 0, ((s for s in x) + 1) pass @@ -170,17 +162,15 @@ dis_bug1333982 = """\ %3d RESUME 0 %3d LOAD_ASSERTION_ERROR - LOAD_CONST 2 (<code object <listcomp> at 0x..., file "%s", line %d>) + LOAD_CONST 1 (<code object <genexpr> at 0x..., file "%s", line %d>) MAKE_FUNCTION 0 LOAD_FAST 0 (x) GET_ITER - PRECALL 0 CALL 0 -%3d LOAD_CONST 3 (1) +%3d LOAD_CONST 2 (1) %3d BINARY_OP 0 (+) - PRECALL 0 CALL 0 RAISE_VARARGS 1 """ % (bug1333982.__code__.co_firstlineno, @@ -201,8 +191,7 @@ bug42562.__code__ = bug42562.__code__.replace(co_linetable=b'\xf8') dis_bug42562 = """\ RESUME 0 - LOAD_CONST 0 (None) - RETURN_VALUE + RETURN_CONST 0 (None) """ # Extended arg followed by NOP @@ -238,13 +227,61 @@ dis_bug46724 = """\ JUMP_FORWARD -4 (to 0) """ +def func_w_kwargs(a, b, **c): + pass + +def wrap_func_w_kwargs(): + func_w_kwargs(1, 2, c=5) + +dis_kw_names = """\ +%3d RESUME 0 + +%3d LOAD_GLOBAL 1 (NULL + func_w_kwargs) + LOAD_CONST 1 (1) + LOAD_CONST 2 (2) + LOAD_CONST 3 (5) + KW_NAMES 4 (('c',)) + CALL 3 + POP_TOP + RETURN_CONST 0 (None) +""" % (wrap_func_w_kwargs.__code__.co_firstlineno, + wrap_func_w_kwargs.__code__.co_firstlineno + 1) + +dis_intrinsic_1_2 = """\ + 0 RESUME 0 + + 1 LOAD_CONST 0 (0) + LOAD_CONST 1 (('*',)) + IMPORT_NAME 0 (math) + CALL_INTRINSIC_1 2 (INTRINSIC_IMPORT_STAR) + POP_TOP + RETURN_CONST 2 (None) +""" + +dis_intrinsic_1_5 = """\ + 0 RESUME 0 + + 1 LOAD_NAME 0 (a) + CALL_INTRINSIC_1 5 (INTRINSIC_UNARY_POSITIVE) + RETURN_VALUE +""" + +dis_intrinsic_1_6 = """\ + 0 RESUME 0 + + 1 BUILD_LIST 0 + LOAD_NAME 0 (a) + LIST_EXTEND 1 + CALL_INTRINSIC_1 6 (INTRINSIC_LIST_TO_TUPLE) + RETURN_VALUE +""" + _BIG_LINENO_FORMAT = """\ 1 RESUME 0 %3d LOAD_GLOBAL 0 (spam) POP_TOP - LOAD_CONST 0 (None) - RETURN_VALUE + RETURN_CONST 0 (None) """ _BIG_LINENO_FORMAT2 = """\ @@ -252,20 +289,17 @@ _BIG_LINENO_FORMAT2 = """\ %4d LOAD_GLOBAL 0 (spam) POP_TOP - LOAD_CONST 0 (None) - RETURN_VALUE + RETURN_CONST 0 (None) """ dis_module_expected_results = """\ Disassembly of f: 4 RESUME 0 - LOAD_CONST 0 (None) - RETURN_VALUE + RETURN_CONST 0 (None) Disassembly of g: 5 RESUME 0 - LOAD_CONST 0 (None) - RETURN_VALUE + RETURN_CONST 0 (None) """ @@ -289,8 +323,7 @@ dis_simple_stmt_str = """\ LOAD_CONST 0 (1) BINARY_OP 0 (+) STORE_NAME 0 (x) - LOAD_CONST 1 (None) - RETURN_VALUE + RETURN_CONST 1 (None) """ annot_stmt_str = """\ @@ -315,7 +348,6 @@ dis_annot_stmt_str = """\ 3 PUSH_NULL LOAD_NAME 3 (fun) LOAD_CONST 0 (1) - PRECALL 1 CALL 1 LOAD_NAME 2 (__annotations__) LOAD_CONST 2 ('y') @@ -326,13 +358,11 @@ dis_annot_stmt_str = """\ PUSH_NULL LOAD_NAME 3 (fun) LOAD_CONST 3 (0) - PRECALL 1 CALL 1 STORE_SUBSCR LOAD_NAME 1 (int) POP_TOP - LOAD_CONST 4 (None) - RETURN_VALUE + RETURN_CONST 4 (None) """ compound_stmt_str = """\ @@ -366,22 +396,26 @@ dis_traceback = """\ LOAD_CONST 2 (0) --> BINARY_OP 11 (/) POP_TOP - JUMP_FORWARD 30 (to 76) + +%3d LOAD_FAST_CHECK 1 (tb) + RETURN_VALUE >> PUSH_EXC_INFO %3d LOAD_GLOBAL 0 (Exception) CHECK_EXC_MATCH - POP_JUMP_FORWARD_IF_FALSE 17 (to 68) + POP_JUMP_IF_FALSE 23 (to 80) STORE_FAST 0 (e) %3d LOAD_FAST 0 (e) - LOAD_ATTR 1 (__traceback__) + LOAD_ATTR 2 (__traceback__) STORE_FAST 1 (tb) POP_EXCEPT LOAD_CONST 0 (None) STORE_FAST 0 (e) DELETE_FAST 0 (e) - JUMP_FORWARD 8 (to 76) + +%3d LOAD_FAST 1 (tb) + RETURN_VALUE >> LOAD_CONST 0 (None) STORE_FAST 0 (e) DELETE_FAST 0 (e) @@ -391,17 +425,16 @@ dis_traceback = """\ >> COPY 3 POP_EXCEPT RERAISE 1 - -%3d >> LOAD_FAST 1 (tb) - RETURN_VALUE ExceptionTable: +4 rows """ % (TRACEBACK_CODE.co_firstlineno, TRACEBACK_CODE.co_firstlineno + 1, TRACEBACK_CODE.co_firstlineno + 2, + TRACEBACK_CODE.co_firstlineno + 5, TRACEBACK_CODE.co_firstlineno + 3, TRACEBACK_CODE.co_firstlineno + 4, - TRACEBACK_CODE.co_firstlineno + 3, - TRACEBACK_CODE.co_firstlineno + 5) + TRACEBACK_CODE.co_firstlineno + 5, + TRACEBACK_CODE.co_firstlineno + 3) def _fstring(a, b, c, d): return f'{a} {b:4} {c!r} {d!r:4}' @@ -426,6 +459,139 @@ dis_fstring = """\ RETURN_VALUE """ % (_fstring.__code__.co_firstlineno, _fstring.__code__.co_firstlineno + 1) +def _with(c): + with c: + x = 1 + y = 2 + +dis_with = """\ +%3d RESUME 0 + +%3d LOAD_FAST 0 (c) + BEFORE_WITH + POP_TOP + +%3d LOAD_CONST 1 (1) + STORE_FAST 1 (x) + +%3d LOAD_CONST 0 (None) + LOAD_CONST 0 (None) + LOAD_CONST 0 (None) + CALL 2 + POP_TOP + +%3d LOAD_CONST 2 (2) + STORE_FAST 2 (y) + RETURN_CONST 0 (None) + +%3d >> PUSH_EXC_INFO + WITH_EXCEPT_START + POP_JUMP_IF_TRUE 1 (to 42) + RERAISE 2 + >> POP_TOP + POP_EXCEPT + POP_TOP + POP_TOP + +%3d LOAD_CONST 2 (2) + STORE_FAST 2 (y) + RETURN_CONST 0 (None) + >> COPY 3 + POP_EXCEPT + RERAISE 1 +ExceptionTable: +2 rows +""" % (_with.__code__.co_firstlineno, + _with.__code__.co_firstlineno + 1, + _with.__code__.co_firstlineno + 2, + _with.__code__.co_firstlineno + 1, + _with.__code__.co_firstlineno + 3, + _with.__code__.co_firstlineno + 1, + _with.__code__.co_firstlineno + 3, + ) + +async def _asyncwith(c): + async with c: + x = 1 + y = 2 + +dis_asyncwith = """\ +%3d RETURN_GENERATOR + POP_TOP + RESUME 0 + +%3d LOAD_FAST 0 (c) + BEFORE_ASYNC_WITH + GET_AWAITABLE 1 + LOAD_CONST 0 (None) + >> SEND 3 (to 24) + YIELD_VALUE 2 + RESUME 3 + JUMP_BACKWARD_NO_INTERRUPT 5 (to 14) + >> END_SEND + POP_TOP + +%3d LOAD_CONST 1 (1) + STORE_FAST 1 (x) + +%3d LOAD_CONST 0 (None) + LOAD_CONST 0 (None) + LOAD_CONST 0 (None) + CALL 2 + GET_AWAITABLE 2 + LOAD_CONST 0 (None) + >> SEND 3 (to 60) + YIELD_VALUE 2 + RESUME 3 + JUMP_BACKWARD_NO_INTERRUPT 5 (to 50) + >> END_SEND + POP_TOP + +%3d LOAD_CONST 2 (2) + STORE_FAST 2 (y) + RETURN_CONST 0 (None) + +%3d >> CLEANUP_THROW + JUMP_BACKWARD 25 (to 24) + >> CLEANUP_THROW + JUMP_BACKWARD 9 (to 60) + >> PUSH_EXC_INFO + WITH_EXCEPT_START + GET_AWAITABLE 2 + LOAD_CONST 0 (None) + >> SEND 4 (to 98) + YIELD_VALUE 3 + RESUME 3 + JUMP_BACKWARD_NO_INTERRUPT 5 (to 86) + >> CLEANUP_THROW + >> END_SEND + POP_JUMP_IF_TRUE 1 (to 104) + RERAISE 2 + >> POP_TOP + POP_EXCEPT + POP_TOP + POP_TOP + +%3d LOAD_CONST 2 (2) + STORE_FAST 2 (y) + RETURN_CONST 0 (None) + >> COPY 3 + POP_EXCEPT + RERAISE 1 + >> CALL_INTRINSIC_1 3 (INTRINSIC_STOPITERATION_ERROR) + RERAISE 1 +ExceptionTable: +12 rows +""" % (_asyncwith.__code__.co_firstlineno, + _asyncwith.__code__.co_firstlineno + 1, + _asyncwith.__code__.co_firstlineno + 2, + _asyncwith.__code__.co_firstlineno + 1, + _asyncwith.__code__.co_firstlineno + 3, + _asyncwith.__code__.co_firstlineno + 1, + _asyncwith.__code__.co_firstlineno + 3, + ) + + def _tryfinally(a, b): try: return a @@ -447,14 +613,12 @@ dis_tryfinally = """\ %3d PUSH_NULL LOAD_FAST 1 (b) - PRECALL 0 CALL 0 POP_TOP RETURN_VALUE >> PUSH_EXC_INFO PUSH_NULL LOAD_FAST 1 (b) - PRECALL 0 CALL 0 POP_TOP RERAISE 0 @@ -462,6 +626,7 @@ dis_tryfinally = """\ POP_EXCEPT RERAISE 1 ExceptionTable: +2 rows """ % (_tryfinally.__code__.co_firstlineno, _tryfinally.__code__.co_firstlineno + 1, _tryfinally.__code__.co_firstlineno + 2, @@ -477,15 +642,12 @@ dis_tryfinallyconst = """\ %3d PUSH_NULL LOAD_FAST 0 (b) - PRECALL 0 CALL 0 POP_TOP - LOAD_CONST 1 (1) - RETURN_VALUE + RETURN_CONST 1 (1) PUSH_EXC_INFO PUSH_NULL LOAD_FAST 0 (b) - PRECALL 0 CALL 0 POP_TOP RERAISE 0 @@ -493,6 +655,7 @@ dis_tryfinallyconst = """\ POP_EXCEPT RERAISE 1 ExceptionTable: +1 row """ % (_tryfinallyconst.__code__.co_firstlineno, _tryfinallyconst.__code__.co_firstlineno + 1, _tryfinallyconst.__code__.co_firstlineno + 2, @@ -512,7 +675,7 @@ async def _co(x): def _h(y): def foo(x): '''funcdoc''' - return [x + z for z in y] + return list(x + z for z in y) return foo dis_nested_0 = """\ @@ -542,14 +705,15 @@ Disassembly of <code object foo at 0x..., file "%s", line %d>: %3d RESUME 0 -%3d LOAD_CLOSURE 0 (x) +%3d LOAD_GLOBAL 1 (NULL + list) + LOAD_CLOSURE 0 (x) BUILD_TUPLE 1 - LOAD_CONST 1 (<code object <listcomp> at 0x..., file "%s", line %d>) + LOAD_CONST 1 (<code object <genexpr> at 0x..., file "%s", line %d>) MAKE_FUNCTION 8 (closure) LOAD_DEREF 1 (y) GET_ITER - PRECALL 0 CALL 0 + CALL 1 RETURN_VALUE """ % (dis_nested_0, __file__, @@ -561,20 +725,28 @@ Disassembly of <code object foo at 0x..., file "%s", line %d>: ) dis_nested_2 = """%s -Disassembly of <code object <listcomp> at 0x..., file "%s", line %d>: +Disassembly of <code object <genexpr> at 0x..., file "%s", line %d>: COPY_FREE_VARS 1 -%3d RESUME 0 - BUILD_LIST 0 +%3d RETURN_GENERATOR + POP_TOP + RESUME 0 LOAD_FAST 0 (.0) - >> FOR_ITER 7 (to 24) + >> FOR_ITER 9 (to 32) STORE_FAST 1 (z) LOAD_DEREF 2 (x) LOAD_FAST 1 (z) BINARY_OP 0 (+) - LIST_APPEND 2 - JUMP_BACKWARD 8 (to 8) - >> RETURN_VALUE + YIELD_VALUE 1 + RESUME 1 + POP_TOP + JUMP_BACKWARD 11 (to 10) + >> END_FOR + RETURN_CONST 0 (None) + >> CALL_INTRINSIC_1 3 (INTRINSIC_STOPITERATION_ERROR) + RERAISE 1 +ExceptionTable: +1 row """ % (dis_nested_1, __file__, _h.__code__.co_firstlineno + 3, @@ -586,7 +758,7 @@ def load_test(x, y=0): return a, b dis_load_test_quickened_code = """\ -%3d 0 RESUME_QUICK 0 +%3d 0 RESUME 0 %3d 2 LOAD_FAST__LOAD_FAST 0 (x) 4 LOAD_FAST 1 (y) @@ -606,26 +778,25 @@ def loop_test(): load_test(i) dis_loop_test_quickened_code = """\ -%3d 0 RESUME_QUICK 0 - -%3d 2 BUILD_LIST 0 - 4 LOAD_CONST 1 ((1, 2, 3)) - 6 LIST_EXTEND 1 - 8 LOAD_CONST 2 (3) - 10 BINARY_OP_ADAPTIVE 5 (*) - 14 GET_ITER - 16 FOR_ITER 17 (to 52) - 18 STORE_FAST 0 (i) - -%3d 20 LOAD_GLOBAL_MODULE 1 (NULL + load_test) - 32 LOAD_FAST 0 (i) - 34 PRECALL_PYFUNC 1 - 38 CALL_PY_WITH_DEFAULTS 1 - 48 POP_TOP - 50 JUMP_BACKWARD_QUICK 18 (to 16) - -%3d >> 52 LOAD_CONST 0 (None) - 54 RETURN_VALUE +%3d RESUME 0 + +%3d BUILD_LIST 0 + LOAD_CONST 1 ((1, 2, 3)) + LIST_EXTEND 1 + LOAD_CONST 2 (3) + BINARY_OP 5 (*) + GET_ITER + >> FOR_ITER_LIST 13 (to 46) + STORE_FAST 0 (i) + +%3d LOAD_GLOBAL_MODULE 1 (NULL + load_test) + LOAD_FAST 0 (i) + CALL_PY_WITH_DEFAULTS 1 + POP_TOP + JUMP_BACKWARD 15 (to 16) + +%3d >> END_FOR + RETURN_CONST 0 (None) """ % (loop_test.__code__.co_firstlineno, loop_test.__code__.co_firstlineno + 1, loop_test.__code__.co_firstlineno + 2, @@ -642,12 +813,11 @@ dis_extended_arg_quick_code = """\ 6 UNPACK_EX 256 8 STORE_FAST 0 (_) 10 STORE_FAST 0 (_) - 12 LOAD_CONST 0 (None) - 14 RETURN_VALUE + 12 RETURN_CONST 0 (None) """% (extended_arg_quick.__code__.co_firstlineno, extended_arg_quick.__code__.co_firstlineno + 1,) -QUICKENING_WARMUP_DELAY = 8 +ADAPTIVE_WARMUP_DELAY = 2 class DisTestBase(unittest.TestCase): "Common utilities for DisTests and TestDisTraceback" @@ -689,6 +859,18 @@ class DisTestBase(unittest.TestCase): self.assertGreaterEqual(offset, expected_offset, line) expected_offset = offset + delta + def assert_exception_table_increasing(self, lines): + prev_start, prev_end = -1, -1 + count = 0 + for line in lines: + m = re.match(r' (\d+) to (\d+) -> \d+ \[\d+\]', line) + start, end = [int(g) for g in m.groups()] + self.assertGreaterEqual(end, start) + self.assertGreater(start, prev_end) + prev_start, prev_end = start, end + count += 1 + return count + def strip_offsets(self, text): lines = text.splitlines(True) start, end = self.find_offset_column(lines) @@ -702,6 +884,9 @@ class DisTestBase(unittest.TestCase): res.append(line) else: res.append(line[:start] + line[end:]) + num_rows = self.assert_exception_table_increasing(lines) + if num_rows: + res.append(f"{num_rows} row{'s' if num_rows > 1 else ''}\n") return "".join(res) def do_disassembly_compare(self, got, expected, with_offsets=False): @@ -734,6 +919,13 @@ class DisTests(DisTestBase): self.maxDiff = None got = self.get_disassembly(func, depth=0) self.do_disassembly_compare(got, expected, with_offsets) + # Add checks for dis.disco + if hasattr(func, '__code__'): + got_disco = io.StringIO() + with contextlib.redirect_stdout(got_disco): + dis.disco(func.__code__) + self.do_disassembly_compare(got_disco.getvalue(), expected, + with_offsets) def test_opmap(self): self.assertEqual(dis.opmap["NOP"], 9) @@ -748,22 +940,14 @@ class DisTests(DisTestBase): self.assertEqual(dis.opmap["STORE_NAME"], dis.HAVE_ARGUMENT) def test_widths(self): - long_opcodes = set(['POP_JUMP_FORWARD_IF_FALSE', - 'POP_JUMP_FORWARD_IF_TRUE', - 'POP_JUMP_FORWARD_IF_NOT_NONE', - 'POP_JUMP_FORWARD_IF_NONE', - 'POP_JUMP_BACKWARD_IF_FALSE', - 'POP_JUMP_BACKWARD_IF_TRUE', - 'POP_JUMP_BACKWARD_IF_NOT_NONE', - 'POP_JUMP_BACKWARD_IF_NONE', - 'JUMP_BACKWARD_NO_INTERRUPT', - ]) + long_opcodes = set(['JUMP_BACKWARD_NO_INTERRUPT', + 'INSTRUMENTED_CALL_FUNCTION_EX']) for opcode, opname in enumerate(dis.opname): - if opname in long_opcodes: + if opname in long_opcodes or opname.startswith("INSTRUMENTED"): continue with self.subTest(opname=opname): width = dis._OPNAME_WIDTH - if opcode < dis.HAVE_ARGUMENT: + if opcode in dis.hasarg: width += 1 + dis._OPARG_WIDTH self.assertLessEqual(len(opname), width) @@ -792,6 +976,20 @@ class DisTests(DisTestBase): # Test that negative operargs are handled properly self.do_disassembly_test(bug46724, dis_bug46724) + def test_kw_names(self): + # Test that value is displayed for KW_NAMES + self.do_disassembly_test(wrap_func_w_kwargs, dis_kw_names) + + def test_intrinsic_1(self): + # Test that argrepr is displayed for CALL_INTRINSIC_1 + self.do_disassembly_test("from math import *", dis_intrinsic_1_2) + self.do_disassembly_test("+a", dis_intrinsic_1_5) + self.do_disassembly_test("(*a,)", dis_intrinsic_1_6) + + def test_intrinsic_2(self): + self.assertIn("CALL_INTRINSIC_2 1 (INTRINSIC_PREP_RERAISE_STAR)", + self.get_disassembly("try: pass\nexcept* Exception: x")) + def test_big_linenos(self): def func(count): namespace = {} @@ -894,11 +1092,21 @@ class DisTests(DisTestBase): def test_disassemble_fstring(self): self.do_disassembly_test(_fstring, dis_fstring) + def test_disassemble_with(self): + self.do_disassembly_test(_with, dis_with) + + def test_disassemble_asyncwith(self): + self.do_disassembly_test(_asyncwith, dis_asyncwith) + def test_disassemble_try_finally(self): self.do_disassembly_test(_tryfinally, dis_tryfinally) self.do_disassembly_test(_tryfinallyconst, dis_tryfinallyconst) def test_dis_none(self): + try: + del sys.last_exc + except AttributeError: + pass try: del sys.last_traceback except AttributeError: @@ -916,7 +1124,7 @@ class DisTests(DisTestBase): 1/0 except Exception as e: tb = e.__traceback__ - sys.last_traceback = tb + sys.last_exc = e tb_dis = self.get_disassemble_as_string(tb.tb_frame.f_code, tb.tb_lasti) self.do_disassembly_test(None, tb_dis, True) @@ -938,21 +1146,30 @@ class DisTests(DisTestBase): check(dis_nested_2, depth=None) check(dis_nested_2) + def test__try_compile_no_context_exc_on_error(self): + # see gh-102114 + try: + dis._try_compile(")", "") + except Exception as e: + self.assertIsNone(e.__context__) + @staticmethod - def code_quicken(f, times=QUICKENING_WARMUP_DELAY): + def code_quicken(f, times=ADAPTIVE_WARMUP_DELAY): for _ in range(times): f() @cpython_only + @requires_specialization def test_super_instructions(self): self.code_quicken(lambda: load_test(0, 0)) got = self.get_disassembly(load_test, adaptive=True) self.do_disassembly_compare(got, dis_load_test_quickened_code, True) @cpython_only + @requires_specialization def test_binary_specialize(self): binary_op_quicken = """\ - 0 0 RESUME_QUICK 0 + 0 0 RESUME 0 1 2 LOAD_NAME 0 (a) 4 LOAD_NAME 1 (b) @@ -970,12 +1187,12 @@ class DisTests(DisTestBase): self.do_disassembly_compare(got, binary_op_quicken % "BINARY_OP_ADD_UNICODE 0 (+)", True) binary_subscr_quicken = """\ - 0 0 RESUME_QUICK 0 + 0 0 RESUME 0 1 2 LOAD_NAME 0 (a) 4 LOAD_CONST 0 (0) 6 %s - 16 RETURN_VALUE + 10 RETURN_VALUE """ co_list = compile('a[0]', "<list>", "eval") self.code_quicken(lambda: exec(co_list, {}, {'a': [0]})) @@ -988,13 +1205,14 @@ class DisTests(DisTestBase): self.do_disassembly_compare(got, binary_subscr_quicken % "BINARY_SUBSCR_DICT", True) @cpython_only + @requires_specialization def test_load_attr_specialize(self): load_attr_quicken = """\ - 0 0 RESUME_QUICK 0 + 0 0 RESUME 0 1 2 LOAD_CONST 0 ('a') 4 LOAD_ATTR_SLOT 0 (__class__) - 14 RETURN_VALUE + 24 RETURN_VALUE """ co = compile("'a'.__class__", "", "eval") self.code_quicken(lambda: exec(co, {}, {})) @@ -1002,28 +1220,29 @@ class DisTests(DisTestBase): self.do_disassembly_compare(got, load_attr_quicken, True) @cpython_only + @requires_specialization def test_call_specialize(self): call_quicken = """\ - 0 0 RESUME_QUICK 0 - - 1 2 PUSH_NULL - 4 LOAD_NAME 0 (str) - 6 LOAD_CONST 0 (1) - 8 PRECALL_NO_KW_STR_1 1 - 12 CALL_ADAPTIVE 1 - 22 RETURN_VALUE + 0 RESUME 0 + + 1 PUSH_NULL + LOAD_NAME 0 (str) + LOAD_CONST 0 (1) + CALL_NO_KW_STR_1 1 + RETURN_VALUE """ co = compile("str(1)", "", "eval") self.code_quicken(lambda: exec(co, {}, {})) got = self.get_disassembly(co, adaptive=True) - self.do_disassembly_compare(got, call_quicken, True) + self.do_disassembly_compare(got, call_quicken) @cpython_only + @requires_specialization def test_loop_quicken(self): # Loop can trigger a quicken where the loop is located self.code_quicken(loop_test, 1) got = self.get_disassembly(loop_test, adaptive=True) - self.do_disassembly_compare(got, dis_loop_test_quickened_code, True) + self.do_disassembly_compare(got, dis_loop_test_quickened_code) @cpython_only def test_extended_arg_quick(self): @@ -1051,18 +1270,46 @@ class DisTests(DisTestBase): for quickened in (False, True): for adaptive in (False, True): with self.subTest(f"{quickened=}, {adaptive=}"): - if quickened and adaptive: + if adaptive: pattern = r"^(\w+: \d+)?$" else: pattern = r"^(\w+: 0)?$" caches = list(self.get_cached_values(quickened, adaptive)) for cache in caches: self.assertRegex(cache, pattern) - total_caches = 25 - empty_caches = 8 if adaptive and quickened else total_caches + total_caches = 20 + empty_caches = 7 self.assertEqual(caches.count(""), empty_caches) self.assertEqual(len(caches), total_caches) + @cpython_only + def test_show_currinstr_with_cache(self): + """ + Make sure that with lasti pointing to CACHE, it still shows the current + line correctly + """ + def f(): + print(a) + # The code above should generate a LOAD_GLOBAL which has CACHE instr after + # However, this might change in the future. So we explicitly try to find + # a CACHE entry in the instructions. If we can't do that, fail the test + + for inst in dis.get_instructions(f, show_caches=True): + if inst.opname == "CACHE": + op_offset = inst.offset - 2 + cache_offset = inst.offset + break + else: + self.fail("Can't find a CACHE entry in the function provided to do the test") + + assem_op = self.get_disassembly(f.__code__, lasti=op_offset, wrapper=False) + assem_cache = self.get_disassembly(f.__code__, lasti=cache_offset, wrapper=False) + + # Make sure --> exists and points to the correct offset + self.assertRegex(assem_op, fr"-->\s+{op_offset}") + # Make sure when lasti points to cache, it shows the same disassembly + self.assertEqual(assem_op, assem_cache) + class DisWithFileTests(DisTests): @@ -1306,9 +1553,9 @@ def jumpy(): # End fodder for opinfo generation tests expected_outer_line = 1 _line_offset = outer.__code__.co_firstlineno - 1 -code_object_f = outer.__code__.co_consts[3] +code_object_f = outer.__code__.co_consts[1] expected_f_line = code_object_f.co_firstlineno - _line_offset -code_object_inner = code_object_f.co_consts[3] +code_object_inner = code_object_f.co_consts[1] expected_inner_line = code_object_inner.co_firstlineno - _line_offset expected_jumpy_line = 1 @@ -1340,30 +1587,30 @@ def _prepare_test_cases(): #_prepare_test_cases() Instruction = dis.Instruction + expected_opinfo_outer = [ Instruction(opname='MAKE_CELL', opcode=135, arg=0, argval='a', argrepr='a', offset=0, starts_line=None, is_jump_target=False, positions=None), Instruction(opname='MAKE_CELL', opcode=135, arg=1, argval='b', argrepr='b', offset=2, starts_line=None, is_jump_target=False, positions=None), Instruction(opname='RESUME', opcode=151, arg=0, argval=0, argrepr='', offset=4, starts_line=1, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=7, argval=(3, 4), argrepr='(3, 4)', offset=6, starts_line=2, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval=(3, 4), argrepr='(3, 4)', offset=6, starts_line=2, is_jump_target=False, positions=None), Instruction(opname='LOAD_CLOSURE', opcode=136, arg=0, argval='a', argrepr='a', offset=8, starts_line=None, is_jump_target=False, positions=None), Instruction(opname='LOAD_CLOSURE', opcode=136, arg=1, argval='b', argrepr='b', offset=10, starts_line=None, is_jump_target=False, positions=None), Instruction(opname='BUILD_TUPLE', opcode=102, arg=2, argval=2, argrepr='', offset=12, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=code_object_f, argrepr=repr(code_object_f), offset=14, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=1, argval=code_object_f, argrepr=repr(code_object_f), offset=14, starts_line=None, is_jump_target=False, positions=None), Instruction(opname='MAKE_FUNCTION', opcode=132, arg=9, argval=9, argrepr='defaults, closure', offset=16, starts_line=None, is_jump_target=False, positions=None), Instruction(opname='STORE_FAST', opcode=125, arg=2, argval='f', argrepr='f', offset=18, starts_line=None, is_jump_target=False, positions=None), Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='NULL + print', offset=20, starts_line=7, is_jump_target=False, positions=None), - Instruction(opname='LOAD_DEREF', opcode=137, arg=0, argval='a', argrepr='a', offset=32, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_DEREF', opcode=137, arg=1, argval='b', argrepr='b', offset=34, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=4, argval='', argrepr="''", offset=36, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval=1, argrepr='1', offset=38, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='BUILD_LIST', opcode=103, arg=0, argval=0, argrepr='', offset=40, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='BUILD_MAP', opcode=105, arg=0, argval=0, argrepr='', offset=42, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=6, argval='Hello world!', argrepr="'Hello world!'", offset=44, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PRECALL', opcode=166, arg=7, argval=7, argrepr='', offset=46, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=7, argval=7, argrepr='', offset=50, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=60, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=2, argval='f', argrepr='f', offset=62, starts_line=8, is_jump_target=False, positions=None), - Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=64, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_DEREF', opcode=137, arg=0, argval='a', argrepr='a', offset=30, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_DEREF', opcode=137, arg=1, argval='b', argrepr='b', offset=32, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=2, argval='', argrepr="''", offset=34, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=1, argrepr='1', offset=36, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='BUILD_LIST', opcode=103, arg=0, argval=0, argrepr='', offset=38, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='BUILD_MAP', opcode=105, arg=0, argval=0, argrepr='', offset=40, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=4, argval='Hello world!', argrepr="'Hello world!'", offset=42, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=7, argval=7, argrepr='', offset=44, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=52, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=2, argval='f', argrepr='f', offset=54, starts_line=8, is_jump_target=False, positions=None), + Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=56, starts_line=None, is_jump_target=False, positions=None), ] expected_opinfo_f = [ @@ -1371,176 +1618,162 @@ expected_opinfo_f = [ Instruction(opname='MAKE_CELL', opcode=135, arg=0, argval='c', argrepr='c', offset=2, starts_line=None, is_jump_target=False, positions=None), Instruction(opname='MAKE_CELL', opcode=135, arg=1, argval='d', argrepr='d', offset=4, starts_line=None, is_jump_target=False, positions=None), Instruction(opname='RESUME', opcode=151, arg=0, argval=0, argrepr='', offset=6, starts_line=2, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=4, argval=(5, 6), argrepr='(5, 6)', offset=8, starts_line=3, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=2, argval=(5, 6), argrepr='(5, 6)', offset=8, starts_line=3, is_jump_target=False, positions=None), Instruction(opname='LOAD_CLOSURE', opcode=136, arg=3, argval='a', argrepr='a', offset=10, starts_line=None, is_jump_target=False, positions=None), Instruction(opname='LOAD_CLOSURE', opcode=136, arg=4, argval='b', argrepr='b', offset=12, starts_line=None, is_jump_target=False, positions=None), Instruction(opname='LOAD_CLOSURE', opcode=136, arg=0, argval='c', argrepr='c', offset=14, starts_line=None, is_jump_target=False, positions=None), Instruction(opname='LOAD_CLOSURE', opcode=136, arg=1, argval='d', argrepr='d', offset=16, starts_line=None, is_jump_target=False, positions=None), Instruction(opname='BUILD_TUPLE', opcode=102, arg=4, argval=4, argrepr='', offset=18, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=code_object_inner, argrepr=repr(code_object_inner), offset=20, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=1, argval=code_object_inner, argrepr=repr(code_object_inner), offset=20, starts_line=None, is_jump_target=False, positions=None), Instruction(opname='MAKE_FUNCTION', opcode=132, arg=9, argval=9, argrepr='defaults, closure', offset=22, starts_line=None, is_jump_target=False, positions=None), Instruction(opname='STORE_FAST', opcode=125, arg=2, argval='inner', argrepr='inner', offset=24, starts_line=None, is_jump_target=False, positions=None), Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='NULL + print', offset=26, starts_line=5, is_jump_target=False, positions=None), - Instruction(opname='LOAD_DEREF', opcode=137, arg=3, argval='a', argrepr='a', offset=38, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_DEREF', opcode=137, arg=4, argval='b', argrepr='b', offset=40, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_DEREF', opcode=137, arg=0, argval='c', argrepr='c', offset=42, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_DEREF', opcode=137, arg=1, argval='d', argrepr='d', offset=44, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PRECALL', opcode=166, arg=4, argval=4, argrepr='', offset=46, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=4, argval=4, argrepr='', offset=50, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=60, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=2, argval='inner', argrepr='inner', offset=62, starts_line=6, is_jump_target=False, positions=None), - Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=64, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_DEREF', opcode=137, arg=3, argval='a', argrepr='a', offset=36, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_DEREF', opcode=137, arg=4, argval='b', argrepr='b', offset=38, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_DEREF', opcode=137, arg=0, argval='c', argrepr='c', offset=40, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_DEREF', opcode=137, arg=1, argval='d', argrepr='d', offset=42, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=4, argval=4, argrepr='', offset=44, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=52, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=2, argval='inner', argrepr='inner', offset=54, starts_line=6, is_jump_target=False, positions=None), + Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=56, starts_line=None, is_jump_target=False, positions=None), ] expected_opinfo_inner = [ Instruction(opname='COPY_FREE_VARS', opcode=149, arg=4, argval=4, argrepr='', offset=0, starts_line=None, is_jump_target=False, positions=None), Instruction(opname='RESUME', opcode=151, arg=0, argval=0, argrepr='', offset=2, starts_line=3, is_jump_target=False, positions=None), Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='NULL + print', offset=4, starts_line=4, is_jump_target=False, positions=None), - Instruction(opname='LOAD_DEREF', opcode=137, arg=2, argval='a', argrepr='a', offset=16, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_DEREF', opcode=137, arg=3, argval='b', argrepr='b', offset=18, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_DEREF', opcode=137, arg=4, argval='c', argrepr='c', offset=20, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_DEREF', opcode=137, arg=5, argval='d', argrepr='d', offset=22, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='e', argrepr='e', offset=24, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=1, argval='f', argrepr='f', offset=26, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PRECALL', opcode=166, arg=6, argval=6, argrepr='', offset=28, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=6, argval=6, argrepr='', offset=32, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=42, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=44, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=46, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_DEREF', opcode=137, arg=2, argval='a', argrepr='a', offset=14, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_DEREF', opcode=137, arg=3, argval='b', argrepr='b', offset=16, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_DEREF', opcode=137, arg=4, argval='c', argrepr='c', offset=18, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_DEREF', opcode=137, arg=5, argval='d', argrepr='d', offset=20, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='e', argrepr='e', offset=22, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=1, argval='f', argrepr='f', offset=24, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=6, argval=6, argrepr='', offset=26, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=34, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='RETURN_CONST', opcode=121, arg=0, argval=None, argrepr='None', offset=36, starts_line=None, is_jump_target=False, positions=None), ] expected_opinfo_jumpy = [ Instruction(opname='RESUME', opcode=151, arg=0, argval=0, argrepr='', offset=0, starts_line=1, is_jump_target=False, positions=None), Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='range', argrepr='NULL + range', offset=2, starts_line=3, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=1, argval=10, argrepr='10', offset=14, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=16, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=20, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='GET_ITER', opcode=68, arg=None, argval=None, argrepr='', offset=30, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='FOR_ITER', opcode=93, arg=32, argval=98, argrepr='to 98', offset=32, starts_line=None, is_jump_target=True, positions=None), - Instruction(opname='STORE_FAST', opcode=125, arg=0, argval='i', argrepr='i', offset=34, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=3, argval='print', argrepr='NULL + print', offset=36, starts_line=4, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=48, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=50, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=54, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=64, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=66, starts_line=5, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=2, argval=4, argrepr='4', offset=68, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='COMPARE_OP', opcode=107, arg=0, argval='<', argrepr='<', offset=70, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_JUMP_FORWARD_IF_FALSE', opcode=114, arg=1, argval=80, argrepr='to 80', offset=76, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='JUMP_BACKWARD', opcode=140, arg=24, argval=32, argrepr='to 32', offset=78, starts_line=6, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=80, starts_line=7, is_jump_target=True, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=6, argrepr='6', offset=82, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='COMPARE_OP', opcode=107, arg=4, argval='>', argrepr='>', offset=84, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_JUMP_FORWARD_IF_FALSE', opcode=114, arg=2, argval=96, argrepr='to 96', offset=90, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=92, starts_line=8, is_jump_target=False, positions=None), - Instruction(opname='JUMP_FORWARD', opcode=110, arg=16, argval=128, argrepr='to 128', offset=94, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='JUMP_BACKWARD', opcode=140, arg=33, argval=32, argrepr='to 32', offset=96, starts_line=7, is_jump_target=True, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=3, argval='print', argrepr='NULL + print', offset=98, starts_line=10, is_jump_target=True, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=4, argval='I can haz else clause?', argrepr="'I can haz else clause?'", offset=110, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=112, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=116, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=126, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=128, starts_line=11, is_jump_target=True, positions=None), - Instruction(opname='POP_JUMP_FORWARD_IF_FALSE', opcode=114, arg=36, argval=204, argrepr='to 204', offset=130, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=3, argval='print', argrepr='NULL + print', offset=132, starts_line=12, is_jump_target=True, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=144, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=146, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=150, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=160, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=162, starts_line=13, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval=1, argrepr='1', offset=164, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='BINARY_OP', opcode=122, arg=23, argval=23, argrepr='-=', offset=166, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='STORE_FAST', opcode=125, arg=0, argval='i', argrepr='i', offset=170, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=172, starts_line=14, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=6, argrepr='6', offset=174, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='COMPARE_OP', opcode=107, arg=4, argval='>', argrepr='>', offset=176, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_JUMP_FORWARD_IF_FALSE', opcode=114, arg=1, argval=186, argrepr='to 186', offset=182, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='JUMP_BACKWARD', opcode=140, arg=29, argval=128, argrepr='to 128', offset=184, starts_line=15, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=186, starts_line=16, is_jump_target=True, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=2, argval=4, argrepr='4', offset=188, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='COMPARE_OP', opcode=107, arg=0, argval='<', argrepr='<', offset=190, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_JUMP_FORWARD_IF_FALSE', opcode=114, arg=1, argval=200, argrepr='to 200', offset=196, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='JUMP_FORWARD', opcode=110, arg=17, argval=234, argrepr='to 234', offset=198, starts_line=17, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=200, starts_line=11, is_jump_target=True, positions=None), - Instruction(opname='POP_JUMP_BACKWARD_IF_TRUE', opcode=176, arg=36, argval=132, argrepr='to 132', offset=202, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=3, argval='print', argrepr='NULL + print', offset=204, starts_line=19, is_jump_target=True, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=6, argval='Who let lolcatz into this test suite?', argrepr="'Who let lolcatz into this test suite?'", offset=216, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=218, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=1, argval=10, argrepr='10', offset=12, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=14, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='GET_ITER', opcode=68, arg=None, argval=None, argrepr='', offset=22, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='FOR_ITER', opcode=93, arg=26, argval=80, argrepr='to 80', offset=24, starts_line=None, is_jump_target=True, positions=None), + Instruction(opname='STORE_FAST', opcode=125, arg=0, argval='i', argrepr='i', offset=28, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=3, argval='print', argrepr='NULL + print', offset=30, starts_line=4, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=40, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=42, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=50, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=52, starts_line=5, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=2, argval=4, argrepr='4', offset=54, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='COMPARE_OP', opcode=107, arg=2, argval='<', argrepr='<', offset=56, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=1, argval=64, argrepr='to 64', offset=60, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='JUMP_BACKWARD', opcode=140, arg=20, argval=24, argrepr='to 24', offset=62, starts_line=6, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=64, starts_line=7, is_jump_target=True, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=6, argrepr='6', offset=66, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='COMPARE_OP', opcode=107, arg=68, argval='>', argrepr='>', offset=68, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_JUMP_IF_TRUE', opcode=115, arg=1, argval=76, argrepr='to 76', offset=72, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='JUMP_BACKWARD', opcode=140, arg=26, argval=24, argrepr='to 24', offset=74, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=76, starts_line=8, is_jump_target=True, positions=None), + Instruction(opname='JUMP_FORWARD', opcode=110, arg=12, argval=104, argrepr='to 104', offset=78, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='END_FOR', opcode=4, arg=None, argval=None, argrepr='', offset=80, starts_line=3, is_jump_target=True, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=3, argval='print', argrepr='NULL + print', offset=82, starts_line=10, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=4, argval='I can haz else clause?', argrepr="'I can haz else clause?'", offset=92, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=94, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=102, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST_CHECK', opcode=127, arg=0, argval='i', argrepr='i', offset=104, starts_line=11, is_jump_target=True, positions=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=31, argval=170, argrepr='to 170', offset=106, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=3, argval='print', argrepr='NULL + print', offset=108, starts_line=12, is_jump_target=True, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=118, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=120, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=128, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=130, starts_line=13, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval=1, argrepr='1', offset=132, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='BINARY_OP', opcode=122, arg=23, argval=23, argrepr='-=', offset=134, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='STORE_FAST', opcode=125, arg=0, argval='i', argrepr='i', offset=138, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=140, starts_line=14, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=6, argrepr='6', offset=142, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='COMPARE_OP', opcode=107, arg=68, argval='>', argrepr='>', offset=144, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=1, argval=152, argrepr='to 152', offset=148, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='JUMP_BACKWARD', opcode=140, arg=24, argval=104, argrepr='to 104', offset=150, starts_line=15, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=152, starts_line=16, is_jump_target=True, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=2, argval=4, argrepr='4', offset=154, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='COMPARE_OP', opcode=107, arg=2, argval='<', argrepr='<', offset=156, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=1, argval=164, argrepr='to 164', offset=160, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='JUMP_FORWARD', opcode=110, arg=14, argval=192, argrepr='to 192', offset=162, starts_line=17, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=164, starts_line=11, is_jump_target=True, positions=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=1, argval=170, argrepr='to 170', offset=166, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='JUMP_BACKWARD', opcode=140, arg=31, argval=108, argrepr='to 108', offset=168, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=3, argval='print', argrepr='NULL + print', offset=170, starts_line=19, is_jump_target=True, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=6, argval='Who let lolcatz into this test suite?', argrepr="'Who let lolcatz into this test suite?'", offset=180, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=182, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=190, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='NOP', opcode=9, arg=None, argval=None, argrepr='', offset=192, starts_line=20, is_jump_target=True, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval=1, argrepr='1', offset=194, starts_line=21, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=7, argval=0, argrepr='0', offset=196, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='BINARY_OP', opcode=122, arg=11, argval=11, argrepr='/', offset=198, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=202, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=204, starts_line=25, is_jump_target=False, positions=None), + Instruction(opname='BEFORE_WITH', opcode=53, arg=None, argval=None, argrepr='', offset=206, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='STORE_FAST', opcode=125, arg=1, argval='dodgy', argrepr='dodgy', offset=208, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=3, argval='print', argrepr='NULL + print', offset=210, starts_line=26, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=8, argval='Never reach this', argrepr="'Never reach this'", offset=220, starts_line=None, is_jump_target=False, positions=None), Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=222, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=232, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='NOP', opcode=9, arg=None, argval=None, argrepr='', offset=234, starts_line=20, is_jump_target=True, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval=1, argrepr='1', offset=236, starts_line=21, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=7, argval=0, argrepr='0', offset=238, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='BINARY_OP', opcode=122, arg=11, argval=11, argrepr='/', offset=240, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=244, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=246, starts_line=25, is_jump_target=False, positions=None), - Instruction(opname='BEFORE_WITH', opcode=53, arg=None, argval=None, argrepr='', offset=248, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='STORE_FAST', opcode=125, arg=1, argval='dodgy', argrepr='dodgy', offset=250, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=3, argval='print', argrepr='NULL + print', offset=252, starts_line=26, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=8, argval='Never reach this', argrepr="'Never reach this'", offset=264, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=266, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=270, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=280, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=282, starts_line=25, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=284, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=286, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PRECALL', opcode=166, arg=2, argval=2, argrepr='', offset=288, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=2, argval=2, argrepr='', offset=292, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=302, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='JUMP_FORWARD', opcode=110, arg=11, argval=328, argrepr='to 328', offset=304, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PUSH_EXC_INFO', opcode=35, arg=None, argval=None, argrepr='', offset=306, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='WITH_EXCEPT_START', opcode=49, arg=None, argval=None, argrepr='', offset=308, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_JUMP_FORWARD_IF_TRUE', opcode=115, arg=4, argval=320, argrepr='to 320', offset=310, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='RERAISE', opcode=119, arg=2, argval=2, argrepr='', offset=312, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='COPY', opcode=120, arg=3, argval=3, argrepr='', offset=314, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=316, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='RERAISE', opcode=119, arg=1, argval=1, argrepr='', offset=318, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=320, starts_line=None, is_jump_target=True, positions=None), - Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=322, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=324, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=326, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='JUMP_FORWARD', opcode=110, arg=31, argval=392, argrepr='to 392', offset=328, starts_line=None, is_jump_target=True, positions=None), - Instruction(opname='PUSH_EXC_INFO', opcode=35, arg=None, argval=None, argrepr='', offset=330, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=4, argval='ZeroDivisionError', argrepr='ZeroDivisionError', offset=332, starts_line=22, is_jump_target=False, positions=None), - Instruction(opname='CHECK_EXC_MATCH', opcode=36, arg=None, argval=None, argrepr='', offset=344, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_JUMP_FORWARD_IF_FALSE', opcode=114, arg=18, argval=384, argrepr='to 384', offset=346, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=348, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=3, argval='print', argrepr='NULL + print', offset=350, starts_line=23, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=9, argval='Here we go, here we go, here we go...', argrepr="'Here we go, here we go, here we go...'", offset=362, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=364, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=368, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=378, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=380, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='JUMP_FORWARD', opcode=110, arg=4, argval=392, argrepr='to 392', offset=382, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='RERAISE', opcode=119, arg=0, argval=0, argrepr='', offset=384, starts_line=22, is_jump_target=True, positions=None), - Instruction(opname='COPY', opcode=120, arg=3, argval=3, argrepr='', offset=386, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=388, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='RERAISE', opcode=119, arg=1, argval=1, argrepr='', offset=390, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=3, argval='print', argrepr='NULL + print', offset=392, starts_line=28, is_jump_target=True, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=404, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=406, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=410, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=420, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=422, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=424, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PUSH_EXC_INFO', opcode=35, arg=None, argval=None, argrepr='', offset=426, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_GLOBAL', opcode=116, arg=3, argval='print', argrepr='NULL + print', offset=428, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=440, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='PRECALL', opcode=166, arg=1, argval=1, argrepr='', offset=442, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=446, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=456, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='RERAISE', opcode=119, arg=0, argval=0, argrepr='', offset=458, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='COPY', opcode=120, arg=3, argval=3, argrepr='', offset=460, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=462, starts_line=None, is_jump_target=False, positions=None), - Instruction(opname='RERAISE', opcode=119, arg=1, argval=1, argrepr='', offset=464, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=230, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=232, starts_line=25, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=234, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=236, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=2, argval=2, argrepr='', offset=238, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=246, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=3, argval='print', argrepr='NULL + print', offset=248, starts_line=28, is_jump_target=True, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=258, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=260, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=268, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='RETURN_CONST', opcode=121, arg=0, argval=None, argrepr='None', offset=270, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PUSH_EXC_INFO', opcode=35, arg=None, argval=None, argrepr='', offset=272, starts_line=25, is_jump_target=False, positions=None), + Instruction(opname='WITH_EXCEPT_START', opcode=49, arg=None, argval=None, argrepr='', offset=274, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_JUMP_IF_TRUE', opcode=115, arg=1, argval=280, argrepr='to 280', offset=276, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='RERAISE', opcode=119, arg=2, argval=2, argrepr='', offset=278, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=280, starts_line=None, is_jump_target=True, positions=None), + Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=282, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=284, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=286, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='JUMP_BACKWARD', opcode=140, arg=21, argval=248, argrepr='to 248', offset=288, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='COPY', opcode=120, arg=3, argval=3, argrepr='', offset=290, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=292, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='RERAISE', opcode=119, arg=1, argval=1, argrepr='', offset=294, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PUSH_EXC_INFO', opcode=35, arg=None, argval=None, argrepr='', offset=296, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=4, argval='ZeroDivisionError', argrepr='ZeroDivisionError', offset=298, starts_line=22, is_jump_target=False, positions=None), + Instruction(opname='CHECK_EXC_MATCH', opcode=36, arg=None, argval=None, argrepr='', offset=308, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_JUMP_IF_FALSE', opcode=114, arg=14, argval=340, argrepr='to 340', offset=310, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=312, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=3, argval='print', argrepr='NULL + print', offset=314, starts_line=23, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=9, argval='Here we go, here we go, here we go...', argrepr="'Here we go, here we go, here we go...'", offset=324, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=326, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=334, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=336, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='JUMP_BACKWARD', opcode=140, arg=46, argval=248, argrepr='to 248', offset=338, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='RERAISE', opcode=119, arg=0, argval=0, argrepr='', offset=340, starts_line=22, is_jump_target=True, positions=None), + Instruction(opname='COPY', opcode=120, arg=3, argval=3, argrepr='', offset=342, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=344, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='RERAISE', opcode=119, arg=1, argval=1, argrepr='', offset=346, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='PUSH_EXC_INFO', opcode=35, arg=None, argval=None, argrepr='', offset=348, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='LOAD_GLOBAL', opcode=116, arg=3, argval='print', argrepr='NULL + print', offset=350, starts_line=28, is_jump_target=False, positions=None), + Instruction(opname='LOAD_CONST', opcode=100, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=360, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='CALL', opcode=171, arg=1, argval=1, argrepr='', offset=362, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=370, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='RERAISE', opcode=119, arg=0, argval=0, argrepr='', offset=372, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='COPY', opcode=120, arg=3, argval=3, argrepr='', offset=374, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=376, starts_line=None, is_jump_target=False, positions=None), + Instruction(opname='RERAISE', opcode=119, arg=1, argval=1, argrepr='', offset=378, starts_line=None, is_jump_target=False, positions=None), ] # One last piece of inspect fodder to check the default line number handling def simple(): pass expected_opinfo_simple = [ Instruction(opname='RESUME', opcode=151, arg=0, argval=0, argrepr='', offset=0, starts_line=simple.__code__.co_firstlineno, is_jump_target=False, positions=None), - Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=2, starts_line=None, is_jump_target=False), - Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=4, starts_line=None, is_jump_target=False) + Instruction(opname='RETURN_CONST', opcode=121, arg=0, argval=None, argrepr='None', offset=2, starts_line=None, is_jump_target=False), ] @@ -1601,8 +1834,6 @@ class InstructionTests(InstructionTestCase): (2, 2, 8, 9), (1, 3, 0, 1), (1, 3, 0, 1), - (1, 3, 0, 1), - (1, 3, 0, 1), (1, 3, 0, 1) ] self.assertEqual(positions, expected) @@ -1783,9 +2014,21 @@ class TestFinderMethods(unittest.TestCase): self.assertEqual(sorted(labels), sorted(jumps)) + def test_findlinestarts(self): + def func(): + pass + + code = func.__code__ + offsets = [linestart[0] for linestart in dis.findlinestarts(code)] + self.assertEqual(offsets, [0, 2]) + class TestDisTraceback(DisTestBase): def setUp(self) -> None: + try: # We need to clean up existing tracebacks + del sys.last_exc + except AttributeError: + pass try: # We need to clean up existing tracebacks del sys.last_traceback except AttributeError: diff --git a/Lib/test/test_distutils.py b/Lib/test/test_distutils.py deleted file mode 100644 index 28320fb5..00000000 --- a/Lib/test/test_distutils.py +++ /dev/null @@ -1,30 +0,0 @@ -"""Tests for distutils. - -The tests for distutils are defined in the distutils.tests package; -the test_suite() function there returns a test suite that's ready to -be run. -""" - -import unittest -from test import support -from test.support import warnings_helper - -with warnings_helper.check_warnings( - ("The distutils package is deprecated", DeprecationWarning), quiet=True): - - import distutils.tests - - -def load_tests(*_): - # used by unittest - return distutils.tests.test_suite() - - -def tearDownModule(): - support.reap_children() - -if support.check_sanitizer(address=True): - raise unittest.SkipTest("Exposes ASAN flakiness in GitHub CI") - -if __name__ == "__main__": - unittest.main() diff --git a/Lib/test/test_doctest.py b/Lib/test/test_doctest.py index 00aeacdd..bca4915e 100644 --- a/Lib/test/test_doctest.py +++ b/Lib/test/test_doctest.py @@ -4,7 +4,6 @@ Test script for doctest. from test import support from test.support import import_helper -from test.support import os_helper import doctest import functools import os @@ -14,7 +13,6 @@ import importlib.abc import importlib.util import unittest import tempfile -import shutil import types import contextlib @@ -461,7 +459,7 @@ We'll simulate a __file__ attr that ends in pyc: >>> tests = finder.find(sample_func) >>> print(tests) # doctest: +ELLIPSIS - [<DocTest sample_func from test_doctest.py:34 (1 example)>] + [<DocTest sample_func from test_doctest.py:32 (1 example)>] The exact name depends on how test_doctest was invoked, so allow for leading path components. @@ -709,7 +707,7 @@ plain ol' Python and is guaranteed to be available. >>> import builtins >>> tests = doctest.DocTestFinder().find(builtins) - >>> 825 < len(tests) < 845 # approximate number of objects with docstrings + >>> 830 < len(tests) < 860 # approximate number of objects with docstrings True >>> real_tests = [t for t in tests if len(t.examples) > 0] >>> len(real_tests) # objects that actually have doctests @@ -742,15 +740,13 @@ class TestDocTestFinder(unittest.TestCase): def test_issue35753(self): # This import of `call` should trigger issue35753 when - # `support.run_doctest` is called due to unwrap failing, + # DocTestFinder.find() is called due to inspect.unwrap() failing, # however with a patched doctest this should succeed. from unittest.mock import call dummy_module = types.ModuleType("dummy") dummy_module.__dict__['inject_call'] = call - try: - support.run_doctest(dummy_module, verbosity=True) - except ValueError as e: - raise support.TestFailed("Doctest unwrap failed") from e + finder = doctest.DocTestFinder() + self.assertEqual(finder.find(dummy_module), []) def test_empty_namespace_package(self): pkg_name = 'doctest_empty_pkg' @@ -2811,6 +2807,8 @@ in it, and use a package hook to install a custom loader; on any platform, at least one of the line endings will raise a ValueError for inconsistent whitespace if doctest does not correctly do the newline conversion. + >>> from test.support import os_helper + >>> import shutil >>> dn = tempfile.mkdtemp() >>> pkg = os.path.join(dn, "doctest_testpkg") >>> os.mkdir(pkg) diff --git a/Lib/test/test_dtrace.py b/Lib/test/test_dtrace.py index 4b971dea..e1adf8e9 100644 --- a/Lib/test/test_dtrace.py +++ b/Lib/test/test_dtrace.py @@ -3,6 +3,7 @@ import os.path import re import subprocess import sys +import sysconfig import types import unittest @@ -173,6 +174,87 @@ class SystemTapOptimizedTests(TraceTests, unittest.TestCase): backend = SystemTapBackend() optimize_python = 2 +class CheckDtraceProbes(unittest.TestCase): + @classmethod + def setUpClass(cls): + if sysconfig.get_config_var('WITH_DTRACE'): + readelf_major_version, readelf_minor_version = cls.get_readelf_version() + if support.verbose: + print(f"readelf version: {readelf_major_version}.{readelf_minor_version}") + else: + raise unittest.SkipTest("CPython must be configured with the --with-dtrace option.") + + + @staticmethod + def get_readelf_version(): + try: + cmd = ["readelf", "--version"] + proc = subprocess.Popen( + cmd, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + universal_newlines=True, + ) + with proc: + version, stderr = proc.communicate() + + if proc.returncode: + raise Exception( + f"Command {' '.join(cmd)!r} failed " + f"with exit code {proc.returncode}: " + f"stdout={version!r} stderr={stderr!r}" + ) + except OSError: + raise unittest.SkipTest("Couldn't find readelf on the path") + + # Regex to parse: + # 'GNU readelf (GNU Binutils) 2.40.0\n' -> 2.40 + match = re.search(r"^(?:GNU) readelf.*?\b(\d+)\.(\d+)", version) + if match is None: + raise unittest.SkipTest(f"Unable to parse readelf version: {version}") + + return int(match.group(1)), int(match.group(2)) + + def get_readelf_output(self): + command = ["readelf", "-n", sys.executable] + stdout, _ = subprocess.Popen( + command, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + universal_newlines=True, + ).communicate() + return stdout + + def test_check_probes(self): + readelf_output = self.get_readelf_output() + + available_probe_names = [ + "Name: import__find__load__done", + "Name: import__find__load__start", + "Name: audit", + "Name: gc__start", + "Name: gc__done", + ] + + for probe_name in available_probe_names: + with self.subTest(probe_name=probe_name): + self.assertIn(probe_name, readelf_output) + + @unittest.expectedFailure + def test_missing_probes(self): + readelf_output = self.get_readelf_output() + + # Missing probes will be added in the future. + missing_probe_names = [ + "Name: function__entry", + "Name: function__return", + "Name: line", + ] + + for probe_name in missing_probe_names: + with self.subTest(probe_name=probe_name): + self.assertIn(probe_name, readelf_output) + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_dynamic.py b/Lib/test/test_dynamic.py index fee7718f..7e12d428 100644 --- a/Lib/test/test_dynamic.py +++ b/Lib/test/test_dynamic.py @@ -140,12 +140,14 @@ class RebindBuiltinsTests(unittest.TestCase): def __missing__(self, key): return int(key.removeprefix("_number_")) - code = "lambda: " + "+".join(f"_number_{i}" for i in range(1000)) - sum_1000 = eval(code, MyGlobals()) - expected = sum(range(1000)) + # Need more than 256 variables to use EXTENDED_ARGS + variables = 400 + code = "lambda: " + "+".join(f"_number_{i}" for i in range(variables)) + sum_func = eval(code, MyGlobals()) + expected = sum(range(variables)) # Warm up the the function for quickening (PEP 659) for _ in range(30): - self.assertEqual(sum_1000(), expected) + self.assertEqual(sum_func(), expected) class TestTracing(unittest.TestCase): diff --git a/Lib/test/test_eintr.py b/Lib/test/test_eintr.py index 52814780..49b15f1a 100644 --- a/Lib/test/test_eintr.py +++ b/Lib/test/test_eintr.py @@ -9,6 +9,7 @@ from test.support import script_helper class EINTRTests(unittest.TestCase): @unittest.skipUnless(hasattr(signal, "setitimer"), "requires setitimer()") + @support.requires_resource('walltime') def test_all(self): # Run the tester in a sub-process, to make sure there is only one # thread (for reliable signal delivery). diff --git a/Lib/test/test_email/data/msg_47.txt b/Lib/test/test_email/data/msg_47.txt new file mode 100644 index 00000000..bb48b47d --- /dev/null +++ b/Lib/test/test_email/data/msg_47.txt @@ -0,0 +1,14 @@ +Date: 01 Jan 2001 00:01+0000 +From: arthur@example.example +MIME-Version: 1.0 +Content-Type: multipart/mixed; boundary=foo + +--foo +Content-Type: text/plain +bar + +--foo +Content-Type: text/html +<html><body><p>baz</p></body></html> + +--foo-- \ No newline at end of file diff --git a/Lib/test/test_email/test_email.py b/Lib/test/test_email/test_email.py index ca821282..2a237095 100644 --- a/Lib/test/test_email/test_email.py +++ b/Lib/test/test_email/test_email.py @@ -7,7 +7,6 @@ import time import base64 import unittest import textwrap -import warnings from io import StringIO, BytesIO from itertools import chain @@ -39,13 +38,14 @@ from email import iterators from email import quoprimime from email import utils +from test import support from test.support import threading_helper from test.support.os_helper import unlink from test.test_email import openfile, TestEmailBase # These imports are documented to work, but we are testing them using a # different path, so we import them here just to make sure they are importable. -from email.parser import FeedParser, BytesFeedParser +from email.parser import FeedParser NL = '\n' EMPTYSTRING = '' @@ -3320,6 +3320,23 @@ Foo [('Al Person', 'aperson@dom.ain'), ('Bud Person', 'bperson@dom.ain')]) + def test_getaddresses_comma_in_name(self): + """GH-106669 regression test.""" + self.assertEqual( + utils.getaddresses( + [ + '"Bud, Person" <bperson@dom.ain>', + 'aperson@dom.ain (Al Person)', + '"Mariusz Felisiak" <to@example.com>', + ] + ), + [ + ('Bud, Person', 'bperson@dom.ain'), + ('Al Person', 'aperson@dom.ain'), + ('Mariusz Felisiak', 'to@example.com'), + ], + ) + def test_getaddresses_nasty(self): eq = self.assertEqual eq(utils.getaddresses(['foo: ;']), [('', '')]) @@ -3342,6 +3359,7 @@ Foo self.assertEqual(addrs[0][1], 'aperson@dom.ain') @threading_helper.requires_working_threading() + @support.requires_resource('cpu') def test_make_msgid_collisions(self): # Test make_msgid uniqueness, even with multiple threads class MsgidsThread(Thread): @@ -3696,6 +3714,16 @@ class TestParsers(TestEmailBase): self.assertIsInstance(msg.get_payload(), str) self.assertIsInstance(msg.get_payload(decode=True), bytes) + def test_header_parser_multipart_is_valid(self): + # Don't flag valid multipart emails as having defects + with openfile('msg_47.txt', encoding="utf-8") as fp: + msgdata = fp.read() + + parser = email.parser.Parser(policy=email.policy.default) + parsed_msg = parser.parsestr(msgdata, headersonly=True) + + self.assertEqual(parsed_msg.defects, []) + def test_bytes_parser_does_not_close_file(self): with openfile('msg_02.txt', 'rb') as fp: email.parser.BytesParser().parse(fp) diff --git a/Lib/test/test_email/test_message.py b/Lib/test/test_email/test_message.py index 4c754bf4..d3f396f0 100644 --- a/Lib/test/test_email/test_message.py +++ b/Lib/test/test_email/test_message.py @@ -696,14 +696,16 @@ class TestEmailMessageBase: self.assertIsNone(part['Content-Disposition']) class _TestSetRaisingContentManager: + class CustomError(Exception): + pass def set_content(self, msg, content, *args, **kw): - raise Exception('test') + raise self.CustomError('test') def test_default_content_manager_for_add_comes_from_policy(self): cm = self._TestSetRaisingContentManager() m = self.message(policy=self.policy.clone(content_manager=cm)) for method in ('add_related', 'add_alternative', 'add_attachment'): - with self.assertRaises(Exception) as ar: + with self.assertRaises(self._TestSetRaisingContentManager.CustomError) as ar: getattr(m, method)('') self.assertEqual(str(ar.exception), 'test') diff --git a/Lib/test/test_email/test_utils.py b/Lib/test/test_email/test_utils.py index 78afb358..25fa48c5 100644 --- a/Lib/test/test_email/test_utils.py +++ b/Lib/test/test_email/test_utils.py @@ -83,14 +83,14 @@ class LocaltimeTests(unittest.TestCase): def test_localtime_daylight_true_dst_false(self): test.support.patch(self, time, 'daylight', True) t0 = datetime.datetime(2012, 3, 12, 1, 1) - t1 = utils.localtime(t0, isdst=-1) + t1 = utils.localtime(t0) t2 = utils.localtime(t1) self.assertEqual(t1, t2) def test_localtime_daylight_false_dst_false(self): test.support.patch(self, time, 'daylight', False) t0 = datetime.datetime(2012, 3, 12, 1, 1) - t1 = utils.localtime(t0, isdst=-1) + t1 = utils.localtime(t0) t2 = utils.localtime(t1) self.assertEqual(t1, t2) @@ -98,7 +98,7 @@ class LocaltimeTests(unittest.TestCase): def test_localtime_daylight_true_dst_true(self): test.support.patch(self, time, 'daylight', True) t0 = datetime.datetime(2012, 3, 12, 1, 1) - t1 = utils.localtime(t0, isdst=1) + t1 = utils.localtime(t0) t2 = utils.localtime(t1) self.assertEqual(t1, t2) @@ -106,7 +106,7 @@ class LocaltimeTests(unittest.TestCase): def test_localtime_daylight_false_dst_true(self): test.support.patch(self, time, 'daylight', False) t0 = datetime.datetime(2012, 3, 12, 1, 1) - t1 = utils.localtime(t0, isdst=1) + t1 = utils.localtime(t0) t2 = utils.localtime(t1) self.assertEqual(t1, t2) @@ -157,6 +157,11 @@ class LocaltimeTests(unittest.TestCase): t1 = utils.localtime(t0) self.assertEqual(t1.tzname(), 'EET') + def test_isdst_deprecation(self): + with self.assertWarns(DeprecationWarning): + t0 = datetime.datetime(1990, 1, 1) + t1 = utils.localtime(t0, isdst=True) + # Issue #24836: The timezone files are out of date (pre 2011k) # on Mac OS X Snow Leopard. @test.support.requires_mac_ver(10, 7) diff --git a/Lib/test/test_embed.py b/Lib/test/test_embed.py index 2affa17e..582392ec 100644 --- a/Lib/test/test_embed.py +++ b/Lib/test/test_embed.py @@ -2,6 +2,7 @@ from test import support from test.support import import_helper from test.support import os_helper +from test.support import requires_specialization import unittest from collections import namedtuple @@ -22,7 +23,6 @@ if not support.has_subprocess_support: MS_WINDOWS = (os.name == 'nt') MACOS = (sys.platform == 'darwin') -Py_DEBUG = hasattr(sys, 'gettotalrefcount') PYMEM_ALLOCATOR_NOT_SET = 0 PYMEM_ALLOCATOR_DEBUG = 2 PYMEM_ALLOCATOR_MALLOC = 3 @@ -110,7 +110,7 @@ class EmbeddingTestsMixin: print(f"--- {cmd} failed ---") print(f"stdout:\n{out}") print(f"stderr:\n{err}") - print(f"------") + print("------") self.assertEqual(p.returncode, returncode, "bad returncode %d, stderr is %r" % @@ -347,33 +347,38 @@ class EmbeddingTests(EmbeddingTestsMixin, unittest.TestCase): out, err = self.run_embedded_interpreter("test_repeated_simple_init") self.assertEqual(out, 'Finalized\n' * INIT_LOOPS) - def test_quickened_static_code_gets_unquickened_at_Py_FINALIZE(self): + @requires_specialization + def test_specialized_static_code_gets_unspecialized_at_Py_FINALIZE(self): # https://github.com/python/cpython/issues/92031 - # Do these imports outside of the code string to avoid using - # importlib too much from within the code string, so that - # _handle_fromlist doesn't get quickened until we intend it to. - from dis import _all_opmap - resume = _all_opmap["RESUME"] - resume_quick = _all_opmap["RESUME_QUICK"] - from test.test_dis import QUICKENING_WARMUP_DELAY - - code = textwrap.dedent(f"""\ + code = textwrap.dedent("""\ + import dis import importlib._bootstrap + import opcode + import test.test_dis + + def is_specialized(f): + for instruction in dis.get_instructions(f, adaptive=True): + opname = instruction.opname + if ( + opname in opcode._specialized_instructions + # Exclude superinstructions: + and "__" not in opname + ): + return True + return False + func = importlib._bootstrap._handle_fromlist - code = func.__code__ - # Assert initially unquickened. - # Use sets to account for byte order. - if set(code._co_code_adaptive[:2]) != set([{resume}, 0]): - raise AssertionError() + # "copy" the code to un-specialize it: + func.__code__ = func.__code__.replace() - for i in range({QUICKENING_WARMUP_DELAY}): + assert not is_specialized(func), "specialized instructions found" + + for i in range(test.test_dis.ADAPTIVE_WARMUP_DELAY): func(importlib._bootstrap, ["x"], lambda *args: None) - # Assert quickening worked - if set(code._co_code_adaptive[:2]) != set([{resume_quick}, 0]): - raise AssertionError() + assert is_specialized(func), "no specialized instructions found" print("Tests passed") """) @@ -441,8 +446,10 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): 'install_signal_handlers': 1, 'use_hash_seed': 0, 'hash_seed': 0, + 'int_max_str_digits': sys.int_info.default_max_str_digits, 'faulthandler': 0, 'tracemalloc': 0, + 'perf_profiling': 0, 'import_time': 0, 'code_debug_ranges': 1, 'show_ref_count': 0, @@ -501,8 +508,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): 'check_hash_pycs_mode': 'default', 'pathconfig_warnings': 1, '_init_main': 1, - '_isolated_interpreter': 0, - 'use_frozen_modules': not Py_DEBUG, + 'use_frozen_modules': not support.Py_DEBUG, 'safe_path': 0, '_is_python_build': IGNORE_CONFIG, } @@ -527,6 +533,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): use_hash_seed=0, faulthandler=0, tracemalloc=0, + perf_profiling=0, pathconfig_warnings=0, ) if MS_WINDOWS: @@ -837,6 +844,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): 'use_hash_seed': 1, 'hash_seed': 123, 'tracemalloc': 2, + 'perf_profiling': 0, 'import_time': 1, 'code_debug_ranges': 0, 'show_ref_count': 1, @@ -882,11 +890,10 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): 'platlibdir': 'my_platlibdir', 'module_search_paths': self.IGNORE_CONFIG, 'safe_path': 1, + 'int_max_str_digits': 31337, 'check_hash_pycs_mode': 'always', 'pathconfig_warnings': 0, - - '_isolated_interpreter': 1, } self.check_all_configs("test_init_from_config", config, preconfig, api=API_COMPAT) @@ -899,6 +906,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): 'use_hash_seed': 1, 'hash_seed': 42, 'tracemalloc': 2, + 'perf_profiling': 0, 'import_time': 1, 'code_debug_ranges': 0, 'malloc_stats': 1, @@ -917,6 +925,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): 'platlibdir': 'env_platlibdir', 'module_search_paths': self.IGNORE_CONFIG, 'safe_path': 1, + 'int_max_str_digits': 4567, } self.check_all_configs("test_init_compat_env", config, preconfig, api=API_COMPAT) @@ -930,6 +939,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): 'use_hash_seed': 1, 'hash_seed': 42, 'tracemalloc': 2, + 'perf_profiling': 0, 'import_time': 1, 'code_debug_ranges': 0, 'malloc_stats': 1, @@ -948,6 +958,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): 'platlibdir': 'env_platlibdir', 'module_search_paths': self.IGNORE_CONFIG, 'safe_path': 1, + 'int_max_str_digits': 4567, } self.check_all_configs("test_init_python_env", config, preconfig, api=API_PYTHON) @@ -1208,7 +1219,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): # The current getpath.c doesn't determine the stdlib dir # in this case. 'stdlib_dir': '', - 'use_frozen_modules': not Py_DEBUG, + 'use_frozen_modules': not support.Py_DEBUG, # overridden by PyConfig 'program_name': 'conf_program_name', 'base_executable': 'conf_executable', @@ -1502,12 +1513,12 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): config['base_prefix'] = pyvenv_home config['prefix'] = pyvenv_home config['stdlib_dir'] = os.path.join(pyvenv_home, 'Lib') - config['use_frozen_modules'] = int(not Py_DEBUG) + config['use_frozen_modules'] = int(not support.Py_DEBUG) else: # cannot reliably assume stdlib_dir here because it # depends too much on our build. But it ought to be found config['stdlib_dir'] = self.IGNORE_CONFIG - config['use_frozen_modules'] = int(not Py_DEBUG) + config['use_frozen_modules'] = int(not support.Py_DEBUG) env = self.copy_paths_by_env(config) self.check_all_configs("test_init_compat_config", config, @@ -1644,6 +1655,30 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase): self.check_all_configs("test_init_use_frozen_modules", config, api=API_PYTHON, env=env) + def test_init_main_interpreter_settings(self): + OBMALLOC = 1<<5 + EXTENSIONS = 1<<8 + THREADS = 1<<10 + DAEMON_THREADS = 1<<11 + FORK = 1<<15 + EXEC = 1<<16 + expected = { + # All optional features should be enabled. + 'feature_flags': + OBMALLOC | FORK | EXEC | THREADS | DAEMON_THREADS, + 'own_gil': True, + } + out, err = self.run_embedded_interpreter( + 'test_init_main_interpreter_settings', + ) + self.assertEqual(err, '') + try: + out = json.loads(out) + except json.JSONDecodeError: + self.fail(f'fail to decode stdout: {out!r}') + + self.assertEqual(out, expected) + class SetConfigTests(unittest.TestCase): def test_set_config(self): @@ -1740,7 +1775,7 @@ class MiscTests(EmbeddingTestsMixin, unittest.TestCase): """).lstrip() self.assertEqual(out, expected) - @unittest.skipUnless(hasattr(sys, 'gettotalrefcount'), + @unittest.skipUnless(support.Py_DEBUG, '-X showrefcount requires a Python debug build') def test_no_memleak(self): # bpo-1635741: Python must release all memory at exit diff --git a/Lib/test/test_ensurepip.py b/Lib/test/test_ensurepip.py index bfca0cd7..69ab2a4f 100644 --- a/Lib/test/test_ensurepip.py +++ b/Lib/test/test_ensurepip.py @@ -20,7 +20,6 @@ class TestPackages(unittest.TestCase): # Test version() with tempfile.TemporaryDirectory() as tmpdir: self.touch(tmpdir, "pip-1.2.3b1-py2.py3-none-any.whl") - self.touch(tmpdir, "setuptools-49.1.3-py3-none-any.whl") with (unittest.mock.patch.object(ensurepip, '_PACKAGES', None), unittest.mock.patch.object(ensurepip, '_WHEEL_PKG_DIR', tmpdir)): self.assertEqual(ensurepip.version(), '1.2.3b1') @@ -36,15 +35,12 @@ class TestPackages(unittest.TestCase): # use bundled wheel packages self.assertIsNotNone(packages['pip'].wheel_name) - self.assertIsNotNone(packages['setuptools'].wheel_name) def test_get_packages_with_dir(self): # Test _get_packages() with a wheel package directory - setuptools_filename = "setuptools-49.1.3-py3-none-any.whl" pip_filename = "pip-20.2.2-py2.py3-none-any.whl" with tempfile.TemporaryDirectory() as tmpdir: - self.touch(tmpdir, setuptools_filename) self.touch(tmpdir, pip_filename) # not used, make sure that it's ignored self.touch(tmpdir, "wheel-0.34.2-py2.py3-none-any.whl") @@ -53,15 +49,12 @@ class TestPackages(unittest.TestCase): unittest.mock.patch.object(ensurepip, '_WHEEL_PKG_DIR', tmpdir)): packages = ensurepip._get_packages() - self.assertEqual(packages['setuptools'].version, '49.1.3') - self.assertEqual(packages['setuptools'].wheel_path, - os.path.join(tmpdir, setuptools_filename)) self.assertEqual(packages['pip'].version, '20.2.2') self.assertEqual(packages['pip'].wheel_path, os.path.join(tmpdir, pip_filename)) # wheel package is ignored - self.assertEqual(sorted(packages), ['pip', 'setuptools']) + self.assertEqual(sorted(packages), ['pip']) class EnsurepipMixin: @@ -92,13 +85,13 @@ class TestBootstrap(EnsurepipMixin, unittest.TestCase): self.run_pip.assert_called_once_with( [ "install", "--no-cache-dir", "--no-index", "--find-links", - unittest.mock.ANY, "setuptools", "pip", + unittest.mock.ANY, "pip", ], unittest.mock.ANY, ) additional_paths = self.run_pip.call_args[0][1] - self.assertEqual(len(additional_paths), 2) + self.assertEqual(len(additional_paths), 1) def test_bootstrapping_with_root(self): ensurepip.bootstrap(root="/foo/bar/") @@ -107,7 +100,7 @@ class TestBootstrap(EnsurepipMixin, unittest.TestCase): [ "install", "--no-cache-dir", "--no-index", "--find-links", unittest.mock.ANY, "--root", "/foo/bar/", - "setuptools", "pip", + "pip", ], unittest.mock.ANY, ) @@ -118,7 +111,7 @@ class TestBootstrap(EnsurepipMixin, unittest.TestCase): self.run_pip.assert_called_once_with( [ "install", "--no-cache-dir", "--no-index", "--find-links", - unittest.mock.ANY, "--user", "setuptools", "pip", + unittest.mock.ANY, "--user", "pip", ], unittest.mock.ANY, ) @@ -129,7 +122,7 @@ class TestBootstrap(EnsurepipMixin, unittest.TestCase): self.run_pip.assert_called_once_with( [ "install", "--no-cache-dir", "--no-index", "--find-links", - unittest.mock.ANY, "--upgrade", "setuptools", "pip", + unittest.mock.ANY, "--upgrade", "pip", ], unittest.mock.ANY, ) @@ -140,7 +133,7 @@ class TestBootstrap(EnsurepipMixin, unittest.TestCase): self.run_pip.assert_called_once_with( [ "install", "--no-cache-dir", "--no-index", "--find-links", - unittest.mock.ANY, "-v", "setuptools", "pip", + unittest.mock.ANY, "-v", "pip", ], unittest.mock.ANY, ) @@ -151,7 +144,7 @@ class TestBootstrap(EnsurepipMixin, unittest.TestCase): self.run_pip.assert_called_once_with( [ "install", "--no-cache-dir", "--no-index", "--find-links", - unittest.mock.ANY, "-vv", "setuptools", "pip", + unittest.mock.ANY, "-vv", "pip", ], unittest.mock.ANY, ) @@ -162,7 +155,7 @@ class TestBootstrap(EnsurepipMixin, unittest.TestCase): self.run_pip.assert_called_once_with( [ "install", "--no-cache-dir", "--no-index", "--find-links", - unittest.mock.ANY, "-vvv", "setuptools", "pip", + unittest.mock.ANY, "-vvv", "pip", ], unittest.mock.ANY, ) @@ -239,7 +232,6 @@ class TestUninstall(EnsurepipMixin, unittest.TestCase): self.run_pip.assert_called_once_with( [ "uninstall", "-y", "--disable-pip-version-check", "pip", - "setuptools", ] ) @@ -250,7 +242,6 @@ class TestUninstall(EnsurepipMixin, unittest.TestCase): self.run_pip.assert_called_once_with( [ "uninstall", "-y", "--disable-pip-version-check", "-v", "pip", - "setuptools", ] ) @@ -261,7 +252,6 @@ class TestUninstall(EnsurepipMixin, unittest.TestCase): self.run_pip.assert_called_once_with( [ "uninstall", "-y", "--disable-pip-version-check", "-vv", "pip", - "setuptools", ] ) @@ -272,7 +262,7 @@ class TestUninstall(EnsurepipMixin, unittest.TestCase): self.run_pip.assert_called_once_with( [ "uninstall", "-y", "--disable-pip-version-check", "-vvv", - "pip", "setuptools", + "pip" ] ) @@ -312,13 +302,13 @@ class TestBootstrappingMainFunction(EnsurepipMixin, unittest.TestCase): self.run_pip.assert_called_once_with( [ "install", "--no-cache-dir", "--no-index", "--find-links", - unittest.mock.ANY, "setuptools", "pip", + unittest.mock.ANY, "pip", ], unittest.mock.ANY, ) additional_paths = self.run_pip.call_args[0][1] - self.assertEqual(len(additional_paths), 2) + self.assertEqual(len(additional_paths), 1) self.assertEqual(exit_code, 0) def test_bootstrapping_error_code(self): @@ -344,7 +334,6 @@ class TestUninstallationMainFunction(EnsurepipMixin, unittest.TestCase): self.run_pip.assert_called_once_with( [ "uninstall", "-y", "--disable-pip-version-check", "pip", - "setuptools", ] ) diff --git a/Lib/test/test_enum.py b/Lib/test/test_enum.py index 0143e859..14f16f7f 100644 --- a/Lib/test/test_enum.py +++ b/Lib/test/test_enum.py @@ -11,7 +11,7 @@ import typing import builtins as bltns from collections import OrderedDict from datetime import date -from enum import Enum, IntEnum, StrEnum, EnumType, Flag, IntFlag, unique, auto +from enum import Enum, EnumMeta, IntEnum, StrEnum, EnumType, Flag, IntFlag, unique, auto from enum import STRICT, CONFORM, EJECT, KEEP, _simple_enum, _test_simple_enum from enum import verify, UNIQUE, CONTINUOUS, NAMED_FLAGS, ReprEnum from enum import member, nonmember, _iter_bits_lsb @@ -20,7 +20,6 @@ from pickle import dumps, loads, PicklingError, HIGHEST_PROTOCOL from test import support from test.support import ALWAYS_EQ from test.support import threading_helper -from textwrap import dedent from datetime import timedelta python_version = sys.version_info[:2] @@ -32,6 +31,11 @@ def load_tests(loader, tests, ignore): '../../Doc/library/enum.rst', optionflags=doctest.ELLIPSIS|doctest.NORMALIZE_WHITESPACE, )) + if os.path.exists('Doc/howto/enum.rst'): + tests.addTests(doctest.DocFileSuite( + '../../Doc/howto/enum.rst', + optionflags=doctest.ELLIPSIS|doctest.NORMALIZE_WHITESPACE, + )) return tests MODULE = __name__ @@ -67,6 +71,7 @@ try: LARRY = 1 CURLY = 2 MOE = 4 + BIG = 389 except Exception as exc: FlagStooges = exc @@ -75,17 +80,20 @@ class FlagStoogesWithZero(Flag): LARRY = 1 CURLY = 2 MOE = 4 + BIG = 389 class IntFlagStooges(IntFlag): LARRY = 1 CURLY = 2 MOE = 4 + BIG = 389 class IntFlagStoogesWithZero(IntFlag): NOFLAG = 0 LARRY = 1 CURLY = 2 MOE = 4 + BIG = 389 # for pickle test and subclass tests class Name(StrEnum): @@ -228,11 +236,83 @@ class _EnumTests: values = None def setUp(self): - class BaseEnum(self.enum_type): + if self.__class__.__name__[-5:] == 'Class': + class BaseEnum(self.enum_type): + @enum.property + def first(self): + return '%s is first!' % self.name + class MainEnum(BaseEnum): + first = auto() + second = auto() + third = auto() + if issubclass(self.enum_type, Flag): + dupe = 3 + else: + dupe = third + self.MainEnum = MainEnum + # + class NewStrEnum(self.enum_type): + def __str__(self): + return self.name.upper() + first = auto() + self.NewStrEnum = NewStrEnum + # + class NewFormatEnum(self.enum_type): + def __format__(self, spec): + return self.name.upper() + first = auto() + self.NewFormatEnum = NewFormatEnum + # + class NewStrFormatEnum(self.enum_type): + def __str__(self): + return self.name.title() + def __format__(self, spec): + return ''.join(reversed(self.name)) + first = auto() + self.NewStrFormatEnum = NewStrFormatEnum + # + class NewBaseEnum(self.enum_type): + def __str__(self): + return self.name.title() + def __format__(self, spec): + return ''.join(reversed(self.name)) + self.NewBaseEnum = NewBaseEnum + class NewSubEnum(NewBaseEnum): + first = auto() + self.NewSubEnum = NewSubEnum + # + class LazyGNV(self.enum_type): + def _generate_next_value_(name, start, last, values): + pass + self.LazyGNV = LazyGNV + # + class BusyGNV(self.enum_type): + @staticmethod + def _generate_next_value_(name, start, last, values): + pass + self.BusyGNV = BusyGNV + # + self.is_flag = False + self.names = ['first', 'second', 'third'] + if issubclass(MainEnum, StrEnum): + self.values = self.names + elif MainEnum._member_type_ is str: + self.values = ['1', '2', '3'] + elif issubclass(self.enum_type, Flag): + self.values = [1, 2, 4] + self.is_flag = True + self.dupe2 = MainEnum(5) + else: + self.values = self.values or [1, 2, 3] + # + if not getattr(self, 'source_values', False): + self.source_values = self.values + elif self.__class__.__name__[-8:] == 'Function': @enum.property def first(self): return '%s is first!' % self.name - class MainEnum(BaseEnum): + BaseEnum = self.enum_type('BaseEnum', {'first':first}) + # first = auto() second = auto() third = auto() @@ -240,52 +320,58 @@ class _EnumTests: dupe = 3 else: dupe = third - self.MainEnum = MainEnum - # - class NewStrEnum(self.enum_type): + self.MainEnum = MainEnum = BaseEnum('MainEnum', dict(first=first, second=second, third=third, dupe=dupe)) + # def __str__(self): return self.name.upper() first = auto() - self.NewStrEnum = NewStrEnum - # - class NewFormatEnum(self.enum_type): + self.NewStrEnum = self.enum_type('NewStrEnum', (('first',first),('__str__',__str__))) + # def __format__(self, spec): return self.name.upper() first = auto() - self.NewFormatEnum = NewFormatEnum - # - class NewStrFormatEnum(self.enum_type): + self.NewFormatEnum = self.enum_type('NewFormatEnum', [('first',first),('__format__',__format__)]) + # def __str__(self): return self.name.title() def __format__(self, spec): return ''.join(reversed(self.name)) first = auto() - self.NewStrFormatEnum = NewStrFormatEnum - # - class NewBaseEnum(self.enum_type): + self.NewStrFormatEnum = self.enum_type('NewStrFormatEnum', dict(first=first, __format__=__format__, __str__=__str__)) + # def __str__(self): return self.name.title() def __format__(self, spec): return ''.join(reversed(self.name)) - class NewSubEnum(NewBaseEnum): - first = auto() - self.NewSubEnum = NewSubEnum - # - self.is_flag = False - self.names = ['first', 'second', 'third'] - if issubclass(MainEnum, StrEnum): - self.values = self.names - elif MainEnum._member_type_ is str: - self.values = ['1', '2', '3'] - elif issubclass(self.enum_type, Flag): - self.values = [1, 2, 4] - self.is_flag = True - self.dupe2 = MainEnum(5) + self.NewBaseEnum = self.enum_type('NewBaseEnum', dict(__format__=__format__, __str__=__str__)) + self.NewSubEnum = self.NewBaseEnum('NewSubEnum', 'first') + # + def _generate_next_value_(name, start, last, values): + pass + self.LazyGNV = self.enum_type('LazyGNV', {'_generate_next_value_':_generate_next_value_}) + # + @staticmethod + def _generate_next_value_(name, start, last, values): + pass + self.BusyGNV = self.enum_type('BusyGNV', {'_generate_next_value_':_generate_next_value_}) + # + self.is_flag = False + self.names = ['first', 'second', 'third'] + if issubclass(MainEnum, StrEnum): + self.values = self.names + elif MainEnum._member_type_ is str: + self.values = ['1', '2', '3'] + elif issubclass(self.enum_type, Flag): + self.values = [1, 2, 4] + self.is_flag = True + self.dupe2 = MainEnum(5) + else: + self.values = self.values or [1, 2, 3] + # + if not getattr(self, 'source_values', False): + self.source_values = self.values else: - self.values = self.values or [1, 2, 3] - # - if not getattr(self, 'source_values', False): - self.source_values = self.values + raise ValueError('unknown enum style: %r' % self.__class__.__name__) def assertFormatIsValue(self, spec, member): self.assertEqual(spec.format(member), spec.format(member.value)) @@ -313,6 +399,17 @@ class _EnumTests: with self.assertRaises(AttributeError): del Season.SPRING.name + def test_bad_new_super(self): + with self.assertRaisesRegex( + TypeError, + 'has no members defined', + ): + class BadSuper(self.enum_type): + def __new__(cls, value): + obj = super().__new__(cls, value) + return obj + failed = 1 + def test_basics(self): TE = self.MainEnum if self.is_flag: @@ -364,19 +461,12 @@ class _EnumTests: with self.assertRaises(AttributeError): self.MainEnum.second = 'really first' - @unittest.skipIf( - python_version >= (3, 12), - '__contains__ now returns True/False for all inputs', - ) - def test_contains_er(self): + def test_contains_tf(self): MainEnum = self.MainEnum - self.assertIn(MainEnum.third, MainEnum) - with self.assertRaises(TypeError): - with self.assertWarns(DeprecationWarning): - self.source_values[1] in MainEnum - with self.assertRaises(TypeError): - with self.assertWarns(DeprecationWarning): - 'first' in MainEnum + self.assertIn(MainEnum.first, MainEnum) + self.assertTrue(self.values[0] in MainEnum) + if type(self) not in (TestStrEnumClass, TestStrEnumFunction): + self.assertFalse('first' in MainEnum) val = MainEnum.dupe self.assertIn(val, MainEnum) # @@ -384,23 +474,43 @@ class _EnumTests: one = auto() two = auto() self.assertNotIn(OtherEnum.two, MainEnum) - - @unittest.skipIf( - python_version < (3, 12), - '__contains__ works only with enum memmbers before 3.12', - ) - def test_contains_tf(self): + # + if MainEnum._member_type_ is object: + # enums without mixed data types will always be False + class NotEqualEnum(self.enum_type): + this = self.source_values[0] + that = self.source_values[1] + self.assertNotIn(NotEqualEnum.this, MainEnum) + self.assertNotIn(NotEqualEnum.that, MainEnum) + else: + # enums with mixed data types may be True + class EqualEnum(self.enum_type): + this = self.source_values[0] + that = self.source_values[1] + self.assertIn(EqualEnum.this, MainEnum) + self.assertIn(EqualEnum.that, MainEnum) + + def test_contains_same_name_diff_enum_diff_values(self): MainEnum = self.MainEnum - self.assertIn(MainEnum.first, MainEnum) - self.assertTrue(self.source_values[0] in MainEnum) - self.assertFalse('first' in MainEnum) - val = MainEnum.dupe - self.assertIn(val, MainEnum) # class OtherEnum(Enum): - one = auto() - two = auto() - self.assertNotIn(OtherEnum.two, MainEnum) + first = "brand" + second = "new" + third = "values" + # + self.assertIn(MainEnum.first, MainEnum) + self.assertIn(MainEnum.second, MainEnum) + self.assertIn(MainEnum.third, MainEnum) + self.assertNotIn(MainEnum.first, OtherEnum) + self.assertNotIn(MainEnum.second, OtherEnum) + self.assertNotIn(MainEnum.third, OtherEnum) + # + self.assertIn(OtherEnum.first, OtherEnum) + self.assertIn(OtherEnum.second, OtherEnum) + self.assertIn(OtherEnum.third, OtherEnum) + self.assertNotIn(OtherEnum.first, MainEnum) + self.assertNotIn(OtherEnum.second, MainEnum) + self.assertNotIn(OtherEnum.third, MainEnum) def test_dir_on_class(self): TE = self.MainEnum @@ -450,10 +560,20 @@ class _EnumTests: self.assertTrue('description' not in dir(SubEnum)) self.assertTrue('description' in dir(SubEnum.sample), dir(SubEnum.sample)) + def test_empty_enum_has_no_values(self): + with self.assertRaisesRegex(TypeError, "<.... 'NewBaseEnum'> has no members"): + self.NewBaseEnum(7) + def test_enum_in_enum_out(self): Main = self.MainEnum self.assertIs(Main(Main.first), Main.first) + def test_gnv_is_static(self): + lazy = self.LazyGNV + busy = self.BusyGNV + self.assertTrue(type(lazy.__dict__['_generate_next_value_']) is staticmethod) + self.assertTrue(type(busy.__dict__['_generate_next_value_']) is staticmethod) + def test_hash(self): MainEnum = self.MainEnum mapping = {} @@ -632,6 +752,13 @@ class _EnumTests: theother = auto() self.assertEqual(repr(MySubEnum.that), "My name is that.") + def test_multiple_superclasses_repr(self): + class _EnumSuperClass(metaclass=EnumMeta): + pass + class E(_EnumSuperClass, Enum): + A = 1 + self.assertEqual(repr(E.A), "<E.A: 1>") + def test_reversed_iteration_order(self): self.assertEqual( list(reversed(self.MainEnum)), @@ -759,9 +886,17 @@ class _MinimalOutputTests: TE = self.MainEnum copied = copy.copy(TE) self.assertEqual(copied, TE) + self.assertIs(copied, TE) deep = copy.deepcopy(TE) self.assertEqual(deep, TE) + self.assertIs(deep, TE) + def test_copy_member(self): + TE = self.MainEnum + copied = copy.copy(TE.first) + self.assertIs(copied, TE.first) + deep = copy.deepcopy(TE.first) + self.assertIs(deep, TE.first) class _FlagTests: @@ -773,80 +908,275 @@ class _FlagTests: self.MainEnum('RED') self.assertIs(ctx.exception.__context__, None) -class TestPlainEnum(_EnumTests, _PlainOutputTests, unittest.TestCase): + def test_closed_invert_expectations(self): + class ClosedAB(self.enum_type): + A = 1 + B = 2 + MASK = 3 + A, B = ClosedAB + AB_MASK = ClosedAB.MASK + # + self.assertIs(~A, B) + self.assertIs(~B, A) + self.assertIs(~(A|B), ClosedAB(0)) + self.assertIs(~AB_MASK, ClosedAB(0)) + self.assertIs(~ClosedAB(0), (A|B)) + # + class ClosedXYZ(self.enum_type): + X = 4 + Y = 2 + Z = 1 + MASK = 7 + X, Y, Z = ClosedXYZ + XYZ_MASK = ClosedXYZ.MASK + # + self.assertIs(~X, Y|Z) + self.assertIs(~Y, X|Z) + self.assertIs(~Z, X|Y) + self.assertIs(~(X|Y), Z) + self.assertIs(~(X|Z), Y) + self.assertIs(~(Y|Z), X) + self.assertIs(~(X|Y|Z), ClosedXYZ(0)) + self.assertIs(~XYZ_MASK, ClosedXYZ(0)) + self.assertIs(~ClosedXYZ(0), (X|Y|Z)) + + def test_open_invert_expectations(self): + class OpenAB(self.enum_type): + A = 1 + B = 2 + MASK = 255 + A, B = OpenAB + AB_MASK = OpenAB.MASK + # + if OpenAB._boundary_ in (EJECT, KEEP): + self.assertIs(~A, OpenAB(254)) + self.assertIs(~B, OpenAB(253)) + self.assertIs(~(A|B), OpenAB(252)) + self.assertIs(~AB_MASK, OpenAB(0)) + self.assertIs(~OpenAB(0), AB_MASK) + else: + self.assertIs(~A, B) + self.assertIs(~B, A) + self.assertIs(~(A|B), OpenAB(0)) + self.assertIs(~AB_MASK, OpenAB(0)) + self.assertIs(~OpenAB(0), (A|B)) + # + class OpenXYZ(self.enum_type): + X = 4 + Y = 2 + Z = 1 + MASK = 31 + X, Y, Z = OpenXYZ + XYZ_MASK = OpenXYZ.MASK + # + if OpenXYZ._boundary_ in (EJECT, KEEP): + self.assertIs(~X, OpenXYZ(27)) + self.assertIs(~Y, OpenXYZ(29)) + self.assertIs(~Z, OpenXYZ(30)) + self.assertIs(~(X|Y), OpenXYZ(25)) + self.assertIs(~(X|Z), OpenXYZ(26)) + self.assertIs(~(Y|Z), OpenXYZ(28)) + self.assertIs(~(X|Y|Z), OpenXYZ(24)) + self.assertIs(~XYZ_MASK, OpenXYZ(0)) + self.assertTrue(~OpenXYZ(0), XYZ_MASK) + else: + self.assertIs(~X, Y|Z) + self.assertIs(~Y, X|Z) + self.assertIs(~Z, X|Y) + self.assertIs(~(X|Y), Z) + self.assertIs(~(X|Z), Y) + self.assertIs(~(Y|Z), X) + self.assertIs(~(X|Y|Z), OpenXYZ(0)) + self.assertIs(~XYZ_MASK, OpenXYZ(0)) + self.assertTrue(~OpenXYZ(0), (X|Y|Z)) + + +class TestPlainEnumClass(_EnumTests, _PlainOutputTests, unittest.TestCase): + enum_type = Enum + + +class TestPlainEnumFunction(_EnumTests, _PlainOutputTests, unittest.TestCase): enum_type = Enum -class TestPlainFlag(_EnumTests, _PlainOutputTests, _FlagTests, unittest.TestCase): +class TestPlainFlagClass(_EnumTests, _PlainOutputTests, _FlagTests, unittest.TestCase): enum_type = Flag -class TestIntEnum(_EnumTests, _MinimalOutputTests, unittest.TestCase): +class TestPlainFlagFunction(_EnumTests, _PlainOutputTests, _FlagTests, unittest.TestCase): + enum_type = Flag + + +class TestIntEnumClass(_EnumTests, _MinimalOutputTests, unittest.TestCase): enum_type = IntEnum + # + def test_shadowed_attr(self): + class Number(IntEnum): + divisor = 1 + numerator = 2 + # + self.assertEqual(Number.divisor.numerator, 1) + self.assertIs(Number.numerator.divisor, Number.divisor) + + +class TestIntEnumFunction(_EnumTests, _MinimalOutputTests, unittest.TestCase): + enum_type = IntEnum + # + def test_shadowed_attr(self): + Number = IntEnum('Number', ('divisor', 'numerator')) + # + self.assertEqual(Number.divisor.numerator, 1) + self.assertIs(Number.numerator.divisor, Number.divisor) -class TestStrEnum(_EnumTests, _MinimalOutputTests, unittest.TestCase): +class TestStrEnumClass(_EnumTests, _MinimalOutputTests, unittest.TestCase): enum_type = StrEnum + # + def test_shadowed_attr(self): + class Book(StrEnum): + author = 'author' + title = 'title' + # + self.assertEqual(Book.author.title(), 'Author') + self.assertEqual(Book.title.title(), 'Title') + self.assertIs(Book.title.author, Book.author) + +class TestStrEnumFunction(_EnumTests, _MinimalOutputTests, unittest.TestCase): + enum_type = StrEnum + # + def test_shadowed_attr(self): + Book = StrEnum('Book', ('author', 'title')) + # + self.assertEqual(Book.author.title(), 'Author') + self.assertEqual(Book.title.title(), 'Title') + self.assertIs(Book.title.author, Book.author) -class TestIntFlag(_EnumTests, _MinimalOutputTests, _FlagTests, unittest.TestCase): + +class TestIntFlagClass(_EnumTests, _MinimalOutputTests, _FlagTests, unittest.TestCase): enum_type = IntFlag -class TestMixedInt(_EnumTests, _MixedOutputTests, unittest.TestCase): +class TestIntFlagFunction(_EnumTests, _MinimalOutputTests, _FlagTests, unittest.TestCase): + enum_type = IntFlag + + +class TestMixedIntClass(_EnumTests, _MixedOutputTests, unittest.TestCase): class enum_type(int, Enum): pass -class TestMixedStr(_EnumTests, _MixedOutputTests, unittest.TestCase): +class TestMixedIntFunction(_EnumTests, _MixedOutputTests, unittest.TestCase): + enum_type = Enum('enum_type', type=int) + + +class TestMixedStrClass(_EnumTests, _MixedOutputTests, unittest.TestCase): class enum_type(str, Enum): pass -class TestMixedIntFlag(_EnumTests, _MixedOutputTests, _FlagTests, unittest.TestCase): +class TestMixedStrFunction(_EnumTests, _MixedOutputTests, unittest.TestCase): + enum_type = Enum('enum_type', type=str) + + +class TestMixedIntFlagClass(_EnumTests, _MixedOutputTests, _FlagTests, unittest.TestCase): class enum_type(int, Flag): pass -class TestMixedDate(_EnumTests, _MixedOutputTests, unittest.TestCase): +class TestMixedIntFlagFunction(_EnumTests, _MixedOutputTests, _FlagTests, unittest.TestCase): + enum_type = Flag('enum_type', type=int) + +class TestMixedDateClass(_EnumTests, _MixedOutputTests, unittest.TestCase): + # values = [date(2021, 12, 25), date(2020, 3, 15), date(2019, 11, 27)] source_values = [(2021, 12, 25), (2020, 3, 15), (2019, 11, 27)] - + # class enum_type(date, Enum): + @staticmethod def _generate_next_value_(name, start, count, last_values): values = [(2021, 12, 25), (2020, 3, 15), (2019, 11, 27)] return values[count] -class TestMinimalDate(_EnumTests, _MinimalOutputTests, unittest.TestCase): +class TestMixedDateFunction(_EnumTests, _MixedOutputTests, unittest.TestCase): + # + values = [date(2021, 12, 25), date(2020, 3, 15), date(2019, 11, 27)] + source_values = [(2021, 12, 25), (2020, 3, 15), (2019, 11, 27)] + # + # staticmethod decorator will be added by EnumType if not present + def _generate_next_value_(name, start, count, last_values): + values = [(2021, 12, 25), (2020, 3, 15), (2019, 11, 27)] + return values[count] + # + enum_type = Enum('enum_type', {'_generate_next_value_':_generate_next_value_}, type=date) + +class TestMinimalDateClass(_EnumTests, _MinimalOutputTests, unittest.TestCase): + # values = [date(2023, 12, 1), date(2016, 2, 29), date(2009, 1, 1)] source_values = [(2023, 12, 1), (2016, 2, 29), (2009, 1, 1)] - + # class enum_type(date, ReprEnum): + # staticmethod decorator will be added by EnumType if absent def _generate_next_value_(name, start, count, last_values): values = [(2023, 12, 1), (2016, 2, 29), (2009, 1, 1)] return values[count] -class TestMixedFloat(_EnumTests, _MixedOutputTests, unittest.TestCase): +class TestMinimalDateFunction(_EnumTests, _MinimalOutputTests, unittest.TestCase): + # + values = [date(2023, 12, 1), date(2016, 2, 29), date(2009, 1, 1)] + source_values = [(2023, 12, 1), (2016, 2, 29), (2009, 1, 1)] + # + @staticmethod + def _generate_next_value_(name, start, count, last_values): + values = [(2023, 12, 1), (2016, 2, 29), (2009, 1, 1)] + return values[count] + # + enum_type = ReprEnum('enum_type', {'_generate_next_value_':_generate_next_value_}, type=date) - values = [1.1, 2.2, 3.3] +class TestMixedFloatClass(_EnumTests, _MixedOutputTests, unittest.TestCase): + # + values = [1.1, 2.2, 3.3] + # class enum_type(float, Enum): def _generate_next_value_(name, start, count, last_values): values = [1.1, 2.2, 3.3] return values[count] -class TestMinimalFloat(_EnumTests, _MinimalOutputTests, unittest.TestCase): +class TestMixedFloatFunction(_EnumTests, _MixedOutputTests, unittest.TestCase): + # + values = [1.1, 2.2, 3.3] + # + def _generate_next_value_(name, start, count, last_values): + values = [1.1, 2.2, 3.3] + return values[count] + # + enum_type = Enum('enum_type', {'_generate_next_value_':_generate_next_value_}, type=float) - values = [4.4, 5.5, 6.6] +class TestMinimalFloatClass(_EnumTests, _MinimalOutputTests, unittest.TestCase): + # + values = [4.4, 5.5, 6.6] + # class enum_type(float, ReprEnum): def _generate_next_value_(name, start, count, last_values): values = [4.4, 5.5, 6.6] return values[count] +class TestMinimalFloatFunction(_EnumTests, _MinimalOutputTests, unittest.TestCase): + # + values = [4.4, 5.5, 6.6] + # + def _generate_next_value_(name, start, count, last_values): + values = [4.4, 5.5, 6.6] + return values[count] + # + enum_type = ReprEnum('enum_type', {'_generate_next_value_':_generate_next_value_}, type=float) + + class TestSpecial(unittest.TestCase): """ various operations that are not attributable to every possible enum @@ -1134,6 +1464,28 @@ class TestSpecial(unittest.TestCase): self.assertEqual(Huh.name.name, 'name') self.assertEqual(Huh.name.value, 1) + def test_contains_name_and_value_overlap(self): + class IntEnum1(IntEnum): + X = 1 + class IntEnum2(IntEnum): + X = 1 + class IntEnum3(IntEnum): + X = 2 + class IntEnum4(IntEnum): + Y = 1 + self.assertIn(IntEnum1.X, IntEnum1) + self.assertIn(IntEnum1.X, IntEnum2) + self.assertNotIn(IntEnum1.X, IntEnum3) + self.assertIn(IntEnum1.X, IntEnum4) + + def test_contains_different_types_same_members(self): + class IntEnum1(IntEnum): + X = 1 + class IntFlag1(IntFlag): + X = 1 + self.assertIn(IntEnum1.X, IntFlag1) + self.assertIn(IntFlag1.X, IntEnum1) + def test_inherited_data_type(self): class HexInt(int): __qualname__ = 'HexInt' @@ -1152,7 +1504,6 @@ class TestSpecial(unittest.TestCase): # class SillyInt(HexInt): __qualname__ = 'SillyInt' - pass class MyOtherEnum(SillyInt, enum.Enum): __qualname__ = 'MyOtherEnum' D = 4 @@ -1286,6 +1637,21 @@ class TestSpecial(unittest.TestCase): self.assertIn(e, MinorEnum) self.assertIs(type(e), MinorEnum) + def test_programmatic_function_is_value_call(self): + class TwoPart(Enum): + ONE = 1, 1.0 + TWO = 2, 2.0 + THREE = 3, 3.0 + self.assertRaisesRegex(ValueError, '1 is not a valid .*TwoPart', TwoPart, 1) + self.assertIs(TwoPart((1, 1.0)), TwoPart.ONE) + self.assertIs(TwoPart(1, 1.0), TwoPart.ONE) + class ThreePart(Enum): + ONE = 1, 1.0, 'one' + TWO = 2, 2.0, 'two' + THREE = 3, 3.0, 'three' + self.assertIs(ThreePart((3, 3.0, 'three')), ThreePart.THREE) + self.assertIs(ThreePart(3, 3.0, 'three'), ThreePart.THREE) + def test_intenum_from_bytes(self): self.assertIs(IntStooges.from_bytes(b'\x00\x03', 'big'), IntStooges.MOE) with self.assertRaises(ValueError): @@ -1314,7 +1680,6 @@ class TestSpecial(unittest.TestCase): class Huh(MyStr, MyInt, Enum): One = 1 - def test_pickle_enum(self): if isinstance(Stooges, Exception): raise Stooges @@ -1428,7 +1793,7 @@ class TestSpecial(unittest.TestCase): class EvenMoreColor(Color, IntEnum): chartruese = 7 # - with self.assertRaisesRegex(TypeError, "<enum .Foo.> cannot extend <enum .Color.>"): + with self.assertRaisesRegex(ValueError, r"\(.Foo., \(.pink., .black.\)\) is not a valid .*Color"): Color('Foo', ('pink', 'black')) def test_exclude_methods(self): @@ -1854,7 +2219,6 @@ class TestSpecial(unittest.TestCase): __qualname__ = 'NEI' x = ('the-x', 1) y = ('the-y', 2) - self.assertIs(NEI.__new__, Enum.__new__) self.assertEqual(repr(NEI.x + NEI.y), "NamedInt('(the-x + the-y)', 3)") globals()['NamedInt'] = NamedInt @@ -1862,6 +2226,10 @@ class TestSpecial(unittest.TestCase): NI5 = NamedInt('test', 5) self.assertEqual(NI5, 5) self.assertEqual(NEI.y.value, 2) + with self.assertRaisesRegex(TypeError, "name and value must be specified"): + test_pickle_dump_load(self.assertIs, NEI.y) + # fix pickle support and try again + NEI.__reduce_ex__ = enum.pickle_by_enum_name test_pickle_dump_load(self.assertIs, NEI.y) test_pickle_dump_load(self.assertIs, NEI) @@ -2615,14 +2983,15 @@ class TestSpecial(unittest.TestCase): self.assertEqual(Private._Private__corporal, 'Radar') self.assertEqual(Private._Private__major_, 'Hoolihan') - @unittest.skip("Accessing all values retained for performance reasons, see GH-93910") - def test_exception_for_member_from_member_access(self): - with self.assertRaisesRegex(AttributeError, "<enum .Di.> member has no attribute .NO."): - class Di(Enum): - YES = 1 - NO = 0 - nope = Di.YES.NO - + def test_member_from_member_access(self): + class Di(Enum): + YES = 1 + NO = 0 + name = 3 + warn = Di.YES.NO + self.assertIs(warn, Di.NO) + self.assertIs(Di.name, Di['name']) + self.assertEqual(Di.name.name, 'name') def test_dynamic_members_with_static_methods(self): # @@ -2653,20 +3022,69 @@ class TestSpecial(unittest.TestCase): def test_repr_with_dataclass(self): "ensure dataclass-mixin has correct repr()" - from dataclasses import dataclass - @dataclass + # + # check overridden dataclass __repr__ is used + # + from dataclasses import dataclass, field + @dataclass(repr=False) class Foo: __qualname__ = 'Foo' a: int + def __repr__(self): + return 'ha hah!' class Entries(Foo, Enum): ENTRY1 = 1 + self.assertEqual(repr(Entries.ENTRY1), '<Entries.ENTRY1: ha hah!>') + self.assertTrue(Entries.ENTRY1.value == Foo(1), Entries.ENTRY1.value) self.assertTrue(isinstance(Entries.ENTRY1, Foo)) self.assertTrue(Entries._member_type_ is Foo, Entries._member_type_) - self.assertTrue(Entries.ENTRY1.value == Foo(1), Entries.ENTRY1.value) - self.assertEqual(repr(Entries.ENTRY1), '<Entries.ENTRY1: Foo(a=1)>') - - def test_repr_with_init_data_type_mixin(self): - # non-data_type is a mixin that doesn't define __new__ + # + # check auto-generated dataclass __repr__ is not used + # + @dataclass + class CreatureDataMixin: + __qualname__ = 'CreatureDataMixin' + size: str + legs: int + tail: bool = field(repr=False, default=True) + class Creature(CreatureDataMixin, Enum): + __qualname__ = 'Creature' + BEETLE = ('small', 6) + DOG = ('medium', 4) + self.assertEqual(repr(Creature.DOG), "<Creature.DOG: size='medium', legs=4>") + # + # check inherited repr used + # + class Huh: + def __repr__(self): + return 'inherited' + @dataclass(repr=False) + class CreatureDataMixin(Huh): + __qualname__ = 'CreatureDataMixin' + size: str + legs: int + tail: bool = field(repr=False, default=True) + class Creature(CreatureDataMixin, Enum): + __qualname__ = 'Creature' + BEETLE = ('small', 6) + DOG = ('medium', 4) + self.assertEqual(repr(Creature.DOG), "<Creature.DOG: inherited>") + # + # check default object.__repr__ used if nothing provided + # + @dataclass(repr=False) + class CreatureDataMixin: + __qualname__ = 'CreatureDataMixin' + size: str + legs: int + tail: bool = field(repr=False, default=True) + class Creature(CreatureDataMixin, Enum): + __qualname__ = 'Creature' + BEETLE = ('small', 6) + DOG = ('medium', 4) + self.assertRegex(repr(Creature.DOG), "<Creature.DOG: .*CreatureDataMixin object at .*>") + + def test_repr_with_init_mixin(self): class Foo: def __init__(self, a): self.a = a @@ -2675,9 +3093,9 @@ class TestSpecial(unittest.TestCase): class Entries(Foo, Enum): ENTRY1 = 1 # - self.assertEqual(repr(Entries.ENTRY1), '<Entries.ENTRY1: Foo(a=1)>') + self.assertEqual(repr(Entries.ENTRY1), 'Foo(a=1)') - def test_repr_and_str_with_non_data_type_mixin(self): + def test_repr_and_str_with_no_init_mixin(self): # non-data_type is a mixin that doesn't define __new__ class Foo: def __repr__(self): @@ -2751,6 +3169,8 @@ class TestSpecial(unittest.TestCase): # a = ord('a') # + self.assertEqual(FlagFromChar._all_bits_, 316912650057057350374175801343) + self.assertEqual(FlagFromChar._flag_mask_, 158456325028528675187087900672) self.assertEqual(FlagFromChar.a, 158456325028528675187087900672) self.assertEqual(FlagFromChar.a|1, 158456325028528675187087900673) # @@ -2765,6 +3185,8 @@ class TestSpecial(unittest.TestCase): a = ord('a') z = 1 # + self.assertEqual(FlagFromChar._all_bits_, 316912650057057350374175801343) + self.assertEqual(FlagFromChar._flag_mask_, 158456325028528675187087900674) self.assertEqual(FlagFromChar.a.value, 158456325028528675187087900672) self.assertEqual((FlagFromChar.a|FlagFromChar.z).value, 158456325028528675187087900674) # @@ -2778,9 +3200,33 @@ class TestSpecial(unittest.TestCase): # a = ord('a') # + self.assertEqual(FlagFromChar._all_bits_, 316912650057057350374175801343) + self.assertEqual(FlagFromChar._flag_mask_, 158456325028528675187087900672) self.assertEqual(FlagFromChar.a, 158456325028528675187087900672) self.assertEqual(FlagFromChar.a|1, 158456325028528675187087900673) + def test_init_exception(self): + class Base: + def __new__(cls, *args): + return object.__new__(cls) + def __init__(self, x): + raise ValueError("I don't like", x) + with self.assertRaises(TypeError): + class MyEnum(Base, enum.Enum): + A = 'a' + def __init__(self, y): + self.y = y + with self.assertRaises(ValueError): + class MyEnum(Base, enum.Enum): + A = 'a' + def __init__(self, y): + self.y = y + def __new__(cls, value): + member = Base.__new__(cls) + member._value_ = Base(value) + return member + + class TestOrder(unittest.TestCase): "test usage of the `_order_` attribute" @@ -2910,22 +3356,6 @@ class OldTestFlag(unittest.TestCase): self.assertIs(Open.RO ^ Open.CE, Open.CE) self.assertIs(Open.CE ^ Open.CE, Open.RO) - def test_invert(self): - Perm = self.Perm - RW = Perm.R | Perm.W - RX = Perm.R | Perm.X - WX = Perm.W | Perm.X - RWX = Perm.R | Perm.W | Perm.X - values = list(Perm) + [RW, RX, WX, RWX, Perm(0)] - for i in values: - self.assertIs(type(~i), Perm) - self.assertEqual(~~i, i) - for i in Perm: - self.assertIs(~~i, i) - Open = self.Open - self.assertIs(Open.WO & ~Open.WO, Open.RO) - self.assertIs((Open.WO|Open.CE) & ~Open.WO, Open.CE) - def test_bool(self): Perm = self.Perm for f in Perm: @@ -2935,18 +3365,18 @@ class OldTestFlag(unittest.TestCase): self.assertEqual(bool(f.value), bool(f)) def test_boundary(self): - self.assertIs(enum.Flag._boundary_, CONFORM) - class Iron(Flag, boundary=STRICT): + self.assertIs(enum.Flag._boundary_, STRICT) + class Iron(Flag, boundary=CONFORM): ONE = 1 TWO = 2 EIGHT = 8 - self.assertIs(Iron._boundary_, STRICT) + self.assertIs(Iron._boundary_, CONFORM) # - class Water(Flag, boundary=CONFORM): + class Water(Flag, boundary=STRICT): ONE = 1 TWO = 2 EIGHT = 8 - self.assertIs(Water._boundary_, CONFORM) + self.assertIs(Water._boundary_, STRICT) # class Space(Flag, boundary=EJECT): ONE = 1 @@ -2959,10 +3389,10 @@ class OldTestFlag(unittest.TestCase): c = 4 d = 6 # - self.assertRaisesRegex(ValueError, 'invalid value 7', Iron, 7) + self.assertRaisesRegex(ValueError, 'invalid value 7', Water, 7) # - self.assertIs(Water(7), Water.ONE|Water.TWO) - self.assertIs(Water(~9), Water.TWO) + self.assertIs(Iron(7), Iron.ONE|Iron.TWO) + self.assertIs(Iron(~9), Iron.TWO) # self.assertEqual(Space(7), 7) self.assertTrue(type(Space(7)) is int) @@ -2970,6 +3400,31 @@ class OldTestFlag(unittest.TestCase): self.assertEqual(list(Bizarre), [Bizarre.c]) self.assertIs(Bizarre(3), Bizarre.b) self.assertIs(Bizarre(6), Bizarre.d) + # + class SkipFlag(enum.Flag): + A = 1 + B = 2 + C = 4 | B + # + self.assertTrue(SkipFlag.C in (SkipFlag.A|SkipFlag.C)) + self.assertRaisesRegex(ValueError, 'SkipFlag.. invalid value 42', SkipFlag, 42) + # + class SkipIntFlag(enum.IntFlag): + A = 1 + B = 2 + C = 4 | B + # + self.assertTrue(SkipIntFlag.C in (SkipIntFlag.A|SkipIntFlag.C)) + self.assertEqual(SkipIntFlag(42).value, 42) + # + class MethodHint(Flag): + HiddenText = 0x10 + DigitsOnly = 0x01 + LettersOnly = 0x02 + OnlyMask = 0x0f + # + self.assertEqual(str(MethodHint.HiddenText|MethodHint.OnlyMask), 'MethodHint.HiddenText|DigitsOnly|LettersOnly|OnlyMask') + def test_iter(self): Color = self.Color @@ -3061,11 +3516,17 @@ class OldTestFlag(unittest.TestCase): test_pickle_dump_load(self.assertEqual, FlagStooges.CURLY&~FlagStooges.CURLY) test_pickle_dump_load(self.assertIs, FlagStooges) + test_pickle_dump_load(self.assertEqual, FlagStooges.BIG) + test_pickle_dump_load(self.assertEqual, + FlagStooges.CURLY|FlagStooges.BIG) test_pickle_dump_load(self.assertIs, FlagStoogesWithZero.CURLY) test_pickle_dump_load(self.assertEqual, FlagStoogesWithZero.CURLY|FlagStoogesWithZero.MOE) test_pickle_dump_load(self.assertIs, FlagStoogesWithZero.NOFLAG) + test_pickle_dump_load(self.assertEqual, FlagStoogesWithZero.BIG) + test_pickle_dump_load(self.assertEqual, + FlagStoogesWithZero.CURLY|FlagStoogesWithZero.BIG) test_pickle_dump_load(self.assertIs, IntFlagStooges.CURLY) test_pickle_dump_load(self.assertEqual, @@ -3075,38 +3536,20 @@ class OldTestFlag(unittest.TestCase): test_pickle_dump_load(self.assertEqual, IntFlagStooges(0)) test_pickle_dump_load(self.assertEqual, IntFlagStooges(0x30)) test_pickle_dump_load(self.assertIs, IntFlagStooges) + test_pickle_dump_load(self.assertEqual, IntFlagStooges.BIG) + test_pickle_dump_load(self.assertEqual, IntFlagStooges.BIG|1) + test_pickle_dump_load(self.assertEqual, + IntFlagStooges.CURLY|IntFlagStooges.BIG) test_pickle_dump_load(self.assertIs, IntFlagStoogesWithZero.CURLY) test_pickle_dump_load(self.assertEqual, IntFlagStoogesWithZero.CURLY|IntFlagStoogesWithZero.MOE) test_pickle_dump_load(self.assertIs, IntFlagStoogesWithZero.NOFLAG) + test_pickle_dump_load(self.assertEqual, IntFlagStoogesWithZero.BIG) + test_pickle_dump_load(self.assertEqual, IntFlagStoogesWithZero.BIG|1) + test_pickle_dump_load(self.assertEqual, + IntFlagStoogesWithZero.CURLY|IntFlagStoogesWithZero.BIG) - @unittest.skipIf( - python_version >= (3, 12), - '__contains__ now returns True/False for all inputs', - ) - def test_contains_er(self): - Open = self.Open - Color = self.Color - self.assertFalse(Color.BLACK in Open) - self.assertFalse(Open.RO in Color) - with self.assertRaises(TypeError): - with self.assertWarns(DeprecationWarning): - 'BLACK' in Color - with self.assertRaises(TypeError): - with self.assertWarns(DeprecationWarning): - 'RO' in Open - with self.assertRaises(TypeError): - with self.assertWarns(DeprecationWarning): - 1 in Color - with self.assertRaises(TypeError): - with self.assertWarns(DeprecationWarning): - 1 in Open - - @unittest.skipIf( - python_version < (3, 12), - '__contains__ only works with enum memmbers before 3.12', - ) def test_contains_tf(self): Open = self.Open Color = self.Color @@ -3114,6 +3557,8 @@ class OldTestFlag(unittest.TestCase): self.assertFalse(Open.RO in Color) self.assertFalse('BLACK' in Color) self.assertFalse('RO' in Open) + self.assertTrue(Color.BLACK in Color) + self.assertTrue(Open.RO in Open) self.assertTrue(1 in Color) self.assertTrue(1 in Open) @@ -3653,41 +4098,11 @@ class OldTestIntFlag(unittest.TestCase): self.assertEqual(len(lst), len(Thing)) self.assertEqual(len(Thing), 0, Thing) - @unittest.skipIf( - python_version >= (3, 12), - '__contains__ now returns True/False for all inputs', - ) - def test_contains_er(self): - Open = self.Open - Color = self.Color - self.assertTrue(Color.GREEN in Color) - self.assertTrue(Open.RW in Open) - self.assertFalse(Color.GREEN in Open) - self.assertFalse(Open.RW in Color) - with self.assertRaises(TypeError): - with self.assertWarns(DeprecationWarning): - 'GREEN' in Color - with self.assertRaises(TypeError): - with self.assertWarns(DeprecationWarning): - 'RW' in Open - with self.assertRaises(TypeError): - with self.assertWarns(DeprecationWarning): - 2 in Color - with self.assertRaises(TypeError): - with self.assertWarns(DeprecationWarning): - 2 in Open - - @unittest.skipIf( - python_version < (3, 12), - '__contains__ only works with enum memmbers before 3.12', - ) def test_contains_tf(self): Open = self.Open Color = self.Color self.assertTrue(Color.GREEN in Color) self.assertTrue(Open.RW in Open) - self.assertTrue(Color.GREEN in Open) - self.assertTrue(Open.RW in Color) self.assertFalse('GREEN' in Color) self.assertFalse('RW' in Open) self.assertTrue(2 in Color) @@ -4117,11 +4532,14 @@ class TestInternals(unittest.TestCase): red = 'red' blue = 2 green = auto() + yellow = auto() - self.assertEqual(list(Color), [Color.red, Color.blue, Color.green]) + self.assertEqual(list(Color), + [Color.red, Color.blue, Color.green, Color.yellow]) self.assertEqual(Color.red.value, 'red') self.assertEqual(Color.blue.value, 2) self.assertEqual(Color.green.value, 3) + self.assertEqual(Color.yellow.value, 4) @unittest.skipIf( python_version < (3, 13), @@ -4239,55 +4657,55 @@ expected_help_output_with_docs = """\ Help on class Color in module %s: class Color(enum.Enum) - | Color(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None) - |\x20\x20 + | Color(*values) + | | Method resolution order: | Color | enum.Enum | builtins.object - |\x20\x20 + | | Data and other attributes defined here: - |\x20\x20 + | | CYAN = <Color.CYAN: 1> - |\x20\x20 + | | MAGENTA = <Color.MAGENTA: 2> - |\x20\x20 + | | YELLOW = <Color.YELLOW: 3> - |\x20\x20 + | | ---------------------------------------------------------------------- | Data descriptors inherited from enum.Enum: - |\x20\x20 + | | name | The name of the Enum member. - |\x20\x20 + | | value | The value of the Enum member. - |\x20\x20 + | | ---------------------------------------------------------------------- | Methods inherited from enum.EnumType: - |\x20\x20 - | __contains__(member) from enum.EnumType - | Return True if member is a member of this enum - | raises TypeError if member is not an enum member - |\x20\x20\x20\x20\x20\x20 - | note: in 3.12 TypeError will no longer be raised, and True will also be - | returned if member is the value of a member in this enum - |\x20\x20 + | + | __contains__(value) from enum.EnumType + | Return True if `value` is in `cls`. + | + | `value` is in `cls` if: + | 1) `value` is a member of `cls`, or + | 2) `value` is the value of one of the `cls`'s members. + | | __getitem__(name) from enum.EnumType | Return the member matching `name`. - |\x20\x20 + | | __iter__() from enum.EnumType | Return members in definition order. - |\x20\x20 + | | __len__() from enum.EnumType | Return the number of members (no aliases) - |\x20\x20 + | | ---------------------------------------------------------------------- | Readonly properties inherited from enum.EnumType: - |\x20\x20 + | | __members__ | Returns a mapping of member name->value. - |\x20\x20\x20\x20\x20\x20 + | | This mapping lists all enum members, including aliases. Note that this | is a read-only view of the internal mapping.""" @@ -4295,31 +4713,31 @@ expected_help_output_without_docs = """\ Help on class Color in module %s: class Color(enum.Enum) - | Color(value, names=None, *, module=None, qualname=None, type=None, start=1) - |\x20\x20 + | Color(*values) + | | Method resolution order: | Color | enum.Enum | builtins.object - |\x20\x20 + | | Data and other attributes defined here: - |\x20\x20 + | | YELLOW = <Color.YELLOW: 3> - |\x20\x20 + | | MAGENTA = <Color.MAGENTA: 2> - |\x20\x20 + | | CYAN = <Color.CYAN: 1> - |\x20\x20 + | | ---------------------------------------------------------------------- | Data descriptors inherited from enum.Enum: - |\x20\x20 + | | name - |\x20\x20 + | | value - |\x20\x20 + | | ---------------------------------------------------------------------- | Data descriptors inherited from enum.EnumType: - |\x20\x20 + | | __members__""" class TestStdLib(unittest.TestCase): @@ -4442,6 +4860,27 @@ class TestStdLib(unittest.TestCase): if failed: self.fail("result does not equal expected, see print above") + def test_inspect_signatures(self): + from inspect import signature, Signature, Parameter + self.assertEqual( + signature(Enum), + Signature([ + Parameter('new_class_name', Parameter.POSITIONAL_ONLY), + Parameter('names', Parameter.POSITIONAL_OR_KEYWORD), + Parameter('module', Parameter.KEYWORD_ONLY, default=None), + Parameter('qualname', Parameter.KEYWORD_ONLY, default=None), + Parameter('type', Parameter.KEYWORD_ONLY, default=None), + Parameter('start', Parameter.KEYWORD_ONLY, default=1), + Parameter('boundary', Parameter.KEYWORD_ONLY, default=None), + ]), + ) + self.assertEqual( + signature(enum.FlagBoundary), + Signature([ + Parameter('values', Parameter.VAR_POSITIONAL), + ]), + ) + def test_test_simple_enum(self): @_simple_enum(Enum) class SimpleColor: @@ -4500,15 +4939,14 @@ class MiscTestCase(unittest.TestCase): TWO = 2 self.assertEqual(Double.__doc__, None) - - def test_doc_1(self): + def test_doc_3(self): class Triple(Enum): ONE = 1 TWO = 2 THREE = 3 self.assertEqual(Triple.__doc__, None) - def test_doc_1(self): + def test_doc_4(self): class Quadruple(Enum): ONE = 1 TWO = 2 @@ -4546,11 +4984,6 @@ COMPLEX_C = 1j COMPLEX_A = 2j COMPLEX_B = 3j -class _ModuleWrapper: - """We use this class as a namespace for swapping modules.""" - def __init__(self, module): - self.__dict__.update(module.__dict__) - class TestConvert(unittest.TestCase): def tearDown(self): # Reset the module-level test variables to their original integer @@ -4590,12 +5023,6 @@ class TestConvert(unittest.TestCase): self.assertEqual(test_type.CONVERT_TEST_NAME_D, 5) self.assertEqual(test_type.CONVERT_TEST_NAME_E, 5) # Ensure that test_type only picked up names matching the filter. - int_dir = dir(int) + [ - 'CONVERT_TEST_NAME_A', 'CONVERT_TEST_NAME_B', 'CONVERT_TEST_NAME_C', - 'CONVERT_TEST_NAME_D', 'CONVERT_TEST_NAME_E', 'CONVERT_TEST_NAME_F', - 'CONVERT_TEST_SIGABRT', 'CONVERT_TEST_SIGIOT', - 'CONVERT_TEST_EIO', 'CONVERT_TEST_EBUS', - ] extra = [name for name in dir(test_type) if name not in enum_dir(test_type)] missing = [name for name in enum_dir(test_type) if name not in dir(test_type)] self.assertEqual( @@ -4637,7 +5064,6 @@ class TestConvert(unittest.TestCase): self.assertEqual(test_type.CONVERT_STR_TEST_1, 'hello') self.assertEqual(test_type.CONVERT_STR_TEST_2, 'goodbye') # Ensure that test_type only picked up names matching the filter. - str_dir = dir(str) + ['CONVERT_STR_TEST_1', 'CONVERT_STR_TEST_2'] extra = [name for name in dir(test_type) if name not in enum_dir(test_type)] missing = [name for name in enum_dir(test_type) if name not in dir(test_type)] self.assertEqual( @@ -4705,8 +5131,6 @@ def member_dir(member): allowed.add(name) return sorted(allowed) -missing = object() - if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_eof.py b/Lib/test/test_eof.py index abcbf046..be4fd73b 100644 --- a/Lib/test/test_eof.py +++ b/Lib/test/test_eof.py @@ -4,6 +4,7 @@ import sys from test import support from test.support import os_helper from test.support import script_helper +from test.support import warnings_helper import unittest class EOFTestCase(unittest.TestCase): @@ -36,10 +37,11 @@ class EOFTestCase(unittest.TestCase): rc, out, err = script_helper.assert_python_failure(file_name) self.assertIn(b'unterminated triple-quoted string literal (detected at line 3)', err) + @warnings_helper.ignore_warnings(category=SyntaxWarning) def test_eof_with_line_continuation(self): expect = "unexpected EOF while parsing (<string>, line 1)" try: - compile('"\\xhh" \\', '<string>', 'exec', dont_inherit=True) + compile('"\\Xhh" \\', '<string>', 'exec') except SyntaxError as msg: self.assertEqual(str(msg), expect) else: diff --git a/Lib/test/test_epoll.py b/Lib/test/test_epoll.py index b623852f..c94946a6 100644 --- a/Lib/test/test_epoll.py +++ b/Lib/test/test_epoll.py @@ -27,6 +27,7 @@ import select import socket import time import unittest +from test import support if not hasattr(select, "epoll"): raise unittest.SkipTest("test works only on Linux 2.6") @@ -186,10 +187,16 @@ class TestEPoll(unittest.TestCase): client.sendall(b"Hello!") server.sendall(b"world!!!") - now = time.monotonic() - events = ep.poll(1.0, 4) - then = time.monotonic() - self.assertFalse(then - now > 0.01) + # we might receive events one at a time, necessitating multiple calls to + # poll + events = [] + for _ in support.busy_retry(support.SHORT_TIMEOUT): + now = time.monotonic() + events += ep.poll(1.0, 4) + then = time.monotonic() + self.assertFalse(then - now > 0.01) + if len(events) >= 2: + break expected = [(client.fileno(), select.EPOLLIN | select.EPOLLOUT), (server.fileno(), select.EPOLLIN | select.EPOLLOUT)] diff --git a/Lib/test/test_except_star.py b/Lib/test/test_except_star.py index 9de72dbd..c49c6008 100644 --- a/Lib/test/test_except_star.py +++ b/Lib/test/test_except_star.py @@ -1,6 +1,7 @@ import sys import unittest import textwrap +from test.support.testcase import ExceptionIsLikeMixin class TestInvalidExceptStar(unittest.TestCase): def test_mixed_except_and_except_star_is_syntax_error(self): @@ -169,26 +170,7 @@ class TestBreakContinueReturnInExceptStarBlock(unittest.TestCase): self.assertIsInstance(exc, ExceptionGroup) -class ExceptStarTest(unittest.TestCase): - def assertExceptionIsLike(self, exc, template): - if exc is None and template is None: - return - - if template is None: - self.fail(f"unexpected exception: {exc}") - - if exc is None: - self.fail(f"expected an exception like {template!r}, got None") - - if not isinstance(exc, ExceptionGroup): - self.assertEqual(exc.__class__, template.__class__) - self.assertEqual(exc.args[0], template.args[0]) - else: - self.assertEqual(exc.message, template.message) - self.assertEqual(len(exc.exceptions), len(template.exceptions)) - for e, t in zip(exc.exceptions, template.exceptions): - self.assertExceptionIsLike(e, t) - +class ExceptStarTest(ExceptionIsLikeMixin, unittest.TestCase): def assertMetadataEqual(self, e1, e2): if e1 is None or e2 is None: self.assertTrue(e1 is None and e2 is None) @@ -208,44 +190,38 @@ class ExceptStarTest(unittest.TestCase): class TestExceptStarSplitSemantics(ExceptStarTest): def doSplitTestNamed(self, exc, T, match_template, rest_template): - initial_exc_info = sys.exc_info() - exc_info = match = rest = None + initial_sys_exception = sys.exception() + sys_exception = match = rest = None try: try: raise exc except* T as e: - exc_info = sys.exc_info() + sys_exception = sys.exception() match = e except BaseException as e: rest = e - if match_template: - self.assertEqual(exc_info[1], match) - else: - self.assertIsNone(exc_info) + self.assertEqual(sys_exception, match) self.assertExceptionIsLike(match, match_template) self.assertExceptionIsLike(rest, rest_template) - self.assertEqual(sys.exc_info(), initial_exc_info) + self.assertEqual(sys.exception(), initial_sys_exception) def doSplitTestUnnamed(self, exc, T, match_template, rest_template): - initial_exc_info = sys.exc_info() - exc_info = match = rest = None + initial_sys_exception = sys.exception() + sys_exception = match = rest = None try: try: raise exc except* T: - exc_info = sys.exc_info() - match = sys.exc_info()[1] + sys_exception = match = sys.exception() else: if rest_template: self.fail("Exception not raised") except BaseException as e: rest = e self.assertExceptionIsLike(match, match_template) - if match_template: - self.assertEqual(exc_info[0], type(match_template)) self.assertExceptionIsLike(rest, rest_template) - self.assertEqual(sys.exc_info(), initial_exc_info) + self.assertEqual(sys.exception(), initial_sys_exception) def doSplitTestInExceptHandler(self, exc, T, match_template, rest_template): try: @@ -409,11 +385,11 @@ class TestExceptStarSplitSemantics(ExceptStarTest): try: raise ExceptionGroup("mmu", [OSError("os"), BlockingIOError("io")]) except* BlockingIOError: - e = sys.exc_info()[1] + e = sys.exception() self.assertExceptionIsLike(e, ExceptionGroup("mmu", [BlockingIOError("io")])) except* OSError: - e = sys.exc_info()[1] + e = sys.exception() self.assertExceptionIsLike(e, ExceptionGroup("mmu", [OSError("os")])) else: @@ -434,7 +410,7 @@ class TestExceptStarSplitSemantics(ExceptStarTest): try: raise ExceptionGroup("fstu", [BlockingIOError("io")]) except* OSError: - e = sys.exc_info()[1] + e = sys.exception() self.assertExceptionIsLike(e, ExceptionGroup("fstu", [BlockingIOError("io")])) except* BlockingIOError: @@ -452,7 +428,7 @@ class TestExceptStarSplitSemantics(ExceptStarTest): pass else: self.fail("Exception not raised") - e = sys.exc_info()[1] + e = sys.exception() self.assertExceptionIsLike(e, ExceptionGroup("n", [BlockingIOError("io")])) else: @@ -642,18 +618,17 @@ class TestExceptStarRaise(ExceptStarTest): raise orig except* (TypeError, ValueError) as e: raise SyntaxError(3) - except BaseException as e: + except SyntaxError as e: exc = e - self.assertExceptionIsLike( - exc, ExceptionGroup("", [SyntaxError(3)])) + self.assertExceptionIsLike(exc, SyntaxError(3)) self.assertExceptionIsLike( - exc.exceptions[0].__context__, + exc.__context__, ExceptionGroup("eg", [TypeError(1), ValueError(2)])) self.assertMetadataNotEqual(orig, exc) - self.assertMetadataEqual(orig, exc.exceptions[0].__context__) + self.assertMetadataEqual(orig, exc.__context__) def test_raise_handle_all_raise_one_unnamed(self): orig = ExceptionGroup("eg", [TypeError(1), ValueError(2)]) @@ -662,18 +637,17 @@ class TestExceptStarRaise(ExceptStarTest): raise orig except* (TypeError, ValueError) as e: raise SyntaxError(3) - except ExceptionGroup as e: + except SyntaxError as e: exc = e - self.assertExceptionIsLike( - exc, ExceptionGroup("", [SyntaxError(3)])) + self.assertExceptionIsLike(exc, SyntaxError(3)) self.assertExceptionIsLike( - exc.exceptions[0].__context__, + exc.__context__, ExceptionGroup("eg", [TypeError(1), ValueError(2)])) self.assertMetadataNotEqual(orig, exc) - self.assertMetadataEqual(orig, exc.exceptions[0].__context__) + self.assertMetadataEqual(orig, exc.__context__) def test_raise_handle_all_raise_two_named(self): orig = ExceptionGroup("eg", [TypeError(1), ValueError(2)]) @@ -766,7 +740,7 @@ class TestExceptStarRaiseFrom(ExceptStarTest): try: raise orig except* OSError: - e = sys.exc_info()[1] + e = sys.exception() raise TypeError(3) from e except ExceptionGroup as e: exc = e @@ -797,23 +771,22 @@ class TestExceptStarRaiseFrom(ExceptStarTest): raise orig except* (TypeError, ValueError) as e: raise SyntaxError(3) from e - except BaseException as e: + except SyntaxError as e: exc = e - self.assertExceptionIsLike( - exc, ExceptionGroup("", [SyntaxError(3)])) + self.assertExceptionIsLike(exc, SyntaxError(3)) self.assertExceptionIsLike( - exc.exceptions[0].__context__, + exc.__context__, ExceptionGroup("eg", [TypeError(1), ValueError(2)])) self.assertExceptionIsLike( - exc.exceptions[0].__cause__, + exc.__cause__, ExceptionGroup("eg", [TypeError(1), ValueError(2)])) self.assertMetadataNotEqual(orig, exc) - self.assertMetadataEqual(orig, exc.exceptions[0].__context__) - self.assertMetadataEqual(orig, exc.exceptions[0].__cause__) + self.assertMetadataEqual(orig, exc.__context__) + self.assertMetadataEqual(orig, exc.__cause__) def test_raise_handle_all_raise_one_unnamed(self): orig = ExceptionGroup("eg", [TypeError(1), ValueError(2)]) @@ -821,25 +794,24 @@ class TestExceptStarRaiseFrom(ExceptStarTest): try: raise orig except* (TypeError, ValueError) as e: - e = sys.exc_info()[1] + e = sys.exception() raise SyntaxError(3) from e - except ExceptionGroup as e: + except SyntaxError as e: exc = e - self.assertExceptionIsLike( - exc, ExceptionGroup("", [SyntaxError(3)])) + self.assertExceptionIsLike(exc, SyntaxError(3)) self.assertExceptionIsLike( - exc.exceptions[0].__context__, + exc.__context__, ExceptionGroup("eg", [TypeError(1), ValueError(2)])) self.assertExceptionIsLike( - exc.exceptions[0].__cause__, + exc.__cause__, ExceptionGroup("eg", [TypeError(1), ValueError(2)])) self.assertMetadataNotEqual(orig, exc) - self.assertMetadataEqual(orig, exc.exceptions[0].__context__) - self.assertMetadataEqual(orig, exc.exceptions[0].__cause__) + self.assertMetadataEqual(orig, exc.__context__) + self.assertMetadataEqual(orig, exc.__cause__) def test_raise_handle_all_raise_two_named(self): orig = ExceptionGroup("eg", [TypeError(1), ValueError(2)]) @@ -882,10 +854,10 @@ class TestExceptStarRaiseFrom(ExceptStarTest): try: raise orig except* TypeError: - e = sys.exc_info()[1] + e = sys.exception() raise SyntaxError(3) from e except* ValueError: - e = sys.exc_info()[1] + e = sys.exception() raise SyntaxError(4) from e except ExceptionGroup as e: exc = e @@ -982,7 +954,7 @@ class TestExceptStarExceptionGroupSubclass(ExceptStarTest): class TestExceptStarCleanup(ExceptStarTest): - def test_exc_info_restored(self): + def test_sys_exception_restored(self): try: try: raise ValueError(42) @@ -997,7 +969,7 @@ class TestExceptStarCleanup(ExceptStarTest): self.assertExceptionIsLike(exc, ZeroDivisionError('division by zero')) self.assertExceptionIsLike(exc.__context__, ValueError(42)) - self.assertEqual(sys.exc_info(), (None, None, None)) + self.assertEqual(sys.exception(), None) class TestExceptStar_WeirdLeafExceptions(ExceptStarTest): diff --git a/Lib/test/test_exception_group.py b/Lib/test/test_exception_group.py index 7fb45462..22be3a77 100644 --- a/Lib/test/test_exception_group.py +++ b/Lib/test/test_exception_group.py @@ -1,8 +1,7 @@ import collections.abc -import traceback import types import unittest - +from test.support import C_RECURSION_LIMIT class TestExceptionGroupTypeHierarchy(unittest.TestCase): def test_exception_group_types(self): @@ -103,6 +102,20 @@ class InstanceCreation(unittest.TestCase): with self.assertRaisesRegex(TypeError, msg): MyEG("eg", [ValueError(12), KeyboardInterrupt(42)]) + def test_EG_and_specific_subclass_can_wrap_any_nonbase_exception(self): + class MyEG(ExceptionGroup, ValueError): + pass + + # The restriction is specific to Exception, not "the other base class" + MyEG("eg", [ValueError(12), Exception()]) + + def test_BEG_and_specific_subclass_can_wrap_any_nonbase_exception(self): + class MyEG(BaseExceptionGroup, ValueError): + pass + + # The restriction is specific to Exception, not "the other base class" + MyEG("eg", [ValueError(12), Exception()]) + def test_BEG_subclass_wraps_anything(self): class MyBEG(BaseExceptionGroup): @@ -420,7 +433,7 @@ class ExceptionGroupSplitTests(ExceptionGroupTestBase): class DeepRecursionInSplitAndSubgroup(unittest.TestCase): def make_deep_eg(self): e = TypeError(1) - for i in range(2000): + for i in range(C_RECURSION_LIMIT + 1): e = ExceptionGroup('eg', [e]) return e @@ -773,6 +786,18 @@ class NestedExceptionGroupSplitTest(ExceptionGroupSplitTestBase): self.assertFalse(hasattr(match, '__notes__')) self.assertFalse(hasattr(rest, '__notes__')) + def test_drive_invalid_return_value(self): + class MyEg(ExceptionGroup): + def derive(self, excs): + return 42 + + eg = MyEg('eg', [TypeError(1), ValueError(2)]) + msg = "derive must return an instance of BaseExceptionGroup" + with self.assertRaisesRegex(TypeError, msg): + eg.split(TypeError) + with self.assertRaisesRegex(TypeError, msg): + eg.subgroup(TypeError) + class NestedExceptionGroupSubclassSplitTest(ExceptionGroupSplitTestBase): diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py index d7133adf..72afb3b0 100644 --- a/Lib/test/test_exceptions.py +++ b/Lib/test/test_exceptions.py @@ -1,7 +1,6 @@ # Python test set -- part 5, built-in exceptions import copy -import gc import os import sys import unittest @@ -156,6 +155,7 @@ class ExceptionTests(unittest.TestCase): ckmsg(s, "'continue' not properly in loop") ckmsg("continue\n", "'continue' not properly in loop") + ckmsg("f'{6 0}'", "invalid syntax. Perhaps you forgot a comma?") def testSyntaxErrorMissingParens(self): def ckmsg(src, msg, exception=SyntaxError): @@ -228,7 +228,7 @@ class ExceptionTests(unittest.TestCase): check('Python = "\u1e54\xfd\u0163\u0125\xf2\xf1" +', 1, 20) check(b'# -*- coding: cp1251 -*-\nPython = "\xcf\xb3\xf2\xee\xed" +', 2, 19, encoding='cp1251') - check(b'Python = "\xcf\xb3\xf2\xee\xed" +', 1, 18) + check(b'Python = "\xcf\xb3\xf2\xee\xed" +', 1, 10) check('x = "a', 1, 5) check('lambda x: x = 2', 1, 1) check('f{a + b + c}', 1, 2) @@ -335,8 +335,7 @@ class ExceptionTests(unittest.TestCase): try: _testcapi.raise_exception(BadException, 1) except TypeError as err: - exc, err, tb = sys.exc_info() - co = tb.tb_frame.f_code + co = err.__traceback__.tb_frame.f_code self.assertEqual(co.co_name, "test_capi1") self.assertTrue(co.co_filename.endswith('test_exceptions.py')) else: @@ -347,7 +346,7 @@ class ExceptionTests(unittest.TestCase): try: _testcapi.raise_exception(BadException, 0) except RuntimeError as err: - exc, err, tb = sys.exc_info() + tb = err.__traceback__.tb_next co = tb.tb_frame.f_code self.assertEqual(co.co_name, "__init__") self.assertTrue(co.co_filename.endswith('test_exceptions.py')) @@ -361,10 +360,9 @@ class ExceptionTests(unittest.TestCase): self.assertRaises(SystemError, _testcapi.raise_exception, InvalidException, 1) - if not sys.platform.startswith('java'): - test_capi1() - test_capi2() - test_capi3() + test_capi1() + test_capi2() + test_capi3() def test_WindowsError(self): try: @@ -419,45 +417,45 @@ class ExceptionTests(unittest.TestCase): # test that exception attributes are happy exceptionList = [ - (BaseException, (), {'args' : ()}), - (BaseException, (1, ), {'args' : (1,)}), - (BaseException, ('foo',), + (BaseException, (), {}, {'args' : ()}), + (BaseException, (1, ), {}, {'args' : (1,)}), + (BaseException, ('foo',), {}, {'args' : ('foo',)}), - (BaseException, ('foo', 1), + (BaseException, ('foo', 1), {}, {'args' : ('foo', 1)}), - (SystemExit, ('foo',), + (SystemExit, ('foo',), {}, {'args' : ('foo',), 'code' : 'foo'}), - (OSError, ('foo',), + (OSError, ('foo',), {}, {'args' : ('foo',), 'filename' : None, 'filename2' : None, 'errno' : None, 'strerror' : None}), - (OSError, ('foo', 'bar'), + (OSError, ('foo', 'bar'), {}, {'args' : ('foo', 'bar'), 'filename' : None, 'filename2' : None, 'errno' : 'foo', 'strerror' : 'bar'}), - (OSError, ('foo', 'bar', 'baz'), + (OSError, ('foo', 'bar', 'baz'), {}, {'args' : ('foo', 'bar'), 'filename' : 'baz', 'filename2' : None, 'errno' : 'foo', 'strerror' : 'bar'}), - (OSError, ('foo', 'bar', 'baz', None, 'quux'), + (OSError, ('foo', 'bar', 'baz', None, 'quux'), {}, {'args' : ('foo', 'bar'), 'filename' : 'baz', 'filename2': 'quux'}), - (OSError, ('errnoStr', 'strErrorStr', 'filenameStr'), + (OSError, ('errnoStr', 'strErrorStr', 'filenameStr'), {}, {'args' : ('errnoStr', 'strErrorStr'), 'strerror' : 'strErrorStr', 'errno' : 'errnoStr', 'filename' : 'filenameStr'}), - (OSError, (1, 'strErrorStr', 'filenameStr'), + (OSError, (1, 'strErrorStr', 'filenameStr'), {}, {'args' : (1, 'strErrorStr'), 'errno' : 1, 'strerror' : 'strErrorStr', 'filename' : 'filenameStr', 'filename2' : None}), - (SyntaxError, (), {'msg' : None, 'text' : None, + (SyntaxError, (), {}, {'msg' : None, 'text' : None, 'filename' : None, 'lineno' : None, 'offset' : None, 'end_offset': None, 'print_file_and_line' : None}), - (SyntaxError, ('msgStr',), + (SyntaxError, ('msgStr',), {}, {'args' : ('msgStr',), 'text' : None, 'print_file_and_line' : None, 'msg' : 'msgStr', 'filename' : None, 'lineno' : None, 'offset' : None, 'end_offset': None}), (SyntaxError, ('msgStr', ('filenameStr', 'linenoStr', 'offsetStr', - 'textStr', 'endLinenoStr', 'endOffsetStr')), + 'textStr', 'endLinenoStr', 'endOffsetStr')), {}, {'offset' : 'offsetStr', 'text' : 'textStr', 'args' : ('msgStr', ('filenameStr', 'linenoStr', 'offsetStr', 'textStr', @@ -467,7 +465,7 @@ class ExceptionTests(unittest.TestCase): 'end_lineno': 'endLinenoStr', 'end_offset': 'endOffsetStr'}), (SyntaxError, ('msgStr', 'filenameStr', 'linenoStr', 'offsetStr', 'textStr', 'endLinenoStr', 'endOffsetStr', - 'print_file_and_lineStr'), + 'print_file_and_lineStr'), {}, {'text' : None, 'args' : ('msgStr', 'filenameStr', 'linenoStr', 'offsetStr', 'textStr', 'endLinenoStr', 'endOffsetStr', @@ -475,38 +473,40 @@ class ExceptionTests(unittest.TestCase): 'print_file_and_line' : None, 'msg' : 'msgStr', 'filename' : None, 'lineno' : None, 'offset' : None, 'end_lineno': None, 'end_offset': None}), - (UnicodeError, (), {'args' : (),}), + (UnicodeError, (), {}, {'args' : (),}), (UnicodeEncodeError, ('ascii', 'a', 0, 1, - 'ordinal not in range'), + 'ordinal not in range'), {}, {'args' : ('ascii', 'a', 0, 1, 'ordinal not in range'), 'encoding' : 'ascii', 'object' : 'a', 'start' : 0, 'reason' : 'ordinal not in range'}), (UnicodeDecodeError, ('ascii', bytearray(b'\xff'), 0, 1, - 'ordinal not in range'), + 'ordinal not in range'), {}, {'args' : ('ascii', bytearray(b'\xff'), 0, 1, 'ordinal not in range'), 'encoding' : 'ascii', 'object' : b'\xff', 'start' : 0, 'reason' : 'ordinal not in range'}), (UnicodeDecodeError, ('ascii', b'\xff', 0, 1, - 'ordinal not in range'), + 'ordinal not in range'), {}, {'args' : ('ascii', b'\xff', 0, 1, 'ordinal not in range'), 'encoding' : 'ascii', 'object' : b'\xff', 'start' : 0, 'reason' : 'ordinal not in range'}), - (UnicodeTranslateError, ("\u3042", 0, 1, "ouch"), + (UnicodeTranslateError, ("\u3042", 0, 1, "ouch"), {}, {'args' : ('\u3042', 0, 1, 'ouch'), 'object' : '\u3042', 'reason' : 'ouch', 'start' : 0, 'end' : 1}), - (NaiveException, ('foo',), + (NaiveException, ('foo',), {}, {'args': ('foo',), 'x': 'foo'}), - (SlottedNaiveException, ('foo',), + (SlottedNaiveException, ('foo',), {}, {'args': ('foo',), 'x': 'foo'}), + (AttributeError, ('foo',), dict(name='name', obj='obj'), + dict(args=('foo',), name='name', obj='obj')), ] try: # More tests are in test_WindowsError exceptionList.append( - (WindowsError, (1, 'strErrorStr', 'filenameStr'), + (WindowsError, (1, 'strErrorStr', 'filenameStr'), {}, {'args' : (1, 'strErrorStr'), 'strerror' : 'strErrorStr', 'winerror' : None, 'errno' : 1, @@ -515,11 +515,11 @@ class ExceptionTests(unittest.TestCase): except NameError: pass - for exc, args, expected in exceptionList: + for exc, args, kwargs, expected in exceptionList: try: - e = exc(*args) + e = exc(*args, **kwargs) except: - print("\nexc=%r, args=%r" % (exc, args), file=sys.stderr) + print(f"\nexc={exc!r}, args={args!r}", file=sys.stderr) # raise else: # Verify module name @@ -542,11 +542,39 @@ class ExceptionTests(unittest.TestCase): new = p.loads(s) for checkArgName in expected: got = repr(getattr(new, checkArgName)) - want = repr(expected[checkArgName]) + if exc == AttributeError and checkArgName == 'obj': + # See GH-103352, we're not pickling + # obj at this point. So verify it's None. + want = repr(None) + else: + want = repr(expected[checkArgName]) self.assertEqual(got, want, 'pickled "%r", attribute "%s' % (e, checkArgName)) + def test_setstate(self): + e = Exception(42) + e.blah = 53 + self.assertEqual(e.args, (42,)) + self.assertEqual(e.blah, 53) + self.assertRaises(AttributeError, getattr, e, 'a') + self.assertRaises(AttributeError, getattr, e, 'b') + e.__setstate__({'a': 1 , 'b': 2}) + self.assertEqual(e.args, (42,)) + self.assertEqual(e.blah, 53) + self.assertEqual(e.a, 1) + self.assertEqual(e.b, 2) + e.__setstate__({'a': 11, 'args': (1,2,3), 'blah': 35}) + self.assertEqual(e.args, (1,2,3)) + self.assertEqual(e.blah, 35) + self.assertEqual(e.a, 11) + self.assertEqual(e.b, 2) + + def test_invalid_setstate(self): + e = Exception(42) + with self.assertRaisesRegex(TypeError, "state is not a dictionary"): + e.__setstate__(42) + def test_notes(self): for e in [BaseException(1), Exception(2), ValueError(3)]: with self.subTest(e=e): @@ -577,8 +605,8 @@ class ExceptionTests(unittest.TestCase): def testWithTraceback(self): try: raise IndexError(4) - except: - tb = sys.exc_info()[2] + except Exception as e: + tb = e.__traceback__ e = BaseException().with_traceback(tb) self.assertIsInstance(e, BaseException) @@ -603,17 +631,36 @@ class ExceptionTests(unittest.TestCase): else: self.fail("No exception raised") - def testInvalidAttrs(self): - self.assertRaises(TypeError, setattr, Exception(), '__cause__', 1) - self.assertRaises(TypeError, delattr, Exception(), '__cause__') - self.assertRaises(TypeError, setattr, Exception(), '__context__', 1) - self.assertRaises(TypeError, delattr, Exception(), '__context__') + def test_invalid_setattr(self): + TE = TypeError + exc = Exception() + msg = "'int' object is not iterable" + self.assertRaisesRegex(TE, msg, setattr, exc, 'args', 1) + msg = "__traceback__ must be a traceback or None" + self.assertRaisesRegex(TE, msg, setattr, exc, '__traceback__', 1) + msg = "exception cause must be None or derive from BaseException" + self.assertRaisesRegex(TE, msg, setattr, exc, '__cause__', 1) + msg = "exception context must be None or derive from BaseException" + self.assertRaisesRegex(TE, msg, setattr, exc, '__context__', 1) + + def test_invalid_delattr(self): + TE = TypeError + try: + raise IndexError(4) + except Exception as e: + exc = e + + msg = "may not be deleted" + self.assertRaisesRegex(TE, msg, delattr, exc, 'args') + self.assertRaisesRegex(TE, msg, delattr, exc, '__traceback__') + self.assertRaisesRegex(TE, msg, delattr, exc, '__cause__') + self.assertRaisesRegex(TE, msg, delattr, exc, '__context__') def testNoneClearsTracebackAttr(self): try: raise IndexError(4) - except: - tb = sys.exc_info()[2] + except Exception as e: + tb = e.__traceback__ e = Exception() e.__traceback__ = tb @@ -847,28 +894,28 @@ class ExceptionTests(unittest.TestCase): try: raise KeyError("caught") except KeyError: - yield sys.exc_info()[0] - yield sys.exc_info()[0] - yield sys.exc_info()[0] + yield sys.exception() + yield sys.exception() + yield sys.exception() g = yield_raise() - self.assertEqual(next(g), KeyError) - self.assertEqual(sys.exc_info()[0], None) - self.assertEqual(next(g), KeyError) - self.assertEqual(sys.exc_info()[0], None) - self.assertEqual(next(g), None) + self.assertIsInstance(next(g), KeyError) + self.assertIsNone(sys.exception()) + self.assertIsInstance(next(g), KeyError) + self.assertIsNone(sys.exception()) + self.assertIsNone(next(g)) # Same test, but inside an exception handler try: raise TypeError("foo") except TypeError: g = yield_raise() - self.assertEqual(next(g), KeyError) - self.assertEqual(sys.exc_info()[0], TypeError) - self.assertEqual(next(g), KeyError) - self.assertEqual(sys.exc_info()[0], TypeError) - self.assertEqual(next(g), TypeError) + self.assertIsInstance(next(g), KeyError) + self.assertIsInstance(sys.exception(), TypeError) + self.assertIsInstance(next(g), KeyError) + self.assertIsInstance(sys.exception(), TypeError) + self.assertIsInstance(next(g), TypeError) del g - self.assertEqual(sys.exc_info()[0], TypeError) + self.assertIsInstance(sys.exception(), TypeError) def test_generator_leaking2(self): # See issue 12475. @@ -883,7 +930,7 @@ class ExceptionTests(unittest.TestCase): next(it) except StopIteration: pass - self.assertEqual(sys.exc_info(), (None, None, None)) + self.assertIsNone(sys.exception()) def test_generator_leaking3(self): # See issue #23353. When gen.throw() is called, the caller's @@ -892,17 +939,17 @@ class ExceptionTests(unittest.TestCase): try: yield except ZeroDivisionError: - yield sys.exc_info()[1] + yield sys.exception() it = g() next(it) try: 1/0 except ZeroDivisionError as e: - self.assertIs(sys.exc_info()[1], e) + self.assertIs(sys.exception(), e) gen_exc = it.throw(e) - self.assertIs(sys.exc_info()[1], e) + self.assertIs(sys.exception(), e) self.assertIs(gen_exc, e) - self.assertEqual(sys.exc_info(), (None, None, None)) + self.assertIsNone(sys.exception()) def test_generator_leaking4(self): # See issue #23353. When an exception is raised by a generator, @@ -911,7 +958,7 @@ class ExceptionTests(unittest.TestCase): try: 1/0 except ZeroDivisionError: - yield sys.exc_info()[0] + yield sys.exception() raise it = g() try: @@ -919,7 +966,7 @@ class ExceptionTests(unittest.TestCase): except TypeError: # The caller's exception state (TypeError) is temporarily # saved in the generator. - tp = next(it) + tp = type(next(it)) self.assertIs(tp, ZeroDivisionError) try: next(it) @@ -927,15 +974,15 @@ class ExceptionTests(unittest.TestCase): # with an exception, it shouldn't have restored the old # exception state (TypeError). except ZeroDivisionError as e: - self.assertIs(sys.exc_info()[1], e) + self.assertIs(sys.exception(), e) # We used to find TypeError here. - self.assertEqual(sys.exc_info(), (None, None, None)) + self.assertIsNone(sys.exception()) def test_generator_doesnt_retain_old_exc(self): def g(): - self.assertIsInstance(sys.exc_info()[1], RuntimeError) + self.assertIsInstance(sys.exception(), RuntimeError) yield - self.assertEqual(sys.exc_info(), (None, None, None)) + self.assertIsNone(sys.exception()) it = g() try: raise RuntimeError @@ -943,7 +990,7 @@ class ExceptionTests(unittest.TestCase): next(it) self.assertRaises(StopIteration, next, it) - def test_generator_finalizing_and_exc_info(self): + def test_generator_finalizing_and_sys_exception(self): # See #7173 def simple_gen(): yield 1 @@ -955,7 +1002,7 @@ class ExceptionTests(unittest.TestCase): return next(gen) run_gen() gc_collect() - self.assertEqual(sys.exc_info(), (None, None, None)) + self.assertIsNone(sys.exception()) def _check_generator_cleanup_exc_state(self, testfunc): # Issue #12791: exception state is cleaned up as soon as a generator @@ -1026,14 +1073,14 @@ class ExceptionTests(unittest.TestCase): class MyObject: def __del__(self): nonlocal e - e = sys.exc_info() + e = sys.exception() e = () try: raise Exception(MyObject()) except: pass gc_collect() # For PyPy or other GCs. - self.assertEqual(e, (None, None, None)) + self.assertIsNone(e) def test_raise_does_not_create_context_chain_cycle(self): class A(Exception): @@ -1094,7 +1141,6 @@ class ExceptionTests(unittest.TestCase): self.assertIsInstance(exc.__context__, ValueError) self.assertIs(exc.__context__.__context__, exc.__context__) - @unittest.skip("See issue 44895") def test_no_hang_on_context_chain_cycle2(self): # See issue 25782. Cycle at head of context chain. @@ -1296,14 +1342,15 @@ class ExceptionTests(unittest.TestCase): def g(): try: return g() - except RecursionError: - return sys.exc_info() - e, v, tb = g() - self.assertIsInstance(v, RecursionError, type(v)) - self.assertIn("maximum recursion depth exceeded", str(v)) + except RecursionError as e: + return e + exc = g() + self.assertIsInstance(exc, RecursionError, type(exc)) + self.assertIn("maximum recursion depth exceeded", str(exc)) @cpython_only + @support.requires_resource('cpu') def test_trashcan_recursion(self): # See bpo-33930 @@ -1331,6 +1378,7 @@ class ExceptionTests(unittest.TestCase): code = """if 1: import sys from _testinternalcapi import get_recursion_depth + from test import support class MyException(Exception): pass @@ -1358,13 +1406,8 @@ class ExceptionTests(unittest.TestCase): 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) + recurse(support.EXCEEDS_RECURSION_LIMIT) finally: sys.setrecursionlimit(recursionlimit) print('Done.') @@ -1379,8 +1422,8 @@ class ExceptionTests(unittest.TestCase): @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. + # maximum recursion depth has been exceeded when creating + # an exception code = """if 1: import _testcapi try: @@ -1390,8 +1433,7 @@ class ExceptionTests(unittest.TestCase): """ 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'RecursionError: maximum recursion depth exceeded', err) self.assertIn(b'Done.', out) @@ -1657,7 +1699,7 @@ class ExceptionTests(unittest.TestCase): raise ValueError except ValueError: yield 1 - self.assertEqual(sys.exc_info(), (None, None, None)) + self.assertIsNone(sys.exception()) yield 2 gen = g() @@ -1729,7 +1771,6 @@ class ExceptionTests(unittest.TestCase): gc_collect() -global_for_suggestions = None class NameErrorTests(unittest.TestCase): def test_name_error_has_name(self): @@ -1738,272 +1779,6 @@ class NameErrorTests(unittest.TestCase): except NameError as exc: self.assertEqual("bluch", exc.name) - def test_name_error_suggestions(self): - def Substitution(): - noise = more_noise = a = bc = None - blech = None - print(bluch) - - def Elimination(): - noise = more_noise = a = bc = None - blch = None - print(bluch) - - def Addition(): - noise = more_noise = a = bc = None - bluchin = None - print(bluch) - - def SubstitutionOverElimination(): - blach = None - bluc = None - print(bluch) - - def SubstitutionOverAddition(): - blach = None - bluchi = None - print(bluch) - - def EliminationOverAddition(): - blucha = None - bluc = None - print(bluch) - - for func, suggestion in [(Substitution, "'blech'?"), - (Elimination, "'blch'?"), - (Addition, "'bluchin'?"), - (EliminationOverAddition, "'blucha'?"), - (SubstitutionOverElimination, "'blach'?"), - (SubstitutionOverAddition, "'blach'?")]: - err = None - try: - func() - except NameError as exc: - with support.captured_stderr() as err: - sys.__excepthook__(*sys.exc_info()) - self.assertIn(suggestion, err.getvalue()) - - def test_name_error_suggestions_from_globals(self): - def func(): - print(global_for_suggestio) - try: - func() - except NameError as exc: - with support.captured_stderr() as err: - sys.__excepthook__(*sys.exc_info()) - self.assertIn("'global_for_suggestions'?", err.getvalue()) - - def test_name_error_suggestions_from_builtins(self): - def func(): - print(ZeroDivisionErrrrr) - try: - func() - except NameError as exc: - with support.captured_stderr() as err: - sys.__excepthook__(*sys.exc_info()) - self.assertIn("'ZeroDivisionError'?", err.getvalue()) - - def test_name_error_suggestions_do_not_trigger_for_long_names(self): - def f(): - somethingverywronghehehehehehe = None - print(somethingverywronghe) - - try: - f() - except NameError as exc: - with support.captured_stderr() as err: - sys.__excepthook__(*sys.exc_info()) - - self.assertNotIn("somethingverywronghehe", err.getvalue()) - - def test_name_error_bad_suggestions_do_not_trigger_for_small_names(self): - vvv = mom = w = id = pytho = None - - with self.subTest(name="b"): - try: - b - except NameError as exc: - with support.captured_stderr() as err: - sys.__excepthook__(*sys.exc_info()) - self.assertNotIn("you mean", err.getvalue()) - self.assertNotIn("vvv", err.getvalue()) - self.assertNotIn("mom", err.getvalue()) - self.assertNotIn("'id'", err.getvalue()) - self.assertNotIn("'w'", err.getvalue()) - self.assertNotIn("'pytho'", err.getvalue()) - - with self.subTest(name="v"): - try: - v - except NameError as exc: - with support.captured_stderr() as err: - sys.__excepthook__(*sys.exc_info()) - self.assertNotIn("you mean", err.getvalue()) - self.assertNotIn("vvv", err.getvalue()) - self.assertNotIn("mom", err.getvalue()) - self.assertNotIn("'id'", err.getvalue()) - self.assertNotIn("'w'", err.getvalue()) - self.assertNotIn("'pytho'", err.getvalue()) - - with self.subTest(name="m"): - try: - m - except NameError as exc: - with support.captured_stderr() as err: - sys.__excepthook__(*sys.exc_info()) - self.assertNotIn("you mean", err.getvalue()) - self.assertNotIn("vvv", err.getvalue()) - self.assertNotIn("mom", err.getvalue()) - self.assertNotIn("'id'", err.getvalue()) - self.assertNotIn("'w'", err.getvalue()) - self.assertNotIn("'pytho'", err.getvalue()) - - with self.subTest(name="py"): - try: - py - except NameError as exc: - with support.captured_stderr() as err: - sys.__excepthook__(*sys.exc_info()) - self.assertNotIn("you mean", err.getvalue()) - self.assertNotIn("vvv", err.getvalue()) - self.assertNotIn("mom", err.getvalue()) - self.assertNotIn("'id'", err.getvalue()) - self.assertNotIn("'w'", err.getvalue()) - self.assertNotIn("'pytho'", err.getvalue()) - - def test_name_error_suggestions_do_not_trigger_for_too_many_locals(self): - def f(): - # Mutating locals() is unreliable, so we need to do it by hand - a1 = a2 = a3 = a4 = a5 = a6 = a7 = a8 = a9 = a10 = \ - a11 = a12 = a13 = a14 = a15 = a16 = a17 = a18 = a19 = a20 = \ - a21 = a22 = a23 = a24 = a25 = a26 = a27 = a28 = a29 = a30 = \ - a31 = a32 = a33 = a34 = a35 = a36 = a37 = a38 = a39 = a40 = \ - a41 = a42 = a43 = a44 = a45 = a46 = a47 = a48 = a49 = a50 = \ - a51 = a52 = a53 = a54 = a55 = a56 = a57 = a58 = a59 = a60 = \ - a61 = a62 = a63 = a64 = a65 = a66 = a67 = a68 = a69 = a70 = \ - a71 = a72 = a73 = a74 = a75 = a76 = a77 = a78 = a79 = a80 = \ - a81 = a82 = a83 = a84 = a85 = a86 = a87 = a88 = a89 = a90 = \ - a91 = a92 = a93 = a94 = a95 = a96 = a97 = a98 = a99 = a100 = \ - a101 = a102 = a103 = a104 = a105 = a106 = a107 = a108 = a109 = a110 = \ - a111 = a112 = a113 = a114 = a115 = a116 = a117 = a118 = a119 = a120 = \ - a121 = a122 = a123 = a124 = a125 = a126 = a127 = a128 = a129 = a130 = \ - a131 = a132 = a133 = a134 = a135 = a136 = a137 = a138 = a139 = a140 = \ - a141 = a142 = a143 = a144 = a145 = a146 = a147 = a148 = a149 = a150 = \ - a151 = a152 = a153 = a154 = a155 = a156 = a157 = a158 = a159 = a160 = \ - a161 = a162 = a163 = a164 = a165 = a166 = a167 = a168 = a169 = a170 = \ - a171 = a172 = a173 = a174 = a175 = a176 = a177 = a178 = a179 = a180 = \ - a181 = a182 = a183 = a184 = a185 = a186 = a187 = a188 = a189 = a190 = \ - a191 = a192 = a193 = a194 = a195 = a196 = a197 = a198 = a199 = a200 = \ - a201 = a202 = a203 = a204 = a205 = a206 = a207 = a208 = a209 = a210 = \ - a211 = a212 = a213 = a214 = a215 = a216 = a217 = a218 = a219 = a220 = \ - a221 = a222 = a223 = a224 = a225 = a226 = a227 = a228 = a229 = a230 = \ - a231 = a232 = a233 = a234 = a235 = a236 = a237 = a238 = a239 = a240 = \ - a241 = a242 = a243 = a244 = a245 = a246 = a247 = a248 = a249 = a250 = \ - a251 = a252 = a253 = a254 = a255 = a256 = a257 = a258 = a259 = a260 = \ - a261 = a262 = a263 = a264 = a265 = a266 = a267 = a268 = a269 = a270 = \ - a271 = a272 = a273 = a274 = a275 = a276 = a277 = a278 = a279 = a280 = \ - a281 = a282 = a283 = a284 = a285 = a286 = a287 = a288 = a289 = a290 = \ - a291 = a292 = a293 = a294 = a295 = a296 = a297 = a298 = a299 = a300 = \ - a301 = a302 = a303 = a304 = a305 = a306 = a307 = a308 = a309 = a310 = \ - a311 = a312 = a313 = a314 = a315 = a316 = a317 = a318 = a319 = a320 = \ - a321 = a322 = a323 = a324 = a325 = a326 = a327 = a328 = a329 = a330 = \ - a331 = a332 = a333 = a334 = a335 = a336 = a337 = a338 = a339 = a340 = \ - a341 = a342 = a343 = a344 = a345 = a346 = a347 = a348 = a349 = a350 = \ - a351 = a352 = a353 = a354 = a355 = a356 = a357 = a358 = a359 = a360 = \ - a361 = a362 = a363 = a364 = a365 = a366 = a367 = a368 = a369 = a370 = \ - a371 = a372 = a373 = a374 = a375 = a376 = a377 = a378 = a379 = a380 = \ - a381 = a382 = a383 = a384 = a385 = a386 = a387 = a388 = a389 = a390 = \ - a391 = a392 = a393 = a394 = a395 = a396 = a397 = a398 = a399 = a400 = \ - a401 = a402 = a403 = a404 = a405 = a406 = a407 = a408 = a409 = a410 = \ - a411 = a412 = a413 = a414 = a415 = a416 = a417 = a418 = a419 = a420 = \ - a421 = a422 = a423 = a424 = a425 = a426 = a427 = a428 = a429 = a430 = \ - a431 = a432 = a433 = a434 = a435 = a436 = a437 = a438 = a439 = a440 = \ - a441 = a442 = a443 = a444 = a445 = a446 = a447 = a448 = a449 = a450 = \ - a451 = a452 = a453 = a454 = a455 = a456 = a457 = a458 = a459 = a460 = \ - a461 = a462 = a463 = a464 = a465 = a466 = a467 = a468 = a469 = a470 = \ - a471 = a472 = a473 = a474 = a475 = a476 = a477 = a478 = a479 = a480 = \ - a481 = a482 = a483 = a484 = a485 = a486 = a487 = a488 = a489 = a490 = \ - a491 = a492 = a493 = a494 = a495 = a496 = a497 = a498 = a499 = a500 = \ - a501 = a502 = a503 = a504 = a505 = a506 = a507 = a508 = a509 = a510 = \ - a511 = a512 = a513 = a514 = a515 = a516 = a517 = a518 = a519 = a520 = \ - a521 = a522 = a523 = a524 = a525 = a526 = a527 = a528 = a529 = a530 = \ - a531 = a532 = a533 = a534 = a535 = a536 = a537 = a538 = a539 = a540 = \ - a541 = a542 = a543 = a544 = a545 = a546 = a547 = a548 = a549 = a550 = \ - a551 = a552 = a553 = a554 = a555 = a556 = a557 = a558 = a559 = a560 = \ - a561 = a562 = a563 = a564 = a565 = a566 = a567 = a568 = a569 = a570 = \ - a571 = a572 = a573 = a574 = a575 = a576 = a577 = a578 = a579 = a580 = \ - a581 = a582 = a583 = a584 = a585 = a586 = a587 = a588 = a589 = a590 = \ - a591 = a592 = a593 = a594 = a595 = a596 = a597 = a598 = a599 = a600 = \ - a601 = a602 = a603 = a604 = a605 = a606 = a607 = a608 = a609 = a610 = \ - a611 = a612 = a613 = a614 = a615 = a616 = a617 = a618 = a619 = a620 = \ - a621 = a622 = a623 = a624 = a625 = a626 = a627 = a628 = a629 = a630 = \ - a631 = a632 = a633 = a634 = a635 = a636 = a637 = a638 = a639 = a640 = \ - a641 = a642 = a643 = a644 = a645 = a646 = a647 = a648 = a649 = a650 = \ - a651 = a652 = a653 = a654 = a655 = a656 = a657 = a658 = a659 = a660 = \ - a661 = a662 = a663 = a664 = a665 = a666 = a667 = a668 = a669 = a670 = \ - a671 = a672 = a673 = a674 = a675 = a676 = a677 = a678 = a679 = a680 = \ - a681 = a682 = a683 = a684 = a685 = a686 = a687 = a688 = a689 = a690 = \ - a691 = a692 = a693 = a694 = a695 = a696 = a697 = a698 = a699 = a700 = \ - a701 = a702 = a703 = a704 = a705 = a706 = a707 = a708 = a709 = a710 = \ - a711 = a712 = a713 = a714 = a715 = a716 = a717 = a718 = a719 = a720 = \ - a721 = a722 = a723 = a724 = a725 = a726 = a727 = a728 = a729 = a730 = \ - a731 = a732 = a733 = a734 = a735 = a736 = a737 = a738 = a739 = a740 = \ - a741 = a742 = a743 = a744 = a745 = a746 = a747 = a748 = a749 = a750 = \ - a751 = a752 = a753 = a754 = a755 = a756 = a757 = a758 = a759 = a760 = \ - a761 = a762 = a763 = a764 = a765 = a766 = a767 = a768 = a769 = a770 = \ - a771 = a772 = a773 = a774 = a775 = a776 = a777 = a778 = a779 = a780 = \ - a781 = a782 = a783 = a784 = a785 = a786 = a787 = a788 = a789 = a790 = \ - a791 = a792 = a793 = a794 = a795 = a796 = a797 = a798 = a799 = a800 \ - = None - print(a0) - - try: - f() - except NameError as exc: - with support.captured_stderr() as err: - sys.__excepthook__(*sys.exc_info()) - - self.assertNotRegex(err.getvalue(), r"NameError.*a1") - - def test_name_error_with_custom_exceptions(self): - def f(): - blech = None - raise NameError() - - try: - f() - except NameError as exc: - with support.captured_stderr() as err: - sys.__excepthook__(*sys.exc_info()) - - self.assertNotIn("blech", err.getvalue()) - - def f(): - blech = None - raise NameError - - try: - f() - except NameError as exc: - with support.captured_stderr() as err: - sys.__excepthook__(*sys.exc_info()) - - self.assertNotIn("blech", err.getvalue()) - - def test_unbound_local_error_doesn_not_match(self): - def foo(): - something = 3 - print(somethong) - somethong = 3 - - try: - foo() - except UnboundLocalError as exc: - with support.captured_stderr() as err: - sys.__excepthook__(*sys.exc_info()) - - self.assertNotIn("something", err.getvalue()) - def test_issue45826(self): # regression test for bpo-45826 def f(): @@ -2035,6 +1810,8 @@ class NameErrorTests(unittest.TestCase): self.assertIn("nonsense", err.getvalue()) self.assertIn("ZeroDivisionError", err.getvalue()) + # Note: name suggestion tests live in `test_traceback`. + class AttributeErrorTests(unittest.TestCase): def test_attributes(self): @@ -2076,239 +1853,7 @@ class AttributeErrorTests(unittest.TestCase): self.assertEqual("bluch", exc.name) self.assertEqual(obj, exc.obj) - def test_getattr_suggestions(self): - class Substitution: - noise = more_noise = a = bc = None - blech = None - - class Elimination: - noise = more_noise = a = bc = None - blch = None - - class Addition: - noise = more_noise = a = bc = None - bluchin = None - - class SubstitutionOverElimination: - blach = None - bluc = None - - class SubstitutionOverAddition: - blach = None - bluchi = None - - class EliminationOverAddition: - blucha = None - bluc = None - - for cls, suggestion in [(Substitution, "'blech'?"), - (Elimination, "'blch'?"), - (Addition, "'bluchin'?"), - (EliminationOverAddition, "'bluc'?"), - (SubstitutionOverElimination, "'blach'?"), - (SubstitutionOverAddition, "'blach'?")]: - try: - cls().bluch - except AttributeError as exc: - with support.captured_stderr() as err: - sys.__excepthook__(*sys.exc_info()) - - self.assertIn(suggestion, err.getvalue()) - - def test_getattr_suggestions_do_not_trigger_for_long_attributes(self): - class A: - blech = None - - try: - A().somethingverywrong - except AttributeError as exc: - with support.captured_stderr() as err: - sys.__excepthook__(*sys.exc_info()) - - self.assertNotIn("blech", err.getvalue()) - - def test_getattr_error_bad_suggestions_do_not_trigger_for_small_names(self): - class MyClass: - vvv = mom = w = id = pytho = None - - with self.subTest(name="b"): - try: - MyClass.b - except AttributeError as exc: - with support.captured_stderr() as err: - sys.__excepthook__(*sys.exc_info()) - self.assertNotIn("you mean", err.getvalue()) - self.assertNotIn("vvv", err.getvalue()) - self.assertNotIn("mom", err.getvalue()) - self.assertNotIn("'id'", err.getvalue()) - self.assertNotIn("'w'", err.getvalue()) - self.assertNotIn("'pytho'", err.getvalue()) - - with self.subTest(name="v"): - try: - MyClass.v - except AttributeError as exc: - with support.captured_stderr() as err: - sys.__excepthook__(*sys.exc_info()) - self.assertNotIn("you mean", err.getvalue()) - self.assertNotIn("vvv", err.getvalue()) - self.assertNotIn("mom", err.getvalue()) - self.assertNotIn("'id'", err.getvalue()) - self.assertNotIn("'w'", err.getvalue()) - self.assertNotIn("'pytho'", err.getvalue()) - - with self.subTest(name="m"): - try: - MyClass.m - except AttributeError as exc: - with support.captured_stderr() as err: - sys.__excepthook__(*sys.exc_info()) - self.assertNotIn("you mean", err.getvalue()) - self.assertNotIn("vvv", err.getvalue()) - self.assertNotIn("mom", err.getvalue()) - self.assertNotIn("'id'", err.getvalue()) - self.assertNotIn("'w'", err.getvalue()) - self.assertNotIn("'pytho'", err.getvalue()) - - with self.subTest(name="py"): - try: - MyClass.py - except AttributeError as exc: - with support.captured_stderr() as err: - sys.__excepthook__(*sys.exc_info()) - self.assertNotIn("you mean", err.getvalue()) - self.assertNotIn("vvv", err.getvalue()) - self.assertNotIn("mom", err.getvalue()) - self.assertNotIn("'id'", err.getvalue()) - self.assertNotIn("'w'", err.getvalue()) - self.assertNotIn("'pytho'", err.getvalue()) - - - def test_getattr_suggestions_do_not_trigger_for_big_dicts(self): - class A: - blech = None - # A class with a very big __dict__ will not be consider - # for suggestions. - for index in range(2000): - setattr(A, f"index_{index}", None) - - try: - A().bluch - except AttributeError as exc: - with support.captured_stderr() as err: - sys.__excepthook__(*sys.exc_info()) - - self.assertNotIn("blech", err.getvalue()) - - def test_getattr_suggestions_no_args(self): - class A: - blech = None - def __getattr__(self, attr): - raise AttributeError() - - try: - A().bluch - except AttributeError as exc: - with support.captured_stderr() as err: - sys.__excepthook__(*sys.exc_info()) - - self.assertIn("blech", err.getvalue()) - - class A: - blech = None - def __getattr__(self, attr): - raise AttributeError - - try: - A().bluch - except AttributeError as exc: - with support.captured_stderr() as err: - sys.__excepthook__(*sys.exc_info()) - - self.assertIn("blech", err.getvalue()) - - def test_getattr_suggestions_invalid_args(self): - class NonStringifyClass: - __str__ = None - __repr__ = None - - class A: - blech = None - def __getattr__(self, attr): - raise AttributeError(NonStringifyClass()) - - class B: - blech = None - def __getattr__(self, attr): - raise AttributeError("Error", 23) - - class C: - blech = None - def __getattr__(self, attr): - raise AttributeError(23) - - for cls in [A, B, C]: - try: - cls().bluch - except AttributeError as exc: - with support.captured_stderr() as err: - sys.__excepthook__(*sys.exc_info()) - - self.assertIn("blech", err.getvalue()) - - def test_getattr_suggestions_for_same_name(self): - class A: - def __dir__(self): - return ['blech'] - try: - A().blech - except AttributeError as exc: - with support.captured_stderr() as err: - sys.__excepthook__(*sys.exc_info()) - - self.assertNotIn("Did you mean", err.getvalue()) - - def test_attribute_error_with_failing_dict(self): - class T: - bluch = 1 - def __dir__(self): - raise AttributeError("oh no!") - - try: - T().blich - except AttributeError as exc: - with support.captured_stderr() as err: - sys.__excepthook__(*sys.exc_info()) - - self.assertNotIn("blech", err.getvalue()) - self.assertNotIn("oh no!", err.getvalue()) - - def test_attribute_error_with_bad_name(self): - try: - raise AttributeError(name=12, obj=23) - except AttributeError as exc: - with support.captured_stderr() as err: - sys.__excepthook__(*sys.exc_info()) - - self.assertNotIn("?", err.getvalue()) - - def test_attribute_error_inside_nested_getattr(self): - class A: - bluch = 1 - - class B: - def __getattribute__(self, attr): - a = A() - return a.blich - - try: - B().something - except AttributeError as exc: - with support.captured_stderr() as err: - sys.__excepthook__(*sys.exc_info()) - - self.assertIn("Did you mean", err.getvalue()) - self.assertIn("bluch", err.getvalue()) + # Note: name suggestion tests live in `test_traceback`. class ImportErrorTests(unittest.TestCase): diff --git a/Lib/test/test_extcall.py b/Lib/test/test_extcall.py index 13265ea0..d9d85fe7 100644 --- a/Lib/test/test_extcall.py +++ b/Lib/test/test_extcall.py @@ -8,6 +8,7 @@ We're going the use these types for extra testing We're defining four helper functions + >>> from test import support >>> def e(a,b): ... print(a, b) @@ -381,6 +382,27 @@ Test a kwargs mapping with duplicated keys. ... TypeError: test.test_extcall.g() got multiple values for keyword argument 'x' +Call with dict subtype: + + >>> class MyDict(dict): + ... pass + + >>> def s1(**kwargs): + ... return kwargs + >>> def s2(*args, **kwargs): + ... return (args, kwargs) + >>> def s3(*, n, **kwargs): + ... return (n, kwargs) + + >>> md = MyDict({'a': 1, 'b': 2}) + >>> assert s1(**md) == {'a': 1, 'b': 2} + >>> assert s2(*(1, 2), **md) == ((1, 2), {'a': 1, 'b': 2}) + >>> assert s3(**MyDict({'n': 1, 'b': 2})) == (1, {'b': 2}) + >>> s3(**md) + Traceback (most recent call last): + ... + TypeError: s3() missing 1 required keyword-only argument: 'n' + Another helper function >>> def f2(*a, **b): @@ -522,7 +544,6 @@ Same with keyword only args: import doctest import unittest -from test import support def load_tests(loader, tests, pattern): tests.addTest(doctest.DocTestSuite()) diff --git a/Lib/test/test_faulthandler.py b/Lib/test/test_faulthandler.py index 8d106daa..cfc7ce5a 100644 --- a/Lib/test/test_faulthandler.py +++ b/Lib/test/test_faulthandler.py @@ -270,7 +270,7 @@ class FaultHandlerTests(unittest.TestCase): """, 2, 'xyz', - func='test_fatal_error', + func='_testcapi_fatal_error_impl', py_fatal_error=True) def test_fatal_error(self): @@ -676,6 +676,7 @@ class FaultHandlerTests(unittest.TestCase): with tempfile.TemporaryFile('wb+') as fp: self.check_dump_traceback_later(fd=fp.fileno()) + @support.requires_resource('walltime') def test_dump_traceback_later_twice(self): self.check_dump_traceback_later(loops=2) diff --git a/Lib/test/test_fcntl.py b/Lib/test/test_fcntl.py index fc8c3936..203dd6fe 100644 --- a/Lib/test/test_fcntl.py +++ b/Lib/test/test_fcntl.py @@ -1,12 +1,12 @@ """Test program for the fcntl C module. """ +import multiprocessing import platform import os import struct import sys import unittest -from multiprocessing import Process -from test.support import verbose, cpython_only +from test.support import verbose, cpython_only, get_pagesize from test.support.import_helper import import_module from test.support.os_helper import TESTFN, unlink @@ -16,37 +16,6 @@ fcntl = import_module('fcntl') -def get_lockdata(): - try: - os.O_LARGEFILE - except AttributeError: - start_len = "ll" - else: - start_len = "qq" - - if (sys.platform.startswith(('netbsd', 'freebsd', 'openbsd')) - or sys.platform == 'darwin'): - if struct.calcsize('l') == 8: - off_t = 'l' - pid_t = 'i' - else: - off_t = 'lxxxx' - pid_t = 'l' - lockdata = struct.pack(off_t + off_t + pid_t + 'hh', 0, 0, 0, - fcntl.F_WRLCK, 0) - elif sys.platform.startswith('gnukfreebsd'): - lockdata = struct.pack('qqihhi', 0, 0, 0, fcntl.F_WRLCK, 0, 0) - elif sys.platform in ['hp-uxB', 'unixware7']: - lockdata = struct.pack('hhlllii', fcntl.F_WRLCK, 0, 0, 0, 0, 0, 0) - else: - lockdata = struct.pack('hh'+start_len+'hh', fcntl.F_WRLCK, 0, 0, 0, 0, 0) - if lockdata: - if verbose: - print('struct.pack: ', repr(lockdata)) - return lockdata - -lockdata = get_lockdata() - class BadFile: def __init__(self, fn): self.fn = fn @@ -78,12 +47,43 @@ class TestFcntl(unittest.TestCase): self.f.close() unlink(TESTFN) + @staticmethod + def get_lockdata(): + try: + os.O_LARGEFILE + except AttributeError: + start_len = "ll" + else: + start_len = "qq" + + if (sys.platform.startswith(('netbsd', 'freebsd', 'openbsd')) + or sys.platform == 'darwin'): + if struct.calcsize('l') == 8: + off_t = 'l' + pid_t = 'i' + else: + off_t = 'lxxxx' + pid_t = 'l' + lockdata = struct.pack(off_t + off_t + pid_t + 'hh', 0, 0, 0, + fcntl.F_WRLCK, 0) + elif sys.platform.startswith('gnukfreebsd'): + lockdata = struct.pack('qqihhi', 0, 0, 0, fcntl.F_WRLCK, 0, 0) + elif sys.platform in ['hp-uxB', 'unixware7']: + lockdata = struct.pack('hhlllii', fcntl.F_WRLCK, 0, 0, 0, 0, 0, 0) + else: + lockdata = struct.pack('hh'+start_len+'hh', fcntl.F_WRLCK, 0, 0, 0, 0, 0) + if lockdata: + if verbose: + print('struct.pack: ', repr(lockdata)) + return lockdata + def test_fcntl_fileno(self): # the example from the library docs self.f = open(TESTFN, 'wb') rv = fcntl.fcntl(self.f.fileno(), fcntl.F_SETFL, os.O_NONBLOCK) if verbose: print('Status from fcntl with O_NONBLOCK: ', rv) + lockdata = self.get_lockdata() rv = fcntl.fcntl(self.f.fileno(), fcntl.F_SETLKW, lockdata) if verbose: print('String from fcntl with F_SETLKW: ', repr(rv)) @@ -95,6 +95,7 @@ class TestFcntl(unittest.TestCase): rv = fcntl.fcntl(self.f, fcntl.F_SETFL, os.O_NONBLOCK) if verbose: print('Status from fcntl with O_NONBLOCK: ', rv) + lockdata = self.get_lockdata() rv = fcntl.fcntl(self.f, fcntl.F_SETLKW, lockdata) if verbose: print('String from fcntl with F_SETLKW: ', repr(rv)) @@ -160,7 +161,8 @@ class TestFcntl(unittest.TestCase): self.f = open(TESTFN, 'wb+') cmd = fcntl.LOCK_EX | fcntl.LOCK_NB fcntl.lockf(self.f, cmd) - p = Process(target=try_lockf_on_other_process_fail, args=(TESTFN, cmd)) + mp = multiprocessing.get_context('spawn') + p = mp.Process(target=try_lockf_on_other_process_fail, args=(TESTFN, cmd)) p.start() p.join() fcntl.lockf(self.f, fcntl.LOCK_UN) @@ -171,7 +173,8 @@ class TestFcntl(unittest.TestCase): self.f = open(TESTFN, 'wb+') cmd = fcntl.LOCK_SH | fcntl.LOCK_NB fcntl.lockf(self.f, cmd) - p = Process(target=try_lockf_on_other_process, args=(TESTFN, cmd)) + mp = multiprocessing.get_context('spawn') + p = mp.Process(target=try_lockf_on_other_process, args=(TESTFN, cmd)) p.start() p.join() fcntl.lockf(self.f, fcntl.LOCK_UN) @@ -199,8 +202,9 @@ class TestFcntl(unittest.TestCase): # Get the default pipesize with F_GETPIPE_SZ pipesize_default = fcntl.fcntl(test_pipe_w, fcntl.F_GETPIPE_SZ) pipesize = pipesize_default // 2 # A new value to detect change. - if pipesize < 512: # the POSIX minimum - raise unittest.SkitTest( + pagesize_default = get_pagesize() + if pipesize < pagesize_default: # the POSIX minimum + raise unittest.SkipTest( 'default pipesize too small to perform test.') fcntl.fcntl(test_pipe_w, fcntl.F_SETPIPE_SZ, pipesize) self.assertEqual(fcntl.fcntl(test_pipe_w, fcntl.F_GETPIPE_SZ), diff --git a/Lib/test/test_file.py b/Lib/test/test_file.py index 1146a373..9df55278 100644 --- a/Lib/test/test_file.py +++ b/Lib/test/test_file.py @@ -217,7 +217,7 @@ class OtherFileTests: self._checkBufferSize(1) def testTruncateOnWindows(self): - # SF bug <http://www.python.org/sf/801631> + # SF bug <https://bugs.python.org/issue801631> # "file.truncate fault on windows" f = self.open(TESTFN, 'wb') diff --git a/Lib/test/test_fileinput.py b/Lib/test/test_fileinput.py index ac20c74b..786d9186 100644 --- a/Lib/test/test_fileinput.py +++ b/Lib/test/test_fileinput.py @@ -855,29 +855,29 @@ class Test_hook_compressed(unittest.TestCase): self.fake_open = InvocationRecorder() def test_empty_string(self): - self.do_test_use_builtin_open("", 1) + self.do_test_use_builtin_open_text("", "r") def test_no_ext(self): - self.do_test_use_builtin_open("abcd", 2) + self.do_test_use_builtin_open_text("abcd", "r") @unittest.skipUnless(gzip, "Requires gzip and zlib") def test_gz_ext_fake(self): original_open = gzip.open gzip.open = self.fake_open try: - result = fileinput.hook_compressed("test.gz", "3") + result = fileinput.hook_compressed("test.gz", "r") finally: gzip.open = original_open self.assertEqual(self.fake_open.invocation_count, 1) - self.assertEqual(self.fake_open.last_invocation, (("test.gz", "3"), {})) + self.assertEqual(self.fake_open.last_invocation, (("test.gz", "r"), {})) @unittest.skipUnless(gzip, "Requires gzip and zlib") def test_gz_with_encoding_fake(self): original_open = gzip.open gzip.open = lambda filename, mode: io.BytesIO(b'Ex-binary string') try: - result = fileinput.hook_compressed("test.gz", "3", encoding="utf-8") + result = fileinput.hook_compressed("test.gz", "r", encoding="utf-8") finally: gzip.open = original_open self.assertEqual(list(result), ['Ex-binary string']) @@ -887,23 +887,40 @@ class Test_hook_compressed(unittest.TestCase): original_open = bz2.BZ2File bz2.BZ2File = self.fake_open try: - result = fileinput.hook_compressed("test.bz2", "4") + result = fileinput.hook_compressed("test.bz2", "r") finally: bz2.BZ2File = original_open self.assertEqual(self.fake_open.invocation_count, 1) - self.assertEqual(self.fake_open.last_invocation, (("test.bz2", "4"), {})) + self.assertEqual(self.fake_open.last_invocation, (("test.bz2", "r"), {})) def test_blah_ext(self): - self.do_test_use_builtin_open("abcd.blah", "5") + self.do_test_use_builtin_open_binary("abcd.blah", "rb") def test_gz_ext_builtin(self): - self.do_test_use_builtin_open("abcd.Gz", "6") + self.do_test_use_builtin_open_binary("abcd.Gz", "rb") def test_bz2_ext_builtin(self): - self.do_test_use_builtin_open("abcd.Bz2", "7") + self.do_test_use_builtin_open_binary("abcd.Bz2", "rb") - def do_test_use_builtin_open(self, filename, mode): + def test_binary_mode_encoding(self): + self.do_test_use_builtin_open_binary("abcd", "rb") + + def test_text_mode_encoding(self): + self.do_test_use_builtin_open_text("abcd", "r") + + def do_test_use_builtin_open_binary(self, filename, mode): + original_open = self.replace_builtin_open(self.fake_open) + try: + result = fileinput.hook_compressed(filename, mode) + finally: + self.replace_builtin_open(original_open) + + self.assertEqual(self.fake_open.invocation_count, 1) + self.assertEqual(self.fake_open.last_invocation, + ((filename, mode), {'encoding': None, 'errors': None})) + + def do_test_use_builtin_open_text(self, filename, mode): original_open = self.replace_builtin_open(self.fake_open) try: result = fileinput.hook_compressed(filename, mode) diff --git a/Lib/test/test_fileio.py b/Lib/test/test_fileio.py index c26cdc02..ebfcffd1 100644 --- a/Lib/test/test_fileio.py +++ b/Lib/test/test_fileio.py @@ -12,7 +12,9 @@ from functools import wraps from test.support import ( cpython_only, swap_attr, gc_collect, is_emscripten, is_wasi ) -from test.support.os_helper import (TESTFN, TESTFN_UNICODE, make_bad_fd) +from test.support.os_helper import ( + TESTFN, TESTFN_ASCII, TESTFN_UNICODE, make_bad_fd, + ) from test.support.warnings_helper import check_warnings from collections import UserList @@ -431,18 +433,15 @@ class OtherFileTests: def testBytesOpen(self): # Opening a bytes filename - try: - fn = TESTFN.encode("ascii") - except UnicodeEncodeError: - self.skipTest('could not encode %r to ascii' % TESTFN) + fn = TESTFN_ASCII.encode("ascii") f = self.FileIO(fn, "w") try: f.write(b"abc") f.close() - with open(TESTFN, "rb") as f: + with open(TESTFN_ASCII, "rb") as f: self.assertEqual(f.read(), b"abc") finally: - os.unlink(TESTFN) + os.unlink(TESTFN_ASCII) @unittest.skipIf(sys.getfilesystemencoding() != 'utf-8', "test only works for utf-8 filesystems") @@ -503,7 +502,7 @@ class OtherFileTests: def testTruncateOnWindows(self): def bug801631(): - # SF bug <http://www.python.org/sf/801631> + # SF bug <https://bugs.python.org/issue801631> # "file.truncate fault on windows" f = self.FileIO(TESTFN, 'w') f.write(bytes(range(11))) diff --git a/Lib/test/test_float.py b/Lib/test/test_float.py index 304388e1..c4ee1e08 100644 --- a/Lib/test/test_float.py +++ b/Lib/test/test_float.py @@ -8,7 +8,6 @@ import time import unittest from test import support -from test.support import import_helper from test.test_grammar import (VALID_UNDERSCORE_LITERALS, INVALID_UNDERSCORE_LITERALS) from math import isinf, isnan, copysign, ldexp @@ -1041,11 +1040,8 @@ class InfNanTest(unittest.TestCase): self.assertEqual(copysign(1.0, float('inf')), 1.0) self.assertEqual(copysign(1.0, float('-inf')), -1.0) - @unittest.skipUnless(getattr(sys, 'float_repr_style', '') == 'short', - "applies only when using short float repr style") def test_nan_signs(self): - # When using the dtoa.c code, the sign of float('nan') should - # be predictable. + # The sign of float('nan') should be predictable. self.assertEqual(copysign(1.0, float('nan')), 1.0) self.assertEqual(copysign(1.0, float('-nan')), -1.0) diff --git a/Lib/test/test_flufl.py b/Lib/test/test_flufl.py index a81a4d4c..fd264c92 100644 --- a/Lib/test/test_flufl.py +++ b/Lib/test/test_flufl.py @@ -1,6 +1,5 @@ import __future__ import unittest -from test import support class FLUFLTests(unittest.TestCase): diff --git a/Lib/test/test_format.py b/Lib/test/test_format.py index 69b0d5f1..6fa49dbc 100644 --- a/Lib/test/test_format.py +++ b/Lib/test/test_format.py @@ -619,6 +619,8 @@ class FormatTest(unittest.TestCase): error_msg = re.escape("unsupported format character 'z'") with self.assertRaisesRegex(ValueError, error_msg): "%z.1f" % 0 # not allowed in old style string interpolation + with self.assertRaisesRegex(ValueError, error_msg): + b"%z.1f" % 0 if __name__ == "__main__": diff --git a/Lib/test/test_fractions.py b/Lib/test/test_fractions.py index fc46e867..e112f49d 100644 --- a/Lib/test/test_fractions.py +++ b/Lib/test/test_fractions.py @@ -162,6 +162,7 @@ class FractionTest(unittest.TestCase): def testFromString(self): self.assertEqual((5, 1), _components(F("5"))) self.assertEqual((3, 2), _components(F("3/2"))) + self.assertEqual((3, 2), _components(F("3 / 2"))) self.assertEqual((3, 2), _components(F(" \n +3/2"))) self.assertEqual((-3, 2), _components(F("-3/2 "))) self.assertEqual((13, 2), _components(F(" 013/02 \n "))) @@ -190,9 +191,6 @@ class FractionTest(unittest.TestCase): self.assertRaisesMessage( ValueError, "Invalid literal for Fraction: '/2'", F, "/2") - self.assertRaisesMessage( - ValueError, "Invalid literal for Fraction: '3 /2'", - F, "3 /2") self.assertRaisesMessage( # Denominators don't need a sign. ValueError, "Invalid literal for Fraction: '3/+2'", @@ -342,6 +340,19 @@ class FractionTest(unittest.TestCase): ValueError, "cannot convert NaN to integer ratio", F.from_decimal, Decimal("snan")) + def test_is_integer(self): + self.assertTrue(F(1, 1).is_integer()) + self.assertTrue(F(-1, 1).is_integer()) + self.assertTrue(F(1, -1).is_integer()) + self.assertTrue(F(2, 2).is_integer()) + self.assertTrue(F(-2, 2).is_integer()) + self.assertTrue(F(2, -2).is_integer()) + + self.assertFalse(F(1, 2).is_integer()) + self.assertFalse(F(-1, 2).is_integer()) + self.assertFalse(F(1, -2).is_integer()) + self.assertFalse(F(-1, -2).is_integer()) + def test_as_integer_ratio(self): self.assertEqual(F(4, 6).as_integer_ratio(), (2, 3)) self.assertEqual(F(-4, 6).as_integer_ratio(), (-2, 3)) @@ -477,6 +488,7 @@ class FractionTest(unittest.TestCase): self.assertEqual(F(5, 6), F(2, 3) * F(5, 4)) self.assertEqual(F(1, 4), F(1, 10) / F(2, 5)) self.assertEqual(F(-15, 8), F(3, 4) / F(-2, 5)) + self.assertRaises(ZeroDivisionError, operator.truediv, F(1), F(0)) self.assertTypedEquals(2, F(9, 10) // F(2, 5)) self.assertTypedEquals(10**23, F(10**23, 1) // F(1)) self.assertEqual(F(5, 6), F(7, 3) % F(3, 2)) @@ -832,6 +844,382 @@ class FractionTest(unittest.TestCase): self.assertEqual(type(f.numerator), myint) self.assertEqual(type(f.denominator), myint) + def test_format_no_presentation_type(self): + # Triples (fraction, specification, expected_result) + testcases = [ + (F(1, 3), '', '1/3'), + (F(-1, 3), '', '-1/3'), + (F(3), '', '3'), + (F(-3), '', '-3'), + ] + for fraction, spec, expected in testcases: + with self.subTest(fraction=fraction, spec=spec): + self.assertEqual(format(fraction, spec), expected) + + def test_format_e_presentation_type(self): + # Triples (fraction, specification, expected_result) + testcases = [ + (F(2, 3), '.6e', '6.666667e-01'), + (F(3, 2), '.6e', '1.500000e+00'), + (F(2, 13), '.6e', '1.538462e-01'), + (F(2, 23), '.6e', '8.695652e-02'), + (F(2, 33), '.6e', '6.060606e-02'), + (F(13, 2), '.6e', '6.500000e+00'), + (F(20, 2), '.6e', '1.000000e+01'), + (F(23, 2), '.6e', '1.150000e+01'), + (F(33, 2), '.6e', '1.650000e+01'), + (F(2, 3), '.6e', '6.666667e-01'), + (F(3, 2), '.6e', '1.500000e+00'), + # Zero + (F(0), '.3e', '0.000e+00'), + # Powers of 10, to exercise the log10 boundary logic + (F(1, 1000), '.3e', '1.000e-03'), + (F(1, 100), '.3e', '1.000e-02'), + (F(1, 10), '.3e', '1.000e-01'), + (F(1, 1), '.3e', '1.000e+00'), + (F(10), '.3e', '1.000e+01'), + (F(100), '.3e', '1.000e+02'), + (F(1000), '.3e', '1.000e+03'), + # Boundary where we round up to the next power of 10 + (F('99.999994999999'), '.6e', '9.999999e+01'), + (F('99.999995'), '.6e', '1.000000e+02'), + (F('99.999995000001'), '.6e', '1.000000e+02'), + # Negatives + (F(-2, 3), '.6e', '-6.666667e-01'), + (F(-3, 2), '.6e', '-1.500000e+00'), + (F(-100), '.6e', '-1.000000e+02'), + # Large and small + (F('1e1000'), '.3e', '1.000e+1000'), + (F('1e-1000'), '.3e', '1.000e-1000'), + # Using 'E' instead of 'e' should give us a capital 'E' + (F(2, 3), '.6E', '6.666667E-01'), + # Tiny precision + (F(2, 3), '.1e', '6.7e-01'), + (F('0.995'), '.0e', '1e+00'), + # Default precision is 6 + (F(22, 7), 'e', '3.142857e+00'), + # Alternate form forces a decimal point + (F('0.995'), '#.0e', '1.e+00'), + # Check that padding takes the exponent into account. + (F(22, 7), '11.6e', '3.142857e+00'), + (F(22, 7), '12.6e', '3.142857e+00'), + (F(22, 7), '13.6e', ' 3.142857e+00'), + # Thousands separators + (F('1234567.123456'), ',.5e', '1.23457e+06'), + (F('123.123456'), '012_.2e', '0_001.23e+02'), + # z flag is legal, but never makes a difference to the output + (F(-1, 7**100), 'z.6e', '-3.091690e-85'), + ] + for fraction, spec, expected in testcases: + with self.subTest(fraction=fraction, spec=spec): + self.assertEqual(format(fraction, spec), expected) + + def test_format_f_presentation_type(self): + # Triples (fraction, specification, expected_result) + testcases = [ + # Simple .f formatting + (F(0, 1), '.2f', '0.00'), + (F(1, 3), '.2f', '0.33'), + (F(2, 3), '.2f', '0.67'), + (F(4, 3), '.2f', '1.33'), + (F(1, 8), '.2f', '0.12'), + (F(3, 8), '.2f', '0.38'), + (F(1, 13), '.2f', '0.08'), + (F(1, 199), '.2f', '0.01'), + (F(1, 200), '.2f', '0.00'), + (F(22, 7), '.5f', '3.14286'), + (F('399024789'), '.2f', '399024789.00'), + # Large precision (more than float can provide) + (F(104348, 33215), '.50f', + '3.14159265392142104470871594159265392142104470871594'), + # Precision defaults to 6 if not given + (F(22, 7), 'f', '3.142857'), + (F(0), 'f', '0.000000'), + (F(-22, 7), 'f', '-3.142857'), + # Round-ties-to-even checks + (F('1.225'), '.2f', '1.22'), + (F('1.2250000001'), '.2f', '1.23'), + (F('1.2349999999'), '.2f', '1.23'), + (F('1.235'), '.2f', '1.24'), + (F('1.245'), '.2f', '1.24'), + (F('1.2450000001'), '.2f', '1.25'), + (F('1.2549999999'), '.2f', '1.25'), + (F('1.255'), '.2f', '1.26'), + (F('-1.225'), '.2f', '-1.22'), + (F('-1.2250000001'), '.2f', '-1.23'), + (F('-1.2349999999'), '.2f', '-1.23'), + (F('-1.235'), '.2f', '-1.24'), + (F('-1.245'), '.2f', '-1.24'), + (F('-1.2450000001'), '.2f', '-1.25'), + (F('-1.2549999999'), '.2f', '-1.25'), + (F('-1.255'), '.2f', '-1.26'), + # Negatives and sign handling + (F(2, 3), '.2f', '0.67'), + (F(2, 3), '-.2f', '0.67'), + (F(2, 3), '+.2f', '+0.67'), + (F(2, 3), ' .2f', ' 0.67'), + (F(-2, 3), '.2f', '-0.67'), + (F(-2, 3), '-.2f', '-0.67'), + (F(-2, 3), '+.2f', '-0.67'), + (F(-2, 3), ' .2f', '-0.67'), + # Formatting to zero places + (F(1, 2), '.0f', '0'), + (F(-1, 2), '.0f', '-0'), + (F(22, 7), '.0f', '3'), + (F(-22, 7), '.0f', '-3'), + # Formatting to zero places, alternate form + (F(1, 2), '#.0f', '0.'), + (F(-1, 2), '#.0f', '-0.'), + (F(22, 7), '#.0f', '3.'), + (F(-22, 7), '#.0f', '-3.'), + # z flag for suppressing negative zeros + (F('-0.001'), 'z.2f', '0.00'), + (F('-0.001'), '-z.2f', '0.00'), + (F('-0.001'), '+z.2f', '+0.00'), + (F('-0.001'), ' z.2f', ' 0.00'), + (F('0.001'), 'z.2f', '0.00'), + (F('0.001'), '-z.2f', '0.00'), + (F('0.001'), '+z.2f', '+0.00'), + (F('0.001'), ' z.2f', ' 0.00'), + # Specifying a minimum width + (F(2, 3), '6.2f', ' 0.67'), + (F(12345), '6.2f', '12345.00'), + (F(12345), '12f', '12345.000000'), + # Fill and alignment + (F(2, 3), '>6.2f', ' 0.67'), + (F(2, 3), '<6.2f', '0.67 '), + (F(2, 3), '^3.2f', '0.67'), + (F(2, 3), '^4.2f', '0.67'), + (F(2, 3), '^5.2f', '0.67 '), + (F(2, 3), '^6.2f', ' 0.67 '), + (F(2, 3), '^7.2f', ' 0.67 '), + (F(2, 3), '^8.2f', ' 0.67 '), + # '=' alignment + (F(-2, 3), '=+8.2f', '- 0.67'), + (F(2, 3), '=+8.2f', '+ 0.67'), + # Fill character + (F(-2, 3), 'X>3.2f', '-0.67'), + (F(-2, 3), 'X>7.2f', 'XX-0.67'), + (F(-2, 3), 'X<7.2f', '-0.67XX'), + (F(-2, 3), 'X^7.2f', 'X-0.67X'), + (F(-2, 3), 'X=7.2f', '-XX0.67'), + (F(-2, 3), ' >7.2f', ' -0.67'), + # Corner cases: weird fill characters + (F(-2, 3), '\x00>7.2f', '\x00\x00-0.67'), + (F(-2, 3), '\n>7.2f', '\n\n-0.67'), + (F(-2, 3), '\t>7.2f', '\t\t-0.67'), + (F(-2, 3), '>>7.2f', '>>-0.67'), + (F(-2, 3), '<>7.2f', '<<-0.67'), + (F(-2, 3), '→>7.2f', '→→-0.67'), + # Zero-padding + (F(-2, 3), '07.2f', '-000.67'), + (F(-2, 3), '-07.2f', '-000.67'), + (F(2, 3), '+07.2f', '+000.67'), + (F(2, 3), ' 07.2f', ' 000.67'), + # An isolated zero is a minimum width, not a zero-pad flag. + # So unlike zero-padding, it's legal in combination with alignment. + (F(2, 3), '0.2f', '0.67'), + (F(2, 3), '>0.2f', '0.67'), + (F(2, 3), '<0.2f', '0.67'), + (F(2, 3), '^0.2f', '0.67'), + (F(2, 3), '=0.2f', '0.67'), + # Corner case: zero-padding _and_ a zero minimum width. + (F(2, 3), '00.2f', '0.67'), + # Thousands separator (only affects portion before the point) + (F(2, 3), ',.2f', '0.67'), + (F(2, 3), ',.7f', '0.6666667'), + (F('123456.789'), ',.2f', '123,456.79'), + (F('1234567'), ',.2f', '1,234,567.00'), + (F('12345678'), ',.2f', '12,345,678.00'), + (F('12345678'), ',f', '12,345,678.000000'), + # Underscore as thousands separator + (F(2, 3), '_.2f', '0.67'), + (F(2, 3), '_.7f', '0.6666667'), + (F('123456.789'), '_.2f', '123_456.79'), + (F('1234567'), '_.2f', '1_234_567.00'), + (F('12345678'), '_.2f', '12_345_678.00'), + # Thousands and zero-padding + (F('1234.5678'), '07,.2f', '1,234.57'), + (F('1234.5678'), '08,.2f', '1,234.57'), + (F('1234.5678'), '09,.2f', '01,234.57'), + (F('1234.5678'), '010,.2f', '001,234.57'), + (F('1234.5678'), '011,.2f', '0,001,234.57'), + (F('1234.5678'), '012,.2f', '0,001,234.57'), + (F('1234.5678'), '013,.2f', '00,001,234.57'), + (F('1234.5678'), '014,.2f', '000,001,234.57'), + (F('1234.5678'), '015,.2f', '0,000,001,234.57'), + (F('1234.5678'), '016,.2f', '0,000,001,234.57'), + (F('-1234.5678'), '07,.2f', '-1,234.57'), + (F('-1234.5678'), '08,.2f', '-1,234.57'), + (F('-1234.5678'), '09,.2f', '-1,234.57'), + (F('-1234.5678'), '010,.2f', '-01,234.57'), + (F('-1234.5678'), '011,.2f', '-001,234.57'), + (F('-1234.5678'), '012,.2f', '-0,001,234.57'), + (F('-1234.5678'), '013,.2f', '-0,001,234.57'), + (F('-1234.5678'), '014,.2f', '-00,001,234.57'), + (F('-1234.5678'), '015,.2f', '-000,001,234.57'), + (F('-1234.5678'), '016,.2f', '-0,000,001,234.57'), + # Corner case: no decimal point + (F('-1234.5678'), '06,.0f', '-1,235'), + (F('-1234.5678'), '07,.0f', '-01,235'), + (F('-1234.5678'), '08,.0f', '-001,235'), + (F('-1234.5678'), '09,.0f', '-0,001,235'), + # Corner-case - zero-padding specified through fill and align + # instead of the zero-pad character - in this case, treat '0' as a + # regular fill character and don't attempt to insert commas into + # the filled portion. This differs from the int and float + # behaviour. + (F('1234.5678'), '0=12,.2f', '00001,234.57'), + # Corner case where it's not clear whether the '0' indicates zero + # padding or gives the minimum width, but there's still an obvious + # answer to give. We want this to work in case the minimum width + # is being inserted programmatically: spec = f'{width}.2f'. + (F('12.34'), '0.2f', '12.34'), + (F('12.34'), 'X>0.2f', '12.34'), + # 'F' should work identically to 'f' + (F(22, 7), '.5F', '3.14286'), + # %-specifier + (F(22, 7), '.2%', '314.29%'), + (F(1, 7), '.2%', '14.29%'), + (F(1, 70), '.2%', '1.43%'), + (F(1, 700), '.2%', '0.14%'), + (F(1, 7000), '.2%', '0.01%'), + (F(1, 70000), '.2%', '0.00%'), + (F(1, 7), '.0%', '14%'), + (F(1, 7), '#.0%', '14.%'), + (F(100, 7), ',.2%', '1,428.57%'), + (F(22, 7), '7.2%', '314.29%'), + (F(22, 7), '8.2%', ' 314.29%'), + (F(22, 7), '08.2%', '0314.29%'), + # Test cases from #67790 and discuss.python.org Ideas thread. + (F(1, 3), '.2f', '0.33'), + (F(1, 8), '.2f', '0.12'), + (F(3, 8), '.2f', '0.38'), + (F(2545, 1000), '.2f', '2.54'), + (F(2549, 1000), '.2f', '2.55'), + (F(2635, 1000), '.2f', '2.64'), + (F(1, 100), '.1f', '0.0'), + (F(49, 1000), '.1f', '0.0'), + (F(51, 1000), '.1f', '0.1'), + (F(149, 1000), '.1f', '0.1'), + (F(151, 1000), '.1f', '0.2'), + ] + for fraction, spec, expected in testcases: + with self.subTest(fraction=fraction, spec=spec): + self.assertEqual(format(fraction, spec), expected) + + def test_format_g_presentation_type(self): + # Triples (fraction, specification, expected_result) + testcases = [ + (F('0.000012345678'), '.6g', '1.23457e-05'), + (F('0.00012345678'), '.6g', '0.000123457'), + (F('0.0012345678'), '.6g', '0.00123457'), + (F('0.012345678'), '.6g', '0.0123457'), + (F('0.12345678'), '.6g', '0.123457'), + (F('1.2345678'), '.6g', '1.23457'), + (F('12.345678'), '.6g', '12.3457'), + (F('123.45678'), '.6g', '123.457'), + (F('1234.5678'), '.6g', '1234.57'), + (F('12345.678'), '.6g', '12345.7'), + (F('123456.78'), '.6g', '123457'), + (F('1234567.8'), '.6g', '1.23457e+06'), + # Rounding up cases + (F('9.99999e+2'), '.4g', '1000'), + (F('9.99999e-8'), '.4g', '1e-07'), + (F('9.99999e+8'), '.4g', '1e+09'), + # Check round-ties-to-even behaviour + (F('-0.115'), '.2g', '-0.12'), + (F('-0.125'), '.2g', '-0.12'), + (F('-0.135'), '.2g', '-0.14'), + (F('-0.145'), '.2g', '-0.14'), + (F('0.115'), '.2g', '0.12'), + (F('0.125'), '.2g', '0.12'), + (F('0.135'), '.2g', '0.14'), + (F('0.145'), '.2g', '0.14'), + # Trailing zeros and decimal point suppressed by default ... + (F(0), '.6g', '0'), + (F('123.400'), '.6g', '123.4'), + (F('123.000'), '.6g', '123'), + (F('120.000'), '.6g', '120'), + (F('12000000'), '.6g', '1.2e+07'), + # ... but not when alternate form is in effect + (F(0), '#.6g', '0.00000'), + (F('123.400'), '#.6g', '123.400'), + (F('123.000'), '#.6g', '123.000'), + (F('120.000'), '#.6g', '120.000'), + (F('12000000'), '#.6g', '1.20000e+07'), + # 'G' format (uses 'E' instead of 'e' for the exponent indicator) + (F('123.45678'), '.6G', '123.457'), + (F('1234567.8'), '.6G', '1.23457E+06'), + # Default precision is 6 significant figures + (F('3.1415926535'), 'g', '3.14159'), + # Precision 0 is treated the same as precision 1. + (F('0.000031415'), '.0g', '3e-05'), + (F('0.00031415'), '.0g', '0.0003'), + (F('0.31415'), '.0g', '0.3'), + (F('3.1415'), '.0g', '3'), + (F('3.1415'), '#.0g', '3.'), + (F('31.415'), '.0g', '3e+01'), + (F('31.415'), '#.0g', '3.e+01'), + (F('0.000031415'), '.1g', '3e-05'), + (F('0.00031415'), '.1g', '0.0003'), + (F('0.31415'), '.1g', '0.3'), + (F('3.1415'), '.1g', '3'), + (F('3.1415'), '#.1g', '3.'), + (F('31.415'), '.1g', '3e+01'), + # Thousands separator + (F(2**64), '_.25g', '18_446_744_073_709_551_616'), + # As with 'e' format, z flag is legal, but has no effect + (F(-1, 7**100), 'zg', '-3.09169e-85'), + ] + for fraction, spec, expected in testcases: + with self.subTest(fraction=fraction, spec=spec): + self.assertEqual(format(fraction, spec), expected) + + def test_invalid_formats(self): + fraction = F(2, 3) + with self.assertRaises(TypeError): + format(fraction, None) + + invalid_specs = [ + 'Q6f', # regression test + # illegal to use fill or alignment when zero padding + 'X>010f', + 'X<010f', + 'X^010f', + 'X=010f', + '0>010f', + '0<010f', + '0^010f', + '0=010f', + '>010f', + '<010f', + '^010f', + '=010e', + '=010f', + '=010g', + '=010%', + '>00.2f', + '>00f', + # Too many zeros - minimum width should not have leading zeros + '006f', + # Leading zeros in precision + '.010f', + '.02f', + '.000f', + # Missing precision + '.e', + '.f', + '.g', + '.%', + # Z instead of z for negative zero suppression + 'Z.2f' + ] + for spec in invalid_specs: + with self.subTest(spec=spec): + with self.assertRaises(ValueError): + format(fraction, spec) + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_frame.py b/Lib/test/test_frame.py index 9cb2686f..6bb0144e 100644 --- a/Lib/test/test_frame.py +++ b/Lib/test/test_frame.py @@ -1,4 +1,5 @@ import gc +import operator import re import sys import textwrap @@ -6,6 +7,10 @@ import threading import types import unittest import weakref +try: + import _testcapi +except ImportError: + _testcapi = None from test import support from test.support import threading_helper @@ -279,7 +284,7 @@ class TestIncompleteFrameAreInvisible(unittest.TestCase): frame! """ nonlocal sneaky_frame_object - sneaky_frame_object = sys._getframe().f_back + sneaky_frame_object = sys._getframe().f_back.f_back # We're done here: gc.callbacks.remove(callback) @@ -368,5 +373,71 @@ class TestIncompleteFrameAreInvisible(unittest.TestCase): ) sneaky_frame_object = sneaky_frame_object.f_back + def test_entry_frames_are_invisible_during_teardown(self): + class C: + """A weakref'able class.""" + + def f(): + """Try to find globals and locals as this frame is being cleared.""" + ref = C() + # Ignore the fact that exec(C()) is a nonsense callback. We're only + # using exec here because it tries to access the current frame's + # globals and locals. If it's trying to get those from a shim frame, + # we'll crash before raising: + return weakref.ref(ref, exec) + + with support.catch_unraisable_exception() as catcher: + # Call from C, so there is a shim frame directly above f: + weak = operator.call(f) # BOOM! + # Cool, we didn't crash. Check that the callback actually happened: + self.assertIs(catcher.unraisable.exc_type, TypeError) + self.assertIsNone(weak()) + +@unittest.skipIf(_testcapi is None, 'need _testcapi') +class TestCAPI(unittest.TestCase): + def getframe(self): + return sys._getframe() + + def test_frame_getters(self): + frame = self.getframe() + self.assertEqual(frame.f_locals, _testcapi.frame_getlocals(frame)) + self.assertIs(frame.f_globals, _testcapi.frame_getglobals(frame)) + self.assertIs(frame.f_builtins, _testcapi.frame_getbuiltins(frame)) + self.assertEqual(frame.f_lasti, _testcapi.frame_getlasti(frame)) + + def test_getvar(self): + current_frame = sys._getframe() + x = 1 + self.assertEqual(_testcapi.frame_getvar(current_frame, "x"), 1) + self.assertEqual(_testcapi.frame_getvarstring(current_frame, b"x"), 1) + with self.assertRaises(NameError): + _testcapi.frame_getvar(current_frame, "y") + with self.assertRaises(NameError): + _testcapi.frame_getvarstring(current_frame, b"y") + + # wrong name type + with self.assertRaises(TypeError): + _testcapi.frame_getvar(current_frame, b'x') + with self.assertRaises(TypeError): + _testcapi.frame_getvar(current_frame, 123) + + def getgenframe(self): + yield sys._getframe() + + def test_frame_get_generator(self): + gen = self.getgenframe() + frame = next(gen) + self.assertIs(gen, _testcapi.frame_getgenerator(frame)) + + def test_frame_fback_api(self): + """Test that accessing `f_back` does not cause a segmentation fault on + a frame created with `PyFrame_New` (GH-99110).""" + def dummy(): + pass + + frame = _testcapi.frame_new(dummy.__code__, globals(), locals()) + # The following line should not cause a segmentation fault. + self.assertIsNone(frame.f_back) + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_fstring.py b/Lib/test/test_fstring.py index 453de621..4f05a149 100644 --- a/Lib/test/test_fstring.py +++ b/Lib/test/test_fstring.py @@ -13,8 +13,10 @@ import re import types import decimal import unittest +import warnings +from test import support from test.support.os_helper import temp_cwd -from test.support.script_helper import assert_python_failure +from test.support.script_helper import assert_python_failure, assert_python_ok a_global = 'global variable' @@ -329,13 +331,13 @@ non-important content self.assertEqual(t.body[1].lineno, 3) self.assertEqual(t.body[1].value.lineno, 3) self.assertEqual(t.body[1].value.values[0].lineno, 3) - self.assertEqual(t.body[1].value.values[1].lineno, 3) - self.assertEqual(t.body[1].value.values[2].lineno, 3) + self.assertEqual(t.body[1].value.values[1].lineno, 4) + self.assertEqual(t.body[1].value.values[2].lineno, 6) self.assertEqual(t.body[1].col_offset, 0) self.assertEqual(t.body[1].value.col_offset, 0) - self.assertEqual(t.body[1].value.values[0].col_offset, 0) - self.assertEqual(t.body[1].value.values[1].col_offset, 0) - self.assertEqual(t.body[1].value.values[2].col_offset, 0) + self.assertEqual(t.body[1].value.values[0].col_offset, 4) + self.assertEqual(t.body[1].value.values[1].col_offset, 2) + self.assertEqual(t.body[1].value.values[2].col_offset, 11) # NOTE: the following lineno information and col_offset is correct for # expressions within FormattedValues. binop = t.body[1].value.values[1].value @@ -366,13 +368,13 @@ a = f''' self.assertEqual(t.body[0].lineno, 2) self.assertEqual(t.body[0].value.lineno, 2) self.assertEqual(t.body[0].value.values[0].lineno, 2) - self.assertEqual(t.body[0].value.values[1].lineno, 2) - self.assertEqual(t.body[0].value.values[2].lineno, 2) + self.assertEqual(t.body[0].value.values[1].lineno, 3) + self.assertEqual(t.body[0].value.values[2].lineno, 3) self.assertEqual(t.body[0].col_offset, 0) self.assertEqual(t.body[0].value.col_offset, 4) - self.assertEqual(t.body[0].value.values[0].col_offset, 4) - self.assertEqual(t.body[0].value.values[1].col_offset, 4) - self.assertEqual(t.body[0].value.values[2].col_offset, 4) + self.assertEqual(t.body[0].value.values[0].col_offset, 8) + self.assertEqual(t.body[0].value.values[1].col_offset, 10) + self.assertEqual(t.body[0].value.values[2].col_offset, 17) # Check {blech} self.assertEqual(t.body[0].value.values[1].value.lineno, 3) self.assertEqual(t.body[0].value.values[1].value.end_lineno, 3) @@ -387,6 +389,20 @@ x = ( t = ast.parse(expr) self.assertEqual(type(t), ast.Module) self.assertEqual(len(t.body), 1) + # check the joinedstr location + joinedstr = t.body[0].value + self.assertEqual(type(joinedstr), ast.JoinedStr) + self.assertEqual(joinedstr.lineno, 3) + self.assertEqual(joinedstr.end_lineno, 3) + self.assertEqual(joinedstr.col_offset, 4) + self.assertEqual(joinedstr.end_col_offset, 17) + # check the formatted value location + fv = t.body[0].value.values[1] + self.assertEqual(type(fv), ast.FormattedValue) + self.assertEqual(fv.lineno, 3) + self.assertEqual(fv.end_lineno, 3) + self.assertEqual(fv.col_offset, 7) + self.assertEqual(fv.end_col_offset, 16) # check the test(t) location call = t.body[0].value.values[1].value self.assertEqual(type(call), ast.Call) @@ -397,6 +413,50 @@ x = ( expr = """ x = ( + u'wat', + u"wat", + b'wat', + b"wat", + f'wat', + f"wat", +) + +y = ( + u'''wat''', + u\"\"\"wat\"\"\", + b'''wat''', + b\"\"\"wat\"\"\", + f'''wat''', + f\"\"\"wat\"\"\", +) + """ + t = ast.parse(expr) + self.assertEqual(type(t), ast.Module) + self.assertEqual(len(t.body), 2) + x, y = t.body + + # Check the single quoted string offsets first. + offsets = [ + (elt.col_offset, elt.end_col_offset) + for elt in x.value.elts + ] + self.assertTrue(all( + offset == (4, 10) + for offset in offsets + )) + + # Check the triple quoted string offsets. + offsets = [ + (elt.col_offset, elt.end_col_offset) + for elt in y.value.elts + ] + self.assertTrue(all( + offset == (4, 14) + for offset in offsets + )) + + expr = """ +x = ( 'PERL_MM_OPT', ( f'wat' f'some_string={f(x)} ' @@ -415,9 +475,9 @@ x = ( # check the first wat self.assertEqual(type(wat1), ast.Constant) self.assertEqual(wat1.lineno, 4) - self.assertEqual(wat1.end_lineno, 6) - self.assertEqual(wat1.col_offset, 12) - self.assertEqual(wat1.end_col_offset, 18) + self.assertEqual(wat1.end_lineno, 5) + self.assertEqual(wat1.col_offset, 14) + self.assertEqual(wat1.end_col_offset, 26) # check the call call = middle.value self.assertEqual(type(call), ast.Call) @@ -427,10 +487,32 @@ x = ( self.assertEqual(call.end_col_offset, 31) # check the second wat self.assertEqual(type(wat2), ast.Constant) - self.assertEqual(wat2.lineno, 4) + self.assertEqual(wat2.lineno, 5) self.assertEqual(wat2.end_lineno, 6) - self.assertEqual(wat2.col_offset, 12) - self.assertEqual(wat2.end_col_offset, 18) + self.assertEqual(wat2.col_offset, 32) + # wat ends at the offset 17, but the whole f-string + # ends at the offset 18 (since the quote is part of the + # f-string but not the wat string) + self.assertEqual(wat2.end_col_offset, 17) + self.assertEqual(fstring.end_col_offset, 18) + + def test_ast_fstring_empty_format_spec(self): + expr = "f'{expr:}'" + + mod = ast.parse(expr) + self.assertEqual(type(mod), ast.Module) + self.assertEqual(len(mod.body), 1) + + fstring = mod.body[0].value + self.assertEqual(type(fstring), ast.JoinedStr) + self.assertEqual(len(fstring.values), 1) + + fv = fstring.values[0] + self.assertEqual(type(fv), ast.FormattedValue) + + format_spec = fv.format_spec + self.assertEqual(type(format_spec), ast.JoinedStr) + self.assertEqual(len(format_spec.values), 0) def test_docstring(self): def f(): @@ -467,36 +549,59 @@ x = ( self.assertEqual(f' ', ' ') def test_unterminated_string(self): - self.assertAllRaise(SyntaxError, 'f-string: unterminated string', + self.assertAllRaise(SyntaxError, 'unterminated string', [r"""f'{"x'""", r"""f'{"x}'""", r"""f'{("x'""", r"""f'{("x}'""", ]) + @unittest.skipIf(support.is_wasi, "exhausts limited stack on WASI") def test_mismatched_parens(self): - self.assertAllRaise(SyntaxError, r"f-string: closing parenthesis '\}' " + self.assertAllRaise(SyntaxError, r"closing parenthesis '\}' " r"does not match opening parenthesis '\('", ["f'{((}'", ]) - self.assertAllRaise(SyntaxError, r"f-string: closing parenthesis '\)' " + self.assertAllRaise(SyntaxError, r"closing parenthesis '\)' " r"does not match opening parenthesis '\['", ["f'{a[4)}'", ]) - self.assertAllRaise(SyntaxError, r"f-string: closing parenthesis '\]' " + self.assertAllRaise(SyntaxError, r"closing parenthesis '\]' " r"does not match opening parenthesis '\('", ["f'{a(4]}'", ]) - self.assertAllRaise(SyntaxError, r"f-string: closing parenthesis '\}' " + self.assertAllRaise(SyntaxError, r"closing parenthesis '\}' " r"does not match opening parenthesis '\['", ["f'{a[4}'", ]) - self.assertAllRaise(SyntaxError, r"f-string: closing parenthesis '\}' " + self.assertAllRaise(SyntaxError, r"closing parenthesis '\}' " r"does not match opening parenthesis '\('", ["f'{a(4}'", ]) self.assertRaises(SyntaxError, eval, "f'{" + "("*500 + "}'") + @unittest.skipIf(support.is_wasi, "exhausts limited stack on WASI") + def test_fstring_nested_too_deeply(self): + self.assertAllRaise(SyntaxError, + "f-string: expressions nested too deeply", + ['f"{1+2:{1+2:{1+1:{1}}}}"']) + + def create_nested_fstring(n): + if n == 0: + return "1+1" + prev = create_nested_fstring(n-1) + return f'f"{{{prev}}}"' + + self.assertAllRaise(SyntaxError, + "too many nested f-strings", + [create_nested_fstring(160)]) + + def test_syntax_error_in_nested_fstring(self): + # See gh-104016 for more information on this crash + self.assertAllRaise(SyntaxError, + "invalid syntax", + ['f"{1 1:' + ('{f"1:' * 199)]) + def test_double_braces(self): self.assertEqual(f'{{', '{') self.assertEqual(f'a{{', 'a{') @@ -559,8 +664,14 @@ x = ( self.assertEqual(f'' '' f'', '') self.assertEqual(f'' '' f'' '', '') - self.assertAllRaise(SyntaxError, "f-string: expecting '}'", - ["f'{3' f'}'", # can't concat to get a valid f-string + # This is not really [f'{'] + [f'}'] since we treat the inside + # of braces as a purely new context, so it is actually f'{ and + # then eval(' f') (a valid expression) and then }' which would + # constitute a valid f-string. + self.assertEqual(f'{' f'}', ' f') + + self.assertAllRaise(SyntaxError, "expecting '}'", + ['''f'{3' f"}"''', # can't concat to get a valid f-string ]) def test_comments(self): @@ -569,15 +680,50 @@ x = ( self.assertEqual(f'{"#"}', '#') self.assertEqual(f'{d["#"]}', 'hash') - self.assertAllRaise(SyntaxError, "f-string expression part cannot include '#'", - ["f'{1#}'", # error because the expression becomes "(1#)" - "f'{3(#)}'", + self.assertAllRaise(SyntaxError, "'{' was never closed", + ["f'{1#}'", # error because everything after '#' is a comment "f'{#}'", + "f'one: {1#}'", + "f'{1# one} {2 this is a comment still#}'", ]) self.assertAllRaise(SyntaxError, r"f-string: unmatched '\)'", ["f'{)#}'", # When wrapped in parens, this becomes # '()#)'. Make sure that doesn't compile. ]) + self.assertEqual(f'''A complex trick: { +2 # two +}''', 'A complex trick: 2') + self.assertEqual(f''' +{ +40 # fourty ++ # plus +2 # two +}''', '\n42') + self.assertEqual(f''' +{ +40 # fourty ++ # plus +2 # two +}''', '\n42') + + self.assertEqual(f''' +# this is not a comment +{ # the following operation it's +3 # this is a number +* 2}''', '\n# this is not a comment\n6') + self.assertEqual(f''' +{# f'a {comment}' +86 # constant +# nothing more +}''', '\n86') + + self.assertAllRaise(SyntaxError, r"f-string: valid expression required before '}'", + ["""f''' +{ +# only a comment +}''' +""", # this is equivalent to f'{}' + ]) def test_many_expressions(self): # Create a string with many expressions in it. Note that @@ -618,29 +764,35 @@ x = ( self.assertEqual(f'{-10:-{"#"}1{0}x}', ' -0xa') self.assertEqual(f'{-10:{"-"}#{1}0{"x"}}', ' -0xa') self.assertEqual(f'{10:#{3 != {4:5} and width}x}', ' 0xa') + self.assertEqual(f'result: {value:{width:{0}}.{precision:1}}', 'result: 12.35') - self.assertAllRaise(SyntaxError, "f-string: expecting '}'", + self.assertAllRaise(SyntaxError, "f-string: expecting ':' or '}'", ["""f'{"s"!r{":10"}}'""", - # This looks like a nested format spec. ]) - self.assertAllRaise(SyntaxError, "f-string: invalid syntax", + self.assertAllRaise(SyntaxError, + "f-string: expecting a valid expression after '{'", [# Invalid syntax inside a nested spec. "f'{4:{/5}}'", ]) - self.assertAllRaise(SyntaxError, "f-string: expressions nested too deeply", - [# Can't nest format specifiers. - "f'result: {value:{width:{0}}.{precision:1}}'", - ]) - self.assertAllRaise(SyntaxError, 'f-string: invalid conversion character', [# No expansion inside conversion or for # the : or ! itself. """f'{"s"!{"r"}}'""", ]) + def test_custom_format_specifier(self): + class CustomFormat: + def __format__(self, format_spec): + return format_spec + + self.assertEqual(f'{CustomFormat():\n}', '\n') + self.assertEqual(f'{CustomFormat():\u2603}', '☃') + with self.assertWarns(SyntaxWarning): + exec(r'f"{F():¯\_(ツ)_/¯}"', {'F': CustomFormat}) + def test_side_effect_order(self): class X: def __init__(self): @@ -653,7 +805,8 @@ x = ( self.assertEqual(f'{x} {x}', '1 2') def test_missing_expression(self): - self.assertAllRaise(SyntaxError, 'f-string: empty expression not allowed', + self.assertAllRaise(SyntaxError, + "f-string: valid expression required before '}'", ["f'{}'", "f'{ }'" "f' {} '", @@ -665,8 +818,8 @@ x = ( "f'''{\t\f\r\n}'''", ]) - # Different error messeges are raised when a specfier ('!', ':' or '=') is used after an empty expression - self.assertAllRaise(SyntaxError, "f-string: expression required before '!'", + self.assertAllRaise(SyntaxError, + "f-string: valid expression required before '!'", ["f'{!r}'", "f'{ !r}'", "f'{!}'", @@ -687,7 +840,8 @@ x = ( "f'{ !xr:a}'", ]) - self.assertAllRaise(SyntaxError, "f-string: expression required before ':'", + self.assertAllRaise(SyntaxError, + "f-string: valid expression required before ':'", ["f'{:}'", "f'{ :!}'", "f'{:2}'", @@ -695,7 +849,8 @@ x = ( "f'{:'", ]) - self.assertAllRaise(SyntaxError, "f-string: expression required before '='", + self.assertAllRaise(SyntaxError, + "f-string: valid expression required before '='", ["f'{=}'", "f'{ =}'", "f'{ =:}'", @@ -713,24 +868,18 @@ x = ( def test_parens_in_expressions(self): self.assertEqual(f'{3,}', '(3,)') - # Add these because when an expression is evaluated, parens - # are added around it. But we shouldn't go from an invalid - # expression to a valid one. The added parens are just - # supposed to allow whitespace (including newlines). - self.assertAllRaise(SyntaxError, 'f-string: invalid syntax', + self.assertAllRaise(SyntaxError, + "f-string: expecting a valid expression after '{'", ["f'{,}'", - "f'{,}'", # this is (,), which is an error ]) self.assertAllRaise(SyntaxError, r"f-string: unmatched '\)'", ["f'{3)+(4}'", ]) - self.assertAllRaise(SyntaxError, 'unterminated string literal', - ["f'{\n}'", - ]) def test_newlines_before_syntax_error(self): - self.assertAllRaise(SyntaxError, "invalid syntax", + self.assertAllRaise(SyntaxError, + "f-string: expecting a valid expression after '{'", ["f'{.}'", "\nf'{.}'", "\n\nf'{.}'"]) def test_backslashes_in_string_part(self): @@ -774,9 +923,12 @@ x = ( self.assertEqual(f'2\x203', '2 3') self.assertEqual(f'\x203', ' 3') - with self.assertWarns(DeprecationWarning): # invalid escape sequence + with self.assertWarns(SyntaxWarning): # invalid escape sequence value = eval(r"f'\{6*7}'") self.assertEqual(value, '\\42') + with self.assertWarns(SyntaxWarning): # invalid escape sequence + value = eval(r"f'\g'") + self.assertEqual(value, '\\g') self.assertEqual(f'\\{6*7}', '\\42') self.assertEqual(fr'\{6*7}', '\\42') @@ -807,18 +959,40 @@ x = ( r"'\N{GREEK CAPITAL LETTER DELTA'", ]) - def test_no_backslashes_in_expression_part(self): - self.assertAllRaise(SyntaxError, 'f-string expression part cannot include a backslash', - [r"f'{\'a\'}'", - r"f'{\t3}'", - r"f'{\}'", - r"rf'{\'a\'}'", - r"rf'{\t3}'", - r"rf'{\}'", - r"""rf'{"\N{LEFT CURLY BRACKET}"}'""", - r"f'{\n}'", + def test_backslashes_in_expression_part(self): + self.assertEqual(f"{( + 1 + + 2 + )}", "3") + + self.assertEqual("\N{LEFT CURLY BRACKET}", '{') + self.assertEqual(f'{"\N{LEFT CURLY BRACKET}"}', '{') + self.assertEqual(rf'{"\N{LEFT CURLY BRACKET}"}', '{') + + self.assertAllRaise(SyntaxError, + "f-string: valid expression required before '}'", + ["f'{\n}'", ]) + def test_invalid_backslashes_inside_fstring_context(self): + # All of these variations are invalid python syntax, + # so they are also invalid in f-strings as well. + cases = [ + formatting.format(expr=expr) + for formatting in [ + "{expr}", + "f'{{{expr}}}'", + "rf'{{{expr}}}'", + ] + for expr in [ + r"\'a\'", + r"\t3", + r"\\"[0], + ] + ] + self.assertAllRaise(SyntaxError, 'unexpected character after line continuation', + cases) + def test_no_escapes_for_braces(self): """ Only literal curly braces begin an expression. @@ -841,10 +1015,83 @@ x = ( self.assertEqual(f'{(lambda y:x*y)("8"):10}', "88888 ") # lambda doesn't work without parens, because the colon - # makes the parser think it's a format_spec - self.assertAllRaise(SyntaxError, 'f-string: invalid syntax', + # makes the parser think it's a format_spec + # emit warning if we can match a format_spec + self.assertAllRaise(SyntaxError, + "f-string: lambda expressions are not allowed " + "without parentheses", ["f'{lambda x:x}'", + "f'{lambda :x}'", + "f'{lambda *arg, :x}'", + "f'{1, lambda:x}'", + "f'{lambda x:}'", + "f'{lambda :}'", ]) + # Ensure the detection of invalid lambdas doesn't trigger detection + # for valid lambdas in the second error pass + with self.assertRaisesRegex(SyntaxError, "invalid syntax"): + compile("lambda name_3=f'{name_4}': {name_3}\n1 $ 1", "<string>", "exec") + + # but don't emit the paren warning in general cases + with self.assertRaisesRegex(SyntaxError, "f-string: expecting a valid expression after '{'"): + eval("f'{+ lambda:None}'") + + def test_valid_prefixes(self): + self.assertEqual(F'{1}', "1") + self.assertEqual(FR'{2}', "2") + self.assertEqual(fR'{3}', "3") + + def test_roundtrip_raw_quotes(self): + self.assertEqual(fr"\'", "\\'") + self.assertEqual(fr'\"', '\\"') + self.assertEqual(fr'\"\'', '\\"\\\'') + self.assertEqual(fr'\'\"', '\\\'\\"') + self.assertEqual(fr'\"\'\"', '\\"\\\'\\"') + self.assertEqual(fr'\'\"\'', '\\\'\\"\\\'') + self.assertEqual(fr'\"\'\"\'', '\\"\\\'\\"\\\'') + + def test_fstring_backslash_before_double_bracket(self): + deprecated_cases = [ + (r"f'\{{\}}'", '\\{\\}'), + (r"f'\{{'", '\\{'), + (r"f'\{{{1+1}'", '\\{2'), + (r"f'\}}{1+1}'", '\\}2'), + (r"f'{1+1}\}}'", '2\\}') + ] + for case, expected_result in deprecated_cases: + with self.subTest(case=case, expected_result=expected_result): + with self.assertWarns(SyntaxWarning): + result = eval(case) + self.assertEqual(result, expected_result) + self.assertEqual(fr'\{{\}}', '\\{\\}') + self.assertEqual(fr'\{{', '\\{') + self.assertEqual(fr'\{{{1+1}', '\\{2') + self.assertEqual(fr'\}}{1+1}', '\\}2') + self.assertEqual(fr'{1+1}\}}', '2\\}') + + def test_fstring_backslash_before_double_bracket_warns_once(self): + with self.assertWarns(SyntaxWarning) as w: + eval(r"f'\{{'") + self.assertEqual(len(w.warnings), 1) + self.assertEqual(w.warnings[0].category, SyntaxWarning) + + def test_fstring_backslash_prefix_raw(self): + self.assertEqual(f'\\', '\\') + self.assertEqual(f'\\\\', '\\\\') + self.assertEqual(fr'\\', r'\\') + self.assertEqual(fr'\\\\', r'\\\\') + self.assertEqual(rf'\\', r'\\') + self.assertEqual(rf'\\\\', r'\\\\') + self.assertEqual(Rf'\\', R'\\') + self.assertEqual(Rf'\\\\', R'\\\\') + self.assertEqual(fR'\\', R'\\') + self.assertEqual(fR'\\\\', R'\\\\') + self.assertEqual(FR'\\', R'\\') + self.assertEqual(FR'\\\\', R'\\\\') + + def test_fstring_format_spec_greedy_matching(self): + self.assertEqual(f"{1:}}}", "1}") + self.assertEqual(f"{1:>3{5}}}}", " 1}") def test_yield(self): # Not terribly useful, but make sure the yield turns @@ -1035,25 +1282,50 @@ x = ( self.assertEqual(f'{"a"!r}', "'a'") self.assertEqual(f'{"a"!a}', "'a'") + # Conversions can have trailing whitespace after them since it + # does not provide any significance + self.assertEqual(f"{3!s }", "3") + self.assertEqual(f'{3.14!s :10.10}', '3.14 ') + # Not a conversion. self.assertEqual(f'{"a!r"}', "a!r") # Not a conversion, but show that ! is allowed in a format spec. self.assertEqual(f'{3.14:!<10.10}', '3.14!!!!!!') - self.assertAllRaise(SyntaxError, 'f-string: invalid conversion character', - ["f'{3!g}'", - "f'{3!A}'", - "f'{3!3}'", - "f'{3!G}'", - "f'{3!!}'", + self.assertAllRaise(SyntaxError, "f-string: expecting '}'", + ["f'{3!'", + "f'{3!s'", + "f'{3!g'", + ]) + + self.assertAllRaise(SyntaxError, 'f-string: missing conversion character', + ["f'{3!}'", + "f'{3!:'", "f'{3!:}'", - "f'{3! s}'", # no space before conversion char ]) - self.assertAllRaise(SyntaxError, "f-string: expecting '}'", - ["f'{x!s{y}}'", - "f'{3!ss}'", + for conv_identifier in 'g', 'A', 'G', 'ä', 'ɐ': + self.assertAllRaise(SyntaxError, + "f-string: invalid conversion character %r: " + "expected 's', 'r', or 'a'" % conv_identifier, + ["f'{3!" + conv_identifier + "}'"]) + + for conv_non_identifier in '3', '!': + self.assertAllRaise(SyntaxError, + "f-string: invalid conversion character", + ["f'{3!" + conv_non_identifier + "}'"]) + + for conv in ' s', ' s ': + self.assertAllRaise(SyntaxError, + "f-string: conversion type must come right after the" + " exclamanation mark", + ["f'{3!" + conv + "}'"]) + + self.assertAllRaise(SyntaxError, + "f-string: invalid conversion character 'ss': " + "expected 's', 'r', or 'a'", + ["f'{3!ss}'", "f'{3!ss:}'", "f'{3!ss:s}'", ]) @@ -1086,8 +1358,7 @@ x = ( ]) self.assertAllRaise(SyntaxError, "f-string: expecting '}'", - ["f'{3:{{>10}'", - "f'{3'", + ["f'{3'", "f'{3!'", "f'{3:'", "f'{3!s'", @@ -1100,11 +1371,14 @@ x = ( "f'{{{'", "f'{{}}{'", "f'{'", - "f'x{<'", # See bpo-46762. - "f'x{>'", "f'{i='", # See gh-93418. ]) + self.assertAllRaise(SyntaxError, + "f-string: expecting a valid expression after '{'", + ["f'{3:{{>10}'", + ]) + # But these are just normal strings. self.assertEqual(f'{"{"}', '{') self.assertEqual(f'{"}"}', '}') @@ -1303,6 +1577,7 @@ x = ( self.assertEqual(f'X{x =}Y', 'Xx ='+repr(x)+'Y') self.assertEqual(f'X{x= }Y', 'Xx= '+repr(x)+'Y') self.assertEqual(f'X{x = }Y', 'Xx = '+repr(x)+'Y') + self.assertEqual(f"sadsd {1 + 1 = :{1 + 1:1d}f}", "sadsd 1 + 1 = 2.000000") # These next lines contains tabs. Backslash escapes don't # work in f-strings. @@ -1324,7 +1599,8 @@ x = ( self.assertEqual(x, 10) def test_invalid_syntax_error_message(self): - with self.assertRaisesRegex(SyntaxError, "f-string: invalid syntax"): + with self.assertRaisesRegex(SyntaxError, + "f-string: expecting '=', or '!', or ':', or '}'"): compile("f'{a $ b}'", "?", "exec") def test_with_two_commas_in_format_specifier(self): @@ -1348,13 +1624,68 @@ x = ( f'{1:_,}' def test_syntax_error_for_starred_expressions(self): - error_msg = re.escape("cannot use starred expression here") - with self.assertRaisesRegex(SyntaxError, error_msg): + with self.assertRaisesRegex(SyntaxError, "can't use starred expression here"): compile("f'{*a}'", "?", "exec") - error_msg = re.escape("cannot use double starred expression here") - with self.assertRaisesRegex(SyntaxError, error_msg): + with self.assertRaisesRegex(SyntaxError, + "f-string: expecting a valid expression after '{'"): compile("f'{**a}'", "?", "exec") + def test_not_closing_quotes(self): + self.assertAllRaise(SyntaxError, "unterminated f-string literal", ['f"', "f'"]) + self.assertAllRaise(SyntaxError, "unterminated triple-quoted f-string literal", + ['f"""', "f'''"]) + # Ensure that the errors are reported at the correct line number. + data = '''\ +x = 1 + 1 +y = 2 + 2 +z = f""" +sdfjnsdfjsdf +sdfsdfs{1+ +2} dfigdf {3+ +4}sdufsd"" +''' + try: + compile(data, "?", "exec") + except SyntaxError as e: + self.assertEqual(e.text, 'z = f"""') + self.assertEqual(e.lineno, 3) + def test_syntax_error_after_debug(self): + self.assertAllRaise(SyntaxError, "f-string: expecting a valid expression after '{'", + [ + "f'{1=}{;'", + "f'{1=}{+;'", + "f'{1=}{2}{;'", + "f'{1=}{3}{;'", + ]) + self.assertAllRaise(SyntaxError, "f-string: expecting '=', or '!', or ':', or '}'", + [ + "f'{1=}{1;'", + "f'{1=}{1;}'", + ]) + + def test_debug_in_file(self): + with temp_cwd(): + script = 'script.py' + with open('script.py', 'w') as f: + f.write(f"""\ +print(f'''{{ +3 +=}}''')""") + + _, stdout, _ = assert_python_ok(script) + self.assertEqual(stdout.decode('utf-8').strip().replace('\r\n', '\n').replace('\r', '\n'), + "3\n=3") + + def test_syntax_warning_infinite_recursion_in_file(self): + with temp_cwd(): + script = 'script.py' + with open(script, 'w') as f: + f.write(r"print(f'\{1}')") + + _, stdout, stderr = assert_python_ok(script) + self.assertIn(rb'\1', stdout) + self.assertEqual(len(stderr.strip().splitlines()), 2) + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_ftplib.py b/Lib/test/test_ftplib.py index 082a90d4..544228e3 100644 --- a/Lib/test/test_ftplib.py +++ b/Lib/test/test_ftplib.py @@ -21,13 +21,11 @@ from test import support from test.support import threading_helper from test.support import socket_helper from test.support import warnings_helper +from test.support import asynchat +from test.support import asyncore from test.support.socket_helper import HOST, HOSTv6 -asynchat = warnings_helper.import_deprecated('asynchat') -asyncore = warnings_helper.import_deprecated('asyncore') - - support.requires_working_socket(module=True) TIMEOUT = support.LOOPBACK_TIMEOUT @@ -984,11 +982,11 @@ class TestTLS_FTPClass(TestCase): ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) ctx.check_hostname = False ctx.verify_mode = ssl.CERT_NONE - self.assertRaises(ValueError, ftplib.FTP_TLS, keyfile=CERTFILE, + self.assertRaises(TypeError, ftplib.FTP_TLS, keyfile=CERTFILE, context=ctx) - self.assertRaises(ValueError, ftplib.FTP_TLS, certfile=CERTFILE, + self.assertRaises(TypeError, ftplib.FTP_TLS, certfile=CERTFILE, context=ctx) - self.assertRaises(ValueError, ftplib.FTP_TLS, certfile=CERTFILE, + self.assertRaises(TypeError, ftplib.FTP_TLS, certfile=CERTFILE, keyfile=CERTFILE, context=ctx) self.client = ftplib.FTP_TLS(context=ctx, timeout=TIMEOUT) diff --git a/Lib/test/test_funcattrs.py b/Lib/test/test_funcattrs.py index 77977d0a..35b473d5 100644 --- a/Lib/test/test_funcattrs.py +++ b/Lib/test/test_funcattrs.py @@ -1,5 +1,6 @@ import textwrap import types +import typing import unittest @@ -190,6 +191,23 @@ class FunctionPropertiesTest(FuncAttrsTest): # __qualname__ must be a string self.cannot_set_attr(self.b, '__qualname__', 7, TypeError) + def test___type_params__(self): + def generic[T](): pass + def not_generic(): pass + lambda_ = lambda: ... + T, = generic.__type_params__ + self.assertIsInstance(T, typing.TypeVar) + self.assertEqual(generic.__type_params__, (T,)) + for func in (not_generic, lambda_): + with self.subTest(func=func): + self.assertEqual(func.__type_params__, ()) + with self.assertRaises(TypeError): + del func.__type_params__ + with self.assertRaises(TypeError): + func.__type_params__ = 42 + func.__type_params__ = (T,) + self.assertEqual(func.__type_params__, (T,)) + def test___code__(self): num_one, num_two = 7, 8 def a(): pass diff --git a/Lib/test/test_functools.py b/Lib/test/test_functools.py index 382e7dbf..ce2bdeb6 100644 --- a/Lib/test/test_functools.py +++ b/Lib/test/test_functools.py @@ -13,24 +13,29 @@ import time import typing import unittest import unittest.mock -import os import weakref import gc from weakref import proxy import contextlib +from inspect import Signature from test.support import import_helper from test.support import threading_helper -from test.support.script_helper import assert_python_ok import functools py_functools = import_helper.import_fresh_module('functools', blocked=['_functools']) -c_functools = import_helper.import_fresh_module('functools') +c_functools = import_helper.import_fresh_module('functools', + fresh=['_functools']) decimal = import_helper.import_fresh_module('decimal', fresh=['_decimal']) +_partial_types = [py_functools.partial] +if c_functools: + _partial_types.append(c_functools.partial) + + @contextlib.contextmanager def replaced_module(name, replacement): original_module = sys.modules[name] @@ -202,7 +207,7 @@ class TestPartial: kwargs = {'a': object(), 'b': object()} kwargs_reprs = ['a={a!r}, b={b!r}'.format_map(kwargs), 'b={b!r}, a={a!r}'.format_map(kwargs)] - if self.partial in (c_functools.partial, py_functools.partial): + if self.partial in _partial_types: name = 'functools.partial' else: name = self.partial.__name__ @@ -224,7 +229,7 @@ class TestPartial: for kwargs_repr in kwargs_reprs]) def test_recursive_repr(self): - if self.partial in (c_functools.partial, py_functools.partial): + if self.partial in _partial_types: name = 'functools.partial' else: name = self.partial.__name__ @@ -251,7 +256,7 @@ class TestPartial: f.__setstate__((capture, (), {}, {})) def test_pickle(self): - with self.AllowPickle(): + with replaced_module('functools', self.module): f = self.partial(signature, ['asdf'], bar=[True]) f.attr = [] for proto in range(pickle.HIGHEST_PROTOCOL + 1): @@ -334,7 +339,7 @@ class TestPartial: self.assertIs(type(r[0]), tuple) def test_recursive_pickle(self): - with self.AllowPickle(): + with replaced_module('functools', self.module): f = self.partial(capture) f.__setstate__((f, (), {}, {})) try: @@ -388,14 +393,9 @@ class TestPartial: @unittest.skipUnless(c_functools, 'requires the C _functools module') class TestPartialC(TestPartial, unittest.TestCase): if c_functools: + module = c_functools partial = c_functools.partial - class AllowPickle: - def __enter__(self): - return self - def __exit__(self, type, value, tb): - return False - def test_attributes_unwritable(self): # attributes should not be writable p = self.partial(capture, 1, 2, a=10, b=20) @@ -438,15 +438,9 @@ class TestPartialC(TestPartial, unittest.TestCase): class TestPartialPy(TestPartial, unittest.TestCase): + module = py_functools partial = py_functools.partial - class AllowPickle: - def __init__(self): - self._cm = replaced_module("functools", py_functools) - def __enter__(self): - return self._cm.__enter__() - def __exit__(self, type, value, tb): - return self._cm.__exit__(type, value, tb) if c_functools: class CPartialSubclass(c_functools.partial): @@ -618,7 +612,7 @@ class TestUpdateWrapper(unittest.TestCase): def _default_update(self): - def f(a:'This is a new annotation'): + def f[T](a:'This is a new annotation'): """This is a test""" pass f.attr = 'This is also a test' @@ -631,12 +625,14 @@ class TestUpdateWrapper(unittest.TestCase): def test_default_update(self): wrapper, f = self._default_update() self.check_wrapper(wrapper, f) + T, = f.__type_params__ self.assertIs(wrapper.__wrapped__, f) self.assertEqual(wrapper.__name__, 'f') self.assertEqual(wrapper.__qualname__, f.__qualname__) self.assertEqual(wrapper.attr, 'This is also a test') self.assertEqual(wrapper.__annotations__['a'], 'This is a new annotation') self.assertNotIn('b', wrapper.__annotations__) + self.assertEqual(wrapper.__type_params__, (T,)) @unittest.skipIf(sys.flags.optimize >= 2, "Docstrings are omitted with -O2 and above") @@ -943,6 +939,10 @@ class TestCmpToKey: self.assertRaises(TypeError, hash, k) self.assertNotIsInstance(k, collections.abc.Hashable) + def test_cmp_to_signature(self): + self.assertEqual(str(Signature.from_callable(self.cmp_to_key)), + '(mycmp)') + @unittest.skipUnless(c_functools, 'requires the C _functools module') class TestCmpToKeyC(TestCmpToKey, unittest.TestCase): @@ -1855,14 +1855,22 @@ class TestLRU: for ref in refs: self.assertIsNone(ref()) + def test_common_signatures(self): + def orig(): ... + lru = self.module.lru_cache(1)(orig) + + self.assertEqual(str(Signature.from_callable(lru.cache_info)), '()') + self.assertEqual(str(Signature.from_callable(lru.cache_clear)), '()') + @py_functools.lru_cache() def py_cached_func(x, y): return 3 * x + y -@c_functools.lru_cache() -def c_cached_func(x, y): - return 3 * x + y +if c_functools: + @c_functools.lru_cache() + def c_cached_func(x, y): + return 3 * x + y class TestLRUPy(TestLRU, unittest.TestCase): @@ -1879,18 +1887,20 @@ class TestLRUPy(TestLRU, unittest.TestCase): return 3 * x + y +@unittest.skipUnless(c_functools, 'requires the C _functools module') class TestLRUC(TestLRU, unittest.TestCase): - module = c_functools - cached_func = c_cached_func, + if c_functools: + module = c_functools + cached_func = c_cached_func, - @module.lru_cache() - def cached_meth(self, x, y): - return 3 * x + y + @module.lru_cache() + def cached_meth(self, x, y): + return 3 * x + y - @staticmethod - @module.lru_cache() - def cached_staticmeth(x, y): - return 3 * x + y + @staticmethod + @module.lru_cache() + def cached_staticmeth(x, y): + return 3 * x + y class TestSingleDispatch(unittest.TestCase): @@ -2005,7 +2015,7 @@ class TestSingleDispatch(unittest.TestCase): c.MutableSequence.register(D) bases = [c.MutableSequence, c.MutableMapping] for haystack in permutations(bases): - m = mro(D, bases) + m = mro(D, haystack) self.assertEqual(m, [D, c.MutableSequence, c.Sequence, c.Reversible, collections.defaultdict, dict, c.MutableMapping, c.Mapping, c.Collection, c.Sized, c.Iterable, c.Container, @@ -2921,21 +2931,6 @@ class OptionallyCachedCostItem: cached_cost = py_functools.cached_property(get_cost) -class CachedCostItemWait: - - def __init__(self, event): - self._cost = 1 - self.lock = py_functools.RLock() - self.event = event - - @py_functools.cached_property - def cost(self): - self.event.wait(1) - with self.lock: - self._cost += 1 - return self._cost - - class CachedCostItemWithSlots: __slots__ = ('_cost') @@ -2960,27 +2955,6 @@ class TestCachedProperty(unittest.TestCase): self.assertEqual(item.get_cost(), 4) self.assertEqual(item.cached_cost, 3) - @threading_helper.requires_working_threading() - def test_threaded(self): - go = threading.Event() - item = CachedCostItemWait(go) - - num_threads = 3 - - orig_si = sys.getswitchinterval() - sys.setswitchinterval(1e-6) - try: - threads = [ - threading.Thread(target=lambda: item.cost) - for k in range(num_threads) - ] - with threading_helper.start_threads(threads): - go.set() - finally: - sys.setswitchinterval(orig_si) - - self.assertEqual(item.cost, 2) - def test_object_with_slots(self): item = CachedCostItemWithSlots() with self.assertRaisesRegex( @@ -3006,7 +2980,7 @@ class TestCachedProperty(unittest.TestCase): def test_reuse_different_names(self): """Disallow this case because decorated function a would not be cached.""" - with self.assertRaises(RuntimeError) as ctx: + with self.assertRaises(TypeError) as ctx: class ReusedCachedProperty: @py_functools.cached_property def a(self): @@ -3015,7 +2989,7 @@ class TestCachedProperty(unittest.TestCase): b = a self.assertEqual( - str(ctx.exception.__context__), + str(ctx.exception), str(TypeError("Cannot assign the same cached_property to two different names ('a' and 'b').")) ) @@ -3061,6 +3035,25 @@ class TestCachedProperty(unittest.TestCase): def test_doc(self): self.assertEqual(CachedCostItem.cost.__doc__, "The cost of the item.") + def test_subclass_with___set__(self): + """Caching still works for a subclass defining __set__.""" + class readonly_cached_property(py_functools.cached_property): + def __set__(self, obj, value): + raise AttributeError("read only property") + + class Test: + def __init__(self, prop): + self._prop = prop + + @readonly_cached_property + def prop(self): + return self._prop + + t = Test(1) + self.assertEqual(t.prop, 1) + t._prop = 999 + self.assertEqual(t.prop, 1) + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_future.py b/Lib/test/test_future.py index c3e8420d..4730bfaf 100644 --- a/Lib/test/test_future.py +++ b/Lib/test/test_future.py @@ -3,8 +3,8 @@ import __future__ import ast import unittest -from test import support from test.support import import_helper +from test.support.script_helper import spawn_python, kill_python from textwrap import dedent import os import re @@ -61,7 +61,7 @@ class FutureTest(unittest.TestCase): def test_badfuture7(self): with self.assertRaises(SyntaxError) as cm: from test import badsyntax_future7 - self.check_syntax_error(cm.exception, "badsyntax_future7", 3, 53) + self.check_syntax_error(cm.exception, "badsyntax_future7", 3, 54) def test_badfuture8(self): with self.assertRaises(SyntaxError) as cm: @@ -122,6 +122,13 @@ class FutureTest(unittest.TestCase): exec("from __future__ import unicode_literals; x = ''", {}, scope) self.assertIsInstance(scope["x"], str) + def test_syntactical_future_repl(self): + p = spawn_python('-i') + p.stdin.write(b"from __future__ import barry_as_FLUFL\n") + p.stdin.write(b"2 <> 3\n") + out = kill_python(p) + self.assertNotIn(b'SyntaxError: invalid syntax', out) + class AnnotationsFutureTestCase(unittest.TestCase): template = dedent( """ diff --git a/Lib/test/test_gc.py b/Lib/test/test_gc.py index dbbd67b4..db7cb9ac 100644 --- a/Lib/test/test_gc.py +++ b/Lib/test/test_gc.py @@ -542,48 +542,6 @@ class GCTests(unittest.TestCase): self.assertEqual(gc.collect(), 2) self.assertEqual(len(gc.garbage), garbagelen) - def test_boom_new(self): - # boom__new and boom2_new are exactly like boom and boom2, except use - # new-style classes. - - class Boom_New(object): - def __getattr__(self, someattribute): - del self.attr - raise AttributeError - - a = Boom_New() - b = Boom_New() - a.attr = b - b.attr = a - - gc.collect() - garbagelen = len(gc.garbage) - del a, b - self.assertEqual(gc.collect(), 2) - self.assertEqual(len(gc.garbage), garbagelen) - - def test_boom2_new(self): - class Boom2_New(object): - def __init__(self): - self.x = 0 - - def __getattr__(self, someattribute): - self.x += 1 - if self.x > 1: - del self.attr - raise AttributeError - - a = Boom2_New() - b = Boom2_New() - a.attr = b - b.attr = a - - gc.collect() - garbagelen = len(gc.garbage) - del a, b - self.assertEqual(gc.collect(), 2) - self.assertEqual(len(gc.garbage), garbagelen) - def test_get_referents(self): alist = [1, 3, 5] got = gc.get_referents(alist) @@ -1440,19 +1398,13 @@ class PythonFinalizationTests(unittest.TestCase): code = textwrap.dedent(""" import ast import codecs + from test import support # Small AST tree to keep their AST types alive tree = ast.parse("def f(x, y): return 2*x-y") - x = [tree] - x.append(x) - - # Put the cycle somewhere to survive until the last GC collection. - # Codec search functions are only cleared at the end of - # interpreter_clear(). - def search_func(encoding): - return None - search_func.a = x - codecs.register(search_func) + + # Store the tree somewhere to survive until the last GC collection + support.late_deletion(tree) """) assert_python_ok("-c", code) diff --git a/Lib/test/test_gdb.py b/Lib/test/test_gdb.py index 0f39b8f4..b99e0aba 100644 --- a/Lib/test/test_gdb.py +++ b/Lib/test/test_gdb.py @@ -55,10 +55,6 @@ if gdb_major_version < 7: if not sysconfig.is_python_build(): raise unittest.SkipTest("test_gdb only works on source builds at the moment.") -if 'Clang' in platform.python_compiler() and sys.platform == 'darwin': - raise unittest.SkipTest("test_gdb doesn't work correctly when python is" - " built with LLVM clang") - if ((sysconfig.get_config_var('PGO_PROF_USE_FLAG') or 'xxx') in (sysconfig.get_config_var('PY_CORE_CFLAGS') or '')): raise unittest.SkipTest("test_gdb is not reliable on PGO builds") @@ -247,6 +243,17 @@ class DebuggerTests(unittest.TestCase): for pattern in ( '(frame information optimized out)', 'Unable to read information on python frame', + # gh-91960: On Python built with "clang -Og", gdb gets + # "frame=<optimized out>" for _PyEval_EvalFrameDefault() parameter + '(unable to read python frame information)', + # gh-104736: On Python built with "clang -Og" on ppc64le, + # "py-bt" displays a truncated or not traceback, but "where" + # logs this error message: + 'Backtrace stopped: frame did not save the PC', + # gh-104736: When "bt" command displays something like: + # "#1 0x0000000000000000 in ?? ()", the traceback is likely + # truncated or wrong. + ' ?? ()', ): if pattern in out: raise unittest.SkipTest(f"{pattern!r} found in gdb output") @@ -317,6 +324,7 @@ class PrettyPrintTests(DebuggerTests): ('%r did not equal expected %r; full output was:\n%s' % (gdb_repr, exp_repr, gdb_output))) + @support.requires_resource('cpu') def test_int(self): 'Verify the pretty-printing of various int values' self.assertGdbRepr(42) @@ -343,6 +351,7 @@ class PrettyPrintTests(DebuggerTests): self.assertGdbRepr([]) self.assertGdbRepr(list(range(5))) + @support.requires_resource('cpu') def test_bytes(self): 'Verify the pretty-printing of bytes' self.assertGdbRepr(b'') @@ -357,6 +366,7 @@ class PrettyPrintTests(DebuggerTests): self.assertGdbRepr(bytes([b for b in range(255)])) + @support.requires_resource('cpu') def test_strings(self): 'Verify the pretty-printing of unicode strings' # We cannot simply call locale.getpreferredencoding() here, @@ -407,6 +417,7 @@ class PrettyPrintTests(DebuggerTests): self.assertGdbRepr((1,), '(1,)') self.assertGdbRepr(('foo', 'bar', 'baz')) + @support.requires_resource('cpu') def test_sets(self): 'Verify the pretty-printing of sets' if (gdb_major_version, gdb_minor_version) < (7, 3): @@ -425,6 +436,7 @@ s.remove('a') id(s)''') self.assertEqual(gdb_repr, "{'b'}") + @support.requires_resource('cpu') def test_frozensets(self): 'Verify the pretty-printing of frozensets' if (gdb_major_version, gdb_minor_version) < (7, 3): @@ -828,6 +840,7 @@ Traceback \(most recent call first\): @unittest.skipIf(python_is_optimized(), "Python was compiled with optimizations") + @support.requires_resource('cpu') def test_threads(self): 'Verify that "py-bt" indicates threads that are waiting for the GIL' cmd = ''' @@ -889,6 +902,7 @@ id(42) @unittest.skipIf(python_is_optimized(), "Python was compiled with optimizations") + @support.requires_resource('cpu') # Some older versions of gdb will fail with # "Cannot find new threads: generic error" # unless we add LD_PRELOAD=PATH-TO-libpthread.so.1 as a workaround @@ -962,7 +976,7 @@ id(42) cmd = textwrap.dedent(''' class MyList(list): def __init__(self): - super().__init__() # wrapper_call() + super(*[]).__init__() # wrapper_call() id("first break point") l = MyList() diff --git a/Lib/test/test_generators.py b/Lib/test/test_generators.py index 353073db..1ee99584 100644 --- a/Lib/test/test_generators.py +++ b/Lib/test/test_generators.py @@ -225,7 +225,22 @@ class GeneratorTest(unittest.TestCase): gi = f() self.assertIsNone(gi.gi_frame.f_back) + def test_issue103488(self): + def gen_raises(): + yield + raise ValueError() + + def loop(): + try: + for _ in gen_raises(): + if True is False: + return + except ValueError: + pass + + #This should not raise + loop() class ExceptionTest(unittest.TestCase): # Tests for the issue #23353: check that the currently handled exception @@ -234,16 +249,16 @@ class ExceptionTest(unittest.TestCase): def test_except_throw(self): def store_raise_exc_generator(): try: - self.assertEqual(sys.exc_info()[0], None) + self.assertIsNone(sys.exception()) yield except Exception as exc: # exception raised by gen.throw(exc) - self.assertEqual(sys.exc_info()[0], ValueError) + self.assertIsInstance(sys.exception(), ValueError) self.assertIsNone(exc.__context__) yield # ensure that the exception is not lost - self.assertEqual(sys.exc_info()[0], ValueError) + self.assertIsInstance(sys.exception(), ValueError) yield # we should be able to raise back the ValueError @@ -265,11 +280,11 @@ class ExceptionTest(unittest.TestCase): next(make) self.assertIsNone(cm.exception.__context__) - self.assertEqual(sys.exc_info(), (None, None, None)) + self.assertIsNone(sys.exception()) def test_except_next(self): def gen(): - self.assertEqual(sys.exc_info()[0], ValueError) + self.assertIsInstance(sys.exception(), ValueError) yield "done" g = gen() @@ -277,23 +292,23 @@ class ExceptionTest(unittest.TestCase): raise ValueError except Exception: self.assertEqual(next(g), "done") - self.assertEqual(sys.exc_info(), (None, None, None)) + self.assertIsNone(sys.exception()) def test_except_gen_except(self): def gen(): try: - self.assertEqual(sys.exc_info()[0], None) + self.assertIsNone(sys.exception()) yield # we are called from "except ValueError:", TypeError must # inherit ValueError in its context raise TypeError() except TypeError as exc: - self.assertEqual(sys.exc_info()[0], TypeError) + self.assertIsInstance(sys.exception(), TypeError) self.assertEqual(type(exc.__context__), ValueError) # here we are still called from the "except ValueError:" - self.assertEqual(sys.exc_info()[0], ValueError) + self.assertIsInstance(sys.exception(), ValueError) yield - self.assertIsNone(sys.exc_info()[0]) + self.assertIsNone(sys.exception()) yield "done" g = gen() @@ -304,25 +319,45 @@ class ExceptionTest(unittest.TestCase): next(g) self.assertEqual(next(g), "done") - self.assertEqual(sys.exc_info(), (None, None, None)) + self.assertIsNone(sys.exception()) + + def test_nested_gen_except_loop(self): + def gen(): + for i in range(100): + self.assertIsInstance(sys.exception(), TypeError) + yield "doing" + + def outer(): + try: + raise TypeError + except: + for x in gen(): + yield x + + try: + raise ValueError + except Exception: + for x in outer(): + self.assertEqual(x, "doing") + self.assertEqual(sys.exception(), None) def test_except_throw_exception_context(self): def gen(): try: try: - self.assertEqual(sys.exc_info()[0], None) + self.assertIsNone(sys.exception()) yield except ValueError: # we are called from "except ValueError:" - self.assertEqual(sys.exc_info()[0], ValueError) + self.assertIsInstance(sys.exception(), ValueError) raise TypeError() except Exception as exc: - self.assertEqual(sys.exc_info()[0], TypeError) + self.assertIsInstance(sys.exception(), TypeError) self.assertEqual(type(exc.__context__), ValueError) # we are still called from "except ValueError:" - self.assertEqual(sys.exc_info()[0], ValueError) + self.assertIsInstance(sys.exception(), ValueError) yield - self.assertIsNone(sys.exc_info()[0]) + self.assertIsNone(sys.exception()) yield "done" g = gen() @@ -333,7 +368,7 @@ class ExceptionTest(unittest.TestCase): g.throw(exc) self.assertEqual(next(g), "done") - self.assertEqual(sys.exc_info(), (None, None, None)) + self.assertIsNone(sys.exception()) def test_except_throw_bad_exception(self): class E(Exception): @@ -361,6 +396,15 @@ class ExceptionTest(unittest.TestCase): with self.assertRaises(StopIteration): gen.throw(E) + def test_gen_3_arg_deprecation_warning(self): + def g(): + yield 42 + + gen = g() + with self.assertWarns(DeprecationWarning): + with self.assertRaises(TypeError): + gen.throw(TypeError, TypeError(24), None) + def test_stopiteration_error(self): # See also PEP 479. @@ -2097,11 +2141,10 @@ Traceback (most recent call last): ... SyntaxError: 'yield' outside function -# Pegen does not produce this error message yet -# >>> def f(): x = yield = y -# Traceback (most recent call last): -# ... -# SyntaxError: assignment to yield expression not possible +>>> def f(): x = yield = y +Traceback (most recent call last): + ... +SyntaxError: assignment to yield expression not possible >>> def f(): (yield bar) = y Traceback (most recent call last): @@ -2132,6 +2175,13 @@ caught ValueError () >>> g.throw(ValueError("xyz")) # value only caught ValueError (xyz) +>>> import warnings +>>> old_filters = warnings.filters.copy() +>>> warnings.filterwarnings("ignore", category=DeprecationWarning) + +# Filter DeprecationWarning: regarding the (type, val, tb) signature of throw(). +# Deprecation warnings are re-enabled below. + >>> g.throw(ValueError, ValueError(1)) # value+matching type caught ValueError (1) @@ -2200,6 +2250,11 @@ Traceback (most recent call last): ... ValueError: 7 +>>> warnings.filters[:] = old_filters + +# Re-enable DeprecationWarning: the (type, val, tb) exception representation is deprecated, +# and may be removed in a future version of Python. + Plain "raise" inside a generator should preserve the traceback (#13188). The traceback should have 3 levels: - g.throw() diff --git a/Lib/test/test_genericalias.py b/Lib/test/test_genericalias.py index e44193a0..bf600a0f 100644 --- a/Lib/test/test_genericalias.py +++ b/Lib/test/test_genericalias.py @@ -2,6 +2,7 @@ import unittest import pickle +from array import array import copy from collections import ( defaultdict, deque, OrderedDict, Counter, UserDict, UserList @@ -11,6 +12,7 @@ from concurrent.futures import Future from concurrent.futures.thread import _WorkItem from contextlib import AbstractContextManager, AbstractAsyncContextManager from contextvars import ContextVar, Token +from csv import DictReader, DictWriter from dataclasses import Field from functools import partial, partialmethod, cached_property from graphlib import TopologicalSorter @@ -29,11 +31,15 @@ try: from multiprocessing.managers import ValueProxy from multiprocessing.pool import ApplyResult from multiprocessing.queues import SimpleQueue as MPSimpleQueue + from multiprocessing.queues import Queue as MPQueue + from multiprocessing.queues import JoinableQueue as MPJoinableQueue except ImportError: # _multiprocessing module is optional ValueProxy = None ApplyResult = None MPSimpleQueue = None + MPQueue = None + MPJoinableQueue = None try: from multiprocessing.shared_memory import ShareableList except ImportError: @@ -122,11 +128,14 @@ class BaseTest(unittest.TestCase): WeakSet, ReferenceType, ref, ShareableList, Future, _WorkItem, - Morsel] + Morsel, + DictReader, DictWriter, + array] if ctypes is not None: generic_types.extend((ctypes.Array, ctypes.LibraryLoader)) if ValueProxy is not None: - generic_types.extend((ValueProxy, ApplyResult, MPSimpleQueue)) + generic_types.extend((ValueProxy, ApplyResult, + MPSimpleQueue, MPQueue, MPJoinableQueue)) def test_subscriptable(self): for t in self.generic_types: @@ -200,6 +209,9 @@ class BaseTest(unittest.TestCase): def test_repr(self): class MyList(list): pass + class MyGeneric: + __class_getitem__ = classmethod(GenericAlias) + self.assertEqual(repr(list[str]), 'list[str]') self.assertEqual(repr(list[()]), 'list[()]') self.assertEqual(repr(tuple[int, ...]), 'tuple[int, ...]') @@ -212,6 +224,11 @@ class BaseTest(unittest.TestCase): self.assertTrue(repr(MyList[int]).endswith('.BaseTest.test_repr.<locals>.MyList[int]')) self.assertEqual(repr(list[str]()), '[]') # instances should keep their normal repr + # gh-105488 + self.assertTrue(repr(MyGeneric[int]).endswith('MyGeneric[int]')) + self.assertTrue(repr(MyGeneric[[]]).endswith('MyGeneric[[]]')) + self.assertTrue(repr(MyGeneric[[int, str]]).endswith('MyGeneric[[int, str]]')) + def test_exposed_type(self): import types a = types.GenericAlias(list, int) @@ -305,8 +322,11 @@ class BaseTest(unittest.TestCase): with self.assertRaises(TypeError): list[int][int] + with self.assertRaises(TypeError): dict[T, int][str, int] + with self.assertRaises(TypeError): dict[str, T][str, int] + with self.assertRaises(TypeError): dict[T, T][str, int] def test_equality(self): diff --git a/Lib/test/test_genericpath.py b/Lib/test/test_genericpath.py index 489044f8..4f311c2d 100644 --- a/Lib/test/test_genericpath.py +++ b/Lib/test/test_genericpath.py @@ -460,6 +460,10 @@ class CommonTest(GenericTest): for path in ('', '.', '/', '\\', '///foo/.//bar//'): self.assertIsInstance(self.pathmodule.normpath(path), str) + def test_normpath_issue106242(self): + for path in ('\x00', 'foo\x00bar', '\x00\x00', '\x00foo', 'foo\x00'): + self.assertEqual(self.pathmodule.normpath(path), path) + def test_abspath_issue3426(self): # Check that abspath returns unicode when the arg is unicode # with both ASCII and non-ASCII cwds. diff --git a/Lib/test/test_getopt.py b/Lib/test/test_getopt.py index 64b9ce01..c8b3442d 100644 --- a/Lib/test/test_getopt.py +++ b/Lib/test/test_getopt.py @@ -1,8 +1,8 @@ # test_getopt.py # David Goodger <dgoodger@bigfoot.com> 2000-08-19 -from test.support import verbose, run_doctest from test.support.os_helper import EnvironmentVarGuard +import doctest import unittest import getopt @@ -83,7 +83,7 @@ class GetoptTests(unittest.TestCase): # Much like the preceding, except with a non-alpha character ("-") in # option name that precedes "="; failed in - # http://python.org/sf/126863 + # https://bugs.python.org/issue126863 opts, args = getopt.do_longs([], 'foo=42', ['foo-bar', 'foo=',], []) self.assertEqual(opts, [('--foo', '42')]) self.assertEqual(args, []) @@ -134,48 +134,49 @@ class GetoptTests(unittest.TestCase): self.assertEqual(opts, [('-a', '')]) self.assertEqual(args, ['arg1', '-b', '1', '--alpha', '--beta=2']) - def test_libref_examples(self): - s = """ - Examples from the Library Reference: Doc/lib/libgetopt.tex + def test_issue4629(self): + longopts, shortopts = getopt.getopt(['--help='], '', ['help=']) + self.assertEqual(longopts, [('--help', '')]) + longopts, shortopts = getopt.getopt(['--help=x'], '', ['help=']) + self.assertEqual(longopts, [('--help', 'x')]) + self.assertRaises(getopt.GetoptError, getopt.getopt, ['--help='], '', ['help']) - An example using only Unix style options: +def test_libref_examples(): + """ + Examples from the Library Reference: Doc/lib/libgetopt.tex + An example using only Unix style options: - >>> import getopt - >>> args = '-a -b -cfoo -d bar a1 a2'.split() - >>> args - ['-a', '-b', '-cfoo', '-d', 'bar', 'a1', 'a2'] - >>> optlist, args = getopt.getopt(args, 'abc:d:') - >>> optlist - [('-a', ''), ('-b', ''), ('-c', 'foo'), ('-d', 'bar')] - >>> args - ['a1', 'a2'] - Using long option names is equally easy: + >>> import getopt + >>> args = '-a -b -cfoo -d bar a1 a2'.split() + >>> args + ['-a', '-b', '-cfoo', '-d', 'bar', 'a1', 'a2'] + >>> optlist, args = getopt.getopt(args, 'abc:d:') + >>> optlist + [('-a', ''), ('-b', ''), ('-c', 'foo'), ('-d', 'bar')] + >>> args + ['a1', 'a2'] + Using long option names is equally easy: - >>> s = '--condition=foo --testing --output-file abc.def -x a1 a2' - >>> args = s.split() - >>> args - ['--condition=foo', '--testing', '--output-file', 'abc.def', '-x', 'a1', 'a2'] - >>> optlist, args = getopt.getopt(args, 'x', [ - ... 'condition=', 'output-file=', 'testing']) - >>> optlist - [('--condition', 'foo'), ('--testing', ''), ('--output-file', 'abc.def'), ('-x', '')] - >>> args - ['a1', 'a2'] - """ - import types - m = types.ModuleType("libreftest", s) - run_doctest(m, verbose) + >>> s = '--condition=foo --testing --output-file abc.def -x a1 a2' + >>> args = s.split() + >>> args + ['--condition=foo', '--testing', '--output-file', 'abc.def', '-x', 'a1', 'a2'] + >>> optlist, args = getopt.getopt(args, 'x', [ + ... 'condition=', 'output-file=', 'testing']) + >>> optlist + [('--condition', 'foo'), ('--testing', ''), ('--output-file', 'abc.def'), ('-x', '')] + >>> args + ['a1', 'a2'] + """ + +def load_tests(loader, tests, pattern): + tests.addTest(doctest.DocTestSuite()) + return tests - def test_issue4629(self): - longopts, shortopts = getopt.getopt(['--help='], '', ['help=']) - self.assertEqual(longopts, [('--help', '')]) - longopts, shortopts = getopt.getopt(['--help=x'], '', ['help=']) - self.assertEqual(longopts, [('--help', 'x')]) - self.assertRaises(getopt.GetoptError, getopt.getopt, ['--help='], '', ['help']) if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_getpath.py b/Lib/test/test_getpath.py index 8d5b4265..b9cbe1d9 100644 --- a/Lib/test/test_getpath.py +++ b/Lib/test/test_getpath.py @@ -2,7 +2,6 @@ import copy import ntpath import pathlib import posixpath -import sys import unittest from test.support import verbose diff --git a/Lib/test/test_gettext.py b/Lib/test/test_gettext.py index 1608d1b1..8430fc23 100644 --- a/Lib/test/test_gettext.py +++ b/Lib/test/test_gettext.py @@ -320,6 +320,8 @@ class PluralFormsTestCase(GettextBaseTest): eq(x, 'Hay %s fichero') x = gettext.ngettext('There is %s file', 'There are %s files', 2) eq(x, 'Hay %s ficheros') + x = gettext.gettext('There is %s file') + eq(x, 'Hay %s fichero') def test_plural_context_forms1(self): eq = self.assertEqual @@ -329,6 +331,8 @@ class PluralFormsTestCase(GettextBaseTest): x = gettext.npgettext('With context', 'There is %s file', 'There are %s files', 2) eq(x, 'Hay %s ficheros (context)') + x = gettext.pgettext('With context', 'There is %s file') + eq(x, 'Hay %s fichero (context)') def test_plural_forms2(self): eq = self.assertEqual @@ -338,6 +342,8 @@ class PluralFormsTestCase(GettextBaseTest): eq(x, 'Hay %s fichero') x = t.ngettext('There is %s file', 'There are %s files', 2) eq(x, 'Hay %s ficheros') + x = t.gettext('There is %s file') + eq(x, 'Hay %s fichero') def test_plural_context_forms2(self): eq = self.assertEqual @@ -349,6 +355,8 @@ class PluralFormsTestCase(GettextBaseTest): x = t.npgettext('With context', 'There is %s file', 'There are %s files', 2) eq(x, 'Hay %s ficheros (context)') + x = gettext.pgettext('With context', 'There is %s file') + eq(x, 'Hay %s fichero (context)') # Examples from http://www.gnu.org/software/gettext/manual/gettext.html diff --git a/Lib/test/test_grammar.py b/Lib/test/test_grammar.py index bcd8d584..b2415d57 100644 --- a/Lib/test/test_grammar.py +++ b/Lib/test/test_grammar.py @@ -3,7 +3,6 @@ from test.support import check_syntax_error from test.support import import_helper -from test.support.warnings_helper import check_syntax_warning import inspect import unittest import sys @@ -15,7 +14,6 @@ from sys import * # with import machinery import test.ann_module as ann_module import typing -from collections import ChainMap from test import ann_module2 import test @@ -238,12 +236,9 @@ class TokenTests(unittest.TestCase): check(f"[{num}for x in ()]") check(f"{num}spam", error=True) + with self.assertWarnsRegex(SyntaxWarning, r'invalid \w+ literal'): + compile(f"{num}is x", "<testcase>", "eval") with warnings.catch_warnings(): - warnings.filterwarnings('ignore', '"is" with a literal', - SyntaxWarning) - with self.assertWarnsRegex(SyntaxWarning, - r'invalid \w+ literal'): - compile(f"{num}is x", "<testcase>", "eval") warnings.simplefilter('error', SyntaxWarning) with self.assertRaisesRegex(SyntaxError, r'invalid \w+ literal'): @@ -355,6 +350,11 @@ class GrammarTests(unittest.TestCase): check_syntax_error(self, "x: int: str") check_syntax_error(self, "def f():\n" " nonlocal x: int\n") + check_syntax_error(self, "def f():\n" + " global x: int\n") + check_syntax_error(self, "x: int = y = 1") + check_syntax_error(self, "z = w: int = 1") + check_syntax_error(self, "x: int = y: int = 1") # AST pass check_syntax_error(self, "[x, 0]: int\n") check_syntax_error(self, "f(): int\n") @@ -368,6 +368,12 @@ class GrammarTests(unittest.TestCase): check_syntax_error(self, "def f():\n" " global x\n" " x: int\n") + check_syntax_error(self, "def f():\n" + " x: int\n" + " nonlocal x\n") + check_syntax_error(self, "def f():\n" + " nonlocal x\n" + " x: int\n") def test_var_annot_basic_semantics(self): # execution order @@ -1469,14 +1475,22 @@ class GrammarTests(unittest.TestCase): if 1 < 1 > 1 == 1 >= 1 <= 1 != 1 in 1 not in x is x is not x: pass def test_comparison_is_literal(self): - def check(test, msg='"is" with a literal'): + def check(test, msg): self.check_syntax_warning(test, msg) - check('x is 1') - check('x is "thing"') - check('1 is x') - check('x is y is 1') - check('x is not 1', '"is not" with a literal') + check('x is 1', '"is" with \'int\' literal') + check('x is "thing"', '"is" with \'str\' literal') + check('1 is x', '"is" with \'int\' literal') + check('x is y is 1', '"is" with \'int\' literal') + check('x is not 1', '"is not" with \'int\' literal') + check('x is not (1, 2)', '"is not" with \'tuple\' literal') + check('(1, 2) is not x', '"is not" with \'tuple\' literal') + + check('None is 1', '"is" with \'int\' literal') + check('1 is None', '"is" with \'int\' literal') + + check('x == 3 is y', '"is" with \'int\' literal') + check('x == "thing" is y', '"is" with \'str\' literal') with warnings.catch_warnings(): warnings.simplefilter('error', SyntaxWarning) @@ -1484,6 +1498,10 @@ class GrammarTests(unittest.TestCase): compile('x is False', '<testcase>', 'exec') compile('x is True', '<testcase>', 'exec') compile('x is ...', '<testcase>', 'exec') + compile('None is x', '<testcase>', 'exec') + compile('False is x', '<testcase>', 'exec') + compile('True is x', '<testcase>', 'exec') + compile('... is x', '<testcase>', 'exec') def test_warn_missed_comma(self): def check(test): @@ -1614,7 +1632,7 @@ class GrammarTests(unittest.TestCase): s = a[-5:] s = a[:-1] s = a[-4:-3] - # A rough test of SF bug 1333982. http://python.org/sf/1333982 + # A rough test of SF bug 1333982. https://bugs.python.org/issue1333982 # The testing here is fairly incomplete. # Test cases should include: commas with 1 and 2 colons d = {} diff --git a/Lib/test/test_gzip.py b/Lib/test/test_gzip.py index 6de413e5..128f9337 100644 --- a/Lib/test/test_gzip.py +++ b/Lib/test/test_gzip.py @@ -16,6 +16,7 @@ from test.support import _4G, bigmemtest, requires_subprocess from test.support.script_helper import assert_python_ok, assert_python_failure gzip = import_helper.import_module('gzip') +zlib = import_helper.import_module('zlib') data1 = b""" int length=DEFAULTALLOC, err = Z_OK; PyObject *RetVal; @@ -616,6 +617,66 @@ class TestGzip(BaseTest): self.assertEqual(f.write(q), LENGTH) self.assertEqual(f.tell(), LENGTH) + def test_flush_flushes_compressor(self): + # See issue GH-105808. + b = io.BytesIO() + message = b"important message here." + with gzip.GzipFile(fileobj=b, mode='w') as f: + f.write(message) + f.flush() + partial_data = b.getvalue() + full_data = b.getvalue() + self.assertEqual(gzip.decompress(full_data), message) + # The partial data should contain the gzip header and the complete + # message, but not the end-of-stream markers (so we can't just + # decompress it directly). + with self.assertRaises(EOFError): + gzip.decompress(partial_data) + d = zlib.decompressobj(wbits=-zlib.MAX_WBITS) + f = io.BytesIO(partial_data) + gzip._read_gzip_header(f) + read_message = d.decompress(f.read()) + self.assertEqual(read_message, message) + + def test_flush_modes(self): + # Make sure the argument to flush is properly passed to the + # zlib.compressobj; see issue GH-105808. + class FakeCompressor: + def __init__(self): + self.modes = [] + def compress(self, data): + return b'' + def flush(self, mode=-1): + self.modes.append(mode) + return b'' + b = io.BytesIO() + fc = FakeCompressor() + with gzip.GzipFile(fileobj=b, mode='w') as f: + f.compress = fc + f.flush() + f.flush(50) + f.flush(zlib_mode=100) + # The implicit close will also flush the compressor. + expected_modes = [ + zlib.Z_SYNC_FLUSH, + 50, + 100, + -1, + ] + self.assertEqual(fc.modes, expected_modes) + + def test_write_seek_write(self): + # Make sure that offset is up-to-date before seeking + # See issue GH-108111 + b = io.BytesIO() + message = b"important message here." + with gzip.GzipFile(fileobj=b, mode='w') as f: + f.write(message) + f.seek(len(message)) + f.write(message) + data = b.getvalue() + self.assertEqual(gzip.decompress(data), message * 2) + class TestOpen(BaseTest): def test_binary_modes(self): diff --git a/Lib/test/test_hashlib.py b/Lib/test/test_hashlib.py index 67becdd6..73d758a3 100644 --- a/Lib/test/test_hashlib.py +++ b/Lib/test/test_hashlib.py @@ -1,6 +1,4 @@ -# Test hashlib module -# -# $Id$ +# Test the hashlib module. # # Copyright (C) 2005-2010 Gregory P. Smith (greg@krypto.org) # Licensed to PSF under a Contributor Agreement. @@ -22,14 +20,11 @@ from test import support from test.support import _4G, bigmemtest from test.support.import_helper import import_fresh_module from test.support import os_helper +from test.support import requires_resource from test.support import threading_helper -from test.support import warnings_helper from http.client import HTTPException -# Were we compiled --with-pydebug or with #define Py_DEBUG? -COMPILED_WITH_PYDEBUG = hasattr(sys, 'gettotalrefcount') -# default builtin hash module default_builtin_hashes = {'md5', 'sha1', 'sha256', 'sha512', 'sha3', 'blake2'} # --with-builtin-hashlib-hashes override builtin_hashes = sysconfig.get_config_var("PY_BUILTIN_HASHLIB_HASHES") @@ -67,6 +62,7 @@ except ImportError: requires_blake2 = unittest.skipUnless(_blake2, 'requires _blake2') # bpo-46913: Don't test the _sha3 extension on a Python UBSAN build +# TODO(gh-99108): Revisit this after _sha3 uses HACL*. SKIP_SHA3 = support.check_sanitizer(ub=True) requires_sha3 = unittest.skipUnless(not SKIP_SHA3, 'requires _sha3') @@ -108,8 +104,8 @@ class HashLibTestCase(unittest.TestCase): shakes = {'shake_128', 'shake_256'} - # Issue #14693: fallback modules are always compiled under POSIX - _warn_on_extension_import = os.name == 'posix' or COMPILED_WITH_PYDEBUG + # gh-58898: Fallback modules are always compiled under POSIX. + _warn_on_extension_import = (os.name == 'posix' or support.Py_DEBUG) def _conditional_import_module(self, module_name): """Import a module and return a reference to it or None on failure.""" @@ -117,7 +113,7 @@ class HashLibTestCase(unittest.TestCase): return importlib.import_module(module_name) except ModuleNotFoundError as error: if self._warn_on_extension_import and module_name in builtin_hashes: - warnings.warn('Did a C extension fail to compile? %s' % error) + warnings.warn(f'Did a C extension fail to compile? {error}') return None def __init__(self, *args, **kwargs): @@ -148,7 +144,7 @@ class HashLibTestCase(unittest.TestCase): _hashlib = self._conditional_import_module('_hashlib') self._hashlib = _hashlib if _hashlib: - # These two algorithms should always be present when this module + # These algorithms should always be present when this module # is compiled. If not, something was compiled wrong. self.assertTrue(hasattr(_hashlib, 'openssl_md5')) self.assertTrue(hasattr(_hashlib, 'openssl_sha1')) @@ -173,12 +169,10 @@ class HashLibTestCase(unittest.TestCase): _sha1 = self._conditional_import_module('_sha1') if _sha1: add_builtin_constructor('sha1') - _sha256 = self._conditional_import_module('_sha256') - if _sha256: + _sha2 = self._conditional_import_module('_sha2') + if _sha2: add_builtin_constructor('sha224') add_builtin_constructor('sha256') - _sha512 = self._conditional_import_module('_sha512') - if _sha512: add_builtin_constructor('sha384') add_builtin_constructor('sha512') if _blake2: @@ -356,6 +350,24 @@ class HashLibTestCase(unittest.TestCase): self.assertEqual(m1.digest(*args), m4_copy.digest(*args)) self.assertEqual(m4.digest(*args), m4_digest) + @requires_resource('cpu') + def test_sha256_update_over_4gb(self): + zero_1mb = b"\0" * 1024 * 1024 + h = hashlib.sha256() + for i in range(0, 4096): + h.update(zero_1mb) + h.update(b"hello world") + self.assertEqual(h.hexdigest(), "a5364f7a52ebe2e25f1838a4ca715a893b6fd7a23f2a0d9e9762120da8b1bf53") + + @requires_resource('cpu') + def test_sha3_256_update_over_4gb(self): + zero_1mb = b"\0" * 1024 * 1024 + h = hashlib.sha3_256() + for i in range(0, 4096): + h.update(zero_1mb) + h.update(b"hello world") + self.assertEqual(h.hexdigest(), "e2d4535e3b613135c14f2fe4e026d7ad8d569db44901740beffa30d430acb038") + def check(self, name, data, hexdigest, shake=False, **kwargs): length = len(hexdigest)//2 hexdigest = hexdigest.lower() @@ -452,9 +464,9 @@ class HashLibTestCase(unittest.TestCase): self.assertEqual(len(m.hexdigest()), 2*digest_size) self.assertEqual(m.name, name) # split for sha3_512 / _sha3.sha3 object - self.assertIn(name.split("_")[0], repr(m)) + self.assertIn(name.split("_")[0], repr(m).lower()) - def test_blocksize_name(self): + def test_blocksize_and_name(self): self.check_blocksize_name('md5', 64, 16) self.check_blocksize_name('sha1', 64, 20) self.check_blocksize_name('sha224', 64, 28) @@ -1098,15 +1110,7 @@ class KDFTests(unittest.TestCase): iterations=1, dklen=None) self.assertEqual(out, self.pbkdf2_results['sha1'][0][0]) - @unittest.skipIf(builtin_hashlib is None, "test requires builtin_hashlib") - def test_pbkdf2_hmac_py(self): - with warnings_helper.check_warnings(): - self._test_pbkdf2_hmac( - builtin_hashlib.pbkdf2_hmac, builtin_hashes - ) - - @unittest.skipUnless(hasattr(openssl_hashlib, 'pbkdf2_hmac'), - ' test requires OpenSSL > 1.0') + @unittest.skipIf(openssl_hashlib is None, "requires OpenSSL bindings") def test_pbkdf2_hmac_c(self): self._test_pbkdf2_hmac(openssl_hashlib.pbkdf2_hmac, openssl_md_meth_names) diff --git a/Lib/test/test_heapq.py b/Lib/test/test_heapq.py index cb1e4505..1aa8e4e2 100644 --- a/Lib/test/test_heapq.py +++ b/Lib/test/test_heapq.py @@ -4,7 +4,6 @@ import random import unittest import doctest -from test import support from test.support import import_helper from unittest import TestCase, skipUnless from operator import itemgetter diff --git a/Lib/test/test_hmac.py b/Lib/test/test_hmac.py index 7cf99735..a39a2c45 100644 --- a/Lib/test/test_hmac.py +++ b/Lib/test/test_hmac.py @@ -373,6 +373,16 @@ class TestVectorsTestCase(unittest.TestCase): with self.assertRaisesRegex(TypeError, r'required.*digestmod'): hmac.HMAC(key, msg=data, digestmod='') + def test_with_fallback(self): + cache = getattr(hashlib, '__builtin_constructor_cache') + try: + cache['foo'] = hashlib.sha256 + hexdigest = hmac.digest(b'key', b'message', 'foo').hex() + expected = '6e9ef29b75fffc5b7abae527d58fdadb2fe42e7219011976917343065f58ed4a' + self.assertEqual(hexdigest, expected) + finally: + cache.pop('foo') + class ConstructorTestCase(unittest.TestCase): diff --git a/Lib/test/test_htmlparser.py b/Lib/test/test_htmlparser.py index 12917755..b42a611c 100644 --- a/Lib/test/test_htmlparser.py +++ b/Lib/test/test_htmlparser.py @@ -4,6 +4,8 @@ import html.parser import pprint import unittest +from unittest.mock import patch + class EventCollector(html.parser.HTMLParser): @@ -787,5 +789,17 @@ class AttributesTestCase(TestCaseBase): ('starttag', 'form', [('action', 'bogus|&#()value')])]) + +class TestInheritance(unittest.TestCase): + + @patch("_markupbase.ParserBase.__init__") + @patch("_markupbase.ParserBase.reset") + def test_base_class_methods_called(self, super_reset_method, super_init_method): + with patch('_markupbase.ParserBase') as parser_base: + EventCollector() + super_init_method.assert_called_once() + super_reset_method.assert_called_once() + + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_http_cookiejar.py b/Lib/test/test_http_cookiejar.py index b9061286..97e9c82c 100644 --- a/Lib/test/test_http_cookiejar.py +++ b/Lib/test/test_http_cookiejar.py @@ -4,7 +4,6 @@ import os import stat import sys import re -import test.support from test.support import os_helper from test.support import warnings_helper import time diff --git a/Lib/test/test_httplib.py b/Lib/test/test_httplib.py index 15dab035..676725c4 100644 --- a/Lib/test/test_httplib.py +++ b/Lib/test/test_httplib.py @@ -8,7 +8,6 @@ import array import re import socket import threading -import warnings import unittest from unittest import mock @@ -17,7 +16,6 @@ TestCase = unittest.TestCase from test import support from test.support import os_helper from test.support import socket_helper -from test.support import warnings_helper support.requires_working_socket(module=True) @@ -553,6 +551,27 @@ class BasicTest(TestCase): obj.phrase = phrase obj.description = description return obj + + @property + def is_informational(self): + return 100 <= self <= 199 + + @property + def is_success(self): + return 200 <= self <= 299 + + @property + def is_redirection(self): + return 300 <= self <= 399 + + @property + def is_client_error(self): + return 400 <= self <= 499 + + @property + def is_server_error(self): + return 500 <= self <= 599 + # informational CONTINUE = 100, 'Continue', 'Request received, please continue' SWITCHING_PROTOCOLS = (101, 'Switching Protocols', @@ -669,6 +688,30 @@ class BasicTest(TestCase): 'The client needs to authenticate to gain network access') enum._test_simple_enum(CheckedHTTPStatus, HTTPStatus) + def test_httpstatus_range(self): + """Checks that the statuses are in the 100-599 range""" + + for member in HTTPStatus.__members__.values(): + self.assertGreaterEqual(member, 100) + self.assertLessEqual(member, 599) + + def test_httpstatus_category(self): + """Checks that the statuses belong to the standard categories""" + + categories = ( + ((100, 199), "is_informational"), + ((200, 299), "is_success"), + ((300, 399), "is_redirection"), + ((400, 499), "is_client_error"), + ((500, 599), "is_server_error"), + ) + for member in HTTPStatus.__members__.values(): + for (lower, upper), category in categories: + category_indicator = getattr(member, category) + if lower <= member <= upper: + self.assertTrue(category_indicator) + else: + self.assertFalse(category_indicator) def test_status_lines(self): # Test HTTP status lines @@ -1911,6 +1954,7 @@ class HTTPSTest(TestCase): h.close() self.assertIn('nginx', server_string) + @support.requires_resource('walltime') def test_networked_bad_cert(self): # We feed a "CA" cert that is unrelated to the server's cert import ssl @@ -1933,7 +1977,7 @@ class HTTPSTest(TestCase): self.assertEqual(exc_info.exception.reason, 'CERTIFICATE_VERIFY_FAILED') def test_local_good_hostname(self): - # The (valid) cert validates the HTTP hostname + # The (valid) cert validates the HTTPS hostname import ssl server = self.make_server(CERT_localhost) context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) @@ -1946,7 +1990,7 @@ class HTTPSTest(TestCase): self.assertEqual(resp.status, 404) def test_local_bad_hostname(self): - # The (valid) cert doesn't validate the HTTP hostname + # The (valid) cert doesn't validate the HTTPS hostname import ssl server = self.make_server(CERT_fakehostname) context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) @@ -1954,38 +1998,21 @@ class HTTPSTest(TestCase): h = client.HTTPSConnection('localhost', server.port, context=context) with self.assertRaises(ssl.CertificateError): h.request('GET', '/') - # Same with explicit check_hostname=True - with warnings_helper.check_warnings(('', DeprecationWarning)): - h = client.HTTPSConnection('localhost', server.port, - context=context, check_hostname=True) + + # Same with explicit context.check_hostname=True + context.check_hostname = True + h = client.HTTPSConnection('localhost', server.port, context=context) with self.assertRaises(ssl.CertificateError): h.request('GET', '/') - # With check_hostname=False, the mismatching is ignored - context.check_hostname = False - with warnings_helper.check_warnings(('', DeprecationWarning)): - h = client.HTTPSConnection('localhost', server.port, - context=context, check_hostname=False) - h.request('GET', '/nonexistent') - resp = h.getresponse() - resp.close() - h.close() - self.assertEqual(resp.status, 404) - # The context's check_hostname setting is used if one isn't passed to - # HTTPSConnection. + + # With context.check_hostname=False, the mismatching is ignored context.check_hostname = False h = client.HTTPSConnection('localhost', server.port, context=context) h.request('GET', '/nonexistent') resp = h.getresponse() - self.assertEqual(resp.status, 404) resp.close() h.close() - # Passing check_hostname to HTTPSConnection should override the - # context's setting. - with warnings_helper.check_warnings(('', DeprecationWarning)): - h = client.HTTPSConnection('localhost', server.port, - context=context, check_hostname=True) - with self.assertRaises(ssl.CertificateError): - h.request('GET', '/') + self.assertEqual(resp.status, 404) @unittest.skipIf(not hasattr(client, 'HTTPSConnection'), 'http.client.HTTPSConnection not available') @@ -2021,11 +2048,9 @@ class HTTPSTest(TestCase): self.assertIs(h._context, context) self.assertFalse(h._context.post_handshake_auth) - with warnings.catch_warnings(): - warnings.filterwarnings('ignore', 'key_file, cert_file and check_hostname are deprecated', - DeprecationWarning) - h = client.HTTPSConnection('localhost', 443, context=context, - cert_file=CERT_localhost) + context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT, cert_file=CERT_localhost) + context.post_handshake_auth = True + h = client.HTTPSConnection('localhost', 443, context=context) self.assertTrue(h._context.post_handshake_auth) @@ -2163,11 +2188,12 @@ class HTTPResponseTest(TestCase): class TunnelTests(TestCase): def setUp(self): response_text = ( - 'HTTP/1.0 200 OK\r\n\r\n' # Reply to CONNECT + 'HTTP/1.1 200 OK\r\n\r\n' # Reply to CONNECT 'HTTP/1.1 200 OK\r\n' # Reply to HEAD 'Content-Length: 42\r\n\r\n' ) self.host = 'proxy.com' + self.port = client.HTTP_PORT self.conn = client.HTTPConnection(self.host) self.conn._create_connection = self._create_connection(response_text) @@ -2179,15 +2205,45 @@ class TunnelTests(TestCase): return FakeSocket(response_text, host=address[0], port=address[1]) return create_connection - def test_set_tunnel_host_port_headers(self): + def test_set_tunnel_host_port_headers_add_host_missing(self): tunnel_host = 'destination.com' tunnel_port = 8888 tunnel_headers = {'User-Agent': 'Mozilla/5.0 (compatible, MSIE 11)'} + tunnel_headers_after = tunnel_headers.copy() + tunnel_headers_after['Host'] = '%s:%d' % (tunnel_host, tunnel_port) self.conn.set_tunnel(tunnel_host, port=tunnel_port, headers=tunnel_headers) self.conn.request('HEAD', '/', '') self.assertEqual(self.conn.sock.host, self.host) - self.assertEqual(self.conn.sock.port, client.HTTP_PORT) + self.assertEqual(self.conn.sock.port, self.port) + self.assertEqual(self.conn._tunnel_host, tunnel_host) + self.assertEqual(self.conn._tunnel_port, tunnel_port) + self.assertEqual(self.conn._tunnel_headers, tunnel_headers_after) + + def test_set_tunnel_host_port_headers_set_host_identical(self): + tunnel_host = 'destination.com' + tunnel_port = 8888 + tunnel_headers = {'User-Agent': 'Mozilla/5.0 (compatible, MSIE 11)', + 'Host': '%s:%d' % (tunnel_host, tunnel_port)} + self.conn.set_tunnel(tunnel_host, port=tunnel_port, + headers=tunnel_headers) + self.conn.request('HEAD', '/', '') + self.assertEqual(self.conn.sock.host, self.host) + self.assertEqual(self.conn.sock.port, self.port) + self.assertEqual(self.conn._tunnel_host, tunnel_host) + self.assertEqual(self.conn._tunnel_port, tunnel_port) + self.assertEqual(self.conn._tunnel_headers, tunnel_headers) + + def test_set_tunnel_host_port_headers_set_host_different(self): + tunnel_host = 'destination.com' + tunnel_port = 8888 + tunnel_headers = {'User-Agent': 'Mozilla/5.0 (compatible, MSIE 11)', + 'Host': '%s:%d' % ('example.com', 4200)} + self.conn.set_tunnel(tunnel_host, port=tunnel_port, + headers=tunnel_headers) + self.conn.request('HEAD', '/', '') + self.assertEqual(self.conn.sock.host, self.host) + self.assertEqual(self.conn.sock.port, self.port) self.assertEqual(self.conn._tunnel_host, tunnel_host) self.assertEqual(self.conn._tunnel_port, tunnel_port) self.assertEqual(self.conn._tunnel_headers, tunnel_headers) @@ -2199,17 +2255,96 @@ class TunnelTests(TestCase): 'destination.com') def test_connect_with_tunnel(self): - self.conn.set_tunnel('destination.com') + d = { + b'host': b'destination.com', + b'port': client.HTTP_PORT, + } + self.conn.set_tunnel(d[b'host'].decode('ascii')) + self.conn.request('HEAD', '/', '') + self.assertEqual(self.conn.sock.host, self.host) + self.assertEqual(self.conn.sock.port, self.port) + self.assertIn(b'CONNECT %(host)s:%(port)d HTTP/1.1\r\n' + b'Host: %(host)s:%(port)d\r\n\r\n' % d, + self.conn.sock.data) + self.assertIn(b'HEAD / HTTP/1.1\r\nHost: %(host)s\r\n' % d, + self.conn.sock.data) + + def test_connect_with_tunnel_with_default_port(self): + d = { + b'host': b'destination.com', + b'port': client.HTTP_PORT, + } + self.conn.set_tunnel(d[b'host'].decode('ascii'), port=d[b'port']) + self.conn.request('HEAD', '/', '') + self.assertEqual(self.conn.sock.host, self.host) + self.assertEqual(self.conn.sock.port, self.port) + self.assertIn(b'CONNECT %(host)s:%(port)d HTTP/1.1\r\n' + b'Host: %(host)s:%(port)d\r\n\r\n' % d, + self.conn.sock.data) + self.assertIn(b'HEAD / HTTP/1.1\r\nHost: %(host)s\r\n' % d, + self.conn.sock.data) + + def test_connect_with_tunnel_with_nonstandard_port(self): + d = { + b'host': b'destination.com', + b'port': 8888, + } + self.conn.set_tunnel(d[b'host'].decode('ascii'), port=d[b'port']) + self.conn.request('HEAD', '/', '') + self.assertEqual(self.conn.sock.host, self.host) + self.assertEqual(self.conn.sock.port, self.port) + self.assertIn(b'CONNECT %(host)s:%(port)d HTTP/1.1\r\n' + b'Host: %(host)s:%(port)d\r\n\r\n' % d, + self.conn.sock.data) + self.assertIn(b'HEAD / HTTP/1.1\r\nHost: %(host)s:%(port)d\r\n' % d, + self.conn.sock.data) + + # This request is not RFC-valid, but it's been possible with the library + # for years, so don't break it unexpectedly... This also tests + # case-insensitivity when injecting Host: headers if they're missing. + def test_connect_with_tunnel_with_different_host_header(self): + d = { + b'host': b'destination.com', + b'tunnel_host_header': b'example.com:9876', + b'port': client.HTTP_PORT, + } + self.conn.set_tunnel( + d[b'host'].decode('ascii'), + headers={'HOST': d[b'tunnel_host_header'].decode('ascii')}) + self.conn.request('HEAD', '/', '') + self.assertEqual(self.conn.sock.host, self.host) + self.assertEqual(self.conn.sock.port, self.port) + self.assertIn(b'CONNECT %(host)s:%(port)d HTTP/1.1\r\n' + b'HOST: %(tunnel_host_header)s\r\n\r\n' % d, + self.conn.sock.data) + self.assertIn(b'HEAD / HTTP/1.1\r\nHost: %(host)s\r\n' % d, + self.conn.sock.data) + + def test_connect_with_tunnel_different_host(self): + d = { + b'host': b'destination.com', + b'port': client.HTTP_PORT, + } + self.conn.set_tunnel(d[b'host'].decode('ascii')) + self.conn.request('HEAD', '/', '') + self.assertEqual(self.conn.sock.host, self.host) + self.assertEqual(self.conn.sock.port, self.port) + self.assertIn(b'CONNECT %(host)s:%(port)d HTTP/1.1\r\n' + b'Host: %(host)s:%(port)d\r\n\r\n' % d, + self.conn.sock.data) + self.assertIn(b'HEAD / HTTP/1.1\r\nHost: %(host)s\r\n' % d, + self.conn.sock.data) + + def test_connect_with_tunnel_idna(self): + dest = '\u03b4\u03c0\u03b8.gr' + dest_port = b'%s:%d' % (dest.encode('idna'), client.HTTP_PORT) + expected = b'CONNECT %s HTTP/1.1\r\nHost: %s\r\n\r\n' % ( + dest_port, dest_port) + self.conn.set_tunnel(dest) self.conn.request('HEAD', '/', '') self.assertEqual(self.conn.sock.host, self.host) self.assertEqual(self.conn.sock.port, client.HTTP_PORT) - self.assertIn(b'CONNECT destination.com', self.conn.sock.data) - # issue22095 - self.assertNotIn(b'Host: destination.com:None', self.conn.sock.data) - self.assertIn(b'Host: destination.com', self.conn.sock.data) - - # This test should be removed when CONNECT gets the HTTP/1.1 blessing - self.assertNotIn(b'Host: proxy.com', self.conn.sock.data) + self.assertIn(expected, self.conn.sock.data) def test_tunnel_connect_single_send_connection_setup(self): """Regresstion test for https://bugs.python.org/issue43332.""" @@ -2229,12 +2364,19 @@ class TunnelTests(TestCase): msg=f'unexpected proxy data sent {proxy_setup_data_sent!r}') def test_connect_put_request(self): - self.conn.set_tunnel('destination.com') + d = { + b'host': b'destination.com', + b'port': client.HTTP_PORT, + } + self.conn.set_tunnel(d[b'host'].decode('ascii')) self.conn.request('PUT', '/', '') self.assertEqual(self.conn.sock.host, self.host) - self.assertEqual(self.conn.sock.port, client.HTTP_PORT) - self.assertIn(b'CONNECT destination.com', self.conn.sock.data) - self.assertIn(b'Host: destination.com', self.conn.sock.data) + self.assertEqual(self.conn.sock.port, self.port) + self.assertIn(b'CONNECT %(host)s:%(port)d HTTP/1.1\r\n' + b'Host: %(host)s:%(port)d\r\n\r\n' % d, + self.conn.sock.data) + self.assertIn(b'PUT / HTTP/1.1\r\nHost: %(host)s\r\n' % d, + self.conn.sock.data) def test_tunnel_debuglog(self): expected_header = 'X-Dummy: 1' @@ -2249,6 +2391,56 @@ class TunnelTests(TestCase): lines = output.getvalue().splitlines() self.assertIn('header: {}'.format(expected_header), lines) + def test_proxy_response_headers(self): + expected_header = ('X-Dummy', '1') + response_text = ( + 'HTTP/1.0 200 OK\r\n' + '{0}\r\n\r\n'.format(':'.join(expected_header)) + ) + + self.conn._create_connection = self._create_connection(response_text) + self.conn.set_tunnel('destination.com') + + self.conn.request('PUT', '/', '') + headers = self.conn.get_proxy_response_headers() + self.assertIn(expected_header, headers.items()) + + def test_no_proxy_response_headers(self): + expected_header = ('X-Dummy', '1') + response_text = ( + 'HTTP/1.0 200 OK\r\n' + '{0}\r\n\r\n'.format(':'.join(expected_header)) + ) + + self.conn._create_connection = self._create_connection(response_text) + + self.conn.request('PUT', '/', '') + headers = self.conn.get_proxy_response_headers() + self.assertIsNone(headers) + + def test_tunnel_leak(self): + sock = None + + def _create_connection(address, timeout=None, source_address=None): + nonlocal sock + sock = FakeSocket( + 'HTTP/1.1 404 NOT FOUND\r\n\r\n', + host=address[0], + port=address[1], + ) + return sock + + self.conn._create_connection = _create_connection + self.conn.set_tunnel('destination.com') + exc = None + try: + self.conn.request('HEAD', '/', '') + except OSError as e: + # keeping a reference to exc keeps response alive in the traceback + exc = e + self.assertIsNotNone(exc) + self.assertTrue(sock.file_closed) + if __name__ == '__main__': unittest.main(verbosity=2) diff --git a/Lib/test/test_httpservers.py b/Lib/test/test_httpservers.py index cbcf9413..15f94473 100644 --- a/Lib/test/test_httpservers.py +++ b/Lib/test/test_httpservers.py @@ -26,6 +26,7 @@ import time import datetime import threading from unittest import mock +import warnings from io import BytesIO, StringIO import unittest @@ -164,6 +165,27 @@ class BaseHTTPServerTestCase(BaseTestCase): res = self.con.getresponse() self.assertEqual(res.status, HTTPStatus.BAD_REQUEST) + def test_version_signs_and_underscores(self): + self.con._http_vsn_str = 'HTTP/-9_9_9.+9_9_9' + self.con.putrequest('GET', '/') + self.con.endheaders() + res = self.con.getresponse() + self.assertEqual(res.status, HTTPStatus.BAD_REQUEST) + + def test_major_version_number_too_long(self): + self.con._http_vsn_str = 'HTTP/909876543210.0' + self.con.putrequest('GET', '/') + self.con.endheaders() + res = self.con.getresponse() + self.assertEqual(res.status, HTTPStatus.BAD_REQUEST) + + def test_minor_version_number_too_long(self): + self.con._http_vsn_str = 'HTTP/1.909876543210' + self.con.putrequest('GET', '/') + self.con.endheaders() + res = self.con.getresponse() + self.assertEqual(res.status, HTTPStatus.BAD_REQUEST) + def test_version_none_get(self): self.con._http_vsn_str = '' self.con.putrequest('GET', '/') @@ -418,6 +440,14 @@ class SimpleHTTPServerTestCase(BaseTestCase): self.check_status_and_reason(response, HTTPStatus.OK, data=os_helper.TESTFN_UNDECODABLE) + def test_undecodable_parameter(self): + # sanity check using a valid parameter + response = self.request(self.base_url + '/?x=123').read() + self.assertRegex(response, rf'listing for {self.base_url}/\?x=123'.encode('latin1')) + # now the bogus encoding + response = self.request(self.base_url + '/?x=%bb').read() + self.assertRegex(response, rf'listing for {self.base_url}/\?x=\xef\xbf\xbd'.encode('latin1')) + def test_get_dir_redirect_location_domain_injection_bug(self): """Ensure //evil.co/..%2f../../X does not put //evil.co/ in Location. @@ -670,7 +700,11 @@ print("</pre>") "This test can't be run reliably as root (issue #13308).") class CGIHTTPServerTestCase(BaseTestCase): class request_handler(NoLogRequestHandler, CGIHTTPRequestHandler): - pass + def run_cgi(self): + # Silence the threading + fork DeprecationWarning this causes. + # gh-109096: This is deprecated in 3.13 to go away in 3.15. + with warnings.catch_warnings(action='ignore', category=DeprecationWarning): + return super().run_cgi() linesep = os.linesep.encode('ascii') diff --git a/Lib/test/test_idle.py b/Lib/test/test_idle.py index b94b18a5..ebb1e8eb 100644 --- a/Lib/test/test_idle.py +++ b/Lib/test/test_idle.py @@ -3,14 +3,10 @@ from test.support.import_helper import import_module from test.support import check_sanitizer if check_sanitizer(address=True, memory=True): - raise unittest.SkipTest("Tests involvin libX11 can SEGFAULT on ASAN/MSAN builds") + raise unittest.SkipTest("Tests involving libX11 can SEGFAULT on ASAN/MSAN builds") -# Skip test_idle if _tkinter wasn't built, if tkinter is missing, -# if tcl/tk is not the 8.5+ needed for ttk widgets, -# or if idlelib is missing (not installed). +# Skip test_idle if _tkinter, tkinter, or idlelib are missing. tk = import_module('tkinter') # Also imports _tkinter. -if tk.TkVersion < 8.5: - raise unittest.SkipTest("IDLE requires tk 8.5 or later.") idlelib = import_module('idlelib') # Before importing and executing more of idlelib, diff --git a/Lib/test/test_imaplib.py b/Lib/test/test_imaplib.py index ed26fa16..4b38355c 100644 --- a/Lib/test/test_imaplib.py +++ b/Lib/test/test_imaplib.py @@ -10,12 +10,9 @@ import calendar import threading import socket -from test.support import (verbose, - run_with_tz, run_with_locale, cpython_only, - requires_working_socket) +from test.support import verbose, run_with_tz, run_with_locale, cpython_only, requires_resource from test.support import hashlib_helper from test.support import threading_helper -from test.support import warnings_helper import unittest from unittest import mock from datetime import datetime, timezone, timedelta @@ -77,6 +74,7 @@ class TestImaplib(unittest.TestCase): for t in self.timevalues(): imaplib.Time2Internaldate(t) + @socket_helper.skip_if_tcp_blackhole def test_imap4_host_default_value(self): # Check whether the IMAP4_PORT is truly unavailable. with socket.socket() as s: @@ -459,6 +457,7 @@ class NewIMAPTestsMixin(): with self.imap_class(*server.server_address): pass + @requires_resource('walltime') def test_imaplib_timeout_test(self): _, server = self._setup(SimpleIMAPHandler) addr = server.server_address[1] @@ -552,6 +551,7 @@ class NewIMAPSSLTests(NewIMAPTestsMixin, unittest.TestCase): imap_class = IMAP4_SSL server_class = SecureTCPServer + @requires_resource('walltime') def test_ssl_raises(self): ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) self.assertEqual(ssl_context.verify_mode, ssl.CERT_REQUIRED) @@ -566,6 +566,7 @@ class NewIMAPSSLTests(NewIMAPTestsMixin, unittest.TestCase): ssl_context=ssl_context) client.shutdown() + @requires_resource('walltime') def test_ssl_verified(self): ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) ssl_context.load_verify_locations(CAFILE) @@ -575,15 +576,6 @@ class NewIMAPSSLTests(NewIMAPTestsMixin, unittest.TestCase): ssl_context=ssl_context) client.shutdown() - # Mock the private method _connect(), so mark the test as specific - # to CPython stdlib - @cpython_only - def test_certfile_arg_warn(self): - with warnings_helper.check_warnings(('', DeprecationWarning)): - with mock.patch.object(self.imap_class, 'open'): - with mock.patch.object(self.imap_class, '_connect'): - self.imap_class('localhost', 143, certfile=CERTFILE) - class ThreadedNetworkedTests(unittest.TestCase): server_class = socketserver.TCPServer imap_class = imaplib.IMAP4 @@ -762,7 +754,6 @@ class ThreadedNetworkedTests(unittest.TestCase): typ, data = client.login('user', 'pass') self.assertEqual(typ, 'OK') client.enable('UTF8=ACCEPT') - pass @threading_helper.reap_threads def test_enable_UTF8_True_append(self): @@ -1072,18 +1063,6 @@ class RemoteIMAP_SSLTest(RemoteIMAPTest): rs = _server.logout() self.assertEqual(rs[0], 'BYE', rs) - def test_ssl_context_certfile_exclusive(self): - with socket_helper.transient_internet(self.host): - self.assertRaises( - ValueError, self.imap_class, self.host, self.port, - certfile=CERTFILE, ssl_context=self.create_ssl_context()) - - def test_ssl_context_keyfile_exclusive(self): - with socket_helper.transient_internet(self.host): - self.assertRaises( - ValueError, self.imap_class, self.host, self.port, - keyfile=CERTFILE, ssl_context=self.create_ssl_context()) - if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_imp.py b/Lib/test/test_imp.py deleted file mode 100644 index 4bb03908..00000000 --- a/Lib/test/test_imp.py +++ /dev/null @@ -1,494 +0,0 @@ -import gc -import importlib -import importlib.util -import os -import os.path -import py_compile -import sys -from test import support -from test.support import import_helper -from test.support import os_helper -from test.support import script_helper -from test.support import warnings_helper -import unittest -import warnings -imp = warnings_helper.import_deprecated('imp') -import _imp - - -OS_PATH_NAME = os.path.__name__ - - -def requires_load_dynamic(meth): - """Decorator to skip a test if not running under CPython or lacking - imp.load_dynamic().""" - meth = support.cpython_only(meth) - return unittest.skipIf(getattr(imp, 'load_dynamic', None) is None, - 'imp.load_dynamic() required')(meth) - - -class LockTests(unittest.TestCase): - - """Very basic test of import lock functions.""" - - def verify_lock_state(self, expected): - self.assertEqual(imp.lock_held(), expected, - "expected imp.lock_held() to be %r" % expected) - def testLock(self): - LOOPS = 50 - - # The import lock may already be held, e.g. if the test suite is run - # via "import test.autotest". - lock_held_at_start = imp.lock_held() - self.verify_lock_state(lock_held_at_start) - - for i in range(LOOPS): - imp.acquire_lock() - self.verify_lock_state(True) - - for i in range(LOOPS): - imp.release_lock() - - # The original state should be restored now. - self.verify_lock_state(lock_held_at_start) - - if not lock_held_at_start: - try: - imp.release_lock() - except RuntimeError: - pass - else: - self.fail("release_lock() without lock should raise " - "RuntimeError") - -class ImportTests(unittest.TestCase): - def setUp(self): - mod = importlib.import_module('test.encoded_modules') - self.test_strings = mod.test_strings - self.test_path = mod.__path__ - - def test_import_encoded_module(self): - for modname, encoding, teststr in self.test_strings: - mod = importlib.import_module('test.encoded_modules.' - 'module_' + modname) - self.assertEqual(teststr, mod.test) - - def test_find_module_encoding(self): - for mod, encoding, _ in self.test_strings: - with imp.find_module('module_' + mod, self.test_path)[0] as fd: - self.assertEqual(fd.encoding, encoding) - - path = [os.path.dirname(__file__)] - with self.assertRaises(SyntaxError): - imp.find_module('badsyntax_pep3120', path) - - def test_issue1267(self): - for mod, encoding, _ in self.test_strings: - fp, filename, info = imp.find_module('module_' + mod, - self.test_path) - with fp: - self.assertNotEqual(fp, None) - self.assertEqual(fp.encoding, encoding) - self.assertEqual(fp.tell(), 0) - self.assertEqual(fp.readline(), '# test %s encoding\n' - % encoding) - - fp, filename, info = imp.find_module("tokenize") - with fp: - self.assertNotEqual(fp, None) - self.assertEqual(fp.encoding, "utf-8") - self.assertEqual(fp.tell(), 0) - self.assertEqual(fp.readline(), - '"""Tokenization help for Python programs.\n') - - def test_issue3594(self): - temp_mod_name = 'test_imp_helper' - sys.path.insert(0, '.') - try: - with open(temp_mod_name + '.py', 'w', encoding="latin-1") as file: - file.write("# coding: cp1252\nu = 'test.test_imp'\n") - file, filename, info = imp.find_module(temp_mod_name) - file.close() - self.assertEqual(file.encoding, 'cp1252') - finally: - del sys.path[0] - os_helper.unlink(temp_mod_name + '.py') - os_helper.unlink(temp_mod_name + '.pyc') - - def test_issue5604(self): - # Test cannot cover imp.load_compiled function. - # Martin von Loewis note what shared library cannot have non-ascii - # character because init_xxx function cannot be compiled - # and issue never happens for dynamic modules. - # But sources modified to follow generic way for processing paths. - - # the return encoding could be uppercase or None - fs_encoding = sys.getfilesystemencoding() - - # covers utf-8 and Windows ANSI code pages - # one non-space symbol from every page - # (http://en.wikipedia.org/wiki/Code_page) - known_locales = { - 'utf-8' : b'\xc3\xa4', - 'cp1250' : b'\x8C', - 'cp1251' : b'\xc0', - 'cp1252' : b'\xc0', - 'cp1253' : b'\xc1', - 'cp1254' : b'\xc0', - 'cp1255' : b'\xe0', - 'cp1256' : b'\xe0', - 'cp1257' : b'\xc0', - 'cp1258' : b'\xc0', - } - - if sys.platform == 'darwin': - self.assertEqual(fs_encoding, 'utf-8') - # Mac OS X uses the Normal Form D decomposition - # http://developer.apple.com/mac/library/qa/qa2001/qa1173.html - special_char = b'a\xcc\x88' - else: - special_char = known_locales.get(fs_encoding) - - if not special_char: - self.skipTest("can't run this test with %s as filesystem encoding" - % fs_encoding) - decoded_char = special_char.decode(fs_encoding) - temp_mod_name = 'test_imp_helper_' + decoded_char - test_package_name = 'test_imp_helper_package_' + decoded_char - init_file_name = os.path.join(test_package_name, '__init__.py') - try: - # if the curdir is not in sys.path the test fails when run with - # ./python ./Lib/test/regrtest.py test_imp - sys.path.insert(0, os.curdir) - with open(temp_mod_name + '.py', 'w', encoding="utf-8") as file: - file.write('a = 1\n') - file, filename, info = imp.find_module(temp_mod_name) - with file: - self.assertIsNotNone(file) - self.assertTrue(filename[:-3].endswith(temp_mod_name)) - self.assertEqual(info[0], '.py') - self.assertEqual(info[1], 'r') - self.assertEqual(info[2], imp.PY_SOURCE) - - mod = imp.load_module(temp_mod_name, file, filename, info) - self.assertEqual(mod.a, 1) - - with warnings.catch_warnings(): - warnings.simplefilter('ignore') - mod = imp.load_source(temp_mod_name, temp_mod_name + '.py') - self.assertEqual(mod.a, 1) - - with warnings.catch_warnings(): - warnings.simplefilter('ignore') - if not sys.dont_write_bytecode: - mod = imp.load_compiled( - temp_mod_name, - imp.cache_from_source(temp_mod_name + '.py')) - self.assertEqual(mod.a, 1) - - if not os.path.exists(test_package_name): - os.mkdir(test_package_name) - with open(init_file_name, 'w', encoding="utf-8") as file: - file.write('b = 2\n') - with warnings.catch_warnings(): - warnings.simplefilter('ignore') - package = imp.load_package(test_package_name, test_package_name) - self.assertEqual(package.b, 2) - finally: - del sys.path[0] - for ext in ('.py', '.pyc'): - os_helper.unlink(temp_mod_name + ext) - os_helper.unlink(init_file_name + ext) - os_helper.rmtree(test_package_name) - os_helper.rmtree('__pycache__') - - def test_issue9319(self): - path = os.path.dirname(__file__) - self.assertRaises(SyntaxError, - imp.find_module, "badsyntax_pep3120", [path]) - - def test_load_from_source(self): - # Verify that the imp module can correctly load and find .py files - # XXX (ncoghlan): It would be nice to use import_helper.CleanImport - # here, but that breaks because the os module registers some - # handlers in copy_reg on import. Since CleanImport doesn't - # revert that registration, the module is left in a broken - # state after reversion. Reinitialising the module contents - # and just reverting os.environ to its previous state is an OK - # workaround - with import_helper.CleanImport('os', 'os.path', OS_PATH_NAME): - import os - orig_path = os.path - orig_getenv = os.getenv - with os_helper.EnvironmentVarGuard(): - x = imp.find_module("os") - self.addCleanup(x[0].close) - new_os = imp.load_module("os", *x) - self.assertIs(os, new_os) - self.assertIs(orig_path, new_os.path) - self.assertIsNot(orig_getenv, new_os.getenv) - - @requires_load_dynamic - def test_issue15828_load_extensions(self): - # Issue 15828 picked up that the adapter between the old imp API - # and importlib couldn't handle C extensions - example = "_heapq" - x = imp.find_module(example) - file_ = x[0] - if file_ is not None: - self.addCleanup(file_.close) - mod = imp.load_module(example, *x) - self.assertEqual(mod.__name__, example) - - @requires_load_dynamic - def test_issue16421_multiple_modules_in_one_dll(self): - # Issue 16421: loading several modules from the same compiled file fails - m = '_testimportmultiple' - fileobj, pathname, description = imp.find_module(m) - fileobj.close() - mod0 = imp.load_dynamic(m, pathname) - mod1 = imp.load_dynamic('_testimportmultiple_foo', pathname) - mod2 = imp.load_dynamic('_testimportmultiple_bar', pathname) - self.assertEqual(mod0.__name__, m) - self.assertEqual(mod1.__name__, '_testimportmultiple_foo') - self.assertEqual(mod2.__name__, '_testimportmultiple_bar') - with self.assertRaises(ImportError): - imp.load_dynamic('nonexistent', pathname) - - @requires_load_dynamic - def test_load_dynamic_ImportError_path(self): - # Issue #1559549 added `name` and `path` attributes to ImportError - # in order to provide better detail. Issue #10854 implemented those - # attributes on import failures of extensions on Windows. - path = 'bogus file path' - name = 'extension' - with self.assertRaises(ImportError) as err: - imp.load_dynamic(name, path) - self.assertIn(path, err.exception.path) - self.assertEqual(name, err.exception.name) - - @requires_load_dynamic - def test_load_module_extension_file_is_None(self): - # When loading an extension module and the file is None, open one - # on the behalf of imp.load_dynamic(). - # Issue #15902 - name = '_testimportmultiple' - found = imp.find_module(name) - if found[0] is not None: - found[0].close() - if found[2][2] != imp.C_EXTENSION: - self.skipTest("found module doesn't appear to be a C extension") - imp.load_module(name, None, *found[1:]) - - @requires_load_dynamic - def test_issue24748_load_module_skips_sys_modules_check(self): - name = 'test.imp_dummy' - try: - del sys.modules[name] - except KeyError: - pass - try: - module = importlib.import_module(name) - spec = importlib.util.find_spec('_testmultiphase') - module = imp.load_dynamic(name, spec.origin) - self.assertEqual(module.__name__, name) - self.assertEqual(module.__spec__.name, name) - self.assertEqual(module.__spec__.origin, spec.origin) - self.assertRaises(AttributeError, getattr, module, 'dummy_name') - self.assertEqual(module.int_const, 1969) - self.assertIs(sys.modules[name], module) - finally: - try: - del sys.modules[name] - except KeyError: - pass - - @unittest.skipIf(sys.dont_write_bytecode, - "test meaningful only when writing bytecode") - def test_bug7732(self): - with os_helper.temp_cwd(): - source = os_helper.TESTFN + '.py' - os.mkdir(source) - self.assertRaisesRegex(ImportError, '^No module', - imp.find_module, os_helper.TESTFN, ["."]) - - def test_multiple_calls_to_get_data(self): - # Issue #18755: make sure multiple calls to get_data() can succeed. - loader = imp._LoadSourceCompatibility('imp', imp.__file__, - open(imp.__file__, encoding="utf-8")) - loader.get_data(imp.__file__) # File should be closed - loader.get_data(imp.__file__) # Will need to create a newly opened file - - def test_load_source(self): - # 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()) - - def test_issue_35321(self): - # Both _frozen_importlib and _frozen_importlib_external - # should have a spec origin of "frozen" and - # no need to clean up imports in this case. - - import _frozen_importlib_external - self.assertEqual(_frozen_importlib_external.__spec__.origin, "frozen") - - import _frozen_importlib - self.assertEqual(_frozen_importlib.__spec__.origin, "frozen") - - def test_source_hash(self): - self.assertEqual(_imp.source_hash(42, b'hi'), b'\xfb\xd9G\x05\xaf$\x9b~') - self.assertEqual(_imp.source_hash(43, b'hi'), b'\xd0/\x87C\xccC\xff\xe2') - - def test_pyc_invalidation_mode_from_cmdline(self): - cases = [ - ([], "default"), - (["--check-hash-based-pycs", "default"], "default"), - (["--check-hash-based-pycs", "always"], "always"), - (["--check-hash-based-pycs", "never"], "never"), - ] - for interp_args, expected in cases: - args = interp_args + [ - "-c", - "import _imp; print(_imp.check_hash_based_pycs)", - ] - res = script_helper.assert_python_ok(*args) - self.assertEqual(res.out.strip().decode('utf-8'), expected) - - def test_find_and_load_checked_pyc(self): - # issue 34056 - with os_helper.temp_cwd(): - with open('mymod.py', 'wb') as fp: - fp.write(b'x = 42\n') - py_compile.compile( - 'mymod.py', - doraise=True, - invalidation_mode=py_compile.PycInvalidationMode.CHECKED_HASH, - ) - file, path, description = imp.find_module('mymod', path=['.']) - mod = imp.load_module('mymod', file, path, description) - self.assertEqual(mod.x, 42) - - - @support.cpython_only - def test_create_builtin_subinterp(self): - # gh-99578: create_builtin() behavior changes after the creation of the - # first sub-interpreter. Test both code paths, before and after the - # creation of a sub-interpreter. Previously, create_builtin() had - # a reference leak after the creation of the first sub-interpreter. - - import builtins - create_builtin = support.get_attribute(_imp, "create_builtin") - class Spec: - name = "builtins" - spec = Spec() - - def check_get_builtins(): - refcnt = sys.getrefcount(builtins) - mod = _imp.create_builtin(spec) - self.assertIs(mod, builtins) - self.assertEqual(sys.getrefcount(builtins), refcnt + 1) - # Check that a GC collection doesn't crash - gc.collect() - - check_get_builtins() - - ret = support.run_in_subinterp("import builtins") - self.assertEqual(ret, 0) - - check_get_builtins() - - -class ReloadTests(unittest.TestCase): - - """Very basic tests to make sure that imp.reload() operates just like - reload().""" - - def test_source(self): - # XXX (ncoghlan): It would be nice to use test.import_helper.CleanImport - # here, but that breaks because the os module registers some - # handlers in copy_reg on import. Since CleanImport doesn't - # revert that registration, the module is left in a broken - # state after reversion. Reinitialising the module contents - # and just reverting os.environ to its previous state is an OK - # workaround - with os_helper.EnvironmentVarGuard(): - import os - imp.reload(os) - - def test_extension(self): - with import_helper.CleanImport('time'): - import time - imp.reload(time) - - def test_builtin(self): - with import_helper.CleanImport('marshal'): - import marshal - imp.reload(marshal) - - def test_with_deleted_parent(self): - # see #18681 - from html import parser - html = sys.modules.pop('html') - def cleanup(): - sys.modules['html'] = html - self.addCleanup(cleanup) - with self.assertRaisesRegex(ImportError, 'html'): - imp.reload(parser) - - -class PEP3147Tests(unittest.TestCase): - """Tests of PEP 3147.""" - - tag = imp.get_tag() - - @unittest.skipUnless(sys.implementation.cache_tag is not None, - 'requires sys.implementation.cache_tag not be None') - def test_cache_from_source(self): - # Given the path to a .py file, return the path to its PEP 3147 - # defined .pyc file (i.e. under __pycache__). - path = os.path.join('foo', 'bar', 'baz', 'qux.py') - expect = os.path.join('foo', 'bar', 'baz', '__pycache__', - 'qux.{}.pyc'.format(self.tag)) - self.assertEqual(imp.cache_from_source(path, True), expect) - - @unittest.skipUnless(sys.implementation.cache_tag is not None, - 'requires sys.implementation.cache_tag to not be ' - 'None') - def test_source_from_cache(self): - # Given the path to a PEP 3147 defined .pyc file, return the path to - # its source. This tests the good path. - path = os.path.join('foo', 'bar', 'baz', '__pycache__', - 'qux.{}.pyc'.format(self.tag)) - expect = os.path.join('foo', 'bar', 'baz', 'qux.py') - self.assertEqual(imp.source_from_cache(path), expect) - - -class NullImporterTests(unittest.TestCase): - @unittest.skipIf(os_helper.TESTFN_UNENCODABLE is None, - "Need an undecodeable filename") - def test_unencodeable(self): - name = os_helper.TESTFN_UNENCODABLE - os.mkdir(name) - try: - self.assertRaises(ImportError, imp.NullImporter, name) - finally: - os.rmdir(name) - - -if __name__ == "__main__": - unittest.main() diff --git a/Lib/test/test_import/__init__.py b/Lib/test/test_import/__init__.py index 6c5b80bc..62585b23 100644 --- a/Lib/test/test_import/__init__.py +++ b/Lib/test/test_import/__init__.py @@ -2,8 +2,12 @@ import builtins import contextlib import errno import glob +import json import importlib.util from importlib._bootstrap_external import _get_sourcefile +from importlib.machinery import ( + BuiltinImporter, ExtensionFileLoader, FrozenImporter, SourceFileLoader, +) import marshal import os import py_compile @@ -15,13 +19,16 @@ import sys import textwrap import threading import time +import types import unittest from unittest import mock +import _testinternalcapi +import _imp from test.support import os_helper from test.support import ( - STDLIB_DIR, is_jython, swap_attr, swap_item, cpython_only, is_emscripten, - is_wasi) + STDLIB_DIR, swap_attr, swap_item, cpython_only, is_emscripten, + is_wasi, run_in_subinterp, run_in_subinterp_with_config) from test.support.import_helper import ( forget, make_legacy_pyc, unlink, unload, DirsOnSysPath, CleanImport) from test.support.os_helper import ( @@ -30,12 +37,66 @@ from test.support import script_helper from test.support import threading_helper from test.test_importlib.util import uncache from types import ModuleType +try: + import _testsinglephase +except ImportError: + _testsinglephase = None +try: + import _testmultiphase +except ImportError: + _testmultiphase = None +try: + import _xxsubinterpreters as _interpreters +except ModuleNotFoundError: + _interpreters = None skip_if_dont_write_bytecode = unittest.skipIf( sys.dont_write_bytecode, "test meaningful only when writing bytecode") + +def _require_loader(module, loader, skip): + if isinstance(module, str): + module = __import__(module) + + MODULE_KINDS = { + BuiltinImporter: 'built-in', + ExtensionFileLoader: 'extension', + FrozenImporter: 'frozen', + SourceFileLoader: 'pure Python', + } + + expected = loader + assert isinstance(expected, type), expected + expected = MODULE_KINDS[expected] + + actual = module.__spec__.loader + if not isinstance(actual, type): + actual = type(actual) + actual = MODULE_KINDS[actual] + + if actual != expected: + err = f'expected module to be {expected}, got {module.__spec__}' + if skip: + raise unittest.SkipTest(err) + raise Exception(err) + return module + +def require_builtin(module, *, skip=False): + module = _require_loader(module, BuiltinImporter, skip) + assert module.__spec__.origin == 'built-in', module.__spec__ + +def require_extension(module, *, skip=False): + _require_loader(module, ExtensionFileLoader, skip) + +def require_frozen(module, *, skip=True): + module = _require_loader(module, FrozenImporter, skip) + assert module.__spec__.origin == 'frozen', module.__spec__ + +def require_pure_python(module, *, skip=False): + _require_loader(module, SourceFileLoader, skip) + def remove_files(name): for f in (name + ".py", name + ".pyc", @@ -45,6 +106,25 @@ def remove_files(name): rmtree('__pycache__') +def no_rerun(reason): + """Skip rerunning for a particular test. + + WARNING: Use this decorator with care; skipping rerunning makes it + impossible to find reference leaks. Provide a clear reason for skipping the + test using the 'reason' parameter. + """ + def deco(func): + _has_run = False + def wrapper(self): + nonlocal _has_run + if _has_run: + self.skipTest(reason) + func(self) + _has_run = True + return wrapper + return deco + + @contextlib.contextmanager def _ready_to_import(name=None, source=""): # sets up a temporary directory and removes it @@ -66,6 +146,198 @@ def _ready_to_import(name=None, source=""): del sys.modules[name] +if _testsinglephase is not None: + def restore__testsinglephase(*, _orig=_testsinglephase): + # We started with the module imported and want to restore + # it to its nominal state. + sys.modules.pop('_testsinglephase', None) + _orig._clear_globals() + _testinternalcapi.clear_extension('_testsinglephase', _orig.__file__) + import _testsinglephase + + +def requires_singlephase_init(meth): + """Decorator to skip if single-phase init modules are not supported.""" + if not isinstance(meth, type): + def meth(self, _meth=meth): + try: + return _meth(self) + finally: + restore__testsinglephase() + meth = cpython_only(meth) + return unittest.skipIf(_testsinglephase is None, + 'test requires _testsinglephase module')(meth) + + +def requires_subinterpreters(meth): + """Decorator to skip a test if subinterpreters are not supported.""" + return unittest.skipIf(_interpreters is None, + 'subinterpreters required')(meth) + + +class ModuleSnapshot(types.SimpleNamespace): + """A representation of a module for testing. + + Fields: + + * id - the module's object ID + * module - the actual module or an adequate substitute + * __file__ + * __spec__ + * name + * origin + * ns - a copy (dict) of the module's __dict__ (or None) + * ns_id - the object ID of the module's __dict__ + * cached - the sys.modules[mod.__spec__.name] entry (or None) + * cached_id - the object ID of the sys.modules entry (or None) + + In cases where the value is not available (e.g. due to serialization), + the value will be None. + """ + _fields = tuple('id module ns ns_id cached cached_id'.split()) + + @classmethod + def from_module(cls, mod): + name = mod.__spec__.name + cached = sys.modules.get(name) + return cls( + id=id(mod), + module=mod, + ns=types.SimpleNamespace(**mod.__dict__), + ns_id=id(mod.__dict__), + cached=cached, + cached_id=id(cached), + ) + + SCRIPT = textwrap.dedent(''' + {imports} + + name = {name!r} + + {prescript} + + mod = {name} + + {body} + + {postscript} + ''') + IMPORTS = textwrap.dedent(''' + import sys + ''').strip() + SCRIPT_BODY = textwrap.dedent(''' + # Capture the snapshot data. + cached = sys.modules.get(name) + snapshot = dict( + id=id(mod), + module=dict( + __file__=mod.__file__, + __spec__=dict( + name=mod.__spec__.name, + origin=mod.__spec__.origin, + ), + ), + ns=None, + ns_id=id(mod.__dict__), + cached=None, + cached_id=id(cached) if cached else None, + ) + ''').strip() + CLEANUP_SCRIPT = textwrap.dedent(''' + # Clean up the module. + sys.modules.pop(name, None) + ''').strip() + + @classmethod + def build_script(cls, name, *, + prescript=None, + import_first=False, + postscript=None, + postcleanup=False, + ): + if postcleanup is True: + postcleanup = cls.CLEANUP_SCRIPT + elif isinstance(postcleanup, str): + postcleanup = textwrap.dedent(postcleanup).strip() + postcleanup = cls.CLEANUP_SCRIPT + os.linesep + postcleanup + else: + postcleanup = '' + prescript = textwrap.dedent(prescript).strip() if prescript else '' + postscript = textwrap.dedent(postscript).strip() if postscript else '' + + if postcleanup: + if postscript: + postscript = postscript + os.linesep * 2 + postcleanup + else: + postscript = postcleanup + + if import_first: + prescript += textwrap.dedent(f''' + + # Now import the module. + assert name not in sys.modules + import {name}''') + + return cls.SCRIPT.format( + imports=cls.IMPORTS.strip(), + name=name, + prescript=prescript.strip(), + body=cls.SCRIPT_BODY.strip(), + postscript=postscript, + ) + + @classmethod + def parse(cls, text): + raw = json.loads(text) + mod = raw['module'] + mod['__spec__'] = types.SimpleNamespace(**mod['__spec__']) + raw['module'] = types.SimpleNamespace(**mod) + return cls(**raw) + + @classmethod + def from_subinterp(cls, name, interpid=None, *, pipe=None, **script_kwds): + if pipe is not None: + return cls._from_subinterp(name, interpid, pipe, script_kwds) + pipe = os.pipe() + try: + return cls._from_subinterp(name, interpid, pipe, script_kwds) + finally: + r, w = pipe + os.close(r) + os.close(w) + + @classmethod + def _from_subinterp(cls, name, interpid, pipe, script_kwargs): + r, w = pipe + + # Build the script. + postscript = textwrap.dedent(f''' + # Send the result over the pipe. + import json + import os + os.write({w}, json.dumps(snapshot).encode()) + + ''') + _postscript = script_kwargs.get('postscript') + if _postscript: + _postscript = textwrap.dedent(_postscript).lstrip() + postscript += _postscript + script_kwargs['postscript'] = postscript.strip() + script = cls.build_script(name, **script_kwargs) + + # Run the script. + if interpid is None: + ret = run_in_subinterp(script) + if ret != 0: + raise AssertionError(f'{ret} != 0') + else: + _interpreters.run_string(interpid, script) + + # Parse the results. + text = os.read(r, 1000) + return cls.parse(text.decode()) + + class ImportTests(unittest.TestCase): def setUp(self): @@ -163,10 +435,7 @@ class ImportTests(unittest.TestCase): def test_with_extension(ext): # The extension is normally ".py", perhaps ".pyw". source = TESTFN + ext - if is_jython: - pyc = TESTFN + "$py.class" - else: - pyc = TESTFN + ".pyc" + pyc = TESTFN + ".pyc" with open(source, "w", encoding='utf-8') as f: print("# This tests Python's ability to import a", @@ -529,6 +798,13 @@ class ImportTests(unittest.TestCase): env=env, cwd=os.path.dirname(pyexe)) + def test_issue105979(self): + # this used to crash + with self.assertRaises(ImportError) as cm: + _imp.get_frozen_object("x", b"6\'\xd5Cu\x12") + self.assertIn("Frozen object named 'x' is invalid", + str(cm.exception)) + @skip_if_dont_write_bytecode class FilePermissionTests(unittest.TestCase): @@ -1395,6 +1671,1019 @@ class CircularImportTests(unittest.TestCase): unwritable.x = 42 +class SubinterpImportTests(unittest.TestCase): + + RUN_KWARGS = dict( + allow_fork=False, + allow_exec=False, + allow_threads=True, + allow_daemon_threads=False, + # Isolation-related config values aren't included here. + ) + ISOLATED = dict( + use_main_obmalloc=False, + gil=2, + ) + NOT_ISOLATED = {k: not v for k, v in ISOLATED.items()} + NOT_ISOLATED['gil'] = 1 + + @unittest.skipUnless(hasattr(os, "pipe"), "requires os.pipe()") + def pipe(self): + r, w = os.pipe() + self.addCleanup(os.close, r) + self.addCleanup(os.close, w) + if hasattr(os, 'set_blocking'): + os.set_blocking(r, False) + return (r, w) + + def import_script(self, name, fd, filename=None, check_override=None): + override_text = '' + if check_override is not None: + override_text = f''' + import _imp + _imp._override_multi_interp_extensions_check({check_override}) + ''' + if filename: + return textwrap.dedent(f''' + from importlib.util import spec_from_loader, module_from_spec + from importlib.machinery import ExtensionFileLoader + import os, sys + {override_text} + loader = ExtensionFileLoader({name!r}, {filename!r}) + spec = spec_from_loader({name!r}, loader) + try: + module = module_from_spec(spec) + loader.exec_module(module) + except ImportError as exc: + text = 'ImportError: ' + str(exc) + else: + text = 'okay' + os.write({fd}, text.encode('utf-8')) + ''') + else: + return textwrap.dedent(f''' + import os, sys + {override_text} + try: + import {name} + except ImportError as exc: + text = 'ImportError: ' + str(exc) + else: + text = 'okay' + os.write({fd}, text.encode('utf-8')) + ''') + + def run_here(self, name, filename=None, *, + check_singlephase_setting=False, + check_singlephase_override=None, + isolated=False, + ): + """ + Try importing the named module in a subinterpreter. + + The subinterpreter will be in the current process. + The module will have already been imported in the main interpreter. + Thus, for extension/builtin modules, the module definition will + have been loaded already and cached globally. + + "check_singlephase_setting" determines whether or not + the interpreter will be configured to check for modules + that are not compatible with use in multiple interpreters. + + This should always return "okay" for all modules if the + setting is False (with no override). + """ + __import__(name) + + kwargs = dict( + **self.RUN_KWARGS, + **(self.ISOLATED if isolated else self.NOT_ISOLATED), + check_multi_interp_extensions=check_singlephase_setting, + ) + + r, w = self.pipe() + script = self.import_script(name, w, filename, + check_singlephase_override) + + ret = run_in_subinterp_with_config(script, **kwargs) + self.assertEqual(ret, 0) + return os.read(r, 100) + + def check_compatible_here(self, name, filename=None, *, + strict=False, + isolated=False, + ): + # Verify that the named module may be imported in a subinterpreter. + # (See run_here() for more info.) + out = self.run_here(name, filename, + check_singlephase_setting=strict, + isolated=isolated, + ) + self.assertEqual(out, b'okay') + + def check_incompatible_here(self, name, filename=None, *, isolated=False): + # Differences from check_compatible_here(): + # * verify that import fails + # * "strict" is always True + out = self.run_here(name, filename, + check_singlephase_setting=True, + isolated=isolated, + ) + self.assertEqual( + out.decode('utf-8'), + f'ImportError: module {name} does not support loading in subinterpreters', + ) + + def check_compatible_fresh(self, name, *, strict=False, isolated=False): + # Differences from check_compatible_here(): + # * subinterpreter in a new process + # * module has never been imported before in that process + # * this tests importing the module for the first time + kwargs = dict( + **self.RUN_KWARGS, + **(self.ISOLATED if isolated else self.NOT_ISOLATED), + check_multi_interp_extensions=strict, + ) + _, out, err = script_helper.assert_python_ok('-c', textwrap.dedent(f''' + import _testcapi, sys + assert ( + {name!r} in sys.builtin_module_names or + {name!r} not in sys.modules + ), repr({name!r}) + ret = _testcapi.run_in_subinterp_with_config( + {self.import_script(name, "sys.stdout.fileno()")!r}, + **{kwargs}, + ) + assert ret == 0, ret + ''')) + self.assertEqual(err, b'') + self.assertEqual(out, b'okay') + + def check_incompatible_fresh(self, name, *, isolated=False): + # Differences from check_compatible_fresh(): + # * verify that import fails + # * "strict" is always True + kwargs = dict( + **self.RUN_KWARGS, + **(self.ISOLATED if isolated else self.NOT_ISOLATED), + check_multi_interp_extensions=True, + ) + _, out, err = script_helper.assert_python_ok('-c', textwrap.dedent(f''' + import _testcapi, sys + assert {name!r} not in sys.modules, {name!r} + ret = _testcapi.run_in_subinterp_with_config( + {self.import_script(name, "sys.stdout.fileno()")!r}, + **{kwargs}, + ) + assert ret == 0, ret + ''')) + self.assertEqual(err, b'') + self.assertEqual( + out.decode('utf-8'), + f'ImportError: module {name} does not support loading in subinterpreters', + ) + + def test_builtin_compat(self): + # For now we avoid using sys or builtins + # since they still don't implement multi-phase init. + module = '_imp' + require_builtin(module) + with self.subTest(f'{module}: not strict'): + self.check_compatible_here(module, strict=False) + with self.subTest(f'{module}: strict, not fresh'): + self.check_compatible_here(module, strict=True) + + @cpython_only + def test_frozen_compat(self): + module = '_frozen_importlib' + require_frozen(module, skip=True) + if __import__(module).__spec__.origin != 'frozen': + raise unittest.SkipTest(f'{module} is unexpectedly not frozen') + with self.subTest(f'{module}: not strict'): + self.check_compatible_here(module, strict=False) + with self.subTest(f'{module}: strict, not fresh'): + self.check_compatible_here(module, strict=True) + + @requires_singlephase_init + def test_single_init_extension_compat(self): + module = '_testsinglephase' + require_extension(module) + with self.subTest(f'{module}: not strict'): + self.check_compatible_here(module, strict=False) + with self.subTest(f'{module}: strict, not fresh'): + self.check_incompatible_here(module) + with self.subTest(f'{module}: strict, fresh'): + self.check_incompatible_fresh(module) + + @unittest.skipIf(_testmultiphase is None, "test requires _testmultiphase module") + def test_multi_init_extension_compat(self): + module = '_testmultiphase' + require_extension(module) + with self.subTest(f'{module}: not strict'): + self.check_compatible_here(module, strict=False) + with self.subTest(f'{module}: strict, not fresh'): + self.check_compatible_here(module, strict=True) + with self.subTest(f'{module}: strict, fresh'): + self.check_compatible_fresh(module, strict=True) + + @unittest.skipIf(_testmultiphase is None, "test requires _testmultiphase module") + def test_multi_init_extension_non_isolated_compat(self): + modname = '_test_non_isolated' + filename = _testmultiphase.__file__ + loader = ExtensionFileLoader(modname, filename) + spec = importlib.util.spec_from_loader(modname, loader) + module = importlib.util.module_from_spec(spec) + loader.exec_module(module) + sys.modules[modname] = module + + require_extension(module) + with self.subTest(f'{modname}: isolated'): + self.check_incompatible_here(modname, filename, isolated=True) + with self.subTest(f'{modname}: not isolated'): + self.check_incompatible_here(modname, filename, isolated=False) + with self.subTest(f'{modname}: not strict'): + self.check_compatible_here(modname, filename, strict=False) + + @unittest.skipIf(_testmultiphase is None, "test requires _testmultiphase module") + def test_multi_init_extension_per_interpreter_gil_compat(self): + modname = '_test_shared_gil_only' + filename = _testmultiphase.__file__ + loader = ExtensionFileLoader(modname, filename) + spec = importlib.util.spec_from_loader(modname, loader) + module = importlib.util.module_from_spec(spec) + loader.exec_module(module) + sys.modules[modname] = module + + require_extension(module) + with self.subTest(f'{modname}: isolated, strict'): + self.check_incompatible_here(modname, filename, isolated=True) + with self.subTest(f'{modname}: not isolated, strict'): + self.check_compatible_here(modname, filename, + strict=True, isolated=False) + with self.subTest(f'{modname}: not isolated, not strict'): + self.check_compatible_here(modname, filename, + strict=False, isolated=False) + + def test_python_compat(self): + module = 'threading' + require_pure_python(module) + with self.subTest(f'{module}: not strict'): + self.check_compatible_here(module, strict=False) + with self.subTest(f'{module}: strict, not fresh'): + self.check_compatible_here(module, strict=True) + with self.subTest(f'{module}: strict, fresh'): + self.check_compatible_fresh(module, strict=True) + + @requires_singlephase_init + def test_singlephase_check_with_setting_and_override(self): + module = '_testsinglephase' + require_extension(module) + + def check_compatible(setting, override): + out = self.run_here( + module, + check_singlephase_setting=setting, + check_singlephase_override=override, + ) + self.assertEqual(out, b'okay') + + def check_incompatible(setting, override): + out = self.run_here( + module, + check_singlephase_setting=setting, + check_singlephase_override=override, + ) + self.assertNotEqual(out, b'okay') + + with self.subTest('config: check enabled; override: enabled'): + check_incompatible(True, 1) + with self.subTest('config: check enabled; override: use config'): + check_incompatible(True, 0) + with self.subTest('config: check enabled; override: disabled'): + check_compatible(True, -1) + + with self.subTest('config: check disabled; override: enabled'): + check_incompatible(False, 1) + with self.subTest('config: check disabled; override: use config'): + check_compatible(False, 0) + with self.subTest('config: check disabled; override: disabled'): + check_compatible(False, -1) + + def test_isolated_config(self): + module = 'threading' + require_pure_python(module) + with self.subTest(f'{module}: strict, not fresh'): + self.check_compatible_here(module, strict=True, isolated=True) + with self.subTest(f'{module}: strict, fresh'): + self.check_compatible_fresh(module, strict=True, isolated=True) + + @requires_subinterpreters + @requires_singlephase_init + def test_disallowed_reimport(self): + # See https://github.com/python/cpython/issues/104621. + script = textwrap.dedent(''' + import _testsinglephase + print(_testsinglephase) + ''') + interpid = _interpreters.create() + with self.assertRaises(_interpreters.RunFailedError): + _interpreters.run_string(interpid, script) + with self.assertRaises(_interpreters.RunFailedError): + _interpreters.run_string(interpid, script) + + +class TestSinglePhaseSnapshot(ModuleSnapshot): + + @classmethod + def from_module(cls, mod): + self = super().from_module(mod) + self.summed = mod.sum(1, 2) + self.lookedup = mod.look_up_self() + self.lookedup_id = id(self.lookedup) + self.state_initialized = mod.state_initialized() + if hasattr(mod, 'initialized_count'): + self.init_count = mod.initialized_count() + return self + + SCRIPT_BODY = ModuleSnapshot.SCRIPT_BODY + textwrap.dedent(''' + snapshot['module'].update(dict( + int_const=mod.int_const, + str_const=mod.str_const, + _module_initialized=mod._module_initialized, + )) + snapshot.update(dict( + summed=mod.sum(1, 2), + lookedup_id=id(mod.look_up_self()), + state_initialized=mod.state_initialized(), + init_count=mod.initialized_count(), + has_spam=hasattr(mod, 'spam'), + spam=getattr(mod, 'spam', None), + )) + ''').rstrip() + + @classmethod + def parse(cls, text): + self = super().parse(text) + if not self.has_spam: + del self.spam + del self.has_spam + return self + + +@requires_singlephase_init +class SinglephaseInitTests(unittest.TestCase): + + NAME = '_testsinglephase' + + @classmethod + def setUpClass(cls): + spec = importlib.util.find_spec(cls.NAME) + from importlib.machinery import ExtensionFileLoader + cls.FILE = spec.origin + cls.LOADER = type(spec.loader) + assert cls.LOADER is ExtensionFileLoader + + # Start fresh. + cls.clean_up() + + @classmethod + def tearDownClass(cls): + restore__testsinglephase() + + def tearDown(self): + # Clean up the module. + self.clean_up() + + @classmethod + def clean_up(cls): + name = cls.NAME + filename = cls.FILE + if name in sys.modules: + if hasattr(sys.modules[name], '_clear_globals'): + assert sys.modules[name].__file__ == filename + sys.modules[name]._clear_globals() + del sys.modules[name] + # Clear all internally cached data for the extension. + _testinternalcapi.clear_extension(name, filename) + + ######################### + # helpers + + def add_module_cleanup(self, name): + def clean_up(): + # Clear all internally cached data for the extension. + _testinternalcapi.clear_extension(name, self.FILE) + self.addCleanup(clean_up) + + def _load_dynamic(self, name, path): + """ + Load an extension module. + """ + # This is essentially copied from the old imp module. + from importlib._bootstrap import _load + loader = self.LOADER(name, path) + + # Issue bpo-24748: Skip the sys.modules check in _load_module_shim; + # always load new extension. + spec = importlib.util.spec_from_file_location(name, path, + loader=loader) + return _load(spec) + + def load(self, name): + try: + already_loaded = self.already_loaded + except AttributeError: + already_loaded = self.already_loaded = {} + assert name not in already_loaded + mod = self._load_dynamic(name, self.FILE) + self.assertNotIn(mod, already_loaded.values()) + already_loaded[name] = mod + return types.SimpleNamespace( + name=name, + module=mod, + snapshot=TestSinglePhaseSnapshot.from_module(mod), + ) + + def re_load(self, name, mod): + assert sys.modules[name] is mod + assert mod.__dict__ == mod.__dict__ + reloaded = self._load_dynamic(name, self.FILE) + return types.SimpleNamespace( + name=name, + module=reloaded, + snapshot=TestSinglePhaseSnapshot.from_module(reloaded), + ) + + # subinterpreters + + def add_subinterpreter(self): + interpid = _interpreters.create(isolated=False) + _interpreters.run_string(interpid, textwrap.dedent(''' + import sys + import _testinternalcapi + ''')) + def clean_up(): + _interpreters.run_string(interpid, textwrap.dedent(f''' + name = {self.NAME!r} + if name in sys.modules: + sys.modules.pop(name)._clear_globals() + _testinternalcapi.clear_extension(name, {self.FILE!r}) + ''')) + _interpreters.destroy(interpid) + self.addCleanup(clean_up) + return interpid + + def import_in_subinterp(self, interpid=None, *, + postscript=None, + postcleanup=False, + ): + name = self.NAME + + if postcleanup: + import_ = 'import _testinternalcapi' if interpid is None else '' + postcleanup = f''' + {import_} + mod._clear_globals() + _testinternalcapi.clear_extension(name, {self.FILE!r}) + ''' + + try: + pipe = self._pipe + except AttributeError: + r, w = pipe = self._pipe = os.pipe() + self.addCleanup(os.close, r) + self.addCleanup(os.close, w) + + snapshot = TestSinglePhaseSnapshot.from_subinterp( + name, + interpid, + pipe=pipe, + import_first=True, + postscript=postscript, + postcleanup=postcleanup, + ) + + return types.SimpleNamespace( + name=name, + module=None, + snapshot=snapshot, + ) + + # checks + + def check_common(self, loaded): + isolated = False + + mod = loaded.module + if not mod: + # It came from a subinterpreter. + isolated = True + mod = loaded.snapshot.module + # mod.__name__ might not match, but the spec will. + self.assertEqual(mod.__spec__.name, loaded.name) + self.assertEqual(mod.__file__, self.FILE) + self.assertEqual(mod.__spec__.origin, self.FILE) + if not isolated: + self.assertTrue(issubclass(mod.error, Exception)) + self.assertEqual(mod.int_const, 1969) + self.assertEqual(mod.str_const, 'something different') + self.assertIsInstance(mod._module_initialized, float) + self.assertGreater(mod._module_initialized, 0) + + snap = loaded.snapshot + self.assertEqual(snap.summed, 3) + if snap.state_initialized is not None: + self.assertIsInstance(snap.state_initialized, float) + self.assertGreater(snap.state_initialized, 0) + if isolated: + # The "looked up" module is interpreter-specific + # (interp->imports.modules_by_index was set for the module). + self.assertEqual(snap.lookedup_id, snap.id) + self.assertEqual(snap.cached_id, snap.id) + with self.assertRaises(AttributeError): + snap.spam + else: + self.assertIs(snap.lookedup, mod) + self.assertIs(snap.cached, mod) + + def check_direct(self, loaded): + # The module has its own PyModuleDef, with a matching name. + self.assertEqual(loaded.module.__name__, loaded.name) + self.assertIs(loaded.snapshot.lookedup, loaded.module) + + def check_indirect(self, loaded, orig): + # The module re-uses another's PyModuleDef, with a different name. + assert orig is not loaded.module + assert orig.__name__ != loaded.name + self.assertNotEqual(loaded.module.__name__, loaded.name) + self.assertIs(loaded.snapshot.lookedup, loaded.module) + + def check_basic(self, loaded, expected_init_count): + # m_size == -1 + # The module loads fresh the first time and copies m_copy after. + snap = loaded.snapshot + self.assertIsNot(snap.state_initialized, None) + self.assertIsInstance(snap.init_count, int) + self.assertGreater(snap.init_count, 0) + self.assertEqual(snap.init_count, expected_init_count) + + def check_with_reinit(self, loaded): + # m_size >= 0 + # The module loads fresh every time. + pass + + def check_fresh(self, loaded): + """ + The module had not been loaded before (at least since fully reset). + """ + snap = loaded.snapshot + # The module's init func was run. + # A copy of the module's __dict__ was stored in def->m_base.m_copy. + # The previous m_copy was deleted first. + # _PyRuntime.imports.extensions was set. + self.assertEqual(snap.init_count, 1) + # The global state was initialized. + # The module attrs were initialized from that state. + self.assertEqual(snap.module._module_initialized, + snap.state_initialized) + + def check_semi_fresh(self, loaded, base, prev): + """ + The module had been loaded before and then reset + (but the module global state wasn't). + """ + snap = loaded.snapshot + # The module's init func was run again. + # A copy of the module's __dict__ was stored in def->m_base.m_copy. + # The previous m_copy was deleted first. + # The module globals did not get reset. + self.assertNotEqual(snap.id, base.snapshot.id) + self.assertNotEqual(snap.id, prev.snapshot.id) + self.assertEqual(snap.init_count, prev.snapshot.init_count + 1) + # The global state was updated. + # The module attrs were initialized from that state. + self.assertEqual(snap.module._module_initialized, + snap.state_initialized) + self.assertNotEqual(snap.state_initialized, + base.snapshot.state_initialized) + self.assertNotEqual(snap.state_initialized, + prev.snapshot.state_initialized) + + def check_copied(self, loaded, base): + """ + The module had been loaded before and never reset. + """ + snap = loaded.snapshot + # The module's init func was not run again. + # The interpreter copied m_copy, as set by the other interpreter, + # with objects owned by the other interpreter. + # The module globals did not get reset. + self.assertNotEqual(snap.id, base.snapshot.id) + self.assertEqual(snap.init_count, base.snapshot.init_count) + # The global state was not updated since the init func did not run. + # The module attrs were not directly initialized from that state. + # The state and module attrs still match the previous loading. + self.assertEqual(snap.module._module_initialized, + snap.state_initialized) + self.assertEqual(snap.state_initialized, + base.snapshot.state_initialized) + + ######################### + # the tests + + def test_cleared_globals(self): + loaded = self.load(self.NAME) + _testsinglephase = loaded.module + init_before = _testsinglephase.state_initialized() + + _testsinglephase._clear_globals() + init_after = _testsinglephase.state_initialized() + init_count = _testsinglephase.initialized_count() + + self.assertGreater(init_before, 0) + self.assertEqual(init_after, 0) + self.assertEqual(init_count, -1) + + def test_variants(self): + # Exercise the most meaningful variants described in Python/import.c. + self.maxDiff = None + + # Check the "basic" module. + + name = self.NAME + expected_init_count = 1 + with self.subTest(name): + loaded = self.load(name) + + self.check_common(loaded) + self.check_direct(loaded) + self.check_basic(loaded, expected_init_count) + basic = loaded.module + + # Check its indirect variants. + + name = f'{self.NAME}_basic_wrapper' + self.add_module_cleanup(name) + expected_init_count += 1 + with self.subTest(name): + loaded = self.load(name) + + self.check_common(loaded) + self.check_indirect(loaded, basic) + self.check_basic(loaded, expected_init_count) + + # Currently PyState_AddModule() always replaces the cached module. + self.assertIs(basic.look_up_self(), loaded.module) + self.assertEqual(basic.initialized_count(), expected_init_count) + + # The cached module shouldn't change after this point. + basic_lookedup = loaded.module + + # Check its direct variant. + + name = f'{self.NAME}_basic_copy' + self.add_module_cleanup(name) + expected_init_count += 1 + with self.subTest(name): + loaded = self.load(name) + + self.check_common(loaded) + self.check_direct(loaded) + self.check_basic(loaded, expected_init_count) + + # This should change the cached module for _testsinglephase. + self.assertIs(basic.look_up_self(), basic_lookedup) + self.assertEqual(basic.initialized_count(), expected_init_count) + + # Check the non-basic variant that has no state. + + name = f'{self.NAME}_with_reinit' + self.add_module_cleanup(name) + with self.subTest(name): + loaded = self.load(name) + + self.check_common(loaded) + self.assertIs(loaded.snapshot.state_initialized, None) + self.check_direct(loaded) + self.check_with_reinit(loaded) + + # This should change the cached module for _testsinglephase. + self.assertIs(basic.look_up_self(), basic_lookedup) + self.assertEqual(basic.initialized_count(), expected_init_count) + + # Check the basic variant that has state. + + name = f'{self.NAME}_with_state' + self.add_module_cleanup(name) + with self.subTest(name): + loaded = self.load(name) + self.addCleanup(loaded.module._clear_module_state) + + self.check_common(loaded) + self.assertIsNot(loaded.snapshot.state_initialized, None) + self.check_direct(loaded) + self.check_with_reinit(loaded) + + # This should change the cached module for _testsinglephase. + self.assertIs(basic.look_up_self(), basic_lookedup) + self.assertEqual(basic.initialized_count(), expected_init_count) + + def test_basic_reloaded(self): + # m_copy is copied into the existing module object. + # Global state is not changed. + self.maxDiff = None + + for name in [ + self.NAME, # the "basic" module + f'{self.NAME}_basic_wrapper', # the indirect variant + f'{self.NAME}_basic_copy', # the direct variant + ]: + self.add_module_cleanup(name) + with self.subTest(name): + loaded = self.load(name) + reloaded = self.re_load(name, loaded.module) + + self.check_common(loaded) + self.check_common(reloaded) + + # Make sure the original __dict__ did not get replaced. + self.assertEqual(id(loaded.module.__dict__), + loaded.snapshot.ns_id) + self.assertEqual(loaded.snapshot.ns.__dict__, + loaded.module.__dict__) + + self.assertEqual(reloaded.module.__spec__.name, reloaded.name) + self.assertEqual(reloaded.module.__name__, + reloaded.snapshot.ns.__name__) + + self.assertIs(reloaded.module, loaded.module) + self.assertIs(reloaded.module.__dict__, loaded.module.__dict__) + # It only happens to be the same but that's good enough here. + # We really just want to verify that the re-loaded attrs + # didn't change. + self.assertIs(reloaded.snapshot.lookedup, + loaded.snapshot.lookedup) + self.assertEqual(reloaded.snapshot.state_initialized, + loaded.snapshot.state_initialized) + self.assertEqual(reloaded.snapshot.init_count, + loaded.snapshot.init_count) + + self.assertIs(reloaded.snapshot.cached, reloaded.module) + + def test_with_reinit_reloaded(self): + # The module's m_init func is run again. + self.maxDiff = None + + # Keep a reference around. + basic = self.load(self.NAME) + + for name, has_state in [ + (f'{self.NAME}_with_reinit', False), # m_size == 0 + (f'{self.NAME}_with_state', True), # m_size > 0 + ]: + self.add_module_cleanup(name) + with self.subTest(name=name, has_state=has_state): + loaded = self.load(name) + if has_state: + self.addCleanup(loaded.module._clear_module_state) + + reloaded = self.re_load(name, loaded.module) + if has_state: + self.addCleanup(reloaded.module._clear_module_state) + + self.check_common(loaded) + self.check_common(reloaded) + + # Make sure the original __dict__ did not get replaced. + self.assertEqual(id(loaded.module.__dict__), + loaded.snapshot.ns_id) + self.assertEqual(loaded.snapshot.ns.__dict__, + loaded.module.__dict__) + + self.assertEqual(reloaded.module.__spec__.name, reloaded.name) + self.assertEqual(reloaded.module.__name__, + reloaded.snapshot.ns.__name__) + + self.assertIsNot(reloaded.module, loaded.module) + self.assertNotEqual(reloaded.module.__dict__, + loaded.module.__dict__) + self.assertIs(reloaded.snapshot.lookedup, reloaded.module) + if loaded.snapshot.state_initialized is None: + self.assertIs(reloaded.snapshot.state_initialized, None) + else: + self.assertGreater(reloaded.snapshot.state_initialized, + loaded.snapshot.state_initialized) + + self.assertIs(reloaded.snapshot.cached, reloaded.module) + + # Currently, for every single-phrase init module loaded + # in multiple interpreters, those interpreters share a + # PyModuleDef for that object, which can be a problem. + # Also, we test with a single-phase module that has global state, + # which is shared by all interpreters. + + @requires_subinterpreters + def test_basic_multiple_interpreters_main_no_reset(self): + # without resetting; already loaded in main interpreter + + # At this point: + # * alive in 0 interpreters + # * module def may or may not be loaded already + # * module def not in _PyRuntime.imports.extensions + # * mod init func has not run yet (since reset, at least) + # * m_copy not set (hasn't been loaded yet or already cleared) + # * module's global state has not been initialized yet + # (or already cleared) + + main_loaded = self.load(self.NAME) + _testsinglephase = main_loaded.module + # Attrs set after loading are not in m_copy. + _testsinglephase.spam = 'spam, spam, spam, spam, eggs, and spam' + + self.check_common(main_loaded) + self.check_fresh(main_loaded) + + interpid1 = self.add_subinterpreter() + interpid2 = self.add_subinterpreter() + + # At this point: + # * alive in 1 interpreter (main) + # * module def in _PyRuntime.imports.extensions + # * mod init func ran for the first time (since reset, at least) + # * m_copy was copied from the main interpreter (was NULL) + # * module's global state was initialized + + # Use an interpreter that gets destroyed right away. + loaded = self.import_in_subinterp() + self.check_common(loaded) + self.check_copied(loaded, main_loaded) + + # At this point: + # * alive in 1 interpreter (main) + # * module def still in _PyRuntime.imports.extensions + # * mod init func ran again + # * m_copy is NULL (claered when the interpreter was destroyed) + # (was from main interpreter) + # * module's global state was updated, not reset + + # Use a subinterpreter that sticks around. + loaded = self.import_in_subinterp(interpid1) + self.check_common(loaded) + self.check_copied(loaded, main_loaded) + + # At this point: + # * alive in 2 interpreters (main, interp1) + # * module def still in _PyRuntime.imports.extensions + # * mod init func ran again + # * m_copy was copied from interp1 + # * module's global state was updated, not reset + + # Use a subinterpreter while the previous one is still alive. + loaded = self.import_in_subinterp(interpid2) + self.check_common(loaded) + self.check_copied(loaded, main_loaded) + + # At this point: + # * alive in 3 interpreters (main, interp1, interp2) + # * module def still in _PyRuntime.imports.extensions + # * mod init func ran again + # * m_copy was copied from interp2 (was from interp1) + # * module's global state was updated, not reset + + @no_rerun(reason="rerun not possible; module state is never cleared (see gh-102251)") + @requires_subinterpreters + def test_basic_multiple_interpreters_deleted_no_reset(self): + # without resetting; already loaded in a deleted interpreter + + if hasattr(sys, 'getobjects'): + # It's a Py_TRACE_REFS build. + # This test breaks interpreter isolation a little, + # which causes problems on Py_TRACE_REF builds. + raise unittest.SkipTest('crashes on Py_TRACE_REFS builds') + + # At this point: + # * alive in 0 interpreters + # * module def may or may not be loaded already + # * module def not in _PyRuntime.imports.extensions + # * mod init func has not run yet (since reset, at least) + # * m_copy not set (hasn't been loaded yet or already cleared) + # * module's global state has not been initialized yet + # (or already cleared) + + interpid1 = self.add_subinterpreter() + interpid2 = self.add_subinterpreter() + + # First, load in the main interpreter but then completely clear it. + loaded_main = self.load(self.NAME) + loaded_main.module._clear_globals() + _testinternalcapi.clear_extension(self.NAME, self.FILE) + + # At this point: + # * alive in 0 interpreters + # * module def loaded already + # * module def was in _PyRuntime.imports.extensions, but cleared + # * mod init func ran for the first time (since reset, at least) + # * m_copy was set, but cleared (was NULL) + # * module's global state was initialized but cleared + + # Start with an interpreter that gets destroyed right away. + base = self.import_in_subinterp(postscript=''' + # Attrs set after loading are not in m_copy. + mod.spam = 'spam, spam, mash, spam, eggs, and spam' + ''') + self.check_common(base) + self.check_fresh(base) + + # At this point: + # * alive in 0 interpreters + # * module def in _PyRuntime.imports.extensions + # * mod init func ran again + # * m_copy is NULL (claered when the interpreter was destroyed) + # * module's global state was initialized, not reset + + # Use a subinterpreter that sticks around. + loaded_interp1 = self.import_in_subinterp(interpid1) + self.check_common(loaded_interp1) + self.check_semi_fresh(loaded_interp1, loaded_main, base) + + # At this point: + # * alive in 1 interpreter (interp1) + # * module def still in _PyRuntime.imports.extensions + # * mod init func ran again + # * m_copy was copied from interp1 (was NULL) + # * module's global state was updated, not reset + + # Use a subinterpreter while the previous one is still alive. + loaded_interp2 = self.import_in_subinterp(interpid2) + self.check_common(loaded_interp2) + self.check_copied(loaded_interp2, loaded_interp1) + + # At this point: + # * alive in 2 interpreters (interp1, interp2) + # * module def still in _PyRuntime.imports.extensions + # * mod init func ran again + # * m_copy was copied from interp2 (was from interp1) + # * module's global state was updated, not reset + + @requires_subinterpreters + def test_basic_multiple_interpreters_reset_each(self): + # resetting between each interpreter + + # At this point: + # * alive in 0 interpreters + # * module def may or may not be loaded already + # * module def not in _PyRuntime.imports.extensions + # * mod init func has not run yet (since reset, at least) + # * m_copy not set (hasn't been loaded yet or already cleared) + # * module's global state has not been initialized yet + # (or already cleared) + + interpid1 = self.add_subinterpreter() + interpid2 = self.add_subinterpreter() + + # Use an interpreter that gets destroyed right away. + loaded = self.import_in_subinterp( + postscript=''' + # Attrs set after loading are not in m_copy. + mod.spam = 'spam, spam, mash, spam, eggs, and spam' + ''', + postcleanup=True, + ) + self.check_common(loaded) + self.check_fresh(loaded) + + # At this point: + # * alive in 0 interpreters + # * module def in _PyRuntime.imports.extensions + # * mod init func ran for the first time (since reset, at least) + # * m_copy is NULL (claered when the interpreter was destroyed) + # * module's global state was initialized, not reset + + # Use a subinterpreter that sticks around. + loaded = self.import_in_subinterp(interpid1, postcleanup=True) + self.check_common(loaded) + self.check_fresh(loaded) + + # At this point: + # * alive in 1 interpreter (interp1) + # * module def still in _PyRuntime.imports.extensions + # * mod init func ran again + # * m_copy was copied from interp1 (was NULL) + # * module's global state was initialized, not reset + + # Use a subinterpreter while the previous one is still alive. + loaded = self.import_in_subinterp(interpid2, postcleanup=True) + self.check_common(loaded) + self.check_fresh(loaded) + + # At this point: + # * alive in 2 interpreters (interp2, interp2) + # * module def still in _PyRuntime.imports.extensions + # * mod init func ran again + # * m_copy was copied from interp2 (was from interp1) + # * module's global state was initialized, not reset + + if __name__ == '__main__': # Test needs to be a package, so we can do relative imports. unittest.main() diff --git a/Lib/test/test_importlib/_context.py b/Lib/test/test_importlib/_context.py new file mode 100644 index 00000000..8a53eb55 --- /dev/null +++ b/Lib/test/test_importlib/_context.py @@ -0,0 +1,13 @@ +import contextlib + + +# from jaraco.context 4.3 +class suppress(contextlib.suppress, contextlib.ContextDecorator): + """ + A version of contextlib.suppress with decorator support. + + >>> @suppress(KeyError) + ... def key_error(): + ... {}[''] + >>> key_error() + """ diff --git a/Lib/test/test_importlib/_path.py b/Lib/test/test_importlib/_path.py new file mode 100644 index 00000000..71a70438 --- /dev/null +++ b/Lib/test/test_importlib/_path.py @@ -0,0 +1,109 @@ +# from jaraco.path 3.5 + +import functools +import pathlib +from typing import Dict, Union + +try: + from typing import Protocol, runtime_checkable +except ImportError: # pragma: no cover + # Python 3.7 + from typing_extensions import Protocol, runtime_checkable # type: ignore + + +FilesSpec = Dict[str, Union[str, bytes, 'FilesSpec']] # type: ignore + + +@runtime_checkable +class TreeMaker(Protocol): + def __truediv__(self, *args, **kwargs): + ... # pragma: no cover + + def mkdir(self, **kwargs): + ... # pragma: no cover + + def write_text(self, content, **kwargs): + ... # pragma: no cover + + def write_bytes(self, content): + ... # pragma: no cover + + +def _ensure_tree_maker(obj: Union[str, TreeMaker]) -> TreeMaker: + return obj if isinstance(obj, TreeMaker) else pathlib.Path(obj) # type: ignore + + +def build( + spec: FilesSpec, + prefix: Union[str, TreeMaker] = pathlib.Path(), # type: ignore +): + """ + Build a set of files/directories, as described by the spec. + + Each key represents a pathname, and the value represents + the content. Content may be a nested directory. + + >>> spec = { + ... 'README.txt': "A README file", + ... "foo": { + ... "__init__.py": "", + ... "bar": { + ... "__init__.py": "", + ... }, + ... "baz.py": "# Some code", + ... } + ... } + >>> target = getfixture('tmp_path') + >>> build(spec, target) + >>> target.joinpath('foo/baz.py').read_text(encoding='utf-8') + '# Some code' + """ + for name, contents in spec.items(): + create(contents, _ensure_tree_maker(prefix) / name) + + +@functools.singledispatch +def create(content: Union[str, bytes, FilesSpec], path): + path.mkdir(exist_ok=True) + build(content, prefix=path) # type: ignore + + +@create.register +def _(content: bytes, path): + path.write_bytes(content) + + +@create.register +def _(content: str, path): + path.write_text(content, encoding='utf-8') + + +@create.register +def _(content: str, path): + path.write_text(content, encoding='utf-8') + + +class Recording: + """ + A TreeMaker object that records everything that would be written. + + >>> r = Recording() + >>> build({'foo': {'foo1.txt': 'yes'}, 'bar.txt': 'abc'}, r) + >>> r.record + ['foo/foo1.txt', 'bar.txt'] + """ + + def __init__(self, loc=pathlib.PurePosixPath(), record=None): + self.loc = loc + self.record = record if record is not None else [] + + def __truediv__(self, other): + return Recording(self.loc / other, self.record) + + def write_text(self, content, **kwargs): + self.record.append(str(self.loc)) + + write_bytes = write_text + + def mkdir(self, **kwargs): + return diff --git a/Lib/test/test_importlib/builtin/test_finder.py b/Lib/test/test_importlib/builtin/test_finder.py index a4869e07..111c4af1 100644 --- a/Lib/test/test_importlib/builtin/test_finder.py +++ b/Lib/test/test_importlib/builtin/test_finder.py @@ -37,61 +37,11 @@ class FindSpecTests(abc.FinderTests): spec = self.machinery.BuiltinImporter.find_spec(name) self.assertIsNone(spec) - def test_ignore_path(self): - # The value for 'path' should always trigger a failed import. - with util.uncache(util.BUILTINS.good_name): - spec = self.machinery.BuiltinImporter.find_spec(util.BUILTINS.good_name, - ['pkg']) - self.assertIsNone(spec) - (Frozen_FindSpecTests, Source_FindSpecTests ) = util.test_both(FindSpecTests, machinery=machinery) -@unittest.skipIf(util.BUILTINS.good_name is None, 'no reasonable builtin module') -class FinderTests(abc.FinderTests): - - """Test find_module() for built-in modules.""" - - def test_module(self): - # Common case. - with util.uncache(util.BUILTINS.good_name): - with warnings.catch_warnings(): - warnings.simplefilter("ignore", DeprecationWarning) - found = self.machinery.BuiltinImporter.find_module(util.BUILTINS.good_name) - self.assertTrue(found) - self.assertTrue(hasattr(found, 'load_module')) - - # Built-in modules cannot be a package. - test_package = test_package_in_package = test_package_over_module = None - - # Built-in modules cannot be in a package. - test_module_in_package = None - - def test_failure(self): - assert 'importlib' not in sys.builtin_module_names - with warnings.catch_warnings(): - warnings.simplefilter("ignore", DeprecationWarning) - loader = self.machinery.BuiltinImporter.find_module('importlib') - self.assertIsNone(loader) - - def test_ignore_path(self): - # The value for 'path' should always trigger a failed import. - with util.uncache(util.BUILTINS.good_name): - with warnings.catch_warnings(): - warnings.simplefilter("ignore", DeprecationWarning) - loader = self.machinery.BuiltinImporter.find_module( - util.BUILTINS.good_name, - ['pkg']) - self.assertIsNone(loader) - - -(Frozen_FinderTests, - Source_FinderTests - ) = util.test_both(FinderTests, machinery=machinery) - - if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_importlib/extension/test_case_sensitivity.py b/Lib/test/test_importlib/extension/test_case_sensitivity.py index 366e565c..0bb74fff 100644 --- a/Lib/test/test_importlib/extension/test_case_sensitivity.py +++ b/Lib/test/test_importlib/extension/test_case_sensitivity.py @@ -8,7 +8,7 @@ importlib = util.import_importlib('importlib') machinery = util.import_importlib('importlib.machinery') -@unittest.skipIf(util.EXTENSIONS.filename is None, '_testcapi not available') +@unittest.skipIf(util.EXTENSIONS.filename is None, f'{util.EXTENSIONS.name} not available') @util.case_insensitive_tests class ExtensionModuleCaseSensitivityTest(util.CASEOKTestBase): diff --git a/Lib/test/test_importlib/extension/test_loader.py b/Lib/test/test_importlib/extension/test_loader.py index 8570c6bc..a7c62458 100644 --- a/Lib/test/test_importlib/extension/test_loader.py +++ b/Lib/test/test_importlib/extension/test_loader.py @@ -13,9 +13,9 @@ import importlib from test.support.script_helper import assert_python_failure -class LoaderTests(abc.LoaderTests): +class LoaderTests: - """Test load_module() for extension modules.""" + """Test ExtensionFileLoader.""" def setUp(self): if not self.machinery.EXTENSION_SUFFIXES: @@ -32,15 +32,6 @@ class LoaderTests(abc.LoaderTests): warnings.simplefilter("ignore", DeprecationWarning) return self.loader.load_module(fullname) - def test_load_module_API(self): - # Test the default argument for load_module(). - with warnings.catch_warnings(): - warnings.simplefilter("ignore", DeprecationWarning) - self.loader.load_module() - self.loader.load_module(None) - with self.assertRaises(ImportError): - self.load_module('XXX') - def test_equality(self): other = self.machinery.ExtensionFileLoader(util.EXTENSIONS.name, util.EXTENSIONS.file_path) @@ -51,6 +42,15 @@ class LoaderTests(abc.LoaderTests): util.EXTENSIONS.file_path) self.assertNotEqual(self.loader, other) + def test_load_module_API(self): + # Test the default argument for load_module(). + with warnings.catch_warnings(): + warnings.simplefilter("ignore", DeprecationWarning) + self.loader.load_module() + self.loader.load_module(None) + with self.assertRaises(ImportError): + self.load_module('XXX') + def test_module(self): with util.uncache(util.EXTENSIONS.name): module = self.load_module(util.EXTENSIONS.name) @@ -68,12 +68,6 @@ class LoaderTests(abc.LoaderTests): # No extension module in a package available for testing. test_lacking_parent = None - def test_module_reuse(self): - with util.uncache(util.EXTENSIONS.name): - module1 = self.load_module(util.EXTENSIONS.name) - module2 = self.load_module(util.EXTENSIONS.name) - self.assertIs(module1, module2) - # No easy way to trigger a failure after a successful import. test_state_after_failure = None @@ -83,6 +77,12 @@ class LoaderTests(abc.LoaderTests): self.load_module(name) self.assertEqual(cm.exception.name, name) + def test_module_reuse(self): + with util.uncache(util.EXTENSIONS.name): + module1 = self.load_module(util.EXTENSIONS.name) + module2 = self.load_module(util.EXTENSIONS.name) + self.assertIs(module1, module2) + def test_is_package(self): self.assertFalse(self.loader.is_package(util.EXTENSIONS.name)) for suffix in self.machinery.EXTENSION_SUFFIXES: @@ -90,10 +90,93 @@ class LoaderTests(abc.LoaderTests): loader = self.machinery.ExtensionFileLoader('pkg', path) self.assertTrue(loader.is_package('pkg')) + (Frozen_LoaderTests, Source_LoaderTests ) = util.test_both(LoaderTests, machinery=machinery) + +class SinglePhaseExtensionModuleTests(abc.LoaderTests): + # Test loading extension modules without multi-phase initialization. + + def setUp(self): + if not self.machinery.EXTENSION_SUFFIXES: + raise unittest.SkipTest("Requires dynamic loading support.") + self.name = '_testsinglephase' + if self.name in sys.builtin_module_names: + raise unittest.SkipTest( + f"{self.name} is a builtin module" + ) + finder = self.machinery.FileFinder(None) + self.spec = importlib.util.find_spec(self.name) + assert self.spec + self.loader = self.machinery.ExtensionFileLoader( + self.name, self.spec.origin) + + def load_module(self): + with warnings.catch_warnings(): + warnings.simplefilter("ignore", DeprecationWarning) + return self.loader.load_module(self.name) + + def load_module_by_name(self, fullname): + # Load a module from the test extension by name. + origin = self.spec.origin + loader = self.machinery.ExtensionFileLoader(fullname, origin) + spec = importlib.util.spec_from_loader(fullname, loader) + module = importlib.util.module_from_spec(spec) + loader.exec_module(module) + return module + + def test_module(self): + # Test loading an extension module. + with util.uncache(self.name): + module = self.load_module() + for attr, value in [('__name__', self.name), + ('__file__', self.spec.origin), + ('__package__', '')]: + self.assertEqual(getattr(module, attr), value) + with self.assertRaises(AttributeError): + module.__path__ + self.assertIs(module, sys.modules[self.name]) + self.assertIsInstance(module.__loader__, + self.machinery.ExtensionFileLoader) + + # No extension module as __init__ available for testing. + test_package = None + + # No extension module in a package available for testing. + test_lacking_parent = None + + # No easy way to trigger a failure after a successful import. + test_state_after_failure = None + + def test_unloadable(self): + name = 'asdfjkl;' + with self.assertRaises(ImportError) as cm: + self.load_module_by_name(name) + self.assertEqual(cm.exception.name, name) + + def test_unloadable_nonascii(self): + # Test behavior with nonexistent module with non-ASCII name. + name = 'fo\xf3' + with self.assertRaises(ImportError) as cm: + self.load_module_by_name(name) + self.assertEqual(cm.exception.name, name) + + # It may make sense to add the equivalent to + # the following MultiPhaseExtensionModuleTests tests: + # + # * test_nonmodule + # * test_nonmodule_with_methods + # * test_bad_modules + # * test_nonascii + + +(Frozen_SinglePhaseExtensionModuleTests, + Source_SinglePhaseExtensionModuleTests + ) = util.test_both(SinglePhaseExtensionModuleTests, machinery=machinery) + + class MultiPhaseExtensionModuleTests(abc.LoaderTests): # Test loading extension modules with multi-phase initialization (PEP 489). @@ -179,15 +262,16 @@ class MultiPhaseExtensionModuleTests(abc.LoaderTests): def test_try_registration(self): # Assert that the PyState_{Find,Add,Remove}Module C API doesn't work. - module = self.load_module() - with self.subTest('PyState_FindModule'): - self.assertEqual(module.call_state_registration_func(0), None) - with self.subTest('PyState_AddModule'): - with self.assertRaises(SystemError): - module.call_state_registration_func(1) - with self.subTest('PyState_RemoveModule'): - with self.assertRaises(SystemError): - module.call_state_registration_func(2) + with util.uncache(self.name): + module = self.load_module() + with self.subTest('PyState_FindModule'): + self.assertEqual(module.call_state_registration_func(0), None) + with self.subTest('PyState_AddModule'): + with self.assertRaises(SystemError): + module.call_state_registration_func(1) + with self.subTest('PyState_RemoveModule'): + with self.assertRaises(SystemError): + module.call_state_registration_func(2) def test_load_submodule(self): # Test loading a simulated submodule. @@ -265,12 +349,19 @@ class MultiPhaseExtensionModuleTests(abc.LoaderTests): 'exec_err', 'exec_raise', 'exec_unreported_exception', + 'multiple_create_slots', + 'multiple_multiple_interpreters_slots', ]: with self.subTest(name_base): name = self.name + '_' + name_base - with self.assertRaises(SystemError): + with self.assertRaises(SystemError) as cm: self.load_module_by_name(name) + # If there is an unreported exception, it should be chained + # with the `SystemError`. + if "unreported_exception" in name_base: + self.assertIsNotNone(cm.exception.__cause__) + def test_nonascii(self): # Test that modules with non-ASCII names can be loaded. # punycode behaves slightly differently in some-ASCII and no-ASCII diff --git a/Lib/test/test_importlib/extension/test_path_hook.py b/Lib/test/test_importlib/extension/test_path_hook.py index a0adc70a..ec9644dc 100644 --- a/Lib/test/test_importlib/extension/test_path_hook.py +++ b/Lib/test/test_importlib/extension/test_path_hook.py @@ -19,7 +19,7 @@ class PathHookTests: def test_success(self): # Path hook should handle a directory where a known extension module # exists. - self.assertTrue(hasattr(self.hook(util.EXTENSIONS.path), 'find_module')) + self.assertTrue(hasattr(self.hook(util.EXTENSIONS.path), 'find_spec')) (Frozen_PathHooksTests, diff --git a/Lib/test/test_importlib/fixtures.py b/Lib/test/test_importlib/fixtures.py index e7be77b3..73e5da2b 100644 --- a/Lib/test/test_importlib/fixtures.py +++ b/Lib/test/test_importlib/fixtures.py @@ -10,7 +10,10 @@ import contextlib from test.support.os_helper import FS_NONASCII from test.support import requires_zlib -from typing import Dict, Union + +from . import _path +from ._path import FilesSpec + try: from importlib import resources # type: ignore @@ -83,13 +86,8 @@ class OnSysPath(Fixtures): self.fixtures.enter_context(self.add_sys_path(self.site_dir)) -# Except for python/mypy#731, prefer to define -# FilesDef = Dict[str, Union['FilesDef', str]] -FilesDef = Dict[str, Union[Dict[str, Union[Dict[str, str], str]], str]] - - class DistInfoPkg(OnSysPath, SiteDir): - files: FilesDef = { + files: FilesSpec = { "distinfo_pkg-1.0.0.dist-info": { "METADATA": """ Name: distinfo-pkg @@ -131,7 +129,7 @@ class DistInfoPkg(OnSysPath, SiteDir): class DistInfoPkgWithDot(OnSysPath, SiteDir): - files: FilesDef = { + files: FilesSpec = { "pkg_dot-1.0.0.dist-info": { "METADATA": """ Name: pkg.dot @@ -146,7 +144,7 @@ class DistInfoPkgWithDot(OnSysPath, SiteDir): class DistInfoPkgWithDotLegacy(OnSysPath, SiteDir): - files: FilesDef = { + files: FilesSpec = { "pkg.dot-1.0.0.dist-info": { "METADATA": """ Name: pkg.dot @@ -173,7 +171,7 @@ class DistInfoPkgOffPath(SiteDir): class EggInfoPkg(OnSysPath, SiteDir): - files: FilesDef = { + files: FilesSpec = { "egginfo_pkg.egg-info": { "PKG-INFO": """ Name: egginfo-pkg @@ -212,8 +210,99 @@ class EggInfoPkg(OnSysPath, SiteDir): build_files(EggInfoPkg.files, prefix=self.site_dir) +class EggInfoPkgPipInstalledNoToplevel(OnSysPath, SiteDir): + files: FilesSpec = { + "egg_with_module_pkg.egg-info": { + "PKG-INFO": "Name: egg_with_module-pkg", + # SOURCES.txt is made from the source archive, and contains files + # (setup.py) that are not present after installation. + "SOURCES.txt": """ + egg_with_module.py + setup.py + egg_with_module_pkg.egg-info/PKG-INFO + egg_with_module_pkg.egg-info/SOURCES.txt + egg_with_module_pkg.egg-info/top_level.txt + """, + # installed-files.txt is written by pip, and is a strictly more + # accurate source than SOURCES.txt as to the installed contents of + # the package. + "installed-files.txt": """ + ../egg_with_module.py + PKG-INFO + SOURCES.txt + top_level.txt + """, + # missing top_level.txt (to trigger fallback to installed-files.txt) + }, + "egg_with_module.py": """ + def main(): + print("hello world") + """, + } + + def setUp(self): + super().setUp() + build_files(EggInfoPkgPipInstalledNoToplevel.files, prefix=self.site_dir) + + +class EggInfoPkgPipInstalledNoModules(OnSysPath, SiteDir): + files: FilesSpec = { + "egg_with_no_modules_pkg.egg-info": { + "PKG-INFO": "Name: egg_with_no_modules-pkg", + # SOURCES.txt is made from the source archive, and contains files + # (setup.py) that are not present after installation. + "SOURCES.txt": """ + setup.py + egg_with_no_modules_pkg.egg-info/PKG-INFO + egg_with_no_modules_pkg.egg-info/SOURCES.txt + egg_with_no_modules_pkg.egg-info/top_level.txt + """, + # installed-files.txt is written by pip, and is a strictly more + # accurate source than SOURCES.txt as to the installed contents of + # the package. + "installed-files.txt": """ + PKG-INFO + SOURCES.txt + top_level.txt + """, + # top_level.txt correctly reflects that no modules are installed + "top_level.txt": b"\n", + }, + } + + def setUp(self): + super().setUp() + build_files(EggInfoPkgPipInstalledNoModules.files, prefix=self.site_dir) + + +class EggInfoPkgSourcesFallback(OnSysPath, SiteDir): + files: FilesSpec = { + "sources_fallback_pkg.egg-info": { + "PKG-INFO": "Name: sources_fallback-pkg", + # SOURCES.txt is made from the source archive, and contains files + # (setup.py) that are not present after installation. + "SOURCES.txt": """ + sources_fallback.py + setup.py + sources_fallback_pkg.egg-info/PKG-INFO + sources_fallback_pkg.egg-info/SOURCES.txt + """, + # missing installed-files.txt (i.e. not installed by pip) and + # missing top_level.txt (to trigger fallback to SOURCES.txt) + }, + "sources_fallback.py": """ + def main(): + print("hello world") + """, + } + + def setUp(self): + super().setUp() + build_files(EggInfoPkgSourcesFallback.files, prefix=self.site_dir) + + class EggInfoFile(OnSysPath, SiteDir): - files: FilesDef = { + files: FilesSpec = { "egginfo_file.egg-info": """ Metadata-Version: 1.0 Name: egginfo_file @@ -233,38 +322,22 @@ class EggInfoFile(OnSysPath, SiteDir): build_files(EggInfoFile.files, prefix=self.site_dir) -def build_files(file_defs, prefix=pathlib.Path()): - """Build a set of files/directories, as described by the +# dedent all text strings before writing +orig = _path.create.registry[str] +_path.create.register(str, lambda content, path: orig(DALS(content), path)) - file_defs dictionary. Each key/value pair in the dictionary is - interpreted as a filename/contents pair. If the contents value is a - dictionary, a directory is created, and the dictionary interpreted - as the files within it, recursively. - For example: +build_files = _path.build - {"README.txt": "A README file", - "foo": { - "__init__.py": "", - "bar": { - "__init__.py": "", - }, - "baz.py": "# Some code", - } - } - """ - for name, contents in file_defs.items(): - full_name = prefix / name - if isinstance(contents, dict): - full_name.mkdir() - build_files(contents, prefix=full_name) - else: - if isinstance(contents, bytes): - with full_name.open('wb') as f: - f.write(contents) - else: - with full_name.open('w', encoding='utf-8') as f: - f.write(DALS(contents)) + +def build_record(file_defs): + return ''.join(f'{name},,\n' for name in record_names(file_defs)) + + +def record_names(file_defs): + recording = _path.Recording() + _path.build(file_defs, recording) + return recording.record class FileBuilder: @@ -277,11 +350,6 @@ def DALS(str): return textwrap.dedent(str).lstrip() -class NullFinder: - def find_module(self, name): - pass - - @requires_zlib() class ZipFixtures: root = 'test.test_importlib.data' diff --git a/Lib/test/test_importlib/frozen/test_finder.py b/Lib/test/test_importlib/frozen/test_finder.py index 06975560..469dcdbd 100644 --- a/Lib/test/test_importlib/frozen/test_finder.py +++ b/Lib/test/test_importlib/frozen/test_finder.py @@ -182,45 +182,5 @@ class FindSpecTests(abc.FinderTests): ) = util.test_both(FindSpecTests, machinery=machinery) -class FinderTests(abc.FinderTests): - - """Test finding frozen modules.""" - - def find(self, name, path=None): - finder = self.machinery.FrozenImporter - with warnings.catch_warnings(): - warnings.simplefilter("ignore", DeprecationWarning) - with import_helper.frozen_modules(): - return finder.find_module(name, path) - - def test_module(self): - name = '__hello__' - loader = self.find(name) - self.assertTrue(hasattr(loader, 'load_module')) - - def test_package(self): - loader = self.find('__phello__') - self.assertTrue(hasattr(loader, 'load_module')) - - def test_module_in_package(self): - loader = self.find('__phello__.spam', ['__phello__']) - self.assertTrue(hasattr(loader, 'load_module')) - - # No frozen package within another package to test with. - test_package_in_package = None - - # No easy way to test. - test_package_over_module = None - - def test_failure(self): - loader = self.find('<not real>') - self.assertIsNone(loader) - - -(Frozen_FinderTests, - Source_FinderTests - ) = util.test_both(FinderTests, machinery=machinery) - - if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_importlib/frozen/test_loader.py b/Lib/test/test_importlib/frozen/test_loader.py index f2df7e60..4f1af454 100644 --- a/Lib/test/test_importlib/frozen/test_loader.py +++ b/Lib/test/test_importlib/frozen/test_loader.py @@ -103,15 +103,7 @@ class ExecModuleTests(abc.LoaderTests): expected=value)) self.assertEqual(output, 'Hello world!\n') - def test_module_repr(self): - name = '__hello__' - module, output = self.exec_module(name) - with deprecated(): - repr_str = self.machinery.FrozenImporter.module_repr(module) - self.assertEqual(repr_str, - "<module '__hello__' (frozen)>") - - def test_module_repr_indirect(self): + def test_module_repr_indirect_through_spec(self): name = '__hello__' module, output = self.exec_module(name) self.assertEqual(repr(module), @@ -133,95 +125,6 @@ class ExecModuleTests(abc.LoaderTests): ) = util.test_both(ExecModuleTests, machinery=machinery) -class LoaderTests(abc.LoaderTests): - - def load_module(self, name): - with fresh(name, oldapi=True): - module = self.machinery.FrozenImporter.load_module(name) - with captured_stdout() as stdout: - module.main() - return module, stdout - - def test_module(self): - module, stdout = self.load_module('__hello__') - filename = resolve_stdlib_file('__hello__') - check = {'__name__': '__hello__', - '__package__': '', - '__loader__': self.machinery.FrozenImporter, - '__file__': filename, - } - for attr, value in check.items(): - self.assertEqual(getattr(module, attr, None), value) - self.assertEqual(stdout.getvalue(), 'Hello world!\n') - - def test_package(self): - module, stdout = self.load_module('__phello__') - filename = resolve_stdlib_file('__phello__', ispkg=True) - pkgdir = os.path.dirname(filename) - check = {'__name__': '__phello__', - '__package__': '__phello__', - '__path__': [pkgdir], - '__loader__': self.machinery.FrozenImporter, - '__file__': filename, - } - for attr, value in check.items(): - attr_value = getattr(module, attr, None) - self.assertEqual(attr_value, value, - "for __phello__.%s, %r != %r" % - (attr, attr_value, value)) - self.assertEqual(stdout.getvalue(), 'Hello world!\n') - - def test_lacking_parent(self): - with util.uncache('__phello__'): - module, stdout = self.load_module('__phello__.spam') - filename = resolve_stdlib_file('__phello__.spam') - check = {'__name__': '__phello__.spam', - '__package__': '__phello__', - '__loader__': self.machinery.FrozenImporter, - '__file__': filename, - } - for attr, value in check.items(): - attr_value = getattr(module, attr) - self.assertEqual(attr_value, value, - "for __phello__.spam.%s, %r != %r" % - (attr, attr_value, value)) - self.assertEqual(stdout.getvalue(), 'Hello world!\n') - - def test_module_reuse(self): - with fresh('__hello__', oldapi=True): - module1 = self.machinery.FrozenImporter.load_module('__hello__') - module2 = self.machinery.FrozenImporter.load_module('__hello__') - with captured_stdout() as stdout: - module1.main() - module2.main() - self.assertIs(module1, module2) - self.assertEqual(stdout.getvalue(), - 'Hello world!\nHello world!\n') - - def test_module_repr(self): - with fresh('__hello__', oldapi=True): - module = self.machinery.FrozenImporter.load_module('__hello__') - repr_str = self.machinery.FrozenImporter.module_repr(module) - self.assertEqual(repr_str, - "<module '__hello__' (frozen)>") - - # No way to trigger an error in a frozen module. - test_state_after_failure = None - - def test_unloadable(self): - with import_helper.frozen_modules(): - with deprecated(): - assert self.machinery.FrozenImporter.find_module('_not_real') is None - with self.assertRaises(ImportError) as cm: - self.load_module('_not_real') - self.assertEqual(cm.exception.name, '_not_real') - - -(Frozen_LoaderTests, - Source_LoaderTests - ) = util.test_both(LoaderTests, machinery=machinery) - - class InspectLoaderTests: """Tests for the InspectLoader methods for FrozenImporter.""" diff --git a/Lib/test/test_importlib/import_/test___loader__.py b/Lib/test/test_importlib/import_/test___loader__.py index eaf665a6..a1416391 100644 --- a/Lib/test/test_importlib/import_/test___loader__.py +++ b/Lib/test/test_importlib/import_/test___loader__.py @@ -33,48 +33,5 @@ class SpecLoaderAttributeTests: ) = util.test_both(SpecLoaderAttributeTests, __import__=util.__import__) -class LoaderMock: - - def find_module(self, fullname, path=None): - return self - - def load_module(self, fullname): - sys.modules[fullname] = self.module - return self.module - - -class LoaderAttributeTests: - - def test___loader___missing(self): - with warnings.catch_warnings(): - warnings.simplefilter("ignore", ImportWarning) - module = types.ModuleType('blah') - try: - del module.__loader__ - except AttributeError: - pass - loader = LoaderMock() - loader.module = module - with util.uncache('blah'), util.import_state(meta_path=[loader]): - module = self.__import__('blah') - self.assertEqual(loader, module.__loader__) - - def test___loader___is_None(self): - with warnings.catch_warnings(): - warnings.simplefilter("ignore", ImportWarning) - module = types.ModuleType('blah') - module.__loader__ = None - loader = LoaderMock() - loader.module = module - with util.uncache('blah'), util.import_state(meta_path=[loader]): - returned_module = self.__import__('blah') - self.assertEqual(loader, module.__loader__) - - -(Frozen_Tests, - Source_Tests - ) = util.test_both(LoaderAttributeTests, __import__=util.__import__) - - if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_importlib/import_/test___package__.py b/Lib/test/test_importlib/import_/test___package__.py index 1ab5018a..7130c99a 100644 --- a/Lib/test/test_importlib/import_/test___package__.py +++ b/Lib/test/test_importlib/import_/test___package__.py @@ -74,8 +74,8 @@ class Using__package__: self.assertEqual(module.__name__, 'pkg') def test_warn_when_package_and_spec_disagree(self): - # Raise an ImportWarning if __package__ != __spec__.parent. - with self.assertWarns(ImportWarning): + # Raise a DeprecationWarning if __package__ != __spec__.parent. + with self.assertWarns(DeprecationWarning): self.import_module({'__package__': 'pkg.fake', '__spec__': FakeSpec('pkg.fakefake')}) @@ -95,25 +95,6 @@ class FakeSpec: self.parent = parent -class Using__package__PEP302(Using__package__): - mock_modules = util.mock_modules - - def test_using___package__(self): - with warnings.catch_warnings(): - warnings.simplefilter("ignore", ImportWarning) - super().test_using___package__() - - def test_spec_fallback(self): - with warnings.catch_warnings(): - warnings.simplefilter("ignore", ImportWarning) - super().test_spec_fallback() - - -(Frozen_UsingPackagePEP302, - Source_UsingPackagePEP302 - ) = util.test_both(Using__package__PEP302, __import__=util.__import__) - - class Using__package__PEP451(Using__package__): mock_modules = util.mock_spec @@ -162,23 +143,6 @@ class Setting__package__: module = getattr(pkg, 'mod') self.assertEqual(module.__package__, 'pkg') -class Setting__package__PEP302(Setting__package__, unittest.TestCase): - mock_modules = util.mock_modules - - def test_top_level(self): - with warnings.catch_warnings(): - warnings.simplefilter("ignore", ImportWarning) - super().test_top_level() - - def test_package(self): - with warnings.catch_warnings(): - warnings.simplefilter("ignore", ImportWarning) - super().test_package() - - def test_submodule(self): - with warnings.catch_warnings(): - warnings.simplefilter("ignore", ImportWarning) - super().test_submodule() class Setting__package__PEP451(Setting__package__, unittest.TestCase): mock_modules = util.mock_spec diff --git a/Lib/test/test_importlib/import_/test_api.py b/Lib/test/test_importlib/import_/test_api.py index 0ee032b0..d6ad590b 100644 --- a/Lib/test/test_importlib/import_/test_api.py +++ b/Lib/test/test_importlib/import_/test_api.py @@ -28,11 +28,6 @@ class BadSpecFinderLoader: class BadLoaderFinder: - @classmethod - def find_module(cls, fullname, path): - if fullname == SUBMOD_NAME: - return cls - @classmethod def load_module(cls, fullname): if fullname == SUBMOD_NAME: diff --git a/Lib/test/test_importlib/import_/test_caching.py b/Lib/test/test_importlib/import_/test_caching.py index 3ca765fb..aedf0fd4 100644 --- a/Lib/test/test_importlib/import_/test_caching.py +++ b/Lib/test/test_importlib/import_/test_caching.py @@ -52,12 +52,11 @@ class ImportlibUseCache(UseCache, unittest.TestCase): __import__ = util.__import__['Source'] def create_mock(self, *names, return_=None): - mock = util.mock_modules(*names) - original_load = mock.load_module - def load_module(self, fullname): - original_load(fullname) - return return_ - mock.load_module = MethodType(load_module, mock) + mock = util.mock_spec(*names) + original_spec = mock.find_spec + def find_spec(self, fullname, path, target=None): + return original_spec(fullname) + mock.find_spec = MethodType(find_spec, mock) return mock # __import__ inconsistent between loaders and built-in import when it comes @@ -86,14 +85,12 @@ class ImportlibUseCache(UseCache, unittest.TestCase): # See test_using_cache_after_loader() for reasoning. def test_using_cache_for_fromlist(self): # [from cache for fromlist] - with warnings.catch_warnings(): - warnings.simplefilter("ignore", ImportWarning) - with self.create_mock('pkg.__init__', 'pkg.module') as importer: - with util.import_state(meta_path=[importer]): - module = self.__import__('pkg', fromlist=['module']) - self.assertTrue(hasattr(module, 'module')) - self.assertEqual(id(module.module), - id(sys.modules['pkg.module'])) + with self.create_mock('pkg.__init__', 'pkg.module') as importer: + with util.import_state(meta_path=[importer]): + module = self.__import__('pkg', fromlist=['module']) + self.assertTrue(hasattr(module, 'module')) + self.assertEqual(id(module.module), + id(sys.modules['pkg.module'])) if __name__ == '__main__': diff --git a/Lib/test/test_importlib/import_/test_helpers.py b/Lib/test/test_importlib/import_/test_helpers.py new file mode 100644 index 00000000..550f88d1 --- /dev/null +++ b/Lib/test/test_importlib/import_/test_helpers.py @@ -0,0 +1,184 @@ +"""Tests for helper functions used by import.c .""" + +from importlib import _bootstrap_external, machinery +import os.path +from types import ModuleType, SimpleNamespace +import unittest +import warnings + +from .. import util + + +class FixUpModuleTests: + + def test_no_loader_but_spec(self): + loader = object() + name = "hello" + path = "hello.py" + spec = machinery.ModuleSpec(name, loader) + ns = {"__spec__": spec} + _bootstrap_external._fix_up_module(ns, name, path) + + expected = {"__spec__": spec, "__loader__": loader, "__file__": path, + "__cached__": None} + self.assertEqual(ns, expected) + + def test_no_loader_no_spec_but_sourceless(self): + name = "hello" + path = "hello.py" + ns = {} + _bootstrap_external._fix_up_module(ns, name, path, path) + + expected = {"__file__": path, "__cached__": path} + + for key, val in expected.items(): + with self.subTest(f"{key}: {val}"): + self.assertEqual(ns[key], val) + + spec = ns["__spec__"] + self.assertIsInstance(spec, machinery.ModuleSpec) + self.assertEqual(spec.name, name) + self.assertEqual(spec.origin, os.path.abspath(path)) + self.assertEqual(spec.cached, os.path.abspath(path)) + self.assertIsInstance(spec.loader, machinery.SourcelessFileLoader) + self.assertEqual(spec.loader.name, name) + self.assertEqual(spec.loader.path, path) + self.assertEqual(spec.loader, ns["__loader__"]) + + def test_no_loader_no_spec_but_source(self): + name = "hello" + path = "hello.py" + ns = {} + _bootstrap_external._fix_up_module(ns, name, path) + + expected = {"__file__": path, "__cached__": None} + + for key, val in expected.items(): + with self.subTest(f"{key}: {val}"): + self.assertEqual(ns[key], val) + + spec = ns["__spec__"] + self.assertIsInstance(spec, machinery.ModuleSpec) + self.assertEqual(spec.name, name) + self.assertEqual(spec.origin, os.path.abspath(path)) + self.assertIsInstance(spec.loader, machinery.SourceFileLoader) + self.assertEqual(spec.loader.name, name) + self.assertEqual(spec.loader.path, path) + self.assertEqual(spec.loader, ns["__loader__"]) + + +FrozenFixUpModuleTests, SourceFixUpModuleTests = util.test_both(FixUpModuleTests) + + +class TestBlessMyLoader(unittest.TestCase): + # GH#86298 is part of the migration away from module attributes and toward + # __spec__ attributes. There are several cases to test here. This will + # have to change in Python 3.14 when we actually remove/ignore __loader__ + # in favor of requiring __spec__.loader. + + def test_gh86298_no_loader_and_no_spec(self): + bar = ModuleType('bar') + del bar.__loader__ + del bar.__spec__ + # 2022-10-06(warsaw): For backward compatibility with the + # implementation in _warnings.c, this can't raise an + # AttributeError. See _bless_my_loader() in _bootstrap_external.py + # If working with a module: + ## self.assertRaises( + ## AttributeError, _bootstrap_external._bless_my_loader, + ## bar.__dict__) + self.assertIsNone(_bootstrap_external._bless_my_loader(bar.__dict__)) + + def test_gh86298_loader_is_none_and_no_spec(self): + bar = ModuleType('bar') + bar.__loader__ = None + del bar.__spec__ + # 2022-10-06(warsaw): For backward compatibility with the + # implementation in _warnings.c, this can't raise an + # AttributeError. See _bless_my_loader() in _bootstrap_external.py + # If working with a module: + ## self.assertRaises( + ## AttributeError, _bootstrap_external._bless_my_loader, + ## bar.__dict__) + self.assertIsNone(_bootstrap_external._bless_my_loader(bar.__dict__)) + + def test_gh86298_no_loader_and_spec_is_none(self): + bar = ModuleType('bar') + del bar.__loader__ + bar.__spec__ = None + self.assertRaises( + ValueError, + _bootstrap_external._bless_my_loader, bar.__dict__) + + def test_gh86298_loader_is_none_and_spec_is_none(self): + bar = ModuleType('bar') + bar.__loader__ = None + bar.__spec__ = None + self.assertRaises( + ValueError, + _bootstrap_external._bless_my_loader, bar.__dict__) + + def test_gh86298_loader_is_none_and_spec_loader_is_none(self): + bar = ModuleType('bar') + bar.__loader__ = None + bar.__spec__ = SimpleNamespace(loader=None) + self.assertRaises( + ValueError, + _bootstrap_external._bless_my_loader, bar.__dict__) + + def test_gh86298_no_spec(self): + bar = ModuleType('bar') + bar.__loader__ = object() + del bar.__spec__ + with warnings.catch_warnings(): + self.assertWarns( + DeprecationWarning, + _bootstrap_external._bless_my_loader, bar.__dict__) + + def test_gh86298_spec_is_none(self): + bar = ModuleType('bar') + bar.__loader__ = object() + bar.__spec__ = None + with warnings.catch_warnings(): + self.assertWarns( + DeprecationWarning, + _bootstrap_external._bless_my_loader, bar.__dict__) + + def test_gh86298_no_spec_loader(self): + bar = ModuleType('bar') + bar.__loader__ = object() + bar.__spec__ = SimpleNamespace() + with warnings.catch_warnings(): + self.assertWarns( + DeprecationWarning, + _bootstrap_external._bless_my_loader, bar.__dict__) + + def test_gh86298_loader_and_spec_loader_disagree(self): + bar = ModuleType('bar') + bar.__loader__ = object() + bar.__spec__ = SimpleNamespace(loader=object()) + with warnings.catch_warnings(): + self.assertWarns( + DeprecationWarning, + _bootstrap_external._bless_my_loader, bar.__dict__) + + def test_gh86298_no_loader_and_no_spec_loader(self): + bar = ModuleType('bar') + del bar.__loader__ + bar.__spec__ = SimpleNamespace() + self.assertRaises( + AttributeError, + _bootstrap_external._bless_my_loader, bar.__dict__) + + def test_gh86298_no_loader_with_spec_loader_okay(self): + bar = ModuleType('bar') + del bar.__loader__ + loader = object() + bar.__spec__ = SimpleNamespace(loader=loader) + self.assertEqual( + _bootstrap_external._bless_my_loader(bar.__dict__), + loader) + + +if __name__ == "__main__": + unittest.main() diff --git a/Lib/test/test_importlib/import_/test_meta_path.py b/Lib/test/test_importlib/import_/test_meta_path.py index c8b898ec..8689017b 100644 --- a/Lib/test/test_importlib/import_/test_meta_path.py +++ b/Lib/test/test_importlib/import_/test_meta_path.py @@ -113,16 +113,6 @@ class CallSignoreSuppressImportWarning(CallSignature): super().test_no_path() -class CallSignaturePEP302(CallSignoreSuppressImportWarning): - mock_modules = util.mock_modules - finder_name = 'find_module' - - -(Frozen_CallSignaturePEP302, - Source_CallSignaturePEP302 - ) = util.test_both(CallSignaturePEP302, __import__=util.__import__) - - class CallSignaturePEP451(CallSignature): mock_modules = util.mock_spec finder_name = 'find_spec' diff --git a/Lib/test/test_importlib/import_/test_path.py b/Lib/test/test_importlib/import_/test_path.py index de620842..89b52fbd 100644 --- a/Lib/test/test_importlib/import_/test_path.py +++ b/Lib/test/test_importlib/import_/test_path.py @@ -116,46 +116,6 @@ class FinderTests: if email is not missing: sys.modules['email'] = email - def test_finder_with_find_module(self): - class TestFinder: - def find_module(self, fullname): - return self.to_return - failing_finder = TestFinder() - failing_finder.to_return = None - path = 'testing path' - with util.import_state(path_importer_cache={path: failing_finder}): - with warnings.catch_warnings(): - warnings.simplefilter("ignore", ImportWarning) - self.assertIsNone( - self.machinery.PathFinder.find_spec('whatever', [path])) - success_finder = TestFinder() - success_finder.to_return = __loader__ - with util.import_state(path_importer_cache={path: success_finder}): - with warnings.catch_warnings(): - warnings.simplefilter("ignore", ImportWarning) - spec = self.machinery.PathFinder.find_spec('whatever', [path]) - self.assertEqual(spec.loader, __loader__) - - def test_finder_with_find_loader(self): - class TestFinder: - loader = None - portions = [] - def find_loader(self, fullname): - return self.loader, self.portions - path = 'testing path' - with util.import_state(path_importer_cache={path: TestFinder()}): - with warnings.catch_warnings(): - warnings.simplefilter("ignore", ImportWarning) - self.assertIsNone( - self.machinery.PathFinder.find_spec('whatever', [path])) - success_finder = TestFinder() - success_finder.loader = __loader__ - with util.import_state(path_importer_cache={path: success_finder}): - with warnings.catch_warnings(): - warnings.simplefilter("ignore", ImportWarning) - spec = self.machinery.PathFinder.find_spec('whatever', [path]) - self.assertEqual(spec.loader, __loader__) - def test_finder_with_find_spec(self): class TestFinder: spec = None @@ -228,9 +188,9 @@ class FinderTests: class FindModuleTests(FinderTests): def find(self, *args, **kwargs): - with warnings.catch_warnings(): - warnings.simplefilter("ignore", DeprecationWarning) - return self.machinery.PathFinder.find_module(*args, **kwargs) + spec = self.machinery.PathFinder.find_spec(*args, **kwargs) + return None if spec is None else spec.loader + def check_found(self, found, importer): self.assertIs(found, importer) @@ -255,16 +215,14 @@ class FindSpecTests(FinderTests): class PathEntryFinderTests: def test_finder_with_failing_find_spec(self): - # PathEntryFinder with find_module() defined should work. - # Issue #20763. class Finder: - path_location = 'test_finder_with_find_module' + path_location = 'test_finder_with_find_spec' def __init__(self, path): if path != self.path_location: raise ImportError @staticmethod - def find_module(fullname): + def find_spec(fullname, target=None): return None @@ -274,27 +232,6 @@ class PathEntryFinderTests: warnings.simplefilter("ignore", ImportWarning) self.machinery.PathFinder.find_spec('importlib') - def test_finder_with_failing_find_module(self): - # PathEntryFinder with find_module() defined should work. - # Issue #20763. - class Finder: - path_location = 'test_finder_with_find_module' - def __init__(self, path): - if path != self.path_location: - raise ImportError - - @staticmethod - def find_module(fullname): - return None - - - with util.import_state(path=[Finder.path_location]+sys.path[:], - path_hooks=[Finder]): - with warnings.catch_warnings(): - warnings.simplefilter("ignore", ImportWarning) - warnings.simplefilter("ignore", DeprecationWarning) - self.machinery.PathFinder.find_module('importlib') - (Frozen_PEFTests, Source_PEFTests diff --git a/Lib/test/test_importlib/resources/_path.py b/Lib/test/test_importlib/resources/_path.py new file mode 100644 index 00000000..1f97c961 --- /dev/null +++ b/Lib/test/test_importlib/resources/_path.py @@ -0,0 +1,56 @@ +import pathlib +import functools + +from typing import Dict, Union + + +#### +# from jaraco.path 3.4.1 + +FilesSpec = Dict[str, Union[str, bytes, 'FilesSpec']] # type: ignore + + +def build(spec: FilesSpec, prefix=pathlib.Path()): + """ + Build a set of files/directories, as described by the spec. + + Each key represents a pathname, and the value represents + the content. Content may be a nested directory. + + >>> spec = { + ... 'README.txt': "A README file", + ... "foo": { + ... "__init__.py": "", + ... "bar": { + ... "__init__.py": "", + ... }, + ... "baz.py": "# Some code", + ... } + ... } + >>> target = getfixture('tmp_path') + >>> build(spec, target) + >>> target.joinpath('foo/baz.py').read_text(encoding='utf-8') + '# Some code' + """ + for name, contents in spec.items(): + create(contents, pathlib.Path(prefix) / name) + + +@functools.singledispatch +def create(content: Union[str, bytes, FilesSpec], path): + path.mkdir(exist_ok=True) + build(content, prefix=path) # type: ignore + + +@create.register +def _(content: bytes, path): + path.write_bytes(content) + + +@create.register +def _(content: str, path): + path.write_text(content, encoding='utf-8') + + +# end from jaraco.path +#### diff --git a/Lib/lib2to3/tests/data/fixers/myfixes/__init__.py b/Lib/test/test_importlib/resources/data01/__init__.py similarity index 100% rename from Lib/lib2to3/tests/data/fixers/myfixes/__init__.py rename to Lib/test/test_importlib/resources/data01/__init__.py diff --git a/Lib/test/test_importlib/data01/binary.file b/Lib/test/test_importlib/resources/data01/binary.file similarity index 100% rename from Lib/test/test_importlib/data01/binary.file rename to Lib/test/test_importlib/resources/data01/binary.file diff --git a/Lib/test/test_importlib/data01/__init__.py b/Lib/test/test_importlib/resources/data01/subdirectory/__init__.py similarity index 100% rename from Lib/test/test_importlib/data01/__init__.py rename to Lib/test/test_importlib/resources/data01/subdirectory/__init__.py diff --git a/Lib/test/test_importlib/data01/subdirectory/binary.file b/Lib/test/test_importlib/resources/data01/subdirectory/binary.file similarity index 100% rename from Lib/test/test_importlib/data01/subdirectory/binary.file rename to Lib/test/test_importlib/resources/data01/subdirectory/binary.file diff --git a/Lib/test/test_importlib/data01/utf-16.file b/Lib/test/test_importlib/resources/data01/utf-16.file similarity index 100% rename from Lib/test/test_importlib/data01/utf-16.file rename to Lib/test/test_importlib/resources/data01/utf-16.file diff --git a/Lib/test/test_importlib/data01/utf-8.file b/Lib/test/test_importlib/resources/data01/utf-8.file similarity index 100% rename from Lib/test/test_importlib/data01/utf-8.file rename to Lib/test/test_importlib/resources/data01/utf-8.file diff --git a/Lib/test/test_importlib/data01/subdirectory/__init__.py b/Lib/test/test_importlib/resources/data02/__init__.py similarity index 100% rename from Lib/test/test_importlib/data01/subdirectory/__init__.py rename to Lib/test/test_importlib/resources/data02/__init__.py diff --git a/Lib/test/test_importlib/data02/__init__.py b/Lib/test/test_importlib/resources/data02/one/__init__.py similarity index 100% rename from Lib/test/test_importlib/data02/__init__.py rename to Lib/test/test_importlib/resources/data02/one/__init__.py diff --git a/Lib/test/test_importlib/data02/one/resource1.txt b/Lib/test/test_importlib/resources/data02/one/resource1.txt similarity index 100% rename from Lib/test/test_importlib/data02/one/resource1.txt rename to Lib/test/test_importlib/resources/data02/one/resource1.txt diff --git a/Lib/test/test_importlib/resources/data02/subdirectory/subsubdir/resource.txt b/Lib/test/test_importlib/resources/data02/subdirectory/subsubdir/resource.txt new file mode 100644 index 00000000..48f587a2 --- /dev/null +++ b/Lib/test/test_importlib/resources/data02/subdirectory/subsubdir/resource.txt @@ -0,0 +1 @@ +a resource \ No newline at end of file diff --git a/Lib/test/test_importlib/data02/one/__init__.py b/Lib/test/test_importlib/resources/data02/two/__init__.py similarity index 100% rename from Lib/test/test_importlib/data02/one/__init__.py rename to Lib/test/test_importlib/resources/data02/two/__init__.py diff --git a/Lib/test/test_importlib/data02/two/resource2.txt b/Lib/test/test_importlib/resources/data02/two/resource2.txt similarity index 100% rename from Lib/test/test_importlib/data02/two/resource2.txt rename to Lib/test/test_importlib/resources/data02/two/resource2.txt diff --git a/Lib/test/test_importlib/data02/two/__init__.py b/Lib/test/test_importlib/resources/data03/__init__.py similarity index 100% rename from Lib/test/test_importlib/data02/two/__init__.py rename to Lib/test/test_importlib/resources/data03/__init__.py diff --git a/Lib/test/test_importlib/data03/__init__.py b/Lib/test/test_importlib/resources/data03/namespace/portion1/__init__.py similarity index 100% rename from Lib/test/test_importlib/data03/__init__.py rename to Lib/test/test_importlib/resources/data03/namespace/portion1/__init__.py diff --git a/Lib/test/test_importlib/data03/namespace/portion1/__init__.py b/Lib/test/test_importlib/resources/data03/namespace/portion2/__init__.py similarity index 100% rename from Lib/test/test_importlib/data03/namespace/portion1/__init__.py rename to Lib/test/test_importlib/resources/data03/namespace/portion2/__init__.py diff --git a/Lib/test/test_importlib/data03/namespace/resource1.txt b/Lib/test/test_importlib/resources/data03/namespace/resource1.txt similarity index 100% rename from Lib/test/test_importlib/data03/namespace/resource1.txt rename to Lib/test/test_importlib/resources/data03/namespace/resource1.txt diff --git a/Lib/test/test_importlib/namespacedata01/binary.file b/Lib/test/test_importlib/resources/namespacedata01/binary.file similarity index 100% rename from Lib/test/test_importlib/namespacedata01/binary.file rename to Lib/test/test_importlib/resources/namespacedata01/binary.file diff --git a/Lib/test/test_importlib/namespacedata01/utf-16.file b/Lib/test/test_importlib/resources/namespacedata01/utf-16.file similarity index 100% rename from Lib/test/test_importlib/namespacedata01/utf-16.file rename to Lib/test/test_importlib/resources/namespacedata01/utf-16.file diff --git a/Lib/test/test_importlib/namespacedata01/utf-8.file b/Lib/test/test_importlib/resources/namespacedata01/utf-8.file similarity index 100% rename from Lib/test/test_importlib/namespacedata01/utf-8.file rename to Lib/test/test_importlib/resources/namespacedata01/utf-8.file diff --git a/Lib/test/test_importlib/test_compatibilty_files.py b/Lib/test/test_importlib/resources/test_compatibilty_files.py similarity index 93% rename from Lib/test/test_importlib/test_compatibilty_files.py rename to Lib/test/test_importlib/resources/test_compatibilty_files.py index 9a823f2d..bcf608d9 100644 --- a/Lib/test/test_importlib/test_compatibilty_files.py +++ b/Lib/test/test_importlib/resources/test_compatibilty_files.py @@ -8,7 +8,7 @@ from importlib.resources._adapters import ( wrap_spec, ) -from .resources import util +from . import util class CompatibilityFilesTests(unittest.TestCase): @@ -64,11 +64,13 @@ class CompatibilityFilesTests(unittest.TestCase): def test_spec_path_open(self): self.assertEqual(self.files.read_bytes(), b'Hello, world!') - self.assertEqual(self.files.read_text(), 'Hello, world!') + self.assertEqual(self.files.read_text(encoding='utf-8'), 'Hello, world!') def test_child_path_open(self): self.assertEqual((self.files / 'a').read_bytes(), b'Hello, world!') - self.assertEqual((self.files / 'a').read_text(), 'Hello, world!') + self.assertEqual( + (self.files / 'a').read_text(encoding='utf-8'), 'Hello, world!' + ) def test_orphan_path_open(self): with self.assertRaises(FileNotFoundError): diff --git a/Lib/test/test_importlib/test_contents.py b/Lib/test/test_importlib/resources/test_contents.py similarity index 97% rename from Lib/test/test_importlib/test_contents.py rename to Lib/test/test_importlib/resources/test_contents.py index 3323bf5b..1a13f043 100644 --- a/Lib/test/test_importlib/test_contents.py +++ b/Lib/test/test_importlib/resources/test_contents.py @@ -2,7 +2,7 @@ import unittest from importlib import resources from . import data01 -from .resources import util +from . import util class ContentsTests: diff --git a/Lib/test/test_importlib/resources/test_custom.py b/Lib/test/test_importlib/resources/test_custom.py new file mode 100644 index 00000000..73127209 --- /dev/null +++ b/Lib/test/test_importlib/resources/test_custom.py @@ -0,0 +1,46 @@ +import unittest +import contextlib +import pathlib + +from test.support import os_helper + +from importlib import resources +from importlib.resources.abc import TraversableResources, ResourceReader +from . import util + + +class SimpleLoader: + """ + A simple loader that only implements a resource reader. + """ + + def __init__(self, reader: ResourceReader): + self.reader = reader + + def get_resource_reader(self, package): + return self.reader + + +class MagicResources(TraversableResources): + """ + Magically returns the resources at path. + """ + + def __init__(self, path: pathlib.Path): + self.path = path + + def files(self): + return self.path + + +class CustomTraversableResourcesTests(unittest.TestCase): + def setUp(self): + self.fixtures = contextlib.ExitStack() + self.addCleanup(self.fixtures.close) + + def test_custom_loader(self): + temp_dir = self.fixtures.enter_context(os_helper.temp_dir()) + loader = SimpleLoader(MagicResources(temp_dir)) + pkg = util.create_package_from_loader(loader) + files = resources.files(pkg) + assert files is temp_dir diff --git a/Lib/test/test_importlib/resources/test_files.py b/Lib/test/test_importlib/resources/test_files.py new file mode 100644 index 00000000..1450cfb3 --- /dev/null +++ b/Lib/test/test_importlib/resources/test_files.py @@ -0,0 +1,113 @@ +import typing +import textwrap +import unittest +import warnings +import importlib +import contextlib + +from importlib import resources +from importlib.resources.abc import Traversable +from . import data01 +from . import util +from . import _path +from test.support import os_helper +from test.support import import_helper + + +@contextlib.contextmanager +def suppress_known_deprecation(): + with warnings.catch_warnings(record=True) as ctx: + warnings.simplefilter('default', category=DeprecationWarning) + yield ctx + + +class FilesTests: + def test_read_bytes(self): + files = resources.files(self.data) + actual = files.joinpath('utf-8.file').read_bytes() + assert actual == b'Hello, UTF-8 world!\n' + + def test_read_text(self): + files = resources.files(self.data) + actual = files.joinpath('utf-8.file').read_text(encoding='utf-8') + assert actual == 'Hello, UTF-8 world!\n' + + @unittest.skipUnless( + hasattr(typing, 'runtime_checkable'), + "Only suitable when typing supports runtime_checkable", + ) + def test_traversable(self): + assert isinstance(resources.files(self.data), Traversable) + + def test_old_parameter(self): + """ + Files used to take a 'package' parameter. Make sure anyone + passing by name is still supported. + """ + with suppress_known_deprecation(): + resources.files(package=self.data) + + +class OpenDiskTests(FilesTests, unittest.TestCase): + def setUp(self): + self.data = data01 + + +class OpenZipTests(FilesTests, util.ZipSetup, unittest.TestCase): + pass + + +class OpenNamespaceTests(FilesTests, unittest.TestCase): + def setUp(self): + from . import namespacedata01 + + self.data = namespacedata01 + + +class SiteDir: + def setUp(self): + self.fixtures = contextlib.ExitStack() + self.addCleanup(self.fixtures.close) + self.site_dir = self.fixtures.enter_context(os_helper.temp_dir()) + self.fixtures.enter_context(import_helper.DirsOnSysPath(self.site_dir)) + self.fixtures.enter_context(import_helper.CleanImport()) + + +class ModulesFilesTests(SiteDir, unittest.TestCase): + def test_module_resources(self): + """ + A module can have resources found adjacent to the module. + """ + spec = { + 'mod.py': '', + 'res.txt': 'resources are the best', + } + _path.build(spec, self.site_dir) + import mod + + actual = resources.files(mod).joinpath('res.txt').read_text(encoding='utf-8') + assert actual == spec['res.txt'] + + +class ImplicitContextFilesTests(SiteDir, unittest.TestCase): + def test_implicit_files(self): + """ + Without any parameter, files() will infer the location as the caller. + """ + spec = { + 'somepkg': { + '__init__.py': textwrap.dedent( + """ + import importlib.resources as res + val = res.files().joinpath('res.txt').read_text(encoding='utf-8') + """ + ), + 'res.txt': 'resources are the best', + }, + } + _path.build(spec, self.site_dir) + assert importlib.import_module('somepkg').val == 'resources are the best' + + +if __name__ == '__main__': + unittest.main() diff --git a/Lib/test/test_importlib/test_open.py b/Lib/test/test_importlib/resources/test_open.py similarity index 86% rename from Lib/test/test_importlib/test_open.py rename to Lib/test/test_importlib/resources/test_open.py index df75e343..86becb4b 100644 --- a/Lib/test/test_importlib/test_open.py +++ b/Lib/test/test_importlib/resources/test_open.py @@ -2,7 +2,7 @@ import unittest from importlib import resources from . import data01 -from .resources import util +from . import util class CommonBinaryTests(util.CommonTests, unittest.TestCase): @@ -15,7 +15,7 @@ class CommonBinaryTests(util.CommonTests, unittest.TestCase): class CommonTextTests(util.CommonTests, unittest.TestCase): def execute(self, package, path): target = resources.files(package).joinpath(path) - with target.open(): + with target.open(encoding='utf-8'): pass @@ -28,7 +28,7 @@ class OpenTests: def test_open_text_default_encoding(self): target = resources.files(self.data) / 'utf-8.file' - with target.open() as fp: + with target.open(encoding='utf-8') as fp: result = fp.read() self.assertEqual(result, 'Hello, UTF-8 world!\n') @@ -39,7 +39,9 @@ class OpenTests: self.assertEqual(result, 'Hello, UTF-16 world!\n') def test_open_text_with_errors(self): - # Raises UnicodeError without the 'errors' argument. + """ + Raises UnicodeError without the 'errors' argument. + """ target = resources.files(self.data) / 'utf-16.file' with target.open(encoding='utf-8', errors='strict') as fp: self.assertRaises(UnicodeError, fp.read) @@ -54,11 +56,13 @@ class OpenTests: def test_open_binary_FileNotFoundError(self): target = resources.files(self.data) / 'does-not-exist' - self.assertRaises(FileNotFoundError, target.open, 'rb') + with self.assertRaises(FileNotFoundError): + target.open('rb') def test_open_text_FileNotFoundError(self): target = resources.files(self.data) / 'does-not-exist' - self.assertRaises(FileNotFoundError, target.open) + with self.assertRaises(FileNotFoundError): + target.open(encoding='utf-8') class OpenDiskTests(OpenTests, unittest.TestCase): diff --git a/Lib/test/test_importlib/test_path.py b/Lib/test/test_importlib/resources/test_path.py similarity index 84% rename from Lib/test/test_importlib/test_path.py rename to Lib/test/test_importlib/resources/test_path.py index 6fc41f30..34a6bdd2 100644 --- a/Lib/test/test_importlib/test_path.py +++ b/Lib/test/test_importlib/resources/test_path.py @@ -3,7 +3,7 @@ import unittest from importlib import resources from . import data01 -from .resources import util +from . import util class CommonTests(util.CommonTests, unittest.TestCase): @@ -14,9 +14,12 @@ class CommonTests(util.CommonTests, unittest.TestCase): class PathTests: def test_reading(self): - # Path should be readable. - # Test also implicitly verifies the returned object is a pathlib.Path - # instance. + """ + Path should be readable. + + Test also implicitly verifies the returned object is a pathlib.Path + instance. + """ target = resources.files(self.data) / 'utf-8.file' with resources.as_file(target) as path: self.assertTrue(path.name.endswith("utf-8.file"), repr(path)) @@ -51,8 +54,10 @@ class PathMemoryTests(PathTests, unittest.TestCase): class PathZipTests(PathTests, util.ZipSetup, unittest.TestCase): def test_remove_in_context_manager(self): - # It is not an error if the file that was temporarily stashed on the - # file system is removed inside the `with` stanza. + """ + It is not an error if the file that was temporarily stashed on the + file system is removed inside the `with` stanza. + """ target = resources.files(self.data) / 'utf-8.file' with resources.as_file(target) as path: path.unlink() diff --git a/Lib/test/test_importlib/test_read.py b/Lib/test/test_importlib/resources/test_read.py similarity index 86% rename from Lib/test/test_importlib/test_read.py rename to Lib/test/test_importlib/resources/test_read.py index ebd72267..08898268 100644 --- a/Lib/test/test_importlib/test_read.py +++ b/Lib/test/test_importlib/resources/test_read.py @@ -2,7 +2,7 @@ import unittest from importlib import import_module, resources from . import data01 -from .resources import util +from . import util class CommonBinaryTests(util.CommonTests, unittest.TestCase): @@ -12,7 +12,7 @@ class CommonBinaryTests(util.CommonTests, unittest.TestCase): class CommonTextTests(util.CommonTests, unittest.TestCase): def execute(self, package, path): - resources.files(package).joinpath(path).read_text() + resources.files(package).joinpath(path).read_text(encoding='utf-8') class ReadTests: @@ -21,7 +21,11 @@ class ReadTests: self.assertEqual(result, b'\0\1\2\3') def test_read_text_default_encoding(self): - result = resources.files(self.data).joinpath('utf-8.file').read_text() + result = ( + resources.files(self.data) + .joinpath('utf-8.file') + .read_text(encoding='utf-8') + ) self.assertEqual(result, 'Hello, UTF-8 world!\n') def test_read_text_given_encoding(self): @@ -33,7 +37,9 @@ class ReadTests: self.assertEqual(result, 'Hello, UTF-16 world!\n') def test_read_text_with_errors(self): - # Raises UnicodeError without the 'errors' argument. + """ + Raises UnicodeError without the 'errors' argument. + """ target = resources.files(self.data) / 'utf-16.file' self.assertRaises(UnicodeError, target.read_text, encoding='utf-8') result = target.read_text(encoding='utf-8', errors='ignore') diff --git a/Lib/test/test_importlib/test_reader.py b/Lib/test/test_importlib/resources/test_reader.py similarity index 85% rename from Lib/test/test_importlib/test_reader.py rename to Lib/test/test_importlib/resources/test_reader.py index 9d20c976..8670f72a 100644 --- a/Lib/test/test_importlib/test_reader.py +++ b/Lib/test/test_importlib/resources/test_reader.py @@ -75,6 +75,22 @@ class MultiplexedPathTest(unittest.TestCase): str(path.joinpath('imaginary'))[len(prefix) + 1 :], os.path.join('namespacedata01', 'imaginary'), ) + self.assertEqual(path.joinpath(), path) + + def test_join_path_compound(self): + path = MultiplexedPath(self.folder) + assert not path.joinpath('imaginary/foo.py').exists() + + def test_join_path_common_subdir(self): + prefix = os.path.abspath(os.path.join(__file__, '..')) + data01 = os.path.join(prefix, 'data01') + data02 = os.path.join(prefix, 'data02') + path = MultiplexedPath(data01, data02) + self.assertIsInstance(path.joinpath('subdirectory'), MultiplexedPath) + self.assertEqual( + str(path.joinpath('subdirectory', 'subsubdir'))[len(prefix) + 1 :], + os.path.join('data02', 'subdirectory', 'subsubdir'), + ) def test_repr(self): self.assertEqual( diff --git a/Lib/test/test_importlib/test_resource.py b/Lib/test/test_importlib/resources/test_resource.py similarity index 74% rename from Lib/test/test_importlib/test_resource.py rename to Lib/test/test_importlib/resources/test_resource.py index 834b8bd8..6f75cf57 100644 --- a/Lib/test/test_importlib/test_resource.py +++ b/Lib/test/test_importlib/resources/test_resource.py @@ -1,3 +1,4 @@ +import contextlib import sys import unittest import uuid @@ -5,9 +6,9 @@ import pathlib from . import data01 from . import zipdata01, zipdata02 -from .resources import util +from . import util from importlib import resources, import_module -from test.support import import_helper +from test.support import import_helper, os_helper from test.support.os_helper import unlink @@ -69,10 +70,12 @@ class ResourceLoaderTests(unittest.TestCase): class ResourceCornerCaseTests(unittest.TestCase): def test_package_has_no_reader_fallback(self): - # Test odd ball packages which: + """ + Test odd ball packages which: # 1. Do not have a ResourceReader as a loader # 2. Are not on the file system # 3. Are not in a zip file + """ module = util.create_package( file=data01, path=data01.__file__, contents=['A', 'B', 'C'] ) @@ -111,6 +114,14 @@ class ResourceFromZipsTest01(util.ZipSetupBase, unittest.TestCase): {'__init__.py', 'binary.file'}, ) + def test_as_file_directory(self): + with resources.as_file(resources.files('ziptestdata')) as data: + assert data.name == 'ziptestdata' + assert data.is_dir() + assert data.joinpath('subdirectory').is_dir() + assert len(list(data.iterdir())) + assert not data.parent.exists() + class ResourceFromZipsTest02(util.ZipSetupBase, unittest.TestCase): ZIP_MODULE = zipdata02 # type: ignore @@ -130,82 +141,71 @@ class ResourceFromZipsTest02(util.ZipSetupBase, unittest.TestCase): ) +@contextlib.contextmanager +def zip_on_path(dir): + data_path = pathlib.Path(zipdata01.__file__) + source_zip_path = data_path.parent.joinpath('ziptestdata.zip') + zip_path = pathlib.Path(dir) / f'{uuid.uuid4()}.zip' + zip_path.write_bytes(source_zip_path.read_bytes()) + sys.path.append(str(zip_path)) + import_module('ziptestdata') + + try: + yield + finally: + with contextlib.suppress(ValueError): + sys.path.remove(str(zip_path)) + + with contextlib.suppress(KeyError): + del sys.path_importer_cache[str(zip_path)] + del sys.modules['ziptestdata'] + + with contextlib.suppress(OSError): + unlink(zip_path) + + class DeletingZipsTest(unittest.TestCase): """Having accessed resources in a zip file should not keep an open reference to the zip. """ - ZIP_MODULE = zipdata01 - def setUp(self): + self.fixtures = contextlib.ExitStack() + self.addCleanup(self.fixtures.close) + modules = import_helper.modules_setup() self.addCleanup(import_helper.modules_cleanup, *modules) - data_path = pathlib.Path(self.ZIP_MODULE.__file__) - data_dir = data_path.parent - self.source_zip_path = data_dir / 'ziptestdata.zip' - self.zip_path = pathlib.Path(f'{uuid.uuid4()}.zip').absolute() - self.zip_path.write_bytes(self.source_zip_path.read_bytes()) - sys.path.append(str(self.zip_path)) - self.data = import_module('ziptestdata') - - def tearDown(self): - try: - sys.path.remove(str(self.zip_path)) - except ValueError: - pass - - try: - del sys.path_importer_cache[str(self.zip_path)] - del sys.modules[self.data.__name__] - except KeyError: - pass - - try: - unlink(self.zip_path) - except OSError: - # If the test fails, this will probably fail too - pass + temp_dir = self.fixtures.enter_context(os_helper.temp_dir()) + self.fixtures.enter_context(zip_on_path(temp_dir)) def test_iterdir_does_not_keep_open(self): - c = [item.name for item in resources.files('ziptestdata').iterdir()] - self.zip_path.unlink() - del c + [item.name for item in resources.files('ziptestdata').iterdir()] def test_is_file_does_not_keep_open(self): - c = resources.files('ziptestdata').joinpath('binary.file').is_file() - self.zip_path.unlink() - del c + resources.files('ziptestdata').joinpath('binary.file').is_file() def test_is_file_failure_does_not_keep_open(self): - c = resources.files('ziptestdata').joinpath('not-present').is_file() - self.zip_path.unlink() - del c + resources.files('ziptestdata').joinpath('not-present').is_file() @unittest.skip("Desired but not supported.") def test_as_file_does_not_keep_open(self): # pragma: no cover - c = resources.as_file(resources.files('ziptestdata') / 'binary.file') - self.zip_path.unlink() - del c + resources.as_file(resources.files('ziptestdata') / 'binary.file') def test_entered_path_does_not_keep_open(self): - # This is what certifi does on import to make its bundle - # available for the process duration. - c = resources.as_file( - resources.files('ziptestdata') / 'binary.file' - ).__enter__() - self.zip_path.unlink() - del c + """ + Mimic what certifi does on import to make its bundle + available for the process duration. + """ + resources.as_file(resources.files('ziptestdata') / 'binary.file').__enter__() def test_read_binary_does_not_keep_open(self): - c = resources.files('ziptestdata').joinpath('binary.file').read_bytes() - self.zip_path.unlink() - del c + resources.files('ziptestdata').joinpath('binary.file').read_bytes() def test_read_text_does_not_keep_open(self): - c = resources.files('ziptestdata').joinpath('utf-8.file').read_text() - self.zip_path.unlink() - del c + resources.files('ziptestdata').joinpath('utf-8.file').read_text( + encoding='utf-8' + ) class ResourceFromNamespaceTest01(unittest.TestCase): diff --git a/Lib/test/test_importlib/update-zips.py b/Lib/test/test_importlib/resources/update-zips.py similarity index 100% rename from Lib/test/test_importlib/update-zips.py rename to Lib/test/test_importlib/resources/update-zips.py diff --git a/Lib/test/test_importlib/resources/util.py b/Lib/test/test_importlib/resources/util.py index 11c8aa80..dbe6ee81 100644 --- a/Lib/test/test_importlib/resources/util.py +++ b/Lib/test/test_importlib/resources/util.py @@ -3,11 +3,11 @@ import importlib import io import sys import types -from pathlib import Path, PurePath +import pathlib -from .. import data01 -from .. import zipdata01 -from importlib.abc import ResourceReader +from . import data01 +from . import zipdata01 +from importlib.resources.abc import ResourceReader from test.support import import_helper @@ -80,43 +80,44 @@ class CommonTests(metaclass=abc.ABCMeta): """ def test_package_name(self): - # Passing in the package name should succeed. + """ + Passing in the package name should succeed. + """ self.execute(data01.__name__, 'utf-8.file') def test_package_object(self): - # Passing in the package itself should succeed. + """ + Passing in the package itself should succeed. + """ self.execute(data01, 'utf-8.file') def test_string_path(self): - # Passing in a string for the path should succeed. + """ + Passing in a string for the path should succeed. + """ path = 'utf-8.file' self.execute(data01, path) def test_pathlib_path(self): - # Passing in a pathlib.PurePath object for the path should succeed. - path = PurePath('utf-8.file') + """ + Passing in a pathlib.PurePath object for the path should succeed. + """ + path = pathlib.PurePath('utf-8.file') self.execute(data01, path) def test_importing_module_as_side_effect(self): - # The anchor package can already be imported. + """ + The anchor package can already be imported. + """ del sys.modules[data01.__name__] self.execute(data01.__name__, 'utf-8.file') - def test_non_package_by_name(self): - # The anchor package cannot be a module. - with self.assertRaises(TypeError): - self.execute(__name__, 'utf-8.file') - - def test_non_package_by_package(self): - # The anchor package cannot be a module. - with self.assertRaises(TypeError): - module = sys.modules['test.test_importlib.resources.util'] - self.execute(module, 'utf-8.file') - def test_missing_path(self): - # Attempting to open or read or request the path for a - # non-existent path should succeed if open_resource - # can return a viable data stream. + """ + Attempting to open or read or request the path for a + non-existent path should succeed if open_resource + can return a viable data stream. + """ bytes_data = io.BytesIO(b'Hello, world!') package = create_package(file=bytes_data, path=FileNotFoundError()) self.execute(package, 'utf-8.file') @@ -144,7 +145,7 @@ class ZipSetupBase: @classmethod def setUpClass(cls): - data_path = Path(cls.ZIP_MODULE.__file__) + data_path = pathlib.Path(cls.ZIP_MODULE.__file__) data_dir = data_path.parent cls._zip_path = str(data_dir / 'ziptestdata.zip') sys.path.append(cls._zip_path) diff --git a/Lib/test/test_importlib/data03/namespace/portion2/__init__.py b/Lib/test/test_importlib/resources/zipdata01/__init__.py similarity index 100% rename from Lib/test/test_importlib/data03/namespace/portion2/__init__.py rename to Lib/test/test_importlib/resources/zipdata01/__init__.py diff --git a/Lib/test/test_importlib/zipdata01/ziptestdata.zip b/Lib/test/test_importlib/resources/zipdata01/ziptestdata.zip similarity index 100% rename from Lib/test/test_importlib/zipdata01/ziptestdata.zip rename to Lib/test/test_importlib/resources/zipdata01/ziptestdata.zip diff --git a/Lib/test/test_importlib/zipdata01/__init__.py b/Lib/test/test_importlib/resources/zipdata02/__init__.py similarity index 100% rename from Lib/test/test_importlib/zipdata01/__init__.py rename to Lib/test/test_importlib/resources/zipdata02/__init__.py diff --git a/Lib/test/test_importlib/zipdata02/ziptestdata.zip b/Lib/test/test_importlib/resources/zipdata02/ziptestdata.zip similarity index 100% rename from Lib/test/test_importlib/zipdata02/ziptestdata.zip rename to Lib/test/test_importlib/resources/zipdata02/ziptestdata.zip diff --git a/Lib/test/test_importlib/source/test_case_sensitivity.py b/Lib/test/test_importlib/source/test_case_sensitivity.py index 9d472707..6a063133 100644 --- a/Lib/test/test_importlib/source/test_case_sensitivity.py +++ b/Lib/test/test_importlib/source/test_case_sensitivity.py @@ -63,19 +63,6 @@ class CaseSensitivityTest(util.CASEOKTestBase): self.assertIn(self.name, insensitive.get_filename(self.name)) -class CaseSensitivityTestPEP302(CaseSensitivityTest): - def find(self, finder): - with warnings.catch_warnings(): - warnings.simplefilter("ignore", DeprecationWarning) - return finder.find_module(self.name) - - -(Frozen_CaseSensitivityTestPEP302, - Source_CaseSensitivityTestPEP302 - ) = util.test_both(CaseSensitivityTestPEP302, importlib=importlib, - machinery=machinery) - - class CaseSensitivityTestPEP451(CaseSensitivityTest): def find(self, finder): found = finder.find_spec(self.name) diff --git a/Lib/test/test_importlib/source/test_file_loader.py b/Lib/test/test_importlib/source/test_file_loader.py index 378dcbe0..f35adec1 100644 --- a/Lib/test/test_importlib/source/test_file_loader.py +++ b/Lib/test/test_importlib/source/test_file_loader.py @@ -51,7 +51,6 @@ class SimpleTest(abc.LoaderTests): def get_code(self, _): pass def get_source(self, _): pass def is_package(self, _): pass - def module_repr(self, _): pass path = 'some_path' name = 'some_name' diff --git a/Lib/test/test_importlib/source/test_finder.py b/Lib/test/test_importlib/source/test_finder.py index bed9d56d..12db7c7d 100644 --- a/Lib/test/test_importlib/source/test_finder.py +++ b/Lib/test/test_importlib/source/test_finder.py @@ -120,7 +120,7 @@ class FinderTests(abc.FinderTests): def test_failure(self): with util.create_modules('blah') as mapping: nothing = self.import_(mapping['.root'], 'sdfsadsadf') - self.assertIsNone(nothing) + self.assertEqual(nothing, self.NOT_FOUND) def test_empty_string_for_dir(self): # The empty string from sys.path means to search in the cwd. @@ -150,7 +150,7 @@ class FinderTests(abc.FinderTests): found = self._find(finder, 'mod', loader_only=True) self.assertIsNotNone(found) found = self._find(finder, 'mod', loader_only=True) - self.assertIsNone(found) + self.assertEqual(found, self.NOT_FOUND) @unittest.skipUnless(sys.platform != 'win32', 'os.chmod() does not support the needed arguments under Windows') @@ -196,10 +196,12 @@ class FinderTestsPEP420(FinderTests): NOT_FOUND = (None, []) def _find(self, finder, name, loader_only=False): - with warnings.catch_warnings(): - warnings.simplefilter("ignore", DeprecationWarning) - loader_portions = finder.find_loader(name) - return loader_portions[0] if loader_only else loader_portions + spec = finder.find_spec(name) + if spec is None: + return self.NOT_FOUND + if loader_only: + return spec.loader + return spec.loader, spec.submodule_search_locations (Frozen_FinderTestsPEP420, @@ -207,20 +209,5 @@ class FinderTestsPEP420(FinderTests): ) = util.test_both(FinderTestsPEP420, machinery=machinery) -class FinderTestsPEP302(FinderTests): - - NOT_FOUND = None - - def _find(self, finder, name, loader_only=False): - with warnings.catch_warnings(): - warnings.simplefilter("ignore", DeprecationWarning) - return finder.find_module(name) - - -(Frozen_FinderTestsPEP302, - Source_FinderTestsPEP302 - ) = util.test_both(FinderTestsPEP302, machinery=machinery) - - if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_importlib/source/test_path_hook.py b/Lib/test/test_importlib/source/test_path_hook.py index ead62f5e..f274330e 100644 --- a/Lib/test/test_importlib/source/test_path_hook.py +++ b/Lib/test/test_importlib/source/test_path_hook.py @@ -18,19 +18,10 @@ class PathHookTest: self.assertTrue(hasattr(self.path_hook()(mapping['.root']), 'find_spec')) - def test_success_legacy(self): - with util.create_modules('dummy') as mapping: - self.assertTrue(hasattr(self.path_hook()(mapping['.root']), - 'find_module')) - def test_empty_string(self): # The empty string represents the cwd. self.assertTrue(hasattr(self.path_hook()(''), 'find_spec')) - def test_empty_string_legacy(self): - # The empty string represents the cwd. - self.assertTrue(hasattr(self.path_hook()(''), 'find_module')) - (Frozen_PathHookTest, Source_PathHooktest diff --git a/Lib/test/test_importlib/test_abc.py b/Lib/test/test_importlib/test_abc.py index 92cb7806..603125f6 100644 --- a/Lib/test/test_importlib/test_abc.py +++ b/Lib/test/test_importlib/test_abc.py @@ -2,7 +2,6 @@ import io import marshal import os import sys -from test import support from test.support import import_helper import types import unittest @@ -148,20 +147,13 @@ class ABCTestHarness: class MetaPathFinder: - def find_module(self, fullname, path): - return super().find_module(fullname, path) + pass class MetaPathFinderDefaultsTests(ABCTestHarness): SPLIT = make_abc_subclasses(MetaPathFinder) - def test_find_module(self): - # Default should return None. - with self.assertWarns(DeprecationWarning): - found = self.ins.find_module('something', None) - self.assertIsNone(found) - def test_invalidate_caches(self): # Calling the method is a no-op. self.ins.invalidate_caches() @@ -174,22 +166,13 @@ class MetaPathFinderDefaultsTests(ABCTestHarness): class PathEntryFinder: - def find_loader(self, fullname): - return super().find_loader(fullname) + pass class PathEntryFinderDefaultsTests(ABCTestHarness): SPLIT = make_abc_subclasses(PathEntryFinder) - def test_find_loader(self): - with self.assertWarns(DeprecationWarning): - found = self.ins.find_loader('something') - self.assertEqual(found, (None, [])) - - def find_module(self): - self.assertEqual(None, self.ins.find_module('something')) - def test_invalidate_caches(self): # Should be a no-op. self.ins.invalidate_caches() @@ -202,8 +185,7 @@ class PathEntryFinderDefaultsTests(ABCTestHarness): class Loader: - def load_module(self, fullname): - return super().load_module(fullname) + pass class LoaderDefaultsTests(ABCTestHarness): @@ -222,8 +204,6 @@ class LoaderDefaultsTests(ABCTestHarness): mod = types.ModuleType('blah') with warnings.catch_warnings(): warnings.simplefilter("ignore", DeprecationWarning) - with self.assertRaises(NotImplementedError): - self.ins.module_repr(mod) original_repr = repr(mod) mod.__loader__ = self.ins # Should still return a proper repr. @@ -323,32 +303,6 @@ class ResourceReader: return super().contents(*args, **kwargs) -class ResourceReaderDefaultsTests(ABCTestHarness): - - SPLIT = make_abc_subclasses(ResourceReader) - - def test_open_resource(self): - with self.assertRaises(FileNotFoundError): - self.ins.open_resource('dummy_file') - - def test_resource_path(self): - with self.assertRaises(FileNotFoundError): - self.ins.resource_path('dummy_file') - - def test_is_resource(self): - with self.assertRaises(FileNotFoundError): - self.ins.is_resource('dummy_file') - - def test_contents(self): - with self.assertRaises(FileNotFoundError): - self.ins.contents() - - -(Frozen_RRDefaultTests, - Source_RRDefaultsTests - ) = test_util.test_both(ResourceReaderDefaultsTests) - - ##### MetaPathFinder concrete methods ########################################## class MetaPathFinderFindModuleTests: @@ -362,14 +316,6 @@ class MetaPathFinderFindModuleTests: return MetaPathSpecFinder() - def test_find_module(self): - finder = self.finder(None) - path = ['a', 'b', 'c'] - name = 'blah' - with self.assertWarns(DeprecationWarning): - found = finder.find_module(name, path) - self.assertIsNone(found) - def test_find_spec_with_explicit_target(self): loader = object() spec = self.util.spec_from_loader('blah', loader) @@ -399,53 +345,6 @@ class MetaPathFinderFindModuleTests: ) = test_util.test_both(MetaPathFinderFindModuleTests, abc=abc, util=util) -##### PathEntryFinder concrete methods ######################################### -class PathEntryFinderFindLoaderTests: - - @classmethod - def finder(cls, spec): - class PathEntrySpecFinder(cls.abc.PathEntryFinder): - - def find_spec(self, fullname, target=None): - self.called_for = fullname - return spec - - return PathEntrySpecFinder() - - def test_no_spec(self): - finder = self.finder(None) - name = 'blah' - with self.assertWarns(DeprecationWarning): - found = finder.find_loader(name) - self.assertIsNone(found[0]) - self.assertEqual([], found[1]) - self.assertEqual(name, finder.called_for) - - def test_spec_with_loader(self): - loader = object() - spec = self.util.spec_from_loader('blah', loader) - finder = self.finder(spec) - with self.assertWarns(DeprecationWarning): - found = finder.find_loader('blah') - self.assertIs(found[0], spec.loader) - - def test_spec_with_portions(self): - spec = self.machinery.ModuleSpec('blah', None) - paths = ['a', 'b', 'c'] - spec.submodule_search_locations = paths - finder = self.finder(spec) - with self.assertWarns(DeprecationWarning): - found = finder.find_loader('blah') - self.assertIsNone(found[0]) - self.assertEqual(paths, found[1]) - - -(Frozen_PEFFindLoaderTests, - Source_PEFFindLoaderTests - ) = test_util.test_both(PathEntryFinderFindLoaderTests, abc=abc, util=util, - machinery=machinery) - - ##### Loader concrete methods ################################################## class LoaderLoadModuleTests: @@ -716,9 +615,6 @@ class SourceOnlyLoader: def get_filename(self, fullname): return self.path - def module_repr(self, module): - return '<module>' - SPLIT_SOL = make_abc_subclasses(SourceOnlyLoader, 'SourceLoader') @@ -803,13 +699,7 @@ class SourceLoaderTestHarness: class SourceOnlyLoaderTests(SourceLoaderTestHarness): - - """Test importlib.abc.SourceLoader for source-only loading. - - Reload testing is subsumed by the tests for - importlib.util.module_for_loader. - - """ + """Test importlib.abc.SourceLoader for source-only loading.""" def test_get_source(self): # Verify the source code is returned as a string. diff --git a/Lib/test/test_importlib/test_api.py b/Lib/test/test_importlib/test_api.py index 1beb7835..ecf2c47c 100644 --- a/Lib/test/test_importlib/test_api.py +++ b/Lib/test/test_importlib/test_api.py @@ -6,7 +6,6 @@ machinery = test_util.import_importlib('importlib.machinery') import os.path import sys -from test import support from test.support import import_helper from test.support import os_helper import types @@ -96,7 +95,8 @@ class ImportModuleTests: (Frozen_ImportModuleTests, Source_ImportModuleTests - ) = test_util.test_both(ImportModuleTests, init=init) + ) = test_util.test_both( + ImportModuleTests, init=init, util=util, machinery=machinery) class FindLoaderTests: @@ -104,29 +104,26 @@ class FindLoaderTests: FakeMetaFinder = None def test_sys_modules(self): - # If a module with __loader__ is in sys.modules, then return it. + # If a module with __spec__.loader is in sys.modules, then return it. name = 'some_mod' with test_util.uncache(name): module = types.ModuleType(name) loader = 'a loader!' - module.__loader__ = loader + module.__spec__ = self.machinery.ModuleSpec(name, loader) sys.modules[name] = module - with warnings.catch_warnings(): - warnings.simplefilter('ignore', DeprecationWarning) - found = self.init.find_loader(name) - self.assertEqual(loader, found) + spec = self.util.find_spec(name) + self.assertIsNotNone(spec) + self.assertEqual(spec.loader, loader) def test_sys_modules_loader_is_None(self): - # If sys.modules[name].__loader__ is None, raise ValueError. + # If sys.modules[name].__spec__.loader is None, raise ValueError. name = 'some_mod' with test_util.uncache(name): module = types.ModuleType(name) module.__loader__ = None sys.modules[name] = module with self.assertRaises(ValueError): - with warnings.catch_warnings(): - warnings.simplefilter('ignore', DeprecationWarning) - self.init.find_loader(name) + self.util.find_spec(name) def test_sys_modules_loader_is_not_set(self): # Should raise ValueError @@ -135,24 +132,20 @@ class FindLoaderTests: with test_util.uncache(name): module = types.ModuleType(name) try: - del module.__loader__ + del module.__spec__.loader except AttributeError: pass sys.modules[name] = module with self.assertRaises(ValueError): - with warnings.catch_warnings(): - warnings.simplefilter('ignore', DeprecationWarning) - self.init.find_loader(name) + self.util.find_spec(name) def test_success(self): # Return the loader found on sys.meta_path. name = 'some_mod' with test_util.uncache(name): with test_util.import_state(meta_path=[self.FakeMetaFinder]): - with warnings.catch_warnings(): - warnings.simplefilter('ignore', DeprecationWarning) - warnings.simplefilter('ignore', ImportWarning) - self.assertEqual((name, None), self.init.find_loader(name)) + spec = self.util.find_spec(name) + self.assertEqual((name, (name, None)), (spec.name, spec.loader)) def test_success_path(self): # Searching on a path should work. @@ -160,17 +153,12 @@ class FindLoaderTests: path = 'path to some place' with test_util.uncache(name): with test_util.import_state(meta_path=[self.FakeMetaFinder]): - with warnings.catch_warnings(): - warnings.simplefilter('ignore', DeprecationWarning) - warnings.simplefilter('ignore', ImportWarning) - self.assertEqual((name, path), - self.init.find_loader(name, path)) + spec = self.util.find_spec(name, path) + self.assertEqual(name, spec.name) def test_nothing(self): # None is returned upon failure to find a loader. - with warnings.catch_warnings(): - warnings.simplefilter('ignore', DeprecationWarning) - self.assertIsNone(self.init.find_loader('nevergoingtofindthismodule')) + self.assertIsNone(self.util.find_spec('nevergoingtofindthismodule')) class FindLoaderPEP451Tests(FindLoaderTests): @@ -183,20 +171,8 @@ class FindLoaderPEP451Tests(FindLoaderTests): (Frozen_FindLoaderPEP451Tests, Source_FindLoaderPEP451Tests - ) = test_util.test_both(FindLoaderPEP451Tests, init=init) - - -class FindLoaderPEP302Tests(FindLoaderTests): - - class FakeMetaFinder: - @staticmethod - def find_module(name, path=None): - return name, path - - -(Frozen_FindLoaderPEP302Tests, - Source_FindLoaderPEP302Tests - ) = test_util.test_both(FindLoaderPEP302Tests, init=init) + ) = test_util.test_both( + FindLoaderPEP451Tests, init=init, util=util, machinery=machinery) class ReloadTests: @@ -301,7 +277,8 @@ class ReloadTests: name = 'spam' with os_helper.temp_cwd(None) as cwd: with test_util.uncache('spam'): - with import_helper.DirsOnSysPath(cwd): + with test_util.import_state(path=[cwd]): + self.init._bootstrap_external._install(self.init._bootstrap) # Start as a namespace package. self.init.invalidate_caches() bad_path = os.path.join(cwd, name, '__init.py') @@ -380,7 +357,8 @@ class ReloadTests: (Frozen_ReloadTests, Source_ReloadTests - ) = test_util.test_both(ReloadTests, init=init, util=util) + ) = test_util.test_both( + ReloadTests, init=init, util=util, machinery=machinery) class InvalidateCacheTests: @@ -390,8 +368,6 @@ class InvalidateCacheTests: class InvalidatingNullFinder: def __init__(self, *ignored): self.called = False - def find_module(self, *args): - return None def invalidate_caches(self): self.called = True @@ -416,7 +392,8 @@ class InvalidateCacheTests: (Frozen_InvalidateCacheTests, Source_InvalidateCacheTests - ) = test_util.test_both(InvalidateCacheTests, init=init) + ) = test_util.test_both( + InvalidateCacheTests, init=init, util=util, machinery=machinery) class FrozenImportlibTests(unittest.TestCase): diff --git a/Lib/test/test_importlib/test_files.py b/Lib/test/test_importlib/test_files.py deleted file mode 100644 index b9170d83..00000000 --- a/Lib/test/test_importlib/test_files.py +++ /dev/null @@ -1,46 +0,0 @@ -import typing -import unittest - -from importlib import resources -from importlib.abc import Traversable -from . import data01 -from .resources import util - - -class FilesTests: - def test_read_bytes(self): - files = resources.files(self.data) - actual = files.joinpath('utf-8.file').read_bytes() - assert actual == b'Hello, UTF-8 world!\n' - - def test_read_text(self): - files = resources.files(self.data) - actual = files.joinpath('utf-8.file').read_text(encoding='utf-8') - assert actual == 'Hello, UTF-8 world!\n' - - @unittest.skipUnless( - hasattr(typing, 'runtime_checkable'), - "Only suitable when typing supports runtime_checkable", - ) - def test_traversable(self): - assert isinstance(resources.files(self.data), Traversable) - - -class OpenDiskTests(FilesTests, unittest.TestCase): - def setUp(self): - self.data = data01 - - -class OpenZipTests(FilesTests, util.ZipSetup, unittest.TestCase): - pass - - -class OpenNamespaceTests(FilesTests, unittest.TestCase): - def setUp(self): - from . import namespacedata01 - - self.data = namespacedata01 - - -if __name__ == '__main__': - unittest.main() diff --git a/Lib/test/test_importlib/test_locks.py b/Lib/test/test_importlib/test_locks.py index 56d73c49..ba9cf51c 100644 --- a/Lib/test/test_importlib/test_locks.py +++ b/Lib/test/test_importlib/test_locks.py @@ -33,6 +33,11 @@ class ModuleLockAsRLockTests: test_repr = None test_locked_repr = None + def tearDown(self): + for splitinit in init.values(): + splitinit._bootstrap._blocking_on.clear() + + LOCK_TYPES = {kind: splitinit._bootstrap._ModuleLock for kind, splitinit in init.items()} diff --git a/Lib/test/test_importlib/test_main.py b/Lib/test/test_importlib/test_main.py index d9d067c4..81f68379 100644 --- a/Lib/test/test_importlib/test_main.py +++ b/Lib/test/test_importlib/test_main.py @@ -1,9 +1,10 @@ import re -import json import pickle import unittest import warnings import importlib.metadata +import contextlib +import itertools try: import pyfakefs.fake_filesystem_unittest as ffs @@ -11,6 +12,7 @@ except ImportError: from .stubs import fake_filesystem_unittest as ffs from . import fixtures +from ._context import suppress from importlib.metadata import ( Distribution, EntryPoint, @@ -24,6 +26,13 @@ from importlib.metadata import ( ) +@contextlib.contextmanager +def suppress_known_deprecation(): + with warnings.catch_warnings(record=True) as ctx: + warnings.simplefilter('default', category=DeprecationWarning) + yield ctx + + class BasicTests(fixtures.DistInfoPkg, unittest.TestCase): version_pattern = r'\d+\.\d+(\.\d)?' @@ -39,7 +48,7 @@ class BasicTests(fixtures.DistInfoPkg, unittest.TestCase): def test_package_not_found_mentions_metadata(self): """ When a package is not found, that could indicate that the - packgae is not installed or that it is installed without + package is not installed or that it is installed without metadata. Ensure the exception mentions metadata to help guide users toward the cause. See #124. """ @@ -48,15 +57,19 @@ class BasicTests(fixtures.DistInfoPkg, unittest.TestCase): assert "metadata" in str(ctx.exception) - def test_new_style_classes(self): - self.assertIsInstance(Distribution, type) + # expected to fail until ABC is enforced + @suppress(AssertionError) + @suppress_known_deprecation() + def test_abc_enforced(self): + with self.assertRaises(TypeError): + type('DistributionSubclass', (Distribution,), {})() @fixtures.parameterize( dict(name=None), dict(name=''), ) def test_invalid_inputs_to_from_name(self, name): - with self.assertRaises(Exception): + with self.assertRaises(ValueError): Distribution.from_name(name) @@ -174,11 +187,21 @@ class NonASCIITests(fixtures.OnSysPath, fixtures.SiteDir, unittest.TestCase): assert meta['Description'] == 'pôrˈtend' -class DiscoveryTests(fixtures.EggInfoPkg, fixtures.DistInfoPkg, unittest.TestCase): +class DiscoveryTests( + fixtures.EggInfoPkg, + fixtures.EggInfoPkgPipInstalledNoToplevel, + fixtures.EggInfoPkgPipInstalledNoModules, + fixtures.EggInfoPkgSourcesFallback, + fixtures.DistInfoPkg, + unittest.TestCase, +): def test_package_discovery(self): dists = list(distributions()) assert all(isinstance(dist, Distribution) for dist in dists) assert any(dist.metadata['Name'] == 'egginfo-pkg' for dist in dists) + assert any(dist.metadata['Name'] == 'egg_with_module-pkg' for dist in dists) + assert any(dist.metadata['Name'] == 'egg_with_no_modules-pkg' for dist in dists) + assert any(dist.metadata['Name'] == 'sources_fallback-pkg' for dist in dists) assert any(dist.metadata['Name'] == 'distinfo-pkg' for dist in dists) def test_invalid_usage(self): @@ -260,14 +283,6 @@ class TestEntryPoints(unittest.TestCase): """EntryPoints should be hashable""" hash(self.ep) - def test_json_dump(self): - """ - json should not expect to be able to dump an EntryPoint - """ - with self.assertRaises(Exception): - with warnings.catch_warnings(record=True): - json.dumps(self.ep) - def test_module(self): assert self.ep.module == 'value' @@ -334,3 +349,79 @@ class PackagesDistributionsTest( prefix=self.site_dir, ) packages_distributions() + + def test_packages_distributions_all_module_types(self): + """ + Test top-level modules detected on a package without 'top-level.txt'. + """ + suffixes = importlib.machinery.all_suffixes() + metadata = dict( + METADATA=""" + Name: all_distributions + Version: 1.0.0 + """, + ) + files = { + 'all_distributions-1.0.0.dist-info': metadata, + } + for i, suffix in enumerate(suffixes): + files.update( + { + f'importable-name {i}{suffix}': '', + f'in_namespace_{i}': { + f'mod{suffix}': '', + }, + f'in_package_{i}': { + '__init__.py': '', + f'mod{suffix}': '', + }, + } + ) + metadata.update(RECORD=fixtures.build_record(files)) + fixtures.build_files(files, prefix=self.site_dir) + + distributions = packages_distributions() + + for i in range(len(suffixes)): + assert distributions[f'importable-name {i}'] == ['all_distributions'] + assert distributions[f'in_namespace_{i}'] == ['all_distributions'] + assert distributions[f'in_package_{i}'] == ['all_distributions'] + + assert not any(name.endswith('.dist-info') for name in distributions) + + +class PackagesDistributionsEggTest( + fixtures.EggInfoPkg, + fixtures.EggInfoPkgPipInstalledNoToplevel, + fixtures.EggInfoPkgPipInstalledNoModules, + fixtures.EggInfoPkgSourcesFallback, + unittest.TestCase, +): + def test_packages_distributions_on_eggs(self): + """ + Test old-style egg packages with a variation of 'top_level.txt', + 'SOURCES.txt', and 'installed-files.txt', available. + """ + distributions = packages_distributions() + + def import_names_from_package(package_name): + return { + import_name + for import_name, package_names in distributions.items() + if package_name in package_names + } + + # egginfo-pkg declares one import ('mod') via top_level.txt + assert import_names_from_package('egginfo-pkg') == {'mod'} + + # egg_with_module-pkg has one import ('egg_with_module') inferred from + # installed-files.txt (top_level.txt is missing) + assert import_names_from_package('egg_with_module-pkg') == {'egg_with_module'} + + # egg_with_no_modules-pkg should not be associated with any import names + # (top_level.txt is empty, and installed-files.txt has no .py files) + assert import_names_from_package('egg_with_no_modules-pkg') == set() + + # sources_fallback-pkg has one import ('sources_fallback') inferred from + # SOURCES.txt (top_level.txt and installed-files.txt is missing) + assert import_names_from_package('sources_fallback-pkg') == {'sources_fallback'} diff --git a/Lib/test/test_importlib/test_metadata_api.py b/Lib/test/test_importlib/test_metadata_api.py index 69c78e98..33c6e85e 100644 --- a/Lib/test/test_importlib/test_metadata_api.py +++ b/Lib/test/test_importlib/test_metadata_api.py @@ -27,12 +27,14 @@ def suppress_known_deprecation(): class APITests( fixtures.EggInfoPkg, + fixtures.EggInfoPkgPipInstalledNoToplevel, + fixtures.EggInfoPkgPipInstalledNoModules, + fixtures.EggInfoPkgSourcesFallback, fixtures.DistInfoPkg, fixtures.DistInfoPkgWithDot, fixtures.EggInfoFile, unittest.TestCase, ): - version_pattern = r'\d+\.\d+(\.\d)?' def test_retrieves_version_of_self(self): @@ -63,15 +65,28 @@ class APITests( distribution(prefix) def test_for_top_level(self): - self.assertEqual( - distribution('egginfo-pkg').read_text('top_level.txt').strip(), 'mod' - ) + tests = [ + ('egginfo-pkg', 'mod'), + ('egg_with_no_modules-pkg', ''), + ] + for pkg_name, expect_content in tests: + with self.subTest(pkg_name): + self.assertEqual( + distribution(pkg_name).read_text('top_level.txt').strip(), + expect_content, + ) def test_read_text(self): - top_level = [ - path for path in files('egginfo-pkg') if path.name == 'top_level.txt' - ][0] - self.assertEqual(top_level.read_text(), 'mod\n') + tests = [ + ('egginfo-pkg', 'mod\n'), + ('egg_with_no_modules-pkg', '\n'), + ] + for pkg_name, expect_content in tests: + with self.subTest(pkg_name): + top_level = [ + path for path in files(pkg_name) if path.name == 'top_level.txt' + ][0] + self.assertEqual(top_level.read_text(), expect_content) def test_entry_points(self): eps = entry_points() @@ -124,62 +139,6 @@ class APITests( def test_entry_points_missing_group(self): assert entry_points(group='missing') == () - def test_entry_points_dict_construction(self): - """ - Prior versions of entry_points() returned simple lists and - allowed casting those lists into maps by name using ``dict()``. - Capture this now deprecated use-case. - """ - with suppress_known_deprecation() as caught: - eps = dict(entry_points(group='entries')) - - assert 'main' in eps - assert eps['main'] == entry_points(group='entries')['main'] - - # check warning - expected = next(iter(caught)) - assert expected.category is DeprecationWarning - assert "Construction of dict of EntryPoints is deprecated" in str(expected) - - def test_entry_points_by_index(self): - """ - Prior versions of Distribution.entry_points would return a - tuple that allowed access by index. - Capture this now deprecated use-case - See python/importlib_metadata#300 and bpo-44246. - """ - eps = distribution('distinfo-pkg').entry_points - with suppress_known_deprecation() as caught: - eps[0] - - # check warning - expected = next(iter(caught)) - assert expected.category is DeprecationWarning - assert "Accessing entry points by index is deprecated" in str(expected) - - def test_entry_points_groups_getitem(self): - """ - Prior versions of entry_points() returned a dict. Ensure - that callers using '.__getitem__()' are supported but warned to - migrate. - """ - with suppress_known_deprecation(): - entry_points()['entries'] == entry_points(group='entries') - - with self.assertRaises(KeyError): - entry_points()['missing'] - - def test_entry_points_groups_get(self): - """ - Prior versions of entry_points() returned a dict. Ensure - that callers using '.get()' are supported but warned to - migrate. - """ - with suppress_known_deprecation(): - entry_points().get('missing', 'default') == 'default' - entry_points().get('entries', 'default') == entry_points()['entries'] - entry_points().get('missing', ()) == () - def test_entry_points_allows_no_attributes(self): ep = entry_points().select(group='entries', name='main') with self.assertRaises(AttributeError): @@ -193,6 +152,28 @@ class APITests( classifiers = md.get_all('Classifier') assert 'Topic :: Software Development :: Libraries' in classifiers + def test_missing_key_legacy(self): + """ + Requesting a missing key will still return None, but warn. + """ + md = metadata('distinfo-pkg') + with suppress_known_deprecation(): + assert md['does-not-exist'] is None + + def test_get_key(self): + """ + Getting a key gets the key. + """ + md = metadata('egginfo-pkg') + assert md.get('Name') == 'egginfo-pkg' + + def test_get_missing_key(self): + """ + Requesting a missing key will return None. + """ + md = metadata('distinfo-pkg') + assert md.get('does-not-exist') is None + @staticmethod def _test_files(files): root = files[0].root @@ -215,6 +196,9 @@ class APITests( def test_files_egg_info(self): self._test_files(files('egginfo-pkg')) + self._test_files(files('egg_with_module-pkg')) + self._test_files(files('egg_with_no_modules-pkg')) + self._test_files(files('sources_fallback-pkg')) def test_version_egg_info_file(self): self.assertEqual(version('egginfo-file'), '0.1') diff --git a/Lib/test/test_importlib/test_namespace_pkgs.py b/Lib/test/test_importlib/test_namespace_pkgs.py index cd084985..65428c3d 100644 --- a/Lib/test/test_importlib/test_namespace_pkgs.py +++ b/Lib/test/test_importlib/test_namespace_pkgs.py @@ -79,12 +79,9 @@ class SingleNamespacePackage(NamespacePackageTest): with self.assertRaises(ImportError): import foo.two - def test_module_repr(self): + def test_simple_repr(self): import foo.one - with warnings.catch_warnings(): - warnings.simplefilter("ignore") - self.assertEqual(foo.__spec__.loader.module_repr(foo), - "<module 'foo' (namespace)>") + assert repr(foo).startswith("<module 'foo' (namespace) from [") class DynamicPathNamespacePackage(NamespacePackageTest): diff --git a/Lib/test/test_importlib/test_spec.py b/Lib/test/test_importlib/test_spec.py index 21e2c020..80aa3609 100644 --- a/Lib/test/test_importlib/test_spec.py +++ b/Lib/test/test_importlib/test_spec.py @@ -47,21 +47,6 @@ class NewLoader(TestLoader): module.eggs = self.EGGS -class LegacyLoader(TestLoader): - - HAM = -1 - - with warnings.catch_warnings(): - warnings.simplefilter("ignore", DeprecationWarning) - - frozen_util = util['Frozen'] - - @frozen_util.module_for_loader - def load_module(self, module): - module.ham = self.HAM - return module - - class ModuleSpecTests: def setUp(self): @@ -302,26 +287,6 @@ class ModuleSpecMethodsTests: loaded = self.bootstrap._load(self.spec) self.assertNotIn(self.spec.name, sys.modules) - def test_load_legacy(self): - with warnings.catch_warnings(): - warnings.simplefilter("ignore", ImportWarning) - self.spec.loader = LegacyLoader() - with CleanImport(self.spec.name): - loaded = self.bootstrap._load(self.spec) - - self.assertEqual(loaded.ham, -1) - - def test_load_legacy_attributes(self): - with warnings.catch_warnings(): - warnings.simplefilter("ignore", ImportWarning) - self.spec.loader = LegacyLoader() - with CleanImport(self.spec.name): - loaded = self.bootstrap._load(self.spec) - - self.assertIs(loaded.__loader__, self.spec.loader) - self.assertEqual(loaded.__package__, self.spec.parent) - self.assertIs(loaded.__spec__, self.spec) - def test_load_legacy_attributes_immutable(self): module = object() with warnings.catch_warnings(): @@ -387,19 +352,6 @@ class ModuleSpecMethodsTests: self.assertFalse(hasattr(loaded, '__file__')) self.assertFalse(hasattr(loaded, '__cached__')) - def test_reload_legacy(self): - with warnings.catch_warnings(): - warnings.simplefilter("ignore", ImportWarning) - self.spec.loader = LegacyLoader() - with CleanImport(self.spec.name): - loaded = self.bootstrap._load(self.spec) - reloaded = self.bootstrap._exec(self.spec, loaded) - installed = sys.modules[self.spec.name] - - self.assertEqual(loaded.ham, -1) - self.assertIs(reloaded, loaded) - self.assertIs(installed, loaded) - (Frozen_ModuleSpecMethodsTests, Source_ModuleSpecMethodsTests @@ -407,101 +359,6 @@ class ModuleSpecMethodsTests: machinery=machinery) -class ModuleReprTests: - - @property - def bootstrap(self): - return self.init._bootstrap - - def setUp(self): - self.module = type(os)('spam') - self.spec = self.machinery.ModuleSpec('spam', TestLoader()) - - def test_module___loader___module_repr(self): - class Loader: - def module_repr(self, module): - return '<delicious {}>'.format(module.__name__) - self.module.__loader__ = Loader() - modrepr = self.bootstrap._module_repr(self.module) - - self.assertEqual(modrepr, '<delicious spam>') - - def test_module___loader___module_repr_bad(self): - class Loader(TestLoader): - def module_repr(self, module): - raise Exception - self.module.__loader__ = Loader() - modrepr = self.bootstrap._module_repr(self.module) - - self.assertEqual(modrepr, - '<module {!r} (<TestLoader object>)>'.format('spam')) - - def test_module___spec__(self): - origin = 'in a hole, in the ground' - self.spec.origin = origin - self.module.__spec__ = self.spec - modrepr = self.bootstrap._module_repr(self.module) - - self.assertEqual(modrepr, '<module {!r} ({})>'.format('spam', origin)) - - def test_module___spec___location(self): - location = 'in_a_galaxy_far_far_away.py' - self.spec.origin = location - self.spec._set_fileattr = True - self.module.__spec__ = self.spec - modrepr = self.bootstrap._module_repr(self.module) - - self.assertEqual(modrepr, - '<module {!r} from {!r}>'.format('spam', location)) - - def test_module___spec___no_origin(self): - self.spec.loader = TestLoader() - self.module.__spec__ = self.spec - modrepr = self.bootstrap._module_repr(self.module) - - self.assertEqual(modrepr, - '<module {!r} (<TestLoader object>)>'.format('spam')) - - def test_module___spec___no_origin_no_loader(self): - self.spec.loader = None - self.module.__spec__ = self.spec - modrepr = self.bootstrap._module_repr(self.module) - - self.assertEqual(modrepr, '<module {!r}>'.format('spam')) - - def test_module_no_name(self): - del self.module.__name__ - modrepr = self.bootstrap._module_repr(self.module) - - self.assertEqual(modrepr, '<module {!r}>'.format('?')) - - def test_module_with_file(self): - filename = 'e/i/e/i/o/spam.py' - self.module.__file__ = filename - modrepr = self.bootstrap._module_repr(self.module) - - self.assertEqual(modrepr, - '<module {!r} from {!r}>'.format('spam', filename)) - - def test_module_no_file(self): - self.module.__loader__ = TestLoader() - modrepr = self.bootstrap._module_repr(self.module) - - self.assertEqual(modrepr, - '<module {!r} (<TestLoader object>)>'.format('spam')) - - def test_module_no_file_no_loader(self): - modrepr = self.bootstrap._module_repr(self.module) - - self.assertEqual(modrepr, '<module {!r}>'.format('spam')) - - -(Frozen_ModuleReprTests, - Source_ModuleReprTests - ) = test_util.test_both(ModuleReprTests, init=init, util=util, - machinery=machinery) - - class FactoryTests: def setUp(self): diff --git a/Lib/test/test_importlib/test_threaded_import.py b/Lib/test/test_importlib/test_threaded_import.py index 9aeeb5e6..68de4a66 100644 --- a/Lib/test/test_importlib/test_threaded_import.py +++ b/Lib/test/test_importlib/test_threaded_import.py @@ -15,7 +15,7 @@ import threading import unittest from unittest import mock from test.support import verbose -from test.support.import_helper import forget +from test.support.import_helper import forget, mock_register_at_fork from test.support.os_helper import (TESTFN, unlink, rmtree) from test.support import script_helper, threading_helper @@ -41,12 +41,6 @@ def task(N, done, done_tasks, errors): if finished: done.set() -def mock_register_at_fork(func): - # bpo-30599: Mock os.register_at_fork() when importing the random module, - # since this function doesn't allow to unregister callbacks and would leak - # memory. - return mock.patch('os.register_at_fork', create=True)(func) - # Create a circular import structure: A -> C -> B -> D -> A # NOTE: `time` is already loaded and therefore doesn't threaten to deadlock. @@ -244,7 +238,8 @@ class ThreadedImportTests(unittest.TestCase): self.addCleanup(forget, TESTFN) self.addCleanup(rmtree, '__pycache__') importlib.invalidate_caches() - __import__(TESTFN) + with threading_helper.wait_threads_exit(): + __import__(TESTFN) del sys.modules[TESTFN] def test_concurrent_futures_circular_import(self): diff --git a/Lib/test/test_importlib/test_util.py b/Lib/test/test_importlib/test_util.py index a62d68fc..217c1ad7 100644 --- a/Lib/test/test_importlib/test_util.py +++ b/Lib/test/test_importlib/test_util.py @@ -8,14 +8,29 @@ importlib_util = util.import_importlib('importlib.util') import importlib.util import os import pathlib +import re import string import sys from test import support +import textwrap import types import unittest import unittest.mock import warnings +try: + import _testsinglephase +except ImportError: + _testsinglephase = None +try: + import _testmultiphase +except ImportError: + _testmultiphase = None +try: + import _xxsubinterpreters as _interpreters +except ModuleNotFoundError: + _interpreters = None + class DecodeSourceBytesTests: @@ -121,247 +136,6 @@ class ModuleFromSpecTests: util=importlib_util) -class ModuleForLoaderTests: - - """Tests for importlib.util.module_for_loader.""" - - @classmethod - def module_for_loader(cls, func): - with warnings.catch_warnings(): - warnings.simplefilter('ignore', DeprecationWarning) - return cls.util.module_for_loader(func) - - def test_warning(self): - # Should raise a PendingDeprecationWarning when used. - with warnings.catch_warnings(): - warnings.simplefilter('error', DeprecationWarning) - with self.assertRaises(DeprecationWarning): - func = self.util.module_for_loader(lambda x: x) - - def return_module(self, name): - fxn = self.module_for_loader(lambda self, module: module) - return fxn(self, name) - - def raise_exception(self, name): - def to_wrap(self, module): - raise ImportError - fxn = self.module_for_loader(to_wrap) - try: - fxn(self, name) - except ImportError: - pass - - def test_new_module(self): - # Test that when no module exists in sys.modules a new module is - # created. - module_name = 'a.b.c' - with util.uncache(module_name): - module = self.return_module(module_name) - self.assertIn(module_name, sys.modules) - self.assertIsInstance(module, types.ModuleType) - self.assertEqual(module.__name__, module_name) - - def test_reload(self): - # Test that a module is reused if already in sys.modules. - class FakeLoader: - def is_package(self, name): - return True - @self.module_for_loader - def load_module(self, module): - return module - name = 'a.b.c' - module = types.ModuleType('a.b.c') - module.__loader__ = 42 - module.__package__ = 42 - with util.uncache(name): - sys.modules[name] = module - loader = FakeLoader() - returned_module = loader.load_module(name) - self.assertIs(returned_module, sys.modules[name]) - self.assertEqual(module.__loader__, loader) - self.assertEqual(module.__package__, name) - - def test_new_module_failure(self): - # Test that a module is removed from sys.modules if added but an - # exception is raised. - name = 'a.b.c' - with util.uncache(name): - self.raise_exception(name) - self.assertNotIn(name, sys.modules) - - def test_reload_failure(self): - # Test that a failure on reload leaves the module in-place. - name = 'a.b.c' - module = types.ModuleType(name) - with util.uncache(name): - sys.modules[name] = module - self.raise_exception(name) - self.assertIs(module, sys.modules[name]) - - def test_decorator_attrs(self): - def fxn(self, module): pass - wrapped = self.module_for_loader(fxn) - self.assertEqual(wrapped.__name__, fxn.__name__) - self.assertEqual(wrapped.__qualname__, fxn.__qualname__) - - def test_false_module(self): - # If for some odd reason a module is considered false, still return it - # from sys.modules. - class FalseModule(types.ModuleType): - def __bool__(self): return False - - name = 'mod' - module = FalseModule(name) - with util.uncache(name): - self.assertFalse(module) - sys.modules[name] = module - given = self.return_module(name) - self.assertIs(given, module) - - def test_attributes_set(self): - # __name__, __loader__, and __package__ should be set (when - # is_package() is defined; undefined implicitly tested elsewhere). - class FakeLoader: - def __init__(self, is_package): - self._pkg = is_package - def is_package(self, name): - return self._pkg - @self.module_for_loader - def load_module(self, module): - return module - - name = 'pkg.mod' - with util.uncache(name): - loader = FakeLoader(False) - module = loader.load_module(name) - self.assertEqual(module.__name__, name) - self.assertIs(module.__loader__, loader) - self.assertEqual(module.__package__, 'pkg') - - name = 'pkg.sub' - with util.uncache(name): - loader = FakeLoader(True) - module = loader.load_module(name) - self.assertEqual(module.__name__, name) - self.assertIs(module.__loader__, loader) - self.assertEqual(module.__package__, name) - - -(Frozen_ModuleForLoaderTests, - Source_ModuleForLoaderTests - ) = util.test_both(ModuleForLoaderTests, util=importlib_util) - - -class SetPackageTests: - - """Tests for importlib.util.set_package.""" - - def verify(self, module, expect): - """Verify the module has the expected value for __package__ after - passing through set_package.""" - fxn = lambda: module - wrapped = self.util.set_package(fxn) - with warnings.catch_warnings(): - warnings.simplefilter('ignore', DeprecationWarning) - wrapped() - self.assertTrue(hasattr(module, '__package__')) - self.assertEqual(expect, module.__package__) - - def test_top_level(self): - # __package__ should be set to the empty string if a top-level module. - # Implicitly tests when package is set to None. - module = types.ModuleType('module') - module.__package__ = None - self.verify(module, '') - - def test_package(self): - # Test setting __package__ for a package. - module = types.ModuleType('pkg') - module.__path__ = ['<path>'] - module.__package__ = None - self.verify(module, 'pkg') - - def test_submodule(self): - # Test __package__ for a module in a package. - module = types.ModuleType('pkg.mod') - module.__package__ = None - self.verify(module, 'pkg') - - def test_setting_if_missing(self): - # __package__ should be set if it is missing. - module = types.ModuleType('mod') - if hasattr(module, '__package__'): - delattr(module, '__package__') - self.verify(module, '') - - def test_leaving_alone(self): - # If __package__ is set and not None then leave it alone. - for value in (True, False): - module = types.ModuleType('mod') - module.__package__ = value - self.verify(module, value) - - def test_decorator_attrs(self): - def fxn(module): pass - with warnings.catch_warnings(): - warnings.simplefilter('ignore', DeprecationWarning) - wrapped = self.util.set_package(fxn) - self.assertEqual(wrapped.__name__, fxn.__name__) - self.assertEqual(wrapped.__qualname__, fxn.__qualname__) - - -(Frozen_SetPackageTests, - Source_SetPackageTests - ) = util.test_both(SetPackageTests, util=importlib_util) - - -class SetLoaderTests: - - """Tests importlib.util.set_loader().""" - - @property - def DummyLoader(self): - # Set DummyLoader on the class lazily. - class DummyLoader: - @self.util.set_loader - def load_module(self, module): - return self.module - self.__class__.DummyLoader = DummyLoader - return DummyLoader - - def test_no_attribute(self): - loader = self.DummyLoader() - loader.module = types.ModuleType('blah') - try: - del loader.module.__loader__ - except AttributeError: - pass - with warnings.catch_warnings(): - warnings.simplefilter('ignore', DeprecationWarning) - self.assertEqual(loader, loader.load_module('blah').__loader__) - - def test_attribute_is_None(self): - loader = self.DummyLoader() - loader.module = types.ModuleType('blah') - loader.module.__loader__ = None - with warnings.catch_warnings(): - warnings.simplefilter('ignore', DeprecationWarning) - self.assertEqual(loader, loader.load_module('blah').__loader__) - - def test_not_reset(self): - loader = self.DummyLoader() - loader.module = types.ModuleType('blah') - loader.module.__loader__ = 42 - with warnings.catch_warnings(): - warnings.simplefilter('ignore', DeprecationWarning) - self.assertEqual(42, loader.load_module('blah').__loader__) - - -(Frozen_SetLoaderTests, - Source_SetLoaderTests - ) = util.test_both(SetLoaderTests, util=importlib_util) - - class ResolveNameTests: """Tests importlib.util.resolve_name().""" @@ -860,7 +634,7 @@ class MagicNumberTests(unittest.TestCase): # stakeholders such as OS package maintainers must be notified # in advance. Such exceptional releases will then require an # adjustment to this test case. - EXPECTED_MAGIC_NUMBER = 3495 + EXPECTED_MAGIC_NUMBER = 3531 actual = int.from_bytes(importlib.util.MAGIC_NUMBER[:2], 'little') msg = ( @@ -878,5 +652,111 @@ class MagicNumberTests(unittest.TestCase): self.assertEqual(EXPECTED_MAGIC_NUMBER, actual, msg) +@unittest.skipIf(_interpreters is None, 'subinterpreters required') +class IncompatibleExtensionModuleRestrictionsTests(unittest.TestCase): + + ERROR = re.compile("^<class 'ImportError'>: module (.*) does not support loading in subinterpreters") + + def run_with_own_gil(self, script): + interpid = _interpreters.create(isolated=True) + try: + _interpreters.run_string(interpid, script) + except _interpreters.RunFailedError as exc: + if m := self.ERROR.match(str(exc)): + modname, = m.groups() + raise ImportError(modname) + + def run_with_shared_gil(self, script): + interpid = _interpreters.create(isolated=False) + try: + _interpreters.run_string(interpid, script) + except _interpreters.RunFailedError as exc: + if m := self.ERROR.match(str(exc)): + modname, = m.groups() + raise ImportError(modname) + + @unittest.skipIf(_testsinglephase is None, "test requires _testsinglephase module") + def test_single_phase_init_module(self): + script = textwrap.dedent(''' + from importlib.util import _incompatible_extension_module_restrictions + with _incompatible_extension_module_restrictions(disable_check=True): + import _testsinglephase + ''') + with self.subTest('check disabled, shared GIL'): + self.run_with_shared_gil(script) + with self.subTest('check disabled, per-interpreter GIL'): + self.run_with_own_gil(script) + + script = textwrap.dedent(f''' + from importlib.util import _incompatible_extension_module_restrictions + with _incompatible_extension_module_restrictions(disable_check=False): + import _testsinglephase + ''') + with self.subTest('check enabled, shared GIL'): + with self.assertRaises(ImportError): + self.run_with_shared_gil(script) + with self.subTest('check enabled, per-interpreter GIL'): + with self.assertRaises(ImportError): + self.run_with_own_gil(script) + + @unittest.skipIf(_testmultiphase is None, "test requires _testmultiphase module") + def test_incomplete_multi_phase_init_module(self): + prescript = textwrap.dedent(f''' + from importlib.util import spec_from_loader, module_from_spec + from importlib.machinery import ExtensionFileLoader + + name = '_test_shared_gil_only' + filename = {_testmultiphase.__file__!r} + loader = ExtensionFileLoader(name, filename) + spec = spec_from_loader(name, loader) + + ''') + + script = prescript + textwrap.dedent(''' + from importlib.util import _incompatible_extension_module_restrictions + with _incompatible_extension_module_restrictions(disable_check=True): + module = module_from_spec(spec) + loader.exec_module(module) + ''') + with self.subTest('check disabled, shared GIL'): + self.run_with_shared_gil(script) + with self.subTest('check disabled, per-interpreter GIL'): + self.run_with_own_gil(script) + + script = prescript + textwrap.dedent(''' + from importlib.util import _incompatible_extension_module_restrictions + with _incompatible_extension_module_restrictions(disable_check=False): + module = module_from_spec(spec) + loader.exec_module(module) + ''') + with self.subTest('check enabled, shared GIL'): + self.run_with_shared_gil(script) + with self.subTest('check enabled, per-interpreter GIL'): + with self.assertRaises(ImportError): + self.run_with_own_gil(script) + + @unittest.skipIf(_testmultiphase is None, "test requires _testmultiphase module") + def test_complete_multi_phase_init_module(self): + script = textwrap.dedent(''' + from importlib.util import _incompatible_extension_module_restrictions + with _incompatible_extension_module_restrictions(disable_check=True): + import _testmultiphase + ''') + with self.subTest('check disabled, shared GIL'): + self.run_with_shared_gil(script) + with self.subTest('check disabled, per-interpreter GIL'): + self.run_with_own_gil(script) + + script = textwrap.dedent(f''' + from importlib.util import _incompatible_extension_module_restrictions + with _incompatible_extension_module_restrictions(disable_check=False): + import _testmultiphase + ''') + with self.subTest('check enabled, shared GIL'): + self.run_with_shared_gil(script) + with self.subTest('check enabled, per-interpreter GIL'): + self.run_with_own_gil(script) + + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_importlib/test_windows.py b/Lib/test/test_importlib/test_windows.py index b7dfe865..40b8aa17 100644 --- a/Lib/test/test_importlib/test_windows.py +++ b/Lib/test/test_importlib/test_windows.py @@ -92,30 +92,16 @@ class WindowsRegistryFinderTests: def test_find_spec_missing(self): spec = self.machinery.WindowsRegistryFinder.find_spec('spam') - self.assertIs(spec, None) - - def test_find_module_missing(self): - with warnings.catch_warnings(): - warnings.simplefilter("ignore", DeprecationWarning) - loader = self.machinery.WindowsRegistryFinder.find_module('spam') - self.assertIs(loader, None) + self.assertIsNone(spec) def test_module_found(self): with setup_module(self.machinery, self.test_module): - with warnings.catch_warnings(): - warnings.simplefilter("ignore", DeprecationWarning) - loader = self.machinery.WindowsRegistryFinder.find_module(self.test_module) spec = self.machinery.WindowsRegistryFinder.find_spec(self.test_module) - self.assertIsNot(loader, None) - self.assertIsNot(spec, None) + self.assertIsNotNone(spec) def test_module_not_found(self): with setup_module(self.machinery, self.test_module, path="."): - with warnings.catch_warnings(): - warnings.simplefilter("ignore", DeprecationWarning) - loader = self.machinery.WindowsRegistryFinder.find_module(self.test_module) spec = self.machinery.WindowsRegistryFinder.find_spec(self.test_module) - self.assertIsNone(loader) self.assertIsNone(spec) (Frozen_WindowsRegistryFinderTests, diff --git a/Lib/test/test_importlib/util.py b/Lib/test/test_importlib/util.py index 0b6dcc5e..c25be096 100644 --- a/Lib/test/test_importlib/util.py +++ b/Lib/test/test_importlib/util.py @@ -27,7 +27,7 @@ EXTENSIONS.path = None EXTENSIONS.ext = None EXTENSIONS.filename = None EXTENSIONS.file_path = None -EXTENSIONS.name = '_testcapi' +EXTENSIONS.name = '_testsinglephase' def _extension_details(): global EXTENSIONS @@ -131,9 +131,8 @@ def uncache(*names): """ for name in names: - if name in ('sys', 'marshal', 'imp'): - raise ValueError( - "cannot uncache {0}".format(name)) + if name in ('sys', 'marshal'): + raise ValueError("cannot uncache {}".format(name)) try: del sys.modules[name] except KeyError: @@ -195,8 +194,7 @@ def import_state(**kwargs): new_value = default setattr(sys, attr, new_value) if len(kwargs): - raise ValueError( - 'unrecognized arguments: {0}'.format(kwargs.keys())) + raise ValueError('unrecognized arguments: {}'.format(kwargs)) yield finally: for attr, value in originals.items(): @@ -244,30 +242,6 @@ class _ImporterMock: self._uncache.__exit__(None, None, None) -class mock_modules(_ImporterMock): - - """Importer mock using PEP 302 APIs.""" - - def find_module(self, fullname, path=None): - if fullname not in self.modules: - return None - else: - return self - - def load_module(self, fullname): - if fullname not in self.modules: - raise ImportError - else: - sys.modules[fullname] = self.modules[fullname] - if fullname in self.module_code: - try: - self.module_code[fullname]() - except Exception: - del sys.modules[fullname] - raise - return self.modules[fullname] - - class mock_spec(_ImporterMock): """Importer mock using PEP 451 APIs.""" diff --git a/Lib/test/test_inspect.py b/Lib/test/test_inspect.py index 9ea49854..d89953ab 100644 --- a/Lib/test/test_inspect.py +++ b/Lib/test/test_inspect.py @@ -1,3 +1,4 @@ +import asyncio import builtins import collections import datetime @@ -65,6 +66,11 @@ def revise(filename, *args): git = mod.StupidGit() +def tearDownModule(): + if support.has_socket_support: + asyncio.set_event_loop_policy(None) + + def signatures_with_lexicographic_keyword_only_parameters(): """ Yields a whole bunch of functions with only keyword-only parameters, @@ -202,6 +208,59 @@ class TestPredicates(IsTestBase): gen_coroutine_function_example)))) self.assertTrue(inspect.isgenerator(gen_coro)) + async def _fn3(): + pass + + @inspect.markcoroutinefunction + def fn3(): + return _fn3() + + self.assertTrue(inspect.iscoroutinefunction(fn3)) + self.assertTrue( + inspect.iscoroutinefunction( + inspect.markcoroutinefunction(lambda: _fn3()) + ) + ) + + class Cl: + async def __call__(self): + pass + + self.assertFalse(inspect.iscoroutinefunction(Cl)) + # instances with async def __call__ are NOT recognised. + self.assertFalse(inspect.iscoroutinefunction(Cl())) + # unless explicitly marked. + self.assertTrue(inspect.iscoroutinefunction( + inspect.markcoroutinefunction(Cl()) + )) + + class Cl2: + @inspect.markcoroutinefunction + def __call__(self): + pass + + self.assertFalse(inspect.iscoroutinefunction(Cl2)) + # instances with marked __call__ are NOT recognised. + self.assertFalse(inspect.iscoroutinefunction(Cl2())) + # unless explicitly marked. + self.assertTrue(inspect.iscoroutinefunction( + inspect.markcoroutinefunction(Cl2()) + )) + + class Cl3: + @inspect.markcoroutinefunction + @classmethod + def do_something_classy(cls): + pass + + @inspect.markcoroutinefunction + @staticmethod + def do_something_static(): + pass + + self.assertTrue(inspect.iscoroutinefunction(Cl3.do_something_classy)) + self.assertTrue(inspect.iscoroutinefunction(Cl3.do_something_static)) + self.assertFalse( inspect.iscoroutinefunction(unittest.mock.Mock())) self.assertTrue( @@ -371,7 +430,7 @@ class TestInterpreterStack(IsTestBase): git.abuse(7, 8, 9) def test_abuse_done(self): - self.istest(inspect.istraceback, 'git.ex[2]') + self.istest(inspect.istraceback, 'git.ex.__traceback__') self.istest(inspect.isframe, 'mod.fr') def test_stack(self): @@ -498,7 +557,8 @@ class TestRetrievingSourceCode(GetSourceBase): def test_getfunctions(self): functions = inspect.getmembers(mod, inspect.isfunction) - self.assertEqual(functions, [('eggs', mod.eggs), + self.assertEqual(functions, [('after_closing', mod.after_closing), + ('eggs', mod.eggs), ('lobbest', mod.lobbest), ('spam', mod.spam)]) @@ -582,6 +642,7 @@ class TestRetrievingSourceCode(GetSourceBase): self.assertSourceEqual(git.abuse, 29, 39) self.assertSourceEqual(mod.StupidGit, 21, 51) self.assertSourceEqual(mod.lobbest, 75, 76) + self.assertSourceEqual(mod.after_closing, 120, 120) def test_getsourcefile(self): self.assertEqual(normcase(inspect.getsourcefile(mod.spam)), modfile) @@ -717,6 +778,22 @@ class TestOneliners(GetSourceBase): # where the second line _is_ indented. self.assertSourceEqual(mod2.tlli, 33, 34) + def test_parenthesized_multiline_lambda(self): + # Test inspect.getsource with a parenthesized multi-line lambda + # function. + self.assertSourceEqual(mod2.parenthesized_lambda, 279, 279) + self.assertSourceEqual(mod2.parenthesized_lambda2, 281, 281) + self.assertSourceEqual(mod2.parenthesized_lambda3, 283, 283) + + def test_post_line_parenthesized_lambda(self): + # Test inspect.getsource with a parenthesized multi-line lambda + # function. + self.assertSourceEqual(mod2.post_line_parenthesized_lambda1, 286, 287) + + def test_nested_lambda(self): + # Test inspect.getsource with a nested lambda function. + self.assertSourceEqual(mod2.nested_lambda, 291, 292) + def test_onelinefunc(self): # Test inspect.getsource with a regular one-line function. self.assertSourceEqual(mod2.onelinefunc, 37, 37) @@ -1761,8 +1838,7 @@ class TestGetcallargsFunctions(unittest.TestCase): self.assertEqualException(f, '2, 3, 4') self.assertEqualException(f, '1, 2, 3, a=1') self.assertEqualException(f, '2, 3, 4, c=5') - # XXX: success of this one depends on dict order - ## self.assertEqualException(f, '2, 3, 4, a=1, c=5') + self.assertEqualException(f, '2, 3, 4, a=1, c=5') # f got an unexpected keyword argument self.assertEqualException(f, 'c=2') self.assertEqualException(f, '2, c=3') @@ -1773,17 +1849,19 @@ class TestGetcallargsFunctions(unittest.TestCase): self.assertEqualException(f, '1, a=2') self.assertEqualException(f, '1, **{"a":2}') self.assertEqualException(f, '1, 2, b=3') - # XXX: Python inconsistency - # - for functions and bound methods: unexpected keyword 'c' - # - for unbound methods: multiple values for keyword 'a' - #self.assertEqualException(f, '1, c=3, a=2') + self.assertEqualException(f, '1, c=3, a=2') # issue11256: f3 = self.makeCallable('**c') self.assertEqualException(f3, '1, 2') self.assertEqualException(f3, '1, 2, a=1, b=2') f4 = self.makeCallable('*, a, b=0') - self.assertEqualException(f3, '1, 2') - self.assertEqualException(f3, '1, 2, a=1, b=2') + self.assertEqualException(f4, '1, 2') + self.assertEqualException(f4, '1, 2, a=1, b=2') + self.assertEqualException(f4, 'a=1, a=3') + self.assertEqualException(f4, 'a=1, c=3') + self.assertEqualException(f4, 'a=1, a=3, b=4') + self.assertEqualException(f4, 'a=1, b=2, a=3, b=4') + self.assertEqualException(f4, 'a=1, a=2, a=3, b=4') # issue #20816: getcallargs() fails to iterate over non-existent # kwonlydefaults and raises a wrong TypeError @@ -1992,6 +2070,9 @@ class TestGetattrStatic(unittest.TestCase): descriptor.__set__ = lambda s, i, v: None self.assertEqual(inspect.getattr_static(foo, 'd'), Foo.__dict__['d']) + del descriptor.__set__ + descriptor.__delete__ = lambda s, i, o: None + self.assertEqual(inspect.getattr_static(foo, 'd'), Foo.__dict__['d']) def test_metaclass_with_descriptor(self): class descriptor(object): @@ -2051,6 +2132,28 @@ class TestGetattrStatic(unittest.TestCase): self.assertEqual(inspect.getattr_static(foo, 'a'), 3) self.assertFalse(test.called) + def test_mutated_mro(self): + test = self + test.called = False + + class Foo(dict): + a = 3 + @property + def __dict__(self): + test.called = True + return {} + + class Bar(dict): + a = 4 + + class Baz(Bar): pass + + baz = Baz() + self.assertEqual(inspect.getattr_static(baz, 'a'), 4) + Baz.__bases__ = (Foo,) + self.assertEqual(inspect.getattr_static(baz, 'a'), 3) + self.assertFalse(test.called) + def test_custom_object_dict(self): test = self test.called = False @@ -2105,6 +2208,35 @@ class TestGetattrStatic(unittest.TestCase): inspect.getattr_static(Thing, "spam") self.assertFalse(Thing.executed) + def test_custom___getattr__(self): + test = self + test.called = False + + class Foo: + def __getattr__(self, attr): + test.called = True + return {} + + with self.assertRaises(AttributeError): + inspect.getattr_static(Foo(), 'whatever') + + self.assertFalse(test.called) + + def test_custom___getattribute__(self): + test = self + test.called = False + + class Foo: + def __getattribute__(self, attr): + test.called = True + return {} + + with self.assertRaises(AttributeError): + inspect.getattr_static(Foo(), 'really_could_be_anything') + + self.assertFalse(test.called) + + class TestGetGeneratorState(unittest.TestCase): def setUp(self): @@ -2268,6 +2400,109 @@ class TestGetCoroutineState(unittest.TestCase): {'a': None, 'gencoro': gencoro, 'b': 'spam'}) +@support.requires_working_socket() +class TestGetAsyncGenState(unittest.IsolatedAsyncioTestCase): + + def setUp(self): + async def number_asyncgen(): + for number in range(5): + yield number + self.asyncgen = number_asyncgen() + + async def asyncTearDown(self): + await self.asyncgen.aclose() + + def _asyncgenstate(self): + return inspect.getasyncgenstate(self.asyncgen) + + def test_created(self): + self.assertEqual(self._asyncgenstate(), inspect.AGEN_CREATED) + + async def test_suspended(self): + value = await anext(self.asyncgen) + self.assertEqual(self._asyncgenstate(), inspect.AGEN_SUSPENDED) + self.assertEqual(value, 0) + + async def test_closed_after_exhaustion(self): + countdown = 7 + with self.assertRaises(StopAsyncIteration): + while countdown := countdown - 1: + await anext(self.asyncgen) + self.assertEqual(countdown, 1) + self.assertEqual(self._asyncgenstate(), inspect.AGEN_CLOSED) + + async def test_closed_after_immediate_exception(self): + with self.assertRaises(RuntimeError): + await self.asyncgen.athrow(RuntimeError) + self.assertEqual(self._asyncgenstate(), inspect.AGEN_CLOSED) + + async def test_running(self): + async def running_check_asyncgen(): + for number in range(5): + self.assertEqual(self._asyncgenstate(), inspect.AGEN_RUNNING) + yield number + self.assertEqual(self._asyncgenstate(), inspect.AGEN_RUNNING) + self.asyncgen = running_check_asyncgen() + # Running up to the first yield + await anext(self.asyncgen) + self.assertEqual(self._asyncgenstate(), inspect.AGEN_SUSPENDED) + # Running after the first yield + await anext(self.asyncgen) + self.assertEqual(self._asyncgenstate(), inspect.AGEN_SUSPENDED) + + def test_easy_debugging(self): + # repr() and str() of a asyncgen state should contain the state name + names = 'AGEN_CREATED AGEN_RUNNING AGEN_SUSPENDED AGEN_CLOSED'.split() + for name in names: + state = getattr(inspect, name) + self.assertIn(name, repr(state)) + self.assertIn(name, str(state)) + + async def test_getasyncgenlocals(self): + async def each(lst, a=None): + b=(1, 2, 3) + for v in lst: + if v == 3: + c = 12 + yield v + + numbers = each([1, 2, 3]) + self.assertEqual(inspect.getasyncgenlocals(numbers), + {'a': None, 'lst': [1, 2, 3]}) + await anext(numbers) + self.assertEqual(inspect.getasyncgenlocals(numbers), + {'a': None, 'lst': [1, 2, 3], 'v': 1, + 'b': (1, 2, 3)}) + await anext(numbers) + self.assertEqual(inspect.getasyncgenlocals(numbers), + {'a': None, 'lst': [1, 2, 3], 'v': 2, + 'b': (1, 2, 3)}) + await anext(numbers) + self.assertEqual(inspect.getasyncgenlocals(numbers), + {'a': None, 'lst': [1, 2, 3], 'v': 3, + 'b': (1, 2, 3), 'c': 12}) + with self.assertRaises(StopAsyncIteration): + await anext(numbers) + self.assertEqual(inspect.getasyncgenlocals(numbers), {}) + + async def test_getasyncgenlocals_empty(self): + async def yield_one(): + yield 1 + one = yield_one() + self.assertEqual(inspect.getasyncgenlocals(one), {}) + await anext(one) + self.assertEqual(inspect.getasyncgenlocals(one), {}) + with self.assertRaises(StopAsyncIteration): + await anext(one) + self.assertEqual(inspect.getasyncgenlocals(one), {}) + + def test_getasyncgenlocals_error(self): + self.assertRaises(TypeError, inspect.getasyncgenlocals, 1) + self.assertRaises(TypeError, inspect.getasyncgenlocals, lambda x: True) + self.assertRaises(TypeError, inspect.getasyncgenlocals, set) + self.assertRaises(TypeError, inspect.getasyncgenlocals, (2,3)) + + class MySignature(inspect.Signature): # Top-level to make it picklable; # used in test_signature_object_pickle @@ -2300,18 +2535,43 @@ class TestSignatureObject(unittest.TestCase): self.assertEqual(str(S()), '()') self.assertEqual(repr(S().parameters), 'mappingproxy(OrderedDict())') - def test(po, pk, pod=42, pkd=100, *args, ko, **kwargs): + def test(po, /, pk, pkd=100, *args, ko, kod=10, **kwargs): pass + sig = inspect.signature(test) - po = sig.parameters['po'].replace(kind=P.POSITIONAL_ONLY) - pod = sig.parameters['pod'].replace(kind=P.POSITIONAL_ONLY) + self.assertTrue(repr(sig).startswith('<Signature')) + self.assertTrue('(po, /, pk' in repr(sig)) + + # We need two functions, because it is impossible to represent + # all param kinds in a single one. + def test2(pod=42, /): + pass + + sig2 = inspect.signature(test2) + self.assertTrue(repr(sig2).startswith('<Signature')) + self.assertTrue('(pod=42, /)' in repr(sig2)) + + po = sig.parameters['po'] + pod = sig2.parameters['pod'] pk = sig.parameters['pk'] pkd = sig.parameters['pkd'] args = sig.parameters['args'] ko = sig.parameters['ko'] + kod = sig.parameters['kod'] kwargs = sig.parameters['kwargs'] S((po, pk, args, ko, kwargs)) + S((po, pk, ko, kod)) + S((po, pod, ko)) + S((po, pod, kod)) + S((pod, ko, kod)) + S((pod, kod)) + S((pod, args, kod, kwargs)) + # keyword-only parameters without default values + # can follow keyword-only parameters with default values: + S((kod, ko)) + S((kod, ko, kwargs)) + S((args, kod, ko)) with self.assertRaisesRegex(ValueError, 'wrong parameter order'): S((pk, po, args, ko, kwargs)) @@ -2332,15 +2592,18 @@ class TestSignatureObject(unittest.TestCase): with self.assertRaisesRegex(ValueError, 'follows default argument'): S((pod, po)) + with self.assertRaisesRegex(ValueError, 'follows default argument'): + S((pod, pk)) + + with self.assertRaisesRegex(ValueError, 'follows default argument'): + S((po, pod, pk)) + with self.assertRaisesRegex(ValueError, 'follows default argument'): S((po, pkd, pk)) with self.assertRaisesRegex(ValueError, 'follows default argument'): S((pkd, pk)) - self.assertTrue(repr(sig).startswith('<Signature')) - self.assertTrue('(po, pk' in repr(sig)) - def test_signature_object_pickle(self): def foo(a, b, *, c:1={}, **kw) -> {42:'ham'}: pass foo_partial = functools.partial(foo, a=1) @@ -2521,6 +2784,11 @@ class TestSignatureObject(unittest.TestCase): # Regression test for issue #20586 test_callable(_testcapi.docstring_with_signature_but_no_doc) + # Regression test for gh-104955 + method = bytearray.__release_buffer__ + sig = test_unbound_method(method) + self.assertEqual(list(sig.parameters), ['self', 'buffer']) + @cpython_only @unittest.skipIf(MISSING_C_DOCSTRINGS, "Signature information for builtins requires docstrings") @@ -2710,8 +2978,6 @@ class TestSignatureObject(unittest.TestCase): def test_signature_on_partial(self): from functools import partial - Parameter = inspect.Parameter - def test(): pass @@ -2826,8 +3092,6 @@ class TestSignatureObject(unittest.TestCase): ((('c', ..., int, "positional_or_keyword"),), 42)) - psig = inspect.signature(partial(partial(test, 1), 2)) - def foo(a): return a _foo = partial(partial(foo, a=10), a=20) @@ -2882,14 +3146,9 @@ class TestSignatureObject(unittest.TestCase): self.assertEqual(_foo(*ba.args, **ba.kwargs), (12, 10, 20)) - def foo(a, b, c, d, **kwargs): + def foo(a, b, /, c, d, **kwargs): pass sig = inspect.signature(foo) - params = sig.parameters.copy() - params['a'] = params['a'].replace(kind=Parameter.POSITIONAL_ONLY) - params['b'] = params['b'].replace(kind=Parameter.POSITIONAL_ONLY) - foo.__signature__ = inspect.Signature(params.values()) - sig = inspect.signature(foo) self.assertEqual(str(sig), '(a, b, /, c, d, **kwargs)') self.assertEqual(self.signature(partial(foo, 1)), @@ -3238,6 +3497,25 @@ class TestSignatureObject(unittest.TestCase): ((('a', 10, ..., "positional_or_keyword"),), ...)) + def test_signature_on_mocks(self): + # https://github.com/python/cpython/issues/96127 + for mock in ( + unittest.mock.Mock(), + unittest.mock.AsyncMock(), + unittest.mock.MagicMock(), + ): + with self.subTest(mock=mock): + self.assertEqual(str(inspect.signature(mock)), '(*args, **kwargs)') + + def test_signature_on_noncallable_mocks(self): + for mock in ( + unittest.mock.NonCallableMock(), + unittest.mock.NonCallableMagicMock(), + ): + with self.subTest(mock=mock): + with self.assertRaises(TypeError): + inspect.signature(mock) + def test_signature_equality(self): def foo(a, *, b:int) -> float: pass self.assertFalse(inspect.signature(foo) == 42) @@ -3375,14 +3653,9 @@ class TestSignatureObject(unittest.TestCase): P = inspect.Parameter S = inspect.Signature - def test(a_po, *, b, **kwargs): + def test(a_po, /, *, b, **kwargs): return a_po, kwargs - sig = inspect.signature(test) - new_params = list(sig.parameters.values()) - new_params[0] = new_params[0].replace(kind=P.POSITIONAL_ONLY) - test.__signature__ = sig.replace(parameters=new_params) - self.assertEqual(str(inspect.signature(test)), '(a_po, /, *, b, **kwargs)') @@ -3412,6 +3685,14 @@ class TestSignatureObject(unittest.TestCase): self.assertEqual(sig.return_annotation, 42) self.assertEqual(sig, inspect.signature(test)) + def test_signature_replaced(self): + def test(): + pass + + spam_param = inspect.Parameter('spam', inspect.Parameter.POSITIONAL_ONLY) + sig = test.__signature__ = inspect.Signature(parameters=(spam_param,)) + self.assertEqual(sig, inspect.signature(test)) + def test_signature_on_mangled_parameters(self): class Spam: def foo(self, __p1:1=2, *, __p2:2=3): @@ -3614,6 +3895,56 @@ class TestSignatureObject(unittest.TestCase): self.assertEqual(signature_func(foo), inspect.Signature()) self.assertEqual(inspect.get_annotations(foo), {}) + def test_signature_as_str(self): + self.maxDiff = None + class S: + __signature__ = '(a, b=2)' + + self.assertEqual(self.signature(S), + ((('a', ..., ..., 'positional_or_keyword'), + ('b', 2, ..., 'positional_or_keyword')), + ...)) + + def test_signature_as_callable(self): + # __signature__ should be either a staticmethod or a bound classmethod + class S: + @classmethod + def __signature__(cls): + return '(a, b=2)' + + self.assertEqual(self.signature(S), + ((('a', ..., ..., 'positional_or_keyword'), + ('b', 2, ..., 'positional_or_keyword')), + ...)) + + class S: + @staticmethod + def __signature__(): + return '(a, b=2)' + + self.assertEqual(self.signature(S), + ((('a', ..., ..., 'positional_or_keyword'), + ('b', 2, ..., 'positional_or_keyword')), + ...)) + + def test_signature_on_derived_classes(self): + # gh-105080: Make sure that signatures are consistent on derived classes + + class B: + def __new__(self, *args, **kwargs): + return super().__new__(self) + def __init__(self, value): + self.value = value + + class D1(B): + def __init__(self, value): + super().__init__(value) + + class D2(D1): + pass + + self.assertEqual(inspect.signature(D2), inspect.signature(D1)) + class TestParameterObject(unittest.TestCase): def test_signature_parameter_kinds(self): @@ -3909,7 +4240,8 @@ class TestSignatureBind(unittest.TestCase): self.call(test, 1, bar=2, spam='ham') with self.assertRaisesRegex(TypeError, - "missing a required argument: 'bar'"): + "missing a required keyword-only " + "argument: 'bar'"): self.call(test, 1) def test(foo, *, bar, **bin): @@ -3941,18 +4273,9 @@ class TestSignatureBind(unittest.TestCase): self.assertEqual(ba.args, (10, 20)) def test_signature_bind_positional_only(self): - P = inspect.Parameter - - def test(a_po, b_po, c_po=3, foo=42, *, bar=50, **kwargs): + def test(a_po, b_po, c_po=3, /, foo=42, *, bar=50, **kwargs): return a_po, b_po, c_po, foo, bar, kwargs - sig = inspect.signature(test) - new_params = collections.OrderedDict(tuple(sig.parameters.items())) - for name in ('a_po', 'b_po', 'c_po'): - new_params[name] = new_params[name].replace(kind=P.POSITIONAL_ONLY) - new_sig = sig.replace(parameters=new_params.values()) - test.__signature__ = new_sig - self.assertEqual(self.call(test, 1, 2, 4, 5, bar=6), (1, 2, 4, 5, 6, {})) @@ -4001,14 +4324,14 @@ class TestSignatureBind(unittest.TestCase): @cpython_only def test_signature_bind_implicit_arg(self): - # Issue #19611: getcallargs should work with set comprehensions + # Issue #19611: getcallargs should work with comprehensions def make_set(): - return {z * z for z in range(5)} - setcomp_code = make_set.__code__.co_consts[1] - setcomp_func = types.FunctionType(setcomp_code, {}) + return set(z * z for z in range(5)) + gencomp_code = make_set.__code__.co_consts[1] + gencomp_func = types.FunctionType(gencomp_code, {}) iterator = iter(range(5)) - self.assertEqual(self.call(setcomp_func, iterator), {0, 1, 4, 9, 16}) + self.assertEqual(set(self.call(gencomp_func, iterator)), {0, 1, 4, 9, 16}) def test_signature_bind_posonly_kwargs(self): def foo(bar, /, **kwargs): @@ -4125,56 +4448,47 @@ class TestBoundArguments(unittest.TestCase): class TestSignaturePrivateHelpers(unittest.TestCase): def _strip_non_python_syntax(self, input, - clean_signature, self_parameter, last_positional_only): + clean_signature, self_parameter): computed_clean_signature, \ - computed_self_parameter, \ - computed_last_positional_only = \ + computed_self_parameter = \ inspect._signature_strip_non_python_syntax(input) self.assertEqual(computed_clean_signature, clean_signature) self.assertEqual(computed_self_parameter, self_parameter) - self.assertEqual(computed_last_positional_only, last_positional_only) def test_signature_strip_non_python_syntax(self): self._strip_non_python_syntax( "($module, /, path, mode, *, dir_fd=None, " + "effective_ids=False,\n follow_symlinks=True)", - "(module, path, mode, *, dir_fd=None, " + + "(module, /, path, mode, *, dir_fd=None, " + "effective_ids=False, follow_symlinks=True)", - 0, 0) self._strip_non_python_syntax( "($module, word, salt, /)", - "(module, word, salt)", - 0, - 2) + "(module, word, salt, /)", + 0) self._strip_non_python_syntax( "(x, y=None, z=None, /)", - "(x, y=None, z=None)", - None, - 2) + "(x, y=None, z=None, /)", + None) self._strip_non_python_syntax( "(x, y=None, z=None)", "(x, y=None, z=None)", - None, None) self._strip_non_python_syntax( "(x,\n y=None,\n z = None )", "(x, y=None, z=None)", - None, None) self._strip_non_python_syntax( "", "", - None, None) self._strip_non_python_syntax( - None, None, None, None) @@ -4382,7 +4696,6 @@ class TestMain(unittest.TestCase): self.assertEqual(err, b'') def test_builtins(self): - module = importlib.import_module('unittest') _, out, err = assert_python_failure('-m', 'inspect', 'sys') lines = err.decode().splitlines() @@ -4395,8 +4708,11 @@ class TestMain(unittest.TestCase): 'unittest', '--details') output = out.decode() # Just a quick sanity check on the output + self.assertIn(module.__spec__.name, output) self.assertIn(module.__name__, output) + self.assertIn(module.__spec__.origin, output) self.assertIn(module.__file__, output) + self.assertIn(module.__spec__.cached, output) self.assertIn(module.__cached__, output) self.assertEqual(err, b'') diff --git a/Lib/test/test_int.py b/Lib/test/test_int.py index c972b8af..5545ee39 100644 --- a/Lib/test/test_int.py +++ b/Lib/test/test_int.py @@ -2,10 +2,16 @@ import sys import time import unittest +from unittest import mock from test import support from test.test_grammar import (VALID_UNDERSCORE_LITERALS, INVALID_UNDERSCORE_LITERALS) +try: + import _pylong +except ImportError: + _pylong = None + L = [ ('0', 0), ('1', 1), @@ -149,6 +155,8 @@ class IntTestCases(unittest.TestCase): self.assertEqual(int(' 0O123 ', 0), 83) self.assertEqual(int(' 0X123 ', 0), 291) self.assertEqual(int(' 0B100 ', 0), 4) + with self.assertRaises(ValueError): + int('010', 0) # without base still base 10 self.assertEqual(int('0123'), 123) @@ -215,6 +223,24 @@ class IntTestCases(unittest.TestCase): self.assertEqual(int('2br45qc', 35), 4294967297) self.assertEqual(int('1z141z5', 36), 4294967297) + def test_invalid_signs(self): + with self.assertRaises(ValueError): + int('+') + with self.assertRaises(ValueError): + int('-') + with self.assertRaises(ValueError): + int('- 1') + with self.assertRaises(ValueError): + int('+ 1') + with self.assertRaises(ValueError): + int(' + 1 ') + + def test_unicode(self): + self.assertEqual(int("१२३४५६७८९०1234567890"), 12345678901234567890) + self.assertEqual(int('١٢٣٤٥٦٧٨٩٠'), 1234567890) + self.assertEqual(int("१२३४५६७८९०1234567890", 0), 12345678901234567890) + self.assertEqual(int('١٢٣٤٥٦٧٨٩٠', 0), 1234567890) + def test_underscores(self): for lit in VALID_UNDERSCORE_LITERALS: if any(ch in lit for ch in '.eEjJ'): @@ -770,10 +796,110 @@ class IntStrDigitLimitsTests(unittest.TestCase): with self.subTest(base=base): self._other_base_helper(base) + def test_int_max_str_digits_is_per_interpreter(self): + # Changing the limit in one interpreter does not change others. + code = """if 1: + # Subinterpreters maintain and enforce their own limit + import sys + sys.set_int_max_str_digits(2323) + try: + int('3'*3333) + except ValueError: + pass + else: + raise AssertionError('Expected a int max str digits ValueError.') + """ + with support.adjust_int_max_str_digits(4000): + before_value = sys.get_int_max_str_digits() + self.assertEqual(support.run_in_subinterp(code), 0, + 'subinterp code failure, check stderr.') + after_value = sys.get_int_max_str_digits() + self.assertEqual(before_value, after_value) + class IntSubclassStrDigitLimitsTests(IntStrDigitLimitsTests): int_class = IntSubclass +class PyLongModuleTests(unittest.TestCase): + # Tests of the functions in _pylong.py. Those get used when the + # number of digits in the input values are large enough. + + def setUp(self): + super().setUp() + self._previous_limit = sys.get_int_max_str_digits() + sys.set_int_max_str_digits(0) + + def tearDown(self): + sys.set_int_max_str_digits(self._previous_limit) + super().tearDown() + + def test_pylong_int_to_decimal(self): + n = (1 << 100_000) - 1 + suffix = '9883109375' + s = str(n) + assert s[-10:] == suffix + s = str(-n) + assert s[-10:] == suffix + s = '%d' % n + assert s[-10:] == suffix + s = b'%d' % n + assert s[-10:] == suffix.encode('ascii') + + def test_pylong_int_divmod(self): + n = (1 << 100_000) + a, b = divmod(n*3 + 1, n) + assert a == 3 and b == 1 + + def test_pylong_str_to_int(self): + v1 = 1 << 100_000 + s = str(v1) + v2 = int(s) + assert v1 == v2 + v3 = int(' -' + s) + assert -v1 == v3 + v4 = int(' +' + s + ' ') + assert v1 == v4 + with self.assertRaises(ValueError) as err: + int(s + 'z') + with self.assertRaises(ValueError) as err: + int(s + '_') + with self.assertRaises(ValueError) as err: + int('_' + s) + + @support.cpython_only # tests implementation details of CPython. + @unittest.skipUnless(_pylong, "_pylong module required") + @mock.patch.object(_pylong, "int_to_decimal_string") + def test_pylong_misbehavior_error_path_to_str( + self, mock_int_to_str): + with support.adjust_int_max_str_digits(20_000): + big_value = int('7'*19_999) + mock_int_to_str.return_value = None # not a str + with self.assertRaises(TypeError) as ctx: + str(big_value) + self.assertIn('_pylong.int_to_decimal_string did not', + str(ctx.exception)) + mock_int_to_str.side_effect = RuntimeError("testABC") + with self.assertRaises(RuntimeError): + str(big_value) + + @support.cpython_only # tests implementation details of CPython. + @unittest.skipUnless(_pylong, "_pylong module required") + @mock.patch.object(_pylong, "int_from_string") + def test_pylong_misbehavior_error_path_from_str( + self, mock_int_from_str): + big_value = '7'*19_999 + with support.adjust_int_max_str_digits(20_000): + mock_int_from_str.return_value = b'not an int' + with self.assertRaises(TypeError) as ctx: + int(big_value) + self.assertIn('_pylong.int_from_string did not', + str(ctx.exception)) + + mock_int_from_str.side_effect = RuntimeError("test123") + with self.assertRaises(RuntimeError): + int(big_value) + + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_interpreters.py b/Lib/test/test_interpreters.py index b969ddf3..27a143c7 100644 --- a/Lib/test/test_interpreters.py +++ b/Lib/test/test_interpreters.py @@ -7,7 +7,9 @@ import time from test import support from test.support import import_helper +from test.support import threading_helper _interpreters = import_helper.import_module('_xxsubinterpreters') +_channels = import_helper.import_module('_xxinterpchannels') from test.support import interpreters @@ -462,6 +464,30 @@ class TestInterpreterRun(TestBase): # test_xxsubinterpreters covers the remaining Interpreter.run() behavior. +@unittest.skip('these are crashing, likely just due just to _xxsubinterpreters (see gh-105699)') +class StressTests(TestBase): + + # In these tests we generally want a lot of interpreters, + # but not so many that any test takes too long. + + @support.requires_resource('cpu') + def test_create_many_sequential(self): + alive = [] + for _ in range(100): + interp = interpreters.create() + alive.append(interp) + + @support.requires_resource('cpu') + def test_create_many_threaded(self): + alive = [] + def task(): + interp = interpreters.create() + alive.append(interp) + threads = (threading.Thread(target=task) for _ in range(200)) + with threading_helper.start_threads(threads): + pass + + class TestIsShareable(TestBase): def test_default_shareables(self): @@ -533,7 +559,7 @@ class TestRecvChannelAttrs(TestBase): def test_id_type(self): rch, _ = interpreters.create_channel() - self.assertIsInstance(rch.id, _interpreters.ChannelID) + self.assertIsInstance(rch.id, _channels.ChannelID) def test_custom_id(self): rch = interpreters.RecvChannel(1) @@ -558,7 +584,7 @@ class TestSendChannelAttrs(TestBase): def test_id_type(self): _, sch = interpreters.create_channel() - self.assertIsInstance(sch.id, _interpreters.ChannelID) + self.assertIsInstance(sch.id, _channels.ChannelID) def test_custom_id(self): sch = interpreters.SendChannel(1) diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py index 79aa2da5..e032325f 100644 --- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -68,7 +68,7 @@ else: # Does io.IOBase finalizer log the exception if the close() method fails? # The exception is ignored silently by default in release build. -IOBASE_EMITS_UNRAISABLE = (hasattr(sys, "gettotalrefcount") or sys.flags.dev_mode) +IOBASE_EMITS_UNRAISABLE = (support.Py_DEBUG or sys.flags.dev_mode) def _default_chunk_size(): @@ -1042,6 +1042,95 @@ class CIOTest(IOTest): support.gc_collect() self.assertIsNone(wr(), wr) +@support.cpython_only +class TestIOCTypes(unittest.TestCase): + def setUp(self): + _io = import_helper.import_module("_io") + self.types = [ + _io.BufferedRWPair, + _io.BufferedRandom, + _io.BufferedReader, + _io.BufferedWriter, + _io.BytesIO, + _io.FileIO, + _io.IncrementalNewlineDecoder, + _io.StringIO, + _io.TextIOWrapper, + _io._BufferedIOBase, + _io._BytesIOBuffer, + _io._IOBase, + _io._RawIOBase, + _io._TextIOBase, + ] + if sys.platform == "win32": + self.types.append(_io._WindowsConsoleIO) + self._io = _io + + def test_immutable_types(self): + for tp in self.types: + with self.subTest(tp=tp): + with self.assertRaisesRegex(TypeError, "immutable"): + tp.foo = "bar" + + def test_class_hierarchy(self): + def check_subs(types, base): + for tp in types: + with self.subTest(tp=tp, base=base): + self.assertTrue(issubclass(tp, base)) + + def recursive_check(d): + for k, v in d.items(): + if isinstance(v, dict): + recursive_check(v) + elif isinstance(v, set): + check_subs(v, k) + else: + self.fail("corrupt test dataset") + + _io = self._io + hierarchy = { + _io._IOBase: { + _io._BufferedIOBase: { + _io.BufferedRWPair, + _io.BufferedRandom, + _io.BufferedReader, + _io.BufferedWriter, + _io.BytesIO, + }, + _io._RawIOBase: { + _io.FileIO, + }, + _io._TextIOBase: { + _io.StringIO, + _io.TextIOWrapper, + }, + }, + } + if sys.platform == "win32": + hierarchy[_io._IOBase][_io._RawIOBase].add(_io._WindowsConsoleIO) + + recursive_check(hierarchy) + + def test_subclassing(self): + _io = self._io + dataset = {k: True for k in self.types} + dataset[_io._BytesIOBuffer] = False + + for tp, is_basetype in dataset.items(): + with self.subTest(tp=tp, is_basetype=is_basetype): + name = f"{tp.__name__}_subclass" + bases = (tp,) + if is_basetype: + _ = type(name, bases, {}) + else: + msg = "not an acceptable base type" + with self.assertRaisesRegex(TypeError, msg): + _ = type(name, bases, {}) + + def test_disallow_instantiation(self): + _io = self._io + support.check_disallow_instantiation(self, _io._BytesIOBuffer) + class PyIOTest(IOTest): pass @@ -1459,8 +1548,8 @@ class BufferedReaderTest(unittest.TestCase, CommonBufferedTests): self.assertEqual(b"abcdefg", bufio.read()) - @support.requires_resource('cpu') @threading_helper.requires_working_threading() + @support.requires_resource('cpu') def test_threads(self): try: # Write out many bytes with exactly the same number of 0's, @@ -1539,11 +1628,25 @@ class BufferedReaderTest(unittest.TestCase, CommonBufferedTests): def test_read_on_closed(self): # Issue #23796 - b = io.BufferedReader(io.BytesIO(b"12")) + b = self.BufferedReader(self.BytesIO(b"12")) b.read(1) b.close() - self.assertRaises(ValueError, b.peek) - self.assertRaises(ValueError, b.read1, 1) + with self.subTest('peek'): + self.assertRaises(ValueError, b.peek) + with self.subTest('read1'): + self.assertRaises(ValueError, b.read1, 1) + with self.subTest('read'): + self.assertRaises(ValueError, b.read) + with self.subTest('readinto'): + self.assertRaises(ValueError, b.readinto, bytearray()) + with self.subTest('readinto1'): + self.assertRaises(ValueError, b.readinto1, bytearray()) + with self.subTest('flush'): + self.assertRaises(ValueError, b.flush) + with self.subTest('truncate'): + self.assertRaises(ValueError, b.truncate) + with self.subTest('seek'): + self.assertRaises(ValueError, b.seek, 0) def test_truncate_on_read_only(self): rawio = self.MockFileIO(b"abc") @@ -1601,10 +1704,10 @@ class CBufferedReaderTest(BufferedReaderTest, SizeofTest): def test_args_error(self): # Issue #17275 with self.assertRaisesRegex(TypeError, "BufferedReader"): - self.tp(io.BytesIO(), 1024, 1024, 1024) + self.tp(self.BytesIO(), 1024, 1024, 1024) def test_bad_readinto_value(self): - rawio = io.BufferedReader(io.BytesIO(b"12")) + rawio = self.tp(self.BytesIO(b"12")) rawio.readinto = lambda buf: -1 bufio = self.tp(rawio) with self.assertRaises(OSError) as cm: @@ -1612,7 +1715,7 @@ class CBufferedReaderTest(BufferedReaderTest, SizeofTest): self.assertIsNone(cm.exception.__cause__) def test_bad_readinto_type(self): - rawio = io.BufferedReader(io.BytesIO(b"12")) + rawio = self.tp(self.BytesIO(b"12")) rawio.readinto = lambda buf: b'' bufio = self.tp(rawio) with self.assertRaises(OSError) as cm: @@ -1755,7 +1858,7 @@ class BufferedWriterTest(unittest.TestCase, CommonBufferedTests): self.assertTrue(s.startswith(b"01234567A"), s) def test_write_and_rewind(self): - raw = io.BytesIO() + raw = self.BytesIO() bufio = self.tp(raw, 4) self.assertEqual(bufio.write(b"abcdef"), 6) self.assertEqual(bufio.tell(), 6) @@ -1834,8 +1937,8 @@ class BufferedWriterTest(unittest.TestCase, CommonBufferedTests): f.truncate() self.assertEqual(f.tell(), buffer_size + 2) - @support.requires_resource('cpu') @threading_helper.requires_working_threading() + @support.requires_resource('cpu') def test_threads(self): try: # Write out many bytes from many threads and test they were @@ -1965,7 +2068,7 @@ class CBufferedWriterTest(BufferedWriterTest, SizeofTest): def test_args_error(self): # Issue #17275 with self.assertRaisesRegex(TypeError, "BufferedWriter"): - self.tp(io.BytesIO(), 1024, 1024, 1024) + self.tp(self.BytesIO(), 1024, 1024, 1024) class PyBufferedWriterTest(BufferedWriterTest): @@ -2441,7 +2544,7 @@ class CBufferedRandomTest(BufferedRandomTest, SizeofTest): def test_args_error(self): # Issue #17275 with self.assertRaisesRegex(TypeError, "BufferedRandom"): - self.tp(io.BytesIO(), 1024, 1024, 1024) + self.tp(self.BytesIO(), 1024, 1024, 1024) class PyBufferedRandomTest(BufferedRandomTest): @@ -3473,7 +3576,7 @@ class TextIOWrapperTest(unittest.TestCase): # encode() is invalid shouldn't cause an assertion failure. rot13 = codecs.lookup("rot13") with support.swap_attr(rot13, '_is_text_encoding', True): - t = io.TextIOWrapper(io.BytesIO(b'foo'), encoding="rot13") + t = self.TextIOWrapper(self.BytesIO(b'foo'), encoding="rot13") self.assertRaises(TypeError, t.write, 'bar') def test_illegal_decoder(self): @@ -3579,7 +3682,7 @@ class TextIOWrapperTest(unittest.TestCase): t = self.TextIOWrapper(F(), encoding='utf-8') def test_reconfigure_locale(self): - wrapper = io.TextIOWrapper(io.BytesIO(b"test")) + wrapper = self.TextIOWrapper(self.BytesIO(b"test")) wrapper.reconfigure(encoding="locale") def test_reconfigure_encoding_read(self): @@ -3749,7 +3852,7 @@ class CTextIOWrapperTest(TextIOWrapperTest): # all data to disk. # The Python version has __del__, so it ends in gc.garbage instead. with warnings_helper.check_warnings(('', ResourceWarning)): - rawio = io.FileIO(os_helper.TESTFN, "wb") + rawio = self.FileIO(os_helper.TESTFN, "wb") b = self.BufferedWriter(rawio) t = self.TextIOWrapper(b, encoding="ascii") t.write("456def") @@ -4139,6 +4242,7 @@ class MiscIOTest(unittest.TestCase): def test_pickling(self): # Pickling file objects is forbidden + msg = "cannot pickle" for kwargs in [ {"mode": "w"}, {"mode": "wb"}, @@ -4153,8 +4257,10 @@ class MiscIOTest(unittest.TestCase): if "b" not in kwargs["mode"]: kwargs["encoding"] = "utf-8" for protocol in range(pickle.HIGHEST_PROTOCOL + 1): - with self.open(os_helper.TESTFN, **kwargs) as f: - self.assertRaises(TypeError, pickle.dumps, f, protocol) + with self.subTest(protocol=protocol, kwargs=kwargs): + with self.open(os_helper.TESTFN, **kwargs) as f: + with self.assertRaisesRegex(TypeError, msg): + pickle.dumps(f, protocol) @unittest.skipIf( support.is_emscripten, "fstat() of a pipe fd is not supported" @@ -4317,14 +4423,6 @@ class MiscIOTest(unittest.TestCase): proc = assert_python_ok('-X', 'utf8=1', '-c', code) self.assertEqual(b"utf-8", proc.out.strip()) - @support.cpython_only - # Depending if OpenWrapper was already created or not, the warning is - # emitted or not. For example, the attribute is already created when this - # test is run multiple times. - @warnings_helper.ignore_warnings(category=DeprecationWarning) - def test_openwrapper(self): - self.assertIs(self.io.OpenWrapper, self.io.open) - class CMiscIOTest(MiscIOTest): io = io @@ -4380,10 +4478,12 @@ class CMiscIOTest(MiscIOTest): self.assertFalse(err.strip('.!')) @threading_helper.requires_working_threading() + @support.requires_resource('walltime') def test_daemon_threads_shutdown_stdout_deadlock(self): self.check_daemon_threads_shutdown_deadlock('stdout') @threading_helper.requires_working_threading() + @support.requires_resource('walltime') def test_daemon_threads_shutdown_stderr_deadlock(self): self.check_daemon_threads_shutdown_deadlock('stderr') @@ -4557,11 +4657,13 @@ class SignalsTest(unittest.TestCase): os.close(r) @requires_alarm + @support.requires_resource('walltime') def test_interrupted_read_retry_buffered(self): self.check_interrupted_read_retry(lambda x: x.decode('latin1'), mode="rb") @requires_alarm + @support.requires_resource('walltime') def test_interrupted_read_retry_text(self): self.check_interrupted_read_retry(lambda x: x, mode="r", encoding="latin1") @@ -4635,10 +4737,12 @@ class SignalsTest(unittest.TestCase): raise @requires_alarm + @support.requires_resource('walltime') def test_interrupted_write_retry_buffered(self): self.check_interrupted_write_retry(b"x", mode="wb") @requires_alarm + @support.requires_resource('walltime') def test_interrupted_write_retry_text(self): self.check_interrupted_write_retry("x", mode="w", encoding="latin1") @@ -4665,7 +4769,7 @@ def load_tests(loader, tests, pattern): CIncrementalNewlineDecoderTest, PyIncrementalNewlineDecoderTest, CTextIOWrapperTest, PyTextIOWrapperTest, CMiscIOTest, PyMiscIOTest, - CSignalsTest, PySignalsTest, + CSignalsTest, PySignalsTest, TestIOCTypes, ) # Put the namespaces of the IO module we are testing and some useful mock diff --git a/Lib/test/test_isinstance.py b/Lib/test/test_isinstance.py index a0974640..bf9332e4 100644 --- a/Lib/test/test_isinstance.py +++ b/Lib/test/test_isinstance.py @@ -3,12 +3,11 @@ # testing of error conditions uncovered when using extension types. import unittest -import sys import typing from test import support - + class TestIsInstanceExceptions(unittest.TestCase): # Test to make sure that an AttributeError when accessing the instance's # class's bases is masked. This was actually a bug in Python 2.2 and @@ -97,7 +96,7 @@ class TestIsInstanceExceptions(unittest.TestCase): class D: pass self.assertRaises(RuntimeError, isinstance, c, D) - + # These tests are similar to above, but tickle certain code paths in # issubclass() instead of isinstance() -- really PyObject_IsSubclass() # vs. PyObject_IsInstance(). @@ -147,7 +146,7 @@ class TestIsSubclassExceptions(unittest.TestCase): self.assertRaises(TypeError, issubclass, B, C()) - + # meta classes for creating abstract classes and instances class AbstractClass(object): def __init__(self, bases): @@ -179,7 +178,7 @@ class Super: class Child(Super): pass - + class TestIsInstanceIsSubclass(unittest.TestCase): # Tests to ensure that isinstance and issubclass work on abstract # classes and instances. Before the 2.2 release, TypeErrors were @@ -353,10 +352,10 @@ def blowstack(fxn, arg, compare_to): # Make sure that calling isinstance with a deeply nested tuple for its # argument will raise RecursionError eventually. tuple_arg = (compare_to,) - for cnt in range(sys.getrecursionlimit()+5): + for cnt in range(support.EXCEEDS_RECURSION_LIMIT): tuple_arg = (tuple_arg,) fxn(arg, tuple_arg) - + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_iter.py b/Lib/test/test_iter.py index acbdcb5f..30aedb0d 100644 --- a/Lib/test/test_iter.py +++ b/Lib/test/test_iter.py @@ -7,6 +7,9 @@ from test.support.os_helper import TESTFN, unlink from test.support import check_free_after_iterating, ALWAYS_EQ, NEVER_EQ import pickle import collections.abc +import functools +import contextlib +import builtins # Test result of triple loop (too big to inline) TRIPLETS = [(0, 0, 0), (0, 0, 1), (0, 0, 2), @@ -91,6 +94,12 @@ class CallableIterClass: raise IndexError # Emergency stop return i +class EmptyIterClass: + def __len__(self): + return 0 + def __getitem__(self, i): + raise StopIteration + # Main test suite class TestCase(unittest.TestCase): @@ -238,6 +247,78 @@ class TestCase(unittest.TestCase): self.assertEqual(list(empit), [5, 6]) self.assertEqual(list(a), [0, 1, 2, 3, 4, 5, 6]) + def test_reduce_mutating_builtins_iter(self): + # This is a reproducer of issue #101765 + # where iter `__reduce__` calls could lead to a segfault or SystemError + # depending on the order of C argument evaluation, which is undefined + + # Backup builtins + builtins_dict = builtins.__dict__ + orig = {"iter": iter, "reversed": reversed} + + def run(builtin_name, item, sentinel=None): + it = iter(item) if sentinel is None else iter(item, sentinel) + + class CustomStr: + def __init__(self, name, iterator): + self.name = name + self.iterator = iterator + def __hash__(self): + return hash(self.name) + def __eq__(self, other): + # Here we exhaust our iterator, possibly changing + # its `it_seq` pointer to NULL + # The `__reduce__` call should correctly get + # the pointers after this call + list(self.iterator) + return other == self.name + + # del is required here + # to not prematurely call __eq__ from + # the hash collision with the old key + del builtins_dict[builtin_name] + builtins_dict[CustomStr(builtin_name, it)] = orig[builtin_name] + + return it.__reduce__() + + types = [ + (EmptyIterClass(),), + (bytes(8),), + (bytearray(8),), + ((1, 2, 3),), + (lambda: 0, 0), + (tuple[int],) # GenericAlias + ] + + try: + run_iter = functools.partial(run, "iter") + # The returned value of `__reduce__` should not only be valid + # but also *empty*, as `it` was exhausted during `__eq__` + # i.e "xyz" returns (iter, ("",)) + self.assertEqual(run_iter("xyz"), (orig["iter"], ("",))) + self.assertEqual(run_iter([1, 2, 3]), (orig["iter"], ([],))) + + # _PyEval_GetBuiltin is also called for `reversed` in a branch of + # listiter_reduce_general + self.assertEqual( + run("reversed", orig["reversed"](list(range(8)))), + (iter, ([],)) + ) + + for case in types: + self.assertEqual(run_iter(*case), (orig["iter"], ((),))) + finally: + # Restore original builtins + for key, func in orig.items(): + # need to suppress KeyErrors in case + # a failed test deletes the key without setting anything + with contextlib.suppress(KeyError): + # del is required here + # to not invoke our custom __eq__ from + # the hash collision with the old key + del builtins_dict[key] + builtins_dict[key] = func + # Test a new_style class with __iter__ but no next() method def test_new_style_iter_class(self): class IterClass(object): @@ -267,6 +348,31 @@ class TestCase(unittest.TestCase): return i self.check_iterator(iter(spam, 20), list(range(10)), pickle=False) + def test_iter_function_concealing_reentrant_exhaustion(self): + # gh-101892: Test two-argument iter() with a function that + # exhausts its associated iterator but forgets to either return + # a sentinel value or raise StopIteration. + HAS_MORE = 1 + NO_MORE = 2 + + def exhaust(iterator): + """Exhaust an iterator without raising StopIteration.""" + list(iterator) + + def spam(): + # Touching the iterator with exhaust() below will call + # spam() once again so protect against recursion. + if spam.is_recursive_call: + return NO_MORE + spam.is_recursive_call = True + exhaust(spam.iterator) + return HAS_MORE + + spam.is_recursive_call = False + spam.iterator = iter(spam, NO_MORE) + with self.assertRaises(StopIteration): + next(spam.iterator) + # Test exception propagation through function iterator def test_exception_function(self): def spam(state=[0]): diff --git a/Lib/test/test_itertools.py b/Lib/test/test_itertools.py index 311c2a32..512745e4 100644 --- a/Lib/test/test_itertools.py +++ b/Lib/test/test_itertools.py @@ -15,6 +15,26 @@ import sys import struct import threading import gc +import warnings + +def pickle_deprecated(testfunc): + """ Run the test three times. + First, verify that a Deprecation Warning is raised. + Second, run normally but with DeprecationWarnings temporarily disabled. + Third, run with warnings promoted to errors. + """ + def inner(self): + with self.assertWarns(DeprecationWarning): + testfunc(self) + with warnings.catch_warnings(): + warnings.simplefilter("ignore", category=DeprecationWarning) + testfunc(self) + with warnings.catch_warnings(): + warnings.simplefilter("error", category=DeprecationWarning) + with self.assertRaises((DeprecationWarning, AssertionError, SystemError)): + testfunc(self) + + return inner maxsize = support.MAX_Py_ssize_t minsize = -maxsize-1 @@ -124,6 +144,7 @@ class TestBasicOps(unittest.TestCase): c = expand(compare[took:]) self.assertEqual(a, c); + @pickle_deprecated def test_accumulate(self): self.assertEqual(list(accumulate(range(10))), # one positional arg [0, 1, 3, 6, 10, 15, 21, 28, 36, 45]) @@ -159,6 +180,44 @@ class TestBasicOps(unittest.TestCase): with self.assertRaises(TypeError): list(accumulate([10, 20], 100)) + def test_batched(self): + self.assertEqual(list(batched('ABCDEFG', 3)), + [('A', 'B', 'C'), ('D', 'E', 'F'), ('G',)]) + self.assertEqual(list(batched('ABCDEFG', 2)), + [('A', 'B'), ('C', 'D'), ('E', 'F'), ('G',)]) + self.assertEqual(list(batched('ABCDEFG', 1)), + [('A',), ('B',), ('C',), ('D',), ('E',), ('F',), ('G',)]) + + with self.assertRaises(TypeError): # Too few arguments + list(batched('ABCDEFG')) + with self.assertRaises(TypeError): + list(batched('ABCDEFG', 3, None)) # Too many arguments + with self.assertRaises(TypeError): + list(batched(None, 3)) # Non-iterable input + with self.assertRaises(TypeError): + list(batched('ABCDEFG', 'hello')) # n is a string + with self.assertRaises(ValueError): + list(batched('ABCDEFG', 0)) # n is zero + with self.assertRaises(ValueError): + list(batched('ABCDEFG', -1)) # n is negative + + data = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + for n in range(1, 6): + for i in range(len(data)): + s = data[:i] + batches = list(batched(s, n)) + with self.subTest(s=s, n=n, batches=batches): + # Order is preserved and no data is lost + self.assertEqual(''.join(chain(*batches)), s) + # Each batch is an exact tuple + self.assertTrue(all(type(batch) is tuple for batch in batches)) + # All but the last batch is of size n + if batches: + last_batch = batches.pop() + self.assertTrue(all(len(batch) == n for batch in batches)) + self.assertTrue(len(last_batch) <= n) + batches.append(last_batch) + def test_chain(self): def chain2(*iterables): @@ -180,7 +239,9 @@ class TestBasicOps(unittest.TestCase): self.assertEqual(list(chain.from_iterable([''])), []) self.assertEqual(take(4, chain.from_iterable(['abc', 'def'])), list('abcd')) self.assertRaises(TypeError, list, chain.from_iterable([2, 3])) + self.assertEqual(list(islice(chain.from_iterable(repeat(range(5))), 2)), [0, 1]) + @pickle_deprecated def test_chain_reducible(self): for oper in [copy.deepcopy] + picklecopiers: it = chain('abc', 'def') @@ -194,6 +255,7 @@ class TestBasicOps(unittest.TestCase): for proto in range(pickle.HIGHEST_PROTOCOL + 1): self.pickletest(proto, chain('abc', 'def'), compare=list('abcdef')) + @pickle_deprecated def test_chain_setstate(self): self.assertRaises(TypeError, chain().__setstate__, ()) self.assertRaises(TypeError, chain().__setstate__, []) @@ -207,6 +269,7 @@ class TestBasicOps(unittest.TestCase): it.__setstate__((iter(['abc', 'def']), iter(['ghi']))) self.assertEqual(list(it), ['ghi', 'a', 'b', 'c', 'd', 'e', 'f']) + @pickle_deprecated def test_combinations(self): self.assertRaises(TypeError, combinations, 'abc') # missing r argument self.assertRaises(TypeError, combinations, 'abc', 2, 1) # too many arguments @@ -230,7 +293,6 @@ class TestBasicOps(unittest.TestCase): self.assertEqual(list(op(testIntermediate)), [(0,1,3), (0,2,3), (1,2,3)]) - def combinations1(iterable, r): 'Pure python version shown in the docs' pool = tuple(iterable) @@ -298,6 +360,7 @@ class TestBasicOps(unittest.TestCase): self.assertEqual(len(set(map(id, combinations('abcde', 3)))), 1) self.assertNotEqual(len(set(map(id, list(combinations('abcde', 3))))), 1) + @pickle_deprecated def test_combinations_with_replacement(self): cwr = combinations_with_replacement self.assertRaises(TypeError, cwr, 'abc') # missing r argument @@ -386,6 +449,7 @@ class TestBasicOps(unittest.TestCase): self.assertEqual(len(set(map(id, cwr('abcde', 3)))), 1) self.assertNotEqual(len(set(map(id, list(cwr('abcde', 3))))), 1) + @pickle_deprecated def test_permutations(self): self.assertRaises(TypeError, permutations) # too few arguments self.assertRaises(TypeError, permutations, 'abc', 2, 1) # too many arguments @@ -492,6 +556,7 @@ class TestBasicOps(unittest.TestCase): self.assertEqual(comb, list(filter(set(perm).__contains__, cwr))) # comb: cwr that is a perm self.assertEqual(comb, sorted(set(cwr) & set(perm))) # comb: both a cwr and a perm + @pickle_deprecated def test_compress(self): self.assertEqual(list(compress(data='ABCDEF', selectors=[1,0,1,0,1,1])), list('ACEF')) self.assertEqual(list(compress('ABCDEF', [1,0,1,0,1,1])), list('ACEF')) @@ -525,7 +590,7 @@ class TestBasicOps(unittest.TestCase): next(testIntermediate) self.assertEqual(list(op(testIntermediate)), list(result2)) - + @pickle_deprecated def test_count(self): self.assertEqual(lzip('abc',count()), [('a', 0), ('b', 1), ('c', 2)]) self.assertEqual(lzip('abc',count(3)), [('a', 3), ('b', 4), ('c', 5)]) @@ -574,6 +639,7 @@ class TestBasicOps(unittest.TestCase): #check proper internal error handling for large "step' sizes count(1, maxsize+5); sys.exc_info() + @pickle_deprecated def test_count_with_stride(self): self.assertEqual(lzip('abc',count(2,3)), [('a', 2), ('b', 5), ('c', 8)]) self.assertEqual(lzip('abc',count(start=2,step=3)), @@ -636,6 +702,7 @@ class TestBasicOps(unittest.TestCase): self.assertRaises(TypeError, cycle, 5) self.assertEqual(list(islice(cycle(gen3()),10)), [0,1,2,0,1,2,0,1,2,0]) + @pickle_deprecated def test_cycle_copy_pickle(self): # check copy, deepcopy, pickle c = cycle('abc') @@ -672,6 +739,7 @@ class TestBasicOps(unittest.TestCase): d = pickle.loads(p) # rebuild the cycle object self.assertEqual(take(20, d), list('cdeabcdeabcdeabcdeab')) + @pickle_deprecated def test_cycle_unpickle_compat(self): testcases = [ b'citertools\ncycle\n(c__builtin__\niter\n((lI1\naI2\naI3\natRI1\nbtR((lI1\naI0\ntb.', @@ -703,6 +771,7 @@ class TestBasicOps(unittest.TestCase): it = pickle.loads(t) self.assertEqual(take(10, it), [2, 3, 1, 2, 3, 1, 2, 3, 1, 2]) + @pickle_deprecated def test_cycle_setstate(self): # Verify both modes for restoring state @@ -739,6 +808,7 @@ class TestBasicOps(unittest.TestCase): self.assertRaises(TypeError, cycle('').__setstate__, ()) self.assertRaises(TypeError, cycle('').__setstate__, ([],)) + @pickle_deprecated def test_groupby(self): # Check whether it accepts arguments correctly self.assertEqual([], list(groupby([]))) @@ -896,6 +966,7 @@ class TestBasicOps(unittest.TestCase): c = filter(isEven, range(6)) self.pickletest(proto, c) + @pickle_deprecated def test_filterfalse(self): self.assertEqual(list(filterfalse(isEven, range(6))), [1,3,5]) self.assertEqual(list(filterfalse(None, [0,1,0,2,0])), [0,0,0]) @@ -926,6 +997,7 @@ class TestBasicOps(unittest.TestCase): lzip('abc', 'def')) @support.impl_detail("tuple reuse is specific to CPython") + @pickle_deprecated def test_zip_tuple_reuse(self): ids = list(map(id, zip('abc', 'def'))) self.assertEqual(min(ids), max(ids)) @@ -1001,6 +1073,7 @@ class TestBasicOps(unittest.TestCase): ids = list(map(id, list(zip_longest('abc', 'def')))) self.assertEqual(len(dict.fromkeys(ids)), len(ids)) + @pickle_deprecated def test_zip_longest_pickling(self): for proto in range(pickle.HIGHEST_PROTOCOL + 1): self.pickletest(proto, zip_longest("abc", "def")) @@ -1147,6 +1220,7 @@ class TestBasicOps(unittest.TestCase): self.assertEqual(len(set(map(id, product('abc', 'def')))), 1) self.assertNotEqual(len(set(map(id, list(product('abc', 'def'))))), 1) + @pickle_deprecated def test_product_pickling(self): # check copy, deepcopy, pickle for args, result in [ @@ -1162,6 +1236,7 @@ class TestBasicOps(unittest.TestCase): for proto in range(pickle.HIGHEST_PROTOCOL + 1): self.pickletest(proto, product(*args)) + @pickle_deprecated def test_product_issue_25021(self): # test that indices are properly clamped to the length of the tuples p = product((1, 2),(3,)) @@ -1172,6 +1247,7 @@ class TestBasicOps(unittest.TestCase): p.__setstate__((0, 0, 0x1000)) # will access tuple element 1 if not clamped self.assertRaises(StopIteration, next, p) + @pickle_deprecated def test_repeat(self): self.assertEqual(list(repeat(object='a', times=3)), ['a', 'a', 'a']) self.assertEqual(lzip(range(3),repeat('a')), @@ -1204,6 +1280,7 @@ class TestBasicOps(unittest.TestCase): self.assertEqual(repr(repeat('a', times=-1)), "repeat('a', 0)") self.assertEqual(repr(repeat('a', times=-2)), "repeat('a', 0)") + @pickle_deprecated def test_map(self): self.assertEqual(list(map(operator.pow, range(3), range(1,7))), [0**1, 1**2, 2**3]) @@ -1234,6 +1311,7 @@ class TestBasicOps(unittest.TestCase): c = map(tupleize, 'abc', count()) self.pickletest(proto, c) + @pickle_deprecated def test_starmap(self): self.assertEqual(list(starmap(operator.pow, zip(range(3), range(1,7)))), [0**1, 1**2, 2**3]) @@ -1261,6 +1339,7 @@ class TestBasicOps(unittest.TestCase): c = starmap(operator.pow, zip(range(3), range(1,7))) self.pickletest(proto, c) + @pickle_deprecated def test_islice(self): for args in [ # islice(args) should agree with range(args) (10, 20, 3), @@ -1355,6 +1434,7 @@ class TestBasicOps(unittest.TestCase): self.assertEqual(list(islice(range(100), IntLike(10), IntLike(50), IntLike(5))), list(range(10,50,5))) + @pickle_deprecated def test_takewhile(self): data = [1, 3, 5, 20, 2, 4, 6, 8] self.assertEqual(list(takewhile(underten, data)), [1, 3, 5]) @@ -1375,6 +1455,7 @@ class TestBasicOps(unittest.TestCase): for proto in range(pickle.HIGHEST_PROTOCOL + 1): self.pickletest(proto, takewhile(underten, data)) + @pickle_deprecated def test_dropwhile(self): data = [1, 3, 5, 20, 2, 4, 6, 8] self.assertEqual(list(dropwhile(underten, data)), [20, 2, 4, 6, 8]) @@ -1392,6 +1473,7 @@ class TestBasicOps(unittest.TestCase): for proto in range(pickle.HIGHEST_PROTOCOL + 1): self.pickletest(proto, dropwhile(underten, data)) + @pickle_deprecated def test_tee(self): n = 200 @@ -1655,12 +1737,45 @@ class TestBasicOps(unittest.TestCase): gc.collect() self.assertTrue(gc.is_tracked(next(it))) + @support.cpython_only + def test_immutable_types(self): + from itertools import _grouper, _tee, _tee_dataobject + dataset = ( + accumulate, + batched, + chain, + combinations, + combinations_with_replacement, + compress, + count, + cycle, + dropwhile, + filterfalse, + groupby, + _grouper, + islice, + pairwise, + permutations, + product, + repeat, + starmap, + takewhile, + _tee, + _tee_dataobject, + zip_longest, + ) + for tp in dataset: + with self.subTest(tp=tp): + with self.assertRaisesRegex(TypeError, "immutable"): + tp.foobar = 1 + class TestExamples(unittest.TestCase): def test_accumulate(self): self.assertEqual(list(accumulate([1,2,3,4,5])), [1, 3, 6, 10, 15]) + @pickle_deprecated def test_accumulate_reducible(self): # check copy, deepcopy, pickle data = [1, 2, 3, 4, 5] @@ -1676,6 +1791,7 @@ class TestExamples(unittest.TestCase): self.assertEqual(list(copy.deepcopy(it)), accumulated[1:]) self.assertEqual(list(copy.copy(it)), accumulated[1:]) + @pickle_deprecated def test_accumulate_reducible_none(self): # Issue #25718: total is None it = accumulate([None, None, None], operator.is_) @@ -1768,6 +1884,31 @@ class TestExamples(unittest.TestCase): class TestPurePythonRoughEquivalents(unittest.TestCase): + def test_batched_recipe(self): + def batched_recipe(iterable, n): + "Batch data into tuples of length n. The last batch may be shorter." + # batched('ABCDEFG', 3) --> ABC DEF G + if n < 1: + raise ValueError('n must be at least one') + it = iter(iterable) + while batch := tuple(islice(it, n)): + yield batch + + for iterable, n in product( + ['', 'a', 'ab', 'abc', 'abcd', 'abcde', 'abcdef', 'abcdefg', None], + [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, None]): + with self.subTest(iterable=iterable, n=n): + try: + e1, r1 = None, list(batched(iterable, n)) + except Exception as e: + e1, r1 = type(e), None + try: + e2, r2 = None, list(batched_recipe(iterable, n)) + except Exception as e: + e2, r2 = type(e), None + self.assertEqual(r1, r2) + self.assertEqual(e1, e2) + @staticmethod def islice(iterable, *args): s = slice(*args) @@ -1819,6 +1960,10 @@ class TestGC(unittest.TestCase): a = [] self.makecycle(accumulate([1,2,a,3]), a) + def test_batched(self): + a = [] + self.makecycle(batched([1,2,a,3], 2), a) + def test_chain(self): a = [] self.makecycle(chain(a), a) @@ -1976,6 +2121,20 @@ class E: def __next__(self): 3 // 0 +class E2: + 'Test propagation of exceptions after two iterations' + def __init__(self, seqn): + self.seqn = seqn + self.i = 0 + def __iter__(self): + return self + def __next__(self): + if self.i == 2: + raise ZeroDivisionError + v = self.seqn[self.i] + self.i += 1 + return v + class S: 'Test immediate stop' def __init__(self, seqn): @@ -2003,6 +2162,19 @@ class TestVariousIteratorArgs(unittest.TestCase): self.assertRaises(TypeError, accumulate, N(s)) self.assertRaises(ZeroDivisionError, list, accumulate(E(s))) + def test_batched(self): + s = 'abcde' + r = [('a', 'b'), ('c', 'd'), ('e',)] + n = 2 + for g in (G, I, Ig, L, R): + with self.subTest(g=g): + self.assertEqual(list(batched(g(s), n)), r) + self.assertEqual(list(batched(S(s), 2)), []) + self.assertRaises(TypeError, batched, X(s), 2) + self.assertRaises(TypeError, batched, N(s), 2) + self.assertRaises(ZeroDivisionError, list, batched(E(s), 2)) + self.assertRaises(ZeroDivisionError, list, batched(E2(s), 4)) + def test_chain(self): for s in ("123", "", range(1000), ('do', 1.2), range(2000,2200,5)): for g in (G, I, Ig, S, L, R): @@ -2229,6 +2401,7 @@ class RegressionTests(unittest.TestCase): self.assertEqual(hist, [0,1]) @support.skip_if_pgo_task + @support.requires_resource('cpu') def test_long_chain_of_empty_iterables(self): # Make sure itertools.chain doesn't run into recursion limits when # dealing with long chains of empty iterables. Even with a high diff --git a/Lib/test/test_json/test_default.py b/Lib/test/test_json/test_default.py index 9b8325e9..3ce16684 100644 --- a/Lib/test/test_json/test_default.py +++ b/Lib/test/test_json/test_default.py @@ -1,3 +1,4 @@ +import collections from test.test_json import PyTest, CTest @@ -7,6 +8,16 @@ class TestDefault: self.dumps(type, default=repr), self.dumps(repr(type))) + def test_ordereddict(self): + od = collections.OrderedDict(a=1, b=2, c=3, d=4) + od.move_to_end('b') + self.assertEqual( + self.dumps(od), + '{"a": 1, "c": 3, "d": 4, "b": 2}') + self.assertEqual( + self.dumps(od, sort_keys=True), + '{"a": 1, "b": 2, "c": 3, "d": 4}') + class TestPyDefault(TestDefault, PyTest): pass class TestCDefault(TestDefault, CTest): pass diff --git a/Lib/test/test_json/test_float.py b/Lib/test/test_json/test_float.py index d0c72143..61540a3a 100644 --- a/Lib/test/test_json/test_float.py +++ b/Lib/test/test_json/test_float.py @@ -26,7 +26,8 @@ class TestFloat: res = self.loads(out) self.assertEqual(len(res), 1) self.assertNotEqual(res[0], res[0]) - self.assertRaises(ValueError, self.dumps, [val], allow_nan=False) + msg = f'Out of range float values are not JSON compliant: {val}' + self.assertRaisesRegex(ValueError, msg, self.dumps, [val], allow_nan=False) class TestPyFloat(TestFloat, PyTest): pass diff --git a/Lib/test/test_keyword.py b/Lib/test/test_keyword.py index 3e2a8b3f..858e5de3 100644 --- a/Lib/test/test_keyword.py +++ b/Lib/test/test_keyword.py @@ -20,18 +20,37 @@ class Test_iskeyword(unittest.TestCase): keyword.kwlist = ['its', 'all', 'eggs', 'beans', 'and', 'a', 'slice'] self.assertFalse(keyword.iskeyword('eggs')) + def test_changing_the_softkwlist_does_not_affect_issoftkeyword(self): + oldlist = keyword.softkwlist + self.addCleanup(setattr, keyword, "softkwlist", oldlist) + keyword.softkwlist = ["foo", "bar", "spam", "egs", "case"] + self.assertFalse(keyword.issoftkeyword("spam")) + def test_all_keywords_fail_to_be_used_as_names(self): for key in keyword.kwlist: with self.assertRaises(SyntaxError): exec(f"{key} = 42") + def test_all_soft_keywords_can_be_used_as_names(self): + for key in keyword.softkwlist: + exec(f"{key} = 42") + def test_async_and_await_are_keywords(self): self.assertIn("async", keyword.kwlist) self.assertIn("await", keyword.kwlist) + def test_soft_keywords(self): + self.assertIn("type", keyword.softkwlist) + self.assertIn("match", keyword.softkwlist) + self.assertIn("case", keyword.softkwlist) + self.assertIn("_", keyword.softkwlist) + def test_keywords_are_sorted(self): self.assertListEqual(sorted(keyword.kwlist), keyword.kwlist) + def test_softkeywords_are_sorted(self): + self.assertListEqual(sorted(keyword.softkwlist), keyword.softkwlist) + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_largefile.py b/Lib/test/test_largefile.py index 3c11c59b..3b0930fe 100644 --- a/Lib/test/test_largefile.py +++ b/Lib/test/test_largefile.py @@ -8,7 +8,7 @@ import unittest import socket import shutil import threading -from test.support import requires, bigmemtest +from test.support import requires, bigmemtest, requires_resource from test.support import SHORT_TIMEOUT from test.support import socket_helper from test.support.os_helper import TESTFN, unlink @@ -173,6 +173,7 @@ class TestCopyfile(LargeFileTest, unittest.TestCase): # Exact required disk space would be (size * 2), but let's give it a # bit more tolerance. @skip_no_disk_space(TESTFN, size * 2.5) + @requires_resource('cpu') def test_it(self): # Internally shutil.copyfile() can use "fast copy" methods like # os.sendfile(). @@ -222,6 +223,7 @@ class TestSocketSendfile(LargeFileTest, unittest.TestCase): # Exact required disk space would be (size * 2), but let's give it a # bit more tolerance. @skip_no_disk_space(TESTFN, size * 2.5) + @requires_resource('cpu') def test_it(self): port = socket_helper.find_unused_port() with socket.create_server(("", port)) as sock: diff --git a/Lib/test/test_launcher.py b/Lib/test/test_launcher.py index d0a1f624..362b507d 100644 --- a/Lib/test/test_launcher.py +++ b/Lib/test/test_launcher.py @@ -7,7 +7,6 @@ import subprocess import sys import sysconfig import tempfile -import textwrap import unittest from pathlib import Path from test import support @@ -395,17 +394,17 @@ class TestLauncher(unittest.TestCase, RunPyMixin): def test_filter_to_tag(self): company = "PythonTestSuite" - data = self.run_py([f"-V:3.100"]) + data = self.run_py(["-V:3.100"]) self.assertEqual("X.Y.exe", data["LaunchCommand"]) self.assertEqual(company, data["env.company"]) self.assertEqual("3.100", data["env.tag"]) - data = self.run_py([f"-V:3.100-32"]) + data = self.run_py(["-V:3.100-32"]) self.assertEqual("X.Y-32.exe", data["LaunchCommand"]) self.assertEqual(company, data["env.company"]) self.assertEqual("3.100-32", data["env.tag"]) - data = self.run_py([f"-V:3.100-arm64"]) + data = self.run_py(["-V:3.100-arm64"]) self.assertEqual("X.Y-arm64.exe -X fake_arg_for_test", data["LaunchCommand"]) self.assertEqual(company, data["env.company"]) self.assertEqual("3.100-arm64", data["env.tag"]) @@ -422,7 +421,7 @@ class TestLauncher(unittest.TestCase, RunPyMixin): def test_filter_with_single_install(self): company = "PythonTestSuite1" data = self.run_py( - [f"-V:Nonexistent"], + ["-V:Nonexistent"], env={"PYLAUNCHER_LIMIT_TO_COMPANY": company}, expect_returncode=103, ) @@ -501,7 +500,7 @@ class TestLauncher(unittest.TestCase, RunPyMixin): data = self.run_py(["--version"], argv=f'{argv0} --version') self.assertEqual("PythonTestSuite", data["SearchInfo.company"]) self.assertEqual("3.100", data["SearchInfo.tag"]) - self.assertEqual(f'X.Y.exe --version', data["stdout"].strip()) + self.assertEqual("X.Y.exe --version", data["stdout"].strip()) def test_py_default_in_list(self): data = self.run_py(["-0"], env=TEST_PY_ENV) @@ -663,7 +662,7 @@ class TestLauncher(unittest.TestCase, RunPyMixin): self.assertIn("9PJPW5LDXLZ5", cmd) def test_literal_shebang_absolute(self): - with self.script(f"#! C:/some_random_app -witharg") as script: + with self.script("#! C:/some_random_app -witharg") as script: data = self.run_py([script]) self.assertEqual( f"C:\\some_random_app -witharg {script}", @@ -671,7 +670,7 @@ class TestLauncher(unittest.TestCase, RunPyMixin): ) def test_literal_shebang_relative(self): - with self.script(f"#! ..\\some_random_app -witharg") as script: + with self.script("#! ..\\some_random_app -witharg") as script: data = self.run_py([script]) self.assertEqual( f"{script.parent.parent}\\some_random_app -witharg {script}", @@ -679,14 +678,14 @@ class TestLauncher(unittest.TestCase, RunPyMixin): ) def test_literal_shebang_quoted(self): - with self.script(f'#! "some random app" -witharg') as script: + with self.script('#! "some random app" -witharg') as script: data = self.run_py([script]) self.assertEqual( f'"{script.parent}\\some random app" -witharg {script}', data["stdout"].strip(), ) - with self.script(f'#! some" random "app -witharg') as script: + with self.script('#! some" random "app -witharg') as script: data = self.run_py([script]) self.assertEqual( f'"{script.parent}\\some random app" -witharg {script}', @@ -694,7 +693,7 @@ class TestLauncher(unittest.TestCase, RunPyMixin): ) def test_literal_shebang_quoted_escape(self): - with self.script(f'#! some\\" random "app -witharg') as script: + with self.script('#! some\\" random "app -witharg') as script: data = self.run_py([script]) self.assertEqual( f'"{script.parent}\\some\\ random app" -witharg {script}', diff --git a/Lib/test/test_lib2to3.py b/Lib/test/test_lib2to3.py deleted file mode 100644 index 6ea8aa4a..00000000 --- a/Lib/test/test_lib2to3.py +++ /dev/null @@ -1,9 +0,0 @@ -import unittest -from test.support.import_helper import import_fresh_module -from test.support.warnings_helper import check_warnings - -with check_warnings(("", DeprecationWarning)): - load_tests = import_fresh_module('lib2to3.tests', fresh=['lib2to3']).load_tests - -if __name__ == '__main__': - unittest.main() diff --git a/Lib/lib2to3/tests/__init__.py b/Lib/test/test_lib2to3/__init__.py similarity index 100% rename from Lib/lib2to3/tests/__init__.py rename to Lib/test/test_lib2to3/__init__.py diff --git a/Lib/lib2to3/tests/__main__.py b/Lib/test/test_lib2to3/__main__.py similarity index 100% rename from Lib/lib2to3/tests/__main__.py rename to Lib/test/test_lib2to3/__main__.py diff --git a/Lib/lib2to3/tests/data/README b/Lib/test/test_lib2to3/data/README similarity index 100% rename from Lib/lib2to3/tests/data/README rename to Lib/test/test_lib2to3/data/README diff --git a/Lib/lib2to3/tests/data/bom.py b/Lib/test/test_lib2to3/data/bom.py similarity index 100% rename from Lib/lib2to3/tests/data/bom.py rename to Lib/test/test_lib2to3/data/bom.py diff --git a/Lib/lib2to3/tests/data/crlf.py b/Lib/test/test_lib2to3/data/crlf.py similarity index 100% rename from Lib/lib2to3/tests/data/crlf.py rename to Lib/test/test_lib2to3/data/crlf.py diff --git a/Lib/lib2to3/tests/data/different_encoding.py b/Lib/test/test_lib2to3/data/different_encoding.py similarity index 100% rename from Lib/lib2to3/tests/data/different_encoding.py rename to Lib/test/test_lib2to3/data/different_encoding.py diff --git a/Lib/lib2to3/tests/data/false_encoding.py b/Lib/test/test_lib2to3/data/false_encoding.py similarity index 100% rename from Lib/lib2to3/tests/data/false_encoding.py rename to Lib/test/test_lib2to3/data/false_encoding.py diff --git a/Lib/lib2to3/tests/data/fixers/bad_order.py b/Lib/test/test_lib2to3/data/fixers/bad_order.py similarity index 100% rename from Lib/lib2to3/tests/data/fixers/bad_order.py rename to Lib/test/test_lib2to3/data/fixers/bad_order.py diff --git a/Lib/test/test_importlib/zipdata02/__init__.py b/Lib/test/test_lib2to3/data/fixers/myfixes/__init__.py similarity index 100% rename from Lib/test/test_importlib/zipdata02/__init__.py rename to Lib/test/test_lib2to3/data/fixers/myfixes/__init__.py diff --git a/Lib/lib2to3/tests/data/fixers/myfixes/fix_explicit.py b/Lib/test/test_lib2to3/data/fixers/myfixes/fix_explicit.py similarity index 100% rename from Lib/lib2to3/tests/data/fixers/myfixes/fix_explicit.py rename to Lib/test/test_lib2to3/data/fixers/myfixes/fix_explicit.py diff --git a/Lib/lib2to3/tests/data/fixers/myfixes/fix_first.py b/Lib/test/test_lib2to3/data/fixers/myfixes/fix_first.py similarity index 100% rename from Lib/lib2to3/tests/data/fixers/myfixes/fix_first.py rename to Lib/test/test_lib2to3/data/fixers/myfixes/fix_first.py diff --git a/Lib/lib2to3/tests/data/fixers/myfixes/fix_last.py b/Lib/test/test_lib2to3/data/fixers/myfixes/fix_last.py similarity index 100% rename from Lib/lib2to3/tests/data/fixers/myfixes/fix_last.py rename to Lib/test/test_lib2to3/data/fixers/myfixes/fix_last.py diff --git a/Lib/lib2to3/tests/data/fixers/myfixes/fix_parrot.py b/Lib/test/test_lib2to3/data/fixers/myfixes/fix_parrot.py similarity index 100% rename from Lib/lib2to3/tests/data/fixers/myfixes/fix_parrot.py rename to Lib/test/test_lib2to3/data/fixers/myfixes/fix_parrot.py diff --git a/Lib/lib2to3/tests/data/fixers/myfixes/fix_preorder.py b/Lib/test/test_lib2to3/data/fixers/myfixes/fix_preorder.py similarity index 100% rename from Lib/lib2to3/tests/data/fixers/myfixes/fix_preorder.py rename to Lib/test/test_lib2to3/data/fixers/myfixes/fix_preorder.py diff --git a/Lib/lib2to3/tests/data/fixers/no_fixer_cls.py b/Lib/test/test_lib2to3/data/fixers/no_fixer_cls.py similarity index 100% rename from Lib/lib2to3/tests/data/fixers/no_fixer_cls.py rename to Lib/test/test_lib2to3/data/fixers/no_fixer_cls.py diff --git a/Lib/lib2to3/tests/data/fixers/parrot_example.py b/Lib/test/test_lib2to3/data/fixers/parrot_example.py similarity index 100% rename from Lib/lib2to3/tests/data/fixers/parrot_example.py rename to Lib/test/test_lib2to3/data/fixers/parrot_example.py diff --git a/Lib/lib2to3/tests/data/infinite_recursion.py b/Lib/test/test_lib2to3/data/infinite_recursion.py similarity index 100% rename from Lib/lib2to3/tests/data/infinite_recursion.py rename to Lib/test/test_lib2to3/data/infinite_recursion.py diff --git a/Lib/lib2to3/tests/data/py2_test_grammar.py b/Lib/test/test_lib2to3/data/py2_test_grammar.py similarity index 99% rename from Lib/lib2to3/tests/data/py2_test_grammar.py rename to Lib/test/test_lib2to3/data/py2_test_grammar.py index f9e4ea13..1a631510 100644 --- a/Lib/lib2to3/tests/data/py2_test_grammar.py +++ b/Lib/test/test_lib2to3/data/py2_test_grammar.py @@ -735,7 +735,7 @@ hello world s = a[-5:] s = a[:-1] s = a[-4:-3] - # A rough test of SF bug 1333982. https://python.org/sf/1333982 + # A rough test of SF bug 1333982. https://bugs.python.org/issue1333982 # The testing here is fairly incomplete. # Test cases should include: commas with 1 and 2 colons d = {} diff --git a/Lib/lib2to3/tests/data/py3_test_grammar.py b/Lib/test/test_lib2to3/data/py3_test_grammar.py similarity index 99% rename from Lib/lib2to3/tests/data/py3_test_grammar.py rename to Lib/test/test_lib2to3/data/py3_test_grammar.py index a4a3f7ea..774851f5 100644 --- a/Lib/lib2to3/tests/data/py3_test_grammar.py +++ b/Lib/test/test_lib2to3/data/py3_test_grammar.py @@ -714,7 +714,7 @@ class GrammarTests(unittest.TestCase): s = a[-5:] s = a[:-1] s = a[-4:-3] - # A rough test of SF bug 1333982. https://python.org/sf/1333982 + # A rough test of SF bug 1333982. https://bugs.python.org/issue1333982 # The testing here is fairly incomplete. # Test cases should include: commas with 1 and 2 colons d = {} diff --git a/Lib/lib2to3/tests/pytree_idempotency.py b/Lib/test/test_lib2to3/pytree_idempotency.py similarity index 96% rename from Lib/lib2to3/tests/pytree_idempotency.py rename to Lib/test/test_lib2to3/pytree_idempotency.py index 2e7e9781..eb2e2aa0 100755 --- a/Lib/lib2to3/tests/pytree_idempotency.py +++ b/Lib/test/test_lib2to3/pytree_idempotency.py @@ -17,9 +17,9 @@ import sys import logging # Local imports -from .. import pytree -from .. import pgen2 -from ..pgen2 import driver +from lib2to3 import pytree +from lib2to3 import pgen2 +from lib2to3.pgen2 import driver logging.basicConfig() diff --git a/Lib/lib2to3/tests/support.py b/Lib/test/test_lib2to3/support.py similarity index 77% rename from Lib/lib2to3/tests/support.py rename to Lib/test/test_lib2to3/support.py index fe084e89..9e56273e 100644 --- a/Lib/lib2to3/tests/support.py +++ b/Lib/test/test_lib2to3/support.py @@ -8,12 +8,14 @@ import os.path from textwrap import dedent # Local imports +import lib2to3 from lib2to3 import pytree, refactor from lib2to3.pgen2 import driver as pgen2_driver +lib2to3_dir = os.path.dirname(lib2to3.__file__) test_dir = os.path.dirname(__file__) proj_dir = os.path.normpath(os.path.join(test_dir, "..")) -grammar_path = os.path.join(test_dir, "..", "Grammar.txt") +grammar_path = os.path.join(lib2to3_dir, "Grammar.txt") grammar = pgen2_driver.load_grammar(grammar_path) grammar_no_print_statement = pgen2_driver.load_grammar(grammar_path) del grammar_no_print_statement.keywords["print"] @@ -49,10 +51,19 @@ def get_refactorer(fixer_pkg="lib2to3", fixers=None, options=None): options = options or {} return refactor.RefactoringTool(fixers, options, explicit=True) -def all_project_files(): - for dirpath, dirnames, filenames in os.walk(proj_dir): +def _all_project_files(root, files): + for dirpath, dirnames, filenames in os.walk(root): for filename in filenames: - if filename.endswith(".py"): - yield os.path.join(dirpath, filename) + if not filename.endswith(".py"): + continue + files.append(os.path.join(dirpath, filename)) + +def all_project_files(): + files = [] + _all_project_files(lib2to3_dir, files) + _all_project_files(test_dir, files) + # Sort to get more reproducible tests + files.sort() + return files TestCase = unittest.TestCase diff --git a/Lib/lib2to3/tests/test_all_fixers.py b/Lib/test/test_lib2to3/test_all_fixers.py similarity index 99% rename from Lib/lib2to3/tests/test_all_fixers.py rename to Lib/test/test_lib2to3/test_all_fixers.py index a2659414..d0fca707 100644 --- a/Lib/lib2to3/tests/test_all_fixers.py +++ b/Lib/test/test_lib2to3/test_all_fixers.py @@ -7,7 +7,6 @@ running time. # Python imports import os.path -import sys import test.support import unittest diff --git a/Lib/lib2to3/tests/test_fixers.py b/Lib/test/test_lib2to3/test_fixers.py similarity index 99% rename from Lib/lib2to3/tests/test_fixers.py rename to Lib/test/test_lib2to3/test_fixers.py index 121ebe68..68efeee7 100644 --- a/Lib/lib2to3/tests/test_fixers.py +++ b/Lib/test/test_lib2to3/test_fixers.py @@ -7,7 +7,7 @@ from operator import itemgetter # Local imports from lib2to3 import pygram, fixer_util -from lib2to3.tests import support +from test.test_lib2to3 import support class FixerTestCase(support.TestCase): @@ -1791,7 +1791,7 @@ class ImportsFixerTests: class Test_imports(FixerTestCase, ImportsFixerTests): fixer = "imports" - from ..fixes.fix_imports import MAPPING as modules + from lib2to3.fixes.fix_imports import MAPPING as modules def test_multiple_imports(self): b = """import urlparse, cStringIO""" @@ -1812,16 +1812,16 @@ class Test_imports(FixerTestCase, ImportsFixerTests): class Test_imports2(FixerTestCase, ImportsFixerTests): fixer = "imports2" - from ..fixes.fix_imports2 import MAPPING as modules + from lib2to3.fixes.fix_imports2 import MAPPING as modules class Test_imports_fixer_order(FixerTestCase, ImportsFixerTests): def setUp(self): super(Test_imports_fixer_order, self).setUp(['imports', 'imports2']) - from ..fixes.fix_imports2 import MAPPING as mapping2 + from lib2to3.fixes.fix_imports2 import MAPPING as mapping2 self.modules = mapping2.copy() - from ..fixes.fix_imports import MAPPING as mapping1 + from lib2to3.fixes.fix_imports import MAPPING as mapping1 for key in ('dbhash', 'dumbdbm', 'dbm', 'gdbm'): self.modules[key] = mapping1[key] @@ -1833,7 +1833,7 @@ class Test_imports_fixer_order(FixerTestCase, ImportsFixerTests): class Test_urllib(FixerTestCase): fixer = "urllib" - from ..fixes.fix_urllib import MAPPING as modules + from lib2to3.fixes.fix_urllib import MAPPING as modules def test_import_module(self): for old, changes in self.modules.items(): diff --git a/Lib/lib2to3/tests/test_main.py b/Lib/test/test_lib2to3/test_main.py similarity index 100% rename from Lib/lib2to3/tests/test_main.py rename to Lib/test/test_lib2to3/test_main.py diff --git a/Lib/lib2to3/tests/test_parser.py b/Lib/test/test_lib2to3/test_parser.py similarity index 99% rename from Lib/lib2to3/tests/test_parser.py rename to Lib/test/test_lib2to3/test_parser.py index 8e7773bc..2c798b18 100644 --- a/Lib/lib2to3/tests/test_parser.py +++ b/Lib/test/test_lib2to3/test_parser.py @@ -26,7 +26,7 @@ import unittest # Local imports from lib2to3.pgen2 import driver as pgen2_driver from lib2to3.pgen2 import tokenize -from ..pgen2.parse import ParseError +from lib2to3.pgen2.parse import ParseError from lib2to3.pygram import python_symbols as syms diff --git a/Lib/lib2to3/tests/test_pytree.py b/Lib/test/test_lib2to3/test_pytree.py similarity index 100% rename from Lib/lib2to3/tests/test_pytree.py rename to Lib/test/test_lib2to3/test_pytree.py diff --git a/Lib/lib2to3/tests/test_refactor.py b/Lib/test/test_lib2to3/test_refactor.py similarity index 100% rename from Lib/lib2to3/tests/test_refactor.py rename to Lib/test/test_lib2to3/test_refactor.py diff --git a/Lib/lib2to3/tests/test_util.py b/Lib/test/test_lib2to3/test_util.py similarity index 100% rename from Lib/lib2to3/tests/test_util.py rename to Lib/test/test_lib2to3/test_util.py diff --git a/Lib/test/test_list.py b/Lib/test/test_list.py index 9aa6dd10..2969c6e2 100644 --- a/Lib/test/test_list.py +++ b/Lib/test/test_list.py @@ -103,7 +103,7 @@ class ListTest(list_tests.CommonTest): del lst[1:] self.assertEqual(len(lst), 1) - size = ((2 ** (tuple.__itemsize__ * 8) - 1) // 2) + size = sys.maxsize with self.assertRaises((MemoryError, OverflowError)): lst * size with self.assertRaises((MemoryError, OverflowError)): diff --git a/Lib/test/test_listcomps.py b/Lib/test/test_listcomps.py index 91bf2547..12f7bbd1 100644 --- a/Lib/test/test_listcomps.py +++ b/Lib/test/test_listcomps.py @@ -1,4 +1,5 @@ import doctest +import textwrap import unittest @@ -87,63 +88,530 @@ Make sure that None is a valid return value >>> [None for i in range(10)] [None, None, None, None, None, None, None, None, None, None] -########### Tests for various scoping corner cases ############ - -Return lambdas that use the iteration variable as a default argument - - >>> items = [(lambda i=i: i) for i in range(5)] - >>> [x() for x in items] - [0, 1, 2, 3, 4] - -Same again, only this time as a closure variable - - >>> items = [(lambda: i) for i in range(5)] - >>> [x() for x in items] - [4, 4, 4, 4, 4] - -Another way to test that the iteration variable is local to the list comp - - >>> items = [(lambda: i) for i in range(5)] - >>> i = 20 - >>> [x() for x in items] - [4, 4, 4, 4, 4] - -And confirm that a closure can jump over the list comp scope - - >>> items = [(lambda: y) for i in range(5)] - >>> y = 2 - >>> [x() for x in items] - [2, 2, 2, 2, 2] - -We also repeat each of the above scoping tests inside a function - - >>> def test_func(): - ... items = [(lambda i=i: i) for i in range(5)] - ... return [x() for x in items] - >>> test_func() - [0, 1, 2, 3, 4] +""" - >>> def test_func(): - ... items = [(lambda: i) for i in range(5)] - ... return [x() for x in items] - >>> test_func() - [4, 4, 4, 4, 4] - - >>> def test_func(): - ... items = [(lambda: i) for i in range(5)] - ... i = 20 - ... return [x() for x in items] - >>> test_func() - [4, 4, 4, 4, 4] - - >>> def test_func(): - ... items = [(lambda: y) for i in range(5)] - ... y = 2 - ... return [x() for x in items] - >>> test_func() - [2, 2, 2, 2, 2] -""" +class ListComprehensionTest(unittest.TestCase): + def _check_in_scopes(self, code, outputs=None, ns=None, scopes=None, raises=()): + code = textwrap.dedent(code) + scopes = scopes or ["module", "class", "function"] + for scope in scopes: + with self.subTest(scope=scope): + if scope == "class": + newcode = textwrap.dedent(""" + class _C: + {code} + """).format(code=textwrap.indent(code, " ")) + def get_output(moddict, name): + return getattr(moddict["_C"], name) + elif scope == "function": + newcode = textwrap.dedent(""" + def _f(): + {code} + return locals() + _out = _f() + """).format(code=textwrap.indent(code, " ")) + def get_output(moddict, name): + return moddict["_out"][name] + else: + newcode = code + def get_output(moddict, name): + return moddict[name] + newns = ns.copy() if ns else {} + try: + exec(newcode, newns) + except raises as e: + # We care about e.g. NameError vs UnboundLocalError + self.assertIs(type(e), raises) + else: + for k, v in (outputs or {}).items(): + self.assertEqual(get_output(newns, k), v, k) + + def test_lambdas_with_iteration_var_as_default(self): + code = """ + items = [(lambda i=i: i) for i in range(5)] + y = [x() for x in items] + """ + outputs = {"y": [0, 1, 2, 3, 4]} + self._check_in_scopes(code, outputs) + + def test_lambdas_with_free_var(self): + code = """ + items = [(lambda: i) for i in range(5)] + y = [x() for x in items] + """ + outputs = {"y": [4, 4, 4, 4, 4]} + self._check_in_scopes(code, outputs) + + def test_class_scope_free_var_with_class_cell(self): + class C: + def method(self): + super() + return __class__ + items = [(lambda: i) for i in range(5)] + y = [x() for x in items] + + self.assertEqual(C.y, [4, 4, 4, 4, 4]) + self.assertIs(C().method(), C) + + def test_inner_cell_shadows_outer(self): + code = """ + items = [(lambda: i) for i in range(5)] + i = 20 + y = [x() for x in items] + """ + outputs = {"y": [4, 4, 4, 4, 4], "i": 20} + self._check_in_scopes(code, outputs) + + def test_inner_cell_shadows_outer_no_store(self): + code = """ + def f(x): + return [lambda: x for x in range(x)], x + fns, x = f(2) + y = [fn() for fn in fns] + """ + outputs = {"y": [1, 1], "x": 2} + self._check_in_scopes(code, outputs) + + def test_closure_can_jump_over_comp_scope(self): + code = """ + items = [(lambda: y) for i in range(5)] + y = 2 + z = [x() for x in items] + """ + outputs = {"z": [2, 2, 2, 2, 2]} + self._check_in_scopes(code, outputs, scopes=["module", "function"]) + + def test_cell_inner_free_outer(self): + code = """ + def f(): + return [lambda: x for x in (x, [1])[1]] + x = ... + y = [fn() for fn in f()] + """ + outputs = {"y": [1]} + self._check_in_scopes(code, outputs, scopes=["module", "function"]) + + def test_free_inner_cell_outer(self): + code = """ + g = 2 + def f(): + return g + y = [g for x in [1]] + """ + outputs = {"y": [2]} + self._check_in_scopes(code, outputs, scopes=["module", "function"]) + self._check_in_scopes(code, scopes=["class"], raises=NameError) + + def test_inner_cell_shadows_outer_redefined(self): + code = """ + y = 10 + items = [(lambda: y) for y in range(5)] + x = y + y = 20 + out = [z() for z in items] + """ + outputs = {"x": 10, "out": [4, 4, 4, 4, 4]} + self._check_in_scopes(code, outputs) + + def test_shadows_outer_cell(self): + code = """ + def inner(): + return g + [g for g in range(5)] + x = inner() + """ + outputs = {"x": -1} + self._check_in_scopes(code, outputs, ns={"g": -1}) + + def test_explicit_global(self): + code = """ + global g + x = g + g = 2 + items = [g for g in [1]] + y = g + """ + outputs = {"x": 1, "y": 2, "items": [1]} + self._check_in_scopes(code, outputs, ns={"g": 1}) + + def test_explicit_global_2(self): + code = """ + global g + x = g + g = 2 + items = [g for x in [1]] + y = g + """ + outputs = {"x": 1, "y": 2, "items": [2]} + self._check_in_scopes(code, outputs, ns={"g": 1}) + + def test_explicit_global_3(self): + code = """ + global g + fns = [lambda: g for g in [2]] + items = [fn() for fn in fns] + """ + outputs = {"items": [2]} + self._check_in_scopes(code, outputs, ns={"g": 1}) + + def test_assignment_expression(self): + code = """ + x = -1 + items = [(x:=y) for y in range(3)] + """ + outputs = {"x": 2} + # assignment expression in comprehension is disallowed in class scope + self._check_in_scopes(code, outputs, scopes=["module", "function"]) + + def test_free_var_in_comp_child(self): + code = """ + lst = range(3) + funcs = [lambda: x for x in lst] + inc = [x + 1 for x in lst] + [x for x in inc] + x = funcs[0]() + """ + outputs = {"x": 2} + self._check_in_scopes(code, outputs) + + def test_shadow_with_free_and_local(self): + code = """ + lst = range(3) + x = -1 + funcs = [lambda: x for x in lst] + items = [x + 1 for x in lst] + """ + outputs = {"x": -1} + self._check_in_scopes(code, outputs) + + def test_shadow_comp_iterable_name(self): + code = """ + x = [1] + y = [x for x in x] + """ + outputs = {"x": [1]} + self._check_in_scopes(code, outputs) + + def test_nested_free(self): + code = """ + x = 1 + def g(): + [x for x in range(3)] + return x + g() + """ + outputs = {"x": 1} + self._check_in_scopes(code, outputs, scopes=["module", "function"]) + + def test_introspecting_frame_locals(self): + code = """ + import sys + [i for i in range(2)] + i = 20 + sys._getframe().f_locals + """ + outputs = {"i": 20} + self._check_in_scopes(code, outputs) + + def test_nested(self): + code = """ + l = [2, 3] + y = [[x ** 2 for x in range(x)] for x in l] + """ + outputs = {"y": [[0, 1], [0, 1, 4]]} + self._check_in_scopes(code, outputs) + + def test_nested_2(self): + code = """ + l = [1, 2, 3] + x = 3 + y = [x for [x ** x for x in range(x)][x - 1] in l] + """ + outputs = {"y": [3, 3, 3]} + self._check_in_scopes(code, outputs, scopes=["module", "function"]) + self._check_in_scopes(code, scopes=["class"], raises=NameError) + + def test_nested_3(self): + code = """ + l = [(1, 2), (3, 4), (5, 6)] + y = [x for (x, [x ** x for x in range(x)][x - 1]) in l] + """ + outputs = {"y": [1, 3, 5]} + self._check_in_scopes(code, outputs) + + def test_nested_4(self): + code = """ + items = [([lambda: x for x in range(2)], lambda: x) for x in range(3)] + out = [([fn() for fn in fns], fn()) for fns, fn in items] + """ + outputs = {"out": [([1, 1], 2), ([1, 1], 2), ([1, 1], 2)]} + self._check_in_scopes(code, outputs) + + def test_nameerror(self): + code = """ + [x for x in [1]] + x + """ + + self._check_in_scopes(code, raises=NameError) + + def test_dunder_name(self): + code = """ + y = [__x for __x in [1]] + """ + outputs = {"y": [1]} + self._check_in_scopes(code, outputs) + + def test_unbound_local_after_comprehension(self): + def f(): + if False: + x = 0 + [x for x in [1]] + return x + + with self.assertRaises(UnboundLocalError): + f() + + def test_unbound_local_inside_comprehension(self): + def f(): + l = [None] + return [1 for (l[0], l) in [[1, 2]]] + + with self.assertRaises(UnboundLocalError): + f() + + def test_global_outside_cellvar_inside_plus_freevar(self): + code = """ + a = 1 + def f(): + func, = [(lambda: b) for b in [a]] + return b, func() + x = f() + """ + self._check_in_scopes( + code, {"x": (2, 1)}, ns={"b": 2}, scopes=["function", "module"]) + # inside a class, the `a = 1` assignment is not visible + self._check_in_scopes(code, raises=NameError, scopes=["class"]) + + def test_cell_in_nested_comprehension(self): + code = """ + a = 1 + def f(): + (func, inner_b), = [[lambda: b for b in c] + [b] for c in [[a]]] + return b, inner_b, func() + x = f() + """ + self._check_in_scopes( + code, {"x": (2, 2, 1)}, ns={"b": 2}, scopes=["function", "module"]) + # inside a class, the `a = 1` assignment is not visible + self._check_in_scopes(code, raises=NameError, scopes=["class"]) + + def test_name_error_in_class_scope(self): + code = """ + y = 1 + [x + y for x in range(2)] + """ + self._check_in_scopes(code, raises=NameError, scopes=["class"]) + + def test_global_in_class_scope(self): + code = """ + y = 2 + vals = [(x, y) for x in range(2)] + """ + outputs = {"vals": [(0, 1), (1, 1)]} + self._check_in_scopes(code, outputs, ns={"y": 1}, scopes=["class"]) + + def test_in_class_scope_inside_function_1(self): + code = """ + class C: + y = 2 + vals = [(x, y) for x in range(2)] + vals = C.vals + """ + outputs = {"vals": [(0, 1), (1, 1)]} + self._check_in_scopes(code, outputs, ns={"y": 1}, scopes=["function"]) + + def test_in_class_scope_inside_function_2(self): + code = """ + y = 1 + class C: + y = 2 + vals = [(x, y) for x in range(2)] + vals = C.vals + """ + outputs = {"vals": [(0, 1), (1, 1)]} + self._check_in_scopes(code, outputs, scopes=["function"]) + + def test_in_class_scope_with_global(self): + code = """ + y = 1 + class C: + global y + y = 2 + # Ensure the listcomp uses the global, not the value in the + # class namespace + locals()['y'] = 3 + vals = [(x, y) for x in range(2)] + vals = C.vals + """ + outputs = {"vals": [(0, 2), (1, 2)]} + self._check_in_scopes(code, outputs, scopes=["module", "class"]) + outputs = {"vals": [(0, 1), (1, 1)]} + self._check_in_scopes(code, outputs, scopes=["function"]) + + def test_in_class_scope_with_nonlocal(self): + code = """ + y = 1 + class C: + nonlocal y + y = 2 + # Ensure the listcomp uses the global, not the value in the + # class namespace + locals()['y'] = 3 + vals = [(x, y) for x in range(2)] + vals = C.vals + """ + outputs = {"vals": [(0, 2), (1, 2)]} + self._check_in_scopes(code, outputs, scopes=["function"]) + + def test_nested_has_free_var(self): + code = """ + items = [a for a in [1] if [a for _ in [0]]] + """ + outputs = {"items": [1]} + self._check_in_scopes(code, outputs, scopes=["class"]) + + def test_nested_free_var_not_bound_in_outer_comp(self): + code = """ + z = 1 + items = [a for a in [1] if [x for x in [1] if z]] + """ + self._check_in_scopes(code, {"items": [1]}, scopes=["module", "function"]) + self._check_in_scopes(code, {"items": []}, ns={"z": 0}, scopes=["class"]) + + def test_nested_free_var_in_iter(self): + code = """ + items = [_C for _C in [1] for [0, 1][[x for x in [1] if _C][0]] in [2]] + """ + self._check_in_scopes(code, {"items": [1]}) + + def test_nested_free_var_in_expr(self): + code = """ + items = [(_C, [x for x in [1] if _C]) for _C in [0, 1]] + """ + self._check_in_scopes(code, {"items": [(0, []), (1, [1])]}) + + def test_nested_listcomp_in_lambda(self): + code = """ + f = [(z, lambda y: [(x, y, z) for x in [3]]) for z in [1]] + (z, func), = f + out = func(2) + """ + self._check_in_scopes(code, {"z": 1, "out": [(3, 2, 1)]}) + + def test_lambda_in_iter(self): + code = """ + (func, c), = [(a, b) for b in [1] for a in [lambda : a]] + d = func() + assert d is func + # must use "a" in this scope + e = a if False else None + """ + self._check_in_scopes(code, {"c": 1, "e": None}) + + def test_assign_to_comp_iter_var_in_outer_function(self): + code = """ + a = [1 for a in [0]] + """ + self._check_in_scopes(code, {"a": [1]}, scopes=["function"]) + + def test_no_leakage_to_locals(self): + code = """ + def b(): + [a for b in [1] for _ in []] + return b, locals() + r, s = b() + x = r is b + y = list(s.keys()) + """ + self._check_in_scopes(code, {"x": True, "y": []}, scopes=["module"]) + self._check_in_scopes(code, {"x": True, "y": ["b"]}, scopes=["function"]) + self._check_in_scopes(code, raises=NameError, scopes=["class"]) + + def test_iter_var_available_in_locals(self): + code = """ + l = [1, 2] + y = 0 + items = [locals()["x"] for x in l] + items2 = [vars()["x"] for x in l] + items3 = [("x" in dir()) for x in l] + items4 = [eval("x") for x in l] + # x is available, and does not overwrite y + [exec("y = x") for x in l] + """ + self._check_in_scopes( + code, + { + "items": [1, 2], + "items2": [1, 2], + "items3": [True, True], + "items4": [1, 2], + "y": 0 + } + ) + + def test_comp_in_try_except(self): + template = """ + value = ["ab"] + result = snapshot = None + try: + result = [{func}(value) for value in value] + except: + snapshot = value + raise + """ + # No exception. + code = template.format(func='len') + self._check_in_scopes(code, {"value": ["ab"], "result": [2], "snapshot": None}) + # Handles exception. + code = template.format(func='int') + self._check_in_scopes(code, {"value": ["ab"], "result": None, "snapshot": ["ab"]}, + raises=ValueError) + + def test_comp_in_try_finally(self): + template = """ + value = ["ab"] + result = snapshot = None + try: + result = [{func}(value) for value in value] + finally: + snapshot = value + """ + # No exception. + code = template.format(func='len') + self._check_in_scopes(code, {"value": ["ab"], "result": [2], "snapshot": ["ab"]}) + # Handles exception. + code = template.format(func='int') + self._check_in_scopes(code, {"value": ["ab"], "result": None, "snapshot": ["ab"]}, + raises=ValueError) + + def test_exception_in_post_comp_call(self): + code = """ + value = [1, None] + try: + [v for v in value].sort() + except: + pass + """ + self._check_in_scopes(code, {"value": [1, None]}) + + def test_frame_locals(self): + code = """ + val = [sys._getframe().f_locals for a in [0]][0]["a"] + """ + import sys + self._check_in_scopes(code, {"val": 0}, ns={"sys": sys}) __test__ = {'doctests' : doctests} diff --git a/Lib/test/test_lltrace.py b/Lib/test/test_lltrace.py index 63b65e4b..f638b649 100644 --- a/Lib/test/test_lltrace.py +++ b/Lib/test/test_lltrace.py @@ -1,22 +1,21 @@ import dis -import sys import textwrap import unittest -from test.support import os_helper, verbose +from test import support +from test.support import os_helper from test.support.script_helper import assert_python_ok def example(): x = [] - for i in range(1): + for i in range(0): x.append(i) x = "this is" y = "an example" print(x, y) -Py_DEBUG = hasattr(sys, 'gettotalrefcount') -@unittest.skipUnless(Py_DEBUG, "lltrace requires Py_DEBUG") +@unittest.skipUnless(support.Py_DEBUG, "lltrace requires Py_DEBUG") class TestLLTrace(unittest.TestCase): def run_code(self, code): @@ -28,7 +27,7 @@ class TestLLTrace(unittest.TestCase): self.assertEqual(stderr, b"") self.assertEqual(status, 0) result = stdout.decode('utf-8') - if verbose: + if support.verbose: print("\n\n--- code ---") print(code) print("\n--- stdout ---") @@ -55,7 +54,7 @@ class TestLLTrace(unittest.TestCase): """) self.assertIn("GET_ITER", stdout) self.assertIn("FOR_ITER", stdout) - self.assertIn("UNARY_POSITIVE", stdout) + self.assertIn("CALL_INTRINSIC_1", stdout) self.assertIn("POP_TOP", stdout) self.assertNotIn("BINARY_OP", stdout) self.assertNotIn("UNARY_NEGATIVE", stdout) @@ -76,7 +75,7 @@ class TestLLTrace(unittest.TestCase): self.assertIn('this is an example', stdout) # check that offsets match the output of dis.dis() - instr_map = {i.offset: i for i in dis.get_instructions(example)} + instr_map = {i.offset: i for i in dis.get_instructions(example, adaptive=True)} for line in stdout.splitlines(): offset, colon, opname_oparg = line.partition(":") if not colon: diff --git a/Lib/test/test_locale.py b/Lib/test/test_locale.py index bc8a7a35..b0d79985 100644 --- a/Lib/test/test_locale.py +++ b/Lib/test/test_locale.py @@ -141,18 +141,9 @@ class BaseFormattingTest(object): # Utility functions for formatting tests # - def _test_formatfunc(self, format, value, out, func, **format_opts): - self.assertEqual( - func(format, value, **format_opts), out) - - def _test_format(self, format, value, out, **format_opts): - with check_warnings(('', DeprecationWarning)): - self._test_formatfunc(format, value, out, - func=locale.format, **format_opts) - def _test_format_string(self, format, value, out, **format_opts): - self._test_formatfunc(format, value, out, - func=locale.format_string, **format_opts) + self.assertEqual( + locale.format_string(format, value, **format_opts), out) def _test_currency(self, value, out, **format_opts): self.assertEqual(locale.currency(value, **format_opts), out) @@ -166,44 +157,40 @@ class EnUSNumberFormatting(BaseFormattingTest): self.sep = locale.localeconv()['thousands_sep'] def test_grouping(self): - self._test_format("%f", 1024, grouping=1, out='1%s024.000000' % self.sep) - self._test_format("%f", 102, grouping=1, out='102.000000') - self._test_format("%f", -42, grouping=1, out='-42.000000') - self._test_format("%+f", -42, grouping=1, out='-42.000000') + self._test_format_string("%f", 1024, grouping=1, out='1%s024.000000' % self.sep) + self._test_format_string("%f", 102, grouping=1, out='102.000000') + self._test_format_string("%f", -42, grouping=1, out='-42.000000') + self._test_format_string("%+f", -42, grouping=1, out='-42.000000') def test_grouping_and_padding(self): - self._test_format("%20.f", -42, grouping=1, out='-42'.rjust(20)) + self._test_format_string("%20.f", -42, grouping=1, out='-42'.rjust(20)) if self.sep: - self._test_format("%+10.f", -4200, grouping=1, + self._test_format_string("%+10.f", -4200, grouping=1, out=('-4%s200' % self.sep).rjust(10)) - self._test_format("%-10.f", -4200, grouping=1, + self._test_format_string("%-10.f", -4200, grouping=1, out=('-4%s200' % self.sep).ljust(10)) def test_integer_grouping(self): - self._test_format("%d", 4200, grouping=True, out='4%s200' % self.sep) - self._test_format("%+d", 4200, grouping=True, out='+4%s200' % self.sep) - self._test_format("%+d", -4200, grouping=True, out='-4%s200' % self.sep) + self._test_format_string("%d", 4200, grouping=True, out='4%s200' % self.sep) + self._test_format_string("%+d", 4200, grouping=True, out='+4%s200' % self.sep) + self._test_format_string("%+d", -4200, grouping=True, out='-4%s200' % self.sep) def test_integer_grouping_and_padding(self): - self._test_format("%10d", 4200, grouping=True, + self._test_format_string("%10d", 4200, grouping=True, out=('4%s200' % self.sep).rjust(10)) - self._test_format("%-10d", -4200, grouping=True, + self._test_format_string("%-10d", -4200, grouping=True, out=('-4%s200' % self.sep).ljust(10)) def test_simple(self): - self._test_format("%f", 1024, grouping=0, out='1024.000000') - self._test_format("%f", 102, grouping=0, out='102.000000') - self._test_format("%f", -42, grouping=0, out='-42.000000') - self._test_format("%+f", -42, grouping=0, out='-42.000000') + self._test_format_string("%f", 1024, grouping=0, out='1024.000000') + self._test_format_string("%f", 102, grouping=0, out='102.000000') + self._test_format_string("%f", -42, grouping=0, out='-42.000000') + self._test_format_string("%+f", -42, grouping=0, out='-42.000000') def test_padding(self): - self._test_format("%20.f", -42, grouping=0, out='-42'.rjust(20)) - self._test_format("%+10.f", -4200, grouping=0, out='-4200'.rjust(10)) - self._test_format("%-10.f", 4200, grouping=0, out='4200'.ljust(10)) - - def test_format_deprecation(self): - with self.assertWarns(DeprecationWarning): - locale.format("%-10.f", 4200, grouping=True) + self._test_format_string("%20.f", -42, grouping=0, out='-42'.rjust(20)) + self._test_format_string("%+10.f", -4200, grouping=0, out='-4200'.rjust(10)) + self._test_format_string("%-10.f", 4200, grouping=0, out='4200'.ljust(10)) def test_complex_formatting(self): # Spaces in formatting string @@ -230,20 +217,9 @@ class EnUSNumberFormatting(BaseFormattingTest): out='int 1%s000 float 1%s000.00 str str' % (self.sep, self.sep)) - -class TestFormatPatternArg(unittest.TestCase): - # Test handling of pattern argument of format - - def test_onlyOnePattern(self): - with check_warnings(('', DeprecationWarning)): - # Issue 2522: accept exactly one % pattern, and no extra chars. - self.assertRaises(ValueError, locale.format, "%f\n", 'foo') - self.assertRaises(ValueError, locale.format, "%f\r", 'foo') - self.assertRaises(ValueError, locale.format, "%f\r\n", 'foo') - self.assertRaises(ValueError, locale.format, " %f", 'foo') - self.assertRaises(ValueError, locale.format, "%fg", 'foo') - self.assertRaises(ValueError, locale.format, "%^g", 'foo') - self.assertRaises(ValueError, locale.format, "%f%%", 'foo') + self._test_format_string("total=%i%%", 100, out='total=100%') + self._test_format_string("newline: %i\n", 3, out='newline: 3\n') + self._test_format_string("extra: %ii", 3, out='extra: 3i') class TestLocaleFormatString(unittest.TestCase): @@ -292,45 +268,45 @@ class TestCNumberFormatting(CCookedTest, BaseFormattingTest): # Test number formatting with a cooked "C" locale. def test_grouping(self): - self._test_format("%.2f", 12345.67, grouping=True, out='12345.67') + self._test_format_string("%.2f", 12345.67, grouping=True, out='12345.67') def test_grouping_and_padding(self): - self._test_format("%9.2f", 12345.67, grouping=True, out=' 12345.67') + self._test_format_string("%9.2f", 12345.67, grouping=True, out=' 12345.67') class TestFrFRNumberFormatting(FrFRCookedTest, BaseFormattingTest): # Test number formatting with a cooked "fr_FR" locale. def test_decimal_point(self): - self._test_format("%.2f", 12345.67, out='12345,67') + self._test_format_string("%.2f", 12345.67, out='12345,67') def test_grouping(self): - self._test_format("%.2f", 345.67, grouping=True, out='345,67') - self._test_format("%.2f", 12345.67, grouping=True, out='12 345,67') + self._test_format_string("%.2f", 345.67, grouping=True, out='345,67') + self._test_format_string("%.2f", 12345.67, grouping=True, out='12 345,67') def test_grouping_and_padding(self): - self._test_format("%6.2f", 345.67, grouping=True, out='345,67') - self._test_format("%7.2f", 345.67, grouping=True, out=' 345,67') - self._test_format("%8.2f", 12345.67, grouping=True, out='12 345,67') - self._test_format("%9.2f", 12345.67, grouping=True, out='12 345,67') - self._test_format("%10.2f", 12345.67, grouping=True, out=' 12 345,67') - self._test_format("%-6.2f", 345.67, grouping=True, out='345,67') - self._test_format("%-7.2f", 345.67, grouping=True, out='345,67 ') - self._test_format("%-8.2f", 12345.67, grouping=True, out='12 345,67') - self._test_format("%-9.2f", 12345.67, grouping=True, out='12 345,67') - self._test_format("%-10.2f", 12345.67, grouping=True, out='12 345,67 ') + self._test_format_string("%6.2f", 345.67, grouping=True, out='345,67') + self._test_format_string("%7.2f", 345.67, grouping=True, out=' 345,67') + self._test_format_string("%8.2f", 12345.67, grouping=True, out='12 345,67') + self._test_format_string("%9.2f", 12345.67, grouping=True, out='12 345,67') + self._test_format_string("%10.2f", 12345.67, grouping=True, out=' 12 345,67') + self._test_format_string("%-6.2f", 345.67, grouping=True, out='345,67') + self._test_format_string("%-7.2f", 345.67, grouping=True, out='345,67 ') + self._test_format_string("%-8.2f", 12345.67, grouping=True, out='12 345,67') + self._test_format_string("%-9.2f", 12345.67, grouping=True, out='12 345,67') + self._test_format_string("%-10.2f", 12345.67, grouping=True, out='12 345,67 ') def test_integer_grouping(self): - self._test_format("%d", 200, grouping=True, out='200') - self._test_format("%d", 4200, grouping=True, out='4 200') + self._test_format_string("%d", 200, grouping=True, out='200') + self._test_format_string("%d", 4200, grouping=True, out='4 200') def test_integer_grouping_and_padding(self): - self._test_format("%4d", 4200, grouping=True, out='4 200') - self._test_format("%5d", 4200, grouping=True, out='4 200') - self._test_format("%10d", 4200, grouping=True, out='4 200'.rjust(10)) - self._test_format("%-4d", 4200, grouping=True, out='4 200') - self._test_format("%-5d", 4200, grouping=True, out='4 200') - self._test_format("%-10d", 4200, grouping=True, out='4 200'.ljust(10)) + self._test_format_string("%4d", 4200, grouping=True, out='4 200') + self._test_format_string("%5d", 4200, grouping=True, out='4 200') + self._test_format_string("%10d", 4200, grouping=True, out='4 200'.rjust(10)) + self._test_format_string("%-4d", 4200, grouping=True, out='4 200') + self._test_format_string("%-5d", 4200, grouping=True, out='4 200') + self._test_format_string("%-10d", 4200, grouping=True, out='4 200'.ljust(10)) def test_currency(self): euro = '\u20ac' diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py index 350f4a57..b7f4c6ed 100644 --- a/Lib/test/test_logging.py +++ b/Lib/test/test_logging.py @@ -18,7 +18,6 @@ Copyright (C) 2001-2022 Vinay Sajip. All Rights Reserved. """ - import logging import logging.handlers import logging.config @@ -30,6 +29,7 @@ import datetime import pathlib import pickle import io +import itertools import gc import json import os @@ -47,9 +47,11 @@ from test.support import os_helper from test.support import socket_helper from test.support import threading_helper from test.support import warnings_helper +from test.support import asyncore from test.support.logging_helper import TestHandler import textwrap import threading +import asyncio import time import unittest import warnings @@ -60,10 +62,8 @@ from urllib.parse import urlparse, parse_qs from socketserver import (ThreadingUDPServer, DatagramRequestHandler, ThreadingTCPServer, StreamRequestHandler) - -asyncore = warnings_helper.import_deprecated('asyncore') -smtpd = warnings_helper.import_deprecated('smtpd') - +with warnings.catch_warnings(): + from . import smtpd try: import win32evtlog, win32evtlogutil, pywintypes @@ -467,6 +467,51 @@ class CustomLevelsAndFiltersTest(BaseTest): for lvl in LEVEL_RANGE: logger.log(lvl, self.next_message()) + def test_handler_filter_replaces_record(self): + def replace_message(record: logging.LogRecord): + record = copy.copy(record) + record.msg = "new message!" + return record + + # Set up a logging hierarchy such that "child" and it's handler + # (and thus `replace_message()`) always get called before + # propagating up to "parent". + # Then we can confirm that `replace_message()` was able to + # replace the log record without having a side effect on + # other loggers or handlers. + parent = logging.getLogger("parent") + child = logging.getLogger("parent.child") + stream_1 = io.StringIO() + stream_2 = io.StringIO() + handler_1 = logging.StreamHandler(stream_1) + handler_2 = logging.StreamHandler(stream_2) + handler_2.addFilter(replace_message) + parent.addHandler(handler_1) + child.addHandler(handler_2) + + child.info("original message") + handler_1.flush() + handler_2.flush() + self.assertEqual(stream_1.getvalue(), "original message\n") + self.assertEqual(stream_2.getvalue(), "new message!\n") + + def test_logging_filter_replaces_record(self): + records = set() + + class RecordingFilter(logging.Filter): + def filter(self, record: logging.LogRecord): + records.add(id(record)) + return copy.copy(record) + + logger = logging.getLogger("logger") + logger.setLevel(logging.INFO) + logger.addFilter(RecordingFilter()) + logger.addFilter(RecordingFilter()) + + logger.info("msg") + + self.assertEqual(2, len(records)) + def test_logger_filter(self): # Filter at logger level. self.root_logger.setLevel(VERBOSE) @@ -540,6 +585,12 @@ class CustomLevelsAndFiltersTest(BaseTest): handler.removeFilter(garr) +def make_temp_file(*args, **kwargs): + fd, fn = tempfile.mkstemp(*args, **kwargs) + os.close(fd) + return fn + + class HandlerTest(BaseTest): def test_name(self): h = logging.Handler() @@ -554,8 +605,7 @@ class HandlerTest(BaseTest): # but we can try instantiating them with various options if sys.platform in ('linux', 'darwin'): for existing in (True, False): - fd, fn = tempfile.mkstemp() - os.close(fd) + fn = make_temp_file() if not existing: os.unlink(fn) h = logging.handlers.WatchedFileHandler(fn, encoding='utf-8', delay=True) @@ -609,8 +659,7 @@ class HandlerTest(BaseTest): See Issue #27493. """ - fd, fn = tempfile.mkstemp() - os.close(fd) + fn = make_temp_file() os.unlink(fn) pfn = pathlib.Path(fn) cases = ( @@ -631,6 +680,7 @@ class HandlerTest(BaseTest): support.is_emscripten, "Emscripten cannot fstat unlinked files." ) @threading_helper.requires_working_threading() + @support.requires_resource('walltime') def test_race(self): # Issue #14632 refers. def remove_loop(fname, tries): @@ -649,8 +699,7 @@ class HandlerTest(BaseTest): self.deletion_time = None for delay in (False, True): - fd, fn = tempfile.mkstemp('.log', 'test_logging-3-') - os.close(fd) + fn = make_temp_file('.log', 'test_logging-3-') remover = threading.Thread(target=remove_loop, args=(fn, del_count)) remover.daemon = True remover.start() @@ -1175,6 +1224,35 @@ class MemoryHandlerTest(BaseTest): # assert that no new lines have been added self.assert_log_lines(lines) # no change + def test_shutdown_flush_on_close(self): + """ + Test that the flush-on-close configuration is respected by the + shutdown method. + """ + self.mem_logger.debug(self.next_message()) + self.assert_log_lines([]) + self.mem_logger.info(self.next_message()) + self.assert_log_lines([]) + # Default behaviour is to flush on close. Check that it happens. + logging.shutdown(handlerList=[logging.weakref.ref(self.mem_hdlr)]) + lines = [ + ('DEBUG', '1'), + ('INFO', '2'), + ] + self.assert_log_lines(lines) + # Now configure for flushing not to be done on close. + self.mem_hdlr = logging.handlers.MemoryHandler(10, logging.WARNING, + self.root_hdlr, + False) + self.mem_logger.addHandler(self.mem_hdlr) + self.mem_logger.debug(self.next_message()) + self.assert_log_lines(lines) # no change + self.mem_logger.info(self.next_message()) + self.assert_log_lines(lines) # no change + # assert that no new lines have been added after shutdown + logging.shutdown(handlerList=[logging.weakref.ref(self.mem_hdlr)]) + self.assert_log_lines(lines) # no change + @threading_helper.requires_working_threading() def test_race_between_set_target_and_flush(self): class MockRaceConditionHandler: @@ -1208,6 +1286,9 @@ class ExceptionFormatter(logging.Formatter): def formatException(self, ei): return "Got a [%s]" % ei[0].__name__ +def closeFileHandler(h, fn): + h.close() + os.remove(fn) class ConfigFileTest(BaseTest): @@ -1444,6 +1525,32 @@ class ConfigFileTest(BaseTest): kwargs={{"encoding": "utf-8"}} """ + + config9 = """ + [loggers] + keys=root + + [handlers] + keys=hand1 + + [formatters] + keys=form1 + + [logger_root] + level=WARNING + handlers=hand1 + + [handler_hand1] + class=StreamHandler + level=NOTSET + formatter=form1 + args=(sys.stdout,) + + [formatter_form1] + format=%(message)s ++ %(customfield)s + defaults={"customfield": "defaultvalue"} + """ + disable_test = """ [loggers] keys=root @@ -1591,13 +1698,8 @@ class ConfigFileTest(BaseTest): def test_config8_ok(self): - def cleanup(h1, fn): - h1.close() - os.remove(fn) - with self.check_no_resource_warning(): - fd, fn = tempfile.mkstemp(".log", "test_logging-X-") - os.close(fd) + fn = make_temp_file(".log", "test_logging-X-") # Replace single backslash with double backslash in windows # to avoid unicode error during string formatting @@ -1610,7 +1712,17 @@ class ConfigFileTest(BaseTest): self.apply_config(config8) handler = logging.root.handlers[0] - self.addCleanup(cleanup, handler, fn) + self.addCleanup(closeFileHandler, handler, fn) + + def test_config9_ok(self): + self.apply_config(self.config9) + formatter = logging.root.handlers[0].formatter + result = formatter.format(logging.makeLogRecord({'msg': 'test'})) + self.assertEqual(result, 'test ++ defaultvalue') + result = formatter.format(logging.makeLogRecord( + {'msg': 'test', 'customfield': "customvalue"})) + self.assertEqual(result, 'test ++ customvalue') + def test_logger_disabling(self): self.apply_config(self.disable_test) @@ -1645,6 +1757,42 @@ class ConfigFileTest(BaseTest): self.apply_config(test_config) self.assertEqual(logging.getLogger().handlers[0].name, 'hand1') + def test_exception_if_confg_file_is_invalid(self): + test_config = """ + [loggers] + keys=root + + [handlers] + keys=hand1 + + [formatters] + keys=form1 + + [logger_root] + handlers=hand1 + + [handler_hand1] + class=StreamHandler + formatter=form1 + + [formatter_form1] + format=%(levelname)s ++ %(message)s + + prince + """ + + file = io.StringIO(textwrap.dedent(test_config)) + self.assertRaises(RuntimeError, logging.config.fileConfig, file) + + def test_exception_if_confg_file_is_empty(self): + fd, fn = tempfile.mkstemp(prefix='test_empty_', suffix='.ini') + os.close(fd) + self.assertRaises(RuntimeError, logging.config.fileConfig, fn) + os.remove(fn) + + def test_exception_if_config_file_does_not_exist(self): + self.assertRaises(FileNotFoundError, logging.config.fileConfig, 'filenotfound') + def test_defaults_do_no_interpolation(self): """bpo-33802 defaults should not get interpolated""" ini = textwrap.dedent(""" @@ -1781,13 +1929,6 @@ class SocketHandlerTest(BaseTest): time.sleep(self.sock_hdlr.retryTime - now + 0.001) self.root_logger.error('Nor this') -def _get_temp_domain_socket(): - fd, fn = tempfile.mkstemp(prefix='test_logging_', suffix='.sock') - os.close(fd) - # just need a name - file can't be present, or we'll get an - # 'address already in use' error. - os.remove(fn) - return fn @unittest.skipUnless(hasattr(socket, "AF_UNIX"), "Unix sockets required") class UnixSocketHandlerTest(SocketHandlerTest): @@ -1799,13 +1940,10 @@ class UnixSocketHandlerTest(SocketHandlerTest): def setUp(self): # override the definition in the base class - self.address = _get_temp_domain_socket() + self.address = socket_helper.create_unix_domain_name() + self.addCleanup(os_helper.unlink, self.address) SocketHandlerTest.setUp(self) - def tearDown(self): - SocketHandlerTest.tearDown(self) - os_helper.unlink(self.address) - @support.requires_working_socket() @threading_helper.requires_working_threading() class DatagramHandlerTest(BaseTest): @@ -1882,13 +2020,10 @@ class UnixDatagramHandlerTest(DatagramHandlerTest): def setUp(self): # override the definition in the base class - self.address = _get_temp_domain_socket() + self.address = socket_helper.create_unix_domain_name() + self.addCleanup(os_helper.unlink, self.address) DatagramHandlerTest.setUp(self) - def tearDown(self): - DatagramHandlerTest.tearDown(self) - os_helper.unlink(self.address) - @support.requires_working_socket() @threading_helper.requires_working_threading() class SysLogHandlerTest(BaseTest): @@ -1945,17 +2080,17 @@ class SysLogHandlerTest(BaseTest): # The log message sent to the SysLogHandler is properly received. logger = logging.getLogger("slh") logger.error("sp\xe4m") - self.handled.wait() + self.handled.wait(support.LONG_TIMEOUT) self.assertEqual(self.log_output, b'<11>sp\xc3\xa4m\x00') self.handled.clear() self.sl_hdlr.append_nul = False logger.error("sp\xe4m") - self.handled.wait() + self.handled.wait(support.LONG_TIMEOUT) self.assertEqual(self.log_output, b'<11>sp\xc3\xa4m') self.handled.clear() self.sl_hdlr.ident = "h\xe4m-" logger.error("sp\xe4m") - self.handled.wait() + self.handled.wait(support.LONG_TIMEOUT) self.assertEqual(self.log_output, b'<11>h\xc3\xa4m-sp\xc3\xa4m') def test_udp_reconnection(self): @@ -1963,7 +2098,7 @@ class SysLogHandlerTest(BaseTest): self.sl_hdlr.close() self.handled.clear() logger.error("sp\xe4m") - self.handled.wait(0.1) + self.handled.wait(support.LONG_TIMEOUT) self.assertEqual(self.log_output, b'<11>sp\xc3\xa4m\x00') @unittest.skipUnless(hasattr(socket, "AF_UNIX"), "Unix sockets required") @@ -1976,13 +2111,10 @@ class UnixSysLogHandlerTest(SysLogHandlerTest): def setUp(self): # override the definition in the base class - self.address = _get_temp_domain_socket() + self.address = socket_helper.create_unix_domain_name() + self.addCleanup(os_helper.unlink, self.address) SysLogHandlerTest.setUp(self) - def tearDown(self): - SysLogHandlerTest.tearDown(self) - os_helper.unlink(self.address) - @unittest.skipUnless(socket_helper.IPV6_ENABLED, 'IPv6 support required for this test.') class IPv6SysLogHandlerTest(SysLogHandlerTest): @@ -2135,8 +2267,7 @@ class EncodingTest(BaseTest): def test_encoding_plain_file(self): # In Python 2.x, a plain file object is treated as having no encoding. log = logging.getLogger("test") - fd, fn = tempfile.mkstemp(".log", "test_logging-1-") - os.close(fd) + fn = make_temp_file(".log", "test_logging-1-") # the non-ascii data we write to the log. data = "foo\x80" try: @@ -2233,6 +2364,21 @@ def handlerFunc(): class CustomHandler(logging.StreamHandler): pass +class CustomListener(logging.handlers.QueueListener): + pass + +class CustomQueue(queue.Queue): + pass + +def queueMaker(): + return queue.Queue() + +def listenerMaker(arg1, arg2, respect_handler_level=False): + def func(queue, *handlers, **kwargs): + kwargs.setdefault('respect_handler_level', respect_handler_level) + return CustomListener(queue, *handlers, **kwargs) + return func + class ConfigDictTest(BaseTest): """Reading logging config from a dictionary.""" @@ -2836,7 +2982,31 @@ class ConfigDictTest(BaseTest): }, } - out_of_order = { + # config0 but with default values for formatter. Skipped 15, it is defined + # in the test code. + config16 = { + 'version': 1, + 'formatters': { + 'form1' : { + 'format' : '%(message)s ++ %(customfield)s', + 'defaults': {"customfield": "defaultvalue"} + }, + }, + 'handlers' : { + 'hand1' : { + 'class' : 'logging.StreamHandler', + 'formatter' : 'form1', + 'level' : 'NOTSET', + 'stream' : 'ext://sys.stdout', + }, + }, + 'root' : { + 'level' : 'WARNING', + 'handlers' : ['hand1'], + }, + } + + bad_format = { "version": 1, "formatters": { "mySimpleFormatter": { @@ -2856,7 +3026,7 @@ class ConfigDictTest(BaseTest): "formatter": "mySimpleFormatter", "target": "fileGlobal", "level": "DEBUG" - } + } }, "loggers": { "mymodule": { @@ -2948,7 +3118,7 @@ class ConfigDictTest(BaseTest): } } - # Configuration with custom function and 'validate' set to False + # Configuration with custom function, 'validate' set to False and no defaults custom_formatter_with_function = { 'version': 1, 'formatters': { @@ -2975,13 +3145,63 @@ class ConfigDictTest(BaseTest): } } + # Configuration with custom function, and defaults + custom_formatter_with_defaults = { + 'version': 1, + 'formatters': { + 'form1': { + '()': formatFunc, + 'format': '%(levelname)s:%(name)s:%(message)s:%(customfield)s', + 'defaults': {"customfield": "myvalue"} + }, + }, + 'handlers' : { + 'hand1' : { + 'class': 'logging.StreamHandler', + 'formatter': 'form1', + 'level': 'NOTSET', + 'stream': 'ext://sys.stdout', + }, + }, + "loggers": { + "my_test_logger_custom_formatter": { + "level": "DEBUG", + "handlers": ["hand1"], + "propagate": "true" + } + } + } + + config_queue_handler = { + 'version': 1, + 'handlers' : { + 'h1' : { + 'class': 'logging.FileHandler', + }, + # key is before depended on handlers to test that deferred config works + 'ah' : { + 'class': 'logging.handlers.QueueHandler', + 'handlers': ['h1'] + }, + }, + "root": { + "level": "DEBUG", + "handlers": ["ah"] + } + } + def apply_config(self, conf): logging.config.dictConfig(conf) + def check_handler(self, name, cls): + h = logging.getHandlerByName(name) + self.assertIsInstance(h, cls) + def test_config0_ok(self): # A simple config which overrides the default settings. with support.captured_stdout() as output: self.apply_config(self.config0) + self.check_handler('hand1', logging.StreamHandler) logger = logging.getLogger() # Won't output anything logger.info(self.next_message()) @@ -3028,6 +3248,7 @@ class ConfigDictTest(BaseTest): # A config specifying a custom formatter class. with support.captured_stdout() as output: self.apply_config(self.config4) + self.check_handler('hand1', logging.StreamHandler) #logger = logging.getLogger() try: raise RuntimeError() @@ -3056,6 +3277,7 @@ class ConfigDictTest(BaseTest): def test_config5_ok(self): self.test_config1_ok(config=self.config5) + self.check_handler('hand1', CustomHandler) def test_config6_failure(self): self.assertRaises(Exception, self.apply_config, self.config6) @@ -3075,6 +3297,7 @@ class ConfigDictTest(BaseTest): self.assert_log_lines([]) with support.captured_stdout() as output: self.apply_config(self.config7) + self.check_handler('hand1', logging.StreamHandler) logger = logging.getLogger("compiler.parser") self.assertTrue(logger.disabled) logger = logging.getLogger("compiler.lexer") @@ -3104,6 +3327,7 @@ class ConfigDictTest(BaseTest): self.assert_log_lines([]) with support.captured_stdout() as output: self.apply_config(self.config8) + self.check_handler('hand1', logging.StreamHandler) logger = logging.getLogger("compiler.parser") self.assertFalse(logger.disabled) # Both will output a message @@ -3125,6 +3349,7 @@ class ConfigDictTest(BaseTest): def test_config_8a_ok(self): with support.captured_stdout() as output: self.apply_config(self.config1a) + self.check_handler('hand1', logging.StreamHandler) logger = logging.getLogger("compiler.parser") # See issue #11424. compiler-hyphenated sorts # between compiler and compiler.xyz and this @@ -3145,6 +3370,7 @@ class ConfigDictTest(BaseTest): self.assert_log_lines([]) with support.captured_stdout() as output: self.apply_config(self.config8a) + self.check_handler('hand1', logging.StreamHandler) logger = logging.getLogger("compiler.parser") self.assertFalse(logger.disabled) # Both will output a message @@ -3168,6 +3394,7 @@ class ConfigDictTest(BaseTest): def test_config_9_ok(self): with support.captured_stdout() as output: self.apply_config(self.config9) + self.check_handler('hand1', logging.StreamHandler) logger = logging.getLogger("compiler.parser") # Nothing will be output since both handler and logger are set to WARNING logger.info(self.next_message()) @@ -3186,6 +3413,7 @@ class ConfigDictTest(BaseTest): def test_config_10_ok(self): with support.captured_stdout() as output: self.apply_config(self.config10) + self.check_handler('hand1', logging.StreamHandler) logger = logging.getLogger("compiler.parser") logger.warning(self.next_message()) logger = logging.getLogger('compiler') @@ -3222,13 +3450,8 @@ class ConfigDictTest(BaseTest): def test_config15_ok(self): - def cleanup(h1, fn): - h1.close() - os.remove(fn) - with self.check_no_resource_warning(): - fd, fn = tempfile.mkstemp(".log", "test_logging-X-") - os.close(fd) + fn = make_temp_file(".log", "test_logging-X-") config = { "version": 1, @@ -3248,7 +3471,23 @@ class ConfigDictTest(BaseTest): self.apply_config(config) handler = logging.root.handlers[0] - self.addCleanup(cleanup, handler, fn) + self.addCleanup(closeFileHandler, handler, fn) + + def test_config16_ok(self): + self.apply_config(self.config16) + h = logging._handlers['hand1'] + + # Custom value + result = h.formatter.format(logging.makeLogRecord( + {'msg': 'Hello', 'customfield': 'customvalue'})) + self.assertEqual(result, 'Hello ++ customvalue') + + # Default value + result = h.formatter.format(logging.makeLogRecord( + {'msg': 'Hello'})) + self.assertEqual(result, 'Hello ++ defaultvalue') + + def setup_via_listener(self, text, verify=None): text = text.encode("utf-8") @@ -3282,6 +3521,7 @@ class ConfigDictTest(BaseTest): def test_listen_config_10_ok(self): with support.captured_stdout() as output: self.setup_via_listener(json.dumps(self.config10)) + self.check_handler('hand1', logging.StreamHandler) logger = logging.getLogger("compiler.parser") logger.warning(self.next_message()) logger = logging.getLogger('compiler') @@ -3376,11 +3616,11 @@ class ConfigDictTest(BaseTest): ('ERROR', '2'), ], pat=r"^[\w.]+ -> (\w+): (\d+)$") - def test_out_of_order(self): - self.assertRaises(ValueError, self.apply_config, self.out_of_order) + def test_bad_format(self): + self.assertRaises(ValueError, self.apply_config, self.bad_format) - def test_out_of_order_with_dollar_style(self): - config = copy.deepcopy(self.out_of_order) + def test_bad_format_with_dollar_style(self): + config = copy.deepcopy(self.bad_format) config['formatters']['mySimpleFormatter']['format'] = "${asctime} (${name}) ${levelname}: ${message}" self.apply_config(config) @@ -3388,6 +3628,8 @@ class ConfigDictTest(BaseTest): self.assertIsInstance(handler.target, logging.Handler) self.assertIsInstance(handler.formatter._style, logging.StringTemplateStyle) + self.assertEqual(sorted(logging.getHandlerNames()), + ['bufferGlobal', 'fileGlobal']) def test_custom_formatter_class_with_validate(self): self.apply_config(self.custom_formatter_class_validate) @@ -3403,7 +3645,7 @@ class ConfigDictTest(BaseTest): config = self.custom_formatter_class_validate.copy() config['formatters']['form1']['style'] = "$" - # Exception should not be raise as we have configured 'validate' to False + # Exception should not be raised as we have configured 'validate' to False self.apply_config(config) handler = logging.getLogger("my_test_logger_custom_formatter").handlers[0] self.assertIsInstance(handler.formatter, ExceptionFormatter) @@ -3414,6 +3656,9 @@ class ConfigDictTest(BaseTest): def test_custom_formatter_function_with_validate(self): self.assertRaises(ValueError, self.apply_config, self.custom_formatter_with_function) + def test_custom_formatter_function_with_defaults(self): + self.assertRaises(ValueError, self.apply_config, self.custom_formatter_with_defaults) + def test_baseconfig(self): d = { 'atuple': (1, 2, 3), @@ -3504,6 +3749,75 @@ class ConfigDictTest(BaseTest): {"version": 1, "root": {"level": "DEBUG", "filters": [filter_]}} ) + def do_queuehandler_configuration(self, qspec, lspec): + cd = copy.deepcopy(self.config_queue_handler) + fn = make_temp_file('.log', 'test_logging-cqh-') + cd['handlers']['h1']['filename'] = fn + if qspec is not None: + cd['handlers']['ah']['queue'] = qspec + if lspec is not None: + cd['handlers']['ah']['listener'] = lspec + qh = None + try: + self.apply_config(cd) + qh = logging.getHandlerByName('ah') + self.assertEqual(sorted(logging.getHandlerNames()), ['ah', 'h1']) + self.assertIsNotNone(qh.listener) + qh.listener.start() + logging.debug('foo') + logging.info('bar') + logging.warning('baz') + + # Need to let the listener thread finish its work + while support.sleeping_retry(support.LONG_TIMEOUT, + "queue not empty"): + if qh.listener.queue.empty(): + break + + # wait until the handler completed its last task + qh.listener.queue.join() + + with open(fn, encoding='utf-8') as f: + data = f.read().splitlines() + self.assertEqual(data, ['foo', 'bar', 'baz']) + finally: + if qh: + qh.listener.stop() + h = logging.getHandlerByName('h1') + if h: + self.addCleanup(closeFileHandler, h, fn) + else: + self.addCleanup(os.remove, fn) + + @threading_helper.requires_working_threading() + def test_config_queue_handler(self): + q = CustomQueue() + dq = { + '()': __name__ + '.CustomQueue', + 'maxsize': 10 + } + dl = { + '()': __name__ + '.listenerMaker', + 'arg1': None, + 'arg2': None, + 'respect_handler_level': True + } + qvalues = (None, __name__ + '.queueMaker', __name__ + '.CustomQueue', dq, q) + lvalues = (None, __name__ + '.CustomListener', dl, CustomListener) + for qspec, lspec in itertools.product(qvalues, lvalues): + self.do_queuehandler_configuration(qspec, lspec) + + # Some failure cases + qvalues = (None, 4, int, '', 'foo') + lvalues = (None, 4, int, '', 'bar') + for qspec, lspec in itertools.product(qvalues, lvalues): + if lspec is None and qspec is None: + continue + with self.assertRaises(ValueError) as ctx: + self.do_queuehandler_configuration(qspec, lspec) + msg = str(ctx.exception) + self.assertEqual(msg, "Unable to configure handler 'ah'") + def test_90195(self): # See gh-90195 config = { @@ -3573,6 +3887,20 @@ class ChildLoggerTest(BaseTest): self.assertIs(c2, logging.getLogger('abc.def.ghi')) self.assertIs(c2, c3) + def test_get_children(self): + r = logging.getLogger() + l1 = logging.getLogger('foo') + l2 = logging.getLogger('foo.bar') + l3 = logging.getLogger('foo.bar.baz.bozz') + l4 = logging.getLogger('bar') + kids = r.getChildren() + expected = {l1, l4} + self.assertEqual(expected, kids & expected) # might be other kids for root + self.assertNotIn(l2, expected) + kids = l1.getChildren() + self.assertEqual({l2}, kids) + kids = l2.getChildren() + self.assertEqual(set(), kids) class DerivedLogRecord(logging.LogRecord): pass @@ -4591,29 +4919,65 @@ class LogRecordTest(BaseTest): import multiprocessing def test_optional(self): - r = logging.makeLogRecord({}) + NONE = self.assertIsNone NOT_NONE = self.assertIsNotNone + + r = logging.makeLogRecord({}) NOT_NONE(r.thread) NOT_NONE(r.threadName) NOT_NONE(r.process) NOT_NONE(r.processName) + NONE(r.taskName) log_threads = logging.logThreads log_processes = logging.logProcesses log_multiprocessing = logging.logMultiprocessing + log_asyncio_tasks = logging.logAsyncioTasks try: logging.logThreads = False logging.logProcesses = False logging.logMultiprocessing = False + logging.logAsyncioTasks = False r = logging.makeLogRecord({}) - NONE = self.assertIsNone + NONE(r.thread) NONE(r.threadName) NONE(r.process) NONE(r.processName) + NONE(r.taskName) finally: logging.logThreads = log_threads logging.logProcesses = log_processes logging.logMultiprocessing = log_multiprocessing + logging.logAsyncioTasks = log_asyncio_tasks + + async def _make_record_async(self, assertion): + r = logging.makeLogRecord({}) + assertion(r.taskName) + + @support.requires_working_socket() + def test_taskName_with_asyncio_imported(self): + try: + make_record = self._make_record_async + with asyncio.Runner() as runner: + logging.logAsyncioTasks = True + runner.run(make_record(self.assertIsNotNone)) + logging.logAsyncioTasks = False + runner.run(make_record(self.assertIsNone)) + finally: + asyncio.set_event_loop_policy(None) + + @support.requires_working_socket() + def test_taskName_without_asyncio_imported(self): + try: + make_record = self._make_record_async + with asyncio.Runner() as runner, support.swap_item(sys.modules, 'asyncio', None): + logging.logAsyncioTasks = True + runner.run(make_record(self.assertIsNone)) + logging.logAsyncioTasks = False + runner.run(make_record(self.assertIsNone)) + finally: + asyncio.set_event_loop_policy(None) + class BasicConfigTest(unittest.TestCase): @@ -4876,8 +5240,7 @@ class BasicConfigTest(unittest.TestCase): message = [] def dummy_handle_error(record): - _, v, _ = sys.exc_info() - message.append(str(v)) + message.append(str(sys.exception())) handler.handleError = dummy_handle_error logging.debug('The Øresund Bridge joins Copenhagen to Malmö') @@ -4892,6 +5255,35 @@ class BasicConfigTest(unittest.TestCase): # didn't write anything due to the encoding error self.assertEqual(data, r'') + @support.requires_working_socket() + def test_log_taskName(self): + async def log_record(): + logging.warning('hello world') + + handler = None + log_filename = make_temp_file('.log', 'test-logging-taskname-') + self.addCleanup(os.remove, log_filename) + try: + encoding = 'utf-8' + logging.basicConfig(filename=log_filename, errors='strict', + encoding=encoding, level=logging.WARNING, + format='%(taskName)s - %(message)s') + + self.assertEqual(len(logging.root.handlers), 1) + handler = logging.root.handlers[0] + self.assertIsInstance(handler, logging.FileHandler) + + with asyncio.Runner(debug=True) as runner: + logging.logAsyncioTasks = True + runner.run(log_record()) + with open(log_filename, encoding='utf-8') as f: + data = f.read().strip() + self.assertRegex(data, r'Task-\d+ - hello world') + finally: + asyncio.set_event_loop_policy(None) + if handler: + handler.close() + def _test_log(self, method, level=None): # logging.root has no handlers so basicConfig should be called @@ -5275,8 +5667,7 @@ class BaseFileTest(BaseTest): def setUp(self): BaseTest.setUp(self) - fd, self.fn = tempfile.mkstemp(".log", "test_logging-2-") - os.close(fd) + self.fn = make_temp_file(".log", "test_logging-2-") self.rmfiles = [] def tearDown(self): @@ -5683,7 +6074,7 @@ class MiscTestCase(unittest.TestCase): 'logThreads', 'logMultiprocessing', 'logProcesses', 'currentframe', 'PercentStyle', 'StrFormatStyle', 'StringTemplateStyle', 'Filterer', 'PlaceHolder', 'Manager', 'RootLogger', 'root', - 'threading'} + 'threading', 'logAsyncioTasks'} support.check__all__(self, logging, not_exported=not_exported) diff --git a/Lib/test/test_long.py b/Lib/test/test_long.py index 77b37ca1..d299c34c 100644 --- a/Lib/test/test_long.py +++ b/Lib/test/test_long.py @@ -1553,6 +1553,11 @@ class LongTest(unittest.TestCase): b = i.to_bytes(2, signed=True) self.assertIs(int.from_bytes(b, signed=True), i) + def test_is_integer(self): + self.assertTrue((-1).is_integer()) + self.assertTrue((0).is_integer()) + self.assertTrue((1).is_integer()) + def test_access_to_nonexistent_digit_0(self): # http://bugs.python.org/issue14630: A bug in _PyLong_Copy meant that # ob_digit[0] was being incorrectly accessed for instances of a @@ -1596,5 +1601,44 @@ class LongTest(unittest.TestCase): self.assertEqual(n**2, (1 << (2 * bitlen)) - (1 << (bitlen + 1)) + 1) + def test___sizeof__(self): + self.assertEqual(int.__itemsize__, sys.int_info.sizeof_digit) + + # Pairs (test_value, number of allocated digits) + test_values = [ + # We always allocate space for at least one digit, even for + # a value of zero; sys.getsizeof should reflect that. + (0, 1), + (1, 1), + (-1, 1), + (BASE-1, 1), + (1-BASE, 1), + (BASE, 2), + (-BASE, 2), + (BASE*BASE - 1, 2), + (BASE*BASE, 3), + ] + + for value, ndigits in test_values: + with self.subTest(value): + self.assertEqual( + value.__sizeof__(), + int.__basicsize__ + int.__itemsize__ * ndigits + ) + + # Same test for a subclass of int. + class MyInt(int): + pass + + self.assertEqual(MyInt.__itemsize__, sys.int_info.sizeof_digit) + + for value, ndigits in test_values: + with self.subTest(value): + self.assertEqual( + MyInt(value).__sizeof__(), + MyInt.__basicsize__ + MyInt.__itemsize__ * ndigits + ) + + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_lzma.py b/Lib/test/test_lzma.py index 145c8cfc..13b20091 100644 --- a/Lib/test/test_lzma.py +++ b/Lib/test/test_lzma.py @@ -352,10 +352,10 @@ class CompressorDecompressorTestCase(unittest.TestCase): @bigmemtest(size=_4G + 100, memuse=3) def test_decompressor_bigmem(self, size): lzd = LZMADecompressor() - blocksize = 10 * 1024 * 1024 + blocksize = min(10 * 1024 * 1024, size) block = random.randbytes(blocksize) try: - input = block * (size // blocksize + 1) + input = block * ((size-1) // blocksize + 1) cdata = lzma.compress(input) ddata = lzd.decompress(cdata) self.assertEqual(ddata, input) @@ -380,6 +380,10 @@ class CompressorDecompressorTestCase(unittest.TestCase): lzd.__init__() self.assertAlmostEqual(gettotalrefcount() - refs_before, 0, delta=10) + def test_uninitialized_LZMADecompressor_crash(self): + self.assertEqual(LZMADecompressor.__new__(LZMADecompressor). + decompress(bytes()), b'') + class CompressDecompressFunctionTestCase(unittest.TestCase): @@ -825,10 +829,7 @@ class FileTestCase(unittest.TestCase): def test_read_10(self): with LZMAFile(BytesIO(COMPRESSED_XZ)) as f: chunks = [] - while True: - result = f.read(10) - if not result: - break + while result := f.read(10): self.assertLessEqual(len(result), 10) chunks.append(result) self.assertEqual(b"".join(chunks), INPUT) @@ -911,10 +912,7 @@ class FileTestCase(unittest.TestCase): def test_read1(self): with LZMAFile(BytesIO(COMPRESSED_XZ)) as f: blocks = [] - while True: - result = f.read1() - if not result: - break + while result := f.read1(): blocks.append(result) self.assertEqual(b"".join(blocks), INPUT) self.assertEqual(f.read1(), b"") @@ -926,10 +924,7 @@ class FileTestCase(unittest.TestCase): def test_read1_10(self): with LZMAFile(BytesIO(COMPRESSED_XZ)) as f: blocks = [] - while True: - result = f.read1(10) - if not result: - break + while result := f.read1(10): blocks.append(result) self.assertEqual(b"".join(blocks), INPUT) self.assertEqual(f.read1(), b"") @@ -937,10 +932,7 @@ class FileTestCase(unittest.TestCase): def test_read1_multistream(self): with LZMAFile(BytesIO(COMPRESSED_XZ * 5)) as f: blocks = [] - while True: - result = f.read1() - if not result: - break + while result := f.read1(): blocks.append(result) self.assertEqual(b"".join(blocks), INPUT * 5) self.assertEqual(f.read1(), b"") diff --git a/Lib/test/test_mailbox.py b/Lib/test/test_mailbox.py index 07c2764d..4977a936 100644 --- a/Lib/test/test_mailbox.py +++ b/Lib/test/test_mailbox.py @@ -31,7 +31,7 @@ class TestBase: # Inspect a mailbox.Message representation of the sample message self.assertIsInstance(msg, email.message.Message) self.assertIsInstance(msg, mailbox.Message) - for key, value in _sample_headers.items(): + for key, value in _sample_headers: self.assertIn(value, msg.get_all(key)) self.assertTrue(msg.is_multipart()) self.assertEqual(len(msg.get_payload()), len(_sample_payloads)) @@ -116,10 +116,13 @@ class TestMailbox(TestBase): self.assertMailboxEmpty() def test_add_that_raises_leaves_mailbox_empty(self): + class CustomError(Exception): ... + exc_msg = "a fake error" + def raiser(*args, **kw): - raise Exception("a fake error") + raise CustomError(exc_msg) support.patch(self, email.generator.BytesGenerator, 'flatten', raiser) - with self.assertRaises(Exception): + with self.assertRaisesRegex(CustomError, exc_msg): self._box.add(email.message_from_string("From: Alphöso")) self.assertEqual(len(self._box), 0) self._box.close() @@ -2264,30 +2267,31 @@ H4sICM2D1UIAA3RleHQAC8nILFYAokSFktSKEoW0zJxUPa7wzJIMhZLyfIWczLzUYj0uAHTs _bytes_sample_message = _sample_message.encode('ascii') -_sample_headers = { - "Return-Path":"<gkj@gregorykjohnson.com>", - "X-Original-To":"gkj+person@localhost", - "Delivered-To":"gkj+person@localhost", - "Received":"""from localhost (localhost [127.0.0.1]) +_sample_headers = [ + ("Return-Path", "<gkj@gregorykjohnson.com>"), + ("X-Original-To", "gkj+person@localhost"), + ("Delivered-To", "gkj+person@localhost"), + ("Received", """from localhost (localhost [127.0.0.1]) by andy.gregorykjohnson.com (Postfix) with ESMTP id 356ED9DD17 - for <gkj+person@localhost>; Wed, 13 Jul 2005 17:23:16 -0400 (EDT)""", - "Delivered-To":"gkj@sundance.gregorykjohnson.com", - "Received":"""from localhost [127.0.0.1] + for <gkj+person@localhost>; Wed, 13 Jul 2005 17:23:16 -0400 (EDT)"""), + ("Delivered-To", "gkj@sundance.gregorykjohnson.com"), + ("Received", """from localhost [127.0.0.1] by localhost with POP3 (fetchmail-6.2.5) - for gkj+person@localhost (single-drop); Wed, 13 Jul 2005 17:23:16 -0400 (EDT)""", - "Received":"""from andy.gregorykjohnson.com (andy.gregorykjohnson.com [64.32.235.228]) + for gkj+person@localhost (single-drop); Wed, 13 Jul 2005 17:23:16 -0400 (EDT)"""), + ("Received", """from andy.gregorykjohnson.com (andy.gregorykjohnson.com [64.32.235.228]) by sundance.gregorykjohnson.com (Postfix) with ESMTP id 5B056316746 - for <gkj@gregorykjohnson.com>; Wed, 13 Jul 2005 17:23:11 -0400 (EDT)""", - "Received":"""by andy.gregorykjohnson.com (Postfix, from userid 1000) - id 490CD9DD17; Wed, 13 Jul 2005 17:23:11 -0400 (EDT)""", - "Date":"Wed, 13 Jul 2005 17:23:11 -0400", - "From":""""Gregory K. Johnson" <gkj@gregorykjohnson.com>""", - "To":"gkj@gregorykjohnson.com", - "Subject":"Sample message", - "Mime-Version":"1.0", - "Content-Type":"""multipart/mixed; boundary="NMuMz9nt05w80d4+\"""", - "Content-Disposition":"inline", - "User-Agent": "Mutt/1.5.9i" } + for <gkj@gregorykjohnson.com>; Wed, 13 Jul 2005 17:23:11 -0400 (EDT)"""), + ("Received", """by andy.gregorykjohnson.com (Postfix, from userid 1000) + id 490CD9DD17; Wed, 13 Jul 2005 17:23:11 -0400 (EDT)"""), + ("Date", "Wed, 13 Jul 2005 17:23:11 -0400"), + ("From", """"Gregory K. Johnson" <gkj@gregorykjohnson.com>"""), + ("To", "gkj@gregorykjohnson.com"), + ("Subject", "Sample message"), + ("Mime-Version", "1.0"), + ("Content-Type", """multipart/mixed; boundary="NMuMz9nt05w80d4+\""""), + ("Content-Disposition", "inline"), + ("User-Agent", "Mutt/1.5.9i"), +] _sample_payloads = ("""This is a sample message. diff --git a/Lib/test/test_mailcap.py b/Lib/test/test_mailcap.py index 8185f4a7..8a94b0cb 100644 --- a/Lib/test/test_mailcap.py +++ b/Lib/test/test_mailcap.py @@ -3,7 +3,6 @@ import os import sys import test.support import unittest -import warnings from test.support import os_helper from test.support import warnings_helper @@ -128,7 +127,6 @@ class HelperFunctionTest(unittest.TestCase): (["", "audio/*", "foo.txt"], ""), (["echo foo", "audio/*", "foo.txt"], "echo foo"), (["echo %s", "audio/*", "foo.txt"], "echo foo.txt"), - (["echo %t", "audio/*", "foo.txt"], None), (["echo %t", "audio/wav", "foo.txt"], "echo audio/wav"), (["echo \\%t", "audio/*", "foo.txt"], "echo %t"), (["echo foo", "audio/*", "foo.txt", plist], "echo foo"), @@ -211,9 +209,6 @@ class FindmatchTest(unittest.TestCase): ([c, "audio/basic"], {"key": "description", "filename": fname}, ('"An audio fragment"', audio_basic_entry)), - ([c, "audio/*"], - {"filename": fname}, - (None, None)), ([c, "audio/wav"], {"filename": fname}, ("/usr/local/bin/showaudio audio/wav", audio_entry)), @@ -246,6 +241,30 @@ class FindmatchTest(unittest.TestCase): ] self._run_cases(cases) + def test_unsafe_mailcap_input(self): + with self.assertWarnsRegex(mailcap.UnsafeMailcapInput, + 'Refusing to substitute parameter.*' + 'into a shell command'): + unsafe_param = mailcap.subst("echo %{total}", + "audio/wav", + "foo.txt", + ["total=*"]) + self.assertEqual(unsafe_param, None) + + with self.assertWarnsRegex(mailcap.UnsafeMailcapInput, + 'Refusing to substitute MIME type' + '.*into a shell'): + unsafe_mimetype = mailcap.subst("echo %t", "audio/*", "foo.txt") + self.assertEqual(unsafe_mimetype, None) + + with self.assertWarnsRegex(mailcap.UnsafeMailcapInput, + 'Refusing to use mailcap with filename.*' + 'Use a safe temporary filename.'): + unsafe_filename = mailcap.findmatch(MAILCAPDICT, + "audio/wav", + filename="foo*.txt") + self.assertEqual(unsafe_filename, (None, None)) + def _run_cases(self, cases): for c in cases: self.assertEqual(mailcap.findmatch(*c[0], **c[1]), c[2]) diff --git a/Lib/test/test_marshal.py b/Lib/test/test_marshal.py index a1a91f66..3d9d6d5d 100644 --- a/Lib/test/test_marshal.py +++ b/Lib/test/test_marshal.py @@ -117,7 +117,8 @@ class CodeTestCase(unittest.TestCase): def test_many_codeobjects(self): # Issue2957: bad recursion count on code objects - count = 5000 # more than MAX_MARSHAL_STACK_DEPTH + # more than MAX_MARSHAL_STACK_DEPTH + count = support.EXCEEDS_RECURSION_LIMIT codes = (ExceptionTestCase.test_exceptions.__code__,) * count marshal.loads(marshal.dumps(codes)) @@ -256,7 +257,7 @@ class BugsTestCase(unittest.TestCase): # The max stack depth should match the value in Python/marshal.c. # BUG: https://bugs.python.org/issue33720 # Windows always limits the maximum depth on release and debug builds - #if os.name == 'nt' and hasattr(sys, 'gettotalrefcount'): + #if os.name == 'nt' and support.Py_DEBUG: if os.name == 'nt': MAX_MARSHAL_STACK_DEPTH = 1000 elif sys.platform == 'wasi': diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py index bf0d0a56..2bda6101 100644 --- a/Lib/test/test_math.py +++ b/Lib/test/test_math.py @@ -4,6 +4,7 @@ from test.support import verbose, requires_IEEE_754 from test import support import unittest +import fractions import itertools import decimal import math @@ -1202,6 +1203,260 @@ class MathTests(unittest.TestCase): self.assertEqual(math.log(INF), INF) self.assertTrue(math.isnan(math.log10(NAN))) + def testSumProd(self): + sumprod = math.sumprod + Decimal = decimal.Decimal + Fraction = fractions.Fraction + + # Core functionality + self.assertEqual(sumprod(iter([10, 20, 30]), (1, 2, 3)), 140) + self.assertEqual(sumprod([1.5, 2.5], [3.5, 4.5]), 16.5) + self.assertEqual(sumprod([], []), 0) + + # Type preservation and coercion + for v in [ + (10, 20, 30), + (1.5, -2.5), + (Fraction(3, 5), Fraction(4, 5)), + (Decimal(3.5), Decimal(4.5)), + (2.5, 10), # float/int + (2.5, Fraction(3, 5)), # float/fraction + (25, Fraction(3, 5)), # int/fraction + (25, Decimal(4.5)), # int/decimal + ]: + for p, q in [(v, v), (v, v[::-1])]: + with self.subTest(p=p, q=q): + expected = sum(p_i * q_i for p_i, q_i in zip(p, q, strict=True)) + actual = sumprod(p, q) + self.assertEqual(expected, actual) + self.assertEqual(type(expected), type(actual)) + + # Bad arguments + self.assertRaises(TypeError, sumprod) # No args + self.assertRaises(TypeError, sumprod, []) # One arg + self.assertRaises(TypeError, sumprod, [], [], []) # Three args + self.assertRaises(TypeError, sumprod, None, [10]) # Non-iterable + self.assertRaises(TypeError, sumprod, [10], None) # Non-iterable + + # Uneven lengths + self.assertRaises(ValueError, sumprod, [10, 20], [30]) + self.assertRaises(ValueError, sumprod, [10], [20, 30]) + + # Error in iterator + def raise_after(n): + for i in range(n): + yield i + raise RuntimeError + with self.assertRaises(RuntimeError): + sumprod(range(10), raise_after(5)) + with self.assertRaises(RuntimeError): + sumprod(raise_after(5), range(10)) + + # Error in multiplication + class BadMultiply: + def __mul__(self, other): + raise RuntimeError + def __rmul__(self, other): + raise RuntimeError + with self.assertRaises(RuntimeError): + sumprod([10, BadMultiply(), 30], [1, 2, 3]) + with self.assertRaises(RuntimeError): + sumprod([1, 2, 3], [10, BadMultiply(), 30]) + + # Error in addition + with self.assertRaises(TypeError): + sumprod(['abc', 3], [5, 10]) + with self.assertRaises(TypeError): + sumprod([5, 10], ['abc', 3]) + + # Special values should give the same as the pure python recipe + self.assertEqual(sumprod([10.1, math.inf], [20.2, 30.3]), math.inf) + self.assertEqual(sumprod([10.1, math.inf], [math.inf, 30.3]), math.inf) + self.assertEqual(sumprod([10.1, math.inf], [math.inf, math.inf]), math.inf) + self.assertEqual(sumprod([10.1, -math.inf], [20.2, 30.3]), -math.inf) + self.assertTrue(math.isnan(sumprod([10.1, math.inf], [-math.inf, math.inf]))) + self.assertTrue(math.isnan(sumprod([10.1, math.nan], [20.2, 30.3]))) + self.assertTrue(math.isnan(sumprod([10.1, math.inf], [math.nan, 30.3]))) + self.assertTrue(math.isnan(sumprod([10.1, math.inf], [20.3, math.nan]))) + + # Error cases that arose during development + args = ((-5, -5, 10), (1.5, 4611686018427387904, 2305843009213693952)) + self.assertEqual(sumprod(*args), 0.0) + + + @requires_IEEE_754 + @unittest.skipIf(HAVE_DOUBLE_ROUNDING, + "sumprod() accuracy not guaranteed on machines with double rounding") + @support.cpython_only # Other implementations may choose a different algorithm + def test_sumprod_accuracy(self): + sumprod = math.sumprod + self.assertEqual(sumprod([0.1] * 10, [1]*10), 1.0) + self.assertEqual(sumprod([0.1] * 20, [True, False] * 10), 1.0) + self.assertEqual(sumprod([1.0, 10E100, 1.0, -10E100], [1.0]*4), 2.0) + + @support.requires_resource('cpu') + def test_sumprod_stress(self): + sumprod = math.sumprod + product = itertools.product + Decimal = decimal.Decimal + Fraction = fractions.Fraction + + class Int(int): + def __add__(self, other): + return Int(int(self) + int(other)) + def __mul__(self, other): + return Int(int(self) * int(other)) + __radd__ = __add__ + __rmul__ = __mul__ + def __repr__(self): + return f'Int({int(self)})' + + class Flt(float): + def __add__(self, other): + return Int(int(self) + int(other)) + def __mul__(self, other): + return Int(int(self) * int(other)) + __radd__ = __add__ + __rmul__ = __mul__ + def __repr__(self): + return f'Flt({int(self)})' + + def baseline_sumprod(p, q): + """This defines the target behavior including expections and special values. + However, it is subject to rounding errors, so float inputs should be exactly + representable with only a few bits. + """ + total = 0 + for p_i, q_i in zip(p, q, strict=True): + total += p_i * q_i + return total + + def run(func, *args): + "Make comparing functions easier. Returns error status, type, and result." + try: + result = func(*args) + except (AssertionError, NameError): + raise + except Exception as e: + return type(e), None, 'None' + return None, type(result), repr(result) + + pools = [ + (-5, 10, -2**20, 2**31, 2**40, 2**61, 2**62, 2**80, 1.5, Int(7)), + (5.25, -3.5, 4.75, 11.25, 400.5, 0.046875, 0.25, -1.0, -0.078125), + (-19.0*2**500, 11*2**1000, -3*2**1500, 17*2*333, + 5.25, -3.25, -3.0*2**(-333), 3, 2**513), + (3.75, 2.5, -1.5, float('inf'), -float('inf'), float('NaN'), 14, + 9, 3+4j, Flt(13), 0.0), + (13.25, -4.25, Decimal('10.5'), Decimal('-2.25'), Fraction(13, 8), + Fraction(-11, 16), 4.75 + 0.125j, 97, -41, Int(3)), + (Decimal('6.125'), Decimal('12.375'), Decimal('-2.75'), Decimal(0), + Decimal('Inf'), -Decimal('Inf'), Decimal('NaN'), 12, 13.5), + (-2.0 ** -1000, 11*2**1000, 3, 7, -37*2**32, -2*2**-537, -2*2**-538, + 2*2**-513), + (-7 * 2.0 ** -510, 5 * 2.0 ** -520, 17, -19.0, -6.25), + (11.25, -3.75, -0.625, 23.375, True, False, 7, Int(5)), + ] + + for pool in pools: + for size in range(4): + for args1 in product(pool, repeat=size): + for args2 in product(pool, repeat=size): + args = (args1, args2) + self.assertEqual( + run(baseline_sumprod, *args), + run(sumprod, *args), + args, + ) + + @requires_IEEE_754 + @unittest.skipIf(HAVE_DOUBLE_ROUNDING, + "sumprod() accuracy not guaranteed on machines with double rounding") + @support.cpython_only # Other implementations may choose a different algorithm + @support.requires_resource('cpu') + def test_sumprod_extended_precision_accuracy(self): + import operator + from fractions import Fraction + from itertools import starmap + from collections import namedtuple + from math import log2, exp2, fabs + from random import choices, uniform, shuffle + from statistics import median + + DotExample = namedtuple('DotExample', ('x', 'y', 'target_sumprod', 'condition')) + + def DotExact(x, y): + vec1 = map(Fraction, x) + vec2 = map(Fraction, y) + return sum(starmap(operator.mul, zip(vec1, vec2, strict=True))) + + def Condition(x, y): + return 2.0 * DotExact(map(abs, x), map(abs, y)) / abs(DotExact(x, y)) + + def linspace(lo, hi, n): + width = (hi - lo) / (n - 1) + return [lo + width * i for i in range(n)] + + def GenDot(n, c): + """ Algorithm 6.1 (GenDot) works as follows. The condition number (5.7) of + the dot product xT y is proportional to the degree of cancellation. In + order to achieve a prescribed cancellation, we generate the first half of + the vectors x and y randomly within a large exponent range. This range is + chosen according to the anticipated condition number. The second half of x + and y is then constructed choosing xi randomly with decreasing exponent, + and calculating yi such that some cancellation occurs. Finally, we permute + the vectors x, y randomly and calculate the achieved condition number. + """ + + assert n >= 6 + n2 = n // 2 + x = [0.0] * n + y = [0.0] * n + b = log2(c) + + # First half with exponents from 0 to |_b/2_| and random ints in between + e = choices(range(int(b/2)), k=n2) + e[0] = int(b / 2) + 1 + e[-1] = 0.0 + + x[:n2] = [uniform(-1.0, 1.0) * exp2(p) for p in e] + y[:n2] = [uniform(-1.0, 1.0) * exp2(p) for p in e] + + # Second half + e = list(map(round, linspace(b/2, 0.0 , n-n2))) + for i in range(n2, n): + x[i] = uniform(-1.0, 1.0) * exp2(e[i - n2]) + y[i] = (uniform(-1.0, 1.0) * exp2(e[i - n2]) - DotExact(x, y)) / x[i] + + # Shuffle + pairs = list(zip(x, y)) + shuffle(pairs) + x, y = zip(*pairs) + + return DotExample(x, y, DotExact(x, y), Condition(x, y)) + + def RelativeError(res, ex): + x, y, target_sumprod, condition = ex + n = DotExact(list(x) + [-res], list(y) + [1]) + return fabs(n / target_sumprod) + + def Trial(dotfunc, c, n): + ex = GenDot(10, c) + res = dotfunc(ex.x, ex.y) + return RelativeError(res, ex) + + times = 1000 # Number of trials + n = 20 # Length of vectors + c = 1e30 # Target condition number + + # If the following test fails, it means that the C math library + # implementation of fma() is not compliant with the C99 standard + # and is inaccurate. To solve this problem, make a new build + # with the symbol UNRELIABLE_FMA defined. That will enable a + # slower but accurate code path that avoids the fma() call. + relative_err = median(Trial(math.sumprod, c, n) for i in range(times)) + self.assertLess(relative_err, 1e-16) + def testModf(self): self.assertRaises(TypeError, math.modf) @@ -1626,11 +1881,11 @@ class MathTests(unittest.TestCase): self.assertFalse(math.isinf(0.)) self.assertFalse(math.isinf(1.)) - @requires_IEEE_754 def test_nan_constant(self): + # `math.nan` must be a quiet NaN with positive sign bit self.assertTrue(math.isnan(math.nan)) + self.assertEqual(math.copysign(1., math.nan), 1.) - @requires_IEEE_754 def test_inf_constant(self): self.assertTrue(math.isinf(math.inf)) self.assertGreater(math.inf, 0.0) @@ -2041,11 +2296,20 @@ class MathTests(unittest.TestCase): float.fromhex('0x1.fffffffffffffp-1')) self.assertEqual(math.nextafter(1.0, INF), float.fromhex('0x1.0000000000001p+0')) + self.assertEqual(math.nextafter(1.0, -INF, steps=1), + float.fromhex('0x1.fffffffffffffp-1')) + self.assertEqual(math.nextafter(1.0, INF, steps=1), + float.fromhex('0x1.0000000000001p+0')) + self.assertEqual(math.nextafter(1.0, -INF, steps=3), + float.fromhex('0x1.ffffffffffffdp-1')) + self.assertEqual(math.nextafter(1.0, INF, steps=3), + float.fromhex('0x1.0000000000003p+0')) # x == y: y is returned - self.assertEqual(math.nextafter(2.0, 2.0), 2.0) - self.assertEqualSign(math.nextafter(-0.0, +0.0), +0.0) - self.assertEqualSign(math.nextafter(+0.0, -0.0), -0.0) + for steps in range(1, 5): + self.assertEqual(math.nextafter(2.0, 2.0, steps=steps), 2.0) + self.assertEqualSign(math.nextafter(-0.0, +0.0, steps=steps), +0.0) + self.assertEqualSign(math.nextafter(+0.0, -0.0, steps=steps), -0.0) # around 0.0 smallest_subnormal = sys.float_info.min * sys.float_info.epsilon @@ -2070,6 +2334,11 @@ class MathTests(unittest.TestCase): self.assertIsNaN(math.nextafter(1.0, NAN)) self.assertIsNaN(math.nextafter(NAN, NAN)) + self.assertEqual(1.0, math.nextafter(1.0, INF, steps=0)) + with self.assertRaises(ValueError): + math.nextafter(1.0, INF, steps=-1) + + @requires_IEEE_754 def test_ulp(self): self.assertEqual(math.ulp(1.0), sys.float_info.epsilon) diff --git a/Lib/test/test_math_property.py b/Lib/test/test_math_property.py new file mode 100644 index 00000000..7d51aa17 --- /dev/null +++ b/Lib/test/test_math_property.py @@ -0,0 +1,41 @@ +import functools +import unittest +from math import isnan, nextafter +from test.support import requires_IEEE_754 +from test.support.hypothesis_helper import hypothesis + +floats = hypothesis.strategies.floats +integers = hypothesis.strategies.integers + + +def assert_equal_float(x, y): + assert isnan(x) and isnan(y) or x == y + + +def via_reduce(x, y, steps): + return functools.reduce(nextafter, [y] * steps, x) + + +class NextafterTests(unittest.TestCase): + @requires_IEEE_754 + @hypothesis.given( + x=floats(), + y=floats(), + steps=integers(min_value=0, max_value=2**16)) + def test_count(self, x, y, steps): + assert_equal_float(via_reduce(x, y, steps), + nextafter(x, y, steps=steps)) + + @requires_IEEE_754 + @hypothesis.given( + x=floats(), + y=floats(), + a=integers(min_value=0), + b=integers(min_value=0)) + def test_addition_commutes(self, x, y, a, b): + first = nextafter(x, y, steps=a) + second = nextafter(first, y, steps=b) + combined = nextafter(x, y, steps=a+b) + hypothesis.note(f"{first} -> {second} == {combined}") + + assert_equal_float(second, combined) diff --git a/Lib/test/test_memoryview.py b/Lib/test/test_memoryview.py index 9d1e1f30..0eb2a367 100644 --- a/Lib/test/test_memoryview.py +++ b/Lib/test/test_memoryview.py @@ -13,6 +13,7 @@ import array import io import copy import pickle +import struct from test.support import import_helper @@ -527,6 +528,14 @@ class OtherTest(unittest.TestCase): m[2:] = memoryview(p6).cast(format)[2:] self.assertEqual(d.value, 0.6) + def test_half_float(self): + half_data = struct.pack('eee', 0.0, -1.5, 1.5) + float_data = struct.pack('fff', 0.0, -1.5, 1.5) + half_view = memoryview(half_data).cast('e') + float_view = memoryview(float_data).cast('f') + self.assertEqual(half_view.nbytes * 2, float_view.nbytes) + self.assertListEqual(half_view.tolist(), float_view.tolist()) + def test_memoryview_hex(self): # Issue #9951: memoryview.hex() segfaults with non-contiguous buffers. x = b'0' * 200000 diff --git a/Lib/test/test_minidom.py b/Lib/test/test_minidom.py index ef38c362..699265cc 100644 --- a/Lib/test/test_minidom.py +++ b/Lib/test/test_minidom.py @@ -6,7 +6,6 @@ import io from test import support import unittest -import pyexpat import xml.dom.minidom from xml.dom.minidom import parse, Attr, Node, Document, parseString @@ -1163,14 +1162,10 @@ class MinidomTest(unittest.TestCase): # Verify that character decoding errors raise exceptions instead # of crashing - if pyexpat.version_info >= (2, 4, 5): - self.assertRaises(ExpatError, parseString, - b'<fran\xe7ais></fran\xe7ais>') - self.assertRaises(ExpatError, parseString, - b'<franais>Comment \xe7a va ? Tr\xe8s bien ?</franais>') - else: - self.assertRaises(UnicodeDecodeError, parseString, - b'<fran\xe7ais>Comment \xe7a va ? Tr\xe8s bien ?</fran\xe7ais>') + with self.assertRaises((UnicodeDecodeError, ExpatError)): + parseString( + b'<fran\xe7ais>Comment \xe7a va ? Tr\xe8s bien ?</fran\xe7ais>' + ) doc.unlink() @@ -1631,13 +1626,11 @@ class MinidomTest(unittest.TestCase): self.confirm(doc2.namespaceURI == xml.dom.EMPTY_NAMESPACE) def testExceptionOnSpacesInXMLNSValue(self): - if pyexpat.version_info >= (2, 4, 5): - context = self.assertRaisesRegex(ExpatError, 'syntax error') - else: - context = self.assertRaisesRegex(ValueError, 'Unsupported syntax') - - with context: - parseString('<element xmlns:abc="http:abc.com/de f g/hi/j k"><abc:foo /></element>') + with self.assertRaises((ValueError, ExpatError)): + parseString( + '<element xmlns:abc="http:abc.com/de f g/hi/j k">' + + '<abc:foo /></element>' + ) def testDocRemoveChild(self): doc = parse(tstfile) diff --git a/Lib/test/test_mmap.py b/Lib/test/test_mmap.py index 213a44d5..dfcf3039 100644 --- a/Lib/test/test_mmap.py +++ b/Lib/test/test_mmap.py @@ -255,10 +255,15 @@ class MmapTests(unittest.TestCase): # Try writing with PROT_EXEC and without PROT_WRITE prot = mmap.PROT_READ | getattr(mmap, 'PROT_EXEC', 0) with open(TESTFN, "r+b") as f: - m = mmap.mmap(f.fileno(), mapsize, prot=prot) - self.assertRaises(TypeError, m.write, b"abcdef") - self.assertRaises(TypeError, m.write_byte, 0) - m.close() + try: + m = mmap.mmap(f.fileno(), mapsize, prot=prot) + except PermissionError: + # on macOS 14, PROT_READ | PROT_EXEC is not allowed + pass + else: + self.assertRaises(TypeError, m.write, b"abcdef") + self.assertRaises(TypeError, m.write_byte, 0) + m.close() def test_bad_file_desc(self): # Try opening a bad file descriptor... @@ -299,6 +304,27 @@ class MmapTests(unittest.TestCase): self.assertEqual(m.find(b'one', 1, -2), -1) self.assertEqual(m.find(bytearray(b'one')), 0) + for i in range(-n-1, n+1): + for j in range(-n-1, n+1): + for p in [b"o", b"on", b"two", b"ones", b"s"]: + expected = data.find(p, i, j) + self.assertEqual(m.find(p, i, j), expected, (p, i, j)) + + def test_find_does_not_access_beyond_buffer(self): + try: + flags = mmap.MAP_PRIVATE | mmap.MAP_ANONYMOUS + PAGESIZE = mmap.PAGESIZE + PROT_NONE = 0 + PROT_READ = mmap.PROT_READ + except AttributeError as e: + raise unittest.SkipTest("mmap flags unavailable") from e + for i in range(0, 2049): + with mmap.mmap(-1, PAGESIZE * (i + 1), + flags=flags, prot=PROT_NONE) as guard: + with mmap.mmap(-1, PAGESIZE * (i + 2048), + flags=flags, prot=PROT_READ) as fm: + fm.find(b"fo", -2) + def test_rfind(self): # test the new 'end' parameter works as expected @@ -407,7 +433,6 @@ class MmapTests(unittest.TestCase): m.move(0, 0, 1) m.move(0, 0, 0) - def test_anonymous(self): # anonymous mmap.mmap(-1, PAGE) m = mmap.mmap(-1, PAGESIZE) @@ -887,6 +912,92 @@ class MmapTests(unittest.TestCase): self.assertEqual(m1[:data_length], data) self.assertEqual(m2[:data_length], data) + def test_mmap_closed_by_int_scenarios(self): + """ + gh-103987: Test that mmap objects raise ValueError + for closed mmap files + """ + + class MmapClosedByIntContext: + def __init__(self, access) -> None: + self.access = access + + def __enter__(self): + self.f = open(TESTFN, "w+b") + self.f.write(random.randbytes(100)) + self.f.flush() + + m = mmap.mmap(self.f.fileno(), 100, access=self.access) + + class X: + def __index__(self): + m.close() + return 10 + + return (m, X) + + def __exit__(self, exc_type, exc_value, traceback): + self.f.close() + + read_access_modes = [ + mmap.ACCESS_READ, + mmap.ACCESS_WRITE, + mmap.ACCESS_COPY, + mmap.ACCESS_DEFAULT, + ] + + write_access_modes = [ + mmap.ACCESS_WRITE, + mmap.ACCESS_COPY, + mmap.ACCESS_DEFAULT, + ] + + for access in read_access_modes: + with MmapClosedByIntContext(access) as (m, X): + with self.assertRaisesRegex(ValueError, "mmap closed or invalid"): + m[X()] + + with MmapClosedByIntContext(access) as (m, X): + with self.assertRaisesRegex(ValueError, "mmap closed or invalid"): + m[X() : 20] + + with MmapClosedByIntContext(access) as (m, X): + with self.assertRaisesRegex(ValueError, "mmap closed or invalid"): + m[X() : 20 : 2] + + with MmapClosedByIntContext(access) as (m, X): + with self.assertRaisesRegex(ValueError, "mmap closed or invalid"): + m[20 : X() : -2] + + with MmapClosedByIntContext(access) as (m, X): + with self.assertRaisesRegex(ValueError, "mmap closed or invalid"): + m.read(X()) + + with MmapClosedByIntContext(access) as (m, X): + with self.assertRaisesRegex(ValueError, "mmap closed or invalid"): + m.find(b"1", 1, X()) + + for access in write_access_modes: + with MmapClosedByIntContext(access) as (m, X): + with self.assertRaisesRegex(ValueError, "mmap closed or invalid"): + m[X() : 20] = b"1" * 10 + + with MmapClosedByIntContext(access) as (m, X): + with self.assertRaisesRegex(ValueError, "mmap closed or invalid"): + m[X() : 20 : 2] = b"1" * 5 + + with MmapClosedByIntContext(access) as (m, X): + with self.assertRaisesRegex(ValueError, "mmap closed or invalid"): + m[20 : X() : -2] = b"1" * 5 + + with MmapClosedByIntContext(access) as (m, X): + with self.assertRaisesRegex(ValueError, "mmap closed or invalid"): + m.move(1, 2, X()) + + with MmapClosedByIntContext(access) as (m, X): + with self.assertRaisesRegex(ValueError, "mmap closed or invalid"): + m.write_byte(X()) + class LargeMmapTests(unittest.TestCase): def setUp(self): diff --git a/Lib/test/test_module.py b/Lib/test/test_module/__init__.py similarity index 91% rename from Lib/test/test_module.py rename to Lib/test/test_module/__init__.py index f72177dd..cfc4d9cc 100644 --- a/Lib/test/test_module.py +++ b/Lib/test/test_module/__init__.py @@ -8,10 +8,10 @@ from test.support.script_helper import assert_python_ok import sys ModuleType = type(sys) + class FullLoader: - @classmethod - def module_repr(cls, m): - return "<module '{}' (crafted)>".format(m.__name__) + pass + class BareLoader: pass @@ -126,8 +126,8 @@ a = A(destroyed)""" self.assertIs(wr(), None) def test_module_getattr(self): - import test.good_getattr as gga - from test.good_getattr import test + import test.test_module.good_getattr as gga + from test.test_module.good_getattr import test self.assertEqual(test, "There is test") self.assertEqual(gga.x, 1) self.assertEqual(gga.y, 2) @@ -135,46 +135,46 @@ a = A(destroyed)""" "Deprecated, use whatever instead"): gga.yolo self.assertEqual(gga.whatever, "There is whatever") - del sys.modules['test.good_getattr'] + del sys.modules['test.test_module.good_getattr'] def test_module_getattr_errors(self): - import test.bad_getattr as bga - from test import bad_getattr2 + import test.test_module.bad_getattr as bga + from test.test_module import bad_getattr2 self.assertEqual(bga.x, 1) self.assertEqual(bad_getattr2.x, 1) with self.assertRaises(TypeError): bga.nope with self.assertRaises(TypeError): bad_getattr2.nope - del sys.modules['test.bad_getattr'] - if 'test.bad_getattr2' in sys.modules: - del sys.modules['test.bad_getattr2'] + del sys.modules['test.test_module.bad_getattr'] + if 'test.test_module.bad_getattr2' in sys.modules: + del sys.modules['test.test_module.bad_getattr2'] def test_module_dir(self): - import test.good_getattr as gga + import test.test_module.good_getattr as gga self.assertEqual(dir(gga), ['a', 'b', 'c']) - del sys.modules['test.good_getattr'] + del sys.modules['test.test_module.good_getattr'] def test_module_dir_errors(self): - import test.bad_getattr as bga - from test import bad_getattr2 + import test.test_module.bad_getattr as bga + from test.test_module import bad_getattr2 with self.assertRaises(TypeError): dir(bga) with self.assertRaises(TypeError): dir(bad_getattr2) - del sys.modules['test.bad_getattr'] - if 'test.bad_getattr2' in sys.modules: - del sys.modules['test.bad_getattr2'] + del sys.modules['test.test_module.bad_getattr'] + if 'test.test_module.bad_getattr2' in sys.modules: + del sys.modules['test.test_module.bad_getattr2'] def test_module_getattr_tricky(self): - from test import bad_getattr3 + from test.test_module import bad_getattr3 # these lookups should not crash with self.assertRaises(AttributeError): bad_getattr3.one with self.assertRaises(AttributeError): bad_getattr3.delgetattr - if 'test.bad_getattr3' in sys.modules: - del sys.modules['test.bad_getattr3'] + if 'test.test_module.bad_getattr3' in sys.modules: + del sys.modules['test.test_module.bad_getattr3'] def test_module_repr_minimal(self): # reprs when modules have no __file__, __name__, or __loader__ @@ -236,10 +236,9 @@ a = A(destroyed)""" # Yes, a class not an instance. m.__loader__ = FullLoader self.assertEqual( - repr(m), "<module 'foo' (crafted)>") + repr(m), f"<module 'foo' (<class '{__name__}.FullLoader'>)>") def test_module_repr_with_bare_loader_and_filename(self): - # Because the loader has no module_repr(), use the file name. m = ModuleType('foo') # Yes, a class not an instance. m.__loader__ = BareLoader @@ -247,12 +246,11 @@ a = A(destroyed)""" self.assertEqual(repr(m), "<module 'foo' from '/tmp/foo.py'>") def test_module_repr_with_full_loader_and_filename(self): - # Even though the module has an __file__, use __loader__.module_repr() m = ModuleType('foo') # Yes, a class not an instance. m.__loader__ = FullLoader m.__file__ = '/tmp/foo.py' - self.assertEqual(repr(m), "<module 'foo' (crafted)>") + self.assertEqual(repr(m), "<module 'foo' from '/tmp/foo.py'>") def test_module_repr_builtin(self): self.assertEqual(repr(sys), "<module 'sys' (built-in)>") diff --git a/Lib/test/bad_getattr.py b/Lib/test/test_module/bad_getattr.py similarity index 100% rename from Lib/test/bad_getattr.py rename to Lib/test/test_module/bad_getattr.py diff --git a/Lib/test/bad_getattr2.py b/Lib/test/test_module/bad_getattr2.py similarity index 100% rename from Lib/test/bad_getattr2.py rename to Lib/test/test_module/bad_getattr2.py diff --git a/Lib/test/bad_getattr3.py b/Lib/test/test_module/bad_getattr3.py similarity index 100% rename from Lib/test/bad_getattr3.py rename to Lib/test/test_module/bad_getattr3.py diff --git a/Lib/test/good_getattr.py b/Lib/test/test_module/good_getattr.py similarity index 100% rename from Lib/test/good_getattr.py rename to Lib/test/test_module/good_getattr.py diff --git a/Lib/test/test_monitoring.py b/Lib/test/test_monitoring.py new file mode 100644 index 00000000..8c9755d2 --- /dev/null +++ b/Lib/test/test_monitoring.py @@ -0,0 +1,1745 @@ +"""Test suite for the sys.monitoring.""" + +import collections +import dis +import functools +import operator +import sys +import textwrap +import types +import unittest +import asyncio + +PAIR = (0,1) + +def f1(): + pass + +def f2(): + len([]) + sys.getsizeof(0) + +def floop(): + for item in PAIR: + pass + +def gen(): + yield + yield + +def g1(): + for _ in gen(): + pass + +TEST_TOOL = 2 +TEST_TOOL2 = 3 +TEST_TOOL3 = 4 + +class MonitoringBasicTest(unittest.TestCase): + + def test_has_objects(self): + m = sys.monitoring + m.events + m.use_tool_id + m.free_tool_id + m.get_tool + m.get_events + m.set_events + m.get_local_events + m.set_local_events + m.register_callback + m.restart_events + m.DISABLE + m.MISSING + m.events.NO_EVENTS + + def test_tool(self): + sys.monitoring.use_tool_id(TEST_TOOL, "MonitoringTest.Tool") + self.assertEqual(sys.monitoring.get_tool(TEST_TOOL), "MonitoringTest.Tool") + sys.monitoring.set_events(TEST_TOOL, 15) + self.assertEqual(sys.monitoring.get_events(TEST_TOOL), 15) + sys.monitoring.set_events(TEST_TOOL, 0) + with self.assertRaises(ValueError): + sys.monitoring.set_events(TEST_TOOL, sys.monitoring.events.C_RETURN) + with self.assertRaises(ValueError): + sys.monitoring.set_events(TEST_TOOL, sys.monitoring.events.C_RAISE) + sys.monitoring.free_tool_id(TEST_TOOL) + self.assertEqual(sys.monitoring.get_tool(TEST_TOOL), None) + with self.assertRaises(ValueError): + sys.monitoring.set_events(TEST_TOOL, sys.monitoring.events.CALL) + + +class MonitoringTestBase: + + def setUp(self): + # Check that a previous test hasn't left monitoring on. + for tool in range(6): + self.assertEqual(sys.monitoring.get_events(tool), 0) + self.assertIs(sys.monitoring.get_tool(TEST_TOOL), None) + self.assertIs(sys.monitoring.get_tool(TEST_TOOL2), None) + self.assertIs(sys.monitoring.get_tool(TEST_TOOL3), None) + sys.monitoring.use_tool_id(TEST_TOOL, "test " + self.__class__.__name__) + sys.monitoring.use_tool_id(TEST_TOOL2, "test2 " + self.__class__.__name__) + sys.monitoring.use_tool_id(TEST_TOOL3, "test3 " + self.__class__.__name__) + + def tearDown(self): + # Check that test hasn't left monitoring on. + for tool in range(6): + self.assertEqual(sys.monitoring.get_events(tool), 0) + sys.monitoring.free_tool_id(TEST_TOOL) + sys.monitoring.free_tool_id(TEST_TOOL2) + sys.monitoring.free_tool_id(TEST_TOOL3) + + +class MonitoringCountTest(MonitoringTestBase, unittest.TestCase): + + def check_event_count(self, func, event, expected): + + class Counter: + def __init__(self): + self.count = 0 + def __call__(self, *args): + self.count += 1 + + counter = Counter() + sys.monitoring.register_callback(TEST_TOOL, event, counter) + if event == E.C_RETURN or event == E.C_RAISE: + sys.monitoring.set_events(TEST_TOOL, E.CALL) + else: + sys.monitoring.set_events(TEST_TOOL, event) + self.assertEqual(counter.count, 0) + counter.count = 0 + func() + self.assertEqual(counter.count, expected) + prev = sys.monitoring.register_callback(TEST_TOOL, event, None) + counter.count = 0 + func() + self.assertEqual(counter.count, 0) + self.assertEqual(prev, counter) + sys.monitoring.set_events(TEST_TOOL, 0) + + def test_start_count(self): + self.check_event_count(f1, E.PY_START, 1) + + def test_resume_count(self): + self.check_event_count(g1, E.PY_RESUME, 2) + + def test_return_count(self): + self.check_event_count(f1, E.PY_RETURN, 1) + + def test_call_count(self): + self.check_event_count(f2, E.CALL, 3) + + def test_c_return_count(self): + self.check_event_count(f2, E.C_RETURN, 2) + + +E = sys.monitoring.events + +INSTRUMENTED_EVENTS = [ + (E.PY_START, "start"), + (E.PY_RESUME, "resume"), + (E.PY_RETURN, "return"), + (E.PY_YIELD, "yield"), + (E.JUMP, "jump"), + (E.BRANCH, "branch"), +] + +EXCEPT_EVENTS = [ + (E.RAISE, "raise"), + (E.PY_UNWIND, "unwind"), + (E.EXCEPTION_HANDLED, "exception_handled"), +] + +SIMPLE_EVENTS = INSTRUMENTED_EVENTS + EXCEPT_EVENTS + [ + (E.C_RAISE, "c_raise"), + (E.C_RETURN, "c_return"), +] + + +SIMPLE_EVENT_SET = functools.reduce(operator.or_, [ev for (ev, _) in SIMPLE_EVENTS], 0) | E.CALL + + +def just_pass(): + pass + +just_pass.events = [ + "py_call", + "start", + "return", +] + +def just_raise(): + raise Exception + +just_raise.events = [ + 'py_call', + "start", + "raise", + "unwind", +] + +def just_call(): + len([]) + +just_call.events = [ + 'py_call', + "start", + "c_call", + "c_return", + "return", +] + +def caught(): + try: + 1/0 + except Exception: + pass + +caught.events = [ + 'py_call', + "start", + "raise", + "exception_handled", + "branch", + "return", +] + +def nested_call(): + just_pass() + +nested_call.events = [ + "py_call", + "start", + "py_call", + "start", + "return", + "return", +] + +PY_CALLABLES = (types.FunctionType, types.MethodType) + +class MonitoringEventsBase(MonitoringTestBase): + + def gather_events(self, func): + events = [] + for event, event_name in SIMPLE_EVENTS: + def record(*args, event_name=event_name): + events.append(event_name) + sys.monitoring.register_callback(TEST_TOOL, event, record) + def record_call(code, offset, obj, arg): + if isinstance(obj, PY_CALLABLES): + events.append("py_call") + else: + events.append("c_call") + sys.monitoring.register_callback(TEST_TOOL, E.CALL, record_call) + sys.monitoring.set_events(TEST_TOOL, SIMPLE_EVENT_SET) + events = [] + try: + func() + except: + pass + sys.monitoring.set_events(TEST_TOOL, 0) + #Remove the final event, the call to `sys.monitoring.set_events` + events = events[:-1] + return events + + def check_events(self, func, expected=None): + events = self.gather_events(func) + if expected is None: + expected = func.events + self.assertEqual(events, expected) + +class MonitoringEventsTest(MonitoringEventsBase, unittest.TestCase): + + def test_just_pass(self): + self.check_events(just_pass) + + def test_just_raise(self): + try: + self.check_events(just_raise) + except Exception: + pass + self.assertEqual(sys.monitoring.get_events(TEST_TOOL), 0) + + def test_just_call(self): + self.check_events(just_call) + + def test_caught(self): + self.check_events(caught) + + def test_nested_call(self): + self.check_events(nested_call) + +UP_EVENTS = (E.C_RETURN, E.C_RAISE, E.PY_RETURN, E.PY_UNWIND, E.PY_YIELD) +DOWN_EVENTS = (E.PY_START, E.PY_RESUME) + +from test.profilee import testfunc + +class SimulateProfileTest(MonitoringEventsBase, unittest.TestCase): + + def test_balanced(self): + events = self.gather_events(testfunc) + c = collections.Counter(events) + self.assertEqual(c["c_call"], c["c_return"]) + self.assertEqual(c["start"], c["return"] + c["unwind"]) + self.assertEqual(c["raise"], c["exception_handled"] + c["unwind"]) + + def test_frame_stack(self): + self.maxDiff = None + stack = [] + errors = [] + seen = set() + def up(*args): + frame = sys._getframe(1) + if not stack: + errors.append("empty") + else: + expected = stack.pop() + if frame != expected: + errors.append(f" Popping {frame} expected {expected}") + def down(*args): + frame = sys._getframe(1) + stack.append(frame) + seen.add(frame.f_code) + def call(code, offset, callable, arg): + if not isinstance(callable, PY_CALLABLES): + stack.append(sys._getframe(1)) + for event in UP_EVENTS: + sys.monitoring.register_callback(TEST_TOOL, event, up) + for event in DOWN_EVENTS: + sys.monitoring.register_callback(TEST_TOOL, event, down) + sys.monitoring.register_callback(TEST_TOOL, E.CALL, call) + sys.monitoring.set_events(TEST_TOOL, SIMPLE_EVENT_SET) + testfunc() + sys.monitoring.set_events(TEST_TOOL, 0) + self.assertEqual(errors, []) + self.assertEqual(stack, [sys._getframe()]) + self.assertEqual(len(seen), 9) + + +class CounterWithDisable: + + def __init__(self): + self.disable = False + self.count = 0 + + def __call__(self, *args): + self.count += 1 + if self.disable: + return sys.monitoring.DISABLE + + +class RecorderWithDisable: + + def __init__(self, events): + self.disable = False + self.events = events + + def __call__(self, code, event): + self.events.append(event) + if self.disable: + return sys.monitoring.DISABLE + + +class MontoringDisableAndRestartTest(MonitoringTestBase, unittest.TestCase): + + def test_disable(self): + try: + counter = CounterWithDisable() + sys.monitoring.register_callback(TEST_TOOL, E.PY_START, counter) + sys.monitoring.set_events(TEST_TOOL, E.PY_START) + self.assertEqual(counter.count, 0) + counter.count = 0 + f1() + self.assertEqual(counter.count, 1) + counter.disable = True + counter.count = 0 + f1() + self.assertEqual(counter.count, 1) + counter.count = 0 + f1() + self.assertEqual(counter.count, 0) + sys.monitoring.set_events(TEST_TOOL, 0) + finally: + sys.monitoring.restart_events() + + def test_restart(self): + try: + counter = CounterWithDisable() + sys.monitoring.register_callback(TEST_TOOL, E.PY_START, counter) + sys.monitoring.set_events(TEST_TOOL, E.PY_START) + counter.disable = True + f1() + counter.count = 0 + f1() + self.assertEqual(counter.count, 0) + sys.monitoring.restart_events() + counter.count = 0 + f1() + self.assertEqual(counter.count, 1) + sys.monitoring.set_events(TEST_TOOL, 0) + finally: + sys.monitoring.restart_events() + + +class MultipleMonitorsTest(MonitoringTestBase, unittest.TestCase): + + def test_two_same(self): + try: + self.assertEqual(sys.monitoring._all_events(), {}) + counter1 = CounterWithDisable() + counter2 = CounterWithDisable() + sys.monitoring.register_callback(TEST_TOOL, E.PY_START, counter1) + sys.monitoring.register_callback(TEST_TOOL2, E.PY_START, counter2) + sys.monitoring.set_events(TEST_TOOL, E.PY_START) + sys.monitoring.set_events(TEST_TOOL2, E.PY_START) + self.assertEqual(sys.monitoring.get_events(TEST_TOOL), E.PY_START) + self.assertEqual(sys.monitoring.get_events(TEST_TOOL2), E.PY_START) + self.assertEqual(sys.monitoring._all_events(), {'PY_START': (1 << TEST_TOOL) | (1 << TEST_TOOL2)}) + counter1.count = 0 + counter2.count = 0 + f1() + count1 = counter1.count + count2 = counter2.count + self.assertEqual((count1, count2), (1, 1)) + finally: + sys.monitoring.set_events(TEST_TOOL, 0) + sys.monitoring.set_events(TEST_TOOL2, 0) + sys.monitoring.register_callback(TEST_TOOL, E.PY_START, None) + sys.monitoring.register_callback(TEST_TOOL2, E.PY_START, None) + self.assertEqual(sys.monitoring._all_events(), {}) + + def test_three_same(self): + try: + self.assertEqual(sys.monitoring._all_events(), {}) + counter1 = CounterWithDisable() + counter2 = CounterWithDisable() + counter3 = CounterWithDisable() + sys.monitoring.register_callback(TEST_TOOL, E.PY_START, counter1) + sys.monitoring.register_callback(TEST_TOOL2, E.PY_START, counter2) + sys.monitoring.register_callback(TEST_TOOL3, E.PY_START, counter3) + sys.monitoring.set_events(TEST_TOOL, E.PY_START) + sys.monitoring.set_events(TEST_TOOL2, E.PY_START) + sys.monitoring.set_events(TEST_TOOL3, E.PY_START) + self.assertEqual(sys.monitoring.get_events(TEST_TOOL), E.PY_START) + self.assertEqual(sys.monitoring.get_events(TEST_TOOL2), E.PY_START) + self.assertEqual(sys.monitoring.get_events(TEST_TOOL3), E.PY_START) + self.assertEqual(sys.monitoring._all_events(), {'PY_START': (1 << TEST_TOOL) | (1 << TEST_TOOL2) | (1 << TEST_TOOL3)}) + counter1.count = 0 + counter2.count = 0 + counter3.count = 0 + f1() + count1 = counter1.count + count2 = counter2.count + count3 = counter3.count + self.assertEqual((count1, count2, count3), (1, 1, 1)) + finally: + sys.monitoring.set_events(TEST_TOOL, 0) + sys.monitoring.set_events(TEST_TOOL2, 0) + sys.monitoring.set_events(TEST_TOOL3, 0) + sys.monitoring.register_callback(TEST_TOOL, E.PY_START, None) + sys.monitoring.register_callback(TEST_TOOL2, E.PY_START, None) + sys.monitoring.register_callback(TEST_TOOL3, E.PY_START, None) + self.assertEqual(sys.monitoring._all_events(), {}) + + def test_two_different(self): + try: + self.assertEqual(sys.monitoring._all_events(), {}) + counter1 = CounterWithDisable() + counter2 = CounterWithDisable() + sys.monitoring.register_callback(TEST_TOOL, E.PY_START, counter1) + sys.monitoring.register_callback(TEST_TOOL2, E.PY_RETURN, counter2) + sys.monitoring.set_events(TEST_TOOL, E.PY_START) + sys.monitoring.set_events(TEST_TOOL2, E.PY_RETURN) + self.assertEqual(sys.monitoring.get_events(TEST_TOOL), E.PY_START) + self.assertEqual(sys.monitoring.get_events(TEST_TOOL2), E.PY_RETURN) + self.assertEqual(sys.monitoring._all_events(), {'PY_START': 1 << TEST_TOOL, 'PY_RETURN': 1 << TEST_TOOL2}) + counter1.count = 0 + counter2.count = 0 + f1() + count1 = counter1.count + count2 = counter2.count + self.assertEqual((count1, count2), (1, 1)) + finally: + sys.monitoring.set_events(TEST_TOOL, 0) + sys.monitoring.set_events(TEST_TOOL2, 0) + sys.monitoring.register_callback(TEST_TOOL, E.PY_START, None) + sys.monitoring.register_callback(TEST_TOOL2, E.PY_RETURN, None) + self.assertEqual(sys.monitoring._all_events(), {}) + + def test_two_with_disable(self): + try: + self.assertEqual(sys.monitoring._all_events(), {}) + counter1 = CounterWithDisable() + counter2 = CounterWithDisable() + sys.monitoring.register_callback(TEST_TOOL, E.PY_START, counter1) + sys.monitoring.register_callback(TEST_TOOL2, E.PY_START, counter2) + sys.monitoring.set_events(TEST_TOOL, E.PY_START) + sys.monitoring.set_events(TEST_TOOL2, E.PY_START) + self.assertEqual(sys.monitoring.get_events(TEST_TOOL), E.PY_START) + self.assertEqual(sys.monitoring.get_events(TEST_TOOL2), E.PY_START) + self.assertEqual(sys.monitoring._all_events(), {'PY_START': (1 << TEST_TOOL) | (1 << TEST_TOOL2)}) + counter1.count = 0 + counter2.count = 0 + counter1.disable = True + f1() + count1 = counter1.count + count2 = counter2.count + self.assertEqual((count1, count2), (1, 1)) + counter1.count = 0 + counter2.count = 0 + f1() + count1 = counter1.count + count2 = counter2.count + self.assertEqual((count1, count2), (0, 1)) + finally: + sys.monitoring.set_events(TEST_TOOL, 0) + sys.monitoring.set_events(TEST_TOOL2, 0) + sys.monitoring.register_callback(TEST_TOOL, E.PY_START, None) + sys.monitoring.register_callback(TEST_TOOL2, E.PY_START, None) + self.assertEqual(sys.monitoring._all_events(), {}) + sys.monitoring.restart_events() + + def test_with_instruction_event(self): + """Test that the second tool can set events with instruction events set by the first tool.""" + def f(): + pass + code = f.__code__ + + try: + self.assertEqual(sys.monitoring._all_events(), {}) + sys.monitoring.set_local_events(TEST_TOOL, code, E.INSTRUCTION | E.LINE) + sys.monitoring.set_local_events(TEST_TOOL2, code, E.LINE) + finally: + sys.monitoring.set_events(TEST_TOOL, 0) + sys.monitoring.set_events(TEST_TOOL2, 0) + self.assertEqual(sys.monitoring._all_events(), {}) + + +class LineMonitoringTest(MonitoringTestBase, unittest.TestCase): + + def test_lines_single(self): + try: + self.assertEqual(sys.monitoring._all_events(), {}) + events = [] + recorder = RecorderWithDisable(events) + sys.monitoring.register_callback(TEST_TOOL, E.LINE, recorder) + sys.monitoring.set_events(TEST_TOOL, E.LINE) + f1() + sys.monitoring.set_events(TEST_TOOL, 0) + sys.monitoring.register_callback(TEST_TOOL, E.LINE, None) + start = LineMonitoringTest.test_lines_single.__code__.co_firstlineno + self.assertEqual(events, [start+7, 16, start+8]) + finally: + sys.monitoring.set_events(TEST_TOOL, 0) + sys.monitoring.register_callback(TEST_TOOL, E.LINE, None) + self.assertEqual(sys.monitoring._all_events(), {}) + sys.monitoring.restart_events() + + def test_lines_loop(self): + try: + self.assertEqual(sys.monitoring._all_events(), {}) + events = [] + recorder = RecorderWithDisable(events) + sys.monitoring.register_callback(TEST_TOOL, E.LINE, recorder) + sys.monitoring.set_events(TEST_TOOL, E.LINE) + floop() + sys.monitoring.set_events(TEST_TOOL, 0) + sys.monitoring.register_callback(TEST_TOOL, E.LINE, None) + start = LineMonitoringTest.test_lines_loop.__code__.co_firstlineno + self.assertEqual(events, [start+7, 23, 24, 23, 24, 23, start+8]) + finally: + sys.monitoring.set_events(TEST_TOOL, 0) + sys.monitoring.register_callback(TEST_TOOL, E.LINE, None) + self.assertEqual(sys.monitoring._all_events(), {}) + sys.monitoring.restart_events() + + def test_lines_two(self): + try: + self.assertEqual(sys.monitoring._all_events(), {}) + events = [] + recorder = RecorderWithDisable(events) + events2 = [] + recorder2 = RecorderWithDisable(events2) + sys.monitoring.register_callback(TEST_TOOL, E.LINE, recorder) + sys.monitoring.register_callback(TEST_TOOL2, E.LINE, recorder2) + sys.monitoring.set_events(TEST_TOOL, E.LINE); sys.monitoring.set_events(TEST_TOOL2, E.LINE) + f1() + sys.monitoring.set_events(TEST_TOOL, 0); sys.monitoring.set_events(TEST_TOOL2, 0) + sys.monitoring.register_callback(TEST_TOOL, E.LINE, None) + sys.monitoring.register_callback(TEST_TOOL2, E.LINE, None) + start = LineMonitoringTest.test_lines_two.__code__.co_firstlineno + expected = [start+10, 16, start+11] + self.assertEqual(events, expected) + self.assertEqual(events2, expected) + finally: + sys.monitoring.set_events(TEST_TOOL, 0) + sys.monitoring.set_events(TEST_TOOL2, 0) + sys.monitoring.register_callback(TEST_TOOL, E.LINE, None) + sys.monitoring.register_callback(TEST_TOOL2, E.LINE, None) + self.assertEqual(sys.monitoring._all_events(), {}) + sys.monitoring.restart_events() + + def check_lines(self, func, expected, tool=TEST_TOOL): + try: + self.assertEqual(sys.monitoring._all_events(), {}) + events = [] + recorder = RecorderWithDisable(events) + sys.monitoring.register_callback(tool, E.LINE, recorder) + sys.monitoring.set_events(tool, E.LINE) + func() + sys.monitoring.set_events(tool, 0) + sys.monitoring.register_callback(tool, E.LINE, None) + lines = [ line - func.__code__.co_firstlineno for line in events[1:-1] ] + self.assertEqual(lines, expected) + finally: + sys.monitoring.set_events(tool, 0) + + + def test_linear(self): + + def func(): + line = 1 + line = 2 + line = 3 + line = 4 + line = 5 + + self.check_lines(func, [1,2,3,4,5]) + + def test_branch(self): + def func(): + if "true".startswith("t"): + line = 2 + line = 3 + else: + line = 5 + line = 6 + + self.check_lines(func, [1,2,3,6]) + + def test_try_except(self): + + def func1(): + try: + line = 2 + line = 3 + except: + line = 5 + line = 6 + + self.check_lines(func1, [1,2,3,6]) + + def func2(): + try: + line = 2 + raise 3 + except: + line = 5 + line = 6 + + self.check_lines(func2, [1,2,3,4,5,6]) + +class TestDisable(MonitoringTestBase, unittest.TestCase): + + def gen(self, cond): + for i in range(10): + if cond: + yield 1 + else: + yield 2 + + def raise_handle_reraise(self): + try: + 1/0 + except: + raise + + def test_disable_legal_events(self): + for event, name in INSTRUMENTED_EVENTS: + try: + counter = CounterWithDisable() + counter.disable = True + sys.monitoring.register_callback(TEST_TOOL, event, counter) + sys.monitoring.set_events(TEST_TOOL, event) + for _ in self.gen(1): + pass + self.assertLess(counter.count, 4) + finally: + sys.monitoring.set_events(TEST_TOOL, 0) + sys.monitoring.register_callback(TEST_TOOL, event, None) + + + def test_disable_illegal_events(self): + for event, name in EXCEPT_EVENTS: + try: + counter = CounterWithDisable() + counter.disable = True + sys.monitoring.register_callback(TEST_TOOL, event, counter) + sys.monitoring.set_events(TEST_TOOL, event) + with self.assertRaises(ValueError): + self.raise_handle_reraise() + finally: + sys.monitoring.set_events(TEST_TOOL, 0) + sys.monitoring.register_callback(TEST_TOOL, event, None) + + +class ExceptionRecorder: + + event_type = E.RAISE + + def __init__(self, events): + self.events = events + + def __call__(self, code, offset, exc): + self.events.append(("raise", type(exc))) + +class CheckEvents(MonitoringTestBase, unittest.TestCase): + + def get_events(self, func, tool, recorders): + try: + self.assertEqual(sys.monitoring._all_events(), {}) + event_list = [] + all_events = 0 + for recorder in recorders: + ev = recorder.event_type + sys.monitoring.register_callback(tool, ev, recorder(event_list)) + all_events |= ev + sys.monitoring.set_events(tool, all_events) + func() + sys.monitoring.set_events(tool, 0) + for recorder in recorders: + sys.monitoring.register_callback(tool, recorder.event_type, None) + return event_list + finally: + sys.monitoring.set_events(tool, 0) + for recorder in recorders: + sys.monitoring.register_callback(tool, recorder.event_type, None) + + def check_events(self, func, expected, tool=TEST_TOOL, recorders=(ExceptionRecorder,)): + events = self.get_events(func, tool, recorders) + if events != expected: + print(events, file = sys.stderr) + self.assertEqual(events, expected) + + def check_balanced(self, func, recorders): + events = self.get_events(func, TEST_TOOL, recorders) + self.assertEqual(len(events)%2, 0) + for r, h in zip(events[::2],events[1::2]): + r0 = r[0] + self.assertIn(r0, ("raise", "reraise")) + h0 = h[0] + self.assertIn(h0, ("handled", "unwind")) + self.assertEqual(r[1], h[1]) + + +class StopiterationRecorder(ExceptionRecorder): + + event_type = E.STOP_ITERATION + +class ReraiseRecorder(ExceptionRecorder): + + event_type = E.RERAISE + + def __call__(self, code, offset, exc): + self.events.append(("reraise", type(exc))) + +class UnwindRecorder(ExceptionRecorder): + + event_type = E.PY_UNWIND + + def __call__(self, code, offset, exc): + self.events.append(("unwind", type(exc))) + +class ExceptionHandledRecorder(ExceptionRecorder): + + event_type = E.EXCEPTION_HANDLED + + def __call__(self, code, offset, exc): + self.events.append(("handled", type(exc))) + +class ThrowRecorder(ExceptionRecorder): + + event_type = E.PY_THROW + + def __call__(self, code, offset, exc): + self.events.append(("throw", type(exc))) + +class ExceptionMonitoringTest(CheckEvents): + + + exception_recorders = ( + ExceptionRecorder, + ReraiseRecorder, + ExceptionHandledRecorder, + UnwindRecorder + ) + + def test_simple_try_except(self): + + def func1(): + try: + line = 2 + raise KeyError + except: + line = 5 + line = 6 + + self.check_events(func1, [("raise", KeyError)]) + + def test_implicit_stop_iteration(self): + + def gen(): + yield 1 + return 2 + + def implicit_stop_iteration(): + for _ in gen(): + pass + + self.check_events(implicit_stop_iteration, [("raise", StopIteration)], recorders=(StopiterationRecorder,)) + + initial = [ + ("raise", ZeroDivisionError), + ("handled", ZeroDivisionError) + ] + + reraise = [ + ("reraise", ZeroDivisionError), + ("handled", ZeroDivisionError) + ] + + def test_explicit_reraise(self): + + def func(): + try: + try: + 1/0 + except: + raise + except: + pass + + self.check_balanced( + func, + recorders = self.exception_recorders) + + def test_explicit_reraise_named(self): + + def func(): + try: + try: + 1/0 + except Exception as ex: + raise + except: + pass + + self.check_balanced( + func, + recorders = self.exception_recorders) + + def test_implicit_reraise(self): + + def func(): + try: + try: + 1/0 + except ValueError: + pass + except: + pass + + self.check_balanced( + func, + recorders = self.exception_recorders) + + + def test_implicit_reraise_named(self): + + def func(): + try: + try: + 1/0 + except ValueError as ex: + pass + except: + pass + + self.check_balanced( + func, + recorders = self.exception_recorders) + + def test_try_finally(self): + + def func(): + try: + try: + 1/0 + finally: + pass + except: + pass + + self.check_balanced( + func, + recorders = self.exception_recorders) + + def test_async_for(self): + + def func(): + + async def async_generator(): + for i in range(1): + raise ZeroDivisionError + yield i + + async def async_loop(): + try: + async for item in async_generator(): + pass + except Exception: + pass + + try: + async_loop().send(None) + except StopIteration: + pass + + self.check_balanced( + func, + recorders = self.exception_recorders) + + def test_throw(self): + + def gen(): + yield 1 + yield 2 + + def func(): + try: + g = gen() + next(g) + g.throw(IndexError) + except IndexError: + pass + + self.check_balanced( + func, + recorders = self.exception_recorders) + + events = self.get_events( + func, + TEST_TOOL, + self.exception_recorders + (ThrowRecorder,) + ) + self.assertEqual(events[0], ("throw", IndexError)) + +class LineRecorder: + + event_type = E.LINE + + + def __init__(self, events): + self.events = events + + def __call__(self, code, line): + self.events.append(("line", code.co_name, line - code.co_firstlineno)) + +class CallRecorder: + + event_type = E.CALL + + def __init__(self, events): + self.events = events + + def __call__(self, code, offset, func, arg): + self.events.append(("call", func.__name__, arg)) + +class CEventRecorder: + + def __init__(self, events): + self.events = events + + def __call__(self, code, offset, func, arg): + self.events.append((self.event_name, func.__name__, arg)) + +class CReturnRecorder(CEventRecorder): + + event_type = E.C_RETURN + event_name = "C return" + +class CRaiseRecorder(CEventRecorder): + + event_type = E.C_RAISE + event_name = "C raise" + +MANY_RECORDERS = ExceptionRecorder, CallRecorder, LineRecorder, CReturnRecorder, CRaiseRecorder + +class TestManyEvents(CheckEvents): + + def test_simple(self): + + def func1(): + line1 = 1 + line2 = 2 + line3 = 3 + + self.check_events(func1, recorders = MANY_RECORDERS, expected = [ + ('line', 'get_events', 10), + ('call', 'func1', sys.monitoring.MISSING), + ('line', 'func1', 1), + ('line', 'func1', 2), + ('line', 'func1', 3), + ('line', 'get_events', 11), + ('call', 'set_events', 2)]) + + def test_c_call(self): + + def func2(): + line1 = 1 + [].append(2) + line3 = 3 + + self.check_events(func2, recorders = MANY_RECORDERS, expected = [ + ('line', 'get_events', 10), + ('call', 'func2', sys.monitoring.MISSING), + ('line', 'func2', 1), + ('line', 'func2', 2), + ('call', 'append', [2]), + ('C return', 'append', [2]), + ('line', 'func2', 3), + ('line', 'get_events', 11), + ('call', 'set_events', 2)]) + + def test_try_except(self): + + def func3(): + try: + line = 2 + raise KeyError + except: + line = 5 + line = 6 + + self.check_events(func3, recorders = MANY_RECORDERS, expected = [ + ('line', 'get_events', 10), + ('call', 'func3', sys.monitoring.MISSING), + ('line', 'func3', 1), + ('line', 'func3', 2), + ('line', 'func3', 3), + ('raise', KeyError), + ('line', 'func3', 4), + ('line', 'func3', 5), + ('line', 'func3', 6), + ('line', 'get_events', 11), + ('call', 'set_events', 2)]) + +class InstructionRecorder: + + event_type = E.INSTRUCTION + + def __init__(self, events): + self.events = events + + def __call__(self, code, offset): + # Filter out instructions in check_events to lower noise + if code.co_name != "get_events": + self.events.append(("instruction", code.co_name, offset)) + + +LINE_AND_INSTRUCTION_RECORDERS = InstructionRecorder, LineRecorder + +class TestLineAndInstructionEvents(CheckEvents): + maxDiff = None + + def test_simple(self): + + def func1(): + line1 = 1 + line2 = 2 + line3 = 3 + + self.check_events(func1, recorders = LINE_AND_INSTRUCTION_RECORDERS, expected = [ + ('line', 'get_events', 10), + ('line', 'func1', 1), + ('instruction', 'func1', 2), + ('instruction', 'func1', 4), + ('line', 'func1', 2), + ('instruction', 'func1', 6), + ('instruction', 'func1', 8), + ('line', 'func1', 3), + ('instruction', 'func1', 10), + ('instruction', 'func1', 12), + ('instruction', 'func1', 14), + ('line', 'get_events', 11)]) + + def test_c_call(self): + + def func2(): + line1 = 1 + [].append(2) + line3 = 3 + + self.check_events(func2, recorders = LINE_AND_INSTRUCTION_RECORDERS, expected = [ + ('line', 'get_events', 10), + ('line', 'func2', 1), + ('instruction', 'func2', 2), + ('instruction', 'func2', 4), + ('line', 'func2', 2), + ('instruction', 'func2', 6), + ('instruction', 'func2', 8), + ('instruction', 'func2', 28), + ('instruction', 'func2', 30), + ('instruction', 'func2', 38), + ('line', 'func2', 3), + ('instruction', 'func2', 40), + ('instruction', 'func2', 42), + ('instruction', 'func2', 44), + ('line', 'get_events', 11)]) + + def test_try_except(self): + + def func3(): + try: + line = 2 + raise KeyError + except: + line = 5 + line = 6 + + self.check_events(func3, recorders = LINE_AND_INSTRUCTION_RECORDERS, expected = [ + ('line', 'get_events', 10), + ('line', 'func3', 1), + ('instruction', 'func3', 2), + ('line', 'func3', 2), + ('instruction', 'func3', 4), + ('instruction', 'func3', 6), + ('line', 'func3', 3), + ('instruction', 'func3', 8), + ('instruction', 'func3', 18), + ('instruction', 'func3', 20), + ('line', 'func3', 4), + ('instruction', 'func3', 22), + ('line', 'func3', 5), + ('instruction', 'func3', 24), + ('instruction', 'func3', 26), + ('instruction', 'func3', 28), + ('line', 'func3', 6), + ('instruction', 'func3', 30), + ('instruction', 'func3', 32), + ('instruction', 'func3', 34), + ('line', 'get_events', 11)]) + + def test_with_restart(self): + def func1(): + line1 = 1 + line2 = 2 + line3 = 3 + + self.check_events(func1, recorders = LINE_AND_INSTRUCTION_RECORDERS, expected = [ + ('line', 'get_events', 10), + ('line', 'func1', 1), + ('instruction', 'func1', 2), + ('instruction', 'func1', 4), + ('line', 'func1', 2), + ('instruction', 'func1', 6), + ('instruction', 'func1', 8), + ('line', 'func1', 3), + ('instruction', 'func1', 10), + ('instruction', 'func1', 12), + ('instruction', 'func1', 14), + ('line', 'get_events', 11)]) + + sys.monitoring.restart_events() + + self.check_events(func1, recorders = LINE_AND_INSTRUCTION_RECORDERS, expected = [ + ('line', 'get_events', 10), + ('line', 'func1', 1), + ('instruction', 'func1', 2), + ('instruction', 'func1', 4), + ('line', 'func1', 2), + ('instruction', 'func1', 6), + ('instruction', 'func1', 8), + ('line', 'func1', 3), + ('instruction', 'func1', 10), + ('instruction', 'func1', 12), + ('instruction', 'func1', 14), + ('line', 'get_events', 11)]) + +class TestInstallIncrementallly(MonitoringTestBase, unittest.TestCase): + + def check_events(self, func, must_include, tool=TEST_TOOL, recorders=(ExceptionRecorder,)): + try: + self.assertEqual(sys.monitoring._all_events(), {}) + event_list = [] + all_events = 0 + for recorder in recorders: + all_events |= recorder.event_type + sys.monitoring.set_events(tool, all_events) + for recorder in recorders: + sys.monitoring.register_callback(tool, recorder.event_type, recorder(event_list)) + func() + sys.monitoring.set_events(tool, 0) + for recorder in recorders: + sys.monitoring.register_callback(tool, recorder.event_type, None) + for line in must_include: + self.assertIn(line, event_list) + finally: + sys.monitoring.set_events(tool, 0) + for recorder in recorders: + sys.monitoring.register_callback(tool, recorder.event_type, None) + + @staticmethod + def func1(): + line1 = 1 + + MUST_INCLUDE_LI = [ + ('instruction', 'func1', 2), + ('line', 'func1', 1), + ('instruction', 'func1', 4), + ('instruction', 'func1', 6)] + + def test_line_then_instruction(self): + recorders = [ LineRecorder, InstructionRecorder ] + self.check_events(self.func1, + recorders = recorders, must_include = self.EXPECTED_LI) + + def test_instruction_then_line(self): + recorders = [ InstructionRecorder, LineRecorderLowNoise ] + self.check_events(self.func1, + recorders = recorders, must_include = self.EXPECTED_LI) + + @staticmethod + def func2(): + len(()) + + MUST_INCLUDE_CI = [ + ('instruction', 'func2', 2), + ('call', 'func2', sys.monitoring.MISSING), + ('call', 'len', ()), + ('instruction', 'func2', 12), + ('instruction', 'func2', 14)] + + + + def test_line_then_instruction(self): + recorders = [ CallRecorder, InstructionRecorder ] + self.check_events(self.func2, + recorders = recorders, must_include = self.MUST_INCLUDE_CI) + + def test_instruction_then_line(self): + recorders = [ InstructionRecorder, CallRecorder ] + self.check_events(self.func2, + recorders = recorders, must_include = self.MUST_INCLUDE_CI) + +LOCAL_RECORDERS = CallRecorder, LineRecorder, CReturnRecorder, CRaiseRecorder + +class TestLocalEvents(MonitoringTestBase, unittest.TestCase): + + def check_events(self, func, expected, tool=TEST_TOOL, recorders=()): + try: + self.assertEqual(sys.monitoring._all_events(), {}) + event_list = [] + all_events = 0 + for recorder in recorders: + ev = recorder.event_type + sys.monitoring.register_callback(tool, ev, recorder(event_list)) + all_events |= ev + sys.monitoring.set_local_events(tool, func.__code__, all_events) + func() + sys.monitoring.set_local_events(tool, func.__code__, 0) + for recorder in recorders: + sys.monitoring.register_callback(tool, recorder.event_type, None) + self.assertEqual(event_list, expected) + finally: + sys.monitoring.set_local_events(tool, func.__code__, 0) + for recorder in recorders: + sys.monitoring.register_callback(tool, recorder.event_type, None) + + + def test_simple(self): + + def func1(): + line1 = 1 + line2 = 2 + line3 = 3 + + self.check_events(func1, recorders = LOCAL_RECORDERS, expected = [ + ('line', 'func1', 1), + ('line', 'func1', 2), + ('line', 'func1', 3)]) + + def test_c_call(self): + + def func2(): + line1 = 1 + [].append(2) + line3 = 3 + + self.check_events(func2, recorders = LOCAL_RECORDERS, expected = [ + ('line', 'func2', 1), + ('line', 'func2', 2), + ('call', 'append', [2]), + ('C return', 'append', [2]), + ('line', 'func2', 3)]) + + def test_try_except(self): + + def func3(): + try: + line = 2 + raise KeyError + except: + line = 5 + line = 6 + + self.check_events(func3, recorders = LOCAL_RECORDERS, expected = [ + ('line', 'func3', 1), + ('line', 'func3', 2), + ('line', 'func3', 3), + ('line', 'func3', 4), + ('line', 'func3', 5), + ('line', 'func3', 6)]) + + def test_set_non_local_event(self): + with self.assertRaises(ValueError): + sys.monitoring.set_local_events(TEST_TOOL, just_call.__code__, E.RAISE) + +def line_from_offset(code, offset): + for start, end, line in code.co_lines(): + if start <= offset < end: + if line is None: + return f"[offset={offset}]" + return line - code.co_firstlineno + return -1 + +class JumpRecorder: + + event_type = E.JUMP + name = "jump" + + def __init__(self, events): + self.events = events + + def __call__(self, code, from_, to): + from_line = line_from_offset(code, from_) + to_line = line_from_offset(code, to) + self.events.append((self.name, code.co_name, from_line, to_line)) + + +class BranchRecorder(JumpRecorder): + + event_type = E.BRANCH + name = "branch" + +class ReturnRecorder: + + event_type = E.PY_RETURN + + def __init__(self, events): + self.events = events + + def __call__(self, code, offset, val): + self.events.append(("return", val)) + + +JUMP_AND_BRANCH_RECORDERS = JumpRecorder, BranchRecorder +JUMP_BRANCH_AND_LINE_RECORDERS = JumpRecorder, BranchRecorder, LineRecorder +FLOW_AND_LINE_RECORDERS = JumpRecorder, BranchRecorder, LineRecorder, ExceptionRecorder, ReturnRecorder + +class TestBranchAndJumpEvents(CheckEvents): + maxDiff = None + + def test_loop(self): + + def func(): + x = 1 + for a in range(2): + if a: + x = 4 + else: + x = 6 + + self.check_events(func, recorders = JUMP_AND_BRANCH_RECORDERS, expected = [ + ('branch', 'func', 2, 2), + ('branch', 'func', 3, 6), + ('jump', 'func', 6, 2), + ('branch', 'func', 2, 2), + ('branch', 'func', 3, 4), + ('jump', 'func', 4, 2), + ('branch', 'func', 2, 2)]) + + self.check_events(func, recorders = JUMP_BRANCH_AND_LINE_RECORDERS, expected = [ + ('line', 'get_events', 10), + ('line', 'func', 1), + ('line', 'func', 2), + ('branch', 'func', 2, 2), + ('line', 'func', 3), + ('branch', 'func', 3, 6), + ('line', 'func', 6), + ('jump', 'func', 6, 2), + ('line', 'func', 2), + ('branch', 'func', 2, 2), + ('line', 'func', 3), + ('branch', 'func', 3, 4), + ('line', 'func', 4), + ('jump', 'func', 4, 2), + ('line', 'func', 2), + ('branch', 'func', 2, 2), + ('line', 'get_events', 11)]) + + def test_except_star(self): + + class Foo: + def meth(self): + pass + + def func(): + try: + try: + raise KeyError + except* Exception as e: + f = Foo(); f.meth() + except KeyError: + pass + + + self.check_events(func, recorders = JUMP_BRANCH_AND_LINE_RECORDERS, expected = [ + ('line', 'get_events', 10), + ('line', 'func', 1), + ('line', 'func', 2), + ('line', 'func', 3), + ('line', 'func', 4), + ('branch', 'func', 4, 4), + ('line', 'func', 5), + ('line', 'meth', 1), + ('jump', 'func', 5, 5), + ('jump', 'func', 5, '[offset=114]'), + ('branch', 'func', '[offset=120]', '[offset=122]'), + ('line', 'get_events', 11)]) + + self.check_events(func, recorders = FLOW_AND_LINE_RECORDERS, expected = [ + ('line', 'get_events', 10), + ('line', 'func', 1), + ('line', 'func', 2), + ('line', 'func', 3), + ('raise', KeyError), + ('line', 'func', 4), + ('branch', 'func', 4, 4), + ('line', 'func', 5), + ('line', 'meth', 1), + ('return', None), + ('jump', 'func', 5, 5), + ('jump', 'func', 5, '[offset=114]'), + ('branch', 'func', '[offset=120]', '[offset=122]'), + ('return', None), + ('line', 'get_events', 11)]) + +class TestLoadSuperAttr(CheckEvents): + RECORDERS = CallRecorder, LineRecorder, CRaiseRecorder, CReturnRecorder + + def _exec(self, co): + d = {} + exec(co, d, d) + return d + + def _exec_super(self, codestr, optimized=False): + # The compiler checks for statically visible shadowing of the name + # `super`, and declines to emit `LOAD_SUPER_ATTR` if shadowing is found. + # So inserting `super = super` prevents the compiler from emitting + # `LOAD_SUPER_ATTR`, and allows us to test that monitoring events for + # `LOAD_SUPER_ATTR` are equivalent to those we'd get from the + # un-optimized `LOAD_GLOBAL super; CALL; LOAD_ATTR` form. + assignment = "x = 1" if optimized else "super = super" + codestr = f"{assignment}\n{textwrap.dedent(codestr)}" + co = compile(codestr, "<string>", "exec") + # validate that we really do have a LOAD_SUPER_ATTR, only when optimized + self.assertEqual(self._has_load_super_attr(co), optimized) + return self._exec(co) + + def _has_load_super_attr(self, co): + has = any(instr.opname == "LOAD_SUPER_ATTR" for instr in dis.get_instructions(co)) + if not has: + has = any( + isinstance(c, types.CodeType) and self._has_load_super_attr(c) + for c in co.co_consts + ) + return has + + def _super_method_call(self, optimized=False): + codestr = """ + class A: + def method(self, x): + return x + + class B(A): + def method(self, x): + return super( + ).method( + x + ) + + b = B() + def f(): + return b.method(1) + """ + d = self._exec_super(codestr, optimized) + expected = [ + ('line', 'get_events', 10), + ('call', 'f', sys.monitoring.MISSING), + ('line', 'f', 1), + ('call', 'method', d["b"]), + ('line', 'method', 1), + ('call', 'super', sys.monitoring.MISSING), + ('C return', 'super', sys.monitoring.MISSING), + ('line', 'method', 2), + ('line', 'method', 3), + ('line', 'method', 2), + ('call', 'method', 1), + ('line', 'method', 1), + ('line', 'method', 1), + ('line', 'get_events', 11), + ('call', 'set_events', 2), + ] + return d["f"], expected + + def test_method_call(self): + nonopt_func, nonopt_expected = self._super_method_call(optimized=False) + opt_func, opt_expected = self._super_method_call(optimized=True) + + self.check_events(nonopt_func, recorders=self.RECORDERS, expected=nonopt_expected) + self.check_events(opt_func, recorders=self.RECORDERS, expected=opt_expected) + + def _super_method_call_error(self, optimized=False): + codestr = """ + class A: + def method(self, x): + return x + + class B(A): + def method(self, x): + return super( + x, + self, + ).method( + x + ) + + b = B() + def f(): + try: + return b.method(1) + except TypeError: + pass + else: + assert False, "should have raised TypeError" + """ + d = self._exec_super(codestr, optimized) + expected = [ + ('line', 'get_events', 10), + ('call', 'f', sys.monitoring.MISSING), + ('line', 'f', 1), + ('line', 'f', 2), + ('call', 'method', d["b"]), + ('line', 'method', 1), + ('line', 'method', 2), + ('line', 'method', 3), + ('line', 'method', 1), + ('call', 'super', 1), + ('C raise', 'super', 1), + ('line', 'f', 3), + ('line', 'f', 4), + ('line', 'get_events', 11), + ('call', 'set_events', 2), + ] + return d["f"], expected + + def test_method_call_error(self): + nonopt_func, nonopt_expected = self._super_method_call_error(optimized=False) + opt_func, opt_expected = self._super_method_call_error(optimized=True) + + self.check_events(nonopt_func, recorders=self.RECORDERS, expected=nonopt_expected) + self.check_events(opt_func, recorders=self.RECORDERS, expected=opt_expected) + + def _super_attr(self, optimized=False): + codestr = """ + class A: + x = 1 + + class B(A): + def method(self): + return super( + ).x + + b = B() + def f(): + return b.method() + """ + d = self._exec_super(codestr, optimized) + expected = [ + ('line', 'get_events', 10), + ('call', 'f', sys.monitoring.MISSING), + ('line', 'f', 1), + ('call', 'method', d["b"]), + ('line', 'method', 1), + ('call', 'super', sys.monitoring.MISSING), + ('C return', 'super', sys.monitoring.MISSING), + ('line', 'method', 2), + ('line', 'method', 1), + ('line', 'get_events', 11), + ('call', 'set_events', 2) + ] + return d["f"], expected + + def test_attr(self): + nonopt_func, nonopt_expected = self._super_attr(optimized=False) + opt_func, opt_expected = self._super_attr(optimized=True) + + self.check_events(nonopt_func, recorders=self.RECORDERS, expected=nonopt_expected) + self.check_events(opt_func, recorders=self.RECORDERS, expected=opt_expected) + + def test_vs_other_type_call(self): + code_template = textwrap.dedent(""" + class C: + def method(self): + return {cls}().__repr__{call} + c = C() + def f(): + return c.method() + """) + + def get_expected(name, call_method, ns): + repr_arg = 0 if name == "int" else sys.monitoring.MISSING + return [ + ('line', 'get_events', 10), + ('call', 'f', sys.monitoring.MISSING), + ('line', 'f', 1), + ('call', 'method', ns["c"]), + ('line', 'method', 1), + ('call', name, sys.monitoring.MISSING), + ('C return', name, sys.monitoring.MISSING), + *( + [ + ('call', '__repr__', repr_arg), + ('C return', '__repr__', repr_arg), + ] if call_method else [] + ), + ('line', 'get_events', 11), + ('call', 'set_events', 2), + ] + + for call_method in [True, False]: + with self.subTest(call_method=call_method): + call_str = "()" if call_method else "" + code_super = code_template.format(cls="super", call=call_str) + code_int = code_template.format(cls="int", call=call_str) + co_super = compile(code_super, '<string>', 'exec') + self.assertTrue(self._has_load_super_attr(co_super)) + ns_super = self._exec(co_super) + ns_int = self._exec(code_int) + + self.check_events( + ns_super["f"], + recorders=self.RECORDERS, + expected=get_expected("super", call_method, ns_super) + ) + self.check_events( + ns_int["f"], + recorders=self.RECORDERS, + expected=get_expected("int", call_method, ns_int) + ) + + +class TestSetGetEvents(MonitoringTestBase, unittest.TestCase): + + def test_global(self): + sys.monitoring.set_events(TEST_TOOL, E.PY_START) + self.assertEqual(sys.monitoring.get_events(TEST_TOOL), E.PY_START) + sys.monitoring.set_events(TEST_TOOL2, E.PY_START) + self.assertEqual(sys.monitoring.get_events(TEST_TOOL2), E.PY_START) + sys.monitoring.set_events(TEST_TOOL, 0) + self.assertEqual(sys.monitoring.get_events(TEST_TOOL), 0) + sys.monitoring.set_events(TEST_TOOL2,0) + self.assertEqual(sys.monitoring.get_events(TEST_TOOL2), 0) + + def test_local(self): + code = f1.__code__ + sys.monitoring.set_local_events(TEST_TOOL, code, E.PY_START) + self.assertEqual(sys.monitoring.get_local_events(TEST_TOOL, code), E.PY_START) + sys.monitoring.set_local_events(TEST_TOOL2, code, E.PY_START) + self.assertEqual(sys.monitoring.get_local_events(TEST_TOOL2, code), E.PY_START) + sys.monitoring.set_local_events(TEST_TOOL, code, 0) + self.assertEqual(sys.monitoring.get_local_events(TEST_TOOL, code), 0) + sys.monitoring.set_local_events(TEST_TOOL2, code, 0) + self.assertEqual(sys.monitoring.get_local_events(TEST_TOOL2, code), 0) + +class TestUninitialized(unittest.TestCase, MonitoringTestBase): + + @staticmethod + def f(): + pass + + def test_get_local_events_uninitialized(self): + self.assertEqual(sys.monitoring.get_local_events(TEST_TOOL, self.f.__code__), 0) + +class TestRegressions(MonitoringTestBase, unittest.TestCase): + + def test_105162(self): + caught = None + + def inner(): + nonlocal caught + try: + yield + except Exception: + caught = "inner" + yield + + def outer(): + nonlocal caught + try: + yield from inner() + except Exception: + caught = "outer" + yield + + def run(): + gen = outer() + gen.send(None) + gen.throw(Exception) + run() + self.assertEqual(caught, "inner") + caught = None + try: + sys.monitoring.set_events(TEST_TOOL, E.PY_RESUME) + run() + self.assertEqual(caught, "inner") + finally: + sys.monitoring.set_events(TEST_TOOL, 0) + + def test_108390(self): + + class Foo: + def __init__(self, set_event): + if set_event: + sys.monitoring.set_events(TEST_TOOL, E.PY_RESUME) + + def make_foo_optimized_then_set_event(): + for i in range(100): + Foo(i == 99) + + try: + make_foo_optimized_then_set_event() + finally: + sys.monitoring.set_events(TEST_TOOL, 0) + + def test_gh108976(self): + sys.monitoring.use_tool_id(0, "test") + self.addCleanup(sys.monitoring.free_tool_id, 0) + sys.monitoring.set_events(0, 0) + sys.monitoring.register_callback(0, E.LINE, lambda *args: sys.monitoring.set_events(0, 0)) + sys.monitoring.register_callback(0, E.INSTRUCTION, lambda *args: 0) + sys.monitoring.set_events(0, E.LINE | E.INSTRUCTION) + sys.monitoring.set_events(0, 0) diff --git a/Lib/test/test_multibytecodec.py b/Lib/test/test_multibytecodec.py index cf8bb5e3..6451df14 100644 --- a/Lib/test/test_multibytecodec.py +++ b/Lib/test/test_multibytecodec.py @@ -363,6 +363,7 @@ class Test_ISO2022(unittest.TestCase): e = '\u3406'.encode(encoding) self.assertFalse(any(x > 0x80 for x in e)) + @support.requires_resource('cpu') def test_bug1572832(self): for x in range(0x10000, 0x110000): # Any ISO 2022 codec will cause the segfault diff --git a/Lib/test/test_multiprocessing_fork.py b/Lib/test/test_multiprocessing_fork/__init__.py similarity index 66% rename from Lib/test/test_multiprocessing_fork.py rename to Lib/test/test_multiprocessing_fork/__init__.py index 5000edb7..aa1fff50 100644 --- a/Lib/test/test_multiprocessing_fork.py +++ b/Lib/test/test_multiprocessing_fork/__init__.py @@ -1,7 +1,6 @@ -import unittest -import test._test_multiprocessing - +import os.path import sys +import unittest from test import support if support.PGO: @@ -13,7 +12,5 @@ if sys.platform == "win32": if sys.platform == 'darwin': raise unittest.SkipTest("test may crash on macOS (bpo-33725)") -test._test_multiprocessing.install_tests_in_module_dict(globals(), 'fork') - -if __name__ == '__main__': - unittest.main() +def load_tests(*args): + return support.load_package_tests(os.path.dirname(__file__), *args) diff --git a/Lib/test/test_multiprocessing_fork/test_manager.py b/Lib/test/test_multiprocessing_fork/test_manager.py new file mode 100644 index 00000000..9efbb83b --- /dev/null +++ b/Lib/test/test_multiprocessing_fork/test_manager.py @@ -0,0 +1,7 @@ +import unittest +from test._test_multiprocessing import install_tests_in_module_dict + +install_tests_in_module_dict(globals(), 'fork', only_type="manager") + +if __name__ == '__main__': + unittest.main() diff --git a/Lib/test/test_multiprocessing_fork/test_misc.py b/Lib/test/test_multiprocessing_fork/test_misc.py new file mode 100644 index 00000000..891a4940 --- /dev/null +++ b/Lib/test/test_multiprocessing_fork/test_misc.py @@ -0,0 +1,7 @@ +import unittest +from test._test_multiprocessing import install_tests_in_module_dict + +install_tests_in_module_dict(globals(), 'fork', exclude_types=True) + +if __name__ == '__main__': + unittest.main() diff --git a/Lib/test/test_multiprocessing_fork/test_processes.py b/Lib/test/test_multiprocessing_fork/test_processes.py new file mode 100644 index 00000000..e64e9afc --- /dev/null +++ b/Lib/test/test_multiprocessing_fork/test_processes.py @@ -0,0 +1,7 @@ +import unittest +from test._test_multiprocessing import install_tests_in_module_dict + +install_tests_in_module_dict(globals(), 'fork', only_type="processes") + +if __name__ == '__main__': + unittest.main() diff --git a/Lib/test/test_multiprocessing_fork/test_threads.py b/Lib/test/test_multiprocessing_fork/test_threads.py new file mode 100644 index 00000000..1670e34c --- /dev/null +++ b/Lib/test/test_multiprocessing_fork/test_threads.py @@ -0,0 +1,7 @@ +import unittest +from test._test_multiprocessing import install_tests_in_module_dict + +install_tests_in_module_dict(globals(), 'fork', only_type="threads") + +if __name__ == '__main__': + unittest.main() diff --git a/Lib/test/test_multiprocessing_forkserver.py b/Lib/test/test_multiprocessing_forkserver/__init__.py similarity index 58% rename from Lib/test/test_multiprocessing_forkserver.py rename to Lib/test/test_multiprocessing_forkserver/__init__.py index 6ad5faf9..d91715a3 100644 --- a/Lib/test/test_multiprocessing_forkserver.py +++ b/Lib/test/test_multiprocessing_forkserver/__init__.py @@ -1,7 +1,6 @@ -import unittest -import test._test_multiprocessing - +import os.path import sys +import unittest from test import support if support.PGO: @@ -10,7 +9,5 @@ if support.PGO: if sys.platform == "win32": raise unittest.SkipTest("forkserver is not available on Windows") -test._test_multiprocessing.install_tests_in_module_dict(globals(), 'forkserver') - -if __name__ == '__main__': - unittest.main() +def load_tests(*args): + return support.load_package_tests(os.path.dirname(__file__), *args) diff --git a/Lib/test/test_multiprocessing_forkserver/test_manager.py b/Lib/test/test_multiprocessing_forkserver/test_manager.py new file mode 100644 index 00000000..14f8f10d --- /dev/null +++ b/Lib/test/test_multiprocessing_forkserver/test_manager.py @@ -0,0 +1,7 @@ +import unittest +from test._test_multiprocessing import install_tests_in_module_dict + +install_tests_in_module_dict(globals(), 'forkserver', only_type="manager") + +if __name__ == '__main__': + unittest.main() diff --git a/Lib/test/test_multiprocessing_forkserver/test_misc.py b/Lib/test/test_multiprocessing_forkserver/test_misc.py new file mode 100644 index 00000000..9cae1b50 --- /dev/null +++ b/Lib/test/test_multiprocessing_forkserver/test_misc.py @@ -0,0 +1,7 @@ +import unittest +from test._test_multiprocessing import install_tests_in_module_dict + +install_tests_in_module_dict(globals(), 'forkserver', exclude_types=True) + +if __name__ == '__main__': + unittest.main() diff --git a/Lib/test/test_multiprocessing_forkserver/test_processes.py b/Lib/test/test_multiprocessing_forkserver/test_processes.py new file mode 100644 index 00000000..360967cf --- /dev/null +++ b/Lib/test/test_multiprocessing_forkserver/test_processes.py @@ -0,0 +1,7 @@ +import unittest +from test._test_multiprocessing import install_tests_in_module_dict + +install_tests_in_module_dict(globals(), 'forkserver', only_type="processes") + +if __name__ == '__main__': + unittest.main() diff --git a/Lib/test/test_multiprocessing_forkserver/test_threads.py b/Lib/test/test_multiprocessing_forkserver/test_threads.py new file mode 100644 index 00000000..719c752a --- /dev/null +++ b/Lib/test/test_multiprocessing_forkserver/test_threads.py @@ -0,0 +1,7 @@ +import unittest +from test._test_multiprocessing import install_tests_in_module_dict + +install_tests_in_module_dict(globals(), 'forkserver', only_type="threads") + +if __name__ == '__main__': + unittest.main() diff --git a/Lib/test/test_multiprocessing_main_handling.py b/Lib/test/test_multiprocessing_main_handling.py index 510d8d3a..6b30a893 100644 --- a/Lib/test/test_multiprocessing_main_handling.py +++ b/Lib/test/test_multiprocessing_main_handling.py @@ -40,6 +40,7 @@ test_source = """\ import sys import time from multiprocessing import Pool, set_start_method +from test import support # We use this __main__ defined function in the map call below in order to # check that multiprocessing in correctly running the unguarded @@ -59,13 +60,12 @@ if __name__ == '__main__': results = [] with Pool(5) as pool: pool.map_async(f, [1, 2, 3], callback=results.extend) - start_time = time.monotonic() - while not results: - time.sleep(0.05) - # up to 1 min to report the results - dt = time.monotonic() - start_time - if dt > 60.0: - raise RuntimeError("Timed out waiting for results (%.1f sec)" % dt) + + # up to 1 min to report the results + for _ in support.sleeping_retry(support.LONG_TIMEOUT, + "Timed out waiting for results"): + if results: + break results.sort() print(start_method, "->", results) @@ -86,19 +86,18 @@ if __name__ != "__main__": import sys import time from multiprocessing import Pool, set_start_method +from test import support start_method = sys.argv[1] set_start_method(start_method) results = [] with Pool(5) as pool: pool.map_async(int, [1, 4, 9], callback=results.extend) - start_time = time.monotonic() - while not results: - time.sleep(0.05) - # up to 1 min to report the results - dt = time.monotonic() - start_time - if dt > 60.0: - raise RuntimeError("Timed out waiting for results (%.1f sec)" % dt) + # up to 1 min to report the results + for _ in support.sleeping_retry(support.LONG_TIMEOUT, + "Timed out waiting for results"): + if results: + break results.sort() print(start_method, "->", results) diff --git a/Lib/test/test_multiprocessing_spawn.py b/Lib/test/test_multiprocessing_spawn.py deleted file mode 100644 index 65589523..00000000 --- a/Lib/test/test_multiprocessing_spawn.py +++ /dev/null @@ -1,12 +0,0 @@ -import unittest -import test._test_multiprocessing - -from test import support - -if support.PGO: - raise unittest.SkipTest("test is not helpful for PGO") - -test._test_multiprocessing.install_tests_in_module_dict(globals(), 'spawn') - -if __name__ == '__main__': - unittest.main() diff --git a/Lib/test/test_multiprocessing_spawn/__init__.py b/Lib/test/test_multiprocessing_spawn/__init__.py new file mode 100644 index 00000000..3fd0f9b3 --- /dev/null +++ b/Lib/test/test_multiprocessing_spawn/__init__.py @@ -0,0 +1,9 @@ +import os.path +import unittest +from test import support + +if support.PGO: + raise unittest.SkipTest("test is not helpful for PGO") + +def load_tests(*args): + return support.load_package_tests(os.path.dirname(__file__), *args) diff --git a/Lib/test/test_multiprocessing_spawn/test_manager.py b/Lib/test/test_multiprocessing_spawn/test_manager.py new file mode 100644 index 00000000..b40bea0b --- /dev/null +++ b/Lib/test/test_multiprocessing_spawn/test_manager.py @@ -0,0 +1,7 @@ +import unittest +from test._test_multiprocessing import install_tests_in_module_dict + +install_tests_in_module_dict(globals(), 'spawn', only_type="manager") + +if __name__ == '__main__': + unittest.main() diff --git a/Lib/test/test_multiprocessing_spawn/test_misc.py b/Lib/test/test_multiprocessing_spawn/test_misc.py new file mode 100644 index 00000000..32f37c5c --- /dev/null +++ b/Lib/test/test_multiprocessing_spawn/test_misc.py @@ -0,0 +1,7 @@ +import unittest +from test._test_multiprocessing import install_tests_in_module_dict + +install_tests_in_module_dict(globals(), 'spawn', exclude_types=True) + +if __name__ == '__main__': + unittest.main() diff --git a/Lib/test/test_multiprocessing_spawn/test_processes.py b/Lib/test/test_multiprocessing_spawn/test_processes.py new file mode 100644 index 00000000..af764b0d --- /dev/null +++ b/Lib/test/test_multiprocessing_spawn/test_processes.py @@ -0,0 +1,7 @@ +import unittest +from test._test_multiprocessing import install_tests_in_module_dict + +install_tests_in_module_dict(globals(), 'spawn', only_type="processes") + +if __name__ == '__main__': + unittest.main() diff --git a/Lib/test/test_multiprocessing_spawn/test_threads.py b/Lib/test/test_multiprocessing_spawn/test_threads.py new file mode 100644 index 00000000..c1257749 --- /dev/null +++ b/Lib/test/test_multiprocessing_spawn/test_threads.py @@ -0,0 +1,7 @@ +import unittest +from test._test_multiprocessing import install_tests_in_module_dict + +install_tests_in_module_dict(globals(), 'spawn', only_type="threads") + +if __name__ == '__main__': + unittest.main() diff --git a/Lib/test/test_named_expressions.py b/Lib/test/test_named_expressions.py index 20ac2e69..7b2fa844 100644 --- a/Lib/test/test_named_expressions.py +++ b/Lib/test/test_named_expressions.py @@ -114,6 +114,69 @@ class NamedExpressionInvalidTest(unittest.TestCase): "assignment expression within a comprehension cannot be used in a class body"): exec(code, {}, {}) + def test_named_expression_valid_rebinding_iteration_variable(self): + # This test covers that we can reassign variables + # that are not directly assigned in the + # iterable part of a comprehension. + cases = [ + # Regression tests from https://github.com/python/cpython/issues/87447 + ("Complex expression: c", + "{0}(c := 1) for a, (*b, c[d+e::f(g)], h.i) in j{1}"), + ("Complex expression: d", + "{0}(d := 1) for a, (*b, c[d+e::f(g)], h.i) in j{1}"), + ("Complex expression: e", + "{0}(e := 1) for a, (*b, c[d+e::f(g)], h.i) in j{1}"), + ("Complex expression: f", + "{0}(f := 1) for a, (*b, c[d+e::f(g)], h.i) in j{1}"), + ("Complex expression: g", + "{0}(g := 1) for a, (*b, c[d+e::f(g)], h.i) in j{1}"), + ("Complex expression: h", + "{0}(h := 1) for a, (*b, c[d+e::f(g)], h.i) in j{1}"), + ("Complex expression: i", + "{0}(i := 1) for a, (*b, c[d+e::f(g)], h.i) in j{1}"), + ("Complex expression: j", + "{0}(j := 1) for a, (*b, c[d+e::f(g)], h.i) in j{1}"), + ] + for test_case, code in cases: + for lpar, rpar in [('(', ')'), ('[', ']'), ('{', '}')]: + code = code.format(lpar, rpar) + with self.subTest(case=test_case, lpar=lpar, rpar=rpar): + # Names used in snippets are not defined, + # but we are fine with it: just must not be a SyntaxError. + # Names used in snippets are not defined, + # but we are fine with it: just must not be a SyntaxError. + with self.assertRaises(NameError): + exec(code, {}) # Module scope + with self.assertRaises(NameError): + exec(code, {}, {}) # Class scope + exec(f"lambda: {code}", {}) # Function scope + + def test_named_expression_invalid_rebinding_iteration_variable(self): + # This test covers that we cannot reassign variables + # that are directly assigned in the iterable part of a comprehension. + cases = [ + # Regression tests from https://github.com/python/cpython/issues/87447 + ("Complex expression: a", "a", + "{0}(a := 1) for a, (*b, c[d+e::f(g)], h.i) in j{1}"), + ("Complex expression: b", "b", + "{0}(b := 1) for a, (*b, c[d+e::f(g)], h.i) in j{1}"), + ] + for test_case, target, code in cases: + msg = f"assignment expression cannot rebind comprehension iteration variable '{target}'" + for lpar, rpar in [('(', ')'), ('[', ']'), ('{', '}')]: + code = code.format(lpar, rpar) + with self.subTest(case=test_case, lpar=lpar, rpar=rpar): + # Names used in snippets are not defined, + # but we are fine with it: just must not be a SyntaxError. + # Names used in snippets are not defined, + # but we are fine with it: just must not be a SyntaxError. + with self.assertRaisesRegex(SyntaxError, msg): + exec(code, {}) # Module scope + with self.assertRaisesRegex(SyntaxError, msg): + exec(code, {}, {}) # Class scope + with self.assertRaisesRegex(SyntaxError, msg): + exec(f"lambda: {code}", {}) # Function scope + def test_named_expression_invalid_rebinding_list_comprehension_iteration_variable(self): cases = [ ("Local reuse", 'i', "[i := 0 for i in range(5)]"), @@ -129,7 +192,11 @@ class NamedExpressionInvalidTest(unittest.TestCase): msg = f"assignment expression cannot rebind comprehension iteration variable '{target}'" with self.subTest(case=case): with self.assertRaisesRegex(SyntaxError, msg): - exec(code, {}, {}) + exec(code, {}) # Module scope + with self.assertRaisesRegex(SyntaxError, msg): + exec(code, {}, {}) # Class scope + with self.assertRaisesRegex(SyntaxError, msg): + exec(f"lambda: {code}", {}) # Function scope def test_named_expression_invalid_rebinding_list_comprehension_inner_loop(self): cases = [ @@ -178,12 +245,21 @@ class NamedExpressionInvalidTest(unittest.TestCase): ("Unreachable reuse", 'i', "{False or (i:=0) for i in range(5)}"), ("Unreachable nested reuse", 'i', "{(i, j) for i in range(5) for j in range(5) if True or (i:=10)}"), + # Regression tests from https://github.com/python/cpython/issues/87447 + ("Complex expression: a", "a", + "{(a := 1) for a, (*b, c[d+e::f(g)], h.i) in j}"), + ("Complex expression: b", "b", + "{(b := 1) for a, (*b, c[d+e::f(g)], h.i) in j}"), ] for case, target, code in cases: msg = f"assignment expression cannot rebind comprehension iteration variable '{target}'" with self.subTest(case=case): with self.assertRaisesRegex(SyntaxError, msg): - exec(code, {}, {}) + exec(code, {}) # Module scope + with self.assertRaisesRegex(SyntaxError, msg): + exec(code, {}, {}) # Class scope + with self.assertRaisesRegex(SyntaxError, msg): + exec(f"lambda: {code}", {}) # Function scope def test_named_expression_invalid_rebinding_set_comprehension_inner_loop(self): cases = [ diff --git a/Lib/test/test_netrc.py b/Lib/test/test_netrc.py index 573d636d..81e11a29 100644 --- a/Lib/test/test_netrc.py +++ b/Lib/test/test_netrc.py @@ -1,5 +1,5 @@ import netrc, os, unittest, sys, textwrap -from test.support import os_helper, run_unittest +from test.support import os_helper try: import pwd @@ -308,8 +308,6 @@ class NetrcTestCase(unittest.TestCase): self.assertEqual(nrc.hosts['foo.domain.com'], ('anonymous', '', 'pass')) -def test_main(): - run_unittest(NetrcTestCase) if __name__ == "__main__": - test_main() + unittest.main() diff --git a/Lib/test/test_nis.py b/Lib/test/test_nis.py index 797c9023..f327ecf3 100644 --- a/Lib/test/test_nis.py +++ b/Lib/test/test_nis.py @@ -1,4 +1,3 @@ -from test import support from test.support import import_helper import unittest import warnings diff --git a/Lib/test/test_ntpath.py b/Lib/test/test_ntpath.py index c26c74cd..d91dcdfb 100644 --- a/Lib/test/test_ntpath.py +++ b/Lib/test/test_ntpath.py @@ -1,9 +1,11 @@ +import inspect import ntpath import os +import string import sys import unittest import warnings -from test.support import os_helper +from test.support import cpython_only, os_helper from test.support import TestFailed, is_emscripten from test.support.os_helper import FakePath from test import test_genericpath @@ -98,58 +100,118 @@ class TestNtpath(NtpathTestCase): tester('ntpath.splitext("c:a/b\\c.d")', ('c:a/b\\c', '.d')) def test_splitdrive(self): - tester('ntpath.splitdrive("c:\\foo\\bar")', - ('c:', '\\foo\\bar')) - tester('ntpath.splitdrive("c:/foo/bar")', - ('c:', '/foo/bar')) + tester("ntpath.splitdrive('')", ('', '')) + tester("ntpath.splitdrive('foo')", ('', 'foo')) + tester("ntpath.splitdrive('foo\\bar')", ('', 'foo\\bar')) + tester("ntpath.splitdrive('foo/bar')", ('', 'foo/bar')) + tester("ntpath.splitdrive('\\')", ('', '\\')) + tester("ntpath.splitdrive('/')", ('', '/')) + tester("ntpath.splitdrive('\\foo\\bar')", ('', '\\foo\\bar')) + tester("ntpath.splitdrive('/foo/bar')", ('', '/foo/bar')) + tester('ntpath.splitdrive("c:foo\\bar")', ('c:', 'foo\\bar')) + tester('ntpath.splitdrive("c:foo/bar")', ('c:', 'foo/bar')) + tester('ntpath.splitdrive("c:\\foo\\bar")', ('c:', '\\foo\\bar')) + tester('ntpath.splitdrive("c:/foo/bar")', ('c:', '/foo/bar')) + tester("ntpath.splitdrive('\\\\')", ('\\\\', '')) + tester("ntpath.splitdrive('//')", ('//', '')) tester('ntpath.splitdrive("\\\\conky\\mountpoint\\foo\\bar")', ('\\\\conky\\mountpoint', '\\foo\\bar')) tester('ntpath.splitdrive("//conky/mountpoint/foo/bar")', ('//conky/mountpoint', '/foo/bar')) - tester('ntpath.splitdrive("\\\\\\conky\\mountpoint\\foo\\bar")', - ('\\\\\\conky', '\\mountpoint\\foo\\bar')) - tester('ntpath.splitdrive("///conky/mountpoint/foo/bar")', - ('///conky', '/mountpoint/foo/bar')) - tester('ntpath.splitdrive("\\\\conky\\\\mountpoint\\foo\\bar")', - ('\\\\conky\\', '\\mountpoint\\foo\\bar')) - tester('ntpath.splitdrive("//conky//mountpoint/foo/bar")', - ('//conky/', '/mountpoint/foo/bar')) + tester('ntpath.splitdrive("\\\\?\\UNC\\server\\share\\dir")', + ("\\\\?\\UNC\\server\\share", "\\dir")) + tester('ntpath.splitdrive("//?/UNC/server/share/dir")', + ("//?/UNC/server/share", "/dir")) + + def test_splitroot(self): + tester("ntpath.splitroot('')", ('', '', '')) + tester("ntpath.splitroot('foo')", ('', '', 'foo')) + tester("ntpath.splitroot('foo\\bar')", ('', '', 'foo\\bar')) + tester("ntpath.splitroot('foo/bar')", ('', '', 'foo/bar')) + tester("ntpath.splitroot('\\')", ('', '\\', '')) + tester("ntpath.splitroot('/')", ('', '/', '')) + tester("ntpath.splitroot('\\foo\\bar')", ('', '\\', 'foo\\bar')) + tester("ntpath.splitroot('/foo/bar')", ('', '/', 'foo/bar')) + tester('ntpath.splitroot("c:foo\\bar")', ('c:', '', 'foo\\bar')) + tester('ntpath.splitroot("c:foo/bar")', ('c:', '', 'foo/bar')) + tester('ntpath.splitroot("c:\\foo\\bar")', ('c:', '\\', 'foo\\bar')) + tester('ntpath.splitroot("c:/foo/bar")', ('c:', '/', 'foo/bar')) + + # Redundant slashes are not included in the root. + tester("ntpath.splitroot('c:\\\\a')", ('c:', '\\', '\\a')) + tester("ntpath.splitroot('c:\\\\\\a/b')", ('c:', '\\', '\\\\a/b')) + + # Mixed path separators. + tester("ntpath.splitroot('c:/\\')", ('c:', '/', '\\')) + tester("ntpath.splitroot('c:\\/')", ('c:', '\\', '/')) + tester("ntpath.splitroot('/\\a/b\\/\\')", ('/\\a/b', '\\', '/\\')) + tester("ntpath.splitroot('\\/a\\b/\\/')", ('\\/a\\b', '/', '\\/')) + + # UNC paths. + tester("ntpath.splitroot('\\\\')", ('\\\\', '', '')) + tester("ntpath.splitroot('//')", ('//', '', '')) + tester('ntpath.splitroot("\\\\conky\\mountpoint\\foo\\bar")', + ('\\\\conky\\mountpoint', '\\', 'foo\\bar')) + tester('ntpath.splitroot("//conky/mountpoint/foo/bar")', + ('//conky/mountpoint', '/', 'foo/bar')) + tester('ntpath.splitroot("\\\\\\conky\\mountpoint\\foo\\bar")', + ('\\\\\\conky', '\\', 'mountpoint\\foo\\bar')) + tester('ntpath.splitroot("///conky/mountpoint/foo/bar")', + ('///conky', '/', 'mountpoint/foo/bar')) + tester('ntpath.splitroot("\\\\conky\\\\mountpoint\\foo\\bar")', + ('\\\\conky\\', '\\', 'mountpoint\\foo\\bar')) + tester('ntpath.splitroot("//conky//mountpoint/foo/bar")', + ('//conky/', '/', 'mountpoint/foo/bar')) + # Issue #19911: UNC part containing U+0130 - self.assertEqual(ntpath.splitdrive('//conky/MOUNTPOİNT/foo/bar'), - ('//conky/MOUNTPOİNT', '/foo/bar')) + self.assertEqual(ntpath.splitroot('//conky/MOUNTPOİNT/foo/bar'), + ('//conky/MOUNTPOİNT', '/', 'foo/bar')) # gh-81790: support device namespace, including UNC drives. - tester('ntpath.splitdrive("//?/c:")', ("//?/c:", "")) - tester('ntpath.splitdrive("//?/c:/")', ("//?/c:", "/")) - tester('ntpath.splitdrive("//?/c:/dir")', ("//?/c:", "/dir")) - tester('ntpath.splitdrive("//?/UNC")', ("//?/UNC", "")) - tester('ntpath.splitdrive("//?/UNC/")', ("//?/UNC/", "")) - tester('ntpath.splitdrive("//?/UNC/server/")', ("//?/UNC/server/", "")) - tester('ntpath.splitdrive("//?/UNC/server/share")', ("//?/UNC/server/share", "")) - tester('ntpath.splitdrive("//?/UNC/server/share/dir")', ("//?/UNC/server/share", "/dir")) - tester('ntpath.splitdrive("//?/VOLUME{00000000-0000-0000-0000-000000000000}/spam")', - ('//?/VOLUME{00000000-0000-0000-0000-000000000000}', '/spam')) - tester('ntpath.splitdrive("//?/BootPartition/")', ("//?/BootPartition", "/")) - - tester('ntpath.splitdrive("\\\\?\\c:")', ("\\\\?\\c:", "")) - tester('ntpath.splitdrive("\\\\?\\c:\\")', ("\\\\?\\c:", "\\")) - tester('ntpath.splitdrive("\\\\?\\c:\\dir")', ("\\\\?\\c:", "\\dir")) - tester('ntpath.splitdrive("\\\\?\\UNC")', ("\\\\?\\UNC", "")) - tester('ntpath.splitdrive("\\\\?\\UNC\\")', ("\\\\?\\UNC\\", "")) - tester('ntpath.splitdrive("\\\\?\\UNC\\server\\")', ("\\\\?\\UNC\\server\\", "")) - tester('ntpath.splitdrive("\\\\?\\UNC\\server\\share")', ("\\\\?\\UNC\\server\\share", "")) - tester('ntpath.splitdrive("\\\\?\\UNC\\server\\share\\dir")', - ("\\\\?\\UNC\\server\\share", "\\dir")) - tester('ntpath.splitdrive("\\\\?\\VOLUME{00000000-0000-0000-0000-000000000000}\\spam")', - ('\\\\?\\VOLUME{00000000-0000-0000-0000-000000000000}', '\\spam')) - tester('ntpath.splitdrive("\\\\?\\BootPartition\\")', ("\\\\?\\BootPartition", "\\")) + tester('ntpath.splitroot("//?/c:")', ("//?/c:", "", "")) + tester('ntpath.splitroot("//./c:")', ("//./c:", "", "")) + tester('ntpath.splitroot("//?/c:/")', ("//?/c:", "/", "")) + tester('ntpath.splitroot("//?/c:/dir")', ("//?/c:", "/", "dir")) + tester('ntpath.splitroot("//?/UNC")', ("//?/UNC", "", "")) + tester('ntpath.splitroot("//?/UNC/")', ("//?/UNC/", "", "")) + tester('ntpath.splitroot("//?/UNC/server/")', ("//?/UNC/server/", "", "")) + tester('ntpath.splitroot("//?/UNC/server/share")', ("//?/UNC/server/share", "", "")) + tester('ntpath.splitroot("//?/UNC/server/share/dir")', ("//?/UNC/server/share", "/", "dir")) + tester('ntpath.splitroot("//?/VOLUME{00000000-0000-0000-0000-000000000000}/spam")', + ('//?/VOLUME{00000000-0000-0000-0000-000000000000}', '/', 'spam')) + tester('ntpath.splitroot("//?/BootPartition/")', ("//?/BootPartition", "/", "")) + tester('ntpath.splitroot("//./BootPartition/")', ("//./BootPartition", "/", "")) + tester('ntpath.splitroot("//./PhysicalDrive0")', ("//./PhysicalDrive0", "", "")) + tester('ntpath.splitroot("//./nul")', ("//./nul", "", "")) + + tester('ntpath.splitroot("\\\\?\\c:")', ("\\\\?\\c:", "", "")) + tester('ntpath.splitroot("\\\\.\\c:")', ("\\\\.\\c:", "", "")) + tester('ntpath.splitroot("\\\\?\\c:\\")', ("\\\\?\\c:", "\\", "")) + tester('ntpath.splitroot("\\\\?\\c:\\dir")', ("\\\\?\\c:", "\\", "dir")) + tester('ntpath.splitroot("\\\\?\\UNC")', ("\\\\?\\UNC", "", "")) + tester('ntpath.splitroot("\\\\?\\UNC\\")', ("\\\\?\\UNC\\", "", "")) + tester('ntpath.splitroot("\\\\?\\UNC\\server\\")', ("\\\\?\\UNC\\server\\", "", "")) + tester('ntpath.splitroot("\\\\?\\UNC\\server\\share")', + ("\\\\?\\UNC\\server\\share", "", "")) + tester('ntpath.splitroot("\\\\?\\UNC\\server\\share\\dir")', + ("\\\\?\\UNC\\server\\share", "\\", "dir")) + tester('ntpath.splitroot("\\\\?\\VOLUME{00000000-0000-0000-0000-000000000000}\\spam")', + ('\\\\?\\VOLUME{00000000-0000-0000-0000-000000000000}', '\\', 'spam')) + tester('ntpath.splitroot("\\\\?\\BootPartition\\")', ("\\\\?\\BootPartition", "\\", "")) + tester('ntpath.splitroot("\\\\.\\BootPartition\\")', ("\\\\.\\BootPartition", "\\", "")) + tester('ntpath.splitroot("\\\\.\\PhysicalDrive0")', ("\\\\.\\PhysicalDrive0", "", "")) + tester('ntpath.splitroot("\\\\.\\nul")', ("\\\\.\\nul", "", "")) # gh-96290: support partial/invalid UNC drives - tester('ntpath.splitdrive("//")', ("//", "")) # empty server & missing share - tester('ntpath.splitdrive("///")', ("///", "")) # empty server & empty share - tester('ntpath.splitdrive("///y")', ("///y", "")) # empty server & non-empty share - tester('ntpath.splitdrive("//x")', ("//x", "")) # non-empty server & missing share - tester('ntpath.splitdrive("//x/")', ("//x/", "")) # non-empty server & empty share + tester('ntpath.splitroot("//")', ("//", "", "")) # empty server & missing share + tester('ntpath.splitroot("///")', ("///", "", "")) # empty server & empty share + tester('ntpath.splitroot("///y")', ("///y", "", "")) # empty server & non-empty share + tester('ntpath.splitroot("//x")', ("//x", "", "")) # non-empty server & missing share + tester('ntpath.splitroot("//x/")', ("//x/", "", "")) # non-empty server & empty share + + # gh-101363: match GetFullPathNameW() drive letter parsing behaviour + tester('ntpath.splitroot(" :/foo")', (" :", "/", "foo")) + tester('ntpath.splitroot("/:/foo")', ("", "/", ":/foo")) def test_split(self): tester('ntpath.split("c:\\foo\\bar")', ('c:\\foo', 'bar')) @@ -246,6 +308,11 @@ class TestNtpath(NtpathTestCase): tester("ntpath.join('//computer/share', 'a', 'b')", '//computer/share\\a\\b') tester("ntpath.join('//computer/share', 'a/b')", '//computer/share\\a/b') + tester("ntpath.join('\\\\', 'computer')", '\\\\computer') + tester("ntpath.join('\\\\computer\\', 'share')", '\\\\computer\\share') + tester("ntpath.join('\\\\computer\\share\\', 'a')", '\\\\computer\\share\\a') + tester("ntpath.join('\\\\computer\\share\\a\\', 'b')", '\\\\computer\\share\\a\\b') + def test_normpath(self): tester("ntpath.normpath('A//////././//.//B')", r'A\B') tester("ntpath.normpath('A/./B')", r'A\B') @@ -321,6 +388,16 @@ class TestNtpath(NtpathTestCase): self.assertPathEqual(ntpath.realpath(os.fsencode(ABSTFN + "1")), os.fsencode(ABSTFN)) + # gh-88013: call ntpath.realpath with binary drive name may raise a + # TypeError. The drive should not exist to reproduce the bug. + drives = {f"{c}:\\" for c in string.ascii_uppercase} - set(os.listdrives()) + d = drives.pop().encode() + self.assertEqual(ntpath.realpath(d), d) + + # gh-106242: Embedded nulls and non-strict fallback to abspath + self.assertEqual(ABSTFN + "\0spam", + ntpath.realpath(os_helper.TESTFN + "\0spam", strict=False)) + @os_helper.skip_unless_symlink @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname') def test_realpath_strict(self): @@ -331,6 +408,8 @@ class TestNtpath(NtpathTestCase): self.addCleanup(os_helper.unlink, ABSTFN) self.assertRaises(FileNotFoundError, ntpath.realpath, ABSTFN, strict=True) self.assertRaises(FileNotFoundError, ntpath.realpath, ABSTFN + "2", strict=True) + # gh-106242: Embedded nulls should raise OSError (not ValueError) + self.assertRaises(OSError, ntpath.realpath, ABSTFN + "\0spam", strict=True) @os_helper.skip_unless_symlink @unittest.skipUnless(HAVE_GETFINALPATHNAME, 'need _getfinalpathname') @@ -874,6 +953,72 @@ class TestNtpath(NtpathTestCase): self.assertIsInstance(b_final_path, bytes) self.assertGreater(len(b_final_path), 0) + @unittest.skipIf(sys.platform != 'win32', "Can only test junctions with creation on win32.") + def test_isjunction(self): + with os_helper.temp_dir() as d: + with os_helper.change_cwd(d): + os.mkdir('tmpdir') + + import _winapi + try: + _winapi.CreateJunction('tmpdir', 'testjunc') + except OSError: + raise unittest.SkipTest('creating the test junction failed') + + self.assertTrue(ntpath.isjunction('testjunc')) + self.assertFalse(ntpath.isjunction('tmpdir')) + self.assertPathEqual(ntpath.realpath('testjunc'), ntpath.realpath('tmpdir')) + + @unittest.skipIf(sys.platform != 'win32', "drive letters are a windows concept") + def test_isfile_driveletter(self): + drive = os.environ.get('SystemDrive') + if drive is None or len(drive) != 2 or drive[1] != ':': + raise unittest.SkipTest('SystemDrive is not defined or malformed') + self.assertFalse(os.path.isfile('\\\\.\\' + drive)) + + @unittest.skipIf(sys.platform != 'win32', "windows only") + def test_con_device(self): + self.assertFalse(os.path.isfile(r"\\.\CON")) + self.assertFalse(os.path.isdir(r"\\.\CON")) + self.assertFalse(os.path.islink(r"\\.\CON")) + self.assertTrue(os.path.exists(r"\\.\CON")) + + @unittest.skipIf(sys.platform != 'win32', "Fast paths are only for win32") + @cpython_only + def test_fast_paths_in_use(self): + # There are fast paths of these functions implemented in posixmodule.c. + # Confirm that they are being used, and not the Python fallbacks in + # genericpath.py. + self.assertTrue(os.path.isdir is nt._path_isdir) + self.assertFalse(inspect.isfunction(os.path.isdir)) + self.assertTrue(os.path.isfile is nt._path_isfile) + self.assertFalse(inspect.isfunction(os.path.isfile)) + self.assertTrue(os.path.islink is nt._path_islink) + self.assertFalse(inspect.isfunction(os.path.islink)) + self.assertTrue(os.path.exists is nt._path_exists) + self.assertFalse(inspect.isfunction(os.path.exists)) + + @unittest.skipIf(os.name != 'nt', "Dev Drives only exist on Win32") + def test_isdevdrive(self): + # Result may be True or False, but shouldn't raise + self.assertIn(ntpath.isdevdrive(os_helper.TESTFN), (True, False)) + # ntpath.isdevdrive can handle relative paths + self.assertIn(ntpath.isdevdrive("."), (True, False)) + self.assertIn(ntpath.isdevdrive(b"."), (True, False)) + # Volume syntax is supported + self.assertIn(ntpath.isdevdrive(os.listvolumes()[0]), (True, False)) + # Invalid volume returns False from os.path method + self.assertFalse(ntpath.isdevdrive(r"\\?\Volume{00000000-0000-0000-0000-000000000000}\\")) + # Invalid volume raises from underlying helper + with self.assertRaises(OSError): + nt._path_isdevdrive(r"\\?\Volume{00000000-0000-0000-0000-000000000000}\\") + + @unittest.skipIf(os.name == 'nt', "isdevdrive fallback only used off Win32") + def test_isdevdrive_fallback(self): + # Fallback always returns False + self.assertFalse(ntpath.isdevdrive(os_helper.TESTFN)) + + class NtCommonTest(test_genericpath.CommonTest, unittest.TestCase): pathmodule = ntpath attributes = ['relpath'] @@ -897,6 +1042,7 @@ class PathLikeTests(NtpathTestCase): self._check_function(self.path.normcase) if sys.platform == 'win32': self.assertEqual(ntpath.normcase('\u03a9\u2126'), 'ωΩ') + self.assertEqual(ntpath.normcase('abc\x00def'), 'abc\x00def') def test_path_isabs(self): self._check_function(self.path.isabs) @@ -914,6 +1060,9 @@ class PathLikeTests(NtpathTestCase): def test_path_splitdrive(self): self._check_function(self.path.splitdrive) + def test_path_splitroot(self): + self._check_function(self.path.splitroot) + def test_path_basename(self): self._check_function(self.path.basename) diff --git a/Lib/test/test_numeric_tower.py b/Lib/test/test_numeric_tower.py index 9cd85e13..337682d6 100644 --- a/Lib/test/test_numeric_tower.py +++ b/Lib/test/test_numeric_tower.py @@ -145,7 +145,7 @@ class HashTest(unittest.TestCase): # The numbers ABC doesn't enforce that the "true" division # of integers produces a float. This tests that the # Rational.__float__() method has required type conversions. - x = F(DummyIntegral(1), DummyIntegral(2), _normalize=False) + x = F._from_coprime_ints(DummyIntegral(1), DummyIntegral(2)) self.assertRaises(TypeError, lambda: x.numerator/x.denominator) self.assertEqual(float(x), 0.5) diff --git a/Lib/test/test_opcache.py b/Lib/test/test_opcache.py index e39b7260..5281eb77 100644 --- a/Lib/test/test_opcache.py +++ b/Lib/test/test_opcache.py @@ -1,6 +1,29 @@ import unittest +class TestLoadSuperAttrCache(unittest.TestCase): + def test_descriptor_not_double_executed_on_spec_fail(self): + calls = [] + class Descriptor: + def __get__(self, instance, owner): + calls.append((instance, owner)) + return lambda: 1 + + class C: + d = Descriptor() + + class D(C): + def f(self): + return super().d() + + d = D() + + self.assertEqual(d.f(), 1) # warmup + calls.clear() + self.assertEqual(d.f(), 1) # try to specialize + self.assertEqual(calls, [(d, D)]) + + class TestLoadAttrCache(unittest.TestCase): def test_descriptor_added_after_optimization(self): class Descriptor: @@ -429,6 +452,35 @@ class TestLoadMethodCache(unittest.TestCase): self.assertFalse(f()) +class TestCallCache(unittest.TestCase): + def test_too_many_defaults_0(self): + def f(): + pass + + f.__defaults__ = (None,) + for _ in range(1025): + f() + + def test_too_many_defaults_1(self): + def f(x): + pass + + f.__defaults__ = (None, None) + for _ in range(1025): + f(None) + f() + + def test_too_many_defaults_2(self): + def f(x, y): + pass + + f.__defaults__ = (None, None, None) + for _ in range(1025): + f(None, None) + f(None) + f() + + if __name__ == "__main__": import unittest unittest.main() diff --git a/Lib/test/test_operator.py b/Lib/test/test_operator.py index b7e38c23..1db738d2 100644 --- a/Lib/test/test_operator.py +++ b/Lib/test/test_operator.py @@ -208,6 +208,9 @@ class OperatorTestCase: nan = float("nan") self.assertEqual(operator.indexOf([nan, nan, 21], nan), 0) self.assertEqual(operator.indexOf([{}, 1, {}, 2], {}), 0) + it = iter('leave the iterator at exactly the position after the match') + self.assertEqual(operator.indexOf(it, 'a'), 2) + self.assertEqual(next(it), 'v') def test_invert(self): operator = self.module diff --git a/Lib/test/test_ordered_dict.py b/Lib/test/test_ordered_dict.py index 37447fd2..4571b23d 100644 --- a/Lib/test/test_ordered_dict.py +++ b/Lib/test/test_ordered_dict.py @@ -122,6 +122,17 @@ class OrderedDictTests: self.OrderedDict(Spam()) self.assertEqual(calls, ['keys']) + def test_overridden_init(self): + # Sync-up pure Python OD class with C class where + # a consistent internal state is created in __new__ + # rather than __init__. + OrderedDict = self.OrderedDict + class ODNI(OrderedDict): + def __init__(*args, **kwargs): + pass + od = ODNI() + od['a'] = 1 # This used to fail because __init__ was bypassed + def test_fromkeys(self): OrderedDict = self.OrderedDict od = OrderedDict.fromkeys('abc') @@ -362,7 +373,7 @@ class OrderedDictTests: OrderedDict = self.OrderedDict od = OrderedDict([('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]) self.assertEqual(repr(od), - "OrderedDict([('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)])") + "OrderedDict({'c': 1, 'b': 2, 'a': 3, 'd': 4, 'e': 5, 'f': 6})") self.assertEqual(eval(repr(od)), od) self.assertEqual(repr(OrderedDict()), "OrderedDict()") @@ -372,7 +383,7 @@ class OrderedDictTests: od = OrderedDict.fromkeys('abc') od['x'] = od self.assertEqual(repr(od), - "OrderedDict([('a', None), ('b', None), ('c', None), ('x', ...)])") + "OrderedDict({'a': None, 'b': None, 'c': None, 'x': ...})") def test_repr_recursive_values(self): OrderedDict = self.OrderedDict diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index 9970b234..3cc5a6aa 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -33,6 +33,7 @@ from test import support from test.support import import_helper from test.support import os_helper from test.support import socket_helper +from test.support import set_recursion_limit from test.support import warnings_helper from platform import win32_is_iot @@ -555,6 +556,15 @@ class StatAttributeTests(unittest.TestCase): nanosecondy = getattr(result, name + "_ns") // 10000 self.assertAlmostEqual(floaty, nanosecondy, delta=2) + # Ensure both birthtime and birthtime_ns roughly agree, if present + try: + floaty = int(result.st_birthtime * 100000) + nanosecondy = result.st_birthtime_ns // 10000 + except AttributeError: + pass + else: + self.assertAlmostEqual(floaty, nanosecondy, delta=2) + try: result[200] self.fail("No exception raised") @@ -606,12 +616,13 @@ class StatAttributeTests(unittest.TestCase): def test_stat_result_pickle(self): result = os.stat(self.fname) for proto in range(pickle.HIGHEST_PROTOCOL + 1): - p = pickle.dumps(result, proto) - self.assertIn(b'stat_result', p) - if proto < 4: - self.assertIn(b'cos\nstat_result\n', p) - unpickled = pickle.loads(p) - self.assertEqual(result, unpickled) + with self.subTest(f'protocol {proto}'): + p = pickle.dumps(result, proto) + self.assertIn(b'stat_result', p) + if proto < 4: + self.assertIn(b'cos\nstat_result\n', p) + unpickled = pickle.loads(p) + self.assertEqual(result, unpickled) @unittest.skipUnless(hasattr(os, 'statvfs'), 'test needs os.statvfs()') def test_statvfs_attributes(self): @@ -726,7 +737,7 @@ class StatAttributeTests(unittest.TestCase): # denied. See issue 28075. # os.environ['TEMP'] should be located on a volume that # supports file ACLs. - fname = os.path.join(os.environ['TEMP'], self.fname) + fname = os.path.join(os.environ['TEMP'], self.fname + "_access") self.addCleanup(os_helper.unlink, fname) create_file(fname, b'ABC') # Deny the right to [S]YNCHRONIZE on the file to @@ -740,6 +751,7 @@ class StatAttributeTests(unittest.TestCase): ) result = os.stat(fname) self.assertNotEqual(result.st_size, 0) + self.assertTrue(os.path.isfile(fname)) @unittest.skipUnless(sys.platform == "win32", "Win32 specific tests") def test_stat_block_device(self): @@ -1470,6 +1482,46 @@ class WalkTests(unittest.TestCase): self.assertEqual(next(it), expected) p = os.path.join(p, 'd') + def test_walk_above_recursion_limit(self): + depth = 50 + os.makedirs(os.path.join(self.walk_path, *(['d'] * depth))) + with set_recursion_limit(depth - 5): + all = list(self.walk(self.walk_path)) + + sub2_path = self.sub2_tree[0] + for root, dirs, files in all: + if root == sub2_path: + dirs.sort() + files.sort() + + d_entries = [] + d_path = self.walk_path + for _ in range(depth): + d_path = os.path.join(d_path, "d") + d_entries.append((d_path, ["d"], [])) + d_entries[-1][1].clear() + + # Sub-sequences where the order is known + sections = { + "SUB1": [ + (self.sub1_path, ["SUB11"], ["tmp2"]), + (self.sub11_path, [], []), + ], + "SUB2": [self.sub2_tree], + "d": d_entries, + } + + # The ordering of sub-dirs is arbitrary but determines the order in + # which sub-sequences appear + dirs = all[0][1] + expected = [(self.walk_path, dirs, ["tmp1"])] + for d in dirs: + expected.extend(sections[d]) + + self.assertEqual(len(all), depth + 4) + self.assertEqual(sorted(dirs), ["SUB1", "SUB2", "d"]) + self.assertEqual(all, expected) + @unittest.skipUnless(hasattr(os, 'fwalk'), "Test needs os.fwalk()") class FwalkTests(WalkTests): @@ -1544,6 +1596,8 @@ class FwalkTests(WalkTests): # fwalk() keeps file descriptors open test_walk_many_open_files = None + # fwalk() still uses recursion + test_walk_above_recursion_limit = None class BytesWalkTests(WalkTests): @@ -2176,6 +2230,26 @@ class TestInvalidFD(unittest.TestCase): def test_dup2(self): self.check(os.dup2, 20) + @unittest.skipUnless(hasattr(os, 'dup2'), 'test needs os.dup2()') + @unittest.skipIf( + support.is_emscripten, + "dup2() with negative fds is broken on Emscripten (see gh-102179)" + ) + def test_dup2_negative_fd(self): + valid_fd = os.open(__file__, os.O_RDONLY) + self.addCleanup(os.close, valid_fd) + fds = [ + valid_fd, + -1, + -2**31, + ] + for fd, fd2 in itertools.product(fds, repeat=2): + if fd != fd2: + with self.subTest(fd=fd, fd2=fd2): + with self.assertRaises(OSError) as ctx: + os.dup2(fd, fd2) + self.assertEqual(ctx.exception.errno, errno.EBADF) + @unittest.skipUnless(hasattr(os, 'fchmod'), 'test needs os.fchmod()') def test_fchmod(self): self.check(os.fchmod, 0) @@ -2583,6 +2657,54 @@ class Win32ListdirTests(unittest.TestCase): [os.fsencode(path) for path in self.created_paths]) +@unittest.skipUnless(os.name == "nt", "NT specific tests") +class Win32ListdriveTests(unittest.TestCase): + """Test listdrive, listmounts and listvolume on Windows.""" + + def setUp(self): + # Get drives and volumes from fsutil + out = subprocess.check_output( + ["fsutil.exe", "volume", "list"], + cwd=os.path.join(os.getenv("SystemRoot", "\\Windows"), "System32"), + encoding="mbcs", + errors="ignore", + ) + lines = out.splitlines() + self.known_volumes = {l for l in lines if l.startswith('\\\\?\\')} + self.known_drives = {l for l in lines if l[1:] == ':\\'} + self.known_mounts = {l for l in lines if l[1:3] == ':\\'} + + def test_listdrives(self): + drives = os.listdrives() + self.assertIsInstance(drives, list) + self.assertSetEqual( + self.known_drives, + self.known_drives & set(drives), + ) + + def test_listvolumes(self): + volumes = os.listvolumes() + self.assertIsInstance(volumes, list) + self.assertSetEqual( + self.known_volumes, + self.known_volumes & set(volumes), + ) + + def test_listmounts(self): + for volume in os.listvolumes(): + try: + mounts = os.listmounts(volume) + except OSError as ex: + if support.verbose: + print("Skipping", volume, "because of", ex) + else: + self.assertIsInstance(mounts, list) + self.assertSetEqual( + set(mounts), + self.known_mounts & set(mounts), + ) + + @unittest.skipUnless(hasattr(os, 'readlink'), 'needs os.readlink()') class ReadlinkTests(unittest.TestCase): filelink = 'readlinktest' @@ -2816,6 +2938,7 @@ class Win32SymlinkTests(unittest.TestCase): self.assertEqual(st, os.stat(alias)) self.assertFalse(stat.S_ISLNK(st.st_mode)) self.assertEqual(st.st_reparse_tag, stat.IO_REPARSE_TAG_APPEXECLINK) + self.assertTrue(os.path.isfile(alias)) # testing the first one we see is sufficient break else: @@ -3018,11 +3141,13 @@ class DeviceEncodingTests(unittest.TestCase): class PidTests(unittest.TestCase): @unittest.skipUnless(hasattr(os, 'getppid'), "test needs os.getppid") def test_getppid(self): - p = subprocess.Popen([sys.executable, '-c', + p = subprocess.Popen([sys._base_executable, '-c', 'import os; print(os.getppid())'], - stdout=subprocess.PIPE) - stdout, _ = p.communicate() + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + stdout, error = p.communicate() # We are the parent of our subprocess + self.assertEqual(error, b'') self.assertEqual(int(stdout), os.getpid()) def check_waitpid(self, code, exitcode, callback=None): @@ -3089,6 +3214,14 @@ class PidTests(unittest.TestCase): @support.requires_subprocess() class SpawnTests(unittest.TestCase): + @staticmethod + def quote_args(args): + # On Windows, os.spawn* simply joins arguments with spaces: + # arguments need to be quoted + if os.name != 'nt': + return args + return [f'"{arg}"' if " " in arg.strip() else arg for arg in args] + def create_args(self, *, with_env=False, use_bytes=False): self.exitcode = 17 @@ -3109,115 +3242,118 @@ class SpawnTests(unittest.TestCase): with open(filename, "w", encoding="utf-8") as fp: fp.write(code) - args = [sys.executable, filename] + program = sys.executable + args = self.quote_args([program, filename]) if use_bytes: + program = os.fsencode(program) args = [os.fsencode(a) for a in args] self.env = {os.fsencode(k): os.fsencode(v) for k, v in self.env.items()} - return args + return program, args @requires_os_func('spawnl') def test_spawnl(self): - args = self.create_args() - exitcode = os.spawnl(os.P_WAIT, args[0], *args) + program, args = self.create_args() + exitcode = os.spawnl(os.P_WAIT, program, *args) self.assertEqual(exitcode, self.exitcode) @requires_os_func('spawnle') def test_spawnle(self): - args = self.create_args(with_env=True) - exitcode = os.spawnle(os.P_WAIT, args[0], *args, self.env) + program, args = self.create_args(with_env=True) + exitcode = os.spawnle(os.P_WAIT, program, *args, self.env) self.assertEqual(exitcode, self.exitcode) @requires_os_func('spawnlp') def test_spawnlp(self): - args = self.create_args() - exitcode = os.spawnlp(os.P_WAIT, args[0], *args) + program, args = self.create_args() + exitcode = os.spawnlp(os.P_WAIT, program, *args) self.assertEqual(exitcode, self.exitcode) @requires_os_func('spawnlpe') def test_spawnlpe(self): - args = self.create_args(with_env=True) - exitcode = os.spawnlpe(os.P_WAIT, args[0], *args, self.env) + program, args = self.create_args(with_env=True) + exitcode = os.spawnlpe(os.P_WAIT, program, *args, self.env) self.assertEqual(exitcode, self.exitcode) @requires_os_func('spawnv') def test_spawnv(self): - args = self.create_args() - exitcode = os.spawnv(os.P_WAIT, args[0], args) + program, args = self.create_args() + exitcode = os.spawnv(os.P_WAIT, program, args) self.assertEqual(exitcode, self.exitcode) # Test for PyUnicode_FSConverter() - exitcode = os.spawnv(os.P_WAIT, FakePath(args[0]), args) + exitcode = os.spawnv(os.P_WAIT, FakePath(program), args) self.assertEqual(exitcode, self.exitcode) @requires_os_func('spawnve') def test_spawnve(self): - args = self.create_args(with_env=True) - exitcode = os.spawnve(os.P_WAIT, args[0], args, self.env) + program, args = self.create_args(with_env=True) + exitcode = os.spawnve(os.P_WAIT, program, args, self.env) self.assertEqual(exitcode, self.exitcode) @requires_os_func('spawnvp') def test_spawnvp(self): - args = self.create_args() - exitcode = os.spawnvp(os.P_WAIT, args[0], args) + program, args = self.create_args() + exitcode = os.spawnvp(os.P_WAIT, program, args) self.assertEqual(exitcode, self.exitcode) @requires_os_func('spawnvpe') def test_spawnvpe(self): - args = self.create_args(with_env=True) - exitcode = os.spawnvpe(os.P_WAIT, args[0], args, self.env) + program, args = self.create_args(with_env=True) + exitcode = os.spawnvpe(os.P_WAIT, program, args, self.env) self.assertEqual(exitcode, self.exitcode) @requires_os_func('spawnv') def test_nowait(self): - args = self.create_args() - pid = os.spawnv(os.P_NOWAIT, args[0], args) + program, args = self.create_args() + pid = os.spawnv(os.P_NOWAIT, program, args) support.wait_process(pid, exitcode=self.exitcode) @requires_os_func('spawnve') def test_spawnve_bytes(self): # Test bytes handling in parse_arglist and parse_envlist (#28114) - args = self.create_args(with_env=True, use_bytes=True) - exitcode = os.spawnve(os.P_WAIT, args[0], args, self.env) + program, args = self.create_args(with_env=True, use_bytes=True) + exitcode = os.spawnve(os.P_WAIT, program, args, self.env) self.assertEqual(exitcode, self.exitcode) @requires_os_func('spawnl') def test_spawnl_noargs(self): - args = self.create_args() - self.assertRaises(ValueError, os.spawnl, os.P_NOWAIT, args[0]) - self.assertRaises(ValueError, os.spawnl, os.P_NOWAIT, args[0], '') + program, __ = self.create_args() + self.assertRaises(ValueError, os.spawnl, os.P_NOWAIT, program) + self.assertRaises(ValueError, os.spawnl, os.P_NOWAIT, program, '') @requires_os_func('spawnle') def test_spawnle_noargs(self): - args = self.create_args() - self.assertRaises(ValueError, os.spawnle, os.P_NOWAIT, args[0], {}) - self.assertRaises(ValueError, os.spawnle, os.P_NOWAIT, args[0], '', {}) + program, __ = self.create_args() + self.assertRaises(ValueError, os.spawnle, os.P_NOWAIT, program, {}) + self.assertRaises(ValueError, os.spawnle, os.P_NOWAIT, program, '', {}) @requires_os_func('spawnv') def test_spawnv_noargs(self): - args = self.create_args() - self.assertRaises(ValueError, os.spawnv, os.P_NOWAIT, args[0], ()) - self.assertRaises(ValueError, os.spawnv, os.P_NOWAIT, args[0], []) - self.assertRaises(ValueError, os.spawnv, os.P_NOWAIT, args[0], ('',)) - self.assertRaises(ValueError, os.spawnv, os.P_NOWAIT, args[0], ['']) + program, __ = self.create_args() + self.assertRaises(ValueError, os.spawnv, os.P_NOWAIT, program, ()) + self.assertRaises(ValueError, os.spawnv, os.P_NOWAIT, program, []) + self.assertRaises(ValueError, os.spawnv, os.P_NOWAIT, program, ('',)) + self.assertRaises(ValueError, os.spawnv, os.P_NOWAIT, program, ['']) @requires_os_func('spawnve') def test_spawnve_noargs(self): - args = self.create_args() - self.assertRaises(ValueError, os.spawnve, os.P_NOWAIT, args[0], (), {}) - self.assertRaises(ValueError, os.spawnve, os.P_NOWAIT, args[0], [], {}) - self.assertRaises(ValueError, os.spawnve, os.P_NOWAIT, args[0], ('',), {}) - self.assertRaises(ValueError, os.spawnve, os.P_NOWAIT, args[0], [''], {}) + program, __ = self.create_args() + self.assertRaises(ValueError, os.spawnve, os.P_NOWAIT, program, (), {}) + self.assertRaises(ValueError, os.spawnve, os.P_NOWAIT, program, [], {}) + self.assertRaises(ValueError, os.spawnve, os.P_NOWAIT, program, ('',), {}) + self.assertRaises(ValueError, os.spawnve, os.P_NOWAIT, program, [''], {}) def _test_invalid_env(self, spawn): - args = [sys.executable, '-c', 'pass'] + program = sys.executable + args = self.quote_args([program, '-c', 'pass']) # null character in the environment variable name newenv = os.environ.copy() newenv["FRUIT\0VEGETABLE"] = "cabbage" try: - exitcode = spawn(os.P_WAIT, args[0], args, newenv) + exitcode = spawn(os.P_WAIT, program, args, newenv) except ValueError: pass else: @@ -3227,7 +3363,7 @@ class SpawnTests(unittest.TestCase): newenv = os.environ.copy() newenv["FRUIT"] = "orange\0VEGETABLE=cabbage" try: - exitcode = spawn(os.P_WAIT, args[0], args, newenv) + exitcode = spawn(os.P_WAIT, program, args, newenv) except ValueError: pass else: @@ -3237,7 +3373,7 @@ class SpawnTests(unittest.TestCase): newenv = os.environ.copy() newenv["FRUIT=ORANGE"] = "lemon" try: - exitcode = spawn(os.P_WAIT, args[0], args, newenv) + exitcode = spawn(os.P_WAIT, program, args, newenv) except ValueError: pass else: @@ -3250,10 +3386,11 @@ class SpawnTests(unittest.TestCase): fp.write('import sys, os\n' 'if os.getenv("FRUIT") != "orange=lemon":\n' ' raise AssertionError') - args = [sys.executable, filename] + + args = self.quote_args([program, filename]) newenv = os.environ.copy() newenv["FRUIT"] = "orange=lemon" - exitcode = spawn(os.P_WAIT, args[0], args, newenv) + exitcode = spawn(os.P_WAIT, program, args, newenv) self.assertEqual(exitcode, 0) @requires_os_func('spawnve') @@ -3665,6 +3802,19 @@ class TermsizeTests(unittest.TestCase): raise self.assertEqual(expected, actual) + @unittest.skipUnless(sys.platform == 'win32', 'Windows specific test') + def test_windows_fd(self): + """Check if get_terminal_size() returns a meaningful value in Windows""" + try: + conout = open('conout$', 'w') + except OSError: + self.skipTest('failed to open conout$') + with conout: + size = os.get_terminal_size(conout.fileno()) + + self.assertGreaterEqual(size.columns, 0) + self.assertGreaterEqual(size.lines, 0) + @unittest.skipUnless(hasattr(os, 'memfd_create'), 'requires os.memfd_create') @support.requires_linux_version(3, 17) @@ -3784,8 +3934,6 @@ class OSErrorTests(unittest.TestCase): else: encoded = os.fsencode(os_helper.TESTFN) self.bytes_filenames.append(encoded) - self.bytes_filenames.append(bytearray(encoded)) - self.bytes_filenames.append(memoryview(encoded)) self.filenames = self.bytes_filenames + self.unicode_filenames @@ -3797,21 +3945,10 @@ class OSErrorTests(unittest.TestCase): (self.filenames, os.rmdir,), (self.filenames, os.stat,), (self.filenames, os.unlink,), + (self.filenames, os.listdir,), + (self.filenames, os.rename, "dst"), + (self.filenames, os.replace, "dst"), ] - if sys.platform == "win32": - funcs.extend(( - (self.bytes_filenames, os.rename, b"dst"), - (self.bytes_filenames, os.replace, b"dst"), - (self.unicode_filenames, os.rename, "dst"), - (self.unicode_filenames, os.replace, "dst"), - (self.unicode_filenames, os.listdir, ), - )) - else: - funcs.extend(( - (self.filenames, os.listdir,), - (self.filenames, os.rename, "dst"), - (self.filenames, os.replace, "dst"), - )) if os_helper.can_chmod(): funcs.append((self.filenames, os.chmod, 0o777)) if hasattr(os, "chown"): @@ -3827,11 +3964,7 @@ class OSErrorTests(unittest.TestCase): if hasattr(os, "chroot"): funcs.append((self.filenames, os.chroot,)) if hasattr(os, "link"): - if sys.platform == "win32": - funcs.append((self.bytes_filenames, os.link, b"dst")) - funcs.append((self.unicode_filenames, os.link, "dst")) - else: - funcs.append((self.filenames, os.link, "dst")) + funcs.append((self.filenames, os.link, "dst")) if hasattr(os, "listxattr"): funcs.extend(( (self.filenames, os.listxattr,), @@ -3844,21 +3977,16 @@ class OSErrorTests(unittest.TestCase): if hasattr(os, "readlink"): funcs.append((self.filenames, os.readlink,)) - for filenames, func, *func_args in funcs: for name in filenames: try: - if isinstance(name, (str, bytes)): - func(name, *func_args) - else: - with self.assertWarnsRegex(DeprecationWarning, 'should be'): - func(name, *func_args) + func(name, *func_args) except OSError as err: self.assertIs(err.filename, name, str(func)) except UnicodeDecodeError: pass else: - self.fail("No exception thrown by {}".format(func)) + self.fail(f"No exception thrown by {func}") class CPUCountTests(unittest.TestCase): def test_cpu_count(self): @@ -4062,6 +4190,7 @@ class PathTConverterTests(unittest.TestCase): @unittest.skipUnless(hasattr(os, 'get_blocking'), 'needs os.get_blocking() and os.set_blocking()') @unittest.skipIf(support.is_emscripten, "Cannot unset blocking flag") +@unittest.skipIf(sys.platform == 'win32', 'Windows only supports blocking on pipes') class BlockingTests(unittest.TestCase): def test_blocking(self): fd = os.open(__file__, os.O_RDONLY) @@ -4126,7 +4255,8 @@ class TestScandir(unittest.TestCase): for attr in dir(stat1): if not attr.startswith("st_"): continue - if attr in ("st_dev", "st_ino", "st_nlink"): + if attr in ("st_dev", "st_ino", "st_nlink", "st_ctime", + "st_ctime_ns"): continue self.assertEqual(getattr(stat1, attr), getattr(stat2, attr), @@ -4167,6 +4297,8 @@ class TestScandir(unittest.TestCase): self.assertEqual(entry.is_file(follow_symlinks=False), stat.S_ISREG(entry_lstat.st_mode)) + self.assertEqual(entry.is_junction(), os.path.isjunction(entry.path)) + self.assert_stat_equal(entry.stat(), entry_stat, os.name == 'nt' and not is_symlink) @@ -4215,6 +4347,21 @@ class TestScandir(unittest.TestCase): entry = entries['symlink_file.txt'] self.check_entry(entry, 'symlink_file.txt', False, True, True) + @unittest.skipIf(sys.platform != 'win32', "Can only test junctions with creation on win32.") + def test_attributes_junctions(self): + dirname = os.path.join(self.path, "tgtdir") + os.mkdir(dirname) + + import _winapi + try: + _winapi.CreateJunction(dirname, os.path.join(self.path, "srcjunc")) + except OSError: + raise unittest.SkipTest('creating the test junction failed') + + entries = self.get_entries(['srcjunc', 'tgtdir']) + self.assertEqual(entries['srcjunc'].is_junction(), True) + self.assertEqual(entries['tgtdir'].is_junction(), False) + def get_entry(self, name): path = self.bytes_path if isinstance(name, bytes) else self.path entries = list(os.scandir(path)) @@ -4337,16 +4484,8 @@ class TestScandir(unittest.TestCase): for cls in bytearray, memoryview: path_bytes = cls(os.fsencode(self.path)) - with self.assertWarns(DeprecationWarning): - entries = list(os.scandir(path_bytes)) - self.assertEqual(len(entries), 1, entries) - entry = entries[0] - - self.assertEqual(entry.name, b'file.txt') - self.assertEqual(entry.path, - os.fsencode(os.path.join(self.path, 'file.txt'))) - self.assertIs(type(entry.name), bytes) - self.assertIs(type(entry.path), bytes) + with self.assertRaises(TypeError): + os.scandir(path_bytes) @unittest.skipUnless(os.listdir in os.supports_fd, 'fd support for listdir required for this test.') @@ -4533,6 +4672,50 @@ class ForkTests(unittest.TestCase): assert_python_ok("-c", code) assert_python_ok("-c", code, PYTHONMALLOC="malloc_debug") + @unittest.skipUnless(sys.platform in ("linux", "darwin"), + "Only Linux and macOS detect this today.") + def test_fork_warns_when_non_python_thread_exists(self): + code = """if 1: + import os, threading, warnings + from _testcapi import _spawn_pthread_waiter, _end_spawned_pthread + _spawn_pthread_waiter() + try: + with warnings.catch_warnings(record=True) as ws: + warnings.filterwarnings( + "always", category=DeprecationWarning) + if os.fork() == 0: + assert not ws, f"unexpected warnings in child: {ws}" + os._exit(0) # child + else: + assert ws[0].category == DeprecationWarning, ws[0] + assert 'fork' in str(ws[0].message), ws[0] + # Waiting allows an error in the child to hit stderr. + exitcode = os.wait()[1] + assert exitcode == 0, f"child exited {exitcode}" + assert threading.active_count() == 1, threading.enumerate() + finally: + _end_spawned_pthread() + """ + _, out, err = assert_python_ok("-c", code, PYTHONOPTIMIZE='0') + self.assertEqual(err.decode("utf-8"), "") + self.assertEqual(out.decode("utf-8"), "") + + def test_fork_at_exit(self): + code = """if 1: + import atexit + import os + + def exit_handler(): + pid = os.fork() + if pid != 0: + print("shouldn't be printed") + + atexit.register(exit_handler) + """ + _, out, err = assert_python_ok("-c", code) + self.assertEqual(b"", out) + self.assertIn(b"can't fork at interpreter shutdown", err) + # Only test if the C version is provided, otherwise TestPEP519 already tested # the pure Python implementation. diff --git a/Lib/test/test_pathlib.py b/Lib/test/test_pathlib.py index 3b88c084..012dacf1 100644 --- a/Lib/test/test_pathlib.py +++ b/Lib/test/test_pathlib.py @@ -13,6 +13,7 @@ import unittest from unittest import mock from test.support import import_helper +from test.support import set_recursion_limit from test.support import is_emscripten, is_wasi from test.support import os_helper from test.support.os_helper import TESTFN, FakePath @@ -23,149 +24,19 @@ except ImportError: grp = pwd = None -class _BaseFlavourTest(object): - - def _check_parse_parts(self, arg, expected): - f = self.flavour.parse_parts - sep = self.flavour.sep - altsep = self.flavour.altsep - actual = f([x.replace('/', sep) for x in arg]) - self.assertEqual(actual, expected) - if altsep: - actual = f([x.replace('/', altsep) for x in arg]) - self.assertEqual(actual, expected) - - def test_parse_parts_common(self): - check = self._check_parse_parts - sep = self.flavour.sep - # Unanchored parts. - check([], ('', '', [])) - check(['a'], ('', '', ['a'])) - check(['a/'], ('', '', ['a'])) - check(['a', 'b'], ('', '', ['a', 'b'])) - # Expansion. - check(['a/b'], ('', '', ['a', 'b'])) - check(['a/b/'], ('', '', ['a', 'b'])) - check(['a', 'b/c', 'd'], ('', '', ['a', 'b', 'c', 'd'])) - # Collapsing and stripping excess slashes. - check(['a', 'b//c', 'd'], ('', '', ['a', 'b', 'c', 'd'])) - check(['a', 'b/c/', 'd'], ('', '', ['a', 'b', 'c', 'd'])) - # Eliminating standalone dots. - check(['.'], ('', '', [])) - check(['.', '.', 'b'], ('', '', ['b'])) - check(['a', '.', 'b'], ('', '', ['a', 'b'])) - check(['a', '.', '.'], ('', '', ['a'])) - # The first part is anchored. - check(['/a/b'], ('', sep, [sep, 'a', 'b'])) - check(['/a', 'b'], ('', sep, [sep, 'a', 'b'])) - check(['/a/', 'b'], ('', sep, [sep, 'a', 'b'])) - # Ignoring parts before an anchored part. - check(['a', '/b', 'c'], ('', sep, [sep, 'b', 'c'])) - check(['a', '/b', '/c'], ('', sep, [sep, 'c'])) - - -class PosixFlavourTest(_BaseFlavourTest, unittest.TestCase): - flavour = pathlib._posix_flavour - - def test_parse_parts(self): - check = self._check_parse_parts - # Collapsing of excess leading slashes, except for the double-slash - # special case. - check(['//a', 'b'], ('', '//', ['//', 'a', 'b'])) - check(['///a', 'b'], ('', '/', ['/', 'a', 'b'])) - check(['////a', 'b'], ('', '/', ['/', 'a', 'b'])) - # Paths which look like NT paths aren't treated specially. - check(['c:a'], ('', '', ['c:a'])) - check(['c:\\a'], ('', '', ['c:\\a'])) - check(['\\a'], ('', '', ['\\a'])) - - def test_splitroot(self): - f = self.flavour.splitroot - self.assertEqual(f(''), ('', '', '')) - self.assertEqual(f('a'), ('', '', 'a')) - self.assertEqual(f('a/b'), ('', '', 'a/b')) - self.assertEqual(f('a/b/'), ('', '', 'a/b/')) - self.assertEqual(f('/a'), ('', '/', 'a')) - self.assertEqual(f('/a/b'), ('', '/', 'a/b')) - self.assertEqual(f('/a/b/'), ('', '/', 'a/b/')) - # The root is collapsed when there are redundant slashes - # except when there are exactly two leading slashes, which - # is a special case in POSIX. - self.assertEqual(f('//a'), ('', '//', 'a')) - self.assertEqual(f('///a'), ('', '/', 'a')) - self.assertEqual(f('///a/b'), ('', '/', 'a/b')) - # Paths which look like NT paths aren't treated specially. - self.assertEqual(f('c:/a/b'), ('', '', 'c:/a/b')) - self.assertEqual(f('\\/a/b'), ('', '', '\\/a/b')) - self.assertEqual(f('\\a\\b'), ('', '', '\\a\\b')) - - -class NTFlavourTest(_BaseFlavourTest, unittest.TestCase): - flavour = pathlib._windows_flavour - - def test_parse_parts(self): - check = self._check_parse_parts - # First part is anchored. - check(['c:'], ('c:', '', ['c:'])) - check(['c:/'], ('c:', '\\', ['c:\\'])) - check(['/'], ('', '\\', ['\\'])) - check(['c:a'], ('c:', '', ['c:', 'a'])) - check(['c:/a'], ('c:', '\\', ['c:\\', 'a'])) - check(['/a'], ('', '\\', ['\\', 'a'])) - # UNC paths. - check(['//a/b'], ('\\\\a\\b', '\\', ['\\\\a\\b\\'])) - check(['//a/b/'], ('\\\\a\\b', '\\', ['\\\\a\\b\\'])) - check(['//a/b/c'], ('\\\\a\\b', '\\', ['\\\\a\\b\\', 'c'])) - # Second part is anchored, so that the first part is ignored. - check(['a', 'Z:b', 'c'], ('Z:', '', ['Z:', 'b', 'c'])) - check(['a', 'Z:/b', 'c'], ('Z:', '\\', ['Z:\\', 'b', 'c'])) - # UNC paths. - check(['a', '//b/c', 'd'], ('\\\\b\\c', '\\', ['\\\\b\\c\\', 'd'])) - # Collapsing and stripping excess slashes. - check(['a', 'Z://b//c/', 'd/'], ('Z:', '\\', ['Z:\\', 'b', 'c', 'd'])) - # UNC paths. - check(['a', '//b/c//', 'd'], ('\\\\b\\c', '\\', ['\\\\b\\c\\', 'd'])) - # Extended paths. - check(['//?/c:/'], ('\\\\?\\c:', '\\', ['\\\\?\\c:\\'])) - check(['//?/c:/a'], ('\\\\?\\c:', '\\', ['\\\\?\\c:\\', 'a'])) - check(['//?/c:/a', '/b'], ('\\\\?\\c:', '\\', ['\\\\?\\c:\\', 'b'])) - # Extended UNC paths (format is "\\?\UNC\server\share"). - check(['//?/UNC/b/c'], ('\\\\?\\UNC\\b\\c', '\\', ['\\\\?\\UNC\\b\\c\\'])) - check(['//?/UNC/b/c/d'], ('\\\\?\\UNC\\b\\c', '\\', ['\\\\?\\UNC\\b\\c\\', 'd'])) - # Second part has a root but not drive. - check(['a', '/b', 'c'], ('', '\\', ['\\', 'b', 'c'])) - check(['Z:/a', '/b', 'c'], ('Z:', '\\', ['Z:\\', 'b', 'c'])) - check(['//?/Z:/a', '/b', 'c'], ('\\\\?\\Z:', '\\', ['\\\\?\\Z:\\', 'b', 'c'])) - - def test_splitroot(self): - f = self.flavour.splitroot - self.assertEqual(f(''), ('', '', '')) - self.assertEqual(f('a'), ('', '', 'a')) - self.assertEqual(f('a\\b'), ('', '', 'a\\b')) - self.assertEqual(f('\\a'), ('', '\\', 'a')) - self.assertEqual(f('\\a\\b'), ('', '\\', 'a\\b')) - self.assertEqual(f('c:a\\b'), ('c:', '', 'a\\b')) - self.assertEqual(f('c:\\a\\b'), ('c:', '\\', 'a\\b')) - # Redundant slashes in the root are collapsed. - self.assertEqual(f('\\\\a'), ('', '\\', 'a')) - self.assertEqual(f('\\\\\\a/b'), ('', '\\', 'a/b')) - self.assertEqual(f('c:\\\\a'), ('c:', '\\', 'a')) - self.assertEqual(f('c:\\\\\\a/b'), ('c:', '\\', 'a/b')) - # Valid UNC paths. - self.assertEqual(f('\\\\a\\b'), ('\\\\a\\b', '\\', '')) - self.assertEqual(f('\\\\a\\b\\'), ('\\\\a\\b', '\\', '')) - self.assertEqual(f('\\\\a\\b\\c\\d'), ('\\\\a\\b', '\\', 'c\\d')) - # These are non-UNC paths (according to ntpath.py and test_ntpath). - # However, command.com says such paths are invalid, so it's - # difficult to know what the right semantics are. - self.assertEqual(f('\\\\\\a\\b'), ('', '\\', 'a\\b')) - self.assertEqual(f('\\\\a'), ('', '\\', 'a')) - - # # Tests for the pure classes. # +class _BasePurePathSubclass(object): + def __init__(self, *pathsegments, session_id): + super().__init__(*pathsegments) + self.session_id = session_id + + def with_segments(self, *pathsegments): + return type(self)(*pathsegments, session_id=self.session_id) + + class _BasePurePathTest(object): # Keys are canonical paths, values are list of tuples of arguments @@ -178,8 +49,7 @@ class _BasePurePathTest(object): ('', 'a', 'b'), ('a', '', 'b'), ('a', 'b', ''), ], '/b/c/d': [ - ('a', '/b/c', 'd'), ('a', '///b//c', 'd/'), - ('/a', '/b/c', 'd'), + ('a', '/b/c', 'd'), ('/a', '/b/c', 'd'), # Empty components get removed. ('/', 'b', '', 'c/d'), ('/', '', 'b/c/d'), ('', '/b/c/d'), ], @@ -204,6 +74,34 @@ class _BasePurePathTest(object): self.assertEqual(P(P('a'), 'b'), P('a/b')) self.assertEqual(P(P('a'), P('b')), P('a/b')) self.assertEqual(P(P('a'), P('b'), P('c')), P(FakePath("a/b/c"))) + self.assertEqual(P(P('./a:b')), P('./a:b')) + + def test_bytes(self): + P = self.cls + message = (r"argument should be a str or an os\.PathLike object " + r"where __fspath__ returns a str, not 'bytes'") + with self.assertRaisesRegex(TypeError, message): + P(b'a') + with self.assertRaisesRegex(TypeError, message): + P(b'a', 'b') + with self.assertRaisesRegex(TypeError, message): + P('a', b'b') + with self.assertRaises(TypeError): + P('a').joinpath(b'b') + with self.assertRaises(TypeError): + P('a') / b'b' + with self.assertRaises(TypeError): + b'a' / P('b') + with self.assertRaises(TypeError): + P('a').match(b'b') + with self.assertRaises(TypeError): + P('a').relative_to(b'b') + with self.assertRaises(TypeError): + P('a').with_name(b'b') + with self.assertRaises(TypeError): + P('a').with_stem(b'b') + with self.assertRaises(TypeError): + P('a').with_suffix(b'b') def _check_str_subclass(self, *args): # Issue #21127: it should be possible to construct a PurePath object @@ -224,6 +122,62 @@ class _BasePurePathTest(object): self._check_str_subclass('a/b.txt') self._check_str_subclass('/a/b.txt') + def test_with_segments_common(self): + class P(_BasePurePathSubclass, self.cls): + pass + p = P('foo', 'bar', session_id=42) + self.assertEqual(42, (p / 'foo').session_id) + self.assertEqual(42, ('foo' / p).session_id) + self.assertEqual(42, p.joinpath('foo').session_id) + self.assertEqual(42, p.with_name('foo').session_id) + self.assertEqual(42, p.with_stem('foo').session_id) + self.assertEqual(42, p.with_suffix('.foo').session_id) + self.assertEqual(42, p.with_segments('foo').session_id) + self.assertEqual(42, p.relative_to('foo').session_id) + self.assertEqual(42, p.parent.session_id) + for parent in p.parents: + self.assertEqual(42, parent.session_id) + + def _get_drive_root_parts(self, parts): + path = self.cls(*parts) + return path.drive, path.root, path.parts + + def _check_drive_root_parts(self, arg, *expected): + sep = self.flavour.sep + actual = self._get_drive_root_parts([x.replace('/', sep) for x in arg]) + self.assertEqual(actual, expected) + if altsep := self.flavour.altsep: + actual = self._get_drive_root_parts([x.replace('/', altsep) for x in arg]) + self.assertEqual(actual, expected) + + def test_drive_root_parts_common(self): + check = self._check_drive_root_parts + sep = self.flavour.sep + # Unanchored parts. + check((), '', '', ()) + check(('a',), '', '', ('a',)) + check(('a/',), '', '', ('a',)) + check(('a', 'b'), '', '', ('a', 'b')) + # Expansion. + check(('a/b',), '', '', ('a', 'b')) + check(('a/b/',), '', '', ('a', 'b')) + check(('a', 'b/c', 'd'), '', '', ('a', 'b', 'c', 'd')) + # Collapsing and stripping excess slashes. + check(('a', 'b//c', 'd'), '', '', ('a', 'b', 'c', 'd')) + check(('a', 'b/c/', 'd'), '', '', ('a', 'b', 'c', 'd')) + # Eliminating standalone dots. + check(('.',), '', '', ()) + check(('.', '.', 'b'), '', '', ('b',)) + check(('a', '.', 'b'), '', '', ('a', 'b')) + check(('a', '.', '.'), '', '', ('a',)) + # The first part is anchored. + check(('/a/b',), '', sep, (sep, 'a', 'b')) + check(('/a', 'b'), '', sep, (sep, 'a', 'b')) + check(('/a/', 'b'), '', sep, (sep, 'a', 'b')) + # Ignoring parts before an anchored part. + check(('a', '/b', 'c'), '', sep, (sep, 'b', 'c')) + check(('a', '/b', '/c'), '', sep, (sep, 'c')) + def test_join_common(self): P = self.cls p = P('a/b') @@ -287,19 +241,26 @@ class _BasePurePathTest(object): def test_repr_common(self): for pathstr in ('a', 'a/b', 'a/b/c', '/', '/a/b', '/a/b/c'): - p = self.cls(pathstr) - clsname = p.__class__.__name__ - r = repr(p) - # The repr() is in the form ClassName("forward-slashes path"). - self.assertTrue(r.startswith(clsname + '('), r) - self.assertTrue(r.endswith(')'), r) - inner = r[len(clsname) + 1 : -1] - self.assertEqual(eval(inner), p.as_posix()) - # The repr() roundtrips. - q = eval(r, pathlib.__dict__) - self.assertIs(q.__class__, p.__class__) - self.assertEqual(q, p) - self.assertEqual(repr(q), r) + with self.subTest(pathstr=pathstr): + p = self.cls(pathstr) + clsname = p.__class__.__name__ + r = repr(p) + # The repr() is in the form ClassName("forward-slashes path"). + self.assertTrue(r.startswith(clsname + '('), r) + self.assertTrue(r.endswith(')'), r) + inner = r[len(clsname) + 1 : -1] + self.assertEqual(eval(inner), p.as_posix()) + + def test_repr_roundtrips(self): + for pathstr in ('a', 'a/b', 'a/b/c', '/', '/a/b', '/a/b/c'): + with self.subTest(pathstr=pathstr): + p = self.cls(pathstr) + r = repr(p) + # The repr() roundtrips. + q = eval(r, pathlib.__dict__) + self.assertIs(q.__class__, p.__class__) + self.assertEqual(q, p) + self.assertEqual(repr(q), r) def test_eq_common(self): P = self.cls @@ -351,6 +312,15 @@ class _BasePurePathTest(object): # Multi-part glob-style pattern. self.assertFalse(P('/a/b/c.py').match('/**/*.py')) self.assertTrue(P('/a/b/c.py').match('/a/**/*.py')) + # Case-sensitive flag + self.assertFalse(P('A.py').match('a.PY', case_sensitive=True)) + self.assertTrue(P('A.py').match('a.PY', case_sensitive=False)) + self.assertFalse(P('c:/a/B.Py').match('C:/A/*.pY', case_sensitive=True)) + self.assertTrue(P('/a/b/c.py').match('/A/*/*.Py', case_sensitive=False)) + # Matching against empty path + self.assertFalse(P().match('*')) + self.assertTrue(P().match('**')) + self.assertFalse(P().match('**/*')) def test_ordering_common(self): # Ordering is tuple-alike. @@ -387,8 +357,6 @@ class _BasePurePathTest(object): p = P('a/b') parts = p.parts self.assertEqual(parts, ('a', 'b')) - # The object gets reused. - self.assertIs(parts, p.parts) # When the path is absolute, the anchor is a separate part. p = P('/a/b') parts = p.parts @@ -636,13 +604,36 @@ class _BasePurePathTest(object): self.assertEqual(p.relative_to('a/'), P('b')) self.assertEqual(p.relative_to(P('a/b')), P()) self.assertEqual(p.relative_to('a/b'), P()) + self.assertEqual(p.relative_to(P(), walk_up=True), P('a/b')) + self.assertEqual(p.relative_to('', walk_up=True), P('a/b')) + self.assertEqual(p.relative_to(P('a'), walk_up=True), P('b')) + self.assertEqual(p.relative_to('a', walk_up=True), P('b')) + self.assertEqual(p.relative_to('a/', walk_up=True), P('b')) + self.assertEqual(p.relative_to(P('a/b'), walk_up=True), P()) + self.assertEqual(p.relative_to('a/b', walk_up=True), P()) + self.assertEqual(p.relative_to(P('a/c'), walk_up=True), P('../b')) + self.assertEqual(p.relative_to('a/c', walk_up=True), P('../b')) + self.assertEqual(p.relative_to(P('a/b/c'), walk_up=True), P('..')) + self.assertEqual(p.relative_to('a/b/c', walk_up=True), P('..')) + self.assertEqual(p.relative_to(P('c'), walk_up=True), P('../a/b')) + self.assertEqual(p.relative_to('c', walk_up=True), P('../a/b')) # With several args. - self.assertEqual(p.relative_to('a', 'b'), P()) + with self.assertWarns(DeprecationWarning): + p.relative_to('a', 'b') + p.relative_to('a', 'b', walk_up=True) # Unrelated paths. self.assertRaises(ValueError, p.relative_to, P('c')) self.assertRaises(ValueError, p.relative_to, P('a/b/c')) self.assertRaises(ValueError, p.relative_to, P('a/c')) self.assertRaises(ValueError, p.relative_to, P('/a')) + self.assertRaises(ValueError, p.relative_to, P("../a")) + self.assertRaises(ValueError, p.relative_to, P("a/..")) + self.assertRaises(ValueError, p.relative_to, P("/a/..")) + self.assertRaises(ValueError, p.relative_to, P('/'), walk_up=True) + self.assertRaises(ValueError, p.relative_to, P('/a'), walk_up=True) + self.assertRaises(ValueError, p.relative_to, P("../a"), walk_up=True) + self.assertRaises(ValueError, p.relative_to, P("a/.."), walk_up=True) + self.assertRaises(ValueError, p.relative_to, P("/a/.."), walk_up=True) p = P('/a/b') self.assertEqual(p.relative_to(P('/')), P('a/b')) self.assertEqual(p.relative_to('/'), P('a/b')) @@ -651,6 +642,19 @@ class _BasePurePathTest(object): self.assertEqual(p.relative_to('/a/'), P('b')) self.assertEqual(p.relative_to(P('/a/b')), P()) self.assertEqual(p.relative_to('/a/b'), P()) + self.assertEqual(p.relative_to(P('/'), walk_up=True), P('a/b')) + self.assertEqual(p.relative_to('/', walk_up=True), P('a/b')) + self.assertEqual(p.relative_to(P('/a'), walk_up=True), P('b')) + self.assertEqual(p.relative_to('/a', walk_up=True), P('b')) + self.assertEqual(p.relative_to('/a/', walk_up=True), P('b')) + self.assertEqual(p.relative_to(P('/a/b'), walk_up=True), P()) + self.assertEqual(p.relative_to('/a/b', walk_up=True), P()) + self.assertEqual(p.relative_to(P('/a/c'), walk_up=True), P('../b')) + self.assertEqual(p.relative_to('/a/c', walk_up=True), P('../b')) + self.assertEqual(p.relative_to(P('/a/b/c'), walk_up=True), P('..')) + self.assertEqual(p.relative_to('/a/b/c', walk_up=True), P('..')) + self.assertEqual(p.relative_to(P('/c'), walk_up=True), P('../a/b')) + self.assertEqual(p.relative_to('/c', walk_up=True), P('../a/b')) # Unrelated paths. self.assertRaises(ValueError, p.relative_to, P('/c')) self.assertRaises(ValueError, p.relative_to, P('/a/b/c')) @@ -658,6 +662,14 @@ class _BasePurePathTest(object): self.assertRaises(ValueError, p.relative_to, P()) self.assertRaises(ValueError, p.relative_to, '') self.assertRaises(ValueError, p.relative_to, P('a')) + self.assertRaises(ValueError, p.relative_to, P("../a")) + self.assertRaises(ValueError, p.relative_to, P("a/..")) + self.assertRaises(ValueError, p.relative_to, P("/a/..")) + self.assertRaises(ValueError, p.relative_to, P(''), walk_up=True) + self.assertRaises(ValueError, p.relative_to, P('a'), walk_up=True) + self.assertRaises(ValueError, p.relative_to, P("../a"), walk_up=True) + self.assertRaises(ValueError, p.relative_to, P("a/.."), walk_up=True) + self.assertRaises(ValueError, p.relative_to, P("/a/.."), walk_up=True) def test_is_relative_to_common(self): P = self.cls @@ -671,7 +683,8 @@ class _BasePurePathTest(object): self.assertTrue(p.is_relative_to(P('a/b'))) self.assertTrue(p.is_relative_to('a/b')) # With several args. - self.assertTrue(p.is_relative_to('a', 'b')) + with self.assertWarns(DeprecationWarning): + p.is_relative_to('a', 'b') # Unrelated paths. self.assertFalse(p.is_relative_to(P('c'))) self.assertFalse(p.is_relative_to(P('a/b/c'))) @@ -708,6 +721,18 @@ class _BasePurePathTest(object): class PurePosixPathTest(_BasePurePathTest, unittest.TestCase): cls = pathlib.PurePosixPath + def test_drive_root_parts(self): + check = self._check_drive_root_parts + # Collapsing of excess leading slashes, except for the double-slash + # special case. + check(('//a', 'b'), '', '//', ('//', 'a', 'b')) + check(('///a', 'b'), '', '/', ('/', 'a', 'b')) + check(('////a', 'b'), '', '/', ('/', 'a', 'b')) + # Paths which look like NT paths aren't treated specially. + check(('c:a',), '', '', ('c:a',)) + check(('c:\\a',), '', '', ('c:\\a',)) + check(('\\a',), '', '', ('\\a',)) + def test_root(self): P = self.cls self.assertEqual(P('/a/b').root, '/') @@ -780,13 +805,20 @@ class PurePosixPathTest(_BasePurePathTest, unittest.TestCase): pp = P('//a') / '/c' self.assertEqual(pp, P('/c')) + def test_parse_windows_path(self): + P = self.cls + p = P('c:', 'a', 'b') + pp = P(pathlib.PureWindowsPath('c:\\a\\b')) + self.assertEqual(p, pp) + class PureWindowsPathTest(_BasePurePathTest, unittest.TestCase): cls = pathlib.PureWindowsPath equivalences = _BasePurePathTest.equivalences.copy() equivalences.update({ - 'c:a': [ ('c:', 'a'), ('c:', 'a/'), ('/', 'c:', 'a') ], + './a:b': [ ('./a:b',) ], + 'c:a': [ ('c:', 'a'), ('c:', 'a/'), ('.', 'c:', 'a') ], 'c:/a': [ ('c:/', 'a'), ('c:', '/', 'a'), ('c:', '/a'), ('/z', 'c:/', 'a'), ('//x/y', 'c:/', 'a'), @@ -797,6 +829,68 @@ class PureWindowsPathTest(_BasePurePathTest, unittest.TestCase): ], }) + def test_drive_root_parts(self): + check = self._check_drive_root_parts + # First part is anchored. + check(('c:',), 'c:', '', ('c:',)) + check(('c:/',), 'c:', '\\', ('c:\\',)) + check(('/',), '', '\\', ('\\',)) + check(('c:a',), 'c:', '', ('c:', 'a')) + check(('c:/a',), 'c:', '\\', ('c:\\', 'a')) + check(('/a',), '', '\\', ('\\', 'a')) + # UNC paths. + check(('//',), '\\\\', '', ('\\\\',)) + check(('//a',), '\\\\a', '', ('\\\\a',)) + check(('//a/',), '\\\\a\\', '', ('\\\\a\\',)) + check(('//a/b',), '\\\\a\\b', '\\', ('\\\\a\\b\\',)) + check(('//a/b/',), '\\\\a\\b', '\\', ('\\\\a\\b\\',)) + check(('//a/b/c',), '\\\\a\\b', '\\', ('\\\\a\\b\\', 'c')) + # Second part is anchored, so that the first part is ignored. + check(('a', 'Z:b', 'c'), 'Z:', '', ('Z:', 'b', 'c')) + check(('a', 'Z:/b', 'c'), 'Z:', '\\', ('Z:\\', 'b', 'c')) + # UNC paths. + check(('a', '//b/c', 'd'), '\\\\b\\c', '\\', ('\\\\b\\c\\', 'd')) + # Collapsing and stripping excess slashes. + check(('a', 'Z://b//c/', 'd/'), 'Z:', '\\', ('Z:\\', 'b', 'c', 'd')) + # UNC paths. + check(('a', '//b/c//', 'd'), '\\\\b\\c', '\\', ('\\\\b\\c\\', 'd')) + # Extended paths. + check(('//./c:',), '\\\\.\\c:', '', ('\\\\.\\c:',)) + check(('//?/c:/',), '\\\\?\\c:', '\\', ('\\\\?\\c:\\',)) + check(('//?/c:/a',), '\\\\?\\c:', '\\', ('\\\\?\\c:\\', 'a')) + check(('//?/c:/a', '/b'), '\\\\?\\c:', '\\', ('\\\\?\\c:\\', 'b')) + # Extended UNC paths (format is "\\?\UNC\server\share"). + check(('//?',), '\\\\?', '', ('\\\\?',)) + check(('//?/',), '\\\\?\\', '', ('\\\\?\\',)) + check(('//?/UNC',), '\\\\?\\UNC', '', ('\\\\?\\UNC',)) + check(('//?/UNC/',), '\\\\?\\UNC\\', '', ('\\\\?\\UNC\\',)) + check(('//?/UNC/b',), '\\\\?\\UNC\\b', '', ('\\\\?\\UNC\\b',)) + check(('//?/UNC/b/',), '\\\\?\\UNC\\b\\', '', ('\\\\?\\UNC\\b\\',)) + check(('//?/UNC/b/c',), '\\\\?\\UNC\\b\\c', '\\', ('\\\\?\\UNC\\b\\c\\',)) + check(('//?/UNC/b/c/',), '\\\\?\\UNC\\b\\c', '\\', ('\\\\?\\UNC\\b\\c\\',)) + check(('//?/UNC/b/c/d',), '\\\\?\\UNC\\b\\c', '\\', ('\\\\?\\UNC\\b\\c\\', 'd')) + # UNC device paths + check(('//./BootPartition/',), '\\\\.\\BootPartition', '\\', ('\\\\.\\BootPartition\\',)) + check(('//?/BootPartition/',), '\\\\?\\BootPartition', '\\', ('\\\\?\\BootPartition\\',)) + check(('//./PhysicalDrive0',), '\\\\.\\PhysicalDrive0', '', ('\\\\.\\PhysicalDrive0',)) + check(('//?/Volume{}/',), '\\\\?\\Volume{}', '\\', ('\\\\?\\Volume{}\\',)) + check(('//./nul',), '\\\\.\\nul', '', ('\\\\.\\nul',)) + # Second part has a root but not drive. + check(('a', '/b', 'c'), '', '\\', ('\\', 'b', 'c')) + check(('Z:/a', '/b', 'c'), 'Z:', '\\', ('Z:\\', 'b', 'c')) + check(('//?/Z:/a', '/b', 'c'), '\\\\?\\Z:', '\\', ('\\\\?\\Z:\\', 'b', 'c')) + # Joining with the same drive => the first path is appended to if + # the second path is relative. + check(('c:/a/b', 'c:x/y'), 'c:', '\\', ('c:\\', 'a', 'b', 'x', 'y')) + check(('c:/a/b', 'c:/x/y'), 'c:', '\\', ('c:\\', 'x', 'y')) + # Paths to files with NTFS alternate data streams + check(('./c:s',), '', '', ('c:s',)) + check(('cc:s',), '', '', ('cc:s',)) + check(('C:c:s',), 'C:', '', ('C:', 'c:s')) + check(('C:/c:s',), 'C:', '\\', ('C:\\', 'c:s')) + check(('D:a', './c:b'), 'D:', '', ('D:', 'a', 'c:b')) + check(('D:/a', './c:b'), 'D:', '\\', ('D:\\', 'a', 'c:b')) + def test_str(self): p = self.cls('a/b/c') self.assertEqual(str(p), 'a\\b\\c') @@ -810,6 +904,7 @@ class PureWindowsPathTest(_BasePurePathTest, unittest.TestCase): self.assertEqual(str(p), '\\\\a\\b\\c\\d') def test_str_subclass(self): + self._check_str_subclass('.\\a:b') self._check_str_subclass('c:') self._check_str_subclass('c:a') self._check_str_subclass('c:a\\b.txt') @@ -831,6 +926,7 @@ class PureWindowsPathTest(_BasePurePathTest, unittest.TestCase): self.assertEqual(P('a/B'), P('A/b')) self.assertEqual(P('C:a/B'), P('c:A/b')) self.assertEqual(P('//Some/SHARE/a/B'), P('//somE/share/A/b')) + self.assertEqual(P('\u0130'), P('i\u0307')) def test_as_uri(self): P = self.cls @@ -848,11 +944,10 @@ class PureWindowsPathTest(_BasePurePathTest, unittest.TestCase): self.assertEqual(P('//some/share/a/b%#c\xe9').as_uri(), 'file://some/share/a/b%25%23c%C3%A9') - def test_match_common(self): + def test_match(self): P = self.cls # Absolute patterns. - self.assertTrue(P('c:/b.py').match('/*.py')) - self.assertTrue(P('c:/b.py').match('c:*.py')) + self.assertTrue(P('c:/b.py').match('*:/*.py')) self.assertTrue(P('c:/b.py').match('c:/*.py')) self.assertFalse(P('d:/b.py').match('c:/*.py')) # wrong drive self.assertFalse(P('b.py').match('/*.py')) @@ -863,7 +958,7 @@ class PureWindowsPathTest(_BasePurePathTest, unittest.TestCase): self.assertFalse(P('/b.py').match('c:*.py')) self.assertFalse(P('/b.py').match('c:/*.py')) # UNC patterns. - self.assertTrue(P('//some/share/a.py').match('/*.py')) + self.assertTrue(P('//some/share/a.py').match('//*/*/*.py')) self.assertTrue(P('//some/share/a.py').match('//some/share/*.py')) self.assertFalse(P('//other/share/a.py').match('//some/share/*.py')) self.assertFalse(P('//some/share/a/b.py').match('//some/share/*.py')) @@ -871,6 +966,10 @@ class PureWindowsPathTest(_BasePurePathTest, unittest.TestCase): self.assertTrue(P('B.py').match('b.PY')) self.assertTrue(P('c:/a/B.Py').match('C:/A/*.pY')) self.assertTrue(P('//Some/Share/B.Py').match('//somE/sharE/*.pY')) + # Path anchor doesn't match pattern anchor + self.assertFalse(P('c:/b.py').match('/*.py')) # 'c:/' vs '/' + self.assertFalse(P('c:/b.py').match('c:*.py')) # 'c:/' vs 'c:' + self.assertFalse(P('//some/share/a.py').match('/*.py')) # '//some/share/' vs '/' def test_ordering_common(self): # Case-insensitivity. @@ -974,6 +1073,7 @@ class PureWindowsPathTest(_BasePurePathTest, unittest.TestCase): self.assertEqual(P('//a/b').drive, '\\\\a\\b') self.assertEqual(P('//a/b/').drive, '\\\\a\\b') self.assertEqual(P('//a/b/c/d').drive, '\\\\a\\b') + self.assertEqual(P('./c:a').drive, '') def test_root(self): P = self.cls @@ -1120,6 +1220,16 @@ class PureWindowsPathTest(_BasePurePathTest, unittest.TestCase): self.assertEqual(p.relative_to('c:foO/'), P('Bar')) self.assertEqual(p.relative_to(P('c:foO/baR')), P()) self.assertEqual(p.relative_to('c:foO/baR'), P()) + self.assertEqual(p.relative_to(P('c:'), walk_up=True), P('Foo/Bar')) + self.assertEqual(p.relative_to('c:', walk_up=True), P('Foo/Bar')) + self.assertEqual(p.relative_to(P('c:foO'), walk_up=True), P('Bar')) + self.assertEqual(p.relative_to('c:foO', walk_up=True), P('Bar')) + self.assertEqual(p.relative_to('c:foO/', walk_up=True), P('Bar')) + self.assertEqual(p.relative_to(P('c:foO/baR'), walk_up=True), P()) + self.assertEqual(p.relative_to('c:foO/baR', walk_up=True), P()) + self.assertEqual(p.relative_to(P('C:Foo/Bar/Baz'), walk_up=True), P('..')) + self.assertEqual(p.relative_to(P('C:Foo/Baz'), walk_up=True), P('../Bar')) + self.assertEqual(p.relative_to(P('C:Baz/Bar'), walk_up=True), P('../../Foo/Bar')) # Unrelated paths. self.assertRaises(ValueError, p.relative_to, P()) self.assertRaises(ValueError, p.relative_to, '') @@ -1130,11 +1240,14 @@ class PureWindowsPathTest(_BasePurePathTest, unittest.TestCase): self.assertRaises(ValueError, p.relative_to, P('C:/Foo')) self.assertRaises(ValueError, p.relative_to, P('C:Foo/Bar/Baz')) self.assertRaises(ValueError, p.relative_to, P('C:Foo/Baz')) + self.assertRaises(ValueError, p.relative_to, P(), walk_up=True) + self.assertRaises(ValueError, p.relative_to, '', walk_up=True) + self.assertRaises(ValueError, p.relative_to, P('d:'), walk_up=True) + self.assertRaises(ValueError, p.relative_to, P('/'), walk_up=True) + self.assertRaises(ValueError, p.relative_to, P('Foo'), walk_up=True) + self.assertRaises(ValueError, p.relative_to, P('/Foo'), walk_up=True) + self.assertRaises(ValueError, p.relative_to, P('C:/Foo'), walk_up=True) p = P('C:/Foo/Bar') - self.assertEqual(p.relative_to(P('c:')), P('/Foo/Bar')) - self.assertEqual(p.relative_to('c:'), P('/Foo/Bar')) - self.assertEqual(str(p.relative_to(P('c:'))), '\\Foo\\Bar') - self.assertEqual(str(p.relative_to('c:')), '\\Foo\\Bar') self.assertEqual(p.relative_to(P('c:/')), P('Foo/Bar')) self.assertEqual(p.relative_to('c:/'), P('Foo/Bar')) self.assertEqual(p.relative_to(P('c:/foO')), P('Bar')) @@ -1142,7 +1255,19 @@ class PureWindowsPathTest(_BasePurePathTest, unittest.TestCase): self.assertEqual(p.relative_to('c:/foO/'), P('Bar')) self.assertEqual(p.relative_to(P('c:/foO/baR')), P()) self.assertEqual(p.relative_to('c:/foO/baR'), P()) + self.assertEqual(p.relative_to(P('c:/'), walk_up=True), P('Foo/Bar')) + self.assertEqual(p.relative_to('c:/', walk_up=True), P('Foo/Bar')) + self.assertEqual(p.relative_to(P('c:/foO'), walk_up=True), P('Bar')) + self.assertEqual(p.relative_to('c:/foO', walk_up=True), P('Bar')) + self.assertEqual(p.relative_to('c:/foO/', walk_up=True), P('Bar')) + self.assertEqual(p.relative_to(P('c:/foO/baR'), walk_up=True), P()) + self.assertEqual(p.relative_to('c:/foO/baR', walk_up=True), P()) + self.assertEqual(p.relative_to('C:/Baz', walk_up=True), P('../Foo/Bar')) + self.assertEqual(p.relative_to('C:/Foo/Bar/Baz', walk_up=True), P('..')) + self.assertEqual(p.relative_to('C:/Foo/Baz', walk_up=True), P('../Bar')) # Unrelated paths. + self.assertRaises(ValueError, p.relative_to, 'c:') + self.assertRaises(ValueError, p.relative_to, P('c:')) self.assertRaises(ValueError, p.relative_to, P('C:/Baz')) self.assertRaises(ValueError, p.relative_to, P('C:/Foo/Bar/Baz')) self.assertRaises(ValueError, p.relative_to, P('C:/Foo/Baz')) @@ -1152,6 +1277,14 @@ class PureWindowsPathTest(_BasePurePathTest, unittest.TestCase): self.assertRaises(ValueError, p.relative_to, P('/')) self.assertRaises(ValueError, p.relative_to, P('/Foo')) self.assertRaises(ValueError, p.relative_to, P('//C/Foo')) + self.assertRaises(ValueError, p.relative_to, 'c:', walk_up=True) + self.assertRaises(ValueError, p.relative_to, P('c:'), walk_up=True) + self.assertRaises(ValueError, p.relative_to, P('C:Foo'), walk_up=True) + self.assertRaises(ValueError, p.relative_to, P('d:'), walk_up=True) + self.assertRaises(ValueError, p.relative_to, P('d:/'), walk_up=True) + self.assertRaises(ValueError, p.relative_to, P('/'), walk_up=True) + self.assertRaises(ValueError, p.relative_to, P('/Foo'), walk_up=True) + self.assertRaises(ValueError, p.relative_to, P('//C/Foo'), walk_up=True) # UNC paths. p = P('//Server/Share/Foo/Bar') self.assertEqual(p.relative_to(P('//sErver/sHare')), P('Foo/Bar')) @@ -1162,11 +1295,25 @@ class PureWindowsPathTest(_BasePurePathTest, unittest.TestCase): self.assertEqual(p.relative_to('//sErver/sHare/Foo/'), P('Bar')) self.assertEqual(p.relative_to(P('//sErver/sHare/Foo/Bar')), P()) self.assertEqual(p.relative_to('//sErver/sHare/Foo/Bar'), P()) + self.assertEqual(p.relative_to(P('//sErver/sHare'), walk_up=True), P('Foo/Bar')) + self.assertEqual(p.relative_to('//sErver/sHare', walk_up=True), P('Foo/Bar')) + self.assertEqual(p.relative_to('//sErver/sHare/', walk_up=True), P('Foo/Bar')) + self.assertEqual(p.relative_to(P('//sErver/sHare/Foo'), walk_up=True), P('Bar')) + self.assertEqual(p.relative_to('//sErver/sHare/Foo', walk_up=True), P('Bar')) + self.assertEqual(p.relative_to('//sErver/sHare/Foo/', walk_up=True), P('Bar')) + self.assertEqual(p.relative_to(P('//sErver/sHare/Foo/Bar'), walk_up=True), P()) + self.assertEqual(p.relative_to('//sErver/sHare/Foo/Bar', walk_up=True), P()) + self.assertEqual(p.relative_to(P('//sErver/sHare/bar'), walk_up=True), P('../Foo/Bar')) + self.assertEqual(p.relative_to('//sErver/sHare/bar', walk_up=True), P('../Foo/Bar')) # Unrelated paths. self.assertRaises(ValueError, p.relative_to, P('/Server/Share/Foo')) self.assertRaises(ValueError, p.relative_to, P('c:/Server/Share/Foo')) self.assertRaises(ValueError, p.relative_to, P('//z/Share/Foo')) self.assertRaises(ValueError, p.relative_to, P('//Server/z/Foo')) + self.assertRaises(ValueError, p.relative_to, P('/Server/Share/Foo'), walk_up=True) + self.assertRaises(ValueError, p.relative_to, P('c:/Server/Share/Foo'), walk_up=True) + self.assertRaises(ValueError, p.relative_to, P('//z/Share/Foo'), walk_up=True) + self.assertRaises(ValueError, p.relative_to, P('//Server/z/Foo'), walk_up=True) def test_is_relative_to(self): P = self.cls @@ -1189,13 +1336,13 @@ class PureWindowsPathTest(_BasePurePathTest, unittest.TestCase): self.assertFalse(p.is_relative_to(P('C:Foo/Bar/Baz'))) self.assertFalse(p.is_relative_to(P('C:Foo/Baz'))) p = P('C:/Foo/Bar') - self.assertTrue(p.is_relative_to('c:')) self.assertTrue(p.is_relative_to(P('c:/'))) self.assertTrue(p.is_relative_to(P('c:/foO'))) self.assertTrue(p.is_relative_to('c:/foO/')) self.assertTrue(p.is_relative_to(P('c:/foO/baR'))) self.assertTrue(p.is_relative_to('c:/foO/baR')) # Unrelated paths. + self.assertFalse(p.is_relative_to('c:')) self.assertFalse(p.is_relative_to(P('C:/Baz'))) self.assertFalse(p.is_relative_to(P('C:/Foo/Bar/Baz'))) self.assertFalse(p.is_relative_to(P('C:/Foo/Baz'))) @@ -1263,6 +1410,21 @@ class PureWindowsPathTest(_BasePurePathTest, unittest.TestCase): self.assertEqual(pp, P('C:/a/b/x/y')) pp = p.joinpath('c:/x/y') self.assertEqual(pp, P('C:/x/y')) + # Joining with files with NTFS data streams => the filename should + # not be parsed as a drive letter + pp = p.joinpath(P('./d:s')) + self.assertEqual(pp, P('C:/a/b/d:s')) + pp = p.joinpath(P('./dd:s')) + self.assertEqual(pp, P('C:/a/b/dd:s')) + pp = p.joinpath(P('E:d:s')) + self.assertEqual(pp, P('E:d:s')) + # Joining onto a UNC path with no root + pp = P('//').joinpath('server') + self.assertEqual(pp, P('//server')) + pp = P('//server').joinpath('share') + self.assertEqual(pp, P('//server/share')) + pp = P('//./BootPartition').joinpath('Windows') + self.assertEqual(pp, P('//./BootPartition/Windows')) def test_div(self): # Basically the same as joinpath(). @@ -1283,6 +1445,11 @@ class PureWindowsPathTest(_BasePurePathTest, unittest.TestCase): # the second path is relative. self.assertEqual(p / 'c:x/y', P('C:/a/b/x/y')) self.assertEqual(p / 'c:/x/y', P('C:/x/y')) + # Joining with files with NTFS data streams => the filename should + # not be parsed as a drive letter + self.assertEqual(p / P('./d:s'), P('C:/a/b/d:s')) + self.assertEqual(p / P('./dd:s'), P('C:/a/b/dd:s')) + self.assertEqual(p / P('E:d:s'), P('E:d:s')) def test_is_reserved(self): P = self.cls @@ -1510,6 +1677,27 @@ class _BasePathTest(object): env['HOME'] = os.path.join(BASE, 'home') self._test_home(self.cls.home()) + def test_with_segments(self): + class P(_BasePurePathSubclass, self.cls): + pass + p = P(BASE, session_id=42) + self.assertEqual(42, p.absolute().session_id) + self.assertEqual(42, p.resolve().session_id) + if not is_wasi: # WASI has no user accounts. + self.assertEqual(42, p.with_segments('~').expanduser().session_id) + self.assertEqual(42, (p / 'fileA').rename(p / 'fileB').session_id) + self.assertEqual(42, (p / 'fileB').replace(p / 'fileA').session_id) + if os_helper.can_symlink(): + self.assertEqual(42, (p / 'linkA').readlink().session_id) + for path in p.iterdir(): + self.assertEqual(42, path.session_id) + for path in p.glob('*'): + self.assertEqual(42, path.session_id) + for path in p.rglob('*'): + self.assertEqual(42, path.session_id) + for dirpath, dirnames, filenames in p.walk(): + self.assertEqual(42, dirpath.session_id) + def test_samefile(self): fileA_path = os.path.join(BASE, 'fileA') fileB_path = os.path.join(BASE, 'dirB', 'fileB') @@ -1548,6 +1736,8 @@ class _BasePathTest(object): self.assertEqual(p.expanduser(), p) p = P(P('').absolute().anchor) / '~' self.assertEqual(p.expanduser(), p) + p = P('~/a:b') + self.assertEqual(p.expanduser(), P(os.path.expanduser('~'), './a:b')) def test_exists(self): P = self.cls @@ -1561,6 +1751,8 @@ class _BasePathTest(object): self.assertIs(True, (p / 'linkB').exists()) self.assertIs(True, (p / 'linkB' / 'fileB').exists()) self.assertIs(False, (p / 'linkA' / 'bah').exists()) + self.assertIs(False, (p / 'brokenLink').exists()) + self.assertIs(True, (p / 'brokenLink').exists(follow_symlinks=False)) self.assertIs(False, (p / 'foo').exists()) self.assertIs(False, P('/xyzzy').exists()) self.assertIs(False, P(BASE + '\udfff').exists()) @@ -1667,21 +1859,36 @@ class _BasePathTest(object): _check(p.glob("*/fileB"), ['dirB/fileB']) else: _check(p.glob("*/fileB"), ['dirB/fileB', 'linkB/fileB']) + if os_helper.can_symlink(): + _check(p.glob("brokenLink"), ['brokenLink']) if not os_helper.can_symlink(): _check(p.glob("*/"), ["dirA", "dirB", "dirC", "dirE"]) else: _check(p.glob("*/"), ["dirA", "dirB", "dirC", "dirE", "linkB"]) + def test_glob_case_sensitive(self): + P = self.cls + def _check(path, pattern, case_sensitive, expected): + actual = {str(q) for q in path.glob(pattern, case_sensitive=case_sensitive)} + expected = {str(P(BASE, q)) for q in expected} + self.assertEqual(actual, expected) + path = P(BASE) + _check(path, "DIRB/FILE*", True, []) + _check(path, "DIRB/FILE*", False, ["dirB/fileB"]) + _check(path, "dirb/file*", True, []) + _check(path, "dirb/file*", False, ["dirB/fileB"]) + def test_rglob_common(self): def _check(glob, expected): - self.assertEqual(set(glob), { P(BASE, q) for q in expected }) + self.assertEqual(sorted(glob), sorted(P(BASE, q) for q in expected)) P = self.cls p = P(BASE) it = p.rglob("fileA") self.assertIsInstance(it, collections.abc.Iterator) _check(it, ["fileA"]) _check(p.rglob("fileB"), ["dirB/fileB"]) + _check(p.rglob("**/fileB"), ["dirB/fileB"]) _check(p.rglob("*/fileA"), []) if not os_helper.can_symlink(): _check(p.rglob("*/fileB"), ["dirB/fileB"]) @@ -1705,9 +1912,12 @@ class _BasePathTest(object): _check(p.rglob("*"), ["dirC/fileC", "dirC/novel.txt", "dirC/dirD", "dirC/dirD/fileD"]) _check(p.rglob("file*"), ["dirC/fileC", "dirC/dirD/fileD"]) + _check(p.rglob("**/file*"), ["dirC/fileC", "dirC/dirD/fileD"]) + _check(p.rglob("dir*/**"), ["dirC/dirD"]) _check(p.rglob("*/*"), ["dirC/dirD/fileD"]) _check(p.rglob("*/"), ["dirC/dirD"]) _check(p.rglob(""), ["dirC", "dirC/dirD"]) + _check(p.rglob("**"), ["dirC", "dirC/dirD"]) # gh-91616, a re module regression _check(p.rglob("*.txt"), ["dirC/novel.txt"]) _check(p.rglob("*.*"), ["dirC/novel.txt"]) @@ -1753,8 +1963,13 @@ class _BasePathTest(object): P = self.cls p = P(BASE) self.assertEqual(set(p.glob("..")), { P(BASE, "..") }) + self.assertEqual(set(p.glob("../..")), { P(BASE, "..", "..") }) + self.assertEqual(set(p.glob("dirA/..")), { P(BASE, "dirA", "..") }) self.assertEqual(set(p.glob("dirA/../file*")), { P(BASE, "dirA/../fileA") }) + self.assertEqual(set(p.glob("dirA/../file*/..")), set()) self.assertEqual(set(p.glob("../xyzzy")), set()) + self.assertEqual(set(p.glob("xyzzy/..")), set()) + self.assertEqual(set(p.glob("/".join([".."] * 50))), { P(BASE, *[".."] * 50)}) @os_helper.skip_unless_symlink def test_glob_permissions(self): @@ -1762,33 +1977,39 @@ class _BasePathTest(object): P = self.cls base = P(BASE) / 'permissions' base.mkdir() + self.addCleanup(os_helper.rmtree, base) + + for i in range(100): + link = base / f"link{i}" + if i % 2: + link.symlink_to(P(BASE, "dirE", "nonexistent")) + else: + link.symlink_to(P(BASE, "dirC")) + + self.assertEqual(len(set(base.glob("*"))), 100) + self.assertEqual(len(set(base.glob("*/"))), 50) + self.assertEqual(len(set(base.glob("*/fileC"))), 50) + self.assertEqual(len(set(base.glob("*/file*"))), 50) + + @os_helper.skip_unless_symlink + def test_glob_long_symlink(self): + # See gh-87695 + base = self.cls(BASE) / 'long_symlink' + base.mkdir() + bad_link = base / 'bad_link' + bad_link.symlink_to("bad" * 200) + self.assertEqual(sorted(base.glob('**/*')), [bad_link]) - file1 = base / "file1" - file1.touch() - file2 = base / "file2" - file2.touch() - - subdir = base / "subdir" - - file3 = base / "file3" - file3.symlink_to(subdir / "other") - - # Patching is needed to avoid relying on the filesystem - # to return the order of the files as the error will not - # happen if the symlink is the last item. - real_scandir = os.scandir - def my_scandir(path): - with real_scandir(path) as scandir_it: - entries = list(scandir_it) - entries.sort(key=lambda entry: entry.name) - return contextlib.nullcontext(entries) - - with mock.patch("os.scandir", my_scandir): - self.assertEqual(len(set(base.glob("*"))), 3) - subdir.mkdir() - self.assertEqual(len(set(base.glob("*"))), 4) - subdir.chmod(000) - self.assertEqual(len(set(base.glob("*"))), 4) + def test_glob_above_recursion_limit(self): + recursion_limit = 50 + # directory_depth > recursion_limit + directory_depth = recursion_limit + 10 + base = pathlib.Path(os_helper.TESTFN, 'deep') + path = pathlib.Path(base, *(['d'] * directory_depth)) + path.mkdir(parents=True) + + with set_recursion_limit(recursion_limit): + list(base.glob('**')) def _check_resolve(self, p, expected, strict=True): q = p.resolve(strict) @@ -1860,7 +2081,7 @@ class _BasePathTest(object): @os_helper.skip_unless_symlink def test_resolve_dot(self): - # See https://bitbucket.org/pitrou/pathlib/issue/9/pathresolve-fails-on-complex-symlinks + # See http://web.archive.org/web/20200623062557/https://bitbucket.org/pitrou/pathlib/issues/9/ p = self.cls(BASE) self.dirlink('.', join('0')) self.dirlink(os.path.join('0', '0'), join('1')) @@ -2006,28 +2227,6 @@ class _BasePathTest(object): self.assertFileNotFound(p.stat) self.assertFileNotFound(p.unlink) - @unittest.skipUnless(hasattr(os, "link"), "os.link() is not present") - def test_link_to(self): - P = self.cls(BASE) - p = P / 'fileA' - size = p.stat().st_size - # linking to another path. - q = P / 'dirA' / 'fileAA' - try: - with self.assertWarns(DeprecationWarning): - p.link_to(q) - except PermissionError as e: - self.skipTest('os.link(): %s' % e) - self.assertEqual(q.stat().st_size, size) - self.assertEqual(os.path.samefile(p, q), True) - self.assertTrue(p.stat) - # Linking to a str of a relative path. - r = rel_join('fileAAA') - with self.assertWarns(DeprecationWarning): - q.link_to(r) - self.assertEqual(os.stat(r).st_size, size) - self.assertTrue(q.stat) - @unittest.skipUnless(hasattr(os, "link"), "os.link() is not present") def test_hardlink_to(self): P = self.cls(BASE) @@ -2053,7 +2252,7 @@ class _BasePathTest(object): # linking to another path. q = P / 'dirA' / 'fileAA' with self.assertRaises(NotImplementedError): - p.link_to(q) + q.hardlink_to(p) def test_rename(self): P = self.cls(BASE) @@ -2316,10 +2515,12 @@ class _BasePathTest(object): self.assertIs((P / 'fileA\udfff').is_file(), False) self.assertIs((P / 'fileA\x00').is_file(), False) - @only_posix def test_is_mount(self): P = self.cls(BASE) - R = self.cls('/') # TODO: Work out Windows. + if os.name == 'nt': + R = self.cls('c:\\') + else: + R = self.cls('/') self.assertFalse((P / 'fileA').is_mount()) self.assertFalse((P / 'dirA').is_mount()) self.assertFalse((P / 'non-existing').is_mount()) @@ -2327,8 +2528,7 @@ class _BasePathTest(object): self.assertTrue(R.is_mount()) if os_helper.can_symlink(): self.assertFalse((P / 'linkA').is_mount()) - self.assertIs(self.cls('/\udfff').is_mount(), False) - self.assertIs(self.cls('/\x00').is_mount(), False) + self.assertIs((R / '\udfff').is_mount(), False) def test_is_symlink(self): P = self.cls(BASE) @@ -2346,6 +2546,13 @@ class _BasePathTest(object): self.assertIs((P / 'linkA\udfff').is_file(), False) self.assertIs((P / 'linkA\x00').is_file(), False) + def test_is_junction(self): + P = self.cls(BASE) + + with mock.patch.object(P._flavour, 'isjunction'): + self.assertEqual(P.is_junction(), P._flavour.isjunction.return_value) + P._flavour.isjunction.assert_called_once_with(P) + def test_is_fifo_false(self): P = self.cls(BASE) self.assertFalse((P / 'fileA').is_fifo()) @@ -2500,6 +2707,234 @@ class _BasePathTest(object): def test_complex_symlinks_relative_dot_dot(self): self._check_complex_symlinks(os.path.join('dirA', '..')) + def test_passing_kwargs_deprecated(self): + with self.assertWarns(DeprecationWarning): + self.cls(foo="bar") + + +class WalkTests(unittest.TestCase): + + def setUp(self): + self.addCleanup(os_helper.rmtree, os_helper.TESTFN) + + # Build: + # TESTFN/ + # TEST1/ a file kid and two directory kids + # tmp1 + # SUB1/ a file kid and a directory kid + # tmp2 + # SUB11/ no kids + # SUB2/ a file kid and a dirsymlink kid + # tmp3 + # SUB21/ not readable + # tmp5 + # link/ a symlink to TEST2 + # broken_link + # broken_link2 + # broken_link3 + # TEST2/ + # tmp4 a lone file + self.walk_path = pathlib.Path(os_helper.TESTFN, "TEST1") + self.sub1_path = self.walk_path / "SUB1" + self.sub11_path = self.sub1_path / "SUB11" + self.sub2_path = self.walk_path / "SUB2" + sub21_path= self.sub2_path / "SUB21" + tmp1_path = self.walk_path / "tmp1" + tmp2_path = self.sub1_path / "tmp2" + tmp3_path = self.sub2_path / "tmp3" + tmp5_path = sub21_path / "tmp3" + self.link_path = self.sub2_path / "link" + t2_path = pathlib.Path(os_helper.TESTFN, "TEST2") + tmp4_path = pathlib.Path(os_helper.TESTFN, "TEST2", "tmp4") + broken_link_path = self.sub2_path / "broken_link" + broken_link2_path = self.sub2_path / "broken_link2" + broken_link3_path = self.sub2_path / "broken_link3" + + os.makedirs(self.sub11_path) + os.makedirs(self.sub2_path) + os.makedirs(sub21_path) + os.makedirs(t2_path) + + for path in tmp1_path, tmp2_path, tmp3_path, tmp4_path, tmp5_path: + with open(path, "x", encoding='utf-8') as f: + f.write(f"I'm {path} and proud of it. Blame test_pathlib.\n") + + if os_helper.can_symlink(): + os.symlink(os.path.abspath(t2_path), self.link_path) + os.symlink('broken', broken_link_path, True) + os.symlink(pathlib.Path('tmp3', 'broken'), broken_link2_path, True) + os.symlink(pathlib.Path('SUB21', 'tmp5'), broken_link3_path, True) + self.sub2_tree = (self.sub2_path, ["SUB21"], + ["broken_link", "broken_link2", "broken_link3", + "link", "tmp3"]) + else: + self.sub2_tree = (self.sub2_path, ["SUB21"], ["tmp3"]) + + if not is_emscripten: + # Emscripten fails with inaccessible directories. + os.chmod(sub21_path, 0) + try: + os.listdir(sub21_path) + except PermissionError: + self.addCleanup(os.chmod, sub21_path, stat.S_IRWXU) + else: + os.chmod(sub21_path, stat.S_IRWXU) + os.unlink(tmp5_path) + os.rmdir(sub21_path) + del self.sub2_tree[1][:1] + + def test_walk_topdown(self): + walker = self.walk_path.walk() + entry = next(walker) + entry[1].sort() # Ensure we visit SUB1 before SUB2 + self.assertEqual(entry, (self.walk_path, ["SUB1", "SUB2"], ["tmp1"])) + entry = next(walker) + self.assertEqual(entry, (self.sub1_path, ["SUB11"], ["tmp2"])) + entry = next(walker) + self.assertEqual(entry, (self.sub11_path, [], [])) + entry = next(walker) + entry[1].sort() + entry[2].sort() + self.assertEqual(entry, self.sub2_tree) + with self.assertRaises(StopIteration): + next(walker) + + def test_walk_prune(self, walk_path=None): + if walk_path is None: + walk_path = self.walk_path + # Prune the search. + all = [] + for root, dirs, files in walk_path.walk(): + all.append((root, dirs, files)) + if 'SUB1' in dirs: + # Note that this also mutates the dirs we appended to all! + dirs.remove('SUB1') + + self.assertEqual(len(all), 2) + self.assertEqual(all[0], (self.walk_path, ["SUB2"], ["tmp1"])) + + all[1][-1].sort() + all[1][1].sort() + self.assertEqual(all[1], self.sub2_tree) + + def test_file_like_path(self): + self.test_walk_prune(FakePath(self.walk_path).__fspath__()) + + def test_walk_bottom_up(self): + seen_testfn = seen_sub1 = seen_sub11 = seen_sub2 = False + for path, dirnames, filenames in self.walk_path.walk(top_down=False): + if path == self.walk_path: + self.assertFalse(seen_testfn) + self.assertTrue(seen_sub1) + self.assertTrue(seen_sub2) + self.assertEqual(sorted(dirnames), ["SUB1", "SUB2"]) + self.assertEqual(filenames, ["tmp1"]) + seen_testfn = True + elif path == self.sub1_path: + self.assertFalse(seen_testfn) + self.assertFalse(seen_sub1) + self.assertTrue(seen_sub11) + self.assertEqual(dirnames, ["SUB11"]) + self.assertEqual(filenames, ["tmp2"]) + seen_sub1 = True + elif path == self.sub11_path: + self.assertFalse(seen_sub1) + self.assertFalse(seen_sub11) + self.assertEqual(dirnames, []) + self.assertEqual(filenames, []) + seen_sub11 = True + elif path == self.sub2_path: + self.assertFalse(seen_testfn) + self.assertFalse(seen_sub2) + self.assertEqual(sorted(dirnames), sorted(self.sub2_tree[1])) + self.assertEqual(sorted(filenames), sorted(self.sub2_tree[2])) + seen_sub2 = True + else: + raise AssertionError(f"Unexpected path: {path}") + self.assertTrue(seen_testfn) + + @os_helper.skip_unless_symlink + def test_walk_follow_symlinks(self): + walk_it = self.walk_path.walk(follow_symlinks=True) + for root, dirs, files in walk_it: + if root == self.link_path: + self.assertEqual(dirs, []) + self.assertEqual(files, ["tmp4"]) + break + else: + self.fail("Didn't follow symlink with follow_symlinks=True") + + @os_helper.skip_unless_symlink + def test_walk_symlink_location(self): + # Tests whether symlinks end up in filenames or dirnames depending + # on the `follow_symlinks` argument. + walk_it = self.walk_path.walk(follow_symlinks=False) + for root, dirs, files in walk_it: + if root == self.sub2_path: + self.assertIn("link", files) + break + else: + self.fail("symlink not found") + + walk_it = self.walk_path.walk(follow_symlinks=True) + for root, dirs, files in walk_it: + if root == self.sub2_path: + self.assertIn("link", dirs) + break + + def test_walk_bad_dir(self): + errors = [] + walk_it = self.walk_path.walk(on_error=errors.append) + root, dirs, files = next(walk_it) + self.assertEqual(errors, []) + dir1 = 'SUB1' + path1 = root / dir1 + path1new = (root / dir1).with_suffix(".new") + path1.rename(path1new) + try: + roots = [r for r, _, _ in walk_it] + self.assertTrue(errors) + self.assertNotIn(path1, roots) + self.assertNotIn(path1new, roots) + for dir2 in dirs: + if dir2 != dir1: + self.assertIn(root / dir2, roots) + finally: + path1new.rename(path1) + + def test_walk_many_open_files(self): + depth = 30 + base = pathlib.Path(os_helper.TESTFN, 'deep') + path = pathlib.Path(base, *(['d']*depth)) + path.mkdir(parents=True) + + iters = [base.walk(top_down=False) for _ in range(100)] + for i in range(depth + 1): + expected = (path, ['d'] if i else [], []) + for it in iters: + self.assertEqual(next(it), expected) + path = path.parent + + iters = [base.walk(top_down=True) for _ in range(100)] + path = base + for i in range(depth + 1): + expected = (path, ['d'] if i < depth else [], []) + for it in iters: + self.assertEqual(next(it), expected) + path = path / 'd' + + def test_walk_above_recursion_limit(self): + recursion_limit = 40 + # directory_depth > recursion_limit + directory_depth = recursion_limit + 10 + base = pathlib.Path(os_helper.TESTFN, 'deep') + path = pathlib.Path(base, *(['d'] * directory_depth)) + path.mkdir(parents=True) + + with set_recursion_limit(recursion_limit): + list(base.walk()) + list(base.walk(top_down=False)) + class PathTest(_BasePathTest, unittest.TestCase): cls = pathlib.Path @@ -2733,6 +3168,26 @@ class WindowsPathTest(_BasePathTest, unittest.TestCase): self.assertEqual(str(P('a', 'b', 'c').absolute()), os.path.join(share, 'a', 'b', 'c')) + drive = os.path.splitdrive(BASE)[0] + with os_helper.change_cwd(BASE): + # Relative path with root + self.assertEqual(str(P('\\').absolute()), drive + '\\') + self.assertEqual(str(P('\\foo').absolute()), drive + '\\foo') + + # Relative path on current drive + self.assertEqual(str(P(drive).absolute()), BASE) + self.assertEqual(str(P(drive + 'foo').absolute()), os.path.join(BASE, 'foo')) + + with os_helper.subst_drive(BASE) as other_drive: + # Set the working directory on the substitute drive + saved_cwd = os.getcwd() + other_cwd = f'{other_drive}\\dirA' + os.chdir(other_cwd) + os.chdir(saved_cwd) + + # Relative path on another drive + self.assertEqual(str(P(other_drive).absolute()), other_cwd) + self.assertEqual(str(P(other_drive + 'foo').absolute()), other_cwd + '\\foo') def test_glob(self): P = self.cls @@ -2740,7 +3195,7 @@ class WindowsPathTest(_BasePathTest, unittest.TestCase): self.assertEqual(set(p.glob("FILEa")), { P(BASE, "fileA") }) self.assertEqual(set(p.glob("*a\\")), { P(BASE, "dirA") }) self.assertEqual(set(p.glob("F*a")), { P(BASE, "fileA") }) - self.assertEqual(set(map(str, p.glob("FILEa"))), {f"{p}\\FILEa"}) + self.assertEqual(set(map(str, p.glob("FILEa"))), {f"{p}\\fileA"}) self.assertEqual(set(map(str, p.glob("F*a"))), {f"{p}\\fileA"}) def test_rglob(self): @@ -2748,7 +3203,7 @@ class WindowsPathTest(_BasePathTest, unittest.TestCase): p = P(BASE, "dirC") self.assertEqual(set(p.rglob("FILEd")), { P(BASE, "dirC/dirD/fileD") }) self.assertEqual(set(p.rglob("*\\")), { P(BASE, "dirC/dirD") }) - self.assertEqual(set(map(str, p.rglob("FILEd"))), {f"{p}\\dirD\\FILEd"}) + self.assertEqual(set(map(str, p.rglob("FILEd"))), {f"{p}\\dirD\\fileD"}) def test_expanduser(self): P = self.cls @@ -2804,6 +3259,22 @@ class WindowsPathTest(_BasePathTest, unittest.TestCase): check() +class PurePathSubclassTest(_BasePurePathTest, unittest.TestCase): + class cls(pathlib.PurePath): + pass + + # repr() roundtripping is not supported in custom subclass. + test_repr_roundtrips = None + + +class PathSubclassTest(_BasePathTest, unittest.TestCase): + class cls(pathlib.Path): + pass + + # repr() roundtripping is not supported in custom subclass. + test_repr_roundtrips = None + + class CompatiblePathTest(unittest.TestCase): """ Test that a type can be made compatible with PurePath diff --git a/Lib/test/test_patma.py b/Lib/test/test_patma.py index db198f77..3dbd19df 100644 --- a/Lib/test/test_patma.py +++ b/Lib/test/test_patma.py @@ -2654,6 +2654,20 @@ class TestPatma(unittest.TestCase): self.assertEqual(y, 'bar') + def test_patma_249(self): + class C: + __attr = "eggs" # mangled to _C__attr + _Outer__attr = "bacon" + class Outer: + def f(self, x): + match x: + # looks up __attr, not _C__attr or _Outer__attr + case C(__attr=y): + return y + c = C() + setattr(c, "__attr", "spam") # setattr is needed because we're in a class scope + self.assertEqual(Outer().f(c), "spam") + class TestSyntaxErrors(unittest.TestCase): @@ -3151,6 +3165,19 @@ class TestTracing(unittest.TestCase): self.assertListEqual(self._trace(f, "go x"), [1, 2, 3]) self.assertListEqual(self._trace(f, "spam"), [1, 2, 3]) + def test_unreachable_code(self): + def f(command): # 0 + match command: # 1 + case 1: # 2 + if False: # 3 + return 1 # 4 + case _: # 5 + if False: # 6 + return 0 # 7 + + self.assertListEqual(self._trace(f, 1), [1, 2, 3]) + self.assertListEqual(self._trace(f, 0), [1, 2, 5, 6]) + def test_parser_deeply_nested_patterns(self): # Deeply nested patterns can cause exponential backtracking when parsing. # See gh-93671 for more information. diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py index 48f419e6..5793dbfb 100644 --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -240,9 +240,11 @@ def test_pdb_breakpoint_commands(): >>> with PdbTestInput([ # doctest: +NORMALIZE_WHITESPACE ... 'break 3', + ... 'break 4, +', ... 'disable 1', ... 'ignore 1 10', ... 'condition 1 1 < 2', + ... 'condition 1 1 <', ... 'break 4', ... 'break 4', ... 'break', @@ -264,6 +266,8 @@ def test_pdb_breakpoint_commands(): ... 'commands 10', # out of range ... 'commands a', # display help ... 'commands 4', # already deleted + ... 'break 6, undefined', # condition causing `NameError` during evaluation + ... 'continue', # will stop, ignoring runtime error ... 'continue', ... ]): ... test_function() @@ -271,12 +275,16 @@ def test_pdb_breakpoint_commands(): -> print(1) (Pdb) break 3 Breakpoint 1 at <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>:3 + (Pdb) break 4, + + *** Invalid condition +: SyntaxError: invalid syntax (Pdb) disable 1 Disabled breakpoint 1 at <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>:3 (Pdb) ignore 1 10 Will ignore next 10 crossings of breakpoint 1. (Pdb) condition 1 1 < 2 New condition set for breakpoint 1. + (Pdb) condition 1 1 < + *** Invalid condition 1 <: SyntaxError: invalid syntax (Pdb) break 4 Breakpoint 2 at <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>:4 (Pdb) break 4 @@ -331,8 +339,13 @@ def test_pdb_breakpoint_commands(): end (Pdb) commands 4 *** cannot set commands: Breakpoint 4 already deleted + (Pdb) break 6, undefined + Breakpoint 5 at <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>:6 (Pdb) continue 3 + > <doctest test.test_pdb.test_pdb_breakpoint_commands[0]>(6)test_function() + -> print(4) + (Pdb) continue 4 """ @@ -574,6 +587,243 @@ def test_pdb_whatis_command(): (Pdb) continue """ +def test_pdb_display_command(): + """Test display command + + >>> def test_function(): + ... a = 0 + ... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace() + ... a = 1 + ... a = 2 + ... a = 3 + ... a = 4 + + >>> with PdbTestInput([ # doctest: +ELLIPSIS + ... 'display +', + ... 'display', + ... 'display a', + ... 'n', + ... 'display', + ... 'undisplay a', + ... 'n', + ... 'display a', + ... 'undisplay', + ... 'display a < 1', + ... 'n', + ... 'display undefined', + ... 'continue', + ... ]): + ... test_function() + > <doctest test.test_pdb.test_pdb_display_command[0]>(4)test_function() + -> a = 1 + (Pdb) display + + *** Unable to display +: SyntaxError: invalid syntax + (Pdb) display + No expression is being displayed + (Pdb) display a + display a: 0 + (Pdb) n + > <doctest test.test_pdb.test_pdb_display_command[0]>(5)test_function() + -> a = 2 + display a: 1 [old: 0] + (Pdb) display + Currently displaying: + a: 1 + (Pdb) undisplay a + (Pdb) n + > <doctest test.test_pdb.test_pdb_display_command[0]>(6)test_function() + -> a = 3 + (Pdb) display a + display a: 2 + (Pdb) undisplay + (Pdb) display a < 1 + display a < 1: False + (Pdb) n + > <doctest test.test_pdb.test_pdb_display_command[0]>(7)test_function() + -> a = 4 + (Pdb) display undefined + display undefined: ** raised NameError: name 'undefined' is not defined ** + (Pdb) continue + """ + +def test_pdb_alias_command(): + """Test alias command + + >>> class A: + ... def __init__(self): + ... self.attr1 = 10 + ... self.attr2 = 'str' + ... def method(self): + ... pass + + >>> def test_function(): + ... o = A() + ... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace() + ... o.method() + + >>> with PdbTestInput([ # doctest: +ELLIPSIS + ... 'alias pi for k in %1.__dict__.keys(): print(f"%1.{k} = {%1.__dict__[k]}")', + ... 'alias ps pi self', + ... 'pi o', + ... 's', + ... 'ps', + ... 'continue', + ... ]): + ... test_function() + > <doctest test.test_pdb.test_pdb_alias_command[1]>(4)test_function() + -> o.method() + (Pdb) alias pi for k in %1.__dict__.keys(): print(f"%1.{k} = {%1.__dict__[k]}") + (Pdb) alias ps pi self + (Pdb) pi o + o.attr1 = 10 + o.attr2 = str + (Pdb) s + --Call-- + > <doctest test.test_pdb.test_pdb_alias_command[0]>(5)method() + -> def method(self): + (Pdb) ps + self.attr1 = 10 + self.attr2 = str + (Pdb) continue + """ + +def test_pdb_where_command(): + """Test where command + + >>> def g(): + ... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace() + + >>> def f(): + ... g(); + + >>> def test_function(): + ... f() + + >>> with PdbTestInput([ # doctest: +ELLIPSIS + ... 'w', + ... 'where', + ... 'u', + ... 'w', + ... 'continue', + ... ]): + ... test_function() + --Return-- + > <doctest test.test_pdb.test_pdb_where_command[0]>(2)g()->None + -> import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace() + (Pdb) w + ... + <doctest test.test_pdb.test_pdb_where_command[3]>(8)<module>() + -> test_function() + <doctest test.test_pdb.test_pdb_where_command[2]>(2)test_function() + -> f() + <doctest test.test_pdb.test_pdb_where_command[1]>(2)f() + -> g(); + > <doctest test.test_pdb.test_pdb_where_command[0]>(2)g()->None + -> import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace() + (Pdb) where + ... + <doctest test.test_pdb.test_pdb_where_command[3]>(8)<module>() + -> test_function() + <doctest test.test_pdb.test_pdb_where_command[2]>(2)test_function() + -> f() + <doctest test.test_pdb.test_pdb_where_command[1]>(2)f() + -> g(); + > <doctest test.test_pdb.test_pdb_where_command[0]>(2)g()->None + -> import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace() + (Pdb) u + > <doctest test.test_pdb.test_pdb_where_command[1]>(2)f() + -> g(); + (Pdb) w + ... + <doctest test.test_pdb.test_pdb_where_command[3]>(8)<module>() + -> test_function() + <doctest test.test_pdb.test_pdb_where_command[2]>(2)test_function() + -> f() + > <doctest test.test_pdb.test_pdb_where_command[1]>(2)f() + -> g(); + <doctest test.test_pdb.test_pdb_where_command[0]>(2)g()->None + -> import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace() + (Pdb) continue + """ + +def test_convenience_variables(): + """Test convenience variables + + >>> def util_function(): + ... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace() + ... try: + ... raise Exception('test') + ... except: + ... pass + ... return 1 + + >>> def test_function(): + ... util_function() + + >>> with PdbTestInput([ # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE + ... '$_frame.f_lineno', # Check frame convenience variable + ... '$a = 10', # Set a convenience variable + ... '$a', # Print its value + ... 'p $a + 2', # Do some calculation + ... 'u', # Switch frame + ... '$_frame.f_lineno', # Make sure the frame changed + ... '$a', # Make sure the value persists + ... 'd', # Go back to the original frame + ... 'next', + ... '$a', # The value should be gone + ... 'next', + ... '$_exception', # Check exception convenience variable + ... 'next', + ... '$_exception', # Exception should be gone + ... 'return', + ... '$_retval', # Check return convenience variable + ... 'continue', + ... ]): + ... test_function() + > <doctest test.test_pdb.test_convenience_variables[0]>(3)util_function() + -> try: + (Pdb) $_frame.f_lineno + 3 + (Pdb) $a = 10 + (Pdb) $a + 10 + (Pdb) p $a + 2 + 12 + (Pdb) u + > <doctest test.test_pdb.test_convenience_variables[1]>(2)test_function() + -> util_function() + (Pdb) $_frame.f_lineno + 2 + (Pdb) $a + 10 + (Pdb) d + > <doctest test.test_pdb.test_convenience_variables[0]>(3)util_function() + -> try: + (Pdb) next + > <doctest test.test_pdb.test_convenience_variables[0]>(4)util_function() + -> raise Exception('test') + (Pdb) $a + *** KeyError: 'a' + (Pdb) next + Exception: test + > <doctest test.test_pdb.test_convenience_variables[0]>(4)util_function() + -> raise Exception('test') + (Pdb) $_exception + Exception('test') + (Pdb) next + > <doctest test.test_pdb.test_convenience_variables[0]>(5)util_function() + -> except: + (Pdb) $_exception + *** KeyError: '_exception' + (Pdb) return + --Return-- + > <doctest test.test_pdb.test_convenience_variables[0]>(7)util_function()->1 + -> return 1 + (Pdb) $_retval + 1 + (Pdb) continue + """ + def test_post_mortem(): """Test post mortem traceback debugging. @@ -1474,6 +1724,122 @@ def test_pdb_issue_gh_94215(): (Pdb) continue """ +def test_pdb_issue_gh_101673(): + """See GH-101673 + + Make sure ll won't revert local variable assignment + + >>> def test_function(): + ... a = 1 + ... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace() + + >>> with PdbTestInput([ # doctest: +NORMALIZE_WHITESPACE + ... '!a = 2', + ... 'll', + ... 'p a', + ... 'continue' + ... ]): + ... test_function() + --Return-- + > <doctest test.test_pdb.test_pdb_issue_gh_101673[0]>(3)test_function()->None + -> import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace() + (Pdb) !a = 2 + (Pdb) ll + 1 def test_function(): + 2 a = 1 + 3 -> import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace() + (Pdb) p a + 2 + (Pdb) continue + """ + +def test_pdb_issue_gh_103225(): + """See GH-103225 + + Make sure longlist uses 1-based line numbers in frames that correspond to a module + + >>> with PdbTestInput([ # doctest: +NORMALIZE_WHITESPACE + ... 'longlist', + ... 'continue' + ... ]): + ... a = 1 + ... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace() + ... b = 2 + > <doctest test.test_pdb.test_pdb_issue_gh_103225[0]>(7)<module>() + -> b = 2 + (Pdb) longlist + 1 with PdbTestInput([ # doctest: +NORMALIZE_WHITESPACE + 2 'longlist', + 3 'continue' + 4 ]): + 5 a = 1 + 6 import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace() + 7 -> b = 2 + (Pdb) continue + """ + +def test_pdb_issue_gh_101517(): + """See GH-101517 + + Make sure pdb doesn't crash when the exception is caught in a try/except* block + + >>> def test_function(): + ... try: + ... raise KeyError + ... except* Exception as e: + ... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace() + + >>> with PdbTestInput([ # doctest: +NORMALIZE_WHITESPACE + ... 'continue' + ... ]): + ... test_function() + --Return-- + > <doctest test.test_pdb.test_pdb_issue_gh_101517[0]>(None)test_function()->None + -> Warning: lineno is None + (Pdb) continue + """ + +def test_pdb_issue_gh_108976(): + """See GH-108976 + Make sure setting f_trace_opcodes = True won't crash pdb + >>> def test_function(): + ... import sys + ... sys._getframe().f_trace_opcodes = True + ... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace() + ... a = 1 + >>> with PdbTestInput([ # doctest: +NORMALIZE_WHITESPACE + ... 'continue' + ... ]): + ... test_function() + bdb.Bdb.dispatch: unknown debugging event: 'opcode' + > <doctest test.test_pdb.test_pdb_issue_gh_108976[0]>(5)test_function() + -> a = 1 + (Pdb) continue + """ + +def test_pdb_ambiguous_statements(): + """See GH-104301 + + Make sure that ambiguous statements prefixed by '!' are properly disambiguated + + >>> with PdbTestInput([ + ... '! n = 42', # disambiguated statement: reassign the name n + ... 'n', # advance the debugger into the print() + ... 'continue' + ... ]): + ... n = -1 + ... import pdb; pdb.Pdb(nosigint=True, readrc=False).set_trace() + ... print(f"The value of n is {n}") + > <doctest test.test_pdb.test_pdb_ambiguous_statements[0]>(8)<module>() + -> print(f"The value of n is {n}") + (Pdb) ! n = 42 + (Pdb) n + The value of n is 42 + > <doctest test.test_pdb.test_pdb_ambiguous_statements[0]>(1)<module>() + -> with PdbTestInput([ + (Pdb) continue + """ + @support.requires_subprocess() class PdbTestCase(unittest.TestCase): @@ -2150,6 +2516,12 @@ def bœr(): # verify that pdb found the source of the "frozen" function self.assertIn('x = "Sentinel string for gh-93696"', stdout, "Sentinel statement not found") + def test_non_utf8_encoding(self): + script_dir = os.path.join(os.path.dirname(__file__), 'encoded_modules') + for filename in os.listdir(script_dir): + if filename.endswith(".py"): + self._run_pdb([os.path.join(script_dir, filename)], 'q') + class ChecklineTests(unittest.TestCase): def setUp(self): linecache.clearcache() # Pdb.checkline() uses linecache.getline() diff --git a/Lib/test/test_peepholer.py b/Lib/test/test_peepholer.py index 241644ad..0aabce88 100644 --- a/Lib/test/test_peepholer.py +++ b/Lib/test/test_peepholer.py @@ -1,9 +1,11 @@ import dis from itertools import combinations, product +import sys import textwrap import unittest -from test.support.bytecode_helper import BytecodeTestCase +from test import support +from test.support.bytecode_helper import BytecodeTestCase, CfgOptimizationTestCase def compile_pattern_with_fast_locals(pattern): @@ -43,18 +45,14 @@ class TestTranforms(BytecodeTestCase): continue tgt = targets[instr.argval] # jump to unconditional jump - if tgt.opname in ('JUMP_ABSOLUTE', 'JUMP_FORWARD'): + if tgt.opname in ('JUMP_BACKWARD', 'JUMP_FORWARD'): self.fail(f'{instr.opname} at {instr.offset} ' f'jumps to {tgt.opname} at {tgt.offset}') # unconditional jump to RETURN_VALUE - if (instr.opname in ('JUMP_ABSOLUTE', 'JUMP_FORWARD') and + if (instr.opname in ('JUMP_BACKWARD', 'JUMP_FORWARD') and tgt.opname == 'RETURN_VALUE'): self.fail(f'{instr.opname} at {instr.offset} ' f'jumps to {tgt.opname} at {tgt.offset}') - # JUMP_IF_*_OR_POP jump to conditional jump - if '_OR_POP' in instr.opname and 'JUMP_IF_' in tgt.opname: - self.fail(f'{instr.opname} at {instr.offset} ' - f'jumps to {tgt.opname} at {tgt.offset}') def check_lnotab(self, code): "Check that the lnotab byte offsets are sensible." @@ -76,9 +74,8 @@ class TestTranforms(BytecodeTestCase): if not x == 2: del x self.assertNotInBytecode(unot, 'UNARY_NOT') - self.assertNotInBytecode(unot, 'POP_JUMP_FORWARD_IF_FALSE') - self.assertNotInBytecode(unot, 'POP_JUMP_BACKWARD_IF_FALSE') - self.assertInBytecode(unot, 'POP_JUMP_FORWARD_IF_TRUE') + self.assertNotInBytecode(unot, 'POP_JUMP_IF_FALSE') + self.assertInBytecode(unot, 'POP_JUMP_IF_TRUE') self.check_lnotab(unot) def test_elim_inversion_of_is_or_in(self): @@ -117,7 +114,7 @@ class TestTranforms(BytecodeTestCase): return None self.assertNotInBytecode(f, 'LOAD_GLOBAL') - self.assertInBytecode(f, 'LOAD_CONST', None) + self.assertInBytecode(f, 'RETURN_CONST', None) self.check_lnotab(f) def test_while_one(self): @@ -134,7 +131,7 @@ class TestTranforms(BytecodeTestCase): def test_pack_unpack(self): for line, elem in ( - ('a, = a,', 'LOAD_CONST',), + ('a, = a,', 'RETURN_CONST',), ('a, b = a, b', 'SWAP',), ('a, b, c = a, b, c', 'SWAP',), ): @@ -165,7 +162,7 @@ class TestTranforms(BytecodeTestCase): # One LOAD_CONST for the tuple, one for the None return value load_consts = [instr for instr in dis.get_instructions(code) if instr.opname == 'LOAD_CONST'] - self.assertEqual(len(load_consts), 2) + self.assertEqual(len(load_consts), 1) self.check_lnotab(code) # Bug 1053819: Tuple of constants misidentified when presented with: @@ -344,8 +341,6 @@ class TestTranforms(BytecodeTestCase): self.assertEqual(len(returns), 1) self.check_lnotab(f) - @unittest.skip("Following gh-92228 the return has two predecessors " - "and that prevents jump elimination.") def test_elim_jump_to_return(self): # JUMP_FORWARD to RETURN --> RETURN def f(cond, true_value, false_value): @@ -354,7 +349,7 @@ class TestTranforms(BytecodeTestCase): else false_value) self.check_jump_targets(f) self.assertNotInBytecode(f, 'JUMP_FORWARD') - self.assertNotInBytecode(f, 'JUMP_ABSOLUTE') + self.assertNotInBytecode(f, 'JUMP_BACKWARD') returns = [instr for instr in dis.get_instructions(f) if instr.opname == 'RETURN_VALUE'] self.assertEqual(len(returns), 2) @@ -374,7 +369,7 @@ class TestTranforms(BytecodeTestCase): self.check_lnotab(f) def test_elim_jump_to_uncond_jump2(self): - # POP_JUMP_IF_FALSE to JUMP_ABSOLUTE --> POP_JUMP_IF_FALSE to non-jump + # POP_JUMP_IF_FALSE to JUMP_BACKWARD --> POP_JUMP_IF_FALSE to non-jump def f(): while a: # Intentionally use two-line expression to test issue37213. @@ -386,38 +381,43 @@ class TestTranforms(BytecodeTestCase): def test_elim_jump_to_uncond_jump3(self): # Intentionally use two-line expressions to test issue37213. - # JUMP_IF_FALSE_OR_POP to JUMP_IF_FALSE_OR_POP --> JUMP_IF_FALSE_OR_POP to non-jump + # POP_JUMP_IF_FALSE to POP_JUMP_IF_FALSE --> POP_JUMP_IF_FALSE to non-jump def f(a, b, c): return ((a and b) and c) self.check_jump_targets(f) self.check_lnotab(f) - self.assertEqual(count_instr_recursively(f, 'JUMP_IF_FALSE_OR_POP'), 2) - # JUMP_IF_TRUE_OR_POP to JUMP_IF_TRUE_OR_POP --> JUMP_IF_TRUE_OR_POP to non-jump + self.assertEqual(count_instr_recursively(f, 'POP_JUMP_IF_FALSE'), 2) + # POP_JUMP_IF_TRUE to POP_JUMP_IF_TRUE --> POP_JUMP_IF_TRUE to non-jump def f(a, b, c): return ((a or b) or c) self.check_jump_targets(f) self.check_lnotab(f) - self.assertEqual(count_instr_recursively(f, 'JUMP_IF_TRUE_OR_POP'), 2) + self.assertEqual(count_instr_recursively(f, 'POP_JUMP_IF_TRUE'), 2) # JUMP_IF_FALSE_OR_POP to JUMP_IF_TRUE_OR_POP --> POP_JUMP_IF_FALSE to non-jump def f(a, b, c): return ((a and b) or c) self.check_jump_targets(f) self.check_lnotab(f) - self.assertNotInBytecode(f, 'JUMP_IF_FALSE_OR_POP') - self.assertInBytecode(f, 'JUMP_IF_TRUE_OR_POP') - self.assertInBytecode(f, 'POP_JUMP_FORWARD_IF_FALSE') - # JUMP_IF_TRUE_OR_POP to JUMP_IF_FALSE_OR_POP --> POP_JUMP_IF_TRUE to non-jump + self.assertEqual(count_instr_recursively(f, 'POP_JUMP_IF_FALSE'), 1) + self.assertEqual(count_instr_recursively(f, 'POP_JUMP_IF_TRUE'), 1) + # POP_JUMP_IF_TRUE to POP_JUMP_IF_FALSE --> POP_JUMP_IF_TRUE to non-jump def f(a, b, c): return ((a or b) and c) self.check_jump_targets(f) self.check_lnotab(f) - self.assertNotInBytecode(f, 'JUMP_IF_TRUE_OR_POP') - self.assertInBytecode(f, 'JUMP_IF_FALSE_OR_POP') - self.assertInBytecode(f, 'POP_JUMP_FORWARD_IF_TRUE') + self.assertEqual(count_instr_recursively(f, 'POP_JUMP_IF_FALSE'), 1) + self.assertEqual(count_instr_recursively(f, 'POP_JUMP_IF_TRUE'), 1) + + def test_elim_jump_to_uncond_jump4(self): + def f(): + for i in range(5): + if i > 3: + print(i) + self.check_jump_targets(f) def test_elim_jump_after_return1(self): # Eliminate dead code: jumps immediately after returns can't be reached @@ -431,7 +431,7 @@ class TestTranforms(BytecodeTestCase): return 5 return 6 self.assertNotInBytecode(f, 'JUMP_FORWARD') - self.assertNotInBytecode(f, 'JUMP_ABSOLUTE') + self.assertNotInBytecode(f, 'JUMP_BACKWARD') returns = [instr for instr in dis.get_instructions(f) if instr.opname == 'RETURN_VALUE'] self.assertLessEqual(len(returns), 6) @@ -523,6 +523,7 @@ class TestTranforms(BytecodeTestCase): return (y for x in a for y in [f(x)]) self.assertEqual(count_instr_recursively(genexpr, 'FOR_ITER'), 1) + @support.requires_resource('cpu') def test_format_combinations(self): flags = '-+ #0' testcases = [ @@ -677,5 +678,402 @@ class TestBuglets(unittest.TestCase): compile("while True or not spam: pass", "<test>", "exec") +class TestMarkingVariablesAsUnKnown(BytecodeTestCase): + + def setUp(self): + self.addCleanup(sys.settrace, sys.gettrace()) + sys.settrace(None) + + def test_load_fast_known_simple(self): + def f(): + x = 1 + y = x + x + self.assertInBytecode(f, 'LOAD_FAST') + + def test_load_fast_unknown_simple(self): + def f(): + if condition(): + x = 1 + print(x) + self.assertInBytecode(f, 'LOAD_FAST_CHECK') + self.assertNotInBytecode(f, 'LOAD_FAST') + + def test_load_fast_unknown_because_del(self): + def f(): + x = 1 + del x + print(x) + self.assertInBytecode(f, 'LOAD_FAST_CHECK') + self.assertNotInBytecode(f, 'LOAD_FAST') + + def test_load_fast_known_because_parameter(self): + def f1(x): + print(x) + self.assertInBytecode(f1, 'LOAD_FAST') + self.assertNotInBytecode(f1, 'LOAD_FAST_CHECK') + + def f2(*, x): + print(x) + self.assertInBytecode(f2, 'LOAD_FAST') + self.assertNotInBytecode(f2, 'LOAD_FAST_CHECK') + + def f3(*args): + print(args) + self.assertInBytecode(f3, 'LOAD_FAST') + self.assertNotInBytecode(f3, 'LOAD_FAST_CHECK') + + def f4(**kwargs): + print(kwargs) + self.assertInBytecode(f4, 'LOAD_FAST') + self.assertNotInBytecode(f4, 'LOAD_FAST_CHECK') + + def f5(x=0): + print(x) + self.assertInBytecode(f5, 'LOAD_FAST') + self.assertNotInBytecode(f5, 'LOAD_FAST_CHECK') + + def test_load_fast_known_because_already_loaded(self): + def f(): + if condition(): + x = 1 + print(x) + print(x) + self.assertInBytecode(f, 'LOAD_FAST_CHECK') + self.assertInBytecode(f, 'LOAD_FAST') + + def test_load_fast_known_multiple_branches(self): + def f(): + if condition(): + x = 1 + else: + x = 2 + print(x) + self.assertInBytecode(f, 'LOAD_FAST') + self.assertNotInBytecode(f, 'LOAD_FAST_CHECK') + + def test_load_fast_unknown_after_error(self): + def f(): + try: + res = 1 / 0 + except ZeroDivisionError: + pass + return res + # LOAD_FAST (known) still occurs in the no-exception branch. + # Assert that it doesn't occur in the LOAD_FAST_CHECK branch. + self.assertInBytecode(f, 'LOAD_FAST_CHECK') + + def test_load_fast_unknown_after_error_2(self): + def f(): + try: + 1 / 0 + except: + print(a, b, c, d, e, f, g) + a = b = c = d = e = f = g = 1 + self.assertInBytecode(f, 'LOAD_FAST_CHECK') + self.assertNotInBytecode(f, 'LOAD_FAST') + + def test_load_fast_too_many_locals(self): + # When there get to be too many locals to analyze completely, + # later locals are all converted to LOAD_FAST_CHECK, except + # when a store or prior load occurred in the same basicblock. + def f(): + a00 = a01 = a02 = a03 = a04 = a05 = a06 = a07 = a08 = a09 = 1 + a10 = a11 = a12 = a13 = a14 = a15 = a16 = a17 = a18 = a19 = 1 + a20 = a21 = a22 = a23 = a24 = a25 = a26 = a27 = a28 = a29 = 1 + a30 = a31 = a32 = a33 = a34 = a35 = a36 = a37 = a38 = a39 = 1 + a40 = a41 = a42 = a43 = a44 = a45 = a46 = a47 = a48 = a49 = 1 + a50 = a51 = a52 = a53 = a54 = a55 = a56 = a57 = a58 = a59 = 1 + a60 = a61 = a62 = a63 = a64 = a65 = a66 = a67 = a68 = a69 = 1 + a70 = a71 = a72 = a73 = a74 = a75 = a76 = a77 = a78 = a79 = 1 + del a72, a73 + print(a73) + print(a70, a71, a72, a73) + while True: + print(a00, a01, a62, a63) + print(a64, a65, a78, a79) + + for i in 0, 1, 62, 63: + # First 64 locals: analyze completely + self.assertInBytecode(f, 'LOAD_FAST', f"a{i:02}") + self.assertNotInBytecode(f, 'LOAD_FAST_CHECK', f"a{i:02}") + for i in 64, 65, 78, 79: + # Locals >=64 not in the same basicblock + self.assertInBytecode(f, 'LOAD_FAST_CHECK', f"a{i:02}") + self.assertNotInBytecode(f, 'LOAD_FAST', f"a{i:02}") + for i in 70, 71: + # Locals >=64 in the same basicblock + self.assertInBytecode(f, 'LOAD_FAST', f"a{i:02}") + self.assertNotInBytecode(f, 'LOAD_FAST_CHECK', f"a{i:02}") + # del statements should invalidate within basicblocks. + self.assertInBytecode(f, 'LOAD_FAST_CHECK', "a72") + self.assertNotInBytecode(f, 'LOAD_FAST', "a72") + # previous checked loads within a basicblock enable unchecked loads + self.assertInBytecode(f, 'LOAD_FAST_CHECK', "a73") + self.assertInBytecode(f, 'LOAD_FAST', "a73") + + def test_setting_lineno_no_undefined(self): + code = textwrap.dedent("""\ + def f(): + x = y = 2 + if not x: + return 4 + for i in range(55): + x + 6 + L = 7 + L = 8 + L = 9 + L = 10 + """) + ns = {} + exec(code, ns) + f = ns['f'] + self.assertInBytecode(f, "LOAD_FAST") + self.assertNotInBytecode(f, "LOAD_FAST_CHECK") + co_code = f.__code__.co_code + def trace(frame, event, arg): + if event == 'line' and frame.f_lineno == 9: + frame.f_lineno = 3 + sys.settrace(None) + return None + return trace + sys.settrace(trace) + result = f() + self.assertIsNone(result) + self.assertInBytecode(f, "LOAD_FAST") + self.assertNotInBytecode(f, "LOAD_FAST_CHECK") + self.assertEqual(f.__code__.co_code, co_code) + + def test_setting_lineno_one_undefined(self): + code = textwrap.dedent("""\ + def f(): + x = y = 2 + if not x: + return 4 + for i in range(55): + x + 6 + del x + L = 8 + L = 9 + L = 10 + """) + ns = {} + exec(code, ns) + f = ns['f'] + self.assertInBytecode(f, "LOAD_FAST") + self.assertNotInBytecode(f, "LOAD_FAST_CHECK") + co_code = f.__code__.co_code + def trace(frame, event, arg): + if event == 'line' and frame.f_lineno == 9: + frame.f_lineno = 3 + sys.settrace(None) + return None + return trace + e = r"assigning None to 1 unbound local" + with self.assertWarnsRegex(RuntimeWarning, e): + sys.settrace(trace) + result = f() + self.assertEqual(result, 4) + self.assertInBytecode(f, "LOAD_FAST") + self.assertNotInBytecode(f, "LOAD_FAST_CHECK") + self.assertEqual(f.__code__.co_code, co_code) + + def test_setting_lineno_two_undefined(self): + code = textwrap.dedent("""\ + def f(): + x = y = 2 + if not x: + return 4 + for i in range(55): + x + 6 + del x, y + L = 8 + L = 9 + L = 10 + """) + ns = {} + exec(code, ns) + f = ns['f'] + self.assertInBytecode(f, "LOAD_FAST") + self.assertNotInBytecode(f, "LOAD_FAST_CHECK") + co_code = f.__code__.co_code + def trace(frame, event, arg): + if event == 'line' and frame.f_lineno == 9: + frame.f_lineno = 3 + sys.settrace(None) + return None + return trace + e = r"assigning None to 2 unbound locals" + with self.assertWarnsRegex(RuntimeWarning, e): + sys.settrace(trace) + result = f() + self.assertEqual(result, 4) + self.assertInBytecode(f, "LOAD_FAST") + self.assertNotInBytecode(f, "LOAD_FAST_CHECK") + self.assertEqual(f.__code__.co_code, co_code) + + def make_function_with_no_checks(self): + code = textwrap.dedent("""\ + def f(): + x = 2 + L = 3 + L = 4 + L = 5 + if not L: + x + 7 + y = 2 + """) + ns = {} + exec(code, ns) + f = ns['f'] + self.assertInBytecode(f, "LOAD_FAST") + self.assertNotInBytecode(f, "LOAD_FAST_CHECK") + return f + + def test_deleting_local_warns_and_assigns_none(self): + f = self.make_function_with_no_checks() + co_code = f.__code__.co_code + def trace(frame, event, arg): + if event == 'line' and frame.f_lineno == 4: + del frame.f_locals["x"] + sys.settrace(None) + return None + return trace + e = r"assigning None to unbound local 'x'" + with self.assertWarnsRegex(RuntimeWarning, e): + sys.settrace(trace) + f() + self.assertInBytecode(f, "LOAD_FAST") + self.assertNotInBytecode(f, "LOAD_FAST_CHECK") + self.assertEqual(f.__code__.co_code, co_code) + + def test_modifying_local_does_not_add_check(self): + f = self.make_function_with_no_checks() + def trace(frame, event, arg): + if event == 'line' and frame.f_lineno == 4: + frame.f_locals["x"] = 42 + sys.settrace(None) + return None + return trace + sys.settrace(trace) + f() + self.assertInBytecode(f, "LOAD_FAST") + self.assertNotInBytecode(f, "LOAD_FAST_CHECK") + + def test_initializing_local_does_not_add_check(self): + f = self.make_function_with_no_checks() + def trace(frame, event, arg): + if event == 'line' and frame.f_lineno == 4: + frame.f_locals["y"] = 42 + sys.settrace(None) + return None + return trace + sys.settrace(trace) + f() + self.assertInBytecode(f, "LOAD_FAST") + self.assertNotInBytecode(f, "LOAD_FAST_CHECK") + + +class DirectCfgOptimizerTests(CfgOptimizationTestCase): + + def cfg_optimization_test(self, insts, expected_insts, + consts=None, expected_consts=None, + nlocals=0): + if expected_consts is None: + expected_consts = consts + opt_insts, opt_consts = self.get_optimized(insts, consts, nlocals) + expected_insts = self.normalize_insts(expected_insts) + self.assertInstructionsMatch(opt_insts, expected_insts) + self.assertEqual(opt_consts, expected_consts) + + def test_conditional_jump_forward_non_const_condition(self): + insts = [ + ('LOAD_NAME', 1, 11), + ('POP_JUMP_IF_TRUE', lbl := self.Label(), 12), + ('LOAD_CONST', 2, 13), + lbl, + ('LOAD_CONST', 3, 14), + ('RETURN_VALUE', 14), + ] + expected_insts = [ + ('LOAD_NAME', 1, 11), + ('POP_JUMP_IF_TRUE', lbl := self.Label(), 12), + ('LOAD_CONST', 1, 13), + lbl, + ('RETURN_CONST', 2, 14), + ] + self.cfg_optimization_test(insts, + expected_insts, + consts=[0, 1, 2, 3, 4], + expected_consts=[0, 2, 3]) + + def test_conditional_jump_forward_const_condition(self): + # The unreachable branch of the jump is removed, the jump + # becomes redundant and is replaced by a NOP (for the lineno) + + insts = [ + ('LOAD_CONST', 3, 11), + ('POP_JUMP_IF_TRUE', lbl := self.Label(), 12), + ('LOAD_CONST', 2, 13), + lbl, + ('LOAD_CONST', 3, 14), + ('RETURN_VALUE', 14), + ] + expected_insts = [ + ('NOP', 11), + ('NOP', 12), + ('RETURN_CONST', 1, 14), + ] + self.cfg_optimization_test(insts, + expected_insts, + consts=[0, 1, 2, 3, 4], + expected_consts=[0, 3]) + + def test_conditional_jump_backward_non_const_condition(self): + insts = [ + lbl1 := self.Label(), + ('LOAD_NAME', 1, 11), + ('POP_JUMP_IF_TRUE', lbl1, 12), + ('LOAD_NAME', 2, 13), + ('RETURN_VALUE', 13), + ] + expected = [ + lbl := self.Label(), + ('LOAD_NAME', 1, 11), + ('POP_JUMP_IF_TRUE', lbl, 12), + ('LOAD_NAME', 2, 13), + ('RETURN_VALUE', 13), + ] + self.cfg_optimization_test(insts, expected, consts=list(range(5))) + + def test_conditional_jump_backward_const_condition(self): + # The unreachable branch of the jump is removed + insts = [ + lbl1 := self.Label(), + ('LOAD_CONST', 3, 11), + ('POP_JUMP_IF_TRUE', lbl1, 12), + ('LOAD_CONST', 2, 13), + ('RETURN_VALUE', 13), + ] + expected_insts = [ + lbl := self.Label(), + ('NOP', 11), + ('JUMP', lbl, 12), + ] + self.cfg_optimization_test(insts, expected_insts, consts=list(range(5))) + + def test_no_unsafe_static_swap(self): + # We can't change order of two stores to the same location + insts = [ + ('LOAD_CONST', 0, 1), + ('LOAD_CONST', 1, 2), + ('LOAD_CONST', 2, 3), + ('SWAP', 3, 4), + ('STORE_FAST', 1, 4), + ('STORE_FAST', 1, 4), + ('POP_TOP', 0, 4), + ('RETURN_VALUE', 5) + ] + self.cfg_optimization_test(insts, insts, consts=list(range(3)), nlocals=1) + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_peg_generator/test_c_parser.py b/Lib/test/test_peg_generator/test_c_parser.py index d25bc112..f9105a9f 100644 --- a/Lib/test/test_peg_generator/test_c_parser.py +++ b/Lib/test/test_peg_generator/test_c_parser.py @@ -1,3 +1,5 @@ +import contextlib +import subprocess import sysconfig import textwrap import unittest @@ -8,7 +10,7 @@ from pathlib import Path from test import test_tools from test import support -from test.support import os_helper +from test.support import os_helper, import_helper from test.support.script_helper import assert_python_ok _py_cflags_nodist = sysconfig.get_config_var("PY_CFLAGS_NODIST") @@ -24,7 +26,6 @@ with test_tools.imports_under_tool("peg_generator"): generate_parser_c_extension, generate_c_parser_source, ) - from pegen.ast_dump import ast_dump TEST_TEMPLATE = """ @@ -73,9 +74,19 @@ unittest.main() @support.requires_subprocess() class TestCParser(unittest.TestCase): + _has_run = False + @classmethod def setUpClass(cls): - # When running under regtest, a seperate tempdir is used + if cls._has_run: + # Since gh-104798 (Use setuptools in peg-generator and reenable + # tests), this test case has been producing ref leaks. Initial + # debugging points to bug(s) in setuptools and/or importlib. + # See gh-105063 for more info. + raise unittest.SkipTest("gh-105063: can not rerun because of ref. leaks") + cls._has_run = True + + # When running under regtest, a separate tempdir is used # as the current directory and watched for left-overs. # Reusing that as the base for temporary directories # ensures everything is cleaned up properly and @@ -89,6 +100,16 @@ class TestCParser(unittest.TestCase): cls.library_dir = tempfile.mkdtemp(dir=cls.tmp_base) cls.addClassCleanup(shutil.rmtree, cls.library_dir) + with contextlib.ExitStack() as stack: + python_exe = stack.enter_context(support.setup_venv_with_pip_setuptools_wheel("venv")) + sitepackages = subprocess.check_output( + [python_exe, "-c", "import sysconfig; print(sysconfig.get_path('platlib'))"], + text=True, + ).strip() + stack.enter_context(import_helper.DirsOnSysPath(sitepackages)) + cls.addClassCleanup(stack.pop_all().close) + + @support.requires_venv_with_pip() def setUp(self): self._backup_config_vars = dict(sysconfig._CONFIG_VARS) cmd = support.missing_compiler_executable() diff --git a/Lib/test/test_peg_generator/test_pegen.py b/Lib/test/test_peg_generator/test_pegen.py index 30e992ed..d92da7b2 100644 --- a/Lib/test/test_peg_generator/test_pegen.py +++ b/Lib/test/test_peg_generator/test_pegen.py @@ -794,7 +794,7 @@ class TestPegen(unittest.TestCase): start: | "number" n=NUMBER { eval(n.string) } | "string" n=STRING { n.string } - | SOFT_KEYWORD l=NAME n=(NUMBER | NAME | STRING) { f"{l.string} = {n.string}"} + | SOFT_KEYWORD l=NAME n=(NUMBER | NAME | STRING) { l.string + " = " + n.string } """ parser_class = make_parser(grammar) self.assertEqual(parse_string("number 1", parser_class), 1) diff --git a/Lib/test/test_pep646_syntax.py b/Lib/test/test_pep646_syntax.py index 3ffa82dc..aac089b1 100644 --- a/Lib/test/test_pep646_syntax.py +++ b/Lib/test/test_pep646_syntax.py @@ -1,3 +1,6 @@ +import doctest +import unittest + doctests = """ Setup @@ -317,10 +320,10 @@ is *not* valid syntax.) __test__ = {'doctests' : doctests} -def test_main(verbose=False): - from test import support - from test import test_pep646_syntax - support.run_doctest(test_pep646_syntax, verbose) +def load_tests(loader, tests, pattern): + tests.addTest(doctest.DocTestSuite()) + return tests + if __name__ == "__main__": - test_main(verbose=True) + unittest.main() diff --git a/Lib/test/test_perf_profiler.py b/Lib/test/test_perf_profiler.py new file mode 100644 index 00000000..5418f9f3 --- /dev/null +++ b/Lib/test/test_perf_profiler.py @@ -0,0 +1,354 @@ +import unittest +import string +import subprocess +import sys +import sysconfig +import os +import pathlib +from test import support +from test.support.script_helper import ( + make_script, + assert_python_failure, + assert_python_ok, +) +from test.support.os_helper import temp_dir + + +if not support.has_subprocess_support: + raise unittest.SkipTest("test module requires subprocess") + + +def supports_trampoline_profiling(): + perf_trampoline = sysconfig.get_config_var("PY_HAVE_PERF_TRAMPOLINE") + if not perf_trampoline: + return False + return int(perf_trampoline) == 1 + + +if not supports_trampoline_profiling(): + raise unittest.SkipTest("perf trampoline profiling not supported") + + +class TestPerfTrampoline(unittest.TestCase): + def setUp(self): + super().setUp() + self.perf_files = set(pathlib.Path("/tmp/").glob("perf-*.map")) + + def tearDown(self) -> None: + super().tearDown() + files_to_delete = ( + set(pathlib.Path("/tmp/").glob("perf-*.map")) - self.perf_files + ) + for file in files_to_delete: + file.unlink() + + def test_trampoline_works(self): + code = """if 1: + def foo(): + pass + + def bar(): + foo() + + def baz(): + bar() + + baz() + """ + with temp_dir() as script_dir: + script = make_script(script_dir, "perftest", code) + with subprocess.Popen( + [sys.executable, "-Xperf", script], + text=True, + stderr=subprocess.PIPE, + stdout=subprocess.PIPE, + ) as process: + stdout, stderr = process.communicate() + + self.assertEqual(stderr, "") + self.assertEqual(stdout, "") + + perf_file = pathlib.Path(f"/tmp/perf-{process.pid}.map") + self.assertTrue(perf_file.exists()) + perf_file_contents = perf_file.read_text() + perf_lines = perf_file_contents.splitlines(); + expected_symbols = [f"py::foo:{script}", f"py::bar:{script}", f"py::baz:{script}"] + for expected_symbol in expected_symbols: + perf_line = next((line for line in perf_lines if expected_symbol in line), None) + self.assertIsNotNone(perf_line, f"Could not find {expected_symbol} in perf file") + perf_addr = perf_line.split(" ")[0] + self.assertFalse(perf_addr.startswith("0x"), "Address should not be prefixed with 0x") + self.assertTrue(set(perf_addr).issubset(string.hexdigits), "Address should contain only hex characters") + + def test_trampoline_works_with_forks(self): + code = """if 1: + import os, sys + + def foo_fork(): + pass + + def bar_fork(): + foo_fork() + + def baz_fork(): + bar_fork() + + def foo(): + pid = os.fork() + if pid == 0: + print(os.getpid()) + baz_fork() + else: + _, status = os.waitpid(-1, 0) + sys.exit(status) + + def bar(): + foo() + + def baz(): + bar() + + baz() + """ + with temp_dir() as script_dir: + script = make_script(script_dir, "perftest", code) + with subprocess.Popen( + [sys.executable, "-Xperf", script], + text=True, + stderr=subprocess.PIPE, + stdout=subprocess.PIPE, + ) as process: + stdout, stderr = process.communicate() + + self.assertEqual(process.returncode, 0) + self.assertEqual(stderr, "") + child_pid = int(stdout.strip()) + perf_file = pathlib.Path(f"/tmp/perf-{process.pid}.map") + perf_child_file = pathlib.Path(f"/tmp/perf-{child_pid}.map") + self.assertTrue(perf_file.exists()) + self.assertTrue(perf_child_file.exists()) + + perf_file_contents = perf_file.read_text() + self.assertIn(f"py::foo:{script}", perf_file_contents) + self.assertIn(f"py::bar:{script}", perf_file_contents) + self.assertIn(f"py::baz:{script}", perf_file_contents) + + child_perf_file_contents = perf_child_file.read_text() + self.assertIn(f"py::foo_fork:{script}", child_perf_file_contents) + self.assertIn(f"py::bar_fork:{script}", child_perf_file_contents) + self.assertIn(f"py::baz_fork:{script}", child_perf_file_contents) + + def test_sys_api(self): + code = """if 1: + import sys + def foo(): + pass + + def spam(): + pass + + def bar(): + sys.deactivate_stack_trampoline() + foo() + sys.activate_stack_trampoline("perf") + spam() + + def baz(): + bar() + + sys.activate_stack_trampoline("perf") + baz() + """ + with temp_dir() as script_dir: + script = make_script(script_dir, "perftest", code) + with subprocess.Popen( + [sys.executable, script], + text=True, + stderr=subprocess.PIPE, + stdout=subprocess.PIPE, + ) as process: + stdout, stderr = process.communicate() + + self.assertEqual(stderr, "") + self.assertEqual(stdout, "") + + perf_file = pathlib.Path(f"/tmp/perf-{process.pid}.map") + self.assertTrue(perf_file.exists()) + perf_file_contents = perf_file.read_text() + self.assertNotIn(f"py::foo:{script}", perf_file_contents) + self.assertIn(f"py::spam:{script}", perf_file_contents) + self.assertIn(f"py::bar:{script}", perf_file_contents) + self.assertIn(f"py::baz:{script}", perf_file_contents) + + def test_sys_api_with_existing_trampoline(self): + code = """if 1: + import sys + sys.activate_stack_trampoline("perf") + sys.activate_stack_trampoline("perf") + """ + assert_python_ok("-c", code) + + def test_sys_api_with_invalid_trampoline(self): + code = """if 1: + import sys + sys.activate_stack_trampoline("invalid") + """ + rc, out, err = assert_python_failure("-c", code) + self.assertIn("invalid backend: invalid", err.decode()) + + def test_sys_api_get_status(self): + code = """if 1: + import sys + sys.activate_stack_trampoline("perf") + assert sys.is_stack_trampoline_active() is True + sys.deactivate_stack_trampoline() + assert sys.is_stack_trampoline_active() is False + """ + assert_python_ok("-c", code) + + +def is_unwinding_reliable(): + cflags = sysconfig.get_config_var("PY_CORE_CFLAGS") + if not cflags: + return False + return "no-omit-frame-pointer" in cflags + + +def perf_command_works(): + try: + cmd = ["perf", "--help"] + stdout = subprocess.check_output(cmd, text=True) + except (subprocess.SubprocessError, OSError): + return False + + # perf version does not return a version number on Fedora. Use presence + # of "perf.data" in help as indicator that it's perf from Linux tools. + if "perf.data" not in stdout: + return False + + # Check that we can run a simple perf run + with temp_dir() as script_dir: + try: + output_file = script_dir + "/perf_output.perf" + cmd = ( + "perf", + "record", + "-g", + "--call-graph=fp", + "-o", + output_file, + "--", + sys.executable, + "-c", + 'print("hello")', + ) + stdout = subprocess.check_output( + cmd, cwd=script_dir, text=True, stderr=subprocess.STDOUT + ) + except (subprocess.SubprocessError, OSError): + return False + + if "hello" not in stdout: + return False + + return True + + +def run_perf(cwd, *args, **env_vars): + if env_vars: + env = os.environ.copy() + env.update(env_vars) + else: + env = None + output_file = cwd + "/perf_output.perf" + base_cmd = ("perf", "record", "-g", "--call-graph=fp", "-o", output_file, "--") + proc = subprocess.run( + base_cmd + args, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + env=env, + ) + if proc.returncode: + print(proc.stderr) + raise ValueError(f"Perf failed with return code {proc.returncode}") + + base_cmd = ("perf", "script") + proc = subprocess.run( + ("perf", "script", "-i", output_file), + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + env=env, + check=True, + ) + return proc.stdout.decode("utf-8", "replace"), proc.stderr.decode( + "utf-8", "replace" + ) + + +@unittest.skipUnless(perf_command_works(), "perf command doesn't work") +@unittest.skipUnless(is_unwinding_reliable(), "Unwinding is unreliable") +@support.skip_if_sanitizer(address=True, memory=True, ub=True) +class TestPerfProfiler(unittest.TestCase): + def setUp(self): + super().setUp() + self.perf_files = set(pathlib.Path("/tmp/").glob("perf-*.map")) + + def tearDown(self) -> None: + super().tearDown() + files_to_delete = ( + set(pathlib.Path("/tmp/").glob("perf-*.map")) - self.perf_files + ) + for file in files_to_delete: + file.unlink() + + def test_python_calls_appear_in_the_stack_if_perf_activated(self): + with temp_dir() as script_dir: + code = """if 1: + def foo(n): + x = 0 + for i in range(n): + x += i + + def bar(n): + foo(n) + + def baz(n): + bar(n) + + baz(10000000) + """ + script = make_script(script_dir, "perftest", code) + stdout, stderr = run_perf(script_dir, sys.executable, "-Xperf", script) + self.assertEqual(stderr, "") + + self.assertIn(f"py::foo:{script}", stdout) + self.assertIn(f"py::bar:{script}", stdout) + self.assertIn(f"py::baz:{script}", stdout) + + def test_python_calls_do_not_appear_in_the_stack_if_perf_activated(self): + with temp_dir() as script_dir: + code = """if 1: + def foo(n): + x = 0 + for i in range(n): + x += i + + def bar(n): + foo(n) + + def baz(n): + bar(n) + + baz(10000000) + """ + script = make_script(script_dir, "perftest", code) + stdout, stderr = run_perf(script_dir, sys.executable, script) + self.assertEqual(stderr, "") + + self.assertNotIn(f"py::foo:{script}", stdout) + self.assertNotIn(f"py::bar:{script}", stdout) + self.assertNotIn(f"py::baz:{script}", stdout) + + +if __name__ == "__main__": + unittest.main() diff --git a/Lib/test/test_perfmaps.py b/Lib/test/test_perfmaps.py new file mode 100644 index 00000000..a17adb89 --- /dev/null +++ b/Lib/test/test_perfmaps.py @@ -0,0 +1,19 @@ +import os +import sys +import unittest + +from _testinternalcapi import perf_map_state_teardown, write_perf_map_entry + +if sys.platform != 'linux': + raise unittest.SkipTest('Linux only') + + +class TestPerfMapWriting(unittest.TestCase): + def test_write_perf_map_entry(self): + self.assertEqual(write_perf_map_entry(0x1234, 5678, "entry1"), 0) + self.assertEqual(write_perf_map_entry(0x2345, 6789, "entry2"), 0) + with open(f"/tmp/perf-{os.getpid()}.map") as f: + perf_file_contents = f.read() + self.assertIn("1234 162e entry1", perf_file_contents) + self.assertIn("2345 1a85 entry2", perf_file_contents) + perf_map_state_teardown() diff --git a/Lib/test/test_pickle.py b/Lib/test/test_pickle.py index 44fdca7a..1a55da39 100644 --- a/Lib/test/test_pickle.py +++ b/Lib/test/test_pickle.py @@ -293,6 +293,34 @@ if has_c_implementation: pass pickler_class = CustomCPicklerClass + @support.cpython_only + class HeapTypesTests(unittest.TestCase): + def setUp(self): + pickler = _pickle.Pickler(io.BytesIO()) + unpickler = _pickle.Unpickler(io.BytesIO()) + + self._types = ( + _pickle.Pickler, + _pickle.Unpickler, + type(pickler.memo), + type(unpickler.memo), + + # We cannot test the _pickle.Pdata; + # there's no way to get to it. + ) + + def test_have_gc(self): + import gc + for tp in self._types: + with self.subTest(tp=tp): + self.assertTrue(gc.is_tracked(tp)) + + def test_immutable(self): + for tp in self._types: + with self.subTest(tp=tp): + with self.assertRaisesRegex(TypeError, "immutable"): + tp.foo = "bar" + @support.cpython_only class SizeofTests(unittest.TestCase): check_sizeof = support.check_sizeof @@ -533,6 +561,8 @@ class CompatPickleTests(unittest.TestCase): def test_multiprocessing_exceptions(self): module = import_helper.import_module('multiprocessing.context') for name, exc in get_exceptions(module): + if issubclass(exc, Warning): + continue with self.subTest(name): self.assertEqual(reverse_mapping('multiprocessing.context', name), ('multiprocessing', name)) diff --git a/Lib/test/test_pkgutil.py b/Lib/test/test_pkgutil.py index 0cc99e0c..6fcd7263 100644 --- a/Lib/test/test_pkgutil.py +++ b/Lib/test/test_pkgutil.py @@ -1,6 +1,6 @@ from pathlib import Path from test.support.import_helper import unload, CleanImport -from test.support.warnings_helper import check_warnings +from test.support.warnings_helper import check_warnings, ignore_warnings import unittest import sys import importlib @@ -429,7 +429,7 @@ class ExtendPathTests(unittest.TestCase): importers = list(iter_importers(fullname)) expected_importer = get_importer(pathitem) for finder in importers: - spec = pkgutil._get_spec(finder, fullname) + spec = finder.find_spec(fullname) loader = spec.loader try: loader = loader.loader @@ -441,7 +441,7 @@ class ExtendPathTests(unittest.TestCase): self.assertEqual(finder, expected_importer) self.assertIsInstance(loader, importlib.machinery.SourceFileLoader) - self.assertIsNone(pkgutil._get_spec(finder, pkgname)) + self.assertIsNone(finder.find_spec(pkgname)) with self.assertRaises(ImportError): list(iter_importers('invalid.module')) @@ -535,39 +535,18 @@ class ImportlibMigrationTests(unittest.TestCase): # PEP 302 emulation in this module is in the process of being # deprecated in favour of importlib proper - def check_deprecated(self): - return check_warnings( - ("This emulation is deprecated and slated for removal in " - "Python 3.12; use 'importlib' instead", - DeprecationWarning)) - - def test_importer_deprecated(self): - with self.check_deprecated(): - pkgutil.ImpImporter("") - - def test_loader_deprecated(self): - with self.check_deprecated(): - pkgutil.ImpLoader("", "", "", "") - - def test_get_loader_avoids_emulation(self): - with check_warnings() as w: - self.assertIsNotNone(pkgutil.get_loader("sys")) - self.assertIsNotNone(pkgutil.get_loader("os")) - self.assertIsNotNone(pkgutil.get_loader("test.support")) - self.assertEqual(len(w.warnings), 0) - @unittest.skipIf(__name__ == '__main__', 'not compatible with __main__') + @ignore_warnings(category=DeprecationWarning) def test_get_loader_handles_missing_loader_attribute(self): global __loader__ this_loader = __loader__ del __loader__ try: - with check_warnings() as w: - self.assertIsNotNone(pkgutil.get_loader(__name__)) - self.assertEqual(len(w.warnings), 0) + self.assertIsNotNone(pkgutil.get_loader(__name__)) finally: __loader__ = this_loader + @ignore_warnings(category=DeprecationWarning) def test_get_loader_handles_missing_spec_attribute(self): name = 'spam' mod = type(sys)(name) @@ -577,6 +556,7 @@ class ImportlibMigrationTests(unittest.TestCase): loader = pkgutil.get_loader(name) self.assertIsNone(loader) + @ignore_warnings(category=DeprecationWarning) def test_get_loader_handles_spec_attribute_none(self): name = 'spam' mod = type(sys)(name) @@ -586,6 +566,7 @@ class ImportlibMigrationTests(unittest.TestCase): loader = pkgutil.get_loader(name) self.assertIsNone(loader) + @ignore_warnings(category=DeprecationWarning) def test_get_loader_None_in_sys_modules(self): name = 'totally bogus' sys.modules[name] = None @@ -595,18 +576,26 @@ class ImportlibMigrationTests(unittest.TestCase): del sys.modules[name] self.assertIsNone(loader) + def test_get_loader_is_deprecated(self): + with check_warnings( + (r".*\bpkgutil.get_loader\b.*", DeprecationWarning), + ): + res = pkgutil.get_loader("sys") + self.assertIsNotNone(res) + + def test_find_loader_is_deprecated(self): + with check_warnings( + (r".*\bpkgutil.find_loader\b.*", DeprecationWarning), + ): + res = pkgutil.find_loader("sys") + self.assertIsNotNone(res) + + @ignore_warnings(category=DeprecationWarning) def test_find_loader_missing_module(self): name = 'totally bogus' loader = pkgutil.find_loader(name) self.assertIsNone(loader) - def test_find_loader_avoids_emulation(self): - with check_warnings() as w: - self.assertIsNotNone(pkgutil.find_loader("sys")) - self.assertIsNotNone(pkgutil.find_loader("os")) - self.assertIsNotNone(pkgutil.find_loader("test.support")) - self.assertEqual(len(w.warnings), 0) - def test_get_importer_avoids_emulation(self): # We use an illegal path so *none* of the path hooks should fire with check_warnings() as w: diff --git a/Lib/test/test_platform.py b/Lib/test/test_platform.py index c9f27575..21697335 100644 --- a/Lib/test/test_platform.py +++ b/Lib/test/test_platform.py @@ -123,10 +123,6 @@ class PlatformTest(unittest.TestCase): for input, output in ( ('2.4.3 (#1, Jun 21 2006, 13:54:21) \n[GCC 3.3.4 (pre 3.3.5 20040809)]', ('CPython', '2.4.3', '', '', '1', 'Jun 21 2006 13:54:21', 'GCC 3.3.4 (pre 3.3.5 20040809)')), - ('IronPython 1.0.60816 on .NET 2.0.50727.42', - ('IronPython', '1.0.60816', '', '', '', '', '.NET 2.0.50727.42')), - ('IronPython 1.0 (1.0.61005.1977) on .NET 2.0.50727.42', - ('IronPython', '1.0.0', '', '', '', '', '.NET 2.0.50727.42')), ('2.4.3 (truncation, date, t) \n[GCC]', ('CPython', '2.4.3', '', '', 'truncation', 'date t', 'GCC')), ('2.4.3 (truncation, date, ) \n[GCC]', @@ -161,20 +157,11 @@ class PlatformTest(unittest.TestCase): ('r261:67515', 'Dec 6 2008 15:26:00'), 'GCC 4.0.1 (Apple Computer, Inc. build 5370)'), - ("IronPython 2.0 (2.0.0.0) on .NET 2.0.50727.3053", None, "cli") + ("3.10.8 (tags/v3.10.8:aaaf517424, Feb 14 2023, 16:28:12) [GCC 9.4.0]", + None, "linux") : - ("IronPython", "2.0.0", "", "", ("", ""), - ".NET 2.0.50727.3053"), - - ("2.6.1 (IronPython 2.6.1 (2.6.10920.0) on .NET 2.0.50727.1433)", None, "cli") - : - ("IronPython", "2.6.1", "", "", ("", ""), - ".NET 2.0.50727.1433"), - - ("2.7.4 (IronPython 2.7.4 (2.7.0.40) on Mono 4.0.30319.1 (32-bit))", None, "cli") - : - ("IronPython", "2.7.4", "", "", ("", ""), - "Mono 4.0.30319.1 (32-bit)"), + ('CPython', '3.10.8', '', '', + ('tags/v3.10.8:aaaf517424', 'Feb 14 2023 16:28:12'), 'GCC 9.4.0'), ("2.5 (trunk:6107, Mar 26 2009, 13:02:18) \n[Java HotSpot(TM) Client VM (\"Apple Computer, Inc.\")]", ('Jython', 'trunk', '6107'), "java1.5.0_16") @@ -205,6 +192,9 @@ class PlatformTest(unittest.TestCase): self.assertEqual(platform.python_build(), info[4]) self.assertEqual(platform.python_compiler(), info[5]) + with self.assertRaises(ValueError): + platform._sys_version('2. 4.3 (truncation) \n[GCC]') + def test_system_alias(self): res = platform.system_alias( platform.system(), @@ -229,6 +219,14 @@ class PlatformTest(unittest.TestCase): self.assertEqual(res[-1], res.processor) self.assertEqual(len(res), 6) + @unittest.skipUnless(sys.platform.startswith('win'), "windows only test") + def test_uname_win32_without_wmi(self): + def raises_oserror(*a): + raise OSError() + + with support.swap_attr(platform, '_wmi_query', raises_oserror): + self.test_uname() + def test_uname_cast_to_tuple(self): res = platform.uname() expected = ( @@ -297,24 +295,31 @@ class PlatformTest(unittest.TestCase): # on 64 bit Windows: if PROCESSOR_ARCHITEW6432 exists we should be # using it, per # http://blogs.msdn.com/david.wang/archive/2006/03/26/HOWTO-Detect-Process-Bitness.aspx - try: + + # We also need to suppress WMI checks, as those are reliable and + # overrule the environment variables + def raises_oserror(*a): + raise OSError() + + with support.swap_attr(platform, '_wmi_query', raises_oserror): with os_helper.EnvironmentVarGuard() as environ: - if 'PROCESSOR_ARCHITEW6432' in environ: - del environ['PROCESSOR_ARCHITEW6432'] - environ['PROCESSOR_ARCHITECTURE'] = 'foo' - platform._uname_cache = None - system, node, release, version, machine, processor = platform.uname() - self.assertEqual(machine, 'foo') - environ['PROCESSOR_ARCHITEW6432'] = 'bar' - platform._uname_cache = None - system, node, release, version, machine, processor = platform.uname() - self.assertEqual(machine, 'bar') - finally: - platform._uname_cache = None + try: + if 'PROCESSOR_ARCHITEW6432' in environ: + del environ['PROCESSOR_ARCHITEW6432'] + environ['PROCESSOR_ARCHITECTURE'] = 'foo' + platform._uname_cache = None + system, node, release, version, machine, processor = platform.uname() + self.assertEqual(machine, 'foo') + environ['PROCESSOR_ARCHITEW6432'] = 'bar' + platform._uname_cache = None + system, node, release, version, machine, processor = platform.uname() + self.assertEqual(machine, 'bar') + finally: + platform._uname_cache = None def test_java_ver(self): res = platform.java_ver() - if sys.platform == 'java': + if sys.platform == 'java': # Is never actually checked in CI self.assertTrue(all(res)) def test_win32_ver(self): diff --git a/Lib/test/test_plistlib.py b/Lib/test/test_plistlib.py index 6b457440..b08ababa 100644 --- a/Lib/test/test_plistlib.py +++ b/Lib/test/test_plistlib.py @@ -925,7 +925,7 @@ class TestBinaryPlistlib(unittest.TestCase): # Issue #26709: 32-bit timestamp out of range for ts in -2**31-1, 2**31: with self.subTest(ts=ts): - d = (datetime.datetime.utcfromtimestamp(0) + + d = (datetime.datetime(1970, 1, 1, 0, 0) + datetime.timedelta(seconds=ts)) data = plistlib.dumps(d, fmt=plistlib.FMT_BINARY) self.assertEqual(plistlib.loads(data), d) diff --git a/Lib/test/test_poll.py b/Lib/test/test_poll.py index 02165a02..1847ae95 100644 --- a/Lib/test/test_poll.py +++ b/Lib/test/test_poll.py @@ -8,7 +8,7 @@ import threading import time import unittest from test.support import ( - cpython_only, requires_subprocess, requires_working_socket + cpython_only, requires_subprocess, requires_working_socket, requires_resource ) from test.support import threading_helper from test.support.os_helper import TESTFN @@ -124,6 +124,7 @@ class PollTests(unittest.TestCase): # select(), modified to use poll() instead. @requires_subprocess() + @requires_resource('walltime') def test_poll2(self): cmd = 'for i in 0 1 2 3 4 5 6 7 8 9; do echo testing...; sleep 1; done' proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, diff --git a/Lib/test/test_poplib.py b/Lib/test/test_poplib.py index 5ad92024..fa41ba0b 100644 --- a/Lib/test/test_poplib.py +++ b/Lib/test/test_poplib.py @@ -15,11 +15,8 @@ from test import support as test_support from test.support import hashlib_helper from test.support import socket_helper from test.support import threading_helper -from test.support import warnings_helper - - -asynchat = warnings_helper.import_deprecated('asynchat') -asyncore = warnings_helper.import_deprecated('asyncore') +from test.support import asynchat +from test.support import asyncore test_support.requires_working_socket(module=True) @@ -425,13 +422,6 @@ class TestPOP3_SSLClass(TestPOP3Class): ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) ctx.check_hostname = False ctx.verify_mode = ssl.CERT_NONE - self.assertRaises(ValueError, poplib.POP3_SSL, self.server.host, - self.server.port, keyfile=CERTFILE, context=ctx) - self.assertRaises(ValueError, poplib.POP3_SSL, self.server.host, - self.server.port, certfile=CERTFILE, context=ctx) - self.assertRaises(ValueError, poplib.POP3_SSL, self.server.host, - self.server.port, keyfile=CERTFILE, - certfile=CERTFILE, context=ctx) self.client.quit() self.client = poplib.POP3_SSL(self.server.host, self.server.port, diff --git a/Lib/test/test_positional_only_arg.py b/Lib/test/test_positional_only_arg.py index 0a9503e2..1a193814 100644 --- a/Lib/test/test_positional_only_arg.py +++ b/Lib/test/test_positional_only_arg.py @@ -23,10 +23,11 @@ class PositionalOnlyTestCase(unittest.TestCase): compile(codestr + "\n", "<test>", "single") def test_invalid_syntax_errors(self): - check_syntax_error(self, "def f(a, b = 5, /, c): pass", "non-default argument follows default argument") - check_syntax_error(self, "def f(a = 5, b, /, c): pass", "non-default argument follows default argument") - check_syntax_error(self, "def f(a = 5, b=1, /, c, *, d=2): pass", "non-default argument follows default argument") - check_syntax_error(self, "def f(a = 5, b, /): pass", "non-default argument follows default argument") + check_syntax_error(self, "def f(a, b = 5, /, c): pass", "parameter without a default follows parameter with a default") + check_syntax_error(self, "def f(a = 5, b, /, c): pass", "parameter without a default follows parameter with a default") + check_syntax_error(self, "def f(a = 5, b=1, /, c, *, d=2): pass", "parameter without a default follows parameter with a default") + check_syntax_error(self, "def f(a = 5, b, /): pass", "parameter without a default follows parameter with a default") + check_syntax_error(self, "def f(a, /, b = 5, c): pass", "parameter without a default follows parameter with a default") check_syntax_error(self, "def f(*args, /): pass") check_syntax_error(self, "def f(*args, a, /): pass") check_syntax_error(self, "def f(**kwargs, /): pass") @@ -44,10 +45,11 @@ class PositionalOnlyTestCase(unittest.TestCase): check_syntax_error(self, "def f(a, *, c, /, d, e): pass") def test_invalid_syntax_errors_async(self): - check_syntax_error(self, "async def f(a, b = 5, /, c): pass", "non-default argument follows default argument") - check_syntax_error(self, "async def f(a = 5, b, /, c): pass", "non-default argument follows default argument") - check_syntax_error(self, "async def f(a = 5, b=1, /, c, d=2): pass", "non-default argument follows default argument") - check_syntax_error(self, "async def f(a = 5, b, /): pass", "non-default argument follows default argument") + check_syntax_error(self, "async def f(a, b = 5, /, c): pass", "parameter without a default follows parameter with a default") + check_syntax_error(self, "async def f(a = 5, b, /, c): pass", "parameter without a default follows parameter with a default") + check_syntax_error(self, "async def f(a = 5, b=1, /, c, d=2): pass", "parameter without a default follows parameter with a default") + check_syntax_error(self, "async def f(a = 5, b, /): pass", "parameter without a default follows parameter with a default") + check_syntax_error(self, "async def f(a, /, b = 5, c): pass", "parameter without a default follows parameter with a default") check_syntax_error(self, "async def f(*args, /): pass") check_syntax_error(self, "async def f(*args, a, /): pass") check_syntax_error(self, "async def f(**kwargs, /): pass") @@ -231,9 +233,11 @@ class PositionalOnlyTestCase(unittest.TestCase): self.assertEqual(x(1, 2), 3) def test_invalid_syntax_lambda(self): - check_syntax_error(self, "lambda a, b = 5, /, c: None", "non-default argument follows default argument") - check_syntax_error(self, "lambda a = 5, b, /, c: None", "non-default argument follows default argument") - check_syntax_error(self, "lambda a = 5, b, /: None", "non-default argument follows default argument") + check_syntax_error(self, "lambda a, b = 5, /, c: None", "parameter without a default follows parameter with a default") + check_syntax_error(self, "lambda a = 5, b, /, c: None", "parameter without a default follows parameter with a default") + check_syntax_error(self, "lambda a = 5, b=1, /, c, *, d=2: None", "parameter without a default follows parameter with a default") + check_syntax_error(self, "lambda a = 5, b, /: None", "parameter without a default follows parameter with a default") + check_syntax_error(self, "lambda a, /, b = 5, c: None", "parameter without a default follows parameter with a default") check_syntax_error(self, "lambda *args, /: None") check_syntax_error(self, "lambda *args, a, /: None") check_syntax_error(self, "lambda **kwargs, /: None") diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py index e643d8e5..444f8abe 100644 --- a/Lib/test/test_posix.py +++ b/Lib/test/test_posix.py @@ -231,6 +231,9 @@ class PosixTester(unittest.TestCase): with self.assertRaises(TypeError, msg="Invalid arg was allowed"): # Ensure a combination of valid and invalid is an error. os.register_at_fork(before=None, after_in_parent=lambda: 3) + with self.assertRaises(TypeError, msg="At least one argument is required"): + # when no arg is passed + os.register_at_fork() with self.assertRaises(TypeError, msg="Invalid arg was allowed"): # Ensure a combination of valid and invalid is an error. os.register_at_fork(before=lambda: None, after_in_child='') @@ -634,7 +637,7 @@ class PosixTester(unittest.TestCase): self.assertTrue(posix.stat(os_helper.TESTFN)) self.assertTrue(posix.stat(os.fsencode(os_helper.TESTFN))) - self.assertWarnsRegex(DeprecationWarning, + self.assertRaisesRegex(TypeError, 'should be string, bytes, os.PathLike or integer, not', posix.stat, bytearray(os.fsencode(os_helper.TESTFN))) self.assertRaisesRegex(TypeError, @@ -841,11 +844,8 @@ class PosixTester(unittest.TestCase): def test_listdir_bytes_like(self): for cls in bytearray, memoryview: - with self.assertWarns(DeprecationWarning): - names = posix.listdir(cls(b'.')) - self.assertIn(os.fsencode(os_helper.TESTFN), names) - for name in names: - self.assertIs(type(name), bytes) + with self.assertRaises(TypeError): + posix.listdir(cls(b'.')) @unittest.skipUnless(posix.listdir in os.supports_fd, "test needs fd support for posix.listdir()") @@ -1649,12 +1649,6 @@ class _PosixSpawnMixin: ) support.wait_process(pid, exitcode=0) - def test_resetids_wrong_type(self): - with self.assertRaises(TypeError): - self.spawn_func(sys.executable, - [sys.executable, "-c", "pass"], - os.environ, resetids=None) - def test_setpgroup(self): pid = self.spawn_func( sys.executable, @@ -2194,6 +2188,53 @@ class TestPosixWeaklinking(unittest.TestCase): os.utime("path", dir_fd=0) +class NamespacesTests(unittest.TestCase): + """Tests for os.unshare() and os.setns().""" + + @unittest.skipUnless(hasattr(os, 'unshare'), 'needs os.unshare()') + @unittest.skipUnless(hasattr(os, 'setns'), 'needs os.setns()') + @unittest.skipUnless(os.path.exists('/proc/self/ns/uts'), 'need /proc/self/ns/uts') + @support.requires_linux_version(3, 0, 0) + def test_unshare_setns(self): + code = """if 1: + import errno + import os + import sys + fd = os.open('/proc/self/ns/uts', os.O_RDONLY) + try: + original = os.readlink('/proc/self/ns/uts') + try: + os.unshare(os.CLONE_NEWUTS) + except OSError as e: + if e.errno == errno.ENOSPC: + # skip test if limit is exceeded + sys.exit() + raise + new = os.readlink('/proc/self/ns/uts') + if original == new: + raise Exception('os.unshare failed') + os.setns(fd, os.CLONE_NEWUTS) + restored = os.readlink('/proc/self/ns/uts') + if original != restored: + raise Exception('os.setns failed') + except PermissionError: + # The calling process did not have the required privileges + # for this operation + pass + except OSError as e: + # Skip the test on these errors: + # - ENOSYS: syscall not available + # - EINVAL: kernel was not configured with the CONFIG_UTS_NS option + # - ENOMEM: not enough memory + if e.errno not in (errno.ENOSYS, errno.EINVAL, errno.ENOMEM): + raise + finally: + os.close(fd) + """ + + assert_python_ok("-c", code) + + def tearDownModule(): support.reap_children() diff --git a/Lib/test/test_posixpath.py b/Lib/test/test_posixpath.py index 8a1dd131..9be4640f 100644 --- a/Lib/test/test_posixpath.py +++ b/Lib/test/test_posixpath.py @@ -115,6 +115,32 @@ class PosixPathTest(unittest.TestCase): self.splitextTest("........", "........", "") self.splitextTest("", "", "") + def test_splitroot(self): + f = posixpath.splitroot + self.assertEqual(f(''), ('', '', '')) + self.assertEqual(f('a'), ('', '', 'a')) + self.assertEqual(f('a/b'), ('', '', 'a/b')) + self.assertEqual(f('a/b/'), ('', '', 'a/b/')) + self.assertEqual(f('/a'), ('', '/', 'a')) + self.assertEqual(f('/a/b'), ('', '/', 'a/b')) + self.assertEqual(f('/a/b/'), ('', '/', 'a/b/')) + # The root is collapsed when there are redundant slashes + # except when there are exactly two leading slashes, which + # is a special case in POSIX. + self.assertEqual(f('//a'), ('', '//', 'a')) + self.assertEqual(f('///a'), ('', '/', '//a')) + self.assertEqual(f('///a/b'), ('', '/', '//a/b')) + # Paths which look like NT paths aren't treated specially. + self.assertEqual(f('c:/a/b'), ('', '', 'c:/a/b')) + self.assertEqual(f('\\/a/b'), ('', '', '\\/a/b')) + self.assertEqual(f('\\a\\b'), ('', '', '\\a\\b')) + # Byte paths are supported + self.assertEqual(f(b''), (b'', b'', b'')) + self.assertEqual(f(b'a'), (b'', b'', b'a')) + self.assertEqual(f(b'/a'), (b'', b'/', b'a')) + self.assertEqual(f(b'//a'), (b'', b'//', b'a')) + self.assertEqual(f(b'///a'), (b'', b'/', b'//a')) + def test_isabs(self): self.assertIs(posixpath.isabs(""), False) self.assertIs(posixpath.isabs("/"), True) @@ -244,6 +270,9 @@ class PosixPathTest(unittest.TestCase): finally: os.lstat = save_lstat + def test_isjunction(self): + self.assertFalse(posixpath.isjunction(ABSTFN)) + def test_expanduser(self): self.assertEqual(posixpath.expanduser("foo"), "foo") self.assertEqual(posixpath.expanduser(b"foo"), b"foo") @@ -749,6 +778,9 @@ class PathLikeTests(unittest.TestCase): def test_path_splitdrive(self): self.assertPathEqual(self.path.splitdrive) + def test_path_splitroot(self): + self.assertPathEqual(self.path.splitroot) + def test_path_basename(self): self.assertPathEqual(self.path.basename) diff --git a/Lib/test/test_pow.py b/Lib/test/test_pow.py index 5cea9ceb..eeb482ec 100644 --- a/Lib/test/test_pow.py +++ b/Lib/test/test_pow.py @@ -19,12 +19,11 @@ class PowTest(unittest.TestCase): self.assertEqual(pow(2, i), pow2) if i != 30 : pow2 = pow2*2 - for othertype in (int,): - for i in list(range(-10, 0)) + list(range(1, 10)): - ii = type(i) - for j in range(1, 11): - jj = -othertype(j) - pow(ii, jj) + for i in list(range(-10, 0)) + list(range(1, 10)): + ii = type(i) + inv = pow(ii, -1) # inverse of ii + for jj in range(-10, 0): + self.assertAlmostEqual(pow(ii, jj), pow(inv, -jj)) for othertype in int, float: for i in range(1, 100): diff --git a/Lib/test/test_pprint.py b/Lib/test/test_pprint.py index c7b98939..6ea7e7db 100644 --- a/Lib/test/test_pprint.py +++ b/Lib/test/test_pprint.py @@ -203,7 +203,7 @@ class QueryTestCase(unittest.TestCase): def test_unreadable(self): # Not recursive but not readable anyway pp = pprint.PrettyPrinter() - for unreadable in type(3), pprint, pprint.isrecursive: + for unreadable in object(), int, pprint, pprint.isrecursive: # module-level convenience functions self.assertFalse(pprint.isrecursive(unreadable), "expected not isrecursive for %r" % (unreadable,)) diff --git a/Lib/test/test_profile.py b/Lib/test/test_profile.py index d97fe447..a1dfc9ab 100644 --- a/Lib/test/test_profile.py +++ b/Lib/test/test_profile.py @@ -178,7 +178,7 @@ _ProfileOutput['print_stats'] = """\ 8 63.976 7.997 79.960 9.995 profilee.py:98(subhelper)""" _ProfileOutput['print_callers'] = """\ :0(append) <- profilee.py:73(helper1)(4) 119.964 -:0(exc_info) <- profilee.py:73(helper1)(4) 119.964 +:0(exception) <- profilee.py:73(helper1)(4) 119.964 :0(hasattr) <- profilee.py:73(helper1)(4) 119.964 profilee.py:88(helper2)(8) 399.912 profilee.py:110(__getattr__) <- :0(hasattr)(12) 11.964 diff --git a/Lib/test/test_property.py b/Lib/test/test_property.py index 95343150..45aa9e51 100644 --- a/Lib/test/test_property.py +++ b/Lib/test/test_property.py @@ -236,6 +236,9 @@ class PropertyTests(unittest.TestCase): class PropertySub(property): """This is a subclass of property""" +class PropertySubWoDoc(property): + pass + class PropertySubSlots(property): """This is a subclass of property that defines __slots__""" __slots__ = () @@ -243,16 +246,99 @@ class PropertySubSlots(property): class PropertySubclassTests(unittest.TestCase): def test_slots_docstring_copy_exception(self): - try: + # A special case error that we preserve despite the GH-98963 behavior + # that would otherwise silently ignore this error. + # This came from commit b18500d39d791c879e9904ebac293402b4a7cd34 + # as part of https://bugs.python.org/issue5890 which allowed docs to + # be set via property subclasses in the first place. + with self.assertRaises(AttributeError): class Foo(object): @PropertySubSlots def spam(self): """Trying to copy this docstring will raise an exception""" return 1 - except AttributeError: + + def test_property_with_slots_no_docstring(self): + # https://github.com/python/cpython/issues/98963#issuecomment-1574413319 + class slotted_prop(property): + __slots__ = ("foo",) + + p = slotted_prop() # no AttributeError + self.assertIsNone(getattr(p, "__doc__", None)) + + def undocumented_getter(): + return 4 + + p = slotted_prop(undocumented_getter) # New in 3.12: no AttributeError + self.assertIsNone(getattr(p, "__doc__", None)) + + @unittest.skipIf(sys.flags.optimize >= 2, + "Docstrings are omitted with -O2 and above") + def test_property_with_slots_docstring_silently_dropped(self): + # https://github.com/python/cpython/issues/98963#issuecomment-1574413319 + class slotted_prop(property): + __slots__ = ("foo",) + + p = slotted_prop(doc="what's up") # no AttributeError + self.assertIsNone(p.__doc__) + + def documented_getter(): + """getter doc.""" + return 4 + + # Historical behavior: A docstring from a getter always raises. + # (matches test_slots_docstring_copy_exception above). + with self.assertRaises(AttributeError): + p = slotted_prop(documented_getter) + + @unittest.skipIf(sys.flags.optimize >= 2, + "Docstrings are omitted with -O2 and above") + def test_property_with_slots_and_doc_slot_docstring_present(self): + # https://github.com/python/cpython/issues/98963#issuecomment-1574413319 + class slotted_prop(property): + __slots__ = ("foo", "__doc__") + + p = slotted_prop(doc="what's up") + self.assertEqual("what's up", p.__doc__) # new in 3.12: This gets set. + + def documented_getter(): + """what's up getter doc?""" + return 4 + + p = slotted_prop(documented_getter) + self.assertEqual("what's up getter doc?", p.__doc__) + + @unittest.skipIf(sys.flags.optimize >= 2, + "Docstrings are omitted with -O2 and above") + def test_issue41287(self): + + self.assertEqual(PropertySub.__doc__, "This is a subclass of property", + "Docstring of `property` subclass is ignored") + + doc = PropertySub(None, None, None, "issue 41287 is fixed").__doc__ + self.assertEqual(doc, "issue 41287 is fixed", + "Subclasses of `property` ignores `doc` constructor argument") + + def getter(x): + """Getter docstring""" + + def getter_wo_doc(x): pass - else: - raise Exception("AttributeError not raised") + + for ps in property, PropertySub, PropertySubWoDoc: + doc = ps(getter, None, None, "issue 41287 is fixed").__doc__ + self.assertEqual(doc, "issue 41287 is fixed", + "Getter overrides explicit property docstring (%s)" % ps.__name__) + + doc = ps(getter, None, None, None).__doc__ + self.assertEqual(doc, "Getter docstring", "Getter docstring is not picked-up (%s)" % ps.__name__) + + doc = ps(getter_wo_doc, None, None, "issue 41287 is fixed").__doc__ + self.assertEqual(doc, "issue 41287 is fixed", + "Getter overrides explicit property docstring (%s)" % ps.__name__) + + doc = ps(getter_wo_doc, None, None, None).__doc__ + self.assertIsNone(doc, "Property class doc appears in instance __doc__ (%s)" % ps.__name__) @unittest.skipIf(sys.flags.optimize >= 2, "Docstrings are omitted with -O2 and above") @@ -266,6 +352,66 @@ class PropertySubclassTests(unittest.TestCase): Foo.spam.__doc__, "spam wrapped in property subclass") + @unittest.skipIf(sys.flags.optimize >= 2, + "Docstrings are omitted with -O2 and above") + def test_docstring_copy2(self): + """ + Property tries to provide the best docstring it finds for its instances. + If a user-provided docstring is available, it is preserved on copies. + If no docstring is available during property creation, the property + will utilize the docstring from the getter if available. + """ + def getter1(self): + return 1 + def getter2(self): + """doc 2""" + return 2 + def getter3(self): + """doc 3""" + return 3 + + # Case-1: user-provided doc is preserved in copies + # of property with undocumented getter + p = property(getter1, None, None, "doc-A") + + p2 = p.getter(getter2) + self.assertEqual(p.__doc__, "doc-A") + self.assertEqual(p2.__doc__, "doc-A") + + # Case-2: user-provided doc is preserved in copies + # of property with documented getter + p = property(getter2, None, None, "doc-A") + + p2 = p.getter(getter3) + self.assertEqual(p.__doc__, "doc-A") + self.assertEqual(p2.__doc__, "doc-A") + + # Case-3: with no user-provided doc new getter doc + # takes precendence + p = property(getter2, None, None, None) + + p2 = p.getter(getter3) + self.assertEqual(p.__doc__, "doc 2") + self.assertEqual(p2.__doc__, "doc 3") + + # Case-4: A user-provided doc is assigned after property construction + # with documented getter. The doc IS NOT preserved. + # It's an odd behaviour, but it's a strange enough + # use case with no easy solution. + p = property(getter2, None, None, None) + p.__doc__ = "user" + p2 = p.getter(getter3) + self.assertEqual(p.__doc__, "user") + self.assertEqual(p2.__doc__, "doc 3") + + # Case-5: A user-provided doc is assigned after property construction + # with UNdocumented getter. The doc IS preserved. + p = property(getter1, None, None, None) + p.__doc__ = "user" + p2 = p.getter(getter2) + self.assertEqual(p.__doc__, "user") + self.assertEqual(p2.__doc__, "user") + @unittest.skipIf(sys.flags.optimize >= 2, "Docstrings are omitted with -O2 and above") def test_property_setter_copies_getter_docstring(self): diff --git a/Lib/test/test_pty.py b/Lib/test/test_pty.py index fa0dbcc1..c9c2b428 100644 --- a/Lib/test/test_pty.py +++ b/Lib/test/test_pty.py @@ -3,6 +3,8 @@ from test.support.import_helper import import_module # Skip these tests if termios or fcntl are not available import_module('termios') +# fcntl is a proxy for not being one of the wasm32 platforms even though we +# don't use this module... a proper check for what crashes those is needed. import_module("fcntl") import errno @@ -15,20 +17,12 @@ import signal import socket import io # readline import unittest - -import struct -import fcntl import warnings TEST_STRING_1 = b"I wish to buy a fish license.\n" TEST_STRING_2 = b"For my pet fish, Eric.\n" -try: - _TIOCGWINSZ = tty.TIOCGWINSZ - _TIOCSWINSZ = tty.TIOCSWINSZ - _HAVE_WINSZ = True -except AttributeError: - _HAVE_WINSZ = False +_HAVE_WINSZ = hasattr(tty, "TIOCGWINSZ") and hasattr(tty, "TIOCSWINSZ") if verbose: def debug(msg): @@ -82,14 +76,6 @@ def expectedFailureIfStdinIsTTY(fun): pass return fun -def _get_term_winsz(fd): - s = struct.pack("HHHH", 0, 0, 0, 0) - return fcntl.ioctl(fd, _TIOCGWINSZ, s) - -def _set_term_winsz(fd, winsz): - fcntl.ioctl(fd, _TIOCSWINSZ, winsz) - - # Marginal testing of pty suite. Cannot do extensive 'do or fail' testing # because pty code is not too portable. class PtyTest(unittest.TestCase): @@ -105,18 +91,14 @@ class PtyTest(unittest.TestCase): self.addCleanup(signal.alarm, 0) signal.alarm(10) - # Save original stdin window size - self.stdin_rows = None - self.stdin_cols = None + # Save original stdin window size. + self.stdin_dim = None if _HAVE_WINSZ: try: - stdin_dim = os.get_terminal_size(pty.STDIN_FILENO) - self.stdin_rows = stdin_dim.lines - self.stdin_cols = stdin_dim.columns - old_stdin_winsz = struct.pack("HHHH", self.stdin_rows, - self.stdin_cols, 0, 0) - self.addCleanup(_set_term_winsz, pty.STDIN_FILENO, old_stdin_winsz) - except OSError: + self.stdin_dim = tty.tcgetwinsize(pty.STDIN_FILENO) + self.addCleanup(tty.tcsetwinsize, pty.STDIN_FILENO, + self.stdin_dim) + except tty.error: pass def handle_sig(self, sig, frame): @@ -131,41 +113,40 @@ class PtyTest(unittest.TestCase): try: mode = tty.tcgetattr(pty.STDIN_FILENO) except tty.error: - # not a tty or bad/closed fd + # Not a tty or bad/closed fd. debug("tty.tcgetattr(pty.STDIN_FILENO) failed") mode = None - new_stdin_winsz = None - if self.stdin_rows is not None and self.stdin_cols is not None: + new_dim = None + if self.stdin_dim: try: # Modify pty.STDIN_FILENO window size; we need to # check if pty.openpty() is able to set pty slave # window size accordingly. - debug("Setting pty.STDIN_FILENO window size") - debug(f"original size: (rows={self.stdin_rows}, cols={self.stdin_cols})") - target_stdin_rows = self.stdin_rows + 1 - target_stdin_cols = self.stdin_cols + 1 - debug(f"target size: (rows={target_stdin_rows}, cols={target_stdin_cols})") - target_stdin_winsz = struct.pack("HHHH", target_stdin_rows, - target_stdin_cols, 0, 0) - _set_term_winsz(pty.STDIN_FILENO, target_stdin_winsz) + debug("Setting pty.STDIN_FILENO window size.") + debug(f"original size: (row, col) = {self.stdin_dim}") + target_dim = (self.stdin_dim[0] + 1, self.stdin_dim[1] + 1) + debug(f"target size: (row, col) = {target_dim}") + tty.tcsetwinsize(pty.STDIN_FILENO, target_dim) # Were we able to set the window size # of pty.STDIN_FILENO successfully? - new_stdin_winsz = _get_term_winsz(pty.STDIN_FILENO) - self.assertEqual(new_stdin_winsz, target_stdin_winsz, + new_dim = tty.tcgetwinsize(pty.STDIN_FILENO) + self.assertEqual(new_dim, target_dim, "pty.STDIN_FILENO window size unchanged") except OSError: - warnings.warn("Failed to set pty.STDIN_FILENO window size") + warnings.warn("Failed to set pty.STDIN_FILENO window size.") pass try: debug("Calling pty.openpty()") try: - master_fd, slave_fd = pty.openpty(mode, new_stdin_winsz) + master_fd, slave_fd, slave_name = pty.openpty(mode, new_dim, + True) except TypeError: master_fd, slave_fd = pty.openpty() - debug(f"Got master_fd '{master_fd}', slave_fd '{slave_fd}'") + slave_name = None + debug(f"Got {master_fd=}, {slave_fd=}, {slave_name=}") except OSError: # " An optional feature could not be imported " ... ? raise unittest.SkipTest("Pseudo-terminals (seemingly) not functional.") @@ -181,8 +162,8 @@ class PtyTest(unittest.TestCase): if mode: self.assertEqual(tty.tcgetattr(slave_fd), mode, "openpty() failed to set slave termios") - if new_stdin_winsz: - self.assertEqual(_get_term_winsz(slave_fd), new_stdin_winsz, + if new_dim: + self.assertEqual(tty.tcgetwinsize(slave_fd), new_dim, "openpty() failed to set slave window size") # Ensure the fd is non-blocking in case there's nothing to read. @@ -331,8 +312,8 @@ class SmallPtyTests(unittest.TestCase): self.orig_pty_waitpid = pty.waitpid self.fds = [] # A list of file descriptors to close. self.files = [] - self.select_rfds_lengths = [] - self.select_rfds_results = [] + self.select_input = [] + self.select_output = [] self.tcsetattr_mode_setting = None def tearDown(self): @@ -367,11 +348,10 @@ class SmallPtyTests(unittest.TestCase): self.files.extend(socketpair) return socketpair - def _mock_select(self, rfds, wfds, xfds, timeout=0): + def _mock_select(self, rfds, wfds, xfds): # This will raise IndexError when no more expected calls exist. - # This ignores the timeout - self.assertEqual(self.select_rfds_lengths.pop(0), len(rfds)) - return self.select_rfds_results.pop(0), [], [] + self.assertEqual((rfds, wfds, xfds), self.select_input.pop(0)) + return self.select_output.pop(0) def _make_mock_fork(self, pid): def mock_fork(): @@ -394,11 +374,13 @@ class SmallPtyTests(unittest.TestCase): os.write(masters[1], b'from master') os.write(write_to_stdin_fd, b'from stdin') - # Expect two select calls, the last one will cause IndexError + # Expect three select calls, the last one will cause IndexError pty.select = self._mock_select - self.select_rfds_lengths.append(2) - self.select_rfds_results.append([mock_stdin_fd, masters[0]]) - self.select_rfds_lengths.append(2) + self.select_input.append(([mock_stdin_fd, masters[0]], [], [])) + self.select_output.append(([mock_stdin_fd, masters[0]], [], [])) + self.select_input.append(([mock_stdin_fd, masters[0]], [mock_stdout_fd, masters[0]], [])) + self.select_output.append(([], [mock_stdout_fd, masters[0]], [])) + self.select_input.append(([mock_stdin_fd, masters[0]], [], [])) with self.assertRaises(IndexError): pty._copy(masters[0]) @@ -409,28 +391,6 @@ class SmallPtyTests(unittest.TestCase): self.assertEqual(os.read(read_from_stdout_fd, 20), b'from master') self.assertEqual(os.read(masters[1], 20), b'from stdin') - def test__copy_eof_on_all(self): - """Test the empty read EOF case on both master_fd and stdin.""" - read_from_stdout_fd, mock_stdout_fd = self._pipe() - pty.STDOUT_FILENO = mock_stdout_fd - mock_stdin_fd, write_to_stdin_fd = self._pipe() - pty.STDIN_FILENO = mock_stdin_fd - socketpair = self._socketpair() - masters = [s.fileno() for s in socketpair] - - socketpair[1].close() - os.close(write_to_stdin_fd) - - pty.select = self._mock_select - self.select_rfds_lengths.append(2) - self.select_rfds_results.append([mock_stdin_fd, masters[0]]) - # We expect that both fds were removed from the fds list as they - # both encountered an EOF before the second select call. - self.select_rfds_lengths.append(0) - - # We expect the function to return without error. - self.assertEqual(pty._copy(masters[0]), None) - def test__restore_tty_mode_normal_return(self): """Test that spawn resets the tty mode no when _copy returns normally.""" diff --git a/Lib/test/test_py_compile.py b/Lib/test/test_py_compile.py index a4a52b18..5e0a44ad 100644 --- a/Lib/test/test_py_compile.py +++ b/Lib/test/test_py_compile.py @@ -235,11 +235,12 @@ class PyCompileCLITestCase(unittest.TestCase): # assert_python_* helpers don't return proc object. We'll just use # subprocess.run() instead of spawn_python() and its friends to test # stdin support of the CLI. + opts = '-m' if __debug__ else '-Om' if args and args[0] == '-' and 'input' in kwargs: - return subprocess.run([sys.executable, '-m', 'py_compile', '-'], + return subprocess.run([sys.executable, opts, 'py_compile', '-'], input=kwargs['input'].encode(), capture_output=True) - return script_helper.assert_python_ok('-m', 'py_compile', *args, **kwargs) + return script_helper.assert_python_ok(opts, 'py_compile', *args, **kwargs) def pycompilecmd_failure(self, *args): return script_helper.assert_python_failure('-m', 'py_compile', *args) diff --git a/Lib/test/test_pydoc.py b/Lib/test/test_pydoc.py index 89faf0d9..ddb5187f 100644 --- a/Lib/test/test_pydoc.py +++ b/Lib/test/test_pydoc.py @@ -24,7 +24,8 @@ from collections import namedtuple from urllib.request import urlopen, urlcleanup from test.support import import_helper from test.support import os_helper -from test.support.script_helper import assert_python_ok, assert_python_failure +from test.support.script_helper import (assert_python_ok, + assert_python_failure, spawn_python) from test.support import threading_helper from test.support import (reap_children, captured_output, captured_stdout, captured_stderr, is_emscripten, is_wasi, @@ -54,58 +55,58 @@ CLASSES A B C -\x20\x20\x20\x20 + class A(builtins.object) | Hello and goodbye - |\x20\x20 + | | Methods defined here: - |\x20\x20 + | | __init__() | Wow, I have no function! - |\x20\x20 + | | ---------------------------------------------------------------------- | Data descriptors defined here: - |\x20\x20 + | | __dict__%s - |\x20\x20 + | | __weakref__%s -\x20\x20\x20\x20 + class B(builtins.object) | Data descriptors defined here: - |\x20\x20 + | | __dict__%s - |\x20\x20 + | | __weakref__%s - |\x20\x20 + | | ---------------------------------------------------------------------- | Data and other attributes defined here: - |\x20\x20 + | | NO_MEANING = 'eggs' - |\x20\x20 + | | __annotations__ = {'NO_MEANING': <class 'str'>} -\x20\x20\x20\x20 + class C(builtins.object) | Methods defined here: - |\x20\x20 + | | get_answer(self) | Return say_no() - |\x20\x20 + | | is_it_true(self) | Return self.get_answer() - |\x20\x20 + | | say_no(self) - |\x20\x20 + | | ---------------------------------------------------------------------- | Class methods defined here: - |\x20\x20 + | | __class_getitem__(item) from builtins.type - |\x20\x20 + | | ---------------------------------------------------------------------- | Data descriptors defined here: - |\x20\x20 + | | __dict__ | dictionary for instance variables (if defined) - |\x20\x20 + | | __weakref__ | list of weak references to the object (if defined) @@ -115,7 +116,7 @@ FUNCTIONS hunger lack of Python war -\x20\x20\x20\x20 + nodoc_func() DATA @@ -235,16 +236,16 @@ Help on class DA in module %s: class DA(builtins.object) | Data descriptors defined here: - |\x20\x20 + | | __dict__%s - |\x20\x20 + | | __weakref__%s - |\x20\x20 + | | ham - |\x20\x20 + | | ---------------------------------------------------------------------- | Data and other attributes inherited from Meta: - |\x20\x20 + | | ham = 'spam' """.strip() @@ -253,7 +254,7 @@ Help on class Class in module %s: class Class(builtins.object) | Data and other attributes inherited from Meta: - |\x20\x20 + | | LIFE = 42 """.strip() @@ -262,7 +263,7 @@ Help on class Class1 in module %s: class Class1(builtins.object) | Data and other attributes inherited from Meta1: - |\x20\x20 + | | one = 1 """.strip() @@ -274,19 +275,19 @@ class Class2(Class1) | Class2 | Class1 | builtins.object - |\x20\x20 + | | Data and other attributes inherited from Meta1: - |\x20\x20 + | | one = 1 - |\x20\x20 + | | ---------------------------------------------------------------------- | Data and other attributes inherited from Meta3: - |\x20\x20 + | | three = 3 - |\x20\x20 + | | ---------------------------------------------------------------------- | Data and other attributes inherited from Meta2: - |\x20\x20 + | | two = 2 """.strip() @@ -295,7 +296,7 @@ Help on class C in module %s: class C(builtins.object) | Data and other attributes defined here: - |\x20\x20 + | | here = 'present!' """.strip() @@ -631,6 +632,21 @@ class PydocDocTest(unittest.TestCase): # Testing that the subclasses section does not appear self.assertNotIn('Built-in subclasses', text) + def test_fail_help_cli(self): + elines = (missing_pattern % 'abd').splitlines() + with spawn_python("-c" "help()") as proc: + out, _ = proc.communicate(b"abd") + olines = out.decode().splitlines()[-9:-6] + olines[0] = olines[0].removeprefix('help> ') + self.assertEqual(elines, olines) + + def test_fail_help_output_redirect(self): + with StringIO() as buf: + helper = pydoc.Helper(output=buf) + helper.help("abd") + expected = missing_pattern % "abd" + self.assertEqual(expected, buf.getvalue().strip().replace('\n', os.linesep)) + @unittest.skipIf(hasattr(sys, 'gettrace') and sys.gettrace(), 'trace function introduces __locals__ unexpectedly') @requires_docstrings @@ -702,7 +718,7 @@ class PydocDocTest(unittest.TestCase): def test_synopsis_sourceless(self): os = import_helper.import_fresh_module('os') expected = os.__doc__.splitlines()[0] - filename = os.__cached__ + filename = os.__spec__.cached synopsis = pydoc.synopsis(filename) self.assertEqual(synopsis, expected) @@ -785,33 +801,33 @@ class B(A) | B | A | builtins.object - |\x20\x20 + | | Methods defined here: - |\x20\x20 + | | b_size = a_size(self) - |\x20\x20 + | | itemconfig = itemconfigure(self, tagOrId, cnf=None, **kw) - |\x20\x20 + | | itemconfigure(self, tagOrId, cnf=None, **kw) | Configure resources of an item TAGORID. - |\x20\x20 + | | ---------------------------------------------------------------------- | Methods inherited from A: - |\x20\x20 + | | a_size(self) | Return size - |\x20\x20 + | | lift = tkraise(self, aboveThis=None) - |\x20\x20 + | | tkraise(self, aboveThis=None) | Raise this widget in the stacking order. - |\x20\x20 + | | ---------------------------------------------------------------------- | Data descriptors inherited from A: - |\x20\x20 + | | __dict__ | dictionary for instance variables (if defined) - |\x20\x20 + | | __weakref__ | list of weak references to the object (if defined) ''' % __name__) @@ -1180,7 +1196,7 @@ sm(x, y) """) self.assertIn(""" | Static methods defined here: - |\x20\x20 + | | sm(x, y) | A static method """, pydoc.plain(pydoc.render_doc(X))) @@ -1201,7 +1217,7 @@ cm(x) method of builtins.type instance """) self.assertIn(""" | Class methods defined here: - |\x20\x20 + | | cm(x) from builtins.type | A class method """, pydoc.plain(pydoc.render_doc(X))) diff --git a/Lib/test/test_pyexpat.py b/Lib/test/test_pyexpat.py index 6f0441b6..95698c0b 100644 --- a/Lib/test/test_pyexpat.py +++ b/Lib/test/test_pyexpat.py @@ -1,13 +1,15 @@ # XXX TypeErrors on calling handlers, or on bad return values from a # handler, are obscure and unhelpful. -from io import BytesIO import os import platform import sys import sysconfig import unittest import traceback +from io import BytesIO +from test import support +from test.support import os_helper from xml.parsers import expat from xml.parsers.expat import errors @@ -441,37 +443,59 @@ class BufferTextTest(unittest.TestCase): # Test handling of exception from callback: class HandlerExceptionTest(unittest.TestCase): def StartElementHandler(self, name, attrs): - raise RuntimeError(name) + raise RuntimeError(f'StartElementHandler: <{name}>') def check_traceback_entry(self, entry, filename, funcname): - self.assertEqual(os.path.basename(entry[0]), filename) - self.assertEqual(entry[2], funcname) + self.assertEqual(os.path.basename(entry.filename), filename) + self.assertEqual(entry.name, funcname) + @support.cpython_only def test_exception(self): + # gh-66652: test _PyTraceback_Add() used by pyexpat.c to inject frames + + # Change the current directory to the Python source code directory + # if it is available. + src_dir = sysconfig.get_config_var('abs_builddir') + if src_dir: + have_source = os.path.isdir(src_dir) + else: + have_source = False + if have_source: + with os_helper.change_cwd(src_dir): + self._test_exception(have_source) + else: + self._test_exception(have_source) + + def _test_exception(self, have_source): + # Use path relative to the current directory which should be the Python + # source code directory (if it is available). + PYEXPAT_C = os.path.join('Modules', 'pyexpat.c') + parser = expat.ParserCreate() parser.StartElementHandler = self.StartElementHandler try: parser.Parse(b"<a><b><c/></b></a>", True) - self.fail() - except RuntimeError as e: - self.assertEqual(e.args[0], 'a', - "Expected RuntimeError for element 'a', but" + \ - " found %r" % e.args[0]) - # Check that the traceback contains the relevant line in pyexpat.c - entries = traceback.extract_tb(e.__traceback__) - self.assertEqual(len(entries), 3) - self.check_traceback_entry(entries[0], - "test_pyexpat.py", "test_exception") - self.check_traceback_entry(entries[1], - "pyexpat.c", "StartElement") - self.check_traceback_entry(entries[2], - "test_pyexpat.py", "StartElementHandler") - if (sysconfig.is_python_build() - and not (sys.platform == 'win32' and platform.machine() == 'ARM') - and not is_emscripten - and not is_wasi - ): - self.assertIn('call_with_frame("StartElement"', entries[1][3]) + + self.fail("the parser did not raise RuntimeError") + except RuntimeError as exc: + self.assertEqual(exc.args[0], 'StartElementHandler: <a>', exc) + entries = traceback.extract_tb(exc.__traceback__) + + self.assertEqual(len(entries), 3, entries) + self.check_traceback_entry(entries[0], + "test_pyexpat.py", "_test_exception") + self.check_traceback_entry(entries[1], + os.path.basename(PYEXPAT_C), + "StartElement") + self.check_traceback_entry(entries[2], + "test_pyexpat.py", "StartElementHandler") + + # Check that the traceback contains the relevant line in + # Modules/pyexpat.c. Skip the test if Modules/pyexpat.c is not + # available. + if have_source and os.path.exists(PYEXPAT_C): + self.assertIn('call_with_frame("StartElement"', + entries[1].line) # Test Current* members: @@ -508,7 +532,7 @@ class PositionTest(unittest.TestCase): class sf1296433Test(unittest.TestCase): def test_parse_only_xml_data(self): - # http://python.org/sf/1296433 + # https://bugs.python.org/issue1296433 # xml = "<?xml version='1.0' encoding='iso8859'?><s>%s</s>" % ('a' * 1025) # this one doesn't crash diff --git a/Lib/test/test_random.py b/Lib/test/test_random.py index f32d592c..50bea7be 100644 --- a/Lib/test/test_random.py +++ b/Lib/test/test_random.py @@ -500,50 +500,44 @@ class SystemRandom_TestBasicOps(TestBasicOps, unittest.TestCase): self.assertEqual(rint, 0) def test_randrange_errors(self): - raises = partial(self.assertRaises, ValueError, self.gen.randrange) + raises_value_error = partial(self.assertRaises, ValueError, self.gen.randrange) + raises_type_error = partial(self.assertRaises, TypeError, self.gen.randrange) + # Empty range - raises(3, 3) - raises(-721) - raises(0, 100, -12) - # Non-integer start/stop - self.assertWarns(DeprecationWarning, raises, 3.14159) - self.assertWarns(DeprecationWarning, self.gen.randrange, 3.0) - self.assertWarns(DeprecationWarning, self.gen.randrange, Fraction(3, 1)) - self.assertWarns(DeprecationWarning, raises, '3') - self.assertWarns(DeprecationWarning, raises, 0, 2.71828) - self.assertWarns(DeprecationWarning, self.gen.randrange, 0, 2.0) - self.assertWarns(DeprecationWarning, self.gen.randrange, 0, Fraction(2, 1)) - self.assertWarns(DeprecationWarning, raises, 0, '2') - # Zero and non-integer step - raises(0, 42, 0) - self.assertWarns(DeprecationWarning, raises, 0, 42, 0.0) - self.assertWarns(DeprecationWarning, raises, 0, 0, 0.0) - self.assertWarns(DeprecationWarning, raises, 0, 42, 3.14159) - self.assertWarns(DeprecationWarning, self.gen.randrange, 0, 42, 3.0) - self.assertWarns(DeprecationWarning, self.gen.randrange, 0, 42, Fraction(3, 1)) - self.assertWarns(DeprecationWarning, raises, 0, 42, '3') - self.assertWarns(DeprecationWarning, self.gen.randrange, 0, 42, 1.0) - self.assertWarns(DeprecationWarning, raises, 0, 0, 1.0) - - def test_randrange_argument_handling(self): - randrange = self.gen.randrange - with self.assertWarns(DeprecationWarning): - randrange(10.0, 20, 2) - with self.assertWarns(DeprecationWarning): - randrange(10, 20.0, 2) - with self.assertWarns(DeprecationWarning): - randrange(10, 20, 1.0) - with self.assertWarns(DeprecationWarning): - randrange(10, 20, 2.0) - with self.assertWarns(DeprecationWarning): - with self.assertRaises(ValueError): - randrange(10.5) - with self.assertWarns(DeprecationWarning): - with self.assertRaises(ValueError): - randrange(10, 20.5) - with self.assertWarns(DeprecationWarning): - with self.assertRaises(ValueError): - randrange(10, 20, 1.5) + raises_value_error(3, 3) + raises_value_error(-721) + raises_value_error(0, 100, -12) + + # Zero step + raises_value_error(0, 42, 0) + raises_type_error(0, 42, 0.0) + raises_type_error(0, 0, 0.0) + + # Non-integer stop + raises_type_error(3.14159) + raises_type_error(3.0) + raises_type_error(Fraction(3, 1)) + raises_type_error('3') + raises_type_error(0, 2.71827) + raises_type_error(0, 2.0) + raises_type_error(0, Fraction(2, 1)) + raises_type_error(0, '2') + raises_type_error(0, 2.71827, 2) + + # Non-integer start + raises_type_error(2.71827, 5) + raises_type_error(2.0, 5) + raises_type_error(Fraction(2, 1), 5) + raises_type_error('2', 5) + raises_type_error(2.71827, 5, 2) + + # Non-integer step + raises_type_error(0, 42, 3.14159) + raises_type_error(0, 42, 3.0) + raises_type_error(0, 42, Fraction(3, 1)) + raises_type_error(0, 42, '3') + raises_type_error(0, 42, 1.0) + raises_type_error(0, 0, 1.0) def test_randrange_step(self): # bpo-42772: When stop is None, the step argument was being ignored. @@ -1009,6 +1003,7 @@ class TestDistributions(unittest.TestCase): g.random = x[:].pop; g.uniform(1,10) g.random = x[:].pop; g.paretovariate(1.0) g.random = x[:].pop; g.expovariate(1.0) + g.random = x[:].pop; g.expovariate() g.random = x[:].pop; g.weibullvariate(1.0, 1.0) g.random = x[:].pop; g.vonmisesvariate(1.0, 1.0) g.random = x[:].pop; g.normalvariate(0.0, 1.0) @@ -1066,6 +1061,9 @@ class TestDistributions(unittest.TestCase): (g.lognormvariate, (0.0, 0.0), 1.0), (g.lognormvariate, (-float('inf'), 0.0), 0.0), (g.normalvariate, (10.0, 0.0), 10.0), + (g.binomialvariate, (0, 0.5), 0), + (g.binomialvariate, (10, 0.0), 0), + (g.binomialvariate, (10, 1.0), 10), (g.paretovariate, (float('inf'),), 1.0), (g.weibullvariate, (10.0, float('inf')), 10.0), (g.weibullvariate, (0.0, 10.0), 0.0), @@ -1073,6 +1071,59 @@ class TestDistributions(unittest.TestCase): for i in range(N): self.assertEqual(variate(*args), expected) + def test_binomialvariate(self): + B = random.binomialvariate + + # Cover all the code paths + with self.assertRaises(ValueError): + B(n=-1) # Negative n + with self.assertRaises(ValueError): + B(n=1, p=-0.5) # Negative p + with self.assertRaises(ValueError): + B(n=1, p=1.5) # p > 1.0 + self.assertEqual(B(10, 0.0), 0) # p == 0.0 + self.assertEqual(B(10, 1.0), 10) # p == 1.0 + self.assertTrue(B(1, 0.3) in {0, 1}) # n == 1 fast path + self.assertTrue(B(1, 0.9) in {0, 1}) # n == 1 fast path + self.assertTrue(B(1, 0.0) in {0}) # n == 1 fast path + self.assertTrue(B(1, 1.0) in {1}) # n == 1 fast path + + # BG method p <= 0.5 and n*p=1.25 + self.assertTrue(B(5, 0.25) in set(range(6))) + + # BG method p >= 0.5 and n*(1-p)=1.25 + self.assertTrue(B(5, 0.75) in set(range(6))) + + # BTRS method p <= 0.5 and n*p=25 + self.assertTrue(B(100, 0.25) in set(range(101))) + + # BTRS method p > 0.5 and n*(1-p)=25 + self.assertTrue(B(100, 0.75) in set(range(101))) + + # Statistical tests chosen such that they are + # exceedingly unlikely to ever fail for correct code. + + # BG code path + # Expected dist: [31641, 42188, 21094, 4688, 391] + c = Counter(B(4, 0.25) for i in range(100_000)) + self.assertTrue(29_641 <= c[0] <= 33_641, c) + self.assertTrue(40_188 <= c[1] <= 44_188) + self.assertTrue(19_094 <= c[2] <= 23_094) + self.assertTrue(2_688 <= c[3] <= 6_688) + self.assertEqual(set(c), {0, 1, 2, 3, 4}) + + # BTRS code path + # Sum of c[20], c[21], c[22], c[23], c[24] expected to be 36,214 + c = Counter(B(100, 0.25) for i in range(100_000)) + self.assertTrue(34_214 <= c[20]+c[21]+c[22]+c[23]+c[24] <= 38_214) + self.assertTrue(set(c) <= set(range(101))) + self.assertEqual(c.total(), 100_000) + + # Demonstrate the BTRS works for huge values of n + self.assertTrue(19_000_000 <= B(100_000_000, 0.2) <= 21_000_000) + self.assertTrue(89_000_000 <= B(100_000_000, 0.9) <= 91_000_000) + + def test_von_mises_range(self): # Issue 17149: von mises variates were not consistently in the # range [0, 2*PI]. diff --git a/Lib/test/test_range.py b/Lib/test/test_range.py index 851ad5b7..3870b153 100644 --- a/Lib/test/test_range.py +++ b/Lib/test/test_range.py @@ -407,11 +407,7 @@ class RangeTest(unittest.TestCase): for proto in range(pickle.HIGHEST_PROTOCOL + 1): with self.subTest(proto=proto): it = iter(range(2**32 + 2)) - _, _, idx = it.__reduce__() - self.assertEqual(idx, 0) - it.__setstate__(2**32 + 1) # undocumented way to set r->index - _, _, idx = it.__reduce__() - self.assertEqual(idx, 2**32 + 1) + it.__setstate__(2**32 + 1) # undocumented way to advance an iterator d = pickle.dumps(it, proto) it = pickle.loads(d) self.assertEqual(next(it), 2**32 + 1) @@ -442,6 +438,38 @@ class RangeTest(unittest.TestCase): self.assertEqual(list(i), []) self.assertEqual(list(i2), []) + def test_iterator_unpickle_compat(self): + testcases = [ + b'c__builtin__\niter\n(c__builtin__\nxrange\n(I10\nI20\nI2\ntRtRI2\nb.', + b'c__builtin__\niter\n(c__builtin__\nxrange\n(K\nK\x14K\x02tRtRK\x02b.', + b'\x80\x02c__builtin__\niter\nc__builtin__\nxrange\nK\nK\x14K\x02\x87R\x85RK\x02b.', + b'\x80\x03cbuiltins\niter\ncbuiltins\nrange\nK\nK\x14K\x02\x87R\x85RK\x02b.', + b'\x80\x04\x951\x00\x00\x00\x00\x00\x00\x00\x8c\x08builtins\x8c\x04iter\x93\x8c\x08builtins\x8c\x05range\x93K\nK\x14K\x02\x87R\x85RK\x02b.', + + b'c__builtin__\niter\n(c__builtin__\nxrange\n(L-36893488147419103232L\nI20\nI2\ntRtRL18446744073709551623L\nb.', + b'c__builtin__\niter\n(c__builtin__\nxrange\n(L-36893488147419103232L\nK\x14K\x02tRtRL18446744073709551623L\nb.', + b'\x80\x02c__builtin__\niter\nc__builtin__\nxrange\n\x8a\t\x00\x00\x00\x00\x00\x00\x00\x00\xfeK\x14K\x02\x87R\x85R\x8a\t\x07\x00\x00\x00\x00\x00\x00\x00\x01b.', + b'\x80\x03cbuiltins\niter\ncbuiltins\nrange\n\x8a\t\x00\x00\x00\x00\x00\x00\x00\x00\xfeK\x14K\x02\x87R\x85R\x8a\t\x07\x00\x00\x00\x00\x00\x00\x00\x01b.', + b'\x80\x04\x95C\x00\x00\x00\x00\x00\x00\x00\x8c\x08builtins\x8c\x04iter\x93\x8c\x08builtins\x8c\x05range\x93\x8a\t\x00\x00\x00\x00\x00\x00\x00\x00\xfeK\x14K\x02\x87R\x85R\x8a\t\x07\x00\x00\x00\x00\x00\x00\x00\x01b.', + ] + for t in testcases: + it = pickle.loads(t) + self.assertEqual(list(it), [14, 16, 18]) + + def test_iterator_setstate(self): + it = iter(range(10, 20, 2)) + it.__setstate__(2) + self.assertEqual(list(it), [14, 16, 18]) + it = reversed(range(10, 20, 2)) + it.__setstate__(3) + self.assertEqual(list(it), [12, 10]) + it = iter(range(-2**65, 20, 2)) + it.__setstate__(2**64 + 7) + self.assertEqual(list(it), [14, 16, 18]) + it = reversed(range(10, 2**65, 2)) + it.__setstate__(2**64 - 7) + self.assertEqual(list(it), [12, 10]) + def test_odd_bug(self): # This used to raise a "SystemError: NULL result without error" # because the range validation step was eating the exception @@ -514,6 +542,7 @@ class RangeTest(unittest.TestCase): for start in limits for end in limits for step in (-2**63, -2**31, -2, -1, 1, 2)] + test_ranges += [(-2**63, 2**63-2, 1)] # regression test for gh-100810 for start, end, step in test_ranges: iter1 = range(start, end, step) diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py index 59d0b7b5..5a5de523 100644 --- a/Lib/test/test_re.py +++ b/Lib/test/test_re.py @@ -284,21 +284,12 @@ class ReTests(unittest.TestCase): self.checkPatternError('(?P<©>x)', "bad character in group name '©'", 4) self.checkPatternError('(?P=©)', "bad character in group name '©'", 4) self.checkPatternError('(?(©)y)', "bad character in group name '©'", 3) - with self.assertWarnsRegex(DeprecationWarning, - r"bad character in group name '\\xc2\\xb5' " - r"at position 4") as w: - re.compile(b'(?P<\xc2\xb5>x)') - self.assertEqual(w.filename, __file__) - with self.assertWarnsRegex(DeprecationWarning, - r"bad character in group name '\\xc2\\xb5' " - r"at position 4"): - self.checkPatternError(b'(?P=\xc2\xb5)', - r"unknown group name '\xc2\xb5'", 4) - with self.assertWarnsRegex(DeprecationWarning, - r"bad character in group name '\\xc2\\xb5' " - r"at position 3"): - self.checkPatternError(b'(?(\xc2\xb5)y)', - r"unknown group name '\xc2\xb5'", 3) + self.checkPatternError(b'(?P<\xc2\xb5>x)', + r"bad character in group name '\xc2\xb5'", 4) + self.checkPatternError(b'(?P=\xc2\xb5)', + r"bad character in group name '\xc2\xb5'", 4) + self.checkPatternError(b'(?(\xc2\xb5)y)', + r"bad character in group name '\xc2\xb5'", 3) def test_symbolic_refs(self): self.assertEqual(re.sub('(?P<a>x)|(?P<b>y)', r'\g<b>', 'xx'), '') @@ -331,35 +322,22 @@ class ReTests(unittest.TestCase): re.sub('(?P<a>x)', r'\g<ab>', 'xx') self.checkTemplateError('(?P<a>x)', r'\g<-1>', 'xx', "bad character in group name '-1'", 3) - with self.assertWarnsRegex(DeprecationWarning, - r"bad character in group name '\+1' " - r"at position 3") as w: - re.sub('(?P<a>x)', r'\g<+1>', 'xx') - self.assertEqual(w.filename, __file__) - with self.assertWarnsRegex(DeprecationWarning, - r"bad character in group name '1_0' " - r"at position 3"): - re.sub('()'*10, r'\g<1_0>', 'xx') - with self.assertWarnsRegex(DeprecationWarning, - r"bad character in group name ' 1 ' " - r"at position 3"): - re.sub('(?P<a>x)', r'\g< 1 >', 'xx') + self.checkTemplateError('(?P<a>x)', r'\g<+1>', 'xx', + "bad character in group name '+1'", 3) + self.checkTemplateError('()'*10, r'\g<1_0>', 'xx', + "bad character in group name '1_0'", 3) + self.checkTemplateError('(?P<a>x)', r'\g< 1 >', 'xx', + "bad character in group name ' 1 '", 3) self.checkTemplateError('(?P<a>x)', r'\g<©>', 'xx', "bad character in group name '©'", 3) - with self.assertWarnsRegex(DeprecationWarning, - r"bad character in group name '\\xc2\\xb5' " - r"at position 3") as w: - with self.assertRaisesRegex(IndexError, "unknown group name '\xc2\xb5'"): - re.sub(b'(?P<a>x)', b'\\g<\xc2\xb5>', b'xx') - self.assertEqual(w.filename, __file__) + self.checkTemplateError(b'(?P<a>x)', b'\\g<\xc2\xb5>', b'xx', + r"bad character in group name '\xc2\xb5'", 3) self.checkTemplateError('(?P<a>x)', r'\g<㊀>', 'xx', "bad character in group name '㊀'", 3) self.checkTemplateError('(?P<a>x)', r'\g<¹>', 'xx', "bad character in group name '¹'", 3) - with self.assertWarnsRegex(DeprecationWarning, - r"bad character in group name '१' " - r"at position 3"): - re.sub('(?P<a>x)', r'\g<१>', 'xx') + self.checkTemplateError('(?P<a>x)', r'\g<१>', 'xx', + "bad character in group name '१'", 3) def test_re_subn(self): self.assertEqual(re.subn("(?i)b+", "x", "bbbb BBBB"), ('x x', 2)) @@ -625,27 +603,18 @@ class ReTests(unittest.TestCase): self.checkPatternError(r'(?P<a>)(?(0)a|b)', 'bad group number', 10) self.checkPatternError(r'()(?(-1)a|b)', "bad character in group name '-1'", 5) - with self.assertWarnsRegex(DeprecationWarning, - r"bad character in group name '\+1' " - r"at position 5") as w: - re.compile(r'()(?(+1)a|b)') - self.assertEqual(w.filename, __file__) - with self.assertWarnsRegex(DeprecationWarning, - r"bad character in group name '1_0' " - r"at position 23"): - re.compile(r'()'*10 + r'(?(1_0)a|b)') - with self.assertWarnsRegex(DeprecationWarning, - r"bad character in group name ' 1 ' " - r"at position 5"): - re.compile(r'()(?( 1 )a|b)') + self.checkPatternError(r'()(?(+1)a|b)', + "bad character in group name '+1'", 5) + self.checkPatternError(r'()'*10 + r'(?(1_0)a|b)', + "bad character in group name '1_0'", 23) + self.checkPatternError(r'()(?( 1 )a|b)', + "bad character in group name ' 1 '", 5) self.checkPatternError(r'()(?(㊀)a|b)', "bad character in group name '㊀'", 5) self.checkPatternError(r'()(?(¹)a|b)', "bad character in group name '¹'", 5) - with self.assertWarnsRegex(DeprecationWarning, - r"bad character in group name '१' " - r"at position 5"): - re.compile(r'()(?(१)a|b)') + self.checkPatternError(r'()(?(१)a|b)', + "bad character in group name '१'", 5) self.checkPatternError(r'()(?(1', "missing ), unterminated name", 5) self.checkPatternError(r'()(?(1)a', @@ -1077,33 +1046,6 @@ class ReTests(unittest.TestCase): def test_category(self): self.assertEqual(re.match(r"(\s)", " ").group(1), " ") - @cpython_only - def test_case_helpers(self): - import _sre - for i in range(128): - c = chr(i) - lo = ord(c.lower()) - self.assertEqual(_sre.ascii_tolower(i), lo) - self.assertEqual(_sre.unicode_tolower(i), lo) - iscased = c in string.ascii_letters - self.assertEqual(_sre.ascii_iscased(i), iscased) - self.assertEqual(_sre.unicode_iscased(i), iscased) - - for i in list(range(128, 0x1000)) + [0x10400, 0x10428]: - c = chr(i) - self.assertEqual(_sre.ascii_tolower(i), i) - if i != 0x0130: - self.assertEqual(_sre.unicode_tolower(i), ord(c.lower())) - iscased = c != c.lower() or c != c.upper() - self.assertFalse(_sre.ascii_iscased(i)) - self.assertEqual(_sre.unicode_iscased(i), - c != c.lower() or c != c.upper()) - - self.assertEqual(_sre.ascii_tolower(0x0130), 0x0130) - self.assertEqual(_sre.unicode_tolower(0x0130), ord('i')) - self.assertFalse(_sre.ascii_iscased(0x0130)) - self.assertTrue(_sre.unicode_iscased(0x0130)) - def test_not_literal(self): self.assertEqual(re.search(r"\s([^a])", " b").group(1), "b") self.assertEqual(re.search(r"\s([^a]*)", " bb").group(1), "bb") @@ -1800,20 +1742,6 @@ class ReTests(unittest.TestCase): pat = re.compile(b'..') self.assertEqual(pat.sub(lambda m: b'bytes', b'a5'), b'bytes') - def test_dealloc(self): - # issue 3299: check for segfault in debug build - import _sre - # the overflow limit is different on wide and narrow builds and it - # depends on the definition of SRE_CODE (see sre.h). - # 2**128 should be big enough to overflow on both. For smaller values - # a RuntimeError is raised instead of OverflowError. - long_overflow = 2**128 - self.assertRaises(TypeError, re.finditer, "a", {}) - with self.assertRaises(OverflowError): - _sre.compile("abc", 0, [long_overflow], 0, {}, ()) - with self.assertRaises(TypeError): - _sre.compile({}, 0, [], 0, [], []) - def test_search_dot_unicode(self): self.assertTrue(re.search("123.*-", '123abc-')) self.assertTrue(re.search("123.*-", '123\xe9-')) @@ -1871,21 +1799,6 @@ class ReTests(unittest.TestCase): self.assertRaises(OverflowError, re.compile, r".{%d,}?" % 2**128) self.assertRaises(OverflowError, re.compile, r".{%d,%d}" % (2**129, 2**128)) - @cpython_only - def test_repeat_minmax_overflow_maxrepeat(self): - try: - from _sre import MAXREPEAT - except ImportError: - self.skipTest('requires _sre.MAXREPEAT constant') - string = "x" * 100000 - self.assertIsNone(re.match(r".{%d}" % (MAXREPEAT - 1), string)) - self.assertEqual(re.match(r".{,%d}" % (MAXREPEAT - 1), string).span(), - (0, 100000)) - self.assertIsNone(re.match(r".{%d,}?" % (MAXREPEAT - 1), string)) - self.assertRaises(OverflowError, re.compile, r".{%d}" % MAXREPEAT) - self.assertRaises(OverflowError, re.compile, r".{,%d}" % MAXREPEAT) - self.assertRaises(OverflowError, re.compile, r".{%d,}?" % MAXREPEAT) - def test_backref_group_name_in_exception(self): # Issue 17341: Poor error message when compiling invalid regex self.checkPatternError('(?P=<foo>)', @@ -2452,6 +2365,26 @@ class ReTests(unittest.TestCase): self.assertTrue(template_re1.match('ahoy')) self.assertFalse(template_re1.match('nope')) + def test_bug_gh106052(self): + # gh-100061 + self.assertEqual(re.match('(?>(?:.(?!D))+)', 'ABCDE').span(), (0, 2)) + self.assertEqual(re.match('(?:.(?!D))++', 'ABCDE').span(), (0, 2)) + self.assertEqual(re.match('(?>(?:.(?!D))*)', 'ABCDE').span(), (0, 2)) + self.assertEqual(re.match('(?:.(?!D))*+', 'ABCDE').span(), (0, 2)) + self.assertEqual(re.match('(?>(?:.(?!D))?)', 'CDE').span(), (0, 0)) + self.assertEqual(re.match('(?:.(?!D))?+', 'CDE').span(), (0, 0)) + self.assertEqual(re.match('(?>(?:.(?!D)){1,3})', 'ABCDE').span(), (0, 2)) + self.assertEqual(re.match('(?:.(?!D)){1,3}+', 'ABCDE').span(), (0, 2)) + # gh-106052 + self.assertEqual(re.match("(?>(?:ab?c)+)", "aca").span(), (0, 2)) + self.assertEqual(re.match("(?:ab?c)++", "aca").span(), (0, 2)) + self.assertEqual(re.match("(?>(?:ab?c)*)", "aca").span(), (0, 2)) + self.assertEqual(re.match("(?:ab?c)*+", "aca").span(), (0, 2)) + self.assertEqual(re.match("(?>(?:ab?c)?)", "a").span(), (0, 0)) + self.assertEqual(re.match("(?:ab?c)?+", "a").span(), (0, 0)) + self.assertEqual(re.match("(?>(?:ab?c){1,3})", "aca").span(), (0, 2)) + self.assertEqual(re.match("(?:ab?c){1,3}+", "aca").span(), (0, 2)) + @unittest.skipIf(multiprocessing is None, 'test requires multiprocessing') def test_regression_gh94675(self): pattern = re.compile(r'(?<=[({}])(((//[^\n]*)?[\n])([\000-\040])*)*' @@ -2533,7 +2466,10 @@ ELSE def test_atomic_group(self): self.assertEqual(get_debug_out(r'(?>ab?)'), '''\ -ATOMIC_GROUP [(LITERAL, 97), (MAX_REPEAT, (0, 1, [(LITERAL, 98)]))] +ATOMIC_GROUP + LITERAL 97 + MAX_REPEAT 0 1 + LITERAL 98 0. INFO 4 0b0 1 2 (to 5) 5: ATOMIC_GROUP 11 (to 17) @@ -2717,6 +2653,75 @@ class ImplementationTest(unittest.TestCase): self.assertTrue(hasattr(mod, attr)) del sys.modules[name] + @cpython_only + def test_case_helpers(self): + import _sre + for i in range(128): + c = chr(i) + lo = ord(c.lower()) + self.assertEqual(_sre.ascii_tolower(i), lo) + self.assertEqual(_sre.unicode_tolower(i), lo) + iscased = c in string.ascii_letters + self.assertEqual(_sre.ascii_iscased(i), iscased) + self.assertEqual(_sre.unicode_iscased(i), iscased) + + for i in list(range(128, 0x1000)) + [0x10400, 0x10428]: + c = chr(i) + self.assertEqual(_sre.ascii_tolower(i), i) + if i != 0x0130: + self.assertEqual(_sre.unicode_tolower(i), ord(c.lower())) + iscased = c != c.lower() or c != c.upper() + self.assertFalse(_sre.ascii_iscased(i)) + self.assertEqual(_sre.unicode_iscased(i), + c != c.lower() or c != c.upper()) + + self.assertEqual(_sre.ascii_tolower(0x0130), 0x0130) + self.assertEqual(_sre.unicode_tolower(0x0130), ord('i')) + self.assertFalse(_sre.ascii_iscased(0x0130)) + self.assertTrue(_sre.unicode_iscased(0x0130)) + + @cpython_only + def test_dealloc(self): + # issue 3299: check for segfault in debug build + import _sre + # the overflow limit is different on wide and narrow builds and it + # depends on the definition of SRE_CODE (see sre.h). + # 2**128 should be big enough to overflow on both. For smaller values + # a RuntimeError is raised instead of OverflowError. + long_overflow = 2**128 + self.assertRaises(TypeError, re.finditer, "a", {}) + with self.assertRaises(OverflowError): + _sre.compile("abc", 0, [long_overflow], 0, {}, ()) + with self.assertRaises(TypeError): + _sre.compile({}, 0, [], 0, [], []) + + @cpython_only + def test_repeat_minmax_overflow_maxrepeat(self): + try: + from _sre import MAXREPEAT + except ImportError: + self.skipTest('requires _sre.MAXREPEAT constant') + string = "x" * 100000 + self.assertIsNone(re.match(r".{%d}" % (MAXREPEAT - 1), string)) + self.assertEqual(re.match(r".{,%d}" % (MAXREPEAT - 1), string).span(), + (0, 100000)) + self.assertIsNone(re.match(r".{%d,}?" % (MAXREPEAT - 1), string)) + self.assertRaises(OverflowError, re.compile, r".{%d}" % MAXREPEAT) + self.assertRaises(OverflowError, re.compile, r".{,%d}" % MAXREPEAT) + self.assertRaises(OverflowError, re.compile, r".{%d,}?" % MAXREPEAT) + + @cpython_only + def test_sre_template_invalid_group_index(self): + # see gh-106524 + import _sre + with self.assertRaises(TypeError) as cm: + _sre.template("", ["", -1, ""]) + self.assertIn("invalid template", str(cm.exception)) + with self.assertRaises(TypeError) as cm: + _sre.template("", ["", (), ""]) + self.assertIn("an integer is required", str(cm.exception)) + + class ExternalTests(unittest.TestCase): def test_re_benchmarks(self): diff --git a/Lib/test/test_regrtest.py b/Lib/test/test_regrtest.py index 15e2f89e..a72c052c 100644 --- a/Lib/test/test_regrtest.py +++ b/Lib/test/test_regrtest.py @@ -5,8 +5,10 @@ Note: test_regrtest cannot be run twice in parallel. """ import contextlib +import dataclasses import glob import io +import locale import os.path import platform import re @@ -15,21 +17,26 @@ import sys import sysconfig import tempfile import textwrap -import time import unittest from test import libregrtest from test import support -from test.support import os_helper +from test.support import os_helper, TestStats from test.libregrtest import utils, setup +from test.libregrtest.runtest import normalize_test_name if not support.has_subprocess_support: raise unittest.SkipTest("test module requires subprocess") -Py_DEBUG = hasattr(sys, 'gettotalrefcount') ROOT_DIR = os.path.join(os.path.dirname(__file__), '..', '..') ROOT_DIR = os.path.abspath(os.path.normpath(ROOT_DIR)) LOG_PREFIX = r'[0-9]+:[0-9]+:[0-9]+ (?:load avg: [0-9]+\.[0-9]{2} )?' +EXITCODE_BAD_TEST = 2 +EXITCODE_ENV_CHANGED = 3 +EXITCODE_NO_TESTS_RAN = 4 +EXITCODE_RERUN_FAIL = 5 +EXITCODE_INTERRUPTED = 130 + TEST_INTERRUPTED = textwrap.dedent(""" from signal import SIGINT, raise_signal try: @@ -92,11 +99,11 @@ class ParseArgsTestCase(unittest.TestCase): ns = libregrtest._parse_args([]) self.assertEqual(ns.verbose, 0) - def test_verbose2(self): - for opt in '-w', '--verbose2': + def test_rerun(self): + for opt in '-w', '--rerun', '--verbose2': with self.subTest(opt=opt): ns = libregrtest._parse_args([opt]) - self.assertTrue(ns.verbose2) + self.assertTrue(ns.rerun) def test_verbose3(self): for opt in '-W', '--verbose3': @@ -358,6 +365,13 @@ class ParseArgsTestCase(unittest.TestCase): 'unrecognized arguments: --unknown-option') +@dataclasses.dataclass(slots=True) +class Rerun: + name: str + match: str | None + success: bool + + class BaseTestCase(unittest.TestCase): TEST_UNIQUE_ID = 1 TESTNAME_PREFIX = 'test_regrtest_' @@ -405,7 +419,9 @@ class BaseTestCase(unittest.TestCase): self.fail("%r not found in %r" % (regex, output)) return match - def check_line(self, output, regex): + def check_line(self, output, regex, full=False): + if full: + regex += '\n' regex = re.compile(r'^' + regex, re.MULTILINE) self.assertRegex(output, regex) @@ -417,27 +433,42 @@ class BaseTestCase(unittest.TestCase): def check_executed_tests(self, output, tests, skipped=(), failed=(), env_changed=(), omitted=(), - rerun={}, no_test_ran=(), + rerun=None, run_no_tests=(), + resource_denied=(), randomize=False, interrupted=False, - fail_env_changed=False): + fail_env_changed=False, + *, stats, forever=False, filtered=False): if isinstance(tests, str): tests = [tests] if isinstance(skipped, str): skipped = [skipped] + if isinstance(resource_denied, str): + resource_denied = [resource_denied] if isinstance(failed, str): failed = [failed] if isinstance(env_changed, str): env_changed = [env_changed] if isinstance(omitted, str): omitted = [omitted] - if isinstance(no_test_ran, str): - no_test_ran = [no_test_ran] + if isinstance(run_no_tests, str): + run_no_tests = [run_no_tests] + if isinstance(stats, int): + stats = TestStats(stats) + + rerun_failed = [] + if rerun is not None: + failed = [rerun.name] + if not rerun.success: + rerun_failed.append(rerun.name) executed = self.parse_executed_tests(output) + total_tests = list(tests) + if rerun is not None: + total_tests.append(rerun.name) if randomize: - self.assertEqual(set(executed), set(tests), output) + self.assertEqual(set(executed), set(total_tests), output) else: - self.assertEqual(executed, tests, output) + self.assertEqual(executed, total_tests, output) def plural(count): return 's' if count != 1 else '' @@ -453,6 +484,10 @@ class BaseTestCase(unittest.TestCase): regex = list_regex('%s test%s skipped', skipped) self.check_line(output, regex) + if resource_denied: + regex = list_regex(r'%s test%s skipped \(resource denied\)', resource_denied) + self.check_line(output, regex) + if failed: regex = list_regex('%s test%s failed', failed) self.check_line(output, regex) @@ -466,48 +501,90 @@ class BaseTestCase(unittest.TestCase): regex = list_regex('%s test%s omitted', omitted) self.check_line(output, regex) - if rerun: - regex = list_regex('%s re-run test%s', rerun.keys()) + if rerun is not None: + regex = list_regex('%s re-run test%s', [rerun.name]) self.check_line(output, regex) - regex = LOG_PREFIX + r"Re-running failed tests in verbose mode" + regex = LOG_PREFIX + fr"Re-running 1 failed tests in verbose mode" + self.check_line(output, regex) + regex = fr"Re-running {rerun.name} in verbose mode" + if rerun.match: + regex = fr"{regex} \(matching: {rerun.match}\)" self.check_line(output, regex) - for name, match in rerun.items(): - regex = LOG_PREFIX + f"Re-running {name} in verbose mode \\(matching: {match}\\)" - self.check_line(output, regex) - if no_test_ran: - regex = list_regex('%s test%s run no tests', no_test_ran) + if run_no_tests: + regex = list_regex('%s test%s run no tests', run_no_tests) self.check_line(output, regex) - good = (len(tests) - len(skipped) - len(failed) - - len(omitted) - len(env_changed) - len(no_test_ran)) + good = (len(tests) - len(skipped) - len(resource_denied) - len(failed) + - len(omitted) - len(env_changed) - len(run_no_tests)) if good: - regex = r'%s test%s OK\.$' % (good, plural(good)) - if not skipped and not failed and good > 1: + regex = r'%s test%s OK\.' % (good, plural(good)) + if not skipped and not failed and (rerun is None or rerun.success) and good > 1: regex = 'All %s' % regex - self.check_line(output, regex) + self.check_line(output, regex, full=True) if interrupted: self.check_line(output, 'Test suite interrupted by signal SIGINT.') - result = [] + # Total tests + text = f'run={stats.tests_run:,}' + if filtered: + text = fr'{text} \(filtered\)' + parts = [text] + if stats.failures: + parts.append(f'failures={stats.failures:,}') + if stats.skipped: + parts.append(f'skipped={stats.skipped:,}') + line = fr'Total tests: {" ".join(parts)}' + self.check_line(output, line, full=True) + + # Total test files + run = len(total_tests) - len(resource_denied) + if rerun is not None: + total_failed = len(rerun_failed) + total_rerun = 1 + else: + total_failed = len(failed) + total_rerun = 0 + if interrupted: + run = 0 + text = f'run={run}' + if not forever: + text = f'{text}/{len(tests)}' + if filtered: + text = fr'{text} \(filtered\)' + report = [text] + for name, ntest in ( + ('failed', total_failed), + ('env_changed', len(env_changed)), + ('skipped', len(skipped)), + ('resource_denied', len(resource_denied)), + ('rerun', total_rerun), + ('run_no_tests', len(run_no_tests)), + ): + if ntest: + report.append(f'{name}={ntest}') + line = fr'Total test files: {" ".join(report)}' + self.check_line(output, line, full=True) + + # Result + state = [] if failed: - result.append('FAILURE') + state.append('FAILURE') elif fail_env_changed and env_changed: - result.append('ENV CHANGED') + state.append('ENV CHANGED') if interrupted: - result.append('INTERRUPTED') - if not any((good, result, failed, interrupted, skipped, + state.append('INTERRUPTED') + if not any((good, failed, interrupted, skipped, env_changed, fail_env_changed)): - result.append("NO TEST RUN") - elif not result: - result.append('SUCCESS') - result = ', '.join(result) - if rerun: - self.check_line(output, 'Tests result: FAILURE') - result = 'FAILURE then %s' % result - - self.check_line(output, 'Tests result: %s' % result) + state.append("NO TESTS RAN") + elif not state: + state.append('SUCCESS') + state = ', '.join(state) + if rerun is not None: + new_state = 'SUCCESS' if rerun.success else 'FAILURE' + state = 'FAILURE then ' + new_state + self.check_line(output, f'Result: {state}', full=True) def parse_random_seed(self, output): match = self.regex_search(r'Using random seed ([0-9]+)', output) @@ -526,13 +603,13 @@ class BaseTestCase(unittest.TestCase): stdout=subprocess.PIPE, **kw) if proc.returncode != exitcode: - msg = ("Command %s failed with exit code %s\n" + msg = ("Command %s failed with exit code %s, but exit code %s expected!\n" "\n" "stdout:\n" "---\n" "%s\n" "---\n" - % (str(args), proc.returncode, proc.stdout)) + % (str(args), proc.returncode, exitcode, proc.stdout)) if proc.stderr: msg += ("\n" "stderr:\n" @@ -596,7 +673,8 @@ class ProgramsTestCase(BaseTestCase): def check_output(self, output): self.parse_random_seed(output) - self.check_executed_tests(output, self.tests, randomize=True) + self.check_executed_tests(output, self.tests, + randomize=True, stats=len(self.tests)) def run_tests(self, args): output = self.run_python(args) @@ -665,7 +743,7 @@ class ProgramsTestCase(BaseTestCase): test_args.append('-arm32') # 32-bit ARM build elif platform.architecture()[0] == '64bit': test_args.append('-x64') # 64-bit build - if not Py_DEBUG: + if not support.Py_DEBUG: test_args.append('+d') # Release build, use python.exe self.run_batch(script, *test_args, *self.tests) @@ -682,7 +760,7 @@ class ProgramsTestCase(BaseTestCase): rt_args.append('-arm32') # 32-bit ARM build elif platform.architecture()[0] == '64bit': rt_args.append('-x64') # 64-bit build - if Py_DEBUG: + if support.Py_DEBUG: rt_args.append('-d') # Debug build, use python_d.exe self.run_batch(script, *rt_args, *self.regrtest_args, *self.tests) @@ -696,6 +774,40 @@ class ArgsTestCase(BaseTestCase): cmdargs = ['-m', 'test', '--testdir=%s' % self.tmptestdir, *testargs] return self.run_python(cmdargs, **kw) + def test_success(self): + code = textwrap.dedent(""" + import unittest + + class PassingTests(unittest.TestCase): + def test_test1(self): + pass + + def test_test2(self): + pass + + def test_test3(self): + pass + """) + tests = [self.create_test(f'ok{i}', code=code) for i in range(1, 6)] + + output = self.run_tests(*tests) + self.check_executed_tests(output, tests, + stats=3 * len(tests)) + + def test_skip(self): + code = textwrap.dedent(""" + import unittest + raise unittest.SkipTest("nope") + """) + test_ok = self.create_test('ok') + test_skip = self.create_test('skip', code=code) + tests = [test_ok, test_skip] + + output = self.run_tests(*tests) + self.check_executed_tests(output, tests, + skipped=[test_skip], + stats=1) + def test_failing_test(self): # test a failing test code = textwrap.dedent(""" @@ -709,8 +821,9 @@ class ArgsTestCase(BaseTestCase): test_failing = self.create_test('failing', code=code) tests = [test_ok, test_failing] - output = self.run_tests(*tests, exitcode=2) - self.check_executed_tests(output, tests, failed=test_failing) + output = self.run_tests(*tests, exitcode=EXITCODE_BAD_TEST) + self.check_executed_tests(output, tests, failed=test_failing, + stats=TestStats(2, 1)) def test_resources(self): # test -u command line option @@ -729,17 +842,19 @@ class ArgsTestCase(BaseTestCase): # -u all: 2 resources enabled output = self.run_tests('-u', 'all', *test_names) - self.check_executed_tests(output, test_names) + self.check_executed_tests(output, test_names, stats=2) # -u audio: 1 resource enabled output = self.run_tests('-uaudio', *test_names) self.check_executed_tests(output, test_names, - skipped=tests['network']) + resource_denied=tests['network'], + stats=1) # no option: 0 resources enabled - output = self.run_tests(*test_names) + output = self.run_tests(*test_names, exitcode=EXITCODE_NO_TESTS_RAN) self.check_executed_tests(output, test_names, - skipped=test_names) + resource_denied=test_names, + stats=0) def test_random(self): # test -r and --randseed command line option @@ -750,13 +865,14 @@ class ArgsTestCase(BaseTestCase): test = self.create_test('random', code) # first run to get the output with the random seed - output = self.run_tests('-r', test) + output = self.run_tests('-r', test, exitcode=EXITCODE_NO_TESTS_RAN) randseed = self.parse_random_seed(output) match = self.regex_search(r'TESTRANDOM: ([0-9]+)', output) test_random = int(match.group(1)) # try to reproduce with the random seed - output = self.run_tests('-r', '--randseed=%s' % randseed, test) + output = self.run_tests('-r', '--randseed=%s' % randseed, test, + exitcode=EXITCODE_NO_TESTS_RAN) randseed2 = self.parse_random_seed(output) self.assertEqual(randseed2, randseed) @@ -786,7 +902,8 @@ class ArgsTestCase(BaseTestCase): previous = name output = self.run_tests('--fromfile', filename) - self.check_executed_tests(output, tests) + stats = len(tests) + self.check_executed_tests(output, tests, stats=stats) # test format '[2/7] test_opcodes' with open(filename, "w") as fp: @@ -794,7 +911,7 @@ class ArgsTestCase(BaseTestCase): print("[%s/%s] %s" % (index, len(tests), name), file=fp) output = self.run_tests('--fromfile', filename) - self.check_executed_tests(output, tests) + self.check_executed_tests(output, tests, stats=stats) # test format 'test_opcodes' with open(filename, "w") as fp: @@ -802,7 +919,7 @@ class ArgsTestCase(BaseTestCase): print(name, file=fp) output = self.run_tests('--fromfile', filename) - self.check_executed_tests(output, tests) + self.check_executed_tests(output, tests, stats=stats) # test format 'Lib/test/test_opcodes.py' with open(filename, "w") as fp: @@ -810,20 +927,20 @@ class ArgsTestCase(BaseTestCase): print('Lib/test/%s.py' % name, file=fp) output = self.run_tests('--fromfile', filename) - self.check_executed_tests(output, tests) + self.check_executed_tests(output, tests, stats=stats) def test_interrupted(self): code = TEST_INTERRUPTED test = self.create_test('sigint', code=code) - output = self.run_tests(test, exitcode=130) + output = self.run_tests(test, exitcode=EXITCODE_INTERRUPTED) self.check_executed_tests(output, test, omitted=test, - interrupted=True) + interrupted=True, stats=0) def test_slowest(self): # test --slowest tests = [self.create_test() for index in range(3)] output = self.run_tests("--slowest", *tests) - self.check_executed_tests(output, tests) + self.check_executed_tests(output, tests, stats=len(tests)) regex = ('10 slowest tests:\n' '(?:- %s: .*\n){%s}' % (self.TESTNAME_REGEX, len(tests))) @@ -840,9 +957,10 @@ class ArgsTestCase(BaseTestCase): args = ("--slowest", "-j2", test) else: args = ("--slowest", test) - output = self.run_tests(*args, exitcode=130) + output = self.run_tests(*args, exitcode=EXITCODE_INTERRUPTED) self.check_executed_tests(output, test, - omitted=test, interrupted=True) + omitted=test, interrupted=True, + stats=0) regex = ('10 slowest tests:\n') self.check_line(output, regex) @@ -851,7 +969,7 @@ class ArgsTestCase(BaseTestCase): # test --coverage test = self.create_test('coverage') output = self.run_tests("--coverage", test) - self.check_executed_tests(output, [test]) + self.check_executed_tests(output, [test], stats=1) regex = (r'lines +cov% +module +\(path\)\n' r'(?: *[0-9]+ *[0-9]{1,2}% *[^ ]+ +\([^)]+\)+)+') self.check_line(output, regex) @@ -880,8 +998,21 @@ class ArgsTestCase(BaseTestCase): builtins.__dict__['RUN'] = 1 """) test = self.create_test('forever', code=code) - output = self.run_tests('--forever', test, exitcode=2) - self.check_executed_tests(output, [test]*3, failed=test) + + # --forever + output = self.run_tests('--forever', test, exitcode=EXITCODE_BAD_TEST) + self.check_executed_tests(output, [test]*3, failed=test, + stats=TestStats(3, 1), + forever=True) + + # --forever --rerun + output = self.run_tests('--forever', '--rerun', test, exitcode=0) + self.check_executed_tests(output, [test]*3, + rerun=Rerun(test, + match='test_run', + success=True), + stats=TestStats(4, 1), + forever=True) def check_leak(self, code, what): test = self.create_test('huntrleaks', code=code) @@ -889,9 +1020,9 @@ class ArgsTestCase(BaseTestCase): filename = 'reflog.txt' self.addCleanup(os_helper.unlink, filename) output = self.run_tests('--huntrleaks', '3:3:', test, - exitcode=2, + exitcode=EXITCODE_BAD_TEST, stderr=subprocess.STDOUT) - self.check_executed_tests(output, [test], failed=test) + self.check_executed_tests(output, [test], failed=test, stats=1) line = 'beginning 6 repetitions\n123456\n......\n' self.check_line(output, re.escape(line)) @@ -903,7 +1034,7 @@ class ArgsTestCase(BaseTestCase): reflog = fp.read() self.assertIn(line2, reflog) - @unittest.skipUnless(Py_DEBUG, 'need a debug build') + @unittest.skipUnless(support.Py_DEBUG, 'need a debug build') def test_huntrleaks(self): # test --huntrleaks code = textwrap.dedent(""" @@ -917,7 +1048,7 @@ class ArgsTestCase(BaseTestCase): """) self.check_leak(code, 'references') - @unittest.skipUnless(Py_DEBUG, 'need a debug build') + @unittest.skipUnless(support.Py_DEBUG, 'need a debug build') def test_huntrleaks_fd_leak(self): # test --huntrleaks for file descriptor leak code = textwrap.dedent(""" @@ -971,9 +1102,9 @@ class ArgsTestCase(BaseTestCase): crash_test = self.create_test(name="crash", code=code) tests = [crash_test] - output = self.run_tests("-j2", *tests, exitcode=2) + output = self.run_tests("-j2", *tests, exitcode=EXITCODE_BAD_TEST) self.check_executed_tests(output, tests, failed=crash_test, - randomize=True) + randomize=True, stats=0) def parse_methods(self, output): regex = re.compile("^(test[^ ]+).*ok$", flags=re.MULTILINE) @@ -1068,12 +1199,14 @@ class ArgsTestCase(BaseTestCase): # don't fail by default output = self.run_tests(testname) - self.check_executed_tests(output, [testname], env_changed=testname) + self.check_executed_tests(output, [testname], + env_changed=testname, stats=1) # fail with --fail-env-changed - output = self.run_tests("--fail-env-changed", testname, exitcode=3) + output = self.run_tests("--fail-env-changed", testname, + exitcode=EXITCODE_ENV_CHANGED) self.check_executed_tests(output, [testname], env_changed=testname, - fail_env_changed=True) + fail_env_changed=True, stats=1) def test_rerun_fail(self): # FAILURE then FAILURE @@ -1090,30 +1223,232 @@ class ArgsTestCase(BaseTestCase): """) testname = self.create_test(code=code) - output = self.run_tests("-w", testname, exitcode=2) + output = self.run_tests("--rerun", testname, exitcode=EXITCODE_BAD_TEST) self.check_executed_tests(output, [testname], - failed=testname, rerun={testname: "test_fail_always"}) + rerun=Rerun(testname, + "test_fail_always", + success=False), + stats=TestStats(3, 2)) def test_rerun_success(self): # FAILURE then SUCCESS - code = textwrap.dedent(""" - import builtins + marker_filename = os.path.abspath("regrtest_marker_filename") + self.addCleanup(os_helper.unlink, marker_filename) + self.assertFalse(os.path.exists(marker_filename)) + + code = textwrap.dedent(f""" + import os.path import unittest + marker_filename = {marker_filename!r} + class Tests(unittest.TestCase): def test_succeed(self): return def test_fail_once(self): - if not hasattr(builtins, '_test_failed'): - builtins._test_failed = True + if not os.path.exists(marker_filename): + open(marker_filename, "w").close() self.fail("bug") """) testname = self.create_test(code=code) - output = self.run_tests("-w", testname, exitcode=0) + # FAILURE then SUCCESS => exit code 0 + output = self.run_tests("--rerun", testname, exitcode=0) + self.check_executed_tests(output, [testname], + rerun=Rerun(testname, + match="test_fail_once", + success=True), + stats=TestStats(3, 1)) + os_helper.unlink(marker_filename) + + # with --fail-rerun, exit code EXITCODE_RERUN_FAIL + # on "FAILURE then SUCCESS" state. + output = self.run_tests("--rerun", "--fail-rerun", testname, + exitcode=EXITCODE_RERUN_FAIL) self.check_executed_tests(output, [testname], - rerun={testname: "test_fail_once"}) + rerun=Rerun(testname, + match="test_fail_once", + success=True), + stats=TestStats(3, 1)) + os_helper.unlink(marker_filename) + + def test_rerun_setup_class_hook_failure(self): + # FAILURE then FAILURE + code = textwrap.dedent(""" + import unittest + + class ExampleTests(unittest.TestCase): + @classmethod + def setUpClass(self): + raise RuntimeError('Fail') + + def test_success(self): + return + """) + testname = self.create_test(code=code) + + output = self.run_tests("--rerun", testname, exitcode=EXITCODE_BAD_TEST) + self.check_executed_tests(output, testname, + failed=[testname], + rerun=Rerun(testname, + match="ExampleTests", + success=False), + stats=0) + + def test_rerun_teardown_class_hook_failure(self): + # FAILURE then FAILURE + code = textwrap.dedent(""" + import unittest + + class ExampleTests(unittest.TestCase): + @classmethod + def tearDownClass(self): + raise RuntimeError('Fail') + + def test_success(self): + return + """) + testname = self.create_test(code=code) + + output = self.run_tests("--rerun", testname, exitcode=EXITCODE_BAD_TEST) + self.check_executed_tests(output, testname, + failed=[testname], + rerun=Rerun(testname, + match="ExampleTests", + success=False), + stats=2) + + def test_rerun_setup_module_hook_failure(self): + # FAILURE then FAILURE + code = textwrap.dedent(""" + import unittest + + def setUpModule(): + raise RuntimeError('Fail') + + class ExampleTests(unittest.TestCase): + def test_success(self): + return + """) + testname = self.create_test(code=code) + + output = self.run_tests("--rerun", testname, exitcode=EXITCODE_BAD_TEST) + self.check_executed_tests(output, testname, + failed=[testname], + rerun=Rerun(testname, + match=None, + success=False), + stats=0) + + def test_rerun_teardown_module_hook_failure(self): + # FAILURE then FAILURE + code = textwrap.dedent(""" + import unittest + + def tearDownModule(): + raise RuntimeError('Fail') + + class ExampleTests(unittest.TestCase): + def test_success(self): + return + """) + testname = self.create_test(code=code) + + output = self.run_tests("--rerun", testname, exitcode=EXITCODE_BAD_TEST) + self.check_executed_tests(output, [testname], + failed=[testname], + rerun=Rerun(testname, + match=None, + success=False), + stats=2) + + def test_rerun_setup_hook_failure(self): + # FAILURE then FAILURE + code = textwrap.dedent(""" + import unittest + + class ExampleTests(unittest.TestCase): + def setUp(self): + raise RuntimeError('Fail') + + def test_success(self): + return + """) + testname = self.create_test(code=code) + + output = self.run_tests("--rerun", testname, exitcode=EXITCODE_BAD_TEST) + self.check_executed_tests(output, testname, + failed=[testname], + rerun=Rerun(testname, + match="test_success", + success=False), + stats=2) + + def test_rerun_teardown_hook_failure(self): + # FAILURE then FAILURE + code = textwrap.dedent(""" + import unittest + + class ExampleTests(unittest.TestCase): + def tearDown(self): + raise RuntimeError('Fail') + + def test_success(self): + return + """) + testname = self.create_test(code=code) + + output = self.run_tests("--rerun", testname, exitcode=EXITCODE_BAD_TEST) + self.check_executed_tests(output, testname, + failed=[testname], + rerun=Rerun(testname, + match="test_success", + success=False), + stats=2) + + def test_rerun_async_setup_hook_failure(self): + # FAILURE then FAILURE + code = textwrap.dedent(""" + import unittest + + class ExampleTests(unittest.IsolatedAsyncioTestCase): + async def asyncSetUp(self): + raise RuntimeError('Fail') + + async def test_success(self): + return + """) + testname = self.create_test(code=code) + + output = self.run_tests("--rerun", testname, exitcode=EXITCODE_BAD_TEST) + self.check_executed_tests(output, testname, + rerun=Rerun(testname, + match="test_success", + success=False), + stats=2) + + def test_rerun_async_teardown_hook_failure(self): + # FAILURE then FAILURE + code = textwrap.dedent(""" + import unittest + + class ExampleTests(unittest.IsolatedAsyncioTestCase): + async def asyncTearDown(self): + raise RuntimeError('Fail') + + async def test_success(self): + return + """) + testname = self.create_test(code=code) + + output = self.run_tests("--rerun", testname, exitcode=EXITCODE_BAD_TEST) + self.check_executed_tests(output, testname, + failed=[testname], + rerun=Rerun(testname, + match="test_success", + success=False), + stats=2) def test_no_tests_ran(self): code = textwrap.dedent(""" @@ -1125,8 +1460,11 @@ class ArgsTestCase(BaseTestCase): """) testname = self.create_test(code=code) - output = self.run_tests(testname, "-m", "nosuchtest", exitcode=0) - self.check_executed_tests(output, [testname], no_test_ran=testname) + output = self.run_tests(testname, "-m", "nosuchtest", + exitcode=EXITCODE_NO_TESTS_RAN) + self.check_executed_tests(output, [testname], + run_no_tests=testname, + stats=0, filtered=True) def test_no_tests_ran_skip(self): code = textwrap.dedent(""" @@ -1138,8 +1476,9 @@ class ArgsTestCase(BaseTestCase): """) testname = self.create_test(code=code) - output = self.run_tests(testname, exitcode=0) - self.check_executed_tests(output, [testname]) + output = self.run_tests(testname) + self.check_executed_tests(output, [testname], + stats=TestStats(1, skipped=1)) def test_no_tests_ran_multiple_tests_nonexistent(self): code = textwrap.dedent(""" @@ -1152,9 +1491,11 @@ class ArgsTestCase(BaseTestCase): testname = self.create_test(code=code) testname2 = self.create_test(code=code) - output = self.run_tests(testname, testname2, "-m", "nosuchtest", exitcode=0) + output = self.run_tests(testname, testname2, "-m", "nosuchtest", + exitcode=EXITCODE_NO_TESTS_RAN) self.check_executed_tests(output, [testname, testname2], - no_test_ran=[testname, testname2]) + run_no_tests=[testname, testname2], + stats=0, filtered=True) def test_no_test_ran_some_test_exist_some_not(self): code = textwrap.dedent(""" @@ -1177,7 +1518,8 @@ class ArgsTestCase(BaseTestCase): output = self.run_tests(testname, testname2, "-m", "nosuchtest", "-m", "test_other_bug", exitcode=0) self.check_executed_tests(output, [testname, testname2], - no_test_ran=[testname]) + run_no_tests=[testname], + stats=1, filtered=True) @support.cpython_only def test_uncollectable(self): @@ -1200,10 +1542,12 @@ class ArgsTestCase(BaseTestCase): """) testname = self.create_test(code=code) - output = self.run_tests("--fail-env-changed", testname, exitcode=3) + output = self.run_tests("--fail-env-changed", testname, + exitcode=EXITCODE_ENV_CHANGED) self.check_executed_tests(output, [testname], env_changed=[testname], - fail_env_changed=True) + fail_env_changed=True, + stats=1) def test_multiprocessing_timeout(self): code = textwrap.dedent(r""" @@ -1226,9 +1570,10 @@ class ArgsTestCase(BaseTestCase): """) testname = self.create_test(code=code) - output = self.run_tests("-j2", "--timeout=1.0", testname, exitcode=2) + output = self.run_tests("-j2", "--timeout=1.0", testname, + exitcode=EXITCODE_BAD_TEST) self.check_executed_tests(output, [testname], - failed=testname) + failed=testname, stats=0) self.assertRegex(output, re.compile('%s timed out' % testname, re.MULTILINE)) @@ -1258,10 +1603,12 @@ class ArgsTestCase(BaseTestCase): """) testname = self.create_test(code=code) - output = self.run_tests("--fail-env-changed", "-v", testname, exitcode=3) + output = self.run_tests("--fail-env-changed", "-v", testname, + exitcode=EXITCODE_ENV_CHANGED) self.check_executed_tests(output, [testname], env_changed=[testname], - fail_env_changed=True) + fail_env_changed=True, + stats=1) self.assertIn("Warning -- Unraisable exception", output) self.assertIn("Exception: weakref callback bug", output) @@ -1289,10 +1636,12 @@ class ArgsTestCase(BaseTestCase): """) testname = self.create_test(code=code) - output = self.run_tests("--fail-env-changed", "-v", testname, exitcode=3) + output = self.run_tests("--fail-env-changed", "-v", testname, + exitcode=EXITCODE_ENV_CHANGED) self.check_executed_tests(output, [testname], env_changed=[testname], - fail_env_changed=True) + fail_env_changed=True, + stats=1) self.assertIn("Warning -- Uncaught thread exception", output) self.assertIn("Exception: bug in thread", output) @@ -1330,10 +1679,11 @@ class ArgsTestCase(BaseTestCase): for option in ("-v", "-W"): with self.subTest(option=option): cmd = ["--fail-env-changed", option, testname] - output = self.run_tests(*cmd, exitcode=3) + output = self.run_tests(*cmd, exitcode=EXITCODE_ENV_CHANGED) self.check_executed_tests(output, [testname], env_changed=[testname], - fail_env_changed=True) + fail_env_changed=True, + stats=1) self.assertRegex(output, regex) def test_unicode_guard_env(self): @@ -1359,6 +1709,109 @@ class ArgsTestCase(BaseTestCase): for name in names: self.assertFalse(os.path.exists(name), name) + @unittest.skipIf(support.is_wasi, + 'checking temp files is not implemented on WASI') + def test_leak_tmp_file(self): + code = textwrap.dedent(r""" + import os.path + import tempfile + import unittest + + class FileTests(unittest.TestCase): + def test_leak_tmp_file(self): + filename = os.path.join(tempfile.gettempdir(), 'mytmpfile') + with open(filename, "wb") as fp: + fp.write(b'content') + """) + testnames = [self.create_test(code=code) for _ in range(3)] + + output = self.run_tests("--fail-env-changed", "-v", "-j2", *testnames, + exitcode=EXITCODE_ENV_CHANGED) + self.check_executed_tests(output, testnames, + env_changed=testnames, + fail_env_changed=True, + randomize=True, + stats=len(testnames)) + for testname in testnames: + self.assertIn(f"Warning -- {testname} leaked temporary " + f"files (1): mytmpfile", + output) + + def test_mp_decode_error(self): + # gh-101634: If a worker stdout cannot be decoded, report a failed test + # and a non-zero exit code. + if sys.platform == 'win32': + encoding = locale.getencoding() + else: + encoding = sys.stdout.encoding + if encoding is None: + encoding = sys.__stdout__.encoding + if encoding is None: + self.skipTest(f"cannot get regrtest worker encoding") + + nonascii = b"byte:\xa0\xa9\xff\n" + try: + nonascii.decode(encoding) + except UnicodeDecodeError: + pass + else: + self.skipTest(f"{encoding} can decode non-ASCII bytes {nonascii!a}") + + code = textwrap.dedent(fr""" + import sys + # bytes which cannot be decoded from UTF-8 + nonascii = {nonascii!a} + sys.stdout.buffer.write(nonascii) + sys.stdout.buffer.flush() + """) + testname = self.create_test(code=code) + + output = self.run_tests("--fail-env-changed", "-v", "-j1", testname, + exitcode=EXITCODE_BAD_TEST) + self.check_executed_tests(output, [testname], + failed=[testname], + randomize=True, + stats=0) + + def test_doctest(self): + code = textwrap.dedent(fr''' + import doctest + import sys + from test import support + + def my_function(): + """ + Pass: + + >>> 1 + 1 + 2 + + Failure: + + >>> 2 + 3 + 23 + >>> 1 + 1 + 11 + + Skipped test (ignored): + + >>> id(1.0) # doctest: +SKIP + 7948648 + """ + + def load_tests(loader, tests, pattern): + tests.addTest(doctest.DocTestSuite()) + return tests + ''') + testname = self.create_test(code=code) + + output = self.run_tests("--fail-env-changed", "-v", "-j1", testname, + exitcode=EXITCODE_BAD_TEST) + self.check_executed_tests(output, [testname], + failed=[testname], + randomize=True, + stats=TestStats(1, 1, 0)) + class TestUtils(unittest.TestCase): def test_format_duration(self): @@ -1383,6 +1836,17 @@ class TestUtils(unittest.TestCase): self.assertEqual(utils.format_duration(3 * 3600 + 1), '3 hour 1 sec') + def test_normalize_test_name(self): + normalize = normalize_test_name + self.assertEqual(normalize('test_access (test.test_os.FileTests.test_access)'), + 'test_access') + self.assertEqual(normalize('setUpClass (test.test_os.ChownFileTests)', is_error=True), + 'ChownFileTests') + self.assertEqual(normalize('test_success (test.test_bug.ExampleTests.test_success)', is_error=True), + 'test_success') + self.assertIsNone(normalize('setUpModule (test.test_x)', is_error=True)) + self.assertIsNone(normalize('tearDownModule (test.test_module)', is_error=True)) + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_reprlib.py b/Lib/test/test_reprlib.py index aa326399..e7216d42 100644 --- a/Lib/test/test_reprlib.py +++ b/Lib/test/test_reprlib.py @@ -9,6 +9,7 @@ import shutil import importlib import importlib.util import unittest +import textwrap from test.support import verbose from test.support.os_helper import create_empty_file @@ -25,6 +26,29 @@ def nestedTuple(nesting): class ReprTests(unittest.TestCase): + def test_init_kwargs(self): + example_kwargs = { + "maxlevel": 101, + "maxtuple": 102, + "maxlist": 103, + "maxarray": 104, + "maxdict": 105, + "maxset": 106, + "maxfrozenset": 107, + "maxdeque": 108, + "maxstring": 109, + "maxlong": 110, + "maxother": 111, + "fillvalue": "x" * 112, + "indent": "x" * 113, + } + r1 = Repr() + for attr, val in example_kwargs.items(): + setattr(r1, attr, val) + r2 = Repr(**example_kwargs) + for attr in example_kwargs: + self.assertEqual(getattr(r1, attr), getattr(r2, attr), msg=attr) + def test_string(self): eq = self.assertEqual eq(r("abc"), "'abc'") @@ -224,6 +248,338 @@ class ReprTests(unittest.TestCase): r(y) r(z) + def test_valid_indent(self): + test_cases = [ + { + 'object': (), + 'tests': ( + (dict(indent=None), '()'), + (dict(indent=False), '()'), + (dict(indent=True), '()'), + (dict(indent=0), '()'), + (dict(indent=1), '()'), + (dict(indent=4), '()'), + (dict(indent=4, maxlevel=2), '()'), + (dict(indent=''), '()'), + (dict(indent='-->'), '()'), + (dict(indent='....'), '()'), + ), + }, + { + 'object': '', + 'tests': ( + (dict(indent=None), "''"), + (dict(indent=False), "''"), + (dict(indent=True), "''"), + (dict(indent=0), "''"), + (dict(indent=1), "''"), + (dict(indent=4), "''"), + (dict(indent=4, maxlevel=2), "''"), + (dict(indent=''), "''"), + (dict(indent='-->'), "''"), + (dict(indent='....'), "''"), + ), + }, + { + 'object': [1, 'spam', {'eggs': True, 'ham': []}], + 'tests': ( + (dict(indent=None), '''\ + [1, 'spam', {'eggs': True, 'ham': []}]'''), + (dict(indent=False), '''\ + [ + 1, + 'spam', + { + 'eggs': True, + 'ham': [], + }, + ]'''), + (dict(indent=True), '''\ + [ + 1, + 'spam', + { + 'eggs': True, + 'ham': [], + }, + ]'''), + (dict(indent=0), '''\ + [ + 1, + 'spam', + { + 'eggs': True, + 'ham': [], + }, + ]'''), + (dict(indent=1), '''\ + [ + 1, + 'spam', + { + 'eggs': True, + 'ham': [], + }, + ]'''), + (dict(indent=4), '''\ + [ + 1, + 'spam', + { + 'eggs': True, + 'ham': [], + }, + ]'''), + (dict(indent=4, maxlevel=2), '''\ + [ + 1, + 'spam', + { + 'eggs': True, + 'ham': [], + }, + ]'''), + (dict(indent=''), '''\ + [ + 1, + 'spam', + { + 'eggs': True, + 'ham': [], + }, + ]'''), + (dict(indent='-->'), '''\ + [ + -->1, + -->'spam', + -->{ + -->-->'eggs': True, + -->-->'ham': [], + -->}, + ]'''), + (dict(indent='....'), '''\ + [ + ....1, + ....'spam', + ....{ + ........'eggs': True, + ........'ham': [], + ....}, + ]'''), + ), + }, + { + 'object': { + 1: 'two', + b'three': [ + (4.5, 6.7), + [set((8, 9)), frozenset((10, 11))], + ], + }, + 'tests': ( + (dict(indent=None), '''\ + {1: 'two', b'three': [(4.5, 6.7), [{8, 9}, frozenset({10, 11})]]}'''), + (dict(indent=False), '''\ + { + 1: 'two', + b'three': [ + ( + 4.5, + 6.7, + ), + [ + { + 8, + 9, + }, + frozenset({ + 10, + 11, + }), + ], + ], + }'''), + (dict(indent=True), '''\ + { + 1: 'two', + b'three': [ + ( + 4.5, + 6.7, + ), + [ + { + 8, + 9, + }, + frozenset({ + 10, + 11, + }), + ], + ], + }'''), + (dict(indent=0), '''\ + { + 1: 'two', + b'three': [ + ( + 4.5, + 6.7, + ), + [ + { + 8, + 9, + }, + frozenset({ + 10, + 11, + }), + ], + ], + }'''), + (dict(indent=1), '''\ + { + 1: 'two', + b'three': [ + ( + 4.5, + 6.7, + ), + [ + { + 8, + 9, + }, + frozenset({ + 10, + 11, + }), + ], + ], + }'''), + (dict(indent=4), '''\ + { + 1: 'two', + b'three': [ + ( + 4.5, + 6.7, + ), + [ + { + 8, + 9, + }, + frozenset({ + 10, + 11, + }), + ], + ], + }'''), + (dict(indent=4, maxlevel=2), '''\ + { + 1: 'two', + b'three': [ + (...), + [...], + ], + }'''), + (dict(indent=''), '''\ + { + 1: 'two', + b'three': [ + ( + 4.5, + 6.7, + ), + [ + { + 8, + 9, + }, + frozenset({ + 10, + 11, + }), + ], + ], + }'''), + (dict(indent='-->'), '''\ + { + -->1: 'two', + -->b'three': [ + -->-->( + -->-->-->4.5, + -->-->-->6.7, + -->-->), + -->-->[ + -->-->-->{ + -->-->-->-->8, + -->-->-->-->9, + -->-->-->}, + -->-->-->frozenset({ + -->-->-->-->10, + -->-->-->-->11, + -->-->-->}), + -->-->], + -->], + }'''), + (dict(indent='....'), '''\ + { + ....1: 'two', + ....b'three': [ + ........( + ............4.5, + ............6.7, + ........), + ........[ + ............{ + ................8, + ................9, + ............}, + ............frozenset({ + ................10, + ................11, + ............}), + ........], + ....], + }'''), + ), + }, + ] + for test_case in test_cases: + with self.subTest(test_object=test_case['object']): + for repr_settings, expected_repr in test_case['tests']: + with self.subTest(repr_settings=repr_settings): + r = Repr() + for attribute, value in repr_settings.items(): + setattr(r, attribute, value) + resulting_repr = r.repr(test_case['object']) + expected_repr = textwrap.dedent(expected_repr) + self.assertEqual(resulting_repr, expected_repr) + + def test_invalid_indent(self): + test_object = [1, 'spam', {'eggs': True, 'ham': []}] + test_cases = [ + (-1, (ValueError, '[Nn]egative|[Pp]ositive')), + (-4, (ValueError, '[Nn]egative|[Pp]ositive')), + ((), (TypeError, None)), + ([], (TypeError, None)), + ((4,), (TypeError, None)), + ([4,], (TypeError, None)), + (object(), (TypeError, None)), + ] + for indent, (expected_error, expected_msg) in test_cases: + with self.subTest(indent=indent): + r = Repr() + r.indent = indent + expected_msg = expected_msg or f'{type(indent)}' + with self.assertRaisesRegex(expected_error, expected_msg): + r.repr(test_object) + def write_file(path, text): with open(path, 'w', encoding='ASCII') as fp: fp.write(text) diff --git a/Lib/test/test_runpy.py b/Lib/test/test_runpy.py index 6aaa288c..628c8cae 100644 --- a/Lib/test/test_runpy.py +++ b/Lib/test/test_runpy.py @@ -12,7 +12,7 @@ import tempfile import textwrap import unittest import warnings -from test.support import no_tracing, verbose, requires_subprocess +from test.support import no_tracing, verbose, requires_subprocess, requires_resource from test.support.import_helper import forget, make_legacy_pyc, unload from test.support.os_helper import create_empty_file, temp_dir from test.support.script_helper import make_script, make_zip_script @@ -733,6 +733,7 @@ class RunPathTestCase(unittest.TestCase, CodeExecutionMixin): self._check_import_error(zip_name, msg) @no_tracing + @requires_resource('cpu') def test_main_recursion_error(self): with temp_dir() as script_dir, temp_dir() as dummy_dir: mod_name = '__main__' diff --git a/Lib/test/test_select.py b/Lib/test/test_select.py index ca2a9d9d..a82584d6 100644 --- a/Lib/test/test_select.py +++ b/Lib/test/test_select.py @@ -1,5 +1,4 @@ import errno -import os import select import subprocess import sys diff --git a/Lib/test/test_selectors.py b/Lib/test/test_selectors.py index c2db88c2..12ecc50d 100644 --- a/Lib/test/test_selectors.py +++ b/Lib/test/test_selectors.py @@ -449,6 +449,7 @@ class ScalableSelectorMixIn: # see issue #18963 for why it's skipped on older OS X versions @support.requires_mac_ver(10, 5) @unittest.skipUnless(resource, "Test needs resource module") + @support.requires_resource('cpu') def test_above_fd_setsize(self): # A scalable implementation should have no problem with more than # FD_SETSIZE file descriptors. Since we don't know the value, we just diff --git a/Lib/test/test_set.py b/Lib/test/test_set.py index 43f23dbb..2dd65240 100644 --- a/Lib/test/test_set.py +++ b/Lib/test/test_set.py @@ -427,7 +427,7 @@ class TestSet(TestJointOps, unittest.TestCase): self.assertRaises(KeyError, self.s.remove, self.thetype(self.word)) def test_remove_keyerror_unpacking(self): - # bug: www.python.org/sf/1576657 + # https://bugs.python.org/issue1576657 for v1 in ['Q', (1,)]: try: self.s.remove(v1) diff --git a/Lib/test/test_shelve.py b/Lib/test/test_shelve.py index b9eb007c..08c6562f 100644 --- a/Lib/test/test_shelve.py +++ b/Lib/test/test_shelve.py @@ -1,11 +1,9 @@ import unittest import dbm import shelve -import glob import pickle import os -from test import support from test.support import os_helper from collections.abc import MutableMapping from test.test_dbm import dbm_iterator diff --git a/Lib/test/test_shlex.py b/Lib/test/test_shlex.py index 3081a785..797c91ee 100644 --- a/Lib/test/test_shlex.py +++ b/Lib/test/test_shlex.py @@ -3,7 +3,6 @@ import itertools import shlex import string import unittest -from unittest import mock # The original test data set was from shellwords, by Hartmut Goebel. @@ -162,9 +161,8 @@ class ShlexTest(unittest.TestCase): tok = lex.get_token() return ret - @mock.patch('sys.stdin', io.StringIO()) - def testSplitNoneDeprecation(self): - with self.assertWarns(DeprecationWarning): + def testSplitNone(self): + with self.assertRaises(ValueError): shlex.split(None) def testSplitPosix(self): diff --git a/Lib/test/test_shutil.py b/Lib/test/test_shutil.py index 055c9af2..cd1c3d8c 100644 --- a/Lib/test/test_shutil.py +++ b/Lib/test/test_shutil.py @@ -23,6 +23,7 @@ from shutil import (make_archive, unregister_unpack_format, get_unpack_formats, SameFileError, _GiveupOnFastCopy) import tarfile +import warnings import zipfile try: import posix @@ -32,6 +33,7 @@ except ImportError: from test import support from test.support import os_helper from test.support.os_helper import TESTFN, FakePath +from test.support import warnings_helper TESTFN2 = TESTFN + "2" TESTFN_SRC = TESTFN + "_SRC" @@ -195,7 +197,7 @@ class TestRmTree(BaseTest, unittest.TestCase): shutil.rmtree(victim) @os_helper.skip_unless_symlink - def test_rmtree_fails_on_symlink(self): + def test_rmtree_fails_on_symlink_onerror(self): tmp = self.mkdtemp() dir_ = os.path.join(tmp, 'dir') os.mkdir(dir_) @@ -207,12 +209,32 @@ class TestRmTree(BaseTest, unittest.TestCase): errors = [] def onerror(*args): errors.append(args) - shutil.rmtree(link, onerror=onerror) + with self.assertWarns(DeprecationWarning): + shutil.rmtree(link, onerror=onerror) self.assertEqual(len(errors), 1) self.assertIs(errors[0][0], os.path.islink) self.assertEqual(errors[0][1], link) self.assertIsInstance(errors[0][2][1], OSError) + @os_helper.skip_unless_symlink + def test_rmtree_fails_on_symlink_onexc(self): + tmp = self.mkdtemp() + dir_ = os.path.join(tmp, 'dir') + os.mkdir(dir_) + link = os.path.join(tmp, 'link') + os.symlink(dir_, link) + self.assertRaises(OSError, shutil.rmtree, link) + self.assertTrue(os.path.exists(dir_)) + self.assertTrue(os.path.lexists(link)) + errors = [] + def onexc(*args): + errors.append(args) + shutil.rmtree(link, onexc=onexc) + self.assertEqual(len(errors), 1) + self.assertIs(errors[0][0], os.path.islink) + self.assertEqual(errors[0][1], link) + self.assertIsInstance(errors[0][2], OSError) + @os_helper.skip_unless_symlink def test_rmtree_works_on_symlinks(self): tmp = self.mkdtemp() @@ -236,7 +258,7 @@ class TestRmTree(BaseTest, unittest.TestCase): self.assertTrue(os.path.exists(file1)) @unittest.skipUnless(_winapi, 'only relevant on Windows') - def test_rmtree_fails_on_junctions(self): + def test_rmtree_fails_on_junctions_onerror(self): tmp = self.mkdtemp() dir_ = os.path.join(tmp, 'dir') os.mkdir(dir_) @@ -249,12 +271,33 @@ class TestRmTree(BaseTest, unittest.TestCase): errors = [] def onerror(*args): errors.append(args) - shutil.rmtree(link, onerror=onerror) + with self.assertWarns(DeprecationWarning): + shutil.rmtree(link, onerror=onerror) self.assertEqual(len(errors), 1) self.assertIs(errors[0][0], os.path.islink) self.assertEqual(errors[0][1], link) self.assertIsInstance(errors[0][2][1], OSError) + @unittest.skipUnless(_winapi, 'only relevant on Windows') + def test_rmtree_fails_on_junctions_onexc(self): + tmp = self.mkdtemp() + dir_ = os.path.join(tmp, 'dir') + os.mkdir(dir_) + link = os.path.join(tmp, 'link') + _winapi.CreateJunction(dir_, link) + self.addCleanup(os_helper.unlink, link) + self.assertRaises(OSError, shutil.rmtree, link) + self.assertTrue(os.path.exists(dir_)) + self.assertTrue(os.path.lexists(link)) + errors = [] + def onexc(*args): + errors.append(args) + shutil.rmtree(link, onexc=onexc) + self.assertEqual(len(errors), 1) + self.assertIs(errors[0][0], os.path.islink) + self.assertEqual(errors[0][1], link) + self.assertIsInstance(errors[0][2], OSError) + @unittest.skipUnless(_winapi, 'only relevant on Windows') def test_rmtree_works_on_junctions(self): tmp = self.mkdtemp() @@ -277,7 +320,7 @@ class TestRmTree(BaseTest, unittest.TestCase): self.assertTrue(os.path.exists(dir3)) self.assertTrue(os.path.exists(file1)) - def test_rmtree_errors(self): + def test_rmtree_errors_onerror(self): # filename is guaranteed not to exist filename = tempfile.mktemp(dir=self.mkdtemp()) self.assertRaises(FileNotFoundError, shutil.rmtree, filename) @@ -298,7 +341,8 @@ class TestRmTree(BaseTest, unittest.TestCase): errors = [] def onerror(*args): errors.append(args) - shutil.rmtree(filename, onerror=onerror) + with self.assertWarns(DeprecationWarning): + shutil.rmtree(filename, onerror=onerror) self.assertEqual(len(errors), 2) self.assertIs(errors[0][0], os.scandir) self.assertEqual(errors[0][1], filename) @@ -309,6 +353,37 @@ class TestRmTree(BaseTest, unittest.TestCase): self.assertIsInstance(errors[1][2][1], NotADirectoryError) self.assertEqual(errors[1][2][1].filename, filename) + def test_rmtree_errors_onexc(self): + # filename is guaranteed not to exist + filename = tempfile.mktemp(dir=self.mkdtemp()) + self.assertRaises(FileNotFoundError, shutil.rmtree, filename) + # test that ignore_errors option is honored + shutil.rmtree(filename, ignore_errors=True) + + # existing file + tmpdir = self.mkdtemp() + write_file((tmpdir, "tstfile"), "") + filename = os.path.join(tmpdir, "tstfile") + with self.assertRaises(NotADirectoryError) as cm: + shutil.rmtree(filename) + self.assertEqual(cm.exception.filename, filename) + self.assertTrue(os.path.exists(filename)) + # test that ignore_errors option is honored + shutil.rmtree(filename, ignore_errors=True) + self.assertTrue(os.path.exists(filename)) + errors = [] + def onexc(*args): + errors.append(args) + shutil.rmtree(filename, onexc=onexc) + self.assertEqual(len(errors), 2) + self.assertIs(errors[0][0], os.scandir) + self.assertEqual(errors[0][1], filename) + self.assertIsInstance(errors[0][2], NotADirectoryError) + self.assertEqual(errors[0][2].filename, filename) + self.assertIs(errors[1][0], os.rmdir) + self.assertEqual(errors[1][1], filename) + self.assertIsInstance(errors[1][2], NotADirectoryError) + self.assertEqual(errors[1][2].filename, filename) @unittest.skipIf(sys.platform[:6] == 'cygwin', "This test can't be run on Cygwin (issue #1071513).") @@ -336,7 +411,8 @@ class TestRmTree(BaseTest, unittest.TestCase): self.addCleanup(os.chmod, self.child_file_path, old_child_file_mode) self.addCleanup(os.chmod, self.child_dir_path, old_child_dir_mode) - shutil.rmtree(TESTFN, onerror=self.check_args_to_onerror) + with self.assertWarns(DeprecationWarning): + shutil.rmtree(TESTFN, onerror=self.check_args_to_onerror) # Test whether onerror has actually been called. self.assertEqual(self.errorState, 3, "Expected call to onerror function did not happen.") @@ -368,6 +444,105 @@ class TestRmTree(BaseTest, unittest.TestCase): self.assertTrue(issubclass(exc[0], OSError)) self.errorState = 3 + @unittest.skipIf(sys.platform[:6] == 'cygwin', + "This test can't be run on Cygwin (issue #1071513).") + @os_helper.skip_if_dac_override + @os_helper.skip_unless_working_chmod + def test_on_exc(self): + self.errorState = 0 + os.mkdir(TESTFN) + self.addCleanup(shutil.rmtree, TESTFN) + + self.child_file_path = os.path.join(TESTFN, 'a') + self.child_dir_path = os.path.join(TESTFN, 'b') + os_helper.create_empty_file(self.child_file_path) + os.mkdir(self.child_dir_path) + old_dir_mode = os.stat(TESTFN).st_mode + old_child_file_mode = os.stat(self.child_file_path).st_mode + old_child_dir_mode = os.stat(self.child_dir_path).st_mode + # Make unwritable. + new_mode = stat.S_IREAD|stat.S_IEXEC + os.chmod(self.child_file_path, new_mode) + os.chmod(self.child_dir_path, new_mode) + os.chmod(TESTFN, new_mode) + + self.addCleanup(os.chmod, TESTFN, old_dir_mode) + self.addCleanup(os.chmod, self.child_file_path, old_child_file_mode) + self.addCleanup(os.chmod, self.child_dir_path, old_child_dir_mode) + + shutil.rmtree(TESTFN, onexc=self.check_args_to_onexc) + # Test whether onexc has actually been called. + self.assertEqual(self.errorState, 3, + "Expected call to onexc function did not happen.") + + def check_args_to_onexc(self, func, arg, exc): + # test_rmtree_errors deliberately runs rmtree + # on a directory that is chmod 500, which will fail. + # This function is run when shutil.rmtree fails. + # 99.9% of the time it initially fails to remove + # a file in the directory, so the first time through + # func is os.remove. + # However, some Linux machines running ZFS on + # FUSE experienced a failure earlier in the process + # at os.listdir. The first failure may legally + # be either. + if self.errorState < 2: + if func is os.unlink: + self.assertEqual(arg, self.child_file_path) + elif func is os.rmdir: + self.assertEqual(arg, self.child_dir_path) + else: + self.assertIs(func, os.listdir) + self.assertIn(arg, [TESTFN, self.child_dir_path]) + self.assertTrue(isinstance(exc, OSError)) + self.errorState += 1 + else: + self.assertEqual(func, os.rmdir) + self.assertEqual(arg, TESTFN) + self.assertTrue(isinstance(exc, OSError)) + self.errorState = 3 + + @unittest.skipIf(sys.platform[:6] == 'cygwin', + "This test can't be run on Cygwin (issue #1071513).") + @os_helper.skip_if_dac_override + @os_helper.skip_unless_working_chmod + def test_both_onerror_and_onexc(self): + onerror_called = False + onexc_called = False + + def onerror(*args): + nonlocal onerror_called + onerror_called = True + + def onexc(*args): + nonlocal onexc_called + onexc_called = True + + os.mkdir(TESTFN) + self.addCleanup(shutil.rmtree, TESTFN) + + self.child_file_path = os.path.join(TESTFN, 'a') + self.child_dir_path = os.path.join(TESTFN, 'b') + os_helper.create_empty_file(self.child_file_path) + os.mkdir(self.child_dir_path) + old_dir_mode = os.stat(TESTFN).st_mode + old_child_file_mode = os.stat(self.child_file_path).st_mode + old_child_dir_mode = os.stat(self.child_dir_path).st_mode + # Make unwritable. + new_mode = stat.S_IREAD|stat.S_IEXEC + os.chmod(self.child_file_path, new_mode) + os.chmod(self.child_dir_path, new_mode) + os.chmod(TESTFN, new_mode) + + self.addCleanup(os.chmod, TESTFN, old_dir_mode) + self.addCleanup(os.chmod, self.child_file_path, old_child_file_mode) + self.addCleanup(os.chmod, self.child_dir_path, old_child_dir_mode) + + with self.assertWarns(DeprecationWarning): + shutil.rmtree(TESTFN, onerror=onerror, onexc=onexc) + self.assertTrue(onexc_called) + self.assertFalse(onerror_called) + def test_rmtree_does_not_choke_on_failing_lstat(self): try: orig_lstat = os.lstat @@ -1575,28 +1750,65 @@ class TestArchives(BaseTest, unittest.TestCase): finally: archive.close() + def test_make_archive_cwd_default(self): + current_dir = os.getcwd() + def archiver(base_name, base_dir, **kw): + self.assertNotIn('root_dir', kw) + self.assertEqual(base_name, 'basename') + self.assertEqual(os.getcwd(), current_dir) + raise RuntimeError() + + register_archive_format('xxx', archiver, [], 'xxx file') + try: + with no_chdir: + with self.assertRaises(RuntimeError): + make_archive('basename', 'xxx') + self.assertEqual(os.getcwd(), current_dir) + finally: + unregister_archive_format('xxx') + def test_make_archive_cwd(self): current_dir = os.getcwd() root_dir = self.mkdtemp() - def _breaks(*args, **kw): + def archiver(base_name, base_dir, **kw): + self.assertNotIn('root_dir', kw) + self.assertEqual(base_name, os.path.join(current_dir, 'basename')) + self.assertEqual(os.getcwd(), root_dir) raise RuntimeError() dirs = [] def _chdir(path): dirs.append(path) orig_chdir(path) - register_archive_format('xxx', _breaks, [], 'xxx file') + register_archive_format('xxx', archiver, [], 'xxx file') try: with support.swap_attr(os, 'chdir', _chdir) as orig_chdir: - try: - make_archive('xxx', 'xxx', root_dir=root_dir) - except Exception: - pass + with self.assertRaises(RuntimeError): + make_archive('basename', 'xxx', root_dir=root_dir) self.assertEqual(os.getcwd(), current_dir) self.assertEqual(dirs, [root_dir, current_dir]) finally: unregister_archive_format('xxx') + def test_make_archive_cwd_supports_root_dir(self): + current_dir = os.getcwd() + root_dir = self.mkdtemp() + def archiver(base_name, base_dir, **kw): + self.assertEqual(base_name, 'basename') + self.assertEqual(kw['root_dir'], root_dir) + self.assertEqual(os.getcwd(), current_dir) + raise RuntimeError() + archiver.supports_root_dir = True + + register_archive_format('xxx', archiver, [], 'xxx file') + try: + with no_chdir: + with self.assertRaises(RuntimeError): + make_archive('basename', 'xxx', root_dir=root_dir) + self.assertEqual(os.getcwd(), current_dir) + finally: + unregister_archive_format('xxx') + def test_make_tarfile_in_curdir(self): # Issue #21280 root_dir = self.mkdtemp() @@ -1628,14 +1840,59 @@ class TestArchives(BaseTest, unittest.TestCase): formats = [name for name, params in get_archive_formats()] self.assertNotIn('xxx', formats) + def test_make_tarfile_rootdir_nodir(self): + # GH-99203 + self.addCleanup(os_helper.unlink, f'{TESTFN}.tar') + for dry_run in (False, True): + with self.subTest(dry_run=dry_run): + tmp_dir = self.mkdtemp() + nonexisting_file = os.path.join(tmp_dir, 'nonexisting') + with self.assertRaises(FileNotFoundError) as cm: + make_archive(TESTFN, 'tar', nonexisting_file, dry_run=dry_run) + self.assertEqual(cm.exception.errno, errno.ENOENT) + self.assertEqual(cm.exception.filename, nonexisting_file) + self.assertFalse(os.path.exists(f'{TESTFN}.tar')) + + tmp_fd, tmp_file = tempfile.mkstemp(dir=tmp_dir) + os.close(tmp_fd) + with self.assertRaises(NotADirectoryError) as cm: + make_archive(TESTFN, 'tar', tmp_file, dry_run=dry_run) + self.assertEqual(cm.exception.errno, errno.ENOTDIR) + self.assertEqual(cm.exception.filename, tmp_file) + self.assertFalse(os.path.exists(f'{TESTFN}.tar')) + + @support.requires_zlib() + def test_make_zipfile_rootdir_nodir(self): + # GH-99203 + self.addCleanup(os_helper.unlink, f'{TESTFN}.zip') + for dry_run in (False, True): + with self.subTest(dry_run=dry_run): + tmp_dir = self.mkdtemp() + nonexisting_file = os.path.join(tmp_dir, 'nonexisting') + with self.assertRaises(FileNotFoundError) as cm: + make_archive(TESTFN, 'zip', nonexisting_file, dry_run=dry_run) + self.assertEqual(cm.exception.errno, errno.ENOENT) + self.assertEqual(cm.exception.filename, nonexisting_file) + self.assertFalse(os.path.exists(f'{TESTFN}.zip')) + + tmp_fd, tmp_file = tempfile.mkstemp(dir=tmp_dir) + os.close(tmp_fd) + with self.assertRaises(NotADirectoryError) as cm: + make_archive(TESTFN, 'zip', tmp_file, dry_run=dry_run) + self.assertEqual(cm.exception.errno, errno.ENOTDIR) + self.assertEqual(cm.exception.filename, tmp_file) + self.assertFalse(os.path.exists(f'{TESTFN}.zip')) + ### shutil.unpack_archive - def check_unpack_archive(self, format): - self.check_unpack_archive_with_converter(format, lambda path: path) - self.check_unpack_archive_with_converter(format, pathlib.Path) - self.check_unpack_archive_with_converter(format, FakePath) + def check_unpack_archive(self, format, **kwargs): + self.check_unpack_archive_with_converter( + format, lambda path: path, **kwargs) + self.check_unpack_archive_with_converter( + format, pathlib.Path, **kwargs) + self.check_unpack_archive_with_converter(format, FakePath, **kwargs) - def check_unpack_archive_with_converter(self, format, converter): + def check_unpack_archive_with_converter(self, format, converter, **kwargs): root_dir, base_dir = self._create_files() expected = rlistdir(root_dir) expected.remove('outer') @@ -1645,36 +1902,48 @@ class TestArchives(BaseTest, unittest.TestCase): # let's try to unpack it now tmpdir2 = self.mkdtemp() - unpack_archive(converter(filename), converter(tmpdir2)) + unpack_archive(converter(filename), converter(tmpdir2), **kwargs) self.assertEqual(rlistdir(tmpdir2), expected) # and again, this time with the format specified tmpdir3 = self.mkdtemp() - unpack_archive(converter(filename), converter(tmpdir3), format=format) + unpack_archive(converter(filename), converter(tmpdir3), format=format, + **kwargs) self.assertEqual(rlistdir(tmpdir3), expected) - self.assertRaises(shutil.ReadError, unpack_archive, converter(TESTFN)) - self.assertRaises(ValueError, unpack_archive, converter(TESTFN), format='xxx') + with self.assertRaises(shutil.ReadError): + unpack_archive(converter(TESTFN), **kwargs) + with self.assertRaises(ValueError): + unpack_archive(converter(TESTFN), format='xxx', **kwargs) + + def check_unpack_tarball(self, format): + self.check_unpack_archive(format, filter='fully_trusted') + self.check_unpack_archive(format, filter='data') + with warnings_helper.check_warnings( + ('Python 3.14', DeprecationWarning)): + self.check_unpack_archive(format) def test_unpack_archive_tar(self): - self.check_unpack_archive('tar') + self.check_unpack_tarball('tar') @support.requires_zlib() def test_unpack_archive_gztar(self): - self.check_unpack_archive('gztar') + self.check_unpack_tarball('gztar') @support.requires_bz2() def test_unpack_archive_bztar(self): - self.check_unpack_archive('bztar') + self.check_unpack_tarball('bztar') @support.requires_lzma() @unittest.skipIf(AIX and not _maxdataOK(), "AIX MAXDATA must be 0x20000000 or larger") def test_unpack_archive_xztar(self): - self.check_unpack_archive('xztar') + self.check_unpack_tarball('xztar') @support.requires_zlib() def test_unpack_archive_zip(self): self.check_unpack_archive('zip') + with self.assertRaises(TypeError): + self.check_unpack_archive('zip', filter='data') def test_unpack_registry(self): @@ -1823,18 +2092,68 @@ class TestWhich(BaseTest, unittest.TestCase): rv = shutil.which(relpath, path=base_dir) self.assertIsNone(rv) - def test_cwd(self): + @unittest.skipUnless(sys.platform != "win32", + "test is for non win32") + def test_cwd_non_win32(self): # Issue #16957 base_dir = os.path.dirname(self.dir) with os_helper.change_cwd(path=self.dir): rv = shutil.which(self.file, path=base_dir) - if sys.platform == "win32": - # Windows: current directory implicitly on PATH + # non-win32: shouldn't match in the current directory. + self.assertIsNone(rv) + + @unittest.skipUnless(sys.platform == "win32", + "test is for win32") + def test_cwd_win32(self): + base_dir = os.path.dirname(self.dir) + with os_helper.change_cwd(path=self.dir): + with unittest.mock.patch('shutil._win_path_needs_curdir', return_value=True): + rv = shutil.which(self.file, path=base_dir) + # Current directory implicitly on PATH self.assertEqual(rv, os.path.join(self.curdir, self.file)) - else: - # Other platforms: shouldn't match in the current directory. + with unittest.mock.patch('shutil._win_path_needs_curdir', return_value=False): + rv = shutil.which(self.file, path=base_dir) + # Current directory not on PATH self.assertIsNone(rv) + @unittest.skipUnless(sys.platform == "win32", + "test is for win32") + def test_cwd_win32_added_before_all_other_path(self): + base_dir = pathlib.Path(os.fsdecode(self.dir)) + + elsewhere_in_path_dir = base_dir / 'dir1' + elsewhere_in_path_dir.mkdir() + match_elsewhere_in_path = elsewhere_in_path_dir / 'hello.exe' + match_elsewhere_in_path.touch() + + exe_in_cwd = base_dir / 'hello.exe' + exe_in_cwd.touch() + + with os_helper.change_cwd(path=base_dir): + with unittest.mock.patch('shutil._win_path_needs_curdir', return_value=True): + rv = shutil.which('hello.exe', path=elsewhere_in_path_dir) + + self.assertEqual(os.path.abspath(rv), os.path.abspath(exe_in_cwd)) + + @unittest.skipUnless(sys.platform == "win32", + "test is for win32") + def test_pathext_match_before_path_full_match(self): + base_dir = pathlib.Path(os.fsdecode(self.dir)) + dir1 = base_dir / 'dir1' + dir2 = base_dir / 'dir2' + dir1.mkdir() + dir2.mkdir() + + pathext_match = dir1 / 'hello.com.exe' + path_match = dir2 / 'hello.com' + pathext_match.touch() + path_match.touch() + + test_path = os.pathsep.join([str(dir1), str(dir2)]) + assert os.path.basename(shutil.which( + 'hello.com', path=test_path, mode = os.F_OK + )).lower() == 'hello.com.exe' + @os_helper.skip_if_dac_override def test_non_matching_mode(self): # Set the file read-only and ask for writeable files. @@ -1968,6 +2287,32 @@ class TestWhich(BaseTest, unittest.TestCase): rv = shutil.which(program, path=self.temp_dir) self.assertEqual(rv, temp_filexyz.name) + # See GH-75586 + @unittest.skipUnless(sys.platform == "win32", 'test specific to Windows') + def test_pathext_applied_on_files_in_path(self): + with os_helper.EnvironmentVarGuard() as env: + env["PATH"] = self.temp_dir + env["PATHEXT"] = ".test" + + test_path = pathlib.Path(self.temp_dir) / "test_program.test" + test_path.touch(mode=0o755) + + self.assertEqual(shutil.which("test_program"), str(test_path)) + + # See GH-75586 + @unittest.skipUnless(sys.platform == "win32", 'test specific to Windows') + def test_win_path_needs_curdir(self): + with unittest.mock.patch('_winapi.NeedCurrentDirectoryForExePath', return_value=True) as need_curdir_mock: + self.assertTrue(shutil._win_path_needs_curdir('dontcare', os.X_OK)) + need_curdir_mock.assert_called_once_with('dontcare') + need_curdir_mock.reset_mock() + self.assertTrue(shutil._win_path_needs_curdir('dontcare', 0)) + need_curdir_mock.assert_not_called() + + with unittest.mock.patch('_winapi.NeedCurrentDirectoryForExePath', return_value=False) as need_curdir_mock: + self.assertFalse(shutil._win_path_needs_curdir('dontcare', os.X_OK)) + need_curdir_mock.assert_called_once_with('dontcare') + class TestWhichBytes(TestWhich): def setUp(self): @@ -2437,7 +2782,7 @@ class _ZeroCopyFileTest(object): def test_same_file(self): self.addCleanup(self.reset) with self.get_files() as (src, dst): - with self.assertRaises(Exception): + with self.assertRaises((OSError, _GiveupOnFastCopy)): self.zerocopy_fun(src, src) # Make sure src file is not corrupted. self.assertEqual(read_file(TESTFN, binary=True), self.FILEDATA) diff --git a/Lib/test/test_signal.py b/Lib/test/test_signal.py index 6aa529b0..2a1a1ee2 100644 --- a/Lib/test/test_signal.py +++ b/Lib/test/test_signal.py @@ -745,6 +745,7 @@ class SiginterruptTest(unittest.TestCase): interrupted = self.readpipe_interrupted(True) self.assertTrue(interrupted) + @support.requires_resource('walltime') def test_siginterrupt_off(self): # If a signal handler is installed and siginterrupt is called with # a false value for the second argument, when that signal arrives, it @@ -812,15 +813,12 @@ class ItimerTest(unittest.TestCase): signal.signal(signal.SIGVTALRM, self.sig_vtalrm) signal.setitimer(self.itimer, 0.3, 0.2) - start_time = time.monotonic() - while time.monotonic() - start_time < 60.0: + for _ in support.busy_retry(support.LONG_TIMEOUT): # use up some virtual time by doing real work _ = pow(12345, 67890, 10000019) if signal.getitimer(self.itimer) == (0.0, 0.0): - break # sig_vtalrm handler stopped this itimer - else: # Issue 8424 - self.skipTest("timeout: likely cause: machine too slow or load too " - "high") + # sig_vtalrm handler stopped this itimer + break # virtual itimer should be (0.0, 0.0) now self.assertEqual(signal.getitimer(self.itimer), (0.0, 0.0)) @@ -832,15 +830,12 @@ class ItimerTest(unittest.TestCase): signal.signal(signal.SIGPROF, self.sig_prof) signal.setitimer(self.itimer, 0.2, 0.2) - start_time = time.monotonic() - while time.monotonic() - start_time < 60.0: + for _ in support.busy_retry(support.LONG_TIMEOUT): # do some work _ = pow(12345, 67890, 10000019) if signal.getitimer(self.itimer) == (0.0, 0.0): - break # sig_prof handler stopped this itimer - else: # Issue 8424 - self.skipTest("timeout: likely cause: machine too slow or load too " - "high") + # sig_prof handler stopped this itimer + break # profiling itimer should be (0.0, 0.0) now self.assertEqual(signal.getitimer(self.itimer), (0.0, 0.0)) @@ -1307,8 +1302,6 @@ class StressTest(unittest.TestCase): self.setsig(signal.SIGALRM, handler) # for ITIMER_REAL expected_sigs = 0 - deadline = time.monotonic() + support.SHORT_TIMEOUT - while expected_sigs < N: # Hopefully the SIGALRM will be received somewhere during # initial processing of SIGUSR1. @@ -1317,8 +1310,9 @@ class StressTest(unittest.TestCase): expected_sigs += 2 # Wait for handlers to run to avoid signal coalescing - while len(sigs) < expected_sigs and time.monotonic() < deadline: - time.sleep(1e-5) + for _ in support.sleeping_retry(support.SHORT_TIMEOUT): + if len(sigs) >= expected_sigs: + break # All ITIMER_REAL signals should have been delivered to the # Python handler @@ -1413,6 +1407,21 @@ class RaiseSignalTest(unittest.TestCase): signal.raise_signal(signal.SIGINT) self.assertTrue(is_ok) + def test__thread_interrupt_main(self): + # See https://github.com/python/cpython/issues/102397 + code = """if 1: + import _thread + class Foo(): + def __del__(self): + _thread.interrupt_main() + + x = Foo() + """ + + rc, out, err = assert_python_ok('-c', code) + self.assertIn(b'OSError: Signal 2 ignored due to race condition', err) + + class PidfdSignalTest(unittest.TestCase): diff --git a/Lib/test/test_site.py b/Lib/test/test_site.py index b5dc381a..e8ec3b35 100644 --- a/Lib/test/test_site.py +++ b/Lib/test/test_site.py @@ -10,10 +10,9 @@ from test import support from test.support import os_helper from test.support import socket_helper from test.support import captured_stderr -from test.support.os_helper import TESTFN, EnvironmentVarGuard, change_cwd +from test.support.os_helper import TESTFN, EnvironmentVarGuard import ast import builtins -import encodings import glob import io import os @@ -466,10 +465,10 @@ class ImportSideEffectTests(unittest.TestCase): else: self.fail("sitecustomize not imported automatically") - @test.support.requires_resource('network') - @test.support.system_must_validate_cert @unittest.skipUnless(hasattr(urllib.request, "HTTPSHandler"), 'need SSL support to download license') + @test.support.requires_resource('network') + @test.support.system_must_validate_cert def test_license_exists_at_url(self): # This test is a bit fragile since it depends on the format of the # string displayed by license in the absence of a LICENSE file. @@ -577,7 +576,7 @@ class _pthFileTests(unittest.TestCase): _pth_file = os.path.splitext(exe_file)[0] + '._pth' else: _pth_file = os.path.splitext(dll_file)[0] + '._pth' - with open(_pth_file, 'w') as f: + with open(_pth_file, 'w', encoding='utf8') as f: for line in lines: print(line, file=f) return exe_file @@ -614,7 +613,7 @@ class _pthFileTests(unittest.TestCase): os.path.dirname(exe_file), pth_lines) - output = subprocess.check_output([exe_file, '-c', + output = subprocess.check_output([exe_file, '-X', 'utf8', '-c', 'import sys; print("\\n".join(sys.path) if sys.flags.no_site else "")' ], encoding='utf-8', errors='surrogateescape') actual_sys_path = output.rstrip().split('\n') diff --git a/Lib/test/test_slice.py b/Lib/test/test_slice.py index 03fde327..c35a2293 100644 --- a/Lib/test/test_slice.py +++ b/Lib/test/test_slice.py @@ -80,10 +80,16 @@ class SliceTest(unittest.TestCase): self.assertEqual(repr(slice(1, 2, 3)), "slice(1, 2, 3)") def test_hash(self): - # Verify clearing of SF bug #800796 - self.assertRaises(TypeError, hash, slice(5)) + self.assertEqual(hash(slice(5)), slice(5).__hash__()) + self.assertEqual(hash(slice(1, 2)), slice(1, 2).__hash__()) + self.assertEqual(hash(slice(1, 2, 3)), slice(1, 2, 3).__hash__()) + self.assertNotEqual(slice(5), slice(6)) + + with self.assertRaises(TypeError): + hash(slice(1, 2, [])) + with self.assertRaises(TypeError): - slice(5).__hash__() + hash(slice(4, {})) def test_cmp(self): s1 = slice(1, 2, 3) diff --git a/Lib/test/test_smtpd.py b/Lib/test/test_smtpd.py deleted file mode 100644 index 39ff8793..00000000 --- a/Lib/test/test_smtpd.py +++ /dev/null @@ -1,1019 +0,0 @@ -import unittest -import textwrap -from test import support, mock_socket -from test.support import socket_helper -from test.support import warnings_helper -import socket -import io - - -smtpd = warnings_helper.import_deprecated('smtpd') -asyncore = warnings_helper.import_deprecated('asyncore') - -if not socket_helper.has_gethostname: - raise unittest.SkipTest("test requires gethostname()") - - -class DummyServer(smtpd.SMTPServer): - def __init__(self, *args, **kwargs): - smtpd.SMTPServer.__init__(self, *args, **kwargs) - self.messages = [] - if self._decode_data: - self.return_status = 'return status' - else: - self.return_status = b'return status' - - def process_message(self, peer, mailfrom, rcpttos, data, **kw): - self.messages.append((peer, mailfrom, rcpttos, data)) - if data == self.return_status: - return '250 Okish' - if 'mail_options' in kw and 'SMTPUTF8' in kw['mail_options']: - return '250 SMTPUTF8 message okish' - - -class DummyDispatcherBroken(Exception): - pass - - -class BrokenDummyServer(DummyServer): - def listen(self, num): - raise DummyDispatcherBroken() - - -class SMTPDServerTest(unittest.TestCase): - def setUp(self): - smtpd.socket = asyncore.socket = mock_socket - - def test_process_message_unimplemented(self): - server = smtpd.SMTPServer((socket_helper.HOST, 0), ('b', 0), - decode_data=True) - conn, addr = server.accept() - channel = smtpd.SMTPChannel(server, conn, addr, decode_data=True) - - def write_line(line): - channel.socket.queue_recv(line) - channel.handle_read() - - write_line(b'HELO example') - write_line(b'MAIL From:eggs@example') - write_line(b'RCPT To:spam@example') - write_line(b'DATA') - self.assertRaises(NotImplementedError, write_line, b'spam\r\n.\r\n') - - def test_decode_data_and_enable_SMTPUTF8_raises(self): - self.assertRaises( - ValueError, - smtpd.SMTPServer, - (socket_helper.HOST, 0), - ('b', 0), - enable_SMTPUTF8=True, - decode_data=True) - - def tearDown(self): - asyncore.close_all() - asyncore.socket = smtpd.socket = socket - - -class DebuggingServerTest(unittest.TestCase): - - def setUp(self): - smtpd.socket = asyncore.socket = mock_socket - - def send_data(self, channel, data, enable_SMTPUTF8=False): - def write_line(line): - channel.socket.queue_recv(line) - channel.handle_read() - write_line(b'EHLO example') - if enable_SMTPUTF8: - write_line(b'MAIL From:eggs@example BODY=8BITMIME SMTPUTF8') - else: - write_line(b'MAIL From:eggs@example') - write_line(b'RCPT To:spam@example') - write_line(b'DATA') - write_line(data) - write_line(b'.') - - def test_process_message_with_decode_data_true(self): - server = smtpd.DebuggingServer((socket_helper.HOST, 0), ('b', 0), - decode_data=True) - conn, addr = server.accept() - channel = smtpd.SMTPChannel(server, conn, addr, decode_data=True) - with support.captured_stdout() as s: - self.send_data(channel, b'From: test\n\nhello\n') - stdout = s.getvalue() - self.assertEqual(stdout, textwrap.dedent("""\ - ---------- MESSAGE FOLLOWS ---------- - From: test - X-Peer: peer-address - - hello - ------------ END MESSAGE ------------ - """)) - - def test_process_message_with_decode_data_false(self): - server = smtpd.DebuggingServer((socket_helper.HOST, 0), ('b', 0)) - conn, addr = server.accept() - channel = smtpd.SMTPChannel(server, conn, addr) - with support.captured_stdout() as s: - self.send_data(channel, b'From: test\n\nh\xc3\xa9llo\xff\n') - stdout = s.getvalue() - self.assertEqual(stdout, textwrap.dedent("""\ - ---------- MESSAGE FOLLOWS ---------- - b'From: test' - b'X-Peer: peer-address' - b'' - b'h\\xc3\\xa9llo\\xff' - ------------ END MESSAGE ------------ - """)) - - def test_process_message_with_enable_SMTPUTF8_true(self): - server = smtpd.DebuggingServer((socket_helper.HOST, 0), ('b', 0), - enable_SMTPUTF8=True) - conn, addr = server.accept() - channel = smtpd.SMTPChannel(server, conn, addr, enable_SMTPUTF8=True) - with support.captured_stdout() as s: - self.send_data(channel, b'From: test\n\nh\xc3\xa9llo\xff\n') - stdout = s.getvalue() - self.assertEqual(stdout, textwrap.dedent("""\ - ---------- MESSAGE FOLLOWS ---------- - b'From: test' - b'X-Peer: peer-address' - b'' - b'h\\xc3\\xa9llo\\xff' - ------------ END MESSAGE ------------ - """)) - - def test_process_SMTPUTF8_message_with_enable_SMTPUTF8_true(self): - server = smtpd.DebuggingServer((socket_helper.HOST, 0), ('b', 0), - enable_SMTPUTF8=True) - conn, addr = server.accept() - channel = smtpd.SMTPChannel(server, conn, addr, enable_SMTPUTF8=True) - with support.captured_stdout() as s: - self.send_data(channel, b'From: test\n\nh\xc3\xa9llo\xff\n', - enable_SMTPUTF8=True) - stdout = s.getvalue() - self.assertEqual(stdout, textwrap.dedent("""\ - ---------- MESSAGE FOLLOWS ---------- - mail options: ['BODY=8BITMIME', 'SMTPUTF8'] - b'From: test' - b'X-Peer: peer-address' - b'' - b'h\\xc3\\xa9llo\\xff' - ------------ END MESSAGE ------------ - """)) - - def tearDown(self): - asyncore.close_all() - asyncore.socket = smtpd.socket = socket - - -class TestFamilyDetection(unittest.TestCase): - def setUp(self): - smtpd.socket = asyncore.socket = mock_socket - - def tearDown(self): - asyncore.close_all() - asyncore.socket = smtpd.socket = socket - - @unittest.skipUnless(socket_helper.IPV6_ENABLED, "IPv6 not enabled") - def test_socket_uses_IPv6(self): - server = smtpd.SMTPServer((socket_helper.HOSTv6, 0), (socket_helper.HOSTv4, 0)) - self.assertEqual(server.socket.family, socket.AF_INET6) - - def test_socket_uses_IPv4(self): - server = smtpd.SMTPServer((socket_helper.HOSTv4, 0), (socket_helper.HOSTv6, 0)) - self.assertEqual(server.socket.family, socket.AF_INET) - - -class TestRcptOptionParsing(unittest.TestCase): - error_response = (b'555 RCPT TO parameters not recognized or not ' - b'implemented\r\n') - - def setUp(self): - smtpd.socket = asyncore.socket = mock_socket - self.old_debugstream = smtpd.DEBUGSTREAM - self.debug = smtpd.DEBUGSTREAM = io.StringIO() - - def tearDown(self): - asyncore.close_all() - asyncore.socket = smtpd.socket = socket - smtpd.DEBUGSTREAM = self.old_debugstream - - def write_line(self, channel, line): - channel.socket.queue_recv(line) - channel.handle_read() - - def test_params_rejected(self): - server = DummyServer((socket_helper.HOST, 0), ('b', 0)) - conn, addr = server.accept() - channel = smtpd.SMTPChannel(server, conn, addr) - self.write_line(channel, b'EHLO example') - self.write_line(channel, b'MAIL from: <foo@example.com> size=20') - self.write_line(channel, b'RCPT to: <foo@example.com> foo=bar') - self.assertEqual(channel.socket.last, self.error_response) - - def test_nothing_accepted(self): - server = DummyServer((socket_helper.HOST, 0), ('b', 0)) - conn, addr = server.accept() - channel = smtpd.SMTPChannel(server, conn, addr) - self.write_line(channel, b'EHLO example') - self.write_line(channel, b'MAIL from: <foo@example.com> size=20') - self.write_line(channel, b'RCPT to: <foo@example.com>') - self.assertEqual(channel.socket.last, b'250 OK\r\n') - - -class TestMailOptionParsing(unittest.TestCase): - error_response = (b'555 MAIL FROM parameters not recognized or not ' - b'implemented\r\n') - - def setUp(self): - smtpd.socket = asyncore.socket = mock_socket - self.old_debugstream = smtpd.DEBUGSTREAM - self.debug = smtpd.DEBUGSTREAM = io.StringIO() - - def tearDown(self): - asyncore.close_all() - asyncore.socket = smtpd.socket = socket - smtpd.DEBUGSTREAM = self.old_debugstream - - def write_line(self, channel, line): - channel.socket.queue_recv(line) - channel.handle_read() - - def test_with_decode_data_true(self): - server = DummyServer((socket_helper.HOST, 0), ('b', 0), decode_data=True) - conn, addr = server.accept() - channel = smtpd.SMTPChannel(server, conn, addr, decode_data=True) - self.write_line(channel, b'EHLO example') - for line in [ - b'MAIL from: <foo@example.com> size=20 SMTPUTF8', - b'MAIL from: <foo@example.com> size=20 SMTPUTF8 BODY=8BITMIME', - b'MAIL from: <foo@example.com> size=20 BODY=UNKNOWN', - b'MAIL from: <foo@example.com> size=20 body=8bitmime', - ]: - self.write_line(channel, line) - self.assertEqual(channel.socket.last, self.error_response) - self.write_line(channel, b'MAIL from: <foo@example.com> size=20') - self.assertEqual(channel.socket.last, b'250 OK\r\n') - - def test_with_decode_data_false(self): - server = DummyServer((socket_helper.HOST, 0), ('b', 0)) - conn, addr = server.accept() - channel = smtpd.SMTPChannel(server, conn, addr) - self.write_line(channel, b'EHLO example') - for line in [ - b'MAIL from: <foo@example.com> size=20 SMTPUTF8', - b'MAIL from: <foo@example.com> size=20 SMTPUTF8 BODY=8BITMIME', - ]: - self.write_line(channel, line) - self.assertEqual(channel.socket.last, self.error_response) - self.write_line( - channel, - b'MAIL from: <foo@example.com> size=20 SMTPUTF8 BODY=UNKNOWN') - self.assertEqual( - channel.socket.last, - b'501 Error: BODY can only be one of 7BIT, 8BITMIME\r\n') - self.write_line( - channel, b'MAIL from: <foo@example.com> size=20 body=8bitmime') - self.assertEqual(channel.socket.last, b'250 OK\r\n') - - def test_with_enable_smtputf8_true(self): - server = DummyServer((socket_helper.HOST, 0), ('b', 0), enable_SMTPUTF8=True) - conn, addr = server.accept() - channel = smtpd.SMTPChannel(server, conn, addr, enable_SMTPUTF8=True) - self.write_line(channel, b'EHLO example') - self.write_line( - channel, - b'MAIL from: <foo@example.com> size=20 body=8bitmime smtputf8') - self.assertEqual(channel.socket.last, b'250 OK\r\n') - - -class SMTPDChannelTest(unittest.TestCase): - def setUp(self): - smtpd.socket = asyncore.socket = mock_socket - self.old_debugstream = smtpd.DEBUGSTREAM - self.debug = smtpd.DEBUGSTREAM = io.StringIO() - self.server = DummyServer((socket_helper.HOST, 0), ('b', 0), - decode_data=True) - conn, addr = self.server.accept() - self.channel = smtpd.SMTPChannel(self.server, conn, addr, - decode_data=True) - - def tearDown(self): - asyncore.close_all() - asyncore.socket = smtpd.socket = socket - smtpd.DEBUGSTREAM = self.old_debugstream - - def write_line(self, line): - self.channel.socket.queue_recv(line) - self.channel.handle_read() - - def test_broken_connect(self): - self.assertRaises( - DummyDispatcherBroken, BrokenDummyServer, - (socket_helper.HOST, 0), ('b', 0), decode_data=True) - - def test_decode_data_and_enable_SMTPUTF8_raises(self): - self.assertRaises( - ValueError, smtpd.SMTPChannel, - self.server, self.channel.conn, self.channel.addr, - enable_SMTPUTF8=True, decode_data=True) - - def test_server_accept(self): - self.server.handle_accept() - - def test_missing_data(self): - self.write_line(b'') - self.assertEqual(self.channel.socket.last, - b'500 Error: bad syntax\r\n') - - def test_EHLO(self): - self.write_line(b'EHLO example') - self.assertEqual(self.channel.socket.last, b'250 HELP\r\n') - - def test_EHLO_bad_syntax(self): - self.write_line(b'EHLO') - self.assertEqual(self.channel.socket.last, - b'501 Syntax: EHLO hostname\r\n') - - def test_EHLO_duplicate(self): - self.write_line(b'EHLO example') - self.write_line(b'EHLO example') - self.assertEqual(self.channel.socket.last, - b'503 Duplicate HELO/EHLO\r\n') - - def test_EHLO_HELO_duplicate(self): - self.write_line(b'EHLO example') - self.write_line(b'HELO example') - self.assertEqual(self.channel.socket.last, - b'503 Duplicate HELO/EHLO\r\n') - - def test_HELO(self): - name = smtpd.socket.getfqdn() - self.write_line(b'HELO example') - self.assertEqual(self.channel.socket.last, - '250 {}\r\n'.format(name).encode('ascii')) - - def test_HELO_EHLO_duplicate(self): - self.write_line(b'HELO example') - self.write_line(b'EHLO example') - self.assertEqual(self.channel.socket.last, - b'503 Duplicate HELO/EHLO\r\n') - - def test_HELP(self): - self.write_line(b'HELP') - self.assertEqual(self.channel.socket.last, - b'250 Supported commands: EHLO HELO MAIL RCPT ' + \ - b'DATA RSET NOOP QUIT VRFY\r\n') - - def test_HELP_command(self): - self.write_line(b'HELP MAIL') - self.assertEqual(self.channel.socket.last, - b'250 Syntax: MAIL FROM: <address>\r\n') - - def test_HELP_command_unknown(self): - self.write_line(b'HELP SPAM') - self.assertEqual(self.channel.socket.last, - b'501 Supported commands: EHLO HELO MAIL RCPT ' + \ - b'DATA RSET NOOP QUIT VRFY\r\n') - - def test_HELO_bad_syntax(self): - self.write_line(b'HELO') - self.assertEqual(self.channel.socket.last, - b'501 Syntax: HELO hostname\r\n') - - def test_HELO_duplicate(self): - self.write_line(b'HELO example') - self.write_line(b'HELO example') - self.assertEqual(self.channel.socket.last, - b'503 Duplicate HELO/EHLO\r\n') - - def test_HELO_parameter_rejected_when_extensions_not_enabled(self): - self.extended_smtp = False - self.write_line(b'HELO example') - self.write_line(b'MAIL from:<foo@example.com> SIZE=1234') - self.assertEqual(self.channel.socket.last, - b'501 Syntax: MAIL FROM: <address>\r\n') - - def test_MAIL_allows_space_after_colon(self): - self.write_line(b'HELO example') - self.write_line(b'MAIL from: <foo@example.com>') - self.assertEqual(self.channel.socket.last, - b'250 OK\r\n') - - def test_extended_MAIL_allows_space_after_colon(self): - self.write_line(b'EHLO example') - self.write_line(b'MAIL from: <foo@example.com> size=20') - self.assertEqual(self.channel.socket.last, - b'250 OK\r\n') - - def test_NOOP(self): - self.write_line(b'NOOP') - self.assertEqual(self.channel.socket.last, b'250 OK\r\n') - - def test_HELO_NOOP(self): - self.write_line(b'HELO example') - self.write_line(b'NOOP') - self.assertEqual(self.channel.socket.last, b'250 OK\r\n') - - def test_NOOP_bad_syntax(self): - self.write_line(b'NOOP hi') - self.assertEqual(self.channel.socket.last, - b'501 Syntax: NOOP\r\n') - - def test_QUIT(self): - self.write_line(b'QUIT') - self.assertEqual(self.channel.socket.last, b'221 Bye\r\n') - - def test_HELO_QUIT(self): - self.write_line(b'HELO example') - self.write_line(b'QUIT') - self.assertEqual(self.channel.socket.last, b'221 Bye\r\n') - - def test_QUIT_arg_ignored(self): - self.write_line(b'QUIT bye bye') - self.assertEqual(self.channel.socket.last, b'221 Bye\r\n') - - def test_bad_state(self): - self.channel.smtp_state = 'BAD STATE' - self.write_line(b'HELO example') - self.assertEqual(self.channel.socket.last, - b'451 Internal confusion\r\n') - - def test_command_too_long(self): - self.write_line(b'HELO example') - self.write_line(b'MAIL from: ' + - b'a' * self.channel.command_size_limit + - b'@example') - self.assertEqual(self.channel.socket.last, - b'500 Error: line too long\r\n') - - def test_MAIL_command_limit_extended_with_SIZE(self): - self.write_line(b'EHLO example') - fill_len = self.channel.command_size_limit - len('MAIL from:<@example>') - self.write_line(b'MAIL from:<' + - b'a' * fill_len + - b'@example> SIZE=1234') - self.assertEqual(self.channel.socket.last, b'250 OK\r\n') - - self.write_line(b'MAIL from:<' + - b'a' * (fill_len + 26) + - b'@example> SIZE=1234') - self.assertEqual(self.channel.socket.last, - b'500 Error: line too long\r\n') - - def test_MAIL_command_rejects_SMTPUTF8_by_default(self): - self.write_line(b'EHLO example') - self.write_line( - b'MAIL from: <naive@example.com> BODY=8BITMIME SMTPUTF8') - self.assertEqual(self.channel.socket.last[0:1], b'5') - - def test_data_longer_than_default_data_size_limit(self): - # Hack the default so we don't have to generate so much data. - self.channel.data_size_limit = 1048 - self.write_line(b'HELO example') - self.write_line(b'MAIL From:eggs@example') - self.write_line(b'RCPT To:spam@example') - self.write_line(b'DATA') - self.write_line(b'A' * self.channel.data_size_limit + - b'A\r\n.') - self.assertEqual(self.channel.socket.last, - b'552 Error: Too much mail data\r\n') - - def test_MAIL_size_parameter(self): - self.write_line(b'EHLO example') - self.write_line(b'MAIL FROM:<eggs@example> SIZE=512') - self.assertEqual(self.channel.socket.last, - b'250 OK\r\n') - - def test_MAIL_invalid_size_parameter(self): - self.write_line(b'EHLO example') - self.write_line(b'MAIL FROM:<eggs@example> SIZE=invalid') - self.assertEqual(self.channel.socket.last, - b'501 Syntax: MAIL FROM: <address> [SP <mail-parameters>]\r\n') - - def test_MAIL_RCPT_unknown_parameters(self): - self.write_line(b'EHLO example') - self.write_line(b'MAIL FROM:<eggs@example> ham=green') - self.assertEqual(self.channel.socket.last, - b'555 MAIL FROM parameters not recognized or not implemented\r\n') - - self.write_line(b'MAIL FROM:<eggs@example>') - self.write_line(b'RCPT TO:<eggs@example> ham=green') - self.assertEqual(self.channel.socket.last, - b'555 RCPT TO parameters not recognized or not implemented\r\n') - - def test_MAIL_size_parameter_larger_than_default_data_size_limit(self): - self.channel.data_size_limit = 1048 - self.write_line(b'EHLO example') - self.write_line(b'MAIL FROM:<eggs@example> SIZE=2096') - self.assertEqual(self.channel.socket.last, - b'552 Error: message size exceeds fixed maximum message size\r\n') - - def test_need_MAIL(self): - self.write_line(b'HELO example') - self.write_line(b'RCPT to:spam@example') - self.assertEqual(self.channel.socket.last, - b'503 Error: need MAIL command\r\n') - - def test_MAIL_syntax_HELO(self): - self.write_line(b'HELO example') - self.write_line(b'MAIL from eggs@example') - self.assertEqual(self.channel.socket.last, - b'501 Syntax: MAIL FROM: <address>\r\n') - - def test_MAIL_syntax_EHLO(self): - self.write_line(b'EHLO example') - self.write_line(b'MAIL from eggs@example') - self.assertEqual(self.channel.socket.last, - b'501 Syntax: MAIL FROM: <address> [SP <mail-parameters>]\r\n') - - def test_MAIL_missing_address(self): - self.write_line(b'HELO example') - self.write_line(b'MAIL from:') - self.assertEqual(self.channel.socket.last, - b'501 Syntax: MAIL FROM: <address>\r\n') - - def test_MAIL_chevrons(self): - self.write_line(b'HELO example') - self.write_line(b'MAIL from:<eggs@example>') - self.assertEqual(self.channel.socket.last, b'250 OK\r\n') - - def test_MAIL_empty_chevrons(self): - self.write_line(b'EHLO example') - self.write_line(b'MAIL from:<>') - self.assertEqual(self.channel.socket.last, b'250 OK\r\n') - - def test_MAIL_quoted_localpart(self): - self.write_line(b'EHLO example') - self.write_line(b'MAIL from: <"Fred Blogs"@example.com>') - self.assertEqual(self.channel.socket.last, b'250 OK\r\n') - self.assertEqual(self.channel.mailfrom, '"Fred Blogs"@example.com') - - def test_MAIL_quoted_localpart_no_angles(self): - self.write_line(b'EHLO example') - self.write_line(b'MAIL from: "Fred Blogs"@example.com') - self.assertEqual(self.channel.socket.last, b'250 OK\r\n') - self.assertEqual(self.channel.mailfrom, '"Fred Blogs"@example.com') - - def test_MAIL_quoted_localpart_with_size(self): - self.write_line(b'EHLO example') - self.write_line(b'MAIL from: <"Fred Blogs"@example.com> SIZE=1000') - self.assertEqual(self.channel.socket.last, b'250 OK\r\n') - self.assertEqual(self.channel.mailfrom, '"Fred Blogs"@example.com') - - def test_MAIL_quoted_localpart_with_size_no_angles(self): - self.write_line(b'EHLO example') - self.write_line(b'MAIL from: "Fred Blogs"@example.com SIZE=1000') - self.assertEqual(self.channel.socket.last, b'250 OK\r\n') - self.assertEqual(self.channel.mailfrom, '"Fred Blogs"@example.com') - - def test_nested_MAIL(self): - self.write_line(b'HELO example') - self.write_line(b'MAIL from:eggs@example') - self.write_line(b'MAIL from:spam@example') - self.assertEqual(self.channel.socket.last, - b'503 Error: nested MAIL command\r\n') - - def test_VRFY(self): - self.write_line(b'VRFY eggs@example') - self.assertEqual(self.channel.socket.last, - b'252 Cannot VRFY user, but will accept message and attempt ' + \ - b'delivery\r\n') - - def test_VRFY_syntax(self): - self.write_line(b'VRFY') - self.assertEqual(self.channel.socket.last, - b'501 Syntax: VRFY <address>\r\n') - - def test_EXPN_not_implemented(self): - self.write_line(b'EXPN') - self.assertEqual(self.channel.socket.last, - b'502 EXPN not implemented\r\n') - - def test_no_HELO_MAIL(self): - self.write_line(b'MAIL from:<foo@example.com>') - self.assertEqual(self.channel.socket.last, - b'503 Error: send HELO first\r\n') - - def test_need_RCPT(self): - self.write_line(b'HELO example') - self.write_line(b'MAIL From:eggs@example') - self.write_line(b'DATA') - self.assertEqual(self.channel.socket.last, - b'503 Error: need RCPT command\r\n') - - def test_RCPT_syntax_HELO(self): - self.write_line(b'HELO example') - self.write_line(b'MAIL From: eggs@example') - self.write_line(b'RCPT to eggs@example') - self.assertEqual(self.channel.socket.last, - b'501 Syntax: RCPT TO: <address>\r\n') - - def test_RCPT_syntax_EHLO(self): - self.write_line(b'EHLO example') - self.write_line(b'MAIL From: eggs@example') - self.write_line(b'RCPT to eggs@example') - self.assertEqual(self.channel.socket.last, - b'501 Syntax: RCPT TO: <address> [SP <mail-parameters>]\r\n') - - def test_RCPT_lowercase_to_OK(self): - self.write_line(b'HELO example') - self.write_line(b'MAIL From: eggs@example') - self.write_line(b'RCPT to: <eggs@example>') - self.assertEqual(self.channel.socket.last, b'250 OK\r\n') - - def test_no_HELO_RCPT(self): - self.write_line(b'RCPT to eggs@example') - self.assertEqual(self.channel.socket.last, - b'503 Error: send HELO first\r\n') - - def test_data_dialog(self): - self.write_line(b'HELO example') - self.write_line(b'MAIL From:eggs@example') - self.assertEqual(self.channel.socket.last, b'250 OK\r\n') - self.write_line(b'RCPT To:spam@example') - self.assertEqual(self.channel.socket.last, b'250 OK\r\n') - - self.write_line(b'DATA') - self.assertEqual(self.channel.socket.last, - b'354 End data with <CR><LF>.<CR><LF>\r\n') - self.write_line(b'data\r\nmore\r\n.') - self.assertEqual(self.channel.socket.last, b'250 OK\r\n') - self.assertEqual(self.server.messages, - [(('peer-address', 'peer-port'), - 'eggs@example', - ['spam@example'], - 'data\nmore')]) - - def test_DATA_syntax(self): - self.write_line(b'HELO example') - self.write_line(b'MAIL From:eggs@example') - self.write_line(b'RCPT To:spam@example') - self.write_line(b'DATA spam') - self.assertEqual(self.channel.socket.last, b'501 Syntax: DATA\r\n') - - def test_no_HELO_DATA(self): - self.write_line(b'DATA spam') - self.assertEqual(self.channel.socket.last, - b'503 Error: send HELO first\r\n') - - def test_data_transparency_section_4_5_2(self): - self.write_line(b'HELO example') - self.write_line(b'MAIL From:eggs@example') - self.write_line(b'RCPT To:spam@example') - self.write_line(b'DATA') - self.write_line(b'..\r\n.\r\n') - self.assertEqual(self.channel.received_data, '.') - - def test_multiple_RCPT(self): - self.write_line(b'HELO example') - self.write_line(b'MAIL From:eggs@example') - self.write_line(b'RCPT To:spam@example') - self.write_line(b'RCPT To:ham@example') - self.write_line(b'DATA') - self.write_line(b'data\r\n.') - self.assertEqual(self.server.messages, - [(('peer-address', 'peer-port'), - 'eggs@example', - ['spam@example','ham@example'], - 'data')]) - - def test_manual_status(self): - # checks that the Channel is able to return a custom status message - self.write_line(b'HELO example') - self.write_line(b'MAIL From:eggs@example') - self.write_line(b'RCPT To:spam@example') - self.write_line(b'DATA') - self.write_line(b'return status\r\n.') - self.assertEqual(self.channel.socket.last, b'250 Okish\r\n') - - def test_RSET(self): - self.write_line(b'HELO example') - self.write_line(b'MAIL From:eggs@example') - self.write_line(b'RCPT To:spam@example') - self.write_line(b'RSET') - self.assertEqual(self.channel.socket.last, b'250 OK\r\n') - self.write_line(b'MAIL From:foo@example') - self.write_line(b'RCPT To:eggs@example') - self.write_line(b'DATA') - self.write_line(b'data\r\n.') - self.assertEqual(self.server.messages, - [(('peer-address', 'peer-port'), - 'foo@example', - ['eggs@example'], - 'data')]) - - def test_HELO_RSET(self): - self.write_line(b'HELO example') - self.write_line(b'RSET') - self.assertEqual(self.channel.socket.last, b'250 OK\r\n') - - def test_RSET_syntax(self): - self.write_line(b'RSET hi') - self.assertEqual(self.channel.socket.last, b'501 Syntax: RSET\r\n') - - def test_unknown_command(self): - self.write_line(b'UNKNOWN_CMD') - self.assertEqual(self.channel.socket.last, - b'500 Error: command "UNKNOWN_CMD" not ' + \ - b'recognized\r\n') - - def test_attribute_deprecations(self): - with warnings_helper.check_warnings(('', DeprecationWarning)): - spam = self.channel._SMTPChannel__server - with warnings_helper.check_warnings(('', DeprecationWarning)): - self.channel._SMTPChannel__server = 'spam' - with warnings_helper.check_warnings(('', DeprecationWarning)): - spam = self.channel._SMTPChannel__line - with warnings_helper.check_warnings(('', DeprecationWarning)): - self.channel._SMTPChannel__line = 'spam' - with warnings_helper.check_warnings(('', DeprecationWarning)): - spam = self.channel._SMTPChannel__state - with warnings_helper.check_warnings(('', DeprecationWarning)): - self.channel._SMTPChannel__state = 'spam' - with warnings_helper.check_warnings(('', DeprecationWarning)): - spam = self.channel._SMTPChannel__greeting - with warnings_helper.check_warnings(('', DeprecationWarning)): - self.channel._SMTPChannel__greeting = 'spam' - with warnings_helper.check_warnings(('', DeprecationWarning)): - spam = self.channel._SMTPChannel__mailfrom - with warnings_helper.check_warnings(('', DeprecationWarning)): - self.channel._SMTPChannel__mailfrom = 'spam' - with warnings_helper.check_warnings(('', DeprecationWarning)): - spam = self.channel._SMTPChannel__rcpttos - with warnings_helper.check_warnings(('', DeprecationWarning)): - self.channel._SMTPChannel__rcpttos = 'spam' - with warnings_helper.check_warnings(('', DeprecationWarning)): - spam = self.channel._SMTPChannel__data - with warnings_helper.check_warnings(('', DeprecationWarning)): - self.channel._SMTPChannel__data = 'spam' - with warnings_helper.check_warnings(('', DeprecationWarning)): - spam = self.channel._SMTPChannel__fqdn - with warnings_helper.check_warnings(('', DeprecationWarning)): - self.channel._SMTPChannel__fqdn = 'spam' - with warnings_helper.check_warnings(('', DeprecationWarning)): - spam = self.channel._SMTPChannel__peer - with warnings_helper.check_warnings(('', DeprecationWarning)): - self.channel._SMTPChannel__peer = 'spam' - with warnings_helper.check_warnings(('', DeprecationWarning)): - spam = self.channel._SMTPChannel__conn - with warnings_helper.check_warnings(('', DeprecationWarning)): - self.channel._SMTPChannel__conn = 'spam' - with warnings_helper.check_warnings(('', DeprecationWarning)): - spam = self.channel._SMTPChannel__addr - with warnings_helper.check_warnings(('', DeprecationWarning)): - self.channel._SMTPChannel__addr = 'spam' - -@unittest.skipUnless(socket_helper.IPV6_ENABLED, "IPv6 not enabled") -class SMTPDChannelIPv6Test(SMTPDChannelTest): - def setUp(self): - smtpd.socket = asyncore.socket = mock_socket - self.old_debugstream = smtpd.DEBUGSTREAM - self.debug = smtpd.DEBUGSTREAM = io.StringIO() - self.server = DummyServer((socket_helper.HOSTv6, 0), ('b', 0), - decode_data=True) - conn, addr = self.server.accept() - self.channel = smtpd.SMTPChannel(self.server, conn, addr, - decode_data=True) - -class SMTPDChannelWithDataSizeLimitTest(unittest.TestCase): - - def setUp(self): - smtpd.socket = asyncore.socket = mock_socket - self.old_debugstream = smtpd.DEBUGSTREAM - self.debug = smtpd.DEBUGSTREAM = io.StringIO() - self.server = DummyServer((socket_helper.HOST, 0), ('b', 0), - decode_data=True) - conn, addr = self.server.accept() - # Set DATA size limit to 32 bytes for easy testing - self.channel = smtpd.SMTPChannel(self.server, conn, addr, 32, - decode_data=True) - - def tearDown(self): - asyncore.close_all() - asyncore.socket = smtpd.socket = socket - smtpd.DEBUGSTREAM = self.old_debugstream - - def write_line(self, line): - self.channel.socket.queue_recv(line) - self.channel.handle_read() - - def test_data_limit_dialog(self): - self.write_line(b'HELO example') - self.write_line(b'MAIL From:eggs@example') - self.assertEqual(self.channel.socket.last, b'250 OK\r\n') - self.write_line(b'RCPT To:spam@example') - self.assertEqual(self.channel.socket.last, b'250 OK\r\n') - - self.write_line(b'DATA') - self.assertEqual(self.channel.socket.last, - b'354 End data with <CR><LF>.<CR><LF>\r\n') - self.write_line(b'data\r\nmore\r\n.') - self.assertEqual(self.channel.socket.last, b'250 OK\r\n') - self.assertEqual(self.server.messages, - [(('peer-address', 'peer-port'), - 'eggs@example', - ['spam@example'], - 'data\nmore')]) - - def test_data_limit_dialog_too_much_data(self): - self.write_line(b'HELO example') - self.write_line(b'MAIL From:eggs@example') - self.assertEqual(self.channel.socket.last, b'250 OK\r\n') - self.write_line(b'RCPT To:spam@example') - self.assertEqual(self.channel.socket.last, b'250 OK\r\n') - - self.write_line(b'DATA') - self.assertEqual(self.channel.socket.last, - b'354 End data with <CR><LF>.<CR><LF>\r\n') - self.write_line(b'This message is longer than 32 bytes\r\n.') - self.assertEqual(self.channel.socket.last, - b'552 Error: Too much mail data\r\n') - - -class SMTPDChannelWithDecodeDataFalse(unittest.TestCase): - - def setUp(self): - smtpd.socket = asyncore.socket = mock_socket - self.old_debugstream = smtpd.DEBUGSTREAM - self.debug = smtpd.DEBUGSTREAM = io.StringIO() - self.server = DummyServer((socket_helper.HOST, 0), ('b', 0)) - conn, addr = self.server.accept() - self.channel = smtpd.SMTPChannel(self.server, conn, addr) - - def tearDown(self): - asyncore.close_all() - asyncore.socket = smtpd.socket = socket - smtpd.DEBUGSTREAM = self.old_debugstream - - def write_line(self, line): - self.channel.socket.queue_recv(line) - self.channel.handle_read() - - def test_ascii_data(self): - self.write_line(b'HELO example') - self.write_line(b'MAIL From:eggs@example') - self.write_line(b'RCPT To:spam@example') - self.write_line(b'DATA') - self.write_line(b'plain ascii text') - self.write_line(b'.') - self.assertEqual(self.channel.received_data, b'plain ascii text') - - def test_utf8_data(self): - self.write_line(b'HELO example') - self.write_line(b'MAIL From:eggs@example') - self.write_line(b'RCPT To:spam@example') - self.write_line(b'DATA') - self.write_line(b'utf8 enriched text: \xc5\xbc\xc5\xba\xc4\x87') - self.write_line(b'and some plain ascii') - self.write_line(b'.') - self.assertEqual( - self.channel.received_data, - b'utf8 enriched text: \xc5\xbc\xc5\xba\xc4\x87\n' - b'and some plain ascii') - - -class SMTPDChannelWithDecodeDataTrue(unittest.TestCase): - - def setUp(self): - smtpd.socket = asyncore.socket = mock_socket - self.old_debugstream = smtpd.DEBUGSTREAM - self.debug = smtpd.DEBUGSTREAM = io.StringIO() - self.server = DummyServer((socket_helper.HOST, 0), ('b', 0), - decode_data=True) - conn, addr = self.server.accept() - # Set decode_data to True - self.channel = smtpd.SMTPChannel(self.server, conn, addr, - decode_data=True) - - def tearDown(self): - asyncore.close_all() - asyncore.socket = smtpd.socket = socket - smtpd.DEBUGSTREAM = self.old_debugstream - - def write_line(self, line): - self.channel.socket.queue_recv(line) - self.channel.handle_read() - - def test_ascii_data(self): - self.write_line(b'HELO example') - self.write_line(b'MAIL From:eggs@example') - self.write_line(b'RCPT To:spam@example') - self.write_line(b'DATA') - self.write_line(b'plain ascii text') - self.write_line(b'.') - self.assertEqual(self.channel.received_data, 'plain ascii text') - - def test_utf8_data(self): - self.write_line(b'HELO example') - self.write_line(b'MAIL From:eggs@example') - self.write_line(b'RCPT To:spam@example') - self.write_line(b'DATA') - self.write_line(b'utf8 enriched text: \xc5\xbc\xc5\xba\xc4\x87') - self.write_line(b'and some plain ascii') - self.write_line(b'.') - self.assertEqual( - self.channel.received_data, - 'utf8 enriched text: żźć\nand some plain ascii') - - -class SMTPDChannelTestWithEnableSMTPUTF8True(unittest.TestCase): - def setUp(self): - smtpd.socket = asyncore.socket = mock_socket - self.old_debugstream = smtpd.DEBUGSTREAM - self.debug = smtpd.DEBUGSTREAM = io.StringIO() - self.server = DummyServer((socket_helper.HOST, 0), ('b', 0), - enable_SMTPUTF8=True) - conn, addr = self.server.accept() - self.channel = smtpd.SMTPChannel(self.server, conn, addr, - enable_SMTPUTF8=True) - - def tearDown(self): - asyncore.close_all() - asyncore.socket = smtpd.socket = socket - smtpd.DEBUGSTREAM = self.old_debugstream - - def write_line(self, line): - self.channel.socket.queue_recv(line) - self.channel.handle_read() - - def test_MAIL_command_accepts_SMTPUTF8_when_announced(self): - self.write_line(b'EHLO example') - self.write_line( - 'MAIL from: <naïve@example.com> BODY=8BITMIME SMTPUTF8'.encode( - 'utf-8') - ) - self.assertEqual(self.channel.socket.last, b'250 OK\r\n') - - def test_process_smtputf8_message(self): - self.write_line(b'EHLO example') - for mail_parameters in [b'', b'BODY=8BITMIME SMTPUTF8']: - self.write_line(b'MAIL from: <a@example> ' + mail_parameters) - self.assertEqual(self.channel.socket.last[0:3], b'250') - self.write_line(b'rcpt to:<b@example.com>') - self.assertEqual(self.channel.socket.last[0:3], b'250') - self.write_line(b'data') - self.assertEqual(self.channel.socket.last[0:3], b'354') - self.write_line(b'c\r\n.') - if mail_parameters == b'': - self.assertEqual(self.channel.socket.last, b'250 OK\r\n') - else: - self.assertEqual(self.channel.socket.last, - b'250 SMTPUTF8 message okish\r\n') - - def test_utf8_data(self): - self.write_line(b'EHLO example') - self.write_line( - 'MAIL From: naïve@examplé BODY=8BITMIME SMTPUTF8'.encode('utf-8')) - self.assertEqual(self.channel.socket.last[0:3], b'250') - self.write_line('RCPT To:späm@examplé'.encode('utf-8')) - self.assertEqual(self.channel.socket.last[0:3], b'250') - self.write_line(b'DATA') - self.assertEqual(self.channel.socket.last[0:3], b'354') - self.write_line(b'utf8 enriched text: \xc5\xbc\xc5\xba\xc4\x87') - self.write_line(b'.') - self.assertEqual( - self.channel.received_data, - b'utf8 enriched text: \xc5\xbc\xc5\xba\xc4\x87') - - def test_MAIL_command_limit_extended_with_SIZE_and_SMTPUTF8(self): - self.write_line(b'ehlo example') - fill_len = (512 + 26 + 10) - len('mail from:<@example>') - self.write_line(b'MAIL from:<' + - b'a' * (fill_len + 1) + - b'@example>') - self.assertEqual(self.channel.socket.last, - b'500 Error: line too long\r\n') - self.write_line(b'MAIL from:<' + - b'a' * fill_len + - b'@example>') - self.assertEqual(self.channel.socket.last, b'250 OK\r\n') - - def test_multiple_emails_with_extended_command_length(self): - self.write_line(b'ehlo example') - fill_len = (512 + 26 + 10) - len('mail from:<@example>') - for char in [b'a', b'b', b'c']: - self.write_line(b'MAIL from:<' + char * fill_len + b'a@example>') - self.assertEqual(self.channel.socket.last[0:3], b'500') - self.write_line(b'MAIL from:<' + char * fill_len + b'@example>') - self.assertEqual(self.channel.socket.last[0:3], b'250') - self.write_line(b'rcpt to:<hans@example.com>') - self.assertEqual(self.channel.socket.last[0:3], b'250') - self.write_line(b'data') - self.assertEqual(self.channel.socket.last[0:3], b'354') - self.write_line(b'test\r\n.') - self.assertEqual(self.channel.socket.last[0:3], b'250') - - -class MiscTestCase(unittest.TestCase): - def test__all__(self): - not_exported = { - "program", "Devnull", "DEBUGSTREAM", "NEWLINE", "COMMASPACE", - "DATA_SIZE_DEFAULT", "usage", "Options", "parseargs", - } - support.check__all__(self, smtpd, not_exported=not_exported) - - -if __name__ == "__main__": - unittest.main() diff --git a/Lib/test/test_smtplib.py b/Lib/test/test_smtplib.py index a4074c02..b6d5b8c3 100644 --- a/Lib/test/test_smtplib.py +++ b/Lib/test/test_smtplib.py @@ -21,12 +21,10 @@ from test import support, mock_socket from test.support import hashlib_helper from test.support import socket_helper from test.support import threading_helper -from test.support import warnings_helper +from test.support import asyncore from unittest.mock import Mock - -asyncore = warnings_helper.import_deprecated('asyncore') -smtpd = warnings_helper.import_deprecated('smtpd') +from . import smtpd support.requires_working_socket(module=True) diff --git a/Lib/test/test_smtpnet.py b/Lib/test/test_smtpnet.py index 72f51cd8..2e0dc1aa 100644 --- a/Lib/test/test_smtpnet.py +++ b/Lib/test/test_smtpnet.py @@ -61,6 +61,7 @@ class SmtpSSLTest(unittest.TestCase): server.ehlo() server.quit() + @support.requires_resource('walltime') def test_connect_using_sslcontext(self): context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) context.check_hostname = False diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index 13cb2a79..99c4c5cb 100644 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -4,30 +4,31 @@ from test.support import os_helper from test.support import socket_helper from test.support import threading_helper +import _thread as thread +import array +import contextlib import errno +import gc import io import itertools -import socket -import select -import tempfile -import time -import traceback -import queue -import sys -import os -import platform -import array -import contextlib -from weakref import proxy -import signal import math +import os import pickle -import struct +import platform +import queue import random -import shutil +import re +import select +import signal +import socket import string -import _thread as thread +import struct +import sys +import tempfile import threading +import time +import traceback +from weakref import proxy try: import multiprocessing except ImportError: @@ -143,6 +144,17 @@ def _have_socket_bluetooth(): return True +def _have_socket_hyperv(): + """Check whether AF_HYPERV sockets are supported on this host.""" + try: + s = socket.socket(socket.AF_HYPERV, socket.SOCK_STREAM, socket.HV_PROTOCOL_RAW) + except (AttributeError, OSError): + return False + else: + s.close() + return True + + @contextlib.contextmanager def socket_setdefaulttimeout(timeout): old_timeout = socket.getdefaulttimeout() @@ -171,6 +183,8 @@ HAVE_SOCKET_UDPLITE = hasattr(socket, "IPPROTO_UDPLITE") HAVE_SOCKET_BLUETOOTH = _have_socket_bluetooth() +HAVE_SOCKET_HYPERV = _have_socket_hyperv() + # Size in bytes of the int type SIZEOF_INT = array.array("i").itemsize @@ -591,17 +605,18 @@ class SocketTestBase(unittest.TestCase): def setUp(self): self.serv = self.newSocket() + self.addCleanup(self.close_server) self.bindServer() + def close_server(self): + self.serv.close() + self.serv = None + def bindServer(self): """Bind server socket and set self.serv_addr to its address.""" self.bindSock(self.serv) self.serv_addr = self.serv.getsockname() - def tearDown(self): - self.serv.close() - self.serv = None - class SocketListeningTestMixin(SocketTestBase): """Mixin to listen on the server socket.""" @@ -686,15 +701,10 @@ class UnixSocketTestBase(SocketTestBase): # can't send anything that might be problematic for a privileged # user running the tests. - def setUp(self): - self.dir_path = tempfile.mkdtemp() - self.addCleanup(os.rmdir, self.dir_path) - super().setUp() - def bindSock(self, sock): - path = tempfile.mktemp(dir=self.dir_path) - socket_helper.bind_unix_socket(sock, path) + path = socket_helper.create_unix_domain_name() self.addCleanup(os_helper.unlink, path) + socket_helper.bind_unix_socket(sock, path) class UnixStreamBase(UnixSocketTestBase): """Base class for Unix-domain SOCK_STREAM tests.""" @@ -827,6 +837,12 @@ def requireSocket(*args): class GeneralModuleTests(unittest.TestCase): + @unittest.skipUnless(_socket is not None, 'need _socket module') + def test_socket_type(self): + self.assertTrue(gc.is_tracked(_socket.socket)) + with self.assertRaisesRegex(TypeError, "immutable"): + _socket.socket.foo = 1 + def test_SocketType_is_socketobject(self): import _socket self.assertTrue(socket.SocketType is _socket.socket) @@ -1591,6 +1607,54 @@ class GeneralModuleTests(unittest.TestCase): except socket.gaierror: pass + def test_getaddrinfo_int_port_overflow(self): + # gh-74895: Test that getaddrinfo does not raise OverflowError on port. + # + # POSIX getaddrinfo() never specify the valid range for "service" + # decimal port number values. For IPv4 and IPv6 they are technically + # unsigned 16-bit values, but the API is protocol agnostic. Which values + # trigger an error from the C library function varies by platform as + # they do not all perform validation. + + # The key here is that we don't want to produce OverflowError as Python + # prior to 3.12 did for ints outside of a [LONG_MIN, LONG_MAX] range. + # Leave the error up to the underlying string based platform C API. + + from _testcapi import ULONG_MAX, LONG_MAX, LONG_MIN + try: + socket.getaddrinfo(None, ULONG_MAX + 1, type=socket.SOCK_STREAM) + except OverflowError: + # Platforms differ as to what values consitute a getaddrinfo() error + # return. Some fail for LONG_MAX+1, others ULONG_MAX+1, and Windows + # silently accepts such huge "port" aka "service" numeric values. + self.fail("Either no error or socket.gaierror expected.") + except socket.gaierror: + pass + + try: + socket.getaddrinfo(None, LONG_MAX + 1, type=socket.SOCK_STREAM) + except OverflowError: + self.fail("Either no error or socket.gaierror expected.") + except socket.gaierror: + pass + + try: + socket.getaddrinfo(None, LONG_MAX - 0xffff + 1, type=socket.SOCK_STREAM) + except OverflowError: + self.fail("Either no error or socket.gaierror expected.") + except socket.gaierror: + pass + + try: + socket.getaddrinfo(None, LONG_MIN - 1, type=socket.SOCK_STREAM) + except OverflowError: + self.fail("Either no error or socket.gaierror expected.") + except socket.gaierror: + pass + + socket.getaddrinfo(None, 0, type=socket.SOCK_STREAM) # No error expected. + socket.getaddrinfo(None, 0xffff, type=socket.SOCK_STREAM) # No error expected. + def test_getnameinfo(self): # only IP addresses are allowed self.assertRaises(OSError, socket.getnameinfo, ('mail.python.org',0), 0) @@ -1919,17 +1983,18 @@ class GeneralModuleTests(unittest.TestCase): self._test_socket_fileno(s, socket.AF_INET6, socket.SOCK_STREAM) if hasattr(socket, "AF_UNIX"): - tmpdir = tempfile.mkdtemp() - self.addCleanup(shutil.rmtree, tmpdir) + unix_name = socket_helper.create_unix_domain_name() + self.addCleanup(os_helper.unlink, unix_name) + s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) - self.addCleanup(s.close) - try: - s.bind(os.path.join(tmpdir, 'socket')) - except PermissionError: - pass - else: - self._test_socket_fileno(s, socket.AF_UNIX, - socket.SOCK_STREAM) + with s: + try: + s.bind(unix_name) + except PermissionError: + pass + else: + self._test_socket_fileno(s, socket.AF_UNIX, + socket.SOCK_STREAM) def test_socket_fileno_rejects_float(self): with self.assertRaises(TypeError): @@ -2487,6 +2552,58 @@ class BasicBluetoothTest(unittest.TestCase): pass +@unittest.skipUnless(HAVE_SOCKET_HYPERV, + 'Hyper-V sockets required for this test.') +class BasicHyperVTest(unittest.TestCase): + + def testHyperVConstants(self): + socket.HVSOCKET_CONNECT_TIMEOUT + socket.HVSOCKET_CONNECT_TIMEOUT_MAX + socket.HVSOCKET_CONNECTED_SUSPEND + socket.HVSOCKET_ADDRESS_FLAG_PASSTHRU + socket.HV_GUID_ZERO + socket.HV_GUID_WILDCARD + socket.HV_GUID_BROADCAST + socket.HV_GUID_CHILDREN + socket.HV_GUID_LOOPBACK + socket.HV_GUID_PARENT + + def testCreateHyperVSocketWithUnknownProtoFailure(self): + expected = r"\[WinError 10041\]" + with self.assertRaisesRegex(OSError, expected): + socket.socket(socket.AF_HYPERV, socket.SOCK_STREAM) + + def testCreateHyperVSocketAddrNotTupleFailure(self): + expected = "connect(): AF_HYPERV address must be tuple, not str" + with socket.socket(socket.AF_HYPERV, socket.SOCK_STREAM, socket.HV_PROTOCOL_RAW) as s: + with self.assertRaisesRegex(TypeError, re.escape(expected)): + s.connect(socket.HV_GUID_ZERO) + + def testCreateHyperVSocketAddrNotTupleOf2StrsFailure(self): + expected = "AF_HYPERV address must be a str tuple (vm_id, service_id)" + with socket.socket(socket.AF_HYPERV, socket.SOCK_STREAM, socket.HV_PROTOCOL_RAW) as s: + with self.assertRaisesRegex(TypeError, re.escape(expected)): + s.connect((socket.HV_GUID_ZERO,)) + + def testCreateHyperVSocketAddrNotTupleOfStrsFailure(self): + expected = "AF_HYPERV address must be a str tuple (vm_id, service_id)" + with socket.socket(socket.AF_HYPERV, socket.SOCK_STREAM, socket.HV_PROTOCOL_RAW) as s: + with self.assertRaisesRegex(TypeError, re.escape(expected)): + s.connect((1, 2)) + + def testCreateHyperVSocketAddrVmIdNotValidUUIDFailure(self): + expected = "connect(): AF_HYPERV address vm_id is not a valid UUID string" + with socket.socket(socket.AF_HYPERV, socket.SOCK_STREAM, socket.HV_PROTOCOL_RAW) as s: + with self.assertRaisesRegex(ValueError, re.escape(expected)): + s.connect(("00", socket.HV_GUID_ZERO)) + + def testCreateHyperVSocketAddrServiceIdNotValidUUIDFailure(self): + expected = "connect(): AF_HYPERV address service_id is not a valid UUID string" + with socket.socket(socket.AF_HYPERV, socket.SOCK_STREAM, socket.HV_PROTOCOL_RAW) as s: + with self.assertRaisesRegex(ValueError, re.escape(expected)): + s.connect((socket.HV_GUID_ZERO, "00")) + + class BasicTCPTest(SocketConnectedTest): def __init__(self, methodName='runTest'): @@ -5171,6 +5288,7 @@ class NetworkConnectionNoServer(unittest.TestCase): finally: socket.socket = old_socket + @socket_helper.skip_if_tcp_blackhole def test_connect(self): port = socket_helper.find_unused_port() cli = socket.socket(socket.AF_INET, socket.SOCK_STREAM) @@ -5179,6 +5297,7 @@ class NetworkConnectionNoServer(unittest.TestCase): cli.connect((HOST, port)) self.assertEqual(cm.exception.errno, errno.ECONNREFUSED) + @socket_helper.skip_if_tcp_blackhole def test_create_connection(self): # Issue #9792: errors raised by create_connection() should have # a proper errno attribute. @@ -5381,10 +5500,10 @@ class TCPTimeoutTest(SocketTCPTest): self.fail("caught timeout instead of Alarm") except Alarm: pass - except: + except BaseException as e: self.fail("caught other exception instead of Alarm:" " %s(%s):\n%s" % - (sys.exc_info()[:2] + (traceback.format_exc(),))) + (type(e), e, traceback.format_exc())) else: self.fail("nothing caught") finally: @@ -6355,12 +6474,16 @@ class LinuxKernelCryptoAPI(unittest.TestCase): self.assertEqual(op.recv(512), expected) def test_hmac_sha1(self): - expected = bytes.fromhex("effcdf6ae5eb2fa2d27416d5f184df9c259a7c79") + # gh-109396: In FIPS mode, Linux 6.5 requires a key + # of at least 112 bits. Use a key of 152 bits. + key = b"Python loves AF_ALG" + data = b"what do ya want for nothing?" + expected = bytes.fromhex("193dbb43c6297b47ea6277ec0ce67119a3f3aa66") with self.create_alg('hash', 'hmac(sha1)') as algo: - algo.setsockopt(socket.SOL_ALG, socket.ALG_SET_KEY, b"Jefe") + algo.setsockopt(socket.SOL_ALG, socket.ALG_SET_KEY, key) op, _ = algo.accept() with op: - op.sendall(b"what do ya want for nothing?") + op.sendall(data) self.assertEqual(op.recv(512), expected) # Although it should work with 3.19 and newer the test blocks on diff --git a/Lib/test/test_socketserver.py b/Lib/test/test_socketserver.py index 2edb1e0c..c81d559c 100644 --- a/Lib/test/test_socketserver.py +++ b/Lib/test/test_socketserver.py @@ -8,7 +8,6 @@ import os import select import signal import socket -import tempfile import threading import unittest import socketserver @@ -48,16 +47,8 @@ def receive(sock, n, timeout=test.support.SHORT_TIMEOUT): else: raise RuntimeError("timed out on %r" % (sock,)) -if HAVE_UNIX_SOCKETS and HAVE_FORKING: - class ForkingUnixStreamServer(socketserver.ForkingMixIn, - socketserver.UnixStreamServer): - pass - - class ForkingUnixDatagramServer(socketserver.ForkingMixIn, - socketserver.UnixDatagramServer): - pass - +@test.support.requires_fork() @contextlib.contextmanager def simple_subprocess(testcase): """Tests that a custom child process is not waited on (Issue 1540386)""" @@ -98,8 +89,7 @@ class SocketServerTest(unittest.TestCase): else: # XXX: We need a way to tell AF_UNIX to pick its own name # like AF_INET provides port==0. - dir = None - fn = tempfile.mktemp(prefix='unix_socket.', dir=dir) + fn = socket_helper.create_unix_domain_name() self.test_files.append(fn) return fn @@ -213,7 +203,7 @@ class SocketServerTest(unittest.TestCase): @requires_forking def test_ForkingUnixStreamServer(self): with simple_subprocess(self): - self.run_server(ForkingUnixStreamServer, + self.run_server(socketserver.ForkingUnixStreamServer, socketserver.StreamRequestHandler, self.stream_examine) @@ -249,7 +239,7 @@ class SocketServerTest(unittest.TestCase): @requires_unix_sockets @requires_forking def test_ForkingUnixDatagramServer(self): - self.run_server(ForkingUnixDatagramServer, + self.run_server(socketserver.ForkingUnixDatagramServer, socketserver.DatagramRequestHandler, self.dgram_examine) diff --git a/Lib/test/test_source_encoding.py b/Lib/test/test_source_encoding.py index 5fe0f312..72c2b477 100644 --- a/Lib/test/test_source_encoding.py +++ b/Lib/test/test_source_encoding.py @@ -1,7 +1,7 @@ -# -*- coding: koi8-r -*- +# -*- coding: utf-8 -*- import unittest -from test.support import script_helper, captured_stdout, requires_subprocess +from test.support import script_helper, captured_stdout, requires_subprocess, requires_resource from test.support.os_helper import TESTFN, unlink, rmtree from test.support.import_helper import unload import importlib @@ -12,15 +12,14 @@ import tempfile class MiscSourceEncodingTest(unittest.TestCase): - def test_pep263(self): - self.assertEqual( - "ðÉÔÏÎ".encode("utf-8"), - b'\xd0\x9f\xd0\xb8\xd1\x82\xd0\xbe\xd0\xbd' - ) - self.assertEqual( - "\ð".encode("utf-8"), - b'\\\xd0\x9f' - ) + def test_import_encoded_module(self): + from test.encoded_modules import test_strings + # Make sure we're actually testing something + self.assertGreaterEqual(len(test_strings), 1) + for modname, encoding, teststr in test_strings: + mod = importlib.import_module('test.encoded_modules.' + 'module_' + modname) + self.assertEqual(teststr, mod.test) def test_compilestring(self): # see #1882 @@ -251,6 +250,7 @@ class AbstractSourceEncodingTest: class UTF8ValidatorTest(unittest.TestCase): @unittest.skipIf(not sys.platform.startswith("linux"), "Too slow to run on non-Linux platforms") + @requires_resource('cpu') def test_invalid_utf8(self): # This is a port of test_utf8_decode_invalid_sequences in # test_unicode.py to exercise the separate utf8 validator in diff --git a/Lib/test/test_sqlite3/__init__.py b/Lib/test/test_sqlite3/__init__.py index 099c01e3..d777fca8 100644 --- a/Lib/test/test_sqlite3/__init__.py +++ b/Lib/test/test_sqlite3/__init__.py @@ -3,7 +3,6 @@ from test.support import import_helper, load_package_tests, verbose # Skip test if _sqlite3 module not installed. import_helper.import_module('_sqlite3') -import unittest import os import sqlite3 @@ -13,6 +12,4 @@ def load_tests(*args): return load_package_tests(pkg_dir, *args) if verbose: - print("test_sqlite3: testing with version", - "{!r}, sqlite_version {!r}".format(sqlite3.version, - sqlite3.sqlite_version)) + print(f"test_sqlite3: testing with SQLite version {sqlite3.sqlite_version}") diff --git a/Lib/test/test_sqlite3/test_cli.py b/Lib/test/test_sqlite3/test_cli.py new file mode 100644 index 00000000..303f9e03 --- /dev/null +++ b/Lib/test/test_sqlite3/test_cli.py @@ -0,0 +1,155 @@ +"""sqlite3 CLI tests.""" +import sqlite3 +import unittest + +from sqlite3.__main__ import main as cli +from test.support.os_helper import TESTFN, unlink +from test.support import captured_stdout, captured_stderr, captured_stdin + + +class CommandLineInterface(unittest.TestCase): + + def _do_test(self, *args, expect_success=True): + with ( + captured_stdout() as out, + captured_stderr() as err, + self.assertRaises(SystemExit) as cm + ): + cli(args) + return out.getvalue(), err.getvalue(), cm.exception.code + + def expect_success(self, *args): + out, err, code = self._do_test(*args) + self.assertEqual(code, 0, + "\n".join([f"Unexpected failure: {args=}", out, err])) + self.assertEqual(err, "") + return out + + def expect_failure(self, *args): + out, err, code = self._do_test(*args, expect_success=False) + self.assertNotEqual(code, 0, + "\n".join([f"Unexpected failure: {args=}", out, err])) + self.assertEqual(out, "") + return err + + def test_cli_help(self): + out = self.expect_success("-h") + self.assertIn("usage: python -m sqlite3", out) + + def test_cli_version(self): + out = self.expect_success("-v") + self.assertIn(sqlite3.sqlite_version, out) + + def test_cli_execute_sql(self): + out = self.expect_success(":memory:", "select 1") + self.assertIn("(1,)", out) + + def test_cli_execute_too_much_sql(self): + stderr = self.expect_failure(":memory:", "select 1; select 2") + err = "ProgrammingError: You can only execute one statement at a time" + self.assertIn(err, stderr) + + def test_cli_execute_incomplete_sql(self): + stderr = self.expect_failure(":memory:", "sel") + self.assertIn("OperationalError (SQLITE_ERROR)", stderr) + + def test_cli_on_disk_db(self): + self.addCleanup(unlink, TESTFN) + out = self.expect_success(TESTFN, "create table t(t)") + self.assertEqual(out, "") + out = self.expect_success(TESTFN, "select count(t) from t") + self.assertIn("(0,)", out) + + +class InteractiveSession(unittest.TestCase): + MEMORY_DB_MSG = "Connected to a transient in-memory database" + PS1 = "sqlite> " + PS2 = "... " + + def run_cli(self, *args, commands=()): + with ( + captured_stdin() as stdin, + captured_stdout() as stdout, + captured_stderr() as stderr, + self.assertRaises(SystemExit) as cm + ): + for cmd in commands: + stdin.write(cmd + "\n") + stdin.seek(0) + cli(args) + + out = stdout.getvalue() + err = stderr.getvalue() + self.assertEqual(cm.exception.code, 0, + f"Unexpected failure: {args=}\n{out}\n{err}") + return out, err + + def test_interact(self): + out, err = self.run_cli() + self.assertIn(self.MEMORY_DB_MSG, err) + self.assertIn(self.MEMORY_DB_MSG, err) + self.assertTrue(out.endswith(self.PS1)) + self.assertEqual(out.count(self.PS1), 1) + self.assertEqual(out.count(self.PS2), 0) + + def test_interact_quit(self): + out, err = self.run_cli(commands=(".quit",)) + self.assertIn(self.MEMORY_DB_MSG, err) + self.assertTrue(out.endswith(self.PS1)) + self.assertEqual(out.count(self.PS1), 1) + self.assertEqual(out.count(self.PS2), 0) + + def test_interact_version(self): + out, err = self.run_cli(commands=(".version",)) + self.assertIn(self.MEMORY_DB_MSG, err) + self.assertIn(sqlite3.sqlite_version + "\n", out) + self.assertTrue(out.endswith(self.PS1)) + self.assertEqual(out.count(self.PS1), 2) + self.assertEqual(out.count(self.PS2), 0) + self.assertIn(sqlite3.sqlite_version, out) + + def test_interact_valid_sql(self): + out, err = self.run_cli(commands=("SELECT 1;",)) + self.assertIn(self.MEMORY_DB_MSG, err) + self.assertIn("(1,)\n", out) + self.assertTrue(out.endswith(self.PS1)) + self.assertEqual(out.count(self.PS1), 2) + self.assertEqual(out.count(self.PS2), 0) + + def test_interact_incomplete_multiline_sql(self): + out, err = self.run_cli(commands=("SELECT 1",)) + self.assertIn(self.MEMORY_DB_MSG, err) + self.assertTrue(out.endswith(self.PS2)) + self.assertEqual(out.count(self.PS1), 1) + self.assertEqual(out.count(self.PS2), 1) + + def test_interact_valid_multiline_sql(self): + out, err = self.run_cli(commands=("SELECT 1\n;",)) + self.assertIn(self.MEMORY_DB_MSG, err) + self.assertIn(self.PS2, out) + self.assertIn("(1,)\n", out) + self.assertTrue(out.endswith(self.PS1)) + self.assertEqual(out.count(self.PS1), 2) + self.assertEqual(out.count(self.PS2), 1) + + def test_interact_invalid_sql(self): + out, err = self.run_cli(commands=("sel;",)) + self.assertIn(self.MEMORY_DB_MSG, err) + self.assertIn("OperationalError (SQLITE_ERROR)", err) + self.assertTrue(out.endswith(self.PS1)) + self.assertEqual(out.count(self.PS1), 2) + self.assertEqual(out.count(self.PS2), 0) + + def test_interact_on_disk_file(self): + self.addCleanup(unlink, TESTFN) + + out, err = self.run_cli(TESTFN, commands=("CREATE TABLE t(t);",)) + self.assertIn(TESTFN, err) + self.assertTrue(out.endswith(self.PS1)) + + out, _ = self.run_cli(TESTFN, commands=("SELECT count(t) FROM t;",)) + self.assertIn("(0,)\n", out) + + +if __name__ == "__main__": + unittest.main() diff --git a/Lib/test/test_sqlite3/test_dbapi.py b/Lib/test/test_sqlite3/test_dbapi.py index 2aea1105..1a3bb6cc 100644 --- a/Lib/test/test_sqlite3/test_dbapi.py +++ b/Lib/test/test_sqlite3/test_dbapi.py @@ -30,7 +30,7 @@ import unittest import urllib.parse from test.support import ( - SHORT_TIMEOUT, bigmemtest, check_disallow_instantiation, requires_subprocess, + SHORT_TIMEOUT, check_disallow_instantiation, requires_subprocess, is_emscripten, is_wasi ) from test.support import threading_helper @@ -60,6 +60,17 @@ class ModuleTests(unittest.TestCase): self.assertEqual(sqlite.apilevel, "2.0", "apilevel is %s, should be 2.0" % sqlite.apilevel) + def test_deprecated_version(self): + msg = "deprecated and will be removed in Python 3.14" + for attr in "version", "version_info": + with self.subTest(attr=attr): + with self.assertWarnsRegex(DeprecationWarning, msg) as cm: + getattr(sqlite, attr) + self.assertEqual(cm.filename, __file__) + with self.assertWarnsRegex(DeprecationWarning, msg) as cm: + getattr(sqlite.dbapi2, attr) + self.assertEqual(cm.filename, __file__) + def test_thread_safety(self): self.assertIn(sqlite.threadsafety, {0, 1, 3}, "threadsafety is %d, should be 0, 1 or 3" % @@ -333,15 +344,6 @@ class ModuleTests(unittest.TestCase): sqlite.SQLITE_CONSTRAINT_CHECK) self.assertEqual(exc.sqlite_errorname, "SQLITE_CONSTRAINT_CHECK") - # sqlite3_enable_shared_cache() is deprecated on macOS and calling it may raise - # OperationalError on some buildbots. - @unittest.skipIf(sys.platform == "darwin", "shared cache is deprecated on macOS") - def test_shared_cache_deprecated(self): - for enable in (True, False): - with self.assertWarns(DeprecationWarning) as cm: - sqlite.enable_shared_cache(enable) - self.assertIn("dbapi.py", cm.filename) - def test_disallow_instantiation(self): cx = sqlite.connect(":memory:") check_disallow_instantiation(self, type(cx("select 1"))) @@ -575,6 +577,30 @@ class ConnectionTests(unittest.TestCase): cx.executemany, "insert into t values(?)", ((v,) for v in range(3))) + def test_connection_config(self): + op = sqlite.SQLITE_DBCONFIG_ENABLE_FKEY + with memory_database() as cx: + with self.assertRaisesRegex(ValueError, "unknown"): + cx.getconfig(-1) + + # Toggle and verify. + old = cx.getconfig(op) + new = not old + cx.setconfig(op, new) + self.assertEqual(cx.getconfig(op), new) + + cx.setconfig(op) # defaults to True + self.assertTrue(cx.getconfig(op)) + + # Check that foreign key support was actually enabled. + with cx: + cx.executescript(""" + create table t(t integer primary key); + create table u(u, foreign key(u) references t(t)); + """) + with self.assertRaisesRegex(sqlite.IntegrityError, "constraint"): + cx.execute("insert into u values(0)") + class UninitialisedConnectionTests(unittest.TestCase): def setUp(self): @@ -604,7 +630,6 @@ class SerializeTests(unittest.TestCase): with cx: cx.execute("create table t(t)") data = cx.serialize() - self.assertEqual(len(data), 8192) # Remove test table, verify that it was removed. with cx: @@ -638,13 +663,6 @@ class SerializeTests(unittest.TestCase): # deserialized database. cx.execute("create table fail(f)") - @unittest.skipUnless(sys.maxsize > 2**32, 'requires 64bit platform') - @bigmemtest(size=2**63, memuse=3, dry_run=False) - def test_deserialize_too_much_data_64bit(self): - with memory_database() as cx: - with self.assertRaisesRegex(OverflowError, "'data' is too large"): - cx.deserialize(b"b" * size) - class OpenTests(unittest.TestCase): _sql = "create table test(id integer)" @@ -866,6 +884,21 @@ class CursorTests(unittest.TestCase): with self.assertRaises(ZeroDivisionError): self.cu.execute("select name from test where name=?", L()) + def test_execute_named_param_and_sequence(self): + dataset = ( + ("select :a", (1,)), + ("select :a, ?, ?", (1, 2, 3)), + ("select ?, :b, ?", (1, 2, 3)), + ("select ?, ?, :c", (1, 2, 3)), + ("select :a, :b, ?", (1, 2, 3)), + ) + msg = "Binding.*is a named parameter" + for query, params in dataset: + with self.subTest(query=query, params=params): + with self.assertWarnsRegex(DeprecationWarning, msg) as cm: + self.cu.execute(query, params) + self.assertEqual(cm.filename, __file__) + def test_execute_too_many_params(self): category = sqlite.SQLITE_LIMIT_VARIABLE_NUMBER msg = "too many SQL variables" @@ -1462,6 +1495,14 @@ class BlobTests(unittest.TestCase): "Cannot operate on a closed database", blob.read) + def test_blob_32bit_rowid(self): + # gh-100370: we should not get an OverflowError for 32-bit rowids + with memory_database() as cx: + rowid = 2**32 + cx.execute("create table t(t blob)") + cx.execute("insert into t(rowid, t) values (?, zeroblob(1))", (rowid,)) + cx.blobopen('t', 't', rowid) + @threading_helper.requires_working_threading() class ThreadTests(unittest.TestCase): @@ -1830,7 +1871,7 @@ class SqliteOnConflictTests(unittest.TestCase): @requires_subprocess() class MultiprocessTests(unittest.TestCase): - CONNECTION_TIMEOUT = SHORT_TIMEOUT / 1000. # Defaults to 30 ms + CONNECTION_TIMEOUT = 0 # Disable the busy timeout. def tearDown(self): unlink(TESTFN) diff --git a/Lib/test/test_sqlite3/test_dump.py b/Lib/test/test_sqlite3/test_dump.py index d0c24b9c..c3ed3aef 100644 --- a/Lib/test/test_sqlite3/test_dump.py +++ b/Lib/test/test_sqlite3/test_dump.py @@ -117,6 +117,26 @@ class DumpTests(unittest.TestCase): got = list(self.cx.iterdump()) self.assertEqual(expected, got) + def test_dump_virtual_tables(self): + # gh-64662 + expected = [ + "BEGIN TRANSACTION;", + "PRAGMA writable_schema=ON;", + ("INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)" + "VALUES('table','test','test',0,'CREATE VIRTUAL TABLE test USING fts4(example)');"), + "CREATE TABLE 'test_content'(docid INTEGER PRIMARY KEY, 'c0example');", + "CREATE TABLE 'test_docsize'(docid INTEGER PRIMARY KEY, size BLOB);", + ("CREATE TABLE 'test_segdir'(level INTEGER,idx INTEGER,start_block INTEGER," + "leaves_end_block INTEGER,end_block INTEGER,root BLOB,PRIMARY KEY(level, idx));"), + "CREATE TABLE 'test_segments'(blockid INTEGER PRIMARY KEY, block BLOB);", + "CREATE TABLE 'test_stat'(id INTEGER PRIMARY KEY, value BLOB);", + "PRAGMA writable_schema=OFF;", + "COMMIT;" + ] + self.cu.execute("CREATE VIRTUAL TABLE test USING fts4(example)") + actual = list(self.cx.iterdump()) + self.assertEqual(expected, actual) + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_sqlite3/test_factory.py b/Lib/test/test_sqlite3/test_factory.py index 2b70093b..62909842 100644 --- a/Lib/test/test_sqlite3/test_factory.py +++ b/Lib/test/test_sqlite3/test_factory.py @@ -111,6 +111,7 @@ class RowFactoryTestsBackwardsCompat(unittest.TestCase): class RowFactoryTests(unittest.TestCase): def setUp(self): self.con = sqlite.connect(":memory:") + self.con.row_factory = sqlite.Row def test_custom_factory(self): self.con.row_factory = lambda cur, row: list(row) @@ -118,7 +119,6 @@ class RowFactoryTests(unittest.TestCase): self.assertIsInstance(row, list) def test_sqlite_row_index(self): - self.con.row_factory = sqlite.Row row = self.con.execute("select 1 as a_1, 2 as b").fetchone() self.assertIsInstance(row, sqlite.Row) @@ -149,7 +149,6 @@ class RowFactoryTests(unittest.TestCase): row[complex()] # index must be int or string def test_sqlite_row_index_unicode(self): - self.con.row_factory = sqlite.Row row = self.con.execute("select 1 as \xff").fetchone() self.assertEqual(row["\xff"], 1) with self.assertRaises(IndexError): @@ -159,7 +158,6 @@ class RowFactoryTests(unittest.TestCase): def test_sqlite_row_slice(self): # A sqlite.Row can be sliced like a list. - self.con.row_factory = sqlite.Row row = self.con.execute("select 1, 2, 3, 4").fetchone() self.assertEqual(row[0:0], ()) self.assertEqual(row[0:1], (1,)) @@ -176,8 +174,7 @@ class RowFactoryTests(unittest.TestCase): self.assertEqual(row[3:0:-2], (4, 2)) def test_sqlite_row_iter(self): - """Checks if the row object is iterable""" - self.con.row_factory = sqlite.Row + # Checks if the row object is iterable. row = self.con.execute("select 1 as a, 2 as b").fetchone() # Is iterable in correct order and produces valid results: @@ -189,23 +186,20 @@ class RowFactoryTests(unittest.TestCase): self.assertEqual(items, [1, 2]) def test_sqlite_row_as_tuple(self): - """Checks if the row object can be converted to a tuple""" - self.con.row_factory = sqlite.Row + # Checks if the row object can be converted to a tuple. row = self.con.execute("select 1 as a, 2 as b").fetchone() t = tuple(row) self.assertEqual(t, (row['a'], row['b'])) def test_sqlite_row_as_dict(self): - """Checks if the row object can be correctly converted to a dictionary""" - self.con.row_factory = sqlite.Row + # Checks if the row object can be correctly converted to a dictionary. row = self.con.execute("select 1 as a, 2 as b").fetchone() d = dict(row) self.assertEqual(d["a"], row["a"]) self.assertEqual(d["b"], row["b"]) def test_sqlite_row_hash_cmp(self): - """Checks if the row object compares and hashes correctly""" - self.con.row_factory = sqlite.Row + # Checks if the row object compares and hashes correctly. row_1 = self.con.execute("select 1 as a, 2 as b").fetchone() row_2 = self.con.execute("select 1 as a, 2 as b").fetchone() row_3 = self.con.execute("select 1 as a, 3 as b").fetchone() @@ -238,21 +232,24 @@ class RowFactoryTests(unittest.TestCase): self.assertEqual(hash(row_1), hash(row_2)) def test_sqlite_row_as_sequence(self): - """ Checks if the row object can act like a sequence """ - self.con.row_factory = sqlite.Row + # Checks if the row object can act like a sequence. row = self.con.execute("select 1 as a, 2 as b").fetchone() as_tuple = tuple(row) self.assertEqual(list(reversed(row)), list(reversed(as_tuple))) self.assertIsInstance(row, Sequence) + def test_sqlite_row_keys(self): + # Checks if the row object can return a list of columns as strings. + row = self.con.execute("select 1 as a, 2 as b").fetchone() + self.assertEqual(row.keys(), ['a', 'b']) + def test_fake_cursor_class(self): # Issue #24257: Incorrect use of PyObject_IsInstance() caused # segmentation fault. # Issue #27861: Also applies for cursor factory. class FakeCursor(str): __class__ = sqlite.Cursor - self.con.row_factory = sqlite.Row self.assertRaises(TypeError, self.con.cursor, FakeCursor) self.assertRaises(TypeError, sqlite.Row, FakeCursor(), ()) @@ -282,18 +279,6 @@ class TextFactoryTests(unittest.TestCase): self.assertEqual(type(row[0]), str, "type of row[0] must be unicode") self.assertTrue(row[0].endswith("reich"), "column must contain original data") - def test_optimized_unicode(self): - # OptimizedUnicode is deprecated as of Python 3.10 - with self.assertWarns(DeprecationWarning) as cm: - self.con.text_factory = sqlite.OptimizedUnicode - self.assertIn("factory.py", cm.filename) - austria = "Österreich" - germany = "Deutchland" - a_row = self.con.execute("select ?", (austria,)).fetchone() - d_row = self.con.execute("select ?", (germany,)).fetchone() - self.assertEqual(type(a_row[0]), str, "type of non-ASCII row must be str") - self.assertEqual(type(d_row[0]), str, "type of ASCII-only row must be str") - def tearDown(self): self.con.close() diff --git a/Lib/test/test_sqlite3/test_regression.py b/Lib/test/test_sqlite3/test_regression.py index 9a07e02a..7e8221e7 100644 --- a/Lib/test/test_sqlite3/test_regression.py +++ b/Lib/test/test_sqlite3/test_regression.py @@ -129,7 +129,8 @@ class RegressionTests(unittest.TestCase): con = sqlite.connect(":memory:",detect_types=sqlite.PARSE_DECLTYPES) cur = con.cursor() cur.execute("create table foo(bar timestamp)") - cur.execute("insert into foo(bar) values (?)", (datetime.datetime.now(),)) + with self.assertWarnsRegex(DeprecationWarning, "adapter"): + cur.execute("insert into foo(bar) values (?)", (datetime.datetime.now(),)) cur.execute(SELECT) cur.execute("drop table foo") cur.execute("create table foo(bar integer)") @@ -305,7 +306,8 @@ class RegressionTests(unittest.TestCase): cur.execute("INSERT INTO t (x) VALUES ('2012-04-04 15:06:00.123456789')") cur.execute("SELECT * FROM t") - values = [x[0] for x in cur.fetchall()] + with self.assertWarnsRegex(DeprecationWarning, "converter"): + values = [x[0] for x in cur.fetchall()] self.assertEqual(values, [ datetime.datetime(2012, 4, 4, 15, 6, 0, 456000), @@ -469,18 +471,6 @@ class RegressionTests(unittest.TestCase): con.executescript("select step(t) from t") self.assertEqual(steps, values) - def test_custom_cursor_object_crash_gh_99886(self): - # This test segfaults on GH-99886 - class MyCursor(sqlite.Cursor): - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - # this can go before or after the super call; doesn't matter - self.some_attr = None - - with memory_database() as con: - cur = con.cursor(MyCursor) - cur.close() - del cur class RecursiveUseOfCursors(unittest.TestCase): # GH-80254: sqlite3 should not segfault for recursive use of cursors. @@ -501,21 +491,21 @@ class RecursiveUseOfCursors(unittest.TestCase): def test_recursive_cursor_init(self): conv = lambda x: self.cur.__init__(self.con) with patch.dict(sqlite.converters, {"INIT": conv}): - self.cur.execute(f'select x as "x [INIT]", x from test') + self.cur.execute('select x as "x [INIT]", x from test') self.assertRaisesRegex(sqlite.ProgrammingError, self.msg, self.cur.fetchall) def test_recursive_cursor_close(self): conv = lambda x: self.cur.close() with patch.dict(sqlite.converters, {"CLOSE": conv}): - self.cur.execute(f'select x as "x [CLOSE]", x from test') + self.cur.execute('select x as "x [CLOSE]", x from test') self.assertRaisesRegex(sqlite.ProgrammingError, self.msg, self.cur.fetchall) def test_recursive_cursor_iter(self): conv = lambda x, l=[]: self.cur.fetchone() if l else l.append(None) with patch.dict(sqlite.converters, {"ITER": conv}): - self.cur.execute(f'select x as "x [ITER]", x from test') + self.cur.execute('select x as "x [ITER]", x from test') self.assertRaisesRegex(sqlite.ProgrammingError, self.msg, self.cur.fetchall) diff --git a/Lib/test/test_sqlite3/test_transactions.py b/Lib/test/test_sqlite3/test_transactions.py index a67d7270..2d7a9327 100644 --- a/Lib/test/test_sqlite3/test_transactions.py +++ b/Lib/test/test_sqlite3/test_transactions.py @@ -20,24 +20,24 @@ # misrepresented as being the original software. # 3. This notice may not be removed or altered from any source distribution. -import os, unittest +import unittest import sqlite3 as sqlite +from contextlib import contextmanager -from test.support import LOOPBACK_TIMEOUT from test.support.os_helper import TESTFN, unlink +from test.support.script_helper import assert_python_ok from test.test_sqlite3.test_dbapi import memory_database -TIMEOUT = LOOPBACK_TIMEOUT / 10 - - class TransactionTests(unittest.TestCase): def setUp(self): - self.con1 = sqlite.connect(TESTFN, timeout=TIMEOUT) + # We can disable the busy handlers, since we control + # the order of SQLite C API operations. + self.con1 = sqlite.connect(TESTFN, timeout=0) self.cur1 = self.con1.cursor() - self.con2 = sqlite.connect(TESTFN, timeout=TIMEOUT) + self.con2 = sqlite.connect(TESTFN, timeout=0) self.cur2 = self.con2.cursor() def tearDown(self): @@ -117,10 +117,8 @@ class TransactionTests(unittest.TestCase): self.cur2.execute("insert into test(i) values (5)") def test_locking(self): - """ - This tests the improved concurrency with pysqlite 2.3.4. You needed - to roll back con2 before you could commit con1. - """ + # This tests the improved concurrency with pysqlite 2.3.4. You needed + # to roll back con2 before you could commit con1. self.cur1.execute("create table test(i)") self.cur1.execute("insert into test(i) values (5)") with self.assertRaises(sqlite.OperationalError): @@ -366,5 +364,176 @@ class IsolationLevelPostInit(unittest.TestCase): self.assertEqual(self.traced, [self.QUERY]) +class AutocommitAttribute(unittest.TestCase): + """Test PEP 249-compliant autocommit behaviour.""" + legacy = sqlite.LEGACY_TRANSACTION_CONTROL + + @contextmanager + def check_stmt_trace(self, cx, expected, reset=True): + try: + traced = [] + cx.set_trace_callback(lambda stmt: traced.append(stmt)) + yield + finally: + self.assertEqual(traced, expected) + if reset: + cx.set_trace_callback(None) + + def test_autocommit_default(self): + with memory_database() as cx: + self.assertEqual(cx.autocommit, + sqlite.LEGACY_TRANSACTION_CONTROL) + + def test_autocommit_setget(self): + dataset = ( + True, + False, + sqlite.LEGACY_TRANSACTION_CONTROL, + ) + for mode in dataset: + with self.subTest(mode=mode): + with memory_database(autocommit=mode) as cx: + self.assertEqual(cx.autocommit, mode) + with memory_database() as cx: + cx.autocommit = mode + self.assertEqual(cx.autocommit, mode) + + def test_autocommit_setget_invalid(self): + msg = "autocommit must be True, False, or.*LEGACY" + for mode in "a", 12, (), None: + with self.subTest(mode=mode): + with self.assertRaisesRegex(ValueError, msg): + sqlite.connect(":memory:", autocommit=mode) + + def test_autocommit_disabled(self): + expected = [ + "SELECT 1", + "COMMIT", + "BEGIN", + "ROLLBACK", + "BEGIN", + ] + with memory_database(autocommit=False) as cx: + self.assertTrue(cx.in_transaction) + with self.check_stmt_trace(cx, expected): + cx.execute("SELECT 1") + cx.commit() + cx.rollback() + + def test_autocommit_disabled_implicit_rollback(self): + expected = ["ROLLBACK"] + with memory_database(autocommit=False) as cx: + self.assertTrue(cx.in_transaction) + with self.check_stmt_trace(cx, expected, reset=False): + cx.close() + + def test_autocommit_enabled(self): + expected = ["CREATE TABLE t(t)", "INSERT INTO t VALUES(1)"] + with memory_database(autocommit=True) as cx: + self.assertFalse(cx.in_transaction) + with self.check_stmt_trace(cx, expected): + cx.execute("CREATE TABLE t(t)") + cx.execute("INSERT INTO t VALUES(1)") + self.assertFalse(cx.in_transaction) + + def test_autocommit_enabled_txn_ctl(self): + for op in "commit", "rollback": + with self.subTest(op=op): + with memory_database(autocommit=True) as cx: + meth = getattr(cx, op) + self.assertFalse(cx.in_transaction) + with self.check_stmt_trace(cx, []): + meth() # expect this to pass silently + self.assertFalse(cx.in_transaction) + + def test_autocommit_disabled_then_enabled(self): + expected = ["COMMIT"] + with memory_database(autocommit=False) as cx: + self.assertTrue(cx.in_transaction) + with self.check_stmt_trace(cx, expected): + cx.autocommit = True # should commit + self.assertFalse(cx.in_transaction) + + def test_autocommit_enabled_then_disabled(self): + expected = ["BEGIN"] + with memory_database(autocommit=True) as cx: + self.assertFalse(cx.in_transaction) + with self.check_stmt_trace(cx, expected): + cx.autocommit = False # should begin + self.assertTrue(cx.in_transaction) + + def test_autocommit_explicit_then_disabled(self): + expected = ["BEGIN DEFERRED"] + with memory_database(autocommit=True) as cx: + self.assertFalse(cx.in_transaction) + with self.check_stmt_trace(cx, expected): + cx.execute("BEGIN DEFERRED") + cx.autocommit = False # should now be a no-op + self.assertTrue(cx.in_transaction) + + def test_autocommit_enabled_ctx_mgr(self): + with memory_database(autocommit=True) as cx: + # The context manager is a no-op if autocommit=True + with self.check_stmt_trace(cx, []): + with cx: + self.assertFalse(cx.in_transaction) + self.assertFalse(cx.in_transaction) + + def test_autocommit_disabled_ctx_mgr(self): + expected = ["COMMIT", "BEGIN"] + with memory_database(autocommit=False) as cx: + with self.check_stmt_trace(cx, expected): + with cx: + self.assertTrue(cx.in_transaction) + self.assertTrue(cx.in_transaction) + + def test_autocommit_compat_ctx_mgr(self): + expected = ["BEGIN ", "INSERT INTO T VALUES(1)", "COMMIT"] + with memory_database(autocommit=self.legacy) as cx: + cx.execute("create table t(t)") + with self.check_stmt_trace(cx, expected): + with cx: + self.assertFalse(cx.in_transaction) + cx.execute("INSERT INTO T VALUES(1)") + self.assertTrue(cx.in_transaction) + self.assertFalse(cx.in_transaction) + + def test_autocommit_enabled_executescript(self): + expected = ["BEGIN", "SELECT 1"] + with memory_database(autocommit=True) as cx: + with self.check_stmt_trace(cx, expected): + self.assertFalse(cx.in_transaction) + cx.execute("BEGIN") + cx.executescript("SELECT 1") + self.assertTrue(cx.in_transaction) + + def test_autocommit_disabled_executescript(self): + expected = ["SELECT 1"] + with memory_database(autocommit=False) as cx: + with self.check_stmt_trace(cx, expected): + self.assertTrue(cx.in_transaction) + cx.executescript("SELECT 1") + self.assertTrue(cx.in_transaction) + + def test_autocommit_compat_executescript(self): + expected = ["BEGIN", "COMMIT", "SELECT 1"] + with memory_database(autocommit=self.legacy) as cx: + with self.check_stmt_trace(cx, expected): + self.assertFalse(cx.in_transaction) + cx.execute("BEGIN") + cx.executescript("SELECT 1") + self.assertFalse(cx.in_transaction) + + def test_autocommit_disabled_implicit_shutdown(self): + # The implicit ROLLBACK should not call back into Python during + # interpreter tear-down. + code = """if 1: + import sqlite3 + cx = sqlite3.connect(":memory:", autocommit=False) + cx.set_trace_callback(print) + """ + assert_python_ok("-c", code, PYTHONIOENCODING="utf-8") + + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_sqlite3/test_types.py b/Lib/test/test_sqlite3/test_types.py index ed225486..fde5f888 100644 --- a/Lib/test/test_sqlite3/test_types.py +++ b/Lib/test/test_sqlite3/test_types.py @@ -496,38 +496,51 @@ class DateTimeTests(unittest.TestCase): def test_sqlite_date(self): d = sqlite.Date(2004, 2, 14) - self.cur.execute("insert into test(d) values (?)", (d,)) + with self.assertWarnsRegex(DeprecationWarning, "adapter") as cm: + self.cur.execute("insert into test(d) values (?)", (d,)) + self.assertEqual(cm.filename, __file__) self.cur.execute("select d from test") - d2 = self.cur.fetchone()[0] + with self.assertWarnsRegex(DeprecationWarning, "converter") as cm: + d2 = self.cur.fetchone()[0] + self.assertEqual(cm.filename, __file__) self.assertEqual(d, d2) def test_sqlite_timestamp(self): ts = sqlite.Timestamp(2004, 2, 14, 7, 15, 0) - self.cur.execute("insert into test(ts) values (?)", (ts,)) + with self.assertWarnsRegex(DeprecationWarning, "adapter") as cm: + self.cur.execute("insert into test(ts) values (?)", (ts,)) + self.assertEqual(cm.filename, __file__) self.cur.execute("select ts from test") - ts2 = self.cur.fetchone()[0] + with self.assertWarnsRegex(DeprecationWarning, "converter") as cm: + ts2 = self.cur.fetchone()[0] + self.assertEqual(cm.filename, __file__) self.assertEqual(ts, ts2) def test_sql_timestamp(self): - now = datetime.datetime.utcnow() + now = datetime.datetime.now(tz=datetime.UTC) self.cur.execute("insert into test(ts) values (current_timestamp)") self.cur.execute("select ts from test") - ts = self.cur.fetchone()[0] + with self.assertWarnsRegex(DeprecationWarning, "converter"): + ts = self.cur.fetchone()[0] self.assertEqual(type(ts), datetime.datetime) self.assertEqual(ts.year, now.year) def test_date_time_sub_seconds(self): ts = sqlite.Timestamp(2004, 2, 14, 7, 15, 0, 500000) - self.cur.execute("insert into test(ts) values (?)", (ts,)) + with self.assertWarnsRegex(DeprecationWarning, "adapter"): + self.cur.execute("insert into test(ts) values (?)", (ts,)) self.cur.execute("select ts from test") - ts2 = self.cur.fetchone()[0] + with self.assertWarnsRegex(DeprecationWarning, "converter"): + ts2 = self.cur.fetchone()[0] self.assertEqual(ts, ts2) def test_date_time_sub_seconds_floating_point(self): ts = sqlite.Timestamp(2004, 2, 14, 7, 15, 0, 510241) - self.cur.execute("insert into test(ts) values (?)", (ts,)) + with self.assertWarnsRegex(DeprecationWarning, "adapter"): + self.cur.execute("insert into test(ts) values (?)", (ts,)) self.cur.execute("select ts from test") - ts2 = self.cur.fetchone()[0] + with self.assertWarnsRegex(DeprecationWarning, "converter"): + ts2 = self.cur.fetchone()[0] self.assertEqual(ts, ts2) diff --git a/Lib/test/test_sqlite3/test_userfunctions.py b/Lib/test/test_sqlite3/test_userfunctions.py index 0970b037..03d27531 100644 --- a/Lib/test/test_sqlite3/test_userfunctions.py +++ b/Lib/test/test_sqlite3/test_userfunctions.py @@ -195,7 +195,6 @@ class FunctionTests(unittest.TestCase): self.con.create_function("returnblob", 0, func_returnblob) self.con.create_function("returnlonglong", 0, func_returnlonglong) self.con.create_function("returnnan", 0, lambda: float("nan")) - self.con.create_function("returntoolargeint", 0, lambda: 1 << 65) self.con.create_function("return_noncont_blob", 0, lambda: memoryview(b"blob")[::2]) self.con.create_function("raiseexception", 0, func_raiseexception) @@ -294,11 +293,6 @@ class FunctionTests(unittest.TestCase): cur.execute("select returnnan()") self.assertIsNone(cur.fetchone()[0]) - def test_func_return_too_large_int(self): - cur = self.con.cursor() - self.assertRaisesRegex(sqlite.DataError, "string or blob too big", - self.con.execute, "select returntoolargeint()") - @with_tracebacks(ZeroDivisionError, name="func_raiseexception") def test_func_exception(self): cur = self.con.cursor() @@ -444,9 +438,10 @@ class FunctionTests(unittest.TestCase): @with_tracebacks(OverflowError) def test_func_return_too_large_int(self): cur = self.con.cursor() + msg = "string or blob too big" for value in 2**63, -2**63-1, 2**64: self.con.create_function("largeint", 0, lambda value=value: value) - with self.assertRaises(sqlite.DataError): + with self.assertRaisesRegex(sqlite.DataError, msg): cur.execute("select largeint()") @with_tracebacks(UnicodeEncodeError, "surrogates not allowed", "chr") @@ -562,7 +557,7 @@ class WindowFunctionTests(unittest.TestCase): # callback errors to sqlite3_step(); this implies that OperationalError # is _not_ raised. with patch.object(WindowSumInt, "finalize", side_effect=BadWindow): - name = f"exception_in_finalize" + name = "exception_in_finalize" self.con.create_window_function(name, 1, WindowSumInt) self.cur.execute(self.query % name) self.cur.fetchall() diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py index 3b3b869b..2c32fec5 100644 --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -9,11 +9,15 @@ from test.support import os_helper from test.support import socket_helper from test.support import threading_helper from test.support import warnings_helper +from test.support import asyncore +import re import socket import select +import struct import time import enum import gc +import http.client import os import errno import pprint @@ -30,16 +34,12 @@ except ImportError: ctypes = None -asyncore = warnings_helper.import_deprecated('asyncore') - - ssl = import_helper.import_module("ssl") import _ssl from ssl import TLSVersion, _TLSContentType, _TLSMessageType, _TLSAlertType -Py_DEBUG = hasattr(sys, 'gettotalrefcount') -Py_DEBUG_WIN32 = Py_DEBUG and sys.platform == 'win32' +Py_DEBUG_WIN32 = support.Py_DEBUG and sys.platform == 'win32' PROTOCOLS = sorted(ssl._PROTOCOL_NAMES) HOST = socket_helper.HOST @@ -48,7 +48,7 @@ PY_SSL_DEFAULT_CIPHERS = sysconfig.get_config_var('PY_SSL_DEFAULT_CIPHERS') PROTOCOL_TO_TLS_VERSION = {} for proto, ver in ( - ("PROTOCOL_SSLv23", "SSLv3"), + ("PROTOCOL_SSLv3", "SSLv3"), ("PROTOCOL_TLSv1", "TLSv1"), ("PROTOCOL_TLSv1_1", "TLSv1_1"), ): @@ -154,7 +154,6 @@ OP_SINGLE_DH_USE = getattr(ssl, "OP_SINGLE_DH_USE", 0) OP_SINGLE_ECDH_USE = getattr(ssl, "OP_SINGLE_ECDH_USE", 0) OP_CIPHER_SERVER_PREFERENCE = getattr(ssl, "OP_CIPHER_SERVER_PREFERENCE", 0) OP_ENABLE_MIDDLEBOX_COMPAT = getattr(ssl, "OP_ENABLE_MIDDLEBOX_COMPAT", 0) -OP_IGNORE_UNEXPECTED_EOF = getattr(ssl, "OP_IGNORE_UNEXPECTED_EOF", 0) # Ubuntu has patched OpenSSL and changed behavior of security level 2 # see https://bugs.python.org/issue41561#msg389003 @@ -209,10 +208,6 @@ def has_tls_version(version): :param version: TLS version name or ssl.TLSVersion member :return: bool """ - if version == "SSLv2": - # never supported and not even in TLSVersion enum - return False - if isinstance(version, str): version = ssl.TLSVersion.__members__[version] @@ -261,7 +256,7 @@ def requires_tls_version(version): def handle_error(prefix): - exc_format = ' '.join(traceback.format_exception(*sys.exc_info())) + exc_format = ' '.join(traceback.format_exception(sys.exception())) if support.verbose: sys.stdout.write(prefix + exc_format) @@ -347,6 +342,15 @@ class BasicSocketTests(unittest.TestCase): ssl.OP_NO_TLSv1_2 self.assertEqual(ssl.PROTOCOL_TLS, ssl.PROTOCOL_SSLv23) + def test_options(self): + # gh-106687: SSL options values are unsigned integer (uint64_t) + for name in dir(ssl): + if not name.startswith('OP_'): + continue + with self.subTest(option=name): + value = getattr(ssl, name) + self.assertGreaterEqual(value, 0, f"ssl.{name}") + def test_ssl_types(self): ssl_types = [ _ssl._SSLContext, @@ -383,10 +387,6 @@ class BasicSocketTests(unittest.TestCase): % (v, (v and "sufficient randomness") or "insufficient randomness")) - with warnings_helper.check_warnings(): - data, is_cryptographic = ssl.RAND_pseudo_bytes(16) - self.assertEqual(len(data), 16) - self.assertEqual(is_cryptographic, v == 1) if v: data = ssl.RAND_bytes(16) self.assertEqual(len(data), 16) @@ -395,8 +395,6 @@ class BasicSocketTests(unittest.TestCase): # negative num is invalid self.assertRaises(ValueError, ssl.RAND_bytes, -5) - with warnings_helper.check_warnings(): - self.assertRaises(ValueError, ssl.RAND_pseudo_bytes, -5) ssl.RAND_add("this is a random string", 75.0) ssl.RAND_add(b"this is a random bytes object", 75.0) @@ -640,36 +638,6 @@ class BasicSocketTests(unittest.TestCase): str(cm.warning) ) - @ignore_deprecation - def test_errors_sslwrap(self): - sock = socket.socket() - self.assertRaisesRegex(ValueError, - "certfile must be specified", - ssl.wrap_socket, sock, keyfile=CERTFILE) - self.assertRaisesRegex(ValueError, - "certfile must be specified for server-side operations", - ssl.wrap_socket, sock, server_side=True) - self.assertRaisesRegex(ValueError, - "certfile must be specified for server-side operations", - ssl.wrap_socket, sock, server_side=True, certfile="") - with ssl.wrap_socket(sock, server_side=True, certfile=CERTFILE) as s: - self.assertRaisesRegex(ValueError, "can't connect in server-side mode", - s.connect, (HOST, 8080)) - with self.assertRaises(OSError) as cm: - with socket.socket() as sock: - ssl.wrap_socket(sock, certfile=NONEXISTINGCERT) - self.assertEqual(cm.exception.errno, errno.ENOENT) - with self.assertRaises(OSError) as cm: - with socket.socket() as sock: - ssl.wrap_socket(sock, - certfile=CERTFILE, keyfile=NONEXISTINGCERT) - self.assertEqual(cm.exception.errno, errno.ENOENT) - with self.assertRaises(OSError) as cm: - with socket.socket() as sock: - ssl.wrap_socket(sock, - certfile=NONEXISTINGCERT, keyfile=NONEXISTINGCERT) - self.assertEqual(cm.exception.errno, errno.ENOENT) - def bad_cert_test(self, certfile): """Check that trying to use the given client certificate fails""" certfile = os.path.join(os.path.dirname(__file__) or os.curdir, @@ -692,205 +660,6 @@ class BasicSocketTests(unittest.TestCase): """Wrapping with a badly formatted key (syntax error)""" self.bad_cert_test("badkey.pem") - @ignore_deprecation - def test_match_hostname(self): - def ok(cert, hostname): - ssl.match_hostname(cert, hostname) - def fail(cert, hostname): - self.assertRaises(ssl.CertificateError, - ssl.match_hostname, cert, hostname) - - # -- Hostname matching -- - - cert = {'subject': ((('commonName', 'example.com'),),)} - ok(cert, 'example.com') - ok(cert, 'ExAmple.cOm') - fail(cert, 'www.example.com') - fail(cert, '.example.com') - fail(cert, 'example.org') - fail(cert, 'exampleXcom') - - cert = {'subject': ((('commonName', '*.a.com'),),)} - ok(cert, 'foo.a.com') - fail(cert, 'bar.foo.a.com') - fail(cert, 'a.com') - fail(cert, 'Xa.com') - fail(cert, '.a.com') - - # only match wildcards when they are the only thing - # in left-most segment - cert = {'subject': ((('commonName', 'f*.com'),),)} - fail(cert, 'foo.com') - fail(cert, 'f.com') - fail(cert, 'bar.com') - fail(cert, 'foo.a.com') - fail(cert, 'bar.foo.com') - - # NULL bytes are bad, CVE-2013-4073 - cert = {'subject': ((('commonName', - 'null.python.org\x00example.org'),),)} - ok(cert, 'null.python.org\x00example.org') # or raise an error? - fail(cert, 'example.org') - fail(cert, 'null.python.org') - - # error cases with wildcards - cert = {'subject': ((('commonName', '*.*.a.com'),),)} - fail(cert, 'bar.foo.a.com') - fail(cert, 'a.com') - fail(cert, 'Xa.com') - fail(cert, '.a.com') - - cert = {'subject': ((('commonName', 'a.*.com'),),)} - fail(cert, 'a.foo.com') - fail(cert, 'a..com') - fail(cert, 'a.com') - - # wildcard doesn't match IDNA prefix 'xn--' - idna = 'püthon.python.org'.encode("idna").decode("ascii") - cert = {'subject': ((('commonName', idna),),)} - ok(cert, idna) - cert = {'subject': ((('commonName', 'x*.python.org'),),)} - fail(cert, idna) - cert = {'subject': ((('commonName', 'xn--p*.python.org'),),)} - fail(cert, idna) - - # wildcard in first fragment and IDNA A-labels in sequent fragments - # are supported. - idna = 'www*.pythön.org'.encode("idna").decode("ascii") - cert = {'subject': ((('commonName', idna),),)} - fail(cert, 'www.pythön.org'.encode("idna").decode("ascii")) - fail(cert, 'www1.pythön.org'.encode("idna").decode("ascii")) - fail(cert, 'ftp.pythön.org'.encode("idna").decode("ascii")) - fail(cert, 'pythön.org'.encode("idna").decode("ascii")) - - # Slightly fake real-world example - cert = {'notAfter': 'Jun 26 21:41:46 2011 GMT', - 'subject': ((('commonName', 'linuxfrz.org'),),), - 'subjectAltName': (('DNS', 'linuxfr.org'), - ('DNS', 'linuxfr.com'), - ('othername', '<unsupported>'))} - ok(cert, 'linuxfr.org') - ok(cert, 'linuxfr.com') - # Not a "DNS" entry - fail(cert, '<unsupported>') - # When there is a subjectAltName, commonName isn't used - fail(cert, 'linuxfrz.org') - - # A pristine real-world example - cert = {'notAfter': 'Dec 18 23:59:59 2011 GMT', - 'subject': ((('countryName', 'US'),), - (('stateOrProvinceName', 'California'),), - (('localityName', 'Mountain View'),), - (('organizationName', 'Google Inc'),), - (('commonName', 'mail.google.com'),))} - ok(cert, 'mail.google.com') - fail(cert, 'gmail.com') - # Only commonName is considered - fail(cert, 'California') - - # -- IPv4 matching -- - cert = {'subject': ((('commonName', 'example.com'),),), - 'subjectAltName': (('DNS', 'example.com'), - ('IP Address', '10.11.12.13'), - ('IP Address', '14.15.16.17'), - ('IP Address', '127.0.0.1'))} - ok(cert, '10.11.12.13') - ok(cert, '14.15.16.17') - # socket.inet_ntoa(socket.inet_aton('127.1')) == '127.0.0.1' - fail(cert, '127.1') - fail(cert, '14.15.16.17 ') - fail(cert, '14.15.16.17 extra data') - fail(cert, '14.15.16.18') - fail(cert, 'example.net') - - # -- IPv6 matching -- - if socket_helper.IPV6_ENABLED: - cert = {'subject': ((('commonName', 'example.com'),),), - 'subjectAltName': ( - ('DNS', 'example.com'), - ('IP Address', '2001:0:0:0:0:0:0:CAFE\n'), - ('IP Address', '2003:0:0:0:0:0:0:BABA\n'))} - ok(cert, '2001::cafe') - ok(cert, '2003::baba') - fail(cert, '2003::baba ') - fail(cert, '2003::baba extra data') - fail(cert, '2003::bebe') - fail(cert, 'example.net') - - # -- Miscellaneous -- - - # Neither commonName nor subjectAltName - cert = {'notAfter': 'Dec 18 23:59:59 2011 GMT', - 'subject': ((('countryName', 'US'),), - (('stateOrProvinceName', 'California'),), - (('localityName', 'Mountain View'),), - (('organizationName', 'Google Inc'),))} - fail(cert, 'mail.google.com') - - # No DNS entry in subjectAltName but a commonName - cert = {'notAfter': 'Dec 18 23:59:59 2099 GMT', - 'subject': ((('countryName', 'US'),), - (('stateOrProvinceName', 'California'),), - (('localityName', 'Mountain View'),), - (('commonName', 'mail.google.com'),)), - 'subjectAltName': (('othername', 'blabla'), )} - ok(cert, 'mail.google.com') - - # No DNS entry subjectAltName and no commonName - cert = {'notAfter': 'Dec 18 23:59:59 2099 GMT', - 'subject': ((('countryName', 'US'),), - (('stateOrProvinceName', 'California'),), - (('localityName', 'Mountain View'),), - (('organizationName', 'Google Inc'),)), - 'subjectAltName': (('othername', 'blabla'),)} - fail(cert, 'google.com') - - # Empty cert / no cert - self.assertRaises(ValueError, ssl.match_hostname, None, 'example.com') - self.assertRaises(ValueError, ssl.match_hostname, {}, 'example.com') - - # Issue #17980: avoid denials of service by refusing more than one - # wildcard per fragment. - cert = {'subject': ((('commonName', 'a*b.example.com'),),)} - with self.assertRaisesRegex( - ssl.CertificateError, - "partial wildcards in leftmost label are not supported"): - ssl.match_hostname(cert, 'axxb.example.com') - - cert = {'subject': ((('commonName', 'www.*.example.com'),),)} - with self.assertRaisesRegex( - ssl.CertificateError, - "wildcard can only be present in the leftmost label"): - ssl.match_hostname(cert, 'www.sub.example.com') - - cert = {'subject': ((('commonName', 'a*b*.example.com'),),)} - with self.assertRaisesRegex( - ssl.CertificateError, - "too many wildcards"): - ssl.match_hostname(cert, 'axxbxxc.example.com') - - cert = {'subject': ((('commonName', '*'),),)} - with self.assertRaisesRegex( - ssl.CertificateError, - "sole wildcard without additional labels are not support"): - ssl.match_hostname(cert, 'host') - - cert = {'subject': ((('commonName', '*.com'),),)} - with self.assertRaisesRegex( - ssl.CertificateError, - r"hostname 'com' doesn't match '\*.com'"): - ssl.match_hostname(cert, 'com') - - # extra checks for _inet_paton() - for invalid in ['1', '', '1.2.3', '256.0.0.1', '127.0.0.1/24']: - with self.assertRaises(ValueError): - ssl._inet_paton(invalid) - for ipaddr in ['127.0.0.1', '192.168.0.1']: - self.assertTrue(ssl._inet_paton(ipaddr)) - if socket_helper.IPV6_ENABLED: - for ipaddr in ['::1', '2001:db8:85a3::8a2e:370:7334']: - self.assertTrue(ssl._inet_paton(ipaddr)) - def test_server_side(self): # server_hostname doesn't work for server sockets ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) @@ -1194,25 +963,39 @@ class ContextTests(unittest.TestCase): ) def test_options(self): + # Test default SSLContext options ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) # OP_ALL | OP_NO_SSLv2 | OP_NO_SSLv3 is the default value default = (ssl.OP_ALL | ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3) # SSLContext also enables these by default default |= (OP_NO_COMPRESSION | OP_CIPHER_SERVER_PREFERENCE | OP_SINGLE_DH_USE | OP_SINGLE_ECDH_USE | - OP_ENABLE_MIDDLEBOX_COMPAT | - OP_IGNORE_UNEXPECTED_EOF) + OP_ENABLE_MIDDLEBOX_COMPAT) self.assertEqual(default, ctx.options) + + # disallow TLSv1 with warnings_helper.check_warnings(): ctx.options |= ssl.OP_NO_TLSv1 self.assertEqual(default | ssl.OP_NO_TLSv1, ctx.options) + + # allow TLSv1 with warnings_helper.check_warnings(): ctx.options = (ctx.options & ~ssl.OP_NO_TLSv1) self.assertEqual(default, ctx.options) + + # clear all options ctx.options = 0 # Ubuntu has OP_NO_SSLv3 forced on by default self.assertEqual(0, ctx.options & ~ssl.OP_NO_SSLv3) + # invalid options + with self.assertRaises(OverflowError): + ctx.options = -1 + with self.assertRaises(OverflowError): + ctx.options = 2 ** 100 + with self.assertRaises(TypeError): + ctx.options = "abc" + def test_verify_mode_protocol(self): with warnings_helper.check_warnings(): ctx = ssl.SSLContext(ssl.PROTOCOL_TLS) @@ -1533,6 +1316,8 @@ class ContextTests(unittest.TestCase): "not enough data: cadata does not contain a certificate" ): ctx.load_verify_locations(cadata=b"broken") + with self.assertRaises(ssl.SSLError): + ctx.load_verify_locations(cadata=cacert_der + b"A") @unittest.skipIf(Py_DEBUG_WIN32, "Avoid mixing debug/release CRT on Windows") def test_load_dh_params(self): @@ -1674,7 +1459,8 @@ class ContextTests(unittest.TestCase): self.assertEqual(ctx.cert_store_stats(), {"crl": 0, "x509": 1, "x509_ca": 0}) @unittest.skipUnless(sys.platform == "win32", "Windows specific") - @unittest.skipIf(hasattr(sys, "gettotalrefcount"), "Debug build does not share environment between CRTs") + @unittest.skipIf(support.Py_DEBUG, + "Debug build does not share environment between CRTs") def test_load_default_certs_env_windows(self): ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) ctx.load_default_certs() @@ -1702,6 +1488,8 @@ class ContextTests(unittest.TestCase): if OP_CIPHER_SERVER_PREFERENCE != 0: self.assertEqual(ctx.options & OP_CIPHER_SERVER_PREFERENCE, OP_CIPHER_SERVER_PREFERENCE) + self.assertEqual(ctx.options & ssl.OP_LEGACY_SERVER_CONNECT, + 0 if IS_OPENSSL_3_0_0 else ssl.OP_LEGACY_SERVER_CONNECT) def test_create_default_context(self): ctx = ssl.create_default_context() @@ -2278,11 +2066,8 @@ class SimpleBackgroundTests(unittest.TestCase): # A simple IO loop. Call func(*args) depending on the error we get # (WANT_READ or WANT_WRITE) move data between the socket and the BIOs. timeout = kwargs.get('timeout', support.SHORT_TIMEOUT) - deadline = time.monotonic() + timeout count = 0 - while True: - if time.monotonic() > deadline: - self.fail("timeout") + for _ in support.busy_retry(timeout): errno = None count += 1 try: @@ -2326,13 +2111,13 @@ class SimpleBackgroundTests(unittest.TestCase): self.assertIs(sslobj._sslobj.owner, sslobj) self.assertIsNone(sslobj.cipher()) self.assertIsNone(sslobj.version()) - self.assertIsNotNone(sslobj.shared_ciphers()) + self.assertIsNone(sslobj.shared_ciphers()) self.assertRaises(ValueError, sslobj.getpeercert) if 'tls-unique' in ssl.CHANNEL_BINDING_TYPES: self.assertIsNone(sslobj.get_channel_binding('tls-unique')) self.ssl_io_loop(sock, incoming, outgoing, sslobj.do_handshake) self.assertTrue(sslobj.cipher()) - self.assertIsNotNone(sslobj.shared_ciphers()) + self.assertIsNone(sslobj.shared_ciphers()) self.assertIsNotNone(sslobj.version()) self.assertTrue(sslobj.getpeercert()) if 'tls-unique' in ssl.CHANNEL_BINDING_TYPES: @@ -2362,6 +2147,20 @@ class SimpleBackgroundTests(unittest.TestCase): self.assertEqual(buf, b'foo\n') self.ssl_io_loop(sock, incoming, outgoing, sslobj.unwrap) + def test_transport_eof(self): + client_context, server_context, hostname = testing_context() + with socket.socket(socket.AF_INET) as sock: + sock.connect(self.server_addr) + incoming = ssl.MemoryBIO() + outgoing = ssl.MemoryBIO() + sslobj = client_context.wrap_bio(incoming, outgoing, + server_hostname=hostname) + self.ssl_io_loop(sock, incoming, outgoing, sslobj.do_handshake) + + # Simulate EOF from the transport. + incoming.write_eof() + self.assertRaises(ssl.SSLEOFError, sslobj.read) + @support.requires_resource('network') class NetworkedTests(unittest.TestCase): @@ -2383,6 +2182,7 @@ class NetworkedTests(unittest.TestCase): self.assertIn(rc, (errno.EAGAIN, errno.EWOULDBLOCK)) @unittest.skipUnless(socket_helper.IPV6_ENABLED, 'Needs IPv6') + @support.requires_resource('walltime') def test_get_server_certificate_ipv6(self): with socket_helper.transient_internet('ipv6.google.com'): _test_get_server_certificate(self, 'ipv6.google.com', 443) @@ -2941,6 +2741,7 @@ def try_protocol_combo(server_protocol, client_protocol, expect_success, class ThreadedTests(unittest.TestCase): + @support.requires_resource('walltime') def test_echo(self): """Basic test of an SSL client connecting to a server""" if support.verbose: @@ -3349,37 +3150,10 @@ class ThreadedTests(unittest.TestCase): self.assertIn(msg, repr(e)) self.assertIn('certificate verify failed', repr(e)) - @requires_tls_version('SSLv2') - def test_protocol_sslv2(self): - """Connecting to an SSLv2 server with various client options""" - if support.verbose: - sys.stdout.write("\n") - try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True) - try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_OPTIONAL) - try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_REQUIRED) - try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_TLS, False) - if has_tls_version('SSLv3'): - try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv3, False) - try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_TLSv1, False) - # SSLv23 client with specific SSL options - try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_TLS, False, - client_options=ssl.OP_NO_SSLv3) - try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_TLS, False, - client_options=ssl.OP_NO_TLSv1) - def test_PROTOCOL_TLS(self): """Connecting to an SSLv23 server with various client options""" if support.verbose: sys.stdout.write("\n") - if has_tls_version('SSLv2'): - try: - try_protocol_combo(ssl.PROTOCOL_TLS, ssl.PROTOCOL_SSLv2, True) - except OSError as x: - # this fails on some older versions of OpenSSL (0.9.7l, for instance) - if support.verbose: - sys.stdout.write( - " SSL2 client to SSL23 server test unexpectedly failed:\n %s\n" - % str(x)) if has_tls_version('SSLv3'): try_protocol_combo(ssl.PROTOCOL_TLS, ssl.PROTOCOL_SSLv3, False) try_protocol_combo(ssl.PROTOCOL_TLS, ssl.PROTOCOL_TLS, True) @@ -3417,8 +3191,6 @@ class ThreadedTests(unittest.TestCase): try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, 'SSLv3') try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, 'SSLv3', ssl.CERT_OPTIONAL) try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, 'SSLv3', ssl.CERT_REQUIRED) - if has_tls_version('SSLv2'): - try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv2, False) try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_TLS, False, client_options=ssl.OP_NO_SSLv3) try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_TLSv1, False) @@ -3431,8 +3203,6 @@ class ThreadedTests(unittest.TestCase): try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, 'TLSv1') try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, 'TLSv1', ssl.CERT_OPTIONAL) try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, 'TLSv1', ssl.CERT_REQUIRED) - if has_tls_version('SSLv2'): - try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv2, False) if has_tls_version('SSLv3'): try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv3, False) try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLS, False, @@ -3445,8 +3215,6 @@ class ThreadedTests(unittest.TestCase): if support.verbose: sys.stdout.write("\n") try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_TLSv1_1, 'TLSv1.1') - if has_tls_version('SSLv2'): - try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_SSLv2, False) if has_tls_version('SSLv3'): try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_SSLv3, False) try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_TLS, False, @@ -3465,8 +3233,6 @@ class ThreadedTests(unittest.TestCase): try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_TLSv1_2, 'TLSv1.2', server_options=ssl.OP_NO_SSLv3|ssl.OP_NO_SSLv2, client_options=ssl.OP_NO_SSLv3|ssl.OP_NO_SSLv2,) - if has_tls_version('SSLv2'): - try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_SSLv2, False) if has_tls_version('SSLv3'): try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_SSLv3, False) try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_TLS, False, @@ -4094,6 +3860,20 @@ class ThreadedTests(unittest.TestCase): sni_name=hostname) self.assertIs(stats['compression'], None) + def test_legacy_server_connect(self): + client_context, server_context, hostname = testing_context() + client_context.options |= ssl.OP_LEGACY_SERVER_CONNECT + server_params_test(client_context, server_context, + chatty=True, connectionchatty=True, + sni_name=hostname) + + def test_no_legacy_server_connect(self): + client_context, server_context, hostname = testing_context() + client_context.options &= ~ssl.OP_LEGACY_SERVER_CONNECT + server_params_test(client_context, server_context, + chatty=True, connectionchatty=True, + sni_name=hostname) + @unittest.skipIf(Py_DEBUG_WIN32, "Avoid mixing debug/release CRT on Windows") def test_dh_params(self): # Check we can get a connection with ephemeral Diffie-Hellman @@ -4302,7 +4082,7 @@ class ThreadedTests(unittest.TestCase): def test_shared_ciphers(self): client_context, server_context, hostname = testing_context() client_context.set_ciphers("AES128:AES256") - server_context.set_ciphers("AES256") + server_context.set_ciphers("AES256:eNULL") expected_algs = [ "AES256", "AES-256", # TLS 1.3 ciphers are always enabled @@ -4884,6 +4664,254 @@ class TestSSLDebug(unittest.TestCase): s.connect((HOST, server.port)) +def set_socket_so_linger_on_with_zero_timeout(sock): + sock.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER, struct.pack('ii', 1, 0)) + + +class TestPreHandshakeClose(unittest.TestCase): + """Verify behavior of close sockets with received data before to the handshake. + """ + + class SingleConnectionTestServerThread(threading.Thread): + + def __init__(self, *, name, call_after_accept, timeout=None): + self.call_after_accept = call_after_accept + self.received_data = b'' # set by .run() + self.wrap_error = None # set by .run() + self.listener = None # set by .start() + self.port = None # set by .start() + if timeout is None: + self.timeout = support.SHORT_TIMEOUT + else: + self.timeout = timeout + super().__init__(name=name) + + def __enter__(self): + self.start() + return self + + def __exit__(self, *args): + try: + if self.listener: + self.listener.close() + except OSError: + pass + self.join() + self.wrap_error = None # avoid dangling references + + def start(self): + self.ssl_ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) + self.ssl_ctx.verify_mode = ssl.CERT_REQUIRED + self.ssl_ctx.load_verify_locations(cafile=ONLYCERT) + self.ssl_ctx.load_cert_chain(certfile=ONLYCERT, keyfile=ONLYKEY) + self.listener = socket.socket() + self.port = socket_helper.bind_port(self.listener) + self.listener.settimeout(self.timeout) + self.listener.listen(1) + super().start() + + def run(self): + try: + conn, address = self.listener.accept() + except TimeoutError: + # on timeout, just close the listener + return + finally: + self.listener.close() + + with conn: + if self.call_after_accept(conn): + return + try: + tls_socket = self.ssl_ctx.wrap_socket(conn, server_side=True) + except OSError as err: # ssl.SSLError inherits from OSError + self.wrap_error = err + else: + try: + self.received_data = tls_socket.recv(400) + except OSError: + pass # closed, protocol error, etc. + + def non_linux_skip_if_other_okay_error(self, err): + if sys.platform == "linux": + return # Expect the full test setup to always work on Linux. + if (isinstance(err, ConnectionResetError) or + (isinstance(err, OSError) and err.errno == errno.EINVAL) or + re.search('wrong.version.number', getattr(err, "reason", ""), re.I)): + # On Windows the TCP RST leads to a ConnectionResetError + # (ECONNRESET) which Linux doesn't appear to surface to userspace. + # If wrap_socket() winds up on the "if connected:" path and doing + # the actual wrapping... we get an SSLError from OpenSSL. Typically + # WRONG_VERSION_NUMBER. While appropriate, neither is the scenario + # we're specifically trying to test. The way this test is written + # is known to work on Linux. We'll skip it anywhere else that it + # does not present as doing so. + try: + self.skipTest(f"Could not recreate conditions on {sys.platform}:" + f" {err=}") + finally: + # gh-108342: Explicitly break the reference cycle + err = None + + # If maintaining this conditional winds up being a problem. + # just turn this into an unconditional skip anything but Linux. + # The important thing is that our CI has the logic covered. + + def test_preauth_data_to_tls_server(self): + server_accept_called = threading.Event() + ready_for_server_wrap_socket = threading.Event() + + def call_after_accept(unused): + server_accept_called.set() + if not ready_for_server_wrap_socket.wait(support.SHORT_TIMEOUT): + raise RuntimeError("wrap_socket event never set, test may fail.") + return False # Tell the server thread to continue. + + server = self.SingleConnectionTestServerThread( + call_after_accept=call_after_accept, + name="preauth_data_to_tls_server") + self.enterContext(server) # starts it & unittest.TestCase stops it. + + with socket.socket() as client: + client.connect(server.listener.getsockname()) + # This forces an immediate connection close via RST on .close(). + set_socket_so_linger_on_with_zero_timeout(client) + client.setblocking(False) + + server_accept_called.wait() + client.send(b"DELETE /data HTTP/1.0\r\n\r\n") + client.close() # RST + + ready_for_server_wrap_socket.set() + server.join() + + wrap_error = server.wrap_error + server.wrap_error = None + try: + self.assertEqual(b"", server.received_data) + self.assertIsInstance(wrap_error, OSError) # All platforms. + self.non_linux_skip_if_other_okay_error(wrap_error) + self.assertIsInstance(wrap_error, ssl.SSLError) + self.assertIn("before TLS handshake with data", wrap_error.args[1]) + self.assertIn("before TLS handshake with data", wrap_error.reason) + self.assertNotEqual(0, wrap_error.args[0]) + self.assertIsNone(wrap_error.library, msg="attr must exist") + finally: + # gh-108342: Explicitly break the reference cycle + wrap_error = None + server = None + + def test_preauth_data_to_tls_client(self): + server_can_continue_with_wrap_socket = threading.Event() + client_can_continue_with_wrap_socket = threading.Event() + + def call_after_accept(conn_to_client): + if not server_can_continue_with_wrap_socket.wait(support.SHORT_TIMEOUT): + print("ERROR: test client took too long") + + # This forces an immediate connection close via RST on .close(). + set_socket_so_linger_on_with_zero_timeout(conn_to_client) + conn_to_client.send( + b"HTTP/1.0 307 Temporary Redirect\r\n" + b"Location: https://example.com/someone-elses-server\r\n" + b"\r\n") + conn_to_client.close() # RST + client_can_continue_with_wrap_socket.set() + return True # Tell the server to stop. + + server = self.SingleConnectionTestServerThread( + call_after_accept=call_after_accept, + name="preauth_data_to_tls_client") + self.enterContext(server) # starts it & unittest.TestCase stops it. + # Redundant; call_after_accept sets SO_LINGER on the accepted conn. + set_socket_so_linger_on_with_zero_timeout(server.listener) + + with socket.socket() as client: + client.connect(server.listener.getsockname()) + server_can_continue_with_wrap_socket.set() + + if not client_can_continue_with_wrap_socket.wait(support.SHORT_TIMEOUT): + self.fail("test server took too long") + ssl_ctx = ssl.create_default_context() + try: + tls_client = ssl_ctx.wrap_socket( + client, server_hostname="localhost") + except OSError as err: # SSLError inherits from OSError + wrap_error = err + received_data = b"" + else: + wrap_error = None + received_data = tls_client.recv(400) + tls_client.close() + + server.join() + try: + self.assertEqual(b"", received_data) + self.assertIsInstance(wrap_error, OSError) # All platforms. + self.non_linux_skip_if_other_okay_error(wrap_error) + self.assertIsInstance(wrap_error, ssl.SSLError) + self.assertIn("before TLS handshake with data", wrap_error.args[1]) + self.assertIn("before TLS handshake with data", wrap_error.reason) + self.assertNotEqual(0, wrap_error.args[0]) + self.assertIsNone(wrap_error.library, msg="attr must exist") + finally: + # gh-108342: Explicitly break the reference cycle + wrap_error = None + server = None + + def test_https_client_non_tls_response_ignored(self): + server_responding = threading.Event() + + class SynchronizedHTTPSConnection(http.client.HTTPSConnection): + def connect(self): + # Call clear text HTTP connect(), not the encrypted HTTPS (TLS) + # connect(): wrap_socket() is called manually below. + http.client.HTTPConnection.connect(self) + + # Wait for our fault injection server to have done its thing. + if not server_responding.wait(support.SHORT_TIMEOUT) and support.verbose: + sys.stdout.write("server_responding event never set.") + self.sock = self._context.wrap_socket( + self.sock, server_hostname=self.host) + + def call_after_accept(conn_to_client): + # This forces an immediate connection close via RST on .close(). + set_socket_so_linger_on_with_zero_timeout(conn_to_client) + conn_to_client.send( + b"HTTP/1.0 402 Payment Required\r\n" + b"\r\n") + conn_to_client.close() # RST + server_responding.set() + return True # Tell the server to stop. + + timeout = 2.0 + server = self.SingleConnectionTestServerThread( + call_after_accept=call_after_accept, + name="non_tls_http_RST_responder", + timeout=timeout) + self.enterContext(server) # starts it & unittest.TestCase stops it. + # Redundant; call_after_accept sets SO_LINGER on the accepted conn. + set_socket_so_linger_on_with_zero_timeout(server.listener) + + connection = SynchronizedHTTPSConnection( + server.listener.getsockname()[0], + port=server.port, + context=ssl.create_default_context(), + timeout=timeout, + ) + + # There are lots of reasons this raises as desired, long before this + # test was added. Sending the request requires a successful TLS wrapped + # socket; that fails if the connection is broken. It may seem pointless + # to test this. It serves as an illustration of something that we never + # want to happen... properly not happening. + with self.assertRaises(OSError): + connection.request("HEAD", "/test", headers={"Host": "localhost"}) + response = connection.getresponse() + + server.join() + + class TestEnumerations(unittest.TestCase): def test_tlsversion(self): diff --git a/Lib/test/test_stable_abi_ctypes.py b/Lib/test/test_stable_abi_ctypes.py index 18c85061..8cad71c7 100644 --- a/Lib/test/test_stable_abi_ctypes.py +++ b/Lib/test/test_stable_abi_ctypes.py @@ -1,5 +1,4 @@ - -# Generated by Tools/scripts/stable_abi.py +# Generated by Tools/build/stable_abi.py """Test that all symbols of the Stable ABI are accessible using ctypes """ @@ -166,12 +165,14 @@ SYMBOL_NAMES = ( "PyErr_CheckSignals", "PyErr_Clear", "PyErr_Display", + "PyErr_DisplayException", "PyErr_ExceptionMatches", "PyErr_Fetch", "PyErr_Format", "PyErr_FormatV", "PyErr_GetExcInfo", "PyErr_GetHandledException", + "PyErr_GetRaisedException", "PyErr_GivenExceptionMatches", "PyErr_NewException", "PyErr_NewExceptionWithDoc", @@ -195,6 +196,7 @@ SYMBOL_NAMES = ( "PyErr_SetInterruptEx", "PyErr_SetNone", "PyErr_SetObject", + "PyErr_SetRaisedException", "PyErr_SetString", "PyErr_SyntaxLocation", "PyErr_SyntaxLocationEx", @@ -292,9 +294,11 @@ SYMBOL_NAMES = ( "PyExc_Warning", "PyExc_ZeroDivisionError", "PyExceptionClass_Name", + "PyException_GetArgs", "PyException_GetCause", "PyException_GetContext", "PyException_GetTraceback", + "PyException_SetArgs", "PyException_SetCause", "PyException_SetContext", "PyException_SetTraceback", @@ -524,6 +528,7 @@ SYMBOL_NAMES = ( "PyObject_GetBuffer", "PyObject_GetItem", "PyObject_GetIter", + "PyObject_GetTypeData", "PyObject_HasAttr", "PyObject_HasAttrString", "PyObject_Hash", @@ -547,6 +552,8 @@ SYMBOL_NAMES = ( "PyObject_Size", "PyObject_Str", "PyObject_Type", + "PyObject_Vectorcall", + "PyObject_VectorcallMethod", "PyProperty_Type", "PyRangeIter_Type", "PyRange_Type", @@ -660,6 +667,7 @@ SYMBOL_NAMES = ( "PyTuple_Size", "PyTuple_Type", "PyType_ClearCache", + "PyType_FromMetaclass", "PyType_FromModuleAndSpec", "PyType_FromSpec", "PyType_FromSpecWithBases", @@ -671,6 +679,7 @@ SYMBOL_NAMES = ( "PyType_GetName", "PyType_GetQualName", "PyType_GetSlot", + "PyType_GetTypeDataSize", "PyType_IsSubtype", "PyType_Modified", "PyType_Ready", @@ -781,6 +790,8 @@ SYMBOL_NAMES = ( "PyUnicode_Translate", "PyUnicode_Type", "PyUnicode_WriteChar", + "PyVectorcall_Call", + "PyVectorcall_NARGS", "PyWeakref_GetObject", "PyWeakref_NewProxy", "PyWeakref_NewRef", diff --git a/Lib/test/test_statistics.py b/Lib/test/test_statistics.py index 3e172e97..0080d996 100644 --- a/Lib/test/test_statistics.py +++ b/Lib/test/test_statistics.py @@ -1,4 +1,4 @@ -"""Test suite for statistics module, including helper NumericTestCase and +x = """Test suite for statistics module, including helper NumericTestCase and approx_equal function. """ @@ -2139,6 +2139,7 @@ class TestSqrtHelpers(unittest.TestCase): self.assertTrue(m * (r - 1)**2 < n < m * (r + 1)**2) @requires_IEEE_754 + @support.requires_resource('cpu') def test_float_sqrt_of_frac(self): def is_root_correctly_rounded(x: Fraction, root: float) -> bool: @@ -2565,6 +2566,22 @@ class TestCorrelationAndCovariance(unittest.TestCase): self.assertAlmostEqual(statistics.covariance(x, y), 0.1) + def test_correlation_spearman(self): + # https://statistics.laerd.com/statistical-guides/spearmans-rank-order-correlation-statistical-guide-2.php + # Compare with: + # >>> import scipy.stats.mstats + # >>> scipy.stats.mstats.spearmanr(reading, mathematics) + # SpearmanrResult(correlation=0.6686960980480712, pvalue=0.03450954165178532) + # And Wolfram Alpha gives: 0.668696 + # https://www.wolframalpha.com/input?i=SpearmanRho%5B%7B56%2C+75%2C+45%2C+71%2C+61%2C+64%2C+58%2C+80%2C+76%2C+61%7D%2C+%7B66%2C+70%2C+40%2C+60%2C+65%2C+56%2C+59%2C+77%2C+67%2C+63%7D%5D + reading = [56, 75, 45, 71, 61, 64, 58, 80, 76, 61] + mathematics = [66, 70, 40, 60, 65, 56, 59, 77, 67, 63] + self.assertAlmostEqual(statistics.correlation(reading, mathematics, method='ranked'), + 0.6686960980480712) + + with self.assertRaises(ValueError): + statistics.correlation(reading, mathematics, method='bad_method') + class TestLinearRegression(unittest.TestCase): def test_constant_input_error(self): @@ -2594,6 +2611,16 @@ class TestLinearRegression(unittest.TestCase): self.assertAlmostEqual(slope, 20 + 1/150) self.assertEqual(intercept, 0.0) + def test_float_output(self): + x = [Fraction(2, 3), Fraction(3, 4)] + y = [Fraction(4, 5), Fraction(5, 6)] + slope, intercept = statistics.linear_regression(x, y) + self.assertTrue(isinstance(slope, float)) + self.assertTrue(isinstance(intercept, float)) + slope, intercept = statistics.linear_regression(x, y, proportional=True) + self.assertTrue(isinstance(slope, float)) + self.assertTrue(isinstance(intercept, float)) + class TestNormalDist: # General note on precision: The pdf(), cdf(), and overlap() methods @@ -2744,6 +2771,7 @@ class TestNormalDist: self.assertTrue(math.isnan(X.cdf(float('NaN')))) @support.skip_if_pgo_task + @support.requires_resource('cpu') def test_inv_cdf(self): NormalDist = self.module.NormalDist @@ -2801,9 +2829,10 @@ class TestNormalDist: iq.inv_cdf(1.0) # p is one with self.assertRaises(self.module.StatisticsError): iq.inv_cdf(1.1) # p over one - with self.assertRaises(self.module.StatisticsError): - iq = NormalDist(100, 0) # sigma is zero - iq.inv_cdf(0.5) + + # Supported case: + iq = NormalDist(100, 0) # sigma is zero + self.assertEqual(iq.inv_cdf(0.5), 100) # Special values self.assertTrue(math.isnan(Z.inv_cdf(float('NaN')))) diff --git a/Lib/test/test_strftime.py b/Lib/test/test_strftime.py index be43c49e..cebfc892 100644 --- a/Lib/test/test_strftime.py +++ b/Lib/test/test_strftime.py @@ -54,14 +54,10 @@ class StrftimeTest(unittest.TestCase): self.now = now def setUp(self): - try: - import java - java.util.Locale.setDefault(java.util.Locale.US) - except ImportError: - from locale import setlocale, LC_TIME - saved_locale = setlocale(LC_TIME) - setlocale(LC_TIME, 'C') - self.addCleanup(setlocale, LC_TIME, saved_locale) + 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() diff --git a/Lib/test/test_string_literals.py b/Lib/test/test_string_literals.py index 7247b7e4..9b663c00 100644 --- a/Lib/test/test_string_literals.py +++ b/Lib/test/test_string_literals.py @@ -109,11 +109,11 @@ class TestLiterals(unittest.TestCase): for b in range(1, 128): if b in b"""\n\r"'01234567NU\\abfnrtuvx""": continue - with self.assertWarns(DeprecationWarning): + with self.assertWarns(SyntaxWarning): self.assertEqual(eval(r"'\%c'" % b), '\\' + chr(b)) with warnings.catch_warnings(record=True) as w: - warnings.simplefilter('always', category=DeprecationWarning) + warnings.simplefilter('always', category=SyntaxWarning) eval("'''\n\\z'''") self.assertEqual(len(w), 1) self.assertEqual(str(w[0].message), r"invalid escape sequence '\z'") @@ -121,7 +121,7 @@ class TestLiterals(unittest.TestCase): self.assertEqual(w[0].lineno, 1) with warnings.catch_warnings(record=True) as w: - warnings.simplefilter('error', category=DeprecationWarning) + warnings.simplefilter('error', category=SyntaxWarning) with self.assertRaises(SyntaxError) as cm: eval("'''\n\\z'''") exc = cm.exception @@ -133,11 +133,11 @@ class TestLiterals(unittest.TestCase): def test_eval_str_invalid_octal_escape(self): for i in range(0o400, 0o1000): - with self.assertWarns(DeprecationWarning): + with self.assertWarns(SyntaxWarning): self.assertEqual(eval(r"'\%o'" % i), chr(i)) with warnings.catch_warnings(record=True) as w: - warnings.simplefilter('always', category=DeprecationWarning) + warnings.simplefilter('always', category=SyntaxWarning) eval("'''\n\\407'''") self.assertEqual(len(w), 1) self.assertEqual(str(w[0].message), @@ -146,7 +146,7 @@ class TestLiterals(unittest.TestCase): self.assertEqual(w[0].lineno, 1) with warnings.catch_warnings(record=True) as w: - warnings.simplefilter('error', category=DeprecationWarning) + warnings.simplefilter('error', category=SyntaxWarning) with self.assertRaises(SyntaxError) as cm: eval("'''\n\\407'''") exc = cm.exception @@ -186,11 +186,11 @@ class TestLiterals(unittest.TestCase): for b in range(1, 128): if b in b"""\n\r"'01234567\\abfnrtvx""": continue - with self.assertWarns(DeprecationWarning): + with self.assertWarns(SyntaxWarning): self.assertEqual(eval(r"b'\%c'" % b), b'\\' + bytes([b])) with warnings.catch_warnings(record=True) as w: - warnings.simplefilter('always', category=DeprecationWarning) + warnings.simplefilter('always', category=SyntaxWarning) eval("b'''\n\\z'''") self.assertEqual(len(w), 1) self.assertEqual(str(w[0].message), r"invalid escape sequence '\z'") @@ -198,7 +198,7 @@ class TestLiterals(unittest.TestCase): self.assertEqual(w[0].lineno, 1) with warnings.catch_warnings(record=True) as w: - warnings.simplefilter('error', category=DeprecationWarning) + warnings.simplefilter('error', category=SyntaxWarning) with self.assertRaises(SyntaxError) as cm: eval("b'''\n\\z'''") exc = cm.exception @@ -209,11 +209,11 @@ class TestLiterals(unittest.TestCase): def test_eval_bytes_invalid_octal_escape(self): for i in range(0o400, 0o1000): - with self.assertWarns(DeprecationWarning): + with self.assertWarns(SyntaxWarning): self.assertEqual(eval(r"b'\%o'" % i), bytes([i & 0o377])) with warnings.catch_warnings(record=True) as w: - warnings.simplefilter('always', category=DeprecationWarning) + warnings.simplefilter('always', category=SyntaxWarning) eval("b'''\n\\407'''") self.assertEqual(len(w), 1) self.assertEqual(str(w[0].message), @@ -222,7 +222,7 @@ class TestLiterals(unittest.TestCase): self.assertEqual(w[0].lineno, 1) with warnings.catch_warnings(record=True) as w: - warnings.simplefilter('error', category=DeprecationWarning) + warnings.simplefilter('error', category=SyntaxWarning) with self.assertRaises(SyntaxError) as cm: eval("b'''\n\\407'''") exc = cm.exception diff --git a/Lib/test/test_strptime.py b/Lib/test/test_strptime.py index e3fcabef..810c5a36 100644 --- a/Lib/test/test_strptime.py +++ b/Lib/test/test_strptime.py @@ -242,6 +242,16 @@ class StrptimeTests(unittest.TestCase): # 5. Julian/ordinal day (%j) is specified with %G, but not %Y with self.assertRaises(ValueError): _strptime._strptime("1999 256", "%G %j") + # 6. Invalid ISO weeks + invalid_iso_weeks = [ + "2019-00-1", + "2019-54-1", + "2021-53-1", + ] + for invalid_iso_dtstr in invalid_iso_weeks: + with self.subTest(invalid_iso_dtstr): + with self.assertRaises(ValueError): + _strptime._strptime(invalid_iso_dtstr, "%G-%V-%u") def test_strptime_exception_context(self): diff --git a/Lib/test/test_struct.py b/Lib/test/test_struct.py index ab738770..6b1f22f6 100644 --- a/Lib/test/test_struct.py +++ b/Lib/test/test_struct.py @@ -700,6 +700,20 @@ class StructTest(unittest.TestCase): with self.assertRaises(TypeError): cls.x = 1 + @support.cpython_only + def test__struct_Struct__new__initialized(self): + # See https://github.com/python/cpython/issues/78724 + + s = struct.Struct.__new__(struct.Struct, "b") + s.unpack_from(b"abcd") + + @support.cpython_only + def test__struct_Struct_subclassing(self): + class Bob(struct.Struct): + pass + + s = Bob("b") + s.unpack_from(b"abcd") def test_issue35714(self): # Embedded null characters should not be allowed in format strings. @@ -709,23 +723,56 @@ class StructTest(unittest.TestCase): struct.calcsize(s) @support.cpython_only - def test_issue45034_unsigned(self): - _testcapi = import_helper.import_module('_testcapi') - error_msg = f'ushort format requires 0 <= number <= {_testcapi.USHRT_MAX}' - with self.assertRaisesRegex(struct.error, error_msg): - struct.pack('H', 70000) # too large - with self.assertRaisesRegex(struct.error, error_msg): - struct.pack('H', -1) # too small + def test_issue98248(self): + def test_error_msg(prefix, int_type, is_unsigned): + fmt_str = prefix + int_type + size = struct.calcsize(fmt_str) + if is_unsigned: + max_ = 2 ** (size * 8) - 1 + min_ = 0 + else: + max_ = 2 ** (size * 8 - 1) - 1 + min_ = -2 ** (size * 8 - 1) + error_msg = f"'{int_type}' format requires {min_} <= number <= {max_}" + for number in [int(-1e50), min_ - 1, max_ + 1, int(1e50)]: + with self.subTest(format_str=fmt_str, number=number): + with self.assertRaisesRegex(struct.error, error_msg): + struct.pack(fmt_str, number) + error_msg = "required argument is not an integer" + not_number = "" + with self.subTest(format_str=fmt_str, number=not_number): + with self.assertRaisesRegex(struct.error, error_msg): + struct.pack(fmt_str, not_number) + + for prefix in '@=<>': + for int_type in 'BHILQ': + test_error_msg(prefix, int_type, True) + for int_type in 'bhilq': + test_error_msg(prefix, int_type, False) + + int_type = 'N' + test_error_msg('@', int_type, True) + + int_type = 'n' + test_error_msg('@', int_type, False) @support.cpython_only - def test_issue45034_signed(self): - _testcapi = import_helper.import_module('_testcapi') - error_msg = f'short format requires {_testcapi.SHRT_MIN} <= number <= {_testcapi.SHRT_MAX}' - with self.assertRaisesRegex(struct.error, error_msg): - struct.pack('h', 70000) # too large - with self.assertRaisesRegex(struct.error, error_msg): - struct.pack('h', -70000) # too small - + def test_issue98248_error_propagation(self): + class Div0: + def __index__(self): + 1 / 0 + + def test_error_propagation(fmt_str): + with self.subTest(format_str=fmt_str, exception="ZeroDivisionError"): + with self.assertRaises(ZeroDivisionError): + struct.pack(fmt_str, Div0()) + + for prefix in '@=<>': + for int_type in 'BHILQbhilq': + test_error_propagation(prefix + int_type) + + test_error_propagation('N') + test_error_propagation('n') class UnpackIteratorTest(unittest.TestCase): """ diff --git a/Lib/test/test_subclassinit.py b/Lib/test/test_subclassinit.py index 0ad7d17f..310473a4 100644 --- a/Lib/test/test_subclassinit.py +++ b/Lib/test/test_subclassinit.py @@ -134,30 +134,28 @@ class Test(unittest.TestCase): def __set_name__(self, owner, name): 1/0 - with self.assertRaises(RuntimeError) as cm: + with self.assertRaises(ZeroDivisionError) as cm: class NotGoingToWork: attr = Descriptor() - exc = cm.exception - self.assertRegex(str(exc), r'\bNotGoingToWork\b') - self.assertRegex(str(exc), r'\battr\b') - self.assertRegex(str(exc), r'\bDescriptor\b') - self.assertIsInstance(exc.__cause__, ZeroDivisionError) + notes = cm.exception.__notes__ + self.assertRegex(str(notes), r'\bNotGoingToWork\b') + self.assertRegex(str(notes), r'\battr\b') + self.assertRegex(str(notes), r'\bDescriptor\b') def test_set_name_wrong(self): class Descriptor: def __set_name__(self): pass - with self.assertRaises(RuntimeError) as cm: + with self.assertRaises(TypeError) as cm: class NotGoingToWork: attr = Descriptor() - exc = cm.exception - self.assertRegex(str(exc), r'\bNotGoingToWork\b') - self.assertRegex(str(exc), r'\battr\b') - self.assertRegex(str(exc), r'\bDescriptor\b') - self.assertIsInstance(exc.__cause__, TypeError) + notes = cm.exception.__notes__ + self.assertRegex(str(notes), r'\bNotGoingToWork\b') + self.assertRegex(str(notes), r'\battr\b') + self.assertRegex(str(notes), r'\bDescriptor\b') def test_set_name_lookup(self): resolved = [] diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py index abd0dd8b..d95ef72b 100644 --- a/Lib/test/test_subprocess.py +++ b/Lib/test/test_subprocess.py @@ -1,9 +1,11 @@ import unittest from unittest import mock from test import support +from test.support import check_sanitizer from test.support import import_helper from test.support import os_helper from test.support import warnings_helper +from test.support.script_helper import assert_python_ok import subprocess import sys import signal @@ -267,6 +269,7 @@ class ProcessTestCase(BaseTestCase): self.assertIn('stdin', c.exception.args[0]) self.assertIn('input', c.exception.args[0]) + @support.requires_resource('walltime') def test_check_output_timeout(self): # check_output() function with timeout arg with self.assertRaises(subprocess.TimeoutExpired) as c: @@ -717,8 +720,9 @@ class ProcessTestCase(BaseTestCase): os.close(test_pipe_r) os.close(test_pipe_w) pipesize = pipesize_default // 2 - if pipesize < 512: # the POSIX minimum - raise unittest.SkitTest( + pagesize_default = support.get_pagesize() + if pipesize < pagesize_default: # the POSIX minimum + raise unittest.SkipTest( 'default pipesize too small to perform test.') p = subprocess.Popen( [sys.executable, "-c", @@ -789,6 +793,8 @@ class ProcessTestCase(BaseTestCase): @unittest.skipIf(sysconfig.get_config_var('Py_ENABLE_SHARED') == 1, 'The Python shared library cannot be loaded ' 'with an empty environment.') + @unittest.skipIf(check_sanitizer(address=True), + 'AddressSanitizer adds to the environment.') def test_empty_env(self): """Verify that env={} is as empty as possible.""" @@ -1287,6 +1293,7 @@ class ProcessTestCase(BaseTestCase): with self.assertWarnsRegex(RuntimeWarning, 'line buffering'): self._test_bufsize_equal_one(line, b'', universal_newlines=False) + @support.requires_resource('cpu') def test_leaking_fds_on_error(self): # see bug #5179: Popen leaks file descriptors to PIPEs if # the child fails to execute; this will eventually exhaust @@ -1637,6 +1644,7 @@ class RunFuncTestCase(BaseTestCase): self.assertIn('stdin', c.exception.args[0]) self.assertIn('input', c.exception.args[0]) + @support.requires_resource('walltime') def test_check_output_timeout(self): with self.assertRaises(subprocess.TimeoutExpired) as c: cp = self.run_python(( @@ -1687,6 +1695,14 @@ class RunFuncTestCase(BaseTestCase): res = subprocess.run(args) self.assertEqual(res.returncode, 57) + @unittest.skipUnless(mswindows, "Maybe test trigger a leak on Ubuntu") + def test_run_with_an_empty_env(self): + # gh-105436: fix subprocess.run(..., env={}) broken on Windows + args = [sys.executable, "-c", 'pass'] + # Ignore subprocess errors - we only care that the API doesn't + # raise an OSError + subprocess.run(args, env={}) + def test_capture_output(self): cp = self.run_python(("import sys;" "sys.stdout.write('BDFL'); " @@ -3325,6 +3341,24 @@ class POSIXProcessTestCase(BaseTestCase): except subprocess.TimeoutExpired: pass + def test_preexec_at_exit(self): + code = f"""if 1: + import atexit + import subprocess + + def dummy(): + pass + + def exit_handler(): + subprocess.Popen({ZERO_RETURN_CMD}, preexec_fn=dummy) + print("shouldn't be printed") + + atexit.register(exit_handler) + """ + _, out, err = assert_python_ok("-c", code) + self.assertEqual(out, b'') + self.assertIn(b"preexec_fn not supported at interpreter shutdown", err) + @unittest.skipUnless(mswindows, "Windows specific tests") class Win32ProcessTestCase(BaseTestCase): diff --git a/Lib/test/test_sundry.py b/Lib/test/test_sundry.py index de2e7305..f4a8d434 100644 --- a/Lib/test/test_sundry.py +++ b/Lib/test/test_sundry.py @@ -18,29 +18,6 @@ class TestUntestedModules(unittest.TestCase): self.fail('{} has tests even though test_sundry claims ' 'otherwise'.format(name)) - import distutils.bcppcompiler - import distutils.ccompiler - import distutils.cygwinccompiler - import distutils.filelist - import distutils.text_file - import distutils.unixccompiler - - import distutils.command.bdist_dumb - import distutils.command.bdist - import distutils.command.bdist_rpm - import distutils.command.build_clib - import distutils.command.build_ext - import distutils.command.build - import distutils.command.clean - import distutils.command.config - import distutils.command.install_data - import distutils.command.install_egg_info - import distutils.command.install_headers - import distutils.command.install_lib - import distutils.command.register - import distutils.command.sdist - import distutils.command.upload - import html.entities try: diff --git a/Lib/test/test_super.py b/Lib/test/test_super.py index a68b38cf..43162c54 100644 --- a/Lib/test/test_super.py +++ b/Lib/test/test_super.py @@ -1,6 +1,11 @@ """Unit tests for zero-argument super() & related machinery.""" import unittest +from unittest.mock import patch +from test import shadowed_super + + +ADAPTIVE_WARMUP_DELAY = 2 class A: @@ -283,17 +288,28 @@ class TestSuper(unittest.TestCase): def test_obscure_super_errors(self): def f(): super() - self.assertRaises(RuntimeError, f) + with self.assertRaisesRegex(RuntimeError, r"no arguments"): + f() + + class C: + def f(): + super() + with self.assertRaisesRegex(RuntimeError, r"no arguments"): + C.f() + def f(x): del x super() - self.assertRaises(RuntimeError, f, None) + with self.assertRaisesRegex(RuntimeError, r"arg\[0\] deleted"): + f(None) + class X: def f(x): nonlocal __class__ del __class__ super() - self.assertRaises(RuntimeError, X().f) + with self.assertRaisesRegex(RuntimeError, r"empty __class__ cell"): + X().f() def test_cell_as_self(self): class X: @@ -325,6 +341,129 @@ class TestSuper(unittest.TestCase): with self.assertRaisesRegex(TypeError, "argument 1 must be a type"): super(1, int) + def test_shadowed_global(self): + self.assertEqual(shadowed_super.C().method(), "truly super") + + def test_shadowed_local(self): + class super: + msg = "quite super" + + class C: + def method(self): + return super().msg + + self.assertEqual(C().method(), "quite super") + + def test_shadowed_dynamic(self): + class MySuper: + msg = "super super" + + class C: + def method(self): + return super().msg + + with patch(f"{__name__}.super", MySuper) as m: + self.assertEqual(C().method(), "super super") + + def test_shadowed_dynamic_two_arg(self): + call_args = [] + class MySuper: + def __init__(self, *args): + call_args.append(args) + msg = "super super" + + class C: + def method(self): + return super(1, 2).msg + + with patch(f"{__name__}.super", MySuper) as m: + self.assertEqual(C().method(), "super super") + self.assertEqual(call_args, [(1, 2)]) + + def test_attribute_error(self): + class C: + def method(self): + return super().msg + + with self.assertRaisesRegex(AttributeError, "'super' object has no attribute 'msg'"): + C().method() + + def test_bad_first_arg(self): + class C: + def method(self): + return super(1, self).method() + + with self.assertRaisesRegex(TypeError, "argument 1 must be a type"): + C().method() + + def test_super___class__(self): + class C: + def method(self): + return super().__class__ + + self.assertEqual(C().method(), super) + + def test_super_subclass___class__(self): + class mysuper(super): + pass + + class C: + def method(self): + return mysuper(C, self).__class__ + + self.assertEqual(C().method(), mysuper) + + def test_unusual_getattro(self): + class MyType(type): + pass + + def test(name): + mytype = MyType(name, (MyType,), {}) + super(MyType, type(mytype)).__setattr__(mytype, "bar", 1) + self.assertEqual(mytype.bar, 1) + + for _ in range(ADAPTIVE_WARMUP_DELAY): + test("foo1") + + def test_reassigned_new(self): + class A: + def __new__(cls): + pass + + def __init_subclass__(cls): + if "__new__" not in cls.__dict__: + cls.__new__ = cls.__new__ + + class B(A): + pass + + class C(B): + def __new__(cls): + return super().__new__(cls) + + for _ in range(ADAPTIVE_WARMUP_DELAY): + C() + + def test_mixed_staticmethod_hierarchy(self): + # This test is just a desugared version of `test_reassigned_new` + class A: + @staticmethod + def some(cls, *args, **kwargs): + self.assertFalse(args) + self.assertFalse(kwargs) + + class B(A): + def some(cls, *args, **kwargs): + return super().some(cls, *args, **kwargs) + + class C(B): + @staticmethod + def some(cls): + return super().some(cls) + + for _ in range(ADAPTIVE_WARMUP_DELAY): + C.some(C) + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_support.py b/Lib/test/test_support.py index 23bcceed..4047e0bd 100644 --- a/Lib/test/test_support.py +++ b/Lib/test/test_support.py @@ -9,7 +9,6 @@ import subprocess import sys import tempfile import textwrap -import time import unittest import warnings @@ -31,7 +30,7 @@ class TestSupport(unittest.TestCase): "test.support.warnings_helper", like=".*used in test_support.*" ) cls._test_support_token = support.ignore_deprecations_from( - "test.test_support", like=".*You should NOT be seeing this.*" + __name__, like=".*You should NOT be seeing this.*" ) assert len(warnings.filters) == orig_filter_len + 2 @@ -461,18 +460,12 @@ class TestSupport(unittest.TestCase): # child process: do nothing, just exit os._exit(0) - t0 = time.monotonic() - deadline = time.monotonic() + support.SHORT_TIMEOUT - was_altered = support.environment_altered try: support.environment_altered = False stderr = io.StringIO() - while True: - if time.monotonic() > deadline: - self.fail("timeout") - + for _ in support.sleeping_retry(support.SHORT_TIMEOUT): with support.swap_attr(support.print_warning, 'orig_stderr', stderr): support.reap_children() @@ -481,9 +474,6 @@ class TestSupport(unittest.TestCase): if support.environment_altered: break - # loop until the child process completed - time.sleep(0.100) - msg = "Warning -- reap_children() reaped child process %s" % pid self.assertIn(msg, stderr.getvalue()) self.assertTrue(support.environment_altered) @@ -510,6 +500,7 @@ class TestSupport(unittest.TestCase): self.assertEqual(proc.stdout.rstrip(), repr(expected)) self.assertEqual(proc.returncode, 0) + @support.requires_resource('cpu') def test_args_from_interpreter_flags(self): # Test test.support.args_from_interpreter_flags() for opts in ( @@ -697,6 +688,83 @@ class TestSupport(unittest.TestCase): else: self.assertTrue(support.has_strftime_extensions) + def test_get_recursion_depth(self): + # test support.get_recursion_depth() + code = textwrap.dedent(""" + from test import support + import sys + + def check(cond): + if not cond: + raise AssertionError("test failed") + + # depth 1 + check(support.get_recursion_depth() == 1) + + # depth 2 + def test_func(): + check(support.get_recursion_depth() == 2) + test_func() + + def test_recursive(depth, limit): + if depth >= limit: + # cannot call get_recursion_depth() at this depth, + # it can raise RecursionError + return + get_depth = support.get_recursion_depth() + print(f"test_recursive: {depth}/{limit}: " + f"get_recursion_depth() says {get_depth}") + check(get_depth == depth) + test_recursive(depth + 1, limit) + + # depth up to 25 + with support.infinite_recursion(max_depth=25): + limit = sys.getrecursionlimit() + print(f"test with sys.getrecursionlimit()={limit}") + test_recursive(2, limit) + + # depth up to 500 + with support.infinite_recursion(max_depth=500): + limit = sys.getrecursionlimit() + print(f"test with sys.getrecursionlimit()={limit}") + test_recursive(2, limit) + """) + script_helper.assert_python_ok("-c", code) + + def test_recursion(self): + # Test infinite_recursion() and get_recursion_available() functions. + def recursive_function(depth): + if depth: + recursive_function(depth - 1) + + for max_depth in (5, 25, 250): + with support.infinite_recursion(max_depth): + available = support.get_recursion_available() + + # Recursion up to 'available' additional frames should be OK. + recursive_function(available) + + # Recursion up to 'available+1' additional frames must raise + # RecursionError. Avoid self.assertRaises(RecursionError) which + # can consume more than 3 frames and so raises RecursionError. + try: + recursive_function(available + 1) + except RecursionError: + pass + else: + self.fail("RecursionError was not raised") + + # Test the bare minimumum: max_depth=3 + with support.infinite_recursion(3): + try: + recursive_function(3) + except RecursionError: + pass + else: + self.fail("RecursionError was not raised") + + #self.assertEqual(available, 2) + # XXX -follows a list of untested API # make_legacy_pyc # is_resource_enabled diff --git a/Lib/test/test_symtable.py b/Lib/test/test_symtable.py index 819354e4..61fda767 100644 --- a/Lib/test/test_symtable.py +++ b/Lib/test/test_symtable.py @@ -40,6 +40,15 @@ def foo(): def namespace_test(): pass def namespace_test(): pass + +type Alias = int +type GenericAlias[T] = list[T] + +def generic_spam[T](a): + pass + +class GenericMine[T: int]: + pass """ @@ -59,6 +68,14 @@ class SymtableTest(unittest.TestCase): internal = find_block(spam, "internal") other_internal = find_block(spam, "other_internal") foo = find_block(top, "foo") + Alias = find_block(top, "Alias") + GenericAlias = find_block(top, "GenericAlias") + GenericAlias_inner = find_block(GenericAlias, "GenericAlias") + generic_spam = find_block(top, "generic_spam") + generic_spam_inner = find_block(generic_spam, "generic_spam") + GenericMine = find_block(top, "GenericMine") + GenericMine_inner = find_block(GenericMine, "GenericMine") + T = find_block(GenericMine, "T") def test_type(self): self.assertEqual(self.top.get_type(), "module") @@ -66,6 +83,15 @@ class SymtableTest(unittest.TestCase): self.assertEqual(self.a_method.get_type(), "function") self.assertEqual(self.spam.get_type(), "function") self.assertEqual(self.internal.get_type(), "function") + self.assertEqual(self.foo.get_type(), "function") + self.assertEqual(self.Alias.get_type(), "type alias") + self.assertEqual(self.GenericAlias.get_type(), "type parameter") + self.assertEqual(self.GenericAlias_inner.get_type(), "type alias") + self.assertEqual(self.generic_spam.get_type(), "type parameter") + self.assertEqual(self.generic_spam_inner.get_type(), "function") + self.assertEqual(self.GenericMine.get_type(), "type parameter") + self.assertEqual(self.GenericMine_inner.get_type(), "class") + self.assertEqual(self.T.get_type(), "TypeVar bound") def test_id(self): self.assertGreater(self.top.get_id(), 0) @@ -73,6 +99,11 @@ class SymtableTest(unittest.TestCase): self.assertGreater(self.a_method.get_id(), 0) self.assertGreater(self.spam.get_id(), 0) self.assertGreater(self.internal.get_id(), 0) + self.assertGreater(self.foo.get_id(), 0) + self.assertGreater(self.Alias.get_id(), 0) + self.assertGreater(self.GenericAlias.get_id(), 0) + self.assertGreater(self.generic_spam.get_id(), 0) + self.assertGreater(self.GenericMine.get_id(), 0) def test_optimized(self): self.assertFalse(self.top.is_optimized()) @@ -222,10 +253,9 @@ class SymtableTest(unittest.TestCase): checkfilename("def f(x): foo)(", 14) # parse-time checkfilename("def f(x): global x", 11) # symtable-build-time symtable.symtable("pass", b"spam", "exec") - with self.assertWarns(DeprecationWarning), \ - self.assertRaises(TypeError): + with self.assertRaises(TypeError): symtable.symtable("pass", bytearray(b"spam"), "exec") - with self.assertWarns(DeprecationWarning): + with self.assertRaises(TypeError): symtable.symtable("pass", memoryview(b"spam"), "exec") with self.assertRaises(TypeError): symtable.symtable("pass", list(b"spam"), "exec") diff --git a/Lib/test/test_syntax.py b/Lib/test/test_syntax.py index 50168d92..4c988382 100644 --- a/Lib/test/test_syntax.py +++ b/Lib/test/test_syntax.py @@ -334,7 +334,12 @@ From ast_for_arguments(): >>> def f(x, y=1, z): ... pass Traceback (most recent call last): -SyntaxError: non-default argument follows default argument +SyntaxError: parameter without a default follows parameter with a default + +>>> def f(x, /, y=1, z): +... pass +Traceback (most recent call last): +SyntaxError: parameter without a default follows parameter with a default >>> def f(x, None): ... pass @@ -555,6 +560,14 @@ SyntaxError: expected default value expression Traceback (most recent call last): SyntaxError: expected default value expression +>>> lambda a,d=3,c: None +Traceback (most recent call last): +SyntaxError: parameter without a default follows parameter with a default + +>>> lambda a,/,d=3,c: None +Traceback (most recent call last): +SyntaxError: parameter without a default follows parameter with a default + >>> import ast; ast.parse(''' ... def f( ... *, # type: int @@ -743,6 +756,27 @@ SyntaxError: cannot assign to __debug__ >>> __debug__: int Traceback (most recent call last): SyntaxError: cannot assign to __debug__ +>>> f(a=) +Traceback (most recent call last): +SyntaxError: expected argument value expression +>>> f(a, b, c=) +Traceback (most recent call last): +SyntaxError: expected argument value expression +>>> f(a, b, c=, d) +Traceback (most recent call last): +SyntaxError: expected argument value expression +>>> f(*args=[0]) +Traceback (most recent call last): +SyntaxError: cannot assign to iterable argument unpacking +>>> f(a, b, *args=[0]) +Traceback (most recent call last): +SyntaxError: cannot assign to iterable argument unpacking +>>> f(**kwargs={'a': 1}) +Traceback (most recent call last): +SyntaxError: cannot assign to keyword argument unpacking +>>> f(a, b, *args, **kwargs={'a': 1}) +Traceback (most recent call last): +SyntaxError: cannot assign to keyword argument unpacking More set_context(): @@ -1571,6 +1605,38 @@ SyntaxError: trailing comma not allowed without surrounding parentheses Traceback (most recent call last): SyntaxError: trailing comma not allowed without surrounding parentheses +>>> import a from b +Traceback (most recent call last): +SyntaxError: Did you mean to use 'from ... import ...' instead? + +>>> import a.y.z from b.y.z +Traceback (most recent call last): +SyntaxError: Did you mean to use 'from ... import ...' instead? + +>>> import a from b as bar +Traceback (most recent call last): +SyntaxError: Did you mean to use 'from ... import ...' instead? + +>>> import a.y.z from b.y.z as bar +Traceback (most recent call last): +SyntaxError: Did you mean to use 'from ... import ...' instead? + +>>> import a, b,c from b +Traceback (most recent call last): +SyntaxError: Did you mean to use 'from ... import ...' instead? + +>>> import a.y.z, b.y.z, c.y.z from b.y.z +Traceback (most recent call last): +SyntaxError: Did you mean to use 'from ... import ...' instead? + +>>> import a,b,c from b as bar +Traceback (most recent call last): +SyntaxError: Did you mean to use 'from ... import ...' instead? + +>>> import a.y.z, b.y.z, c.y.z from b.y.z as bar +Traceback (most recent call last): +SyntaxError: Did you mean to use 'from ... import ...' instead? + # Check that we dont raise the "trailing comma" error if there is more # input to the left of the valid part that we parsed. @@ -1803,6 +1869,92 @@ x: *b Traceback (most recent call last): ... SyntaxError: invalid syntax + +Invalid bytes literals: + + >>> b"Ā" + Traceback (most recent call last): + ... + b"Ā" + ^^^ + SyntaxError: bytes can only contain ASCII literal characters + + >>> b"абвгде" + Traceback (most recent call last): + ... + b"абвгде" + ^^^^^^^^ + SyntaxError: bytes can only contain ASCII literal characters + + >>> b"abc ъющый" # first 3 letters are ascii + Traceback (most recent call last): + ... + b"abc ъющый" + ^^^^^^^^^^^ + SyntaxError: bytes can only contain ASCII literal characters + +Invalid expressions in type scopes: + + >>> type A[T: (x:=3)] = int + Traceback (most recent call last): + ... + SyntaxError: named expression cannot be used within a TypeVar bound + + >>> type A[T: (yield 3)] = int + Traceback (most recent call last): + ... + SyntaxError: yield expression cannot be used within a TypeVar bound + + >>> type A[T: (await 3)] = int + Traceback (most recent call last): + ... + SyntaxError: await expression cannot be used within a TypeVar bound + + >>> type A[T: (yield from [])] = int + Traceback (most recent call last): + ... + SyntaxError: yield expression cannot be used within a TypeVar bound + + >>> type A = (x := 3) + Traceback (most recent call last): + ... + SyntaxError: named expression cannot be used within a type alias + + >>> type A = (yield 3) + Traceback (most recent call last): + ... + SyntaxError: yield expression cannot be used within a type alias + + >>> type A = (await 3) + Traceback (most recent call last): + ... + SyntaxError: await expression cannot be used within a type alias + + >>> type A = (yield from []) + Traceback (most recent call last): + ... + SyntaxError: yield expression cannot be used within a type alias + + >>> class A[T]((x := 3)): ... + Traceback (most recent call last): + ... + SyntaxError: named expression cannot be used within the definition of a generic + + >>> class A[T]((yield 3)): ... + Traceback (most recent call last): + ... + SyntaxError: yield expression cannot be used within the definition of a generic + + >>> class A[T]((await 3)): ... + Traceback (most recent call last): + ... + SyntaxError: await expression cannot be used within the definition of a generic + + >>> class A[T]((yield from [])): ... + Traceback (most recent call last): + ... + SyntaxError: yield expression cannot be used within the definition of a generic + """ import re @@ -2183,7 +2335,7 @@ while 1: source = "-" * 100000 + "4" for mode in ["exec", "eval", "single"]: with self.subTest(mode=mode): - with self.assertRaises(MemoryError): + with self.assertRaisesRegex(MemoryError, r"too complex"): compile(source, "<string>", mode) @support.cpython_only diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py index 6f56c9ef..c3e9f9c4 100644 --- a/Lib/test/test_sys.py +++ b/Lib/test/test_sys.py @@ -269,20 +269,29 @@ class SysModuleTest(unittest.TestCase): finally: sys.setswitchinterval(orig) - def test_recursionlimit(self): + def test_getrecursionlimit(self): + limit = sys.getrecursionlimit() + self.assertIsInstance(limit, int) + self.assertGreater(limit, 1) + self.assertRaises(TypeError, sys.getrecursionlimit, 42) - oldlimit = sys.getrecursionlimit() - self.assertRaises(TypeError, sys.setrecursionlimit) - self.assertRaises(ValueError, sys.setrecursionlimit, -42) - sys.setrecursionlimit(10000) - self.assertEqual(sys.getrecursionlimit(), 10000) - sys.setrecursionlimit(oldlimit) + + def test_setrecursionlimit(self): + old_limit = sys.getrecursionlimit() + try: + sys.setrecursionlimit(10_005) + self.assertEqual(sys.getrecursionlimit(), 10_005) + + self.assertRaises(TypeError, sys.setrecursionlimit) + self.assertRaises(ValueError, sys.setrecursionlimit, -42) + finally: + sys.setrecursionlimit(old_limit) def test_recursionlimit_recovery(self): if hasattr(sys, 'gettrace') and sys.gettrace(): self.skipTest('fatal error if run with a trace function') - oldlimit = sys.getrecursionlimit() + old_limit = sys.getrecursionlimit() def f(): f() try: @@ -301,35 +310,31 @@ class SysModuleTest(unittest.TestCase): with self.assertRaises(RecursionError): f() finally: - sys.setrecursionlimit(oldlimit) + sys.setrecursionlimit(old_limit) @test.support.cpython_only - def test_setrecursionlimit_recursion_depth(self): + def test_setrecursionlimit_to_depth(self): # Issue #25274: Setting a low recursion limit must be blocked if the # current recursion depth is already higher than limit. - from _testinternalcapi import get_recursion_depth - - def set_recursion_limit_at_depth(depth, limit): - recursion_depth = get_recursion_depth() - if recursion_depth >= depth: - with self.assertRaises(RecursionError) as cm: - sys.setrecursionlimit(limit) - self.assertRegex(str(cm.exception), - "cannot set the recursion limit to [0-9]+ " - "at the recursion depth [0-9]+: " - "the limit is too low") - else: - set_recursion_limit_at_depth(depth, limit) - - oldlimit = sys.getrecursionlimit() + old_limit = sys.getrecursionlimit() try: - sys.setrecursionlimit(1000) - - for limit in (10, 25, 50, 75, 100, 150, 200): - set_recursion_limit_at_depth(limit, limit) + depth = support.get_recursion_depth() + with self.subTest(limit=sys.getrecursionlimit(), depth=depth): + # depth + 1 is OK + sys.setrecursionlimit(depth + 1) + + # reset the limit to be able to call self.assertRaises() + # context manager + sys.setrecursionlimit(old_limit) + with self.assertRaises(RecursionError) as cm: + sys.setrecursionlimit(depth) + self.assertRegex(str(cm.exception), + "cannot set the recursion limit to [0-9]+ " + "at the recursion depth [0-9]+: " + "the limit is too low") finally: - sys.setrecursionlimit(oldlimit) + sys.setrecursionlimit(old_limit) def test_getwindowsversion(self): # Raise SkipTest if sys doesn't have getwindowsversion attribute @@ -385,7 +390,8 @@ class SysModuleTest(unittest.TestCase): self.assertRaises(TypeError, sys.getrefcount) c = sys.getrefcount(None) n = None - self.assertEqual(sys.getrefcount(None), c+1) + # Singleton refcnts don't change + self.assertEqual(sys.getrefcount(None), c) del n self.assertEqual(sys.getrefcount(None), c) if hasattr(sys, "gettotalrefcount"): @@ -399,6 +405,26 @@ class SysModuleTest(unittest.TestCase): is sys._getframe().f_code ) + def test_getframemodulename(self): + # Default depth gets ourselves + self.assertEqual(__name__, sys._getframemodulename()) + self.assertEqual("unittest.case", sys._getframemodulename(1)) + i = 0 + f = sys._getframe(i) + while f: + self.assertEqual( + f.f_globals['__name__'], + sys._getframemodulename(i) or '__main__' + ) + i += 1 + f2 = f.f_back + try: + f = sys._getframe(i) + except ValueError: + break + self.assertIs(f, f2) + self.assertIsNone(sys._getframemodulename(i)) + # sys._current_frames() is a CPython-only gimmick. @threading_helper.reap_threads @threading_helper.requires_working_threading() @@ -425,46 +451,47 @@ class SysModuleTest(unittest.TestCase): t.start() entered_g.wait() - # At this point, t has finished its entered_g.set(), although it's - # impossible to guess whether it's still on that line or has moved on - # to its leave_g.wait(). - self.assertEqual(len(thread_info), 1) - thread_id = thread_info[0] - - d = sys._current_frames() - for tid in d: - self.assertIsInstance(tid, int) - self.assertGreater(tid, 0) - - main_id = threading.get_ident() - self.assertIn(main_id, d) - self.assertIn(thread_id, d) - - # Verify that the captured main-thread frame is _this_ frame. - frame = d.pop(main_id) - self.assertTrue(frame is sys._getframe()) - - # Verify that the captured thread frame is blocked in g456, called - # from f123. This is a little tricky, since various bits of - # threading.py are also in the thread's call stack. - frame = d.pop(thread_id) - stack = traceback.extract_stack(frame) - for i, (filename, lineno, funcname, sourceline) in enumerate(stack): - if funcname == "f123": - break - else: - self.fail("didn't find f123() on thread's call stack") - - self.assertEqual(sourceline, "g456()") + try: + # At this point, t has finished its entered_g.set(), although it's + # impossible to guess whether it's still on that line or has moved on + # to its leave_g.wait(). + self.assertEqual(len(thread_info), 1) + thread_id = thread_info[0] + + d = sys._current_frames() + for tid in d: + self.assertIsInstance(tid, int) + self.assertGreater(tid, 0) + + main_id = threading.get_ident() + self.assertIn(main_id, d) + self.assertIn(thread_id, d) + + # Verify that the captured main-thread frame is _this_ frame. + frame = d.pop(main_id) + self.assertTrue(frame is sys._getframe()) + + # Verify that the captured thread frame is blocked in g456, called + # from f123. This is a little tricky, since various bits of + # threading.py are also in the thread's call stack. + frame = d.pop(thread_id) + stack = traceback.extract_stack(frame) + for i, (filename, lineno, funcname, sourceline) in enumerate(stack): + if funcname == "f123": + break + else: + self.fail("didn't find f123() on thread's call stack") - # And the next record must be for g456(). - filename, lineno, funcname, sourceline = stack[i+1] - self.assertEqual(funcname, "g456") - self.assertIn(sourceline, ["leave_g.wait()", "entered_g.set()"]) + self.assertEqual(sourceline, "g456()") - # Reap the spawned thread. - leave_g.set() - t.join() + # And the next record must be for g456(). + filename, lineno, funcname, sourceline = stack[i+1] + self.assertEqual(funcname, "g456") + self.assertIn(sourceline, ["leave_g.wait()", "entered_g.set()"]) + finally: + # Reap the spawned thread. + leave_g.set() + t.join() @threading_helper.reap_threads @threading_helper.requires_working_threading() @@ -496,43 +523,44 @@ class SysModuleTest(unittest.TestCase): t.start() entered_g.wait() - # At this point, t has finished its entered_g.set(), although it's - # impossible to guess whether it's still on that line or has moved on - # to its leave_g.wait(). - self.assertEqual(len(thread_info), 1) - thread_id = thread_info[0] - - d = sys._current_exceptions() - for tid in d: - self.assertIsInstance(tid, int) - self.assertGreater(tid, 0) - - main_id = threading.get_ident() - self.assertIn(main_id, d) - self.assertIn(thread_id, d) - self.assertEqual((None, None, None), d.pop(main_id)) - - # Verify that the captured thread frame is blocked in g456, called - # from f123. This is a little tricky, since various bits of - # threading.py are also in the thread's call stack. - exc_type, exc_value, exc_tb = d.pop(thread_id) - stack = traceback.extract_stack(exc_tb.tb_frame) - for i, (filename, lineno, funcname, sourceline) in enumerate(stack): - if funcname == "f123": - break - else: - self.fail("didn't find f123() on thread's call stack") - - self.assertEqual(sourceline, "g456()") + try: + # At this point, t has finished its entered_g.set(), although it's + # impossible to guess whether it's still on that line or has moved on + # to its leave_g.wait(). + self.assertEqual(len(thread_info), 1) + thread_id = thread_info[0] + + d = sys._current_exceptions() + for tid in d: + self.assertIsInstance(tid, int) + self.assertGreater(tid, 0) + + main_id = threading.get_ident() + self.assertIn(main_id, d) + self.assertIn(thread_id, d) + self.assertEqual(None, d.pop(main_id)) + + # Verify that the captured thread frame is blocked in g456, called + # from f123. This is a little tricky, since various bits of + # threading.py are also in the thread's call stack. + exc_value = d.pop(thread_id) + stack = traceback.extract_stack(exc_value.__traceback__.tb_frame) + for i, (filename, lineno, funcname, sourceline) in enumerate(stack): + if funcname == "f123": + break + else: + self.fail("didn't find f123() on thread's call stack") - # And the next record must be for g456(). - filename, lineno, funcname, sourceline = stack[i+1] - self.assertEqual(funcname, "g456") - self.assertTrue(sourceline.startswith("if leave_g.wait(")) + self.assertEqual(sourceline, "g456()") - # Reap the spawned thread. - leave_g.set() - t.join() + # And the next record must be for g456(). + filename, lineno, funcname, sourceline = stack[i+1] + self.assertEqual(funcname, "g456") + self.assertTrue(sourceline.startswith("if leave_g.wait(")) + finally: + # Reap the spawned thread. + leave_g.set() + t.join() def test_attributes(self): self.assertIsInstance(sys.api_version, int) @@ -1301,7 +1329,7 @@ class SizeofTest(unittest.TestCase): def __sizeof__(self): return int(self) self.assertEqual(sys.getsizeof(OverflowSizeof(sys.maxsize)), - sys.maxsize + self.gc_headsize) + sys.maxsize + self.gc_headsize*2) with self.assertRaises(OverflowError): sys.getsizeof(OverflowSizeof(sys.maxsize + 1)) with self.assertRaises(ValueError): @@ -1426,7 +1454,7 @@ class SizeofTest(unittest.TestCase): check(x, size('3Pi3c7P2ic??2P')) # function def func(): pass - check(func, size('14Pi')) + check(func, size('15Pi')) class c(): @staticmethod def foo(): @@ -1440,7 +1468,7 @@ class SizeofTest(unittest.TestCase): check(bar, size('PP')) # generator def get_gen(): yield 1 - check(get_gen(), size('P2P4P4c7P2ic??P')) + check(get_gen(), size('PP4P4c7P2ic??2P')) # iterator check(iter('abc'), size('lP')) # callable-iterator @@ -1485,7 +1513,8 @@ class SizeofTest(unittest.TestCase): # PyCapsule # XXX # rangeiterator - check(iter(range(1)), size('4l')) + check(iter(range(1)), size('3l')) + check(iter(range(2**65)), size('3P')) # reverse check(reversed(''), size('nP')) # range @@ -1522,7 +1551,7 @@ class SizeofTest(unittest.TestCase): check((1,2,3), vsize('') + 3*self.P) # type # static type: PyTypeObject - fmt = 'P2nPI13Pl4Pn9Pn12PIP' + fmt = 'P2nPI13Pl4Pn9Pn12PIPc' s = vsize('2P' + fmt) check(int, s) # class @@ -1533,7 +1562,7 @@ class SizeofTest(unittest.TestCase): '10P' # PySequenceMethods '2P' # PyBufferProcs '6P' - '1P' # Specializer cache + '1PI' # Specializer cache ) class newstyleclass(object): pass # Separate block for PyDictKeysObject with 8 keys and 5 entries @@ -1555,8 +1584,8 @@ class SizeofTest(unittest.TestCase): '\u0100'*40, '\uffff'*100, '\U00010000'*30, '\U0010ffff'*100] # also update field definitions in test_unicode.test_raiseMemError - asciifields = "nnbP" - compactfields = asciifields + "nPn" + asciifields = "nnb" + compactfields = asciifields + "nP" unicodefields = compactfields + "P" for s in samples: maxchar = ord(max(s)) @@ -1626,8 +1655,8 @@ class SizeofTest(unittest.TestCase): check(_ast.AST(), size('P')) try: raise TypeError - except TypeError: - tb = sys.exc_info()[2] + except TypeError as e: + tb = e.__traceback__ # traceback if tb is not None: check(tb, size('2P2i')) diff --git a/Lib/test/test_sys_setprofile.py b/Lib/test/test_sys_setprofile.py index 4c3053a1..34c70d6c 100644 --- a/Lib/test/test_sys_setprofile.py +++ b/Lib/test/test_sys_setprofile.py @@ -2,7 +2,6 @@ import gc import pprint import sys import unittest -from test import support class TestGetProfile(unittest.TestCase): @@ -437,13 +436,8 @@ class TestEdgeCases(unittest.TestCase): sys.setprofile(bar) sys.setprofile(A()) - with support.catch_unraisable_exception() as cm: - sys.setprofile(foo) - self.assertEqual(cm.unraisable.object, A.__del__) - self.assertIsInstance(cm.unraisable.exc_value, RuntimeError) - - self.assertEqual(sys.getprofile(), foo) - + sys.setprofile(foo) + self.assertEqual(sys.getprofile(), bar) def test_same_object(self): def foo(*args): @@ -453,6 +447,18 @@ class TestEdgeCases(unittest.TestCase): del foo sys.setprofile(sys.getprofile()) + def test_profile_after_trace_opcodes(self): + def f(): + ... + + sys._getframe().f_trace_opcodes = True + prev_trace = sys.gettrace() + sys.settrace(lambda *args: None) + f() + sys.settrace(prev_trace) + sys.setprofile(lambda *args: None) + f() + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_sys_settrace.py b/Lib/test/test_sys_settrace.py index aa61f8b1..c29deeba 100644 --- a/Lib/test/test_sys_settrace.py +++ b/Lib/test/test_sys_settrace.py @@ -2,13 +2,13 @@ from test import support import unittest -from unittest.mock import MagicMock import sys import difflib import gc from functools import wraps import asyncio from test.support import import_helper +import contextlib support.requires_working_socket(module=True) @@ -41,6 +41,20 @@ async def asynciter(iterable): for x in iterable: yield x +def clean_asynciter(test): + @wraps(test) + async def wrapper(*args, **kwargs): + cleanups = [] + def wrapped_asynciter(iterable): + it = asynciter(iterable) + cleanups.append(it.aclose) + return it + try: + return await test(*args, **kwargs, asynciter=wrapped_asynciter) + finally: + while cleanups: + await cleanups.pop()() + return wrapper # A very basic example. If this fails, we're in deep trouble. def basic(): @@ -346,7 +360,7 @@ class TraceTestCase(unittest.TestCase): return Tracer() def compare_events(self, line_offset, events, expected_events): - events = [(l - line_offset, e) for (l, e) in events] + events = [(l - line_offset if l is not None else None, e) for (l, e) in events] if events != expected_events: self.fail( "events did not match expectation:\n" + @@ -834,9 +848,8 @@ class TraceTestCase(unittest.TestCase): (5, 'line'), (6, 'line'), (7, 'line'), - (10, 'line'), - (13, 'line'), - (13, 'return')]) + (10, 'line')] + + ([(13, 'line'), (13, 'return')] if __debug__ else [(10, 'return')])) def test_continue_through_finally(self): @@ -871,9 +884,8 @@ class TraceTestCase(unittest.TestCase): (6, 'line'), (7, 'line'), (10, 'line'), - (3, 'line'), - (13, 'line'), - (13, 'return')]) + (3, 'line')] + + ([(13, 'line'), (13, 'return')] if __debug__ else [(3, 'return')])) def test_return_through_finally(self): @@ -909,6 +921,35 @@ class TraceTestCase(unittest.TestCase): (6, 'line'), (6, 'return')]) + def test_finally_with_conditional(self): + + # See gh-105658 + condition = True + def func(): + try: + try: + raise Exception + finally: + if condition: + result = 1 + result = 2 + except: + result = 3 + return result + + self.run_and_compare(func, + [(0, 'call'), + (1, 'line'), + (2, 'line'), + (3, 'line'), + (3, 'exception'), + (5, 'line'), + (6, 'line'), + (8, 'line'), + (9, 'line'), + (10, 'line'), + (10, 'return')]) + def test_break_to_continue1(self): def func(): @@ -1527,6 +1568,52 @@ class TraceTestCase(unittest.TestCase): (3, 'return'), (1, 'return')]) + def test_class_creation_with_decorator(self): + def func(): + def decorator(arg): + def _dec(c): + return c + return _dec + + @decorator(6) + @decorator( + len([8]), + ) + class MyObject: + pass + + self.run_and_compare(func, [ + (0, 'call'), + (1, 'line'), + (6, 'line'), + (1, 'call'), + (2, 'line'), + (4, 'line'), + (4, 'return'), + (7, 'line'), + (8, 'line'), + (7, 'line'), + (1, 'call'), + (2, 'line'), + (4, 'line'), + (4, 'return'), + (10, 'line'), + (6, 'call'), + (6, 'line'), + (11, 'line'), + (11, 'return'), + (7, 'line'), + (2, 'call'), + (3, 'line'), + (3, 'return'), + (6, 'line'), + (2, 'call'), + (3, 'line'), + (3, 'return'), + (10, 'line'), + (10, 'return'), + ]) + @support.cpython_only def test_no_line_event_after_creating_generator(self): # Spurious line events before call events only show up with C tracer @@ -1571,6 +1658,61 @@ class TraceTestCase(unittest.TestCase): self.run_and_compare(func, EXPECTED_EVENTS) + def test_settrace_error(self): + + raised = False + def error_once(frame, event, arg): + nonlocal raised + if not raised: + raised = True + raise Exception + return error + + try: + sys._getframe().f_trace = error_once + sys.settrace(error_once) + len([]) + except Exception as ex: + count = 0 + tb = ex.__traceback__ + while tb: + if tb.tb_frame.f_code.co_name == "test_settrace_error": + count += 1 + tb = tb.tb_next + if count == 0: + self.fail("Traceback is missing frame") + elif count > 1: + self.fail("Traceback has frame more than once") + else: + self.fail("No exception raised") + finally: + sys.settrace(None) + + @support.cpython_only + def test_testcapi_settrace_error(self): + + # Skip this test if the _testcapi module isn't available. + _testcapi = import_helper.import_module('_testcapi') + + try: + _testcapi.settrace_to_error([]) + len([]) + except Exception as ex: + count = 0 + tb = ex.__traceback__ + while tb: + if tb.tb_frame.f_code.co_name == "test_testcapi_settrace_error": + count += 1 + tb = tb.tb_next + if count == 0: + self.fail("Traceback is missing frame") + elif count > 1: + self.fail("Traceback has frame more than once") + else: + self.fail("No exception raised") + finally: + sys.settrace(None) + def test_very_large_function(self): # There is a separate code path when the number of lines > (1 << 15). d = {} @@ -1801,6 +1943,8 @@ def no_jump_without_trace_function(): class JumpTestCase(unittest.TestCase): + unbound_locals = r"assigning None to [0-9]+ unbound local" + def setUp(self): self.addCleanup(sys.settrace, sys.gettrace()) sys.settrace(None) @@ -1812,33 +1956,47 @@ class JumpTestCase(unittest.TestCase): "Received: " + repr(received)) def run_test(self, func, jumpFrom, jumpTo, expected, error=None, - event='line', decorated=False): - tracer = JumpTracer(func, jumpFrom, jumpTo, event, decorated) + event='line', decorated=False, warning=None): + wrapped = func + while hasattr(wrapped, '__wrapped__'): + wrapped = wrapped.__wrapped__ + + tracer = JumpTracer(wrapped, jumpFrom, jumpTo, event, decorated) sys.settrace(tracer.trace) output = [] - if error is None: + + with contextlib.ExitStack() as stack: + if error is not None: + stack.enter_context(self.assertRaisesRegex(*error)) + if warning is not None: + stack.enter_context(self.assertWarnsRegex(*warning)) func(output) - else: - with self.assertRaisesRegex(*error): - func(output) + sys.settrace(None) self.compare_jump_output(expected, output) def run_async_test(self, func, jumpFrom, jumpTo, expected, error=None, - event='line', decorated=False): - tracer = JumpTracer(func, jumpFrom, jumpTo, event, decorated) + event='line', decorated=False, warning=None): + wrapped = func + while hasattr(wrapped, '__wrapped__'): + wrapped = wrapped.__wrapped__ + + tracer = JumpTracer(wrapped, jumpFrom, jumpTo, event, decorated) sys.settrace(tracer.trace) output = [] - if error is None: + + with contextlib.ExitStack() as stack: + if error is not None: + stack.enter_context(self.assertRaisesRegex(*error)) + if warning is not None: + stack.enter_context(self.assertWarnsRegex(*warning)) asyncio.run(func(output)) - else: - with self.assertRaisesRegex(*error): - asyncio.run(func(output)) + sys.settrace(None) asyncio.set_event_loop_policy(None) self.compare_jump_output(expected, output) - def jump_test(jumpFrom, jumpTo, expected, error=None, event='line'): + def jump_test(jumpFrom, jumpTo, expected, error=None, event='line', warning=None): """Decorator that creates a test that makes a jump from one place to another in the following code. """ @@ -1846,11 +2004,11 @@ class JumpTestCase(unittest.TestCase): @wraps(func) def test(self): self.run_test(func, jumpFrom, jumpTo, expected, - error=error, event=event, decorated=True) + error=error, event=event, decorated=True, warning=warning) return test return decorator - def async_jump_test(jumpFrom, jumpTo, expected, error=None, event='line'): + def async_jump_test(jumpFrom, jumpTo, expected, error=None, event='line', warning=None): """Decorator that creates a test that makes a jump from one place to another in the following asynchronous code. """ @@ -1858,7 +2016,7 @@ class JumpTestCase(unittest.TestCase): @wraps(func) def test(self): self.run_async_test(func, jumpFrom, jumpTo, expected, - error=error, event=event, decorated=True) + error=error, event=event, decorated=True, warning=warning) return test return decorator @@ -1875,7 +2033,7 @@ class JumpTestCase(unittest.TestCase): output.append(1) output.append(2) - @jump_test(3, 5, [2, 5]) + @jump_test(3, 5, [2, 5], warning=(RuntimeWarning, unbound_locals)) def test_jump_out_of_block_forwards(output): for i in 1, 2: output.append(2) @@ -1894,7 +2052,8 @@ class JumpTestCase(unittest.TestCase): output.append(7) @async_jump_test(4, 5, [3, 5]) - async def test_jump_out_of_async_for_block_forwards(output): + @clean_asynciter + async def test_jump_out_of_async_for_block_forwards(output, asynciter): for i in [1]: async for i in asynciter([1, 2]): output.append(3) @@ -1902,7 +2061,8 @@ class JumpTestCase(unittest.TestCase): output.append(5) @async_jump_test(5, 2, [2, 4, 2, 4, 5, 6]) - async def test_jump_out_of_async_for_block_backwards(output): + @clean_asynciter + async def test_jump_out_of_async_for_block_backwards(output, asynciter): for i in [1]: output.append(2) async for i in asynciter([1]): @@ -1961,7 +2121,7 @@ class JumpTestCase(unittest.TestCase): output.append(11) output.append(12) - @jump_test(5, 11, [2, 4], (ValueError, 'exception')) + @jump_test(5, 11, [2, 4], (ValueError, 'comes after the current code block')) def test_no_jump_over_return_try_finally_in_finally_block(output): try: output.append(2) @@ -2089,7 +2249,7 @@ class JumpTestCase(unittest.TestCase): output.append(6) output.append(7) - @jump_test(6, 1, [1, 5, 1, 5]) + @jump_test(6, 1, [1, 5, 1, 5], warning=(RuntimeWarning, unbound_locals)) def test_jump_over_try_except(output): output.append(1) try: @@ -2185,7 +2345,7 @@ class JumpTestCase(unittest.TestCase): output.append(11) output.append(12) - @jump_test(3, 5, [1, 2, 5]) + @jump_test(3, 5, [1, 2, 5], warning=(RuntimeWarning, unbound_locals)) def test_jump_out_of_with_assignment(output): output.append(1) with tracecontext(output, 2) \ @@ -2193,7 +2353,7 @@ class JumpTestCase(unittest.TestCase): output.append(4) output.append(5) - @async_jump_test(3, 5, [1, 2, 5]) + @async_jump_test(3, 5, [1, 2, 5], warning=(RuntimeWarning, unbound_locals)) async def test_jump_out_of_async_with_assignment(output): output.append(1) async with asynctracecontext(output, 2) \ @@ -2229,7 +2389,7 @@ class JumpTestCase(unittest.TestCase): break output.append(13) - @jump_test(1, 7, [7, 8]) + @jump_test(1, 7, [7, 8], warning=(RuntimeWarning, unbound_locals)) def test_jump_over_for_block_before_else(output): output.append(1) if not output: # always false @@ -2240,7 +2400,7 @@ class JumpTestCase(unittest.TestCase): output.append(7) output.append(8) - @async_jump_test(1, 7, [7, 8]) + @async_jump_test(1, 7, [7, 8], warning=(RuntimeWarning, unbound_locals)) async def test_jump_over_async_for_block_before_else(output): output.append(1) if not output: # always false @@ -2315,6 +2475,7 @@ class JumpTestCase(unittest.TestCase): output.append(2) output.append(3) + @async_jump_test(3, 2, [2, 2], (ValueError, "can't jump into the body of a for loop")) async def test_no_jump_backwards_into_async_for_block(output): async for i in asynciter([1, 2]): @@ -2380,7 +2541,7 @@ class JumpTestCase(unittest.TestCase): output.append(6) # 'except' with a variable creates an implicit finally block - @jump_test(5, 7, [4, 7, 8]) + @jump_test(5, 7, [4, 7, 8], warning=(RuntimeWarning, unbound_locals)) def test_jump_between_except_blocks_2(output): try: 1/0 @@ -2543,7 +2704,7 @@ class JumpTestCase(unittest.TestCase): output.append(x) # line 1007 return""" % ('\n' * 1000,), d) f = d['f'] - self.run_test(f, 2, 1007, [0]) + self.run_test(f, 2, 1007, [0], warning=(RuntimeWarning, self.unbound_locals)) def test_jump_to_firstlineno(self): # This tests that PDB can jump back to the first line in a @@ -2593,7 +2754,7 @@ output.append(4) next(gen()) output.append(5) - @jump_test(2, 3, [1, 3]) + @jump_test(2, 3, [1, 3], warning=(RuntimeWarning, unbound_locals)) def test_jump_forward_over_listcomp(output): output.append(1) x = [i for i in range(10)] @@ -2601,13 +2762,13 @@ output.append(4) # checking for segfaults. # See https://github.com/python/cpython/issues/92311 - @jump_test(3, 1, []) + @jump_test(3, 1, [], warning=(RuntimeWarning, unbound_locals)) def test_jump_backward_over_listcomp(output): a = 1 x = [i for i in range(10)] c = 3 - @jump_test(8, 2, [2, 7, 2]) + @jump_test(8, 2, [2, 7, 2], warning=(RuntimeWarning, unbound_locals)) def test_jump_backward_over_listcomp_v2(output): flag = False output.append(2) @@ -2618,19 +2779,19 @@ output.append(4) output.append(7) output.append(8) - @async_jump_test(2, 3, [1, 3]) + @async_jump_test(2, 3, [1, 3], warning=(RuntimeWarning, unbound_locals)) async def test_jump_forward_over_async_listcomp(output): output.append(1) x = [i async for i in asynciter(range(10))] output.append(3) - @async_jump_test(3, 1, []) + @async_jump_test(3, 1, [], warning=(RuntimeWarning, unbound_locals)) async def test_jump_backward_over_async_listcomp(output): a = 1 x = [i async for i in asynciter(range(10))] c = 3 - @async_jump_test(8, 2, [2, 7, 2]) + @async_jump_test(8, 2, [2, 7, 2], warning=(RuntimeWarning, unbound_locals)) async def test_jump_backward_over_async_listcomp_v2(output): flag = False output.append(2) @@ -2699,13 +2860,13 @@ output.append(4) ) output.append(15) - @jump_test(2, 3, [1, 3]) + @jump_test(2, 3, [1, 3], warning=(RuntimeWarning, unbound_locals)) def test_jump_extended_args_unpack_ex_simple(output): output.append(1) _, *_, _ = output.append(2) or "Spam" output.append(3) - @jump_test(3, 4, [1, 4, 4, 5]) + @jump_test(3, 4, [1, 4, 4, 5], warning=(RuntimeWarning, unbound_locals)) def test_jump_extended_args_unpack_ex_tricky(output): output.append(1) ( @@ -2713,6 +2874,7 @@ output.append(4) ) = output.append(4) or "Spam" output.append(5) + @support.requires_resource('cpu') def test_jump_extended_args_for_iter(self): # In addition to failing when extended arg handling is broken, this can # also hang for a *very* long time: @@ -2726,9 +2888,9 @@ output.append(4) namespace = {} exec("\n".join(source), namespace) f = namespace["f"] - self.run_test(f, 2, 100_000, [1, 100_000]) + self.run_test(f, 2, 100_000, [1, 100_000], warning=(RuntimeWarning, self.unbound_locals)) - @jump_test(2, 3, [1, 3]) + @jump_test(2, 3, [1, 3], warning=(RuntimeWarning, unbound_locals)) def test_jump_or_pop(output): output.append(1) _ = output.append(2) and "Spam" @@ -2798,12 +2960,8 @@ class TestEdgeCases(unittest.TestCase): sys.settrace(bar) sys.settrace(A()) - with support.catch_unraisable_exception() as cm: - sys.settrace(foo) - self.assertEqual(cm.unraisable.object, A.__del__) - self.assertIsInstance(cm.unraisable.exc_value, RuntimeError) - - self.assertEqual(sys.gettrace(), foo) + sys.settrace(foo) + self.assertEqual(sys.gettrace(), bar) def test_same_object(self): @@ -2815,5 +2973,64 @@ class TestEdgeCases(unittest.TestCase): sys.settrace(sys.gettrace()) +class TestLinesAfterTraceStarted(TraceTestCase): + + def test_events(self): + tracer = Tracer() + sys._getframe().f_trace = tracer.trace + sys.settrace(tracer.trace) + line = 4 + line = 5 + sys.settrace(None) + self.compare_events( + TestLinesAfterTraceStarted.test_events.__code__.co_firstlineno, + tracer.events, [ + (4, 'line'), + (5, 'line'), + (6, 'line')]) + + +class TestSetLocalTrace(TraceTestCase): + + def test_with_branches(self): + + def tracefunc(frame, event, arg): + if frame.f_code.co_name == "func": + frame.f_trace = tracefunc + line = frame.f_lineno - frame.f_code.co_firstlineno + events.append((line, event)) + return tracefunc + + def func(arg = 1): + N = 1 + if arg >= 2: + not_reached = 3 + else: + reached = 5 + if arg >= 3: + not_reached = 7 + else: + reached = 9 + the_end = 10 + + EXPECTED_EVENTS = [ + (0, 'call'), + (1, 'line'), + (2, 'line'), + (5, 'line'), + (6, 'line'), + (9, 'line'), + (10, 'line'), + (10, 'return'), + ] + + events = [] + sys.settrace(tracefunc) + sys._getframe().f_trace = tracefunc + func() + self.assertEqual(events, EXPECTED_EVENTS) + sys.settrace(None) + + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_sysconfig.py b/Lib/test/test_sysconfig.py index d96371d2..b6dbf3d5 100644 --- a/Lib/test/test_sysconfig.py +++ b/Lib/test/test_sysconfig.py @@ -11,7 +11,6 @@ from test.support import ( from test.support.import_helper import import_module from test.support.os_helper import (TESTFN, unlink, skip_unless_symlink, change_cwd) -from test.support.warnings_helper import check_warnings import sysconfig from sysconfig import (get_paths, get_platform, get_config_vars, diff --git a/Lib/test/test_syslog.py b/Lib/test/test_syslog.py index 2125ec58..54db80fa 100644 --- a/Lib/test/test_syslog.py +++ b/Lib/test/test_syslog.py @@ -5,6 +5,7 @@ import sys import threading import time import unittest +from textwrap import dedent # XXX(nnorwitz): This test sucks. I don't know of a platform independent way # to verify that the messages were really logged. @@ -78,6 +79,69 @@ class Test(unittest.TestCase): finally: sys.setswitchinterval(orig_si) + def test_subinterpreter_syslog(self): + # syslog.syslog() is not allowed in subinterpreters, but only if + # syslog.openlog() hasn't been called in the main interpreter yet. + with self.subTest('before openlog()'): + code = dedent(''' + import syslog + caught_error = False + try: + syslog.syslog('foo') + except RuntimeError: + caught_error = True + assert(caught_error) + ''') + res = support.run_in_subinterp(code) + self.assertEqual(res, 0) + + syslog.openlog() + try: + with self.subTest('after openlog()'): + code = dedent(''' + import syslog + syslog.syslog('foo') + ''') + res = support.run_in_subinterp(code) + self.assertEqual(res, 0) + finally: + syslog.closelog() + + def test_subinterpreter_openlog(self): + try: + code = dedent(''' + import syslog + caught_error = False + try: + syslog.openlog() + except RuntimeError: + caught_error = True + + assert(caught_error) + ''') + res = support.run_in_subinterp(code) + self.assertEqual(res, 0) + finally: + syslog.closelog() + + def test_subinterpreter_closelog(self): + syslog.openlog('python') + try: + code = dedent(''' + import syslog + caught_error = False + try: + syslog.closelog() + except RuntimeError: + caught_error = True + + assert(caught_error) + ''') + res = support.run_in_subinterp(code) + self.assertEqual(res, 0) + finally: + syslog.closelog() + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_tabnanny.py b/Lib/test/test_tabnanny.py index e0a82e95..cc122caf 100644 --- a/Lib/test/test_tabnanny.py +++ b/Lib/test/test_tabnanny.py @@ -110,9 +110,10 @@ class TestErrPrint(TestCase): for args, expected in tests: with self.subTest(arguments=args, expected=expected): - with captured_stderr() as stderr: - tabnanny.errprint(*args) - self.assertEqual(stderr.getvalue() , expected) + with self.assertRaises(SystemExit): + with captured_stderr() as stderr: + tabnanny.errprint(*args) + self.assertEqual(stderr.getvalue() , expected) class TestNannyNag(TestCase): @@ -203,14 +204,16 @@ class TestCheck(TestCase): err = ('unindent does not match any outer indentation level' ' (<tokenize>, line 3)\n') err = f"{file_path!r}: Indentation Error: {err}" - self.verify_tabnanny_check(file_path, err=err) + with self.assertRaises(SystemExit): + self.verify_tabnanny_check(file_path, err=err) def test_when_tokenize_tokenerror(self): """A python source code file eligible for raising 'tokenize.TokenError'.""" with TemporaryPyFile(SOURCE_CODES["incomplete_expression"]) as file_path: err = "('EOF in multi-line statement', (7, 0))\n" err = f"{file_path!r}: Token Error: {err}" - self.verify_tabnanny_check(file_path, err=err) + with self.assertRaises(SystemExit): + self.verify_tabnanny_check(file_path, err=err) def test_when_nannynag_error_verbose(self): """A python source code file eligible for raising `tabnanny.NannyNag`. @@ -219,8 +222,8 @@ class TestCheck(TestCase): """ with TemporaryPyFile(SOURCE_CODES["nannynag_errored"]) as file_path: out = f"{file_path!r}: *** Line 3: trouble in tab city! ***\n" - out += "offending line: '\\tprint(\"world\")\\n'\n" - out += "indent not equal e.g. at tab size 1\n" + out += "offending line: '\\tprint(\"world\")'\n" + out += "inconsistent use of tabs and spaces in indentation\n" tabnanny.verbose = 1 self.verify_tabnanny_check(file_path, out=out) @@ -228,7 +231,7 @@ class TestCheck(TestCase): def test_when_nannynag_error(self): """A python source code file eligible for raising `tabnanny.NannyNag`.""" with TemporaryPyFile(SOURCE_CODES["nannynag_errored"]) as file_path: - out = f"{file_path} 3 '\\tprint(\"world\")\\n'\n" + out = f"{file_path} 3 '\\tprint(\"world\")'\n" self.verify_tabnanny_check(file_path, out=out) def test_when_no_file(self): @@ -236,7 +239,8 @@ class TestCheck(TestCase): path = 'no_file.py' err = (f"{path!r}: I/O Error: [Errno {errno.ENOENT}] " f"{os.strerror(errno.ENOENT)}: {path!r}\n") - self.verify_tabnanny_check(path, err=err) + with self.assertRaises(SystemExit): + self.verify_tabnanny_check(path, err=err) def test_errored_directory(self): """Directory containing wrongly indented python source code files.""" @@ -251,7 +255,8 @@ class TestCheck(TestCase): err = ('unindent does not match any outer indentation level' ' (<tokenize>, line 3)\n') err = f"{e_file!r}: Indentation Error: {err}" - self.verify_tabnanny_check(tmp_dir, err=err) + with self.assertRaises(SystemExit): + self.verify_tabnanny_check(tmp_dir, err=err) class TestProcessTokens(TestCase): @@ -287,9 +292,12 @@ class TestProcessTokens(TestCase): class TestCommandLine(TestCase): """Tests command line interface of `tabnanny`.""" - def validate_cmd(self, *args, stdout="", stderr="", partial=False): + def validate_cmd(self, *args, stdout="", stderr="", partial=False, expect_failure=False): """Common function to assert the behaviour of command line interface.""" - _, out, err = script_helper.assert_python_ok('-m', 'tabnanny', *args) + if expect_failure: + _, out, err = script_helper.assert_python_failure('-m', 'tabnanny', *args) + else: + _, out, err = script_helper.assert_python_ok('-m', 'tabnanny', *args) # Note: The `splitlines()` will solve the problem of CRLF(\r) added # by OS Windows. out = os.fsdecode(out) @@ -307,10 +315,10 @@ class TestCommandLine(TestCase): def test_with_errored_file(self): """Should displays error when errored python file is given.""" with TemporaryPyFile(SOURCE_CODES["wrong_indented"]) as file_path: - stderr = f"{file_path!r}: Indentation Error: " + stderr = f"{file_path!r}: Token Error: " stderr += ('unindent does not match any outer indentation level' - ' (<tokenize>, line 3)') - self.validate_cmd(file_path, stderr=stderr) + ' (<string>, line 3)') + self.validate_cmd(file_path, stderr=stderr, expect_failure=True) def test_with_error_free_file(self): """Should not display anything if python file is correctly indented.""" @@ -321,7 +329,7 @@ class TestCommandLine(TestCase): """Should display usage on no arguments.""" path = findfile('tabnanny.py') stderr = f"Usage: {path} [-v] file_or_directory ..." - self.validate_cmd(stderr=stderr) + self.validate_cmd(stderr=stderr, expect_failure=True) def test_quiet_flag(self): """Should display less when quite mode is on.""" @@ -333,7 +341,7 @@ class TestCommandLine(TestCase): """Should display more error information if verbose mode is on.""" with TemporaryPyFile(SOURCE_CODES["nannynag_errored"]) as path: stdout = textwrap.dedent( - "offending line: '\\tprint(\"world\")\\n'" + "offending line: '\\tprint(\"world\")'" ).strip() self.validate_cmd("-v", path, stdout=stdout, partial=True) @@ -341,6 +349,6 @@ class TestCommandLine(TestCase): """Should display detailed error information if double verbose is on.""" with TemporaryPyFile(SOURCE_CODES["nannynag_errored"]) as path: stdout = textwrap.dedent( - "offending line: '\\tprint(\"world\")\\n'" + "offending line: '\\tprint(\"world\")'" ).strip() self.validate_cmd("-vv", path, stdout=stdout, partial=True) diff --git a/Lib/test/test_tarfile.py b/Lib/test/test_tarfile.py index 7a0830f6..013c6263 100644 --- a/Lib/test/test_tarfile.py +++ b/Lib/test/test_tarfile.py @@ -2,9 +2,13 @@ import sys import os import io from hashlib import sha256 -from contextlib import contextmanager +from contextlib import contextmanager, ExitStack from random import Random import pathlib +import shutil +import re +import warnings +import stat import unittest import unittest.mock @@ -13,6 +17,7 @@ import tarfile from test import support from test.support import os_helper from test.support import script_helper +from test.support import warnings_helper # Check for our compression modules. try: @@ -108,7 +113,7 @@ class UstarReadTest(ReadTest, unittest.TestCase): "regular file extraction failed") def test_fileobj_readlines(self): - self.tar.extract("ustar/regtype", TEMPDIR) + self.tar.extract("ustar/regtype", TEMPDIR, filter='data') tarinfo = self.tar.getmember("ustar/regtype") with open(os.path.join(TEMPDIR, "ustar/regtype"), "r") as fobj1: lines1 = fobj1.readlines() @@ -126,7 +131,7 @@ class UstarReadTest(ReadTest, unittest.TestCase): "fileobj.readlines() failed") def test_fileobj_iter(self): - self.tar.extract("ustar/regtype", TEMPDIR) + self.tar.extract("ustar/regtype", TEMPDIR, filter='data') tarinfo = self.tar.getmember("ustar/regtype") with open(os.path.join(TEMPDIR, "ustar/regtype"), "r") as fobj1: lines1 = fobj1.readlines() @@ -136,7 +141,8 @@ class UstarReadTest(ReadTest, unittest.TestCase): "fileobj.__iter__() failed") def test_fileobj_seek(self): - self.tar.extract("ustar/regtype", TEMPDIR) + self.tar.extract("ustar/regtype", TEMPDIR, + filter='data') with open(os.path.join(TEMPDIR, "ustar/regtype"), "rb") as fobj: data = fobj.read() @@ -225,18 +231,19 @@ class UstarReadTest(ReadTest, unittest.TestCase): self.add_dir_and_getmember('bar') self.add_dir_and_getmember('a'*101) - @unittest.skipIf( - (hasattr(os, 'getuid') and os.getuid() > 0o777_7777) or - (hasattr(os, 'getgid') and os.getgid() > 0o777_7777), - "uid or gid too high for USTAR format." - ) + @unittest.skipUnless(hasattr(os, "getuid") and hasattr(os, "getgid"), + "Missing getuid or getgid implementation") def add_dir_and_getmember(self, name): + def filter(tarinfo): + tarinfo.uid = tarinfo.gid = 100 + return tarinfo + with os_helper.temp_cwd(): with tarfile.open(tmpname, 'w') as tar: tar.format = tarfile.USTAR_FORMAT try: os.mkdir(name) - tar.add(name) + tar.add(name, filter=filter) finally: os.rmdir(name) with tarfile.open(tmpname) as tar: @@ -466,7 +473,7 @@ class CommonReadTest(ReadTest): t = tar.next() with self.assertRaisesRegex(tarfile.ReadError, "unexpected end of data"): - tar.extract(t, TEMPDIR) + tar.extract(t, TEMPDIR, filter='data') with self.assertRaisesRegex(tarfile.ReadError, "unexpected end of data"): tar.extractfile(t).read() @@ -478,6 +485,13 @@ class CommonReadTest(ReadTest): with tarfile.open(support.findfile('recursion.tar')) as tar: pass + def test_extractfile_name(self): + # gh-74468: TarFile.name must name a file, not a parent archive. + file = self.tar.getmember('ustar/regtype') + with self.tar.extractfile(file) as fobj: + self.assertEqual(fobj.name, 'ustar/regtype') + + class MiscReadTestBase(CommonReadTest): def requires_name_attribute(self): pass @@ -621,16 +635,16 @@ class MiscReadTestBase(CommonReadTest): def test_extract_hardlink(self): # Test hardlink extraction (e.g. bug #857297). with tarfile.open(tarname, errorlevel=1, encoding="iso8859-1") as tar: - tar.extract("ustar/regtype", TEMPDIR) + tar.extract("ustar/regtype", TEMPDIR, filter='data') self.addCleanup(os_helper.unlink, os.path.join(TEMPDIR, "ustar/regtype")) - tar.extract("ustar/lnktype", TEMPDIR) + tar.extract("ustar/lnktype", TEMPDIR, filter='data') self.addCleanup(os_helper.unlink, os.path.join(TEMPDIR, "ustar/lnktype")) with open(os.path.join(TEMPDIR, "ustar/lnktype"), "rb") as f: data = f.read() self.assertEqual(sha256sum(data), sha256_regtype) - tar.extract("ustar/symtype", TEMPDIR) + tar.extract("ustar/symtype", TEMPDIR, filter='data') self.addCleanup(os_helper.unlink, os.path.join(TEMPDIR, "ustar/symtype")) with open(os.path.join(TEMPDIR, "ustar/symtype"), "rb") as f: data = f.read() @@ -645,13 +659,14 @@ class MiscReadTestBase(CommonReadTest): os.mkdir(DIR) try: directories = [t for t in tar if t.isdir()] - tar.extractall(DIR, directories) + tar.extractall(DIR, directories, filter='fully_trusted') for tarinfo in directories: path = os.path.join(DIR, tarinfo.name) if sys.platform != "win32": # Win32 has no support for fine grained permissions. self.assertEqual(tarinfo.mode & 0o777, - os.stat(path).st_mode & 0o777) + os.stat(path).st_mode & 0o777, + tarinfo.name) def format_mtime(mtime): if isinstance(mtime, float): return "{} ({})".format(mtime, mtime.hex()) @@ -675,7 +690,7 @@ class MiscReadTestBase(CommonReadTest): try: with tarfile.open(tarname, encoding="iso8859-1") as tar: tarinfo = tar.getmember(dirtype) - tar.extract(tarinfo, path=DIR) + tar.extract(tarinfo, path=DIR, filter='fully_trusted') extracted = os.path.join(DIR, dirtype) self.assertEqual(os.path.getmtime(extracted), tarinfo.mtime) if sys.platform != "win32": @@ -688,7 +703,7 @@ class MiscReadTestBase(CommonReadTest): with os_helper.temp_dir(DIR), \ tarfile.open(tarname, encoding="iso8859-1") as tar: directories = [t for t in tar if t.isdir()] - tar.extractall(DIR, directories) + tar.extractall(DIR, directories, filter='fully_trusted') for tarinfo in directories: path = DIR / tarinfo.name self.assertEqual(os.path.getmtime(path), tarinfo.mtime) @@ -699,7 +714,7 @@ class MiscReadTestBase(CommonReadTest): with os_helper.temp_dir(DIR), \ tarfile.open(tarname, encoding="iso8859-1") as tar: tarinfo = tar.getmember(dirtype) - tar.extract(tarinfo, path=DIR) + tar.extract(tarinfo, path=DIR, filter='fully_trusted') extracted = DIR / dirtype self.assertEqual(os.path.getmtime(extracted), tarinfo.mtime) @@ -900,6 +915,23 @@ class LzmaDetectReadTest(LzmaTest, DetectReadTest): pass +class GzipBrokenHeaderCorrectException(GzipTest, unittest.TestCase): + """ + See: https://github.com/python/cpython/issues/107396 + """ + def runTest(self): + f = io.BytesIO( + b'\x1f\x8b' # header + b'\x08' # compression method + b'\x04' # flags + b'\0\0\0\0\0\0' # timestamp, compression data, OS ID + b'\0\x01' # size + b'\0\0\0\0\0' # corrupt data (zeros) + ) + with self.assertRaises(tarfile.ReadError): + tarfile.open(fileobj=f, mode='r|gz') + + class MemberReadTest(ReadTest, unittest.TestCase): def _test_member(self, tarinfo, chksum=None, **kwargs): @@ -1067,7 +1099,7 @@ class GNUReadTest(LongnameTest, ReadTest, unittest.TestCase): # an all platforms, and after that a test that will work only on # platforms/filesystems that prove to support sparse files. def _test_sparse_file(self, name): - self.tar.extract(name, TEMPDIR) + self.tar.extract(name, TEMPDIR, filter='data') filename = os.path.join(TEMPDIR, name) with open(filename, "rb") as fobj: data = fobj.read() @@ -1434,7 +1466,8 @@ class WriteTest(WriteTestBase, unittest.TestCase): with tarfile.open(temparchive, errorlevel=2) as tar: # this should not raise OSError: [Errno 17] File exists try: - tar.extractall(path=tempdir) + tar.extractall(path=tempdir, + filter='fully_trusted') except OSError: self.fail("extractall failed with symlinked files") finally: @@ -1571,6 +1604,75 @@ class Bz2StreamWriteTest(Bz2Test, StreamWriteTest): class LzmaStreamWriteTest(LzmaTest, StreamWriteTest): decompressor = lzma.LZMADecompressor if lzma else None +class _CompressedWriteTest(TarTest): + # This is not actually a standalone test. + # It does not inherit WriteTest because it only makes sense with gz,bz2 + source = (b"And we move to Bristol where they have a special, " + + b"Very Silly candidate") + + def _compressed_tar(self, compresslevel): + fobj = io.BytesIO() + with tarfile.open(tmpname, self.mode, fobj, + compresslevel=compresslevel) as tarfl: + tarfl.addfile(tarfile.TarInfo("foo"), io.BytesIO(self.source)) + return fobj + + def _test_bz2_header(self, compresslevel): + fobj = self._compressed_tar(compresslevel) + self.assertEqual(fobj.getvalue()[0:10], + b"BZh%d1AY&SY" % compresslevel) + + def _test_gz_header(self, compresslevel): + fobj = self._compressed_tar(compresslevel) + self.assertEqual(fobj.getvalue()[:3], b"\x1f\x8b\x08") + +class Bz2CompressWriteTest(Bz2Test, _CompressedWriteTest, unittest.TestCase): + prefix = "w:" + def test_compression_levels(self): + self._test_bz2_header(1) + self._test_bz2_header(5) + self._test_bz2_header(9) + +class Bz2CompressStreamWriteTest(Bz2Test, _CompressedWriteTest, + unittest.TestCase): + prefix = "w|" + def test_compression_levels(self): + self._test_bz2_header(1) + self._test_bz2_header(5) + self._test_bz2_header(9) + +class GzCompressWriteTest(GzipTest, _CompressedWriteTest, unittest.TestCase): + prefix = "w:" + def test_compression_levels(self): + self._test_gz_header(1) + self._test_gz_header(5) + self._test_gz_header(9) + +class GzCompressStreamWriteTest(GzipTest, _CompressedWriteTest, + unittest.TestCase): + prefix = "w|" + def test_compression_levels(self): + self._test_gz_header(1) + self._test_gz_header(5) + self._test_gz_header(9) + +class CompressLevelRaises(unittest.TestCase): + def test_compresslevel_wrong_modes(self): + compresslevel = 5 + fobj = io.BytesIO() + with self.assertRaises(TypeError): + tarfile.open(tmpname, "w:", fobj, compresslevel=compresslevel) + + @support.requires_bz2() + def test_wrong_compresslevels(self): + # BZ2 checks that the compresslevel is in [1,9]. gz does not + fobj = io.BytesIO() + with self.assertRaises(ValueError): + tarfile.open(tmpname, "w:bz2", fobj, compresslevel=0) + with self.assertRaises(ValueError): + tarfile.open(tmpname, "w:bz2", fobj, compresslevel=10) + with self.assertRaises(ValueError): + tarfile.open(tmpname, "w|bz2", fobj, compresslevel=10) class GNUWriteTest(unittest.TestCase): # This testcase checks for correct creation of GNU Longname @@ -2470,6 +2572,15 @@ class CommandLineTest(unittest.TestCase): for tardata in files: tf.add(tardata, arcname=os.path.basename(tardata)) + def make_evil_tarfile(self, tar_name): + files = [support.findfile('tokenize_tests.txt')] + self.addCleanup(os_helper.unlink, tar_name) + with tarfile.open(tar_name, 'w') as tf: + benign = tarfile.TarInfo('benign') + tf.addfile(benign, fileobj=io.BytesIO(b'')) + evil = tarfile.TarInfo('../evil') + tf.addfile(evil, fileobj=io.BytesIO(b'')) + def test_bad_use(self): rc, out, err = self.tarfilecmd_failure() self.assertEqual(out, b'') @@ -2626,6 +2737,25 @@ class CommandLineTest(unittest.TestCase): finally: os_helper.rmtree(tarextdir) + def test_extract_command_filter(self): + self.make_evil_tarfile(tmpname) + # Make an inner directory, so the member named '../evil' + # is still extracted into `tarextdir` + destdir = os.path.join(tarextdir, 'dest') + os.mkdir(tarextdir) + try: + with os_helper.temp_cwd(destdir): + self.tarfilecmd_failure('-e', tmpname, + '-v', + '--filter', 'data') + out = self.tarfilecmd('-e', tmpname, + '-v', + '--filter', 'fully_trusted', + PYTHONIOENCODING='utf-8') + self.assertIn(b' file is extracted.', out) + finally: + os_helper.rmtree(tarextdir) + def test_extract_command_different_directory(self): self.make_simple_tarfile(tmpname) try: @@ -2709,7 +2839,7 @@ class LinkEmulationTest(ReadTest, unittest.TestCase): # symbolic or hard links tarfile tries to extract these types of members # as the regular files they point to. def _test_link_extraction(self, name): - self.tar.extract(name, TEMPDIR) + self.tar.extract(name, TEMPDIR, filter='fully_trusted') with open(os.path.join(TEMPDIR, name), "rb") as f: data = f.read() self.assertEqual(sha256sum(data), sha256_regtype) @@ -2841,8 +2971,10 @@ class NumericOwnerTest(unittest.TestCase): mock_chown): with self._setup_test(mock_geteuid) as (tarfl, filename_1, _, filename_2): - tarfl.extract(filename_1, TEMPDIR, numeric_owner=True) - tarfl.extract(filename_2 , TEMPDIR, numeric_owner=True) + tarfl.extract(filename_1, TEMPDIR, numeric_owner=True, + filter='fully_trusted') + tarfl.extract(filename_2 , TEMPDIR, numeric_owner=True, + filter='fully_trusted') # convert to filesystem paths f_filename_1 = os.path.join(TEMPDIR, filename_1) @@ -2860,7 +2992,8 @@ class NumericOwnerTest(unittest.TestCase): mock_chown): with self._setup_test(mock_geteuid) as (tarfl, filename_1, dirname_1, filename_2): - tarfl.extractall(TEMPDIR, numeric_owner=True) + tarfl.extractall(TEMPDIR, numeric_owner=True, + filter='fully_trusted') # convert to filesystem paths f_filename_1 = os.path.join(TEMPDIR, filename_1) @@ -2885,7 +3018,8 @@ class NumericOwnerTest(unittest.TestCase): def test_extract_without_numeric_owner(self, mock_geteuid, mock_chmod, mock_chown): with self._setup_test(mock_geteuid) as (tarfl, filename_1, _, _): - tarfl.extract(filename_1, TEMPDIR, numeric_owner=False) + tarfl.extract(filename_1, TEMPDIR, numeric_owner=False, + filter='fully_trusted') # convert to filesystem paths f_filename_1 = os.path.join(TEMPDIR, filename_1) @@ -2899,6 +3033,1042 @@ class NumericOwnerTest(unittest.TestCase): tarfl.extract, filename_1, TEMPDIR, False, True) +class ReplaceTests(ReadTest, unittest.TestCase): + def test_replace_name(self): + member = self.tar.getmember('ustar/regtype') + replaced = member.replace(name='misc/other') + self.assertEqual(replaced.name, 'misc/other') + self.assertEqual(member.name, 'ustar/regtype') + self.assertEqual(self.tar.getmember('ustar/regtype').name, + 'ustar/regtype') + + def test_replace_deep(self): + member = self.tar.getmember('pax/regtype1') + replaced = member.replace() + replaced.pax_headers['gname'] = 'not-bar' + self.assertEqual(member.pax_headers['gname'], 'bar') + self.assertEqual( + self.tar.getmember('pax/regtype1').pax_headers['gname'], 'bar') + + def test_replace_shallow(self): + member = self.tar.getmember('pax/regtype1') + replaced = member.replace(deep=False) + replaced.pax_headers['gname'] = 'not-bar' + self.assertEqual(member.pax_headers['gname'], 'not-bar') + self.assertEqual( + self.tar.getmember('pax/regtype1').pax_headers['gname'], 'not-bar') + + def test_replace_all(self): + member = self.tar.getmember('ustar/regtype') + for attr_name in ('name', 'mtime', 'mode', 'linkname', + 'uid', 'gid', 'uname', 'gname'): + with self.subTest(attr_name=attr_name): + replaced = member.replace(**{attr_name: None}) + self.assertEqual(getattr(replaced, attr_name), None) + self.assertNotEqual(getattr(member, attr_name), None) + + def test_replace_internal(self): + member = self.tar.getmember('ustar/regtype') + with self.assertRaises(TypeError): + member.replace(offset=123456789) + + +class NoneInfoExtractTests(ReadTest): + # These mainly check that all kinds of members are extracted successfully + # if some metadata is None. + # Some of the methods do additional spot checks. + + # We also test that the default filters can deal with None. + + extraction_filter = None + + @classmethod + def setUpClass(cls): + tar = tarfile.open(tarname, mode='r', encoding="iso8859-1") + cls.control_dir = pathlib.Path(TEMPDIR) / "extractall_ctrl" + tar.errorlevel = 0 + with ExitStack() as cm: + if cls.extraction_filter is None: + cm.enter_context(warnings.catch_warnings( + action="ignore", category=DeprecationWarning)) + tar.extractall(cls.control_dir, filter=cls.extraction_filter) + tar.close() + cls.control_paths = set( + p.relative_to(cls.control_dir) + for p in pathlib.Path(cls.control_dir).glob('**/*')) + + @classmethod + def tearDownClass(cls): + shutil.rmtree(cls.control_dir) + + def check_files_present(self, directory): + got_paths = set( + p.relative_to(directory) + for p in pathlib.Path(directory).glob('**/*')) + self.assertEqual(self.control_paths, got_paths) + + @contextmanager + def extract_with_none(self, *attr_names): + DIR = pathlib.Path(TEMPDIR) / "extractall_none" + self.tar.errorlevel = 0 + for member in self.tar.getmembers(): + for attr_name in attr_names: + setattr(member, attr_name, None) + with os_helper.temp_dir(DIR): + self.tar.extractall(DIR, filter='fully_trusted') + self.check_files_present(DIR) + yield DIR + + def test_extractall_none_mtime(self): + # mtimes of extracted files should be later than 'now' -- the mtime + # of a previously created directory. + now = pathlib.Path(TEMPDIR).stat().st_mtime + with self.extract_with_none('mtime') as DIR: + for path in pathlib.Path(DIR).glob('**/*'): + with self.subTest(path=path): + try: + mtime = path.stat().st_mtime + except OSError: + # Some systems can't stat symlinks, ignore those + if not path.is_symlink(): + raise + else: + self.assertGreaterEqual(path.stat().st_mtime, now) + + def test_extractall_none_mode(self): + # modes of directories and regular files should match the mode + # of a "normally" created directory or regular file + dir_mode = pathlib.Path(TEMPDIR).stat().st_mode + regular_file = pathlib.Path(TEMPDIR) / 'regular_file' + regular_file.write_text('') + regular_file_mode = regular_file.stat().st_mode + with self.extract_with_none('mode') as DIR: + for path in pathlib.Path(DIR).glob('**/*'): + with self.subTest(path=path): + if path.is_dir(): + self.assertEqual(path.stat().st_mode, dir_mode) + elif path.is_file(): + self.assertEqual(path.stat().st_mode, + regular_file_mode) + + def test_extractall_none_uid(self): + with self.extract_with_none('uid'): + pass + + def test_extractall_none_gid(self): + with self.extract_with_none('gid'): + pass + + def test_extractall_none_uname(self): + with self.extract_with_none('uname'): + pass + + def test_extractall_none_gname(self): + with self.extract_with_none('gname'): + pass + + def test_extractall_none_ownership(self): + with self.extract_with_none('uid', 'gid', 'uname', 'gname'): + pass + +class NoneInfoExtractTests_Data(NoneInfoExtractTests, unittest.TestCase): + extraction_filter = 'data' + +class NoneInfoExtractTests_FullyTrusted(NoneInfoExtractTests, + unittest.TestCase): + extraction_filter = 'fully_trusted' + +class NoneInfoExtractTests_Tar(NoneInfoExtractTests, unittest.TestCase): + extraction_filter = 'tar' + +class NoneInfoExtractTests_Default(NoneInfoExtractTests, + unittest.TestCase): + extraction_filter = None + +class NoneInfoTests_Misc(unittest.TestCase): + def test_add(self): + # When addfile() encounters None metadata, it raises a ValueError + bio = io.BytesIO() + for tarformat in (tarfile.USTAR_FORMAT, tarfile.GNU_FORMAT, + tarfile.PAX_FORMAT): + with self.subTest(tarformat=tarformat): + tar = tarfile.open(fileobj=bio, mode='w', format=tarformat) + tarinfo = tar.gettarinfo(tarname) + try: + tar.addfile(tarinfo) + except Exception: + if tarformat == tarfile.USTAR_FORMAT: + # In the old, limited format, adding might fail for + # reasons like the UID being too large + pass + else: + raise + else: + for attr_name in ('mtime', 'mode', 'uid', 'gid', + 'uname', 'gname'): + with self.subTest(attr_name=attr_name): + replaced = tarinfo.replace(**{attr_name: None}) + with self.assertRaisesRegex(ValueError, + f"{attr_name}"): + tar.addfile(replaced) + + def test_list(self): + # Change some metadata to None, then compare list() output + # word-for-word. We want list() to not raise, and to only change + # printout for the affected piece of metadata. + # (n.b.: some contents of the test archive are hardcoded.) + for attr_names in ({'mtime'}, {'mode'}, {'uid'}, {'gid'}, + {'uname'}, {'gname'}, + {'uid', 'uname'}, {'gid', 'gname'}): + with (self.subTest(attr_names=attr_names), + tarfile.open(tarname, encoding="iso8859-1") as tar): + tio_prev = io.TextIOWrapper(io.BytesIO(), 'ascii', newline='\n') + with support.swap_attr(sys, 'stdout', tio_prev): + tar.list() + for member in tar.getmembers(): + for attr_name in attr_names: + setattr(member, attr_name, None) + tio_new = io.TextIOWrapper(io.BytesIO(), 'ascii', newline='\n') + with support.swap_attr(sys, 'stdout', tio_new): + tar.list() + for expected, got in zip(tio_prev.detach().getvalue().split(), + tio_new.detach().getvalue().split()): + if attr_names == {'mtime'} and re.match(rb'2003-01-\d\d', expected): + self.assertEqual(got, b'????-??-??') + elif attr_names == {'mtime'} and re.match(rb'\d\d:\d\d:\d\d', expected): + self.assertEqual(got, b'??:??:??') + elif attr_names == {'mode'} and re.match( + rb'.([r-][w-][x-]){3}', expected): + self.assertEqual(got, b'??????????') + elif attr_names == {'uname'} and expected.startswith( + (b'tarfile/', b'lars/', b'foo/')): + exp_user, exp_group = expected.split(b'/') + got_user, got_group = got.split(b'/') + self.assertEqual(got_group, exp_group) + self.assertRegex(got_user, b'[0-9]+') + elif attr_names == {'gname'} and expected.endswith( + (b'/tarfile', b'/users', b'/bar')): + exp_user, exp_group = expected.split(b'/') + got_user, got_group = got.split(b'/') + self.assertEqual(got_user, exp_user) + self.assertRegex(got_group, b'[0-9]+') + elif attr_names == {'uid'} and expected.startswith( + (b'1000/')): + exp_user, exp_group = expected.split(b'/') + got_user, got_group = got.split(b'/') + self.assertEqual(got_group, exp_group) + self.assertEqual(got_user, b'None') + elif attr_names == {'gid'} and expected.endswith((b'/100')): + exp_user, exp_group = expected.split(b'/') + got_user, got_group = got.split(b'/') + self.assertEqual(got_user, exp_user) + self.assertEqual(got_group, b'None') + elif attr_names == {'uid', 'uname'} and expected.startswith( + (b'tarfile/', b'lars/', b'foo/', b'1000/')): + exp_user, exp_group = expected.split(b'/') + got_user, got_group = got.split(b'/') + self.assertEqual(got_group, exp_group) + self.assertEqual(got_user, b'None') + elif attr_names == {'gname', 'gid'} and expected.endswith( + (b'/tarfile', b'/users', b'/bar', b'/100')): + exp_user, exp_group = expected.split(b'/') + got_user, got_group = got.split(b'/') + self.assertEqual(got_user, exp_user) + self.assertEqual(got_group, b'None') + else: + # In other cases the output should be the same + self.assertEqual(expected, got) + +def _filemode_to_int(mode): + """Inverse of `stat.filemode` (for permission bits) + + Using mode strings rather than numbers makes the later tests more readable. + """ + str_mode = mode[1:] + result = ( + {'r': stat.S_IRUSR, '-': 0}[str_mode[0]] + | {'w': stat.S_IWUSR, '-': 0}[str_mode[1]] + | {'x': stat.S_IXUSR, '-': 0, + 's': stat.S_IXUSR | stat.S_ISUID, + 'S': stat.S_ISUID}[str_mode[2]] + | {'r': stat.S_IRGRP, '-': 0}[str_mode[3]] + | {'w': stat.S_IWGRP, '-': 0}[str_mode[4]] + | {'x': stat.S_IXGRP, '-': 0, + 's': stat.S_IXGRP | stat.S_ISGID, + 'S': stat.S_ISGID}[str_mode[5]] + | {'r': stat.S_IROTH, '-': 0}[str_mode[6]] + | {'w': stat.S_IWOTH, '-': 0}[str_mode[7]] + | {'x': stat.S_IXOTH, '-': 0, + 't': stat.S_IXOTH | stat.S_ISVTX, + 'T': stat.S_ISVTX}[str_mode[8]] + ) + # check we did this right + assert stat.filemode(result)[1:] == mode[1:] + + return result + +class ArchiveMaker: + """Helper to create a tar file with specific contents + + Usage: + + with ArchiveMaker() as t: + t.add('filename', ...) + + with t.open() as tar: + ... # `tar` is now a TarFile with 'filename' in it! + """ + def __init__(self): + self.bio = io.BytesIO() + + def __enter__(self): + self.tar_w = tarfile.TarFile(mode='w', fileobj=self.bio) + return self + + def __exit__(self, *exc): + self.tar_w.close() + self.contents = self.bio.getvalue() + self.bio = None + + def add(self, name, *, type=None, symlink_to=None, hardlink_to=None, + mode=None, size=None, **kwargs): + """Add a member to the test archive. Call within `with`.""" + name = str(name) + tarinfo = tarfile.TarInfo(name).replace(**kwargs) + if size is not None: + tarinfo.size = size + if mode: + tarinfo.mode = _filemode_to_int(mode) + if symlink_to is not None: + type = tarfile.SYMTYPE + tarinfo.linkname = str(symlink_to) + if hardlink_to is not None: + type = tarfile.LNKTYPE + tarinfo.linkname = str(hardlink_to) + if name.endswith('/') and type is None: + type = tarfile.DIRTYPE + if type is not None: + tarinfo.type = type + if tarinfo.isreg(): + fileobj = io.BytesIO(bytes(tarinfo.size)) + else: + fileobj = None + self.tar_w.addfile(tarinfo, fileobj) + + def open(self, **kwargs): + """Open the resulting archive as TarFile. Call after `with`.""" + bio = io.BytesIO(self.contents) + return tarfile.open(fileobj=bio, **kwargs) + +# Under WASI, `os_helper.can_symlink` is False to make +# `skip_unless_symlink` skip symlink tests. " +# But in the following tests we use can_symlink to *determine* which +# behavior is expected. +# Like other symlink tests, skip these on WASI for now. +if support.is_wasi: + def symlink_test(f): + return unittest.skip("WASI: Skip symlink test for now")(f) +else: + def symlink_test(f): + return f + + +class TestExtractionFilters(unittest.TestCase): + + # A temporary directory for the extraction results. + # All files that "escape" the destination path should still end + # up in this directory. + outerdir = pathlib.Path(TEMPDIR) / 'outerdir' + + # The destination for the extraction, within `outerdir` + destdir = outerdir / 'dest' + + @contextmanager + def check_context(self, tar, filter): + """Extracts `tar` to `self.destdir` and allows checking the result + + If an error occurs, it must be checked using `expect_exception` + + Otherwise, all resulting files must be checked using `expect_file`, + except the destination directory itself and parent directories of + other files. + When checking directories, do so before their contents. + """ + with os_helper.temp_dir(self.outerdir): + try: + tar.extractall(self.destdir, filter=filter) + except Exception as exc: + self.raised_exception = exc + self.expected_paths = set() + else: + self.raised_exception = None + self.expected_paths = set(self.outerdir.glob('**/*')) + self.expected_paths.discard(self.destdir) + try: + yield + finally: + tar.close() + if self.raised_exception: + raise self.raised_exception + self.assertEqual(self.expected_paths, set()) + + def expect_file(self, name, type=None, symlink_to=None, mode=None, + size=None): + """Check a single file. See check_context.""" + if self.raised_exception: + raise self.raised_exception + # use normpath() rather than resolve() so we don't follow symlinks + path = pathlib.Path(os.path.normpath(self.destdir / name)) + self.assertIn(path, self.expected_paths) + self.expected_paths.remove(path) + if mode is not None and os_helper.can_chmod(): + got = stat.filemode(stat.S_IMODE(path.stat().st_mode)) + self.assertEqual(got, mode) + if type is None and isinstance(name, str) and name.endswith('/'): + type = tarfile.DIRTYPE + if symlink_to is not None: + got = (self.destdir / name).readlink() + expected = pathlib.Path(symlink_to) + # The symlink might be the same (textually) as what we expect, + # but some systems change the link to an equivalent path, so + # we fall back to samefile(). + if expected != got: + self.assertTrue(got.samefile(expected)) + elif type == tarfile.REGTYPE or type is None: + self.assertTrue(path.is_file()) + elif type == tarfile.DIRTYPE: + self.assertTrue(path.is_dir()) + elif type == tarfile.FIFOTYPE: + self.assertTrue(path.is_fifo()) + else: + raise NotImplementedError(type) + if size is not None: + self.assertEqual(path.stat().st_size, size) + for parent in path.parents: + self.expected_paths.discard(parent) + + def expect_exception(self, exc_type, message_re='.'): + with self.assertRaisesRegex(exc_type, message_re): + if self.raised_exception is not None: + raise self.raised_exception + self.raised_exception = None + + def test_benign_file(self): + with ArchiveMaker() as arc: + arc.add('benign.txt') + for filter in 'fully_trusted', 'tar', 'data': + with self.check_context(arc.open(), filter): + self.expect_file('benign.txt') + + def test_absolute(self): + # Test handling a member with an absolute path + # Inspired by 'absolute1' in https://github.com/jwilk/traversal-archives + with ArchiveMaker() as arc: + arc.add(self.outerdir / 'escaped.evil') + + with self.check_context(arc.open(), 'fully_trusted'): + self.expect_file('../escaped.evil') + + for filter in 'tar', 'data': + with self.check_context(arc.open(), filter): + if str(self.outerdir).startswith('/'): + # We strip leading slashes, as e.g. GNU tar does + # (without --absolute-filenames). + outerdir_stripped = str(self.outerdir).lstrip('/') + self.expect_file(f'{outerdir_stripped}/escaped.evil') + else: + # On this system, absolute paths don't have leading + # slashes. + # So, there's nothing to strip. We refuse to unpack + # to an absolute path, nonetheless. + self.expect_exception( + tarfile.AbsolutePathError, + """['"].*escaped.evil['"] has an absolute path""") + + @symlink_test + def test_parent_symlink(self): + # Test interplaying symlinks + # Inspired by 'dirsymlink2a' in jwilk/traversal-archives + with ArchiveMaker() as arc: + + # `current` links to `.` which is both: + # - the destination directory + # - `current` itself + arc.add('current', symlink_to='.') + + # effectively points to ./../ + arc.add('parent', symlink_to='current/..') + + arc.add('parent/evil') + + if os_helper.can_symlink(): + with self.check_context(arc.open(), 'fully_trusted'): + if self.raised_exception is not None: + # Windows will refuse to create a file that's a symlink to itself + # (and tarfile doesn't swallow that exception) + self.expect_exception(FileExistsError) + # The other cases will fail with this error too. + # Skip the rest of this test. + return + else: + self.expect_file('current', symlink_to='.') + self.expect_file('parent', symlink_to='current/..') + self.expect_file('../evil') + + with self.check_context(arc.open(), 'tar'): + self.expect_exception( + tarfile.OutsideDestinationError, + """'parent/evil' would be extracted to ['"].*evil['"], """ + + "which is outside the destination") + + with self.check_context(arc.open(), 'data'): + self.expect_exception( + tarfile.LinkOutsideDestinationError, + """'parent' would link to ['"].*outerdir['"], """ + + "which is outside the destination") + + else: + # No symlink support. The symlinks are ignored. + with self.check_context(arc.open(), 'fully_trusted'): + self.expect_file('parent/evil') + with self.check_context(arc.open(), 'tar'): + self.expect_file('parent/evil') + with self.check_context(arc.open(), 'data'): + self.expect_file('parent/evil') + + @symlink_test + def test_parent_symlink2(self): + # Test interplaying symlinks + # Inspired by 'dirsymlink2b' in jwilk/traversal-archives + + # Posix and Windows have different pathname resolution: + # either symlink or a '..' component resolve first. + # Let's see which we are on. + if os_helper.can_symlink(): + testpath = os.path.join(TEMPDIR, 'resolution_test') + os.mkdir(testpath) + + # testpath/current links to `.` which is all of: + # - `testpath` + # - `testpath/current` + # - `testpath/current/current` + # - etc. + os.symlink('.', os.path.join(testpath, 'current')) + + # we'll test where `testpath/current/../file` ends up + with open(os.path.join(testpath, 'current', '..', 'file'), 'w'): + pass + + if os.path.exists(os.path.join(testpath, 'file')): + # Windows collapses 'current\..' to '.' first, leaving + # 'testpath\file' + dotdot_resolves_early = True + elif os.path.exists(os.path.join(testpath, '..', 'file')): + # Posix resolves 'current' to '.' first, leaving + # 'testpath/../file' + dotdot_resolves_early = False + else: + raise AssertionError('Could not determine link resolution') + + with ArchiveMaker() as arc: + + # `current` links to `.` which is both the destination directory + # and `current` itself + arc.add('current', symlink_to='.') + + # `current/parent` is also available as `./parent`, + # and effectively points to `./../` + arc.add('current/parent', symlink_to='..') + + arc.add('parent/evil') + + with self.check_context(arc.open(), 'fully_trusted'): + if os_helper.can_symlink(): + self.expect_file('current', symlink_to='.') + self.expect_file('parent', symlink_to='..') + self.expect_file('../evil') + else: + self.expect_file('current/') + self.expect_file('parent/evil') + + with self.check_context(arc.open(), 'tar'): + if os_helper.can_symlink(): + # Fail when extracting a file outside destination + self.expect_exception( + tarfile.OutsideDestinationError, + "'parent/evil' would be extracted to " + + """['"].*evil['"], which is outside """ + + "the destination") + else: + self.expect_file('current/') + self.expect_file('parent/evil') + + with self.check_context(arc.open(), 'data'): + if os_helper.can_symlink(): + if dotdot_resolves_early: + # Fail when extracting a file outside destination + self.expect_exception( + tarfile.OutsideDestinationError, + "'parent/evil' would be extracted to " + + """['"].*evil['"], which is outside """ + + "the destination") + else: + # Fail as soon as we have a symlink outside the destination + self.expect_exception( + tarfile.LinkOutsideDestinationError, + "'current/parent' would link to " + + """['"].*outerdir['"], which is outside """ + + "the destination") + else: + self.expect_file('current/') + self.expect_file('parent/evil') + + @symlink_test + def test_absolute_symlink(self): + # Test symlink to an absolute path + # Inspired by 'dirsymlink' in jwilk/traversal-archives + with ArchiveMaker() as arc: + arc.add('parent', symlink_to=self.outerdir) + arc.add('parent/evil') + + with self.check_context(arc.open(), 'fully_trusted'): + if os_helper.can_symlink(): + self.expect_file('parent', symlink_to=self.outerdir) + self.expect_file('../evil') + else: + self.expect_file('parent/evil') + + with self.check_context(arc.open(), 'tar'): + if os_helper.can_symlink(): + self.expect_exception( + tarfile.OutsideDestinationError, + "'parent/evil' would be extracted to " + + """['"].*evil['"], which is outside """ + + "the destination") + else: + self.expect_file('parent/evil') + + with self.check_context(arc.open(), 'data'): + self.expect_exception( + tarfile.AbsoluteLinkError, + "'parent' is a link to an absolute path") + + def test_absolute_hardlink(self): + # Test hardlink to an absolute path + # Inspired by 'dirsymlink' in https://github.com/jwilk/traversal-archives + with ArchiveMaker() as arc: + arc.add('parent', hardlink_to=self.outerdir / 'foo') + + with self.check_context(arc.open(), 'fully_trusted'): + self.expect_exception(KeyError, ".*foo. not found") + + with self.check_context(arc.open(), 'tar'): + self.expect_exception(KeyError, ".*foo. not found") + + with self.check_context(arc.open(), 'data'): + self.expect_exception( + tarfile.AbsoluteLinkError, + "'parent' is a link to an absolute path") + + @symlink_test + def test_sly_relative0(self): + # Inspired by 'relative0' in jwilk/traversal-archives + with ArchiveMaker() as arc: + # points to `../../tmp/moo` + arc.add('../moo', symlink_to='..//tmp/moo') + + try: + with self.check_context(arc.open(), filter='fully_trusted'): + if os_helper.can_symlink(): + if isinstance(self.raised_exception, FileExistsError): + # XXX TarFile happens to fail creating a parent + # directory. + # This might be a bug, but fixing it would hurt + # security. + # Note that e.g. GNU `tar` rejects '..' components, + # so you could argue this is an invalid archive and we + # just raise an bad type of exception. + self.expect_exception(FileExistsError) + else: + self.expect_file('../moo', symlink_to='..//tmp/moo') + else: + # The symlink can't be extracted and is ignored + pass + except FileExistsError: + pass + + for filter in 'tar', 'data': + with self.check_context(arc.open(), filter): + self.expect_exception( + tarfile.OutsideDestinationError, + "'../moo' would be extracted to " + + "'.*moo', which is outside " + + "the destination") + + @symlink_test + def test_sly_relative2(self): + # Inspired by 'relative2' in jwilk/traversal-archives + with ArchiveMaker() as arc: + arc.add('tmp/') + arc.add('tmp/../../moo', symlink_to='tmp/../..//tmp/moo') + + with self.check_context(arc.open(), 'fully_trusted'): + self.expect_file('tmp', type=tarfile.DIRTYPE) + if os_helper.can_symlink(): + self.expect_file('../moo', symlink_to='tmp/../../tmp/moo') + + for filter in 'tar', 'data': + with self.check_context(arc.open(), filter): + self.expect_exception( + tarfile.OutsideDestinationError, + "'tmp/../../moo' would be extracted to " + + """['"].*moo['"], which is outside the """ + + "destination") + + @symlink_test + def test_deep_symlink(self): + # Test that symlinks and hardlinks inside a directory + # point to the correct file (`target` of size 3). + # If links aren't supported we get a copy of the file. + with ArchiveMaker() as arc: + arc.add('targetdir/target', size=3) + # a hardlink's linkname is relative to the archive + arc.add('linkdir/hardlink', hardlink_to=os.path.join( + 'targetdir', 'target')) + # a symlink's linkname is relative to the link's directory + arc.add('linkdir/symlink', symlink_to=os.path.join( + '..', 'targetdir', 'target')) + + for filter in 'tar', 'data', 'fully_trusted': + with self.check_context(arc.open(), filter): + self.expect_file('targetdir/target', size=3) + self.expect_file('linkdir/hardlink', size=3) + if os_helper.can_symlink(): + self.expect_file('linkdir/symlink', size=3, + symlink_to='../targetdir/target') + else: + self.expect_file('linkdir/symlink', size=3) + + @symlink_test + def test_chains(self): + # Test chaining of symlinks/hardlinks. + # Symlinks are created before the files they point to. + with ArchiveMaker() as arc: + arc.add('linkdir/symlink', symlink_to='hardlink') + arc.add('symlink2', symlink_to=os.path.join( + 'linkdir', 'hardlink2')) + arc.add('targetdir/target', size=3) + arc.add('linkdir/hardlink', hardlink_to='targetdir/target') + arc.add('linkdir/hardlink2', hardlink_to='linkdir/symlink') + + for filter in 'tar', 'data', 'fully_trusted': + with self.check_context(arc.open(), filter): + self.expect_file('targetdir/target', size=3) + self.expect_file('linkdir/hardlink', size=3) + self.expect_file('linkdir/hardlink2', size=3) + if os_helper.can_symlink(): + self.expect_file('linkdir/symlink', size=3, + symlink_to='hardlink') + self.expect_file('symlink2', size=3, + symlink_to='linkdir/hardlink2') + else: + self.expect_file('linkdir/symlink', size=3) + self.expect_file('symlink2', size=3) + + def test_modes(self): + # Test how file modes are extracted + # (Note that the modes are ignored on platforms without working chmod) + with ArchiveMaker() as arc: + arc.add('all_bits', mode='?rwsrwsrwt') + arc.add('perm_bits', mode='?rwxrwxrwx') + arc.add('exec_group_other', mode='?rw-rwxrwx') + arc.add('read_group_only', mode='?---r-----') + arc.add('no_bits', mode='?---------') + arc.add('dir/', mode='?---rwsrwt') + + # On some systems, setting the sticky bit is a no-op. + # Check if that's the case. + tmp_filename = os.path.join(TEMPDIR, "tmp.file") + with open(tmp_filename, 'w'): + pass + os.chmod(tmp_filename, os.stat(tmp_filename).st_mode | stat.S_ISVTX) + have_sticky_files = (os.stat(tmp_filename).st_mode & stat.S_ISVTX) + os.unlink(tmp_filename) + + os.mkdir(tmp_filename) + os.chmod(tmp_filename, os.stat(tmp_filename).st_mode | stat.S_ISVTX) + have_sticky_dirs = (os.stat(tmp_filename).st_mode & stat.S_ISVTX) + os.rmdir(tmp_filename) + + with self.check_context(arc.open(), 'fully_trusted'): + if have_sticky_files: + self.expect_file('all_bits', mode='?rwsrwsrwt') + else: + self.expect_file('all_bits', mode='?rwsrwsrwx') + self.expect_file('perm_bits', mode='?rwxrwxrwx') + self.expect_file('exec_group_other', mode='?rw-rwxrwx') + self.expect_file('read_group_only', mode='?---r-----') + self.expect_file('no_bits', mode='?---------') + if have_sticky_dirs: + self.expect_file('dir/', mode='?---rwsrwt') + else: + self.expect_file('dir/', mode='?---rwsrwx') + + with self.check_context(arc.open(), 'tar'): + self.expect_file('all_bits', mode='?rwxr-xr-x') + self.expect_file('perm_bits', mode='?rwxr-xr-x') + self.expect_file('exec_group_other', mode='?rw-r-xr-x') + self.expect_file('read_group_only', mode='?---r-----') + self.expect_file('no_bits', mode='?---------') + self.expect_file('dir/', mode='?---r-xr-x') + + with self.check_context(arc.open(), 'data'): + normal_dir_mode = stat.filemode(stat.S_IMODE( + self.outerdir.stat().st_mode)) + self.expect_file('all_bits', mode='?rwxr-xr-x') + self.expect_file('perm_bits', mode='?rwxr-xr-x') + self.expect_file('exec_group_other', mode='?rw-r--r--') + self.expect_file('read_group_only', mode='?rw-r-----') + self.expect_file('no_bits', mode='?rw-------') + self.expect_file('dir/', mode=normal_dir_mode) + + def test_pipe(self): + # Test handling of a special file + with ArchiveMaker() as arc: + arc.add('foo', type=tarfile.FIFOTYPE) + + for filter in 'fully_trusted', 'tar': + with self.check_context(arc.open(), filter): + if hasattr(os, 'mkfifo'): + self.expect_file('foo', type=tarfile.FIFOTYPE) + else: + # The pipe can't be extracted and is skipped. + pass + + with self.check_context(arc.open(), 'data'): + self.expect_exception( + tarfile.SpecialFileError, + "'foo' is a special file") + + def test_special_files(self): + # Creating device files is tricky. Instead of attempting that let's + # only check the filter result. + for special_type in tarfile.FIFOTYPE, tarfile.CHRTYPE, tarfile.BLKTYPE: + tarinfo = tarfile.TarInfo('foo') + tarinfo.type = special_type + trusted = tarfile.fully_trusted_filter(tarinfo, '') + self.assertIs(trusted, tarinfo) + tar = tarfile.tar_filter(tarinfo, '') + self.assertEqual(tar.type, special_type) + with self.assertRaises(tarfile.SpecialFileError) as cm: + tarfile.data_filter(tarinfo, '') + self.assertIsInstance(cm.exception.tarinfo, tarfile.TarInfo) + self.assertEqual(cm.exception.tarinfo.name, 'foo') + + def test_fully_trusted_filter(self): + # The 'fully_trusted' filter returns the original TarInfo objects. + with tarfile.TarFile.open(tarname) as tar: + for tarinfo in tar.getmembers(): + filtered = tarfile.fully_trusted_filter(tarinfo, '') + self.assertIs(filtered, tarinfo) + + def test_tar_filter(self): + # The 'tar' filter returns TarInfo objects with the same name/type. + # (It can also fail for particularly "evil" input, but we don't have + # that in the test archive.) + with tarfile.TarFile.open(tarname) as tar: + for tarinfo in tar.getmembers(): + filtered = tarfile.tar_filter(tarinfo, '') + self.assertIs(filtered.name, tarinfo.name) + self.assertIs(filtered.type, tarinfo.type) + + def test_data_filter(self): + # The 'data' filter either raises, or returns TarInfo with the same + # name/type. + with tarfile.TarFile.open(tarname) as tar: + for tarinfo in tar.getmembers(): + try: + filtered = tarfile.data_filter(tarinfo, '') + except tarfile.FilterError: + continue + self.assertIs(filtered.name, tarinfo.name) + self.assertIs(filtered.type, tarinfo.type) + + def test_default_filter_warns(self): + """Ensure the default filter warns""" + with ArchiveMaker() as arc: + arc.add('foo') + with warnings_helper.check_warnings( + ('Python 3.14', DeprecationWarning)): + with self.check_context(arc.open(), None): + self.expect_file('foo') + + def test_change_default_filter_on_instance(self): + tar = tarfile.TarFile(tarname, 'r') + def strict_filter(tarinfo, path): + if tarinfo.name == 'ustar/regtype': + return tarinfo + else: + return None + tar.extraction_filter = strict_filter + with self.check_context(tar, None): + self.expect_file('ustar/regtype') + + def test_change_default_filter_on_class(self): + def strict_filter(tarinfo, path): + if tarinfo.name == 'ustar/regtype': + return tarinfo + else: + return None + tar = tarfile.TarFile(tarname, 'r') + with support.swap_attr(tarfile.TarFile, 'extraction_filter', + staticmethod(strict_filter)): + with self.check_context(tar, None): + self.expect_file('ustar/regtype') + + def test_change_default_filter_on_subclass(self): + class TarSubclass(tarfile.TarFile): + def extraction_filter(self, tarinfo, path): + if tarinfo.name == 'ustar/regtype': + return tarinfo + else: + return None + + tar = TarSubclass(tarname, 'r') + with self.check_context(tar, None): + self.expect_file('ustar/regtype') + + def test_change_default_filter_to_string(self): + tar = tarfile.TarFile(tarname, 'r') + tar.extraction_filter = 'data' + with self.check_context(tar, None): + self.expect_exception(TypeError) + + def test_custom_filter(self): + def custom_filter(tarinfo, path): + self.assertIs(path, self.destdir) + if tarinfo.name == 'move_this': + return tarinfo.replace(name='moved') + if tarinfo.name == 'ignore_this': + return None + return tarinfo + + with ArchiveMaker() as arc: + arc.add('move_this') + arc.add('ignore_this') + arc.add('keep') + with self.check_context(arc.open(), custom_filter): + self.expect_file('moved') + self.expect_file('keep') + + def test_bad_filter_name(self): + with ArchiveMaker() as arc: + arc.add('foo') + with self.check_context(arc.open(), 'bad filter name'): + self.expect_exception(ValueError) + + def test_stateful_filter(self): + # Stateful filters should be possible. + # (This doesn't really test tarfile. Rather, it demonstrates + # that third parties can implement a stateful filter.) + class StatefulFilter: + def __enter__(self): + self.num_files_processed = 0 + return self + + def __call__(self, tarinfo, path): + try: + tarinfo = tarfile.data_filter(tarinfo, path) + except tarfile.FilterError: + return None + self.num_files_processed += 1 + return tarinfo + + def __exit__(self, *exc_info): + self.done = True + + with ArchiveMaker() as arc: + arc.add('good') + arc.add('bad', symlink_to='/') + arc.add('good') + with StatefulFilter() as custom_filter: + with self.check_context(arc.open(), custom_filter): + self.expect_file('good') + self.assertEqual(custom_filter.num_files_processed, 2) + self.assertEqual(custom_filter.done, True) + + def test_errorlevel(self): + def extracterror_filter(tarinfo, path): + raise tarfile.ExtractError('failed with ExtractError') + def filtererror_filter(tarinfo, path): + raise tarfile.FilterError('failed with FilterError') + def oserror_filter(tarinfo, path): + raise OSError('failed with OSError') + def tarerror_filter(tarinfo, path): + raise tarfile.TarError('failed with base TarError') + def valueerror_filter(tarinfo, path): + raise ValueError('failed with ValueError') + + with ArchiveMaker() as arc: + arc.add('file') + + # If errorlevel is 0, errors affected by errorlevel are ignored + + with self.check_context(arc.open(errorlevel=0), extracterror_filter): + self.expect_file('file') + + with self.check_context(arc.open(errorlevel=0), filtererror_filter): + self.expect_file('file') + + with self.check_context(arc.open(errorlevel=0), oserror_filter): + self.expect_file('file') + + with self.check_context(arc.open(errorlevel=0), tarerror_filter): + self.expect_exception(tarfile.TarError) + + with self.check_context(arc.open(errorlevel=0), valueerror_filter): + self.expect_exception(ValueError) + + # If 1, all fatal errors are raised + + with self.check_context(arc.open(errorlevel=1), extracterror_filter): + self.expect_file('file') + + with self.check_context(arc.open(errorlevel=1), filtererror_filter): + self.expect_exception(tarfile.FilterError) + + with self.check_context(arc.open(errorlevel=1), oserror_filter): + self.expect_exception(OSError) + + with self.check_context(arc.open(errorlevel=1), tarerror_filter): + self.expect_exception(tarfile.TarError) + + with self.check_context(arc.open(errorlevel=1), valueerror_filter): + self.expect_exception(ValueError) + + # If 2, all non-fatal errors are raised as well. + + with self.check_context(arc.open(errorlevel=2), extracterror_filter): + self.expect_exception(tarfile.ExtractError) + + with self.check_context(arc.open(errorlevel=2), filtererror_filter): + self.expect_exception(tarfile.FilterError) + + with self.check_context(arc.open(errorlevel=2), oserror_filter): + self.expect_exception(OSError) + + with self.check_context(arc.open(errorlevel=2), tarerror_filter): + self.expect_exception(tarfile.TarError) + + with self.check_context(arc.open(errorlevel=2), valueerror_filter): + self.expect_exception(ValueError) + + # We only handle ExtractionError, FilterError & OSError specially. + + with self.check_context(arc.open(errorlevel='boo!'), filtererror_filter): + self.expect_exception(TypeError) # errorlevel is not int + + def setUpModule(): os_helper.unlink(TEMPDIR) os.makedirs(TEMPDIR) diff --git a/Lib/test/test_tcl.py b/Lib/test/test_tcl.py index 54891479..ebdb58f9 100644 --- a/Lib/test/test_tcl.py +++ b/Lib/test/test_tcl.py @@ -1,10 +1,7 @@ import unittest -import locale -import re import subprocess import sys import os -import warnings from test import support from test.support import import_helper from test.support import os_helper @@ -23,14 +20,6 @@ except ImportError: tcl_version = tuple(map(int, _tkinter.TCL_VERSION.split('.'))) -_tk_patchlevel = None -def get_tk_patchlevel(): - global _tk_patchlevel - if _tk_patchlevel is None: - tcl = Tcl() - _tk_patchlevel = tcl.info_patchlevel() - return _tk_patchlevel - class TkinterTest(unittest.TestCase): @@ -145,7 +134,10 @@ class TclTest(unittest.TestCase): for i in self.get_integers(): self.assertEqual(tcl.getint(' %d ' % i), i) self.assertEqual(tcl.getint(' %#o ' % i), i) - self.assertEqual(tcl.getint((' %#o ' % i).replace('o', '')), i) + # Numbers starting with 0 are parsed as decimal in Tcl 9.0 + # and as octal in older versions. + self.assertEqual(tcl.getint((' %#o ' % i).replace('o', '')), + i if tcl_version < (9, 0) else int('%o' % i)) self.assertEqual(tcl.getint(' %#x ' % i), i) self.assertEqual(tcl.getint(42), 42) self.assertRaises(TypeError, tcl.getint) @@ -571,7 +563,6 @@ class TclTest(unittest.TestCase): (1, '2', (3.4,)) if self.wantobjects else ('1', '2', '3.4')), ] - tk_patchlevel = get_tk_patchlevel() if not self.wantobjects: expected = ('12', '\u20ac', '\xe2\x82\xac', '3.4') else: @@ -580,8 +571,8 @@ class TclTest(unittest.TestCase): (call('dict', 'create', 12, '\u20ac', b'\xe2\x82\xac', (3.4,)), expected), ] - dbg_info = ('want objects? %s, Tcl version: %s, Tk patchlevel: %s' - % (self.wantobjects, tcl_version, tk_patchlevel)) + dbg_info = ('want objects? %s, Tcl version: %s, Tcl patchlevel: %s' + % (self.wantobjects, tcl_version, self.interp.info_patchlevel())) for arg, res in testcases: self.assertEqual(splitlist(arg), res, 'arg=%a, %s' % (arg, dbg_info)) diff --git a/Lib/test/test_tempfile.py b/Lib/test/test_tempfile.py index ccf7ea07..1673507e 100644 --- a/Lib/test/test_tempfile.py +++ b/Lib/test/test_tempfile.py @@ -11,6 +11,8 @@ import contextlib import stat import types import weakref +import gc +import shutil from unittest import mock import unittest @@ -848,6 +850,15 @@ class TestMkdtemp(TestBadTempdir, BaseTestCase): finally: tempfile.tempdir = orig_tempdir + def test_path_is_absolute(self): + # Test that the path returned by mkdtemp with a relative `dir` + # argument is absolute + try: + path = tempfile.mkdtemp(dir=".") + self.assertTrue(os.path.isabs(path)) + finally: + os.rmdir(path) + class TestMktemp(BaseTestCase): """Test mktemp().""" @@ -1013,6 +1024,102 @@ class TestNamedTemporaryFile(BaseTestCase): pass self.assertRaises(ValueError, use_closed) + def test_context_man_not_del_on_close_if_delete_on_close_false(self): + # Issue gh-58451: tempfile.NamedTemporaryFile is not particularly useful + # on Windows + # A NamedTemporaryFile is NOT deleted when closed if + # delete_on_close=False, but is deleted on context manager exit + dir = tempfile.mkdtemp() + try: + with tempfile.NamedTemporaryFile(dir=dir, + delete=True, + delete_on_close=False) as f: + f.write(b'blat') + f_name = f.name + f.close() + with self.subTest(): + # Testing that file is not deleted on close + self.assertTrue(os.path.exists(f.name), + f"NamedTemporaryFile {f.name!r} is incorrectly " + f"deleted on closure when delete_on_close=False") + + with self.subTest(): + # Testing that file is deleted on context manager exit + self.assertFalse(os.path.exists(f.name), + f"NamedTemporaryFile {f.name!r} exists " + f"after context manager exit") + + finally: + os.rmdir(dir) + + def test_context_man_ok_to_delete_manually(self): + # In the case of delete=True, a NamedTemporaryFile can be manually + # deleted in a with-statement context without causing an error. + dir = tempfile.mkdtemp() + try: + with tempfile.NamedTemporaryFile(dir=dir, + delete=True, + delete_on_close=False) as f: + f.write(b'blat') + f.close() + os.unlink(f.name) + + finally: + os.rmdir(dir) + + def test_context_man_not_del_if_delete_false(self): + # A NamedTemporaryFile is not deleted if delete = False + dir = tempfile.mkdtemp() + f_name = "" + try: + # Test that delete_on_close=True has no effect if delete=False. + with tempfile.NamedTemporaryFile(dir=dir, delete=False, + delete_on_close=True) as f: + f.write(b'blat') + f_name = f.name + self.assertTrue(os.path.exists(f.name), + f"NamedTemporaryFile {f.name!r} exists after close") + finally: + os.unlink(f_name) + os.rmdir(dir) + + def test_del_by_finalizer(self): + # A NamedTemporaryFile is deleted when finalized in the case of + # delete=True, delete_on_close=False, and no with-statement is used. + def my_func(dir): + f = tempfile.NamedTemporaryFile(dir=dir, delete=True, + delete_on_close=False) + tmp_name = f.name + f.write(b'blat') + # Testing extreme case, where the file is not explicitly closed + # f.close() + return tmp_name + # Make sure that the garbage collector has finalized the file object. + gc.collect() + dir = tempfile.mkdtemp() + try: + tmp_name = my_func(dir) + self.assertFalse(os.path.exists(tmp_name), + f"NamedTemporaryFile {tmp_name!r} " + f"exists after finalizer ") + finally: + os.rmdir(dir) + + def test_correct_finalizer_work_if_already_deleted(self): + # There should be no error in the case of delete=True, + # delete_on_close=False, no with-statement is used, and the file is + # deleted manually. + def my_func(dir)->str: + f = tempfile.NamedTemporaryFile(dir=dir, delete=True, + delete_on_close=False) + tmp_name = f.name + f.write(b'blat') + f.close() + os.unlink(tmp_name) + return tmp_name + # Make sure that the garbage collector has finalized the file object. + gc.collect() + def test_bad_mode(self): dir = tempfile.mkdtemp() self.addCleanup(os_helper.rmtree, dir) @@ -1081,7 +1188,8 @@ class TestSpooledTemporaryFile(BaseTestCase): missing_attrs = iobase_attrs - spooledtempfile_attrs self.assertFalse( missing_attrs, - 'SpooledTemporaryFile missing attributes from IOBase/BufferedIOBase/TextIOBase' + 'SpooledTemporaryFile missing attributes from ' + 'IOBase/BufferedIOBase/TextIOBase' ) def test_del_on_close(self): @@ -1509,7 +1617,7 @@ class TestTemporaryDirectory(BaseTestCase): finally: os.rmdir(dir) - def test_explict_cleanup_ignore_errors(self): + def test_explicit_cleanup_ignore_errors(self): """Test that cleanup doesn't return an error when ignoring them.""" with tempfile.TemporaryDirectory() as working_dir: temp_dir = self.do_create( @@ -1726,9 +1834,25 @@ class TestTemporaryDirectory(BaseTestCase): d.cleanup() self.assertFalse(os.path.exists(d.name)) - @unittest.skipUnless(hasattr(os, 'chflags'), 'requires os.lchflags') + @unittest.skipUnless(hasattr(os, 'chflags'), 'requires os.chflags') def test_flags(self): flags = stat.UF_IMMUTABLE | stat.UF_NOUNLINK + + # skip the test if these flags are not supported (ex: FreeBSD 13) + filename = os_helper.TESTFN + try: + open(filename, "w").close() + try: + os.chflags(filename, flags) + except OSError as exc: + # "OSError: [Errno 45] Operation not supported" + self.skipTest(f"chflags() doesn't support " + f"UF_IMMUTABLE|UF_NOUNLINK: {exc}") + else: + os.chflags(filename, 0) + finally: + os_helper.unlink(filename) + d = self.do_create(recurse=3, dirs=2, files=2) with d: # Change files and directories flags recursively. @@ -1739,6 +1863,11 @@ class TestTemporaryDirectory(BaseTestCase): d.cleanup() self.assertFalse(os.path.exists(d.name)) + def test_delete_false(self): + with tempfile.TemporaryDirectory(delete=False) as working_dir: + pass + self.assertTrue(os.path.exists(working_dir)) + shutil.rmtree(working_dir) if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_thread.py b/Lib/test/test_thread.py index ed527e71..8656fbdd 100644 --- a/Lib/test/test_thread.py +++ b/Lib/test/test_thread.py @@ -5,6 +5,7 @@ from test import support from test.support import threading_helper import _thread as thread import time +import warnings import weakref from test import lock_tests @@ -13,7 +14,6 @@ threading_helper.requires_working_threading(module=True) NUMTASKS = 10 NUMTRIPS = 3 -POLL_SLEEP = 0.010 # seconds = 10 ms _print_mutex = thread.allocate_lock() @@ -121,19 +121,24 @@ class ThreadRunningTests(BasicThreadTest): with threading_helper.wait_threads_exit(): thread.start_new_thread(task, ()) - while not started: - time.sleep(POLL_SLEEP) + for _ in support.sleeping_retry(support.LONG_TIMEOUT): + if started: + break self.assertEqual(thread._count(), orig + 1) + # Allow the task to finish. mut.release() + # The only reliable way to be sure that the thread ended from the - # interpreter's point of view is to wait for the function object to be - # destroyed. + # interpreter's point of view is to wait for the function object to + # be destroyed. done = [] wr = weakref.ref(task, lambda _: done.append(None)) del task - while not done: - time.sleep(POLL_SLEEP) + + for _ in support.sleeping_retry(support.LONG_TIMEOUT): + if done: + break support.gc_collect() # For PyPy or other GCs. self.assertEqual(thread._count(), orig) @@ -234,11 +239,13 @@ class TestForkInThread(unittest.TestCase): def fork_thread(read_fd, write_fd): nonlocal pid - # fork in a thread - pid = os.fork() - if pid: - # parent process - return + # Ignore the warning about fork with threads. + with warnings.catch_warnings(category=DeprecationWarning, + action="ignore"): + # fork in a thread (DANGER, undefined per POSIX) + if (pid := os.fork()): + # parent process + return # child process try: diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py index 9c6561c0..9e4972ec 100644 --- a/Lib/test/test_threading.py +++ b/Lib/test/test_threading.py @@ -20,6 +20,7 @@ import subprocess import signal import textwrap import traceback +import warnings from unittest import mock from test import lock_tests @@ -33,9 +34,6 @@ threading_helper.requires_working_threading(module=True) # on platforms known to behave badly. platforms_to_skip = ('netbsd5', 'hp-ux11') -# Is Python built with Py_DEBUG macro defined? -Py_DEBUG = hasattr(sys, 'gettotalrefcount') - def restore_default_excepthook(testcase): testcase.addCleanup(setattr, threading, 'excepthook', threading.excepthook) @@ -533,40 +531,12 @@ class ThreadTests(BaseTestCase): t = threading.Thread(daemon=True) self.assertTrue(t.daemon) - @support.requires_fork() - def test_fork_at_exit(self): - # bpo-42350: Calling os.fork() after threading._shutdown() must - # not log an error. - code = textwrap.dedent(""" - import atexit - import os - import sys - from test.support import wait_process - - # Import the threading module to register its "at fork" callback - import threading - - def exit_handler(): - pid = os.fork() - if not pid: - print("child process ok", file=sys.stderr, flush=True) - # child process - else: - wait_process(pid, exitcode=0) - - # exit_handler() will be called after threading._shutdown() - atexit.register(exit_handler) - """) - _, out, err = assert_python_ok("-c", code) - self.assertEqual(out, b'') - self.assertEqual(err.rstrip(), b'child process ok') - @support.requires_fork() def test_dummy_thread_after_fork(self): # Issue #14308: a dummy thread in the active list doesn't mess up # the after-fork mechanism. code = """if 1: - import _thread, threading, os, time + import _thread, threading, os, time, warnings def background_thread(evt): # Creates and registers the _DummyThread instance @@ -578,11 +548,16 @@ class ThreadTests(BaseTestCase): _thread.start_new_thread(background_thread, (evt,)) evt.wait() assert threading.active_count() == 2, threading.active_count() - if os.fork() == 0: - assert threading.active_count() == 1, threading.active_count() - os._exit(0) - else: - os.wait() + with warnings.catch_warnings(record=True) as ws: + warnings.filterwarnings( + "always", category=DeprecationWarning) + if os.fork() == 0: + assert threading.active_count() == 1, threading.active_count() + os._exit(0) + else: + assert ws[0].category == DeprecationWarning, ws[0] + assert 'fork' in str(ws[0].message), ws[0] + os.wait() """ _, out, err = assert_python_ok("-c", code) self.assertEqual(out, b'') @@ -601,13 +576,15 @@ class ThreadTests(BaseTestCase): for i in range(20): t = threading.Thread(target=lambda: None) t.start() - pid = os.fork() - if pid == 0: - os._exit(11 if t.is_alive() else 10) - else: - t.join() + # Ignore the warning about fork with threads. + with warnings.catch_warnings(category=DeprecationWarning, + action="ignore"): + if (pid := os.fork()) == 0: + os._exit(11 if t.is_alive() else 10) + else: + t.join() - support.wait_process(pid, exitcode=10) + support.wait_process(pid, exitcode=10) def test_main_thread(self): main = threading.main_thread() @@ -648,21 +625,26 @@ class ThreadTests(BaseTestCase): @unittest.skipUnless(hasattr(os, 'waitpid'), "test needs os.waitpid()") def test_main_thread_after_fork_from_nonmain_thread(self): code = """if 1: - import os, threading, sys + import os, threading, sys, warnings from test import support def func(): - pid = os.fork() - if pid == 0: - main = threading.main_thread() - print(main.name) - print(main.ident == threading.current_thread().ident) - print(main.ident == threading.get_ident()) - # stdout is fully buffered because not a tty, - # we have to flush before exit. - sys.stdout.flush() - else: - support.wait_process(pid, exitcode=0) + with warnings.catch_warnings(record=True) as ws: + warnings.filterwarnings( + "always", category=DeprecationWarning) + pid = os.fork() + if pid == 0: + main = threading.main_thread() + print(main.name) + print(main.ident == threading.current_thread().ident) + print(main.ident == threading.get_ident()) + # stdout is fully buffered because not a tty, + # we have to flush before exit. + sys.stdout.flush() + else: + assert ws[0].category == DeprecationWarning, ws[0] + assert 'fork' in str(ws[0].message), ws[0] + support.wait_process(pid, exitcode=0) th = threading.Thread(target=func) th.start() @@ -670,7 +652,7 @@ class ThreadTests(BaseTestCase): """ _, out, err = assert_python_ok("-c", code) data = out.decode().replace('\r', '') - self.assertEqual(err, b"") + self.assertEqual(err.decode('utf-8'), "") self.assertEqual(data, "Thread-1 (func)\nTrue\nTrue\n") def test_main_thread_during_shutdown(self): @@ -856,6 +838,7 @@ class ThreadTests(BaseTestCase): callback() finally: sys.settrace(old_trace) + threading.settrace(old_trace) def test_gettrace(self): def noop_trace(frame, event, arg): @@ -869,6 +852,35 @@ class ThreadTests(BaseTestCase): finally: threading.settrace(old_trace) + def test_gettrace_all_threads(self): + def fn(*args): pass + old_trace = threading.gettrace() + first_check = threading.Event() + second_check = threading.Event() + + trace_funcs = [] + def checker(): + trace_funcs.append(sys.gettrace()) + first_check.set() + second_check.wait() + trace_funcs.append(sys.gettrace()) + + try: + t = threading.Thread(target=checker) + t.start() + first_check.wait() + threading.settrace_all_threads(fn) + second_check.set() + t.join() + self.assertEqual(trace_funcs, [None, fn]) + self.assertEqual(threading.gettrace(), fn) + self.assertEqual(sys.gettrace(), fn) + finally: + threading.settrace_all_threads(old_trace) + + self.assertEqual(threading.gettrace(), old_trace) + self.assertEqual(sys.gettrace(), old_trace) + def test_getprofile(self): def fn(*args): pass old_profile = threading.getprofile() @@ -878,6 +890,35 @@ class ThreadTests(BaseTestCase): finally: threading.setprofile(old_profile) + def test_getprofile_all_threads(self): + def fn(*args): pass + old_profile = threading.getprofile() + first_check = threading.Event() + second_check = threading.Event() + + profile_funcs = [] + def checker(): + profile_funcs.append(sys.getprofile()) + first_check.set() + second_check.wait() + profile_funcs.append(sys.getprofile()) + + try: + t = threading.Thread(target=checker) + t.start() + first_check.wait() + threading.setprofile_all_threads(fn) + second_check.set() + t.join() + self.assertEqual(profile_funcs, [None, fn]) + self.assertEqual(threading.getprofile(), fn) + self.assertEqual(sys.getprofile(), fn) + finally: + threading.setprofile_all_threads(old_profile) + + self.assertEqual(threading.getprofile(), old_profile) + self.assertEqual(sys.getprofile(), old_profile) + @cpython_only def test_shutdown_locks(self): for daemon in (False, True): @@ -946,16 +987,6 @@ class ThreadTests(BaseTestCase): threading.Thread(target=noop).start() # Thread.join() is not called - @unittest.skipUnless(Py_DEBUG, 'need debug build (Py_DEBUG)') - def test_debug_deprecation(self): - # bpo-44584: The PYTHONTHREADDEBUG environment variable is deprecated - rc, out, err = assert_python_ok("-Wdefault", "-c", "pass", - PYTHONTHREADDEBUG="1") - msg = (b'DeprecationWarning: The threading debug ' - b'(PYTHONTHREADDEBUG environment variable) ' - b'is deprecated and will be removed in Python 3.12') - self.assertIn(msg, err) - def test_import_from_another_thread(self): # bpo-1596321: If the threading module is first import from a thread # different than the main thread, threading._shutdown() must handle @@ -989,6 +1020,22 @@ class ThreadTests(BaseTestCase): self.assertEqual(out, b'') self.assertEqual(err, b'') + def test_start_new_thread_at_exit(self): + code = """if 1: + import atexit + import _thread + + def f(): + print("shouldn't be printed") + + def exit_handler(): + _thread.start_new_thread(f, ()) + + atexit.register(exit_handler) + """ + _, out, err = assert_python_ok("-c", code) + self.assertEqual(out, b'') + self.assertIn(b"can't create new thread at interpreter shutdown", err) class ThreadJoinOnShutdown(BaseTestCase): @@ -1127,15 +1174,18 @@ class ThreadJoinOnShutdown(BaseTestCase): else: os._exit(50) - # start a bunch of threads that will fork() child processes - threads = [] - for i in range(16): - t = threading.Thread(target=do_fork_and_wait) - threads.append(t) - t.start() + # Ignore the warning about fork with threads. + with warnings.catch_warnings(category=DeprecationWarning, + action="ignore"): + # start a bunch of threads that will fork() child processes + threads = [] + for i in range(16): + t = threading.Thread(target=do_fork_and_wait) + threads.append(t) + t.start() - for t in threads: - t.join() + for t in threads: + t.join() @support.requires_fork() def test_clear_threads_states_after_fork(self): @@ -1148,18 +1198,22 @@ class ThreadJoinOnShutdown(BaseTestCase): threads.append(t) t.start() - pid = os.fork() - if pid == 0: - # check that threads states have been cleared - if len(sys._current_frames()) == 1: - os._exit(51) - else: - os._exit(52) - else: - support.wait_process(pid, exitcode=51) - - for t in threads: - t.join() + try: + # Ignore the warning about fork with threads. + with warnings.catch_warnings(category=DeprecationWarning, + action="ignore"): + pid = os.fork() + if pid == 0: + # check that threads states have been cleared + if len(sys._current_frames()) == 1: + os._exit(51) + else: + os._exit(52) + else: + support.wait_process(pid, exitcode=51) + finally: + for t in threads: + t.join() class SubinterpThreadingTests(BaseTestCase): @@ -1259,6 +1313,65 @@ class SubinterpThreadingTests(BaseTestCase): self.assertIn("Fatal Python error: Py_EndInterpreter: " "not the last thread", err.decode()) + def _check_allowed(self, before_start='', *, + allowed=True, + daemon_allowed=True, + daemon=False, + ): + subinterp_code = textwrap.dedent(f""" + import test.support + import threading + def func(): + print('this should not have run!') + t = threading.Thread(target=func, daemon={daemon}) + {before_start} + t.start() + """) + script = textwrap.dedent(f""" + import test.support + test.support.run_in_subinterp_with_config( + {subinterp_code!r}, + use_main_obmalloc=True, + allow_fork=True, + allow_exec=True, + allow_threads={allowed}, + allow_daemon_threads={daemon_allowed}, + check_multi_interp_extensions=False, + own_gil=False, + ) + """) + with test.support.SuppressCrashReport(): + _, _, err = assert_python_ok("-c", script) + return err.decode() + + @cpython_only + def test_threads_not_allowed(self): + err = self._check_allowed( + allowed=False, + daemon_allowed=False, + daemon=False, + ) + self.assertIn('RuntimeError', err) + + @cpython_only + def test_daemon_threads_not_allowed(self): + with self.subTest('via Thread()'): + err = self._check_allowed( + allowed=True, + daemon_allowed=False, + daemon=True, + ) + self.assertIn('RuntimeError', err) + + with self.subTest('via Thread.daemon setter'): + err = self._check_allowed( + 't.daemon = True', + allowed=True, + daemon_allowed=False, + daemon=False, + ) + self.assertIn('RuntimeError', err) + class ThreadingExceptionTests(BaseTestCase): # A RuntimeError should be raised if Thread.start() is called @@ -1400,6 +1513,37 @@ class ThreadingExceptionTests(BaseTestCase): self.assertEqual(out, b'') self.assertNotIn("Unhandled exception", err.decode()) + def test_print_exception_gh_102056(self): + # This used to crash. See gh-102056. + script = r"""if True: + import time + import threading + import _thread + + def f(): + try: + f() + except RecursionError: + f() + + def g(): + try: + raise ValueError() + except* ValueError: + f() + + def h(): + time.sleep(1) + _thread.interrupt_main() + + t = threading.Thread(target=h) + t.start() + g() + t.join() + """ + + assert_python_failure("-c", script) + def test_bare_raise_in_brand_new_thread(self): def bare_raise(): raise diff --git a/Lib/test/test_threading_local.py b/Lib/test/test_threading_local.py index 65d9fed7..f0b829a9 100644 --- a/Lib/test/test_threading_local.py +++ b/Lib/test/test_threading_local.py @@ -5,7 +5,6 @@ from test import support from test.support import threading_helper from test.support.import_helper import import_module import weakref -import gc # Modules under test import _thread diff --git a/Lib/test/test_time.py b/Lib/test/test_time.py index 884b1423..02cc3f43 100644 --- a/Lib/test/test_time.py +++ b/Lib/test/test_time.py @@ -848,7 +848,7 @@ class CPyTimeTestCase: # test rounding ns_timestamps = self._rounding_values(use_float) valid_values = convert_values(ns_timestamps) - for time_rnd, decimal_rnd in ROUNDING_MODES : + for time_rnd, decimal_rnd in ROUNDING_MODES: with decimal.localcontext() as context: context.rounding = decimal_rnd diff --git a/Lib/test/test_timeout.py b/Lib/test/test_timeout.py index fa85c7e6..35ff56f1 100644 --- a/Lib/test/test_timeout.py +++ b/Lib/test/test_timeout.py @@ -50,10 +50,10 @@ class CreationTestCase(unittest.TestCase): def testReturnType(self): # Test return type of gettimeout() self.sock.settimeout(1) - self.assertEqual(type(self.sock.gettimeout()), type(1.0)) + self.assertIs(type(self.sock.gettimeout()), float) self.sock.settimeout(3.9) - self.assertEqual(type(self.sock.gettimeout()), type(1.0)) + self.assertIs(type(self.sock.gettimeout()), float) def testTypeCheck(self): # Test type checking by settimeout() @@ -148,13 +148,12 @@ class TCPTimeoutTestCase(TimeoutTestCase): def tearDown(self): self.sock.close() - @unittest.skipIf(True, 'need to replace these hosts; see bpo-35518') def testConnectTimeout(self): # Testing connect timeout is tricky: we need to have IP connectivity # to a host that silently drops our packets. We can't simulate this # from Python because it's a function of the underlying TCP/IP stack. - # So, the following Snakebite host has been defined: - blackhole = resolve_address('blackhole.snakebite.net', 56666) + # So, the following port on the pythontest.net host has been defined: + blackhole = resolve_address('pythontest.net', 56666) # Blackhole has been configured to silently drop any incoming packets. # No RSTs (for TCP) or ICMP UNREACH (for UDP/ICMP) will be sent back @@ -166,7 +165,7 @@ class TCPTimeoutTestCase(TimeoutTestCase): # to firewalling or general network configuration. In order to improve # our confidence in testing the blackhole, a corresponding 'whitehole' # has also been set up using one port higher: - whitehole = resolve_address('whitehole.snakebite.net', 56667) + whitehole = resolve_address('pythontest.net', 56667) # This address has been configured to immediately drop any incoming # packets as well, but it does it respectfully with regards to the @@ -180,20 +179,15 @@ class TCPTimeoutTestCase(TimeoutTestCase): # timeframe). # For the records, the whitehole/blackhole configuration has been set - # up using the 'pf' firewall (available on BSDs), using the following: + # up using the 'iptables' firewall, using the following rules: # - # ext_if="bge0" - # - # blackhole_ip="35.8.247.6" - # whitehole_ip="35.8.247.6" - # blackhole_port="56666" - # whitehole_port="56667" - # - # block return in log quick on $ext_if proto { tcp udp } \ - # from any to $whitehole_ip port $whitehole_port - # block drop in log quick on $ext_if proto { tcp udp } \ - # from any to $blackhole_ip port $blackhole_port + # -A INPUT -p tcp --destination-port 56666 -j DROP + # -A INPUT -p udp --destination-port 56666 -j DROP + # -A INPUT -p tcp --destination-port 56667 -j REJECT + # -A INPUT -p udp --destination-port 56667 -j REJECT # + # See https://github.com/python/psf-salt/blob/main/pillar/base/firewall/snakebite.sls + # for the current configuration. skip = True sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) diff --git a/Lib/test/test_tix.py b/Lib/test/test_tix.py index 454baeb3..d0d2a164 100644 --- a/Lib/test/test_tix.py +++ b/Lib/test/test_tix.py @@ -5,7 +5,7 @@ from test.support import import_helper from test.support import check_sanitizer if check_sanitizer(address=True, memory=True): - raise unittest.SkipTest("Tests involvin libX11 can SEGFAULT on ASAN/MSAN builds") + raise unittest.SkipTest("Tests involving libX11 can SEGFAULT on ASAN/MSAN builds") # Skip this test if the _tkinter module wasn't built. diff --git a/Lib/test/test_tk.py b/Lib/test/test_tk.py deleted file mode 100644 index 8f90cbab..00000000 --- a/Lib/test/test_tk.py +++ /dev/null @@ -1,20 +0,0 @@ -import unittest -from test import support -from test.support import import_helper -from test.support import check_sanitizer - -if check_sanitizer(address=True, memory=True): - raise unittest.SkipTest("Tests involvin libX11 can SEGFAULT on ASAN/MSAN builds") - -# Skip test if _tkinter wasn't built. -import_helper.import_module('_tkinter') - -# Skip test if tk cannot be initialized. -support.requires('gui') - -def load_tests(loader, tests, pattern): - return loader.discover('tkinter.test.test_tkinter') - - -if __name__ == '__main__': - unittest.main() diff --git a/Lib/tkinter/test/README b/Lib/test/test_tkinter/README similarity index 100% rename from Lib/tkinter/test/README rename to Lib/test/test_tkinter/README diff --git a/Lib/test/test_tkinter/__init__.py b/Lib/test/test_tkinter/__init__.py new file mode 100644 index 00000000..b1181bc0 --- /dev/null +++ b/Lib/test/test_tkinter/__init__.py @@ -0,0 +1,23 @@ +import os.path +import unittest + +from test.support import ( + check_sanitizer, + import_helper, + load_package_tests, + requires, + ) + + +if check_sanitizer(address=True, memory=True): + raise unittest.SkipTest("Tests involving libX11 can SEGFAULT on ASAN/MSAN builds") + +# Skip test if _tkinter wasn't built. +import_helper.import_module('_tkinter') + +# Skip test if tk cannot be initialized. +requires('gui') + + +def load_tests(*args): + return load_package_tests(os.path.dirname(__file__), *args) diff --git a/Lib/test/test_tkinter/__main__.py b/Lib/test/test_tkinter/__main__.py new file mode 100644 index 00000000..40a23a29 --- /dev/null +++ b/Lib/test/test_tkinter/__main__.py @@ -0,0 +1,4 @@ +from . import load_tests +import unittest + +unittest.main() diff --git a/Lib/tkinter/test/support.py b/Lib/test/test_tkinter/support.py similarity index 89% rename from Lib/tkinter/test/support.py rename to Lib/test/test_tkinter/support.py index 9e26d045..10e64bf4 100644 --- a/Lib/tkinter/test/support.py +++ b/Lib/test/test_tkinter/support.py @@ -1,5 +1,4 @@ import functools -import re import tkinter import unittest @@ -80,28 +79,28 @@ def simulate_mouse_click(widget, x, y): import _tkinter tcl_version = tuple(map(int, _tkinter.TCL_VERSION.split('.'))) +tk_version = tuple(map(int, _tkinter.TK_VERSION.split('.'))) -def requires_tcl(*version): - if len(version) <= 2: - return unittest.skipUnless(tcl_version >= version, - 'requires Tcl version >= ' + '.'.join(map(str, version))) +def requires_tk(*version): + if len(version) <= 2 and tk_version >= version: + return lambda test: test def deco(test): @functools.wraps(test) def newtest(self): - if get_tk_patchlevel() < version: - self.skipTest('requires Tcl version >= ' + + root = getattr(self, 'root', None) + if get_tk_patchlevel(root) < version: + self.skipTest('requires Tk version >= ' + '.'.join(map(str, version))) test(self) return newtest return deco _tk_patchlevel = None -def get_tk_patchlevel(): +def get_tk_patchlevel(root): global _tk_patchlevel if _tk_patchlevel is None: - tcl = tkinter.Tcl() - _tk_patchlevel = tcl.info_patchlevel() + _tk_patchlevel = tkinter._parse_version(root.tk.globalgetvar('tk_patchLevel')) return _tk_patchlevel units = { diff --git a/Lib/tkinter/test/test_tkinter/test_colorchooser.py b/Lib/test/test_tkinter/test_colorchooser.py similarity index 96% rename from Lib/tkinter/test/test_tkinter/test_colorchooser.py rename to Lib/test/test_tkinter/test_colorchooser.py index 488162ff..9bba2139 100644 --- a/Lib/tkinter/test/test_tkinter/test_colorchooser.py +++ b/Lib/test/test_tkinter/test_colorchooser.py @@ -1,7 +1,7 @@ import unittest import tkinter from test.support import requires, swap_attr -from tkinter.test.support import AbstractDefaultRootTest, AbstractTkTest +from test.test_tkinter.support import AbstractDefaultRootTest, AbstractTkTest from tkinter import colorchooser from tkinter.colorchooser import askcolor from tkinter.commondialog import Dialog diff --git a/Lib/tkinter/test/test_tkinter/test_font.py b/Lib/test/test_tkinter/test_font.py similarity index 98% rename from Lib/tkinter/test/test_tkinter/test_font.py rename to Lib/test/test_tkinter/test_font.py index 058c53a9..563707dd 100644 --- a/Lib/tkinter/test/test_tkinter/test_font.py +++ b/Lib/test/test_tkinter/test_font.py @@ -2,7 +2,7 @@ import unittest import tkinter from tkinter import font from test.support import requires, gc_collect, ALWAYS_EQ -from tkinter.test.support import AbstractTkTest, AbstractDefaultRootTest +from test.test_tkinter.support import AbstractTkTest, AbstractDefaultRootTest requires('gui') diff --git a/Lib/tkinter/test/test_tkinter/test_geometry_managers.py b/Lib/test/test_tkinter/test_geometry_managers.py similarity index 99% rename from Lib/tkinter/test/test_tkinter/test_geometry_managers.py rename to Lib/test/test_tkinter/test_geometry_managers.py index c89bc8db..59fe592b 100644 --- a/Lib/tkinter/test/test_tkinter/test_geometry_managers.py +++ b/Lib/test/test_tkinter/test_geometry_managers.py @@ -4,8 +4,8 @@ import tkinter from tkinter import TclError from test.support import requires -from tkinter.test.support import pixels_conv -from tkinter.test.widget_tests import AbstractWidgetTest +from test.test_tkinter.support import pixels_conv +from test.test_tkinter.widget_tests import AbstractWidgetTest requires('gui') @@ -108,8 +108,8 @@ class PackTest(AbstractWidgetTest, unittest.TestCase): a.pack_configure(in_=c) self.assertEqual(pack.pack_slaves(), [b, c, d]) self.assertEqual(c.pack_slaves(), [a]) - with self.assertRaisesRegex(TclError, - 'can\'t pack %s inside itself' % (a,)): + with self.assertRaisesRegex( + TclError, """can't pack "?%s"? inside itself""" % (a,)): a.pack_configure(in_=a) with self.assertRaisesRegex(TclError, 'bad window path name ".foo"'): a.pack_configure(in_='.foo') @@ -292,8 +292,10 @@ class PlaceTest(AbstractWidgetTest, unittest.TestCase): def test_place_configure_in(self): t, f, f2 = self.create2() self.assertEqual(f2.winfo_manager(), '') - with self.assertRaisesRegex(TclError, "can't place %s relative to " - "itself" % re.escape(str(f2))): + with self.assertRaisesRegex( + TclError, + """can't place "?%s"? relative to itself""" + % re.escape(str(f2))): f2.place_configure(in_=f2) self.assertEqual(f2.winfo_manager(), '') with self.assertRaisesRegex(TclError, 'bad window path name'): diff --git a/Lib/tkinter/test/test_tkinter/test_images.py b/Lib/test/test_tkinter/test_images.py similarity index 94% rename from Lib/tkinter/test/test_tkinter/test_images.py rename to Lib/test/test_tkinter/test_images.py index cc69ccac..9f49d6ef 100644 --- a/Lib/tkinter/test/test_tkinter/test_images.py +++ b/Lib/test/test_tkinter/test_images.py @@ -2,7 +2,7 @@ import unittest import tkinter from test import support from test.support import os_helper -from tkinter.test.support import AbstractTkTest, AbstractDefaultRootTest, requires_tcl +from test.test_tkinter.support import AbstractTkTest, AbstractDefaultRootTest, requires_tk support.requires('gui') @@ -144,6 +144,14 @@ class BitmapImageTest(AbstractTkTest, unittest.TestCase): self.assertEqual(image['foreground'], '-foreground {} {} #000000 yellow') + def test_bug_100814(self): + # gh-100814: Passing a callable option value causes AttributeError. + with self.assertRaises(tkinter.TclError): + tkinter.BitmapImage('::img::test', master=self.root, spam=print) + image = tkinter.BitmapImage('::img::test', master=self.root) + with self.assertRaises(tkinter.TclError): + image.configure(spam=print) + class PhotoImageTest(AbstractTkTest, unittest.TestCase): @@ -213,11 +221,11 @@ class PhotoImageTest(AbstractTkTest, unittest.TestCase): def test_create_from_gif_data(self): self.check_create_from_data('gif') - @requires_tcl(8, 6) + @requires_tk(8, 6) def test_create_from_png_file(self): self.check_create_from_file('png') - @requires_tcl(8, 6) + @requires_tk(8, 6) def test_create_from_png_data(self): self.check_create_from_data('png') @@ -274,6 +282,14 @@ class PhotoImageTest(AbstractTkTest, unittest.TestCase): image.configure(palette='3/4/2') self.assertEqual(image['palette'], '3/4/2') + def test_bug_100814(self): + # gh-100814: Passing a callable option value causes AttributeError. + with self.assertRaises(tkinter.TclError): + tkinter.PhotoImage('::img::test', master=self.root, spam=print) + image = tkinter.PhotoImage('::img::test', master=self.root) + with self.assertRaises(tkinter.TclError): + image.configure(spam=print) + def test_blank(self): image = self.create() image.blank() diff --git a/Lib/tkinter/test/test_tkinter/test_loadtk.py b/Lib/test/test_tkinter/test_loadtk.py similarity index 100% rename from Lib/tkinter/test/test_tkinter/test_loadtk.py rename to Lib/test/test_tkinter/test_loadtk.py diff --git a/Lib/tkinter/test/test_tkinter/test_messagebox.py b/Lib/test/test_tkinter/test_messagebox.py similarity index 94% rename from Lib/tkinter/test/test_tkinter/test_messagebox.py rename to Lib/test/test_tkinter/test_messagebox.py index d38541a5..f41bdc98 100644 --- a/Lib/tkinter/test/test_tkinter/test_messagebox.py +++ b/Lib/test/test_tkinter/test_messagebox.py @@ -1,7 +1,7 @@ import unittest import tkinter from test.support import requires, swap_attr -from tkinter.test.support import AbstractDefaultRootTest +from test.test_tkinter.support import AbstractDefaultRootTest from tkinter.commondialog import Dialog from tkinter.messagebox import showinfo diff --git a/Lib/tkinter/test/test_tkinter/test_misc.py b/Lib/test/test_tkinter/test_misc.py similarity index 99% rename from Lib/tkinter/test/test_tkinter/test_misc.py rename to Lib/test/test_tkinter/test_misc.py index 620b6ed6..d1aca58d 100644 --- a/Lib/tkinter/test/test_tkinter/test_misc.py +++ b/Lib/test/test_tkinter/test_misc.py @@ -3,7 +3,7 @@ import unittest import tkinter import enum from test import support -from tkinter.test.support import AbstractTkTest, AbstractDefaultRootTest +from test.test_tkinter.support import AbstractTkTest, AbstractDefaultRootTest support.requires('gui') diff --git a/Lib/tkinter/test/test_tkinter/test_simpledialog.py b/Lib/test/test_tkinter/test_simpledialog.py similarity index 93% rename from Lib/tkinter/test/test_tkinter/test_simpledialog.py rename to Lib/test/test_tkinter/test_simpledialog.py index 18cd2712..502f7f70 100644 --- a/Lib/tkinter/test/test_tkinter/test_simpledialog.py +++ b/Lib/test/test_tkinter/test_simpledialog.py @@ -1,7 +1,7 @@ import unittest import tkinter from test.support import requires, swap_attr -from tkinter.test.support import AbstractDefaultRootTest +from test.test_tkinter.support import AbstractDefaultRootTest from tkinter.simpledialog import Dialog, askinteger requires('gui') diff --git a/Lib/tkinter/test/test_tkinter/test_text.py b/Lib/test/test_tkinter/test_text.py similarity index 98% rename from Lib/tkinter/test/test_tkinter/test_text.py rename to Lib/test/test_tkinter/test_text.py index ea557586..328e4256 100644 --- a/Lib/tkinter/test/test_tkinter/test_text.py +++ b/Lib/test/test_tkinter/test_text.py @@ -1,7 +1,7 @@ import unittest import tkinter from test.support import requires -from tkinter.test.support import AbstractTkTest +from test.test_tkinter.support import AbstractTkTest requires('gui') diff --git a/Lib/tkinter/test/test_tkinter/test_variables.py b/Lib/test/test_tkinter/test_variables.py similarity index 99% rename from Lib/tkinter/test/test_tkinter/test_variables.py rename to Lib/test/test_tkinter/test_variables.py index 427e1684..c1d232e2 100644 --- a/Lib/tkinter/test/test_tkinter/test_variables.py +++ b/Lib/test/test_tkinter/test_variables.py @@ -6,7 +6,7 @@ import tkinter from tkinter import (Variable, StringVar, IntVar, DoubleVar, BooleanVar, Tcl, TclError) from test.support import ALWAYS_EQ -from tkinter.test.support import AbstractDefaultRootTest +from test.test_tkinter.support import AbstractDefaultRootTest class Var(Variable): diff --git a/Lib/tkinter/test/test_tkinter/test_widgets.py b/Lib/test/test_tkinter/test_widgets.py similarity index 98% rename from Lib/tkinter/test/test_tkinter/test_widgets.py rename to Lib/test/test_tkinter/test_widgets.py index da321a1d..d3f942db 100644 --- a/Lib/tkinter/test/test_tkinter/test_widgets.py +++ b/Lib/test/test_tkinter/test_widgets.py @@ -4,13 +4,12 @@ from tkinter import TclError import os from test.support import requires -from tkinter.test.support import (requires_tcl, +from test.test_tkinter.support import (requires_tk, get_tk_patchlevel, widget_eq, AbstractDefaultRootTest) -from tkinter.test.widget_tests import ( +from test.test_tkinter.widget_tests import ( add_standard_options, - AbstractWidgetTest, StandardOptionsTests, IntegerSizeTests, PixelSizeTests, - setUpModule) + AbstractWidgetTest, StandardOptionsTests, IntegerSizeTests, PixelSizeTests) requires('gui') @@ -77,6 +76,8 @@ class ToplevelTest(AbstractToplevelTest, unittest.TestCase): def test_configure_screen(self): widget = self.create() + if widget._windowingsystem != 'x11': + self.skipTest('Not using Tk for X11') self.assertEqual(widget['screen'], '') try: display = os.environ['DISPLAY'] @@ -612,7 +613,7 @@ class TextTest(AbstractWidgetTest, unittest.TestCase): widget = self.create() self.checkColorParam(widget, 'inactiveselectbackground') - @requires_tcl(8, 6) + @requires_tk(8, 6) def test_configure_insertunfocussed(self): widget = self.create() self.checkEnumParam(widget, 'insertunfocussed', @@ -900,6 +901,12 @@ class CanvasTest(AbstractWidgetTest, unittest.TestCase): c.coords(i, [21, 31, 41, 51, 61, 11]) self.assertEqual(c.coords(i), [21.0, 31.0, 41.0, 51.0, 61.0, 11.0]) + c.coords(i, (22, 32), (42, 52), (62, 12)) + self.assertEqual(c.coords(i), [22.0, 32.0, 42.0, 52.0, 62.0, 12.0]) + + c.coords(i, [(23, 33), (43, 53), (63, 13)]) + self.assertEqual(c.coords(i), [23.0, 33.0, 43.0, 53.0, 63.0, 13.0]) + c.coords(i, 20, 30, 60, 10) self.assertEqual(c.coords(i), [20.0, 30.0, 60.0, 10.0]) self.assertEqual(c.bbox(i), (18, 8, 62, 32)) @@ -917,7 +924,7 @@ class CanvasTest(AbstractWidgetTest, unittest.TestCase): for i in range(4): self.assertIsInstance(coords[i], float) - @requires_tcl(8, 6) + @requires_tk(8, 6) def test_moveto(self): widget = self.create() i1 = widget.create_rectangle(1, 1, 20, 20, tags='group') @@ -962,7 +969,7 @@ class ListboxTest(AbstractWidgetTest, unittest.TestCase): self.checkEnumParam(widget, 'activestyle', 'dotbox', 'none', 'underline') - test_configure_justify = requires_tcl(8, 6, 5)(StandardOptionsTests.test_configure_justify) + test_configure_justify = requires_tk(8, 6, 5)(StandardOptionsTests.test_configure_justify) def test_configure_listvariable(self): widget = self.create() @@ -1101,7 +1108,7 @@ class ScaleTest(AbstractWidgetTest, unittest.TestCase): def test_configure_from(self): widget = self.create() - conv = float if get_tk_patchlevel() >= (8, 6, 10) else float_round + conv = float if get_tk_patchlevel(self.root) >= (8, 6, 10) else float_round self.checkFloatParam(widget, 'from', 100, 14.9, 15.1, conv=conv) def test_configure_label(self): @@ -1228,19 +1235,19 @@ class PanedWindowTest(AbstractWidgetTest, unittest.TestCase): widget = self.create() self.checkBooleanParam(widget, 'opaqueresize') - @requires_tcl(8, 6, 5) + @requires_tk(8, 6, 5) def test_configure_proxybackground(self): widget = self.create() self.checkColorParam(widget, 'proxybackground') - @requires_tcl(8, 6, 5) + @requires_tk(8, 6, 5) def test_configure_proxyborderwidth(self): widget = self.create() self.checkPixelsParam(widget, 'proxyborderwidth', 0, 1.3, 2.9, 6, -2, '10p', conv=False) - @requires_tcl(8, 6, 5) + @requires_tk(8, 6, 5) def test_configure_proxyrelief(self): widget = self.create() self.checkReliefParam(widget, 'proxyrelief') @@ -1378,6 +1385,11 @@ class MenuTest(AbstractWidgetTest, unittest.TestCase): def create(self, **kwargs): return tkinter.Menu(self.root, **kwargs) + def test_indexcommand_none(self): + widget = self.create() + i = widget.index('none') + self.assertIsNone(i) + def test_configure_postcommand(self): widget = self.create() self.checkCommandParam(widget, 'postcommand') @@ -1396,10 +1408,13 @@ class MenuTest(AbstractWidgetTest, unittest.TestCase): def test_configure_type(self): widget = self.create() + opts = ('normal, tearoff, or menubar' + if widget.info_patchlevel() < (8, 7) else + 'menubar, normal, or tearoff') self.checkEnumParam( widget, 'type', 'normal', 'tearoff', 'menubar', - errmsg='bad type "{}": must be normal, tearoff, or menubar', + errmsg='bad type "{}": must be ' + opts, ) def test_entryconfigure(self): diff --git a/Lib/tkinter/test/widget_tests.py b/Lib/test/test_tkinter/widget_tests.py similarity index 99% rename from Lib/tkinter/test/widget_tests.py rename to Lib/test/test_tkinter/widget_tests.py index a450544c..514b42be 100644 --- a/Lib/tkinter/test/widget_tests.py +++ b/Lib/test/test_tkinter/widget_tests.py @@ -1,8 +1,7 @@ # Common tests for test_tkinter/test_widgets.py and test_ttk/test_widgets.py -import unittest import tkinter -from tkinter.test.support import (AbstractTkTest, tcl_version, +from test.test_tkinter.support import (AbstractTkTest, tk_version, pixels_conv, tcl_obj_eq) import test.support @@ -23,7 +22,7 @@ class AbstractWidgetTest(AbstractTkTest): return self._scaling def _str(self, value): - if not self._stringify and self.wantobjects and tcl_version >= (8, 6): + if not self._stringify and self.wantobjects and tk_version >= (8, 6): return value if isinstance(value, tuple): return ' '.join(map(self._str, value)) @@ -157,7 +156,7 @@ class AbstractWidgetTest(AbstractTkTest): 'flat', 'groove', 'raised', 'ridge', 'solid', 'sunken') errmsg='bad relief "spam": must be '\ 'flat, groove, raised, ridge, solid, or sunken' - if tcl_version < (8, 6): + if tk_version < (8, 6): errmsg = None self.checkInvalidParam(widget, name, 'spam', errmsg=errmsg) diff --git a/Lib/test/test_tokenize.py b/Lib/test/test_tokenize.py index 63c2501c..c320478c 100644 --- a/Lib/test/test_tokenize.py +++ b/Lib/test/test_tokenize.py @@ -1,9 +1,10 @@ from test import support from test.support import os_helper -from tokenize import (tokenize, _tokenize, untokenize, NUMBER, NAME, OP, +from tokenize import (tokenize, untokenize, NUMBER, NAME, OP, STRING, ENDMARKER, ENCODING, tok_name, detect_encoding, open as tokenize_open, Untokenizer, generate_tokens, - NEWLINE, _generate_tokens_from_c_tokenizer, DEDENT) + NEWLINE, _generate_tokens_from_c_tokenizer, DEDENT, TokenInfo, + TokenError) from io import BytesIO, StringIO import unittest from textwrap import dedent @@ -11,7 +12,7 @@ from unittest import TestCase, mock from test.test_grammar import (VALID_UNDERSCORE_LITERALS, INVALID_UNDERSCORE_LITERALS) from test.support import os_helper -from test.support.script_helper import run_test_script, make_script +from test.support.script_helper import run_test_script, make_script, run_python_until_end import os import token @@ -51,6 +52,25 @@ class TokenizeTest(TestCase): [" ENCODING 'utf-8' (0, 0) (0, 0)"] + expected.rstrip().splitlines()) + def test_invalid_readline(self): + def gen(): + yield "sdfosdg" + yield "sdfosdg" + with self.assertRaises(TypeError): + list(tokenize(gen().__next__)) + + def gen(): + yield b"sdfosdg" + yield b"sdfosdg" + with self.assertRaises(TypeError): + list(generate_tokens(gen().__next__)) + + def gen(): + yield "sdfosdg" + 1/0 + with self.assertRaises(ZeroDivisionError): + list(generate_tokens(gen().__next__)) + def test_implicit_newline(self): # Make sure that the tokenizer puts in an implicit NEWLINE # when the input lacks a trailing new line. @@ -84,6 +104,32 @@ class TokenizeTest(TestCase): NEWLINE '\\n' (4, 26) (4, 27) DEDENT '' (5, 0) (5, 0) """) + + self.check_tokenize("if True:\r\n # NL\r\n foo='bar'\r\n\r\n", """\ + NAME 'if' (1, 0) (1, 2) + NAME 'True' (1, 3) (1, 7) + OP ':' (1, 7) (1, 8) + NEWLINE '\\r\\n' (1, 8) (1, 10) + COMMENT '# NL' (2, 4) (2, 8) + NL '\\r\\n' (2, 8) (2, 10) + INDENT ' ' (3, 0) (3, 4) + NAME 'foo' (3, 4) (3, 7) + OP '=' (3, 7) (3, 8) + STRING "\'bar\'" (3, 8) (3, 13) + NEWLINE '\\r\\n' (3, 13) (3, 15) + NL '\\r\\n' (4, 0) (4, 2) + DEDENT '' (5, 0) (5, 0) + """) + + self.check_tokenize("x = 1 + \\\r\n1\r\n", """\ + NAME 'x' (1, 0) (1, 1) + OP '=' (1, 2) (1, 3) + NUMBER '1' (1, 4) (1, 5) + OP '+' (1, 6) (1, 7) + NUMBER '1' (2, 0) (2, 1) + NEWLINE '\\r\\n' (2, 1) (2, 3) + """) + indent_error_file = b"""\ def k(x): x += 2 @@ -92,9 +138,18 @@ def k(x): readline = BytesIO(indent_error_file).readline with self.assertRaisesRegex(IndentationError, "unindent does not match any " - "outer indentation level"): + "outer indentation level") as e: for tok in tokenize(readline): pass + self.assertEqual(e.exception.lineno, 3) + self.assertEqual(e.exception.filename, '<string>') + self.assertEqual(e.exception.end_lineno, None) + self.assertEqual(e.exception.end_offset, None) + self.assertEqual( + e.exception.msg, + 'unindent does not match any outer indentation level') + self.assertEqual(e.exception.offset, 9) + self.assertEqual(e.exception.text, ' x += 5') def test_int(self): # Ordinary integers and binary operators @@ -229,7 +284,16 @@ def k(x): # this won't work with compound complex inputs continue self.assertEqual(number_token(lit), lit) + # Valid cases with extra underscores in the tokenize module + # See gh-105549 for context + extra_valid_cases = {"0_7", "09_99"} for lit in INVALID_UNDERSCORE_LITERALS: + if lit in extra_valid_cases: + continue + try: + number_token(lit) + except TokenError: + continue self.assertNotEqual(number_token(lit), lit) def test_string(self): @@ -381,21 +445,132 @@ c"""', """\ STRING 'rb"\""a\\\\\\nb\\\\\\nc"\""' (1, 0) (3, 4) """) self.check_tokenize('f"abc"', """\ - STRING 'f"abc"' (1, 0) (1, 6) + FSTRING_START 'f"' (1, 0) (1, 2) + FSTRING_MIDDLE 'abc' (1, 2) (1, 5) + FSTRING_END '"' (1, 5) (1, 6) """) self.check_tokenize('fR"a{b}c"', """\ - STRING 'fR"a{b}c"' (1, 0) (1, 9) + FSTRING_START 'fR"' (1, 0) (1, 3) + FSTRING_MIDDLE 'a' (1, 3) (1, 4) + OP '{' (1, 4) (1, 5) + NAME 'b' (1, 5) (1, 6) + OP '}' (1, 6) (1, 7) + FSTRING_MIDDLE 'c' (1, 7) (1, 8) + FSTRING_END '"' (1, 8) (1, 9) + """) + self.check_tokenize('fR"a{{{b!r}}}c"', """\ + FSTRING_START 'fR"' (1, 0) (1, 3) + FSTRING_MIDDLE 'a{' (1, 3) (1, 5) + OP '{' (1, 6) (1, 7) + NAME 'b' (1, 7) (1, 8) + OP '!' (1, 8) (1, 9) + NAME 'r' (1, 9) (1, 10) + OP '}' (1, 10) (1, 11) + FSTRING_MIDDLE '}' (1, 11) (1, 12) + FSTRING_MIDDLE 'c' (1, 13) (1, 14) + FSTRING_END '"' (1, 14) (1, 15) + """) + self.check_tokenize('f"{{{1+1}}}"', """\ + FSTRING_START 'f"' (1, 0) (1, 2) + FSTRING_MIDDLE '{' (1, 2) (1, 3) + OP '{' (1, 4) (1, 5) + NUMBER '1' (1, 5) (1, 6) + OP '+' (1, 6) (1, 7) + NUMBER '1' (1, 7) (1, 8) + OP '}' (1, 8) (1, 9) + FSTRING_MIDDLE '}' (1, 9) (1, 10) + FSTRING_END '"' (1, 11) (1, 12) + """) + self.check_tokenize('f"""{f\'\'\'{f\'{f"{1+1}"}\'}\'\'\'}"""', """\ + FSTRING_START 'f\"""' (1, 0) (1, 4) + OP '{' (1, 4) (1, 5) + FSTRING_START "f'''" (1, 5) (1, 9) + OP '{' (1, 9) (1, 10) + FSTRING_START "f'" (1, 10) (1, 12) + OP '{' (1, 12) (1, 13) + FSTRING_START 'f"' (1, 13) (1, 15) + OP '{' (1, 15) (1, 16) + NUMBER '1' (1, 16) (1, 17) + OP '+' (1, 17) (1, 18) + NUMBER '1' (1, 18) (1, 19) + OP '}' (1, 19) (1, 20) + FSTRING_END '"' (1, 20) (1, 21) + OP '}' (1, 21) (1, 22) + FSTRING_END "'" (1, 22) (1, 23) + OP '}' (1, 23) (1, 24) + FSTRING_END "'''" (1, 24) (1, 27) + OP '}' (1, 27) (1, 28) + FSTRING_END '\"""' (1, 28) (1, 31) + """) + self.check_tokenize('f""" x\nstr(data, encoding={invalid!r})\n"""', """\ + FSTRING_START 'f\"""' (1, 0) (1, 4) + FSTRING_MIDDLE ' x\\nstr(data, encoding=' (1, 4) (2, 19) + OP '{' (2, 19) (2, 20) + NAME 'invalid' (2, 20) (2, 27) + OP '!' (2, 27) (2, 28) + NAME 'r' (2, 28) (2, 29) + OP '}' (2, 29) (2, 30) + FSTRING_MIDDLE ')\\n' (2, 30) (3, 0) + FSTRING_END '\"""' (3, 0) (3, 3) + """) + self.check_tokenize('f"""123456789\nsomething{None}bad"""', """\ + FSTRING_START 'f\"""' (1, 0) (1, 4) + FSTRING_MIDDLE '123456789\\nsomething' (1, 4) (2, 9) + OP '{' (2, 9) (2, 10) + NAME 'None' (2, 10) (2, 14) + OP '}' (2, 14) (2, 15) + FSTRING_MIDDLE 'bad' (2, 15) (2, 18) + FSTRING_END '\"""' (2, 18) (2, 21) """) self.check_tokenize('f"""abc"""', """\ - STRING 'f\"\"\"abc\"\"\"' (1, 0) (1, 10) + FSTRING_START 'f\"""' (1, 0) (1, 4) + FSTRING_MIDDLE 'abc' (1, 4) (1, 7) + FSTRING_END '\"""' (1, 7) (1, 10) """) self.check_tokenize(r'f"abc\ def"', """\ - STRING 'f"abc\\\\\\ndef"' (1, 0) (2, 4) + FSTRING_START 'f"' (1, 0) (1, 2) + FSTRING_MIDDLE 'abc\\\\\\ndef' (1, 2) (2, 3) + FSTRING_END '"' (2, 3) (2, 4) """) self.check_tokenize(r'Rf"abc\ def"', """\ - STRING 'Rf"abc\\\\\\ndef"' (1, 0) (2, 4) + FSTRING_START 'Rf"' (1, 0) (1, 3) + FSTRING_MIDDLE 'abc\\\\\\ndef' (1, 3) (2, 3) + FSTRING_END '"' (2, 3) (2, 4) + """) + self.check_tokenize("f'some words {a+b:.3f} more words {c+d=} final words'", """\ + FSTRING_START "f'" (1, 0) (1, 2) + FSTRING_MIDDLE 'some words ' (1, 2) (1, 13) + OP '{' (1, 13) (1, 14) + NAME 'a' (1, 14) (1, 15) + OP '+' (1, 15) (1, 16) + NAME 'b' (1, 16) (1, 17) + OP ':' (1, 17) (1, 18) + FSTRING_MIDDLE '.3f' (1, 18) (1, 21) + OP '}' (1, 21) (1, 22) + FSTRING_MIDDLE ' more words ' (1, 22) (1, 34) + OP '{' (1, 34) (1, 35) + NAME 'c' (1, 35) (1, 36) + OP '+' (1, 36) (1, 37) + NAME 'd' (1, 37) (1, 38) + OP '=' (1, 38) (1, 39) + OP '}' (1, 39) (1, 40) + FSTRING_MIDDLE ' final words' (1, 40) (1, 52) + FSTRING_END "'" (1, 52) (1, 53) + """) + self.check_tokenize("""\ +f'''{ +3 +=}'''""", """\ + FSTRING_START "f'''" (1, 0) (1, 4) + OP '{' (1, 4) (1, 5) + NL '\\n' (1, 5) (1, 6) + NUMBER '3' (2, 0) (2, 1) + NL '\\n' (2, 1) (2, 2) + OP '=' (3, 0) (3, 1) + OP '}' (3, 1) (3, 2) + FSTRING_END "'''" (3, 2) (3, 5) """) def test_function(self): @@ -946,6 +1121,30 @@ async def f(): DEDENT '' (7, 0) (7, 0) """) + def test_newline_after_parenthesized_block_with_comment(self): + self.check_tokenize('''\ +[ + # A comment here + 1 +] +''', """\ + OP '[' (1, 0) (1, 1) + NL '\\n' (1, 1) (1, 2) + COMMENT '# A comment here' (2, 4) (2, 20) + NL '\\n' (2, 20) (2, 21) + NUMBER '1' (3, 4) (3, 5) + NL '\\n' (3, 5) (3, 6) + OP ']' (4, 0) (4, 1) + NEWLINE '\\n' (4, 1) (4, 2) + """) + + def test_closing_parenthesis_from_different_line(self): + self.check_tokenize("); x", """\ + OP ')' (1, 0) (1, 1) + OP ';' (1, 1) (1, 2) + NAME 'x' (1, 3) (1, 4) + """) + class GenerateTokensTest(TokenizeTest): def check_tokenize(self, s, expected): # Format the tokens in s in a table format. @@ -968,7 +1167,7 @@ def decistmt(s): ]) else: result.append((toknum, tokval)) - return untokenize(result).decode('utf-8') + return untokenize(result).decode('utf-8').strip() class TestMisc(TestCase): @@ -1000,7 +1199,8 @@ class TestTokenizerAdheresToPep0263(TestCase): def _testFile(self, filename): path = os.path.join(os.path.dirname(__file__), filename) - TestRoundtrip.check_roundtrip(self, open(path, 'rb')) + with open(path, 'rb') as f: + TestRoundtrip.check_roundtrip(self, f) def test_utf8_coding_cookie_and_no_utf8_bom(self): f = 'tokenize_tests-utf8-coding-cookie-and-no-utf8-bom-sig.txt' @@ -1040,33 +1240,17 @@ class Test_Tokenize(TestCase): nonlocal first if not first: first = True - return line + yield line else: - return b'' + yield b'' # skip the initial encoding token and the end tokens - tokens = list(_tokenize(readline, encoding='utf-8'))[1:-2] - expected_tokens = [(3, '"ЉЊЈЁЂ"', (1, 0), (1, 7), '"ЉЊЈЁЂ"')] + tokens = list(_generate_tokens_from_c_tokenizer(readline().__next__, encoding='utf-8', + extra_tokens=True))[:-2] + expected_tokens = [TokenInfo(3, '"ЉЊЈЁЂ"', (1, 0), (1, 7), '"ЉЊЈЁЂ"')] self.assertEqual(tokens, expected_tokens, "bytes not decoded with encoding") - def test__tokenize_does_not_decode_with_encoding_none(self): - literal = '"ЉЊЈЁЂ"' - first = False - def readline(): - nonlocal first - if not first: - first = True - return literal - else: - return b'' - - # skip the end tokens - tokens = list(_tokenize(readline, encoding=None))[:-2] - expected_tokens = [(3, '"ЉЊЈЁЂ"', (1, 0), (1, 7), '"ЉЊЈЁЂ"')] - self.assertEqual(tokens, expected_tokens, - "string not tokenized when encoding is None") - class TestDetectEncoding(TestCase): @@ -1214,7 +1398,7 @@ class TestDetectEncoding(TestCase): self.assertEqual(found, "iso-8859-1") def test_syntaxerror_latin1(self): - # Issue 14629: need to raise SyntaxError if the first + # Issue 14629: need to raise TokenError if the first # line(s) have non-UTF-8 characters lines = ( b'print("\xdf")', # Latin-1: LATIN SMALL LETTER SHARP S @@ -1326,17 +1510,20 @@ class TestTokenize(TestCase): def test_tokenize(self): import tokenize as tokenize_module - encoding = object() + encoding = "utf-8" encoding_used = None def mock_detect_encoding(readline): return encoding, [b'first', b'second'] - def mock__tokenize(readline, encoding): + def mock__tokenize(readline, encoding, **kwargs): nonlocal encoding_used encoding_used = encoding out = [] while True: - next_line = readline() + try: + next_line = readline() + except StopIteration: + return out if next_line: out.append(next_line) continue @@ -1351,16 +1538,16 @@ class TestTokenize(TestCase): return str(counter).encode() orig_detect_encoding = tokenize_module.detect_encoding - orig__tokenize = tokenize_module._tokenize + orig_c_token = tokenize_module._generate_tokens_from_c_tokenizer tokenize_module.detect_encoding = mock_detect_encoding - tokenize_module._tokenize = mock__tokenize + tokenize_module._generate_tokens_from_c_tokenizer = mock__tokenize try: results = tokenize(mock_readline) - self.assertEqual(list(results), + self.assertEqual(list(results)[1:], [b'first', b'second', b'1', b'2', b'3', b'4']) finally: tokenize_module.detect_encoding = orig_detect_encoding - tokenize_module._tokenize = orig__tokenize + tokenize_module._generate_tokens_from_c_tokenizer = orig_c_token self.assertEqual(encoding_used, encoding) @@ -1462,13 +1649,47 @@ class TestTokenize(TestCase): def test_comment_at_the_end_of_the_source_without_newline(self): # See http://bugs.python.org/issue44667 source = 'b = 1\n\n#test' - expected_tokens = [token.NAME, token.EQUAL, token.NUMBER, token.NEWLINE, token.NL, token.COMMENT] + expected_tokens = [ + TokenInfo(type=token.ENCODING, string='utf-8', start=(0, 0), end=(0, 0), line=''), + TokenInfo(type=token.NAME, string='b', start=(1, 0), end=(1, 1), line='b = 1\n'), + TokenInfo(type=token.OP, string='=', start=(1, 2), end=(1, 3), line='b = 1\n'), + TokenInfo(type=token.NUMBER, string='1', start=(1, 4), end=(1, 5), line='b = 1\n'), + TokenInfo(type=token.NEWLINE, string='\n', start=(1, 5), end=(1, 6), line='b = 1\n'), + TokenInfo(type=token.NL, string='\n', start=(2, 0), end=(2, 1), line='\n'), + TokenInfo(type=token.COMMENT, string='#test', start=(3, 0), end=(3, 5), line='#test'), + TokenInfo(type=token.NL, string='', start=(3, 5), end=(3, 6), line='#test'), + TokenInfo(type=token.ENDMARKER, string='', start=(4, 0), end=(4, 0), line='') + ] tokens = list(tokenize(BytesIO(source.encode('utf-8')).readline)) - self.assertEqual(tok_name[tokens[0].exact_type], tok_name[ENCODING]) - for i in range(6): - self.assertEqual(tok_name[tokens[i + 1].exact_type], tok_name[expected_tokens[i]]) - self.assertEqual(tok_name[tokens[-1].exact_type], tok_name[token.ENDMARKER]) + self.assertEqual(tokens, expected_tokens) + + def test_newline_and_space_at_the_end_of_the_source_without_newline(self): + # See https://github.com/python/cpython/issues/105435 + source = 'a\n ' + expected_tokens = [ + TokenInfo(token.ENCODING, string='utf-8', start=(0, 0), end=(0, 0), line=''), + TokenInfo(token.NAME, string='a', start=(1, 0), end=(1, 1), line='a\n'), + TokenInfo(token.NEWLINE, string='\n', start=(1, 1), end=(1, 2), line='a\n'), + TokenInfo(token.NL, string='', start=(2, 1), end=(2, 2), line=' '), + TokenInfo(token.ENDMARKER, string='', start=(3, 0), end=(3, 0), line='') + ] + + tokens = list(tokenize(BytesIO(source.encode('utf-8')).readline)) + self.assertEqual(tokens, expected_tokens) + + def test_invalid_character_in_fstring_middle(self): + # See gh-103824 + script = b'''F""" + \xe5"""''' + + with os_helper.temp_dir() as temp_dir: + filename = os.path.join(temp_dir, "script.py") + with open(filename, 'wb') as file: + file.write(script) + rs, _ = run_python_until_end(filename) + self.assertIn(b"SyntaxError", rs.err) + class UntokenizeTest(TestCase): @@ -1530,7 +1751,6 @@ class TestRoundtrip(TestCase): code = f.encode('utf-8') else: code = f.read() - f.close() readline = iter(code.splitlines(keepends=True)).__next__ tokens5 = list(tokenize(readline)) tokens2 = [tok[:2] for tok in tokens5] @@ -1545,6 +1765,17 @@ class TestRoundtrip(TestCase): tokens2_from5 = [tok[:2] for tok in tokenize(readline5)] self.assertEqual(tokens2_from5, tokens2) + def check_line_extraction(self, f): + if isinstance(f, str): + code = f.encode('utf-8') + else: + code = f.read() + readline = iter(code.splitlines(keepends=True)).__next__ + for tok in tokenize(readline): + if tok.type in {ENCODING, ENDMARKER}: + continue + self.assertEqual(tok.string, tok.line[tok.start[1]: tok.end[1]]) + def test_roundtrip(self): # There are some standard formatting practices that are easy to get right. @@ -1625,6 +1856,10 @@ class TestRoundtrip(TestCase): # 7 more testfiles fail. Remove them also until the failure is diagnosed. testfiles.remove(os.path.join(tempdir, "test_unicode_identifiers.py")) + + # TODO: Remove this once we can untokenize PEP 701 syntax + testfiles.remove(os.path.join(tempdir, "test_fstring.py")) + for f in ('buffer', 'builtin', 'fileio', 'inspect', 'os', 'platform', 'sys'): testfiles.remove(os.path.join(tempdir, "test_%s.py") % f) @@ -1637,6 +1872,7 @@ class TestRoundtrip(TestCase): with open(testfile, 'rb') as f: with self.subTest(file=testfile): self.check_roundtrip(f) + self.check_line_extraction(f) def roundtrip(self, code): @@ -1655,16 +1891,65 @@ class TestRoundtrip(TestCase): self.check_roundtrip(code) +class InvalidPythonTests(TestCase): + def test_number_followed_by_name(self): + # See issue #gh-105549 + source = "2sin(x)" + expected_tokens = [ + TokenInfo(type=token.NUMBER, string='2', start=(1, 0), end=(1, 1), line='2sin(x)'), + TokenInfo(type=token.NAME, string='sin', start=(1, 1), end=(1, 4), line='2sin(x)'), + TokenInfo(type=token.OP, string='(', start=(1, 4), end=(1, 5), line='2sin(x)'), + TokenInfo(type=token.NAME, string='x', start=(1, 5), end=(1, 6), line='2sin(x)'), + TokenInfo(type=token.OP, string=')', start=(1, 6), end=(1, 7), line='2sin(x)'), + TokenInfo(type=token.NEWLINE, string='', start=(1, 7), end=(1, 8), line='2sin(x)'), + TokenInfo(type=token.ENDMARKER, string='', start=(2, 0), end=(2, 0), line='') + ] + + tokens = list(generate_tokens(StringIO(source).readline)) + self.assertEqual(tokens, expected_tokens) + + def test_number_starting_with_zero(self): + source = "01234" + expected_tokens = [ + TokenInfo(type=token.NUMBER, string='01234', start=(1, 0), end=(1, 5), line='01234'), + TokenInfo(type=token.NEWLINE, string='', start=(1, 5), end=(1, 6), line='01234'), + TokenInfo(type=token.ENDMARKER, string='', start=(2, 0), end=(2, 0), line='') + ] + + tokens = list(generate_tokens(StringIO(source).readline)) + self.assertEqual(tokens, expected_tokens) + class CTokenizeTest(TestCase): def check_tokenize(self, s, expected): # Format the tokens in s in a table format. # The ENDMARKER and final NEWLINE are omitted. + f = StringIO(s) with self.subTest(source=s): result = stringify_tokens_from_source( - _generate_tokens_from_c_tokenizer(s), s + _generate_tokens_from_c_tokenizer(f.readline), s ) self.assertEqual(result, expected.rstrip().splitlines()) + def test_encoding(self): + def readline(encoding): + yield "1+1".encode(encoding) + + expected = [ + TokenInfo(type=NUMBER, string='1', start=(1, 0), end=(1, 1), line='1+1'), + TokenInfo(type=OP, string='+', start=(1, 1), end=(1, 2), line='1+1'), + TokenInfo(type=NUMBER, string='1', start=(1, 2), end=(1, 3), line='1+1'), + TokenInfo(type=NEWLINE, string='', start=(1, 3), end=(1, 4), line='1+1'), + TokenInfo(type=ENDMARKER, string='', start=(2, 0), end=(2, 0), line='') + ] + for encoding in ["utf-8", "latin-1", "utf-16"]: + with self.subTest(encoding=encoding): + tokens = list(_generate_tokens_from_c_tokenizer( + readline(encoding).__next__, + extra_tokens=True, + encoding=encoding, + )) + self.assertEqual(tokens, expected) + def test_int(self): self.check_tokenize('0xff <= 255', """\ @@ -1934,28 +2219,62 @@ b"""', """\ b\ c"""', """\ STRING 'rb"\""a\\\\\\nb\\\\\\nc"\""' (1, 0) (3, 4) + """) + + self.check_tokenize(r'"hola\\\r\ndfgf"', """\ + STRING \'"hola\\\\\\\\\\\\r\\\\ndfgf"\' (1, 0) (1, 16) """) self.check_tokenize('f"abc"', """\ - STRING 'f"abc"' (1, 0) (1, 6) + FSTRING_START 'f"' (1, 0) (1, 2) + FSTRING_MIDDLE 'abc' (1, 2) (1, 5) + FSTRING_END '"' (1, 5) (1, 6) """) self.check_tokenize('fR"a{b}c"', """\ - STRING 'fR"a{b}c"' (1, 0) (1, 9) + FSTRING_START 'fR"' (1, 0) (1, 3) + FSTRING_MIDDLE 'a' (1, 3) (1, 4) + LBRACE '{' (1, 4) (1, 5) + NAME 'b' (1, 5) (1, 6) + RBRACE '}' (1, 6) (1, 7) + FSTRING_MIDDLE 'c' (1, 7) (1, 8) + FSTRING_END '"' (1, 8) (1, 9) """) self.check_tokenize('f"""abc"""', """\ - STRING 'f\"\"\"abc\"\"\"' (1, 0) (1, 10) + FSTRING_START 'f\"""' (1, 0) (1, 4) + FSTRING_MIDDLE 'abc' (1, 4) (1, 7) + FSTRING_END '\"""' (1, 7) (1, 10) """) self.check_tokenize(r'f"abc\ def"', """\ - STRING 'f"abc\\\\\\ndef"' (1, 0) (2, 4) + FSTRING_START \'f"\' (1, 0) (1, 2) + FSTRING_MIDDLE 'abc\\\\\\ndef' (1, 2) (2, 3) + FSTRING_END '"' (2, 3) (2, 4) + """) + + self.check_tokenize('''\ +f"{ +a}"''', """\ + FSTRING_START 'f"' (1, 0) (1, 2) + LBRACE '{' (1, 2) (1, 3) + NAME 'a' (2, 0) (2, 1) + RBRACE '}' (2, 1) (2, 2) + FSTRING_END '"' (2, 2) (2, 3) """) self.check_tokenize(r'Rf"abc\ def"', """\ - STRING 'Rf"abc\\\\\\ndef"' (1, 0) (2, 4) + FSTRING_START 'Rf"' (1, 0) (1, 3) + FSTRING_MIDDLE 'abc\\\\\\ndef' (1, 3) (2, 3) + FSTRING_END '"' (2, 3) (2, 4) + """) + + self.check_tokenize(r'f"hola\\\r\ndfgf"', """\ + FSTRING_START \'f"\' (1, 0) (1, 2) + FSTRING_MIDDLE 'hola\\\\\\\\\\\\r\\\\ndfgf' (1, 2) (1, 16) + FSTRING_END \'"\' (1, 16) (1, 17) """) def test_function(self): @@ -2465,54 +2784,55 @@ async def f(): def test_unicode(self): self.check_tokenize("Örter = u'places'\ngrün = U'green'", """\ - NAME 'Örter' (1, 0) (1, 6) - EQUAL '=' (1, 7) (1, 8) - STRING "u'places'" (1, 9) (1, 18) - NEWLINE '' (1, 18) (1, 18) - NAME 'grün' (2, 0) (2, 5) - EQUAL '=' (2, 6) (2, 7) - STRING "U'green'" (2, 8) (2, 16) + NAME 'Örter' (1, 0) (1, 5) + EQUAL '=' (1, 6) (1, 7) + STRING "u'places'" (1, 8) (1, 17) + NEWLINE '' (1, 17) (1, 17) + NAME 'grün' (2, 0) (2, 4) + EQUAL '=' (2, 5) (2, 6) + STRING "U'green'" (2, 7) (2, 15) """) def test_invalid_syntax(self): def get_tokens(string): - return list(_generate_tokens_from_c_tokenizer(string)) - - self.assertRaises(SyntaxError, get_tokens, "(1+2]") - self.assertRaises(SyntaxError, get_tokens, "(1+2}") - self.assertRaises(SyntaxError, get_tokens, "{1+2]") - - self.assertRaises(SyntaxError, get_tokens, "1_") - self.assertRaises(SyntaxError, get_tokens, "1.2_") - self.assertRaises(SyntaxError, get_tokens, "1e2_") - self.assertRaises(SyntaxError, get_tokens, "1e+") - - self.assertRaises(SyntaxError, get_tokens, "\xa0") - self.assertRaises(SyntaxError, get_tokens, "€") - - self.assertRaises(SyntaxError, get_tokens, "0b12") - self.assertRaises(SyntaxError, get_tokens, "0b1_2") - self.assertRaises(SyntaxError, get_tokens, "0b2") - self.assertRaises(SyntaxError, get_tokens, "0b1_") - self.assertRaises(SyntaxError, get_tokens, "0b") - self.assertRaises(SyntaxError, get_tokens, "0o18") - self.assertRaises(SyntaxError, get_tokens, "0o1_8") - self.assertRaises(SyntaxError, get_tokens, "0o8") - self.assertRaises(SyntaxError, get_tokens, "0o1_") - self.assertRaises(SyntaxError, get_tokens, "0o") - self.assertRaises(SyntaxError, get_tokens, "0x1_") - self.assertRaises(SyntaxError, get_tokens, "0x") - self.assertRaises(SyntaxError, get_tokens, "1_") - self.assertRaises(SyntaxError, get_tokens, "012") - self.assertRaises(SyntaxError, get_tokens, "1.2_") - self.assertRaises(SyntaxError, get_tokens, "1e2_") - self.assertRaises(SyntaxError, get_tokens, "1e+") - - self.assertRaises(SyntaxError, get_tokens, "'sdfsdf") - self.assertRaises(SyntaxError, get_tokens, "'''sdfsdf''") - - self.assertRaises(SyntaxError, get_tokens, "("*1000+"a"+")"*1000) - self.assertRaises(SyntaxError, get_tokens, "]") + the_string = StringIO(string) + return list(_generate_tokens_from_c_tokenizer(the_string.readline)) + + for case in [ + "(1+2]", + "(1+2}", + "{1+2]", + "1_", + "1.2_", + "1e2_", + "1e+", + + "\xa0", + "€", + "0b12", + "0b1_2", + "0b2", + "0b1_", + "0b", + "0o18", + "0o1_8", + "0o8", + "0o1_", + "0o", + "0x1_", + "0x", + "1_", + "012", + "1.2_", + "1e2_", + "1e+", + "'sdfsdf", + "'''sdfsdf''", + "("*1000+"a"+")"*1000, + "]", + ]: + with self.subTest(case=case): + self.assertRaises(TokenError, get_tokens, case) def test_max_indent(self): MAXINDENT = 100 @@ -2523,20 +2843,24 @@ async def f(): return source valid = generate_source(MAXINDENT - 1) - tokens = list(_generate_tokens_from_c_tokenizer(valid)) - self.assertEqual(tokens[-1].type, DEDENT) + the_input = StringIO(valid) + tokens = list(_generate_tokens_from_c_tokenizer(the_input.readline)) + self.assertEqual(tokens[-2].type, DEDENT) + self.assertEqual(tokens[-1].type, ENDMARKER) compile(valid, "<string>", "exec") invalid = generate_source(MAXINDENT) - tokens = list(_generate_tokens_from_c_tokenizer(invalid)) - self.assertEqual(tokens[-1].type, NEWLINE) + the_input = StringIO(invalid) + self.assertRaises(IndentationError, lambda: list(_generate_tokens_from_c_tokenizer(the_input.readline))) self.assertRaises( IndentationError, compile, invalid, "<string>", "exec" ) def test_continuation_lines_indentation(self): def get_tokens(string): - return [(kind, string) for (kind, string, *_) in _generate_tokens_from_c_tokenizer(string)] + the_string = StringIO(string) + return [(kind, string) for (kind, string, *_) + in _generate_tokens_from_c_tokenizer(the_string.readline)] code = dedent(""" def fib(n): diff --git a/Lib/test/test_tomllib/test_misc.py b/Lib/test/test_tomllib/test_misc.py index a477a219..9e677a33 100644 --- a/Lib/test/test_tomllib/test_misc.py +++ b/Lib/test/test_tomllib/test_misc.py @@ -9,6 +9,7 @@ from pathlib import Path import sys import tempfile import unittest +from test import support from . import tomllib @@ -92,13 +93,23 @@ class TestMiscellaneous(unittest.TestCase): self.assertEqual(obj_copy, expected_obj) def test_inline_array_recursion_limit(self): - # 465 with default recursion limit - nest_count = int(sys.getrecursionlimit() * 0.465) - recursive_array_toml = "arr = " + nest_count * "[" + nest_count * "]" - tomllib.loads(recursive_array_toml) + with support.infinite_recursion(max_depth=100): + available = support.get_recursion_available() + nest_count = (available // 2) - 2 + # Add details if the test fails + with self.subTest(limit=sys.getrecursionlimit(), + available=available, + nest_count=nest_count): + recursive_array_toml = "arr = " + nest_count * "[" + nest_count * "]" + tomllib.loads(recursive_array_toml) def test_inline_table_recursion_limit(self): - # 310 with default recursion limit - nest_count = int(sys.getrecursionlimit() * 0.31) - recursive_table_toml = nest_count * "key = {" + nest_count * "}" - tomllib.loads(recursive_table_toml) + with support.infinite_recursion(max_depth=100): + available = support.get_recursion_available() + nest_count = (available // 3) - 1 + # Add details if the test fails + with self.subTest(limit=sys.getrecursionlimit(), + available=available, + nest_count=nest_count): + recursive_table_toml = nest_count * "key = {" + nest_count * "}" + tomllib.loads(recursive_table_toml) diff --git a/Lib/test/test_tools/test_fixcid.py b/Lib/test/test_tools/test_fixcid.py deleted file mode 100644 index a72f74b8..00000000 --- a/Lib/test/test_tools/test_fixcid.py +++ /dev/null @@ -1,94 +0,0 @@ -'''Test Tools/scripts/fixcid.py.''' - -from io import StringIO -import os, os.path -import runpy -import sys -from test import support -from test.support import os_helper -from test.test_tools import skip_if_missing, scriptsdir -import unittest - -skip_if_missing() - -class Test(unittest.TestCase): - def test_parse_strings(self): - old1 = 'int xx = "xx\\"xx"[xx];\n' - old2 = "int xx = 'x\\'xx' + xx;\n" - output = self.run_script(old1 + old2) - new1 = 'int yy = "xx\\"xx"[yy];\n' - new2 = "int yy = 'x\\'xx' + yy;\n" - self.assertMultiLineEqual(output, - "1\n" - "< {old1}" - "> {new1}" - "{new1}" - "2\n" - "< {old2}" - "> {new2}" - "{new2}".format(old1=old1, old2=old2, new1=new1, new2=new2) - ) - - def test_alter_comments(self): - output = self.run_script( - substfile= - "xx yy\n" - "*aa bb\n", - args=("-c", "-",), - input= - "/* xx altered */\n" - "int xx;\n" - "/* aa unaltered */\n" - "int aa;\n", - ) - self.assertMultiLineEqual(output, - "1\n" - "< /* xx altered */\n" - "> /* yy altered */\n" - "/* yy altered */\n" - "2\n" - "< int xx;\n" - "> int yy;\n" - "int yy;\n" - "/* aa unaltered */\n" - "4\n" - "< int aa;\n" - "> int bb;\n" - "int bb;\n" - ) - - def test_directory(self): - os.mkdir(os_helper.TESTFN) - self.addCleanup(os_helper.rmtree, os_helper.TESTFN) - c_filename = os.path.join(os_helper.TESTFN, "file.c") - with open(c_filename, "w", encoding="utf-8") as file: - file.write("int xx;\n") - with open(os.path.join(os_helper.TESTFN, "file.py"), "w", - encoding="utf-8") as file: - file.write("xx = 'unaltered'\n") - script = os.path.join(scriptsdir, "fixcid.py") - output = self.run_script(args=(os_helper.TESTFN,)) - self.assertMultiLineEqual(output, - "{}:\n" - "1\n" - '< int xx;\n' - '> int yy;\n'.format(c_filename) - ) - - def run_script(self, input="", *, args=("-",), substfile="xx yy\n"): - substfilename = os_helper.TESTFN + ".subst" - with open(substfilename, "w", encoding="utf-8") as file: - file.write(substfile) - self.addCleanup(os_helper.unlink, substfilename) - - argv = ["fixcid.py", "-s", substfilename] + list(args) - script = os.path.join(scriptsdir, "fixcid.py") - with support.swap_attr(sys, "argv", argv), \ - support.swap_attr(sys, "stdin", StringIO(input)), \ - support.captured_stdout() as output, \ - support.captured_stderr(): - try: - runpy.run_path(script, run_name="__main__") - except SystemExit as exit: - self.assertEqual(exit.code, 0) - return output.getvalue() diff --git a/Lib/test/test_tools/test_freeze.py b/Lib/test/test_tools/test_freeze.py index 2ba36ca2..922e74b4 100644 --- a/Lib/test/test_tools/test_freeze.py +++ b/Lib/test/test_tools/test_freeze.py @@ -17,6 +17,7 @@ with imports_under_tool('freeze', 'test'): @support.skip_if_buildbot('not all buildbots have enough space') class TestFreeze(unittest.TestCase): + @support.requires_resource('cpu') # Building Python is slow def test_freeze_simple_script(self): script = textwrap.dedent(""" import sys diff --git a/Lib/test/test_tools/test_gprof2html.py b/Lib/test/test_tools/test_gprof2html.py deleted file mode 100644 index 7cceb8fa..00000000 --- a/Lib/test/test_tools/test_gprof2html.py +++ /dev/null @@ -1,35 +0,0 @@ -"""Tests for the gprof2html script in the Tools directory.""" - -import os -import sys -import unittest -from unittest import mock -import tempfile - -from test.test_tools import skip_if_missing, import_tool - -skip_if_missing() - -class Gprof2htmlTests(unittest.TestCase): - - def setUp(self): - self.gprof = import_tool('gprof2html') - oldargv = sys.argv - def fixup(): - sys.argv = oldargv - self.addCleanup(fixup) - sys.argv = [] - - def test_gprof(self): - # Issue #14508: this used to fail with a NameError. - with mock.patch.object(self.gprof, 'webbrowser') as wmock, \ - tempfile.TemporaryDirectory() as tmpdir: - fn = os.path.join(tmpdir, 'abc') - open(fn, 'wb').close() - sys.argv = ['gprof2html', fn] - self.gprof.main() - self.assertTrue(wmock.open.called) - - -if __name__ == '__main__': - unittest.main() diff --git a/Lib/test/test_tools/test_lll.py b/Lib/test/test_tools/test_lll.py deleted file mode 100644 index 6eeb96ed..00000000 --- a/Lib/test/test_tools/test_lll.py +++ /dev/null @@ -1,41 +0,0 @@ -"""Tests for the lll script in the Tools/script directory.""" - -import os -import tempfile -from test import support -from test.support import os_helper -from test.test_tools import skip_if_missing, import_tool -import unittest - -skip_if_missing() - - -class lllTests(unittest.TestCase): - - def setUp(self): - self.lll = import_tool('lll') - - @os_helper.skip_unless_symlink - def test_lll_multiple_dirs(self): - with tempfile.TemporaryDirectory() as dir1, \ - tempfile.TemporaryDirectory() as dir2: - fn1 = os.path.join(dir1, 'foo1') - fn2 = os.path.join(dir2, 'foo2') - for fn, dir in (fn1, dir1), (fn2, dir2): - open(fn, 'wb').close() - os.symlink(fn, os.path.join(dir, 'symlink')) - - with support.captured_stdout() as output: - self.lll.main([dir1, dir2]) - prefix = '\\\\?\\' if os.name == 'nt' else '' - self.assertEqual(output.getvalue(), - f'{dir1}:\n' - f'symlink -> {prefix}{fn1}\n' - f'\n' - f'{dir2}:\n' - f'symlink -> {prefix}{fn2}\n' - ) - - -if __name__ == '__main__': - unittest.main() diff --git a/Lib/test/test_tools/test_md5sum.py b/Lib/test/test_tools/test_md5sum.py deleted file mode 100644 index c5a230e9..00000000 --- a/Lib/test/test_tools/test_md5sum.py +++ /dev/null @@ -1,79 +0,0 @@ -"""Tests for the md5sum script in the Tools directory.""" - -import sys -import os -import unittest -from test.support import os_helper -from test.support import hashlib_helper -from test.support.script_helper import assert_python_ok, assert_python_failure - -from test.test_tools import scriptsdir, skip_if_missing - -skip_if_missing() - -@hashlib_helper.requires_hashdigest('md5', openssl=True) -class MD5SumTests(unittest.TestCase): - @classmethod - def setUpClass(cls): - cls.script = os.path.join(scriptsdir, 'md5sum.py') - os.mkdir(os_helper.TESTFN_ASCII) - cls.fodder = os.path.join(os_helper.TESTFN_ASCII, 'md5sum.fodder') - with open(cls.fodder, 'wb') as f: - f.write(b'md5sum\r\ntest file\r\n') - cls.fodder_md5 = b'd38dae2eb1ab346a292ef6850f9e1a0d' - cls.fodder_textmode_md5 = b'a8b07894e2ca3f2a4c3094065fa6e0a5' - - @classmethod - def tearDownClass(cls): - os_helper.rmtree(os_helper.TESTFN_ASCII) - - def test_noargs(self): - rc, out, err = assert_python_ok(self.script) - self.assertEqual(rc, 0) - self.assertTrue( - out.startswith(b'd41d8cd98f00b204e9800998ecf8427e <stdin>')) - self.assertFalse(err) - - def test_checksum_fodder(self): - rc, out, err = assert_python_ok(self.script, self.fodder) - self.assertEqual(rc, 0) - self.assertTrue(out.startswith(self.fodder_md5)) - for part in self.fodder.split(os.path.sep): - self.assertIn(part.encode(), out) - self.assertFalse(err) - - def test_dash_l(self): - rc, out, err = assert_python_ok(self.script, '-l', self.fodder) - self.assertEqual(rc, 0) - self.assertIn(self.fodder_md5, out) - parts = self.fodder.split(os.path.sep) - self.assertIn(parts[-1].encode(), out) - self.assertNotIn(parts[-2].encode(), out) - - def test_dash_t(self): - rc, out, err = assert_python_ok(self.script, '-t', self.fodder) - self.assertEqual(rc, 0) - self.assertTrue(out.startswith(self.fodder_textmode_md5)) - self.assertNotIn(self.fodder_md5, out) - - def test_dash_s(self): - rc, out, err = assert_python_ok(self.script, '-s', '512', self.fodder) - self.assertEqual(rc, 0) - self.assertIn(self.fodder_md5, out) - - def test_multiple_files(self): - rc, out, err = assert_python_ok(self.script, self.fodder, self.fodder) - self.assertEqual(rc, 0) - lines = out.splitlines() - self.assertEqual(len(lines), 2) - self.assertEqual(*lines) - - def test_usage(self): - rc, out, err = assert_python_failure(self.script, '-h') - self.assertEqual(rc, 2) - self.assertEqual(out, b'') - self.assertGreater(err, b'') - - -if __name__ == '__main__': - unittest.main() diff --git a/Lib/test/test_tools/test_pathfix.py b/Lib/test/test_tools/test_pathfix.py deleted file mode 100644 index ff619352..00000000 --- a/Lib/test/test_tools/test_pathfix.py +++ /dev/null @@ -1,132 +0,0 @@ -import os -import subprocess -import sys -import unittest -from test import support -from test.support import os_helper -from test.test_tools import scriptsdir, skip_if_missing - - -# need Tools/script/ directory: skip if run on Python installed on the system -skip_if_missing() - - -class TestPathfixFunctional(unittest.TestCase): - script = os.path.join(scriptsdir, 'pathfix.py') - - def setUp(self): - self.addCleanup(os_helper.unlink, os_helper.TESTFN) - - def pathfix(self, shebang, pathfix_flags, exitcode=0, stdout='', stderr='', - directory=''): - if directory: - # bpo-38347: Test filename should contain lowercase, uppercase, - # "-", "_" and digits. - filename = os.path.join(directory, 'script-A_1.py') - pathfix_arg = directory - else: - filename = os_helper.TESTFN - pathfix_arg = filename - - with open(filename, 'w', encoding='utf8') as f: - f.write(f'{shebang}\n' + 'print("Hello world")\n') - - encoding = sys.getfilesystemencoding() - proc = subprocess.run( - [sys.executable, self.script, - *pathfix_flags, '-n', pathfix_arg], - env={**os.environ, 'PYTHONIOENCODING': encoding}, - capture_output=True) - - if stdout == '' and proc.returncode == 0: - stdout = f'{filename}: updating\n' - self.assertEqual(proc.returncode, exitcode, proc) - self.assertEqual(proc.stdout.decode(encoding), stdout.replace('\n', os.linesep), proc) - self.assertEqual(proc.stderr.decode(encoding), stderr.replace('\n', os.linesep), proc) - - with open(filename, 'r', encoding='utf8') as f: - output = f.read() - - lines = output.split('\n') - self.assertEqual(lines[1:], ['print("Hello world")', '']) - new_shebang = lines[0] - - if proc.returncode != 0: - self.assertEqual(shebang, new_shebang) - - return new_shebang - - def test_recursive(self): - tmpdir = os_helper.TESTFN + '.d' - self.addCleanup(os_helper.rmtree, tmpdir) - os.mkdir(tmpdir) - expected_stderr = f"recursedown('{os.path.basename(tmpdir)}')\n" - self.assertEqual( - self.pathfix( - '#! /usr/bin/env python', - ['-i', '/usr/bin/python3'], - directory=tmpdir, - stderr=expected_stderr), - '#! /usr/bin/python3') - - def test_pathfix(self): - self.assertEqual( - self.pathfix( - '#! /usr/bin/env python', - ['-i', '/usr/bin/python3']), - '#! /usr/bin/python3') - self.assertEqual( - self.pathfix( - '#! /usr/bin/env python -R', - ['-i', '/usr/bin/python3']), - '#! /usr/bin/python3') - - def test_pathfix_keeping_flags(self): - self.assertEqual( - self.pathfix( - '#! /usr/bin/env python -R', - ['-i', '/usr/bin/python3', '-k']), - '#! /usr/bin/python3 -R') - self.assertEqual( - self.pathfix( - '#! /usr/bin/env python', - ['-i', '/usr/bin/python3', '-k']), - '#! /usr/bin/python3') - - def test_pathfix_adding_flag(self): - self.assertEqual( - self.pathfix( - '#! /usr/bin/env python', - ['-i', '/usr/bin/python3', '-a', 's']), - '#! /usr/bin/python3 -s') - self.assertEqual( - self.pathfix( - '#! /usr/bin/env python -S', - ['-i', '/usr/bin/python3', '-a', 's']), - '#! /usr/bin/python3 -s') - self.assertEqual( - self.pathfix( - '#! /usr/bin/env python -V', - ['-i', '/usr/bin/python3', '-a', 'v', '-k']), - '#! /usr/bin/python3 -vV') - self.assertEqual( - self.pathfix( - '#! /usr/bin/env python', - ['-i', '/usr/bin/python3', '-a', 'Rs']), - '#! /usr/bin/python3 -Rs') - self.assertEqual( - self.pathfix( - '#! /usr/bin/env python -W default', - ['-i', '/usr/bin/python3', '-a', 's', '-k']), - '#! /usr/bin/python3 -sW default') - - def test_pathfix_adding_errors(self): - self.pathfix( - '#! /usr/bin/env python -E', - ['-i', '/usr/bin/python3', '-a', 'W default', '-k'], - exitcode=2, - stderr="-a option doesn't support whitespaces") - - -if __name__ == '__main__': - unittest.main() diff --git a/Lib/test/test_tools/test_pdeps.py b/Lib/test/test_tools/test_pdeps.py deleted file mode 100644 index a986d10e..00000000 --- a/Lib/test/test_tools/test_pdeps.py +++ /dev/null @@ -1,32 +0,0 @@ -"""Tests for the pdeps script in the Tools directory.""" - -import os -import unittest -import tempfile - -from test.test_tools import skip_if_missing, import_tool - -skip_if_missing() - - -class PdepsTests(unittest.TestCase): - - @classmethod - def setUpClass(self): - self.pdeps = import_tool('pdeps') - - def test_process_errors(self): - # Issue #14492: m_import.match(line) can be None. - with tempfile.TemporaryDirectory() as tmpdir: - fn = os.path.join(tmpdir, 'foo') - with open(fn, 'w', encoding='utf-8') as stream: - stream.write("#!/this/will/fail") - self.pdeps.process(fn, {}) - - def test_inverse_attribute_error(self): - # Issue #14492: this used to fail with an AttributeError. - self.pdeps.inverse({'a': []}) - - -if __name__ == '__main__': - unittest.main() diff --git a/Lib/test/test_tools/test_pindent.py b/Lib/test/test_tools/test_pindent.py deleted file mode 100644 index 01f13850..00000000 --- a/Lib/test/test_tools/test_pindent.py +++ /dev/null @@ -1,340 +0,0 @@ -"""Tests for the pindent script in the Tools directory.""" - -import os -import sys -import unittest -import subprocess -import textwrap -from test import support -from test.support import os_helper -from test.support.script_helper import assert_python_ok - -from test.test_tools import scriptsdir, skip_if_missing - -skip_if_missing() - - -class PindentTests(unittest.TestCase): - script = os.path.join(scriptsdir, 'pindent.py') - - def assertFileEqual(self, fn1, fn2): - with open(fn1) as f1, open(fn2) as f2: - self.assertEqual(f1.readlines(), f2.readlines()) - - def pindent(self, source, *args): - with subprocess.Popen( - (sys.executable, self.script) + args, - stdin=subprocess.PIPE, stdout=subprocess.PIPE, - universal_newlines=True) as proc: - out, err = proc.communicate(source) - self.assertIsNone(err) - return out - - def lstriplines(self, data): - return '\n'.join(line.lstrip() for line in data.splitlines()) + '\n' - - def test_selftest(self): - self.maxDiff = None - with os_helper.temp_dir() as directory: - data_path = os.path.join(directory, '_test.py') - with open(self.script, encoding='utf-8') as f: - closed = f.read() - with open(data_path, 'w', encoding='utf-8') as f: - f.write(closed) - - rc, out, err = assert_python_ok(self.script, '-d', data_path) - self.assertEqual(out, b'') - self.assertEqual(err, b'') - backup = data_path + '~' - self.assertTrue(os.path.exists(backup)) - with open(backup, encoding='utf-8') as f: - self.assertEqual(f.read(), closed) - with open(data_path, encoding='utf-8') as f: - clean = f.read() - compile(clean, '_test.py', 'exec') - self.assertEqual(self.pindent(clean, '-c'), closed) - self.assertEqual(self.pindent(closed, '-d'), clean) - - rc, out, err = assert_python_ok(self.script, '-c', data_path) - self.assertEqual(out, b'') - self.assertEqual(err, b'') - with open(backup, encoding='utf-8') as f: - self.assertEqual(f.read(), clean) - with open(data_path, encoding='utf-8') as f: - self.assertEqual(f.read(), closed) - - broken = self.lstriplines(closed) - with open(data_path, 'w', encoding='utf-8') as f: - f.write(broken) - rc, out, err = assert_python_ok(self.script, '-r', data_path) - self.assertEqual(out, b'') - self.assertEqual(err, b'') - with open(backup, encoding='utf-8') as f: - self.assertEqual(f.read(), broken) - with open(data_path, encoding='utf-8') as f: - indented = f.read() - compile(indented, '_test.py', 'exec') - self.assertEqual(self.pindent(broken, '-r'), indented) - - def pindent_test(self, clean, closed): - self.assertEqual(self.pindent(clean, '-c'), closed) - self.assertEqual(self.pindent(closed, '-d'), clean) - broken = self.lstriplines(closed) - self.assertEqual(self.pindent(broken, '-r', '-e', '-s', '4'), closed) - - def test_statements(self): - clean = textwrap.dedent("""\ - if a: - pass - - if a: - pass - else: - pass - - if a: - pass - elif: - pass - else: - pass - - while a: - break - - while a: - break - else: - pass - - for i in a: - break - - for i in a: - break - else: - pass - - try: - pass - finally: - pass - - try: - pass - except TypeError: - pass - except ValueError: - pass - else: - pass - - try: - pass - except TypeError: - pass - except ValueError: - pass - finally: - pass - - with a: - pass - - class A: - pass - - def f(): - pass - """) - - closed = textwrap.dedent("""\ - if a: - pass - # end if - - if a: - pass - else: - pass - # end if - - if a: - pass - elif: - pass - else: - pass - # end if - - while a: - break - # end while - - while a: - break - else: - pass - # end while - - for i in a: - break - # end for - - for i in a: - break - else: - pass - # end for - - try: - pass - finally: - pass - # end try - - try: - pass - except TypeError: - pass - except ValueError: - pass - else: - pass - # end try - - try: - pass - except TypeError: - pass - except ValueError: - pass - finally: - pass - # end try - - with a: - pass - # end with - - class A: - pass - # end class A - - def f(): - pass - # end def f - """) - self.pindent_test(clean, closed) - - def test_multilevel(self): - clean = textwrap.dedent("""\ - def foobar(a, b): - if a == b: - a = a+1 - elif a < b: - b = b-1 - if b > a: a = a-1 - else: - print 'oops!' - """) - closed = textwrap.dedent("""\ - def foobar(a, b): - if a == b: - a = a+1 - elif a < b: - b = b-1 - if b > a: a = a-1 - # end if - else: - print 'oops!' - # end if - # end def foobar - """) - self.pindent_test(clean, closed) - - def test_preserve_indents(self): - clean = textwrap.dedent("""\ - if a: - if b: - pass - """) - closed = textwrap.dedent("""\ - if a: - if b: - pass - # end if - # end if - """) - self.assertEqual(self.pindent(clean, '-c'), closed) - self.assertEqual(self.pindent(closed, '-d'), clean) - broken = self.lstriplines(closed) - self.assertEqual(self.pindent(broken, '-r', '-e', '-s', '9'), closed) - clean = textwrap.dedent("""\ - if a: - \tif b: - \t\tpass - """) - closed = textwrap.dedent("""\ - if a: - \tif b: - \t\tpass - \t# end if - # end if - """) - self.assertEqual(self.pindent(clean, '-c'), closed) - self.assertEqual(self.pindent(closed, '-d'), clean) - broken = self.lstriplines(closed) - self.assertEqual(self.pindent(broken, '-r'), closed) - - def test_escaped_newline(self): - clean = textwrap.dedent("""\ - class\\ - \\ - A: - def\ - \\ - f: - pass - """) - closed = textwrap.dedent("""\ - class\\ - \\ - A: - def\ - \\ - f: - pass - # end def f - # end class A - """) - self.assertEqual(self.pindent(clean, '-c'), closed) - self.assertEqual(self.pindent(closed, '-d'), clean) - - def test_empty_line(self): - clean = textwrap.dedent("""\ - if a: - - pass - """) - closed = textwrap.dedent("""\ - if a: - - pass - # end if - """) - self.pindent_test(clean, closed) - - def test_oneline(self): - clean = textwrap.dedent("""\ - if a: pass - """) - closed = textwrap.dedent("""\ - if a: pass - # end if - """) - self.pindent_test(clean, closed) - - -if __name__ == '__main__': - unittest.main() diff --git a/Lib/test/test_tools/test_reindent.py b/Lib/test/test_tools/test_reindent.py index 34df0c5d..3b0c793a 100644 --- a/Lib/test/test_tools/test_reindent.py +++ b/Lib/test/test_tools/test_reindent.py @@ -9,12 +9,12 @@ import unittest from test.support.script_helper import assert_python_ok from test.support import findfile -from test.test_tools import scriptsdir, skip_if_missing +from test.test_tools import toolsdir, skip_if_missing skip_if_missing() class ReindentTests(unittest.TestCase): - script = os.path.join(scriptsdir, 'reindent.py') + script = os.path.join(toolsdir, 'patchcheck', 'reindent.py') def test_noargs(self): assert_python_ok(self.script) diff --git a/Lib/test/test_tools/test_sundry.py b/Lib/test/test_tools/test_sundry.py index 52369ec0..3177fafb 100644 --- a/Lib/test/test_tools/test_sundry.py +++ b/Lib/test/test_tools/test_sundry.py @@ -1,4 +1,4 @@ -"""Tests for scripts in the Tools directory. +"""Tests for scripts in the Tools/scripts directory. This file contains extremely basic regression tests for the scripts found in the Tools directory of a Python checkout or tarball which don't have separate @@ -6,7 +6,6 @@ tests of their own. """ import os -import sys import unittest from test.support import import_helper @@ -18,18 +17,13 @@ class TestSundryScripts(unittest.TestCase): # At least make sure the rest don't have syntax errors. When tests are # added for a script it should be added to the allowlist below. - # scripts that have independent tests. - allowlist = ['reindent', 'pdeps', 'gprof2html', 'md5sum'] - # scripts that can't be imported without running - denylist = ['make_ctype'] - # scripts that use windows-only modules - windows_only = ['win_add2path'] - # denylisted for other reasons - other = ['analyze_dxp', '2to3'] + skiplist = ['2to3'] - skiplist = denylist + allowlist + windows_only + other - - def test_sundry(self): + # import logging registers "atfork" functions which keep indirectly the + # logging module dictionary alive. Mock the function to be able to unload + # cleanly the logging module. + @import_helper.mock_register_at_fork + def test_sundry(self, mock_os): old_modules = import_helper.modules_setup() try: for fn in os.listdir(scriptsdir): @@ -45,18 +39,6 @@ class TestSundryScripts(unittest.TestCase): # Unload all modules loaded in this test import_helper.modules_cleanup(*old_modules) - @unittest.skipIf(sys.platform != "win32", "Windows-only test") - def test_sundry_windows(self): - for name in self.windows_only: - import_tool(name) - - def test_analyze_dxp_import(self): - if hasattr(sys, 'getdxp'): - import_tool('analyze_dxp') - else: - with self.assertRaises(RuntimeError): - import_tool('analyze_dxp') - if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_trace.py b/Lib/test/test_trace.py index fad2b3b8..c1e289bc 100644 --- a/Lib/test/test_trace.py +++ b/Lib/test/test_trace.py @@ -1,7 +1,7 @@ import os from pickle import dump import sys -from test.support import captured_stdout +from test.support import captured_stdout, requires_resource from test.support.os_helper import (TESTFN, rmtree, unlink) from test.support.script_helper import assert_python_ok, assert_python_failure import textwrap @@ -187,9 +187,7 @@ class TestLineCounts(unittest.TestCase): firstlineno_called = get_firstlineno(traced_doubler) expected = { (self.my_py_filename, firstlineno_calling + 1): 1, - # List comprehensions work differently in 3.x, so the count - # below changed compared to 2.x. - (self.my_py_filename, firstlineno_calling + 2): 12, + (self.my_py_filename, firstlineno_calling + 2): 11, (self.my_py_filename, firstlineno_calling + 3): 1, (self.my_py_filename, firstlineno_called + 1): 10, } @@ -362,13 +360,19 @@ class TestCoverage(unittest.TestCase): rmtree(TESTFN) unlink(TESTFN) - def _coverage(self, tracer, - cmd='import test.support, test.test_pprint;' - 'test.support.run_unittest(test.test_pprint.QueryTestCase)'): + DEFAULT_SCRIPT = '''if True: + import unittest + from test.test_pprint import QueryTestCase + loader = unittest.TestLoader() + tests = loader.loadTestsFromTestCase(QueryTestCase) + tests(unittest.TestResult()) + ''' + def _coverage(self, tracer, cmd=DEFAULT_SCRIPT): tracer.run(cmd) r = tracer.results() r.write_results(show_missing=True, summary=True, coverdir=TESTFN) + @requires_resource('cpu') def test_coverage(self): tracer = trace.Trace(trace=0, count=1) with captured_stdout() as stdout: diff --git a/Lib/test/test_traceback.py b/Lib/test/test_traceback.py index eadc9c44..e84e8fec 100644 --- a/Lib/test/test_traceback.py +++ b/Lib/test/test_traceback.py @@ -6,19 +6,26 @@ import linecache import sys import types import inspect +import builtins import unittest import re +import tempfile +import random +import string from test import support +import shutil from test.support import (Error, captured_output, cpython_only, ALWAYS_EQ, requires_debug_ranges, has_no_debug_ranges, requires_subprocess) from test.support.os_helper import TESTFN, unlink from test.support.script_helper import assert_python_ok, assert_python_failure +from test.support.import_helper import forget -import os +import json import textwrap import traceback from functools import partial +from pathlib import Path MODULE_PREFIX = f'{__name__}.' if __name__ == '__main__' else '' @@ -28,6 +35,9 @@ test_frame = namedtuple('frame', ['f_code', 'f_globals', 'f_locals']) test_tb = namedtuple('tb', ['tb_frame', 'tb_lineno', 'tb_next', 'tb_lasti']) +LEVENSHTEIN_DATA_FILE = Path(__file__).parent / 'levenshtein_examples.json' + + class TracebackCases(unittest.TestCase): # For now, a very minimal set of tests. I want to be sure that # formatting of SyntaxErrors works based on changes for 2.1. @@ -286,15 +296,15 @@ class TracebackCases(unittest.TestCase): def __init__(self): try: x = 1 / 0 - except Exception: - self.exc_info = sys.exc_info() - # self.exc_info[1] (traceback) contains frames: + except Exception as e: + self.exc = e + # self.exc.__traceback__ contains frames: # explicitly clear the reference to self in the current # frame to break a reference cycle self = None def __del__(self): - traceback.print_exception(*self.exc_info) + traceback.print_exception(self.exc) # Keep a reference in the module namespace to call the destructor # when the module is unloaded @@ -372,20 +382,40 @@ class TracebackCases(unittest.TestCase): '(exc, /, value=<implicit>)') -@requires_debug_ranges() -class TracebackErrorLocationCaretTests(unittest.TestCase): - """ - Tests for printing code error expressions as part of PEP 657 - """ - def get_exception(self, callable): +class PurePythonExceptionFormattingMixin: + def get_exception(self, callable, slice_start=0, slice_end=-1): try: callable() self.fail("No exception thrown.") except: - return traceback.format_exc().splitlines()[:-1] + return traceback.format_exc().splitlines()[slice_start:slice_end] callable_line = get_exception.__code__.co_firstlineno + 2 + +class CAPIExceptionFormattingMixin: + LEGACY = 0 + + def get_exception(self, callable, slice_start=0, slice_end=-1): + from _testcapi import exception_print + try: + callable() + self.fail("No exception thrown.") + except Exception as e: + with captured_output("stderr") as tbstderr: + exception_print(e, self.LEGACY) + return tbstderr.getvalue().splitlines()[slice_start:slice_end] + + callable_line = get_exception.__code__.co_firstlineno + 3 + +class CAPIExceptionFormattingLegacyMixin(CAPIExceptionFormattingMixin): + LEGACY = 1 + +@requires_debug_ranges() +class TracebackErrorLocationCaretTestBase: + """ + Tests for printing code error expressions as part of PEP 657 + """ def test_basic_caret(self): # NOTE: In caret tests, "if True:" is used as a way to force indicator # display, since the raising expression spans only part of the line. @@ -566,6 +596,24 @@ class TracebackErrorLocationCaretTests(unittest.TestCase): result_lines = self.get_exception(f_with_binary_operator) self.assertEqual(result_lines, expected_error.splitlines()) + def test_caret_for_binary_operators_with_spaces_and_parenthesis(self): + def f_with_binary_operator(): + a = 1 + b = "" + return ( a ) + b + + lineno_f = f_with_binary_operator.__code__.co_firstlineno + expected_error = ( + 'Traceback (most recent call last):\n' + f' File "{__file__}", line {self.callable_line}, in get_exception\n' + ' callable()\n' + f' File "{__file__}", line {lineno_f+3}, in f_with_binary_operator\n' + ' return ( a ) + b\n' + ' ~~~~~~~~~~^~~\n' + ) + result_lines = self.get_exception(f_with_binary_operator) + self.assertEqual(result_lines, expected_error.splitlines()) + def test_caret_for_subscript(self): def f_with_subscript(): some_dict = {'x': {'y': None}} @@ -600,6 +648,24 @@ class TracebackErrorLocationCaretTests(unittest.TestCase): result_lines = self.get_exception(f_with_subscript) self.assertEqual(result_lines, expected_error.splitlines()) + def test_caret_for_subscript_with_spaces_and_parenthesis(self): + def f_with_binary_operator(): + a = [] + b = c = 1 + return b [ a ] + c + + lineno_f = f_with_binary_operator.__code__.co_firstlineno + expected_error = ( + 'Traceback (most recent call last):\n' + f' File "{__file__}", line {self.callable_line}, in get_exception\n' + ' callable()\n' + f' File "{__file__}", line {lineno_f+3}, in f_with_binary_operator\n' + ' return b [ a ] + c\n' + ' ~~~~~~^^^^^^^^^\n' + ) + result_lines = self.get_exception(f_with_binary_operator) + self.assertEqual(result_lines, expected_error.splitlines()) + def test_traceback_specialization_with_syntax_error(self): bytecode = compile("1 / 0 / 1 / 2\n", TESTFN, "exec") @@ -772,12 +838,12 @@ class TracebackErrorLocationCaretTests(unittest.TestCase): )() actual = self.get_exception(f) expected = [ - f"Traceback (most recent call last):", + "Traceback (most recent call last):", f" File \"{__file__}\", line {self.callable_line}, in get_exception", - f" callable()", + " callable()", f" File \"{__file__}\", line {f.__code__.co_firstlineno + 2}, in f", - f" .method", - f" ^^^^^^", + " .method", + " ^^^^^^", ] self.assertEqual(actual, expected) @@ -788,11 +854,11 @@ class TracebackErrorLocationCaretTests(unittest.TestCase): )() actual = self.get_exception(f) expected = [ - f"Traceback (most recent call last):", + "Traceback (most recent call last):", f" File \"{__file__}\", line {self.callable_line}, in get_exception", - f" callable()", + " callable()", f" File \"{__file__}\", line {f.__code__.co_firstlineno + 2}, in f", - f" method", + " method", ] self.assertEqual(actual, expected) @@ -803,12 +869,12 @@ class TracebackErrorLocationCaretTests(unittest.TestCase): )() actual = self.get_exception(f) expected = [ - f"Traceback (most recent call last):", + "Traceback (most recent call last):", f" File \"{__file__}\", line {self.callable_line}, in get_exception", - f" callable()", + " callable()", f" File \"{__file__}\", line {f.__code__.co_firstlineno + 2}, in f", - f" . method", - f" ^^^^^^", + " . method", + " ^^^^^^", ] self.assertEqual(actual, expected) @@ -818,11 +884,11 @@ class TracebackErrorLocationCaretTests(unittest.TestCase): actual = self.get_exception(f) expected = [ - f"Traceback (most recent call last):", + "Traceback (most recent call last):", f" File \"{__file__}\", line {self.callable_line}, in get_exception", - f" callable()", + " callable()", f" File \"{__file__}\", line {f.__code__.co_firstlineno + 1}, in f", - f" width", + " width", ] self.assertEqual(actual, expected) @@ -834,11 +900,11 @@ class TracebackErrorLocationCaretTests(unittest.TestCase): actual = self.get_exception(f) expected = [ - f"Traceback (most recent call last):", + "Traceback (most recent call last):", f" File \"{__file__}\", line {self.callable_line}, in get_exception", - f" callable()", + " callable()", f" File \"{__file__}\", line {f.__code__.co_firstlineno + 2}, in f", - f" raise ValueError(width)", + " raise ValueError(width)", ] self.assertEqual(actual, expected) @@ -852,34 +918,50 @@ class TracebackErrorLocationCaretTests(unittest.TestCase): actual = self.get_exception(f) expected = [ - f"Traceback (most recent call last):", + "Traceback (most recent call last):", f" File \"{__file__}\", line {self.callable_line}, in get_exception", - f" callable()", + " callable()", f" File \"{__file__}\", line {f.__code__.co_firstlineno + 4}, in f", - f" print(1, www(", - f" ^^^^", + " print(1, www(", + " ^^^^", ] self.assertEqual(actual, expected) + +@requires_debug_ranges() +class PurePythonTracebackErrorCaretTests( + PurePythonExceptionFormattingMixin, + TracebackErrorLocationCaretTestBase, + unittest.TestCase, +): + """ + Same set of tests as above using the pure Python implementation of + traceback printing in traceback.py. + """ + + @cpython_only @requires_debug_ranges() -class CPythonTracebackErrorCaretTests(TracebackErrorLocationCaretTests): +class CPythonTracebackErrorCaretTests( + CAPIExceptionFormattingMixin, + TracebackErrorLocationCaretTestBase, + unittest.TestCase, +): """ Same set of tests as above but with Python's internal traceback printing. """ - def get_exception(self, callable): - from _testcapi import exception_print - try: - callable() - self.fail("No exception thrown.") - except Exception as e: - with captured_output("stderr") as tbstderr: - exception_print(e) - return tbstderr.getvalue().splitlines()[:-1] - - callable_line = get_exception.__code__.co_firstlineno + 3 +@cpython_only +@requires_debug_ranges() +class CPythonTracebackLegacyErrorCaretTests( + CAPIExceptionFormattingLegacyMixin, + TracebackErrorLocationCaretTestBase, + unittest.TestCase, +): + """ + Same set of tests as above but with Python's legacy internal traceback printing. + """ class TracebackFormatTests(unittest.TestCase): @@ -891,8 +973,8 @@ class TracebackFormatTests(unittest.TestCase): from _testcapi import traceback_print try: self.some_exception() - except KeyError: - type_, value, tb = sys.exc_info() + except KeyError as e: + tb = e.__traceback__ if cleanup_func is not None: # Clear the inner frames, not this one cleanup_func(tb.tb_next) @@ -1165,8 +1247,7 @@ class TracebackFormatTests(unittest.TestCase): def test_recursive_traceback_cpython_internal(self): from _testcapi import exception_print def render_exc(): - exc_type, exc_value, exc_tb = sys.exc_info() - exception_print(exc_value) + exception_print(sys.exception()) self._check_recursive_traceback_display(render_exc) def test_format_stack(self): @@ -1196,8 +1277,8 @@ class TracebackFormatTests(unittest.TestCase): except UnhashableException: try: raise ex1 - except UnhashableException: - exc_type, exc_val, exc_tb = sys.exc_info() + except UnhashableException as e: + exc_val = e with captured_output("stderr") as stderr_f: exception_print(exc_val) @@ -1494,11 +1575,11 @@ class BaseExceptionReportingTests: e.__notes__ = BadThing() notes_repr = 'bad repr' - self.assertEqual(self.get_report(e), vanilla + notes_repr) + self.assertEqual(self.get_report(e), vanilla + notes_repr + '\n') e.__notes__ = Unprintable() err_msg = '<__notes__ repr() failed>' - self.assertEqual(self.get_report(e), vanilla + err_msg) + self.assertEqual(self.get_report(e), vanilla + err_msg + '\n') # non-string item in the __notes__ sequence e.__notes__ = [BadThing(), 'Final Note'] @@ -1510,6 +1591,14 @@ class BaseExceptionReportingTests: err_msg = '<note str() failed>' self.assertEqual(self.get_report(e), vanilla + err_msg + '\nFinal Note\n') + e.__notes__ = "please do not explode me" + err_msg = "'please do not explode me'" + self.assertEqual(self.get_report(e), vanilla + err_msg + '\n') + + e.__notes__ = b"please do not show me as numbers" + err_msg = "b'please do not show me as numbers'" + self.assertEqual(self.get_report(e), vanilla + err_msg + '\n') + def test_exception_with_note_with_multiple_notes(self): e = ValueError(42) vanilla = self.get_report(e) @@ -1562,6 +1651,21 @@ class BaseExceptionReportingTests: exp = "%s: %s\n" % (str_name, str_value) self.assertEqual(exp, err) + def test_exception_angle_bracketed_filename(self): + src = textwrap.dedent(""" + try: + raise ValueError(42) + except Exception as e: + exc = e + """) + + code = compile(src, "<does not exist>", "exec") + g, l = {}, {} + exec(code, g, l) + err = self.get_report(l['exc']) + exp = ' File "<does not exist>", line 3, in <module>\nValueError: 42\n' + self.assertIn(exp, err) + def test_exception_modulename_not_unicode(self): class X(Exception): def __str__(self): @@ -2086,8 +2190,8 @@ class LimitTests(unittest.TestCase): def test_extract_tb(self): try: self.last_raises5() - except Exception: - exc_type, exc_value, tb = sys.exc_info() + except Exception as e: + tb = e.__traceback__ def extract(**kwargs): return traceback.extract_tb(tb, **kwargs) @@ -2113,12 +2217,12 @@ class LimitTests(unittest.TestCase): def test_format_exception(self): try: self.last_raises5() - except Exception: - exc_type, exc_value, tb = sys.exc_info() + except Exception as e: + exc = e # [1:-1] to exclude "Traceback (...)" header and # exception type and value def extract(**kwargs): - return traceback.format_exception(exc_type, exc_value, tb, **kwargs)[1:-1] + return traceback.format_exception(exc, **kwargs)[1:-1] with support.swap_attr(sys, 'tracebacklimit', 1000): nolim = extract() @@ -2156,8 +2260,8 @@ class MiscTracebackCases(unittest.TestCase): try: outer() - except: - type_, value, tb = sys.exc_info() + except BaseException as e: + tb = e.__traceback__ # Initial assertion: there's one local in the inner frame. inner_frame = tb.tb_next.tb_next.tb_next.tb_frame @@ -2235,8 +2339,8 @@ class TestStack(unittest.TestCase): def test_walk_tb(self): try: 1/0 - except Exception: - _, _, tb = sys.exc_info() + except Exception as e: + tb = e.__traceback__ s = list(traceback.walk_tb(tb)) self.assertEqual(len(s), 1) @@ -2339,10 +2443,10 @@ class TestStack(unittest.TestCase): def g(): try: f() - except: - return sys.exc_info() + except Exception as e: + return e.__traceback__ - exc_info = g() + tb = g() class Skip_G(traceback.StackSummary): def format_frame_summary(self, frame_summary): @@ -2351,7 +2455,7 @@ class TestStack(unittest.TestCase): return super().format_frame_summary(frame_summary) stack = Skip_G.extract( - traceback.walk_tb(exc_info[2])).format() + traceback.walk_tb(tb)).format() self.assertEqual(len(stack), 1) lno = f.__code__.co_firstlineno + 1 @@ -2360,23 +2464,26 @@ class TestStack(unittest.TestCase): f' File "{__file__}", line {lno}, in f\n 1/0\n' ) +class Unrepresentable: + def __repr__(self) -> str: + raise Exception("Unrepresentable") class TestTracebackException(unittest.TestCase): def test_smoke(self): try: 1/0 - except Exception: - exc_info = sys.exc_info() - exc = traceback.TracebackException(*exc_info) + except Exception as e: + exc_obj = e + exc = traceback.TracebackException.from_exception(e) expected_stack = traceback.StackSummary.extract( - traceback.walk_tb(exc_info[2])) + traceback.walk_tb(e.__traceback__)) self.assertEqual(None, exc.__cause__) self.assertEqual(None, exc.__context__) self.assertEqual(False, exc.__suppress_context__) self.assertEqual(expected_stack, exc.stack) - self.assertEqual(exc_info[0], exc.exc_type) - self.assertEqual(str(exc_info[1]), str(exc)) + self.assertEqual(type(exc_obj), exc.exc_type) + self.assertEqual(str(exc_obj), str(exc)) def test_from_exception(self): # Check all the parameters are accepted. @@ -2385,9 +2492,10 @@ class TestTracebackException(unittest.TestCase): try: foo() except Exception as e: - exc_info = sys.exc_info() + exc_obj = e + tb = e.__traceback__ self.expected_stack = traceback.StackSummary.extract( - traceback.walk_tb(exc_info[2]), limit=1, lookup_lines=False, + traceback.walk_tb(tb), limit=1, lookup_lines=False, capture_locals=True) self.exc = traceback.TracebackException.from_exception( e, limit=1, lookup_lines=False, capture_locals=True) @@ -2397,50 +2505,50 @@ class TestTracebackException(unittest.TestCase): self.assertEqual(None, exc.__context__) self.assertEqual(False, exc.__suppress_context__) self.assertEqual(expected_stack, exc.stack) - self.assertEqual(exc_info[0], exc.exc_type) - self.assertEqual(str(exc_info[1]), str(exc)) + self.assertEqual(type(exc_obj), exc.exc_type) + self.assertEqual(str(exc_obj), str(exc)) def test_cause(self): try: try: 1/0 finally: - exc_info_context = sys.exc_info() - exc_context = traceback.TracebackException(*exc_info_context) + exc = sys.exception() + exc_context = traceback.TracebackException.from_exception(exc) cause = Exception("cause") raise Exception("uh oh") from cause - except Exception: - exc_info = sys.exc_info() - exc = traceback.TracebackException(*exc_info) + except Exception as e: + exc_obj = e + exc = traceback.TracebackException.from_exception(e) expected_stack = traceback.StackSummary.extract( - traceback.walk_tb(exc_info[2])) + traceback.walk_tb(e.__traceback__)) exc_cause = traceback.TracebackException(Exception, cause, None) self.assertEqual(exc_cause, exc.__cause__) self.assertEqual(exc_context, exc.__context__) self.assertEqual(True, exc.__suppress_context__) self.assertEqual(expected_stack, exc.stack) - self.assertEqual(exc_info[0], exc.exc_type) - self.assertEqual(str(exc_info[1]), str(exc)) + self.assertEqual(type(exc_obj), exc.exc_type) + self.assertEqual(str(exc_obj), str(exc)) def test_context(self): try: try: 1/0 finally: - exc_info_context = sys.exc_info() - exc_context = traceback.TracebackException(*exc_info_context) + exc = sys.exception() + exc_context = traceback.TracebackException.from_exception(exc) raise Exception("uh oh") - except Exception: - exc_info = sys.exc_info() - exc = traceback.TracebackException(*exc_info) + except Exception as e: + exc_obj = e + exc = traceback.TracebackException.from_exception(e) expected_stack = traceback.StackSummary.extract( - traceback.walk_tb(exc_info[2])) + traceback.walk_tb(e.__traceback__)) self.assertEqual(None, exc.__cause__) self.assertEqual(exc_context, exc.__context__) self.assertEqual(False, exc.__suppress_context__) self.assertEqual(expected_stack, exc.stack) - self.assertEqual(exc_info[0], exc.exc_type) - self.assertEqual(str(exc_info[1]), str(exc)) + self.assertEqual(type(exc_obj), exc.exc_type) + self.assertEqual(str(exc_obj), str(exc)) def test_long_context_chain(self): def f(): @@ -2451,12 +2559,12 @@ class TestTracebackException(unittest.TestCase): try: f() - except RecursionError: - exc_info = sys.exc_info() + except RecursionError as e: + exc_obj = e else: self.fail("Exception not raised") - te = traceback.TracebackException(*exc_info) + te = traceback.TracebackException.from_exception(exc_obj) res = list(te.format()) # many ZeroDiv errors followed by the RecursionError @@ -2474,58 +2582,58 @@ class TestTracebackException(unittest.TestCase): finally: cause = Exception("cause") raise Exception("uh oh") from cause - except Exception: - exc_info = sys.exc_info() - exc = traceback.TracebackException(*exc_info, compact=True) + except Exception as e: + exc_obj = e + exc = traceback.TracebackException.from_exception(exc_obj, compact=True) expected_stack = traceback.StackSummary.extract( - traceback.walk_tb(exc_info[2])) + traceback.walk_tb(exc_obj.__traceback__)) exc_cause = traceback.TracebackException(Exception, cause, None) self.assertEqual(exc_cause, exc.__cause__) self.assertEqual(None, exc.__context__) self.assertEqual(True, exc.__suppress_context__) self.assertEqual(expected_stack, exc.stack) - self.assertEqual(exc_info[0], exc.exc_type) - self.assertEqual(str(exc_info[1]), str(exc)) + self.assertEqual(type(exc_obj), exc.exc_type) + self.assertEqual(str(exc_obj), str(exc)) def test_compact_no_cause(self): try: try: 1/0 finally: - exc_info_context = sys.exc_info() - exc_context = traceback.TracebackException(*exc_info_context) + exc = sys.exception() + exc_context = traceback.TracebackException.from_exception(exc) raise Exception("uh oh") - except Exception: - exc_info = sys.exc_info() - exc = traceback.TracebackException(*exc_info, compact=True) + except Exception as e: + exc_obj = e + exc = traceback.TracebackException.from_exception(e, compact=True) expected_stack = traceback.StackSummary.extract( - traceback.walk_tb(exc_info[2])) + traceback.walk_tb(exc_obj.__traceback__)) self.assertEqual(None, exc.__cause__) self.assertEqual(exc_context, exc.__context__) self.assertEqual(False, exc.__suppress_context__) self.assertEqual(expected_stack, exc.stack) - self.assertEqual(exc_info[0], exc.exc_type) - self.assertEqual(str(exc_info[1]), str(exc)) + self.assertEqual(type(exc_obj), exc.exc_type) + self.assertEqual(str(exc_obj), str(exc)) def test_no_refs_to_exception_and_traceback_objects(self): try: 1/0 - except Exception: - exc_info = sys.exc_info() + except Exception as e: + exc_obj = e - refcnt1 = sys.getrefcount(exc_info[1]) - refcnt2 = sys.getrefcount(exc_info[2]) - exc = traceback.TracebackException(*exc_info) - self.assertEqual(sys.getrefcount(exc_info[1]), refcnt1) - self.assertEqual(sys.getrefcount(exc_info[2]), refcnt2) + refcnt1 = sys.getrefcount(exc_obj) + refcnt2 = sys.getrefcount(exc_obj.__traceback__) + exc = traceback.TracebackException.from_exception(exc_obj) + self.assertEqual(sys.getrefcount(exc_obj), refcnt1) + self.assertEqual(sys.getrefcount(exc_obj.__traceback__), refcnt2) def test_comparison_basic(self): try: 1/0 - except Exception: - exc_info = sys.exc_info() - exc = traceback.TracebackException(*exc_info) - exc2 = traceback.TracebackException(*exc_info) + except Exception as e: + exc_obj = e + exc = traceback.TracebackException.from_exception(exc_obj) + exc2 = traceback.TracebackException.from_exception(exc_obj) self.assertIsNot(exc, exc2) self.assertEqual(exc, exc2) self.assertNotEqual(exc, object()) @@ -2544,28 +2652,28 @@ class TestTracebackException(unittest.TestCase): try: raise_with_locals() - except Exception: - exc_info = sys.exc_info() + except Exception as e: + exc_obj = e - exc = traceback.TracebackException(*exc_info) - exc1 = traceback.TracebackException(*exc_info, limit=10) - exc2 = traceback.TracebackException(*exc_info, limit=2) + exc = traceback.TracebackException.from_exception(exc_obj) + exc1 = traceback.TracebackException.from_exception(exc_obj, limit=10) + exc2 = traceback.TracebackException.from_exception(exc_obj, limit=2) self.assertEqual(exc, exc1) # limit=10 gets all frames self.assertNotEqual(exc, exc2) # limit=2 truncates the output # locals change the output - exc3 = traceback.TracebackException(*exc_info, capture_locals=True) + exc3 = traceback.TracebackException.from_exception(exc_obj, capture_locals=True) self.assertNotEqual(exc, exc3) # there are no locals in the innermost frame - exc4 = traceback.TracebackException(*exc_info, limit=-1) - exc5 = traceback.TracebackException(*exc_info, limit=-1, capture_locals=True) + exc4 = traceback.TracebackException.from_exception(exc_obj, limit=-1) + exc5 = traceback.TracebackException.from_exception(exc_obj, limit=-1, capture_locals=True) self.assertEqual(exc4, exc5) # there are locals in the next-to-innermost frame - exc6 = traceback.TracebackException(*exc_info, limit=-2) - exc7 = traceback.TracebackException(*exc_info, limit=-2, capture_locals=True) + exc6 = traceback.TracebackException.from_exception(exc_obj, limit=-2) + exc7 = traceback.TracebackException.from_exception(exc_obj, limit=-2, capture_locals=True) self.assertNotEqual(exc6, exc7) def test_comparison_equivalent_exceptions_are_equal(self): @@ -2573,8 +2681,8 @@ class TestTracebackException(unittest.TestCase): for _ in range(2): try: 1/0 - except: - excs.append(traceback.TracebackException(*sys.exc_info())) + except Exception as e: + excs.append(traceback.TracebackException.from_exception(e)) self.assertEqual(excs[0], excs[1]) self.assertEqual(list(excs[0].format()), list(excs[1].format())) @@ -2590,9 +2698,9 @@ class TestTracebackException(unittest.TestCase): except UnhashableException: try: raise ex1 - except UnhashableException: - exc_info = sys.exc_info() - exc = traceback.TracebackException(*exc_info) + except UnhashableException as e: + exc_obj = e + exc = traceback.TracebackException.from_exception(exc_obj) formatted = list(exc.format()) self.assertIn('UnhashableException: ex2\n', formatted[2]) self.assertIn('UnhashableException: ex1\n', formatted[6]) @@ -2605,11 +2713,10 @@ class TestTracebackException(unittest.TestCase): 1/0 try: recurse(10) - except Exception: - exc_info = sys.exc_info() - exc = traceback.TracebackException(*exc_info, limit=5) + except Exception as e: + exc = traceback.TracebackException.from_exception(e, limit=5) expected_stack = traceback.StackSummary.extract( - traceback.walk_tb(exc_info[2]), limit=5) + traceback.walk_tb(e.__traceback__), limit=5) self.assertEqual(expected_stack, exc.stack) def test_lookup_lines(self): @@ -2627,12 +2734,13 @@ class TestTracebackException(unittest.TestCase): linecache.updatecache('/foo.py', globals()) e = Exception("uh oh") c = test_code('/foo.py', 'method') - f = test_frame(c, globals(), {'something': 1, 'other': 'string'}) + f = test_frame(c, globals(), {'something': 1, 'other': 'string', 'unrepresentable': Unrepresentable()}) tb = test_tb(f, 6, None, 0) exc = traceback.TracebackException( Exception, e, tb, capture_locals=True) self.assertEqual( - exc.stack[0].locals, {'something': '1', 'other': "'string'"}) + exc.stack[0].locals, + {'something': '1', 'other': "'string'", 'unrepresentable': '<local repr() failed>'}) def test_no_locals(self): linecache.updatecache('/foo.py', globals()) @@ -2655,9 +2763,9 @@ class TestTracebackException(unittest.TestCase): x = 12 try: x/0 - except Exception: - return sys.exc_info() - exc = traceback.TracebackException(*f(), capture_locals=True) + except Exception as e: + return e + exc = traceback.TracebackException.from_exception(f(), capture_locals=True) output = StringIO() exc.print(file=output) self.assertEqual( @@ -2672,7 +2780,7 @@ class TestTracebackException(unittest.TestCase): class TestTracebackException_ExceptionGroups(unittest.TestCase): def setUp(self): super().setUp() - self.eg_info = self._get_exception_group() + self.eg = self._get_exception_group() def _get_exception_group(self): def f(): @@ -2702,26 +2810,26 @@ class TestTracebackException_ExceptionGroups(unittest.TestCase): except Exception as e: exc4 = e raise ExceptionGroup("eg2", [exc3, exc4]) - except ExceptionGroup: - return sys.exc_info() + except ExceptionGroup as eg: + return eg self.fail('Exception Not Raised') def test_exception_group_construction(self): - eg_info = self.eg_info - teg1 = traceback.TracebackException(*eg_info) - teg2 = traceback.TracebackException.from_exception(eg_info[1]) + eg = self.eg + teg1 = traceback.TracebackException(type(eg), eg, eg.__traceback__) + teg2 = traceback.TracebackException.from_exception(eg) self.assertIsNot(teg1, teg2) self.assertEqual(teg1, teg2) def test_exception_group_format_exception_only(self): - teg = traceback.TracebackException(*self.eg_info) + teg = traceback.TracebackException.from_exception(self.eg) formatted = ''.join(teg.format_exception_only()).split('\n') expected = "ExceptionGroup: eg2 (2 sub-exceptions)\n".split('\n') self.assertEqual(formatted, expected) def test_exception_group_format(self): - teg = traceback.TracebackException(*self.eg_info) + teg = traceback.TracebackException.from_exception(self.eg) formatted = ''.join(teg.format()).split('\n') lno_f = self.lno_f @@ -2780,26 +2888,26 @@ class TestTracebackException_ExceptionGroups(unittest.TestCase): formatted = ''.join(teg.format()).split('\n') expected = [ - f' | ExceptionGroup: eg (2 sub-exceptions)', - f' +-+---------------- 1 ----------------', - f' | ExceptionGroup: eg1 (3 sub-exceptions)', - f' +-+---------------- 1 ----------------', - f' | ValueError: 0', - f' +---------------- 2 ----------------', - f' | ValueError: 1', - f' +---------------- ... ----------------', - f' | and 1 more exception', - f' +------------------------------------', - f' +---------------- 2 ----------------', - f' | ExceptionGroup: eg2 (10 sub-exceptions)', - f' +-+---------------- 1 ----------------', - f' | TypeError: 0', - f' +---------------- 2 ----------------', - f' | TypeError: 1', - f' +---------------- ... ----------------', - f' | and 8 more exceptions', - f' +------------------------------------', - f''] + ' | ExceptionGroup: eg (2 sub-exceptions)', + ' +-+---------------- 1 ----------------', + ' | ExceptionGroup: eg1 (3 sub-exceptions)', + ' +-+---------------- 1 ----------------', + ' | ValueError: 0', + ' +---------------- 2 ----------------', + ' | ValueError: 1', + ' +---------------- ... ----------------', + ' | and 1 more exception', + ' +------------------------------------', + ' +---------------- 2 ----------------', + ' | ExceptionGroup: eg2 (10 sub-exceptions)', + ' +-+---------------- 1 ----------------', + ' | TypeError: 0', + ' +---------------- 2 ----------------', + ' | TypeError: 1', + ' +---------------- ... ----------------', + ' | and 8 more exceptions', + ' +------------------------------------', + ''] self.assertEqual(formatted, expected) @@ -2812,39 +2920,39 @@ class TestTracebackException_ExceptionGroups(unittest.TestCase): formatted = ''.join(teg.format()).split('\n') expected = [ - f' | ExceptionGroup: exc (3 sub-exceptions)', - f' +-+---------------- 1 ----------------', - f' | ValueError: -2', - f' +---------------- 2 ----------------', - f' | ExceptionGroup: exc (3 sub-exceptions)', - f' +-+---------------- 1 ----------------', - f' | ValueError: -1', - f' +---------------- 2 ----------------', - f' | ... (max_group_depth is 2)', - f' +---------------- 3 ----------------', - f' | ValueError: 1', - f' +------------------------------------', - f' +---------------- 3 ----------------', - f' | ValueError: 2', - f' +------------------------------------', - f''] + ' | ExceptionGroup: exc (3 sub-exceptions)', + ' +-+---------------- 1 ----------------', + ' | ValueError: -2', + ' +---------------- 2 ----------------', + ' | ExceptionGroup: exc (3 sub-exceptions)', + ' +-+---------------- 1 ----------------', + ' | ValueError: -1', + ' +---------------- 2 ----------------', + ' | ... (max_group_depth is 2)', + ' +---------------- 3 ----------------', + ' | ValueError: 1', + ' +------------------------------------', + ' +---------------- 3 ----------------', + ' | ValueError: 2', + ' +------------------------------------', + ''] self.assertEqual(formatted, expected) def test_comparison(self): try: - raise self.eg_info[1] - except ExceptionGroup: - exc_info = sys.exc_info() + raise self.eg + except ExceptionGroup as e: + exc = e for _ in range(5): try: - raise exc_info[1] - except: - exc_info = sys.exc_info() - exc = traceback.TracebackException(*exc_info) - exc2 = traceback.TracebackException(*exc_info) - exc3 = traceback.TracebackException(*exc_info, limit=300) - ne = traceback.TracebackException(*exc_info, limit=3) + raise exc + except Exception as e: + exc_obj = e + exc = traceback.TracebackException.from_exception(exc_obj) + exc2 = traceback.TracebackException.from_exception(exc_obj) + exc3 = traceback.TracebackException.from_exception(exc_obj, limit=300) + ne = traceback.TracebackException.from_exception(exc_obj, limit=3) self.assertIsNot(exc, exc2) self.assertEqual(exc, exc2) self.assertEqual(exc, exc3) @@ -2853,6 +2961,564 @@ class TestTracebackException_ExceptionGroups(unittest.TestCase): self.assertEqual(exc, ALWAYS_EQ) +global_for_suggestions = None + + +class SuggestionFormattingTestBase: + def get_suggestion(self, obj, attr_name=None): + if attr_name is not None: + def callable(): + getattr(obj, attr_name) + else: + callable = obj + + result_lines = self.get_exception( + callable, slice_start=-1, slice_end=None + ) + return result_lines[0] + + def test_getattr_suggestions(self): + class Substitution: + noise = more_noise = a = bc = None + blech = None + + class Elimination: + noise = more_noise = a = bc = None + blch = None + + class Addition: + noise = more_noise = a = bc = None + bluchin = None + + class SubstitutionOverElimination: + blach = None + bluc = None + + class SubstitutionOverAddition: + blach = None + bluchi = None + + class EliminationOverAddition: + blucha = None + bluc = None + + class CaseChangeOverSubstitution: + Luch = None + fluch = None + BLuch = None + + for cls, suggestion in [ + (Addition, "'bluchin'?"), + (Substitution, "'blech'?"), + (Elimination, "'blch'?"), + (Addition, "'bluchin'?"), + (SubstitutionOverElimination, "'blach'?"), + (SubstitutionOverAddition, "'blach'?"), + (EliminationOverAddition, "'bluc'?"), + (CaseChangeOverSubstitution, "'BLuch'?"), + ]: + actual = self.get_suggestion(cls(), 'bluch') + self.assertIn(suggestion, actual) + + def test_getattr_suggestions_do_not_trigger_for_long_attributes(self): + class A: + blech = None + + actual = self.get_suggestion(A(), 'somethingverywrong') + self.assertNotIn("blech", actual) + + def test_getattr_error_bad_suggestions_do_not_trigger_for_small_names(self): + class MyClass: + vvv = mom = w = id = pytho = None + + for name in ("b", "v", "m", "py"): + with self.subTest(name=name): + actual = self.get_suggestion(MyClass, name) + self.assertNotIn("Did you mean", actual) + self.assertNotIn("'vvv", actual) + self.assertNotIn("'mom'", actual) + self.assertNotIn("'id'", actual) + self.assertNotIn("'w'", actual) + self.assertNotIn("'pytho'", actual) + + def test_getattr_suggestions_do_not_trigger_for_big_dicts(self): + class A: + blech = None + # A class with a very big __dict__ will not be considered + # for suggestions. + for index in range(2000): + setattr(A, f"index_{index}", None) + + actual = self.get_suggestion(A(), 'bluch') + self.assertNotIn("blech", actual) + + def test_getattr_suggestions_no_args(self): + class A: + blech = None + def __getattr__(self, attr): + raise AttributeError() + + actual = self.get_suggestion(A(), 'bluch') + self.assertIn("blech", actual) + + class A: + blech = None + def __getattr__(self, attr): + raise AttributeError + + actual = self.get_suggestion(A(), 'bluch') + self.assertIn("blech", actual) + + def test_getattr_suggestions_invalid_args(self): + class NonStringifyClass: + __str__ = None + __repr__ = None + + class A: + blech = None + def __getattr__(self, attr): + raise AttributeError(NonStringifyClass()) + + class B: + blech = None + def __getattr__(self, attr): + raise AttributeError("Error", 23) + + class C: + blech = None + def __getattr__(self, attr): + raise AttributeError(23) + + for cls in [A, B, C]: + actual = self.get_suggestion(cls(), 'bluch') + self.assertIn("blech", actual) + + def test_getattr_suggestions_for_same_name(self): + class A: + def __dir__(self): + return ['blech'] + actual = self.get_suggestion(A(), 'blech') + self.assertNotIn("Did you mean", actual) + + def test_attribute_error_with_failing_dict(self): + class T: + bluch = 1 + def __dir__(self): + raise AttributeError("oh no!") + + actual = self.get_suggestion(T(), 'blich') + self.assertNotIn("blech", actual) + self.assertNotIn("oh no!", actual) + + def test_attribute_error_with_bad_name(self): + def raise_attribute_error_with_bad_name(): + raise AttributeError(name=12, obj=23) + + result_lines = self.get_exception( + raise_attribute_error_with_bad_name, slice_start=-1, slice_end=None + ) + self.assertNotIn("?", result_lines[-1]) + + def test_attribute_error_inside_nested_getattr(self): + class A: + bluch = 1 + + class B: + def __getattribute__(self, attr): + a = A() + return a.blich + + actual = self.get_suggestion(B(), 'something') + self.assertIn("Did you mean", actual) + self.assertIn("bluch", actual) + + def make_module(self, code): + tmpdir = Path(tempfile.mkdtemp()) + self.addCleanup(shutil.rmtree, tmpdir) + + sys.path.append(str(tmpdir)) + self.addCleanup(sys.path.pop) + + mod_name = ''.join(random.choices(string.ascii_letters, k=16)) + module = tmpdir / (mod_name + ".py") + module.write_text(code) + + return mod_name + + def get_import_from_suggestion(self, mod_dict, name): + modname = self.make_module(mod_dict) + + def callable(): + try: + exec(f"from {modname} import {name}") + except ImportError as e: + raise e from None + except Exception as e: + self.fail(f"Expected ImportError but got {type(e)}") + self.addCleanup(forget, modname) + + result_lines = self.get_exception( + callable, slice_start=-1, slice_end=None + ) + return result_lines[0] + + def test_import_from_suggestions(self): + substitution = textwrap.dedent("""\ + noise = more_noise = a = bc = None + blech = None + """) + + elimination = textwrap.dedent(""" + noise = more_noise = a = bc = None + blch = None + """) + + addition = textwrap.dedent(""" + noise = more_noise = a = bc = None + bluchin = None + """) + + substitutionOverElimination = textwrap.dedent(""" + blach = None + bluc = None + """) + + substitutionOverAddition = textwrap.dedent(""" + blach = None + bluchi = None + """) + + eliminationOverAddition = textwrap.dedent(""" + blucha = None + bluc = None + """) + + caseChangeOverSubstitution = textwrap.dedent(""" + Luch = None + fluch = None + BLuch = None + """) + + for code, suggestion in [ + (addition, "'bluchin'?"), + (substitution, "'blech'?"), + (elimination, "'blch'?"), + (addition, "'bluchin'?"), + (substitutionOverElimination, "'blach'?"), + (substitutionOverAddition, "'blach'?"), + (eliminationOverAddition, "'bluc'?"), + (caseChangeOverSubstitution, "'BLuch'?"), + ]: + actual = self.get_import_from_suggestion(code, 'bluch') + self.assertIn(suggestion, actual) + + def test_import_from_suggestions_do_not_trigger_for_long_attributes(self): + code = "blech = None" + + actual = self.get_suggestion(code, 'somethingverywrong') + self.assertNotIn("blech", actual) + + def test_import_from_error_bad_suggestions_do_not_trigger_for_small_names(self): + code = "vvv = mom = w = id = pytho = None" + + for name in ("b", "v", "m", "py"): + with self.subTest(name=name): + actual = self.get_import_from_suggestion(code, name) + self.assertNotIn("Did you mean", actual) + self.assertNotIn("'vvv'", actual) + self.assertNotIn("'mom'", actual) + self.assertNotIn("'id'", actual) + self.assertNotIn("'w'", actual) + self.assertNotIn("'pytho'", actual) + + def test_import_from_suggestions_do_not_trigger_for_big_namespaces(self): + # A module with lots of names will not be considered for suggestions. + chunks = [f"index_{index} = " for index in range(200)] + chunks.append(" None") + code = " ".join(chunks) + actual = self.get_import_from_suggestion(code, 'bluch') + self.assertNotIn("blech", actual) + + def test_import_from_error_with_bad_name(self): + def raise_attribute_error_with_bad_name(): + raise ImportError(name=12, obj=23, name_from=11) + + result_lines = self.get_exception( + raise_attribute_error_with_bad_name, slice_start=-1, slice_end=None + ) + self.assertNotIn("?", result_lines[-1]) + + def test_name_error_suggestions(self): + def Substitution(): + noise = more_noise = a = bc = None + blech = None + print(bluch) + + def Elimination(): + noise = more_noise = a = bc = None + blch = None + print(bluch) + + def Addition(): + noise = more_noise = a = bc = None + bluchin = None + print(bluch) + + def SubstitutionOverElimination(): + blach = None + bluc = None + print(bluch) + + def SubstitutionOverAddition(): + blach = None + bluchi = None + print(bluch) + + def EliminationOverAddition(): + blucha = None + bluc = None + print(bluch) + + for func, suggestion in [(Substitution, "'blech'?"), + (Elimination, "'blch'?"), + (Addition, "'bluchin'?"), + (EliminationOverAddition, "'blucha'?"), + (SubstitutionOverElimination, "'blach'?"), + (SubstitutionOverAddition, "'blach'?")]: + actual = self.get_suggestion(func) + self.assertIn(suggestion, actual) + + def test_name_error_suggestions_from_globals(self): + def func(): + print(global_for_suggestio) + actual = self.get_suggestion(func) + self.assertIn("'global_for_suggestions'?", actual) + + def test_name_error_suggestions_from_builtins(self): + def func(): + print(ZeroDivisionErrrrr) + actual = self.get_suggestion(func) + self.assertIn("'ZeroDivisionError'?", actual) + + def test_name_error_suggestions_from_builtins_when_builtins_is_module(self): + def func(): + custom_globals = globals().copy() + custom_globals["__builtins__"] = builtins + print(eval("ZeroDivisionErrrrr", custom_globals)) + actual = self.get_suggestion(func) + self.assertIn("'ZeroDivisionError'?", actual) + + def test_name_error_suggestions_do_not_trigger_for_long_names(self): + def func(): + somethingverywronghehehehehehe = None + print(somethingverywronghe) + actual = self.get_suggestion(func) + self.assertNotIn("somethingverywronghehe", actual) + + def test_name_error_bad_suggestions_do_not_trigger_for_small_names(self): + + def f_b(): + vvv = mom = w = id = pytho = None + b + + def f_v(): + vvv = mom = w = id = pytho = None + v + + def f_m(): + vvv = mom = w = id = pytho = None + m + + def f_py(): + vvv = mom = w = id = pytho = None + py + + for name, func in (("b", f_b), ("v", f_v), ("m", f_m), ("py", f_py)): + with self.subTest(name=name): + actual = self.get_suggestion(func) + self.assertNotIn("you mean", actual) + self.assertNotIn("vvv", actual) + self.assertNotIn("mom", actual) + self.assertNotIn("'id'", actual) + self.assertNotIn("'w'", actual) + self.assertNotIn("'pytho'", actual) + + def test_name_error_suggestions_do_not_trigger_for_too_many_locals(self): + def func(): + # Mutating locals() is unreliable, so we need to do it by hand + a1 = a2 = a3 = a4 = a5 = a6 = a7 = a8 = a9 = a10 = \ + a11 = a12 = a13 = a14 = a15 = a16 = a17 = a18 = a19 = a20 = \ + a21 = a22 = a23 = a24 = a25 = a26 = a27 = a28 = a29 = a30 = \ + a31 = a32 = a33 = a34 = a35 = a36 = a37 = a38 = a39 = a40 = \ + a41 = a42 = a43 = a44 = a45 = a46 = a47 = a48 = a49 = a50 = \ + a51 = a52 = a53 = a54 = a55 = a56 = a57 = a58 = a59 = a60 = \ + a61 = a62 = a63 = a64 = a65 = a66 = a67 = a68 = a69 = a70 = \ + a71 = a72 = a73 = a74 = a75 = a76 = a77 = a78 = a79 = a80 = \ + a81 = a82 = a83 = a84 = a85 = a86 = a87 = a88 = a89 = a90 = \ + a91 = a92 = a93 = a94 = a95 = a96 = a97 = a98 = a99 = a100 = \ + a101 = a102 = a103 = a104 = a105 = a106 = a107 = a108 = a109 = a110 = \ + a111 = a112 = a113 = a114 = a115 = a116 = a117 = a118 = a119 = a120 = \ + a121 = a122 = a123 = a124 = a125 = a126 = a127 = a128 = a129 = a130 = \ + a131 = a132 = a133 = a134 = a135 = a136 = a137 = a138 = a139 = a140 = \ + a141 = a142 = a143 = a144 = a145 = a146 = a147 = a148 = a149 = a150 = \ + a151 = a152 = a153 = a154 = a155 = a156 = a157 = a158 = a159 = a160 = \ + a161 = a162 = a163 = a164 = a165 = a166 = a167 = a168 = a169 = a170 = \ + a171 = a172 = a173 = a174 = a175 = a176 = a177 = a178 = a179 = a180 = \ + a181 = a182 = a183 = a184 = a185 = a186 = a187 = a188 = a189 = a190 = \ + a191 = a192 = a193 = a194 = a195 = a196 = a197 = a198 = a199 = a200 = \ + a201 = a202 = a203 = a204 = a205 = a206 = a207 = a208 = a209 = a210 = \ + a211 = a212 = a213 = a214 = a215 = a216 = a217 = a218 = a219 = a220 = \ + a221 = a222 = a223 = a224 = a225 = a226 = a227 = a228 = a229 = a230 = \ + a231 = a232 = a233 = a234 = a235 = a236 = a237 = a238 = a239 = a240 = \ + a241 = a242 = a243 = a244 = a245 = a246 = a247 = a248 = a249 = a250 = \ + a251 = a252 = a253 = a254 = a255 = a256 = a257 = a258 = a259 = a260 = \ + a261 = a262 = a263 = a264 = a265 = a266 = a267 = a268 = a269 = a270 = \ + a271 = a272 = a273 = a274 = a275 = a276 = a277 = a278 = a279 = a280 = \ + a281 = a282 = a283 = a284 = a285 = a286 = a287 = a288 = a289 = a290 = \ + a291 = a292 = a293 = a294 = a295 = a296 = a297 = a298 = a299 = a300 = \ + a301 = a302 = a303 = a304 = a305 = a306 = a307 = a308 = a309 = a310 = \ + a311 = a312 = a313 = a314 = a315 = a316 = a317 = a318 = a319 = a320 = \ + a321 = a322 = a323 = a324 = a325 = a326 = a327 = a328 = a329 = a330 = \ + a331 = a332 = a333 = a334 = a335 = a336 = a337 = a338 = a339 = a340 = \ + a341 = a342 = a343 = a344 = a345 = a346 = a347 = a348 = a349 = a350 = \ + a351 = a352 = a353 = a354 = a355 = a356 = a357 = a358 = a359 = a360 = \ + a361 = a362 = a363 = a364 = a365 = a366 = a367 = a368 = a369 = a370 = \ + a371 = a372 = a373 = a374 = a375 = a376 = a377 = a378 = a379 = a380 = \ + a381 = a382 = a383 = a384 = a385 = a386 = a387 = a388 = a389 = a390 = \ + a391 = a392 = a393 = a394 = a395 = a396 = a397 = a398 = a399 = a400 = \ + a401 = a402 = a403 = a404 = a405 = a406 = a407 = a408 = a409 = a410 = \ + a411 = a412 = a413 = a414 = a415 = a416 = a417 = a418 = a419 = a420 = \ + a421 = a422 = a423 = a424 = a425 = a426 = a427 = a428 = a429 = a430 = \ + a431 = a432 = a433 = a434 = a435 = a436 = a437 = a438 = a439 = a440 = \ + a441 = a442 = a443 = a444 = a445 = a446 = a447 = a448 = a449 = a450 = \ + a451 = a452 = a453 = a454 = a455 = a456 = a457 = a458 = a459 = a460 = \ + a461 = a462 = a463 = a464 = a465 = a466 = a467 = a468 = a469 = a470 = \ + a471 = a472 = a473 = a474 = a475 = a476 = a477 = a478 = a479 = a480 = \ + a481 = a482 = a483 = a484 = a485 = a486 = a487 = a488 = a489 = a490 = \ + a491 = a492 = a493 = a494 = a495 = a496 = a497 = a498 = a499 = a500 = \ + a501 = a502 = a503 = a504 = a505 = a506 = a507 = a508 = a509 = a510 = \ + a511 = a512 = a513 = a514 = a515 = a516 = a517 = a518 = a519 = a520 = \ + a521 = a522 = a523 = a524 = a525 = a526 = a527 = a528 = a529 = a530 = \ + a531 = a532 = a533 = a534 = a535 = a536 = a537 = a538 = a539 = a540 = \ + a541 = a542 = a543 = a544 = a545 = a546 = a547 = a548 = a549 = a550 = \ + a551 = a552 = a553 = a554 = a555 = a556 = a557 = a558 = a559 = a560 = \ + a561 = a562 = a563 = a564 = a565 = a566 = a567 = a568 = a569 = a570 = \ + a571 = a572 = a573 = a574 = a575 = a576 = a577 = a578 = a579 = a580 = \ + a581 = a582 = a583 = a584 = a585 = a586 = a587 = a588 = a589 = a590 = \ + a591 = a592 = a593 = a594 = a595 = a596 = a597 = a598 = a599 = a600 = \ + a601 = a602 = a603 = a604 = a605 = a606 = a607 = a608 = a609 = a610 = \ + a611 = a612 = a613 = a614 = a615 = a616 = a617 = a618 = a619 = a620 = \ + a621 = a622 = a623 = a624 = a625 = a626 = a627 = a628 = a629 = a630 = \ + a631 = a632 = a633 = a634 = a635 = a636 = a637 = a638 = a639 = a640 = \ + a641 = a642 = a643 = a644 = a645 = a646 = a647 = a648 = a649 = a650 = \ + a651 = a652 = a653 = a654 = a655 = a656 = a657 = a658 = a659 = a660 = \ + a661 = a662 = a663 = a664 = a665 = a666 = a667 = a668 = a669 = a670 = \ + a671 = a672 = a673 = a674 = a675 = a676 = a677 = a678 = a679 = a680 = \ + a681 = a682 = a683 = a684 = a685 = a686 = a687 = a688 = a689 = a690 = \ + a691 = a692 = a693 = a694 = a695 = a696 = a697 = a698 = a699 = a700 = \ + a701 = a702 = a703 = a704 = a705 = a706 = a707 = a708 = a709 = a710 = \ + a711 = a712 = a713 = a714 = a715 = a716 = a717 = a718 = a719 = a720 = \ + a721 = a722 = a723 = a724 = a725 = a726 = a727 = a728 = a729 = a730 = \ + a731 = a732 = a733 = a734 = a735 = a736 = a737 = a738 = a739 = a740 = \ + a741 = a742 = a743 = a744 = a745 = a746 = a747 = a748 = a749 = a750 = \ + a751 = a752 = a753 = a754 = a755 = a756 = a757 = a758 = a759 = a760 = \ + a761 = a762 = a763 = a764 = a765 = a766 = a767 = a768 = a769 = a770 = \ + a771 = a772 = a773 = a774 = a775 = a776 = a777 = a778 = a779 = a780 = \ + a781 = a782 = a783 = a784 = a785 = a786 = a787 = a788 = a789 = a790 = \ + a791 = a792 = a793 = a794 = a795 = a796 = a797 = a798 = a799 = a800 \ + = None + print(a0) + + actual = self.get_suggestion(func) + self.assertNotRegex(actual, r"NameError.*a1") + + def test_name_error_with_custom_exceptions(self): + def func(): + blech = None + raise NameError() + + actual = self.get_suggestion(func) + self.assertNotIn("blech", actual) + + def func(): + blech = None + raise NameError + + actual = self.get_suggestion(func) + self.assertNotIn("blech", actual) + + def test_name_error_with_instance(self): + class A: + def __init__(self): + self.blech = None + def foo(self): + blich = 1 + x = blech + + instance = A() + actual = self.get_suggestion(instance.foo) + self.assertIn("self.blech", actual) + + def test_unbound_local_error_with_instance(self): + class A: + def __init__(self): + self.blech = None + def foo(self): + blich = 1 + x = blech + blech = 1 + + instance = A() + actual = self.get_suggestion(instance.foo) + self.assertNotIn("self.blech", actual) + + def test_unbound_local_error_does_not_match(self): + def func(): + something = 3 + print(somethong) + somethong = 3 + + actual = self.get_suggestion(func) + self.assertNotIn("something", actual) + + def test_name_error_for_stdlib_modules(self): + def func(): + stream = io.StringIO() + + actual = self.get_suggestion(func) + self.assertIn("forget to import 'io'", actual) + + def test_name_error_for_private_stdlib_modules(self): + def func(): + stream = _io.StringIO() + + actual = self.get_suggestion(func) + self.assertIn("forget to import '_io'", actual) + + + +class PurePythonSuggestionFormattingTests( + PurePythonExceptionFormattingMixin, + SuggestionFormattingTestBase, + unittest.TestCase, +): + """ + Same set of tests as above using the pure Python implementation of + traceback printing in traceback.py. + """ + + +@cpython_only +class CPythonSuggestionFormattingTests( + CAPIExceptionFormattingMixin, + SuggestionFormattingTestBase, + unittest.TestCase, +): + """ + Same set of tests as above but with Python's internal traceback printing. + """ + + class MiscTest(unittest.TestCase): def test_all(self): @@ -2866,6 +3532,60 @@ class MiscTest(unittest.TestCase): expected.add(name) self.assertCountEqual(traceback.__all__, expected) + def test_levenshtein_distance(self): + # copied from _testinternalcapi.test_edit_cost + # to also exercise the Python implementation + + def CHECK(a, b, expected): + actual = traceback._levenshtein_distance(a, b, 4044) + self.assertEqual(actual, expected) + + CHECK("", "", 0) + CHECK("", "a", 2) + CHECK("a", "A", 1) + CHECK("Apple", "Aple", 2) + CHECK("Banana", "B@n@n@", 6) + CHECK("Cherry", "Cherry!", 2) + CHECK("---0---", "------", 2) + CHECK("abc", "y", 6) + CHECK("aa", "bb", 4) + CHECK("aaaaa", "AAAAA", 5) + CHECK("wxyz", "wXyZ", 2) + CHECK("wxyz", "wXyZ123", 8) + CHECK("Python", "Java", 12) + CHECK("Java", "C#", 8) + CHECK("AbstractFoobarManager", "abstract_foobar_manager", 3+2*2) + CHECK("CPython", "PyPy", 10) + CHECK("CPython", "pypy", 11) + CHECK("AttributeError", "AttributeErrop", 2) + CHECK("AttributeError", "AttributeErrorTests", 10) + CHECK("ABA", "AAB", 4) + + @support.requires_resource('cpu') + def test_levenshtein_distance_short_circuit(self): + if not LEVENSHTEIN_DATA_FILE.is_file(): + self.fail( + f"{LEVENSHTEIN_DATA_FILE} is missing." + f" Run `make regen-test-levenshtein`" + ) + + with LEVENSHTEIN_DATA_FILE.open("r") as f: + examples = json.load(f) + for a, b, expected in examples: + res1 = traceback._levenshtein_distance(a, b, 1000) + self.assertEqual(res1, expected, msg=(a, b)) + + for threshold in [expected, expected + 1, expected + 2]: + # big enough thresholds shouldn't change the result + res2 = traceback._levenshtein_distance(a, b, threshold) + self.assertEqual(res2, expected, msg=(a, b, threshold)) + + for threshold in range(expected): + # for small thresholds, the only piece of information + # we receive is "strings not close enough". + res3 = traceback._levenshtein_distance(a, b, threshold) + self.assertGreater(res3, threshold, msg=(a, b, threshold)) + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_ttk_guionly.py b/Lib/test/test_ttk/__init__.py similarity index 68% rename from Lib/test/test_ttk_guionly.py rename to Lib/test/test_ttk/__init__.py index c4919045..7ee7ffbd 100644 --- a/Lib/test/test_ttk_guionly.py +++ b/Lib/test/test_ttk/__init__.py @@ -1,10 +1,11 @@ +import os.path import unittest from test import support from test.support import import_helper -from test.support import check_sanitizer -if check_sanitizer(address=True, memory=True): - raise unittest.SkipTest("Tests involvin libX11 can SEGFAULT on ASAN/MSAN builds") + +if support.check_sanitizer(address=True, memory=True): + raise unittest.SkipTest("Tests involving libX11 can SEGFAULT on ASAN/MSAN builds") # Skip this test if _tkinter wasn't built. import_helper.import_module('_tkinter') @@ -12,6 +13,7 @@ import_helper.import_module('_tkinter') # Skip test if tk cannot be initialized. support.requires('gui') + import tkinter from _tkinter import TclError from tkinter import ttk @@ -32,9 +34,6 @@ def setUpModule(): root.destroy() del root -def load_tests(loader, tests, pattern): - return loader.discover('tkinter.test.test_ttk') - -if __name__ == '__main__': - unittest.main() +def load_tests(*args): + return support.load_package_tests(os.path.dirname(__file__), *args) diff --git a/Lib/test/test_ttk/__main__.py b/Lib/test/test_ttk/__main__.py new file mode 100644 index 00000000..40a23a29 --- /dev/null +++ b/Lib/test/test_ttk/__main__.py @@ -0,0 +1,4 @@ +from . import load_tests +import unittest + +unittest.main() diff --git a/Lib/tkinter/test/test_ttk/test_extensions.py b/Lib/test/test_ttk/test_extensions.py similarity index 98% rename from Lib/tkinter/test/test_ttk/test_extensions.py rename to Lib/test/test_ttk/test_extensions.py index 1220c483..d5e06971 100644 --- a/Lib/tkinter/test/test_ttk/test_extensions.py +++ b/Lib/test/test_ttk/test_extensions.py @@ -3,7 +3,7 @@ import unittest import tkinter from tkinter import ttk from test.support import requires, gc_collect -from tkinter.test.support import AbstractTkTest, AbstractDefaultRootTest +from test.test_tkinter.support import AbstractTkTest, AbstractDefaultRootTest requires('gui') @@ -45,7 +45,9 @@ class LabeledScaleTest(AbstractTkTest, unittest.TestCase): # value which causes the tracing callback to be called and then # it tries calling instance attributes not yet defined. ttk.LabeledScale(self.root, variable=myvar) - if hasattr(sys, 'last_type'): + if hasattr(sys, 'last_exc'): + self.assertNotEqual(type(sys.last_exc), tkinter.TclError) + elif hasattr(sys, 'last_type'): self.assertNotEqual(sys.last_type, tkinter.TclError) def test_initialization(self): diff --git a/Lib/tkinter/test/test_ttk/test_style.py b/Lib/test/test_ttk/test_style.py similarity index 98% rename from Lib/tkinter/test/test_ttk/test_style.py rename to Lib/test/test_ttk/test_style.py index 54ad3437..f9c56ec2 100644 --- a/Lib/tkinter/test/test_ttk/test_style.py +++ b/Lib/test/test_ttk/test_style.py @@ -4,7 +4,7 @@ import tkinter from tkinter import ttk from test import support from test.support import requires -from tkinter.test.support import AbstractTkTest, get_tk_patchlevel +from test.test_tkinter.support import AbstractTkTest, get_tk_patchlevel requires('gui') @@ -170,7 +170,7 @@ class StyleTest(AbstractTkTest, unittest.TestCase): newname = f'C.{name}' self.assertEqual(style.map(newname), {}) style.map(newname, **default) - if theme == 'alt' and name == '.' and get_tk_patchlevel() < (8, 6, 1): + if theme == 'alt' and name == '.' and get_tk_patchlevel(self.root) < (8, 6, 1): default['embossed'] = [('disabled', '1')] self.assertEqual(style.map(newname), default) for key, value in default.items(): diff --git a/Lib/tkinter/test/test_ttk/test_widgets.py b/Lib/test/test_ttk/test_widgets.py similarity index 99% rename from Lib/tkinter/test/test_ttk/test_widgets.py rename to Lib/test/test_ttk/test_widgets.py index 96d2afcf..fd1a748a 100644 --- a/Lib/tkinter/test/test_ttk/test_widgets.py +++ b/Lib/test/test_ttk/test_widgets.py @@ -5,11 +5,10 @@ from test.support import requires, gc_collect import sys from test.test_ttk_textonly import MockTclObj -from tkinter.test.support import (AbstractTkTest, tcl_version, get_tk_patchlevel, +from test.test_tkinter.support import (AbstractTkTest, tk_version, get_tk_patchlevel, simulate_mouse_click, AbstractDefaultRootTest) -from tkinter.test.widget_tests import (add_standard_options, - AbstractWidgetTest, StandardOptionsTests, IntegerSizeTests, PixelSizeTests, - setUpModule) +from test.test_tkinter.widget_tests import (add_standard_options, + AbstractWidgetTest, StandardOptionsTests, IntegerSizeTests, PixelSizeTests) requires('gui') @@ -20,7 +19,7 @@ class StandardTtkOptionsTests(StandardOptionsTests): widget = self.create() self.assertEqual(widget['class'], '') errmsg='attempt to change read-only option' - if get_tk_patchlevel() < (8, 6, 0, 'beta', 3): + if get_tk_patchlevel(self.root) < (8, 6, 0, 'beta', 3): errmsg='Attempt to change read-only option' self.checkInvalidParam(widget, 'class', 'Foo', errmsg=errmsg) widget2 = self.create(class_='Foo') @@ -50,7 +49,6 @@ class StandardTtkOptionsTests(StandardOptionsTests): widget2 = self.create(class_='Foo') self.assertEqual(widget2['class'], 'Foo') # XXX - pass class WidgetTest(AbstractTkTest, unittest.TestCase): @@ -562,7 +560,7 @@ class PanedWindowTest(AbstractWidgetTest, unittest.TestCase): widget = self.create() self.assertEqual(str(widget['orient']), 'vertical') errmsg='attempt to change read-only option' - if get_tk_patchlevel() < (8, 6, 0, 'beta', 3): + if get_tk_patchlevel(self.root) < (8, 6, 0, 'beta', 3): errmsg='Attempt to change read-only option' self.checkInvalidParam(widget, 'orient', 'horizontal', errmsg=errmsg) @@ -1528,7 +1526,7 @@ class TreeviewTest(AbstractWidgetTest, unittest.TestCase): def test_heading_callback(self): def simulate_heading_click(x, y): - if tcl_version >= (8, 6): + if tk_version >= (8, 6): self.assertEqual(self.tv.identify_column(x), '#0') self.assertEqual(self.tv.identify_region(x, y), 'heading') simulate_mouse_click(self.tv, x, y) diff --git a/Lib/test/test_turtle.py b/Lib/test/test_turtle.py index 95af84e3..14121a59 100644 --- a/Lib/test/test_turtle.py +++ b/Lib/test/test_turtle.py @@ -267,6 +267,14 @@ class TestTNavigator(VectorComparisonMixin, unittest.TestCase): self.assertAlmostEqual(self.nav.xcor(), 100) self.assertAlmostEqual(self.nav.ycor(), -100) + def test_teleport(self): + self.nav.teleport(20, -30, fill_gap=True) + self.assertAlmostEqual(self.nav.xcor(), 20) + self.assertAlmostEqual(self.nav.ycor(), -30) + self.nav.teleport(-20, 30, fill_gap=False) + self.assertAlmostEqual(self.nav.xcor(), -20) + self.assertAlmostEqual(self.nav.ycor(), 30) + def test_pos(self): self.assertEqual(self.nav.pos(), self.nav._position) self.nav.goto(100, -100) @@ -440,6 +448,38 @@ class TestTPen(unittest.TestCase): tpen.showturtle() self.assertTrue(tpen.isvisible()) + def test_teleport(self): + + tpen = turtle.TPen() + + for fill_gap_value in [True, False]: + tpen.penup() + tpen.teleport(100, 100, fill_gap=fill_gap_value) + self.assertFalse(tpen.isdown()) + tpen.pendown() + tpen.teleport(-100, -100, fill_gap=fill_gap_value) + self.assertTrue(tpen.isdown()) + + +class TestModuleLevel(unittest.TestCase): + def test_all_signatures(self): + import inspect + + known_signatures = { + 'teleport': + '(x=None, y=None, *, fill_gap: bool = False) -> None', + 'undo': '()', + 'goto': '(x, y=None)', + 'bgcolor': '(*args)', + 'pen': '(pen=None, **pendict)', + } + + for name in known_signatures: + with self.subTest(name=name): + obj = getattr(turtle, name) + sig = inspect.signature(obj) + self.assertEqual(str(sig), known_signatures[name]) + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_type_aliases.py b/Lib/test/test_type_aliases.py new file mode 100644 index 00000000..8f0a998e --- /dev/null +++ b/Lib/test/test_type_aliases.py @@ -0,0 +1,330 @@ +import pickle +import types +import unittest +from test.support import check_syntax_error, run_code +from test import mod_generics_cache + +from typing import Callable, TypeAliasType, TypeVar, get_args + + +class TypeParamsInvalidTest(unittest.TestCase): + def test_name_collisions(self): + check_syntax_error(self, 'type TA1[A, **A] = None', "duplicate type parameter 'A'") + check_syntax_error(self, 'type T[A, *A] = None', "duplicate type parameter 'A'") + check_syntax_error(self, 'type T[*A, **A] = None', "duplicate type parameter 'A'") + + def test_name_non_collision_02(self): + ns = run_code("""type TA1[A] = lambda A: A""") + self.assertIsInstance(ns["TA1"], TypeAliasType) + self.assertTrue(callable(ns["TA1"].__value__)) + self.assertEqual("arg", ns["TA1"].__value__("arg")) + + def test_name_non_collision_03(self): + ns = run_code(""" + class Outer[A]: + type TA1[A] = None + """ + ) + outer_A, = ns["Outer"].__type_params__ + inner_A, = ns["Outer"].TA1.__type_params__ + self.assertIsNot(outer_A, inner_A) + + +class TypeParamsAccessTest(unittest.TestCase): + def test_alias_access_01(self): + ns = run_code("type TA1[A, B] = dict[A, B]") + alias = ns["TA1"] + self.assertIsInstance(alias, TypeAliasType) + self.assertEqual(alias.__type_params__, get_args(alias.__value__)) + + def test_alias_access_02(self): + ns = run_code(""" + type TA1[A, B] = TA1[A, B] | int + """ + ) + alias = ns["TA1"] + self.assertIsInstance(alias, TypeAliasType) + A, B = alias.__type_params__ + self.assertEqual(alias.__value__, alias[A, B] | int) + + def test_alias_access_03(self): + ns = run_code(""" + class Outer[A]: + def inner[B](self): + type TA1[C] = TA1[A, B] | int + return TA1 + """ + ) + cls = ns["Outer"] + A, = cls.__type_params__ + B, = cls.inner.__type_params__ + alias = cls.inner(None) + self.assertIsInstance(alias, TypeAliasType) + alias2 = cls.inner(None) + self.assertIsNot(alias, alias2) + self.assertEqual(len(alias.__type_params__), 1) + + self.assertEqual(alias.__value__, alias[A, B] | int) + + +class TypeParamsAliasValueTest(unittest.TestCase): + def test_alias_value_01(self): + type TA1 = int + + self.assertIsInstance(TA1, TypeAliasType) + self.assertEqual(TA1.__value__, int) + self.assertEqual(TA1.__parameters__, ()) + self.assertEqual(TA1.__type_params__, ()) + + type TA2 = TA1 | str + + self.assertIsInstance(TA2, TypeAliasType) + a, b = TA2.__value__.__args__ + self.assertEqual(a, TA1) + self.assertEqual(b, str) + self.assertEqual(TA2.__parameters__, ()) + self.assertEqual(TA2.__type_params__, ()) + + def test_alias_value_02(self): + class Parent[A]: + type TA1[B] = dict[A, B] + + self.assertIsInstance(Parent.TA1, TypeAliasType) + self.assertEqual(len(Parent.TA1.__parameters__), 1) + self.assertEqual(len(Parent.__parameters__), 1) + a, = Parent.__parameters__ + b, = Parent.TA1.__parameters__ + self.assertEqual(Parent.__type_params__, (a,)) + self.assertEqual(Parent.TA1.__type_params__, (b,)) + self.assertEqual(Parent.TA1.__value__, dict[a, b]) + + def test_alias_value_03(self): + def outer[A](): + type TA1[B] = dict[A, B] + return TA1 + + o = outer() + self.assertIsInstance(o, TypeAliasType) + self.assertEqual(len(o.__parameters__), 1) + self.assertEqual(len(outer.__type_params__), 1) + b = o.__parameters__[0] + self.assertEqual(o.__type_params__, (b,)) + + def test_alias_value_04(self): + def more_generic[T, *Ts, **P](): + type TA[T2, *Ts2, **P2] = tuple[Callable[P, tuple[T, *Ts]], Callable[P2, tuple[T2, *Ts2]]] + return TA + + alias = more_generic() + self.assertIsInstance(alias, TypeAliasType) + T2, Ts2, P2 = alias.__type_params__ + self.assertEqual(alias.__parameters__, (T2, *Ts2, P2)) + T, Ts, P = more_generic.__type_params__ + self.assertEqual(alias.__value__, tuple[Callable[P, tuple[T, *Ts]], Callable[P2, tuple[T2, *Ts2]]]) + + def test_subscripting(self): + type NonGeneric = int + type Generic[A] = dict[A, A] + type VeryGeneric[T, *Ts, **P] = Callable[P, tuple[T, *Ts]] + + with self.assertRaises(TypeError): + NonGeneric[int] + + specialized = Generic[int] + self.assertIsInstance(specialized, types.GenericAlias) + self.assertIs(specialized.__origin__, Generic) + self.assertEqual(specialized.__args__, (int,)) + + specialized2 = VeryGeneric[int, str, float, [bool, range]] + self.assertIsInstance(specialized2, types.GenericAlias) + self.assertIs(specialized2.__origin__, VeryGeneric) + self.assertEqual(specialized2.__args__, (int, str, float, [bool, range])) + + def test_repr(self): + type Simple = int + type VeryGeneric[T, *Ts, **P] = Callable[P, tuple[T, *Ts]] + + self.assertEqual(repr(Simple), "Simple") + self.assertEqual(repr(VeryGeneric), "VeryGeneric") + self.assertEqual(repr(VeryGeneric[int, bytes, str, [float, object]]), + "VeryGeneric[int, bytes, str, [float, object]]") + self.assertEqual(repr(VeryGeneric[int, []]), + "VeryGeneric[int, []]") + self.assertEqual(repr(VeryGeneric[int, [VeryGeneric[int], list[str]]]), + "VeryGeneric[int, [VeryGeneric[int], list[str]]]") + + def test_recursive_repr(self): + type Recursive = Recursive + self.assertEqual(repr(Recursive), "Recursive") + + type X = list[Y] + type Y = list[X] + self.assertEqual(repr(X), "X") + self.assertEqual(repr(Y), "Y") + + type GenericRecursive[X] = list[X | GenericRecursive[X]] + self.assertEqual(repr(GenericRecursive), "GenericRecursive") + self.assertEqual(repr(GenericRecursive[int]), "GenericRecursive[int]") + self.assertEqual(repr(GenericRecursive[GenericRecursive[int]]), + "GenericRecursive[GenericRecursive[int]]") + + def test_raising(self): + type MissingName = list[_My_X] + with self.assertRaisesRegex( + NameError, + "cannot access free variable '_My_X' where it is not associated with a value", + ): + MissingName.__value__ + _My_X = int + self.assertEqual(MissingName.__value__, list[int]) + del _My_X + # Cache should still work: + self.assertEqual(MissingName.__value__, list[int]) + + # Explicit exception: + type ExprException = 1 / 0 + with self.assertRaises(ZeroDivisionError): + ExprException.__value__ + + +class TypeAliasConstructorTest(unittest.TestCase): + def test_basic(self): + TA = TypeAliasType("TA", int) + self.assertEqual(TA.__name__, "TA") + self.assertIs(TA.__value__, int) + self.assertEqual(TA.__type_params__, ()) + self.assertEqual(TA.__module__, __name__) + + def test_attributes_with_exec(self): + ns = {} + exec("type TA = int", ns, ns) + TA = ns["TA"] + self.assertEqual(TA.__name__, "TA") + self.assertIs(TA.__value__, int) + self.assertEqual(TA.__type_params__, ()) + self.assertIs(TA.__module__, None) + + def test_generic(self): + T = TypeVar("T") + TA = TypeAliasType("TA", list[T], type_params=(T,)) + self.assertEqual(TA.__name__, "TA") + self.assertEqual(TA.__value__, list[T]) + self.assertEqual(TA.__type_params__, (T,)) + self.assertEqual(TA.__module__, __name__) + + def test_keywords(self): + TA = TypeAliasType(name="TA", value=int) + self.assertEqual(TA.__name__, "TA") + self.assertIs(TA.__value__, int) + self.assertEqual(TA.__type_params__, ()) + self.assertEqual(TA.__module__, __name__) + + def test_errors(self): + with self.assertRaises(TypeError): + TypeAliasType() + with self.assertRaises(TypeError): + TypeAliasType("TA") + with self.assertRaises(TypeError): + TypeAliasType("TA", list, ()) + with self.assertRaises(TypeError): + TypeAliasType("TA", list, type_params=42) + + +class TypeAliasTypeTest(unittest.TestCase): + def test_immutable(self): + with self.assertRaises(TypeError): + TypeAliasType.whatever = "not allowed" + + def test_no_subclassing(self): + with self.assertRaisesRegex(TypeError, "not an acceptable base type"): + class MyAlias(TypeAliasType): + pass + + def test_union(self): + type Alias1 = int + type Alias2 = str + union = Alias1 | Alias2 + self.assertIsInstance(union, types.UnionType) + self.assertEqual(get_args(union), (Alias1, Alias2)) + union2 = Alias1 | list[float] + self.assertIsInstance(union2, types.UnionType) + self.assertEqual(get_args(union2), (Alias1, list[float])) + union3 = list[range] | Alias1 + self.assertIsInstance(union3, types.UnionType) + self.assertEqual(get_args(union3), (list[range], Alias1)) + + def test_module(self): + self.assertEqual(TypeAliasType.__module__, "typing") + type Alias = int + self.assertEqual(Alias.__module__, __name__) + self.assertEqual(mod_generics_cache.Alias.__module__, + mod_generics_cache.__name__) + self.assertEqual(mod_generics_cache.OldStyle.__module__, + mod_generics_cache.__name__) + + +# All these type aliases are used for pickling tests: +T = TypeVar('T') +type SimpleAlias = int +type RecursiveAlias = dict[str, RecursiveAlias] +type GenericAlias[X] = list[X] +type GenericAliasMultipleTypes[X, Y] = dict[X, Y] +type RecursiveGenericAlias[X] = dict[str, RecursiveAlias[X]] +type BoundGenericAlias[X: int] = set[X] +type ConstrainedGenericAlias[LongName: (str, bytes)] = list[LongName] +type AllTypesAlias[A, *B, **C] = Callable[C, A] | tuple[*B] + + +class TypeAliasPickleTest(unittest.TestCase): + def test_pickling(self): + things_to_test = [ + SimpleAlias, + RecursiveAlias, + + GenericAlias, + GenericAlias[T], + GenericAlias[int], + + GenericAliasMultipleTypes, + GenericAliasMultipleTypes[str, T], + GenericAliasMultipleTypes[T, str], + GenericAliasMultipleTypes[int, str], + + RecursiveGenericAlias, + RecursiveGenericAlias[T], + RecursiveGenericAlias[int], + + BoundGenericAlias, + BoundGenericAlias[int], + BoundGenericAlias[T], + + ConstrainedGenericAlias, + ConstrainedGenericAlias[str], + ConstrainedGenericAlias[T], + + AllTypesAlias, + AllTypesAlias[int, str, T, [T, object]], + + # Other modules: + mod_generics_cache.Alias, + mod_generics_cache.OldStyle, + ] + for thing in things_to_test: + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.subTest(thing=thing, proto=proto): + pickled = pickle.dumps(thing, protocol=proto) + self.assertEqual(pickle.loads(pickled), thing) + + type ClassLevel = str + + def test_pickling_local(self): + type A = int + things_to_test = [ + self.ClassLevel, + A, + ] + for thing in things_to_test: + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.subTest(thing=thing, proto=proto): + with self.assertRaises(pickle.PickleError): + pickle.dumps(thing, protocol=proto) diff --git a/Lib/test/test_type_annotations.py b/Lib/test/test_type_annotations.py index 87f46c2c..3dbb35af 100644 --- a/Lib/test/test_type_annotations.py +++ b/Lib/test/test_type_annotations.py @@ -1,4 +1,6 @@ +import textwrap import unittest +from test.support import run_code class TypeAnnotationTests(unittest.TestCase): @@ -101,3 +103,112 @@ class TypeAnnotationTests(unittest.TestCase): with self.assertRaises(AttributeError): del D.__annotations__ self.assertEqual(D.__annotations__, {}) + + +class TestSetupAnnotations(unittest.TestCase): + def check(self, code: str): + code = textwrap.dedent(code) + for scope in ("module", "class"): + with self.subTest(scope=scope): + if scope == "class": + code = f"class C:\n{textwrap.indent(code, ' ')}" + ns = run_code(code) + if scope == "class": + annotations = ns["C"].__annotations__ + else: + annotations = ns["__annotations__"] + self.assertEqual(annotations, {"x": int}) + + def test_top_level(self): + self.check("x: int = 1") + + def test_blocks(self): + self.check("if True:\n x: int = 1") + self.check(""" + while True: + x: int = 1 + break + """) + self.check(""" + while False: + pass + else: + x: int = 1 + """) + self.check(""" + for i in range(1): + x: int = 1 + """) + self.check(""" + for i in range(1): + pass + else: + x: int = 1 + """) + + def test_try(self): + self.check(""" + try: + x: int = 1 + except: + pass + """) + self.check(""" + try: + pass + except: + pass + else: + x: int = 1 + """) + self.check(""" + try: + pass + except: + pass + finally: + x: int = 1 + """) + self.check(""" + try: + 1/0 + except: + x: int = 1 + """) + + def test_try_star(self): + self.check(""" + try: + x: int = 1 + except* Exception: + pass + """) + self.check(""" + try: + pass + except* Exception: + pass + else: + x: int = 1 + """) + self.check(""" + try: + pass + except* Exception: + pass + finally: + x: int = 1 + """) + self.check(""" + try: + 1/0 + except* Exception: + x: int = 1 + """) + + def test_match(self): + self.check(""" + match 0: + case 0: + x: int = 1 + """) diff --git a/Lib/test/test_type_cache.py b/Lib/test/test_type_cache.py index 8502f6b0..72587ecc 100644 --- a/Lib/test/test_type_cache.py +++ b/Lib/test/test_type_cache.py @@ -9,6 +9,7 @@ except ImportError: # Skip this test if the _testcapi module isn't available. type_get_version = import_helper.import_module('_testcapi').type_get_version +type_assign_version = import_helper.import_module('_testcapi').type_assign_version @support.cpython_only @@ -42,6 +43,19 @@ class TypeCacheTests(unittest.TestCase): self.assertEqual(len(set(all_version_tags)), 30, msg=f"{all_version_tags} contains non-unique versions") + def test_type_assign_version(self): + class C: + x = 5 + + self.assertEqual(type_assign_version(C), 1) + c_ver = type_get_version(C) + + C.x = 6 + self.assertEqual(type_get_version(C), 0) + self.assertEqual(type_assign_version(C), 1) + self.assertNotEqual(type_get_version(C), 0) + self.assertNotEqual(type_get_version(C), c_ver) + if __name__ == "__main__": - support.run_unittest(TypeCacheTests) + unittest.main() diff --git a/Lib/test/test_type_comments.py b/Lib/test/test_type_comments.py index 7a348be6..aba4a44b 100644 --- a/Lib/test/test_type_comments.py +++ b/Lib/test/test_type_comments.py @@ -1,7 +1,6 @@ import ast import sys import unittest -from test import support funcdef = """\ @@ -273,7 +272,7 @@ class TypeCommentTests(unittest.TestCase): pass def test_fstring(self): - for tree in self.parse_all(fstring, minver=6): + for tree in self.parse_all(fstring): pass def test_underscorednumber(self): diff --git a/Lib/test/test_type_params.py b/Lib/test/test_type_params.py new file mode 100644 index 00000000..25ee1887 --- /dev/null +++ b/Lib/test/test_type_params.py @@ -0,0 +1,1104 @@ +import asyncio +import textwrap +import types +import unittest +import pickle +import weakref +from test.support import requires_working_socket, check_syntax_error, run_code + +from typing import Generic, Sequence, TypeVar, TypeVarTuple, ParamSpec, get_args + + +class TypeParamsInvalidTest(unittest.TestCase): + def test_name_collisions(self): + check_syntax_error(self, 'def func[**A, A](): ...', "duplicate type parameter 'A'") + check_syntax_error(self, 'def func[A, *A](): ...', "duplicate type parameter 'A'") + check_syntax_error(self, 'def func[*A, **A](): ...', "duplicate type parameter 'A'") + + check_syntax_error(self, 'class C[**A, A](): ...', "duplicate type parameter 'A'") + check_syntax_error(self, 'class C[A, *A](): ...', "duplicate type parameter 'A'") + check_syntax_error(self, 'class C[*A, **A](): ...', "duplicate type parameter 'A'") + + def test_name_non_collision_02(self): + ns = run_code("""def func[A](A): return A""") + func = ns["func"] + self.assertEqual(func(1), 1) + A, = func.__type_params__ + self.assertEqual(A.__name__, "A") + + def test_name_non_collision_03(self): + ns = run_code("""def func[A](*A): return A""") + func = ns["func"] + self.assertEqual(func(1), (1,)) + A, = func.__type_params__ + self.assertEqual(A.__name__, "A") + + def test_name_non_collision_04(self): + # Mangled names should not cause a conflict. + ns = run_code(""" + class ClassA: + def func[__A](self, __A): return __A + """ + ) + cls = ns["ClassA"] + self.assertEqual(cls().func(1), 1) + A, = cls.func.__type_params__ + self.assertEqual(A.__name__, "__A") + + def test_name_non_collision_05(self): + ns = run_code(""" + class ClassA: + def func[_ClassA__A](self, __A): return __A + """ + ) + cls = ns["ClassA"] + self.assertEqual(cls().func(1), 1) + A, = cls.func.__type_params__ + self.assertEqual(A.__name__, "_ClassA__A") + + def test_name_non_collision_06(self): + ns = run_code(""" + class ClassA[X]: + def func(self, X): return X + """ + ) + cls = ns["ClassA"] + self.assertEqual(cls().func(1), 1) + X, = cls.__type_params__ + self.assertEqual(X.__name__, "X") + + def test_name_non_collision_07(self): + ns = run_code(""" + class ClassA[X]: + def func(self): + X = 1 + return X + """ + ) + cls = ns["ClassA"] + self.assertEqual(cls().func(), 1) + X, = cls.__type_params__ + self.assertEqual(X.__name__, "X") + + def test_name_non_collision_08(self): + ns = run_code(""" + class ClassA[X]: + def func(self): + return [X for X in [1, 2]] + """ + ) + cls = ns["ClassA"] + self.assertEqual(cls().func(), [1, 2]) + X, = cls.__type_params__ + self.assertEqual(X.__name__, "X") + + def test_name_non_collision_9(self): + ns = run_code(""" + class ClassA[X]: + def func[X](self): + ... + """ + ) + cls = ns["ClassA"] + outer_X, = cls.__type_params__ + inner_X, = cls.func.__type_params__ + self.assertEqual(outer_X.__name__, "X") + self.assertEqual(inner_X.__name__, "X") + self.assertIsNot(outer_X, inner_X) + + def test_name_non_collision_10(self): + ns = run_code(""" + class ClassA[X]: + X: int + """ + ) + cls = ns["ClassA"] + X, = cls.__type_params__ + self.assertEqual(X.__name__, "X") + self.assertIs(cls.__annotations__["X"], int) + + def test_name_non_collision_13(self): + ns = run_code(""" + X = 1 + def outer(): + def inner[X](): + global X + X = 2 + return inner + """ + ) + self.assertEqual(ns["X"], 1) + outer = ns["outer"] + outer()() + self.assertEqual(ns["X"], 2) + + def test_disallowed_expressions(self): + check_syntax_error(self, "type X = (yield)") + check_syntax_error(self, "type X = (yield from x)") + check_syntax_error(self, "type X = (await 42)") + check_syntax_error(self, "async def f(): type X = (yield)") + check_syntax_error(self, "type X = (y := 3)") + check_syntax_error(self, "class X[T: (yield)]: pass") + check_syntax_error(self, "class X[T: (yield from x)]: pass") + check_syntax_error(self, "class X[T: (await 42)]: pass") + check_syntax_error(self, "class X[T: (y := 3)]: pass") + check_syntax_error(self, "class X[T](y := Sequence[T]): pass") + check_syntax_error(self, "def f[T](y: (x := Sequence[T])): pass") + check_syntax_error(self, "class X[T]([(x := 3) for _ in range(2)] and B): pass") + check_syntax_error(self, "def f[T: [(x := 3) for _ in range(2)]](): pass") + check_syntax_error(self, "type T = [(x := 3) for _ in range(2)]") + + def test_incorrect_mro_explicit_object(self): + with self.assertRaisesRegex(TypeError, r"\(MRO\) for bases object, Generic"): + class My[X](object): ... + + +class TypeParamsNonlocalTest(unittest.TestCase): + def test_nonlocal_disallowed_01(self): + code = """ + def outer(): + X = 1 + def inner[X](): + nonlocal X + return X + """ + check_syntax_error(self, code) + + def test_nonlocal_disallowed_02(self): + code = """ + def outer2[T](): + def inner1(): + nonlocal T + """ + check_syntax_error(self, textwrap.dedent(code)) + + def test_nonlocal_disallowed_03(self): + code = """ + class Cls[T]: + nonlocal T + """ + check_syntax_error(self, textwrap.dedent(code)) + + def test_nonlocal_allowed(self): + code = """ + def func[T](): + T = "func" + def inner(): + nonlocal T + T = "inner" + inner() + assert T == "inner" + """ + ns = run_code(code) + func = ns["func"] + T, = func.__type_params__ + self.assertEqual(T.__name__, "T") + + +class TypeParamsAccessTest(unittest.TestCase): + def test_class_access_01(self): + ns = run_code(""" + class ClassA[A, B](dict[A, B]): + ... + """ + ) + cls = ns["ClassA"] + A, B = cls.__type_params__ + self.assertEqual(types.get_original_bases(cls), (dict[A, B], Generic[A, B])) + + def test_class_access_02(self): + ns = run_code(""" + class MyMeta[A, B](type): ... + class ClassA[A, B](metaclass=MyMeta[A, B]): + ... + """ + ) + meta = ns["MyMeta"] + cls = ns["ClassA"] + A1, B1 = meta.__type_params__ + A2, B2 = cls.__type_params__ + self.assertIsNot(A1, A2) + self.assertIsNot(B1, B2) + self.assertIs(type(cls), meta) + + def test_class_access_03(self): + code = """ + def my_decorator(a): + ... + @my_decorator(A) + class ClassA[A, B](): + ... + """ + + with self.assertRaisesRegex(NameError, "name 'A' is not defined"): + run_code(code) + + def test_function_access_01(self): + ns = run_code(""" + def func[A, B](a: dict[A, B]): + ... + """ + ) + func = ns["func"] + A, B = func.__type_params__ + self.assertEqual(func.__annotations__["a"], dict[A, B]) + + def test_function_access_02(self): + code = """ + def func[A](a = list[A]()): + ... + """ + + with self.assertRaisesRegex(NameError, "name 'A' is not defined"): + run_code(code) + + def test_function_access_03(self): + code = """ + def my_decorator(a): + ... + @my_decorator(A) + def func[A](): + ... + """ + + with self.assertRaisesRegex(NameError, "name 'A' is not defined"): + run_code(code) + + def test_method_access_01(self): + ns = run_code(""" + class ClassA: + x = int + def func[T](self, a: x, b: T): + ... + """ + ) + cls = ns["ClassA"] + self.assertIs(cls.func.__annotations__["a"], int) + T, = cls.func.__type_params__ + self.assertIs(cls.func.__annotations__["b"], T) + + def test_nested_access_01(self): + ns = run_code(""" + class ClassA[A]: + def funcB[B](self): + class ClassC[C]: + def funcD[D](self): + return lambda: (A, B, C, D) + return ClassC + """ + ) + cls = ns["ClassA"] + A, = cls.__type_params__ + B, = cls.funcB.__type_params__ + classC = cls().funcB() + C, = classC.__type_params__ + D, = classC.funcD.__type_params__ + self.assertEqual(classC().funcD()(), (A, B, C, D)) + + def test_out_of_scope_01(self): + code = """ + class ClassA[T]: ... + x = T + """ + + with self.assertRaisesRegex(NameError, "name 'T' is not defined"): + run_code(code) + + def test_out_of_scope_02(self): + code = """ + class ClassA[A]: + def funcB[B](self): ... + + x = B + """ + + with self.assertRaisesRegex(NameError, "name 'B' is not defined"): + run_code(code) + + def test_class_scope_interaction_01(self): + ns = run_code(""" + class C: + x = 1 + def method[T](self, arg: x): pass + """) + cls = ns["C"] + self.assertEqual(cls.method.__annotations__["arg"], 1) + + def test_class_scope_interaction_02(self): + ns = run_code(""" + class C: + class Base: pass + class Child[T](Base): pass + """) + cls = ns["C"] + self.assertEqual(cls.Child.__bases__, (cls.Base, Generic)) + T, = cls.Child.__type_params__ + self.assertEqual(types.get_original_bases(cls.Child), (cls.Base, Generic[T])) + + def test_class_deref(self): + ns = run_code(""" + class C[T]: + T = "class" + type Alias = T + """) + cls = ns["C"] + self.assertEqual(cls.Alias.__value__, "class") + + def test_shadowing_nonlocal(self): + ns = run_code(""" + def outer[T](): + T = "outer" + def inner(): + nonlocal T + T = "inner" + return T + return lambda: T, inner + """) + outer = ns["outer"] + T, = outer.__type_params__ + self.assertEqual(T.__name__, "T") + getter, inner = outer() + self.assertEqual(getter(), "outer") + self.assertEqual(inner(), "inner") + self.assertEqual(getter(), "inner") + + def test_reference_previous_typevar(self): + def func[S, T: Sequence[S]](): + pass + + S, T = func.__type_params__ + self.assertEqual(T.__bound__, Sequence[S]) + + def test_super(self): + class Base: + def meth(self): + return "base" + + class Child(Base): + # Having int in the annotation ensures the class gets cells for both + # __class__ and __classdict__ + def meth[T](self, arg: int) -> T: + return super().meth() + "child" + + c = Child() + self.assertEqual(c.meth(1), "basechild") + + def test_type_alias_containing_lambda(self): + type Alias[T] = lambda: T + T, = Alias.__type_params__ + self.assertIs(Alias.__value__(), T) + + def test_class_base_containing_lambda(self): + # Test that scopes nested inside hidden functions work correctly + outer_var = "outer" + class Base[T]: ... + class Child[T](Base[lambda: (int, outer_var, T)]): ... + base, _ = types.get_original_bases(Child) + func, = get_args(base) + T, = Child.__type_params__ + self.assertEqual(func(), (int, "outer", T)) + + def test_comprehension_01(self): + type Alias[T: ([T for T in (T, [1])[1]], T)] = [T for T in T.__name__] + self.assertEqual(Alias.__value__, ["T"]) + T, = Alias.__type_params__ + self.assertEqual(T.__constraints__, ([1], T)) + + def test_comprehension_02(self): + type Alias[T: [lambda: T for T in (T, [1])[1]]] = [lambda: T for T in T.__name__] + func, = Alias.__value__ + self.assertEqual(func(), "T") + T, = Alias.__type_params__ + func, = T.__bound__ + self.assertEqual(func(), 1) + + def test_gen_exp_in_nested_class(self): + code = """ + from test.test_type_params import make_base + + class C[T]: + T = "class" + class Inner(make_base(T for _ in (1,)), make_base(T)): + pass + """ + C = run_code(code)["C"] + T, = C.__type_params__ + base1, base2 = C.Inner.__bases__ + self.assertEqual(list(base1.__arg__), [T]) + self.assertEqual(base2.__arg__, "class") + + def test_gen_exp_in_nested_generic_class(self): + code = """ + from test.test_type_params import make_base + + class C[T]: + T = "class" + class Inner[U](make_base(T for _ in (1,)), make_base(T)): + pass + """ + with self.assertRaisesRegex(SyntaxError, + "Cannot use comprehension in annotation scope within class scope"): + run_code(code) + + def test_listcomp_in_nested_class(self): + code = """ + from test.test_type_params import make_base + + class C[T]: + T = "class" + class Inner(make_base([T for _ in (1,)]), make_base(T)): + pass + """ + C = run_code(code)["C"] + T, = C.__type_params__ + base1, base2 = C.Inner.__bases__ + self.assertEqual(base1.__arg__, [T]) + self.assertEqual(base2.__arg__, "class") + + def test_listcomp_in_nested_generic_class(self): + code = """ + from test.test_type_params import make_base + + class C[T]: + T = "class" + class Inner[U](make_base([T for _ in (1,)]), make_base(T)): + pass + """ + with self.assertRaisesRegex(SyntaxError, + "Cannot use comprehension in annotation scope within class scope"): + run_code(code) + + def test_gen_exp_in_generic_method(self): + code = """ + class C[T]: + T = "class" + def meth[U](x: (T for _ in (1,)), y: T): + pass + """ + with self.assertRaisesRegex(SyntaxError, + "Cannot use comprehension in annotation scope within class scope"): + run_code(code) + + def test_nested_scope_in_generic_alias(self): + code = """ + class C[T]: + T = "class" + {} + """ + error_cases = [ + "type Alias1[T] = lambda: T", + "type Alias2 = lambda: T", + "type Alias3[T] = (T for _ in (1,))", + "type Alias4 = (T for _ in (1,))", + "type Alias5[T] = [T for _ in (1,)]", + "type Alias6 = [T for _ in (1,)]", + ] + for case in error_cases: + with self.subTest(case=case): + with self.assertRaisesRegex(SyntaxError, + r"Cannot use [a-z]+ in annotation scope within class scope"): + run_code(code.format(case)) + + +def make_base(arg): + class Base: + __arg__ = arg + return Base + + +def global_generic_func[T](): + pass + +class GlobalGenericClass[T]: + pass + + +class TypeParamsLazyEvaluationTest(unittest.TestCase): + def test_qualname(self): + class Foo[T]: + pass + + def func[T](): + pass + + self.assertEqual(Foo.__qualname__, "TypeParamsLazyEvaluationTest.test_qualname.<locals>.Foo") + self.assertEqual(func.__qualname__, "TypeParamsLazyEvaluationTest.test_qualname.<locals>.func") + self.assertEqual(global_generic_func.__qualname__, "global_generic_func") + self.assertEqual(GlobalGenericClass.__qualname__, "GlobalGenericClass") + + def test_recursive_class(self): + class Foo[T: Foo, U: (Foo, Foo)]: + pass + + type_params = Foo.__type_params__ + self.assertEqual(len(type_params), 2) + self.assertEqual(type_params[0].__name__, "T") + self.assertIs(type_params[0].__bound__, Foo) + self.assertEqual(type_params[0].__constraints__, ()) + + self.assertEqual(type_params[1].__name__, "U") + self.assertIs(type_params[1].__bound__, None) + self.assertEqual(type_params[1].__constraints__, (Foo, Foo)) + + def test_evaluation_error(self): + class Foo[T: Undefined, U: (Undefined,)]: + pass + + type_params = Foo.__type_params__ + with self.assertRaises(NameError): + type_params[0].__bound__ + self.assertEqual(type_params[0].__constraints__, ()) + self.assertIs(type_params[1].__bound__, None) + with self.assertRaises(NameError): + type_params[1].__constraints__ + + Undefined = "defined" + self.assertEqual(type_params[0].__bound__, "defined") + self.assertEqual(type_params[0].__constraints__, ()) + + self.assertIs(type_params[1].__bound__, None) + self.assertEqual(type_params[1].__constraints__, ("defined",)) + + +class TypeParamsClassScopeTest(unittest.TestCase): + def test_alias(self): + class X: + T = int + type U = T + self.assertIs(X.U.__value__, int) + + ns = run_code(""" + glb = "global" + class X: + cls = "class" + type U = (glb, cls) + """) + cls = ns["X"] + self.assertEqual(cls.U.__value__, ("global", "class")) + + def test_bound(self): + class X: + T = int + def foo[U: T](self): ... + self.assertIs(X.foo.__type_params__[0].__bound__, int) + + ns = run_code(""" + glb = "global" + class X: + cls = "class" + def foo[T: glb, U: cls](self): ... + """) + cls = ns["X"] + T, U = cls.foo.__type_params__ + self.assertEqual(T.__bound__, "global") + self.assertEqual(U.__bound__, "class") + + def test_modified_later(self): + class X: + T = int + def foo[U: T](self): ... + type Alias = T + X.T = float + self.assertIs(X.foo.__type_params__[0].__bound__, float) + self.assertIs(X.Alias.__value__, float) + + def test_binding_uses_global(self): + ns = run_code(""" + x = "global" + def outer(): + x = "nonlocal" + class Cls: + type Alias = x + val = Alias.__value__ + def meth[T: x](self, arg: x): ... + bound = meth.__type_params__[0].__bound__ + annotation = meth.__annotations__["arg"] + x = "class" + return Cls + """) + cls = ns["outer"]() + self.assertEqual(cls.val, "global") + self.assertEqual(cls.bound, "global") + self.assertEqual(cls.annotation, "global") + + def test_no_binding_uses_nonlocal(self): + ns = run_code(""" + x = "global" + def outer(): + x = "nonlocal" + class Cls: + type Alias = x + val = Alias.__value__ + def meth[T: x](self, arg: x): ... + bound = meth.__type_params__[0].__bound__ + return Cls + """) + cls = ns["outer"]() + self.assertEqual(cls.val, "nonlocal") + self.assertEqual(cls.bound, "nonlocal") + self.assertEqual(cls.meth.__annotations__["arg"], "nonlocal") + + def test_explicit_global(self): + ns = run_code(""" + x = "global" + def outer(): + x = "nonlocal" + class Cls: + global x + type Alias = x + Cls.x = "class" + return Cls + """) + cls = ns["outer"]() + self.assertEqual(cls.Alias.__value__, "global") + + def test_explicit_global_with_no_static_bound(self): + ns = run_code(""" + def outer(): + class Cls: + global x + type Alias = x + Cls.x = "class" + return Cls + """) + ns["x"] = "global" + cls = ns["outer"]() + self.assertEqual(cls.Alias.__value__, "global") + + def test_explicit_global_with_assignment(self): + ns = run_code(""" + x = "global" + def outer(): + x = "nonlocal" + class Cls: + global x + type Alias = x + x = "global from class" + Cls.x = "class" + return Cls + """) + cls = ns["outer"]() + self.assertEqual(cls.Alias.__value__, "global from class") + + def test_explicit_nonlocal(self): + ns = run_code(""" + x = "global" + def outer(): + x = "nonlocal" + class Cls: + nonlocal x + type Alias = x + x = "class" + return Cls + """) + cls = ns["outer"]() + self.assertEqual(cls.Alias.__value__, "class") + + def test_nested_free(self): + ns = run_code(""" + def f(): + T = str + class C: + T = int + class D[U](T): + x = T + return C + """) + C = ns["f"]() + self.assertIn(int, C.D.__bases__) + self.assertIs(C.D.x, str) + +class TypeParamsManglingTest(unittest.TestCase): + def test_mangling(self): + class Foo[__T]: + param = __T + def meth[__U](self, arg: __T, arg2: __U): + return (__T, __U) + type Alias[__V] = (__T, __V) + + T = Foo.__type_params__[0] + self.assertEqual(T.__name__, "__T") + U = Foo.meth.__type_params__[0] + self.assertEqual(U.__name__, "__U") + V = Foo.Alias.__type_params__[0] + self.assertEqual(V.__name__, "__V") + + anno = Foo.meth.__annotations__ + self.assertIs(anno["arg"], T) + self.assertIs(anno["arg2"], U) + self.assertEqual(Foo().meth(1, 2), (T, U)) + + self.assertEqual(Foo.Alias.__value__, (T, V)) + + +class TypeParamsComplexCallsTest(unittest.TestCase): + def test_defaults(self): + # Generic functions with both defaults and kwdefaults trigger a specific code path + # in the compiler. + def func[T](a: T = "a", *, b: T = "b"): + return (a, b) + + T, = func.__type_params__ + self.assertIs(func.__annotations__["a"], T) + self.assertIs(func.__annotations__["b"], T) + self.assertEqual(func(), ("a", "b")) + self.assertEqual(func(1), (1, "b")) + self.assertEqual(func(b=2), ("a", 2)) + + def test_complex_base(self): + class Base: + def __init_subclass__(cls, **kwargs) -> None: + cls.kwargs = kwargs + + kwargs = {"c": 3} + # Base classes with **kwargs trigger a different code path in the compiler. + class C[T](Base, a=1, b=2, **kwargs): + pass + + T, = C.__type_params__ + self.assertEqual(T.__name__, "T") + self.assertEqual(C.kwargs, {"a": 1, "b": 2, "c": 3}) + + bases = (Base,) + class C2[T](*bases, **kwargs): + pass + + T, = C2.__type_params__ + self.assertEqual(T.__name__, "T") + self.assertEqual(C2.kwargs, {"c": 3}) + + +class TypeParamsTraditionalTypeVarsTest(unittest.TestCase): + def test_traditional_01(self): + code = """ + from typing import Generic + class ClassA[T](Generic[T]): ... + """ + + with self.assertRaisesRegex(TypeError, r"Cannot inherit from Generic\[...\] multiple times."): + run_code(code) + + def test_traditional_02(self): + from typing import TypeVar + S = TypeVar("S") + with self.assertRaises(TypeError): + class ClassA[T](dict[T, S]): ... + + def test_traditional_03(self): + # This does not generate a runtime error, but it should be + # flagged as an error by type checkers. + from typing import TypeVar + S = TypeVar("S") + def func[T](a: T, b: S) -> T | S: + return a + + +class TypeParamsTypeVarTest(unittest.TestCase): + def test_typevar_01(self): + def func1[A: str, B: str | int, C: (int, str)](): + return (A, B, C) + + a, b, c = func1() + + self.assertIsInstance(a, TypeVar) + self.assertEqual(a.__bound__, str) + self.assertTrue(a.__infer_variance__) + self.assertFalse(a.__covariant__) + self.assertFalse(a.__contravariant__) + + self.assertIsInstance(b, TypeVar) + self.assertEqual(b.__bound__, str | int) + self.assertTrue(b.__infer_variance__) + self.assertFalse(b.__covariant__) + self.assertFalse(b.__contravariant__) + + self.assertIsInstance(c, TypeVar) + self.assertEqual(c.__bound__, None) + self.assertEqual(c.__constraints__, (int, str)) + self.assertTrue(c.__infer_variance__) + self.assertFalse(c.__covariant__) + self.assertFalse(c.__contravariant__) + + def test_typevar_generator(self): + def get_generator[A](): + def generator1[C](): + yield C + + def generator2[B](): + yield A + yield B + yield from generator1() + return generator2 + + gen = get_generator() + + a, b, c = [x for x in gen()] + + self.assertIsInstance(a, TypeVar) + self.assertEqual(a.__name__, "A") + self.assertIsInstance(b, TypeVar) + self.assertEqual(b.__name__, "B") + self.assertIsInstance(c, TypeVar) + self.assertEqual(c.__name__, "C") + + @requires_working_socket() + def test_typevar_coroutine(self): + def get_coroutine[A](): + async def coroutine[B](): + return (A, B) + return coroutine + + co = get_coroutine() + + self.addCleanup(asyncio.set_event_loop_policy, None) + a, b = asyncio.run(co()) + + self.assertIsInstance(a, TypeVar) + self.assertEqual(a.__name__, "A") + self.assertIsInstance(b, TypeVar) + self.assertEqual(b.__name__, "B") + + +class TypeParamsTypeVarTupleTest(unittest.TestCase): + def test_typevartuple_01(self): + code = """def func1[*A: str](): pass""" + check_syntax_error(self, code, "cannot use bound with TypeVarTuple") + code = """def func1[*A: (int, str)](): pass""" + check_syntax_error(self, code, "cannot use constraints with TypeVarTuple") + code = """class X[*A: str]: pass""" + check_syntax_error(self, code, "cannot use bound with TypeVarTuple") + code = """class X[*A: (int, str)]: pass""" + check_syntax_error(self, code, "cannot use constraints with TypeVarTuple") + code = """type X[*A: str] = int""" + check_syntax_error(self, code, "cannot use bound with TypeVarTuple") + code = """type X[*A: (int, str)] = int""" + check_syntax_error(self, code, "cannot use constraints with TypeVarTuple") + + def test_typevartuple_02(self): + def func1[*A](): + return A + + a = func1() + self.assertIsInstance(a, TypeVarTuple) + + +class TypeParamsTypeVarParamSpecTest(unittest.TestCase): + def test_paramspec_01(self): + code = """def func1[**A: str](): pass""" + check_syntax_error(self, code, "cannot use bound with ParamSpec") + code = """def func1[**A: (int, str)](): pass""" + check_syntax_error(self, code, "cannot use constraints with ParamSpec") + code = """class X[**A: str]: pass""" + check_syntax_error(self, code, "cannot use bound with ParamSpec") + code = """class X[**A: (int, str)]: pass""" + check_syntax_error(self, code, "cannot use constraints with ParamSpec") + code = """type X[**A: str] = int""" + check_syntax_error(self, code, "cannot use bound with ParamSpec") + code = """type X[**A: (int, str)] = int""" + check_syntax_error(self, code, "cannot use constraints with ParamSpec") + + def test_paramspec_02(self): + def func1[**A](): + return A + + a = func1() + self.assertIsInstance(a, ParamSpec) + self.assertTrue(a.__infer_variance__) + self.assertFalse(a.__covariant__) + self.assertFalse(a.__contravariant__) + + +class TypeParamsTypeParamsDunder(unittest.TestCase): + def test_typeparams_dunder_class_01(self): + class Outer[A, B]: + class Inner[C, D]: + @staticmethod + def get_typeparams(): + return A, B, C, D + + a, b, c, d = Outer.Inner.get_typeparams() + self.assertEqual(Outer.__type_params__, (a, b)) + self.assertEqual(Outer.Inner.__type_params__, (c, d)) + + self.assertEqual(Outer.__parameters__, (a, b)) + self.assertEqual(Outer.Inner.__parameters__, (c, d)) + + def test_typeparams_dunder_class_02(self): + class ClassA: + pass + + self.assertEqual(ClassA.__type_params__, ()) + + def test_typeparams_dunder_class_03(self): + code = """ + class ClassA[A](): + pass + ClassA.__type_params__ = () + params = ClassA.__type_params__ + """ + + ns = run_code(code) + self.assertEqual(ns["params"], ()) + + def test_typeparams_dunder_function_01(self): + def outer[A, B](): + def inner[C, D](): + return A, B, C, D + + return inner + + inner = outer() + a, b, c, d = inner() + self.assertEqual(outer.__type_params__, (a, b)) + self.assertEqual(inner.__type_params__, (c, d)) + + def test_typeparams_dunder_function_02(self): + def func1(): + pass + + self.assertEqual(func1.__type_params__, ()) + + def test_typeparams_dunder_function_03(self): + code = """ + def func[A](): + pass + func.__type_params__ = () + """ + + ns = run_code(code) + self.assertEqual(ns["func"].__type_params__, ()) + + + +# All these type aliases are used for pickling tests: +T = TypeVar('T') +def func1[X](x: X) -> X: ... +def func2[X, Y](x: X | Y) -> X | Y: ... +def func3[X, *Y, **Z](x: X, y: tuple[*Y], z: Z) -> X: ... +def func4[X: int, Y: (bytes, str)](x: X, y: Y) -> X | Y: ... + +class Class1[X]: ... +class Class2[X, Y]: ... +class Class3[X, *Y, **Z]: ... +class Class4[X: int, Y: (bytes, str)]: ... + + +class TypeParamsPickleTest(unittest.TestCase): + def test_pickling_functions(self): + things_to_test = [ + func1, + func2, + func3, + func4, + ] + for thing in things_to_test: + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.subTest(thing=thing, proto=proto): + pickled = pickle.dumps(thing, protocol=proto) + self.assertEqual(pickle.loads(pickled), thing) + + def test_pickling_classes(self): + things_to_test = [ + Class1, + Class1[int], + Class1[T], + + Class2, + Class2[int, T], + Class2[T, int], + Class2[int, str], + + Class3, + Class3[int, T, str, bytes, [float, object, T]], + + Class4, + Class4[int, bytes], + Class4[T, bytes], + Class4[int, T], + Class4[T, T], + ] + for thing in things_to_test: + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.subTest(thing=thing, proto=proto): + pickled = pickle.dumps(thing, protocol=proto) + self.assertEqual(pickle.loads(pickled), thing) + + for klass in things_to_test: + real_class = getattr(klass, '__origin__', klass) + thing = klass() + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.subTest(thing=thing, proto=proto): + pickled = pickle.dumps(thing, protocol=proto) + # These instances are not equal, + # but class check is good enough: + self.assertIsInstance(pickle.loads(pickled), real_class) + + +class TypeParamsWeakRefTest(unittest.TestCase): + def test_weakrefs(self): + T = TypeVar('T') + P = ParamSpec('P') + class OldStyle(Generic[T]): + pass + + class NewStyle[T]: + pass + + cases = [ + T, + TypeVar('T', bound=int), + P, + P.args, + P.kwargs, + TypeVarTuple('Ts'), + OldStyle, + OldStyle[int], + OldStyle(), + NewStyle, + NewStyle[int], + NewStyle(), + Generic[T], + ] + for case in cases: + with self.subTest(case=case): + weakref.ref(case) + + +class TypeParamsRuntimeTest(unittest.TestCase): + def test_name_error(self): + # gh-109118: This crashed the interpreter due to a refcounting bug + code = """ + class name_2[name_5]: + class name_4[name_5](name_0): + pass + """ + with self.assertRaises(NameError): + run_code(code) + + # Crashed with a slightly different stack trace + code = """ + class name_2[name_5]: + class name_4[name_5: name_5](name_0): + pass + """ + with self.assertRaises(NameError): + run_code(code) + + def test_broken_class_namespace(self): + code = """ + class WeirdMapping(dict): + def __missing__(self, key): + if key == "T": + raise RuntimeError + raise KeyError(key) + + class Meta(type): + def __prepare__(name, bases): + return WeirdMapping() + + class MyClass[V](metaclass=Meta): + class Inner[U](T): + pass + """ + with self.assertRaises(RuntimeError): + run_code(code) diff --git a/Lib/test/test_types.py b/Lib/test/test_types.py index 8556ca35..f2efee90 100644 --- a/Lib/test/test_types.py +++ b/Lib/test/test_types.py @@ -226,8 +226,8 @@ class TypesTests(unittest.TestCase): def test_int__format__(self): def test(i, format_spec, result): # just make sure we have the unified type for integers - assert type(i) == int - assert type(format_spec) == str + self.assertIs(type(i), int) + self.assertIs(type(format_spec), str) self.assertEqual(i.__format__(format_spec), result) test(123456789, 'd', '123456789') @@ -782,8 +782,8 @@ class UnionTests(unittest.TestCase): def test_or_type_operator_with_TypeVar(self): TV = typing.TypeVar('T') - assert TV | str == typing.Union[TV, str] - assert str | TV == typing.Union[str, TV] + self.assertEqual(TV | str, typing.Union[TV, str]) + self.assertEqual(str | TV, typing.Union[str, TV]) self.assertIs((int | TV)[int], int) self.assertIs((TV | int)[int], int) @@ -887,51 +887,82 @@ class UnionTests(unittest.TestCase): ForwardBefore = 'Forward' | T def forward_after(x: ForwardAfter[int]) -> None: ... def forward_before(x: ForwardBefore[int]) -> None: ... - assert typing.get_args(typing.get_type_hints(forward_after)['x']) == (int, Forward) - assert typing.get_args(typing.get_type_hints(forward_before)['x']) == (int, Forward) + self.assertEqual(typing.get_args(typing.get_type_hints(forward_after)['x']), + (int, Forward)) + self.assertEqual(typing.get_args(typing.get_type_hints(forward_before)['x']), + (int, Forward)) def test_or_type_operator_with_Protocol(self): class Proto(typing.Protocol): def meth(self) -> int: ... - assert Proto | str == typing.Union[Proto, str] + self.assertEqual(Proto | str, typing.Union[Proto, str]) def test_or_type_operator_with_Alias(self): - assert list | str == typing.Union[list, str] - assert typing.List | str == typing.Union[typing.List, str] + self.assertEqual(list | str, typing.Union[list, str]) + self.assertEqual(typing.List | str, typing.Union[typing.List, str]) def test_or_type_operator_with_NamedTuple(self): - NT=namedtuple('A', ['B', 'C', 'D']) - assert NT | str == typing.Union[NT,str] + NT = namedtuple('A', ['B', 'C', 'D']) + self.assertEqual(NT | str, typing.Union[NT, str]) def test_or_type_operator_with_TypedDict(self): class Point2D(typing.TypedDict): x: int y: int label: str - assert Point2D | str == typing.Union[Point2D, str] + self.assertEqual(Point2D | str, typing.Union[Point2D, str]) def test_or_type_operator_with_NewType(self): UserId = typing.NewType('UserId', int) - assert UserId | str == typing.Union[UserId, str] + self.assertEqual(UserId | str, typing.Union[UserId, str]) def test_or_type_operator_with_IO(self): - assert typing.IO | str == typing.Union[typing.IO, str] + self.assertEqual(typing.IO | str, typing.Union[typing.IO, str]) def test_or_type_operator_with_SpecialForm(self): - assert typing.Any | str == typing.Union[typing.Any, str] - assert typing.NoReturn | str == typing.Union[typing.NoReturn, str] - assert typing.Optional[int] | str == typing.Union[typing.Optional[int], str] - assert typing.Optional[int] | str == typing.Union[int, str, None] - assert typing.Union[int, bool] | str == typing.Union[int, bool, str] + self.assertEqual(typing.Any | str, typing.Union[typing.Any, str]) + self.assertEqual(typing.NoReturn | str, typing.Union[typing.NoReturn, str]) + self.assertEqual(typing.Optional[int] | str, typing.Union[typing.Optional[int], str]) + self.assertEqual(typing.Optional[int] | str, typing.Union[int, str, None]) + self.assertEqual(typing.Union[int, bool] | str, typing.Union[int, bool, str]) + + def test_or_type_operator_with_Literal(self): + Literal = typing.Literal + self.assertEqual((Literal[1] | Literal[2]).__args__, + (Literal[1], Literal[2])) + + self.assertEqual((Literal[0] | Literal[False]).__args__, + (Literal[0], Literal[False])) + self.assertEqual((Literal[1] | Literal[True]).__args__, + (Literal[1], Literal[True])) + + self.assertEqual(Literal[1] | Literal[1], Literal[1]) + self.assertEqual(Literal['a'] | Literal['a'], Literal['a']) + + import enum + class Ints(enum.IntEnum): + A = 0 + B = 1 + + self.assertEqual(Literal[Ints.A] | Literal[Ints.A], Literal[Ints.A]) + self.assertEqual(Literal[Ints.B] | Literal[Ints.B], Literal[Ints.B]) + + self.assertEqual((Literal[Ints.B] | Literal[Ints.A]).__args__, + (Literal[Ints.B], Literal[Ints.A])) + + self.assertEqual((Literal[0] | Literal[Ints.A]).__args__, + (Literal[0], Literal[Ints.A])) + self.assertEqual((Literal[1] | Literal[Ints.B]).__args__, + (Literal[1], Literal[Ints.B])) def test_or_type_repr(self): - assert repr(int | str) == "int | str" - assert repr((int | str) | list) == "int | str | list" - assert repr(int | (str | list)) == "int | str | list" - assert repr(int | None) == "int | None" - assert repr(int | type(None)) == "int | None" - assert repr(int | typing.GenericAlias(list, int)) == "int | list[int]" + self.assertEqual(repr(int | str), "int | str") + self.assertEqual(repr((int | str) | list), "int | str | list") + self.assertEqual(repr(int | (str | list)), "int | str | list") + self.assertEqual(repr(int | None), "int | None") + self.assertEqual(repr(int | type(None)), "int | None") + self.assertEqual(repr(int | typing.GenericAlias(list, int)), "int | list[int]") def test_or_type_operator_with_genericalias(self): a = list[int] @@ -1203,6 +1234,16 @@ class MappingProxyTests(unittest.TestCase): self.assertDictEqual(mapping, {'a': 0, 'b': 1, 'c': 2}) self.assertDictEqual(other, {'c': 3, 'p': 0}) + def test_hash(self): + class HashableDict(dict): + def __hash__(self): + return 3844817361 + view = self.mappingproxy({'a': 1, 'b': 2}) + self.assertRaises(TypeError, hash, view) + mapping = HashableDict({'a': 1, 'b': 2}) + view = self.mappingproxy(mapping) + self.assertEqual(hash(view), hash(mapping)) + class ClassCreationTests(unittest.TestCase): @@ -1350,6 +1391,80 @@ class ClassCreationTests(unittest.TestCase): D = types.new_class('D', (A(), C, B()), {}) self.assertEqual(D.__bases__, (A1, A2, A3, C, B1, B2)) + def test_get_original_bases(self): + T = typing.TypeVar('T') + class A: pass + class B(typing.Generic[T]): pass + class C(B[int]): pass + class D(B[str], float): pass + + self.assertEqual(types.get_original_bases(A), (object,)) + self.assertEqual(types.get_original_bases(B), (typing.Generic[T],)) + self.assertEqual(types.get_original_bases(C), (B[int],)) + self.assertEqual(types.get_original_bases(int), (object,)) + self.assertEqual(types.get_original_bases(D), (B[str], float)) + + class E(list[T]): pass + class F(list[int]): pass + + self.assertEqual(types.get_original_bases(E), (list[T],)) + self.assertEqual(types.get_original_bases(F), (list[int],)) + + class FirstBase(typing.Generic[T]): pass + class SecondBase(typing.Generic[T]): pass + class First(FirstBase[int]): pass + class Second(SecondBase[int]): pass + class G(First, Second): pass + self.assertEqual(types.get_original_bases(G), (First, Second)) + + class First_(typing.Generic[T]): pass + class Second_(typing.Generic[T]): pass + class H(First_, Second_): pass + self.assertEqual(types.get_original_bases(H), (First_, Second_)) + + class ClassBasedNamedTuple(typing.NamedTuple): + x: int + + class GenericNamedTuple(typing.NamedTuple, typing.Generic[T]): + x: T + + CallBasedNamedTuple = typing.NamedTuple("CallBasedNamedTuple", [("x", int)]) + + self.assertIs( + types.get_original_bases(ClassBasedNamedTuple)[0], typing.NamedTuple + ) + self.assertEqual( + types.get_original_bases(GenericNamedTuple), + (typing.NamedTuple, typing.Generic[T]) + ) + self.assertIs( + types.get_original_bases(CallBasedNamedTuple)[0], typing.NamedTuple + ) + + class ClassBasedTypedDict(typing.TypedDict): + x: int + + class GenericTypedDict(typing.TypedDict, typing.Generic[T]): + x: T + + CallBasedTypedDict = typing.TypedDict("CallBasedTypedDict", {"x": int}) + + self.assertIs( + types.get_original_bases(ClassBasedTypedDict)[0], + typing.TypedDict + ) + self.assertEqual( + types.get_original_bases(GenericTypedDict), + (typing.TypedDict, typing.Generic[T]) + ) + self.assertIs( + types.get_original_bases(CallBasedTypedDict)[0], + typing.TypedDict + ) + + with self.assertRaisesRegex(TypeError, "Expected an instance of type"): + types.get_original_bases(object()) + # Many of the following tests are derived from test_descr.py def test_prepare_class(self): # Basic test of metaclass derivation @@ -2062,7 +2177,7 @@ class CoroutineTests(unittest.TestCase): wrapper = foo() wrapper.send(None) with self.assertRaisesRegex(Exception, 'ham'): - wrapper.throw(Exception, Exception('ham')) + wrapper.throw(Exception('ham')) # decorate foo second time foo = types.coroutine(foo) diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index 276f95ba..6c9f168b 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -1,7 +1,9 @@ import contextlib import collections +import collections.abc from collections import defaultdict from functools import lru_cache, wraps +import gc import inspect import itertools import pickle @@ -23,6 +25,7 @@ from typing import Generic, ClassVar, Final, final, Protocol from typing import assert_type, cast, runtime_checkable from typing import get_type_hints from typing import get_origin, get_args +from typing import override from typing import is_typeddict from typing import reveal_type from typing import dataclass_transform @@ -47,10 +50,9 @@ from test import mod_generics_cache from test import _typed_dict_helper -py_typing = import_helper.import_fresh_module('typing', blocked=['_typing']) -c_typing = import_helper.import_fresh_module('typing', fresh=['_typing']) - CANNOT_SUBCLASS_TYPE = 'Cannot subclass special typing classes' +NOT_A_BASE_TYPE = "type 'typing.%s' is not an acceptable base type" +CANNOT_SUBCLASS_INSTANCE = 'Cannot subclass an instance of %s' class BaseTestCase(TestCase): @@ -114,7 +116,7 @@ class AnyTests(BaseTestCase): class Sub(Any): pass self.assertEqual( repr(Sub), - "<class 'test.test_typing.AnyTests.test_repr.<locals>.Sub'>", + f"<class '{__name__}.AnyTests.test_repr.<locals>.Sub'>", ) def test_errors(self): @@ -178,10 +180,11 @@ class BottomTypeTestsMixin: self.bottom_type[int] def test_cannot_subclass(self): - with self.assertRaises(TypeError): + with self.assertRaisesRegex(TypeError, + 'Cannot subclass ' + re.escape(str(self.bottom_type))): class A(self.bottom_type): pass - with self.assertRaises(TypeError): + with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): class A(type(self.bottom_type)): pass @@ -274,10 +277,11 @@ class SelfTests(BaseTestCase): Self[int] def test_cannot_subclass(self): - with self.assertRaises(TypeError): + with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): class C(type(Self)): pass - with self.assertRaises(TypeError): + with self.assertRaisesRegex(TypeError, + r'Cannot subclass typing\.Self'): class C(Self): pass @@ -330,10 +334,11 @@ class LiteralStringTests(BaseTestCase): LiteralString[int] def test_cannot_subclass(self): - with self.assertRaises(TypeError): + with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): class C(type(LiteralString)): pass - with self.assertRaises(TypeError): + with self.assertRaisesRegex(TypeError, + r'Cannot subclass typing\.LiteralString'): class C(LiteralString): pass @@ -364,6 +369,55 @@ class TypeVarTests(BaseTestCase): self.assertEqual(T, T) # T is an instance of TypeVar self.assertIsInstance(T, TypeVar) + self.assertEqual(T.__name__, 'T') + self.assertEqual(T.__constraints__, ()) + self.assertIs(T.__bound__, None) + self.assertIs(T.__covariant__, False) + self.assertIs(T.__contravariant__, False) + self.assertIs(T.__infer_variance__, False) + self.assertEqual(T.__module__, __name__) + + def test_basic_with_exec(self): + ns = {} + exec('from typing import TypeVar; T = TypeVar("T", bound=float)', ns, ns) + T = ns['T'] + self.assertIsInstance(T, TypeVar) + self.assertEqual(T.__name__, 'T') + self.assertEqual(T.__constraints__, ()) + self.assertIs(T.__bound__, float) + self.assertIs(T.__covariant__, False) + self.assertIs(T.__contravariant__, False) + self.assertIs(T.__infer_variance__, False) + self.assertIs(T.__module__, None) + + def test_attributes(self): + T_bound = TypeVar('T_bound', bound=int) + self.assertEqual(T_bound.__name__, 'T_bound') + self.assertEqual(T_bound.__constraints__, ()) + self.assertIs(T_bound.__bound__, int) + + T_constraints = TypeVar('T_constraints', int, str) + self.assertEqual(T_constraints.__name__, 'T_constraints') + self.assertEqual(T_constraints.__constraints__, (int, str)) + self.assertIs(T_constraints.__bound__, None) + + T_co = TypeVar('T_co', covariant=True) + self.assertEqual(T_co.__name__, 'T_co') + self.assertIs(T_co.__covariant__, True) + self.assertIs(T_co.__contravariant__, False) + self.assertIs(T_co.__infer_variance__, False) + + T_contra = TypeVar('T_contra', contravariant=True) + self.assertEqual(T_contra.__name__, 'T_contra') + self.assertIs(T_contra.__covariant__, False) + self.assertIs(T_contra.__contravariant__, True) + self.assertIs(T_contra.__infer_variance__, False) + + T_infer = TypeVar('T_infer', infer_variance=True) + self.assertEqual(T_infer.__name__, 'T_infer') + self.assertIs(T_infer.__covariant__, False) + self.assertIs(T_infer.__contravariant__, False) + self.assertIs(T_infer.__infer_variance__, True) def test_typevar_instance_type_error(self): T = TypeVar('T') @@ -423,15 +477,13 @@ class TypeVarTests(BaseTestCase): self.assertNotEqual(TypeVar('T'), TypeVar('T')) self.assertNotEqual(TypeVar('T', int, str), TypeVar('T', int, str)) - def test_cannot_subclass_vars(self): - with self.assertRaises(TypeError): - class V(TypeVar('T')): - pass - - def test_cannot_subclass_var_itself(self): - with self.assertRaises(TypeError): - class V(TypeVar): - pass + def test_cannot_subclass(self): + with self.assertRaisesRegex(TypeError, NOT_A_BASE_TYPE % 'TypeVar'): + class V(TypeVar): pass + T = TypeVar("T") + with self.assertRaisesRegex(TypeError, + CANNOT_SUBCLASS_INSTANCE % 'TypeVar'): + class V(T): pass def test_cannot_instantiate_vars(self): with self.assertRaises(TypeError): @@ -442,6 +494,9 @@ class TypeVarTests(BaseTestCase): TypeVar('X', bound=Union) with self.assertRaises(TypeError): TypeVar('X', str, float, bound=Employee) + with self.assertRaisesRegex(TypeError, + r"Bound must be a type\. Got \(1, 2\)\."): + TypeVar('X', bound=(1, 2)) def test_missing__name__(self): # See bpo-39942 @@ -454,6 +509,12 @@ class TypeVarTests(BaseTestCase): with self.assertRaises(ValueError): TypeVar('T', covariant=True, contravariant=True) + def test_cannot_combine_explicit_and_infer(self): + with self.assertRaises(ValueError): + TypeVar('T', covariant=True, infer_variance=True) + with self.assertRaises(ValueError): + TypeVar('T', contravariant=True, infer_variance=True) + def test_var_substitution(self): T = TypeVar('T') subst = T.__typing_subst__ @@ -469,7 +530,6 @@ class TypeVarTests(BaseTestCase): def test_bad_var_substitution(self): T = TypeVar('T') - P = ParamSpec("P") bad_args = ( (), (int, str), Union, Generic, Generic[T], Protocol, Protocol[T], @@ -484,6 +544,16 @@ class TypeVarTests(BaseTestCase): with self.assertRaises(TypeError): list[T][arg] + def test_many_weakrefs(self): + # gh-108295: this used to segfault + for cls in (ParamSpec, TypeVarTuple, TypeVar): + with self.subTest(cls=cls): + vals = weakref.WeakValueDictionary() + + for x in range(100000): + vals[x] = cls(str(x)) + del vals + def template_replace(templates: list[str], replacements: dict[str, list[str]]) -> list[tuple[str]]: """Renders templates with possible combinations of replacements. @@ -852,6 +922,14 @@ class UnpackTests(BaseTestCase): (*tuple[int],) Unpack[Tuple[int]] + def test_dir(self): + dir_items = set(dir(Unpack[Tuple[int]])) + for required_item in [ + '__args__', '__parameters__', '__origin__', + ]: + with self.subTest(required_item=required_item): + self.assertIn(required_item, dir_items) + def test_rejects_multiple_types(self): with self.assertRaises(TypeError): Unpack[Tuple[int], Tuple[str]] @@ -869,6 +947,11 @@ class UnpackTests(BaseTestCase): with self.assertRaises(TypeError): Unpack() + def test_usage_with_kwargs(self): + Movie = TypedDict('Movie', {'name': str, 'year': int}) + def foo(**kwargs: Unpack[Movie]): ... + self.assertEqual(repr(foo.__annotations__['kwargs']), + f"typing.Unpack[{__name__}.Movie]") class TypeVarTupleTests(BaseTestCase): @@ -882,6 +965,17 @@ class TypeVarTupleTests(BaseTestCase): Ts2 = TypeVarTuple('Ts2') self.assertEqual(Ts2.__name__, 'Ts2') + def test_module(self): + Ts = TypeVarTuple('Ts') + self.assertEqual(Ts.__module__, __name__) + + def test_exec(self): + ns = {} + exec('from typing import TypeVarTuple; Ts = TypeVarTuple("Ts")', ns) + Ts = ns['Ts'] + self.assertEqual(Ts.__name__, 'Ts') + self.assertIs(Ts.__module__, None) + def test_instance_is_equal_to_itself(self): Ts = TypeVarTuple('Ts') self.assertEqual(Ts, Ts) @@ -1033,22 +1127,20 @@ class TypeVarTupleTests(BaseTestCase): def test_repr_is_correct(self): Ts = TypeVarTuple('Ts') - T = TypeVar('T') - T2 = TypeVar('T2') class G1(Generic[*Ts]): pass class G2(Generic[Unpack[Ts]]): pass self.assertEqual(repr(Ts), 'Ts') - self.assertEqual(repr((*Ts,)[0]), '*Ts') - self.assertEqual(repr(Unpack[Ts]), '*Ts') + self.assertEqual(repr((*Ts,)[0]), 'typing.Unpack[Ts]') + self.assertEqual(repr(Unpack[Ts]), 'typing.Unpack[Ts]') - self.assertEqual(repr(tuple[*Ts]), 'tuple[*Ts]') - self.assertEqual(repr(Tuple[Unpack[Ts]]), 'typing.Tuple[*Ts]') + self.assertEqual(repr(tuple[*Ts]), 'tuple[typing.Unpack[Ts]]') + self.assertEqual(repr(Tuple[Unpack[Ts]]), 'typing.Tuple[typing.Unpack[Ts]]') - self.assertEqual(repr(*tuple[*Ts]), '*tuple[*Ts]') - self.assertEqual(repr(Unpack[Tuple[Unpack[Ts]]]), '*typing.Tuple[*Ts]') + self.assertEqual(repr(*tuple[*Ts]), '*tuple[typing.Unpack[Ts]]') + self.assertEqual(repr(Unpack[Tuple[Unpack[Ts]]]), 'typing.Unpack[typing.Tuple[typing.Unpack[Ts]]]') def test_variadic_class_repr_is_correct(self): Ts = TypeVarTuple('Ts') @@ -1065,94 +1157,93 @@ class TypeVarTupleTests(BaseTestCase): self.assertEndsWith(repr(A[*tuple[int, ...]]), 'A[*tuple[int, ...]]') self.assertEndsWith(repr(B[Unpack[Tuple[int, ...]]]), - 'B[*typing.Tuple[int, ...]]') + 'B[typing.Unpack[typing.Tuple[int, ...]]]') self.assertEndsWith(repr(A[float, *tuple[int, ...]]), 'A[float, *tuple[int, ...]]') self.assertEndsWith(repr(A[float, Unpack[Tuple[int, ...]]]), - 'A[float, *typing.Tuple[int, ...]]') + 'A[float, typing.Unpack[typing.Tuple[int, ...]]]') self.assertEndsWith(repr(A[*tuple[int, ...], str]), 'A[*tuple[int, ...], str]') self.assertEndsWith(repr(B[Unpack[Tuple[int, ...]], str]), - 'B[*typing.Tuple[int, ...], str]') + 'B[typing.Unpack[typing.Tuple[int, ...]], str]') self.assertEndsWith(repr(A[float, *tuple[int, ...], str]), 'A[float, *tuple[int, ...], str]') self.assertEndsWith(repr(B[float, Unpack[Tuple[int, ...]], str]), - 'B[float, *typing.Tuple[int, ...], str]') + 'B[float, typing.Unpack[typing.Tuple[int, ...]], str]') def test_variadic_class_alias_repr_is_correct(self): Ts = TypeVarTuple('Ts') class A(Generic[Unpack[Ts]]): pass B = A[*Ts] - self.assertEndsWith(repr(B), 'A[*Ts]') + self.assertEndsWith(repr(B), 'A[typing.Unpack[Ts]]') self.assertEndsWith(repr(B[()]), 'A[()]') self.assertEndsWith(repr(B[float]), 'A[float]') self.assertEndsWith(repr(B[float, str]), 'A[float, str]') C = A[Unpack[Ts]] - self.assertEndsWith(repr(C), 'A[*Ts]') + self.assertEndsWith(repr(C), 'A[typing.Unpack[Ts]]') self.assertEndsWith(repr(C[()]), 'A[()]') self.assertEndsWith(repr(C[float]), 'A[float]') self.assertEndsWith(repr(C[float, str]), 'A[float, str]') D = A[*Ts, int] - self.assertEndsWith(repr(D), 'A[*Ts, int]') + self.assertEndsWith(repr(D), 'A[typing.Unpack[Ts], int]') self.assertEndsWith(repr(D[()]), 'A[int]') self.assertEndsWith(repr(D[float]), 'A[float, int]') self.assertEndsWith(repr(D[float, str]), 'A[float, str, int]') E = A[Unpack[Ts], int] - self.assertEndsWith(repr(E), 'A[*Ts, int]') + self.assertEndsWith(repr(E), 'A[typing.Unpack[Ts], int]') self.assertEndsWith(repr(E[()]), 'A[int]') self.assertEndsWith(repr(E[float]), 'A[float, int]') self.assertEndsWith(repr(E[float, str]), 'A[float, str, int]') F = A[int, *Ts] - self.assertEndsWith(repr(F), 'A[int, *Ts]') + self.assertEndsWith(repr(F), 'A[int, typing.Unpack[Ts]]') self.assertEndsWith(repr(F[()]), 'A[int]') self.assertEndsWith(repr(F[float]), 'A[int, float]') self.assertEndsWith(repr(F[float, str]), 'A[int, float, str]') G = A[int, Unpack[Ts]] - self.assertEndsWith(repr(G), 'A[int, *Ts]') + self.assertEndsWith(repr(G), 'A[int, typing.Unpack[Ts]]') self.assertEndsWith(repr(G[()]), 'A[int]') self.assertEndsWith(repr(G[float]), 'A[int, float]') self.assertEndsWith(repr(G[float, str]), 'A[int, float, str]') H = A[int, *Ts, str] - self.assertEndsWith(repr(H), 'A[int, *Ts, str]') + self.assertEndsWith(repr(H), 'A[int, typing.Unpack[Ts], str]') self.assertEndsWith(repr(H[()]), 'A[int, str]') self.assertEndsWith(repr(H[float]), 'A[int, float, str]') self.assertEndsWith(repr(H[float, str]), 'A[int, float, str, str]') I = A[int, Unpack[Ts], str] - self.assertEndsWith(repr(I), 'A[int, *Ts, str]') + self.assertEndsWith(repr(I), 'A[int, typing.Unpack[Ts], str]') self.assertEndsWith(repr(I[()]), 'A[int, str]') self.assertEndsWith(repr(I[float]), 'A[int, float, str]') self.assertEndsWith(repr(I[float, str]), 'A[int, float, str, str]') J = A[*Ts, *tuple[str, ...]] - self.assertEndsWith(repr(J), 'A[*Ts, *tuple[str, ...]]') + self.assertEndsWith(repr(J), 'A[typing.Unpack[Ts], *tuple[str, ...]]') self.assertEndsWith(repr(J[()]), 'A[*tuple[str, ...]]') self.assertEndsWith(repr(J[float]), 'A[float, *tuple[str, ...]]') self.assertEndsWith(repr(J[float, str]), 'A[float, str, *tuple[str, ...]]') K = A[Unpack[Ts], Unpack[Tuple[str, ...]]] - self.assertEndsWith(repr(K), 'A[*Ts, *typing.Tuple[str, ...]]') - self.assertEndsWith(repr(K[()]), 'A[*typing.Tuple[str, ...]]') - self.assertEndsWith(repr(K[float]), 'A[float, *typing.Tuple[str, ...]]') - self.assertEndsWith(repr(K[float, str]), 'A[float, str, *typing.Tuple[str, ...]]') + self.assertEndsWith(repr(K), 'A[typing.Unpack[Ts], typing.Unpack[typing.Tuple[str, ...]]]') + self.assertEndsWith(repr(K[()]), 'A[typing.Unpack[typing.Tuple[str, ...]]]') + self.assertEndsWith(repr(K[float]), 'A[float, typing.Unpack[typing.Tuple[str, ...]]]') + self.assertEndsWith(repr(K[float, str]), 'A[float, str, typing.Unpack[typing.Tuple[str, ...]]]') - def test_cannot_subclass_class(self): - with self.assertRaises(TypeError): + def test_cannot_subclass(self): + with self.assertRaisesRegex(TypeError, NOT_A_BASE_TYPE % 'TypeVarTuple'): class C(TypeVarTuple): pass - - def test_cannot_subclass_instance(self): Ts = TypeVarTuple('Ts') - with self.assertRaises(TypeError): + with self.assertRaisesRegex(TypeError, + CANNOT_SUBCLASS_INSTANCE % 'TypeVarTuple'): class C(Ts): pass with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): class C(type(Unpack)): pass @@ -1163,9 +1254,9 @@ class TypeVarTupleTests(BaseTestCase): with self.assertRaisesRegex(TypeError, r'Cannot subclass typing\.Unpack'): class C(Unpack): pass - with self.assertRaisesRegex(TypeError, r'Cannot subclass \*Ts'): + with self.assertRaisesRegex(TypeError, r'Cannot subclass typing.Unpack\[Ts\]'): class C(*Ts): pass - with self.assertRaisesRegex(TypeError, r'Cannot subclass \*Ts'): + with self.assertRaisesRegex(TypeError, r'Cannot subclass typing.Unpack\[Ts\]'): class C(Unpack[Ts]): pass def test_variadic_class_args_are_correct(self): @@ -1304,7 +1395,7 @@ class TypeVarTupleTests(BaseTestCase): i = Callable[[None], *Ts] j = Callable[[None], Unpack[Ts]] self.assertEqual(i.__args__, (type(None), *Ts)) - self.assertEqual(i.__args__, (type(None), Unpack[Ts])) + self.assertEqual(j.__args__, (type(None), Unpack[Ts])) k = Callable[[None], tuple[int, *Ts]] l = Callable[[None], Tuple[int, Unpack[Ts]]] @@ -1432,8 +1523,6 @@ class TypeVarTupleTests(BaseTestCase): self.assertEqual(g.__annotations__, {'args': (*Ts,)[0]}) def test_variadic_args_with_ellipsis_annotations_are_correct(self): - Ts = TypeVarTuple('Ts') - def a(*args: *tuple[int, ...]): pass self.assertEqual(a.__annotations__, {'args': (*tuple[int, ...],)[0]}) @@ -1701,14 +1790,24 @@ class UnionTests(BaseTestCase): u = Optional[str] self.assertEqual(repr(u), 'typing.Optional[str]') + def test_dir(self): + dir_items = set(dir(Union[str, int])) + for required_item in [ + '__args__', '__parameters__', '__origin__', + ]: + with self.subTest(required_item=required_item): + self.assertIn(required_item, dir_items) + def test_cannot_subclass(self): - with self.assertRaises(TypeError): + with self.assertRaisesRegex(TypeError, + r'Cannot subclass typing\.Union'): class C(Union): pass - with self.assertRaises(TypeError): + with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): class C(type(Union)): pass - with self.assertRaises(TypeError): + with self.assertRaisesRegex(TypeError, + r'Cannot subclass typing\.Union\[int, str\]'): class C(Union[int, str]): pass @@ -1773,6 +1872,35 @@ class UnionTests(BaseTestCase): Union[Elem, str] # Nor should this + def test_union_of_literals(self): + self.assertEqual(Union[Literal[1], Literal[2]].__args__, + (Literal[1], Literal[2])) + self.assertEqual(Union[Literal[1], Literal[1]], + Literal[1]) + + self.assertEqual(Union[Literal[False], Literal[0]].__args__, + (Literal[False], Literal[0])) + self.assertEqual(Union[Literal[True], Literal[1]].__args__, + (Literal[True], Literal[1])) + + import enum + class Ints(enum.IntEnum): + A = 0 + B = 1 + + self.assertEqual(Union[Literal[Ints.A], Literal[Ints.A]], + Literal[Ints.A]) + self.assertEqual(Union[Literal[Ints.B], Literal[Ints.B]], + Literal[Ints.B]) + + self.assertEqual(Union[Literal[Ints.A], Literal[Ints.B]].__args__, + (Literal[Ints.A], Literal[Ints.B])) + + self.assertEqual(Union[Literal[0], Literal[Ints.A], Literal[False]].__args__, + (Literal[0], Literal[Ints.A], Literal[False])) + self.assertEqual(Union[Literal[1], Literal[Ints.B], Literal[True]].__args__, + (Literal[1], Literal[Ints.B], Literal[True])) + class TupleTests(BaseTestCase): @@ -1839,6 +1967,15 @@ class BaseCallableTests: self.assertNotEqual(C, Callable[..., int]) self.assertNotEqual(C, Callable) + def test_dir(self): + Callable = self.Callable + dir_items = set(dir(Callable[..., int])) + for required_item in [ + '__args__', '__parameters__', '__origin__', + ]: + with self.subTest(required_item=required_item): + self.assertIn(required_item, dir_items) + def test_cannot_instantiate(self): Callable = self.Callable with self.assertRaises(TypeError): @@ -1921,14 +2058,29 @@ class BaseCallableTests: self.assertEqual(weakref.ref(alias)(), alias) def test_pickle(self): + global T_pickle, P_pickle, TS_pickle # needed for pickling Callable = self.Callable - alias = Callable[[int, str], float] - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - s = pickle.dumps(alias, proto) - loaded = pickle.loads(s) - self.assertEqual(alias.__origin__, loaded.__origin__) - self.assertEqual(alias.__args__, loaded.__args__) - self.assertEqual(alias.__parameters__, loaded.__parameters__) + T_pickle = TypeVar('T_pickle') + P_pickle = ParamSpec('P_pickle') + TS_pickle = TypeVarTuple('TS_pickle') + + samples = [ + Callable[[int, str], float], + Callable[P_pickle, int], + Callable[P_pickle, T_pickle], + Callable[Concatenate[int, P_pickle], int], + Callable[Concatenate[*TS_pickle, P_pickle], int], + ] + for alias in samples: + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.subTest(alias=alias, proto=proto): + s = pickle.dumps(alias, proto) + loaded = pickle.loads(s) + self.assertEqual(alias.__origin__, loaded.__origin__) + self.assertEqual(alias.__args__, loaded.__args__) + self.assertEqual(alias.__parameters__, loaded.__parameters__) + + del T_pickle, P_pickle, TS_pickle # cleaning up global state def test_var_substitution(self): Callable = self.Callable @@ -1954,6 +2106,16 @@ class BaseCallableTests: self.assertEqual(C5[int, str, float], Callable[[typing.List[int], tuple[str, int], float], int]) + def test_type_subst_error(self): + Callable = self.Callable + P = ParamSpec('P') + T = TypeVar('T') + + pat = "Expected a list of types, an ellipsis, ParamSpec, or Concatenate." + + with self.assertRaisesRegex(TypeError, pat): + Callable[P, T][0, int] + def test_type_erasure(self): Callable = self.Callable class C1(Callable): @@ -2024,6 +2186,48 @@ class BaseCallableTests: Callable[Concatenate[int, str, P2], int]) self.assertEqual(C[...], Callable[Concatenate[int, ...], int]) + def test_nested_paramspec(self): + # Since Callable has some special treatment, we want to be sure + # that substituion works correctly, see gh-103054 + Callable = self.Callable + P = ParamSpec('P') + P2 = ParamSpec('P2') + T = TypeVar('T') + T2 = TypeVar('T2') + Ts = TypeVarTuple('Ts') + class My(Generic[P, T]): + pass + + self.assertEqual(My.__parameters__, (P, T)) + + C1 = My[[int, T2], Callable[P2, T2]] + self.assertEqual(C1.__args__, ((int, T2), Callable[P2, T2])) + self.assertEqual(C1.__parameters__, (T2, P2)) + self.assertEqual(C1[str, [list[int], bytes]], + My[[int, str], Callable[[list[int], bytes], str]]) + + C2 = My[[Callable[[T2], int], list[T2]], str] + self.assertEqual(C2.__args__, ((Callable[[T2], int], list[T2]), str)) + self.assertEqual(C2.__parameters__, (T2,)) + self.assertEqual(C2[list[str]], + My[[Callable[[list[str]], int], list[list[str]]], str]) + + C3 = My[[Callable[P2, T2], T2], T2] + self.assertEqual(C3.__args__, ((Callable[P2, T2], T2), T2)) + self.assertEqual(C3.__parameters__, (P2, T2)) + self.assertEqual(C3[[], int], + My[[Callable[[], int], int], int]) + self.assertEqual(C3[[str, bool], int], + My[[Callable[[str, bool], int], int], int]) + self.assertEqual(C3[[str, bool], T][int], + My[[Callable[[str, bool], int], int], int]) + + C4 = My[[Callable[[int, *Ts, str], T2], T2], T2] + self.assertEqual(C4.__args__, ((Callable[[int, *Ts, str], T2], T2), T2)) + self.assertEqual(C4.__parameters__, (Ts, T2)) + self.assertEqual(C4[bool, bytes, float], + My[[Callable[[int, bool, bytes, str], float], float], float]) + def test_errors(self): Callable = self.Callable alias = Callable[[int, str], float] @@ -2064,6 +2268,13 @@ class LiteralTests(BaseTestCase): Literal[Literal[1, 2], Literal[4, 5]] Literal[b"foo", u"bar"] + def test_enum(self): + import enum + class My(enum.Enum): + A = 'A' + + self.assertEqual(Literal[My.A].__args__, (My.A,)) + def test_illegal_parameters_do_not_raise_runtime_errors(self): # Type checkers should reject these types, but we do not # raise errors at runtime to maintain maximum flexibility. @@ -2084,6 +2295,14 @@ class LiteralTests(BaseTestCase): self.assertEqual(repr(Literal[None]), "typing.Literal[None]") self.assertEqual(repr(Literal[1, 2, 3, 3]), "typing.Literal[1, 2, 3]") + def test_dir(self): + dir_items = set(dir(Literal[1, 2, 3])) + for required_item in [ + '__args__', '__parameters__', '__origin__', + ]: + with self.subTest(required_item=required_item): + self.assertIn(required_item, dir_items) + def test_cannot_init(self): with self.assertRaises(TypeError): Literal() @@ -2145,6 +2364,20 @@ class LiteralTests(BaseTestCase): self.assertEqual(l, Literal[1, 2, 3]) self.assertEqual(l.__args__, (1, 2, 3)) + def test_does_not_flatten_enum(self): + import enum + class Ints(enum.IntEnum): + A = 1 + B = 2 + + l = Literal[ + Literal[Ints.A], + Literal[Ints.B], + Literal[1], + Literal[2], + ] + self.assertEqual(l.__args__, (Ints.A, Ints.B, 1, 2)) + XK = TypeVar('XK', str, bytes) XV = TypeVar('XV') @@ -2251,6 +2484,48 @@ class ProtocolTests(BaseTestCase): self.assertNotIsSubclass(types.FunctionType, P) self.assertNotIsInstance(f, P) + def test_runtime_checkable_generic_non_protocol(self): + # Make sure this doesn't raise AttributeError + with self.assertRaisesRegex( + TypeError, + "@runtime_checkable can be only applied to protocol classes", + ): + @runtime_checkable + class Foo[T]: ... + + def test_runtime_checkable_generic(self): + @runtime_checkable + class Foo[T](Protocol): + def meth(self) -> T: ... + + class Impl: + def meth(self) -> int: ... + + self.assertIsSubclass(Impl, Foo) + + class NotImpl: + def method(self) -> int: ... + + self.assertNotIsSubclass(NotImpl, Foo) + + def test_pep695_generics_can_be_runtime_checkable(self): + @runtime_checkable + class HasX(Protocol): + x: int + + class Bar[T]: + x: T + def __init__(self, x): + self.x = x + + class Capybara[T]: + y: str + def __init__(self, y): + self.y = y + + self.assertIsInstance(Bar(1), HasX) + self.assertNotIsInstance(Capybara('a'), HasX) + def test_everything_implements_empty_protocol(self): @runtime_checkable class Empty(Protocol): @@ -2459,19 +2734,187 @@ class ProtocolTests(BaseTestCase): self.assertIsSubclass(C, PG) self.assertIsSubclass(BadP, PG) - with self.assertRaises(TypeError): + no_subscripted_generics = ( + "Subscripted generics cannot be used with class and instance checks" + ) + + with self.assertRaisesRegex(TypeError, no_subscripted_generics): issubclass(C, PG[T]) - with self.assertRaises(TypeError): + with self.assertRaisesRegex(TypeError, no_subscripted_generics): issubclass(C, PG[C]) - with self.assertRaises(TypeError): + + only_runtime_checkable_protocols = ( + "Instance and class checks can only be used with " + "@runtime_checkable protocols" + ) + + with self.assertRaisesRegex(TypeError, only_runtime_checkable_protocols): issubclass(C, BadP) - with self.assertRaises(TypeError): + with self.assertRaisesRegex(TypeError, only_runtime_checkable_protocols): issubclass(C, BadPG) - with self.assertRaises(TypeError): + + with self.assertRaisesRegex(TypeError, no_subscripted_generics): issubclass(P, PG[T]) - with self.assertRaises(TypeError): + with self.assertRaisesRegex(TypeError, no_subscripted_generics): issubclass(PG, PG[int]) + only_classes_allowed = r"issubclass\(\) arg 1 must be a class" + + with self.assertRaisesRegex(TypeError, only_classes_allowed): + issubclass(1, P) + with self.assertRaisesRegex(TypeError, only_classes_allowed): + issubclass(1, PG) + with self.assertRaisesRegex(TypeError, only_classes_allowed): + issubclass(1, BadP) + with self.assertRaisesRegex(TypeError, only_classes_allowed): + issubclass(1, BadPG) + + def test_implicit_issubclass_between_two_protocols(self): + @runtime_checkable + class CallableMembersProto(Protocol): + def meth(self): ... + + # All the below protocols should be considered "subclasses" + # of CallableMembersProto at runtime, + # even though none of them explicitly subclass CallableMembersProto + + class IdenticalProto(Protocol): + def meth(self): ... + + class SupersetProto(Protocol): + def meth(self): ... + def meth2(self): ... + + class NonCallableMembersProto(Protocol): + meth: Callable[[], None] + + class NonCallableMembersSupersetProto(Protocol): + meth: Callable[[], None] + meth2: Callable[[str, int], bool] + + class MixedMembersProto1(Protocol): + meth: Callable[[], None] + def meth2(self): ... + + class MixedMembersProto2(Protocol): + def meth(self): ... + meth2: Callable[[str, int], bool] + + for proto in ( + IdenticalProto, SupersetProto, NonCallableMembersProto, + NonCallableMembersSupersetProto, MixedMembersProto1, MixedMembersProto2 + ): + with self.subTest(proto=proto.__name__): + self.assertIsSubclass(proto, CallableMembersProto) + + # These two shouldn't be considered subclasses of CallableMembersProto, however, + # since they don't have the `meth` protocol member + + class EmptyProtocol(Protocol): ... + class UnrelatedProtocol(Protocol): + def wut(self): ... + + self.assertNotIsSubclass(EmptyProtocol, CallableMembersProto) + self.assertNotIsSubclass(UnrelatedProtocol, CallableMembersProto) + + # These aren't protocols at all (despite having annotations), + # so they should only be considered subclasses of CallableMembersProto + # if they *actually have an attribute* matching the `meth` member + # (just having an annotation is insufficient) + + class AnnotatedButNotAProtocol: + meth: Callable[[], None] + + class NotAProtocolButAnImplicitSubclass: + def meth(self): pass + + class NotAProtocolButAnImplicitSubclass2: + meth: Callable[[], None] + def meth(self): pass + + class NotAProtocolButAnImplicitSubclass3: + meth: Callable[[], None] + meth2: Callable[[int, str], bool] + def meth(self): pass + def meth(self, x, y): return True + + self.assertNotIsSubclass(AnnotatedButNotAProtocol, CallableMembersProto) + self.assertIsSubclass(NotAProtocolButAnImplicitSubclass, CallableMembersProto) + self.assertIsSubclass(NotAProtocolButAnImplicitSubclass2, CallableMembersProto) + self.assertIsSubclass(NotAProtocolButAnImplicitSubclass3, CallableMembersProto) + + def test_isinstance_checks_not_at_whim_of_gc(self): + self.addCleanup(gc.enable) + gc.disable() + + with self.assertRaisesRegex( + TypeError, + "Protocols can only inherit from other protocols" + ): + class Foo(collections.abc.Mapping, Protocol): + pass + + self.assertNotIsInstance([], collections.abc.Mapping) + + def test_issubclass_and_isinstance_on_Protocol_itself(self): + class C: + def x(self): pass + + self.assertNotIsSubclass(object, Protocol) + self.assertNotIsInstance(object(), Protocol) + + self.assertNotIsSubclass(str, Protocol) + self.assertNotIsInstance('foo', Protocol) + + self.assertNotIsSubclass(C, Protocol) + self.assertNotIsInstance(C(), Protocol) + + only_classes_allowed = r"issubclass\(\) arg 1 must be a class" + + with self.assertRaisesRegex(TypeError, only_classes_allowed): + issubclass(1, Protocol) + with self.assertRaisesRegex(TypeError, only_classes_allowed): + issubclass('foo', Protocol) + with self.assertRaisesRegex(TypeError, only_classes_allowed): + issubclass(C(), Protocol) + + T = TypeVar('T') + + @runtime_checkable + class EmptyProtocol(Protocol): pass + + @runtime_checkable + class SupportsStartsWith(Protocol): + def startswith(self, x: str) -> bool: ... + + @runtime_checkable + class SupportsX(Protocol[T]): + def x(self): ... + + for proto in EmptyProtocol, SupportsStartsWith, SupportsX: + with self.subTest(proto=proto.__name__): + self.assertIsSubclass(proto, Protocol) + + # gh-105237 / PR #105239: + # check that the presence of Protocol subclasses + # where `issubclass(X, <subclass>)` evaluates to True + # doesn't influence the result of `issubclass(X, Protocol)` + + self.assertIsSubclass(object, EmptyProtocol) + self.assertIsInstance(object(), EmptyProtocol) + self.assertNotIsSubclass(object, Protocol) + self.assertNotIsInstance(object(), Protocol) + + self.assertIsSubclass(str, SupportsStartsWith) + self.assertIsInstance('foo', SupportsStartsWith) + self.assertNotIsSubclass(str, Protocol) + self.assertNotIsInstance('foo', Protocol) + + self.assertIsSubclass(C, SupportsX) + self.assertIsInstance(C(), SupportsX) + self.assertNotIsSubclass(C, Protocol) + self.assertNotIsInstance(C(), Protocol) + def test_protocols_issubclass_non_callable(self): class C: x = 1 @@ -2480,12 +2923,19 @@ class ProtocolTests(BaseTestCase): class PNonCall(Protocol): x = 1 - with self.assertRaises(TypeError): + non_callable_members_illegal = ( + "Protocols with non-method members don't support issubclass()" + ) + + with self.assertRaisesRegex(TypeError, non_callable_members_illegal): issubclass(C, PNonCall) + self.assertIsInstance(C(), PNonCall) PNonCall.register(C) - with self.assertRaises(TypeError): + + with self.assertRaisesRegex(TypeError, non_callable_members_illegal): issubclass(C, PNonCall) + self.assertIsInstance(C(), PNonCall) # check that non-protocol subclasses are not affected @@ -2496,9 +2946,98 @@ class ProtocolTests(BaseTestCase): D.register(C) self.assertIsSubclass(C, D) self.assertIsInstance(C(), D) - with self.assertRaises(TypeError): + + with self.assertRaisesRegex(TypeError, non_callable_members_illegal): issubclass(D, PNonCall) + def test_no_weird_caching_with_issubclass_after_isinstance(self): + @runtime_checkable + class Spam(Protocol): + x: int + + class Eggs: + def __init__(self) -> None: + self.x = 42 + + self.assertIsInstance(Eggs(), Spam) + + # gh-104555: If we didn't override ABCMeta.__subclasscheck__ in _ProtocolMeta, + # TypeError wouldn't be raised here, + # as the cached result of the isinstance() check immediately above + # would mean the issubclass() call would short-circuit + # before we got to the "raise TypeError" line + with self.assertRaisesRegex( + TypeError, + "Protocols with non-method members don't support issubclass()" + ): + issubclass(Eggs, Spam) + + def test_no_weird_caching_with_issubclass_after_isinstance_2(self): + @runtime_checkable + class Spam(Protocol): + x: int + + class Eggs: ... + + self.assertNotIsInstance(Eggs(), Spam) + + # gh-104555: If we didn't override ABCMeta.__subclasscheck__ in _ProtocolMeta, + # TypeError wouldn't be raised here, + # as the cached result of the isinstance() check immediately above + # would mean the issubclass() call would short-circuit + # before we got to the "raise TypeError" line + with self.assertRaisesRegex( + TypeError, + "Protocols with non-method members don't support issubclass()" + ): + issubclass(Eggs, Spam) + + def test_no_weird_caching_with_issubclass_after_isinstance_3(self): + @runtime_checkable + class Spam(Protocol): + x: int + + class Eggs: + def __getattr__(self, attr): + if attr == "x": + return 42 + raise AttributeError(attr) + + self.assertNotIsInstance(Eggs(), Spam) + + # gh-104555: If we didn't override ABCMeta.__subclasscheck__ in _ProtocolMeta, + # TypeError wouldn't be raised here, + # as the cached result of the isinstance() check immediately above + # would mean the issubclass() call would short-circuit + # before we got to the "raise TypeError" line + with self.assertRaisesRegex( + TypeError, + "Protocols with non-method members don't support issubclass()" + ): + issubclass(Eggs, Spam) + + def test_no_weird_caching_with_issubclass_after_isinstance_pep695(self): + @runtime_checkable + class Spam[T](Protocol): + x: T + + class Eggs[T]: + def __init__(self, x: T) -> None: + self.x = x + + self.assertIsInstance(Eggs(42), Spam) + + # gh-104555: If we didn't override ABCMeta.__subclasscheck__ in _ProtocolMeta, + # TypeError wouldn't be raised here, + # as the cached result of the isinstance() check immediately above + # would mean the issubclass() call would short-circuit + # before we got to the "raise TypeError" line + with self.assertRaisesRegex( + TypeError, + "Protocols with non-method members don't support issubclass()" + ): + issubclass(Eggs, Spam) + def test_protocols_isinstance(self): T = TypeVar('T') @@ -2510,6 +3049,22 @@ class ProtocolTests(BaseTestCase): class PG(Protocol[T]): def meth(x): ... + @runtime_checkable + class WeirdProto(Protocol): + meth = str.maketrans + + @runtime_checkable + class WeirdProto2(Protocol): + meth = lambda *args, **kwargs: None + + class CustomCallable: + def __call__(self, *args, **kwargs): + pass + + @runtime_checkable + class WeirderProto(Protocol): + meth = CustomCallable() + class BadP(Protocol): def meth(x): ... @@ -2519,17 +3074,209 @@ class ProtocolTests(BaseTestCase): class C: def meth(x): ... - self.assertIsInstance(C(), P) - self.assertIsInstance(C(), PG) - with self.assertRaises(TypeError): + class C2: + def __init__(self): + self.meth = lambda: None + + for klass in C, C2: + for proto in P, PG, WeirdProto, WeirdProto2, WeirderProto: + with self.subTest(klass=klass.__name__, proto=proto.__name__): + self.assertIsInstance(klass(), proto) + + no_subscripted_generics = "Subscripted generics cannot be used with class and instance checks" + + with self.assertRaisesRegex(TypeError, no_subscripted_generics): isinstance(C(), PG[T]) - with self.assertRaises(TypeError): + with self.assertRaisesRegex(TypeError, no_subscripted_generics): isinstance(C(), PG[C]) - with self.assertRaises(TypeError): + + only_runtime_checkable_msg = ( + "Instance and class checks can only be used " + "with @runtime_checkable protocols" + ) + + with self.assertRaisesRegex(TypeError, only_runtime_checkable_msg): isinstance(C(), BadP) - with self.assertRaises(TypeError): + with self.assertRaisesRegex(TypeError, only_runtime_checkable_msg): isinstance(C(), BadPG) + def test_protocols_isinstance_properties_and_descriptors(self): + class C: + @property + def attr(self): + return 42 + + class CustomDescriptor: + def __get__(self, obj, objtype=None): + return 42 + + class D: + attr = CustomDescriptor() + + # Check that properties set on superclasses + # are still found by the isinstance() logic + class E(C): ... + class F(D): ... + + class Empty: ... + + T = TypeVar('T') + + @runtime_checkable + class P(Protocol): + @property + def attr(self): ... + + @runtime_checkable + class P1(Protocol): + attr: int + + @runtime_checkable + class PG(Protocol[T]): + @property + def attr(self): ... + + @runtime_checkable + class PG1(Protocol[T]): + attr: T + + @runtime_checkable + class MethodP(Protocol): + def attr(self): ... + + @runtime_checkable + class MethodPG(Protocol[T]): + def attr(self) -> T: ... + + for protocol_class in P, P1, PG, PG1, MethodP, MethodPG: + for klass in C, D, E, F: + with self.subTest( + klass=klass.__name__, + protocol_class=protocol_class.__name__ + ): + self.assertIsInstance(klass(), protocol_class) + + with self.subTest(klass="Empty", protocol_class=protocol_class.__name__): + self.assertNotIsInstance(Empty(), protocol_class) + + class BadP(Protocol): + @property + def attr(self): ... + + class BadP1(Protocol): + attr: int + + class BadPG(Protocol[T]): + @property + def attr(self): ... + + class BadPG1(Protocol[T]): + attr: T + + cases = ( + PG[T], PG[C], PG1[T], PG1[C], MethodPG[T], + MethodPG[C], BadP, BadP1, BadPG, BadPG1 + ) + + for obj in cases: + for klass in C, D, E, F, Empty: + with self.subTest(klass=klass.__name__, obj=obj): + with self.assertRaises(TypeError): + isinstance(klass(), obj) + + def test_protocols_isinstance_not_fooled_by_custom_dir(self): + @runtime_checkable + class HasX(Protocol): + x: int + + class CustomDirWithX: + x = 10 + def __dir__(self): + return [] + + class CustomDirWithoutX: + def __dir__(self): + return ["x"] + + self.assertIsInstance(CustomDirWithX(), HasX) + self.assertNotIsInstance(CustomDirWithoutX(), HasX) + + def test_protocols_isinstance_attribute_access_with_side_effects(self): + class C: + @property + def attr(self): + raise AttributeError('no') + + class CustomDescriptor: + def __get__(self, obj, objtype=None): + raise RuntimeError("NO") + + class D: + attr = CustomDescriptor() + + # Check that properties set on superclasses + # are still found by the isinstance() logic + class E(C): ... + class F(D): ... + + class WhyWouldYouDoThis: + def __getattr__(self, name): + raise RuntimeError("wut") + + T = TypeVar('T') + + @runtime_checkable + class P(Protocol): + @property + def attr(self): ... + + @runtime_checkable + class P1(Protocol): + attr: int + + @runtime_checkable + class PG(Protocol[T]): + @property + def attr(self): ... + + @runtime_checkable + class PG1(Protocol[T]): + attr: T + + @runtime_checkable + class MethodP(Protocol): + def attr(self): ... + + @runtime_checkable + class MethodPG(Protocol[T]): + def attr(self) -> T: ... + + for protocol_class in P, P1, PG, PG1, MethodP, MethodPG: + for klass in C, D, E, F: + with self.subTest( + klass=klass.__name__, + protocol_class=protocol_class.__name__ + ): + self.assertIsInstance(klass(), protocol_class) + + with self.subTest( + klass="WhyWouldYouDoThis", + protocol_class=protocol_class.__name__ + ): + self.assertNotIsInstance(WhyWouldYouDoThis(), protocol_class) + + def test_protocols_isinstance___slots__(self): + # As per the consensus in https://github.com/python/typing/issues/1367, + # this is desirable behaviour + @runtime_checkable + class HasX(Protocol): + x: int + + class HasNothingButSlots: + __slots__ = ("x",) + + self.assertIsInstance(HasNothingButSlots(), HasX) + def test_protocols_isinstance_py36(self): class APoint: def __init__(self, x, y, label): @@ -2585,6 +3332,20 @@ class ProtocolTests(BaseTestCase): self.assertIsInstance(C(1), P) self.assertIsInstance(C(1), PG) + def test_protocols_isinstance_monkeypatching(self): + @runtime_checkable + class HasX(Protocol): + x: int + + class Foo: ... + + f = Foo() + self.assertNotIsInstance(f, HasX) + f.x = 42 + self.assertIsInstance(f, HasX) + del f.x + self.assertNotIsInstance(f, HasX) + def test_protocol_checks_after_subscript(self): class P(Protocol[T]): pass class C(P[T]): pass @@ -2668,10 +3429,10 @@ class ProtocolTests(BaseTestCase): class NonPR(PR): pass - class C: + class C(metaclass=abc.ABCMeta): x = 1 - class D: + class D(metaclass=abc.ABCMeta): def meth(self): pass self.assertNotIsInstance(C(), NonP) @@ -2681,6 +3442,20 @@ class ProtocolTests(BaseTestCase): self.assertIsInstance(NonPR(), PR) self.assertIsSubclass(NonPR, PR) + self.assertNotIn("__protocol_attrs__", vars(NonP)) + self.assertNotIn("__protocol_attrs__", vars(NonPR)) + self.assertNotIn("__callable_proto_members_only__", vars(NonP)) + self.assertNotIn("__callable_proto_members_only__", vars(NonPR)) + + acceptable_extra_attrs = { + '_is_protocol', '_is_runtime_protocol', '__parameters__', + '__init__', '__annotations__', '__subclasshook__', + } + self.assertLessEqual(vars(NonP).keys(), vars(C).keys() | acceptable_extra_attrs) + self.assertLessEqual( + vars(NonPR).keys(), vars(D).keys() | acceptable_extra_attrs + ) + def test_custom_subclasshook(self): class P(Protocol): x = 1 @@ -2700,6 +3475,46 @@ class ProtocolTests(BaseTestCase): self.assertIsSubclass(OKClass, C) self.assertNotIsSubclass(BadClass, C) + def test_custom_subclasshook_2(self): + @runtime_checkable + class HasX(Protocol): + # The presence of a non-callable member + # would mean issubclass() checks would fail with TypeError + # if it weren't for the custom `__subclasshook__` method + x = 1 + + @classmethod + def __subclasshook__(cls, other): + return hasattr(other, 'x') + + class Empty: pass + + class ImplementsHasX: + x = 1 + + self.assertIsInstance(ImplementsHasX(), HasX) + self.assertNotIsInstance(Empty(), HasX) + self.assertIsSubclass(ImplementsHasX, HasX) + self.assertNotIsSubclass(Empty, HasX) + + # isinstance() and issubclass() checks against this still raise TypeError, + # despite the presence of the custom __subclasshook__ method, + # as it's not decorated with @runtime_checkable + class NotRuntimeCheckable(Protocol): + @classmethod + def __subclasshook__(cls, other): + return hasattr(other, 'x') + + must_be_runtime_checkable = ( + "Instance and class checks can only be used " + "with @runtime_checkable protocols" + ) + + with self.assertRaisesRegex(TypeError, must_be_runtime_checkable): + issubclass(object, NotRuntimeCheckable) + with self.assertRaisesRegex(TypeError, must_be_runtime_checkable): + isinstance(object(), NotRuntimeCheckable) + def test_issubclass_fails_correctly(self): @runtime_checkable class P(Protocol): @@ -2707,7 +3522,7 @@ class ProtocolTests(BaseTestCase): class C: pass - with self.assertRaises(TypeError): + with self.assertRaisesRegex(TypeError, r"issubclass\(\) arg 1 must be a class"): issubclass(C(), P) def test_defining_generic_protocols(self): @@ -2765,6 +3580,24 @@ class ProtocolTests(BaseTestCase): self.assertIsInstance(Test(), PSub) + def test_pep695_generic_protocol_callable_members(self): + @runtime_checkable + class Foo[T](Protocol): + def meth(self, x: T) -> None: ... + + class Bar[T]: + def meth(self, x: T) -> None: ... + + self.assertIsInstance(Bar(), Foo) + self.assertIsSubclass(Bar, Foo) + + @runtime_checkable + class SupportsTrunc[T](Protocol): + def __trunc__(self) -> T: ... + + self.assertIsInstance(0.0, SupportsTrunc) + self.assertIsSubclass(float, SupportsTrunc) + def test_init_called(self): T = TypeVar('T') @@ -2916,8 +3749,8 @@ class ProtocolTests(BaseTestCase): def __init__(self): self.x = None - self.assertIsInstance(C(), P) - self.assertIsInstance(D(), P) + self.assertIsInstance(CI(), P) + self.assertIsInstance(DI(), P) def test_protocols_in_unions(self): class P(Protocol): @@ -3025,8 +3858,24 @@ class ProtocolTests(BaseTestCase): def close(self): return 0 - self.assertIsSubclass(B, Custom) - self.assertNotIsSubclass(A, Custom) + self.assertIsSubclass(B, Custom) + self.assertNotIsSubclass(A, Custom) + + @runtime_checkable + class ReleasableBuffer(collections.abc.Buffer, Protocol): + def __release_buffer__(self, mv: memoryview) -> None: ... + + class C: pass + class D: + def __buffer__(self, flags: int) -> memoryview: + return memoryview(b'') + def __release_buffer__(self, mv: memoryview) -> None: + pass + + self.assertIsSubclass(D, ReleasableBuffer) + self.assertIsInstance(D(), ReleasableBuffer) + self.assertNotIsSubclass(C, ReleasableBuffer) + self.assertNotIsInstance(C(), ReleasableBuffer) def test_builtin_protocol_allowlist(self): with self.assertRaises(TypeError): @@ -3053,6 +3902,93 @@ class ProtocolTests(BaseTestCase): Foo() # Previously triggered RecursionError + def test_interaction_with_isinstance_checks_on_superclasses_with_ABCMeta(self): + # Ensure the cache is empty, or this test won't work correctly + collections.abc.Sized._abc_registry_clear() + + class Foo(collections.abc.Sized, Protocol): pass + + # gh-105144: this previously raised TypeError + # if a Protocol subclass of Sized had been created + # before any isinstance() checks against Sized + self.assertNotIsInstance(1, collections.abc.Sized) + + def test_interaction_with_isinstance_checks_on_superclasses_with_ABCMeta_2(self): + # Ensure the cache is empty, or this test won't work correctly + collections.abc.Sized._abc_registry_clear() + + class Foo(typing.Sized, Protocol): pass + + # gh-105144: this previously raised TypeError + # if a Protocol subclass of Sized had been created + # before any isinstance() checks against Sized + self.assertNotIsInstance(1, typing.Sized) + + def test_empty_protocol_decorated_with_final(self): + @final + @runtime_checkable + class EmptyProtocol(Protocol): ... + + self.assertIsSubclass(object, EmptyProtocol) + self.assertIsInstance(object(), EmptyProtocol) + + def test_protocol_decorated_with_final_callable_members(self): + @final + @runtime_checkable + class ProtocolWithMethod(Protocol): + def startswith(self, string: str) -> bool: ... + + self.assertIsSubclass(str, ProtocolWithMethod) + self.assertNotIsSubclass(int, ProtocolWithMethod) + self.assertIsInstance('foo', ProtocolWithMethod) + self.assertNotIsInstance(42, ProtocolWithMethod) + + def test_protocol_decorated_with_final_noncallable_members(self): + @final + @runtime_checkable + class ProtocolWithNonCallableMember(Protocol): + x: int + + class Foo: + x = 42 + + only_callable_members_please = ( + r"Protocols with non-method members don't support issubclass()" + ) + + with self.assertRaisesRegex(TypeError, only_callable_members_please): + issubclass(Foo, ProtocolWithNonCallableMember) + + with self.assertRaisesRegex(TypeError, only_callable_members_please): + issubclass(int, ProtocolWithNonCallableMember) + + self.assertIsInstance(Foo(), ProtocolWithNonCallableMember) + self.assertNotIsInstance(42, ProtocolWithNonCallableMember) + + def test_protocol_decorated_with_final_mixed_members(self): + @final + @runtime_checkable + class ProtocolWithMixedMembers(Protocol): + x: int + def method(self) -> None: ... + + class Foo: + x = 42 + def method(self) -> None: ... + + only_callable_members_please = ( + r"Protocols with non-method members don't support issubclass()" + ) + + with self.assertRaisesRegex(TypeError, only_callable_members_please): + issubclass(Foo, ProtocolWithMixedMembers) + + with self.assertRaisesRegex(TypeError, only_callable_members_please): + issubclass(int, ProtocolWithMixedMembers) + + self.assertIsInstance(Foo(), ProtocolWithMixedMembers) + self.assertNotIsInstance(42, ProtocolWithMixedMembers) + class GenericTests(BaseTestCase): @@ -3721,6 +4657,51 @@ class GenericTests(BaseTestCase): self.assertEqual(Y.__qualname__, 'GenericTests.test_repr_2.<locals>.Y') + def test_repr_3(self): + T = TypeVar('T') + T1 = TypeVar('T1') + P = ParamSpec('P') + P2 = ParamSpec('P2') + Ts = TypeVarTuple('Ts') + + class MyCallable(Generic[P, T]): + pass + + class DoubleSpec(Generic[P, P2, T]): + pass + + class TsP(Generic[*Ts, P]): + pass + + object_to_expected_repr = { + MyCallable[P, T]: "MyCallable[~P, ~T]", + MyCallable[Concatenate[T1, P], T]: "MyCallable[typing.Concatenate[~T1, ~P], ~T]", + MyCallable[[], bool]: "MyCallable[[], bool]", + MyCallable[[int], bool]: "MyCallable[[int], bool]", + MyCallable[[int, str], bool]: "MyCallable[[int, str], bool]", + MyCallable[[int, list[int]], bool]: "MyCallable[[int, list[int]], bool]", + MyCallable[Concatenate[*Ts, P], T]: "MyCallable[typing.Concatenate[typing.Unpack[Ts], ~P], ~T]", + + DoubleSpec[P2, P, T]: "DoubleSpec[~P2, ~P, ~T]", + DoubleSpec[[int], [str], bool]: "DoubleSpec[[int], [str], bool]", + DoubleSpec[[int, int], [str, str], bool]: "DoubleSpec[[int, int], [str, str], bool]", + + TsP[*Ts, P]: "TsP[typing.Unpack[Ts], ~P]", + TsP[int, str, list[int], []]: "TsP[int, str, list[int], []]", + TsP[int, [str, list[int]]]: "TsP[int, [str, list[int]]]", + + # These lines are just too long to fit: + MyCallable[Concatenate[*Ts, P], int][int, str, [bool, float]]: + "MyCallable[[int, str, bool, float], int]", + } + + for obj, expected_repr in object_to_expected_repr.items(): + with self.subTest(obj=obj, expected_repr=expected_repr): + self.assertRegex( + repr(obj), + fr"^{re.escape(MyCallable.__module__)}.*\.{re.escape(expected_repr)}$", + ) + def test_eq_1(self): self.assertEqual(Generic, Generic) self.assertEqual(Generic[T], Generic[T]) @@ -4008,12 +4989,20 @@ class ClassVarTests(BaseTestCase): self.assertEqual(repr(cv), 'typing.ClassVar[%s.Employee]' % __name__) def test_cannot_subclass(self): - with self.assertRaises(TypeError): + with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): class C(type(ClassVar)): pass - with self.assertRaises(TypeError): + with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): class C(type(ClassVar[int])): pass + with self.assertRaisesRegex(TypeError, + r'Cannot subclass typing\.ClassVar'): + class C(ClassVar): + pass + with self.assertRaisesRegex(TypeError, + r'Cannot subclass typing\.ClassVar\[int\]'): + class C(ClassVar[int]): + pass def test_cannot_init(self): with self.assertRaises(TypeError): @@ -4050,12 +5039,20 @@ class FinalTests(BaseTestCase): self.assertEqual(repr(cv), 'typing.Final[tuple[int]]') def test_cannot_subclass(self): - with self.assertRaises(TypeError): + with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): class C(type(Final)): pass - with self.assertRaises(TypeError): + with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): class C(type(Final[int])): pass + with self.assertRaisesRegex(TypeError, + r'Cannot subclass typing\.Final'): + class C(Final): + pass + with self.assertRaisesRegex(TypeError, + r'Cannot subclass typing\.Final\[int\]'): + class C(Final[int]): + pass def test_cannot_init(self): with self.assertRaises(TypeError): @@ -4146,6 +5143,134 @@ class FinalDecoratorTests(BaseTestCase): self.assertIs(True, Methods.cached.__final__) +class OverrideDecoratorTests(BaseTestCase): + def test_override(self): + class Base: + def normal_method(self): ... + @classmethod + def class_method_good_order(cls): ... + @classmethod + def class_method_bad_order(cls): ... + @staticmethod + def static_method_good_order(): ... + @staticmethod + def static_method_bad_order(): ... + + class Derived(Base): + @override + def normal_method(self): + return 42 + + @classmethod + @override + def class_method_good_order(cls): + return 42 + @override + @classmethod + def class_method_bad_order(cls): + return 42 + + @staticmethod + @override + def static_method_good_order(): + return 42 + @override + @staticmethod + def static_method_bad_order(): + return 42 + + self.assertIsSubclass(Derived, Base) + instance = Derived() + self.assertEqual(instance.normal_method(), 42) + self.assertIs(True, Derived.normal_method.__override__) + self.assertIs(True, instance.normal_method.__override__) + + self.assertEqual(Derived.class_method_good_order(), 42) + self.assertIs(True, Derived.class_method_good_order.__override__) + self.assertEqual(Derived.class_method_bad_order(), 42) + self.assertIs(False, hasattr(Derived.class_method_bad_order, "__override__")) + + self.assertEqual(Derived.static_method_good_order(), 42) + self.assertIs(True, Derived.static_method_good_order.__override__) + self.assertEqual(Derived.static_method_bad_order(), 42) + self.assertIs(False, hasattr(Derived.static_method_bad_order, "__override__")) + + # Base object is not changed: + self.assertIs(False, hasattr(Base.normal_method, "__override__")) + self.assertIs(False, hasattr(Base.class_method_good_order, "__override__")) + self.assertIs(False, hasattr(Base.class_method_bad_order, "__override__")) + self.assertIs(False, hasattr(Base.static_method_good_order, "__override__")) + self.assertIs(False, hasattr(Base.static_method_bad_order, "__override__")) + + def test_property(self): + class Base: + @property + def correct(self) -> int: + return 1 + @property + def wrong(self) -> int: + return 1 + + class Child(Base): + @property + @override + def correct(self) -> int: + return 2 + @override + @property + def wrong(self) -> int: + return 2 + + instance = Child() + self.assertEqual(instance.correct, 2) + self.assertTrue(Child.correct.fget.__override__) + self.assertEqual(instance.wrong, 2) + self.assertFalse(hasattr(Child.wrong, "__override__")) + self.assertFalse(hasattr(Child.wrong.fset, "__override__")) + + def test_silent_failure(self): + class CustomProp: + __slots__ = ('fget',) + def __init__(self, fget): + self.fget = fget + def __get__(self, obj, objtype=None): + return self.fget(obj) + + class WithOverride: + @override # must not fail on object with `__slots__` + @CustomProp + def some(self): + return 1 + + self.assertEqual(WithOverride.some, 1) + self.assertFalse(hasattr(WithOverride.some, "__override__")) + + def test_multiple_decorators(self): + import functools + + def with_wraps(f): # similar to `lru_cache` definition + @functools.wraps(f) + def wrapper(*args, **kwargs): + return f(*args, **kwargs) + return wrapper + + class WithOverride: + @override + @with_wraps + def on_top(self, a: int) -> int: + return a + 1 + @with_wraps + @override + def on_bottom(self, a: int) -> int: + return a + 2 + + instance = WithOverride() + self.assertEqual(instance.on_top(1), 2) + self.assertTrue(instance.on_top.__override__) + self.assertEqual(instance.on_bottom(1), 3) + self.assertTrue(instance.on_bottom.__override__) + + class CastTests(BaseTestCase): def test_basics(self): @@ -4769,7 +5894,6 @@ class OverloadTests(BaseTestCase): # Definitions needed for features introduced in Python 3.6 from test import ann_module, ann_module2, ann_module3, ann_module5, ann_module6 -import asyncio T_a = TypeVar('T_a') @@ -5273,17 +6397,28 @@ class GetUtilitiesTestCase(TestCase): class C(Generic[T]): pass self.assertEqual(get_args(C[int]), (int,)) self.assertEqual(get_args(C[T]), (T,)) + self.assertEqual(get_args(typing.SupportsAbs[int]), (int,)) # Protocol + self.assertEqual(get_args(typing.SupportsAbs[T]), (T,)) + self.assertEqual(get_args(Point2DGeneric[int]), (int,)) # TypedDict + self.assertEqual(get_args(Point2DGeneric[T]), (T,)) + self.assertEqual(get_args(T), ()) self.assertEqual(get_args(int), ()) + self.assertEqual(get_args(Any), ()) + self.assertEqual(get_args(Self), ()) + self.assertEqual(get_args(LiteralString), ()) self.assertEqual(get_args(ClassVar[int]), (int,)) self.assertEqual(get_args(Union[int, str]), (int, str)) self.assertEqual(get_args(Literal[42, 43]), (42, 43)) self.assertEqual(get_args(Final[List[int]]), (List[int],)) + self.assertEqual(get_args(Optional[int]), (int, type(None))) + self.assertEqual(get_args(Union[int, None]), (int, type(None))) self.assertEqual(get_args(Union[int, Tuple[T, int]][str]), (int, Tuple[str, int])) self.assertEqual(get_args(typing.Dict[int, Tuple[T, T]][Optional[int]]), (int, Tuple[Optional[int], Optional[int]])) self.assertEqual(get_args(Callable[[], T][int]), ([], int)) self.assertEqual(get_args(Callable[..., int]), (..., int)) + self.assertEqual(get_args(Callable[[int], str]), ([int], str)) self.assertEqual(get_args(Union[int, Callable[[Tuple[T, ...]], str]]), (int, Callable[[Tuple[T, ...]], str])) self.assertEqual(get_args(Tuple[int, ...]), (int, ...)) @@ -5300,9 +6435,16 @@ class GetUtilitiesTestCase(TestCase): self.assertEqual(get_args(collections.abc.Callable[[int], str]), get_args(Callable[[int], str])) P = ParamSpec('P') + self.assertEqual(get_args(P), ()) + self.assertEqual(get_args(P.args), ()) + self.assertEqual(get_args(P.kwargs), ()) self.assertEqual(get_args(Callable[P, int]), (P, int)) + self.assertEqual(get_args(collections.abc.Callable[P, int]), (P, int)) self.assertEqual(get_args(Callable[Concatenate[int, P], int]), (Concatenate[int, P], int)) + self.assertEqual(get_args(collections.abc.Callable[Concatenate[int, P], int]), + (Concatenate[int, P], int)) + self.assertEqual(get_args(Concatenate[int, str, P]), (int, str, P)) self.assertEqual(get_args(list | str), (list, str)) self.assertEqual(get_args(Required[int]), (int,)) self.assertEqual(get_args(NotRequired[int]), (int,)) @@ -5421,8 +6563,14 @@ class CollectionsAbcTests(BaseTestCase): self.assertNotIsInstance((), typing.MutableSequence) def test_bytestring(self): - self.assertIsInstance(b'', typing.ByteString) - self.assertIsInstance(bytearray(b''), typing.ByteString) + with self.assertWarns(DeprecationWarning): + self.assertIsInstance(b'', typing.ByteString) + with self.assertWarns(DeprecationWarning): + self.assertIsInstance(bytearray(b''), typing.ByteString) + with self.assertWarns(DeprecationWarning): + class Foo(typing.ByteString): ... + with self.assertWarns(DeprecationWarning): + class Bar(typing.ByteString, typing.Awaitable): ... def test_list(self): self.assertIsSubclass(list, typing.List) @@ -5661,7 +6809,7 @@ class CollectionsAbcTests(BaseTestCase): return 0 self.assertEqual(len(MMC()), 0) - assert callable(MMC.update) + self.assertTrue(callable(MMC.update)) self.assertIsInstance(MMC(), typing.Mapping) class MMB(typing.MutableMapping[KT, VT]): @@ -5856,44 +7004,30 @@ class TypeTests(BaseTestCase): else: return a() - assert isinstance(foo(KeyboardInterrupt), KeyboardInterrupt) - assert foo(None) is None + self.assertIsInstance(foo(KeyboardInterrupt), KeyboardInterrupt) + self.assertIsNone(foo(None)) class TestModules(TestCase): func_names = ['_idfunc'] - def test_py_functions(self): - for fname in self.func_names: - self.assertEqual(getattr(py_typing, fname).__module__, 'typing') - - @skipUnless(c_typing, 'requires _typing') def test_c_functions(self): for fname in self.func_names: - self.assertEqual(getattr(c_typing, fname).__module__, '_typing') + self.assertEqual(getattr(typing, fname).__module__, '_typing') -class NewTypeTests: - def cleanup(self): - for f in self.module._cleanups: - f() - +class NewTypeTests(BaseTestCase): @classmethod def setUpClass(cls): - sys.modules['typing'] = cls.module global UserId - UserId = cls.module.NewType('UserId', int) - cls.UserName = cls.module.NewType(cls.__qualname__ + '.UserName', str) + UserId = typing.NewType('UserId', int) + cls.UserName = typing.NewType(cls.__qualname__ + '.UserName', str) @classmethod def tearDownClass(cls): global UserId del UserId del cls.UserName - sys.modules['typing'] = typing - - def tearDown(self): - self.cleanup() def test_basic(self): self.assertIsInstance(UserId(5), int) @@ -5910,11 +7044,11 @@ class NewTypeTests: def test_or(self): for cls in (int, self.UserName): with self.subTest(cls=cls): - self.assertEqual(UserId | cls, self.module.Union[UserId, cls]) - self.assertEqual(cls | UserId, self.module.Union[cls, UserId]) + self.assertEqual(UserId | cls, typing.Union[UserId, cls]) + self.assertEqual(cls | UserId, typing.Union[cls, UserId]) - self.assertEqual(self.module.get_args(UserId | cls), (UserId, cls)) - self.assertEqual(self.module.get_args(cls | UserId), (cls, UserId)) + self.assertEqual(typing.get_args(UserId | cls), (UserId, cls)) + self.assertEqual(typing.get_args(cls | UserId), (cls, UserId)) def test_special_attrs(self): self.assertEqual(UserId.__name__, 'UserId') @@ -5935,7 +7069,7 @@ class NewTypeTests: f'{__name__}.{self.__class__.__qualname__}.UserName') def test_pickle(self): - UserAge = self.module.NewType('UserAge', float) + UserAge = typing.NewType('UserAge', float) for proto in range(pickle.HIGHEST_PROTOCOL + 1): with self.subTest(proto=proto): pickled = pickle.dumps(UserId, proto) @@ -5967,15 +7101,6 @@ class NewTypeTests: ... -class NewTypePythonTests(NewTypeTests, BaseTestCase): - module = py_typing - - -@skipUnless(c_typing, 'requires _typing') -class NewTypeCTests(NewTypeTests, BaseTestCase): - module = c_typing - - class NamedTupleTests(BaseTestCase): class NestedEmployee(NamedTuple): name: str @@ -6080,9 +7205,12 @@ class NamedTupleTests(BaseTestCase): for G in X, Y: with self.subTest(type=G): self.assertEqual(G.__parameters__, (T,)) + self.assertEqual(G[T].__args__, (T,)) + self.assertEqual(get_args(G[T]), (T,)) A = G[int] self.assertIs(A.__origin__, G) self.assertEqual(A.__args__, (int,)) + self.assertEqual(get_args(A), (int,)) self.assertEqual(A.__parameters__, ()) a = A(3) @@ -6092,6 +7220,19 @@ class NamedTupleTests(BaseTestCase): with self.assertRaises(TypeError): G[int, str] + def test_generic_pep695(self): + class X[T](NamedTuple): + x: T + T, = X.__type_params__ + self.assertIsInstance(T, TypeVar) + self.assertEqual(T.__name__, 'T') + self.assertEqual(X.__bases__, (tuple, Generic)) + self.assertEqual(X.__orig_bases__, (NamedTuple, Generic[T])) + self.assertEqual(X.__mro__, (X, tuple, Generic, object)) + self.assertEqual(X.__parameters__, (T,)) + self.assertEqual(X[str].__args__, (str,)) + self.assertEqual(X[str].__parameters__, ()) + def test_non_generic_subscript(self): # For backward compatibility, subscription works # on arbitrary NamedTuple types. @@ -6172,6 +7313,22 @@ class NamedTupleTests(BaseTestCase): self.assertEqual(jane2, jane) self.assertIsInstance(jane2, cls) + def test_orig_bases(self): + T = TypeVar('T') + + class SimpleNamedTuple(NamedTuple): + pass + + class GenericNamedTuple(NamedTuple, Generic[T]): + pass + + self.assertEqual(SimpleNamedTuple.__orig_bases__, (NamedTuple,)) + self.assertEqual(GenericNamedTuple.__orig_bases__, (NamedTuple, Generic[T])) + + CallNamedTuple = NamedTuple('CallNamedTuple', []) + + self.assertEqual(CallNamedTuple.__orig_bases__, (NamedTuple,)) + class TypedDictTests(BaseTestCase): def test_basics_functional_syntax(self): @@ -6188,6 +7345,10 @@ class TypedDictTests(BaseTestCase): self.assertEqual(Emp.__bases__, (dict,)) self.assertEqual(Emp.__annotations__, {'name': str, 'id': int}) self.assertEqual(Emp.__total__, True) + self.assertEqual(Emp.__required_keys__, {'name', 'id'}) + self.assertIsInstance(Emp.__required_keys__, frozenset) + self.assertEqual(Emp.__optional_keys__, set()) + self.assertIsInstance(Emp.__optional_keys__, frozenset) def test_basics_keywords_syntax(self): with self.assertWarns(DeprecationWarning): @@ -6290,7 +7451,9 @@ class TypedDictTests(BaseTestCase): self.assertEqual(D(x=1), {'x': 1}) self.assertEqual(D.__total__, False) self.assertEqual(D.__required_keys__, frozenset()) + self.assertIsInstance(D.__required_keys__, frozenset) self.assertEqual(D.__optional_keys__, {'x'}) + self.assertIsInstance(D.__optional_keys__, frozenset) self.assertEqual(Options(), {}) self.assertEqual(Options(log_level=2), {'log_level': 2}) @@ -6302,8 +7465,10 @@ class TypedDictTests(BaseTestCase): class Point2Dor3D(Point2D, total=False): z: int - assert Point2Dor3D.__required_keys__ == frozenset(['x', 'y']) - assert Point2Dor3D.__optional_keys__ == frozenset(['z']) + self.assertEqual(Point2Dor3D.__required_keys__, frozenset(['x', 'y'])) + self.assertIsInstance(Point2Dor3D.__required_keys__, frozenset) + self.assertEqual(Point2Dor3D.__optional_keys__, frozenset(['z'])) + self.assertIsInstance(Point2Dor3D.__optional_keys__, frozenset) def test_keys_inheritance(self): class BaseAnimal(TypedDict): @@ -6316,26 +7481,26 @@ class TypedDictTests(BaseTestCase): class Cat(Animal): fur_color: str - assert BaseAnimal.__required_keys__ == frozenset(['name']) - assert BaseAnimal.__optional_keys__ == frozenset([]) - assert BaseAnimal.__annotations__ == {'name': str} + self.assertEqual(BaseAnimal.__required_keys__, frozenset(['name'])) + self.assertEqual(BaseAnimal.__optional_keys__, frozenset([])) + self.assertEqual(BaseAnimal.__annotations__, {'name': str}) - assert Animal.__required_keys__ == frozenset(['name']) - assert Animal.__optional_keys__ == frozenset(['tail', 'voice']) - assert Animal.__annotations__ == { + self.assertEqual(Animal.__required_keys__, frozenset(['name'])) + self.assertEqual(Animal.__optional_keys__, frozenset(['tail', 'voice'])) + self.assertEqual(Animal.__annotations__, { 'name': str, 'tail': bool, 'voice': str, - } + }) - assert Cat.__required_keys__ == frozenset(['name', 'fur_color']) - assert Cat.__optional_keys__ == frozenset(['tail', 'voice']) - assert Cat.__annotations__ == { + self.assertEqual(Cat.__required_keys__, frozenset(['name', 'fur_color'])) + self.assertEqual(Cat.__optional_keys__, frozenset(['tail', 'voice'])) + self.assertEqual(Cat.__annotations__, { 'fur_color': str, 'name': str, 'tail': bool, 'voice': str, - } + }) def test_required_notrequired_keys(self): self.assertEqual(NontotalMovie.__required_keys__, @@ -6461,10 +7626,29 @@ class TypedDictTests(BaseTestCase): pass def test_is_typeddict(self): - assert is_typeddict(Point2D) is True - assert is_typeddict(Union[str, int]) is False + self.assertIs(is_typeddict(Point2D), True) + self.assertIs(is_typeddict(Union[str, int]), False) # classes, not instances - assert is_typeddict(Point2D()) is False + self.assertIs(is_typeddict(Point2D()), False) + call_based = TypedDict('call_based', {'a': int}) + self.assertIs(is_typeddict(call_based), True) + self.assertIs(is_typeddict(call_based()), False) + + T = TypeVar("T") + class BarGeneric(TypedDict, Generic[T]): + a: T + self.assertIs(is_typeddict(BarGeneric), True) + self.assertIs(is_typeddict(BarGeneric[int]), False) + self.assertIs(is_typeddict(BarGeneric()), False) + + class NewGeneric[T](TypedDict): + a: T + self.assertIs(is_typeddict(NewGeneric), True) + self.assertIs(is_typeddict(NewGeneric[int]), False) + self.assertIs(is_typeddict(NewGeneric()), False) + + # The TypedDict constructor is not itself a TypedDict + self.assertIs(is_typeddict(TypedDict), False) def test_get_type_hints(self): self.assertEqual( @@ -6486,6 +7670,20 @@ class TypedDictTests(BaseTestCase): {'a': typing.Optional[T], 'b': int, 'c': str} ) + def test_pep695_generic_typeddict(self): + class A[T](TypedDict): + a: T + + T, = A.__type_params__ + self.assertIsInstance(T, TypeVar) + self.assertEqual(T.__name__, 'T') + self.assertEqual(A.__bases__, (Generic, dict)) + self.assertEqual(A.__orig_bases__, (TypedDict, Generic[T])) + self.assertEqual(A.__mro__, (A, Generic, dict, object)) + self.assertEqual(A.__parameters__, (T,)) + self.assertEqual(A[str].__parameters__, ()) + self.assertEqual(A[str].__args__, (str,)) + def test_generic_inheritance(self): class A(TypedDict, Generic[T]): a: T @@ -6532,11 +7730,11 @@ class TypedDictTests(BaseTestCase): self.assertEqual(C.__total__, True) self.assertEqual(C.__optional_keys__, frozenset(['b'])) self.assertEqual(C.__required_keys__, frozenset(['a', 'c'])) - assert C.__annotations__ == { + self.assertEqual(C.__annotations__, { 'a': T, 'b': KT, 'c': int, - } + }) with self.assertRaises(TypeError): C[str] @@ -6551,11 +7749,11 @@ class TypedDictTests(BaseTestCase): self.assertEqual(Point3D.__total__, True) self.assertEqual(Point3D.__optional_keys__, frozenset()) self.assertEqual(Point3D.__required_keys__, frozenset(['a', 'b', 'c'])) - assert Point3D.__annotations__ == { + self.assertEqual(Point3D.__annotations__, { 'a': T, 'b': T, 'c': KT, - } + }) self.assertEqual(Point3D[int, str].__origin__, Point3D) with self.assertRaises(TypeError): @@ -6582,11 +7780,11 @@ class TypedDictTests(BaseTestCase): self.assertEqual(WithImplicitAny.__total__, True) self.assertEqual(WithImplicitAny.__optional_keys__, frozenset(['b'])) self.assertEqual(WithImplicitAny.__required_keys__, frozenset(['a', 'c'])) - assert WithImplicitAny.__annotations__ == { + self.assertEqual(WithImplicitAny.__annotations__, { 'a': T, 'b': KT, 'c': int, - } + }) with self.assertRaises(TypeError): WithImplicitAny[str] @@ -6603,6 +7801,49 @@ class TypedDictTests(BaseTestCase): self.assertIs(type(a), dict) self.assertEqual(a, {'a': 1}) + def test_orig_bases(self): + T = TypeVar('T') + + class Parent(TypedDict): + pass + + class Child(Parent): + pass + + class OtherChild(Parent): + pass + + class MixedChild(Child, OtherChild, Parent): + pass + + class GenericParent(TypedDict, Generic[T]): + pass + + class GenericChild(GenericParent[int]): + pass + + class OtherGenericChild(GenericParent[str]): + pass + + class MixedGenericChild(GenericChild, OtherGenericChild, GenericParent[float]): + pass + + class MultipleGenericBases(GenericParent[int], GenericParent[float]): + pass + + CallTypedDict = TypedDict('CallTypedDict', {}) + + self.assertEqual(Parent.__orig_bases__, (TypedDict,)) + self.assertEqual(Child.__orig_bases__, (Parent,)) + self.assertEqual(OtherChild.__orig_bases__, (Parent,)) + self.assertEqual(MixedChild.__orig_bases__, (Child, OtherChild, Parent,)) + self.assertEqual(GenericParent.__orig_bases__, (TypedDict, Generic[T])) + self.assertEqual(GenericChild.__orig_bases__, (GenericParent[int],)) + self.assertEqual(OtherGenericChild.__orig_bases__, (GenericParent[str],)) + self.assertEqual(MixedGenericChild.__orig_bases__, (GenericChild, OtherGenericChild, GenericParent[float])) + self.assertEqual(MultipleGenericBases.__orig_bases__, (GenericParent[int], GenericParent[float])) + self.assertEqual(CallTypedDict.__orig_bases__, (TypedDict,)) + class RequiredTests(BaseTestCase): @@ -6622,16 +7863,18 @@ class RequiredTests(BaseTestCase): self.assertEqual(repr(cv), f'typing.Required[{__name__}.Employee]') def test_cannot_subclass(self): - with self.assertRaises(TypeError): + with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): class C(type(Required)): pass - with self.assertRaises(TypeError): + with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): class C(type(Required[int])): pass - with self.assertRaises(TypeError): + with self.assertRaisesRegex(TypeError, + r'Cannot subclass typing\.Required'): class C(Required): pass - with self.assertRaises(TypeError): + with self.assertRaisesRegex(TypeError, + r'Cannot subclass typing\.Required\[int\]'): class C(Required[int]): pass @@ -6668,16 +7911,18 @@ class NotRequiredTests(BaseTestCase): self.assertEqual(repr(cv), f'typing.NotRequired[{__name__}.Employee]') def test_cannot_subclass(self): - with self.assertRaises(TypeError): + with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): class C(type(NotRequired)): pass - with self.assertRaises(TypeError): + with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): class C(type(NotRequired[int])): pass - with self.assertRaises(TypeError): + with self.assertRaisesRegex(TypeError, + r'Cannot subclass typing\.NotRequired'): class C(NotRequired): pass - with self.assertRaises(TypeError): + with self.assertRaisesRegex(TypeError, + r'Cannot subclass typing\.NotRequired\[int\]'): class C(NotRequired[int]): pass @@ -6788,13 +8033,18 @@ class RETests(BaseTestCase): self.assertEqual(len(w), 1) def test_cannot_subclass(self): - with self.assertRaises(TypeError) as ex: - + with self.assertRaisesRegex( + TypeError, + r"type 're\.Match' is not an acceptable base type", + ): class A(typing.Match): pass - - self.assertEqual(str(ex.exception), - "type 're.Match' is not an acceptable base type") + with self.assertRaisesRegex( + TypeError, + r"type 're\.Pattern' is not an acceptable base type", + ): + class A(typing.Pattern): + pass class AnnotatedTests(BaseTestCase): @@ -6816,6 +8066,15 @@ class AnnotatedTests(BaseTestCase): "typing.Annotated[typing.List[int], 4, 5]" ) + def test_dir(self): + dir_items = set(dir(Annotated[int, 4])) + for required_item in [ + '__args__', '__parameters__', '__origin__', + '__metadata__', + ]: + with self.subTest(required_item=required_item): + self.assertIn(required_item, dir_items) + def test_flatten(self): A = Annotated[Annotated[int, 4], 5] self.assertEqual(A, Annotated[int, 4, 5]) @@ -6898,16 +8157,6 @@ class AnnotatedTests(BaseTestCase): self.assertEqual(get_type_hints(C, globals())['classvar'], ClassVar[int]) self.assertEqual(get_type_hints(C, globals())['const'], Final[int]) - def test_hash_eq(self): - self.assertEqual(len({Annotated[int, 4, 5], Annotated[int, 4, 5]}), 1) - self.assertNotEqual(Annotated[int, 4, 5], Annotated[int, 5, 4]) - self.assertNotEqual(Annotated[int, 4, 5], Annotated[str, 4, 5]) - self.assertNotEqual(Annotated[int, 4], Annotated[int, 4, 4]) - self.assertEqual( - {Annotated[int, 4, 5], Annotated[int, 4, 5], Annotated[T, 4, 5]}, - {Annotated[int, 4, 5], Annotated[T, 4, 5]} - ) - def test_cannot_subclass(self): with self.assertRaisesRegex(TypeError, "Cannot subclass .*Annotated"): class C(Annotated): @@ -7136,7 +8385,8 @@ class TypeAliasTests(BaseTestCase): issubclass(TypeAlias, Employee) def test_cannot_subclass(self): - with self.assertRaises(TypeError): + with self.assertRaisesRegex(TypeError, + r'Cannot subclass typing\.TypeAlias'): class C(TypeAlias): pass @@ -7158,6 +8408,16 @@ class ParamSpecTests(BaseTestCase): P = ParamSpec('P') self.assertEqual(P, P) self.assertIsInstance(P, ParamSpec) + self.assertEqual(P.__name__, 'P') + self.assertEqual(P.__module__, __name__) + + def test_basic_with_exec(self): + ns = {} + exec('from typing import ParamSpec; P = ParamSpec("P")', ns, ns) + P = ns['P'] + self.assertIsInstance(P, ParamSpec) + self.assertEqual(P.__name__, 'P') + self.assertIs(P.__module__, None) def test_valid_uses(self): P = ParamSpec('P') @@ -7335,7 +8595,6 @@ class ParamSpecTests(BaseTestCase): self.assertEqual(B.__args__, ((int, str,), Tuple[bytes, float])) def test_var_substitution(self): - T = TypeVar("T") P = ParamSpec("P") subst = P.__typing_subst__ self.assertEqual(subst((int, str)), (int, str)) @@ -7358,6 +8617,127 @@ class ParamSpecTests(BaseTestCase): with self.assertRaises(TypeError): collections.abc.Callable[P, T][arg, str] + def test_type_var_subst_for_other_type_vars(self): + T = TypeVar('T') + T2 = TypeVar('T2') + P = ParamSpec('P') + P2 = ParamSpec('P2') + Ts = TypeVarTuple('Ts') + + class Base(Generic[P]): + pass + + A1 = Base[T] + self.assertEqual(A1.__parameters__, (T,)) + self.assertEqual(A1.__args__, ((T,),)) + self.assertEqual(A1[int], Base[int]) + + A2 = Base[[T]] + self.assertEqual(A2.__parameters__, (T,)) + self.assertEqual(A2.__args__, ((T,),)) + self.assertEqual(A2[int], Base[int]) + + A3 = Base[[int, T]] + self.assertEqual(A3.__parameters__, (T,)) + self.assertEqual(A3.__args__, ((int, T),)) + self.assertEqual(A3[str], Base[[int, str]]) + + A4 = Base[[T, int, T2]] + self.assertEqual(A4.__parameters__, (T, T2)) + self.assertEqual(A4.__args__, ((T, int, T2),)) + self.assertEqual(A4[str, bool], Base[[str, int, bool]]) + + A5 = Base[[*Ts, int]] + self.assertEqual(A5.__parameters__, (Ts,)) + self.assertEqual(A5.__args__, ((*Ts, int),)) + self.assertEqual(A5[str, bool], Base[[str, bool, int]]) + + A5_2 = Base[[int, *Ts]] + self.assertEqual(A5_2.__parameters__, (Ts,)) + self.assertEqual(A5_2.__args__, ((int, *Ts),)) + self.assertEqual(A5_2[str, bool], Base[[int, str, bool]]) + + A6 = Base[[T, *Ts]] + self.assertEqual(A6.__parameters__, (T, Ts)) + self.assertEqual(A6.__args__, ((T, *Ts),)) + self.assertEqual(A6[int, str, bool], Base[[int, str, bool]]) + + A7 = Base[[T, T]] + self.assertEqual(A7.__parameters__, (T,)) + self.assertEqual(A7.__args__, ((T, T),)) + self.assertEqual(A7[int], Base[[int, int]]) + + A8 = Base[[T, list[T]]] + self.assertEqual(A8.__parameters__, (T,)) + self.assertEqual(A8.__args__, ((T, list[T]),)) + self.assertEqual(A8[int], Base[[int, list[int]]]) + + A9 = Base[[Tuple[*Ts], *Ts]] + self.assertEqual(A9.__parameters__, (Ts,)) + self.assertEqual(A9.__args__, ((Tuple[*Ts], *Ts),)) + self.assertEqual(A9[int, str], Base[Tuple[int, str], int, str]) + + A10 = Base[P2] + self.assertEqual(A10.__parameters__, (P2,)) + self.assertEqual(A10.__args__, (P2,)) + self.assertEqual(A10[[int, str]], Base[[int, str]]) + + class DoubleP(Generic[P, P2]): + pass + + B1 = DoubleP[P, P2] + self.assertEqual(B1.__parameters__, (P, P2)) + self.assertEqual(B1.__args__, (P, P2)) + self.assertEqual(B1[[int, str], [bool]], DoubleP[[int, str], [bool]]) + self.assertEqual(B1[[], []], DoubleP[[], []]) + + B2 = DoubleP[[int, str], P2] + self.assertEqual(B2.__parameters__, (P2,)) + self.assertEqual(B2.__args__, ((int, str), P2)) + self.assertEqual(B2[[bool, bool]], DoubleP[[int, str], [bool, bool]]) + self.assertEqual(B2[[]], DoubleP[[int, str], []]) + + B3 = DoubleP[P, [bool, bool]] + self.assertEqual(B3.__parameters__, (P,)) + self.assertEqual(B3.__args__, (P, (bool, bool))) + self.assertEqual(B3[[int, str]], DoubleP[[int, str], [bool, bool]]) + self.assertEqual(B3[[]], DoubleP[[], [bool, bool]]) + + B4 = DoubleP[[T, int], [bool, T2]] + self.assertEqual(B4.__parameters__, (T, T2)) + self.assertEqual(B4.__args__, ((T, int), (bool, T2))) + self.assertEqual(B4[str, float], DoubleP[[str, int], [bool, float]]) + + B5 = DoubleP[[*Ts, int], [bool, T2]] + self.assertEqual(B5.__parameters__, (Ts, T2)) + self.assertEqual(B5.__args__, ((*Ts, int), (bool, T2))) + self.assertEqual(B5[str, bytes, float], + DoubleP[[str, bytes, int], [bool, float]]) + + B6 = DoubleP[[T, int], [bool, *Ts]] + self.assertEqual(B6.__parameters__, (T, Ts)) + self.assertEqual(B6.__args__, ((T, int), (bool, *Ts))) + self.assertEqual(B6[str, bytes, float], + DoubleP[[str, int], [bool, bytes, float]]) + + class PandT(Generic[P, T]): + pass + + C1 = PandT[P, T] + self.assertEqual(C1.__parameters__, (P, T)) + self.assertEqual(C1.__args__, (P, T)) + self.assertEqual(C1[[int, str], bool], PandT[[int, str], bool]) + + C2 = PandT[[int, T], T] + self.assertEqual(C2.__parameters__, (T,)) + self.assertEqual(C2.__args__, ((int, T), T)) + self.assertEqual(C2[str], PandT[[int, str], str]) + + C3 = PandT[[int, *Ts], T] + self.assertEqual(C3.__parameters__, (Ts, T)) + self.assertEqual(C3.__args__, ((int, *Ts), T)) + self.assertEqual(C3[str, bool, bytes], PandT[[int, str, bool], bytes]) + def test_paramspec_in_nested_generics(self): # Although ParamSpec should not be found in __parameters__ of most # generics, they probably should be found when nested in @@ -7397,6 +8777,24 @@ class ParamSpecTests(BaseTestCase): self.assertEqual(C2[Concatenate[str, P2]].__parameters__, (P2,)) self.assertEqual(C2[Concatenate[T, P2]].__parameters__, (T, P2)) + def test_cannot_subclass(self): + with self.assertRaisesRegex(TypeError, NOT_A_BASE_TYPE % 'ParamSpec'): + class C(ParamSpec): pass + with self.assertRaisesRegex(TypeError, NOT_A_BASE_TYPE % 'ParamSpecArgs'): + class C(ParamSpecArgs): pass + with self.assertRaisesRegex(TypeError, NOT_A_BASE_TYPE % 'ParamSpecKwargs'): + class C(ParamSpecKwargs): pass + P = ParamSpec('P') + with self.assertRaisesRegex(TypeError, + CANNOT_SUBCLASS_INSTANCE % 'ParamSpec'): + class C(P): pass + with self.assertRaisesRegex(TypeError, + CANNOT_SUBCLASS_INSTANCE % 'ParamSpecArgs'): + class C(P.args): pass + with self.assertRaisesRegex(TypeError, + CANNOT_SUBCLASS_INSTANCE % 'ParamSpecKwargs'): + class C(P.kwargs): pass + class ConcatenateTests(BaseTestCase): def test_basics(self): @@ -7405,6 +8803,15 @@ class ConcatenateTests(BaseTestCase): c = Concatenate[MyClass, P] self.assertNotEqual(c, Concatenate) + def test_dir(self): + P = ParamSpec('P') + dir_items = set(dir(Concatenate[int, P])) + for required_item in [ + '__args__', '__parameters__', '__origin__', + ]: + with self.subTest(required_item=required_item): + self.assertIn(required_item, dir_items) + def test_valid_uses(self): P = ParamSpec('P') T = TypeVar('T') @@ -7463,12 +8870,20 @@ class TypeGuardTests(BaseTestCase): self.assertEqual(repr(cv), 'typing.TypeGuard[tuple[int]]') def test_cannot_subclass(self): - with self.assertRaises(TypeError): + with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): class C(type(TypeGuard)): pass - with self.assertRaises(TypeError): + with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE): class C(type(TypeGuard[int])): pass + with self.assertRaisesRegex(TypeError, + r'Cannot subclass typing\.TypeGuard'): + class C(TypeGuard): + pass + with self.assertRaisesRegex(TypeError, + r'Cannot subclass typing\.TypeGuard\[int\]'): + class C(TypeGuard[int]): + pass def test_cannot_init(self): with self.assertRaises(TypeError): @@ -7589,6 +9004,7 @@ class SpecialAttrsTests(BaseTestCase): typing.Self: 'Self', # Subscribed special forms typing.Annotated[Any, "Annotation"]: 'Annotated', + typing.Annotated[int, 'Annotation']: 'Annotated', typing.ClassVar[Any]: 'ClassVar', typing.Concatenate[Any, SpecialAttrsP]: 'Concatenate', typing.Final[Any]: 'Final', @@ -7628,7 +9044,7 @@ class SpecialAttrsTests(BaseTestCase): self.assertEqual(fr.__module__, 'typing') # Forward refs are currently unpicklable. for proto in range(pickle.HIGHEST_PROTOCOL + 1): - with self.assertRaises(TypeError) as exc: + with self.assertRaises(TypeError): pickle.dumps(fr, proto) self.assertEqual(SpecialAttrsTests.TypeName.__name__, 'TypeName') @@ -7673,10 +9089,18 @@ class SpecialAttrsTests(BaseTestCase): def bar(self): pass baz = 3 + __magic__ = 4 + # The class attributes of the original class should be visible even # in dir() of the GenericAlias. See bpo-45755. - self.assertIn('bar', dir(Foo[int])) - self.assertIn('baz', dir(Foo[int])) + dir_items = set(dir(Foo[int])) + for required_item in [ + 'bar', 'baz', + '__args__', '__parameters__', '__origin__', + ]: + with self.subTest(required_item=required_item): + self.assertIn(required_item, dir_items) + self.assertNotIn('__magic__', dir_items) class RevealTypeTests(BaseTestCase): @@ -7704,6 +9128,7 @@ class DataclassTransformTests(BaseTestCase): "eq_default": True, "order_default": False, "kw_only_default": True, + "frozen_default": False, "field_specifiers": (), "kwargs": {}, } @@ -7734,6 +9159,7 @@ class DataclassTransformTests(BaseTestCase): "eq_default": True, "order_default": True, "kw_only_default": False, + "frozen_default": False, "field_specifiers": (), "kwargs": {"make_everything_awesome": True}, } @@ -7750,7 +9176,7 @@ class DataclassTransformTests(BaseTestCase): return super().__new__(cls, name, bases, namespace) Decorated = dataclass_transform( - order_default=True, field_specifiers=(Field,) + order_default=True, frozen_default=True, field_specifiers=(Field,) )(ModelMeta) class ModelBase(metaclass=Decorated): ... @@ -7765,6 +9191,7 @@ class DataclassTransformTests(BaseTestCase): "eq_default": True, "order_default": True, "kw_only_default": False, + "frozen_default": True, "field_specifiers": (Field,), "kwargs": {}, } diff --git a/Lib/test/test_unary.py b/Lib/test/test_unary.py index c3c17cc9..a45fbf6b 100644 --- a/Lib/test/test_unary.py +++ b/Lib/test/test_unary.py @@ -8,7 +8,6 @@ class UnaryOpTestCase(unittest.TestCase): self.assertTrue(-2 == 0 - 2) self.assertEqual(-0, 0) self.assertEqual(--2, 2) - self.assertTrue(-2 == 0 - 2) self.assertTrue(-2.0 == 0 - 2.0) self.assertTrue(-2j == 0 - 2j) @@ -16,15 +15,13 @@ class UnaryOpTestCase(unittest.TestCase): self.assertEqual(+2, 2) self.assertEqual(+0, 0) self.assertEqual(++2, 2) - self.assertEqual(+2, 2) self.assertEqual(+2.0, 2.0) self.assertEqual(+2j, 2j) def test_invert(self): - self.assertTrue(-2 == 0 - 2) - self.assertEqual(-0, 0) - self.assertEqual(--2, 2) - self.assertTrue(-2 == 0 - 2) + self.assertTrue(~2 == -(2+1)) + self.assertEqual(~0, -1) + self.assertEqual(~~2, 2) def test_no_overflow(self): nines = "9" * 32 diff --git a/Lib/test/test_unicode.py b/Lib/test/test_unicode.py index c265438a..2fd66c93 100644 --- a/Lib/test/test_unicode.py +++ b/Lib/test/test_unicode.py @@ -94,88 +94,85 @@ class UnicodeTest(string_tests.CommonTest, self.assertNotEqual(r"\u0020", " ") def test_ascii(self): - if not sys.platform.startswith('java'): - # Test basic sanity of repr() - self.assertEqual(ascii('abc'), "'abc'") - self.assertEqual(ascii('ab\\c'), "'ab\\\\c'") - self.assertEqual(ascii('ab\\'), "'ab\\\\'") - self.assertEqual(ascii('\\c'), "'\\\\c'") - self.assertEqual(ascii('\\'), "'\\\\'") - self.assertEqual(ascii('\n'), "'\\n'") - self.assertEqual(ascii('\r'), "'\\r'") - self.assertEqual(ascii('\t'), "'\\t'") - self.assertEqual(ascii('\b'), "'\\x08'") - self.assertEqual(ascii("'\""), """'\\'"'""") - self.assertEqual(ascii("'\""), """'\\'"'""") - self.assertEqual(ascii("'"), '''"'"''') - self.assertEqual(ascii('"'), """'"'""") - latin1repr = ( - "'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r" - "\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a" - "\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123456789:;<=>?@ABCDEFGHI" - "JKLMNOPQRSTUVWXYZ[\\\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\\x7f" - "\\x80\\x81\\x82\\x83\\x84\\x85\\x86\\x87\\x88\\x89\\x8a\\x8b\\x8c\\x8d" - "\\x8e\\x8f\\x90\\x91\\x92\\x93\\x94\\x95\\x96\\x97\\x98\\x99\\x9a\\x9b" - "\\x9c\\x9d\\x9e\\x9f\\xa0\\xa1\\xa2\\xa3\\xa4\\xa5\\xa6\\xa7\\xa8\\xa9" - "\\xaa\\xab\\xac\\xad\\xae\\xaf\\xb0\\xb1\\xb2\\xb3\\xb4\\xb5\\xb6\\xb7" - "\\xb8\\xb9\\xba\\xbb\\xbc\\xbd\\xbe\\xbf\\xc0\\xc1\\xc2\\xc3\\xc4\\xc5" - "\\xc6\\xc7\\xc8\\xc9\\xca\\xcb\\xcc\\xcd\\xce\\xcf\\xd0\\xd1\\xd2\\xd3" - "\\xd4\\xd5\\xd6\\xd7\\xd8\\xd9\\xda\\xdb\\xdc\\xdd\\xde\\xdf\\xe0\\xe1" - "\\xe2\\xe3\\xe4\\xe5\\xe6\\xe7\\xe8\\xe9\\xea\\xeb\\xec\\xed\\xee\\xef" - "\\xf0\\xf1\\xf2\\xf3\\xf4\\xf5\\xf6\\xf7\\xf8\\xf9\\xfa\\xfb\\xfc\\xfd" - "\\xfe\\xff'") - testrepr = ascii(''.join(map(chr, range(256)))) - self.assertEqual(testrepr, latin1repr) - # Test ascii works on wide unicode escapes without overflow. - self.assertEqual(ascii("\U00010000" * 39 + "\uffff" * 4096), - ascii("\U00010000" * 39 + "\uffff" * 4096)) - - class WrongRepr: - def __repr__(self): - return b'byte-repr' - self.assertRaises(TypeError, ascii, WrongRepr()) + self.assertEqual(ascii('abc'), "'abc'") + self.assertEqual(ascii('ab\\c'), "'ab\\\\c'") + self.assertEqual(ascii('ab\\'), "'ab\\\\'") + self.assertEqual(ascii('\\c'), "'\\\\c'") + self.assertEqual(ascii('\\'), "'\\\\'") + self.assertEqual(ascii('\n'), "'\\n'") + self.assertEqual(ascii('\r'), "'\\r'") + self.assertEqual(ascii('\t'), "'\\t'") + self.assertEqual(ascii('\b'), "'\\x08'") + self.assertEqual(ascii("'\""), """'\\'"'""") + self.assertEqual(ascii("'\""), """'\\'"'""") + self.assertEqual(ascii("'"), '''"'"''') + self.assertEqual(ascii('"'), """'"'""") + latin1repr = ( + "'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r" + "\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a" + "\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123456789:;<=>?@ABCDEFGHI" + "JKLMNOPQRSTUVWXYZ[\\\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\\x7f" + "\\x80\\x81\\x82\\x83\\x84\\x85\\x86\\x87\\x88\\x89\\x8a\\x8b\\x8c\\x8d" + "\\x8e\\x8f\\x90\\x91\\x92\\x93\\x94\\x95\\x96\\x97\\x98\\x99\\x9a\\x9b" + "\\x9c\\x9d\\x9e\\x9f\\xa0\\xa1\\xa2\\xa3\\xa4\\xa5\\xa6\\xa7\\xa8\\xa9" + "\\xaa\\xab\\xac\\xad\\xae\\xaf\\xb0\\xb1\\xb2\\xb3\\xb4\\xb5\\xb6\\xb7" + "\\xb8\\xb9\\xba\\xbb\\xbc\\xbd\\xbe\\xbf\\xc0\\xc1\\xc2\\xc3\\xc4\\xc5" + "\\xc6\\xc7\\xc8\\xc9\\xca\\xcb\\xcc\\xcd\\xce\\xcf\\xd0\\xd1\\xd2\\xd3" + "\\xd4\\xd5\\xd6\\xd7\\xd8\\xd9\\xda\\xdb\\xdc\\xdd\\xde\\xdf\\xe0\\xe1" + "\\xe2\\xe3\\xe4\\xe5\\xe6\\xe7\\xe8\\xe9\\xea\\xeb\\xec\\xed\\xee\\xef" + "\\xf0\\xf1\\xf2\\xf3\\xf4\\xf5\\xf6\\xf7\\xf8\\xf9\\xfa\\xfb\\xfc\\xfd" + "\\xfe\\xff'") + testrepr = ascii(''.join(map(chr, range(256)))) + self.assertEqual(testrepr, latin1repr) + # Test ascii works on wide unicode escapes without overflow. + self.assertEqual(ascii("\U00010000" * 39 + "\uffff" * 4096), + ascii("\U00010000" * 39 + "\uffff" * 4096)) + + class WrongRepr: + def __repr__(self): + return b'byte-repr' + self.assertRaises(TypeError, ascii, WrongRepr()) def test_repr(self): - if not sys.platform.startswith('java'): - # Test basic sanity of repr() - self.assertEqual(repr('abc'), "'abc'") - self.assertEqual(repr('ab\\c'), "'ab\\\\c'") - self.assertEqual(repr('ab\\'), "'ab\\\\'") - self.assertEqual(repr('\\c'), "'\\\\c'") - self.assertEqual(repr('\\'), "'\\\\'") - self.assertEqual(repr('\n'), "'\\n'") - self.assertEqual(repr('\r'), "'\\r'") - self.assertEqual(repr('\t'), "'\\t'") - self.assertEqual(repr('\b'), "'\\x08'") - self.assertEqual(repr("'\""), """'\\'"'""") - self.assertEqual(repr("'\""), """'\\'"'""") - self.assertEqual(repr("'"), '''"'"''') - self.assertEqual(repr('"'), """'"'""") - latin1repr = ( - "'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r" - "\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a" - "\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123456789:;<=>?@ABCDEFGHI" - "JKLMNOPQRSTUVWXYZ[\\\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\\x7f" - "\\x80\\x81\\x82\\x83\\x84\\x85\\x86\\x87\\x88\\x89\\x8a\\x8b\\x8c\\x8d" - "\\x8e\\x8f\\x90\\x91\\x92\\x93\\x94\\x95\\x96\\x97\\x98\\x99\\x9a\\x9b" - "\\x9c\\x9d\\x9e\\x9f\\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9" - "\xaa\xab\xac\\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7" - "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5" - "\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3" - "\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1" - "\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef" - "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd" - "\xfe\xff'") - testrepr = repr(''.join(map(chr, range(256)))) - self.assertEqual(testrepr, latin1repr) - # Test repr works on wide unicode escapes without overflow. - self.assertEqual(repr("\U00010000" * 39 + "\uffff" * 4096), - repr("\U00010000" * 39 + "\uffff" * 4096)) - - class WrongRepr: - def __repr__(self): - return b'byte-repr' - self.assertRaises(TypeError, repr, WrongRepr()) + # Test basic sanity of repr() + self.assertEqual(repr('abc'), "'abc'") + self.assertEqual(repr('ab\\c'), "'ab\\\\c'") + self.assertEqual(repr('ab\\'), "'ab\\\\'") + self.assertEqual(repr('\\c'), "'\\\\c'") + self.assertEqual(repr('\\'), "'\\\\'") + self.assertEqual(repr('\n'), "'\\n'") + self.assertEqual(repr('\r'), "'\\r'") + self.assertEqual(repr('\t'), "'\\t'") + self.assertEqual(repr('\b'), "'\\x08'") + self.assertEqual(repr("'\""), """'\\'"'""") + self.assertEqual(repr("'\""), """'\\'"'""") + self.assertEqual(repr("'"), '''"'"''') + self.assertEqual(repr('"'), """'"'""") + latin1repr = ( + "'\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\n\\x0b\\x0c\\r" + "\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a" + "\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./0123456789:;<=>?@ABCDEFGHI" + "JKLMNOPQRSTUVWXYZ[\\\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\\x7f" + "\\x80\\x81\\x82\\x83\\x84\\x85\\x86\\x87\\x88\\x89\\x8a\\x8b\\x8c\\x8d" + "\\x8e\\x8f\\x90\\x91\\x92\\x93\\x94\\x95\\x96\\x97\\x98\\x99\\x9a\\x9b" + "\\x9c\\x9d\\x9e\\x9f\\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9" + "\xaa\xab\xac\\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7" + "\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5" + "\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3" + "\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1" + "\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef" + "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd" + "\xfe\xff'") + testrepr = repr(''.join(map(chr, range(256)))) + self.assertEqual(testrepr, latin1repr) + # Test repr works on wide unicode escapes without overflow. + self.assertEqual(repr("\U00010000" * 39 + "\uffff" * 4096), + repr("\U00010000" * 39 + "\uffff" * 4096)) + + class WrongRepr: + def __repr__(self): + return b'byte-repr' + self.assertRaises(TypeError, repr, WrongRepr()) def test_iterators(self): # Make sure unicode objects have an __iter__ method @@ -240,6 +237,10 @@ class UnicodeTest(string_tests.CommonTest, self.checkequal(0, 'a' * 10, 'count', 'a\u0102') self.checkequal(0, 'a' * 10, 'count', 'a\U00100304') self.checkequal(0, '\u0102' * 10, 'count', '\u0102\U00100304') + # test subclass + class MyStr(str): + pass + self.checkequal(3, MyStr('aaa'), 'count', 'a') def test_find(self): string_tests.CommonTest.test_find(self) @@ -680,8 +681,7 @@ class UnicodeTest(string_tests.CommonTest, def test_isupper(self): super().test_isupper() - if not sys.platform.startswith('java'): - self.checkequalnofix(False, '\u1FFc', 'isupper') + self.checkequalnofix(False, '\u1FFc', 'isupper') self.assertTrue('\u2167'.isupper()) self.assertFalse('\u2177'.isupper()) # non-BMP, uppercase @@ -814,7 +814,7 @@ class UnicodeTest(string_tests.CommonTest, self.assertFalse("0".isidentifier()) @support.cpython_only - @support.requires_legacy_unicode_capi + @support.requires_legacy_unicode_capi() @unittest.skipIf(_testcapi is None, 'need _testcapi module') def test_isidentifier_legacy(self): u = '𝖀𝖓𝖎𝖈𝖔𝖉𝖊' @@ -1483,10 +1483,9 @@ class UnicodeTest(string_tests.CommonTest, self.assertEqual("%s, %s, %i, %f, %5.2f" % ("abc", "abc", -1, -2, 3.5), 'abc, abc, -1, -2.000000, 3.50') self.assertEqual("%s, %s, %i, %f, %5.2f" % ("abc", "abc", -1, -2, 3.57), 'abc, abc, -1, -2.000000, 3.57') self.assertEqual("%s, %s, %i, %f, %5.2f" % ("abc", "abc", -1, -2, 1003.57), 'abc, abc, -1, -2.000000, 1003.57') - if not sys.platform.startswith('java'): - self.assertEqual("%r, %r" % (b"abc", "abc"), "b'abc', 'abc'") - self.assertEqual("%r" % ("\u1234",), "'\u1234'") - self.assertEqual("%a" % ("\u1234",), "'\\u1234'") + self.assertEqual("%r, %r" % (b"abc", "abc"), "b'abc', 'abc'") + self.assertEqual("%r" % ("\u1234",), "'\u1234'") + self.assertEqual("%a" % ("\u1234",), "'\\u1234'") self.assertEqual("%(x)s, %(y)s" % {'x':"abc", 'y':"def"}, 'abc, def') self.assertEqual("%(x)s, %(\xfc)s" % {'x':"abc", '\xfc':"def"}, 'abc, def') @@ -1701,29 +1700,27 @@ class UnicodeTest(string_tests.CommonTest, # unicode(obj, encoding, error) tests (this maps to # PyUnicode_FromEncodedObject() at C level) - if not sys.platform.startswith('java'): - self.assertRaises( - TypeError, - str, - 'decoding unicode is not supported', - 'utf-8', - 'strict' - ) + self.assertRaises( + TypeError, + str, + 'decoding unicode is not supported', + 'utf-8', + 'strict' + ) self.assertEqual( str(b'strings are decoded to unicode', 'utf-8', 'strict'), 'strings are decoded to unicode' ) - if not sys.platform.startswith('java'): - self.assertEqual( - str( - memoryview(b'character buffers are decoded to unicode'), - 'utf-8', - 'strict' - ), - 'character buffers are decoded to unicode' - ) + self.assertEqual( + str( + memoryview(b'character buffers are decoded to unicode'), + 'utf-8', + 'strict' + ), + 'character buffers are decoded to unicode' + ) self.assertRaises(TypeError, str, 42, 42, 42) @@ -2409,12 +2406,7 @@ class UnicodeTest(string_tests.CommonTest, def __repr__(self): return '\\n' - class s2: - def __repr__(self): - return '\\n' - self.assertEqual(repr(s1()), '\\n') - self.assertEqual(repr(s2()), '\\n') def test_printable_repr(self): self.assertEqual(repr('\U00010000'), "'%c'" % (0x10000,)) # printable @@ -2434,8 +2426,8 @@ class UnicodeTest(string_tests.CommonTest, self.assertIs(s.expandtabs(), s) def test_raiseMemError(self): - asciifields = "nnbP" - compactfields = asciifields + "nPn" + asciifields = "nnb" + compactfields = asciifields + "nP" ascii_struct_size = support.calcobjsize(asciifields) compact_struct_size = support.calcobjsize(compactfields) @@ -2499,7 +2491,7 @@ class UnicodeTest(string_tests.CommonTest, self.assertEqual(len(args), 1) @support.cpython_only - @support.requires_legacy_unicode_capi + @support.requires_legacy_unicode_capi() @unittest.skipIf(_testcapi is None, 'need _testcapi module') def test_resize(self): for length in range(1, 100, 7): diff --git a/Lib/test/test_unicodedata.py b/Lib/test/test_unicodedata.py index 9e0097c8..515c3840 100644 --- a/Lib/test/test_unicodedata.py +++ b/Lib/test/test_unicodedata.py @@ -12,14 +12,13 @@ import sys import unicodedata import unittest from test.support import (open_urlresource, requires_resource, script_helper, - cpython_only, check_disallow_instantiation, - ResourceDenied) + cpython_only, check_disallow_instantiation) class UnicodeMethodsTest(unittest.TestCase): # update this, if the database changes - expectedchecksum = '4739770dd4d0e5f1b1677accfc3552ed3c8ef326' + expectedchecksum = 'e708c31c0d51f758adf475cb7201cf80917362be' @requires_resource('cpu') def test_method_checksum(self): @@ -72,7 +71,7 @@ class UnicodeFunctionsTest(UnicodeDatabaseTest): # Update this if the database changes. Make sure to do a full rebuild # (e.g. 'make distclean && make') to get the correct checksum. - expectedchecksum = '98d602e1f69d5c5bb8a5910c40bbbad4e18e8370' + expectedchecksum = '26ff0d31c14194b4606a5b3a81ac36df3a14e331' @requires_resource('cpu') def test_function_checksum(self): @@ -91,6 +90,8 @@ class UnicodeFunctionsTest(UnicodeDatabaseTest): self.db.decomposition(char), str(self.db.mirrored(char)), str(self.db.combining(char)), + unicodedata.east_asian_width(char), + self.db.name(char, ""), ] h.update(''.join(data).encode("ascii")) result = h.hexdigest() @@ -228,6 +229,23 @@ class UnicodeFunctionsTest(UnicodeDatabaseTest): self.assertEqual(eaw('\u2010'), 'A') self.assertEqual(eaw('\U00020000'), 'W') + def test_east_asian_width_unassigned(self): + eaw = self.db.east_asian_width + # unassigned + for char in '\u0530\u0ecf\u10c6\u20fc\uaaca\U000107bd\U000115f2': + self.assertEqual(eaw(char), 'N') + self.assertIs(self.db.name(char, None), None) + + # unassigned but reserved for CJK + for char in '\uFA6E\uFADA\U0002A6E0\U0002FA20\U0003134B\U0003FFFD': + self.assertEqual(eaw(char), 'W') + self.assertIs(self.db.name(char, None), None) + + # private use areas + for char in '\uE000\uF800\U000F0000\U000FFFEE\U00100000\U0010FFF0': + self.assertEqual(eaw(char), 'A') + self.assertIs(self.db.name(char, None), None) + def test_east_asian_width_9_0_changes(self): self.assertEqual(self.db.ucd_3_2_0.east_asian_width('\u231a'), 'N') self.assertEqual(self.db.east_asian_width('\u231a'), 'W') @@ -295,6 +313,7 @@ class UnicodeMiscTest(UnicodeDatabaseTest): self.assertTrue("\u1d79".upper()=='\ua77d') self.assertTrue(".".upper()=='.') + @requires_resource('cpu') def test_bug_5828(self): self.assertEqual("\u1d79".lower(), "\u1d79") # Only U+0000 should have U+0000 as its upper/lower/titlecase variant @@ -335,6 +354,7 @@ class NormalizationTest(unittest.TestCase): return "".join([chr(x) for x in data]) @requires_resource('network') + @requires_resource('cpu') def test_normalization(self): TESTDATAFILE = "NormalizationTest.txt" TESTDATAURL = f"http://www.pythontest.net/unicode/{unicodedata.unidata_version}/{TESTDATAFILE}" diff --git a/Lib/test/test_unittest.py b/Lib/test/test_unittest.py deleted file mode 100644 index 1079c7df..00000000 --- a/Lib/test/test_unittest.py +++ /dev/null @@ -1,16 +0,0 @@ -import unittest.test - -from test import support - - -def load_tests(*_): - # used by unittest - return unittest.test.suite() - - -def tearDownModule(): - support.reap_children() - - -if __name__ == "__main__": - unittest.main() diff --git a/Lib/test/test_unittest/__init__.py b/Lib/test/test_unittest/__init__.py new file mode 100644 index 00000000..bc502ef3 --- /dev/null +++ b/Lib/test/test_unittest/__init__.py @@ -0,0 +1,6 @@ +import os.path +from test.support import load_package_tests + + +def load_tests(*args): + return load_package_tests(os.path.dirname(__file__), *args) diff --git a/Lib/test/test_unittest/__main__.py b/Lib/test/test_unittest/__main__.py new file mode 100644 index 00000000..40a23a29 --- /dev/null +++ b/Lib/test/test_unittest/__main__.py @@ -0,0 +1,4 @@ +from . import load_tests +import unittest + +unittest.main() diff --git a/Lib/unittest/test/_test_warnings.py b/Lib/test/test_unittest/_test_warnings.py similarity index 84% rename from Lib/unittest/test/_test_warnings.py rename to Lib/test/test_unittest/_test_warnings.py index 5cbfb532..08b846ee 100644 --- a/Lib/unittest/test/_test_warnings.py +++ b/Lib/test/test_unittest/_test_warnings.py @@ -18,17 +18,6 @@ def warnfun(): warnings.warn('rw', RuntimeWarning) class TestWarnings(unittest.TestCase): - # unittest warnings will be printed at most once per type (max one message - # for the fail* methods, and one for the assert* methods) - def test_assert(self): - self.assertEquals(2+2, 4) - self.assertEquals(2*2, 4) - self.assertEquals(2**2, 4) - - def test_fail(self): - self.failUnless(1) - self.failUnless(True) - def test_other_unittest(self): self.assertAlmostEqual(2+2, 4) self.assertNotAlmostEqual(4+4, 2) diff --git a/Lib/unittest/test/dummy.py b/Lib/test/test_unittest/dummy.py similarity index 100% rename from Lib/unittest/test/dummy.py rename to Lib/test/test_unittest/dummy.py diff --git a/Lib/unittest/test/support.py b/Lib/test/test_unittest/support.py similarity index 92% rename from Lib/unittest/test/support.py rename to Lib/test/test_unittest/support.py index 52926530..8c97bf5c 100644 --- a/Lib/unittest/test/support.py +++ b/Lib/test/test_unittest/support.py @@ -136,3 +136,19 @@ class ResultWithNoStartTestRunStopTestRun(object): def wasSuccessful(self): return True + + +class BufferedWriter: + def __init__(self): + self.result = '' + self.buffer = '' + + def write(self, arg): + self.buffer += arg + + def flush(self): + self.result += self.buffer + self.buffer = '' + + def getvalue(self): + return self.result diff --git a/Lib/unittest/test/test_assertions.py b/Lib/test/test_unittest/test_assertions.py similarity index 96% rename from Lib/unittest/test/test_assertions.py rename to Lib/test/test_unittest/test_assertions.py index a0db3423..5c1a28ec 100644 --- a/Lib/unittest/test/test_assertions.py +++ b/Lib/test/test_unittest/test_assertions.py @@ -271,20 +271,11 @@ class TestLongMessage(unittest.TestCase): r"\+ \{'key': 'value'\}$", r"\+ \{'key': 'value'\} : oops$"]) - def testAssertDictContainsSubset(self): - with warnings.catch_warnings(): - warnings.simplefilter("ignore", DeprecationWarning) - - self.assertMessages('assertDictContainsSubset', ({'key': 'value'}, {}), - ["^Missing: 'key'$", "^oops$", - "^Missing: 'key'$", - "^Missing: 'key' : oops$"]) - def testAssertMultiLineEqual(self): self.assertMessages('assertMultiLineEqual', ("", "foo"), - [r"\+ foo$", "^oops$", - r"\+ foo$", - r"\+ foo : oops$"]) + [r"\+ foo\n$", "^oops$", + r"\+ foo\n$", + r"\+ foo\n : oops$"]) def testAssertLess(self): self.assertMessages('assertLess', (2, 1), diff --git a/Lib/unittest/test/test_async_case.py b/Lib/test/test_unittest/test_async_case.py similarity index 100% rename from Lib/unittest/test/test_async_case.py rename to Lib/test/test_unittest/test_async_case.py diff --git a/Lib/unittest/test/test_break.py b/Lib/test/test_unittest/test_break.py similarity index 98% rename from Lib/unittest/test/test_break.py rename to Lib/test/test_unittest/test_break.py index 33cbdd26..1da98af3 100644 --- a/Lib/unittest/test/test_break.py +++ b/Lib/test/test_unittest/test_break.py @@ -236,6 +236,7 @@ class TestBreak(unittest.TestCase): self.testRunner = FakeRunner self.test = test self.result = None + self.durations = None p = Program(False) p.runTests() @@ -244,7 +245,8 @@ class TestBreak(unittest.TestCase): 'verbosity': verbosity, 'failfast': failfast, 'tb_locals': False, - 'warnings': None})]) + 'warnings': None, + 'durations': None})]) self.assertEqual(FakeRunner.runArgs, [test]) self.assertEqual(p.result, result) @@ -259,7 +261,8 @@ class TestBreak(unittest.TestCase): 'verbosity': verbosity, 'failfast': failfast, 'tb_locals': False, - 'warnings': None})]) + 'warnings': None, + 'durations': None})]) self.assertEqual(FakeRunner.runArgs, [test]) self.assertEqual(p.result, result) diff --git a/Lib/unittest/test/test_case.py b/Lib/test/test_unittest/test_case.py similarity index 96% rename from Lib/unittest/test/test_case.py rename to Lib/test/test_unittest/test_case.py index 78303b35..ed5eb560 100644 --- a/Lib/unittest/test/test_case.py +++ b/Lib/test/test_unittest/test_case.py @@ -15,7 +15,7 @@ from test import support import unittest -from unittest.test.support import ( +from test.test_unittest.support import ( TestEquality, TestHashing, LoggingResult, LegacyLoggingResult, ResultWithNoStartTestRunStopTestRun ) @@ -304,7 +304,8 @@ class Test_TestCase(unittest.TestCase, TestEquality, TestHashing): def test(self): pass - Foo('test').run() + with self.assertWarns(RuntimeWarning): + Foo('test').run() def test_deprecation_of_return_val_from_test(self): # Issue 41322 - deprecate return of value that is not None from a test @@ -709,36 +710,6 @@ class Test_TestCase(unittest.TestCase, TestEquality, TestHashing): self.assertRaises(self.failureException, self.assertNotIn, 'cow', animals) - def testAssertDictContainsSubset(self): - with warnings.catch_warnings(): - warnings.simplefilter("ignore", DeprecationWarning) - - self.assertDictContainsSubset({}, {}) - self.assertDictContainsSubset({}, {'a': 1}) - self.assertDictContainsSubset({'a': 1}, {'a': 1}) - self.assertDictContainsSubset({'a': 1}, {'a': 1, 'b': 2}) - self.assertDictContainsSubset({'a': 1, 'b': 2}, {'a': 1, 'b': 2}) - - with self.assertRaises(self.failureException): - self.assertDictContainsSubset({1: "one"}, {}) - - with self.assertRaises(self.failureException): - self.assertDictContainsSubset({'a': 2}, {'a': 1}) - - with self.assertRaises(self.failureException): - self.assertDictContainsSubset({'c': 1}, {'a': 1}) - - with self.assertRaises(self.failureException): - self.assertDictContainsSubset({'a': 1, 'c': 1}, {'a': 1}) - - with self.assertRaises(self.failureException): - self.assertDictContainsSubset({'a': 1, 'c': 1}, {'a': 1}) - - one = ''.join(chr(i) for i in range(255)) - # this used to cause a UnicodeDecodeError constructing the failure msg - with self.assertRaises(self.failureException): - self.assertDictContainsSubset({'foo': one}, {'foo': '\uFFFD'}) - def testAssertEqual(self): equal_pairs = [ ((), ()), @@ -1178,6 +1149,66 @@ test case error = str(e).split('\n', 1)[1] self.assertEqual(sample_text_error, error) + def testAssertEqualwithEmptyString(self): + '''Verify when there is an empty string involved, the diff output + does not treat the empty string as a single empty line. It should + instead be handled as a non-line. + ''' + sample_text = '' + revised_sample_text = 'unladen swallows fly quickly' + sample_text_error = '''\ ++ unladen swallows fly quickly +''' + try: + self.assertEqual(sample_text, revised_sample_text) + except self.failureException as e: + # need to remove the first line of the error message + error = str(e).split('\n', 1)[1] + self.assertEqual(sample_text_error, error) + + def testAssertEqualMultipleLinesMissingNewlineTerminator(self): + '''Verifying format of diff output from assertEqual involving strings + with multiple lines, but missing the terminating newline on both. + ''' + sample_text = 'laden swallows\nfly sloely' + revised_sample_text = 'laden swallows\nfly slowly' + sample_text_error = '''\ + laden swallows +- fly sloely +? ^ ++ fly slowly +? ^ +''' + try: + self.assertEqual(sample_text, revised_sample_text) + except self.failureException as e: + # need to remove the first line of the error message + error = str(e).split('\n', 1)[1] + self.assertEqual(sample_text_error, error) + + def testAssertEqualMultipleLinesMismatchedNewlinesTerminators(self): + '''Verifying format of diff output from assertEqual involving strings + with multiple lines and mismatched newlines. The output should + include a - on it's own line to indicate the newline difference + between the two strings + ''' + sample_text = 'laden swallows\nfly sloely\n' + revised_sample_text = 'laden swallows\nfly slowly' + sample_text_error = '''\ + laden swallows +- fly sloely +? ^ ++ fly slowly +? ^ +-\x20 +''' + try: + self.assertEqual(sample_text, revised_sample_text) + except self.failureException as e: + # need to remove the first line of the error message + error = str(e).split('\n', 1)[1] + self.assertEqual(sample_text_error, error) + def testEqualityBytesWarning(self): if sys.flags.bytes_warning: def bytes_warning(): @@ -1801,45 +1832,18 @@ test case pass self.assertIsNone(value) - def testDeprecatedMethodNames(self): - """ - Test that the deprecated methods raise a DeprecationWarning. See #9424. - """ - old = ( - (self.failIfEqual, (3, 5)), - (self.assertNotEquals, (3, 5)), - (self.failUnlessEqual, (3, 3)), - (self.assertEquals, (3, 3)), - (self.failUnlessAlmostEqual, (2.0, 2.0)), - (self.assertAlmostEquals, (2.0, 2.0)), - (self.failIfAlmostEqual, (3.0, 5.0)), - (self.assertNotAlmostEquals, (3.0, 5.0)), - (self.failUnless, (True,)), - (self.assert_, (True,)), - (self.failUnlessRaises, (TypeError, lambda _: 3.14 + 'spam')), - (self.failIf, (False,)), - (self.assertDictContainsSubset, (dict(a=1, b=2), dict(a=1, b=2, c=3))), - (self.assertRaisesRegexp, (KeyError, 'foo', lambda: {}['foo'])), - (self.assertRegexpMatches, ('bar', 'bar')), - ) - for meth, args in old: - with self.assertWarns(DeprecationWarning): - meth(*args) - - # disable this test for now. When the version where the fail* methods will - # be removed is decided, re-enable it and update the version - def _testDeprecatedFailMethods(self): - """Test that the deprecated fail* methods get removed in 3.x""" - if sys.version_info[:2] < (3, 3): - return + def testDeprecatedFailMethods(self): + """Test that the deprecated fail* methods get removed in 3.12""" deprecated_names = [ 'failIfEqual', 'failUnlessEqual', 'failUnlessAlmostEqual', 'failIfAlmostEqual', 'failUnless', 'failUnlessRaises', 'failIf', - 'assertDictContainsSubset', + 'assertNotEquals', 'assertEquals', 'assertAlmostEquals', + 'assertNotAlmostEquals', 'assert_', 'assertDictContainsSubset', + 'assertRaisesRegexp', 'assertRegexpMatches' ] for deprecated_name in deprecated_names: with self.assertRaises(AttributeError): - getattr(self, deprecated_name) # remove these in 3.x + getattr(self, deprecated_name) def testDeepcopy(self): # Issue: 5660 diff --git a/Lib/unittest/test/test_discovery.py b/Lib/test/test_unittest/test_discovery.py similarity index 99% rename from Lib/unittest/test/test_discovery.py rename to Lib/test/test_unittest/test_discovery.py index 3b58786e..004898ed 100644 --- a/Lib/unittest/test/test_discovery.py +++ b/Lib/test/test_unittest/test_discovery.py @@ -6,11 +6,10 @@ import types import pickle from test import support from test.support import import_helper -import test.test_importlib.util import unittest import unittest.mock -import unittest.test +import test.test_unittest class TestableTestProgram(unittest.TestProgram): @@ -789,7 +788,7 @@ class TestDiscovery(unittest.TestCase): loader = unittest.TestLoader() tests = [self] - expectedPath = os.path.abspath(os.path.dirname(unittest.test.__file__)) + expectedPath = os.path.abspath(os.path.dirname(test.test_unittest.__file__)) self.wasRun = False def _find_tests(start_dir, pattern): @@ -797,7 +796,7 @@ class TestDiscovery(unittest.TestCase): self.assertEqual(start_dir, expectedPath) return tests loader._find_tests = _find_tests - suite = loader.discover('unittest.test') + suite = loader.discover('test.test_unittest') self.assertTrue(self.wasRun) self.assertEqual(suite._tests, tests) @@ -826,6 +825,8 @@ class TestDiscovery(unittest.TestCase): 'as dotted module names') def test_discovery_failed_discovery(self): + from test.test_importlib import util + loader = unittest.TestLoader() package = types.ModuleType('package') @@ -837,7 +838,7 @@ class TestDiscovery(unittest.TestCase): # Since loader.discover() can modify sys.path, restore it when done. with import_helper.DirsOnSysPath(): # Make sure to remove 'package' from sys.modules when done. - with test.test_importlib.util.uncache('package'): + with util.uncache('package'): with self.assertRaises(TypeError) as cm: loader.discover('package') self.assertEqual(str(cm.exception), diff --git a/Lib/unittest/test/test_functiontestcase.py b/Lib/test/test_unittest/test_functiontestcase.py similarity index 99% rename from Lib/unittest/test/test_functiontestcase.py rename to Lib/test/test_unittest/test_functiontestcase.py index 49717298..2ebed956 100644 --- a/Lib/unittest/test/test_functiontestcase.py +++ b/Lib/test/test_unittest/test_functiontestcase.py @@ -1,6 +1,6 @@ import unittest -from unittest.test.support import LoggingResult +from test.test_unittest.support import LoggingResult class Test_FunctionTestCase(unittest.TestCase): diff --git a/Lib/unittest/test/test_loader.py b/Lib/test/test_unittest/test_loader.py similarity index 90% rename from Lib/unittest/test/test_loader.py rename to Lib/test/test_unittest/test_loader.py index de2268cd..a203145a 100644 --- a/Lib/unittest/test/test_loader.py +++ b/Lib/test/test_unittest/test_loader.py @@ -1,29 +1,9 @@ import functools import sys import types -import warnings import unittest -# Decorator used in the deprecation tests to reset the warning registry for -# test isolation and reproducibility. -def warningregistry(func): - def wrapper(*args, **kws): - missing = [] - saved = getattr(warnings, '__warningregistry__', missing).copy() - try: - return func(*args, **kws) - finally: - if saved is missing: - try: - del warnings.__warningregistry__ - except AttributeError: - pass - else: - warnings.__warningregistry__ = saved - return wrapper - - class Test_TestLoader(unittest.TestCase): ### Basic object tests @@ -174,9 +154,8 @@ class Test_TestLoader(unittest.TestCase): self.assertEqual(list(suite), reference) - # Check that loadTestsFromModule honors (or not) a module + # Check that loadTestsFromModule honors a module # with a load_tests function. - @warningregistry def test_loadTestsFromModule__load_tests(self): m = types.ModuleType('m') class MyTestCase(unittest.TestCase): @@ -195,126 +174,13 @@ class Test_TestLoader(unittest.TestCase): suite = loader.loadTestsFromModule(m) self.assertIsInstance(suite, unittest.TestSuite) self.assertEqual(load_tests_args, [loader, suite, None]) - # With Python 3.5, the undocumented and unofficial use_load_tests is - # ignored (and deprecated). - load_tests_args = [] - with warnings.catch_warnings(record=False): - warnings.simplefilter('ignore') - suite = loader.loadTestsFromModule(m, use_load_tests=False) - self.assertEqual(load_tests_args, [loader, suite, None]) - - @warningregistry - def test_loadTestsFromModule__use_load_tests_deprecated_positional(self): - m = types.ModuleType('m') - class MyTestCase(unittest.TestCase): - def test(self): - pass - m.testcase_1 = MyTestCase - - load_tests_args = [] - def load_tests(loader, tests, pattern): - self.assertIsInstance(tests, unittest.TestSuite) - load_tests_args.extend((loader, tests, pattern)) - return tests - m.load_tests = load_tests - # The method still works. - loader = unittest.TestLoader() - # use_load_tests=True as a positional argument. - with warnings.catch_warnings(record=True) as w: - warnings.simplefilter('always') - suite = loader.loadTestsFromModule(m, False) - self.assertIsInstance(suite, unittest.TestSuite) - # load_tests was still called because use_load_tests is deprecated - # and ignored. - self.assertEqual(load_tests_args, [loader, suite, None]) - # We got a warning. - self.assertIs(w[-1].category, DeprecationWarning) - self.assertEqual(str(w[-1].message), - 'use_load_tests is deprecated and ignored') - - @warningregistry - def test_loadTestsFromModule__use_load_tests_deprecated_keyword(self): - m = types.ModuleType('m') - class MyTestCase(unittest.TestCase): - def test(self): - pass - m.testcase_1 = MyTestCase - - load_tests_args = [] - def load_tests(loader, tests, pattern): - self.assertIsInstance(tests, unittest.TestSuite) - load_tests_args.extend((loader, tests, pattern)) - return tests - m.load_tests = load_tests - # The method still works. - loader = unittest.TestLoader() - with warnings.catch_warnings(record=True) as w: - warnings.simplefilter('always') - suite = loader.loadTestsFromModule(m, use_load_tests=False) - self.assertIsInstance(suite, unittest.TestSuite) - # load_tests was still called because use_load_tests is deprecated - # and ignored. - self.assertEqual(load_tests_args, [loader, suite, None]) - # We got a warning. - self.assertIs(w[-1].category, DeprecationWarning) - self.assertEqual(str(w[-1].message), - 'use_load_tests is deprecated and ignored') - - @warningregistry - def test_loadTestsFromModule__too_many_positional_args(self): - m = types.ModuleType('m') - class MyTestCase(unittest.TestCase): - def test(self): - pass - m.testcase_1 = MyTestCase - - load_tests_args = [] - def load_tests(loader, tests, pattern): - self.assertIsInstance(tests, unittest.TestSuite) - load_tests_args.extend((loader, tests, pattern)) - return tests - m.load_tests = load_tests - loader = unittest.TestLoader() - with self.assertRaises(TypeError) as cm, \ - warnings.catch_warnings(record=True) as w: - warnings.simplefilter('always') - loader.loadTestsFromModule(m, False, 'testme.*') - # We still got the deprecation warning. - self.assertIs(w[-1].category, DeprecationWarning) - self.assertEqual(str(w[-1].message), - 'use_load_tests is deprecated and ignored') - # We also got a TypeError for too many positional arguments. - self.assertEqual(type(cm.exception), TypeError) - self.assertEqual( - str(cm.exception), - 'loadTestsFromModule() takes 1 positional argument but 3 were given') - - @warningregistry - def test_loadTestsFromModule__use_load_tests_other_bad_keyword(self): - m = types.ModuleType('m') - class MyTestCase(unittest.TestCase): - def test(self): - pass - m.testcase_1 = MyTestCase - load_tests_args = [] - def load_tests(loader, tests, pattern): - self.assertIsInstance(tests, unittest.TestSuite) - load_tests_args.extend((loader, tests, pattern)) - return tests - m.load_tests = load_tests - loader = unittest.TestLoader() - with warnings.catch_warnings(): - warnings.simplefilter('ignore') - with self.assertRaises(TypeError) as cm: - loader.loadTestsFromModule( - m, use_load_tests=False, very_bad=True, worse=False) - self.assertEqual(type(cm.exception), TypeError) - # The error message names the first bad argument alphabetically, - # however use_load_tests (which sorts first) is ignored. - self.assertEqual( - str(cm.exception), - "loadTestsFromModule() got an unexpected keyword argument 'very_bad'") + # In Python 3.12, the undocumented and unofficial use_load_tests has + # been removed. + with self.assertRaises(TypeError): + loader.loadTestsFromModule(m, False) + with self.assertRaises(TypeError): + loader.loadTestsFromModule(m, use_load_tests=False) def test_loadTestsFromModule__pattern(self): m = types.ModuleType('m') @@ -716,7 +582,7 @@ class Test_TestLoader(unittest.TestCase): # We're going to try to load this module as a side-effect, so it # better not be loaded before we try. # - module_name = 'unittest.test.dummy' + module_name = 'test.test_unittest.dummy' sys.modules.pop(module_name, None) loader = unittest.TestLoader() @@ -844,7 +710,7 @@ class Test_TestLoader(unittest.TestCase): loader = unittest.TestLoader() suite = loader.loadTestsFromNames( - ['unittest.loader.sdasfasfasdf', 'unittest.test.dummy']) + ['unittest.loader.sdasfasfasdf', 'test.test_unittest.dummy']) error, test = self.check_deferred_error(loader, list(suite)[0]) expected = "module 'unittest.loader' has no attribute 'sdasfasfasdf'" self.assertIn( @@ -1141,7 +1007,7 @@ class Test_TestLoader(unittest.TestCase): # We're going to try to load this module as a side-effect, so it # better not be loaded before we try. # - module_name = 'unittest.test.dummy' + module_name = 'test.test_unittest.dummy' sys.modules.pop(module_name, None) loader = unittest.TestLoader() diff --git a/Lib/unittest/test/test_program.py b/Lib/test/test_unittest/test_program.py similarity index 83% rename from Lib/unittest/test/test_program.py rename to Lib/test/test_unittest/test_program.py index 26a8550a..f6d52f93 100644 --- a/Lib/unittest/test/test_program.py +++ b/Lib/test/test_unittest/test_program.py @@ -1,12 +1,10 @@ -import io - import os import sys import subprocess from test import support import unittest -import unittest.test -from unittest.test.test_result import BufferedWriter +import test.test_unittest +from test.test_unittest.test_result import BufferedWriter class Test_TestProgram(unittest.TestCase): @@ -15,7 +13,7 @@ class Test_TestProgram(unittest.TestCase): loader = unittest.TestLoader() tests = [self] - expectedPath = os.path.abspath(os.path.dirname(unittest.test.__file__)) + expectedPath = os.path.abspath(os.path.dirname(test.test_unittest.__file__)) self.wasRun = False def _find_tests(start_dir, pattern): @@ -23,7 +21,7 @@ class Test_TestProgram(unittest.TestCase): self.assertEqual(start_dir, expectedPath) return tests loader._find_tests = _find_tests - suite = loader.discover('unittest.test') + suite = loader.discover('test.test_unittest') self.assertTrue(self.wasRun) self.assertEqual(suite._tests, tests) @@ -73,15 +71,22 @@ class Test_TestProgram(unittest.TestCase): def testUnexpectedSuccess(self): pass - class FooBarLoader(unittest.TestLoader): - """Test loader that returns a suite containing FooBar.""" + class Empty(unittest.TestCase): + pass + + class TestLoader(unittest.TestLoader): + """Test loader that returns a suite containing the supplied testcase.""" + + def __init__(self, testcase): + self.testcase = testcase + def loadTestsFromModule(self, module): return self.suiteClass( - [self.loadTestsFromTestCase(Test_TestProgram.FooBar)]) + [self.loadTestsFromTestCase(self.testcase)]) def loadTestsFromNames(self, names, module): return self.suiteClass( - [self.loadTestsFromTestCase(Test_TestProgram.FooBar)]) + [self.loadTestsFromTestCase(self.testcase)]) def test_defaultTest_with_string(self): class FakeRunner(object): @@ -93,10 +98,10 @@ class Test_TestProgram(unittest.TestCase): sys.argv = ['faketest'] runner = FakeRunner() program = unittest.TestProgram(testRunner=runner, exit=False, - defaultTest='unittest.test', - testLoader=self.FooBarLoader()) + defaultTest='test.test_unittest', + testLoader=self.TestLoader(self.FooBar)) sys.argv = old_argv - self.assertEqual(('unittest.test',), program.testNames) + self.assertEqual(('test.test_unittest',), program.testNames) def test_defaultTest_with_iterable(self): class FakeRunner(object): @@ -109,10 +114,10 @@ class Test_TestProgram(unittest.TestCase): runner = FakeRunner() program = unittest.TestProgram( testRunner=runner, exit=False, - defaultTest=['unittest.test', 'unittest.test2'], - testLoader=self.FooBarLoader()) + defaultTest=['test.test_unittest', 'test.test_unittest2'], + testLoader=self.TestLoader(self.FooBar)) sys.argv = old_argv - self.assertEqual(['unittest.test', 'unittest.test2'], + self.assertEqual(['test.test_unittest', 'test.test_unittest2'], program.testNames) def test_NonExit(self): @@ -120,7 +125,7 @@ class Test_TestProgram(unittest.TestCase): program = unittest.main(exit=False, argv=["foobar"], testRunner=unittest.TextTestRunner(stream=stream), - testLoader=self.FooBarLoader()) + testLoader=self.TestLoader(self.FooBar)) self.assertTrue(hasattr(program, 'result')) out = stream.getvalue() self.assertIn('\nFAIL: testFail ', out) @@ -132,13 +137,13 @@ class Test_TestProgram(unittest.TestCase): def test_Exit(self): stream = BufferedWriter() - self.assertRaises( - SystemExit, - unittest.main, - argv=["foobar"], - testRunner=unittest.TextTestRunner(stream=stream), - exit=True, - testLoader=self.FooBarLoader()) + with self.assertRaises(SystemExit) as cm: + unittest.main( + argv=["foobar"], + testRunner=unittest.TextTestRunner(stream=stream), + exit=True, + testLoader=self.TestLoader(self.FooBar)) + self.assertEqual(cm.exception.code, 1) out = stream.getvalue() self.assertIn('\nFAIL: testFail ', out) self.assertIn('\nERROR: testError ', out) @@ -149,12 +154,11 @@ class Test_TestProgram(unittest.TestCase): def test_ExitAsDefault(self): stream = BufferedWriter() - self.assertRaises( - SystemExit, - unittest.main, - argv=["foobar"], - testRunner=unittest.TextTestRunner(stream=stream), - testLoader=self.FooBarLoader()) + with self.assertRaises(SystemExit): + unittest.main( + argv=["foobar"], + testRunner=unittest.TextTestRunner(stream=stream), + testLoader=self.TestLoader(self.FooBar)) out = stream.getvalue() self.assertIn('\nFAIL: testFail ', out) self.assertIn('\nERROR: testError ', out) @@ -163,6 +167,17 @@ class Test_TestProgram(unittest.TestCase): 'expected failures=1, unexpected successes=1)\n') self.assertTrue(out.endswith(expected)) + def test_ExitEmptySuite(self): + stream = BufferedWriter() + with self.assertRaises(SystemExit) as cm: + unittest.main( + argv=["empty"], + testRunner=unittest.TextTestRunner(stream=stream), + testLoader=self.TestLoader(self.Empty)) + self.assertEqual(cm.exception.code, 5) + out = stream.getvalue() + self.assertIn('\nNO TESTS RAN\n', out) + class InitialisableProgram(unittest.TestProgram): exit = False @@ -286,6 +301,7 @@ class TestCommandLineArgs(unittest.TestCase): program.failfast = 'failfast' program.buffer = 'buffer' program.warnings = 'warnings' + program.durations = '5' program.runTests() @@ -293,7 +309,8 @@ class TestCommandLineArgs(unittest.TestCase): 'failfast': 'failfast', 'buffer': 'buffer', 'tb_locals': False, - 'warnings': 'warnings'}) + 'warnings': 'warnings', + 'durations': '5'}) self.assertEqual(FakeRunner.test, 'test') self.assertIs(program.result, RESULT) @@ -322,7 +339,8 @@ class TestCommandLineArgs(unittest.TestCase): 'failfast': False, 'tb_locals': True, 'verbosity': 1, - 'warnings': None}) + 'warnings': None, + 'durations': None}) def testRunTestsOldRunnerClass(self): program = self.program @@ -335,6 +353,7 @@ class TestCommandLineArgs(unittest.TestCase): program.failfast = 'failfast' program.buffer = 'buffer' program.test = 'test' + program.durations = '0' program.runTests() @@ -358,6 +377,7 @@ class TestCommandLineArgs(unittest.TestCase): program = self.program program.catchbreak = True + program.durations = None program.testRunner = FakeRunner @@ -463,14 +483,14 @@ class TestCommandLineArgs(unittest.TestCase): return stderr.decode() t = '_test_warnings' - self.assertIn('Ran 7 tests', run_unittest([t])) - self.assertIn('Ran 7 tests', run_unittest(['-k', 'TestWarnings', t])) - self.assertIn('Ran 7 tests', run_unittest(['discover', '-p', '*_test*', '-k', 'TestWarnings'])) - self.assertIn('Ran 2 tests', run_unittest(['-k', 'f', t])) - self.assertIn('Ran 7 tests', run_unittest(['-k', 't', t])) - self.assertIn('Ran 3 tests', run_unittest(['-k', '*t', t])) - self.assertIn('Ran 7 tests', run_unittest(['-k', '*test_warnings.*Warning*', t])) - self.assertIn('Ran 1 test', run_unittest(['-k', '*test_warnings.*warning*', t])) + self.assertIn('Ran 5 tests', run_unittest([t])) + self.assertIn('Ran 5 tests', run_unittest(['-k', 'TestWarnings', t])) + self.assertIn('Ran 5 tests', run_unittest(['discover', '-p', '*_test*', '-k', 'TestWarnings'])) + self.assertIn('Ran 1 test ', run_unittest(['-k', 'f', t])) + self.assertIn('Ran 5 tests', run_unittest(['-k', 't', t])) + self.assertIn('Ran 2 tests', run_unittest(['-k', '*t', t])) + self.assertIn('Ran 5 tests', run_unittest(['-k', '*test_warnings.*Warning*', t])) + self.assertIn('Ran 1 test ', run_unittest(['-k', '*test_warnings.*warning*', t])) if __name__ == '__main__': diff --git a/Lib/unittest/test/test_result.py b/Lib/test/test_unittest/test_result.py similarity index 98% rename from Lib/unittest/test/test_result.py rename to Lib/test/test_unittest/test_result.py index 9320b0a4..db551b78 100644 --- a/Lib/unittest/test/test_result.py +++ b/Lib/test/test_unittest/test_result.py @@ -2,11 +2,13 @@ import io import sys import textwrap -from test.support import warnings_helper, captured_stdout, captured_stderr +from test.support import warnings_helper, captured_stdout import traceback import unittest +from unittest import mock from unittest.util import strclass +from test.test_unittest.support import BufferedWriter class MockTraceback(object): @@ -33,22 +35,6 @@ def bad_cleanup2(): raise ValueError('bad cleanup2') -class BufferedWriter: - def __init__(self): - self.result = '' - self.buffer = '' - - def write(self, arg): - self.buffer += arg - - def flush(self): - self.result += self.buffer - self.buffer = '' - - def getvalue(self): - return self.result - - class Test_TestResult(unittest.TestCase): # Note: there are not separate tests for TestResult.wasSuccessful(), # TestResult.errors, TestResult.failures, TestResult.testsRun or @@ -465,6 +451,7 @@ class Test_TestResult(unittest.TestCase): stream = BufferedWriter() runner = unittest.TextTestRunner(stream=stream, failfast=True) def test(result): + result.testsRun += 1 self.assertTrue(result.failfast) result = runner.run(test) stream.flush() @@ -505,8 +492,8 @@ class Test_TextTestResult(unittest.TestCase): '(' + __name__ + '.Test_TextTestResult.testGetSubTestDescriptionWithoutDocstringAndParams) ' '(<subtest>)') - def testGetSubTestDescriptionForFalsyValues(self): - expected = 'testGetSubTestDescriptionForFalsyValues (%s.Test_TextTestResult.testGetSubTestDescriptionForFalsyValues) [%s]' + def testGetSubTestDescriptionForFalseValues(self): + expected = 'testGetSubTestDescriptionForFalseValues (%s.Test_TextTestResult.testGetSubTestDescriptionForFalseValues) [%s]' result = unittest.TextTestResult(None, True, 1) for arg in [0, None, []]: with self.subTest(arg): diff --git a/Lib/unittest/test/test_runner.py b/Lib/test/test_unittest/test_runner.py similarity index 89% rename from Lib/unittest/test/test_runner.py rename to Lib/test/test_unittest/test_runner.py index e02b2dad..1b9cef43 100644 --- a/Lib/unittest/test/test_runner.py +++ b/Lib/test/test_unittest/test_runner.py @@ -8,8 +8,11 @@ from test import support import unittest from unittest.case import _Outcome -from unittest.test.support import (LoggingResult, - ResultWithNoStartTestRunStopTestRun) +from test.test_unittest.support import ( + BufferedWriter, + LoggingResult, + ResultWithNoStartTestRunStopTestRun, +) def resultFactory(*_): @@ -21,6 +24,13 @@ def getRunner(): stream=io.StringIO()) +class CustomError(Exception): + pass + +# For test output compat: +CustomErrorRepr = f"{__name__ + '.' if __name__ != '__main__' else ''}CustomError" + + def runTests(*cases): suite = unittest.TestSuite() for case in cases: @@ -43,7 +53,7 @@ def cleanup(ordering, blowUp=False): ordering.append('cleanup_good') else: ordering.append('cleanup_exc') - raise Exception('CleanUpExc') + raise CustomError('CleanUpExc') class TestCM: @@ -105,8 +115,8 @@ class TestCleanUp(unittest.TestCase): result = unittest.TestResult() outcome = test._outcome = _Outcome(result=result) - CleanUpExc = Exception('foo') - exc2 = Exception('bar') + CleanUpExc = CustomError('foo') + exc2 = CustomError('bar') def cleanup1(): raise CleanUpExc @@ -122,10 +132,10 @@ class TestCleanUp(unittest.TestCase): (_, msg2), (_, msg1) = result.errors self.assertIn('in cleanup1', msg1) self.assertIn('raise CleanUpExc', msg1) - self.assertIn('Exception: foo', msg1) + self.assertIn(f'{CustomErrorRepr}: foo', msg1) self.assertIn('in cleanup2', msg2) self.assertIn('raise exc2', msg2) - self.assertIn('Exception: bar', msg2) + self.assertIn(f'{CustomErrorRepr}: bar', msg2) def testCleanupInRun(self): blowUp = False @@ -136,7 +146,7 @@ class TestCleanUp(unittest.TestCase): ordering.append('setUp') test.addCleanup(cleanup2) if blowUp: - raise Exception('foo') + raise CustomError('foo') def testNothing(self): ordering.append('test') @@ -277,7 +287,7 @@ class TestClassCleanup(unittest.TestCase): ordering.append('setUpClass') cls.addClassCleanup(cleanup, ordering) if blowUp: - raise Exception() + raise CustomError() def testNothing(self): ordering.append('test') @classmethod @@ -303,7 +313,7 @@ class TestClassCleanup(unittest.TestCase): ordering.append('setUpClass') cls.addClassCleanup(cleanup, ordering) if blowUp: - raise Exception() + raise CustomError() def testNothing(self): ordering.append('test') @classmethod @@ -343,7 +353,7 @@ class TestClassCleanup(unittest.TestCase): ordering = [] blowUp = True suite = unittest.defaultTestLoader.loadTestsFromTestCase(TestableTest) - with self.assertRaises(Exception) as cm: + with self.assertRaises(CustomError) as cm: suite.debug() self.assertEqual(str(cm.exception), 'CleanUpExc') self.assertEqual(ordering, @@ -363,10 +373,10 @@ class TestClassCleanup(unittest.TestCase): @classmethod def tearDownClass(cls): ordering.append('tearDownClass') - raise Exception('TearDownClassExc') + raise CustomError('TearDownClassExc') suite = unittest.defaultTestLoader.loadTestsFromTestCase(TestableTest) - with self.assertRaises(Exception) as cm: + with self.assertRaises(CustomError) as cm: suite.debug() self.assertEqual(str(cm.exception), 'TearDownClassExc') self.assertEqual(ordering, ['setUpClass', 'test', 'tearDownClass']) @@ -376,7 +386,7 @@ class TestClassCleanup(unittest.TestCase): ordering = [] blowUp = True suite = unittest.defaultTestLoader.loadTestsFromTestCase(TestableTest) - with self.assertRaises(Exception) as cm: + with self.assertRaises(CustomError) as cm: suite.debug() self.assertEqual(str(cm.exception), 'TearDownClassExc') self.assertEqual(ordering, ['setUpClass', 'test', 'tearDownClass']) @@ -389,16 +399,22 @@ class TestClassCleanup(unittest.TestCase): pass def cleanup1(): - raise Exception('cleanup1') + raise CustomError('cleanup1') def cleanup2(): - raise Exception('cleanup2') + raise CustomError('cleanup2') TestableTest.addClassCleanup(cleanup1) TestableTest.addClassCleanup(cleanup2) - with self.assertRaises(Exception) as e: - TestableTest.doClassCleanups() - self.assertEqual(e, 'cleanup1') + TestableTest.doClassCleanups() + + self.assertEqual(len(TestableTest.tearDown_exceptions), 2) + + e1, e2 = TestableTest.tearDown_exceptions + self.assertIsInstance(e1[1], CustomError) + self.assertEqual(str(e1[1]), 'cleanup2') + self.assertIsInstance(e2[1], CustomError) + self.assertEqual(str(e2[1]), 'cleanup1') def test_with_errors_addCleanUp(self): ordering = [] @@ -418,7 +434,7 @@ class TestClassCleanup(unittest.TestCase): result = runTests(TestableTest) self.assertEqual(result.errors[0][1].splitlines()[-1], - 'Exception: CleanUpExc') + f'{CustomErrorRepr}: CleanUpExc') self.assertEqual(ordering, ['setUpClass', 'setUp', 'cleanup_exc', 'tearDownClass', 'cleanup_good']) @@ -441,7 +457,7 @@ class TestClassCleanup(unittest.TestCase): result = runTests(TestableTest) self.assertEqual(result.errors[0][1].splitlines()[-1], - 'Exception: CleanUpExc') + f'{CustomErrorRepr}: CleanUpExc') self.assertEqual(ordering, ['setUpClass', 'setUp', 'test', 'cleanup_good', 'tearDownClass', 'cleanup_exc']) @@ -457,11 +473,11 @@ class TestClassCleanup(unittest.TestCase): ordering.append('setUpClass') cls.addClassCleanup(cleanup, ordering, blowUp=True) if class_blow_up: - raise Exception('ClassExc') + raise CustomError('ClassExc') def setUp(self): ordering.append('setUp') if method_blow_up: - raise Exception('MethodExc') + raise CustomError('MethodExc') def testNothing(self): ordering.append('test') @classmethod @@ -470,7 +486,7 @@ class TestClassCleanup(unittest.TestCase): result = runTests(TestableTest) self.assertEqual(result.errors[0][1].splitlines()[-1], - 'Exception: CleanUpExc') + f'{CustomErrorRepr}: CleanUpExc') self.assertEqual(ordering, ['setUpClass', 'setUp', 'test', 'tearDownClass', 'cleanup_exc']) @@ -480,9 +496,9 @@ class TestClassCleanup(unittest.TestCase): method_blow_up = False result = runTests(TestableTest) self.assertEqual(result.errors[0][1].splitlines()[-1], - 'Exception: ClassExc') + f'{CustomErrorRepr}: ClassExc') self.assertEqual(result.errors[1][1].splitlines()[-1], - 'Exception: CleanUpExc') + f'{CustomErrorRepr}: CleanUpExc') self.assertEqual(ordering, ['setUpClass', 'cleanup_exc']) @@ -491,9 +507,9 @@ class TestClassCleanup(unittest.TestCase): method_blow_up = True result = runTests(TestableTest) self.assertEqual(result.errors[0][1].splitlines()[-1], - 'Exception: MethodExc') + f'{CustomErrorRepr}: MethodExc') self.assertEqual(result.errors[1][1].splitlines()[-1], - 'Exception: CleanUpExc') + f'{CustomErrorRepr}: CleanUpExc') self.assertEqual(ordering, ['setUpClass', 'setUp', 'tearDownClass', 'cleanup_exc']) @@ -510,11 +526,11 @@ class TestClassCleanup(unittest.TestCase): @classmethod def tearDownClass(cls): ordering.append('tearDownClass') - raise Exception('TearDownExc') + raise CustomError('TearDownExc') result = runTests(TestableTest) self.assertEqual(result.errors[0][1].splitlines()[-1], - 'Exception: TearDownExc') + f'{CustomErrorRepr}: TearDownExc') self.assertEqual(ordering, ['setUpClass', 'test', 'tearDownClass', 'cleanup_good']) @@ -574,6 +590,16 @@ class TestClassCleanup(unittest.TestCase): 'inner setup', 'inner test', 'inner cleanup', 'end outer test', 'outer cleanup']) + def test_run_empty_suite_error_message(self): + class EmptyTest(unittest.TestCase): + pass + + suite = unittest.defaultTestLoader.loadTestsFromTestCase(EmptyTest) + runner = getRunner() + runner.run(suite) + + self.assertIn("\nNO TESTS RAN\n", runner.stream.getvalue()) + class TestModuleCleanUp(unittest.TestCase): def test_add_and_do_ModuleCleanup(self): @@ -607,7 +633,7 @@ class TestModuleCleanUp(unittest.TestCase): module_cleanups.append((3, args, kwargs)) def module_cleanup_bad(*args, **kwargs): - raise Exception('CleanUpExc') + raise CustomError('CleanUpExc') class Module(object): unittest.addModuleCleanup(module_cleanup_good, 1, 2, 3, @@ -617,7 +643,7 @@ class TestModuleCleanUp(unittest.TestCase): [(module_cleanup_good, (1, 2, 3), dict(four='hello', five='goodbye')), (module_cleanup_bad, (), {})]) - with self.assertRaises(Exception) as e: + with self.assertRaises(CustomError) as e: unittest.case.doModuleCleanups() self.assertEqual(str(e.exception), 'CleanUpExc') self.assertEqual(unittest.case._module_cleanups, []) @@ -646,7 +672,7 @@ class TestModuleCleanUp(unittest.TestCase): ordering.append('setUpModule') unittest.addModuleCleanup(cleanup, ordering) if blowUp: - raise Exception('setUpModule Exc') + raise CustomError('setUpModule Exc') @staticmethod def tearDownModule(): ordering.append('tearDownModule') @@ -666,7 +692,7 @@ class TestModuleCleanUp(unittest.TestCase): result = runTests(TestableTest) self.assertEqual(ordering, ['setUpModule', 'cleanup_good']) self.assertEqual(result.errors[0][1].splitlines()[-1], - 'Exception: setUpModule Exc') + f'{CustomErrorRepr}: setUpModule Exc') ordering = [] blowUp = False @@ -686,7 +712,7 @@ class TestModuleCleanUp(unittest.TestCase): ordering.append('setUpModule') unittest.addModuleCleanup(cleanup, ordering) if blowUp: - raise Exception() + raise CustomError() @staticmethod def tearDownModule(): ordering.append('tearDownModule') @@ -697,7 +723,7 @@ class TestModuleCleanUp(unittest.TestCase): ordering.append('setUpModule2') unittest.addModuleCleanup(cleanup, ordering) if blowUp2: - raise Exception() + raise CustomError() @staticmethod def tearDownModule(): ordering.append('tearDownModule2') @@ -786,7 +812,7 @@ class TestModuleCleanUp(unittest.TestCase): @staticmethod def tearDownModule(): ordering.append('tearDownModule') - raise Exception('CleanUpExc') + raise CustomError('CleanUpExc') class TestableTest(unittest.TestCase): @classmethod @@ -802,7 +828,7 @@ class TestModuleCleanUp(unittest.TestCase): sys.modules['Module'] = Module result = runTests(TestableTest) self.assertEqual(result.errors[0][1].splitlines()[-1], - 'Exception: CleanUpExc') + f'{CustomErrorRepr}: CleanUpExc') self.assertEqual(ordering, ['setUpModule', 'setUpClass', 'test', 'tearDownClass', 'tearDownModule', 'cleanup_good']) @@ -842,7 +868,7 @@ class TestModuleCleanUp(unittest.TestCase): ordering = [] blowUp = True suite = unittest.defaultTestLoader.loadTestsFromTestCase(TestableTest) - with self.assertRaises(Exception) as cm: + with self.assertRaises(CustomError) as cm: suite.debug() self.assertEqual(str(cm.exception), 'CleanUpExc') self.assertEqual(ordering, ['setUpModule', 'setUpClass', 'test', @@ -860,7 +886,7 @@ class TestModuleCleanUp(unittest.TestCase): @staticmethod def tearDownModule(): ordering.append('tearDownModule') - raise Exception('TearDownModuleExc') + raise CustomError('TearDownModuleExc') class TestableTest(unittest.TestCase): @classmethod @@ -875,7 +901,7 @@ class TestModuleCleanUp(unittest.TestCase): TestableTest.__module__ = 'Module' sys.modules['Module'] = Module suite = unittest.defaultTestLoader.loadTestsFromTestCase(TestableTest) - with self.assertRaises(Exception) as cm: + with self.assertRaises(CustomError) as cm: suite.debug() self.assertEqual(str(cm.exception), 'TearDownModuleExc') self.assertEqual(ordering, ['setUpModule', 'setUpClass', 'test', @@ -886,7 +912,7 @@ class TestModuleCleanUp(unittest.TestCase): ordering = [] blowUp = True suite = unittest.defaultTestLoader.loadTestsFromTestCase(TestableTest) - with self.assertRaises(Exception) as cm: + with self.assertRaises(CustomError) as cm: suite.debug() self.assertEqual(str(cm.exception), 'TearDownModuleExc') self.assertEqual(ordering, ['setUpModule', 'setUpClass', 'test', @@ -965,7 +991,7 @@ class TestModuleCleanUp(unittest.TestCase): result = runTests(TestableTest) self.assertEqual(result.errors[0][1].splitlines()[-1], - 'Exception: CleanUpExc') + f'{CustomErrorRepr}: CleanUpExc') self.assertEqual(ordering, ['setUpModule', 'setUpClass', 'test', 'tearDownClass', 'cleanup_exc', 'tearDownModule', 'cleanup_good']) @@ -995,7 +1021,7 @@ class TestModuleCleanUp(unittest.TestCase): result = runTests(TestableTest) self.assertEqual(result.errors[0][1].splitlines()[-1], - 'Exception: CleanUpExc') + f'{CustomErrorRepr}: CleanUpExc') self.assertEqual(ordering, ['setUpModule', 'setUp', 'test', 'tearDown', 'cleanup_exc', 'tearDownModule', 'cleanup_good']) @@ -1011,7 +1037,7 @@ class TestModuleCleanUp(unittest.TestCase): ordering.append('setUpModule') unittest.addModuleCleanup(cleanup, ordering, blowUp=True) if module_blow_up: - raise Exception('ModuleExc') + raise CustomError('ModuleExc') @staticmethod def tearDownModule(): ordering.append('tearDownModule') @@ -1021,11 +1047,11 @@ class TestModuleCleanUp(unittest.TestCase): def setUpClass(cls): ordering.append('setUpClass') if class_blow_up: - raise Exception('ClassExc') + raise CustomError('ClassExc') def setUp(self): ordering.append('setUp') if method_blow_up: - raise Exception('MethodExc') + raise CustomError('MethodExc') def testNothing(self): ordering.append('test') @classmethod @@ -1037,7 +1063,7 @@ class TestModuleCleanUp(unittest.TestCase): result = runTests(TestableTest) self.assertEqual(result.errors[0][1].splitlines()[-1], - 'Exception: CleanUpExc') + f'{CustomErrorRepr}: CleanUpExc') self.assertEqual(ordering, ['setUpModule', 'setUpClass', 'setUp', 'test', 'tearDownClass', 'tearDownModule', @@ -1049,9 +1075,9 @@ class TestModuleCleanUp(unittest.TestCase): method_blow_up = False result = runTests(TestableTest) self.assertEqual(result.errors[0][1].splitlines()[-1], - 'Exception: ModuleExc') + f'{CustomErrorRepr}: ModuleExc') self.assertEqual(result.errors[1][1].splitlines()[-1], - 'Exception: CleanUpExc') + f'{CustomErrorRepr}: CleanUpExc') self.assertEqual(ordering, ['setUpModule', 'cleanup_exc']) ordering = [] @@ -1060,9 +1086,9 @@ class TestModuleCleanUp(unittest.TestCase): method_blow_up = False result = runTests(TestableTest) self.assertEqual(result.errors[0][1].splitlines()[-1], - 'Exception: ClassExc') + f'{CustomErrorRepr}: ClassExc') self.assertEqual(result.errors[1][1].splitlines()[-1], - 'Exception: CleanUpExc') + f'{CustomErrorRepr}: CleanUpExc') self.assertEqual(ordering, ['setUpModule', 'setUpClass', 'tearDownModule', 'cleanup_exc']) @@ -1072,9 +1098,9 @@ class TestModuleCleanUp(unittest.TestCase): method_blow_up = True result = runTests(TestableTest) self.assertEqual(result.errors[0][1].splitlines()[-1], - 'Exception: MethodExc') + f'{CustomErrorRepr}: MethodExc') self.assertEqual(result.errors[1][1].splitlines()[-1], - 'Exception: CleanUpExc') + f'{CustomErrorRepr}: CleanUpExc') self.assertEqual(ordering, ['setUpModule', 'setUpClass', 'setUp', 'tearDownClass', 'tearDownModule', 'cleanup_exc']) @@ -1176,6 +1202,7 @@ class Test_TextTestRunner(unittest.TestCase): self.assertTrue(runner.descriptions) self.assertEqual(runner.resultclass, unittest.TextTestResult) self.assertFalse(runner.tb_locals) + self.assertIsNone(runner.durations) def test_multiple_inheritance(self): class AResult(unittest.TestResult): @@ -1303,8 +1330,6 @@ class Test_TextTestRunner(unittest.TestCase): return [b.splitlines() for b in p.communicate()] opts = dict(stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=os.path.dirname(__file__)) - ae_msg = b'Please use assertEqual instead.' - at_msg = b'Please use assertTrue instead.' # no args -> all the warnings are printed, unittest warnings only once p = subprocess.Popen([sys.executable, '-E', '_test_warnings.py'], **opts) @@ -1312,11 +1337,11 @@ class Test_TextTestRunner(unittest.TestCase): out, err = get_parse_out_err(p) self.assertIn(b'OK', err) # check that the total number of warnings in the output is correct - self.assertEqual(len(out), 12) + self.assertEqual(len(out), 10) # check that the numbers of the different kind of warnings is correct for msg in [b'dw', b'iw', b'uw']: self.assertEqual(out.count(msg), 3) - for msg in [ae_msg, at_msg, b'rw']: + for msg in [b'rw']: self.assertEqual(out.count(msg), 1) args_list = ( @@ -1343,11 +1368,9 @@ class Test_TextTestRunner(unittest.TestCase): with p: out, err = get_parse_out_err(p) self.assertIn(b'OK', err) - self.assertEqual(len(out), 14) + self.assertEqual(len(out), 12) for msg in [b'dw', b'iw', b'uw', b'rw']: self.assertEqual(out.count(msg), 3) - for msg in [ae_msg, at_msg]: - self.assertEqual(out.count(msg), 1) def testStdErrLookedUpAtInstantiationTime(self): # see issue 10786 @@ -1366,6 +1389,65 @@ class Test_TextTestRunner(unittest.TestCase): runner = unittest.TextTestRunner(f) self.assertTrue(runner.stream.stream is f) + def test_durations(self): + def run(test, *, expect_durations=True): + stream = BufferedWriter() + runner = unittest.TextTestRunner(stream=stream, durations=5, verbosity=2) + result = runner.run(test) + self.assertEqual(result.durations, 5) + stream.flush() + text = stream.getvalue() + regex = r"\n\d+.\d\d\ds" + if expect_durations: + self.assertEqual(len(result.collectedDurations), 1) + self.assertIn('Slowest test durations', text) + self.assertRegex(text, regex) + else: + self.assertEqual(len(result.collectedDurations), 0) + self.assertNotIn('Slowest test durations', text) + self.assertNotRegex(text, regex) + + # success + class Foo(unittest.TestCase): + def test_1(self): + pass + + run(Foo('test_1'), expect_durations=True) + + # failure + class Foo(unittest.TestCase): + def test_1(self): + self.assertEqual(0, 1) + + run(Foo('test_1'), expect_durations=True) + + # error + class Foo(unittest.TestCase): + def test_1(self): + 1 / 0 + + run(Foo('test_1'), expect_durations=True) + + + # error in setUp and tearDown + class Foo(unittest.TestCase): + def setUp(self): + 1 / 0 + tearDown = setUp + def test_1(self): + pass + + run(Foo('test_1'), expect_durations=True) + + # skip (expect no durations) + class Foo(unittest.TestCase): + @unittest.skip("reason") + def test_1(self): + pass + + run(Foo('test_1'), expect_durations=False) + + if __name__ == "__main__": unittest.main() diff --git a/Lib/unittest/test/test_setups.py b/Lib/test/test_unittest/test_setups.py similarity index 100% rename from Lib/unittest/test/test_setups.py rename to Lib/test/test_unittest/test_setups.py diff --git a/Lib/unittest/test/test_skipping.py b/Lib/test/test_unittest/test_skipping.py similarity index 99% rename from Lib/unittest/test/test_skipping.py rename to Lib/test/test_unittest/test_skipping.py index 64ceeae3..f146dcac 100644 --- a/Lib/unittest/test/test_skipping.py +++ b/Lib/test/test_unittest/test_skipping.py @@ -1,6 +1,6 @@ import unittest -from unittest.test.support import LoggingResult +from test.test_unittest.support import LoggingResult class Test_TestSkipping(unittest.TestCase): diff --git a/Lib/unittest/test/test_suite.py b/Lib/test/test_unittest/test_suite.py similarity index 99% rename from Lib/unittest/test/test_suite.py rename to Lib/test/test_unittest/test_suite.py index 0551a169..ca52ee9d 100644 --- a/Lib/unittest/test/test_suite.py +++ b/Lib/test/test_unittest/test_suite.py @@ -3,7 +3,7 @@ import unittest import gc import sys import weakref -from unittest.test.support import LoggingResult, TestEquality +from test.test_unittest.support import LoggingResult, TestEquality ### Support code for Test_TestSuite diff --git a/Lib/test/test_unittest/testmock/__init__.py b/Lib/test/test_unittest/testmock/__init__.py new file mode 100644 index 00000000..bc502ef3 --- /dev/null +++ b/Lib/test/test_unittest/testmock/__init__.py @@ -0,0 +1,6 @@ +import os.path +from test.support import load_package_tests + + +def load_tests(*args): + return load_package_tests(os.path.dirname(__file__), *args) diff --git a/Lib/unittest/test/testmock/__main__.py b/Lib/test/test_unittest/testmock/__main__.py similarity index 86% rename from Lib/unittest/test/testmock/__main__.py rename to Lib/test/test_unittest/testmock/__main__.py index 45c633a4..1e3068b0 100644 --- a/Lib/unittest/test/testmock/__main__.py +++ b/Lib/test/test_unittest/testmock/__main__.py @@ -6,7 +6,7 @@ def load_tests(loader, standard_tests, pattern): # top level directory cached on loader instance this_dir = os.path.dirname(__file__) pattern = pattern or "test*.py" - # We are inside unittest.test.testmock, so the top-level is three notches up + # We are inside test.test_unittest.testmock, so the top-level is three notches up top_level_dir = os.path.dirname(os.path.dirname(os.path.dirname(this_dir))) package_tests = loader.discover(start_dir=this_dir, pattern=pattern, top_level_dir=top_level_dir) diff --git a/Lib/unittest/test/testmock/support.py b/Lib/test/test_unittest/testmock/support.py similarity index 100% rename from Lib/unittest/test/testmock/support.py rename to Lib/test/test_unittest/testmock/support.py diff --git a/Lib/unittest/test/testmock/testasync.py b/Lib/test/test_unittest/testmock/testasync.py similarity index 98% rename from Lib/unittest/test/testmock/testasync.py rename to Lib/test/test_unittest/testmock/testasync.py index df260abd..edd9a5df 100644 --- a/Lib/unittest/test/testmock/testasync.py +++ b/Lib/test/test_unittest/testmock/testasync.py @@ -218,10 +218,6 @@ class AsyncAutospecTest(unittest.TestCase): with self.assertRaises(RuntimeError): create_autospec(async_func, instance=True) - @unittest.skip('Broken test from https://bugs.python.org/issue37251') - def test_create_autospec_awaitable_class(self): - self.assertIsInstance(create_autospec(AwaitableClass), AsyncMock) - def test_create_autospec(self): spec = create_autospec(async_func_args) awaitable = spec(1, 2, c=3) @@ -308,6 +304,19 @@ class AsyncSpecTest(unittest.TestCase): with self.assertRaises(AttributeError): mock.async_method + def test_spec_async_attributes_instance(self): + async_instance = AsyncClass() + async_instance.async_func_attr = async_func + async_instance.later_async_func_attr = normal_func + + mock_async_instance = Mock(spec_set=async_instance) + + async_instance.later_async_func_attr = async_func + + self.assertIsInstance(mock_async_instance.async_func_attr, AsyncMock) + # only the shape of the spec at the time of mock construction matters + self.assertNotIsInstance(mock_async_instance.later_async_func_attr, AsyncMock) + def test_spec_mock_type_kw(self): def inner_test(mock_type): async_mock = mock_type(spec=async_func) @@ -427,9 +436,10 @@ class AsyncArguments(IsolatedAsyncioTestCase): self.assertEqual(output, 10) async def test_add_side_effect_exception(self): + class CustomError(Exception): pass async def addition(var): pass - mock = AsyncMock(addition, side_effect=Exception('err')) - with self.assertRaises(Exception): + mock = AsyncMock(addition, side_effect=CustomError('side-effect')) + with self.assertRaisesRegex(CustomError, 'side-effect'): await mock(5) async def test_add_side_effect_coroutine(self): diff --git a/Lib/unittest/test/testmock/testcallable.py b/Lib/test/test_unittest/testmock/testcallable.py similarity index 98% rename from Lib/unittest/test/testmock/testcallable.py rename to Lib/test/test_unittest/testmock/testcallable.py index 5eadc007..ca88511f 100644 --- a/Lib/unittest/test/testmock/testcallable.py +++ b/Lib/test/test_unittest/testmock/testcallable.py @@ -3,7 +3,7 @@ # http://www.voidspace.org.uk/python/mock/ import unittest -from unittest.test.testmock.support import is_instance, X, SomeClass +from test.test_unittest.testmock.support import is_instance, X, SomeClass from unittest.mock import ( Mock, MagicMock, NonCallableMagicMock, diff --git a/Lib/unittest/test/testmock/testhelpers.py b/Lib/test/test_unittest/testmock/testhelpers.py similarity index 96% rename from Lib/unittest/test/testmock/testhelpers.py rename to Lib/test/test_unittest/testmock/testhelpers.py index 9e7ec5d6..74785a83 100644 --- a/Lib/unittest/test/testmock/testhelpers.py +++ b/Lib/test/test_unittest/testmock/testhelpers.py @@ -952,6 +952,24 @@ class SpecSignatureTest(unittest.TestCase): self.assertFalse(hasattr(autospec, '__name__')) + def test_autospec_signature_staticmethod(self): + class Foo: + @staticmethod + def static_method(a, b=10, *, c): pass + + mock = create_autospec(Foo.__dict__['static_method']) + self.assertEqual(inspect.signature(Foo.static_method), inspect.signature(mock)) + + + def test_autospec_signature_classmethod(self): + class Foo: + @classmethod + def class_method(cls, a, b=10, *, c): pass + + mock = create_autospec(Foo.__dict__['class_method']) + self.assertEqual(inspect.signature(Foo.class_method), inspect.signature(mock)) + + def test_spec_inspect_signature(self): def myfunc(x, y): pass @@ -1077,7 +1095,7 @@ class TestCallList(unittest.TestCase): p.stop() - def test_propertymock_returnvalue(self): + def test_propertymock_bare(self): m = MagicMock() p = PropertyMock() type(m).foo = p @@ -1088,6 +1106,27 @@ class TestCallList(unittest.TestCase): self.assertNotIsInstance(returned, PropertyMock) + def test_propertymock_returnvalue(self): + m = MagicMock() + p = PropertyMock(return_value=42) + type(m).foo = p + + returned = m.foo + p.assert_called_once_with() + self.assertEqual(returned, 42) + self.assertNotIsInstance(returned, PropertyMock) + + + def test_propertymock_side_effect(self): + m = MagicMock() + p = PropertyMock(side_effect=ValueError) + type(m).foo = p + + with self.assertRaises(ValueError): + m.foo + p.assert_called_once_with() + + class TestCallablePredicate(unittest.TestCase): def test_type(self): diff --git a/Lib/unittest/test/testmock/testmagicmethods.py b/Lib/test/test_unittest/testmock/testmagicmethods.py similarity index 100% rename from Lib/unittest/test/testmock/testmagicmethods.py rename to Lib/test/test_unittest/testmock/testmagicmethods.py diff --git a/Lib/unittest/test/testmock/testmock.py b/Lib/test/test_unittest/testmock/testmock.py similarity index 99% rename from Lib/unittest/test/testmock/testmock.py rename to Lib/test/test_unittest/testmock/testmock.py index eaae22e8..d1cae47a 100644 --- a/Lib/unittest/test/testmock/testmock.py +++ b/Lib/test/test_unittest/testmock/testmock.py @@ -5,7 +5,7 @@ import tempfile from test.support import ALWAYS_EQ import unittest -from unittest.test.testmock.support import is_instance +from test.test_unittest.testmock.support import is_instance from unittest import mock from unittest.mock import ( call, DEFAULT, patch, sentinel, @@ -1645,21 +1645,41 @@ class MockTest(unittest.TestCase): m.aseert_foo_call() with self.assertRaisesRegex(AttributeError, msg): m.assrt_foo_call() + with self.assertRaisesRegex(AttributeError, msg): + m.called_once_with() + with self.assertRaisesRegex(AttributeError, msg): + m.called_once() + with self.assertRaisesRegex(AttributeError, msg): + m.has_calls() + + class Foo(object): + def called_once(self): pass + + def has_calls(self): pass + + m = Mock(spec=Foo) + m.called_once() + m.has_calls() + + m.called_once.assert_called_once() + m.has_calls.assert_called_once() + m = Mock(unsafe=True) m.assert_foo_call() m.assret_foo_call() m.asert_foo_call() m.aseert_foo_call() m.assrt_foo_call() + m.called_once() + m.called_once_with() + m.has_calls() # gh-100739 def test_mock_safe_with_spec(self): class Foo(object): - def assert_bar(self): - pass + def assert_bar(self): pass - def assertSome(self): - pass + def assertSome(self): pass m = Mock(spec=Foo) m.assert_bar() diff --git a/Lib/unittest/test/testmock/testpatch.py b/Lib/test/test_unittest/testmock/testpatch.py similarity index 96% rename from Lib/unittest/test/testmock/testpatch.py rename to Lib/test/test_unittest/testmock/testpatch.py index 8ab63a13..833d7da1 100644 --- a/Lib/unittest/test/testmock/testpatch.py +++ b/Lib/test/test_unittest/testmock/testpatch.py @@ -7,8 +7,8 @@ import sys from collections import OrderedDict import unittest -from unittest.test.testmock import support -from unittest.test.testmock.support import SomeClass, is_instance +from test.test_unittest.testmock import support +from test.test_unittest.testmock.support import SomeClass, is_instance from test.test_importlib.util import uncache from unittest.mock import ( @@ -669,7 +669,7 @@ class PatchTest(unittest.TestCase): # the new dictionary during function call original = support.target.copy() - @patch.dict('unittest.test.testmock.support.target', {'bar': 'BAR'}) + @patch.dict('test.test_unittest.testmock.support.target', {'bar': 'BAR'}) def test(): self.assertEqual(support.target, {'foo': 'BAZ', 'bar': 'BAR'}) @@ -996,6 +996,36 @@ class PatchTest(unittest.TestCase): method.assert_called_once_with() + def test_autospec_staticmethod_signature(self): + # Patched methods which are decorated with @staticmethod should have the same signature + class Foo: + @staticmethod + def static_method(a, b=10, *, c): pass + + Foo.static_method(1, 2, c=3) + + with patch.object(Foo, 'static_method', autospec=True) as method: + method(1, 2, c=3) + self.assertRaises(TypeError, method) + self.assertRaises(TypeError, method, 1) + self.assertRaises(TypeError, method, 1, 2, 3, c=4) + + + def test_autospec_classmethod_signature(self): + # Patched methods which are decorated with @classmethod should have the same signature + class Foo: + @classmethod + def class_method(cls, a, b=10, *, c): pass + + Foo.class_method(1, 2, c=3) + + with patch.object(Foo, 'class_method', autospec=True) as method: + method(1, 2, c=3) + self.assertRaises(TypeError, method) + self.assertRaises(TypeError, method, 1) + self.assertRaises(TypeError, method, 1, 2, 3, c=4) + + def test_autospec_with_new(self): patcher = patch('%s.function' % __name__, new=3, autospec=True) self.assertRaises(TypeError, patcher.start) @@ -1614,7 +1644,7 @@ class PatchTest(unittest.TestCase): def test_patch_nested_autospec_repr(self): - with patch('unittest.test.testmock.support', autospec=True) as m: + with patch('test.test_unittest.testmock.support', autospec=True) as m: self.assertIn(" name='support.SomeClass.wibble()'", repr(m.SomeClass.wibble())) self.assertIn(" name='support.SomeClass().wibble()'", @@ -1882,7 +1912,7 @@ class PatchTest(unittest.TestCase): with patch.object(foo, '__module__', "testpatch2"): self.assertEqual(foo.__module__, "testpatch2") - self.assertEqual(foo.__module__, 'unittest.test.testmock.testpatch') + self.assertEqual(foo.__module__, 'test.test_unittest.testmock.testpatch') with patch.object(foo, '__annotations__', dict([('s', 1, )])): self.assertEqual(foo.__annotations__, dict([('s', 1, )])) @@ -1917,16 +1947,16 @@ class PatchTest(unittest.TestCase): # This exercises the AttributeError branch of _dot_lookup. # make sure it's there - import unittest.test.testmock.support + import test.test_unittest.testmock.support # now make sure it's not: with patch.dict('sys.modules'): - del sys.modules['unittest.test.testmock.support'] - del sys.modules['unittest.test.testmock'] - del sys.modules['unittest.test'] - del sys.modules['unittest'] + del sys.modules['test.test_unittest.testmock.support'] + del sys.modules['test.test_unittest.testmock'] + del sys.modules['test.test_unittest'] + del sys.modules['test'] # now make sure we can patch based on a dotted path: - @patch('unittest.test.testmock.support.X') + @patch('test.test_unittest.testmock.support.X') def test(mock): pass test() @@ -1943,7 +1973,7 @@ class PatchTest(unittest.TestCase): def test_cant_set_kwargs_when_passing_a_mock(self): - @patch('unittest.test.testmock.support.X', new=object(), x=1) + @patch('test.test_unittest.testmock.support.X', new=object(), x=1) def test(): pass with self.assertRaises(TypeError): test() diff --git a/Lib/unittest/test/testmock/testsealable.py b/Lib/test/test_unittest/testmock/testsealable.py similarity index 96% rename from Lib/unittest/test/testmock/testsealable.py rename to Lib/test/test_unittest/testmock/testsealable.py index daba2b49..8bf98cfa 100644 --- a/Lib/unittest/test/testmock/testsealable.py +++ b/Lib/test/test_unittest/testmock/testsealable.py @@ -175,15 +175,12 @@ class TestSealable(unittest.TestCase): # https://bugs.python.org/issue45156 class Foo: foo = 0 - def bar1(self): - return 1 - def bar2(self): - return 2 + def bar1(self): pass + def bar2(self): pass class Baz: baz = 3 - def ban(self): - return 4 + def ban(self): pass for spec_set in (True, False): with self.subTest(spec_set=spec_set): @@ -200,6 +197,9 @@ class TestSealable(unittest.TestCase): self.assertIsInstance(foo.Baz.baz, mock.NonCallableMagicMock) self.assertIsInstance(foo.Baz.ban, mock.MagicMock) + # see gh-91803 + self.assertIsInstance(foo.bar2(), mock.MagicMock) + self.assertEqual(foo.bar1(), 'a') foo.bar1.return_value = 'new_a' self.assertEqual(foo.bar1(), 'new_a') @@ -212,7 +212,7 @@ class TestSealable(unittest.TestCase): with self.assertRaises(AttributeError): foo.bar = 1 with self.assertRaises(AttributeError): - foo.bar2() + foo.bar2().x foo.bar2.return_value = 'bar2' self.assertEqual(foo.bar2(), 'bar2') diff --git a/Lib/unittest/test/testmock/testsentinel.py b/Lib/test/test_unittest/testmock/testsentinel.py similarity index 100% rename from Lib/unittest/test/testmock/testsentinel.py rename to Lib/test/test_unittest/testmock/testsentinel.py diff --git a/Lib/unittest/test/testmock/testwith.py b/Lib/test/test_unittest/testmock/testwith.py similarity index 99% rename from Lib/unittest/test/testmock/testwith.py rename to Lib/test/test_unittest/testmock/testwith.py index c74d49a6..8dc8eb11 100644 --- a/Lib/unittest/test/testmock/testwith.py +++ b/Lib/test/test_unittest/testmock/testwith.py @@ -1,7 +1,7 @@ import unittest from warnings import catch_warnings -from unittest.test.testmock.support import is_instance +from test.test_unittest.testmock.support import is_instance from unittest.mock import MagicMock, Mock, patch, sentinel, mock_open, call diff --git a/Lib/test/test_univnewlines.py b/Lib/test/test_univnewlines.py index b9054918..ed2e0970 100644 --- a/Lib/test/test_univnewlines.py +++ b/Lib/test/test_univnewlines.py @@ -4,7 +4,6 @@ import _pyio as pyio import unittest import os import sys -from test import support from test.support import os_helper diff --git a/Lib/test/test_unparse.py b/Lib/test/test_unparse.py index f1f1dd5d..bdf7b058 100644 --- a/Lib/test/test_unparse.py +++ b/Lib/test/test_unparse.py @@ -1,4 +1,4 @@ -"""Tests for the unparse.py script in the Tools/parser directory.""" +"""Tests for ast.unparse.""" import unittest import test.support @@ -6,6 +6,7 @@ import pathlib import random import tokenize import ast +from test.support.ast_helper import ASTTestMixin def read_pyfile(filename): @@ -128,46 +129,7 @@ docstring_prefixes = ( "async def foo():\n ", ) -class ASTTestCase(unittest.TestCase): - def assertASTEqual(self, ast1, ast2): - # Ensure the comparisons start at an AST node - self.assertIsInstance(ast1, ast.AST) - self.assertIsInstance(ast2, ast.AST) - - # An AST comparison routine modeled after ast.dump(), but - # instead of string building, it traverses the two trees - # in lock-step. - def traverse_compare(a, b, missing=object()): - if type(a) is not type(b): - self.fail(f"{type(a)!r} is not {type(b)!r}") - if isinstance(a, ast.AST): - for field in a._fields: - value1 = getattr(a, field, missing) - value2 = getattr(b, field, missing) - # Singletons are equal by definition, so further - # testing can be skipped. - if value1 is not value2: - traverse_compare(value1, value2) - elif isinstance(a, list): - try: - for node1, node2 in zip(a, b, strict=True): - traverse_compare(node1, node2) - except ValueError: - # Attempt a "pretty" error ala assertSequenceEqual() - len1 = len(a) - len2 = len(b) - if len1 > len2: - what = "First" - diff = len1 - len2 - else: - what = "Second" - diff = len2 - len1 - msg = f"{what} list contains {diff} additional elements." - raise self.failureException(msg) from None - elif a != b: - self.fail(f"{a!r} != {b!r}") - traverse_compare(ast1, ast2) - +class ASTTestCase(ASTTestMixin, unittest.TestCase): def check_ast_roundtrip(self, code1, **kwargs): with self.subTest(code1=code1, ast_parse_kwargs=kwargs): ast1 = ast.parse(code1, **kwargs) @@ -235,6 +197,10 @@ class UnparseTestCase(ASTTestCase): self.check_ast_roundtrip('''f"a\\r\\nb"''') self.check_ast_roundtrip('''f"\\u2028{'x'}"''') + def test_fstrings_pep701(self): + self.check_ast_roundtrip('f" something { my_dict["key"] } something else "') + self.check_ast_roundtrip('f"{f"{f"{f"{f"{f"{1+1}"}"}"}"}"}"') + def test_strings(self): self.check_ast_roundtrip("u'foo'") self.check_ast_roundtrip("r'foo'") @@ -416,8 +382,15 @@ class UnparseTestCase(ASTTestCase): ) ) - def test_invalid_fstring_backslash(self): - self.check_invalid(ast.FormattedValue(value=ast.Constant(value="\\\\"))) + def test_fstring_backslash(self): + # valid since Python 3.12 + self.assertEqual(ast.unparse( + ast.FormattedValue( + value=ast.Constant(value="\\\\"), + conversion=-1, + format_spec=None, + ) + ), "{'\\\\\\\\'}") def test_invalid_yield_from(self): self.check_invalid(ast.YieldFrom(value=None)) @@ -540,11 +513,11 @@ class CosmeticTestCase(ASTTestCase): self.check_src_roundtrip("class X(*args, **kwargs):\n pass") def test_fstrings(self): - self.check_src_roundtrip('''f\'\'\'-{f"""*{f"+{f'.{x}.'}+"}*"""}-\'\'\'''') - self.check_src_roundtrip('''f"\\u2028{'x'}"''') + self.check_src_roundtrip("f'-{f'*{f'+{f'.{x}.'}+'}*'}-'") + self.check_src_roundtrip("f'\\u2028{'x'}'") self.check_src_roundtrip(r"f'{x}\n'") - self.check_src_roundtrip('''f''\'{"""\n"""}\\n''\'''') - self.check_src_roundtrip('''f''\'{f"""{x}\n"""}\\n''\'''') + self.check_src_roundtrip("f'{'\\n'}\\n'") + self.check_src_roundtrip("f'{f'{x}\\n'}\\n'") def test_docstrings(self): docstrings = ( @@ -662,6 +635,92 @@ class CosmeticTestCase(ASTTestCase): self.check_src_roundtrip("[a, b] = [c, d] = [e, f] = g") self.check_src_roundtrip("a, b = [c, d] = e, f = g") + def test_multiquote_joined_string(self): + self.check_ast_roundtrip("f\"'''{1}\\\"\\\"\\\"\" ") + self.check_ast_roundtrip("""f"'''{1}""\\"" """) + self.check_ast_roundtrip("""f'""\"{1}''' """) + self.check_ast_roundtrip("""f'""\"{1}""\\"' """) + + self.check_ast_roundtrip("""f"'''{"\\n"}""\\"" """) + self.check_ast_roundtrip("""f'""\"{"\\n"}''' """) + self.check_ast_roundtrip("""f'""\"{"\\n"}""\\"' """) + + self.check_ast_roundtrip("""f'''""\"''\\'{"\\n"}''' """) + self.check_ast_roundtrip("""f'''""\"''\\'{"\\n\\"'"}''' """) + self.check_ast_roundtrip("""f'''""\"''\\'{""\"\\n\\"'''""\" '''\\n'''}''' """) + + +class ManualASTCreationTestCase(unittest.TestCase): + """Test that AST nodes created without a type_params field unparse correctly.""" + + def test_class(self): + node = ast.ClassDef(name="X", bases=[], keywords=[], body=[ast.Pass()], decorator_list=[]) + ast.fix_missing_locations(node) + self.assertEqual(ast.unparse(node), "class X:\n pass") + + def test_class_with_type_params(self): + node = ast.ClassDef(name="X", bases=[], keywords=[], body=[ast.Pass()], decorator_list=[], + type_params=[ast.TypeVar("T")]) + ast.fix_missing_locations(node) + self.assertEqual(ast.unparse(node), "class X[T]:\n pass") + + def test_function(self): + node = ast.FunctionDef( + name="f", + args=ast.arguments(posonlyargs=[], args=[], vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), + body=[ast.Pass()], + decorator_list=[], + returns=None, + ) + ast.fix_missing_locations(node) + self.assertEqual(ast.unparse(node), "def f():\n pass") + + def test_function_with_type_params(self): + node = ast.FunctionDef( + name="f", + args=ast.arguments(posonlyargs=[], args=[], vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), + body=[ast.Pass()], + decorator_list=[], + returns=None, + type_params=[ast.TypeVar("T")], + ) + ast.fix_missing_locations(node) + self.assertEqual(ast.unparse(node), "def f[T]():\n pass") + + def test_function_with_type_params_and_bound(self): + node = ast.FunctionDef( + name="f", + args=ast.arguments(posonlyargs=[], args=[], vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), + body=[ast.Pass()], + decorator_list=[], + returns=None, + type_params=[ast.TypeVar("T", bound=ast.Name("int"))], + ) + ast.fix_missing_locations(node) + self.assertEqual(ast.unparse(node), "def f[T: int]():\n pass") + + def test_async_function(self): + node = ast.AsyncFunctionDef( + name="f", + args=ast.arguments(posonlyargs=[], args=[], vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), + body=[ast.Pass()], + decorator_list=[], + returns=None, + ) + ast.fix_missing_locations(node) + self.assertEqual(ast.unparse(node), "async def f():\n pass") + + def test_async_function_with_type_params(self): + node = ast.AsyncFunctionDef( + name="f", + args=ast.arguments(posonlyargs=[], args=[], vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), + body=[ast.Pass()], + decorator_list=[], + returns=None, + type_params=[ast.TypeVar("T")], + ) + ast.fix_missing_locations(node) + self.assertEqual(ast.unparse(node), "async def f[T]():\n pass") class DirectoryTestCase(ASTTestCase): @@ -671,7 +730,7 @@ class DirectoryTestCase(ASTTestCase): test_directories = (lib_dir, lib_dir / "test") run_always_files = {"test_grammar.py", "test_syntax.py", "test_compile.py", "test_ast.py", "test_asdl_parser.py", "test_fstring.py", - "test_patma.py"} + "test_patma.py", "test_type_alias.py", "test_type_params.py"} _files_to_test = None diff --git a/Lib/test/test_urllib.py b/Lib/test/test_urllib.py index f067560c..2df74f5e 100644 --- a/Lib/test/test_urllib.py +++ b/Lib/test/test_urllib.py @@ -1104,6 +1104,8 @@ class UnquotingTests(unittest.TestCase): self.assertEqual(result.count('%'), 1, "using unquote(): not all characters escaped: " "%s" % result) + + def test_unquote_rejects_none_and_tuple(self): self.assertRaises((TypeError, AttributeError), urllib.parse.unquote, None) self.assertRaises((TypeError, AttributeError), urllib.parse.unquote, ()) diff --git a/Lib/test/test_urllib2.py b/Lib/test/test_urllib2.py index db92ba56..99c9e249 100644 --- a/Lib/test/test_urllib2.py +++ b/Lib/test/test_urllib2.py @@ -1,9 +1,9 @@ import unittest from test import support from test.support import os_helper -from test.support import socket_helper from test.support import warnings_helper from test import test_urllib +from unittest import mock import os import io @@ -485,7 +485,18 @@ def build_test_opener(*handler_instances): return opener -class MockHTTPHandler(urllib.request.BaseHandler): +class MockHTTPHandler(urllib.request.HTTPHandler): + # Very simple mock HTTP handler with no special behavior other than using a mock HTTP connection + + def __init__(self, debuglevel=None): + super(MockHTTPHandler, self).__init__(debuglevel=debuglevel) + self.httpconn = MockHTTPClass() + + def http_open(self, req): + return self.do_open(self.httpconn, req) + + +class MockHTTPHandlerRedirect(urllib.request.BaseHandler): # useful for testing redirections and auth # sends supplied headers and code as first response # sends 200 OK as second response @@ -513,16 +524,17 @@ class MockHTTPHandler(urllib.request.BaseHandler): return MockResponse(200, "OK", msg, "", req.get_full_url()) -class MockHTTPSHandler(urllib.request.AbstractHTTPHandler): - # Useful for testing the Proxy-Authorization request by verifying the - # properties of httpcon +if hasattr(http.client, 'HTTPSConnection'): + class MockHTTPSHandler(urllib.request.HTTPSHandler): + # Useful for testing the Proxy-Authorization request by verifying the + # properties of httpcon - def __init__(self, debuglevel=0): - urllib.request.AbstractHTTPHandler.__init__(self, debuglevel=debuglevel) - self.httpconn = MockHTTPClass() + def __init__(self, debuglevel=None, context=None, check_hostname=None): + super(MockHTTPSHandler, self).__init__(debuglevel, context, check_hostname) + self.httpconn = MockHTTPClass() - def https_open(self, req): - return self.do_open(self.httpconn, req) + def https_open(self, req): + return self.do_open(self.httpconn, req) class MockHTTPHandlerCheckAuth(urllib.request.BaseHandler): @@ -1049,12 +1061,37 @@ class HandlerTests(unittest.TestCase): newreq = h.do_request_(req) self.assertEqual(int(newreq.get_header('Content-length')),16) - def test_http_handler_debuglevel(self): + def test_http_handler_global_debuglevel(self): + with mock.patch.object(http.client.HTTPConnection, 'debuglevel', 6): + o = OpenerDirector() + h = MockHTTPHandler() + o.add_handler(h) + o.open("http://www.example.com") + self.assertEqual(h._debuglevel, 6) + + def test_http_handler_local_debuglevel(self): + o = OpenerDirector() + h = MockHTTPHandler(debuglevel=5) + o.add_handler(h) + o.open("http://www.example.com") + self.assertEqual(h._debuglevel, 5) + + @unittest.skipUnless(hasattr(http.client, 'HTTPSConnection'), 'HTTPSConnection required for HTTPS tests.') + def test_https_handler_global_debuglevel(self): + with mock.patch.object(http.client.HTTPSConnection, 'debuglevel', 7): + o = OpenerDirector() + h = MockHTTPSHandler() + o.add_handler(h) + o.open("https://www.example.com") + self.assertEqual(h._debuglevel, 7) + + @unittest.skipUnless(hasattr(http.client, 'HTTPSConnection'), 'HTTPSConnection required for HTTPS tests.') + def test_https_handler_local_debuglevel(self): o = OpenerDirector() - h = MockHTTPSHandler(debuglevel=1) + h = MockHTTPSHandler(debuglevel=4) o.add_handler(h) o.open("https://www.example.com") - self.assertEqual(h._debuglevel, 1) + self.assertEqual(h._debuglevel, 4) def test_http_doubleslash(self): # Checks the presence of any unnecessary double slash in url does not @@ -1290,7 +1327,7 @@ class HandlerTests(unittest.TestCase): cj = CookieJar() interact_netscape(cj, "http://www.example.com/", "spam=eggs") - hh = MockHTTPHandler(302, "Location: http://www.cracker.com/\r\n\r\n") + hh = MockHTTPHandlerRedirect(302, "Location: http://www.cracker.com/\r\n\r\n") hdeh = urllib.request.HTTPDefaultErrorHandler() hrh = urllib.request.HTTPRedirectHandler() cp = urllib.request.HTTPCookieProcessor(cj) @@ -1300,7 +1337,7 @@ class HandlerTests(unittest.TestCase): def test_redirect_fragment(self): redirected_url = 'http://www.example.com/index.html#OK\r\n\r\n' - hh = MockHTTPHandler(302, 'Location: ' + redirected_url) + hh = MockHTTPHandlerRedirect(302, 'Location: ' + redirected_url) hdeh = urllib.request.HTTPDefaultErrorHandler() hrh = urllib.request.HTTPRedirectHandler() o = build_test_opener(hh, hdeh, hrh) @@ -1422,6 +1459,7 @@ class HandlerTests(unittest.TestCase): self.assertEqual([(handlers[0], "https_open")], [tup[0:2] for tup in o.calls]) + @unittest.skipUnless(hasattr(http.client, 'HTTPSConnection'), 'HTTPSConnection required for HTTPS tests.') def test_proxy_https_proxy_authorization(self): o = OpenerDirector() ph = urllib.request.ProxyHandler(dict(https='proxy.example.com:3128')) @@ -1485,7 +1523,7 @@ class HandlerTests(unittest.TestCase): password_manager = MockPasswordManager() auth_handler = urllib.request.HTTPBasicAuthHandler(password_manager) body = '\r\n'.join(headers) + '\r\n\r\n' - http_handler = MockHTTPHandler(401, body) + http_handler = MockHTTPHandlerRedirect(401, body) opener.add_handler(auth_handler) opener.add_handler(http_handler) self._test_basic_auth(opener, auth_handler, "Authorization", @@ -1545,7 +1583,7 @@ class HandlerTests(unittest.TestCase): password_manager = MockPasswordManager() auth_handler = urllib.request.ProxyBasicAuthHandler(password_manager) realm = "ACME Networks" - http_handler = MockHTTPHandler( + http_handler = MockHTTPHandlerRedirect( 407, 'Proxy-Authenticate: Basic realm="%s"\r\n\r\n' % realm) opener.add_handler(auth_handler) opener.add_handler(http_handler) @@ -1557,11 +1595,11 @@ class HandlerTests(unittest.TestCase): def test_basic_and_digest_auth_handlers(self): # HTTPDigestAuthHandler raised an exception if it couldn't handle a 40* - # response (http://python.org/sf/1479302), where it should instead + # response (https://bugs.python.org/issue1479302), where it should instead # return None to allow another handler (especially # HTTPBasicAuthHandler) to handle the response. - # Also (http://python.org/sf/14797027, RFC 2617 section 1.2), we must + # Also (https://bugs.python.org/issue14797027, RFC 2617 section 1.2), we must # try digest first (since it's the strongest auth scheme), so we record # order of calls here to check digest comes first: class RecordingOpenerDirector(OpenerDirector): @@ -1589,7 +1627,7 @@ class HandlerTests(unittest.TestCase): digest_handler = TestDigestAuthHandler(password_manager) basic_handler = TestBasicAuthHandler(password_manager) realm = "ACME Networks" - http_handler = MockHTTPHandler( + http_handler = MockHTTPHandlerRedirect( 401, 'WWW-Authenticate: Basic realm="%s"\r\n\r\n' % realm) opener.add_handler(basic_handler) opener.add_handler(digest_handler) @@ -1609,7 +1647,7 @@ class HandlerTests(unittest.TestCase): opener = OpenerDirector() # While using DigestAuthHandler digest_auth_handler = urllib.request.HTTPDigestAuthHandler(None) - http_handler = MockHTTPHandler( + http_handler = MockHTTPHandlerRedirect( 401, 'WWW-Authenticate: Kerberos\r\n\r\n') opener.add_handler(digest_auth_handler) opener.add_handler(http_handler) @@ -1619,7 +1657,7 @@ class HandlerTests(unittest.TestCase): # While using BasicAuthHandler opener = OpenerDirector() basic_auth_handler = urllib.request.HTTPBasicAuthHandler(None) - http_handler = MockHTTPHandler( + http_handler = MockHTTPHandlerRedirect( 401, 'WWW-Authenticate: NTLM\r\n\r\n') opener.add_handler(basic_auth_handler) opener.add_handler(http_handler) @@ -1706,7 +1744,7 @@ class HandlerTests(unittest.TestCase): opener = OpenerDirector() opener.add_handler(auth_prior_handler) - http_handler = MockHTTPHandler( + http_handler = MockHTTPHandlerRedirect( 401, 'WWW-Authenticate: Basic realm="%s"\r\n\r\n' % None) opener.add_handler(http_handler) @@ -1828,6 +1866,7 @@ class MiscTests(unittest.TestCase): def test_gh_98778(self): x = urllib.error.HTTPError("url", 405, "METHOD NOT ALLOWED", None, None) self.assertEqual(getattr(x, "__notes__", ()), ()) + self.assertIsInstance(x.fp.read(), bytes) def test_parse_proxy(self): parse_proxy_test_cases = [ diff --git a/Lib/test/test_urllib2net.py b/Lib/test/test_urllib2net.py index 5da41c37..f0874d8d 100644 --- a/Lib/test/test_urllib2net.py +++ b/Lib/test/test_urllib2net.py @@ -133,8 +133,11 @@ class OtherNetworkTests(unittest.TestCase): # XXX The rest of these tests aren't very good -- they don't check much. # They do sometimes catch some major disasters, though. + @support.requires_resource('walltime') def test_ftp(self): + # Testing the same URL twice exercises the caching in CacheFTPHandler urls = [ + 'ftp://www.pythontest.net/README', 'ftp://www.pythontest.net/README', ('ftp://www.pythontest.net/non-existent-file', None, urllib.error.URLError), @@ -194,6 +197,7 @@ class OtherNetworkTests(unittest.TestCase): self.assertEqual(res.geturl(), "http://www.pythontest.net/index.html#frag") + @support.requires_resource('walltime') def test_redirect_url_withfrag(self): redirect_url_with_frag = "http://www.pythontest.net/redir/with_frag/" with socket_helper.transient_internet(redirect_url_with_frag): @@ -332,6 +336,7 @@ class TimeoutTest(unittest.TestCase): FTP_HOST = 'ftp://www.pythontest.net/' + @support.requires_resource('walltime') def test_ftp_basic(self): self.assertIsNone(socket.getdefaulttimeout()) with socket_helper.transient_internet(self.FTP_HOST, timeout=None): @@ -350,6 +355,7 @@ class TimeoutTest(unittest.TestCase): socket.setdefaulttimeout(None) self.assertEqual(u.fp.fp.raw._sock.gettimeout(), 60) + @support.requires_resource('walltime') def test_ftp_no_timeout(self): self.assertIsNone(socket.getdefaulttimeout()) with socket_helper.transient_internet(self.FTP_HOST): @@ -361,6 +367,7 @@ class TimeoutTest(unittest.TestCase): socket.setdefaulttimeout(None) self.assertIsNone(u.fp.fp.raw._sock.gettimeout()) + @support.requires_resource('walltime') def test_ftp_timeout(self): with socket_helper.transient_internet(self.FTP_HOST): u = _urlopen_with_retry(self.FTP_HOST, timeout=60) diff --git a/Lib/test/test_urllibnet.py b/Lib/test/test_urllibnet.py index 773101ce..49a3b5af 100644 --- a/Lib/test/test_urllibnet.py +++ b/Lib/test/test_urllibnet.py @@ -109,6 +109,7 @@ class urlopenNetworkTests(unittest.TestCase): open_url.close() self.assertEqual(code, 404) + @support.requires_resource('walltime') def test_bad_address(self): # Make sure proper exception is raised when connecting to a bogus # address. @@ -191,6 +192,7 @@ class urlretrieveNetworkTests(unittest.TestCase): logo = "http://www.pythontest.net/" + @support.requires_resource('walltime') def test_data_header(self): with self.urlretrieve(self.logo) as (file_location, fileheaders): datevalue = fileheaders.get('Date') diff --git a/Lib/test/test_urlparse.py b/Lib/test/test_urlparse.py index b4261107..625c6dc8 100644 --- a/Lib/test/test_urlparse.py +++ b/Lib/test/test_urlparse.py @@ -72,20 +72,20 @@ class UrlParseTestCase(unittest.TestCase): def checkRoundtrips(self, url, parsed, split): result = urllib.parse.urlparse(url) - self.assertEqual(result, parsed) + self.assertSequenceEqual(result, parsed) t = (result.scheme, result.netloc, result.path, result.params, result.query, result.fragment) - self.assertEqual(t, parsed) + self.assertSequenceEqual(t, parsed) # put it back together and it should be the same result2 = urllib.parse.urlunparse(result) - self.assertEqual(result2, url) - self.assertEqual(result2, result.geturl()) + self.assertSequenceEqual(result2, url) + self.assertSequenceEqual(result2, result.geturl()) # the result of geturl() is a fixpoint; we can always parse it # again to get the same result: result3 = urllib.parse.urlparse(result.geturl()) self.assertEqual(result3.geturl(), result.geturl()) - self.assertEqual(result3, result) + self.assertSequenceEqual(result3, result) self.assertEqual(result3.scheme, result.scheme) self.assertEqual(result3.netloc, result.netloc) self.assertEqual(result3.path, result.path) @@ -99,18 +99,18 @@ class UrlParseTestCase(unittest.TestCase): # check the roundtrip using urlsplit() as well result = urllib.parse.urlsplit(url) - self.assertEqual(result, split) + self.assertSequenceEqual(result, split) t = (result.scheme, result.netloc, result.path, result.query, result.fragment) - self.assertEqual(t, split) + self.assertSequenceEqual(t, split) result2 = urllib.parse.urlunsplit(result) - self.assertEqual(result2, url) - self.assertEqual(result2, result.geturl()) + self.assertSequenceEqual(result2, url) + self.assertSequenceEqual(result2, result.geturl()) # check the fixpoint property of re-parsing the result of geturl() result3 = urllib.parse.urlsplit(result.geturl()) self.assertEqual(result3.geturl(), result.geturl()) - self.assertEqual(result3, result) + self.assertSequenceEqual(result3, result) self.assertEqual(result3.scheme, result.scheme) self.assertEqual(result3.netloc, result.netloc) self.assertEqual(result3.path, result.path) @@ -162,10 +162,15 @@ class UrlParseTestCase(unittest.TestCase): ('svn+ssh', 'svn.zope.org', '/repos/main/ZConfig/trunk/', '', '')), ('git+ssh://git@github.com/user/project.git', - ('git+ssh', 'git@github.com','/user/project.git', - '','',''), - ('git+ssh', 'git@github.com','/user/project.git', - '', '')), + ('git+ssh', 'git@github.com','/user/project.git', + '','',''), + ('git+ssh', 'git@github.com','/user/project.git', + '', '')), + ('itms-services://?action=download-manifest&url=https://example.com/app', + ('itms-services', '', '', '', + 'action=download-manifest&url=https://example.com/app', ''), + ('itms-services', '', '', + 'action=download-manifest&url=https://example.com/app', '')), ] def _encode(t): return (t[0].encode('ascii'), @@ -649,6 +654,65 @@ class UrlParseTestCase(unittest.TestCase): self.assertEqual(p.scheme, "http") self.assertEqual(p.geturl(), "http://www.python.org/javascript:alert('msg')/?query=something#fragment") + def test_urlsplit_strip_url(self): + noise = bytes(range(0, 0x20 + 1)) + base_url = "http://User:Pass@www.python.org:080/doc/?query=yes#frag" + + url = noise.decode("utf-8") + base_url + p = urllib.parse.urlsplit(url) + self.assertEqual(p.scheme, "http") + self.assertEqual(p.netloc, "User:Pass@www.python.org:080") + self.assertEqual(p.path, "/doc/") + self.assertEqual(p.query, "query=yes") + self.assertEqual(p.fragment, "frag") + self.assertEqual(p.username, "User") + self.assertEqual(p.password, "Pass") + self.assertEqual(p.hostname, "www.python.org") + self.assertEqual(p.port, 80) + self.assertEqual(p.geturl(), base_url) + + url = noise + base_url.encode("utf-8") + p = urllib.parse.urlsplit(url) + self.assertEqual(p.scheme, b"http") + self.assertEqual(p.netloc, b"User:Pass@www.python.org:080") + self.assertEqual(p.path, b"/doc/") + self.assertEqual(p.query, b"query=yes") + self.assertEqual(p.fragment, b"frag") + self.assertEqual(p.username, b"User") + self.assertEqual(p.password, b"Pass") + self.assertEqual(p.hostname, b"www.python.org") + self.assertEqual(p.port, 80) + self.assertEqual(p.geturl(), base_url.encode("utf-8")) + + # Test that trailing space is preserved as some applications rely on + # this within query strings. + query_spaces_url = "https://www.python.org:88/doc/?query= " + p = urllib.parse.urlsplit(noise.decode("utf-8") + query_spaces_url) + self.assertEqual(p.scheme, "https") + self.assertEqual(p.netloc, "www.python.org:88") + self.assertEqual(p.path, "/doc/") + self.assertEqual(p.query, "query= ") + self.assertEqual(p.port, 88) + self.assertEqual(p.geturl(), query_spaces_url) + + p = urllib.parse.urlsplit("www.pypi.org ") + # That "hostname" gets considered a "path" due to the + # trailing space and our existing logic... YUCK... + # and re-assembles via geturl aka unurlsplit into the original. + # django.core.validators.URLValidator (at least through v3.2) relies on + # this, for better or worse, to catch it in a ValidationError via its + # regular expressions. + # Here we test the basic round trip concept of such a trailing space. + self.assertEqual(urllib.parse.urlunsplit(p), "www.pypi.org ") + + # with scheme as cache-key + url = "//www.python.org/" + scheme = noise.decode("utf-8") + "https" + noise.decode("utf-8") + for _ in range(2): + p = urllib.parse.urlsplit(url, scheme=scheme) + self.assertEqual(p.scheme, "https") + self.assertEqual(p.geturl(), "https://www.python.org/") + def test_attributes_bad_port(self): """Check handling of invalid ports.""" for bytes in (False, True): @@ -656,7 +720,7 @@ class UrlParseTestCase(unittest.TestCase): for port in ("foo", "1.5", "-1", "0x10", "-0", "1_1", " 1", "1 ", "६"): with self.subTest(bytes=bytes, parse=parse, port=port): netloc = "www.example.net:" + port - url = "http://" + netloc + url = "http://" + netloc + "/" if bytes: if netloc.isascii() and port.isascii(): netloc = netloc.encode("ascii") @@ -1006,6 +1070,10 @@ class UrlParseTestCase(unittest.TestCase): self.assertEqual(result, 'archaeological%20arcana') result = urllib.parse.quote_from_bytes(b'') self.assertEqual(result, '') + result = urllib.parse.quote_from_bytes(b'A'*10_000) + self.assertEqual(result, 'A'*10_000) + result = urllib.parse.quote_from_bytes(b'z\x01/ '*253_183) + self.assertEqual(result, 'z%01/%20'*253_183) def test_unquote_to_bytes(self): result = urllib.parse.unquote_to_bytes('abc%20def') @@ -1033,6 +1101,32 @@ class UrlParseTestCase(unittest.TestCase): self.assertEqual(p2.scheme, 'tel') self.assertEqual(p2.path, '+31641044153') + def test_invalid_bracketed_hosts(self): + self.assertRaises(ValueError, urllib.parse.urlsplit, 'Scheme://user@[192.0.2.146]/Path?Query') + self.assertRaises(ValueError, urllib.parse.urlsplit, 'Scheme://user@[important.com:8000]/Path?Query') + self.assertRaises(ValueError, urllib.parse.urlsplit, 'Scheme://user@[v123r.IP]/Path?Query') + self.assertRaises(ValueError, urllib.parse.urlsplit, 'Scheme://user@[v12ae]/Path?Query') + self.assertRaises(ValueError, urllib.parse.urlsplit, 'Scheme://user@[v.IP]/Path?Query') + self.assertRaises(ValueError, urllib.parse.urlsplit, 'Scheme://user@[v123.]/Path?Query') + self.assertRaises(ValueError, urllib.parse.urlsplit, 'Scheme://user@[v]/Path?Query') + self.assertRaises(ValueError, urllib.parse.urlsplit, 'Scheme://user@[0439:23af::2309::fae7:1234]/Path?Query') + self.assertRaises(ValueError, urllib.parse.urlsplit, 'Scheme://user@[0439:23af:2309::fae7:1234:2342:438e:192.0.2.146]/Path?Query') + self.assertRaises(ValueError, urllib.parse.urlsplit, 'Scheme://user@]v6a.ip[/Path') + + def test_splitting_bracketed_hosts(self): + p1 = urllib.parse.urlsplit('scheme://user@[v6a.ip]/path?query') + self.assertEqual(p1.hostname, 'v6a.ip') + self.assertEqual(p1.username, 'user') + self.assertEqual(p1.path, '/path') + p2 = urllib.parse.urlsplit('scheme://user@[0439:23af:2309::fae7%test]/path?query') + self.assertEqual(p2.hostname, '0439:23af:2309::fae7%test') + self.assertEqual(p2.username, 'user') + self.assertEqual(p2.path, '/path') + p3 = urllib.parse.urlsplit('scheme://user@[0439:23af:2309::fae7:1234:192.0.2.146%test]/path?query') + self.assertEqual(p3.hostname, '0439:23af:2309::fae7:1234:192.0.2.146%test') + self.assertEqual(p3.username, 'user') + self.assertEqual(p3.path, '/path') + def test_port_casting_failure_message(self): message = "Port could not be cast to integer value as 'oracle'" p1 = urllib.parse.urlparse('http://Server=sde; Service=sde:oracle') diff --git a/Lib/test/test_uu.py b/Lib/test/test_uu.py index 0493aae4..a189d6bc 100644 --- a/Lib/test/test_uu.py +++ b/Lib/test/test_uu.py @@ -147,6 +147,34 @@ class UUTest(unittest.TestCase): uu.encode(inp, out, filename) self.assertIn(safefilename, out.getvalue()) + def test_no_directory_traversal(self): + relative_bad = b"""\ +begin 644 ../../../../../../../../tmp/test1 +$86)C"@`` +` +end +""" + with self.assertRaisesRegex(uu.Error, 'directory'): + uu.decode(io.BytesIO(relative_bad)) + if os.altsep: + relative_bad_bs = relative_bad.replace(b'/', b'\\') + with self.assertRaisesRegex(uu.Error, 'directory'): + uu.decode(io.BytesIO(relative_bad_bs)) + + absolute_bad = b"""\ +begin 644 /tmp/test2 +$86)C"@`` +` +end +""" + with self.assertRaisesRegex(uu.Error, 'directory'): + uu.decode(io.BytesIO(absolute_bad)) + if os.altsep: + absolute_bad_bs = absolute_bad.replace(b'/', b'\\') + with self.assertRaisesRegex(uu.Error, 'directory'): + uu.decode(io.BytesIO(absolute_bad_bs)) + + class UUStdIOTest(unittest.TestCase): def setUp(self): diff --git a/Lib/test/test_uuid.py b/Lib/test/test_uuid.py index 411eec0f..9cec1e87 100755 --- a/Lib/test/test_uuid.py +++ b/Lib/test/test_uuid.py @@ -600,7 +600,22 @@ class BaseTestUUID: def test_uuid3(self): equal = self.assertEqual - # Test some known version-3 UUIDs. + # Test some known version-3 UUIDs with name passed as a byte object + for u, v in [(self.uuid.uuid3(self.uuid.NAMESPACE_DNS, b'python.org'), + '6fa459ea-ee8a-3ca4-894e-db77e160355e'), + (self.uuid.uuid3(self.uuid.NAMESPACE_URL, b'http://python.org/'), + '9fe8e8c4-aaa8-32a9-a55c-4535a88b748d'), + (self.uuid.uuid3(self.uuid.NAMESPACE_OID, b'1.3.6.1'), + 'dd1a1cef-13d5-368a-ad82-eca71acd4cd1'), + (self.uuid.uuid3(self.uuid.NAMESPACE_X500, b'c=ca'), + '658d3002-db6b-3040-a1d1-8ddd7d189a4d'), + ]: + equal(u.variant, self.uuid.RFC_4122) + equal(u.version, 3) + equal(u, self.uuid.UUID(v)) + equal(str(u), v) + + # Test some known version-3 UUIDs with name passed as a string for u, v in [(self.uuid.uuid3(self.uuid.NAMESPACE_DNS, 'python.org'), '6fa459ea-ee8a-3ca4-894e-db77e160355e'), (self.uuid.uuid3(self.uuid.NAMESPACE_URL, 'http://python.org/'), @@ -632,7 +647,22 @@ class BaseTestUUID: def test_uuid5(self): equal = self.assertEqual - # Test some known version-5 UUIDs. + # Test some known version-5 UUIDs with names given as byte objects + for u, v in [(self.uuid.uuid5(self.uuid.NAMESPACE_DNS, b'python.org'), + '886313e1-3b8a-5372-9b90-0c9aee199e5d'), + (self.uuid.uuid5(self.uuid.NAMESPACE_URL, b'http://python.org/'), + '4c565f0d-3f5a-5890-b41b-20cf47701c5e'), + (self.uuid.uuid5(self.uuid.NAMESPACE_OID, b'1.3.6.1'), + '1447fa61-5277-5fef-a9b3-fbc6e44f4af3'), + (self.uuid.uuid5(self.uuid.NAMESPACE_X500, b'c=ca'), + 'cc957dd1-a972-5349-98cd-874190002798'), + ]: + equal(u.variant, self.uuid.RFC_4122) + equal(u.version, 5) + equal(u, self.uuid.UUID(v)) + equal(str(u), v) + + # Test some known version-5 UUIDs with names given as strings for u, v in [(self.uuid.uuid5(self.uuid.NAMESPACE_DNS, 'python.org'), '886313e1-3b8a-5372-9b90-0c9aee199e5d'), (self.uuid.uuid5(self.uuid.NAMESPACE_URL, 'http://python.org/'), @@ -675,6 +705,67 @@ class BaseTestUUID: weak = weakref.ref(strong) self.assertIs(strong, weak()) + @mock.patch.object(sys, "argv", ["", "-u", "uuid3", "-n", "@dns"]) + @mock.patch('sys.stderr', new_callable=io.StringIO) + def test_cli_namespace_required_for_uuid3(self, mock_err): + with self.assertRaises(SystemExit) as cm: + self.uuid.main() + + # Check that exception code is the same as argparse.ArgumentParser.error + self.assertEqual(cm.exception.code, 2) + self.assertIn("error: Incorrect number of arguments", mock_err.getvalue()) + + @mock.patch.object(sys, "argv", ["", "-u", "uuid3", "-N", "python.org"]) + @mock.patch('sys.stderr', new_callable=io.StringIO) + def test_cli_name_required_for_uuid3(self, mock_err): + with self.assertRaises(SystemExit) as cm: + self.uuid.main() + # Check that exception code is the same as argparse.ArgumentParser.error + self.assertEqual(cm.exception.code, 2) + self.assertIn("error: Incorrect number of arguments", mock_err.getvalue()) + + @mock.patch.object(sys, "argv", [""]) + def test_cli_uuid4_outputted_with_no_args(self): + stdout = io.StringIO() + with contextlib.redirect_stdout(stdout): + self.uuid.main() + + output = stdout.getvalue().strip() + uuid_output = self.uuid.UUID(output) + + # Output uuid should be in the format of uuid4 + self.assertEqual(output, str(uuid_output)) + self.assertEqual(uuid_output.version, 4) + + @mock.patch.object(sys, "argv", + ["", "-u", "uuid3", "-n", "@dns", "-N", "python.org"]) + def test_cli_uuid3_ouputted_with_valid_namespace_and_name(self): + stdout = io.StringIO() + with contextlib.redirect_stdout(stdout): + self.uuid.main() + + output = stdout.getvalue().strip() + uuid_output = self.uuid.UUID(output) + + # Output should be in the form of uuid5 + self.assertEqual(output, str(uuid_output)) + self.assertEqual(uuid_output.version, 3) + + @mock.patch.object(sys, "argv", + ["", "-u", "uuid5", "-n", "@dns", "-N", "python.org"]) + def test_cli_uuid5_ouputted_with_valid_namespace_and_name(self): + stdout = io.StringIO() + with contextlib.redirect_stdout(stdout): + self.uuid.main() + + output = stdout.getvalue().strip() + uuid_output = self.uuid.UUID(output) + + # Output should be in the form of uuid5 + self.assertEqual(output, str(uuid_output)) + self.assertEqual(uuid_output.version, 5) + + class TestUUIDWithoutExtModule(BaseTestUUID, unittest.TestCase): uuid = py_uuid diff --git a/Lib/test/test_venv.py b/Lib/test/test_venv.py index 86ce60fe..aa6a8fbf 100644 --- a/Lib/test/test_venv.py +++ b/Lib/test/test_venv.py @@ -17,10 +17,11 @@ import subprocess import sys import sysconfig import tempfile -from test.support import (captured_stdout, captured_stderr, requires_zlib, +from test.support import (captured_stdout, captured_stderr, skip_if_broken_multiprocessing_synchronize, verbose, requires_subprocess, is_emscripten, is_wasi, - requires_venv_with_pip, TEST_HOME_DIR) + requires_venv_with_pip, TEST_HOME_DIR, + requires_resource) from test.support.os_helper import (can_symlink, EnvironmentVarGuard, rmtree) import unittest import venv @@ -227,7 +228,6 @@ class BasicTest(BaseTest): 'install', '--upgrade', 'pip', - 'setuptools' ] ) @@ -601,9 +601,14 @@ class BasicTest(BaseTest): ld_library_path_env = "DYLD_LIBRARY_PATH" else: ld_library_path_env = "LD_LIBRARY_PATH" - subprocess.check_call(cmd, - env={"PYTHONPATH": pythonpath, - ld_library_path_env: ld_library_path}) + child_env = { + "PYTHONPATH": pythonpath, + ld_library_path_env: ld_library_path, + } + if asan_options := os.environ.get("ASAN_OPTIONS"): + # prevent https://github.com/python/cpython/issues/104839 + child_env["ASAN_OPTIONS"] = asan_options + subprocess.check_call(cmd, env=child_env) envpy = os.path.join(self.env_dir, self.bindir, self.exe) # Now check the venv created from the non-installed python has # correct zip path in pythonpath. @@ -611,6 +616,22 @@ class BasicTest(BaseTest): out, err = check_output(cmd) self.assertTrue(zip_landmark.encode() in out) + def test_activate_shell_script_has_no_dos_newlines(self): + """ + Test that the `activate` shell script contains no CR LF. + This is relevant for Cygwin, as the Windows build might have + converted line endings accidentally. + """ + venv_dir = pathlib.Path(self.env_dir) + rmtree(venv_dir) + [[scripts_dir], *_] = self.ENV_SUBDIRS + script_path = venv_dir / scripts_dir / "activate" + venv.create(venv_dir) + with open(script_path, 'rb') as script: + for i, line in enumerate(script, 1): + error_message = f"CR LF found in line {i}" + self.assertFalse(line.endswith(b'\r\n'), error_message) + @requireVenvCreate class EnsurePipTest(BaseTest): """Test venv module installation of pip.""" @@ -729,7 +750,6 @@ class EnsurePipTest(BaseTest): # future pip versions, this test can likely be relaxed further. out = out.decode("latin-1") # Force to text, prevent decoding errors self.assertIn("Successfully uninstalled pip", out) - self.assertIn("Successfully uninstalled setuptools", out) # Check pip is now gone from the virtual environment. This only # applies in the system_site_packages=False case, because in the # other case, pip may still be available in the system site-packages @@ -756,6 +776,7 @@ class EnsurePipTest(BaseTest): ) @requires_venv_with_pip() + @requires_resource('cpu') def test_with_pip(self): self.do_test_with_pip(False) self.do_test_with_pip(True) diff --git a/Lib/test/test_wait3.py b/Lib/test/test_wait3.py index 4ec7690a..eae885a6 100644 --- a/Lib/test/test_wait3.py +++ b/Lib/test/test_wait3.py @@ -4,7 +4,6 @@ import os import subprocess import sys -import time import unittest from test.fork_wait import ForkWait from test import support @@ -20,14 +19,12 @@ class Wait3Test(ForkWait): # This many iterations can be required, since some previously run # tests (e.g. test_ctypes) could have spawned a lot of children # very quickly. - deadline = time.monotonic() + support.SHORT_TIMEOUT - while time.monotonic() <= deadline: + for _ in support.sleeping_retry(support.SHORT_TIMEOUT): # wait3() shouldn't hang, but some of the buildbots seem to hang # in the forking tests. This is an attempt to fix the problem. spid, status, rusage = os.wait3(os.WNOHANG) if spid == cpid: break - time.sleep(0.1) self.assertEqual(spid, cpid) self.assertEqual(os.waitstatus_to_exitcode(status), exitcode) diff --git a/Lib/test/test_wait4.py b/Lib/test/test_wait4.py index 24f1aaec..67afab1d 100644 --- a/Lib/test/test_wait4.py +++ b/Lib/test/test_wait4.py @@ -2,7 +2,6 @@ """ import os -import time import sys import unittest from test.fork_wait import ForkWait @@ -22,14 +21,12 @@ class Wait4Test(ForkWait): # Issue #11185: wait4 is broken on AIX and will always return 0 # with WNOHANG. option = 0 - deadline = time.monotonic() + support.SHORT_TIMEOUT - while time.monotonic() <= deadline: + for _ in support.sleeping_retry(support.SHORT_TIMEOUT): # wait4() shouldn't hang, but some of the buildbots seem to hang # in the forking tests. This is an attempt to fix the problem. spid, status, rusage = os.wait4(cpid, option) if spid == cpid: break - time.sleep(0.1) self.assertEqual(spid, cpid) self.assertEqual(os.waitstatus_to_exitcode(status), exitcode) self.assertTrue(rusage) diff --git a/Lib/test/test_warnings/__init__.py b/Lib/test/test_warnings/__init__.py index 61a64440..83237f5f 100644 --- a/Lib/test/test_warnings/__init__.py +++ b/Lib/test/test_warnings/__init__.py @@ -12,6 +12,7 @@ from test.support import os_helper from test.support import warnings_helper from test.support.script_helper import assert_python_ok, assert_python_failure +from test.test_warnings.data import package_helper from test.test_warnings.data import stacklevel as warning_tests import warnings as original_warnings @@ -22,8 +23,6 @@ py_warnings = import_helper.import_fresh_module('warnings', c_warnings = import_helper.import_fresh_module('warnings', fresh=['_warnings']) -Py_DEBUG = hasattr(sys, 'gettotalrefcount') - @contextmanager def warnings_state(module): """Use a specific warnings implementation in warning_tests.""" @@ -388,9 +387,13 @@ class FilterTests(BaseTest): with self.module.catch_warnings( module=self.module, action="error", category=FutureWarning ): - self.module.warn("Other types of warnings are not errors") - self.assertRaises(FutureWarning, - self.module.warn, FutureWarning("msg")) + with support.captured_stderr() as stderr: + error_msg = "Other types of warnings are not errors" + self.module.warn(error_msg) + self.assertRaises(FutureWarning, + self.module.warn, FutureWarning("msg")) + stderr = stderr.getvalue() + self.assertIn(error_msg, stderr) class CFilterTests(FilterTests, unittest.TestCase): module = c_warnings @@ -474,6 +477,42 @@ class WarnTests(BaseTest): self.assertEqual(len(w), 1) self.assertEqual(w[0].filename, __file__) + def test_skip_file_prefixes(self): + with warnings_state(self.module): + with original_warnings.catch_warnings(record=True, + module=self.module) as w: + self.module.simplefilter('always') + + # Warning never attributed to the data/ package. + package_helper.inner_api( + "inner_api", stacklevel=2, + warnings_module=warning_tests.warnings) + self.assertEqual(w[-1].filename, __file__) + warning_tests.package("package api", stacklevel=2) + self.assertEqual(w[-1].filename, __file__) + self.assertEqual(w[-2].filename, w[-1].filename) + # Low stacklevels are overridden to 2 behavior. + warning_tests.package("package api 1", stacklevel=1) + self.assertEqual(w[-1].filename, __file__) + warning_tests.package("package api 0", stacklevel=0) + self.assertEqual(w[-1].filename, __file__) + warning_tests.package("package api -99", stacklevel=-99) + self.assertEqual(w[-1].filename, __file__) + + # The stacklevel still goes up out of the package. + warning_tests.package("prefix02", stacklevel=3) + self.assertIn("unittest", w[-1].filename) + + def test_skip_file_prefixes_type_errors(self): + with warnings_state(self.module): + warn = warning_tests.warnings.warn + with self.assertRaises(TypeError): + warn("msg", skip_file_prefixes=[]) + with self.assertRaises(TypeError): + warn("msg", skip_file_prefixes=(b"bytes",)) + with self.assertRaises(TypeError): + warn("msg", skip_file_prefixes="a sequence of strs") + def test_exec_filename(self): filename = "<warnings-test>" codeobj = compile(("import warnings\n" @@ -897,7 +936,7 @@ class WarningsDisplayTests(BaseTest): message = "msg" category = Warning file_name = os.path.splitext(warning_tests.__file__)[0] + '.py' - line_num = 3 + line_num = 5 file_line = linecache.getline(file_name, line_num).strip() format = "%s:%s: %s: %s\n %s\n" expect = format % (file_name, line_num, category.__name__, message, @@ -1198,7 +1237,7 @@ class EnvironmentVariableTests(BaseTest): def test_default_filter_configuration(self): pure_python_api = self.module is py_warnings - if Py_DEBUG: + if support.Py_DEBUG: expected_default_filters = [] else: if pure_python_api: diff --git a/Lib/test/test_warnings/data/package_helper.py b/Lib/test/test_warnings/data/package_helper.py new file mode 100644 index 00000000..c22a4f64 --- /dev/null +++ b/Lib/test/test_warnings/data/package_helper.py @@ -0,0 +1,10 @@ +# helper to the helper for testing skip_file_prefixes. + +import os + +package_path = os.path.dirname(__file__) + +def inner_api(message, *, stacklevel, warnings_module): + warnings_module.warn( + message, stacklevel=stacklevel, + skip_file_prefixes=(package_path,)) diff --git a/Lib/test/test_warnings/data/stacklevel.py b/Lib/test/test_warnings/data/stacklevel.py index d0519eff..c6dd2473 100644 --- a/Lib/test/test_warnings/data/stacklevel.py +++ b/Lib/test/test_warnings/data/stacklevel.py @@ -1,9 +1,15 @@ -# Helper module for testing the skipmodules argument of warnings.warn() +# Helper module for testing stacklevel and skip_file_prefixes arguments +# of warnings.warn() import warnings +from test.test_warnings.data import package_helper def outer(message, stacklevel=1): inner(message, stacklevel) def inner(message, stacklevel=1): warnings.warn(message, stacklevel=stacklevel) + +def package(message, *, stacklevel): + package_helper.inner_api(message, stacklevel=stacklevel, + warnings_module=warnings) diff --git a/Lib/test/test_wave.py b/Lib/test/test_wave.py index 0cc94e88..6c336285 100644 --- a/Lib/test/test_wave.py +++ b/Lib/test/test_wave.py @@ -77,6 +77,33 @@ class WavePCM24Test(WaveTest, unittest.TestCase): frames = wave._byteswap(frames, 3) +class WavePCM24ExtTest(WaveTest, unittest.TestCase): + sndfilename = 'pluck-pcm24-ext.wav' + sndfilenframes = 3307 + nchannels = 2 + sampwidth = 3 + framerate = 11025 + nframes = 48 + comptype = 'NONE' + compname = 'not compressed' + frames = bytes.fromhex("""\ + 022D65FFEB9D 4B5A0F00FA54 3113C304EE2B 80DCD6084303 \ + CBDEC006B261 48A99803F2F8 BFE82401B07D 036BFBFE7B5D \ + B85756FA3EC9 B4B055F3502B 299830EBCB62 1A5CA7E6D99A \ + EDFA3EE491BD C625EBE27884 0E05A9E0B6CF EF2929E02922 \ + 5758D8E27067 FB3557E83E16 1377BFEF8402 D82C5BF7272A \ + 978F16FB7745 F5F865FC1013 086635FB9C4E DF30FCFB40EE \ + 117FE0FA3438 3EE6B8FB5AC3 BC77A3FCB2F4 66D6DAFF5F32 \ + CF13B9041275 431D69097A8C C1BB600EC74E 5120B912A2BA \ + EEDF641754C0 8207001664B7 7FFFFF14453F 8000001294E6 \ + 499C1B0EB3B2 52B73E0DBCA0 EFB2B20F5FD8 CE3CDB0FBE12 \ + E4B49C0CEA2D 6344A80A5A7C 08C8FE0A1FFE 2BB9860B0A0E \ + 51486F0E44E1 8BCC64113B05 B6F4EC0EEB36 4413170A5B48 \ + """) + if sys.byteorder != 'big': + frames = wave._byteswap(frames, 3) + + class WavePCM32Test(WaveTest, unittest.TestCase): sndfilename = 'pluck-pcm32.wav' sndfilenframes = 3307 @@ -106,7 +133,8 @@ class WavePCM32Test(WaveTest, unittest.TestCase): class MiscTestCase(unittest.TestCase): def test__all__(self): - support.check__all__(self, wave, not_exported={'WAVE_FORMAT_PCM'}) + not_exported = {'WAVE_FORMAT_PCM', 'WAVE_FORMAT_EXTENSIBLE', 'KSDATAFORMAT_SUBTYPE_PCM'} + support.check__all__(self, wave, not_exported=not_exported) class WaveLowLevelTest(unittest.TestCase): diff --git a/Lib/test/test_weakref.py b/Lib/test/test_weakref.py index 7c592079..4cdd66d3 100644 --- a/Lib/test/test_weakref.py +++ b/Lib/test/test_weakref.py @@ -116,6 +116,17 @@ class ReferencesTestCase(TestBase): del o repr(wr) + def test_repr_failure_gh99184(self): + class MyConfig(dict): + def __getattr__(self, x): + return self[x] + + obj = MyConfig(offset=5) + obj_weakref = weakref.ref(obj) + + self.assertIn('MyConfig', repr(obj_weakref)) + self.assertIn('MyConfig', str(obj_weakref)) + def test_basic_callback(self): self.check_basic_callback(C) self.check_basic_callback(create_function) @@ -1922,6 +1933,7 @@ class MappingTestCase(TestBase): self.check_threaded_weak_dict_copy(weakref.WeakKeyDictionary, False) @threading_helper.requires_working_threading() + @support.requires_resource('cpu') def test_threaded_weak_key_dict_deepcopy(self): # Issue #35615: Weakref keys or values getting GC'ed during dict # copying should not result in a crash. @@ -1934,6 +1946,7 @@ class MappingTestCase(TestBase): self.check_threaded_weak_dict_copy(weakref.WeakValueDictionary, False) @threading_helper.requires_working_threading() + @support.requires_resource('cpu') def test_threaded_weak_value_dict_deepcopy(self): # Issue #35615: Weakref keys or values getting GC'ed during dict # copying should not result in a crash. diff --git a/Lib/test/test_webbrowser.py b/Lib/test/test_webbrowser.py index 9d608d63..2d695bc8 100644 --- a/Lib/test/test_webbrowser.py +++ b/Lib/test/test_webbrowser.py @@ -11,7 +11,7 @@ from test.support import os_helper if not support.has_subprocess_support: raise unittest.SkipTest("test webserver requires subprocess") -URL = 'http://www.example.com' +URL = 'https://www.example.com' CMD_NAME = 'test' @@ -95,9 +95,9 @@ class ChromeCommandTest(CommandTestMixin, unittest.TestCase): arguments=[URL]) -class MozillaCommandTest(CommandTestMixin, unittest.TestCase): +class EdgeCommandTest(CommandTestMixin, unittest.TestCase): - browser_class = webbrowser.Mozilla + browser_class = webbrowser.Edge def test_open(self): self._test('open', @@ -111,43 +111,43 @@ class MozillaCommandTest(CommandTestMixin, unittest.TestCase): def test_open_new(self): self._test('open_new', - options=[], - arguments=['-new-window', URL]) + options=['--new-window'], + arguments=[URL]) def test_open_new_tab(self): self._test('open_new_tab', options=[], - arguments=['-new-tab', URL]) + arguments=[URL]) -class NetscapeCommandTest(CommandTestMixin, unittest.TestCase): +class MozillaCommandTest(CommandTestMixin, unittest.TestCase): - browser_class = webbrowser.Netscape + browser_class = webbrowser.Mozilla def test_open(self): self._test('open', - options=['-raise', '-remote'], - arguments=['openURL({})'.format(URL)]) + options=[], + arguments=[URL]) def test_open_with_autoraise_false(self): self._test('open', kw=dict(autoraise=False), - options=['-noraise', '-remote'], - arguments=['openURL({})'.format(URL)]) + options=[], + arguments=[URL]) def test_open_new(self): self._test('open_new', - options=['-raise', '-remote'], - arguments=['openURL({},new-window)'.format(URL)]) + options=[], + arguments=['-new-window', URL]) def test_open_new_tab(self): self._test('open_new_tab', - options=['-raise', '-remote'], - arguments=['openURL({},new-tab)'.format(URL)]) + options=[], + arguments=['-new-tab', URL]) -class GaleonCommandTest(CommandTestMixin, unittest.TestCase): +class EpiphanyCommandTest(CommandTestMixin, unittest.TestCase): - browser_class = webbrowser.Galeon + browser_class = webbrowser.Epiphany def test_open(self): self._test('open', diff --git a/Lib/test/test_winreg.py b/Lib/test/test_winreg.py index 769ab67b..924a9627 100644 --- a/Lib/test/test_winreg.py +++ b/Lib/test/test_winreg.py @@ -1,11 +1,12 @@ # Test the windows specific win32reg module. # Only win32reg functions not hit here: FlushKey, LoadKey and SaveKey +import gc import os, sys, errno -import unittest -from test.support import import_helper import threading +import unittest from platform import machine, win32_edition +from test.support import cpython_only, import_helper # Do this first so test will be skipped if module doesn't exist import_helper.import_module('winreg', required_on=['win']) @@ -49,6 +50,17 @@ test_data = [ ("Japanese 日本", "日本語", REG_SZ), ] + +@cpython_only +class HeapTypeTests(unittest.TestCase): + def test_have_gc(self): + self.assertTrue(gc.is_tracked(HKEYType)) + + def test_immutable(self): + with self.assertRaisesRegex(TypeError, "immutable"): + HKEYType.foo = "bar" + + class BaseWinregTests(unittest.TestCase): def setUp(self): diff --git a/Lib/test/test_winsound.py b/Lib/test/test_winsound.py index 3c3359b9..a59d0d24 100644 --- a/Lib/test/test_winsound.py +++ b/Lib/test/test_winsound.py @@ -1,6 +1,7 @@ # Ridiculously simple test of the winsound module for Windows. import functools +import pathlib import time import unittest @@ -84,6 +85,13 @@ class MessageBeepTest(unittest.TestCase): safe_MessageBeep(type=winsound.MB_OK) +# A class for testing winsound when the given path resolves +# to bytes rather than str. +class BytesPath(pathlib.WindowsPath): + def __fspath__(self): + return bytes(super().__fspath__(), 'UTF-8') + + class PlaySoundTest(unittest.TestCase): def test_errors(self): @@ -116,6 +124,20 @@ class PlaySoundTest(unittest.TestCase): fn = support.findfile('pluck-pcm8.wav', subdir='audiodata') safe_PlaySound(fn, winsound.SND_FILENAME | winsound.SND_NODEFAULT) + def test_snd_filepath(self): + fn = support.findfile('pluck-pcm8.wav', subdir='audiodata') + path = pathlib.Path(fn) + safe_PlaySound(path, winsound.SND_FILENAME | winsound.SND_NODEFAULT) + + def test_snd_filepath_as_bytes(self): + fn = support.findfile('pluck-pcm8.wav', subdir='audiodata') + self.assertRaises( + TypeError, + winsound.PlaySound, + BytesPath(fn), + winsound.SND_FILENAME | winsound.SND_NODEFAULT + ) + def test_aliases(self): aliases = [ "SystemAsterisk", diff --git a/Lib/test/test_with.py b/Lib/test/test_with.py index 07522bda..d8190232 100644 --- a/Lib/test/test_with.py +++ b/Lib/test/test_with.py @@ -79,11 +79,11 @@ class Nested(object): try: if mgr.__exit__(*ex): ex = (None, None, None) - except: - ex = sys.exc_info() + except BaseException as e: + ex = (type(e), e, e.__traceback__) self.entered = None if ex is not exc_info: - raise ex[0](ex[1]).with_traceback(ex[2]) + raise ex class MockNested(Nested): diff --git a/Lib/test/test_wmi.py b/Lib/test/test_wmi.py new file mode 100644 index 00000000..34457028 --- /dev/null +++ b/Lib/test/test_wmi.py @@ -0,0 +1,74 @@ +# Test the internal _wmi module on Windows +# This is used by the platform module, and potentially others + +import unittest +from test.support import import_helper, requires_resource + + +# Do this first so test will be skipped if module doesn't exist +_wmi = import_helper.import_module('_wmi', required_on=['win']) + + +class WmiTests(unittest.TestCase): + def test_wmi_query_os_version(self): + r = _wmi.exec_query("SELECT Version FROM Win32_OperatingSystem").split("\0") + self.assertEqual(1, len(r)) + k, eq, v = r[0].partition("=") + self.assertEqual("=", eq, r[0]) + self.assertEqual("Version", k, r[0]) + # Best we can check for the version is that it's digits, dot, digits, anything + # Otherwise, we are likely checking the result of the query against itself + self.assertRegex(v, r"\d+\.\d+.+$", r[0]) + + def test_wmi_query_repeated(self): + # Repeated queries should not break + for _ in range(10): + self.test_wmi_query_os_version() + + def test_wmi_query_error(self): + # Invalid queries fail with OSError + try: + _wmi.exec_query("SELECT InvalidColumnName FROM InvalidTableName") + except OSError as ex: + if ex.winerror & 0xFFFFFFFF == 0x80041010: + # This is the expected error code. All others should fail the test + return + self.fail("Expected OSError") + + def test_wmi_query_repeated_error(self): + for _ in range(10): + self.test_wmi_query_error() + + def test_wmi_query_not_select(self): + # Queries other than SELECT are blocked to avoid potential exploits + with self.assertRaises(ValueError): + _wmi.exec_query("not select, just in case someone tries something") + + @requires_resource('cpu') + def test_wmi_query_overflow(self): + # Ensure very big queries fail + # Test multiple times to ensure consistency + for _ in range(2): + with self.assertRaises(OSError): + _wmi.exec_query("SELECT * FROM CIM_DataFile") + + def test_wmi_query_multiple_rows(self): + # Multiple instances should have an extra null separator + r = _wmi.exec_query("SELECT ProcessId FROM Win32_Process WHERE ProcessId < 1000") + self.assertFalse(r.startswith("\0"), r) + self.assertFalse(r.endswith("\0"), r) + it = iter(r.split("\0")) + try: + while True: + self.assertRegex(next(it), r"ProcessId=\d+") + self.assertEqual("", next(it)) + except StopIteration: + pass + + def test_wmi_query_threads(self): + from concurrent.futures import ThreadPoolExecutor + query = "SELECT ProcessId FROM Win32_Process WHERE ProcessId < 1000" + with ThreadPoolExecutor(4) as pool: + task = [pool.submit(_wmi.exec_query, query) for _ in range(32)] + for t in task: + self.assertRegex(t.result(), "ProcessId=") diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py index 63b6725a..3cde6ef5 100644 --- a/Lib/test/test_xml_etree.py +++ b/Lib/test/test_xml_etree.py @@ -203,25 +203,6 @@ class ElementTreeTest(unittest.TestCase): def test_interface(self): # Test element tree interface. - def check_string(string): - len(string) - for char in string: - self.assertEqual(len(char), 1, - msg="expected one-character string, got %r" % char) - new_string = string + "" - new_string = string + " " - string[:0] - - def check_mapping(mapping): - len(mapping) - keys = mapping.keys() - items = mapping.items() - for key in keys: - item = mapping[key] - mapping["key"] = "value" - self.assertEqual(mapping["key"], "value", - msg="expected value string, got %r" % mapping["key"]) - def check_element(element): self.assertTrue(ET.iselement(element), msg="not an element") direlem = dir(element) @@ -231,12 +212,12 @@ class ElementTreeTest(unittest.TestCase): self.assertIn(attr, direlem, msg='no %s visible by dir' % attr) - check_string(element.tag) - check_mapping(element.attrib) + self.assertIsInstance(element.tag, str) + self.assertIsInstance(element.attrib, dict) if element.text is not None: - check_string(element.text) + self.assertIsInstance(element.text, str) if element.tail is not None: - check_string(element.tail) + self.assertIsInstance(element.tail, str) for elem in element: check_element(elem) @@ -384,6 +365,7 @@ class ElementTreeTest(unittest.TestCase): from xml.etree import ElementPath elem = ET.XML(SAMPLE_XML) + ElementPath._cache.clear() for i in range(10): ET.ElementTree(elem).find('./'+str(i)) cache_len_10 = len(ElementPath._cache) for i in range(10): ET.ElementTree(elem).find('./'+str(i)) @@ -2333,35 +2315,6 @@ class BasicElementTest(ElementTestCase, unittest.TestCase): self.assertIsNot(element_foo.attrib, attrib) self.assertNotEqual(element_foo.attrib, attrib) - def test_copy(self): - # Only run this test if Element.copy() is defined. - if "copy" not in dir(ET.Element): - raise unittest.SkipTest("Element.copy() not present") - - element_foo = ET.Element("foo", { "zix": "wyp" }) - element_foo.append(ET.Element("bar", { "baz": "qix" })) - - with self.assertWarns(DeprecationWarning): - element_foo2 = element_foo.copy() - - # elements are not the same - self.assertIsNot(element_foo2, element_foo) - - # string attributes are equal - self.assertEqual(element_foo2.tag, element_foo.tag) - self.assertEqual(element_foo2.text, element_foo.text) - self.assertEqual(element_foo2.tail, element_foo.tail) - - # number of children is the same - self.assertEqual(len(element_foo2), len(element_foo)) - - # children are the same - for (child1, child2) in itertools.zip_longest(element_foo, element_foo2): - self.assertIs(child1, child2) - - # attrib is a copy - self.assertEqual(element_foo2.attrib, element_foo.attrib) - def test___copy__(self): element_foo = ET.Element("foo", { "zix": "wyp" }) element_foo.append(ET.Element("bar", { "baz": "qix" })) @@ -3974,8 +3927,9 @@ class KeywordArgsTest(unittest.TestCase): # -------------------------------------------------------------------- class NoAcceleratorTest(unittest.TestCase): - def setUp(self): - if not pyET: + @classmethod + def setUpClass(cls): + if ET is not pyET: raise unittest.SkipTest('only for the Python version') # Test that the C accelerator was not imported for pyET @@ -3986,6 +3940,25 @@ class NoAcceleratorTest(unittest.TestCase): self.assertIsInstance(pyET.Element.__init__, types.FunctionType) self.assertIsInstance(pyET.XMLParser.__init__, types.FunctionType) +# -------------------------------------------------------------------- + +class BoolTest(unittest.TestCase): + def test_warning(self): + e = ET.fromstring('<a style="new"></a>') + msg = ( + r"Testing an element's truth value will raise an exception in " + r"future versions. " + r"Use specific 'len\(elem\)' or 'elem is not None' test instead.") + with self.assertWarnsRegex(DeprecationWarning, msg): + result = bool(e) + # Emulate prior behavior for now + self.assertIs(result, False) + + # Element with children + ET.SubElement(e, 'b') + with self.assertWarnsRegex(DeprecationWarning, msg): + new_result = bool(e) + self.assertIs(new_result, True) # -------------------------------------------------------------------- @@ -4221,8 +4194,7 @@ class C14NTest(unittest.TestCase): # -------------------------------------------------------------------- - -def test_main(module=None): +def setUpModule(module=None): # When invoked without a module, runs the Python ET tests by loading pyET. # Otherwise, uses the given module as the ET. global pyET @@ -4234,62 +4206,30 @@ def test_main(module=None): global ET ET = module - test_classes = [ - ModuleTest, - ElementSlicingTest, - BasicElementTest, - BadElementTest, - BadElementPathTest, - ElementTreeTest, - IOTest, - ParseErrorTest, - XIncludeTest, - ElementTreeTypeTest, - ElementFindTest, - ElementIterTest, - TreeBuilderTest, - XMLParserTest, - XMLPullParserTest, - BugsTest, - KeywordArgsTest, - C14NTest, - ] - - # These tests will only run for the pure-Python version that doesn't import - # _elementtree. We can't use skipUnless here, because pyET is filled in only - # after the module is loaded. - if pyET is not ET: - test_classes.extend([ - NoAcceleratorTest, - ]) + # don't interfere with subsequent tests + def cleanup(): + global ET, pyET + ET = pyET = None + unittest.addModuleCleanup(cleanup) # Provide default namespace mapping and path cache. from xml.etree import ElementPath nsmap = ET.register_namespace._namespace_map # Copy the default namespace mapping nsmap_copy = nsmap.copy() + unittest.addModuleCleanup(nsmap.update, nsmap_copy) + unittest.addModuleCleanup(nsmap.clear) + # Copy the path cache (should be empty) path_cache = ElementPath._cache + unittest.addModuleCleanup(setattr, ElementPath, "_cache", path_cache) ElementPath._cache = path_cache.copy() + # Align the Comment/PI factories. if hasattr(ET, '_set_factories'): old_factories = ET._set_factories(ET.Comment, ET.PI) - else: - old_factories = None - - try: - support.run_unittest(*test_classes) - finally: - from xml.etree import ElementPath - # Restore mapping and path cache - nsmap.clear() - nsmap.update(nsmap_copy) - ElementPath._cache = path_cache - if old_factories is not None: - ET._set_factories(*old_factories) - # don't interfere with subsequent tests - ET = pyET = None + unittest.addModuleCleanup(ET._set_factories, *old_factories) if __name__ == '__main__': - test_main() + unittest.main() diff --git a/Lib/test/test_xml_etree_c.py b/Lib/test/test_xml_etree_c.py index bec82085..3a0fc572 100644 --- a/Lib/test/test_xml_etree_c.py +++ b/Lib/test/test_xml_etree_c.py @@ -181,6 +181,26 @@ class MiscTests(unittest.TestCase): r = e.get(X()) self.assertIsNone(r) + @support.cpython_only + def test_immutable_types(self): + root = cET.fromstring('<a></a>') + dataset = ( + cET.Element, + cET.TreeBuilder, + cET.XMLParser, + type(root.iter()), + ) + for tp in dataset: + with self.subTest(tp=tp): + with self.assertRaisesRegex(TypeError, "immutable"): + tp.foo = 1 + + @support.cpython_only + def test_disallow_instantiation(self): + root = cET.fromstring('<a></a>') + iter_type = type(root.iter()) + support.check_disallow_instantiation(self, iter_type) + @unittest.skipUnless(cET, 'requires _elementtree') class TestAliasWorking(unittest.TestCase): @@ -234,20 +254,25 @@ class SizeofTest(unittest.TestCase): self.check_sizeof(e, self.elementsize + self.extra + struct.calcsize('8P')) -def test_main(): - from test import test_xml_etree - - # Run the tests specific to the C implementation - support.run_unittest( - MiscTests, - TestAliasWorking, - TestAcceleratorImported, - SizeofTest, - ) - # Run the same test suite as the Python module - test_xml_etree.test_main(module=cET) +def install_tests(): + # Test classes should have __module__ referring to this module. + from test import test_xml_etree + for name, base in vars(test_xml_etree).items(): + if isinstance(base, type) and issubclass(base, unittest.TestCase): + class Temp(base): + pass + Temp.__name__ = Temp.__qualname__ = name + Temp.__module__ = __name__ + assert name not in globals() + globals()[name] = Temp + +install_tests() + +def setUpModule(): + from test import test_xml_etree + test_xml_etree.setUpModule(module=cET) if __name__ == '__main__': - test_main() + unittest.main() diff --git a/Lib/test/test_xmlrpc.py b/Lib/test/test_xmlrpc.py index 9ff5545f..7f517dc7 100644 --- a/Lib/test/test_xmlrpc.py +++ b/Lib/test/test_xmlrpc.py @@ -1031,38 +1031,47 @@ class MultiPathServerTestCase(BaseServerTestCase): self.assertEqual(p.add(6,8), 6+8) self.assertRaises(xmlrpclib.Fault, p.pow, 6, 8) + @support.requires_resource('walltime') def test_path3(self): p = xmlrpclib.ServerProxy(URL+"/is/broken") self.assertRaises(xmlrpclib.Fault, p.add, 6, 8) + @support.requires_resource('walltime') def test_invalid_path(self): p = xmlrpclib.ServerProxy(URL+"/invalid") self.assertRaises(xmlrpclib.Fault, p.add, 6, 8) + @support.requires_resource('walltime') def test_path_query_fragment(self): p = xmlrpclib.ServerProxy(URL+"/foo?k=v#frag") self.assertEqual(p.test(), "/foo?k=v#frag") + @support.requires_resource('walltime') def test_path_fragment(self): p = xmlrpclib.ServerProxy(URL+"/foo#frag") self.assertEqual(p.test(), "/foo#frag") + @support.requires_resource('walltime') def test_path_query(self): p = xmlrpclib.ServerProxy(URL+"/foo?k=v") self.assertEqual(p.test(), "/foo?k=v") + @support.requires_resource('walltime') def test_empty_path(self): p = xmlrpclib.ServerProxy(URL) self.assertEqual(p.test(), "/RPC2") + @support.requires_resource('walltime') def test_root_path(self): p = xmlrpclib.ServerProxy(URL + "/") self.assertEqual(p.test(), "/") + @support.requires_resource('walltime') def test_empty_path_query(self): p = xmlrpclib.ServerProxy(URL + "?k=v") self.assertEqual(p.test(), "?k=v") + @support.requires_resource('walltime') def test_empty_path_fragment(self): p = xmlrpclib.ServerProxy(URL + "#frag") self.assertEqual(p.test(), "#frag") diff --git a/Lib/test/test_yield_from.py b/Lib/test/test_yield_from.py index d105d8c6..1a60357a 100644 --- a/Lib/test/test_yield_from.py +++ b/Lib/test/test_yield_from.py @@ -1049,6 +1049,533 @@ class TestPEP380Operation(unittest.TestCase): g.send((1, 2, 3, 4)) self.assertEqual(v, (1, 2, 3, 4)) +class TestInterestingEdgeCases(unittest.TestCase): + + def assert_stop_iteration(self, iterator): + with self.assertRaises(StopIteration) as caught: + next(iterator) + self.assertIsNone(caught.exception.value) + self.assertIsNone(caught.exception.__context__) + + def assert_generator_raised_stop_iteration(self): + return self.assertRaisesRegex(RuntimeError, r"^generator raised StopIteration$") + + def assert_generator_ignored_generator_exit(self): + return self.assertRaisesRegex(RuntimeError, r"^generator ignored GeneratorExit$") + + def test_close_and_throw_work(self): + + yielded_first = object() + yielded_second = object() + returned = object() + + def inner(): + yield yielded_first + yield yielded_second + return returned + + def outer(): + return (yield from inner()) + + with self.subTest("close"): + g = outer() + self.assertIs(next(g), yielded_first) + g.close() + self.assert_stop_iteration(g) + + with self.subTest("throw GeneratorExit"): + g = outer() + self.assertIs(next(g), yielded_first) + thrown = GeneratorExit() + with self.assertRaises(GeneratorExit) as caught: + g.throw(thrown) + self.assertIs(caught.exception, thrown) + self.assertIsNone(caught.exception.__context__) + self.assert_stop_iteration(g) + + with self.subTest("throw StopIteration"): + g = outer() + self.assertIs(next(g), yielded_first) + thrown = StopIteration() + # PEP 479: + with self.assert_generator_raised_stop_iteration() as caught: + g.throw(thrown) + self.assertIs(caught.exception.__context__, thrown) + self.assertIsNone(caught.exception.__context__.__context__) + self.assert_stop_iteration(g) + + with self.subTest("throw BaseException"): + g = outer() + self.assertIs(next(g), yielded_first) + thrown = BaseException() + with self.assertRaises(BaseException) as caught: + g.throw(thrown) + self.assertIs(caught.exception, thrown) + self.assertIsNone(caught.exception.__context__) + self.assert_stop_iteration(g) + + with self.subTest("throw Exception"): + g = outer() + self.assertIs(next(g), yielded_first) + thrown = Exception() + with self.assertRaises(Exception) as caught: + g.throw(thrown) + self.assertIs(caught.exception, thrown) + self.assertIsNone(caught.exception.__context__) + self.assert_stop_iteration(g) + + def test_close_and_throw_raise_generator_exit(self): + + yielded_first = object() + yielded_second = object() + returned = object() + + def inner(): + try: + yield yielded_first + yield yielded_second + return returned + finally: + raise raised + + def outer(): + return (yield from inner()) + + with self.subTest("close"): + g = outer() + self.assertIs(next(g), yielded_first) + raised = GeneratorExit() + # GeneratorExit is suppressed. This is consistent with PEP 342: + # https://peps.python.org/pep-0342/#new-generator-method-close + g.close() + self.assert_stop_iteration(g) + + with self.subTest("throw GeneratorExit"): + g = outer() + self.assertIs(next(g), yielded_first) + raised = GeneratorExit() + thrown = GeneratorExit() + with self.assertRaises(GeneratorExit) as caught: + g.throw(thrown) + # The raised GeneratorExit is suppressed, but the thrown one + # propagates. This is consistent with PEP 380: + # https://peps.python.org/pep-0380/#proposal + self.assertIs(caught.exception, thrown) + self.assertIsNone(caught.exception.__context__) + self.assert_stop_iteration(g) + + with self.subTest("throw StopIteration"): + g = outer() + self.assertIs(next(g), yielded_first) + raised = GeneratorExit() + thrown = StopIteration() + with self.assertRaises(GeneratorExit) as caught: + g.throw(thrown) + self.assertIs(caught.exception, raised) + self.assertIs(caught.exception.__context__, thrown) + self.assertIsNone(caught.exception.__context__.__context__) + self.assert_stop_iteration(g) + + with self.subTest("throw BaseException"): + g = outer() + self.assertIs(next(g), yielded_first) + raised = GeneratorExit() + thrown = BaseException() + with self.assertRaises(GeneratorExit) as caught: + g.throw(thrown) + self.assertIs(caught.exception, raised) + self.assertIs(caught.exception.__context__, thrown) + self.assertIsNone(caught.exception.__context__.__context__) + self.assert_stop_iteration(g) + + with self.subTest("throw Exception"): + g = outer() + self.assertIs(next(g), yielded_first) + raised = GeneratorExit() + thrown = Exception() + with self.assertRaises(GeneratorExit) as caught: + g.throw(thrown) + self.assertIs(caught.exception, raised) + self.assertIs(caught.exception.__context__, thrown) + self.assertIsNone(caught.exception.__context__.__context__) + self.assert_stop_iteration(g) + + def test_close_and_throw_raise_stop_iteration(self): + + yielded_first = object() + yielded_second = object() + returned = object() + + def inner(): + try: + yield yielded_first + yield yielded_second + return returned + finally: + raise raised + + def outer(): + return (yield from inner()) + + with self.subTest("close"): + g = outer() + self.assertIs(next(g), yielded_first) + raised = StopIteration() + # PEP 479: + with self.assert_generator_raised_stop_iteration() as caught: + g.close() + self.assertIs(caught.exception.__context__, raised) + self.assertIsInstance(caught.exception.__context__.__context__, GeneratorExit) + self.assertIsNone(caught.exception.__context__.__context__.__context__) + self.assert_stop_iteration(g) + + with self.subTest("throw GeneratorExit"): + g = outer() + self.assertIs(next(g), yielded_first) + raised = StopIteration() + thrown = GeneratorExit() + # PEP 479: + with self.assert_generator_raised_stop_iteration() as caught: + g.throw(thrown) + self.assertIs(caught.exception.__context__, raised) + # This isn't the same GeneratorExit as thrown! It's the one created + # by calling inner.close(): + self.assertIsInstance(caught.exception.__context__.__context__, GeneratorExit) + self.assertIsNone(caught.exception.__context__.__context__.__context__) + self.assert_stop_iteration(g) + + with self.subTest("throw StopIteration"): + g = outer() + self.assertIs(next(g), yielded_first) + raised = StopIteration() + thrown = StopIteration() + # PEP 479: + with self.assert_generator_raised_stop_iteration() as caught: + g.throw(thrown) + self.assertIs(caught.exception.__context__, raised) + self.assertIs(caught.exception.__context__.__context__, thrown) + self.assertIsNone(caught.exception.__context__.__context__.__context__) + self.assert_stop_iteration(g) + + with self.subTest("throw BaseException"): + g = outer() + self.assertIs(next(g), yielded_first) + raised = StopIteration() + thrown = BaseException() + # PEP 479: + with self.assert_generator_raised_stop_iteration() as caught: + g.throw(thrown) + self.assertIs(caught.exception.__context__, raised) + self.assertIs(caught.exception.__context__.__context__, thrown) + self.assertIsNone(caught.exception.__context__.__context__.__context__) + self.assert_stop_iteration(g) + + with self.subTest("throw Exception"): + g = outer() + self.assertIs(next(g), yielded_first) + raised = StopIteration() + thrown = Exception() + # PEP 479: + with self.assert_generator_raised_stop_iteration() as caught: + g.throw(thrown) + self.assertIs(caught.exception.__context__, raised) + self.assertIs(caught.exception.__context__.__context__, thrown) + self.assertIsNone(caught.exception.__context__.__context__.__context__) + self.assert_stop_iteration(g) + + def test_close_and_throw_raise_base_exception(self): + + yielded_first = object() + yielded_second = object() + returned = object() + + def inner(): + try: + yield yielded_first + yield yielded_second + return returned + finally: + raise raised + + def outer(): + return (yield from inner()) + + with self.subTest("close"): + g = outer() + self.assertIs(next(g), yielded_first) + raised = BaseException() + with self.assertRaises(BaseException) as caught: + g.close() + self.assertIs(caught.exception, raised) + self.assertIsInstance(caught.exception.__context__, GeneratorExit) + self.assertIsNone(caught.exception.__context__.__context__) + self.assert_stop_iteration(g) + + with self.subTest("throw GeneratorExit"): + g = outer() + self.assertIs(next(g), yielded_first) + raised = BaseException() + thrown = GeneratorExit() + with self.assertRaises(BaseException) as caught: + g.throw(thrown) + self.assertIs(caught.exception, raised) + # This isn't the same GeneratorExit as thrown! It's the one created + # by calling inner.close(): + self.assertIsInstance(caught.exception.__context__, GeneratorExit) + self.assertIsNone(caught.exception.__context__.__context__) + self.assert_stop_iteration(g) + + with self.subTest("throw StopIteration"): + g = outer() + self.assertIs(next(g), yielded_first) + raised = BaseException() + thrown = StopIteration() + with self.assertRaises(BaseException) as caught: + g.throw(thrown) + self.assertIs(caught.exception, raised) + self.assertIs(caught.exception.__context__, thrown) + self.assertIsNone(caught.exception.__context__.__context__) + self.assert_stop_iteration(g) + + with self.subTest("throw BaseException"): + g = outer() + self.assertIs(next(g), yielded_first) + raised = BaseException() + thrown = BaseException() + with self.assertRaises(BaseException) as caught: + g.throw(thrown) + self.assertIs(caught.exception, raised) + self.assertIs(caught.exception.__context__, thrown) + self.assertIsNone(caught.exception.__context__.__context__) + self.assert_stop_iteration(g) + + with self.subTest("throw Exception"): + g = outer() + self.assertIs(next(g), yielded_first) + raised = BaseException() + thrown = Exception() + with self.assertRaises(BaseException) as caught: + g.throw(thrown) + self.assertIs(caught.exception, raised) + self.assertIs(caught.exception.__context__, thrown) + self.assertIsNone(caught.exception.__context__.__context__) + self.assert_stop_iteration(g) + + def test_close_and_throw_raise_exception(self): + + yielded_first = object() + yielded_second = object() + returned = object() + + def inner(): + try: + yield yielded_first + yield yielded_second + return returned + finally: + raise raised + + def outer(): + return (yield from inner()) + + with self.subTest("close"): + g = outer() + self.assertIs(next(g), yielded_first) + raised = Exception() + with self.assertRaises(Exception) as caught: + g.close() + self.assertIs(caught.exception, raised) + self.assertIsInstance(caught.exception.__context__, GeneratorExit) + self.assertIsNone(caught.exception.__context__.__context__) + self.assert_stop_iteration(g) + + with self.subTest("throw GeneratorExit"): + g = outer() + self.assertIs(next(g), yielded_first) + raised = Exception() + thrown = GeneratorExit() + with self.assertRaises(Exception) as caught: + g.throw(thrown) + self.assertIs(caught.exception, raised) + # This isn't the same GeneratorExit as thrown! It's the one created + # by calling inner.close(): + self.assertIsInstance(caught.exception.__context__, GeneratorExit) + self.assertIsNone(caught.exception.__context__.__context__) + self.assert_stop_iteration(g) + + with self.subTest("throw StopIteration"): + g = outer() + self.assertIs(next(g), yielded_first) + raised = Exception() + thrown = StopIteration() + with self.assertRaises(Exception) as caught: + g.throw(thrown) + self.assertIs(caught.exception, raised) + self.assertIs(caught.exception.__context__, thrown) + self.assertIsNone(caught.exception.__context__.__context__) + self.assert_stop_iteration(g) + + with self.subTest("throw BaseException"): + g = outer() + self.assertIs(next(g), yielded_first) + raised = Exception() + thrown = BaseException() + with self.assertRaises(Exception) as caught: + g.throw(thrown) + self.assertIs(caught.exception, raised) + self.assertIs(caught.exception.__context__, thrown) + self.assertIsNone(caught.exception.__context__.__context__) + self.assert_stop_iteration(g) + + with self.subTest("throw Exception"): + g = outer() + self.assertIs(next(g), yielded_first) + raised = Exception() + thrown = Exception() + with self.assertRaises(Exception) as caught: + g.throw(thrown) + self.assertIs(caught.exception, raised) + self.assertIs(caught.exception.__context__, thrown) + self.assertIsNone(caught.exception.__context__.__context__) + self.assert_stop_iteration(g) + + def test_close_and_throw_yield(self): + + yielded_first = object() + yielded_second = object() + returned = object() + + def inner(): + try: + yield yielded_first + finally: + yield yielded_second + return returned + + def outer(): + return (yield from inner()) + + with self.subTest("close"): + g = outer() + self.assertIs(next(g), yielded_first) + # No chaining happens. This is consistent with PEP 342: + # https://peps.python.org/pep-0342/#new-generator-method-close + with self.assert_generator_ignored_generator_exit() as caught: + g.close() + self.assertIsNone(caught.exception.__context__) + self.assert_stop_iteration(g) + + with self.subTest("throw GeneratorExit"): + g = outer() + self.assertIs(next(g), yielded_first) + thrown = GeneratorExit() + # No chaining happens. This is consistent with PEP 342: + # https://peps.python.org/pep-0342/#new-generator-method-close + with self.assert_generator_ignored_generator_exit() as caught: + g.throw(thrown) + self.assertIsNone(caught.exception.__context__) + self.assert_stop_iteration(g) + + with self.subTest("throw StopIteration"): + g = outer() + self.assertIs(next(g), yielded_first) + thrown = StopIteration() + self.assertEqual(g.throw(thrown), yielded_second) + # PEP 479: + with self.assert_generator_raised_stop_iteration() as caught: + next(g) + self.assertIs(caught.exception.__context__, thrown) + self.assertIsNone(caught.exception.__context__.__context__) + self.assert_stop_iteration(g) + + with self.subTest("throw BaseException"): + g = outer() + self.assertIs(next(g), yielded_first) + thrown = BaseException() + self.assertEqual(g.throw(thrown), yielded_second) + with self.assertRaises(BaseException) as caught: + next(g) + self.assertIs(caught.exception, thrown) + self.assertIsNone(caught.exception.__context__) + self.assert_stop_iteration(g) + + with self.subTest("throw Exception"): + g = outer() + self.assertIs(next(g), yielded_first) + thrown = Exception() + self.assertEqual(g.throw(thrown), yielded_second) + with self.assertRaises(Exception) as caught: + next(g) + self.assertIs(caught.exception, thrown) + self.assertIsNone(caught.exception.__context__) + self.assert_stop_iteration(g) + + def test_close_and_throw_return(self): + + yielded_first = object() + yielded_second = object() + returned = object() + + def inner(): + try: + yield yielded_first + yield yielded_second + finally: + return returned + + def outer(): + return (yield from inner()) + + with self.subTest("close"): + g = outer() + self.assertIs(next(g), yielded_first) + # StopIteration is suppressed. This is consistent with PEP 342: + # https://peps.python.org/pep-0342/#new-generator-method-close + g.close() + self.assert_stop_iteration(g) + + with self.subTest("throw GeneratorExit"): + g = outer() + self.assertIs(next(g), yielded_first) + thrown = GeneratorExit() + # StopIteration is suppressed. This is consistent with PEP 342: + # https://peps.python.org/pep-0342/#new-generator-method-close + with self.assertRaises(GeneratorExit) as caught: + g.throw(thrown) + self.assertIs(caught.exception, thrown) + self.assertIsNone(caught.exception.__context__) + self.assert_stop_iteration(g) + + with self.subTest("throw StopIteration"): + g = outer() + self.assertIs(next(g), yielded_first) + thrown = StopIteration() + with self.assertRaises(StopIteration) as caught: + g.throw(thrown) + self.assertIs(caught.exception.value, returned) + self.assertIsNone(caught.exception.__context__) + self.assert_stop_iteration(g) + + with self.subTest("throw BaseException"): + g = outer() + self.assertIs(next(g), yielded_first) + thrown = BaseException() + with self.assertRaises(StopIteration) as caught: + g.throw(thrown) + self.assertIs(caught.exception.value, returned) + self.assertIsNone(caught.exception.__context__) + self.assert_stop_iteration(g) + + with self.subTest("throw Exception"): + g = outer() + self.assertIs(next(g), yielded_first) + thrown = Exception() + with self.assertRaises(StopIteration) as caught: + g.throw(thrown) + self.assertIs(caught.exception.value, returned) + self.assertIsNone(caught.exception.__context__) + self.assert_stop_iteration(g) + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_zipapp.py b/Lib/test/test_zipapp.py index 371e6011..f1c6b2d9 100644 --- a/Lib/test/test_zipapp.py +++ b/Lib/test/test_zipapp.py @@ -55,6 +55,22 @@ class ZipAppTest(unittest.TestCase): self.assertIn('foo/', z.namelist()) self.assertIn('bar/', z.namelist()) + def test_create_sorted_archive(self): + # Test that zipapps order their files by name + source = self.tmpdir / 'source' + source.mkdir() + (source / 'zed.py').touch() + (source / 'bin').mkdir() + (source / 'bin' / 'qux').touch() + (source / 'bin' / 'baz').touch() + (source / '__main__.py').touch() + target = io.BytesIO() + zipapp.create_archive(str(source), target) + target.seek(0) + with zipfile.ZipFile(target, 'r') as zf: + self.assertEqual(zf.namelist(), + ["__main__.py", "bin/", "bin/baz", "bin/qux", "zed.py"]) + def test_create_archive_with_filter(self): # Test packing a directory and using filter to specify # which files to include. diff --git a/Lib/test/test_zipfile/__init__.py b/Lib/test/test_zipfile/__init__.py new file mode 100644 index 00000000..4b16ecc3 --- /dev/null +++ b/Lib/test/test_zipfile/__init__.py @@ -0,0 +1,5 @@ +import os +from test.support import load_package_tests + +def load_tests(*args): + return load_package_tests(os.path.dirname(__file__), *args) diff --git a/Lib/test/test_zipfile/__main__.py b/Lib/test/test_zipfile/__main__.py new file mode 100644 index 00000000..e25ac946 --- /dev/null +++ b/Lib/test/test_zipfile/__main__.py @@ -0,0 +1,7 @@ +import unittest + +from . import load_tests # noqa: F401 + + +if __name__ == "__main__": + unittest.main() diff --git a/Lib/tkinter/test/__init__.py b/Lib/test/test_zipfile/_path/__init__.py similarity index 100% rename from Lib/tkinter/test/__init__.py rename to Lib/test/test_zipfile/_path/__init__.py diff --git a/Lib/test/test_zipfile/_path/_functools.py b/Lib/test/test_zipfile/_path/_functools.py new file mode 100644 index 00000000..75f2b20e --- /dev/null +++ b/Lib/test/test_zipfile/_path/_functools.py @@ -0,0 +1,9 @@ +import functools + + +# from jaraco.functools 3.5.2 +def compose(*funcs): + def compose_two(f1, f2): + return lambda *args, **kwargs: f1(f2(*args, **kwargs)) + + return functools.reduce(compose_two, funcs) diff --git a/Lib/test/test_zipfile/_path/_itertools.py b/Lib/test/test_zipfile/_path/_itertools.py new file mode 100644 index 00000000..f735dd21 --- /dev/null +++ b/Lib/test/test_zipfile/_path/_itertools.py @@ -0,0 +1,79 @@ +import itertools +from collections import deque +from itertools import islice + + +# from jaraco.itertools 6.3.0 +class Counter: + """ + Wrap an iterable in an object that stores the count of items + that pass through it. + + >>> items = Counter(range(20)) + >>> items.count + 0 + >>> values = list(items) + >>> items.count + 20 + """ + + def __init__(self, i): + self.count = 0 + self.iter = zip(itertools.count(1), i) + + def __iter__(self): + return self + + def __next__(self): + self.count, result = next(self.iter) + return result + + +# from more_itertools v8.13.0 +def always_iterable(obj, base_type=(str, bytes)): + if obj is None: + return iter(()) + + if (base_type is not None) and isinstance(obj, base_type): + return iter((obj,)) + + try: + return iter(obj) + except TypeError: + return iter((obj,)) + + +# from more_itertools v9.0.0 +def consume(iterator, n=None): + """Advance *iterable* by *n* steps. If *n* is ``None``, consume it + entirely. + Efficiently exhausts an iterator without returning values. Defaults to + consuming the whole iterator, but an optional second argument may be + provided to limit consumption. + >>> i = (x for x in range(10)) + >>> next(i) + 0 + >>> consume(i, 3) + >>> next(i) + 4 + >>> consume(i) + >>> next(i) + Traceback (most recent call last): + File "<stdin>", line 1, in <module> + StopIteration + If the iterator has fewer items remaining than the provided limit, the + whole iterator will be consumed. + >>> i = (x for x in range(3)) + >>> consume(i, 5) + >>> next(i) + Traceback (most recent call last): + File "<stdin>", line 1, in <module> + StopIteration + """ + # Use functions that consume iterators at C speed. + if n is None: + # feed the entire iterator into a zero-length deque + deque(iterator, maxlen=0) + else: + # advance to the empty slice starting at position n + next(islice(iterator, n, n), None) diff --git a/Lib/test/test_zipfile/_path/_support.py b/Lib/test/test_zipfile/_path/_support.py new file mode 100644 index 00000000..1afdf3b3 --- /dev/null +++ b/Lib/test/test_zipfile/_path/_support.py @@ -0,0 +1,9 @@ +import importlib +import unittest + + +def import_or_skip(name): + try: + return importlib.import_module(name) + except ImportError: # pragma: no cover + raise unittest.SkipTest(f'Unable to import {name}') diff --git a/Lib/test/test_zipfile/_path/_test_params.py b/Lib/test/test_zipfile/_path/_test_params.py new file mode 100644 index 00000000..bc95b4eb --- /dev/null +++ b/Lib/test/test_zipfile/_path/_test_params.py @@ -0,0 +1,39 @@ +import types +import functools + +from ._itertools import always_iterable + + +def parameterize(names, value_groups): + """ + Decorate a test method to run it as a set of subtests. + + Modeled after pytest.parametrize. + """ + + def decorator(func): + @functools.wraps(func) + def wrapped(self): + for values in value_groups: + resolved = map(Invoked.eval, always_iterable(values)) + params = dict(zip(always_iterable(names), resolved)) + with self.subTest(**params): + func(self, **params) + + return wrapped + + return decorator + + +class Invoked(types.SimpleNamespace): + """ + Wrap a function to be invoked for each usage. + """ + + @classmethod + def wrap(cls, func): + return cls(func=func) + + @classmethod + def eval(cls, cand): + return cand.func() if isinstance(cand, cls) else cand diff --git a/Lib/test/test_zipfile/_path/test_complexity.py b/Lib/test/test_zipfile/_path/test_complexity.py new file mode 100644 index 00000000..70509377 --- /dev/null +++ b/Lib/test/test_zipfile/_path/test_complexity.py @@ -0,0 +1,103 @@ +import io +import itertools +import math +import re +import string +import unittest +import zipfile + +from ._functools import compose +from ._itertools import consume + +from ._support import import_or_skip + + +big_o = import_or_skip('big_o') +pytest = import_or_skip('pytest') + + +class TestComplexity(unittest.TestCase): + @pytest.mark.flaky + def test_implied_dirs_performance(self): + best, others = big_o.big_o( + compose(consume, zipfile.CompleteDirs._implied_dirs), + lambda size: [ + '/'.join(string.ascii_lowercase + str(n)) for n in range(size) + ], + max_n=1000, + min_n=1, + ) + assert best <= big_o.complexities.Linear + + def make_zip_path(self, depth=1, width=1) -> zipfile.Path: + """ + Construct a Path with width files at every level of depth. + """ + zf = zipfile.ZipFile(io.BytesIO(), mode='w') + pairs = itertools.product(self.make_deep_paths(depth), self.make_names(width)) + for path, name in pairs: + zf.writestr(f"{path}{name}.txt", b'') + zf.filename = "big un.zip" + return zipfile.Path(zf) + + @classmethod + def make_names(cls, width, letters=string.ascii_lowercase): + """ + >>> list(TestComplexity.make_names(2)) + ['a', 'b'] + >>> list(TestComplexity.make_names(30)) + ['aa', 'ab', ..., 'bd'] + """ + # determine how many products are needed to produce width + n_products = math.ceil(math.log(width, len(letters))) + inputs = (letters,) * n_products + combinations = itertools.product(*inputs) + names = map(''.join, combinations) + return itertools.islice(names, width) + + @classmethod + def make_deep_paths(cls, depth): + return map(cls.make_deep_path, range(depth)) + + @classmethod + def make_deep_path(cls, depth): + return ''.join(('d/',) * depth) + + def test_baseline_regex_complexity(self): + best, others = big_o.big_o( + lambda path: re.fullmatch(r'[^/]*\\.txt', path), + self.make_deep_path, + max_n=100, + min_n=1, + ) + assert best <= big_o.complexities.Constant + + @pytest.mark.flaky + def test_glob_depth(self): + best, others = big_o.big_o( + lambda path: consume(path.glob('*.txt')), + self.make_zip_path, + max_n=100, + min_n=1, + ) + assert best <= big_o.complexities.Quadratic + + @pytest.mark.flaky + def test_glob_width(self): + best, others = big_o.big_o( + lambda path: consume(path.glob('*.txt')), + lambda size: self.make_zip_path(width=size), + max_n=100, + min_n=1, + ) + assert best <= big_o.complexities.Linear + + @pytest.mark.flaky + def test_glob_width_and_depth(self): + best, others = big_o.big_o( + lambda path: consume(path.glob('*.txt')), + lambda size: self.make_zip_path(depth=size, width=size), + max_n=10, + min_n=1, + ) + assert best <= big_o.complexities.Linear diff --git a/Lib/test/test_zipfile/_path/test_path.py b/Lib/test/test_zipfile/_path/test_path.py new file mode 100644 index 00000000..c66cb3cb --- /dev/null +++ b/Lib/test/test_zipfile/_path/test_path.py @@ -0,0 +1,579 @@ +import io +import itertools +import contextlib +import pathlib +import pickle +import sys +import unittest +import zipfile + +from ._functools import compose +from ._itertools import Counter + +from ._test_params import parameterize, Invoked + +from test.support.os_helper import temp_dir + + +class jaraco: + class itertools: + Counter = Counter + + +def add_dirs(zf): + """ + Given a writable zip file zf, inject directory entries for + any directories implied by the presence of children. + """ + for name in zipfile.CompleteDirs._implied_dirs(zf.namelist()): + zf.writestr(name, b"") + return zf + + +def build_alpharep_fixture(): + """ + Create a zip file with this structure: + + . + ├── a.txt + ├── b + │ ├── c.txt + │ ├── d + │ │ └── e.txt + │ └── f.txt + ├── g + │ └── h + │ └── i.txt + └── j + ├── k.bin + ├── l.baz + └── m.bar + + This fixture has the following key characteristics: + + - a file at the root (a) + - a file two levels deep (b/d/e) + - multiple files in a directory (b/c, b/f) + - a directory containing only a directory (g/h) + - a directory with files of different extensions (j/klm) + + "alpha" because it uses alphabet + "rep" because it's a representative example + """ + data = io.BytesIO() + zf = zipfile.ZipFile(data, "w") + zf.writestr("a.txt", b"content of a") + zf.writestr("b/c.txt", b"content of c") + zf.writestr("b/d/e.txt", b"content of e") + zf.writestr("b/f.txt", b"content of f") + zf.writestr("g/h/i.txt", b"content of i") + zf.writestr("j/k.bin", b"content of k") + zf.writestr("j/l.baz", b"content of l") + zf.writestr("j/m.bar", b"content of m") + zf.filename = "alpharep.zip" + return zf + + +alpharep_generators = [ + Invoked.wrap(build_alpharep_fixture), + Invoked.wrap(compose(add_dirs, build_alpharep_fixture)), +] + +pass_alpharep = parameterize(['alpharep'], alpharep_generators) + + +class TestPath(unittest.TestCase): + def setUp(self): + self.fixtures = contextlib.ExitStack() + self.addCleanup(self.fixtures.close) + + def zipfile_ondisk(self, alpharep): + tmpdir = pathlib.Path(self.fixtures.enter_context(temp_dir())) + buffer = alpharep.fp + alpharep.close() + path = tmpdir / alpharep.filename + with path.open("wb") as strm: + strm.write(buffer.getvalue()) + return path + + @pass_alpharep + def test_iterdir_and_types(self, alpharep): + root = zipfile.Path(alpharep) + assert root.is_dir() + a, b, g, j = root.iterdir() + assert a.is_file() + assert b.is_dir() + assert g.is_dir() + c, f, d = b.iterdir() + assert c.is_file() and f.is_file() + (e,) = d.iterdir() + assert e.is_file() + (h,) = g.iterdir() + (i,) = h.iterdir() + assert i.is_file() + + @pass_alpharep + def test_is_file_missing(self, alpharep): + root = zipfile.Path(alpharep) + assert not root.joinpath('missing.txt').is_file() + + @pass_alpharep + def test_iterdir_on_file(self, alpharep): + root = zipfile.Path(alpharep) + a, b, g, j = root.iterdir() + with self.assertRaises(ValueError): + a.iterdir() + + @pass_alpharep + def test_subdir_is_dir(self, alpharep): + root = zipfile.Path(alpharep) + assert (root / 'b').is_dir() + assert (root / 'b/').is_dir() + assert (root / 'g').is_dir() + assert (root / 'g/').is_dir() + + @pass_alpharep + def test_open(self, alpharep): + root = zipfile.Path(alpharep) + a, b, g, j = root.iterdir() + with a.open(encoding="utf-8") as strm: + data = strm.read() + self.assertEqual(data, "content of a") + with a.open('r', "utf-8") as strm: # not a kw, no gh-101144 TypeError + data = strm.read() + self.assertEqual(data, "content of a") + + def test_open_encoding_utf16(self): + in_memory_file = io.BytesIO() + zf = zipfile.ZipFile(in_memory_file, "w") + zf.writestr("path/16.txt", "This was utf-16".encode("utf-16")) + zf.filename = "test_open_utf16.zip" + root = zipfile.Path(zf) + (path,) = root.iterdir() + u16 = path.joinpath("16.txt") + with u16.open('r', "utf-16") as strm: + data = strm.read() + assert data == "This was utf-16" + with u16.open(encoding="utf-16") as strm: + data = strm.read() + assert data == "This was utf-16" + + def test_open_encoding_errors(self): + in_memory_file = io.BytesIO() + zf = zipfile.ZipFile(in_memory_file, "w") + zf.writestr("path/bad-utf8.bin", b"invalid utf-8: \xff\xff.") + zf.filename = "test_read_text_encoding_errors.zip" + root = zipfile.Path(zf) + (path,) = root.iterdir() + u16 = path.joinpath("bad-utf8.bin") + + # encoding= as a positional argument for gh-101144. + data = u16.read_text("utf-8", errors="ignore") + assert data == "invalid utf-8: ." + with u16.open("r", "utf-8", errors="surrogateescape") as f: + assert f.read() == "invalid utf-8: \udcff\udcff." + + # encoding= both positional and keyword is an error; gh-101144. + with self.assertRaisesRegex(TypeError, "encoding"): + data = u16.read_text("utf-8", encoding="utf-8") + + # both keyword arguments work. + with u16.open("r", encoding="utf-8", errors="strict") as f: + # error during decoding with wrong codec. + with self.assertRaises(UnicodeDecodeError): + f.read() + + @unittest.skipIf( + not getattr(sys.flags, 'warn_default_encoding', 0), + "Requires warn_default_encoding", + ) + @pass_alpharep + def test_encoding_warnings(self, alpharep): + """EncodingWarning must blame the read_text and open calls.""" + assert sys.flags.warn_default_encoding + root = zipfile.Path(alpharep) + with self.assertWarns(EncodingWarning) as wc: + root.joinpath("a.txt").read_text() + assert __file__ == wc.filename + with self.assertWarns(EncodingWarning) as wc: + root.joinpath("a.txt").open("r").close() + assert __file__ == wc.filename + + def test_open_write(self): + """ + If the zipfile is open for write, it should be possible to + write bytes or text to it. + """ + zf = zipfile.Path(zipfile.ZipFile(io.BytesIO(), mode='w')) + with zf.joinpath('file.bin').open('wb') as strm: + strm.write(b'binary contents') + with zf.joinpath('file.txt').open('w', encoding="utf-8") as strm: + strm.write('text file') + + def test_open_extant_directory(self): + """ + Attempting to open a directory raises IsADirectoryError. + """ + zf = zipfile.Path(add_dirs(build_alpharep_fixture())) + with self.assertRaises(IsADirectoryError): + zf.joinpath('b').open() + + @pass_alpharep + def test_open_binary_invalid_args(self, alpharep): + root = zipfile.Path(alpharep) + with self.assertRaises(ValueError): + root.joinpath('a.txt').open('rb', encoding='utf-8') + with self.assertRaises(ValueError): + root.joinpath('a.txt').open('rb', 'utf-8') + + def test_open_missing_directory(self): + """ + Attempting to open a missing directory raises FileNotFoundError. + """ + zf = zipfile.Path(add_dirs(build_alpharep_fixture())) + with self.assertRaises(FileNotFoundError): + zf.joinpath('z').open() + + @pass_alpharep + def test_read(self, alpharep): + root = zipfile.Path(alpharep) + a, b, g, j = root.iterdir() + assert a.read_text(encoding="utf-8") == "content of a" + # Also check positional encoding arg (gh-101144). + assert a.read_text("utf-8") == "content of a" + assert a.read_bytes() == b"content of a" + + @pass_alpharep + def test_joinpath(self, alpharep): + root = zipfile.Path(alpharep) + a = root.joinpath("a.txt") + assert a.is_file() + e = root.joinpath("b").joinpath("d").joinpath("e.txt") + assert e.read_text(encoding="utf-8") == "content of e" + + @pass_alpharep + def test_joinpath_multiple(self, alpharep): + root = zipfile.Path(alpharep) + e = root.joinpath("b", "d", "e.txt") + assert e.read_text(encoding="utf-8") == "content of e" + + @pass_alpharep + def test_traverse_truediv(self, alpharep): + root = zipfile.Path(alpharep) + a = root / "a.txt" + assert a.is_file() + e = root / "b" / "d" / "e.txt" + assert e.read_text(encoding="utf-8") == "content of e" + + @pass_alpharep + def test_pathlike_construction(self, alpharep): + """ + zipfile.Path should be constructable from a path-like object + """ + zipfile_ondisk = self.zipfile_ondisk(alpharep) + pathlike = pathlib.Path(str(zipfile_ondisk)) + zipfile.Path(pathlike) + + @pass_alpharep + def test_traverse_pathlike(self, alpharep): + root = zipfile.Path(alpharep) + root / pathlib.Path("a") + + @pass_alpharep + def test_parent(self, alpharep): + root = zipfile.Path(alpharep) + assert (root / 'a').parent.at == '' + assert (root / 'a' / 'b').parent.at == 'a/' + + @pass_alpharep + def test_dir_parent(self, alpharep): + root = zipfile.Path(alpharep) + assert (root / 'b').parent.at == '' + assert (root / 'b/').parent.at == '' + + @pass_alpharep + def test_missing_dir_parent(self, alpharep): + root = zipfile.Path(alpharep) + assert (root / 'missing dir/').parent.at == '' + + @pass_alpharep + def test_mutability(self, alpharep): + """ + If the underlying zipfile is changed, the Path object should + reflect that change. + """ + root = zipfile.Path(alpharep) + a, b, g, j = root.iterdir() + alpharep.writestr('foo.txt', 'foo') + alpharep.writestr('bar/baz.txt', 'baz') + assert any(child.name == 'foo.txt' for child in root.iterdir()) + assert (root / 'foo.txt').read_text(encoding="utf-8") == 'foo' + (baz,) = (root / 'bar').iterdir() + assert baz.read_text(encoding="utf-8") == 'baz' + + HUGE_ZIPFILE_NUM_ENTRIES = 2**13 + + def huge_zipfile(self): + """Create a read-only zipfile with a huge number of entries entries.""" + strm = io.BytesIO() + zf = zipfile.ZipFile(strm, "w") + for entry in map(str, range(self.HUGE_ZIPFILE_NUM_ENTRIES)): + zf.writestr(entry, entry) + zf.mode = 'r' + return zf + + def test_joinpath_constant_time(self): + """ + Ensure joinpath on items in zipfile is linear time. + """ + root = zipfile.Path(self.huge_zipfile()) + entries = jaraco.itertools.Counter(root.iterdir()) + for entry in entries: + entry.joinpath('suffix') + # Check the file iterated all items + assert entries.count == self.HUGE_ZIPFILE_NUM_ENTRIES + + @pass_alpharep + def test_read_does_not_close(self, alpharep): + alpharep = self.zipfile_ondisk(alpharep) + with zipfile.ZipFile(alpharep) as file: + for rep in range(2): + zipfile.Path(file, 'a.txt').read_text(encoding="utf-8") + + @pass_alpharep + def test_subclass(self, alpharep): + class Subclass(zipfile.Path): + pass + + root = Subclass(alpharep) + assert isinstance(root / 'b', Subclass) + + @pass_alpharep + def test_filename(self, alpharep): + root = zipfile.Path(alpharep) + assert root.filename == pathlib.Path('alpharep.zip') + + @pass_alpharep + def test_root_name(self, alpharep): + """ + The name of the root should be the name of the zipfile + """ + root = zipfile.Path(alpharep) + assert root.name == 'alpharep.zip' == root.filename.name + + @pass_alpharep + def test_suffix(self, alpharep): + """ + The suffix of the root should be the suffix of the zipfile. + The suffix of each nested file is the final component's last suffix, if any. + Includes the leading period, just like pathlib.Path. + """ + root = zipfile.Path(alpharep) + assert root.suffix == '.zip' == root.filename.suffix + + b = root / "b.txt" + assert b.suffix == ".txt" + + c = root / "c" / "filename.tar.gz" + assert c.suffix == ".gz" + + d = root / "d" + assert d.suffix == "" + + @pass_alpharep + def test_suffixes(self, alpharep): + """ + The suffix of the root should be the suffix of the zipfile. + The suffix of each nested file is the final component's last suffix, if any. + Includes the leading period, just like pathlib.Path. + """ + root = zipfile.Path(alpharep) + assert root.suffixes == ['.zip'] == root.filename.suffixes + + b = root / 'b.txt' + assert b.suffixes == ['.txt'] + + c = root / 'c' / 'filename.tar.gz' + assert c.suffixes == ['.tar', '.gz'] + + d = root / 'd' + assert d.suffixes == [] + + e = root / '.hgrc' + assert e.suffixes == [] + + @pass_alpharep + def test_suffix_no_filename(self, alpharep): + alpharep.filename = None + root = zipfile.Path(alpharep) + assert root.joinpath('example').suffix == "" + assert root.joinpath('example').suffixes == [] + + @pass_alpharep + def test_stem(self, alpharep): + """ + The final path component, without its suffix + """ + root = zipfile.Path(alpharep) + assert root.stem == 'alpharep' == root.filename.stem + + b = root / "b.txt" + assert b.stem == "b" + + c = root / "c" / "filename.tar.gz" + assert c.stem == "filename.tar" + + d = root / "d" + assert d.stem == "d" + + assert (root / ".gitignore").stem == ".gitignore" + + @pass_alpharep + def test_root_parent(self, alpharep): + root = zipfile.Path(alpharep) + assert root.parent == pathlib.Path('.') + root.root.filename = 'foo/bar.zip' + assert root.parent == pathlib.Path('foo') + + @pass_alpharep + def test_root_unnamed(self, alpharep): + """ + It is an error to attempt to get the name + or parent of an unnamed zipfile. + """ + alpharep.filename = None + root = zipfile.Path(alpharep) + with self.assertRaises(TypeError): + root.name + with self.assertRaises(TypeError): + root.parent + + # .name and .parent should still work on subs + sub = root / "b" + assert sub.name == "b" + assert sub.parent + + @pass_alpharep + def test_match_and_glob(self, alpharep): + root = zipfile.Path(alpharep) + assert not root.match("*.txt") + + assert list(root.glob("b/c.*")) == [zipfile.Path(alpharep, "b/c.txt")] + assert list(root.glob("b/*.txt")) == [ + zipfile.Path(alpharep, "b/c.txt"), + zipfile.Path(alpharep, "b/f.txt"), + ] + + @pass_alpharep + def test_glob_recursive(self, alpharep): + root = zipfile.Path(alpharep) + files = root.glob("**/*.txt") + assert all(each.match("*.txt") for each in files) + + assert list(root.glob("**/*.txt")) == list(root.rglob("*.txt")) + + @pass_alpharep + def test_glob_subdirs(self, alpharep): + root = zipfile.Path(alpharep) + + assert list(root.glob("*/i.txt")) == [] + assert list(root.rglob("*/i.txt")) == [zipfile.Path(alpharep, "g/h/i.txt")] + + @pass_alpharep + def test_glob_does_not_overmatch_dot(self, alpharep): + root = zipfile.Path(alpharep) + + assert list(root.glob("*.xt")) == [] + + @pass_alpharep + def test_glob_single_char(self, alpharep): + root = zipfile.Path(alpharep) + + assert list(root.glob("a?txt")) == [zipfile.Path(alpharep, "a.txt")] + assert list(root.glob("a[.]txt")) == [zipfile.Path(alpharep, "a.txt")] + assert list(root.glob("a[?]txt")) == [] + + @pass_alpharep + def test_glob_chars(self, alpharep): + root = zipfile.Path(alpharep) + + assert list(root.glob("j/?.b[ai][nz]")) == [ + zipfile.Path(alpharep, "j/k.bin"), + zipfile.Path(alpharep, "j/l.baz"), + ] + + def test_glob_empty(self): + root = zipfile.Path(zipfile.ZipFile(io.BytesIO(), 'w')) + with self.assertRaises(ValueError): + root.glob('') + + @pass_alpharep + def test_eq_hash(self, alpharep): + root = zipfile.Path(alpharep) + assert root == zipfile.Path(alpharep) + + assert root != (root / "a.txt") + assert (root / "a.txt") == (root / "a.txt") + + root = zipfile.Path(alpharep) + assert root in {root} + + @pass_alpharep + def test_is_symlink(self, alpharep): + """ + See python/cpython#82102 for symlink support beyond this object. + """ + + root = zipfile.Path(alpharep) + assert not root.is_symlink() + + @pass_alpharep + def test_relative_to(self, alpharep): + root = zipfile.Path(alpharep) + relative = root.joinpath("b", "c.txt").relative_to(root / "b") + assert str(relative) == "c.txt" + + relative = root.joinpath("b", "d", "e.txt").relative_to(root / "b") + assert str(relative) == "d/e.txt" + + @pass_alpharep + def test_inheritance(self, alpharep): + cls = type('PathChild', (zipfile.Path,), {}) + file = cls(alpharep).joinpath('some dir').parent + assert isinstance(file, cls) + + @parameterize( + ['alpharep', 'path_type', 'subpath'], + itertools.product( + alpharep_generators, + [str, pathlib.Path], + ['', 'b/'], + ), + ) + def test_pickle(self, alpharep, path_type, subpath): + zipfile_ondisk = path_type(self.zipfile_ondisk(alpharep)) + + saved_1 = pickle.dumps(zipfile.Path(zipfile_ondisk, at=subpath)) + restored_1 = pickle.loads(saved_1) + first, *rest = restored_1.iterdir() + assert first.read_text(encoding='utf-8').startswith('content of ') + + @pass_alpharep + def test_extract_orig_with_implied_dirs(self, alpharep): + """ + A zip file wrapped in a Path should extract even with implied dirs. + """ + source_path = self.zipfile_ondisk(alpharep) + zf = zipfile.ZipFile(source_path) + # wrap the zipfile for its side effect + zipfile.Path(zf) + zf.extractall(source_path.parent) + + @pass_alpharep + def test_getinfo_missing(self, alpharep): + """ + Validate behavior of getinfo on original zipfile after wrapping. + """ + zipfile.Path(alpharep) + with self.assertRaises(KeyError): + alpharep.getinfo('does-not-exist') diff --git a/Lib/test/test_zipfile/_path/write-alpharep.py b/Lib/test/test_zipfile/_path/write-alpharep.py new file mode 100644 index 00000000..48c09b53 --- /dev/null +++ b/Lib/test/test_zipfile/_path/write-alpharep.py @@ -0,0 +1,4 @@ +from . import test_path + + +__name__ == '__main__' and test_path.build_alpharep_fixture().extractall('alpharep') diff --git a/Lib/test/test_zipfile.py b/Lib/test/test_zipfile/test_core.py similarity index 88% rename from Lib/test/test_zipfile.py rename to Lib/test/test_zipfile/test_core.py index 35d78d96..9960259c 100644 --- a/Lib/test/test_zipfile.py +++ b/Lib/test/test_zipfile/test_core.py @@ -6,16 +6,13 @@ import itertools import os import pathlib import posixpath -import string import struct import subprocess import sys -from test.support.script_helper import assert_python_ok import time import unittest import unittest.mock as mock import zipfile -import functools from tempfile import TemporaryFile @@ -125,8 +122,9 @@ class AbstractTestsWithSourceFile: self.assertEqual(info.filename, nm) self.assertEqual(info.file_size, len(self.data)) - # Check that testzip doesn't raise an exception - zipfp.testzip() + # Check that testzip thinks the archive is ok + # (it returns None if all contents could be read properly) + self.assertIsNone(zipfp.testzip()) def test_basic(self): for f in get_files(self): @@ -749,8 +747,8 @@ class AbstractTestZip64InSmallFiles: self.assertEqual(info.filename, nm) self.assertEqual(info.file_size, len(self.data)) - # Check that testzip doesn't raise an exception - zipfp.testzip() + # Check that testzip thinks the archive is valid + self.assertIsNone(zipfp.testzip()) def test_basic(self): for f in get_files(self): @@ -1082,6 +1080,159 @@ class StoredTestZip64InSmallFiles(AbstractTestZip64InSmallFiles, self.assertEqual(zinfo.header_offset, expected_header_offset) self.assertEqual(zf.read(zinfo), expected_content) + def test_force_zip64(self): + """Test that forcing zip64 extensions correctly notes this in the zip file""" + + # GH-103861 describes an issue where forcing a small file to use zip64 + # extensions would add a zip64 extra record, but not change the data + # sizes to 0xFFFFFFFF to indicate to the extractor that the zip64 + # record should be read. Additionally, it would not set the required + # version to indicate that zip64 extensions are required to extract it. + # This test replicates the situation and reads the raw data to specifically ensure: + # - The required extract version is always >= ZIP64_VERSION + # - The compressed and uncompressed size in the file headers are both + # 0xFFFFFFFF (ie. point to zip64 record) + # - The zip64 record is provided and has the correct sizes in it + # Other aspects of the zip are checked as well, but verifying the above is the main goal. + # Because this is hard to verify by parsing the data as a zip, the raw + # bytes are checked to ensure that they line up with the zip spec. + # The spec for this can be found at: https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT + # The relevent sections for this test are: + # - 4.3.7 for local file header + # - 4.5.3 for zip64 extra field + + data = io.BytesIO() + with zipfile.ZipFile(data, mode="w", allowZip64=True) as zf: + with zf.open("text.txt", mode="w", force_zip64=True) as zi: + zi.write(b"_") + + zipdata = data.getvalue() + + # pull out and check zip information + ( + header, vers, os, flags, comp, csize, usize, fn_len, + ex_total_len, filename, ex_id, ex_len, ex_usize, ex_csize, cd_sig + ) = struct.unpack("<4sBBHH8xIIHH8shhQQx4s", zipdata[:63]) + + self.assertEqual(header, b"PK\x03\x04") # local file header + self.assertGreaterEqual(vers, zipfile.ZIP64_VERSION) # requires zip64 to extract + self.assertEqual(os, 0) # compatible with MS-DOS + self.assertEqual(flags, 0) # no flags + self.assertEqual(comp, 0) # compression method = stored + self.assertEqual(csize, 0xFFFFFFFF) # sizes are in zip64 extra + self.assertEqual(usize, 0xFFFFFFFF) + self.assertEqual(fn_len, 8) # filename len + self.assertEqual(ex_total_len, 20) # size of extra records + self.assertEqual(ex_id, 1) # Zip64 extra record + self.assertEqual(ex_len, 16) # 16 bytes of data + self.assertEqual(ex_usize, 1) # uncompressed size + self.assertEqual(ex_csize, 1) # compressed size + self.assertEqual(cd_sig, b"PK\x01\x02") # ensure the central directory header is next + + z = zipfile.ZipFile(io.BytesIO(zipdata)) + zinfos = z.infolist() + self.assertEqual(len(zinfos), 1) + self.assertGreaterEqual(zinfos[0].extract_version, zipfile.ZIP64_VERSION) # requires zip64 to extract + + def test_unseekable_zip_unknown_filesize(self): + """Test that creating a zip with/without seeking will raise a RuntimeError if zip64 was required but not used""" + + def make_zip(fp): + with zipfile.ZipFile(fp, mode="w", allowZip64=True) as zf: + with zf.open("text.txt", mode="w", force_zip64=False) as zi: + zi.write(b"_" * (zipfile.ZIP64_LIMIT + 1)) + + self.assertRaises(RuntimeError, make_zip, io.BytesIO()) + self.assertRaises(RuntimeError, make_zip, Unseekable(io.BytesIO())) + + def test_zip64_required_not_allowed_fail(self): + """Test that trying to add a large file to a zip that doesn't allow zip64 extensions fails on add""" + def make_zip(fp): + with zipfile.ZipFile(fp, mode="w", allowZip64=False) as zf: + # pretend zipfile.ZipInfo.from_file was used to get the name and filesize + info = zipfile.ZipInfo("text.txt") + info.file_size = zipfile.ZIP64_LIMIT + 1 + zf.open(info, mode="w") + + self.assertRaises(zipfile.LargeZipFile, make_zip, io.BytesIO()) + self.assertRaises(zipfile.LargeZipFile, make_zip, Unseekable(io.BytesIO())) + + def test_unseekable_zip_known_filesize(self): + """Test that creating a zip without seeking will use zip64 extensions if the file size is provided up-front""" + + # This test ensures that the zip will use a zip64 data descriptor (same + # as a regular data descriptor except the sizes are 8 bytes instead of + # 4) record to communicate the size of a file if the zip is being + # written to an unseekable stream. + # Because this sort of thing is hard to verify by parsing the data back + # in as a zip, this test looks at the raw bytes created to ensure that + # the correct data has been generated. + # The spec for this can be found at: https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT + # The relevent sections for this test are: + # - 4.3.7 for local file header + # - 4.3.9 for the data descriptor + # - 4.5.3 for zip64 extra field + + file_size = zipfile.ZIP64_LIMIT + 1 + + def make_zip(fp): + with zipfile.ZipFile(fp, mode="w", allowZip64=True) as zf: + # pretend zipfile.ZipInfo.from_file was used to get the name and filesize + info = zipfile.ZipInfo("text.txt") + info.file_size = file_size + with zf.open(info, mode="w", force_zip64=False) as zi: + zi.write(b"_" * file_size) + return fp + + # check seekable file information + seekable_data = make_zip(io.BytesIO()).getvalue() + ( + header, vers, os, flags, comp, csize, usize, fn_len, + ex_total_len, filename, ex_id, ex_len, ex_usize, ex_csize, + cd_sig + ) = struct.unpack("<4sBBHH8xIIHH8shhQQ{}x4s".format(file_size), seekable_data[:62 + file_size]) + + self.assertEqual(header, b"PK\x03\x04") # local file header + self.assertGreaterEqual(vers, zipfile.ZIP64_VERSION) # requires zip64 to extract + self.assertEqual(os, 0) # compatible with MS-DOS + self.assertEqual(flags, 0) # no flags set + self.assertEqual(comp, 0) # compression method = stored + self.assertEqual(csize, 0xFFFFFFFF) # sizes are in zip64 extra + self.assertEqual(usize, 0xFFFFFFFF) + self.assertEqual(fn_len, 8) # filename len + self.assertEqual(ex_total_len, 20) # size of extra records + self.assertEqual(ex_id, 1) # Zip64 extra record + self.assertEqual(ex_len, 16) # 16 bytes of data + self.assertEqual(ex_usize, file_size) # uncompressed size + self.assertEqual(ex_csize, file_size) # compressed size + self.assertEqual(cd_sig, b"PK\x01\x02") # ensure the central directory header is next + + # check unseekable file information + unseekable_data = make_zip(Unseekable(io.BytesIO())).fp.getvalue() + ( + header, vers, os, flags, comp, csize, usize, fn_len, + ex_total_len, filename, ex_id, ex_len, ex_usize, ex_csize, + dd_header, dd_usize, dd_csize, cd_sig + ) = struct.unpack("<4sBBHH8xIIHH8shhQQ{}x4s4xQQ4s".format(file_size), unseekable_data[:86 + file_size]) + + self.assertEqual(header, b"PK\x03\x04") # local file header + self.assertGreaterEqual(vers, zipfile.ZIP64_VERSION) # requires zip64 to extract + self.assertEqual(os, 0) # compatible with MS-DOS + self.assertEqual("{:b}".format(flags), "1000") # streaming flag set + self.assertEqual(comp, 0) # compression method = stored + self.assertEqual(csize, 0xFFFFFFFF) # sizes are in zip64 extra + self.assertEqual(usize, 0xFFFFFFFF) + self.assertEqual(fn_len, 8) # filename len + self.assertEqual(ex_total_len, 20) # size of extra records + self.assertEqual(ex_id, 1) # Zip64 extra record + self.assertEqual(ex_len, 16) # 16 bytes of data + self.assertEqual(ex_usize, 0) # uncompressed size - 0 to defer to data descriptor + self.assertEqual(ex_csize, 0) # compressed size - 0 to defer to data descriptor + self.assertEqual(dd_header, b"PK\07\x08") # data descriptor + self.assertEqual(dd_usize, file_size) # file size (8 bytes because zip64) + self.assertEqual(dd_csize, file_size) # compressed size (8 bytes because zip64) + self.assertEqual(cd_sig, b"PK\x01\x02") # ensure the central directory header is next + @requires_zlib() class DeflateTestZip64InSmallFiles(AbstractTestZip64InSmallFiles, @@ -1441,6 +1592,8 @@ class ExtractTests(unittest.TestCase): self.assertEqual(san(r',,?,C:,foo,bar/z', ','), r'_,C_,foo,bar/z') self.assertEqual(san(r'a\b,c<d>e|f"g?h*i', ','), r'a\b,c_d_e_f_g_h_i') self.assertEqual(san('../../foo../../ba..r', '/'), r'foo/ba..r') + self.assertEqual(san(' / /foo / /ba r', '/'), r'foo/ba r') + self.assertEqual(san(' . /. /foo ./ . /. ./ba .r', '/'), r'foo/ba .r') def test_extract_hackers_arcnames_common_cases(self): common_hacknames = [ @@ -1616,6 +1769,33 @@ class OtherTests(unittest.TestCase): self.assertEqual(zf.filelist[0].filename, "foo.txt") self.assertEqual(zf.filelist[1].filename, "\xf6.txt") + @requires_zlib() + def test_read_zipfile_containing_unicode_path_extra_field(self): + with zipfile.ZipFile(TESTFN, mode='w') as zf: + # create a file with a non-ASCII name + filename = '이름.txt' + filename_encoded = filename.encode('utf-8') + + # create a ZipInfo object with Unicode path extra field + zip_info = zipfile.ZipInfo(filename) + + tag_for_unicode_path = b'\x75\x70' + version_of_unicode_path = b'\x01' + + import zlib + filename_crc = struct.pack('<L', zlib.crc32(filename_encoded)) + + extra_data = version_of_unicode_path + filename_crc + filename_encoded + tsize = len(extra_data).to_bytes(2, 'little') + + zip_info.extra = tag_for_unicode_path + tsize + extra_data + + # add the file to the ZIP archive + zf.writestr(zip_info, b'Hello World!') + + with zipfile.ZipFile(TESTFN, "r") as zf: + self.assertEqual(zf.filelist[0].filename, "이름.txt") + def test_read_after_write_unicode_filenames(self): with zipfile.ZipFile(TESTFN2, 'w') as zipfp: zipfp.writestr('приклад', b'sample') @@ -2031,6 +2211,7 @@ class OtherTests(unittest.TestCase): fp.seek(bloc, os.SEEK_CUR) self.assertEqual(fp.tell(), bloc) self.assertEqual(fp.read(5), txt[bloc:bloc+5]) + self.assertEqual(fp.tell(), bloc + 5) fp.seek(0, os.SEEK_END) self.assertEqual(fp.tell(), len(txt)) fp.seek(0, os.SEEK_SET) @@ -2048,6 +2229,7 @@ class OtherTests(unittest.TestCase): fp.seek(bloc, os.SEEK_CUR) self.assertEqual(fp.tell(), bloc) self.assertEqual(fp.read(5), txt[bloc:bloc+5]) + self.assertEqual(fp.tell(), bloc + 5) fp.seek(0, os.SEEK_END) self.assertEqual(fp.tell(), len(txt)) fp.seek(0, os.SEEK_SET) @@ -2711,13 +2893,13 @@ class TestWithDirectory(unittest.TestCase): class ZipInfoTests(unittest.TestCase): def test_from_file(self): zi = zipfile.ZipInfo.from_file(__file__) - self.assertEqual(posixpath.basename(zi.filename), 'test_zipfile.py') + self.assertEqual(posixpath.basename(zi.filename), 'test_core.py') self.assertFalse(zi.is_dir()) self.assertEqual(zi.file_size, os.path.getsize(__file__)) def test_from_file_pathlike(self): zi = zipfile.ZipInfo.from_file(pathlib.Path(__file__)) - self.assertEqual(posixpath.basename(zi.filename), 'test_zipfile.py') + self.assertEqual(posixpath.basename(zi.filename), 'test_core.py') self.assertFalse(zi.is_dir()) self.assertEqual(zi.file_size, os.path.getsize(__file__)) @@ -2863,483 +3045,6 @@ class TestExecutablePrependedZip(unittest.TestCase): self.assertIn(b'number in executable: 5', output) -# Poor man's technique to consume a (smallish) iterable. -consume = tuple - - -# from jaraco.itertools 5.0 -class jaraco: - class itertools: - class Counter: - def __init__(self, i): - self.count = 0 - self._orig_iter = iter(i) - - def __iter__(self): - return self - - def __next__(self): - result = next(self._orig_iter) - self.count += 1 - return result - - -def add_dirs(zf): - """ - Given a writable zip file zf, inject directory entries for - any directories implied by the presence of children. - """ - for name in zipfile.CompleteDirs._implied_dirs(zf.namelist()): - zf.writestr(name, b"") - return zf - - -def build_alpharep_fixture(): - """ - Create a zip file with this structure: - - . - ├── a.txt - ├── b - │ ├── c.txt - │ ├── d - │ │ └── e.txt - │ └── f.txt - └── g - └── h - └── i.txt - - This fixture has the following key characteristics: - - - a file at the root (a) - - a file two levels deep (b/d/e) - - multiple files in a directory (b/c, b/f) - - a directory containing only a directory (g/h) - - "alpha" because it uses alphabet - "rep" because it's a representative example - """ - data = io.BytesIO() - zf = zipfile.ZipFile(data, "w") - zf.writestr("a.txt", b"content of a") - zf.writestr("b/c.txt", b"content of c") - zf.writestr("b/d/e.txt", b"content of e") - zf.writestr("b/f.txt", b"content of f") - zf.writestr("g/h/i.txt", b"content of i") - zf.filename = "alpharep.zip" - return zf - - -def pass_alpharep(meth): - """ - Given a method, wrap it in a for loop that invokes method - with each subtest. - """ - - @functools.wraps(meth) - def wrapper(self): - for alpharep in self.zipfile_alpharep(): - meth(self, alpharep=alpharep) - - return wrapper - - -class TestPath(unittest.TestCase): - def setUp(self): - self.fixtures = contextlib.ExitStack() - self.addCleanup(self.fixtures.close) - - def zipfile_alpharep(self): - with self.subTest(): - yield build_alpharep_fixture() - with self.subTest(): - yield add_dirs(build_alpharep_fixture()) - - def zipfile_ondisk(self, alpharep): - tmpdir = pathlib.Path(self.fixtures.enter_context(temp_dir())) - buffer = alpharep.fp - alpharep.close() - path = tmpdir / alpharep.filename - with path.open("wb") as strm: - strm.write(buffer.getvalue()) - return path - - @pass_alpharep - def test_iterdir_and_types(self, alpharep): - root = zipfile.Path(alpharep) - assert root.is_dir() - a, b, g = root.iterdir() - assert a.is_file() - assert b.is_dir() - assert g.is_dir() - c, f, d = b.iterdir() - assert c.is_file() and f.is_file() - (e,) = d.iterdir() - assert e.is_file() - (h,) = g.iterdir() - (i,) = h.iterdir() - assert i.is_file() - - @pass_alpharep - def test_is_file_missing(self, alpharep): - root = zipfile.Path(alpharep) - assert not root.joinpath('missing.txt').is_file() - - @pass_alpharep - def test_iterdir_on_file(self, alpharep): - root = zipfile.Path(alpharep) - a, b, g = root.iterdir() - with self.assertRaises(ValueError): - a.iterdir() - - @pass_alpharep - def test_subdir_is_dir(self, alpharep): - root = zipfile.Path(alpharep) - assert (root / 'b').is_dir() - assert (root / 'b/').is_dir() - assert (root / 'g').is_dir() - assert (root / 'g/').is_dir() - - @pass_alpharep - def test_open(self, alpharep): - root = zipfile.Path(alpharep) - a, b, g = root.iterdir() - with a.open(encoding="utf-8") as strm: - data = strm.read() - self.assertEqual(data, "content of a") - with a.open('r', "utf-8") as strm: # not a kw, no gh-101144 TypeError - data = strm.read() - self.assertEqual(data, "content of a") - - def test_open_encoding_utf16(self): - in_memory_file = io.BytesIO() - zf = zipfile.ZipFile(in_memory_file, "w") - zf.writestr("path/16.txt", "This was utf-16".encode("utf-16")) - zf.filename = "test_open_utf16.zip" - root = zipfile.Path(zf) - (path,) = root.iterdir() - u16 = path.joinpath("16.txt") - with u16.open('r', "utf-16") as strm: - data = strm.read() - self.assertEqual(data, "This was utf-16") - with u16.open(encoding="utf-16") as strm: - data = strm.read() - self.assertEqual(data, "This was utf-16") - - def test_open_encoding_errors(self): - in_memory_file = io.BytesIO() - zf = zipfile.ZipFile(in_memory_file, "w") - zf.writestr("path/bad-utf8.bin", b"invalid utf-8: \xff\xff.") - zf.filename = "test_read_text_encoding_errors.zip" - root = zipfile.Path(zf) - (path,) = root.iterdir() - u16 = path.joinpath("bad-utf8.bin") - - # encoding= as a positional argument for gh-101144. - data = u16.read_text("utf-8", errors="ignore") - self.assertEqual(data, "invalid utf-8: .") - with u16.open("r", "utf-8", errors="surrogateescape") as f: - self.assertEqual(f.read(), "invalid utf-8: \udcff\udcff.") - - # encoding= both positional and keyword is an error; gh-101144. - with self.assertRaisesRegex(TypeError, "encoding"): - data = u16.read_text("utf-8", encoding="utf-8") - - # both keyword arguments work. - with u16.open("r", encoding="utf-8", errors="strict") as f: - # error during decoding with wrong codec. - with self.assertRaises(UnicodeDecodeError): - f.read() - - def test_encoding_warnings(self): - """EncodingWarning must blame the read_text and open calls.""" - code = '''\ -import io, zipfile -with zipfile.ZipFile(io.BytesIO(), "w") as zf: - zf.filename = '<test_encoding_warnings in memory zip file>' - zf.writestr("path/file.txt", b"Spanish Inquisition") - root = zipfile.Path(zf) - (path,) = root.iterdir() - file_path = path.joinpath("file.txt") - unused = file_path.read_text() # should warn - file_path.open("r").close() # should warn -''' - proc = assert_python_ok('-X', 'warn_default_encoding', '-c', code) - warnings = proc.err.splitlines() - self.assertEqual(len(warnings), 2, proc.err) - self.assertRegex(warnings[0], rb"^<string>:8: EncodingWarning:") - self.assertRegex(warnings[1], rb"^<string>:9: EncodingWarning:") - - def test_open_write(self): - """ - If the zipfile is open for write, it should be possible to - write bytes or text to it. - """ - zf = zipfile.Path(zipfile.ZipFile(io.BytesIO(), mode='w')) - with zf.joinpath('file.bin').open('wb') as strm: - strm.write(b'binary contents') - with zf.joinpath('file.txt').open('w', encoding="utf-8") as strm: - strm.write('text file') - - def test_open_extant_directory(self): - """ - Attempting to open a directory raises IsADirectoryError. - """ - zf = zipfile.Path(add_dirs(build_alpharep_fixture())) - with self.assertRaises(IsADirectoryError): - zf.joinpath('b').open() - - @pass_alpharep - def test_open_binary_invalid_args(self, alpharep): - root = zipfile.Path(alpharep) - with self.assertRaises(ValueError): - root.joinpath('a.txt').open('rb', encoding='utf-8') - with self.assertRaises(ValueError): - root.joinpath('a.txt').open('rb', 'utf-8') - - def test_open_missing_directory(self): - """ - Attempting to open a missing directory raises FileNotFoundError. - """ - zf = zipfile.Path(add_dirs(build_alpharep_fixture())) - with self.assertRaises(FileNotFoundError): - zf.joinpath('z').open() - - @pass_alpharep - def test_read(self, alpharep): - root = zipfile.Path(alpharep) - a, b, g = root.iterdir() - assert a.read_text(encoding="utf-8") == "content of a" - a.read_text("utf-8") # No positional arg TypeError per gh-101144. - assert a.read_bytes() == b"content of a" - - @pass_alpharep - def test_joinpath(self, alpharep): - root = zipfile.Path(alpharep) - a = root.joinpath("a.txt") - assert a.is_file() - e = root.joinpath("b").joinpath("d").joinpath("e.txt") - assert e.read_text(encoding="utf-8") == "content of e" - - @pass_alpharep - def test_joinpath_multiple(self, alpharep): - root = zipfile.Path(alpharep) - e = root.joinpath("b", "d", "e.txt") - assert e.read_text(encoding="utf-8") == "content of e" - - @pass_alpharep - def test_traverse_truediv(self, alpharep): - root = zipfile.Path(alpharep) - a = root / "a.txt" - assert a.is_file() - e = root / "b" / "d" / "e.txt" - assert e.read_text(encoding="utf-8") == "content of e" - - @pass_alpharep - def test_traverse_simplediv(self, alpharep): - """ - Disable the __future__.division when testing traversal. - """ - code = compile( - source="zipfile.Path(alpharep) / 'a'", - filename="(test)", - mode="eval", - dont_inherit=True, - ) - eval(code) - - @pass_alpharep - def test_pathlike_construction(self, alpharep): - """ - zipfile.Path should be constructable from a path-like object - """ - zipfile_ondisk = self.zipfile_ondisk(alpharep) - pathlike = pathlib.Path(str(zipfile_ondisk)) - zipfile.Path(pathlike) - - @pass_alpharep - def test_traverse_pathlike(self, alpharep): - root = zipfile.Path(alpharep) - root / pathlib.Path("a") - - @pass_alpharep - def test_parent(self, alpharep): - root = zipfile.Path(alpharep) - assert (root / 'a').parent.at == '' - assert (root / 'a' / 'b').parent.at == 'a/' - - @pass_alpharep - def test_dir_parent(self, alpharep): - root = zipfile.Path(alpharep) - assert (root / 'b').parent.at == '' - assert (root / 'b/').parent.at == '' - - @pass_alpharep - def test_missing_dir_parent(self, alpharep): - root = zipfile.Path(alpharep) - assert (root / 'missing dir/').parent.at == '' - - @pass_alpharep - def test_mutability(self, alpharep): - """ - If the underlying zipfile is changed, the Path object should - reflect that change. - """ - root = zipfile.Path(alpharep) - a, b, g = root.iterdir() - alpharep.writestr('foo.txt', 'foo') - alpharep.writestr('bar/baz.txt', 'baz') - assert any(child.name == 'foo.txt' for child in root.iterdir()) - assert (root / 'foo.txt').read_text(encoding="utf-8") == 'foo' - (baz,) = (root / 'bar').iterdir() - assert baz.read_text(encoding="utf-8") == 'baz' - - HUGE_ZIPFILE_NUM_ENTRIES = 2 ** 13 - - def huge_zipfile(self): - """Create a read-only zipfile with a huge number of entries entries.""" - strm = io.BytesIO() - zf = zipfile.ZipFile(strm, "w") - for entry in map(str, range(self.HUGE_ZIPFILE_NUM_ENTRIES)): - zf.writestr(entry, entry) - zf.mode = 'r' - return zf - - def test_joinpath_constant_time(self): - """ - Ensure joinpath on items in zipfile is linear time. - """ - root = zipfile.Path(self.huge_zipfile()) - entries = jaraco.itertools.Counter(root.iterdir()) - for entry in entries: - entry.joinpath('suffix') - # Check the file iterated all items - assert entries.count == self.HUGE_ZIPFILE_NUM_ENTRIES - - # @func_timeout.func_set_timeout(3) - def test_implied_dirs_performance(self): - data = ['/'.join(string.ascii_lowercase + str(n)) for n in range(10000)] - zipfile.CompleteDirs._implied_dirs(data) - - @pass_alpharep - def test_read_does_not_close(self, alpharep): - alpharep = self.zipfile_ondisk(alpharep) - with zipfile.ZipFile(alpharep) as file: - for rep in range(2): - zipfile.Path(file, 'a.txt').read_text(encoding="utf-8") - - @pass_alpharep - def test_subclass(self, alpharep): - class Subclass(zipfile.Path): - pass - - root = Subclass(alpharep) - assert isinstance(root / 'b', Subclass) - - @pass_alpharep - def test_filename(self, alpharep): - root = zipfile.Path(alpharep) - assert root.filename == pathlib.Path('alpharep.zip') - - @pass_alpharep - def test_root_name(self, alpharep): - """ - The name of the root should be the name of the zipfile - """ - root = zipfile.Path(alpharep) - assert root.name == 'alpharep.zip' == root.filename.name - - @pass_alpharep - def test_suffix(self, alpharep): - """ - The suffix of the root should be the suffix of the zipfile. - The suffix of each nested file is the final component's last suffix, if any. - Includes the leading period, just like pathlib.Path. - """ - root = zipfile.Path(alpharep) - assert root.suffix == '.zip' == root.filename.suffix - - b = root / "b.txt" - assert b.suffix == ".txt" - - c = root / "c" / "filename.tar.gz" - assert c.suffix == ".gz" - - d = root / "d" - assert d.suffix == "" - - @pass_alpharep - def test_suffixes(self, alpharep): - """ - The suffix of the root should be the suffix of the zipfile. - The suffix of each nested file is the final component's last suffix, if any. - Includes the leading period, just like pathlib.Path. - """ - root = zipfile.Path(alpharep) - assert root.suffixes == ['.zip'] == root.filename.suffixes - - b = root / 'b.txt' - assert b.suffixes == ['.txt'] - - c = root / 'c' / 'filename.tar.gz' - assert c.suffixes == ['.tar', '.gz'] - - d = root / 'd' - assert d.suffixes == [] - - e = root / '.hgrc' - assert e.suffixes == [] - - @pass_alpharep - def test_stem(self, alpharep): - """ - The final path component, without its suffix - """ - root = zipfile.Path(alpharep) - assert root.stem == 'alpharep' == root.filename.stem - - b = root / "b.txt" - assert b.stem == "b" - - c = root / "c" / "filename.tar.gz" - assert c.stem == "filename.tar" - - d = root / "d" - assert d.stem == "d" - - @pass_alpharep - def test_root_parent(self, alpharep): - root = zipfile.Path(alpharep) - assert root.parent == pathlib.Path('.') - root.root.filename = 'foo/bar.zip' - assert root.parent == pathlib.Path('foo') - - @pass_alpharep - def test_root_unnamed(self, alpharep): - """ - It is an error to attempt to get the name - or parent of an unnamed zipfile. - """ - alpharep.filename = None - root = zipfile.Path(alpharep) - with self.assertRaises(TypeError): - root.name - with self.assertRaises(TypeError): - root.parent - - # .name and .parent should still work on subs - sub = root / "b" - assert sub.name == "b" - assert sub.parent - - @pass_alpharep - def test_inheritance(self, alpharep): - cls = type('PathChild', (zipfile.Path,), {}) - for alpharep in self.zipfile_alpharep(): - file = cls(alpharep).joinpath('some dir').parent - assert isinstance(file, cls) - - class EncodedMetadataTests(unittest.TestCase): file_names = ['\u4e00', '\u4e8c', '\u4e09'] # Han 'one', 'two', 'three' file_content = [ @@ -3485,5 +3190,67 @@ class EncodedMetadataTests(unittest.TestCase): self.assertIn(name, listing) +class StripExtraTests(unittest.TestCase): + # Note: all of the "z" characters are technically invalid, but up + # to 3 bytes at the end of the extra will be passed through as they + # are too short to encode a valid extra. + + ZIP64_EXTRA = 1 + + def test_no_data(self): + s = struct.Struct("<HH") + a = s.pack(self.ZIP64_EXTRA, 0) + b = s.pack(2, 0) + c = s.pack(3, 0) + + self.assertEqual(b'', zipfile._strip_extra(a, (self.ZIP64_EXTRA,))) + self.assertEqual(b, zipfile._strip_extra(b, (self.ZIP64_EXTRA,))) + self.assertEqual( + b+b"z", zipfile._strip_extra(b+b"z", (self.ZIP64_EXTRA,))) + + self.assertEqual(b+c, zipfile._strip_extra(a+b+c, (self.ZIP64_EXTRA,))) + self.assertEqual(b+c, zipfile._strip_extra(b+a+c, (self.ZIP64_EXTRA,))) + self.assertEqual(b+c, zipfile._strip_extra(b+c+a, (self.ZIP64_EXTRA,))) + + def test_with_data(self): + s = struct.Struct("<HH") + a = s.pack(self.ZIP64_EXTRA, 1) + b"a" + b = s.pack(2, 2) + b"bb" + c = s.pack(3, 3) + b"ccc" + + self.assertEqual(b"", zipfile._strip_extra(a, (self.ZIP64_EXTRA,))) + self.assertEqual(b, zipfile._strip_extra(b, (self.ZIP64_EXTRA,))) + self.assertEqual( + b+b"z", zipfile._strip_extra(b+b"z", (self.ZIP64_EXTRA,))) + + self.assertEqual(b+c, zipfile._strip_extra(a+b+c, (self.ZIP64_EXTRA,))) + self.assertEqual(b+c, zipfile._strip_extra(b+a+c, (self.ZIP64_EXTRA,))) + self.assertEqual(b+c, zipfile._strip_extra(b+c+a, (self.ZIP64_EXTRA,))) + + def test_multiples(self): + s = struct.Struct("<HH") + a = s.pack(self.ZIP64_EXTRA, 1) + b"a" + b = s.pack(2, 2) + b"bb" + + self.assertEqual(b"", zipfile._strip_extra(a+a, (self.ZIP64_EXTRA,))) + self.assertEqual(b"", zipfile._strip_extra(a+a+a, (self.ZIP64_EXTRA,))) + self.assertEqual( + b"z", zipfile._strip_extra(a+a+b"z", (self.ZIP64_EXTRA,))) + self.assertEqual( + b+b"z", zipfile._strip_extra(a+a+b+b"z", (self.ZIP64_EXTRA,))) + + self.assertEqual(b, zipfile._strip_extra(a+a+b, (self.ZIP64_EXTRA,))) + self.assertEqual(b, zipfile._strip_extra(a+b+a, (self.ZIP64_EXTRA,))) + self.assertEqual(b, zipfile._strip_extra(b+a+a, (self.ZIP64_EXTRA,))) + + def test_too_short(self): + self.assertEqual(b"", zipfile._strip_extra(b"", (self.ZIP64_EXTRA,))) + self.assertEqual(b"z", zipfile._strip_extra(b"z", (self.ZIP64_EXTRA,))) + self.assertEqual( + b"zz", zipfile._strip_extra(b"zz", (self.ZIP64_EXTRA,))) + self.assertEqual( + b"zzz", zipfile._strip_extra(b"zzz", (self.ZIP64_EXTRA,))) + + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_zipfile64.py b/Lib/test/test_zipfile64.py index 0947013a..2e1affe0 100644 --- a/Lib/test/test_zipfile64.py +++ b/Lib/test/test_zipfile64.py @@ -11,7 +11,7 @@ support.requires( 'test requires loads of disk-space bytes and a long time to run' ) -import zipfile, os, unittest +import zipfile, unittest import time import sys @@ -32,10 +32,6 @@ class TestsWithSourceFile(unittest.TestCase): line_gen = ("Test of zipfile line %d." % i for i in range(1000000)) self.data = '\n'.join(line_gen).encode('ascii') - # And write it to a file. - with open(TESTFN, "wb") as fp: - fp.write(self.data) - def zipTest(self, f, compression): # Create the ZIP archive. with zipfile.ZipFile(f, "w", compression) as zipfp: @@ -67,6 +63,9 @@ class TestsWithSourceFile(unittest.TestCase): (num, filecount)), file=sys.__stdout__) sys.__stdout__.flush() + # Check that testzip thinks the archive is valid + self.assertIsNone(zipfp.testzip()) + def testStored(self): # Try the temp file first. If we do TESTFN2 first, then it hogs # gigabytes of disk space for the duration of the test. @@ -85,9 +84,7 @@ class TestsWithSourceFile(unittest.TestCase): self.zipTest(TESTFN2, zipfile.ZIP_DEFLATED) def tearDown(self): - for fname in TESTFN, TESTFN2: - if os.path.exists(fname): - os.remove(fname) + os_helper.unlink(TESTFN2) class OtherTests(unittest.TestCase): diff --git a/Lib/test/test_zipimport.py b/Lib/test/test_zipimport.py index 59a52001..14c19719 100644 --- a/Lib/test/test_zipimport.py +++ b/Lib/test/test_zipimport.py @@ -460,12 +460,6 @@ class UncompressedZipImportTestCase(ImportHooksBaseTestCase): # PEP 302 with warnings.catch_warnings(): warnings.simplefilter("ignore", DeprecationWarning) - find_mod = zi.find_module('spam') - self.assertIsNotNone(find_mod) - self.assertIsInstance(find_mod, zipimport.zipimporter) - self.assertFalse(find_mod.is_package('spam')) - load_mod = find_mod.load_module('spam') - self.assertEqual(find_mod.get_filename('spam'), load_mod.__file__) mod = zi.load_module(TESTPACK) self.assertEqual(zi.get_filename(TESTPACK), mod.__file__) @@ -586,16 +580,6 @@ class UncompressedZipImportTestCase(ImportHooksBaseTestCase): pkg_path = TEMP_ZIP + os.sep + packdir + TESTPACK2 zi2 = zipimport.zipimporter(pkg_path) - # PEP 302 - with warnings.catch_warnings(): - warnings.simplefilter("ignore", DeprecationWarning) - find_mod_dotted = zi2.find_module(TESTMOD) - self.assertIsNotNone(find_mod_dotted) - self.assertIsInstance(find_mod_dotted, zipimport.zipimporter) - self.assertFalse(zi2.is_package(TESTMOD)) - load_mod = find_mod_dotted.load_module(TESTMOD) - self.assertEqual( - find_mod_dotted.get_filename(TESTMOD), load_mod.__file__) # PEP 451 spec = zi2.find_spec(TESTMOD) @@ -852,7 +836,6 @@ class BadFileZipImportTestCase(unittest.TestCase): self.assertRaises(TypeError, z.get_source, None) error = zipimport.ZipImportError - self.assertIsNone(z.find_module('abc')) self.assertIsNone(z.find_spec('abc')) with warnings.catch_warnings(): diff --git a/Lib/test/test_zlib.py b/Lib/test/test_zlib.py index f20aad05..55306c63 100644 --- a/Lib/test/test_zlib.py +++ b/Lib/test/test_zlib.py @@ -7,7 +7,7 @@ import os import pickle import random import sys -from test.support import bigmemtest, _1G, _4G +from test.support import bigmemtest, _1G, _4G, skip_on_s390x zlib = import_helper.import_module('zlib') @@ -44,10 +44,7 @@ requires_Decompress_copy = unittest.skipUnless( # zlib.decompress(func1(data)) == zlib.decompress(func2(data)) == data # # Make the assumption that s390x always has an accelerator to simplify the skip -# condition. Windows doesn't have os.uname() but it doesn't support s390x. -skip_on_s390x = unittest.skipIf(hasattr(os, 'uname') and os.uname().machine == 's390x', - 'skipped on s390x') - +# condition. class VersionTestCase(unittest.TestCase): @@ -944,6 +941,178 @@ LAERTES """ +class ZlibDecompressorTest(unittest.TestCase): + # Test adopted from test_bz2.py + TEXT = HAMLET_SCENE + DATA = zlib.compress(HAMLET_SCENE) + BAD_DATA = b"Not a valid deflate block" + BIG_TEXT = DATA * ((128 * 1024 // len(DATA)) + 1) + BIG_DATA = zlib.compress(BIG_TEXT) + + def test_Constructor(self): + self.assertRaises(TypeError, zlib._ZlibDecompressor, "ASDA") + self.assertRaises(TypeError, zlib._ZlibDecompressor, -15, "notbytes") + self.assertRaises(TypeError, zlib._ZlibDecompressor, -15, b"bytes", 5) + + def testDecompress(self): + zlibd = zlib._ZlibDecompressor() + self.assertRaises(TypeError, zlibd.decompress) + text = zlibd.decompress(self.DATA) + self.assertEqual(text, self.TEXT) + + def testDecompressChunks10(self): + zlibd = zlib._ZlibDecompressor() + text = b'' + n = 0 + while True: + str = self.DATA[n*10:(n+1)*10] + if not str: + break + text += zlibd.decompress(str) + n += 1 + self.assertEqual(text, self.TEXT) + + def testDecompressUnusedData(self): + zlibd = zlib._ZlibDecompressor() + unused_data = b"this is unused data" + text = zlibd.decompress(self.DATA+unused_data) + self.assertEqual(text, self.TEXT) + self.assertEqual(zlibd.unused_data, unused_data) + + def testEOFError(self): + zlibd = zlib._ZlibDecompressor() + text = zlibd.decompress(self.DATA) + self.assertRaises(EOFError, zlibd.decompress, b"anything") + self.assertRaises(EOFError, zlibd.decompress, b"") + + @support.skip_if_pgo_task + @bigmemtest(size=_4G + 100, memuse=3.3) + def testDecompress4G(self, size): + # "Test zlib._ZlibDecompressor.decompress() with >4GiB input" + blocksize = min(10 * 1024 * 1024, size) + block = random.randbytes(blocksize) + try: + data = block * ((size-1) // blocksize + 1) + compressed = zlib.compress(data) + zlibd = zlib._ZlibDecompressor() + decompressed = zlibd.decompress(compressed) + self.assertTrue(decompressed == data) + finally: + data = None + compressed = None + decompressed = None + + def testPickle(self): + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.assertRaises(TypeError): + pickle.dumps(zlib._ZlibDecompressor(), proto) + + def testDecompressorChunksMaxsize(self): + zlibd = zlib._ZlibDecompressor() + max_length = 100 + out = [] + + # Feed some input + len_ = len(self.BIG_DATA) - 64 + out.append(zlibd.decompress(self.BIG_DATA[:len_], + max_length=max_length)) + self.assertFalse(zlibd.needs_input) + self.assertEqual(len(out[-1]), max_length) + + # Retrieve more data without providing more input + out.append(zlibd.decompress(b'', max_length=max_length)) + self.assertFalse(zlibd.needs_input) + self.assertEqual(len(out[-1]), max_length) + + # Retrieve more data while providing more input + out.append(zlibd.decompress(self.BIG_DATA[len_:], + max_length=max_length)) + self.assertLessEqual(len(out[-1]), max_length) + + # Retrieve remaining uncompressed data + while not zlibd.eof: + out.append(zlibd.decompress(b'', max_length=max_length)) + self.assertLessEqual(len(out[-1]), max_length) + + out = b"".join(out) + self.assertEqual(out, self.BIG_TEXT) + self.assertEqual(zlibd.unused_data, b"") + + def test_decompressor_inputbuf_1(self): + # Test reusing input buffer after moving existing + # contents to beginning + zlibd = zlib._ZlibDecompressor() + out = [] + + # Create input buffer and fill it + self.assertEqual(zlibd.decompress(self.DATA[:100], + max_length=0), b'') + + # Retrieve some results, freeing capacity at beginning + # of input buffer + out.append(zlibd.decompress(b'', 2)) + + # Add more data that fits into input buffer after + # moving existing data to beginning + out.append(zlibd.decompress(self.DATA[100:105], 15)) + + # Decompress rest of data + out.append(zlibd.decompress(self.DATA[105:])) + self.assertEqual(b''.join(out), self.TEXT) + + def test_decompressor_inputbuf_2(self): + # Test reusing input buffer by appending data at the + # end right away + zlibd = zlib._ZlibDecompressor() + out = [] + + # Create input buffer and empty it + self.assertEqual(zlibd.decompress(self.DATA[:200], + max_length=0), b'') + out.append(zlibd.decompress(b'')) + + # Fill buffer with new data + out.append(zlibd.decompress(self.DATA[200:280], 2)) + + # Append some more data, not enough to require resize + out.append(zlibd.decompress(self.DATA[280:300], 2)) + + # Decompress rest of data + out.append(zlibd.decompress(self.DATA[300:])) + self.assertEqual(b''.join(out), self.TEXT) + + def test_decompressor_inputbuf_3(self): + # Test reusing input buffer after extending it + + zlibd = zlib._ZlibDecompressor() + out = [] + + # Create almost full input buffer + out.append(zlibd.decompress(self.DATA[:200], 5)) + + # Add even more data to it, requiring resize + out.append(zlibd.decompress(self.DATA[200:300], 5)) + + # Decompress rest of data + out.append(zlibd.decompress(self.DATA[300:])) + self.assertEqual(b''.join(out), self.TEXT) + + def test_failure(self): + zlibd = zlib._ZlibDecompressor() + self.assertRaises(Exception, zlibd.decompress, self.BAD_DATA * 30) + # Previously, a second call could crash due to internal inconsistency + self.assertRaises(Exception, zlibd.decompress, self.BAD_DATA * 30) + + @support.refcount_test + def test_refleaks_in___init__(self): + gettotalrefcount = support.get_attribute(sys, 'gettotalrefcount') + zlibd = zlib._ZlibDecompressor() + refs_before = gettotalrefcount() + for i in range(100): + zlibd.__init__() + self.assertAlmostEqual(gettotalrefcount() - refs_before, 0, delta=10) + + class CustomInt: def __index__(self): return 100 diff --git a/Lib/test/test_zoneinfo/__init__.py b/Lib/test/test_zoneinfo/__init__.py index 98cc4412..c3ea5671 100644 --- a/Lib/test/test_zoneinfo/__init__.py +++ b/Lib/test/test_zoneinfo/__init__.py @@ -1 +1,2 @@ from .test_zoneinfo import * +from .test_zoneinfo_property import * diff --git a/Lib/test/test_zoneinfo/test_zoneinfo.py b/Lib/test/test_zoneinfo/test_zoneinfo.py index a2172f3a..ae921f74 100644 --- a/Lib/test/test_zoneinfo/test_zoneinfo.py +++ b/Lib/test/test_zoneinfo/test_zoneinfo.py @@ -404,6 +404,19 @@ class ZoneInfoTest(TzPathUserMixin, ZoneInfoTestBase): class CZoneInfoTest(ZoneInfoTest): module = c_zoneinfo + def test_signatures(self): + """Ensure that C module has valid method signatures.""" + import inspect + + must_have_signatures = ( + self.klass.clear_cache, + self.klass.no_cache, + self.klass.from_file, + ) + for method in must_have_signatures: + with self.subTest(method=method): + inspect.Signature.from_callable(method) + def test_fold_mutate(self): """Test that fold isn't mutated when no change is necessary. @@ -1530,13 +1543,20 @@ class TzPathTest(TzPathUserMixin, ZoneInfoTestBase): @contextlib.contextmanager def python_tzpath_context(value): path_var = "PYTHONTZPATH" + unset_env_sentinel = object() + old_env = unset_env_sentinel try: with OS_ENV_LOCK: old_env = os.environ.get(path_var, None) os.environ[path_var] = value yield finally: - if old_env is None: + if old_env is unset_env_sentinel: + # In this case, `old_env` was never retrieved from the + # environment for whatever reason, so there's no need to + # reset the environment TZPATH. + pass + elif old_env is None: del os.environ[path_var] else: os.environ[path_var] = old_env # pragma: nocover @@ -1784,12 +1804,10 @@ class ExtensionBuiltTest(unittest.TestCase): self.assertTrue(hasattr(py_zoneinfo.ZoneInfo, "_weak_cache")) def test_gc_tracked(self): - # The pure Python version is tracked by the GC but (for now) the C - # version is not. import gc self.assertTrue(gc.is_tracked(py_zoneinfo.ZoneInfo)) - self.assertFalse(gc.is_tracked(c_zoneinfo.ZoneInfo)) + self.assertTrue(gc.is_tracked(c_zoneinfo.ZoneInfo)) @dataclasses.dataclass(frozen=True) diff --git a/Lib/test/test_zoneinfo/test_zoneinfo_property.py b/Lib/test/test_zoneinfo/test_zoneinfo_property.py new file mode 100644 index 00000000..feaa77f3 --- /dev/null +++ b/Lib/test/test_zoneinfo/test_zoneinfo_property.py @@ -0,0 +1,368 @@ +import contextlib +import datetime +import os +import pickle +import unittest +import zoneinfo + +from test.support.hypothesis_helper import hypothesis + +import test.test_zoneinfo._support as test_support + +ZoneInfoTestBase = test_support.ZoneInfoTestBase + +py_zoneinfo, c_zoneinfo = test_support.get_modules() + +UTC = datetime.timezone.utc +MIN_UTC = datetime.datetime.min.replace(tzinfo=UTC) +MAX_UTC = datetime.datetime.max.replace(tzinfo=UTC) +ZERO = datetime.timedelta(0) + + +def _valid_keys(): + """Get available time zones, including posix/ and right/ directories.""" + from importlib import resources + + available_zones = sorted(zoneinfo.available_timezones()) + TZPATH = zoneinfo.TZPATH + + def valid_key(key): + for root in TZPATH: + key_file = os.path.join(root, key) + if os.path.exists(key_file): + return True + + components = key.split("/") + package_name = ".".join(["tzdata.zoneinfo"] + components[:-1]) + resource_name = components[-1] + + try: + return resources.files(package_name).joinpath(resource_name).is_file() + except ModuleNotFoundError: + return False + + # This relies on the fact that dictionaries maintain insertion order — for + # shrinking purposes, it is preferable to start with the standard version, + # then move to the posix/ version, then to the right/ version. + out_zones = {"": available_zones} + for prefix in ["posix", "right"]: + prefix_out = [] + for key in available_zones: + prefix_key = f"{prefix}/{key}" + if valid_key(prefix_key): + prefix_out.append(prefix_key) + + out_zones[prefix] = prefix_out + + output = [] + for keys in out_zones.values(): + output.extend(keys) + + return output + + +VALID_KEYS = _valid_keys() +if not VALID_KEYS: + raise unittest.SkipTest("No time zone data available") + + +def valid_keys(): + return hypothesis.strategies.sampled_from(VALID_KEYS) + + +KEY_EXAMPLES = [ + "Africa/Abidjan", + "Africa/Casablanca", + "America/Los_Angeles", + "America/Santiago", + "Asia/Tokyo", + "Australia/Sydney", + "Europe/Dublin", + "Europe/Lisbon", + "Europe/London", + "Pacific/Kiritimati", + "UTC", +] + + +def add_key_examples(f): + for key in KEY_EXAMPLES: + f = hypothesis.example(key)(f) + return f + + +class ZoneInfoTest(ZoneInfoTestBase): + module = py_zoneinfo + + @hypothesis.given(key=valid_keys()) + @add_key_examples + def test_str(self, key): + zi = self.klass(key) + self.assertEqual(str(zi), key) + + @hypothesis.given(key=valid_keys()) + @add_key_examples + def test_key(self, key): + zi = self.klass(key) + + self.assertEqual(zi.key, key) + + @hypothesis.given( + dt=hypothesis.strategies.one_of( + hypothesis.strategies.datetimes(), hypothesis.strategies.times() + ) + ) + @hypothesis.example(dt=datetime.datetime.min) + @hypothesis.example(dt=datetime.datetime.max) + @hypothesis.example(dt=datetime.datetime(1970, 1, 1)) + @hypothesis.example(dt=datetime.datetime(2039, 1, 1)) + @hypothesis.example(dt=datetime.time(0)) + @hypothesis.example(dt=datetime.time(12, 0)) + @hypothesis.example(dt=datetime.time(23, 59, 59, 999999)) + def test_utc(self, dt): + zi = self.klass("UTC") + dt_zi = dt.replace(tzinfo=zi) + + self.assertEqual(dt_zi.utcoffset(), ZERO) + self.assertEqual(dt_zi.dst(), ZERO) + self.assertEqual(dt_zi.tzname(), "UTC") + + +class CZoneInfoTest(ZoneInfoTest): + module = c_zoneinfo + + +class ZoneInfoPickleTest(ZoneInfoTestBase): + module = py_zoneinfo + + def setUp(self): + with contextlib.ExitStack() as stack: + stack.enter_context(test_support.set_zoneinfo_module(self.module)) + self.addCleanup(stack.pop_all().close) + + super().setUp() + + @hypothesis.given(key=valid_keys()) + @add_key_examples + def test_pickle_unpickle_cache(self, key): + zi = self.klass(key) + pkl_str = pickle.dumps(zi) + zi_rt = pickle.loads(pkl_str) + + self.assertIs(zi, zi_rt) + + @hypothesis.given(key=valid_keys()) + @add_key_examples + def test_pickle_unpickle_no_cache(self, key): + zi = self.klass.no_cache(key) + pkl_str = pickle.dumps(zi) + zi_rt = pickle.loads(pkl_str) + + self.assertIsNot(zi, zi_rt) + self.assertEqual(str(zi), str(zi_rt)) + + @hypothesis.given(key=valid_keys()) + @add_key_examples + def test_pickle_unpickle_cache_multiple_rounds(self, key): + """Test that pickle/unpickle is idempotent.""" + zi_0 = self.klass(key) + pkl_str_0 = pickle.dumps(zi_0) + zi_1 = pickle.loads(pkl_str_0) + pkl_str_1 = pickle.dumps(zi_1) + zi_2 = pickle.loads(pkl_str_1) + pkl_str_2 = pickle.dumps(zi_2) + + self.assertEqual(pkl_str_0, pkl_str_1) + self.assertEqual(pkl_str_1, pkl_str_2) + + self.assertIs(zi_0, zi_1) + self.assertIs(zi_0, zi_2) + self.assertIs(zi_1, zi_2) + + @hypothesis.given(key=valid_keys()) + @add_key_examples + def test_pickle_unpickle_no_cache_multiple_rounds(self, key): + """Test that pickle/unpickle is idempotent.""" + zi_cache = self.klass(key) + + zi_0 = self.klass.no_cache(key) + pkl_str_0 = pickle.dumps(zi_0) + zi_1 = pickle.loads(pkl_str_0) + pkl_str_1 = pickle.dumps(zi_1) + zi_2 = pickle.loads(pkl_str_1) + pkl_str_2 = pickle.dumps(zi_2) + + self.assertEqual(pkl_str_0, pkl_str_1) + self.assertEqual(pkl_str_1, pkl_str_2) + + self.assertIsNot(zi_0, zi_1) + self.assertIsNot(zi_0, zi_2) + self.assertIsNot(zi_1, zi_2) + + self.assertIsNot(zi_0, zi_cache) + self.assertIsNot(zi_1, zi_cache) + self.assertIsNot(zi_2, zi_cache) + + +class CZoneInfoPickleTest(ZoneInfoPickleTest): + module = c_zoneinfo + + +class ZoneInfoCacheTest(ZoneInfoTestBase): + module = py_zoneinfo + + @hypothesis.given(key=valid_keys()) + @add_key_examples + def test_cache(self, key): + zi_0 = self.klass(key) + zi_1 = self.klass(key) + + self.assertIs(zi_0, zi_1) + + @hypothesis.given(key=valid_keys()) + @add_key_examples + def test_no_cache(self, key): + zi_0 = self.klass.no_cache(key) + zi_1 = self.klass.no_cache(key) + + self.assertIsNot(zi_0, zi_1) + + +class CZoneInfoCacheTest(ZoneInfoCacheTest): + klass = c_zoneinfo.ZoneInfo + + +class PythonCConsistencyTest(unittest.TestCase): + """Tests that the C and Python versions do the same thing.""" + + def _is_ambiguous(self, dt): + return dt.replace(fold=not dt.fold).utcoffset() == dt.utcoffset() + + @hypothesis.given(dt=hypothesis.strategies.datetimes(), key=valid_keys()) + @hypothesis.example(dt=datetime.datetime.min, key="America/New_York") + @hypothesis.example(dt=datetime.datetime.max, key="America/New_York") + @hypothesis.example(dt=datetime.datetime(1970, 1, 1), key="America/New_York") + @hypothesis.example(dt=datetime.datetime(2020, 1, 1), key="Europe/Paris") + @hypothesis.example(dt=datetime.datetime(2020, 6, 1), key="Europe/Paris") + def test_same_str(self, dt, key): + py_dt = dt.replace(tzinfo=py_zoneinfo.ZoneInfo(key)) + c_dt = dt.replace(tzinfo=c_zoneinfo.ZoneInfo(key)) + + self.assertEqual(str(py_dt), str(c_dt)) + + @hypothesis.given(dt=hypothesis.strategies.datetimes(), key=valid_keys()) + @hypothesis.example(dt=datetime.datetime(1970, 1, 1), key="America/New_York") + @hypothesis.example(dt=datetime.datetime(2020, 2, 5), key="America/New_York") + @hypothesis.example(dt=datetime.datetime(2020, 8, 12), key="America/New_York") + @hypothesis.example(dt=datetime.datetime(2040, 1, 1), key="Africa/Casablanca") + @hypothesis.example(dt=datetime.datetime(1970, 1, 1), key="Europe/Paris") + @hypothesis.example(dt=datetime.datetime(2040, 1, 1), key="Europe/Paris") + @hypothesis.example(dt=datetime.datetime.min, key="Asia/Tokyo") + @hypothesis.example(dt=datetime.datetime.max, key="Asia/Tokyo") + def test_same_offsets_and_names(self, dt, key): + py_dt = dt.replace(tzinfo=py_zoneinfo.ZoneInfo(key)) + c_dt = dt.replace(tzinfo=c_zoneinfo.ZoneInfo(key)) + + self.assertEqual(py_dt.tzname(), c_dt.tzname()) + self.assertEqual(py_dt.utcoffset(), c_dt.utcoffset()) + self.assertEqual(py_dt.dst(), c_dt.dst()) + + @hypothesis.given( + dt=hypothesis.strategies.datetimes(timezones=hypothesis.strategies.just(UTC)), + key=valid_keys(), + ) + @hypothesis.example(dt=MIN_UTC, key="Asia/Tokyo") + @hypothesis.example(dt=MAX_UTC, key="Asia/Tokyo") + @hypothesis.example(dt=MIN_UTC, key="America/New_York") + @hypothesis.example(dt=MAX_UTC, key="America/New_York") + @hypothesis.example( + dt=datetime.datetime(2006, 10, 29, 5, 15, tzinfo=UTC), + key="America/New_York", + ) + def test_same_from_utc(self, dt, key): + py_zi = py_zoneinfo.ZoneInfo(key) + c_zi = c_zoneinfo.ZoneInfo(key) + + # Convert to UTC: This can overflow, but we just care about consistency + py_overflow_exc = None + c_overflow_exc = None + try: + py_dt = dt.astimezone(py_zi) + except OverflowError as e: + py_overflow_exc = e + + try: + c_dt = dt.astimezone(c_zi) + except OverflowError as e: + c_overflow_exc = e + + if (py_overflow_exc is not None) != (c_overflow_exc is not None): + raise py_overflow_exc or c_overflow_exc # pragma: nocover + + if py_overflow_exc is not None: + return # Consistently raises the same exception + + # PEP 495 says that an inter-zone comparison between ambiguous + # datetimes is always False. + if py_dt != c_dt: + self.assertEqual( + self._is_ambiguous(py_dt), + self._is_ambiguous(c_dt), + (py_dt, c_dt), + ) + + self.assertEqual(py_dt.tzname(), c_dt.tzname()) + self.assertEqual(py_dt.utcoffset(), c_dt.utcoffset()) + self.assertEqual(py_dt.dst(), c_dt.dst()) + + @hypothesis.given(dt=hypothesis.strategies.datetimes(), key=valid_keys()) + @hypothesis.example(dt=datetime.datetime.max, key="America/New_York") + @hypothesis.example(dt=datetime.datetime.min, key="America/New_York") + @hypothesis.example(dt=datetime.datetime.min, key="Asia/Tokyo") + @hypothesis.example(dt=datetime.datetime.max, key="Asia/Tokyo") + def test_same_to_utc(self, dt, key): + py_dt = dt.replace(tzinfo=py_zoneinfo.ZoneInfo(key)) + c_dt = dt.replace(tzinfo=c_zoneinfo.ZoneInfo(key)) + + # Convert from UTC: Overflow OK if it happens in both implementations + py_overflow_exc = None + c_overflow_exc = None + try: + py_utc = py_dt.astimezone(UTC) + except OverflowError as e: + py_overflow_exc = e + + try: + c_utc = c_dt.astimezone(UTC) + except OverflowError as e: + c_overflow_exc = e + + if (py_overflow_exc is not None) != (c_overflow_exc is not None): + raise py_overflow_exc or c_overflow_exc # pragma: nocover + + if py_overflow_exc is not None: + return # Consistently raises the same exception + + self.assertEqual(py_utc, c_utc) + + @hypothesis.given(key=valid_keys()) + @add_key_examples + def test_cross_module_pickle(self, key): + py_zi = py_zoneinfo.ZoneInfo(key) + c_zi = c_zoneinfo.ZoneInfo(key) + + with test_support.set_zoneinfo_module(py_zoneinfo): + py_pkl = pickle.dumps(py_zi) + + with test_support.set_zoneinfo_module(c_zoneinfo): + c_pkl = pickle.dumps(c_zi) + + with test_support.set_zoneinfo_module(c_zoneinfo): + # Python → C + py_to_c_zi = pickle.loads(py_pkl) + self.assertIs(py_to_c_zi, c_zi) + + with test_support.set_zoneinfo_module(py_zoneinfo): + # C → Python + c_to_py_zi = pickle.loads(c_pkl) + self.assertIs(c_to_py_zi, py_zi) diff --git a/Lib/test/wheel-0.40.0-py3-none-any.whl b/Lib/test/wheel-0.40.0-py3-none-any.whl new file mode 100644 index 0000000000000000000000000000000000000000..410132385bba4d3919508eb280a9095a796f3c7e GIT binary patch literal 64545 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 HKR^9HaRT!n literal 0 HcmV?d00001 diff --git a/Lib/threading.py b/Lib/threading.py index 4f729385..df273870 100644 --- a/Lib/threading.py +++ b/Lib/threading.py @@ -7,7 +7,7 @@ import functools from time import monotonic as _time from _weakrefset import WeakSet -from itertools import islice as _islice, count as _count +from itertools import count as _count try: from _collections import deque as _deque except ImportError: @@ -28,10 +28,12 @@ __all__ = ['get_ident', 'active_count', 'Condition', 'current_thread', 'Event', 'Lock', 'RLock', 'Semaphore', 'BoundedSemaphore', 'Thread', 'Barrier', 'BrokenBarrierError', 'Timer', 'ThreadError', 'setprofile', 'settrace', 'local', 'stack_size', - 'excepthook', 'ExceptHookArgs', 'gettrace', 'getprofile'] + 'excepthook', 'ExceptHookArgs', 'gettrace', 'getprofile', + 'setprofile_all_threads','settrace_all_threads'] # Rename some stuff so "from threading import *" is safe _start_new_thread = _thread.start_new_thread +_daemon_threads_allowed = _thread.daemon_threads_allowed _allocate_lock = _thread.allocate_lock _set_sentinel = _thread._set_sentinel get_ident = _thread.get_ident @@ -60,11 +62,20 @@ def setprofile(func): The func will be passed to sys.setprofile() for each thread, before its run() method is called. - """ global _profile_hook _profile_hook = func +def setprofile_all_threads(func): + """Set a profile function for all threads started from the threading module + and all Python threads that are currently executing. + + The func will be passed to sys.setprofile() for each thread, before its + run() method is called. + """ + setprofile(func) + _sys._setprofileallthreads(func) + def getprofile(): """Get the profiler function as set by threading.setprofile().""" return _profile_hook @@ -74,11 +85,20 @@ def settrace(func): The func will be passed to sys.settrace() for each thread, before its run() method is called. - """ global _trace_hook _trace_hook = func +def settrace_all_threads(func): + """Set a trace function for all threads started from the threading module + and all Python threads that are currently executing. + + The func will be passed to sys.settrace() for each thread, before its run() + method is called. + """ + settrace(func) + _sys._settraceallthreads(func) + def gettrace(): """Get the trace function as set by threading.settrace().""" return _trace_hook @@ -243,18 +263,12 @@ class Condition: # If the lock defines _release_save() and/or _acquire_restore(), # these override the default implementations (which just call # release() and acquire() on the lock). Ditto for _is_owned(). - try: + if hasattr(lock, '_release_save'): self._release_save = lock._release_save - except AttributeError: - pass - try: + if hasattr(lock, '_acquire_restore'): self._acquire_restore = lock._acquire_restore - except AttributeError: - pass - try: + if hasattr(lock, '_is_owned'): self._is_owned = lock._is_owned - except AttributeError: - pass self._waiters = _deque() def _at_fork_reinit(self): @@ -488,8 +502,7 @@ class Semaphore: raise ValueError('n must be one or more') with self._cond: self._value += n - for i in range(n): - self._cond.notify() + self._cond.notify(n) def __exit__(self, t, v, tb): self.release() @@ -513,7 +526,7 @@ class BoundedSemaphore(Semaphore): """ def __init__(self, value=1): - Semaphore.__init__(self, value) + super().__init__(value) self._initial_value = value def __repr__(self): @@ -537,8 +550,7 @@ class BoundedSemaphore(Semaphore): if self._value + n > self._initial_value: raise ValueError("Semaphore released too many times") self._value += n - for i in range(n): - self._cond.notify() + self._cond.notify(n) class Event: @@ -888,6 +900,8 @@ class Thread: self._args = args self._kwargs = kwargs if daemon is not None: + if daemon and not _daemon_threads_allowed(): + raise RuntimeError('daemon threads are disabled in this (sub)interpreter') self._daemonic = daemon else: self._daemonic = current_thread().daemon @@ -1215,6 +1229,8 @@ class Thread: def daemon(self, daemonic): if not self._initialized: raise RuntimeError("Thread.__init__() not called") + if daemonic and not _daemon_threads_allowed(): + raise RuntimeError('daemon threads are disabled in this interpreter') if self._started.is_set(): raise RuntimeError("cannot set daemon status of active thread") self._daemonic = daemonic @@ -1421,7 +1437,8 @@ class _MainThread(Thread): class _DummyThread(Thread): def __init__(self): - Thread.__init__(self, name=_newname("Dummy-%d"), daemon=True) + Thread.__init__(self, name=_newname("Dummy-%d"), + daemon=_daemon_threads_allowed()) self._started.set() self._set_ident() @@ -1473,6 +1490,8 @@ def active_count(): enumerate(). """ + # NOTE: if the logic in here ever changes, update Modules/posixmodule.c + # warn_about_fork_with_threads() to match. with _active_limbo_lock: return len(_active) + len(_limbo) diff --git a/Lib/timeit.py b/Lib/timeit.py index 9dfd4549..02cfafaf 100755 --- a/Lib/timeit.py +++ b/Lib/timeit.py @@ -50,9 +50,9 @@ Functions: """ import gc +import itertools import sys import time -import itertools __all__ = ["Timer", "timeit", "repeat", "default_timer"] @@ -77,9 +77,11 @@ def inner(_it, _timer{init}): return _t1 - _t0 """ + def reindent(src, indent): """Helper to reindent a multi-line statement.""" - return src.replace("\n", "\n" + " "*indent) + return src.replace("\n", "\n" + " " * indent) + class Timer: """Class for timing execution speed of small code snippets. @@ -166,7 +168,7 @@ class Timer: To be precise, this executes the setup statement once, and then returns the time it takes to execute the main statement - a number of times, as a float measured in seconds. The + a number of times, as float seconds if using the default timer. The argument is the number of times through the loop, defaulting to one million. The main statement, the setup statement and the timer function to be used are passed to the constructor. @@ -228,16 +230,19 @@ class Timer: return (number, time_taken) i *= 10 + def timeit(stmt="pass", setup="pass", timer=default_timer, number=default_number, globals=None): """Convenience function to create Timer object and call timeit method.""" return Timer(stmt, setup, timer, globals).timeit(number) + def repeat(stmt="pass", setup="pass", timer=default_timer, repeat=default_repeat, number=default_number, globals=None): """Convenience function to create Timer object and call repeat method.""" return Timer(stmt, setup, timer, globals).repeat(repeat, number) + def main(args=None, *, _wrap_timer=None): """Main program, used when run as a script. @@ -259,10 +264,9 @@ def main(args=None, *, _wrap_timer=None): args = sys.argv[1:] import getopt try: - opts, args = getopt.getopt(args, "n:u:s:r:tcpvh", + opts, args = getopt.getopt(args, "n:u:s:r:pvh", ["number=", "setup=", "repeat=", - "time", "clock", "process", - "verbose", "unit=", "help"]) + "process", "verbose", "unit=", "help"]) except getopt.error as err: print(err) print("use -h/--help for command line help") @@ -270,7 +274,7 @@ def main(args=None, *, _wrap_timer=None): timer = default_timer stmt = "\n".join(args) or "pass" - number = 0 # auto-determine + number = 0 # auto-determine setup = [] repeat = default_repeat verbose = 0 @@ -287,7 +291,7 @@ def main(args=None, *, _wrap_timer=None): time_unit = a else: print("Unrecognized unit. Please select nsec, usec, msec, or sec.", - file=sys.stderr) + file=sys.stderr) return 2 if o in ("-r", "--repeat"): repeat = int(a) @@ -321,7 +325,7 @@ def main(args=None, *, _wrap_timer=None): msg = "{num} loop{s} -> {secs:.{prec}g} secs" plural = (number != 1) print(msg.format(num=number, s='s' if plural else '', - secs=time_taken, prec=precision)) + secs=time_taken, prec=precision)) try: number, _ = t.autorange(callback) except: @@ -372,5 +376,6 @@ def main(args=None, *, _wrap_timer=None): UserWarning, '', 0) return None + if __name__ == "__main__": sys.exit(main()) diff --git a/Lib/tkinter/__init__.py b/Lib/tkinter/__init__.py index 7565e0f7..c59f8d11 100644 --- a/Lib/tkinter/__init__.py +++ b/Lib/tkinter/__init__.py @@ -2400,6 +2400,7 @@ class Tk(Misc, Wm): should when sys.stderr is None.""" import traceback print("Exception in Tkinter callback", file=sys.stderr) + sys.last_exc = val sys.last_type = exc sys.last_value = val sys.last_traceback = tb @@ -2816,7 +2817,7 @@ class Canvas(Widget, XView, YView): def coords(self, *args): """Return a list of coordinates for the item given in ARGS.""" - # XXX Should use _flatten on args + args = _flatten(args) return [self.tk.getdouble(x) for x in self.tk.splitlist( self.tk.call((self._w, 'coords') + args))] @@ -3429,8 +3430,7 @@ class Menu(Widget): def index(self, index): """Return the index of a menu item identified by INDEX.""" i = self.tk.call(self._w, 'index', index) - if i == 'none': return None - return self.tk.getint(i) + return None if i in ('', 'none') else self.tk.getint(i) # GH-103685. def invoke(self, index): """Invoke a menu item identified by INDEX and execute @@ -4069,8 +4069,6 @@ class Image: elif kw: cnf = kw options = () for k, v in cnf.items(): - if callable(v): - v = self._register(v) options = options + ('-'+k, v) self.tk.call(('image', 'create', imgtype, name,) + options) self.name = name @@ -4097,8 +4095,6 @@ class Image: for k, v in _cnfmerge(kw).items(): if v is not None: if k[-1] == '_': k = k[:-1] - if callable(v): - v = self._register(v) res = res + ('-'+k, v) self.tk.call((self.name, 'config') + res) diff --git a/Lib/tkinter/commondialog.py b/Lib/tkinter/commondialog.py index e595c99d..86f5387e 100644 --- a/Lib/tkinter/commondialog.py +++ b/Lib/tkinter/commondialog.py @@ -10,7 +10,7 @@ __all__ = ["Dialog"] -from tkinter import Frame, _get_temp_root, _destroy_temp_root +from tkinter import _get_temp_root, _destroy_temp_root class Dialog: diff --git a/Lib/tkinter/filedialog.py b/Lib/tkinter/filedialog.py index 600d0bd4..e2eff98e 100644 --- a/Lib/tkinter/filedialog.py +++ b/Lib/tkinter/filedialog.py @@ -461,7 +461,6 @@ def test(): # Start off with UTF-8 enc = "utf-8" - import sys # See whether CODESET is defined try: @@ -477,9 +476,9 @@ def test(): try: fp=open(openfilename,"r") fp.close() - except: + except BaseException as exc: print("Could not open File: ") - print(sys.exc_info()[1]) + print(exc) print("open", openfilename.encode(enc)) diff --git a/Lib/tkinter/test/test_ttk/__init__.py b/Lib/tkinter/test/test_ttk/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/Lib/token.py b/Lib/token.py index 9d0c0bf0..487f6edd 100644 --- a/Lib/token.py +++ b/Lib/token.py @@ -1,5 +1,5 @@ """Token constants.""" -# Auto-generated by Tools/scripts/generate_token.py +# Auto-generated by Tools/build/generate_token.py __all__ = ['tok_name', 'ISTERMINAL', 'ISNONTERMINAL', 'ISEOF'] @@ -57,18 +57,22 @@ ATEQUAL = 50 RARROW = 51 ELLIPSIS = 52 COLONEQUAL = 53 -OP = 54 -AWAIT = 55 -ASYNC = 56 -TYPE_IGNORE = 57 -TYPE_COMMENT = 58 -SOFT_KEYWORD = 59 +EXCLAMATION = 54 +OP = 55 +AWAIT = 56 +ASYNC = 57 +TYPE_IGNORE = 58 +TYPE_COMMENT = 59 +SOFT_KEYWORD = 60 +FSTRING_START = 61 +FSTRING_MIDDLE = 62 +FSTRING_END = 63 +COMMENT = 64 +NL = 65 # These aren't used by the C tokenizer but are needed for tokenize.py -ERRORTOKEN = 60 -COMMENT = 61 -NL = 62 -ENCODING = 63 -N_TOKENS = 64 +ERRORTOKEN = 66 +ENCODING = 67 +N_TOKENS = 68 # Special definitions for cooperation with parser NT_OFFSET = 256 @@ -78,6 +82,7 @@ tok_name = {value: name __all__.extend(tok_name.values()) EXACT_TOKEN_TYPES = { + '!': EXCLAMATION, '!=': NOTEQUAL, '%': PERCENT, '%=': PERCENTEQUAL, diff --git a/Lib/tokenize.py b/Lib/tokenize.py index 46d2224f..49e8144e 100644 --- a/Lib/tokenize.py +++ b/Lib/tokenize.py @@ -34,6 +34,7 @@ import re import sys from token import * from token import EXACT_TOKEN_TYPES +import _tokenize cookie_re = re.compile(r'^[ \t\f]*#.*?coding[:=][ \t]*([-\w.]+)', re.ASCII) blank_re = re.compile(br'^[ \t\f]*(?:[#\r\n]|$)', re.ASCII) @@ -160,8 +161,8 @@ tabsize = 8 class TokenError(Exception): pass -class StopTokenizing(Exception): pass +class StopTokenizing(Exception): pass class Untokenizer: @@ -213,6 +214,14 @@ class Untokenizer: self.tokens.append(indent) self.prev_col = len(indent) startline = False + elif tok_type == FSTRING_MIDDLE: + if '{' in token or '}' in token: + end_line, end_col = end + end = (end_line, end_col + token.count('{') + token.count('}')) + token = re.sub('{', '{{', token) + token = re.sub('}', '}}', token) + + self.add_whitespace(start) self.tokens.append(token) self.prev_row, self.prev_col = end @@ -255,6 +264,11 @@ class Untokenizer: elif startline and indents: toks_append(indents[-1]) startline = False + elif toknum == FSTRING_MIDDLE: + if '{' in tokval or '}' in tokval: + tokval = re.sub('{', '{{', tokval) + tokval = re.sub('}', '}}', tokval) + toks_append(tokval) @@ -404,7 +418,6 @@ def open(filename): buffer.close() raise - def tokenize(readline): """ The tokenize() generator requires one argument, readline, which @@ -425,193 +438,13 @@ def tokenize(readline): which tells you which encoding was used to decode the bytes stream. """ encoding, consumed = detect_encoding(readline) - empty = _itertools.repeat(b"") - rl_gen = _itertools.chain(consumed, iter(readline, b""), empty) - return _tokenize(rl_gen.__next__, encoding) - - -def _tokenize(readline, encoding): - lnum = parenlev = continued = 0 - numchars = '0123456789' - contstr, needcont = '', 0 - contline = None - indents = [0] - + rl_gen = _itertools.chain(consumed, iter(readline, b"")) if encoding is not None: if encoding == "utf-8-sig": # BOM will already have been stripped. encoding = "utf-8" yield TokenInfo(ENCODING, encoding, (0, 0), (0, 0), '') - last_line = b'' - line = b'' - while True: # loop over lines in stream - try: - # We capture the value of the line variable here because - # readline uses the empty string '' to signal end of input, - # hence `line` itself will always be overwritten at the end - # of this loop. - last_line = line - line = readline() - except StopIteration: - line = b'' - - if encoding is not None: - line = line.decode(encoding) - lnum += 1 - pos, max = 0, len(line) - - if contstr: # continued string - if not line: - raise TokenError("EOF in multi-line string", strstart) - endmatch = endprog.match(line) - if endmatch: - pos = end = endmatch.end(0) - yield TokenInfo(STRING, contstr + line[:end], - strstart, (lnum, end), contline + line) - contstr, needcont = '', 0 - contline = None - elif needcont and line[-2:] != '\\\n' and line[-3:] != '\\\r\n': - yield TokenInfo(ERRORTOKEN, contstr + line, - strstart, (lnum, len(line)), contline) - contstr = '' - contline = None - continue - else: - contstr = contstr + line - contline = contline + line - continue - - elif parenlev == 0 and not continued: # new statement - if not line: break - column = 0 - while pos < max: # measure leading whitespace - if line[pos] == ' ': - column += 1 - elif line[pos] == '\t': - column = (column//tabsize + 1)*tabsize - elif line[pos] == '\f': - column = 0 - else: - break - pos += 1 - if pos == max: - break - - if line[pos] in '#\r\n': # skip comments or blank lines - if line[pos] == '#': - comment_token = line[pos:].rstrip('\r\n') - yield TokenInfo(COMMENT, comment_token, - (lnum, pos), (lnum, pos + len(comment_token)), line) - pos += len(comment_token) - - yield TokenInfo(NL, line[pos:], - (lnum, pos), (lnum, len(line)), line) - continue - - if column > indents[-1]: # count indents or dedents - indents.append(column) - yield TokenInfo(INDENT, line[:pos], (lnum, 0), (lnum, pos), line) - while column < indents[-1]: - if column not in indents: - raise IndentationError( - "unindent does not match any outer indentation level", - ("<tokenize>", lnum, pos, line)) - indents = indents[:-1] - - yield TokenInfo(DEDENT, '', (lnum, pos), (lnum, pos), line) - - else: # continued statement - if not line: - raise TokenError("EOF in multi-line statement", (lnum, 0)) - continued = 0 - - while pos < max: - pseudomatch = _compile(PseudoToken).match(line, pos) - if pseudomatch: # scan for tokens - start, end = pseudomatch.span(1) - spos, epos, pos = (lnum, start), (lnum, end), end - if start == end: - continue - token, initial = line[start:end], line[start] - - if (initial in numchars or # ordinary number - (initial == '.' and token != '.' and token != '...')): - yield TokenInfo(NUMBER, token, spos, epos, line) - elif initial in '\r\n': - if parenlev > 0: - yield TokenInfo(NL, token, spos, epos, line) - else: - yield TokenInfo(NEWLINE, token, spos, epos, line) - - elif initial == '#': - assert not token.endswith("\n") - yield TokenInfo(COMMENT, token, spos, epos, line) - - elif token in triple_quoted: - endprog = _compile(endpats[token]) - endmatch = endprog.match(line, pos) - if endmatch: # all on one line - pos = endmatch.end(0) - token = line[start:pos] - yield TokenInfo(STRING, token, spos, (lnum, pos), line) - else: - strstart = (lnum, start) # multiple lines - contstr = line[start:] - contline = line - break - - # Check up to the first 3 chars of the token to see if - # they're in the single_quoted set. If so, they start - # a string. - # We're using the first 3, because we're looking for - # "rb'" (for example) at the start of the token. If - # we switch to longer prefixes, this needs to be - # adjusted. - # Note that initial == token[:1]. - # Also note that single quote checking must come after - # triple quote checking (above). - elif (initial in single_quoted or - token[:2] in single_quoted or - token[:3] in single_quoted): - if token[-1] == '\n': # continued string - strstart = (lnum, start) - # Again, using the first 3 chars of the - # token. This is looking for the matching end - # regex for the correct type of quote - # character. So it's really looking for - # endpats["'"] or endpats['"'], by trying to - # skip string prefix characters, if any. - endprog = _compile(endpats.get(initial) or - endpats.get(token[1]) or - endpats.get(token[2])) - contstr, needcont = line[start:], 1 - contline = line - break - else: # ordinary string - yield TokenInfo(STRING, token, spos, epos, line) - - elif initial.isidentifier(): # ordinary name - yield TokenInfo(NAME, token, spos, epos, line) - elif initial == '\\': # continued stmt - continued = 1 - else: - if initial in '([{': - parenlev += 1 - elif initial in ')]}': - parenlev -= 1 - yield TokenInfo(OP, token, spos, epos, line) - else: - yield TokenInfo(ERRORTOKEN, line[pos], - (lnum, pos), (lnum, pos+1), line) - pos += 1 - - # Add an implicit NEWLINE if the input doesn't end in one - if last_line and last_line[-1] not in '\r\n' and not last_line.strip().startswith("#"): - yield TokenInfo(NEWLINE, '', (lnum - 1, len(last_line)), (lnum - 1, len(last_line) + 1), '') - for indent in indents[1:]: # pop remaining indent levels - yield TokenInfo(DEDENT, '', (lnum, 0), (lnum, 0), '') - yield TokenInfo(ENDMARKER, '', (lnum, 0), (lnum, 0), '') - + yield from _generate_tokens_from_c_tokenizer(rl_gen.__next__, encoding, extra_tokens=True) def generate_tokens(readline): """Tokenize a source reading Python code as unicode strings. @@ -619,7 +452,7 @@ def generate_tokens(readline): This has the same API as tokenize(), except that it expects the *readline* callable to return str objects instead of bytes. """ - return _tokenize(readline, None) + return _generate_tokens_from_c_tokenizer(readline, extra_tokens=True) def main(): import argparse @@ -656,7 +489,9 @@ def main(): tokens = list(tokenize(f.readline)) else: filename = "<stdin>" - tokens = _tokenize(sys.stdin.readline, None) + tokens = _generate_tokens_from_c_tokenizer( + sys.stdin.readline, extra_tokens=True) + # Output the tokenization for token in tokens: @@ -682,12 +517,30 @@ def main(): perror("unexpected error: %s" % err) raise -def _generate_tokens_from_c_tokenizer(source): +def _transform_msg(msg): + """Transform error messages from the C tokenizer into the Python tokenize + + The C tokenizer is more picky than the Python one, so we need to massage + the error messages a bit for backwards compatibility. + """ + if "unterminated triple-quoted string literal" in msg: + return "EOF in multi-line string" + return msg + +def _generate_tokens_from_c_tokenizer(source, encoding=None, extra_tokens=False): """Tokenize a source reading Python code as unicode strings using the internal C tokenizer""" - import _tokenize as c_tokenizer - for info in c_tokenizer.TokenizerIter(source): - tok, type, lineno, end_lineno, col_off, end_col_off, line = info - yield TokenInfo(type, tok, (lineno, col_off), (end_lineno, end_col_off), line) + if encoding is None: + it = _tokenize.TokenizerIter(source, extra_tokens=extra_tokens) + else: + it = _tokenize.TokenizerIter(source, encoding=encoding, extra_tokens=extra_tokens) + try: + for info in it: + yield TokenInfo._make(info) + except SyntaxError as e: + if type(e) != SyntaxError: + raise e from None + msg = _transform_msg(e.msg) + raise TokenError(msg, (e.lineno, e.offset)) from None if __name__ == "__main__": diff --git a/Lib/trace.py b/Lib/trace.py index 213e4651..fb9a423e 100755 --- a/Lib/trace.py +++ b/Lib/trace.py @@ -49,6 +49,7 @@ Sample use, programmatically """ __all__ = ['Trace', 'CoverageResults'] +import io import linecache import os import sys @@ -716,7 +717,7 @@ def main(): sys.argv = [opts.progname, *opts.arguments] sys.path[0] = os.path.dirname(opts.progname) - with open(opts.progname, 'rb') as fp: + with io.open_code(opts.progname) as fp: code = compile(fp.read(), opts.progname, 'exec') # try to emulate __main__ namespace as much as possible globs = { diff --git a/Lib/traceback.py b/Lib/traceback.py index 0182bb75..813e13e1 100644 --- a/Lib/traceback.py +++ b/Lib/traceback.py @@ -179,20 +179,24 @@ def _safe_string(value, what, func=str): # -- def print_exc(limit=None, file=None, chain=True): - """Shorthand for 'print_exception(*sys.exc_info(), limit, file)'.""" - print_exception(*sys.exc_info(), limit=limit, file=file, chain=chain) + """Shorthand for 'print_exception(sys.exception(), limit, file, chain)'.""" + print_exception(sys.exception(), limit=limit, file=file, chain=chain) def format_exc(limit=None, chain=True): """Like print_exc() but return a string.""" - return "".join(format_exception(*sys.exc_info(), limit=limit, chain=chain)) + return "".join(format_exception(sys.exception(), limit=limit, chain=chain)) def print_last(limit=None, file=None, chain=True): - """This is a shorthand for 'print_exception(sys.last_type, - sys.last_value, sys.last_traceback, limit, file)'.""" - if not hasattr(sys, "last_type"): + """This is a shorthand for 'print_exception(sys.last_exc, limit, file, chain)'.""" + if not hasattr(sys, "last_exc") and not hasattr(sys, "last_type"): raise ValueError("no last exception") - print_exception(sys.last_type, sys.last_value, sys.last_traceback, - limit, file, chain) + + if hasattr(sys, "last_exc"): + print_exception(sys.last_exc, limit, file, chain) + else: + print_exception(sys.last_type, sys.last_value, sys.last_traceback, + limit, file, chain) + # # Printing and Extracting Stacks. @@ -279,7 +283,8 @@ class FrameSummary: self._line = line if lookup_line: self.line - self.locals = {k: repr(v) for k, v in locals.items()} if locals else None + self.locals = {k: _safe_string(v, 'local', func=repr) + for k, v in locals.items()} if locals else None self.end_lineno = end_lineno self.colno = colno self.end_colno = end_colno @@ -603,11 +608,21 @@ def _extract_caret_anchors_from_line_segment(segment): and not operator_str[operator_offset + 1].isspace() ): right_anchor += 1 + + while left_anchor < len(segment) and ((ch := segment[left_anchor]).isspace() or ch in ")#"): + left_anchor += 1 + right_anchor += 1 return _Anchors(normalize(left_anchor), normalize(right_anchor)) case ast.Subscript(): - subscript_start = normalize(expr.value.end_col_offset) - subscript_end = normalize(expr.slice.end_col_offset + 1) - return _Anchors(subscript_start, subscript_end) + left_anchor = normalize(expr.value.end_col_offset) + right_anchor = normalize(expr.slice.end_col_offset + 1) + while left_anchor < len(segment) and ((ch := segment[left_anchor]).isspace() or ch != "["): + left_anchor += 1 + while right_anchor < len(segment) and ((ch := segment[right_anchor]).isspace() or ch != "]"): + right_anchor += 1 + if right_anchor < len(segment): + right_anchor += 1 + return _Anchors(left_anchor, right_anchor) return None @@ -653,6 +668,8 @@ class TracebackException: - :attr:`__cause__` A TracebackException of the original *__cause__*. - :attr:`__context__` A TracebackException of the original *__context__*. + - :attr:`exceptions` For exception groups - a list of TracebackException + instances for the nested *exceptions*. ``None`` for other exceptions. - :attr:`__suppress_context__` The *__suppress_context__* value from the original exception. - :attr:`stack` A `StackSummary` representing the traceback. @@ -667,8 +684,8 @@ class TracebackException: occurred. - :attr:`offset` For syntax errors - the offset into the text where the error occurred. - - :attr:`end_offset` For syntax errors - the offset into the text where the - error occurred. Can be `None` if not present. + - :attr:`end_offset` For syntax errors - the end offset into the text where + the error occurred. Can be `None` if not present. - :attr:`msg` For syntax errors - the compiler error message. """ @@ -708,6 +725,25 @@ class TracebackException: self.offset = exc_value.offset self.end_offset = exc_value.end_offset self.msg = exc_value.msg + elif exc_type and issubclass(exc_type, ImportError) and \ + getattr(exc_value, "name_from", None) is not None: + wrong_name = getattr(exc_value, "name_from", None) + suggestion = _compute_suggestion_error(exc_value, exc_traceback, wrong_name) + if suggestion: + self._str += f". Did you mean: '{suggestion}'?" + elif exc_type and issubclass(exc_type, (NameError, AttributeError)) and \ + getattr(exc_value, "name", None) is not None: + wrong_name = getattr(exc_value, "name", None) + suggestion = _compute_suggestion_error(exc_value, exc_traceback, wrong_name) + if suggestion: + self._str += f". Did you mean: '{suggestion}'?" + if issubclass(exc_type, NameError): + wrong_name = getattr(exc_value, "name", None) + if wrong_name is not None and wrong_name in sys.stdlib_module_names: + if suggestion: + self._str += f" Or did you forget to import '{wrong_name}'" + else: + self._str += f". Did you forget to import '{wrong_name}'" if lookup_lines: self._load_lines() self.__suppress_context__ = \ @@ -828,12 +864,16 @@ class TracebackException: yield _format_final_exc_line(stype, self._str) else: yield from self._format_syntax_error(stype) - if isinstance(self.__notes__, collections.abc.Sequence): + + if ( + isinstance(self.__notes__, collections.abc.Sequence) + and not isinstance(self.__notes__, (str, bytes)) + ): for note in self.__notes__: note = _safe_string(note, 'note') yield from [l + '\n' for l in note.split('\n')] elif self.__notes__ is not None: - yield _safe_string(self.__notes__, '__notes__', func=repr) + yield "{}\n".format(_safe_string(self.__notes__, '__notes__', func=repr)) def _format_syntax_error(self, stype): """Format SyntaxError exceptions (internal helper).""" @@ -978,3 +1018,140 @@ class TracebackException: file = sys.stderr for line in self.format(chain=chain): print(line, file=file, end="") + + +_MAX_CANDIDATE_ITEMS = 750 +_MAX_STRING_SIZE = 40 +_MOVE_COST = 2 +_CASE_COST = 1 + + +def _substitution_cost(ch_a, ch_b): + if ch_a == ch_b: + return 0 + if ch_a.lower() == ch_b.lower(): + return _CASE_COST + return _MOVE_COST + + +def _compute_suggestion_error(exc_value, tb, wrong_name): + if wrong_name is None or not isinstance(wrong_name, str): + return None + if isinstance(exc_value, AttributeError): + obj = exc_value.obj + try: + d = dir(obj) + except Exception: + return None + elif isinstance(exc_value, ImportError): + try: + mod = __import__(exc_value.name) + d = dir(mod) + except Exception: + return None + else: + assert isinstance(exc_value, NameError) + # find most recent frame + if tb is None: + return None + while tb.tb_next is not None: + tb = tb.tb_next + frame = tb.tb_frame + d = ( + list(frame.f_locals) + + list(frame.f_globals) + + list(frame.f_builtins) + ) + + # Check first if we are in a method and the instance + # has the wrong name as attribute + if 'self' in frame.f_locals: + self = frame.f_locals['self'] + if hasattr(self, wrong_name): + return f"self.{wrong_name}" + + # Compute closest match + + if len(d) > _MAX_CANDIDATE_ITEMS: + return None + wrong_name_len = len(wrong_name) + if wrong_name_len > _MAX_STRING_SIZE: + return None + best_distance = wrong_name_len + suggestion = None + for possible_name in d: + if possible_name == wrong_name: + # A missing attribute is "found". Don't suggest it (see GH-88821). + continue + # No more than 1/3 of the involved characters should need changed. + max_distance = (len(possible_name) + wrong_name_len + 3) * _MOVE_COST // 6 + # Don't take matches we've already beaten. + max_distance = min(max_distance, best_distance - 1) + current_distance = _levenshtein_distance(wrong_name, possible_name, max_distance) + if current_distance > max_distance: + continue + if not suggestion or current_distance < best_distance: + suggestion = possible_name + best_distance = current_distance + return suggestion + + +def _levenshtein_distance(a, b, max_cost): + # A Python implementation of Python/suggestions.c:levenshtein_distance. + + # Both strings are the same + if a == b: + return 0 + + # Trim away common affixes + pre = 0 + while a[pre:] and b[pre:] and a[pre] == b[pre]: + pre += 1 + a = a[pre:] + b = b[pre:] + post = 0 + while a[:post or None] and b[:post or None] and a[post-1] == b[post-1]: + post -= 1 + a = a[:post or None] + b = b[:post or None] + if not a or not b: + return _MOVE_COST * (len(a) + len(b)) + if len(a) > _MAX_STRING_SIZE or len(b) > _MAX_STRING_SIZE: + return max_cost + 1 + + # Prefer shorter buffer + if len(b) < len(a): + a, b = b, a + + # Quick fail when a match is impossible + if (len(b) - len(a)) * _MOVE_COST > max_cost: + return max_cost + 1 + + # Instead of producing the whole traditional len(a)-by-len(b) + # matrix, we can update just one row in place. + # Initialize the buffer row + row = list(range(_MOVE_COST, _MOVE_COST * (len(a) + 1), _MOVE_COST)) + + result = 0 + for bindex in range(len(b)): + bchar = b[bindex] + distance = result = bindex * _MOVE_COST + minimum = sys.maxsize + for index in range(len(a)): + # 1) Previous distance in this row is cost(b[:b_index], a[:index]) + substitute = distance + _substitution_cost(bchar, a[index]) + # 2) cost(b[:b_index], a[:index+1]) from previous row + distance = row[index] + # 3) existing result is cost(b[:b_index+1], a[index]) + + insert_delete = min(result, distance) + _MOVE_COST + result = min(insert_delete, substitute) + + # cost(b[:b_index+1], a[:index+1]) + row[index] = result + if result < minimum: + minimum = result + if minimum > max_cost: + # Everything in this row is too big, so bail early. + return max_cost + 1 + return result diff --git a/Lib/tty.py b/Lib/tty.py index a72eb675..7d916029 100644 --- a/Lib/tty.py +++ b/Lib/tty.py @@ -4,9 +4,9 @@ from termios import * -__all__ = ["setraw", "setcbreak"] +__all__ = ["cfmakeraw", "cfmakecbreak", "setraw", "setcbreak"] -# Indexes for termios list. +# Indices for termios list. IFLAG = 0 OFLAG = 1 CFLAG = 2 @@ -15,22 +15,60 @@ ISPEED = 4 OSPEED = 5 CC = 6 -def setraw(fd, when=TCSAFLUSH): - """Put terminal into a raw mode.""" - mode = tcgetattr(fd) - mode[IFLAG] = mode[IFLAG] & ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON) - mode[OFLAG] = mode[OFLAG] & ~(OPOST) - mode[CFLAG] = mode[CFLAG] & ~(CSIZE | PARENB) - mode[CFLAG] = mode[CFLAG] | CS8 - mode[LFLAG] = mode[LFLAG] & ~(ECHO | ICANON | IEXTEN | ISIG) +def cfmakeraw(mode): + """Make termios mode raw.""" + # Clear all POSIX.1-2017 input mode flags. + # See chapter 11 "General Terminal Interface" + # of POSIX.1-2017 Base Definitions. + mode[IFLAG] &= ~(IGNBRK | BRKINT | IGNPAR | PARMRK | INPCK | ISTRIP | + INLCR | IGNCR | ICRNL | IXON | IXANY | IXOFF) + + # Do not post-process output. + mode[OFLAG] &= ~OPOST + + # Disable parity generation and detection; clear character size mask; + # let character size be 8 bits. + mode[CFLAG] &= ~(PARENB | CSIZE) + mode[CFLAG] |= CS8 + + # Clear all POSIX.1-2017 local mode flags. + mode[LFLAG] &= ~(ECHO | ECHOE | ECHOK | ECHONL | ICANON | + IEXTEN | ISIG | NOFLSH | TOSTOP) + + # POSIX.1-2017, 11.1.7 Non-Canonical Mode Input Processing, + # Case B: MIN>0, TIME=0 + # A pending read shall block until MIN (here 1) bytes are received, + # or a signal is received. mode[CC][VMIN] = 1 mode[CC][VTIME] = 0 - tcsetattr(fd, when, mode) -def setcbreak(fd, when=TCSAFLUSH): - """Put terminal into a cbreak mode.""" - mode = tcgetattr(fd) - mode[LFLAG] = mode[LFLAG] & ~(ECHO | ICANON) +def cfmakecbreak(mode): + """Make termios mode cbreak.""" + # Do not map CR to NL on input. + mode[IFLAG] &= ~(ICRNL) + + # Do not echo characters; disable canonical input. + mode[LFLAG] &= ~(ECHO | ICANON) + + # POSIX.1-2017, 11.1.7 Non-Canonical Mode Input Processing, + # Case B: MIN>0, TIME=0 + # A pending read shall block until MIN (here 1) bytes are received, + # or a signal is received. mode[CC][VMIN] = 1 mode[CC][VTIME] = 0 - tcsetattr(fd, when, mode) + +def setraw(fd, when=TCSAFLUSH): + """Put terminal into raw mode.""" + mode = tcgetattr(fd) + new = list(mode) + cfmakeraw(new) + tcsetattr(fd, when, new) + return mode + +def setcbreak(fd, when=TCSAFLUSH): + """Put terminal into cbreak mode.""" + mode = tcgetattr(fd) + new = list(mode) + cfmakecbreak(new) + tcsetattr(fd, when, new) + return mode diff --git a/Lib/turtle.py b/Lib/turtle.py index 6abf9f7f..811c5dfa 100644 --- a/Lib/turtle.py +++ b/Lib/turtle.py @@ -21,7 +21,6 @@ # misrepresented as being the original software. # 3. This notice may not be removed or altered from any source distribution. - """ Turtle graphics is a popular way for introducing programming to kids. It was part of the original Logo programming language developed @@ -97,13 +96,8 @@ Roughly it has the following features added: Behind the scenes there are some features included with possible extensions in mind. These will be commented and documented elsewhere. - """ -_ver = "turtle 1.1b- - for Python 3.1 - 4. 5. 2009" - -# print(_ver) - import tkinter as TK import types import math @@ -135,13 +129,13 @@ _tg_turtle_functions = ['back', 'backward', 'begin_fill', 'begin_poly', 'bk', 'pu', 'radians', 'right', 'reset', 'resizemode', 'rt', 'seth', 'setheading', 'setpos', 'setposition', 'settiltangle', 'setundobuffer', 'setx', 'sety', 'shape', 'shapesize', 'shapetransform', 'shearfactor', 'showturtle', - 'speed', 'st', 'stamp', 'tilt', 'tiltangle', 'towards', + 'speed', 'st', 'stamp', 'teleport', 'tilt', 'tiltangle', 'towards', 'turtlesize', 'undo', 'undobufferentries', 'up', 'width', 'write', 'xcor', 'ycor'] _tg_utilities = ['write_docstringdict', 'done'] __all__ = (_tg_classes + _tg_screen_functions + _tg_turtle_functions + - _tg_utilities + ['Terminator']) # + _math_functions) + _tg_utilities + ['Terminator']) _alias_list = ['addshape', 'backward', 'bk', 'fd', 'ht', 'lt', 'pd', 'pos', 'pu', 'rt', 'seth', 'setpos', 'setposition', 'st', @@ -598,9 +592,6 @@ class TurtleScreenBase(object): x0, y0, x1, y1 = self.cv.bbox(item) return item, x1-1 -## def _dot(self, pos, size, color): -## """may be implemented for some other graphics toolkit""" - def _onclick(self, item, fun, num=1, add=None): """Bind fun to mouse-click event on turtle. fun must be a function with two arguments, the coordinates @@ -954,7 +945,7 @@ class Tbuffer(object): class TurtleScreen(TurtleScreenBase): - """Provides screen oriented methods like setbg etc. + """Provides screen oriented methods like bgcolor etc. Only relies upon the methods of TurtleScreenBase and NOT upon components of the underlying graphics toolkit - @@ -1614,6 +1605,13 @@ class TNavigator(object): """move turtle to position end.""" self._position = end + def teleport(self, x=None, y=None, *, fill_gap: bool = False) -> None: + """To be overwritten by child class RawTurtle. + Includes no TPen references.""" + new_x = x if x is not None else self._position[0] + new_y = y if y is not None else self._position[1] + self._position = Vec2D(new_x, new_y) + def forward(self, distance): """Move the turtle forward by the specified distance. @@ -2293,6 +2291,15 @@ class TPen(object): else: return self._color(self._fillcolor) + def teleport(self, x=None, y=None, *, fill_gap: bool = False) -> None: + """To be overwritten by child class RawTurtle. + Includes no TNavigator references. + """ + pendown = self.isdown() + if pendown: + self.pen(pendown=False) + self.pen(pendown=pendown) + def showturtle(self): """Makes the turtle visible. @@ -2711,6 +2718,54 @@ class RawTurtle(TPen, TNavigator): raise TurtleGraphicsError("bad color sequence: %s" % str(args)) return "#%02x%02x%02x" % (r, g, b) + def teleport(self, x=None, y=None, *, fill_gap: bool = False) -> None: + """Instantly move turtle to an absolute position. + + Arguments: + x -- a number or None + y -- a number None + fill_gap -- a boolean This argument must be specified by name. + + call: teleport(x, y) # two coordinates + --or: teleport(x) # teleport to x position, keeping y as is + --or: teleport(y=y) # teleport to y position, keeping x as is + --or: teleport(x, y, fill_gap=True) + # teleport but fill the gap in between + + Move turtle to an absolute position. Unlike goto(x, y), a line will not + be drawn. The turtle's orientation does not change. If currently + filling, the polygon(s) teleported from will be filled after leaving, + and filling will begin again after teleporting. This can be disabled + with fill_gap=True, which makes the imaginary line traveled during + teleporting act as a fill barrier like in goto(x, y). + + Example (for a Turtle instance named turtle): + >>> tp = turtle.pos() + >>> tp + (0.00,0.00) + >>> turtle.teleport(60) + >>> turtle.pos() + (60.00,0.00) + >>> turtle.teleport(y=10) + >>> turtle.pos() + (60.00,10.00) + >>> turtle.teleport(20, 30) + >>> turtle.pos() + (20.00,30.00) + """ + pendown = self.isdown() + was_filling = self.filling() + if pendown: + self.pen(pendown=False) + if was_filling and not fill_gap: + self.end_fill() + new_x = x if x is not None else self._position[0] + new_y = y if y is not None else self._position[1] + self._position = Vec2D(new_x, new_y) + self.pen(pendown=pendown) + if was_filling and not fill_gap: + self.begin_fill() + def clone(self): """Create and return a clone of the turtle. @@ -3391,27 +3446,22 @@ class RawTurtle(TPen, TNavigator): if size is None: size = self._pensize + max(self._pensize, 4) color = self._colorstr(color) - if hasattr(self.screen, "_dot"): - item = self.screen._dot(self._position, size, color) - self.items.append(item) - if self.undobuffer: - self.undobuffer.push(("dot", item)) - else: - pen = self.pen() - if self.undobuffer: - self.undobuffer.push(["seq"]) - self.undobuffer.cumulate = True - try: - if self.resizemode() == 'auto': - self.ht() - self.pendown() - self.pensize(size) - self.pencolor(color) - self.forward(0) - finally: - self.pen(pen) - if self.undobuffer: - self.undobuffer.cumulate = False + # If screen were to gain a dot function, see GH #104218. + pen = self.pen() + if self.undobuffer: + self.undobuffer.push(["seq"]) + self.undobuffer.cumulate = True + try: + if self.resizemode() == 'auto': + self.ht() + self.pendown() + self.pensize(size) + self.pencolor(color) + self.forward(0) + finally: + self.pen(pen) + if self.undobuffer: + self.undobuffer.cumulate = False def _write(self, txt, align, font): """Performs the writing for write() @@ -3687,11 +3737,6 @@ class _Screen(TurtleScreen): _title = _CFG["title"] def __init__(self): - # XXX there is no need for this code to be conditional, - # as there will be only a single _Screen instance, anyway - # XXX actually, the turtle demo is injecting root window, - # so perhaps the conditional creation of a root should be - # preserved (perhaps by passing it as an optional parameter) if _Screen._root is None: _Screen._root = self._root = _Root() self._root.title(_Screen._title) @@ -3906,28 +3951,33 @@ def getmethparlist(ob): function definition and the second is suitable for use in function call. The "self" parameter is not included. """ - defText = callText = "" + orig_sig = inspect.signature(ob) # bit of a hack for methods - turn it into a function # but we drop the "self" param. # Try and build one for Python defined functions - args, varargs, varkw = inspect.getargs(ob.__code__) - items2 = args[1:] - realArgs = args[1:] - defaults = ob.__defaults__ or [] - defaults = ["=%r" % (value,) for value in defaults] - defaults = [""] * (len(realArgs)-len(defaults)) + defaults - items1 = [arg + dflt for arg, dflt in zip(realArgs, defaults)] - if varargs is not None: - items1.append("*" + varargs) - items2.append("*" + varargs) - if varkw is not None: - items1.append("**" + varkw) - items2.append("**" + varkw) - defText = ", ".join(items1) - defText = "(%s)" % defText - callText = ", ".join(items2) - callText = "(%s)" % callText - return defText, callText + func_sig = orig_sig.replace( + parameters=list(orig_sig.parameters.values())[1:], + ) + + call_args = [] + for param in func_sig.parameters.values(): + match param.kind: + case ( + inspect.Parameter.POSITIONAL_ONLY + | inspect.Parameter.POSITIONAL_OR_KEYWORD + ): + call_args.append(param.name) + case inspect.Parameter.VAR_POSITIONAL: + call_args.append(f'*{param.name}') + case inspect.Parameter.KEYWORD_ONLY: + call_args.append(f'{param.name}={param.name}') + case inspect.Parameter.VAR_KEYWORD: + call_args.append(f'**{param.name}') + case _: + raise RuntimeError('Unsupported parameter kind', param.kind) + call_text = f'({', '.join(call_args)})' + + return str(func_sig), call_text def _turtle_docrevise(docstr): """To reduce docstrings from RawTurtle class for functions diff --git a/Lib/turtledemo/__main__.py b/Lib/turtledemo/__main__.py index caea022d..f6c9d6aa 100755 --- a/Lib/turtledemo/__main__.py +++ b/Lib/turtledemo/__main__.py @@ -203,10 +203,10 @@ class DemoWindow(object): def onResize(self, event): - cwidth = self._canvas.winfo_width() - cheight = self._canvas.winfo_height() - self._canvas.xview_moveto(0.5*(self.canvwidth-cwidth)/self.canvwidth) - self._canvas.yview_moveto(0.5*(self.canvheight-cheight)/self.canvheight) + cwidth = self.canvas.winfo_width() + cheight = self.canvas.winfo_height() + self.canvas.xview_moveto(0.5*(self.canvwidth-cwidth)/self.canvwidth) + self.canvas.yview_moveto(0.5*(self.canvheight-cheight)/self.canvheight) def makeTextFrame(self, root): self.text_frame = text_frame = Frame(root) @@ -237,19 +237,23 @@ class DemoWindow(object): return text_frame def makeGraphFrame(self, root): + # t._Screen is a singleton class instantiated or retrieved + # by calling Screen. Since tdemo canvas needs a different + # configuration, we manually set class attributes before + # calling Screen and manually call superclass init after. turtle._Screen._root = root + self.canvwidth = 1000 self.canvheight = 800 - turtle._Screen._canvas = self._canvas = canvas = turtle.ScrolledCanvas( + turtle._Screen._canvas = self.canvas = canvas = turtle.ScrolledCanvas( root, 800, 600, self.canvwidth, self.canvheight) canvas.adjustScrolls() canvas._rootwindow.bind('<Configure>', self.onResize) canvas._canvas['borderwidth'] = 0 - self.screen = _s_ = turtle.Screen() - turtle.TurtleScreen.__init__(_s_, _s_._canvas) - self.scanvas = _s_._canvas - turtle.RawTurtle.screens = [_s_] + self.screen = screen = turtle.Screen() + turtle.TurtleScreen.__init__(screen, canvas) + turtle.RawTurtle.screens = [screen] return canvas def set_txtsize(self, size): @@ -373,7 +377,7 @@ class DemoWindow(object): def clearCanvas(self): self.refreshCanvas() self.screen._delete("all") - self.scanvas.config(cursor="") + self.canvas.config(cursor="") self.configGUI(NORMAL, DISABLED, DISABLED) def stopIt(self): diff --git a/Lib/types.py b/Lib/types.py index 2e73fbc4..b4aa19ce 100644 --- a/Lib/types.py +++ b/Lib/types.py @@ -56,11 +56,10 @@ except TypeError as exc: TracebackType = type(exc.__traceback__) FrameType = type(exc.__traceback__.tb_frame) -# For Jython, the following two types are identical GetSetDescriptorType = type(FunctionType.__code__) MemberDescriptorType = type(FunctionType.__globals__) -del sys, _f, _g, _C, _c, _ag # Not for export +del sys, _f, _g, _C, _c, _ag, _cell_factory # Not for export # Provide a PEP 3115 compliant mechanism for class creation @@ -144,6 +143,35 @@ def _calculate_meta(meta, bases): "of the metaclasses of all its bases") return winner + +def get_original_bases(cls, /): + """Return the class's "original" bases prior to modification by `__mro_entries__`. + + Examples:: + + from typing import TypeVar, Generic, NamedTuple, TypedDict + + T = TypeVar("T") + class Foo(Generic[T]): ... + class Bar(Foo[int], float): ... + class Baz(list[str]): ... + Eggs = NamedTuple("Eggs", [("a", int), ("b", str)]) + Spam = TypedDict("Spam", {"a": int, "b": str}) + + assert get_original_bases(Bar) == (Foo[int], float) + assert get_original_bases(Baz) == (list[str],) + assert get_original_bases(Eggs) == (NamedTuple,) + assert get_original_bases(Spam) == (TypedDict,) + assert get_original_bases(int) == (object,) + """ + try: + return cls.__dict__.get("__orig_bases__", cls.__bases__) + except AttributeError: + raise TypeError( + f"Expected an instance of type, not {type(cls).__name__!r}" + ) from None + + class DynamicClassAttribute: """Route attribute access on a class to __getattr__. diff --git a/Lib/typing.py b/Lib/typing.py index 9f5db1a1..9e2adbe2 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -1,28 +1,29 @@ """ -The typing module: Support for gradual typing as defined by PEP 484. - -At large scale, the structure of the module is following: -* Imports and exports, all public names should be explicitly added to __all__. -* Internal helper functions: these should never be used in code outside this module. -* _SpecialForm and its instances (special forms): - Any, NoReturn, Never, ClassVar, Union, Optional, Concatenate, Unpack -* Classes whose instances can be type arguments in addition to types: - ForwardRef, TypeVar and ParamSpec -* The core of internal generics API: _GenericAlias and _VariadicGenericAlias, the latter is - currently only used by Tuple and Callable. All subscripted types like X[int], Union[int, str], - etc., are instances of either of these classes. -* The public counterpart of the generics API consists of two classes: Generic and Protocol. -* Public helper functions: get_type_hints, overload, cast, no_type_check, - no_type_check_decorator. -* Generic aliases for collections.abc ABCs and few additional protocols. +The typing module: Support for gradual typing as defined by PEP 484 and subsequent PEPs. + +Among other things, the module includes the following: +* Generic, Protocol, and internal machinery to support generic aliases. + All subscripted types like X[int], Union[int, str] are generic aliases. +* Various "special forms" that have unique meanings in type annotations: + NoReturn, Never, ClassVar, Self, Concatenate, Unpack, and others. +* Classes whose instances can be type arguments to generic classes and functions: + TypeVar, ParamSpec, TypeVarTuple. +* Public helper functions: get_type_hints, overload, cast, final, and others. +* Several protocols to support duck-typing: + SupportsFloat, SupportsIndex, SupportsAbs, and others. * Special types: NewType, NamedTuple, TypedDict. -* Wrapper submodules for re and io related types. +* Deprecated wrapper submodules for re and io related types. +* Deprecated aliases for builtin types and collections.abc ABCs. + +Any name not present in __all__ is an implementation detail +that may be changed without notice. Use at your own risk! """ from abc import abstractmethod, ABCMeta import collections from collections import defaultdict import collections.abc +import copyreg import contextlib import functools import operator @@ -32,12 +33,16 @@ import types import warnings from types import WrapperDescriptorType, MethodWrapperType, MethodDescriptorType, GenericAlias - -try: - from _typing import _idfunc -except ImportError: - def _idfunc(_, x): - return x +from _typing import ( + _idfunc, + TypeVar, + ParamSpec, + TypeVarTuple, + ParamSpecArgs, + ParamSpecKwargs, + TypeAliasType, + Generic, +) # Please keep __all__ alphabetized within each category. __all__ = [ @@ -138,6 +143,7 @@ __all__ = [ 'NoReturn', 'NotRequired', 'overload', + 'override', 'ParamSpecArgs', 'ParamSpecKwargs', 'Required', @@ -148,6 +154,7 @@ __all__ = [ 'TYPE_CHECKING', 'TypeAlias', 'TypeGuard', + 'TypeAliasType', 'Unpack', ] @@ -171,7 +178,7 @@ def _type_check(arg, msg, is_argument=True, module=None, *, allow_special_forms= As a special case, accept None and return type(None) instead. Also wrap strings into ForwardRef instances. Consider several corner cases, for example plain special forms like Union are not valid, while Union[int, str] is OK, etc. - The msg argument is a human-readable error message, e.g:: + The msg argument is a human-readable error message, e.g.:: "Union[arg, ...]: arg should be a type." @@ -207,10 +214,12 @@ def _should_unflatten_callable_args(typ, args): """Internal helper for munging collections.abc.Callable's __args__. The canonical representation for a Callable's __args__ flattens the - argument types, see https://bugs.python.org/issue42195. For example: + argument types, see https://github.com/python/cpython/issues/86361. + + For example:: - collections.abc.Callable[[int, int], str].__args__ == (int, int, str) - collections.abc.Callable[ParamSpec, str].__args__ == (ParamSpec, str) + assert collections.abc.Callable[[int, int], str].__args__ == (int, int, str) + assert collections.abc.Callable[ParamSpec, str].__args__ == (ParamSpec, str) As a result, if we need to reconstruct the Callable from its __args__, we need to unflatten it. @@ -229,31 +238,44 @@ def _type_repr(obj): typically enough to uniquely identify a type. For everything else, we fall back on repr(obj). """ - if isinstance(obj, types.GenericAlias): - return repr(obj) + # When changing this function, don't forget about + # `_collections_abc._type_repr`, which does the same thing + # and must be consistent with this one. if isinstance(obj, type): if obj.__module__ == 'builtins': return obj.__qualname__ return f'{obj.__module__}.{obj.__qualname__}' if obj is ...: - return('...') + return '...' if isinstance(obj, types.FunctionType): return obj.__name__ + if isinstance(obj, tuple): + # Special case for `repr` of types with `ParamSpec`: + return '[' + ', '.join(_type_repr(t) for t in obj) + ']' return repr(obj) def _collect_parameters(args): """Collect all type variables and parameter specifications in args - in order of first appearance (lexicographic order). For example:: + in order of first appearance (lexicographic order). + + For example:: - _collect_parameters((T, Callable[P, T])) == (T, P) + assert _collect_parameters((T, Callable[P, T])) == (T, P) """ parameters = [] for t in args: - # We don't want __parameters__ descriptor of a bare Python class. if isinstance(t, type): - continue - if hasattr(t, '__typing_subst__'): + # We don't want __parameters__ descriptor of a bare Python class. + pass + elif isinstance(t, tuple): + # `t` might be a tuple, when `ParamSpec` is substituted with + # `[T, int]`, or `[int, *Ts]`, etc. + for x in t: + for collected in _collect_parameters([x]): + if collected not in parameters: + parameters.append(collected) + elif hasattr(t, '__typing_subst__'): if t not in parameters: parameters.append(t) else: @@ -265,6 +287,7 @@ def _collect_parameters(args): def _check_generic(cls, parameters, elen): """Check correct count for parameters of a generic cls (internal helper). + This gives a nice error message in case of count mismatch. """ if not elen: @@ -299,8 +322,9 @@ def _deduplicate(params): def _remove_dups_flatten(parameters): - """An internal helper for Union creation and substitution: flatten Unions - among parameters, then remove duplicates. + """Internal helper for Union creation and substitution. + + Flatten Unions among parameters, then remove duplicates. """ # Flatten out Union[Union[...], ...]. params = [] @@ -314,7 +338,7 @@ def _remove_dups_flatten(parameters): def _flatten_literal_params(parameters): - """An internal helper for Literal creation: flatten Literals among parameters""" + """Internal helper for Literal creation: flatten Literals among parameters.""" params = [] for p in parameters: if isinstance(p, _LiteralGenericAlias): @@ -325,20 +349,29 @@ def _flatten_literal_params(parameters): _cleanups = [] +_caches = {} def _tp_cache(func=None, /, *, typed=False): - """Internal wrapper caching __getitem__ of generic types with a fallback to - original function for non-hashable arguments. + """Internal wrapper caching __getitem__ of generic types. + + For non-hashable arguments, the original function is used as a fallback. """ def decorator(func): - cached = functools.lru_cache(typed=typed)(func) - _cleanups.append(cached.cache_clear) + # The callback 'inner' references the newly created lru_cache + # indirectly by performing a lookup in the global '_caches' dictionary. + # This breaks a reference that can be problematic when combined with + # C API extensions that leak references to types. See GH-98253. + + cache = functools.lru_cache(typed=typed)(func) + _caches[func] = cache + _cleanups.append(cache.cache_clear) + del cache @functools.wraps(func) def inner(*args, **kwds): try: - return cached(*args, **kwds) + return _caches[func](*args, **kwds) except TypeError: pass # All real errors (not unhashable args) are raised below. return func(*args, **kwds) @@ -351,6 +384,7 @@ def _tp_cache(func=None, /, *, typed=False): def _eval_type(t, globalns, localns, recursive_guard=frozenset()): """Evaluate all forward references in the given type t. + For use of globalns and localns see the docstring for get_type_hints(). recursive_guard is used to prevent infinite recursion with a recursive ForwardRef. @@ -383,7 +417,7 @@ def _eval_type(t, globalns, localns, recursive_guard=frozenset()): class _Final: - """Mixin to prohibit subclassing""" + """Mixin to prohibit subclassing.""" __slots__ = ('__weakref__',) @@ -391,22 +425,14 @@ class _Final: if '_root' not in kwds: raise TypeError("Cannot subclass special typing classes") -class _Immutable: - """Mixin to indicate that object should not be copied.""" - __slots__ = () - - def __copy__(self): - return self - - def __deepcopy__(self, memo): - return self - class _NotIterable: """Mixin to prevent iteration, without being compatible with Iterable. - That is, we could do: + That is, we could do:: + def __iter__(self): raise TypeError() + But this would make users of this mixin duck type-compatible with collections.abc.Iterable - isinstance(foo, Iterable) would be True. @@ -493,6 +519,7 @@ class Any(metaclass=_AnyMeta): static type checkers. At runtime, Any should not be used with instance checks. """ + def __new__(cls, *args, **kwargs): if cls is Any: raise TypeError("Any cannot be instantiated") @@ -502,18 +529,18 @@ class Any(metaclass=_AnyMeta): @_SpecialForm def NoReturn(self, parameters): """Special type indicating functions that never return. + Example:: - from typing import NoReturn + from typing import NoReturn - def stop() -> NoReturn: - raise Exception('no way') + def stop() -> NoReturn: + raise Exception('no way') NoReturn can also be used as a bottom type, a type that has no values. Starting in Python 3.11, the Never type should be used for this concept instead. Type checkers should treat the two equivalently. - """ raise TypeError(f"{self} is not subscriptable") @@ -540,8 +567,7 @@ def Never(self, parameters): case str(): print("It's a str") case _: - never_call_me(arg) # ok, arg is of type Never - + never_call_me(arg) # OK, arg is of type Never """ raise TypeError(f"{self} is not subscriptable") @@ -552,12 +578,12 @@ def Self(self, parameters): Example:: - from typing import Self + from typing import Self - class Foo: - def return_self(self) -> Self: - ... - return self + class Foo: + def return_self(self) -> Self: + ... + return self This is especially useful for: - classmethods that are used as alternative constructors @@ -574,13 +600,13 @@ def LiteralString(self, parameters): from typing import LiteralString - def run_query(sql: LiteralString) -> ... + def run_query(sql: LiteralString) -> None: ... def caller(arbitrary_string: str, literal_string: LiteralString) -> None: - run_query("SELECT * FROM students") # ok - run_query(literal_string) # ok - run_query("SELECT * FROM " + literal_string) # ok + run_query("SELECT * FROM students") # OK + run_query(literal_string) # OK + run_query("SELECT * FROM " + literal_string) # OK run_query(arbitrary_string) # type checker error run_query( # type checker error f"SELECT * FROM students WHERE name = {arbitrary_string}" @@ -589,7 +615,6 @@ def LiteralString(self, parameters): Only string literals and other LiteralStrings are compatible with LiteralString. This provides a tool to help prevent security issues such as SQL injection. - """ raise TypeError(f"{self} is not subscriptable") @@ -600,11 +625,13 @@ def ClassVar(self, parameters): An annotation wrapped in ClassVar indicates that a given attribute is intended to be used as a class variable and - should not be set on instances of that class. Usage:: + should not be set on instances of that class. - class Starship: - stats: ClassVar[Dict[str, int]] = {} # class variable - damage: int = 10 # instance variable + Usage:: + + class Starship: + stats: ClassVar[dict[str, int]] = {} # class variable + damage: int = 10 # instance variable ClassVar accepts only types and cannot be further subscribed. @@ -619,16 +646,17 @@ def Final(self, parameters): """Special typing construct to indicate final names to type checkers. A final name cannot be re-assigned or overridden in a subclass. - For example: - MAX_SIZE: Final = 9000 - MAX_SIZE += 1 # Error reported by type checker + For example:: - class Connection: - TIMEOUT: Final[int] = 10 + MAX_SIZE: Final = 9000 + MAX_SIZE += 1 # Error reported by type checker - class FastConnector(Connection): - TIMEOUT = 1 # Error reported by type checker + class Connection: + TIMEOUT: Final[int] = 10 + + class FastConnector(Connection): + TIMEOUT = 1 # Error reported by type checker There is no runtime checking of these properties. """ @@ -639,25 +667,29 @@ def Final(self, parameters): def Union(self, parameters): """Union type; Union[X, Y] means either X or Y. - To define a union, use e.g. Union[int, str]. Details: + On Python 3.10 and higher, the | operator + can also be used to denote unions; + X | Y means the same thing to the type checker as Union[X, Y]. + + To define a union, use e.g. Union[int, str]. Details: - The arguments must be types and there must be at least one. - None as an argument is a special case and is replaced by type(None). - Unions of unions are flattened, e.g.:: - Union[Union[int, str], float] == Union[int, str, float] + assert Union[Union[int, str], float] == Union[int, str, float] - Unions of a single argument vanish, e.g.:: - Union[int] == int # The constructor actually returns int + assert Union[int] == int # The constructor actually returns int - Redundant arguments are skipped, e.g.:: - Union[int, str, int] == Union[int, str] + assert Union[int, str, int] == Union[int, str] - When comparing unions, the argument order is ignored, e.g.:: - Union[int, str] == Union[str, int] + assert Union[int, str] == Union[str, int] - You cannot subclass or instantiate a union. - You can use Optional[X] as a shorthand for Union[X, None]. @@ -675,12 +707,18 @@ def Union(self, parameters): return _UnionGenericAlias(self, parameters, name="Optional") return _UnionGenericAlias(self, parameters) -@_SpecialForm -def Optional(self, parameters): - """Optional type. +def _make_union(left, right): + """Used from the C implementation of TypeVar. - Optional[X] is equivalent to Union[X, None]. + TypeVar.__or__ calls this instead of returning types.UnionType + because we want to allow unions between TypeVars and strings + (forward references). """ + return Union[left, right] + +@_SpecialForm +def Optional(self, parameters): + """Optional[X] is equivalent to Union[X, None].""" arg = _type_check(parameters, f"{self} requires a single type.") return Union[arg, type(None)] @@ -691,17 +729,17 @@ def Literal(self, *parameters): This form can be used to indicate to type checkers that the corresponding variable or function parameter has a value equivalent to the provided - literal (or one of several literals): + literal (or one of several literals):: - def validate_simple(data: Any) -> Literal[True]: # always returns True - ... + def validate_simple(data: Any) -> Literal[True]: # always returns True + ... - MODE = Literal['r', 'rb', 'w', 'wb'] - def open_helper(file: str, mode: MODE) -> str: - ... + MODE = Literal['r', 'rb', 'w', 'wb'] + def open_helper(file: str, mode: MODE) -> str: + ... - open_helper('/some/path', 'r') # Passes type check - open_helper('/other/path', 'typo') # Error in type checker + open_helper('/some/path', 'r') # Passes type check + open_helper('/other/path', 'typo') # Error in type checker Literal[...] cannot be subclassed. At runtime, an arbitrary value is allowed as type argument to Literal[...], but type checkers may @@ -721,7 +759,9 @@ def Literal(self, *parameters): @_SpecialForm def TypeAlias(self, parameters): - """Special marker indicating that an assignment should + """Special form for marking type aliases. + + Use TypeAlias to indicate that an assignment should be recognized as a proper type alias definition by type checkers. @@ -736,13 +776,15 @@ def TypeAlias(self, parameters): @_SpecialForm def Concatenate(self, parameters): - """Used in conjunction with ``ParamSpec`` and ``Callable`` to represent a - higher order function which adds, removes or transforms parameters of a - callable. + """Special form for annotating higher-order functions. + + ``Concatenate`` can be used in conjunction with ``ParamSpec`` and + ``Callable`` to represent a higher-order function which adds, removes or + transforms the parameters of a callable. For example:: - Callable[Concatenate[int, P], int] + Callable[Concatenate[int, P], int] See PEP 612 for detailed information. """ @@ -755,13 +797,14 @@ def Concatenate(self, parameters): "ParamSpec variable or ellipsis.") msg = "Concatenate[arg, ...]: each arg must be a type." parameters = (*(_type_check(p, msg) for p in parameters[:-1]), parameters[-1]) - return _ConcatenateGenericAlias(self, parameters, - _paramspec_tvars=True) + return _ConcatenateGenericAlias(self, parameters) @_SpecialForm def TypeGuard(self, parameters): - """Special typing form used to annotate the return type of a user-defined + """Special typing construct for marking user-defined type guard functions. + + ``TypeGuard`` can be used to annotate the return type of a user-defined type guard function. ``TypeGuard`` only accepts a single type argument. At runtime, functions marked this way should return a boolean. @@ -784,14 +827,14 @@ def TypeGuard(self, parameters): For example:: - def is_str(val: Union[str, float]): - # "isinstance" type guard - if isinstance(val, str): - # Type of ``val`` is narrowed to ``str`` - ... - else: - # Else, type of ``val`` is narrowed to ``float``. - ... + def is_str(val: Union[str, float]): + # "isinstance" type guard + if isinstance(val, str): + # Type of ``val`` is narrowed to ``str`` + ... + else: + # Else, type of ``val`` is narrowed to ``float``. + ... Strict type narrowing is not enforced -- ``TypeB`` need not be a narrower form of ``TypeA`` (it can even be a wider form) and this may lead to @@ -907,334 +950,176 @@ class _PickleUsingNameMixin: return self.__name__ -class _BoundVarianceMixin: - """Mixin giving __init__ bound and variance arguments. - - This is used by TypeVar and ParamSpec, which both employ the notions of - a type 'bound' (restricting type arguments to be a subtype of some - specified type) and type 'variance' (determining subtype relations between - generic types). - """ - def __init__(self, bound, covariant, contravariant): - """Used to setup TypeVars and ParamSpec's bound, covariant and - contravariant attributes. - """ - if covariant and contravariant: - raise ValueError("Bivariant types are not supported.") - self.__covariant__ = bool(covariant) - self.__contravariant__ = bool(contravariant) - if bound: - self.__bound__ = _type_check(bound, "Bound must be a type.") - else: - self.__bound__ = None - - def __or__(self, right): - return Union[self, right] - - def __ror__(self, left): - return Union[left, self] - - def __repr__(self): - if self.__covariant__: - prefix = '+' - elif self.__contravariant__: - prefix = '-' - else: - prefix = '~' - return prefix + self.__name__ - - -class TypeVar(_Final, _Immutable, _BoundVarianceMixin, _PickleUsingNameMixin, - _root=True): - """Type variable. - - Usage:: - - T = TypeVar('T') # Can be anything - A = TypeVar('A', str, bytes) # Must be str or bytes - - Type variables exist primarily for the benefit of static type - checkers. They serve as the parameters for generic types as well - as for generic function definitions. See class Generic for more - information on generic types. Generic functions work as follows: - - def repeat(x: T, n: int) -> List[T]: - '''Return a list containing n references to x.''' - return [x]*n - - def longest(x: A, y: A) -> A: - '''Return the longest of two strings.''' - return x if len(x) >= len(y) else y - - The latter example's signature is essentially the overloading - of (str, str) -> str and (bytes, bytes) -> bytes. Also note - that if the arguments are instances of some subclass of str, - the return type is still plain str. - - At runtime, isinstance(x, T) and issubclass(C, T) will raise TypeError. - - Type variables defined with covariant=True or contravariant=True - can be used to declare covariant or contravariant generic types. - See PEP 484 for more details. By default generic types are invariant - in all type variables. - - Type variables can be introspected. e.g.: - - T.__name__ == 'T' - T.__constraints__ == () - T.__covariant__ == False - T.__contravariant__ = False - A.__constraints__ == (str, bytes) +def _typevar_subst(self, arg): + msg = "Parameters to generic types must be types." + arg = _type_check(arg, msg, is_argument=True) + if ((isinstance(arg, _GenericAlias) and arg.__origin__ is Unpack) or + (isinstance(arg, GenericAlias) and getattr(arg, '__unpacked__', False))): + raise TypeError(f"{arg} is not valid as type argument") + return arg - Note that only type variables defined in global scope can be pickled. - """ - def __init__(self, name, *constraints, bound=None, - covariant=False, contravariant=False): - self.__name__ = name - super().__init__(bound, covariant, contravariant) - if constraints and bound is not None: - raise TypeError("Constraints cannot be combined with bound=...") - if constraints and len(constraints) == 1: - raise TypeError("A single constraint is not allowed") - msg = "TypeVar(name, constraint, ...): constraints must be types." - self.__constraints__ = tuple(_type_check(t, msg) for t in constraints) - def_mod = _caller() - if def_mod != 'typing': - self.__module__ = def_mod - - def __typing_subst__(self, arg): - msg = "Parameters to generic types must be types." - arg = _type_check(arg, msg, is_argument=True) - if ((isinstance(arg, _GenericAlias) and arg.__origin__ is Unpack) or - (isinstance(arg, GenericAlias) and getattr(arg, '__unpacked__', False))): - raise TypeError(f"{arg} is not valid as type argument") - return arg +def _typevartuple_prepare_subst(self, alias, args): + params = alias.__parameters__ + typevartuple_index = params.index(self) + for param in params[typevartuple_index + 1:]: + if isinstance(param, TypeVarTuple): + raise TypeError(f"More than one TypeVarTuple parameter in {alias}") + + alen = len(args) + plen = len(params) + left = typevartuple_index + right = plen - typevartuple_index - 1 + var_tuple_index = None + fillarg = None + for k, arg in enumerate(args): + if not isinstance(arg, type): + subargs = getattr(arg, '__typing_unpacked_tuple_args__', None) + if subargs and len(subargs) == 2 and subargs[-1] is ...: + if var_tuple_index is not None: + raise TypeError("More than one unpacked arbitrary-length tuple argument") + var_tuple_index = k + fillarg = subargs[0] + if var_tuple_index is not None: + left = min(left, var_tuple_index) + right = min(right, alen - var_tuple_index - 1) + elif left + right > alen: + raise TypeError(f"Too few arguments for {alias};" + f" actual {alen}, expected at least {plen-1}") + return ( + *args[:left], + *([fillarg]*(typevartuple_index - left)), + tuple(args[left: alen - right]), + *([fillarg]*(plen - right - left - typevartuple_index - 1)), + *args[alen - right:], + ) -class TypeVarTuple(_Final, _Immutable, _PickleUsingNameMixin, _root=True): - """Type variable tuple. - - Usage: - Ts = TypeVarTuple('Ts') # Can be given any name +def _paramspec_subst(self, arg): + if isinstance(arg, (list, tuple)): + arg = tuple(_type_check(a, "Expected a type.") for a in arg) + elif not _is_param_expr(arg): + raise TypeError(f"Expected a list of types, an ellipsis, " + f"ParamSpec, or Concatenate. Got {arg}") + return arg - Just as a TypeVar (type variable) is a placeholder for a single type, - a TypeVarTuple is a placeholder for an *arbitrary* number of types. For - example, if we define a generic class using a TypeVarTuple: - class C(Generic[*Ts]): ... +def _paramspec_prepare_subst(self, alias, args): + params = alias.__parameters__ + i = params.index(self) + if i >= len(args): + raise TypeError(f"Too few arguments for {alias}") + # Special case where Z[[int, str, bool]] == Z[int, str, bool] in PEP 612. + if len(params) == 1 and not _is_param_expr(args[0]): + assert i == 0 + args = (args,) + # Convert lists to tuples to help other libraries cache the results. + elif isinstance(args[i], list): + args = (*args[:i], tuple(args[i]), *args[i+1:]) + return args - Then we can parameterize that class with an arbitrary number of type - arguments: - C[int] # Fine - C[int, str] # Also fine - C[()] # Even this is fine +@_tp_cache +def _generic_class_getitem(cls, params): + """Parameterizes a generic class. - For more details, see PEP 646. + At least, parameterizing a generic class is the *main* thing this method + does. For example, for some generic class `Foo`, this is called when we + do `Foo[int]` - there, with `cls=Foo` and `params=int`. - Note that only TypeVarTuples defined in global scope can be pickled. + However, note that this method is also called when defining generic + classes in the first place with `class Foo(Generic[T]): ...`. """ + if not isinstance(params, tuple): + params = (params,) - def __init__(self, name): - self.__name__ = name - - # Used for pickling. - def_mod = _caller() - if def_mod != 'typing': - self.__module__ = def_mod + params = tuple(_type_convert(p) for p in params) + is_generic_or_protocol = cls in (Generic, Protocol) - def __iter__(self): - yield Unpack[self] - - def __repr__(self): - return self.__name__ - - def __typing_subst__(self, arg): - raise TypeError("Substitution of bare TypeVarTuple is not supported") + if is_generic_or_protocol: + # Generic and Protocol can only be subscripted with unique type variables. + if not params: + raise TypeError( + f"Parameter list to {cls.__qualname__}[...] cannot be empty" + ) + if not all(_is_typevar_like(p) for p in params): + raise TypeError( + f"Parameters to {cls.__name__}[...] must all be type variables " + f"or parameter specification variables.") + if len(set(params)) != len(params): + raise TypeError( + f"Parameters to {cls.__name__}[...] must all be unique") + else: + # Subscripting a regular Generic subclass. + for param in cls.__parameters__: + prepare = getattr(param, '__typing_prepare_subst__', None) + if prepare is not None: + params = prepare(cls, params) + _check_generic(cls, params, len(cls.__parameters__)) - def __typing_prepare_subst__(self, alias, args): - params = alias.__parameters__ - typevartuple_index = params.index(self) - for param in params[typevartuple_index + 1:]: + new_args = [] + for param, new_arg in zip(cls.__parameters__, params): if isinstance(param, TypeVarTuple): - raise TypeError(f"More than one TypeVarTuple parameter in {alias}") - - alen = len(args) - plen = len(params) - left = typevartuple_index - right = plen - typevartuple_index - 1 - var_tuple_index = None - fillarg = None - for k, arg in enumerate(args): - if not isinstance(arg, type): - subargs = getattr(arg, '__typing_unpacked_tuple_args__', None) - if subargs and len(subargs) == 2 and subargs[-1] is ...: - if var_tuple_index is not None: - raise TypeError("More than one unpacked arbitrary-length tuple argument") - var_tuple_index = k - fillarg = subargs[0] - if var_tuple_index is not None: - left = min(left, var_tuple_index) - right = min(right, alen - var_tuple_index - 1) - elif left + right > alen: - raise TypeError(f"Too few arguments for {alias};" - f" actual {alen}, expected at least {plen-1}") - - return ( - *args[:left], - *([fillarg]*(typevartuple_index - left)), - tuple(args[left: alen - right]), - *([fillarg]*(plen - right - left - typevartuple_index - 1)), - *args[alen - right:], - ) - - -class ParamSpecArgs(_Final, _Immutable, _root=True): - """The args for a ParamSpec object. - - Given a ParamSpec object P, P.args is an instance of ParamSpecArgs. - - ParamSpecArgs objects have a reference back to their ParamSpec: - - P.args.__origin__ is P - - This type is meant for runtime introspection and has no special meaning to - static type checkers. - """ - def __init__(self, origin): - self.__origin__ = origin - - def __repr__(self): - return f"{self.__origin__.__name__}.args" - - def __eq__(self, other): - if not isinstance(other, ParamSpecArgs): - return NotImplemented - return self.__origin__ == other.__origin__ - - -class ParamSpecKwargs(_Final, _Immutable, _root=True): - """The kwargs for a ParamSpec object. - - Given a ParamSpec object P, P.kwargs is an instance of ParamSpecKwargs. - - ParamSpecKwargs objects have a reference back to their ParamSpec: - - P.kwargs.__origin__ is P - - This type is meant for runtime introspection and has no special meaning to - static type checkers. - """ - def __init__(self, origin): - self.__origin__ = origin - - def __repr__(self): - return f"{self.__origin__.__name__}.kwargs" - - def __eq__(self, other): - if not isinstance(other, ParamSpecKwargs): - return NotImplemented - return self.__origin__ == other.__origin__ - - -class ParamSpec(_Final, _Immutable, _BoundVarianceMixin, _PickleUsingNameMixin, - _root=True): - """Parameter specification variable. - - Usage:: + new_args.extend(new_arg) + else: + new_args.append(new_arg) + params = tuple(new_args) - P = ParamSpec('P') - - Parameter specification variables exist primarily for the benefit of static - type checkers. They are used to forward the parameter types of one - callable to another callable, a pattern commonly found in higher order - functions and decorators. They are only valid when used in ``Concatenate``, - or as the first argument to ``Callable``, or as parameters for user-defined - Generics. See class Generic for more information on generic types. An - example for annotating a decorator:: - - T = TypeVar('T') - P = ParamSpec('P') - - def add_logging(f: Callable[P, T]) -> Callable[P, T]: - '''A type-safe decorator to add logging to a function.''' - def inner(*args: P.args, **kwargs: P.kwargs) -> T: - logging.info(f'{f.__name__} was called') - return f(*args, **kwargs) - return inner - - @add_logging - def add_two(x: float, y: float) -> float: - '''Add two numbers together.''' - return x + y - - Parameter specification variables defined with covariant=True or - contravariant=True can be used to declare covariant or contravariant - generic types. These keyword arguments are valid, but their actual semantics - are yet to be decided. See PEP 612 for details. - - Parameter specification variables can be introspected. e.g.: - - P.__name__ == 'P' - P.__bound__ == None - P.__covariant__ == False - P.__contravariant__ == False - - Note that only parameter specification variables defined in global scope can - be pickled. - """ + return _GenericAlias(cls, params) - @property - def args(self): - return ParamSpecArgs(self) - @property - def kwargs(self): - return ParamSpecKwargs(self) - - def __init__(self, name, *, bound=None, covariant=False, contravariant=False): - self.__name__ = name - super().__init__(bound, covariant, contravariant) - def_mod = _caller() - if def_mod != 'typing': - self.__module__ = def_mod - - def __typing_subst__(self, arg): - if isinstance(arg, (list, tuple)): - arg = tuple(_type_check(a, "Expected a type.") for a in arg) - elif not _is_param_expr(arg): - raise TypeError(f"Expected a list of types, an ellipsis, " - f"ParamSpec, or Concatenate. Got {arg}") - return arg +def _generic_init_subclass(cls, *args, **kwargs): + super(Generic, cls).__init_subclass__(*args, **kwargs) + tvars = [] + if '__orig_bases__' in cls.__dict__: + error = Generic in cls.__orig_bases__ + else: + error = (Generic in cls.__bases__ and + cls.__name__ != 'Protocol' and + type(cls) != _TypedDictMeta) + if error: + raise TypeError("Cannot inherit from plain Generic") + if '__orig_bases__' in cls.__dict__: + tvars = _collect_parameters(cls.__orig_bases__) + # Look for Generic[T1, ..., Tn]. + # If found, tvars must be a subset of it. + # If not found, tvars is it. + # Also check for and reject plain Generic, + # and reject multiple Generic[...]. + gvars = None + for base in cls.__orig_bases__: + if (isinstance(base, _GenericAlias) and + base.__origin__ is Generic): + if gvars is not None: + raise TypeError( + "Cannot inherit from Generic[...] multiple times.") + gvars = base.__parameters__ + if gvars is not None: + tvarset = set(tvars) + gvarset = set(gvars) + if not tvarset <= gvarset: + s_vars = ', '.join(str(t) for t in tvars if t not in gvarset) + s_args = ', '.join(str(g) for g in gvars) + raise TypeError(f"Some type variables ({s_vars}) are" + f" not listed in Generic[{s_args}]") + tvars = gvars + cls.__parameters__ = tuple(tvars) - def __typing_prepare_subst__(self, alias, args): - params = alias.__parameters__ - i = params.index(self) - if i >= len(args): - raise TypeError(f"Too few arguments for {alias}") - # Special case where Z[[int, str, bool]] == Z[int, str, bool] in PEP 612. - if len(params) == 1 and not _is_param_expr(args[0]): - assert i == 0 - args = (args,) - # Convert lists to tuples to help other libraries cache the results. - elif isinstance(args[i], list): - args = (*args[:i], tuple(args[i]), *args[i+1:]) - return args def _is_dunder(attr): return attr.startswith('__') and attr.endswith('__') class _BaseGenericAlias(_Final, _root=True): - """The central part of internal API. + """The central part of the internal API. This represents a generic version of type 'origin' with type arguments 'params'. There are two kind of these aliases: user defined and special. The special ones are wrappers around builtin collections and ABCs in collections.abc. These must - have 'name' always set. If 'inst' is False, then the alias can't be instantiated, + have 'name' always set. If 'inst' is False, then the alias can't be instantiated; this is used by e.g. typing.List and typing.Dict. """ + def __init__(self, origin, *, inst=True, name=None): self._inst = inst self._name = name @@ -1275,8 +1160,7 @@ class _BaseGenericAlias(_Final, _root=True): raise AttributeError(attr) def __setattr__(self, attr, val): - if _is_dunder(attr) or attr in {'_name', '_inst', '_nparams', - '_paramspec_tvars'}: + if _is_dunder(attr) or attr in {'_name', '_inst', '_nparams'}: super().__setattr__(attr, val) else: setattr(self.__origin__, attr, val) @@ -1314,8 +1198,7 @@ class _GenericAlias(_BaseGenericAlias, _root=True): # * Note that native container types, e.g. `tuple`, `list`, use # `types.GenericAlias` instead. # * Parameterized classes: - # T = TypeVar('T') - # class C(Generic[T]): pass + # class C[T]: pass # # C[int] is a _GenericAlias # * `Callable` aliases, generic `Callable` aliases, and # parameterized `Callable` aliases: @@ -1330,15 +1213,13 @@ class _GenericAlias(_BaseGenericAlias, _root=True): # ClassVar[float] # TypeVar[bool] - def __init__(self, origin, args, *, inst=True, name=None, - _paramspec_tvars=False): + def __init__(self, origin, args, *, inst=True, name=None): super().__init__(origin, inst=inst, name=name) if not isinstance(args, tuple): args = (args,) self.__args__ = tuple(... if a is _TypingEllipsis else a for a in args) self.__parameters__ = _collect_parameters(args) - self._paramspec_tvars = _paramspec_tvars if not name: self.__module__ = origin.__module__ @@ -1416,10 +1297,12 @@ class _GenericAlias(_BaseGenericAlias, _root=True): raise TypeError(f"Too {'many' if alen > plen else 'few'} arguments for {self};" f" actual {alen}, expected {plen}") new_arg_by_param = dict(zip(params, args)) + return tuple(self._make_substitution(self.__args__, new_arg_by_param)) + def _make_substitution(self, args, new_arg_by_param): + """Create a list of new type arguments.""" new_args = [] - for old_arg in self.__args__: - + for old_arg in args: if isinstance(old_arg, type): new_args.append(old_arg) continue @@ -1463,14 +1346,23 @@ class _GenericAlias(_BaseGenericAlias, _root=True): # should join all these types together in a flat list # `(float, int, str)` - so again, we should `extend`. new_args.extend(new_arg) + elif isinstance(old_arg, tuple): + # Corner case: + # P = ParamSpec('P') + # T = TypeVar('T') + # class Base(Generic[P]): ... + # Can be substituted like this: + # X = Base[[int, T]] + # In this case, `old_arg` will be a tuple: + new_args.append( + tuple(self._make_substitution(old_arg, new_arg_by_param)), + ) else: new_args.append(new_arg) - - return tuple(new_args) + return new_args def copy_with(self, args): - return self.__class__(self.__origin__, args, name=self._name, inst=self._inst, - _paramspec_tvars=self._paramspec_tvars) + return self.__class__(self.__origin__, args, name=self._name, inst=self._inst) def __repr__(self): if self._name: @@ -1560,6 +1452,22 @@ class _SpecialGenericAlias(_NotIterable, _BaseGenericAlias, _root=True): def __ror__(self, left): return Union[left, self] + +class _DeprecatedGenericAlias(_SpecialGenericAlias, _root=True): + def __init__( + self, origin, nparams, *, removal_version, inst=True, name=None + ): + super().__init__(origin, nparams, inst=inst, name=name) + self._removal_version = removal_version + + def __instancecheck__(self, inst): + import warnings + warnings._deprecated( + f"{self.__module__}.{self._name}", remove=self._removal_version + ) + return super().__instancecheck__(inst) + + class _CallableGenericAlias(_NotIterable, _GenericAlias, _root=True): def __repr__(self): assert self._name == 'Callable' @@ -1580,8 +1488,7 @@ class _CallableGenericAlias(_NotIterable, _GenericAlias, _root=True): class _CallableType(_SpecialGenericAlias, _root=True): def copy_with(self, params): return _CallableGenericAlias(self.__origin__, params, - name=self._name, inst=self._inst, - _paramspec_tvars=True) + name=self._name, inst=self._inst) def __getitem__(self, params): if not isinstance(params, tuple) or len(params) != 2: @@ -1664,7 +1571,6 @@ def _value_and_type_iter(parameters): class _LiteralGenericAlias(_GenericAlias, _root=True): - def __eq__(self, other): if not isinstance(other, _LiteralGenericAlias): return NotImplemented @@ -1689,41 +1595,57 @@ def Unpack(self, parameters): """Type unpack operator. The type unpack operator takes the child types from some container type, - such as `tuple[int, str]` or a `TypeVarTuple`, and 'pulls them out'. For - example: + such as `tuple[int, str]` or a `TypeVarTuple`, and 'pulls them out'. - # For some generic class `Foo`: - Foo[Unpack[tuple[int, str]]] # Equivalent to Foo[int, str] + For example:: + + # For some generic class `Foo`: + Foo[Unpack[tuple[int, str]]] # Equivalent to Foo[int, str] - Ts = TypeVarTuple('Ts') - # Specifies that `Bar` is generic in an arbitrary number of types. - # (Think of `Ts` as a tuple of an arbitrary number of individual - # `TypeVar`s, which the `Unpack` is 'pulling out' directly into the - # `Generic[]`.) - class Bar(Generic[Unpack[Ts]]): ... - Bar[int] # Valid - Bar[int, str] # Also valid + Ts = TypeVarTuple('Ts') + # Specifies that `Bar` is generic in an arbitrary number of types. + # (Think of `Ts` as a tuple of an arbitrary number of individual + # `TypeVar`s, which the `Unpack` is 'pulling out' directly into the + # `Generic[]`.) + class Bar(Generic[Unpack[Ts]]): ... + Bar[int] # Valid + Bar[int, str] # Also valid - From Python 3.11, this can also be done using the `*` operator: + From Python 3.11, this can also be done using the `*` operator:: Foo[*tuple[int, str]] class Bar(Generic[*Ts]): ... + And from Python 3.12, it can be done using built-in syntax for generics:: + + Foo[*tuple[int, str]] + class Bar[*Ts]: ... + + The operator can also be used along with a `TypedDict` to annotate + `**kwargs` in a function signature:: + + class Movie(TypedDict): + name: str + year: int + + # This function expects two keyword arguments - *name* of type `str` and + # *year* of type `int`. + def foo(**kwargs: Unpack[Movie]): ... + Note that there is only some runtime checking of this operator. Not everything the runtime allows may be accepted by static type checkers. - For more information, see PEP 646. + For more information, see PEPs 646 and 692. """ item = _type_check(parameters, f'{self} accepts only single type.') return _UnpackGenericAlias(origin=self, args=(item,)) class _UnpackGenericAlias(_GenericAlias, _root=True): - def __repr__(self): # `Unpack` only takes one argument, so __args__ should contain only # a single item. - return '*' + repr(self.__args__[0]) + return f'typing.Unpack[{_type_repr(self.__args__[0])}]' def __getitem__(self, args): if self.__typing_is_unpacked_typevartuple__: @@ -1747,127 +1669,24 @@ class _UnpackGenericAlias(_GenericAlias, _root=True): return isinstance(self.__args__[0], TypeVarTuple) -class Generic: - """Abstract base class for generic types. - - A generic type is typically declared by inheriting from - this class parameterized with one or more type variables. - For example, a generic mapping type might be defined as:: - - class Mapping(Generic[KT, VT]): - def __getitem__(self, key: KT) -> VT: - ... - # Etc. - - This class can then be used as follows:: - - def lookup_name(mapping: Mapping[KT, VT], key: KT, default: VT) -> VT: - try: - return mapping[key] - except KeyError: - return default - """ - __slots__ = () - _is_protocol = False - - @_tp_cache - def __class_getitem__(cls, params): - """Parameterizes a generic class. - - At least, parameterizing a generic class is the *main* thing this method - does. For example, for some generic class `Foo`, this is called when we - do `Foo[int]` - there, with `cls=Foo` and `params=int`. - - However, note that this method is also called when defining generic - classes in the first place with `class Foo(Generic[T]): ...`. - """ - if not isinstance(params, tuple): - params = (params,) - - params = tuple(_type_convert(p) for p in params) - if cls in (Generic, Protocol): - # Generic and Protocol can only be subscripted with unique type variables. - if not params: - raise TypeError( - f"Parameter list to {cls.__qualname__}[...] cannot be empty" - ) - if not all(_is_typevar_like(p) for p in params): - raise TypeError( - f"Parameters to {cls.__name__}[...] must all be type variables " - f"or parameter specification variables.") - if len(set(params)) != len(params): - raise TypeError( - f"Parameters to {cls.__name__}[...] must all be unique") - else: - # Subscripting a regular Generic subclass. - for param in cls.__parameters__: - prepare = getattr(param, '__typing_prepare_subst__', None) - if prepare is not None: - params = prepare(cls, params) - _check_generic(cls, params, len(cls.__parameters__)) - - new_args = [] - for param, new_arg in zip(cls.__parameters__, params): - if isinstance(param, TypeVarTuple): - new_args.extend(new_arg) - else: - new_args.append(new_arg) - params = tuple(new_args) - - return _GenericAlias(cls, params, - _paramspec_tvars=True) - - def __init_subclass__(cls, *args, **kwargs): - super().__init_subclass__(*args, **kwargs) - tvars = [] - if '__orig_bases__' in cls.__dict__: - error = Generic in cls.__orig_bases__ - else: - error = (Generic in cls.__bases__ and - cls.__name__ != 'Protocol' and - type(cls) != _TypedDictMeta) - if error: - raise TypeError("Cannot inherit from plain Generic") - if '__orig_bases__' in cls.__dict__: - tvars = _collect_parameters(cls.__orig_bases__) - # Look for Generic[T1, ..., Tn]. - # If found, tvars must be a subset of it. - # If not found, tvars is it. - # Also check for and reject plain Generic, - # and reject multiple Generic[...]. - gvars = None - for base in cls.__orig_bases__: - if (isinstance(base, _GenericAlias) and - base.__origin__ is Generic): - if gvars is not None: - raise TypeError( - "Cannot inherit from Generic[...] multiple types.") - gvars = base.__parameters__ - if gvars is not None: - tvarset = set(tvars) - gvarset = set(gvars) - if not tvarset <= gvarset: - s_vars = ', '.join(str(t) for t in tvars if t not in gvarset) - s_args = ', '.join(str(g) for g in gvars) - raise TypeError(f"Some type variables ({s_vars}) are" - f" not listed in Generic[{s_args}]") - tvars = gvars - cls.__parameters__ = tuple(tvars) - - class _TypingEllipsis: """Internal placeholder for ... (ellipsis).""" -_TYPING_INTERNALS = ['__parameters__', '__orig_bases__', '__orig_class__', - '_is_protocol', '_is_runtime_protocol'] +_TYPING_INTERNALS = frozenset({ + '__parameters__', '__orig_bases__', '__orig_class__', + '_is_protocol', '_is_runtime_protocol', '__protocol_attrs__', + '__callable_proto_members_only__', '__type_params__', +}) -_SPECIAL_NAMES = ['__abstractmethods__', '__annotations__', '__dict__', '__doc__', - '__init__', '__module__', '__new__', '__slots__', - '__subclasshook__', '__weakref__', '__class_getitem__'] +_SPECIAL_NAMES = frozenset({ + '__abstractmethods__', '__annotations__', '__dict__', '__doc__', + '__init__', '__module__', '__new__', '__slots__', + '__subclasshook__', '__weakref__', '__class_getitem__' +}) # These special attributes will be not collected as protocol members. -EXCLUDED_ATTRIBUTES = _TYPING_INTERNALS + _SPECIAL_NAMES + ['_MutableMapping__marker'] +EXCLUDED_ATTRIBUTES = _TYPING_INTERNALS | _SPECIAL_NAMES | {'_MutableMapping__marker'} def _get_protocol_attrs(cls): @@ -1878,20 +1697,15 @@ def _get_protocol_attrs(cls): """ attrs = set() for base in cls.__mro__[:-1]: # without object - if base.__name__ in ('Protocol', 'Generic'): + if base.__name__ in {'Protocol', 'Generic'}: continue annotations = getattr(base, '__annotations__', {}) - for attr in list(base.__dict__.keys()) + list(annotations.keys()): + for attr in (*base.__dict__, *annotations): if not attr.startswith('_abc_') and attr not in EXCLUDED_ATTRIBUTES: attrs.add(attr) return attrs -def _is_callable_members_only(cls): - # PEP 544 prohibits using issubclass() with protocols that have non-method members. - return all(callable(getattr(cls, attr, None)) for attr in _get_protocol_attrs(cls)) - - def _no_init_or_replace_init(self, *args, **kwargs): cls = type(self) @@ -1922,13 +1736,17 @@ def _no_init_or_replace_init(self, *args, **kwargs): def _caller(depth=1, default='__main__'): + try: + return sys._getframemodulename(depth + 1) or default + except AttributeError: # For platforms without _getframemodulename() + pass try: return sys._getframe(depth + 1).f_globals.get('__name__', default) except (AttributeError, ValueError): # For platforms without _getframe() - return None - + pass + return None -def _allow_reckless_class_checks(depth=3): +def _allow_reckless_class_checks(depth=2): """Allow instance and class checks for special stdlib modules. The abc and functools modules indiscriminately call isinstance() and @@ -1940,38 +1758,146 @@ def _allow_reckless_class_checks(depth=3): _PROTO_ALLOWLIST = { 'collections.abc': [ 'Callable', 'Awaitable', 'Iterable', 'Iterator', 'AsyncIterable', - 'Hashable', 'Sized', 'Container', 'Collection', 'Reversible', + 'Hashable', 'Sized', 'Container', 'Collection', 'Reversible', 'Buffer', ], 'contextlib': ['AbstractContextManager', 'AbstractAsyncContextManager'], } +@functools.cache +def _lazy_load_getattr_static(): + # Import getattr_static lazily so as not to slow down the import of typing.py + # Cache the result so we don't slow down _ProtocolMeta.__instancecheck__ unnecessarily + from inspect import getattr_static + return getattr_static + + +_cleanups.append(_lazy_load_getattr_static.cache_clear) + +def _pickle_psargs(psargs): + return ParamSpecArgs, (psargs.__origin__,) + +copyreg.pickle(ParamSpecArgs, _pickle_psargs) + +def _pickle_pskwargs(pskwargs): + return ParamSpecKwargs, (pskwargs.__origin__,) + +copyreg.pickle(ParamSpecKwargs, _pickle_pskwargs) + +del _pickle_psargs, _pickle_pskwargs + + class _ProtocolMeta(ABCMeta): - # This metaclass is really unfortunate and exists only because of - # the lack of __instancehook__. + # This metaclass is somewhat unfortunate, + # but is necessary for several reasons... + def __new__(mcls, name, bases, namespace, /, **kwargs): + if name == "Protocol" and bases == (Generic,): + pass + elif Protocol in bases: + for base in bases: + if not ( + base in {object, Generic} + or base.__name__ in _PROTO_ALLOWLIST.get(base.__module__, []) + or ( + issubclass(base, Generic) + and getattr(base, "_is_protocol", False) + ) + ): + raise TypeError( + f"Protocols can only inherit from other protocols, " + f"got {base!r}" + ) + return super().__new__(mcls, name, bases, namespace, **kwargs) + + def __init__(cls, *args, **kwargs): + super().__init__(*args, **kwargs) + if getattr(cls, "_is_protocol", False): + cls.__protocol_attrs__ = _get_protocol_attrs(cls) + # PEP 544 prohibits using issubclass() + # with protocols that have non-method members. + cls.__callable_proto_members_only__ = all( + callable(getattr(cls, attr, None)) for attr in cls.__protocol_attrs__ + ) + + def __subclasscheck__(cls, other): + if cls is Protocol: + return type.__subclasscheck__(cls, other) + if ( + getattr(cls, '_is_protocol', False) + and not _allow_reckless_class_checks() + ): + if not isinstance(other, type): + # Same error message as for issubclass(1, int). + raise TypeError('issubclass() arg 1 must be a class') + if ( + not cls.__callable_proto_members_only__ + and cls.__dict__.get("__subclasshook__") is _proto_hook + ): + raise TypeError( + "Protocols with non-method members don't support issubclass()" + ) + if not getattr(cls, '_is_runtime_protocol', False): + raise TypeError( + "Instance and class checks can only be used with " + "@runtime_checkable protocols" + ) + return super().__subclasscheck__(other) + def __instancecheck__(cls, instance): # We need this method for situations where attributes are # assigned in __init__. + if cls is Protocol: + return type.__instancecheck__(cls, instance) + if not getattr(cls, "_is_protocol", False): + # i.e., it's a concrete subclass of a protocol + return super().__instancecheck__(instance) + if ( - getattr(cls, '_is_protocol', False) and not getattr(cls, '_is_runtime_protocol', False) and - not _allow_reckless_class_checks(depth=2) + not _allow_reckless_class_checks() ): raise TypeError("Instance and class checks can only be used with" " @runtime_checkable protocols") - if ((not getattr(cls, '_is_protocol', False) or - _is_callable_members_only(cls)) and - issubclass(instance.__class__, cls)): + if super().__instancecheck__(instance): + return True + + getattr_static = _lazy_load_getattr_static() + for attr in cls.__protocol_attrs__: + try: + val = getattr_static(instance, attr) + except AttributeError: + break + if val is None and callable(getattr(cls, attr, None)): + break + else: return True - if cls._is_protocol: - if all(hasattr(instance, attr) and - # All *methods* can be blocked by setting them to None. - (not callable(getattr(cls, attr, None)) or - getattr(instance, attr) is not None) - for attr in _get_protocol_attrs(cls)): - return True - return super().__instancecheck__(instance) + + return False + + +@classmethod +def _proto_hook(cls, other): + if not cls.__dict__.get('_is_protocol', False): + return NotImplemented + + for attr in cls.__protocol_attrs__: + for base in other.__mro__: + # Check if the members appears in the class dictionary... + if attr in base.__dict__: + if base.__dict__[attr] is None: + return NotImplemented + break + + # ...or in annotations, if it is a sub-protocol. + annotations = getattr(base, '__annotations__', {}) + if (isinstance(annotations, collections.abc.Mapping) and + attr in annotations and + issubclass(other, Generic) and getattr(other, '_is_protocol', False)): + break + else: + return NotImplemented + return True class Protocol(Generic, metaclass=_ProtocolMeta): @@ -1984,7 +1910,9 @@ class Protocol(Generic, metaclass=_ProtocolMeta): ... Such classes are primarily used with static type checkers that recognize - structural subtyping (static duck-typing), for example:: + structural subtyping (static duck-typing). + + For example:: class C: def meth(self) -> int: @@ -2000,10 +1928,11 @@ class Protocol(Generic, metaclass=_ProtocolMeta): only the presence of given attributes, ignoring their type signatures. Protocol classes can be generic, they are defined as:: - class GenProto(Protocol[T]): + class GenProto[T](Protocol): def meth(self) -> T: ... """ + __slots__ = () _is_protocol = True _is_runtime_protocol = False @@ -2016,60 +1945,11 @@ class Protocol(Generic, metaclass=_ProtocolMeta): cls._is_protocol = any(b is Protocol for b in cls.__bases__) # Set (or override) the protocol subclass hook. - def _proto_hook(other): - if not cls.__dict__.get('_is_protocol', False): - return NotImplemented - - # First, perform various sanity checks. - if not getattr(cls, '_is_runtime_protocol', False): - if _allow_reckless_class_checks(): - return NotImplemented - raise TypeError("Instance and class checks can only be used with" - " @runtime_checkable protocols") - if not _is_callable_members_only(cls): - if _allow_reckless_class_checks(): - return NotImplemented - raise TypeError("Protocols with non-method members" - " don't support issubclass()") - if not isinstance(other, type): - # Same error message as for issubclass(1, int). - raise TypeError('issubclass() arg 1 must be a class') - - # Second, perform the actual structural compatibility check. - for attr in _get_protocol_attrs(cls): - for base in other.__mro__: - # Check if the members appears in the class dictionary... - if attr in base.__dict__: - if base.__dict__[attr] is None: - return NotImplemented - break - - # ...or in annotations, if it is a sub-protocol. - annotations = getattr(base, '__annotations__', {}) - if (isinstance(annotations, collections.abc.Mapping) and - attr in annotations and - issubclass(other, Generic) and other._is_protocol): - break - else: - return NotImplemented - return True - if '__subclasshook__' not in cls.__dict__: cls.__subclasshook__ = _proto_hook - # We have nothing more to do for non-protocols... - if not cls._is_protocol: - return - - # ... otherwise check consistency of bases, and prohibit instantiation. - for base in cls.__bases__: - if not (base in (object, Generic) or - base.__module__ in _PROTO_ALLOWLIST and - base.__name__ in _PROTO_ALLOWLIST[base.__module__] or - issubclass(base, Generic) and base._is_protocol): - raise TypeError('Protocols can only inherit from other' - ' protocols, got %r' % base) - if cls.__init__ is Protocol.__init__: + # Prohibit instantiation for protocol classes + if cls._is_protocol and cls.__init__ is Protocol.__init__: cls.__init__ = _no_init_or_replace_init @@ -2077,15 +1957,18 @@ class _AnnotatedAlias(_NotIterable, _GenericAlias, _root=True): """Runtime representation of an annotated type. At its core 'Annotated[t, dec1, dec2, ...]' is an alias for the type 't' - with extra annotations. The alias behaves like a normal typing alias, - instantiating is the same as instantiating the underlying type, binding + with extra annotations. The alias behaves like a normal typing alias. + Instantiating is the same as instantiating the underlying type; binding it to types is also the same. + + The metadata itself is stored in a '__metadata__' attribute as a tuple. """ + def __init__(self, origin, metadata): if isinstance(origin, _AnnotatedAlias): metadata = origin.__metadata__ + metadata origin = origin.__origin__ - super().__init__(origin, origin) + super().__init__(origin, origin, name='Annotated') self.__metadata__ = metadata def copy_with(self, params): @@ -2118,9 +2001,12 @@ class _AnnotatedAlias(_NotIterable, _GenericAlias, _root=True): return 'Annotated' return super().__getattr__(attr) + def __mro_entries__(self, bases): + return (self.__origin__,) + class Annotated: - """Add context specific metadata to a type. + """Add context-specific metadata to a type. Example: Annotated[int, runtime_check.Unsigned] indicates to the hypothetical runtime_check module that this type is an unsigned int. @@ -2132,28 +2018,34 @@ class Annotated: Details: - It's an error to call `Annotated` with less than two arguments. - - Nested Annotated are flattened:: + - Access the metadata via the ``__metadata__`` attribute:: + + assert Annotated[int, '$'].__metadata__ == ('$',) + + - Nested Annotated types are flattened:: - Annotated[Annotated[T, Ann1, Ann2], Ann3] == Annotated[T, Ann1, Ann2, Ann3] + assert Annotated[Annotated[T, Ann1, Ann2], Ann3] == Annotated[T, Ann1, Ann2, Ann3] - Instantiating an annotated type is equivalent to instantiating the underlying type:: - Annotated[C, Ann1](5) == C(5) + assert Annotated[C, Ann1](5) == C(5) - Annotated can be used as a generic type alias:: - Optimized = Annotated[T, runtime.Optimize()] - Optimized[int] == Annotated[int, runtime.Optimize()] + type Optimized[T] = Annotated[T, runtime.Optimize()] + # type checker will treat Optimized[int] + # as equivalent to Annotated[int, runtime.Optimize()] - OptimizedList = Annotated[List[T], runtime.Optimize()] - OptimizedList[int] == Annotated[List[int], runtime.Optimize()] + type OptimizedList[T] = Annotated[list[T], runtime.Optimize()] + # type checker will treat OptimizedList[int] + # as equivalent to Annotated[list[int], runtime.Optimize()] - Annotated cannot be used with an unpacked TypeVarTuple:: - Annotated[*Ts, Ann1] # NOT valid + type Variadic[*Ts] = Annotated[*Ts, Ann1] # NOT valid - This would be equivalent to + This would be equivalent to:: Annotated[T1, T2, T3, ..., Ann1] @@ -2193,6 +2085,7 @@ def runtime_checkable(cls): Raise TypeError if applied to a non-protocol class. This allows a simple-minded structural check very similar to one trick ponies in collections.abc such as Iterable. + For example:: @runtime_checkable @@ -2204,7 +2097,7 @@ def runtime_checkable(cls): Warning: this will check only the presence of the required methods, not their type signatures! """ - if not issubclass(cls, Generic) or not cls._is_protocol: + if not issubclass(cls, Generic) or not getattr(cls, '_is_protocol', False): raise TypeError('@runtime_checkable can be only applied to protocol classes,' ' got %r' % cls) cls._is_runtime_protocol = True @@ -2225,15 +2118,15 @@ def cast(typ, val): def assert_type(val, typ, /): """Ask a static type checker to confirm that the value is of the given type. - When the type checker encounters a call to assert_type(), it + At runtime this does nothing: it returns the first argument unchanged with no + checks or side effects, no matter the actual type of the argument. + + When a static type checker encounters a call to assert_type(), it emits an error if the value is not of the specified type:: def greet(name: str) -> None: - assert_type(name, str) # ok + assert_type(name, str) # OK assert_type(name, int) # type checker error - - At runtime this returns the first argument unchanged and otherwise - does nothing. """ return val @@ -2274,7 +2167,6 @@ def get_type_hints(obj, globalns=None, localns=None, include_extras=False): - If two dict arguments are passed, they specify globals and locals, respectively. """ - if getattr(obj, '__no_type_check__', None): return {} # Classes require a special treatment. @@ -2344,8 +2236,7 @@ def get_type_hints(obj, globalns=None, localns=None, include_extras=False): def _strip_annotations(t): - """Strips the annotations from a given type. - """ + """Strip the annotations from a given type.""" if isinstance(t, _AnnotatedAlias): return _strip_annotations(t.__origin__) if hasattr(t, "__origin__") and t.__origin__ in (Required, NotRequired): @@ -2372,17 +2263,19 @@ def _strip_annotations(t): def get_origin(tp): """Get the unsubscripted version of a type. - This supports generic types, Callable, Tuple, Union, Literal, Final, ClassVar - and Annotated. Return None for unsupported types. Examples:: - - get_origin(Literal[42]) is Literal - get_origin(int) is None - get_origin(ClassVar[int]) is ClassVar - get_origin(Generic) is Generic - get_origin(Generic[T]) is Generic - get_origin(Union[T, int]) is Union - get_origin(List[Tuple[T, T]][int]) == list - get_origin(P.args) is P + This supports generic types, Callable, Tuple, Union, Literal, Final, ClassVar, + Annotated, and others. Return None for unsupported types. + + Examples:: + + assert get_origin(Literal[42]) is Literal + assert get_origin(int) is None + assert get_origin(ClassVar[int]) is ClassVar + assert get_origin(Generic) is Generic + assert get_origin(Generic[T]) is Generic + assert get_origin(Union[T, int]) is Union + assert get_origin(List[Tuple[T, T]][int]) is list + assert get_origin(P.args) is P """ if isinstance(tp, _AnnotatedAlias): return Annotated @@ -2400,12 +2293,14 @@ def get_args(tp): """Get type arguments with all substitutions performed. For unions, basic simplifications used by Union constructor are performed. + Examples:: - get_args(Dict[str, int]) == (str, int) - get_args(int) == () - get_args(Union[int, Union[T, int], str][int]) == (int, str) - get_args(Union[int, Tuple[T, int]][str]) == (int, Tuple[str, int]) - get_args(Callable[[], T][int]) == ([], int) + + assert get_args(Dict[str, int]) == (str, int) + assert get_args(int) == () + assert get_args(Union[int, Union[T, int], str][int]) == (int, str) + assert get_args(Union[int, Tuple[T, int]][str]) == (int, Tuple[str, int]) + assert get_args(Callable[[], T][int]) == ([], int) """ if isinstance(tp, _AnnotatedAlias): return (tp.__origin__,) + tp.__metadata__ @@ -2420,14 +2315,15 @@ def get_args(tp): def is_typeddict(tp): - """Check if an annotation is a TypedDict class + """Check if an annotation is a TypedDict class. For example:: + class Film(TypedDict): title: str year: int - is_typeddict(Film) # => True + is_typeddict(Film) # => True is_typeddict(Union[list, str]) # => False """ return isinstance(tp, _TypedDictMeta) @@ -2454,7 +2350,6 @@ def assert_never(arg: Never, /) -> Never: reachable, it will emit an error. At runtime, this throws an exception when called. - """ value = repr(arg) if len(value) > _ASSERT_NEVER_REPR_MAX_LENGTH: @@ -2504,7 +2399,6 @@ def no_type_check_decorator(decorator): This wraps the decorator with something that wraps the decorated function in @no_type_check. """ - @functools.wraps(decorator) def wrapped_decorator(*args, **kwds): func = decorator(*args, **kwds) @@ -2531,27 +2425,29 @@ def overload(func): """Decorator for overloaded functions/methods. In a stub file, place two or more stub definitions for the same - function in a row, each decorated with @overload. For example: + function in a row, each decorated with @overload. - @overload - def utf8(value: None) -> None: ... - @overload - def utf8(value: bytes) -> bytes: ... - @overload - def utf8(value: str) -> bytes: ... + For example:: + + @overload + def utf8(value: None) -> None: ... + @overload + def utf8(value: bytes) -> bytes: ... + @overload + def utf8(value: str) -> bytes: ... In a non-stub file (i.e. a regular .py file), do the same but follow it with an implementation. The implementation should *not* - be decorated with @overload. For example: + be decorated with @overload:: - @overload - def utf8(value: None) -> None: ... - @overload - def utf8(value: bytes) -> bytes: ... - @overload - def utf8(value: str) -> bytes: ... - def utf8(value): - # implementation goes here + @overload + def utf8(value: None) -> None: ... + @overload + def utf8(value: bytes) -> bytes: ... + @overload + def utf8(value: str) -> bytes: ... + def utf8(value): + ... # implementation goes here The overloads for a function can be retrieved at runtime using the get_overloads() function. @@ -2584,29 +2480,30 @@ def clear_overloads(): def final(f): - """A decorator to indicate final methods and final classes. + """Decorator to indicate final methods and final classes. Use this decorator to indicate to type checkers that the decorated method cannot be overridden, and decorated class cannot be subclassed. - For example: - - class Base: - @final - def done(self) -> None: - ... - class Sub(Base): - def done(self) -> None: # Error reported by type checker + + For example:: + + class Base: + @final + def done(self) -> None: + ... + class Sub(Base): + def done(self) -> None: # Error reported by type checker ... - @final - class Leaf: - ... - class Other(Leaf): # Error reported by type checker - ... + @final + class Leaf: + ... + class Other(Leaf): # Error reported by type checker + ... There is no runtime checking of these properties. The decorator - sets the ``__final__`` attribute to ``True`` on the decorated object - to allow runtime introspection. + attempts to set the ``__final__`` attribute to ``True`` on the decorated + object to allow runtime introspection. """ try: f.__final__ = True @@ -2618,8 +2515,9 @@ def final(f): return f -# Some unconstrained type variables. These are used by the container types. -# (These are not for export.) +# Some unconstrained type variables. These were initially used by the container types. +# They were never meant for export and are now unused, but we keep them around to +# avoid breaking compatibility with users who import them. T = TypeVar('T') # Any type. KT = TypeVar('KT') # Key type. VT = TypeVar('VT') # Value type. @@ -2630,6 +2528,7 @@ T_contra = TypeVar('T_contra', contravariant=True) # Ditto contravariant. # Internal type variable used for Type[]. CT_co = TypeVar('CT_co', covariant=True, bound=type) + # A useful type variable with constraints. This represents string types. # (This one *is* for export!) AnyStr = TypeVar('AnyStr', bytes, str) @@ -2651,13 +2550,17 @@ Container = _alias(collections.abc.Container, 1) Collection = _alias(collections.abc.Collection, 1) Callable = _CallableType(collections.abc.Callable, 2) Callable.__doc__ = \ - """Callable type; Callable[[int], str] is a function of (int) -> str. + """Deprecated alias to collections.abc.Callable. + + Callable[[int], str] signifies a function that takes a single + parameter of type int and returns a str. The subscription syntax must always be used with exactly two - values: the argument list and the return type. The argument list - must be a list of types or ellipsis; the return type must be a single type. + values: the argument list and the return type. + The argument list must be a list of types, a ParamSpec, + Concatenate or ellipsis. The return type must be a single type. - There is no syntax to indicate optional or keyword arguments, + There is no syntax to indicate optional or keyword arguments; such function types are rarely used as callback types. """ AbstractSet = _alias(collections.abc.Set, 1, name='AbstractSet') @@ -2667,11 +2570,15 @@ Mapping = _alias(collections.abc.Mapping, 2) MutableMapping = _alias(collections.abc.MutableMapping, 2) Sequence = _alias(collections.abc.Sequence, 1) MutableSequence = _alias(collections.abc.MutableSequence, 1) -ByteString = _alias(collections.abc.ByteString, 0) # Not generic +ByteString = _DeprecatedGenericAlias( + collections.abc.ByteString, 0, removal_version=(3, 14) # Not generic. +) # Tuple accepts variable number of parameters. Tuple = _TupleType(tuple, -1, inst=False, name='Tuple') Tuple.__doc__ = \ - """Tuple type; Tuple[X, Y] is the cross-product type of X and Y. + """Deprecated alias to builtins.tuple. + + Tuple[X, Y] is the cross-product type of X and Y. Example: Tuple[T1, T2] is a tuple of two elements corresponding to type variables T1 and T2. Tuple[int, float, str] is a tuple @@ -2698,25 +2605,25 @@ Generator = _alias(collections.abc.Generator, 3) AsyncGenerator = _alias(collections.abc.AsyncGenerator, 2) Type = _alias(type, 1, inst=False, name='Type') Type.__doc__ = \ - """A special construct usable to annotate class objects. + """Deprecated alias to builtins.type. + builtins.type or typing.Type can be used to annotate class objects. For example, suppose we have the following classes:: - class User: ... # Abstract base for User classes - class BasicUser(User): ... - class ProUser(User): ... - class TeamUser(User): ... + class User: ... # Abstract base for User classes + class BasicUser(User): ... + class ProUser(User): ... + class TeamUser(User): ... And a function that takes a class argument that's a subclass of User and returns an instance of the corresponding class:: - U = TypeVar('U', bound=User) - def new_user(user_class: Type[U]) -> U: - user = user_class() - # (Here we could write the user object to a database) - return user + def new_user[U](user_class: Type[U]) -> U: + user = user_class() + # (Here we could write the user object to a database) + return user - joe = new_user(BasicUser) + joe = new_user(BasicUser) At this point the type checker knows that joe has type BasicUser. """ @@ -2725,6 +2632,7 @@ Type.__doc__ = \ @runtime_checkable class SupportsInt(Protocol): """An ABC with one abstract method __int__.""" + __slots__ = () @abstractmethod @@ -2735,6 +2643,7 @@ class SupportsInt(Protocol): @runtime_checkable class SupportsFloat(Protocol): """An ABC with one abstract method __float__.""" + __slots__ = () @abstractmethod @@ -2745,6 +2654,7 @@ class SupportsFloat(Protocol): @runtime_checkable class SupportsComplex(Protocol): """An ABC with one abstract method __complex__.""" + __slots__ = () @abstractmethod @@ -2755,6 +2665,7 @@ class SupportsComplex(Protocol): @runtime_checkable class SupportsBytes(Protocol): """An ABC with one abstract method __bytes__.""" + __slots__ = () @abstractmethod @@ -2765,6 +2676,7 @@ class SupportsBytes(Protocol): @runtime_checkable class SupportsIndex(Protocol): """An ABC with one abstract method __index__.""" + __slots__ = () @abstractmethod @@ -2773,22 +2685,24 @@ class SupportsIndex(Protocol): @runtime_checkable -class SupportsAbs(Protocol[T_co]): +class SupportsAbs[T](Protocol): """An ABC with one abstract method __abs__ that is covariant in its return type.""" + __slots__ = () @abstractmethod - def __abs__(self) -> T_co: + def __abs__(self) -> T: pass @runtime_checkable -class SupportsRound(Protocol[T_co]): +class SupportsRound[T](Protocol): """An ABC with one abstract method __round__ that is covariant in its return type.""" + __slots__ = () @abstractmethod - def __round__(self, ndigits: int = 0) -> T_co: + def __round__(self, ndigits: int = 0) -> T: pass @@ -2811,7 +2725,6 @@ _special = frozenset({'__module__', '__name__', '__annotations__'}) class NamedTupleMeta(type): - def __new__(cls, typename, bases, ns): assert _NamedTuple in bases for base in bases: @@ -2834,7 +2747,7 @@ class NamedTupleMeta(type): module=ns['__module__']) nm_tpl.__bases__ = bases if Generic in bases: - class_getitem = Generic.__class_getitem__.__func__ + class_getitem = _generic_class_getitem nm_tpl.__class_getitem__ = classmethod(class_getitem) # update from user namespace without overriding special namedtuple attributes for key in ns: @@ -2850,7 +2763,7 @@ class NamedTupleMeta(type): def NamedTuple(typename, fields=None, /, **kwargs): """Typed version of namedtuple. - Usage in Python versions >= 3.6:: + Usage:: class Employee(NamedTuple): name: str @@ -2863,11 +2776,7 @@ def NamedTuple(typename, fields=None, /, **kwargs): The resulting class has an extra __annotations__ attribute, giving a dict that maps field names to types. (The field names are also in the _fields attribute, which is part of the namedtuple API.) - Alternative equivalent keyword syntax is also accepted:: - - Employee = NamedTuple('Employee', name=str, id=int) - - In Python versions <= 3.5 use:: + An alternative equivalent functional syntax is also accepted:: Employee = NamedTuple('Employee', [('name', str), ('id', int)]) """ @@ -2876,7 +2785,9 @@ def NamedTuple(typename, fields=None, /, **kwargs): elif kwargs: raise TypeError("Either list of fields or keywords" " can be provided to NamedTuple, not both") - return _make_nmtuple(typename, fields, module=_caller()) + nt = _make_nmtuple(typename, fields, module=_caller()) + nt.__orig_bases__ = (NamedTuple,) + return nt _NamedTuple = type.__new__(NamedTupleMeta, 'NamedTuple', (), {}) @@ -2889,7 +2800,7 @@ NamedTuple.__mro_entries__ = _namedtuple_mro_entries class _TypedDictMeta(type): def __new__(cls, name, bases, ns, total=True): - """Create new typed dict class object. + """Create a new typed dict class object. This method is called when TypedDict is subclassed, or when TypedDict is instantiated. This way @@ -2908,6 +2819,9 @@ class _TypedDictMeta(type): tp_dict = type.__new__(_TypedDictMeta, name, (*generic_base, dict), ns) + if not hasattr(tp_dict, '__orig_bases__'): + tp_dict.__orig_bases__ = bases + annotations = {} own_annotations = ns.get('__annotations__', {}) msg = "TypedDict('Name', {f0: t0, f1: t1, ...}); each t must be a type" @@ -2960,10 +2874,11 @@ class _TypedDictMeta(type): def TypedDict(typename, fields=None, /, *, total=True, **kwargs): """A simple typed namespace. At runtime it is equivalent to a plain dict. - TypedDict creates a dictionary type that expects all of its + TypedDict creates a dictionary type such that a type checker will expect all instances to have a certain set of keys, where each key is associated with a value of a consistent type. This expectation - is not checked at runtime but is only enforced by type checkers. + is not checked at runtime. + Usage:: class Point2D(TypedDict): @@ -2983,20 +2898,25 @@ def TypedDict(typename, fields=None, /, *, total=True, **kwargs): Point2D = TypedDict('Point2D', {'x': int, 'y': int, 'label': str}) By default, all keys must be present in a TypedDict. It is possible - to override this by specifying totality. - Usage:: + to override this by specifying totality:: - class point2D(TypedDict, total=False): + class Point2D(TypedDict, total=False): x: int y: int - This means that a point2D TypedDict can have any of the keys omitted.A type + This means that a Point2D TypedDict can have any of the keys omitted. A type checker is only expected to support a literal False or True as the value of the total argument. True is the default, and makes all items defined in the class body be required. - The class syntax is only supported in Python 3.6+, while the other - syntax form works for Python 2.7 and 3.2+ + The Required and NotRequired special forms can also be used to mark + individual keys as being required or not required:: + + class Point2D(TypedDict): + x: int # the "x" key must always be present (Required is the default) + y: NotRequired[int] # the "y" key can be omitted + + See PEP 655 for more details on Required and NotRequired. """ if fields is None: fields = kwargs @@ -3018,7 +2938,9 @@ def TypedDict(typename, fields=None, /, *, total=True, **kwargs): # Setting correct module is necessary to make typed dict classes pickleable. ns['__module__'] = module - return _TypedDictMeta(typename, (), ns, total=total) + td = _TypedDictMeta(typename, (), ns, total=total) + td.__orig_bases__ = (TypedDict,) + return td _TypedDict = type.__new__(_TypedDictMeta, 'TypedDict', (), {}) TypedDict.__mro_entries__ = lambda bases: (_TypedDict,) @@ -3026,8 +2948,11 @@ TypedDict.__mro_entries__ = lambda bases: (_TypedDict,) @_SpecialForm def Required(self, parameters): - """A special typing construct to mark a key of a total=False TypedDict - as required. For example: + """Special typing construct to mark a TypedDict key as required. + + This is mainly useful for total=False TypedDicts. + + For example:: class Movie(TypedDict, total=False): title: Required[str] @@ -3047,8 +2972,9 @@ def Required(self, parameters): @_SpecialForm def NotRequired(self, parameters): - """A special typing construct to mark a key of a TypedDict as - potentially missing. For example: + """Special typing construct to mark a TypedDict key as potentially missing. + + For example:: class Movie(TypedDict): title: str @@ -3064,10 +2990,13 @@ def NotRequired(self, parameters): class NewType: - """NewType creates simple unique types with almost zero - runtime overhead. NewType(name, tp) is considered a subtype of tp + """NewType creates simple unique types with almost zero runtime overhead. + + NewType(name, tp) is considered a subtype of tp by static type checkers. At runtime, NewType(name, tp) returns - a dummy callable that simply returns its argument. Usage:: + a dummy callable that simply returns its argument. + + Usage:: UserId = NewType('UserId', int) @@ -3318,7 +3247,7 @@ re.__name__ = __name__ + '.re' sys.modules[re.__name__] = re -def reveal_type(obj: T, /) -> T: +def reveal_type[T](obj: T, /) -> T: """Reveal the inferred type of a variable. When a static type checker encounters a call to ``reveal_type()``, @@ -3327,34 +3256,38 @@ def reveal_type(obj: T, /) -> T: x: int = 1 reveal_type(x) - Running a static type checker (e.g., ``mypy``) on this example + Running a static type checker (e.g., mypy) on this example will produce output similar to 'Revealed type is "builtins.int"'. At runtime, the function prints the runtime type of the argument and returns it unchanged. - """ print(f"Runtime type is {type(obj).__name__!r}", file=sys.stderr) return obj +class _IdentityCallable(Protocol): + def __call__[T](self, arg: T, /) -> T: + ... + + def dataclass_transform( *, eq_default: bool = True, order_default: bool = False, kw_only_default: bool = False, + frozen_default: bool = False, field_specifiers: tuple[type[Any] | Callable[..., Any], ...] = (), **kwargs: Any, -) -> Callable[[T], T]: - """Decorator that marks a function, class, or metaclass as providing - dataclass-like behavior. +) -> _IdentityCallable: + """Decorator to mark an object as providing dataclass-like behaviour. - Example usage with a decorator function: + The decorator can be applied to a function, class, or metaclass. - T = TypeVar("T") + Example usage with a decorator function:: @dataclass_transform() - def create_model(cls: type[T]) -> type[T]: + def create_model[T](cls: type[T]) -> type[T]: ... return cls @@ -3363,7 +3296,7 @@ def dataclass_transform( id: int name: str - On a base class: + On a base class:: @dataclass_transform() class ModelBase: ... @@ -3372,7 +3305,7 @@ def dataclass_transform( id: int name: str - On a metaclass: + On a metaclass:: @dataclass_transform() class ModelMeta(type): ... @@ -3396,6 +3329,8 @@ def dataclass_transform( assumed to be True or False if it is omitted by the caller. - ``kw_only_default`` indicates whether the ``kw_only`` parameter is assumed to be True or False if it is omitted by the caller. + - ``frozen_default`` indicates whether the ``frozen`` parameter is + assumed to be True or False if it is omitted by the caller. - ``field_specifiers`` specifies a static list of supported classes or functions that describe fields, similar to ``dataclasses.field()``. - Arbitrary other keyword arguments are accepted in order to allow for @@ -3412,8 +3347,47 @@ def dataclass_transform( "eq_default": eq_default, "order_default": order_default, "kw_only_default": kw_only_default, + "frozen_default": frozen_default, "field_specifiers": field_specifiers, "kwargs": kwargs, } return cls_or_fn return decorator + + +type _Func = Callable[..., Any] + + +def override[F: _Func](method: F, /) -> F: + """Indicate that a method is intended to override a method in a base class. + + Usage:: + + class Base: + def method(self) -> None: ... + pass + + class Child(Base): + @override + def method(self) -> None: + super().method() + + When this decorator is applied to a method, the type checker will + validate that it overrides a method or attribute with the same name on a + base class. This helps prevent bugs that may occur when a base class is + changed without an equivalent change to a child class. + + There is no runtime checking of this property. The decorator attempts to + set the ``__override__`` attribute to ``True`` on the decorated object to + allow runtime introspection. + + See PEP 698 for details. + """ + try: + method.__override__ = True + except (AttributeError, TypeError): + # Skip the attribute silently if it is not writable. + # AttributeError happens if the object has __slots__ or a + # read-only property, TypeError if it's a builtin class. + pass + return method diff --git a/Lib/unittest/__init__.py b/Lib/unittest/__init__.py index 005d23f6..5bcbf834 100644 --- a/Lib/unittest/__init__.py +++ b/Lib/unittest/__init__.py @@ -69,19 +69,6 @@ from .signals import installHandler, registerResult, removeResult, removeHandler # IsolatedAsyncioTestCase will be imported lazily. from .loader import makeSuite, getTestCaseNames, findTestCases -# deprecated -_TextTestResult = TextTestResult - - -# There are no tests here, so don't try to run anything discovered from -# introspecting the symbols (e.g. FunctionTestCase). Instead, all our -# tests come from within unittest.test. -def load_tests(loader, tests, pattern): - import os.path - # top level directory cached on loader instance - this_dir = os.path.dirname(__file__) - return loader.discover(start_dir=this_dir, pattern=pattern) - # Lazy import of IsolatedAsyncioTestCase from .async_case # It imports asyncio, which is relatively heavy, but most tests diff --git a/Lib/unittest/case.py b/Lib/unittest/case.py index c4aa2d77..001b640d 100644 --- a/Lib/unittest/case.py +++ b/Lib/unittest/case.py @@ -9,6 +9,7 @@ import warnings import collections import contextlib import traceback +import time import types from . import result @@ -572,6 +573,15 @@ class TestCase(object): else: addUnexpectedSuccess(self) + def _addDuration(self, result, elapsed): + try: + addDuration = result.addDuration + except AttributeError: + warnings.warn("TestResult has no addDuration method", + RuntimeWarning) + else: + addDuration(self, elapsed) + def _callSetUp(self): self.setUp() @@ -612,6 +622,7 @@ class TestCase(object): getattr(testMethod, "__unittest_expecting_failure__", False) ) outcome = _Outcome(result) + start_time = time.perf_counter() try: self._outcome = outcome @@ -625,6 +636,7 @@ class TestCase(object): with outcome.testPartExecutor(self): self._callTearDown() self.doCleanups() + self._addDuration(result, (time.perf_counter() - start_time)) if outcome.success: if expecting_failure: @@ -1171,35 +1183,6 @@ class TestCase(object): standardMsg = self._truncateMessage(standardMsg, diff) self.fail(self._formatMessage(msg, standardMsg)) - def assertDictContainsSubset(self, subset, dictionary, msg=None): - """Checks whether dictionary is a superset of subset.""" - warnings.warn('assertDictContainsSubset is deprecated', - DeprecationWarning) - missing = [] - mismatched = [] - for key, value in subset.items(): - if key not in dictionary: - missing.append(key) - elif value != dictionary[key]: - mismatched.append('%s, expected: %s, actual: %s' % - (safe_repr(key), safe_repr(value), - safe_repr(dictionary[key]))) - - if not (missing or mismatched): - return - - standardMsg = '' - if missing: - standardMsg = 'Missing: %s' % ','.join(safe_repr(m) for m in - missing) - if mismatched: - if standardMsg: - standardMsg += '; ' - standardMsg += 'Mismatched values: %s' % ','.join(mismatched) - - self.fail(self._formatMessage(msg, standardMsg)) - - def assertCountEqual(self, first, second, msg=None): """Asserts that two iterables have the same elements, the same number of times, without regard to order. @@ -1234,19 +1217,34 @@ class TestCase(object): def assertMultiLineEqual(self, first, second, msg=None): """Assert that two multi-line strings are equal.""" - self.assertIsInstance(first, str, 'First argument is not a string') - self.assertIsInstance(second, str, 'Second argument is not a string') + self.assertIsInstance(first, str, "First argument is not a string") + self.assertIsInstance(second, str, "Second argument is not a string") if first != second: - # don't use difflib if the strings are too long + # Don't use difflib if the strings are too long if (len(first) > self._diffThreshold or len(second) > self._diffThreshold): self._baseAssertEqual(first, second, msg) - firstlines = first.splitlines(keepends=True) - secondlines = second.splitlines(keepends=True) - if len(firstlines) == 1 and first.strip('\r\n') == first: - firstlines = [first + '\n'] - secondlines = [second + '\n'] + + # Append \n to both strings if either is missing the \n. + # This allows the final ndiff to show the \n difference. The + # exception here is if the string is empty, in which case no + # \n should be added + first_presplit = first + second_presplit = second + if first and second: + if first[-1] != '\n' or second[-1] != '\n': + first_presplit += '\n' + second_presplit += '\n' + elif second and second[-1] != '\n': + second_presplit += '\n' + elif first and first[-1] != '\n': + first_presplit += '\n' + + firstlines = first_presplit.splitlines(keepends=True) + secondlines = second_presplit.splitlines(keepends=True) + + # Generate the message and diff, then raise the exception standardMsg = '%s != %s' % _common_shorten_repr(first, second) diff = '\n' + ''.join(difflib.ndiff(firstlines, secondlines)) standardMsg = self._truncateMessage(standardMsg, diff) @@ -1363,27 +1361,6 @@ class TestCase(object): raise self.failureException(msg) - def _deprecate(original_func): - def deprecated_func(*args, **kwargs): - warnings.warn( - 'Please use {0} instead.'.format(original_func.__name__), - DeprecationWarning, 2) - return original_func(*args, **kwargs) - return deprecated_func - - # see #9424 - failUnlessEqual = assertEquals = _deprecate(assertEqual) - failIfEqual = assertNotEquals = _deprecate(assertNotEqual) - failUnlessAlmostEqual = assertAlmostEquals = _deprecate(assertAlmostEqual) - failIfAlmostEqual = assertNotAlmostEquals = _deprecate(assertNotAlmostEqual) - failUnless = assert_ = _deprecate(assertTrue) - failUnlessRaises = _deprecate(assertRaises) - failIf = _deprecate(assertFalse) - assertRaisesRegexp = _deprecate(assertRaisesRegex) - assertRegexpMatches = _deprecate(assertRegex) - assertNotRegexpMatches = _deprecate(assertNotRegex) - - class FunctionTestCase(TestCase): """A test case that wraps a test function. diff --git a/Lib/unittest/loader.py b/Lib/unittest/loader.py index 7e6ce2f2..b989284a 100644 --- a/Lib/unittest/loader.py +++ b/Lib/unittest/loader.py @@ -6,7 +6,6 @@ import sys import traceback import types import functools -import warnings from fnmatch import fnmatch, fnmatchcase @@ -57,9 +56,7 @@ def _make_skipped_test(methodname, exception, suiteClass): TestClass = type("ModuleSkipped", (case.TestCase,), attrs) return suiteClass((TestClass(methodname),)) -def _jython_aware_splitext(path): - if path.lower().endswith('$py.class'): - return path[:-9] +def _splitext(path): return os.path.splitext(path)[0] @@ -93,30 +90,8 @@ class TestLoader(object): loaded_suite = self.suiteClass(map(testCaseClass, testCaseNames)) return loaded_suite - # XXX After Python 3.5, remove backward compatibility hacks for - # use_load_tests deprecation via *args and **kws. See issue 16662. - def loadTestsFromModule(self, module, *args, pattern=None, **kws): + def loadTestsFromModule(self, module, *, pattern=None): """Return a suite of all test cases contained in the given module""" - # This method used to take an undocumented and unofficial - # use_load_tests argument. For backward compatibility, we still - # accept the argument (which can also be the first position) but we - # ignore it and issue a deprecation warning if it's present. - if len(args) > 0 or 'use_load_tests' in kws: - warnings.warn('use_load_tests is deprecated and ignored', - DeprecationWarning) - kws.pop('use_load_tests', None) - if len(args) > 1: - # Complain about the number of arguments, but don't forget the - # required `module` argument. - complaint = len(args) + 1 - raise TypeError('loadTestsFromModule() takes 1 positional argument but {} were given'.format(complaint)) - if len(kws) != 0: - # Since the keyword arguments are unsorted (see PEP 468), just - # pick the alphabetically sorted first argument to complain about, - # if multiple were given. At least the error message will be - # predictable. - complaint = sorted(kws)[0] - raise TypeError("loadTestsFromModule() got an unexpected keyword argument '{}'".format(complaint)) tests = [] for name in dir(module): obj = getattr(module, name) @@ -337,7 +312,7 @@ class TestLoader(object): def _get_name_from_path(self, path): if path == self._top_level_dir: return '.' - path = _jython_aware_splitext(os.path.normpath(path)) + path = _splitext(os.path.normpath(path)) _relpath = os.path.relpath(path, self._top_level_dir) assert not os.path.isabs(_relpath), "Path must be within the project" @@ -415,13 +390,13 @@ class TestLoader(object): else: mod_file = os.path.abspath( getattr(module, '__file__', full_path)) - realpath = _jython_aware_splitext( + realpath = _splitext( os.path.realpath(mod_file)) - fullpath_noext = _jython_aware_splitext( + fullpath_noext = _splitext( os.path.realpath(full_path)) if realpath.lower() != fullpath_noext.lower(): module_dir = os.path.dirname(realpath) - mod_name = _jython_aware_splitext( + mod_name = _splitext( os.path.basename(full_path)) expected_dir = os.path.dirname(full_path) msg = ("%r module incorrectly imported from %r. Expected " diff --git a/Lib/unittest/main.py b/Lib/unittest/main.py index 046fbd3a..51b81a6c 100644 --- a/Lib/unittest/main.py +++ b/Lib/unittest/main.py @@ -9,6 +9,7 @@ from . import loader, runner from .signals import installHandler __unittest = True +_NO_TESTS_EXITCODE = 5 MAIN_EXAMPLES = """\ Examples: @@ -66,7 +67,8 @@ class TestProgram(object): def __init__(self, module='__main__', defaultTest=None, argv=None, testRunner=None, testLoader=loader.defaultTestLoader, exit=True, verbosity=1, failfast=None, catchbreak=None, - buffer=None, warnings=None, *, tb_locals=False): + buffer=None, warnings=None, *, tb_locals=False, + durations=None): if isinstance(module, str): self.module = __import__(module) for part in module.split('.')[1:]: @@ -82,6 +84,7 @@ class TestProgram(object): self.verbosity = verbosity self.buffer = buffer self.tb_locals = tb_locals + self.durations = durations if warnings is None and not sys.warnoptions: # even if DeprecationWarnings are ignored by default # print them anyway unless other warnings settings are @@ -178,6 +181,9 @@ class TestProgram(object): parser.add_argument('--locals', dest='tb_locals', action='store_true', help='Show local variables in tracebacks') + parser.add_argument('--durations', dest='durations', type=int, + default=None, metavar="N", + help='Show the N slowest test cases (N=0 for all)') if self.failfast is None: parser.add_argument('-f', '--failfast', dest='failfast', action='store_true', @@ -258,9 +264,10 @@ class TestProgram(object): failfast=self.failfast, buffer=self.buffer, warnings=self.warnings, - tb_locals=self.tb_locals) + tb_locals=self.tb_locals, + durations=self.durations) except TypeError: - # didn't accept the tb_locals argument + # didn't accept the tb_locals or durations argument testRunner = self.testRunner(verbosity=self.verbosity, failfast=self.failfast, buffer=self.buffer, @@ -273,6 +280,12 @@ class TestProgram(object): testRunner = self.testRunner self.result = testRunner.run(self.test) if self.exit: - sys.exit(not self.result.wasSuccessful()) + if self.result.testsRun == 0: + sys.exit(_NO_TESTS_EXITCODE) + elif self.result.wasSuccessful(): + sys.exit(0) + else: + sys.exit(1) + main = TestProgram diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py index fa0bd913..7ca08576 100644 --- a/Lib/unittest/mock.py +++ b/Lib/unittest/mock.py @@ -98,6 +98,12 @@ def _get_signature_object(func, as_instance, eat_self): func = func.__init__ # Skip the `self` argument in __init__ eat_self = True + elif isinstance(func, (classmethod, staticmethod)): + if isinstance(func, classmethod): + # Skip the `cls` argument of a class method + eat_self = True + # Use the original decorated method to extract the correct function signature + func = func.__func__ elif not isinstance(func, FunctionTypes): # If we really want to model an instance of the passed type, # __call__ should be looked up, not __init__. @@ -411,15 +417,18 @@ class NonCallableMock(Base): # necessary. _lock = RLock() - def __new__(cls, /, *args, **kw): + def __new__( + cls, spec=None, wraps=None, name=None, spec_set=None, + parent=None, _spec_state=None, _new_name='', _new_parent=None, + _spec_as_instance=False, _eat_self=None, unsafe=False, **kwargs + ): # every instance has its own class # so we can create magic methods on the # class without stomping on other mocks bases = (cls,) if not issubclass(cls, AsyncMockMixin): # Check if spec is an async object or function - bound_args = _MOCK_SIG.bind_partial(cls, *args, **kw).arguments - spec_arg = bound_args.get('spec_set', bound_args.get('spec')) + spec_arg = spec_set or spec if spec_arg is not None and _is_async_obj(spec_arg): bases = (AsyncMockMixin, cls) new = type(cls.__name__, bases, {'__doc__': cls.__doc__}) @@ -505,10 +514,6 @@ class NonCallableMock(Base): _spec_signature = None _spec_asyncs = [] - for attr in dir(spec): - if iscoroutinefunction(getattr(spec, attr, None)): - _spec_asyncs.append(attr) - if spec is not None and not _is_list(spec): if isinstance(spec, type): _spec_class = spec @@ -518,7 +523,13 @@ class NonCallableMock(Base): _spec_as_instance, _eat_self) _spec_signature = res and res[1] - spec = dir(spec) + spec_list = dir(spec) + + for attr in spec_list: + if iscoroutinefunction(getattr(spec, attr, None)): + _spec_asyncs.append(attr) + + spec = spec_list __dict__ = self.__dict__ __dict__['_spec_class'] = _spec_class @@ -648,7 +659,7 @@ class NonCallableMock(Base): elif _is_magic(name): raise AttributeError(name) if not self._mock_unsafe and (not self._mock_methods or name not in self._mock_methods): - if name.startswith(('assert', 'assret', 'asert', 'aseert', 'assrt')): + if name.startswith(('assert', 'assret', 'asert', 'aseert', 'assrt')) or name in _ATTRIB_DENY_LIST: raise AttributeError( f"{name!r} is not a valid assertion. Use a spec " f"for the mock if {name!r} is meant to be an attribute.") @@ -1057,7 +1068,12 @@ class NonCallableMock(Base): return f"\n{prefix}: {safe_repr(self.mock_calls)}." -_MOCK_SIG = inspect.signature(NonCallableMock.__init__) +# Denylist for forbidden attribute names in safe mode +_ATTRIB_DENY_LIST = frozenset({ + name.removeprefix("assert_") + for name in dir(NonCallableMock) + if name.startswith("assert_") +}) class _AnyComparer(list): @@ -1229,9 +1245,11 @@ class Mock(CallableMixin, NonCallableMock): `return_value` attribute. * `unsafe`: By default, accessing any attribute whose name starts with - *assert*, *assret*, *asert*, *aseert* or *assrt* will raise an - AttributeError. Passing `unsafe=True` will allow access to - these attributes. + *assert*, *assret*, *asert*, *aseert*, or *assrt* raises an AttributeError. + Additionally, an AttributeError is raised when accessing + attributes that match the name of an assertion method without the prefix + `assert_`, e.g. accessing `called_once` instead of `assert_called_once`. + Passing `unsafe=True` will allow access to these attributes. * `wraps`: Item for the mock object to wrap. If `wraps` is not None then calling the Mock will pass the call through to the wrapped object @@ -2138,10 +2156,8 @@ class NonCallableMagicMock(MagicMixin, NonCallableMock): class AsyncMagicMixin(MagicMixin): - def __init__(self, /, *args, **kw): - self._mock_set_magics() # make magic work for kwargs in init - _safe_super(AsyncMagicMixin, self).__init__(*args, **kw) - self._mock_set_magics() # fix magic broken by upper level init + pass + class MagicMock(MagicMixin, Mock): """ @@ -2183,6 +2199,10 @@ class MagicProxy(Base): return self.create_mock() +_CODE_ATTRS = dir(CodeType) +_CODE_SIG = inspect.signature(partial(CodeType.__init__, None)) + + class AsyncMockMixin(Base): await_count = _delegating_property('await_count') await_args = _delegating_property('await_args') @@ -2200,8 +2220,18 @@ class AsyncMockMixin(Base): self.__dict__['_mock_await_count'] = 0 self.__dict__['_mock_await_args'] = None self.__dict__['_mock_await_args_list'] = _CallList() - code_mock = NonCallableMock(spec_set=CodeType) - code_mock.co_flags = inspect.CO_COROUTINE + code_mock = NonCallableMock(spec_set=_CODE_ATTRS) + code_mock.__dict__["_spec_class"] = CodeType + code_mock.__dict__["_spec_signature"] = _CODE_SIG + code_mock.co_flags = ( + inspect.CO_COROUTINE + + inspect.CO_VARARGS + + inspect.CO_VARKEYWORDS + ) + code_mock.co_argcount = 0 + code_mock.co_varnames = ('args', 'kwargs') + code_mock.co_posonlyargcount = 0 + code_mock.co_kwonlyargcount = 0 self.__dict__['__code__'] = code_mock self.__dict__['__name__'] = 'AsyncMock' self.__dict__['__defaults__'] = tuple() @@ -2763,6 +2793,7 @@ def create_autospec(spec, spec_set=False, instance=False, _parent=None, _new_parent=parent, **kwargs) mock._mock_children[entry] = new + new.return_value = child_klass() _check_signature(original, new, skipfirst=skipfirst) # so functions created with _set_signature become instance attributes, diff --git a/Lib/unittest/result.py b/Lib/unittest/result.py index 5ca4c232..3ace0a5b 100644 --- a/Lib/unittest/result.py +++ b/Lib/unittest/result.py @@ -43,6 +43,7 @@ class TestResult(object): self.skipped = [] self.expectedFailures = [] self.unexpectedSuccesses = [] + self.collectedDurations = [] self.shouldStop = False self.buffer = False self.tb_locals = False @@ -157,6 +158,17 @@ class TestResult(object): """Called when a test was expected to fail, but succeed.""" self.unexpectedSuccesses.append(test) + def addDuration(self, test, elapsed): + """Called when a test finished to run, regardless of its outcome. + *test* is the test case corresponding to the test method. + *elapsed* is the time represented in seconds, and it includes the + execution of cleanup functions. + """ + # support for a TextTestRunner using an old TestResult class + if hasattr(self, "collectedDurations"): + # Pass test repr and not the test object itself to avoid resources leak + self.collectedDurations.append((str(test), elapsed)) + def wasSuccessful(self): """Tells whether or not this result was a success.""" # The hasattr check is for test_result's OldResult test. That diff --git a/Lib/unittest/runner.py b/Lib/unittest/runner.py index cb452c7a..e3c020e0 100644 --- a/Lib/unittest/runner.py +++ b/Lib/unittest/runner.py @@ -35,13 +35,16 @@ class TextTestResult(result.TestResult): separator1 = '=' * 70 separator2 = '-' * 70 - def __init__(self, stream, descriptions, verbosity): + def __init__(self, stream, descriptions, verbosity, *, durations=None): + """Construct a TextTestResult. Subclasses should accept **kwargs + to ensure compatibility as the interface changes.""" super(TextTestResult, self).__init__(stream, descriptions, verbosity) self.stream = stream self.showAll = verbosity > 1 self.dots = verbosity == 1 self.descriptions = descriptions self._newline = True + self.durations = durations def getDescription(self, test): doc_first_line = test.shortDescription() @@ -168,7 +171,7 @@ class TextTestRunner(object): def __init__(self, stream=None, descriptions=True, verbosity=1, failfast=False, buffer=False, resultclass=None, warnings=None, - *, tb_locals=False): + *, tb_locals=False, durations=None): """Construct a TextTestRunner. Subclasses should accept **kwargs to ensure compatibility as the @@ -182,12 +185,41 @@ class TextTestRunner(object): self.failfast = failfast self.buffer = buffer self.tb_locals = tb_locals + self.durations = durations self.warnings = warnings if resultclass is not None: self.resultclass = resultclass def _makeResult(self): - return self.resultclass(self.stream, self.descriptions, self.verbosity) + try: + return self.resultclass(self.stream, self.descriptions, + self.verbosity, durations=self.durations) + except TypeError: + # didn't accept the durations argument + return self.resultclass(self.stream, self.descriptions, + self.verbosity) + + def _printDurations(self, result): + if not result.collectedDurations: + return + ls = sorted(result.collectedDurations, key=lambda x: x[1], + reverse=True) + if self.durations > 0: + ls = ls[:self.durations] + self.stream.writeln("Slowest test durations") + if hasattr(result, 'separator2'): + self.stream.writeln(result.separator2) + hidden = False + for test, elapsed in ls: + if self.verbosity < 2 and elapsed < 0.001: + hidden = True + continue + self.stream.writeln("%-10s %s" % ("%.3fs" % elapsed, test)) + if hidden: + self.stream.writeln("\n(durations < 0.001s were hidden; " + "use -v to show these durations)") + else: + self.stream.writeln("") def run(self, test): "Run the given test case or test suite." @@ -200,15 +232,6 @@ class TextTestRunner(object): if self.warnings: # if self.warnings is set, use it to filter all the warnings warnings.simplefilter(self.warnings) - # if the filter is 'default' or 'always', special-case the - # warnings from the deprecated unittest methods to show them - # no more than once per module, because they can be fairly - # noisy. The -Wd and -Wa flags can be used to bypass this - # only when self.warnings is None. - if self.warnings in ['default', 'always']: - warnings.filterwarnings('module', - category=DeprecationWarning, - message=r'Please use assert\w+ instead.') startTime = time.perf_counter() startTestRun = getattr(result, 'startTestRun', None) if startTestRun is not None: @@ -222,8 +245,12 @@ class TextTestRunner(object): stopTime = time.perf_counter() timeTaken = stopTime - startTime result.printErrors() + if self.durations is not None: + self._printDurations(result) + if hasattr(result, 'separator2'): self.stream.writeln(result.separator2) + run = result.testsRun self.stream.writeln("Ran %d test%s in %.3fs" % (run, run != 1 and "s" or "", timeTaken)) @@ -247,6 +274,8 @@ class TextTestRunner(object): infos.append("failures=%d" % failed) if errored: infos.append("errors=%d" % errored) + elif run == 0: + self.stream.write("NO TESTS RAN") else: self.stream.write("OK") if skipped: diff --git a/Lib/unittest/test/__init__.py b/Lib/unittest/test/__init__.py deleted file mode 100644 index 143f4ab5..00000000 --- a/Lib/unittest/test/__init__.py +++ /dev/null @@ -1,25 +0,0 @@ -import os -import sys -import unittest - - -here = os.path.dirname(__file__) -loader = unittest.defaultTestLoader - -def suite(): - suite = unittest.TestSuite() - for fn in os.listdir(here): - if fn.startswith("test") and fn.endswith(".py"): - modname = "unittest.test." + fn[:-3] - try: - __import__(modname) - except unittest.SkipTest: - continue - module = sys.modules[modname] - suite.addTest(loader.loadTestsFromModule(module)) - suite.addTest(loader.loadTestsFromName('unittest.test.testmock')) - return suite - - -if __name__ == "__main__": - unittest.main(defaultTest="suite") diff --git a/Lib/unittest/test/__main__.py b/Lib/unittest/test/__main__.py deleted file mode 100644 index 44d0591e..00000000 --- a/Lib/unittest/test/__main__.py +++ /dev/null @@ -1,18 +0,0 @@ -import os -import unittest - - -def load_tests(loader, standard_tests, pattern): - # top level directory cached on loader instance - this_dir = os.path.dirname(__file__) - pattern = pattern or "test_*.py" - # We are inside unittest.test, so the top-level is two notches up - top_level_dir = os.path.dirname(os.path.dirname(this_dir)) - package_tests = loader.discover(start_dir=this_dir, pattern=pattern, - top_level_dir=top_level_dir) - standard_tests.addTests(package_tests) - return standard_tests - - -if __name__ == '__main__': - unittest.main() diff --git a/Lib/unittest/test/testmock/__init__.py b/Lib/unittest/test/testmock/__init__.py deleted file mode 100644 index 87d7ae99..00000000 --- a/Lib/unittest/test/testmock/__init__.py +++ /dev/null @@ -1,17 +0,0 @@ -import os -import sys -import unittest - - -here = os.path.dirname(__file__) -loader = unittest.defaultTestLoader - -def load_tests(*args): - suite = unittest.TestSuite() - for fn in os.listdir(here): - if fn.startswith("test") and fn.endswith(".py"): - modname = "unittest.test.testmock." + fn[:-3] - __import__(modname) - module = sys.modules[modname] - suite.addTest(loader.loadTestsFromModule(module)) - return suite diff --git a/Lib/urllib/error.py b/Lib/urllib/error.py index feec0e7f..a9cd1eca 100644 --- a/Lib/urllib/error.py +++ b/Lib/urllib/error.py @@ -43,7 +43,7 @@ class HTTPError(URLError, urllib.response.addinfourl): self.fp = fp self.filename = url if fp is None: - fp = io.StringIO() + fp = io.BytesIO() self.__super_init(fp, hdrs, url, code) def __str__(self): diff --git a/Lib/urllib/parse.py b/Lib/urllib/parse.py index 69631cbb..c129b0d7 100644 --- a/Lib/urllib/parse.py +++ b/Lib/urllib/parse.py @@ -25,14 +25,19 @@ currently not entirely compliant with this RFC due to defacto scenarios for parsing, and for backward compatibility purposes, some parsing quirks from older RFCs are retained. The testcases in test_urlparse.py provides a good indicator of parsing behavior. + +The WHATWG URL Parser spec should also be considered. We are not compliant with +it either due to existing user code API behavior expectations (Hyrum's Law). +It serves as a useful guide when making changes. """ from collections import namedtuple import functools +import math import re -import sys import types import warnings +import ipaddress __all__ = ["urlparse", "urlunparse", "urljoin", "urldefrag", "urlsplit", "urlunsplit", "urlencode", "parse_qs", @@ -47,18 +52,18 @@ __all__ = ["urlparse", "urlunparse", "urljoin", "urldefrag", uses_relative = ['', 'ftp', 'http', 'gopher', 'nntp', 'imap', 'wais', 'file', 'https', 'shttp', 'mms', - 'prospero', 'rtsp', 'rtspu', 'sftp', + 'prospero', 'rtsp', 'rtsps', 'rtspu', 'sftp', 'svn', 'svn+ssh', 'ws', 'wss'] uses_netloc = ['', 'ftp', 'http', 'gopher', 'nntp', 'telnet', 'imap', 'wais', 'file', 'mms', 'https', 'shttp', - 'snews', 'prospero', 'rtsp', 'rtspu', 'rsync', + 'snews', 'prospero', 'rtsp', 'rtsps', 'rtspu', 'rsync', 'svn', 'svn+ssh', 'sftp', 'nfs', 'git', 'git+ssh', - 'ws', 'wss'] + 'ws', 'wss', 'itms-services'] uses_params = ['', 'ftp', 'hdl', 'prospero', 'http', 'imap', - 'https', 'shttp', 'rtsp', 'rtspu', 'sip', 'sips', - 'mms', 'sftp', 'tel'] + 'https', 'shttp', 'rtsp', 'rtsps', 'rtspu', 'sip', + 'sips', 'mms', 'sftp', 'tel'] # These are not actually used anymore, but should stay for backwards # compatibility. (They are undocumented, but have a public-looking name.) @@ -67,7 +72,7 @@ non_hierarchical = ['gopher', 'hdl', 'mailto', 'news', 'telnet', 'wais', 'imap', 'snews', 'sip', 'sips'] uses_query = ['', 'http', 'wais', 'imap', 'https', 'shttp', 'mms', - 'gopher', 'rtsp', 'rtspu', 'sip', 'sips'] + 'gopher', 'rtsp', 'rtsps', 'rtspu', 'sip', 'sips'] uses_fragment = ['', 'ftp', 'hdl', 'http', 'gopher', 'news', 'nntp', 'wais', 'https', 'shttp', 'snews', @@ -79,6 +84,10 @@ scheme_chars = ('abcdefghijklmnopqrstuvwxyz' '0123456789' '+-.') +# Leading and trailing C0 control and space to be stripped per WHATWG spec. +# == "".join([chr(i) for i in range(0, 0x20 + 1)]) +_WHATWG_C0_CONTROL_OR_SPACE = '\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f ' + # Unsafe bytes to be removed per WHATWG spec _UNSAFE_URL_BYTES_TO_REMOVE = ['\t', '\r', '\n'] @@ -427,6 +436,17 @@ def _checknetloc(netloc): raise ValueError("netloc '" + netloc + "' contains invalid " + "characters under NFKC normalization") +# Valid bracketed hosts are defined in +# https://www.rfc-editor.org/rfc/rfc3986#page-49 and https://url.spec.whatwg.org/ +def _check_bracketed_host(hostname): + if hostname.startswith('v'): + if not re.match(r"\Av[a-fA-F0-9]+\..+\Z", hostname): + raise ValueError(f"IPvFuture address is invalid") + else: + ip = ipaddress.ip_address(hostname) # Throws Value Error if not IPv6 or IPv4 + if isinstance(ip, ipaddress.IPv4Address): + raise ValueError(f"An IPv4 address cannot be in brackets") + # typed=True avoids BytesWarnings being emitted during cache key # comparison since this API supports both bytes and str input. @functools.lru_cache(typed=True) @@ -452,6 +472,10 @@ def urlsplit(url, scheme='', allow_fragments=True): """ url, scheme, _coerce_result = _coerce_args(url, scheme) + # Only lstrip url as some applications rely on preserving trailing space. + # (https://url.spec.whatwg.org/#concept-basic-url-parser would strip both) + url = url.lstrip(_WHATWG_C0_CONTROL_OR_SPACE) + scheme = scheme.strip(_WHATWG_C0_CONTROL_OR_SPACE) for b in _UNSAFE_URL_BYTES_TO_REMOVE: url = url.replace(b, "") @@ -466,12 +490,14 @@ def urlsplit(url, scheme='', allow_fragments=True): break else: scheme, url = url[:i].lower(), url[i+1:] - if url[:2] == '//': netloc, url = _splitnetloc(url, 2) if (('[' in netloc and ']' not in netloc) or (']' in netloc and '[' not in netloc)): raise ValueError("Invalid IPv6 URL") + if '[' in netloc and ']' in netloc: + bracketed_host = netloc.partition('[')[2].partition(']')[0] + _check_bracketed_host(bracketed_host) if allow_fragments and '#' in url: url, fragment = url.split('#', 1) if '?' in url: @@ -600,6 +626,9 @@ _hextobyte = None def unquote_to_bytes(string): """unquote_to_bytes('abc%20def') -> b'abc def'.""" + return bytes(_unquote_impl(string)) + +def _unquote_impl(string: bytes | bytearray | str) -> bytes | bytearray: # Note: strings are encoded as UTF-8. This is only an issue if it contains # unescaped non-ASCII characters, which URIs should not. if not string: @@ -611,8 +640,8 @@ def unquote_to_bytes(string): bits = string.split(b'%') if len(bits) == 1: return string - res = [bits[0]] - append = res.append + res = bytearray(bits[0]) + append = res.extend # Delay the initialization of the table to not waste memory # if the function is never called global _hextobyte @@ -626,10 +655,20 @@ def unquote_to_bytes(string): except KeyError: append(b'%') append(item) - return b''.join(res) + return res _asciire = re.compile('([\x00-\x7f]+)') +def _generate_unquoted_parts(string, encoding, errors): + previous_match_end = 0 + for ascii_match in _asciire.finditer(string): + start, end = ascii_match.span() + yield string[previous_match_end:start] # Non-ASCII + # The ascii_match[1] group == string[start:end]. + yield _unquote_impl(ascii_match[1]).decode(encoding, errors) + previous_match_end = end + yield string[previous_match_end:] # Non-ASCII tail + def unquote(string, encoding='utf-8', errors='replace'): """Replace %xx escapes by their single-character equivalent. The optional encoding and errors parameters specify how to decode percent-encoded @@ -641,21 +680,16 @@ def unquote(string, encoding='utf-8', errors='replace'): unquote('abc%20def') -> 'abc def'. """ if isinstance(string, bytes): - return unquote_to_bytes(string).decode(encoding, errors) + return _unquote_impl(string).decode(encoding, errors) if '%' not in string: + # Is it a string-like object? string.split return string if encoding is None: encoding = 'utf-8' if errors is None: errors = 'replace' - bits = _asciire.split(string) - res = [bits[0]] - append = res.append - for i in range(1, len(bits), 2): - append(unquote_to_bytes(bits[i]).decode(encoding, errors)) - append(bits[i + 1]) - return ''.join(res) + return ''.join(_generate_unquoted_parts(string, encoding, errors)) def parse_qs(qs, keep_blank_values=False, strict_parsing=False, @@ -906,7 +940,14 @@ def quote_from_bytes(bs, safe='/'): if not bs.rstrip(_ALWAYS_SAFE_BYTES + safe): return bs.decode() quoter = _byte_quoter_factory(safe) - return ''.join([quoter(char) for char in bs]) + if (bs_len := len(bs)) < 200_000: + return ''.join(map(quoter, bs)) + else: + # This saves memory - https://github.com/python/cpython/issues/95865 + chunk_size = math.isqrt(bs_len) + chunks = [''.join(map(quoter, bs[i:i+chunk_size])) + for i in range(0, bs_len, chunk_size)] + return ''.join(chunks) def urlencode(query, doseq=False, safe='', encoding=None, errors=None, quote_via=quote_plus): diff --git a/Lib/urllib/request.py b/Lib/urllib/request.py index 73ad0127..5314b3f2 100644 --- a/Lib/urllib/request.py +++ b/Lib/urllib/request.py @@ -88,7 +88,6 @@ import hashlib import http.client import io import os -import posixpath import re import socket import string @@ -266,10 +265,7 @@ def urlretrieve(url, filename=None, reporthook=None, data=None): if reporthook: reporthook(blocknum, bs, size) - while True: - block = fp.read(bs) - if not block: - break + while block := fp.read(bs): read += len(block) tfp.write(block) blocknum += 1 @@ -1255,8 +1251,8 @@ class ProxyDigestAuthHandler(BaseHandler, AbstractDigestAuthHandler): class AbstractHTTPHandler(BaseHandler): - def __init__(self, debuglevel=0): - self._debuglevel = debuglevel + def __init__(self, debuglevel=None): + self._debuglevel = debuglevel if debuglevel is not None else http.client.HTTPConnection.debuglevel def set_http_debuglevel(self, level): self._debuglevel = level @@ -1382,14 +1378,19 @@ if hasattr(http.client, 'HTTPSConnection'): class HTTPSHandler(AbstractHTTPHandler): - def __init__(self, debuglevel=0, context=None, check_hostname=None): + def __init__(self, debuglevel=None, context=None, check_hostname=None): + debuglevel = debuglevel if debuglevel is not None else http.client.HTTPSConnection.debuglevel AbstractHTTPHandler.__init__(self, debuglevel) + if context is None: + http_version = http.client.HTTPSConnection._http_vsn + context = http.client._create_https_context(http_version) + if check_hostname is not None: + context.check_hostname = check_hostname self._context = context - self._check_hostname = check_hostname def https_open(self, req): return self.do_open(http.client.HTTPSConnection, req, - context=self._context, check_hostname=self._check_hostname) + context=self._context) https_request = AbstractHTTPHandler.do_request_ @@ -1844,10 +1845,7 @@ class URLopener: size = int(headers["Content-Length"]) if reporthook: reporthook(blocknum, bs, size) - while 1: - block = fp.read(bs) - if not block: - break + while block := fp.read(bs): read += len(block) tfp.write(block) blocknum += 1 @@ -1987,9 +1985,17 @@ class URLopener: if _have_ssl: def _https_connection(self, host): - return http.client.HTTPSConnection(host, - key_file=self.key_file, - cert_file=self.cert_file) + if self.key_file or self.cert_file: + http_version = http.client.HTTPSConnection._http_vsn + context = http.client._create_https_context(http_version) + context.load_cert_chain(self.cert_file, self.key_file) + # cert and key file means the user wants to authenticate. + # enable TLS 1.3 PHA implicitly even for custom contexts. + if context.post_handshake_auth is not None: + context.post_handshake_auth = True + else: + context = None + return http.client.HTTPSConnection(host, context=context) def open_https(self, url, data=None): """Use HTTPS protocol.""" @@ -2469,7 +2475,13 @@ class ftpwrapper: return (ftpobj, retrlen) def endtransfer(self): + if not self.busy: + return self.busy = 0 + try: + self.ftp.voidresp() + except ftperrors(): + pass def close(self): self.keepalive = False @@ -2497,28 +2509,34 @@ def getproxies_environment(): this seems to be the standard convention. If you need a different way, you can pass a proxies dictionary to the [Fancy]URLopener constructor. - """ - proxies = {} # in order to prefer lowercase variables, process environment in # two passes: first matches any, second pass matches lowercase only - for name, value in os.environ.items(): - name = name.lower() - if value and name[-6:] == '_proxy': - proxies[name[:-6]] = value + + # select only environment variables which end in (after making lowercase) _proxy + proxies = {} + environment = [] + for name in os.environ.keys(): + # fast screen underscore position before more expensive case-folding + if len(name) > 5 and name[-6] == "_" and name[-5:].lower() == "proxy": + value = os.environ[name] + proxy_name = name[:-6].lower() + environment.append((name, value, proxy_name)) + if value: + proxies[proxy_name] = value # CVE-2016-1000110 - If we are running as CGI script, forget HTTP_PROXY # (non-all-lowercase) as it may be set from the web server by a "Proxy:" # header from the client # If "proxy" is lowercase, it will still be used thanks to the next block if 'REQUEST_METHOD' in os.environ: proxies.pop('http', None) - for name, value in os.environ.items(): + for name, value, proxy_name in environment: + # not case-folded, checking here for lower-case env vars only if name[-6:] == '_proxy': - name = name.lower() if value: - proxies[name[:-6]] = value + proxies[proxy_name] = value else: - proxies.pop(name[:-6], None) + proxies.pop(proxy_name, None) return proxies def proxy_bypass_environment(host, proxies=None): diff --git a/Lib/uu.py b/Lib/uu.py old mode 100755 new mode 100644 index 6f8805d8..26bb59ae --- a/Lib/uu.py +++ b/Lib/uu.py @@ -133,7 +133,14 @@ def decode(in_file, out_file=None, mode=None, quiet=False): # If the filename isn't ASCII, what's up with that?!? out_file = hdrfields[2].rstrip(b' \t\r\n\f').decode("ascii") if os.path.exists(out_file): - raise Error('Cannot overwrite existing file: %s' % out_file) + raise Error(f'Cannot overwrite existing file: {out_file}') + if (out_file.startswith(os.sep) or + f'..{os.sep}' in out_file or ( + os.altsep and + (out_file.startswith(os.altsep) or + f'..{os.altsep}' in out_file)) + ): + raise Error(f'Refusing to write to {out_file} due to directory traversal') if mode is None: mode = int(hdrfields[1], 8) # diff --git a/Lib/uuid.py b/Lib/uuid.py index e863b631..470bc0d6 100644 --- a/Lib/uuid.py +++ b/Lib/uuid.py @@ -53,7 +53,7 @@ from enum import Enum, _simple_enum __author__ = 'Ka-Ping Yee <ping@zesty.ca>' # The recognized platforms - known behaviors -if sys.platform in ('win32', 'darwin'): +if sys.platform in ('win32', 'darwin', 'emscripten', 'wasi'): _AIX = _LINUX = False else: import platform @@ -401,7 +401,7 @@ def _get_command_stdout(command, *args): # over locally administered ones since the former are globally unique, but # we'll return the first of the latter found if that's all the machine has. # -# See https://en.wikipedia.org/wiki/MAC_address#Universal_vs._local +# See https://en.wikipedia.org/wiki/MAC_address#Universal_vs._local_(U/L_bit) def _is_universal(mac): return not (mac & (1 << 41)) @@ -615,7 +615,7 @@ def _random_getnode(): # significant bit of the first octet". This works out to be the 41st bit # counting from 1 being the least significant bit, or 1<<40. # - # See https://en.wikipedia.org/wiki/MAC_address#Unicast_vs._multicast + # See https://en.wikipedia.org/w/index.php?title=MAC_address&oldid=1128764812#Universal_vs._local_(U/L_bit) import random return random.getrandbits(48) | (1 << 40) @@ -711,9 +711,11 @@ def uuid1(node=None, clock_seq=None): def uuid3(namespace, name): """Generate a UUID from the MD5 hash of a namespace UUID and a name.""" + if isinstance(name, str): + name = bytes(name, "utf-8") from hashlib import md5 digest = md5( - namespace.bytes + bytes(name, "utf-8"), + namespace.bytes + name, usedforsecurity=False ).digest() return UUID(bytes=digest[:16], version=3) @@ -724,13 +726,68 @@ def uuid4(): def uuid5(namespace, name): """Generate a UUID from the SHA-1 hash of a namespace UUID and a name.""" + if isinstance(name, str): + name = bytes(name, "utf-8") from hashlib import sha1 - hash = sha1(namespace.bytes + bytes(name, "utf-8")).digest() + hash = sha1(namespace.bytes + name).digest() return UUID(bytes=hash[:16], version=5) + +def main(): + """Run the uuid command line interface.""" + uuid_funcs = { + "uuid1": uuid1, + "uuid3": uuid3, + "uuid4": uuid4, + "uuid5": uuid5 + } + uuid_namespace_funcs = ("uuid3", "uuid5") + namespaces = { + "@dns": NAMESPACE_DNS, + "@url": NAMESPACE_URL, + "@oid": NAMESPACE_OID, + "@x500": NAMESPACE_X500 + } + + import argparse + parser = argparse.ArgumentParser( + description="Generates a uuid using the selected uuid function.") + parser.add_argument("-u", "--uuid", choices=uuid_funcs.keys(), default="uuid4", + help="The function to use to generate the uuid. " + "By default uuid4 function is used.") + parser.add_argument("-n", "--namespace", + help="The namespace is a UUID, or '@ns' where 'ns' is a " + "well-known predefined UUID addressed by namespace name. " + "Such as @dns, @url, @oid, and @x500. " + "Only required for uuid3/uuid5 functions.") + parser.add_argument("-N", "--name", + help="The name used as part of generating the uuid. " + "Only required for uuid3/uuid5 functions.") + + args = parser.parse_args() + uuid_func = uuid_funcs[args.uuid] + namespace = args.namespace + name = args.name + + if args.uuid in uuid_namespace_funcs: + if not namespace or not name: + parser.error( + "Incorrect number of arguments. " + f"{args.uuid} requires a namespace and a name. " + "Run 'python -m uuid -h' for more information." + ) + namespace = namespaces[namespace] if namespace in namespaces else UUID(namespace) + print(uuid_func(namespace, name)) + else: + print(uuid_func()) + + # The following standard UUIDs are for use with uuid3() or uuid5(). NAMESPACE_DNS = UUID('6ba7b810-9dad-11d1-80b4-00c04fd430c8') NAMESPACE_URL = UUID('6ba7b811-9dad-11d1-80b4-00c04fd430c8') NAMESPACE_OID = UUID('6ba7b812-9dad-11d1-80b4-00c04fd430c8') NAMESPACE_X500 = UUID('6ba7b814-9dad-11d1-80b4-00c04fd430c8') + +if __name__ == "__main__": + main() diff --git a/Lib/venv/__init__.py b/Lib/venv/__init__.py index 6bce3081..2173c9b1 100644 --- a/Lib/venv/__init__.py +++ b/Lib/venv/__init__.py @@ -13,7 +13,7 @@ import sysconfig import types -CORE_VENV_DEPS = ('pip', 'setuptools') +CORE_VENV_DEPS = ('pip',) logger = logging.getLogger(__name__) @@ -143,6 +143,7 @@ class EnvBuilder: context.inc_path = incpath create_if_needed(incpath) + context.lib_path = libpath create_if_needed(libpath) # Issue 21197: create lib64 as a symlink to lib on 64-bit non-OS X POSIX if ((sys.maxsize > 2**32) and (os.name == 'posix') and @@ -222,7 +223,7 @@ class EnvBuilder: force_copy = not self.symlinks if not force_copy: try: - if not os.path.islink(dst): # can't link to itself! + if not os.path.islink(dst): # can't link to itself! if relative_symlinks_ok: assert os.path.dirname(src) == os.path.dirname(dst) os.symlink(os.path.basename(src), dst) @@ -417,11 +418,11 @@ class EnvBuilder: binpath = context.bin_path plen = len(path) for root, dirs, files in os.walk(path): - if root == path: # at top-level, remove irrelevant dirs + if root == path: # at top-level, remove irrelevant dirs for d in dirs[:]: if d not in ('common', os.name): dirs.remove(d) - continue # ignore files in top level + continue # ignore files in top level for f in files: if (os.name == 'nt' and f.startswith('python') and f.endswith(('.exe', '.pdb'))): @@ -467,83 +468,76 @@ def create(env_dir, system_site_packages=False, clear=False, prompt=prompt, upgrade_deps=upgrade_deps) builder.create(env_dir) + def main(args=None): - compatible = True - if sys.version_info < (3, 3): - compatible = False - elif not hasattr(sys, 'base_prefix'): - compatible = False - if not compatible: - raise ValueError('This script is only for use with Python >= 3.3') + import argparse + + parser = argparse.ArgumentParser(prog=__name__, + description='Creates virtual Python ' + 'environments in one or ' + 'more target ' + 'directories.', + epilog='Once an environment has been ' + 'created, you may wish to ' + 'activate it, e.g. by ' + 'sourcing an activate script ' + 'in its bin directory.') + parser.add_argument('dirs', metavar='ENV_DIR', nargs='+', + help='A directory to create the environment in.') + parser.add_argument('--system-site-packages', default=False, + action='store_true', dest='system_site', + help='Give the virtual environment access to the ' + 'system site-packages dir.') + if os.name == 'nt': + use_symlinks = False else: - import argparse - - parser = argparse.ArgumentParser(prog=__name__, - description='Creates virtual Python ' - 'environments in one or ' - 'more target ' - 'directories.', - epilog='Once an environment has been ' - 'created, you may wish to ' - 'activate it, e.g. by ' - 'sourcing an activate script ' - 'in its bin directory.') - parser.add_argument('dirs', metavar='ENV_DIR', nargs='+', - help='A directory to create the environment in.') - parser.add_argument('--system-site-packages', default=False, - action='store_true', dest='system_site', - help='Give the virtual environment access to the ' - 'system site-packages dir.') - if os.name == 'nt': - use_symlinks = False - else: - use_symlinks = True - group = parser.add_mutually_exclusive_group() - group.add_argument('--symlinks', default=use_symlinks, - action='store_true', dest='symlinks', - help='Try to use symlinks rather than copies, ' - 'when symlinks are not the default for ' - 'the platform.') - group.add_argument('--copies', default=not use_symlinks, - action='store_false', dest='symlinks', - help='Try to use copies rather than symlinks, ' - 'even when symlinks are the default for ' - 'the platform.') - parser.add_argument('--clear', default=False, action='store_true', - dest='clear', help='Delete the contents of the ' - 'environment directory if it ' - 'already exists, before ' - 'environment creation.') - parser.add_argument('--upgrade', default=False, action='store_true', - dest='upgrade', help='Upgrade the environment ' - 'directory to use this version ' - 'of Python, assuming Python ' - 'has been upgraded in-place.') - parser.add_argument('--without-pip', dest='with_pip', - default=True, action='store_false', - help='Skips installing or upgrading pip in the ' - 'virtual environment (pip is bootstrapped ' - 'by default)') - parser.add_argument('--prompt', - help='Provides an alternative prompt prefix for ' - 'this environment.') - parser.add_argument('--upgrade-deps', default=False, action='store_true', - dest='upgrade_deps', - help='Upgrade core dependencies: {} to the latest ' - 'version in PyPI'.format( - ' '.join(CORE_VENV_DEPS))) - options = parser.parse_args(args) - if options.upgrade and options.clear: - raise ValueError('you cannot supply --upgrade and --clear together.') - builder = EnvBuilder(system_site_packages=options.system_site, - clear=options.clear, - symlinks=options.symlinks, - upgrade=options.upgrade, - with_pip=options.with_pip, - prompt=options.prompt, - upgrade_deps=options.upgrade_deps) - for d in options.dirs: - builder.create(d) + use_symlinks = True + group = parser.add_mutually_exclusive_group() + group.add_argument('--symlinks', default=use_symlinks, + action='store_true', dest='symlinks', + help='Try to use symlinks rather than copies, ' + 'when symlinks are not the default for ' + 'the platform.') + group.add_argument('--copies', default=not use_symlinks, + action='store_false', dest='symlinks', + help='Try to use copies rather than symlinks, ' + 'even when symlinks are the default for ' + 'the platform.') + parser.add_argument('--clear', default=False, action='store_true', + dest='clear', help='Delete the contents of the ' + 'environment directory if it ' + 'already exists, before ' + 'environment creation.') + parser.add_argument('--upgrade', default=False, action='store_true', + dest='upgrade', help='Upgrade the environment ' + 'directory to use this version ' + 'of Python, assuming Python ' + 'has been upgraded in-place.') + parser.add_argument('--without-pip', dest='with_pip', + default=True, action='store_false', + help='Skips installing or upgrading pip in the ' + 'virtual environment (pip is bootstrapped ' + 'by default)') + parser.add_argument('--prompt', + help='Provides an alternative prompt prefix for ' + 'this environment.') + parser.add_argument('--upgrade-deps', default=False, action='store_true', + dest='upgrade_deps', + help=f'Upgrade core dependencies ({", ".join(CORE_VENV_DEPS)}) ' + 'to the latest version in PyPI') + options = parser.parse_args(args) + if options.upgrade and options.clear: + raise ValueError('you cannot supply --upgrade and --clear together.') + builder = EnvBuilder(system_site_packages=options.system_site, + clear=options.clear, + symlinks=options.symlinks, + upgrade=options.upgrade, + with_pip=options.with_pip, + prompt=options.prompt, + upgrade_deps=options.upgrade_deps) + for d in options.dirs: + builder.create(d) + if __name__ == '__main__': rc = 1 diff --git a/Lib/venv/scripts/common/Activate.ps1 b/Lib/venv/scripts/common/Activate.ps1 index b49d77ba..eeea3583 100644 --- a/Lib/venv/scripts/common/Activate.ps1 +++ b/Lib/venv/scripts/common/Activate.ps1 @@ -1,247 +1,247 @@ -<# -.Synopsis -Activate a Python virtual environment for the current PowerShell session. - -.Description -Pushes the python executable for a virtual environment to the front of the -$Env:PATH environment variable and sets the prompt to signify that you are -in a Python virtual environment. Makes use of the command line switches as -well as the `pyvenv.cfg` file values present in the virtual environment. - -.Parameter VenvDir -Path to the directory that contains the virtual environment to activate. The -default value for this is the parent of the directory that the Activate.ps1 -script is located within. - -.Parameter Prompt -The prompt prefix to display when this virtual environment is activated. By -default, this prompt is the name of the virtual environment folder (VenvDir) -surrounded by parentheses and followed by a single space (ie. '(.venv) '). - -.Example -Activate.ps1 -Activates the Python virtual environment that contains the Activate.ps1 script. - -.Example -Activate.ps1 -Verbose -Activates the Python virtual environment that contains the Activate.ps1 script, -and shows extra information about the activation as it executes. - -.Example -Activate.ps1 -VenvDir C:\Users\MyUser\Common\.venv -Activates the Python virtual environment located in the specified location. - -.Example -Activate.ps1 -Prompt "MyPython" -Activates the Python virtual environment that contains the Activate.ps1 script, -and prefixes the current prompt with the specified string (surrounded in -parentheses) while the virtual environment is active. - -.Notes -On Windows, it may be required to enable this Activate.ps1 script by setting the -execution policy for the user. You can do this by issuing the following PowerShell -command: - -PS C:\> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser - -For more information on Execution Policies: -https://go.microsoft.com/fwlink/?LinkID=135170 - -#> -Param( - [Parameter(Mandatory = $false)] - [String] - $VenvDir, - [Parameter(Mandatory = $false)] - [String] - $Prompt -) - -<# Function declarations --------------------------------------------------- #> - -<# -.Synopsis -Remove all shell session elements added by the Activate script, including the -addition of the virtual environment's Python executable from the beginning of -the PATH variable. - -.Parameter NonDestructive -If present, do not remove this function from the global namespace for the -session. - -#> -function global:deactivate ([switch]$NonDestructive) { - # Revert to original values - - # The prior prompt: - if (Test-Path -Path Function:_OLD_VIRTUAL_PROMPT) { - Copy-Item -Path Function:_OLD_VIRTUAL_PROMPT -Destination Function:prompt - Remove-Item -Path Function:_OLD_VIRTUAL_PROMPT - } - - # The prior PYTHONHOME: - if (Test-Path -Path Env:_OLD_VIRTUAL_PYTHONHOME) { - Copy-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME -Destination Env:PYTHONHOME - Remove-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME - } - - # The prior PATH: - if (Test-Path -Path Env:_OLD_VIRTUAL_PATH) { - Copy-Item -Path Env:_OLD_VIRTUAL_PATH -Destination Env:PATH - Remove-Item -Path Env:_OLD_VIRTUAL_PATH - } - - # Just remove the VIRTUAL_ENV altogether: - if (Test-Path -Path Env:VIRTUAL_ENV) { - Remove-Item -Path env:VIRTUAL_ENV - } - - # Just remove VIRTUAL_ENV_PROMPT altogether. - if (Test-Path -Path Env:VIRTUAL_ENV_PROMPT) { - Remove-Item -Path env:VIRTUAL_ENV_PROMPT - } - - # Just remove the _PYTHON_VENV_PROMPT_PREFIX altogether: - if (Get-Variable -Name "_PYTHON_VENV_PROMPT_PREFIX" -ErrorAction SilentlyContinue) { - Remove-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Scope Global -Force - } - - # Leave deactivate function in the global namespace if requested: - if (-not $NonDestructive) { - Remove-Item -Path function:deactivate - } -} - -<# -.Description -Get-PyVenvConfig parses the values from the pyvenv.cfg file located in the -given folder, and returns them in a map. - -For each line in the pyvenv.cfg file, if that line can be parsed into exactly -two strings separated by `=` (with any amount of whitespace surrounding the =) -then it is considered a `key = value` line. The left hand string is the key, -the right hand is the value. - -If the value starts with a `'` or a `"` then the first and last character is -stripped from the value before being captured. - -.Parameter ConfigDir -Path to the directory that contains the `pyvenv.cfg` file. -#> -function Get-PyVenvConfig( - [String] - $ConfigDir -) { - Write-Verbose "Given ConfigDir=$ConfigDir, obtain values in pyvenv.cfg" - - # Ensure the file exists, and issue a warning if it doesn't (but still allow the function to continue). - $pyvenvConfigPath = Join-Path -Resolve -Path $ConfigDir -ChildPath 'pyvenv.cfg' -ErrorAction Continue - - # An empty map will be returned if no config file is found. - $pyvenvConfig = @{ } - - if ($pyvenvConfigPath) { - - Write-Verbose "File exists, parse `key = value` lines" - $pyvenvConfigContent = Get-Content -Path $pyvenvConfigPath - - $pyvenvConfigContent | ForEach-Object { - $keyval = $PSItem -split "\s*=\s*", 2 - if ($keyval[0] -and $keyval[1]) { - $val = $keyval[1] - - # Remove extraneous quotations around a string value. - if ("'""".Contains($val.Substring(0, 1))) { - $val = $val.Substring(1, $val.Length - 2) - } - - $pyvenvConfig[$keyval[0]] = $val - Write-Verbose "Adding Key: '$($keyval[0])'='$val'" - } - } - } - return $pyvenvConfig -} - - -<# Begin Activate script --------------------------------------------------- #> - -# Determine the containing directory of this script -$VenvExecPath = Split-Path -Parent $MyInvocation.MyCommand.Definition -$VenvExecDir = Get-Item -Path $VenvExecPath - -Write-Verbose "Activation script is located in path: '$VenvExecPath'" -Write-Verbose "VenvExecDir Fullname: '$($VenvExecDir.FullName)" -Write-Verbose "VenvExecDir Name: '$($VenvExecDir.Name)" - -# Set values required in priority: CmdLine, ConfigFile, Default -# First, get the location of the virtual environment, it might not be -# VenvExecDir if specified on the command line. -if ($VenvDir) { - Write-Verbose "VenvDir given as parameter, using '$VenvDir' to determine values" -} -else { - Write-Verbose "VenvDir not given as a parameter, using parent directory name as VenvDir." - $VenvDir = $VenvExecDir.Parent.FullName.TrimEnd("\\/") - Write-Verbose "VenvDir=$VenvDir" -} - -# Next, read the `pyvenv.cfg` file to determine any required value such -# as `prompt`. -$pyvenvCfg = Get-PyVenvConfig -ConfigDir $VenvDir - -# Next, set the prompt from the command line, or the config file, or -# just use the name of the virtual environment folder. -if ($Prompt) { - Write-Verbose "Prompt specified as argument, using '$Prompt'" -} -else { - Write-Verbose "Prompt not specified as argument to script, checking pyvenv.cfg value" - if ($pyvenvCfg -and $pyvenvCfg['prompt']) { - Write-Verbose " Setting based on value in pyvenv.cfg='$($pyvenvCfg['prompt'])'" - $Prompt = $pyvenvCfg['prompt']; - } - else { - Write-Verbose " Setting prompt based on parent's directory's name. (Is the directory name passed to venv module when creating the virtual environment)" - Write-Verbose " Got leaf-name of $VenvDir='$(Split-Path -Path $venvDir -Leaf)'" - $Prompt = Split-Path -Path $venvDir -Leaf - } -} - -Write-Verbose "Prompt = '$Prompt'" -Write-Verbose "VenvDir='$VenvDir'" - -# Deactivate any currently active virtual environment, but leave the -# deactivate function in place. -deactivate -nondestructive - -# Now set the environment variable VIRTUAL_ENV, used by many tools to determine -# that there is an activated venv. -$env:VIRTUAL_ENV = $VenvDir - -if (-not $Env:VIRTUAL_ENV_DISABLE_PROMPT) { - - Write-Verbose "Setting prompt to '$Prompt'" - - # Set the prompt to include the env name - # Make sure _OLD_VIRTUAL_PROMPT is global - function global:_OLD_VIRTUAL_PROMPT { "" } - Copy-Item -Path function:prompt -Destination function:_OLD_VIRTUAL_PROMPT - New-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Description "Python virtual environment prompt prefix" -Scope Global -Option ReadOnly -Visibility Public -Value $Prompt - - function global:prompt { - Write-Host -NoNewline -ForegroundColor Green "($_PYTHON_VENV_PROMPT_PREFIX) " - _OLD_VIRTUAL_PROMPT - } - $env:VIRTUAL_ENV_PROMPT = $Prompt -} - -# Clear PYTHONHOME -if (Test-Path -Path Env:PYTHONHOME) { - Copy-Item -Path Env:PYTHONHOME -Destination Env:_OLD_VIRTUAL_PYTHONHOME - Remove-Item -Path Env:PYTHONHOME -} - -# Add the venv to the PATH -Copy-Item -Path Env:PATH -Destination Env:_OLD_VIRTUAL_PATH -$Env:PATH = "$VenvExecDir$([System.IO.Path]::PathSeparator)$Env:PATH" +<# +.Synopsis +Activate a Python virtual environment for the current PowerShell session. + +.Description +Pushes the python executable for a virtual environment to the front of the +$Env:PATH environment variable and sets the prompt to signify that you are +in a Python virtual environment. Makes use of the command line switches as +well as the `pyvenv.cfg` file values present in the virtual environment. + +.Parameter VenvDir +Path to the directory that contains the virtual environment to activate. The +default value for this is the parent of the directory that the Activate.ps1 +script is located within. + +.Parameter Prompt +The prompt prefix to display when this virtual environment is activated. By +default, this prompt is the name of the virtual environment folder (VenvDir) +surrounded by parentheses and followed by a single space (ie. '(.venv) '). + +.Example +Activate.ps1 +Activates the Python virtual environment that contains the Activate.ps1 script. + +.Example +Activate.ps1 -Verbose +Activates the Python virtual environment that contains the Activate.ps1 script, +and shows extra information about the activation as it executes. + +.Example +Activate.ps1 -VenvDir C:\Users\MyUser\Common\.venv +Activates the Python virtual environment located in the specified location. + +.Example +Activate.ps1 -Prompt "MyPython" +Activates the Python virtual environment that contains the Activate.ps1 script, +and prefixes the current prompt with the specified string (surrounded in +parentheses) while the virtual environment is active. + +.Notes +On Windows, it may be required to enable this Activate.ps1 script by setting the +execution policy for the user. You can do this by issuing the following PowerShell +command: + +PS C:\> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser + +For more information on Execution Policies: +https://go.microsoft.com/fwlink/?LinkID=135170 + +#> +Param( + [Parameter(Mandatory = $false)] + [String] + $VenvDir, + [Parameter(Mandatory = $false)] + [String] + $Prompt +) + +<# Function declarations --------------------------------------------------- #> + +<# +.Synopsis +Remove all shell session elements added by the Activate script, including the +addition of the virtual environment's Python executable from the beginning of +the PATH variable. + +.Parameter NonDestructive +If present, do not remove this function from the global namespace for the +session. + +#> +function global:deactivate ([switch]$NonDestructive) { + # Revert to original values + + # The prior prompt: + if (Test-Path -Path Function:_OLD_VIRTUAL_PROMPT) { + Copy-Item -Path Function:_OLD_VIRTUAL_PROMPT -Destination Function:prompt + Remove-Item -Path Function:_OLD_VIRTUAL_PROMPT + } + + # The prior PYTHONHOME: + if (Test-Path -Path Env:_OLD_VIRTUAL_PYTHONHOME) { + Copy-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME -Destination Env:PYTHONHOME + Remove-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME + } + + # The prior PATH: + if (Test-Path -Path Env:_OLD_VIRTUAL_PATH) { + Copy-Item -Path Env:_OLD_VIRTUAL_PATH -Destination Env:PATH + Remove-Item -Path Env:_OLD_VIRTUAL_PATH + } + + # Just remove the VIRTUAL_ENV altogether: + if (Test-Path -Path Env:VIRTUAL_ENV) { + Remove-Item -Path env:VIRTUAL_ENV + } + + # Just remove VIRTUAL_ENV_PROMPT altogether. + if (Test-Path -Path Env:VIRTUAL_ENV_PROMPT) { + Remove-Item -Path env:VIRTUAL_ENV_PROMPT + } + + # Just remove the _PYTHON_VENV_PROMPT_PREFIX altogether: + if (Get-Variable -Name "_PYTHON_VENV_PROMPT_PREFIX" -ErrorAction SilentlyContinue) { + Remove-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Scope Global -Force + } + + # Leave deactivate function in the global namespace if requested: + if (-not $NonDestructive) { + Remove-Item -Path function:deactivate + } +} + +<# +.Description +Get-PyVenvConfig parses the values from the pyvenv.cfg file located in the +given folder, and returns them in a map. + +For each line in the pyvenv.cfg file, if that line can be parsed into exactly +two strings separated by `=` (with any amount of whitespace surrounding the =) +then it is considered a `key = value` line. The left hand string is the key, +the right hand is the value. + +If the value starts with a `'` or a `"` then the first and last character is +stripped from the value before being captured. + +.Parameter ConfigDir +Path to the directory that contains the `pyvenv.cfg` file. +#> +function Get-PyVenvConfig( + [String] + $ConfigDir +) { + Write-Verbose "Given ConfigDir=$ConfigDir, obtain values in pyvenv.cfg" + + # Ensure the file exists, and issue a warning if it doesn't (but still allow the function to continue). + $pyvenvConfigPath = Join-Path -Resolve -Path $ConfigDir -ChildPath 'pyvenv.cfg' -ErrorAction Continue + + # An empty map will be returned if no config file is found. + $pyvenvConfig = @{ } + + if ($pyvenvConfigPath) { + + Write-Verbose "File exists, parse `key = value` lines" + $pyvenvConfigContent = Get-Content -Path $pyvenvConfigPath + + $pyvenvConfigContent | ForEach-Object { + $keyval = $PSItem -split "\s*=\s*", 2 + if ($keyval[0] -and $keyval[1]) { + $val = $keyval[1] + + # Remove extraneous quotations around a string value. + if ("'""".Contains($val.Substring(0, 1))) { + $val = $val.Substring(1, $val.Length - 2) + } + + $pyvenvConfig[$keyval[0]] = $val + Write-Verbose "Adding Key: '$($keyval[0])'='$val'" + } + } + } + return $pyvenvConfig +} + + +<# Begin Activate script --------------------------------------------------- #> + +# Determine the containing directory of this script +$VenvExecPath = Split-Path -Parent $MyInvocation.MyCommand.Definition +$VenvExecDir = Get-Item -Path $VenvExecPath + +Write-Verbose "Activation script is located in path: '$VenvExecPath'" +Write-Verbose "VenvExecDir Fullname: '$($VenvExecDir.FullName)" +Write-Verbose "VenvExecDir Name: '$($VenvExecDir.Name)" + +# Set values required in priority: CmdLine, ConfigFile, Default +# First, get the location of the virtual environment, it might not be +# VenvExecDir if specified on the command line. +if ($VenvDir) { + Write-Verbose "VenvDir given as parameter, using '$VenvDir' to determine values" +} +else { + Write-Verbose "VenvDir not given as a parameter, using parent directory name as VenvDir." + $VenvDir = $VenvExecDir.Parent.FullName.TrimEnd("\\/") + Write-Verbose "VenvDir=$VenvDir" +} + +# Next, read the `pyvenv.cfg` file to determine any required value such +# as `prompt`. +$pyvenvCfg = Get-PyVenvConfig -ConfigDir $VenvDir + +# Next, set the prompt from the command line, or the config file, or +# just use the name of the virtual environment folder. +if ($Prompt) { + Write-Verbose "Prompt specified as argument, using '$Prompt'" +} +else { + Write-Verbose "Prompt not specified as argument to script, checking pyvenv.cfg value" + if ($pyvenvCfg -and $pyvenvCfg['prompt']) { + Write-Verbose " Setting based on value in pyvenv.cfg='$($pyvenvCfg['prompt'])'" + $Prompt = $pyvenvCfg['prompt']; + } + else { + Write-Verbose " Setting prompt based on parent's directory's name. (Is the directory name passed to venv module when creating the virtual environment)" + Write-Verbose " Got leaf-name of $VenvDir='$(Split-Path -Path $venvDir -Leaf)'" + $Prompt = Split-Path -Path $venvDir -Leaf + } +} + +Write-Verbose "Prompt = '$Prompt'" +Write-Verbose "VenvDir='$VenvDir'" + +# Deactivate any currently active virtual environment, but leave the +# deactivate function in place. +deactivate -nondestructive + +# Now set the environment variable VIRTUAL_ENV, used by many tools to determine +# that there is an activated venv. +$env:VIRTUAL_ENV = $VenvDir + +if (-not $Env:VIRTUAL_ENV_DISABLE_PROMPT) { + + Write-Verbose "Setting prompt to '$Prompt'" + + # Set the prompt to include the env name + # Make sure _OLD_VIRTUAL_PROMPT is global + function global:_OLD_VIRTUAL_PROMPT { "" } + Copy-Item -Path function:prompt -Destination function:_OLD_VIRTUAL_PROMPT + New-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Description "Python virtual environment prompt prefix" -Scope Global -Option ReadOnly -Visibility Public -Value $Prompt + + function global:prompt { + Write-Host -NoNewline -ForegroundColor Green "($_PYTHON_VENV_PROMPT_PREFIX) " + _OLD_VIRTUAL_PROMPT + } + $env:VIRTUAL_ENV_PROMPT = $Prompt +} + +# Clear PYTHONHOME +if (Test-Path -Path Env:PYTHONHOME) { + Copy-Item -Path Env:PYTHONHOME -Destination Env:_OLD_VIRTUAL_PYTHONHOME + Remove-Item -Path Env:PYTHONHOME +} + +# Add the venv to the PATH +Copy-Item -Path Env:PATH -Destination Env:_OLD_VIRTUAL_PATH +$Env:PATH = "$VenvExecDir$([System.IO.Path]::PathSeparator)$Env:PATH" diff --git a/Lib/venv/scripts/common/activate b/Lib/venv/scripts/common/activate index 6fbc2b88..408df5cb 100644 --- a/Lib/venv/scripts/common/activate +++ b/Lib/venv/scripts/common/activate @@ -1,5 +1,5 @@ # This file must be used with "source bin/activate" *from bash* -# you cannot run it directly +# You cannot run it directly deactivate () { # reset old environment variables @@ -38,8 +38,15 @@ deactivate () { # unset irrelevant variables deactivate nondestructive -VIRTUAL_ENV="__VENV_DIR__" -export VIRTUAL_ENV +# on Windows, a path can contain colons and backslashes and has to be converted: +if [ "$OSTYPE" = "cygwin" ] || [ "$OSTYPE" = "msys" ] ; then + # transform D:\path\to\venv to /d/path/to/venv on MSYS + # and to /cygdrive/d/path/to/venv on Cygwin + export VIRTUAL_ENV=$(cygpath "__VENV_DIR__") +else + # use the path as-is + export VIRTUAL_ENV="__VENV_DIR__" +fi _OLD_VIRTUAL_PATH="$PATH" PATH="$VIRTUAL_ENV/__VENV_BIN_NAME__:$PATH" diff --git a/Lib/venv/scripts/nt/activate.bat b/Lib/venv/scripts/nt/activate.bat index 5daa45af..c1c3c82e 100644 --- a/Lib/venv/scripts/nt/activate.bat +++ b/Lib/venv/scripts/nt/activate.bat @@ -1,34 +1,34 @@ -@echo off - -rem This file is UTF-8 encoded, so we need to update the current code page while executing it -for /f "tokens=2 delims=:." %%a in ('"%SystemRoot%\System32\chcp.com"') do ( - set _OLD_CODEPAGE=%%a -) -if defined _OLD_CODEPAGE ( - "%SystemRoot%\System32\chcp.com" 65001 > nul -) - -set VIRTUAL_ENV=__VENV_DIR__ - -if not defined PROMPT set PROMPT=$P$G - -if defined _OLD_VIRTUAL_PROMPT set PROMPT=%_OLD_VIRTUAL_PROMPT% -if defined _OLD_VIRTUAL_PYTHONHOME set PYTHONHOME=%_OLD_VIRTUAL_PYTHONHOME% - -set _OLD_VIRTUAL_PROMPT=%PROMPT% -set PROMPT=__VENV_PROMPT__%PROMPT% - -if defined PYTHONHOME set _OLD_VIRTUAL_PYTHONHOME=%PYTHONHOME% -set PYTHONHOME= - -if defined _OLD_VIRTUAL_PATH set PATH=%_OLD_VIRTUAL_PATH% -if not defined _OLD_VIRTUAL_PATH set _OLD_VIRTUAL_PATH=%PATH% - -set PATH=%VIRTUAL_ENV%\__VENV_BIN_NAME__;%PATH% -set VIRTUAL_ENV_PROMPT=__VENV_PROMPT__ - -:END -if defined _OLD_CODEPAGE ( - "%SystemRoot%\System32\chcp.com" %_OLD_CODEPAGE% > nul - set _OLD_CODEPAGE= -) +@echo off + +rem This file is UTF-8 encoded, so we need to update the current code page while executing it +for /f "tokens=2 delims=:." %%a in ('"%SystemRoot%\System32\chcp.com"') do ( + set _OLD_CODEPAGE=%%a +) +if defined _OLD_CODEPAGE ( + "%SystemRoot%\System32\chcp.com" 65001 > nul +) + +set VIRTUAL_ENV=__VENV_DIR__ + +if not defined PROMPT set PROMPT=$P$G + +if defined _OLD_VIRTUAL_PROMPT set PROMPT=%_OLD_VIRTUAL_PROMPT% +if defined _OLD_VIRTUAL_PYTHONHOME set PYTHONHOME=%_OLD_VIRTUAL_PYTHONHOME% + +set _OLD_VIRTUAL_PROMPT=%PROMPT% +set PROMPT=__VENV_PROMPT__%PROMPT% + +if defined PYTHONHOME set _OLD_VIRTUAL_PYTHONHOME=%PYTHONHOME% +set PYTHONHOME= + +if defined _OLD_VIRTUAL_PATH set PATH=%_OLD_VIRTUAL_PATH% +if not defined _OLD_VIRTUAL_PATH set _OLD_VIRTUAL_PATH=%PATH% + +set PATH=%VIRTUAL_ENV%\__VENV_BIN_NAME__;%PATH% +set VIRTUAL_ENV_PROMPT=__VENV_PROMPT__ + +:END +if defined _OLD_CODEPAGE ( + "%SystemRoot%\System32\chcp.com" %_OLD_CODEPAGE% > nul + set _OLD_CODEPAGE= +) diff --git a/Lib/venv/scripts/nt/deactivate.bat b/Lib/venv/scripts/nt/deactivate.bat index 44dae495..62a39a75 100644 --- a/Lib/venv/scripts/nt/deactivate.bat +++ b/Lib/venv/scripts/nt/deactivate.bat @@ -1,22 +1,22 @@ -@echo off - -if defined _OLD_VIRTUAL_PROMPT ( - set "PROMPT=%_OLD_VIRTUAL_PROMPT%" -) -set _OLD_VIRTUAL_PROMPT= - -if defined _OLD_VIRTUAL_PYTHONHOME ( - set "PYTHONHOME=%_OLD_VIRTUAL_PYTHONHOME%" - set _OLD_VIRTUAL_PYTHONHOME= -) - -if defined _OLD_VIRTUAL_PATH ( - set "PATH=%_OLD_VIRTUAL_PATH%" -) - -set _OLD_VIRTUAL_PATH= - -set VIRTUAL_ENV= -set VIRTUAL_ENV_PROMPT= - -:END +@echo off + +if defined _OLD_VIRTUAL_PROMPT ( + set "PROMPT=%_OLD_VIRTUAL_PROMPT%" +) +set _OLD_VIRTUAL_PROMPT= + +if defined _OLD_VIRTUAL_PYTHONHOME ( + set "PYTHONHOME=%_OLD_VIRTUAL_PYTHONHOME%" + set _OLD_VIRTUAL_PYTHONHOME= +) + +if defined _OLD_VIRTUAL_PATH ( + set "PATH=%_OLD_VIRTUAL_PATH%" +) + +set _OLD_VIRTUAL_PATH= + +set VIRTUAL_ENV= +set VIRTUAL_ENV_PROMPT= + +:END diff --git a/Lib/venv/scripts/posix/activate.csh b/Lib/venv/scripts/posix/activate.csh index d6f697c5..5e8d66fa 100644 --- a/Lib/venv/scripts/posix/activate.csh +++ b/Lib/venv/scripts/posix/activate.csh @@ -1,5 +1,6 @@ # This file must be used with "source bin/activate.csh" *from csh*. # You cannot run it directly. + # Created by Davide Di Blasi <davidedb@gmail.com>. # Ported to Python 3.3 venv by Andrew Svetlov <andrew.svetlov@gmail.com> diff --git a/Lib/venv/scripts/posix/activate.fish b/Lib/venv/scripts/posix/activate.fish index 9aa44460..91ad6442 100644 --- a/Lib/venv/scripts/posix/activate.fish +++ b/Lib/venv/scripts/posix/activate.fish @@ -1,5 +1,5 @@ # This file must be used with "source <venv>/bin/activate.fish" *from fish* -# (https://fishshell.com/); you cannot run it directly. +# (https://fishshell.com/). You cannot run it directly. function deactivate -d "Exit virtual environment and return to normal shell environment" # reset old environment variables diff --git a/Lib/warnings.py b/Lib/warnings.py index 7d8c4400..98ae708c 100644 --- a/Lib/warnings.py +++ b/Lib/warnings.py @@ -269,22 +269,32 @@ def _getcategory(category): return cat +def _is_internal_filename(filename): + return 'importlib' in filename and '_bootstrap' in filename + + +def _is_filename_to_skip(filename, skip_file_prefixes): + return any(filename.startswith(prefix) for prefix in skip_file_prefixes) + + def _is_internal_frame(frame): """Signal whether the frame is an internal CPython implementation detail.""" - filename = frame.f_code.co_filename - return 'importlib' in filename and '_bootstrap' in filename + return _is_internal_filename(frame.f_code.co_filename) -def _next_external_frame(frame): - """Find the next frame that doesn't involve CPython internals.""" +def _next_external_frame(frame, skip_file_prefixes): + """Find the next frame that doesn't involve Python or user internals.""" frame = frame.f_back - while frame is not None and _is_internal_frame(frame): + while frame is not None and ( + _is_internal_filename(filename := frame.f_code.co_filename) or + _is_filename_to_skip(filename, skip_file_prefixes)): frame = frame.f_back return frame # Code typically replaced by _warnings -def warn(message, category=None, stacklevel=1, source=None): +def warn(message, category=None, stacklevel=1, source=None, + *, skip_file_prefixes=()): """Issue a warning, or maybe ignore it or raise an exception.""" # Check if message is already a Warning object if isinstance(message, Warning): @@ -295,6 +305,11 @@ def warn(message, category=None, stacklevel=1, source=None): if not (isinstance(category, type) and issubclass(category, Warning)): raise TypeError("category must be a Warning subclass, " "not '{:s}'".format(type(category).__name__)) + if not isinstance(skip_file_prefixes, tuple): + # The C version demands a tuple for implementation performance. + raise TypeError('skip_file_prefixes must be a tuple of strs.') + if skip_file_prefixes: + stacklevel = max(2, stacklevel) # Get context information try: if stacklevel <= 1 or _is_internal_frame(sys._getframe(1)): @@ -305,7 +320,7 @@ def warn(message, category=None, stacklevel=1, source=None): frame = sys._getframe(1) # Look for one frame less since the above line starts us off. for x in range(stacklevel-1): - frame = _next_external_frame(frame) + frame = _next_external_frame(frame, skip_file_prefixes) if frame is None: raise ValueError except ValueError: diff --git a/Lib/wave.py b/Lib/wave.py index 9a455748..4b0c683f 100644 --- a/Lib/wave.py +++ b/Lib/wave.py @@ -83,12 +83,16 @@ class Error(Exception): pass WAVE_FORMAT_PCM = 0x0001 +WAVE_FORMAT_EXTENSIBLE = 0xFFFE +# Derived from uuid.UUID("00000001-0000-0010-8000-00aa00389b71").bytes_le +KSDATAFORMAT_SUBTYPE_PCM = b'\x01\x00\x00\x00\x00\x00\x10\x00\x80\x00\x00\xaa\x008\x9bq' _array_fmts = None, 'b', 'h', None, 'i' _wave_params = namedtuple('_wave_params', 'nchannels sampwidth framerate nframes comptype compname') + def _byteswap(data, width): swapped_data = bytearray(len(data)) @@ -101,7 +105,6 @@ def _byteswap(data, width): class _Chunk: def __init__(self, file, align=True, bigendian=True, inclheader=False): - import struct self.closed = False self.align = align # whether to align to word (2-byte) boundaries if bigendian: @@ -211,7 +214,6 @@ class _Chunk: raise EOFError - class Wave_read: """Variables used in this class: @@ -377,22 +379,38 @@ class Wave_read: wFormatTag, self._nchannels, self._framerate, dwAvgBytesPerSec, wBlockAlign = struct.unpack_from('<HHLLH', chunk.read(14)) except struct.error: raise EOFError from None - if wFormatTag == WAVE_FORMAT_PCM: + if wFormatTag != WAVE_FORMAT_PCM and wFormatTag != WAVE_FORMAT_EXTENSIBLE: + raise Error('unknown format: %r' % (wFormatTag,)) + try: + sampwidth = struct.unpack_from('<H', chunk.read(2))[0] + except struct.error: + raise EOFError from None + if wFormatTag == WAVE_FORMAT_EXTENSIBLE: try: - sampwidth = struct.unpack_from('<H', chunk.read(2))[0] + cbSize, wValidBitsPerSample, dwChannelMask = struct.unpack_from('<HHL', chunk.read(8)) + # Read the entire UUID from the chunk + SubFormat = chunk.read(16) + if len(SubFormat) < 16: + raise EOFError except struct.error: raise EOFError from None - self._sampwidth = (sampwidth + 7) // 8 - if not self._sampwidth: - raise Error('bad sample width') - else: - raise Error('unknown format: %r' % (wFormatTag,)) + if SubFormat != KSDATAFORMAT_SUBTYPE_PCM: + try: + import uuid + subformat_msg = f'unknown extended format: {uuid.UUID(bytes_le=SubFormat)}' + except Exception: + subformat_msg = 'unknown extended format' + raise Error(subformat_msg) + self._sampwidth = (sampwidth + 7) // 8 + if not self._sampwidth: + raise Error('bad sample width') if not self._nchannels: raise Error('bad # of channels') self._framesize = self._nchannels * self._sampwidth self._comptype = 'NONE' self._compname = 'not compressed' + class Wave_write: """Variables used in this class: @@ -620,6 +638,7 @@ class Wave_write: self._file.seek(curpos, 0) self._datalength = self._datawritten + def open(f, mode=None): if mode is None: if hasattr(f, 'mode'): diff --git a/Lib/webbrowser.py b/Lib/webbrowser.py index 44974d43..e0170afd 100755 --- a/Lib/webbrowser.py +++ b/Lib/webbrowser.py @@ -292,19 +292,8 @@ class Mozilla(UnixBrowser): background = True -class Netscape(UnixBrowser): - """Launcher class for Netscape browser.""" - - raise_opts = ["-noraise", "-raise"] - remote_args = ['-remote', 'openURL(%s%action)'] - remote_action = "" - remote_action_newwin = ",new-window" - remote_action_newtab = ",new-tab" - background = True - - -class Galeon(UnixBrowser): - """Launcher class for Galeon/Epiphany browsers.""" +class Epiphany(UnixBrowser): + """Launcher class for Epiphany browser.""" raise_opts = ["-noraise", ""] remote_args = ['%action', '%s'] @@ -402,51 +391,14 @@ class Konqueror(BaseBrowser): return (p.poll() is None) -class Grail(BaseBrowser): - # There should be a way to maintain a connection to Grail, but the - # Grail remote control protocol doesn't really allow that at this - # point. It probably never will! - def _find_grail_rc(self): - import glob - import pwd - import socket - import tempfile - tempdir = os.path.join(tempfile.gettempdir(), - ".grail-unix") - user = pwd.getpwuid(os.getuid())[0] - filename = os.path.join(glob.escape(tempdir), glob.escape(user) + "-*") - maybes = glob.glob(filename) - if not maybes: - return None - s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) - for fn in maybes: - # need to PING each one until we find one that's live - try: - s.connect(fn) - except OSError: - # no good; attempt to clean it out, but don't fail: - try: - os.unlink(fn) - except OSError: - pass - else: - return s - - def _remote(self, action): - s = self._find_grail_rc() - if not s: - return 0 - s.send(action) - s.close() - return 1 +class Edge(UnixBrowser): + "Launcher class for Microsoft Edge browser." - def open(self, url, new=0, autoraise=True): - sys.audit("webbrowser.open", url) - if new: - ok = self._remote("LOADNEW " + url) - else: - ok = self._remote("LOAD " + url) - return ok + remote_args = ['%action', '%s'] + remote_action = "" + remote_action_newwin = "--new-window" + remote_action_newtab = "" + background = True # @@ -475,35 +427,25 @@ def register_X_browsers(): if "KDE_FULL_SESSION" in os.environ and shutil.which("kfmclient"): register("kfmclient", Konqueror, Konqueror("kfmclient")) + # Common symbolic link for the default X11 browser if shutil.which("x-www-browser"): register("x-www-browser", None, BackgroundBrowser("x-www-browser")) # The Mozilla browsers - for browser in ("firefox", "iceweasel", "iceape", "seamonkey"): + for browser in ("firefox", "iceweasel", "seamonkey", "mozilla-firefox", + "mozilla"): if shutil.which(browser): register(browser, None, Mozilla(browser)) - # The Netscape and old Mozilla browsers - for browser in ("mozilla-firefox", - "mozilla-firebird", "firebird", - "mozilla", "netscape"): - if shutil.which(browser): - register(browser, None, Netscape(browser)) - # Konqueror/kfm, the KDE browser. if shutil.which("kfm"): register("kfm", Konqueror, Konqueror("kfm")) elif shutil.which("konqueror"): register("konqueror", Konqueror, Konqueror("konqueror")) - # Gnome's Galeon and Epiphany - for browser in ("galeon", "epiphany"): - if shutil.which(browser): - register(browser, None, Galeon(browser)) - - # Skipstone, another Gtk/Mozilla based browser - if shutil.which("skipstone"): - register("skipstone", None, BackgroundBrowser("skipstone")) + # Gnome's Epiphany + if shutil.which("epiphany"): + register("epiphany", None, Epiphany("epiphany")) # Google Chrome/Chromium browsers for browser in ("google-chrome", "chrome", "chromium", "chromium-browser"): @@ -514,13 +456,10 @@ def register_X_browsers(): if shutil.which("opera"): register("opera", None, Opera("opera")) - # Next, Mosaic -- old but still in use. - if shutil.which("mosaic"): - register("mosaic", None, BackgroundBrowser("mosaic")) - # Grail, the Python browser. Does anybody still use it? - if shutil.which("grail"): - register("grail", Grail, None) + if shutil.which("microsoft-edge"): + register("microsoft-edge", None, Edge("microsoft-edge")) + def register_standard_browsers(): global _tryorder @@ -542,13 +481,19 @@ def register_standard_browsers(): # First try to use the default Windows browser register("windows-default", WindowsDefault) - # Detect some common Windows browsers, fallback to IE - iexplore = os.path.join(os.environ.get("PROGRAMFILES", "C:\\Program Files"), - "Internet Explorer\\IEXPLORE.EXE") - for browser in ("firefox", "firebird", "seamonkey", "mozilla", - "netscape", "opera", iexplore): + # Detect some common Windows browsers, fallback to Microsoft Edge + # location in 64-bit Windows + edge64 = os.path.join(os.environ.get("PROGRAMFILES(x86)", "C:\\Program Files (x86)"), + "Microsoft\\Edge\\Application\\msedge.exe") + # location in 32-bit Windows + edge32 = os.path.join(os.environ.get("PROGRAMFILES", "C:\\Program Files"), + "Microsoft\\Edge\\Application\\msedge.exe") + for browser in ("firefox", "seamonkey", "mozilla", "chrome", + "opera", edge64, edge32): if shutil.which(browser): register(browser, None, BackgroundBrowser(browser)) + if shutil.which("MicrosoftEdge.exe"): + register("microsoft-edge", None, Edge("MicrosoftEdge.exe")) else: # Prefer X browsers if present if os.environ.get("DISPLAY") or os.environ.get("WAYLAND_DISPLAY"): @@ -566,14 +511,15 @@ def register_standard_browsers(): # Also try console browsers if os.environ.get("TERM"): + # Common symbolic link for the default text-based browser if shutil.which("www-browser"): register("www-browser", None, GenericBrowser("www-browser")) - # The Links/elinks browsers <http://artax.karlin.mff.cuni.cz/~mikulas/links/> + # The Links/elinks browsers <http://links.twibright.com/> if shutil.which("links"): register("links", None, GenericBrowser("links")) if shutil.which("elinks"): register("elinks", None, Elinks("elinks")) - # The Lynx browser <http://lynx.isc.org/>, <http://lynx.browser.org/> + # The Lynx browser <https://lynx.invisible-island.net/>, <http://lynx.browser.org/> if shutil.which("lynx"): register("lynx", None, GenericBrowser("lynx")) # The w3m browser <http://w3m.sourceforge.net/> @@ -709,11 +655,12 @@ if sys.platform == 'darwin': def main(): import getopt - usage = """Usage: %s [-n | -t] url + usage = """Usage: %s [-n | -t | -h] url -n: open new window - -t: open new tab""" % sys.argv[0] + -t: open new tab + -h, --help: show help""" % sys.argv[0] try: - opts, args = getopt.getopt(sys.argv[1:], 'ntd') + opts, args = getopt.getopt(sys.argv[1:], 'ntdh',['help']) except getopt.error as msg: print(msg, file=sys.stderr) print(usage, file=sys.stderr) @@ -722,6 +669,9 @@ def main(): for o, a in opts: if o == '-n': new_win = 1 elif o == '-t': new_win = 2 + elif o == '-h' or o == '--help': + print(usage, file=sys.stderr) + sys.exit() if len(args) != 1: print(usage, file=sys.stderr) sys.exit(1) diff --git a/Lib/wsgiref/handlers.py b/Lib/wsgiref/handlers.py index 6623b700..cafe872c 100644 --- a/Lib/wsgiref/handlers.py +++ b/Lib/wsgiref/handlers.py @@ -237,9 +237,7 @@ class BaseHandler: self.status = status self.headers = self.headers_class(headers) status = self._convert_string_type(status, "Status") - assert len(status)>=4,"Status must be at least 4 characters" - assert status[:3].isdigit(), "Status message must begin w/3-digit code" - assert status[3]==" ", "Status message must have a space after code" + self._validate_status(status) if __debug__: for name, val in headers: @@ -250,6 +248,14 @@ class BaseHandler: return self.write + def _validate_status(self, status): + if len(status) < 4: + raise AssertionError("Status must be at least 4 characters") + if not status[:3].isdigit(): + raise AssertionError("Status message must begin w/3-digit code") + if status[3] != " ": + raise AssertionError("Status message must have a space after code") + def _convert_string_type(self, value, title): """Convert/check value type.""" if type(value) is str: @@ -469,10 +475,7 @@ class SimpleHandler(BaseHandler): from warnings import warn warn("SimpleHandler.stdout.write() should not do partial writes", DeprecationWarning) - while True: - data = data[result:] - if not data: - break + while data := data[result:]: result = self.stdout.write(data) def _flush(self): diff --git a/Lib/wsgiref/validate.py b/Lib/wsgiref/validate.py index 6044e320..1a1853cd 100644 --- a/Lib/wsgiref/validate.py +++ b/Lib/wsgiref/validate.py @@ -214,10 +214,7 @@ class InputWrapper: return lines def __iter__(self): - while 1: - line = self.readline() - if not line: - return + while line := self.readline(): yield line def close(self): diff --git a/Lib/xdrlib.py b/Lib/xdrlib.py index b56ffa59..f8c2c182 100644 --- a/Lib/xdrlib.py +++ b/Lib/xdrlib.py @@ -224,9 +224,7 @@ class Unpacker: def unpack_list(self, unpack_item): list = [] - while 1: - x = self.unpack_uint() - if x == 0: break + while (x := self.unpack_uint()) != 0: if x != 1: raise ConversionError('0 or 1 expected, got %r' % (x,)) item = unpack_item() diff --git a/Lib/xml/dom/expatbuilder.py b/Lib/xml/dom/expatbuilder.py index 199c22d0..7dd667bf 100644 --- a/Lib/xml/dom/expatbuilder.py +++ b/Lib/xml/dom/expatbuilder.py @@ -200,10 +200,7 @@ class ExpatBuilder: parser = self.getParser() first_buffer = True try: - while 1: - buffer = file.read(16*1024) - if not buffer: - break + while buffer := file.read(16*1024): parser.Parse(buffer, False) if first_buffer and self.document.documentElement: self._setup_subset(buffer) diff --git a/Lib/xml/etree/ElementTree.py b/Lib/xml/etree/ElementTree.py index 1dc80351..42574eef 100644 --- a/Lib/xml/etree/ElementTree.py +++ b/Lib/xml/etree/ElementTree.py @@ -188,19 +188,6 @@ class Element: """ return self.__class__(tag, attrib) - def copy(self): - """Return copy of current element. - - This creates a shallow copy. Subelements will be shared with the - original tree. - - """ - warnings.warn( - "elem.copy() is deprecated. Use copy.copy(elem) instead.", - DeprecationWarning - ) - return self.__copy__() - def __copy__(self): elem = self.makeelement(self.tag, self.attrib) elem.text = self.text @@ -213,9 +200,10 @@ class Element: def __bool__(self): warnings.warn( - "The behavior of this method will change in future versions. " + "Testing an element's truth value will raise an exception in " + "future versions. " "Use specific 'len(elem)' or 'elem is not None' test instead.", - FutureWarning, stacklevel=2 + DeprecationWarning, stacklevel=2 ) return len(self._children) != 0 # emulate old behaviour, for now @@ -579,10 +567,7 @@ class ElementTree: # it with chunks. self._root = parser._parse_whole(source) return self._root - while True: - data = source.read(65536) - if not data: - break + while data := source.read(65536): parser.feed(data) self._root = parser.close() return self._root diff --git a/Lib/xml/sax/__init__.py b/Lib/xml/sax/__init__.py index 17b75879..b6573102 100644 --- a/Lib/xml/sax/__init__.py +++ b/Lib/xml/sax/__init__.py @@ -60,11 +60,7 @@ if _false: import os, sys if not sys.flags.ignore_environment and "PY_SAX_PARSER" in os.environ: default_parser_list = os.environ["PY_SAX_PARSER"].split(",") -del os - -_key = "python.xml.sax.parser" -if sys.platform[:4] == "java" and sys.registry.containsKey(_key): - default_parser_list = sys.registry.getProperty(_key).split(",") +del os, sys def make_parser(parser_list=()): @@ -93,15 +89,6 @@ def make_parser(parser_list=()): # --- Internal utility methods used by make_parser -if sys.platform[ : 4] == "java": - def _create_parser(parser_name): - from org.python.core import imp - drv_module = imp.importName(parser_name, 0, globals()) - return drv_module.create_parser() - -else: - def _create_parser(parser_name): - drv_module = __import__(parser_name,{},{},['create_parser']) - return drv_module.create_parser() - -del sys +def _create_parser(parser_name): + drv_module = __import__(parser_name,{},{},['create_parser']) + return drv_module.create_parser() diff --git a/Lib/xml/sax/_exceptions.py b/Lib/xml/sax/_exceptions.py index a9b2ba35..f292dc3a 100644 --- a/Lib/xml/sax/_exceptions.py +++ b/Lib/xml/sax/_exceptions.py @@ -1,8 +1,4 @@ """Different kinds of SAX Exceptions""" -import sys -if sys.platform[:4] == "java": - from java.lang import Exception -del sys # ===== SAXEXCEPTION ===== diff --git a/Lib/xml/sax/expatreader.py b/Lib/xml/sax/expatreader.py index e334ac9f..b9ad5269 100644 --- a/Lib/xml/sax/expatreader.py +++ b/Lib/xml/sax/expatreader.py @@ -12,12 +12,6 @@ from xml.sax.handler import feature_external_ges, feature_external_pes from xml.sax.handler import feature_string_interning from xml.sax.handler import property_xml_string, property_interning_dict -# xml.parsers.expat does not raise ImportError in Jython -import sys -if sys.platform[:4] == "java": - raise SAXReaderNotAvailable("expat not available in Java", None) -del sys - try: from xml.parsers import expat except ImportError: diff --git a/Lib/xml/sax/xmlreader.py b/Lib/xml/sax/xmlreader.py index 716f2284..e906121d 100644 --- a/Lib/xml/sax/xmlreader.py +++ b/Lib/xml/sax/xmlreader.py @@ -120,10 +120,8 @@ class IncrementalParser(XMLReader): file = source.getCharacterStream() if file is None: file = source.getByteStream() - buffer = file.read(self._bufsize) - while buffer: + while buffer := file.read(self._bufsize): self.feed(buffer) - buffer = file.read(self._bufsize) self.close() def feed(self, data): diff --git a/Lib/xmlrpc/client.py b/Lib/xmlrpc/client.py index a614cef6..ea8da766 100644 --- a/Lib/xmlrpc/client.py +++ b/Lib/xmlrpc/client.py @@ -850,9 +850,9 @@ class MultiCallIterator: def __getitem__(self, i): item = self.results[i] - if type(item) == type({}): + if isinstance(item, dict): raise Fault(item['faultCode'], item['faultString']) - elif type(item) == type([]): + elif isinstance(item, list): return item[0] else: raise ValueError("unexpected type in multicall result") @@ -1339,10 +1339,7 @@ class Transport: p, u = self.getparser() - while 1: - data = stream.read(1024) - if not data: - break + while data := stream.read(1024): if self.verbose: print("body:", repr(data)) p.feed(data) diff --git a/Lib/xmlrpc/server.py b/Lib/xmlrpc/server.py index 0c4b5580..4dddb1d1 100644 --- a/Lib/xmlrpc/server.py +++ b/Lib/xmlrpc/server.py @@ -720,9 +720,7 @@ class ServerHTMLDoc(pydoc.HTMLDoc): r'RFC[- ]?(\d+)|' r'PEP[- ]?(\d+)|' r'(self\.)?((?:\w|\.)+))\b') - while 1: - match = pattern.search(text, here) - if not match: break + while match := pattern.search(text, here): start, end = match.span() results.append(escape(text[here:start])) diff --git a/Lib/zipapp.py b/Lib/zipapp.py index ce776325..d8ebfcb6 100644 --- a/Lib/zipapp.py +++ b/Lib/zipapp.py @@ -136,7 +136,7 @@ def create_archive(source, target=None, interpreter=None, main=None, compression = (zipfile.ZIP_DEFLATED if compressed else zipfile.ZIP_STORED) with zipfile.ZipFile(fd, 'w', compression=compression) as z: - for child in source.rglob('*'): + for child in sorted(source.rglob('*')): arcname = child.relative_to(source) if filter is None or filter(arcname): z.write(child, arcname.as_posix()) diff --git a/Lib/zipfile.py b/Lib/zipfile/__init__.py similarity index 85% rename from Lib/zipfile.py rename to Lib/zipfile/__init__.py index f69a43b7..9fc1840b 100644 --- a/Lib/zipfile.py +++ b/Lib/zipfile/__init__.py @@ -6,17 +6,13 @@ XXX references to utf-8 need further investigation. import binascii import importlib.util import io -import itertools import os -import posixpath import shutil import stat import struct import sys import threading import time -import contextlib -import pathlib try: import zlib # We may need its compression method @@ -211,6 +207,8 @@ def _strip_extra(extra, xids): i = j if not modified: return extra + if start != len(extra): + buffer.append(extra[start:]) return b''.join(buffer) def _check_zipfile(fp): @@ -340,6 +338,24 @@ def _EndRecData(fpin): # Unable to find a valid end of central directory structure return None +def _sanitize_filename(filename): + """Terminate the file name at the first null byte and + ensure paths always use forward slashes as the directory separator.""" + + # Terminate the file name at the first null byte. Null bytes in file + # names are used as tricks by viruses in archives. + null_byte = filename.find(chr(0)) + if null_byte >= 0: + filename = filename[0:null_byte] + # This is used to ensure paths in generated ZIP files always use + # forward slashes as the directory separator, as required by the + # ZIP format specification. + if os.sep != "/" and os.sep in filename: + filename = filename.replace(os.sep, "/") + if os.altsep and os.altsep != "/" and os.altsep in filename: + filename = filename.replace(os.altsep, "/") + return filename + class ZipInfo (object): """Class with attributes describing each file in the ZIP archive.""" @@ -370,16 +386,9 @@ class ZipInfo (object): def __init__(self, filename="NoName", date_time=(1980,1,1,0,0,0)): self.orig_filename = filename # Original file name in archive - # Terminate the file name at the first null byte. Null bytes in file - # names are used as tricks by viruses in archives. - null_byte = filename.find(chr(0)) - if null_byte >= 0: - filename = filename[0:null_byte] - # This is used to ensure paths in generated ZIP files always use - # forward slashes as the directory separator, as required by the - # ZIP format specification. - if os.sep != "/" and os.sep in filename: - filename = filename.replace(os.sep, "/") + # Terminate the file name at the first null byte and + # ensure paths always use forward slashes as the directory separator. + filename = _sanitize_filename(filename) self.filename = filename # Normalized file name self.date_time = date_time # year, month, day, hour, min, sec @@ -433,7 +442,12 @@ class ZipInfo (object): return ''.join(result) def FileHeader(self, zip64=None): - """Return the per-file header as a bytes object.""" + """Return the per-file header as a bytes object. + + When the optional zip64 arg is None rather than a bool, we will + decide based upon the file_size and compress_size, if known, + False otherwise. + """ dt = self.date_time dosdate = (dt[0] - 1980) << 9 | dt[1] << 5 | dt[2] dostime = dt[3] << 11 | dt[4] << 5 | (dt[5] // 2) @@ -449,16 +463,13 @@ class ZipInfo (object): min_version = 0 if zip64 is None: + # We always explicitly pass zip64 within this module.... This + # remains for anyone using ZipInfo.FileHeader as a public API. zip64 = file_size > ZIP64_LIMIT or compress_size > ZIP64_LIMIT if zip64: fmt = '<HHQQ' extra = extra + struct.pack(fmt, 1, struct.calcsize(fmt)-4, file_size, compress_size) - if file_size > ZIP64_LIMIT or compress_size > ZIP64_LIMIT: - if not zip64: - raise LargeZipFile("Filesize would require ZIP64 extensions") - # File is larger than what fits into a 4 byte integer, - # fall back to the ZIP64 extension file_size = 0xffffffff compress_size = 0xffffffff min_version = ZIP64_VERSION @@ -484,7 +495,7 @@ class ZipInfo (object): except UnicodeEncodeError: return self.filename.encode('utf-8'), self.flag_bits | _MASK_UTF_FILENAME - def _decodeExtra(self): + def _decodeExtra(self, filename_crc): # Try to decode the extra field. extra = self.extra unpack = struct.unpack @@ -510,6 +521,21 @@ class ZipInfo (object): except struct.error: raise BadZipFile(f"Corrupt zip64 extra field. " f"{field} not found.") from None + elif tp == 0x7075: + data = extra[4:ln+4] + # Unicode Path Extra Field + try: + up_version, up_name_crc = unpack('<BL', data[:5]) + if up_version == 1 and up_name_crc == filename_crc: + up_unicode_name = data[5:].decode('utf-8') + if up_unicode_name: + self.filename = _sanitize_filename(up_unicode_name) + else: + warnings.warn("Empty unicode path extra field (0x7075)", stacklevel=2) + except struct.error as e: + raise BadZipFile("Corrupt unicode path extra field (0x7075)") from e + except UnicodeDecodeError as e: + raise BadZipFile('Corrupt unicode path extra field (0x7075): invalid utf-8 bytes') from e extra = extra[ln+4:] @@ -553,7 +579,7 @@ class ZipInfo (object): def is_dir(self): """Return True if this archive member is a directory.""" - return self.filename[-1] == '/' + return self.filename.endswith('/') # ZIP encryption uses the CRC32 one-byte primitive for scrambling some @@ -847,6 +873,7 @@ class ZipExtFile(io.BufferedIOBase): self._orig_compress_size = zipinfo.compress_size self._orig_file_size = zipinfo.file_size self._orig_start_crc = self._running_crc + self._orig_crc = self._expected_crc self._seekable = True except AttributeError: pass @@ -1069,17 +1096,17 @@ class ZipExtFile(io.BufferedIOBase): raise ValueError("I/O operation on closed file.") return self._seekable - def seek(self, offset, whence=0): + def seek(self, offset, whence=os.SEEK_SET): if self.closed: raise ValueError("seek on closed file.") if not self._seekable: raise io.UnsupportedOperation("underlying stream is not seekable") curr_pos = self.tell() - if whence == 0: # Seek from start of file + if whence == os.SEEK_SET: new_pos = offset - elif whence == 1: # Seek from current position + elif whence == os.SEEK_CUR: new_pos = curr_pos + offset - elif whence == 2: # Seek from EOF + elif whence == os.SEEK_END: new_pos = self._orig_file_size + offset else: raise ValueError("whence must be os.SEEK_SET (0), " @@ -1094,7 +1121,19 @@ class ZipExtFile(io.BufferedIOBase): read_offset = new_pos - curr_pos buff_offset = read_offset + self._offset - if buff_offset >= 0 and buff_offset < len(self._readbuffer): + # Fast seek uncompressed unencrypted file + if self._compress_type == ZIP_STORED and self._decrypter is None and read_offset > 0: + # disable CRC checking after first seeking - it would be invalid + self._expected_crc = None + # seek actual file taking already buffered data into account + read_offset -= len(self._readbuffer) - self._offset + self._fileobj.seek(read_offset, os.SEEK_CUR) + self._left -= read_offset + read_offset = 0 + # flush read buffer + self._readbuffer = b'' + self._offset = 0 + elif buff_offset >= 0 and buff_offset < len(self._readbuffer): # Just move the _offset index if the new position is in the _readbuffer self._offset = buff_offset read_offset = 0 @@ -1102,6 +1141,7 @@ class ZipExtFile(io.BufferedIOBase): # Position is before the current position. Reset the ZipExtFile self._fileobj.seek(self._orig_compress_start) self._running_crc = self._orig_start_crc + self._expected_crc = self._orig_crc self._compress_left = self._orig_compress_size self._left = self._orig_file_size self._readbuffer = b'' @@ -1181,6 +1221,12 @@ class _ZipWriteFile(io.BufferedIOBase): self._zinfo.CRC = self._crc self._zinfo.file_size = self._file_size + if not self._zip64: + if self._file_size > ZIP64_LIMIT: + raise RuntimeError("File size too large, try using force_zip64") + if self._compress_size > ZIP64_LIMIT: + raise RuntimeError("Compressed size too large, try using force_zip64") + # Write updated header info if self._zinfo.flag_bits & _MASK_USE_DATA_DESCRIPTOR: # Write CRC and file sizes after the file data @@ -1189,13 +1235,6 @@ class _ZipWriteFile(io.BufferedIOBase): self._zinfo.compress_size, self._zinfo.file_size)) self._zipfile.start_dir = self._fileobj.tell() else: - if not self._zip64: - if self._file_size > ZIP64_LIMIT: - raise RuntimeError( - 'File size unexpectedly exceeded ZIP64 limit') - if self._compress_size > ZIP64_LIMIT: - raise RuntimeError( - 'Compressed size unexpectedly exceeded ZIP64 limit') # Seek backwards and write file header (which will now include # correct CRC and file sizes) @@ -1397,6 +1436,7 @@ class ZipFile: if self.debug > 2: print(centdir) filename = fp.read(centdir[_CD_FILENAME_LENGTH]) + orig_filename_crc = crc32(filename) flags = centdir[_CD_FLAG_BITS] if flags & _MASK_UTF_FILENAME: # UTF-8 file names extension @@ -1420,8 +1460,7 @@ class ZipFile: x._raw_time = t x.date_time = ( (d>>9)+1980, (d>>5)&0xF, d&0x1F, t>>11, (t>>5)&0x3F, (t&0x1F) * 2 ) - - x._decodeExtra() + x._decodeExtra(orig_filename_crc) x.header_offset = x.header_offset + concat self.filelist.append(x) self.NameToInfo[x.filename] = x @@ -1454,7 +1493,10 @@ class ZipFile: file=file) def testzip(self): - """Read all the files and check the CRC.""" + """Read all the files and check the CRC. + + Return None if all files could be read successfully, or the name + of the offending file otherwise.""" chunk_size = 2 ** 20 for zinfo in self.filelist: try: @@ -1566,7 +1608,7 @@ class ZipFile: fname = zef_file.read(fheader[_FH_FILENAME_LENGTH]) if fheader[_FH_EXTRA_FIELD_LENGTH]: - zef_file.read(fheader[_FH_EXTRA_FIELD_LENGTH]) + zef_file.seek(fheader[_FH_EXTRA_FIELD_LENGTH], whence=1) if zinfo.flag_bits & _MASK_COMPRESSED_PATCH: # Zip 2.7: compressed patched data @@ -1631,8 +1673,9 @@ class ZipFile: zinfo.external_attr = 0o600 << 16 # permissions: ?rw------- # Compressed size can be larger than uncompressed size - zip64 = self._allowZip64 and \ - (force_zip64 or zinfo.file_size * 1.05 > ZIP64_LIMIT) + zip64 = force_zip64 or (zinfo.file_size * 1.05 > ZIP64_LIMIT) + if not self._allowZip64 and zip64: + raise LargeZipFile("Filesize would require ZIP64 extensions") if self._seekable: self.fp.seek(self.start_dir) @@ -1685,8 +1728,8 @@ class ZipFile: table = str.maketrans(illegal, '_' * len(illegal)) cls._windows_illegal_name_trans_table = table arcname = arcname.translate(table) - # remove trailing dots - arcname = (x.rstrip('.') for x in arcname.split(pathsep)) + # remove trailing dots and spaces + arcname = (x.rstrip(' .') for x in arcname.split(pathsep)) # rejoin, removing empty parts. arcname = pathsep.join(x for x in arcname if x) return arcname @@ -1714,6 +1757,9 @@ class ZipFile: # filter illegal characters on Windows arcname = self._sanitize_windows_name(arcname, os.path.sep) + if not arcname: + raise ValueError("Empty filename.") + targetpath = os.path.join(targetpath, arcname) targetpath = os.path.normpath(targetpath) @@ -1803,7 +1849,7 @@ class ZipFile: date_time=time.localtime(time.time())[:6]) zinfo.compress_type = self.compression zinfo._compresslevel = self.compresslevel - if zinfo.filename[-1] == '/': + if zinfo.filename.endswith('/'): zinfo.external_attr = 0o40775 << 16 # drwxrwxr-x zinfo.external_attr |= 0x10 # MS-DOS directory flag else: @@ -2166,386 +2212,12 @@ class PyZipFile(ZipFile): return (fname, archivename) -def _parents(path): - """ - Given a path with elements separated by - posixpath.sep, generate all parents of that path. - - >>> list(_parents('b/d')) - ['b'] - >>> list(_parents('/b/d/')) - ['/b'] - >>> list(_parents('b/d/f/')) - ['b/d', 'b'] - >>> list(_parents('b')) - [] - >>> list(_parents('')) - [] - """ - return itertools.islice(_ancestry(path), 1, None) - - -def _ancestry(path): - """ - Given a path with elements separated by - posixpath.sep, generate all elements of that path - - >>> list(_ancestry('b/d')) - ['b/d', 'b'] - >>> list(_ancestry('/b/d/')) - ['/b/d', '/b'] - >>> list(_ancestry('b/d/f/')) - ['b/d/f', 'b/d', 'b'] - >>> list(_ancestry('b')) - ['b'] - >>> list(_ancestry('')) - [] - """ - path = path.rstrip(posixpath.sep) - while path and path != posixpath.sep: - yield path - path, tail = posixpath.split(path) - +from ._path import ( # noqa: E402 + Path, -_dedupe = dict.fromkeys -"""Deduplicate an iterable in original order""" - - -def _difference(minuend, subtrahend): - """ - Return items in minuend not in subtrahend, retaining order - with O(1) lookup. - """ - return itertools.filterfalse(set(subtrahend).__contains__, minuend) - - -class CompleteDirs(ZipFile): - """ - A ZipFile subclass that ensures that implied directories - are always included in the namelist. - """ - - @staticmethod - def _implied_dirs(names): - parents = itertools.chain.from_iterable(map(_parents, names)) - as_dirs = (p + posixpath.sep for p in parents) - return _dedupe(_difference(as_dirs, names)) - - def namelist(self): - names = super(CompleteDirs, self).namelist() - return names + list(self._implied_dirs(names)) - - def _name_set(self): - return set(self.namelist()) - - def resolve_dir(self, name): - """ - If the name represents a directory, return that name - as a directory (with the trailing slash). - """ - names = self._name_set() - dirname = name + '/' - dir_match = name not in names and dirname in names - return dirname if dir_match else name - - @classmethod - def make(cls, source): - """ - Given a source (filename or zipfile), return an - appropriate CompleteDirs subclass. - """ - if isinstance(source, CompleteDirs): - return source - - if not isinstance(source, ZipFile): - return cls(source) - - # Only allow for FastLookup when supplied zipfile is read-only - if 'r' not in source.mode: - cls = CompleteDirs - - source.__class__ = cls - return source - - -class FastLookup(CompleteDirs): - """ - ZipFile subclass to ensure implicit - dirs exist and are resolved rapidly. - """ - - def namelist(self): - with contextlib.suppress(AttributeError): - return self.__names - self.__names = super(FastLookup, self).namelist() - return self.__names - - def _name_set(self): - with contextlib.suppress(AttributeError): - return self.__lookup - self.__lookup = super(FastLookup, self)._name_set() - return self.__lookup - - -def _extract_text_encoding(encoding=None, *args, **kwargs): - # stacklevel=3 so that the caller of the caller see any warning. - return io.text_encoding(encoding, 3), args, kwargs - - -class Path: - """ - A pathlib-compatible interface for zip files. + # used privately for tests + CompleteDirs, # noqa: F401 +) - Consider a zip file with this structure:: - - . - ├── a.txt - └── b - ├── c.txt - └── d - └── e.txt - - >>> data = io.BytesIO() - >>> zf = ZipFile(data, 'w') - >>> zf.writestr('a.txt', 'content of a') - >>> zf.writestr('b/c.txt', 'content of c') - >>> zf.writestr('b/d/e.txt', 'content of e') - >>> zf.filename = 'mem/abcde.zip' - - Path accepts the zipfile object itself or a filename - - >>> root = Path(zf) - - From there, several path operations are available. - - Directory iteration (including the zip file itself): - - >>> a, b = root.iterdir() - >>> a - Path('mem/abcde.zip', 'a.txt') - >>> b - Path('mem/abcde.zip', 'b/') - - name property: - - >>> b.name - 'b' - - join with divide operator: - - >>> c = b / 'c.txt' - >>> c - Path('mem/abcde.zip', 'b/c.txt') - >>> c.name - 'c.txt' - - Read text: - - >>> c.read_text() - 'content of c' - - existence: - - >>> c.exists() - True - >>> (b / 'missing.txt').exists() - False - - Coercion to string: - - >>> import os - >>> str(c).replace(os.sep, posixpath.sep) - 'mem/abcde.zip/b/c.txt' - - At the root, ``name``, ``filename``, and ``parent`` - resolve to the zipfile. Note these attributes are not - valid and will raise a ``ValueError`` if the zipfile - has no filename. - - >>> root.name - 'abcde.zip' - >>> str(root.filename).replace(os.sep, posixpath.sep) - 'mem/abcde.zip' - >>> str(root.parent) - 'mem' - """ - - __repr = "{self.__class__.__name__}({self.root.filename!r}, {self.at!r})" - - def __init__(self, root, at=""): - """ - Construct a Path from a ZipFile or filename. - - Note: When the source is an existing ZipFile object, - its type (__class__) will be mutated to a - specialized type. If the caller wishes to retain the - original type, the caller should either create a - separate ZipFile object or pass a filename. - """ - self.root = FastLookup.make(root) - self.at = at - - def open(self, mode='r', *args, pwd=None, **kwargs): - """ - Open this entry as text or binary following the semantics - of ``pathlib.Path.open()`` by passing arguments through - to io.TextIOWrapper(). - """ - if self.is_dir(): - raise IsADirectoryError(self) - zip_mode = mode[0] - if not self.exists() and zip_mode == 'r': - raise FileNotFoundError(self) - stream = self.root.open(self.at, zip_mode, pwd=pwd) - if 'b' in mode: - if args or kwargs: - raise ValueError("encoding args invalid for binary operation") - return stream - # Text mode: - encoding, args, kwargs = _extract_text_encoding(*args, **kwargs) - return io.TextIOWrapper(stream, encoding, *args, **kwargs) - - @property - def name(self): - return pathlib.Path(self.at).name or self.filename.name - - @property - def suffix(self): - return pathlib.Path(self.at).suffix or self.filename.suffix - - @property - def suffixes(self): - return pathlib.Path(self.at).suffixes or self.filename.suffixes - - @property - def stem(self): - return pathlib.Path(self.at).stem or self.filename.stem - - @property - def filename(self): - return pathlib.Path(self.root.filename).joinpath(self.at) - - def read_text(self, *args, **kwargs): - encoding, args, kwargs = _extract_text_encoding(*args, **kwargs) - with self.open('r', encoding, *args, **kwargs) as strm: - return strm.read() - - def read_bytes(self): - with self.open('rb') as strm: - return strm.read() - - def _is_child(self, path): - return posixpath.dirname(path.at.rstrip("/")) == self.at.rstrip("/") - - def _next(self, at): - return self.__class__(self.root, at) - - def is_dir(self): - return not self.at or self.at.endswith("/") - - def is_file(self): - return self.exists() and not self.is_dir() - - def exists(self): - return self.at in self.root._name_set() - - def iterdir(self): - if not self.is_dir(): - raise ValueError("Can't listdir a file") - subs = map(self._next, self.root.namelist()) - return filter(self._is_child, subs) - - def __str__(self): - return posixpath.join(self.root.filename, self.at) - - def __repr__(self): - return self.__repr.format(self=self) - - def joinpath(self, *other): - next = posixpath.join(self.at, *other) - return self._next(self.root.resolve_dir(next)) - - __truediv__ = joinpath - - @property - def parent(self): - if not self.at: - return self.filename.parent - parent_at = posixpath.dirname(self.at.rstrip('/')) - if parent_at: - parent_at += '/' - return self._next(parent_at) - - -def main(args=None): - import argparse - - description = 'A simple command-line interface for zipfile module.' - parser = argparse.ArgumentParser(description=description) - group = parser.add_mutually_exclusive_group(required=True) - group.add_argument('-l', '--list', metavar='<zipfile>', - help='Show listing of a zipfile') - group.add_argument('-e', '--extract', nargs=2, - metavar=('<zipfile>', '<output_dir>'), - help='Extract zipfile into target dir') - group.add_argument('-c', '--create', nargs='+', - metavar=('<name>', '<file>'), - help='Create zipfile from sources') - group.add_argument('-t', '--test', metavar='<zipfile>', - help='Test if a zipfile is valid') - parser.add_argument('--metadata-encoding', metavar='<encoding>', - help='Specify encoding of member names for -l, -e and -t') - args = parser.parse_args(args) - - encoding = args.metadata_encoding - - if args.test is not None: - src = args.test - with ZipFile(src, 'r', metadata_encoding=encoding) as zf: - badfile = zf.testzip() - if badfile: - print("The following enclosed file is corrupted: {!r}".format(badfile)) - print("Done testing") - - elif args.list is not None: - src = args.list - with ZipFile(src, 'r', metadata_encoding=encoding) as zf: - zf.printdir() - - elif args.extract is not None: - src, curdir = args.extract - with ZipFile(src, 'r', metadata_encoding=encoding) as zf: - zf.extractall(curdir) - - elif args.create is not None: - if encoding: - print("Non-conforming encodings not supported with -c.", - file=sys.stderr) - sys.exit(1) - - zip_name = args.create.pop(0) - files = args.create - - def addToZip(zf, path, zippath): - if os.path.isfile(path): - zf.write(path, zippath, ZIP_DEFLATED) - elif os.path.isdir(path): - if zippath: - zf.write(path, zippath) - for nm in sorted(os.listdir(path)): - addToZip(zf, - os.path.join(path, nm), os.path.join(zippath, nm)) - # else: ignore - - with ZipFile(zip_name, 'w') as zf: - for path in files: - zippath = os.path.basename(path) - if not zippath: - zippath = os.path.basename(os.path.dirname(path)) - if zippath in ('', os.curdir, os.pardir): - zippath = '' - addToZip(zf, path, zippath) - - -if __name__ == "__main__": - main() +# used privately for tests +from .__main__ import main # noqa: F401, E402 diff --git a/Lib/zipfile/__main__.py b/Lib/zipfile/__main__.py new file mode 100644 index 00000000..a9e5fb1b --- /dev/null +++ b/Lib/zipfile/__main__.py @@ -0,0 +1,77 @@ +import sys +import os +from . import ZipFile, ZIP_DEFLATED + + +def main(args=None): + import argparse + + description = 'A simple command-line interface for zipfile module.' + parser = argparse.ArgumentParser(description=description) + group = parser.add_mutually_exclusive_group(required=True) + group.add_argument('-l', '--list', metavar='<zipfile>', + help='Show listing of a zipfile') + group.add_argument('-e', '--extract', nargs=2, + metavar=('<zipfile>', '<output_dir>'), + help='Extract zipfile into target dir') + group.add_argument('-c', '--create', nargs='+', + metavar=('<name>', '<file>'), + help='Create zipfile from sources') + group.add_argument('-t', '--test', metavar='<zipfile>', + help='Test if a zipfile is valid') + parser.add_argument('--metadata-encoding', metavar='<encoding>', + help='Specify encoding of member names for -l, -e and -t') + args = parser.parse_args(args) + + encoding = args.metadata_encoding + + if args.test is not None: + src = args.test + with ZipFile(src, 'r', metadata_encoding=encoding) as zf: + badfile = zf.testzip() + if badfile: + print("The following enclosed file is corrupted: {!r}".format(badfile)) + print("Done testing") + + elif args.list is not None: + src = args.list + with ZipFile(src, 'r', metadata_encoding=encoding) as zf: + zf.printdir() + + elif args.extract is not None: + src, curdir = args.extract + with ZipFile(src, 'r', metadata_encoding=encoding) as zf: + zf.extractall(curdir) + + elif args.create is not None: + if encoding: + print("Non-conforming encodings not supported with -c.", + file=sys.stderr) + sys.exit(1) + + zip_name = args.create.pop(0) + files = args.create + + def addToZip(zf, path, zippath): + if os.path.isfile(path): + zf.write(path, zippath, ZIP_DEFLATED) + elif os.path.isdir(path): + if zippath: + zf.write(path, zippath) + for nm in sorted(os.listdir(path)): + addToZip(zf, + os.path.join(path, nm), os.path.join(zippath, nm)) + # else: ignore + + with ZipFile(zip_name, 'w') as zf: + for path in files: + zippath = os.path.basename(path) + if not zippath: + zippath = os.path.basename(os.path.dirname(path)) + if zippath in ('', os.curdir, os.pardir): + zippath = '' + addToZip(zf, path, zippath) + + +if __name__ == "__main__": + main() diff --git a/Lib/zipfile/_path/__init__.py b/Lib/zipfile/_path/__init__.py new file mode 100644 index 00000000..78c41356 --- /dev/null +++ b/Lib/zipfile/_path/__init__.py @@ -0,0 +1,395 @@ +import io +import posixpath +import zipfile +import itertools +import contextlib +import pathlib +import re + +from .glob import translate + + +__all__ = ['Path'] + + +def _parents(path): + """ + Given a path with elements separated by + posixpath.sep, generate all parents of that path. + + >>> list(_parents('b/d')) + ['b'] + >>> list(_parents('/b/d/')) + ['/b'] + >>> list(_parents('b/d/f/')) + ['b/d', 'b'] + >>> list(_parents('b')) + [] + >>> list(_parents('')) + [] + """ + return itertools.islice(_ancestry(path), 1, None) + + +def _ancestry(path): + """ + Given a path with elements separated by + posixpath.sep, generate all elements of that path + + >>> list(_ancestry('b/d')) + ['b/d', 'b'] + >>> list(_ancestry('/b/d/')) + ['/b/d', '/b'] + >>> list(_ancestry('b/d/f/')) + ['b/d/f', 'b/d', 'b'] + >>> list(_ancestry('b')) + ['b'] + >>> list(_ancestry('')) + [] + """ + path = path.rstrip(posixpath.sep) + while path and path != posixpath.sep: + yield path + path, tail = posixpath.split(path) + + +_dedupe = dict.fromkeys +"""Deduplicate an iterable in original order""" + + +def _difference(minuend, subtrahend): + """ + Return items in minuend not in subtrahend, retaining order + with O(1) lookup. + """ + return itertools.filterfalse(set(subtrahend).__contains__, minuend) + + +class InitializedState: + """ + Mix-in to save the initialization state for pickling. + """ + + def __init__(self, *args, **kwargs): + self.__args = args + self.__kwargs = kwargs + super().__init__(*args, **kwargs) + + def __getstate__(self): + return self.__args, self.__kwargs + + def __setstate__(self, state): + args, kwargs = state + super().__init__(*args, **kwargs) + + +class CompleteDirs(InitializedState, zipfile.ZipFile): + """ + A ZipFile subclass that ensures that implied directories + are always included in the namelist. + + >>> list(CompleteDirs._implied_dirs(['foo/bar.txt', 'foo/bar/baz.txt'])) + ['foo/', 'foo/bar/'] + >>> list(CompleteDirs._implied_dirs(['foo/bar.txt', 'foo/bar/baz.txt', 'foo/bar/'])) + ['foo/'] + """ + + @staticmethod + def _implied_dirs(names): + parents = itertools.chain.from_iterable(map(_parents, names)) + as_dirs = (p + posixpath.sep for p in parents) + return _dedupe(_difference(as_dirs, names)) + + def namelist(self): + names = super().namelist() + return names + list(self._implied_dirs(names)) + + def _name_set(self): + return set(self.namelist()) + + def resolve_dir(self, name): + """ + If the name represents a directory, return that name + as a directory (with the trailing slash). + """ + names = self._name_set() + dirname = name + '/' + dir_match = name not in names and dirname in names + return dirname if dir_match else name + + def getinfo(self, name): + """ + Supplement getinfo for implied dirs. + """ + try: + return super().getinfo(name) + except KeyError: + if not name.endswith('/') or name not in self._name_set(): + raise + return zipfile.ZipInfo(filename=name) + + @classmethod + def make(cls, source): + """ + Given a source (filename or zipfile), return an + appropriate CompleteDirs subclass. + """ + if isinstance(source, CompleteDirs): + return source + + if not isinstance(source, zipfile.ZipFile): + return cls(source) + + # Only allow for FastLookup when supplied zipfile is read-only + if 'r' not in source.mode: + cls = CompleteDirs + + source.__class__ = cls + return source + + +class FastLookup(CompleteDirs): + """ + ZipFile subclass to ensure implicit + dirs exist and are resolved rapidly. + """ + + def namelist(self): + with contextlib.suppress(AttributeError): + return self.__names + self.__names = super().namelist() + return self.__names + + def _name_set(self): + with contextlib.suppress(AttributeError): + return self.__lookup + self.__lookup = super()._name_set() + return self.__lookup + + +def _extract_text_encoding(encoding=None, *args, **kwargs): + # stacklevel=3 so that the caller of the caller see any warning. + return io.text_encoding(encoding, 3), args, kwargs + + +class Path: + """ + A pathlib-compatible interface for zip files. + + Consider a zip file with this structure:: + + . + ├── a.txt + └── b + ├── c.txt + └── d + └── e.txt + + >>> data = io.BytesIO() + >>> zf = ZipFile(data, 'w') + >>> zf.writestr('a.txt', 'content of a') + >>> zf.writestr('b/c.txt', 'content of c') + >>> zf.writestr('b/d/e.txt', 'content of e') + >>> zf.filename = 'mem/abcde.zip' + + Path accepts the zipfile object itself or a filename + + >>> root = Path(zf) + + From there, several path operations are available. + + Directory iteration (including the zip file itself): + + >>> a, b = root.iterdir() + >>> a + Path('mem/abcde.zip', 'a.txt') + >>> b + Path('mem/abcde.zip', 'b/') + + name property: + + >>> b.name + 'b' + + join with divide operator: + + >>> c = b / 'c.txt' + >>> c + Path('mem/abcde.zip', 'b/c.txt') + >>> c.name + 'c.txt' + + Read text: + + >>> c.read_text(encoding='utf-8') + 'content of c' + + existence: + + >>> c.exists() + True + >>> (b / 'missing.txt').exists() + False + + Coercion to string: + + >>> import os + >>> str(c).replace(os.sep, posixpath.sep) + 'mem/abcde.zip/b/c.txt' + + At the root, ``name``, ``filename``, and ``parent`` + resolve to the zipfile. Note these attributes are not + valid and will raise a ``ValueError`` if the zipfile + has no filename. + + >>> root.name + 'abcde.zip' + >>> str(root.filename).replace(os.sep, posixpath.sep) + 'mem/abcde.zip' + >>> str(root.parent) + 'mem' + """ + + __repr = "{self.__class__.__name__}({self.root.filename!r}, {self.at!r})" + + def __init__(self, root, at=""): + """ + Construct a Path from a ZipFile or filename. + + Note: When the source is an existing ZipFile object, + its type (__class__) will be mutated to a + specialized type. If the caller wishes to retain the + original type, the caller should either create a + separate ZipFile object or pass a filename. + """ + self.root = FastLookup.make(root) + self.at = at + + def __eq__(self, other): + """ + >>> Path(zipfile.ZipFile(io.BytesIO(), 'w')) == 'foo' + False + """ + if self.__class__ is not other.__class__: + return NotImplemented + return (self.root, self.at) == (other.root, other.at) + + def __hash__(self): + return hash((self.root, self.at)) + + def open(self, mode='r', *args, pwd=None, **kwargs): + """ + Open this entry as text or binary following the semantics + of ``pathlib.Path.open()`` by passing arguments through + to io.TextIOWrapper(). + """ + if self.is_dir(): + raise IsADirectoryError(self) + zip_mode = mode[0] + if not self.exists() and zip_mode == 'r': + raise FileNotFoundError(self) + stream = self.root.open(self.at, zip_mode, pwd=pwd) + if 'b' in mode: + if args or kwargs: + raise ValueError("encoding args invalid for binary operation") + return stream + # Text mode: + encoding, args, kwargs = _extract_text_encoding(*args, **kwargs) + return io.TextIOWrapper(stream, encoding, *args, **kwargs) + + def _base(self): + return pathlib.PurePosixPath(self.at or self.root.filename) + + @property + def name(self): + return self._base().name + + @property + def suffix(self): + return self._base().suffix + + @property + def suffixes(self): + return self._base().suffixes + + @property + def stem(self): + return self._base().stem + + @property + def filename(self): + return pathlib.Path(self.root.filename).joinpath(self.at) + + def read_text(self, *args, **kwargs): + encoding, args, kwargs = _extract_text_encoding(*args, **kwargs) + with self.open('r', encoding, *args, **kwargs) as strm: + return strm.read() + + def read_bytes(self): + with self.open('rb') as strm: + return strm.read() + + def _is_child(self, path): + return posixpath.dirname(path.at.rstrip("/")) == self.at.rstrip("/") + + def _next(self, at): + return self.__class__(self.root, at) + + def is_dir(self): + return not self.at or self.at.endswith("/") + + def is_file(self): + return self.exists() and not self.is_dir() + + def exists(self): + return self.at in self.root._name_set() + + def iterdir(self): + if not self.is_dir(): + raise ValueError("Can't listdir a file") + subs = map(self._next, self.root.namelist()) + return filter(self._is_child, subs) + + def match(self, path_pattern): + return pathlib.PurePosixPath(self.at).match(path_pattern) + + def is_symlink(self): + """ + Return whether this path is a symlink. Always false (python/cpython#82102). + """ + return False + + def glob(self, pattern): + if not pattern: + raise ValueError(f"Unacceptable pattern: {pattern!r}") + + prefix = re.escape(self.at) + matches = re.compile(prefix + translate(pattern)).fullmatch + return map(self._next, filter(matches, self.root.namelist())) + + def rglob(self, pattern): + return self.glob(f'**/{pattern}') + + def relative_to(self, other, *extra): + return posixpath.relpath(str(self), str(other.joinpath(*extra))) + + def __str__(self): + return posixpath.join(self.root.filename, self.at) + + def __repr__(self): + return self.__repr.format(self=self) + + def joinpath(self, *other): + next = posixpath.join(self.at, *other) + return self._next(self.root.resolve_dir(next)) + + __truediv__ = joinpath + + @property + def parent(self): + if not self.at: + return self.filename.parent + parent_at = posixpath.dirname(self.at.rstrip('/')) + if parent_at: + parent_at += '/' + return self._next(parent_at) diff --git a/Lib/zipfile/_path/glob.py b/Lib/zipfile/_path/glob.py new file mode 100644 index 00000000..4a2e665e --- /dev/null +++ b/Lib/zipfile/_path/glob.py @@ -0,0 +1,40 @@ +import re + + +def translate(pattern): + r""" + Given a glob pattern, produce a regex that matches it. + + >>> translate('*.txt') + '[^/]*\\.txt' + >>> translate('a?txt') + 'a.txt' + >>> translate('**/*') + '.*/[^/]*' + """ + return ''.join(map(replace, separate(pattern))) + + +def separate(pattern): + """ + Separate out character sets to avoid translating their contents. + + >>> [m.group(0) for m in separate('*.txt')] + ['*.txt'] + >>> [m.group(0) for m in separate('a[?]txt')] + ['a', '[?]', 'txt'] + """ + return re.finditer(r'([^\[]+)|(?P<set>[\[].*?[\]])|([\[][^\]]*$)', pattern) + + +def replace(match): + """ + Perform the replacements for a match from :func:`separate`. + """ + + return match.group('set') or ( + re.escape(match.group(0)) + .replace('\\*\\*', r'.*') + .replace('\\*', r'[^/]*') + .replace('\\?', r'.') + ) diff --git a/Lib/zipimport.py b/Lib/zipimport.py index e9da8be5..a7333a4c 100644 --- a/Lib/zipimport.py +++ b/Lib/zipimport.py @@ -101,64 +101,6 @@ class zipimporter(_bootstrap_external._LoaderBasics): self.prefix += path_sep - # Check whether we can satisfy the import of the module named by - # 'fullname', or whether it could be a portion of a namespace - # package. Return self if we can load it, a string containing the - # full path if it's a possible namespace portion, None if we - # can't load it. - def find_loader(self, fullname, path=None): - """find_loader(fullname, path=None) -> self, str or None. - - Search for a module specified by 'fullname'. 'fullname' must be the - fully qualified (dotted) module name. It returns the zipimporter - instance itself if the module was found, a string containing the - full path name if it's possibly a portion of a namespace package, - or None otherwise. The optional 'path' argument is ignored -- it's - there for compatibility with the importer protocol. - - Deprecated since Python 3.10. Use find_spec() instead. - """ - _warnings.warn("zipimporter.find_loader() is deprecated and slated for " - "removal in Python 3.12; use find_spec() instead", - DeprecationWarning) - mi = _get_module_info(self, fullname) - if mi is not None: - # This is a module or package. - return self, [] - - # Not a module or regular package. See if this is a directory, and - # therefore possibly a portion of a namespace package. - - # We're only interested in the last path component of fullname - # earlier components are recorded in self.prefix. - modpath = _get_module_path(self, fullname) - if _is_dir(self, modpath): - # This is possibly a portion of a namespace - # package. Return the string representing its path, - # without a trailing separator. - return None, [f'{self.archive}{path_sep}{modpath}'] - - return None, [] - - - # Check whether we can satisfy the import of the module named by - # 'fullname'. Return self if we can, None if we can't. - def find_module(self, fullname, path=None): - """find_module(fullname, path=None) -> self or None. - - Search for a module specified by 'fullname'. 'fullname' must be the - fully qualified (dotted) module name. It returns the zipimporter - instance itself if the module was found, or None if it wasn't. - The optional 'path' argument is ignored -- it's there for compatibility - with the importer protocol. - - Deprecated since Python 3.10. Use find_spec() instead. - """ - _warnings.warn("zipimporter.find_module() is deprecated and slated for " - "removal in Python 3.12; use find_spec() instead", - DeprecationWarning) - return self.find_loader(fullname, path)[0] - def find_spec(self, fullname, target=None): """Create a ModuleSpec for the specified module. diff --git a/Lib/zoneinfo/_zoneinfo.py b/Lib/zoneinfo/_zoneinfo.py index de683807..eede15b8 100644 --- a/Lib/zoneinfo/_zoneinfo.py +++ b/Lib/zoneinfo/_zoneinfo.py @@ -302,7 +302,7 @@ class ZoneInfo(tzinfo): # difference between utcoffset() and the "standard" offset, but # the "base offset" and "DST offset" are not encoded in the file; # we can infer what they are from the isdst flag, but it is not - # sufficient to to just look at the last standard offset, because + # sufficient to just look at the last standard offset, because # occasionally countries will shift both DST offset and base offset. typecnt = len(isdsts) diff --git a/Mac/BuildScript/build-installer.py b/Mac/BuildScript/build-installer.py index f756a994..c54de880 100755 --- a/Mac/BuildScript/build-installer.py +++ b/Mac/BuildScript/build-installer.py @@ -203,7 +203,7 @@ def internalTk(): # Do we use 8.6.8 when building our own copy # of Tcl/Tk or a modern version. -# We use the old version when buildin on +# We use the old version when building on # old versions of macOS due to build issues. def useOldTk(): return getBuildTuple() < (10, 15) @@ -246,9 +246,9 @@ def library_recipes(): result.extend([ dict( - name="OpenSSL 1.1.1s", - url="https://www.openssl.org/source/openssl-1.1.1s.tar.gz", - checksum='c5ac01e760ee6ff0dab61d6b2bbd30146724d063eb322180c6f18a6f74e4b6aa', + name="OpenSSL 3.0.11", + url="https://www.openssl.org/source/openssl-3.0.11.tar.gz", + checksum='b3425d3bb4a2218d0697eb41f7fc0cdede016ed19ca49d168b78e8d947887f55', buildrecipe=build_universal_openssl, configure=None, install=None, @@ -264,17 +264,18 @@ def library_recipes(): tk_patches = ['tk868_on_10_8_10_9.patch'] else: - tcl_tk_ver='8.6.12' - tcl_checksum='87ea890821d2221f2ab5157bc5eb885f' + tcl_tk_ver='8.6.13' + tcl_checksum='43a1fae7412f61ff11de2cfd05d28cfc3a73762f354a417c62370a54e2caf066' - tk_checksum='1d6dcf6120356e3d211e056dff5e462a' + tk_checksum='2e65fa069a23365440a3c56c556b8673b5e32a283800d8d9b257e3f584ce0675' tk_patches = [ ] + base_url = "https://prdownloads.sourceforge.net/tcl/{what}{version}-src.tar.gz" result.extend([ dict( name="Tcl %s"%(tcl_tk_ver,), - url="ftp://ftp.tcl.tk/pub/tcl//tcl8_6/tcl%s-src.tar.gz"%(tcl_tk_ver,), + url=base_url.format(what="tcl", version=tcl_tk_ver), checksum=tcl_checksum, buildDir="unix", configure_pre=[ @@ -291,7 +292,7 @@ def library_recipes(): ), dict( name="Tk %s"%(tcl_tk_ver,), - url="ftp://ftp.tcl.tk/pub/tcl//tcl8_6/tk%s-src.tar.gz"%(tcl_tk_ver,), + url=base_url.format(what="tk", version=tcl_tk_ver), checksum=tk_checksum, patches=tk_patches, buildDir="unix", @@ -358,9 +359,9 @@ def library_recipes(): ), ), dict( - name="SQLite 3.39.4", - url="https://sqlite.org/2022/sqlite-autoconf-3390400.tar.gz", - checksum="44b7e6691b0954086f717a6c43b622a5", + name="SQLite 3.42.0", + url="https://sqlite.org/2023/sqlite-autoconf-3420000.tar.gz", + checksum="0c5a92bc51cf07cae45b4a1e94653dea", extra_cflags=('-Os ' '-DSQLITE_ENABLE_FTS5 ' '-DSQLITE_ENABLE_FTS4 ' @@ -1357,7 +1358,7 @@ def buildPython(): build_time_vars = l_dict['build_time_vars'] vars = {} for k, v in build_time_vars.items(): - if type(v) == type(''): + if isinstance(v, str): for p in (include_path, lib_path): v = v.replace(' ' + p, '') v = v.replace(p + ' ', '') diff --git a/Mac/BuildScript/resources/ReadMe.rtf b/Mac/BuildScript/resources/ReadMe.rtf index 2d6ca8f2..384840cd 100644 --- a/Mac/BuildScript/resources/ReadMe.rtf +++ b/Mac/BuildScript/resources/ReadMe.rtf @@ -1,4 +1,4 @@ -{\rtf1\ansi\ansicpg1252\cocoartf2639 +{\rtf1\ansi\ansicpg1252\cocoartf2709 \cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fswiss\fcharset0 Helvetica;\f1\fswiss\fcharset0 Helvetica-Bold;\f2\fswiss\fcharset0 Helvetica-Oblique; \f3\fmodern\fcharset0 CourierNewPSMT;\f4\fmodern\fcharset0 Courier;} {\colortbl;\red255\green255\blue255;} @@ -13,14 +13,14 @@ \f1\b \cf0 \ul \ulc0 Certificate verification and OpenSSL\ \f0\b0 \ulnone \ -This package includes its own private copy of OpenSSL 1.1.1. The trust certificates in system and user keychains managed by the +This package includes its own private copy of OpenSSL 3.0. The trust certificates in system and user keychains managed by the \f2\i Keychain Access \f0\i0 application and the \f2\i security \f0\i0 command line utility are not used as defaults by the Python \f3 ssl \f0 module. A sample command script is included in -\f3 /Applications/Python 3.11 +\f3 /Applications/Python 3.12 \f0 to install a curated bundle of default root certificates from the third-party \f3 certifi \f0 package ({\field{\*\fldinst{HYPERLINK "https://pypi.org/project/certifi/"}}{\fldrslt https://pypi.org/project/certifi/}}). Double-click on diff --git a/Mac/BuildScript/resources/Welcome.rtf b/Mac/BuildScript/resources/Welcome.rtf index 4a0dac36..8ae9b01b 100644 --- a/Mac/BuildScript/resources/Welcome.rtf +++ b/Mac/BuildScript/resources/Welcome.rtf @@ -1,9 +1,9 @@ -{\rtf1\ansi\ansicpg1252\cocoartf2639 +{\rtf1\ansi\ansicpg1252\cocoartf2709 \cocoascreenfonts1\cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fswiss\fcharset0 Helvetica;\f1\fswiss\fcharset0 Helvetica-Bold;\f2\fmodern\fcharset0 CourierNewPSMT; } {\colortbl;\red255\green255\blue255;} {\*\expandedcolortbl;;} -\paperw11905\paperh16837\margl1440\margr1440\vieww12200\viewh10880\viewkind0 +\margl1440\margr1440\vieww12200\viewh10880\viewkind0 \pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\partightenfactor0 \f0\fs24 \cf0 This package will install diff --git a/Mac/BuildScript/scripts/postflight.ensurepip b/Mac/BuildScript/scripts/postflight.ensurepip index 36d05945..ce3c6c1c 100755 --- a/Mac/BuildScript/scripts/postflight.ensurepip +++ b/Mac/BuildScript/scripts/postflight.ensurepip @@ -56,19 +56,19 @@ if [ -d /usr/local/bin ] ; then cd /usr/local/bin - # Create pipx.y and easy_install-x.y links if /usr/local/bin/pythonx.y + # Create pipx.y links if /usr/local/bin/pythonx.y # is linked to this framework version install_links_if_our_fw "python${PYVER}" \ - "pip${PYVER}" "easy_install-${PYVER}" + "pip${PYVER}" # Create pipx link if /usr/local/bin/pythonx is linked to this version install_links_if_our_fw "python${PYMAJOR}" \ "pip${PYMAJOR}" - # Create pip and easy_install link if /usr/local/bin/python + # Create pip link if /usr/local/bin/python # is linked to this version install_links_if_our_fw "python" \ - "pip" "easy_install" + "pip" ) fi exit 0 diff --git a/Mac/BuildScript/scripts/postflight.framework b/Mac/BuildScript/scripts/postflight.framework index 0f2e52c4..a6390935 100755 --- a/Mac/BuildScript/scripts/postflight.framework +++ b/Mac/BuildScript/scripts/postflight.framework @@ -8,12 +8,12 @@ FWK="/Library/Frameworks/Python.framework/Versions/@PYVER@" "${FWK}/bin/python@PYVER@" -E -s -Wi \ "${FWK}/lib/python${PYVER}/compileall.py" -q -j0 \ - -f -x 'bad_coding|badsyntax|site-packages|lib2to3/tests/data' \ + -f -x 'bad_coding|badsyntax|site-packages|test/test_lib2to3/data' \ "${FWK}/lib/python${PYVER}" "${FWK}/bin/python@PYVER@" -E -s -Wi -O \ "${FWK}/lib/python${PYVER}/compileall.py" -q -j0 \ - -f -x 'bad_coding|badsyntax|site-packages|lib2to3/tests/data' \ + -f -x 'bad_coding|badsyntax|site-packages|test/test_lib2to3/data' \ "${FWK}/lib/python${PYVER}" "${FWK}/bin/python@PYVER@" -E -s -Wi \ diff --git a/Mac/Makefile.in b/Mac/Makefile.in index f9691288..69ab4198 100644 --- a/Mac/Makefile.in +++ b/Mac/Makefile.in @@ -166,7 +166,6 @@ altinstallunixtools: -if test "x$(ENSUREPIP)" != "xno" ; then \ cd "$(DESTDIR)$(FRAMEWORKUNIXTOOLSPREFIX)/bin" && \ for fn in \ - easy_install-$(VERSION) \ pip$(VERSION) \ ; \ do \ diff --git a/Mac/Tools/pythonw.c b/Mac/Tools/pythonw.c index 78813e81..9dfb77f6 100644 --- a/Mac/Tools/pythonw.c +++ b/Mac/Tools/pythonw.c @@ -27,7 +27,6 @@ #include <err.h> #include <dlfcn.h> #include <stdlib.h> -#include <Python.h> #include <mach-o/dyld.h> diff --git a/Makefile.pre.in b/Makefile.pre.in index b356f629..09ceccda 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -36,7 +36,6 @@ abs_builddir= @abs_builddir@ CC= @CC@ CXX= @CXX@ -MAINCC= @MAINCC@ LINKCC= @LINKCC@ AR= @AR@ READELF= @READELF@ @@ -55,11 +54,13 @@ DTRACE= @DTRACE@ DFLAGS= @DFLAGS@ DTRACE_HEADERS= @DTRACE_HEADERS@ DTRACE_OBJS= @DTRACE_OBJS@ +DSYMUTIL= @DSYMUTIL@ +DSYMUTIL_PATH= @DSYMUTIL_PATH@ GNULD= @GNULD@ # Shell used by make (some versions default to the login shell, which is bad) -SHELL= /bin/sh +SHELL= /bin/sh -e # Use this to make a link between python$(VERSION) and python in $(BINDIR) LN= @LN@ @@ -150,6 +151,8 @@ CONFINCLUDEDIR= $(exec_prefix)/include PLATLIBDIR= @PLATLIBDIR@ SCRIPTDIR= $(prefix)/$(PLATLIBDIR) ABIFLAGS= @ABIFLAGS@ +# executable name for shebangs +EXENAME= $(BINDIR)/python$(LDVERSION)$(EXE) # Variable used by ensurepip WHEEL_PKG_DIR= @WHEEL_PKG_DIR@ @@ -196,9 +199,6 @@ LIPO_32BIT_FLAGS=@LIPO_32BIT_FLAGS@ # Flags to lipo to produce an intel-64-only universal executable LIPO_INTEL64_FLAGS=@LIPO_INTEL64_FLAGS@ -# Options to enable prebinding (for fast startup prior to Mac OS X 10.3) -OTHER_LIBTOOL_OPT=@OTHER_LIBTOOL_OPT@ - # Environment to run shared python without installed libraries RUNSHARED= @RUNSHARED@ @@ -208,12 +208,7 @@ ENSUREPIP= @ENSUREPIP@ # Internal static libraries LIBMPDEC_A= Modules/_decimal/libmpdec/libmpdec.a LIBEXPAT_A= Modules/expat/libexpat.a - -# OpenSSL options for setup.py so sysconfig can pick up AC_SUBST() vars. -OPENSSL_INCLUDES=@OPENSSL_INCLUDES@ -OPENSSL_LIBS=@OPENSSL_LIBS@ -OPENSSL_LDFLAGS=@OPENSSL_LDFLAGS@ -OPENSSL_RPATH=@OPENSSL_RPATH@ +LIBHACL_SHA2_A= Modules/_hacl/libHacl_Hash_SHA2.a # Module state, compiler flags and linker flags # Empty CFLAGS and LDFLAGS are omitted. @@ -288,7 +283,7 @@ BUILDPYTHON= python$(BUILDEXE) HOSTRUNNER= @HOSTRUNNER@ PYTHON_FOR_REGEN?=@PYTHON_FOR_REGEN@ -UPDATE_FILE=$(PYTHON_FOR_REGEN) $(srcdir)/Tools/scripts/update_file.py +UPDATE_FILE=$(PYTHON_FOR_REGEN) $(srcdir)/Tools/build/update_file.py PYTHON_FOR_BUILD=@PYTHON_FOR_BUILD@ # Single-platform builds depend on $(BUILDPYTHON). Cross builds use an # external "build Python" and have an empty PYTHON_FOR_BUILD_DEPS. @@ -341,10 +336,6 @@ IO_OBJS= \ Modules/_io/bytesio.o \ Modules/_io/stringio.o -########################################################################## - -LIBFFI_INCLUDEDIR= @LIBFFI_INCLUDEDIR@ - ########################################################################## # Parser @@ -379,6 +370,7 @@ PYTHON_OBJS= \ Python/Python-ast.o \ Python/Python-tokenize.o \ Python/asdl.o \ + Python/assemble.o \ Python/ast.o \ Python/ast_opt.o \ Python/ast_unparse.o \ @@ -389,6 +381,7 @@ PYTHON_OBJS= \ Python/context.o \ Python/dynamic_annotations.o \ Python/errors.o \ + Python/flowgraph.o \ Python/frame.o \ Python/frozenmain.o \ Python/future.o \ @@ -397,11 +390,15 @@ PYTHON_OBJS= \ Python/getcopyright.o \ Python/getplatform.o \ Python/getversion.o \ + Python/ceval_gil.o \ Python/hamt.o \ Python/hashtable.o \ Python/import.o \ Python/importdl.o \ Python/initconfig.o \ + Python/instrumentation.o \ + Python/intrinsics.o \ + Python/legacy_tracing.o \ Python/marshal.o \ Python/modsupport.o \ Python/mysnprintf.o \ @@ -424,6 +421,7 @@ PYTHON_OBJS= \ Python/sysmodule.o \ Python/thread.o \ Python/traceback.o \ + Python/tracemalloc.o \ Python/getopt.o \ Python/pystrcmp.o \ Python/pystrtod.o \ @@ -432,6 +430,7 @@ PYTHON_OBJS= \ Python/formatter_unicode.o \ Python/fileutils.o \ Python/suggestions.o \ + Python/perf_trampoline.o \ Python/$(DYNLOADFILE) \ $(LIBOBJS) \ $(MACHDEP_OBJS) \ @@ -443,7 +442,6 @@ PYTHON_OBJS= \ # Objects OBJECT_OBJS= \ Objects/abstract.o \ - Objects/accu.o \ Objects/boolobject.o \ Objects/bytes_methods.o \ Objects/bytearrayobject.o \ @@ -482,11 +480,14 @@ OBJECT_OBJS= \ Objects/structseq.o \ Objects/tupleobject.o \ Objects/typeobject.o \ + Objects/typevarobject.o \ Objects/unicodeobject.o \ Objects/unicodectype.o \ Objects/unionobject.o \ - Objects/weakrefobject.o + Objects/weakrefobject.o \ + @PERF_TRAMPOLINE_OBJ@ +DEEPFREEZE_C = Python/deepfreeze/deepfreeze.c DEEPFREEZE_OBJS = Python/deepfreeze/deepfreeze.o ########################################################################## @@ -579,16 +580,47 @@ LIBEXPAT_HEADERS= \ Modules/expat/xmltok.h \ Modules/expat/xmltok_impl.h +########################################################################## +# hashlib's HACL* library + +LIBHACL_SHA2_OBJS= \ + Modules/_hacl/Hacl_Hash_SHA2.o + +LIBHACL_HEADERS= \ + Modules/_hacl/include/krml/FStar_UInt128_Verified.h \ + Modules/_hacl/include/krml/FStar_UInt_8_16_32_64.h \ + Modules/_hacl/include/krml/fstar_uint128_struct_endianness.h \ + Modules/_hacl/include/krml/internal/target.h \ + Modules/_hacl/include/krml/lowstar_endianness.h \ + Modules/_hacl/include/krml/types.h \ + Modules/_hacl/Hacl_Streaming_Types.h \ + Modules/_hacl/python_hacl_namespaces.h + +LIBHACL_SHA2_HEADERS= \ + Modules/_hacl/Hacl_Hash_SHA2.h \ + Modules/_hacl/internal/Hacl_Hash_SHA2.h \ + $(LIBHACL_HEADERS) + ######################################################################### # Rules # Default target all: @DEF_MAKE_ALL_RULE@ -build_all: check-clean-src $(BUILDPYTHON) platform oldsharedmods sharedmods \ - gdbhooks Programs/_testembed python-config -build_wasm: check-clean-src $(BUILDPYTHON) platform oldsharedmods python-config + +# First target in Makefile is implicit default. So .PHONY needs to come after +# all. +.PHONY: all + +.PHONY: build_all +build_all: check-clean-src $(BUILDPYTHON) platform sharedmods \ + gdbhooks Programs/_testembed scripts checksharedmods rundsymutil + +.PHONY: build_wasm +build_wasm: check-clean-src $(BUILDPYTHON) platform sharedmods \ + python-config checksharedmods # Check that the source is clean when building out of source. +.PHONY: check-clean-src check-clean-src: @if test -n "$(VPATH)" -a \( \ -f "$(srcdir)/Programs/python.o" \ @@ -613,7 +645,7 @@ profile-gen-stamp: profile-clean-stamp exit 1;\ fi @echo "Building with support for profile generation:" - $(MAKE) build_all_generate_profile + $(MAKE) @DEF_MAKE_RULE@ CFLAGS_NODIST="$(CFLAGS_NODIST) $(PGO_PROF_GEN_FLAG)" LDFLAGS_NODIST="$(LDFLAGS_NODIST) $(PGO_PROF_GEN_FLAG)" LIBS="$(LIBS)" touch $@ # Run task with profile generation build to create profile information. @@ -623,8 +655,9 @@ profile-run-stamp: # enabled. $(MAKE) profile-gen-stamp # Next, run the profile task to generate the profile information. - $(MAKE) run_profile_task - $(MAKE) build_all_merge_profile + @ # FIXME: can't run for a cross build + $(LLVM_PROF_FILE) $(RUNSHARED) ./$(BUILDPYTHON) $(PROFILE_TASK) || true + $(LLVM_PROF_MERGER) # Remove profile generation binary since we are done with it. $(MAKE) clean-retain-profile # This is an expensive target to build and it does not have proper @@ -632,30 +665,72 @@ profile-run-stamp: # to record its completion and avoid re-running it. touch $@ -build_all_generate_profile: - $(MAKE) @DEF_MAKE_RULE@ CFLAGS_NODIST="$(CFLAGS_NODIST) $(PGO_PROF_GEN_FLAG)" LDFLAGS_NODIST="$(LDFLAGS_NODIST) $(PGO_PROF_GEN_FLAG)" LIBS="$(LIBS)" - -run_profile_task: - @ # FIXME: can't run for a cross build - $(LLVM_PROF_FILE) $(RUNSHARED) ./$(BUILDPYTHON) $(PROFILE_TASK) || true - -build_all_merge_profile: - $(LLVM_PROF_MERGER) - # Compile Python binary with profile guided optimization. # To force re-running of the profile task, remove the profile-run-stamp file. +.PHONY: profile-opt profile-opt: profile-run-stamp @echo "Rebuilding with profile guided optimizations:" -rm -f profile-clean-stamp $(MAKE) @DEF_MAKE_RULE@ CFLAGS_NODIST="$(CFLAGS_NODIST) $(PGO_PROF_USE_FLAG)" LDFLAGS_NODIST="$(LDFLAGS_NODIST)" +# List of binaries that BOLT runs on. +BOLT_BINARIES := @BOLT_BINARIES@ + +BOLT_INSTRUMENT_FLAGS := @BOLT_INSTRUMENT_FLAGS@ +BOLT_APPLY_FLAGS := @BOLT_APPLY_FLAGS@ + +.PHONY: clean-bolt +clean-bolt: + # Profile data. + rm -f *.fdata + # Pristine binaries before BOLT optimization. + rm -f *.prebolt + # BOLT instrumented binaries. + rm -f *.bolt_inst + +profile-bolt-stamp: $(BUILDPYTHON) + # Ensure a pristine, pre-BOLT copy of the binary and no profile data from last run. + for bin in $(BOLT_BINARIES); do \ + prebolt="$${bin}.prebolt"; \ + if [ -e "$${prebolt}" ]; then \ + echo "Restoring pre-BOLT binary $${prebolt}"; \ + mv "$${bin}.prebolt" "$${bin}"; \ + fi; \ + cp "$${bin}" "$${prebolt}"; \ + rm -f $${bin}.bolt.*.fdata $${bin}.fdata; \ + done + # Instrument each binary. + for bin in $(BOLT_BINARIES); do \ + @LLVM_BOLT@ "$${bin}" -instrument -instrumentation-file-append-pid -instrumentation-file=$(abspath $${bin}.bolt) -o $${bin}.bolt_inst $(BOLT_INSTRUMENT_FLAGS); \ + mv "$${bin}.bolt_inst" "$${bin}"; \ + done + # Run instrumented binaries to collect data. + $(RUNSHARED) ./$(BUILDPYTHON) $(PROFILE_TASK) || true + # Merge all the data files together. + for bin in $(BOLT_BINARIES); do \ + @MERGE_FDATA@ $${bin}.*.fdata > "$${bin}.fdata"; \ + rm -f $${bin}.*.fdata; \ + done + # Run bolt against the merged data to produce an optimized binary. + for bin in $(BOLT_BINARIES); do \ + @LLVM_BOLT@ "$${bin}.prebolt" -o "$${bin}.bolt" -data="$${bin}.fdata" $(BOLT_APPLY_FLAGS); \ + mv "$${bin}.bolt" "$${bin}"; \ + done + touch $@ + +.PHONY: bolt-opt +bolt-opt: + $(MAKE) @PREBOLT_RULE@ + $(MAKE) profile-bolt-stamp + # Compile and run with gcov -.PHONY=coverage coverage-lcov coverage-report +.PHONY: coverage coverage: @echo "Building with support for coverage checking:" $(MAKE) clean $(MAKE) @DEF_MAKE_RULE@ CFLAGS="$(CFLAGS) -O0 -pg --coverage" LDFLAGS="$(LDFLAGS) --coverage" +.PHONY: coverage-lcov coverage-lcov: @echo "Creating Coverage HTML report with LCOV:" @rm -f $(COVERAGE_INFO) @@ -687,6 +762,7 @@ coverage-lcov: @echo # Force regeneration of parser and frozen modules +.PHONY: coverage-report coverage-report: regen-token regen-frozen @ # build with coverage info $(MAKE) coverage @@ -696,7 +772,7 @@ coverage-report: regen-token regen-frozen $(MAKE) coverage-lcov # Run "Argument Clinic" over all source files -.PHONY=clinic +.PHONY: clinic clinic: check-clean-src $(srcdir)/Modules/_blake2/blake2s_impl.c $(PYTHON_FOR_REGEN) $(srcdir)/Tools/clinic/clinic.py --make --srcdir $(srcdir) @@ -728,22 +804,6 @@ $(srcdir)/Modules/_blake2/blake2s_impl.c: $(srcdir)/Modules/_blake2/blake2b_impl $(PYTHON_FOR_REGEN) $(srcdir)/Modules/_blake2/blake2b2s.py $(PYTHON_FOR_REGEN) $(srcdir)/Tools/clinic/clinic.py -f $@ -# Build the shared modules -# Under GNU make, MAKEFLAGS are sorted and normalized; the 's' for -# -s, --silent or --quiet is always the first char. -# Under BSD make, MAKEFLAGS might be " -s -v x=y". -# Ignore macros passed by GNU make, passed after -- -sharedmods: $(PYTHON_FOR_BUILD_DEPS) pybuilddir.txt @LIBMPDEC_INTERNAL@ @LIBEXPAT_INTERNAL@ - @case "`echo X $$MAKEFLAGS | sed 's/^X //;s/ -- .*//'`" in \ - *\ -s*|s*) quiet="-q";; \ - *) quiet="";; \ - esac; \ - echo "$(RUNSHARED) CC='$(CC)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' \ - $(PYTHON_FOR_BUILD) $(srcdir)/setup.py $$quiet build"; \ - $(RUNSHARED) CC='$(CC)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' \ - $(PYTHON_FOR_BUILD) $(srcdir)/setup.py $$quiet build - - # Build static library $(LIBRARY): $(LIBRARY_OBJS) -rm -f $@ @@ -776,6 +836,7 @@ Modules/python.exp: $(LIBRARY) # # Distributors are likely to want to install this somewhere else e.g. relative # to the stripped DWARF data for the shared library. +.PHONY: gdbhooks gdbhooks: $(BUILDPYTHON)-gdb.py SRC_GDB_HOOKS=$(srcdir)/Tools/gdb/libpython.py @@ -835,10 +896,6 @@ python.worker.js: $(srcdir)/Tools/wasm/python.worker.js # Build static libmpdec.a LIBMPDEC_CFLAGS=@LIBMPDEC_CFLAGS@ $(PY_STDMODULE_CFLAGS) $(CCSHARED) -# for setup.py -DECIMAL_CFLAGS=@LIBMPDEC_CFLAGS@ -DECIMAL_LDFLAGS=@LIBMPDEC_LDFLAGS@ - # "%.o: %c" is not portable Modules/_decimal/libmpdec/basearith.o: $(srcdir)/Modules/_decimal/libmpdec/basearith.c $(LIBMPDEC_HEADERS) $(PYTHON_HEADERS) $(CC) -c $(LIBMPDEC_CFLAGS) -o $@ $(srcdir)/Modules/_decimal/libmpdec/basearith.c @@ -893,10 +950,6 @@ $(LIBMPDEC_A): $(LIBMPDEC_OBJS) # Build static libexpat.a LIBEXPAT_CFLAGS=@LIBEXPAT_CFLAGS@ $(PY_STDMODULE_CFLAGS) $(CCSHARED) -# for setup.py -EXPAT_CFLAGS=@LIBEXPAT_CFLAGS@ -EXPAT_LDFLAGS=@LIBEXPAT_LDFLAGS@ - Modules/expat/xmlparse.o: $(srcdir)/Modules/expat/xmlparse.c $(LIBEXPAT_HEADERS) $(PYTHON_HEADERS) $(CC) -c $(LIBEXPAT_CFLAGS) -o $@ $(srcdir)/Modules/expat/xmlparse.c @@ -910,10 +963,22 @@ $(LIBEXPAT_A): $(LIBEXPAT_OBJS) -rm -f $@ $(AR) $(ARFLAGS) $@ $(LIBEXPAT_OBJS) +########################################################################## +# Build HACL* static libraries for hashlib: libHacl_Hash_SHA2.a +LIBHACL_CFLAGS=-I$(srcdir)/Modules/_hacl/include -D_BSD_SOURCE -D_DEFAULT_SOURCE $(PY_STDMODULE_CFLAGS) $(CCSHARED) + +Modules/_hacl/Hacl_Hash_SHA2.o: $(srcdir)/Modules/_hacl/Hacl_Hash_SHA2.c $(LIBHACL_SHA2_HEADERS) + $(CC) -c $(LIBHACL_CFLAGS) -o $@ $(srcdir)/Modules/_hacl/Hacl_Hash_SHA2.c + +$(LIBHACL_SHA2_A): $(LIBHACL_SHA2_OBJS) + -rm -f $@ + $(AR) $(ARFLAGS) $@ $(LIBHACL_SHA2_OBJS) + # create relative links from build/lib.platform/egg.so to Modules/egg.so # pybuilddir.txt is created too late. We cannot use it in Makefile # targets. ln --relative is not portable. -oldsharedmods: $(SHAREDMODS) pybuilddir.txt +.PHONY: sharedmods +sharedmods: $(SHAREDMODS) pybuilddir.txt @target=`cat pybuilddir.txt`; \ $(MKDIR_P) $$target; \ for mod in X $(SHAREDMODS); do \ @@ -922,6 +987,28 @@ oldsharedmods: $(SHAREDMODS) pybuilddir.txt fi; \ done +# dependency on BUILDPYTHON ensures that the target is run last +.PHONY: checksharedmods +checksharedmods: sharedmods $(PYTHON_FOR_BUILD_DEPS) $(BUILDPYTHON) + @$(RUNSHARED) $(PYTHON_FOR_BUILD) $(srcdir)/Tools/build/check_extension_modules.py + +.PHONY: rundsymutil +rundsymutil: sharedmods $(PYTHON_FOR_BUILD_DEPS) $(BUILDPYTHON) + @if [ ! -z $(DSYMUTIL) ] ; then \ + echo $(DSYMUTIL_PATH) $(BUILDPYTHON); \ + $(DSYMUTIL_PATH) $(BUILDPYTHON); \ + if test -f $(LDLIBRARY); then \ + echo $(DSYMUTIL_PATH) $(LDLIBRARY); \ + $(DSYMUTIL_PATH) $(LDLIBRARY); \ + fi; \ + for mod in X $(SHAREDMODS); do \ + if test $$mod != X; then \ + echo $(DSYMUTIL_PATH) $$mod; \ + $(DSYMUTIL_PATH) $$mod; \ + fi; \ + done \ + fi + Modules/Setup.local: @# Create empty Setup.local when file was deleted by user echo "# Edit this file for local setup changes" > $@ @@ -939,10 +1026,10 @@ Makefile Modules/config.c: Makefile.pre \ Modules/Setup.local \ Modules/Setup.bootstrap \ Modules/Setup.stdlib - $(SHELL) $(MAKESETUP) -c $(srcdir)/Modules/config.c.in \ + $(MAKESETUP) -c $(srcdir)/Modules/config.c.in \ -s Modules \ Modules/Setup.local \ - @MODULES_SETUP_STDLIB@ \ + Modules/Setup.stdlib \ Modules/Setup.bootstrap \ $(srcdir)/Modules/Setup @mv config.c Modules @@ -955,11 +1042,16 @@ regen-test-frozenmain: $(BUILDPYTHON) # using Programs/freeze_test_frozenmain.py $(RUNSHARED) ./$(BUILDPYTHON) $(srcdir)/Programs/freeze_test_frozenmain.py Programs/test_frozenmain.h +.PHONY: regen-test-levenshtein +regen-test-levenshtein: + # Regenerate Lib/test/levenshtein_examples.json + $(PYTHON_FOR_REGEN) $(srcdir)/Tools/build/generate_levenshtein_examples.py $(srcdir)/Lib/test/levenshtein_examples.json + .PHONY: regen-re regen-re: $(BUILDPYTHON) # Regenerate Lib/re/_casefix.py - # using Tools/scripts/generate_re_casefix.py - $(RUNSHARED) ./$(BUILDPYTHON) $(srcdir)/Tools/scripts/generate_re_casefix.py $(srcdir)/Lib/re/_casefix.py + # using Tools/build/generate_re_casefix.py + $(RUNSHARED) ./$(BUILDPYTHON) $(srcdir)/Tools/build/generate_re_casefix.py $(srcdir)/Lib/re/_casefix.py Programs/_testembed: Programs/_testembed.o $(LINK_PYTHON_DEPS) $(LINKCC) $(PY_CORE_LDFLAGS) $(LINKFORSHARED) -o $@ Programs/_testembed.o $(LINK_PYTHON_OBJS) $(LIBS) $(MODLIBS) $(SYSLIBS) @@ -969,7 +1061,8 @@ Programs/_testembed: Programs/_testembed.o $(LINK_PYTHON_DEPS) BOOTSTRAP_HEADERS = \ Python/frozen_modules/importlib._bootstrap.h \ - Python/frozen_modules/importlib._bootstrap_external.h + Python/frozen_modules/importlib._bootstrap_external.h \ + Python/frozen_modules/zipimport.h Programs/_bootstrap_python.o: Programs/_bootstrap_python.c $(BOOTSTRAP_HEADERS) $(PYTHON_HEADERS) @@ -1005,7 +1098,7 @@ _bootstrap_python: $(LIBRARY_OBJS_OMIT_FROZEN) Programs/_bootstrap_python.o Modu # 2) deepfreeze modules with external build Python. # -# FROZEN_FILES_* are auto-generated by Tools/scripts/freeze_modules.py. +# FROZEN_FILES_* are auto-generated by Tools/build/freeze_modules.py. FROZEN_FILES_IN = \ Lib/importlib/_bootstrap.py \ Lib/importlib/_bootstrap_external.py \ @@ -1141,24 +1234,24 @@ Python/frozen_modules/frozen_only.h: Tools/freeze/flag.py $(FREEZE_MODULE_DEPS) # END: freezing modules -Tools/scripts/freeze_modules.py: $(FREEZE_MODULE) +Tools/build/freeze_modules.py: $(FREEZE_MODULE) .PHONY: regen-frozen -regen-frozen: Tools/scripts/freeze_modules.py $(FROZEN_FILES_IN) - $(PYTHON_FOR_REGEN) $(srcdir)/Tools/scripts/freeze_modules.py +regen-frozen: Tools/build/freeze_modules.py $(FROZEN_FILES_IN) + $(PYTHON_FOR_REGEN) $(srcdir)/Tools/build/freeze_modules.py --frozen-modules @echo "The Makefile was updated, you may need to re-run make." ############################################################################ # Deepfreeze targets .PHONY: regen-deepfreeze -regen-deepfreeze: $(DEEPFREEZE_OBJS) +regen-deepfreeze: $(DEEPFREEZE_C) -DEEPFREEZE_DEPS=$(srcdir)/Tools/scripts/deepfreeze.py $(FREEZE_MODULE_DEPS) $(FROZEN_FILES_OUT) +DEEPFREEZE_DEPS=$(srcdir)/Tools/build/deepfreeze.py $(FREEZE_MODULE_DEPS) $(FROZEN_FILES_OUT) # BEGIN: deepfreeze modules -Python/deepfreeze/deepfreeze.c: $(DEEPFREEZE_DEPS) - $(PYTHON_FOR_FREEZE) $(srcdir)/Tools/scripts/deepfreeze.py \ +$(DEEPFREEZE_C): $(DEEPFREEZE_DEPS) + $(PYTHON_FOR_FREEZE) $(srcdir)/Tools/build/deepfreeze.py \ Python/frozen_modules/importlib._bootstrap.h:importlib._bootstrap \ Python/frozen_modules/importlib._bootstrap_external.h:importlib._bootstrap_external \ Python/frozen_modules/zipimport.h:zipimport \ @@ -1184,8 +1277,6 @@ Python/deepfreeze/deepfreeze.c: $(DEEPFREEZE_DEPS) Python/frozen_modules/frozen_only.h:frozen_only \ -o Python/deepfreeze/deepfreeze.c # END: deepfreeze modules - @echo "Note: Deepfreeze may have added some global objects," - @echo " so run 'make regen-global-objects' if necessary." # We keep this renamed target around for folks with muscle memory. .PHONY: regen-importlib @@ -1194,33 +1285,39 @@ regen-importlib: regen-frozen ############################################################################ # Global objects +# Dependencies which can add and/or remove _Py_ID() identifiers: +# - deepfreeze.c +# - "make clinic" .PHONY: regen-global-objects -regen-global-objects: $(srcdir)/Tools/scripts/generate_global_objects.py - $(PYTHON_FOR_REGEN) $(srcdir)/Tools/scripts/generate_global_objects.py - @echo "Note: Global objects can be added or removed by other tools (e.g. deepfreeze), " - @echo " so be sure to re-run regen-global-objects after those tools." +regen-global-objects: $(srcdir)/Tools/build/generate_global_objects.py $(DEEPFREEZE_C) clinic + $(PYTHON_FOR_REGEN) $(srcdir)/Tools/build/generate_global_objects.py ############################################################################ # ABI +.PHONY: regen-abidump regen-abidump: all @$(MKDIR_P) $(srcdir)/Doc/data/ abidw "libpython$(LDVERSION).so" --no-architecture --out-file $(srcdir)/Doc/data/python$(LDVERSION).abi.new - @$(UPDATE_FILE) $(srcdir)/Doc/data/python$(LDVERSION).abi $(srcdir)/Doc/data/python$(LDVERSION).abi.new + @$(UPDATE_FILE) --create $(srcdir)/Doc/data/python$(LDVERSION).abi $(srcdir)/Doc/data/python$(LDVERSION).abi.new +.PHONY: check-abidump check-abidump: all - abidiff $(srcdir)/Doc/data/python$(LDVERSION).abi "libpython$(LDVERSION).so" --drop-private-types --no-architecture --no-added-syms + abidiff $(srcdir)/Doc/data/python$(LDVERSION).abi "libpython$(LDVERSION).so" --drop-private-types --no-architecture --no-added-syms +.PHONY: regen-limited-abi regen-limited-abi: all - $(RUNSHARED) ./$(BUILDPYTHON) $(srcdir)/Tools/scripts/stable_abi.py --generate-all $(srcdir)/Misc/stable_abi.toml + $(RUNSHARED) ./$(BUILDPYTHON) $(srcdir)/Tools/build/stable_abi.py --generate-all $(srcdir)/Misc/stable_abi.toml ############################################################################ # Regenerate all generated files -regen-all: regen-opcode regen-opcode-targets regen-typeslots \ - regen-token regen-ast regen-keyword regen-sre regen-frozen clinic \ +# "clinic" is regenerated implicitly via "regen-global-objects". +.PHONY: regen-all +regen-all: regen-cases regen-opcode regen-opcode-targets regen-typeslots \ + regen-token regen-ast regen-keyword regen-sre regen-frozen \ regen-pegen-metaparser regen-pegen regen-test-frozenmain \ - regen-global-objects + regen-test-levenshtein regen-global-objects @echo @echo "Note: make regen-stdlib-module-names and make regen-configure should be run manually" @@ -1251,10 +1348,10 @@ Modules/getpath.o: $(srcdir)/Modules/getpath.c Python/frozen_modules/getpath.h M -o $@ $(srcdir)/Modules/getpath.c Programs/python.o: $(srcdir)/Programs/python.c - $(MAINCC) -c $(PY_CORE_CFLAGS) -o $@ $(srcdir)/Programs/python.c + $(CC) -c $(PY_CORE_CFLAGS) -o $@ $(srcdir)/Programs/python.c Programs/_testembed.o: $(srcdir)/Programs/_testembed.c Programs/test_frozenmain.h - $(MAINCC) -c $(PY_CORE_CFLAGS) -o $@ $(srcdir)/Programs/_testembed.c + $(CC) -c $(PY_CORE_CFLAGS) -o $@ $(srcdir)/Programs/_testembed.c Modules/_sre/sre.o: $(srcdir)/Modules/_sre/sre.c $(srcdir)/Modules/_sre/sre.h $(srcdir)/Modules/_sre/sre_constants.h $(srcdir)/Modules/_sre/sre_lib.h @@ -1302,7 +1399,7 @@ regen-pegen: -o $(srcdir)/Parser/parser.new.c $(UPDATE_FILE) $(srcdir)/Parser/parser.c $(srcdir)/Parser/parser.new.c -.PHONY=regen-ast +.PHONY: regen-ast regen-ast: # Regenerate 3 files using using Parser/asdl_c.py: # - Include/internal/pycore_ast.h @@ -1323,34 +1420,36 @@ regen-ast: .PHONY: regen-opcode regen-opcode: # Regenerate Include/opcode.h from Lib/opcode.py - # using Tools/scripts/generate_opcode_h.py - $(PYTHON_FOR_REGEN) $(srcdir)/Tools/scripts/generate_opcode_h.py \ + # using Tools/build/generate_opcode_h.py + $(PYTHON_FOR_REGEN) $(srcdir)/Tools/build/generate_opcode_h.py \ $(srcdir)/Lib/opcode.py \ $(srcdir)/Include/opcode.h.new \ - $(srcdir)/Include/internal/pycore_opcode.h.new + $(srcdir)/Include/internal/pycore_opcode.h.new \ + $(srcdir)/Include/internal/pycore_intrinsics.h.new $(UPDATE_FILE) $(srcdir)/Include/opcode.h $(srcdir)/Include/opcode.h.new $(UPDATE_FILE) $(srcdir)/Include/internal/pycore_opcode.h $(srcdir)/Include/internal/pycore_opcode.h.new + $(UPDATE_FILE) $(srcdir)/Include/internal/pycore_intrinsics.h $(srcdir)/Include/internal/pycore_intrinsics.h.new .PHONY: regen-token regen-token: # Regenerate Doc/library/token-list.inc from Grammar/Tokens - # using Tools/scripts/generate_token.py - $(PYTHON_FOR_REGEN) $(srcdir)/Tools/scripts/generate_token.py rst \ + # using Tools/build/generate_token.py + $(PYTHON_FOR_REGEN) $(srcdir)/Tools/build/generate_token.py rst \ $(srcdir)/Grammar/Tokens \ $(srcdir)/Doc/library/token-list.inc - # Regenerate Include/token.h from Grammar/Tokens - # using Tools/scripts/generate_token.py - $(PYTHON_FOR_REGEN) $(srcdir)/Tools/scripts/generate_token.py h \ + # Regenerate Include/internal/pycore_token.h from Grammar/Tokens + # using Tools/build/generate_token.py + $(PYTHON_FOR_REGEN) $(srcdir)/Tools/build/generate_token.py h \ $(srcdir)/Grammar/Tokens \ - $(srcdir)/Include/token.h + $(srcdir)/Include/internal/pycore_token.h # Regenerate Parser/token.c from Grammar/Tokens - # using Tools/scripts/generate_token.py - $(PYTHON_FOR_REGEN) $(srcdir)/Tools/scripts/generate_token.py c \ + # using Tools/build/generate_token.py + $(PYTHON_FOR_REGEN) $(srcdir)/Tools/build/generate_token.py c \ $(srcdir)/Grammar/Tokens \ $(srcdir)/Parser/token.c # Regenerate Lib/token.py from Grammar/Tokens - # using Tools/scripts/generate_token.py - $(PYTHON_FOR_REGEN) $(srcdir)/Tools/scripts/generate_token.py py \ + # using Tools/build/generate_token.py + $(PYTHON_FOR_REGEN) $(srcdir)/Tools/build/generate_token.py py \ $(srcdir)/Grammar/Tokens \ $(srcdir)/Lib/token.py @@ -1367,16 +1466,17 @@ regen-keyword: .PHONY: regen-stdlib-module-names regen-stdlib-module-names: all Programs/_testembed # Regenerate Python/stdlib_module_names.h - # using Tools/scripts/generate_stdlib_module_names.py + # using Tools/build/generate_stdlib_module_names.py $(RUNSHARED) ./$(BUILDPYTHON) \ - $(srcdir)/Tools/scripts/generate_stdlib_module_names.py \ + $(srcdir)/Tools/build/generate_stdlib_module_names.py \ > $(srcdir)/Python/stdlib_module_names.h.new $(UPDATE_FILE) $(srcdir)/Python/stdlib_module_names.h $(srcdir)/Python/stdlib_module_names.h.new +.PHONY: regen-sre regen-sre: # Regenerate Modules/_sre/sre_constants.h and Modules/_sre/sre_targets.h - # from Lib/re/_constants.py using Tools/scripts/generate_sre_constants.py - $(PYTHON_FOR_REGEN) $(srcdir)/Tools/scripts/generate_sre_constants.py \ + # from Lib/re/_constants.py using Tools/build/generate_sre_constants.py + $(PYTHON_FOR_REGEN) $(srcdir)/Tools/build/generate_sre_constants.py \ $(srcdir)/Lib/re/_constants.py \ $(srcdir)/Modules/_sre/sre_constants.h \ $(srcdir)/Modules/_sre/sre_targets.h @@ -1418,8 +1518,7 @@ UNICODE_DEPS = \ $(srcdir)/Objects/stringlib/ucs2lib.h \ $(srcdir)/Objects/stringlib/ucs4lib.h \ $(srcdir)/Objects/stringlib/undef.h \ - $(srcdir)/Objects/stringlib/unicode_format.h \ - $(srcdir)/Objects/stringlib/unicodedefs.h + $(srcdir)/Objects/stringlib/unicode_format.h Objects/bytes_methods.o: $(srcdir)/Objects/bytes_methods.c $(BYTESTR_DEPS) Objects/bytesobject.o: $(srcdir)/Objects/bytesobject.c $(BYTESTR_DEPS) @@ -1438,8 +1537,30 @@ regen-opcode-targets: $(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 \ - $(srcdir)/Python/condvar.h +.PHONY: regen-cases +regen-cases: + # Regenerate Python/generated_cases.c.h + # and Python/opcode_metadata.h + # from Python/bytecodes.c + # using Tools/cases_generator/generate_cases.py + PYTHONPATH=$(srcdir)/Tools/cases_generator \ + $(PYTHON_FOR_REGEN) \ + $(srcdir)/Tools/cases_generator/generate_cases.py \ + --emit-line-directives \ + -o $(srcdir)/Python/generated_cases.c.h.new \ + -m $(srcdir)/Python/opcode_metadata.h.new \ + $(srcdir)/Python/bytecodes.c + $(UPDATE_FILE) $(srcdir)/Python/generated_cases.c.h $(srcdir)/Python/generated_cases.c.h.new + $(UPDATE_FILE) $(srcdir)/Python/opcode_metadata.h $(srcdir)/Python/opcode_metadata.h.new + +Python/compile.o: $(srcdir)/Python/opcode_metadata.h + +Python/ceval.o: \ + $(srcdir)/Python/ceval_macros.h \ + $(srcdir)/Python/condvar.h \ + $(srcdir)/Python/generated_cases.c.h \ + $(srcdir)/Python/opcode_metadata.h \ + $(srcdir)/Python/opcode_targets.h Python/frozen.o: $(FROZEN_FILES_OUT) @@ -1495,6 +1616,7 @@ PYTHON_HEADERS= \ $(srcdir)/Include/floatobject.h \ $(srcdir)/Include/frameobject.h \ $(srcdir)/Include/import.h \ + $(srcdir)/Include/interpreteridobject.h \ $(srcdir)/Include/intrcheck.h \ $(srcdir)/Include/iterobject.h \ $(srcdir)/Include/listobject.h \ @@ -1523,6 +1645,7 @@ PYTHON_HEADERS= \ $(srcdir)/Include/pymem.h \ $(srcdir)/Include/pyport.h \ $(srcdir)/Include/pystate.h \ + $(srcdir)/Include/pystats.h \ $(srcdir)/Include/pystrcmp.h \ $(srcdir)/Include/pystrtod.h \ $(srcdir)/Include/pythonrun.h \ @@ -1534,7 +1657,6 @@ PYTHON_HEADERS= \ $(srcdir)/Include/structmember.h \ $(srcdir)/Include/structseq.h \ $(srcdir)/Include/sysmodule.h \ - $(srcdir)/Include/token.h \ $(srcdir)/Include/traceback.h \ $(srcdir)/Include/tracemalloc.h \ $(srcdir)/Include/tupleobject.h \ @@ -1565,9 +1687,11 @@ PYTHON_HEADERS= \ $(srcdir)/Include/cpython/genobject.h \ $(srcdir)/Include/cpython/import.h \ $(srcdir)/Include/cpython/initconfig.h \ + $(srcdir)/Include/cpython/interpreteridobject.h \ $(srcdir)/Include/cpython/listobject.h \ $(srcdir)/Include/cpython/longintrepr.h \ $(srcdir)/Include/cpython/longobject.h \ + $(srcdir)/Include/cpython/memoryobject.h \ $(srcdir)/Include/cpython/methodobject.h \ $(srcdir)/Include/cpython/modsupport.h \ $(srcdir)/Include/cpython/object.h \ @@ -1595,10 +1719,10 @@ PYTHON_HEADERS= \ $(srcdir)/Include/cpython/weakrefobject.h \ \ $(srcdir)/Include/internal/pycore_abstract.h \ - $(srcdir)/Include/internal/pycore_accu.h \ $(srcdir)/Include/internal/pycore_asdl.h \ $(srcdir)/Include/internal/pycore_ast.h \ $(srcdir)/Include/internal/pycore_ast_state.h \ + $(srcdir)/Include/internal/pycore_atexit.h \ $(srcdir)/Include/internal/pycore_atomic.h \ $(srcdir)/Include/internal/pycore_atomic_funcs.h \ $(srcdir)/Include/internal/pycore_bitutils.h \ @@ -1606,40 +1730,55 @@ PYTHON_HEADERS= \ $(srcdir)/Include/internal/pycore_bytesobject.h \ $(srcdir)/Include/internal/pycore_call.h \ $(srcdir)/Include/internal/pycore_ceval.h \ + $(srcdir)/Include/internal/pycore_ceval_state.h \ $(srcdir)/Include/internal/pycore_code.h \ $(srcdir)/Include/internal/pycore_compile.h \ $(srcdir)/Include/internal/pycore_condvar.h \ $(srcdir)/Include/internal/pycore_context.h \ $(srcdir)/Include/internal/pycore_dict.h \ + $(srcdir)/Include/internal/pycore_dict_state.h \ + $(srcdir)/Include/internal/pycore_descrobject.h \ $(srcdir)/Include/internal/pycore_dtoa.h \ $(srcdir)/Include/internal/pycore_exceptions.h \ + $(srcdir)/Include/internal/pycore_faulthandler.h \ $(srcdir)/Include/internal/pycore_fileutils.h \ $(srcdir)/Include/internal/pycore_floatobject.h \ $(srcdir)/Include/internal/pycore_format.h \ + $(srcdir)/Include/internal/pycore_frame.h \ $(srcdir)/Include/internal/pycore_function.h \ $(srcdir)/Include/internal/pycore_genobject.h \ $(srcdir)/Include/internal/pycore_getopt.h \ $(srcdir)/Include/internal/pycore_gil.h \ $(srcdir)/Include/internal/pycore_global_objects.h \ + $(srcdir)/Include/internal/pycore_global_objects_fini_generated.h \ $(srcdir)/Include/internal/pycore_hamt.h \ $(srcdir)/Include/internal/pycore_hashtable.h \ $(srcdir)/Include/internal/pycore_import.h \ $(srcdir)/Include/internal/pycore_initconfig.h \ $(srcdir)/Include/internal/pycore_interp.h \ - $(srcdir)/Include/internal/pycore_interpreteridobject.h \ + $(srcdir)/Include/internal/pycore_intrinsics.h \ $(srcdir)/Include/internal/pycore_list.h \ $(srcdir)/Include/internal/pycore_long.h \ $(srcdir)/Include/internal/pycore_moduleobject.h \ $(srcdir)/Include/internal/pycore_namespace.h \ $(srcdir)/Include/internal/pycore_object.h \ + $(srcdir)/Include/internal/pycore_object_state.h \ + $(srcdir)/Include/internal/pycore_obmalloc.h \ + $(srcdir)/Include/internal/pycore_obmalloc_init.h \ + $(srcdir)/Include/internal/pycore_opcode.h \ + $(srcdir)/Include/internal/pycore_opcode_utils.h \ $(srcdir)/Include/internal/pycore_pathconfig.h \ $(srcdir)/Include/internal/pycore_pyarena.h \ $(srcdir)/Include/internal/pycore_pyerrors.h \ $(srcdir)/Include/internal/pycore_pyhash.h \ $(srcdir)/Include/internal/pycore_pylifecycle.h \ $(srcdir)/Include/internal/pycore_pymem.h \ + $(srcdir)/Include/internal/pycore_pymem_init.h \ $(srcdir)/Include/internal/pycore_pystate.h \ + $(srcdir)/Include/internal/pycore_pythread.h \ + $(srcdir)/Include/internal/pycore_range.h \ $(srcdir)/Include/internal/pycore_runtime.h \ + $(srcdir)/Include/internal/pycore_runtime_init_generated.h \ $(srcdir)/Include/internal/pycore_runtime_init.h \ $(srcdir)/Include/internal/pycore_signal.h \ $(srcdir)/Include/internal/pycore_sliceobject.h \ @@ -1647,12 +1786,17 @@ PYTHON_HEADERS= \ $(srcdir)/Include/internal/pycore_structseq.h \ $(srcdir)/Include/internal/pycore_symtable.h \ $(srcdir)/Include/internal/pycore_sysmodule.h \ + $(srcdir)/Include/internal/pycore_time.h \ + $(srcdir)/Include/internal/pycore_token.h \ $(srcdir)/Include/internal/pycore_traceback.h \ + $(srcdir)/Include/internal/pycore_tracemalloc.h \ $(srcdir)/Include/internal/pycore_tuple.h \ $(srcdir)/Include/internal/pycore_typeobject.h \ + $(srcdir)/Include/internal/pycore_typevarobject.h \ $(srcdir)/Include/internal/pycore_ucnhash.h \ $(srcdir)/Include/internal/pycore_unionobject.h \ $(srcdir)/Include/internal/pycore_unicodeobject.h \ + $(srcdir)/Include/internal/pycore_unicodeobject_generated.h \ $(srcdir)/Include/internal/pycore_warnings.h \ $(DTRACE_HEADERS) \ @PLATFORM_HEADERS@ \ @@ -1669,15 +1813,15 @@ TESTPYTHON= $(RUNSHARED) $(PYTHON_FOR_BUILD) $(TESTPYTHONOPTS) TESTRUNNER= $(TESTPYTHON) $(srcdir)/Tools/scripts/run_tests.py TESTTIMEOUT= 1200 -.PHONY: test testall testuniversal buildbottest pythoninfo - # Remove "test_python_*" directories of previous failed test jobs. # Pass TESTOPTS options because it can contain --tempdir option. +.PHONY: cleantest cleantest: all $(TESTRUNNER) $(TESTOPTS) --cleanup # Run a basic set of regression tests. # This excludes some tests that are particularly resource-intensive. +.PHONY: test test: all $(TESTRUNNER) $(TESTOPTS) @@ -1688,6 +1832,7 @@ test: all # the bytecode read from a .pyc file had the bug, sometimes the directly # generated bytecode. This is sometimes a very shy bug needing a lot of # sample data. +.PHONY: testall testall: all -find $(srcdir)/Lib -name '*.py[co]' -print | xargs rm -f $(TESTPYTHON) -E $(srcdir)/Lib/compileall.py @@ -1697,6 +1842,7 @@ testall: all # Run the test suite for both architectures in a Universal build on OSX. # Must be run on an Intel box. +.PHONY: testuniversal testuniversal: all @if [ `arch` != 'i386' ]; then \ echo "This can only be used on OSX/i386" ;\ @@ -1708,6 +1854,7 @@ testuniversal: all # Like testall, but with only one pass and without multiple processes. # Run an optional script to include information about the build environment. +.PHONY: buildbottest buildbottest: all -@if which pybuildbot.identify >/dev/null 2>&1; then \ pybuildbot.identify "CC='$(CC)'" "CXX='$(CXX)'"; \ @@ -1715,9 +1862,11 @@ buildbottest: all $(TESTRUNNER) -j 1 -u all -W --slowest --fail-env-changed --timeout=$(TESTTIMEOUT) $(TESTOPTS) # Like testall, but run Python tests with HOSTRUNNER directly. +.PHONY: hostrunnertest hostrunnertest: all $(RUNSHARED) $(HOSTRUNNER) ./$(BUILDPYTHON) -m test -u all $(TESTOPTS) +.PHONY: pythoninfo pythoninfo: all $(RUNSHARED) $(HOSTRUNNER) ./$(BUILDPYTHON) -m test.pythoninfo @@ -1727,14 +1876,17 @@ QUICKTESTOPTS= $(TESTOPTS) -x test_subprocess test_io test_lib2to3 \ test_multiprocessing_forkserver \ test_mailbox test_nntplib test_socket test_poll \ test_select test_zipfile test_concurrent_futures + +.PHONY: quicktest quicktest: all $(TESTRUNNER) $(QUICKTESTOPTS) # SSL tests -.PHONY: multisslcompile multissltest +.PHONY: multisslcompile multisslcompile: all $(RUNSHARED) ./$(BUILDPYTHON) $(srcdir)/Tools/ssl/multissltests.py --steps=modules +.PHONY: multissltest multissltest: all $(RUNSHARED) ./$(BUILDPYTHON) $(srcdir)/Tools/ssl/multissltests.py @@ -1742,6 +1894,7 @@ multissltest: all # prevent race conditions with PGO builds. PGO builds use recursive make, # which can lead to two parallel `./python setup.py build` processes that # step on each others toes. +.PHONY: install install: @FRAMEWORKINSTALLFIRST@ commoninstall bininstall maninstall @FRAMEWORKINSTALLLAST@ if test "x$(ENSUREPIP)" != "xno" ; then \ case $(ENSUREPIP) in \ @@ -1752,6 +1905,7 @@ install: @FRAMEWORKINSTALLFIRST@ commoninstall bininstall maninstall @FRAMEWORKI $$ensurepip --root=$(DESTDIR)/ ; \ fi +.PHONY: altinstall altinstall: commoninstall if test "x$(ENSUREPIP)" != "xno" ; then \ case $(ENSUREPIP) in \ @@ -1762,23 +1916,16 @@ altinstall: commoninstall $$ensurepip --root=$(DESTDIR)/ ; \ fi +.PHONY: commoninstall commoninstall: check-clean-src @FRAMEWORKALTINSTALLFIRST@ \ altbininstall libinstall inclinstall libainstall \ - sharedinstall oldsharedinstall altmaninstall \ - @FRAMEWORKALTINSTALLLAST@ + sharedinstall altmaninstall @FRAMEWORKALTINSTALLLAST@ # Install shared libraries enabled by Setup DESTDIRS= $(exec_prefix) $(LIBDIR) $(BINLIBDEST) $(DESTSHARED) -oldsharedinstall: $(DESTSHARED) all - @for i in X $(SHAREDMODS); do \ - if test $$i != X; then \ - echo $(INSTALL_SHARED) $$i $(DESTSHARED)/`basename $$i`; \ - $(INSTALL_SHARED) $$i $(DESTDIR)$(DESTSHARED)/`basename $$i`; \ - fi; \ - done - -$(DESTSHARED): +.PHONY: sharedinstall +sharedinstall: all @for i in $(DESTDIRS); \ do \ if test ! -d $(DESTDIR)$$i; then \ @@ -1787,9 +1934,20 @@ $(DESTSHARED): else true; \ fi; \ done + @for i in X $(SHAREDMODS); do \ + if test $$i != X; then \ + echo $(INSTALL_SHARED) $$i $(DESTSHARED)/`basename $$i`; \ + $(INSTALL_SHARED) $$i $(DESTDIR)$(DESTSHARED)/`basename $$i`; \ + if test -d "$$i.dSYM"; then \ + echo $(DSYMUTIL_PATH) $(DESTDIR)$(DESTSHARED)/`basename $$i`; \ + $(DSYMUTIL_PATH) $(DESTDIR)$(DESTSHARED)/`basename $$i`; \ + fi; \ + fi; \ + done # Install the interpreter with $(VERSION) affixed # This goes into $(exec_prefix) +.PHONY: altbininstall altbininstall: $(BUILDPYTHON) @FRAMEWORKPYTHONW@ @for i in $(BINDIR) $(LIBDIR); \ do \ @@ -1838,8 +1996,29 @@ altbininstall: $(BUILDPYTHON) @FRAMEWORKPYTHONW@ -output $(DESTDIR)$(BINDIR)/python$(VERSION)-intel64$(EXE) \ $(DESTDIR)$(BINDIR)/python$(VERSION)$(EXE); \ fi + # Install macOS debug information (if available) + if test -d "$(BUILDPYTHON).dSYM"; then \ + echo $(DSYMUTIL_PATH) $(DESTDIR)$(BINDIR)/python$(LDVERSION)$(EXE); \ + $(DSYMUTIL_PATH) $(DESTDIR)$(BINDIR)/python$(LDVERSION)$(EXE); \ + fi + if test "$(PYTHONFRAMEWORKDIR)" = "no-framework" ; then \ + if test -d "$(LDLIBRARY).dSYM"; then \ + echo $(DSYMUTIL_PATH) $(DESTDIR)$(LIBDIR)/$(INSTSONAME); \ + $(DSYMUTIL_PATH) $(DESTDIR)$(LIBDIR)/$(INSTSONAME); \ + fi \ + else \ + if test -d "$(LDLIBRARY).dSYM"; then \ + echo $(DSYMUTIL_PATH) $(DESTDIR)$(PYTHONFRAMEWORKPREFIX)/$(INSTSONAME); \ + $(DSYMUTIL_PATH) $(DESTDIR)$(PYTHONFRAMEWORKPREFIX)/$(INSTSONAME); \ + fi \ + fi -bininstall: altbininstall +.PHONY: bininstall +# We depend on commoninstall here to make sure the installation is already usable +# before we possibly overwrite the global 'python3' symlink to avoid causing +# problems for anything else trying to run 'python3' while we install, particularly +# if we're installing in parallel with -j. +bininstall: commoninstall altbininstall if test ! -d $(DESTDIR)$(LIBPC); then \ echo "Creating directory $(LIBPC)"; \ $(INSTALL) -d -m $(DIRMODE) $(DESTDIR)$(LIBPC); \ @@ -1879,6 +2058,7 @@ bininstall: altbininstall fi # Install the versioned manual page +.PHONY: altmaninstall altmaninstall: @for i in $(MANDIR) $(MANDIR)/man1; \ do \ @@ -1892,6 +2072,7 @@ altmaninstall: $(DESTDIR)$(MANDIR)/man1/python$(VERSION).1 # Install the unversioned manual page +.PHONY: maninstall maninstall: altmaninstall -rm -f $(DESTDIR)$(MANDIR)/man1/python3.1 (cd $(DESTDIR)$(MANDIR)/man1; $(LN) -s python$(VERSION).1 python3.1) @@ -1905,7 +2086,6 @@ LIBSUBDIRS= asyncio \ ctypes ctypes/macholib \ curses \ dbm \ - distutils distutils/command \ email email/mime \ encodings \ ensurepip ensurepip/_bundled \ @@ -1930,24 +2110,32 @@ LIBSUBDIRS= asyncio \ wsgiref \ $(XMLLIBSUBDIRS) \ xmlrpc \ + zipfile zipfile/_path \ zoneinfo \ __phello__ -TESTSUBDIRS= ctypes/test \ - distutils/tests \ - idlelib/idle_test \ - lib2to3/tests \ - lib2to3/tests/data \ - lib2to3/tests/data/fixers \ - lib2to3/tests/data/fixers/myfixes \ - test test/audiodata \ - test/capath test/cjkencodings \ - test/data test/decimaltestdata \ - test/dtracedata test/eintrdata \ - test/encoded_modules test/imghdrdata \ - test/libregrtest test/sndhdrdata \ - test/subprocessdata test/support \ +TESTSUBDIRS= idlelib/idle_test \ + test \ + test/audiodata \ + test/capath \ + test/cjkencodings \ + test/crashers \ + test/data \ + test/decimaltestdata \ + test/dtracedata \ + test/encoded_modules \ + test/imghdrdata \ + test/leakers \ + test/libregrtest \ + test/sndhdrdata \ + test/subprocessdata \ + test/support \ + test/support/_hypothesis_stubs \ test/test_asyncio \ - test/test_email test/test_email/data \ + test/test_capi \ + test/test_cppext \ + test/test_ctypes \ + test/test_email \ + test/test_email/data \ test/test_import \ test/test_import/data \ test/test_import/data/circular_imports \ @@ -1960,15 +2148,6 @@ TESTSUBDIRS= ctypes/test \ test/test_importlib \ test/test_importlib/builtin \ test/test_importlib/data \ - test/test_importlib/data01 \ - test/test_importlib/data01/subdirectory \ - test/test_importlib/data02 \ - test/test_importlib/data02/one \ - test/test_importlib/data02/two \ - test/test_importlib/data03 \ - test/test_importlib/data03/namespace \ - test/test_importlib/data03/namespace/portion1 \ - test/test_importlib/data03/namespace/portion2 \ test/test_importlib/extension \ test/test_importlib/frozen \ test/test_importlib/import_ \ @@ -1992,26 +2171,71 @@ TESTSUBDIRS= ctypes/test \ test/test_importlib/namespace_pkgs/project3 \ test/test_importlib/namespace_pkgs/project3/parent \ test/test_importlib/namespace_pkgs/project3/parent/child \ - test/test_importlib/namespacedata01 \ test/test_importlib/partial \ test/test_importlib/resources \ + test/test_importlib/resources/data01 \ + test/test_importlib/resources/data01/subdirectory \ + test/test_importlib/resources/data02 \ + test/test_importlib/resources/data02/one \ + test/test_importlib/resources/data02/subdirectory \ + test/test_importlib/resources/data02/subdirectory/subsubdir \ + test/test_importlib/resources/data02/two \ + test/test_importlib/resources/data03 \ + test/test_importlib/resources/data03/namespace \ + test/test_importlib/resources/data03/namespace/portion1 \ + test/test_importlib/resources/data03/namespace/portion2 \ + test/test_importlib/resources/namespacedata01 \ + test/test_importlib/resources/zipdata01 \ + test/test_importlib/resources/zipdata02 \ test/test_importlib/source \ - test/test_importlib/zipdata01 \ - test/test_importlib/zipdata02 \ test/test_json \ + test/test_lib2to3 \ + test/test_lib2to3/data \ + test/test_lib2to3/data/fixers \ + test/test_lib2to3/data/fixers/myfixes \ + test/test_module \ test/test_peg_generator \ + test/test_sqlite3 \ + test/test_tkinter \ + test/test_tomllib \ + test/test_tomllib/data \ + test/test_tomllib/data/invalid \ + test/test_tomllib/data/invalid/array \ + test/test_tomllib/data/invalid/array-of-tables \ + test/test_tomllib/data/invalid/boolean \ + test/test_tomllib/data/invalid/dates-and-times \ + test/test_tomllib/data/invalid/dotted-keys \ + test/test_tomllib/data/invalid/inline-table \ + test/test_tomllib/data/invalid/keys-and-vals \ + test/test_tomllib/data/invalid/literal-str \ + test/test_tomllib/data/invalid/multiline-basic-str \ + test/test_tomllib/data/invalid/multiline-literal-str \ + test/test_tomllib/data/invalid/table \ + test/test_tomllib/data/valid \ + test/test_tomllib/data/valid/array \ + test/test_tomllib/data/valid/dates-and-times \ + test/test_tomllib/data/valid/multiline-basic-str \ test/test_tools \ - test/test_warnings test/test_warnings/data \ - test/test_zoneinfo test/test_zoneinfo/data \ + test/test_ttk \ + test/test_unittest \ + test/test_unittest/testmock \ + test/test_warnings \ + test/test_warnings/data \ + test/test_zipfile \ + test/test_zipfile/_path \ + test/test_zoneinfo \ + test/test_zoneinfo/data \ test/tracedmodules \ test/typinganndata \ - test/xmltestdata test/xmltestdata/c14n-20 \ - test/ziptestdata \ - tkinter/test tkinter/test/test_tkinter \ - tkinter/test/test_ttk \ - unittest/test unittest/test/testmock + test/xmltestdata \ + test/xmltestdata/c14n-20 \ + test/ziptestdata + +COMPILEALL_OPTS=-j0 TEST_MODULES=@TEST_MODULES@ + +.PHONY: libinstall libinstall: all $(srcdir)/Modules/xxmodule.c @for i in $(SCRIPTDIR) $(LIBDEST); \ do \ @@ -2080,36 +2304,15 @@ libinstall: all $(srcdir)/Modules/xxmodule.c $(INSTALL_DATA) `cat pybuilddir.txt`/_sysconfigdata_$(ABIFLAGS)_$(MACHDEP)_$(MULTIARCH).py \ $(DESTDIR)$(LIBDEST); \ $(INSTALL_DATA) $(srcdir)/LICENSE $(DESTDIR)$(LIBDEST)/LICENSE.txt - if test -d $(DESTDIR)$(LIBDEST)/distutils/tests; then \ - $(INSTALL_DATA) $(srcdir)/Modules/xxmodule.c \ - $(DESTDIR)$(LIBDEST)/distutils/tests ; \ - fi - -PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \ - $(PYTHON_FOR_BUILD) -Wi $(DESTDIR)$(LIBDEST)/compileall.py \ - -j0 -d $(LIBDEST) -f \ - -x 'bad_coding|badsyntax|site-packages|lib2to3/tests/data' \ - $(DESTDIR)$(LIBDEST) + @ # Build PYC files for the 3 optimization levels (0, 1, 2) -PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \ - $(PYTHON_FOR_BUILD) -Wi -O $(DESTDIR)$(LIBDEST)/compileall.py \ - -j0 -d $(LIBDEST) -f \ - -x 'bad_coding|badsyntax|site-packages|lib2to3/tests/data' \ - $(DESTDIR)$(LIBDEST) - -PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \ - $(PYTHON_FOR_BUILD) -Wi -OO $(DESTDIR)$(LIBDEST)/compileall.py \ - -j0 -d $(LIBDEST) -f \ - -x 'bad_coding|badsyntax|site-packages|lib2to3/tests/data' \ + $(PYTHON_FOR_BUILD) -Wi $(DESTDIR)$(LIBDEST)/compileall.py \ + -o 0 -o 1 -o 2 $(COMPILEALL_OPTS) -d $(LIBDEST) -f \ + -x 'bad_coding|badsyntax|site-packages|test/test_lib2to3/data' \ $(DESTDIR)$(LIBDEST) -PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \ $(PYTHON_FOR_BUILD) -Wi $(DESTDIR)$(LIBDEST)/compileall.py \ - -j0 -d $(LIBDEST)/site-packages -f \ - -x badsyntax $(DESTDIR)$(LIBDEST)/site-packages - -PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \ - $(PYTHON_FOR_BUILD) -Wi -O $(DESTDIR)$(LIBDEST)/compileall.py \ - -j0 -d $(LIBDEST)/site-packages -f \ - -x badsyntax $(DESTDIR)$(LIBDEST)/site-packages - -PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \ - $(PYTHON_FOR_BUILD) -Wi -OO $(DESTDIR)$(LIBDEST)/compileall.py \ - -j0 -d $(LIBDEST)/site-packages -f \ + -o 0 -o 1 -o 2 $(COMPILEALL_OPTS) -d $(LIBDEST)/site-packages -f \ -x badsyntax $(DESTDIR)$(LIBDEST)/site-packages -PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \ $(PYTHON_FOR_BUILD) -m lib2to3.pgen2.driver $(DESTDIR)$(LIBDEST)/lib2to3/Grammar.txt @@ -2121,7 +2324,7 @@ libinstall: all $(srcdir)/Modules/xxmodule.c python-config: $(srcdir)/Misc/python-config.in Misc/python-config.sh @ # Substitution happens here, as the completely-expanded BINDIR @ # is not available in configure - sed -e "s,@EXENAME@,$(BINDIR)/python$(LDVERSION)$(EXE)," < $(srcdir)/Misc/python-config.in >python-config.py + sed -e "s,@EXENAME@,$(EXENAME)," < $(srcdir)/Misc/python-config.in >python-config.py @ # Replace makefile compat. variable references with shell script compat. ones; $(VAR) -> ${VAR} LC_ALL=C sed -e 's,\$$(\([A-Za-z0-9_]*\)),\$$\{\1\},g' < Misc/python-config.sh >python-config @ # On Darwin, always use the python version of the script, the shell @@ -2131,9 +2334,35 @@ python-config: $(srcdir)/Misc/python-config.in Misc/python-config.sh cp python-config.py python-config; \ fi +# macOS' make seems to ignore a dependency on a +# "$(BUILD_SCRIPTS_DIR): $(MKDIR_P) $@" rule. +BUILD_SCRIPTS_DIR=build/scripts-$(VERSION) +SCRIPT_2TO3=$(BUILD_SCRIPTS_DIR)/2to3-$(VERSION) +SCRIPT_IDLE=$(BUILD_SCRIPTS_DIR)/idle$(VERSION) +SCRIPT_PYDOC=$(BUILD_SCRIPTS_DIR)/pydoc$(VERSION) + +$(SCRIPT_2TO3): $(srcdir)/Tools/scripts/2to3 + @$(MKDIR_P) $(BUILD_SCRIPTS_DIR) + sed -e "s,/usr/bin/env python3,$(EXENAME)," < $(srcdir)/Tools/scripts/2to3 > $@ + @chmod +x $@ + +$(SCRIPT_IDLE): $(srcdir)/Tools/scripts/idle3 + @$(MKDIR_P) $(BUILD_SCRIPTS_DIR) + sed -e "s,/usr/bin/env python3,$(EXENAME)," < $(srcdir)/Tools/scripts/idle3 > $@ + @chmod +x $@ + +$(SCRIPT_PYDOC): $(srcdir)/Tools/scripts/pydoc3 + @$(MKDIR_P) $(BUILD_SCRIPTS_DIR) + sed -e "s,/usr/bin/env python3,$(EXENAME)," < $(srcdir)/Tools/scripts/pydoc3 > $@ + @chmod +x $@ + +.PHONY: scripts +scripts: $(SCRIPT_2TO3) $(SCRIPT_IDLE) $(SCRIPT_PYDOC) python-config # Install the include files INCLDIRSTOMAKE=$(INCLUDEDIR) $(CONFINCLUDEDIR) $(INCLUDEPY) $(CONFINCLUDEPY) + +.PHONY: inclinstall inclinstall: @for i in $(INCLDIRSTOMAKE); \ do \ @@ -2177,7 +2406,8 @@ LIBPL= @LIBPL@ # pkgconfig directory LIBPC= $(LIBDIR)/pkgconfig -libainstall: all python-config +.PHONY: libainstall +libainstall: all scripts @for i in $(LIBDIR) $(LIBPL) $(LIBPC) $(BINDIR); \ do \ if test ! -d $(DESTDIR)$$i; then \ @@ -2213,6 +2443,9 @@ libainstall: all python-config $(INSTALL_SCRIPT) $(srcdir)/install-sh $(DESTDIR)$(LIBPL)/install-sh $(INSTALL_SCRIPT) python-config.py $(DESTDIR)$(LIBPL)/python-config.py $(INSTALL_SCRIPT) python-config $(DESTDIR)$(BINDIR)/python$(LDVERSION)-config + $(INSTALL_SCRIPT) $(SCRIPT_2TO3) $(DESTDIR)$(BINDIR)/2to3-$(VERSION) + $(INSTALL_SCRIPT) $(SCRIPT_IDLE) $(DESTDIR)$(BINDIR)/idle$(VERSION) + $(INSTALL_SCRIPT) $(SCRIPT_PYDOC) $(DESTDIR)$(BINDIR)/pydoc$(VERSION) @if [ -s Modules/python.exp -a \ "`echo $(MACHDEP) | sed 's/^\(...\).*/\1/'`" = "aix" ]; then \ echo; echo "Installing support files for building shared extension modules on AIX:"; \ @@ -2229,17 +2462,6 @@ libainstall: all python-config else true; \ fi -# Install the dynamically loadable modules -# This goes into $(exec_prefix) -sharedinstall: all - $(RUNSHARED) $(PYTHON_FOR_BUILD) $(srcdir)/setup.py install \ - --prefix=$(prefix) \ - --install-scripts=$(BINDIR) \ - --install-platlib=$(DESTSHARED) \ - --root=$(DESTDIR)/ - -rm $(DESTDIR)$(DESTSHARED)/_sysconfigdata_$(ABIFLAGS)_$(MACHDEP)_$(MULTIARCH).py - -rm -r $(DESTDIR)$(DESTSHARED)/__pycache__ - # Here are a couple of targets for MacOSX again, to install a full # framework-based Python. frameworkinstall installs everything, the # subtargets install specific parts. Much of the actual work is offloaded to @@ -2248,6 +2470,7 @@ sharedinstall: all # # This target is here for backward compatibility, previous versions of Python # hadn't integrated framework installation in the normal install process. +.PHONY: frameworkinstall frameworkinstall: install # On install, we re-make the framework @@ -2256,8 +2479,10 @@ frameworkinstall: install # automatically set prefix to the location deep down in the framework, so we # only have to cater for the structural bits of the framework. +.PHONY: frameworkinstallframework frameworkinstallframework: frameworkinstallstructure install frameworkinstallmaclib +.PHONY: frameworkinstallstructure frameworkinstallstructure: $(LDLIBRARY) @if test "$(PYTHONFRAMEWORKDIR)" = no-framework; then \ echo Not configured with --enable-framework; \ @@ -2282,6 +2507,7 @@ frameworkinstallstructure: $(LDLIBRARY) # This installs Mac/Lib into the framework # Install a number of symlinks to keep software that expects a normal unix # install (which includes python-config) happy. +.PHONY: frameworkinstallmaclib frameworkinstallmaclib: $(LN) -fs "../../../$(PYTHONFRAMEWORK)" "$(DESTDIR)$(LIBPL)/libpython$(LDVERSION).a" $(LN) -fs "../../../$(PYTHONFRAMEWORK)" "$(DESTDIR)$(LIBPL)/libpython$(LDVERSION).dylib" @@ -2291,39 +2517,47 @@ frameworkinstallmaclib: $(LN) -fs "../$(PYTHONFRAMEWORK)" "$(DESTDIR)$(prefix)/lib/libpython$(VERSION).dylib" # This installs the IDE, the Launcher and other apps into /Applications +.PHONY: frameworkinstallapps frameworkinstallapps: cd Mac && $(MAKE) installapps DESTDIR="$(DESTDIR)" # Build the bootstrap executable that will spawn the interpreter inside # an app bundle within the framework. This allows the interpreter to # run OS X GUI APIs. +.PHONY: frameworkpythonw frameworkpythonw: cd Mac && $(MAKE) pythonw # This installs the python* and other bin symlinks in $prefix/bin or in # a bin directory relative to the framework root +.PHONY: frameworkinstallunixtools frameworkinstallunixtools: cd Mac && $(MAKE) installunixtools DESTDIR="$(DESTDIR)" +.PHONY: frameworkaltinstallunixtools frameworkaltinstallunixtools: cd Mac && $(MAKE) altinstallunixtools DESTDIR="$(DESTDIR)" # This installs the Tools into the applications directory. # It is not part of a normal frameworkinstall +.PHONY: frameworkinstallextras frameworkinstallextras: cd Mac && $(MAKE) installextras DESTDIR="$(DESTDIR)" # Build the toplevel Makefile Makefile.pre: $(srcdir)/Makefile.pre.in config.status - CONFIG_FILES=Makefile.pre CONFIG_HEADERS= $(SHELL) config.status + CONFIG_FILES=Makefile.pre CONFIG_HEADERS= ./config.status $(MAKE) -f Makefile.pre Makefile # Run the configure script. config.status: $(srcdir)/configure - $(SHELL) $(srcdir)/configure $(CONFIG_ARGS) + $(srcdir)/configure $(CONFIG_ARGS) .PRECIOUS: config.status $(BUILDPYTHON) Makefile Makefile.pre +Python/asm_trampoline.o: $(srcdir)/Python/asm_trampoline.S + $(CC) -c $(PY_CORE_CFLAGS) -o $@ $< + # Some make's put the object file in the current directory .c.o: $(CC) -c $(PY_CORE_CFLAGS) -o $@ $< @@ -2336,26 +2570,29 @@ Python/dtoa.o: Python/dtoa.c $(CC) -c $(PY_CORE_CFLAGS) $(CFLAGS_ALIASING) -o $@ $< # Run reindent on the library +.PHONY: reindent reindent: - ./$(BUILDPYTHON) $(srcdir)/Tools/scripts/reindent.py -r $(srcdir)/Lib + ./$(BUILDPYTHON) $(srcdir)/Tools/patchcheck/reindent.py -r $(srcdir)/Lib # Rerun configure with the same options as it was run last time, # provided the config.status script exists +.PHONY: recheck recheck: - $(SHELL) config.status --recheck - $(SHELL) config.status + ./config.status --recheck + ./config.status # Regenerate configure and pyconfig.h.in .PHONY: autoconf autoconf: (cd $(srcdir); autoreconf -ivf -Werror) +# See https://github.com/tiran/cpython_autoconf container .PHONY: regen-configure regen-configure: @if command -v podman >/dev/null; then RUNTIME="podman"; else RUNTIME="docker"; fi; \ if ! command -v $$RUNTIME; then echo "$@ needs either Podman or Docker container runtime." >&2; exit 1; fi; \ if command -v selinuxenabled >/dev/null && selinuxenabled; then OPT=":Z"; fi; \ - CMD="$$RUNTIME run --rm --pull=always -v $(abs_srcdir):/src$$OPT quay.io/tiran/cpython_autoconf:269"; \ + CMD="$$RUNTIME run --rm --pull=always -v $(abs_srcdir):/src$$OPT quay.io/tiran/cpython_autoconf:271"; \ echo $$CMD; \ $$CMD || exit $? @@ -2377,10 +2614,12 @@ TAGS:: # Sanitation targets -- clean leaves libraries, executables and tags # files, which clobber removes as well +.PHONY: pycremoval pycremoval: -find $(srcdir) -depth -name '__pycache__' -exec rm -rf {} ';' -find $(srcdir) -name '*.py[co]' -exec rm -f {} ';' +.PHONY: rmtestturds rmtestturds: -rm -f *BAD *GOOD *SKIPPED -rm -rf OUT @@ -2388,15 +2627,18 @@ rmtestturds: -rm -f *.txt -rm -f gb-18030-2000.xml +.PHONY: docclean docclean: $(MAKE) -C $(srcdir)/Doc clean # like the 'clean' target but retain the profile guided optimization (PGO) # data. The PGO data is only valid if source code remains unchanged. +.PHONY: clean-retain-profile clean-retain-profile: pycremoval find . -name '*.[oa]' -exec rm -f {} ';' find . -name '*.s[ol]' -exec rm -f {} ';' find . -name '*.so.[0-9]*.[0-9]*' -exec rm -f {} ';' + find . -name '*.lto' -exec rm -f {} ';' find . -name '*.wasm' -exec rm -f {} ';' find . -name '*.lst' -exec rm -f {} ';' find build -name 'fficonfig.h' -exec rm -f {} ';' || true @@ -2415,6 +2657,7 @@ clean-retain-profile: pycremoval -rm -f Include/pydtrace_probes.h -rm -f profile-gen-stamp +.PHONY: profile-removal profile-removal: find . -name '*.gc??' -exec rm -f {} ';' find . -name '*.profclang?' -exec rm -f {} ';' @@ -2422,13 +2665,16 @@ profile-removal: rm -f $(COVERAGE_INFO) rm -rf $(COVERAGE_REPORT) rm -f profile-run-stamp + rm -f profile-bolt-stamp -clean: clean-retain-profile - @if test @DEF_MAKE_ALL_RULE@ = profile-opt; then \ +.PHONY: clean +clean: clean-retain-profile clean-bolt + @if test @DEF_MAKE_ALL_RULE@ = profile-opt -o @DEF_MAKE_ALL_RULE@ = bolt-opt; then \ rm -f profile-gen-stamp profile-clean-stamp; \ $(MAKE) profile-removal; \ fi +.PHONY: clobber clobber: clean -rm -f $(BUILDPYTHON) $(LIBRARY) $(LDLIBRARY) $(DLLLIBRARY) \ tags TAGS \ @@ -2440,6 +2686,7 @@ clobber: clean # Make things extra clean, before making a distribution: # remove all generated files, even Makefile[.pre] # Keep configure and Python-ast.[ch], it's possible they can't be generated +.PHONY: distclean distclean: clobber docclean for file in $(srcdir)/Lib/test/data/* ; do \ if test "$$file" != "$(srcdir)/Lib/test/data/README"; then rm "$$file"; fi; \ @@ -2460,10 +2707,19 @@ distclean: clobber docclean -exec rm -f {} ';' # Check that all symbols exported by libpython start with "Py" or "_Py" +.PHONY: smelly smelly: all - $(RUNSHARED) ./$(BUILDPYTHON) $(srcdir)/Tools/scripts/smelly.py + $(RUNSHARED) ./$(BUILDPYTHON) $(srcdir)/Tools/build/smelly.py + +# Check if any unsupported C global variables have been added. +.PHONY: check-c-globals +check-c-globals: + $(PYTHON_FOR_REGEN) $(srcdir)/Tools/c-analyzer/check-c-globals.py \ + --format summary \ + --traceback # Find files with funny names +.PHONY: funny funny: find $(SUBDIRS) $(SUBDIRSTOO) \ -type d \ @@ -2495,11 +2751,13 @@ funny: -o -print # Perform some verification checks on any modified files. +.PHONY: patchcheck patchcheck: all - $(RUNSHARED) ./$(BUILDPYTHON) $(srcdir)/Tools/scripts/patchcheck.py + $(RUNSHARED) ./$(BUILDPYTHON) $(srcdir)/Tools/patchcheck/patchcheck.py +.PHONY: check-limited-abi check-limited-abi: all - $(RUNSHARED) ./$(BUILDPYTHON) $(srcdir)/Tools/scripts/stable_abi.py --all $(srcdir)/Misc/stable_abi.toml + $(RUNSHARED) ./$(BUILDPYTHON) $(srcdir)/Tools/build/stable_abi.py --all $(srcdir)/Misc/stable_abi.toml .PHONY: update-config update-config: @@ -2511,20 +2769,12 @@ update-config: Python/thread.o: @THREADHEADERS@ $(srcdir)/Python/condvar.h -# Declare targets that aren't real files -.PHONY: all build_all build_wasm sharedmods check-clean-src oldsharedmods test quicktest -.PHONY: install altinstall oldsharedinstall bininstall altbininstall -.PHONY: maninstall libinstall inclinstall libainstall sharedinstall -.PHONY: frameworkinstall frameworkinstallframework frameworkinstallstructure -.PHONY: frameworkinstallmaclib frameworkinstallapps frameworkinstallunixtools -.PHONY: frameworkaltinstallunixtools recheck clean clobber distclean -.PHONY: smelly funny patchcheck touch altmaninstall commoninstall -.PHONY: clean-retain-profile profile-removal run_profile_task -.PHONY: build_all_generate_profile build_all_merge_profile -.PHONY: gdbhooks - ########################################################################## -# Module dependencies +# Module dependencies and platform-specific files + +# force rebuild when header file or module build flavor (static/shared) is changed +MODULE_DEPS_STATIC=Modules/config.c +MODULE_DEPS_SHARED=$(MODULE_DEPS_STATIC) $(EXPORTSYMS) MODULE_CMATH_DEPS=$(srcdir)/Modules/_math.h MODULE_MATH_DEPS=$(srcdir)/Modules/_math.h @@ -2532,20 +2782,29 @@ MODULE_PYEXPAT_DEPS=@LIBEXPAT_INTERNAL@ MODULE_UNICODEDATA_DEPS=$(srcdir)/Modules/unicodedata_db.h $(srcdir)/Modules/unicodename_db.h MODULE__BLAKE2_DEPS=$(srcdir)/Modules/_blake2/impl/blake2-config.h $(srcdir)/Modules/_blake2/impl/blake2-impl.h $(srcdir)/Modules/_blake2/impl/blake2.h $(srcdir)/Modules/_blake2/impl/blake2b-load-sse2.h $(srcdir)/Modules/_blake2/impl/blake2b-load-sse41.h $(srcdir)/Modules/_blake2/impl/blake2b-ref.c $(srcdir)/Modules/_blake2/impl/blake2b-round.h $(srcdir)/Modules/_blake2/impl/blake2b.c $(srcdir)/Modules/_blake2/impl/blake2s-load-sse2.h $(srcdir)/Modules/_blake2/impl/blake2s-load-sse41.h $(srcdir)/Modules/_blake2/impl/blake2s-load-xop.h $(srcdir)/Modules/_blake2/impl/blake2s-ref.c $(srcdir)/Modules/_blake2/impl/blake2s-round.h $(srcdir)/Modules/_blake2/impl/blake2s.c $(srcdir)/Modules/_blake2/blake2module.h $(srcdir)/Modules/hashlib.h MODULE__CTYPES_DEPS=$(srcdir)/Modules/_ctypes/ctypes.h +MODULE__CTYPES_MALLOC_CLOSURE=@MODULE__CTYPES_MALLOC_CLOSURE@ MODULE__DECIMAL_DEPS=$(srcdir)/Modules/_decimal/docstrings.h @LIBMPDEC_INTERNAL@ MODULE__ELEMENTTREE_DEPS=$(srcdir)/Modules/pyexpat.c @LIBEXPAT_INTERNAL@ MODULE__HASHLIB_DEPS=$(srcdir)/Modules/hashlib.h MODULE__IO_DEPS=$(srcdir)/Modules/_io/_iomodule.h -MODULE__MD5_DEPS=$(srcdir)/Modules/hashlib.h -MODULE__SHA1_DEPS=$(srcdir)/Modules/hashlib.h -MODULE__SHA256_DEPS=$(srcdir)/Modules/hashlib.h -MODULE__SHA3_DEPS=$(srcdir)/Modules/_sha3/sha3.c $(srcdir)/Modules/_sha3/sha3.h $(srcdir)/Modules/hashlib.h -MODULE__SHA512_DEPS=$(srcdir)/Modules/hashlib.h +MODULE__MD5_DEPS=$(srcdir)/Modules/hashlib.h $(LIBHACL_HEADERS) Modules/_hacl/Hacl_Hash_MD5.h Modules/_hacl/Hacl_Hash_MD5.c +MODULE__SHA1_DEPS=$(srcdir)/Modules/hashlib.h $(LIBHACL_HEADERS) Modules/_hacl/Hacl_Hash_SHA1.h Modules/_hacl/Hacl_Hash_SHA1.c +MODULE__SHA2_DEPS=$(srcdir)/Modules/hashlib.h $(LIBHACL_SHA2_HEADERS) $(LIBHACL_SHA2_A) +MODULE__SHA3_DEPS=$(srcdir)/Modules/hashlib.h $(LIBHACL_HEADERS) Modules/_hacl/Hacl_Hash_SHA3.h Modules/_hacl/Hacl_Hash_SHA3.c MODULE__SOCKET_DEPS=$(srcdir)/Modules/socketmodule.h $(srcdir)/Modules/addrinfo.h $(srcdir)/Modules/getaddrinfo.c $(srcdir)/Modules/getnameinfo.c MODULE__SSL_DEPS=$(srcdir)/Modules/_ssl.h $(srcdir)/Modules/_ssl/cert.c $(srcdir)/Modules/_ssl/debughelpers.c $(srcdir)/Modules/_ssl/misc.c $(srcdir)/Modules/_ssl_data.h $(srcdir)/Modules/_ssl_data_111.h $(srcdir)/Modules/_ssl_data_300.h $(srcdir)/Modules/socketmodule.h -MODULE__TESTCAPI_DEPS=$(srcdir)/Modules/testcapi_long.h +MODULE__TESTCAPI_DEPS=$(srcdir)/Modules/_testcapi/testcapi_long.h $(srcdir)/Modules/_testcapi/parts.h $(srcdir)/Modules/_testcapi/util.h MODULE__SQLITE3_DEPS=$(srcdir)/Modules/_sqlite/connection.h $(srcdir)/Modules/_sqlite/cursor.h $(srcdir)/Modules/_sqlite/microprotocols.h $(srcdir)/Modules/_sqlite/module.h $(srcdir)/Modules/_sqlite/prepare_protocol.h $(srcdir)/Modules/_sqlite/row.h $(srcdir)/Modules/_sqlite/util.h +CODECS_COMMON_HEADERS=$(srcdir)/Modules/cjkcodecs/multibytecodec.h $(srcdir)/Modules/cjkcodecs/cjkcodecs.h +MODULE__CODECS_CN_DEPS=$(srcdir)/Modules/cjkcodecs/mappings_cn.h $(CODECS_COMMON_HEADERS) +MODULE__CODECS_HK_DEPS=$(srcdir)/Modules/cjkcodecs/mappings_hk.h $(CODECS_COMMON_HEADERS) +MODULE__CODECS_ISO2022_DEPS=$(srcdir)/Modules/cjkcodecs/mappings_jisx0213_pair.h $(srcdir)/Modules/cjkcodecs/alg_jisx0201.h $(srcdir)/Modules/cjkcodecs/emu_jisx0213_2000.h $(CODECS_COMMON_HEADERS) +MODULE__CODECS_JP_DEPS=$(srcdir)/Modules/cjkcodecs/mappings_jisx0213_pair.h $(srcdir)/Modules/cjkcodecs/alg_jisx0201.h $(srcdir)/Modules/cjkcodecs/emu_jisx0213_2000.h $(srcdir)/Modules/cjkcodecs/mappings_jp.h $(CODECS_COMMON_HEADERS) +MODULE__CODECS_KR_DEPS=$(srcdir)/Modules/cjkcodecs/mappings_kr.h $(CODECS_COMMON_HEADERS) +MODULE__CODECS_TW_DEPS=$(srcdir)/Modules/cjkcodecs/mappings_tw.h $(CODECS_COMMON_HEADERS) +MODULE__MULTIBYTECODEC_DEPS=$(srcdir)/Modules/cjkcodecs/multibytecodec.h + # IF YOU PUT ANYTHING HERE IT WILL GO AWAY # Local Variables: # mode: makefile diff --git a/Misc/ACKS b/Misc/ACKS index f6743327..7deef8ba 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -160,6 +160,7 @@ Brice Berna Olivier Bernard Vivien Bernet-Rollande Maxwell Bernstein +Jay Berry Eric Beser Steven Bethard Stephen Bevan @@ -198,6 +199,7 @@ Gawain Bolton Carl Friedrich Bolz-Tereick Forest Bond Gregory Bond +David Bonner Angelin Booz Médéric Boquien Matias Bordese @@ -224,6 +226,7 @@ Erik Bray Brian Brazil Demian Brecht Dave Brennan +Christopher Richard James Brett Tom Bridgman Anthony Briggs Keith Briggs @@ -296,6 +299,8 @@ Michael Cetrulo Dave Chambers Pascal Chambon Nicholas Chammas +Ofey Chan +Juhi Chandalia John Chandler Hye-Shik Chang Jeffrey Chang @@ -313,12 +318,14 @@ Nicolas Chauvat Jerry Chen Michael Chermside Ingrid Cheung +Adam Chhina Terry Chia Albert Chin-A-Young Adal Chiriliuc Matt Chisholm Lita Cho Kit Yan Choi +Byeongmin Choi Sayan Chowdhury Yuan-Chao Chou Anders Chrigström @@ -342,6 +349,7 @@ Hervé Coatanhay Riccardo Coccioli Nick Coghlan Josh Cogliati +Noam Cohen Dave Cole Terrence Cole Benjamin Collar @@ -494,6 +502,7 @@ Daniel Ellis Phil Elson David Ely Victor van den Elzen +Vlad Emelianov Jeff Epler Tom Epperly Gökcen Eraslan @@ -608,6 +617,8 @@ Marius Gedminas Jan-Philip Gehrcke Thomas Gellekum Gabriel Genellina +Andrew Geng +Philip Georgi Christos Georgiou Elazar (אלעזר) Gershuni Ben Gertzfield @@ -621,6 +632,7 @@ Julian Gindi Yannick Gingras Neil Girdhar Matt Giuca +Andrea Giudiceandrea Franz Glasner Wim Glenn Michael Goderbauer @@ -631,11 +643,13 @@ Tim Golden Yonatan Goldschmidt Mark Gollahon Mikhail Golubev +Marta Gómez Macías Guilherme Gonçalves Tiago Gonçalves Chris Gonnerman Shelley Gooch David Goodger +Michał Górny Elliot Gorokhovsky Hans de Graaff Tim Graham @@ -685,6 +699,7 @@ Anders Hammarquist Mark Hammond Harald Hanche-Olsen Manus Hand +Michael Handler Andreas Hangauer Milton L. Hankins Carl Bordum Hansen @@ -742,11 +757,13 @@ Aaron Hill Joel Hillacre Richie Hindle Konrad Hinsen +Richard Hoberecht David Hobley Tim Hochberg Benjamin Hodgson Joerg-Cyril Hoehle Douwe Hoekstra +Robert Hoelzl Gregor Hoffleit Chris Hoffman Tim Hoffmann @@ -919,8 +936,10 @@ Tyler Kieft Mads Kiilerich Jason Killen Derek D. Kim +Gihwan Kim Jan Kim Taek Joo Kim +Yeojin Kim Sam Kimbrel Tomohiko Kinebuchi James King @@ -1047,7 +1066,7 @@ Robert Lehmann Petri Lehtinen Luke Kenneth Casson Leighton John Leitch -Tshepang Lekhonkhobe +Tshepang Mbambo Marc-André Lemburg Mateusz Lenik John Lenton @@ -1101,6 +1120,7 @@ Jason Lowe Tony Lownds Ray Loyzaga Kang-Hao (Kenny) Lu +Raymond Lu Lukas Lueg Loren Luke Fredrik Lundh @@ -1130,6 +1150,7 @@ Colin Marc Vincent Marchetti David Marek Doug Marien +Chris Markiewicz Sven Marnach John Marshall Alex Martelli @@ -1211,6 +1232,7 @@ Gideon Mitchell Tim Mitchell Zubin Mithra Florian Mladitsch +Kevin Modzelewski Doug Moen Jakub Molinski Juliette Monsel @@ -1219,6 +1241,7 @@ The Dragon De Monsyne Bastien Montagne Skip Montanaro Peter Moody +HyunKyun Moon Alan D. Moore Nicolai Moore Paul Moore @@ -1233,6 +1256,7 @@ Alessandro Moura Pablo Mouzo Mher Movsisyan Ruslan Mstoi +Marc Mueller Valentina Mukhamedzhanova Michael Mulich Sape Mullender @@ -1244,7 +1268,7 @@ R. David Murray Matti Mäki Jörg Müller Kaushik N -Dong-hee Na +Donghee Na Dale Nagata John Nagle Takahiro Nakayama @@ -1295,6 +1319,7 @@ Jon Oberheide Milan Oberkirch Pascal Oberndoerfer Géry Ogam +Seonkyo Ok Jeffrey Ollie Adam Olsen Bryan Olson @@ -1305,6 +1330,7 @@ Ethan Onstott Ken Jin Ooi Piet van Oostrum Tomas Oppelstrup +Itamar Oren Jason Orendorff Yan "yyyyyyyan" Orestes Bastien Orivel @@ -1368,6 +1394,7 @@ Thomas Perl Mathieu Perreault Mark Perrego Trevor Perrin +Yonatan Perry Gabriel de Perthuis Tim Peters Benjamin Peterson @@ -1436,6 +1463,7 @@ Pierre Quentel Brian Quinlan Anders Qvist Thomas Rachel +Domenico Ragusa Ram Rachum Jeffrey Rackauckas Jérôme Radix @@ -1461,9 +1489,10 @@ Edward K. Ream Chris Rebert Marc Recht John Redford +Kalyan Reddy Terry J. Reedy Gareth Rees -John Reese +Amethyst Reese Steve Reeves Lennart Regebro John Regehr @@ -1488,6 +1517,7 @@ Vlad Riscutia Wes Rishel Daniel Riti Juan M. Bello Rivas +Stefano Rivera Llandy Riveron Del Risco Mohd Sanad Zaki Rizvi Davide Rizzo @@ -1527,6 +1557,7 @@ Hugo van Rossum Saskia van Rossum Robin Roth Clement Rouault +Tomas Roun Donald Wallace Rouse II Liam Routt Todd Rovito @@ -1555,6 +1586,7 @@ Patrick Sabin Sébastien Sablé Amit Saha Suman Saha +Koki Saito Hajime Saitou George Sakkis Victor Salgado @@ -1593,6 +1625,7 @@ Ed Schouten Scott Schram Robin Schreiber Chad J. Schroeder +Simon-Martin Schroeder Christian Schubert Sam Schulenburg Andreas Schwab @@ -1619,6 +1652,7 @@ Silas Sewell Ian Seyer Dmitry Shachnev Anish Shah +Jaineel Shah Daniel Shahaf Hui Shang Geoff Shannon @@ -1672,6 +1706,7 @@ Roman Skurikhin Ville Skyttä Michael Sloan Nick Sloan +Radek Smejkal Václav Šmilauer Casper W. Smet Allen W. Smith @@ -1827,9 +1862,11 @@ Tom Tromey John Tromp Diane Trout Jason Trowbridge +Steven Troxler Brent Tubbs Anthony Tuininga Erno Tukia +Adam Turner David Turner Stephen Turner Itamar Turner-Trauring @@ -1880,6 +1917,7 @@ Kurt Vile Norman Vine Pauli Virtanen Frank Visser +Long Vo Johannes Vogel Michael Vogt Radu Voicilas @@ -1913,6 +1951,7 @@ Colin Watson David Watson Aaron Watters Alex Waygood +James Webber Russel Webber Henrik Weber Leon Weber @@ -2027,6 +2066,7 @@ Yuxiao Zeng Uwe Zessin Cheng Zhang George Zhang +Youfu Zhang Charlie Zhao Kai Zhu Tarek Ziadé @@ -2034,7 +2074,5 @@ Jelle Zijlstra Gennadiy Zlobin Doug Zongker Peter Åstrand -Vlad Emelianov -Andrey Doroschenko (Entries should be added in rough alphabetical order by last names) diff --git a/Misc/HISTORY b/Misc/HISTORY index 0330c489..e66b695f 100644 --- a/Misc/HISTORY +++ b/Misc/HISTORY @@ -21790,7 +21790,7 @@ Library x == y is False, and x != y is True. This is akin to the change made for mixed-type comparisons of datetime objects in 2.3a2; more info about the rationale is in the NEWS entry for that. See also SF bug - report <http://www.python.org/sf/693121>. + report <https://bugs.python.org/issue693121>. - On Unix platforms, if os.listdir() is called with a Unicode argument, it now returns Unicode strings. (This behavior was added earlier @@ -22025,7 +22025,7 @@ Extension modules now. today() and now() now round system timestamps to the closest - microsecond <http://www.python.org/sf/661086>. This repairs an + microsecond <https://bugs.python.org/issue661086>. This repairs an irritation most likely seen on Windows systems. In dt.astimezone(tz), if tz.utcoffset(dt) returns a duration, @@ -22080,7 +22080,7 @@ Extension modules datetime.fromtimestamp(): Like datetime.now() above, this had less than useful behavior when the optional tinzo argument was specified. See - also SF bug report <http://www.python.org/sf/660872>. + also SF bug report <https://bugs.python.org/issue660872>. date and datetime comparison: In order to prevent comparison from falling back to the default compare-object-addresses strategy, these @@ -22139,10 +22139,10 @@ Library dependent path modules (e.g. ntpath.py) rather than os.py, so these variables are now available via os.path. They continue to be available from the os module. - (see <http://www.python.org/sf/680789>). + (see <https://bugs.python.org/issue680789>). - array.array was added to the types repr.py knows about (see - <http://www.python.org/sf/680789>). + <https://bugs.python.org/issue680789>). - The new pickletools.py contains lots of documentation about pickle internals, and supplies some helpers for working with pickles, such as @@ -22527,7 +22527,7 @@ Core and builtins potential drawback is that list.sort() may require temp space of len(list)*2 bytes (``*4`` on a 64-bit machine). It's therefore possible for list.sort() to raise MemoryError now, even if a comparison function - does not. See <http://www.python.org/sf/587076> for full details. + does not. See <https://bugs.python.org/issue587076> for full details. - All standard iterators now ensure that, once StopIteration has been raised, all future calls to next() on the same iterator will also diff --git a/Misc/NEWS b/Misc/NEWS deleted file mode 100644 index 42a3570a..00000000 --- a/Misc/NEWS +++ /dev/null @@ -1,36474 +0,0 @@ -+++++++++++ -Python News -+++++++++++ - -What's New in Python 3.11.2 final? -================================== - -*Release date: 2023-02-07* - -Core and Builtins ------------------ - -- gh-issue-92173: Fix the ``defs`` and ``kwdefs`` arguments to - :c:func:`PyEval_EvalCodeEx` and a reference leak in that function. - -- gh-issue-101400: Fix wrong lineno in exception message on - :keyword:`continue` or :keyword:`break` which are not in a loop. Patch by - Dong-hee Na. - -- gh-issue-101372: Fix :func:`~unicodedata.is_normalized` to properly handle - the UCD 3.2.0 cases. Patch by Dong-hee Na. - -- gh-issue-101046: Fix a possible memory leak in the parser when raising - :exc:`MemoryError`. Patch by Pablo Galindo - -- gh-issue-101037: Fix potential memory underallocation issue for instances - of :class:`int` subclasses with value zero. - -- gh-issue-100942: Fixed segfault in property.getter/setter/deleter that - occurred when a property subclass overrode the ``__new__`` method to - return a non-property instance. - -- gh-issue-100892: Fix race while iterating over thread states in clearing - :class:`threading.local`. Patch by Kumar Aditya. - -- gh-issue-100776: Fix misleading default value in :func:`input`'s - ``__text_signature__``. - -- gh-issue-100637: Fix :func:`int.__sizeof__` calculation to include the 1 - element ob_digit array for 0 and False. - -- gh-issue-100649: Update the native_thread_id field of PyThreadState after - fork. - -- gh-issue-100374: Fix incorrect result and delay in :func:`socket.getfqdn`. - Patch by Dominic Socular. - -- gh-issue-99110: Initialize frame->previous in frameobject.c to fix a - segmentation fault when accessing frames created by :c:func:`PyFrame_New`. - -- gh-issue-100050: Honor existing errors obtained when searching for - mismatching parentheses in the tokenizer. Patch by Pablo Galindo - -- bpo-32782: ``ctypes`` arrays of length 0 now report a correct itemsize - when a ``memoryview`` is constructed from them, rather than always giving - a value of 0. - -Library -------- - -- gh-issue-101541: [Enum] - fix psuedo-flag creation - -- gh-issue-101326: Fix regression when passing ``None`` as second or third - argument to ``FutureIter.throw``. - -- gh-issue-100795: Avoid potential unexpected ``freeaddrinfo`` call (double - free) in :mod:`socket` when when a libc ``getaddrinfo()`` implementation - leaves garbage in an output pointer when returning an error. Original - patch by Sergey G. Brester. - -- gh-issue-101143: Remove unused references to :class:`~asyncio.TimerHandle` - in ``asyncio.base_events.BaseEventLoop._add_callback``. - -- gh-issue-101144: Make :func:`zipfile.Path.open` and - :func:`zipfile.Path.read_text` also accept ``encoding`` as a positional - argument. This was the behavior in Python 3.9 and earlier. 3.10 - introduced a regression where supplying it as a positional argument would - lead to a :exc:`TypeError`. - -- gh-issue-101015: Fix :func:`typing.get_type_hints` on ``'*tuple[...]'`` - and ``*tuple[...]``. It must not drop the ``Unpack`` part. - -- gh-issue-100573: Fix a Windows :mod:`asyncio` bug with named pipes where a - client doing ``os.stat()`` on the pipe would cause an error in the server - that disabled serving future requests. - -- gh-issue-100805: Modify :func:`random.choice` implementation to once again - work with NumPy arrays. - -- gh-issue-90104: Avoid RecursionError on ``repr`` if a dataclass field - definition has a cyclic reference. - -- gh-issue-100750: pass encoding kwarg to subprocess in platform - -- gh-issue-100689: Fix crash in :mod:`pyexpat` by statically allocating - ``PyExpat_CAPI`` capsule. - -- gh-issue-100740: Fix ``unittest.mock.Mock`` not respecting the spec for - attribute names prefixed with ``assert``. - -- gh-issue-86508: Fix :func:`asyncio.open_connection` to skip binding to - local addresses of different family. Patch by Kumar Aditya. - -- gh-issue-100287: Fix the interaction of :func:`unittest.mock.seal` with - :class:`unittest.mock.AsyncMock`. - -- gh-issue-100474: :mod:`http.server` now checks that an index page is - actually a regular file before trying to serve it. This avoids issues - with directories named ``index.html``. - -- gh-issue-100160: Remove any deprecation warnings in - :func:`asyncio.get_event_loop`. They are deferred to Python 3.12. - -- gh-issue-96290: Fix handling of partial and invalid UNC drives in - ``ntpath.splitdrive()``, and in ``ntpath.normpath()`` on non-Windows - systems. Paths such as '\\server' and '\\' are now considered by - ``splitdrive()`` to contain only a drive, and consequently are not - modified by ``normpath()`` on non-Windows systems. The behaviour of - ``normpath()`` on Windows systems is unaffected, as native OS APIs are - used. Patch by Eryk Sun, with contributions by Barney Gale. - -- gh-issue-78878: Fix crash when creating an instance of - :class:`!_ctypes.CField`. - -- gh-issue-99952: Fix a reference undercounting issue in - :class:`ctypes.Structure` with ``from_param()`` results larger than a C - pointer. - -- gh-issue-100133: Fix regression in :mod:`asyncio` where a subprocess would - sometimes lose data received from pipe. - -- gh-issue-100098: Fix ``tuple`` subclasses being cast to ``tuple`` when - used as enum values. - -- gh-issue-98778: Update :exc:`~urllib.error.HTTPError` to be initialized - properly, even if the ``fp`` is ``None``. Patch by Dong-hee Na. - -- gh-issue-83035: Fix :func:`inspect.getsource` handling of decorator calls - with nested parentheses. - -- gh-issue-99576: Fix ``.save()`` method for ``LWPCookieJar`` and - ``MozillaCookieJar``: saved file was not truncated on repeated save. - -- gh-issue-99433: Fix :mod:`doctest` failure on - :class:`types.MethodWrapperType` in modules. - -- gh-issue-99240: Fix double-free bug in Argument Clinic ``str_converter`` - by extracting memory clean up to a new ``post_parsing`` section. - -- gh-issue-64490: Fix refcount error when arguments are packed to tuple in - Argument Clinic. - -- gh-issue-85267: Several improvements to :func:`inspect.signature`'s - handling of ``__text_signature``. - Fixes a case where - :func:`inspect.signature` dropped parameters - Fixes a case where - :func:`inspect.signature` raised :exc:`tokenize.TokenError` - Allows - :func:`inspect.signature` to understand defaults involving binary - operations of constants - :func:`inspect.signature` is documented as only - raising :exc:`TypeError` or :exc:`ValueError`, but sometimes raised - :exc:`RuntimeError`. These cases now raise :exc:`ValueError` - Removed a - dead code path - -- gh-issue-95882: Fix a 3.11 regression in - :func:`~contextlib.asynccontextmanager`, which caused it to propagate - exceptions with incorrect tracebacks and fix a 3.11 regression in - :func:`~contextlib.contextmanager`, which caused it to propagate - exceptions with incorrect tracebacks for :exc:`StopIteration`. - -- bpo-44817: Ignore WinError 53 (ERROR_BAD_NETPATH), 65 - (ERROR_NETWORK_ACCESS_DENIED) and 161 (ERROR_BAD_PATHNAME) when using - ntpath.realpath(). - -- bpo-40447: Accept :class:`os.PathLike` (such as :class:`pathlib.Path`) in - the ``stripdir`` arguments of :meth:`compileall.compile_file` and - :meth:`compileall.compile_dir`. - -- bpo-36880: Fix a reference counting issue when a :mod:`ctypes` callback - with return type :class:`~ctypes.py_object` returns ``None``, which could - cause crashes. - -Documentation -------------- - -- gh-issue-100616: Document existing ``attr`` parameter to - :func:`curses.window.vline` function in :mod:`curses`. - -- gh-issue-100472: Remove claim in documentation that the ``stripdir``, - ``prependdir`` and ``limit_sl_dest`` parameters of - :func:`compileall.compile_dir` and :func:`compileall.compile_file` could - be :class:`bytes`. - -- gh-issue-99931: Use `sphinxext-opengraph - <https://sphinxext-opengraph.readthedocs.io/>`__ to generate `OpenGraph - metadata <https://ogp.me/>`__. - -Tests ------ - -- gh-issue-101334: ``test_tarfile`` has been updated to pass when run as a - high UID. - -- gh-issue-100454: Start running SSL tests with OpenSSL 3.1.0-beta1. - -- gh-issue-96002: Add functional test for Argument Clinic. - -Build ------ - -- gh-issue-101522: Allow overriding Windows dependencies versions and paths - using MSBuild properties. - -Windows -------- - -- gh-issue-101543: Ensure the install path in the registry is only used when - the standard library hasn't been located in any other way. - -- gh-issue-101467: The ``py.exe`` launcher now correctly filters when only a - single runtime is installed. It also correctly handles prefix matches on - tags so that ``-3.1`` does not match ``3.11``, but would still match - ``3.1-32``. - -- gh-issue-101135: Restore ability to launch older 32-bit versions from the - :file:`py.exe` launcher when both 32-bit and 64-bit installs of the same - version are available. - -- gh-issue-82052: Fixed an issue where writing more than 32K of Unicode - output to the console screen in one go can result in mojibake. - -- gh-issue-100320: Ensures the ``PythonPath`` registry key from an install - is used when launching from a different copy of Python that relies on an - existing install to provide a copy of its modules and standard library. - -- gh-issue-100247: Restores support for the :file:`py.exe` launcher finding - shebang commands in its configuration file using the full command name. - -- gh-issue-100180: Update Windows installer to OpenSSL 1.1.1s - -- bpo-43984: :meth:`winreg.SetValueEx` now leaves the target value untouched - in the case of conversion errors. Previously, ``-1`` would be written in - case of such errors. - -macOS ------ - -- gh-issue-100180: Update macOS installer to OpenSSL 1.1.1s - -Tools/Demos ------------ - -- bpo-45256: Fix a bug that caused an :exc:`AttributeError` to be raised in - ``python-gdb.py`` when ``py-locals`` is used without a frame. - -- gh-issue-100342: Add missing ``NULL`` check for possible allocation - failure in ``*args`` parsing in Argument Clinic. - -- gh-issue-64490: Argument Clinic varargs bugfixes - - * Fix out-of-bounds error in :c:func:`!_PyArg_UnpackKeywordsWithVararg`. - * Fix incorrect check which allowed more than one varargs in clinic.py. - * Fix miscalculation of ``noptargs`` in generated code. - * Do not generate ``noptargs`` when there is a vararg argument and no optional argument. - -C API ------ - -- gh-issue-99240: In argument parsing, after deallocating newly allocated - memory, reset its pointer to NULL. - - -What's New in Python 3.11.1 final? -================================== - -*Release date: 2022-12-06* - -Security --------- - -- gh-issue-100001: ``python -m http.server`` no longer allows terminal - control characters sent within a garbage request to be printed to the - stderr server log. - - This is done by changing the :mod:`http.server` - :class:`BaseHTTPRequestHandler` ``.log_message`` method to replace control - characters with a ``\xHH`` hex escape before printing. - -- gh-issue-87604: Avoid publishing list of active per-interpreter audit - hooks via the :mod:`gc` module - -- gh-issue-98433: The IDNA codec decoder used on DNS hostnames by - :mod:`socket` or :mod:`asyncio` related name resolution functions no - longer involves a quadratic algorithm. This prevents a potential CPU - denial of service if an out-of-spec excessive length hostname involving - bidirectional characters were decoded. Some protocols such as - :mod:`urllib` http ``3xx`` redirects potentially allow for an attacker to - supply such a name. - -- gh-issue-98739: Update bundled libexpat to 2.5.0 - -- gh-issue-97612: Fix a shell code injection vulnerability in the - ``get-remote-certificate.py`` example script. The script no longer uses a - shell to run ``openssl`` commands. Issue reported and initial fix by Caleb - Shortt. Patch by Victor Stinner. - -Core and Builtins ------------------ - -- gh-issue-99886: Fix a crash when an object which does not have a - dictionary frees its instance values. - -- gh-issue-99891: Fix a bug in the tokenizer that could cause infinite - recursion when showing syntax warnings that happen in the first line of - the source. Patch by Pablo Galindo - -- gh-issue-99729: Fix an issue that could cause frames to be visible to - Python code as they are being torn down, possibly leading to memory - corruption or hard crashes of the interpreter. - -- gh-issue-99578: Fix a reference bug in :func:`_imp.create_builtin()` after - the creation of the first sub-interpreter for modules ``builtins`` and - ``sys``. Patch by Victor Stinner. - -- gh-issue-99581: Fixed a bug that was causing a buffer overflow if the - tokenizer copies a line missing the newline caracter from a file that is - as long as the available tokenizer buffer. Patch by Pablo galindo - -- gh-issue-99553: Fix bug where an :exc:`ExceptionGroup` subclass can wrap a - :exc:`BaseException`. - -- gh-issue-99370: Fix zip path for venv created from a non-installed python - on POSIX platforms. - -- gh-issue-99298: Fix an issue that could potentially cause incorrect error - handling for some bytecode instructions. - -- gh-issue-99205: Fix an issue that prevented :c:type:`PyThreadState` and - :c:type:`PyInterpreterState` memory from being freed properly. - -- gh-issue-99181: Fix failure in :keyword:`except* <except_star>` with - unhashable exceptions. - -- gh-issue-99204: Fix calculation of :data:`sys._base_executable` when - inside a POSIX virtual environment using copies of the python binary when - the base installation does not provide the executable name used by the - venv. Calculation will fall back to alternative names ("python<MAJOR>", - "python<MAJOR>.<MINOR>"). - -- gh-issue-96055: Update :mod:`faulthandler` to emit an error message with - the proper unexpected signal number. Patch by Dong-hee Na. - -- gh-issue-99153: Fix location of :exc:`SyntaxError` for a :keyword:`try` - block with both :keyword:`except` and :keyword:`except* <except_star>`. - -- gh-issue-99103: Fix the error reporting positions of specialized traceback - anchors when the source line contains Unicode characters. - -- gh-issue-98852: Fix subscription of type aliases containing bare generic - types or types like :class:`~typing.TypeVar`: for example ``tuple[A, - T][int]`` and ``tuple[TypeVar, T][int]``, where ``A`` is a generic type, - and ``T`` is a type variable. - -- gh-issue-98925: Lower the recursion depth for marshal on WASI to support - wasmtime 2.0/main. - -- gh-issue-98783: Fix multiple crashes in debug mode when ``str`` subclasses - are used instead of ``str`` itself. - -- gh-issue-99257: Fix an issue where member descriptors (such as those for - :attr:`~object.__slots__`) could behave incorrectly or crash instead of - raising a :exc:`TypeError` when accessed via an instance of an invalid - type. - -- gh-issue-98374: Suppress ImportError for invalid query for help() command. - Patch by Dong-hee Na. - -- gh-issue-98415: Fix detection of MAC addresses for :mod:`uuid` on certain - OSs. Patch by Chaim Sanders - -- gh-issue-92119: Print exception class name instead of its string - representation when raising errors from :mod:`ctypes` calls. - -- gh-issue-96078: :func:`os.sched_yield` now release the GIL while calling - sched_yield(2). Patch by Dong-hee Na. - -- gh-issue-93354: Fix an issue that could delay the specialization of - :opcode:`PRECALL` instructions. - -- gh-issue-97943: Bugfix: :func:`PyFunction_GetAnnotations` should return a - borrowed reference. It was returning a new reference. - -- gh-issue-97779: Ensure that all Python frame objects are backed by - "complete" frames. - -- gh-issue-97591: Fixed a missing incref/decref pair in - ``Exception.__setstate__()``. Patch by Ofey Chan. - -- gh-issue-94526: Fix the Python path configuration used to initialized - :data:`sys.path` at Python startup. Paths are no longer encoded to - UTF-8/strict to avoid encoding errors if it contains surrogate characters - (bytes paths are decoded with the surrogateescape error handler). Patch by - Victor Stinner. - -- gh-issue-95921: Fix overly-broad source position information for chained - comparisons used as branching conditions. - -- gh-issue-96387: At Python exit, sometimes a thread holding the GIL can - wait forever for a thread (usually a daemon thread) which requested to - drop the GIL, whereas the thread already exited. To fix the race - condition, the thread which requested the GIL drop now resets its request - before exiting. Issue discovered and analyzed by Mingliang ZHAO. Patch by - Victor Stinner. - -- gh-issue-96864: Fix a possible assertion failure, fatal error, or - :exc:`SystemError` if a line tracing event raises an exception while - opcode tracing is enabled. - -- gh-issue-96678: Fix undefined behaviour in C code of null pointer - arithmetic. - -- gh-issue-96754: Make sure that all frame objects created are created from - valid interpreter frames. Prevents the possibility of invalid frames in - backtraces and signal handlers. - -- gh-issue-95196: Disable incorrect pickling of the C implemented - classmethod descriptors. - -- gh-issue-96005: On WASI :data:`~errno.ENOTCAPABLE` is now mapped to - :exc:`PermissionError`. The :mod:`errno` modules exposes the new error - number. ``getpath.py`` now ignores :exc:`PermissionError` when it cannot - open landmark files ``pybuilddir.txt`` and ``pyenv.cfg``. - -- gh-issue-93696: Allow :mod:`pdb` to locate source for frozen modules in - the standard library. - -- bpo-31718: Raise :exc:`ValueError` instead of :exc:`SystemError` when - methods of uninitialized :class:`io.IncrementalNewlineDecoder` objects are - called. Patch by Oren Milman. - -- bpo-38031: Fix a possible assertion failure in :class:`io.FileIO` when the - opener returns an invalid file descriptor. - -Library -------- - -- gh-issue-100001: Also \ escape \s in the http.server - BaseHTTPRequestHandler.log_message so that it is technically possible to - parse the line and reconstruct what the original data was. Without this a - \xHH is ambiguious as to if it is a hex replacement we put in or the - characters r"\x" came through in the original request line. - -- gh-issue-93453: :func:`asyncio.get_event_loop` now only emits a - deprecation warning when a new event loop was created implicitly. It no - longer emits a deprecation warning if the current event loop was set. - -- gh-issue-51524: Fix bug when calling trace.CoverageResults with valid - infile. - -- gh-issue-99645: Fix a bug in handling class cleanups in - :class:`unittest.TestCase`. Now ``addClassCleanup()`` uses separate lists - for different ``TestCase`` subclasses, and ``doClassCleanups()`` only - cleans up the particular class. - -- gh-issue-97001: Release the GIL when calling termios APIs to avoid - blocking threads. - -- gh-issue-99341: Fix :func:`ast.increment_lineno` to also cover - :class:`ast.TypeIgnore` when changing line numbers. - -- gh-issue-99418: Fix bug in :func:`urllib.parse.urlparse` that causes URL - schemes that begin with a digit, a plus sign, or a minus sign to be parsed - incorrectly. - -- gh-issue-99382: Check the number of arguments in substitution in user - generics containing a :class:`~typing.TypeVarTuple` and one or more - :class:`~typing.TypeVar`. - -- gh-issue-99379: Fix substitution of :class:`~typing.ParamSpec` followed by - :class:`~typing.TypeVarTuple` in generic aliases. - -- gh-issue-99344: Fix substitution of :class:`~typing.TypeVarTuple` and - :class:`~typing.ParamSpec` together in user generics. - -- gh-issue-74044: Fixed bug where :func:`inspect.signature` reported - incorrect arguments for decorated methods. - -- gh-issue-99275: Fix ``SystemError`` in :mod:`ctypes` when exception was - not set during ``__initsubclass__``. - -- gh-issue-99277: Remove older version of - ``_SSLProtocolTransport.get_write_buffer_limits`` in - :mod:`!asyncio.sslproto` - -- gh-issue-99248: fix negative numbers failing in verify() - -- gh-issue-99155: Fix :class:`statistics.NormalDist` pickle with ``0`` and - ``1`` protocols. - -- gh-issue-93464: ``enum.auto()`` is now correctly activated when combined - with other assignment values. E.g. ``ONE = auto(), 'some text'`` will now - evaluate as ``(1, 'some text')``. - -- gh-issue-99134: Update the bundled copy of pip to version 22.3.1. - -- gh-issue-83004: Clean up refleak on failed module initialisation in - :mod:`_zoneinfo` - -- gh-issue-83004: Clean up refleaks on failed module initialisation in in - :mod:`_pickle` - -- gh-issue-83004: Clean up refleak on failed module initialisation in - :mod:`_io`. - -- gh-issue-98897: Fix memory leak in :func:`math.dist` when both points - don't have the same dimension. Patch by Kumar Aditya. - -- gh-issue-98706: [3.11] Applied changes from importlib_metadata `4.11.4 - through 4.13 - <https://importlib-metadata.readthedocs.io/en/latest/history.html#v4-13-0>`_, - including compatibility and robustness fixes for ``Distribution`` objects - without ``_normalized_name``, disallowing invalid inputs to - ``Distribution.from_name``, and refined behaviors in - ``PathDistribution._name_from_stem`` and - ``PathDistribution._normalized_name``. - -- gh-issue-98793: Fix argument typechecks in :func:`!_overlapped.WSAConnect` - and :func:`!_overlapped.Overlapped.WSASendTo` functions. - -- gh-issue-98744: Prevent crashing in :mod:`traceback` when retrieving the - byte-offset for some source files that contain certain unicode characters. - -- gh-issue-98740: Fix internal error in the :mod:`re` module which in very - rare circumstances prevented compilation of a regular expression - containing a :ref:`conditional expression <re-conditional-expression>` - without the "else" branch. - -- gh-issue-98703: Fix :meth:`asyncio.StreamWriter.drain` to call - ``protocol.connection_lost`` callback only once on Windows. - -- gh-issue-98624: Add a mutex to unittest.mock.NonCallableMock to protect - concurrent access to mock attributes. - -- gh-issue-89237: Fix hang on Windows in ``subprocess.wait_closed()`` in - :mod:`asyncio` with :class:`~asyncio.ProactorEventLoop`. Patch by Kumar - Aditya. - -- gh-issue-98458: Fix infinite loop in unittest when a self-referencing - chained exception is raised - -- gh-issue-97928: :meth:`tkinter.Text.count` raises now an exception for - options starting with "-" instead of silently ignoring them. - -- gh-issue-97966: On ``uname_result``, restored expectation that ``_fields`` - and ``_asdict`` would include all six properties including ``processor``. - -- gh-issue-98307: A :meth:`~logging.handlers.SysLogHandler.createSocket` - method was added to :class:`~logging.handlers.SysLogHandler`. - -- gh-issue-96035: Fix bug in :func:`urllib.parse.urlparse` that causes - certain port numbers containing whitespace, underscores, plus and minus - signs, or non-ASCII digits to be incorrectly accepted. - -- gh-issue-98251: Allow :mod:`venv` to pass along :envvar:`PYTHON*` - variables to ``ensurepip`` and ``pip`` when they do not impact path - resolution - -- gh-issue-98178: On macOS, fix a crash in :func:`syslog.syslog` in - multi-threaded applications. On macOS, the libc ``syslog()`` function is - not thread-safe, so :func:`syslog.syslog` no longer releases the GIL to - call it. Patch by Victor Stinner. - -- gh-issue-96151: Allow ``BUILTINS`` to be a valid field name for frozen - dataclasses. - -- gh-issue-87730: Wrap network errors consistently in urllib FTP support, so - the test suite doesn't fail when a network is available but the public - internet is not reachable. - -- gh-issue-98086: Make sure ``patch.dict()`` can be applied on async - functions. - -- gh-issue-90985: Earlier in 3.11 we deprecated - ``asyncio.Task.cancel("message")``. We realized we were too harsh, and - have undeprecated it. - -- gh-issue-97837: Change deprecate warning message in :mod:`unittest` from - - ``It is deprecated to return a value!=None`` - - to - - ``It is deprecated to return a value that is not None from a test case`` - -- gh-issue-97825: Fixes :exc:`AttributeError` when - :meth:`subprocess.check_output` is used with argument ``input=None`` and - either of the arguments *encoding* or *errors* are used. - -- gh-issue-82836: Fix :attr:`~ipaddress.IPv4Address.is_private` properties - in the :mod:`ipaddress` module. Previously non-private networks - (0.0.0.0/0) would return True from this method; now they correctly return - False. - -- gh-issue-96827: Avoid spurious tracebacks from :mod:`asyncio` when default - executor cleanup is delayed until after the event loop is closed (e.g. as - the result of a keyboard interrupt). - -- gh-issue-97592: Avoid a crash in the C version of - :meth:`asyncio.Future.remove_done_callback` when an evil argument is - passed. - -- gh-issue-97639: Remove ``tokenize.NL`` check from :mod:`tabnanny`. - -- gh-issue-73588: Fix generation of the default name of - :class:`tkinter.Checkbutton`. Previously, checkbuttons in different parent - widgets could have the same short name and share the same state if - arguments "name" and "variable" are not specified. Now they are globally - unique. - -- gh-issue-97005: Update bundled libexpat to 2.4.9 - -- gh-issue-85760: Fix race condition in :mod:`asyncio` where - :meth:`~asyncio.SubprocessProtocol.process_exited` called before the - :meth:`~asyncio.SubprocessProtocol.pipe_data_received` leading to - inconsistent output. Patch by Kumar Aditya. - -- gh-issue-96819: Fixed check in :mod:`multiprocessing.resource_tracker` - that guarantees that the length of a write to a pipe is not greater than - ``PIPE_BUF``. - -- gh-issue-96741: Corrected type annotation for dataclass attribute - ``pstats.FunctionProfile.ncalls`` to be ``str``. - -- gh-issue-95987: Fix ``repr`` of ``Any`` subclasses. - -- gh-issue-96388: Work around missing socket functions in - :class:`~socket.socket`'s ``__repr__``. - -- gh-issue-96073: In :mod:`inspect`, fix overeager replacement of - "``typing.``" in formatting annotations. - -- gh-issue-96192: Fix handling of ``bytes`` :term:`path-like objects - <path-like object>` in :func:`os.ismount()`. - -- gh-issue-96052: Fix handling compiler warnings (SyntaxWarning and - DeprecationWarning) in :func:`codeop.compile_command` when checking for - incomplete input. Previously it emitted warnings and raised a SyntaxError. - Now it always returns ``None`` for incomplete input without emitting any - warnings. - -- gh-issue-88863: To avoid apparent memory leaks when - :func:`asyncio.open_connection` raises, break reference cycles generated - by local exception and future instances (which has exception instance as - its member var). Patch by Dong Uk, Kang. - -- gh-issue-91212: Fixed flickering of the turtle window when the tracer is - turned off. Patch by Shin-myoung-serp. - -- gh-issue-88050: Fix :mod:`asyncio` subprocess transport to kill process - cleanly when process is blocked and avoid ``RuntimeError`` when loop is - closed. Patch by Kumar Aditya. - -- gh-issue-93858: Prevent error when activating venv in nested fish - instances. - -- gh-issue-91078: :meth:`TarFile.next` now returns ``None`` when called on - an empty tarfile. - -- bpo-47220: Document the optional *callback* parameter of - :class:`WeakMethod`. Patch by Géry Ogam. - -- bpo-46364: Restrict use of sockets instead of pipes for stdin of - subprocesses created by :mod:`asyncio` to AIX platform only. - -- bpo-38523: :func:`shutil.copytree` now applies the - *ignore_dangling_symlinks* argument recursively. - -- bpo-36267: Fix IndexError in :class:`argparse.ArgumentParser` when a - ``store_true`` action is given an explicit argument. - -Documentation -------------- - -- gh-issue-92892: Document that calling variadic functions with ctypes - requires special care on macOS/arm64 (and possibly other platforms). - -- gh-issue-85525: Remove extra row - -- gh-issue-95588: Clarified the conflicting advice given in the :mod:`ast` - documentation about :func:`ast.literal_eval` being "safe" for use on - untrusted input while at the same time warning that it can crash the - process. The latter statement is true and is deemed unfixable without a - large amount of work unsuitable for a bugfix. So we keep the warning and - no longer claim that ``literal_eval`` is safe. - -- bpo-41825: Restructured the documentation for the :func:`os.wait* - <os.wait>` family of functions, and improved the docs for - :func:`os.waitid` with more explanation of the possible argument - constants. - -Tests ------ - -- gh-issue-99892: Skip test_normalization() of test_unicodedata if it fails - to download NormalizationTest.txt file from pythontest.net. Patch by - Victor Stinner. - -- gh-issue-99934: Correct test_marsh on (32 bit) x86: test_deterministic - sets was failing. - -- gh-issue-99659: Optional big memory tests in ``test_sqlite3`` now catch - the correct :exc:`sqlite.DataError` exception type in case of too large - strings and/or blobs passed. - -- gh-issue-98713: Fix a bug in the :mod:`typing` tests where a test relying - on CPython-specific implementation details was not decorated with - ``@cpython_only`` and was not skipped on other implementations. - -- gh-issue-87390: Add tests for star-unpacking with PEP 646, and some other - miscellaneous PEP 646 tests. - -- gh-issue-96853: Added explicit coverage of ``Py_Initialize`` (and hence - ``Py_InitializeEx``) back to the embedding tests (all other embedding - tests migrated to ``Py_InitializeFromConfig`` in Python 3.11) - -- bpo-34272: Some C API tests were moved into the new Lib/test/test_capi/ - directory. - -Build ------ - -- gh-issue-99086: Fix ``-Wimplicit-int``, ``-Wstrict-prototypes``, and - ``-Wimplicit-function-declaration`` compiler warnings in - :program:`configure` checks. - -- gh-issue-99337: Fix a compilation issue with GCC 12 on macOS. - -- gh-issue-99086: Fix ``-Wimplicit-int`` compiler warning in - :program:`configure` check for ``PTHREAD_SCOPE_SYSTEM``. - -- gh-issue-98872: Fix a possible fd leak in ``Programs/_freeze_module.c`` - introduced in Python 3.11. - -- gh-issue-99016: Fix build with ``PYTHON_FOR_REGEN=python3.8``. - -- gh-issue-97731: Specify the full path to the source location for ``make - docclean`` (needed for cross-builds). - -- gh-issue-98707: Don't use vendored ``libmpdec`` headers if - :option:`--with-system-libmpdec` is passed to :program:`configure`. Don't - use vendored ``libexpat`` headers if :option:`--with-system-expat` is - passed to :program:`!configure`. - -- gh-issue-96761: Fix the build process of clang compiler for - :program:`_bootstrap_python` if LTO optimization is applied. Patch by - Matthias Görgens and Dong-hee Na. - -- gh-issue-96883: ``wasm32-emscripten`` builds for browsers now include - :mod:`concurrent.futures` for :mod:`asyncio` and :mod:`unittest.mock`. - -- gh-issue-84461: ``wasm32-emscripten`` platform no longer builds - :mod:`resource` module, :func:`~os.getresuid`, :func:`~os.getresgid`, and - their setters. The APIs are stubs and not functional. - -- gh-issue-94280: Updated pegen regeneration script on Windows to find and - use Python 3.9 or higher. Prior to this, pegen regeneration already - required 3.9 or higher, but the script may have used lower versions of - Python. - -Windows -------- - -- gh-issue-99345: Use faster initialization functions to detect install - location for Windows Store package - -- gh-issue-98629: Fix initialization of :data:`sys.version` and ``sys._git`` - on Windows - -- gh-issue-99442: Fix handling in :ref:`launcher` when ``argv[0]`` does not - include a file extension. - -- gh-issue-98689: Update Windows builds to zlib v1.2.13. v1.2.12 has - CVE-2022-37434, but the vulnerable ``inflateGetHeader`` API is not used by - Python. - -- gh-issue-98790: Assumes that a missing ``DLLs`` directory means that - standard extension modules are in the executable's directory. - -- gh-issue-98745: Update :file:`py.exe` launcher to install 3.11 by default - and 3.12 on request. - -- gh-issue-98692: Fix the :ref:`launcher` ignoring unrecognized shebang - lines instead of treating them as local paths - -- gh-issue-94328: Update Windows installer to use SQLite 3.39.4. - -- gh-issue-97728: Fix possible crashes caused by the use of uninitialized - variables when pass invalid arguments in :func:`os.system` on Windows and - in Windows-specific modules (like ``winreg``). - -- gh-issue-96965: Update libffi to 3.4.3 - -- gh-issue-94781: Fix :file:`pcbuild.proj` to clean previous instances of - ouput files in ``Python\deepfreeze`` and ``Python\frozen_modules`` - directories on Windows. Patch by Charlie Zhao. - -- bpo-40882: Fix a memory leak in - :class:`multiprocessing.shared_memory.SharedMemory` on Windows. - -macOS ------ - -- gh-issue-87235: On macOS ``python3 /dev/fd/9 9</path/to/script.py`` failed - for any script longer than a couple of bytes. - -- gh-issue-98940: Fix ``Mac/Extras.install.py`` file filter bug. - -- gh-issue-94328: Update macOS installer to SQLite 3.39.4. - -IDLE ----- - -- gh-issue-97527: Fix a bug in the previous bugfix that caused IDLE to not - start when run with 3.10.8, 3.12.0a1, and at least Microsoft Python - 3.10.2288.0 installed without the Lib/test package. 3.11.0 was never - affected. - -Tools/Demos ------------ - -- gh-issue-95853: The ``wasm_build.py`` script now pre-builds Emscripten - ports, checks for broken EMSDK versions, and warns about pkg-config env - vars. - -- gh-issue-95853: The new tool ``Tools/wasm/wasm_builder.py`` automates - configure, compile, and test steps for building CPython on WebAssembly - platforms. - -- gh-issue-95731: Fix handling of module docstrings in - :file:`Tools/i18n/pygettext.py`. - -C API ------ - -- gh-issue-98680: ``PyBUF_*`` constants were marked as part of Limited API - of Python 3.11+. These were available in 3.11.0 with - :c:macro:`Py_LIMITED_API` defined for 3.11, and are necessary to use the - buffer API. - -- gh-issue-98978: Fix use-after-free in ``Py_SetPythonHome(NULL)``, - ``Py_SetProgramName(NULL)`` and ``_Py_SetProgramFullPath(NULL)`` function - calls. Issue reported by Benedikt Reinartz. Patch by Victor Stinner. - -- gh-issue-96853: ``Py_InitializeEx`` now correctly calls ``PyConfig_Clear`` - after initializing the interpreter (the omission didn't cause a memory - leak only because none of the dynamically allocated config fields are - populated by the wrapper function) - - -What's New in Python 3.11.0 final? -================================== - -*Release date: 2022-10-24* - -Security --------- - -- gh-issue-97616: Fix multiplying a list by an integer (``list *= int``): - detect the integer overflow when the new allocated length is close to the - maximum size. Issue reported by Jordan Limor. Patch by Victor Stinner. - -- gh-issue-97514: On Linux the :mod:`multiprocessing` module returns to - using filesystem backed unix domain sockets for communication with the - *forkserver* process instead of the Linux abstract socket namespace. Only - code that chooses to use the :ref:`"forkserver" start method - <multiprocessing-start-methods>` is affected. - - Abstract sockets have no permissions and could allow any user on the - system in the same `network namespace - <https://man7.org/linux/man-pages/man7/network_namespaces.7.html>`_ (often - the whole system) to inject code into the multiprocessing *forkserver* - process. This was a potential privilege escalation. Filesystem based - socket permissions restrict this to the *forkserver* process user as was - the default in Python 3.8 and earlier. - - This prevents Linux `CVE-2022-42919 - <https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-42919>`_. - -Core and Builtins ------------------ - -- gh-issue-97002: Fix an issue where several frame objects could be backed - by the same interpreter frame, possibly leading to corrupted memory and - hard crashes of the interpreter. - -- gh-issue-97752: Fix possible data corruption or crashes when accessing the - ``f_back`` member of newly-created generator or coroutine frames. - -- gh-issue-96975: Fix a crash occurring when :c:func:`PyEval_GetFrame` is - called while the topmost Python frame is in a partially-initialized state. - -- gh-issue-96848: Fix command line parsing: reject :option:`-X - int_max_str_digits <-X>` option with no value (invalid) when the - :envvar:`PYTHONINTMAXSTRDIGITS` environment variable is set to a valid - limit. Patch by Victor Stinner. - -- gh-issue-96821: Fix undefined behaviour in ``_testcapimodule.c``. - -- gh-issue-95778: When :exc:`ValueError` is raised if an integer is larger - than the limit, mention the :func:`sys.set_int_max_str_digits` function in - the error message. Patch by Victor Stinner. - -- gh-issue-96587: Correctly raise ``SyntaxError`` on exception groups - (:pep:`654`) on python versions prior to 3.11 - -- bpo-42316: Document some places where an assignment expression needs - parentheses. - -Library -------- - -- gh-issue-98331: Update the bundled copies of pip and setuptools to - versions 22.3 and 65.5.0 respectively. - -- gh-issue-90985: Earlier in 3.11 we deprecated - ``asyncio.Task.cancel("message")``. We realized we were too harsh, and - have undeprecated it. - -- gh-issue-97545: Make Semaphore run faster. - -- gh-issue-96865: fix Flag to use boundary CONFORM - - This restores previous Flag behavior of allowing flags with non-sequential - values to be combined; e.g. - - class Skip(Flag): TWO = 2 EIGHT = 8 - - Skip.TWO | Skip.EIGHT -> <Skip.TWO|EIGHT: 10> - -- gh-issue-90155: Fix broken :class:`asyncio.Semaphore` when acquire is - cancelled. - -Documentation -------------- - -- gh-issue-97741: Fix ``!`` in c domain ref target syntax via a ``conf.py`` - patch, so it works as intended to disable ref target resolution. - -- gh-issue-93031: Update tutorial introduction output to use 3.10+ - SyntaxError invalid range. - -Tests ------ - -- gh-issue-95027: On Windows, when the Python test suite is run with the - ``-jN`` option, the ANSI code page is now used as the encoding for the - stdout temporary file, rather than using UTF-8 which can lead to decoding - errors. Patch by Victor Stinner. - -Build ------ - -- gh-issue-96729: Ensure that Windows releases built with - ``Tools\msi\buildrelease.bat`` are upgradable to and from official Python - releases. - -Windows -------- - -- gh-issue-98360: Fixes :mod:`multiprocessing` spawning child processes on - Windows from a virtual environment to ensure that child processes that - also use :mod:`multiprocessing` to spawn more children will recognize that - they are in a virtual environment. - -- gh-issue-98414: Fix :file:`py.exe` launcher handling of ``-V:<company>/`` - option when default preferences have been set in environment variables or - configuration files. - -- gh-issue-90989: Clarify some text in the Windows installer. - -macOS ------ - -- gh-issue-97897: The macOS 13 SDK includes support for the ``mkfifoat`` and - ``mknodat`` system calls. Using the ``dir_fd`` option with either - :func:`os.mkfifo` or :func:`os.mknod` could result in a segfault if - cpython is built with the macOS 13 SDK but run on an earlier version of - macOS. Prevent this by adding runtime support for detection of these - system calls ("weaklinking") as is done for other newer syscalls on macOS. - - -What's New in Python 3.11.0 release candidate 2? -================================================ - -*Release date: 2022-09-11* - -Security --------- - -- gh-issue-95778: Converting between :class:`int` and :class:`str` in bases - other than 2 (binary), 4, 8 (octal), 16 (hexadecimal), or 32 such as base - 10 (decimal) now raises a :exc:`ValueError` if the number of digits in - string form is above a limit to avoid potential denial of service attacks - due to the algorithmic complexity. This is a mitigation for - `CVE-2020-10735 - <https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-10735>`_. - - This new limit can be configured or disabled by environment variable, - command line flag, or :mod:`sys` APIs. See the :ref:`integer string - conversion length limitation <int_max_str_digits>` documentation. The - default limit is 4300 digits in string form. - - Patch by Gregory P. Smith [Google] and Christian Heimes [Red Hat] with - feedback from Victor Stinner, Thomas Wouters, Steve Dower, Ned Deily, and - Mark Dickinson. - -Core and Builtins ------------------ - -- gh-issue-96678: Fix case of undefined behavior in ceval.c - -- gh-issue-96641: Do not expose ``KeyWrapper`` in :mod:`_functools`. - -- gh-issue-96636: Ensure that tracing, ``sys.setrace()``, is turned on - immediately. In pre-release versions of 3.11, some tracing events might - have been lost when turning on tracing in a ``__del__`` method or - interrupt. - -- gh-issue-96572: Fix use after free in trace refs build mode. Patch by - Kumar Aditya. - -- gh-issue-96611: When loading a file with invalid UTF-8 inside a multi-line - string, a correct SyntaxError is emitted. - -- gh-issue-96612: Make sure that incomplete frames do not show up in - tracemalloc traces. - -- gh-issue-96569: Remove two cases of undefined behavior, by adding NULL - checks. - -- gh-issue-96582: Fix possible ``NULL`` pointer dereference in - ``_PyThread_CurrentFrames``. Patch by Kumar Aditya. - -- gh-issue-96352: Fix :exc:`AttributeError` missing ``name`` and ``obj`` - attributes in :meth:`object.__getattribute__`. Patch by Philip Georgi. - -- gh-issue-96268: Loading a file with invalid UTF-8 will now report the - broken character at the correct location. - -- gh-issue-96187: Fixed a bug that caused ``_PyCode_GetExtra`` to return - garbage for negative indexes. Patch by Pablo Galindo - -- gh-issue-96071: Fix a deadlock in :c:func:`PyGILState_Ensure` when - allocating new thread state. Patch by Kumar Aditya. - -- gh-issue-96046: :c:func:`PyType_Ready` now initializes ``ht_cached_keys`` - and performs additional checks to ensure that type objects are properly - configured. This avoids crashes in 3rd party packages that don't use - regular API to create new types. - -- gh-issue-95818: Skip over incomplete frames in - :c:func:`PyThreadState_GetFrame`. - -- gh-issue-95876: Fix format string in - ``_PyPegen_raise_error_known_location`` that can lead to memory corruption - on some 64bit systems. The function was building a tuple with ``i`` (int) - instead of ``n`` (Py_ssize_t) for Py_ssize_t arguments. - -- gh-issue-95605: Fix misleading contents of error message when converting - an all-whitespace string to :class:`float`. - -- gh-issue-94996: :func:`ast.parse` will no longer parse function - definitions with positional-only params when passed ``feature_version`` - less than ``(3, 8)``. Patch by Shantanu Jain. - -Library -------- - -- gh-issue-96700: Fix incorrect error message in the :mod:`io` module. - -- gh-issue-96652: Fix the faulthandler implementation of - ``faulthandler.register(signal, chain=True)`` if the ``sigaction()`` - function is not available: don't call the previous signal handler if it's - NULL. Patch by Victor Stinner. - -- gh-issue-68163: Correct conversion of :class:`numbers.Rational`'s to - :class:`float`. - -- gh-issue-96385: Fix ``TypeVarTuple.__typing_prepare_subst__``. - ``TypeError`` was not raised when using more than one ``TypeVarTuple``, - like ``[*T, *V]`` in type alias substitutions. - -- gh-issue-90467: Fix :class:`asyncio.streams.StreamReaderProtocol` to keep - a strong reference to the created task, so that it's not garbage collected - -- gh-issue-96159: Fix a performance regression in logging - TimedRotatingFileHandler. Only check for special files when the rollover - time has passed. - -- gh-issue-96175: Fix unused ``localName`` parameter in the ``Attr`` class - in :mod:`xml.dom.minidom`. - -- gh-issue-96125: Fix incorrect condition that causes - ``sys.thread_info.name`` to be wrong on pthread platforms. - -- gh-issue-95463: Remove an incompatible change from :issue:`28080` that - caused a regression that ignored the utf8 in ``ZipInfo.flag_bits``. Patch - by Pablo Galindo. - -- gh-issue-95899: Fix :class:`asyncio.Runner` to call - :func:`asyncio.set_event_loop` only once to avoid calling - :meth:`~asyncio.AbstractChildWatcher.attach_loop` multiple times on child - watchers. Patch by Kumar Aditya. - -- gh-issue-95736: Fix :class:`unittest.IsolatedAsyncioTestCase` to set event - loop before calling setup functions. Patch by Kumar Aditya. - -- gh-issue-95704: When a task catches :exc:`asyncio.CancelledError` and - raises some other error, the other error should generally not silently be - suppressed. - -- gh-issue-95231: Fail gracefully if :data:`~errno.EPERM` or - :data:`~errno.ENOSYS` is raised when loading :mod:`crypt` methods. This - may happen when trying to load ``MD5`` on a Linux kernel with :abbr:`FIPS - (Federal Information Processing Standard)` enabled. - -- gh-issue-74116: Allow :meth:`asyncio.StreamWriter.drain` to be awaited - concurrently by multiple tasks. Patch by Kumar Aditya. - -- gh-issue-92986: Fix :func:`ast.unparse` when ``ImportFrom.level`` is None - -Documentation -------------- - -- gh-issue-96098: Improve discoverability of the higher level - concurrent.futures module by providing clearer links from the lower level - threading and multiprocessing modules. - -- gh-issue-95957: What's New 3.11 now has instructions for how to provide - compiler and linker flags for Tcl/Tk and OpenSSL on RHEL 7 and CentOS 7. - -Tests ------ - -- gh-issue-95243: Mitigate the inherent race condition from using - find_unused_port() in testSockName() by trying to find an unused port a - few times before failing. Patch by Ross Burton. - -Build ------ - -- gh-issue-94682: Build and test with OpenSSL 1.1.1q - -Windows -------- - -- gh-issue-96577: Fixes a potential buffer overrun in :mod:`msilib`. - -- gh-issue-96559: Fixes the Windows launcher not using the compatible - interpretation of default tags found in configuration files when no tag - was passed to the command. - - -What's New in Python 3.11.0 release candidate 1? -================================================ - -*Release date: 2022-08-05* - -Core and Builtins ------------------ - -- gh-issue-95150: Update code object hashing and equality to consider all - debugging and exception handling tables. This fixes an issue where certain - non-identical code objects could be "deduplicated" during compilation. - -- gh-issue-95355: ``_PyPegen_Parser_New`` now properly detects token memory - allocation errors. Patch by Honglin Zhu. - -- gh-issue-90081: Run Python code in tracer/profiler function at full speed. - Fixes slowdown in earlier versions of 3.11. - -- gh-issue-95324: Emit a warning in debug mode if an object does not call - :c:func:`PyObject_GC_UnTrack` before deallocation. Patch by Pablo Galindo. - -- gh-issue-95185: Prevented crashes in the AST constructor when compiling - some absurdly long expressions like ``"+0"*1000000``. - :exc:`RecursionError` is now raised instead. Patch by Pablo Galindo - -- gh-issue-93351: :class:`ast.AST` node positions are now validated when - provided to :func:`compile` and other related functions. If invalid - positions are detected, a :exc:`ValueError` will be raised. - -- gh-issue-94938: Fix error detection in some builtin functions when keyword - argument name is an instance of a str subclass with overloaded ``__eq__`` - and ``__hash__``. Previously it could cause SystemError or other undesired - behavior. - -Library -------- - -- gh-issue-95609: Update bundled pip to 22.2.2. - -- gh-issue-95289: Fix :class:`asyncio.TaskGroup` to propagate exception when - :exc:`asyncio.CancelledError` was replaced with another exception by a - context manger. Patch by Kumar Aditya and Guido van Rossum. - -- gh-issue-95339: Update bundled pip to 22.2.1. - -- gh-issue-95045: Fix GC crash when deallocating ``_lsprof.Profiler`` by - untracking it before calling any callbacks. Patch by Kumar Aditya. - -- gh-issue-95097: Fix :func:`asyncio.run` for :class:`asyncio.Task` - implementations without :meth:`~asyncio.Task.uncancel` method. Patch by - Kumar Aditya. - -- gh-issue-93899: Fix check for existence of :data:`os.EFD_CLOEXEC`, - :data:`os.EFD_NONBLOCK` and :data:`os.EFD_SEMAPHORE` flags on older kernel - versions where these flags are not present. Patch by Kumar Aditya. - -- gh-issue-95166: Fix :meth:`concurrent.futures.Executor.map` to cancel the - currently waiting on future on an error - e.g. TimeoutError or - KeyboardInterrupt. - -- gh-issue-95109: Ensure that timeouts scheduled with - :class:`asyncio.Timeout` that have already expired are delivered promptly. - -- gh-issue-91810: Suppress writing an XML declaration in open files in - ``ElementTree.write()`` with ``encoding='unicode'`` and - ``xml_declaration=None``. - -- gh-issue-91447: Fix findtext in the xml module to only give an empty - string when the text attribute is set to None. - -Documentation -------------- - -- gh-issue-91207: Fix stylesheet not working in Windows CHM htmlhelp docs - and add warning that they are deprecated. Contributed by C.A.M. Gerlach. - -- gh-issue-95451: Update library documentation with :ref:`availability - information <wasm-availability>` on WebAssembly platforms - ``wasm32-emscripten`` and ``wasm32-wasi``. - -- gh-issue-95415: Use consistent syntax for platform availability. The - directive now supports a content body and emits a warning when it - encounters an unknown platform. - -- gh-issue-86128: Document a limitation in ThreadPoolExecutor where its exit - handler is executed before any handlers in atexit. - -Tests ------ - -- gh-issue-95573: :source:`Lib/test/test_asyncio/test_ssl.py` exposed a bug - in the macOS kernel where intense concurrent load on non-blocking sockets - occasionally causes :const:`errno.ENOBUFS` ("No buffer space available") - to be emitted. FB11063974 filed with Apple, in the mean time as a - workaround buffer size used in tests on macOS is decreased to avoid - intermittent failures. Patch by Fantix King. - -- gh-issue-95280: Fix problem with ``test_ssl`` ``test_get_ciphers`` on - systems that require perfect forward secrecy (PFS) ciphers. - -- gh-issue-94675: Add a regression test for :mod:`re` exponentional slowdown - when using rjsmin. - -Build ------ - -- gh-issue-94801: Fix a regression in ``configure`` script that caused some - header checks to ignore custom ``CPPFLAGS``. The regression was introduced - in :gh:`94802`. - -- gh-issue-95145: wasm32-wasi builds no longer depend on WASIX's pthread - stubs. Python now has its own stubbed pthread API. - -- gh-issue-95174: Python now detects missing ``dup`` function in WASI and - works around some missing :mod:`errno`, :mod:`select`, and :mod:`socket` - constants. - -- gh-issue-95174: Python now skips missing :mod:`socket` functions and - methods on WASI. WASI can only create sockets from existing fd / accept - and has no netdb. - -- gh-issue-95085: Platforms ``wasm32-unknown-emscripten`` and - ``wasm32-unknown-wasi`` have been promoted to :pep:`11` tier 3 platform - support. - -Windows -------- - -- gh-issue-95656: Enable the - :meth:`~sqlite3.Connection.enable_load_extension` :mod:`sqlite3` API. - -- gh-issue-95587: Fixes some issues where the Windows installer would - incorrectly detect certain features of an existing install when upgrading. - -- gh-issue-94399: Restores the behaviour of :ref:`launcher` for - ``/usr/bin/env`` shebang lines, which will now search :envvar:`PATH` for - an executable matching the given command. If none is found, the usual - search process is used. - -- gh-issue-95445: Fixes the unsuccessful removal of the HTML document - directory when uninstalling with Windows msi. - -- gh-issue-95359: Fix :ref:`launcher` handling of :file:`py.ini` commands - (it was incorrectly expecting a ``py_`` prefix on keys) and crashes when - reading per-user configuration file. - -- gh-issue-95285: Fix :ref:`launcher` handling of command lines where it is - only passed a short executable name. - -IDLE ----- - -- gh-issue-65802: Document handling of extensions in Save As dialogs. - -- gh-issue-95191: Include prompts when saving Shell (interactive input and - output). - -- gh-issue-95511: Fix the Shell context menu copy-with-prompts bug of - copying an extra line when one selects whole lines. - -- gh-issue-95471: In the Edit menu, move ``Select All`` and add a new - separator. - -- gh-issue-95411: Enable using IDLE's module browser with .pyw files. - -- gh-issue-89610: Add .pyi as a recognized extension for IDLE on macOS. - This allows opening stub files by double clicking on them in the Finder. - -C API ------ - -- gh-issue-92678: Restore the 3.10 behavior for multiple inheritance of C - extension classes that store their dictionary at the end of the struct. - -- gh-issue-94936: Added :c:func:`PyCode_GetVarnames`, - :c:func:`PyCode_GetCellvars` and :c:func:`PyCode_GetFreevars` for - accessing ``co_varnames``, ``co_cellvars`` and ``co_freevars`` - respectively via the C API. - - -What's New in Python 3.11.0 beta 5? -=================================== - -*Release date: 2022-07-25* - -Core and Builtins ------------------ - -- gh-issue-93351: :class:`ast.AST` node positions are now validated when - provided to :func:`compile` and other related functions. If invalid - positions are detected, a :exc:`ValueError` will be raised. - -- gh-issue-94438: Fix an issue that caused extended opcode arguments and - some conditional pops to be ignored when calculating valid jump targets - for assignments to the ``f_lineno`` attribute of frame objects. In some - cases, this could cause inconsistent internal state, resulting in a hard - crash of the interpreter. - -- gh-issue-95060: Undocumented ``PyCode_Addr2Location`` function now - properly returns when ``addrq`` argument is less than zero. - -- gh-issue-95113: Replace all ``EXTENDED_ARG_QUICK`` instructions with basic - :opcode:`EXTENDED_ARG` instructions in unquickened code. Consumers of - non-adaptive bytecode should be able to handle extended arguments the same - way they were handled in CPython 3.10 and older. - -- gh-issue-91409: Fix incorrect source location info caused by certain - optimizations in the bytecode compiler. - -- gh-issue-94036: Fix incorrect source location info for some multi-line - attribute accesses and method calls. - -- gh-issue-94739: Allow jumping within, out of, and across exception - handlers in the debugger. - -- gh-issue-94949: :func:`ast.parse` will no longer parse parenthesized - context managers when passed ``feature_version`` less than ``(3, 9)``. - Patch by Shantanu Jain. - -- gh-issue-94947: :func:`ast.parse` will no longer parse assignment - expressions when passed ``feature_version`` less than ``(3, 8)``. Patch by - Shantanu Jain. - -- gh-issue-91256: Ensures the program name is known for help text during - interpreter startup. - -- gh-issue-94869: Fix the column offsets for some expressions in multi-line - f-strings :mod:`ast` nodes. Patch by Pablo Galindo. - -- gh-issue-94822: Fix an issue where lookups of metaclass descriptors may be - ignored when an identically-named attribute also exists on the class - itself. - -- gh-issue-91153: Fix an issue where a :class:`bytearray` item assignment - could crash if it's resized by the new value's :meth:`__index__` method. - -- gh-issue-90699: Fix reference counting bug in :meth:`bool.__repr__`. Patch - by Kumar Aditya. - -Library -------- - -- gh-issue-95087: Fix IndexError in parsing invalid date in the :mod:`email` - module. - -- gh-issue-95199: Upgrade bundled setuptools to 63.2.0. - -- gh-issue-95194: Upgrade bundled pip to 22.2. - -- gh-issue-95132: Fix a :mod:`sqlite3` regression where ``*args`` and - ``**kwds`` were incorrectly relayed from :py:func:`~sqlite3.connect` to - the :class:`~sqlite3.Connection` factory. The regression was introduced in - 3.11a1 with PR 24421 (:gh:`85128`). Patch by Erlend E. Aasland.` - -- gh-issue-93157: Fix :mod:`fileinput` module didn't support ``errors`` - option when ``inplace`` is true. - -- gh-issue-95105: :meth:`wsgiref.types.InputStream.__iter__` should return - ``Iterator[bytes]``, not ``Iterable[bytes]``. Patch by Shantanu Jain. - -- gh-issue-94857: Fix refleak in ``_io.TextIOWrapper.reconfigure``. Patch by - Kumar Aditya. - -- gh-issue-94821: Fix binding of unix socket to empty address on Linux to - use an available address from the abstract namespace, instead of "\0". - -- gh-issue-89988: Fix memory leak in :class:`pickle.Pickler` when looking up - :attr:`dispatch_table`. Patch by Kumar Aditya. - -- bpo-47025: Drop support for :class:`bytes` on :attr:`sys.path`. - -Tests ------ - -- gh-issue-95212: Make multiprocessing test case - ``test_shared_memory_recreate`` parallel-safe. - -Build ------ - -- gh-issue-94847: Fixed ``_decimal`` module build issue on GCC when - compiling with LTO and pydebug. Debug builds no longer force inlining of - functions. - -- gh-issue-94841: Fix the possible performance regression of - :c:func:`PyObject_Free` compiled with MSVC version 1932. - -- gh-issue-94801: ``configure`` now uses custom flags like ``ZLIB_CFLAGS`` - and ``ZLIB_LIBS`` when searching for headers and libraries. - -- gh-issue-94773: ``deepfreeze.py`` now supports code object with frozensets - that contain incompatible, unsortable types. - -Windows -------- - -- gh-issue-90844: Allow virtual environments to correctly launch when they - have spaces in the path. - -- gh-issue-94772: Fix incorrect handling of shebang lines in py.exe launcher - -C API ------ - -- gh-issue-92678: Adds unstable C-API functions - ``_PyObject_VisitManagedDict`` and ``_PyObject_ClearManagedDict`` to allow - C extensions to allow the VM to manage their object's dictionaries. - -- gh-issue-94930: Fix ``SystemError`` raised when - :c:func:`PyArg_ParseTupleAndKeywords` is used with ``#`` in ``(...)`` but - without ``PY_SSIZE_T_CLEAN`` defined. - -- gh-issue-94864: Fix ``PyArg_Parse*`` with deprecated format units "u" and - "Z". It returned 1 (success) when warnings are turned into exceptions. - -- gh-issue-94731: Python again uses C-style casts for most casting - operations when compiled with C++. This may trigger compiler warnings, if - they are enabled with e.g. ``-Wold-style-cast `` or - ``-Wzero-as-null-pointer-constant`` options for ``g++``. - - -What's New in Python 3.11.0 beta 4? -=================================== - -*Release date: 2022-07-11* - -Security --------- - -- gh-issue-87389: :mod:`http.server`: Fix an open redirection vulnerability - in the HTTP server when an URI path starts with ``//``. Vulnerability - discovered, and initial fix proposed, by Hamza Avvan. - -- gh-issue-79096: LWPCookieJar and MozillaCookieJar create files with file - mode 600 instead of 644 (Microsoft Windows is not affected) - -- gh-issue-92888: Fix ``memoryview`` use after free when accessing the - backing buffer in certain cases. - -- gh-issue-68966: The deprecated mailcap module now refuses to inject unsafe - text (filenames, MIME types, parameters) into shell commands. Instead of - using such text, it will warn and act as if a match was not found (or for - test commands, as if the test failed). - -Core and Builtins ------------------ - -- gh-issue-94694: Fix an issue that could cause code with multi-line method - lookups to have misleading or incorrect column offset information. In some - cases (when compiling a hand-built AST) this could have resulted in a hard - crash of the interpreter. - -- gh-issue-93252: Fix an issue that caused internal frames to outlive failed - Python function calls, possibly resulting in memory leaks or hard - interpreter crashes. - -- gh-issue-94215: Fix an issue where exceptions raised by line-tracing - events would cause frames to be left in an invalid state, possibly - resulting in a hard crash of the interpreter. - -- gh-issue-92228: Disable the compiler's inline-small-exit-blocks - optimization for exit blocks that are associated with source code lines. - This fixes a bug where the debugger cannot tell where an exception handler - ends and the following code block begins. - -- gh-issue-94485: Line number of a module's ``RESUME`` instruction is set to - 0 as specified in :pep:`626`. - -- gh-issue-94438: Account for instructions that can push NULL to the stack - when setting line number in a frame. Prevents some (unlikely) crashes. - -- gh-issue-91719: Reload ``opcode`` when raising ``unknown opcode error`` in - the interpreter main loop, for C compilers to generate dispatching code - independently. - -- gh-issue-94329: Compile and run code with unpacking of extremely large - sequences (1000s of elements). Such code failed to compile. It now - compiles and runs correctly. - -- gh-issue-94360: Fixed a tokenizer crash when reading encoded files with - syntax errors from ``stdin`` with non utf-8 encoded text. Patch by Pablo - Galindo - -- gh-issue-88116: Fix an issue when reading line numbers from code objects - if the encoded line numbers are close to ``INT_MIN``. Patch by Pablo - Galindo - -- gh-issue-94262: Don't create frame objects for incomplete frames. Prevents - the creation of generators and closures from being observable to Python - and C extensions, restoring the behavior of 3.10 and earlier. - -- gh-issue-94192: Fix error for dictionary literals with invalid expression - as value. - -- gh-issue-93883: Revise the display strategy of traceback enhanced error - locations. The indicators are only shown when the location doesn't span - the whole line. - -- gh-issue-94021: Fix unreachable code warning in ``Python/specialize.c``. - -- gh-issue-93516: Store offset of first traceable instruction in code object - to avoid having to recompute it for each instruction when tracing. - -- gh-issue-93516: Lazily create a table mapping bytecode offsets to line - numbers to speed up calculation of line numbers when tracing. - -- gh-issue-89828: :class:`types.GenericAlias` no longer relays the - ``__class__`` attribute. For example, ``isinstance(list[int], type)`` no - longer returns ``True``. - -- gh-issue-93671: Fix some exponential backtrace case happening with deeply - nested sequence patterns in match statements. Patch by Pablo Galindo - -- gh-issue-93662: Make sure that the end column offsets are correct in - multi-line method calls. Previously, the end column could precede the - column offset. - -- gh-issue-93461: :func:`importlib.invalidate_caches` now drops entries from - :data:`sys.path_importer_cache` with a relative path as name. This solves - a caching issue when a process changes its current working directory. - - ``FileFinder`` no longer inserts a dot in the path, e.g. ``/egg/./spam`` - is now ``/egg/spam``. - -- gh-issue-93418: Fixed an assert where an f-string has an equal sign '=' - following an expression, but there's no trailing brace. For example, - f"{i=". - -- gh-issue-93382: Cache the result of :c:func:`PyCode_GetCode` function to - restore the O(1) lookup of the :attr:`~types.CodeType.co_code` attribute. - -- gh-issue-93354: Use exponential backoff for specialization counters in the - interpreter. Can reduce the number of failed specializations significantly - and avoid slowdown for those parts of a program that are not suitable for - specialization. - -- gh-issue-93021: Fix the :attr:`__text_signature__` for :meth:`__get__` - methods implemented in C. Patch by Jelle Zijlstra. - -- gh-issue-92930: Fixed a crash in ``_pickle.c`` from mutating collections - during ``__reduce__`` or ``persistent_id``. - -- gh-issue-92914: Always round the allocated size for lists up to the - nearest even number. - -- gh-issue-92858: Improve error message for some suites with syntax error - before ':' - -- bpo-46142: Make ``--help`` output shorter by moving some info to the new - ``--help-env`` and ``--help-xoptions`` command-line options. Also add - ``--help-all`` option to print complete usage. - -Library -------- - -- gh-issue-94736: Fix crash when deallocating an instance of a subclass of - ``_multiprocessing.SemLock``. Patch by Kumar Aditya. - -- gh-issue-94637: :meth:`SSLContext.set_default_verify_paths` now releases - the GIL around ``SSL_CTX_set_default_verify_paths`` call. The function - call performs I/O and CPU intensive work. - -- gh-issue-94607: Fix subclassing complex generics with type variables in - :mod:`typing`. Previously an error message saying ``Some type variables - ... are not listed in Generic[...]`` was shown. :mod:`typing` no longer - populates ``__parameters__`` with the ``__parameters__`` of a Python - class. - -- gh-issue-93910: The ability to access the other values of an enum on an - enum (e.g. ``Color.RED.BLUE``) has been restored in order to fix a - performance regression. - -- gh-issue-93896: Fix :func:`asyncio.run` and - :class:`unittest.IsolatedAsyncioTestCase` to always the set event loop as - it was done in Python 3.10 and earlier. Patch by Kumar Aditya. - -- gh-issue-94510: Re-entrant calls to :func:`sys.setprofile` and - :func:`sys.settrace` now raise :exc:`RuntimeError`. Patch by Pablo - Galindo. - -- gh-issue-92336: Fix bug where :meth:`linecache.getline` fails on bad files - with :exc:`UnicodeDecodeError` or :exc:`SyntaxError`. It now returns an - empty string as per the documentation. - -- gh-issue-94398: Once a :class:`asyncio.TaskGroup` has started shutting - down (i.e., at least one task has failed and the task group has started - cancelling the remaining tasks), it should not be possible to add new - tasks to the task group. - -- gh-issue-94254: Fixed types of :mod:`struct` module to be immutable. Patch - by Kumar Aditya. - -- gh-issue-94207: Made :class:`_struct.Struct` GC-tracked in order to fix a - reference leak in the :mod:`_struct` module. - -- gh-issue-91742: Fix :mod:`pdb` crash after jump caused by a null pointer - dereference. Patch by Kumar Aditya. - -- gh-issue-94101: Manual instantiation of :class:`ssl.SSLSession` objects is - no longer allowed as it lead to misconfigured instances that crashed the - interpreter when attributes where accessed on them. - -- gh-issue-84753: :func:`inspect.iscoroutinefunction`, - :func:`inspect.isgeneratorfunction`, and - :func:`inspect.isasyncgenfunction` now properly return ``True`` for - duck-typed function-like objects like instances of - :class:`unittest.mock.AsyncMock`. - - This makes :func:`inspect.iscoroutinefunction` consistent with the - behavior of :func:`asyncio.iscoroutinefunction`. Patch by Mehdi ABAAKOUK. - -- gh-issue-94028: Fix a regression in the :mod:`sqlite3` where statement - objects were not properly cleared and reset after use in cursor iters. The - regression was introduced by PR 27884 in Python 3.11a1. Patch by Erlend E. - Aasland. - -- gh-issue-93820: Pickle :class:`enum.Flag` by name. - -- gh-issue-93847: Fix repr of enum of generic aliases. - -- gh-issue-91404: Revert the :mod:`re` memory leak when a match is - terminated by a signal or memory allocation failure as the implemented fix - caused a major performance regression. - -- gh-issue-83499: Fix double closing of file description in :mod:`tempfile`. - -- gh-issue-93820: Fixed a regression when :func:`copy.copy`-ing - :class:`enum.Flag` with multiple flag members. - -- gh-issue-79512: Fixed names and ``__module__`` value of :mod:`weakref` - classes :class:`~weakref.ReferenceType`, :class:`~weakref.ProxyType`, - :class:`~weakref.CallableProxyType`. It makes them pickleable. - -- gh-issue-91389: Fix an issue where :mod:`dis` utilities could report - missing or incorrect position information in the presence of ``CACHE`` - entries. - -- gh-issue-93626: Set ``__future__.annotations`` to have a ``None`` - mandatoryRelease to indicate that it is currently 'TBD'. - -- gh-issue-90473: Emscripten and WASI have no home directory and cannot - provide :pep:`370` user site directory. - -- gh-issue-90494: :func:`copy.copy` and :func:`copy.deepcopy` now always - raise a TypeError if ``__reduce__()`` returns a tuple with length 6 - instead of silently ignore the 6th item or produce incorrect result. - -- gh-issue-90549: Fix a multiprocessing bug where a global named resource - (such as a semaphore) could leak when a child process is spawned (as - opposed to forked). - -- gh-issue-93521: Fixed a case where dataclasses would try to add - ``__weakref__`` into the ``__slots__`` for a dataclass that specified - ``weakref_slot=True`` when it was already defined in one of its bases. - This resulted in a ``TypeError`` upon the new class being created. - -- gh-issue-79579: :mod:`sqlite3` now correctly detects DML queries with - leading comments. Patch by Erlend E. Aasland. - -- gh-issue-93421: Update :data:`sqlite3.Cursor.rowcount` when a DML - statement has run to completion. This fixes the row count for SQL queries - like ``UPDATE ... RETURNING``. Patch by Erlend E. Aasland. - -- gh-issue-91162: Support splitting of unpacked arbitrary-length tuple over - ``TypeVar`` and ``TypeVarTuple`` parameters. For example: - - * ``A[T, *Ts][*tuple[int, ...]]`` -> ``A[int, *tuple[int, ...]]`` - * ``A[*Ts, T][*tuple[int, ...]]`` -> ``A[*tuple[int, ...], int]`` - -- gh-issue-93353: Fix the :func:`importlib.resources.as_file` context - manager to remove the temporary file if destroyed late during Python - finalization: keep a local reference to the :func:`os.remove` function. - Patch by Victor Stinner. - -- gh-issue-83658: Make :class:`multiprocessing.Pool` raise an exception if - ``maxtasksperchild`` is not ``None`` or a positive int. - -- gh-issue-93156: Accessing the :attr:`pathlib.PurePath.parents` sequence of - an absolute path using negative index values produced incorrect results. - -- gh-issue-74696: :func:`shutil.make_archive` no longer temporarily changes - the current working directory during creation of standard ``.zip`` or tar - archives. - -- gh-issue-89973: Fix :exc:`re.error` raised in :mod:`fnmatch` if the - pattern contains a character range with upper bound lower than lower bound - (e.g. ``[c-a]``). Now such ranges are interpreted as empty ranges. - -- gh-issue-92932: Now :func:`~dis.dis` and :func:`~dis.get_instructions` - handle operand values for instructions prefixed by ``EXTENDED_ARG_QUICK``. - Patch by Sam Gross and Dong-hee Na. - -- gh-issue-91577: Move imports in :class:`~multiprocessing.SharedMemory` - methods to module level so that they can be executed late in python - finalization. - -- gh-issue-91456: Deprecate current default auto() behavior: In 3.13 the - default will be for for auto() to always return the largest member value - incremented by 1, and to raise if incompatible value types are used. - -- bpo-47231: Fixed an issue with inconsistent trailing slashes in tarfile - longname directories. - -- bpo-46755: In :class:`QueueHandler`, clear ``stack_info`` from - :class:`LogRecord` to prevent stack trace from being written twice. - -- bpo-46197: Fix :mod:`ensurepip` environment isolation for subprocess - running ``pip``. - -- bpo-45924: Fix :mod:`asyncio` incorrect traceback when future's exception - is raised multiple times. Patch by Kumar Aditya. - -- bpo-34828: :meth:`sqlite3.Connection.iterdump` now handles databases that - use ``AUTOINCREMENT`` in one or more tables. - -Documentation -------------- - -- gh-issue-94321: Document the :pep:`246` style protocol type - :class:`sqlite3.PrepareProtocol`. - -- gh-issue-61162: Clarify :mod:`sqlite3` behavior when - :ref:`sqlite3-connection-context-manager`. - -- gh-issue-87260: Align :mod:`sqlite3` argument specs with the actual - implementation. - -- gh-issue-86986: The minimum Sphinx version required to build the - documentation is now 3.2. - -- gh-issue-88831: Augmented documentation of asyncio.create_task(). - Clarified the need to keep strong references to tasks and added a code - snippet detailing how to to this. - -- bpo-47161: Document that :class:`pathlib.PurePath` does not collapse - initial double slashes because they denote UNC paths. - -Tests ------ - -- gh-issue-91330: Added more tests for :mod:`dataclasses` to cover behavior - with data descriptor-based fields. - -- gh-issue-94208: ``test_ssl`` is now checking for supported TLS version and - protocols in more tests. - -- gh-issue-94315: Tests now check for DAC override capability instead of - relying on :func:`os.geteuid`. - -- gh-issue-93951: In test_bdb.StateTestCase.test_skip, avoid including - auxiliary importers. - -- gh-issue-93957: Provide nicer error reporting from subprocesses in - test_venv.EnsurePipTest.test_with_pip. - -- gh-issue-84461: ``run_tests.py`` now handles cross compiling env vars - correctly and pass ``HOSTRUNNER`` to regression tests. - -- gh-issue-93616: ``test_modulefinder`` now creates a temporary directory in - ``ModuleFinderTest.setUp()`` instead of module scope. - -- gh-issue-93575: Fix issue with test_unicode test_raiseMemError. The test - case now use ``test.support.calcobjsize`` to calculate size of PyUnicode - structs. :func:`sys.getsizeof` may return different size when string has - UTF-8 memory. - -- gh-issue-90473: WASI does not have a ``chmod(2)`` syscall. - :func:`os.chmod` is now a dummy function on WASI. Skip all tests that - depend on working :func:`os.chmod`. - -- gh-issue-90473: Skip tests on WASI that require symlinks with absolute - paths. - -- gh-issue-57539: Increase calendar test coverage for - :meth:`calendar.LocaleTextCalendar.formatweekday`. - -- gh-issue-90473: Skip symlink tests on WASI. wasmtime uses ``openat2(2)`` - with ``RESOLVE_BENEATH`` flag, which prevents symlinks with absolute - paths. - -- gh-issue-89858: Fix ``test_embed`` for out-of-tree builds. Patch by Kumar - Aditya. - -- gh-issue-92886: Fixing tests that fail when running with optimizations - (``-O``) in ``test_imaplib.py``. - -- gh-issue-92886: Fixing tests that fail when running with optimizations - (``-O``) in ``test_zipimport.py`` - -- bpo-47016: Create a GitHub Actions workflow for verifying bundled pip and - setuptools. Patch by Illia Volochii and Adam Turner. - -Build ------ - -- gh-issue-94404: ``makesetup`` now works around an issue with sed on macOS - and uses correct CFLAGS for object files that end up in a shared - extension. Module CFLAGS are used before PY_STDMODULE_CFLAGS to avoid - clashes with system headers. - -- gh-issue-93584: Address race condition in ``Makefile`` when installing a - PGO build. All ``test`` and ``install`` targets now depend on ``all`` - target. - -- gh-issue-93491: ``configure`` now detects and reports :pep:`11` support - tiers. - -Windows -------- - -- gh-issue-93824: Drag and drop of files onto Python files in Windows - Explorer has been enabled for Windows ARM64. - -- bpo-42658: Support native Windows case-insensitive path comparisons by - using ``LCMapStringEx`` instead of :func:`str.lower` in - :func:`ntpath.normcase`. Add ``LCMapStringEx`` to the :mod:`_winapi` - module. - -Tools/Demos ------------ - -- gh-issue-94538: Fix Argument Clinic output to custom file destinations. - Patch by Erlend E. Aasland. - -- gh-issue-94430: Allow parameters named ``module`` and ``self`` with custom - C names in Argument Clinic. Patch by Erlend E. Aasland - -C API ------ - -- gh-issue-93937: The following frame functions and type are now directly - available with ``#include <Python.h>``, it's no longer needed to add - ``#include <frameobject.h>``: - - * :c:func:`PyFrame_Check` - * :c:func:`PyFrame_GetBack` - * :c:func:`PyFrame_GetBuiltins` - * :c:func:`PyFrame_GetGenerator` - * :c:func:`PyFrame_GetGlobals` - * :c:func:`PyFrame_GetLasti` - * :c:func:`PyFrame_GetLocals` - * :c:type:`PyFrame_Type` - - Patch by Victor Stinner. - -- gh-issue-91321: Fix the compatibility of the Python C API with C++ older - than C++11. Patch by Victor Stinner. - -- gh-issue-91731: Avoid defining the ``static_assert`` when compiling with - C++ 11, where this is a keyword and redefining it can lead to undefined - behavior. Patch by Pablo Galindo - -- gh-issue-93442: Add C++ overloads for _Py_CAST_impl() to handle 0/NULL. - This will allow C++ extensions that pass 0 or NULL to macros using - _Py_CAST() to continue to compile. - - -What's New in Python 3.11.0 beta 3? -=================================== - -*Release date: 2022-06-01* - -Core and Builtins ------------------ - -- gh-issue-93359: Ensure that custom :mod:`ast` nodes without explicit end - positions can be compiled. Patch by Pablo Galindo. - -- gh-issue-93345: Fix a crash in substitution of a ``TypeVar`` in nested - generic alias after ``TypeVarTuple``. - -Build ------ - -- gh-issue-69093: Fix ``Modules/Setup.stdlib.in`` rule for ``_sqlite3`` - extension. - - -What's New in Python 3.11.0 beta 2? -=================================== - -*Release date: 2022-05-30* - -Core and Builtins ------------------ - -- gh-issue-84694: The ``--experimental-isolated-subinterpreters`` configure - option and ``EXPERIMENTAL_ISOLATED_SUBINTERPRETERS`` macro have been - removed. - -- gh-issue-91924: Fix ``__lltrace__`` debug feature if the stdout encoding - is not UTF-8. Patch by Victor Stinner. - -- gh-issue-93061: Backward jumps after ``async for`` loops are no longer - given dubious line numbers. - -- gh-issue-93065: Fix contextvars HAMT implementation to handle iteration - over deep trees. - - The bug was discovered and fixed by Eli Libman. See - `MagicStack/immutables#84 - <https://github.com/MagicStack/immutables/issues/84>`_ for more details. - -- gh-issue-90473: Decrease default recursion limit on WASI to address - limited call stack size. - -- gh-issue-92804: Fix memory leak in ``memoryview`` iterator as it was not - finalized at exit. Patch by Kumar Aditya. - -- gh-issue-92236: Remove spurious "LINE" event when starting a generator or - coroutine, visible tracing functions implemented in C. - -- gh-issue-92619: Make the compiler duplicate an exit block only if none of - its instructions have a lineno (previously only the first instruction in - the block was checked, leading to unnecessarily duplicated blocks). - -- gh-issue-92261: Fix hang when trying to iterate over a ``typing.Union``. - -Library -------- - -- gh-issue-93297: Make asyncio task groups prevent child tasks from being - GCed - -- gh-issue-90817: The :func:`locale.resetlocale` function is deprecated and - will be removed in Python 3.13. Use ``locale.setlocale(locale.LC_ALL, - "")`` instead. Patch by Victor Stinner. - -- gh-issue-92728: The :func:`re.template` function and the corresponding - :const:`re.TEMPLATE` and :const:`re.T` flags are restored after they were - removed in 3.11.0b1, but they are now deprecated, so they might be removed - from Python 3.13. - -- gh-issue-93044: No longer convert the database argument of - :func:`sqlite3.connect` to bytes before passing it to the factory. - -- gh-issue-93010: In a very special case, the email package tried to append - the nonexistent ``InvalidHeaderError`` to the defect list. It should have - been ``InvalidHeaderDefect``. - -- gh-issue-92675: Fix :func:`venv.ensure_directories` to accept - :class:`pathlib.Path` arguments in addition to :class:`str` paths. Patch - by David Foster. - -- gh-issue-87901: Removed the ``encoding`` argument from :func:`os.popen` - that was added in 3.11b1. - -- gh-issue-91922: Fix function :func:`sqlite.connect` and the - :class:`sqlite.Connection` constructor on non-UTF-8 locales. Also, they - now support bytes paths non-decodable with the current FS encoding. - -- gh-issue-92839: Fixed crash resulting from calling bisect.insort() or - bisect.insort_left() with the key argument not equal to None. - -- gh-issue-90473: :mod:`subprocess` now fails early on Emscripten and WASI - platforms to work around missing :func:`os.pipe` on WASI. - -- gh-issue-92671: Fixed :func:`ast.unparse` for empty tuples in the - assignment target context. - -- gh-issue-91581: :meth:`~datetime.datetime.utcfromtimestamp` no longer - attempts to resolve ``fold`` in the pure Python implementation, since the - fold is never 1 in UTC. In addition to being slightly faster in the common - case, this also prevents some errors when the timestamp is close to - :attr:`datetime.min <datetime.datetime.min>`. Patch by Paul Ganssle. - -- gh-issue-92550: Fix :meth:`pathlib.Path.rglob` for empty pattern. - -- gh-issue-92530: Fix an issue that occurred after interrupting - :func:`threading.Condition.notify`. - -- gh-issue-92531: The statistics.median_grouped() function now always return - a float. Formerly, it did not convert the input type when for sequences of - length one. - -- gh-issue-91810: :class:`~xml.etree.ElementTree.ElementTree` method - :meth:`~xml.etree.ElementTree.ElementTree.write` and function - :func:`~xml.etree.ElementTree.tostring` now use the text file's encoding - ("UTF-8" if not available) instead of locale encoding in XML declaration - when ``encoding="unicode"`` is specified. - -- gh-issue-90622: Worker processes for - :class:`concurrent.futures.ProcessPoolExecutor` are no longer spawned on - demand (a feature added in 3.9) when the multiprocessing context start - method is ``"fork"`` as that can lead to deadlocks in the child processes - due to a fork happening while threads are running. - -- gh-issue-91581: Remove an unhandled error case in the C implementation of - calls to :meth:`datetime.fromtimestamp <datetime.datetime.fromtimestamp>` - with no time zone (i.e. getting a local time from an epoch timestamp). - This should have no user-facing effect other than giving a possibly more - accurate error message when called with timestamps that fall on - 10000-01-01 in the local time. Patch by Paul Ganssle. - -- bpo-39064: :class:`zipfile.ZipFile` now raises :exc:`zipfile.BadZipFile` - instead of ``ValueError`` when reading a corrupt zip file in which the - central directory offset is negative. - -- bpo-45393: Fix the formatting for ``await x`` and ``not x`` in the - operator precedence table when using the :func:`help` system. - -- bpo-28249: Set :attr:`doctest.DocTest.lineno` to ``None`` when object does - not have :attr:`__doc__`. - -- bpo-45046: Add support of context managers in :mod:`unittest`: methods - :meth:`~unittest.TestCase.enterContext` and - :meth:`~unittest.TestCase.enterClassContext` of class - :class:`~unittest.TestCase`, method - :meth:`~unittest.IsolatedAsyncioTestCase.enterAsyncContext` of class - :class:`~unittest.IsolatedAsyncioTestCase` and function - :func:`unittest.enterModuleContext`. - -- bpo-42627: Fix incorrect parsing of Windows registry proxy settings - -Documentation -------------- - -- gh-issue-86438: Clarify that :option:`-W` and :envvar:`PYTHONWARNINGS` are - matched literally and case-insensitively, rather than as regular - expressions, in :mod:`warnings`. - -- gh-issue-92240: Added release dates for "What's New in Python 3.X" for - 3.0, 3.1, 3.2, 3.8 and 3.10 - -- bpo-40838: Document that :func:`inspect.getdoc`, - :func:`inspect.getmodule`, and :func:`inspect.getsourcefile` might return - ``None``. - -- bpo-38056: Overhaul the :ref:`error-handlers` documentation in - :mod:`codecs`. - -- bpo-13553: Document tkinter.Tk args. - -Tests ------ - -- gh-issue-92670: Skip - ``test_shutil.TestCopy.test_copyfile_nonexistent_dir`` test on AIX as the - test uses a trailing slash to force the OS consider the path as a - directory, but on AIX the trailing slash has no effect and is considered - as a file. - -Build ------ - -- gh-issue-90473: Disable pymalloc and increase stack size on - ``wasm32-wasi``. - -- bpo-34449: Drop invalid compiler switch ``-fPIC`` for HP aCC on HP-UX. - Patch by Michael Osipov. - -Windows -------- - -- gh-issue-92817: Ensures that :file:`py.exe` will prefer an active virtual - environment over default tags specified with environment variables or - through a :file:`py.ini` file. - -- gh-issue-92984: Explicitly disable incremental linking for non-Debug - builds - -- gh-issue-92841: :mod:`asyncio` no longer throws ``RuntimeError: Event loop - is closed`` on interpreter exit after asynchronous socket activity. Patch - by Oleg Iarygin. - -- bpo-46907: Update Windows installer to use SQLite 3.38.4. - -C API ------ - -- gh-issue-92898: Fix C++ compiler warnings when casting function arguments - to ``PyObject*``. Patch by Serge Guelton. - -- gh-issue-92913: Ensures changes to - :c:member:`PyConfig.module_search_paths` are ignored unless - :c:member:`PyConfig.module_search_paths_set` is set - -- gh-issue-92781: Avoid mixing declarations and code in the C API to fix the - compiler warning: "ISO C90 forbids mixed declarations and code" - [-Werror=declaration-after-statement]. Patch by Victor Stinner. - - -What's New in Python 3.11.0 beta 1? -=================================== - -*Release date: 2022-05-06* - -Security --------- - -- gh-issue-57684: Add the :option:`-P` command line option and the - :envvar:`PYTHONSAFEPATH` environment variable to not prepend a potentially - unsafe path to :data:`sys.path`. Patch by Victor Stinner. - -Core and Builtins ------------------ - -- gh-issue-89519: Chaining classmethod descriptors (introduced in bpo-19072) - is deprecated. It can no longer be used to wrap other descriptors such as - property(). The core design of this feature was flawed, and it caused a - number of downstream problems. - -- gh-issue-92345: ``pymain_run_python()`` now imports ``readline`` and - ``rlcompleter`` before sys.path is extended to include the current working - directory of an interactive interpreter. Non-interactive interpreters are - not affected. - -- bpo-43857: Improve the :exc:`AttributeError` message when deleting a - missing attribute. Patch by Géry Ogam. - -- gh-issue-92245: Make sure that PEP 523 is respected in all cases. In - 3.11a7, specialization may have prevented Python-to-Python calls - respecting PEP 523. - -- gh-issue-92203: Add a closure keyword-only parameter to exec(). It can - only be specified when exec-ing a code object that uses free variables. - When specified, it must be a tuple, with exactly the number of cell - variables referenced by the code object. closure has a default value of - None, and it must be None if the code object doesn't refer to any free - variables. - -- gh-issue-91173: Disable frozen modules in debug builds. Patch by Kumar - Aditya. - -- gh-issue-92114: Improve error message when subscript a type with - ``__class_getitem__`` set to ``None``. - -- gh-issue-92112: Fix crash triggered by an evil custom ``mro()`` on a - metaclass. - -- gh-issue-92063: The ``PRECALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS`` - instruction now ensures methods are called only on objects of the correct - type. - -- gh-issue-92031: Deoptimize statically allocated code objects during - ``Py_FINALIZE()`` so that future ``_PyCode_Quicken`` calls always start - with unquickened code. - -- gh-issue-92036: Fix a crash in subinterpreters related to the garbage - collector. When a subinterpreter is deleted, untrack all objects tracked - by its GC. To prevent a crash in deallocator functions expecting objects - to be tracked by the GC, leak a strong reference to these objects on - purpose, so they are never deleted and their deallocator functions are not - called. Patch by Victor Stinner. - -- gh-issue-92032: The interpreter can now autocomplete soft keywords, as of - now ``match``, ``case``, and ``_`` (wildcard pattern) from :pep:`634`. - -- gh-issue-87999: The warning emitted by the Python parser for a numeric - literal immediately followed by keyword has been changed from deprecation - warning to syntax warning. - -- gh-issue-91869: Fix an issue where specialized opcodes with extended - arguments could produce incorrect tracing output or lead to assertion - failures. - -- gh-issue-91603: Speed up :class:`types.UnionType` instantiation. Based on - patch provided by Yurii Karabas. - -- gh-issue-89373: If Python is built in debug mode, Python now ensures that - deallocator functions leave the current exception unchanged. Patch by - Victor Stinner. - -- gh-issue-91632: Fix a minor memory leak at exit: release the memory of the - :class:`generic_alias_iterator` type. Patch by Dong-hee Na. - -- gh-issue-81548: Octal escapes with value larger than ``0o377`` now produce - a :exc:`DeprecationWarning`. In a future Python version they will be a - :exc:`SyntaxWarning` and eventually a :exc:`SyntaxError`. - -- bpo-43950: Use a single compact table for line starts, ends and column - offsets. Reduces memory consumption for location info by half - -- gh-issue-91102: Use Argument Clinic for :class:`EncodingMap`. Patch by - Oleg Iarygin. - -- gh-issue-91636: Fixed a crash in a garbage-collection edge-case, in which - a ``PyFunction_Type.tp_clear`` function could leave a python function - object in an inconsistent state. - -- gh-issue-91603: Speed up :func:`isinstance` and :func:`issubclass` checks - for :class:`types.UnionType`. Patch by Yurii Karabas. - -- gh-issue-91625: Fixed a bug in which adaptive opcodes ignored any - preceding ``EXTENDED_ARG``\ s on specialization failure. - -- gh-issue-78607: The LLTRACE special build now looks for the name - ``__lltrace__`` defined in module globals, rather than the name - ``__ltrace__``, which had been introduced as a typo. - -- gh-issue-91576: Speed up iteration of ascii strings by 50%. Patch by Kumar - Aditya. - -- gh-issue-89279: Improve interpreter performance on Windows by inlining a - few specific macros. - -- gh-issue-91502: Add a new :c:func:`_PyFrame_IsEntryFrame` API function, to - check if a :c:type:`PyFrameObject` is an entry frame. Patch by Pablo - Galindo. - -- gh-issue-91266: Refactor the ``bytearray`` strip methods ``strip``, - ``lstrip`` and ``rstrip`` to use a common implementation. - -- gh-issue-91479: Replaced the ``__note__`` field of :exc:`BaseException` - (added in an earlier version of 3.11) with the final design of :pep:`678`. - Namely, :exc:`BaseException` gets an :meth:`add_note` method, and its - ``__notes__`` field is created when necessary. - -- gh-issue-46055: Speed up right shift of negative integers, by removing - unnecessary creation of temporaries. Original patch by Xinhang Xu, - reworked by Mark Dickinson. - -- gh-issue-91462: Make the interpreter's low-level tracing (lltrace) feature - output more readable by displaying opcode names (rather than just - numbers), and by displaying stack contents before each opcode. - -- gh-issue-89455: Fixed an uninitialized bool value in the traceback - printing code path that was introduced by the initial bpo-45292 exception - groups work. - -- gh-issue-91421: Fix a potential integer overflow in _Py_DecodeUTF8Ex. - -- gh-issue-91428: Add ``static const char *const _PyOpcode_OpName[256] = - {...};`` to ``opcode.h`` for debug builds to assist in debugging the - Python interpreter. It is now more convenient to make various forms of - debugging output more human-readable by including opcode names rather than - just the corresponding decimal digits. - -- bpo-47120: Make :opcode:`POP_JUMP_IF_TRUE`, :opcode:`POP_JUMP_IF_FALSE`, - :opcode:`POP_JUMP_IF_NONE` and :opcode:`POP_JUMP_IF_NOT_NONE` virtual, - mapping to new relative jump opcodes. - -- bpo-45317: Add internal documentation explaining design of new (for 3.11) - frame stack. - -- bpo-47197: ctypes used to mishandle ``void`` return types, so that for - instance a function declared like ``ctypes.CFUNCTYPE(None, ctypes.c_int)`` - would be called with signature ``int f(int)`` instead of ``void f(int)``. - Wasm targets require function pointers to be called with the correct - signatures so this led to crashes. The problem is now fixed. - -- bpo-47120: Make opcodes :opcode:`JUMP_IF_TRUE_OR_POP` and - :opcode:`JUMP_IF_FALSE_OR_POP` relative rather than absolute. - -- bpo-47177: Replace the ``f_lasti`` member of the internal - ``_PyInterpreterFrame`` structure with a ``prev_instr`` pointer, which - reduces overhead in the main interpreter loop. The ``f_lasti`` attribute - of Python-layer frame objects is preserved for backward-compatibility. - -- bpo-46961: Integer mod/remainder operations, including the three-argument - form of :func:`pow`, now consistently return ints from the global small - integer cache when applicable. - -- bpo-46962: Classes and functions that unconditionally declared their - docstrings ignoring the `--without-doc-strings` compilation flag no longer - do so. - - The classes affected are :class:`ctypes.UnionType`, - :class:`pickle.PickleBuffer`, :class:`testcapi.RecursingInfinitelyError`, - and :class:`types.GenericAlias`. - - The functions affected are 24 methods in :mod:`ctypes`. - - Patch by Oleg Iarygin. - -- bpo-46942: Use Argument Clinic for the :class:`types.MethodType` - constructor. Patch by Oleg Iarygin. - -- bpo-46764: Fix wrapping bound methods with @classmethod - -- bpo-43464: Optimize :meth:`set.intersection` for non-set arguments. - -- bpo-46721: Optimize :meth:`set.issuperset` for non-set argument. - -- bpo-46509: Add type-specialized versions of the ``Py_DECREF()``, and use - them for ``float``, ``int``, ``str``, ``bool``, and ``None`` to avoid - pointer-chasing at runtime where types are known at C compile time. - -- bpo-46045: Do not use POSIX semaphores on NetBSD - -- bpo-36819: Fix crashes in built-in encoders with error handlers that - return position less or equal than the starting position of non-encodable - characters. - -- bpo-34093: ``marshal.dumps()`` uses ``FLAG_REF`` for all interned strings. - This makes output more deterministic and helps reproducible build. - -- bpo-26579: Added ``object.__getstate__`` which provides the default - implementation of the ``__getstate__()`` method. - - Copying and pickling instances of subclasses of builtin types bytearray, - set, frozenset, collections.OrderedDict, collections.deque, - weakref.WeakSet, and datetime.tzinfo now copies and pickles instance - attributes implemented as slots. - -Library -------- - -- gh-issue-87901: Add the *encoding* parameter to :func:`os.popen`. - -- gh-issue-90997: Fix an issue where :mod:`dis` utilities may interpret - populated inline cache entries as valid instructions. - -- gh-issue-92332: Deprecate :class:`typing.Text` (removal of the class is - currently not planned). Patch by Alex Waygood. - -- Deprecate nested classes in enum definitions becoming members -- in 3.13 - they will be normal classes; add `member` and `nonmember` functions to - allow control over results now. - -- gh-issue-92356: Fixed a performance regression in ctypes function calls. - -- gh-issue-90997: Show the actual named values stored in inline caches when - ``show_caches=True`` is passed to :mod:`dis` utilities. - -- gh-issue-92301: Prefer ``close_range()`` to iterating over procfs for file - descriptor closing in :mod:`subprocess` for better performance. - -- gh-issue-67248: Sort the miscellaneous topics in Cmd.do_help() - -- gh-issue-92210: Port ``socket.__init__`` to Argument Clinic. Patch by - Cinder. - -- gh-issue-80010: Add support for generalized ISO 8601 parsing to - :meth:`datetime.datetime.fromisoformat`, - :meth:`datetime.date.fromisoformat` and - :meth:`datetime.time.fromisoformat`. Patch by Paul Ganssle. - -- gh-issue-92118: Fix a 3.11 regression in - :func:`~contextlib.contextmanager`, which caused it to propagate - exceptions with incorrect tracebacks. - -- gh-issue-90887: Adding ``COPYFILE_STAT``, ``COPYFILE_ACL`` and - ``COPYFILE_XATTR`` constants for :func:`os.fcopyfile` available in macOs. - -- gh-issue-91215: For @dataclass, add weakref_slot. Default is False. If - True, and if slots=True, add a slot named "__weakref__", which will allow - instances to be weakref'd. Contributed by Eric V. Smith - -- gh-issue-85984: New function os.login_tty() for Unix. - -- gh-issue-92128: Add :meth:`~object.__class_getitem__` to - :class:`logging.LoggerAdapter` and :class:`logging.StreamHandler`, - allowing them to be parameterized at runtime. Patch by Alex Waygood. - -- gh-issue-92049: Forbid pickling constants ``re._constants.SUCCESS`` etc. - Previously, pickling did not fail, but the result could not be unpickled. - -- gh-issue-92062: :class:`inspect.Parameter` now raises :exc:`ValueError` if - ``name`` is a keyword, in addition to the existing check that it is an - identifier. - -- gh-issue-87390: Add an ``__unpacked__`` attribute to - :class:`types.GenericAlias`. Patch by Jelle Zijlstra. - -- gh-issue-88089: Add support for generic :class:`typing.NamedTuple`. - -- gh-issue-91996: New http.HTTPMethod enum to represent all the available - HTTP request methods in a convenient way - -- gh-issue-91984: Modified test strings in test_argparse.py to not contain - trailing spaces before end of line. - -- gh-issue-91952: Add ``encoding="locale"`` support to - :meth:`TextIOWrapper.reconfigure`. - -- gh-issue-91954: Add *encoding* and *errors* arguments to - :func:`subprocess.getoutput` and :func:`subprocess.getstatusoutput`. - -- bpo-47029: Always close the read end of the pipe used by - :class:`multiprocessing.Queue` *after* the last write of buffered data to - the write end of the pipe to avoid :exc:`BrokenPipeError` at garbage - collection and at :meth:`multiprocessing.Queue.close` calls. Patch by Géry - Ogam. - -- gh-issue-91928: Add `datetime.UTC` alias for `datetime.timezone.utc`. - - Patch by Kabir Kwatra. - -- gh-issue-68966: The :mod:`mailcap` module is now deprecated and will be - removed in Python 3.13. See :pep:`594` for the rationale and the - :mod:`mimetypes` module for an alternative. Patch by Victor Stinner. - -- gh-issue-91401: Provide a way to disable :mod:`subprocess` use of - ``vfork()`` just in case it is ever needed and document the existing - mechanism for ``posix_spawn()``. - -- gh-issue-64783: Fix :data:`signal.NSIG` value on FreeBSD to accept signal - numbers greater than 32, like :data:`signal.SIGRTMIN` and - :data:`signal.SIGRTMAX`. Patch by Victor Stinner. - -- gh-issue-91910: Add missing f prefix to f-strings in error messages from - the :mod:`multiprocessing` and :mod:`asyncio` modules. - -- gh-issue-91860: Add :func:`typing.dataclass_transform`, implementing - :pep:`681`. Patch by Jelle Zijlstra. - -- gh-issue-91832: Add ``required`` attribute to :class:`argparse.Action` - repr output. - -- gh-issue-91827: In the :mod:`tkinter` module add method - ``info_patchlevel()`` which returns the exact version of the Tcl library - as a named tuple similar to :data:`sys.version_info`. - -- gh-issue-84461: Add :option:`--enable-wasm-pthreads` to enable pthreads - support for WASM builds. ``Emscripten/node`` no longer has threading - enabled by default. Include additional file systems. - -- gh-issue-91821: Fix unstable ``test_from_tuple`` test in - ``test_decimal.py``. - -- gh-issue-91217: Deprecate the xdrlib module. - -- gh-issue-91217: Deprecate the uu module. - -- gh-issue-91760: More strict rules will be applied for numerical group - references and group names in regular expressions. For now, a deprecation - warning is emitted for group references and group names which will be - errors in future Python versions. - -- gh-issue-84461: Add provisional :data:`sys._emscripten_info` named tuple - with build-time and run-time information about Emscripten platform. - -- gh-issue-90623: :func:`signal.raise_signal` and :func:`os.kill` now check - immediately for pending signals. Patch by Victor Stinner. - -- gh-issue-91734: Fix OSS audio support on Solaris. - -- gh-issue-90633: Include the passed value in the exception thrown by - :func:`typing.assert_never`. Patch by Jelle Zijlstra. - -- gh-issue-91700: Compilation of regular expression containing a conditional - expression ``(?(group)...)`` now raises an appropriate :exc:`re.error` if - the group number refers to not defined group. Previously an internal - RuntimeError was raised. - -- gh-issue-91231: Add an optional keyword *shutdown_timeout* parameter to - the :class:`multiprocessing.BaseManager` constructor. Kill the process if - terminate() takes longer than the timeout. Patch by Victor Stinner. - -- gh-issue-91621: Fix :func:`typing.get_type_hints` for - :class:`collections.abc.Callable`. Patch by Shantanu Jain. - -- gh-issue-90568: Parsing ``\N`` escapes of Unicode Named Character - Sequences in a :mod:`regular expression <re>` raises now :exc:`re.error` - instead of ``TypeError``. - -- gh-issue-91670: Remove deprecated ``SO`` config variable in - :mod:`sysconfig`. - -- gh-issue-91217: Deprecate the telnetlib module. - -- gh-issue-91217: Deprecate the sunau module. - -- gh-issue-91217: Deprecate the spwd module. - -- gh-issue-91217: Deprecate the sndhdr module, as well as inline needed - functionality for ``email.mime.MIMEAudio``. - -- gh-issue-91616: :mod:`re` module, fix :meth:`~re.Pattern.fullmatch` - mismatch when using Atomic Grouping or Possessive Quantifiers. - -- gh-issue-91217: Deprecate the 'pipes' module. - -- gh-issue-91217: Deprecate the ossaudiodev module. - -- bpo-47256: :mod:`re` module, limit the maximum capturing group to - 1,073,741,823 in 64-bit build, this increases the depth of backtracking. - -- gh-issue-91217: Deprecate the nis module. - -- gh-issue-91595: Fix the comparison of character and integer inside - :func:`Tools.gdb.libpython.write_repr`. Patch by Yu Liu. - -- gh-issue-74166: Add option to raise all errors from - :meth:`~socket.create_connection` in an :exc:`ExceptionGroup` when it - fails to create a connection. The default remains to raise only the last - error that had occurred when multiple addresses were tried. - -- gh-issue-91487: Optimize asyncio UDP speed, over 100 times faster when - transferring a large file. - -- gh-issue-91575: Update case-insensitive matching in the :mod:`re` module - to the latest Unicode version. - -- gh-issue-90622: In ``concurrent.futures.process.ProcessPoolExecutor`` - disallow the "fork" multiprocessing start method when the new - ``max_tasks_per_child`` feature is used as the mix of threads+fork can - hang the child processes. Default to using the safe "spawn" start method - in that circumstance if no ``mp_context`` was supplied. - -- gh-issue-89022: In :mod:`sqlite3`, ``SQLITE_MISUSE`` result codes are now - mapped to :exc:`~sqlite3.InterfaceError` instead of - :exc:`~sqlite3.ProgrammingError`. Also, more accurate exceptions are - raised when binding parameters fail. Patch by Erlend E. Aasland. - -- gh-issue-91526: Stop calling ``os.device_encoding(file.fileno())`` in - :class:`TextIOWrapper`. It was complex, never documented, and didn't work - for most cases. (Patch by Inada Naoki.) - -- gh-issue-88116: Change the frame-related functions in the :mod:`inspect` - module to return a regular object (that is backwards compatible with the - old tuple-like interface) that include the extended :pep:`657` position - information (end line number, column and end column). The affected - functions are: :func:`inspect.getframeinfo`, - :func:`inspect.getouterframes`, :func:`inspect.getinnerframes`, - :func:`inspect.stack` and :func:`inspect.trace`. Patch by Pablo Galindo. - -- gh-issue-69093: Add indexing and slicing support to :class:`sqlite3.Blob`. - Patch by Aviv Palivoda and Erlend E. Aasland. - -- gh-issue-69093: Add :term:`context manager` support to - :class:`sqlite3.Blob`. Patch by Aviv Palivoda and Erlend E. Aasland. - -- gh-issue-91217: Deprecate nntplib. - -- gh-issue-91217: Deprecate msilib. - -- gh-issue-91404: Improve the performance of :mod:`re` matching by using - computed gotos (or "threaded code") on supported platforms and removing - expensive pointer indirections. - -- gh-issue-91217: Deprecate the imghdr module. - -- gh-issue-91217: Deprecate the crypt module. - -- gh-issue-91276: Make space for longer opcodes in :mod:`dis` output. - -- bpo-47000: Make :class:`TextIOWrapper` uses locale encoding when - ``encoding="locale"`` is specified even in UTF-8 mode. - -- gh-issue-91230: :func:`warnings.catch_warnings` now accepts arguments for - :func:`warnings.simplefilter`, providing a more concise way to locally - ignore warnings or convert them to errors. - -- gh-issue-91217: Deprecate the chunk module. - -- Add the ``TCP_CONNECTION_INFO`` option (available on macOS) to - :mod:`socket`. - -- bpo-47260: Fix ``os.closerange()`` potentially being a no-op in a Linux - seccomp sandbox. - -- bpo-47087: Implement ``typing.Required`` and ``typing.NotRequired`` - (:pep:`655`). Patch by David Foster and Jelle Zijlstra. - -- bpo-47061: Deprecate cgi and cgitb. - -- bpo-47061: Deprecate audioop. - -- bpo-47000: Add :func:`locale.getencoding` to get the current locale - encoding. It is similar to ``locale.getpreferredencoding(False)`` but - ignores the :ref:`Python UTF-8 Mode <utf8-mode>`. - -- bpo-42012: Add :mod:`wsgiref.types`, containing WSGI-specific types for - static type checking. - -- bpo-47227: Suppress expression chaining for more :mod:`re` parsing errors. - -- bpo-47211: Remove undocumented and never working function - ``re.template()`` and flag ``re.TEMPLATE``. This was later reverted in - 3.11.0b2 and deprecated instead. - -- bpo-47135: :meth:`decimal.localcontext` now accepts context attributes via - keyword arguments - -- bpo-43323: Fix errors in the :mod:`email` module if the charset itself - contains undecodable/unencodable characters. - -- bpo-46841: Disassembly of quickened code. - -- bpo-46681: Forward gzip.compress() compresslevel to zlib. - -- bpo-45100: Add :func:`typing.get_overloads` and - :func:`typing.clear_overloads`. Patch by Jelle Zijlstra. - -- bpo-44807: :class:`typing.Protocol` no longer silently replaces - :meth:`__init__` methods defined on subclasses. Patch by Adrian Garcia - Badaracco. - -- bpo-46787: Fix :class:`concurrent.futures.ProcessPoolExecutor` exception - memory leak - -- bpo-46720: Add support for path-like objects to - :func:`multiprocessing.set_executable` for Windows to be on a par with - Unix-like systems. Patch by Géry Ogam. - -- bpo-46696: Add ``SO_INCOMING_CPU`` constant to :mod:`socket`. - -- bpo-46053: Fix OSS audio support on NetBSD. - -- bpo-45639: ``image/avif`` and ``image/webp`` were added to - :mod:`mimetypes`. - -- bpo-46285: Add command-line option ``-p``/``--protocol`` to module - :mod:`http.server` which specifies the HTTP version to which the server is - conformant (HTTP/1.1 conformant servers can now be run from the - command-line interface of module :mod:`http.server`). Patch by Géry Ogam. - -- bpo-44791: Accept ellipsis as the last argument of - :data:`typing.Concatenate`. - -- bpo-46547: Remove variables leaking into ``pydoc.Helper`` class namespace. - -- bpo-46415: Fix ipaddress.ip_{address,interface,network} raising TypeError - instead of ValueError if given invalid tuple as address parameter. - -- bpo-46075: ``CookieJar`` with ``DefaultCookiePolicy`` now can process - cookies from localhost with domain=localhost explicitly specified in - Set-Cookie header. - -- bpo-45995: Add a "z" option to the string formatting specification that - coerces negative zero floating-point values to positive zero after - rounding to the format precision. Contributed by John Belmonte. - -- bpo-26175: Fully implement the :class:`io.BufferedIOBase` or - :class:`io.TextIOBase` interface for - :class:`tempfile.SpooledTemporaryFile` objects. This lets them work - correctly with higher-level layers (like compression modules). Patch by - Carey Metcalfe. - -- bpo-45138: Fix a regression in the :mod:`sqlite3` trace callback where - bound parameters were not expanded in the passed statement string. The - regression was introduced in Python 3.10 by :issue:`40318`. Patch by - Erlend E. Aasland. - -- bpo-44863: Allow :class:`~typing.TypedDict` subclasses to also include - :class:`~typing.Generic` as a base class in class based syntax. Thereby - allowing the user to define a generic ``TypedDict``, just like a - user-defined generic but with ``TypedDict`` semantics. - -- bpo-44587: Fix BooleanOptionalAction to not automatically add a default - string. If a default string is desired, use a formatter to add it. - -- bpo-43827: All positional-or-keyword parameters to ``ABCMeta.__new__`` are - now positional-only to avoid conflicts with keyword arguments to be passed - to :meth:`__init_subclass__`. - -- bpo-43218: Prevent creation of a venv whose path contains the PATH - separator. This could affect the usage of the activate script. Patch by - Dustin Rodrigues. - -- bpo-38435: Add a ``process_group`` parameter to :class:`subprocess.Popen` - to help move more things off of the unsafe ``preexec_fn`` parameter. - -- bpo-42066: Fix cookies getting sorted in :func:`CookieJar.__iter__` which - is an extra behavior and not mentioned in RFC 2965 or Netscape cookie - protocol. Now the cookies in ``CookieJar`` follows the order of the - ``Set-Cookie`` header. Patch by Iman Kermani. - -- bpo-40617: Add :meth:`~sqlite3.Connection.create_window_function` to - :class:`sqlite3.Connection` for creating aggregate window functions. Patch - by Erlend E. Aasland. - -- bpo-40676: Convert :mod:`csv` to use Argument Clinic for - :func:`csv.field_size_limit`, :func:`csv.get_dialect`, - :func:`csv.unregister_dialect` and :func:`csv.list_dialects`. - -- bpo-39716: Raise an ArgumentError when the same subparser name is added - twice to an `argparse.ArgumentParser`. This is consistent with the - (default) behavior when the same option string is added twice to an - ArgumentParser. - -- bpo-36073: Raise :exc:`~sqlite3.ProgrammingError` instead of segfaulting - on recursive usage of cursors in :mod:`sqlite3` converters. Patch by - Sergey Fedoseev. - -- bpo-34975: Adds a ``start_tls()`` method to - :class:`~asyncio.streams.StreamWriter`, which upgrades the connection with - TLS using the given :class:`~ssl.SSLContext`. - -- bpo-22276: :class:`~pathlib.Path` methods :meth:`~pathlib.Path.glob` and - :meth:`~pathlib.Path.rglob` return only directories if *pattern* ends with - a pathname components separator (``/`` or :data:`~os.sep`). Patch by - Eisuke Kawashima. - -- bpo-24905: Add :meth:`~sqlite3.Connection.blobopen` to - :class:`sqlite3.Connection`. :class:`sqlite3.Blob` allows incremental I/O - operations on blobs. Patch by Aviv Palivoda and Erlend E. Aasland. - -Documentation -------------- - -- gh-issue-91888: Add a new `gh` role to the documentation to link to GitHub - issues. - -- gh-issue-91783: Document security issues concerning the use of the - function :meth:`shutil.unpack_archive` - -- gh-issue-91547: Remove "Undocumented modules" page. - -- gh-issue-91298: In ``importlib.resources.abc``, refined the documentation - of the Traversable Protocol, applying changes from importlib_resources - 5.7.1. - -- bpo-44347: Clarify the meaning of *dirs_exist_ok*, a kwarg of - :func:`shutil.copytree`. - -- bpo-36329: Remove 'make -C Doc serve' in favour of 'make -C Doc htmlview' - -- bpo-47189: Add a What's New in Python 3.11 entry for the Faster CPython - project. Documentation by Ken Jin and Kumar Aditya. - -- bpo-38668: Update the introduction to documentation for :mod:`os.path` to - remove warnings that became irrelevant after the implementations of - :pep:`383` and :pep:`529`. - -- bpo-47115: The documentation now lists which members of C structs are part - of the :ref:`Limited API/Stable ABI <stable>`. - -- bpo-46962: All docstrings in code snippets are now wrapped into - :func:`PyDoc_STR` to follow the guideline of `PEP 7's Documentation - Strings paragraph - <https://www.python.org/dev/peps/pep-0007/#documentation-strings>`_. Patch - by Oleg Iarygin. - -- bpo-26792: Improve the docstrings of :func:`runpy.run_module` and - :func:`runpy.run_path`. Original patch by Andrew Brezovsky. - -Tests ------ - -- gh-issue-92169: Use ``warnings_helper.import_deprecated()`` to import - deprecated modules uniformly in tests. Patch by Hugo van Kemenade. - -- gh-issue-84461: When multiprocessing is enabled, libregrtest can now use a - Python executable other than :code:`sys.executable` via the ``--python`` - flag. - -- gh-issue-91904: Fix initialization of - :envvar:`PYTHONREGRTEST_UNICODE_GUARD` which prevented running regression - tests on non-UTF-8 locale. - -- gh-issue-91752: Added @requires_zlib to - test.test_tools.test_freeze.TestFreeze. - -- gh-issue-91607: Fix ``test_concurrent_futures`` to test the correct - multiprocessing start method context in several cases where the test logic - mixed this up. - -- bpo-40280: Threading tests are now skipped on WASM targets without pthread - support. - -- bpo-47109: Test for :mod:`ctypes.macholib.dyld`, - :mod:`ctypes.macholib.dylib`, and :mod:`ctypes.macholib.framework` are - brought from manual pre-:mod:`unittest` times to :mod:`ctypes.test` - location and structure. Patch by Oleg Iarygin. - -- bpo-29890: Add tests for :class:`ipaddress.IPv4Interface` and - :class:`ipaddress.IPv6Interface` construction with tuple arguments. - Original patch and tests by louisom. - -Build ------ - -- gh-issue-89452: gdbm-compat is now preferred over ndbm if both are - available on the system. This allows avoiding the problematic ndbm.h on - macOS. - -- gh-issue-91731: Python is now built with ``-std=c11`` compiler option, - rather than ``-std=c99``. Patch by Victor Stinner. - -- bpo-47152: Add script and make target for generating ``sre_constants.h``. - -- bpo-47103: Windows ``PGInstrument`` builds now copy a required DLL into - the output directory, making it easier to run the profile stage of a PGO - build. - -Windows -------- - -- bpo-46907: Update Windows installer to use SQLite 3.38.3. - -- bpo-47239: Fixed --list and --list-paths output for :ref:`launcher` when - used in an active virtual environment. - -- bpo-46907: Update Windows installer to use SQLite 3.38.2. - -- bpo-46785: Fix race condition between :func:`os.stat` and unlinking a file - on Windows, by using errors codes returned by ``FindFirstFileW()`` when - appropriate in ``win32_xstat_impl``. - -- bpo-40859: Update Windows build to use xz-5.2.5 - -macOS ------ - -- bpo-46907: Update macOS installer to SQLite 3.38.4. - -Tools/Demos ------------ - -- gh-issue-91583: Fix regression in the code generated by Argument Clinic - for functions with the ``defining_class`` parameter. - -- gh-issue-91575: Add script ``Tools/scripts/generate_re_casefix.py`` and - the make target ``regen-re`` for generating additional data for - case-insensitive matching according to the current Unicode version. - -- gh-issue-91551: Remove the ancient Pynche color editor. It has moved to - https://gitlab.com/warsaw/pynche - -C API ------ - -- gh-issue-88279: Deprecate the C functions: :c:func:`PySys_SetArgv`, - :c:func:`PySys_SetArgvEx`, :c:func:`PySys_SetPath`. Patch by Victor - Stinner. - -- gh-issue-92154: Added the :c:func:`PyCode_GetCode` function. This function - does the equivalent of the Python code ``getattr(code_object, - 'co_code')``. - -- gh-issue-92173: Fix the ``closure`` argument to - :c:func:`PyEval_EvalCodeEx`. - -- gh-issue-91320: Fix C++ compiler warnings about "old-style cast" (``g++ - -Wold-style-cast``) in the Python C API. Use C++ ``reinterpret_cast<>`` - and ``static_cast<>`` casts when the Python C API is used in C++. Patch by - Victor Stinner. - -- gh-issue-80527: Mark functions as deprecated by :pep:`623`: - :c:func:`PyUnicode_AS_DATA`, :c:func:`PyUnicode_AS_UNICODE`, - :c:func:`PyUnicode_GET_DATA_SIZE`, :c:func:`PyUnicode_GET_SIZE`. Patch by - Victor Stinner. - -- gh-issue-91768: :c:func:`Py_REFCNT`, :c:func:`Py_TYPE`, :c:func:`Py_SIZE` - and :c:func:`Py_IS_TYPE` functions argument type is now ``PyObject*``, - rather than ``const PyObject*``. Patch by Victor Stinner. - -- gh-issue-91020: Add ``PyBytes_Type.tp_alloc`` to initialize - ``PyBytesObject.ob_shash`` for bytes subclasses. - -- bpo-40421: Add ``PyFrame_GetLasti`` C-API function to access frame - object's ``f_lasti`` attribute safely from C code. - -- bpo-35134: Remove the ``Include/code.h`` header file. C extensions should - only include the main ``<Python.h>`` header file. Patch by Victor Stinner. - -- bpo-47169: :c:func:`PyOS_CheckStack` is now exported in the Stable ABI on - Windows. - -- bpo-47169: :c:func:`PyThread_get_thread_native_id` is excluded from the - stable ABI on platforms where it doesn't exist (like Solaris). - -- bpo-46343: Added :c:func:`PyErr_GetHandledException` and - :c:func:`PyErr_SetHandledException` as simpler alternatives to - :c:func:`PyErr_GetExcInfo` and :c:func:`PyErr_SetExcInfo`. - - They are included in the stable ABI. - - -What's New in Python 3.11.0 alpha 7? -==================================== - -*Release date: 2022-04-05* - -Core and Builtins ------------------ - -- bpo-47212: Raise :exc:`IndentationError` instead of :exc:`SyntaxError` for - a bare ``except`` with no following indent. Improve :exc:`SyntaxError` - locations for an un-parenthesized generator used as arguments. Patch by - Matthieu Dartiailh. - -- bpo-47186: Replace :opcode:`JUMP_IF_NOT_EG_MATCH` by - :opcode:`CHECK_EG_MATCH` + jump. - -- bpo-47176: Emscripten builds cannot handle signals in the usual way due to - platform limitations. Python can now handle signals. To use, set - Module.Py_EmscriptenSignalBuffer to be a single byte SharedArrayBuffer and - set Py_EMSCRIPTEN_SIGNAL_HANDLING to 1. Writing a number into the - SharedArrayBuffer will cause the corresponding signal to be raised into - the Python thread. - -- bpo-47186: Replace :opcode:`JUMP_IF_NOT_EXC_MATCH` by - :opcode:`CHECK_EXC_MATCH` + jump. - -- bpo-47120: Replace the absolute jump opcode :opcode:`JUMP_NO_INTERRUPT` by - the relative :opcode:`JUMP_BACKWARD_NO_INTERRUPT`. - -- bpo-46841: Avoid unnecessary allocations when comparing code objects. - -- bpo-47182: Fix a crash when using a named unicode character like - ``"\N{digit nine}"`` after the main interpreter has been initialized a - second time. - -- bpo-47162: WebAssembly cannot deal with bad function pointer casts - (different count or types of arguments). Python can now use call - trampolines to mitigate the problem. Define :c:macro:`PY_CALL_TRAMPOLINE` - to enable call trampolines. - -- bpo-46775: Some Windows system error codes(>= 10000) are now mapped into - the correct errno and may now raise a subclass of :exc:`OSError`. Patch by - Dong-hee Na. - -- bpo-47129: Improve error messages in f-string syntax errors concerning - empty expressions. - -- bpo-47117: Fix a crash if we fail to decode characters in interactive mode - if the tokenizer buffers are uninitialized. Patch by Pablo Galindo. - -- bpo-47127: Speed up calls to c functions with keyword arguments by 25% - with specialization. Patch by Kumar Aditya. - -- bpo-47120: Replaced :opcode:`JUMP_ABSOLUTE` by the relative jump - :opcode:`JUMP_BACKWARD`. - -- bpo-42197: :c:func:`PyFrame_FastToLocalsWithError` and - :c:func:`PyFrame_LocalsToFast` are no longer called during profiling nor - tracing. C code can access the ``f_locals`` attribute of - :c:type:`PyFrameObject` by calling :c:func:`PyFrame_GetLocals`. - -- bpo-47070: Improve performance of ``array_inplace_repeat`` by reducing the - number of invocations of ``memcpy``. Refactor the ``repeat`` and inplace - ``repeat`` methods of ``array``, ``bytes``, ``bytearray`` and - ``unicodeobject`` to use the common ``_PyBytes_Repeat``. - -- bpo-47053: Reduce de-optimization in the specialized - ``BINARY_OP_INPLACE_ADD_UNICODE`` opcode. - -- bpo-47045: Remove the ``f_state`` field from the _PyInterpreterFrame - struct. Add the ``owner`` field to the _PyInterpreterFrame struct to make - ownership explicit to simplify clearing and deallocing frames and - generators. - -- bpo-46968: Check for the existence of the "sys/auxv.h" header in - :mod:`faulthandler` to avoid compilation problems in systems where this - header doesn't exist. Patch by Pablo Galindo - -- bpo-46329: Use low bit of ``LOAD_GLOBAL`` to indicate whether to push a - ``NULL`` before the global. Helps streamline the call sequence a bit. - -- bpo-46841: Quicken bytecode in-place by storing it as part of the - corresponding ``PyCodeObject``. - -- bpo-47012: Speed up iteration of :class:`bytes` and :class:`bytearray` by - 30%. Patch by Kumar Aditya. - -- bpo-47009: Improved the performance of :meth:`list.append()` and list - comprehensions by optimizing for the common case, where no resize is - needed. Patch by Dennis Sweeney. - -- bpo-47005: Improve performance of ``bytearray_repeat`` and - ``bytearray_irepeat`` by reducing the number of invocations of ``memcpy``. - -- bpo-46829: Deprecate passing a message into :meth:`asyncio.Future.cancel` - and :meth:`asyncio.Task.cancel` - -- bpo-46993: Speed up :class:`bytearray` creation from :class:`list` and - :class:`tuple` by 40%. Patch by Kumar Aditya. - -- bpo-39829: Removed the ``__len__()`` call when initializing a list and - moved initializing to ``list_extend``. Patch by Jeremiah Pascual. - -- bpo-46944: Speed up throwing exception in generator with - :const:`METH_FASTCALL` calling convention. Patch by Kumar Aditya. - -- bpo-46841: Modify :opcode:`STORE_SUBSCR` to use an inline cache entry - (rather than its oparg) as an adaptive counter. - -- bpo-46841: Use inline caching for :opcode:`PRECALL` and :opcode:`CALL`, - and remove the internal machinery for managing the (now unused) non-inline - caches. - -- bpo-46881: Statically allocate and initialize the latin1 characters. - -- bpo-46838: Improve syntax errors for incorrect function definitions. Patch - by Pablo Galindo - -- bpo-43721: Fix docstrings of :attr:`~property.getter`, - :attr:`~property.setter`, and :attr:`~property.deleter` to clarify that - they create a new copy of the property. - -- bpo-43224: Make grammar changes required for PEP 646. - -Library -------- - -- bpo-47208: Allow vendors to override :const:`CTYPES_MAX_ARGCOUNT`. - -- bpo-23689: :mod:`re` module: fix memory leak when a match is terminated by - a signal or memory allocation failure. Patch by Ma Lin. - -- bpo-47167: Allow overriding a future compliance check in - :class:`asyncio.Task`. - -- bpo-47151: When subprocess tries to use vfork, it now falls back to fork - if vfork returns an error. This allows use in situations where vfork isn't - allowed by the OS kernel. - -- bpo-47152: Convert the :mod:`re` module into a package. Deprecate modules - ``sre_compile``, ``sre_constants`` and ``sre_parse``. - -- bpo-4833: Add :meth:`ZipFile.mkdir` - -- bpo-27929: Fix :meth:`asyncio.loop.sock_connect` to only resolve names for - :const:`socket.AF_INET` or :const:`socket.AF_INET6` families. Resolution - may not make sense for other families, like :const:`socket.AF_BLUETOOTH` - and :const:`socket.AF_UNIX`. - -- bpo-14265: Adds the fully qualified test name to unittest output - -- bpo-47061: Deprecate the aifc module. - -- bpo-39622: Handle Ctrl+C in asyncio programs to interrupt the main task. - -- bpo-47101: :const:`hashlib.algorithms_available` now lists only algorithms - that are provided by activated crypto providers on OpenSSL 3.0. Legacy - algorithms are not listed unless the legacy provider has been loaded into - the default OSSL context. - -- bpo-47099: All :exc:`URLError` exception messages raised in - :class:`urllib.request.URLopener` now contain a colon between ``ftp - error`` and the rest of the message. Previously, - :func:`~urllib.request.URLopener.open_ftp` missed the colon. Patch by Oleg - Iarygin. - -- bpo-47099: Exception chaining is changed from - :func:`Exception.with_traceback`/:func:`sys.exc_info` to :pep:`3134`. - Patch by Oleg Iarygin. - -- bpo-47095: :mod:`hashlib`'s internal ``_blake2`` module now prefers - ``libb2`` from https://www.blake2.net/ over Python's vendored copy of - blake2. - -- bpo-47098: The Keccak Code Package for :mod:`hashlib`'s internal ``_sha3`` - module has been replaced with tiny_sha3. The module is used as fallback - when Python is built without OpenSSL. - -- bpo-47088: Implement :data:`typing.LiteralString`, part of :pep:`675`. - Patch by Jelle Zijlstra. - -- bpo-42885: Optimize :func:`re.search`, :func:`re.split`, - :func:`re.findall`, :func:`re.finditer` and :func:`re.sub` for regular - expressions starting with ``\A`` or ``^``. - -- bpo-23691: Protect the :func:`re.finditer` iterator from re-entering. - -- bpo-47067: Optimize calling ``GenericAlias`` objects by using :pep:`590` - ``vectorcall`` and by replacing ``PyObject_SetAttrString`` with - ``PyObject_SetAttr``. - -- bpo-28080: Add the *metadata_encoding* parameter in the - :class:`zipfile.ZipFile` constructor and the ``--metadata-encoding`` - option in the :mod:`zipfile` CLI to allow reading zipfiles using - non-standard codecs to encode the filenames within the archive. - -- bpo-47000: Make :func:`io.text_encoding` returns "utf-8" when UTF-8 mode - is enabled. - -- bpo-42369: Fix thread safety of :meth:`zipfile._SharedFile.tell` to avoid - a "zipfile.BadZipFile: Bad CRC-32 for file" exception when reading a - :class:`ZipFile` from multiple threads. - -- bpo-38256: Fix :func:`binascii.crc32` when it is compiled to use zlib'c - crc32 to work properly on inputs 4+GiB in length instead of returning the - wrong result. The workaround prior to this was to always feed the function - data in increments smaller than 4GiB or to just call the zlib module - function. - - We also have :func:`binascii.crc32` release the GIL when computing on - larger inputs as :func:`zlib.crc32` and :mod:`hashlib` do. - - This also boosts performance on Windows as it now uses the zlib crc32 - implementation for :func:`binascii.crc32` for a 2-3x speedup. - - That the stdlib has a crc32 API in two modules is a known historical - oddity. This moves us closer to a single implementation behind them. - -- bpo-47066: Global inline flags (e.g. ``(?i)``) can now only be used at the - start of the regular expressions. Using them not at the start of - expression was deprecated since Python 3.6. - -- bpo-39394: A warning about inline flags not at the start of the regular - expression now contains the position of the flag. - -- bpo-433030: Add support of atomic grouping (``(?>...)``) and possessive - quantifiers (``*+``, ``++``, ``?+``, ``{m,n}+``) in :mod:`regular - expressions <re>`. - -- bpo-47062: Implement :class:`asyncio.Runner` context manager. - -- bpo-46382: :func:`~dataclasses.dataclass` ``slots=True`` now correctly - omits slots already defined in base classes. Patch by Arie Bovenberg. - -- bpo-47057: Use FASTCALL convention for ``FutureIter.throw()`` - -- bpo-47061: Deprecate the various modules listed by :pep:`594`: - - aifc, asynchat, asyncore, audioop, cgi, cgitb, chunk, crypt, imghdr, - msilib, nntplib, nis, ossaudiodev, pipes, smtpd, sndhdr, spwd, sunau, - telnetlib, uu, xdrlib - -- bpo-34790: Remove passing coroutine objects to :func:`asyncio.wait`. - -- bpo-47039: Normalize ``repr()`` of asyncio future and task objects. - -- bpo-2604: Fix bug where doctests using globals would fail when run - multiple times. - -- bpo-45150: Add :func:`hashlib.file_digest` helper for efficient hashing of - file object. - -- bpo-34861: Made cumtime the default sorting key for cProfile - -- bpo-45997: Fix :class:`asyncio.Semaphore` re-aquiring FIFO order. - -- bpo-47022: The :mod:`asynchat`, :mod:`asyncore` and :mod:`smtpd` modules - have been deprecated since at least Python 3.6. Their documentation and - deprecation warnings and have now been updated to note they will removed - in Python 3.12 (:pep:`594`). - -- bpo-43253: Fix a crash when closing transports where the underlying socket - handle is already invalid on the Proactor event loop. - -- bpo-40280: :func:`select.select` now passes ``NULL`` to ``select`` for - each empty fdset. - -- bpo-47004: Apply bugfixes from importlib_metadata 4.11.3, including bugfix - for EntryPoint.extras, which was returning match objects and not the - extras strings. - -- bpo-46998: Allow subclassing of :class:`typing.Any`. Patch by Shantanu - Jain. - -- bpo-46995: Deprecate missing :meth:`asyncio.Task.set_name` for third-party - task implementations, schedule making it mandatory in Python 3.13. - -- bpo-46994: Accept explicit contextvars.Context in - :func:`asyncio.create_task` and :meth:`asyncio.loop.create_task`. - -- bpo-46981: ``typing.get_args(typing.Tuple[()])`` now returns ``()`` - instead of ``((),)``. - -- bpo-46968: Add ``os.sysconf_names['SC_MINSIGSTKSZ']``. - -- bpo-46985: Upgrade pip wheel bundled with ensurepip (pip 22.0.4) - -- bpo-46968: :mod:`faulthandler`: On Linux 5.14 and newer, dynamically - determine size of signal handler stack size CPython allocates using - ``getauxval(AT_MINSIGSTKSZ)``. This changes allows for Python extension's - request to Linux kernel to use AMX_TILE instruction set on Sapphire Rapids - Xeon processor to succeed, unblocking use of the ISA in frameworks. - -- bpo-46917: The :data:`math.nan` value is now always available. Patch by - Victor Stinner. - -- bpo-46955: Expose :class:`asyncio.base_events.Server` as - :class:`asyncio.Server`. Patch by Stefan Zabka. - -- bpo-23325: The :mod:`signal` module no longer assumes that - :const:`~signal.SIG_IGN` and :const:`~signal.SIG_DFL` are small int - singletons. - -- bpo-46932: Update bundled libexpat to 2.4.7 - -- bpo-46933: The :mod:`pwd` module is now optional. - :func:`os.path.expanduser` returns the path when the :mod:`pwd` module is - not available. - -- bpo-40059: :pep:`680`, the :mod:`tomllib` module. Adds support for parsing - TOML. - -- bpo-464471: :func:`asyncio.timeout` and :func:`asyncio.timeout_at` context - managers added. Patch by Tin Tvrtković and Andrew Svetlov. - -- bpo-46805: Added raw datagram socket functions for asyncio: - :meth:`~asyncio.AbstractEventLoop.sock_sendto`, - :meth:`~asyncio.AbstractEventLoop.sock_recvfrom` and - :meth:`~asyncio.AbstractEventLoop.sock_recvfrom_into`. - -- bpo-46644: No longer require valid typeforms to be callable. This allows - :data:`typing.Annotated` to wrap :data:`typing.ParamSpecArgs` and - :data:`dataclasses.InitVar`. Patch by Gregory Beauregard. - -- bpo-46581: Brings :class:`ParamSpec` propagation for :class:`GenericAlias` - in line with :class:`Concatenate` (and others). - -- bpo-45413: Define *posix_venv* and *nt_venv* :ref:`sysconfig installation - schemes <installation_paths>` to be used for bootstrapping new virtual - environments. Add *venv* sysconfig installation scheme to get the - appropriate one of the above. The schemes are identical to the - pre-existing *posix_prefix* and *nt* install schemes. The :mod:`venv` - module now uses the *venv* scheme to create new virtual environments - instead of hardcoding the paths depending only on the platform. Downstream - Python distributors customizing the *posix_prefix* or *nt* install scheme - in a way that is not compatible with the install scheme used in virtual - environments are encouraged not to customize the *venv* schemes. When - Python itself runs in a virtual environment, - :func:`sysconfig.get_default_scheme` and - :func:`sysconfig.get_preferred_scheme` with ``key="prefix"`` returns - *venv*. - -- bpo-43224: Implement support for PEP 646 in typing.py. - -- bpo-43224: Allow unpacking types.GenericAlias objects, e.g. ``*tuple[int, - str]``. - -- bpo-46557: Warnings captured by the logging module are now logged without - a format string to prevent systems that group logs by the msg argument - from grouping captured warnings together. - -- bpo-41370: :func:`typing.get_type_hints` now supports evaluating strings - as forward references in :ref:`PEP 585 generic aliases - <types-genericalias>`. - -- bpo-46607: Add :exc:`DeprecationWarning` to :class:`LegacyInterpolation`, - deprecated in the docstring since Python 3.2. Will be removed in Python - 3.13. Use :class:`BasicInterpolation` or :class:`ExtendedInterpolation` - instead. - -- bpo-26120: :mod:`pydoc` now excludes __future__ imports from the module's - data items. - -- bpo-46480: Add :func:`typing.assert_type`. Patch by Jelle Zijlstra. - -- bpo-46421: Fix a unittest issue where if the command was invoked as - ``python -m unittest`` and the filename(s) began with a dot (.), a - ``ValueError`` is returned. - -- bpo-46245: Add optional parameter *dir_fd* in :func:`shutil.rmtree`. - -- bpo-22859: :meth:`~unittest.TestProgram.usageExit` is marked deprecated, - to be removed in 3.13. - -- bpo-46170: Improve the error message when you try to subclass an instance - of :class:`typing.NewType`. - -- bpo-40296: Fix supporting generic aliases in :mod:`pydoc`. - -- bpo-20392: Fix inconsistency with uppercase file extensions in - :meth:`MimeTypes.guess_type`. Patch by Kumar Aditya. - -- bpo-46030: Add ``LOCAL_CREDS``, ``LOCAL_CREDS_PERSISTENT`` and - ``SCM_CREDS2`` FreeBSD constants to the socket module. - -- bpo-44439: Fix ``.write()`` method of a member file in ``ZipFile``, when - the input data is an object that supports the buffer protocol, the file - length may be wrong. - -- bpo-45171: Fix handling of the ``stacklevel`` argument to logging - functions in the :mod:`logging` module so that it is consistent across all - logging functions and, as advertised, similar to the ``stacklevel`` - argument used in :meth:`~warnings.warn`. - -- bpo-24959: Fix bug where :mod:`unittest` sometimes drops frames from - tracebacks of exceptions raised in tests. - -- bpo-44859: Raise more accurate and :pep:`249` compatible exceptions in - :mod:`sqlite3`. - - * Raise :exc:`~sqlite3.InterfaceError` instead of - :exc:`~sqlite3.ProgrammingError` for ``SQLITE_MISUSE`` errors. - * Don't overwrite :exc:`BufferError` with :exc:`ValueError` when conversion to - BLOB fails. - * Raise :exc:`~sqlite3.ProgrammingError` instead of :exc:`~sqlite3.Warning` if - user tries to :meth:`~sqlite3.Cursor.execute()` more than one SQL statement. - * Raise :exc:`~sqlite3.ProgrammingError` instead of :exc:`ValueError` if an SQL - query contains null characters. - -- bpo-44493: Add missing terminated NUL in sockaddr_un's length - - This was potentially observable when using non-abstract AF_UNIX datagram - sockets to processes written in another programming language. - -- bpo-41930: Add :meth:`~sqlite3.Connection.serialize` and - :meth:`~sqlite3.Connection.deserialize` support to :mod:`sqlite3`. Patch - by Erlend E. Aasland. - -- bpo-33178: Added :class:`ctypes.BigEndianUnion` and - :class:`ctypes.LittleEndianUnion` classes, as originally documented in the - library docs but not yet implemented. - -- bpo-43352: Add an Barrier object in synchronization primitives of - *asyncio* Lib in order to be consistant with Barrier from *threading* and - *multiprocessing* libs* - -- bpo-35859: :mod:`re` module, fix a few bugs about capturing group. In rare - cases, capturing group gets an incorrect string. Patch by Ma Lin. - -Documentation -------------- - -- bpo-45099: Document internal :mod:`asyncio` API. - -- bpo-47126: Update PEP URLs to :pep:`676`'s new canonical form. - -- bpo-47040: Clarified the old Python versions compatiblity note of - :func:`binascii.crc32` / :func:`zlib.adler32` / :func:`zlib.crc32` - functions. - -- bpo-46033: Clarify ``for`` statement execution in its doc. - -- bpo-45790: Adjust inaccurate phrasing in - :doc:`../extending/newtypes_tutorial` about the ``ob_base`` field and the - macros used to access its contents. - -- bpo-42340: Document that in some circumstances :exc:`KeyboardInterrupt` - may cause the code to enter an inconsistent state. Provided a sample - workaround to avoid it if needed. - -- bpo-41233: Link the errnos referenced in ``Doc/library/exceptions.rst`` to - their respective section in ``Doc/library/errno.rst``, and vice versa. - Previously this was only done for EINTR and InterruptedError. Patch by Yan - "yyyyyyyan" Orestes. - -Tests ------ - -- bpo-47205: Skip test for :func:`~os.sched_getaffinity` and - :func:`~os.sched_setaffinity` error case on FreeBSD. - -- bpo-46126: Restore 'descriptions' when running tests internally. - -- bpo-47104: Rewrite :func:`asyncio.to_thread` tests to use - :class:`unittest.IsolatedAsyncioTestCase`. - -- bpo-40280: The test suite is now passing on the Emscripten platform. All - fork, socket, and subprocess-based tests are skipped. - -- bpo-47037: Skip ``strftime("%4Y")`` feature test on Windows. It can cause - an assertion error in debug builds. - -- bpo-46587: Skip tests if platform's ``strftime`` does not support - non-portable glibc extensions. - -- bpo-47015: A test case for :func:`os.sendfile` is converted from - deprecated :mod:`asyncore` (see :pep:`594`) to :mod:`asyncio`. Patch by - Oleg Iarygin. - -Build ------ - -- bpo-40280: Add configure option :option:`--enable-wasm-dynamic-linking` to - enable ``dlopen`` and MAIN_MODULE / SIDE_MODULE on ``wasm32-emscripten``. - -- bpo-46023: ``makesetup`` now detects and skips all duplicated module - definitions. The first entry wins. - -- bpo-40280: Add SOABI ``wasm32-emscripten`` for Emscripten and - ``wasm32-wasi`` for WASI on 32bit WASM as well as ``wasm64`` counter - parts. - -- bpo-47032: Ensure Windows install builds fail correctly with a non-zero - exit code when part of the build fails. - -- bpo-47024: Update OpenSSL to 1.1.1n for macOS installers and all Windows - builds. - -- bpo-46996: The :mod:`tkinter` package now requires Tcl/Tk version 8.5.12 - or newer. - -- bpo-46973: Add ``regen-configure`` make target to regenerate configure - script with Christian's container image - ``quay.io/tiran/cpython_autoconf:269``. - -- bpo-46917: Building Python now requires support of IEEE 754 floating point - numbers. Patch by Victor Stinner. - -- bpo-45774: ``configure`` now verifies that all SQLite C APIs needed for - the :mod:`sqlite3` extension module are found. - -Windows -------- - -- bpo-47194: Update ``zlib`` to v1.2.12 to resolve CVE-2018-25032. - -- bpo-47171: Enables installing the :file:`py.exe` launcher on Windows - ARM64. - -- bpo-46566: Upgraded :ref:`launcher` to support a new ``-V:company/tag`` - argument for full :pep:`514` support and to detect ARM64 installs. The - ``-64`` suffix on arguments is deprecated, but still selects any - non-32-bit install. Setting :envvar:`PYLAUNCHER_ALLOW_INSTALL` and - specifying a version that is not installed will attempt to install the - requested version from the Microsoft Store. - -- bpo-47086: The installer for Windows now includes documentation as loose - HTML files rather than a single compiled :file:`.chm` file. - -- bpo-46907: Update Windows installer to use SQLite 3.38.1. - -- bpo-44549: Update bzip2 to 1.0.8 in Windows builds to mitigate - CVE-2016-3189 and CVE-2019-12900 - -- bpo-46948: Prevent CVE-2022-26488 by ensuring the Add to PATH option in - the Windows installer uses the correct path when being repaired. - -macOS ------ - -- bpo-46890: Fix a regression in the setting of ``sys._base_executable`` in - framework builds, and thereby fix a regression in :mod:`venv` virtual - environments with such builds. - -- bpo-46907: Update macOS installer to SQLite 3.38.1. - -Tools/Demos ------------ - -- bpo-40280: Replace Emscripten's limited shell with Katie Bell's browser-ui - REPL from python-wasm project. - -C API ------ - -- bpo-40421: Add ``PyFrame_GetBuiltins``, ``PyFrame_GetGenerator`` and - ``PyFrame_GetGlobals`` C-API functions to access frame object attributes - safely from C code. - -- bpo-46850: Move the private ``_PyFrameEvalFunction`` type, and private - ``_PyInterpreterState_GetEvalFrameFunc()`` and - ``_PyInterpreterState_SetEvalFrameFunc()`` functions to the internal C - API. The ``_PyFrameEvalFunction`` callback function type now uses the - ``_PyInterpreterFrame`` type which is part of the internal C API. Patch by - Victor Stinner. - -- bpo-46850: Move the private undocumented ``_PyEval_EvalFrameDefault()`` - function to the internal C API. The function now uses the - ``_PyInterpreterFrame`` type which is part of the internal C API. Patch by - Victor Stinner. - -- bpo-46850: Remove the private undocumented function - ``_PyEval_CallTracing()`` from the C API. Call the public - :func:`sys.call_tracing` function instead. Patch by Victor Stinner. - -- bpo-46850: Remove the private undocumented function - ``_PyEval_GetCoroutineOriginTrackingDepth()`` from the C API. Call the - public :func:`sys.get_coroutine_origin_tracking_depth` function instead. - Patch by Victor Stinner. - -- bpo-46850: Remove the following private undocumented functions from the C - API: - - * ``_PyEval_GetAsyncGenFirstiter()`` - * ``_PyEval_GetAsyncGenFinalizer()`` - * ``_PyEval_SetAsyncGenFirstiter()`` - * ``_PyEval_SetAsyncGenFinalizer()`` - - Call the public :func:`sys.get_asyncgen_hooks` and - :func:`sys.set_asyncgen_hooks` functions instead. Patch by Victor Stinner. - -- bpo-46987: Remove private functions ``_PySys_GetObjectId()`` and - ``_PySys_SetObjectId()``. Patch by Dong-hee Na. - -- bpo-46906: Add new functions to pack and unpack C double (serialize and - deserialize): :c:func:`PyFloat_Pack2`, :c:func:`PyFloat_Pack4`, - :c:func:`PyFloat_Pack8`, :c:func:`PyFloat_Unpack2`, - :c:func:`PyFloat_Unpack4` and :c:func:`PyFloat_Unpack8`. Patch by Victor - Stinner. - - -What's New in Python 3.11.0 alpha 6? -==================================== - -*Release date: 2022-03-07* - -Core and Builtins ------------------ - -- bpo-46940: Avoid overriding :exc:`AttributeError` metadata information for - nested attribute access calls. Patch by Pablo Galindo. - -- bpo-46927: Include the type's name in the error message for subscripting - non-generic types. - -- bpo-46921: Support vectorcall for ``super()``. Patch by Ken Jin. - -- bpo-46841: Fix incorrect handling of inline cache entries when - specializing :opcode:`BINARY_OP`. - -- bpo-46841: Use an oparg to simplify the construction of helpful error - messages in :opcode:`GET_AWAITABLE`. - -- bpo-46903: Make sure that str subclasses can be used as attribute names - for instances with virtual dictionaries. Fixes regression in 3.11alpha - -- bpo-46841: Add more detailed specialization failure stats for - :opcode:`COMPARE_OP` followed by :opcode:`EXTENDED_ARG`. - -- bpo-46891: Fix bug introduced during 3.11alpha where subclasses of - ``types.ModuleType`` with ``__slots__`` were not initialized correctly, - resulting in an interpreter crash. - -- bpo-46841: Use inline caching for :opcode:`LOAD_ATTR`, - :opcode:`LOAD_METHOD`, and :opcode:`STORE_ATTR`. - -- bpo-46841: Use inline cache for :opcode:`BINARY_SUBSCR`. - -- bpo-46841: Use inline caching for :opcode:`COMPARE_OP`. - -- bpo-46864: Deprecate ``PyBytesObject.ob_shash``. It will be removed in - Python 3.13. - -- bpo-46841: Use inline caching for :opcode:`UNPACK_SEQUENCE`. - -- bpo-46845: Reduces dict size by removing hash value from hash table when - all inserted keys are Unicode. For example, - ``sys.getsizeof(dict.fromkeys("abcdefg"))`` becomes 272 bytes from 352 - bytes on 64bit platform. - -- bpo-46841: Use inline cache for :opcode:`LOAD_GLOBAL`. - -- bpo-46852: Rename the private undocumented ``float.__set_format__()`` - method to ``float.__setformat__()`` to fix a typo introduced in Python - 3.7. The method is only used by test_float. Patch by Victor Stinner. - -- bpo-46852: Remove the undocumented private ``float.__set_format__()`` - method, previously known as ``float.__setformat__()`` in Python 3.7. Its - docstring said: "You probably don't want to use this function. It exists - mainly to be used in Python's test suite." Patch by Victor Stinner. - -- bpo-40116: Fix regression that dict.update(other) may don't respect - iterate order of other when other is key sharing dict. - -- bpo-46712: Share global string identifiers in deep-frozen modules. - -- bpo-46430: Fix memory leak in interned strings of deep-frozen modules. - -- bpo-46841: Store :opcode:`BINARY_OP` caches inline using a new - :opcode:`CACHE` instruction. - -- bpo-45107: Specialize ``LOAD_METHOD`` for instances with a dict. - -- bpo-44337: Reduce the memory usage of specialized :opcode:`LOAD_ATTR` and - :opcode:`STORE_ATTR` instructions. - -- bpo-46729: Add number of sub-exceptions to :meth:`BaseException.__str__`. - -- bpo-45885: Don't un-adapt :opcode:`COMPARE_OP` when collecting - specialization stats. - -- bpo-46329: Fix specialization stats gathering for :opcode:`PRECALL` - instructions. - -- bpo-46794: Bump up the libexpat version into 2.4.6 - -- bpo-46823: Implement a specialized combined opcode - ``LOAD_FAST__LOAD_ATTR_INSTANCE_VALUE``. Patch by Dennis Sweeney. - -- bpo-46820: Fix parsing a numeric literal immediately (without spaces) - followed by "not in" keywords, like in ``1not in x``. Now the parser only - emits a warning, not a syntax error. - -- bpo-46329: Move ``KW_NAMES`` before ``PRECALL`` instruction in call - sequence. Change ``operand`` of ``CALL`` to match ``PRECALL`` for easier - specialization. - -- bpo-46808: Remove the ``NEXT_BLOCK`` macro from compile.c, and make the - compiler automatically generate implicit blocks when they are needed. - -- bpo-46329: Add ``PUSH_NULL`` instruction. This is used as a prefix when - evaluating a callable, so that the stack has the same shape for methods - and other calls. ``PRECALL_FUNCTION`` and ``PRECALL_METHOD`` are merged - into a single ``PRECALL`` instruction. - - There is no change in semantics. - -- bpo-46762: Fix an assert failure in debug builds when a '<', '>', or '=' - is the last character in an f-string that's missing a closing right brace. - -- bpo-46730: Message of AttributeError caused by getting, setting or - deleting a property without the corresponding function now mentions that - the attribute is in fact a property and also specifies type of the class - that it belongs to. - -- bpo-46724: Make sure that all backwards jumps use the ``JUMP_ABSOLUTE`` - instruction, rather than ``JUMP_FORWARD`` with an argument of - ``(2**32)+offset``. - -- bpo-46732: Correct the docstring for the :meth:`__bool__` method. Patch by - Jelle Zijlstra. - -- bpo-46072: Add more detailed specialization failure statistics for - :opcode:`BINARY_OP`. - -- bpo-46707: Avoid potential exponential backtracking when producing some - syntax errors involving lots of brackets. Patch by Pablo Galindo. - -- bpo-46323: :mod:`ctypes` now allocates memory on the stack instead of on - the heap to pass arguments while calling a Python callback function. Patch - by Dong-hee Na. - -- bpo-45923: Add a quickened form of :opcode:`RESUME` that skips quickening - checks. - -- bpo-46702: Specialize :opcode:`UNPACK_SEQUENCE` for :class:`tuple` and - :class:`list` unpackings. - -- bpo-46072: Opcode pair stats are now gathered with ``--enable-pystats``. - Defining ``DYNAMIC_EXECUTION_PROFILE`` or ``DXPAIRS`` no longer has any - effect. - -- bpo-46675: Allow more than 16 items in a split dict before it is combined. - The limit is now 254. - -- bpo-40479: Add a missing call to ``va_end()`` in - ``Modules/_hashopenssl.c``. - -- bpo-46323: Use :c:func:`PyObject_Vectorcall` while calling ctypes callback - function. Patch by Dong-hee Na. - -- bpo-46615: When iterating over sets internally in ``setobject.c``, acquire - strong references to the resulting items from the set. This prevents - crashes in corner-cases of various set operations where the set gets - mutated. - -- bpo-45828: The bytecode compiler now attempts to apply runtime stack - manipulations at compile-time (whenever it is feasible to do so). - -- bpo-30496: Fixed a minor portability issue in the implementation of - :c:func:`PyLong_FromLong`, and added a fast path for single-digit integers - to :c:func:`PyLong_FromLongLong`. - -Library -------- - -- bpo-25707: Fixed a file leak in :func:`xml.etree.ElementTree.iterparse` - when the iterator is not exhausted. Patch by Jacob Walls. - -- bpo-46877: Export :func:`unittest.doModuleCleanups` in :mod:`unittest`. - Patch by Kumar Aditya. - -- bpo-46848: For performance, use the optimized string-searching - implementations from :meth:`~bytes.find` and :meth:`~bytes.rfind` for - :meth:`~mmap.find` and :meth:`~mmap.rfind`. - -- bpo-46736: :class:`~http.server.SimpleHTTPRequestHandler` now uses HTML5 - grammar. Patch by Dong-hee Na. - -- bpo-44886: Inherit asyncio proactor datagram transport from - :class:`asyncio.DatagramTransport`. - -- bpo-46827: Support UDP sockets in :meth:`asyncio.loop.sock_connect` for - selector-based event loops. Patch by Thomas Grainger. - -- bpo-46811: Make test suite support Expat >=2.4.5 - -- bpo-46252: Raise :exc:`TypeError` if :class:`ssl.SSLSocket` is passed to - transport-based APIs. - -- bpo-46784: Fix libexpat symbols collisions with user dynamically loaded or - statically linked libexpat in embedded Python. - -- bpo-46786: The HTML serialisation in xml.etree.ElementTree now writes - ``embed``, ``source``, ``track`` and ``wbr`` as empty tags, as defined in - HTML 5. - -- bpo-39327: :func:`shutil.rmtree` can now work with VirtualBox shared - folders when running from the guest operating-system. - -- bpo-45390: Propagate :exc:`asyncio.CancelledError` message from inner task - to outer awaiter. - -- bpo-46756: Fix a bug in - :meth:`urllib.request.HTTPPasswordMgr.find_user_password` and - :meth:`urllib.request.HTTPPasswordMgrWithPriorAuth.is_authenticated` which - allowed to bypass authorization. For example, access to URI - ``example.org/foobar`` was allowed if the user was authorized for URI - ``example.org/foo``. - -- bpo-46737: :func:`random.gauss` and :func:`random.normalvariate` now have - default arguments. - -- bpo-46752: Add task groups to asyncio (structured concurrency, inspired by - Trio's nurseries). This also introduces a change to task cancellation, - where a cancelled task can't be cancelled again until it calls - .uncancel(). - -- bpo-46724: Fix :mod:`dis` behavior on negative jump offsets. - -- bpo-46333: The :meth:`__repr__` method of :class:`typing.ForwardRef` now - includes the ``module`` parameter of :class:`typing.ForwardRef` when it is - set. - -- bpo-46643: In :func:`typing.get_type_hints`, support evaluating - stringified ``ParamSpecArgs`` and ``ParamSpecKwargs`` annotations. Patch - by Gregory Beauregard. - -- bpo-45863: When the :mod:`tarfile` module creates a pax format archive, it - will put an integer representation of timestamps in the ustar header (if - possible) for the benefit of older unarchivers, in addition to the - existing full-precision timestamps in the pax extended header. - -- bpo-46066: Deprecate kwargs-based syntax for :class:`typing.TypedDict` - definitions. It had confusing semantics when specifying totality, and was - largely unused. Patch by Jingchen Ye. - -- bpo-46676: Make :data:`typing.ParamSpec` args and kwargs equal to - themselves. Patch by Gregory Beauregard. - -- bpo-46323: ``ctypes.CFUNCTYPE()`` and ``ctypes.WINFUNCTYPE()`` now fail to - create the type if its ``_argtypes_`` member contains too many arguments. - Previously, the error was only raised when calling a function. Patch by - Victor Stinner. - -- bpo-46672: Fix ``NameError`` in :func:`asyncio.gather` when initial type - check fails. - -- bpo-46659: The :class:`calendar.LocaleTextCalendar` and - :class:`calendar.LocaleHTMLCalendar` classes now use - :func:`locale.getlocale`, instead of using - :func:`locale.getdefaultlocale`, if no locale is specified. Patch by - Victor Stinner. - -- bpo-46659: The :func:`locale.getdefaultlocale` function is deprecated and - will be removed in Python 3.13. Use :func:`locale.setlocale`, - :func:`locale.getpreferredencoding(False) <locale.getpreferredencoding>` - and :func:`locale.getlocale` functions instead. Patch by Victor Stinner. - -- bpo-46655: In :func:`typing.get_type_hints`, support evaluating bare - stringified ``TypeAlias`` annotations. Patch by Gregory Beauregard. - -- bpo-45948: Fixed a discrepancy in the C implementation of the - :mod:`xml.etree.ElementTree` module. Now, instantiating an - :class:`xml.etree.ElementTree.XMLParser` with a ``target=None`` keyword - provides a default :class:`xml.etree.ElementTree.TreeBuilder` target as - the Python implementation does. - -- bpo-46626: Expose Linux's ``IP_BIND_ADDRESS_NO_PORT`` option in - :mod:`socket`. - -- bpo-46521: Fix a bug in the :mod:`codeop` module that was incorrectly - identifying invalid code involving string quotes as valid code. - -- bpo-46571: Improve :func:`typing.no_type_check`. - - Now it does not modify external classes and functions. We also now - correctly mark classmethods as not to be type checked. - -- bpo-46400: expat: Update libexpat from 2.4.1 to 2.4.4 - -- bpo-46556: Deprecate undocumented support for using a - :class:`pathlib.Path` object as a context manager. - -- bpo-46534: Implement :pep:`673` :class:`typing.Self`. Patch by James - Hilton-Balfe. - -- bpo-46522: Make various module ``__getattr__`` AttributeErrors more - closely match a typical AttributeError - -- bpo-46475: Add :data:`typing.Never` and :func:`typing.assert_never`. Patch - by Jelle Zijlstra. - -- bpo-46333: The :meth:`__eq__` and :meth:`__hash__` methods of - :class:`typing.ForwardRef` now honor the ``module`` parameter of - :class:`typing.ForwardRef`. Forward references from different modules are - now differentiated. - -- bpo-46246: Add missing ``__slots__`` to - ``importlib.metadata.DeprecatedList``. Patch by Arie Bovenberg. - -- bpo-46232: The :mod:`ssl` module now handles certificates with bit strings - in DN correctly. - -- bpo-46195: :func:`typing.get_type_hints` no longer adds ``Optional`` to - parameters with ``None`` as a default. This aligns to changes to PEP 484 - in https://github.com/python/peps/pull/689 - -- bpo-31369: Add :class:`~re.RegexFlag` to ``re.__all__`` and documented it. - Add :data:`~re.RegexFlag.NOFLAG` to indicate no flags being set. - -- bpo-45898: :mod:`ctypes` no longer defines ``ffi_type_*`` symbols in - ``cfield.c``. The symbols have been provided by libffi for over a decade. - -- bpo-44953: Calling ``operator.itemgetter`` objects and - ``operator.attrgetter`` objects is now faster due to use of the vectorcall - calling convention. - -- bpo-44289: Fix an issue with :meth:`~tarfile.is_tarfile` method when using - *fileobj* argument: position in the *fileobj* was advanced forward which - made it unreadable with :meth:`tarfile.TarFile.open`. - -- bpo-44011: Reimplement SSL/TLS support in asyncio, borrow the - implementation from uvloop library. - -- bpo-41086: Make the :class:`configparser.ConfigParser` constructor raise - :exc:`TypeError` if the ``interpolation`` parameter is not of type - :class:`configparser.Interpolation` - -- bpo-29418: Implement :func:`inspect.ismethodwrapper` and fix - :func:`inspect.isroutine` for cases where methodwrapper is given. Patch by - Hakan Çelik. - -- bpo-14156: argparse.FileType now supports an argument of '-' in binary - mode, returning the .buffer attribute of sys.stdin/sys.stdout as - appropriate. Modes including 'x' and 'a' are treated equivalently to 'w' - when argument is '-'. Patch contributed by Josh Rosenberg - -Documentation -------------- - -- bpo-42238: ``Doc/tools/rstlint.py`` has moved to its own repository and is - now packaged on PyPI as ``sphinx-lint``. - -Tests ------ - -- bpo-46913: Fix test_faulthandler.test_sigfpe() if Python is built with - undefined behavior sanitizer (UBSAN): disable UBSAN on the - faulthandler_sigfpe() function. Patch by Victor Stinner. - -- bpo-46760: Remove bytecode offsets from expected values in test.test_dis - module. Reduces the obstacles to modifying the VM or compiler. - -- bpo-46708: Prevent default asyncio event loop policy modification warning - after ``test_asyncio`` execution. - -- bpo-46678: The function ``make_legacy_pyc`` in - ``Lib/test/support/import_helper.py`` no longer fails when - ``PYTHONPYCACHEPREFIX`` is set to a directory on a different device from - where tempfiles are stored. - -- bpo-46623: Skip test_pair() and test_speech128() of test_zlib on s390x - since they fail if zlib uses the s390x hardware accelerator. Patch by - Victor Stinner. - -Build ------ - -- bpo-46860: Respect `--with-suffix` when building on case-insensitive file - systems. - -- bpo-46656: Building Python now requires a C11 compiler. Optional C11 - features are not required. Patch by Victor Stinner. - -- bpo-46656: Building Python now requires support for floating point - Not-a-Number (NaN): remove the ``Py_NO_NAN`` macro. Patch by by Victor - Stinner. - -- bpo-46640: Building Python now requires a C99 ``<math.h>`` header file - providing a ``NAN`` constant, or the ``__builtin_nan()`` built-in - function. Patch by Victor Stinner. - -- bpo-46608: Exclude marshalled-frozen data if deep-freezing to save 300 KB - disk space. This includes adding a new ``is_package`` field to - :c:struct:`_frozen`. Patch by Kumar Aditya. - -- bpo-40280: Fix wasm32-emscripten test failures and platform issues. - - Disable syscalls that are not supported or don't work, e.g. wait, - getrusage, prlimit, mkfifo, mknod, setres[gu]id, setgroups. - Use fd_count - to cound open fds. - Add more checks for subprocess and fork. - Add - workarounds for missing _multiprocessing and failing socket.accept(). - - Enable bzip2. - Disable large file support. - Disable signal.alarm. - -- bpo-46430: Intern strings in deep-frozen modules. Patch by Kumar Aditya. - -Windows -------- - -- bpo-46744: The default all users install directory for ARM64 is now under - the native ``Program Files`` folder, rather than ``Program Files (Arm)`` - which is intended for ARM (32-bit) files. - -- bpo-46567: Adds Tcl and Tk support for Windows ARM64. This also adds IDLE - to the installation. - -- bpo-46638: Ensures registry virtualization is consistently disabled. For - 3.10 and earlier, it remains enabled (some registry writes are protected), - while for 3.11 and later it is disabled (registry modifications affect all - applications). - -IDLE ----- - -- bpo-46630: Make query dialogs on Windows start with a cursor in the entry - box. - -- bpo-45447: Apply IDLE syntax highlighting to `.pyi` files. Patch by Alex - Waygood and Terry Jan Reedy. - -C API ------ - -- bpo-46748: Python's public headers no longer import ``<stdbool.h>``, - leaving code that embedd/extends Python free to define ``bool``, ``true`` - and ``false``. - -- bpo-46836: Move the :c:type:`PyFrameObject` type definition (``struct - _frame``) to the internal C API ``pycore_frame.h`` header file. Patch by - Victor Stinner. - -- bpo-45459: Rename ``Include/buffer.h`` header file to - ``Include/pybuffer.h`` to avoid conflits with projects having an existing - ``buffer.h`` header file. Patch by Victor Stinner. - -- bpo-45412: Remove the ``HAVE_PY_SET_53BIT_PRECISION`` macro (moved to the - internal C API). Patch by Victor Stinner. - -- bpo-46613: Added function :c:func:`PyType_GetModuleByDef`, which allows - accesss to module state when a method's defining class is not available. - - -What's New in Python 3.11.0 alpha 5? -==================================== - -*Release date: 2022-02-03* - -Core and Builtins ------------------ - -- bpo-45773: Remove two invalid "peephole" optimizations from the bytecode - compiler. - -- bpo-46564: Do not create frame objects when creating :class:`super` - object. Patch by Kumar Aditya. - -- bpo-45885: Added more fined-grained specialization failure stats regarding - the ``COMPARE_OP`` bytecode. - -- bpo-44977: The delegation of :func:`int` to :meth:`__trunc__` is now - deprecated. Calling ``int(a)`` when ``type(a)`` implements - :meth:`__trunc__` but not :meth:`__int__` or :meth:`__index__` now raises - a :exc:`DeprecationWarning`. - -- bpo-46458: Reorder code emitted by the compiler for a - :keyword:`try`-:keyword:`except` block so that the :keyword:`else` block's - code immediately follows the :keyword:`try` body (without a jump). This is - more optimal for the happy path. - -- bpo-46527: Allow passing ``iterable`` as a keyword argument to - :func:`enumerate` again. Patch by Jelle Zijlstra. - -- bpo-46528: Replace several stack manipulation instructions (``DUP_TOP``, - ``DUP_TOP_TWO``, ``ROT_TWO``, ``ROT_THREE``, ``ROT_FOUR``, and ``ROT_N``) - with new :opcode:`COPY` and :opcode:`SWAP` instructions. - -- bpo-46329: Use two or three bytecodes to implement most calls. - - Calls without named arguments are implemented as a sequence of two - instructions: ``PRECALL; CALL``. Calls with named arguments are - implemented as a sequence of three instructions: ``PRECALL; KW_NAMES; - CALL``. There are two different ``PRECALL`` instructions: - ``PRECALL_FUNTION`` and ``PRECALL_METHOD``. The latter pairs with - ``LOAD_METHOD``. - - This partition into pre-call and call allows better specialization, and - thus better performance ultimately. - - There is no change in semantics. - -- bpo-46503: Fix an assert when parsing some invalid \N escape sequences in - f-strings. - -- bpo-46431: Improve error message on invalid calls to - :meth:`BaseExceptionGroup.__new__`. - -- bpo-46476: Fix memory leak in code objects generated by deepfreeze. Patch - by Kumar Aditya. - -- bpo-46481: Speed up calls to :meth:`weakref.ref.__call__` by using the - :pep:`590` ``vectorcall`` calling convention. Patch by Dong-hee Na. - -- bpo-46417: Fix a race condition on setting a type ``__bases__`` attribute: - the internal function ``add_subclass()`` now gets the - ``PyTypeObject.tp_subclasses`` member after calling - :c:func:`PyWeakref_NewRef` which can trigger a garbage collection which - can indirectly modify ``PyTypeObject.tp_subclasses``. Patch by Victor - Stinner. - -- bpo-46417: ``python -X showrefcount`` now shows the total reference count - after clearing and destroyed the main Python interpreter. Previously, it - was shown before. Patch by Victor Stinner. - -- bpo-43683: Add ASYNC_GEN_WRAP opcode to wrap the value to be yielded in - async generators. Removes the need to special case async generators in the - ``YIELD_VALUE`` instruction. - -- bpo-46407: Optimize some modulo operations in ``Objects/longobject.c``. - Patch by Jeremiah Vivian. - -- bpo-46409: Add new ``RETURN_GENERATOR`` bytecode to make generators. - Simplifies calling Python functions in the VM, as they no longer any need - to special case generator functions. - - Also add ``JUMP_NO_INTERRUPT`` bytecode that acts like ``JUMP_ABSOLUTE``, - but does not check for interrupts. - -- bpo-46406: The integer division ``//`` implementation has been optimized - to better let the compiler understand its constraints. It can be 20% - faster on the amd64 platform when dividing an int by a value smaller than - ``2**30``. - -- bpo-46383: Fix invalid signature of ``_zoneinfo``'s ``module_free`` - function to resolve a crash on wasm32-emscripten platform. - -- bpo-46361: Ensure that "small" integers created by :meth:`int.from_bytes` - and :class:`decimal.Decimal` are properly cached. - -- bpo-46161: Fix the class building error when the arguments are constants - and CALL_FUNCTION_EX is used. - -- bpo-46028: Fixes calculation of :data:`sys._base_executable` when inside a - virtual environment that uses symlinks with different binary names than - the base environment provides. - -- bpo-46091: Correctly calculate indentation levels for lines with - whitespace character that are ended by line continuation characters. Patch - by Pablo Galindo - -- bpo-30512: Add CAN Socket support for NetBSD. - -- bpo-46045: Do not use POSIX semaphores on NetBSD - -- bpo-44024: Improve the exc:`TypeError` message for non-string second - arguments passed to the built-in functions :func:`getattr` and - :func:`hasattr`. Patch by Géry Ogam. - -Library -------- - -- bpo-46624: Restore support for non-integer arguments of - :func:`random.randrange` and :func:`random.randint`. - -- bpo-46591: Make the IDLE doc URL on the About IDLE dialog clickable. - -- bpo-46565: Remove loop variables that are leaking into modules' - namespaces. - -- bpo-46553: In :func:`typing.get_type_hints`, support evaluating bare - stringified ``ClassVar`` annotations. Patch by Gregory Beauregard. - -- bpo-46544: Don't leak ``x`` & ``uspace`` intermediate vars in - :class:`textwrap.TextWrapper`. - -- bpo-46487: Add the ``get_write_buffer_limits`` method to - :class:`asyncio.transports.WriteTransport` and to the SSL transport. - -- bpo-45173: Note the configparser deprecations will be removed in Python - 3.12. - -- bpo-45162: The deprecated :mod:`unittest` APIs removed in 3.11a1 have been - temporarily restored to be removed in 3.12 while cleanups in external - projects go in. - -- bpo-46539: In :func:`typing.get_type_hints`, support evaluating - stringified ``ClassVar`` and ``Final`` annotations inside ``Annotated``. - Patch by Gregory Beauregard. - -- bpo-46510: Add missing test for :class:`types.TracebackType` and - :class:`types.FrameType`. Calculate them directly from the caught - exception without calling :func:`sys.exc_info`. - -- bpo-46491: Allow :data:`typing.Annotated` to wrap :data:`typing.Final` and - :data:`typing.ClassVar`. Patch by Gregory Beauregard. - -- bpo-46483: Remove :meth:`~object.__class_getitem__` from - :class:`pathlib.PurePath` as this class was not supposed to be generic. - -- bpo-46436: Fix command-line option ``-d``/``--directory`` in module - :mod:`http.server` which is ignored when combined with command-line option - ``--cgi``. Patch by Géry Ogam. - -- bpo-41403: Make :meth:`mock.patch` raise a :exc:`TypeError` with a - relevant error message on invalid arg. Previously it allowed a cryptic - :exc:`AttributeError` to escape. - -- bpo-46474: In ``importlib.metadata.EntryPoint.pattern``, avoid potential - REDoS by limiting ambiguity in consecutive whitespace. - -- bpo-46474: Removed private method from ``importlib.metadata.Path``. Sync - with importlib_metadata 4.10.0. - -- bpo-46470: Remove unused branch from ``typing._remove_dups_flatten`` - -- bpo-46469: :mod:`asyncio` generic classes now return - :class:`types.GenericAlias` in ``__class_getitem__`` instead of the same - class. - -- bpo-41906: Support passing filter instances in the ``filters`` values of - ``handlers`` and ``loggers`` in the dictionary passed to - :func:`logging.config.dictConfig`. - -- bpo-46422: Use ``dis.Positions`` in ``dis.Instruction`` instead of a - regular ``tuple``. - -- bpo-46434: :mod:`pdb` now gracefully handles ``help`` when :attr:`__doc__` - is missing, for example when run with pregenerated optimized ``.pyc`` - files. - -- bpo-43869: Python uses the same time Epoch on all platforms. Add an - explicit unit test to ensure that it's the case. Patch by Victor Stinner. - -- bpo-46414: Add :func:`typing.reveal_type`. Patch by Jelle Zijlstra. - -- bpo-40280: :mod:`subprocess` now imports Windows-specific imports when - ``msvcrt`` module is available, and POSIX-specific imports on all other - platforms. This gives a clean exception when ``_posixsubprocess`` is not - available (e.g. Emscripten browser target). - -- bpo-40066: ``IntEnum``, ``IntFlag``, and ``StrEnum`` use the mixed-in type - for their ``str()`` and ``format()`` output. - -- bpo-46316: Optimize :meth:`pathlib.Path.iterdir` by removing an - unnecessary check for special entries. - -- bpo-29688: Document :meth:`pathlib.Path.absolute` (which has always - existed). - -- bpo-43012: The pathlib module's obsolete and internal ``_Accessor`` class - has been removed to prepare the terrain for upcoming enhancements to the - module. - -- bpo-46258: Speed up :func:`math.isqrt` for small positive integers by - replacing two division steps with a lookup table. - -- bpo-46242: Improve error message when creating a new :class:`enum.Enum` - type subclassing an existing ``Enum`` with ``_member_names_`` using - :meth:`enum.Enum.__call__`. - -- bpo-43118: Fix a bug in :func:`inspect.signature` that was causing it to - fail on some subclasses of classes with a ``__text_signature__`` - referencing module globals. Patch by Weipeng Hong. - -- bpo-26552: Fixed case where failing :func:`asyncio.ensure_future` did not - close the coroutine. Patch by Kumar Aditya. - -- bpo-21987: Fix an issue with :meth:`tarfile.TarFile.getmember` getting a - directory name with a trailing slash. - -- bpo-46124: Update :mod:`zoneinfo` to rely on importlib.resources - traversable API. - -- bpo-46103: Now :func:`inspect.getmembers` only gets :attr:`__bases__` - attribute from class type. Patch by Weipeng Hong. - -- bpo-46080: Fix exception in argparse help text generation if a - :class:`argparse.BooleanOptionalAction` argument's default is - ``argparse.SUPPRESS`` and it has ``help`` specified. Patch by Felix - Fontein. - -- bpo-44791: Fix substitution of :class:`~typing.ParamSpec` in - :data:`~typing.Concatenate` with different parameter expressions. - Substitution with a list of types returns now a tuple of types. - Substitution with ``Concatenate`` returns now a ``Concatenate`` with - concatenated lists of arguments. - -Documentation -------------- - -- bpo-46463: Fixes :file:`escape4chm.py` script used when building the CHM - documentation file - -Tests ------ - -- bpo-43478: Mocks can no longer be provided as the specs for other Mocks. - As a result, an already-mocked object cannot be passed to `mock.Mock()`. - This can uncover bugs in tests since these Mock-derived Mocks will always - pass certain tests (e.g. isinstance) and builtin assert functions (e.g. - assert_called_once_with) will unconditionally pass. - -- bpo-46616: Ensures ``test_importlib.test_windows`` cleans up registry keys - after completion. - -- bpo-44359: test_ftplib now silently ignores socket errors to prevent - logging unhandled threading exceptions. Patch by Victor Stinner. - -- bpo-46600: Fix test_gdb.test_pycfunction() for Python built with ``clang - -Og``. Tolerate inlined functions in the gdb traceback. Patch by Victor - Stinner. - -- bpo-46542: Fix a Python crash in test_lib2to3 when using Python built in - debug mode: limit the recursion limit. Patch by Victor Stinner. - -- bpo-46576: test_peg_generator now disables compiler optimization when - testing compilation of its own C extensions to significantly speed up the - testing on non-debug builds of CPython. - -- bpo-46542: Fix ``test_json`` tests checking for :exc:`RecursionError`: - modify these tests to use ``support.infinite_recursion()``. Patch by - Victor Stinner. - -- bpo-13886: Skip test_builtin PTY tests on non-ASCII characters if the - readline module is loaded. The readline module changes input() behavior, - but test_builtin is not intented to test the readline module. Patch by - Victor Stinner. - -- bpo-40280: Add :func:`test.support.requires_fork` decorators to mark tests - that require a working :func:`os.fork`. - -- bpo-40280: Add :func:`test.support.requires_subprocess` decorator to mark - tests which require working :mod:`subprocess` module or ``os.spawn*``. The - wasm32-emscripten platform has no support for processes. - -- bpo-46126: Disable 'descriptions' when running tests internally. - -Build ------ - -- bpo-46602: Tidied up configure.ac so that conftest.c is truncated rather - than appended. This assists in the case where the 'rm' of conftest.c fails - to happen between tests. Downstream issues such as a clobbered SOABI can - result. - -- bpo-46600: Fix the test checking if the C compiler supports ``-Og`` option - in the ``./configure`` script to also use ``-Og`` on clang which supports - it. Patch by Victor Stinner. - -- bpo-38472: Fix GCC detection in setup.py when cross-compiling. The C - compiler is now run with LC_ALL=C. Previously, the detection failed with a - German locale. - -- bpo-46513: :program:`configure` no longer uses ``AC_C_CHAR_UNSIGNED`` - macro and ``pyconfig.h`` no longer defines reserved symbol - ``__CHAR_UNSIGNED__``. - -- bpo-46471: Use global singletons for single byte bytes objects in - deepfreeze. - -- bpo-46443: Deepfreeze now uses cached small integers as it saves some - space for common small integers. - -- bpo-46429: Merge all deep-frozen files into one for space savings. Patch - by Kumar Aditya. - -- bpo-45569: The build now defaults to using 30-bit digits for Python - integers. Previously either 15-bit or 30-bit digits would be selected, - depending on the platform. 15-bit digits may still be selected using the - ``--enable-big-digits=15`` option to the ``configure`` script, or by - defining ``PYLONG_BITS_IN_DIGIT`` in ``pyconfig.h``. - -- bpo-45925: Update Windows installer to use SQLite 3.37.2. - -- bpo-43112: Detect musl libc as a separate SOABI (tagged as - ``linux-musl``). - -Windows -------- - -- bpo-33125: The traditional EXE/MSI based installer for Windows is now - available for ARM64 - -- bpo-46362: os.path.abspath("C:\CON") is now fixed to return "\\.\CON", not - the same path. The regression was true of all legacy DOS devices such as - COM1, LPT1, or NUL. - -- bpo-44934: The installer now offers a command-line only option to add the - installation directory to the end of :envvar:`PATH` instead of at the - start. - -macOS ------ - -- bpo-45925: Update macOS installer to SQLite 3.37.2. - -IDLE ----- - -- bpo-45296: Clarify close, quit, and exit in IDLE. In the File menu, - 'Close' and 'Exit' are now 'Close Window' (the current one) and 'Exit' is - now 'Exit IDLE' (by closing all windows). In Shell, 'quit()' and 'exit()' - mean 'close Shell'. If there are no other windows, this also exits IDLE. - -C API ------ - -- bpo-40170: Remove the ``PyHeapType_GET_MEMBERS()`` macro. It was exposed - in the public C API by mistake, it must only be used by Python internally. - Use the ``PyTypeObject.tp_members`` member instead. Patch by Victor - Stinner. - -- bpo-40170: Move _Py_GetAllocatedBlocks() and _PyObject_DebugMallocStats() - private functions to the internal C API. Patch by Victor Stinner. - -- bpo-46433: The internal function _PyType_GetModuleByDef now correctly - handles inheritance patterns involving static types. - -- bpo-45459: :c:type:`Py_buffer` and various ``Py_buffer`` related functions - are now part of the limited API and stable ABI. - -- bpo-14916: Fixed bug in the tokenizer that prevented - ``PyRun_InteractiveOne`` from parsing from the provided FD. - - -What's New in Python 3.11.0 alpha 4? -==================================== - -*Release date: 2022-01-13* - -Core and Builtins ------------------ - -- bpo-46070: :c:func:`Py_EndInterpreter` now explicitly untracks all objects - currently tracked by the GC. Previously, if an object was used later by - another interpreter, calling :c:func:`PyObject_GC_UnTrack` on the object - crashed if the previous or the next object of the :c:type:`PyGC_Head` - structure became a dangling pointer. Patch by Victor Stinner. - -- bpo-46347: Fix memory leak in PyEval_EvalCodeEx. - -- bpo-46339: Fix a crash in the parser when retrieving the error text for - multi-line f-strings expressions that do not start in the first line of - the string. Patch by Pablo Galindo - -- bpo-46331: Do not set line number of instruction storing doc-string. Fixes - regression introduced in 3.11 alpha. - -- bpo-46314: Remove spurious "call" event when creating a lambda function - that was accidentally introduced in 3.11a4. - -- bpo-46289: ASDL declaration of ``FormattedValue`` has changed to reflect - ``conversion`` field is not optional. - -- bpo-46297: Fixed an interpreter crash on bootup with multiple PythonPaths - set in the Windows registry. Patch by Derzsi Dániel. - -- bpo-46237: Fix the line number of tokenizer errors inside f-strings. Patch - by Pablo Galindo. - -- bpo-46263: We always expect the "use_frozen_modules" config to be set, now - that getpath.c was rewritten in pure Python and the logic improved. - -- bpo-46006: Fix a regression when a type method like ``__init__()`` is - modified in a subinterpreter. Fix a regression in - ``_PyUnicode_EqualToASCIIId()`` and type ``update_slot()``. Revert the - change which made the Unicode dictionary of interned strings compatible - with subinterpreters: the internal interned dictionary is shared again by - all interpreters. Patch by Victor Stinner. - -- bpo-45923: Add RESUME opcode. This is a logical no-op. It is emitted by - the compiler anywhere a Python function can be entered. It is used by the - interpreter to perform tracing and optimizer checks. - -- bpo-46208: Fix the regression of os.path.normpath("A/../../B") not - returning expected "../B" but "B". - -- bpo-46240: Correct the error message for unclosed parentheses when the - tokenizer doesn't reach the end of the source when the error is reported. - Patch by Pablo Galindo - -- bpo-46009: Remove the ``GEN_START`` opcode. - -- bpo-46235: Certain sequence multiplication operations like ``[0] * 1_000`` - are now faster due to reference-counting optimizations. Patch by Dennis - Sweeney. - -- bpo-46221: :opcode:`PREP_RERAISE_STAR` no longer pushes ``lasti`` to the - stack. - -- bpo-46202: Remove :opcode:`POP_EXCEPT_AND_RERAISE` and replace it by an - equivalent sequence of other opcodes. - -- bpo-46085: Fix iterator cache mechanism of :class:`OrderedDict`. - -- bpo-46055: Speed up shifting operation involving integers less than - :c:macro:`PyLong_BASE`. Patch by Xinhang Xu. - -- bpo-46110: Add a maximum recursion check to the PEG parser to avoid stack - overflow. Patch by Pablo Galindo - -- bpo-46107: Fix bug where :meth:`ExceptionGroup.split` and - :meth:`ExceptionGroup.subgroup` did not copy the exception group's - ``__note__`` field to the parts. - -- bpo-45711: The interpreter state's representation of handled exceptions - (a.k.a exc_info, or _PyErr_StackItem) now has only the ``exc_value`` - field, ``exc_type`` and ``exc_traceback`` have been removed as their - values can be derived from ``exc_value``. - -- bpo-44525: Replace the four call bytecode instructions which one pre-call - instruction and two call instructions. - - Removes ``CALL_FUNCTION``, ``CALL_FUNCTION_KW``, ``CALL_METHOD`` and - ``CALL_METHOD_KW``. - - Adds ``CALL_NO_KW`` and ``CALL_KW`` call instructions, and - ``PRECALL_METHOD`` prefix for pairing with ``LOAD_METHOD``. - -- bpo-46039: Remove the ``YIELD_FROM`` instruction and replace it with the - ``SEND`` instruction which performs the same operation, but without the - loop. - -- bpo-45635: The code called from :c:func:`_PyErr_Display` was refactored to - improve error handling. It now exits immediately upon an unrecoverable - error. - -- bpo-46054: Fix parser error when parsing non-utf8 characters in source - files. Patch by Pablo Galindo. - -- bpo-46042: Improve the location of the caret in :exc:`SyntaxError` - exceptions emitted by the symbol table. Patch by Pablo Galindo. - -- bpo-46049: Ensure :file:`._pth` files work as intended on platforms other - than Windows. - -- bpo-46048: Fixes parsing of :file:`._pth` files on startup so that - single-character paths are correctly read. - -- bpo-37971: Fix a bug where the line numbers given in a traceback when a - decorator application raised an exception were wrong. - -- bpo-46031: Add :opcode:`POP_JUMP_IF_NOT_NONE` and - :opcode:`POP_JUMP_IF_NONE` opcodes to speed up conditional jumps. - -- bpo-45654: Deepfreeze :mod:`runpy`, patch by Kumar Aditya. - -- bpo-46025: Fix a crash in the :mod:`atexit` module involving functions - that unregister themselves before raising exceptions. Patch by Pablo - Galindo. - -- bpo-46000: Improve compatibility of the :mod:`curses` module with NetBSD - curses. - -- bpo-44525: Specialize the CALL_FUNCTION instruction for calls to builtin - types with a single argument. Speeds up ``range(x)``, ``list(x)``, and - specifically ``type(obj)``. - -- bpo-42918: Fix bug where the built-in :func:`compile` function did not - always raise a :exc:`SyntaxError` when passed multiple statements in - 'single' mode. Patch by Weipeng Hong. - -- bpo-45953: The main interpreter in _PyRuntimeState.interpreters is now - statically allocated (as part of _PyRuntime). Likewise for the initial - thread state of each interpreter. This means less allocation during - runtime init, as well as better memory locality for these key state - objects. - -- bpo-45292: Complete the :pep:`654` implementation: add ``except*``. - -- bpo-43413: Revert changes in ``set.__init__``. Subclass of :class:`set` - needs to define a ``__init__()`` method if it defines a ``__new__()`` - method with additional keyword parameters. - -- bpo-43931: Added the :c:data:`Py_Version` constant which bears the same - value as :c:macro:`PY_VERSION_HEX`. Patch by Gabriele N. Tornetta. - -Library -------- - -- bpo-46342: The ``@typing.final`` decorator now sets the ``__final__`` - attribute on the decorated object to allow runtime introspection. Patch by - Jelle Zijlstra. - -- bpo-46328: Added the :meth:`sys.exception` method which returns the active - exception instance. - -- bpo-46307: Add :meth:`string.Template.is_valid` and - :meth:`string.Template.get_identifiers` methods. - -- bpo-46306: Assume that :class:`types.CodeType` always has - :attr:`types.CodeType.co_firstlineno` in :mod:`doctest`. - -- bpo-40479: Fix :mod:`hashlib` *usedforsecurity* option to work correctly - with OpenSSL 3.0.0 in FIPS mode. - -- bpo-46070: Fix possible segfault when importing the :mod:`asyncio` module - from different sub-interpreters in parallel. Patch by Erlend E. Aasland. - -- bpo-46244: Removed ``__slots__`` from :class:`typing.ParamSpec` and - :class:`typing.TypeVar`. They served no purpose. Patch by Arie Bovenberg. - -- bpo-46278: Reflect ``context`` argument in ``AbstractEventLoop.call_*()`` - methods. Loop implementations already support it. - -- bpo-46269: Remove special-casing of ``__new__`` in - :meth:`enum.Enum.__dir__`. - -- bpo-46266: Improve day constants in :mod:`calendar`. - - Now all constants (`MONDAY` ... `SUNDAY`) are documented, tested, and - added to ``__all__``. - -- bpo-46257: Optimized the mean, variance, and stdev functions in the - statistics module. If the input is an iterator, it is consumed in a single - pass rather than eating memory by conversion to a list. The single pass - algorithm is about twice as fast as the previous two pass code. - -- bpo-41011: Added two new variables to *pyvenv.cfg* which is generated by - :mod:`venv` module: *executable* for the executable and *command* for the - command line used to create the environment. - -- bpo-46239: Improve error message when importing - :mod:`asyncio.windows_events` on non-Windows. - -- bpo-46238: Reuse ``_winapi`` constants in ``asyncio.windows_events``. - -- bpo-46222: Adding ``SF_NOCACHE`` sendfile constant for FreeBSD for the - posixmodule. - -- bpo-37295: Add fast path for ``0 <= k <= n <= 67`` for :func:`math.comb`. - -- bpo-46176: Adding the ``MAP_STACK`` constant for the mmap module. - -- bpo-43424: Deprecate :attr:`webbrowser.MacOSXOSAScript._name` and use - ``name`` instead. - -- bpo-45321: Added missing error codes to module - ``xml.parsers.expat.errors``. - -- bpo-46125: Refactor tests to test traversable API directly. Includes - changes from importlib 5.4.0. - -- bpo-46118: Moved importlib.resources and its related functionality to a - package. - -- bpo-37578: Add *include_hidden* parameter to :func:`~glob.glob` and - :func:`~glob.iglob` to match hidden files and directories when using - special characters like ``*``, ``**``, ``?`` and ``[]``. - -- bpo-20369: :func:`concurrent.futures.wait` no longer blocks forever when - given duplicate Futures. Patch by Kumar Aditya. - -- bpo-46105: Honor spec when generating requirement specs with urls and - extras (importlib_metadata 4.8.3). - -- bpo-44893: EntryPoint objects are no longer tuples. Recommended means to - access is by attribute ('.name', '.group') or accessor ('.load()'). Access - by index is deprecated and will raise deprecation warning. - -- bpo-22815: Print unexpected successes together with failures and errors in - summary in :class:`unittest.TextTestResult`. - -- bpo-22047: Calling :meth:`add_argument_group` on an argument group is - deprecated. Calling :meth:`add_argument_group` or - :meth:`add_mutually_exclusive_group` on a mutually exclusive group is - deprecated. - - These features were never supported and do not always work correctly. The - functions exist on the API by accident through inheritance and will be - removed in the future. - -- bpo-26952: :mod:`argparse` raises :exc:`ValueError` with clear message - when trying to render usage for an empty mutually exclusive group. - Previously it raised a cryptic :exc:`IndexError`. - -- bpo-45615: Functions in the :mod:`traceback` module raise :exc:`TypeError` - rather than :exc:`AttributeError` when an exception argument is not of - type :exc:`BaseException`. - -- bpo-16594: Add allow allow_reuse_port flag in socketserver. - -- bpo-27718: Fix help for the :mod:`signal` module. Some functions (e.g. - ``signal()`` and ``getsignal()``) were omitted. - -- bpo-46032: The ``registry()`` method of :func:`functools.singledispatch` - functions checks now the first argument or the first parameter annotation - and raises a TypeError if it is not supported. Previously unsupported - "types" were ignored (e.g. ``typing.List[int]``) or caused an error at - calling time (e.g. ``list[int]``). - -- bpo-46014: Add ability to use ``typing.Union`` and ``types.UnionType`` as - dispatch argument to ``functools.singledispatch``. Patch provided by Yurii - Karabas. - -- bpo-27062: Add :attr:`__all__` to :mod:`inspect`, patch by Kumar Aditya. - -- bpo-46018: Ensure that :func:`math.expm1` does not raise on underflow. - -- bpo-46016: Adding :attr:`F_DUP2FD` and :attr:`F_DUP2FD_CLOEXEC` constants - from FreeBSD into the fcntl module. - -- bpo-45755: :mod:`typing` generic aliases now reveal the class attributes - of the original generic class when passed to ``dir()``. This was the - behavior up to Python 3.6, but was changed in 3.7-3.9. - -- bpo-45874: The empty query string, consisting of no query arguments, is - now handled correctly in ``urllib.parse.parse_qsl``. This caused problems - before when strict parsing was enabled. - -- bpo-44674: Change how dataclasses disallows mutable default values. It - used to use a list of known types (list, dict, set). Now it disallows - unhashable objects to be defaults. It's using unhashability as a proxy - for mutability. Patch by Eric V. Smith, idea by Raymond Hettinger. - -- bpo-23882: Remove namespace package (PEP 420) support from unittest - discovery. It was introduced in Python 3.4 but has been broken since - Python 3.7. - -- bpo-25066: Added a :meth:`__repr__` method to - :class:`multiprocessing.Event` objects, patch by Kumar Aditya. - -- bpo-45643: Added :data:`signal.SIGSTKFLT` on platforms where this signal - is defined. - -- bpo-44092: Fetch across rollback no longer raises - :exc:`~sqlite3.InterfaceError`. Instead we leave it to the SQLite library - to handle these cases. Patch by Erlend E. Aasland. - -- bpo-42413: Replace ``concurrent.futures.TimeoutError`` and - ``asyncio.TimeoutError`` with builtin :exc:`TimeoutError`, keep these - names as deprecated aliases. - -Documentation -------------- - -- bpo-46196: Document method :meth:`cmd.Cmd.columnize`. - -- bpo-46120: State that ``|`` is preferred for readability over ``Union`` in - the :mod:`typing` docs. - -- bpo-46109: Extracted ``importlib.resources`` and - ``importlib.resources.abc`` documentation into separate files. - -- bpo-19737: Update the documentation for the :func:`globals` function. - -Tests ------ - -- bpo-46296: Add a test case for :mod:`enum` with ``_use_args_ == True`` and - ``_member_type_ == object``. - -- bpo-46205: Fix hang in runtest_mp due to race condition - -- bpo-46263: Fix test_capi on FreeBSD 14-dev: instruct jemalloc to not fill - freed memory with junk byte. - -- bpo-46262: Cover ``ValueError`` path in tests for - :meth:`enum.Flag._missing_`. - -- bpo-46150: Now ``fakename`` in - ``test_pathlib.PosixPathTest.test_expanduser`` is checked to be - non-existent. - -- bpo-46129: Rewrite ``asyncio.locks`` tests with - :class:`unittest.IsolatedAsyncioTestCase` usage. - -- bpo-23819: Fixed :mod:`asyncio` tests in python optimized mode. Patch by - Kumar Aditya. - -- bpo-46114: Fix test case for OpenSSL 3.0.1 version. OpenSSL 3.0 uses - ``0xMNN00PP0L``. - -Build ------ - -- bpo-44133: When Python is configured with - :option:`--without-static-libpython`, the Python static library - (libpython.a) is no longer built. Patch by Victor Stinner. - -- bpo-44133: When Python is built without :option:`--enable-shared`, the - ``python`` program is now linked to object files, rather than being linked - to the Python static library (libpython.a), to make sure that all symbols - are exported. Previously, the linker omitted some symbols like the - :c:func:`Py_FrozenMain` function. Patch by Victor Stinner. - -- bpo-40280: The ``configure`` script has a new option - ``--with-emscripten-target`` to select browser or node as Emscripten build - target. - -- bpo-46315: Added and fixed ``#ifdef HAVE_FEATURE`` checks for - functionality that is not available on WASI platform. - -- bpo-45723: Fixed a regression in ``configure`` check for - :func:`select.epoll`. - -- bpo-46263: ``configure`` no longer sets ``MULTIARCH`` on FreeBSD - platforms. - -- bpo-46106: Updated OpenSSL to 1.1.1m in Windows builds, macOS installer - builds, and CI. Patch by Kumar Aditya. - -- bpo-46088: Automatically detect or install bootstrap Python runtime when - building from Visual Studio. - -- bpo-46072: Add a --with-pystats configure option to turn on internal - statistics gathering. - -- bpo-40280: A new directory ``Tools/wasm`` contains WebAssembly-related - helpers like ``config.site`` override for wasm32-emscripten, wasm assets - generator to bundle the stdlib, and a README. - -- bpo-46023: :program:`makesetup` no longer builds extensions that have been - marked as *disabled*. This allows users to disable modules in - ``Modules/Setup.local``. - -- bpo-45949: Use pure Python ``freeze_module`` for all but importlib - bootstrap files. ``--with-freeze-module`` :program:`configure` option is - no longer needed for cross builds. - -Windows -------- - -- bpo-46217: Removed parameter that is unsupported on Windows 8.1 and early - Windows 10 and may have caused build or runtime failures. - -macOS ------ - -- bpo-40477: The Python Launcher app for macOS now properly launches scripts - and, if necessary, the Terminal app when running on recent macOS releases. - -C API ------ - -- bpo-46236: Fix a bug in :c:func:`PyFunction_GetAnnotations` that caused it - to return a ``tuple`` instead of a ``dict``. - -- bpo-46140: :c:func:`PyBuffer_GetPointer`, - :c:func:`PyBuffer_FromContiguous`, :c:func:`PyBuffer_ToContiguous` and - :c:func:`PyMemoryView_FromBuffer` now take buffer info by ``const - Py_buffer *`` instead of ``Py_buffer *``, as they do not need mutability. - :c:func:`PyBuffer_FromContiguous` also now takes the source buffer as - ``const void *``, and similarly :c:func:`PyBuffer_GetPointer` takes the - strides as ``const Py_ssize_t *``. - -- bpo-45855: Document that the *no_block* argument to - :c:func:`PyCapsule_Import` is a no-op now. - -- bpo-45855: Replaced deprecated usage of - :c:func:`PyImport_ImportModuleNoBlock` with - :c:func:`PyImport_ImportModule` in stdlib modules. Patch by Kumar Aditya. - -- bpo-46007: The :c:func:`PyUnicode_CHECK_INTERNED` macro has been excluded - from the limited C API. It was never usable there, because it used - internal structures which are not available in the limited C API. Patch by - Victor Stinner. - - -What's New in Python 3.11.0 alpha 3? -==================================== - -*Release date: 2021-12-08* - -Core and Builtins ------------------ - -- bpo-46009: Restore behavior from 3.9 and earlier when sending non-None to - newly started generator. In 3.9 this did not affect the state of the - generator. In 3.10.0 and 3.10.1 ``gen_func().send(0)`` is equivalent to - ``gen_func().throw(TypeError(...)`` which exhausts the generator. In - 3.10.2 onward, the behavior has been reverted to that of 3.9. - -- bpo-46004: Fix the :exc:`SyntaxError` location for errors involving for - loops with invalid targets. Patch by Pablo Galindo - -- bpo-45711: :c:func:`_PyErr_ChainStackItem` no longer normalizes - ``exc_info`` (including setting the traceback on the exception instance) - because ``exc_info`` is always normalized. - -- bpo-45607: The ``__note__`` field was added to :exc:`BaseException`. It is - ``None`` by default but can be set to a string which is added to the - exception's traceback. - -- bpo-45947: Place pointers to dict and values immediately before GC header. - This reduces number of dependent memory loads to access either dict or - values from 3 to 1. - -- bpo-45915: ``is_valid_fd`` now uses faster ``fcntl(fd, F_GETFD)`` on - Linux, macOS, and Windows. - -- bpo-44530: Reverts a change to the ``code.__new__`` :ref:`audit event - <audit-events>` from an earlier prerelease. - -- bpo-42268: Fail the configure step if the selected compiler doesn't - support memory sanitizer. Patch by Pablo Galindo - -- bpo-45711: The three values of ``exc_info`` are now always consistent with - each other. In particular, the ``type`` and ``traceback`` fields are now - derived from the exception instance. This impacts the return values of - :func:`sys.exc_info` and :c:func:`PyErr_GetExcInfo()` if the exception - instance is modified while the exception is handled, as well as - :c:func:`PyErr_SetExcInfo()`, which now ignores the ``type`` and - ``traceback`` arguments provided to it. - -- bpo-45727: Refine the custom syntax error that suggests that a comma may - be missing to trigger only when the expressions are detected between - parentheses or brackets. Patch by Pablo Galindo - -- bpo-45885: Specialized the ``COMPARE_OP`` opcode using the PEP 659 - machinery. - -- bpo-45786: Allocate space for the interpreter frame in the frame object, - to avoid an additional allocation when the frame object outlives the frame - activation. - -- bpo-45614: Fix :mod:`traceback` display for exceptions with invalid module - name. - -- bpo-45813: Fix crash when calling coro.cr_frame.clear() after coroutine - has been freed. - -- bpo-45811: Improve the tokenizer errors when encountering invisible - control characters in the parser. Patch by Pablo Galindo - -- bpo-45848: Allow the parser to obtain error lines directly from encoded - files. Patch by Pablo Galindo - -- bpo-45709: Restore behavior from 3.10 when tracing an exception raised - within a with statement. - -- bpo-44525: Adds new :opcode:`COPY_FREE_VARS` opcode, to make copying of - free variables from function to frame explicit. Helps optimization of - calls to Python function. - -- bpo-45829: Specialize :opcode:`BINARY_SUBSCR` for classes with a - ``__getitem__`` method implemented in Python - -- bpo-45826: Fixed a crash when calling ``.with_traceback(None)`` on - ``NameError``. This occurs internally in - ``unittest.TestCase.assertRaises()``. - -- bpo-45822: Fixed a bug in the parser that was causing it to not respect - :pep:`263` coding cookies when no flags are provided. Patch by Pablo - Galindo - -- bpo-45820: Fix a segfault when the parser fails without reading any input. - Patch by Pablo Galindo - -- bpo-45636: Simplify the implementation of :opcode:`BINARY_OP` by indexing - into an array of function pointers (rather than switching on the oparg). - -- bpo-42540: Fix crash when :func:`os.fork` is called with an active - non-default memory allocator. - -- bpo-45738: Fix computation of error location for invalid continuation - characters in the parser. Patch by Pablo Galindo. - -- bpo-45636: Remove an existing "fast path" for old-style string formatting, - since it no longer appears to have any measurable impact. - -- bpo-45753: Make recursion checks a bit more efficient by tracking amount - of calls left before overflow. - -- bpo-45773: Fix a compiler hang when attempting to optimize certain jump - patterns. - -- bpo-45764: The parser now gives a better error message when leaving out - the opening parenthesis ``(`` after a ``def``-statement:: - - >>> def f: - File "<stdin>", line 1 - def f: - ^ - SyntaxError: expected '(' - -- bpo-45609: Specialized the ``STORE_SUBSCR`` opcode using the PEP 659 - machinery. - -- bpo-45636: Replace all numeric ``BINARY_*`` and ``INPLACE_*`` instructions - with a single :opcode:`BINARY_OP` implementation. - -- bpo-45582: Path calculation (known as ``getpath``) has been reimplemented - as a frozen Python module. This should have no visible impact, but may - affect calculation of all paths referenced in :mod:`sys` and - :mod:`sysconfig`. - -- bpo-45450: Improve the syntax error message for parenthesized arguments. - Patch by Pablo Galindo. - -Library -------- - -- bpo-27946: Fix possible crash when getting an attribute of - class:`xml.etree.ElementTree.Element` simultaneously with replacing the - ``attrib`` dict. - -- bpo-45711: Make :mod:`asyncio` normalize exceptions as soon as they are - captured with :c:func:`PyErr_Fetch`, and before they are stored as an - exc_info triplet. This brings :mod:`asyncio` in line with the rest of the - codebase, where an exc_info triplet is always normalized. - -- bpo-23819: Replaced asserts with exceptions in asyncio, patch by Kumar - Aditya. - -- bpo-13236: :class:`unittest.TextTestResult` and - :class:`unittest.TextTestRunner` flush now the output stream more often. - -- bpo-45917: Added :func:`math.exp2`:, which returns 2 raised to the power - of x. - -- bpo-37658: Fix issue when on certain conditions ``asyncio.wait_for()`` may - allow a coroutine to complete successfully, but fail to return the result, - potentially causing memory leaks or other issues. - -- bpo-45876: Improve the accuracy of stdev() and pstdev() in the statistics - module. When the inputs are floats or fractions, the output is a - correctly rounded float - -- bpo-44649: Handle dataclass(slots=True) with a field that has default a - default value, but for which init=False. - -- bpo-45803: Added missing kw_only parameter to - dataclasses.make_dataclass(). - -- bpo-45837: The :meth:`turtle.RawTurtle.settiltangle` is deprecated since - Python 3.1, it now emits a deprecation warning and will be removed in - Python 3.13. - - Use :meth:`turtle.RawTurtle.tiltangle` instead. - - :meth:`turtle.RawTurtle.tiltangle` was earlier incorrectly marked as - deprecated, its docstring has been corrected. - - Patch by Hugo van Kemenade. - -- bpo-45831: :mod:`faulthandler` can now write ASCII-only strings (like - filenames and function names) with a single write() syscall when dumping a - traceback. It reduces the risk of getting an unreadable dump when two - threads or two processes dump a traceback to the same file (like stderr) - at the same time. Patch by Victor Stinner. - -- bpo-45828: :mod:`sqlite` C callbacks now use unraisable exceptions if - callback tracebacks are enabled. Patch by Erlend E. Aasland. - -- bpo-41735: Fix thread lock in ``zlib.Decompress.flush()`` method before - ``PyObject_GetBuffer``. - -- bpo-45235: Reverted an argparse bugfix that caused regression in the - handling of default arguments for subparsers. This prevented leaf level - arguments from taking precedence over root level arguments. - -- bpo-45754: Fix a regression in Python 3.11a1 and 3.11a2 where - :mod:`sqlite3` incorrectly would use ``SQLITE_LIMIT_LENGTH`` when checking - SQL statement lengths. Now, ``SQLITE_LIMIT_SQL_LENGTH`` is used. Patch by - Erlend E. Aasland. - -- bpo-45766: Added *proportional* option to - :meth:`statistics.linear_regression`. - -- bpo-45765: In importlib.metadata, fix distribution discovery for an empty - path. - -- bpo-45757: Fix bug where :mod:`dis` produced an incorrect oparg when - :opcode:`EXTENDED_ARG` is followed by an opcode that does not use its - argument. - -- bpo-45644: In-place JSON file formatting using ``python3 -m json.tool - infile infile`` now works correctly, previously it left the file empty. - Patch by Chris Wesseling. - -- bpo-45703: When a namespace package is imported before another module from - the same namespace is created/installed in a different :data:`sys.path` - location while the program is running, calling the - :func:`importlib.invalidate_caches` function will now also guarantee the - new module is noticed. - -- bpo-45535: Improve output of ``dir()`` with Enums. - -- bpo-45664: Fix :func:`types.resolve_bases` and :func:`types.new_class` for - :class:`types.GenericAlias` instance as a base. - -- bpo-45663: Fix :func:`dataclasses.is_dataclass` for dataclasses which are - subclasses of :class:`types.GenericAlias`. - -- bpo-45662: Fix the repr of :data:`dataclasses.InitVar` with a type alias - to the built-in class, e.g. ``InitVar[list[int]]``. - -- bpo-43137: Launch GNOME web browsers via gio tool instead of obsolete - gvfs-open - -- bpo-45429: On Windows, :func:`time.sleep` now uses a waitable timer which - supports high-resolution timers. Patch by Dong-hee Na and Eryk Sun. - -- bpo-37295: Optimize :func:`math.comb` and :func:`math.perm`. - -- bpo-45514: Deprecated legacy functions in :mod:`importlib.resources`. - -- bpo-45507: Add tests for truncated/missing trailers in gzip.decompress - implementation. - -- bpo-45359: Implement :pep:`585` for :class:`graphlib.TopologicalSorter`. - -- bpo-44733: Add ``max_tasks_per_child`` to - :class:`concurrent.futures.ProcessPoolExecutor`. This allows users to - specify the maximum number of tasks a single process should execute before - the process needs to be restarted. - -- bpo-28806: Improve netrc library. netrc file no longer needs to contain - all tokens. And if the login name is anonymous, security check is no - longer need. - -- bpo-43498: Avoid a possible *"RuntimeError: dictionary changed size during - iteration"* when adjusting the process count of - :class:`ProcessPoolExecutor`. - -- bpo-42158: Add MIME types for N-quads, N-triples, Notation3 and TriG to - ``mimetypes``. - -- bpo-30533: Add :func:`inspect.getmembers_static` , it return all members - without triggering dynamic lookup via the descriptor protocol. Patch by - Weipeng Hong. - -Documentation -------------- - -- bpo-42238: ``make -C Doc suspicious`` will be removed soon in favor of - ``make -C Doc check``, mark it as deprecated. - -- bpo-45840: Improve cross-references in the documentation for the data - model. - -- bpo-45640: Properly marked-up grammar tokens in the documentation are now - clickable and take you to the definition of a given piece of grammar. - Patch by Arthur Milchior. - -- bpo-45788: Link doc for sys.prefix to sysconfig doc on installation paths. - -- bpo-45772: ``socket.socket`` documentation is corrected to a class from a - function. - -- bpo-45392: Update the docstring of the :class:`type` built-in to remove a - redundant line and to mention keyword arguments for the constructor. - -- bpo-45250: Update the documentation to note that CPython does not - consistently require iterators to define ``__iter__``. - -- bpo-25381: In the extending chapter of the extending doc, update a - paragraph about the global variables containing exception information. - -- bpo-43905: Expanded :func:`~dataclasses.astuple` and - :func:`~dataclasses.asdict` docs, warning about deepcopy being applied and - providing a workaround. - -Tests ------ - -- bpo-45695: Out-of-tree builds with a read-only source directory are now - tested by CI. - -- bpo-19460: Add new Test for - ``Lib/email/mime/nonmultipart.py::MIMENonMultipart``. - -- bpo-45835: Fix race condition in test_queue tests with multiple "feeder" - threads. - -- bpo-45783: The test for the freeze tool now handles file moves and - deletions. - -- bpo-45745: Remove the ``--findleaks`` command line option of regrtest: use - the ``--fail-env-changed`` option instead. Since Python 3.7, it was a - deprecated alias to the ``--fail-env-changed`` option. - -- bpo-45701: Add tests with ``tuple`` type with :func:`functools.lru_cache` - to ``test_functools``. - -Build ------ - -- bpo-44035: CI now verifies that autoconf files have been regenerated with - a current and unpatched autoconf package. - -- bpo-45950: The build system now uses a :program:`_bootstrap_python` - interpreter for freezing and deepfreezing again. To speed up build process - the build tools :program:`_bootstrap_python` and :program:`_freeze_module` - are no longer build with LTO. - -- bpo-45881: The :program:`configure` script now accepts - ``--with-build-python`` and ``--with-freeze-module`` options to make cross - compiling easier. - -- bpo-40280: Emscripten platform now uses ``.wasm`` suffix by default. - -- bpo-40280: Disable unusable core extension modules on WASM/Emscripten - targets. - -- bpo-40280: ``configure`` now checks for socket ``shutdown`` function. The - check makes it possible to disable ``SYS_shutdown`` with - ``ac_cv_func_shutdown=no`` in CONFIG_SITE. - -- bpo-40280: ``configure`` now checks for functions ``fork1, getegid, - geteuid, getgid, getppid, getuid, opendir, pipe, system, wait, ttyname``. - -- bpo-33393: Update ``config.guess`` to 2021-06-03 and ``config.sub`` to - 2021-08-14. ``Makefile`` now has an ``update-config`` target to make - updating more convenient. - -- bpo-45866: ``make regen-all`` now produces the same output when run from a - directory other than the source tree: when building Python out of the - source tree. pegen now strips directory of the "generated by pygen from - <FILENAME>" header Patch by Victor Stinner. - -- bpo-40280: ``configure`` now accepts machine ``wasm32`` or ``wasm64`` and - OS ``wasi`` or ``emscripten`` for cross building, e.g. - ``wasm32-unknown-emscripten``, ``wasm32-wasi``, or - ``wasm32-unknown-wasi``. - -- bpo-41498: Python now compiles on platforms without ``sigset_t``. Several - functions in :mod:`signal` are not available when ``sigset_t`` is missing. - - Based on patch by Roman Yurchak for pyodide. - -- bpo-45881: ``setup.py`` now uses ``CC`` from environment first to discover - multiarch and cross compile paths. - -- bpo-45886: The ``_freeze_module`` program path can now be overridden on - the command line, e.g. ``make - FREEZE_MODULE=../x86_64/Program/_freeze_module``. - -- bpo-45873: Get rid of the ``_bootstrap_python`` build step. The - deepfreeze.py script is now run using ``$(PYTHON_FOR_REGEN)`` which can be - Python 3.7 or newer (on Windows, 3.8 or newer). - -- bpo-45847: Port builtin hashlib extensions to ``PY_STDLIB_MOD`` macro and - ``addext()``. - -- bpo-45723: Add ``autoconf`` helpers for saving and restoring environment - variables: - - * ``SAVE_ENV``: Save ``$CFLAGS``, ``$LDFLAGS``, ``$LIBS``, and - ``$CPPFLAGS``. - * ``RESTORE_ENV``: Restore ``$CFLAGS``, ``$LDFLAGS``, ``$LIBS``, and - ``$CPPFLAGS``. - * ``WITH_SAVE_ENV([SCRIPT])``: Run ``SCRIPT`` wrapped with ``SAVE_ENV`` and - ``RESTORE_ENV``. - - Patch by Erlend E. Aasland. - -- bpo-45573: Mandatory core modules, that are required to bootstrap Python, - are now in ``Modules/Setup.bootstrap``. - -- bpo-45573: ``configure`` now creates ``Modules/Setup.stdlib`` with - conditionally enabled/disabled extension module lines. The file is not - used, yet. - -- bpo-45573: ``configure`` now uses a unified format to set state, compiler - flags, and linker flags in Makefile. The new macro ``PY_STDLIB_MOD`` sets - three variables that are consumed by ``Modules/Setup`` and ``setup.py``. - -- bpo-45816: Python now supports building with Visual Studio 2022 (MSVC - v143, VS Version 17.0). Patch by Jeremiah Vivian. - -- bpo-45800: Settings for :mod:`pyexpat` C extension are now detected by - ``configure``. The bundled ``expat`` library is built in ``Makefile``. - -- bpo-45798: Settings for :mod:`decimal` internal C extension are now - detected by ``configure``. The bundled ``libmpdec`` library is built in - ``Makefile``. - -- bpo-45723: :program:`configure` has a new option ``--with-pkg-config`` to - disable or require pkg-config. - -- bpo-45774: The build dependencies for :mod:`sqlite3` are now detected by - ``configure`` and ``pkg-config``. Patch by Erlend E. Aasland. - -- bpo-45763: The build dependencies for :mod:`zlib`, :mod:`bz2`, and - :mod:`lzma` are now detected by ``configure``. - -- bpo-45747: gdbm and dbm build dependencies are now detected by - ``configure``. - -- bpo-45743: On macOS, the build system no longer passes - ``search_paths_first`` to the linker. The flag has been the default since - Xcode 4 / macOS 10.6. - -- bpo-45723: ``configure.ac`` is now compatible with autoconf 2.71. - Deprecated checks ``STDC_HEADERS`` and ``AC_HEADER_TIME`` have been - removed. - -- bpo-45723: ``configure`` now prints a warning when pkg-config is missing. - -- bpo-45731: ``configure --enable-loadable-sqlite-extensions`` is now - handled by new ``PY_SQLITE_ENABLE_LOAD_EXTENSION`` macro instead of logic - in setup.py. - -- bpo-45723: configure.ac now uses custom helper macros and - ``AC_CACHE_CHECK`` to simplify and speed up configure runs. - -- bpo-45696: Skip the marshal step for frozen modules by generating C code - that produces a set of ready-to-use code objects. This speeds up startup - time by another 10% or more. - -- bpo-45561: Run smelly.py tool from $(srcdir). - -Windows -------- - -- bpo-46105: Fixed calculation of :data:`sys.path` in a venv on Windows. - -- bpo-45901: When installed through the Microsoft Store and set as the - default app for :file:`*.py` files, command line arguments will now be - passed to Python when invoking a script without explicitly launching - Python (that is, ``script.py args`` rather than ``python script.py - args``). - -- bpo-45616: Fix Python Launcher's ability to distinguish between versions - 3.1 and 3.10 when either one is explicitly requested. Previously, 3.1 - would be used if 3.10 was requested but not installed, and 3.10 would be - used if 3.1 was requested but 3.10 was installed. - -- bpo-45850: Implement changes to build with deep-frozen modules on Windows. - Note that we now require Python 3.10 as the "bootstrap" or "host" Python. - -- bpo-45732: Updates bundled Tcl/Tk to 8.6.12. - -- bpo-45720: Internal reference to :file:`shlwapi.dll` was dropped to help - improve startup time. This DLL will no longer be loaded at the start of - every Python process. - -macOS ------ - -- bpo-45732: Update python.org macOS installer to use Tcl/Tk 8.6.12. - -C API ------ - -- bpo-39026: Fix Python.h to build C extensions with Xcode: remove a - relative include from ``Include/cpython/pystate.h``. - - -What's New in Python 3.11.0 alpha 2? -==================================== - -*Release date: 2021-11-05* - -Core and Builtins ------------------ - -- bpo-45716: Improve the :exc:`SyntaxError` message when using ``True``, - ``None`` or ``False`` as keywords in a function call. Patch by Pablo - Galindo. - -- bpo-45688: :data:`sys.stdlib_module_names` now contains the macOS-specific - module :mod:`_scproxy`. - -- bpo-45379: Clarify :exc:`ImportError` message when we try to explicitly - import a frozen module but frozen modules are disabled. - -- bpo-44525: Specialize simple calls to Python functions (no starargs, - keyowrd dict, or closure) - -- bpo-45530: Cases of sorting using tuples as keys may now be significantly - faster in some cases. Patch by Tim Peters. - - The order of the result may differ from earlier releases if the tuple - elements don't define a total ordering (see - :ref:`expressions-value-comparisons` for information on total ordering). - It's generally true that the result of sorting simply isn't well-defined - in the absence of a total ordering on list elements. - -- bpo-45526: In obmalloc, set ADDRESS_BITS to not ignore any bits (ignored - 16 before). That is safer in the case that the kernel gives user-space - virtual addresses that span a range greater than 48 bits. - -- bpo-30570: Fixed a crash in ``issubclass()`` from infinite recursion when - searching pathological ``__bases__`` tuples. - -- bpo-45521: Fix a bug in the obmalloc radix tree code. On 64-bit machines, - the bug causes the tree to hold 46-bits of virtual addresses, rather than - the intended 48-bits. - -- bpo-45494: Fix parser crash when reporting errors involving invalid - continuation characters. Patch by Pablo Galindo. - -- bpo-45445: Python now fails to initialize if it finds an invalid - :option:`-X` option in the command line. Patch by Pablo Galindo. - -- bpo-45340: Object attributes are held in an array instead of a dictionary. - An object's dictionary are created lazily, only when needed. Reduces the - memory consumption of a typical Python object by about 30%. Patch by Mark - Shannon. - -- bpo-45408: Fix a crash in the parser when reporting tokenizer errors that - occur at the same time unclosed parentheses are detected. Patch by Pablo - Galindo. - -- bpo-29410: Add SipHash13 for string hash algorithm and use it by default. - -- bpo-45385: Fix reference leak from descr_check. Patch by Dong-hee Na. - -- bpo-45367: Specialized the ``BINARY_MULTIPLY`` opcode to - ``BINARY_MULTIPLY_INT`` and ``BINARY_MULTIPLY_FLOAT`` using the PEP 659 - machinery. - -- bpo-21736: Frozen stdlib modules now have ``__file__`` to the .py file - they would otherwise be loaded from, if possible. For packages, - ``__path__`` now has the correct entry instead of being an empty list, - which allows unfrozen submodules to be imported. These are set only if - the stdlib directory is known when the runtime is initialized. Note that - the file at ``__file__`` is not guaranteed to exist. None of this affects - non-stdlib frozen modules nor, for now, frozen modules imported using - ``PyImport_ImportFrozenModule()``. Also, at the moment ``co_filename`` is - not updated for the module. - -- bpo-45020: For frozen stdlib modules, record the original module name as - ``module.__spec__.loader_state.origname``. If the value is different than - ``module.__spec__.name`` then the module was defined as an alias in - Tools/scripts/freeze_modules.py. If it is ``None`` then the module comes - from a source file outside the stdlib. - -- bpo-45324: In FrozenImporter.find_spec(), we now preserve the information - needed in exec_module() to load the module. This change mostly impacts - internal details, rather than changing the importer's behavior. - -- bpo-45292: Implement :pep:`654`. Add :class:`ExceptionGroup` and - :class:`BaseExceptionGroup`. Update traceback display code. - -- bpo-40116: Change to the implementation of split dictionaries. Classes - where the instances differ either in the exact set of attributes, or in - the order in which those attributes are set, can still share keys. This - should have no observable effect on users of Python or the C-API. Patch by - Mark Shannon. - -- bpo-44050: Extensions that indicate they use global state (by setting - ``m_size`` to -1) can again be used in multiple interpreters. This reverts - to behavior of Python 3.8. - -- bpo-44525: Setup initial specialization infrastructure for the - ``CALL_FUNCTION`` opcode. Implemented initial specializations for C - function calls: - - * ``CALL_FUNCTION_BUILTIN_O`` for ``METH_O`` flag. - - * ``CALL_FUNCTION_BUILTIN_FAST`` for ``METH_FASTCALL`` flag without keywords. - - * ``CALL_FUNCTION_LEN`` for ``len(o)``. - - * ``CALL_FUNCTION_ISINSTANCE`` for ``isinstance(o, t)``. - -- bpo-44511: Improve the generated bytecode for class and mapping patterns. - -- bpo-43706: Speed up calls to ``enumerate()`` by using the :pep:`590` - ``vectorcall`` calling convention. Patch by Dong-hee Na. - -Library -------- - -- bpo-45679: Fix caching of multi-value :data:`typing.Literal`. - ``Literal[True, 2]`` is no longer equal to ``Literal[1, 2]``. - -- bpo-42064: Convert :mod:`sqlite3` to multi-phase initialisation (PEP 489). - Patches by Erlend E. Aasland. - -- bpo-45438: Fix typing.Signature string representation for generic builtin - types. - -- bpo-45613: :mod:`sqlite3` now sets :attr:`sqlite3.threadsafety` based on - the default threading mode the underlying SQLite library has been compiled - with. Patch by Erlend E. Aasland. - -- bpo-45574: Fix warning about ``print_escape`` being unused. - -- bpo-45581: :meth:`sqlite3.connect` now correctly raises :exc:`MemoryError` - if the underlying SQLite API signals memory error. Patch by Erlend E. - Aasland. - -- bpo-45557: pprint.pprint() now handles underscore_numbers correctly. - Previously it was always setting it to False. - -- bpo-44019: Add :func:`operator.call` to ``operator.__all__``. Patch by - Kreusada. - -- bpo-42174: :meth:`shutil.get_terminal_size` now falls back to sane values - if the column or line count are 0. - -- bpo-35673: Improve the introspectability of the ``__loader__`` attribute - for namespace packages. :class:`importlib.machinery.NamespaceLoader` is - now public, and implements the :class:`importlib.abc.InspectLoader` - interface. ``_NamespaceLoader`` is kept for backward compatibility. - -- bpo-45515: Add references to :mod:`zoneinfo` in the :mod:`datetime` - documentation, mostly replacing outdated references to ``dateutil.tz``. - Change by Paul Ganssle. - -- bpo-45475: Reverted optimization of iterating :class:`gzip.GzipFile`, - :class:`bz2.BZ2File`, and :class:`lzma.LZMAFile` (see bpo-43787) because - it caused regression when user iterate them without having reference of - them. Patch by Inada Naoki. - -- bpo-45489: Update :class:`~typing.ForwardRef` to support ``|`` operator. - Patch by Dong-hee Na. - -- bpo-42222: Removed deprecated support for float arguments in - *randrange()*. - -- bpo-45428: Fix a regression in py_compile when reading filenames from - standard input. - -- bpo-45467: Fix incremental decoder and stream reader in the - "raw-unicode-escape" codec. Previously they failed if the escape sequence - was split. - -- bpo-45461: Fix incremental decoder and stream reader in the - "unicode-escape" codec. Previously they failed if the escape sequence was - split. - -- bpo-45239: Fixed :func:`email.utils.parsedate_tz` crashing with - :exc:`UnboundLocalError` on certain invalid input instead of returning - ``None``. Patch by Ben Hoyt. - -- bpo-45417: Fix quadratic behaviour in the enum module: Creation of enum - classes with a lot of entries was quadratic. - -- bpo-45249: Fix the behaviour of :func:`traceback.print_exc` when - displaying the caret when the ``end_offset`` in the exception is set to 0. - Patch by Pablo Galindo - -- bpo-45416: Fix use of :class:`asyncio.Condition` with explicit - :class:`asyncio.Lock` objects, which was a regression due to removal of - explicit loop arguments. Patch by Joongi Kim. - -- bpo-20028: Empty escapechar/quotechar is not allowed when initializing - :class:`csv.Dialect`. Patch by Vajrasky Kok and Dong-hee Na. - -- bpo-44904: Fix bug in the :mod:`doctest` module that caused it to fail if - a docstring included an example with a ``classmethod`` ``property``. Patch - by Alex Waygood. - -- bpo-45406: Make :func:`inspect.getmodule` catch ``FileNotFoundError`` - raised by :'func:`inspect.getabsfile`, and return ``None`` to indicate - that the module could not be determined. - -- bpo-45411: Add extensions for files containing subtitles - .srt & .vtt - - to the mimetypes.py module. - -- bpo-10716: Migrated pydoc to HTML5 (without changing the look of it). Side - effect is to update xmlrpc's ``ServerHTMLDoc`` which now uses the CSS too. - cgitb now relies less on pydoc (as it can't use the CSS file). - -- bpo-27580: Add support of null characters in :mod:`csv`. - -- bpo-45262: Prevent use-after-free in asyncio. Make sure the cached running - loop holder gets cleared on dealloc to prevent use-after-free in - get_running_loop - -- bpo-45386: Make :mod:`xmlrpc.client` more robust to C runtimes where the - underlying C ``strftime`` function results in a ``ValueError`` when - testing for year formatting options. - -- bpo-20028: Improve error message of :class:`csv.Dialect` when - initializing. Patch by Vajrasky Kok and Dong-hee Na. - -- bpo-45343: Update bundled pip to 21.2.4 and setuptools to 58.1.0 - -- bpo-45328: Fixed :class:`http.client.HTTPConnection` to work properly in - OSs that don't support the ``TCP_NODELAY`` socket option. - -- bpo-45243: Add :meth:`~sqlite3.Connection.setlimit` and - :meth:`~sqlite3.Connection.getlimit` to :class:`sqlite3.Connection` for - setting and getting SQLite limits by connection basis. Patch by Erlend E. - Aasland. - -- bpo-45320: Removed from the :mod:`inspect` module: - - * the ``getargspec`` function, deprecated since Python 3.0; - use :func:`inspect.signature` or :func:`inspect.getfullargspec` instead. - - * the ``formatargspec`` function, deprecated since Python 3.5; - use the :func:`inspect.signature` function and :class:`Signature` object - directly. - - * the undocumented ``Signature.from_callable`` and ``Signature.from_function`` - functions, deprecated since Python 3.5; use the - :meth:`Signature.from_callable() <inspect.Signature.from_callable>` method - instead. - - Patch by Hugo van Kemenade. - -- bpo-45192: Fix the ``tempfile._infer_return_type`` function so that the - ``dir`` argument of the :mod:`tempfile` functions accepts an object - implementing the ``os.PathLike`` protocol. - - Patch by Kyungmin Lee. - -- bpo-45160: When tracing a tkinter variable used by a ttk OptionMenu, - callbacks are no longer made twice. - -- bpo-25625: Added non parallel-safe :func:`~contextlib.chdir` context - manager to change the current working directory and then restore it on - exit. Simple wrapper around :func:`~os.chdir`. - -- bpo-24139: Add support for SQLite extended result codes in - :exc:`sqlite3.Error`. Patch by Erlend E. Aasland. - -- bpo-24444: Fixed an error raised in :mod:`argparse` help display when help - for an option is set to 1+ blank spaces or when *choices* arg is an empty - container. - -- bpo-44547: Implement ``Fraction.__int__``, so that a - :class:`fractions.Fraction` instance ``f`` passes an ``isinstance(f, - typing.SupportsInt)`` check. - -- bpo-40321: Adds support for HTTP 308 redirects to :mod:`urllib`. See - :rfc:`7538` for details. Patch by Jochem Schulenklopper. - -- bpo-41374: Ensure that ``socket.TCP_*`` constants are exposed on Cygwin - 3.1.6 and greater. - -- bpo-35970: Add help flag to the base64 module's command line interface. - Patch contributed by Robert Kuska. - -Documentation -------------- - -- bpo-45726: Improve documentation for :func:`functools.singledispatch` and - :class:`functools.singledispatchmethod`. - -- bpo-45680: Amend the docs on ``GenericAlias`` objects to clarify that - non-container classes can also implement ``__class_getitem__``. Patch - contributed by Alex Waygood. - -- bpo-45618: Update Sphinx version used to build the documentation to 4.2.0. - Patch by Maciej Olko. - -- bpo-45655: Add a new "relevant PEPs" section to the top of the - documentation for the ``typing`` module. Patch by Alex Waygood. - -- bpo-45604: Add ``level`` argument to ``multiprocessing.log_to_stderr`` - function docs. - -- bpo-45516: Add protocol description to the - :class:`importlib.abc.TraversableResources` documentation. - -- bpo-45464: Mention in the documentation of :ref:`Built-in Exceptions - <bltin-exceptions>` that inheriting from multiple exception types in a - single subclass is not recommended due to possible memory layout - incompatibility. - -- bpo-45449: Add note about :pep:`585` in :mod:`collections.abc`. - -- bpo-45516: Add protocol description to the - :class:`importlib.abc.Traversable` documentation. - -- bpo-20692: Add Programming FAQ entry explaining that int literal attribute - access requires either a space after or parentheses around the literal. - -Tests ------ - -- bpo-45678: Add tests for scenarios in which - :class:`functools.singledispatchmethod` is stacked on top of a method that - has already been wrapped by two other decorators. Patch by Alex Waygood. - -- bpo-45578: Add tests for :func:`dis.distb` - -- bpo-45678: Add tests to ensure that ``functools.singledispatchmethod`` - correctly wraps the attributes of the target function. - -- bpo-45668: PGO tests now pass when Python is built without test extension - modules. - -- bpo-45577: Add subtests for all ``pickle`` protocols in ``test_zoneinfo``. - -- bpo-45566: Fix ``test_frozen_pickle`` in ``test_dataclasses`` to check all - ``pickle`` versions. - -- bpo-43592: :mod:`test.libregrtest` now raises the soft resource limit for - the maximum number of file descriptors when the default is too low for our - test suite as was often the case on macOS. - -- bpo-39679: Add more test cases for `@functools.singledispatchmethod` when - combined with `@classmethod` or `@staticmethod`. - -- bpo-45410: When libregrtest spawns a worker process, stderr is now written - into stdout to keep messages order. Use a single pipe for stdout and - stderr, rather than two pipes. Previously, messages were out of order - which made analysis of buildbot logs harder Patch by Victor Stinner. - -- bpo-45402: Fix test_tools.test_sundry() when Python is built out of tree: - fix how the freeze_modules.py tool locates the _freeze_module program. - Patch by Victor Stinner. - -- bpo-45403: Fix test_sys.test_stdlib_dir() when Python is built outside the - source tree: compare normalized paths. Patch by Victor Stinner. - -- bpo-45400: Fix - test_name_error_suggestions_do_not_trigger_for_too_many_locals() of - test_exceptions if a directory name contains "a1" (like - "Python-3.11.0a1"): use a stricter regular expression. Patch by Victor - Stinner. - -- bpo-10572: Rename :mod:`sqlite3` tests from ``test_sqlite`` to - ``test_sqlite3``, and relocate them to ``Lib/test/test_sqlite3``. Patch by - Erlend E. Aasland. - -Build ------ - -- bpo-43158: ``setup.py`` now uses values from configure script to build the - ``_uuid`` extension module. Configure now detects util-linux's - ``libuuid``, too. - -- bpo-45666: Fix warning of ``swprintf`` and ``%s`` usage in - ``_testembed.c`` - -- bpo-45548: ``Modules/Setup`` and ``Modules/makesetup`` have been improved. - The ``Setup`` file now contains working rules for all extensions. Outdated - comments have been removed. Rules defined by ``makesetup`` track - dependencies correctly. - -- bpo-45548: The :mod:`math` and :mod:`cmath` implementation now require a - C99 compatible ``libm`` and no longer ship with workarounds for missing - acosh, asinh, atanh, expm1, and log1p functions. - -- bpo-45595: ``setup.py`` and ``makesetup`` now track build dependencies on - all Python header files and module specific header files. - -- bpo-45571: ``Modules/Setup`` now use ``PY_CFLAGS_NODIST`` instead of - ``PY_CFLAGS`` to compile shared modules. - -- bpo-45570: :mod:`pyexpat` and :mod:`_elementtree` no longer define - obsolete macros ``HAVE_EXPAT_CONFIG_H`` and ``USE_PYEXPAT_CAPI``. - ``XML_POOR_ENTROPY`` is now defined in ``expat_config.h``. - -- bpo-43974: ``setup.py`` no longer defines ``Py_BUILD_CORE_MODULE``. - Instead every module, that uses the internal API, defines the macro. - -- bpo-45548: Fill in missing entries in Modules/Setup. - -- bpo-45532: Update :data:`sys.version` to use ``main`` as fallback - information. Patch by Jeong YunWon. - -- bpo-45536: The ``configure`` script now checks whether OpenSSL headers and - libraries provide required APIs. Most common APIs are verified. The check - detects outdated or missing OpenSSL. Failures do not stop configure. - -- bpo-45221: Fixed regression in handling of ``LDFLAGS`` and ``CPPFLAGS`` - options where :meth:`argparse.parse_known_args` could interpret an option - as one of the built-in command line argument, for example ``-h`` for help. - -- bpo-45440: Building Python now requires a C99 ``<math.h>`` header file - providing the following functions: ``copysign()``, ``hypot()``, - ``isfinite()``, ``isinf()``, ``isnan()``, ``round()``. Patch by Victor - Stinner. - -- bpo-45405: Prevent ``internal configure error`` when running ``configure`` - with recent versions of non-Apple clang. Patch by David Bohman. - -- bpo-45433: Avoid linking libpython with libcrypt. - -Windows -------- - -- bpo-43652: Update Tcl/Tk to 8.6.11, actually this time. The previous - update incorrectly included 8.6.10. - -- bpo-45337: venv now warns when the created environment may need to be - accessed at a different path, due to redirections, links or junctions. It - also now correctly installs or upgrades components when the alternate path - is required. - -- bpo-43851: Build SQLite ``SQLITE_OMIT_AUTOINIT`` on Windows. Patch by - Erlend E. Aasland. - -macOS ------ - -- bpo-44828: Avoid tkinter file dialog failure on macOS 12 Monterey when - using the Tk 8.6.11 provided by python.org macOS installers. Patch by Marc - Culler of the Tk project. - -IDLE ----- - -- bpo-45495: Add context keywords 'case' and 'match' to completions list. - -C API ------ - -- bpo-29103: :c:func:`PyType_FromSpec* <PyType_FromModuleAndSpec>` now - copies the class name from the spec to a buffer owned by the class, so the - original can be safely deallocated. Patch by Petr Viktorin. - -- bpo-45522: The internal freelists for frame, float, list, dict, async - generators, and context objects can now be disabled. - -- bpo-35134: Exclude :c:func:`PyWeakref_GET_OBJECT` from the limited C API. - It never worked since the :c:type:`PyWeakReference` structure is opaque in - the limited C API. - -- bpo-35081: Move the ``interpreteridobject.h`` header file from - ``Include/`` to ``Include/internal/``. It only provides private functions. - Patch by Victor Stinner. - -- bpo-35134: The non-limited API files ``cellobject.h``, ``classobject.h``, - ``context.h``, ``funcobject.h``, ``genobject.h`` and ``longintrepr.h`` - have been moved to the ``Include/cpython`` directory. Moreover, the - ``eval.h`` header file was removed. These files must not be included - directly, as they are already included in ``Python.h``: :ref:`Include - Files <api-includes>`. If they have been included directly, consider - including ``Python.h`` instead. Patch by Victor Stinner. - -- bpo-45474: The following items are no longer available when - ``Py_LIMITED_API`` is defined: - - * :c:func:`PyMarshal_WriteLongToFile` - * :c:func:`PyMarshal_WriteObjectToFile` - * :c:func:`PyMarshal_ReadObjectFromString` - * :c:func:`PyMarshal_WriteObjectToString` - * the ``Py_MARSHAL_VERSION`` macro - - These are not part of the :ref:`limited API <stable-abi-list>`. - - Patch by Victor Stinner. - -- bpo-45434: Remove the ``pystrhex.h`` header file. It only contains private - functions. C extensions should only include the main ``<Python.h>`` header - file. Patch by Victor Stinner. - -- bpo-45440: Remove the ``Py_FORCE_DOUBLE()`` macro. It was used by the - ``Py_IS_INFINITY()`` macro. Patch by Victor Stinner. - -- bpo-45434: ``<Python.h>`` no longer includes the header files - ``<stdlib.h>``, ``<stdio.h>``, ``<errno.h>`` and ``<string.h>`` when the - ``Py_LIMITED_API`` macro is set to ``0x030b0000`` (Python 3.11) or higher. - C extensions should explicitly include the header files after ``#include - <Python.h>``. Patch by Victor Stinner. - -- bpo-41123: Remove ``Py_UNICODE_COPY()`` and ``Py_UNICODE_FILL()`` macros, - deprecated since Python 3.3. Use ``PyUnicode_CopyCharacters()`` or - ``memcpy()`` (``wchar_t*`` string), and ``PyUnicode_Fill()`` functions - instead. Patch by Victor Stinner. - -- bpo-45412: Remove the following math macros using the ``errno`` variable: - - * ``Py_ADJUST_ERANGE1()`` - * ``Py_ADJUST_ERANGE2()`` - * ``Py_OVERFLOWED()`` - * ``Py_SET_ERANGE_IF_OVERFLOW()`` - * ``Py_SET_ERRNO_ON_MATH_ERROR()`` - - Patch by Victor Stinner. - -- bpo-45395: Custom frozen modules (the array set to - ``PyImport_FrozenModules``) are now treated as additions, rather than - replacing all the default frozen modules. Frozen stdlib modules can still - be disabled by setting the "code" field of the custom array entry to NULL. - -- bpo-43760: Add new :c:func:`PyThreadState_EnterTracing`, and - :c:func:`PyThreadState_LeaveTracing` functions to the limited C API to - suspend and resume tracing and profiling. Patch by Victor Stinner. - -- bpo-44220: :c:var:`PyStructSequence_UnnamedField` is added to the Stable - ABI. - - -What's New in Python 3.11.0 alpha 1? -==================================== - -*Release date: 2021-10-05* - -Security --------- - -- bpo-42278: Replaced usage of :func:`tempfile.mktemp` with - :class:`~tempfile.TemporaryDirectory` to avoid a potential race condition. - -- bpo-44600: Fix incorrect line numbers while tracing some failed patterns - in :ref:`match <match>` statements. Patch by Charles Burkland. - -- bpo-41180: Add auditing events to the :mod:`marshal` module, and stop - raising ``code.__init__`` events for every unmarshalled code object. - Directly instantiated code objects will continue to raise an event, and - audit event handlers should inspect or collect the raw marshal data. This - reduces a significant performance overhead when loading from ``.pyc`` - files. - -- bpo-44394: Update the vendored copy of libexpat to 2.4.1 (from 2.2.8) to - get the fix for the CVE-2013-0340 "Billion Laughs" vulnerability. This - copy is most used on Windows and macOS. - -- bpo-43124: Made the internal ``putcmd`` function in :mod:`smtplib` - sanitize input for presence of ``\r`` and ``\n`` characters to avoid - (unlikely) command injection. - -- bpo-44022: :mod:`http.client` now avoids infinitely reading potential HTTP - headers after a ``100 Continue`` status response from the server. - -Core and Builtins ------------------ - -- bpo-43760: The number of hardware branches per instruction dispatch is - reduced from two to one by adding a special instruction for tracing. Patch - by Mark Shannon. - -- bpo-45061: Add a deallocator to the bool type to detect refcount bugs in C - extensions which call Py_DECREF(Py_True) or Py_DECREF(Py_False) by - mistake. Detect also refcount bugs when the empty tuple singleton or the - Unicode empty string singleton is destroyed by mistake. Patch by Victor - Stinner. - -- bpo-24076: sum() was further optimised for summing up single digit - integers. - -- bpo-45190: Update Unicode databases to Unicode 14.0.0. - -- bpo-45167: Fix deepcopying of :class:`types.GenericAlias` objects. - -- bpo-45155: :meth:`int.to_bytes` and :meth:`int.from_bytes` now take a - default value of ``"big"`` for the ``byteorder`` argument. - :meth:`int.to_bytes` also takes a default value of ``1`` for the - ``length`` argument. - -- bpo-44219: Release the GIL while performing ``isatty`` system calls on - arbitrary file descriptors. In particular, this affects :func:`os.isatty`, - :func:`os.device_encoding` and :class:`io.TextIOWrapper`. By extension, - :func:`io.open` in text mode is also affected. This change solves a - deadlock in :func:`os.isatty`. Patch by Vincent Michel in :issue:`44219`. - -- bpo-44959: Added fallback to extension modules with '.sl' suffix on HP-UX - -- bpo-45121: Fix issue where ``Protocol.__init__`` raises ``RecursionError`` - when it's called directly or via ``super()``. Patch provided by Yurii - Karabas. - -- bpo-44348: The deallocator function of the :exc:`BaseException` type now - uses the trashcan mechanism to prevent stack overflow. For example, when a - :exc:`RecursionError` instance is raised, it can be linked to another - RecursionError through the ``__context__`` attribute or the - ``__traceback__`` attribute, and then a chain of exceptions is created. - When the chain is destroyed, nested deallocator function calls can crash - with a stack overflow if the chain is too long compared to the available - stack memory. Patch by Victor Stinner. - -- bpo-45123: Fix PyAiter_Check to only check for the __anext__ presence (not - for __aiter__). Rename PyAiter_Check to PyAIter_Check, PyObject_GetAiter - -> PyObject_GetAIter. - -- bpo-1514420: Interpreter no longer attempts to open files with names in - angle brackets (like "<string>" or "<stdin>") when formatting an - exception. - -- bpo-41031: Match C and Python code formatting of unprintable exceptions - and exceptions in the :mod:`__main__` module. - -- bpo-37330: :func:`open`, :func:`io.open`, :func:`codecs.open` and - :class:`fileinput.FileInput` no longer accept ``'U'`` ("universal - newline") in the file mode. This flag was deprecated since Python 3.3. - Patch by Victor Stinner. - -- bpo-45083: When the interpreter renders an exception, its name now has a - complete qualname. Previously only the class name was concatenated to the - module name, which sometimes resulted in an incorrect full name being - displayed. - - (This issue impacted only the C code exception rendering, the - :mod:`traceback` module was using qualname already). - -- bpo-34561: List sorting now uses the merge-ordering strategy from Munro - and Wild's ``powersort()``. Unlike the former strategy, this is provably - near-optimal in the entropy of the distribution of run lengths. Most uses - of ``list.sort()`` probably won't see a significant time difference, but - may see significant improvements in cases where the former strategy was - exceptionally poor. However, as these are all fast linear-time - approximations to a problem that's inherently at best quadratic-time to - solve truly optimally, it's also possible to contrive cases where the - former strategy did better. - -- bpo-45056: Compiler now removes trailing unused constants from co_consts. - -- bpo-45020: Add a new command line option, "-X frozen_modules=[on|off]" to - opt out of (or into) using optional frozen modules. This defaults to "on" - (or "off" if it's running out of the source tree). - -- bpo-45012: In :mod:`posix`, release GIL during ``stat()``, ``lstat()``, - and ``fstatat()`` syscalls made by :func:`os.DirEntry.stat`. Patch by - Stanisław Skonieczny. - -- bpo-45018: Fixed pickling of range iterators that iterated for over - ``2**32`` times. - -- bpo-45000: A :exc:`SyntaxError` is now raised when trying to delete - :const:`__debug__`. Patch by Dong-hee Na. - -- bpo-44963: Implement ``send()`` and ``throw()`` methods for - ``anext_awaitable`` objects. Patch by Pablo Galindo. - -- bpo-44962: Fix a race in WeakKeyDictionary, WeakValueDictionary and - WeakSet when two threads attempt to commit the last pending removal. This - fixes asyncio.create_task and fixes a data loss in asyncio.run where - shutdown_asyncgens is not run - -- bpo-24234: Implement the :meth:`__bytes__` special method on the - :class:`bytes` type, so a bytes object ``b`` passes an ``isinstance(b, - typing.SupportsBytes)`` check. - -- bpo-24234: Implement the :meth:`__complex__` special method on the - :class:`complex` type, so a complex number ``z`` passes an ``isinstance(z, - typing.SupportsComplex)`` check. - -- bpo-44954: Fixed a corner case bug where the result of - ``float.fromhex('0x.8p-1074')`` was rounded the wrong way. - -- bpo-44947: Refine the syntax error for trailing commas in import - statements. Patch by Pablo Galindo. - -- bpo-44945: Specialize the BINARY_ADD instruction using the PEP 659 - machinery. Adds five new instructions: - - * BINARY_ADD_ADAPTIVE - * BINARY_ADD_FLOAT - * BINARY_ADD_INT - * BINARY_ADD_UNICODE - * BINARY_ADD_UNICODE_INPLACE_FAST - -- bpo-44929: Fix some edge cases of ``enum.Flag`` string representation in - the REPL. Patch by Pablo Galindo. - -- bpo-44914: Class version tags are no longer recycled. - - This means that a version tag serves as a unique identifier for the state - of a class. We rely on this for effective specialization of the LOAD_ATTR - and other instructions. - -- bpo-44698: Restore behaviour of complex exponentiation with integer-valued - exponent of type :class:`float` or :class:`complex`. - -- bpo-44895: A debug variable :envvar:`PYTHONDUMPREFSFILE` is added for - creating a dump file which is generated by :option:`--with-trace-refs`. - Patch by Dong-hee Na. - -- bpo-44900: Add five superinstructions for PEP 659 quickening: - - * LOAD_FAST LOAD_FAST - * STORE_FAST LOAD_FAST - * LOAD_FAST LOAD_CONST - * LOAD_CONST LOAD_FAST - * STORE_FAST STORE_FAST - -- bpo-44889: Initial implementation of adaptive specialization of - ``LOAD_METHOD``. The following specialized forms were added: - - * ``LOAD_METHOD_CACHED`` - - * ``LOAD_METHOD_MODULE`` - - * ``LOAD_METHOD_CLASS`` - -- bpo-44890: Specialization stats are always collected in debug builds. - -- bpo-44885: Correct the ast locations of f-strings with format specs and - repeated expressions. Patch by Pablo Galindo - -- bpo-44878: Remove the loop from the bytecode interpreter. All instructions - end with a DISPATCH macro, so the loop is now redundant. - -- bpo-44878: Remove switch statement for interpreter loop when using - computed gotos. This makes sure that we only have one dispatch table in - the interpreter. - -- bpo-44874: Deprecate the old trashcan macros - (``Py_TRASHCAN_SAFE_BEGIN``/``Py_TRASHCAN_SAFE_END``). They should be - replaced by the new macros ``Py_TRASHCAN_BEGIN`` and ``Py_TRASHCAN_END``. - -- bpo-44872: Use new trashcan macros (Py_TRASHCAN_BEGIN/END) in - frameobject.c instead of the old ones (Py_TRASHCAN_SAFE_BEGIN/END). - -- bpo-33930: Fix segmentation fault with deep recursion when cleaning method - objects. Patch by Augusto Goulart and Pablo Galindo. - -- bpo-25782: Fix bug where ``PyErr_SetObject`` hangs when the current - exception has a cycle in its context chain. - -- bpo-44856: Fix reference leaks in the error paths of ``update_bases()`` - and ``__build_class__``. Patch by Pablo Galindo. - -- bpo-44826: Initial implementation of adaptive specialization of STORE_ATTR - - Three specialized forms of STORE_ATTR are added: - - * STORE_ATTR_SLOT - - * STORE_ATTR_SPLIT_KEYS - - * STORE_ATTR_WITH_HINT - -- bpo-44838: Fixed a bug that was causing the parser to raise an incorrect - custom :exc:`SyntaxError` for invalid 'if' expressions. Patch by Pablo - Galindo. - -- bpo-44821: Create instance dictionaries (__dict__) eagerly, to improve - regularity of object layout and assist specialization. - -- bpo-44792: Improve syntax errors for if expressions. Patch by Miguel Brito - -- bpo-34013: Generalize the invalid legacy statement custom error message - (like the one generated when "print" is called without parentheses) to - include more generic expressions. Patch by Pablo Galindo - -- bpo-44732: Rename ``types.Union`` to ``types.UnionType``. - -- bpo-44725: Expose specialization stats in python via - :func:`_opcode.get_specialization_stats`. - -- bpo-44717: Improve AttributeError on circular imports of submodules. - -- bpo-44698: Fix undefined behaviour in complex object exponentiation. - -- bpo-44653: Support :mod:`typing` types in parameter substitution in the - union type. - -- bpo-44676: Add ability to serialise ``types.Union`` objects. Patch - provided by Yurii Karabas. - -- bpo-44633: Parameter substitution of the union type with wrong types now - raises ``TypeError`` instead of returning ``NotImplemented``. - -- bpo-44661: Update ``property_descr_set`` to use vectorcall if possible. - Patch by Dong-hee Na. - -- bpo-44662: Add ``__module__`` to ``types.Union``. This also fixes - ``types.Union`` issues with ``typing.Annotated``. Patch provided by Yurii - Karabas. - -- bpo-44655: Include the name of the type in unset __slots__ attribute - errors. Patch by Pablo Galindo - -- bpo-44655: Don't include a missing attribute with the same name as the - failing one when offering suggestions for missing attributes. Patch by - Pablo Galindo - -- bpo-44646: Fix the hash of the union type: it no longer depends on the - order of arguments. - -- bpo-44636: Collapse union of equal types. E.g. the result of ``int | int`` - is now ``int``. Fix comparison of the union type with non-hashable - objects. E.g. ``int | str == {}`` no longer raises a TypeError. - -- bpo-44611: On Windows, :func:`os.urandom`: uses BCryptGenRandom API - instead of CryptGenRandom API which is deprecated from Microsoft Windows - API. Patch by Dong-hee Na. - -- bpo-44635: Convert ``None`` to ``type(None)`` in the union type - constructor. - -- bpo-26280: Implement adaptive specialization for BINARY_SUBSCR - - Three specialized forms of BINARY_SUBSCR are added: - - * BINARY_SUBSCR_LIST_INT - - * BINARY_SUBSCR_TUPLE_INT - - * BINARY_SUBSCR_DICT - -- bpo-44589: Mapping patterns in ``match`` statements with two or more equal - literal keys will now raise a :exc:`SyntaxError` at compile-time. - -- bpo-44606: Fix ``__instancecheck__`` and ``__subclasscheck__`` for the - union type. - -- bpo-42073: The ``@classmethod`` decorator can now wrap other - classmethod-like descriptors. - -- bpo-41972: Tuned the string-searching algorithm of fastsearch.h to have a - shorter inner loop for most cases. - -- bpo-44590: All necessary data for executing a Python function (local - variables, stack, etc) is now kept in a per-thread stack. Frame objects - are lazily allocated on demand. This increases performance by about 7% on - the standard benchmark suite. Introspection and debugging are unaffected - as frame objects are always available when needed. Patch by Mark Shannon. - -- bpo-44584: The threading debug (:envvar:`PYTHONTHREADDEBUG` environment - variable) is deprecated in Python 3.10 and will be removed in Python 3.12. - This feature requires a debug build of Python. Patch by Victor Stinner. - -- bpo-43895: An obsolete internal cache of shared object file handles added - in 1995 that attempted, but did not guarantee, that a .so would not be - dlopen'ed twice to work around flaws in mid-1990s posix-ish operating - systems has been removed from dynload_shlib.c. - -- bpo-44490: :mod:`typing` now searches for type parameters in - ``types.Union`` objects. ``get_type_hints`` will also properly resolve - annotations with nested ``types.Union`` objects. Patch provided by Yurii - Karabas. - -- bpo-43950: Code objects can now provide the column information for - instructions when available. This is levaraged during traceback printing - to show the expressions responsible for errors. - - Contributed by Pablo Galindo, Batuhan Taskaya and Ammar Askar as part of - :pep:`657`. - -- bpo-44562: Remove uses of :c:func:`PyObject_GC_Del` in error path when - initializing :class:`types.GenericAlias`. - -- bpo-41486: Fix a memory consumption and copying performance regression in - earlier 3.10 beta releases if someone used an output buffer larger than - 4GiB with zlib.decompress on input data that expands that large. - -- bpo-43908: Heap types with the :const:`Py_TPFLAGS_IMMUTABLETYPE` flag can - now inherit the :pep:`590` vectorcall protocol. Previously, this was only - possible for :ref:`static types <static-types>`. Patch by Erlend E. - Aasland. - -- bpo-44553: Implement GC methods for ``types.Union`` to break reference - cycles and prevent memory leaks. - -- bpo-44490: Add ``__parameters__`` attribute and ``__getitem__`` operator - to ``types.Union``. Patch provided by Yurii Karabas. - -- bpo-44523: Remove the pass-through for :func:`hash` of - :class:`weakref.proxy` objects to prevent unintended consequences when the - original referred object dies while the proxy is part of a hashable - object. Patch by Pablo Galindo. - -- bpo-44483: Fix a crash in ``types.Union`` objects when creating a union of - an object with bad ``__module__`` field. - -- bpo-44486: Modules will always have a dictionary, even when created by - ``types.ModuleType.__new__()`` - -- bpo-44472: Fix ltrace functionality when exceptions are raised. Patch by - Pablo Galindo - -- bpo-12022: A :exc:`TypeError` is now raised instead of an - :exc:`AttributeError` in :keyword:`with` and :keyword:`async with` - statements for objects which do not support the :term:`context manager` or - :term:`asynchronous context manager` protocols correspondingly. - -- bpo-44297: Make sure that the line number is set when entering a - comprehension scope. Ensures that backtraces inclusing generator - expressions show the correct line number. - -- bpo-44456: Improve the syntax error when mixing positional and keyword - patterns. Patch by Pablo Galindo. - -- bpo-44409: Fix error location information for tokenizer errors raised on - initialization of the tokenizer. Patch by Pablo Galindo. - -- bpo-44396: Fix a possible crash in the tokenizer when raising syntax - errors for unclosed strings. Patch by Pablo Galindo. - -- bpo-44376: Exact integer exponentiation (like ``i**2`` or ``pow(i, 2)``) - with a small exponent is much faster, due to reducing overhead in such - cases. - -- bpo-44313: Directly imported objects and modules (through import and from - import statements) don't generate ``LOAD_METHOD``/``CALL_METHOD`` for - directly accessed objects on their namespace. They now use the regular - ``LOAD_ATTR``/``CALL_FUNCTION``. - -- bpo-44338: Implement adaptive specialization for LOAD_GLOBAL - - Two specialized forms of LOAD_GLOBAL are added: - - * LOAD_GLOBAL_MODULE - - * LOAD_GLOBAL_BUILTIN - -- bpo-44368: Improve syntax errors for invalid "as" targets. Patch by Pablo - Galindo - -- bpo-44349: Fix an edge case when displaying text from files with encoding - in syntax errors. Patch by Pablo Galindo. - -- bpo-44337: Initial implementation of adaptive specialization of LOAD_ATTR - - Four specialized forms of LOAD_ATTR are added: - - * LOAD_ATTR_SLOT - - * LOAD_ATTR_SPLIT_KEYS - - * LOAD_ATTR_WITH_HINT - - * LOAD_ATTR_MODULE - -- bpo-44335: Fix a regression when identifying incorrect characters in - syntax errors. Patch by Pablo Galindo - -- bpo-43693: Computation of the offsets of cell variables is done in the - compiler instead of at runtime. This reduces the overhead of handling cell - and free variables, especially in the case where a variable is both an - argument and cell variable. - -- bpo-44317: Improve tokenizer error with improved locations. Patch by Pablo - Galindo. - -- bpo-44304: Fix a crash in the :mod:`sqlite3` module that happened when the - garbage collector clears :class:`sqlite.Statement` objects. Patch by Pablo - Galindo - -- bpo-44305: Improve error message for ``try`` blocks without ``except`` or - ``finally`` blocks. Patch by Pablo Galindo. - -- bpo-43413: Constructors of subclasses of some builtin classes (e.g. - :class:`tuple`, :class:`list`, :class:`frozenset`) no longer accept - arbitrary keyword arguments. [reverted in 3.11a4] Subclass of :class:`set` - can now define a ``__new__()`` method with additional keyword parameters - without overriding also ``__init__()``. - -- bpo-43667: Improve Unicode support in non-UTF locales on Oracle Solaris. - This issue does not affect other Solaris systems. - -- bpo-43693: A new opcode MAKE_CELL has been added that effectively moves - some of the work done on function entry into the compiler and into the - eval loop. In addition to creating the required cell objects, the new - opcode converts relevant arguments (and other locals) to cell variables on - function entry. - -- bpo-44232: Fix a regression in :func:`type` when a metaclass raises an - exception. The C function :c:func:`type_new` must properly report the - exception when a metaclass constructor raises an exception and the winner - class is not the metaclass. Patch by Victor Stinner. - -- bpo-44201: Avoid side effects of checking for specialized syntax errors in - the REPL that was causing it to ask for extra tokens after a syntax error - had been detected. Patch by Pablo Galindo - -- bpo-43693: ``PyCodeObject`` gained ``co_fastlocalnames`` and - ``co_fastlocalkinds`` as the authoritative source of fast locals info. - Marshaled code objects have changed accordingly. - -- bpo-44184: Fix a crash at Python exit when a deallocator function removes - the last strong reference to a heap type. Patch by Victor Stinner. - -- bpo-44187: Implement quickening in the interpreter. This offers no - advantages as yet, but is an enabler of future optimizations. See PEP 659 - for full explanation. - -- bpo-44180: The parser doesn't report generic syntax errors that happen in - a position further away that the one it reached in the first pass. Patch - by Pablo Galindo - -- bpo-44168: Fix error message in the parser involving keyword arguments - with invalid expressions. Patch by Pablo Galindo - -- bpo-44156: String caches in ``compile.c`` are now subinterpreter - compatible. - -- bpo-44143: Fixed a crash in the parser that manifest when raising - tokenizer errors when an existing exception was present. Patch by Pablo - Galindo. - -- bpo-44032: Move 'fast' locals and other variables from the frame object to - a per-thread datastack. - -- bpo-44114: Fix incorrect dictkeys_reversed and dictitems_reversed function - signatures in C code, which broke webassembly builds. - -- bpo-44110: Improve :func:`str.__getitem__` error message - -- bpo-26110: Add ``CALL_METHOD_KW`` opcode to speed up method calls with - keyword arguments. Idea originated from PyPy. A side effect is executing - ``CALL_METHOD`` is now branchless in the evaluation loop. - -- bpo-28307: Compiler now optimizes simple C-style formatting with literal - format containing only format codes %s, %r and %a by converting them to - f-string expressions. - -- bpo-43149: Correct the syntax error message regarding multiple exception - types to not refer to "exception groups". Patch by Pablo Galindo - -- bpo-43822: The parser will prioritize tokenizer errors over custom syntax - errors when raising exceptions. Patch by Pablo Galindo. - -- bpo-40222: "Zero cost" exception handling. - - * Uses a lookup table to determine how to handle exceptions. - * Removes SETUP_FINALLY and POP_TOP block instructions, eliminating the runtime overhead of try statements. - * Reduces the size of the frame object by about 60%. - - Patch by Mark Shannon - -- bpo-43918: Document the signature and ``default`` argument in the - docstring of the new ``anext`` builtin. - -- bpo-43833: Emit a deprecation warning if the numeric literal is - immediately followed by one of keywords: and, else, for, if, in, is, or. - Raise a syntax error with more informative message if it is immediately - followed by other keyword or identifier. - -- bpo-43879: Add native_thread_id to PyThreadState. Patch by Gabriele N. - Tornetta. - -- bpo-43693: Compute cell offsets relative to locals in compiler. Allows the - interpreter to treats locals and cells a single array, which is slightly - more efficient. Also make the LOAD_CLOSURE opcode an alias for LOAD_FAST. - Preserving LOAD_CLOSURE helps keep bytecode a bit more readable. - -- bpo-17792: More accurate error messages for access of unbound locals or - free vars. - -- bpo-28146: Fix a confusing error message in :func:`str.format`. - -- bpo-11105: When compiling :class:`ast.AST` objects with recursive - references through :func:`compile`, the interpreter doesn't crash anymore - instead it raises a :exc:`RecursionError`. - -- bpo-39091: Fix crash when using passing a non-exception to a generator's - ``throw()`` method. Patch by Noah Oxer - -- bpo-33346: Asynchronous comprehensions are now allowed inside - comprehensions in asynchronous functions. Outer comprehensions implicitly - become asynchronous. - -Library -------- - -- bpo-45371: Fix clang rpath issue in :mod:`distutils`. The UnixCCompiler - now uses correct clang option to add a runtime library directory (rpath) - to a shared library. - -- bpo-45329: Fix freed memory access in :class:`pyexpat.xmlparser` when - building it with an installed expat library <= 2.2.0. - -- bpo-41710: On Unix, if the ``sem_clockwait()`` function is available in - the C library (glibc 2.30 and newer), the :meth:`threading.Lock.acquire` - method now uses the monotonic clock (:data:`time.CLOCK_MONOTONIC`) for the - timeout, rather than using the system clock (:data:`time.CLOCK_REALTIME`), - to not be affected by system clock changes. Patch by Victor Stinner. - -- bpo-1596321: Fix the :func:`threading._shutdown` function when the - :mod:`threading` module was imported first from a thread different than - the main thread: no longer log an error at Python exit. - -- bpo-45274: Fix a race condition in the :meth:`Thread.join() - <threading.Thread.join>` method of the :mod:`threading` module. If the - function is interrupted by a signal and the signal handler raises an - exception, make sure that the thread remains in a consistent state to - prevent a deadlock. Patch by Victor Stinner. - -- bpo-21302: In Unix operating systems, :func:`time.sleep` now uses the - ``nanosleep()`` function, if ``clock_nanosleep()`` is not available but - ``nanosleep()`` is available. ``nanosleep()`` allows to sleep with - nanosecond precision. - -- bpo-21302: On Windows, :func:`time.sleep` now uses a waitable timer which - has a resolution of 100 nanoseconds (10\ :sup:`-7` seconds). Previously, - it had a resolution of 1 millisecond (10\ :sup:`-3` seconds). Patch by - Benjamin Szőke and Victor Stinner. - -- bpo-45238: Fix :meth:`unittest.IsolatedAsyncioTestCase.debug`: it runs now - asynchronous methods and callbacks. - -- bpo-36674: :meth:`unittest.TestCase.debug` raises now a - :class:`unittest.SkipTest` if the class or the test method are decorated - with the skipping decorator. - -- bpo-45235: Fix an issue where argparse would not preserve values in a - provided namespace when using a subparser with defaults. - -- bpo-45183: Have zipimport.zipimporter.find_spec() not raise an exception - when the underlying zip file has been deleted and the internal cache has - been reset via invalidate_cache(). - -- bpo-45234: Fixed a regression in :func:`~shutil.copyfile`, - :func:`~shutil.copy`, :func:`~shutil.copy2` raising - :exc:`FileNotFoundError` when source is a directory, which should raise - :exc:`IsADirectoryError` - -- bpo-45228: Fix stack buffer overflow in parsing J1939 network address. - -- bpo-45225: use map function instead of genexpr in capwords. - -- bpo-42135: Fix typo: ``importlib.find_loader`` is really slated for - removal in Python 3.12 not 3.10, like the others in PR 25169. - - Patch by Hugo van Kemenade. - -- bpo-20524: Improves error messages on ``.format()`` operation for ``str``, - ``float``, ``int``, and ``complex``. New format now shows the problematic - pattern and the object type. - -- bpo-45168: Change :func:`dis.dis` output to omit op arg values that cannot - be resolved due to ``co_consts``, ``co_names`` etc not being provided. - Previously the oparg itself was repeated in the value field, which is not - useful and can be confusing. - -- bpo-21302: In Unix operating systems, :func:`time.sleep` now uses the - ``clock_nanosleep()`` function, if available, which allows to sleep for an - interval specified with nanosecond precision. - -- bpo-45173: Remove from the :mod:`configparser` module: the - :class:`SafeConfigParser` class, the :attr:`filename` property of the - :class:`ParsingError` class, the :meth:`readfp` method of the - :class:`ConfigParser` class, deprecated since Python 3.2. - - Patch by Hugo van Kemenade. - -- bpo-44987: Pure ASCII strings are now normalized in constant time by - :func:`unicodedata.normalize`. Patch by Dong-hee Na. - -- bpo-35474: Calling :func:`mimetypes.guess_all_extensions` with - ``strict=False`` no longer affects the result of the following call with - ``strict=True``. Also, mutating the returned list no longer affects the - global state. - -- bpo-45166: :func:`typing.get_type_hints` now works with - :data:`~typing.Final` wrapped in :class:`~typing.ForwardRef`. - -- bpo-45162: Remove many old deprecated :mod:`unittest` features: - - * "``fail*``" and "``assert*``" aliases of :class:`~unittest.TestCase` methods. - * Broken from start :class:`~unittest.TestCase` method ``assertDictContainsSubset()``. - * Ignored :meth:`<unittest.TestLoader.loadTestsFromModule> TestLoader.loadTestsFromModule` parameter *use_load_tests*. - * Old alias ``_TextTestResult`` of :class:`~unittest.TextTestResult`. - -- bpo-38371: Remove the deprecated ``split()`` method of - :class:`_tkinter.TkappType`. Patch by Erlend E. Aasland. - -- bpo-20499: Improve the speed and accuracy of statistics.pvariance(). - -- bpo-45132: Remove :meth:`__getitem__` methods of - :class:`xml.dom.pulldom.DOMEventStream`, :class:`wsgiref.util.FileWrapper` - and :class:`fileinput.FileInput`, deprecated since Python 3.9. - - Patch by Hugo van Kemenade. - -- bpo-45129: Due to significant security concerns, the *reuse_address* - parameter of :meth:`asyncio.loop.create_datagram_endpoint`, disabled in - Python 3.9, is now entirely removed. This is because of the behavior of - the socket option ``SO_REUSEADDR`` in UDP. - - Patch by Hugo van Kemenade. - -- bpo-45124: The ``bdist_msi`` command, deprecated in Python 3.9, is now - removed. - - Use ``bdist_wheel`` (wheel packages) instead. - - Patch by Hugo van Kemenade. - -- bpo-30856: :class:`unittest.TestResult` methods - :meth:`~unittest.TestResult.addFailure`, - :meth:`~unittest.TestResult.addError`, - :meth:`~unittest.TestResult.addSkip` and - :meth:`~unittest.TestResult.addSubTest` are now called immediately after - raising an exception in test or finishing a subtest. Previously they were - called only after finishing the test clean up. - -- bpo-45034: Changes how error is formatted for ``struct.pack`` with ``'H'`` - and ``'h'`` modes and too large / small numbers. Now it shows the actual - numeric limits, while previously it was showing arithmetic expressions. - -- bpo-25894: :mod:`unittest` now always reports skipped and failed subtests - separately: separate characters in default mode and separate lines in - verbose mode. Also the test description is now output for errors in test - method, class and module cleanups. - -- bpo-45081: Fix issue when dataclasses that inherit from - ``typing.Protocol`` subclasses have wrong ``__init__``. Patch provided by - Yurii Karabas. - -- bpo-45085: The ``binhex`` module, deprecated in Python 3.9, is now - removed. The following :mod:`binascii` functions, deprecated in Python - 3.9, are now also removed: - - * ``a2b_hqx()``, ``b2a_hqx()``; - * ``rlecode_hqx()``, ``rledecode_hqx()``. - - The :func:`binascii.crc_hqx` function remains available. - - Patch by Victor Stinner. - -- bpo-40360: The :mod:`lib2to3` package is now deprecated and may not be - able to parse Python 3.10 or newer. See the :pep:`617` (New PEG parser for - CPython). Patch by Victor Stinner. - -- bpo-45075: Rename :meth:`traceback.StackSummary.format_frame` to - :meth:`traceback.StackSummary.format_frame_summary`. This method was added - for 3.11 so it was not released yet. - - Updated code and docs to better distinguish frame and FrameSummary. - -- bpo-31299: Add option to completely drop frames from a traceback by - returning ``None`` from a :meth:`~traceback.StackSummary.format_frame` - override. - -- bpo-41620: :meth:`~unittest.TestCase.run` now always return a - :class:`~unittest.TestResult` instance. Previously it returned ``None`` if - the test class or method was decorated with a skipping decorator. - -- bpo-45021: Fix a potential deadlock at shutdown of forked children when - using :mod:`concurrent.futures` module - -- bpo-43913: Fix bugs in cleaning up classes and modules in :mod:`unittest`: - - * Functions registered with :func:`~unittest.addModuleCleanup` were not called unless the user defines ``tearDownModule()`` in their test module. - * Functions registered with :meth:`~unittest.TestCase.addClassCleanup` were not called if ``tearDownClass`` is set to ``None``. - * Buffering in :class:`~unittest.TestResult` did not work with functions registered with ``addClassCleanup()`` and ``addModuleCleanup()``. - * Errors in functions registered with ``addClassCleanup()`` and ``addModuleCleanup()`` were not handled correctly in buffered and debug modes. - * Errors in ``setUpModule()`` and functions registered with ``addModuleCleanup()`` were reported in wrong order. - * And several lesser bugs. - -- bpo-45030: Fix integer overflow in pickling and copying the range - iterator. - -- bpo-45001: Made email date parsing more robust against malformed input, - namely a whitespace-only ``Date:`` header. Patch by Wouter Bolsterlee. - -- bpo-45010: Remove support of special method ``__div__`` in - :mod:`unittest.mock`. It is not used in Python 3. - -- bpo-39218: Improve accuracy of variance calculations by using ``x*x`` - instead of ``x**2``. - -- bpo-43613: Improve the speed of :func:`gzip.compress` and - :func:`gzip.decompress` by compressing and decompressing at once in memory - instead of in a streamed fashion. - -- bpo-37596: Ensure that :class:`set` and :class:`frozenset` objects are - always :mod:`marshalled <marshal>` reproducibly. - -- bpo-44019: A new function ``operator.call`` has been added, such that - ``operator.call(obj, *args, **kwargs) == obj(*args, **kwargs)``. - -- bpo-42255: :class:`webbrowser.MacOSX` is deprecated and will be removed in - Python 3.13. It is untested and undocumented and also not used by - webbrowser itself. Patch by Dong-hee Na. - -- bpo-44955: Method :meth:`~unittest.TestResult.stopTestRun` is now always - called in pair with method :meth:`~unittest.TestResult.startTestRun` for - :class:`~unittest.TestResult` objects implicitly created in - :meth:`~unittest.TestCase.run`. Previously it was not called for test - methods and classes decorated with a skipping decorator. - -- bpo-39039: tarfile.open raises :exc:`~tarfile.ReadError` when a zlib error - occurs during file extraction. - -- bpo-44935: :mod:`subprocess` on Solaris now also uses - :func:`os.posix_spawn()` for better performance. - -- bpo-44911: :class:`~unittest.IsolatedAsyncioTestCase` will no longer throw - an exception while cancelling leaked tasks. Patch by Bar Harel. - -- bpo-41322: Added ``DeprecationWarning`` for tests and async tests that - return a value!=None (as this may indicate an improperly written test, for - example a test written as a generator function). - -- bpo-44524: Make exception message more useful when subclass from typing - special form alias. Patch provided by Yurii Karabas. - -- bpo-38956: :class:`argparse.BooleanOptionalAction`'s default value is no - longer printed twice when used with - :class:`argparse.ArgumentDefaultsHelpFormatter`. - -- bpo-44860: Fix the ``posix_user`` scheme in :mod:`sysconfig` to not depend - on :data:`sys.platlibdir`. - -- bpo-44859: Improve error handling in :mod:`sqlite3` and raise more - accurate exceptions. - - * :exc:`MemoryError` is now raised instead of :exc:`sqlite3.Warning` when memory is not enough for encoding a statement to UTF-8 in ``Connection.__call__()`` and ``Cursor.execute()``. - * :exc:`UnicodEncodeError` is now raised instead of :exc:`sqlite3.Warning` when the statement contains surrogate characters in ``Connection.__call__()`` and ``Cursor.execute()``. - * :exc:`TypeError` is now raised instead of :exc:`ValueError` for non-string script argument in ``Cursor.executescript()``. - * :exc:`ValueError` is now raised for script containing the null character instead of truncating it in ``Cursor.executescript()``. - * Correctly handle exceptions raised when getting boolean value of the result of the progress handler. - * Add many tests covering different corner cases. - -- bpo-44581: Upgrade bundled pip to 21.2.3 and setuptools to 57.4.0 - -- bpo-44849: Fix the :func:`os.set_inheritable` function on FreeBSD 14 for - file descriptor opened with the :data:`~os.O_PATH` flag: ignore the - :data:`~errno.EBADF` error on ``ioctl()``, fallback on the ``fcntl()`` - implementation. Patch by Victor Stinner. - -- bpo-44605: The @functools.total_ordering() decorator now works with - metaclasses. - -- bpo-44524: Fixed an issue wherein the ``__name__`` and ``__qualname__`` - attributes of subscribed specialforms could be ``None``. - -- bpo-44839: :class:`MemoryError` raised in user-defined functions will now - produce a ``MemoryError`` in :mod:`sqlite3`. :class:`OverflowError` will - now be converted to :class:`~sqlite3.DataError`. Previously - :class:`~sqlite3.OperationalError` was produced in these cases. - -- bpo-44822: :mod:`sqlite3` user-defined functions and aggregators returning - :class:`strings <str>` with embedded NUL characters are no longer - truncated. Patch by Erlend E. Aasland. - -- bpo-44801: Ensure that the :class:`~typing.ParamSpec` variable in Callable - can only be substituted with a parameters expression (a list of types, an - ellipsis, ParamSpec or Concatenate). - -- bpo-44806: Non-protocol subclasses of :class:`typing.Protocol` ignore now - the ``__init__`` method inherited from protocol base classes. - -- bpo-27275: :meth:`collections.OrderedDict.popitem` and - :meth:`collections.OrderedDict.pop` no longer call ``__getitem__`` and - ``__delitem__`` methods of the OrderedDict subclasses. - -- bpo-44793: Fix checking the number of arguments when subscribe a generic - type with ``ParamSpec`` parameter. - -- bpo-44784: In importlib.metadata tests, override warnings behavior under - expected DeprecationWarnings (importlib_metadata 4.6.3). - -- bpo-44667: The :func:`tokenize.tokenize` doesn't incorrectly generate a - ``NEWLINE`` token if the source doesn't end with a new line character but - the last line is a comment, as the function is already generating a ``NL`` - token. Patch by Pablo Galindo - -- bpo-44771: Added ``importlib.simple`` module implementing adapters from a - low-level resources reader interface to a ``TraversableResources`` - interface. Legacy API (``path``, ``contents``, ...) is now supported - entirely by the ``.files()`` API with a compatibility shim supplied for - resource loaders without that functionality. Feature parity with - ``importlib_resources`` 5.2. - -- bpo-44752: :mod:`rcompleter` does not call :func:`getattr` on - :class:`property` objects to avoid the side-effect of evaluating the - corresponding method. - -- bpo-44747: Refactor usage of ``sys._getframe`` in ``typing`` module. Patch - provided by Yurii Karabas. - -- bpo-42378: Fixes the issue with log file being overwritten when - :class:`logging.FileHandler` is used in :mod:`atexit` with *filemode* set - to ``'w'``. Note this will cause the message in *atexit* not being logged - if the log stream is already closed due to shutdown of logging. - -- bpo-44720: ``weakref.proxy`` objects referencing non-iterators now raise - ``TypeError`` rather than dereferencing the null ``tp_iternext`` slot and - crashing. - -- bpo-44704: The implementation of ``collections.abc.Set._hash()`` now - matches that of ``frozenset.__hash__()``. - -- bpo-44666: Fixed issue in :func:`compileall.compile_file` when - ``sys.stdout`` is redirected. Patch by Stefan Hölzl. - -- bpo-44688: :meth:`sqlite3.Connection.create_collation` now accepts - non-ASCII collation names. Patch by Erlend E. Aasland. - -- bpo-44690: Adopt *binacii.a2b_base64*'s strict mode in *base64.b64decode*. - -- bpo-42854: Fixed a bug in the :mod:`_ssl` module that was throwing - :exc:`OverflowError` when using :meth:`_ssl._SSLSocket.write` and - :meth:`_ssl._SSLSocket.read` for a big value of the ``len`` parameter. - Patch by Pablo Galindo - -- bpo-44686: Replace ``unittest.mock._importer`` with - ``pkgutil.resolve_name``. - -- bpo-44353: Make ``NewType.__call__`` faster by implementing it in C. Patch - provided by Yurii Karabas. - -- bpo-44682: Change the :mod:`pdb` *commands* directive to disallow setting - commands for an invalid breakpoint and to display an appropriate error. - -- bpo-44353: Refactor ``typing.NewType`` from function into callable class. - Patch provided by Yurii Karabas. - -- bpo-44678: Added a separate error message for discontinuous padding in - *binascii.a2b_base64* strict mode. - -- bpo-44524: Add missing ``__name__`` and ``__qualname__`` attributes to - ``typing`` module classes. Patch provided by Yurii Karabas. - -- bpo-40897: Give priority to using the current class constructor in - :func:`inspect.signature`. Patch by Weipeng Hong. - -- bpo-44638: Add a reference to the zipp project and hint as to how to use - it. - -- bpo-44648: Fixed wrong error being thrown by :func:`inspect.getsource` - when examining a class in the interactive session. Instead of - :exc:`TypeError`, it should be :exc:`OSError` with appropriate error - message. - -- bpo-44608: Fix memory leak in :func:`_tkinter._flatten` if it is called - with a sequence or set, but not list or tuple. - -- bpo-44594: Fix an edge case of :class:`ExitStack` and - :class:`AsyncExitStack` exception chaining. They will now match ``with`` - block behavior when ``__context__`` is explicitly set to ``None`` when the - exception is in flight. - -- bpo-42799: In :mod:`fnmatch`, the cache size for compiled regex patterns - (:func:`functools.lru_cache`) was bumped up from 256 to 32768, affecting - functions: :func:`fnmatch.fnmatch`, :func:`fnmatch.fnmatchcase`, - :func:`fnmatch.filter`. - -- bpo-41928: Update :func:`shutil.copyfile` to raise - :exc:`FileNotFoundError` instead of confusing :exc:`IsADirectoryError` - when a path ending with a :const:`os.path.sep` does not exist; - :func:`shutil.copy` and :func:`shutil.copy2` are also affected. - -- bpo-44569: Added the :func:`StackSummary.format_frame` function in - :mod:`traceback`. This allows users to customize the way individual lines - are formatted in tracebacks without re-implementing logic to handle - recursive tracebacks. - -- bpo-44566: handle StopIteration subclass raised from - @contextlib.contextmanager generator - -- bpo-44558: Make the implementation consistency of - :func:`~operator.indexOf` between C and Python versions. Patch by Dong-hee - Na. - -- bpo-41249: Fixes ``TypedDict`` to work with ``typing.get_type_hints()`` - and postponed evaluation of annotations across modules. - -- bpo-44554: Refactor argument processing in :func:`pdb.main` to simplify - detection of errors in input loading and clarify behavior around module or - script invocation. - -- bpo-34798: Break up paragraph about :class:`pprint.PrettyPrinter` - construction parameters to make it easier to read. - -- bpo-44539: Added support for recognizing JPEG files without JFIF or Exif - markers. - -- bpo-44461: Fix bug with :mod:`pdb`'s handling of import error due to a - package which does not have a ``__main__`` module - -- bpo-43625: Fix a bug in the detection of CSV file headers by - :meth:`csv.Sniffer.has_header` and improve documentation of same. - -- bpo-44516: Update vendored pip to 21.1.3 - -- bpo-42892: Fixed an exception thrown while parsing a malformed multipart - email by :class:`email.message.EmailMessage`. - -- bpo-44468: :func:`typing.get_type_hints` now finds annotations in classes - and base classes with unexpected ``__module__``. Previously, it skipped - those MRO elements. - -- bpo-44491: Allow clearing the :mod:`sqlite3` authorizer callback by - passing :const:`None` to :meth:`~sqlite3.Connection.set_authorizer`. Patch - by Erlend E. Aasland. - -- bpo-43977: Set the proper :const:`Py_TPFLAGS_MAPPING` and - :const:`Py_TPFLAGS_SEQUENCE` flags for subclasses created before a parent - has been registered as a :class:`collections.abc.Mapping` or - :class:`collections.abc.Sequence`. - -- bpo-44482: Fix very unlikely resource leak in :mod:`glob` in alternate - Python implementations. - -- bpo-44466: The :mod:`faulthandler` module now detects if a fatal error - occurs during a garbage collector collection. Patch by Victor Stinner. - -- bpo-44471: A :exc:`TypeError` is now raised instead of an - :exc:`AttributeError` in :meth:`contextlib.ExitStack.enter_context` and - :meth:`contextlib.AsyncExitStack.enter_async_context` for objects which do - not support the :term:`context manager` or :term:`asynchronous context - manager` protocols correspondingly. - -- bpo-44404: :mod:`tkinter`'s ``after()`` method now supports callables - without the ``__name__`` attribute. - -- bpo-41546: Make :mod:`pprint` (like the builtin ``print``) not attempt to - write to ``stdout`` when it is ``None``. - -- bpo-44458: ``BUFFER_BLOCK_SIZE`` is now declared static, to avoid linking - collisions when bz2, lmza or zlib are statically linked. - -- bpo-44464: Remove exception for flake8 in deprecated importlib.metadata - interfaces. Sync with importlib_metadata 4.6. - -- bpo-44446: Take into account that ``lineno`` might be ``None`` in - :class:`traceback.FrameSummary`. - -- bpo-44439: Fix in :meth:`bz2.BZ2File.write` / :meth:`lzma.LZMAFile.write` - methods, when the input data is an object that supports the buffer - protocol, the file length may be wrong. - -- bpo-44434: _thread.start_new_thread() no longer calls - PyThread_exit_thread() explicitly at the thread exit, the call was - redundant. On Linux with the glibc, pthread_exit() aborts the whole - process if dlopen() fails to open libgcc_s.so file (ex: EMFILE error). - Patch by Victor Stinner. - -- bpo-42972: The _thread.RLock type now fully implement the GC protocol: add - a traverse function and the :const:`Py_TPFLAGS_HAVE_GC` flag. Patch by - Victor Stinner. - -- bpo-44422: The :func:`threading.enumerate` function now uses a reentrant - lock to prevent a hang on reentrant call. Patch by Victor Stinner. - -- bpo-38291: Importing typing.io or typing.re now prints a - ``DeprecationWarning``. - -- bpo-37880: argparse actions store_const and append_const each receive a - default value of None when the ``const`` kwarg is not provided. - Previously, this raised a :exc:`TypeError`. - -- bpo-44389: Fix deprecation of :data:`ssl.OP_NO_TLSv1_3` - -- bpo-27827: :meth:`pathlib.PureWindowsPath.is_reserved` now identifies a - greater range of reserved filenames, including those with trailing spaces - or colons. - -- bpo-44395: Fix :meth:`~email.message.MIMEPart.as_string` to pass unixfrom - properly. Patch by Dong-hee Na. - -- bpo-34266: Handle exceptions from parsing the arg of :mod:`pdb`'s - run/restart command. - -- bpo-44362: Improve :mod:`ssl` module's deprecation messages, error - reporting, and documentation for deprecations. - -- bpo-44342: [Enum] Change pickling from by-value to by-name. - -- bpo-44356: [Enum] Allow multiple data-type mixins if they are all the - same. - -- bpo-44351: Restore back :func:`parse_makefile` in - :mod:`distutils.sysconfig` because it behaves differently than the similar - implementation in :mod:`sysconfig`. - -- bpo-35800: :class:`smtpd.MailmanProxy` is now removed as it is unusable - without an external module, ``mailman``. Patch by Dong-hee Na. - -- bpo-44357: Added a function that returns cube root of the given number - :func:`math.cbrt` - -- bpo-44339: Change ``math.pow(±0.0, -math.inf)`` to return ``inf`` instead - of raising ``ValueError``. This brings the special-case handling of - ``math.pow`` into compliance with the IEEE 754 standard. - -- bpo-44242: Remove missing flag check from Enum creation and move into a - ``verify`` decorator. - -- bpo-44246: In ``importlib.metadata``, restore compatibility in the result - from ``Distribution.entry_points`` (``EntryPoints``) to honor expectations - in older implementations and issuing deprecation warnings for these cases: - A. ``EntryPoints`` objects are once again mutable, allowing for - ``sort()`` and other list-based mutation operations. Avoid deprecation - warnings by casting to a mutable sequence (e.g. - ``list(dist.entry_points).sort()``). B. ``EntryPoints`` results once again - allow for access by index. To avoid deprecation warnings, cast the - result to a Sequence first (e.g. ``tuple(dist.entry_points)[0]``). - -- bpo-44246: In importlib.metadata.entry_points, de-duplication of - distributions no longer requires loading the full metadata for - PathDistribution objects, improving entry point loading performance by - ~10x. - -- bpo-43858: Added a function that returns a copy of a dict of logging - levels: :func:`logging.getLevelNamesMapping` - -- bpo-44260: The :class:`random.Random` constructor no longer reads system - entropy without need. - -- bpo-44254: On Mac, give turtledemo button text a color that works on both - light or dark background. Programmers cannot control the latter. - -- bpo-44258: Support PEP 515 for Fraction's initialization from string. - -- bpo-44235: Remove deprecated functions in the :mod:`gettext`. Patch by - Dong-hee Na. - -- bpo-38693: Prefer f-strings to ``.format`` in importlib.resources. - -- bpo-33693: Importlib.metadata now prefers f-strings to .format. - -- bpo-44241: Incorporate minor tweaks from importlib_metadata 4.1: - SimplePath protocol, support for Metadata 2.2. - -- bpo-43216: Remove the :func:`@asyncio.coroutine <asyncio.coroutine>` - :term:`decorator` enabling legacy generator-based coroutines to be - compatible with async/await code; remove - :class:`asyncio.coroutines.CoroWrapper` used for wrapping legacy coroutine - objects in the debug mode. The decorator has been deprecated since Python - 3.8 and the removal was initially scheduled for Python 3.10. Patch by - Illia Volochii. - -- bpo-44210: Make importlib.metadata._meta.PackageMetadata public. - -- bpo-43643: Declare readers.MultiplexedPath.name as a property per the - spec. - -- bpo-27334: The :mod:`sqlite3` context manager now performs a rollback - (thus releasing the database lock) if commit failed. Patch by Luca Citi - and Erlend E. Aasland. - -- bpo-4928: Documented existing behavior on POSIX: NamedTemporaryFiles are - not deleted when creating process is killed with SIGKILL - -- bpo-44154: Optimize :class:`fractions.Fraction` pickling for large - components. - -- bpo-33433: For IPv4 mapped IPv6 addresses (:rfc:`4291` Section 2.5.5.2), - the :mod:`ipaddress.IPv6Address.is_private` check is deferred to the - mapped IPv4 address. This solves a bug where public mapped IPv4 addresses - were considered private by the IPv6 check. - -- bpo-44150: Add optional *weights* argument to statistics.fmean(). - -- bpo-44142: :func:`ast.unparse` will now drop the redundant parentheses - when tuples used as assignment targets (e.g in for loops). - -- bpo-44145: :mod:`hmac` computations were not releasing the GIL while - calling the OpenSSL ``HMAC_Update`` C API (a new feature in 3.9). This - unintentionally prevented parallel computation as other :mod:`hashlib` - algorithms support. - -- bpo-44095: :class:`zipfile.Path` now supports :attr:`zipfile.Path.stem`, - :attr:`zipfile.Path.suffixes`, and :attr:`zipfile.Path.suffix` attributes. - -- bpo-44077: It's now possible to receive the type of service (ToS), a.k.a. - differentiated services (DS), a.k.a. differentiated services code point - (DSCP) and explicit congestion notification (ECN) IP header fields with - ``socket.IP_RECVTOS``. - -- bpo-37788: Fix a reference leak when a Thread object is never joined. - -- bpo-38908: Subclasses of ``typing.Protocol`` which only have data - variables declared will now raise a ``TypeError`` when checked with - ``isinstance`` unless they are decorated with :func:`runtime_checkable`. - Previously, these checks passed silently. Patch provided by Yurii Karabas. - -- bpo-44098: ``typing.ParamSpec`` will no longer be found in the - ``__parameters__`` of most :mod:`typing` generics except in valid use - locations specified by :pep:`612`. This prevents incorrect usage like - ``typing.List[P][int]``. This change means incorrect usage which may have - passed silently in 3.10 beta 1 and earlier will now error. - -- bpo-44089: Allow subclassing ``csv.Error`` in 3.10 (it was allowed in 3.9 - and earlier but was disallowed in early versions of 3.10). - -- bpo-44081: :func:`ast.unparse` now doesn't use redundant spaces to - separate ``lambda`` and the ``:`` if there are no parameters. - -- bpo-44061: Fix regression in previous release when calling - :func:`pkgutil.iter_modules` with a list of :class:`pathlib.Path` objects - -- bpo-44059: Register the SerenityOS Browser in the :mod:`webbrowser` - module. - -- bpo-36515: The :mod:`hashlib` module no longer does unaligned memory - accesses when compiled for ARM platforms. - -- bpo-40465: Remove random module features deprecated in Python 3.9. - -- bpo-44018: random.seed() no longer mutates bytearray inputs. - -- bpo-38352: Add ``IO``, ``BinaryIO``, ``TextIO``, ``Match``, and - ``Pattern`` to ``typing.__all__``. Patch by Jelle Zijlstra. - -- bpo-44002: :mod:`urllib.parse` now uses :func:`functool.lru_cache` for its - internal URL splitting and quoting caches instead of rolling its own like - its the '90s. - - The undocumented internal :mod:`urllib.parse` ``Quoted`` class API is now - deprecated, for removal in 3.14. - -- bpo-43972: When :class:`http.server.SimpleHTTPRequestHandler` sends a - ``301 (Moved Permanently)`` for a directory path not ending with `/`, add - a ``Content-Length: 0`` header. This improves the behavior for certain - clients. - -- bpo-28528: Fix a bug in :mod:`pdb` where :meth:`~pdb.Pdb.checkline` raises - :exc:`AttributeError` if it is called after :meth:`~pdb.Pdb.reset`. - -- bpo-43853: Improved string handling for :mod:`sqlite3` user-defined - functions and aggregates: - - * It is now possible to pass strings with embedded null characters to UDFs - * Conversion failures now correctly raise :exc:`MemoryError` - - Patch by Erlend E. Aasland. - -- bpo-43666: AIX: `Lib/_aix_support.get_platform()` may fail in an AIX WPAR. - The fileset bos.rte appears to have a builddate in both LPAR and WPAR so - this fileset is queried rather than bos.mp64. To prevent a similar - situation (no builddate in ODM) a value (9988) sufficient for completing a - build is provided. Patch by M Felt. - -- bpo-43650: Fix :exc:`MemoryError` in :func:`shutil.unpack_archive` which - fails inside :func:`shutil._unpack_zipfile` on large files. Patch by Igor - Bolshakov. - -- bpo-43612: :func:`zlib.compress` now accepts a wbits parameter which - allows users to compress data as a raw deflate block without zlib headers - and trailers in one go. Previously this required instantiating a - ``zlib.compressobj``. It also provides a faster alternative to - ``gzip.compress`` when wbits=31 is used. - -- bpo-43392: :func:`importlib._bootstrap._find_and_load` now implements a - two-step check to avoid locking when modules have been already imported - and are ready. This improves performance of repeated calls to - :func:`importlib.import_module` and :func:`importlib.__import__`. - -- bpo-43318: Fix a bug where :mod:`pdb` does not always echo cleared - breakpoints. - -- bpo-43234: Prohibit passing - non-:class:`concurrent.futures.ThreadPoolExecutor` executors to - :meth:`loop.set_default_executor` following a deprecation in Python 3.8. - Patch by Illia Volochii. - -- bpo-43232: Prohibit previously deprecated potentially disruptive - operations on :class:`asyncio.trsock.TransportSocket`. Patch by Illia - Volochii. - -- bpo-30077: Added support for Apple's aifc/sowt pseudo-compression - -- bpo-42971: Add definition of ``errno.EQFULL`` for platforms that define - this constant (such as macOS). - -- bpo-43086: Added a new optional :code:`strict_mode` parameter to - *binascii.a2b_base64*. When :code:`scrict_mode` is set to :code:`True`, - the *a2b_base64* function will accept only valid base64 content. More - details about what "valid base64 content" is, can be found in the - function's documentation. - -- bpo-43024: Improve the help signature of - :func:`traceback.print_exception`, :func:`traceback.format_exception` and - :func:`traceback.format_exception_only`. - -- bpo-33809: Add the :meth:`traceback.TracebackException.print` method which - prints the formatted exception information. - -- bpo-42862: :mod:`sqlite3` now utilizes :meth:`functools.lru_cache` to - implement the connection statement cache. As a small optimisation, the - default statement cache size has been increased from 100 to 128. Patch by - Erlend E. Aasland. - -- bpo-41818: Soumendra Ganguly: add termios.tcgetwinsize(), - termios.tcsetwinsize(). - -- bpo-40497: :meth:`subprocess.check_output` now raises :exc:`ValueError` - when the invalid keyword argument *check* is passed by user code. - Previously such use would fail later with a :exc:`TypeError`. Patch by - Rémi Lapeyre. - -- bpo-37449: ``ensurepip`` now uses ``importlib.resources.files()`` - traversable APIs - -- bpo-40956: Use Argument Clinic in :mod:`sqlite3`. Patches by Erlend E. - Aasland. - -- bpo-41730: ``DeprecationWarning`` is now raised when importing - :mod:`tkinter.tix`, which has been deprecated in documentation since - Python 3.6. - -- bpo-20684: Remove unused ``_signature_get_bound_param`` function from - :mod:`inspect` - by Anthony Sottile. - -- bpo-41402: Fix :meth:`email.message.EmailMessage.set_content` when called - with binary data and ``7bit`` content transfer encoding. - -- bpo-32695: The *compresslevel* and *preset* keyword arguments of - :func:`tarfile.open` are now both documented and tested. - -- bpo-41137: Use utf-8 encoding while reading .pdbrc files. Patch by - Srinivas Reddy Thatiparthy - -- bpo-24391: Improved reprs of :mod:`threading` synchronization objects: - :class:`~threading.Semaphore`, :class:`~threading.BoundedSemaphore`, - :class:`~threading.Event` and :class:`~threading.Barrier`. - -- bpo-5846: Deprecated the following :mod:`unittest` functions, scheduled - for removal in Python 3.13: - - * :func:`~unittest.findTestCases` - * :func:`~unittest.makeSuite` - * :func:`~unittest.getTestCaseNames` - - Use :class:`~unittest.TestLoader` methods instead: - - * :meth:`unittest.TestLoader.loadTestsFromModule` - * :meth:`unittest.TestLoader.loadTestsFromTestCase` - * :meth:`unittest.TestLoader.getTestCaseNames` - - Patch by Erlend E. Aasland. - -- bpo-40563: Support pathlike objects on dbm/shelve. Patch by Hakan Çelik - and Henry-Joseph Audéoud. - -- bpo-34990: Fixed a Y2k38 bug in the compileall module where it would fail - to compile files with a modification time after the year 2038. - -- bpo-39549: Whereas the code for reprlib.Repr had previously used a - hardcoded string value of '...', this PR updates it to use of a - “fillvalue” attribute, whose value defaults to '...' and can be reset in - either individual reprlib.Repr instances or in subclasses thereof. - -- bpo-37022: :mod:`pdb` now displays exceptions from ``repr()`` with its - ``p`` and ``pp`` commands. - -- bpo-38840: Fix ``test___all__`` on platforms lacking a shared memory - implementation. - -- bpo-39359: Add one missing check that the password is a bytes object for - an encrypted zipfile. - -- bpo-38741: :mod:`configparser`: using ']' inside a section header will no - longer cut the section name short at the ']' - -- bpo-38415: Added missing behavior to - :func:`contextlib.asynccontextmanager` to match - :func:`contextlib.contextmanager` so decorated functions can themselves be - decorators. - -- bpo-30256: Pass multiprocessing BaseProxy argument ``manager_owned`` - through AutoProxy. - -- bpo-27513: :func:`email.utils.getaddresses` now accepts - :class:`email.header.Header` objects along with string values. Patch by - Zackery Spytz. - -- bpo-16379: Add SQLite error code and name to :mod:`sqlite3` exceptions. - Patch by Aviv Palivoda, Daniel Shahaf, and Erlend E. Aasland. - -- bpo-26228: pty.spawn no longer hangs on FreeBSD, macOS, and Solaris. - -- bpo-33349: lib2to3 now recognizes async generators everywhere. - -- bpo-29298: Fix ``TypeError`` when required subparsers without ``dest`` do - not receive arguments. Patch by Anthony Sottile. - -Documentation -------------- - -- bpo-45216: Remove extra documentation listing methods in ``difflib``. It - was rendering twice in pydoc and was outdated in some places. - -- bpo-45024: :mod:`collections.abc` documentation has been expanded to - explicitly cover how instance and subclass checks work, with additional - doctest examples and an exhaustive list of ABCs which test membership - purely by presence of the right :term:`special method`\s. Patch by Raymond - Hettinger. - -- bpo-44957: Promote PEP 604 union syntax by using it where possible. Also, - mention ``X | Y`` more prominently in section about ``Union`` and mention - ``X | None`` at all in section about ``Optional``. - -- bpo-16580: Added code equivalents for the :meth:`int.to_bytes` and - :meth:`int.from_bytes` methods, as well as tests ensuring that these code - equivalents are valid. - -- bpo-44903: Removed the othergui.rst file, any references to it, and the - list of GUI frameworks in the FAQ. In their place I've added links to the - Python Wiki `page on GUI frameworks - <https://wiki.python.org/moin/GuiProgramming>`. - -- bpo-33479: Tkinter documentation has been greatly expanded with new - "Architecture" and "Threading model" sections. - -- bpo-36700: :mod:`base64` RFC references were updated to point to - :rfc:`4648`; a section was added to point users to the new "security - considerations" section of the RFC. - -- bpo-44740: Replaced occurrences of uppercase "Web" and "Internet" with - lowercase versions per the 2016 revised Associated Press Style Book. - -- bpo-44693: Update the definition of __future__ in the glossary by - replacing the confusing word "pseudo-module" with a more accurate - description. - -- bpo-35183: Add typical examples to os.path.splitext docs - -- bpo-30511: Clarify that :func:`shutil.make_archive` is not thread-safe due - to reliance on changing the current working directory. - -- bpo-44561: Update of three expired hyperlinks in - Doc/distributing/index.rst: "Project structure", "Building and packaging - the project", and "Uploading the project to the Python Packaging Index". - -- bpo-44651: Delete entry "coercion" in Doc/glossary.rst for its outdated - definition. - -- bpo-42958: Updated the docstring and docs of :func:`filecmp.cmp` to be - more accurate and less confusing especially in respect to *shallow* arg. - -- bpo-44631: Refactored the ``repr()`` code of the ``_Environ`` (os module). - -- bpo-44613: importlib.metadata is no longer provisional. - -- bpo-44558: Match the docstring and python implementation of - :func:`~operator.countOf` to the behavior of its c implementation. - -- bpo-44544: List all kwargs for :func:`textwrap.wrap`, - :func:`textwrap.fill`, and :func:`textwrap.shorten`. Now, there are nav - links to attributes of :class:`TextWrap`, which makes navigation much - easier while minimizing duplication in the documentation. - -- bpo-38062: Clarify that atexit uses equality comparisons internally. - -- bpo-40620: Convert examples in tutorial controlflow.rst section 4.3 to be - interpreter-demo style. - -- bpo-43066: Added a warning to :mod:`zipfile` docs: filename arg with a - leading slash may cause archive to be un-openable on Windows systems. - -- bpo-39452: Rewrote ``Doc/library/__main__.rst``. Broadened scope of the - document to explicitly discuss and differentiate between ``__main__.py`` - in packages versus the ``__name__ == '__main__'`` expression (and the - idioms that surround it). - -- bpo-13814: In the Design FAQ, answer "Why don't generators support the - with statement?" - -- bpo-27752: Documentation of csv.Dialect is more descriptive. - -- bpo-44453: Fix documentation for the return type of - :func:`sysconfig.get_path`. - -- bpo-44392: Added a new section in the C API documentation for types used - in type hinting. Documented ``Py_GenericAlias`` and - ``Py_GenericAliasType``. - -- bpo-38291: Mark ``typing.io`` and ``typing.re`` as deprecated since Python - 3.8 in the documentation. They were never properly supported by type - checkers. - -- bpo-44322: Document that SyntaxError args have a details tuple and that - details are adjusted for errors in f-string field replacement expressions. - -- bpo-42392: Document the deprecation and removal of the ``loop`` parameter - for many functions and classes in :mod:`asyncio`. - -- bpo-44195: Corrected references to ``TraversableResources`` in docs. There - is no ``TraversableReader``. - -- bpo-41963: Document that ``ConfigParser`` strips off comments when reading - configuration files. - -- bpo-44072: Correct where in the numeric ABC hierarchy ``**`` support is - added, i.e., in numbers.Complex, not numbers.Integral. - -- bpo-43558: Add the remark to :mod:`dataclasses` documentation that the - :meth:`__init__` of any base class has to be called in - :meth:`__post_init__`, along with a code example. - -- bpo-44025: Clarify when '_' in match statements is a keyword, and when - not. - -- bpo-41706: Fix docs about how methods like ``__add__`` are invoked when - evaluating operator expressions. - -- bpo-41621: Document that :class:`collections.defaultdict` parameter - ``default_factory`` defaults to None and is positional-only. - -- bpo-41576: document BaseException in favor of bare except - -- bpo-21760: The description for __file__ fixed. Patch by Furkan Onder - -- bpo-39498: Add a "Security Considerations" index which links to standard - library modules that have explicitly documented security considerations. - -- bpo-33479: Remove the unqualified claim that tkinter is threadsafe. It has - not been true for several years and likely never was. An explanation of - what is true may be added later, after more discussion, and possibly after - patching _tkinter.c, - -Tests ------ - -- bpo-40173: Fix :func:`test.support.import_helper.import_fresh_module`. - -- bpo-45280: Add a test case for empty :class:`typing.NamedTuple`. - -- bpo-45269: Cover case when invalid ``markers`` type is supplied to - ``c_make_encoder``. - -- bpo-45128: Fix ``test_multiprocessing_fork`` failure due to - ``test_logging`` and ``sys.modules`` manipulation. - -- bpo-45209: Fix ``UserWarning: resource_tracker`` warning in - ``_test_multiprocessing._TestSharedMemory.test_shared_memory_cleaned_after_process_termination`` - -- bpo-45185: Enables ``TestEnumerations`` test cases in ``test_ssl`` suite. - -- bpo-45195: Fix test_readline.test_nonascii(): sometimes, the newline - character is not written at the end, so don't expect it in the output. - Patch by Victor Stinner. - -- bpo-45156: Fixes infinite loop on :func:`unittest.mock.seal` of mocks - created by :func:`~unittest.create_autospec`. - -- bpo-45125: Improves pickling tests and docs of ``SharedMemory`` and - ``SharableList`` objects. - -- bpo-44860: Update ``test_sysconfig.test_user_similar()`` for the - posix_user scheme: ``platlib`` doesn't use :data:`sys.platlibdir`. Patch - by Victor Stinner. - -- bpo-45052: ``WithProcessesTestSharedMemory.test_shared_memory_basics`` - test was ignored, because ``self.assertEqual(sms.size, sms2.size)`` line - was failing. It is now removed and test is unskipped. - - The main motivation for this line to be removed from the test is that the - ``size`` of ``SharedMemory`` is not ever guaranteed to be the same. It is - decided by the platform. - -- bpo-44895: libregrtest now clears the type cache later to reduce the risk - of false alarm when checking for reference leaks. Previously, the type - cache was cleared too early and libregrtest raised a false alarm about - reference leaks under very specific conditions. Patch by Irit Katriel and - Victor Stinner. - -- bpo-45042: Fixes that test classes decorated with - ``@hashlib_helper.requires_hashdigest`` were skipped all the time. - -- bpo-25130: Add calls of :func:`gc.collect` in tests to support PyPy. - -- bpo-45011: Made tests relying on the :mod:`_asyncio` C extension module - optional to allow running on alternative Python implementations. Patch by - Serhiy Storchaka. - -- bpo-44949: Fix auto history tests of test_readline: sometimes, the newline - character is not written at the end, so don't expect it in the output. - -- bpo-44891: Tests were added to clarify :func:`id` is preserved when ``obj - * 1`` is used on :class:`str` and :class:`bytes` objects. Patch by Nikita - Sobolev. - -- bpo-44852: Add ability to wholesale silence DeprecationWarnings while - running the regression test suite. - -- bpo-40928: Notify users running test_decimal regression tests on macOS of - potential harmless "malloc can't allocate region" messages spewed by - test_decimal. - -- bpo-44734: Fixed floating point precision issue in turtle tests. - -- bpo-44708: Regression tests, when run with -w, are now re-running only the - affected test methods instead of re-running the entire test file. - -- bpo-42095: Added interop tests for Apple plists: generate plist files with - Python plistlib and parse with Apple plutil; and the other way round. - -- bpo-44647: Added a permanent Unicode-valued environment variable to - regression tests to ensure they handle this use case in the future. If - your test environment breaks because of that, report a bug to us, and - temporarily set PYTHONREGRTEST_UNICODE_GUARD=0 in your test environment. - -- bpo-44515: Adjust recently added contextlib tests to avoid assuming the - use of a refcounted GC - -- bpo-44287: Fix asyncio test_popen() of test_windows_utils by using a - longer timeout. Use military grade battle-tested - :data:`test.support.SHORT_TIMEOUT` timeout rather than a hardcoded timeout - of 10 seconds: it's 30 seconds by default, but it is made longer on slow - buildbots. Patch by Victor Stinner. - -- bpo-44451: Reset ``DeprecationWarning`` filters in - ``test.test_importlib.test_metadata_api.APITests.test_entry_points_by_index`` - to avoid ``StopIteration`` error if ``DeprecationWarnings`` are ignored. - -- bpo-44363: Account for address sanitizer in test_capi. test_capi now - passes when run GCC address sanitizer. - -- bpo-44364: Add non integral tests for :func:`math.sqrt` function. - -- bpo-43921: Fix test_ssl.test_wrong_cert_tls13(): use - ``suppress_ragged_eofs=False``, since ``read()`` can raise - :exc:`ssl.SSLEOFError` on Windows. Patch by Victor Stinner. - -- bpo-43921: Fix test_pha_required_nocert() of test_ssl: catch two more EOF - cases (when the ``recv()`` method returns an empty string). Patch by - Victor Stinner. - -- bpo-44131: Add test_frozenmain to test_embed to test the - :c:func:`Py_FrozenMain` C function. Patch by Victor Stinner. - -- bpo-31904: Ignore error string case in test_file_not_exists(). - -- bpo-42083: Add test to check that ``PyStructSequence_NewType`` accepts a - ``PyStructSequence_Desc`` with ``doc`` field set to ``NULL``. - -- bpo-35753: Fix crash in doctest when doctest parses modules that include - unwrappable functions by skipping those functions. - -- bpo-30256: Add test for nested queues when using ``multiprocessing`` - shared objects ``AutoProxy[Queue]`` inside ``ListProxy`` and ``DictProxy`` - -Build ------ - -- bpo-45220: Avoid building with the Windows 11 SDK previews automatically. - This may be overridden by setting the ``DefaultWindowsSDKVersion`` - environment variable before building. - -- bpo-45020: Freeze stdlib modules that are imported during startup. This - provides significant performance improvements to startup. If necessary, - use the previously added "-X frozen_modules=off" commandline option to - force importing the source modules. - -- bpo-45188: Windows builds now regenerate frozen modules as the first part - of the build. Previously the regeneration was later in the build, which - would require it to be restarted if any modules had changed. - -- bpo-45163: Fixes Haiku platform build. - -- bpo-45067: The ncurses function extended_color_content was introduced in - 2017 - - (https://invisible-island.net/ncurses/NEWS.html#index-t20170401). The - - ncurses-devel package in CentOS 7 had a older version ncurses resulted in - compilation error. For compiling ncurses with extended color support, we - verify the version of the ncurses library >= 20170401. - -- bpo-45019: Generate lines in relevant files for frozen modules. Up until - now each of the files had to be edited manually. This change makes it - easier to add to and modify the frozen modules. - -- bpo-44340: Add support for building with clang thin lto via - --with-lto=thin/full. Patch by Dong-hee Na and Brett Holman. - -- bpo-44535: Enable building using a Visual Studio 2022 install on Windows. - -- bpo-43298: Improved error message when building without a Windows SDK - installed. - -- bpo-44381: The Windows build now accepts :envvar:`EnableControlFlowGuard` - set to ``guard`` to enable CFG. - -- bpo-41282: Fix broken ``make install`` that caused standard library - extension modules to be unnecessarily and incorrectly rebuilt during the - install phase of cpython. - -Windows -------- - -- bpo-45375: Fixes an assertion failure due to searching for the standard - library in unnormalised paths. - -- bpo-45022: Update Windows release to include libffi 3.4.2 - -- bpo-45007: Update to OpenSSL 1.1.1l in Windows build - -- bpo-44848: Upgrade Windows installer to use SQLite 3.36.0. - -- bpo-44572: Avoid consuming standard input in the :mod:`platform` module - -- bpo-44582: Accelerate speed of :mod:`mimetypes` initialization using a - native implementation of the registry scan. - -- bpo-41299: Fix 16 milliseconds jitter when using timeouts in - :mod:`threading`, such as with :meth:`threading.Lock.acquire` or - :meth:`threading.Condition.wait`. - -- bpo-42686: Build :mod:`sqlite3` with math functions enabled. Patch by - Erlend E. Aasland. - -- bpo-40263: This is a follow-on bug from - https://bugs.python.org/issue26903. Once that is applied we run into an - off-by-one assertion problem. The assert was not correct. - -macOS ------ - -- bpo-45007: Update macOS installer builds to use OpenSSL 1.1.1l. - -- bpo-34602: When building CPython on macOS with ``./configure - --with-undefined-behavior-sanitizer --with-pydebug``, the stack size is - now quadrupled to allow for the entire test suite to pass. - -- bpo-44848: Update macOS installer to use SQLite 3.36.0. - -- bpo-44689: :meth:`ctypes.util.find_library` now works correctly on macOS - 11 Big Sur even if Python is built on an older version of macOS. - Previously, when built on older macOS systems, ``find_library`` was not - able to find macOS system libraries when running on Big Sur due to - changes in how system libraries are stored. - -- bpo-41972: The framework build's user header path in sysconfig is changed - to add a 'pythonX.Y' component to match distutils's behavior. - -- bpo-43109: Allow --with-lto configure option to work with Apple-supplied - Xcode or Command Line Tools. - -- bpo-34932: Add socket.TCP_KEEPALIVE support for macOS. Patch by Shane - Harvey. - -IDLE ----- - -- bpo-45296: On Windows, change exit/quit message to suggest Ctrl-D, which - works, instead of <Ctrl-Z Return>, which does not work in IDLE. - -- bpo-45193: Make completion boxes appear on Ubuntu again. - -- bpo-40128: Mostly fix completions on macOS when not using tcl/tk 8.6.11 - (as with 3.9). The added update_idletask call should be harmless and - possibly helpful otherwise. - -- bpo-33962: Move the indent space setting from the Font tab to the new - Windows tab. Patch by Mark Roseman and Terry Jan Reedy. - -- bpo-40468: Split the settings dialog General tab into Windows and Shell/ED - tabs. Move help sources, which extend the Help menu, to the Extensions - tab. Make space for new options and shorten the dialog. The latter makes - the dialog better fit small screens. - -- bpo-41611: Avoid uncaught exceptions in - ``AutoCompleteWindow.winconfig_event()``. - -- bpo-41611: Fix IDLE sometimes freezing upon tab-completion on macOS. - -- bpo-44010: Highlight the new :ref:`match <match>` statement's :ref:`soft - keywords <soft-keywords>`: :keyword:`match`, :keyword:`case <match>`, and - :keyword:`_ <wildcard-patterns>`. However, this highlighting is not - perfect and will be incorrect in some rare cases, including some ``_``-s - in ``case`` patterns. - -- bpo-44026: Include interpreter's typo fix suggestions in message line for - NameErrors and AttributeErrors. Patch by E. Paine. - -Tools/Demos ------------ - -- bpo-44786: Fix a warning in regular expression in the c-analyzer script. - -- bpo-44967: pydoc now returns a non-zero status code when a module cannot - be found. - -- bpo-44978: Allow the Argument Clinic tool to handle ``__complex__`` - special methods. - -- bpo-43425: Removed the 'test2to3' demo project that demonstrated using - lib2to3 to support Python 2.x and Python 3.x from a single source in a - distutils package. Patch by Dong-hee Na - -- bpo-44074: Make patchcheck automatically detect the correct base branch - name (previously it was hardcoded to 'master') - -- bpo-20291: Added support for variadic positional parameters in Argument - Clinic. - -C API ------ - -- bpo-41710: The PyThread_acquire_lock_timed() function now clamps the - timeout if it is too large, rather than aborting the process. Patch by - Victor Stinner. - -- bpo-44687: :meth:`BufferedReader.peek` no longer raises :exc:`ValueError` - when the entire file has already been buffered. - -- bpo-45116: Add the :c:macro:`Py_ALWAYS_INLINE` macro to ask the compiler - to always inline a static inline function. The compiler can ignore it and - decides to not inline the function. Patch by Victor Stinner. - -- bpo-45094: Add the :c:macro:`Py_NO_INLINE` macro to disable inlining on a - function. Patch by Victor Stinner. - -- bpo-45061: Add a deallocator to the :class:`bool` type to detect refcount - bugs in C extensions which call ``Py_DECREF(Py_True);`` or - ``Py_DECREF(Py_False);`` by mistake. Patch by Victor Stinner. - -- bpo-42035: Add a new :c:func:`PyType_GetQualName` function to get type's - qualified name. - -- bpo-41103: Reverts removal of the old buffer protocol because they are - part of stable ABI. - -- bpo-44751: Remove ``crypt.h`` include from the public ``Python.h`` header. - -- bpo-42747: The ``Py_TPFLAGS_HAVE_VERSION_TAG`` type flag now does nothing. - The ``Py_TPFLAGS_HAVE_AM_SEND`` flag (which was added in 3.10) is removed. - Both were unnecessary because it is not possible to have type objects with - the relevant fields missing. - -- bpo-44530: Added the ``co_qualname`` to the ``PyCodeObject`` structure to - propagate the qualified name from the compiler to code objects. - - Patch by Gabriele N. Tornetta - -- bpo-44441: :c:func:`Py_RunMain` now resets :c:data:`PyImport_Inittab` to - its initial value at exit. It must be possible to call - :c:func:`PyImport_AppendInittab` or :c:func:`PyImport_ExtendInittab` at - each Python initialization. Patch by Victor Stinner. - -- bpo-39947: Remove 4 private trashcan C API functions which were only kept - for the backward compatibility of the stable ABI with Python 3.8 and - older, since the trashcan API was not usable with the limited C API on - Python 3.8 and older. The trashcan API was excluded from the limited C API - in Python 3.9. - - Removed functions: - - * _PyTrash_deposit_object() - * _PyTrash_destroy_chain() - * _PyTrash_thread_deposit_object() - * _PyTrash_thread_destroy_chain() - - The trashcan C API was never usable with the limited C API, since old - trashcan macros accessed directly :c:type:`PyThreadState` members like - ``_tstate->trash_delete_nesting``, whereas the :c:type:`PyThreadState` - structure is opaque in the limited C API. - - Exclude also the ``PyTrash_UNWIND_LEVEL`` constant from the C API. - - Patch by Victor Stinner. - -- bpo-40939: Removed documentation for the removed ``PyParser_*`` C API. - -- bpo-43795: The list in :ref:`stable-abi-list` now shows the public name - :c:struct:`PyFrameObject` rather than ``_frame``. The non-existing entry - ``_node`` no longer appears in the list. - -- bpo-44378: :c:func:`Py_IS_TYPE` no longer uses :c:func:`Py_TYPE` to avoid - a compiler warning: no longer cast ``const PyObject*`` to ``PyObject*``. - Patch by Victor Stinner. - -- bpo-39573: Convert the :c:func:`Py_TYPE` and :c:func:`Py_SIZE` macros to - static inline functions. The :c:func:`Py_SET_TYPE` and - :c:func:`Py_SET_SIZE` functions must now be used to set an object type and - size. Patch by Victor Stinner. - -- bpo-44263: The :c:func:`PyType_Ready` function now raises an error if a - type is defined with the :const:`Py_TPFLAGS_HAVE_GC` flag set but has no - traverse function (:c:member:`PyTypeObject.tp_traverse`). Patch by Victor - Stinner. - -- bpo-43795: The undocumented function :c:func:`Py_FrozenMain` is removed - from the Limited API. - -- bpo-44113: Deprecate the following functions to configure the Python - initialization: - - * :c:func:`PySys_AddWarnOptionUnicode` - * :c:func:`PySys_AddWarnOption` - * :c:func:`PySys_AddXOption` - * :c:func:`PySys_HasWarnOptions` - * :c:func:`Py_SetPath` - * :c:func:`Py_SetProgramName` - * :c:func:`Py_SetPythonHome` - * :c:func:`Py_SetStandardStreamEncoding` - * :c:func:`_Py_SetProgramFullPath` - - Use the new :c:type:`PyConfig` API of the :ref:`Python Initialization - Configuration <init-config>` instead (:pep:`587`). - -- bpo-44094: Remove ``PyErr_SetFromErrnoWithUnicodeFilename()``, - ``PyErr_SetFromWindowsErrWithUnicodeFilename()``, and - ``PyErr_SetExcFromWindowsErrWithUnicodeFilename()``. They are not - documented and have been deprecated since Python 3.3. - -- bpo-43795: :c:func:`PyCodec_Unregister` is now properly exported as a - function in the Windows Stable ABI DLL. - -- bpo-44029: Remove deprecated ``Py_UNICODE`` APIs: ``PyUnicode_Encode``, - ``PyUnicode_EncodeUTF7``, ``PyUnicode_EncodeUTF8``, - ``PyUnicode_EncodeUTF16``, ``PyUnicode_EncodeUTF32``, - ``PyUnicode_EncodeLatin1``, ``PyUnicode_EncodeMBCS``, - ``PyUnicode_EncodeDecimal``, ``PyUnicode_EncodeRawUnicodeEscape``, - ``PyUnicode_EncodeCharmap``, ``PyUnicode_EncodeUnicodeEscape``, - ``PyUnicode_TransformDecimalToASCII``, ``PyUnicode_TranslateCharmap``, - ``PyUnicodeEncodeError_Create``, ``PyUnicodeTranslateError_Create``. See - :pep:`393` and :pep:`624` for reference. - -- bpo-42035: Add a new :c:func:`PyType_GetName` function to get type's short - name. - - -What's New in Python 3.10.0 beta 1? -=================================== - -*Release date: 2021-05-03* - -Security --------- - -- bpo-43434: Creating :class:`sqlite3.Connection` objects now also produces - ``sqlite3.connect`` and ``sqlite3.connect/handle`` :ref:`auditing events - <auditing>`. Previously these events were only produced by - :func:`sqlite3.connect` calls. Patch by Erlend E. Aasland. - -- bpo-43998: The :mod:`ssl` module sets more secure cipher suites defaults. - Ciphers without forward secrecy and with SHA-1 MAC are disabled by - default. Security level 2 prohibits weak RSA, DH, and ECC keys with less - than 112 bits of security. :class:`~ssl.SSLContext` defaults to minimum - protocol version TLS 1.2. Settings are based on Hynek Schlawack's - research. - -- bpo-43882: The presence of newline or tab characters in parts of a URL - could allow some forms of attacks. - - Following the controlling specification for URLs defined by WHATWG - :func:`urllib.parse` now removes ASCII newlines and tabs from URLs, - preventing such attacks. - -- bpo-43472: Ensures interpreter-level audit hooks receive the - ``cpython.PyInterpreterState_New`` event when called through the - ``_xxsubinterpreters`` module. - -- bpo-43362: Fix invalid free in _sha3 module. The issue was introduced in - 3.10.0a1. Python 3.9 and earlier are not affected. - -- bpo-43762: Add audit events for :func:`sqlite3.connect/handle`, - :meth:`sqlite3.Connection.enable_load_extension`, and - :meth:`sqlite3.Connection.load_extension`. Patch by Erlend E. Aasland. - -- bpo-43756: Add new audit event ``glob.glob/2`` to incorporate the new - *root_dir* and *dir_fd* arguments added to :func:`glob.glob` and - :func:`glob.iglob`. - -- bpo-36384: :mod:`ipaddress` module no longer accepts any leading zeros in - IPv4 address strings. Leading zeros are ambiguous and interpreted as octal - notation by some libraries. For example the legacy function - :func:`socket.inet_aton` treats leading zeros as octal notation. glibc - implementation of modern :func:`~socket.inet_pton` does not accept any - leading zeros. For a while the :mod:`ipaddress` module used to accept - ambiguous leading zeros. - -- bpo-43075: Fix Regular Expression Denial of Service (ReDoS) vulnerability - in :class:`urllib.request.AbstractBasicAuthHandler`. The ReDoS-vulnerable - regex has quadratic worst-case complexity and it allows cause a denial of - service when identifying crafted invalid RFCs. This ReDoS issue is on the - client side and needs remote attackers to control the HTTP server. - -- bpo-42800: Audit hooks are now fired for frame.f_code, traceback.tb_frame, - and generator code/frame attribute access. - -- bpo-37363: Add audit events to the :mod:`http.client` module. - -Core and Builtins ------------------ - -- bpo-43977: Prevent classes being both a sequence and a mapping when - pattern matching. - -- bpo-43977: Use :c:member:`~PyTypeObject.tp_flags` on the class object to - determine if the subject is a sequence or mapping when pattern matching. - Avoids the need to import :mod:`collections.abc` when pattern matching. - -- bpo-43892: Restore proper validation of complex literal value patterns - when parsing :keyword:`!match` blocks. - -- bpo-43933: Set frame.f_lineno to the line number of the 'with' kweyword - when executing the call to ``__exit__``. - -- bpo-43933: If the current position in a frame has no line number then set - the f_lineno attribute to None, instead of -1, to conform to PEP 626. This - should not normally be possible, but might occur in some unusual - circumstances. - -- bpo-43963: Importing the :mod:`_signal` module in a subinterpreter has no - longer side effects. - -- bpo-42739: The internal representation of line number tables is changed to - not use sentinels, and an explicit length parameter is added to the out of - process API function ``PyLineTable_InitAddressRange``. This makes the - handling of line number tables more robust in some circumstances. - -- bpo-43908: Make :mod:`re` types immutable. Patch by Erlend E. Aasland. - -- bpo-43908: Make the :class:`array.array` type immutable. Patch by Erlend - E. Aasland. - -- bpo-43901: Change class and module objects to lazy-create empty - annotations dicts on demand. The annotations dicts are stored in the - object's __dict__ for backwards compatibility. - -- bpo-43892: Match patterns now use new dedicated AST nodes (``MatchValue``, - ``MatchSingleton``, ``MatchSequence``, ``MatchStar``, ``MatchMapping``, - ``MatchClass``) rather than reusing expression AST nodes. ``MatchAs`` and - ``MatchOr`` are now defined as pattern nodes rather than as expression - nodes. Patch by Nick Coghlan. - -- bpo-42725: Usage of ``await``/``yield``/``yield from`` and named - expressions within an annotation is now forbidden when PEP 563 is - activated. - -- bpo-43754: When performing structural pattern matching (:pep:`634`), - captured names are now left unbound until the *entire* pattern has matched - successfully. - -- bpo-42737: Annotations for complex targets (everything beside simple - names) no longer cause any runtime effects with ``from __future__ import - annotations``. - -- bpo-43914: :exc:`SyntaxError` exceptions raised by the interpreter will - highlight the full error range of the expression that consistutes the - syntax error itself, instead of just where the problem is detected. Patch - by Pablo Galindo. - -- bpo-38605: Revert making ``from __future__ import annotations`` the - default. This follows the Steering Council decision to postpone PEP 563 - changes to at least Python 3.11. See the original email for more - information regarding the decision: - https://mail.python.org/archives/list/python-dev@python.org/thread/CLVXXPQ2T2LQ5MP2Y53VVQFCXYWQJHKZ/. - Patch by Pablo Galindo. - -- bpo-43475: Hashes of NaN values now depend on object identity. Formerly, - they always hashed to 0 even though NaN values are not equal to one - another. Having the same hash for unequal values caused pile-ups in hash - tables. - -- bpo-43859: Improve the error message for :exc:`IndentationError` - exceptions. Patch by Pablo Galindo - -- bpo-41323: Constant tuple folding in bytecode optimizer now reuses tuple - in constant table. - -- bpo-43846: Data stack usage is much reduced for large literal and call - expressions. - -- bpo-38530: When printing :exc:`NameError` raised by the interpreter, - :c:func:`PyErr_Display` will offer suggestions of similar variable names - in the function that the exception was raised from. Patch by Pablo Galindo - -- bpo-43823: Improve syntax errors for invalid dictionary literals. Patch by - Pablo Galindo. - -- bpo-43822: Improve syntax errors in the parser for missing commas between - expressions. Patch by Pablo Galindo. - -- bpo-43798: :class:`ast.alias` nodes now include source location metadata - attributes e.g. lineno, col_offset. - -- bpo-43797: Improve ``SyntaxError`` error messages for invalid comparisons. - Patch by Pablo Galindo. - -- bpo-43760: Move the flag for checking whether tracing is enabled to the C - stack, from the heap. Should speed up dispatch in the interpreter. - -- bpo-43682: Static methods (:func:`@staticmethod <staticmethod>`) and class - methods (:func:`@classmethod <classmethod>`) now inherit the method - attributes (``__module__``, ``__name__``, ``__qualname__``, ``__doc__``, - ``__annotations__``) and have a new ``__wrapped__`` attribute. Patch by - Victor Stinner. - -- bpo-43751: Fixed a bug where ``anext(ait, default)`` would erroneously - return None. - -- bpo-42128: :data:`~object.__match_args__` is no longer allowed to be a - list. - -- bpo-43683: Add GEN_START opcode. Marks start of generator, including - async, or coroutine and handles sending values to a newly created - generator or coroutine. - -- bpo-43105: Importlib now resolves relative paths when creating module spec - objects from file locations. - -- bpo-43682: Static methods (:func:`@staticmethod <staticmethod>`) are now - callable as regular functions. Patch by Victor Stinner. - -- bpo-42609: Prevented crashes in the AST validator and optimizer when - compiling some absurdly long expressions like ``"+0"*1000000``. - :exc:`RecursionError` is now raised instead. - -- bpo-38530: When printing :exc:`AttributeError`, :c:func:`PyErr_Display` - will offer suggestions of similar attribute names in the object that the - exception was raised from. Patch by Pablo Galindo - -Library -------- - -- bpo-44015: In @dataclass(), raise a TypeError if KW_ONLY is specified more - than once. - -- bpo-25478: Added a *total()* method to collections.Counter() to compute - the sum of the counts. - -- bpo-43733: Change :class:`netrc.netrc` to use UTF-8 encoding before using - locale encoding. - -- bpo-43979: Removed an unnecessary list comprehension before looping from - :func:`urllib.parse.parse_qsl`. Patch by Christoph Zwerschke and Dong-hee - Na. - -- bpo-43993: Update bundled pip to 21.1.1. - -- bpo-43957: [Enum] Deprecate ``TypeError`` when non-member is used in a - containment check; In 3.12 ``True`` or ``False`` will be returned instead, - and containment will return ``True`` if the value is either a member of - that enum or one of its members' value. - -- bpo-42904: For backwards compatibility with previous minor versions of - Python, if :func:`typing.get_type_hints` receives no namespace dictionary - arguments, :func:`typing.get_type_hints` will search through the global - then local namespaces during evaluation of stringized type annotations - (string forward references) inside a class. - -- bpo-43945: [Enum] Deprecate non-standard mixin format() behavior: in 3.12 - the enum member, not the member's value, will be used for format() calls. - -- bpo-41139: Deprecate undocumented ``cgi.log()`` API. - -- bpo-43937: Fixed the :mod:`turtle` module working with non-default root - window. - -- bpo-43930: Update bundled pip to 21.1 and setuptools to 56.0.0 - -- bpo-43907: Fix a bug in the pure-Python pickle implementation when using - protocol 5, where bytearray instances that occur several time in the - pickled object graph would incorrectly unpickle into repeated copies of - the bytearray object. - -- bpo-43926: In ``importlib.metadata``, provide a uniform interface to - ``Description``, allow for any field to be encoded with multiline values, - remove continuation lines from multiline values, and add a ``.json`` - property for easy access to the PEP 566 JSON-compatible form. Sync with - ``importlib_metadata 4.0``. - -- bpo-43920: OpenSSL 3.0.0: :meth:`~ssl.SSLContext.load_verify_locations` - now returns a consistent error message when cadata contains no valid - certificate. - -- bpo-43607: :mod:`urllib` can now convert Windows paths with ``\\?\`` - prefixes into URL paths. - -- bpo-43817: Add :func:`inspect.get_annotations`, which safely computes the - annotations defined on an object. It works around the quirks of accessing - the annotations from various types of objects, and makes very few - assumptions about the object passed in. :func:`inspect.get_annotations` - can also correctly un-stringize stringized annotations. - - :func:`inspect.signature`, :func:`inspect.from_callable`, and - :func:`inspect.from_function` now call :func:`inspect.get_annotations` to - retrieve annotations. This means :func:`inspect.signature` and - :func:`inspect.from_callable` can now un-stringize stringized annotations, - too. - -- bpo-43284: platform.win32_ver derives the windows version from - sys.getwindowsversion().platform_version which in turn derives the version - from kernel32.dll (which can be of a different version than Windows - itself). Therefore change the platform.win32_ver to determine the version - using the platform module's _syscmd_ver private function to return an - accurate version. - -- bpo-42854: The :mod:`ssl` module now uses ``SSL_read_ex`` and - ``SSL_write_ex`` internally. The functions support reading and writing of - data larger than 2 GB. Writing zero-length data no longer fails with a - protocol violation error. - -- bpo-42333: Port ``_ssl`` extension module to multiphase initialization. - -- bpo-43880: :mod:`ssl` now raises DeprecationWarning for OP_NO_SSL/TLS* - options, old TLS versions, old protocols, and other features that have - been deprecated since Python 3.6, 3.7, or OpenSSL 1.1.0. - -- bpo-41559: :pep:`612` is now implemented purely in Python; builtin - ``types.GenericAlias`` objects no longer include ``typing.ParamSpec`` in - ``__parameters__`` (with the exception of ``collections.abc.Callable``\ 's - ``GenericAlias``). This means previously invalid uses of ``ParamSpec`` - (such as ``list[P]``) which worked in earlier versions of Python 3.10 - alpha, will now raise ``TypeError`` during substitution. - -- bpo-43867: The :mod:`multiprocessing` ``Server`` class now explicitly - catches :exc:`SystemExit` and closes the client connection in this case. - It happens when the ``Server.serve_client()`` method reaches the end of - file (EOF). - -- bpo-40443: Remove unused imports: pyclbr no longer uses copy, and typing - no longer uses ast. Patch by Victor Stinner. - -- bpo-43820: Remove an unneeded copy of the namespace passed to - dataclasses.make_dataclass(). - -- bpo-43787: Add ``__iter__()`` method to :class:`bz2.BZ2File`, - :class:`gzip.GzipFile`, and :class:`lzma.LZMAFile`. It makes iterating - them about 2x faster. Patch by Inada Naoki. - -- bpo-43680: Deprecate io.OpenWrapper and _pyio.OpenWrapper: use io.open and - _pyio.open instead. Until Python 3.9, _pyio.open was not a static method - and builtins.open was set to OpenWrapper to not become a bound method when - set to a class variable. _io.open is a built-in function whereas - _pyio.open is a Python function. In Python 3.10, _pyio.open() is now a - static method, and builtins.open() is now io.open(). - -- bpo-43680: The Python :func:`_pyio.open` function becomes a static method - to behave as :func:`io.open` built-in function: don't become a bound - method when stored as a class variable. It becomes possible since static - methods are now callable in Python 3.10. Moreover, - :func:`_pyio.OpenWrapper` becomes a simple alias to :func:`_pyio.open`. - Patch by Victor Stinner. - -- bpo-41515: Fix :exc:`KeyError` raised in :func:`typing.get_type_hints` due - to synthetic modules that don't appear in ``sys.modules``. - -- bpo-43776: When :class:`subprocess.Popen` args are provided as a string or - as :class:`pathlib.Path`, the Popen instance repr now shows the right - thing. - -- bpo-42248: [Enum] ensure exceptions raised in ``_missing__`` are released - -- bpo-43744: fix issue with enum member name matching the start of a private - variable name - -- bpo-43772: Fixed the return value of ``TypeVar.__ror__``. Patch by Jelle - Zijlstra. - -- bpo-43764: Add match_args parameter to @dataclass decorator to allow - suppression of __match_args__ generation. - -- bpo-43799: OpenSSL 3.0.0: define ``OPENSSL_API_COMPAT`` 1.1.1 to suppress - deprecation warnings. Python requires OpenSSL 1.1.1 APIs. - -- bpo-43478: Mocks can no longer be used as the specs for other Mocks. As a - result, an already-mocked object cannot have an attribute mocked using - ``autospec=True`` or be the subject of a ``create_autospec(...)`` call. - This can uncover bugs in tests since these Mock-derived Mocks will always - pass certain tests (e.g. :func:`isinstance`) and builtin assert functions - (e.g. assert_called_once_with) will unconditionally pass. - -- bpo-43794: Add :data:`ssl.OP_IGNORE_UNEXPECTED_EOF` constants (OpenSSL - 3.0.0) - -- bpo-43785: Improve ``bz2.BZ2File`` performance by removing the RLock from - BZ2File. This makes BZ2File thread unsafe in the face of multiple - simultaneous readers or writers, just like its equivalent classes in - :mod:`gzip` and :mod:`lzma` have always been. Patch by Inada Naoki. - -- bpo-43789: OpenSSL 3.0.0: Don't call the password callback function a - second time when first call has signaled an error condition. - -- bpo-43788: The header files for :mod:`ssl` error codes are now OpenSSL - version-specific. Exceptions will now show correct reason and library - codes. The ``make_ssl_data.py`` script has been rewritten to use OpenSSL's - text file with error codes. - -- bpo-43766: Implement :pep:`647` in the :mod:`typing` module by adding - :data:`TypeGuard`. - -- bpo-25264: :func:`os.path.realpath` now accepts a *strict* keyword-only - argument. When set to ``True``, :exc:`OSError` is raised if a path doesn't - exist or a symlink loop is encountered. - -- bpo-43780: In ``importlib.metadata``, incorporate changes from - importlib_metadata 3.10: Add mtime-based caching during distribution - discovery. Flagged use of dict result from ``entry_points()`` as - deprecated. - -- The ``P.args`` and ``P.kwargs`` attributes of :class:`typing.ParamSpec` - are now instances of the new classes :class:`typing.ParamSpecArgs` and - :class:`typing.ParamSpecKwargs`, which enables a more useful ``repr()``. - Patch by Jelle Zijlstra. - -- bpo-43731: Add an ``encoding`` parameter :func:`logging.fileConfig()`. - -- bpo-43712: Add ``encoding`` and ``errors`` parameters to - :func:`fileinput.input` and :class:`fileinput.FileInput`. - -- bpo-38659: A ``simple_enum`` decorator is added to the ``enum`` module to - convert a normal class into an Enum. ``test_simple_enum`` added to test - simple enums against a corresponding normal Enum. Standard library - modules updated to use ``simple_enum``. - -- bpo-43764: Fix an issue where :data:`~object.__match_args__` generation - could fail for some :mod:`dataclasses`. - -- bpo-43752: Fix :mod:`sqlite3` regression for zero-sized blobs with - converters, where ``b""`` was returned instead of ``None``. The regression - was introduced by PR 24723. Patch by Erlend E. Aasland. - -- bpo-43655: :mod:`tkinter` dialog windows are now recognized as dialogs by - window managers on macOS and X Window. - -- bpo-43723: The following ``threading`` methods are now deprecated and - should be replaced: - - - ``currentThread`` => :func:`threading.current_thread` - - - ``activeCount`` => :func:`threading.active_count` - - - ``Condition.notifyAll`` => :meth:`threading.Condition.notify_all` - - - ``Event.isSet`` => :meth:`threading.Event.is_set` - - - ``Thread.setName`` => :attr:`threading.Thread.name` - - - ``thread.getName`` => :attr:`threading.Thread.name` - - - ``Thread.isDaemon`` => :attr:`threading.Thread.daemon` - - - ``Thread.setDaemon`` => :attr:`threading.Thread.daemon` - - Patch by Jelle Zijlstra. - -- bpo-2135: Deprecate find_module() and find_loader() implementations in - importlib and zipimport. - -- bpo-43534: :func:`turtle.textinput` and :func:`turtle.numinput` create now - a transient window working on behalf of the canvas window. - -- bpo-43532: Add the ability to specify keyword-only fields to dataclasses. - These fields will become keyword-only arguments to the generated __init__. - -- bpo-43522: Fix problem with - :attr:`~ssl.SSLContext.hostname_checks_common_name`. OpenSSL does not copy - hostflags from *struct SSL_CTX* to *struct SSL*. - -- bpo-8978: Improve error message for :func:`tarfile.open` when :mod:`lzma` - / :mod:`bz2` are unavailable. Patch by Anthony Sottile. - -- bpo-42967: Allow :class:`bytes` ``separator`` argument in - ``urllib.parse.parse_qs`` and ``urllib.parse.parse_qsl`` when parsing - :class:`str` query strings. Previously, this raised a ``TypeError``. - -- bpo-43296: Improve :mod:`sqlite3` error handling: ``sqlite3_value_blob()`` - errors that set ``SQLITE_NOMEM`` now raise :exc:`MemoryError`. Patch by - Erlend E. Aasland. - -- bpo-43312: New functions :func:`sysconfig.get_preferred_scheme` and - :func:`sysconfig.get_default_scheme` are added to query a platform for its - preferred "user", "home", and "prefix" (default) scheme names. - -- bpo-43265: Improve :meth:`sqlite3.Connection.backup` error handling. The - error message for non-existent target database names is now ``unknown - database <database name>`` instead of ``SQL logic error``. Patch by Erlend - E. Aasland. - -- bpo-41282: Install schemes in :mod:`distutils.command.install` are now - loaded from :mod:`sysconfig`. - -- bpo-41282: :mod:`distutils.sysconfig` has been merged to :mod:`sysconfig`. - -- bpo-43176: Fixed processing of a dataclass that inherits from a frozen - dataclass with no fields. It is now correctly detected as an error. - -- bpo-43080: :mod:`pprint` now has support for - :class:`dataclasses.dataclass`. Patch by Lewis Gaul. - -- bpo-39950: Add `pathlib.Path.hardlink_to()` method that supersedes - `link_to()`. The new method has the same argument order as `symlink_to()`. - -- bpo-42904: :func:`typing.get_type_hints` now checks the local namespace of - a class when evaluating :pep:`563` annotations inside said class. - -- bpo-42269: Add ``slots`` parameter to ``dataclasses.dataclass`` decorator - to automatically generate ``__slots__`` for class. Patch provided by Yurii - Karabas. - -- bpo-39529: Deprecated use of :func:`asyncio.get_event_loop` without - running event loop. Emit deprecation warning for :mod:`asyncio` functions - which implicitly create a :class:`~asyncio.Future` or - :class:`~asyncio.Task` objects if there is no running event loop and no - explicit *loop* argument is passed: :func:`~asyncio.ensure_future`, - :func:`~asyncio.wrap_future`, :func:`~asyncio.gather`, - :func:`~asyncio.shield`, :func:`~asyncio.as_completed` and constructors of - :class:`~asyncio.Future`, :class:`~asyncio.Task`, - :class:`~asyncio.StreamReader`, :class:`~asyncio.StreamReaderProtocol`. - -- bpo-18369: Certificate and PrivateKey classes were added to the ssl - module. Certificates and keys can now be loaded from memory buffer, too. - -- bpo-41486: Use a new output buffer management code for :mod:`bz2` / - :mod:`lzma` / :mod:`zlib` modules, and add ``.readall()`` function to - ``_compression.DecompressReader`` class. These bring some performance - improvements. Patch by Ma Lin. - -- bpo-31870: The :func:`ssl.get_server_certificate` function now has a - *timeout* parameter. - -- bpo-41735: Fix thread locks in zlib module may go wrong in rare case. - Patch by Ma Lin. - -- bpo-36470: Fix dataclasses with ``InitVar``\s and - :func:`~dataclasses.replace()`. Patch by Claudiu Popa. - -- bpo-40849: Expose X509_V_FLAG_PARTIAL_CHAIN ssl flag - -- bpo-35114: :func:`ssl.RAND_status` now returns a boolean value (as - documented) instead of ``1`` or ``0``. - -- bpo-39906: :meth:`pathlib.Path.stat` and :meth:`~pathlib.Path.chmod` now - accept a *follow_symlinks* keyword-only argument for consistency with - corresponding functions in the :mod:`os` module. - -- bpo-39899: :func:`os.path.expanduser()` now refuses to guess Windows home - directories if the basename of current user's home directory does not - match their username. - - :meth:`pathlib.Path.expanduser()` and :meth:`~pathlib.Path.home()` now - consistently raise :exc:`RuntimeError` exception when a home directory - cannot be resolved. Previously a :exc:`KeyError` exception could be raised - on Windows when the ``"USERNAME"`` environment variable was unset. - -- bpo-36076: Added SNI support to :func:`ssl.get_server_certificate`. - -- bpo-38490: Covariance, Pearson's correlation, and simple linear regression - functionality was added to statistics module. Patch by Tymoteusz Wołodźko. - -- bpo-33731: Provide a locale.localize() function, which converts a - normalized number string into a locale format. - -- bpo-32745: Fix a regression in the handling of ctypes' - :data:`ctypes.c_wchar_p` type: embedded null characters would cause a - :exc:`ValueError` to be raised. Patch by Zackery Spytz. - -Documentation -------------- - -- bpo-43987: Add "Annotations Best Practices" document as a new HOWTO. - -- bpo-43977: Document the new :const:`Py_TPFLAGS_MAPPING` and - :const:`Py_TPFLAGS_SEQUENCE` type flags. - -- bpo-43959: The documentation on the PyContextVar C-API was clarified. - -- bpo-43938: Update dataclasses documentation to express that - FrozenInstanceError is derived from AttributeError. - -- bpo-43778: Fix the Sphinx glossary_search extension: create the _static/ - sub-directory if it doesn't exist. - -- bpo-43755: Update documentation to reflect that unparenthesized lambda - expressions can no longer be the expression part in an ``if`` clause in - comprehensions and generator expressions since Python 3.9. - -- bpo-43739: Fixing the example code in Doc/extending/extending.rst to - declare and initialize the pmodule variable to be of the right type. - -Tests ------ - -- bpo-43961: Fix test_logging.test_namer_rotator_inheritance() on Windows: - use :func:`os.replace` rather than :func:`os.rename`. Patch by Victor - Stinner. - -- bpo-43842: Fix a race condition in the SMTP test of test_logging. Don't - close a file descriptor (socket) from a different thread while - asyncore.loop() is polling the file descriptor. Patch by Victor Stinner. - -- bpo-43843: :mod:`test.libregrtest` now marks a test as ENV_CHANGED - (altered the execution environment) if a thread raises an exception but - does not catch it. It sets a hook on :func:`threading.excepthook`. Use - ``--fail-env-changed`` option to mark the test as failed. Patch by Victor - Stinner. - -- bpo-43811: Tests multiple OpenSSL versions on GitHub Actions. Use ccache - to speed up testing. - -- bpo-43791: OpenSSL 3.0.0: Disable testing of legacy protocols TLS 1.0 and - 1.1. Tests are failing with TLSV1_ALERT_INTERNAL_ERROR. - -Build ------ - -- bpo-43567: Improved generated code refresh (AST/tokens/opcodes/keywords) - on Windows. - -- bpo-43669: Implement :pep:`644`. Python now requires OpenSSL 1.1.1 or - newer. - -Windows -------- - -- bpo-35306: Adds additional arguments to :func:`os.startfile` function. - -- bpo-43538: Avoid raising errors from :meth:`pathlib.Path.exists()` when - passed an invalid filename. - -- bpo-38822: Fixed :func:`os.stat` failing on inaccessible directories with - a trailing slash, rather than falling back to the parent directory's - metadata. This implicitly affected :func:`os.path.exists` and - :func:`os.path.isdir`. - -- bpo-26227: Fixed decoding of host names in :func:`socket.gethostbyaddr` - and :func:`socket.gethostbyname_ex`. - -- bpo-40432: Updated pegen regeneration script on Windows to find and use - Python 3.8 or higher. Prior to this, pegen regeneration already required - 3.8 or higher, but the script may have used lower versions of Python. - -- bpo-43745: Actually updates Windows release to OpenSSL 1.1.1k. Earlier - releases were mislabelled and actually included 1.1.1i again. - -- bpo-43652: Update Tcl and Tk to 8.6.11 in Windows installer. - -- bpo-43492: Upgrade Windows installer to use SQLite 3.35.5. - -- bpo-30555: Fix ``WindowsConsoleIO`` errors in the presence of fd - redirection. Patch by Segev Finer. - -macOS ------ - -- bpo-42119: Fix check for macOS SDK paths when building Python. Narrow - search to match contents of SDKs, namely only files in - ``/System/Library``, ``/System/IOSSupport``, and ``/usr`` other than - ``/usr/local``. Previously, anything under ``/System`` was assumed to be - in an SDK which causes problems with the new file system layout in 10.15+ - where user file systems may appear to be mounted under ``/System``. Paths - in ``/Library`` were also incorrectly treated as SDK locations. - -- bpo-43568: Drop support for MACOSX_DEPLOYMENT_TARGET < 10.3 - -- bpo-44009: Provide "python3.x-intel64" executable to allow reliably - forcing macOS universal2 framework builds to run under Rosetta 2 Intel-64 - emulation on Apple Silicon Macs. This can be useful for testing or when - universal2 wheels are not yet available. - -- bpo-43851: Build SQLite with ``SQLITE_OMIT_AUTOINIT`` on macOS. Patch by - Erlend E. Aasland. - -- bpo-43492: Update macOS installer to use SQLite 3.35.4. - -- bpo-42235: ``Mac/BuildScript/build-installer.py`` will now use - "--enable-optimizations" and ``--with-lto`` when building on macOS 10.15 - or later. - -IDLE ----- - -- bpo-37903: Add mouse actions to the shell sidebar. Left click and - optional drag selects one or more lines, as with the editor line number - sidebar. Right click after selecting raises a context menu with 'copy - with prompts'. This zips together prompts from the sidebar with lines - from the selected text. - -- bpo-43981: Fix reference leak in test_sidebar and test_squeezer. Patches - by Terry Jan Reedy and Pablo Galindo - -- bpo-37892: Indent IDLE Shell input with spaces instead of tabs - -- bpo-43655: IDLE dialog windows are now recognized as dialogs by window - managers on macOS and X Window. - -- bpo-37903: IDLE's shell now shows prompts in a separate side-bar. - -C API ------ - -- bpo-43916: Add a new :c:data:`Py_TPFLAGS_DISALLOW_INSTANTIATION` type flag - to disallow creating type instances. Patch by Victor Stinner. - -- bpo-43774: Remove the now unused ``PYMALLOC_DEBUG`` macro. Debug hooks on - memory allocators are now installed by default if Python is built in debug - mode (if ``Py_DEBUG`` macro is defined). Moreover, they can now be used on - Python build in release mode (ex: using ``PYTHONMALLOC=debug`` environment - variable). - -- bpo-43962: _PyInterpreterState_IDIncref() now calls - _PyInterpreterState_IDInitref() and always increments id_refcount. - Previously, calling _xxsubinterpreters.get_current() could create an - id_refcount inconsistency when a _xxsubinterpreters.InterpreterID object - was deallocated. Patch by Victor Stinner. - -- bpo-28254: Add new C-API functions to control the state of the garbage - collector: :c:func:`PyGC_Enable()`, :c:func:`PyGC_Disable()`, - :c:func:`PyGC_IsEnabled()`, corresponding to the functions in the - :mod:`gc` module. - -- bpo-43908: Introduce :const:`Py_TPFLAGS_IMMUTABLETYPE` flag for immutable - type objects, and modify :c:func:`PyType_Ready` to set it for static - types. Patch by Erlend E. Aasland. - -- bpo-43795: :c:func:`PyMem_Calloc` is now available in the limited C API - (``Py_LIMITED_API``). - -- bpo-43868: :c:func:`PyOS_ReadlineFunctionPointer` is no longer exported by - limited C API headers and by ``python3.dll`` on Windows. Like any function - that takes ``FILE*``, it is not part of the stable ABI. - -- bpo-43795: Stable ABI and limited API definitions are generated from a - central manifest (:pep:`652`). - -- bpo-43753: Add the :c:func:`Py_Is(x, y) <Py_Is>` function to test if the - *x* object is the *y* object, the same as ``x is y`` in Python. Add also - the :c:func:`Py_IsNone`, :c:func:`Py_IsTrue`, :c:func:`Py_IsFalse` - functions to test if an object is, respectively, the ``None`` singleton, - the ``True`` singleton or the ``False`` singleton. Patch by Victor - Stinner. - - -What's New in Python 3.10.0 alpha 7? -==================================== - -*Release date: 2021-04-05* - -Security --------- - -- bpo-42988: CVE-2021-3426: Remove the ``getfile`` feature of the - :mod:`pydoc` module which could be abused to read arbitrary files on the - disk (directory traversal vulnerability). Moreover, even source code of - Python modules can contain sensitive data like passwords. Vulnerability - reported by David Schwörer. - -- bpo-43285: :mod:`ftplib` no longer trusts the IP address value returned - from the server in response to the PASV command by default. This prevents - a malicious FTP server from using the response to probe IPv4 address and - port combinations on the client network. - - Code that requires the former vulnerable behavior may set a - ``trust_server_pasv_ipv4_address`` attribute on their :class:`ftplib.FTP` - instances to ``True`` to re-enable it. - -- bpo-43439: Add audit hooks for :func:`gc.get_objects`, - :func:`gc.get_referrers` and :func:`gc.get_referents`. Patch by Pablo - Galindo. - -Core and Builtins ------------------ - -- bpo-27129: Update CPython bytecode magic number. - -- bpo-43672: Raise ImportWarning when calling find_loader(). - -- bpo-43660: Fix crash that happens when replacing ``sys.stderr`` with a - callable that can remove the object while an exception is being printed. - Patch by Pablo Galindo. - -- bpo-27129: The bytecode interpreter uses instruction, rather byte, offsets - internally. This reduces the number of EXTENDED_ARG instructions needed - and streamlines instruction dispatch a bit. - -- bpo-40645: Fix reference leak in the :mod:`_hashopenssl` extension. Patch - by Pablo Galindo. - -- bpo-42134: Calls to find_module() by the import system now raise - ImportWarning. - -- bpo-41064: Improve the syntax error for invalid usage of double starred - elements ('**') in f-strings. Patch by Pablo Galindo. - -- bpo-43575: Speed up calls to ``map()`` by using the :pep:`590` - ``vectorcall`` calling convention. Patch by Dong-hee Na. - -- bpo-42137: The import system now prefers using ``__spec__`` for - ``ModuleType.__repr__`` over ``module_repr()``. - -- bpo-43452: Added micro-optimizations to ``_PyType_Lookup()`` to improve - cache lookup performance in the common case of cache hits. - -- bpo-43555: Report the column offset for :exc:`SyntaxError` for invalid - line continuation characters. Patch by Pablo Galindo. - -- bpo-43517: Fix misdetection of circular imports when using ``from pkg.mod - import attr``, which caused false positives in non-trivial multi-threaded - code. - -- bpo-43497: Emit SyntaxWarnings for assertions with tuple constants, this - is a regression introduced in python3.7 - -- bpo-39316: Tracing now has correct line numbers for attribute accesses - when the attribute is on a different line from the object. Improves - debugging and profiling for multi-line method chains. - -- bpo-35883: Python no longer fails at startup with a fatal error if a - command line argument contains an invalid Unicode character. The - :c:func:`Py_DecodeLocale` function now escapes byte sequences which would - be decoded as Unicode characters outside the [U+0000; U+10ffff] range. - -- bpo-43410: Fix a bug that was causing the parser to crash when emitting - syntax errors when reading input from stdin. Patch by Pablo Galindo - -- bpo-43406: Fix a possible race condition where ``PyErr_CheckSignals`` - tries to execute a non-Python signal handler. - -- bpo-42128: Add ``__match_args__`` to :c:type:`structsequence` based - classes. Patch by Pablo Galindo. - -- bpo-43390: CPython now sets the ``SA_ONSTACK`` flag in ``PyOS_setsig`` for - the VM's default signal handlers. This is friendlier to other in-process - code that an extension module or embedding use could pull in (such as - Golang's cgo) where tiny thread stacks are the norm and ``sigaltstack()`` - has been used to provide for signal handlers. This is a no-op change for - the vast majority of processes that don't use sigaltstack. - -- bpo-43287: Speed up calls to ``filter()`` by using the :pep:`590` - ``vectorcall`` calling convention. Patch by Dong-hee Na. - -- bpo-37448: Add a radix tree based memory map to track in-use obmalloc - arenas. Use to replace the old implementation of address_in_range(). The - radix tree approach makes it easy to increase pool sizes beyond the OS - page size. Boosting the pool and arena size allows obmalloc to handle a - significantly higher percentage of requests from its ultra-fast paths. - - It also has the advantage of eliminating the memory unsanitary behavior of - the previous address_in_range(). The old address_in_range() was marked - with the annotations _Py_NO_SANITIZE_ADDRESS, _Py_NO_SANITIZE_THREAD, and - _Py_NO_SANITIZE_MEMORY. Those annotations are no longer needed. - - To disable the radix tree map, set a preprocessor flag as follows: - `-DWITH_PYMALLOC_RADIX_TREE=0`. - - Co-authored-by: Tim Peters <tim.peters@gmail.com> - -- bpo-29988: Only handle asynchronous exceptions and requests to drop the - GIL when returning from a call or on the back edges of loops. Makes sure - that :meth:`__exit__` is always called in with statements, even for - interrupts. - -Library -------- - -- bpo-43720: Document various stdlib deprecations in imp, pkgutil, and - importlib.util for removal in Python 3.12. - -- bpo-43433: :class:`xmlrpc.client.ServerProxy` no longer ignores query and - fragment in the URL of the server. - -- bpo-31956: The :meth:`~array.array.index` method of :class:`array.array` - now has optional *start* and *stop* parameters. - -- bpo-40066: Enum: adjust ``repr()`` to show only enum and member name (not - value, nor angle brackets) and ``str()`` to show only member name. Update - and improve documentation to match. - -- bpo-42136: Deprecate all module_repr() methods found in importlib as their - use is being phased out by Python 3.12. - -- bpo-35930: Raising an exception raised in a "future" instance will create - reference cycles. - -- bpo-41369: Finish updating the vendored libmpdec to version 2.5.1. Patch - by Stefan Krah. - -- bpo-43422: Revert the _decimal C API which was added in bpo-41324. - -- bpo-43577: Fix deadlock when using :class:`ssl.SSLContext` debug callback - with :meth:`ssl.SSLContext.sni_callback`. - -- bpo-43571: It's now possible to create MPTCP sockets with IPPROTO_MPTCP - -- bpo-43542: ``image/heic`` and ``image/heif`` were added to - :mod:`mimetypes`. - -- bpo-40645: The :mod:`hmac` module now uses OpenSSL's HMAC implementation - when digestmod argument is a hash name or builtin hash function. - -- bpo-43510: Implement :pep:`597`: Add ``EncodingWarning`` warning, ``-X - warn_default_encoding`` option, :envvar:`PYTHONWARNDEFAULTENCODING` - environment variable and ``encoding="locale"`` argument value. - -- bpo-43521: ``ast.unparse`` can now render NaNs and empty sets. - -- bpo-42914: :func:`pprint.pprint` gains a new boolean - ``underscore_numbers`` optional argument to emit integers with thousands - separated by an underscore character for improved readability (for example - ``1_000_000`` instead of ``1000000``). - -- bpo-41361: :meth:`~collections.deque.rotate` calls are now slightly faster - due to faster argument parsing. - -- bpo-43423: :func:`subprocess.communicate` no longer raises an IndexError - when there is an empty stdout or stderr IO buffer during a timeout on - Windows. - -- bpo-27820: Fixed long-standing bug of smtplib.SMTP where doing AUTH LOGIN - with initial_response_ok=False will fail. - - The cause is that SMTP.auth_login _always_ returns a password if provided - with a challenge string, thus non-compliant with the standard for AUTH - LOGIN. - - Also fixes bug with the test for smtpd. - -- bpo-43445: Add frozen modules to :data:`sys.stdlib_module_names`. For - example, add ``"_frozen_importlib"`` and ``"_frozen_importlib_external"`` - names. - -- bpo-43245: Add keyword arguments support to ``ChainMap.new_child()``. - -- bpo-29982: Add optional parameter *ignore_cleanup_errors* to - :func:`tempfile.TemporaryDirectory` and allow multiple :func:`cleanup` - attempts. Contributed by C.A.M. Gerlach. - -- bpo-43428: Include changes from `importlib_metadata 3.7 - <https://importlib-metadata.readthedocs.io/en/latest/history.html#v3-7-0>`_: - - Performance enhancements to distribution discovery. - - ``entry_points`` only returns unique distributions. - - Introduces new ``EntryPoints`` object for containing a set of entry points - with convenience methods for selecting entry points by group or name. - ``entry_points`` now returns this object if selection parameters are - supplied but continues to return a dict object for compatibility. Users - are encouraged to rely on the selection interface. The dict object result - is likely to be deprecated in the future. - - Added packages_distributions function to return a mapping of packages to - the distributions that provide them. - -- bpo-43332: Improves the networking efficiency of :mod:`http.client` when - using a proxy via :meth:`~HTTPConnection.set_tunnel`. Fewer small send - calls are made during connection setup. - -- bpo-43420: Improve performance of :class:`fractions.Fraction` arithmetics - for large components. Contributed by Sergey B. Kirpichev. - -- bpo-43356: Allow passing a signal number to ``_thread.interrupt_main()``. - -- bpo-43399: Fix ``ElementTree.extend`` not working on iterators when using - the Python implementation - -- bpo-43369: Improve :mod:`sqlite3` error handling: If - ``sqlite3_column_text()`` and ``sqlite3_column_blob()`` set - ``SQLITE_NOMEM``, :exc:`MemoryError` is now raised. Patch by Erlend E. - Aasland. - -- bpo-43368: Fix a regression introduced in PR 24562, where an empty - bytestring was fetched as ``None`` instead of ``b''`` in :mod:`sqlite3`. - Patch by Mariusz Felisiak. - -- bpo-41282: Fixed stacklevel of ``DeprecationWarning`` emitted from - ``import distutils``. - -- bpo-42129: ``importlib.resources`` now honors namespace packages, merging - resources from each location in the namespace as introduced in - ``importlib_resources`` 3.2 and including incidental changes through - 5.0.3. - -- bpo-43295: :meth:`datetime.datetime.strptime` now raises ``ValueError`` - instead of ``IndexError`` when matching ``'z'`` with the ``%z`` format - specifier. - -- bpo-43125: Return empty string if base64mime.body_encode receive empty - bytes - -- bpo-43084: :func:`curses.window.enclose` returns now ``True`` or ``False`` - (as was documented) instead of ``1`` or ``0``. - -- bpo-42994: Add MIME types for opus, AAC, 3gpp and 3gpp2 - -- bpo-14678: Add an invalidate_caches() method to the zipimport.zipimporter - class to support importlib.invalidate_caches(). Patch by Desmond Cheong. - -- bpo-42782: Fail fast in :func:`shutil.move()` to avoid creating - destination directories on failure. - -- bpo-40066: Enum's `repr()` and `str()` have changed: `repr()` is now - *EnumClass.MemberName* and `str()` is *MemberName*. Additionally, stdlib - Enum's whose contents are available as module attributes, such as - `RegexFlag.IGNORECASE`, have their `repr()` as *module.name*, e.g. - `re.IGNORECASE`. - -- bpo-26053: Fixed bug where the :mod:`pdb` interactive run command echoed - the args from the shell command line, even if those have been overridden - at the pdb prompt. - -- bpo-24160: Fixed bug where breakpoints did not persist across multiple - debugger sessions in :mod:`pdb`'s interactive mode. - -- bpo-40701: When the :data:`tempfile.tempdir` global variable is set to a - value of type bytes, it is now handled consistently. Previously - exceptions could be raised from some tempfile APIs when the directory did - not already exist in this situation. Also ensures that the - :func:`tempfile.gettempdir()` and :func:`tempfile.gettempdirb()` functions - *always* return ``str`` and ``bytes`` respectively. - -- bpo-39342: Expose ``X509_V_FLAG_ALLOW_PROXY_CERTS`` as - :data:`~ssl.VERIFY_ALLOW_PROXY_CERTS` to allow proxy certificate - validation as explained in - https://www.openssl.org/docs/man1.1.1/man7/proxy-certificates.html. - -- bpo-31861: Add builtins.aiter and builtins.anext. Patch by Joshua Bronson - (@jab), Daniel Pope (@lordmauve), and Justin Wang (@justin39). - -Documentation -------------- - -- bpo-43199: Answer "Why is there no goto?" in the Design and History FAQ. - -- bpo-43407: Clarified that a result from :func:`time.monotonic`, - :func:`time.perf_counter`, :func:`time.process_time`, or - :func:`time.thread_time` can be compared with the result from any - following call to the same function - not just the next immediate call. - -- bpo-43354: Fix type documentation for ``Fault.faultCode``; the type has to - be ``int`` instead of ``str``. - -- bpo-41933: Clarified wording of s * n in the Common Sequence Operations - -Tests ------ - -- bpo-37945: Fix test_getsetlocale_issue1813() of test_locale: skip the test - if ``setlocale()`` fails. Patch by Victor Stinner. - -- bpo-41561: Add workaround for Ubuntu's custom OpenSSL security level - policy. - -Build ------ - -- bpo-43179: Introduce and correctly use ALIGNOF_X in place of SIZEOF_X for - alignment-related code in optimized string routines. Patch by Jessica - Clarke. - -- bpo-43631: Update macOS, Windows, and CI to OpenSSL 1.1.1k. - -- bpo-43617: Improve configure.ac: Check for presence of autoconf-archive - package and remove our copies of M4 macros. - -- bpo-43466: The ``configure`` script now supports ``--with-openssl-rpath`` - option. - -- bpo-43372: Use ``_freeze_importlib`` to generate code for the - ``__hello__`` module. This approach ensures the code matches the - interpreter version. Previously, PYTHON_FOR_REGEN was used to generate - the code, which might be wrong. The marshal format for code objects has - changed with bpo-42246, commit 877df851. Update the code and the expected - code sizes in ctypes test_frozentable. - -Windows -------- - -- bpo-43440: Build :mod:`sqlite3` with the ``R*Tree`` module enabled. Patch - by Erlend E. Aasland. - -IDLE ----- - -- bpo-42225: Document that IDLE can fail on Unix either from misconfigured - IP masquerade rules or failure displaying complex colored (non-ascii) - characters. - -C API ------ - -- bpo-43688: The limited C API is now supported if Python is built in debug - mode (if the ``Py_DEBUG`` macro is defined). In the limited C API, the - :c:func:`Py_INCREF` and :c:func:`Py_DECREF` functions are now implemented - as opaque function calls, rather than accessing directly the - :c:member:`PyObject.ob_refcnt` member, if Python is built in debug mode - and the ``Py_LIMITED_API`` macro targets Python 3.10 or newer. It became - possible to support the limited C API in debug mode because the - :c:type:`PyObject` structure is the same in release and debug mode since - Python 3.8 (see :issue:`36465`). - - The limited C API is still not supported in the ``--with-trace-refs`` - special build (``Py_TRACE_REFS`` macro). - - Patch by Victor Stinner. - -- bpo-43244: Remove the ``pyarena.h`` header file with functions: - - * ``PyArena_New()`` - * ``PyArena_Free()`` - * ``PyArena_Malloc()`` - * ``PyArena_AddPyObject()`` - - These functions were undocumented, excluded from the limited C API, and - were only used internally by the compiler. Patch by Victor Stinner. - -- bpo-43244: Remove the compiler and parser functions using ``struct _mod`` - type, because the public AST C API was removed: - - * ``PyAST_Compile()`` - * ``PyAST_CompileEx()`` - * ``PyAST_CompileObject()`` - * ``PyFuture_FromAST()`` - * ``PyFuture_FromASTObject()`` - * ``PyParser_ASTFromFile()`` - * ``PyParser_ASTFromFileObject()`` - * ``PyParser_ASTFromFilename()`` - * ``PyParser_ASTFromString()`` - * ``PyParser_ASTFromStringObject()`` - - These functions were undocumented and excluded from the limited C API. - Patch by Victor Stinner. - -- bpo-43244: Remove ``ast.h``, ``asdl.h``, and ``Python-ast.h`` header - files. These functions were undocumented and excluded from the limited C - API. Most names defined by these header files were not prefixed by ``Py`` - and so could create names conflicts. For example, ``Python-ast.h`` defined - a ``Yield`` macro which was conflict with the ``Yield`` name used by the - Windows ``<winbase.h>`` header. Use the Python :mod:`ast` module instead. - Patch by Victor Stinner. - -- bpo-43541: Fix a ``PyEval_EvalCodeEx()`` regression: fix reference - counting on builtins. Patch by Victor Stinner. - -- bpo-43244: Remove the ``symtable.h`` header file and the undocumented - functions: - - * ``PyST_GetScope()`` - * ``PySymtable_Build()`` - * ``PySymtable_BuildObject()`` - * ``PySymtable_Free()`` - * ``Py_SymtableString()`` - * ``Py_SymtableStringObject()`` - - The ``Py_SymtableString()`` function was part the stable ABI by mistake - but it could not be used, because the ``symtable.h`` header file was - excluded from the limited C API. - - The Python :mod:`symtable` module remains available and is unchanged. - - Patch by Victor Stinner. - -- bpo-43244: Remove the ``PyAST_Validate()`` function. It is no longer - possible to build a AST object (``mod_ty`` type) with the public C API. - The function was already excluded from the limited C API (:pep:`384`). - Patch by Victor Stinner. - - -What's New in Python 3.10.0 alpha 6? -==================================== - -*Release date: 2021-03-01* - -Security --------- - -- bpo-42967: Fix web cache poisoning vulnerability by defaulting the query - args separator to ``&``, and allowing the user to choose a custom - separator. - -Core and Builtins ------------------ - -- bpo-43321: Fix ``SystemError`` raised when ``PyArg_Parse*()`` is used with - ``#`` but without ``PY_SSIZE_T_CLEAN`` defined. - -- bpo-36346: ``PyArg_Parse*()`` functions now emits ``DeprecationWarning`` - when ``u`` or ``Z`` format is used. See :pep:`623` for detail. - -- bpo-43277: Add a new :c:func:`PySet_CheckExact` function to the C-API to - check if an object is an instance of :class:`set` but not an instance of a - subtype. Patch by Pablo Galindo. - -- bpo-42990: The :data:`types.FunctionType` constructor now inherits the - current builtins if the *globals* dictionary has no ``"__builtins__"`` - key, rather than using ``{"None": None}`` as builtins: same behavior as - :func:`eval` and :func:`exec` functions. Defining a function with ``def - function(...): ...`` in Python is not affected, globals cannot be - overridden with this syntax: it also inherits the current builtins. Patch - by Victor Stinner. - -- bpo-42990: Functions have a new ``__builtins__`` attribute which is used - to look for builtin symbols when a function is executed, instead of - looking into ``__globals__['__builtins__']``. Patch by Mark Shannon and - Victor Stinner. - -- bpo-43149: Improve the error message in the parser for exception groups - without parentheses. Patch by Pablo Galindo. - -- bpo-43121: Fixed an incorrect :exc:`SyntaxError` message for missing comma - in literals. Patch by Pablo Galindo. - -- bpo-42819: :mod:`readline`: Explicitly disable bracketed paste in the - interactive interpreter, even if it's set in the inputrc, is enabled by - default (eg GNU Readline 8.1), or a user calls - ``readline.read_init_file()``. The Python REPL has not implemented - bracketed paste support. Also, bracketed mode writes the ``"\x1b[?2004h"`` - escape sequence into stdout which causes test failures in applications - that don't support it. It can still be explicitly enabled by calling - ``readline.parse_and_bind("set enable-bracketed-paste on")``. Patch by - Dustin Rodrigues. - -- bpo-42808: Simple calls to ``type(object)`` are now faster due to the - ``vectorcall`` calling convention. Patch by Dennis Sweeney. - -- bpo-42217: Make the compiler merges same co_code and co_linetable objects - in a module like already did for co_consts. - -- bpo-41972: Substring search functions such as ``str1 in str2`` and - ``str2.find(str1)`` now sometimes use the "Two-Way" string comparison - algorithm to avoid quadratic behavior on long strings. - -- bpo-42128: Implement :pep:`634` (structural pattern matching). Patch by - Brandt Bucher. - -- bpo-40692: In the :class:`concurrent.futures.ProcessPoolExecutor`, - validate that :func:`multiprocess.synchronize` is available on a given - platform and rely on that check in the :mod:`concurrent.futures` test - suite so we can run tests that are unrelated to - :class:`ProcessPoolExecutor` on those platforms. - -- bpo-38302: If :func:`object.__ipow__` returns :const:`NotImplemented`, the - operator will correctly fall back to :func:`object.__pow__` and - :func:`object.__rpow__` as expected. - -Library -------- - -- bpo-43316: The ``python -m gzip`` command line application now properly - fails when detecting an unsupported extension. It exits with a non-zero - exit code and prints an error message to stderr. - -- bpo-43317: Set the chunk size for the ``gzip`` module main function to - io.DEFAULT_BUFFER_SIZE. This is slightly faster than the 1024 bytes - constant that was used previously. - -- bpo-43146: Handle None in single-arg versions of - :func:`~traceback.print_exception` and - :func:`~traceback.format_exception`. - -- bpo-43260: Fix TextIOWrapper can not flush internal buffer forever after - very large text is written. - -- bpo-43258: Prevent needless allocation of :mod:`sqlite3` aggregate - function context when no rows match an aggregate query. Patch by Erlend E. - Aasland. - -- bpo-43251: Improve :mod:`sqlite3` error handling: - ``sqlite3_column_name()`` failures now result in :exc:`MemoryError`. Patch - by Erlend E. Aasland. - -- bpo-40956: Fix segfault in :meth:`sqlite3.Connection.backup` if no - argument was provided. The regression was introduced by PR 23838. Patch by - Erlend E. Aasland. - -- bpo-43172: The readline module now passes its tests when built directly - against libedit. Existing irreconcilable API differences remain in - :func:`readline.get_begidx` and :func:`readline.get_endidx` behavior based - on libreadline vs libedit use. - -- bpo-43163: Fix a bug in :mod:`codeop` that was causing it to not ask for - more input when multi-line snippets have unclosed parentheses. Patch by - Pablo Galindo - -- bpo-43162: deprecate unsupported ability to access enum members as - attributes of other enum members - -- bpo-43146: Fix recent regression in None argument handling in - :mod:`~traceback` module functions. - -- bpo-43102: The namedtuple __new__ method had its __builtins__ set to None - instead of an actual dictionary. This created problems for introspection - tools. - -- bpo-43106: Added :data:`~os.O_EVTONLY`, :data:`~os.O_FSYNC`, - :data:`~os.O_SYMLINK` and :data:`~os.O_NOFOLLOW_ANY` for macOS. Patch by - Dong-hee Na. - -- bpo-42960: Adds :data:`resource.RLIMIT_KQUEUES` constant from FreeBSD to - the :mod:`resource` module. - -- bpo-42151: Make the pure Python implementation of - :mod:`xml.etree.ElementTree` behave the same as the C implementation - (:mod:`_elementree`) regarding default attribute values (by not setting - ``specified_attributes=1``). - -- bpo-29753: In ctypes, now packed bitfields are calculated properly and the - first item of packed bitfields is now shrank correctly. - -Documentation -------------- - -- bpo-27646: Clarify that 'yield from <expr>' works with any iterable, not - just iterators. - -- bpo-36346: Update some deprecated unicode APIs which are documented as - "will be removed in 4.0" to "3.12". See :pep:`623` for detail. - -Tests ------ - -- bpo-43288: Fix test_importlib to correctly skip Unicode file tests if the - filesystem does not support them. - -Build ------ - -- bpo-43174: Windows build now uses ``/utf-8`` compiler option. - -- bpo-43103: Add a new configure ``--without-static-libpython`` option to - not build the ``libpythonMAJOR.MINOR.a`` static library and not install - the ``python.o`` object file. - -- bpo-13501: The configure script can now use *libedit* instead of - *readline* with the command line option ``--with-readline=editline``. - -- bpo-42603: Make configure script use pkg-config to detect the location of - Tcl/Tk headers and libraries, used to build tkinter. - - On macOS, a Tcl/Tk configuration provided by pkg-config will be preferred - over Tcl/Tk frameworks installed in ``/{System/,}Library/Frameworks``. If - both exist and the latter is preferred, the appropriate ``--with-tcltk-*`` - configuration options need to be explicitly set. - -- bpo-39448: Add the "regen-frozen" makefile target that regenerates the - code for the frozen ``__hello__`` module. - -Windows -------- - -- bpo-43155: :c:func:`PyCMethod_New` is now present in ``python3.lib``. - -macOS ------ - -- bpo-41837: Update macOS installer build to use OpenSSL 1.1.1j. - -IDLE ----- - -- bpo-43283: Document why printing to IDLE's Shell is often slower than - printing to a system terminal and that it can be made faster by - pre-formatting a single string before printing. - -C API ------ - -- bpo-43278: Always put compiler and system information on the first line of - the REPL welcome message. - -- bpo-43270: Remove the private ``_PyErr_OCCURRED()`` macro: use the public - :c:func:`PyErr_Occurred` function instead. - -- bpo-35134: Move odictobject.h, parser_interface.h, picklebufobject.h, - pydebug.h, and pyfpe.h into the cpython/ directory. They must not be - included directly, as they are already included by Python.h: :ref:`Include - Files <api-includes>`. - -- bpo-35134: Move pyarena.h, pyctype.h, and pytime.h into the cpython/ - directory. They must not be included directly, as they are already - included by Python.h: :ref:`Include Files <api-includes>`. - -- bpo-40170: :c:func:`PyExceptionClass_Name` is now always declared as a - function, in order to hide implementation details. The macro accessed - :c:member:`PyTypeObject.tp_name` directly. Patch by Erlend E. Aasland. - -- bpo-43239: The :c:func:`PyCFunction_New` function is now exported in the - ABI when compiled with ``-fvisibility=hidden``. - -- bpo-40170: :c:func:`PyIter_Check` is now always declared as a function, in - order to hide implementation details. The macro accessed - :c:member:`PyTypeObject.tp_iternext` directly. Patch by Erlend E. Aasland. - -- bpo-40170: Convert :c:func:`PyDescr_IsData` macro to a function to hide - implementation details: The macro accessed - :c:member:`PyTypeObject.tp_descr_set` directly. Patch by Erlend E. - Aasland. - -- bpo-43181: Convert :c:func:`PyObject_TypeCheck` macro to a static inline - function. Patch by Erlend E. Aasland. - - -What's New in Python 3.10.0 alpha 5? -==================================== - -*Release date: 2021-02-02* - -Security --------- - -- bpo-42938: Avoid static buffers when computing the repr of - :class:`ctypes.c_double` and :class:`ctypes.c_longdouble` values. - -Core and Builtins ------------------ - -- bpo-42990: Refactor the ``PyEval_`` family of functions. - - * An new function ``_PyEval_Vector`` is added to simplify calls to Python from C. - * ``_PyEval_EvalCodeWithName`` is removed - * ``PyEval_EvalCodeEx`` is retained as part of the API, but is not used internally - -- bpo-38631: Replace :c:func:`Py_FatalError` calls in the compiler with - regular :exc:`SystemError` exceptions. Patch by Victor Stinner. - -- bpo-42997: Improve error message for missing ":" before blocks. Patch by - Pablo Galindo. - -- bpo-43017: Improve error message in the parser when using un-parenthesised - tuples in comprehensions. Patch by Pablo Galindo. - -- bpo-42986: Fix parser crash when reporting syntax errors in f-string with - newlines. Patch by Pablo Galindo. - -- bpo-40176: Syntax errors for unterminated string literals now point to the - start of the string instead of reporting EOF/EOL. - -- bpo-42927: The inline cache for ``LOAD_ATTR`` now also optimizes access to - attributes defined by ``__slots__``. This makes reading such attribute up - to 30% faster. - -- bpo-42864: Improve error messages in the parser when parentheses are not - closed. Patch by Pablo Galindo. - -- bpo-42924: Fix ``bytearray`` repetition incorrectly copying data from the - start of the buffer, even if the data is offset within the buffer (e.g. - after reassigning a slice at the start of the ``bytearray`` to a shorter - byte string). - -- bpo-42882: Fix the :c:func:`_PyUnicode_FromId` function - (_Py_IDENTIFIER(var) API) when :c:func:`Py_Initialize` / - :c:func:`Py_Finalize` is called multiple times: preserve - ``_PyRuntime.unicode_ids.next_index`` value. - -- bpo-42827: Fix a crash when working out the error line of a - :exc:`SyntaxError` in some multi-line expressions. - -- bpo-42823: frame.f_lineno is correct even if frame.f_trace is set to True - -- bpo-37324: Remove deprecated aliases to - :ref:`collections-abstract-base-classes` from the :mod:`collections` - module. - -- bpo-41994: Fixed possible leak in ``import`` when ``sys.modules`` is not a - ``dict``. - -- bpo-27772: In string formatting, preceding the *width* field by ``'0'`` no - longer affects the default alignment for strings. - -Library -------- - -- bpo-43108: Fixed a reference leak in the :mod:`curses` module. Patch by - Pablo Galindo - -- bpo-43077: Update the bundled pip to 21.0.1 and setuptools to 52.0.0. - -- bpo-41282: Deprecate ``distutils`` in documentation and add warning on - import. - -- bpo-43014: Improve performance of :mod:`tokenize` by 20-30%. Patch by - Anthony Sottile. - -- bpo-42323: Fix :func:`math.nextafter` for NaN on AIX. - -- bpo-42955: Add :data:`sys.stdlib_module_names`, containing the list of the - standard library module names. Patch by Victor Stinner. - -- bpo-42944: Fix ``random.Random.sample`` when ``counts`` argument is not - ``None``. - -- bpo-42934: Use :class:`~traceback.TracebackException`'s new ``compact`` - param in :class:`~unittest.TestResult` to reduce time and memory consumed - by traceback formatting. - -- bpo-42931: Add :func:`randbytes` to ``random.__all__``. - -- bpo-38250: [Enum] Flags consisting of a single bit are now considered - canonical, and will be the only flags returned from listing and iterating - over a Flag class or a Flag member. Multi-bit flags are considered - aliases; they will be returned from lookups and operations that result in - their value. Iteration for both Flag and Flag members is in definition - order. - -- bpo-42877: Added the ``compact`` parameter to the constructor of - :class:`traceback.TracebackException` to reduce time and memory for use - cases that only need to call :func:`TracebackException.format` and - :func:`TracebackException.format_exception_only`. - -- bpo-42923: The :c:func:`Py_FatalError` function and the - :mod:`faulthandler` module now dump the list of extension modules on a - fatal error. - -- bpo-42848: Removed recursion from :class:`~traceback.TracebackException` - to allow it to handle long exception chains. - -- bpo-42901: [Enum] move member creation from ``EnumMeta.__new__`` to - ``_proto_member.__set_name__``, allowing members to be created and visible - in ``__init_subclass__``. - -- bpo-42780: Fix os.set_inheritable() for O_PATH file descriptors on Linux. - -- bpo-42866: Fix a reference leak in the ``getcodec()`` function of CJK - codecs. Patch by Victor Stinner. - -- bpo-42846: Convert the 6 CJK codec extension modules (_codecs_cn, - _codecs_hk, _codecs_iso2022, _codecs_jp, _codecs_kr and _codecs_tw) to the - multiphase initialization API (:pep:`489`). Patch by Victor Stinner. - -- bpo-42851: remove __init_subclass__ support for Enum members - -- bpo-42834: Make internal caches of the ``_json`` module compatible with - subinterpreters. - -- bpo-41748: Fix HTMLParser parsing rules for element attributes containing - commas with spaces. Patch by Karl Dubost. - -- bpo-40810: Require SQLite 3.7.15 or newer. Patch by Erlend E. Aasland. - -- bpo-1635741: Convert the _multibytecodec extension module (CJK codecs) to - multi-phase initialization (:pep:`489`). Patch by Erlend E. Aasland. - -- bpo-42802: The distutils ``bdist_wininst`` command deprecated in Python - 3.8 has been removed. The distutils ``bdist_wheel`` command is now - recommended to distribute binary packages on Windows. - -- bpo-24464: The undocumented built-in function - ``sqlite3.enable_shared_cache`` is now deprecated, scheduled for removal - in Python 3.12. Its use is strongly discouraged by the SQLite3 - documentation. Patch by Erlend E. Aasland. - -- bpo-42384: Make pdb populate sys.path[0] exactly the same as regular - python execution. - -- bpo-42383: Fix pdb: previously pdb would fail to restart the debugging - target if it was specified using a relative path and the current directory - changed. - -- bpo-42005: Fix CLI of :mod:`cProfile` and :mod:`profile` to catch - :exc:`BrokenPipeError`. - -- bpo-41604: Don't decrement the reference count of the previous user_ptr - when set_panel_userptr fails. - -- bpo-41149: Allow executing callables that have a boolean value of - ``False`` when passed to :class:`Threading.thread` as the target. Patch - contributed by Barney Stratford. - -- bpo-38307: Add an 'end_lineno' attribute to the Class and Function objects - that appear in the tree returned by pyclbr functions. This and the - existing 'lineno' attribute define the extent of class and def statements. - Patch by Aviral Srivastava. - -- bpo-39273: The ``BUTTON5_*`` constants are now exposed in the - :mod:`curses` module if available. - -- bpo-33289: Correct call to :mod:`tkinter.colorchooser` to return RGB - triplet of ints instead of floats. Patch by Cheryl Sabella. - -Documentation -------------- - -- bpo-40304: Fix doc for type(name, bases, dict). Patch by Boris - Verkhovskiy and Éric Araujo. - -- bpo-42811: Updated importlib.utils.resolve_name() doc to use - __spec__.parent instead of __package__. (Thanks Yair Frid.) - -Tests ------ - -- bpo-40823: Use :meth:`unittest.TestLoader().loadTestsFromTestCase` instead - of :meth:`unittest.makeSuite` in :mod:`sqlite3` tests. Patch by Erlend E. - Aasland. - -- bpo-40810: In :mod:`sqlite3`, fix ``CheckTraceCallbackContent`` for SQLite - pre 3.7.15. - -Build ------ - -- bpo-43031: Pass ``--timeout=$(TESTTIMEOUT)`` option to the default profile - task ``./python -m test --pgo`` command. - -- bpo-36143: ``make regen-all`` now also runs ``regen-keyword``. Patch by - Victor Stinner. - -- bpo-42874: Removed the grep -q and -E flags in the tzpath validation - section of the configure script to better accommodate users of some - platforms (specifically Solaris 10). - -- bpo-31904: Add library search path by wr-cc in add_cross_compiling_paths() - for VxWorks. - -- bpo-42856: Add ``--with-wheel-pkg-dir=PATH`` option to the ``./configure`` - script. If specified, the :mod:`ensurepip` module looks for ``setuptools`` - and ``pip`` wheel packages in this directory: if both are present, these - wheel packages are used instead of ensurepip bundled wheel packages. - - Some Linux distribution packaging policies recommend against bundling - dependencies. For example, Fedora installs wheel packages in the - ``/usr/share/python-wheels/`` directory and don't install the - ``ensurepip._bundled`` package. - -Windows -------- - -- bpo-41837: Updated Windows installer to include OpenSSL 1.1.1i - -- bpo-42584: Upgrade Windows installer to use SQLite 3.34.0. - -macOS ------ - -- bpo-42504: Ensure that the value of - sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') is always a string, - even in when the value is parsable as an integer. - -IDLE ----- - -- bpo-43008: Make IDLE invoke :func:`sys.excepthook` in normal, 2-process - mode. Patch by Ken Hilton. - -- bpo-33065: Fix problem debugging user classes with __repr__ method. - -- bpo-23544: Disable Debug=>Stack Viewer when user code is running or - Debugger is active, to prevent hang or crash. Patch by Zackery Spytz. - -- bpo-32631: Finish zzdummy example extension module: make menu entries - work; add docstrings and tests with 100% coverage. - -C API ------ - -- bpo-42979: When Python is built in debug mode (with C assertions), calling - a type slot like ``sq_length`` (``__len__()`` in Python) now fails with a - fatal error if the slot succeeded with an exception set, or failed with no - exception set. The error message contains the slot, the type name, and the - current exception (if an exception is set). Patch by Victor Stinner. - -- bpo-43030: Fixed a compiler warning in :c:func:`Py_UNICODE_ISSPACE()` on - platforms with signed ``wchar_t``. - - -What's New in Python 3.10.0 alpha 4? -==================================== - -*Release date: 2021-01-04* - -Core and Builtins ------------------ - -- bpo-42814: Fix undefined behavior in ``Objects/genericaliasobject.c``. - -- bpo-42806: Fix the column offsets for f-strings :mod:`ast` nodes - surrounded by parentheses and for nodes that spawn multiple lines. Patch - by Pablo Galindo. - -- bpo-40631: Fix regression where a single parenthesized starred expression - was a valid assignment target. - -- bpo-27794: Improve the error message for failed writes/deletes to property - objects. When possible, the attribute name is now shown. Patch provided by - Yurii Karabas. - -- bpo-42745: Make the type attribute lookup cache per-interpreter. Patch by - Victor Stinner. - -- bpo-42246: Jumps to jumps are not eliminated when it would break PEP 626. - -- bpo-42246: Make sure that the ``f_lasti`` and ``f_lineno`` attributes of a - frame are set correctly when an exception is raised or re-raised. Required - for PEP 626. - -- bpo-32381: The coding cookie (ex: ``# coding: latin1``) is now ignored in - the command passed to the :option:`-c` command line option. Patch by - Victor Stinner. - -- bpo-30858: Improve error location in expressions that contain assignments. - Patch by Pablo Galindo and Lysandros Nikolaou. - -- bpo-42615: Remove jump commands made redundant by the deletion of - unreachable bytecode blocks - -- bpo-42639: Make the :mod:`atexit` module state per-interpreter. It is now - safe have more than one :mod:`atexit` module instance. Patch by Dong-hee - Na and Victor Stinner. - -- bpo-32381: Fix encoding name when running a ``.pyc`` file on Windows: - :c:func:`PyRun_SimpleFileExFlags()` now uses the correct encoding to - decode the filename. - -- bpo-42195: The ``__args__`` of the parameterized generics for - :data:`typing.Callable` and :class:`collections.abc.Callable` are now - consistent. The ``__args__`` for :class:`collections.abc.Callable` are - now flattened while :data:`typing.Callable`'s have not changed. To allow - this change, :class:`types.GenericAlias` can now be subclassed and - ``collections.abc.Callable``'s ``__class_getitem__`` will now return a - subclass of ``types.GenericAlias``. Tests for typing were also updated to - not subclass things like ``Callable[..., T]`` as that is not a valid base - class. Finally, both ``Callable``\ s no longer validate their - ``argtypes``, in ``Callable[[argtypes], resulttype]`` to prepare for - :pep:`612`. Patch by Ken Jin. - -- bpo-40137: Convert functools module to use - :c:func:`PyType_FromModuleAndSpec`. - -- bpo-40077: Convert :mod:`array` to use heap types, and establish module - state for these. - -- bpo-42008: Fix _random.Random() seeding. - -- bpo-1635741: Port the :mod:`pyexpat` extension module to multi-phase - initialization (:pep:`489`). - -- bpo-40521: Make the Unicode dictionary of interned strings compatible with - subinterpreters. Patch by Victor Stinner. - -- bpo-39465: Make :c:func:`_PyUnicode_FromId` function compatible with - subinterpreters. Each interpreter now has an array of identifier objects - (interned strings decoded from UTF-8). Patch by Victor Stinner. - -Library -------- - -- bpo-42257: Handle empty string in variable executable in - platform.libc_ver() - -- bpo-42772: randrange() now raises a TypeError when step is specified - without a stop argument. Formerly, it silently ignored the step argument. - -- bpo-42759: Fixed equality comparison of :class:`tkinter.Variable` and - :class:`tkinter.font.Font`. Objects which belong to different Tcl - interpreters are now always different, even if they have the same name. - -- bpo-42756: Configure LMTP Unix-domain socket to use socket global default - timeout when a timeout is not explicitly provided. - -- bpo-23328: Allow / character in username, password fields on _PROXY - envars. - -- bpo-42740: :func:`typing.get_args` and :func:`typing.get_origin` now - support :pep:`604` union types and :pep:`612` additions to ``Callable``. - -- bpo-42655: :mod:`subprocess` *extra_groups* is now correctly passed into - setgroups() system call. - -- bpo-42727: ``EnumMeta.__prepare__`` now accepts ``**kwds`` to properly - support ``__init_subclass__`` - -- bpo-38308: Add optional *weights* to *statistics.harmonic_mean()*. - -- bpo-42721: When simple query dialogs (:mod:`tkinter.simpledialog`), - message boxes (:mod:`tkinter.messagebox`) or color choose dialog - (:mod:`tkinter.colorchooser`) are created without arguments *master* and - *parent*, and the default root window is not yet created, and - :func:`~tkinter.NoDefaultRoot` was not called, a new temporal hidden root - window will be created automatically. It will not be set as the default - root window and will be destroyed right after closing the dialog window. - It will help to use these simple dialog windows in programs which do not - need other GUI. - -- bpo-25246: Optimized :meth:`collections.deque.remove`. - -- bpo-35728: Added a root parameter to :func:`tkinter.font.nametofont`. - -- bpo-15303: :mod:`tkinter` supports now widgets with boolean value False. - -- bpo-42681: Fixed range checks for color and pair numbers in :mod:`curses`. - -- bpo-42685: Improved placing of simple query windows in Tkinter (such as - :func:`tkinter.simpledialog.askinteger`). They are now centered at the - center of the parent window if it is specified and shown, otherwise at the - center of the screen. - -- bpo-9694: Argparse help no longer uses the confusing phrase, "optional - arguments". It uses "options" instead. - -- bpo-1635741: Port the :mod:`_thread` extension module to the multiphase - initialization API (:pep:`489`) and convert its static types to heap - types. - -- bpo-37961: Fix crash in :func:`tracemalloc.Traceback.__repr__` (regressed - in Python 3.9). - -- bpo-42630: :mod:`tkinter` functions and constructors which need a default - root window raise now :exc:`RuntimeError` with descriptive message instead - of obscure :exc:`AttributeError` or :exc:`NameError` if it is not created - yet or cannot be created automatically. - -- bpo-42639: :func:`atexit._run_exitfuncs` now logs callback exceptions - using :data:`sys.unraisablehook`, rather than logging them directly into - :data:`sys.stderr` and raise the last exception. - -- bpo-42644: ``logging.disable`` will now validate the types and value of - its parameter. It also now accepts strings representing the levels (as - does ``loging.setLevel``) instead of only the numerical values. - -- bpo-42639: At Python exit, if a callback registered with - :func:`atexit.register` fails, its exception is now logged. Previously, - only some exceptions were logged, and the last exception was always - silently ignored. - -- bpo-36541: Fixed lib2to3.pgen2 to be able to parse PEP-570 positional only - argument syntax. - -- bpo-42382: In ``importlib.metadata``: - ``EntryPoint`` objects now expose - a ``.dist`` object referencing the ``Distribution`` when constructed from - a ``Distribution``. - Add support for package discovery under package - normalization rules. - The object returned by ``metadata()`` now has a - formally defined protocol called ``PackageMetadata`` with declared support - for the ``.get_all()`` method. - Synced with importlib_metadata 3.3. - -- bpo-41877: A check is added against misspellings of autospect, auto_spec - and set_spec being passed as arguments to patch, patch.object and - create_autospec. - -- bpo-39717: [tarfile] update nested exception raising to use ``from None`` - or ``from e`` - -- bpo-41877: AttributeError for suspected misspellings of assertions on - mocks are now pointing out that the cause are misspelled assertions and - also what to do if the misspelling is actually an intended attribute name. - The unittest.mock document is also updated to reflect the current set of - recognised misspellings. - -- bpo-41559: Implemented :pep:`612`: added ``ParamSpec`` and ``Concatenate`` - to :mod:`typing`. Patch by Ken Jin. - -- bpo-42385: StrEnum: fix _generate_next_value_ to return a str - -- bpo-31904: Define THREAD_STACK_SIZE for VxWorks. - -- bpo-34750: [Enum] `_EnumDict.update()` is now supported - -- bpo-42517: Enum: private names do not become members / do not generate - errors -- they remain normal attributes - -- bpo-42678: ``Enum``: call ``__init_subclass__`` after members have been - added - -- bpo-28964: :func:`ast.literal_eval` adds line number information (if - available) in error message for malformed nodes. - -- bpo-42470: :func:`random.sample` no longer warns on a sequence which is - also a set. - -- bpo-31904: :func:`posixpath.expanduser` returns the input *path* unchanged - if user home directory is None on VxWorks. - -- bpo-42388: Fix subprocess.check_output(..., input=None) behavior when - text=True to be consistent with that of the documentation and - universal_newlines=True. - -- bpo-34463: Fixed discrepancy between :mod:`traceback` and the interpreter - in formatting of SyntaxError with lineno not set (:mod:`traceback` was - changed to match interpreter). - -- bpo-42393: Raise :exc:`OverflowError` instead of silent truncation in - :meth:`socket.ntohs` and :meth:`socket.htons`. Silent truncation was - deprecated in Python 3.7. Patch by Erlend E. Aasland - -- bpo-42222: Harmonized :func:`random.randrange` argument handling to match - :func:`range`. - - * The integer test and conversion in ``randrange()`` now uses - :func:`operator.index`. - * Non-integer arguments to ``randrange()`` are deprecated. - * The ``ValueError`` is deprecated in favor of a ``TypeError``. - * It now runs a little faster than before. - - (Contributed by Raymond Hettinger and Serhiy Storchaka.) - -- bpo-42163: Restore compatibility for ``uname_result`` around deepcopy and - _replace. - -- bpo-42090: ``zipfile.Path.joinpath`` now accepts arbitrary arguments, same - as ``pathlib.Path.joinpath``. - -- bpo-1635741: Port the _csv module to the multi-phase initialization API - (:pep:`489`). - -- bpo-42059: :class:`typing.TypedDict` types created using the alternative - call-style syntax now correctly respect the ``total`` keyword argument - when setting their ``__required_keys__`` and ``__optional_keys__`` class - attributes. - -- bpo-41960: Add ``globalns`` and ``localns`` parameters to the - :func:`inspect.signature` and :meth:`inspect.Signature.from_callable`. - -- bpo-41907: fix ``format()`` behavior for ``IntFlag`` - -- bpo-41891: Ensure asyncio.wait_for waits for task completion - -- bpo-24792: Fixed bug where :mod:`zipimporter` sometimes reports an - incorrect cause of import errors. - -- bpo-31904: Fix site and sysconfig modules for VxWorks RTOS which has no - home directories. - -- bpo-41462: Add :func:`os.set_blocking()` support for VxWorks RTOS. - -- bpo-40219: Lowered :class:`tkinter.ttk.LabeledScale` dummy widget to - prevent hiding part of the content label. - -- bpo-37193: Fixed memory leak in ``socketserver.ThreadingMixIn`` introduced - in Python 3.7. - -- bpo-39068: Fix initialization race condition in :func:`a85encode` and - :func:`b85encode` in :mod:`base64`. Patch by Brandon Stansbury. - -Documentation -------------- - -- bpo-17140: Add documentation for the - :class:`multiprocessing.pool.ThreadPool` class. - -- bpo-34398: Prominently feature listings from the glossary in documentation - search results. Patch by Ammar Askar. - -Tests ------ - -- bpo-42794: Update test_nntplib to use official group name of news.aioe.org - for testing. Patch by Dong-hee Na. - -- bpo-31904: Skip some asyncio tests on VxWorks. - -- bpo-42641: Enhance ``test_select.test_select()``: it now takes 500 - milliseconds rather than 10 seconds. Use Python rather than a shell to - make the test more portable. - -- bpo-31904: Skip some tests in _test_all_chown_common() on VxWorks. - -- bpo-42199: Fix bytecode helper assertNotInBytecode. - -- bpo-41443: Add more attribute checking in test_posix.py - -- bpo-31904: Disable os.popen and impacted tests on VxWorks - -- bpo-41439: Port test_ssl and test_uuid to VxWorks RTOS. - -Build ------ - -- bpo-42692: Fix __builtin_available check on older compilers. Patch by - Joshua Root. - -- bpo-27640: Added ``--disable-test-modules`` option to the ``configure`` - script: don't build nor install test modules. Patch by Xavier de Gaye, - Thomas Petazzoni and Peixing Xin. - -- bpo-42604: Now all platforms use a value for the "EXT_SUFFIX" build - variable derived from SOABI (for instance in freeBSD, "EXT_SUFFIX" is now - ".cpython-310d.so" instead of ".so"). Previously only Linux, Mac and - VxWorks were using a value for "EXT_SUFFIX" that included "SOABI". - -- bpo-42598: Fix implicit function declarations in configure which could - have resulted in incorrect configuration checks. Patch contributed by - Joshua Root. - -- bpo-31904: Enable libpython3.so for VxWorks. - -- bpo-29076: Add fish shell support to macOS installer. - -macOS ------ - -- bpo-42361: Update macOS installer build to use Tcl/Tk 8.6.11 (rc2, - expected to be final release). - -- bpo-41837: Update macOS installer build to use OpenSSL 1.1.1i. - -- bpo-42584: Update macOS installer to use SQLite 3.34.0. - -Tools/Demos ------------ - -- bpo-42726: Fixed Python 3 compatibility issue with gdb/libpython.py - handling of attribute dictionaries. - -- bpo-42613: Fix ``freeze.py`` tool to use the prope config and library - directories. Patch by Victor Stinner. - -C API ------ - -- bpo-42591: Export the :c:func:`Py_FrozenMain` function: fix a Python 3.9.0 - regression. Python 3.9 uses ``-fvisibility=hidden`` and the function was - not exported explicitly and so not exported. - -- bpo-32381: Remove the private :c:func:`_Py_fopen` function which is no - longer needed. Use :c:func:`_Py_wfopen` or :c:func:`_Py_fopen_obj` - instead. Patch by Victor Stinner. - -- bpo-1635741: Port :mod:`resource` extension module to module state - -- bpo-42111: Update the ``xxlimited`` module to be a better example of how - to use the limited C API. - -- bpo-40052: Fix an alignment build warning/error in function - ``PyVectorcall_Function()``. Patch by Andreas Schneider, Antoine Pitrou - and Petr Viktorin. - - -What's New in Python 3.10.0 alpha 3? -==================================== - -*Release date: 2020-12-07* - -Security --------- - -- bpo-40791: Add ``volatile`` to the accumulator variable in - ``hmac.compare_digest``, making constant-time-defeating optimizations less - likely. - -Core and Builtins ------------------ - -- bpo-42576: ``types.GenericAlias`` will now raise a ``TypeError`` when - attempting to initialize with a keyword argument. Previously, this would - cause the interpreter to crash if the interpreter was compiled with debug - symbols. This does not affect interpreters compiled for release. Patch by - Ken Jin. - -- bpo-42536: Several built-in and standard library types now ensure that - their internal result tuples are always tracked by the :term:`garbage - collector <garbage collection>`: - - - :meth:`collections.OrderedDict.items() <collections.OrderedDict>` - - - :meth:`dict.items` - - - :func:`enumerate` - - - :func:`functools.reduce` - - - :func:`itertools.combinations` - - - :func:`itertools.combinations_with_replacement` - - - :func:`itertools.permutations` - - - :func:`itertools.product` - - - :func:`itertools.zip_longest` - - - :func:`zip` - - Previously, they could have become untracked by a prior garbage - collection. Patch by Brandt Bucher. - -- bpo-42500: Improve handling of exceptions near recursion limit. Converts a - number of Fatal Errors in RecursionErrors. - -- bpo-42246: PEP 626: After a return, the f_lineno attribute of a frame is - always the last line executed. - -- bpo-42435: Speed up comparison of bytes objects with non-bytes objects - when option :option:`-b` is specified. Speed up comparison of bytarray - objects with non-buffer object. - -- bpo-1635741: Port the ``_warnings`` extension module to the multi-phase - initialization API (:pep:`489`). Patch by Victor Stinner. - -- bpo-41686: On Windows, the ``SIGINT`` event, ``_PyOS_SigintEvent()``, is - now created even if Python is configured to not install signal handlers - (if :c:member:`PyConfig.install_signal_handlers` equals to 0, or - ``Py_InitializeEx(0)``). - -- bpo-42381: Allow assignment expressions in set literals and set - comprehensions as per PEP 572. Patch by Pablo Galindo. - -- bpo-42202: Change function parameters annotations internal representation - to tuple of strings. Patch provided by Yurii Karabas. - -- bpo-42374: Fix a regression introduced by the new parser, where an - unparenthesized walrus operator was not allowed within generator - expressions. - -- bpo-42316: Allow an unparenthesized walrus in subscript indexes. - -- bpo-42349: Make sure that the compiler front-end produces a well-formed - control flow graph. Be be more aggressive in the compiler back-end, as it - is now safe to do so. - -- bpo-42296: On Windows, fix a regression in signal handling which prevented - to interrupt a program using CTRL+C. The signal handler can be run in a - thread different than the Python thread, in which case the test deciding - if the thread can handle signals is wrong. - -- bpo-42332: :class:`types.GenericAlias` objects can now be the targets of - weakrefs. - -- bpo-42282: Optimise constant subexpressions that appear as part of named - expressions (previously the AST optimiser did not descend into named - expressions). Patch by Nick Coghlan. - -- bpo-42266: Fixed a bug with the LOAD_ATTR opcode cache that was not - respecting monkey-patching a class-level attribute to make it a - descriptor. Patch by Pablo Galindo. - -- bpo-40077: Convert :mod:`queue` to use heap types. - -- bpo-42246: Improved accuracy of line tracing events and f_lineno attribute - of Frame objects. See PEP 626 for details. - -- bpo-40077: Convert :mod:`mmap` to use heap types. - -- bpo-42233: Allow ``GenericAlias`` objects to use :ref:`union type - expressions <types-union>`. This allows expressions like ``list[int] | - dict[float, str]`` where previously a ``TypeError`` would have been - thrown. This also fixes union type expressions not de-duplicating - ``GenericAlias`` objects. (Contributed by Ken Jin in :issue:`42233`.) - -- bpo-26131: The import system triggers a `ImportWarning` when it falls back - to using `load_module()`. - -Library -------- - -- bpo-5054: CGIHTTPRequestHandler.run_cgi() HTTP_ACCEPT improperly parsed. - Replace the special purpose getallmatchingheaders with generic get_all - method and add relevant tests. - - Original Patch by Martin Panter. Modified by Senthil Kumaran. - -- bpo-42562: Fix issue when dis failed to parse function that has no line - numbers. Patch provided by Yurii Karabas. - -- bpo-17735: :func:`inspect.findsource` now raises :exc:`OSError` instead of - :exc:`IndexError` when :attr:`co_lineno` of a code object is greater than - the file length. This can happen, for example, when a file is edited after - it was imported. PR by Irit Katriel. - -- bpo-42116: Fix handling of trailing comments by :func:`inspect.getsource`. - -- bpo-42532: Remove unexpected call of ``__bool__`` when passing a - ``spec_arg`` argument to a Mock. - -- bpo-38200: Added itertools.pairwise() - -- bpo-41818: Fix test_master_read() so that it succeeds on all platforms - that either raise OSError or return b"" upon reading from master. - -- bpo-42487: ChainMap.__iter__ no longer calls __getitem__ on underlying - maps - -- bpo-42482: :class:`~traceback.TracebackException` no longer holds a - reference to the exception's traceback object. Consequently, instances of - TracebackException for equivalent but non-equal exceptions now compare as - equal. - -- bpo-41818: Make test_openpty() avoid unexpected success due to number of - rows and/or number of columns being == 0. - -- bpo-42392: Remove loop parameter from ``asyncio.subprocess`` and - ``asyncio.tasks`` functions. Patch provided by Yurii Karabas. - -- bpo-42392: Remove loop parameter from ``asyncio.open_connection`` and - ``asyncio.start_server`` functions. Patch provided by Yurii Karabas. - -- bpo-28468: Add :func:`platform.freedesktop_os_release` function to parse - freedesktop.org ``os-release`` files. - -- bpo-42299: Removed the ``formatter`` module, which was deprecated in - Python 3.4. It is somewhat obsolete, little used, and not tested. It was - originally scheduled to be removed in Python 3.6, but such removals were - delayed until after Python 2.7 EOL. Existing users should copy whatever - classes they use into their code. Patch by Dong-hee Na and and Terry J. - Reedy. - -- bpo-26131: Deprecate zipimport.zipimporter.load_module() in favour of - exec_module(). - -- bpo-41818: Updated tests for the pty library. test_basic() has been - changed to test_openpty(); this additionally checks if slave termios and - slave winsize are being set properly by pty.openpty(). In order to add - support for FreeBSD, NetBSD, OpenBSD, and Darwin, this also adds - test_master_read(), which demonstrates that pty.spawn() should not depend - on an OSError to exit from its copy loop. - -- bpo-42392: Remove loop parameter from ``__init__`` in all - ``asyncio.locks`` and ``asyncio.Queue`` classes. Patch provided by Yurii - Karabas. - -- bpo-15450: Make :class:`filecmp.dircmp` respect subclassing. Now the - :attr:`filecmp.dircmp.subdirs` behaves as expected when subclassing - dircmp. - -- bpo-42413: The exception :exc:`socket.timeout` is now an alias of - :exc:`TimeoutError`. - -- bpo-31904: Support signal module on VxWorks. - -- bpo-42406: We fixed an issue in `pickle.whichmodule` in which importing - `multiprocessing` could change the how pickle identifies which module an - object belongs to, potentially breaking the unpickling of those objects. - -- bpo-42403: Simplify the :mod:`importlib` external bootstrap code: - ``importlib._bootstrap_external`` now uses regular imports to import - builtin modules. When it is imported, the builtin :func:`__import__()` - function is already fully working and so can be used to import builtin - modules like :mod:`sys`. Patch by Victor Stinner. - -- bpo-1635741: Convert _sre module types to heap types (PEP 384). Patch by - Erlend E. Aasland. - -- bpo-42375: subprocess module update for DragonFlyBSD support. - -- bpo-41713: Port the ``_signal`` extension module to the multi-phase - initialization API (:pep:`489`). Patch by Victor Stinner and Mohamed - Koubaa. - -- bpo-37205: :func:`time.time()`, :func:`time.perf_counter()` and - :func:`time.monotonic()` functions can no longer fail with a Python fatal - error, instead raise a regular Python exception on failure. - -- bpo-42328: Fixed :meth:`tkinter.ttk.Style.map`. The function accepts now - the representation of the default state as empty sequence (as returned by - ``Style.map()``). The structure of the result is now the same on all - platform and does not depend on the value of ``wantobjects``. - -- bpo-42345: Fix various issues with ``typing.Literal`` parameter handling - (flatten, deduplicate, use type to cache key). Patch provided by Yurii - Karabas. - -- bpo-37205: :func:`time.perf_counter()` on Windows and - :func:`time.monotonic()` on macOS are now system-wide. Previously, they - used an offset computed at startup to reduce the precision loss caused by - the float type. Use :func:`time.perf_counter_ns()` and - :func:`time.monotonic_ns()` added in Python 3.7 to avoid this precision - loss. - -- bpo-42318: Fixed support of non-BMP characters in :mod:`tkinter` on macOS. - -- bpo-42350: Fix the :class:`threading.Thread` class at fork: do nothing if - the thread is already stopped (ex: fork called at Python exit). - Previously, an error was logged in the child process. - -- bpo-42333: Port _ssl extension module to heap types. - -- bpo-42014: The ``onerror`` callback from ``shutil.rmtree`` now receives - correct function when ``os.open`` fails. - -- bpo-42237: Fix `os.sendfile()` on illumos. - -- bpo-42308: Add :data:`threading.__excepthook__` to allow retrieving the - original value of :func:`threading.excepthook` in case it is set to a - broken or a different value. Patch by Mario Corchero. - -- bpo-42131: Implement PEP 451/spec methods on zipimport.zipimporter: - find_spec(), create_module(), and exec_module(). - - This also allows for the documented deprecation of find_loader(), - find_module(), and load_module(). - -- bpo-41877: Mock objects which are not unsafe will now raise an - AttributeError if an attribute with the prefix asert, aseert, or assrt is - accessed, in addition to this already happening for the prefixes assert or - assret. - -- bpo-42264: ``sqlite3.OptimizedUnicode`` has been undocumented and obsolete - since Python 3.3, when it was made an alias to :class:`str`. It is now - deprecated, scheduled for removal in Python 3.12. - -- bpo-42251: Added :func:`threading.gettrace` and - :func:`threading.getprofile` to retrieve the functions set by - :func:`threading.settrace` and :func:`threading.setprofile` respectively. - Patch by Mario Corchero. - -- bpo-42249: Fixed writing binary Plist files larger than 4 GiB. - -- bpo-42236: On Unix, the :func:`os.device_encoding` function now returns - ``'UTF-8'`` rather than the device encoding if the :ref:`Python UTF-8 Mode - <utf8-mode>` is enabled. - -- bpo-41754: webbrowser: Ignore *NotADirectoryError* when calling - ``xdg-settings``. - -- bpo-42183: Fix a stack overflow error for asyncio Task or Future repr(). - - The overflow occurs under some circumstances when a Task or Future - recursively returns itself. - -- bpo-42140: Improve asyncio.wait function to create the futures set just - one time. - -- bpo-42133: Update various modules in the stdlib to fall back on - `__spec__.loader` when `__loader__` isn't defined on a module. - -- bpo-26131: The `load_module()` methods found in importlib now trigger a - DeprecationWarning. - -- bpo-39825: Windows: Change ``sysconfig.get_config_var('EXT_SUFFIX')`` to - the expected full ``platform_tag.extension`` format. Previously it was - hard-coded to ``.pyd``, now it is compatible with ``distutils.sysconfig`` - and will result in something like ``.cp38-win_amd64.pyd``. This brings - windows into conformance with the other platforms. - -- bpo-26389: The :func:`traceback.format_exception`, - :func:`traceback.format_exception_only`, and - :func:`traceback.print_exception` functions can now take an exception - object as a positional-only argument. - -- bpo-41889: Enum: fix regression involving inheriting a multiply inherited - enum - -- bpo-41861: Convert :mod:`sqlite3` to use heap types (PEP 384). Patch by - Erlend E. Aasland. - -- bpo-40624: Added support for the XPath ``!=`` operator in xml.etree - -- bpo-28850: Fix :meth:`pprint.PrettyPrinter.format` overrides being ignored - for contents of small containers. The :func:`pprint._safe_repr` function - was removed. - -- bpo-41625: Expose the :c:func:`splice` as :func:`os.splice` in the - :mod:`os` module. Patch by Pablo Galindo - -- bpo-34215: Clarify the error message for - :exc:`asyncio.IncompleteReadError` when ``expected`` is ``None``. - -- bpo-41543: Add async context manager support for contextlib.nullcontext. - -- bpo-21041: :attr:`pathlib.PurePath.parents` now supports negative - indexing. Patch contributed by Yaroslav Pankovych. - -- bpo-41332: Added missing connect_accepted_socket() method to - ``asyncio.AbstractEventLoop``. - -- bpo-12800: Extracting a symlink from a tarball should succeed and - overwrite the symlink if it already exists. The fix is to remove the - existing file or symlink before extraction. Based on patch by Chris AtLee, - Jeffrey Kintscher, and Senthil Kumaran. - -- bpo-40968: :mod:`urllib.request` and :mod:`http.client` now send - ``http/1.1`` ALPN extension during TLS handshake when no custom context is - supplied. - -- bpo-41001: Add func:`os.eventfd` to provide a low level interface for - Linux's event notification file descriptor. - -- bpo-40816: Add AsyncContextDecorator to contextlib to support async - context manager as a decorator. - -- bpo-40550: Fix time-of-check/time-of-action issue in - subprocess.Popen.send_signal. - -- bpo-39411: Add an ``is_async`` identifier to :mod:`pyclbr`'s ``Function`` - objects. Patch by Batuhan Taskaya - -- bpo-35498: Add slice support to :attr:`pathlib.PurePath.parents`. - -Documentation -------------- - -- bpo-42238: Tentative to deprecate ``make suspicious`` by first removing it - from the CI and documentation builds, but keeping it around for manual - uses. - -- bpo-42153: Fix the URL for the IMAP protocol documents. - -- bpo-41028: Language and version switchers, previously maintained in every - cpython branches, are now handled by docsbuild-script. - -Tests ------ - -- bpo-41473: Re-enable test_gdb on gdb 9.2 and newer: - https://bugzilla.redhat.com/show_bug.cgi?id=1866884 bug is fixed in gdb - 10.1. - -- bpo-42553: Fix ``test_asyncio.test_call_later()`` race condition: don't - measure asyncio performance in the ``call_later()`` unit test. The test - failed randomly on the CI. - -- bpo-31904: Fix test_netrc on VxWorks: create temporary directories using - temp_cwd(). - -- bpo-31904: skip test_getaddrinfo_ipv6_scopeid_symbolic and - test_getnameinfo_ipv6_scopeid_symbolic on VxWorks - -- bpo-31904: skip test_test of test_mailcap on VxWorks - -- bpo-31904: add shell requirement for test_pipes - -- bpo-31904: skip some tests related to fifo on VxWorks - -- bpo-31904: Fix test_doctest.py failures for VxWorks. - -- bpo-40754: Include ``_testinternalcapi`` module in Windows installer for - test suite - -- bpo-41561: test_ssl: skip test_min_max_version_mismatch when TLS 1.0 is - not available - -- bpo-31904: Fix os module failures for VxWorks RTOS. - -- bpo-31904: Fix fifo test cases for VxWorks RTOS. - -Build ------ - -- bpo-31904: remove libnet dependency from detect_socket() for VxWorks - -- bpo-42398: Fix a race condition in "make regen-all" when make -jN option - is used to run jobs in parallel. The clinic.py script now only use atomic - write to write files. Moveover, generated files are now left unchanged if - the content does not change, to not change the file modification time. - -- bpo-41617: Fix building ``pycore_bitutils.h`` internal header on old clang - version without ``__builtin_bswap16()`` (ex: Xcode 4.6.3 on Mac OS X - 10.7). Patch by Joshua Root and Victor Stinner. - -- bpo-38823: It is no longer possible to build the ``_ctypes`` extension - module without :c:type:`wchar_t` type: remove ``CTYPES_UNICODE`` macro. - Anyway, the :c:type:`wchar_t` type is required to build Python. Patch by - Victor Stinner. - -- bpo-42087: Support was removed for AIX 5.3 and below. See :issue:`40680`. - -- bpo-40998: Addressed three compiler warnings found by undefined behavior - sanitizer (ubsan). - -Windows -------- - -- bpo-42120: Remove macro definition of ``copysign`` (to ``_copysign``) in - headers. - -- bpo-38506: The Windows launcher now properly handles Python 3.10 when - listing installed Python versions. - -macOS ------ - -- bpo-42504: Fix build on macOS Big Sur when MACOSX_DEPLOYMENT_TARGET=11 - -- bpo-41116: Ensure distutils.unixxcompiler.find_library_file can find - system provided libraries on macOS 11. - -- bpo-41100: Add support for macOS 11 and Apple Silicon systems. - - It is now possible to build "Universal 2" binaries using - "--enable-universalsdk --with-universal-archs=universal2". - - Binaries build on later macOS versions can be deployed back to older - versions (tested up to macOS 10.9), when using the correct deployment - target. This is tested using Xcode 11 and later. - -- bpo-42232: Added Darwin specific madvise options to mmap module. - -- bpo-38443: The ``--enable-universalsdk`` and ``--with-universal-archs`` - options for the configure script now check that the specified - architectures can be used. - -IDLE ----- - -- bpo-42508: Keep IDLE running on macOS. Remove obsolete workaround that - prevented running files with shortcuts when using new universal2 - installers built on macOS 11. - -- bpo-42426: Fix reporting offset of the RE error in searchengine. - -- bpo-42415: Get docstrings for IDLE calltips more often by using - inspect.getdoc. - -Tools/Demos ------------ - -- bpo-42212: The smelly.py script now also checks the Python dynamic library - and extension modules, not only the Python static library. Make also the - script more verbose: explain what it does. - -- bpo-36310: Allow :file:`Tools/i18n/pygettext.py` to detect calls to - ``gettext`` in f-strings. - -C API ------ - -- bpo-42423: The :c:func:`PyType_FromSpecWithBases` and - :c:func:`PyType_FromModuleAndSpec` functions now accept a single class as - the *bases* argument. - -- bpo-1635741: Port :mod:`select` extension module to multiphase - initialization (:pep:`489`). - -- bpo-1635741: Port _posixsubprocess extension module to multiphase - initialization (:pep:`489`). - -- bpo-1635741: Port _posixshmem extension module to multiphase - initialization (:pep:`489`) - -- bpo-1635741: Port _struct extension module to multiphase initialization - (:pep:`489`) - -- bpo-1635741: Port :mod:`spwd` extension module to multiphase - initialization (:pep:`489`) - -- bpo-1635741: Port :mod:`gc` extension module to multiphase initialization - (:pep:`489`) - -- bpo-1635741: Port _queue extension module to multiphase initialization - (:pep:`489`) - -- bpo-39573: Convert :c:func:`Py_TYPE` and :c:func:`Py_SIZE` back to macros - to allow using them as an l-value. Many third party C extension modules - rely on the ability of using Py_TYPE() and Py_SIZE() to set an object type - and size: ``Py_TYPE(obj) = type;`` and ``Py_SIZE(obj) = size;``. - -- bpo-1635741: Port :mod:`symtable` extension module to multiphase - initialization (:pep:`489`) - -- bpo-1635741: Port :mod:`grp` and :mod:`pwd` extension modules to - multiphase initialization (:pep:`489`) - -- bpo-1635741: Port _random extension module to multiphase initialization - (:pep:`489`) - -- bpo-1635741: Port _hashlib extension module to multiphase initialization - (:pep:`489`) - -- bpo-41713: Removed the undocumented ``PyOS_InitInterrupts()`` function. - Initializing Python already implicitly installs signal handlers: see - :c:member:`PyConfig.install_signal_handlers`. Patch by Victor Stinner. - -- bpo-40170: The ``Py_TRASHCAN_BEGIN`` macro no longer accesses PyTypeObject - attributes, but now can get the condition by calling the new private - :c:func:`_PyTrash_cond()` function which hides implementation details. - -- bpo-42260: :c:func:`Py_GetPath`, :c:func:`Py_GetPrefix`, - :c:func:`Py_GetExecPrefix`, :c:func:`Py_GetProgramFullPath`, - :c:func:`Py_GetPythonHome` and :c:func:`Py_GetProgramName` functions now - return ``NULL`` if called before :c:func:`Py_Initialize` (before Python is - initialized). Use the new :ref:`Python Initialization Configuration API - <init-config>` to get the :ref:`Python Path Configuration. - <init-path-config>`. Patch by Victor Stinner. - -- bpo-42260: The :c:func:`PyConfig_Read` function now only parses - :c:member:`PyConfig.argv` arguments once: :c:member:`PyConfig.parse_argv` - is set to ``2`` after arguments are parsed. Since Python arguments are - strippped from :c:member:`PyConfig.argv`, parsing arguments twice would - parse the application options as Python options. - -- bpo-42262: Added :c:func:`Py_NewRef` and :c:func:`Py_XNewRef` functions to - increment the reference count of an object and return the object. Patch by - Victor Stinner. - -- bpo-42260: When :c:func:`Py_Initialize` is called twice, the second call - now updates more :mod:`sys` attributes for the configuration, rather than - only :data:`sys.argv`. Patch by Victor Stinner. - -- bpo-41832: The :c:func:`PyType_FromModuleAndSpec` function now accepts - NULL ``tp_doc`` slot. - -- bpo-1635741: Added :c:func:`PyModule_AddObjectRef` function: similar to - :c:func:`PyModule_AddObject` but don't steal a reference to the value on - success. Patch by Victor Stinner. - -- bpo-42171: The :c:data:`METH_FASTCALL` calling convention is added to the - limited API. The functions :c:func:`PyModule_AddType`, - :c:func:`PyType_FromModuleAndSpec`, :c:func:`PyType_GetModule` and - :c:func:`PyType_GetModuleState` are added to the limited API on Windows. - -- bpo-42085: Add dedicated entry to PyAsyncMethods for sending values - -- bpo-41073: :c:func:`PyType_GetSlot()` can now accept static types. - -- bpo-30459: :c:func:`PyList_SET_ITEM`, :c:func:`PyTuple_SET_ITEM` and - :c:func:`PyCell_SET` macros can no longer be used as l-value or r-value. - For example, ``x = PyList_SET_ITEM(a, b, c)`` and ``PyList_SET_ITEM(a, b, - c) = x`` now fail with a compiler error. It prevents bugs like ``if - (PyList_SET_ITEM (a, b, c) < 0) ...`` test. Patch by Zackery Spytz and - Victor Stinner. - - -What's New in Python 3.10.0 alpha 2? -==================================== - -*Release date: 2020-11-03* - -Security --------- - -- bpo-42103: Prevented potential DoS attack via CPU and RAM exhaustion when - processing malformed Apple Property List files in binary format. - -- bpo-42051: The :mod:`plistlib` module no longer accepts entity - declarations in XML plist files to avoid XML vulnerabilities. This should - not affect users as entity declarations are not used in regular plist - files. - -Core and Builtins ------------------ - -- bpo-42236: If the ``nl_langinfo(CODESET)`` function returns an empty - string, Python now uses UTF-8 as the filesystem encoding. Patch by Victor - Stinner. - -- bpo-42218: Fixed a bug in the PEG parser that was causing crashes in debug - mode. Now errors are checked in left-recursive rules to avoid cases where - such errors do not get handled in time and appear as long-distance crashes - in other places. - -- bpo-42214: Fixed a possible crash in the PEG parser when checking for the - '!=' token in the ``barry_as_flufl`` rule. Patch by Pablo Galindo. - -- bpo-42206: Propagate and raise the errors caused by - :c:func:`PyAST_Validate` in the parser. - -- bpo-41796: The :mod:`ast` module internal state is now per interpreter. - Patch by Victor Stinner. - -- bpo-42143: Fix handling of errors during creation of ``PyFunctionObject``, - which resulted in operations on uninitialized memory. Patch by Yonatan - Goldschmidt. - -- bpo-41659: Fix a bug in the parser, where a curly brace following a - `primary` didn't fail immediately. This led to invalid expressions like `a - {b}` to throw a :exc:`SyntaxError` with a wrong offset, or invalid - expressions ending with a curly brace like `a {` to not fail immediately - in the REPL. - -- bpo-42150: Fix possible buffer overflow in the new parser when checking - for continuation lines. Patch by Pablo Galindo. - -- bpo-42123: Run the parser two times. On the first run, disable all the - rules that only generate better error messages to gain performance. If - there's a parse failure, run the parser a second time with those enabled. - -- bpo-42093: The ``LOAD_ATTR`` instruction now uses new "per opcode cache" - mechanism and it is about 36% faster now. Patch by Pablo Galindo and Yury - Selivanov. - -- bpo-42030: Support for the legacy AIX-specific shared library loading - support has been removed. All versions of AIX since 4.3 have supported and - defaulted to using the common Unix mechanism instead. - -- bpo-41984: The garbage collector now tracks all user-defined classes. - Patch by Brandt Bucher. - -- bpo-41993: Fixed potential issues with removing not completely initialized - module from ``sys.modules`` when import fails. - -- bpo-41979: Star-unpacking is now allowed for with item's targets in the - PEG parser. - -- bpo-41974: Removed special methods ``__int__``, ``__float__``, - ``__floordiv__``, ``__mod__``, ``__divmod__``, ``__rfloordiv__``, - ``__rmod__`` and ``__rdivmod__`` of the :class:`complex` class. They - always raised a :exc:`TypeError`. - -- bpo-41902: Micro optimization when compute - :c:member:`~PySequenceMethods.sq_item` and - :c:member:`~PyMappingMethods.mp_subscript` of :class:`range`. Patch by - Dong-hee Na. - -- bpo-41894: When loading a native module and a load failure occurs, prevent - a possible UnicodeDecodeError when not running in a UTF-8 locale by - decoding the load error message using the current locale's encoding. - -- bpo-41902: Micro optimization for range.index if step is 1. Patch by - Dong-hee Na. - -- bpo-41435: Add `sys._current_exceptions()` function to retrieve a - dictionary mapping each thread's identifier to the topmost exception - currently active in that thread at the time the function is called. - -- bpo-38605: Enable ``from __future__ import annotations`` (:pep:`563`) by - default. The values found in :attr:`__annotations__` dicts are now - strings, e.g. ``{"x": "int"}`` instead of ``{"x": int}``. - -Library -------- - -- bpo-35455: On Solaris, :func:`~time.thread_time` is now implemented with - ``gethrvtime()`` because ``clock_gettime(CLOCK_THREAD_CPUTIME_ID)`` is not - always available. Patch by Jakub Kulik. - -- bpo-42233: The :func:`repr` of :mod:`typing` types containing - :ref:`Generic Alias Types <types-genericalias>` previously did not show - the parameterized types in the ``GenericAlias``. They have now been - changed to do so. - -- bpo-29566: ``binhex.binhex()`` consistently writes macOS 9 line endings. - -- bpo-26789: The :class:`logging.FileHandler` class now keeps a reference to - the builtin :func:`open` function to be able to open or reopen the file - during Python finalization. Fix errors like: ``NameError: name 'open' is - not defined``. Patch by Victor Stinner. - -- bpo-42157: Removed the ``unicodedata.ucnhash_CAPI`` attribute which was an - internal PyCapsule object. The related private ``_PyUnicode_Name_CAPI`` - structure was moved to the internal C API. Patch by Victor Stinner. - -- bpo-42157: Convert the :mod:`unicodedata` extension module to the - multiphase initialization API (:pep:`489`) and convert the - ``unicodedata.UCD`` static type to a heap type. Patch by Mohamed Koubaa - and Victor Stinner. - -- bpo-42146: Fix memory leak in :func:`subprocess.Popen` in case an uid - (gid) specified in `user` (`group`, `extra_groups`) overflows `uid_t` - (`gid_t`). - -- bpo-42103: :exc:`~plistlib.InvalidFileException` and :exc:`RecursionError` - are now the only errors caused by loading malformed binary Plist file - (previously ValueError and TypeError could be raised in some specific - cases). - -- bpo-41490: In ``importlib.resources``, ``.path`` method is more aggressive - about releasing handles to zipfile objects early, enabling use-cases like - certifi to leave the context open but delete the underlying zip file. - -- bpo-41052: Pickling heap types implemented in C with protocols 0 and 1 - raises now an error instead of producing incorrect data. - -- bpo-42089: In ``importlib.metadata.PackageNotFoundError``, make reference - to the package metadata being missing to improve the user experience. - -- bpo-41491: plistlib: fix parsing XML plists with hexadecimal integer - values - -- bpo-42065: Fix an incorrectly formatted error from - :meth:`_codecs.charmap_decode` when called with a mapped value outside the - range of valid Unicode code points. PR by Max Bernstein. - -- bpo-41966: Fix pickling pure Python :class:`datetime.time` subclasses. - Patch by Dean Inwood. - -- bpo-19270: :meth:`sched.scheduler.cancel()` will now cancel the correct - event, if two events with same priority are scheduled for the same time. - Patch by Bar Harel. - -- bpo-28660: :func:`textwrap.wrap` now attempts to break long words after - hyphens when ``break_long_words=True`` and ``break_on_hyphens=True``. - -- bpo-35823: Use ``vfork()`` instead of ``fork()`` for - :func:`subprocess.Popen` on Linux to improve performance in cases where it - is deemed safe. - -- bpo-42043: Add support for ``zipfile.Path`` inheritance. - ``zipfile.Path.is_file()`` now returns False for non-existent names. - ``zipfile.Path`` objects now expose a ``.filename`` attribute and rely on - that to resolve ``.name`` and ``.parent`` when the ``Path`` object is at - the root of the zipfile. - -- bpo-42021: Fix possible ref leaks in :mod:`sqlite3` module init. - -- bpo-39101: Fixed tests using IsolatedAsyncioTestCase from hanging on - BaseExceptions. - -- bpo-41976: Fixed a bug that was causing :func:`ctypes.util.find_library` - to return ``None`` when triying to locate a library in an environment when - gcc>=9 is available and ``ldconfig`` is not. Patch by Pablo Galindo - -- bpo-41943: Fix bug where TestCase.assertLogs doesn't correctly filter - messages by level. - -- bpo-41923: Implement :pep:`613`, introducing :data:`typing.TypeAlias` - annotation. - -- bpo-41905: A new function in abc: *update_abstractmethods* to re-calculate - an abstract class's abstract status. In addition, *dataclass* has been - changed to call this function. - -- bpo-23706: Added *newline* parameter to ``pathlib.Path.write_text()``. - -- bpo-41876: Tkinter font class repr uses font name - -- bpo-41831: ``str()`` for the ``type`` attribute of the ``tkinter.Event`` - object always returns now the numeric code returned by Tk instead of the - name of the event type. - -- bpo-39337: :func:`encodings.normalize_encoding` now ignores non-ASCII - characters. - -- bpo-41747: Ensure all methods that generated from - :func:`dataclasses.dataclass` objects now have the proper ``__qualname__`` - attribute referring to the class they belong to. Patch by Batuhan Taskaya. - -- bpo-30681: Handle exceptions caused by unparsable date headers when using - email "default" policy. Patch by Tim Bell, Georges Toth - -- bpo-41586: Add F_SETPIPE_SZ and F_GETPIPE_SZ to fcntl module. Allow - setting pipesize on subprocess.Popen. - -- bpo-41229: Add ``contextlib.aclosing`` for deterministic cleanup of async - generators which is analogous to ``contextlib.closing`` for non-async - generators. Patch by Joongi Kim and John Belmonte. - -- bpo-16396: Allow ``ctypes.wintypes`` to be imported on non-Windows - systems. - -- bpo-4356: Add a key function to the bisect module. - -- bpo-40592: :func:`shutil.which` now ignores empty entries in - :envvar:`PATHEXT` instead of treating them as a match. - -- bpo-40492: Fix ``--outfile`` for :mod:`cProfile` / :mod:`profile` not - writing the output file in the original directory when the program being - profiled changes the working directory. PR by Anthony Sottile. - -- bpo-34204: The :mod:`shelve` module now uses - :data:`pickle.DEFAULT_PROTOCOL` by default instead of :mod:`pickle` - protocol ``3``. - -- bpo-27321: Fixed KeyError exception when flattening an email to a string - attempts to replace a non-existent Content-Transfer-Encoding header. - -- bpo-38976: The :mod:`http.cookiejar` module now supports the parsing of - cookies in CURL-style cookiejar files through MozillaCookieJar on all - platforms. Previously, such cookie entries would be silently ignored when - loading a cookiejar with such entries. - - Additionally, the HTTP Only attribute is persisted in the object, and will - be correctly written to file if the MozillaCookieJar object is - subsequently dumped. - -Documentation -------------- - -- bpo-42061: Document __format__ functionality for IP addresses. - -- bpo-41910: Document the default implementation of `object.__eq__`. - -- bpo-42010: Clarify that subscription expressions are also valid for - certain :term:`classes <class>` and :term:`types <type>` in the standard - library, and for user-defined classes and types if the classmethod - :meth:`__class_getitem__` is provided. - -- bpo-41805: Documented :ref:`generic alias type <types-genericalias>` and - :data:`types.GenericAlias`. Also added an entry in glossary for - :term:`generic types <generic type>`. - -- bpo-39693: Fix tarfile's extractfile documentation - -- bpo-39416: Document some restrictions on the default string - representations of numeric classes. - -Tests ------ - -- bpo-41739: Fix test_logging.test_race_between_set_target_and_flush(): the - test now waits until all threads complete to avoid leaking running - threads. - -- bpo-41970: Avoid a test failure in ``test_lib2to3`` if the module has - already imported at the time the test executes. Patch by Pablo Galindo. - -- bpo-41944: Tests for CJK codecs no longer call ``eval()`` on content - received via HTTP. - -- bpo-41306: Fixed a failure in ``test_tk.test_widgets.ScaleTest`` happening - when executing the test with Tk 8.6.10. - -Build ------ - -- bpo-38980: Add ``-fno-semantic-interposition`` to both the compile and - link line when building with ``--enable-optimizations``. Patch by Victor - Stinner and Pablo Galindo. - -Windows -------- - -- bpo-38439: Updates the icons for IDLE in the Windows Store package. - -- bpo-38252: Use 8-byte step to detect ASCII sequence in 64-bit Windows - build. - -- bpo-39107: Update Tcl and Tk to 8.6.10 in Windows installer. - -- bpo-41557: Update Windows installer to use SQLite 3.33.0. - -- bpo-38324: Avoid Unicode errors when accessing certain locale data on - Windows. - -macOS ------ - -- bpo-41471: Ignore invalid prefix lengths in system proxy excludes. - -IDLE ----- - -- bpo-33987: Mostly finish using ttk widgets, mainly for editor, settings, - and searches. Some patches by Mark Roseman. - -- bpo-40511: Typing opening and closing parentheses inside the parentheses - of a function call will no longer cause unnecessary "flashing" off and on - of an existing open call-tip, e.g. when typed in a string literal. - -- bpo-38439: Add a 256×256 pixel IDLE icon to the Windows .ico file. Created - by Andrew Clover. Remove the low-color gif variations from the .ico file. - -C API ------ - -- bpo-42157: The private ``_PyUnicode_Name_CAPI`` structure of the PyCapsule - API ``unicodedata.ucnhash_CAPI`` has been moved to the internal C API. - Patch by Victor Stinner. - -- bpo-42015: Fix potential crash in deallocating method objects when - dynamically allocated `PyMethodDef`'s lifetime is managed through the - ``self`` argument of a `PyCFunction`. - -- bpo-40423: The :mod:`subprocess` module and ``os.closerange`` will now use - the ``close_range(low, high, flags)`` syscall when it is available for - more efficient closing of ranges of descriptors. - -- bpo-41845: :c:func:`PyObject_GenericGetDict` is available again in the - limited API when targeting 3.10 or later. - -- bpo-40422: Add `_Py_closerange` function to provide performant closing of - a range of file descriptors. - -- bpo-41986: :c:data:`Py_FileSystemDefaultEncodeErrors` and - :c:data:`Py_UTF8Mode` are available again in limited API. - -- bpo-41756: Add `PyIter_Send` function to allow sending value into - generator/coroutine/iterator without raising StopIteration exception to - signal return. - -- bpo-41784: Added ``PyUnicode_AsUTF8AndSize`` to the limited C API. - - -What's New in Python 3.10.0 alpha 1? -==================================== - -*Release date: 2020-10-05* - -Security --------- - -- bpo-41304: Fixes `python3x._pth` being ignored on Windows, caused by the - fix for :issue:`29778` (CVE-2020-15801). - -- bpo-41162: Audit hooks are now cleared later during finalization to avoid - missing events. - -- bpo-29778: Ensure :file:`python3.dll` is loaded from correct locations - when Python is embedded (CVE-2020-15523). - -- bpo-41004: The __hash__() methods of ipaddress.IPv4Interface and - ipaddress.IPv6Interface incorrectly generated constant hash values of 32 - and 128 respectively. This resulted in always causing hash collisions. The - fix uses hash() to generate hash values for the tuple of (address, mask - length, network address). - -- bpo-39603: Prevent http header injection by rejecting control characters - in http.client.putrequest(...). - -Core and Builtins ------------------ - -- bpo-41909: Fixed stack overflow in :func:`issubclass` and - :func:`isinstance` when getting the ``__bases__`` attribute leads to - infinite recursion. - -- bpo-41922: Speed up calls to ``reversed()`` by using the :pep:`590` - ``vectorcall`` calling convention. Patch by Dong-hee Na. - -- bpo-41873: Calls to ``float()`` are now faster due to the ``vectorcall`` - calling convention. Patch by Dennis Sweeney. - -- bpo-41870: Speed up calls to ``bool()`` by using the :pep:`590` - ``vectorcall`` calling convention. Patch by Dong-hee Na. - -- bpo-1635741: Port the :mod:`_bisect` module to the multi-phase - initialization API (:pep:`489`). - -- bpo-39934: Correctly count control blocks in 'except' in compiler. Ensures - that a syntax error, rather a fatal error, occurs for deeply nested, named - exception handlers. - -- bpo-41780: Fix :meth:`__dir__` of :class:`types.GenericAlias`. Patch by - Batuhan Taskaya. - -- bpo-1635741: Port the :mod:`_lsprof` extension module to multi-phase - initialization (:pep:`489`). - -- bpo-1635741: Port the :mod:`cmath` extension module to multi-phase - initialization (:pep:`489`). - -- bpo-1635741: Port the :mod:`_scproxy` extension module to multi-phase - initialization (:pep:`489`). - -- bpo-1635741: Port the :mod:`termios` extension module to multi-phase - initialization (:pep:`489`). - -- bpo-1635741: Convert the :mod:`_sha256` extension module types to heap - types. - -- bpo-41690: Fix a possible stack overflow in the parser when parsing - functions and classes with a huge amount of arguments. Patch by Pablo - Galindo. - -- bpo-1635741: Port the :mod:`_overlapped` extension module to multi-phase - initialization (:pep:`489`). - -- bpo-1635741: Port the :mod:`_curses_panel` extension module to multi-phase - initialization (:pep:`489`). - -- bpo-1635741: Port the :mod:`_opcode` extension module to multi-phase - initialization (:pep:`489`). - -- bpo-41681: Fixes the wrong error description in the error raised by using - 2 `,` in format string in f-string and :meth:`str.format`. - -- bpo-41675: The implementation of :func:`signal.siginterrupt` now uses - :c:func:`sigaction` (if it is available in the system) instead of the - deprecated :c:func:`siginterrupt`. Patch by Pablo Galindo. - -- bpo-41670: Prevent line trace being skipped on platforms not compiled with - ``USE_COMPUTED_GOTOS``. Fixes issue where some lines nested within a - try-except block were not being traced on Windows. - -- bpo-41654: Fix a crash that occurred when destroying subclasses of - :class:`MemoryError`. Patch by Pablo Galindo. - -- bpo-1635741: Port the :mod:`zlib` extension module to multi-phase - initialization (:pep:`489`). - -- bpo-41631: The ``_ast`` module uses again a global state. Using a module - state per module instance is causing subtle practical problems. For - example, the Mercurial project replaces the ``__import__()`` function to - implement lazy import, whereas Python expected that ``import _ast`` always - return a fully initialized ``_ast`` module. - -- bpo-40077: Convert :mod:`_operator` to use :c:func:`PyType_FromSpec`. - -- bpo-1653741: Port :mod:`_sha3` to multi-phase init. Convert static types - to heap types. - -- bpo-1635741: Port the :mod:`_blake2` extension module to the multi-phase - initialization API (:pep:`489`). - -- bpo-41533: Free the stack allocated in ``va_build_stack`` if - ``do_mkstack`` fails and the stack is not a ``small_stack``. - -- bpo-41531: Fix a bug that was dropping keys when compiling dict literals - with more than 0xFFFF elements. Patch by Pablo Galindo. - -- bpo-41525: The output of ``python --help`` contains now only ASCII - characters. - -- bpo-1635741: Port the :mod:`_sha1`, :mod:`_sha512`, and :mod:`_md5` - extension modules to multi-phase initialization API (:pep:`489`). - -- bpo-41431: Optimize ``dict_merge()`` for copying dict (e.g. ``dict(d)`` - and ``{}.update(d)``). - -- bpo-41428: Implement PEP 604. This supports (int | str) etc. in place of - Union[str, int]. - -- bpo-41340: Removed fallback implementation for ``strdup``. - -- bpo-38156: Handle interrupts that come after EOF correctly in - ``PyOS_StdioReadline``. - -- bpo-41342: :func:`round` with integer argument is now faster (9--60%). - -- bpo-41334: Constructors :func:`str`, :func:`bytes` and :func:`bytearray` - are now faster (around 30--40% for small objects). - -- bpo-41295: Resolve a regression in CPython 3.8.4 where defining - "__setattr__" in a multi-inheritance setup and calling up the hierarchy - chain could fail if builtins/extension types were involved in the base - types. - -- bpo-41323: Bytecode optimizations are performed directly on the control - flow graph. This will result in slightly more compact code objects in some - circumstances. - -- bpo-41247: Always cache the running loop holder when running - ``asyncio.set_running_loop``. - -- bpo-41252: Fix incorrect refcounting in _ssl.c's - ``_servername_callback()``. - -- bpo-1635741: Port :mod:`multiprocessing` to multi-phase initialization - -- bpo-1635741: Port :mod:`winapi` to multiphase initialization - -- bpo-41215: Use non-NULL default values in the PEG parser keyword list to - overcome a bug that was preventing Python from being properly compiled - when using the XLC compiler. Patch by Pablo Galindo. - -- bpo-41218: Python 3.8.3 had a regression where compiling with - ast.PyCF_ALLOW_TOP_LEVEL_AWAIT would aggressively mark list comprehension - with CO_COROUTINE. Now only list comprehension making use of async/await - will tagged as so. - -- bpo-1635741: Port :mod:`faulthandler` to multiphase initialization. - -- bpo-1635741: Port :mod:`sha256` to multiphase initialization - -- bpo-41175: Guard against a NULL pointer dereference within bytearrayobject - triggered by the ``bytearray() + bytearray()`` operation. - -- bpo-41100: add arm64 to the allowable Mac OS arches in mpdecimal.h - -- bpo-41094: Fix decoding errors with audit when open files with non-ASCII - names on non-UTF-8 locale. - -- bpo-39960: The "hackcheck" that prevents sneaking around a type's - __setattr__() by calling the superclass method was rewritten to allow C - implemented heap types. - -- bpo-41084: Prefix the error message with 'f-string: ', when parsing an - f-string expression which throws a :exc:`SyntaxError`. - -- bpo-40521: Empty frozensets are no longer singletons. - -- bpo-41076: Pre-feed the parser with the location of the f-string - expression, not the f-string itself, which allows us to skip the shifting - of the AST node locations after the parsing is completed. - -- bpo-41056: Fixes a reference to deallocated stack space during startup - when constructing sys.path involving a relative symlink when code was - supplied via -c. (discovered via Coverity) - -- bpo-41061: Fix incorrect expressions and asserts in hashtable code and - tests. - -- bpo-41052: Opt out serialization/deserialization for _random.Random - -- bpo-40939: Rename `PyPegen*` functions to `PyParser*`, so that we can - remove the old set of `PyParser*` functions that were using the old - parser, but keep everything backwards-compatible. - -- bpo-35975: Stefan Behnel reported that cf_feature_version is used even - when PyCF_ONLY_AST is not set. This is against the intention and against - the documented behavior, so it's been fixed. - -- bpo-40939: Remove the remaining files from the old parser and the - :mod:`symbol` module. - -- bpo-40077: Convert :mod:`_bz2` to use :c:func:`PyType_FromSpec`. - -- bpo-41006: The ``encodings.latin_1`` module is no longer imported at - startup. Now it is only imported when it is the filesystem encoding or the - stdio encoding. - -- bpo-40636: :func:`zip` now supports :pep:`618`'s ``strict`` parameter, - which raises a :exc:`ValueError` if the arguments are exhausted at - different lengths. Patch by Brandt Bucher. - -- bpo-1635741: Port :mod:`_gdbm` to multiphase initialization. - -- bpo-40985: Fix a bug that caused the :exc:`SyntaxError` text to be empty - when a file ends with a line ending in a line continuation character (i.e. - backslash). The error text should contain the text of the last line. - -- bpo-40958: Fix a possible buffer overflow in the PEG parser when gathering - information for emitting syntax errors. Patch by Pablo Galindo. - -- bpo-1635741: Port :mod:`_dbm` to multiphase initialization. - -- bpo-40957: Fix refleak in _Py_fopen_obj() when PySys_Audit() fails - -- bpo-40950: Add a state to the :mod:`nis` module (:pep:`3121`) and apply - the multiphase initialization. Patch by Dong-hee Na. - -- bpo-40947: The Python :ref:`Path Configuration <init-path-config>` now - takes :c:member:`PyConfig.platlibdir` in account. - -- bpo-40939: Remove the old parser, the :mod:`parser` module and all - associated support code, command-line options and environment variables. - Patch by Pablo Galindo. - -- bpo-40847: Fix a bug where a line with only a line continuation character - is not considered a blank line at tokenizer level. In such cases, more - than a single `NEWLINE` token was emitted. The old parser was working - around the issue, but the new parser threw a :exc:`SyntaxError` for valid - input due to this. For example, an empty line following a line - continuation character was interpreted as a :exc:`SyntaxError`. - -- bpo-40890: Each dictionary view now has a ``mapping`` attribute that - provides a :class:`types.MappingProxyType` wrapping the original - dictionary. Patch contributed by Dennis Sweeney. - -- bpo-40889: Improved the performance of symmetric difference operations on - dictionary item views. Patch by Dennis Sweeney. - -- bpo-40904: Fix possible segfault in the new PEG parser when parsing - f-string containing yield statements with no value (:code:`f"{yield}"`). - Patch by Pablo Galindo - -- bpo-40903: Fixed a possible segfault in the new PEG parser when producing - error messages for invalid assignments of the form :code:`p=p=`. Patch by - Pablo Galindo - -- bpo-40880: Fix invalid memory read in the new parser when checking - newlines in string literals. Patch by Pablo Galindo. - -- bpo-40883: Fix memory leak in when parsing f-strings in the new parser. - Patch by Pablo Galindo - -- bpo-40870: Raise :exc:`ValueError` when validating custom AST's where the - constants ``True``, ``False`` and ``None`` are used within a - :class:`ast.Name` node. - -- bpo-40854: Allow overriding :data:`sys.platlibdir` via a new - :envvar:`PYTHONPLATLIBDIR` environment variable. - -- bpo-40826: Fix GIL usage in :c:func:`PyOS_Readline`: lock the GIL to set - an exception and pass the Python thread state when checking if there is a - pending signal. - -- bpo-1635741: Port :mod:`fcntl` to multiphase initialization. - -- bpo-19468: Delete unnecessary instance check in importlib.reload(). Patch - by Furkan Önder. - -- bpo-40824: Unexpected errors in calling the ``__iter__`` method are no - longer masked by ``TypeError`` in the :keyword:`in` operator and functions - :func:`~operator.contains`, :func:`~operator.indexOf` and - :func:`~operator.countOf` of the :mod:`operator` module. - -- bpo-40792: Attributes ``start``, ``stop`` and ``step`` of the - :class:`range` object now always has exact type :class:`int`. Previously, - they could have been an instance of a subclass of ``int``. - -- bpo-40780: Fix a corner case where g-style string formatting of a float - failed to remove trailing zeros. - -- bpo-38964: When there's a :exc:`SyntaxError` in the expression part of an - fstring, the filename attribute of the :exc:`SyntaxError` gets correctly - set to the name of the file the fstring resides in. - -- bpo-40750: Support the "-d" debug flag in the new PEG parser. Patch by - Pablo Galindo - -- bpo-40217: Instances of types created with - :c:func:`PyType_FromSpecWithBases` will no longer automatically visit - their class object when traversing references in the garbage collector. - The user is expected to manually visit the object's class. Patch by Pablo - Galindo. - -- bpo-39573: :c:func:`Py_TYPE()` is changed to the inline static function. - Patch by Dong-hee Na. - -- bpo-40696: Fix a hang that can arise after :meth:`generator.throw` due to - a cycle in the exception context chain. - -- bpo-40521: Each interpreter now its has own free lists, singletons and - caches: - - * Free lists: float, tuple, list, dict, frame, context, - asynchronous generator, MemoryError. - * Singletons: empty tuple, empty bytes string, empty Unicode string, - single byte character, single Unicode (latin1) character. - * Slice cache. - - They are no longer shared by all interpreters. - -- bpo-40679: Certain :exc:`TypeError` messages about missing or extra - arguments now include the function's :term:`qualified name`. Patch by - Dennis Sweeney. - -- bpo-29590: Make the stack trace correct after calling - :meth:`generator.throw` on a generator that has yielded from a ``yield - from``. - -- bpo-4022: Improve performance of generators by not raising internal - StopIteration. - -- bpo-1635741: Port :mod:`mmap` to multiphase initialization. - -- bpo-1635741: Port :mod:`_lzma` to multiphase initialization. - -- bpo-37999: Builtin and extension functions that take integer arguments no - longer accept :class:`~decimal.Decimal`\ s, :class:`~fractions.Fraction`\ - s and other objects that can be converted to integers only with a loss - (e.g. that have the :meth:`~object.__int__` method but do not have the - :meth:`~object.__index__` method). - -- bpo-29882: Add :meth:`int.bit_count()`, counting the number of ones in the - binary representation of an integer. Patch by Niklas Fiekas. - -- bpo-36982: Use ncurses extended color functions when available to support - terminals with 256 colors, and add the new function - :func:`curses.has_extended_color_support` to indicate whether extended - color support is provided by the underlying ncurses library. - -- bpo-19569: Add the private macros ``_Py_COMP_DIAG_PUSH``, - ``_Py_COMP_DIAG_IGNORE_DEPR_DECLS``, and ``_Py_COMP_DIAG_POP``. - -- bpo-26680: The int type now supports the x.is_integer() method for - compatibility with float. - -Library -------- - -- bpo-41900: C14N 2.0 serialisation in xml.etree.ElementTree failed for - unprefixed attributes when a default namespace was defined. - -- bpo-41887: Strip leading spaces and tabs on :func:`ast.literal_eval`. Also - document stripping of spaces and tabs for :func:`eval`. - -- bpo-41773: Note in documentation that :func:`random.choices` doesn't - support non-finite weights, raise :exc:`ValueError` when given non-finite - weights. - -- bpo-41840: Fix a bug in the :mod:`symtable` module that was causing - module-scope global variables to not be reported as both local and global. - Patch by Pablo Galindo. - -- bpo-41842: Add :func:`codecs.unregister` function to unregister a codec - search function. - -- bpo-40564: In ``zipfile.Path``, mutate the passed ZipFile object type - instead of making a copy. Prevents issues when both the local copy and the - caller’s copy attempt to close the same file handle. - -- bpo-40670: More reliable validation of statements in - :class:`timeit.Timer`. It now accepts "empty" statements (only whitespaces - and comments) and rejects misindentent statements. - -- bpo-41833: The :class:`threading.Thread` constructor now uses the target - name if the *target* argument is specified but the *name* argument is - omitted. - -- bpo-41817: fix `tkinter.EventType` Enum so all members are strings, and - none are tuples - -- bpo-41810: :data:`types.EllipsisType`, :data:`types.NotImplementedType` - and :data:`types.NoneType` have been reintroduced, providing a new set of - types readily interpretable by static type checkers. - -- bpo-41815: Fix SQLite3 segfault when backing up closed database. Patch - contributed by Peter David McCormick. - -- bpo-41816: StrEnum added: it ensures that all members are already strings - or string candidates - -- bpo-41517: fix bug allowing Enums to be extended via multiple inheritance - -- bpo-39587: use the correct mix-in data type when constructing Enums - -- bpo-41792: Add is_typeddict function to typing.py to check if a type is a - TypedDict class - - Previously there was no way to check that without using private API. See - the `relevant issue in python/typing - <https://github.com/python/typing/issues/751>` - -- bpo-41789: Honor `object` overrides in `Enum` class creation - (specifically, `__str__`, `__repr__`, `__format__`, and `__reduce_ex__`). - -- bpo-32218: `enum.Flag` and `enum.IntFlag` members are now iterable - -- bpo-39651: Fix a race condition in the ``call_soon_threadsafe()`` method - of ``asyncio.ProactorEventLoop``: do nothing if the self-pipe socket has - been closed. - -- bpo-1635741: Port the ``mashal`` extension module to the multi-phase - initialization API (:pep:`489`). - -- bpo-1635741: Port the ``_string`` extension module to the multi-phase - initialization API (:pep:`489`). - -- bpo-41732: Added an :term:`iterator` to :class:`memoryview`. - -- bpo-41720: Fixed :meth:`turtle.Vec2D.__rmul__` for arguments which are not - int or float. - -- bpo-41696: Fix handling of debug mode in :func:`asyncio.run`. This allows - setting ``PYTHONASYNCIODEBUG`` or ``-X dev`` to enable asyncio debug mode - when using :func:`asyncio.run`. - -- bpo-41687: Fix implementation of sendfile to be compatible with Solaris. - -- bpo-41662: No longer override exceptions raised in ``__len__()`` of a - sequence of parameters in :mod:`sqlite3` with - :exc:`~sqlite3.ProgrammingError`. - -- bpo-39010: Restarting a ``ProactorEventLoop`` on Windows no longer logs - spurious ``ConnectionResetErrors``. - -- bpo-41638: :exc:`~sqlite3.ProgrammingError` message for absent parameter - in :mod:`sqlite3` contains now the name of the parameter instead of its - index when parameters are supplied as a dict. - -- bpo-41662: Fixed crash when mutate list of parameters during iteration in - :mod:`sqlite3`. - -- bpo-41513: Improved the accuracy of math.hypot(). Internally, each step - is computed with extra precision so that the result is now almost always - correctly rounded. - -- bpo-41609: The pdb whatis command correctly reports instance methods as - 'Method' rather than 'Function'. - -- bpo-39994: Fixed pprint's handling of dict subclasses that override - __repr__. - -- bpo-32751: When cancelling the task due to a timeout, - :meth:`asyncio.wait_for` will now wait until the cancellation is complete - also in the case when *timeout* is <= 0, like it does with positive - timeouts. - -- bpo-37658: :meth:`asyncio.wait_for` now properly handles races between - cancellation of itself and the completion of the wrapped awaitable. - -- bpo-40782: Change the method asyncio.AbstractEventLoop.run_in_executor to - not be a coroutine. - -- bpo-41520: Fix :mod:`codeop` regression that prevented turning compile - warnings into errors. - -- bpo-41528: turtle uses math module functions to convert degrees to radians - and vice versa and to calculate vector norm - -- bpo-41513: Minor algorithmic improvement to math.hypot() and math.dist() - giving small gains in speed and accuracy. - -- bpo-41503: Fixed a race between setTarget and flush in - logging.handlers.MemoryHandler. - -- bpo-41497: Fix potential UnicodeDecodeError in dis module. - -- bpo-41467: On Windows, fix asyncio ``recv_into()`` return value when the - socket/pipe is closed (:exc:`BrokenPipeError`): return ``0`` rather than - an empty byte string (``b''``). - -- bpo-41425: Make tkinter doc example runnable. - -- bpo-41421: Make an algebraic simplification to random.paretovariate(). It - now is slightly less subject to round-off error and is slightly faster. - Inputs that used to cause ZeroDivisionError now cause an OverflowError - instead. - -- bpo-41440: Add :func:`os.cpu_count()` support for VxWorks RTOS. - -- bpo-41316: Fix the :mod:`tarfile` module to write only basename of TAR - file to GZIP compression header. - -- bpo-41384: Raise TclError instead of TypeError when an unknown option is - passed to tkinter.OptionMenu. - -- bpo-41317: Use add_done_callback() in asyncio.loop.sock_accept() to - unsubscribe reader early on cancellation. - -- bpo-41364: Reduce import overhead of :mod:`uuid`. - -- bpo-35328: Set the environment variable ``VIRTUAL_ENV_PROMPT`` at - :mod:`venv` activation. - -- bpo-41341: Recursive evaluation of `typing.ForwardRef` in - `get_type_hints`. - -- bpo-41344: Prevent creating :class:`shared_memory.SharedMemory` objects - with :code:`size=0`. - -- bpo-41333: :meth:`collections.OrderedDict.pop` is now 2 times faster. - -- bpo-41288: Unpickling invalid NEWOBJ_EX opcode with the C implementation - raises now UnpicklingError instead of crashing. - -- bpo-39017: Avoid infinite loop when reading specially crafted TAR files - using the tarfile module (CVE-2019-20907). - -- bpo-41273: Speed up any transport using ``_ProactorReadPipeTransport`` by - calling ``recv_into`` instead of ``recv``, thus not creating a new buffer - for each ``recv`` call in the transport's read loop. - -- bpo-41235: Fix the error handling in - :meth:`ssl.SSLContext.load_dh_params`. - -- bpo-41207: In distutils.spawn, restore expectation that DistutilsExecError - is raised when the command is not found. - -- bpo-29727: Register :class:`array.array` as a - :class:`~collections.abc.MutableSequence`. Patch by Pablo Galindo. - -- bpo-39168: Remove the ``__new__`` method of :class:`typing.Generic`. - -- bpo-41194: Fix a crash in the ``_ast`` module: it can no longer be loaded - more than once. It now uses a global state rather than a module state. - -- bpo-41195: Add read-only ssl.SSLContext.security_level attribute to - retrieve the context's security level. - -- bpo-41193: The ``write_history()`` atexit function of the readline - completer now ignores any :exc:`OSError` to ignore error if the filesystem - is read-only, instead of only ignoring :exc:`FileNotFoundError` and - :exc:`PermissionError`. - -- bpo-41182: selector: use DefaultSelector based upon implementation - -- bpo-41161: The decimal module now requires libmpdec-2.5.0. Users of - --with-system-libmpdec should update their system library. - -- bpo-40874: The decimal module now requires libmpdec-2.5.0. - -- bpo-41138: Fixed the :mod:`trace` module CLI for Python source files with - non-UTF-8 encoding. - -- bpo-31082: Use the term "iterable" in the docstring for - :func:`functools.reduce`. - -- bpo-40521: Remove freelist from collections.deque(). - -- bpo-31938: Fix default-value signatures of several functions in the - :mod:`select` module - by Anthony Sottile. - -- bpo-41068: Fixed reading files with non-ASCII names from ZIP archive - directly after writing them. - -- bpo-41058: :func:`pdb.find_function` now correctly determines the source - file encoding. - -- bpo-41056: Invalid file descriptor values are now prevented from being - passed to os.fpathconf. (discovered by Coverity) - -- bpo-41056: Fix a NULL pointer dereference within the ssl module during a - MemoryError in the keylog callback. (discovered by Coverity) - -- bpo-41056: Fixed an instance where a MemoryError within the zoneinfo - module might not be reported or not reported at its source. (found by - Coverity) - -- bpo-41048: :func:`mimetypes.read_mime_types` function reads the rule file - using UTF-8 encoding, not the locale encoding. Patch by Srinivas Reddy - Thatiparthy. - -- bpo-41043: Fixed the use of :func:`~glob.glob` in the stdlib: literal part - of the path is now always correctly escaped. - -- bpo-41025: Fixed an issue preventing the C implementation of - :class:`zoneinfo.ZoneInfo` from being subclassed. - -- bpo-35018: Add the :class:`xml.sax.handler.LexicalHandler` class that is - present in other SAX XML implementations. - -- bpo-41002: Improve performance of HTTPResponse.read with a given amount. - Patch by Bruce Merry. - -- bpo-40448: :mod:`ensurepip` now disables the use of `pip` cache when - installing the bundled versions of `pip` and `setuptools`. Patch by - Krzysztof Konopko. - -- bpo-40967: Removed :meth:`asyncio.Task.current_task` and - :meth:`asyncio.Task.all_tasks`. Patch contributed by Rémi Lapeyre. - -- bpo-40924: Ensure ``importlib.resources.path`` returns an extant path for - the SourceFileLoader's resource reader. Avoids the regression identified - in master while a long-term solution is devised. - -- bpo-40955: Fix a minor memory leak in :mod:`subprocess` module when - extra_groups was specified. - -- bpo-40855: The standard deviation and variance functions in the statistics - module were ignoring their mu and xbar arguments. - -- bpo-40939: Use the new PEG parser when generating the stdlib - :mod:`keyword` module. - -- bpo-23427: Add :data:`sys.orig_argv` attribute: the list of the original - command line arguments passed to the Python executable. - -- bpo-33689: Ignore empty or whitespace-only lines in .pth files. This - matches the documentated behavior. Before, empty lines caused the - site-packages dir to appear multiple times in sys.path. By Ido Michael, - contributors Malcolm Smith and Tal Einat. - -- bpo-40884: Added a `defaults` parameter to :class:`logging.Formatter`, to - allow specifying default values for custom fields. Patch by Asaf Alon and - Bar Harel. - -- bpo-40876: Clarify error message in the :mod:`csv` module. - -- bpo-39791: Refresh importlib.metadata from importlib_metadata 1.6.1. - -- bpo-40807: Stop codeop._maybe_compile, used by code.InteractiveInterpreter - (and IDLE). from emitting each warning three times. - -- bpo-32604: Fix reference leak in the :mod:`select` module when the module - is imported in a subinterpreter. - -- bpo-39791: Built-in loaders (SourceFileLoader and ZipImporter) now supply - ``TraversableResources`` implementations for ``ResourceReader``, and the - fallback function has been removed. - -- bpo-39314: :class:`rlcompleter.Completer` and the standard Python shell - now close the parenthesis for functions that take no arguments. Patch - contributed by Rémi Lapeyre. - -- bpo-17005: The topological sort functionality that was introduced - initially in the :mod:`functools` module has been moved to a new - :mod:`graphlib` module to better accommodate the new tools and keep the - original scope of the :mod:`functools` module. Patch by Pablo Galindo - -- bpo-40834: Fix truncate when sending str object - with_xxsubinterpreters.channel_send. - -- bpo-40755: Add rich comparisons to collections.Counter(). - -- bpo-26407: Unexpected errors in calling the ``__iter__`` method are no - longer masked by ``TypeError`` in :func:`csv.reader`, - :func:`csv.writer.writerow` and :meth:`csv.writer.writerows`. - -- bpo-39384: Fixed email.contentmanager to allow set_content() to set a null - string. - -- bpo-40744: The :mod:`sqlite3` module uses SQLite API functions that - require SQLite v3.7.3 or higher. This patch removes support for older - SQLite versions, and explicitly requires SQLite 3.7.3 both at build, - compile and runtime. Patch by Sergey Fedoseev and Erlend E. Aasland. - -- bpo-40777: Initialize PyDateTime_IsoCalendarDateType.tp_base at run-time - to avoid errors on some compilers. - -- bpo-38488: Update ensurepip to install pip 20.1.1 and setuptools 47.1.0. - -- bpo-40792: The result of :func:`operator.index` now always has exact type - :class:`int`. Previously, the result could have been an instance of a - subclass of ``int``. - -- bpo-40767: :mod:`webbrowser` now properly finds the default browser in - pure Wayland systems by checking the WAYLAND_DISPLAY environment variable. - Patch contributed by Jérémy Attali. - -- bpo-40791: :func:`hashlib.compare_digest` uses OpenSSL's - ``CRYPTO_memcmp()`` function when OpenSSL is available. - -- bpo-40795: :mod:`ctypes` module: If ctypes fails to convert the result of - a callback or if a ctypes callback function raises an exception, - sys.unraisablehook is now called with an exception set. Previously, the - error was logged into stderr by :c:func:`PyErr_Print`. - -- bpo-16995: Add :func:`base64.b32hexencode` and :func:`base64.b32hexdecode` - to support the Base32 Encoding with Extended Hex Alphabet. - -- bpo-30008: Fix :mod:`ssl` code to be compatible with OpenSSL 1.1.x builds - that use ``no-deprecated`` and ``--api=1.1.0``. - -- bpo-30064: Fix asyncio ``loop.sock_*`` race condition issue - -- bpo-40759: Deprecate the :mod:`symbol` module. - -- bpo-40756: The second argument (extra) of ``LoggerAdapter.__init__`` now - defaults to None. - -- bpo-37129: Add a new :data:`os.RWF_APPEND` flag for :func:`os.pwritev`. - -- bpo-40737: Fix possible reference leak for :mod:`sqlite3` initialization. - -- bpo-40726: Handle cases where the ``end_lineno`` is ``None`` on - :func:`ast.increment_lineno`. - -- bpo-40698: :mod:`distutils` upload creates SHA2-256 and Blake2b-256 - digests. MD5 digests is skipped if platform blocks MD5. - -- bpo-40695: :mod:`hashlib` no longer falls back to builtin hash - implementations when OpenSSL provides a hash digest and the algorithm is - blocked by security policy. - -- bpo-9216: func:`hashlib.new` passed ``usedforsecurity`` to OpenSSL EVP - constructor ``_hashlib.new()``. test_hashlib and test_smtplib handle - strict security policy better. - -- bpo-40614: :func:`ast.parse` will not parse self documenting expressions - in f-strings when passed ``feature_version`` is less than ``(3, 8)``. - -- bpo-40626: Add h5 file extension as MIME Type application/x-hdf5, as per - HDF Group recommendation for HDF5 formatted data files. Patch contributed - by Mark Schwab. - -- bpo-25920: On macOS, when building Python for macOS 10.4 and older, which - wasn't the case for python.org macOS installer, :func:`socket.getaddrinfo` - no longer uses an internal lock to prevent race conditions when calling - ``getaddrinfo()`` which is thread-safe since macOS 10.5. Python 3.9 - requires macOS 10.6 or newer. The internal lock caused random hang on fork - when another thread was calling :func:`socket.getaddrinfo`. The lock was - also used on FreeBSD older than 5.3, OpenBSD older than 201311 and NetBSD - older than 4. - -- bpo-40671: Prepare ``_hashlib`` for :pep:`489` and use - :c:func:`PyModule_AddType`. - -- bpo-32309: Added a new :term:`coroutine` :func:`asyncio.to_thread`. It is - mainly used for running IO-bound functions in a separate thread to avoid - blocking the event loop, and essentially works as a high-level version of - :meth:`~asyncio.loop.run_in_executor` that can directly take keyword - arguments. - -- bpo-36543: Restored the deprecated :mod:`xml.etree.cElementTree` module. - -- bpo-40611: :data:`~mmap.MAP_POPULATE` constant has now been added to the - list of exported :mod:`mmap` module flags. - -- bpo-39881: PEP 554 for use in the test suite. (Patch By Joannah Nanjekye) - -- bpo-13097: ``ctypes`` now raises an ``ArgumentError`` when a callback is - invoked with more than 1024 arguments. - -- bpo-39385: A new test assertion context-manager, - :func:`unittest.assertNoLogs` will ensure a given block of code emits no - log messages using the logging module. Contributed by Kit Yan Choi. - -- bpo-23082: Updated the error message and docs of PurePath.relative_to() to - better reflect the function behaviour. - -- bpo-40318: Use SQLite3 trace v2 API, if it is available. - -- bpo-40105: ZipFile truncates files to avoid corruption when a shorter - comment is provided in append ("a") mode. Patch by Jan Mazur. - -- bpo-40084: Fix ``Enum.__dir__``: dir(Enum.member) now includes attributes - as well as methods. - -- bpo-31122: ssl.wrap_socket() now raises ssl.SSLEOFError rather than - OSError when peer closes connection during TLS negotiation - -- bpo-39728: fix default `_missing_` so a duplicate `ValueError` is not set - as the `__context__` of the original `ValueError` - -- bpo-39244: Fixed :class:`multiprocessing.context.get_all_start_methods` to - properly return the default method first on macOS. - -- bpo-39040: Fix parsing of invalid mime headers parameters by collapsing - whitespace between encoded words in a bare-quote-string. - -- bpo-38731: Add ``--quiet`` option to command-line interface of - :mod:`py_compile`. Patch by Gregory Schevchenko. - -- bpo-35714: :exc:`struct.error` is now raised if there is a null character - in a :mod:`struct` format string. - -- bpo-38144: Added the *root_dir* and *dir_fd* parameters in - :func:`glob.glob`. - -- bpo-26543: Fix :meth:`IMAP4.noop()` when debug mode is enabled (ex: - ``imaplib.Debug = 3``). - -- bpo-12178: :func:`csv.writer` now correctly escapes *escapechar* when - input contains *escapechar*. Patch by Catalin Iacob, Berker Peksag, and - Itay Elbirt. - -- bpo-36290: AST nodes are now raising :exc:`TypeError` on conflicting - keyword arguments. Patch contributed by Rémi Lapeyre. - -- bpo-33944: Added site.py site-packages tracing in verbose mode. - -- bpo-35078: Refactor formatweekday, formatmonthname methods in - LocaleHTMLCalendar and LocaleTextCalendar classes in calendar module to - call the base class methods.This enables customizable CSS classes for - LocaleHTMLCalendar. Patch by Srinivas Reddy Thatiparthy - -- bpo-29620: :func:`~unittest.TestCase.assertWarns` no longer raises a - ``RuntimeException`` when accessing a module's ``__warningregistry__`` - causes importation of a new module, or when a new module is imported in - another thread. Patch by Kernc. - -- bpo-31844: Remove ``ParserBase.error()`` method from the private and - undocumented ``_markupbase`` module. :class:`html.parser.HTMLParser` is - the only subclass of ``ParserBase`` and its ``error()`` implementation was - deprecated in Python 3.4 and removed in Python 3.5. - -- bpo-34226: Fix `cgi.parse_multipart` without content_length. Patch by - Roger Duran - -- bpo-33660: Fix pathlib.PosixPath to resolve a relative path located on the - root directory properly. - -- bpo-28557: Improve the error message for a misbehaving ``rawio.readinto`` - -- bpo-26680: The d.is_integer() method is added to the Decimal type, for - compatibility with other number types. - -- bpo-26680: The x.is_integer() method is incorporated into the abstract - types of the numeric tower, Real, Rational and Integral, with appropriate - default implementations. - -Documentation -------------- - -- bpo-41428: Add documentation for :pep:`604` (Allow writing union types as - ``X | Y``). - -- bpo-41774: In Programming FAQ "Sequences (Tuples/Lists)" section, add "How - do you remove multiple items from a list". - -- bpo-35293: Fix RemovedInSphinx40Warning when building the documentation. - Patch by Dong-hee Na. - -- bpo-37149: Change Shipman tkinter doc link from archive.org to TkDocs. - (The doc has been removed from the NMT server.) The new link responds - much faster and includes a short explanatory note. - -- bpo-41726: Update the refcounts info of ``PyType_FromModuleAndSpec``. - -- bpo-41624: Fix the signature of :class:`typing.Coroutine`. - -- bpo-40204: Enable Sphinx 3.2 ``c_allow_pre_v3`` option and disable - ``c_warn_on_allowed_pre_v3`` option to make the documentation compatible - with Sphinx 2 and Sphinx 3. - -- bpo-41045: Add documentation for debug feature of f-strings. - -- bpo-41314: Changed the release when ``from __future__ import annotations`` - becomes the default from ``4.0`` to ``3.10`` (following a change in PEP - 563). - -- bpo-40979: Refactored typing.rst, arranging more than 70 classes, - functions, and decorators into new sub-sections. - -- bpo-40552: Fix in tutorial section 4.2. Code snippet is now correct. - -- bpo-39883: Make code, examples, and recipes in the Python documentation be - licensed under the more permissive BSD0 license in addition to the - existing Python 2.0 license. - -- bpo-37703: Updated Documentation to comprehensively elaborate on the - behaviour of gather.cancel() - -Tests ------ - -- bpo-41939: Fix test_site.test_license_exists_at_url(): call - ``urllib.request.urlcleanup()`` to reset the global - ``urllib.request._opener``. Patch by Victor Stinner. - -- bpo-41731: Make test_cmd_line_script pass with option '-vv'. - -- bpo-41602: Add tests for SIGINT handling in the runpy module. - -- bpo-41521: :mod:`test.support`: Rename ``blacklist`` parameter of - :func:`~test.support.check__all__` to ``not_exported``. - -- bpo-41477: Make ctypes optional in test_genericalias. - -- bpo-41085: Fix integer overflow in the :meth:`array.array.index` method on - 64-bit Windows for index larger than ``2**31``. - -- bpo-41069: :data:`test.support.TESTFN` and the current directory for tests - when run via ``test.regrtest`` contain now non-ascii characters if - possible. - -- bpo-38377: On Linux, skip tests using multiprocessing if the current user - cannot create a file in ``/dev/shm/`` directory. Add the - :func:`~test.support.skip_if_broken_multiprocessing_synchronize` function - to the :mod:`test.support` module. - -- bpo-41009: Fix use of ``support.require_{linux|mac|freebsd}_version()`` - decorators as class decorator. - -- bpo-41003: Fix ``test_copyreg`` when ``numpy`` is installed: - ``test.pickletester`` now saves/restores warnings filters when importing - ``numpy``, to ignore filters installed by ``numpy``. - -- bpo-40964: Disable remote :mod:`imaplib` tests, host cyrus.andrew.cmu.edu - is blocking incoming connections. - -- bpo-40927: Fix test_binhex when run twice: it now uses - import_fresh_module() to ensure that it raises DeprecationWarning each - time. - -- bpo-17258: Skip some :mod:`multiprocessing` tests when MD5 hash digest is - blocked. - -- bpo-31904: Increase LOOPBACK_TIMEOUT to 10 for VxWorks RTOS. - -- bpo-38169: Increase code coverage for SharedMemory and ShareableList - -- bpo-34401: Make test_gdb properly run on HP-UX. Patch by Michael Osipov. - -Build ------ - -- bpo-38249: Update :c:macro:`Py_UNREACHABLE` to use __builtin_unreachable() - if only the compiler is able to use it. Patch by Dong-hee Na. - -- bpo-41617: Fix ``pycore_bitutils.h`` header file to support old clang - versions: ``__builtin_bswap16()`` is not available in LLVM clang 3.0. - -- bpo-40204: Pin Sphinx version to 2.3.1 in ``Doc/Makefile``. - -- bpo-36020: The C99 functions :c:func:`snprintf` and :c:func:`vsnprintf` - are now required to build Python. - -- bpo-40684: ``make install`` now uses the ``PLATLIBDIR`` variable for the - destination ``lib-dynload/`` directory when ``./configure - --with-platlibdir`` is used. - -- bpo-40683: Fixed an issue where the :mod:`zoneinfo` module and its tests - were not included when Python is installed with ``make``. - -Windows -------- - -- bpo-41744: Fixes automatic import of props file when using the Nuget - package. - -- bpo-41627: The user site directory for 32-bit now includes a ``-32`` - suffix to distinguish it from the 64-bit interpreter's directory. - -- bpo-41526: Fixed layout of final page of the installer by removing the - special thanks to Mark Hammond (with his permission). - -- bpo-41492: Fixes the description that appears in UAC prompts. - -- bpo-40948: Improve post-install message to direct people to the "py" - command. - -- bpo-41412: The installer will now fail to install on Windows 7 and Windows - 8. Further, the UCRT dependency is now always downloaded on demand. - -- bpo-40741: Update Windows release to include SQLite 3.32.3. - -- bpo-41142: :mod:`msilib` now supports creating CAB files with non-ASCII - file path and adding files with non-ASCII file path to them. - -- bpo-41074: Fixed support of non-ASCII names in functions - :func:`msilib.OpenDatabase` and :func:`msilib.init_database` and non-ASCII - SQL in method :meth:`msilib.Database.OpenView`. - -- bpo-41039: Stable ABI redirection DLL (python3.dll) now uses ``#pragma - comment(linker)`` for re-exporting. - -- bpo-40164: Updates Windows OpenSSL to 1.1.1g - -- bpo-39631: Changes the registered MIME type for ``.py`` files on Windows - to ``text/x-python`` instead of ``text/plain``. - -- bpo-40677: Manually define IO_REPARSE_TAG_APPEXECLINK in case some old - Windows SDK doesn't have it. - -- bpo-37556: Extend py.exe help to mention overrides via venv, shebang, - environmental variables & ini files. - -macOS ------ - -- bpo-41557: Update macOS installer to use SQLite 3.33.0. - -- bpo-39580: Avoid opening Finder window if running installer from the - command line. Patch contributed by Rick Heil. - -- bpo-41100: Fix configure error when building on macOS 11. Note that the - current Python release was released shortly after the first developer - preview of macOS 11 (Big Sur); there are other known issues with building - and running on the developer preview. Big Sur is expected to be fully - supported in a future bugfix release of Python 3.8.x and with 3.9.0. - -- bpo-40741: Update macOS installer to use SQLite 3.32.3. - -- bpo-41005: fixed an XDG settings issue not allowing macos to open browser - in webbrowser.py - -- bpo-40741: Update macOS installer to use SQLite 3.32.2. - -IDLE ----- - -- bpo-41775: Use 'IDLE Shell' as shell title - -- bpo-35764: Rewrite the Calltips doc section. - -- bpo-40181: In calltips, stop reminding that '/' marks the end of - positional-only arguments. - -- bpo-41468: Improve IDLE run crash error message (which users should never - see). - -- bpo-41373: Save files loaded with no line ending, as when blank, or - different line endings, by setting its line ending to the system default. - Fix regression in 3.8.4 and 3.9.0b4. - -- bpo-41300: Save files with non-ascii chars. Fix regression released in - 3.9.0b4 and 3.8.4. - -- bpo-37765: Add keywords to module name completion list. Rewrite - Completions section of IDLE doc. - -- bpo-41152: The encoding of ``stdin``, ``stdout`` and ``stderr`` in IDLE is - now always UTF-8. - -- bpo-41144: Make Open Module open a special module such as os.path. - -- bpo-39885: Make context menu Cut and Copy work again when right-clicking - within a selection. - -- bpo-40723: Make test_idle pass when run after import. - -C API ------ - -- bpo-41936: Removed undocumented macros ``Py_ALLOW_RECURSION`` and - ``Py_END_ALLOW_RECURSION`` and the ``recursion_critical`` field of the - :c:type:`PyInterpreterState` structure. - -- bpo-41692: The ``PyUnicode_InternImmortal()`` function is now deprecated - and will be removed in Python 3.12: use :c:func:`PyUnicode_InternInPlace` - instead. Patch by Victor Stinner. - -- bpo-41842: Add :c:func:`PyCodec_Unregister` function to unregister a codec - search function. - -- bpo-41834: Remove the ``_Py_CheckRecursionLimit`` variable: it has been - replaced by ``ceval.recursion_limit`` of the :c:type:`PyInterpreterState` - structure. Patch by Victor Stinner. - -- bpo-41689: Types created with :c:func:`PyType_FromSpec` now make any - signature in their ``tp_doc`` slot accessible from ``__text_signature__``. - -- bpo-41524: Fix bug in PyOS_mystrnicmp and PyOS_mystricmp that incremented - pointers beyond the end of a string. - -- bpo-41324: Add a minimal decimal capsule API. The API supports fast - conversions between Decimals up to 38 digits and their triple - representation as a C struct. - -- bpo-30155: Add :c:func:`PyDateTime_DATE_GET_TZINFO` and - :c:func:`PyDateTime_TIME_GET_TZINFO` macros for accessing the ``tzinfo`` - attributes of :class:`datetime.datetime` and :class:`datetime.time` - objects. - -- bpo-40170: Revert :c:func:`PyType_HasFeature` change: it reads again - directly the :c:member:`PyTypeObject.tp_flags` member when the limited C - API is not used, rather than always calling :c:func:`PyType_GetFlags` - which hides implementation details. - -- bpo-41123: Remove ``PyUnicode_AsUnicodeCopy``. - -- bpo-41123: Removed ``PyLong_FromUnicode()``. - -- bpo-41123: Removed ``PyUnicode_GetMax()``. - -- bpo-41123: Removed ``Py_UNICODE_str*`` functions manipulating - ``Py_UNICODE*`` strings. - -- bpo-41103: ``PyObject_AsCharBuffer()``, ``PyObject_AsReadBuffer()``, - ``PyObject_CheckReadBuffer()``, and ``PyObject_AsWriteBuffer()`` are - removed. Please migrate to new buffer protocol; - :c:func:`PyObject_GetBuffer` and :c:func:`PyBuffer_Release`. - -- bpo-36346: Raises DeprecationWarning for ``PyUnicode_FromUnicode(NULL, - size)`` and ``PyUnicode_FromStringAndSize(NULL, size)`` with ``size > 0``. - -- bpo-36346: Mark ``Py_UNICODE_COPY``, ``Py_UNICODE_FILL``, - ``PyUnicode_WSTR_LENGTH``, ``PyUnicode_FromUnicode``, - ``PyUnicode_AsUnicode``, and ``PyUnicode_AsUnicodeAndSize`` as deprecated - in C. Remove ``Py_UNICODE_MATCH`` which was deprecated and broken since - Python 3.3. - -- bpo-40989: The :c:func:`PyObject_INIT` and :c:func:`PyObject_INIT_VAR` - macros become aliases to, respectively, :c:func:`PyObject_Init` and - :c:func:`PyObject_InitVar` functions. - -- bpo-36020: On Windows, ``#include "pyerrors.h"`` no longer defines - ``snprintf`` and ``vsnprintf`` macros. - -- bpo-40943: The ``PY_SSIZE_T_CLEAN`` macro must now be defined to use - :c:func:`PyArg_ParseTuple` and :c:func:`Py_BuildValue` formats which use - ``#``: ``es#``, ``et#``, ``s#``, ``u#``, ``y#``, ``z#``, ``U#`` and - ``Z#``. See :ref:`Parsing arguments and building values <arg-parsing>` and - the :pep:`353`. - -- bpo-40910: Export explicitly the :c:func:`Py_GetArgcArgv` function to the - C API and document the function. Previously, it was exported implicitly - which no longer works since Python is built with ``-fvisibility=hidden``. - -- bpo-40724: Allow defining buffer slots in type specs. - -- bpo-40679: Fix a ``_PyEval_EvalCode()`` crash if *qualname* argument is - NULL. - -- bpo-40839: Calling :c:func:`PyDict_GetItem` without :term:`GIL` held had - been allowed for historical reason. It is no longer allowed. - -- bpo-40826: :c:func:`PyOS_InterruptOccurred` now fails with a fatal error - if it is called with the GIL released. - -- bpo-40792: The result of :c:func:`PyNumber_Index` now always has exact - type :class:`int`. Previously, the result could have been an instance of a - subclass of ``int``. - -- bpo-39573: Convert :c:func:`Py_REFCNT` and :c:func:`Py_SIZE` macros to - static inline functions. They cannot be used as l-value anymore: use - :c:func:`Py_SET_REFCNT` and :c:func:`Py_SET_SIZE` to set an object - reference count and size. This change is backward incompatible on purpose, - to prepare the C API for an opaque :c:type:`PyObject` structure. - -- bpo-40703: The PyType_FromSpec*() functions no longer overwrite the type's - "__module__" attribute if it is set via "Py_tp_members" or "Py_tp_getset". - -- bpo-39583: Remove superfluous "extern C" declarations from - ``Include/cpython/*.h``. - - -What's New in Python 3.9.0 beta 1? -================================== - -*Release date: 2020-05-19* - -Security --------- - -- bpo-40501: :mod:`uuid` no longer uses :mod:`ctypes` to load - :file:`libuuid` or :file:`rpcrt4.dll` at runtime. - -Core and Builtins ------------------ - -- bpo-40663: Correctly generate annotations where parentheses are omitted - but required (e.g: ``Type[(str, int, *other))]``. - -- bpo-40596: Fixed :meth:`str.isidentifier` for non-canonicalized strings - containing non-BMP characters on Windows. - -- bpo-40593: Improved syntax errors for invalid characters in source code. - -- bpo-40585: Fixed a bug when using :func:`codeop.compile_command` that was - causing exceptions to be swallowed with the new parser. Patch by Pablo - Galindo - -- bpo-40566: Apply :pep:`573` to :mod:`abc`. - -- bpo-40502: Initialize ``n->n_col_offset``. (Patch by Joannah Nanjekye) - -- bpo-40527: Fix command line argument parsing: no longer write errors - multiple times into stderr. - -- bpo-1635741: Port :mod:`errno` to multiphase initialization (:pep:`489`). - -- bpo-40523: Add pass-throughs for :func:`hash` and :func:`reversed` to - :class:`weakref.proxy` objects. Patch by Pablo Galindo. - -- bpo-1635741: Port :mod:`syslog` to multiphase initialization (:pep:`489`). - -- bpo-40246: Reporting a specialised error message for invalid string - prefixes, which was introduced in :issue:`40246`, is being reverted due to - backwards compatibility concerns for strings that immediately follow a - reserved keyword without whitespace between them. Constructs like - `bg="#d00" if clear else"#fca"` were failing to parse, which is not an - acceptable breakage on such short notice. - -- bpo-40417: Fix imp module deprecation warning when PyImport_ReloadModule - is called. Patch by Robert Rouhani. - -- bpo-40408: Fixed support of nested type variables in GenericAlias (e.g. - ``list[list[T]]``). - -- bpo-1635741: Port _stat module to multiphase initialization (:pep:`489`). - -- bpo-29587: Enable implicit exception chaining when calling - :meth:`generator.throw`. - -- bpo-40328: Add tools for generating mappings headers for CJKCodecs. - -- bpo-40228: Setting frame.f_lineno is now robust w.r.t. changes in the - source-to-bytecode compiler - -- bpo-38880: Added the ability to list interpreters associated with channel - ends in the internal subinterpreters module. - -- bpo-37986: Improve performance of :c:func:`PyLong_FromDouble` for values - that fit into :c:expr:`long`. - -Library -------- - -- bpo-40662: Fixed :func:`ast.get_source_segment` for ast nodes that have - incomplete location information. Patch by Irit Katriel. - -- bpo-40665: Convert :mod:`bisect` to use Argument Clinic. - -- bpo-40536: Added the :func:`~zoneinfo.available_timezones` function to the - :mod:`zoneinfo` module. Patch by Paul Ganssle. - -- bpo-40645: The :class:`hmac.HMAC` exposes internal implementation details. - The attributes ``digest_cons``, ``inner``, and ``outer`` are deprecated - and will be removed in the future. - -- bpo-40645: The internal module ``_hashlib`` wraps and exposes OpenSSL's - HMAC API. The new code will be used in Python 3.10 after the internal - implementation details of the pure Python HMAC module are no longer part - of the public API. - -- bpo-40637: Builtin hash modules can now be disabled or selectively enabled - with ``configure --with-builtin-hashlib-hashes=sha3,blake1`` or - ``--without-builtin-hashlib-hashes``. - -- bpo-37630: The :mod:`hashlib` module can now use SHA3 hashes and SHAKE XOF - from OpenSSL when available. - -- bpo-40479: The :mod:`hashlib` now compiles with OpenSSL 3.0.0-alpha2. - -- bpo-40257: Revert changes to :func:`inspect.getdoc`. - -- bpo-40607: When cancelling a task due to timeout, :meth:`asyncio.wait_for` - will now propagate the exception if an error happens during cancellation. - Patch by Roman Skurikhin. - -- bpo-40612: Fix edge cases in SyntaxError formatting. If the offset is <= - 0, no caret is printed. If the offset is > line length, the caret is - printed pointing just after the last character. - -- bpo-40597: If text content lines are longer than policy.max_line_length, - always use a content-encoding to make sure they are wrapped. - -- bpo-40571: Added functools.cache() as a simpler, more discoverable way to - access the unbounded cache variant of lru_cache(maxsize=None). - -- bpo-40503: :pep:`615`, the :mod:`zoneinfo` module. Adds support for the - IANA time zone database. - -- bpo-40397: Removed attributes ``__args__`` and ``__parameters__`` from - special generic aliases like ``typing.List`` (not subscripted). - -- bpo-40549: Convert posixmodule.c ("posix" or "nt" module) to the - multiphase initialization (PEP 489). - -- bpo-31033: Add a ``msg`` argument to :meth:`Future.cancel` and - :meth:`Task.cancel`. - -- bpo-40541: Added an optional *counts* parameter to random.sample(). - -- bpo-40515: The :mod:`ssl` and :mod:`hashlib` modules now actively check - that OpenSSL is build with thread support. Python 3.7.0 made thread - support mandatory and no longer works safely with a no-thread builds. - -- bpo-31033: When a :class:`asyncio.Task` is cancelled, the exception - traceback now chains all the way back to where the task was first - interrupted. - -- bpo-40504: :func:`functools.lru_cache` objects can now be the targets of - weakrefs. - -- bpo-40559: Fix possible memory leak in the C implementation of - :class:`asyncio.Task`. - -- bpo-40480: ``fnmatch.fnmatch()`` could take exponential time in the - presence of multiple ``*`` pattern characters. This was repaired by - generating more elaborate regular expressions to avoid futile - backtracking. - -- bpo-40495: :mod:`compileall` is now able to use hardlinks to prevent - duplicates in a case when ``.pyc`` files for different optimization levels - have the same content. - -- bpo-40457: The ssl module now support OpenSSL builds without TLS 1.0 and - 1.1 methods. - -- bpo-40355: Improve error reporting in :func:`ast.literal_eval` in the - presence of malformed :class:`ast.Dict` nodes instead of silently ignoring - any non-conforming elements. Patch by Curtis Bucher. - -- bpo-40465: Deprecated the optional *random* argument to - *random.shuffle()*. - -- bpo-40459: :func:`platform.win32_ver` now produces correct *ptype* strings - instead of empty strings. - -- bpo-39435: The first argument of :func:`pickle.loads` is now - positional-only. - -- bpo-39305: Update :mod:`nntplib` to merge :class:`nntplib.NNTP` and - :class:`nntplib._NNTPBase`. Patch by Dong-hee Na. - -- bpo-32494: Update :mod:`dbm.gnu` to use gdbm_count if possible when - calling :func:`len`. Patch by Dong-hee Na. - -- bpo-40453: Add ``isolated=True`` keyword-only parameter to - ``_xxsubinterpreters.create()``. An isolated subinterpreter cannot spawn - threads, spawn a child process or call ``os.fork()``. - -- bpo-40286: Remove ``_random.Random.randbytes()``: the C implementation of - ``randbytes()``. Implement the method in Python to ease subclassing: - ``randbytes()`` now directly reuses ``getrandbits()``. - -- bpo-40394: Added default arguments to - :meth:`difflib.SequenceMatcher.find_longest_match()`. - -- bpo-39995: Fix a race condition in concurrent.futures._ThreadWakeup: - access to _ThreadWakeup is now protected with the shutdown lock. - -- bpo-30966: ``Process.shutdown(wait=True)`` of :mod:`concurrent.futures` - now closes explicitly the result queue. - -- bpo-30966: Add a new :meth:`~multiprocessing.SimpleQueue.close` method to - the :class:`~multiprocessing.SimpleQueue` class to explicitly close the - queue. - -- bpo-39966: Revert bpo-25597. :class:`unittest.mock.MagicMock` with wraps' - set uses default return values for magic methods. - -- bpo-39791: Added ``files()`` function to importlib.resources with support - for subdirectories in package data, matching backport in - importlib_resources 1.5. - -- bpo-40375: :meth:`imaplib.IMAP4.unselect` is added. Patch by Dong-hee Na. - -- bpo-40389: ``repr()`` now returns ``typing.Optional[T]`` when called for - ``typing.Union`` of two types, one of which is ``NoneType``. - -- bpo-40291: Add support for CAN_J1939 sockets (available on Linux 5.4+) - -- bpo-40273: :class:`types.MappingProxyType` is now reversible. - -- bpo-39075: The repr for :class:`types.SimpleNamespace` is now insertion - ordered rather than alphabetical. - -- bpo-40192: On AIX, :func:`~time.thread_time` is now implemented with - ``thread_cputime()`` which has nanosecond resolution, rather than - ``clock_gettime(CLOCK_THREAD_CPUTIME_ID)`` which has a resolution of 10 - milliseconds. Patch by Batuhan Taskaya. - -- bpo-40025: Raise TypeError when _generate_next_value_ is defined after - members. Patch by Ethan Onstott. - -- bpo-39058: In the argparse module, the repr for Namespace() and other - argument holders now displayed in the order attributes were added. - Formerly, it displayed in alphabetical order even though argument order is - preserved the user visible parts of the module. - -- bpo-24416: The ``isocalendar()`` methods of :class:`datetime.date` and - :class:`datetime.datetime` now return a :term:`named tuple` instead of a - :class:`tuple`. - -Documentation -------------- - -- bpo-34790: Add version of removal for explicit passing of coros to - `asyncio.wait()`'s documentation - -- bpo-40561: Provide docstrings for webbrowser open functions. - -- bpo-40499: Mention that :func:`asyncio.wait` requires a non-empty set of - awaitables. - -- bpo-39705: Tutorial example for sorted() in the Loop Techniques section is - given a better explanation. Also a new example is included to explain - sorted()'s basic behavior. - -- bpo-39435: Fix an incorrect signature for :func:`pickle.loads` in the docs - -Tests ------ - -- bpo-40055: distutils.tests now saves/restores warnings filters to leave - them unchanged. Importing tests imports docutils which imports - pkg_resources which adds a warnings filter. - -- bpo-40436: test_gdb and test.pythoninfo now check gdb command exit code. - -Build ------ - -- bpo-40653: Move _dirnameW out of HAVE_SYMLINK to fix a potential compiling - issue. - -- bpo-40514: Add ``--with-experimental-isolated-subinterpreters`` build - option to ``configure``: better isolate subinterpreters, experimental - build mode. - -Windows -------- - -- bpo-40650: Include winsock2.h in pytime.c for timeval. - -- bpo-40458: Increase reserved stack space to prevent overflow crash on - Windows. - -- bpo-39148: Add IPv6 support to :mod:`asyncio` datagram endpoints in - ProactorEventLoop. Change the raised exception for unknown address - families to ValueError as it's not coming from Windows API. - -macOS ------ - -- bpo-34956: When building Python on macOS from source, ``_tkinter`` now - links with non-system Tcl and Tk frameworks if they are installed in - ``/Library/Frameworks``, as had been the case on older releases of macOS. - If a macOS SDK is explicitly configured, by using - ``--enable-universalsdk=`` or ``-isysroot``, only the SDK itself is - searched. The default behavior can still be overridden with - ``--with-tcltk-includes`` and ``--with-tcltk-libs``. - -- bpo-35569: Expose RFC 3542 IPv6 socket options. - -Tools/Demos ------------ - -- bpo-40479: Update multissltest helper to test with latest OpenSSL 1.0.2, - 1.1.0, 1.1.1, and 3.0.0-alpha. - -- bpo-40431: Fix a syntax typo in ``turtledemo`` that now raises a - ``SyntaxError``. - -- bpo-40163: Fix multissltest tool. OpenSSL has changed download URL for old - releases. The multissltest tool now tries to download from current and old - download URLs. - -C API ------ - -- bpo-39465: Remove the ``_PyUnicode_ClearStaticStrings()`` function from - the C API. - -- bpo-38787: Add PyCFunction_CheckExact() macro for exact type checks now - that we allow subtypes of PyCFunction, as well as PyCMethod_CheckExact() - and PyCMethod_Check() for the new PyCMethod subtype. - -- bpo-40545: Declare ``_PyErr_GetTopmostException()`` with ``PyAPI_FUNC()`` - to properly export the function in the C API. The function remains private - (``_Py``) prefix. - -- bpo-40412: Nullify inittab_copy during finalization, preventing future - interpreter initializations in an embedded situation from crashing. Patch - by Gregory Szorc. - -- bpo-40429: The :c:func:`PyThreadState_GetFrame` function now returns a - strong reference to the frame. - -- bpo-40428: Remove the following functions from the C API. Call - :c:func:`PyGC_Collect` explicitly to free all free lists. - - * ``PyAsyncGen_ClearFreeLists()`` - * ``PyContext_ClearFreeList()`` - * ``PyDict_ClearFreeList()`` - * ``PyFloat_ClearFreeList()`` - * ``PyFrame_ClearFreeList()`` - * ``PyList_ClearFreeList()`` - * ``PySet_ClearFreeList()`` - * ``PyTuple_ClearFreeList()`` - -- bpo-40421: New :c:func:`PyFrame_GetBack` function: get the frame next - outer frame. - -- bpo-40421: New :c:func:`PyFrame_GetCode` function: return a borrowed - reference to the frame code. - -- bpo-40217: Ensure that instances of types created with - :c:func:`PyType_FromSpecWithBases` will visit its class object when - traversing references in the garbage collector (implemented as an - extension of the provided :c:member:`~PyTypeObject.tp_traverse`). Patch by - Pablo Galindo. - -- bpo-38787: Module C state is now accessible from C-defined heap type - methods (:pep:`573`). Patch by Marcel Plch and Petr Viktorin. - - -What's New in Python 3.9.0 alpha 6? -=================================== - -*Release date: 2020-04-27* - -Security --------- - -- bpo-40121: Fixes audit events raised on creating a new socket. - -- bpo-39073: Disallow CR or LF in email.headerregistry.Address arguments to - guard against header injection attacks. - -- bpo-39503: CVE-2020-8492: The - :class:`~urllib.request.AbstractBasicAuthHandler` class of the - :mod:`urllib.request` module uses an inefficient regular expression which - can be exploited by an attacker to cause a denial of service. Fix the - regex to prevent the catastrophic backtracking. Vulnerability reported by - Ben Caller and Matt Schwager. - -Core and Builtins ------------------ - -- bpo-40313: Improve the performance of bytes.hex(). - -- bpo-40334: Switch to a new parser, based on PEG. For more details see PEP - 617. To temporarily switch back to the old parser, use ``-X oldparser`` or - ``PYTHONOLDPARSER=1``. In Python 3.10 we will remove the old parser - completely, including the ``parser`` module (already deprecated) and - anything that depends on it. - -- bpo-40267: Fix the tokenizer to display the correct error message, when - there is a SyntaxError on the last input character and no newline follows. - It used to be `unexpected EOF while parsing`, while it should be `invalid - syntax`. - -- bpo-39522: Correctly unparse explicit ``u`` prefix for strings when - postponed evaluation for annotations activated. Patch by Batuhan Taskaya. - -- bpo-40246: Report a specialized error message, `invalid string prefix`, - when the tokenizer encounters a string with an invalid prefix. - -- bpo-40082: Fix the signal handler: it now always uses the main - interpreter, rather than trying to get the current Python thread state. - -- bpo-37388: str.encode() and str.decode() no longer check the encoding and - errors in development mode or in debug mode during Python finalization. - The codecs machinery can no longer work on very late calls to str.encode() - and str.decode(). - -- bpo-40077: Fix possible refleaks in :mod:`_json`, memo of PyScannerObject - should be traversed. - -- bpo-37207: Speed up calls to ``dict()`` by using the :pep:`590` - ``vectorcall`` calling convention. - -- bpo-40141: Add column and line information to ``ast.keyword`` nodes. Patch - by Pablo Galindo. - -- bpo-1635741: Port :mod:`resource` to multiphase initialization - (:pep:`489`). - -- bpo-1635741: Port :mod:`math` to multiphase initialization (:pep:`489`). - -- bpo-1635741: Port _uuid module to multiphase initialization (:pep:`489`). - -- bpo-40077: Convert json module to use :c:func:`PyType_FromSpec`. - -- bpo-40067: Improve the error message for multiple star expressions in an - assignment. Patch by Furkan Onder - -- bpo-1635741: Port _functools module to multiphase initialization (PEP - 489). Patch by Paulo Henrique Silva. - -- bpo-1635741: Port operator module to multiphase initialization (PEP 489). - Patch by Paulo Henrique Silva. - -- bpo-20526: Fix :c:func:`PyThreadState_Clear()`. ``PyThreadState.frame`` is - a borrowed reference, not a strong reference: ``PyThreadState_Clear()`` - must not call ``Py_CLEAR(tstate->frame)``. - -- bpo-1635741: Port time module to multiphase initialization (:pep:`489`). - Patch by Paulo Henrique Silva. - -- bpo-1635741: Port _weakref extension module to multiphase initialization - (:pep:`489`). - -- bpo-40020: Fix a leak and subsequent crash in parsetok.c caused by realloc - misuse on a rare codepath. - -- bpo-39939: Added str.removeprefix and str.removesuffix methods and - corresponding bytes, bytearray, and collections.UserString methods to - remove affixes from a string if present. See :pep:`616` for a full - description. Patch by Dennis Sweeney. - -- bpo-39481: Implement PEP 585. This supports list[int], tuple[str, ...] - etc. - -- bpo-32894: Support unparsing of infinity numbers in postponed annotations. - Patch by Batuhan Taşkaya. - -- bpo-37207: Speed up calls to ``list()`` by using the :pep:`590` - ``vectorcall`` calling convention. Patch by Mark Shannon. - -Library -------- - -- bpo-40398: :func:`typing.get_args` now always returns an empty tuple for - special generic aliases. - -- bpo-40396: Functions :func:`typing.get_origin`, :func:`typing.get_args` - and :func:`typing.get_type_hints` support now generic aliases like - ``list[int]``. - -- bpo-38061: Optimize the :mod:`subprocess` module on FreeBSD using - ``closefrom()``. A single ``close(fd)`` syscall is cheap, but when - ``sysconf(_SC_OPEN_MAX)`` is high, the loop calling ``close(fd)`` on each - file descriptor can take several milliseconds. - - The workaround on FreeBSD to improve performance was to load and mount the - fdescfs kernel module, but this is not enabled by default. - - Initial patch by Ed Maste (emaste), Conrad Meyer (cem), Kyle Evans - (kevans) and Kubilay Kocak (koobs): - https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=242274 - -- bpo-38061: On FreeBSD, ``os.closerange(fd_low, fd_high)`` now calls - ``closefrom(fd_low)`` if *fd_high* is greater than or equal to - ``sysconf(_SC_OPEN_MAX)``. - - Initial patch by Ed Maste (emaste), Conrad Meyer (cem), Kyle Evans - (kevans) and Kubilay Kocak (koobs): - https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=242274 - -- bpo-40360: The :mod:`lib2to3` module is pending deprecation due to - :pep:`617`. - -- bpo-40138: Fix the Windows implementation of :func:`os.waitpid` for exit - code larger than ``INT_MAX >> 8``. The exit status is now interpreted as - an unsigned number. - -- bpo-39942: Set "__main__" as the default module name when "__name__" is - missing in :class:`typing.TypeVar`. Patch by Weipeng Hong. - -- bpo-40275: The :mod:`logging` package is now imported lazily in - :mod:`unittest` only when the :meth:`~unittest.TestCase.assertLogs` - assertion is used. - -- bpo-40275: The :mod:`asyncio` package is now imported lazily in - :mod:`unittest` only when the :class:`~unittest.IsolatedAsyncioTestCase` - class is used. - -- bpo-40330: In :meth:`ShareableList.__setitem__`, check the size of a new - string item after encoding it to utf-8, not before. - -- bpo-40148: Added :meth:`pathlib.Path.with_stem()` to create a new Path - with the stem replaced. - -- bpo-40325: Deprecated support for set objects in random.sample(). - -- bpo-40257: Improved help for the :mod:`typing` module. Docstrings are now - shown for all special forms and special generic aliases (like ``Union`` - and ``List``). Using ``help()`` with generic alias like ``List[int]`` will - show the help for the correspondent concrete type (``list`` in this case). - -- bpo-40257: func:`inspect.getdoc` no longer returns docstring inherited - from the type of the object or from parent class if it is a class if it is - not defined in the object itself. In :mod:`pydoc` the documentation string - is now shown not only for class, function, method etc, but for any object - that has its own ``__doc__`` attribute. - -- bpo-40287: Fixed ``SpooledTemporaryFile.seek()`` to return the position. - -- bpo-40290: Added zscore() to statistics.NormalDist(). - -- bpo-40282: Allow ``random.getrandbits(0)`` to succeed and to return 0. - -- bpo-40286: Add :func:`random.randbytes` function and - :meth:`random.Random.randbytes` method to generate random bytes. - -- bpo-40277: :func:`collections.namedtuple` now provides a human-readable - repr for its field accessors. - -- bpo-40270: The included copy of sqlite3 on Windows is now compiled with - the json extension. This allows the use of functions such as - ``json_object``. - -- bpo-29255: Wait in `KqueueSelector.select` when no fds are registered - -- bpo-40260: Ensure :mod:`modulefinder` uses :func:`io.open_code` and - respects coding comments. - -- bpo-40234: Allow again to spawn daemon threads in subinterpreters (revert - change which denied them). - -- bpo-39207: Workers in :class:`~concurrent.futures.ProcessPoolExecutor` are - now spawned on demand, only when there are no available idle workers to - reuse. This optimizes startup overhead and reduces the amount of lost CPU - time to idle workers. Patch by Kyle Stanley. - -- bpo-40091: Fix a hang at fork in the logging module: the new private - _at_fork_reinit() method is now used to reinitialize locks at fork in the - child process. - -- bpo-40149: Implement traverse and clear slots in _abc._abc_data type. - -- bpo-40208: Remove deprecated :meth:`symtable.SymbolTable.has_exec`. - -- bpo-40196: Fix a bug in the :mod:`symtable` module that was causing - incorrectly report global variables as local. Patch by Pablo Galindo. - -- bpo-40190: Add support for ``_SC_AIX_REALMEM`` to :func:`posix.sysconf`. - -- bpo-40182: Removed the ``_field_types`` attribute of the - :class:`typing.NamedTuple` class. - -- bpo-36517: Multiple inheritance with :class:`typing.NamedTuple` now raises - an error instead of silently ignoring other types. - -- bpo-40126: Fixed reverting multiple patches in unittest.mock. Patcher's - ``__exit__()`` is now never called if its ``__enter__()`` is failed. - Returning true from ``__exit__()`` silences now the exception. - -- bpo-40094: CGIHTTPRequestHandler of http.server now logs the CGI script - exit code, rather than the CGI script exit status of os.waitpid(). For - example, if the script is killed by signal 11, it now logs: "CGI script - exit code -11." - -- bpo-40108: Improve the error message when triying to import a module using - :mod:`runpy` and incorrently use the ".py" extension at the end of the - module name. Patch by Pablo Galindo. - -- bpo-40094: Add :func:`os.waitstatus_to_exitcode` function: convert a wait - status to an exit code. - -- bpo-40089: Fix threading._after_fork(): if fork was not called by a thread - spawned by threading.Thread, threading._after_fork() now creates a - _MainThread instance for _main_thread, instead of a _DummyThread instance. - -- bpo-40089: Add a private ``_at_fork_reinit()`` method to - :class:`_thread.Lock`, :class:`_thread.RLock`, :class:`threading.RLock` - and :class:`threading.Condition` classes: reinitialize the lock at fork in - the child process, reset the lock to the unlocked state. Rename also the - private ``_reset_internal_locks()`` method of :class:`threading.Event` to - ``_at_fork_reinit()``. - -- bpo-25780: Expose :data:`~socket.CAN_RAW_JOIN_FILTERS` in the - :mod:`socket` module. - -- bpo-39503: :class:`~urllib.request.AbstractBasicAuthHandler` of - :mod:`urllib.request` now parses all WWW-Authenticate HTTP headers and - accepts multiple challenges per header: use the realm of the first Basic - challenge. - -- bpo-39812: Removed daemon threads from :mod:`concurrent.futures` by adding - an internal `threading._register_atexit()`, which calls registered - functions prior to joining all non-daemon threads. This allows for - compatibility with subinterpreters, which don't support daemon threads. - -- bpo-40050: Fix ``importlib._bootstrap_external``: avoid creating a new - ``winreg`` builtin module if it's already available in - :data:`sys.modules`, and remove redundant imports. - -- bpo-40014: Fix ``os.getgrouplist()``: if ``getgrouplist()`` function fails - because the group list is too small, retry with a larger group list. On - failure, the glibc implementation of ``getgrouplist()`` sets ``ngroups`` - to the total number of groups. For other implementations, double the group - list size. - -- bpo-40017: Add :data:`time.CLOCK_TAI` constant if the operating system - support it. - -- bpo-40016: In re docstring, clarify the relationship between inline and - argument compile flags. - -- bpo-39953: Update internal table of OpenSSL error codes in the ``ssl`` - module. - -- bpo-36144: Added :pep:`584` operators to - :class:`weakref.WeakValueDictionary`. - -- bpo-36144: Added :pep:`584` operators to - :class:`weakref.WeakKeyDictionary`. - -- bpo-38891: Fix linear runtime behaviour of the `__getitem__` and - `__setitem__` methods in - :class:`multiprocessing.shared_memory.ShareableList`. This avoids - quadratic performance when iterating a `ShareableList`. Patch by Thomas - Krennwallner. - -- bpo-39682: Remove undocumented support for *closing* a `pathlib.Path` - object via its context manager. The context manager magic methods remain, - but they are now a no-op, making `Path` objects immutable. - -- bpo-36144: Added :pep:`584` operators (``|`` and ``|=``) to - :class:`collections.ChainMap`. - -- bpo-39011: Normalization of line endings in ElementTree attributes was - removed, as line endings which were replaced by entity numbers should be - preserved in original form. - -- bpo-38410: Properly handle :func:`sys.audit` failures in - :func:`sys.set_asyncgen_hooks`. - -- bpo-36541: lib2to3 now recognizes named assignment expressions (the walrus - operator, ``:=``) - -- bpo-35967: In platform, delay the invocation of 'uname -p' until the - processor attribute is requested. - -- bpo-35113: :meth:`inspect.getsource` now returns correct source code for - inner class with same name as module level class. Decorators are also - returned as part of source of the class. Patch by Karthikeyan - Singaravelan. - -- bpo-33262: Deprecate passing None as an argument for - :func:`shlex.split()`'s ``s`` parameter. Patch by Zackery Spytz. - -- bpo-31758: Prevent crashes when using an uninitialized - ``_elementtree.XMLParser`` object. Patch by Oren Milman. - -Documentation -------------- - -- bpo-27635: The pickle documentation incorrectly claimed that ``__new__`` - isn't called by default when unpickling. - -- bpo-39879: Updated :ref:`datamodel` docs to include :func:`dict` insertion - order preservation. Patch by Furkan Onder and Samy Lahfa. - -- bpo-38387: Document :c:macro:`PyDoc_STRVAR` macro in the C-API reference. - -- bpo-13743: Some methods within xml.dom.minidom.Element class are now - better documented. - -Tests ------ - -- bpo-31904: Set expected default encoding in test_c_locale_coercion.py for - VxWorks RTOS. - -- bpo-40162: Update Travis CI configuration to OpenSSL 1.1.1f. - -- bpo-40146: Update OpenSSL to 1.1.1f in Azure Pipelines. - -- bpo-40094: Add :func:`test.support.wait_process` function. - -- bpo-40003: ``test.bisect_cmd`` now copies Python command line options like - ``-O`` or ``-W``. Moreover, emit a warning if ``test.bisect_cmd`` is used - with ``-w``/``--verbose2`` option. - -- bpo-39380: Add the encoding in :class:`ftplib.FTP` and - :class:`ftplib.FTP_TLS` to the constructor as keyword-only and change the - default from ``latin-1`` to ``utf-8`` to follow :rfc:`2640`. - -- bpo-39793: Use the same domain when testing ``make_msgid``. Patch by - Batuhan Taskaya. - -- bpo-1812: Fix newline handling in doctest.testfile when loading from a - package whose loader has a get_data method. Patch by Peter Donis. - -Build ------ - -- bpo-38360: Support single-argument form of macOS -isysroot flag. - -- bpo-40158: Fix CPython MSBuild Properties in NuGet Package - (build/native/python.props) - -- bpo-38527: Fix configure check on Solaris for "float word ordering": - sometimes, the correct "grep" command was not being used. Patch by Arnon - Yaari. - -Windows -------- - -- bpo-40164: Updates Windows to OpenSSL 1.1.1f - -- bpo-8901: Ignore the Windows registry when the ``-E`` option is used. - -macOS ------ - -- bpo-38329: python.org macOS installers now update the Current version - symlink of /Library/Frameworks/Python.framework/Versions for 3.9 installs. - Previously, Current was only updated for Python 2.x installs. This should - make it easier to embed Python 3 into other macOS applications. - -- bpo-40164: Update macOS installer builds to use OpenSSL 1.1.1g. - -IDLE ----- - -- bpo-38439: Add a 256×256 pixel IDLE icon to support more modern - environments. Created by Andrew Clover. Delete the unused macOS idle.icns - icon file. - -- bpo-38689: IDLE will no longer freeze when inspect.signature fails when - fetching a calltip. - -Tools/Demos ------------ - -- bpo-40385: Removed the checkpyc.py tool. Please see compileall without - force mode as a potential alternative. - -- bpo-40179: Fixed translation of ``#elif`` in Argument Clinic. - -- bpo-40094: Fix ``which.py`` script exit code: it now uses - :func:`os.waitstatus_to_exitcode` to convert :func:`os.system` exit status - into an exit code. - -C API ------ - -- bpo-40241: Move the :c:type:`PyGC_Head` structure to the internal C API. - -- bpo-40170: Convert :c:func:`PyObject_IS_GC` macro to a function to hide - implementation details. - -- bpo-40241: Add the functions :c:func:`PyObject_GC_IsTracked` and - :c:func:`PyObject_GC_IsFinalized` to the public API to allow to query if - Python objects are being currently tracked or have been already finalized - by the garbage collector respectively. Patch by Pablo Galindo. - -- bpo-40170: The :c:func:`PyObject_NEW` macro becomes an alias to the - :c:func:`PyObject_New` macro, and the :c:func:`PyObject_NEW_VAR` macro - becomes an alias to the :c:func:`PyObject_NewVar` macro, to hide - implementation details. They no longer access directly the - :c:member:`PyTypeObject.tp_basicsize` member. - -- bpo-40170: :c:func:`PyType_HasFeature` now always calls - :c:func:`PyType_GetFlags` to hide implementation details. Previously, it - accessed directly the :c:member:`PyTypeObject.tp_flags` member when the - limited C API was not used. - -- bpo-40170: Convert the :c:func:`PyObject_GET_WEAKREFS_LISTPTR` macro to a - function to hide implementation details: the macro accessed directly to - the :c:member:`PyTypeObject.tp_weaklistoffset` member. - -- bpo-40170: Convert :c:func:`PyObject_CheckBuffer` macro to a function to - hide implementation details: the macro accessed directly the - :c:member:`PyTypeObject.tp_as_buffer` member. - -- bpo-40170: Always declare :c:func:`PyIndex_Check` as an opaque function to - hide implementation details: remove ``PyIndex_Check()`` macro. The macro - accessed directly the :c:member:`PyTypeObject.tp_as_number` member. - -- bpo-39947: Add :c:func:`PyThreadState_GetID` function: get the unique - identifier of a Python thread state. - - -What's New in Python 3.9.0 alpha 5? -=================================== - -*Release date: 2020-03-23* - -Security --------- - -- bpo-38576: Disallow control characters in hostnames in http.client, - addressing CVE-2019-18348. Such potentially malicious header injection - URLs now cause a InvalidURL to be raised. - -Core and Builtins ------------------ - -- bpo-40010: Optimize pending calls in multithreaded applications. If a - thread different than the main thread schedules a pending call - (:c:func:`Py_AddPendingCall`), the bytecode evaluation loop is no longer - interrupted at each bytecode instruction to check for pending calls which - cannot be executed. Only the main thread can execute pending calls. - - Previously, the bytecode evaluation loop was interrupted at each - instruction until the main thread executes pending calls. - -- bpo-1635741: Port _weakref extension module to multiphase initialization - (:pep:`489`). - -- bpo-1635741: Port _collections module to multiphase initialization - (:pep:`489`). - -- bpo-40010: Optimize signal handling in multithreaded applications. If a - thread different than the main thread gets a signal, the bytecode - evaluation loop is no longer interrupted at each bytecode instruction to - check for pending signals which cannot be handled. Only the main thread of - the main interpreter can handle signals. - - Previously, the bytecode evaluation loop was interrupted at each - instruction until the main thread handles signals. - -- bpo-39984: If :c:func:`Py_AddPendingCall` is called in a subinterpreter, - the function is now scheduled to be called from the subinterpreter, rather - than being called from the main interpreter. Each subinterpreter now has - its own list of scheduled calls. - -- bpo-1635741: Port _heapq module to multiphase initialization. - -- bpo-1635741: Port itertools module to multiphase initialization - (:pep:`489`). - -- bpo-37207: Speed up calls to ``frozenset()`` by using the :pep:`590` - ``vectorcall`` calling convention. Patch by Dong-hee Na. - -- bpo-39984: subinterpreters: Move - ``_PyRuntimeState.ceval.tracing_possible`` to - ``PyInterpreterState.ceval.tracing_possible``: each interpreter now has - its own variable. - -- bpo-37207: Speed up calls to ``set()`` by using the :pep:`590` - ``vectorcall`` calling convention. Patch by Dong-hee Na. - -- bpo-1635741: Port _statistics module to multiphase initialization - (:pep:`489`). - -- bpo-39968: Use inline function to replace extension modules' - get_module_state macros. - -- bpo-39965: Correctly raise ``SyntaxError`` if *await* is used inside - non-async functions and ``PyCF_ALLOW_TOP_LEVEL_AWAIT`` is set (like in the - asyncio REPL). Patch by Pablo Galindo. - -- bpo-39562: Allow executing asynchronous comprehensions on the top level - when the ``PyCF_ALLOW_TOP_LEVEL_AWAIT`` flag is given. Patch by Batuhan - Taskaya. - -- bpo-37207: Speed up calls to ``tuple()`` by using the :pep:`590` - ``vectorcall`` calling convention. Patch by Dong-hee Na. - -- bpo-38373: Changed list overallocation strategy. It no longer - overallocates if the new size is closer to overallocated size than to the - old size and adds padding. - -- bpo-39926: Update Unicode database to Unicode version 13.0.0. - -- bpo-19466: Clear the frames of daemon threads earlier during the Python - shutdown to call objects destructors. So "unclosed file" resource warnings - are now emitted for daemon threads in a more reliable way. - -- bpo-38894: Fix a bug that was causing incomplete results when calling - ``pathlib.Path.glob`` in the presence of symlinks that point to files - where the user does not have read access. Patch by Pablo Galindo and Matt - Wozniski. - -- bpo-39877: Fix :c:func:`PyEval_RestoreThread` random crash at exit with - daemon threads. It now accesses the ``_PyRuntime`` variable directly - instead of using ``tstate->interp->runtime``, since ``tstate`` can be a - dangling pointer after :c:func:`Py_Finalize` has been called. Moreover, - the daemon thread now exits before trying to take the GIL. - -- bpo-39871: Fix a possible :exc:`SystemError` in - ``math.{atan2,copysign,remainder}()`` when the first argument cannot be - converted to a :class:`float`. Patch by Zackery Spytz. - -- bpo-39776: Fix race condition where threads created by PyGILState_Ensure() - could get a duplicate id. - - This affects consumers of tstate->id like the contextvar caching - machinery, which could return invalid cached objects under heavy thread - load (observed in embedded scenarios). - -- bpo-39778: Fixed a crash due to incorrect handling of weak references in - ``collections.OrderedDict`` classes. Patch by Pablo Galindo. - -- bpo-1635741: Port audioop extension module to multiphase initialization - (:pep:`489`). - -- bpo-39702: Relax :term:`decorator` grammar restrictions to allow any valid - expression (:pep:`614`). - -- bpo-38091: Tweak import deadlock detection code to not deadlock itself. - -- bpo-1635741: Port _locale extension module to multiphase initialization - (:pep:`489`). - -- bpo-39087: Optimize :c:func:`PyUnicode_AsUTF8` and - :c:func:`PyUnicode_AsUTF8AndSize` slightly when they need to create - internal UTF-8 cache. - -- bpo-39520: Fix unparsing of ext slices with no items (``foo[:,]``). Patch - by Batuhan Taskaya. - -- bpo-39220: Do not optimize annotations if 'from __future__ import - annotations' is used. Patch by Pablo Galindo. - -- bpo-35712: Using :data:`NotImplemented` in a boolean context has been - deprecated. Patch contributed by Josh Rosenberg. - -- bpo-22490: Don't leak environment variable ``__PYVENV_LAUNCHER__`` into - the interpreter session on macOS. - -Library -------- - -- bpo-39830: Add :class:`zipfile.Path` to ``__all__`` in the :mod:`zipfile` - module. - -- bpo-40000: Improved error messages for validation of ``ast.Constant`` - nodes. Patch by Batuhan Taskaya. - -- bpo-39999: ``__module__`` of the AST node classes is now set to "ast" - instead of "_ast". Added docstrings for dummy AST node classes and - deprecated attributes. - -- bpo-39991: :func:`uuid.getnode` now skips IPv6 addresses with the same - string length than a MAC address (17 characters): only use MAC addresses. - -- bpo-39988: Deprecated ``ast.AugLoad`` and ``ast.AugStore`` node classes - because they are no longer used. - -- bpo-39656: Ensure ``bin/python3.#`` is always present in virtual - environments on POSIX platforms - by Anthony Sottile. - -- bpo-39969: Deprecated ``ast.Param`` node class because it's no longer - used. Patch by Batuhan Taskaya. - -- bpo-39360: Ensure all workers exit when finalizing a - :class:`multiprocessing.Pool` implicitly via the module finalization - handlers of multiprocessing. This fixes a deadlock situation that can be - experienced when the Pool is not properly finalized via the context - manager or a call to ``multiprocessing.Pool.terminate``. Patch by Batuhan - Taskaya and Pablo Galindo. - -- bpo-35370: sys.settrace(), sys.setprofile() and _lsprof.Profiler.enable() - now properly report :c:func:`PySys_Audit` error if "sys.setprofile" or - "sys.settrace" audit event is denied. - -- bpo-39936: AIX: Fix _aix_support module when the subprocess is not - available, when building Python from scratch. It now uses new private - _bootsubprocess module, rather than having two implementations depending - if subprocess is available or not. So _aix_support.aix_platform() result - is now the same if subprocess is available or not. - -- bpo-36144: :class:`collections.OrderedDict` now implements ``|`` and - ``|=`` (:pep:`584`). - -- bpo-39652: The column name found in ``sqlite3.Cursor.description`` is now - truncated on the first '[' only if the PARSE_COLNAMES option is set. - -- bpo-39915: Ensure :attr:`unittest.mock.AsyncMock.await_args_list` has call - objects in the order of awaited arguments instead of using - :attr:`unittest.mock.Mock.call_args` which has the last value of the call. - Patch by Karthikeyan Singaravelan. - -- bpo-36144: Updated :data:`os.environ` and :data:`os.environb` to support - :pep:`584`'s merge (``|``) and update (``|=``) operators. - -- bpo-38662: The ``ensurepip`` module now invokes ``pip`` via the ``runpy`` - module. Hence it is no longer tightly coupled with the internal API of the - bundled ``pip`` version, allowing easier updates to a newer ``pip`` - version both internally and for distributors. - -- bpo-38075: Fix the :meth:`random.Random.seed` method when a :class:`bool` - is passed as the seed. - -- bpo-39916: More reliable use of ``os.scandir()`` in ``Path.glob()``. It no - longer emits a ResourceWarning when interrupted. - -- bpo-39850: :mod:`multiprocessing` now supports abstract socket addresses - (if abstract sockets are supported in the running platform). When creating - arbitrary addresses (like when default-constructing - :class:`multiprocessing.connection.Listener` objects) abstract sockets are - preferred to avoid the case when the temporary-file-generated address is - too large for an AF_UNIX socket address. Patch by Pablo Galindo. - -- bpo-36287: :func:`ast.dump()` no longer outputs optional fields and - attributes with default values. The default values for optional fields and - attributes of AST nodes are now set as class attributes (e.g. - ``Constant.kind`` is set to ``None``). - -- bpo-39889: Fixed :func:`ast.unparse` for extended slices containing a - single element (e.g. ``a[i:j,]``). Remove redundant tuples when index with - a tuple (e.g. ``a[i, j]``). - -- bpo-39828: Fix :mod:`json.tool` to catch :exc:`BrokenPipeError`. Patch by - Dong-hee Na. - -- bpo-13487: Avoid a possible *"RuntimeError: dictionary changed size during - iteration"* from :func:`inspect.getmodule` when it tried to loop through - :attr:`sys.modules`. - -- bpo-39674: Revert "bpo-37330: open() no longer accept 'U' in file mode". - The "U" mode of open() is kept in Python 3.9 to ease transition from - Python 2.7, but will be removed in Python 3.10. - -- bpo-28577: The hosts method on 32-bit prefix length IPv4Networks and - 128-bit prefix IPv6Networks now returns a list containing the single - Address instead of an empty list. - -- bpo-39826: Add getConnection method to logging HTTPHandler to enable - custom connections. - -- bpo-39763: Reimplement :func:`distutils.spawn.spawn` function with the - :mod:`subprocess` module. - -- bpo-39794: Add --without-decimal-contextvar build option. This enables a - thread-local rather than a coroutine local context. - -- bpo-36144: :class:`collections.defaultdict` now implements ``|`` - (:pep:`584`). - -- bpo-39517: Fix runpy.run_path() when using pathlike objects - -- bpo-39775: Change ``inspect.Signature.parameters`` back to - ``collections.OrderedDict``. This was changed to ``dict`` in Python - 3.9.0a4. - -- bpo-39678: Refactor queue_manager in - :class:`concurrent.futures.ProcessPoolExecutor` to make it easier to - maintain. - -- bpo-39764: Fix AttributeError when calling get_stack on a PyAsyncGenObject - Task - -- bpo-39769: The :func:`compileall.compile_dir` function's *ddir* parameter - and the compileall command line flag `-d` no longer write the wrong - pathname to the generated pyc file for submodules beneath the root of the - directory tree being compiled. This fixes a regression introduced with - Python 3.5. - -- bpo-36144: :class:`types.MappingProxyType` objects now support the merge - (``|``) operator from :pep:`584`. - -- bpo-38691: The :mod:`importlib` module now ignores the - :envvar:`PYTHONCASEOK` environment variable when the :option:`-E` or - :option:`-I` command line options are being used. - -- bpo-39719: Remove :meth:`tempfile.SpooledTemporaryFile.softspace` as files - no longer have the ``softspace`` attribute in Python 3. Patch by Shantanu. - -- bpo-39667: Improve pathlib.Path compatibility on zipfile.Path and correct - performance degradation as found in zipp 3.0. - -- bpo-39638: Keep ASDL signatures in the docstrings for ``AST`` nodes. Patch - by Batuhan Taskaya - -- bpo-39639: Deprecated ``ast.Suite`` node class because it's no longer - used. Patch by Batuhan Taskaya. - -- bpo-39609: Add thread_name_prefix to default asyncio executor - -- bpo-39548: Fix handling of header in - :class:`urllib.request.AbstractDigestAuthHandler` when the optional - ``qop`` parameter is not present. - -- bpo-39509: HTTP status codes ``103 EARLY_HINTS`` and ``425 TOO_EARLY`` are - added to :class:`http.HTTPStatus`. Patch by Dong-hee Na. - -- bpo-39507: Adding HTTP status 418 "I'm a Teapot" to HTTPStatus in http - library. Patch by Ross Rhodes. - -- bpo-39495: Remove default value from *attrs* parameter of - :meth:`xml.etree.ElementTree.TreeBuilder.start` for consistency between - Python and C implementations. - -- bpo-38971: Open issue in the BPO indicated a desire to make the - implementation of codecs.open() at parity with io.open(), which implements - a try/except to assure file stream gets closed before an exception is - raised. - -- bpo-38641: Added starred expressions support to ``return`` and ``yield`` - statements for ``lib2to3``. Patch by Vlad Emelianov. - -- bpo-37534: When using minidom module to generate XML documents the ability - to add Standalone Document Declaration is added. All the changes are made - to generate a document in compliance with Extensible Markup Language (XML) - 1.0 (Fifth Edition) W3C Recommendation (available here: - https://www.w3.org/TR/xml/#sec-prolog-dtd). - -- bpo-34788: Add support for scoped IPv6 addresses to :mod:`ipaddress`. - Patch by Oleksandr Pavliuk. - -- bpo-34822: Simplified AST for subscription. Simple indices are now - represented by their value, extended slices are represented as tuples. - :mod:`ast` classes ``Index`` and ``ExtSlice`` are considered deprecated - and will be removed in future Python versions. In the meantime, - ``Index(value)`` now returns a ``value`` itself, ``ExtSlice(slices)`` - returns ``Tuple(slices, Load())``. - -Documentation -------------- - -- bpo-39868: Updated the Language Reference for :pep:`572`. - -- bpo-13790: Change 'string' to 'specification' in format doc. - -- bpo-17422: The language reference no longer restricts default class - namespaces to dicts only. - -- bpo-39530: Fix misleading documentation about mixed-type numeric - comparisons. - -- bpo-39718: Update :mod:`token` documentation to reflect additions in - Python 3.8 - -- bpo-39677: Changed operand name of **MAKE_FUNCTION** from *argc* to - *flags* for module :mod:`dis` - -Tests ------ - -- bpo-40019: test_gdb now skips tests if it detects that gdb failed to read - debug information because the Python binary is optimized. - -- bpo-27807: ``test_site.test_startup_imports()`` is now skipped if a path - of :data:`sys.path` contains a ``.pth`` file. - -- bpo-26067: Do not fail test_shutil test_chown test when uid or gid of user - cannot be resolved to a name. - -- bpo-39855: test_subprocess.test_user() now skips the test on an user name - if the user name doesn't exist. For example, skip the test if the user - "nobody" doesn't exist on Linux. - -Build ------ - -- bpo-39761: Fix build with DTrace but without additional DFLAGS. - -- bpo-39763: setup.py now uses a basic implementation of the - :mod:`subprocess` module if the :mod:`subprocess` module is not available: - before required C extension modules are built. - -- bpo-1294959: Add ``--with-platlibdir`` option to the configure script: - name of the platform-specific library directory, stored in the new - :attr:`sys.platlibdir` attribute. It is used to build the path of - platform-specific extension modules and the path of the standard library. - It is equal to ``"lib"`` on most platforms. On Fedora and SuSE, it is - equal to ``"lib64"`` on 64-bit platforms. Patch by Jan Matějek, Matěj - Cepl, Charalampos Stratakis and Victor Stinner. - -Windows -------- - -- bpo-39930: Ensures the required :file:`vcruntime140.dll` is included in - install packages. - -- bpo-39847: Avoid hang when computer is hibernated whilst waiting for a - mutex (for lock-related objects from :mod:`threading`) around 49-day - uptime. - -- bpo-38597: :mod:`distutils` will no longer statically link - :file:`vcruntime140.dll` when a redistributable version is unavailable. - All future releases of CPython will include a copy of this DLL to ensure - distributed extensions can continue to load. - -- bpo-38380: Update Windows builds to use SQLite 3.31.1 - -- bpo-39789: Update Windows release build machines to Visual Studio 2019 - (MSVC 14.2). - -- bpo-34803: Package for nuget.org now includes repository reference and - bundled icon image. - -macOS ------ - -- bpo-38380: Update macOS builds to use SQLite 3.31.1 - -IDLE ----- - -- bpo-27115: For 'Go to Line', use a Query box subclass with IDLE standard - behavior and improved error checking. - -- bpo-39885: Since clicking to get an IDLE context menu moves the cursor, - any text selection should be and now is cleared. - -- bpo-39852: Edit "Go to line" now clears any selection, preventing - accidental deletion. It also updates Ln and Col on the status bar. - -- bpo-39781: Selecting code context lines no longer causes a jump. - -Tools/Demos ------------ - -- bpo-36184: Port python-gdb.py to FreeBSD. python-gdb.py now checks for - "take_gil" function name to check if a frame tries to acquire the GIL, - instead of checking for "pthread_cond_timedwait" which is specific to - Linux and can be a different condition than the GIL. - -- bpo-38080: Added support to fix ``getproxies`` in the - :mod:`lib2to3.fixes.fix_urllib` module. Patch by José Roberto Meza - Cabrera. - -C API ------ - -- bpo-40024: Add :c:func:`PyModule_AddType` helper function: add a type to a - module. Patch by Dong-hee Na. - -- bpo-39946: Remove ``_PyRuntime.getframe`` hook and remove - ``_PyThreadState_GetFrame`` macro which was an alias to - ``_PyRuntime.getframe``. They were only exposed by the internal C API. - Remove also ``PyThreadFrameGetter`` type. - -- bpo-39947: Add :c:func:`PyThreadState_GetFrame` function: get the current - frame of a Python thread state. - -- bpo-37207: Add _PyArg_NoKwnames helper function. Patch by Dong-hee Na. - -- bpo-39947: Add :c:func:`PyThreadState_GetInterpreter`: get the interpreter - of a Python thread state. - -- bpo-39947: Add :c:func:`PyInterpreterState_Get` function to the limited C - API. - -- bpo-35370: If :c:func:`PySys_Audit` fails in :c:func:`PyEval_SetProfile` - or :c:func:`PyEval_SetTrace`, log the error as an unraisable exception. - -- bpo-39947: Move the static inline function flavor of - Py_EnterRecursiveCall() and Py_LeaveRecursiveCall() to the internal C API: - they access PyThreadState attributes. The limited C API provides regular - functions which hide implementation details. - -- bpo-39947: Py_TRASHCAN_BEGIN_CONDITION and Py_TRASHCAN_END macro no longer - access PyThreadState attributes, but call new private _PyTrash_begin() and - _PyTrash_end() functions which hide implementation details. - -- bpo-39884: :c:func:`PyDescr_NewMethod` and :c:func:`PyCFunction_NewEx` now - include the method name in the SystemError "bad call flags" error message - to ease debug. - -- bpo-39877: Deprecated :c:func:`PyEval_InitThreads` and - :c:func:`PyEval_ThreadsInitialized`. Calling :c:func:`PyEval_InitThreads` - now does nothing. - -- bpo-38249: :c:macro:`Py_UNREACHABLE` is now implemented with - ``__builtin_unreachable()`` and analogs in release mode. - -- bpo-38643: :c:func:`PyNumber_ToBase` now raises a :exc:`SystemError` - instead of crashing when called with invalid base. - -- bpo-39882: The :c:func:`Py_FatalError` function is replaced with a macro - which logs automatically the name of the current function, unless the - ``Py_LIMITED_API`` macro is defined. - -- bpo-39824: Extension modules: :c:member:`~PyModuleDef.m_traverse`, - :c:member:`~PyModuleDef.m_clear` and :c:member:`~PyModuleDef.m_free` - functions of :c:type:`PyModuleDef` are no longer called if the module - state was requested but is not allocated yet. This is the case immediately - after the module is created and before the module is executed - (:c:data:`Py_mod_exec` function). More precisely, these functions are not - called if :c:member:`~PyModuleDef.m_size` is greater than 0 and the module - state (as returned by :c:func:`PyModule_GetState`) is ``NULL``. - - Extension modules without module state (``m_size <= 0``) are not affected. - -- bpo-38913: Fixed segfault in ``Py_BuildValue()`` called with a format - containing "#" and undefined PY_SSIZE_T_CLEAN whwn an exception is set. - -- bpo-38500: Add a private API to get and set the frame evaluation function: - add :c:func:`_PyInterpreterState_GetEvalFrameFunc` and - :c:func:`_PyInterpreterState_SetEvalFrameFunc` C functions. The - :c:type:`_PyFrameEvalFunction` function type now takes a *tstate* - parameter. - - -What's New in Python 3.9.0 alpha 4? -=================================== - -*Release date: 2020-02-25* - -Security --------- - -- bpo-39184: Add audit events to functions in `fcntl`, `msvcrt`, `os`, - `resource`, `shutil`, `signal` and `syslog`. - -- bpo-39401: Avoid unsafe DLL load at startup on Windows 7 and earlier. - -- bpo-39184: Add audit events to command execution functions in os and pty - modules. - -Core and Builtins ------------------ - -- bpo-39382: Fix a use-after-free in the single inheritance path of - ``issubclass()``, when the ``__bases__`` of an object has a single - reference, and so does its first item. Patch by Yonatan Goldschmidt. - -- bpo-39573: Update clinic tool to use :c:func:`Py_IS_TYPE`. Patch by - Dong-hee Na. - -- bpo-39619: Enable use of :func:`os.chroot` on HP-UX systems. - -- bpo-39573: Add :c:func:`Py_IS_TYPE` static inline function to check - whether the object *o* type is *type*. - -- bpo-39606: Fix regression caused by fix for bpo-39386, that prevented - calling ``aclose`` on an async generator that had already been closed or - exhausted. - -- bpo-39579: Change the ending column offset of `Attribute` nodes - constructed in `ast_for_dotted_name` to point at the end of the current - node and not at the end of the last `NAME` node. - -- bpo-1635741: Port _crypt extension module to multiphase initialization - (:pep:`489`). - -- bpo-1635741: Port _contextvars extension module to multiphase - initialization (:pep:`489`). - -- bpo-39510: Fix segfault in ``readinto()`` method on closed BufferedReader. - -- bpo-39502: Fix :func:`time.localtime` on 64-bit AIX to support years - before 1902 and after 2038. Patch by M Felt. - -- bpo-39492: Fix a reference cycle in the C Pickler that was preventing the - garbage collection of deleted, pickled objects. - -- bpo-39453: Fixed a possible crash in :meth:`list.__contains__` when a list - is changed during comparing items. Patch by Dong-hee Na. - -- bpo-39434: :term:`floor division` of float operation now has a better - performance. Also the message of :exc:`ZeroDivisionError` for this - operation is updated. Patch by Dong-hee Na. - -- bpo-1635741: Port _codecs extension module to multiphase initialization - (:pep:`489`). - -- bpo-1635741: Port _bz2 extension module to multiphase initialization - (:pep:`489`). - -- bpo-1635741: Port _abc extension module to multiphase initialization - (:pep:`489`). - -- bpo-39320: Replace two complex bytecodes for building dicts with two - simpler ones. The new bytecodes ``DICT_MERGE`` and ``DICT_UPDATE`` have - been added The old bytecodes ``BUILD_MAP_UNPACK`` and - ``BUILD_MAP_UNPACK_WITH_CALL`` have been removed. - -- bpo-39219: Syntax errors raised in the tokenizer now always set correct - "text" and "offset" attributes. - -- bpo-36051: Drop the GIL during large ``bytes.join`` operations. Patch by - Bruce Merry. - -- bpo-38960: Fix DTrace build issues on FreeBSD. Patch by David Carlier. - -- bpo-37207: Speed up calls to ``range()`` by about 30%, by using the PEP - 590 ``vectorcall`` calling convention. Patch by Mark Shannon. - -- bpo-36144: :class:`dict` (and :class:`collections.UserDict`) objects now - support PEP 584's merge (``|``) and update (``|=``) operators. Patch by - Brandt Bucher. - -- bpo-32856: Optimized the idiom for assignment a temporary variable in - comprehensions. Now ``for y in [expr]`` in comprehensions is as fast as a - simple assignment ``y = expr``. - -Library -------- - -- bpo-30566: Fix :exc:`IndexError` when trying to decode an invalid string - with punycode codec. - -- bpo-39649: Remove obsolete check for `__args__` in - bdb.Bdb.format_stack_entry. - -- bpo-39648: Expanded :func:`math.gcd` and :func:`math.lcm` to handle - multiple arguments. - -- bpo-39681: Fix a regression where the C pickle module wouldn't allow - unpickling from a file-like object that doesn't expose a readinto() - method. - -- bpo-35950: Raise :exc:`io.UnsupportedOperation` in - :meth:`io.BufferedReader.truncate` when it is called on a read-only - :class:`io.BufferedReader` instance. - -- bpo-39479: Add :func:`math.lcm` function: least common multiple. - -- bpo-39674: Revert "Do not expose abstract collection classes in the - collections module" change (bpo-25988). Aliases to ABC like - collections.Mapping are kept in Python 3.9 to ease transition from Python - 2.7, but will be removed in Python 3.10. - -- bpo-39104: Fix hanging ProcessPoolExcutor on ``shutdown(wait=False)`` when - a task has failed pickling. - -- bpo-39627: Fixed TypedDict totality check for inherited keys. - -- bpo-39474: Fixed starting position of AST for expressions like ``(a)(b)``, - ``(a)[b]`` and ``(a).b``. - -- bpo-21016: The :mod:`pydoc` and :mod:`trace` modules now use the - :mod:`sysconfig` module to get the path to the Python standard library, to - support uncommon installation path like ``/usr/lib64/python3.9/`` on - Fedora. Patch by Jan Matějek. - -- bpo-39590: Collections.deque now holds strong references during - deque.__contains__ and deque.count, fixing crashes. - -- bpo-39586: The distutils ``bdist_msi`` command is deprecated in Python - 3.9, use ``bdist_wheel`` (wheel packages) instead. - -- bpo-39595: Improved performance of zipfile.Path for files with a large - number of entries. Also improved performance and fixed minor issue as - published with `importlib_metadata 1.5 - <https://importlib-metadata.readthedocs.io/en/latest/changelog%20(links).html#v1-5-0>`_. - -- bpo-39350: Fix regression in :class:`fractions.Fraction` if the numerator - and/or the denominator is an :class:`int` subclass. The :func:`math.gcd` - function is now used to normalize the *numerator* and *denominator*. - :func:`math.gcd` always return a :class:`int` type. Previously, the GCD - type depended on *numerator* and *denominator*. - -- bpo-39567: Added audit for :func:`os.walk`, :func:`os.fwalk`, - :meth:`pathlib.Path.glob` and :meth:`pathlib.Path.rglob`. - -- bpo-39559: Remove unused, undocumented argument ``getters`` from - :func:`uuid.getnode` - -- bpo-38149: :func:`sys.audit` is now called only once per call of - :func:`glob.glob` and :func:`glob.iglob`. - -- bpo-39546: Fix a regression in :class:`~argparse.ArgumentParser` where - ``allow_abbrev=False`` was ignored for long options that used a prefix - character other than "-". - -- bpo-39450: Striped whitespace from docstring before returning it from - :func:`unittest.case.shortDescription`. - -- bpo-12915: A new function ``resolve_name`` has been added to the - ``pkgutil`` module. This resolves a string of the form ``'a.b.c.d'`` or - ``'a.b:c.d'`` to an object. In the example, ``a.b`` is a package/module - and ``c.d`` is an object within that package/module reached via recursive - attribute access. - -- bpo-39353: The :func:`binascii.crc_hqx` function is no longer deprecated. - -- bpo-39493: Mark ``typing.IO.closed`` as a property - -- bpo-39491: Add :data:`typing.Annotated` and ``include_extras`` parameter - to :func:`typing.get_type_hints` as part of :pep:`593`. Patch by Till - Varoquaux, documentation by Till Varoquaux and Konstantin Kashin. - -- bpo-39485: Fix a bug in :func:`unittest.mock.create_autospec` that would - complain about the wrong number of arguments for custom descriptors - defined in an extension module returning functions. - -- bpo-38932: Mock fully resets child objects on reset_mock(). Patch by - Vegard Stikbakke - -- bpo-39082: Allow AsyncMock to correctly patch static/class methods - -- bpo-39432: Implement PEP-489 algorithm for non-ascii "PyInit\_..." symbol - names in distutils to make it export the correct init symbol also on - Windows. - -- bpo-18819: Omit ``devmajor`` and ``devminor`` fields for non-device files - in :mod:`tarfile` archives, enabling bit-for-bit compatibility with GNU - ``tar(1)``. - -- bpo-39349: Added a new *cancel_futures* parameter to - :meth:`concurrent.futures.Executor.shutdown` that cancels all pending - futures which have not started running, instead of waiting for them to - complete before shutting down the executor. - -- bpo-39274: ``bool(fraction.Fraction)`` now returns a boolean even if - (numerator != 0) does not return a boolean (ex: numpy number). - -- bpo-34793: Remove support for ``with (await asyncio.lock):`` and ``with - (yield from asyncio.lock):``. The same is correct for - ``asyncio.Condition`` and ``asyncio.Semaphore``. - -- bpo-25597: Ensure, if ``wraps`` is supplied to - :class:`unittest.mock.MagicMock`, it is used to calculate return values - for the magic methods instead of using the default return values. Patch by - Karthikeyan Singaravelan. - -- bpo-36350: `inspect.Signature.parameters` and - `inspect.BoundArguments.arguments` are now dicts instead of OrderedDicts. - Patch contributed by Rémi Lapeyre. - -- bpo-35727: Fix sys.exit() and sys.exit(None) exit code propagation when - used in multiprocessing.Process. - -- bpo-32173: * Add `lazycache` function to `__all__`. * Use `dict.clear` to - clear the cache. * Refactoring `getline` function and `checkcache` - function. - -Documentation -------------- - -- bpo-17422: The language reference now specifies restrictions on class - namespaces. Adapted from a patch by Ethan Furman. - -- bpo-39572: Updated documentation of ``total`` flag of ``TypedDict``. - -- bpo-39654: In pyclbr doc, update 'class' to 'module' where appropriate and - add readmodule comment. Patch by Hakan Çelik. - -- bpo-39153: Clarify refcounting semantics for the following functions: - - PyObject_SetItem - PyMapping_SetItemString - PyDict_SetItem - - PyDict_SetItemString - -- bpo-39392: Explain that when filling with turtle, overlap regions may be - left unfilled. - -- bpo-39369: Update mmap readline method description. The fact that the - readline method does update the file position should not be ignored since - this might give the impression for the programmer that it doesn't update - it. - -- bpo-9056: Include subsection in TOC for PDF version of docs. - -Tests ------ - -- bpo-38325: Skip tests on non-BMP characters of test_winconsoleio. - -- bpo-39502: Skip test_zipfile.test_add_file_after_2107() if - :func:`time.localtime` fails with :exc:`OverflowError`. It is the case on - AIX 6.1 for example. - -Build ------ - -- bpo-39489: Remove ``COUNT_ALLOCS`` special build. - -Windows -------- - -- bpo-39553: Delete unused code related to SxS manifests. - -- bpo-39439: Honor the Python path when a virtualenv is active on Windows. - -- bpo-39393: Improve the error message when attempting to load a DLL with - unresolved dependencies. - -- bpo-38883: :meth:`~pathlib.Path.home()` and - :meth:`~pathlib.Path.expanduser()` on Windows now prefer - :envvar:`USERPROFILE` and no longer use :envvar:`HOME`, which is not - normally set for regular user accounts. This makes them again behave like - :func:`os.path.expanduser`, which was changed to ignore :envvar:`HOME` in - 3.8, see :issue:`36264`. - -- bpo-39185: The build.bat script has additional options for very-quiet - output (-q) and very-verbose output (-vv) - -IDLE ----- - -- bpo-39663: Add tests for pyparse find_good_parse_start(). - -- bpo-39600: In the font configuration window, remove duplicated font names. - -- bpo-30780: Add remaining configdialog tests for buttons and highlights and - keys tabs. - -- bpo-39388: IDLE Settings Cancel button now cancels pending changes - -- bpo-38792: Close an IDLE shell calltip if a :exc:`KeyboardInterrupt` or - shell restart occurs. Patch by Zackery Spytz. - -C API ------ - -- bpo-35081: Move the ``bytes_methods.h`` header file to the internal C API - as ``pycore_bytes_methods.h``: it only contains private symbols (prefixed - by ``_Py``), except of the ``PyDoc_STRVAR_shared()`` macro. - -- bpo-35081: Move the ``dtoa.h`` header file to the internal C API as - ``pycore_dtoa.h``: it only contains private functions (prefixed by - ``_Py``). The :mod:`math` and :mod:`cmath` modules must now be compiled - with the ``Py_BUILD_CORE`` macro defined. - -- bpo-39573: Add :c:func:`Py_SET_SIZE` function to set the size of an - object. - -- bpo-39500: :c:func:`PyUnicode_IsIdentifier` does not call - :c:func:`Py_FatalError` anymore if the string is not ready. - -- bpo-39573: Add :c:func:`Py_SET_TYPE` function to set the type of an - object. - -- bpo-39573: Add a :c:func:`Py_SET_REFCNT` function to set the reference - counter of an object. - -- bpo-39542: Convert :c:func:`PyType_HasFeature`, :c:func:`PyType_Check` and - :c:func:`PyType_CheckExact` macros to static inline functions. - -- bpo-39542: In the limited C API, ``PyObject_INIT()`` and - ``PyObject_INIT_VAR()`` are now defined as aliases to - :c:func:`PyObject_Init` and :c:func:`PyObject_InitVar` to make their - implementation opaque. It avoids to leak implementation details in the - limited C API. Exclude the following functions from the limited C API: - ``_Py_NewReference()``, ``_Py_ForgetReference()``, - ``_PyTraceMalloc_NewReference()`` and ``_Py_GetRefTotal()``. - -- bpo-39542: Exclude trashcan mechanism from the limited C API: it requires - access to PyTypeObject and PyThreadState structure fields, whereas these - structures are opaque in the limited C API. - -- bpo-39511: The :c:func:`PyThreadState_Clear` function now calls the - :c:member:`PyThreadState.on_delete` callback. Previously, that happened in - :c:func:`PyThreadState_Delete`. - -- bpo-38076: Fix to clear the interpreter state only after clearing module - globals to guarantee module state access from C Extensions during runtime - destruction - -- bpo-39245: The Vectorcall API (PEP 590) was made public, adding the - functions ``PyObject_Vectorcall``, ``PyObject_VectorcallMethod``, - ``PyVectorcall_Function``, ``PyObject_CallOneArg``, - ``PyObject_CallMethodNoArgs``, ``PyObject_CallMethodOneArg``, - ``PyObject_FastCallDict``, and the flag ``Py_TPFLAGS_HAVE_VECTORCALL``. - - -What's New in Python 3.9.0 alpha 3? -=================================== - -*Release date: 2020-01-24* - -Core and Builtins ------------------ - -- bpo-39427: Document all possibilities for the ``-X`` options in the - command line help section. Patch by Pablo Galindo. - -- bpo-39421: Fix possible crashes when operating with the functions in the - :mod:`heapq` module and custom comparison operators. - -- bpo-39386: Prevent double awaiting of async iterator. - -- bpo-17005: Add :class:`functools.TopologicalSorter` to the - :mod:`functools` module to offers functionality to perform topological - sorting of graphs. Patch by Pablo Galindo, Tim Peters and Larry Hastings. - -- bpo-39320: Replace four complex bytecodes for building sequences with - three simpler ones. - - The following four bytecodes have been removed: - - * BUILD_LIST_UNPACK - * BUILD_TUPLE_UNPACK - * BUILD_SET_UNPACK - * BUILD_TUPLE_UNPACK_WITH_CALL - - The following three bytecodes have been added: - - * LIST_TO_TUPLE - * LIST_EXTEND - * SET_UPDATE - -- bpo-39336: Import loaders which publish immutable module objects can now - publish immutable packages in addition to individual modules. - -- bpo-39322: Added a new function :func:`gc.is_finalized` to check if an - object has been finalized by the garbage collector. Patch by Pablo - Galindo. - -- bpo-39048: Improve the displayed error message when incorrect types are - passed to ``async with`` statements by looking up the :meth:`__aenter__` - special method before the :meth:`__aexit__` special method when entering - an asynchronous context manager. Patch by Géry Ogam. - -- bpo-39235: Fix AST end location for lone generator expression in function - call, e.g. f(i for i in a). - -- bpo-39209: Correctly handle multi-line tokens in interactive mode. Patch - by Pablo Galindo. - -- bpo-1635741: Port _json extension module to multiphase initialization - (:pep:`489`). - -- bpo-39216: Fix constant folding optimization for positional only arguments - - by Anthony Sottile. - -- bpo-39215: Fix ``SystemError`` when nested function has annotation on - positional-only argument - by Anthony Sottile. - -- bpo-39200: Correct the error message when calling the :func:`min` or - :func:`max` with no arguments. Patch by Dong-hee Na. - -- bpo-39200: Correct the error message when trying to construct - :class:`range` objects with no arguments. Patch by Pablo Galindo. - -- bpo-39166: Fix incorrect line execution reporting in trace functions when - tracing the last iteration of asynchronous for loops. Patch by Pablo - Galindo. - -- bpo-39114: Fix incorrect line execution reporting in trace functions when - tracing exception handlers with name binding. Patch by Pablo Galindo. - -- bpo-39156: Split the COMPARE_OP bytecode instruction into four distinct - instructions. - - * COMPARE_OP for rich comparisons - * IS_OP for 'is' and 'is not' tests - * CONTAINS_OP for 'in' and 'is not' tests - * JUMP_IF_NOT_EXC_MATCH for checking exceptions in 'try-except' statements. - - This improves the clarity of the interpreter and should provide a modest - speedup. - -- bpo-38588: Fix possible crashes in dict and list when calling - :c:func:`PyObject_RichCompareBool`. - -- bpo-13601: By default, ``sys.stderr`` is line-buffered now, even if - ``stderr`` is redirected to a file. You can still make ``sys.stderr`` - unbuffered by passing the :option:`-u` command-line option or setting the - :envvar:`PYTHONUNBUFFERED` environment variable. - - (Contributed by Jendrik Seipp in bpo-13601.) - -- bpo-38610: Fix possible crashes in several list methods by holding strong - references to list elements when calling - :c:func:`PyObject_RichCompareBool`. - -- bpo-32021: Include brotli .br encoding in mimetypes encodings_map - -Library -------- - -- bpo-39430: Fixed race condition in lazy imports in :mod:`tarfile`. - -- bpo-39413: The :func:`os.unsetenv` function is now also available on - Windows. - -- bpo-39390: Fixed a regression with the `ignore` callback of - :func:`shutil.copytree`. The argument types are now str and List[str] - again. - -- bpo-39395: The :func:`os.putenv` and :func:`os.unsetenv` functions are now - always available. - -- bpo-39406: If ``setenv()`` C function is available, :func:`os.putenv` is - now implemented with ``setenv()`` instead of ``putenv()``, so Python - doesn't have to handle the environment variable memory. - -- bpo-39396: Fix ``math.nextafter(-0.0, +0.0)`` on AIX 7.1. - -- bpo-29435: Allow :func:`tarfile.is_tarfile` to be used with file and - file-like objects, like :func:`zipfile.is_zipfile`. Patch by William - Woodruff. - -- bpo-39377: Removed ``encoding`` option from :func:`json.loads`. It has - been deprecated since Python 3.1. - -- bpo-39389: Write accurate compression level metadata in :mod:`gzip` - archives, rather than always signaling maximum compression. - -- bpo-39366: The previously deprecated ``xpath()`` and ``xgtitle()`` methods - of :class:`nntplib.NNTP` have been removed. - -- bpo-39357: Remove the *buffering* parameter of :class:`bz2.BZ2File`. Since - Python 3.0, it was ignored and using it was emitting - :exc:`DeprecationWarning`. Pass an open file object, to control how the - file is opened. The *compresslevel* parameter becomes keyword-only. - -- bpo-39353: Deprecate binhex4 and hexbin4 standards. Deprecate the - :mod:`binhex` module and the following :mod:`binascii` functions: - :func:`~binascii.b2a_hqx`, :func:`~binascii.a2b_hqx`, - :func:`~binascii.rlecode_hqx`, :func:`~binascii.rledecode_hqx`, - :func:`~binascii.crc_hqx`. - -- bpo-39351: Remove ``base64.encodestring()`` and ``base64.decodestring()``, - aliases deprecated since Python 3.1: use :func:`base64.encodebytes` and - :func:`base64.decodebytes` instead. - -- bpo-39350: Remove ``fractions.gcd()`` function, deprecated since Python - 3.5 (:issue:`22486`): use :func:`math.gcd` instead. - -- bpo-39329: :class:`~smtplib.LMTP` constructor now has an optional - *timeout* parameter. Patch by Dong-hee Na. - -- bpo-39313: Add a new ``exec_function`` option (*--exec-function* in the - CLI) to ``RefactoringTool`` for making ``exec`` a function. Patch by - Batuhan Taskaya. - -- bpo-39259: :class:`~ftplib.FTP_TLS` and :class:`~ftplib.FTP_TLS` now raise - a :class:`ValueError` if the given timeout for their constructor is zero - to prevent the creation of a non-blocking socket. Patch by Dong-hee Na. - -- bpo-39259: :class:`~smtplib.SMTP` and :class:`~smtplib.SMTP_SSL` now raise - a :class:`ValueError` if the given timeout for their constructor is zero - to prevent the creation of a non-blocking socket. Patch by Dong-hee Na. - -- bpo-39310: Add :func:`math.ulp`: return the value of the least significant - bit of a float. - -- bpo-39297: Improved performance of importlib.metadata distribution - discovery and resilients to inaccessible sys.path entries - (importlib_metadata v1.4.0). - -- bpo-39259: :class:`~nntplib.NNTP` and :class:`~nntplib.NNTP_SSL` now raise - a :class:`ValueError` if the given timeout for their constructor is zero - to prevent the creation of a non-blocking socket. Patch by Dong-hee Na. - -- bpo-38901: When you specify prompt='.' or equivalently python -m venv - --prompt . ... the basename of the current directory is used to set the - created venv's prompt when it's activated. - -- bpo-39288: Add :func:`math.nextafter`: return the next floating-point - value after *x* towards *y*. - -- bpo-39259: :class:`~poplib.POP3` and :class:`~poplib.POP3_SSL` now raise a - :class:`ValueError` if the given timeout for their constructor is zero to - prevent the creation of a non-blocking socket. Patch by Dong-hee Na. - -- bpo-39242: Updated the Gmane domain from news.gmane.org to news.gmane.io - which is used for examples of :class:`~nntplib.NNTP` news reader server - and nntplib tests. - -- bpo-35292: Proxy the `SimpleHTTPRequestHandler.guess_type` to - `mimetypes.guess_type` so the `mimetypes.init` is called lazily to avoid - unnecessary costs when :mod:`http.server` module is imported. - -- bpo-39239: The :meth:`select.epoll.unregister` method no longer ignores - the :data:`~errno.EBADF` error. - -- bpo-38907: In http.server script, restore binding to IPv4 on Windows. - -- bpo-39152: Fix ttk.Scale.configure([name]) to return configuration tuple - for name or all options. Giovanni Lombardo contributed part of the patch. - -- bpo-39198: If an exception were to be thrown in `Logger.isEnabledFor` - (say, by asyncio timeouts or stopit) , the `logging` global lock may not - be released appropriately, resulting in deadlock. This change wraps that - block of code with `try...finally` to ensure the lock is released. - -- bpo-39191: Perform a check for running loop before starting a new task in - ``loop.run_until_complete()`` to fail fast; it prevents the side effect of - new task spawning before exception raising. - -- bpo-38871: Correctly parenthesize filter-based statements that contain - lambda expressions in mod:`lib2to3`. Patch by Dong-hee Na. - -- bpo-39142: A change was made to logging.config.dictConfig to avoid - converting instances of named tuples to ConvertingTuple. It's assumed that - named tuples are too specialised to be treated like ordinary tuples; if a - user of named tuples requires ConvertingTuple functionality, they will - have to implement that themselves in their named tuple class. - -- bpo-39158: ast.literal_eval() now supports empty sets. - -- bpo-39129: Fix import path for ``asyncio.TimeoutError`` - -- bpo-39057: :func:`urllib.request.proxy_bypass_environment` now ignores - leading dots and no longer ignores a trailing newline. - -- bpo-39056: Fixed handling invalid warning category in the -W option. No - longer import the re module if it is not needed. - -- bpo-39055: :func:`base64.b64decode` with ``validate=True`` raises now a - binascii.Error if the input ends with a single ``\n``. - -- bpo-21600: Fix :func:`mock.patch.stopall` to stop active patches that were - created with :func:`mock.patch.dict`. - -- bpo-39019: Implement dummy ``__class_getitem__`` for - :class:`tempfile.SpooledTemporaryFile`. - -- bpo-39019: Implement dummy ``__class_getitem__`` for ``subprocess.Popen``, - ``subprocess.CompletedProcess`` - -- bpo-38914: Adjusted the wording of the warning issued by distutils' - ``check`` command when the ``author`` and ``maintainer`` fields are - supplied but no corresponding e-mail field (``author_email`` or - ``maintainer_email``) is found. The wording now reflects the fact that - these fields are suggested, but not required. Patch by Juergen Gmach. - -- bpo-38878: Fixed __subclasshook__ of :class:`os.PathLike` to return a - correct result upon inheritance. Patch by Bar Harel. - -- bpo-38615: :class:`~imaplib.IMAP4` and :class:`~imaplib.IMAP4_SSL` now - have an optional *timeout* parameter for their constructors. Also, the - :meth:`~imaplib.IMAP4.open` method now has an optional *timeout* parameter - with this change. The overridden methods of :class:`~imaplib.IMAP4_SSL` - and :class:`~imaplib.IMAP4_stream` were applied to this change. Patch by - Dong-hee Na. - -- bpo-35182: Fixed :func:`Popen.communicate` subsequent call crash when the - child process has already closed any piped standard stream, but still - continues to be running. Patch by Andriy Maletsky. - -- bpo-38630: On Unix, :meth:`subprocess.Popen.send_signal` now polls the - process status. Polling reduces the risk of sending a signal to the wrong - process if the process completed, the :attr:`subprocess.Popen.returncode` - attribute is still ``None``, and the pid has been reassigned (recycled) to - a new different process. - -- bpo-38536: Removes trailing space in formatted currency with - `international=True` and a locale with symbol following value. E.g. - `locale.currency(12.34, international=True)` returned `'12,34 EUR '` - instead of `'12,34 EUR'`. - -- bpo-38473: Use signature from inner mock for autospecced methods attached - with :func:`unittest.mock.attach_mock`. Patch by Karthikeyan Singaravelan. - -- bpo-38361: Fixed an issue where ``ident`` could include a leading path - separator when :func:`syslog.openlog` was called without arguments. - -- bpo-38293: Add :func:`copy.copy` and :func:`copy.deepcopy` support to - :func:`property` objects. - -- bpo-37958: Added the pstats.Stats.get_profile_dict() method to return the - profile data as a StatsProfile instance. - -- bpo-28367: Termios magic constants for the following baud rates: - - B500000 - B576000 - B921600 - B1000000 - B1152000 - B1500000 - - B2000000 - B2500000 - B3000000 - B3500000 - B4000000 Patch by - Andrey Smirnov - -Documentation -------------- - -- bpo-39381: Mention in docs that :func:`asyncio.get_event_loop` implicitly - creates new event loop only if called from the main thread. - -- bpo-38918: Add an entry for ``__module__`` in the "function" & "method" - sections of the :mod:`inspect` docs' :ref:`inspect-types` table. - -- bpo-3530: In the :mod:`ast` module documentation, fix a misleading - ``NodeTransformer`` example and add advice on when to use the - ``fix_missing_locations`` function. - -Build ------ - -- bpo-39395: On non-Windows platforms, the :c:func:`setenv` and - :c:func:`unsetenv` functions are now required to build Python. - -- bpo-39160: Updated the documentation in `./configure --help` to show - default values, reference documentation where required and add additional - explanation where needed. - -- bpo-39144: The ctags and etags build targets both include Modules/_ctypes - and Python standard library source files. - -IDLE ----- - -- bpo-39050: Make IDLE Settings dialog Help button work again. - -- bpo-34118: Tag memoryview, range, and tuple as classes, the same as list, - etcetera, in the library manual built-in functions list. - -- bpo-32989: Add tests for editor newline_and_indent_event method. Remove - dead code from pyparse find_good_parse_start method. - -C API ------ - -- bpo-39372: Clean header files of interfaces defined but with no - implementation. The public API symbols being removed are: - ``_PyBytes_InsertThousandsGroupingLocale``, - ``_PyBytes_InsertThousandsGrouping``, ``_Py_InitializeFromArgs``, - ``_Py_InitializeFromWideArgs``, ``_PyFloat_Repr``, ``_PyFloat_Digits``, - ``_PyFloat_DigitsInit``, ``PyFrame_ExtendStack``, - ``_PyAIterWrapper_Type``, ``PyNullImporter_Type``, ``PyCmpWrapper_Type``, - ``PySortWrapper_Type``, ``PyNoArgsFunction``. - -- bpo-39164: Add a private ``_PyErr_GetExcInfo()`` function to retrieve - exception information of the specified Python thread state. - - -What's New in Python 3.9.0 alpha 2? -=================================== - -*Release date: 2019-12-18* - -Security --------- - -- bpo-38945: Newline characters have been escaped when performing uu - encoding to prevent them from overflowing into to content section of the - encoded file. This prevents malicious or accidental modification of data - during the decoding process. - -- bpo-37228: Due to significant security concerns, the *reuse_address* - parameter of :meth:`asyncio.loop.create_datagram_endpoint` is no longer - supported. This is because of the behavior of ``SO_REUSEADDR`` in UDP. For - more details, see the documentation for - ``loop.create_datagram_endpoint()``. (Contributed by Kyle Stanley, Antoine - Pitrou, and Yury Selivanov in :issue:`37228`.) - -- bpo-38804: Fixes a ReDoS vulnerability in :mod:`http.cookiejar`. Patch by - Ben Caller. - -Core and Builtins ------------------ - -- bpo-39028: Slightly improve the speed of keyword argument parsing with - many kwargs by strengthening the assumption that kwargs are interned - strings. - -- bpo-39080: Fix the value of *end_col_offset* for Starred Expression AST - nodes when they are among the elements in the *args* attribute of Call AST - nodes. - -- bpo-39031: When parsing an "elif" node, lineno and col_offset of the node - now point to the "elif" keyword and not to its condition, making it - consistent with the "if" node. Patch by Lysandros Nikolaou. - -- bpo-20443: In Python 3.9.0a1, sys.argv[0] was made an absolute path if a - filename was specified on the command line. Revert this change, since most - users expect sys.argv to be unmodified. - -- bpo-39008: :c:func:`PySys_Audit` now requires ``Py_ssize_t`` to be used - for size arguments in the format string, regardless of whether - ``PY_SSIZE_T_CLEAN`` was defined at include time. - -- bpo-38673: In REPL mode, don't switch to PS2 if the line starts with - comment or whitespace. Based on work by Batuhan Taşkaya. - -- bpo-38922: Calling ``replace`` on a code object now raises the - ``code.__new__`` audit event. - -- bpo-38920: Add audit hooks for when :func:`sys.excepthook` and - :func:`sys.unraisablehook` are invoked. - -- bpo-38892: Improve documentation for audit events table and functions. - -- bpo-38852: Set the thread stack size to 8 Mb for debug builds on android - platforms. - -- bpo-38858: Each Python subinterpreter now has its own "small integer - singletons": numbers in [-5; 257] range. It is no longer possible to - change the number of small integers at build time by overriding - ``NSMALLNEGINTS`` and ``NSMALLPOSINTS`` macros: macros should now be - modified manually in ``pycore_pystate.h`` header file. - -- bpo-36854: The garbage collector state becomes per interpreter - (``PyInterpreterState.gc``), rather than being global - (``_PyRuntimeState.gc``). - -- bpo-38835: The ``PyFPE_START_PROTECT()`` and ``PyFPE_END_PROTECT()`` - macros are empty: they have been doing nothing for the last year, so stop - using them. - -- bpo-38328: Sped up the creation time of constant :class:`list` and - :class:`set` displays. Patch by Brandt Bucher. - -- bpo-38707: ``MainThread.native_id`` is now correctly reset in child - processes spawned using :class:`multiprocessing.Process`, instead of - retaining the parent's value. - -- bpo-38629: Added ``__floor__`` and ``__ceil__`` methods to float object. - Patch by Batuhan Taşkaya. - -- bpo-27145: int + int and int - int operators can now return small integer - singletons. Patch by hongweipeng. - -- bpo-38021: Provide a platform tag for AIX that is sufficient for PEP425 - binary distribution identification. Patch by Michael Felt. - -- bpo-35409: Ignore GeneratorExit exceptions when throwing an exception into - the aclose coroutine of an asynchronous generator. - -- bpo-33387: Removed WITH_CLEANUP_START, WITH_CLEANUP_FINISH, BEGIN_FINALLY, - END_FINALLY, CALL_FINALLY and POP_FINALLY bytecodes. Replaced with RERAISE - and WITH_EXCEPT_START bytecodes. The compiler now generates different code - for exceptional and non-exceptional branches for 'with' and 'try-except' - statements. For 'try-finally' statements the 'finally' block is replicated - for each exit from the 'try' body. - -Library -------- - -- bpo-39033: Fix :exc:`NameError` in :mod:`zipimport`. Patch by Karthikeyan - Singaravelan. - -- bpo-39022: Update importlib.metadata to include improvements from - importlib_metadata 1.3 including better serialization of EntryPoints and - improved documentation for custom finders. - -- bpo-39006: Fix asyncio when the ssl module is missing: only check for - ssl.SSLSocket instance if the ssl module is available. - -- bpo-38708: Fix a potential IndexError in email parser when parsing an - empty msg-id. - -- bpo-38698: Add a new ``InvalidMessageID`` token to email parser to - represent invalid Message-ID headers. Also, add defects when there is - remaining value after parsing the header. - -- bpo-38994: Implement ``__class_getitem__`` for ``os.PathLike``, - ``pathlib.Path``. - -- bpo-38979: Return class from ``ContextVar.__class_getitem__`` to simplify - subclassing. - -- bpo-38978: Implement ``__class_getitem__`` on asyncio objects (Future, - Task, Queue). Patch by Batuhan Taskaya. - -- bpo-38916: :class:`array.array`: Remove ``tostring()`` and - ``fromstring()`` methods. They were aliases to ``tobytes()`` and - ``frombytes()``, deprecated since Python 3.2. - -- bpo-38986: Make repr of C accelerated TaskWakeupMethWrapper the same as of - pure Python version. - -- bpo-38982: Fix asyncio ``PidfdChildWatcher``: handle ``waitpid()`` error. - If ``waitpid()`` is called elsewhere, ``waitpid()`` call fails with - :exc:`ChildProcessError`: use return code 255 in this case, and log a - warning. It ensures that the pidfd file descriptor is closed if this error - occurs. - -- bpo-38529: Drop too noisy asyncio warning about deletion of a stream - without explicit ``.close()`` call. - -- bpo-27413: Added ability to pass through ``ensure_ascii`` options to - json.dumps in the ``json.tool`` command-line interface. - -- bpo-38634: The :mod:`readline` module now detects if Python is linked to - libedit at runtime on all platforms. Previously, the check was only done - on macOS. - -- bpo-33684: Fix ``json.tool`` failed to read a JSON file with non-ASCII - characters when locale encoding is not UTF-8. - -- bpo-38698: Prevent UnboundLocalError to pop up in parse_message_id. - - parse_message_id() was improperly using a token defined inside an - exception handler, which was raising `UnboundLocalError` on parsing an - invalid value. Patch by Claudiu Popa. - -- bpo-38927: Use ``python -m pip`` instead of ``pip`` to upgrade - dependencies in venv. - -- bpo-26730: Fix ``SpooledTemporaryFile.rollover()`` might corrupt the file - when it is in text mode. Patch by Serhiy Storchaka. - -- bpo-38881: random.choices() now raises a ValueError when all the weights - are zero. - -- bpo-38876: Raise pickle.UnpicklingError when loading an item from memo for - invalid input. - - The previous code was raising a `KeyError` for both the Python and C - implementation. This was caused by the specified index of an invalid input - which did not exist in the memo structure, where the pickle stores what - objects it has seen. The malformed input would have caused either a - `BINGET` or `LONG_BINGET` load from the memo, leading to a `KeyError` as - the determined index was bogus. Patch by Claudiu Popa - -- bpo-38688: Calling func:`shutil.copytree` to copy a directory tree from - one directory to another subdirectory resulted in an endless loop and a - RecursionError. A fix was added to consume an iterator and create the list - of the entries to be copied, avoiding the recursion for newly created - directories. Patch by Bruno P. Kinoshita. - -- bpo-38863: Improve :func:`is_cgi` function in :mod:`http.server`, which - enables processing the case that cgi directory is a child of another - directory other than root. - -- bpo-37838: :meth:`typing.get_type_hints` properly handles functions - decorated with :meth:`functools.wraps`. - -- bpo-38870: Expose :func:`ast.unparse` as a function of the :mod:`ast` - module that can be used to unparse an :class:`ast.AST` object and produce - a string with code that would produce an equivalent :class:`ast.AST` - object when parsed. Patch by Pablo Galindo and Batuhan Taskaya. - -- bpo-38859: AsyncMock now returns StopAsyncIteration on the exhaustion of a - side_effects iterable. Since PEP-479 its Impossible to raise a - StopIteration exception from a coroutine. - -- bpo-38857: AsyncMock fix for return values that are awaitable types. This - also covers side_effect iterable values that happened to be awaitable, and - wraps callables that return an awaitable type. Before these awaitables - were being awaited instead of being returned as is. - -- bpo-38834: :class:`typing.TypedDict` subclasses now track which keys are - optional using the ``__required_keys__`` and ``__optional_keys__`` - attributes, to enable runtime validation by downstream projects. Patch by - Zac Hatfield-Dodds. - -- bpo-38821: Fix unhandled exceptions in :mod:`argparse` when - internationalizing error messages for arguments with ``nargs`` set to - special (non-integer) values. Patch by Federico Bond. - -- bpo-38820: Make Python compatible with OpenSSL 3.0.0. - :func:`ssl.SSLSocket.getpeercert` no longer returns IPv6 addresses with a - trailing new line. - -- bpo-38811: Fix an unhandled exception in :mod:`pathlib` when - :meth:`os.link` is missing. Patch by Toke Høiland-Jørgensen. - -- bpo-38686: Added support for multiple ``qop`` values in - :class:`urllib.request.AbstractDigestAuthHandler`. - -- bpo-38712: Add the Linux-specific :func:`signal.pidfd_send_signal` - function, which allows sending a signal to a process identified by a file - descriptor rather than a pid. - -- bpo-38348: Add ``-i`` and ``--indent`` (indentation level), and - ``--no-type-comments`` (type comments) command line options to ast parsing - tool. - -- bpo-37523: Change :class:`zipfile.ZipExtFile` to raise ``ValueError`` when - trying to access the underlying file object after it has been closed. This - new behavior is consistent with how accessing closed files is handled in - other parts of Python. - -- bpo-38045: Improve the performance of :func:`enum._decompose` in - :mod:`enum`. Patch by hongweipeng. - -- bpo-36820: Break cycle generated when saving an exception in socket.py, - codeop.py and dyld.py as they keep alive not only the exception but user - objects through the ``__traceback__`` attribute. Patch by Mario Corchero. - -- bpo-36406: Handle namespace packages in :mod:`doctest`. Patch by - Karthikeyan Singaravelan. - -- bpo-34776: Fix dataclasses to support forward references in type - annotations - -- bpo-20928: ElementTree supports recursive XInclude processing. Patch by - Stefan Behnel. - -- bpo-29636: Add whitespace options for formatting JSON with the - ``json.tool`` CLI. The following mutually exclusive options are now - supported: ``--indent`` for setting the indent level in spaces; ``--tab`` - for indenting with tabs; ``--no-indent`` for suppressing newlines; and - ``--compact`` for suppressing all whitespace. The default behavior remains - the same as ``--indent=4``. - -Documentation -------------- - -- bpo-38928: Correct when venv's ``upgrade_dependencies()`` and - ``--upgrade-deps`` are added. - -- bpo-38899: Update documentation to state that to activate virtual - environments under fish one should use `source`, not `.` as documented at - https://fishshell.com/docs/current/commands.html#source. - -- bpo-22377: Improves documentation of the values that - :meth:`datetime.datetime.strptime` accepts for ``%Z``. Patch by Karl - Dubost. - -Tests ------ - -- bpo-38546: Fix test_ressources_gced_in_workers() of - test_concurrent_futures: explicitly stop the manager to prevent leaking a - child process running in the background after the test completes. - -- bpo-38546: Multiprocessing and concurrent.futures tests now stop the - resource tracker process when tests complete. - -- bpo-38614: Replace hardcoded timeout constants in tests with new - :mod:`test.support` constants: :data:`~test.support.LOOPBACK_TIMEOUT`, - :data:`~test.support.INTERNET_TIMEOUT`, - :data:`~test.support.SHORT_TIMEOUT` and - :data:`~test.support.LONG_TIMEOUT`. It becomes easier to adjust these four - timeout constants for all tests at once, rather than having to adjust - every single test file. - -- bpo-38547: Fix test_pty: if the process is the session leader, closing the - master file descriptor raises a SIGHUP signal: simply ignore SIGHUP when - running the tests. - -- bpo-38992: Fix a test for :func:`math.fsum` that was failing due to - constant folding. - -- bpo-38991: :mod:`test.support`: - :func:`~test.support.run_python_until_end`, - :func:`~test.support.assert_python_ok` and - :func:`~test.support.assert_python_failure` functions no longer strip - whitespaces from stderr. Remove ``test.support.strip_python_stderr()`` - function. - -- bpo-38965: Fix test_faulthandler on GCC 10. Use the "volatile" keyword in - ``faulthandler._stack_overflow()`` to prevent tail call optimization on - any compiler, rather than relying on compiler specific pragma. - -- bpo-38875: test_capi: trashcan tests now require the test "cpu" resource. - -- bpo-38841: Skip asyncio test_create_datagram_endpoint_existing_sock_unix - on platforms lacking a functional bind() for named unix domain sockets. - -- bpo-38692: Skip the test_posix.test_pidfd_open() test if - ``os.pidfd_open()`` fails with a :exc:`PermissionError`. This situation - can happen in a Linux sandbox using a syscall whitelist which doesn't - allow the ``pidfd_open()`` syscall yet. - -- bpo-38839: Fix some unused functions in tests. Patch by Adam Johnson. - -- bpo-38669: Raise :exc:`TypeError` when passing target as a string with - :meth:`unittest.mock.patch.object`. - -- bpo-37957: test.regrtest now can receive a list of test patterns to ignore - (using the -i/--ignore argument) or a file with a list of patterns to - ignore (using the --ignore-file argument). Patch by Pablo Galindo. - -Build ------ - -- bpo-37404: :mod:`asyncio` now raises :exc:`TyperError` when calling - incompatible methods with an :class:`ssl.SSLSocket` socket. Patch by Ido - Michael. - -- bpo-36500: Added an optional "regen" project to the Visual Studio solution - that will regenerate all grammar, tokens, and opcodes. - -Windows -------- - -- bpo-39007: Add auditing events to functions in :mod:`winreg`. - -- bpo-33125: Add support for building and releasing Windows ARM64 packages. - -macOS ------ - -- bpo-37931: Fixed a crash on OSX dynamic builds that occurred when - re-initializing the posix module after a Py_Finalize if the environment - had changed since the previous `import posix`. Patch by Benoît Hudson. - -IDLE ----- - -- bpo-38944: Escape key now closes IDLE completion windows. Patch by Johnny - Najera. - -- bpo-38943: Fix IDLE autocomplete windows not always appearing on some - systems. Patch by Johnny Najera. - -- bpo-38862: 'Strip Trailing Whitespace' on the Format menu removes extra - newlines at the end of non-shell files. - -- bpo-38636: Fix IDLE Format menu tab toggle and file indent width. These - functions (default shortcuts Alt-T and Alt-U) were mistakenly disabled in - 3.7.5 and 3.8.0. - -C API ------ - -- bpo-38896: Remove ``PyUnicode_ClearFreeList()`` function: the Unicode free - list has been removed in Python 3.3. - -- bpo-37340: Remove ``PyMethod_ClearFreeList()`` and - ``PyCFunction_ClearFreeList()`` functions: the free lists of bound method - objects have been removed. - -- bpo-38835: Exclude ``PyFPE_START_PROTECT()`` and ``PyFPE_END_PROTECT()`` - macros of ``pyfpe.h`` from ``Py_LIMITED_API`` (stable API). - - -What's New in Python 3.9.0 alpha 1? -=================================== - -*Release date: 2019-11-19* - -Security --------- - -- bpo-38722: :mod:`runpy` now uses :meth:`io.open_code` to open code files. - Patch by Jason Killen. - -- bpo-38622: Add additional audit events for the :mod:`ctypes` module. - -- bpo-38418: Fixes audit event for :func:`os.system` to be named - ``os.system``. - -- bpo-38243: Escape the server title of - :class:`xmlrpc.server.DocXMLRPCServer` when rendering the document page as - HTML. (Contributed by Dong-hee Na in :issue:`38243`.) - -- bpo-38174: Update vendorized expat library version to 2.2.8, which - resolves CVE-2019-15903. - -- bpo-37764: Fixes email._header_value_parser.get_unstructured going into an - infinite loop for a specific case in which the email header does not have - trailing whitespace, and the case in which it contains an invalid encoded - word. Patch by Ashwin Ramaswami. - -- bpo-37461: Fix an infinite loop when parsing specially crafted email - headers. Patch by Abhilash Raj. - -- bpo-37363: Adds audit events for the range of supported run commands (see - :ref:`using-on-general`). - -- bpo-37463: ssl.match_hostname() no longer accepts IPv4 addresses with - additional text after the address and only quad-dotted notation without - trailing whitespaces. Some inet_aton() implementations ignore whitespace - and all data after whitespace, e.g. '127.0.0.1 whatever'. - -- bpo-37363: Adds audit events for :mod:`ensurepip`, :mod:`ftplib`, - :mod:`glob`, :mod:`imaplib`, :mod:`nntplib`, :mod:`pdb`, :mod:`poplib`, - :mod:`shutil`, :mod:`smtplib`, :mod:`sqlite3`, :mod:`subprocess`, - :mod:`telnetlib`, :mod:`tempfile` and :mod:`webbrowser`, as well as - :func:`os.listdir`, :func:`os.scandir` and :func:`breakpoint`. - -- bpo-37364: :func:`io.open_code` is now used when reading :file:`.pth` - files. - -- bpo-34631: Updated OpenSSL to 1.1.1c in Windows installer - -- bpo-34155: Fix parsing of invalid email addresses with more than one ``@`` - (e.g. a@b@c.com.) to not return the part before 2nd ``@`` as valid email - address. Patch by maxking & jpic. - -Core and Builtins ------------------ - -- bpo-38631: Replace ``Py_FatalError()`` call with a regular - :exc:`RuntimeError` exception in :meth:`float.__getformat__`. - -- bpo-38639: Optimized :func:`math.floor()`, :func:`math.ceil()` and - :func:`math.trunc()` for floats. - -- bpo-38640: Fixed a bug in the compiler that was causing to raise in the - presence of break statements and continue statements inside always false - while loops. Patch by Pablo Galindo. - -- bpo-38613: Optimized some set operations (e.g. ``|``, ``^``, and ``-``) of - ``dict_keys``. ``d.keys() | other`` was slower than ``set(d) | other`` but - they are almost same performance for now. - -- bpo-28029: ``"".replace("", s, n)`` now returns ``s`` instead of an empty - string for all non-zero ``n``. There are similar changes for - :class:`bytes` and :class:`bytearray` objects. - -- bpo-38535: Fixed line numbers and column offsets for AST nodes for calls - without arguments in decorators. - -- bpo-38525: Fix a segmentation fault when using reverse iterators of empty - ``dict`` objects. Patch by Dong-hee Na and Inada Naoki. - -- bpo-38465: :class:`bytearray`, :class:`~array.array` and - :class:`~mmap.mmap` objects allow now to export more than ``2**31`` - buffers at a time. - -- bpo-38469: Fixed a bug where the scope of named expressions was not being - resolved correctly in the presence of the *global* keyword. Patch by Pablo - Galindo. - -- bpo-38437: Activate the ``GC_DEBUG`` macro for debug builds of the - interpreter (when ``Py_DEBUG`` is set). Patch by Pablo Galindo. - -- bpo-38379: When the garbage collector makes a collection in which some - objects resurrect (they are reachable from outside the isolated cycles - after the finalizers have been executed), do not block the collection of - all objects that are still unreachable. Patch by Pablo Galindo and Tim - Peters. - -- bpo-38379: When cyclic garbage collection (gc) runs finalizers that - resurrect unreachable objects, the current gc run ends, without collecting - any cyclic trash. However, the statistics reported by ``collect()`` and - ``get_stats()`` claimed that all cyclic trash found was collected, and - that the resurrected objects were collected. Changed the stats to report - that none were collected. - -- bpo-38392: In debug mode, :c:func:`PyObject_GC_Track` now calls - ``tp_traverse()`` of the object type to ensure that the object is valid: - test that objects visited by ``tp_traverse()`` are valid. - -- bpo-38210: Remove unnecessary intersection and update set operation in - dictview with empty set. (Contributed by Dong-hee Na in :issue:`38210`.) - -- bpo-38402: Check the error from the system's underlying ``crypt`` or - ``crypt_r``. - -- bpo-37474: On FreeBSD, Python no longer calls ``fedisableexcept()`` at - startup to control the floating point control mode. The call became - useless since FreeBSD 6: it became the default mode. - -- bpo-38006: Fix a bug due to the interaction of weakrefs and the cyclic - garbage collector. We must clear any weakrefs in garbage in order to - prevent their callbacks from executing and causing a crash. - -- bpo-38317: Fix warnings options priority: ``PyConfig.warnoptions`` has the - highest priority, as stated in the :pep:`587`. - -- bpo-38310: Predict ``BUILD_MAP_UNPACK_WITH_CALL`` -> ``CALL_FUNCTION_EX`` - opcode pairs in the main interpreter loop. Patch by Brandt Bucher. - -- bpo-36871: Improve error handling for the assert_has_calls and - assert_has_awaits methods of mocks. Fixed a bug where any errors - encountered while binding the expected calls to the mock's spec were - silently swallowed, leading to misleading error output. - -- bpo-11410: Better control over symbol visibility is provided through use - of the visibility attributes available in gcc >= 4.0, provided in a - uniform way across POSIX and Windows. The POSIX build files have been - updated to compile with -fvisibility=hidden, minimising exported symbols. - -- bpo-38219: Optimized the :class:`dict` constructor and the - :meth:`~dict.update` method for the case when the argument is a dict. - -- bpo-38236: Python now dumps path configuration if it fails to import the - Python codecs of the filesystem and stdio encodings. - -- bpo-38013: Allow to call ``async_generator_athrow().throw(...)`` even for - non-started async generator helper. It fixes annoying warning at the end - of :func:`asyncio.run` call. - -- bpo-38124: Fix an off-by-one error in PyState_AddModule that could cause - out-of-bounds memory access. - -- bpo-38116: The select module is now PEP-384 compliant and no longer has - static state - -- bpo-38113: ast module updated to PEP-384 and all statics removed - -- bpo-38076: The struct module is now PEP-384 compatible - -- bpo-38075: The random module is now PEP-384 compatible - -- bpo-38074: zlib module made PEP-384 compatible - -- bpo-38073: Make pwd extension module PEP-384 compatible - -- bpo-38072: grp module made PEP-384 compatible - -- bpo-38069: Make _posixsubprocess PEP-384 compatible - -- bpo-38071: Make termios extension module PEP-384 compatible - -- bpo-38005: Fixed comparing and creating of InterpreterID and ChannelID. - -- bpo-36946: Fix possible signed integer overflow when handling slices. - Patch by hongweipeng. - -- bpo-37994: Fixed silencing arbitrary errors if an attribute lookup fails - in several sites. Only AttributeError should be silenced. - -- bpo-8425: Optimize set difference_update for the case when the other set - is much larger than the base set. (Suggested by Evgeny Kapun with code - contributed by Michele Orrù). - -- bpo-37966: The implementation of :func:`~unicodedata.is_normalized` has - been greatly sped up on strings that aren't normalized, by implementing - the full normalization-quick-check algorithm from the Unicode standard. - -- bpo-37947: Adjust correctly the recursion level in the symtable generation - for named expressions. Patch by Pablo Galindo. - -- bpo-37812: The ``CHECK_SMALL_INT`` macro used inside - :file:`Object/longobject.c` has been replaced with an explicit ``return`` - at each call site. - -- bpo-37751: Fix :func:`codecs.lookup` to normalize the encoding name the - same way than :func:`encodings.normalize_encoding`, except that - :func:`codecs.lookup` also converts the name to lower case. - -- bpo-37830: Fixed compilation of :keyword:`break` and :keyword:`continue` - in the :keyword:`finally` block when the corresponding :keyword:`try` - block contains :keyword:`return` with a non-constant value. - -- bpo-20490: Improve import error message for partially initialized module - on circular ``from`` imports - by Anthony Sottile. - -- bpo-37840: Fix handling of negative indices in - :c:member:`~PySequenceMethods.sq_item` of :class:`bytearray`. Patch by - Sergey Fedoseev. - -- bpo-37802: Slightly improve performance of - :c:func:`PyLong_FromUnsignedLong`, :c:func:`PyLong_FromUnsignedLongLong` - and :c:func:`PyLong_FromSize_t`. Patch by Sergey Fedoseev. - -- bpo-37409: Ensure explicit relative imports from interactive sessions and - scripts (having no parent package) always raise ImportError, rather than - treating the current module as the package. Patch by Ben Lewis. - -- bpo-32912: Reverted :issue:`32912`: emitting :exc:`SyntaxWarning` instead - of :exc:`DeprecationWarning` for invalid escape sequences in string and - bytes literals. - -- bpo-37757: :pep:`572`: As described in the PEP, assignment expressions now - raise :exc:`SyntaxError` when their interaction with comprehension scoping - results in an ambiguous target scope. - - The ``TargetScopeError`` subclass originally proposed by the PEP has been - removed in favour of just raising regular syntax errors for the disallowed - cases. - -- bpo-36279: Fix potential use of uninitialized memory in :func:`os.wait3`. - -- bpo-36311: Decoding bytes objects larger than 2GiB is faster and no longer - fails when a multibyte characters spans a chunk boundary. - -- bpo-34880: The :keyword:`assert` statement now works properly if the - :exc:`AssertionError` exception is being shadowed. Patch by Zackery Spytz. - -- bpo-37340: Removed object cache (``free_list``) for bound method objects. - Temporary bound method objects are less used than before thanks to the - ``LOAD_METHOD`` opcode and the ``_PyObject_VectorcallMethod`` C API. - -- bpo-37648: Fixed minor inconsistency in :meth:`list.__contains__`, - :meth:`tuple.__contains__` and a few other places. The collection's item - is now always at the left and the needle is on the right of ``==``. - -- bpo-37444: Update differing exception between :meth:`builtins.__import__` - and :meth:`importlib.__import__`. - -- bpo-37619: When adding a wrapper descriptor from one class to a different - class (for example, setting ``__add__ = str.__add__`` on an ``int`` - subclass), an exception is correctly raised when the operator is called. - -- bpo-37593: Swap the positions of the *posonlyargs* and *args* parameters - in the constructor of :class:`ast.parameters` nodes. - -- bpo-37543: Optimized pymalloc for non PGO build. - -- bpo-37537: Compute allocated pymalloc blocks inside - _Py_GetAllocatedBlocks(). This slows down _Py_GetAllocatedBlocks() but - gives a small speedup to _PyObject_Malloc() and _PyObject_Free(). - -- bpo-37467: Fix :func:`sys.excepthook` and :c:func:`PyErr_Display` if a - filename is a bytes string. For example, for a SyntaxError exception where - the filename attribute is a bytes string. - -- bpo-37433: Fix ``SyntaxError`` indicator printing too many spaces for - multi-line strings - by Anthony Sottile. - -- bpo-37417: :meth:`bytearray.extend` now correctly handles errors that - arise during iteration. Patch by Brandt Bucher. - -- bpo-37414: The undocumented ``sys.callstats()`` function has been removed. - Since Python 3.7, it was deprecated and always returned ``None``. It - required a special build option ``CALL_PROFILE`` which was already removed - in Python 3.7. - -- bpo-37392: Remove ``sys.getcheckinterval()`` and - ``sys.setcheckinterval()`` functions. They were deprecated since Python - 3.2. Use :func:`sys.getswitchinterval` and :func:`sys.setswitchinterval` - instead. Remove also ``check_interval`` field of the - ``PyInterpreterState`` structure. - -- bpo-37388: In development mode and in debug build, *encoding* and *errors* - arguments are now checked on string encoding and decoding operations. - Examples: :func:`open`, :meth:`str.encode` and :meth:`bytes.decode`. - - By default, for best performances, the *errors* argument is only checked - at the first encoding/decoding error, and the *encoding* argument is - sometimes ignored for empty strings. - -- bpo-37348: Optimized decoding short ASCII string with UTF-8 and ascii - codecs. ``b"foo".decode()`` is about 15% faster. Patch by Inada Naoki. - -- bpo-24214: Improved support of the surrogatepass error handler in the - UTF-8 and UTF-16 incremental decoders. - -- bpo-37330: :func:`open`, :func:`io.open`, :func:`codecs.open` and - :class:`fileinput.FileInput` no longer accept ``'U'`` ("universal - newline") in the file mode. This flag was deprecated since Python 3.3. - -- bpo-35224: Reverse evaluation order of key: value in dict comprehensions - as proposed in PEP 572. I.e. in ``{k: v for ...}``, ``k`` will be - evaluated before ``v``. - -- bpo-37316: Fix the :c:func:`PySys_Audit` call in :class:`mmap.mmap`. - -- bpo-37300: Remove an unnecessary Py_XINCREF in classobject.c. - -- bpo-37269: Fix a bug in the peephole optimizer that was not treating - correctly constant conditions with binary operators. Patch by Pablo - Galindo. - -- bpo-20443: Python now gets the absolute path of the script filename - specified on the command line (ex: "python3 script.py"): the __file__ - attribute of the __main__ module and sys.path[0] become an absolute path, - rather than a relative path. - -- bpo-37257: Python's small object allocator (``obmalloc.c``) now allows (no - more than) one empty arena to remain available for immediate reuse, - without returning it to the OS. This prevents thrashing in simple loops - where an arena could be created and destroyed anew on each iteration. - -- bpo-37231: The dispatching of type slots to special methods (for example - calling ``__mul__`` when doing ``x * y``) has been made faster. - -- bpo-36974: Implemented separate vectorcall functions for every calling - convention of builtin functions and methods. This improves performance for - calls. - -- bpo-37213: Handle correctly negative line offsets in the peephole - optimizer. Patch by Pablo Galindo. - -- bpo-37219: Remove erroneous optimization for empty set differences. - -- bpo-15913: Implement :c:func:`PyBuffer_SizeFromFormat()` function - (previously documented but not implemented): call :func:`struct.calcsize`. - Patch by Joannah Nanjekye. - -- bpo-36922: Slot functions optimize any callable with - ``Py_TPFLAGS_METHOD_DESCRIPTOR`` instead of only instances of - ``function``. - -- bpo-36974: The slot ``tp_vectorcall_offset`` is inherited unconditionally - to support ``super().__call__()`` when the base class uses vectorcall. - -- bpo-37160: :func:`threading.get_native_id` now also supports NetBSD. - -- bpo-37077: Add :func:`threading.get_native_id` support for AIX. Patch by - M. Felt - -- bpo-36781: :func:`sum` has been optimized for boolean values. - -- bpo-34556: Add ``--upgrade-deps`` to venv module. Patch by Cooper Ry Lees - -- bpo-20523: ``pdb.Pdb`` supports ~/.pdbrc in Windows 7. Patch by Tim Hopper - and Dan Lidral-Porter. - -- bpo-35551: Updated encodings: - Removed the "tis260" encoding, which was - an alias for the nonexistent "tactis" codec. - Added "mac_centeuro" as an - alias for the mac_latin2 encoding. - -- bpo-19072: The :class:`classmethod` decorator can now wrap other - descriptors such as property objects. Adapted from a patch written by - Graham Dumpleton. - -- bpo-27575: Improve speed of dictview intersection by directly using set - intersection logic. Patch by David Su. - -- bpo-30773: Prohibit parallel running of aclose() / asend() / athrow(). Fix - ag_running to reflect the actual running status of the AG. - -Library -------- - -- bpo-36589: The :func:`curses.update_lines_cols` function now returns - ``None`` instead of ``1`` on success. - -- bpo-38807: Update :exc:`TypeError` messages for :meth:`os.path.join` to - include :class:`os.PathLike` objects as acceptable input types. - -- bpo-38724: Add a repr for ``subprocess.Popen`` objects. Patch by Andrey - Doroschenko. - -- bpo-38786: pydoc now recognizes and parses HTTPS URLs. Patch by python273. - -- bpo-38785: Prevent asyncio from crashing if parent ``__init__`` is not - called from a constructor of object derived from ``asyncio.Future``. - -- bpo-38723: :mod:`pdb` now uses :meth:`io.open_code` to trigger auditing - events. - -- bpo-27805: Allow opening pipes and other non-seekable files in append mode - with :func:`open`. - -- bpo-38438: Simplify the :mod:`argparse` usage message for ``nargs="*"``. - -- bpo-38761: WeakSet is now registered as a collections.abc.MutableSet. - -- bpo-38716: logging: change RotatingHandler namer and rotator to - class-level attributes. This stops __init__ from setting them to None in - the case where a subclass defines them with eponymous methods. - -- bpo-38713: Add :data:`os.P_PIDFD` constant, which may be passed to - :func:`os.waitid` to wait on a Linux process file descriptor. - -- bpo-38692: Add :class:`asyncio.PidfdChildWatcher`, a Linux-specific child - watcher implementation that polls process file descriptors. - -- bpo-38692: Expose the Linux ``pidfd_open`` syscall as - :func:`os.pidfd_open`. - -- bpo-38602: Added constants :data:`~fcntl.F_OFD_GETLK`, - :data:`~fcntl.F_OFD_SETLK` and :data:`~fcntl.F_OFD_SETLKW` to the - :mod:`fcntl` module. Patch by Dong-hee Na. - -- bpo-38334: Fixed seeking backward on an encrypted - :class:`zipfile.ZipExtFile`. - -- bpo-38312: Add :func:`curses.get_escdelay`, :func:`curses.set_escdelay`, - :func:`curses.get_tabsize`, and :func:`curses.set_tabsize` functions - by - Anthony Sottile. - -- bpo-38586: Now :func:`~logging.config.fileConfig` correctly sets the .name - of handlers loaded. - -- bpo-38565: Add new cache_parameters() method for functools.lru_cache() to - better support pickling. - -- bpo-34679: asynci.ProactorEventLoop.close() now only calls - signal.set_wakeup_fd() in the main thread. - -- bpo-31202: The case the result of :func:`pathlib.WindowsPath.glob` matches - now the case of the pattern for literal parts. - -- bpo-36321: Remove misspelled attribute. The 3.8 changelog noted that this - would be removed in 3.9. - -- bpo-38521: Fixed erroneous equality comparison in statistics.NormalDist(). - -- bpo-38493: Added :data:`~os.CLD_KILLED` and :data:`~os.CLD_STOPPED` for - :attr:`si_code`. Patch by Dong-hee Na. - -- bpo-38478: Fixed a bug in :meth:`inspect.signature.bind` that was causing - it to fail when handling a keyword argument with same name as - positional-only parameter. Patch by Pablo Galindo. - -- bpo-33604: Fixed `hmac.new` and `hmac.HMAC` to raise TypeError instead of - ValueError when the digestmod parameter, now required in 3.8, is omitted. - Also clarified the hmac module documentation and docstrings. - -- bpo-38378: Parameters *out* and *in* of :func:`os.sendfile` was renamed to - *out_fd* and *in_fd*. - -- bpo-38417: Added support for setting the umask in the child process to the - subprocess module on POSIX systems. - -- bpo-38449: Revert PR 15522, which introduces a regression in - :meth:`mimetypes.guess_type` due to improper handling of filenames as - urls. - -- bpo-38431: Fix ``__repr__`` method for :class:`dataclasses.InitVar` to - support typing objects, patch by Samuel Colvin. - -- bpo-38109: Add missing :data:`stat.S_IFDOOR`, :data:`stat.S_IFPORT`, - :data:`stat.S_IFWHT`, :func:`stat.S_ISDOOR`, :func:`stat.S_ISPORT`, and - :func:`stat.S_ISWHT` values to the Python implementation of :mod:`stat`. - -- bpo-38422: Clarify docstrings of pathlib suffix(es) - -- bpo-38405: Nested subclasses of :class:`typing.NamedTuple` are now - pickleable. - -- bpo-38332: Prevent :exc:`KeyError` thrown by :func:`_encoded_words.decode` - when given an encoded-word with invalid content-type encoding from - propagating all the way to :func:`email.message.get`. - -- bpo-38371: Deprecated the ``split()`` method in - :class:`_tkinter.TkappType` in favour of the ``splitlist()`` method which - has more consistent and predicable behavior. - -- bpo-38341: Add :exc:`smtplib.SMTPNotSupportedError` to the :mod:`smtplib` - exported names. - -- bpo-38319: sendfile() used in socket and shutil modules was raising - OverflowError for files >= 2GiB on 32-bit architectures. (patch by - Giampaolo Rodola) - -- bpo-38242: Revert the new asyncio Streams API - -- bpo-13153: OS native encoding is now used for converting between Python - strings and Tcl objects. This allows to display, copy and paste to - clipboard emoji and other non-BMP characters. Converting strings from Tcl - to Python and back now never fails (except MemoryError). - -- bpo-38019: Correctly handle pause/resume reading of closed asyncio unix - pipe. - -- bpo-38163: Child mocks will now detect their type as either synchronous or - asynchronous, asynchronous child mocks will be AsyncMocks and synchronous - child mocks will be either MagicMock or Mock (depending on their parent - type). - -- bpo-38161: Removes _AwaitEvent from AsyncMock. - -- bpo-38216: Allow the rare code that wants to send invalid http requests - from the `http.client` library a way to do so. The fixes for bpo-30458 - led to breakage for some projects that were relying on this ability to - test their own behavior in the face of bad requests. - -- bpo-28286: Deprecate opening :class:`~gzip.GzipFile` for writing - implicitly. Always specify the *mode* argument for writing. - -- bpo-38108: Any synchronous magic methods on an AsyncMock now return a - MagicMock. Any asynchronous magic methods on a MagicMock now return an - AsyncMock. - -- bpo-38265: Update the *length* parameter of :func:`os.pread` to accept - :c:type:`Py_ssize_t` instead of :c:expr:`int`. - -- bpo-38112: :mod:`compileall` has a higher default recursion limit and new - command-line arguments for path manipulation, symlinks handling, and - multiple optimization levels. - -- bpo-38248: asyncio: Fix inconsistent immediate Task cancellation - -- bpo-38237: The arguments for the builtin pow function are more - descriptive. They can now also be passed in as keywords. - -- bpo-34002: Improve efficiency in parts of email package by changing - while-pop to a for loop, using isdisjoint instead of set intersections. - -- bpo-38191: Constructors of :class:`~typing.NamedTuple` and - :class:`~typing.TypedDict` types now accept arbitrary keyword argument - names, including "cls", "self", "typename", "_typename", "fields" and - "_fields". - -- bpo-38155: Add ``__all__`` to :mod:`datetime`. Patch by Tahia Khan. - -- bpo-38185: Fixed case-insensitive string comparison in - :class:`sqlite3.Row` indexing. - -- bpo-38136: Changes AsyncMock call count and await count to be two - different counters. Now await count only counts when a coroutine has been - awaited, not when it has been called, and vice-versa. Update the - documentation around this. - -- bpo-37828: Fix default mock name in - :meth:`unittest.mock.Mock.assert_called` exceptions. Patch by Abraham - Toriz Cruz. - -- bpo-38175: Fix a memory leak in comparison of :class:`sqlite3.Row` - objects. - -- bpo-33936: _hashlib no longer calls obsolete OpenSSL initialization - function with OpenSSL 1.1.0+. - -- bpo-34706: Preserve subclassing in inspect.Signature.from_callable. - -- bpo-38153: Names of hashing algorithms from OpenSSL are now normalized to - follow Python's naming conventions. For example OpenSSL uses sha3-512 - instead of sha3_512 or blake2b512 instead of blake2b. - -- bpo-38115: Fix a bug in dis.findlinestarts() where it would return invalid - bytecode offsets. Document that a code object's co_lnotab can contain - invalid bytecode offsets. - -- bpo-38148: Add slots to :mod:`asyncio` transport classes, which can reduce - memory usage. - -- bpo-38142: The _hashlib OpenSSL wrapper extension module is now PEP-384 - compliant. - -- bpo-9216: hashlib constructors now support usedforsecurity flag to signal - that a hashing algorithm is not used in a security context. - -- bpo-36991: Fixes a potential incorrect AttributeError exception escaping - ZipFile.extract() in some unsupported input error situations. - -- bpo-38134: Remove obsolete copy of PBKDF2_HMAC_fast. All supported OpenSSL - versions contain a fast implementation. - -- bpo-38132: The OpenSSL hashlib wrapper uses a simpler implementation. - Several Macros and pointless caches are gone. The hash name now comes from - OpenSSL's EVP. The algorithm name stays the same, except it is now always - lower case. - -- bpo-38008: Fix parent class check in protocols to correctly identify the - module that provides a builtin protocol, instead of assuming they all come - from the :mod:`collections.abc` module - -- bpo-34037: For :mod:`asyncio`, add a new coroutine - :meth:`loop.shutdown_default_executor`. The new coroutine provides an API - to schedule an executor shutdown that waits on the threadpool to finish - closing. Also, :func:`asyncio.run` has been updated to utilize the new - coroutine. Patch by Kyle Stanley. - -- bpo-37405: Fixed regression bug for socket.getsockname() for non-CAN_ISOTP - AF_CAN address family sockets by returning a 1-tuple instead of string. - -- bpo-38121: Update parameter names on functions in importlib.metadata - matching the changes in the 0.22 release of importlib_metadata. - -- bpo-38110: The os.closewalk() implementation now uses the libc fdwalk() - API on platforms where it is available. - -- bpo-38093: Fixes AsyncMock so it doesn't crash when used with - AsyncContextManagers or AsyncIterators. - -- bpo-37488: Add warning to :meth:`datetime.utctimetuple`, - :meth:`datetime.utcnow` and :meth:`datetime.utcfromtimestamp` . - -- bpo-35640: Allow passing a :term:`path-like object` as ``directory`` - argument to the :class:`http.server.SimpleHTTPRequestHandler` class. Patch - by Géry Ogam. - -- bpo-38086: Update importlib.metadata with changes from `importlib_metadata - 0.21 - <https://gitlab.com/python-devs/importlib_metadata/blob/0.21/importlib_metadata/docs/changelog.rst>`_. - -- bpo-37251: Remove `__code__` check in AsyncMock that incorrectly evaluated - function specs as async objects but failed to evaluate classes with - `__await__` but no `__code__` attribute defined as async objects. - -- bpo-38037: Fix reference counters in the :mod:`signal` module. - -- bpo-38066: Hide internal asyncio.Stream methods: feed_eof(), feed_data(), - set_exception() and set_transport(). - -- bpo-38059: inspect.py now uses sys.exit() instead of exit() - -- bpo-38049: Added command-line interface for the :mod:`ast` module. - -- bpo-37953: In :mod:`typing`, improved the ``__hash__`` and ``__eq__`` - methods for :class:`ForwardReferences`. - -- bpo-38026: Fixed :func:`inspect.getattr_static` used ``isinstance`` while - it should avoid dynamic lookup. - -- bpo-35923: Update :class:`importlib.machinery.BuiltinImporter` to use - ``loader._ORIGIN`` instead of a hardcoded value. Patch by Dong-hee Na. - -- bpo-38010: In ``importlib.metadata`` sync with ``importlib_metadata`` - 0.20, clarifying behavior of ``files()`` and fixing issue where only one - requirement was returned for ``requires()`` on ``dist-info`` packages. - -- bpo-38006: weakref.WeakValueDictionary defines a local remove() function - used as callback for weak references. This function was created with a - closure. Modify the implementation to avoid the closure. - -- bpo-37995: Added the *indent* option to :func:`ast.dump` which allows it - to produce a multiline indented output. - -- bpo-34410: Fixed a crash in the :func:`tee` iterator when re-enter it. - RuntimeError is now raised in this case. - -- bpo-37140: Fix a ctypes regression of Python 3.8. When a ctypes.Structure - is passed by copy to a function, ctypes internals created a temporary - object which had the side effect of calling the structure finalizer - (__del__) twice. The Python semantics requires a finalizer to be called - exactly once. Fix ctypes internals to no longer call the finalizer twice. - -- bpo-37587: ``_json.scanstring`` is now up to 3x faster when there are many - backslash escaped characters in the JSON string. - -- bpo-37834: Prevent shutil.rmtree exception when built on non-Windows - system without fd system call support, like older versions of macOS. - -- bpo-10978: Semaphores and BoundedSemaphores can now release more than one - waiting thread at a time. - -- bpo-37972: Subscripts to the `unittest.mock.call` objects now receive the - same chaining mechanism as any other custom attributes, so that the - following usage no longer raises a `TypeError`: - - call().foo().__getitem__('bar') - - Patch by blhsing - -- bpo-37965: Fix C compiler warning caused by - distutils.ccompiler.CCompiler.has_function. - -- bpo-37964: Add ``F_GETPATH`` command to :mod:`fcntl`. - -- bpo-37960: ``repr()`` of buffered and text streams now silences only - expected exceptions when get the value of "name" and "mode" attributes. - -- bpo-37961: Add a ``total_nframe`` field to the traces collected by the - tracemalloc module. This field indicates the original number of frames - before it was truncated. - -- bpo-37951: Most features of the subprocess module now work again in - subinterpreters. Only *preexec_fn* is restricted in subinterpreters. - -- bpo-36205: Fix the rusage implementation of time.process_time() to - correctly report the sum of the system and user CPU time. - -- bpo-37950: Fix :func:`ast.dump` when call with incompletely initialized - node. - -- bpo-34679: Restores instantiation of Windows IOCP event loops from the - non-main thread. - -- bpo-36917: Add default implementation of the - :meth:`ast.NodeVisitor.visit_Constant` method which emits a deprecation - warning and calls corresponding methody ``visit_Num()``, ``visit_Str()``, - etc. - -- bpo-37798: Update test_statistics.py to verify that the statistics module - works well for both C and Python implementations. Patch by Dong-hee Na - -- bpo-26589: Added a new status code to the http module: 451 - UNAVAILABLE_FOR_LEGAL_REASONS - -- bpo-37915: Fix a segmentation fault that appeared when comparing instances - of ``datetime.timezone`` and ``datetime.tzinfo`` objects. Patch by Pablo - Galindo. - -- bpo-32554: Deprecate having random.seed() call hash on arbitrary types. - -- bpo-9938: Add optional keyword argument ``exit_on_error`` for - :class:`ArgumentParser`. - -- bpo-37851: The :mod:`faulthandler` module no longer allocates its - alternative stack at Python startup. Now the stack is only allocated at - the first faulthandler usage. - -- bpo-32793: Fix a duplicated debug message when - :meth:`smtplib.SMTP.connect` is called. - -- bpo-37885: venv: Don't generate unset variable warning on deactivate. - -- bpo-37868: Fix dataclasses.is_dataclass when given an instance that never - raises AttributeError in __getattr__. That is, an object that returns - something for __dataclass_fields__ even if it's not a dataclass. - -- bpo-37811: Fix ``socket`` module's ``socket.connect(address)`` function - being unable to establish connection in case of interrupted system call. - The problem was observed on all OSes which ``poll(2)`` system call can - take only non-negative integers and -1 as a timeout value. - -- bpo-37863: Optimizations for Fraction.__hash__ suggested by Tim Peters. - -- bpo-21131: Fix ``faulthandler.register(chain=True)`` stack. faulthandler - now allocates a dedicated stack of ``SIGSTKSZ*2`` bytes, instead of just - ``SIGSTKSZ`` bytes. Calling the previous signal handler in faulthandler - signal handler uses more than ``SIGSTKSZ`` bytes of stack memory on some - platforms. - -- bpo-37798: Add C fastpath for statistics.NormalDist.inv_cdf() Patch by - Dong-hee Na - -- bpo-37804: Remove the deprecated method `threading.Thread.isAlive()`. - Patch by Dong-hee Na. - -- bpo-37819: Add Fraction.as_integer_ratio() to match the corresponding - methods in bool, int, float, and decimal. - -- bpo-14465: Add an xml.etree.ElementTree.indent() function for - pretty-printing XML trees. Contributed by Stefan Behnel. - -- bpo-37810: Fix :mod:`difflib` ``?`` hint in diff output when dealing with - tabs. Patch by Anthony Sottile. - -- bpo-37772: In ``zipfile.Path``, when adding implicit dirs, ensure that - ancestral directories are added and that duplicates are excluded. - -- bpo-18578: Renamed and documented `test.bytecode_helper` as - `test.support.bytecode_helper`. Patch by Joannah Nanjekye. - -- bpo-37785: Fix xgettext warnings in :mod:`argparse`. - -- bpo-34488: :meth:`writelines` method of :class:`io.BytesIO` is now - slightly faster when many small lines are passed. Patch by Sergey - Fedoseev. - -- bpo-37449: `ensurepip` now uses `importlib.resources.read_binary()` to - read data instead of `pkgutil.get_data()`. Patch by Joannah Nanjekye. - -- bpo-28292: Mark calendar.py helper functions as being private. The - follows PEP 8 guidance to maintain the style conventions in the module and - it addresses a known case of user confusion. - -- bpo-18049: Add definition of THREAD_STACK_SIZE for AIX in - Python/thread_pthread.h The default thread stacksize caused crashes with - the default recursion limit Patch by M Felt - -- bpo-37742: The logging.getLogger() API now returns the root logger when - passed the name 'root', whereas previously it returned a non-root logger - named 'root'. This could affect cases where user code explicitly wants a - non-root logger named 'root', or instantiates a logger using - logging.getLogger(__name__) in some top-level module called 'root.py'. - -- bpo-37738: Fix the implementation of curses ``addch(str, color_pair)``: - pass the color pair to ``setcchar()``, instead of always passing 0 as the - color pair. - -- bpo-37723: Fix performance regression on regular expression parsing with - huge character sets. Patch by Yann Vaginay. - -- bpo-35943: The function :c:func:`PyImport_GetModule` now ensures any - module it returns is fully initialized. Patch by Joannah Nanjekye. - -- bpo-32178: Fix IndexError in :mod:`email` package when trying to parse - invalid address fields starting with ``:``. - -- bpo-37268: The :mod:`parser` module is deprecated and will be removed in - future versions of Python. - -- bpo-11953: Completing WSA* error codes in :mod:`socket`. - -- bpo-37685: Fixed comparisons of :class:`datetime.timedelta` and - :class:`datetime.timezone`. - -- bpo-37697: Synchronize ``importlib.metadata`` with `importlib_metadata - 0.19 - <https://gitlab.com/python-devs/importlib_metadata/-/milestones/20>`_, - improving handling of EGG-INFO files and fixing a crash when entry point - names contained colons. - -- bpo-37695: Correct :func:`curses.unget_wch` error message. Patch by - Anthony Sottile. - -- bpo-37689: Add :meth:`is_relative_to` in :class:`PurePath` to determine - whether or not one path is relative to another. - -- bpo-29553: Fixed :meth:`argparse.ArgumentParser.format_usage` for mutually - exclusive groups. Patch by Andrew Nester. - -- bpo-37691: Let math.dist() accept coordinates as sequences (or iterables) - rather than just tuples. - -- bpo-37685: Fixed ``__eq__``, ``__lt__`` etc implementations in some - classes. They now return :data:`NotImplemented` for unsupported type of - the other operand. This allows the other operand to play role (for example - the equality comparison with :data:`~unittest.mock.ANY` will return - ``True``). - -- bpo-37354: Make Activate.ps1 Powershell script static to allow for signing - it. - -- bpo-37664: Update wheels bundled with ensurepip (pip 19.2.3 and setuptools - 41.2.0) - -- bpo-37663: Bring consistency to venv shell activation scripts by always - using __VENV_PROMPT__. - -- bpo-37642: Allowed the pure Python implementation of - :class:`datetime.timezone` to represent sub-minute offsets close to - minimum and maximum boundaries, specifically in the ranges (23:59, 24:00) - and (-23:59, 24:00). Patch by Ngalim Siregar - -- bpo-36161: In :mod:`posix`, use ``ttyname_r`` instead of ``ttyname`` for - thread safety. - -- bpo-36324: Make internal attributes for statistics.NormalDist() private. - -- bpo-37555: Fix `NonCallableMock._call_matcher` returning tuple instead of - `_Call` object when `self._spec_signature` exists. Patch by Elizabeth - Uselton - -- bpo-29446: Make `from tkinter import *` import only the expected objects. - -- bpo-16970: Adding a value error when an invalid value in passed to nargs - Patch by Robert Leenders - -- bpo-34443: Exceptions from :mod:`enum` now use the ``__qualname`` of the - enum class in the exception message instead of the ``__name__``. - -- bpo-37491: Fix ``IndexError`` when parsing email headers with unexpectedly - ending bare-quoted string value. Patch by Abhilash Raj. - -- bpo-37587: Make json.loads faster for long strings. (Patch by Marco - Paolini) - -- bpo-18378: Recognize "UTF-8" as a valid value for LC_CTYPE in - locale._parse_localename. - -- bpo-37579: Return :exc:`NotImplemented` in Python implementation of - ``__eq__`` for :class:`~datetime.timedelta` and :class:`~datetime.time` - when the other object being compared is not of the same type to match C - implementation. Patch by Karthikeyan Singaravelan. - -- bpo-21478: Record calls to parent when autospecced object is attached to a - mock using :func:`unittest.mock.attach_mock`. Patch by Karthikeyan - Singaravelan. - -- bpo-37531: "python3 -m test -jN --timeout=TIMEOUT" now kills a worker - process if it runs longer than *TIMEOUT* seconds. - -- bpo-37482: Fix serialization of display name in originator or destination - address fields with both encoded words and special chars. - -- bpo-36993: Improve error reporting for corrupt zip files with bad zip64 - extra data. Patch by Daniel Hillier. - -- bpo-37502: pickle.loads() no longer raises TypeError when the buffers - argument is set to None - -- bpo-37520: Correct behavior for zipfile.Path.parent when the path object - identifies a subdirectory. - -- bpo-18374: Fix the ``.col_offset`` attribute of nested :class:`ast.BinOp` - instances which had a too large value in some situations. - -- bpo-37424: Fixes a possible hang when using a timeout on - `subprocess.run()` while capturing output. If the child process spawned - its own children or otherwise connected its stdout or stderr handles with - another process, we could hang after the timeout was reached and our child - was killed when attempting to read final output from the pipes. - -- bpo-37421: Fix :func:`multiprocessing.util.get_temp_dir` finalizer: clear - also the 'tempdir' configuration of the current process, so next call to - ``get_temp_dir()`` will create a new temporary directory, rather than - reusing the removed temporary directory. - -- bpo-37481: The distutils ``bdist_wininst`` command is deprecated in Python - 3.8, use ``bdist_wheel`` (wheel packages) instead. - -- bpo-37479: When `Enum.__str__` is overridden in a derived class, the - override will be used by `Enum.__format__` regardless of whether mixin - classes are present. - -- bpo-37440: http.client now enables TLS 1.3 post-handshake authentication - for default context or if a cert_file is passed to HTTPSConnection. - -- bpo-37437: Update vendorized expat version to 2.2.7. - -- bpo-37428: SSLContext.post_handshake_auth = True no longer sets - SSL_VERIFY_POST_HANDSHAKE verify flag for client connections. Although the - option is documented as ignored for clients, OpenSSL implicitly enables - cert chain validation when the flag is set. - -- bpo-37420: :func:`os.sched_setaffinity` now correctly handles errors that - arise during iteration over its ``mask`` argument. Patch by Brandt Bucher. - -- bpo-37412: The :func:`os.getcwdb` function now uses the UTF-8 encoding on - Windows, rather than the ANSI code page: see :pep:`529` for the rationale. - The function is no longer deprecated on Windows. - -- bpo-37406: The sqlite3 module now raises TypeError, rather than - ValueError, if operation argument type is not str: execute(), - executemany() and calling a connection. - -- bpo-29412: Fix IndexError in parsing a header value ending unexpectedly. - Patch by Abhilash Raj. - -- bpo-36546: The *dist* argument for statistics.quantiles() is now - positional only. The current name doesn't reflect that the argument can be - either a dataset or a distribution. Marking the parameter as positional - avoids confusion and makes it possible to change the name later. - -- bpo-37394: Fix a bug that was causing the :mod:`queue` module to fail if - the accelerator module was not available. Patch by Pablo Galindo. - -- bpo-37376: :mod:`pprint` now has support for - :class:`types.SimpleNamespace`. Patch by Carl Bordum Hansen. - -- bpo-26967: An :class:`~argparse.ArgumentParser` with - ``allow_abbrev=False`` no longer disables grouping of short flags, such as - ``-vv``, but only disables abbreviation of long flags as documented. Patch - by Zac Hatfield-Dodds. - -- bpo-37212: :func:`unittest.mock.call` now preserves the order of keyword - arguments in repr output. Patch by Karthikeyan Singaravelan. - -- bpo-37372: Fix error unpickling datetime.time objects from Python 2 with - seconds>=24. Patch by Justin Blanchard. - -- bpo-37345: Add formal support for UDPLITE sockets. Support was present - before, but it is now easier to detect support with ``hasattr(socket, - 'IPPROTO_UDPLITE')`` and there are constants defined for each of the - values needed: :py:obj:`socket.IPPROTO_UDPLITE`, - :py:obj:`UDPLITE_SEND_CSCOV`, and :py:obj:`UDPLITE_RECV_CSCOV`. Patch by - Gabe Appleton. - -- bpo-37358: Optimized ``functools.partial`` by using vectorcall. - -- bpo-37347: :meth:`sqlite3.Connection.create_aggregate`, - :meth:`sqlite3.Connection.create_function`, - :meth:`sqlite3.Connection.set_authorizer`, - :meth:`sqlite3.Connection.set_progress_handler` - :meth:`sqlite3.Connection.set_trace_callback` methods lead to segfaults if - some of these methods are called twice with an equal object but not the - same. Now callbacks are stored more carefully. Patch by Aleksandr Balezin. - -- bpo-37163: The *obj* argument of :func:`dataclasses.replace` is - positional-only now. - -- bpo-37085: Add the optional Linux SocketCAN Broadcast Manager constants, - used as flags to configure the BCM behaviour, in the socket module. Patch - by Karl Ding. - -- bpo-37328: ``HTMLParser.unescape`` is removed. It was undocumented and - deprecated since Python 3.4. - -- bpo-37305: Add .webmanifest -> application/manifest+json to list of - recognized file types and content type headers - -- bpo-37320: ``aifc.openfp()`` alias to ``aifc.open()``, ``sunau.openfp()`` - alias to ``sunau.open()``, and ``wave.openfp()`` alias to ``wave.open()`` - have been removed. They were deprecated since Python 3.7. - -- bpo-37315: Deprecated accepting floats with integral value (like ``5.0``) - in :func:`math.factorial`. - -- bpo-37312: ``_dummy_thread`` and ``dummy_threading`` modules have been - removed. These modules were deprecated since Python 3.7 which requires - threading support. - -- bpo-33972: Email with single part but content-type set to ``multipart/*`` - doesn't raise AttributeError anymore. - -- bpo-37280: Use threadpool for reading from file for sendfile fallback - mode. - -- bpo-37279: Fix asyncio sendfile support when sendfile sends extra data in - fallback mode. - -- bpo-19865: :func:`ctypes.create_unicode_buffer()` now also supports - non-BMP characters on platforms with 16-bit :c:type:`wchar_t` (for - example, Windows and AIX). - -- bpo-37266: In a subinterpreter, spawning a daemon thread now raises an - exception. Daemon threads were never supported in subinterpreters. - Previously, the subinterpreter finalization crashed with a Python fatal - error if a daemon thread was still running. - -- bpo-37210: Allow pure Python implementation of :mod:`pickle` to work even - when the C :mod:`_pickle` module is unavailable. - -- bpo-21872: Fix :mod:`lzma`: module decompresses data incompletely. When - decompressing a FORMAT_ALONE format file, and it doesn't have the end - marker, sometimes the last one to dozens bytes can't be output. Patch by - Ma Lin. - -- bpo-35922: Fix :meth:`RobotFileParser.crawl_delay` and - :meth:`RobotFileParser.request_rate` to return ``None`` rather than raise - :exc:`AttributeError` when no relevant rule is defined in the robots.txt - file. Patch by Rémi Lapeyre. - -- bpo-35766: Change the format of feature_version to be a (major, minor) - tuple. - -- bpo-36607: Eliminate :exc:`RuntimeError` raised by - :func:`asyncio.all_tasks()` if internal tasks weak set is changed by - another thread during iteration. - -- bpo-18748: :class:`_pyio.IOBase` destructor now does nothing if getting - the ``closed`` attribute fails to better mimic :class:`_io.IOBase` - finalizer. - -- bpo-36402: Fix a race condition at Python shutdown when waiting for - threads. Wait until the Python thread state of all non-daemon threads get - deleted (join all non-daemon threads), rather than just wait until - non-daemon Python threads complete. - -- bpo-37206: Default values which cannot be represented as Python objects no - longer improperly represented as ``None`` in function signatures. - -- bpo-37111: Added ``encoding`` and ``errors`` keyword parameters to - ``logging.basicConfig``. - -- bpo-12144: Ensure cookies with ``expires`` attribute are handled in - :meth:`CookieJar.make_cookies`. - -- bpo-34886: Fix an unintended ValueError from :func:`subprocess.run` when - checking for conflicting `input` and `stdin` or `capture_output` and - `stdout` or `stderr` args when they were explicitly provided but with - `None` values within a passed in `**kwargs` dict rather than as passed - directly by name. Patch contributed by Rémi Lapeyre. - -- bpo-37173: The exception message for ``inspect.getfile()`` now correctly - reports the passed class rather than the builtins module. - -- bpo-37178: Give math.perm() a one argument form that means the same as - math.factorial(). - -- bpo-37178: For math.perm(n, k), let k default to n, giving the same result - as factorial. - -- bpo-37165: Converted _collections._count_elements to use the Argument - Clinic. - -- bpo-34767: Do not always create a :class:`collections.deque` in - :class:`asyncio.Lock`. - -- bpo-37158: Speed-up statistics.fmean() by switching from a function to a - generator. - -- bpo-34282: Remove ``Enum._convert`` method, deprecated in 3.8. - -- bpo-37150: `argparse._ActionsContainer.add_argument` now throws error, if - someone accidentally pass FileType class object instead of instance of - FileType as `type` argument - -- bpo-28724: The socket module now has the :func:`socket.send_fds` and - :func:`socket.recv.fds` methods. Contributed by Joannah Nanjekye, Shinya - Okano and Victor Stinner. - -- bpo-35621: Support running asyncio subprocesses when execution event loop - in a thread on UNIX. - -- bpo-36520: Lengthy email headers with UTF-8 characters are now properly - encoded when they are folded. Patch by Jeffrey Kintscher. - -- bpo-30835: Fixed a bug in email parsing where a message with invalid bytes - in content-transfer-encoding of a multipart message can cause an - AttributeError. Patch by Andrew Donnellan. - -- bpo-31163: pathlib.Path instance's rename and replace methods now return - the new Path instance. - -- bpo-25068: :class:`urllib.request.ProxyHandler` now lowercases the keys of - the passed dictionary. - -- bpo-26185: Fix :func:`repr` on empty :class:`ZipInfo` object. Patch by - Mickaël Schoentgen. - -- bpo-21315: Email headers containing RFC2047 encoded words are parsed - despite the missing whitespace, and a defect registered. Also missing - trailing whitespace after encoded words is now registered as a defect. - -- bpo-31904: Port test_datetime to VxWorks: skip zoneinfo tests on VxWorks - -- bpo-35805: Add parser for Message-ID header and add it to default - HeaderRegistry. This should prevent folding of Message-ID using RFC 2048 - encoded words. - -- bpo-36871: Ensure method signature is used instead of constructor - signature of a class while asserting mock object against method calls. - Patch by Karthikeyan Singaravelan. - -- bpo-35070: posix.getgrouplist() now works correctly when the user belongs - to NGROUPS_MAX supplemental groups. Patch by Jeffrey Kintscher. - -- bpo-31783: Fix race condition in ThreadPoolExecutor when worker threads - are created during interpreter shutdown. - -- bpo-36582: Fix ``UserString.encode()`` to correctly return ``bytes`` - rather than a ``UserString`` instance. - -- bpo-32424: Deprecate xml.etree.ElementTree.Element.copy() in favor of - copy.copy(). - - Patch by Gordon P. Hemsley - -- bpo-36564: Fix infinite loop in email header folding logic that would be - triggered when an email policy's max_line_length is not long enough to - include the required markup and any values in the message. Patch by Paul - Ganssle - -- bpo-36543: Removed methods Element.getchildren(), Element.getiterator() - and ElementTree.getiterator() and the xml.etree.cElementTree module. - -- bpo-36409: Remove the old plistlib API deprecated in Python 3.4 - -- bpo-36302: distutils sorts source file lists so that Extension .so files - build more reproducibly by default - -- bpo-36250: Ignore ``ValueError`` from ``signal`` with ``interaction`` in - non-main thread. - -- bpo-36046: Added ``user``, ``group`` and ``extra_groups`` parameters to - the subprocess.Popen constructor. Patch by Patrick McLean. - -- bpo-32627: Fix compile error when ``_uuid`` headers conflicting included. - -- bpo-35800: Deprecate ``smtpd.MailmanProxy`` ready for future removal. - -- bpo-35168: :attr:`shlex.shlex.punctuation_chars` is now a read-only - property. - -- bpo-8538: Add support for boolean actions like ``--foo`` and ``--no-foo`` - to argparse. Patch contributed by Rémi Lapeyre. - -- bpo-20504: Fixes a bug in :mod:`cgi` module when a multipart/form-data - request has no `Content-Length` header. - -- bpo-25988: The abstract base classes in :mod:`collections.abc` no longer - are exposed in the regular :mod:`collections` module. - -- bpo-11122: Distutils won't check for rpmbuild in specified paths only. - -- bpo-34775: Division handling of PurePath now returns NotImplemented - instead of raising a TypeError when passed something other than an - instance of str or PurePath. Patch by Roger Aiudi. - -- bpo-34749: :func:`binascii.a2b_base64` is now up to 2 times faster. Patch - by Sergey Fedoseev. - -- bpo-34519: Add additional aliases for HP Roman 8. Patch by Michael Osipov. - -- bpo-28009: Fix uuid.getnode() on platforms with '.' as MAC Addr delimiter - as well fix for MAC Addr format that omits a leading 0 in MAC Addr values. - Currently, AIX is the only know platform with these settings. Patch by - Michael Felt. - -- bpo-30618: Add :meth:`~pathlib.Path.readlink`. Patch by Girts Folkmanis. - -- bpo-32498: Made :func:`urllib.parse.unquote()` accept bytes in addition to - strings. Patch by Stein Karlsen. - -- bpo-33348: lib2to3 now recognizes expressions after ``*`` and `**` like in - ``f(*[] or [])``. - -- bpo-32689: Update :func:`shutil.move` function to allow for Path objects - to be used as source argument. Patch by Emily Morehouse and Maxwell - "5.13b" McKinnon. - -- bpo-32820: Added __format__ to IPv4 and IPv6 classes. Always outputs a - fully zero- padded string. Supports b/x/n modifiers (bin/hex/native - format). Native format for IPv4 is bin, native format for IPv6 is hex. - Also supports '#' and '_' modifiers. - -- bpo-27657: Fix urllib.parse.urlparse() with numeric paths. A string like - "path:80" is no longer parsed as a path but as a scheme ("path") and a - path ("80"). - -- bpo-4963: Fixed non-deterministic behavior related to mimetypes extension - mapping and module reinitialization. - -Documentation -------------- - -- bpo-21767: Explicitly mention abc support in functools.singledispatch - -- bpo-38816: Provides more details about the interaction between - :c:func:`fork` and CPython's runtime, focusing just on the C-API. This - includes cautions about where :c:func:`fork` should and shouldn't be - called. - -- bpo-38351: Modernize :mod:`email` examples from %-formatting to f-strings. - -- bpo-38778: Document the fact that :exc:`RuntimeError` is raised if - :meth:`os.fork` is called in a subinterpreter. - -- bpo-38592: Add Brazilian Portuguese to the language switcher at Python - Documentation website. - -- bpo-38294: Add list of no-longer-escaped chars to re.escape documentation - -- bpo-38053: Modernized the plistlib documentation - -- bpo-26868: Fix example usage of :c:func:`PyModule_AddObject` to properly - handle errors. - -- bpo-36797: Fix a dead link in the distutils API Reference. - -- bpo-37977: Warn more strongly and clearly about pickle insecurity - -- bpo-37979: Added a link to dateutil.parser.isoparse in the - datetime.fromisoformat documentation. Patch by Paul Ganssle - -- bpo-12707: Deprecate info(), geturl(), getcode() methods in favor of the - headers, url, and status properties, respectively, for HTTPResponse and - addinfourl. Also deprecate the code attribute of addinfourl in favor of - the status attribute. Patch by Ashwin Ramaswami - -- bpo-37937: Mention ``frame.f_trace`` in :func:`sys.settrace` docs. - -- bpo-37878: Make :c:func:`PyThreadState_DeleteCurrent` Internal. - -- bpo-37759: Beginning edits to Whatsnew 3.8 - -- bpo-37726: Stop recommending getopt in the tutorial for command line - argument parsing and promote argparse. - -- bpo-32910: Remove implementation-specific behaviour of how venv's - Deactivate works. - -- bpo-37256: Fix wording of arguments for :class:`Request` in - :mod:`urllib.request` - -- bpo-37284: Add a brief note to indicate that any new - ``sys.implementation`` required attributes must go through the PEP - process. - -- bpo-30088: Documented that :class:`mailbox.Maildir` constructor doesn't - attempt to verify the maildir folder layout correctness. Patch by - Sviatoslav Sydorenko. - -- bpo-37521: Fix `importlib` examples to insert any newly created modules - via importlib.util.module_from_spec() immediately into sys.modules instead - of after calling loader.exec_module(). - - Thanks to Benjamin Mintz for finding the bug. - -- bpo-37456: Slash ('/') is now part of syntax. - -- bpo-37487: Fix PyList_GetItem index description to include 0. - -- bpo-37149: Replace the dead link to the Tkinter 8.5 reference by John - Shipman, New Mexico Tech, with a link to the archive.org copy. - -- bpo-37478: Added possible exceptions to the description of os.chdir(). - -- bpo-34903: Documented that in :meth:`datetime.datetime.strptime()`, the - leading zero in some two-digit formats is optional. Patch by Mike Gleen. - -- bpo-36260: Add decompression pitfalls to zipfile module documentation. - -- bpo-37004: In the documentation for difflib, a note was added explicitly - warning that the results of SequenceMatcher's ratio method may depend on - the order of the input strings. - -- bpo-36960: Restructured the :mod:`datetime` docs in the interest of making - them more user-friendly and improving readability. Patch by Brad Solomon. - -- bpo-36487: Make C-API docs clear about what the "main" interpreter is. - -- bpo-23460: The documentation for decimal string formatting using the `:g` - specifier has been updated to reflect the correct exponential notation - cutoff point. Original patch contributed by Tuomas Suutari. - -- bpo-35803: Document and test that ``tempfile`` functions may accept a - :term:`path-like object` for the ``dir`` argument. Patch by Anthony - Sottile. - -- bpo-33944: Added a note about the intended use of code in .pth files. - -- bpo-34293: Fix the Doc/Makefile regarding PAPER environment variable and - PDF builds - -- bpo-25237: Add documentation for tkinter modules - -Tests ------ - -- bpo-38614: Fix test_communicate() of test_asyncio.test_subprocess: use - ``support.LONG_TIMEOUT`` (5 minutes), instead of just 1 minute. - -- bpo-38614: Add timeout constants to :mod:`test.support`: - :data:`~test.support.LOOPBACK_TIMEOUT`, - :data:`~test.support.INTERNET_TIMEOUT`, - :data:`~test.support.SHORT_TIMEOUT` and - :data:`~test.support.LONG_TIMEOUT`. - -- bpo-38502: test.regrtest now uses process groups in the multiprocessing - mode (-jN command line option) if process groups are available: if - :func:`os.setsid` and :func:`os.killpg` functions are available. - -- bpo-35998: Fix a race condition in test_asyncio.test_start_tls_server_1(). - Previously, there was a race condition between the test main() function - which replaces the protocol and the test ServerProto protocol which sends - ANSWER once it gets HELLO. Now, only the test main() function is - responsible to send data, ServerProto no longer sends data. - -- bpo-38470: Fix ``test_compileall.test_compile_dir_maxlevels()`` on Windows - without long path support: only create 3 subdirectories instead of between - 20 and 100 subdirectories. - -- bpo-37531: On timeout, regrtest no longer attempts to call - ``popen.communicate()`` again: it can hang until all child processes using - stdout and stderr pipes completes. Kill the worker process and ignores its - output. Change also the faulthandler timeout of the main process from 1 - minute to 5 minutes, for Python slowest buildbots. - -- bpo-38239: Fix test_gdb for Link Time Optimization (LTO) builds. - -- bpo-38275: test_ssl now handles disabled TLS/SSL versions better. - OpenSSL's crypto policy and run-time settings are recognized and tests for - disabled versions are skipped. Tests also accept more TLS minimum_versions - for platforms that override OpenSSL's default with strict settings. - -- bpo-38271: The private keys for test_ssl were encrypted with 3DES in - traditional PKCS#5 format. 3DES and the digest algorithm of PKCS#5 are - blocked by some strict crypto policies. Use PKCS#8 format with AES256 - encryption instead. - -- bpo-38270: test.support now has a helper function to check for - availability of a hash digest function. Several tests are refactored avoid - MD5 and use SHA256 instead. Other tests are marked to use MD5 and skipped - when MD5 is disabled. - -- bpo-37123: Multiprocessing test test_mymanager() now also expects - -SIGTERM, not only exitcode 0. BaseManager._finalize_manager() sends - SIGTERM to the manager process if it takes longer than 1 second to stop, - which happens on slow buildbots. - -- bpo-38212: Multiprocessing tests: increase - test_queue_feeder_donot_stop_onexc() timeout from 1 to 60 seconds. - -- bpo-38117: Test with OpenSSL 1.1.1d - -- bpo-38018: Increase code coverage for multiprocessing.shared_memory. - -- bpo-37805: Add tests for json.dump(..., skipkeys=True). Patch by Dong-hee - Na. - -- bpo-37531: Enhance regrtest multiprocess timeout: write a message when - killing a worker process, catch popen.kill() and popen.wait() exceptions, - put a timeout on the second call to popen.communicate(). - -- bpo-37876: Add tests for ROT-13 codec. - -- bpo-36833: Added tests for PyDateTime_xxx_GET_xxx() macros of the C API of - the :mod:`datetime` module. Patch by Joannah Nanjekye. - -- bpo-37558: Fix test_shared_memory_cleaned_after_process_termination name - handling - -- bpo-37526: Add :func:`test.support.catch_threading_exception`: context - manager catching :class:`threading.Thread` exception using - :func:`threading.excepthook`. - -- bpo-37421: test_concurrent_futures now explicitly stops the ForkServer - instance if it's running. - -- bpo-37421: multiprocessing tests now stop the ForkServer instance if it's - running: close the "alive" file descriptor to ask the server to stop and - then remove its UNIX address. - -- bpo-37421: test_distutils.test_build_ext() is now able to remove the - temporary directory on Windows: don't import the newly built C extension - ("xx") in the current process, but test it in a separated process. - -- bpo-37421: test_concurrent_futures now cleans up multiprocessing to remove - immediately temporary directories created by - multiprocessing.util.get_temp_dir(). - -- bpo-37421: test_winconsoleio doesn't leak a temporary file anymore: use - tempfile.TemporaryFile() to remove it when the test completes. - -- bpo-37421: multiprocessing tests now explicitly call ``_run_finalizers()`` - to immediately remove temporary directories created by tests. - -- bpo-37421: urllib.request tests now call - :func:`~urllib.request.urlcleanup` to remove temporary files created by - ``urlretrieve()`` tests and to clear the ``_opener`` global variable set - by ``urlopen()`` and functions calling indirectly ``urlopen()``. - -- bpo-37472: Remove ``Lib/test/outstanding_bugs.py``. - -- bpo-37199: Fix test failures when IPv6 is unavailable or disabled. - -- bpo-19696: Replace deprecated method "random.choose" with "random.choice" - in "test_pkg_import.py". - -- bpo-37335: Remove no longer necessary code from c locale coercion tests - -- bpo-37421: Fix test_shutil to no longer leak temporary files. - -- bpo-37411: Fix test_wsgiref.testEnviron() to no longer depend on the - environment variables (don't fail if "X" variable is set). - -- bpo-37400: Fix test_os.test_chown(): use os.getgroups() rather than - grp.getgrall() to get groups. Rename also the test to test_chown_gid(). - -- bpo-37359: Add --cleanup option to python3 -m test to remove - ``test_python_*`` directories of previous failed jobs. Add "make - cleantest" to run ``python3 -m test --cleanup``. - -- bpo-37362: test_gdb no longer fails if it gets an "unexpected" message on - stderr: it now ignores stderr. The purpose of test_gdb is to test that - python-gdb.py commands work as expected, not to test gdb. - -- bpo-35998: Avoid TimeoutError in test_asyncio: test_start_tls_server_1() - -- bpo-37278: Fix test_asyncio ProactorLoopCtrlC: join the thread to prevent - leaking a running thread and leaking a reference. - -- bpo-37261: Fix :func:`test.support.catch_unraisable_exception`: its - __exit__() method now ignores unraisable exception raised when clearing - its ``unraisable`` attribute. - -- bpo-37069: regrtest now uses :func:`sys.unraisablehook` to mark a test as - "environment altered" (ENV_CHANGED) if it emits an "unraisable exception". - Moreover, regrtest logs a warning in this case. - - Use ``python3 -m test --fail-env-changed`` to catch unraisable exceptions - in tests. - -- bpo-37252: Fix assertions in ``test_close`` and - ``test_events_mask_overflow`` devpoll tests. - -- bpo-37169: Rewrite ``_PyObject_IsFreed()`` unit tests. - -- bpo-37153: ``test_venv.test_multiprocessing()`` now explicitly calls - ``pool.terminate()`` to wait until the pool completes. - -- bpo-34001: Make test_ssl pass with LibreSSL. LibreSSL handles minimum and - maximum TLS version differently than OpenSSL. - -- bpo-36919: Make ``test_source_encoding.test_issue2301`` implementation - independent. The test will work now for both CPython and IronPython. - -- bpo-30202: Update ``test.test_importlib.test_abc`` to test - ``find_spec()``. - -- bpo-28009: Modify the test_uuid logic to test when a program is available - AND can be used to obtain a MACADDR as basis for an UUID. Patch by M. Felt - -- bpo-34596: Fallback to a default reason when :func:`unittest.skip` is - uncalled. Patch by Naitree Zhu. - -Build ------ - -- bpo-38809: On Windows, build scripts will now recognize and use python.exe - from an active virtual env. - -- bpo-38684: Fix _hashlib build when Blake2 is disabled, but OpenSSL - supports it. - -- bpo-38468: Misc/python-config.in now uses `getvar()` for all still - existing `sysconfig.get_config_var()` calls. Patch by Joannah Nanjekye. - -- bpo-37415: Fix stdatomic.h header check for ICC compiler: the ICC - implementation lacks atomic_uintptr_t type which is needed by Python. - -- bpo-38301: In Solaris family, we must be sure to use ``-D_REENTRANT``. - Patch by Jesús Cea Avión. - -- bpo-36002: Locate ``llvm-profdata`` and ``llvm-ar`` binaries using - ``AC_PATH_TOOL`` rather than ``AC_PATH_TARGET_TOOL``. - -- bpo-37936: The :file:`.gitignore` file systematically keeps "rooted", with - a non-trailing slash, all the rules that are meant to apply to files in a - specific place in the repo. Previously, when the intended file to ignore - happened to be at the root of the repo, we'd most often accidentally also - ignore files and directories with the same name anywhere in the tree. - -- bpo-37760: The :file:`Tools/unicode/makeunicodedata.py` script, which is - used for converting information from the Unicode Character Database into - generated code and data used by the methods of :class:`str` and by the - :mod:`unicodedata` module, now handles each character's data as a - ``dataclass`` with named attributes, rather than a length-18 list of - different fields. - -- bpo-37936: The :file:`.gitignore` file no longer applies to any files that - are in fact tracked in the Git repository. Patch by Greg Price. - -- bpo-37725: Change "clean" makefile target to also clean the program guided - optimization (PGO) data. Previously you would have to use "make clean" - and "make profile-removal", or "make clobber". - -- bpo-37707: Mark some individual tests to skip when --pgo is used. The - tests marked increase the PGO task time significantly and likely don't - help improve optimization of the final executable. - -- bpo-36044: Reduce the number of unit tests run for the PGO generation - task. This speeds up the task by a factor of about 15x. Running the full - unit test suite is slow. This change may result in a slightly less - optimized build since not as many code branches will be executed. If you - are willing to wait for the much slower build, the old behavior can be - restored using './configure [..] PROFILE_TASK="-m test --pgo-extended"'. - We make no guarantees as to which PGO task set produces a faster build. - Users who care should run their own relevant benchmarks as results can - depend on the environment, workload, and compiler tool chain. - -- bpo-37468: ``make install`` no longer installs ``wininst-*.exe`` files - used by distutils bdist_wininst: bdist_wininst only works on Windows. - -- bpo-37189: Many ``PyRun_XXX()`` functions like :c:func:`PyRun_String` were - no longer exported in ``libpython38.dll`` by mistake. Export them again to - fix the ABI compatibility. - -- bpo-25361: Enables use of SSE2 instructions in Windows 32-bit build. - -- bpo-36210: Update optional extension module detection for AIX. ossaudiodev - and spwd are not applicable for AIX, and are no longer reported as - missing. 3rd-party packaging of ncurses (with ASIS support) conflicts with - officially supported AIX curses library, so configure AIX to use - libcurses.a. However, skip trying to build _curses_panel. - - patch by M Felt - -Windows -------- - -- bpo-38589: Fixes HTML Help shortcut when Windows is not installed to C - drive - -- bpo-38453: Ensure ntpath.realpath() correctly resolves relative paths. - -- bpo-38519: Restores the internal C headers that were missing from the - nuget.org and Microsoft Store packages. - -- bpo-38492: Remove ``pythonw.exe`` dependency on the Microsoft C++ runtime. - -- bpo-38344: Fix error message in activate.bat - -- bpo-38359: Ensures ``pyw.exe`` launcher reads correct registry key. - -- bpo-38355: Fixes ``ntpath.realpath`` failing on ``sys.executable``. - -- bpo-38117: Update bundled OpenSSL to 1.1.1d - -- bpo-38092: Reduce overhead when using multiprocessing in a Windows virtual - environment. - -- bpo-38133: Allow py.exe launcher to locate installations from the - Microsoft Store and improve display of active virtual environments. - -- bpo-38114: The ``pip.ini`` is no longer included in the Nuget package. - -- bpo-32592: Set Windows 8 as the minimum required version for API support - -- bpo-36634: :func:`os.cpu_count` now returns active processors rather than - maximum processors. - -- bpo-36634: venv activate.bat now works when the existing variables contain - double quote characters. - -- bpo-38081: Prevent error calling :func:`os.path.realpath` on ``'NUL'``. - -- bpo-38087: Fix case sensitivity in test_pathlib and test_ntpath. - -- bpo-38088: Fixes distutils not finding vcruntime140.dll with only the v142 - toolset installed. - -- bpo-37283: Ensure command-line and unattend.xml setting override - previously detected states in Windows installer. - -- bpo-38030: Fixes :func:`os.stat` failing for block devices on Windows - -- bpo-38020: Fixes potential crash when calling :func:`os.readlink` (or - indirectly through :func:`~os.path.realpath`) on a file that is not a - supported link. - -- bpo-37705: Improve the implementation of ``winerror_to_errno()``. - -- bpo-37549: :func:`os.dup` no longer fails for standard streams on Windows - 7. - -- bpo-1311: The ``nul`` file on Windows now returns True from - :func:`~os.path.exists` and a valid result from :func:`os.stat` with - ``S_IFCHR`` set. - -- bpo-9949: Enable support for following symlinks in :func:`os.realpath`. - -- bpo-37834: Treat all name surrogate reparse points on Windows in - :func:`os.lstat` and other reparse points as regular files in - :func:`os.stat`. - -- bpo-36266: Add the module name in the formatted error message when DLL - load fail happens during module import in - ``_PyImport_FindSharedFuncptrWindows()``. Patch by Srinivas Nyayapati. - -- bpo-25172: Trying to import the :mod:`crypt` module on Windows will result - in an :exc:`ImportError` with a message explaining that the module isn't - supported on Windows. On other platforms, if the underlying ``_crypt`` - module is not available, the ImportError will include a message explaining - the problem. - -- bpo-37778: Fixes the icons used for file associations to the Microsoft - Store package. - -- bpo-37734: Fix use of registry values to launch Python from Microsoft - Store app. - -- bpo-37702: Fix memory leak on Windows in creating an SSLContext object or - running urllib.request.urlopen('https://...'). - -- bpo-37672: Switch Windows Store package's pip to use bundled - :file:`pip.ini` instead of :envvar:`PIP_USER` variable. - -- bpo-10945: Officially drop support for creating bdist_wininst installers - on non-Windows systems. - -- bpo-37445: Include the ``FORMAT_MESSAGE_IGNORE_INSERTS`` flag in - ``FormatMessageW()`` calls. - -- bpo-37369: Fixes path for :data:`sys.executable` when running from the - Microsoft Store. - -- bpo-37380: Don't collect unfinished processes with ``subprocess._active`` - on Windows to cleanup later. Patch by Ruslan Kuprieiev. - -- bpo-37351: Removes libpython38.a from standard Windows distribution. - -- bpo-35360: Update Windows builds to use SQLite 3.28.0. - -- bpo-37267: On Windows, :func:`os.dup` no longer creates an inheritable fd - when handling a character file. - -- bpo-36779: Ensure ``time.tzname`` is correct on Windows when the active - code page is set to CP_UTF7 or CP_UTF8. - -- bpo-32587: Make :data:`winreg.REG_MULTI_SZ` support zero-length strings. - -- bpo-28269: Replace use of :c:func:`strcasecmp` for the system function - :c:func:`_stricmp`. Patch by Minmin Gong. - -- bpo-36590: Add native Bluetooth RFCOMM support to socket module. - -macOS ------ - -- bpo-38117: Updated OpenSSL to 1.1.1d in macOS installer. - -- bpo-38089: Move Azure Pipelines to latest VM versions and make macOS tests - optional - -- bpo-18049: Increase the default stack size of threads from 5MB to 16MB on - macOS, to match the stack size of the main thread. This avoids crashes on - deep recursion in threads. - -- bpo-34602: Avoid test suite failures on macOS by no longer calling - resource.setrlimit to increase the process stack size limit at runtime. - The runtime change is no longer needed since the interpreter is being - built with a larger default stack size. - -- bpo-35360: Update macOS installer to use SQLite 3.28.0. - -- bpo-34631: Updated OpenSSL to 1.1.1c in macOS installer. - -IDLE ----- - -- bpo-26353: Stop adding newline when saving an IDLE shell window. - -- bpo-4630: Add an option to toggle IDLE's cursor blink for shell, editor, - and output windows. See Settings, General, Window Preferences, Cursor - Blink. Patch by Zackery Spytz. - -- bpo-38598: Do not try to compile IDLE shell or output windows - -- bpo-36698: IDLE no longer fails when write non-encodable characters to - stderr. It now escapes them with a backslash, as the regular Python - interpreter. Added the ``errors`` field to the standard streams. - -- bpo-35379: When exiting IDLE, catch any AttributeError. One happens when - EditorWindow.close is called twice. Printing a traceback, when IDLE is - run from a terminal, is useless and annoying. - -- bpo-38183: To avoid problems, test_idle ignores the user config directory. - It no longer tries to create or access .idlerc or any files within. Users - must run IDLE to discover problems with saving settings. - -- bpo-38077: IDLE no longer adds 'argv' to the user namespace when - initializing it. This bug only affected 3.7.4 and 3.8.0b2 to 3.8.0b4. - -- bpo-38041: Shell restart lines now fill the window width, always start - with '=', and avoid wrapping unnecessarily. The line will still wrap if - the included file name is long relative to the width. - -- bpo-35771: To avoid occasional spurious test_idle failures on slower - machines, increase the ``hover_delay`` in test_tooltip. - -- bpo-37824: Properly handle user input warnings in IDLE shell. Cease - turning SyntaxWarnings into SyntaxErrors. - -- bpo-37929: IDLE Settings dialog now closes properly when there is no shell - window. - -- bpo-37902: Add mousewheel scrolling for IDLE module, path, and stack - browsers. Patch by George Zhang. - -- bpo-37849: Fixed completions list appearing too high or low when shown - above the current line. - -- bpo-36419: Refactor IDLE autocomplete and improve testing. - -- bpo-37748: Reorder the Run menu. Put the most common choice, Run Module, - at the top. - -- bpo-37692: Improve highlight config sample with example shell interaction - and better labels for shell elements. - -- bpo-37628: Settings dialog no longer expands with font size. - -- bpo-37627: Initialize the Customize Run dialog with the command line - arguments most recently entered before. The user can optionally edit - before submitting them. - -- bpo-33610: Fix code context not showing the correct context when first - toggled on. - -- bpo-37530: Optimize code context to reduce unneeded background activity. - Font and highlight changes now occur along with text changes instead of - after a random delay. - -- bpo-27452: Cleanup ``config.py`` by inlining ``RemoveFile`` and - simplifying the handling of ``file`` in ``CreateConfigHandlers``. - -- bpo-37325: Fix tab focus traversal order for help source and custom run - dialogs. - -- bpo-37321: Both subprocess connection error messages now refer to the - 'Startup failure' section of the IDLE doc. - -- bpo-17535: Add optional line numbers for IDLE editor windows. Windows - open without line numbers unless set otherwise in the General tab of the - configuration dialog. - -- bpo-26806: To compensate for stack frames added by IDLE and avoid possible - problems with low recursion limits, add 30 to limits in the user code - execution process. Subtract 30 when reporting recursion limits to make - this addition mostly transparent. - -- bpo-37177: Properly 'attach' search dialogs to their main window so that - they behave like other dialogs and do not get hidden behind their main - window. - -- bpo-37039: Adjust "Zoom Height" to individual screens by momentarily - maximizing the window on first use with a particular screen. Changing - screen settings may invalidate the saved height. While a window is - maximized, "Zoom Height" has no effect. - -- bpo-35763: Make calltip reminder about '/' meaning positional-only less - obtrusive by only adding it when there is room on the first line. - -- bpo-5680: Add 'Run... Customized' to the Run menu to run a module with - customized settings. Any 'command line arguments' entered are added to - sys.argv. One can suppress the normal Shell main module restart. - -- bpo-36390: Gather Format menu functions into format.py. Combine - paragraph.py, rstrip.py, and format methods from editor.py. - -Tools/Demos ------------ - -- bpo-38118: Update Valgrind suppression file to ignore a false alarm in - :c:func:`PyUnicode_Decode` when using GCC builtin strcmp(). - -- bpo-38347: pathfix.py: Assume all files that end on '.py' are Python - scripts when working recursively. - -- bpo-37803: pdb's ``--help`` and ``--version`` long options now work. - -- bpo-37942: Improve ArgumentClinic converter for floats. - -- bpo-37704: Remove ``Tools/scripts/h2py.py``: use cffi to access a C API in - Python. - -- bpo-37675: 2to3 now works when run from a zipped standard library. - -- bpo-37034: Argument Clinic now uses the argument name on errors with - keyword-only argument instead of their position. Patch contributed by Rémi - Lapeyre. - -- bpo-37064: Add option -k to pathscript.py script: preserve shebang flags. - Add option -a to pathscript.py script: add flags. - -C API ------ - -- bpo-37633: Re-export some function compatibility wrappers for macros in - ``pythonrun.h``. - -- bpo-38644: Provide :c:func:`Py_EnterRecursiveCall` and - :c:func:`Py_LeaveRecursiveCall` as regular functions for the limited API. - Previously, there were defined as macros, but these macros didn't work - with the limited API which cannot access ``PyThreadState.recursion_depth`` - field. Remove ``_Py_CheckRecursionLimit`` from the stable ABI. - -- bpo-38650: The global variable :c:data:`PyStructSequence_UnnamedField` is - now a constant and refers to a constant string. - -- bpo-38540: Fixed possible leak in :c:func:`PyArg_Parse` and similar - functions for format units ``"es#"`` and ``"et#"`` when the macro - :c:macro:`PY_SSIZE_T_CLEAN` is not defined. - -- bpo-38395: Fix a crash in :class:`weakref.proxy` objects due to incorrect - lifetime management when calling some associated methods that may delete - the last reference to object being referenced by the proxy. Patch by Pablo - Galindo. - -- bpo-36389: The ``_PyObject_CheckConsistency()`` function is now also - available in release mode. For example, it can be used to debug a crash in - the ``visit_decref()`` function of the GC. - -- bpo-38266: Revert the removal of PyThreadState_DeleteCurrent() with - documentation. - -- bpo-38303: Update audioop extension module to use the stable ABI - (PEP-384). Patch by Tyler Kieft. - -- bpo-38234: :c:func:`Py_SetPath` now sets :data:`sys.executable` to the - program full path (:c:func:`Py_GetProgramFullPath`) rather than to the - program name (:c:func:`Py_GetProgramName`). - -- bpo-38234: Python ignored arguments passed to :c:func:`Py_SetPath`, - :c:func:`Py_SetPythonHome` and :c:func:`Py_SetProgramName`: fix Python - initialization to use specified arguments. - -- bpo-38205: The :c:func:`Py_UNREACHABLE` macro now calls - :c:func:`Py_FatalError`. - -- bpo-38140: Make dict and weakref offsets opaque for C heap types by - passing the offsets through PyMemberDef - -- bpo-15088: The C function ``PyGen_NeedsFinalizing`` has been removed. It - was not documented, tested or used anywhere within CPython after the - implementation of :pep:`442`. Patch by Joannah Nanjekye. (Patch by Joannah - Nanjekye) - -- bpo-36763: Options added by ``PySys_AddXOption()`` are now handled the - same way than ``PyConfig.xoptions`` and command line ``-X`` options. - -- bpo-37926: Fix a crash in ``PySys_SetArgvEx(0, NULL, 0)``. - -- bpo-37879: Fix subtype_dealloc to suppress the type decref when the base - type is a C heap type - -- bpo-37645: Add :c:func:`_PyObject_FunctionStr` to get a user-friendly - string representation of a function-like object. Patch by Jeroen Demeyer. - -- bpo-29548: The functions ``PyEval_CallObject``, ``PyEval_CallFunction``, - ``PyEval_CallMethod`` and ``PyEval_CallObjectWithKeywords`` are - deprecated. Use :c:func:`PyObject_Call` and its variants instead. - -- bpo-37151: ``PyCFunction_Call`` is now a deprecated alias of - :c:func:`PyObject_Call`. - -- bpo-37540: The vectorcall protocol now requires that the caller passes - only strings as keyword names. - -- bpo-37207: The vectorcall protocol is now enabled for ``type`` objects: - set ``tp_vectorcall`` to a vectorcall function to be used instead of - ``tp_new`` and ``tp_init`` when calling the class itself. - -- bpo-21120: Exclude Python-ast.h, ast.h and asdl.h from the limited API. - -- bpo-37483: Add new function ``_PyObject_CallOneArg`` for calling an object - with one positional argument. - -- bpo-36763: Add :func:`PyConfig_SetWideStringList` function. - -- bpo-37337: Add fast functions for calling methods: - :c:func:`_PyObject_VectorcallMethod`, :c:func:`_PyObject_CallMethodNoArgs` - and :c:func:`_PyObject_CallMethodOneArg`. - -- bpo-28805: The :const:`METH_FASTCALL` calling convention has been - documented. - -- bpo-37221: The new function :c:func:`PyCode_NewWithPosOnlyArgs` allows to - create code objects like :c:func:`PyCode_New`, but with an extra - *posonlyargcount* parameter for indicating the number of positonal-only - arguments. - -- bpo-37215: Fix dtrace issue introduce by bpo-36842 - -- bpo-37194: Add a new public :c:func:`PyObject_CallNoArgs` function to the - C API: call a callable Python object without any arguments. It is the most - efficient way to call a callback without any argument. On x86-64, for - example, ``PyObject_CallFunctionObjArgs(func, NULL)`` allocates 960 bytes - on the stack per call, whereas ``PyObject_CallNoArgs(func)`` only - allocates 624 bytes per call. - -- bpo-37170: Fix the cast on error in - :c:func:`PyLong_AsUnsignedLongLongMask()`. - -- bpo-35381: Convert posixmodule.c statically allocated types - ``DirEntryType`` and ``ScandirIteratorType`` to heap-allocated types. - -- bpo-34331: Use singular/plural noun in error message when instantiating an - abstract class with non-overriden abstract method(s). - - -What's New in Python 3.8.0 beta 1? -================================== - -*Release date: 2019-06-04* - -Security --------- - -- bpo-35907: CVE-2019-9948: Avoid file reading by disallowing - ``local-file://`` and ``local_file://`` URL schemes in - ``URLopener().open()`` and ``URLopener().retrieve()`` of - :mod:`urllib.request`. - -- bpo-33529: Prevent fold function used in email header encoding from - entering infinite loop when there are too many non-ASCII characters in a - header. - -- bpo-33164: Updated blake2 implementation which uses secure memset - implementation provided by platform. - -Core and Builtins ------------------ - -- bpo-35814: Allow unpacking in the right hand side of annotated - assignments. In particular, ``t: Tuple[int, ...] = x, y, *z`` is now - allowed. - -- bpo-37126: All structseq objects are now tracked by the garbage collector. - Patch by Pablo Galindo. - -- bpo-37122: Make the *co_argcount* attribute of code objects represent the - total number of positional arguments (including positional-only - arguments). The value of *co_posonlyargcount* can be used to distinguish - which arguments are positional only, and the difference (*co_argcount* - - *co_posonlyargcount*) is the number of positional-or-keyword arguments. - Patch by Pablo Galindo. - -- bpo-20092: Constructors of :class:`int`, :class:`float` and - :class:`complex` will now use the :meth:`~object.__index__` special - method, if available and the corresponding method :meth:`~object.__int__`, - :meth:`~object.__float__` or :meth:`~object.__complex__` is not available. - -- bpo-37087: Add native thread ID (TID) support to OpenBSD. - -- bpo-26219: Implemented per opcode cache mechanism and ``LOAD_GLOBAL`` - instruction use it. ``LOAD_GLOBAL`` is now about 40% faster. Contributed - by Yury Selivanov, and Inada Naoki. - -- bpo-37072: Fix crash in PyAST_FromNodeObject() when flags is NULL. - -- bpo-37029: Freeing a great many small objects could take time quadratic in - the number of arenas, due to using linear search to keep ``obmalloc.c``'s - list of usable arenas sorted by order of number of free memory pools. - This is accomplished without search now, leaving the worst-case time - linear in the number of arenas. For programs where this quite visibly - matters (typically with more than 100 thousand small objects alive - simultaneously), this can greatly reduce the time needed to release their - memory. - -- bpo-26423: Fix possible overflow in ``wrap_lenfunc()`` when ``sizeof(long) - < sizeof(Py_ssize_t)`` (e.g., 64-bit Windows). - -- bpo-37050: Improve the AST for "debug" f-strings, which use '=' to print - out the source of the expression being evaluated. Delete expr_text from - the FormattedValue node, and instead use a Constant string node (possibly - merged with adjacent constant expressions inside the f-string). - -- bpo-22385: The `bytes.hex`, `bytearray.hex`, and `memoryview.hex` methods - as well as the `binascii.hexlify` and `b2a_hex` functions now have the - ability to include an optional separator between hex bytes. This - functionality was inspired by MicroPython's hexlify implementation. - -- bpo-26836: Add :func:`os.memfd_create`. - -- bpo-37032: Added new ``replace()`` method to the code type - (:class:`types.CodeType`). - -- bpo-37007: Implement :func:`socket.if_nameindex()`, - :func:`socket.if_nametoindex()`, and :func:`socket.if_indextoname()` on - Windows. - -- bpo-36829: :c:func:`PyErr_WriteUnraisable` now creates a traceback object - if there is no current traceback. Moreover, call - :c:func:`PyErr_NormalizeException` and :c:func:`PyException_SetTraceback` - to normalize the exception value. Ignore any error. - -- bpo-36878: Only accept text after `# type: ignore` if the first character - is ASCII. This is to disallow things like `# type: ignoreé`. - -- bpo-36878: Store text appearing after a `# type: ignore` comment in the - AST. For example a type ignore like `# type: ignore[E1000]` will have the - string `"[E1000]"` stored in its AST node. - -- bpo-2180: Treat line continuation at EOF as a ``SyntaxError`` by Anthony - Sottile. - -- bpo-36907: Fix a crash when calling a C function with a keyword dict - (``f(**kwargs)``) and changing the dict ``kwargs`` while that function is - running. - -- bpo-36946: Fix possible signed integer overflow when handling slices. - -- bpo-36826: Add NamedExpression kind support to ast_unparse.c - -- bpo-1875: A :exc:`SyntaxError` is now raised if a code blocks that will be - optimized away (e.g. if conditions that are always false) contains syntax - errors. Patch by Pablo Galindo. - -- bpo-36027: Allow computation of modular inverses via three-argument - ``pow``: the second argument is now permitted to be negative in the case - where the first and third arguments are relatively prime. - -- bpo-36861: Update the Unicode database to version 12.1.0. - -- bpo-28866: Avoid caching attributes of classes which type defines mro() to - avoid a hard cache invalidation problem. - -- bpo-36851: The ``FrameType`` stack is now correctly cleaned up if the - execution ends with a return and the stack is not empty. - -- bpo-34616: The ``compile()`` builtin functions now support the - ``ast.PyCF_ALLOW_TOP_LEVEL_AWAIT`` flag, which allow to compile sources - that contains top-level ``await``, ``async with`` or ``async for``. This - is useful to evaluate async-code from with an already async functions; for - example in a custom REPL. - -- bpo-36842: Implement PEP 578, adding sys.audit, io.open_code and related - APIs. - -- bpo-27639: Correct return type for UserList slicing operations. Patch by - Michael Blahay, Erick Cervantes, and vaultah - -- bpo-36737: Move PyRuntimeState.warnings into per-interpreter state (via - "module state"). - -- bpo-36793: Removed ``__str__`` implementations from builtin types - :class:`bool`, :class:`int`, :class:`float`, :class:`complex` and few - classes from the standard library. They now inherit ``__str__()`` from - :class:`object`. - -- bpo-36817: Add a ``=`` feature f-strings for debugging. This can precede - ``!s``, ``!r``, or ``!a``. It produces the text of the expression, - followed by an equal sign, followed by the repr of the value of the - expression. So ``f'{3*9+15=}'`` would be equal to the string - ``'3*9+15=42'``. If ``=`` is specified, the default conversion is set to - ``!r``, unless a format spec is given, in which case the formatting - behavior is unchanged, and __format__ will be used. - -- bpo-24048: Save the live exception during import.c's ``remove_module()``. - -- bpo-27987: pymalloc returns memory blocks aligned by 16 bytes, instead of - 8 bytes, on 64-bit platforms to conform x86-64 ABI. Recent compilers - assume this alignment more often. Patch by Inada Naoki. - -- bpo-36601: A long-since-meaningless check for ``getpid() == main_pid`` was - removed from Python's internal C signal handler. - -- bpo-36594: Fix incorrect use of ``%p`` in format strings. Patch by Zackery - Spytz. - -- bpo-36045: builtins.help() now prefixes `async` for async functions - -- bpo-36084: Add native thread ID (TID) to threading.Thread objects - (supported platforms: Windows, FreeBSD, Linux, macOS) - -- bpo-36035: Added fix for broken symlinks in combination with pathlib - -- bpo-35983: Added new trashcan macros to deal with a double deallocation - that could occur when the `tp_dealloc` of a subclass calls the - `tp_dealloc` of a base class and that base class uses the trashcan - mechanism. Patch by Jeroen Demeyer. - -- bpo-20602: Do not clear :data:`sys.flags` and :data:`sys.float_info` - during shutdown. Patch by Zackery Spytz. - -- bpo-26826: Expose :func:`copy_file_range` as a low level API in the - :mod:`os` module. - -- bpo-32388: Remove cross-version binary compatibility requirement in - tp_flags. - -- bpo-31862: Port binascii to PEP 489 multiphase initialization. Patch by - Marcel Plch. - -Library -------- - -- bpo-37128: Added :func:`math.perm`. - -- bpo-37120: Add SSLContext.num_tickets to control the number of TLSv1.3 - session tickets. - -- bpo-12202: Fix the error handling in - :meth:`msilib.SummaryInformation.GetProperty`. Patch by Zackery Spytz. - -- bpo-26835: The fcntl module now contains file sealing constants for - sealing of memfds. - -- bpo-29262: Add ``get_origin()`` and ``get_args()`` introspection helpers - to ``typing`` module. - -- bpo-12639: :meth:`msilib.Directory.start_component()` no longer fails if - *keyfile* is not ``None``. - -- bpo-36999: Add the ``asyncio.Task.get_coro()`` method to publicly expose - the tasks's coroutine object. - -- bpo-35246: Make :func:`asyncio.create_subprocess_exec` accept path-like - arguments. - -- bpo-35279: Change default *max_workers* of ``ThreadPoolExecutor`` from - ``cpu_count() * 5`` to ``min(32, cpu_count() + 4)``. Previous value was - unreasonably large on many cores machines. - -- bpo-37076: :func:`_thread.start_new_thread` now logs uncaught exception - raised by the function using :func:`sys.unraisablehook`, rather than - :func:`sys.excepthook`, so the hook gets access to the function which - raised the exception. - -- bpo-33725: On macOS, the :mod:`multiprocessing` module now uses *spawn* - start method by default. - -- bpo-37054: Fix destructor :class:`_pyio.BytesIO` and - :class:`_pyio.TextIOWrapper`: initialize their ``_buffer`` attribute as - soon as possible (in the class body), because it's used by ``__del__()`` - which calls ``close()``. - -- bpo-37058: PEP 544: Add ``Protocol`` and ``@runtime_checkable`` to the - ``typing`` module. - -- bpo-36933: The functions ``sys.set_coroutine_wrapper`` and - ``sys.get_coroutine_wrapper`` that were deprecated and marked for removal - in 3.8 have been removed. - -- bpo-37047: Handle late binding and attribute access in - :class:`unittest.mock.AsyncMock` setup for autospeccing. Document newly - implemented async methods in :class:`unittest.mock.MagicMock`. - -- bpo-37049: PEP 589: Add ``TypedDict`` to the ``typing`` module. - -- bpo-37046: PEP 586: Add ``Literal`` to the ``typing`` module. - -- bpo-37045: PEP 591: Add ``Final`` qualifier and ``@final`` decorator to - the ``typing`` module. - -- bpo-37035: Don't log OSError based exceptions if a fatal error has - occurred in asyncio transport. Peer can generate almost any OSError, user - cannot avoid these exceptions by fixing own code. Errors are still - propagated to user code, it's just logging them is pointless and pollute - asyncio logs. - -- bpo-37001: :func:`symtable.symtable` now accepts the same input types for - source code as the built-in :func:`compile` function. Patch by Dino - Viehland. - -- bpo-37028: Implement asyncio REPL - -- bpo-37027: Return safe to use proxy socket object from - transport.get_extra_info('socket') - -- bpo-32528: Make asyncio.CancelledError a BaseException. - - This will address the common mistake many asyncio users make: an "except - Exception" clause breaking Tasks cancellation. - - In addition to this change, we stop inheriting asyncio.TimeoutError and - asyncio.InvalidStateError from their concurrent.futures.* counterparts. - There's no point for these exceptions to share the inheritance chain. - -- bpo-1230540: Add a new :func:`threading.excepthook` function which handles - uncaught :meth:`threading.Thread.run` exception. It can be overridden to - control how uncaught :meth:`threading.Thread.run` exceptions are handled. - -- bpo-36996: Handle :func:`unittest.mock.patch` used as a decorator on async - functions. - -- bpo-37008: Add support for calling :func:`next` with the mock resulting - from :func:`unittest.mock.mock_open` - -- bpo-27737: Allow whitespace only header encoding in ``email.header`` - by - Batuhan Taskaya - -- bpo-36969: PDB command `args` now display positional only arguments. - Patch contributed by Rémi Lapeyre. - -- bpo-36969: PDB command `args` now display keyword only arguments. Patch - contributed by Rémi Lapeyre. - -- bpo-36983: Add missing names to ``typing.__all__``: ``ChainMap``, - ``ForwardRef``, ``OrderedDict`` - by Anthony Sottile. - -- bpo-36972: Add SupportsIndex protocol to the typing module to allow type - checking to detect classes that can be passed to `hex()`, `oct()` and - `bin()`. - -- bpo-32972: Implement ``unittest.IsolatedAsyncioTestCase`` to help testing - asyncio-based code. - -- bpo-36952: :func:`fileinput.input` and :class:`fileinput.FileInput` - **bufsize** argument has been removed (was deprecated and ignored since - Python 3.6), and as a result the **mode** and **openhook** arguments have - been made keyword-only. - -- bpo-36952: Starting with Python 3.3, importing ABCs from - :mod:`collections` is deprecated, and import should be done from - :mod:`collections.abc`. Still being able to import from :mod:`collections` - was marked for removal in 3.8, but has been delayed to 3.9; documentation - and ``DeprecationWarning`` clarified. - -- bpo-36949: Implement __repr__ for WeakSet objects. - -- bpo-36948: Fix :exc:`NameError` in - :meth:`urllib.request.URLopener.retrieve`. Patch by Karthikeyan - Singaravelan. - -- bpo-33524: Fix the folding of email header when the max_line_length is 0 - or None and the header contains non-ascii characters. Contributed by - Licht Takeuchi (@Licht-T). - -- bpo-24564: :func:`shutil.copystat` now ignores :const:`errno.EINVAL` on - :func:`os.setxattr` which may occur when copying files on filesystems - without extended attributes support. - - Original patch by Giampaolo Rodola, updated by Ying Wang. - -- bpo-36888: Python child processes can now access the status of their - parent process using multiprocessing.process.parent_process - -- bpo-36921: Deprecate ``@coroutine`` for sake of ``async def``. - -- bpo-25652: Fix bug in ``__rmod__`` of ``UserString`` - by Batuhan Taskaya. - -- bpo-36916: Remove a message about an unhandled exception in a task when - writer.write() is used without await and writer.drain() fails with an - exception. - -- bpo-36889: Introduce :class:`asyncio.Stream` class that merges - :class:`asyncio.StreamReader` and :class:`asyncio.StreamWriter` - functionality. :class:`asyncio.Stream` can work in readonly, writeonly and - readwrite modes. Provide :func:`asyncio.connect`, - :func:`asyncio.connect_unix`, :func:`asyncio.connect_read_pipe` and - :func:`asyncio.connect_write_pipe` factories to open - :class:`asyncio.Stream` connections. Provide :class:`asyncio.StreamServer` - and :class:`UnixStreamServer` to serve servers with asyncio.Stream API. - Modify :func:`asyncio.create_subprocess_shell` and - :func:`asyncio.create_subprocess_exec` to use :class:`asyncio.Stream` - instead of deprecated :class:`StreamReader` and :class:`StreamWriter`. - Deprecate :class:`asyncio.StreamReader` and :class:`asyncio.StreamWriter`. - Deprecate usage of private classes, e.g. - :class:`asyncio.FlowControlMixing` and - :class:`asyncio.StreamReaderProtocol` outside of asyncio package. - -- bpo-36845: Added validation of integer prefixes to the construction of IP - networks and interfaces in the ipaddress module. - -- bpo-23378: Add an extend action to argparser. - -- bpo-36867: Fix a bug making a SharedMemoryManager instance and its parent - process use two separate resource_tracker processes. - -- bpo-23896: Adds a grammar to lib2to3.pygram that contains exec as a - function not as statement. - -- bpo-36895: The function ``time.clock()`` was deprecated in 3.3 in favor of - ``time.perf_counter()`` and marked for removal in 3.8, it has removed. - -- bpo-35545: Fix asyncio discarding IPv6 scopes when ensuring hostname - resolutions internally - -- bpo-36887: Add new function :func:`math.isqrt` to compute integer square - roots. - -- bpo-34632: Introduce the ``importlib.metadata`` module with (provisional) - support for reading metadata from third-party packages. - -- bpo-36878: When using `type_comments=True` in `ast.parse`, treat `# type: - ignore` followed by a non-alphanumeric character and then arbitrary text - as a type ignore, instead of requiring nothing but whitespace or another - comment. This is to permit formations such as `# type: ignore[E1000]`. - -- bpo-36778: ``cp65001`` encoding (Windows code page 65001) becomes an alias - to ``utf_8`` encoding. - -- bpo-36867: The multiprocessing.resource_tracker replaces the - multiprocessing.semaphore_tracker module. Other than semaphores, - resource_tracker also tracks shared_memory segments. - -- bpo-30262: The ``Cache`` and ``Statement`` objects of the :mod:`sqlite3` - module are not exposed to the user. Patch by Aviv Palivoda. - -- bpo-24538: In `shutil.copystat()`, first copy extended file attributes and - then file permissions, since extended attributes can only be set on the - destination while it is still writeable. - -- bpo-36829: Add new :func:`sys.unraisablehook` function which can be - overridden to control how "unraisable exceptions" are handled. It is - called when an exception has occurred but there is no way for Python to - handle it. For example, when a destructor raises an exception or during - garbage collection (:func:`gc.collect`). - -- bpo-36832: Introducing ``zipfile.Path``, a pathlib-compatible wrapper for - traversing zip files. - -- bpo-36814: Fix an issue where os.posix_spawnp() would incorrectly raise a - TypeError when file_actions is None. - -- bpo-33110: Handle exceptions raised by functions added by - concurrent.futures add_done_callback correctly when the Future has already - completed. - -- bpo-26903: Limit `max_workers` in `ProcessPoolExecutor` to 61 to work - around a WaitForMultipleObjects limitation. - -- bpo-36813: Fix :class:`~logging.handlers.QueueListener` to call - ``queue.task_done()`` upon stopping. Patch by Bar Harel. - -- bpo-36806: Forbid creation of asyncio stream objects like StreamReader, - StreamWriter, Process, and their protocols outside of asyncio package. - -- bpo-36802: Provide both sync and async calls for StreamWriter.write() and - StreamWriter.close() - -- bpo-36801: Properly handle SSL connection closing in asyncio - StreamWriter.drain() call. - -- bpo-36785: Implement PEP 574 (pickle protocol 5 with out-of-band buffers). - -- bpo-36772: functools.lru_cache() can now be used as a straight decorator - in addition to its existing usage as a function that returns a decorator. - -- bpo-6584: Add a :exc:`~gzip.BadGzipFile` exception to the :mod:`gzip` - module. - -- bpo-36748: Optimized write buffering in C implementation of - ``TextIOWrapper``. Writing ASCII string to ``TextIOWrapper`` with ascii, - latin1, or utf-8 encoding is about 20% faster. Patch by Inada Naoki. - -- bpo-8138: Don't mark ``wsgiref.simple_server.SimpleServer`` as - multi-threaded since ``wsgiref.simple_server.WSGIServer`` is - single-threaded. - -- bpo-22640: :func:`py_compile.compile` now supports silent mode. Patch by - Joannah Nanjekye - -- bpo-29183: Fix double exceptions in :class:`wsgiref.handlers.BaseHandler` - by calling its :meth:`~wsgiref.handlers.BaseHandler.close` method only - when no exception is raised. - -- bpo-36548: Improved the repr of regular expression flags. - -- bpo-36542: The signature of Python functions can now be overridden by - specifying the ``__text_signature__`` attribute. - -- bpo-36533: Reinitialize logging.Handler locks in forked child processes - instead of attempting to acquire them all in the parent before forking - only to be released in the child process. The acquire/release pattern was - leading to deadlocks in code that has implemented any form of chained - logging handlers that depend upon one another as the lock acquisition - order cannot be guaranteed. - -- bpo-35252: Throw a TypeError instead of an AssertionError when using an - invalid type annotation with singledispatch. - -- bpo-35900: Allow reduction methods to return a 6-item tuple where the 6th - item specifies a custom state-setting method that's called instead of the - regular ``__setstate__`` method. - -- bpo-35900: enable custom reduction callback registration for functions and - classes in _pickle.c, using the new Pickler's attribute - ``reducer_override`` - -- bpo-36368: Fix a bug crashing SharedMemoryManager instances in interactive - sessions after a ctrl-c (KeyboardInterrupt) was sent - -- bpo-31904: Fix mmap fail for VxWorks - -- bpo-27497: :meth:`csv.DictWriter.writeheader` now returns the return value - of the underlying :meth:`csv.Writer.writerow` method. Patch contributed by - Ashish Nitin Patil. - -- bpo-36239: Parsing .mo files now ignores comments starting and ending with - #-#-#-#-#. - -- bpo-26707: Enable plistlib to read and write binary plist files that were - created as a KeyedArchive file. Specifically, this allows the plistlib to - process 0x80 tokens as UID objects. - -- bpo-31904: Add posix module support for VxWorks. - -- bpo-35125: Asyncio: Remove inner callback on outer cancellation in shield - -- bpo-35721: Fix :meth:`asyncio.SelectorEventLoop.subprocess_exec()` leaks - file descriptors if ``Popen`` fails and called with - ``stdin=subprocess.PIPE``. Patch by Niklas Fiekas. - -- bpo-31855: :func:`unittest.mock.mock_open` results now respects the - argument of read([size]). Patch contributed by Rémi Lapeyre. - -- bpo-35431: Implement :func:`math.comb` that returns binomial coefficient, - that computes the number of ways to choose k items from n items without - repetition and without order. Patch by Yash Aggarwal and Keller Fuchs. - -- bpo-26660: Fixed permission errors in - :class:`~tempfile.TemporaryDirectory` clean up. Previously - ``TemporaryDirectory.cleanup()`` failed when non-writeable or - non-searchable files or directories were created inside a temporary - directory. - -- bpo-34271: Add debugging helpers to ssl module. It's now possible to dump - key material and to trace TLS protocol. The default and stdlib contexts - also support SSLKEYLOGFILE env var. - -- bpo-26467: Added AsyncMock to support using unittest to mock asyncio - coroutines. Patch by Lisa Roach. - -- bpo-33569: dataclasses.InitVar: Exposes the type used to create the init - var. - -- bpo-34424: Fix serialization of messages containing encoded strings when - the policy.linesep is set to a multi-character string. Patch by Jens - Troeger. - -- bpo-34303: Performance of :func:`functools.reduce` is slightly improved. - Patch by Sergey Fedoseev. - -- bpo-33361: Fix a bug in :class:`codecs.StreamRecoder` where seeking might - leave old data in a buffer and break subsequent read calls. Patch by Ammar - Askar. - -- bpo-22454: The :mod:`shlex` module now exposes :func:`shlex.join`, the - inverse of :func:`shlex.split`. Patch by Bo Bayles. - -- bpo-31922: :meth:`asyncio.AbstractEventLoop.create_datagram_endpoint`: Do - not connect UDP socket when broadcast is allowed. This allows to receive - replies after a UDP broadcast. - -- bpo-24882: Change ThreadPoolExecutor to use existing idle threads before - spinning up new ones. - -- bpo-31961: Added support for bytes and path-like objects in - :func:`subprocess.Popen` on Windows. The *args* parameter now accepts a - :term:`path-like object` if *shell* is ``False`` and a sequence containing - bytes and path-like objects. The *executable* parameter now accepts a - bytes and :term:`path-like object`. The *cwd* parameter now accepts a - bytes object. Based on patch by Anders Lorentsen. - -- bpo-33123: :class:`pathlib.Path.unlink` now accepts a *missing_ok* - parameter to avoid a :exc:`FileNotFoundError` from being raised. Patch by - Robert Buchholz. - -- bpo-32941: Allow :class:`mmap.mmap` objects to access the madvise() system - call (through :meth:`mmap.mmap.madvise`). - -- bpo-22102: Added support for ZIP files with disks set to 0. Such files are - commonly created by builtin tools on Windows when use ZIP64 extension. - Patch by Francisco Facioni. - -- bpo-32515: trace.py can now run modules via python3 -m trace -t --module - module_name - -- bpo-32299: Changed :func:`unittest.mock.patch.dict` to return the patched - dictionary when used as context manager. Patch by Vadim Tsander. - -- bpo-27141: Added a ``__copy__()`` to ``collections.UserList`` and - ``collections.UserDict`` in order to correctly implement shallow copying - of the objects. Patch by Bar Harel. - -- bpo-31829: ``\r``, ``\0`` and ``\x1a`` (end-of-file on Windows) are now - escaped in protocol 0 pickles of Unicode strings. This allows to load them - without loss from files open in text mode in Python 2. - -- bpo-23395: ``_thread.interrupt_main()`` now avoids setting the Python - error status if the ``SIGINT`` signal is ignored or not handled by Python. - -Documentation -------------- - -- bpo-36896: Clarify that some types have unstable constructor signature - between Python versions. - -- bpo-36686: Improve documentation of the stdin, stdout, and stderr - arguments of the ``asyncio.subprocess_exec`` function to specify which - values are supported. Also mention that decoding as text is not supported. - - Add a few tests to verify that the various values passed to the std* - arguments actually work. - -- bpo-36984: Improve version added references in ``typing`` module - by - Anthony Sottile. - -- bpo-36868: What's new now mentions SSLContext.hostname_checks_common_name - instead of SSLContext.host_flags. - -- bpo-35924: Add a note to the ``curses.addstr()`` documentation to warn - that multiline strings can cause segfaults because of an ncurses bug. - -- bpo-36783: Added C API Documentation for Time_FromTimeAndFold and - PyDateTime_FromDateAndTimeAndFold as per PEP 495. Patch by Edison - Abahurire. - -- bpo-36797: More of the legacy distutils documentation has been either - pruned, or else more clearly marked as being retained solely until the - setuptools documentation covers it independently. - -- bpo-22865: Add detail to the documentation on the `pty.spawn` function. - -- bpo-35397: Remove deprecation and document urllib.parse.unwrap(). Patch - contributed by Rémi Lapeyre. - -- bpo-32995: Added the context variable in glossary. - -- bpo-33519: Clarify that `copy()` is not part of the `MutableSequence` ABC. - -- bpo-33482: Make `codecs.StreamRecoder.writelines` take a list of bytes. - -- bpo-25735: Added documentation for func factorial to indicate that returns - integer values - -- bpo-20285: Expand object.__doc__ (docstring) to make it clearer. Modify - pydoc.py so that help(object) lists object methods (for other classes, - help omits methods of the object base class.) - -Tests ------ - -- bpo-37069: Modify test_coroutines, test_cprofile, test_generators, - test_raise, test_ssl and test_yield_from to use - :func:`test.support.catch_unraisable_exception` rather than - :func:`test.support.captured_stderr`. - -- bpo-37098: Fix test_memfd_create on older Linux Kernels. - -- bpo-37081: Test with OpenSSL 1.1.1c - -- bpo-36829: Add :func:`test.support.catch_unraisable_exception`: context - manager catching unraisable exception using :func:`sys.unraisablehook`. - -- bpo-36915: The main regrtest process now always removes all temporary - directories of worker processes even if they crash or if they are killed - on KeyboardInterrupt (CTRL+c). - -- bpo-36719: "python3 -m test -jN ..." now continues the execution of next - tests when a worker process crash (CHILD_ERROR state). Previously, the - test suite stopped immediately. Use --failfast to stop at the first error. - -- bpo-36816: Update Lib/test/selfsigned_pythontestdotnet.pem to match - self-signed.pythontest.net's new TLS certificate. - -- bpo-35925: Skip httplib and nntplib networking tests when they would - otherwise fail due to a modern OS or distro with a default OpenSSL policy - of rejecting connections to servers with weak certificates. - -- bpo-36782: Add tests for several C API functions in the :mod:`datetime` - module. Patch by Edison Abahurire. - -- bpo-36342: Fix test_multiprocessing in test_venv if platform lacks - functioning sem_open. - -Build ------ - -- bpo-36721: To embed Python into an application, a new ``--embed`` option - must be passed to ``python3-config --libs --embed`` to get ``-lpython3.8`` - (link the application to libpython). To support both 3.8 and older, try - ``python3-config --libs --embed`` first and fallback to ``python3-config - --libs`` (without ``--embed``) if the previous command fails. - - Add a pkg-config ``python-3.8-embed`` module to embed Python into an - application: ``pkg-config python-3.8-embed --libs`` includes - ``-lpython3.8``. To support both 3.8 and older, try ``pkg-config - python-X.Y-embed --libs`` first and fallback to ``pkg-config python-X.Y - --libs`` (without ``--embed``) if the previous command fails (replace - ``X.Y`` with the Python version). - - On the other hand, ``pkg-config python3.8 --libs`` no longer contains - ``-lpython3.8``. C extensions must not be linked to libpython (except on - Android, case handled by the script); this change is backward incompatible - on purpose. - -- bpo-36786: "make install" now runs compileall in parallel. - -Windows -------- - -- bpo-36965: include of STATUS_CONTROL_C_EXIT without depending on MSC - compiler - -- bpo-35926: Update to OpenSSL 1.1.1b for Windows. - -- bpo-29883: Add Windows support for UDP transports for the Proactor Event - Loop. Patch by Adam Meily. - -- bpo-33407: The :c:macro:`Py_DEPRECATED()` macro has been implemented for - MSVC. - -macOS ------ - -- bpo-36231: Support building Python on macOS without /usr/include - installed. As of macOS 10.14, system header files are only available - within an SDK provided by either the Command Line Tools or the Xcode app. - -IDLE ----- - -- bpo-35610: Replace now redundant .context_use_ps1 with .prompt_last_line. - This finishes change started in bpo-31858. - -- bpo-37038: Make idlelib.run runnable; add test clause. - -- bpo-36958: Print any argument other than None or int passed to SystemExit - or sys.exit(). - -- bpo-36807: When saving a file, call os.fsync() so bits are flushed to e.g. - USB drive. - -- bpo-32411: In browser.py, remove extraneous sorting by line number since - dictionary was created in line number order. - -Tools/Demos ------------ - -- bpo-37053: Handle strings like u"bar" correctly in - Tools/parser/unparse.py. Patch by Chih-Hsuan Yen. - -C API ------ - -- bpo-36763: Implement the :pep:`587` "Python Initialization Configuration". - -- bpo-36379: Fix crashes when attempting to use the *modulo* parameter when - ``__ipow__`` is implemented in C. - -- bpo-37107: Update :c:func:`PyObject_CallMethodObjArgs` and - ``_PyObject_CallMethodIdObjArgs`` to use ``_PyObject_GetMethod`` to avoid - creating a bound method object in many cases. Patch by Michael J. - Sullivan. - -- bpo-36974: Implement :pep:`590`: Vectorcall: a fast calling protocol for - CPython. This is a new protocol to optimize calls of custom callable - objects. - -- bpo-36763: ``Py_Main()`` now returns the exitcode rather than calling - ``Py_Exit(exitcode)`` when calling ``PyErr_Print()`` if the current - exception type is ``SystemExit``. - -- bpo-36922: Add new type flag ``Py_TPFLAGS_METHOD_DESCRIPTOR`` for objects - behaving like unbound methods. These are objects supporting the - optimization given by the ``LOAD_METHOD``/``CALL_METHOD`` opcodes. See PEP - 590. - -- bpo-36728: The :c:func:`PyEval_ReInitThreads` function has been removed - from the C API. It should not be called explicitly: use - :c:func:`PyOS_AfterFork_Child` instead. - - -What's New in Python 3.8.0 alpha 4? -=================================== - -*Release date: 2019-05-06* - -Security --------- - -- bpo-36742: Fixes mishandling of pre-normalization characters in - urlsplit(). - -- bpo-30458: Address CVE-2019-9740 by disallowing URL paths with embedded - whitespace or control characters through into the underlying http client - request. Such potentially malicious header injection URLs now cause an - http.client.InvalidURL exception to be raised. - -- bpo-35755: :func:`shutil.which` now uses ``os.confstr("CS_PATH")`` if - available and if the :envvar:`PATH` environment variable is not set. - Remove also the current directory from :data:`posixpath.defpath`. On Unix, - :func:`shutil.which` and the :mod:`subprocess` module no longer search the - executable in the current directory if the :envvar:`PATH` environment - variable is not set. - -Core and Builtins ------------------ - -- bpo-36722: In debug build, import now also looks for C extensions compiled - in release mode and for C extensions compiled in the stable ABI. - -- bpo-32849: Fix Python Initialization code on FreeBSD to detect properly - when stdin file descriptor (fd 0) is invalid. - -- bpo-36623: Remove parser headers and related function declarations that - lack implementations after the removal of pgen. - -- bpo-20180: ``dict.pop()`` is now up to 33% faster thanks to Argument - Clinic. Patch by Inada Naoki. - -- bpo-36611: Debug memory allocators: disable serialno field by default from - debug hooks on Python memory allocators to reduce the memory footprint by - 5%. Enable :mod:`tracemalloc` to get the traceback where a memory block - has been allocated when a fatal memory error is logged to decide where to - put a breakpoint. Compile Python with ``PYMEM_DEBUG_SERIALNO`` defined to - get back the field. - -- bpo-36588: On AIX, :attr:`sys.platform` doesn't contain the major version - anymore. Always return ``'aix'``, instead of ``'aix3'`` .. ``'aix7'``. - Since older Python versions include the version number, it is recommended - to always use ``sys.platform.startswith('aix')``. Contributed by M. Felt. - -- bpo-36549: Change str.capitalize to use titlecase for the first character - instead of uppercase. - -- bpo-36540: Implement :pep:`570` (Python positional-only parameters). Patch - by Pablo Galindo. - -- bpo-36475: :c:func:`PyEval_AcquireLock` and :c:func:`PyEval_AcquireThread` - now terminate the current thread if called while the interpreter is - finalizing, making them consistent with :c:func:`PyEval_RestoreThread`, - :c:func:`Py_END_ALLOW_THREADS`, and :c:func:`PyGILState_Ensure`. - -- bpo-36504: Fix signed integer overflow in _ctypes.c's - ``PyCArrayType_new()``. - -- bpo-20844: Fix running script with encoding cookie and LF line ending may - fail on Windows. - -- bpo-24214: Fixed support of the surrogatepass error handler in the UTF-8 - incremental decoder. - -- bpo-36452: Changing ``dict`` keys during iteration of the dict itself, - ``keys()``, ``values()``, or ``items()`` will now be detected in certain - corner cases where keys are deleted/added so that the number of keys isn't - changed. A `RuntimeError` will be raised after ``len(dict)`` iterations. - Contributed by Thomas Perl. - -- bpo-36459: Fix a possible double ``PyMem_FREE()`` due to tokenizer.c's - ``tok_nextc()``. - -- bpo-36433: Fixed TypeError message in classmethoddescr_call. - -- bpo-36430: Fix a possible reference leak in :func:`itertools.count`. - -- bpo-36440: Include node names in ``ParserError`` messages, instead of - numeric IDs. Patch by A. Skrobov. - -- bpo-36143: Regenerate :mod:`keyword` from the Grammar and Tokens file - using pgen. Patch by Pablo Galindo. - -- bpo-18372: Add missing :c:func:`PyObject_GC_Track` calls in the - :mod:`pickle` module. Patch by Zackery Spytz. - -Library -------- - -- bpo-35952: Fix pythoninfo when the compiler is missing. - -- bpo-28238: The ``.find*()`` methods of xml.etree.ElementTree can now - search for wildcards like ``{*}tag`` and ``{ns}*`` that match a tag in any - namespace or all tags in a namespace. Patch by Stefan Behnel. - -- bpo-26978: `pathlib.path.link_to()` is now implemented. It creates a hard - link pointing to a path. - -- bpo-1613500: :class:`fileinput.FileInput` now uses the input file mode to - correctly set the output file mode (previously it was hardcoded to - ``'w'``) when ``inplace=True`` is passed to its constructor. - -- bpo-36734: Fix compilation of ``faulthandler.c`` on HP-UX. Initialize - ``stack_t current_stack`` to zero using ``memset()``. - -- bpo-13611: The xml.etree.ElementTree packages gained support for C14N 2.0 - serialisation. Patch by Stefan Behnel. - -- bpo-36669: Add missing matrix multiplication operator support to - weakref.proxy. - -- bpo-36676: The XMLParser() in xml.etree.ElementTree provides namespace - prefix context to the parser target if it defines the callback methods - "start_ns()" and/or "end_ns()". Patch by Stefan Behnel. - -- bpo-36673: The TreeBuilder and XMLPullParser in xml.etree.ElementTree - gained support for parsing comments and processing instructions. Patch by - Stefan Behnel. - -- bpo-36650: The C version of functools.lru_cache() was treating calls with - an empty ``**kwargs`` dictionary as being distinct from calls with no - keywords at all. This did not result in an incorrect answer, but it did - trigger an unexpected cache miss. - -- bpo-28552: Fix :mod:`distutils.sysconfig` if :data:`sys.executable` is - ``None`` or an empty string: use :func:`os.getcwd` to initialize - ``project_base``. Fix also the distutils build command: don't use - :data:`sys.executable` if it is ``None`` or an empty string. - -- bpo-35755: :func:`shutil.which` and - :func:`distutils.spawn.find_executable` now use ``os.confstr("CS_PATH")`` - if available instead of :data:`os.defpath`, if the ``PATH`` environment - variable is not set. Moreover, don't use ``os.confstr("CS_PATH")`` nor - :data:`os.defpath` if the ``PATH`` environment variable is set to an empty - string. - -- bpo-25430: improve performance of ``IPNetwork.__contains__()`` - -- bpo-30485: Path expressions in xml.etree.ElementTree can now avoid - explicit namespace prefixes for tags (or the "{namespace}tag" notation) by - passing a default namespace with an empty string prefix. - -- bpo-36613: Fix :mod:`asyncio` wait() not removing callback if exception - -- bpo-36598: Fix ``isinstance`` check for Mock objects with spec when the - code is executed under tracing. Patch by Karthikeyan Singaravelan. - -- bpo-18748: In development mode (:option:`-X` ``dev``) and in debug build, - the :class:`io.IOBase` destructor now logs ``close()`` exceptions. These - exceptions are silent by default in release mode. - -- bpo-36575: The ``_lsprof`` module now uses internal timer same to - ``time.perf_counter()`` by default. ``gettimeofday(2)`` was used on Unix. - New timer has better resolution on most Unix platforms and timings are no - longer impacted by system clock updates since ``perf_counter()`` is - monotonic. Patch by Inada Naoki. - -- bpo-33461: ``json.loads`` now emits ``DeprecationWarning`` when - ``encoding`` option is specified. Patch by Matthias Bussonnier. - -- bpo-36559: The random module now prefers the lean internal _sha512 module - over hashlib for seed(version=2) to optimize import time. - -- bpo-17561: Set backlog=None as the default for socket.create_server. - -- bpo-34373: Fix :func:`time.mktime` error handling on AIX for year before - 1970. - -- bpo-36232: Improve error message when trying to open existing DBM database - that actually doesn't exist. Patch by Marco Rougeth. - -- bpo-36546: Add statistics.quantiles() - -- bpo-36050: Optimized ``http.client.HTTPResponse.read()`` for large - response. Patch by Inada Naoki. - -- bpo-36522: If *debuglevel* is set to >0 in :mod:`http.client`, print all - values for headers with multiple values for the same header name. Patch by - Matt Houglum. - -- bpo-36492: Deprecated passing required arguments like *func* as keyword - arguments in functions which should accept arbitrary keyword arguments and - pass them to other function. Arbitrary keyword arguments (even with names - "self" and "func") can now be passed to these functions if the required - arguments are passed as positional arguments. - -- bpo-27181: Add statistics.geometric_mean(). - -- bpo-30427: ``os.path.normcase()`` relies on ``os.fspath()`` to check the - type of its argument. Redundant checks have been removed from its - ``posixpath.normcase()`` and ``ntpath.normcase()`` implementations. Patch - by Wolfgang Maier. - -- bpo-36385: Stop rejecting IPv4 octets for being ambiguously octal. Leading - zeros are ignored, and no longer are assumed to specify octal octets. - Octets are always decimal numbers. Octets must still be no more than three - digits, including leading zeroes. - -- bpo-36434: Errors during writing to a ZIP file no longer prevent to - properly close it. - -- bpo-36407: Fixed wrong indentation writing for CDATA section in - xml.dom.minidom. Patch by Vladimir Surjaninov. - -- bpo-36326: inspect.getdoc() can now find docstrings for member objects - when __slots__ is a dictionary. - -- bpo-36366: Calling ``stop()`` on an unstarted or stopped - :func:`unittest.mock.patch` object will now return `None` instead of - raising :exc:`RuntimeError`, making the method idempotent. Patch by - Karthikeyan Singaravelan. - -- bpo-36348: The :meth:`imap.IMAP4.logout` method no longer ignores silently - arbitrary exceptions. - -- bpo-31904: Add time module support and fix test_time faiures for VxWorks. - -- bpo-36227: Added support for keyword arguments `default_namespace` and - `xml_declaration` in functions ElementTree.tostring() and - ElementTree.tostringlist(). - -- bpo-36004: Added new alternate constructors - :meth:`datetime.date.fromisocalendar` and - :meth:`datetime.datetime.fromisocalendar`, which construct date objects - from ISO year, week number and weekday; these are the inverse of each - class's ``isocalendar`` method. Patch by Paul Ganssle. - -- bpo-35936: :mod:`modulefinder` no longer depends on the deprecated - :mod:`imp` module, and the initializer for - :class:`modulefinder.ModuleFinder` now has immutable default arguments. - Patch by Brandt Bucher. - -- bpo-35376: :mod:`modulefinder` correctly handles modules that have the - same name as a bad package. Patch by Brandt Bucher. - -- bpo-17396: :mod:`modulefinder` no longer crashes when encountering syntax - errors in followed imports. Patch by Brandt Bucher. - -- bpo-35934: Added :meth:`~socket.create_server()` and - :meth:`~socket.has_dualstack_ipv6()` convenience functions to automate the - necessary tasks usually involved when creating a server socket, including - accepting both IPv4 and IPv6 connections on the same socket. (Contributed - by Giampaolo Rodola in :issue:`17561`.) - -- bpo-23078: Add support for :func:`classmethod` and :func:`staticmethod` to - :func:`unittest.mock.create_autospec`. Initial patch by Felipe Ochoa. - -- bpo-35416: Fix potential resource warnings in distutils. Patch by Mickaël - Schoentgen. - -- bpo-25451: Add transparency methods to :class:`tkinter.PhotoImage`. Patch - by Zackery Spytz. - -- bpo-35082: Don't return deleted attributes when calling dir on a - :class:`unittest.mock.Mock`. - -- bpo-34547: :class:`wsgiref.handlers.BaseHandler` now handles abrupt client - connection terminations gracefully. Patch by Petter Strandmark. - -- bpo-31658: :func:`xml.sax.parse` now supports :term:`path-like <path-like - object>`. Patch by Mickaël Schoentgen. - -- bpo-34139: Remove stale unix datagram socket before binding - -- bpo-33530: Implemented Happy Eyeballs in `asyncio.create_connection()`. - Added two new arguments, *happy_eyeballs_delay* and *interleave*, to - specify Happy Eyeballs behavior. - -- bpo-33291: Do not raise AttributeError when calling the inspect functions - isgeneratorfunction, iscoroutinefunction, isasyncgenfunction on a method - created from an arbitrary callable. Instead, return False. - -- bpo-31310: Fix the multiprocessing.semaphore_tracker so it is reused by - child processes - -- bpo-31292: Fix ``setup.py check --restructuredtext`` for files containing - ``include`` directives. - -Documentation -------------- - -- bpo-36625: Remove obsolete comments from docstrings in fractions.Fraction - -- bpo-30840: Document relative imports - -- bpo-36523: Add docstring for io.IOBase.writelines(). - -- bpo-36425: New documentation translation: `Simplified Chinese - <https://docs.python.org/zh-cn/>`_. - -- bpo-36345: Avoid the duplication of code from ``Tools/scripts/serve.py`` - in using the :rst:dir:`literalinclude` directive for the basic - wsgiref-based web server in the documentation of :mod:`wsgiref`. - Contributed by Stéphane Wirtel. - -- bpo-36345: Using the code of the ``Tools/scripts/serve.py`` script as an - example in the :mod:`wsgiref` documentation. Contributed by Stéphane - Wirtel. - -- bpo-36157: Added Documention for PyInterpreterState_Main(). - -- bpo-33043: Updates the docs.python.org page with the addition of a - 'Contributing to Docs' link at the end of the page (between 'Reporting - Bugs' and 'About Documentation'). Updates the 'Found a Bug' page with - additional links and information in the Documentation Bugs section. - -- bpo-35581: @typing.type_check_only now allows type stubs to mark functions - and classes not available during runtime. - -- bpo-33832: Add glossary entry for 'magic method'. - -- bpo-32913: Added re.Match.groupdict example to regex HOWTO. - -Tests ------ - -- bpo-36719: regrtest now always detects uncollectable objects. Previously, - the check was only enabled by ``--findleaks``. The check now also works - with ``-jN/--multiprocess N``. ``--findleaks`` becomes a deprecated alias - to ``--fail-env-changed``. - -- bpo-36725: When using multiprocessing mode (-jN), regrtest now better - reports errors if a worker process fails, and it exits immediately on a - worker thread failure or when interrupted. - -- bpo-36454: Change test_time.test_monotonic() to test only the lower bound - of elapsed time after a sleep command rather than the upper bound. This - prevents unnecessary test failures on slow buildbots. Patch by Victor - Stinner. - -- bpo-32424: Improve test coverage for xml.etree.ElementTree. Patch by - Gordon P. Hemsley. - -- bpo-32424: Fix typo in test_cyclic_gc() test for xml.etree.ElementTree. - Patch by Gordon P. Hemsley. - -- bpo-36635: Add a new :mod:`_testinternalcapi` module to test the internal - C API. - -- bpo-36629: Fix ``test_imap4_host_default_value()`` of ``test_imaplib``: - catch also :data:`errno.ENETUNREACH` error. - -- bpo-36611: Fix ``test_sys.test_getallocatedblocks()`` when - :mod:`tracemalloc` is enabled. - -- bpo-36560: Fix reference leak hunting in regrtest: compute also deltas (of - reference count, allocated memory blocks, file descriptor count) during - warmup, to ensure that everything is initialized before starting to hunt - reference leaks. - -- bpo-36565: Fix reference hunting (``python3 -m test -R 3:3``) when Python - has no built-in abc module. - -- bpo-31904: Port test_resource to VxWorks: skip tests cases setting - RLIMIT_FSIZE and RLIMIT_CPU. - -- bpo-31904: Fix test_tabnanny on VxWorks: adjust ENOENT error message. - -- bpo-36436: Fix ``_testcapi.pymem_buffer_overflow()``: handle memory - allocation failure. - -- bpo-31904: Fix test_utf8_mode on VxWorks: Python always use UTF-8 on - VxWorks. - -- bpo-36341: Fix tests that may fail with PermissionError upon calling - bind() on AF_UNIX sockets. - -Build ------ - -- bpo-36747: Remove the stale scriptsinstall Makefile target. - -- bpo-21536: On Unix, C extensions are no longer linked to libpython except - on Android and Cygwin. - - It is now possible for a statically linked Python to load a C extension - built using a shared library Python. - - When Python is embedded, ``libpython`` must not be loaded with - ``RTLD_LOCAL``, but ``RTLD_GLOBAL`` instead. Previously, using - ``RTLD_LOCAL``, it was already not possible to load C extensions which - were not linked to ``libpython``, such as C extensions of the standard - library built by the ``*shared*`` section of ``Modules/Setup``. - - distutils, python-config and python-config.py have been modified. - -- bpo-36707: ``./configure --with-pymalloc`` no longer adds the ``m`` flag - to SOABI (sys.implementation.cache_tag). Enabling or disabling pymalloc - has no impact on the ABI. - -- bpo-36635: Change ``PyAPI_FUNC(type)``, ``PyAPI_DATA(type)`` and - ``PyMODINIT_FUNC`` macros of ``pyport.h`` when ``Py_BUILD_CORE_MODULE`` is - defined. The ``Py_BUILD_CORE_MODULE`` define must be now be used to build - a C extension as a dynamic library accessing Python internals: export the - PyInit_xxx() function in DLL exports on Windows. - -- bpo-31904: Don't build the ``_crypt`` extension on VxWorks. - -- bpo-36618: Add ``-fmax-type-align=8`` to CFLAGS when clang compiler is - detected. The pymalloc memory allocator aligns memory on 8 bytes. On - x86-64, clang expects alignment on 16 bytes by default and so uses MOVAPS - instruction which can lead to segmentation fault. Instruct clang that - Python is limited to alignment on 8 bytes to use MOVUPS instruction - instead: slower but don't trigger a SIGSEGV if the memory is not aligned - on 16 bytes. Sadly, the flag must be added to ``CFLAGS`` and not just - ``CFLAGS_NODIST``, since third party C extensions can have the same issue. - -- bpo-36605: ``make tags`` and ``make TAGS`` now also parse - ``Modules/_io/*.c`` and ``Modules/_io/*.h``. - -- bpo-36465: Release builds and debug builds are now ABI compatible: - defining the ``Py_DEBUG`` macro no longer implies the ``Py_TRACE_REFS`` - macro, which introduces the only ABI incompatibility. The - ``Py_TRACE_REFS`` macro, which adds the :func:`sys.getobjects` function - and the :envvar:`PYTHONDUMPREFS` environment variable, can be set using - the new ``./configure --with-trace-refs`` build option. - -- bpo-36577: setup.py now correctly reports missing OpenSSL headers and - libraries again. - -- bpo-36544: Fix regression introduced in bpo-36146 refactoring setup.py - -- bpo-36508: ``python-config --ldflags`` no longer includes flags of the - ``LINKFORSHARED`` variable. The ``LINKFORSHARED`` variable must only be - used to build executables. - -- bpo-36503: Remove references to "aix3" and "aix4". Patch by M. Felt. - -Windows -------- - -- bpo-35920: Added platform.win32_edition() and platform.win32_is_iot(). - Added support for cross-compiling packages for Windows ARM32. Skip tests - that are not expected to work on Windows IoT Core ARM32. - -- bpo-36649: Remove trailing spaces for registry keys when installed via the - Store. - -- bpo-34144: Fixed activate.bat to correctly update codepage when chcp.com - returns dots in output. Patch by Lorenz Mende. - -- bpo-36509: Added preset-iot layout for Windows IoT ARM containers. This - layout doesn't contain UI components like tkinter or IDLE. It also doesn't - contain files to support on-target builds since Windows ARM32 builds must - be cross-compiled when using MSVC. - -- bpo-35941: enum_certificates function of the ssl module now returns - certificates from all available certificate stores inside windows in a - query instead of returning only certificates from the system wide - certificate store. This includes certificates from these certificate - stores: local machine, local machine enterprise, local machine group - policy, current user, current user group policy, services, users. - ssl.enum_crls() function is changed in the same way to return all - certificate revocation lists inside the windows certificate revocation - list stores. - -- bpo-36441: Fixes creating a venv when debug binaries are installed. - -- bpo-36085: Enable better DLL resolution on Windows by using safe DLL - search paths and adding :func:`os.add_dll_directory`. - -- bpo-36010: Add the venv standard library module to the nuget distribution - for Windows. - -- bpo-29515: Add the following socket module constants on Windows: - IPPROTO_AH IPPROTO_CBT IPPROTO_DSTOPTS IPPROTO_EGP IPPROTO_ESP - IPPROTO_FRAGMENT IPPROTO_GGP IPPROTO_HOPOPTS IPPROTO_ICLFXBM - IPPROTO_ICMPV6 IPPROTO_IDP IPPROTO_IGMP IPPROTO_IGP IPPROTO_IPV4 - IPPROTO_IPV6 IPPROTO_L2TP IPPROTO_MAX IPPROTO_ND IPPROTO_NONE IPPROTO_PGM - IPPROTO_PIM IPPROTO_PUP IPPROTO_RDP IPPROTO_ROUTING IPPROTO_SCTP - IPPROTO_ST - -- bpo-35947: Added current version of libffi to cpython-source-deps. Change - _ctypes to use current version of libffi on Windows. - -- bpo-34060: Report system load when running test suite on Windows. Patch by - Ammar Askar. Based on prior work by Jeremy Kloth. - -- bpo-31512: With the Windows 10 Creators Update, non-elevated users can now - create symlinks as long as the computer has Developer Mode enabled. - -macOS ------ - -- bpo-34602: Avoid failures setting macOS stack resource limit with - resource.setrlimit. This reverts an earlier fix for bpo-18075 which forced - a non-default stack size when building the interpreter executable on - macOS. - -IDLE ----- - -- bpo-36429: Fix starting IDLE with pyshell. Add idlelib.pyshell alias at - top; remove pyshell alias at bottom. Remove obsolete __name__=='__main__' - command. - -Tools/Demos ------------ - -- bpo-14546: Fix the argument handling in Tools/scripts/lll.py. - -C API ------ - -- bpo-36763: Fix memory leak in :c:func:`Py_SetStandardStreamEncoding`: - release memory if the function is called twice. - -- bpo-36641: :c:expr:`PyDoc_VAR(name)` and :c:expr:`PyDoc_STRVAR(name,str)` - now create ``static const char name[]`` instead of ``static char name[]``. - Patch by Inada Naoki. - -- bpo-36389: Change the value of ``CLEANBYTE``, ``DEADDYTE`` and - ``FORBIDDENBYTE`` internal constants used by debug hooks on Python memory - allocators (:c:func:`PyMem_SetupDebugHooks` function). Byte patterns - ``0xCB``, ``0xDB`` and ``0xFB`` have been replaced with ``0xCD``, ``0xDD`` - and ``0xFD`` to use the same values than Windows CRT debug ``malloc()`` - and ``free()``. - -- bpo-36443: Since Python 3.7.0, calling :c:func:`Py_DecodeLocale` before - :c:func:`Py_Initialize` produces mojibake if the ``LC_CTYPE`` locale is - coerced and/or if the UTF-8 Mode is enabled by the user configuration. The - LC_CTYPE coercion and UTF-8 Mode are now disabled by default to fix the - mojibake issue. They must now be enabled explicitly (opt-in) using the new - :c:func:`_Py_PreInitialize` API with ``_PyPreConfig``. - -- bpo-36025: Fixed an accidental change to the datetime C API where the - arguments to the :c:func:`PyDate_FromTimestamp` function were incorrectly - interpreted as a single timestamp rather than an arguments tuple, which - causes existing code to start raising :exc:`TypeError`. The - backwards-incompatible change was only present in alpha releases of Python - 3.8. Patch by Paul Ganssle. - -- bpo-35810: Modify ``PyObject_Init`` to correctly increase the refcount of - heap- allocated Type objects. Also fix the refcounts of the heap-allocated - types that were either doing this manually or not decreasing the type's - refcount in tp_dealloc - - -What's New in Python 3.8.0 alpha 3? -=================================== - -*Release date: 2019-03-25* - -Security --------- - -- bpo-36216: Changes urlsplit() to raise ValueError when the URL contains - characters that decompose under IDNA encoding (NFKC-normalization) into - characters that affect how the URL is parsed. - -- bpo-35121: Don't send cookies of domain A without Domain attribute to - domain B when domain A is a suffix match of domain B while using a - cookiejar with :class:`http.cookiejar.DefaultCookiePolicy` policy. Patch - by Karthikeyan Singaravelan. - -Core and Builtins ------------------ - -- bpo-36421: Fix a possible double decref in _ctypes.c's - ``PyCArrayType_new()``. - -- bpo-36412: Fix a possible crash when creating a new dictionary. - -- bpo-36398: Fix a possible crash in ``structseq_repr()``. - -- bpo-36256: Fix bug in parsermodule when parsing a state in a DFA that has - two or more arcs with labels of the same type. Patch by Pablo Galindo. - -- bpo-36365: repr(structseq) is no longer limited to 512 bytes. - -- bpo-36374: Fix a possible null pointer dereference in - ``merge_consts_recursive()``. Patch by Zackery Spytz. - -- bpo-36236: At Python initialization, the current directory is no longer - prepended to :data:`sys.path` if it has been removed. - -- bpo-36352: Python initialization now fails with an error, rather than - silently truncating paths, if a path is too long. - -- bpo-36301: Python initialization now fails if decoding ``pybuilddir.txt`` - configuration file fails at startup. - -- bpo-36333: Fix leak in _PyRuntimeState_Fini. Contributed by Stéphane - Wirtel. - -- bpo-36332: The builtin :func:`compile` can now handle AST objects that - contain assignment expressions. Patch by Pablo Galindo. - -- bpo-36282: Improved error message for too much positional arguments in - some builtin functions. - -- bpo-30040: New empty dict uses fewer memory for now. It used more memory - than empty dict created by ``dict.clear()``. And empty dict creation and - deletion is about 2x faster. Patch by Inada Naoki. - -- bpo-36262: Fix an unlikely memory leak on conversion from string to float - in the function ``_Py_dg_strtod()`` used by ``float(str)``, - ``complex(str)``, :func:`pickle.load`, :func:`marshal.load`, etc. - -- bpo-36252: Update Unicode databases to version 12.0.0. - -- bpo-36218: Fix a segfault occurring when sorting a list of heterogeneous - values. Patch contributed by Rémi Lapeyre and Elliot Gorokhovsky. - -- bpo-36188: Cleaned up left-over vestiges of Python 2 unbound method - handling in method objects and documentation. Patch by Martijn Pieters - -- bpo-36124: Add a new interpreter-specific dict and expose it in the C-API - via PyInterpreterState_GetDict(). This parallels PyThreadState_GetDict(). - However, extension modules should continue using PyModule_GetState() for - their own internal per-interpreter state. - -- bpo-35975: Add a ``feature_version`` flag to ``ast.parse()`` (documented) - and ``compile()`` (hidden) that allows tweaking the parser to support - older versions of the grammar. In particular, if ``feature_version`` is 5 - or 6, the hacks for the ``async`` and ``await`` keyword from PEP 492 are - reinstated. (For 7 or higher, these are unconditionally treated as - keywords, but they are still special tokens rather than ``NAME`` tokens - that the parser driver recognizes.) - -- bpo-31904: Use UTF-8 as the system encoding on VxWorks. - -- bpo-36048: The :meth:`~object.__index__` special method will be used - instead of :meth:`~object.__int__` for implicit conversion of Python - numbers to C integers. Using the ``__int__()`` method in implicit - conversions has been deprecated. - -- bpo-35808: Retire pgen and use a modified version of pgen2 to generate the - parser. Patch by Pablo Galindo. - -Library -------- - -- bpo-36401: The class documentation created by pydoc now has a separate - section for readonly properties. - -- bpo-36320: The typing.NamedTuple() class has deprecated the _field_types - attribute in favor of the __annotations__ attribute which carried the same - information. Also, both attributes were converted from OrderedDict to a - regular dict. - -- bpo-34745: Fix :mod:`asyncio` ssl memory issues caused by circular - references - -- bpo-36324: Add method to statistics.NormalDist for computing the inverse - cumulative normal distribution. - -- bpo-36321: collections.namedtuple() misspelled the name of an attribute. - To be consistent with typing.NamedTuple, the attribute name should have - been "_field_defaults" instead of "_fields_defaults". For backwards - compatibility, both spellings are now created. The misspelled version may - be removed in the future. - -- bpo-36297: "unicode_internal" codec is removed. It was deprecated since - Python 3.3. Patch by Inada Naoki. - -- bpo-36298: Raise ModuleNotFoundError in pyclbr when a module can't be - found. Thanks to 'mental' for the bug report. - -- bpo-36268: Switch the default format used for writing tars with - mod:`tarfile` to the modern POSIX.1-2001 pax standard, from the - vendor-specific GNU. Contributed by C.A.M. Gerlach. - -- bpo-36285: Fix integer overflows in the array module. Patch by Stephan - Hohe. - -- bpo-31904: Add _signal module support for VxWorks. - -- bpo-36272: :mod:`logging` does not silently ignore RecursionError anymore. - Patch contributed by Rémi Lapeyre. - -- bpo-36280: Add a kind field to ast.Constant. It is 'u' if the literal has - a 'u' prefix (i.e. a Python 2 style unicode literal), else None. - -- bpo-35931: The :mod:`pdb` ``debug`` command now gracefully handles all - exceptions. - -- bpo-36251: Fix format strings used for stderrprinter and re.Match reprs. - Patch by Stephan Hohe. - -- bpo-36235: Fix ``CFLAGS`` in ``customize_compiler()`` of - ``distutils.sysconfig``: when the ``CFLAGS`` environment variable is - defined, don't override ``CFLAGS`` variable with the ``OPT`` variable - anymore. Initial patch written by David Malcolm. - -- bpo-35807: Update ensurepip to install pip 19.0.3 and setuptools 40.8.0. - -- bpo-36139: Release GIL when closing :class:`~mmap.mmap` objects. - -- bpo-36179: Fix two unlikely reference leaks in _hashopenssl. The leaks - only occur in out-of-memory cases. - -- bpo-36169: Add overlap() method to statistics.NormalDist. Computes the - overlapping coefficient for two normal distributions. - -- bpo-36103: Default buffer size used by ``shutil.copyfileobj()`` is changed - from 16 KiB to 64 KiB on non-Windows platform to reduce system call - overhead. Contributed by Inada Naoki. - -- bpo-36130: Fix ``pdb`` with ``skip=...`` when stepping into a frame - without a ``__name__`` global. Patch by Anthony Sottile. - -- bpo-35652: shutil.copytree(copy_function=...) erroneously pass DirEntry - instead of a path string. - -- bpo-35178: Ensure custom :func:`warnings.formatwarning` function can - receive `line` as positional argument. Based on patch by Tashrif Billah. - -- bpo-36106: Resolve potential name clash with libm's sinpi(). Patch by - Dmitrii Pasechnik. - -- bpo-36091: Clean up reference to async generator in Lib/types. Patch by - Henry Chen. - -- bpo-36043: :class:`FileCookieJar` supports :term:`path-like object`. - Contributed by Stéphane Wirtel - -- bpo-35899: Enum has been fixed to correctly handle empty strings and - strings with non-Latin characters (ie. 'α', 'א') without crashing. - Original patch contributed by Maxwell. Assisted by Stéphane Wirtel. - -- bpo-21269: Add ``args`` and ``kwargs`` properties to mock call objects. - Contributed by Kumar Akshay. - -- bpo-30670: `pprint.pp` has been added to pretty-print objects with - dictionary keys being sorted with their insertion order by default. - Parameter *sort_dicts* has been added to `pprint.pprint`, `pprint.pformat` - and `pprint.PrettyPrinter`. Contributed by Rémi Lapeyre. - -- bpo-35843: Implement ``__getitem__`` for ``_NamespacePath``. Patch by - Anthony Sottile. - -- bpo-35802: Clean up code which checked presence of ``os.stat`` / - ``os.lstat`` / ``os.chmod`` which are always present. Patch by Anthony - Sottile. - -- bpo-35715: Librates the return value of a ProcessPoolExecutor - _process_worker after it's no longer needed to free memory - -- bpo-35493: Use :func:`multiprocessing.connection.wait` instead of polling - each 0.2 seconds for worker updates in :class:`multiprocessing.Pool`. - Patch by Pablo Galindo. - -- bpo-35661: Store the venv prompt in pyvenv.cfg. - -- bpo-35121: Don't set cookie for a request when the request path is a - prefix match of the cookie's path attribute but doesn't end with "/". - Patch by Karthikeyan Singaravelan. - -- bpo-21478: Calls to a child function created with - :func:`unittest.mock.create_autospec` should propagate to the parent. - Patch by Karthikeyan Singaravelan. - -- bpo-35198: Fix C++ extension compilation on AIX - -Documentation -------------- - -- bpo-36329: Declare the path of the Python binary for the usage of - ``Tools/scripts/serve.py`` when executing ``make -C Doc/ serve``. - Contributed by Stéphane Wirtel - -- bpo-36138: Improve documentation about converting datetime.timedelta to - scalars. - -- bpo-21314: A new entry was added to the Core Language Section of the - Programming FAQ, which explaines the usage of slash(/) in the signature of - a function. Patch by Lysandros Nikolaou - -Tests ------ - -- bpo-36234: test_posix.PosixUidGidTests: add tests for invalid uid/gid type - (str). Initial patch written by David Malcolm. - -- bpo-29571: Fix ``test_re.test_locale_flag()``: use - ``locale.getpreferredencoding()`` rather than ``locale.getlocale()`` to - get the locale encoding. With some locales, ``locale.getlocale()`` returns - the wrong encoding. - -- bpo-36123: Fix race condition in test_socket. - -Build ------ - -- bpo-36356: Fix leaks that led to build failure when configured with - address sanitizer. - -- bpo-36146: Add ``TEST_EXTENSIONS`` constant to ``setup.py`` to allow to - not build test extensions like ``_testcapi``. - -- bpo-36146: Fix setup.py on macOS: only add ``/usr/include/ffi`` to include - directories of _ctypes, not for all extensions. - -- bpo-31904: Enable build system to cross-build for VxWorks RTOS. - -Windows -------- - -- bpo-36312: Fixed decoders for the following code pages: 50220, 50221, - 50222, 50225, 50227, 50229, 57002 through 57011, 65000 and 42. - -- bpo-36264: Don't honor POSIX ``HOME`` in ``os.path.expanduser`` on - windows. Patch by Anthony Sottile. - -- bpo-24643: Fix name collisions due to ``#define timezone _timezone`` in - PC/pyconfig.h. - -IDLE ----- - -- bpo-36405: Use dict unpacking in idlelib. - -- bpo-36396: Remove fgBg param of idlelib.config.GetHighlight(). This param - was only used twice and changed the return type. - -- bpo-36176: Fix IDLE autocomplete & calltip popup colors. Prevent conflicts - with Linux dark themes (and slightly darken calltip background). - -- bpo-23205: For the grep module, add tests for findfiles, refactor - findfiles to be a module-level function, and refactor findfiles to use - os.walk. - -- bpo-23216: Add docstrings to IDLE search modules. - -- bpo-36152: Remove colorizer.ColorDelegator.close_when_done and the - corresponding argument of .close(). In IDLE, both have always been None - or False since 2007. - -- bpo-32129: Avoid blurry IDLE application icon on macOS with Tk 8.6. Patch - by Kevin Walzer. - -- bpo-36096: Refactor class variables to instance variables in colorizer. - -- bpo-30348: Increase test coverage of idlelib.autocomplete by 30%. Patch by - Louie Lu - -Tools/Demos ------------ - -- bpo-35132: Fix py-list and py-bt commands of python-gdb.py on gdb7. - -- bpo-32217: Fix freeze script on Windows. - -C API ------ - -- bpo-36381: Raise ``DeprecationWarning`` when '#' formats are used for - building or parsing values without ``PY_SSIZE_T_CLEAN``. - -- bpo-36142: The whole coreconfig.h header is now excluded from - Py_LIMITED_API. Move functions definitions into a new internal - pycore_coreconfig.h header. - - -What's New in Python 3.8.0 alpha 2? -=================================== - -*Release date: 2019-02-25* - -Core and Builtins ------------------ - -- bpo-36052: Raise a :exc:`SyntaxError` when assigning a value to - `__debug__` with the Assignment Operator. Contributed by Stéphane Wirtel - and Pablo Galindo. - -- bpo-36012: Doubled the speed of class variable writes. When a non-dunder - attribute was updated, there was an unnecessary call to update slots. - -- bpo-35942: The error message emitted when returning invalid types from - ``__fspath__`` in interfaces that allow passing :class:`~os.PathLike` - objects has been improved and now it does explain the origin of the error. - -- bpo-36016: ``gc.get_objects`` can now receive an optional parameter - indicating a generation to get objects from. Patch by Pablo Galindo. - -- bpo-1054041: When the main interpreter exits due to an uncaught - KeyboardInterrupt, the process now exits in the appropriate manner for its - parent process to detect that a SIGINT or ^C terminated the process. This - allows shells and batch scripts to understand that the user has asked them - to stop. - -- bpo-35992: Fix ``__class_getitem__()`` not being called on a class with a - custom non-subscriptable metaclass. - -- bpo-35993: Fix a crash on fork when using subinterpreters. Contributed by - Stéphane Wirtel - -- bpo-35991: Fix a potential double free in Modules/_randommodule.c. - -- bpo-35961: Fix a crash in slice_richcompare(): use strong references - rather than stolen references for the two temporary internal tuples. - -- bpo-35911: Enable the creation of cell objects by adding a - ``cell.__new__`` method, and expose the type ``cell`` in ``Lib/types.py`` - under the name CellType. Patch by Pierre Glaser. - -- bpo-12822: Use monotonic clock for ``pthread_cond_timedwait`` when - ``pthread_condattr_setclock`` and ``CLOCK_MONOTONIC`` are available. - -- bpo-15248: The compiler emits now syntax warnings in the case when a comma - is likely missed before tuple or list. - -- bpo-35886: The implementation of PyInterpreterState has been moved into - the internal header files (guarded by Py_BUILD_CORE). - -- bpo-31506: Clarify the errors reported when ``object.__new__`` and - ``object.__init__`` receive more than one argument. Contributed by Sanyam - Khurana. - -- bpo-35724: Signal-handling is now guaranteed to happen relative to the - main interpreter. - -- bpo-33608: We added a new internal _Py_AddPendingCall() that operates - relative to the provided interpreter. This allows us to use the existing - implementation to ask another interpreter to do work that cannot be done - in the current interpreter, like decref an object the other interpreter - owns. The existing Py_AddPendingCall() only operates relative to the main - interpreter. - -- bpo-33989: Fix a possible crash in :meth:`list.sort` when sorting objects - with ``ob_type->tp_richcompare == NULL``. Patch by Zackery Spytz. - -Library -------- - -- bpo-35512: :func:`unittest.mock.patch.dict` used as a decorator with - string target resolves the target during function call instead of during - decorator construction. Patch by Karthikeyan Singaravelan. - -- bpo-36018: Add statistics.NormalDist, a tool for creating and manipulating - normal distributions of random variable. Features a composite class that - treats the mean and standard deviation of measurement data as single - entity. - -- bpo-35904: Added statistics.fmean() as a faster, floating point variant of - the existing mean() function. - -- bpo-35918: Removed broken ``has_key`` method from - multiprocessing.managers.SyncManager.dict. Contributed by Rémi Lapeyre. - -- bpo-18283: Add support for bytes to :func:`shutil.which`. - -- bpo-35960: Fix :func:`dataclasses.field` throwing away empty mapping - objects passed as metadata. - -- bpo-35500: Write expected and actual call parameters on separate lines in - :meth:`unittest.mock.Mock.assert_called_with` assertion errors. - Contributed by Susan Su. - -- bpo-35931: The :mod:`pdb` ``debug`` command now gracefully handles syntax - errors. - -- bpo-24209: In http.server script, rely on getaddrinfo to bind to preferred - address based on the bind parameter. Now default bind or binding to a name - may bind to IPv6 or dual-stack, depending on the environment. - -- bpo-35321: Set ``__spec__.origin`` of ``_frozen_importlib`` to frozen so - that it matches the behavior of ``_frozen_importlib_external``. Patch by - Nina Zakharenko. - -- bpo-35378: Fix a reference issue inside :class:`multiprocessing.Pool` that - caused the pool to remain alive if it was deleted without being closed or - terminated explicitly. A new strong reference is added to the pool - iterators to link the lifetime of the pool to the lifetime of its - iterators so the pool does not get destroyed if a pool iterator is still - alive. - -- bpo-34294: re module, fix wrong capturing groups in rare cases. - :func:`re.search`, :func:`re.findall`, :func:`re.sub` and other functions - that scan through string looking for a match, should reset capturing - groups between two match attempts. Patch by Ma Lin. - -- bpo-35615: :mod:`weakref`: Fix a RuntimeError when copying a - WeakKeyDictionary or a WeakValueDictionary, due to some keys or values - disappearing while iterating. - -- bpo-35606: Implement :func:`math.prod` as analogous function to - :func:`sum` that returns the product of a 'start' value (default: 1) times - an iterable of numbers. Patch by Pablo Galindo. - -- bpo-32417: Performing arithmetic between :class:`datetime.datetime` - subclasses and :class:`datetime.timedelta` now returns an object of the - same type as the :class:`datetime.datetime` subclass. As a result, - :meth:`datetime.datetime.astimezone` and alternate constructors like - :meth:`datetime.datetime.now` and :meth:`datetime.fromtimestamp` called - with a ``tz`` argument now *also* retain their subclass. - -- bpo-35153: Add *headers* optional keyword-only parameter to - :class:`xmlrpc.client.ServerProxy`, :class:`xmlrpc.client.Transport` and - :class:`xmlrpc.client.SafeTransport`. Patch by Cédric Krier. - -- bpo-34572: Fix C implementation of pickle.loads to use importlib's locking - mechanisms, and thereby avoid using partially loaded modules. Patch by Tim - Burgess. - -Documentation -------------- - -- bpo-36083: Fix formatting of --check-hash-based-pycs options in the - manpage Synopsis. - -- bpo-36007: Bump minimum sphinx version to 1.8. Patch by Anthony Sottile. - -- bpo-22062: Update documentation and docstrings for pathlib. Original patch - by Mike Short. - -Tests ------ - -- bpo-27313: Avoid test_ttk_guionly ComboboxTest failure with macOS Cocoa - Tk. - -- bpo-36019: Add test.support.TEST_HTTP_URL and replace references of - http://www.example.com by this new constant. Contributed by Stéphane - Wirtel. - -- bpo-36037: Fix test_ssl for strict OpenSSL configuration like RHEL8 strict - crypto policy. Use older TLS version for minimum TLS version of the server - SSL context if needed, to test TLS version older than default minimum TLS - version. - -- bpo-35798: Added :func:`test.support.check_syntax_warning`. - -- bpo-35505: Make test_imap4_host_default_value independent on whether the - local IMAP server is running. - -- bpo-35917: multiprocessing: provide unit tests for SyncManager and - SharedMemoryManager classes + all the shareable types which are supposed - to be supported by them. (patch by Giampaolo Rodola) - -- bpo-35704: Skip ``test_shutil.test_unpack_archive_xztar`` to prevent a - MemoryError on 32-bit AIX when MAXDATA setting is less than 0x20000000. - - Patch by Michael Felt (aixtools) - -- bpo-34720: Assert m_state != NULL to mimic GC traversal functions that do - not correctly handle module creation when the module state has not been - created. - -Windows -------- - -- bpo-35976: Added ARM build support to Windows build files in PCBuild. - -- bpo-35692: ``pathlib`` no longer raises when checking file and directory - existence on drives that are not ready - -- bpo-35872: Uses the base Python executable when invoking venv in a virtual - environment - -- bpo-35873: Prevents venv paths being inherited by child processes - -- bpo-35299: Fix sysconfig detection of the source directory and distutils - handling of pyconfig.h during PGO profiling - -IDLE ----- - -- bpo-24310: IDLE -- Document settings dialog font tab sample. - -- bpo-35833: Revise IDLE doc for control codes sent to Shell. Add a code - example block. - -- bpo-35689: Add docstrings and unittests for colorizer.py. - - -What's New in Python 3.8.0 alpha 1? -=================================== - -*Release date: 2019-02-03* - -Security --------- - -- bpo-35746: [CVE-2019-5010] Fix a NULL pointer deref in ssl module. The - cert parser did not handle CRL distribution points with empty DP or URI - correctly. A malicious or buggy certificate can result into segfault. - Vulnerability (TALOS-2018-0758) reported by Colin Read and Nicolas Edet of - Cisco. - -- bpo-34812: The :option:`-I` command line option (run Python in isolated - mode) is now also copied by the :mod:`multiprocessing` and - :mod:`distutils` modules when spawning child processes. Previously, only - :option:`-E` and :option:`-s` options (enabled by :option:`-I`) were - copied. - -- bpo-34791: The xml.sax and xml.dom.domreg no longer use environment - variables to override parser implementations when - sys.flags.ignore_environment is set by -E or -I arguments. - -- bpo-17239: The xml.sax and xml.dom.minidom parsers no longer processes - external entities by default. External DTD and ENTITY declarations no - longer load files or create network connections. - -- bpo-34623: CVE-2018-14647: The C accelerated _elementtree module now - initializes hash randomization salt from _Py_HashSecret instead of - libexpat's default CSPRNG. - -- bpo-34405: Updated to OpenSSL 1.1.0i for Windows builds. - -- bpo-33871: Fixed sending the part of the file in :func:`os.sendfile` on - macOS. Using the *trailers* argument could cause sending more bytes from - the input file than was specified. - -- bpo-32533: Fixed thread-safety of error handling in _ssl. - -- bpo-33136: Harden ssl module against LibreSSL CVE-2018-8970. - X509_VERIFY_PARAM_set1_host() is called with an explicit namelen. A new - test ensures that NULL bytes are not allowed. - -- bpo-33001: Minimal fix to prevent buffer overrun in os.symlink on Windows - -- bpo-32981: Regexes in difflib and poplib were vulnerable to catastrophic - backtracking. These regexes formed potential DOS vectors (REDOS). They - have been refactored. This resolves CVE-2018-1060 and CVE-2018-1061. Patch - by Jamie Davis. - -- bpo-28414: The ssl module now allows users to perform their own IDN - en/decoding when using SNI. - -Core and Builtins ------------------ - -- bpo-35877: Make parenthesis optional for named expressions in while - statement. Patch by Karthikeyan Singaravelan. - -- bpo-35814: Allow same right hand side expressions in annotated assignments - as in normal ones. In particular, ``x: Tuple[int, int] = 1, 2`` (without - parentheses on the right) is now allowed. - -- bpo-35766: Add the option to parse PEP 484 type comments in the ast - module. (Off by default.) This is merging the key functionality of the - third party fork thereof, - [typed_ast](https://github.com/python/typed_ast). - -- bpo-35713: Reorganize Python initialization to get working exceptions and - sys.stderr earlier. - -- bpo-33416: Add end line and end column position information to the Python - AST nodes. This is a C-level backwards incompatible change. - -- bpo-35720: Fixed a minor memory leak in pymain_parse_cmdline_impl function - in Modules/main.c - -- bpo-35634: ``func(**kwargs)`` will now raise an error when ``kwargs`` is a - mapping containing multiple entries with the same key. An error was - already raised when other keyword arguments are passed before ``**kwargs`` - since Python 3.6. - -- bpo-35623: Fix a crash when sorting very long lists. Patch by Stephan - Hohe. - -- bpo-35214: clang Memory Sanitizer build instrumentation was added to work - around false positives from posix, socket, time, test_io, and - test_faulthandler. - -- bpo-35560: Fix an assertion error in :func:`format` in debug build for - floating point formatting with "n" format, zero padding and small width. - Release build is not impacted. Patch by Karthikeyan Singaravelan. - -- bpo-35552: Format characters ``%s`` and ``%V`` in - :c:func:`PyUnicode_FromFormat` and ``%s`` in :c:func:`PyBytes_FromFormat` - no longer read memory past the limit if *precision* is specified. - -- bpo-35504: Fix segfaults and :exc:`SystemError`\ s when deleting certain - attributes. Patch by Zackery Spytz. - -- bpo-35504: Fixed a SystemError when delete the characters_written - attribute of an OSError. - -- bpo-35494: Improved syntax error messages for unbalanced parentheses in - f-string. - -- bpo-35444: Fixed error handling in pickling methods when fail to look up - builtin "getattr". Sped up pickling iterators. - -- bpo-35436: Fix various issues with memory allocation error handling. - Patch by Zackery Spytz. - -- bpo-35423: Separate the signal handling trigger in the eval loop from the - "pending calls" machinery. There is no semantic change and the difference - in performance is insignificant. - -- bpo-35357: Internal attributes' names of unittest.mock._Call and - unittest.mock.MagicProxy (name, parent & from_kall) are now prefixed with - _mock_ in order to prevent clashes with widely used object attributes. - Fixed minor typo in test function name. - -- bpo-35372: Fixed the code page decoder for input longer than 2 GiB - containing undecodable bytes. - -- bpo-35336: Fix PYTHONCOERCECLOCALE=1 environment variable: only coerce the - C locale if the LC_CTYPE locale is "C". - -- bpo-31241: The *lineno* and *col_offset* attributes of AST nodes for list - comprehensions, generator expressions and tuples are now point to the - opening parenthesis or square brace. For tuples without parenthesis they - point to the position of the first item. - -- bpo-33954: For :meth:`str.format`, :meth:`float.__format__` and - :meth:`complex.__format__` methods for non-ASCII decimal point when using - the "n" formatter. - -- bpo-35269: Fix a possible segfault involving a newly created coroutine. - Patch by Zackery Spytz. - -- bpo-35224: Implement :pep:`572` (assignment expressions). Patch by Emily - Morehouse. - -- bpo-32492: Speed up :class:`namedtuple` attribute access by 1.6x using a C - fast-path for the name descriptors. Patch by Pablo Galindo. - -- bpo-35214: Fixed an out of bounds memory access when parsing a truncated - unicode escape sequence at the end of a string such as ``'\N'``. It would - read one byte beyond the end of the memory allocation. - -- bpo-35214: The interpreter and extension modules have had annotations - added so that they work properly under clang's Memory Sanitizer. A new - configure flag --with-memory-sanitizer has been added to make test builds - of this nature easier to perform. - -- bpo-35193: Fix an off by one error in the bytecode peephole optimizer - where it could read bytes beyond the end of bounds of an array when - removing unreachable code. This bug was present in every release of Python - 3.6 and 3.7 until now. - -- bpo-35169: Improved error messages for forbidden assignments. - -- bpo-34022: Fix handling of hash-based bytecode files in :mod:`zipimport`. - Patch by Elvis Pranskevichus. - -- bpo-28401: Debug builds will no longer to attempt to import extension - modules built for the ABI as they were never compatible to begin with. - Patch by Stefano Rivera. - -- bpo-29341: Clarify in the docstrings of :mod:`os` methods that path-like - objects are also accepted as input parameters. - -- bpo-35050: :mod:`socket`: Fix off-by-one bug in length check for - ``AF_ALG`` name and type. - -- bpo-29743: Raise :exc:`ValueError` instead of :exc:`OverflowError` in case - of a negative ``_length_`` in a :class:`ctypes.Array` subclass. Also - raise :exc:`TypeError` instead of :exc:`AttributeError` for non-integer - ``_length_``. Original patch by Oren Milman. - -- bpo-16806: Fix ``lineno`` and ``col_offset`` for multi-line string tokens. - -- bpo-35029: :exc:`SyntaxWarning` raised as an exception at code generation - time will be now replaced with a :exc:`SyntaxError` for better error - reporting. - -- bpo-34983: Expose :meth:`symtable.Symbol.is_nonlocal` in the symtable - module. Patch by Pablo Galindo. - -- bpo-34974: :class:`bytes` and :class:`bytearray` constructors no longer - convert unexpected exceptions (e.g. :exc:`MemoryError` and - :exc:`KeyboardInterrupt`) to :exc:`TypeError`. - -- bpo-34939: Allow annotated names in module namespace that are declared - global before the annotation happens. Patch by Pablo Galindo. - -- bpo-34973: Fixed crash in :func:`bytes` when the :class:`list` argument is - mutated while it is iterated. - -- bpo-34876: The *lineno* and *col_offset* attributes of the AST for - decorated function and class refer now to the position of the - corresponding ``def``, ``async def`` and ``class`` instead of the position - of the first decorator. This leads to more correct line reporting in - tracing. This is the only case when the position of child AST nodes can - precede the position of the parent AST node. - -- bpo-34879: Fix a possible null pointer dereference in bytesobject.c. - Patch by Zackery Spytz. - -- bpo-34784: Fix the implementation of PyStructSequence_NewType in order to - create heap allocated StructSequences. - -- bpo-32912: A :exc:`SyntaxWarning` is now emitted instead of a - :exc:`DeprecationWarning` for invalid escape sequences in string and bytes - literals. - -- bpo-34854: Fixed a crash in compiling string annotations containing a - lambda with a keyword-only argument that doesn't have a default value. - -- bpo-34850: The compiler now produces a :exc:`SyntaxWarning` when identity - checks (``is`` and ``is not``) are used with certain types of literals - (e.g. strings, ints). These can often work by accident in CPython, but - are not guaranteed by the language spec. The warning advises users to use - equality tests (``==`` and ``!=``) instead. - -- bpo-34824: Fix a possible null pointer dereference in Modules/_ssl.c. - Patch by Zackery Spytz. - -- bpo-30156: The C function ``property_descr_get()`` uses a "cached" tuple - to optimize function calls. But this tuple can be discovered in debug mode - with :func:`sys.getobjects()`. Remove the optimization, it's not really - worth it and it causes 3 different crashes last years. - -- bpo-34762: Fix contextvars C API to use PyObject* pointer types. - -- bpo-34751: The hash function for tuples is now based on xxHash which gives - better collision results on (formerly) pathological cases. Additionally, - on 64-bit systems it improves tuple hashes in general. Patch by Jeroen - Demeyer with substantial contributions by Tim Peters. - -- bpo-34735: Fix a memory leak in Modules/timemodule.c. Patch by Zackery - Spytz. - -- bpo-34683: Fixed a bug where some SyntaxError error pointed to locations - that were off-by-one. - -- bpo-34651: Only allow the main interpreter to fork. The avoids the - possibility of affecting the main interpreter, which is critical to - operation of the runtime. - -- bpo-34653: Remove unused function PyParser_SimpleParseStringFilename. - -- bpo-32236: Warn that line buffering is not supported if :func:`open` is - called with binary mode and ``buffering=1``. - -- bpo-34641: Further restrict the syntax of the left-hand side of keyword - arguments in function calls. In particular, ``f((keyword)=arg)`` is now - disallowed. - -- bpo-34637: Make the *start* argument to *sum()* visible as a keyword - argument. - -- bpo-1621: Do not assume signed integer overflow behavior (C undefined - behavior) when performing set hash table resizing. - -- bpo-34588: Fix an off-by-one in the recursive call pruning feature of - traceback formatting. - -- bpo-34485: On Windows, the LC_CTYPE is now set to the user preferred - locale at startup. Previously, the LC_CTYPE locale was "C" at startup, but - changed when calling setlocale(LC_CTYPE, "") or setlocale(LC_ALL, ""). - -- bpo-34485: Standard streams like sys.stdout now use the "surrogateescape" - error handler, instead of "strict", on the POSIX locale (when the C locale - is not coerced and the UTF-8 Mode is disabled). - -- bpo-34485: Fix the error handler of standard streams like sys.stdout: - PYTHONIOENCODING=":" is now ignored instead of setting the error handler - to "strict". - -- bpo-34485: Python now gets the locale encoding with C code to initialize - the encoding of standard streams like sys.stdout. Moreover, the encoding - is now initialized to the Python codec name to get a normalized encoding - name and to ensure that the codec is loaded. The change avoids importing - _bootlocale and _locale modules at startup by default. - -- bpo-34527: On FreeBSD, Py_DecodeLocale() and Py_EncodeLocale() now also - forces the ASCII encoding if the LC_CTYPE locale is "POSIX", not only if - the LC_CTYPE locale is "C". - -- bpo-34527: The UTF-8 Mode is now also enabled by the "POSIX" locale, not - only by the "C" locale. - -- bpo-34403: On HP-UX with C or POSIX locale, sys.getfilesystemencoding() - now returns "ascii" instead of "roman8" (when the UTF-8 Mode is disabled - and the C locale is not coerced). - -- bpo-34523: The Python filesystem encoding is now read earlier during the - Python initialization. - -- bpo-12458: Tracebacks show now correct line number for subexpressions in - multiline expressions. Tracebacks show now the line number of the first - line for multiline expressions instead of the line number of the last - subexpression. - -- bpo-34408: Prevent a null pointer dereference and resource leakage in - ``PyInterpreterState_New()``. - -- bpo-34400: Fix undefined behavior in parsetok.c. Patch by Zackery Spytz. - -- bpo-33073: Added as_integer_ratio to ints to make them more interoperable - with floats. - -- bpo-34377: Update valgrind suppression list to use - ``_PyObject_Free``/``_PyObject_Realloc`` instead of - ``PyObject_Free``/``PyObject_Realloc``. - -- bpo-34353: Added the "socket" option in the `stat.filemode()` Python - implementation to match the C implementation. - -- bpo-34320: Fix ``dict(od)`` didn't copy iteration order of OrderedDict. - -- bpo-34113: Fixed crash on debug builds when opcode stack was adjusted with - negative numbers. Patch by Constantin Petrisor. - -- bpo-34100: Compiler now merges constants in tuples and frozensets - recursively. Code attributes like ``co_names`` are merged too. - -- bpo-34151: Performance of list concatenation, repetition and slicing - operations is slightly improved. Patch by Sergey Fedoseev. - -- bpo-34170: -X dev: it is now possible to override the memory allocator - using PYTHONMALLOC even if the developer mode is enabled. - -- bpo-33237: Improved :exc:`AttributeError` message for partially - initialized module. - -- bpo-34149: Fix min and max functions to get default behavior when key is - None. - -- bpo-34125: Profiling of unbound built-in methods now works when - ``**kwargs`` is given. - -- bpo-34141: Optimized pickling atomic types (None, bool, int, float, bytes, - str). - -- bpo-34126: Fix crashes when profiling certain invalid calls of unbound - methods. Patch by Jeroen Demeyer. - -- bpo-24618: Fixed reading invalid memory when create the code object with - too small varnames tuple or too large argument counts. - -- bpo-34068: In :meth:`io.IOBase.close`, ensure that the - :attr:`~io.IOBase.closed` attribute is not set with a live exception. - Patch by Zackery Spytz and Serhiy Storchaka. - -- bpo-34087: Fix buffer overflow while converting unicode to numeric values. - -- bpo-34080: Fixed a memory leak in the compiler when it raised some - uncommon errors during tokenizing. - -- bpo-34066: Disabled interruption by Ctrl-C between calling ``open()`` and - entering a **with** block in ``with open()``. - -- bpo-34042: Fix dict.copy() to maintain correct total refcount (as reported - by sys.gettotalrefcount()). - -- bpo-33418: Fix potential memory leak in function object when it creates - reference cycle. - -- bpo-33985: Implement contextvars.ContextVar.name attribute. - -- bpo-33956: Update vendored Expat library copy to version 2.2.5. - -- bpo-24596: Decref the module object in :c:func:`PyRun_SimpleFileExFlags` - before calling :c:func:`PyErr_Print()`. Patch by Zackery Spytz. - -- bpo-33451: Close directly executed pyc files before calling - ``PyEval_EvalCode()``. - -- bpo-1617161: The hash of :class:`BuiltinMethodType` instances (methods of - built-in classes) now depends on the hash of the identity of *__self__* - instead of its value. The hash and equality of :class:`ModuleType` and - :class:`MethodWrapperType` instances (methods of user-defined classes and - some methods of built-in classes like ``str.__add__``) now depend on the - hash and equality of the identity of *__self__* instead of its value. - :class:`MethodWrapperType` instances no longer support ordering. - -- bpo-33824: Fix "LC_ALL=C python3.7 -V": reset properly the command line - parser when the encoding changes after reading the Python configuration. - -- bpo-33803: Fix a crash in hamt.c caused by enabling GC tracking for an - object that hadn't all of its fields set to NULL. - -- bpo-33738: Seven macro incompatibilities with the Limited API were fixed, - and the macros :c:func:`PyIter_Check`, :c:func:`PyIndex_Check` and - :c:func:`PyExceptionClass_Name` were added as functions. A script for - automatic macro checks was added. - -- bpo-33786: Fix asynchronous generators to handle GeneratorExit in athrow() - correctly - -- bpo-30167: ``PyRun_SimpleFileExFlags`` removes ``__cached__`` from module - in addition to ``__file__``. - -- bpo-33706: Fix a crash in Python initialization when parsing the command - line options. Thanks Christoph Gohlke for the bug report and the fix! - -- bpo-33597: Reduce ``PyGC_Head`` size from 3 words to 2 words. - -- bpo-30654: Fixed reset of the SIGINT handler to SIG_DFL on interpreter - shutdown even when there was a custom handler set previously. Patch by - Philipp Kerling. - -- bpo-33622: Fixed a leak when the garbage collector fails to add an object - with the ``__del__`` method or referenced by it into the - :data:`gc.garbage` list. :c:func:`PyGC_Collect` can now be called when an - exception is set and preserves it. - -- bpo-33462: Make dict and dict views reversible. Patch by Rémi Lapeyre. - -- bpo-23722: A :exc:`RuntimeError` is now raised when the custom metaclass - doesn't provide the ``__classcell__`` entry in the namespace passed to - ``type.__new__``. A :exc:`DeprecationWarning` was emitted in Python - 3.6--3.7. - -- bpo-33499: Add :envvar:`PYTHONPYCACHEPREFIX` environment variable and - :option:`-X` ``pycache_prefix`` command-line option to set an alternate - root directory for writing module bytecode cache files. - -- bpo-25711: The :mod:`zipimport` module has been rewritten in pure Python. - -- bpo-33509: Fix module_globals parameter of warnings.warn_explicit(): don't - crash if module_globals is not a dict. - -- bpo-31849: Fix signed/unsigned comparison warning in pyhash.c. - -- bpo-33475: Fixed miscellaneous bugs in converting annotations to strings - and optimized parentheses in the string representation. - -- bpo-20104: Added support for the `setpgroup`, `resetids`, `setsigmask`, - `setsigdef` and `scheduler` parameters of `posix_spawn`. Patch by Pablo - Galindo. - -- bpo-33391: Fix a leak in set_symmetric_difference(). - -- bpo-33363: Raise a SyntaxError for ``async with`` and ``async for`` - statements outside of async functions. - -- bpo-28055: Fix unaligned accesses in siphash24(). Patch by Rolf Eike Beer. - -- bpo-33128: Fix a bug that causes PathFinder to appear twice on - sys.meta_path. Patch by Pablo Galindo Salgado. - -- bpo-33331: Modules imported last are now cleared first at interpreter - shutdown. - -- bpo-33312: Fixed clang ubsan (undefined behavior sanitizer) warnings in - dictobject.c by adjusting how the internal struct _dictkeysobject shared - keys structure is declared. - -- bpo-33305: Improved syntax error messages for invalid numerical literals. - -- bpo-33306: Improved syntax error messages for unbalanced parentheses. - -- bpo-33234: The list constructor will pre-size and not over-allocate when - the input length is known. - -- bpo-33270: Intern the names for all anonymous code objects. Patch by - Zackery Spytz. - -- bpo-30455: The C and Python code and the documentation related to tokens - are now generated from a single source file :file:`Grammar/Tokens`. - -- bpo-33176: Add a ``toreadonly()`` method to memoryviews. - -- bpo-33231: Fix potential memory leak in ``normalizestring()``. - -- bpo-33205: Change dict growth function from - ``round_up_to_power_2(used*2+hashtable_size/2)`` to - ``round_up_to_power_2(used*3)``. Previously, dict is shrinked only when - ``used == 0``. Now dict has more chance to be shrinked. - -- bpo-29922: Improved error messages in 'async with' when ``__aenter__()`` - or ``__aexit__()`` return non-awaitable object. - -- bpo-33199: Fix ``ma_version_tag`` in dict implementation is uninitialized - when copying from key-sharing dict. - -- bpo-33053: When using the -m switch, sys.path[0] is now explicitly - expanded as the *starting* working directory, rather than being left as - the empty path (which allows imports from the current working directory at - the time of the import) - -- bpo-33138: Changed standard error message for non-pickleable and - non-copyable types. It now says "cannot pickle" instead of "can't pickle" - or "cannot serialize". - -- bpo-33018: Improve consistency of errors raised by ``issubclass()`` when - called with a non-class and an abstract base class as the first and second - arguments, respectively. Patch by Josh Bronson. - -- bpo-33083: ``math.factorial`` no longer accepts arguments that are not - int-like. Patch by Pablo Galindo. - -- bpo-33041: Added new opcode :opcode:`END_ASYNC_FOR` and fixes the - following issues: - - * Setting global :exc:`StopAsyncIteration` no longer breaks ``async for`` - loops. - * Jumping into an ``async for`` loop is now disabled. - * Jumping out of an ``async for`` loop no longer corrupts the stack. - -- bpo-25750: Fix rare Python crash due to bad refcounting in - ``type_getattro()`` if a descriptor deletes itself from the class. Patch - by Jeroen Demeyer. - -- bpo-33041: Fixed bytecode generation for "async for" with a complex - target. A StopAsyncIteration raised on assigning or unpacking will be now - propagated instead of stopping the iteration. - -- bpo-33026: Fixed jumping out of "with" block by setting f_lineno. - -- bpo-33005: Fix a crash on fork when using a custom memory allocator (ex: - using PYTHONMALLOC env var). _PyGILState_Reinit() and - _PyInterpreterState_Enable() now use the default RAW memory allocator to - allocate a new interpreters mutex on fork. - -- bpo-32911: Due to unexpected compatibility issues discovered during - downstream beta testing, reverted :issue:`29463`. ``docstring`` field is - removed from Module, ClassDef, FunctionDef, and AsyncFunctionDef ast nodes - which was added in 3.7a1. Docstring expression is restored as a first - statement in their body. Based on patch by Inada Naoki. - -- bpo-17288: Prevent jumps from 'return' and 'exception' trace events. - -- bpo-32946: Importing names from already imported module with "from ... - import ..." is now 30% faster if the module is not a package. - -- bpo-32932: Make error message more revealing when there are non-str - objects in ``__all__``. - -- bpo-32925: Optimized iterating and containing test for literal lists - consisting of non-constants: ``x in [a, b]`` and ``for x in [a, b]``. The - case of all constant elements already was optimized. - -- bpo-32889: Update Valgrind suppression list to account for the rename of - ``Py_ADDRESS_IN_RANG`` to ``address_in_range``. - -- bpo-32836: Don't use temporary variables in cases of list/dict/set - comprehensions - -- bpo-31356: Remove the new API added in bpo-31356 (gc.ensure_disabled() - context manager). - -- bpo-32305: For namespace packages, ensure that both ``__file__`` and - ``__spec__.origin`` are set to None. - -- bpo-32303: Make sure ``__spec__.loader`` matches ``__loader__`` for - namespace packages. - -- bpo-32711: Fix the warning messages for Python/ast_unparse.c. Patch by - Stéphane Wirtel - -- bpo-32583: Fix possible crashing in builtin Unicode decoders caused by - write out-of-bound errors when using customized decode error handlers. - -- bpo-32489: A :keyword:`continue` statement is now allowed in the - :keyword:`finally` clause. - -- bpo-17611: Simplified the interpreter loop by moving the logic of - unrolling the stack of blocks into the compiler. The compiler emits now - explicit instructions for adjusting the stack of values and calling the - cleaning up code for :keyword:`break`, :keyword:`continue` and - :keyword:`return`. - - Removed opcodes :opcode:`BREAK_LOOP`, :opcode:`CONTINUE_LOOP`, - :opcode:`SETUP_LOOP` and :opcode:`SETUP_EXCEPT`. Added new opcodes - :opcode:`ROT_FOUR`, :opcode:`BEGIN_FINALLY` and :opcode:`CALL_FINALLY` and - :opcode:`POP_FINALLY`. Changed the behavior of :opcode:`END_FINALLY` and - :opcode:`WITH_CLEANUP_START`. - -- bpo-32285: New function unicodedata.is_normalized, which can check whether - a string is in a specific normal form. - -- bpo-10544: Yield expressions are now disallowed in comprehensions and - generator expressions except the expression for the outermost iterable. - -- bpo-32117: Iterable unpacking is now allowed without parentheses in yield - and return statements, e.g. ``yield 1, 2, 3, *rest``. Thanks to David - Cuthbert for the change and Jordan Chapman for added tests. - -- bpo-31902: Fix the ``col_offset`` attribute for ast nodes - ``ast.AsyncFor``, ``ast.AsyncFunctionDef``, and ``ast.AsyncWith``. - Previously, ``col_offset`` pointed to the keyword after ``async``. - -- bpo-25862: Fix assertion failures in the ``tell()`` method of - ``io.TextIOWrapper``. Patch by Zackery Spytz. - -- bpo-21983: Fix a crash in `ctypes.cast()` in case the type argument is a - ctypes structured data type. Patch by Eryk Sun and Oren Milman. - -- bpo-31577: Fix a crash in `os.utime()` in case of a bad ns argument. Patch - by Oren Milman. - -- bpo-29832: Remove references to 'getsockaddrarg' from various socket error - messages. Patch by Oren Milman. - -Library -------- - -- bpo-35845: Add 'order' parameter to memoryview.tobytes(). - -- bpo-35864: The _asdict() method for collections.namedtuple now returns a - regular dict instead of an OrderedDict. - -- bpo-35537: An ExitStack is now used internally within subprocess.Popen to - clean up pipe file handles. No behavior change in normal operation. But if - closing one handle were ever to cause an exception, the others will now be - closed instead of leaked. (patch by Giampaolo Rodola) - -- bpo-35847: RISC-V needed the CTYPES_PASS_BY_REF_HACK. Fixes ctypes - Structure test_pass_by_value. - -- bpo-35813: Shared memory submodule added to multiprocessing to avoid need - for serialization between processes - -- bpo-35780: Fix lru_cache() errors arising in recursive, reentrant, or - multi-threaded code. These errors could result in orphan links and in the - cache being trapped in a state with fewer than the specified maximum - number of links. Fix handling of negative maxsize which should have been - treated as zero. Fix errors in toggling the "full" status flag. Fix - misordering of links when errors are encountered. Sync-up the C code and - pure Python code for the space saving path in functions with a single - positional argument. In this common case, the space overhead of an lru - cache entry is reduced by almost half. Fix counting of cache misses. In - error cases, the miss count was out of sync with the actual number of - times the underlying user function was called. - -- bpo-35537: :func:`os.posix_spawn` and :func:`os.posix_spawnp` now have a - *setsid* parameter. - -- bpo-23846: :class:`asyncio.ProactorEventLoop` now catches and logs send - errors when the self-pipe is full. - -- bpo-34323: :mod:`asyncio`: Enhance ``IocpProactor.close()`` log: wait 1 - second before the first log, then log every second. Log also the number of - seconds since ``close()`` was called. - -- bpo-35674: Add a new :func:`os.posix_spawnp` function. Patch by Joannah - Nanjekye. - -- bpo-35733: ``ast.Constant(boolean)`` no longer an instance of - :class:`ast.Num`. Patch by Anthony Sottile. - -- bpo-35726: QueueHandler.prepare() now makes a copy of the record before - modifying and enqueueing it, to avoid affecting other handlers in the - chain. - -- bpo-35719: Sped up multi-argument :mod:`math` functions atan2(), - copysign(), remainder() and hypot() by 1.3--2.5 times. - -- bpo-35717: Fix KeyError exception raised when using enums and compile. - Patch contributed by Rémi Lapeyre. - -- bpo-35699: Fixed detection of Visual Studio Build Tools 2017 in distutils - -- bpo-32710: Fix memory leaks in asyncio ProactorEventLoop on overlapped - operation failure. - -- bpo-35702: The :data:`time.CLOCK_UPTIME_RAW` constant is now available for - macOS 10.12. - -- bpo-32710: Fix a memory leak in asyncio in the ProactorEventLoop when - ``ReadFile()`` or ``WSASend()`` overlapped operation fail immediately: - release the internal buffer. - -- bpo-35682: Fix ``asyncio.ProactorEventLoop.sendfile()``: don't attempt to - set the result of an internal future if it's already done. - -- bpo-35283: Add a deprecated warning for the - :meth:`threading.Thread.isAlive` method. Patch by Dong-hee Na. - -- bpo-35664: Improve operator.itemgetter() performance by 33% with optimized - argument handling and with adding a fast path for the common case of a - single non-negative integer index into a tuple (which is the typical use - case in the standard library). - -- bpo-35643: Fixed a SyntaxWarning: invalid escape sequence in - Modules/_sha3/cleanup.py. Patch by Mickaël Schoentgen. - -- bpo-35619: Improved support of custom data descriptors in :func:`help` and - :mod:`pydoc`. - -- bpo-28503: The `crypt` module now internally uses the `crypt_r()` library - function instead of `crypt()` when available. - -- bpo-35614: Fixed help() on metaclasses. Patch by Sanyam Khurana. - -- bpo-35568: Expose ``raise(signum)`` as `raise_signal` - -- bpo-35588: The floor division and modulo operations and the :func:`divmod` - function on :class:`fractions.Fraction` types are 2--4x faster. Patch by - Stefan Behnel. - -- bpo-35585: Speed-up building enums by value, e.g. http.HTTPStatus(200). - -- bpo-30561: random.gammavariate(1.0, beta) now computes the same result as - random.expovariate(1.0 / beta). This synchronizes the two algorithms and - eliminates some idiosyncrasies in the old implementation. It does however - produce a difference stream of random variables than it used to. - -- bpo-35537: The :mod:`subprocess` module can now use the - :func:`os.posix_spawn` function in some cases for better performance. - -- bpo-35526: Delaying the 'joke' of barry_as_FLUFL.mandatory to Python - version 4.0 - -- bpo-35523: Remove :mod:`ctypes` callback workaround: no longer create a - callback at startup. Avoid SELinux alert on ``import ctypes`` and ``import - uuid``. - -- bpo-31784: :func:`uuid.uuid1` now calls :func:`time.time_ns` rather than - ``int(time.time() * 1e9)``. - -- bpo-35513: :class:`~unittest.runner.TextTestRunner` of - :mod:`unittest.runner` now uses :func:`time.perf_counter` rather than - :func:`time.time` to measure the execution time of a test: - :func:`time.time` can go backwards, whereas :func:`time.perf_counter` is - monotonic. - -- bpo-35502: Fixed reference leaks in - :class:`xml.etree.ElementTree.TreeBuilder` in case of unfinished building - of the tree (in particular when an error was raised during parsing XML). - -- bpo-35348: Make :func:`platform.architecture` parsing of ``file`` command - output more reliable: add the ``-b`` option to the ``file`` command to - omit the filename, force the usage of the C locale, and search also the - "shared object" pattern. - -- bpo-35491: :mod:`multiprocessing`: Add ``Pool.__repr__()`` and enhance - ``BaseProcess.__repr__()`` (add pid and parent pid) to ease debugging. - Pool state constant values are now strings instead of integers, for - example ``RUN`` value becomes ``'RUN'`` instead of ``0``. - -- bpo-35477: :meth:`multiprocessing.Pool.__enter__` now fails if the pool is - not running: ``with pool:`` fails if used more than once. - -- bpo-31446: Copy command line that was passed to CreateProcessW since this - function can change the content of the input buffer. - -- bpo-35471: Python 2.4 dropped MacOS 9 support. The macpath module was - deprecated in Python 3.7. The module is now removed. - -- bpo-23057: Unblock Proactor event loop when keyboard interrupt is received - on Windows - -- bpo-35052: Fix xml.dom.minidom cloneNode() on a document with an entity: - pass the correct arguments to the user data handler of an entity. - -- bpo-20239: Allow repeated assignment deletion of - :class:`unittest.mock.Mock` attributes. Patch by Pablo Galindo. - -- bpo-17185: Set ``__signature__`` on mock for :mod:`inspect` to get - signature. Patch by Karthikeyan Singaravelan. - -- bpo-35445: Memory errors during creating posix.environ no longer ignored. - -- bpo-35415: Validate fileno= argument to socket.socket(). - -- bpo-35424: :class:`multiprocessing.Pool` destructor now emits - :exc:`ResourceWarning` if the pool is still running. - -- bpo-35330: When a :class:`Mock` instance was used to wrap an object, if - `side_effect` is used in one of the mocks of it methods, don't call the - original implementation and return the result of using the side effect the - same way that it is done with return_value. - -- bpo-35346: Drop Mac OS 9 and Rhapsody support from the :mod:`platform` - module. Rhapsody last release was in 2000. Mac OS 9 last release was in - 2001. - -- bpo-10496: :func:`~distutils.utils.check_environ` of - :mod:`distutils.utils` now catches :exc:`KeyError` on calling - :func:`pwd.getpwuid`: don't create the ``HOME`` environment variable in - this case. - -- bpo-10496: :func:`posixpath.expanduser` now returns the input *path* - unchanged if the ``HOME`` environment variable is not set and the current - user has no home directory (if the current user identifier doesn't exist - in the password database). This change fix the :mod:`site` module if the - current user doesn't exist in the password database (if the user has no - home directory). - -- bpo-35389: :func:`platform.libc_ver` now uses - ``os.confstr('CS_GNU_LIBC_VERSION')`` if available and the *executable* - parameter is not set. - -- bpo-35394: Add empty slots to asyncio abstract protocols. - -- bpo-35310: Fix a bug in :func:`select.select` where, in some cases, the - file descriptor sequences were returned unmodified after a signal - interruption, even though the file descriptors might not be ready yet. - :func:`select.select` will now always return empty lists if a timeout has - occurred. Patch by Oran Avraham. - -- bpo-35380: Enable TCP_NODELAY on Windows for proactor asyncio event loop. - -- bpo-35341: Add generic version of ``collections.OrderedDict`` to the - ``typing`` module. Patch by Ismo Toijala. - -- bpo-35371: Fixed possible crash in ``os.utime()`` on Windows when pass - incorrect arguments. - -- bpo-35346: :func:`platform.uname` now redirects ``stderr`` to - :data:`os.devnull` when running external programs like ``cmd /c ver``. - -- bpo-35066: Previously, calling the strftime() method on a datetime object - with a trailing '%' in the format string would result in an exception. - However, this only occurred when the datetime C module was being used; the - python implementation did not match this behavior. Datetime is now PEP-399 - compliant, and will not throw an exception on a trailing '%'. - -- bpo-35345: The function `platform.popen` has been removed, it was - deprecated since Python 3.3: use :func:`os.popen` instead. - -- bpo-35344: On macOS, :func:`platform.platform` now uses - :func:`platform.mac_ver`, if it returns a non-empty release string, to get - the macOS version rather than the darwin version. - -- bpo-35312: Make ``lib2to3.pgen2.parse.ParseError`` round-trip pickle-able. - Patch by Anthony Sottile. - -- bpo-35308: Fix regression in ``webbrowser`` where default browsers may be - preferred over browsers in the ``BROWSER`` environment variable. - -- bpo-24746: Avoid stripping trailing whitespace in doctest fancy diff. - Original patch by R. David Murray & Jairo Trad. Enhanced by Sanyam - Khurana. - -- bpo-28604: :func:`locale.localeconv` now sets temporarily the ``LC_CTYPE`` - locale to the ``LC_MONETARY`` locale if the two locales are different and - monetary strings are non-ASCII. This temporary change affects other - threads. - -- bpo-35277: Update ensurepip to install pip 18.1 and setuptools 40.6.2. - -- bpo-24209: Adds IPv6 support when invoking http.server directly. - -- bpo-35226: Recursively check arguments when testing for equality of - :class:`unittest.mock.call` objects and add note that tracking of - parameters used to create ancestors of mocks in ``mock_calls`` is not - possible. - -- bpo-29564: The warnings module now suggests to enable tracemalloc if the - source is specified, the tracemalloc module is available, but tracemalloc - is not tracing memory allocations. - -- bpo-35189: Modify the following fnctl function to retry if interrupted by - a signal (EINTR): flock, lockf, fnctl - -- bpo-30064: Use add_done_callback() in sock_* asyncio API to unsubscribe - reader/writer early on calcellation. - -- bpo-35186: Removed the "built with" comment added when ``setup.py upload`` - is used with either ``bdist_rpm`` or ``bdist_dumb``. - -- bpo-35152: Allow sending more than 2 GB at once on a multiprocessing - connection on non-Windows systems. - -- bpo-35062: Fix incorrect parsing of - :class:`_io.IncrementalNewlineDecoder`'s *translate* argument. - -- bpo-35065: Remove `StreamReaderProtocol._untrack_reader`. The call to - `_untrack_reader` is currently performed too soon, causing the protocol to - forget about the reader before `connection_lost` can run and feed the EOF - to the reader. - -- bpo-34160: ElementTree and minidom now preserve the attribute order - specified by the user. - -- bpo-35079: Improve difflib.SequenceManager.get_matching_blocks doc by - adding 'non-overlapping' and changing '!=' to '<'. - -- bpo-33710: Deprecated ``l*gettext()`` functions and methods in the - :mod:`gettext` module. They return encoded bytes instead of Unicode - strings and are artifacts from Python 2 times. Also deprecated functions - and methods related to setting the charset for ``l*gettext()`` functions - and methods. - -- bpo-35017: :meth:`socketserver.BaseServer.serve_forever` now exits - immediately if it's :meth:`~socketserver.BaseServer.shutdown` method is - called while it is polling for new events. - -- bpo-35024: `importlib` no longer logs `wrote <bytecode path>` redundantly - after `(created|could not create) <bytecode path>` is already logged. - Patch by Quentin Agren. - -- bpo-35047: ``unittest.mock`` now includes mock calls in exception messages - if ``assert_not_called``, ``assert_called_once``, or - ``assert_called_once_with`` fails. Patch by Petter Strandmark. - -- bpo-31047: Fix ``ntpath.abspath`` regression where it didn't remove a - trailing separator on Windows. Patch by Tim Graham. - -- bpo-35053: tracemalloc now tries to update the traceback when an object is - reused from a "free list" (optimization for faster object creation, used - by the builtin list type for example). - -- bpo-31553: Add the --json-lines option to json.tool. Patch by hongweipeng. - -- bpo-34794: Fixed a leak in Tkinter when pass the Python wrapper around - Tcl_Obj back to Tcl/Tk. - -- bpo-34909: Enum: fix grandchildren subclassing when parent mixed with - concrete data types. - -- bpo-35022: :class:`unittest.mock.MagicMock` now supports the - ``__fspath__`` method (from :class:`os.PathLike`). - -- bpo-35008: Fixed references leaks when call the ``__setstate__()`` method - of :class:`xml.etree.ElementTree.Element` in the C implementation for - already initialized element. - -- bpo-23420: Verify the value for the parameter '-s' of the cProfile CLI. - Patch by Robert Kuska - -- bpo-33947: dataclasses now handle recursive reprs without raising - RecursionError. - -- bpo-34890: Make :func:`inspect.iscoroutinefunction`, - :func:`inspect.isgeneratorfunction` and :func:`inspect.isasyncgenfunction` - work with :func:`functools.partial`. Patch by Pablo Galindo. - -- bpo-34521: Use :func:`socket.CMSG_SPACE` to calculate ancillary data size - instead of :func:`socket.CMSG_LEN` in - :func:`multiprocessing.reduction.recvfds` as :rfc:`3542` requires the use - of the former for portable applications. - -- bpo-31522: The `mailbox.mbox.get_string` function *from_* parameter can - now successfully be set to a non-default value. - -- bpo-34970: Protect tasks weak set manipulation in ``asyncio.all_tasks()`` - -- bpo-34969: gzip: Add --fast, --best on the gzip CLI, these parameters will - be used for the fast compression method (quick) or the best method - compress (slower, but smaller file). Also, change the default compression - level to 6 (tradeoff). - -- bpo-16965: The :term:`2to3` :2to3fixer:`execfile` fixer now opens the file - with mode ``'rb'``. Patch by Zackery Spytz. - -- bpo-34966: :mod:`pydoc` now supports aliases not only to methods defined - in the end class, but also to inherited methods. The docstring is not - duplicated for aliases. - -- bpo-34926: :meth:`mimetypes.MimeTypes.guess_type` now accepts - :term:`path-like object` in addition to url strings. Patch by Mayank - Asthana. - -- bpo-23831: Add ``moveto()`` method to the ``tkinter.Canvas`` widget. Patch - by Juliette Monsel. - -- bpo-34941: Methods ``find()``, ``findtext()`` and ``findall()`` of the - ``Element`` class in the :mod:`xml.etree.ElementTree` module are now able - to find children which are instances of ``Element`` subclasses. - -- bpo-32680: :class:`smtplib.SMTP` objects now always have a `sock` - attribute present - -- bpo-34769: Fix for async generators not finalizing when event loop is in - debug mode and garbage collector runs in another thread. - -- bpo-34936: Fix ``TclError`` in ``tkinter.Spinbox.selection_element()``. - Patch by Juliette Monsel. - -- bpo-34829: Add methods ``selection_from``, ``selection_range``, - ``selection_present`` and ``selection_to`` to the ``tkinter.Spinbox`` for - consistency with the ``tkinter.Entry`` widget. Patch by Juliette Monsel. - -- bpo-34911: Added *secure_protocols* argument to - *http.cookiejar.DefaultCookiePolicy* to allow for tweaking of protocols - and also to add support by default for *wss*, the secure websocket - protocol. - -- bpo-34922: Fixed integer overflow in the :meth:`~hashlib.shake.digest()` - and :meth:`~hashlib.shake.hexdigest()` methods for the SHAKE algorithm in - the :mod:`hashlib` module. - -- bpo-34925: 25% speedup in argument parsing for the functions in the bisect - module. - -- bpo-34900: Fixed :meth:`unittest.TestCase.debug` when used to call test - methods with subtests. Patch by Bruno Oliveira. - -- bpo-34844: logging.Formatter enhancement - Ensure styles and fmt matches - in logging.Formatter - Added validate method in each format style class: - StrFormatStyle, PercentStyle, StringTemplateStyle. - This method is called - in the constructor of logging.Formatter class - Also re-raise the KeyError - in the format method of each style class, so it would a bit clear that - it's an error with the invalid format fields. - -- bpo-34897: Adjust test.support.missing_compiler_executable check so that a - nominal command name of "" is ignored. Patch by Michael Felt. - -- bpo-34871: Fix inspect module polluted ``sys.modules`` when parsing - ``__text_signature__`` of callable. - -- bpo-34898: Add `mtime` argument to `gzip.compress` for reproducible - output. Patch by Guo Ci Teo. - -- bpo-28441: On Cygwin and MinGW, ensure that ``sys.executable`` always - includes the full filename in the path, including the ``.exe`` suffix - (unless it is a symbolic link). - -- bpo-34866: Adding ``max_num_fields`` to ``cgi.FieldStorage`` to make DOS - attacks harder by limiting the number of ``MiniFieldStorage`` objects - created by ``FieldStorage``. - -- bpo-34711: http.server ensures it reports HTTPStatus.NOT_FOUND when the - local path ends with "/" and is not a directory, even if the underlying OS - (e.g. AIX) accepts such paths as a valid file reference. Patch by Michael - Felt. - -- bpo-34872: Fix self-cancellation in C implementation of asyncio.Task - -- bpo-34849: Don't log waiting for ``selector.select`` in asyncio loop - iteration. The waiting is pretty normal for any asyncio program, logging - its time just adds a noise to logs without any useful information - provided. - -- bpo-34022: The :envvar:`SOURCE_DATE_EPOCH` environment variable no longer - overrides the value of the *invalidation_mode* argument to - :func:`py_compile.compile`, and determines its default value instead. - -- bpo-34819: Use a monotonic clock to compute timeouts in - :meth:`Executor.map` and :func:`as_completed`, in order to prevent - timeouts from deviating when the system clock is adjusted. - -- bpo-34758: Add .wasm -> application/wasm to list of recognized file types - and content type headers - -- bpo-34789: :func:`xml.sax.make_parser` now accepts any iterable as its - *parser_list* argument. Patch by Andrés Delfino. - -- bpo-34334: In :class:`QueueHandler`, clear `exc_text` from - :class:`LogRecord` to prevent traceback from being written twice. - -- bpo-34687: On Windows, asyncio now uses ProactorEventLoop, instead of - SelectorEventLoop, by default. - -- bpo-5950: Support reading zip files with archive comments in - :mod:`zipimport`. - -- bpo-32892: The parser now represents all constants as - :class:`ast.Constant` instead of using specific constant AST types - (``Num``, ``Str``, ``Bytes``, ``NameConstant`` and ``Ellipsis``). These - classes are considered deprecated and will be removed in future Python - versions. - -- bpo-34728: Add deprecation warning when `loop` is used in methods: - `asyncio.sleep`, `asyncio.wait` and `asyncio.wait_for`. - -- bpo-34738: ZIP files created by :mod:`distutils` will now include entries - for directories. - -- bpo-34659: Add an optional *initial* argument to itertools.accumulate(). - -- bpo-29577: Support multiple mixin classes when creating Enums. - -- bpo-34670: Add SSLContext.post_handshake_auth and - SSLSocket.verify_client_post_handshake for TLS 1.3's post handshake - authentication feature. - -- bpo-32718: The Activate.ps1 script from venv works with PowerShell Core - 6.1 and is now available under all operating systems. - -- bpo-31177: Fix bug that prevented using :meth:`reset_mock - <unittest.mock.Mock.reset_mock>` on mock instances with deleted attributes - -- bpo-34672: Add a workaround, so the ``'Z'`` :func:`time.strftime` - specifier on the musl C library can work in some cases. - -- bpo-34666: Implement ``asyncio.StreamWriter.awrite`` and - ``asyncio.StreamWriter.aclose()`` coroutines. Methods are needed for - providing a consistent stream API with control flow switched on by - default. - -- bpo-6721: Acquire the logging module's commonly used internal locks while - fork()ing to avoid deadlocks in the child process. - -- bpo-34658: Fix a rare interpreter unhandled exception state SystemError - only seen when using subprocess with a preexec_fn while an after_parent - handler has been registered with os.register_at_fork and the fork system - call fails. - -- bpo-34652: Ensure :func:`os.lchmod` is never defined on Linux. - -- bpo-34638: Store a weak reference to stream reader to break strong - references loop between reader and protocol. It allows to detect and - close the socket if the stream is deleted (garbage collected) without - ``close()`` call. - -- bpo-34536: `Enum._missing_`: raise `ValueError` if None returned and - `TypeError` if non-member is returned. - -- bpo-34636: Speed up re scanning of many non-matching characters for \s \w - and \d within bytes objects. (microoptimization) - -- bpo-24412: Add :func:`~unittest.addModuleCleanup()` and - :meth:`~unittest.TestCase.addClassCleanup()` to unittest to support - cleanups for :func:`~unittest.setUpModule()` and - :meth:`~unittest.TestCase.setUpClass()`. Patch by Lisa Roach. - -- bpo-34630: Don't log SSL certificate errors in asyncio code (connection - error logging is skipped already). - -- bpo-32490: Prevent filename duplication in :mod:`subprocess` exception - messages. Patch by Zackery Spytz. - -- bpo-34363: dataclasses.asdict() and .astuple() now handle namedtuples - correctly. - -- bpo-34625: Update vendorized expat library version to 2.2.6. - -- bpo-32270: The subprocess module no longer mistakenly closes redirected - fds even when they were in pass_fds when outside of the default {0, 1, 2} - set. - -- bpo-34622: Create a dedicated ``asyncio.CancelledError``, - ``asyncio.InvalidStateError`` and ``asyncio.TimeoutError`` exception - classes. Inherit them from corresponding exceptions from - ``concurrent.futures`` package. Extract ``asyncio`` exceptions into a - separate file. - -- bpo-34610: Fixed iterator of :class:`multiprocessing.managers.DictProxy`. - -- bpo-34421: Fix distutils logging for non-ASCII strings. This caused - installation issues on Windows. - -- bpo-34604: Fix possible mojibake in the error message of `pwd.getpwnam` - and `grp.getgrnam` using string representation because of invisible - characters or trailing whitespaces. Patch by William Grzybowski. - -- bpo-30977: Make uuid.UUID use ``__slots__`` to reduce its memory - footprint. Based on original patch by Wouter Bolsterlee. - -- bpo-34574: OrderedDict iterators are not exhausted during pickling - anymore. Patch by Sergey Fedoseev. - -- bpo-8110: Refactored :mod:`subprocess` to check for Windows-specific - modules rather than ``sys.platform == 'win32'``. - -- bpo-34530: ``distutils.spawn.find_executable()`` now falls back on - :data:`os.defpath` if the ``PATH`` environment variable is not set. - -- bpo-34563: On Windows, fix multiprocessing.Connection for very large read: - fix _winapi.PeekNamedPipe() and _winapi.ReadFile() for read larger than - INT_MAX (usually ``2**31-1``). - -- bpo-34558: Correct typo in Lib/ctypes/_aix.py - -- bpo-34282: Move ``Enum._convert`` to ``EnumMeta._convert_`` and fix enum - members getting shadowed by parent attributes. - -- bpo-22872: When the queue is closed, :exc:`ValueError` is now raised by - :meth:`multiprocessing.Queue.put` and :meth:`multiprocessing.Queue.get` - instead of :exc:`AssertionError` and :exc:`OSError`, respectively. Patch - by Zackery Spytz. - -- bpo-34515: Fix parsing non-ASCII identifiers in - :mod:`lib2to3.pgen2.tokenize` (PEP 3131). - -- bpo-13312: Avoids a possible integer underflow (undefined behavior) in the - time module's year handling code when passed a very low negative year - value. - -- bpo-34472: Improved compatibility for streamed files in :mod:`zipfile`. - Previously an optional signature was not being written and certain ZIP - applications were not supported. Patch by Silas Sewell. - -- bpo-34454: Fix the .fromisoformat() methods of datetime types crashing - when given unicode with non-UTF-8-encodable code points. Specifically, - datetime.fromisoformat() now accepts surrogate unicode code points used as - the separator. Report and tests by Alexey Izbyshev, patch by Paul Ganssle. - -- bpo-6700: Fix inspect.getsourcelines for module level frames/tracebacks. - Patch by Vladimir Matveev. - -- bpo-34171: Running the :mod:`trace` module no longer creates the - ``trace.cover`` file. - -- bpo-34441: Fix crash when an ``ABC``-derived class with invalid - ``__subclasses__`` is passed as the second argument to - :func:`issubclass()`. Patch by Alexey Izbyshev. - -- bpo-34427: Fix infinite loop in ``a.extend(a)`` for ``MutableSequence`` - subclasses. - -- bpo-34412: Make :func:`signal.strsignal` work on HP-UX. Patch by Michael - Osipov. - -- bpo-20849: shutil.copytree now accepts a new ``dirs_exist_ok`` keyword - argument. Patch by Josh Bronson. - -- bpo-31715: Associate ``.mjs`` file extension with - ``application/javascript`` MIME Type. - -- bpo-34384: :func:`os.readlink` now accepts :term:`path-like <path-like - object>` and :class:`bytes` objects on Windows. - -- bpo-22602: The UTF-7 decoder now raises :exc:`UnicodeDecodeError` for - ill-formed sequences starting with "+" (as specified in RFC 2152). Patch - by Zackery Spytz. - -- bpo-2122: The :meth:`mmap.flush() <mmap.mmap.flush>` method now returns - ``None`` on success, raises an exception on error under all platforms. - -- bpo-34341: Appending to the ZIP archive with the ZIP64 extension no longer - grows the size of extra fields of existing entries. - -- bpo-34333: Fix %-formatting in :meth:`pathlib.PurePath.with_suffix` when - formatting an error message. - -- bpo-18540: The :class:`imaplib.IMAP4` and :class:`imaplib.IMAP4_SSL` - classes now resolve to the local host IP correctly when the default value - of *host* parameter (``''``) is used. - -- bpo-26502: Implement ``traceback.FrameSummary.__len__()`` method to - preserve compatibility with the old tuple API. - -- bpo-34318: :func:`~unittest.TestCase.assertRaises`, - :func:`~unittest.TestCase.assertRaisesRegex`, - :func:`~unittest.TestCase.assertWarns` and - :func:`~unittest.TestCase.assertWarnsRegex` no longer success if the - passed callable is None. They no longer ignore unknown keyword arguments - in the context manager mode. A DeprecationWarning was raised in these - cases since Python 3.5. - -- bpo-9372: Deprecate :meth:`__getitem__` methods of - :class:`xml.dom.pulldom.DOMEventStream`, :class:`wsgiref.util.FileWrapper` - and :class:`fileinput.FileInput`. - -- bpo-33613: Fix a race condition in ``multiprocessing.semaphore_tracker`` - when the tracker receives SIGINT before it can register signal handlers - for ignoring it. - -- bpo-34248: Report filename in the exception raised when the database file - cannot be opened by :func:`dbm.gnu.open` and :func:`dbm.ndbm.open` due to - OS-related error. Patch by Zsolt Cserna. - -- bpo-33089: Add math.dist() to compute the Euclidean distance between two - points. - -- bpo-34246: :meth:`smtplib.SMTP.send_message` no longer modifies the - content of the *mail_options* argument. Patch by Pablo S. Blum de Aguiar. - -- bpo-31047: Fix ``ntpath.abspath`` for invalid paths on windows. Patch by - Franz Woellert. - -- bpo-32321: Add pure Python fallback for functools.reduce. Patch by Robert - Wright. - -- bpo-34270: The default asyncio task class now always has a name which can - be get or set using two new methods (:meth:`~asyncio.Task.get_name()` and - :meth:`~asyncio.Task.set_name`) and is visible in the :func:`repr` output. - An initial name can also be set using the new ``name`` keyword argument to - :func:`asyncio.create_task` or the - :meth:`~asyncio.AbstractEventLoop.create_task` method of the event loop. - If no initial name is set, the default Task implementation generates a - name like ``Task-1`` using a monotonic counter. - -- bpo-34263: asyncio's event loop will not pass timeouts longer than one day - to epoll/select etc. - -- bpo-34035: Fix several AttributeError in zipfile seek() methods. Patch by - Mickaël Schoentgen. - -- bpo-32215: Fix performance regression in :mod:`sqlite3` when a DML - statement appeared in a different line than the rest of the SQL query. - -- bpo-34075: Deprecate passing non-ThreadPoolExecutor instances to - :meth:`AbstractEventLoop.set_default_executor`. - -- bpo-34251: Restore ``msilib.Win64`` to preserve backwards compatibility - since it's already used by :mod:`distutils`' ``bdist_msi`` command. - -- bpo-19891: Ignore errors caused by missing / non-writable homedir while - writing history during exit of an interactive session. Patch by Anthony - Sottile. - -- bpo-33089: Enhanced math.hypot() to support more than two dimensions. - -- bpo-34228: tracemalloc: PYTHONTRACEMALLOC=0 environment variable and -X - tracemalloc=0 command line option are now allowed to disable explicitly - tracemalloc at startup. - -- bpo-13041: Use :func:`shutil.get_terminal_size` to calculate the terminal - width correctly in the ``argparse.HelpFormatter`` class. Initial patch by - Zbyszek Jędrzejewski-Szmek. - -- bpo-34213: Allow frozen dataclasses to have a field named "object". - Previously this conflicted with an internal use of "object". - -- bpo-34052: :meth:`sqlite3.Connection.create_aggregate`, - :meth:`sqlite3.Connection.create_function`, - :meth:`sqlite3.Connection.set_authorizer`, - :meth:`sqlite3.Connection.set_progress_handler` methods raises TypeError - when unhashable objects are passed as callable. These methods now don't - pass such objects to SQLite API. Previous behavior could lead to - segfaults. Patch by Sergey Fedoseev. - -- bpo-34197: Attributes *skipinitialspace*, *doublequote* and *strict* of - the *dialect* attribute of the :mod:`csv` reader are now :class:`bool` - instances instead of integers 0 or 1. - -- bpo-32788: Errors other than :exc:`TypeError` raised in methods - ``__adapt__()`` and ``__conform__()`` in the :mod:`sqlite3` module are now - propagated to the user. - -- bpo-21446: The :2to3fixer:`reload` fixer now uses :func:`importlib.reload` - instead of deprecated :func:`imp.reload`. - -- bpo-940286: pydoc's ``Helper.showtopic()`` method now prints the cross - references of a topic correctly. - -- bpo-34164: :func:`base64.b32decode` could raise UnboundLocalError or - OverflowError for incorrect padding. Now it always raises - :exc:`base64.Error` in these cases. - -- bpo-33729: Fixed issues with arguments parsing in :mod:`hashlib`. - -- bpo-34097: ZipFile can zip files older than 1980-01-01 and newer than - 2107-12-31 using a new ``strict_timestamps`` parameter at the cost of - setting the timestamp to the limit. - -- bpo-34108: Remove extraneous CR in 2to3 refactor. - -- bpo-34070: Make sure to only check if the handle is a tty, when opening a - file with ``buffering=-1``. - -- bpo-27494: Reverted :issue:`27494`. 2to3 rejects now a trailing comma in - generator expressions. - -- bpo-33967: functools.singledispatch now raises TypeError instead of - IndexError when no positional arguments are passed. - -- bpo-34041: Add the parameter *deterministic* to the - :meth:`sqlite3.Connection.create_function` method. Patch by Sergey - Fedoseev. - -- bpo-34056: Ensure the loader shim created by ``imp.load_module`` always - returns bytes from its ``get_data()`` function. This fixes using - ``imp.load_module`` with :pep:`552` hash-based pycs. - -- bpo-34054: The multiprocessing module now uses the monotonic clock - :func:`time.monotonic` instead of the system clock :func:`time.time` to - implement timeout. - -- bpo-34043: Optimize tarfile uncompress performance about 15% when gzip is - used. - -- bpo-34044: ``subprocess.Popen`` now copies the *startupinfo* argument to - leave it unchanged: it will modify the copy, so that the same - ``STARTUPINFO`` object can be used multiple times. - -- bpo-34010: Fixed a performance regression for reading streams with - tarfile. The buffered read should use a list, instead of appending to a - bytes object. - -- bpo-34019: webbrowser: Correct the arguments passed to Opera Browser when - opening a new URL using the ``webbrowser`` module. Patch by Bumsik Kim. - -- bpo-34003: csv.DictReader now creates dicts instead of OrderedDicts. Patch - by Michael Selik. - -- bpo-33978: Closed existing logging handlers before reconfiguration via - fileConfig and dictConfig. Patch by Karthikeyan Singaravelan. - -- bpo-14117: Make minor tweaks to turtledemo. The 'wikipedia' example is now - 'rosette', describing what it draws. The 'penrose' print output is - reduced. The'1024' output of 'tree' is eliminated. - -- bpo-33974: Fixed passing lists and tuples of strings containing special - characters ``"``, ``\``, ``{``, ``}`` and ``\n`` as options to - :mod:`~tkinter.ttk` widgets. - -- bpo-27500: Fix getaddrinfo to resolve IPv6 addresses correctly. - -- bpo-24567: Improve random.choices() to handle subnormal input weights that - could occasionally trigger an IndexError. - -- bpo-33871: Fixed integer overflow in :func:`os.readv`, :func:`os.writev`, - :func:`os.preadv` and :func:`os.pwritev` and in :func:`os.sendfile` with - *headers* or *trailers* arguments (on BSD-based OSes and macOS). - -- bpo-25007: Add :func:`copy.copy` and :func:`copy.deepcopy` support to zlib - compressors and decompressors. Patch by Zackery Spytz. - -- bpo-33929: multiprocessing: Fix a race condition in Popen of - multiprocessing.popen_spawn_win32. The child process now duplicates the - read end of pipe instead of "stealing" it. Previously, the read end of - pipe was "stolen" by the child process, but it leaked a handle if the - child process had been terminated before it could steal the handle from - the parent process. - -- bpo-33899: Tokenize module now implicitly emits a NEWLINE when provided - with input that does not have a trailing new line. This behavior now - matches what the C tokenizer does internally. Contributed by Ammar Askar. - -- bpo-33897: Added a 'force' keyword argument to logging.basicConfig(). - -- bpo-33695: :func:`shutil.copytree` uses :func:`os.scandir` function and - all copy functions depending from it use cached :func:`os.stat` values. - The speedup for copying a directory with 8000 files is around +9% on - Linux, +20% on Windows and + 30% on a Windows SMB share. Also the number - of :func:`os.stat` syscalls is reduced by 38% making - :func:`shutil.copytree` especially faster on network filesystems. - (Contributed by Giampaolo Rodola' in :issue:`33695`.) - -- bpo-33916: bz2 and lzma: When Decompressor.__init__() is called twice, - free the old lock to not leak memory. - -- bpo-32568: Make select.epoll() and its documentation consistent regarding - *sizehint* and *flags*. - -- bpo-33833: Fixed bug in asyncio where ProactorSocketTransport logs - AssertionError if force closed during write. - -- bpo-33663: Convert content length to string before putting to header. - -- bpo-33721: :mod:`os.path` functions that return a boolean result like - :func:`~os.path.exists`, :func:`~os.path.lexists`, :func:`~os.path.isdir`, - :func:`~os.path.isfile`, :func:`~os.path.islink`, and - :func:`~os.path.ismount`, and :mod:`pathlib.Path` methods that return a - boolean result like :meth:`~pathlib.Path.exists()`, - :meth:`~pathlib.Path.is_dir()`, :meth:`~pathlib.Path.is_file()`, - :meth:`~pathlib.Path.is_mount()`, :meth:`~pathlib.Path.is_symlink()`, - :meth:`~pathlib.Path.is_block_device()`, - :meth:`~pathlib.Path.is_char_device()`, :meth:`~pathlib.Path.is_fifo()`, - :meth:`~pathlib.Path.is_socket()` now return ``False`` instead of raising - :exc:`ValueError` or its subclasses :exc:`UnicodeEncodeError` and - :exc:`UnicodeDecodeError` for paths that contain characters or bytes - unrepresentable at the OS level. - -- bpo-26544: Fixed implementation of :func:`platform.libc_ver`. It almost - always returned version '2.9' for glibc. - -- bpo-33843: Remove deprecated ``cgi.escape``, ``cgi.parse_qs`` and - ``cgi.parse_qsl``. - -- bpo-33842: Remove ``tarfile.filemode`` which is deprecated since Python - 3.3. - -- bpo-30167: Prevent site.main() exception if PYTHONSTARTUP is set. Patch by - Steve Weber. - -- bpo-33805: Improve error message of dataclasses.replace() when an InitVar - is not specified - -- bpo-33687: Fix the call to ``os.chmod()`` for ``uu.decode()`` if a mode is - given or decoded. Patch by Timo Furrer. - -- bpo-33812: Datetime instance d with non-None tzinfo, but with - d.tzinfo.utcoffset(d) returning None is now treated as naive by the - astimezone() method. - -- bpo-32108: In configparser, don't clear section when it is assigned to - itself. - -- bpo-27397: Make email module properly handle invalid-length base64 - strings. - -- bpo-33578: Implement multibyte encoder/decoder state methods - -- bpo-30805: Avoid race condition with debug logging - -- bpo-33476: Fix _header_value_parser.py when address group is missing final - ';'. Contributed by Enrique Perez-Terron - -- bpo-33694: asyncio: Fix a race condition causing data loss on - pause_reading()/resume_reading() when using the ProactorEventLoop. - -- bpo-32493: Correct test for ``uuid_enc_be`` availability in - ``configure.ac``. Patch by Michael Felt. - -- bpo-33792: Add asyncio.WindowsSelectorEventLoopPolicy and - asyncio.WindowsProactorEventLoopPolicy. - -- bpo-33274: W3C DOM Level 1 specifies return value of - Element.removeAttributeNode() as "The Attr node that was removed." - xml.dom.minidom now complies with this requirement. - -- bpo-33778: Update ``unicodedata``'s database to Unicode version 11.0.0. - -- bpo-33165: Added a stacklevel parameter to logging calls to allow use of - wrapper/helper functions for logging APIs. - -- bpo-33770: improve base64 exception message for encoded inputs of invalid - length - -- bpo-33769: asyncio/start_tls: Fix error message; cancel callbacks in case - of an unhandled error; mark SSLTransport as closed if it is aborted. - -- bpo-33767: The concatenation (``+``) and repetition (``*``) sequence - operations now raise :exc:`TypeError` instead of :exc:`SystemError` when - performed on :class:`mmap.mmap` objects. Patch by Zackery Spytz. - -- bpo-33734: asyncio/ssl: Fix AttributeError, increase default handshake - timeout - -- bpo-31014: Fixed creating a controller for :mod:`webbrowser` when a user - specifies a path to an entry in the BROWSER environment variable. Based - on patch by John Still. - -- bpo-2504: Add gettext.pgettext() and variants. - -- bpo-33197: Add description property for _ParameterKind - -- bpo-32751: When cancelling the task due to a timeout, - :meth:`asyncio.wait_for` will now wait until the cancellation is complete. - -- bpo-32684: Fix gather to propagate cancellation of itself even with - return_exceptions. - -- bpo-33654: Support protocol type switching in SSLTransport.set_protocol(). - -- bpo-33674: Pause the transport as early as possible to further reduce the - risk of data_received() being called before connection_made(). - -- bpo-33671: :func:`shutil.copyfile`, :func:`shutil.copy`, - :func:`shutil.copy2`, :func:`shutil.copytree` and :func:`shutil.move` use - platform-specific fast-copy syscalls on Linux and macOS in order to copy - the file more efficiently. On Windows :func:`shutil.copyfile` uses a - bigger default buffer size (1 MiB instead of 16 KiB) and a - :func:`memoryview`-based variant of :func:`shutil.copyfileobj` is used. - The speedup for copying a 512MiB file is about +26% on Linux, +50% on - macOS and +40% on Windows. Also, much less CPU cycles are consumed. - (Contributed by Giampaolo Rodola' in :issue:`25427`.) - -- bpo-33674: Fix a race condition in SSLProtocol.connection_made() of - asyncio.sslproto: start immediately the handshake instead of using - call_soon(). Previously, data_received() could be called before the - handshake started, causing the handshake to hang or fail. - -- bpo-31647: Fixed bug where calling write_eof() on a - _SelectorSocketTransport after it's already closed raises AttributeError. - -- bpo-32610: Make asyncio.all_tasks() return only pending tasks. - -- bpo-32410: Avoid blocking on file IO in sendfile fallback code - -- bpo-33469: Fix RuntimeError after closing loop that used run_in_executor - -- bpo-33672: Fix Task.__repr__ crash with Cython's bogus coroutines - -- bpo-33654: Fix transport.set_protocol() to support switching between - asyncio.Protocol and asyncio.BufferedProtocol. Fix loop.start_tls() to - work with asyncio.BufferedProtocols. - -- bpo-33652: Pickles of type variables and subscripted generics are now - future-proof and compatible with older Python versions. - -- bpo-32493: Fixed :func:`uuid.uuid1` on FreeBSD. - -- bpo-33238: Add ``InvalidStateError`` to :mod:`concurrent.futures`. - ``Future.set_result`` and ``Future.set_exception`` now raise - ``InvalidStateError`` if the futures are not pending or running. Patch by - Jason Haydaman. - -- bpo-33618: Finalize and document preliminary and experimental TLS 1.3 - support with OpenSSL 1.1.1 - -- bpo-33625: Release GIL on `grp.getgrnam`, `grp.getgrgid`, `pwd.getpwnam` - and `pwd.getpwuid` if reentrant variants of these functions are available. - Patch by William Grzybowski. - -- bpo-33623: Fix possible SIGSGV when asyncio.Future is created in __del__ - -- bpo-11874: Use a better regex when breaking usage into wrappable parts. - Avoids bogus assertion errors from custom metavar strings. - -- bpo-30877: Fixed a bug in the Python implementation of the JSON decoder - that prevented the cache of parsed strings from clearing after finishing - the decoding. Based on patch by c-fos. - -- bpo-33604: Remove HMAC default to md5 marked for removal in 3.8 (removal - originally planned in 3.6, bump to 3.8 in PR 7062). - -- bpo-33582: Emit a deprecation warning for inspect.formatargspec - -- bpo-21145: Add ``functools.cached_property`` decorator, for computed - properties cached for the life of the instance. - -- bpo-33570: Change TLS 1.3 cipher suite settings for compatibility with - OpenSSL 1.1.1-pre6 and newer. OpenSSL 1.1.1 will have TLS 1.3 ciphers - enabled by default. - -- bpo-28556: Do not simplify arguments to `typing.Union`. Now - `Union[Manager, Employee]` is not simplified to `Employee` at runtime. - Such simplification previously caused several bugs and limited - possibilities for introspection. - -- bpo-12486: :func:`tokenize.generate_tokens` is now documented as a public - API to tokenize unicode strings. It was previously present but - undocumented. - -- bpo-33540: Add a new ``block_on_close`` class attribute to - ``ForkingMixIn`` and ``ThreadingMixIn`` classes of :mod:`socketserver`. - -- bpo-33548: tempfile._candidate_tempdir_list should consider common TEMP - locations - -- bpo-33109: argparse subparsers are once again not required by default, - reverting the change in behavior introduced by bpo-26510 in 3.7.0a2. - -- bpo-33541: Remove unused private method ``_strptime.LocaleTime.__pad`` - (a.k.a. ``_LocaleTime__pad``). - -- bpo-33536: dataclasses.make_dataclass now checks for invalid field names - and duplicate fields. Also, added a check for invalid field - specifications. - -- bpo-33542: Prevent ``uuid.get_node`` from using a DUID instead of a MAC on - Windows. Patch by Zvi Effron - -- bpo-26819: Fix race condition with `ReadTransport.resume_reading` in - Windows proactor event loop. - -- Fix failure in `typing.get_type_hints()` when ClassVar was provided as a - string forward reference. - -- bpo-33516: :class:`unittest.mock.MagicMock` now supports the ``__round__`` - magic method. - -- bpo-28612: Added support for Site Maps to urllib's ``RobotFileParser`` as - :meth:`RobotFileParser.site_maps() - <urllib.robotparser.RobotFileParser.site_maps>`. Patch by Lady Red, based - on patch by Peter Wirtz. - -- bpo-28167: Remove platform.linux_distribution, which was deprecated since - 3.5. - -- bpo-33504: Switch the default dictionary implementation for - :mod:`configparser` from :class:`collections.OrderedDict` to the standard - :class:`dict` type. - -- bpo-33505: Optimize asyncio.ensure_future() by reordering if checks: 1.17x - faster. - -- bpo-33497: Add errors param to cgi.parse_multipart and make an encoding in - FieldStorage use the given errors (needed for Twisted). Patch by Amber - Brown. - -- bpo-29235: The :class:`cProfile.Profile` class can now be used as a - context manager. Patch by Scott Sanderson. - -- bpo-33495: Change dataclasses.Fields repr to use the repr of each of its - members, instead of str. This makes it more clear what each field - actually represents. This is especially true for the 'type' member. - -- bpo-26103: Correct ``inspect.isdatadescriptor`` to look for ``__set__`` or - ``__delete__``. Patch by Aaron Hall. - -- bpo-29209: Removed the ``doctype()`` method and the *html* parameter of - the constructor of :class:`~xml.etree.ElementTree.XMLParser`. The - ``doctype()`` method defined in a subclass will no longer be called. - Deprecated methods ``getchildren()`` and ``getiterator()`` in the - :mod:`~xml.etree.ElementTree` module emit now a :exc:`DeprecationWarning` - instead of :exc:`PendingDeprecationWarning`. - -- bpo-33453: Fix dataclasses to work if using literal string type - annotations or if using PEP 563 "Postponed Evaluation of Annotations". - Only specific string prefixes are detected for both ClassVar ("ClassVar" - and "typing.ClassVar") and InitVar ("InitVar" and "dataclasses.InitVar"). - -- bpo-28556: Minor fixes in typing module: add annotations to - ``NamedTuple.__new__``, pass ``*args`` and ``**kwds`` in - ``Generic.__new__``. Original PRs by Paulius Šarka and Chad Dombrova. - -- bpo-33365: Print the header values besides the header keys instead just - the header keys if *debuglevel* is set to >0 in :mod:`http.client`. Patch - by Marco Strigl. - -- bpo-20087: Updated alias mapping with glibc 2.27 supported locales. - -- bpo-33422: Fix trailing quotation marks getting deleted when looking up - byte/string literals on pydoc. Patch by Andrés Delfino. - -- bpo-28167: The function ``platform.linux_distribution`` and - ``platform.dist`` now trigger a ``DeprecationWarning`` and have been - marked for removal in Python 3.8 - -- bpo-33281: Fix ctypes.util.find_library regression on macOS. - -- bpo-33311: Text and html output generated by cgitb does not display - parentheses if the current call is done directly in the module. Patch by - Stéphane Blondon. - -- bpo-27300: The file classes in *tempfile* now accept an *errors* parameter - that complements the already existing *encoding*. Patch by Stephan Hohe. - -- bpo-32933: :func:`unittest.mock.mock_open` now supports iteration over the - file contents. Patch by Tony Flury. - -- bpo-33217: Raise :exc:`TypeError` when looking up non-Enum objects in Enum - classes and Enum members. - -- bpo-33197: Update error message when constructing invalid - inspect.Parameters Patch by Dong-hee Na. - -- bpo-33383: Fixed crash in the get() method of the :mod:`dbm.ndbm` database - object when it is called with a single argument. - -- bpo-33375: The warnings module now finds the Python file associated with a - warning from the code object, rather than the frame's global namespace. - This is consistent with how tracebacks and pdb find filenames, and should - work better for dynamically executed code. - -- bpo-33336: ``imaplib`` now allows ``MOVE`` command in ``IMAP4.uid()`` (RFC - 6851: IMAP MOVE Extension) and potentially as a name of supported method - of ``IMAP4`` object. - -- bpo-32455: Added *jump* parameter to :func:`dis.stack_effect`. - -- bpo-27485: Rename and deprecate undocumented functions in - :func:`urllib.parse`. - -- bpo-33332: Add ``signal.valid_signals()`` to expose the POSIX sigfillset() - functionality. - -- bpo-33251: `ConfigParser.items()` was fixed so that key-value pairs passed - in via `vars` are not included in the resulting output. - -- bpo-33329: Fix multiprocessing regression on newer glibcs - -- bpo-33334: :func:`dis.stack_effect` now supports all defined opcodes - including NOP and EXTENDED_ARG. - -- bpo-991266: Fix quoting of the ``Comment`` attribute of - :class:`http.cookies.SimpleCookie`. - -- bpo-33131: Upgrade bundled version of pip to 10.0.1. - -- bpo-33308: Fixed a crash in the :mod:`parser` module when converting an ST - object to a tree of tuples or lists with ``line_info=False`` and - ``col_info=True``. - -- bpo-23403: lib2to3 now uses pickle protocol 4 for pre-computed grammars. - -- bpo-33266: lib2to3 now recognizes ``rf'...'`` strings. - -- bpo-11594: Ensure line-endings are respected when using lib2to3. - -- bpo-33254: Have :func:`importlib.resources.contents` and - :meth:`importlib.abc.ResourceReader.contents` return an :term:`iterable` - instead of an :term:`iterator`. - -- bpo-33265: ``contextlib.ExitStack`` and ``contextlib.AsyncExitStack`` now - use a method instead of a wrapper function for exit callbacks. - -- bpo-33263: Fix FD leak in `_SelectorSocketTransport` Patch by Vlad - Starostin. - -- bpo-33256: Fix display of ``<module>`` call in the html produced by - ``cgitb.html()``. Patch by Stéphane Blondon. - -- bpo-33144: ``random.Random()`` and its subclassing mechanism got optimized - to check only once at class/subclass instantiation time whether its - ``getrandbits()`` method can be relied on by other methods, including - ``randrange()``, for the generation of arbitrarily large random integers. - Patch by Wolfgang Maier. - -- bpo-33185: Fixed regression when running pydoc with the :option:`-m` - switch. (The regression was introduced in 3.7.0b3 by the resolution of - :issue:`33053`) - - This fix also changed pydoc to add ``os.getcwd()`` to :data:`sys.path` - when necessary, rather than adding ``"."``. - -- bpo-29613: Added support for the ``SameSite`` cookie flag to the - ``http.cookies`` module. - -- bpo-33169: Delete entries of ``None`` in :data:`sys.path_importer_cache` - when :meth:`importlib.machinery.invalidate_caches` is called. - -- bpo-33203: ``random.Random.choice()`` now raises ``IndexError`` for empty - sequences consistently even when called from subclasses without a - ``getrandbits()`` implementation. - -- bpo-33224: Update difflib.mdiff() for :pep:`479`. Convert an uncaught - StopIteration in a generator into a return-statement. - -- bpo-33209: End framing at the end of C implementation of - :func:`pickle.Pickler.dump`. - -- bpo-32861: The urllib.robotparser's ``__str__`` representation now - includes wildcard entries and the "Crawl-delay" and "Request-rate" fields. - Also removes extra newlines that were being appended to the end of the - string. Patch by Michael Lazar. - -- bpo-23403: ``DEFAULT_PROTOCOL`` in :mod:`pickle` was bumped to 4. Protocol - 4 is described in :pep:`3154` and available since Python 3.4. It offers - better performance and smaller size compared to protocol 3 introduced in - Python 3.0. - -- bpo-20104: Improved error handling and fixed a reference leak in - :func:`os.posix_spawn()`. - -- bpo-33106: Deleting a key from a read-only dbm database raises module - specific error instead of KeyError. - -- bpo-33175: In dataclasses, Field.__set_name__ now looks up the - __set_name__ special method on the class, not the instance, of the default - value. - -- bpo-32380: Create functools.singledispatchmethod to support generic single - dispatch on descriptors and methods. - -- bpo-33141: Have Field objects pass through __set_name__ to their default - values, if they have their own __set_name__. - -- bpo-33096: Allow ttk.Treeview.insert to insert iid that has a false - boolean value. Note iid=0 and iid=False would be same. Patch by Garvit - Khatri. - -- bpo-32873: Treat type variables and special typing forms as immutable by - copy and pickle. This fixes several minor issues and inconsistencies, and - improves backwards compatibility with Python 3.6. - -- bpo-33134: When computing dataclass's __hash__, use the lookup table to - contain the function which returns the __hash__ value. This is an - improvement over looking up a string, and then testing that string to see - what to do. - -- bpo-33127: The ssl module now compiles with LibreSSL 2.7.1. - -- bpo-32505: Raise TypeError if a member variable of a dataclass is of type - Field, but doesn't have a type annotation. - -- bpo-33078: Fix the failure on OSX caused by the tests relying on - sem_getvalue - -- bpo-33116: Add 'Field' to dataclasses.__all__. - -- bpo-32896: Fix an error where subclassing a dataclass with a field that - uses a default_factory would generate an incorrect class. - -- bpo-33100: Dataclasses: If a field has a default value that's a - MemberDescriptorType, then it's from that field being in __slots__, not an - actual default value. - -- bpo-32953: If a non-dataclass inherits from a frozen dataclass, allow - attributes to be added to the derived class. Only attributes from the - frozen dataclass cannot be assigned to. Require all dataclasses in a - hierarchy to be either all frozen or all non-frozen. - -- bpo-33097: Raise RuntimeError when ``executor.submit`` is called during - interpreter shutdown. - -- bpo-32968: Modulo and floor division involving Fraction and float should - return float. - -- bpo-33061: Add missing ``NoReturn`` to ``__all__`` in typing.py - -- bpo-33078: Fix the size handling in multiprocessing.Queue when a pickling - error occurs. - -- bpo-33064: lib2to3 now properly supports trailing commas after ``*args`` - and ``**kwargs`` in function signatures. - -- bpo-33056: FIX properly close leaking fds in - concurrent.futures.ProcessPoolExecutor. - -- bpo-33021: Release the GIL during fstat() calls, avoiding hang of all - threads when calling mmap.mmap(), os.urandom(), and random.seed(). Patch - by Nir Soffer. - -- bpo-31804: Avoid failing in multiprocessing.Process if the standard - streams are closed or None at exit. - -- bpo-33034: Providing an explicit error message when casting the port - property to anything that is not an integer value using ``urlparse()`` and - ``urlsplit()``. Patch by Matt Eaton. - -- bpo-30249: Improve struct.unpack_from() exception messages for problems - with the buffer size and offset. - -- bpo-33037: Skip sending/receiving data after SSL transport closing. - -- bpo-27683: Fix a regression in :mod:`ipaddress` that result of - :meth:`hosts` is empty when the network is constructed by a tuple - containing an integer mask and only 1 bit left for addresses. - -- bpo-22674: Add the strsignal() function in the signal module that returns - the system description of the given signal, as returned by strsignal(3). - -- bpo-32999: Fix C implementation of ``ABC.__subclasscheck__(cls, - subclass)`` crashed when ``subclass`` is not a type object. - -- bpo-33009: Fix inspect.signature() for single-parameter partialmethods. - -- bpo-32969: Expose several missing constants in zlib and fix corresponding - documentation. - -- bpo-32056: Improved exceptions raised for invalid number of channels and - sample width when read an audio file in modules :mod:`aifc`, :mod:`wave` - and :mod:`sunau`. - -- bpo-32970: Improved disassembly of the MAKE_FUNCTION instruction. - -- bpo-32844: Fix wrong redirection of a low descriptor (0 or 1) to stderr in - subprocess if another low descriptor is closed. - -- bpo-32960: For dataclasses, disallow inheriting frozen from non-frozen - classes, and also disallow inheriting non-frozen from frozen classes. This - restriction will be relaxed at a future date. - -- bpo-32713: Fixed tarfile.itn handling of out-of-bounds float values. Patch - by Joffrey Fuhrer. - -- bpo-32257: The ssl module now contains OP_NO_RENEGOTIATION constant, - available with OpenSSL 1.1.0h or 1.1.1. - -- bpo-32951: Direct instantiation of SSLSocket and SSLObject objects is now - prohibited. The constructors were never documented, tested, or designed as - public constructors. Users were suppose to use ssl.wrap_socket() or - SSLContext. - -- bpo-32929: Remove the tri-state parameter "hash", and add the boolean - "unsafe_hash". If unsafe_hash is True, add a __hash__ function, but if a - __hash__ exists, raise TypeError. If unsafe_hash is False, add a __hash__ - based on the values of eq= and frozen=. The unsafe_hash=False behavior is - the same as the old hash=None behavior. unsafe_hash=False is the default, - just as hash=None used to be. - -- bpo-32947: Add OP_ENABLE_MIDDLEBOX_COMPAT and test workaround for TLSv1.3 - for future compatibility with OpenSSL 1.1.1. - -- bpo-32146: Document the interaction between frozen executables and the - spawn and forkserver start methods in multiprocessing. - -- bpo-30622: The ssl module now detects missing NPN support in LibreSSL. - -- bpo-32922: dbm.open() now encodes filename with the filesystem encoding - rather than default encoding. - -- bpo-32759: Free unused arenas in multiprocessing.heap. - -- bpo-32859: In ``os.dup2``, don't check every call whether the ``dup3`` - syscall exists or not. - -- bpo-32556: nt._getfinalpathname, nt._getvolumepathname and - nt._getdiskusage now correctly convert from bytes. - -- bpo-21060: Rewrite confusing message from setup.py upload from "No dist - file created in earlier command" to the more helpful "Must create and - upload files in one command". - -- bpo-32857: In :mod:`tkinter`, ``after_cancel(None)`` now raises a - :exc:`ValueError` instead of canceling the first scheduled function. - Patch by Cheryl Sabella. - -- bpo-32852: Make sure sys.argv remains as a list when running trace. - -- bpo-31333: ``_abc`` module is added. It is a speedup module with C - implementations for various functions and methods in ``abc``. Creating an - ABC subclass and calling ``isinstance`` or ``issubclass`` with an ABC - subclass are up to 1.5x faster. In addition, this makes Python start-up up - to 10% faster. - - Note that the new implementation hides internal registry and caches, - previously accessible via private attributes ``_abc_registry``, - ``_abc_cache``, and ``_abc_negative_cache``. There are three debugging - helper methods that can be used instead ``_dump_registry``, - ``_abc_registry_clear``, and ``_abc_caches_clear``. - -- bpo-32841: Fixed `asyncio.Condition` issue which silently ignored - cancellation after notifying and cancelling a conditional lock. Patch by - Bar Harel. - -- bpo-32819: ssl.match_hostname() has been simplified and no longer depends - on re and ipaddress module for wildcard and IP addresses. Error reporting - for invalid wildcards has been improved. - -- bpo-19675: ``multiprocessing.Pool`` no longer leaks processes if its - initialization fails. - -- bpo-32394: socket: Remove - TCP_FASTOPEN,TCP_KEEPCNT,TCP_KEEPIDLE,TCP_KEEPINTVL flags on older version - Windows during run-time. - -- bpo-31787: Fixed refleaks of ``__init__()`` methods in various modules. - (Contributed by Oren Milman) - -- bpo-30157: Fixed guessing quote and delimiter in csv.Sniffer.sniff() when - only the last field is quoted. Patch by Jake Davis. - -- bpo-30688: Added support of ``\N{name}`` escapes in regular expressions. - Based on patch by Jonathan Eunice. - -- bpo-32792: collections.ChainMap() preserves the order of the underlying - mappings. - -- bpo-32775: :func:`fnmatch.translate()` no longer produces patterns which - contain set operations. Sets starting with '[' or containing '--', '&&', - '~~' or '||' will be interpreted differently in regular expressions in - future versions. Currently they emit warnings. fnmatch.translate() now - avoids producing patterns containing such sets by accident. - -- bpo-32622: Implement native fast sendfile for Windows proactor event loop. - -- bpo-32777: Fix a rare but potential pre-exec child process deadlock in - subprocess on POSIX systems when marking file descriptors inheritable on - exec in the child process. This bug appears to have been introduced in - 3.4. - -- bpo-32647: The ctypes module used to depend on indirect linking for - dlopen. The shared extension is now explicitly linked against libdl on - platforms with dl. - -- bpo-32749: A :mod:`dbm.dumb` database opened with flags 'r' is now - read-only. :func:`dbm.dumb.open` with flags 'r' and 'w' no longer creates - a database if it does not exist. - -- bpo-32741: Implement ``asyncio.TimerHandle.when()`` method. - -- bpo-32691: Use mod_spec.parent when running modules with pdb - -- bpo-32734: Fixed ``asyncio.Lock()`` safety issue which allowed acquiring - and locking the same lock multiple times, without it being free. Patch by - Bar Harel. - -- bpo-32727: Do not include name field in SMTP envelope from address. Patch - by Stéphane Wirtel - -- bpo-31453: Add TLSVersion constants and SSLContext.maximum_version / - minimum_version attributes. The new API wraps OpenSSL 1.1 - https://www.openssl.org/docs/man1.1.0/ssl/SSL_CTX_set_min_proto_version.html - feature. - -- bpo-24334: Internal implementation details of ssl module were cleaned up. - The SSLSocket has one less layer of indirection. Owner and session - information are now handled by the SSLSocket and SSLObject constructor. - Channel binding implementation has been simplified. - -- bpo-31848: Fix the error handling in Aifc_read.initfp() when the SSND - chunk is not found. Patch by Zackery Spytz. - -- bpo-32585: Add Ttk spinbox widget to :mod:`tkinter.ttk`. Patch by Alan D - Moore. - -- bpo-32512: :mod:`profile` CLI accepts `-m module_name` as an alternative - to script path. - -- bpo-8525: help() on a type now displays builtin subclasses. This is - intended primarily to help with notification of more specific exception - subclasses. - - Patch by Sanyam Khurana. - -- bpo-31639: http.server now exposes a ThreadingHTTPServer class and uses it - when the module is run with ``-m`` to cope with web browsers pre-opening - sockets. - -- bpo-29877: compileall: import ProcessPoolExecutor only when needed, - preventing hangs on low resource platforms - -- bpo-32221: Various functions returning tuple containing IPv6 addresses now - omit ``%scope`` part since the same information is already encoded in - *scopeid* tuple item. Especially this speeds up :func:`socket.recvfrom` - when it receives multicast packet since useless resolving of network - interface name is omitted. - -- bpo-32147: :func:`binascii.unhexlify` is now up to 2 times faster. Patch - by Sergey Fedoseev. - -- bpo-30693: The TarFile class now recurses directories in a reproducible - way. - -- bpo-30693: The ZipFile class now recurses directories in a reproducible - way. - -- bpo-31680: Added :data:`curses.ncurses_version`. - -- bpo-31908: Fix output of cover files for ``trace`` module command-line - tool. Previously emitted cover files only when ``--missing`` option was - used. Patch by Michael Selik. - -- bpo-31608: Raise a ``TypeError`` instead of crashing if a - ``collections.deque`` subclass returns a non-deque from ``__new__``. Patch - by Oren Milman. - -- bpo-31425: Add support for sockets of the AF_QIPCRTR address family, - supported by the Linux kernel. This is used to communicate with services, - such as GPS or radio, running on Qualcomm devices. Patch by Bjorn - Andersson. - -- bpo-22005: Implemented unpickling instances of - :class:`~datetime.datetime`, :class:`~datetime.date` and - :class:`~datetime.time` pickled by Python 2. ``encoding='latin1'`` should - be used for successful decoding. - -- bpo-27645: :class:`sqlite3.Connection` now exposes a - :class:`~sqlite3.Connection.backup` method, if the underlying SQLite - library is at version 3.6.11 or higher. Patch by Lele Gaifax. - -- bpo-16865: Support arrays >=2GiB in :mod:`ctypes`. Patch by Segev Finer. - -- bpo-31508: Removed support of arguments in - `tkinter.ttk.Treeview.selection`. It was deprecated in 3.6. Use - specialized methods like `selection_set` for changing the selection. - -- bpo-29456: Fix bugs in hangul normalization: u1176, u11a7 and u11c3 - -Documentation -------------- - -- bpo-21257: Document :func:`http.client.parse_headers`. - -- bpo-34764: Improve example of iter() with 2nd sentinel argument. - -- bpo-35564: Explicitly set master_doc variable in conf.py for compliance - with Sphinx 2.0 - -- bpo-35511: Specified that profile.Profile class doesn't not support enable - or disable methods. Also, elaborated that Profile object as a context - manager is only supported in cProfile module. - -- bpo-10536: Enhance the gettext docs. Patch by Éric Araujo - -- bpo-35089: Remove mention of ``typing.io`` and ``typing.re``. Their types - should be imported from ``typing`` directly. - -- bpo-35038: Fix the documentation about an unexisting `f_restricted` - attribute in the frame object. Patch by Stéphane Wirtel - -- bpo-35042: Replace PEP XYZ by the pep role and allow to use the direct - links to the PEPs. - -- bpo-35044: Fix the documentation with the role ``exc`` for the - appropriated exception. Patch by Stéphane Wirtel - -- bpo-35035: Rename documentation for :mod:`email.utils` to - ``email.utils.rst``. - -- bpo-34967: Use app.add_object_type() instead of the deprecated Sphinx - function app.description_unit() - -- bpo-34913: Add documentation about the new command line interface of the - gzip module. - -- bpo-32174: chm document displays non-ASCII charaters properly on some MBCS - Windows systems. - -- bpo-11233: Create availability directive for documentation. Original - patch by Georg Brandl. - -- bpo-34790: Document how passing coroutines to asyncio.wait() can be - confusing. - -- bpo-34552: Make clear that ``==`` operator sometimes is equivalent to - `is`. The ``<``, ``<=``, ``>`` and ``>=`` operators are only defined where - they make sense. - -- bpo-28617: Fixed info in the stdtypes docs concerning the types that - support membership tests. - -- bpo-20177: Migrate datetime.date.fromtimestamp to Argument Clinic. Patch - by Tim Hoffmann. - -- bpo-34065: Fix wrongly written basicConfig documentation markup syntax - -- bpo-33460: replaced ellipsis with correct error codes in tutorial chapter - 3. - -- bpo-33847: Add '@' operator entry to index. - -- bpo-33409: Clarified the relationship between :pep:`538`'s - PYTHONCOERCECLOCALE and PEP 540's PYTHONUTF8 mode. - -- bpo-33197: Add versionadded tag to the documentation of - ParameterKind.description - -- bpo-17045: Improve the C-API doc for PyTypeObject. This includes adding - several quick-reference tables and a lot of missing slot/typedef entries. - The existing entries were also cleaned up with a slightly more consistent - format. - -- bpo-33736: Improve the documentation of :func:`asyncio.open_connection`, - :func:`asyncio.start_server` and their UNIX socket counterparts. - -- bpo-23859: Document that `asyncio.wait()` does not cancel its futures on - timeout. - -- bpo-32436: Document :pep:`567` changes to asyncio. - -- bpo-33604: Update HMAC md5 default to a DeprecationWarning, bump removal - to 3.8. - -- bpo-33594: Document ``getargspec``, ``from_function`` and ``from_builtin`` - as deprecated in their respective docstring, and include version since - deprecation in DeprecationWarning message. - -- bpo-33503: Fix broken pypi link - -- bpo-33421: Add missing documentation for ``typing.AsyncContextManager``. - -- bpo-33487: BZ2file now emit a DeprecationWarning when buffering=None is - passed, the deprecation message and documentation also now explicitly - state it is deprecated since 3.0. - -- bpo-33378: Add Korean language switcher for https://docs.python.org/3/ - -- bpo-33276: Clarify that the ``__path__`` attribute on modules cannot be - just any value. - -- bpo-33201: Modernize documentation for writing C extension types. - -- bpo-33195: Deprecate ``Py_UNICODE`` usage in ``c-api/arg`` document. - ``Py_UNICODE`` related APIs are deprecated since Python 3.3, but it is - missed in the document. - -- bpo-33126: Document PyBuffer_ToContiguous(). - -- bpo-27212: Modify documentation for the :func:`islice` recipe to consume - initial values up to the start index. - -- bpo-28247: Update :mod:`zipapp` documentation to describe how to make - standalone applications. - -- bpo-18802: Documentation changes for ipaddress. Patch by Jon Foster and - Berker Peksag. - -- bpo-27428: Update documentation to clarify that ``WindowsRegistryFinder`` - implements ``MetaPathFinder``. (Patch by Himanshu Lakhara) - -- bpo-28124: The ssl module function ssl.wrap_socket() has been - de-emphasized and deprecated in favor of the more secure and efficient - SSLContext.wrap_socket() method. - -- bpo-17232: Clarify docs for -O and -OO. Patch by Terry Reedy. - -- bpo-32436: Add documentation for the contextvars module (PEP 567). - -- bpo-32800: Update link to w3c doc for xml default namespaces. - -- bpo-11015: Update :mod:`test.support` documentation. - -- bpo-32613: Update the faq/windows.html to use the py command from PEP 397 - instead of python. - -- bpo-8722: Document :meth:`__getattr__` behavior when property :meth:`get` - method raises :exc:`AttributeError`. - -- bpo-32614: Modify RE examples in documentation to use raw strings to - prevent :exc:`DeprecationWarning` and add text to REGEX HOWTO to highlight - the deprecation. - -- bpo-20709: Remove the paragraph where we explain that os.utime() does not - support a directory as path under Windows. Patch by Jan-Philip Gehrcke - -- bpo-32722: Remove the bad example in the tutorial of the Generator - Expression. Patch by Stéphane Wirtel - -- bpo-31972: Improve docstrings for `pathlib.PurePath` subclasses. - -- bpo-30607: Use the externalized ``python-docs-theme`` package when - building the documentation. - -- bpo-8243: Add a note about curses.addch and curses.addstr exception - behavior when writing outside a window, or pad. - -- bpo-32337: Update documentation related with ``dict`` order. - -- bpo-25041: Document ``AF_PACKET`` in the :mod:`socket` module. - -- bpo-31432: Clarify meaning of CERT_NONE, CERT_OPTIONAL, and CERT_REQUIRED - flags for ssl.SSLContext.verify_mode. - -Tests ------ - -- bpo-35772: Fix sparse file tests of test_tarfile on ppc64 with the tmpfs - filesystem. Fix the function testing if the filesystem supports sparse - files: create a file which contains data and "holes", instead of creating - a file which contains no data. tmpfs effective block size is a page size - (tmpfs lives in the page cache). RHEL uses 64 KiB pages on aarch64, ppc64, - ppc64le, only s390x and x86_64 use 4 KiB pages, whereas the test punch - holes of 4 KiB. - -- bpo-35045: Make ssl tests less strict and also accept TLSv1 as system - default. The changes unbreaks test_min_max_version on Fedora 29. - -- bpo-32710: ``test_asyncio/test_sendfile.py`` now resets the event loop - policy using :func:`tearDownModule` as done in other tests, to prevent a - warning when running tests on Windows. - -- bpo-33717: test.pythoninfo now logs information of all clocks, not only - time.time() and time.perf_counter(). - -- bpo-35488: Add a test to pathlib's Path.match() to verify it does not - support glob-style ** recursive pattern matching. - -- bpo-31731: Fix a race condition in ``check_interrupted_write()`` of - test_io: create directly the thread with SIGALRM signal blocked, rather - than blocking the signal later from the thread. Previously, it was - possible that the thread gets the signal before the signal is blocked. - -- bpo-35424: Fix test_multiprocessing_main_handling: use - :class:`multiprocessing.Pool` with a context manager and then explicitly - join the pool. - -- bpo-35519: Rename :mod:`test.bisect` module to :mod:`test.bisect_cmd` to - avoid conflict with :mod:`bisect` module when running directly a test like - ``./python Lib/test/test_xmlrpc.py``. - -- bpo-35513: Replace :func:`time.time` with :func:`time.monotonic` in tests - to measure time delta. - -- bpo-34279: :func:`test.support.run_unittest` no longer raise - :exc:`TestDidNotRun` if the test result contains skipped tests. The - exception is now only raised if no test have been run and no test have - been skipped. - -- bpo-35412: Add testcase to ``test_future4``: check unicode literal. - -- bpo-26704: Added test demonstrating double-patching of an instance method. - Patch by Anthony Sottile. - -- bpo-33725: test_multiprocessing_fork may crash on recent versions of - macOS. Until the issue is resolved, skip the test on macOS. - -- bpo-35352: Modify test_asyncio to use the certificate set from the test - directory. - -- bpo-35317: Fix ``mktime()`` overflow error in ``test_email``: run - ``test_localtime_daylight_true_dst_true()`` and - ``test_localtime_daylight_false_dst_true()`` with a specific timezone. - -- bpo-21263: After several reports that test_gdb does not work properly on - macOS and since gdb is not shipped by default anymore, test_gdb is now - skipped on macOS when LLVM Clang has been used to compile Python. Patch by - Lysandros Nikolaou - -- bpo-34279: regrtest issue a warning when no tests have been executed in a - particular test file. Also, a new final result state is issued if no test - have been executed across all test files. Patch by Pablo Galindo. - -- bpo-34962: make docstest in Doc now passes., and is enforced in CI - -- bpo-23596: Use argparse for the command line of the gzip module. Patch by - Antony Lee - -- bpo-34537: Fix ``test_gdb.test_strings()`` when ``LC_ALL=C`` and GDB was - compiled with Python 3.6 or earlier. - -- bpo-34587: test_socket: Remove RDSTest.testCongestion(). The test tries to - fill the receiver's socket buffer and expects an error. But the RDS - protocol doesn't require that. Moreover, the Linux implementation of RDS - expects that the producer of the messages reduces its rate, it's not the - role of the receiver to trigger an error. The test fails on Fedora 28 by - design, so just remove it. - -- bpo-34661: Fix test_shutil if unzip doesn't support -t. - -- bpo-34200: Fixed non-deterministic flakiness of test_pkg by not using the - scary test.support.module_cleanup() logic to save and restore sys.modules - contents between test cases. - -- bpo-34569: The experimental PEP 554 data channels now correctly pass - negative PyLong objects between subinterpreters on 32-bit systems. Patch - by Michael Felt. - -- bpo-34594: Fix usage of hardcoded ``errno`` values in the tests. - -- bpo-34579: Fix test_embed for AIX Patch by Michael Felt - -- bpo-34542: Use 3072 RSA keys and SHA-256 signature for test certs and - keys. - -- bpo-11193: Remove special condition for AIX in - `test_subprocess.test_undecodable_env` - -- bpo-34347: Fix `test_utf8_mode.test_cmd_line` for AIX - -- bpo-34490: On AIX with AF_UNIX family sockets getsockname() does not - provide 'sockname', so skip calls to transport.get_extra_info('sockname') - -- bpo-34391: Fix ftplib test for TLS 1.3 by reading from data socket. - -- bpo-11192: Fix `test_socket` on AIX 6.1 and later IPv6 zone id supports - only supported by inet_pton6_zone() Switch to runtime-based - platform.system() to establish current platform rather than build-time - based sys.platform() - -- bpo-34399: Update all RSA keys and DH params to use at least 2048 bits. - -- bpo-34373: Fix ``test_mktime`` and ``test_pthread_getcpuclickid`` tests - for AIX Add range checking for ``_PyTime_localtime`` for AIX Patch by - Michael Felt - -- bpo-11191: Skip the distutils test 'test_search_cpp' when using XLC as - compiler patch by aixtools (Michael Felt) - -- Improved an error message when mock assert_has_calls fails. - -- bpo-33746: Fix test_unittest when run in verbose mode. - -- bpo-33901: Fix test_dbm_gnu on macOS with gdbm 1.15: add a larger value to - make sure that the file size changes. - -- bpo-33873: Fix a bug in ``regrtest`` that caused an extra test to run if - --huntrleaks/-R was used. Exit with error in case that invalid parameters - are specified to --huntrleaks/-R (at least one warmup run and one - repetition must be used). - -- bpo-33562: Check that a global asyncio event loop policy is not left - behind by any tests. - -- bpo-33655: Ignore test_posix_fallocate failures on BSD platforms that - might be due to running on ZFS. - -- bpo-32962: Fixed test_gdb when Python is compiled with flags -mcet - -fcf-protection -O0. - -- bpo-33358: Fix ``test_embed.test_pre_initialization_sys_options()`` when - the interpreter is built with ``--enable-shared``. - -- bpo-32872: Avoid regrtest compatibility issue with namespace packages. - -- bpo-32517: Fix failing ``test_asyncio`` on macOS 10.12.2+ due to transport - of ``KqueueSelector`` loop was not being closed. - -- bpo-32663: Making sure the `SMTPUTF8SimTests` class of tests gets run in - test_smtplib.py. - -- bpo-27643: Test_C test case needs "signed short" bitfields, but the IBM - XLC compiler (on AIX) does not support this Skip the code and test when - AIX and XLC are used - - Applicable to Python2-2.7 and later - -- bpo-19417: Add test_bdb.py. - -- bpo-31809: Add tests to verify connection with secp ECDH curves. - -Build ------ - -- bpo-34691: The _contextvars module is now built into the core Python - library on Windows. - -- bpo-35683: Improved Azure Pipelines build steps and now verifying layouts - correctly - -- bpo-35642: Remove asynciomodule.c from pythoncore.vcxproj - -- bpo-35550: Fix incorrect Solaris #ifdef checks to look for __sun && __SVR4 - instead of sun when compiling. - -- bpo-35499: ``make profile-opt`` no longer replaces ``CFLAGS_NODIST`` with - ``CFLAGS``. It now adds profile-guided optimization (PGO) flags to - ``CFLAGS_NODIST``: existing ``CFLAGS_NODIST`` flags are kept. - -- bpo-35257: Avoid leaking the linker flags from Link Time Optimizations - (LTO) into distutils when compiling C extensions. - -- bpo-35351: When building Python with clang and LTO, LTO flags are no - longer passed into CFLAGS to build third-party C extensions through - distutils. - -- bpo-35139: Fix a compiler error when statically linking `pyexpat` in - `Modules/Setup`. - -- bpo-35059: PCbuild: Set InlineFunctionExpansion to OnlyExplicitInline - ("/Ob1" option) in pyproject.props in Debug mode to expand functions - marked as inline. This change should make Python compiled in Debug mode a - little bit faster on Windows. - -- bpo-35011: Restores the use of pyexpatns.h to isolate our embedded copy of - the expat C library so that its symbols do not conflict at link or dynamic - loading time with an embedding application or other extension modules with - their own version of libexpat. - -- bpo-28015: Have --with-lto works correctly with clang. - -- bpo-34765: Update the outdated install-sh file to the latest revision from - automake v1.16.1 - -- bpo-34585: Check for floating-point byte order in configure.ac using - compilation tests instead of executing code, so that these checks work in - cross-compiled builds. - -- bpo-34710: Fixed SSL module build with OpenSSL & pedantic CFLAGS. - -- bpo-34582: Add JUnit XML output for regression tests and update Azure - DevOps builds. - -- bpo-34081: Make Sphinx warnings as errors in the Docs Makefile. - -- bpo-34555: Fix for case where it was not possible to have both - ``HAVE_LINUX_VM_SOCKETS_H`` and ``HAVE_SOCKADDR_ALG`` be undefined. - -- bpo-33015: Fix an undefined behaviour in the pthread implementation of - :c:func:`PyThread_start_new_thread`: add a function wrapper to always - return ``NULL``. - -- bpo-34245: The Python shared library is now installed with write - permission (mode 0755), which is the standard way of installing such - libraries. - -- bpo-34121: Fix detection of C11 atomic support on clang. - -- bpo-32430: Rename Modules/Setup.dist to Modules/Setup, and remove the - necessity to copy the former manually to the latter when updating the - local source tree. - -- bpo-30345: Add -g to LDFLAGS when compiling with LTO to get debug symbols. - -- bpo-5755: Move ``-Wstrict-prototypes`` option to ``CFLAGS_NODIST`` from - ``OPT``. This option emitted annoying warnings when building extension - modules written in C++. - -- bpo-33614: Ensures module definition files for the stable ABI on Windows - are correctly regenerated. - -- bpo-33648: The --with-c-locale-warning configuration flag has been - removed. It has had no effect for about a year. - -- bpo-33522: Enable CI builds on Visual Studio Team Services at - https://python.visualstudio.com/cpython - -- bpo-33512: configure's check for "long double" has been simplified - -- bpo-33483: C compiler is now correctly detected from the standard - environment variables. --without-gcc and --with-icc options have been - removed. - -- bpo-33394: Enable the verbose build for extension modules, when GNU make - is passed macros on the command line. - -- bpo-33393: Update config.guess and config.sub files. - -- bpo-33377: Add new triplets for mips r6 and riscv variants (used in - extension suffixes). - -- bpo-32232: By default, modules configured in `Modules/Setup` are no longer - built with `-DPy_BUILD_CORE`. Instead, modules that specifically need that - preprocessor definition include it in their individual entries. - -- bpo-33182: The embedding tests can once again be built with clang 6.0 - -- bpo-33163: Upgrade pip to 9.0.3 and setuptools to v39.0.1. - -- bpo-33012: gcc 8 has added a new warning heuristic to detect invalid - function casts and a stock python build seems to hit that warning quite - often. The most common is the cast of a METH_NOARGS function (that uses - just one argument) to a PyCFunction. Fix this by adding a dummy argument - to all functions that implement METH_NOARGS. - -- bpo-32898: Fix the python debug build when using COUNT_ALLOCS. - -- bpo-29442: Replace optparse with argparse in setup.py - -Windows -------- - -- bpo-35890: Fix API calling consistency of GetVersionEx and wcstok. - -- bpo-32560: The ``py`` launcher now forwards its ``STARTUPINFO`` structure - to child processes. - -- bpo-35854: Fix EnvBuilder and --symlinks in venv on Windows - -- bpo-35811: Avoid propagating venv settings when launching via py.exe - -- bpo-35797: Fix default executable used by the multiprocessing module - -- bpo-35758: Allow building on ARM with MSVC. - -- bpo-29734: Fix handle leaks in os.stat on Windows. - -- bpo-35596: Use unchecked PYCs for the embeddable distro to avoid zipimport - restrictions. - -- bpo-35596: Fix vcruntime140.dll being added to embeddable distro multiple - times. - -- bpo-35402: Update Windows build to use Tcl and Tk 8.6.9 - -- bpo-35401: Updates Windows build to OpenSSL 1.1.0j - -- bpo-34977: venv on Windows will now use a python.exe redirector rather - than copying the actual binaries from the base environment. - -- bpo-34977: Adds support for building a Windows App Store package - -- bpo-35067: Remove _distutils_findvs module and use vswhere.exe instead. - -- bpo-32557: Allow shutil.disk_usage to take a file path on Windows - -- bpo-34770: Fix a possible null pointer dereference in pyshellext.cpp. - -- bpo-34603: Fix returning structs from functions produced by MSVC - -- bpo-34581: Guard MSVC-specific code in socketmodule.c with ``#ifdef - _MSC_VER``. - -- bpo-34532: Fixes exit code of list version arguments for py.exe. - -- bpo-34062: Fixed the '--list' and '--list-paths' arguments for the py.exe - launcher - -- bpo-34225: Ensure INCLUDE and LIB directories do not end with a backslash. - -- bpo-34011: A suite of code has been changed which copied across DLLs and - init.tcl from the running Python location into a venv being created. These - copies are needed only when running from a Python source build, and the - copying code is now only run when that is the case, rather than whenever a - venv is created. - -- bpo-34006: Revert line length limit for Windows help docs. The line-length - limit is not needed because the pages appear in a separate app rather than - on a browser tab. It can also interact badly with the DPI setting. - -- bpo-31546: Restore running PyOS_InputHook while waiting for user input at - the prompt. The restores integration of interactive GUI windows (such as - Matplotlib figures) with the prompt on Windows. - -- bpo-30237: Output error when ReadConsole is canceled by - CancelSynchronousIo instead of crashing. - -- bpo-33895: GIL is released while calling functions that acquire Windows - loader lock. - -- bpo-33720: Reduces maximum marshal recursion depth on release builds. - -- bpo-29097: Fix bug where :meth:`datetime.fromtimestamp` erroneously throws - an :exc:`OSError` on Windows for values between 0 and 86400. Patch by - Ammar Askar. - -- bpo-33316: PyThread_release_lock always fails - -- bpo-33184: Update Windows installer to use OpenSSL 1.1.0h. - -- bpo-32890: Fix usage of GetLastError() instead of errno in os.execve() and - os.truncate(). - -- bpo-33016: Fix potential use of uninitialized memory in - nt._getfinalpathname - -- bpo-32903: Fix a memory leak in os.chdir() on Windows if the current - directory is set to a UNC path. - -- bpo-32901: Update Tcl and Tk versions to 8.6.8 - -- bpo-31966: Fixed WindowsConsoleIO.write() for writing empty data. - -- bpo-32409: Ensures activate.bat can handle Unicode contents. - -- bpo-32457: Improves handling of denormalized executable path when - launching Python. - -- bpo-32370: Use the correct encoding for ipconfig output in the uuid - module. Patch by Segev Finer. - -- bpo-29248: Fix :func:`os.readlink` on Windows, which was mistakenly - treating the ``PrintNameOffset`` field of the reparse data buffer as a - number of characters instead of bytes. Patch by Craig Holmquist and SSE4. - -- bpo-1104: Correctly handle string length in - ``msilib.SummaryInfo.GetProperty()`` to prevent it from truncating the - last character. - -macOS ------ - -- bpo-35401: Update macOS installer to use OpenSSL 1.1.0j. - -- bpo-35025: Properly guard the use of the ``CLOCK_GETTIME`` et al. macros - in ``timemodule`` on macOS. - -- bpo-24658: On macOS, fix reading from and writing into a file with a size - larger than 2 GiB. - -- bpo-34405: Update to OpenSSL 1.1.0i for macOS installer builds. - -- bpo-33635: In macOS stat on some file descriptors (/dev/fd/3 f.e) will - result in bad file descriptor OSError. Guard against this exception was - added in is_dir, is_file and similar methods. DirEntry.is_dir can also - throw this exception so _RecursiveWildcardSelector._iterate_directories - was also extended with the same error ignoring pattern. - -- bpo-13631: The .editrc file in user's home directory is now processed - correctly during the readline initialization through editline emulation on - macOS. - -- bpo-33184: Update macOS installer build to use OpenSSL 1.1.0h. - -- bpo-32726: Build and link with private copy of Tcl/Tk 8.6 for the macOS - 10.6+ installer. The 10.9+ installer variant already does this. This - means that the Python 3.7 provided by the python.org macOS installers no - longer need or use any external versions of Tcl/Tk, either system-provided - or user-installed, such as ActiveTcl. - -- bpo-32901: Update macOS 10.9+ installer to Tcl/Tk 8.6.8. - -- bpo-31903: In :mod:`_scproxy`, drop the GIL when calling into - ``SystemConfiguration`` to avoid deadlocks. - -IDLE ----- - -- bpo-35770: IDLE macosx deletes Options => Configure IDLE. It previously - deleted Window => Zoom Height by mistake. (Zoom Height is now on the - Options menu). On Mac, the settings dialog is accessed via Preferences on - the IDLE menu. - -- bpo-35769: Change IDLE's new file name from 'Untitled' to 'untitled' - -- bpo-35660: Fix imports in idlelib.window. - -- bpo-35641: Proper format `calltip` when the function has no docstring. - -- bpo-33987: Use ttk Frame for ttk widgets. - -- bpo-34055: Fix erroneous 'smart' indents and newlines in IDLE Shell. - -- bpo-35591: Find Selection now works when selection not found. - -- bpo-35196: Speed up squeezer line counting. - -- bpo-35598: Update config_key: use PEP 8 names and ttk widgets, make some - objects global, and add tests. - -- bpo-28097: Add Previous/Next History entries to Shell menu. - -- bpo-35208: Squeezer now properly counts wrapped lines before newlines. - -- bpo-35555: Gray out Code Context menu entry when it's not applicable. - -- bpo-35521: Document the IDLE editor code context feature. Add some - internal references within the IDLE doc. - -- bpo-22703: The Code Context menu label now toggles between Show/Hide Code - Context. The Zoom Height menu now toggles between Zoom/Restore Height. - Zoom Height has moved from the Window menu to the Options menu. - -- bpo-35213: Where appropriate, use 'macOS' in idlelib. - -- bpo-34864: On macOS, warn if the system preference "Prefer tabs when - opening documents" is set to "Always". - -- bpo-34864: Document two IDLE on MacOS issues. The System Preferences Dock - "prefer tabs always" setting disables some IDLE features. Menus are a bit - different than as described for Windows and Linux. - -- bpo-35202: Remove unused imports from lib/idlelib - -- bpo-33000: Document that IDLE's shell has no line limit. A program that - runs indefinitely can overfill memory. - -- bpo-23220: Explain how IDLE's Shell displays output. - -- bpo-35099: Improve the doc about IDLE running user code. The section is - renamed from "IDLE -- console differences" is renamed "Running user code". - It mostly covers the implications of using custom sys.stdxxx objects. - -- bpo-35097: Add IDLE doc subsection explaining editor windows. Topics - include opening, title and status bar, .py* extension, and running. - -- bpo-35093: Document the IDLE document viewer in the IDLE doc. Add a - paragraph in "Help and preferences", "Help sources" subsection. - -- bpo-35088: Update idlelib.help.copy_string docstring. We now use git and - backporting instead of hg and forward merging. - -- bpo-35087: Update idlelib help files for the current doc build. The main - change is the elimination of chapter-section numbers. - -- bpo-34548: Use configured color theme for read-only text views. - -- bpo-1529353: Enable "squeezing" of long outputs in the shell, to avoid - performance degradation and to clean up the history without losing it. - Squeezed outputs may be copied, viewed in a separate window, and - "unsqueezed". - -- bpo-34047: Fixed mousewheel scrolling direction on macOS. - -- bpo-34275: Make IDLE calltips always visible on Mac. Some MacOS-tk - combinations need .update_idletasks(). Patch by Kevin Walzer. - -- bpo-34120: Fix unresponsiveness after closing certain windows and dialogs. - -- bpo-33975: Avoid small type when running htests. Since part of the purpose - of human-viewed tests is to determine that widgets look right, it is - important that they look the same for testing as when running IDLE. - -- bpo-33905: Add test for idlelib.stackview.StackBrowser. - -- bpo-33924: Change mainmenu.menudefs key 'windows' to 'window'. Every other - menudef key is lowercase version of main menu entry. - -- bpo-33906: Rename idlelib.windows as window Match Window on the main menu - and remove last plural module name. - -- bpo-33917: Fix and document idlelib/idle_test/template.py. The revised - file compiles, runs, and tests OK. idle_test/README.txt explains how to - use it to create new IDLE test files. - -- bpo-33904: IDLE: In rstrip, rename class RstripExtension as Rstrip - -- bpo-33907: For consistency and clarity, rename an IDLE module and classes. - Module calltips and its class CallTips are now calltip and Calltip. In - module calltip_w, class CallTip is now CalltipWindow. - -- bpo-33856: Add "help" in the welcome message of IDLE - -- bpo-33839: IDLE: refactor ToolTip and CallTip and add documentation and - tests - -- bpo-33855: Minimally test all IDLE modules. Add missing files, import - module, instantiate classes, and check coverage. Check existing files. - -- bpo-33656: On Windows, add API call saying that tk scales for DPI. On - Windows 8.1+ or 10, with DPI compatibility properties of the Python binary - unchanged, and a monitor resolution greater than 96 DPI, this should make - text and lines sharper. It should otherwise have no effect. - -- bpo-33768: Clicking on a context line moves that line to the top of the - editor window. - -- bpo-33763: IDLE: Use read-only text widget for code context instead of - label widget. - -- bpo-33664: Scroll IDLE editor text by lines. Previously, the mouse wheel - and scrollbar slider moved text by a fixed number of pixels, resulting in - partial lines at the top of the editor box. The change also applies to - the shell and grep output windows, but not to read-only text views. - -- bpo-33679: Enable theme-specific color configuration for Code Context. Use - the Highlights tab to see the setting for built-in themes or add settings - to custom themes. - -- bpo-33642: Display up to maxlines non-blank lines for Code Context. If - there is no current context, show a single blank line. - -- bpo-33628: IDLE: Cleanup codecontext.py and its test. - -- bpo-33564: IDLE's code context now recognizes async as a block opener. - -- bpo-21474: Update word/identifier definition from ascii to unicode. In - text and entry boxes, this affects selection by double-click, movement - left/right by control-left/right, and deletion left/right by - control-BACKSPACE/DEL. - -- bpo-33204: IDLE: consistently color invalid string prefixes. A 'u' string - prefix cannot be paired with either 'r' or 'f'. Consistently color as much - of the prefix, starting at the right, as is valid. Revise and extend - colorizer test. - -- bpo-32984: Set ``__file__`` while running a startup file. Like Python, - IDLE optionally runs one startup file in the Shell window before - presenting the first interactive input prompt. For IDLE, ``-s`` runs a - file named in environmental variable :envvar:`IDLESTARTUP` or - :envvar:`PYTHONSTARTUP`; ``-r file`` runs ``file``. Python sets - ``__file__`` to the startup file name before running the file and unsets - it before the first prompt. IDLE now does the same when run normally, - without the ``-n`` option. - -- bpo-32940: Simplify and rename StringTranslatePseudoMapping in pyparse. - -- bpo-32916: Change ``str`` to ``code`` in pyparse. - -- bpo-32905: Remove unused code in pyparse module. - -- bpo-32874: Add tests for pyparse. - -- bpo-32837: Using the system and place-dependent default encoding for - open() is a bad idea for IDLE's system and location-independent files. - -- bpo-32826: Add "encoding=utf-8" to open() in IDLE's test_help_about. GUI - test test_file_buttons() only looks at initial ascii-only lines, but - failed on systems where open() defaults to 'ascii' because readline() - internally reads and decodes far enough ahead to encounter a non-ascii - character in CREDITS.txt. - -- bpo-32831: Add docstrings and tests for codecontext. - -- bpo-32765: Update configdialog General tab docstring to add new widgets to - the widget list. - -Tools/Demos ------------ - -- bpo-35884: Add a benchmark script for timing various ways to access - variables: ``Tools/scripts/var_access_benchmark.py``. - -- bpo-34989: python-gdb.py now handles errors on computing the line number - of a Python frame. - -- bpo-20260: Argument Clinic now has non-bitwise unsigned int converters. - -- bpo-32962: python-gdb now catches ``UnicodeDecodeError`` exceptions when - calling ``string()``. - -- bpo-32962: python-gdb now catches ValueError on read_var(): when Python - has no debug symbols for example. - -- bpo-33189: :program:`pygettext.py` now recognizes only literal strings as - docstrings and translatable strings, and rejects bytes literals and - f-string expressions. - -- bpo-31920: Fixed handling directories as arguments in the ``pygettext`` - script. Based on patch by Oleg Krasnikov. - -- bpo-29673: Fix pystackv and pystack gdbinit macros. - -- bpo-25427: Remove the pyvenv script in favor of ``python3 -m venv`` in - order to lower confusion as to what Python interpreter a virtual - environment will be created for. - -- bpo-32885: Add an ``-n`` flag for ``Tools/scripts/pathfix.py`` to disable - automatic backup creation (files with ``~`` suffix). - -- bpo-32222: Fix pygettext not extracting docstrings for functions with type - annotated arguments. Patch by Toby Harradine. - -- bpo-31583: Fix 2to3 for using with --add-suffix option but without - --output-dir option for relative path to files in current directory. - -C API ------ - -- bpo-35713: The :c:func:`PyByteArray_Init` and :c:func:`PyByteArray_Fini` - functions have been removed. They did nothing since Python 2.7.4 and - Python 3.2.0, were excluded from the limited API (stable ABI), and were - not documented. - -- bpo-33817: Fixed :c:func:`_PyBytes_Resize` for empty bytes objects. - -- bpo-35322: Fix memory leak in :c:func:`PyUnicode_EncodeLocale` and - :c:func:`PyUnicode_EncodeFSDefault` on error handling. - -- bpo-35059: The following C macros have been converted to static inline - functions: :c:func:`Py_INCREF`, :c:func:`Py_DECREF`, :c:func:`Py_XINCREF`, - :c:func:`Py_XDECREF`, :c:func:`PyObject_INIT`, - :c:func:`PyObject_INIT_VAR`. - -- bpo-35296: ``make install`` now also installs the internal API: - ``Include/internal/*.h`` header files. - -- bpo-35081: Internal APIs surrounded by ``#ifdef Py_BUILD_CORE`` have been - moved from ``Include/*.h`` headers to new header files - ``Include/internal/pycore_*.h``. - -- bpo-35259: Conditionally declare :c:func:`Py_FinalizeEx()` (new in 3.6) - based on Py_LIMITED_API. Patch by Arthur Neufeld. - -- bpo-35081: The :c:func:`_PyObject_GC_TRACK` and - :c:func:`_PyObject_GC_UNTRACK` macros have been removed from the public C - API. - -- bpo-35134: Creation of a new ``Include/cpython/`` subdirectory. - -- bpo-34725: Adds _Py_SetProgramFullPath so embedders may override - sys.executable - -- bpo-34910: Ensure that :c:func:`PyObject_Print` always returns ``-1`` on - error. Patch by Zackery Spytz. - -- bpo-34523: Py_DecodeLocale() and Py_EncodeLocale() now use the UTF-8 - encoding on Windows if Py_LegacyWindowsFSEncodingFlag is zero. - -- bpo-34193: Fix pluralization in TypeError messages in getargs.c and - typeobject.c: '1 argument' instead of '1 arguments' and '1 element' - instead of '1 elements'. - -- bpo-34127: Return grammatically correct error message based on argument - count. Patch by Karthikeyan Singaravelan. - -- bpo-23927: Fixed :exc:`SystemError` in - :c:func:`PyArg_ParseTupleAndKeywords` when the ``w*`` format unit is used - for optional parameter. - -- bpo-32455: Added :c:func:`PyCompile_OpcodeStackEffectWithJump`. - -- bpo-34008: Py_Main() can again be called after Py_Initialize(), as in - Python 3.6. - -- bpo-32500: Fixed error messages for :c:func:`PySequence_Size`, - :c:func:`PySequence_GetItem`, :c:func:`PySequence_SetItem` and - :c:func:`PySequence_DelItem` called with a mapping and - :c:func:`PyMapping_Size` called with a sequence. - -- bpo-33818: :c:func:`PyExceptionClass_Name` will now return ``const char - *`` instead of ``char *``. - -- bpo-33042: Embedding applications may once again call - PySys_ResetWarnOptions, PySys_AddWarnOption, and PySys_AddXOption prior to - calling Py_Initialize. - -- bpo-32374: Document that m_traverse for multi-phase initialized modules - can be called with m_state=NULL, and add a sanity check - -- bpo-30863: :c:func:`PyUnicode_AsWideChar` and - :c:func:`PyUnicode_AsWideCharString` no longer cache the ``wchar_t*`` - representation of string objects. - - -What's New in Python 3.7.0 final? -================================= - -*Release date: 2018-06-27* - -Library -------- - -- bpo-33851: Fix :func:`ast.get_docstring` for a node that lacks a - docstring. - -C API ------ - -- bpo-33932: Calling Py_Initialize() twice does nothing, instead of failing - with a fatal error: restore the Python 3.6 behaviour. - - -What's New in Python 3.7.0 release candidate 1? -=============================================== - -*Release date: 2018-06-12* - -Core and Builtins ------------------ - -- bpo-33803: Fix a crash in hamt.c caused by enabling GC tracking for an - object that hadn't all of its fields set to NULL. - -- bpo-33706: Fix a crash in Python initialization when parsing the command - line options. Thanks Christoph Gohlke for the bug report and the fix! - -- bpo-30654: Fixed reset of the SIGINT handler to SIG_DFL on interpreter - shutdown even when there was a custom handler set previously. Patch by - Philipp Kerling. - -- bpo-31849: Fix signed/unsigned comparison warning in pyhash.c. - -Library -------- - -- bpo-30167: Prevent site.main() exception if PYTHONSTARTUP is set. Patch by - Steve Weber. - -- bpo-33812: Datetime instance d with non-None tzinfo, but with - d.tzinfo.utcoffset(d) returning None is now treated as naive by the - astimezone() method. - -- bpo-30805: Avoid race condition with debug logging - -- bpo-33694: asyncio: Fix a race condition causing data loss on - pause_reading()/resume_reading() when using the ProactorEventLoop. - -- bpo-32493: Correct test for ``uuid_enc_be`` availability in - ``configure.ac``. Patch by Michael Felt. - -- bpo-33792: Add asyncio.WindowsSelectorEventLoopPolicy and - asyncio.WindowsProactorEventLoopPolicy. - -- bpo-33778: Update ``unicodedata``'s database to Unicode version 11.0.0. - -- bpo-33770: improve base64 exception message for encoded inputs of invalid - length - -- bpo-33769: asyncio/start_tls: Fix error message; cancel callbacks in case - of an unhandled error; mark SSLTransport as closed if it is aborted. - -- bpo-33767: The concatenation (``+``) and repetition (``*``) sequence - operations now raise :exc:`TypeError` instead of :exc:`SystemError` when - performed on :class:`mmap.mmap` objects. Patch by Zackery Spytz. - -- bpo-33734: asyncio/ssl: Fix AttributeError, increase default handshake - timeout - -- bpo-11874: Use a better regex when breaking usage into wrappable parts. - Avoids bogus assertion errors from custom metavar strings. - -- bpo-33582: Emit a deprecation warning for inspect.formatargspec - -Documentation -------------- - -- bpo-33409: Clarified the relationship between :pep:`538`'s - PYTHONCOERCECLOCALE and PEP 540's PYTHONUTF8 mode. - -- bpo-33736: Improve the documentation of :func:`asyncio.open_connection`, - :func:`asyncio.start_server` and their UNIX socket counterparts. - -- bpo-31432: Clarify meaning of CERT_NONE, CERT_OPTIONAL, and CERT_REQUIRED - flags for ssl.SSLContext.verify_mode. - -Build ------ - -- bpo-5755: Move ``-Wstrict-prototypes`` option to ``CFLAGS_NODIST`` from - ``OPT``. This option emitted annoying warnings when building extension - modules written in C++. - -Windows -------- - -- bpo-33720: Reduces maximum marshal recursion depth on release builds. - -IDLE ----- - -- bpo-33656: On Windows, add API call saying that tk scales for DPI. On - Windows 8.1+ or 10, with DPI compatibility properties of the Python binary - unchanged, and a monitor resolution greater than 96 DPI, this should make - text and lines sharper. It should otherwise have no effect. - -- bpo-33768: Clicking on a context line moves that line to the top of the - editor window. - -- bpo-33763: IDLE: Use read-only text widget for code context instead of - label widget. - -- bpo-33664: Scroll IDLE editor text by lines. Previously, the mouse wheel - and scrollbar slider moved text by a fixed number of pixels, resulting in - partial lines at the top of the editor box. The change also applies to - the shell and grep output windows, but not to read-only text views. - -- bpo-33679: Enable theme-specific color configuration for Code Context. Use - the Highlights tab to see the setting for built-in themes or add settings - to custom themes. - -- bpo-33642: Display up to maxlines non-blank lines for Code Context. If - there is no current context, show a single blank line. - - -What's New in Python 3.7.0 beta 5? -================================== - -*Release date: 2018-05-30* - -Core and Builtins ------------------ - -- bpo-33622: Fixed a leak when the garbage collector fails to add an object - with the ``__del__`` method or referenced by it into the - :data:`gc.garbage` list. :c:func:`PyGC_Collect` can now be called when an - exception is set and preserves it. - -- bpo-33509: Fix module_globals parameter of warnings.warn_explicit(): don't - crash if module_globals is not a dict. - -- bpo-20104: The new `os.posix_spawn` added in 3.7.0b1 was removed as we are - still working on what the API should look like. Expect this in 3.8 - instead. - -- bpo-33475: Fixed miscellaneous bugs in converting annotations to strings - and optimized parentheses in the string representation. - -- bpo-33391: Fix a leak in set_symmetric_difference(). - -- bpo-28055: Fix unaligned accesses in siphash24(). Patch by Rolf Eike Beer. - -- bpo-32911: Due to unexpected compatibility issues discovered during - downstream beta testing, reverted :issue:`29463`. ``docstring`` field is - removed from Module, ClassDef, FunctionDef, and AsyncFunctionDef ast nodes - which was added in 3.7a1. Docstring expression is restored as a first - statement in their body. Based on patch by Inada Naoki. - -- bpo-21983: Fix a crash in `ctypes.cast()` in case the type argument is a - ctypes structured data type. Patch by Eryk Sun and Oren Milman. - -Library -------- - -- bpo-32751: When cancelling the task due to a timeout, - :meth:`asyncio.wait_for` will now wait until the cancellation is complete. - -- bpo-32684: Fix gather to propagate cancellation of itself even with - return_exceptions. - -- bpo-33654: Support protocol type switching in SSLTransport.set_protocol(). - -- bpo-33674: Pause the transport as early as possible to further reduce the - risk of data_received() being called before connection_made(). - -- bpo-33674: Fix a race condition in SSLProtocol.connection_made() of - asyncio.sslproto: start immediately the handshake instead of using - call_soon(). Previously, data_received() could be called before the - handshake started, causing the handshake to hang or fail. - -- bpo-31647: Fixed bug where calling write_eof() on a - _SelectorSocketTransport after it's already closed raises AttributeError. - -- bpo-32610: Make asyncio.all_tasks() return only pending tasks. - -- bpo-32410: Avoid blocking on file IO in sendfile fallback code - -- bpo-33469: Fix RuntimeError after closing loop that used run_in_executor - -- bpo-33672: Fix Task.__repr__ crash with Cython's bogus coroutines - -- bpo-33654: Fix transport.set_protocol() to support switching between - asyncio.Protocol and asyncio.BufferedProtocol. Fix loop.start_tls() to - work with asyncio.BufferedProtocols. - -- bpo-33652: Pickles of type variables and subscripted generics are now - future-proof and compatible with older Python versions. - -- bpo-32493: Fixed :func:`uuid.uuid1` on FreeBSD. - -- bpo-33618: Finalize and document preliminary and experimental TLS 1.3 - support with OpenSSL 1.1.1 - -- bpo-33623: Fix possible SIGSGV when asyncio.Future is created in __del__ - -- bpo-30877: Fixed a bug in the Python implementation of the JSON decoder - that prevented the cache of parsed strings from clearing after finishing - the decoding. Based on patch by c-fos. - -- bpo-33570: Change TLS 1.3 cipher suite settings for compatibility with - OpenSSL 1.1.1-pre6 and newer. OpenSSL 1.1.1 will have TLS 1.3 ciphers - enabled by default. - -- bpo-28556: Do not simplify arguments to `typing.Union`. Now - `Union[Manager, Employee]` is not simplified to `Employee` at runtime. - Such simplification previously caused several bugs and limited - possibilities for introspection. - -- bpo-33540: Add a new ``block_on_close`` class attribute to - ``ForkingMixIn`` and ``ThreadingMixIn`` classes of :mod:`socketserver`. - -- bpo-33548: tempfile._candidate_tempdir_list should consider common TEMP - locations - -- bpo-33109: argparse subparsers are once again not required by default, - reverting the change in behavior introduced by bpo-26510 in 3.7.0a2. - -- bpo-33536: dataclasses.make_dataclass now checks for invalid field names - and duplicate fields. Also, added a check for invalid field - specifications. - -- bpo-33542: Prevent ``uuid.get_node`` from using a DUID instead of a MAC on - Windows. Patch by Zvi Effron - -- bpo-26819: Fix race condition with `ReadTransport.resume_reading` in - Windows proactor event loop. - -- Fix failure in `typing.get_type_hints()` when ClassVar was provided as a - string forward reference. - -- bpo-33505: Optimize asyncio.ensure_future() by reordering if checks: 1.17x - faster. - -- bpo-33497: Add errors param to cgi.parse_multipart and make an encoding in - FieldStorage use the given errors (needed for Twisted). Patch by Amber - Brown. - -- bpo-33495: Change dataclasses.Fields repr to use the repr of each of its - members, instead of str. This makes it more clear what each field - actually represents. This is especially true for the 'type' member. - -- bpo-33453: Fix dataclasses to work if using literal string type - annotations or if using PEP 563 "Postponed Evaluation of Annotations". - Only specific string prefixes are detected for both ClassVar ("ClassVar" - and "typing.ClassVar") and InitVar ("InitVar" and "dataclasses.InitVar"). - -- bpo-28556: Minor fixes in typing module: add annotations to - ``NamedTuple.__new__``, pass ``*args`` and ``**kwds`` in - ``Generic.__new__``. Original PRs by Paulius Šarka and Chad Dombrova. - -- bpo-20087: Updated alias mapping with glibc 2.27 supported locales. - -- bpo-33422: Fix trailing quotation marks getting deleted when looking up - byte/string literals on pydoc. Patch by Andrés Delfino. - -- bpo-28167: The function ``platform.linux_distribution`` and - ``platform.dist`` now trigger a ``DeprecationWarning`` and have been - marked for removal in Python 3.8 - -- bpo-33197: Update error message when constructing invalid - inspect.Parameters Patch by Dong-hee Na. - -- bpo-33263: Fix FD leak in `_SelectorSocketTransport` Patch by Vlad - Starostin. - -- bpo-32861: The urllib.robotparser's ``__str__`` representation now - includes wildcard entries and the "Crawl-delay" and "Request-rate" fields. - Patch by Michael Lazar. - -- bpo-32257: The ssl module now contains OP_NO_RENEGOTIATION constant, - available with OpenSSL 1.1.0h or 1.1.1. - -- bpo-16865: Support arrays >=2GiB in :mod:`ctypes`. Patch by Segev Finer. - -Documentation -------------- - -- bpo-23859: Document that `asyncio.wait()` does not cancel its futures on - timeout. - -- bpo-32436: Document :pep:`567` changes to asyncio. - -- bpo-33604: Update HMAC md5 default to a DeprecationWarning, bump removal - to 3.8. - -- bpo-33503: Fix broken pypi link - -- bpo-33421: Add missing documentation for ``typing.AsyncContextManager``. - -Tests ------ - -- bpo-33655: Ignore test_posix_fallocate failures on BSD platforms that - might be due to running on ZFS. - -- bpo-32604: Remove the _xxsubinterpreters module (meant for testing) and - associated helpers. This module was originally added recently in 3.7b1. - -Build ------ - -- bpo-33614: Ensures module definition files for the stable ABI on Windows - are correctly regenerated. - -- bpo-33522: Enable CI builds on Visual Studio Team Services at - https://python.visualstudio.com/cpython - -- bpo-33012: Add ``-Wno-cast-function-type`` for gcc 8 for silencing - warnings about function casts like casting to PyCFunction in method - definition lists. - -macOS ------ - -- bpo-13631: The .editrc file in user's home directory is now processed - correctly during the readline initialization through editline emulation on - macOS. - -IDLE ----- - -- bpo-33628: IDLE: Cleanup codecontext.py and its test. - -- bpo-33564: IDLE's code context now recognizes async as a block opener. - -- bpo-32831: Add docstrings and tests for codecontext. - - -What's New in Python 3.7.0 beta 4? -================================== - -*Release date: 2018-05-02* - -Core and Builtins ------------------ - -- bpo-33363: Raise a SyntaxError for ``async with`` and ``async for`` - statements outside of async functions. - -- bpo-33128: Fix a bug that causes PathFinder to appear twice on - sys.meta_path. Patch by Pablo Galindo Salgado. - -- bpo-33312: Fixed clang ubsan (undefined behavior sanitizer) warnings in - dictobject.c by adjusting how the internal struct _dictkeysobject shared - keys structure is declared. - -- bpo-33231: Fix potential memory leak in ``normalizestring()``. - -- bpo-33205: Change dict growth function from - ``round_up_to_power_2(used*2+hashtable_size/2)`` to - ``round_up_to_power_2(used*3)``. Previously, dict is shrinked only when - ``used == 0``. Now dict has more chance to be shrinked. - -- bpo-29922: Improved error messages in 'async with' when ``__aenter__()`` - or ``__aexit__()`` return non-awaitable object. - -- bpo-33199: Fix ``ma_version_tag`` in dict implementation is uninitialized - when copying from key-sharing dict. - -Library -------- - -- bpo-33281: Fix ctypes.util.find_library regression on macOS. - -- bpo-33383: Fixed crash in the get() method of the :mod:`dbm.ndbm` database - object when it is called with a single argument. - -- bpo-33329: Fix multiprocessing regression on newer glibcs - -- bpo-991266: Fix quoting of the ``Comment`` attribute of - :class:`http.cookies.SimpleCookie`. - -- bpo-33131: Upgrade bundled version of pip to 10.0.1. - -- bpo-33308: Fixed a crash in the :mod:`parser` module when converting an ST - object to a tree of tuples or lists with ``line_info=False`` and - ``col_info=True``. - -- bpo-33266: lib2to3 now recognizes ``rf'...'`` strings. - -- bpo-11594: Ensure line-endings are respected when using lib2to3. - -- bpo-33254: Have :func:`importlib.resources.contents` and - :meth:`importlib.abc.ResourceReader.contents` return an :term:`iterable` - instead of an :term:`iterator`. - -- bpo-33256: Fix display of ``<module>`` call in the html produced by - ``cgitb.html()``. Patch by Stéphane Blondon. - -- bpo-33185: Fixed regression when running pydoc with the :option:`-m` - switch. (The regression was introduced in 3.7.0b3 by the resolution of - :issue:`33053`) This fix also changed pydoc to add ``os.getcwd()`` to - :data:`sys.path` when necessary, rather than adding ``"."``. - -- bpo-33169: Delete entries of ``None`` in :data:`sys.path_importer_cache` - when :meth:`importlib.machinery.invalidate_caches` is called. - -- bpo-33217: Deprecate looking up non-Enum objects in Enum classes and Enum - members (will raise :exc:`TypeError` in 3.8+). - -- bpo-33203: ``random.Random.choice()`` now raises ``IndexError`` for empty - sequences consistently even when called from subclasses without a - ``getrandbits()`` implementation. - -- bpo-33224: Update difflib.mdiff() for :pep:`479`. Convert an uncaught - StopIteration in a generator into a return-statement. - -- bpo-33209: End framing at the end of C implementation of - :func:`pickle.Pickler.dump`. - -- bpo-20104: Improved error handling and fixed a reference leak in - :func:`os.posix_spawn()`. - -- bpo-33175: In dataclasses, Field.__set_name__ now looks up the - __set_name__ special method on the class, not the instance, of the default - value. - -- bpo-33097: Raise RuntimeError when ``executor.submit`` is called during - interpreter shutdown. - -- bpo-31908: Fix output of cover files for ``trace`` module command-line - tool. Previously emitted cover files only when ``--missing`` option was - used. Patch by Michael Selik. - -Documentation -------------- - -- bpo-33378: Add Korean language switcher for https://docs.python.org/3/ - -- bpo-33276: Clarify that the ``__path__`` attribute on modules cannot be - just any value. - -- bpo-33201: Modernize documentation for writing C extension types. - -- bpo-33195: Deprecate ``Py_UNICODE`` usage in ``c-api/arg`` document. - ``Py_UNICODE`` related APIs are deprecated since Python 3.3, but it is - missed in the document. - -- bpo-8243: Add a note about curses.addch and curses.addstr exception - behavior when writing outside a window, or pad. - -- bpo-32337: Update documentation related with ``dict`` order. - -Tests ------ - -- bpo-33358: Fix ``test_embed.test_pre_initialization_sys_options()`` when - the interpreter is built with ``--enable-shared``. - -Build ------ - -- bpo-33394: Enable the verbose build for extension modules, when GNU make - is passed macros on the command line. - -- bpo-33393: Update config.guess and config.sub files. - -- bpo-33377: Add new triplets for mips r6 and riscv variants (used in - extension suffixes). - -- bpo-32232: By default, modules configured in `Modules/Setup` are no longer - built with `-DPy_BUILD_CORE`. Instead, modules that specifically need that - preprocessor definition include it in their individual entries. - -- bpo-33182: The embedding tests can once again be built with clang 6.0 - -Windows -------- - -- bpo-33184: Update Windows installer to use OpenSSL 1.1.0h. - -macOS ------ - -- bpo-33184: Update macOS installer build to use OpenSSL 1.1.0h. - -IDLE ----- - -- bpo-21474: Update word/identifier definition from ascii to unicode. In - text and entry boxes, this affects selection by double-click, movement - left/right by control-left/right, and deletion left/right by - control-BACKSPACE/DEL. - -- bpo-33204: IDLE: consistently color invalid string prefixes. A 'u' string - prefix cannot be paired with either 'r' or 'f'. Consistently color as much - of the prefix, starting at the right, as is valid. Revise and extend - colorizer test. - -Tools/Demos ------------ - -- bpo-33189: :program:`pygettext.py` now recognizes only literal strings as - docstrings and translatable strings, and rejects bytes literals and - f-string expressions. - -- bpo-31920: Fixed handling directories as arguments in the ``pygettext`` - script. Based on patch by Oleg Krasnikov. - -- bpo-29673: Fix pystackv and pystack gdbinit macros. - -- bpo-31583: Fix 2to3 for using with --add-suffix option but without - --output-dir option for relative path to files in current directory. - - -What's New in Python 3.7.0 beta 3? -================================== - -*Release date: 2018-03-29* - -Security --------- - -- bpo-33136: Harden ssl module against LibreSSL CVE-2018-8970. - X509_VERIFY_PARAM_set1_host() is called with an explicit namelen. A new - test ensures that NULL bytes are not allowed. - -- bpo-33001: Minimal fix to prevent buffer overrun in os.symlink on Windows - -- bpo-32981: Regexes in difflib and poplib were vulnerable to catastrophic - backtracking. These regexes formed potential DOS vectors (REDOS). They - have been refactored. This resolves CVE-2018-1060 and CVE-2018-1061. Patch - by Jamie Davis. - -Core and Builtins ------------------ - -- bpo-33053: When using the -m switch, sys.path[0] is now explicitly - expanded as the *starting* working directory, rather than being left as - the empty path (which allows imports from the current working directory at - the time of the import) - -- bpo-33018: Improve consistency of errors raised by ``issubclass()`` when - called with a non-class and an abstract base class as the first and second - arguments, respectively. Patch by Josh Bronson. - -- bpo-33041: Fixed jumping when the function contains an ``async for`` loop. - -- bpo-33026: Fixed jumping out of "with" block by setting f_lineno. - -- bpo-33005: Fix a crash on fork when using a custom memory allocator (ex: - using PYTHONMALLOC env var). _PyGILState_Reinit() and - _PyInterpreterState_Enable() now use the default RAW memory allocator to - allocate a new interpreters mutex on fork. - -- bpo-17288: Prevent jumps from 'return' and 'exception' trace events. - -- bpo-32836: Don't use temporary variables in cases of list/dict/set - comprehensions - -Library -------- - -- bpo-33141: Have Field objects pass through __set_name__ to their default - values, if they have their own __set_name__. - -- bpo-33096: Allow ttk.Treeview.insert to insert iid that has a false - boolean value. Note iid=0 and iid=False would be same. Patch by Garvit - Khatri. - -- bpo-32873: Treat type variables and special typing forms as immutable by - copy and pickle. This fixes several minor issues and inconsistencies, and - improves backwards compatibility with Python 3.6. - -- bpo-33134: When computing dataclass's __hash__, use the lookup table to - contain the function which returns the __hash__ value. This is an - improvement over looking up a string, and then testing that string to see - what to do. - -- bpo-33127: The ssl module now compiles with LibreSSL 2.7.1. - -- bpo-32505: Raise TypeError if a member variable of a dataclass is of type - Field, but doesn't have a type annotation. - -- bpo-33078: Fix the failure on OSX caused by the tests relying on - sem_getvalue - -- bpo-33116: Add 'Field' to dataclasses.__all__. - -- bpo-32896: Fix an error where subclassing a dataclass with a field that - uses a default_factory would generate an incorrect class. - -- bpo-33100: Dataclasses: If a field has a default value that's a - MemberDescriptorType, then it's from that field being in __slots__, not an - actual default value. - -- bpo-32953: If a non-dataclass inherits from a frozen dataclass, allow - attributes to be added to the derived class. Only attributes from the - frozen dataclass cannot be assigned to. Require all dataclasses in a - hierarchy to be either all frozen or all non-frozen. - -- bpo-33061: Add missing ``NoReturn`` to ``__all__`` in typing.py - -- bpo-33078: Fix the size handling in multiprocessing.Queue when a pickling - error occurs. - -- bpo-33064: lib2to3 now properly supports trailing commas after ``*args`` - and ``**kwargs`` in function signatures. - -- bpo-33056: FIX properly close leaking fds in - concurrent.futures.ProcessPoolExecutor. - -- bpo-33021: Release the GIL during fstat() calls, avoiding hang of all - threads when calling mmap.mmap(), os.urandom(), and random.seed(). Patch - by Nir Soffer. - -- bpo-31804: Avoid failing in multiprocessing.Process if the standard - streams are closed or None at exit. - -- bpo-33037: Skip sending/receiving data after SSL transport closing. - -- bpo-27683: Fix a regression in :mod:`ipaddress` that result of - :meth:`hosts` is empty when the network is constructed by a tuple - containing an integer mask and only 1 bit left for addresses. - -- bpo-32999: Fix C implementation of ``ABC.__subclasscheck__(cls, - subclass)`` crashed when ``subclass`` is not a type object. - -- bpo-33009: Fix inspect.signature() for single-parameter partialmethods. - -- bpo-32969: Expose several missing constants in zlib and fix corresponding - documentation. - -- bpo-32056: Improved exceptions raised for invalid number of channels and - sample width when read an audio file in modules :mod:`aifc`, :mod:`wave` - and :mod:`sunau`. - -- bpo-32844: Fix wrong redirection of a low descriptor (0 or 1) to stderr in - subprocess if another low descriptor is closed. - -- bpo-32857: In :mod:`tkinter`, ``after_cancel(None)`` now raises a - :exc:`ValueError` instead of canceling the first scheduled function. - Patch by Cheryl Sabella. - -- bpo-31639: http.server now exposes a ThreadedHTTPServer class and uses it - when the module is run with ``-m`` to cope with web browsers pre-opening - sockets. - -- bpo-27645: :class:`sqlite3.Connection` now exposes a - :class:`~sqlite3.Connection.backup` method, if the underlying SQLite - library is at version 3.6.11 or higher. Patch by Lele Gaifax. - -Documentation -------------- - -- bpo-33126: Document PyBuffer_ToContiguous(). - -- bpo-27212: Modify documentation for the :func:`islice` recipe to consume - initial values up to the start index. - -- bpo-28247: Update :mod:`zipapp` documentation to describe how to make - standalone applications. - -- bpo-18802: Documentation changes for ipaddress. Patch by Jon Foster and - Berker Peksag. - -- bpo-27428: Update documentation to clarify that ``WindowsRegistryFinder`` - implements ``MetaPathFinder``. (Patch by Himanshu Lakhara) - -Tests ------ - -- bpo-32872: Avoid regrtest compatibility issue with namespace packages. - -- bpo-32517: Fix failing ``test_asyncio`` on macOS 10.12.2+ due to transport - of ``KqueueSelector`` loop was not being closed. - -- bpo-19417: Add test_bdb.py. - -Build ------ - -- bpo-33163: Upgrade pip to 9.0.3 and setuptools to v39.0.1. - -Windows -------- - -- bpo-33016: Fix potential use of uninitialized memory in - nt._getfinalpathname - -- bpo-32903: Fix a memory leak in os.chdir() on Windows if the current - directory is set to a UNC path. - -macOS ------ - -- bpo-32726: Build and link with private copy of Tcl/Tk 8.6 for the macOS - 10.6+ installer. The 10.9+ installer variant already does this. This - means that the Python 3.7 provided by the python.org macOS installers no - longer need or use any external versions of Tcl/Tk, either system-provided - or user-installed, such as ActiveTcl. - -IDLE ----- - -- bpo-32984: Set ``__file__`` while running a startup file. Like Python, - IDLE optionally runs one startup file in the Shell window before - presenting the first interactive input prompt. For IDLE, ``-s`` runs a - file named in environmental variable :envvar:`IDLESTARTUP` or - :envvar:`PYTHONSTARTUP`; ``-r file`` runs ``file``. Python sets - ``__file__`` to the startup file name before running the file and unsets - it before the first prompt. IDLE now does the same when run normally, - without the ``-n`` option. - -- bpo-32940: Simplify and rename StringTranslatePseudoMapping in pyparse. - -Tools/Demos ------------ - -- bpo-32885: Add an ``-n`` flag for ``Tools/scripts/pathfix.py`` to disable - automatic backup creation (files with ``~`` suffix). - -C API ------ - -- bpo-33042: Embedding applications may once again call - PySys_ResetWarnOptions, PySys_AddWarnOption, and PySys_AddXOption prior to - calling Py_Initialize. - -- bpo-32374: Document that m_traverse for multi-phase initialized modules - can be called with m_state=NULL, and add a sanity check - - -What's New in Python 3.7.0 beta 2? -================================== - -*Release date: 2018-02-27* - -Security --------- - -- bpo-28414: The ssl module now allows users to perform their own IDN - en/decoding when using SNI. - -Core and Builtins ------------------ - -- bpo-32889: Update Valgrind suppression list to account for the rename of - ``Py_ADDRESS_IN_RANG`` to ``address_in_range``. - -- bpo-31356: Remove the new API added in bpo-31356 (gc.ensure_disabled() - context manager). - -- bpo-32305: For namespace packages, ensure that both ``__file__`` and - ``__spec__.origin`` are set to None. - -- bpo-32303: Make sure ``__spec__.loader`` matches ``__loader__`` for - namespace packages. - -- bpo-32711: Fix the warning messages for Python/ast_unparse.c. Patch by - Stéphane Wirtel - -- bpo-32583: Fix possible crashing in builtin Unicode decoders caused by - write out-of-bound errors when using customized decode error handlers. - -Library -------- - -- bpo-32960: For dataclasses, disallow inheriting frozen from non-frozen - classes, and also disallow inheriting non-frozen from frozen classes. This - restriction will be relaxed at a future date. - -- bpo-32713: Fixed tarfile.itn handling of out-of-bounds float values. Patch - by Joffrey Fuhrer. - -- bpo-32951: Direct instantiation of SSLSocket and SSLObject objects is now - prohibited. The constructors were never documented, tested, or designed as - public constructors. Users were suppose to use ssl.wrap_socket() or - SSLContext. - -- bpo-32929: Remove the tri-state parameter "hash", and add the boolean - "unsafe_hash". If unsafe_hash is True, add a __hash__ function, but if a - __hash__ exists, raise TypeError. If unsafe_hash is False, add a __hash__ - based on the values of eq= and frozen=. The unsafe_hash=False behavior is - the same as the old hash=None behavior. unsafe_hash=False is the default, - just as hash=None used to be. - -- bpo-32947: Add OP_ENABLE_MIDDLEBOX_COMPAT and test workaround for TLSv1.3 - for future compatibility with OpenSSL 1.1.1. - -- bpo-30622: The ssl module now detects missing NPN support in LibreSSL. - -- bpo-32922: dbm.open() now encodes filename with the filesystem encoding - rather than default encoding. - -- bpo-32859: In ``os.dup2``, don't check every call whether the ``dup3`` - syscall exists or not. - -- bpo-32556: nt._getfinalpathname, nt._getvolumepathname and - nt._getdiskusage now correctly convert from bytes. - -- bpo-25988: Emit a :exc:`DeprecationWarning` when using or importing an ABC - directly from :mod:`collections` rather than from :mod:`collections.abc`. - -- bpo-21060: Rewrite confusing message from setup.py upload from "No dist - file created in earlier command" to the more helpful "Must create and - upload files in one command". - -- bpo-32852: Make sure sys.argv remains as a list when running trace. - -- bpo-31333: ``_abc`` module is added. It is a speedup module with C - implementations for various functions and methods in ``abc``. Creating an - ABC subclass and calling ``isinstance`` or ``issubclass`` with an ABC - subclass are up to 1.5x faster. In addition, this makes Python start-up up - to 10% faster. Note that the new implementation hides internal registry - and caches, previously accessible via private attributes - ``_abc_registry``, ``_abc_cache``, and ``_abc_negative_cache``. There are - three debugging helper methods that can be used instead - ``_dump_registry``, ``_abc_registry_clear``, and ``_abc_caches_clear``. - -- bpo-32841: Fixed `asyncio.Condition` issue which silently ignored - cancellation after notifying and cancelling a conditional lock. Patch by - Bar Harel. - -- bpo-32819: ssl.match_hostname() has been simplified and no longer depends - on re and ipaddress module for wildcard and IP addresses. Error reporting - for invalid wildcards has been improved. - -- bpo-32394: socket: Remove - TCP_FASTOPEN,TCP_KEEPCNT,TCP_KEEPIDLE,TCP_KEEPINTVL flags on older version - Windows during run-time. - -- bpo-31787: Fixed refleaks of ``__init__()`` methods in various modules. - (Contributed by Oren Milman) - -- bpo-30157: Fixed guessing quote and delimiter in csv.Sniffer.sniff() when - only the last field is quoted. Patch by Jake Davis. - -- bpo-32792: collections.ChainMap() preserves the order of the underlying - mappings. - -- bpo-32775: :func:`fnmatch.translate()` no longer produces patterns which - contain set operations. Sets starting with '[' or containing '--', '&&', - '~~' or '||' will be interpreted differently in regular expressions in - future versions. Currently they emit warnings. fnmatch.translate() now - avoids producing patterns containing such sets by accident. - -- bpo-32622: Implement native fast sendfile for Windows proactor event loop. - -- bpo-32777: Fix a rare but potential pre-exec child process deadlock in - subprocess on POSIX systems when marking file descriptors inheritable on - exec in the child process. This bug appears to have been introduced in - 3.4. - -- bpo-32647: The ctypes module used to depend on indirect linking for - dlopen. The shared extension is now explicitly linked against libdl on - platforms with dl. - -- bpo-32741: Implement ``asyncio.TimerHandle.when()`` method. - -- bpo-32691: Use mod_spec.parent when running modules with pdb - -- bpo-32734: Fixed ``asyncio.Lock()`` safety issue which allowed acquiring - and locking the same lock multiple times, without it being free. Patch by - Bar Harel. - -- bpo-32727: Do not include name field in SMTP envelope from address. Patch - by Stéphane Wirtel - -- bpo-31453: Add TLSVersion constants and SSLContext.maximum_version / - minimum_version attributes. The new API wraps OpenSSL 1.1 - https://www.openssl.org/docs/man1.1.0/ssl/SSL_CTX_set_min_proto_version.html - feature. - -- bpo-24334: Internal implementation details of ssl module were cleaned up. - The SSLSocket has one less layer of indirection. Owner and session - information are now handled by the SSLSocket and SSLObject constructor. - Channel binding implementation has been simplified. - -- bpo-31848: Fix the error handling in Aifc_read.initfp() when the SSND - chunk is not found. Patch by Zackery Spytz. - -- bpo-32585: Add Ttk spinbox widget to :mod:`tkinter.ttk`. Patch by Alan D - Moore. - -- bpo-32221: Various functions returning tuple containing IPv6 addresses now - omit ``%scope`` part since the same information is already encoded in - *scopeid* tuple item. Especially this speeds up :func:`socket.recvfrom` - when it receives multicast packet since useless resolving of network - interface name is omitted. - -- bpo-30693: The TarFile class now recurses directories in a reproducible - way. - -- bpo-30693: The ZipFile class now recurses directories in a reproducible - way. - -Documentation -------------- - -- bpo-28124: The ssl module function ssl.wrap_socket() has been - de-emphasized and deprecated in favor of the more secure and efficient - SSLContext.wrap_socket() method. - -- bpo-17232: Clarify docs for -O and -OO. Patch by Terry Reedy. - -- bpo-32436: Add documentation for the contextvars module (PEP 567). - -- bpo-32800: Update link to w3c doc for xml default namespaces. - -- bpo-11015: Update :mod:`test.support` documentation. - -- bpo-8722: Document :meth:`__getattr__` behavior when property :meth:`get` - method raises :exc:`AttributeError`. - -- bpo-32614: Modify RE examples in documentation to use raw strings to - prevent :exc:`DeprecationWarning` and add text to REGEX HOWTO to highlight - the deprecation. - -- bpo-31972: Improve docstrings for `pathlib.PurePath` subclasses. - -Tests ------ - -- bpo-31809: Add tests to verify connection with secp ECDH curves. - -Build ------ - -- bpo-32898: Fix the python debug build when using COUNT_ALLOCS. - -Windows -------- - -- bpo-32901: Update Tcl and Tk versions to 8.6.8 - -- bpo-31966: Fixed WindowsConsoleIO.write() for writing empty data. - -- bpo-32409: Ensures activate.bat can handle Unicode contents. - -- bpo-32457: Improves handling of denormalized executable path when - launching Python. - -- bpo-32370: Use the correct encoding for ipconfig output in the uuid - module. Patch by Segev Finer. - -- bpo-29248: Fix :func:`os.readlink` on Windows, which was mistakenly - treating the ``PrintNameOffset`` field of the reparse data buffer as a - number of characters instead of bytes. Patch by Craig Holmquist and SSE4. - -macOS ------ - -- bpo-32901: Update macOS 10.9+ installer to Tcl/Tk 8.6.8. - -IDLE ----- - -- bpo-32916: Change ``str`` to ``code`` in pyparse. - -- bpo-32905: Remove unused code in pyparse module. - -- bpo-32874: Add tests for pyparse. - -- bpo-32837: Using the system and place-dependent default encoding for - open() is a bad idea for IDLE's system and location-independent files. - -- bpo-32826: Add "encoding=utf-8" to open() in IDLE's test_help_about. GUI - test test_file_buttons() only looks at initial ascii-only lines, but - failed on systems where open() defaults to 'ascii' because readline() - internally reads and decodes far enough ahead to encounter a non-ascii - character in CREDITS.txt. - -- bpo-32765: Update configdialog General tab docstring to add new widgets to - the widget list. - -Tools/Demos ------------ - -- bpo-32222: Fix pygettext not extracting docstrings for functions with type - annotated arguments. Patch by Toby Harradine. - - -What's New in Python 3.7.0 beta 1? -================================== - -*Release date: 2018-01-30* - -Core and Builtins ------------------ - -- bpo-32703: Fix coroutine's ResourceWarning when there's an active error - set when it's being finalized. - -- bpo-32650: Pdb and other debuggers dependent on bdb.py will correctly step - over (next command) native coroutines. Patch by Pablo Galindo. - -- bpo-28685: Optimize list.sort() and sorted() by using type specialized - comparisons when possible. - -- bpo-32685: Improve suggestion when the Python 2 form of print statement is - either present on the same line as the header of a compound statement or - else terminated by a semi-colon instead of a newline. Patch by Nitish - Chandra. - -- bpo-32697: Python now explicitly preserves the definition order of - keyword-only parameters. It's always preserved their order, but this - behavior was never guaranteed before; this behavior is now guaranteed and - tested. - -- bpo-32690: The locals() dictionary now displays in the lexical order that - variables were defined. Previously, the order was reversed. - -- bpo-32677: Add ``.isascii()`` method to ``str``, ``bytes`` and - ``bytearray``. It can be used to test that string contains only ASCII - characters. - -- bpo-32670: Enforce :pep:`479` for all code. This means that manually - raising a StopIteration exception from a generator is prohibited for all - code, regardless of whether 'from __future__ import generator_stop' was - used or not. - -- bpo-32591: Added built-in support for tracking the origin of coroutine - objects; see sys.set_coroutine_origin_tracking_depth and - CoroutineType.cr_origin. This replaces the asyncio debug mode's use of - coroutine wrapping for native coroutine objects. - -- bpo-31368: Expose preadv and pwritev system calls in the os module. Patch - by Pablo Galindo - -- bpo-32544: ``hasattr(obj, name)`` and ``getattr(obj, name, default)`` are - about 4 times faster than before when ``name`` is not found and ``obj`` - doesn't override ``__getattr__`` or ``__getattribute__``. - -- bpo-26163: Improved frozenset() hash to create more distinct hash values - when faced with datasets containing many similar values. - -- bpo-32550: Remove the STORE_ANNOTATION bytecode. - -- bpo-20104: Expose posix_spawn as a low level API in the os module. - (removed before 3.7.0rc1) - -- bpo-24340: Fixed estimation of the code stack size. - -- bpo-32436: Implement :pep:`567` Context Variables. - -- bpo-18533: ``repr()`` on a dict containing its own ``values()`` or - ``items()`` no longer raises ``RecursionError``; OrderedDict similarly. - Instead, use ``...``, as for other recursive structures. Patch by Ben - North. - -- bpo-20891: Py_Initialize() now creates the GIL. The GIL is no longer - created "on demand" to fix a race condition when PyGILState_Ensure() is - called in a non-Python thread. - -- bpo-32028: Leading whitespace is now correctly ignored when generating - suggestions for converting Py2 print statements to Py3 builtin print - function calls. Patch by Sanyam Khurana. - -- bpo-31179: Make dict.copy() up to 5.5 times faster. - -- bpo-31113: Get rid of recursion in the compiler for normal control flow. - -Library -------- - -- bpo-25988: Deprecate exposing the contents of collections.abc in the - regular collections module. - -- bpo-31429: The default cipher suite selection of the ssl module now uses a - blacklist approach rather than a hard-coded whitelist. Python no longer - re-enables ciphers that have been blocked by OpenSSL security update. - Default cipher suite selection can be configured on compile time. - -- bpo-30306: contextlib.contextmanager now releases the arguments passed to - the underlying generator as soon as the context manager is entered. - Previously it would keep them alive for as long as the context manager was - alive, even when not being used as a function decorator. Patch by Martin - Teichmann. - -- bpo-21417: Added support for setting the compression level for - zipfile.ZipFile. - -- bpo-32251: Implement asyncio.BufferedProtocol (provisional API). - -- bpo-32513: In dataclasses, allow easier overriding of dunder methods - without specifying decorator parameters. - -- bpo-32660: :mod:`termios` makes available ``FIONREAD``, ``FIONCLEX``, - ``FIOCLEX``, ``FIOASYNC`` and ``FIONBIO`` also under Solaris/derivatives. - -- bpo-27931: Fix email address header parsing error when the username is an - empty quoted string. Patch by Xiang Zhang. - -- bpo-32659: Under Solaris and derivatives, :class:`os.stat_result` provides - a st_fstype attribute. - -- bpo-32662: Implement Server.start_serving(), Server.serve_forever(), and - Server.is_serving() methods. Add 'start_serving' keyword parameter to - loop.create_server() and loop.create_unix_server(). - -- bpo-32391: Implement :meth:`asyncio.StreamWriter.wait_closed` and - :meth:`asyncio.StreamWriter.is_closing` methods - -- bpo-32643: Make Task._step, Task._wakeup and Future._schedule_callbacks - methods private. - -- bpo-32630: Refactor decimal module to use contextvars to store decimal - context. - -- bpo-32622: Add :meth:`asyncio.AbstractEventLoop.sendfile` method. - -- bpo-32304: distutils' upload command no longer corrupts tar files ending - with a CR byte, and no longer tries to convert CR to CRLF in any of the - upload text fields. - -- bpo-32502: uuid.uuid1 no longer raises an exception if a 64-bit hardware - address is encountered. - -- bpo-32596: ``concurrent.futures`` imports ``ThreadPoolExecutor`` and - ``ProcessPoolExecutor`` lazily (using :pep:`562`). It makes ``import - asyncio`` about 15% faster because asyncio uses only - ``ThreadPoolExecutor`` by default. - -- bpo-31801: Add ``_ignore_`` to ``Enum`` so temporary variables can be used - during class construction without being turned into members. - -- bpo-32576: Use queue.SimpleQueue() in places where it can be invoked from - a weakref callback. - -- bpo-32574: Fix memory leak in asyncio.Queue, when the queue has limited - size and it is full, the cancelation of queue.put() can cause a memory - leak. Patch by: José Melero. - -- bpo-32521: The nis module is now compatible with new libnsl and headers - location. - -- bpo-32467: collections.abc.ValuesView now inherits from - collections.abc.Collection. - -- bpo-32473: Improve ABCMeta._dump_registry() output readability - -- bpo-32102: New argument ``capture_output`` for subprocess.run - -- bpo-32521: glibc has removed Sun RPC. Use replacement libtirpc headers and - library in nis module. - -- bpo-32493: UUID module fixes build for FreeBSD/OpenBSD - -- bpo-32503: Pickling with protocol 4 no longer creates too small frames. - -- bpo-29237: Create enum for pstats sorting options - -- bpo-32454: Add close(fd) function to the socket module. - -- bpo-25942: The subprocess module is now more graceful when handling a - Ctrl-C KeyboardInterrupt during subprocess.call, subprocess.run, or a - Popen context manager. It now waits a short amount of time for the child - (presumed to have also gotten the SIGINT) to exit, before continuing the - KeyboardInterrupt exception handling. This still includes a SIGKILL in - the call() and run() APIs, but at least the child had a chance first. - -- bpo-32433: The hmac module now has hmac.digest(), which provides an - optimized HMAC digest. - -- bpo-28134: Sockets now auto-detect family, type and protocol from file - descriptor by default. - -- bpo-32404: Fix bug where :meth:`datetime.datetime.fromtimestamp` did not - call __new__ in :class:`datetime.datetime` subclasses. - -- bpo-32403: Improved speed of :class:`datetime.date` and - :class:`datetime.datetime` alternate constructors. - -- bpo-32228: Ensure that ``truncate()`` preserves the file position (as - reported by ``tell()``) after writes longer than the buffer size. - -- bpo-32410: Implement ``loop.sock_sendfile`` for asyncio event loop. - -- bpo-22908: Added seek and tell to the ZipExtFile class. This only works if - the file object used to open the zipfile is seekable. - -- bpo-32373: Add socket.getblocking() method. - -- bpo-32248: Add :mod:`importlib.resources` and - :class:`importlib.abc.ResourceReader` as the unified API for reading - resources contained within packages. Loaders wishing to support resource - reading must implement the :meth:`get_resource_reader()` method. - File-based and zipimport-based loaders both implement these APIs. - :class:`importlib.abc.ResourceLoader` is deprecated in favor of these new - APIs. - -- bpo-32320: collections.namedtuple() now supports default values. - -- bpo-29302: Add contextlib.AsyncExitStack. Patch by Alexander Mohr and Ilya - Kulakov. - -- bpo-31961: *Removed in Python 3.7.0b2.* The *args* argument of - subprocess.Popen can now be a :term:`path-like object`. If *args* is given - as a sequence, it's first element can now be a :term:`path-like object` as - well. - -- bpo-31900: The :func:`locale.localeconv` function now sets temporarily the - ``LC_CTYPE`` locale to the ``LC_NUMERIC`` locale to decode - ``decimal_point`` and ``thousands_sep`` byte strings if they are non-ASCII - or longer than 1 byte, and the ``LC_NUMERIC`` locale is different than the - ``LC_CTYPE`` locale. This temporary change affects other threads. Same - change for the :meth:`str.format` method when formatting a number - (:class:`int`, :class:`float`, :class:`float` and subclasses) with the - ``n`` type (ex: ``'{:n}'.format(1234)``). - -- bpo-31853: Use super().method instead of socket.method in SSLSocket. They - were there most likely for legacy reasons. - -- bpo-31399: The ssl module now uses OpenSSL's X509_VERIFY_PARAM_set1_host() - and X509_VERIFY_PARAM_set1_ip() API to verify hostname and IP addresses. - Subject common name fallback can be disabled with - SSLContext.hostname_checks_common_name. - -- bpo-14976: Add a queue.SimpleQueue class, an unbounded FIFO queue with a - reentrant C implementation of put(). - -Documentation -------------- - -- bpo-32724: Add references to some commands in the documentation of Pdb. - Patch by Stéphane Wirtel - -- bpo-32649: Complete the C API documentation, profiling and tracing part - with the newly added per-opcode events. - -- bpo-17799: Explain real behaviour of sys.settrace and sys.setprofile and - their C-API counterparts regarding which type of events are received in - each function. Patch by Pablo Galindo Salgado. - -Tests ------ - -- bpo-32721: Fix test_hashlib to not fail if the _md5 module is not built. - -- bpo-28414: Add test cases for IDNA 2003 and 2008 host names. IDNA 2003 - internationalized host names are working since bpo-31399 has landed. IDNA - 2008 are still broken. - -- bpo-32604: Add a new "_xxsubinterpreters" extension module that exposes - the existing subinterpreter C-API and a new cross-interpreter data sharing - mechanism. The module is primarily intended for more thorough testing of - the existing subinterpreter support. Note that the _xxsubinterpreters - module has been removed in 3.7.0rc1. - -- bpo-32602: Add test certs and test for ECDSA cert and EC/RSA dual mode. - -- bpo-32549: On Travis CI, Python now Compiles and uses a local copy of - OpenSSL 1.1.0g for testing. - -Build ------ - -- bpo-32635: Fix segfault of the crypt module when libxcrypt is provided - instead of libcrypt at the system. - -- bpo-32598: Use autoconf to detect OpenSSL libs, headers and supported - features. The ax_check_openssl M4 macro uses pkg-config to locate OpenSSL - and falls back to manual search. - -- bpo-32593: Drop support of FreeBSD 9 and older. - -- bpo-29708: If the :envvar:`SOURCE_DATE_EPOCH` environment variable is set, - :mod:`py_compile` will always create hash-based ``.pyc`` files. - -Windows -------- - -- bpo-32588: Create standalone _distutils_findvs module and add missing - _queue module to installer. - -- bpo-29911: Ensure separate Modify and Uninstall buttons are displayed. - -- bpo-32507: Use app-local UCRT install rather than the proper update for - old versions of Windows. - -macOS ------ - -- bpo-32726: Provide an additional, more modern macOS installer variant that - supports macOS 10.9+ systems in 64-bit mode only. Upgrade the supplied - third-party libraries to OpenSSL 1.1.0g and to SQLite 3.22.0. The 10.9+ - installer now links with and supplies its own copy of Tcl/Tk 8.6. - -- bpo-28440: No longer add /Library/Python/3.x/site-packages to sys.path for - macOS framework builds to avoid future conflicts. - -C API ------ - -- bpo-32681: Fix uninitialized variable 'res' in the C implementation of - os.dup2. Patch by Stéphane Wirtel - -- bpo-10381: Add C API access to the ``datetime.timezone`` constructor and - ``datetime.timzone.UTC`` singleton. - - -What's New in Python 3.7.0 alpha 4? -=================================== - -*Release date: 2018-01-08* - -Core and Builtins ------------------ - -- bpo-31975: The default warning filter list now starts with a - "default::DeprecationWarning:__main__" entry, so deprecation warnings are - once again shown by default in single-file scripts and at the interactive - prompt. - -- bpo-32226: ``__class_getitem__`` is now an automatic class method. - -- bpo-32399: Add AIX uuid library support for RFC4122 using uuid_create() in - libc.a - -- bpo-32390: Fix the compilation failure on AIX after the f_fsid field has - been added to the object returned by os.statvfs() (issue #32143). Original - patch by Michael Felt. - -- bpo-32379: Make MRO computation faster when a class inherits from a single - base. - -- bpo-32259: The error message of a TypeError raised when unpack - non-iterable is now more specific. - -- bpo-27169: The ``__debug__`` constant is now optimized out at compile - time. This fixes also bpo-22091. - -- bpo-32329: The :option:`-R` option now turns on hash randomization when - the :envvar:`PYTHONHASHSEED` environment variable is set to ``0``. - Previously, the option was ignored. Moreover, - ``sys.flags.hash_randomization`` is now properly set to 0 when hash - randomization is turned off by ``PYTHONHASHSEED=0``. - -- bpo-30416: The optimizer is now protected from spending much time doing - complex calculations and consuming much memory for creating large - constants in constant folding. Increased limits for constants that can be - produced in constant folding. - -- bpo-32282: Fix an unnecessary ifdef in the include of VersionHelpers.h in - socketmodule on Windows. - -- bpo-30579: Implement TracebackType.__new__ to allow Python-level creation - of traceback objects, and make TracebackType.tb_next mutable. - -- bpo-32260: Don't byte swap the input keys to the SipHash algorithm on - big-endian platforms. This should ensure siphash gives consistent results - across platforms. - -- bpo-31506: Improve the error message logic for object.__new__ and - object.__init__. Patch by Sanyam Khurana. - -- bpo-20361: ``-b`` and ``-bb`` now inject ``'default::BytesWarning'`` and - ``error::BytesWarning`` entries into ``sys.warnoptions``, ensuring that - they take precedence over any other warning filters configured via the - ``-W`` option or the ``PYTHONWARNINGS`` environment variable. - -- bpo-32230: `-X dev` now injects a ``'default'`` entry into - sys.warnoptions, ensuring that it behaves identically to actually passing - ``-Wdefault`` at the command line. - -- bpo-29240: Add a new UTF-8 mode: implementation of the :pep:`540`. - -- bpo-32226: :pep:`560`: Add support for ``__mro_entries__`` and - ``__class_getitem__``. Implemented by Ivan Levkivskyi. - -- bpo-32225: :pep:`562`: Add support for module ``__getattr__`` and - ``__dir__``. Implemented by Ivan Levkivskyi. - -- bpo-31901: The `atexit` module now has its callback stored per - interpreter. - -- bpo-31650: Implement :pep:`552` (Deterministic pycs). Python now supports - invalidating bytecode cache files bashed on a source content hash rather - than source last-modified time. - -- bpo-29469: Move constant folding from bytecode layer to AST layer. - Original patch by Eugene Toder. - -Library -------- - -- bpo-32506: Now that dict is defined as keeping insertion order, drop - OrderedDict and just use plain dict. - -- bpo-32279: Add params to dataclasses.make_dataclasses(): init, repr, eq, - order, hash, and frozen. Pass them through to dataclass(). - -- bpo-32278: Make type information optional on dataclasses.make_dataclass(). - If omitted, the string 'typing.Any' is used. - -- bpo-32499: Add dataclasses.is_dataclass(obj), which returns True if obj is - a dataclass or an instance of one. - -- bpo-32468: Improve frame repr() to mention filename, code name and current - line number. - -- bpo-23749: asyncio: Implement loop.start_tls() - -- bpo-32441: Return the new file descriptor (i.e., the second argument) from - ``os.dup2``. Previously, ``None`` was always returned. - -- bpo-32422: ``functools.lru_cache`` uses less memory (3 words for each - cached key) and takes about 1/3 time for cyclic GC. - -- bpo-31721: Prevent Python crash from happening when Future._log_traceback - is set to True manually. Now it can only be set to False, or a ValueError - is raised. - -- bpo-32415: asyncio: Add Task.get_loop() and Future.get_loop() - -- bpo-26133: Don't unsubscribe signals in asyncio UNIX event loop on - interpreter shutdown. - -- bpo-32363: Make asyncio.Task.set_exception() and set_result() raise - NotImplementedError. Task._step() and Future.__await__() raise proper - exceptions when they are in an invalid state, instead of raising an - AssertionError. - -- bpo-32357: Optimize asyncio.iscoroutine() and loop.create_task() for - non-native coroutines (e.g. async/await compiled with Cython). - 'loop.create_task(python_coroutine)' used to be 20% faster than - 'loop.create_task(cython_coroutine)'. Now, the latter is as fast. - -- bpo-32356: asyncio.transport.resume_reading() and pause_reading() are now - idempotent. New transport.is_reading() method is added. - -- bpo-32355: Optimize asyncio.gather(); now up to 15% faster. - -- bpo-32351: Use fastpath in asyncio.sleep if delay<0 (2x boost) - -- bpo-32348: Optimize asyncio.Future schedule/add/remove callback. The - optimization shows 3-6% performance improvements of async/await code. - -- bpo-32331: Fix socket.settimeout() and socket.setblocking() to keep - socket.type as is. Fix socket.socket() constructor to reset any bit flags - applied to socket's type. This change only affects OSes that have - SOCK_NONBLOCK and/or SOCK_CLOEXEC. - -- bpo-32248: Add :class:`importlib.abc.ResourceReader` as an ABC for loaders - to provide a unified API for reading resources contained within packages. - Also add :mod:`importlib.resources` as the port of - ``importlib_resources``. - -- bpo-32311: Implement asyncio.create_task(coro) shortcut - -- bpo-32327: Convert asyncio functions that were documented as coroutines to - coroutines. Affected functions: loop.sock_sendall, loop.sock_recv, - loop.sock_accept, loop.getaddrinfo, loop.getnameinfo. - -- bpo-32323: :func:`urllib.parse.urlsplit()` does not convert zone-id - (scope) to lower case for scoped IPv6 addresses in hostnames now. - -- bpo-32302: Fix bdist_wininst of distutils for CRT v142: it binary - compatible with CRT v140. - -- bpo-29711: Fix ``stop_serving`` in asyncio proactor loop kill all - listening servers - -- bpo-32308: :func:`re.sub()` now replaces empty matches adjacent to a - previous non-empty match. - -- bpo-29970: Abort asyncio SSLProtocol connection if handshake not complete - within 10 seconds. - -- bpo-32314: Implement asyncio.run(). - -- bpo-17852: Revert incorrect fix based on misunderstanding of - _Py_PyAtExit() semantics. - -- bpo-32296: Implement asyncio._get_running_loop() and get_event_loop() in - C. This makes them 4x faster. - -- bpo-32250: Implement ``asyncio.current_task()`` and - ``asyncio.all_tasks()``. Add helpers intended to be used by alternative - task implementations: ``asyncio._register_task``, ``asyncio._enter_task``, - ``asyncio._leave_task`` and ``asyncio._unregister_task``. Deprecate - ``asyncio.Task.current_task()`` and ``asyncio.Task.all_tasks()``. - -- bpo-32255: A single empty field is now always quoted when written into a - CSV file. This allows to distinguish an empty row from a row consisting of - a single empty field. Patch by Licht Takeuchi. - -- bpo-32277: Raise ``NotImplementedError`` instead of ``SystemError`` on - platforms where ``chmod(..., follow_symlinks=False)`` is not supported. - Patch by Anthony Sottile. - -- bpo-30050: New argument warn_on_full_buffer to signal.set_wakeup_fd lets - you control whether Python prints a warning on stderr when the wakeup fd - buffer overflows. - -- bpo-29137: The ``fpectl`` library has been removed. It was never enabled - by default, never worked correctly on x86-64, and it changed the Python - ABI in ways that caused unexpected breakage of C extensions. - -- bpo-32273: Move asyncio.test_utils to test.test_asyncio. - -- bpo-32272: Remove asyncio.async() function. - -- bpo-32269: Add asyncio.get_running_loop() function. - -- bpo-32265: All class and static methods of builtin types now are correctly - classified by inspect.classify_class_attrs() and grouped in pydoc ouput. - Added types.ClassMethodDescriptorType for unbound class methods of builtin - types. - -- bpo-32253: Deprecate ``yield from lock``, ``await lock``, ``with (yield - from lock)`` and ``with await lock`` for asyncio synchronization - primitives. - -- bpo-22589: Changed MIME type of .bmp from 'image/x-ms-bmp' to 'image/bmp' - -- bpo-32193: Convert asyncio to use *async/await* syntax. Old styled ``yield - from`` is still supported too. - -- bpo-32206: Add support to run modules with pdb - -- bpo-32227: ``functools.singledispatch`` now supports registering - implementations using type annotations. - -- bpo-15873: Added new alternate constructors - :meth:`datetime.datetime.fromisoformat`, - :meth:`datetime.time.fromisoformat` and - :meth:`datetime.date.fromisoformat` as the inverse operation of each - classes's respective ``isoformat`` methods. - -- bpo-32199: The getnode() ip getter now uses 'ip link' instead of 'ip link - list'. - -- bpo-32143: os.statvfs() includes the f_fsid field from statvfs(2) - -- bpo-26439: Fix ctypes.util.find_library() for AIX by implementing - ctypes._aix.find_library() Patch by: Michael Felt - -- bpo-31993: The pickler now uses less memory when serializing large bytes - and str objects into a file. Pickles created with protocol 4 will require - less memory for unpickling large bytes and str objects. - -- bpo-27456: Ensure TCP_NODELAY is set on Linux. Tests by Victor Stinner. - -- bpo-31778: ast.literal_eval() is now more strict. Addition and subtraction - of arbitrary numbers no longer allowed. - -- bpo-31802: Importing native path module (``posixpath``, ``ntpath``) now - works even if the ``os`` module still is not imported. - -- bpo-30241: Add contextlib.AbstractAsyncContextManager. Patch by Jelle - Zijlstra. - -- bpo-31699: Fix deadlocks in - :class:`concurrent.futures.ProcessPoolExecutor` when task arguments or - results cause pickling or unpickling errors. This should make sure that - calls to the :class:`ProcessPoolExecutor` API always eventually return. - -- bpo-15216: ``TextIOWrapper.reconfigure()`` supports changing *encoding*, - *errors*, and *newline*. - -Documentation -------------- - -- bpo-32418: Add get_loop() method to Server and AbstractServer classes. - -Tests ------ - -- bpo-32252: Fix faulthandler_suppress_crash_report() used to prevent core - dump files when testing crashes. getrlimit() returns zero on success. - -- bpo-32002: Adjust C locale coercion testing for the empty locale and POSIX - locale cases to more readily adjust to platform dependent behaviour. - -Windows -------- - -- bpo-19764: Implement support for `subprocess.Popen(close_fds=True)` on - Windows. Patch by Segev Finer. - -Tools/Demos ------------ - -- bpo-24960: 2to3 and lib2to3 can now read pickled grammar files using - pkgutil.get_data() rather than probing the filesystem. This lets 2to3 and - lib2to3 work when run from a zipfile. - -C API ------ - -- bpo-32030: Py_Initialize() doesn't reset the memory allocators to default - if the ``PYTHONMALLOC`` environment variable is not set. - -- bpo-29084: Undocumented C API for OrderedDict has been excluded from the - limited C API. It was added by mistake and actually never worked in the - limited C API. - -- bpo-32264: Moved the pygetopt.h header into internal/, since it has no - public APIs. - -- bpo-32241: :c:func:`Py_SetProgramName` and :c:func:`Py_SetPythonHome` now - take the ``const wchar *`` arguments instead of ``wchar *``. - - -What's New in Python 3.7.0 alpha 3? -=================================== - -*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-10544: Yield expressions are now deprecated in comprehensions and - generator expressions. They are still permitted in the definition of the - outermost iterable, as that is evaluated directly in the enclosing scope. - -- bpo-32137: The repr of deeply nested dict now raises a RecursionError - instead of crashing due to a stack overflow. - -- bpo-32096: Revert memory allocator changes in the C API: move structures - back from _PyRuntime to Objects/obmalloc.c. The memory allocators are once - again initialized statically, and so PyMem_RawMalloc() and - Py_DecodeLocale() can be called before _PyRuntime_Initialize(). - -- bpo-32043: Add a new "developer mode": new "-X dev" command line option to - enable debug checks at runtime. - -- bpo-32023: SyntaxError is now correctly raised when a generator expression - without parenthesis is used instead of an inheritance list in a class - definition. The duplication of the parentheses can be omitted only on - calls. - -- bpo-32012: SyntaxError is now correctly raised when a generator expression - without parenthesis is passed as an argument, but followed by a trailing - comma. A generator expression always needs to be directly inside a set of - parentheses and cannot have a comma on either side. - -- bpo-28180: A new internal ``_Py_SetLocaleFromEnv(category)`` helper - function has been added in order to improve the consistency of behaviour - across different ``libc`` implementations (e.g. Android doesn't support - setting the locale from the environment by default). - -- 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-21720: BytesWarning no longer emitted when the *fromlist* argument of - ``__import__()`` or the ``__all__`` attribute of the module contain bytes - instances. - -- bpo-31845: Environment variables are once more read correctly at - interpreter startup. - -- bpo-28936: Ensure that lexically first syntax error involving a parameter - and ``global`` or ``nonlocal`` is detected first at a given scope. Patch - by Ivan Levkivskyi. - -- bpo-31825: Fixed OverflowError in the 'unicode-escape' codec and in - codecs.escape_decode() when decode an escaped non-ascii byte. - -- bpo-31618: The per-frame tracing logic added in 3.7a1 has been altered so - that ``frame->f_lineno`` is updated before either ``"line"`` or - ``"opcode"`` events are emitted. Previously, opcode events were emitted - first, and therefore would occasionally see stale line numbers on the - frame. The behavior of this feature has changed slightly as a result: when - both ``f_trace_lines`` and ``f_trace_opcodes`` are enabled, line events - now occur first. - -- 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-31781: Prevent crashes when calling methods of an uninitialized - ``zipimport.zipimporter`` object. Patch by Oren Milman. - -- bpo-30399: Standard repr() of BaseException with a single argument no - longer contains redundant trailing comma. - -- bpo-31626: Fixed a bug in debug memory allocator. There was a write to - freed memory after shrinking a memory block. - -- 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-32214: PEP 557, Data Classes. Provides a decorator which adds - boilerplate methods to classes which use type annotations so specify - fields. - -- 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-32101: Add :attr:`sys.flags.dev_mode` flag - -- bpo-32154: The ``asyncio.windows_utils.socketpair()`` function has been - removed: use directly :func:`socket.socketpair` which is available on all - platforms since Python 3.5 (before, it wasn't available on Windows). - ``asyncio.windows_utils.socketpair()`` was just an alias to - ``socket.socketpair`` on Python 3.5 and newer. - -- bpo-32089: warnings: In development (-X dev) and debug mode (pydebug - build), use the "default" action for ResourceWarning, rather than the - "always" action, in the default warnings filters. - -- bpo-32107: ``uuid.getnode()`` now preferentially returns universally - administered MAC addresses if available, over locally administered MAC - addresses. This makes a better guarantee for global uniqueness of UUIDs - returned from ``uuid.uuid1()``. If only locally administered MAC - addresses are available, the first such one found is returned. - -- bpo-23033: Wildcard is now supported in hostname when it is one and only - character in the left most segment of hostname in second argument of - :meth:`ssl.match_hostname`. Patch by Mandeep Singh. - -- bpo-12239: Make :meth:`msilib.SummaryInformation.GetProperty` return - ``None`` when the value of property is ``VT_EMPTY``. Initial patch by - Mark Mc Mahon. - -- bpo-28334: Use :func:`os.path.expanduser` to find the ``~/.netrc`` file in - :class:`netrc.netrc`. If it does not exist, :exc:`FileNotFoundError` is - raised. Patch by Dimitri Merejkowsky. - -- bpo-32121: Made ``tracemalloc.Traceback`` behave more like the traceback - module, sorting the frames from oldest to most recent. - ``Traceback.format()`` now accepts negative *limit*, truncating the result - to the ``abs(limit)`` oldest frames. To get the old behaviour, one can use - the new *most_recent_first* argument to ``Traceback.format()``. (Patch by - Jesse Bakker.) - -- 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-19610: ``setup()`` now warns about invalid types for some fields. The - ``distutils.dist.Distribution`` class now warns when ``classifiers``, - ``keywords`` and ``platforms`` fields are not specified as a list or a - string. - -- bpo-32071: Added the ``-k`` command-line option to ``python -m unittest`` - to run only tests that match the given pattern(s). - -- bpo-10049: Added *nullcontext* no-op context manager to contextlib. This - provides a simpler and faster alternative to ExitStack() when handling - optional context managers. - -- bpo-28684: The new test.support.skip_unless_bind_unix_socket() decorator - is used here to skip asyncio tests that fail because the platform lacks a - functional bind() function for unix domain sockets (as it is the case for - non root users on the recent Android versions that run now SELinux in - enforcing mode). - -- 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-27535: The warnings module doesn't leak memory anymore in the hidden - warnings registry for the "ignore" action of warnings filters. - warn_explicit() function doesn't add the warning key to the registry - anymore for the "ignore" action. - -- bpo-32088: warnings: When Python is build is debug mode (``Py_DEBUG``), - :exc:`DeprecationWarning`, :exc:`PendingDeprecationWarning` and - :exc:`ImportWarning` warnings are now displayed by default. - -- bpo-1647489: Fixed searching regular expression patterns that could match - an empty string. Non-empty string can now be correctly found after - matching an empty string. - -- bpo-25054: Added support of splitting on a pattern that could match an - empty string. - -- 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-32069: Drop legacy SSL transport from asyncio, ssl.MemoryBIO is always - used anyway. - -- bpo-32066: asyncio: Support pathlib.Path in create_unix_connection; sock - arg should be optional - -- bpo-32046: Updates 2to3 to convert from operator.isCallable(obj) to - callable(obj). Patch by Dong-hee Na. - -- bpo-32018: inspect.signature should follow :pep:`8`, if the parameter has - an annotation and a default value. Patch by Dong-hee Na. - -- bpo-32025: Add time.thread_time() and time.thread_time_ns() - -- bpo-32037: Integers that fit in a signed 32-bit integer will be now - pickled with protocol 0 using the INT opcode. This will decrease the size - of a pickle, speed up pickling and unpickling, and make these integers be - unpickled as int instances in Python 2. - -- 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-28369: Enhance add_reader/writer check that socket is not used by some - transport. Before, only cases when add_reader/writer were called with an - int FD were supported. Now the check is implemented correctly for all - file-like objects. - -- bpo-31976: Fix race condition when flushing a file is slow, which can - cause a segfault if closing the file from another thread. - -- bpo-31985: Formally deprecated aifc.openfp, sunau.openfp, and wave.openfp. - Since change 7bc817d5ba917528e8bd07ec461c635291e7b06a in 1993, openfp in - each of the three modules had been pointing to that module's open function - as a matter of backwards compatibility, though it had been both untested - and undocumented. - -- bpo-21862: cProfile command line now accepts `-m module_name` as an - alternative to script path. Patch by Sanyam Khurana. - -- bpo-31970: Reduce performance overhead of asyncio debug mode. - -- bpo-31843: *database* argument of sqlite3.connect() now accepts a - :term:`path-like object`, instead of just a string. - -- bpo-31945: Add Configurable *blocksize* to ``HTTPConnection`` and - ``HTTPSConnection`` for improved upload throughput. Patch by Nir Soffer. - -- bpo-31943: Add a ``cancelled()`` method to :class:`asyncio.Handle`. Patch - by Marat Sharafutdinov. - -- 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-21423: Add an initializer argument to {Process,Thread}PoolExecutor - -- 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-31917: Add 3 new clock identifiers: :data:`time.CLOCK_BOOTTIME`, - :data:`time.CLOCK_PROF` and :data:`time.CLOCK_UPTIME`. - -- 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-31884: added required constants to subprocess module for setting - priority on windows - -- bpo-28281: Remove year (1-9999) limits on the Calendar.weekday() function. - Patch by Mark Gollahon. - -- bpo-31702: crypt.mksalt() now allows to specify the number of rounds for - SHA-256 and SHA-512 hashing. - -- bpo-30639: :func:`inspect.getfile` no longer computes the repr of unknown - objects to display in an error message, to protect against badly behaved - custom reprs. - -- bpo-30768: Fix the pthread+semaphore implementation of - PyThread_acquire_lock_timed() when called with timeout > 0 and - intr_flag=0: recompute the timeout if sem_timedwait() is interrupted by a - signal (EINTR). See also the :pep:`475`. - -- bpo-31854: Add ``mmap.ACCESS_DEFAULT`` constant. - -- bpo-31834: Use optimized code for BLAKE2 only with SSSE3+. The pure SSE2 - implementation is slower than the pure C reference implementation. - -- bpo-28292: Calendar.itermonthdates() will now consistently raise an - exception when a date falls outside of the 0001-01-01 through 9999-12-31 - range. To support applications that cannot tolerate such exceptions, the - new methods itermonthdays3() and itermonthdays4() are added. The new - methods return tuples and are not restricted by the range supported by - datetime.date. - -- bpo-28564: The shutil.rmtree() function has been sped up to 20--40%. This - was done using the os.scandir() function. - -- 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-31653: Don't release the GIL if we can acquire a multiprocessing - semaphore immediately. - -- bpo-28326: Fix multiprocessing.Process when stdout and/or stderr is closed - or None. - -- bpo-20825: Add `subnet_of` and `superset_of` containment tests to - :class:`ipaddress.IPv6Network` and :class:`ipaddress.IPv4Network`. Patch - by Michel Albert and Cheryl Sabella. - -- bpo-31827: Remove the os.stat_float_times() function. It was introduced in - Python 2.3 for backward compatibility with Python 2.2, and was deprecated - since Python 3.1. - -- bpo-31756: Add a ``subprocess.Popen(text=False)`` keyword argument to - `subprocess` functions to be more explicit about when the library should - attempt to decode outputs into text. Patch by Andrew Clegg. - -- bpo-31819: Add AbstractEventLoop.sock_recv_into(). - -- 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-31803: time.clock() and time.get_clock_info('clock') now emit a - DeprecationWarning warning. - -- bpo-31800: Extended support for parsing UTC offsets. strptime '%z' can now - parse the output generated by datetime.isoformat, including seconds and - microseconds. - -- 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-30541: Add new function to seal a mock and prevent the automatically - creation of child mocks. Patch by Mario Corchero. - -- bpo-31784: Implement the :pep:`564`, add new 6 new functions with - nanosecond resolution to the :mod:`time` module: - :func:`~time.clock_gettime_ns`, :func:`~time.clock_settime_ns`, - :func:`~time.monotonic_ns`, :func:`~time.perf_counter_ns`, - :func:`~time.process_time_ns`, :func:`~time.time_ns`. - -- bpo-30143: 2to3 now generates a code that uses abstract collection classes - from collections.abc rather than collections. - -- bpo-31770: Prevent a crash when calling the ``__init__()`` method of a - ``sqlite3.Cursor`` object more than once. Patch by Oren Milman. - -- 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-31620: an empty asyncio.Queue now doesn't leak memory when queue.get - pollers timeout - -- bpo-31690: Allow the flags re.ASCII, re.LOCALE, and re.UNICODE to be used - as group flags for regular expressions. - -- bpo-30349: FutureWarning is now emitted if a regular expression contains - character set constructs that will change semantically in the future - (nested sets and set operations). - -- bpo-31664: Added support for the Blowfish hashing in the crypt module. - -- bpo-31632: Fix method set_protocol() of class _SSLProtocolTransport in - asyncio module. This method was previously modifying a wrong reference to - the protocol. - -- bpo-15037: Added a workaround for getkey() in curses for ncurses 5.7 and - earlier. - -- bpo-31307: Allow use of bytes objects for arguments to - :meth:`configparser.ConfigParser.read`. Patch by Vincent Michel. - -- 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. - -- bpo-31245: Added support for AF_UNIX socket in asyncio - `create_datagram_endpoint`. - -- bpo-30553: Add HTTP/2 status code 421 (Misdirected Request) to - :class:`http.HTTPStatus`. Patch by Vitor Pereira. - -Documentation -------------- - -- bpo-32105: Added asyncio.BaseEventLoop.connect_accepted_socket - versionadded marker. - -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-32138: Skip on Android test_faulthandler tests that raise SIGSEGV and - remove the test.support.requires_android_level decorator. - -- bpo-32136: The runtime embedding tests have been split out from - ``Lib/test/test_capi.py`` into a new ``Lib/test/test_embed.py`` file. - -- bpo-28668: test.support.requires_multiprocessing_queue is removed. Skip - tests with test.support.import_module('multiprocessing.synchronize') - instead when the semaphore implementation is broken or missing. - -- bpo-32126: Skip test_get_event_loop_new_process in - test.test_asyncio.test_events when sem_open() is not functional. - -- 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. - -Build ------ - -- bpo-28538: Revert the previous changes, the if_nameindex structure is - defined by Unified Headers. - -- bpo-28762: Revert the last commit, the F_LOCK macro is defined by Android - Unified Headers. - -- bpo-29040: Support building Android with Unified Headers. The first NDK - release to support Unified Headers is android-ndk-r14. - -- 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-28643: Record profile-opt build progress with stamp files. - -- bpo-31866: Finish removing support for AtheOS. - -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. - -- bpo-20486: Implement the ``Database.Close()`` method to help closing MSI - database objects. - -- bpo-31857: Make the behavior of USE_STACKCHECK deterministic in a - multi-threaded environment. - -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 manipulation 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. - -Tools/Demos ------------ - -- bpo-32159: Remove CVS and Subversion tools: remove svneol.py and - treesync.py scripts. CPython migrated from CVS to Subversion, to - Mercurial, and then to Git. CVS and Subversion are no longer used to - develop CPython. - -- bpo-30722: Make redemo work with Python 3.6 and newer versions. 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-32125: The ``Py_UseClassExceptionsFlag`` flag has been removed. It was - deprecated and wasn't used anymore since Python 2.0. - -- bpo-25612: Move the current exception state from the frame object to the - co-routine. This simplifies the interpreter and fixes a couple of obscure - bugs caused by having swap exception state when entering or exiting a - generator. - -- bpo-23699: Add Py_RETURN_RICHCOMPARE macro to reduce boilerplate code in - rich comparison functions. - -- 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.7.0 alpha 2? -=================================== - -*Release date: 2017-10-16* - -Core and Builtins ------------------ - -- bpo-31558: ``gc.freeze()`` is a new API that allows for moving all objects - currently tracked by the garbage collector to a permanent generation, - effectively removing them from future collection events. This can be used - to protect those objects from having their PyGC_Head mutated. In effect, - this enables great copy-on-write stability at fork(). - -- bpo-31642: Restored blocking "from package import module" by setting - sys.modules["package.module"] to None. - -- bpo-31708: Allow use of asynchronous generator expressions in synchronous - functions. - -- bpo-31709: Drop support of asynchronous __aiter__. - -- bpo-30404: The -u option now makes the stdout and stderr streams - unbuffered rather than line-buffered. - -- bpo-31619: Fixed a ValueError when convert a string with large number of - underscores to integer with binary base. - -- bpo-31602: Fix an assertion failure in `zipimporter.get_source()` in case - of a bad `zlib.decompress()`. Patch by Oren Milman. - -- 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-31574: Importlib was instrumented with two dtrace probes to profile - import timing. - -- bpo-31566: Fix an assertion failure in `_warnings.warn()` in case of a bad - ``__name__`` global. Patch by Oren Milman. - -- bpo-31506: Improved the error message logic for object.__new__ and - object.__init__. - -- 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-31478: Fix an assertion failure in `_random.Random.seed()` in case the - argument has a bad ``__abs__()`` method. Patch by Oren Milman. - -- bpo-31336: Speed up class creation by 10-20% by reducing the overhead in - the necessary special method lookups. Patch by Stefan Behnel. - -- bpo-31415: Add ``-X importtime`` option to show how long each import - takes. It can be used to optimize application's startup time. Support the - :envvar:`PYTHONPROFILEIMPORTTIME` as an equivalent way to enable this. - -- bpo-31410: Optimized calling wrapper and classmethod descriptors. - -- bpo-31353: :pep:`553` - Add a new built-in called ``breakpoint()`` which - calls ``sys.breakpointhook()``. By default this imports ``pdb`` and calls - ``pdb.set_trace()``, but users may override ``sys.breakpointhook()`` to - call whatever debugger they want. The original value of the hook is saved - in ``sys.__breakpointhook__``. - -- bpo-17852: Maintain a list of open buffered files, flush them before - exiting the interpreter. Based on a patch from Armin Rigo. - -- 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-30406: Make ``async`` and ``await`` proper keywords, as specified in - :pep:`492`. - -Library -------- - -- bpo-30058: Fixed buffer overflow in select.kqueue.control(). - -- 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-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-31671: Now ``re.compile()`` converts passed RegexFlag to normal int - object before compiling. bm_regex_compile benchmark shows 14% performance - improvements. - -- bpo-30397: The types of compiled regular objects and match objects are now - exposed as `re.Pattern` and `re.Match`. This adds information in pydoc - output for the re module. - -- 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-31648: Improvements to path predicates in ElementTree: Allow - whitespace around predicate parts, i.e. "[a = 'text']" instead of - requiring the less readable "[a='text']". Add support for text comparison - of the current node, like "[.='text']". Patch by Stefan Behnel. - -- bpo-30806: Fix the string representation of a netrc object. - -- bpo-31638: Add optional argument ``compressed`` to - ``zipapp.create_archive``, and add option ``--compress`` to the command - line interface of ``zipapp``. - -- bpo-25351: Avoid venv activate failures with undefined variables - -- bpo-20519: Avoid ctypes use (if possible) and improve import time for - uuid. - -- bpo-28293: The regular expression cache is no longer completely dumped - when it is full. - -- bpo-31596: Added pthread_getcpuclockid() to the time module - -- bpo-27494: Make 2to3 accept a trailing comma in generator expressions. For - example, ``set(x for x in [],)`` is now allowed. - -- bpo-30347: Stop crashes when concurrently iterate over itertools.groupby() - iterators. - -- bpo-30346: An iterator produced by itertools.groupby() iterator now - becomes exhausted after advancing the groupby iterator. - -- bpo-31556: Cancel asyncio.wait_for future faster if timeout <= 0 - -- bpo-31540: Allow passing a context object in - :class:`concurrent.futures.ProcessPoolExecutor` constructor. Also, free - job resources in :class:`concurrent.futures.ProcessPoolExecutor` earlier - to improve memory usage when a worker waits for new jobs. - -- bpo-31516: ``threading.current_thread()`` should not return a dummy thread - at shutdown. - -- bpo-31525: In the sqlite module, require the sqlite3_prepare_v2 API. Thus, - the sqlite module now requires sqlite version at least 3.3.9. - -- bpo-26510: argparse subparsers are now required by default. This matches - behaviour in Python 2. For optional subparsers, use the new parameter - ``add_subparsers(required=False)``. Patch by Anthony Sottile. (As of - 3.7.0rc1, the default was changed to not required as had been the case - since Python 3.3.) - -- bpo-27541: Reprs of subclasses of some collection and iterator classes - (`bytearray`, `array.array`, `collections.deque`, - `collections.defaultdict`, `itertools.count`, `itertools.repeat`) now - contain actual type name insteads of hardcoded name of the base class. - -- bpo-31351: python -m ensurepip now exits with non-zero exit code if pip - bootstrapping has failed. - -- bpo-31389: ``pdb.set_trace()`` now takes an optional keyword-only argument - ``header``. If given, this is printed to the console just before debugging - begins. - -Documentation -------------- - -- 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. - -Build ------ - -- bpo-31696: Improve compiler version information in :data:`sys.version` - when Python is built with Clang. - -- bpo-31625: Stop using ranlib on static libraries. Instead, we assume ar - supports the 's' flag. - -- bpo-31624: Remove support for BSD/OS. - -- bpo-22140: Prevent double substitution of prefix in python-config.sh. - -- bpo-31569: Correct PCBuild/ case to PCbuild/ in build scripts and - documentation. - -- bpo-31536: Avoid wholesale rebuild after `make regen-all` if nothing - changed. - -IDLE ----- - -- 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. - -C API ------ - -- bpo-28280: Make `PyMapping_Keys()`, `PyMapping_Values()` and - `PyMapping_Items()` always return a `list` (rather than a `list` or a - `tuple`). Patch by Oren Milman. - -- bpo-31532: Fix memory corruption due to allocator mix in getpath.c between - Py_GetPath() and Py_SetPath() - -- bpo-25658: Implement :pep:`539` for Thread Specific Storage (TSS) API: it - is a new Thread Local Storage (TLS) API to CPython which would supersede - use of the existing TLS API within the CPython interpreter, while - deprecating the existing API. PEP written by Erik M. Bray, patch by - Masayuki Yamamoto. - - -What's New in Python 3.7.0 alpha 1? -=================================== - -*Release date: 2017-09-19* - -Security --------- - -- bpo-29781: SSLObject.version() now correctly returns None when handshake - over BIO has not been performed yet. - -- bpo-29505: Add fuzz tests for float(str), int(str), unicode(str); for - oss-fuzz. - -- bpo-30947: Upgrade libexpat embedded copy from version 2.2.1 to 2.2.3 to - get security fixes. - -- bpo-30730: Prevent environment variables injection in subprocess on - Windows. Prevent passing other environment variables and command - arguments. - -- bpo-30694: Upgrade expat copy from 2.2.0 to 2.2.1 to get fixes of multiple - security vulnerabilities including: CVE-2017-9233 (External entity - infinite loop DoS), CVE-2016-9063 (Integer overflow, re-fix), - CVE-2016-0718 (Fix regression bugs from 2.2.0's fix to CVE-2016-0718) and - CVE-2012-0876 (Counter hash flooding with SipHash). Note: the - CVE-2016-5300 (Use os-specific entropy sources like getrandom) doesn't - impact Python, since Python already gets entropy from the OS to set the - expat secret using ``XML_SetHashSalt()``. - -- bpo-30500: Fix urllib.parse.splithost() to correctly parse fragments. For - example, ``splithost('//127.0.0.1#@evil.com/')`` now correctly returns the - ``127.0.0.1`` host, instead of treating ``@evil.com`` as the host in an - authentication (``login@host``). - -- bpo-29591: Update expat copy from 2.1.1 to 2.2.0 to get fixes of - CVE-2016-0718 and CVE-2016-4472. See - https://sourceforge.net/p/expat/bugs/537/ for more information. - -Core and Builtins ------------------ - -- 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-31471: Fix an assertion failure in `subprocess.Popen()` on Windows, in - case the env argument has a bad keys() method. Patch by Oren Milman. - -- bpo-31418: Fix an assertion failure in `PyErr_WriteUnraisable()` in case - of an exception with a bad ``__module__`` attribute. Patch by Oren Milman. - -- bpo-31416: Fix assertion failures in case of a bad warnings.filters or - warnings.defaultaction. Patch by Oren Milman. - -- bpo-28411: Change direct usage of PyInterpreterState.modules to - PyImport_GetModuleDict(). Also introduce more uniformity in other code - that deals with sys.modules. This helps reduce complications when working - on sys.modules. - -- bpo-28411: Switch to the abstract API when dealing with - ``PyInterpreterState.modules``. This allows later support for all dict - subclasses and other Mapping implementations. Also add a - ``PyImport_GetModule()`` function to reduce a bunch of duplicated code. - -- bpo-31411: Raise a TypeError instead of SystemError in case - warnings.onceregistry is not a dictionary. Patch by Oren Milman. - -- bpo-31344: For finer control of tracing behaviour when testing the - interpreter, two new frame attributes have been added to control the - emission of particular trace events: ``f_trace_lines`` (``True`` by - default) to turn off per-line trace events; and ``f_trace_opcodes`` - (``False`` by default) to turn on per-opcode trace events. - -- bpo-31373: Fix several possible instances of undefined behavior due to - floating-point demotions. - -- bpo-30465: Location information (``lineno`` and ``col_offset``) in - f-strings is now (mostly) correct. This fixes tools like flake8 from - showing warnings on the wrong line (typically the first line of the file). - -- bpo-30860: Consolidate CPython's global runtime state under a single - struct. This improves discoverability of the runtime state. - -- bpo-31347: Fix possible undefined behavior in _PyObject_FastCall_Prepend. - -- bpo-31343: Include sys/sysmacros.h for major(), minor(), and makedev(). - GNU C libray plans to remove the functions from sys/types.h. - -- bpo-31291: Fix an assertion failure in `zipimport.zipimporter.get_data` on - Windows, when the return value of ``pathname.replace('/','\\')`` isn't a - string. Patch by Oren Milman. - -- bpo-31271: Fix an assertion failure in the write() method of - `io.TextIOWrapper`, when the encoder doesn't return a bytes object. Patch - by Oren Milman. - -- bpo-31243: Fix a crash in some methods of `io.TextIOWrapper`, when the - decoder's state is invalid. Patch by Oren Milman. - -- bpo-30721: ``print`` now shows correct usage hint for using Python 2 - redirection syntax. Patch by Sanyam Khurana. - -- bpo-31070: Fix a race condition in importlib _get_module_lock(). - -- bpo-30747: Add a non-dummy implementation of _Py_atomic_store and - _Py_atomic_load on MSVC. - -- bpo-31095: Fix potential crash during GC caused by ``tp_dealloc`` which - doesn't call ``PyObject_GC_UnTrack()``. - -- bpo-31071: Avoid masking original TypeError in call with * unpacking when - other arguments are passed. - -- bpo-30978: str.format_map() now passes key lookup exceptions through. - Previously any exception was replaced with a KeyError exception. - -- bpo-30808: Use _Py_atomic API for concurrency-sensitive signal state. - -- bpo-30876: Relative import from unloaded package now reimports the package - instead of failing with SystemError. Relative import from non-package now - fails with ImportError rather than SystemError. - -- bpo-30703: Improve signal delivery. Avoid using Py_AddPendingCall from - signal handler, to avoid calling signal-unsafe functions. The tests I'm - adding here fail without the rest of the patch, on Linux and OS X. This - means our signal delivery logic had defects (some signals could be lost). - -- bpo-30765: Avoid blocking in pthread_mutex_lock() when - PyThread_acquire_lock() is asked not to block. - -- bpo-31161: Make sure the 'Missing parentheses' syntax error message is - only applied to SyntaxError, not to subclasses. Patch by Martijn Pieters. - -- bpo-30814: Fixed a race condition when import a submodule from a package. - -- bpo-30736: The internal unicodedata database has been upgraded to Unicode - 10.0. - -- bpo-30604: Move co_extra_freefuncs from per-thread to per-interpreter to - avoid crashes. - -- bpo-30597: ``print`` now shows expected input in custom error message when - used as a Python 2 statement. Patch by Sanyam Khurana. - -- bpo-30682: Removed a too-strict assertion that failed for certain - f-strings, such as eval("f'\\\n'") and eval("f'\\\r'"). - -- bpo-30501: The compiler now produces more optimal code for complex - condition expressions in the "if", "while" and "assert" statement, the - "if" expression, and generator expressions and comprehensions. - -- bpo-28180: Implement :pep:`538` (legacy C locale coercion). This means - that when a suitable coercion target locale is available, both the core - interpreter and locale-aware C extensions will assume the use of UTF-8 as - the default text encoding, rather than ASCII. - -- bpo-30486: Allows setting cell values for __closure__. Patch by Lisa - Roach. - -- bpo-30537: itertools.islice now accepts integer-like objects (having an - __index__ method) as start, stop, and slice arguments - -- bpo-25324: Tokens needed for parsing in Python moved to C. ``COMMENT``, - ``NL`` and ``ENCODING``. This way the tokens and tok_names in the token - module don't get changed when you import the tokenize module. - -- bpo-29104: Fixed parsing backslashes in f-strings. - -- bpo-27945: Fixed various segfaults with dict when input collections are - mutated during searching, inserting or comparing. Based on patches by - Duane Griffin and Tim Mitchell. - -- bpo-25794: Fixed type.__setattr__() and type.__delattr__() for - non-interned attribute names. Based on patch by Eryk Sun. - -- bpo-30039: If a KeyboardInterrupt happens when the interpreter is in the - middle of resuming a chain of nested 'yield from' or 'await' calls, it's - now correctly delivered to the innermost frame. - -- bpo-28974: ``object.__format__(x, '')`` is now equivalent to ``str(x)`` - rather than ``format(str(self), '')``. - -- bpo-30024: Circular imports involving absolute imports with binding a - submodule to a name are now supported. - -- bpo-12414: sys.getsizeof() on a code object now returns the sizes which - includes the code struct and sizes of objects which it references. Patch - by Dong-hee Na. - -- bpo-29839: len() now raises ValueError rather than OverflowError if - __len__() returned a large negative integer. - -- bpo-11913: README.rst is now included in the list of distutils standard - READMEs and therefore included in source distributions. - -- bpo-29914: Fixed default implementations of __reduce__ and - __reduce_ex__(). object.__reduce__() no longer takes arguments, - object.__reduce_ex__() now requires one argument. - -- bpo-29949: Fix memory usage regression of set and frozenset object. - -- bpo-29935: Fixed error messages in the index() method of tuple, list and - deque when pass indices of wrong type. - -- bpo-29816: Shift operation now has less opportunity to raise - OverflowError. ValueError always is raised rather than OverflowError for - negative counts. Shifting zero with non-negative count always returns - zero. - -- bpo-24821: Fixed the slowing down to 25 times in the searching of some - unlucky Unicode characters. - -- bpo-29102: Add a unique ID to PyInterpreterState. This makes it easier to - identify each subinterpreter. - -- bpo-29894: The deprecation warning is emitted if __complex__ returns an - instance of a strict subclass of complex. In a future versions of Python - this can be an error. - -- bpo-29859: Show correct error messages when any of the pthread_* calls in - thread_pthread.h fails. - -- bpo-29849: Fix a memory leak when an ImportError is raised during from - import. - -- bpo-28856: Fix an oversight that %b format for bytes should support - objects follow the buffer protocol. - -- bpo-29723: The ``sys.path[0]`` initialization change for bpo-29139 caused - a regression by revealing an inconsistency in how sys.path is initialized - when executing ``__main__`` from a zipfile, directory, or other import - location. The interpreter now consistently avoids ever adding the import - location's parent directory to ``sys.path``, and ensures no other - ``sys.path`` entries are inadvertently modified when inserting the import - location named on the command line. - -- bpo-29568: Escaped percent "%%" in the format string for classic string - formatting no longer allows any characters between two percents. - -- bpo-29714: Fix a regression that bytes format may fail when containing - zero bytes inside. - -- bpo-29695: bool(), float(), list() and tuple() no longer take keyword - arguments. The first argument of int() can now be passes only as - positional argument. - -- bpo-28893: Set correct __cause__ for errors about invalid awaitables - returned from __aiter__ and __anext__. - -- bpo-28876: ``bool(range)`` works even if ``len(range)`` raises - :exc:`OverflowError`. - -- bpo-29683: Fixes to memory allocation in _PyCode_SetExtra. Patch by Brian - Coleman. - -- bpo-29684: Fix minor regression of PyEval_CallObjectWithKeywords. It - should raise TypeError when kwargs is not a dict. But it might cause segv - when args=NULL and kwargs is not a dict. - -- bpo-28598: Support __rmod__ for subclasses of str being called before - str.__mod__. Patch by Martijn Pieters. - -- bpo-29607: Fix stack_effect computation for CALL_FUNCTION_EX. Patch by - Matthieu Dartiailh. - -- bpo-29602: Fix incorrect handling of signed zeros in complex constructor - for complex subclasses and for inputs having a __complex__ method. Patch - by Serhiy Storchaka. - -- bpo-29347: Fixed possibly dereferencing undefined pointers when creating - weakref objects. - -- bpo-29463: Add ``docstring`` field to Module, ClassDef, FunctionDef, and - AsyncFunctionDef ast nodes. docstring is not first stmt in their body - anymore. It affects ``co_firstlineno`` and ``co_lnotab`` of code object - for module and class. (Reverted in :issue:`32911`.) - -- bpo-29438: Fixed use-after-free problem in key sharing dict. - -- bpo-29546: Set the 'path' and 'name' attribute on ImportError for ``from - ... import ...``. - -- bpo-29546: Improve from-import error message with location - -- bpo-29478: If max_line_length=None is specified while using the Compat32 - policy, it is no longer ignored. Patch by Mircea Cosbuc. - -- bpo-29319: Prevent RunMainFromImporter overwriting sys.path[0]. - -- bpo-29337: Fixed possible BytesWarning when compare the code objects. - Warnings could be emitted at compile time. - -- bpo-29327: Fixed a crash when pass the iterable keyword argument to - sorted(). - -- bpo-29034: Fix memory leak and use-after-free in os module - (path_converter). - -- bpo-29159: Fix regression in bytes(x) when x.__index__() raises Exception. - -- bpo-29049: Call _PyObject_GC_TRACK() lazily when calling Python function. - Calling function is up to 5% faster. - -- bpo-28927: bytes.fromhex() and bytearray.fromhex() now ignore all ASCII - whitespace, not only spaces. Patch by Robert Xiao. - -- bpo-28932: Do not include <sys/random.h> if it does not exist. - -- bpo-25677: Correct the positioning of the syntax error caret for indented - blocks. Based on patch by Michael Layzell. - -- bpo-29000: Fixed bytes formatting of octals with zero padding in alternate - form. - -- bpo-18896: Python function can now have more than 255 parameters. - collections.namedtuple() now supports tuples with more than 255 elements. - -- bpo-28596: The preferred encoding is UTF-8 on Android. Patch written by - Chi Hsuan Yen. - -- bpo-22257: Clean up interpreter startup (see :pep:`432`). - -- bpo-26919: On Android, operating system data is now always encoded/decoded - to/from UTF-8, instead of the locale encoding to avoid inconsistencies - with os.fsencode() and os.fsdecode() which are already using UTF-8. - -- bpo-28991: functools.lru_cache() was susceptible to an obscure reentrancy - bug triggerable by a monkey-patched len() function. - -- bpo-28147: Fix a memory leak in split-table dictionaries: setattr() must - not convert combined table into split table. Patch written by INADA Naoki. - -- bpo-28739: f-string expressions are no longer accepted as docstrings and - by ast.literal_eval() even if they do not include expressions. - -- bpo-28512: Fixed setting the offset attribute of SyntaxError by - PyErr_SyntaxLocationEx() and PyErr_SyntaxLocationObject(). - -- bpo-28918: Fix the cross compilation of xxlimited when Python has been - built with Py_DEBUG defined. - -- bpo-23722: Rather than silently producing a class that doesn't support - zero-argument ``super()`` in methods, failing to pass the new - ``__classcell__`` namespace entry up to ``type.__new__`` now results in a - ``DeprecationWarning`` and a class that supports zero-argument - ``super()``. - -- bpo-28797: Modifying the class __dict__ inside the __set_name__ method of - a descriptor that is used inside that class no longer prevents calling the - __set_name__ method of other descriptors. - -- bpo-28799: Remove the ``PyEval_GetCallStats()`` function and deprecate the - untested and undocumented ``sys.callstats()`` function. Remove the - ``CALL_PROFILE`` special build: use the :func:`sys.setprofile` function, - :mod:`cProfile` or :mod:`profile` to profile function calls. - -- bpo-12844: More than 255 arguments can now be passed to a function. - -- bpo-28782: Fix a bug in the implementation ``yield from`` when checking if - the next instruction is YIELD_FROM. Regression introduced by WORDCODE - (issue #26647). - -- bpo-28774: Fix error position of the unicode error in ASCII and Latin1 - encoders when a string returned by the error handler contains multiple - non-encodable characters (non-ASCII for the ASCII codec, characters out of - the U+0000-U+00FF range for Latin1). - -- bpo-28731: Optimize _PyDict_NewPresized() to create correct size dict. - Improve speed of dict literal with constant keys up to 30%. - -- bpo-28532: Show sys.version when -V option is supplied twice. - -- bpo-27100: The with-statement now checks for __enter__ before it checks - for __exit__. This gives less confusing error messages when both methods - are missing. Patch by Jonathan Ellington. - -- bpo-28746: Fix the set_inheritable() file descriptor method on platforms - that do not have the ioctl FIOCLEX and FIONCLEX commands. - -- bpo-26920: Fix not getting the locale's charset upon initializing the - interpreter, on platforms that do not have langinfo. - -- bpo-28648: Fixed crash in Py_DecodeLocale() in debug build on Mac OS X - when decode astral characters. Patch by Xiang Zhang. - -- bpo-28665: Improve speed of the STORE_DEREF opcode by 40%. - -- bpo-19398: Extra slash no longer added to sys.path components in case of - empty compile-time PYTHONPATH components. - -- bpo-28621: Sped up converting int to float by reusing faster bits counting - implementation. Patch by Adrian Wielgosik. - -- bpo-28580: Optimize iterating split table values. Patch by Xiang Zhang. - -- bpo-28583: PyDict_SetDefault didn't combine split table when needed. Patch - by Xiang Zhang. - -- bpo-28128: Deprecation warning for invalid str and byte escape sequences - now prints better information about where the error occurs. Patch by - Serhiy Storchaka and Eric Smith. - -- bpo-28509: dict.update() no longer allocate unnecessary large memory. - -- bpo-28426: Fixed potential crash in PyUnicode_AsDecodedObject() in debug - build. - -- bpo-28517: Fixed of-by-one error in the peephole optimizer that caused - keeping unreachable code. - -- bpo-28214: Improved exception reporting for problematic __set_name__ - attributes. - -- bpo-23782: Fixed possible memory leak in _PyTraceback_Add() and exception - loss in PyTraceBack_Here(). - -- bpo-28183: Optimize and cleanup dict iteration. - -- bpo-26081: Added C implementation of asyncio.Future. Original patch by - Yury Selivanov. - -- bpo-28379: Added sanity checks and tests for PyUnicode_CopyCharacters(). - Patch by Xiang Zhang. - -- bpo-28376: The type of long range iterator is now registered as Iterator. - Patch by Oren Milman. - -- bpo-28376: Creating instances of range_iterator by calling range_iterator - type now is disallowed. Calling iter() on range instance is the only way. - Patch by Oren Milman. - -- bpo-26906: Resolving special methods of uninitialized type now causes - implicit initialization of the type instead of a fail. - -- bpo-18287: PyType_Ready() now checks that tp_name is not NULL. Original - patch by Niklas Koep. - -- bpo-24098: Fixed possible crash when AST is changed in process of - compiling it. - -- bpo-28201: Dict reduces possibility of 2nd conflict in hash table when - hashes have same lower bits. - -- bpo-28350: String constants with null character no longer interned. - -- bpo-26617: Fix crash when GC runs during weakref callbacks. - -- bpo-27942: String constants now interned recursively in tuples and - frozensets. - -- bpo-28289: ImportError.__init__ now resets not specified attributes. - -- bpo-21578: Fixed misleading error message when ImportError called with - invalid keyword args. - -- bpo-28203: Fix incorrect type in complex(1.0, {2:3}) error message. Patch - by Soumya Sharma. - -- bpo-28086: Single var-positional argument of tuple subtype was passed - unscathed to the C-defined function. Now it is converted to exact tuple. - -- bpo-28214: Now __set_name__ is looked up on the class instead of the - instance. - -- bpo-27955: Fallback on reading /dev/urandom device when the getrandom() - syscall fails with EPERM, for example when blocked by SECCOMP. - -- bpo-28192: Don't import readline in isolated mode. - -- bpo-27441: Remove some redundant assignments to ob_size in longobject.c. - Thanks Oren Milman. - -- bpo-27222: Clean up redundant code in long_rshift function. Thanks Oren - Milman. - -- Upgrade internal unicode databases to Unicode version 9.0.0. - -- bpo-28131: Fix a regression in zipimport's compile_source(). zipimport - should use the same optimization level as the interpreter. - -- bpo-28126: Replace Py_MEMCPY with memcpy(). Visual Studio can properly - optimize memcpy(). - -- bpo-28120: Fix dict.pop() for splitted dictionary when trying to remove a - "pending key" (Not yet inserted in split-table). Patch by Xiang Zhang. - -- bpo-26182: Raise DeprecationWarning when async and await keywords are used - as variable/attribute/class/function name. - -- bpo-26182: Fix a refleak in code that raises DeprecationWarning. - -- bpo-28721: Fix asynchronous generators aclose() and athrow() to handle - StopAsyncIteration propagation properly. - -- bpo-26110: Speed-up method calls: add LOAD_METHOD and CALL_METHOD opcodes. - -Library -------- - -- bpo-31499: xml.etree: Fix a crash when a parser is part of a reference - cycle. - -- bpo-31482: ``random.seed()`` now works with bytes in version=1 - -- bpo-28556: typing.get_type_hints now finds the right globalns for classes - and modules by default (when no ``globalns`` was specified by the caller). - -- bpo-28556: Speed improvements to the ``typing`` module. Original PRs by - Ivan Levkivskyi and Mitar. - -- bpo-31544: The C accelerator module of ElementTree ignored exceptions - raised when looking up TreeBuilder target methods in XMLParser(). - -- bpo-31234: socket.create_connection() now fixes manually a reference - cycle: clear the variable storing the last exception on success. - -- bpo-31457: LoggerAdapter objects can now be nested. - -- bpo-31431: SSLContext.check_hostname now automatically sets - SSLContext.verify_mode to ssl.CERT_REQUIRED instead of failing with a - ValueError. - -- bpo-31233: socketserver.ThreadingMixIn now keeps a list of non-daemonic - threads to wait until all these threads complete in server_close(). - -- bpo-28638: Changed the implementation strategy for - collections.namedtuple() to substantially reduce the use of exec() in - favor of precomputed methods. As a result, the *verbose* parameter and - *_source* attribute are no longer supported. The benefits include 1) - having a smaller memory footprint for applications using multiple named - tuples, 2) faster creation of the named tuple class (approx 4x to 6x - depending on how it is measured), and 3) minor speed-ups for instance - creation using __new__, _make, and _replace. (The primary patch - contributor is Jelle Zijlstra with further improvements by INADA Naoki, - Serhiy Storchaka, and Raymond Hettinger.) - -- bpo-31400: Improves SSL error handling to avoid losing error numbers. - -- bpo-27629: Make return types of SSLContext.wrap_bio() and - SSLContext.wrap_socket() customizable. - -- bpo-28958: ssl.SSLContext() now uses OpenSSL error information when a - context cannot be instantiated. - -- bpo-28182: The SSL module now raises SSLCertVerificationError when OpenSSL - fails to verify the peer's certificate. The exception contains more - information about the error. - -- bpo-27340: SSLSocket.sendall() now uses memoryview to create slices of - data. This fixes support for all bytes-like object. It is also more - efficient and avoids costly copies. - -- bpo-14191: A new function - ``argparse.ArgumentParser.parse_intermixed_args`` provides the ability to - parse command lines where there user intermixes options and positional - arguments. - -- bpo-31178: Fix string concatenation bug in rare error path in the - subprocess module - -- bpo-31350: Micro-optimize :func:`asyncio._get_running_loop` to become up - to 10% faster. - -- bpo-31170: expat: Update libexpat from 2.2.3 to 2.2.4. Fix copying of - partial characters for UTF-8 input (libexpat bug 115): - https://github.com/libexpat/libexpat/issues/115 - -- bpo-29136: Add TLS 1.3 cipher suites and OP_NO_TLSv1_3. - -- bpo-1198569: ``string.Template`` subclasses can optionally define - ``braceidpattern`` if they want to specify different placeholder patterns - inside and outside the braces. If None (the default) it falls back to - ``idpattern``. - -- bpo-31326: concurrent.futures.ProcessPoolExecutor.shutdown() now - explicitly closes the call queue. Moreover, shutdown(wait=True) now also - join the call queue thread, to prevent leaking a dangling thread. - -- bpo-27144: The ``map()`` and ``as_completed()`` iterators in - ``concurrent.futures`` now avoid keeping a reference to yielded objects. - -- bpo-31281: Fix ``fileinput.FileInput(files, inplace=True)`` when ``files`` - contain ``pathlib.Path`` objects. - -- bpo-10746: Fix ctypes producing wrong :pep:`3118` type codes for integer - types. - -- bpo-27584: ``AF_VSOCK`` has been added to the socket interface which - allows communication between virtual machines and their host. - -- bpo-22536: The subprocess module now sets the filename when - FileNotFoundError is raised on POSIX systems due to the executable or cwd - not being found. - -- bpo-29741: Update some methods in the _pyio module to also accept integer - types. Patch by Oren Milman. - -- bpo-31249: concurrent.futures: WorkItem.run() used by ThreadPoolExecutor - now breaks a reference cycle between an exception object and the WorkItem - object. - -- bpo-31247: xmlrpc.server now explicitly breaks reference cycles when using - sys.exc_info() in code handling exceptions. - -- bpo-23835: configparser: reading defaults in the ``ConfigParser()`` - constructor is now using ``read_dict()``, making its behavior consistent - with the rest of the parser. Non-string keys and values in the defaults - dictionary are now being implicitly converted to strings. Patch by James - Tocknell. - -- bpo-31238: pydoc: the stop() method of the private ServerThread class now - waits until DocServer.serve_until_quit() completes and then explicitly - sets its docserver attribute to None to break a reference cycle. - -- bpo-5001: Many asserts in `multiprocessing` are now more informative, and - some error types have been changed to more specific ones. - -- bpo-31109: Convert zipimport to use Argument Clinic. - -- bpo-30102: The ssl and hashlib modules now call - OPENSSL_add_all_algorithms_noconf() on OpenSSL < 1.1.0. The function - detects CPU features and enables optimizations on some CPU architectures - such as POWER8. Patch is based on research from Gustavo Serra Scalet. - -- bpo-18966: Non-daemonic threads created by a multiprocessing.Process are - now joined on child exit. - -- bpo-31183: `dis` now works with asynchronous generator and coroutine - objects. Patch by George Collins based on diagnosis by Luciano Ramalho. - -- bpo-5001: There are a number of uninformative asserts in the - `multiprocessing` module, as noted in issue 5001. This change fixes two of - the most potentially problematic ones, since they are in error-reporting - code, in the `multiprocessing.managers.convert_to_error` function. (It - also makes more informative a ValueError message.) The only potentially - problematic change is that the AssertionError is now a TypeError; however, - this should also help distinguish it from an AssertionError being - *reported* by the function/its caller (such as in issue 31169). - Patch by - Allen W. Smith (drallensmith on github). - -- bpo-31185: Fixed miscellaneous errors in asyncio speedup module. - -- bpo-31151: socketserver.ForkingMixIn.server_close() now waits until all - child processes completed to prevent leaking zombie processes. - -- bpo-31072: Add an ``include_file`` parameter to - ``zipapp.create_archive()`` - -- bpo-24700: Optimize array.array comparison. It is now from 10x up to 70x - faster when comparing arrays holding values of the same integer type. - -- bpo-31135: ttk: fix the destroy() method of LabeledScale and OptionMenu - classes. Call the parent destroy() method even if the used attribute - doesn't exist. The LabeledScale.destroy() method now also explicitly - clears label and scale attributes to help the garbage collector to destroy - all widgets. - -- bpo-31107: Fix `copyreg._slotnames()` mangled attribute calculation for - classes whose name begins with an underscore. Patch by Shane Harvey. - -- bpo-31080: Allow `logging.config.fileConfig` to accept kwargs and/or args. - -- bpo-30897: ``pathlib.Path`` objects now include an ``is_mount()`` method - (only implemented on POSIX). This is similar to ``os.path.ismount(p)``. - Patch by Cooper Ry Lees. - -- bpo-31061: Fixed a crash when using asyncio and threads. - -- bpo-30987: Added support for CAN ISO-TP protocol in the socket module. - -- bpo-30522: Added a ``setStream`` method to ``logging.StreamHandler`` to - allow the stream to be set after creation. - -- bpo-30502: Fix handling of long oids in ssl. Based on patch by Christian - Heimes. - -- bpo-5288: Support tzinfo objects with sub-minute offsets. - -- bpo-30919: Fix shared memory performance regression in multiprocessing in - 3.x. Shared memory used anonymous memory mappings in 2.x, while 3.x mmaps - actual files. Try to be careful to do as little disk I/O as possible. - -- bpo-26732: Fix too many fds in processes started with the "forkserver" - method. A child process would inherit as many fds as the number of - still-running children. - -- bpo-29403: Fix ``unittest.mock``'s autospec to not fail on method-bound - builtin functions. Patch by Aaron Gallagher. - -- bpo-30961: Fix decrementing a borrowed reference in tracemalloc. - -- bpo-19896: Fix multiprocessing.sharedctypes to recognize typecodes ``'q'`` - and ``'Q'``. - -- bpo-30946: Remove obsolete code in readline module for platforms where GNU - readline is older than 2.1 or where select() is not available. - -- bpo-25684: Change ``ttk.OptionMenu`` radiobuttons to be unique across - instances of ``OptionMenu``. - -- bpo-30886: Fix multiprocessing.Queue.join_thread(): it now waits until the - thread completes, even if the thread was started by the same process which - created the queue. - -- bpo-29854: Fix segfault in readline when using readline's history-size - option. Patch by Nir Soffer. - -- bpo-30794: Added multiprocessing.Process.kill method to terminate using - the SIGKILL signal on Unix. - -- bpo-30319: socket.close() now ignores ECONNRESET error. - -- bpo-30828: Fix out of bounds write in - `asyncio.CFuture.remove_done_callback()`. - -- bpo-30302: Use keywords in the ``repr`` of ``datetime.timedelta``. - -- bpo-30807: signal.setitimer() may disable the timer when passed a tiny - value. Tiny values (such as 1e-6) are valid non-zero values for - setitimer(), which is specified as taking microsecond-resolution - intervals. However, on some platform, our conversion routine could convert - 1e-6 into a zero interval, therefore disabling the timer instead of - (re-)scheduling it. - -- bpo-30441: Fix bug when modifying os.environ while iterating over it - -- bpo-29585: Avoid importing ``sysconfig`` from ``site`` to improve startup - speed. Python startup is about 5% faster on Linux and 30% faster on macOS. - -- bpo-29293: Add missing parameter "n" on - multiprocessing.Condition.notify(). The doc claims - multiprocessing.Condition behaves like threading.Condition, but its - notify() method lacked the optional "n" argument (to specify the number of - sleepers to wake up) that threading.Condition.notify() accepts. - -- bpo-30532: Fix email header value parser dropping folding white space in - certain cases. - -- bpo-30596: Add a ``close()`` method to ``multiprocessing.Process``. - -- bpo-9146: Fix a segmentation fault in _hashopenssl when standard hash - functions such as md5 are not available in the linked OpenSSL library. As - in some special FIPS-140 build environments. - -- bpo-29169: Update zlib to 1.2.11. - -- bpo-30119: ftplib.FTP.putline() now throws ValueError on commands that - contains CR or LF. Patch by Dong-hee Na. - -- bpo-30879: os.listdir() and os.scandir() now emit bytes names when called - with bytes-like argument. - -- bpo-30746: Prohibited the '=' character in environment variable names in - ``os.putenv()`` and ``os.spawn*()``. - -- bpo-30664: The description of a unittest subtest now preserves the order - of keyword arguments of TestCase.subTest(). - -- bpo-21071: struct.Struct.format type is now :class:`str` instead of - :class:`bytes`. - -- bpo-29212: Fix concurrent.futures.thread.ThreadPoolExecutor threads to - have a non repr() based thread name by default when no thread_name_prefix - is supplied. They will now identify themselves as - "ThreadPoolExecutor-y_n". - -- bpo-29755: Fixed the lgettext() family of functions in the gettext module. - They now always return bytes. - -- bpo-30616: Functional API of enum allows to create empty enums. Patched by - Dong-hee Na - -- bpo-30038: Fix race condition between signal delivery and wakeup file - descriptor. Patch by Nathaniel Smith. - -- bpo-23894: lib2to3 now recognizes ``rb'...'`` and ``f'...'`` strings. - -- bpo-24744: pkgutil.walk_packages function now raises ValueError if *path* - is a string. Patch by Sanyam Khurana. - -- bpo-24484: Avoid race condition in multiprocessing cleanup. - -- bpo-30589: Fix multiprocessing.Process.exitcode to return the opposite of - the signal number when the process is killed by a signal (instead of 255) - when using the "forkserver" method. - -- bpo-28994: The traceback no longer displayed for SystemExit raised in a - callback registered by atexit. - -- bpo-30508: Don't log exceptions if Task/Future "cancel()" method was - called. - -- bpo-30645: Fix path calculation in `imp.load_package()`, fixing it for - cases when a package is only shipped with bytecodes. Patch by Alexandru - Ardelean. - -- bpo-11822: The dis.dis() function now is able to disassemble nested code - objects. - -- bpo-30624: selectors does not take KeyboardInterrupt and SystemExit into - account, leaving a fd in a bad state in case of error. Patch by Giampaolo - Rodola'. - -- bpo-30595: multiprocessing.Queue.get() with a timeout now polls its reader - in non-blocking mode if it succeeded to acquire the lock but the acquire - took longer than the timeout. - -- bpo-28556: Updates to typing module: Add generic AsyncContextManager, add - support for ContextManager on all versions. Original PRs by Jelle Zijlstra - and Ivan Levkivskyi - -- bpo-30605: re.compile() no longer raises a BytesWarning when compiling a - bytes instance with misplaced inline modifier. Patch by Roy Williams. - -- bpo-29870: Fix ssl sockets leaks when connection is aborted in asyncio/ssl - implementation. Patch by Michaël Sghaïer. - -- bpo-29743: Closing transport during handshake process leaks open socket. - Patch by Nikolay Kim - -- bpo-27585: Fix waiter cancellation in asyncio.Lock. Patch by Mathieu - Sornay. - -- bpo-30014: modify() method of poll(), epoll() and devpoll() based classes - of selectors module is around 10% faster. Patch by Giampaolo Rodola'. - -- bpo-30418: On Windows, subprocess.Popen.communicate() now also ignore - EINVAL on stdin.write() if the child process is still running but closed - the pipe. - -- bpo-30463: Addded empty __slots__ to abc.ABC. This allows subclassers to - deny __dict__ and __weakref__ creation. Patch by Aaron Hall. - -- bpo-30520: Loggers are now pickleable. - -- bpo-30557: faulthandler now correctly filters and displays exception codes - on Windows - -- bpo-30526: Add TextIOWrapper.reconfigure() and a - TextIOWrapper.write_through attribute. - -- bpo-30245: Fix possible overflow when organize struct.pack_into error - message. Patch by Yuan Liu. - -- bpo-30378: Fix the problem that logging.handlers.SysLogHandler cannot - handle IPv6 addresses. - -- bpo-16500: Allow registering at-fork handlers. - -- bpo-30470: Deprecate invalid ctypes call protection on Windows. Patch by - Mariatta Wijaya. - -- bpo-30414: multiprocessing.Queue._feed background running thread do not - break from main loop on exception. - -- bpo-30003: Fix handling escape characters in HZ codec. Based on patch by - Ma Lin. - -- bpo-30149: inspect.signature() now supports callables with - variable-argument parameters wrapped with partialmethod. Patch by Dong-hee - Na. - -- bpo-30436: importlib.find_spec() raises ModuleNotFoundError instead of - AttributeError if the specified parent module is not a package (i.e. lacks - a __path__ attribute). - -- bpo-30301: Fix AttributeError when using SimpleQueue.empty() under *spawn* - and *forkserver* start methods. - -- bpo-30375: Warnings emitted when compile a regular expression now always - point to the line in the user code. Previously they could point into - inners of the re module if emitted from inside of groups or conditionals. - -- bpo-30329: imaplib and poplib now catch the Windows socket WSAEINVAL error - (code 10022) on shutdown(SHUT_RDWR): An invalid operation was attempted. - This error occurs sometimes on SSL connections. - -- bpo-29196: Removed previously deprecated in Python 2.4 classes Plist, Dict - and _InternalDict in the plistlib module. Dict values in the result of - functions readPlist() and readPlistFromBytes() are now normal dicts. You - no longer can use attribute access to access items of these dictionaries. - -- bpo-9850: The :mod:`macpath` is now deprecated and will be removed in - Python 3.8. - -- bpo-30299: Compiling regular expression in debug mode on CPython now - displays the compiled bytecode in human readable form. - -- bpo-30048: Fixed ``Task.cancel()`` can be ignored when the task is running - coroutine and the coroutine returned without any more ``await``. - -- bpo-30266: contextlib.AbstractContextManager now supports - anti-registration by setting __enter__ = None or __exit__ = None, - following the pattern introduced in bpo-25958. Patch by Jelle Zijlstra. - -- bpo-30340: Enhanced regular expressions optimization. This increased the - performance of matching some patterns up to 25 times. - -- bpo-30298: Weaken the condition of deprecation warnings for inline - modifiers. Now allowed several subsequential inline modifiers at the start - of the pattern (e.g. ``'(?i)(?s)...'``). In verbose mode whitespaces and - comments now are allowed before and between inline modifiers (e.g. ``'(?x) - (?i) (?s)...'``). - -- bpo-30285: Optimized case-insensitive matching and searching of regular - expressions. - -- bpo-29990: Fix range checking in GB18030 decoder. Original patch by Ma - Lin. - -- bpo-29979: rewrite cgi.parse_multipart, reusing the FieldStorage class and - making its results consistent with those of FieldStorage for - multipart/form-data requests. Patch by Pierre Quentel. - -- bpo-30243: Removed the __init__ methods of _json's scanner and encoder. - Misusing them could cause memory leaks or crashes. Now scanner and - encoder objects are completely initialized in the __new__ methods. - -- bpo-30215: Compiled regular expression objects with the re.LOCALE flag no - longer depend on the locale at compile time. Only the locale at matching - time affects the result of matching. - -- bpo-30185: Avoid KeyboardInterrupt tracebacks in forkserver helper process - when Ctrl-C is received. - -- bpo-30103: binascii.b2a_uu() and uu.encode() now support using ``'`'`` as - zero instead of space. - -- bpo-28556: Various updates to typing module: add typing.NoReturn type, use - WrapperDescriptorType, minor bug-fixes. Original PRs by Jim - Fasarakis-Hilliard and Ivan Levkivskyi. - -- bpo-30205: Fix getsockname() for unbound AF_UNIX sockets on Linux. - -- bpo-30228: The seek() and tell() methods of io.FileIO now set the internal - seekable attribute to avoid one syscall on open() (in buffered or text - mode). - -- bpo-30190: unittest's assertAlmostEqual and assertNotAlmostEqual provide a - better message in case of failure which includes the difference between - left and right arguments. (patch by Giampaolo Rodola') - -- bpo-30101: Add support for curses.A_ITALIC. - -- bpo-29822: inspect.isabstract() now works during __init_subclass__. Patch - by Nate Soares. - -- bpo-29960: Preserve generator state when _random.Random.setstate() raises - an exception. Patch by Bryan Olson. - -- bpo-30070: Fixed leaks and crashes in errors handling in the parser - module. - -- bpo-22352: Column widths in the output of dis.dis() are now adjusted for - large line numbers and instruction offsets. - -- bpo-30061: Fixed crashes in IOBase methods __next__() and readlines() when - readline() or __next__() respectively return non-sizeable object. Fixed - possible other errors caused by not checking results of PyObject_Size(), - PySequence_Size(), or PyMapping_Size(). - -- bpo-30218: Fix PathLike support for shutil.unpack_archive. Patch by Jelle - Zijlstra. - -- bpo-10076: Compiled regular expression and match objects in the re module - now support copy.copy() and copy.deepcopy() (they are considered atomic). - -- bpo-30068: _io._IOBase.readlines will check if it's closed first when hint - is present. - -- bpo-29694: Fixed race condition in pathlib mkdir with flags parents=True. - Patch by Armin Rigo. - -- bpo-29692: Fixed arbitrary unchaining of RuntimeError exceptions in - contextlib.contextmanager. Patch by Siddharth Velankar. - -- bpo-26187: Test that sqlite3 trace callback is not called multiple times - when schema is changing. Indirectly fixed by switching to use - sqlite3_prepare_v2() in bpo-9303. Patch by Aviv Palivoda. - -- bpo-30017: Allowed calling the close() method of the zip entry writer - object multiple times. Writing to a closed writer now always produces a - ValueError. - -- bpo-29998: Pickling and copying ImportError now preserves name and path - attributes. - -- bpo-29995: re.escape() now escapes only regex special characters. - -- bpo-29962: Add math.remainder operation, implementing remainder as - specified in IEEE 754. - -- bpo-29649: Improve struct.pack_into() exception messages for problems with - the buffer size and offset. Patch by Andrew Nester. - -- bpo-29654: Support If-Modified-Since HTTP header (browser cache). Patch - by Pierre Quentel. - -- bpo-29931: Fixed comparison check for ipaddress.ip_interface objects. - Patch by Sanjay Sundaresan. - -- bpo-29953: Fixed memory leaks in the replace() method of datetime and time - objects when pass out of bound fold argument. - -- bpo-29942: Fix a crash in itertools.chain.from_iterable when encountering - long runs of empty iterables. - -- bpo-10030: Sped up reading encrypted ZIP files by 2 times. - -- bpo-29204: Element.getiterator() and the html parameter of XMLParser() - were deprecated only in the documentation (since Python 3.2 and 3.4 - correspondingly). Now using them emits a deprecation warning. - -- bpo-27863: Fixed multiple crashes in ElementTree caused by race conditions - and wrong types. - -- bpo-25996: Added support of file descriptors in os.scandir() on Unix. - os.fwalk() is sped up by 2 times by using os.scandir(). - -- bpo-28699: Fixed a bug in pools in multiprocessing.pool that raising an - exception at the very first of an iterable may swallow the exception or - make the program hang. Patch by Davin Potts and Xiang Zhang. - -- bpo-23890: unittest.TestCase.assertRaises() now manually breaks a - reference cycle to not keep objects alive longer than expected. - -- bpo-29901: The zipapp module now supports general path-like objects, not - just pathlib.Path. - -- bpo-25803: Avoid incorrect errors raised by Path.mkdir(exist_ok=True) when - the OS gives priority to errors such as EACCES over EEXIST. - -- bpo-29861: Release references to tasks, their arguments and their results - as soon as they are finished in multiprocessing.Pool. - -- bpo-19930: The mode argument of os.makedirs() no longer affects the file - permission bits of newly created intermediate-level directories. - -- bpo-29884: faulthandler: Restore the old sigaltstack during teardown. - Patch by Christophe Zeitouny. - -- bpo-25455: Fixed crashes in repr of recursive buffered file-like objects. - -- bpo-29800: Fix crashes in partial.__repr__ if the keys of partial.keywords - are not strings. Patch by Michael Seifert. - -- bpo-8256: Fixed possible failing or crashing input() if attributes - "encoding" or "errors" of sys.stdin or sys.stdout are not set or are not - strings. - -- bpo-28692: Using non-integer value for selecting a plural form in gettext - is now deprecated. - -- bpo-26121: Use C library implementation for math functions erf() and - erfc(). - -- bpo-29619: os.stat() and os.DirEntry.inode() now convert inode (st_ino) - using unsigned integers. - -- bpo-28298: Fix a bug that prevented array 'Q', 'L' and 'I' from accepting - big intables (objects that have __int__) as elements. - -- bpo-29645: Speed up importing the webbrowser module. - webbrowser.register() is now thread-safe. - -- bpo-28231: The zipfile module now accepts path-like objects for external - paths. - -- bpo-26915: index() and count() methods of collections.abc.Sequence now - check identity before checking equality when do comparisons. - -- bpo-28682: Added support for bytes paths in os.fwalk(). - -- bpo-29728: Add new :data:`socket.TCP_NOTSENT_LOWAT` (Linux 3.12) constant. - Patch by Nathaniel J. Smith. - -- bpo-29623: Allow use of path-like object as a single argument in - ConfigParser.read(). Patch by David Ellis. - -- bpo-9303: Migrate sqlite3 module to _v2 API. Patch by Aviv Palivoda. - -- bpo-28963: Fix out of bound iteration in - asyncio.Future.remove_done_callback implemented in C. - -- bpo-29704: asyncio.subprocess.SubprocessStreamProtocol no longer closes - before all pipes are closed. - -- bpo-29271: Fix Task.current_task and Task.all_tasks implemented in C to - accept None argument as their pure Python implementation. - -- bpo-29703: Fix asyncio to support instantiation of new event loops in - child processes. - -- bpo-29615: SimpleXMLRPCDispatcher no longer chains KeyError (or any other - exception) to exception(s) raised in the dispatched methods. Patch by Petr - Motejlek. - -- bpo-7769: Method register_function() of - xmlrpc.server.SimpleXMLRPCDispatcher and its subclasses can now be used as - a decorator. - -- bpo-29376: Fix assertion error in threading._DummyThread.is_alive(). - -- bpo-28624: Add a test that checks that cwd parameter of Popen() accepts - PathLike objects. Patch by Sayan Chowdhury. - -- bpo-28518: Start a transaction implicitly before a DML statement. Patch by - Aviv Palivoda. - -- bpo-29742: get_extra_info() raises exception if get called on closed ssl - transport. Patch by Nikolay Kim. - -- bpo-16285: urllib.parse.quote is now based on RFC 3986 and hence includes - '~' in the set of characters that is not quoted by default. Patch by - Christian Theune and Ratnadeep Debnath. - -- bpo-29532: Altering a kwarg dictionary passed to functools.partial() no - longer affects a partial object after creation. - -- bpo-29110: Fix file object leak in aifc.open() when file is given as a - filesystem path and is not in valid AIFF format. Patch by Anthony Zhang. - -- bpo-22807: Add uuid.SafeUUID and uuid.UUID.is_safe to relay information - from the platform about whether generated UUIDs are generated with a - multiprocessing safe method. - -- bpo-29576: Improve some deprecations in importlib. Some deprecated methods - now emit DeprecationWarnings and have better descriptive messages. - -- bpo-29534: Fixed different behaviour of Decimal.from_float() for _decimal - and _pydecimal. Thanks Andrew Nester. - -- bpo-10379: locale.format_string now supports the 'monetary' keyword - argument, and locale.format is deprecated. - -- bpo-29851: importlib.reload() now raises ModuleNotFoundError if the module - lacks a spec. - -- bpo-28556: Various updates to typing module: typing.Counter, - typing.ChainMap, improved ABC caching, etc. Original PRs by Jelle - Zijlstra, Ivan Levkivskyi, Manuel Krebber, and Łukasz Langa. - -- bpo-29100: Fix datetime.fromtimestamp() regression introduced in Python - 3.6.0: check minimum and maximum years. - -- bpo-29416: Prevent infinite loop in pathlib.Path.mkdir - -- bpo-29444: Fixed out-of-bounds buffer access in the group() method of the - match object. Based on patch by WGH. - -- bpo-29377: Add WrapperDescriptorType, MethodWrapperType, and - MethodDescriptorType built-in types to types module. Original patch by - Manuel Krebber. - -- bpo-29218: Unused install_misc command is now removed. It has been - documented as unused since 2000. Patch by Eric N. Vander Weele. - -- bpo-29368: The extend() method is now called instead of the append() - method when unpickle collections.deque and other list-like objects. This - can speed up unpickling to 2 times. - -- bpo-29338: The help of a builtin or extension class now includes the - constructor signature if __text_signature__ is provided for the class. - -- bpo-29335: Fix subprocess.Popen.wait() when the child process has exited - to a stopped instead of terminated state (ex: when under ptrace). - -- bpo-29290: Fix a regression in argparse that help messages would wrap at - non-breaking spaces. - -- bpo-28735: Fixed the comparison of mock.MagickMock with mock.ANY. - -- bpo-29197: Removed deprecated function ntpath.splitunc(). - -- bpo-29210: Removed support of deprecated argument "exclude" in - tarfile.TarFile.add(). - -- bpo-29219: Fixed infinite recursion in the repr of uninitialized - ctypes.CDLL instances. - -- bpo-29192: Removed deprecated features in the http.cookies module. - -- bpo-29193: A format string argument for string.Formatter.format() is now - positional-only. - -- bpo-29195: Removed support of deprecated undocumented keyword arguments in - methods of regular expression objects. - -- bpo-28969: Fixed race condition in C implementation of - functools.lru_cache. KeyError could be raised when cached function with - full cache was simultaneously called from different threads with the same - uncached arguments. - -- bpo-20804: The unittest.mock.sentinel attributes now preserve their - identity when they are copied or pickled. - -- bpo-29142: In urllib.request, suffixes in no_proxy environment variable - with leading dots could match related hostnames again (e.g. .b.c matches - a.b.c). Patch by Milan Oberkirch. - -- bpo-28961: Fix unittest.mock._Call helper: don't ignore the name parameter - anymore. Patch written by Jiajun Huang. - -- bpo-15812: inspect.getframeinfo() now correctly shows the first line of a - context. Patch by Sam Breese. - -- bpo-28985: Update authorizer constants in sqlite3 module. Patch by - Dingyuan Wang. - -- bpo-29079: Prevent infinite loop in pathlib.resolve() on Windows - -- bpo-13051: Fixed recursion errors in large or resized - curses.textpad.Textbox. Based on patch by Tycho Andersen. - -- bpo-9770: curses.ascii predicates now work correctly with negative - integers. - -- bpo-28427: old keys should not remove new values from WeakValueDictionary - when collecting from another thread. - -- bpo-28923: Remove editor artifacts from Tix.py. - -- bpo-28871: Fixed a crash when deallocate deep ElementTree. - -- bpo-19542: Fix bugs in WeakValueDictionary.setdefault() and - WeakValueDictionary.pop() when a GC collection happens in another thread. - -- bpo-20191: Fixed a crash in resource.prlimit() when passing a sequence - that doesn't own its elements as limits. - -- bpo-16255: subprocess.Popen uses /system/bin/sh on Android as the shell, - instead of /bin/sh. - -- bpo-28779: multiprocessing.set_forkserver_preload() would crash the - forkserver process if a preloaded module instantiated some multiprocessing - objects such as locks. - -- bpo-26937: The chown() method of the tarfile.TarFile class does not fail - now when the grp module cannot be imported, as for example on Android - platforms. - -- bpo-28847: dbm.dumb now supports reading read-only files and no longer - writes the index file when it is not changed. A deprecation warning is - now emitted if the index file is missed and recreated in the 'r' and 'w' - modes (will be an error in future Python releases). - -- bpo-27030: Unknown escapes consisting of ``'\'`` and an ASCII letter in - re.sub() replacement templates regular expressions now are errors. - -- bpo-28835: Fix a regression introduced in warnings.catch_warnings(): call - warnings.showwarning() if it was overridden inside the context manager. - -- bpo-27172: To assist with upgrades from 2.7, the previously documented - deprecation of ``inspect.getfullargspec()`` has been reversed. This - decision may be revisited again after the Python 2.7 branch is no longer - officially supported. - -- bpo-28740: Add sys.getandroidapilevel(): return the build time API version - of Android as an integer. Function only available on Android. - -- bpo-26273: Add new :data:`socket.TCP_CONGESTION` (Linux 2.6.13) and - :data:`socket.TCP_USER_TIMEOUT` (Linux 2.6.37) constants. Patch written by - Omar Sandoval. - -- bpo-28752: Restored the __reduce__() methods of datetime objects. - -- bpo-28727: Regular expression patterns, _sre.SRE_Pattern objects created - by re.compile(), become comparable (only x==y and x!=y operators). This - change should fix the issue #18383: don't duplicate warning filters when - the warnings module is reloaded (thing usually only done in unit tests). - -- bpo-20572: Remove the subprocess.Popen.wait endtime parameter. It was - deprecated in 3.4 and undocumented prior to that. - -- bpo-25659: In ctypes, prevent a crash calling the from_buffer() and - from_buffer_copy() methods on abstract classes like Array. - -- bpo-28548: In the "http.server" module, parse the protocol version if - possible, to avoid using HTTP 0.9 in some error responses. - -- bpo-19717: Makes Path.resolve() succeed on paths that do not exist. Patch - by Vajrasky Kok - -- bpo-28563: Fixed possible DoS and arbitrary code execution when handle - plural form selections in the gettext module. The expression parser now - supports exact syntax supported by GNU gettext. - -- bpo-28387: Fixed possible crash in _io.TextIOWrapper deallocator when the - garbage collector is invoked in other thread. Based on patch by Sebastian - Cufre. - -- bpo-27517: LZMA compressor and decompressor no longer raise exceptions if - given empty data twice. Patch by Benjamin Fogle. - -- bpo-28549: Fixed segfault in curses's addch() with ncurses6. - -- bpo-28449: tarfile.open() with mode "r" or "r:" now tries to open a tar - file with compression before trying to open it without compression. - Otherwise it had 50% chance failed with ignore_zeros=True. - -- bpo-23262: The webbrowser module now supports Firefox 36+ and derived - browsers. Based on patch by Oleg Broytman. - -- bpo-24241: The webbrowser in an X environment now prefers using the - default browser directly. Also, the webbrowser register() function now has - a documented 'preferred' argument, to specify browsers to be returned by - get() with no arguments. Patch by David Steele - -- bpo-27939: Fixed bugs in tkinter.ttk.LabeledScale and tkinter.Scale caused - by representing the scale as float value internally in Tk. tkinter.IntVar - now works if float value is set to underlying Tk variable. - -- bpo-28255: calendar.TextCalendar.prweek() no longer prints a space after a - weeks's calendar. calendar.TextCalendar.pryear() no longer prints - redundant newline after a year's calendar. Based on patch by Xiang Zhang. - -- bpo-28255: calendar.TextCalendar.prmonth() no longer prints a space at the - start of new line after printing a month's calendar. Patch by Xiang - Zhang. - -- bpo-20491: The textwrap.TextWrapper class now honors non-breaking spaces. - Based on patch by Kaarle Ritvanen. - -- bpo-28353: os.fwalk() no longer fails on broken links. - -- bpo-28430: Fix iterator of C implemented asyncio.Future doesn't accept - non-None value is passed to it.send(val). - -- bpo-27025: Generated names for Tkinter widgets now start by the "!" prefix - for readability. - -- bpo-25464: Fixed HList.header_exists() in tkinter.tix module by addin a - workaround to Tix library bug. - -- bpo-28488: shutil.make_archive() no longer adds entry "./" to ZIP archive. - -- bpo-25953: re.sub() now raises an error for invalid numerical group - reference in replacement template even if the pattern is not found in the - string. Error message for invalid group reference now includes the group - index and the position of the reference. Based on patch by SilentGhost. - -- bpo-28469: timeit now uses the sequence 1, 2, 5, 10, 20, 50,... instead of - 1, 10, 100,... for autoranging. - -- bpo-28115: Command-line interface of the zipfile module now uses argparse. - Added support of long options. - -- bpo-18219: Optimize csv.DictWriter for large number of columns. Patch by - Mariatta Wijaya. - -- bpo-28448: Fix C implemented asyncio.Future didn't work on Windows. - -- bpo-23214: In the "io" module, the argument to BufferedReader and - BytesIO's read1() methods is now optional and can be -1, matching the - BufferedIOBase specification. - -- bpo-28480: Fix error building socket module when multithreading is - disabled. - -- bpo-28240: timeit: remove ``-c/--clock`` and ``-t/--time`` command line - options which were deprecated since Python 3.3. - -- bpo-28240: timeit now repeats the benchmarks 5 times instead of only 3 to - make benchmarks more reliable. - -- bpo-28240: timeit autorange now uses a single loop iteration if the - benchmark takes less than 10 seconds, instead of 10 iterations. "python3 - -m timeit -s 'import time' 'time.sleep(1)'" now takes 4 seconds instead of - 40 seconds. - -- Distutils.sdist now looks for README and setup.py files with case - sensitivity. This behavior matches that found in Setuptools 6.0 and later. - See `setuptools 100 <https://github.com/pypa/setuptools/issues/100>`_ for - rationale. - -- bpo-24452: Make webbrowser support Chrome on Mac OS X. Patch by Ned - Batchelder. - -- bpo-20766: Fix references leaked by pdb in the handling of SIGINT - handlers. - -- bpo-27998: Fixed bytes path support in os.scandir() on Windows. Patch by - Eryk Sun. - -- bpo-28317: The disassembler now decodes FORMAT_VALUE argument. - -- bpo-28380: unittest.mock Mock autospec functions now properly support - assert_called, assert_not_called, and assert_called_once. - -- bpo-28229: lzma module now supports pathlib. - -- bpo-28321: Fixed writing non-BMP characters with binary format in - plistlib. - -- bpo-28225: bz2 module now supports pathlib. Initial patch by Ethan - Furman. - -- bpo-28227: gzip now supports pathlib. Patch by Ethan Furman. - -- bpo-28332: Deprecated silent truncations in socket.htons and socket.ntohs. - Original patch by Oren Milman. - -- bpo-27358: Optimized merging var-keyword arguments and improved error - message when passing a non-mapping as a var-keyword argument. - -- bpo-28257: Improved error message when passing a non-iterable as a - var-positional argument. Added opcode BUILD_TUPLE_UNPACK_WITH_CALL. - -- bpo-28322: Fixed possible crashes when unpickle itertools objects from - incorrect pickle data. Based on patch by John Leitch. - -- bpo-28228: imghdr now supports pathlib. - -- bpo-28226: compileall now supports pathlib. - -- bpo-28314: Fix function declaration (C flags) for the getiterator() method - of xml.etree.ElementTree.Element. - -- bpo-28148: Stop using localtime() and gmtime() in the time module. - Introduced platform independent _PyTime_localtime API that is similar to - POSIX localtime_r, but available on all platforms. Patch by Ed Schouten. - -- bpo-28253: Fixed calendar functions for extreme months: 0001-01 and - 9999-12. Methods itermonthdays() and itermonthdays2() are reimplemented so - that they don't call itermonthdates() which can cause datetime.date - under/overflow. - -- bpo-28275: Fixed possible use after free in the decompress() methods of - the LZMADecompressor and BZ2Decompressor classes. Original patch by John - Leitch. - -- bpo-27897: Fixed possible crash in sqlite3.Connection.create_collation() - if pass invalid string-like object as a name. Patch by Xiang Zhang. - -- bpo-18844: random.choices() now has k as a keyword-only argument to - improve the readability of common cases and come into line with the - signature used in other languages. - -- bpo-18893: Fix invalid exception handling in Lib/ctypes/macholib/dyld.py. - Patch by Madison May. - -- bpo-27611: Fixed support of default root window in the tkinter.tix module. - Added the master parameter in the DisplayStyle constructor. - -- bpo-27348: In the traceback module, restore the formatting of exception - messages like "Exception: None". This fixes a regression introduced in - 3.5a2. - -- bpo-25651: Allow falsy values to be used for msg parameter of subTest(). - -- bpo-27778: Fix a memory leak in os.getrandom() when the getrandom() is - interrupted by a signal and a signal handler raises a Python exception. - -- bpo-28200: Fix memory leak on Windows in the os module (fix - path_converter() function). - -- bpo-25400: RobotFileParser now correctly returns default values for - crawl_delay and request_rate. Initial patch by Peter Wirtz. - -- bpo-27932: Prevent memory leak in win32_ver(). - -- Fix UnboundLocalError in socket._sendfile_use_sendfile. - -- bpo-28075: Check for ERROR_ACCESS_DENIED in Windows implementation of - os.stat(). Patch by Eryk Sun. - -- bpo-22493: Warning message emitted by using inline flags in the middle of - regular expression now contains a (truncated) regex pattern. Patch by Tim - Graham. - -- bpo-25270: Prevent codecs.escape_encode() from raising SystemError when an - empty bytestring is passed. - -- bpo-28181: Get antigravity over HTTPS. Patch by Kaartic Sivaraam. - -- bpo-25895: Enable WebSocket URL schemes in urllib.parse.urljoin. Patch by - Gergely Imreh and Markus Holtermann. - -- bpo-28114: Fix a crash in parse_envlist() when env contains byte strings. - Patch by Eryk Sun. - -- bpo-27599: Fixed buffer overrun in binascii.b2a_qp() and - binascii.a2b_qp(). - -- bpo-27906: Fix socket accept exhaustion during high TCP traffic. Patch by - Kevin Conway. - -- bpo-28174: Handle when SO_REUSEPORT isn't properly supported. Patch by - Seth Michael Larson. - -- bpo-26654: Inspect functools.partial in asyncio.Handle.__repr__. Patch by - iceboy. - -- bpo-26909: Fix slow pipes IO in asyncio. Patch by INADA Naoki. - -- bpo-28176: Fix callbacks race in asyncio.SelectorLoop.sock_connect. - -- bpo-27759: Fix selectors incorrectly retain invalid file descriptors. - Patch by Mark Williams. - -- bpo-28325: Remove vestigial MacOS 9 macurl2path module and its tests. - -- bpo-28368: Refuse monitoring processes if the child watcher has no loop - attached. Patch by Vincent Michel. - -- bpo-28369: Raise RuntimeError when transport's FD is used with add_reader, - add_writer, etc. - -- bpo-28370: Speedup asyncio.StreamReader.readexactly. Patch by Коренберг - Марк. - -- bpo-28371: Deprecate passing asyncio.Handles to run_in_executor. - -- bpo-28372: Fix asyncio to support formatting of non-python coroutines. - -- bpo-28399: Remove UNIX socket from FS before binding. Patch by Коренберг - Марк. - -- bpo-27972: Prohibit Tasks to await on themselves. - -- bpo-24142: Reading a corrupt config file left configparser in an invalid - state. Original patch by Florian Höch. - -- bpo-29581: ABCMeta.__new__ now accepts ``**kwargs``, allowing abstract - base classes to use keyword parameters in __init_subclass__. Patch by Nate - Soares. - -- 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-30177: path.resolve(strict=False) no longer cuts the path after the - first element not present in the filesystem. Patch by Antoine Pietri. - -Documentation -------------- - -- bpo-31294: Fix incomplete code snippet in the ZeroMQSocketListener and - ZeroMQSocketHandler examples and adapt them to Python 3. - -- bpo-21649: Add RFC 7525 and Mozilla server side TLS links to SSL - documentation. - -- bpo-31128: Allow the pydoc server to bind to arbitrary hostnames. - -- bpo-30803: Clarify doc on truth value testing. Original patch by Peter - Thomassen. - -- bpo-30176: Add missing attribute related constants in curses - documentation. - -- bpo-30052: the link targets for :func:`bytes` and :func:`bytearray` are - now their respective type definitions, rather than the corresponding - builtin function entries. Use :ref:`bytes <func-bytes>` and - :ref:`bytearray <func-bytearray>` to reference the latter. In order to - ensure this and future cross-reference updates are applied automatically, - the daily documentation builds now disable the default output caching - features in Sphinx. - -- bpo-26985: Add missing info of code object in inspect documentation. - -- bpo-19824: Improve the documentation for, and links to, template strings - by emphasizing their utility for internationalization, and by clarifying - some usage constraints. (See also: bpo-20314, bpo-12518) - -- bpo-28929: Link the documentation to its source file on GitHub. - -- bpo-25008: Document smtpd.py as effectively deprecated and add a pointer - to aiosmtpd, a third-party asyncio-based replacement. - -- bpo-26355: Add canonical header link on each page to corresponding major - version of the documentation. Patch by Matthias Bussonnier. - -- bpo-29349: Fix Python 2 syntax in code for building the documentation. - -- bpo-23722: The data model reference and the porting section in the 3.6 - What's New guide now cover the additional ``__classcell__`` handling - needed for custom metaclasses to fully support :pep:`487` and - zero-argument ``super()``. - -- bpo-28513: Documented command-line interface of zipfile. - -Tests ------ - -- bpo-29639: test.support.HOST is now "localhost", a new HOSTv4 constant has - been added for your ``127.0.0.1`` needs, similar to the existing HOSTv6 - constant. - -- bpo-31320: Silence traceback in test_ssl - -- bpo-31346: Prefer PROTOCOL_TLS_CLIENT and PROTOCOL_TLS_SERVER protocols - for SSLContext. - -- bpo-25674: Remove sha256.tbs-internet.com ssl test - -- bpo-30715: Address ALPN callback changes for OpenSSL 1.1.0f. The latest - version behaves like OpenSSL 1.0.2 and no longer aborts handshake. - -- bpo-30822: regrtest: Exclude tzdata from regrtest --all. When running the - test suite using --use=all / -u all, exclude tzdata since it makes - test_datetime too slow (15-20 min on some buildbots) which then times out - on some buildbots. Fix also regrtest command line parser to allow passing - -u extralargefile to run test_zipfile64. - -- bpo-30695: Add the `set_nomemory(start, stop)` and `remove_mem_hooks()` - functions to the _testcapi module. - -- bpo-30357: test_thread: setUp() now uses support.threading_setup() and - support.threading_cleanup() to wait until threads complete to avoid random - side effects on following tests. Initial patch written by Grzegorz - Grzywacz. - -- bpo-30197: Enhanced functions swap_attr() and swap_item() in the - test.support module. They now work when delete replaced attribute or item - inside the with statement. The old value of the attribute or item (or - None if it doesn't exist) now will be assigned to the target of the "as" - clause, if there is one. - -- bpo-24932: Use proper command line parsing in _testembed - -- bpo-28950: Disallow -j0 to be combined with -T/-l in regrtest command line - arguments. - -- bpo-28683: Fix the tests that bind() a unix socket and raise - PermissionError on Android for a non-root user. - -- bpo-26936: Fix the test_socket failures on Android - getservbyname(), - getservbyport() and getaddrinfo() are broken on some Android API levels. - -- bpo-28666: Now test.support.rmtree is able to remove unwritable or - unreadable directories. - -- bpo-23839: Various caches now are cleared before running every test file. - -- bpo-26944: Fix test_posix for Android where 'id -G' is entirely wrong or - missing the effective gid. - -- bpo-28409: regrtest: fix the parser of command line arguments. - -- bpo-28217: Adds _testconsole module to test console input. - -- bpo-26939: Add the support.setswitchinterval() function to fix - test_functools hanging on the Android armv7 qemu emulator. - -Build ------ - -- bpo-31354: Allow --with-lto to be used on all builds, not just `make - profile-opt`. - -- bpo-31370: Remove support for building --without-threads. This option is - not really useful anymore in the 21st century. Removing lots of - conditional paths allows us to simplify the code base, including in - difficult to maintain low-level internal code. - -- bpo-31341: Per :pep:`11`, support for the IRIX operating system was - removed. - -- bpo-30854: Fix compile error when compiling --without-threads. Patch by - Masayuki Yamamoto. - -- bpo-30687: Locate msbuild.exe on Windows when building rather than - vcvarsall.bat - -- bpo-20210: Support the *disabled* marker in Setup files. Extension modules - listed after this marker are not built at all, neither by the Makefile nor - by setup.py. - -- bpo-29941: Add ``--with-assertions`` configure flag to explicitly enable C - ``assert()`` checks. Defaults to off. ``--with-pydebug`` implies - ``--with-assertions``. - -- bpo-28787: Fix out-of-tree builds of Python when configured with - ``--with--dtrace``. - -- bpo-29243: Prevent unnecessary rebuilding of Python during ``make test``, - ``make install`` and some other make targets when configured with - ``--enable-optimizations``. - -- bpo-23404: Don't regenerate generated files based on file modification - time anymore: the action is now explicit. Replace ``make touch`` with - ``make regen-all``. - -- bpo-29643: Fix ``--enable-optimization`` didn't work. - -- bpo-27593: sys.version and the platform module python_build(), - python_branch(), and python_revision() functions now use git information - rather than hg when building from a repo. - -- bpo-29572: Update Windows build and OS X installers to use OpenSSL 1.0.2k. - -- bpo-27659: Prohibit implicit C function declarations: use - ``-Werror=implicit-function-declaration`` when possible (GCC and Clang, - but it depends on the compiler version). Patch written by Chi Hsuan Yen. - -- bpo-29384: Remove old Be OS helper scripts. - -- bpo-26851: Set Android compilation and link flags. - -- bpo-28768: Fix implicit declaration of function _setmode. Patch by - Masayuki Yamamoto - -- bpo-29080: Removes hard dependency on hg.exe from PCBuild/build.bat - -- bpo-23903: Added missed names to PC/python3.def. - -- bpo-28762: lockf() is available on Android API level 24, but the F_LOCK - macro is not defined in android-ndk-r13. - -- bpo-28538: Fix the compilation error that occurs because if_nameindex() is - available on Android API level 24, but the if_nameindex structure is not - defined. - -- bpo-20211: Do not add the directory for installing C header files and the - directory for installing object code libraries to the cross compilation - search paths. Original patch by Thomas Petazzoni. - -- bpo-28849: Do not define sys.implementation._multiarch on Android. - -- bpo-10656: Fix out-of-tree building on AIX. Patch by Tristan Carel and - Michael Haubenwallner. - -- bpo-26359: Rename --with-optimiations to --enable-optimizations. - -- bpo-28444: Fix missing extensions modules when cross compiling. - -- bpo-28208: Update Windows build and OS X installers to use SQLite 3.14.2. - -- bpo-28248: Update Windows build and OS X installers to use OpenSSL 1.0.2j. - -- bpo-21124: Fix building the _struct module on Cygwin by passing ``NULL`` - instead of ``&PyType_Type`` to PyVarObject_HEAD_INIT. Patch by Masayuki - Yamamoto. - -- bpo-13756: Fix building extensions modules on Cygwin. Patch by Roumen - Petrov, based on original patch by Jason Tishler. - -- bpo-21085: Add configure check for siginfo_t.si_band, which Cygwin does - not provide. Patch by Masayuki Yamamoto with review and rebase by Erik - Bray. - -- bpo-28258: Fixed build with Estonian locale (python-config and distclean - targets in Makefile). Patch by Arfrever Frehtes Taifersar Arahesis. - -- bpo-26661: setup.py now detects system libffi with multiarch wrapper. - -- bpo-27979: A full copy of libffi is no longer bundled for use when - building _ctypes on non-OSX UNIX platforms. An installed copy of libffi - is now required when building _ctypes on such platforms. - -- bpo-15819: Remove redundant include search directory option for building - outside the source tree. - -- bpo-28676: Prevent missing 'getentropy' declaration warning on macOS. - Patch by Gareth Rees. - -Windows -------- - -- bpo-31392: Update Windows build to use OpenSSL 1.1.0f - -- bpo-30389: Adds detection of Visual Studio 2017 to distutils on Windows. - -- bpo-31358: zlib is no longer bundled in the CPython source, instead it is - downloaded on demand just like bz2, lzma, OpenSSL, Tcl/Tk, and SQLite. - -- bpo-31340: Change to building with MSVC v141 (included with Visual Studio - 2017) - -- bpo-30581: os.cpu_count() now returns the correct number of processors on - Windows when the number of logical processors is greater than 64. - -- bpo-30916: Pre-build OpenSSL, Tcl and Tk and include the binaries in the - build. - -- bpo-30731: Add a missing xmlns to python.manifest so that it matches the - schema. - -- bpo-30291: Allow requiring 64-bit interpreters from py.exe using -64 - suffix. Contributed by Steve (Gadget) Barnes. - -- bpo-30362: Adds list options (-0, -0p) to py.exe launcher. Contributed by - Steve Barnes. - -- bpo-23451: Fix socket deprecation warnings in socketmodule.c. Patch by - Segev Finer. - -- bpo-30450: The build process on Windows no longer depends on Subversion, - instead pulling external code from GitHub via a Python script. If Python - 3.6 is not found on the system (via ``py -3.6``), NuGet is used to - download a copy of 32-bit Python. - -- bpo-29579: Removes readme.txt from the installer. - -- bpo-25778: winreg does not truncate string correctly (Patch by Eryk Sun) - -- bpo-28896: Deprecate WindowsRegistryFinder and disable it by default - -- bpo-28522: Fixes mishandled buffer reallocation in getpathp.c - -- bpo-28402: Adds signed catalog files for stdlib on Windows. - -- bpo-28333: Enables Unicode for ps1/ps2 and input() prompts. (Patch by Eryk - Sun) - -- bpo-28251: Improvements to help manuals on Windows. - -- bpo-28110: launcher.msi has different product codes between 32-bit and - 64-bit - -- bpo-28161: Opening CON for write access fails - -- bpo-28162: WindowsConsoleIO readall() fails if first line starts with - Ctrl+Z - -- bpo-28163: WindowsConsoleIO fileno() passes wrong flags to _open_osfhandle - -- bpo-28164: _PyIO_get_console_type fails for various paths - -- bpo-28137: Renames Windows path file to ._pth - -- bpo-28138: Windows ._pth file should allow import site - -IDLE ----- - -- bpo-31493: IDLE code context -- fix code update and font update timers. - Canceling timers prevents a warning message when test_idle completes. - -- bpo-31488: IDLE - Update non-key options in former extension classes. When - applying configdialog changes, call .reload for each feature class. Change - ParenMatch so updated options affect existing instances attached to - existing editor windows. - -- bpo-31477: IDLE - Improve rstrip entry in doc. Strip trailing whitespace - strips more than blank spaces. Multiline string literals are not skipped. - -- bpo-31480: IDLE - make tests pass with zzdummy extension disabled by - default. - -- bpo-31421: Document how IDLE runs tkinter programs. IDLE calls tcl/tk - update in the background in order to make live interaction and - experimentation with tkinter applications much easier. - -- bpo-31414: IDLE -- fix tk entry box tests by deleting first. Adding to an - int entry is not the same as deleting and inserting because int('') will - fail. - -- bpo-31051: Rearrange IDLE configdialog GenPage into Window, Editor, and - Help sections. - -- bpo-30617: IDLE - Add docstrings and tests for outwin subclass of editor. - Move some data and functions from the class to module level. Patch by - Cheryl Sabella. - -- bpo-31287: IDLE - Do not modify tkinter.message in test_configdialog. - -- bpo-27099: Convert IDLE's built-in 'extensions' to regular features. About - 10 IDLE features were implemented as supposedly optional extensions. Their - different behavior could be confusing or worse for users and not good for - maintenance. Hence the conversion. The main difference for users is that - user configurable key bindings for builtin features are now handled - uniformly. Now, editing a binding in a keyset only affects its value in - the keyset. All bindings are defined together in the system-specific - default keysets in config-extensions.def. All custom keysets are saved as - a whole in config-extension.cfg. All take effect as soon as one clicks - Apply or Ok. The affected events are '<<force-open-completions>>', - '<<expand-word>>', '<<force-open-calltip>>', '<<flash-paren>>', - '<<format-paragraph>>', '<<run-module>>', '<<check-module>>', and - '<<zoom-height>>'. Any (global) customizations made before 3.6.3 will not - affect their keyset-specific customization after 3.6.3. and vice versa. - Initial patch by Charles Wohlganger. - -- bpo-31206: IDLE: Factor HighPage(Frame) class from ConfigDialog. Patch by - Cheryl Sabella. - -- bpo-31001: Add tests for configdialog highlight tab. Patch by Cheryl - Sabella. - -- bpo-31205: IDLE: Factor KeysPage(Frame) class from ConfigDialog. The - slightly modified tests continue to pass. Patch by Cheryl Sabella. - -- bpo-31130: IDLE -- stop leaks in test_configdialog. Initial patch by - Victor Stinner. - -- bpo-31002: Add tests for configdialog keys tab. Patch by Cheryl Sabella. - -- bpo-19903: IDLE: Calltips use `inspect.signature` instead of - `inspect.getfullargspec`. This improves calltips for builtins converted to - use Argument Clinic. Patch by Louie Lu. - -- bpo-31083: IDLE - Add an outline of a TabPage class in configdialog. - Update existing classes to match outline. Initial patch by Cheryl Sabella. - -- bpo-31050: Factor GenPage(Frame) class from ConfigDialog. The slightly - modified tests continue to pass. Patch by Cheryl Sabella. - -- bpo-31004: IDLE - Factor FontPage(Frame) class from ConfigDialog. Slightly - modified tests continue to pass. Fix General tests. Patch mostly by Cheryl - Sabella. - -- bpo-30781: IDLE - Use ttk widgets in ConfigDialog. Patches by Terry Jan - Reedy and Cheryl Sabella. - -- bpo-31060: IDLE - Finish rearranging methods of ConfigDialog Grouping - methods pertaining to each tab and the buttons will aid writing tests and - improving the tabs and will enable splitting the groups into classes. - -- bpo-30853: IDLE -- Factor a VarTrace class out of ConfigDialog. Instance - tracers manages pairs consisting of a tk variable and a callback function. - When tracing is turned on, setting the variable calls the function. Test - coverage for the new class is 100%. - -- bpo-31003: IDLE: Add more tests for General tab. - -- bpo-30993: IDLE - Improve configdialog font page and tests. In - configdialog: Document causal pathways in create_font_tab docstring. - Simplify some attribute names. Move set_samples calls to var_changed_font - (idea from Cheryl Sabella). Move related functions to positions after the - create widgets function. In test_configdialog: Fix test_font_set so not - order dependent. Fix renamed test_indent_scale so it tests the widget. - Adjust tests for movement of set_samples call. Add tests for load - functions. Put all font tests in one class and tab indent tests in - another. Except for two lines, these tests completely cover the related - functions. - -- bpo-30981: IDLE -- Add more configdialog font page tests. - -- bpo-28523: IDLE: replace 'colour' with 'color' in configdialog. - -- bpo-30917: Add tests for idlelib.config.IdleConf. Increase coverage from - 46% to 96%. Patch by Louie Lu. - -- bpo-30934: Document coverage details for idlelib tests. Add section to - idlelib/idle-test/README.txt. Include check that branches are taken both - ways. Exclude IDLE-specific code that does not run during unit tests. - -- bpo-30913: IDLE: Document ConfigDialog tk Vars, methods, and widgets in - docstrings This will facilitate improving the dialog and splitting up the - class. Original patch by Cheryl Sabella. - -- bpo-30899: IDLE: Add tests for ConfigParser subclasses in config. Patch by - Louie Lu. - -- bpo-30881: IDLE: Add docstrings to browser.py. Patch by Cheryl Sabella. - -- bpo-30851: IDLE: Remove unused variables in configdialog. One is a - duplicate, one is set but cannot be altered by users. Patch by Cheryl - Sabella. - -- bpo-30870: IDLE: In Settings dialog, select font with Up, Down keys as - well as mouse. Initial patch by Louie Lu. - -- bpo-8231: IDLE: call config.IdleConf.GetUserCfgDir only once. - -- bpo-30779: IDLE: Factor ConfigChanges class from configdialog, put in - config; test. * In config, put dump test code in a function; run it and - unittest in 'if __name__ == '__main__'. * Add class config.ConfigChanges - based on changes_class_v4.py on bpo issue. * Add class - test_config.ChangesTest, partly using configdialog_tests_v1.py. * Revise - configdialog to use ConfigChanges; see tracker msg297804. * Revise - test_configdialog to match configdialog changes. * Remove configdialog - functions unused or moved to ConfigChanges. Cheryl Sabella contributed - parts of the patch. - -- bpo-30777: IDLE: configdialog - Add docstrings and fix comments. Patch by - Cheryl Sabella. - -- bpo-30495: IDLE: Improve textview with docstrings, PEP8 names, and more - tests. Patch by Cheryl Sabella. - -- bpo-30723: IDLE: Make several improvements to parenmatch. Add 'parens' - style to highlight both opener and closer. Make 'default' style, which is - not default, a synonym for 'opener'. Make time-delay work the same with - all styles. Add help for config dialog extensions tab, including help for - parenmatch. Add new tests. Original patch by Charles Wohlganger. - -- bpo-30674: IDLE: add docstrings to grep module. Patch by Cheryl Sabella - -- bpo-21519: IDLE's basic custom key entry dialog now detects duplicates - properly. Original patch by Saimadhav Heblikar. - -- bpo-29910: IDLE no longer deletes a character after commenting out a - region by a key shortcut. Add ``return 'break'`` for this and other - potential conflicts between IDLE and default key bindings. - -- bpo-30728: Review and change idlelib.configdialog names. Lowercase method - and attribute names. Replace 'colour' with 'color', expand overly cryptic - names, delete unneeded underscores. Replace ``import *`` with specific - imports. Patches by Cheryl Sabella. - -- bpo-6739: IDLE: Verify user-entered key sequences by trying to bind them - with tk. Add tests for all 3 validation functions. Original patch by G - Polo. Tests added by Cheryl Sabella. - -- bpo-15786: Fix several problems with IDLE's autocompletion box. The - following should now work: clicking on selection box items; using the - scrollbar; selecting an item by hitting Return. Hangs on MacOSX should no - longer happen. Patch by Louie Lu. - -- bpo-25514: Add doc subsubsection about IDLE failure to start. Popup - no-connection message directs users to this section. - -- bpo-30642: Fix reference leaks in IDLE tests. Patches by Louie Lu and - Terry Jan Reedy. - -- bpo-30495: Add docstrings for textview.py and use PEP8 names. Patches by - Cheryl Sabella and Terry Jan Reedy. - -- bpo-30290: Help-about: use pep8 names and add tests. Increase coverage to - 100%. Patches by Louie Lu, Cheryl Sabella, and Terry Jan Reedy. - -- bpo-30303: Add _utest option to textview; add new tests. Increase coverage - to 100%. Patches by Louie Lu and Terry Jan Reedy. - -- bpo-29071: IDLE colors f-string prefixes (but not invalid ur prefixes). - -- bpo-28572: Add 10% to coverage of IDLE's test_configdialog. Update and - augment description of the configuration system. - -Tools/Demos ------------ - -- bpo-30983: gdb integration commands (py-bt, etc.) work on optimized shared - builds now, too. :pep:`523` introduced _PyEval_EvalFrameDefault which - inlines PyEval_EvalFrameEx on non-debug shared builds. This broke the - ability to use py-bt, py-up, and a few other Python-specific gdb - integrations. The problem is fixed by only looking for - _PyEval_EvalFrameDefault frames in python-gdb.py. Original patch by Bruno - "Polaco" Penteado. - -- bpo-29748: Added the slice index converter in Argument Clinic. - -- bpo-24037: Argument Clinic now uses the converter `bool(accept={int})` - rather than `int` for semantical booleans. This avoids repeating the - default value for Python and C and will help in converting to `bool` in - future. - -- bpo-29367: python-gdb.py now supports also ``method-wrapper`` - (``wrapperobject``) objects. - -- bpo-28023: Fix python-gdb.py didn't support new dict implementation. - -- bpo-15369: The pybench and pystone microbenchmark have been removed from - Tools. Please use the new Python benchmark suite - https://github.com/python/performance which is more reliable and includes - a portable version of pybench working on Python 2 and Python 3. - -- bpo-28102: The zipfile module CLI now prints usage to stderr. Patch by - Stephen J. Turnbull. - -C API ------ - -- bpo-31338: Added the ``Py_UNREACHABLE()`` macro for code paths which are - never expected to be reached. This and a few other useful macros are now - documented in the C API manual. - -- bpo-30832: Remove own implementation for thread-local storage. CPython has - provided the own implementation for thread-local storage (TLS) on - Python/thread.c, it's used in the case which a platform has not supplied - native TLS. However, currently all supported platforms (Windows and - pthreads) have provided native TLS and defined the Py_HAVE_NATIVE_TLS - macro with unconditional in any case. - -- bpo-30708: PyUnicode_AsWideCharString() now raises a ValueError if the - second argument is NULL and the wchar_t\* string contains null characters. - -- bpo-16500: Deprecate PyOS_AfterFork() and add PyOS_BeforeFork(), - PyOS_AfterFork_Parent() and PyOS_AfterFork_Child(). - -- bpo-6532: The type of results of PyThread_start_new_thread() and - PyThread_get_thread_ident(), and the id parameter of - PyThreadState_SetAsyncExc() changed from "long" to "unsigned long". - -- bpo-27867: Function PySlice_GetIndicesEx() is deprecated and replaced with - a macro if Py_LIMITED_API is not set or set to the value between - 0x03050400 and 0x03060000 (not including) or 0x03060100 or higher. Added - functions PySlice_Unpack() and PySlice_AdjustIndices(). - -- bpo-29083: Fixed the declaration of some public API functions. - PyArg_VaParse() and PyArg_VaParseTupleAndKeywords() were not available in - limited API. PyArg_ValidateKeywordArguments(), PyArg_UnpackTuple() and - Py_BuildValue() were not available in limited API of version < 3.3 when - PY_SSIZE_T_CLEAN is defined. - -- bpo-28769: The result of PyUnicode_AsUTF8AndSize() and PyUnicode_AsUTF8() - is now of type ``const char *`` rather of ``char *``. - -- bpo-29058: All stable API extensions added after Python 3.2 are now - available only when Py_LIMITED_API is set to the PY_VERSION_HEX value of - the minimum Python version supporting this API. - -- bpo-28822: The index parameters *start* and *end* of PyUnicode_FindChar() - are now adjusted to behave like ``str[start:end]``. - -- bpo-28808: PyUnicode_CompareWithASCIIString() now never raises exceptions. - -- bpo-28761: The fields name and doc of structures PyMemberDef, PyGetSetDef, - PyStructSequence_Field, PyStructSequence_Desc, and wrapperbase are now of - type ``const char *`` rather of ``char *``. - -- bpo-28748: Private variable _Py_PackageContext is now of type ``const char - *`` rather of ``char *``. - -- bpo-19569: Compiler warnings are now emitted if use most of deprecated - functions. - -- bpo-28426: Deprecated undocumented functions PyUnicode_AsEncodedObject(), - PyUnicode_AsDecodedObject(), PyUnicode_AsDecodedUnicode() and - PyUnicode_AsEncodedUnicode(). - - -What's New in Python 3.6.6 final? -================================= - -*Release date: 2018-06-27* - -There were no new changes in version 3.6.6. - - - -What's New in Python 3.6.6 release candidate 1? -=============================================== - -*Release date: 2018-06-11* - -Core and Builtins ------------------ - -- bpo-33786: Fix asynchronous generators to handle GeneratorExit in athrow() - correctly - -- bpo-30654: Fixed reset of the SIGINT handler to SIG_DFL on interpreter - shutdown even when there was a custom handler set previously. Patch by - Philipp Kerling. - -- bpo-33622: Fixed a leak when the garbage collector fails to add an object - with the ``__del__`` method or referenced by it into the - :data:`gc.garbage` list. :c:func:`PyGC_Collect` can now be called when an - exception is set and preserves it. - -- bpo-31849: Fix signed/unsigned comparison warning in pyhash.c. - -- bpo-33391: Fix a leak in set_symmetric_difference(). - -- bpo-28055: Fix unaligned accesses in siphash24(). Patch by Rolf Eike Beer. - -- bpo-33231: Fix potential memory leak in ``normalizestring()``. - -- bpo-29922: Improved error messages in 'async with' when ``__aenter__()`` - or ``__aexit__()`` return non-awaitable object. - -- bpo-33199: Fix ``ma_version_tag`` in dict implementation is uninitialized - when copying from key-sharing dict. - -- bpo-33041: Fixed jumping when the function contains an ``async for`` loop. - -- bpo-32282: Fix an unnecessary ifdef in the include of VersionHelpers.h in - socketmodule on Windows. - -- bpo-21983: Fix a crash in `ctypes.cast()` in case the type argument is a - ctypes structured data type. Patch by Eryk Sun and Oren Milman. - -Library -------- - -- bpo-30167: Prevent site.main() exception if PYTHONSTARTUP is set. Patch by - Steve Weber. - -- bpo-33812: Datetime instance d with non-None tzinfo, but with - d.tzinfo.utcoffset(d) returning None is now treated as naive by the - astimezone() method. - -- bpo-30805: Avoid race condition with debug logging - -- bpo-33767: The concatenation (``+``) and repetition (``*``) sequence - operations now raise :exc:`TypeError` instead of :exc:`SystemError` when - performed on :class:`mmap.mmap` objects. Patch by Zackery Spytz. - -- bpo-32684: Fix gather to propagate cancellation of itself even with - return_exceptions. - -- bpo-33674: Fix a race condition in SSLProtocol.connection_made() of - asyncio.sslproto: start immediately the handshake instead of using - call_soon(). Previously, data_received() could be called before the - handshake started, causing the handshake to hang or fail. - -- bpo-31647: Fixed bug where calling write_eof() on a - _SelectorSocketTransport after it's already closed raises AttributeError. - -- bpo-33672: Fix Task.__repr__ crash with Cython's bogus coroutines - -- bpo-33469: Fix RuntimeError after closing loop that used run_in_executor - -- bpo-11874: Use a better regex when breaking usage into wrappable parts. - Avoids bogus assertion errors from custom metavar strings. - -- bpo-30877: Fixed a bug in the Python implementation of the JSON decoder - that prevented the cache of parsed strings from clearing after finishing - the decoding. Based on patch by c-fos. - -- bpo-33548: tempfile._candidate_tempdir_list should consider common TEMP - locations - -- bpo-33542: Prevent ``uuid.get_node`` from using a DUID instead of a MAC on - Windows. Patch by Zvi Effron - -- bpo-26819: Fix race condition with `ReadTransport.resume_reading` in - Windows proactor event loop. - -- bpo-28556: Minor fixes in typing module: add annotations to - ``NamedTuple.__new__``, pass ``*args`` and ``**kwds`` in - ``Generic.__new__``. Original PRs by Paulius Šarka and Chad Dombrova. - -- bpo-20087: Updated alias mapping with glibc 2.27 supported locales. - -- bpo-33422: Fix trailing quotation marks getting deleted when looking up - byte/string literals on pydoc. Patch by Andrés Delfino. - -- bpo-33197: Update error message when constructing invalid - inspect.Parameters Patch by Dong-hee Na. - -- bpo-33383: Fixed crash in the get() method of the :mod:`dbm.ndbm` database - object when it is called with a single argument. - -- bpo-33329: Fix multiprocessing regression on newer glibcs - -- bpo-991266: Fix quoting of the ``Comment`` attribute of - :class:`http.cookies.SimpleCookie`. - -- bpo-33131: Upgrade bundled version of pip to 10.0.1. - -- bpo-33308: Fixed a crash in the :mod:`parser` module when converting an ST - object to a tree of tuples or lists with ``line_info=False`` and - ``col_info=True``. - -- bpo-33263: Fix FD leak in `_SelectorSocketTransport` Patch by Vlad - Starostin. - -- bpo-33256: Fix display of ``<module>`` call in the html produced by - ``cgitb.html()``. Patch by Stéphane Blondon. - -- bpo-33203: ``random.Random.choice()`` now raises ``IndexError`` for empty - sequences consistently even when called from subclasses without a - ``getrandbits()`` implementation. - -- bpo-33224: Update difflib.mdiff() for :pep:`479`. Convert an uncaught - StopIteration in a generator into a return-statement. - -- bpo-33209: End framing at the end of C implementation of - :func:`pickle.Pickler.dump`. - -- bpo-32861: The urllib.robotparser's ``__str__`` representation now - includes wildcard entries and the "Crawl-delay" and "Request-rate" fields. - Patch by Michael Lazar. - -- bpo-33096: Allow ttk.Treeview.insert to insert iid that has a false - boolean value. Note iid=0 and iid=False would be same. Patch by Garvit - Khatri. - -- bpo-33127: The ssl module now compiles with LibreSSL 2.7.1. - -- bpo-33021: Release the GIL during fstat() calls, avoiding hang of all - threads when calling mmap.mmap(), os.urandom(), and random.seed(). Patch - by Nir Soffer. - -- bpo-27683: Fix a regression in :mod:`ipaddress` that result of - :meth:`hosts` is empty when the network is constructed by a tuple - containing an integer mask and only 1 bit left for addresses. - -- bpo-32844: Fix wrong redirection of a low descriptor (0 or 1) to stderr in - subprocess if another low descriptor is closed. - -- bpo-31908: Fix output of cover files for ``trace`` module command-line - tool. Previously emitted cover files only when ``--missing`` option was - used. Patch by Michael Selik. - -- bpo-31457: If nested log adapters are used, the inner ``process()`` - methods are no longer omitted. - -- bpo-16865: Support arrays >=2GiB in :mod:`ctypes`. Patch by Segev Finer. - -- bpo-31238: pydoc: the stop() method of the private ServerThread class now - waits until DocServer.serve_until_quit() completes and then explicitly - sets its docserver attribute to None to break a reference cycle. - -Documentation -------------- - -- bpo-33503: Fix broken pypi link - -- bpo-33421: Add missing documentation for ``typing.AsyncContextManager``. - -- bpo-33378: Add Korean language switcher for https://docs.python.org/3/ - -- bpo-33276: Clarify that the ``__path__`` attribute on modules cannot be - just any value. - -- bpo-33201: Modernize documentation for writing C extension types. - -- bpo-33195: Deprecate ``Py_UNICODE`` usage in ``c-api/arg`` document. - ``Py_UNICODE`` related APIs are deprecated since Python 3.3, but it is - missed in the document. - -- bpo-33126: Document PyBuffer_ToContiguous(). - -- bpo-27212: Modify documentation for the :func:`islice` recipe to consume - initial values up to the start index. - -- bpo-28247: Update :mod:`zipapp` documentation to describe how to make - standalone applications. - -- bpo-18802: Documentation changes for ipaddress. Patch by Jon Foster and - Berker Peksag. - -- bpo-27428: Update documentation to clarify that ``WindowsRegistryFinder`` - implements ``MetaPathFinder``. (Patch by Himanshu Lakhara) - -- bpo-8243: Add a note about curses.addch and curses.addstr exception - behavior when writing outside a window, or pad. - -- bpo-31432: Clarify meaning of CERT_NONE, CERT_OPTIONAL, and CERT_REQUIRED - flags for ssl.SSLContext.verify_mode. - -Tests ------ - -- bpo-33655: Ignore test_posix_fallocate failures on BSD platforms that - might be due to running on ZFS. - -- bpo-19417: Add test_bdb.py. - -Build ------ - -- bpo-5755: Move ``-Wstrict-prototypes`` option to ``CFLAGS_NODIST`` from - ``OPT``. This option emitted annoying warnings when building extension - modules written in C++. - -- bpo-33614: Ensures module definition files for the stable ABI on Windows - are correctly regenerated. - -- bpo-33522: Enable CI builds on Visual Studio Team Services at - https://python.visualstudio.com/cpython - -- bpo-33012: Add ``-Wno-cast-function-type`` for gcc 8 for silencing - warnings about function casts like casting to PyCFunction in method - definition lists. - -- bpo-33394: Enable the verbose build for extension modules, when GNU make - is passed macros on the command line. - -Windows -------- - -- bpo-33184: Update Windows installer to OpenSSL 1.0.2o. - -macOS ------ - -- bpo-33184: Update macOS installer build to use OpenSSL 1.0.2o. - -IDLE ----- - -- bpo-33656: On Windows, add API call saying that tk scales for DPI. On - Windows 8.1+ or 10, with DPI compatibility properties of the Python binary - unchanged, and a monitor resolution greater than 96 DPI, this should make - text and lines sharper. It should otherwise have no effect. - -- bpo-33768: Clicking on a context line moves that line to the top of the - editor window. - -- bpo-33763: IDLE: Use read-only text widget for code context instead of - label widget. - -- bpo-33664: Scroll IDLE editor text by lines. Previously, the mouse wheel - and scrollbar slider moved text by a fixed number of pixels, resulting in - partial lines at the top of the editor box. The change also applies to - the shell and grep output windows, but not to read-only text views. - -- bpo-33679: Enable theme-specific color configuration for Code Context. Use - the Highlights tab to see the setting for built-in themes or add settings - to custom themes. - -- bpo-33642: Display up to maxlines non-blank lines for Code Context. If - there is no current context, show a single blank line. - -- bpo-33628: IDLE: Cleanup codecontext.py and its test. - -- bpo-33564: IDLE's code context now recognizes async as a block opener. - -- bpo-29706: IDLE now colors async and await as keywords in 3.6. They become - full keywords in 3.7. - -- bpo-21474: Update word/identifier definition from ascii to unicode. In - text and entry boxes, this affects selection by double-click, movement - left/right by control-left/right, and deletion left/right by - control-BACKSPACE/DEL. - -- bpo-33204: IDLE: consistently color invalid string prefixes. A 'u' string - prefix cannot be paired with either 'r' or 'f'. Consistently color as much - of the prefix, starting at the right, as is valid. Revise and extend - colorizer test. - -- bpo-32831: Add docstrings and tests for codecontext. - -Tools/Demos ------------ - -- bpo-33189: :program:`pygettext.py` now recognizes only literal strings as - docstrings and translatable strings, and rejects bytes literals and - f-string expressions. - -- bpo-31920: Fixed handling directories as arguments in the ``pygettext`` - script. Based on patch by Oleg Krasnikov. - -- bpo-29673: Fix pystackv and pystack gdbinit macros. - -- bpo-32885: Add an ``-n`` flag for ``Tools/scripts/pathfix.py`` to disable - automatic backup creation (files with ``~`` suffix). - -- bpo-31583: Fix 2to3 for using with --add-suffix option but without - --output-dir option for relative path to files in current directory. - -C API ------ - -- bpo-32374: Document that m_traverse for multi-phase initialized modules - can be called with m_state=NULL, and add a sanity check - - -What's New in Python 3.6.5 final? -================================= - -*Release date: 2018-03-28* - -Tests ------ - -- bpo-32872: Avoid regrtest compatibility issue with namespace packages. - -Build ------ - -- bpo-33163: Upgrade pip to 9.0.3 and setuptools to v39.0.1. - - -What's New in Python 3.6.5 release candidate 1? -=============================================== - -*Release date: 2018-03-13* - -Security --------- - -- bpo-33001: Minimal fix to prevent buffer overrun in os.symlink on Windows - -- bpo-32981: Regexes in difflib and poplib were vulnerable to catastrophic - backtracking. These regexes formed potential DOS vectors (REDOS). They - have been refactored. This resolves CVE-2018-1060 and CVE-2018-1061. Patch - by Jamie Davis. - -Core and Builtins ------------------ - -- bpo-33026: Fixed jumping out of "with" block by setting f_lineno. - -- bpo-17288: Prevent jumps from 'return' and 'exception' trace events. - -- bpo-32889: Update Valgrind suppression list to account for the rename of - ``Py_ADDRESS_IN_RANG`` to ``address_in_range``. - -- bpo-32650: Pdb and other debuggers dependent on bdb.py will correctly step - over (next command) native coroutines. Patch by Pablo Galindo. - -- bpo-32685: Improve suggestion when the Python 2 form of print statement is - either present on the same line as the header of a compound statement or - else terminated by a semi-colon instead of a newline. Patch by Nitish - Chandra. - -- bpo-32583: Fix possible crashing in builtin Unicode decoders caused by - write out-of-bound errors when using customized decode error handlers. - -- bpo-26163: Improved frozenset() hash to create more distinct hash values - when faced with datasets containing many similar values. - -- bpo-27169: The ``__debug__`` constant is now optimized out at compile - time. This fixes also bpo-22091. - -- bpo-32329: ``sys.flags.hash_randomization`` is now properly set to 0 when - hash randomization is turned off by ``PYTHONHASHSEED=0``. - -- bpo-30416: The optimizer is now protected from spending much time doing - complex calculations and consuming much memory for creating large - constants in constant folding. - -- bpo-18533: ``repr()`` on a dict containing its own ``values()`` or - ``items()`` no longer raises ``RecursionError``; OrderedDict similarly. - Instead, use ``...``, as for other recursive structures. Patch by Ben - North. - -- bpo-32028: Leading whitespace is now correctly ignored when generating - suggestions for converting Py2 print statements to Py3 builtin print - function calls. Patch by Sanyam Khurana. - -- bpo-32137: The repr of deeply nested dict now raises a RecursionError - instead of crashing due to a stack overflow. - -Library -------- - -- bpo-33064: lib2to3 now properly supports trailing commas after ``*args`` - and ``**kwargs`` in function signatures. - -- bpo-31804: Avoid failing in multiprocessing.Process if the standard - streams are closed or None at exit. - -- bpo-33037: Skip sending/receiving data after SSL transport closing. - -- bpo-30353: Fix ctypes pass-by-value for structs on 64-bit Cygwin/MinGW. - -- bpo-33009: Fix inspect.signature() for single-parameter partialmethods. - -- bpo-32969: Expose several missing constants in zlib and fix corresponding - documentation. - -- bpo-32713: Fixed tarfile.itn handling of out-of-bounds float values. Patch - by Joffrey Fuhrer. - -- bpo-30622: The ssl module now detects missing NPN support in LibreSSL. - -- bpo-32922: dbm.open() now encodes filename with the filesystem encoding - rather than default encoding. - -- bpo-32859: In ``os.dup2``, don't check every call whether the ``dup3`` - syscall exists or not. - -- bpo-21060: Rewrite confusing message from setup.py upload from "No dist - file created in earlier command" to the more helpful "Must create and - upload files in one command". - -- bpo-32857: In :mod:`tkinter`, ``after_cancel(None)`` now raises a - :exc:`ValueError` instead of canceling the first scheduled function. - Patch by Cheryl Sabella. - -- bpo-32852: Make sure sys.argv remains as a list when running trace. - -- bpo-32841: Fixed `asyncio.Condition` issue which silently ignored - cancellation after notifying and cancelling a conditional lock. Patch by - Bar Harel. - -- bpo-31787: Fixed refleaks of ``__init__()`` methods in various modules. - (Contributed by Oren Milman) - -- bpo-30157: Fixed guessing quote and delimiter in csv.Sniffer.sniff() when - only the last field is quoted. Patch by Jake Davis. - -- bpo-32394: socket: Remove TCP_FASTOPEN, TCP_KEEPCNT flags on older version - Windows during run-time. - -- bpo-32777: Fix a rare but potential pre-exec child process deadlock in - subprocess on POSIX systems when marking file descriptors inheritable on - exec in the child process. This bug appears to have been introduced in - 3.4. - -- bpo-32647: The ctypes module used to depend on indirect linking for - dlopen. The shared extension is now explicitly linked against libdl on - platforms with dl. - -- bpo-32734: Fixed ``asyncio.Lock()`` safety issue which allowed acquiring - and locking the same lock multiple times, without it being free. Patch by - Bar Harel. - -- bpo-32727: Do not include name field in SMTP envelope from address. Patch - by Stéphane Wirtel - -- bpo-27931: Fix email address header parsing error when the username is an - empty quoted string. Patch by Xiang Zhang. - -- bpo-32304: distutils' upload command no longer corrupts tar files ending - with a CR byte, and no longer tries to convert CR to CRLF in any of the - upload text fields. - -- bpo-32502: uuid.uuid1 no longer raises an exception if a 64-bit hardware - address is encountered. - -- bpo-31848: Fix the error handling in Aifc_read.initfp() when the SSND - chunk is not found. Patch by Zackery Spytz. - -- bpo-32555: On FreeBSD and Solaris, os.strerror() now always decode the - byte string from the current locale encoding, rather than using - ASCII/surrogateescape in some cases. - -- bpo-32521: The nis module is now compatible with new libnsl and headers - location. - -- bpo-32473: Improve ABCMeta._dump_registry() output readability - -- bpo-32521: glibc has removed Sun RPC. Use replacement libtirpc headers and - library in nis module. - -- bpo-32228: Ensure that ``truncate()`` preserves the file position (as - reported by ``tell()``) after writes longer than the buffer size. - -- bpo-26133: Don't unsubscribe signals in asyncio UNIX event loop on - interpreter shutdown. - -- bpo-32185: The SSL module no longer sends IP addresses in SNI TLS - extension on platforms with OpenSSL 1.0.2+ or inet_pton. - -- bpo-32323: :func:`urllib.parse.urlsplit()` does not convert zone-id - (scope) to lower case for scoped IPv6 addresses in hostnames now. - -- bpo-32302: Fix bdist_wininst of distutils for CRT v142: it binary - compatible with CRT v140. - -- bpo-32255: A single empty field is now always quoted when written into a - CSV file. This allows to distinguish an empty row from a row consisting of - a single empty field. Patch by Licht Takeuchi. - -- bpo-32277: Raise ``NotImplementedError`` instead of ``SystemError`` on - platforms where ``chmod(..., follow_symlinks=False)`` is not supported. - Patch by Anthony Sottile. - -- bpo-32199: The getnode() ip getter now uses 'ip link' instead of 'ip link - list'. - -- bpo-27456: Ensure TCP_NODELAY is set on Linux. Tests by Victor Stinner. - -- bpo-31900: The :func:`locale.localeconv` function now sets temporarily the - ``LC_CTYPE`` locale to the ``LC_NUMERIC`` locale to decode - ``decimal_point`` and ``thousands_sep`` byte strings if they are non-ASCII - or longer than 1 byte, and the ``LC_NUMERIC`` locale is different than the - ``LC_CTYPE`` locale. This temporary change affects other threads. Same - change for the :meth:`str.format` method when formatting a number - (:class:`int`, :class:`float`, :class:`float` and subclasses) with the - ``n`` type (ex: ``'{:n}'.format(1234)``). - -- bpo-31802: Importing native path module (``posixpath``, ``ntpath``) now - works even if the ``os`` module still is not imported. - -Documentation -------------- - -- bpo-17232: Clarify docs for -O and -OO. Patch by Terry Reedy. - -- bpo-32800: Update link to w3c doc for xml default namespaces. - -- bpo-8722: Document :meth:`__getattr__` behavior when property :meth:`get` - method raises :exc:`AttributeError`. - -- bpo-32614: Modify RE examples in documentation to use raw strings to - prevent :exc:`DeprecationWarning` and add text to REGEX HOWTO to highlight - the deprecation. - -- bpo-31972: Improve docstrings for `pathlib.PurePath` subclasses. - -- bpo-17799: Explain real behaviour of sys.settrace and sys.setprofile and - their C-API counterparts regarding which type of events are received in - each function. Patch by Pablo Galindo Salgado. - -Tests ------ - -- bpo-32517: Fix failing ``test_asyncio`` on macOS 10.12.2+ due to transport - of ``KqueueSelector`` loop was not being closed. - -- bpo-32721: Fix test_hashlib to not fail if the _md5 module is not built. - -- bpo-32252: Fix faulthandler_suppress_crash_report() used to prevent core - dump files when testing crashes. getrlimit() returns zero on success. - -- bpo-31518: Debian Unstable has disabled TLS 1.0 and 1.1 for - SSLv23_METHOD(). Change TLS/SSL protocol of some tests to PROTOCOL_TLS or - PROTOCOL_TLSv1_2 to make them pass on Debian. - -Build ------ - -- bpo-32635: Fix segfault of the crypt module when libxcrypt is provided - instead of libcrypt at the system. - -Windows -------- - -- bpo-33016: Fix potential use of uninitialized memory in - nt._getfinalpathname - -- bpo-32903: Fix a memory leak in os.chdir() on Windows if the current - directory is set to a UNC path. - -- bpo-31966: Fixed WindowsConsoleIO.write() for writing empty data. - -- bpo-32409: Ensures activate.bat can handle Unicode contents. - -- bpo-32457: Improves handling of denormalized executable path when - launching Python. - -- bpo-32370: Use the correct encoding for ipconfig output in the uuid - module. Patch by Segev Finer. - -- bpo-29248: Fix :func:`os.readlink` on Windows, which was mistakenly - treating the ``PrintNameOffset`` field of the reparse data buffer as a - number of characters instead of bytes. Patch by Craig Holmquist and SSE4. - -- bpo-32588: Create standalone _distutils_findvs module. - -macOS ------ - -- bpo-32726: Provide an additional, more modern macOS installer variant that - supports macOS 10.9+ systems in 64-bit mode only. Upgrade the supplied - third-party libraries to OpenSSL 1.0.2n, XZ 5.2.3, and SQLite 3.22.0. The - 10.9+ installer now links with and supplies its own copy of Tcl/Tk 8.6.8. - -IDLE ----- - -- bpo-32984: Set ``__file__`` while running a startup file. Like Python, - IDLE optionally runs one startup file in the Shell window before - presenting the first interactive input prompt. For IDLE, ``-s`` runs a - file named in environmental variable :envvar:`IDLESTARTUP` or - :envvar:`PYTHONSTARTUP`; ``-r file`` runs ``file``. Python sets - ``__file__`` to the startup file name before running the file and unsets - it before the first prompt. IDLE now does the same when run normally, - without the ``-n`` option. - -- bpo-32940: Simplify and rename StringTranslatePseudoMapping in pyparse. - -- bpo-32916: Change ``str`` to ``code`` in pyparse. - -- bpo-32905: Remove unused code in pyparse module. - -- bpo-32874: Add tests for pyparse. - -- bpo-32837: Using the system and place-dependent default encoding for - open() is a bad idea for IDLE's system and location-independent files. - -- bpo-32826: Add "encoding=utf-8" to open() in IDLE's test_help_about. GUI - test test_file_buttons() only looks at initial ascii-only lines, but - failed on systems where open() defaults to 'ascii' because readline() - internally reads and decodes far enough ahead to encounter a non-ascii - character in CREDITS.txt. - -- bpo-32765: Update configdialog General tab docstring to add new widgets to - the widget list. - -Tools/Demos ------------ - -- bpo-24960: 2to3 and lib2to3 can now read pickled grammar files using - pkgutil.get_data() rather than probing the filesystem. This lets 2to3 and - lib2to3 work when run from a zipfile. - -- bpo-32222: Fix pygettext not extracting docstrings for functions with type - annotated arguments. Patch by Toby Harradine. - -C API ------ - -- bpo-29084: Undocumented C API for OrderedDict has been excluded from the - limited C API. It was added by mistake and actually never worked in the - limited C API. - - -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 - versionadded 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 manipulation 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. 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? -================================= - -*Release date: 2017-10-03* - -Library -------- - -- bpo-31641: Re-allow arbitrary iterables in - `concurrent.futures.as_completed()`. Fixes regression in 3.6.3rc1. - -Build ------ - -- bpo-31662: Fix typos in Windows ``uploadrelease.bat`` script. Fix Windows - Doc build issues in ``Doc/make.bat``. - -- bpo-31423: Fix building the PDF documentation with newer versions of - Sphinx. - - -What's New in Python 3.6.3 release candidate 1? -=============================================== - -*Release date: 2017-09-18* - -Security --------- - -- bpo-29781: SSLObject.version() now correctly returns None when handshake - over BIO has not been performed yet. - -- bpo-30947: Upgrade libexpat embedded copy from version 2.2.1 to 2.2.3 to - get security fixes. - -Core and Builtins ------------------ - -- bpo-31471: Fix an assertion failure in `subprocess.Popen()` on Windows, in - case the env argument has a bad keys() method. Patch by Oren Milman. - -- bpo-31418: Fix an assertion failure in `PyErr_WriteUnraisable()` in case - of an exception with a bad ``__module__`` attribute. Patch by Oren Milman. - -- bpo-31416: Fix assertion failures in case of a bad warnings.filters or - warnings.defaultaction. Patch by Oren Milman. - -- bpo-31411: Raise a TypeError instead of SystemError in case - warnings.onceregistry is not a dictionary. Patch by Oren Milman. - -- bpo-31373: Fix several possible instances of undefined behavior due to - floating-point demotions. - -- bpo-30465: Location information (``lineno`` and ``col_offset``) in - f-strings is now (mostly) correct. This fixes tools like flake8 from - showing warnings on the wrong line (typically the first line of the file). - -- bpo-31343: Include sys/sysmacros.h for major(), minor(), and makedev(). - GNU C libray plans to remove the functions from sys/types.h. - -- bpo-31291: Fix an assertion failure in `zipimport.zipimporter.get_data` on - Windows, when the return value of ``pathname.replace('/','\\')`` isn't a - string. Patch by Oren Milman. - -- bpo-31271: Fix an assertion failure in the write() method of - `io.TextIOWrapper`, when the encoder doesn't return a bytes object. Patch - by Oren Milman. - -- bpo-31243: Fix a crash in some methods of `io.TextIOWrapper`, when the - decoder's state is invalid. Patch by Oren Milman. - -- bpo-30721: ``print`` now shows correct usage hint for using Python 2 - redirection syntax. Patch by Sanyam Khurana. - -- bpo-31070: Fix a race condition in importlib _get_module_lock(). - -- bpo-31095: Fix potential crash during GC caused by ``tp_dealloc`` which - doesn't call ``PyObject_GC_UnTrack()``. - -- bpo-31071: Avoid masking original TypeError in call with * unpacking when - other arguments are passed. - -- bpo-30978: str.format_map() now passes key lookup exceptions through. - Previously any exception was replaced with a KeyError exception. - -- bpo-30808: Use _Py_atomic API for concurrency-sensitive signal state. - -- bpo-30876: Relative import from unloaded package now reimports the package - instead of failing with SystemError. Relative import from non-package now - fails with ImportError rather than SystemError. - -- bpo-30703: Improve signal delivery. Avoid using Py_AddPendingCall from - signal handler, to avoid calling signal-unsafe functions. The tests I'm - adding here fail without the rest of the patch, on Linux and OS X. This - means our signal delivery logic had defects (some signals could be lost). - -- bpo-30765: Avoid blocking in pthread_mutex_lock() when - PyThread_acquire_lock() is asked not to block. - -- bpo-31161: Make sure the 'Missing parentheses' syntax error message is - only applied to SyntaxError, not to subclasses. Patch by Martijn Pieters. - -- bpo-30814: Fixed a race condition when import a submodule from a package. - -- bpo-30597: ``print`` now shows expected input in custom error message when - used as a Python 2 statement. Patch by Sanyam Khurana. - -Library -------- - -- bpo-31499: xml.etree: Fix a crash when a parser is part of a reference - cycle. - -- bpo-28556: typing.get_type_hints now finds the right globalns for classes - and modules by default (when no ``globalns`` was specified by the caller). - -- bpo-28556: Speed improvements to the ``typing`` module. Original PRs by - Ivan Levkivskyi and Mitar. - -- bpo-31544: The C accelerator module of ElementTree ignored exceptions - raised when looking up TreeBuilder target methods in XMLParser(). - -- bpo-31234: socket.create_connection() now fixes manually a reference - cycle: clear the variable storing the last exception on success. - -- bpo-31457: LoggerAdapter objects can now be nested. - -- bpo-31400: Improves SSL error handling to avoid losing error numbers. - -- bpo-28958: ssl.SSLContext() now uses OpenSSL error information when a - context cannot be instantiated. - -- bpo-27340: SSLSocket.sendall() now uses memoryview to create slices of - data. This fixes support for all bytes-like object. It is also more - efficient and avoids costly copies. - -- bpo-31178: Fix string concatenation bug in rare error path in the - subprocess module - -- bpo-31350: Micro-optimize :func:`asyncio._get_running_loop` to become up - to 10% faster. - -- bpo-31170: expat: Update libexpat from 2.2.3 to 2.2.4. Fix copying of - partial characters for UTF-8 input (libexpat bug 115): - https://github.com/libexpat/libexpat/issues/115 - -- bpo-29136: Add TLS 1.3 cipher suites and OP_NO_TLSv1_3. - -- bpo-29212: Fix concurrent.futures.thread.ThreadPoolExecutor threads to - have a non repr() based thread name by default when no thread_name_prefix - is supplied. They will now identify themselves as - "ThreadPoolExecutor-y_n". - -- bpo-9146: Fix a segmentation fault in _hashopenssl when standard hash - functions such as md5 are not available in the linked OpenSSL library. As - in some special FIPS-140 build environments. - -- bpo-27144: The ``map()`` and ``as_completed()`` iterators in - ``concurrent.futures`` now avoid keeping a reference to yielded objects. - -- bpo-10746: Fix ctypes producing wrong :pep:`3118` type codes for integer - types. - -- bpo-22536: The subprocess module now sets the filename when - FileNotFoundError is raised on POSIX systems due to the executable or cwd - not being found. - -- bpo-31249: concurrent.futures: WorkItem.run() used by ThreadPoolExecutor - now breaks a reference cycle between an exception object and the WorkItem - object. - -- bpo-31247: xmlrpc.server now explicitly breaks reference cycles when using - sys.exc_info() in code handling exceptions. - -- bpo-30102: The ssl and hashlib modules now call - OPENSSL_add_all_algorithms_noconf() on OpenSSL < 1.1.0. The function - detects CPU features and enables optimizations on some CPU architectures - such as POWER8. Patch is based on research from Gustavo Serra Scalet. - -- bpo-31185: Fixed miscellaneous errors in asyncio speedup module. - -- bpo-31135: ttk: fix the destroy() method of LabeledScale and OptionMenu - classes. Call the parent destroy() method even if the used attribute - doesn't exist. The LabeledScale.destroy() method now also explicitly - clears label and scale attributes to help the garbage collector to destroy - all widgets. - -- bpo-31107: Fix `copyreg._slotnames()` mangled attribute calculation for - classes whose name begins with an underscore. Patch by Shane Harvey. - -- bpo-31061: Fixed a crash when using asyncio and threads. - -- bpo-30502: Fix handling of long oids in ssl. Based on patch by Christian - Heimes. - -- bpo-30119: ftplib.FTP.putline() now throws ValueError on commands that - contains CR or LF. Patch by Dong-hee Na. - -- bpo-30595: multiprocessing.Queue.get() with a timeout now polls its reader - in non-blocking mode if it succeeded to acquire the lock but the acquire - took longer than the timeout. - -- bpo-29403: Fix ``unittest.mock``'s autospec to not fail on method-bound - builtin functions. Patch by Aaron Gallagher. - -- bpo-30961: Fix decrementing a borrowed reference in tracemalloc. - -- bpo-25684: Change ``ttk.OptionMenu`` radiobuttons to be unique across - instances of ``OptionMenu``. - -- bpo-30886: Fix multiprocessing.Queue.join_thread(): it now waits until the - thread completes, even if the thread was started by the same process which - created the queue. - -- bpo-29854: Fix segfault in readline when using readline's history-size - option. Patch by Nir Soffer. - -- bpo-30319: socket.close() now ignores ECONNRESET error. - -- bpo-30828: Fix out of bounds write in - `asyncio.CFuture.remove_done_callback()`. - -- bpo-30807: signal.setitimer() may disable the timer when passed a tiny - value. Tiny values (such as 1e-6) are valid non-zero values for - setitimer(), which is specified as taking microsecond-resolution - intervals. However, on some platform, our conversion routine could convert - 1e-6 into a zero interval, therefore disabling the timer instead of - (re-)scheduling it. - -- bpo-30441: Fix bug when modifying os.environ while iterating over it - -- bpo-30532: Fix email header value parser dropping folding white space in - certain cases. - -- bpo-30879: os.listdir() and os.scandir() now emit bytes names when called - with bytes-like argument. - -- bpo-30746: Prohibited the '=' character in environment variable names in - ``os.putenv()`` and ``os.spawn*()``. - -- bpo-29755: Fixed the lgettext() family of functions in the gettext module. - They now always return bytes. - -Documentation -------------- - -- bpo-31294: Fix incomplete code snippet in the ZeroMQSocketListener and - ZeroMQSocketHandler examples and adapt them to Python 3. - -- bpo-21649: Add RFC 7525 and Mozilla server side TLS links to SSL - documentation. - -- bpo-30803: Clarify doc on truth value testing. Original patch by Peter - Thomassen. - -Tests ------ - -- bpo-31320: Silence traceback in test_ssl - -- bpo-25674: Remove sha256.tbs-internet.com ssl test - -- bpo-30715: Address ALPN callback changes for OpenSSL 1.1.0f. The latest - version behaves like OpenSSL 1.0.2 and no longer aborts handshake. - -- bpo-30822: regrtest: Exclude tzdata from regrtest --all. When running the - test suite using --use=all / -u all, exclude tzdata since it makes - test_datetime too slow (15-20 min on some buildbots) which then times out - on some buildbots. Fix also regrtest command line parser to allow passing - -u extralargefile to run test_zipfile64. - -Build ------ - -- bpo-30854: Fix compile error when compiling --without-threads. Patch by - Masayuki Yamamoto. - -Windows -------- - -- bpo-30389: Adds detection of Visual Studio 2017 to distutils on Windows. - -- bpo-31340: Change to building with MSVC v141 (included with Visual Studio - 2017) - -- bpo-30581: os.cpu_count() now returns the correct number of processors on - Windows when the number of logical processors is greater than 64. - -- bpo-30731: Add a missing xmlns to python.manifest so that it matches the - schema. - -IDLE ----- - -- bpo-31493: IDLE code context -- fix code update and font update timers. - Canceling timers prevents a warning message when test_idle completes. - -- bpo-31488: IDLE - Update non-key options in former extension classes. When - applying configdialog changes, call .reload for each feature class. Change - ParenMatch so updated options affect existing instances attached to - existing editor windows. - -- bpo-31477: IDLE - Improve rstrip entry in doc. Strip trailing whitespace - strips more than blank spaces. Multiline string literals are not skipped. - -- bpo-31480: IDLE - make tests pass with zzdummy extension disabled by - default. - -- bpo-31421: Document how IDLE runs tkinter programs. IDLE calls tcl/tk - update in the background in order to make live interaction and - experimentation with tkinter applications much easier. - -- bpo-31414: IDLE -- fix tk entry box tests by deleting first. Adding to an - int entry is not the same as deleting and inserting because int('') will - fail. - -- bpo-31051: Rearrange IDLE configdialog GenPage into Window, Editor, and - Help sections. - -- bpo-30617: IDLE - Add docstrings and tests for outwin subclass of editor. - Move some data and functions from the class to module level. Patch by - Cheryl Sabella. - -- bpo-31287: IDLE - Do not modify tkinter.message in test_configdialog. - -- bpo-27099: Convert IDLE's built-in 'extensions' to regular features. About - 10 IDLE features were implemented as supposedly optional extensions. Their - different behavior could be confusing or worse for users and not good for - maintenance. Hence the conversion. The main difference for users is that - user configurable key bindings for builtin features are now handled - uniformly. Now, editing a binding in a keyset only affects its value in - the keyset. All bindings are defined together in the system-specific - default keysets in config-extensions.def. All custom keysets are saved as - a whole in config-extension.cfg. All take effect as soon as one clicks - Apply or Ok. The affected events are '<<force-open-completions>>', - '<<expand-word>>', '<<force-open-calltip>>', '<<flash-paren>>', - '<<format-paragraph>>', '<<run-module>>', '<<check-module>>', and - '<<zoom-height>>'. Any (global) customizations made before 3.6.3 will not - affect their keyset-specific customization after 3.6.3. and vice versa. - Initial patch by Charles Wohlganger. - -- bpo-31206: IDLE: Factor HighPage(Frame) class from ConfigDialog. Patch by - Cheryl Sabella. - -- bpo-31001: Add tests for configdialog highlight tab. Patch by Cheryl - Sabella. - -- bpo-31205: IDLE: Factor KeysPage(Frame) class from ConfigDialog. The - slightly modified tests continue to pass. Patch by Cheryl Sabella. - -- bpo-31130: IDLE -- stop leaks in test_configdialog. Initial patch by - Victor Stinner. - -- bpo-31002: Add tests for configdialog keys tab. Patch by Cheryl Sabella. - -- bpo-19903: IDLE: Calltips use `inspect.signature` instead of - `inspect.getfullargspec`. This improves calltips for builtins converted to - use Argument Clinic. Patch by Louie Lu. - -- bpo-31083: IDLE - Add an outline of a TabPage class in configdialog. - Update existing classes to match outline. Initial patch by Cheryl Sabella. - -- bpo-31050: Factor GenPage(Frame) class from ConfigDialog. The slightly - modified tests continue to pass. Patch by Cheryl Sabella. - -- bpo-31004: IDLE - Factor FontPage(Frame) class from ConfigDialog. Slightly - modified tests continue to pass. Fix General tests. Patch mostly by Cheryl - Sabella. - -- bpo-30781: IDLE - Use ttk widgets in ConfigDialog. Patches by Terry Jan - Reedy and Cheryl Sabella. - -- bpo-31060: IDLE - Finish rearranging methods of ConfigDialog Grouping - methods pertaining to each tab and the buttons will aid writing tests and - improving the tabs and will enable splitting the groups into classes. - -- bpo-30853: IDLE -- Factor a VarTrace class out of ConfigDialog. Instance - tracers manages pairs consisting of a tk variable and a callback function. - When tracing is turned on, setting the variable calls the function. Test - coverage for the new class is 100%. - -- bpo-31003: IDLE: Add more tests for General tab. - -- bpo-30993: IDLE - Improve configdialog font page and tests. In - configdialog: Document causal pathways in create_font_tab docstring. - Simplify some attribute names. Move set_samples calls to var_changed_font - (idea from Cheryl Sabella). Move related functions to positions after the - create widgets function. In test_configdialog: Fix test_font_set so not - order dependent. Fix renamed test_indent_scale so it tests the widget. - Adjust tests for movement of set_samples call. Add tests for load - functions. Put all font tests in one class and tab indent tests in - another. Except for two lines, these tests completely cover the related - functions. - -- bpo-30981: IDLE -- Add more configdialog font page tests. - -- bpo-28523: IDLE: replace 'colour' with 'color' in configdialog. - -- bpo-30917: Add tests for idlelib.config.IdleConf. Increase coverage from - 46% to 96%. Patch by Louie Lu. - -- bpo-30934: Document coverage details for idlelib tests. Add section to - idlelib/idle-test/README.txt. Include check that branches are taken both - ways. Exclude IDLE-specific code that does not run during unit tests. - -- bpo-30913: IDLE: Document ConfigDialog tk Vars, methods, and widgets in - docstrings This will facilitate improving the dialog and splitting up the - class. Original patch by Cheryl Sabella. - -- bpo-30899: IDLE: Add tests for ConfigParser subclasses in config. Patch by - Louie Lu. - -- bpo-30881: IDLE: Add docstrings to browser.py. Patch by Cheryl Sabella. - -- bpo-30851: IDLE: Remove unused variables in configdialog. One is a - duplicate, one is set but cannot be altered by users. Patch by Cheryl - Sabella. - -- bpo-30870: IDLE: In Settings dialog, select font with Up, Down keys as - well as mouse. Initial patch by Louie Lu. - -- bpo-8231: IDLE: call config.IdleConf.GetUserCfgDir only once. - -- bpo-30779: IDLE: Factor ConfigChanges class from configdialog, put in - config; test. * In config, put dump test code in a function; run it and - unittest in 'if __name__ == '__main__'. * Add class config.ConfigChanges - based on changes_class_v4.py on bpo issue. * Add class - test_config.ChangesTest, partly using configdialog_tests_v1.py. * Revise - configdialog to use ConfigChanges; see tracker msg297804. * Revise - test_configdialog to match configdialog changes. * Remove configdialog - functions unused or moved to ConfigChanges. Cheryl Sabella contributed - parts of the patch. - -- bpo-30777: IDLE: configdialog - Add docstrings and fix comments. Patch by - Cheryl Sabella. - -- bpo-30495: IDLE: Improve textview with docstrings, PEP8 names, and more - tests. Patch by Cheryl Sabella. - -- bpo-30723: IDLE: Make several improvements to parenmatch. Add 'parens' - style to highlight both opener and closer. Make 'default' style, which is - not default, a synonym for 'opener'. Make time-delay work the same with - all styles. Add help for config dialog extensions tab, including help for - parenmatch. Add new tests. Original patch by Charles Wohlganger. - -- bpo-30674: IDLE: add docstrings to grep module. Patch by Cheryl Sabella - -- bpo-21519: IDLE's basic custom key entry dialog now detects duplicates - properly. Original patch by Saimadhav Heblikar. - -- bpo-29910: IDLE no longer deletes a character after commenting out a - region by a key shortcut. Add ``return 'break'`` for this and other - potential conflicts between IDLE and default key bindings. - -- bpo-30728: Review and change idlelib.configdialog names. Lowercase method - and attribute names. Replace 'colour' with 'color', expand overly cryptic - names, delete unneeded underscores. Replace ``import *`` with specific - imports. Patches by Cheryl Sabella. - -- bpo-6739: IDLE: Verify user-entered key sequences by trying to bind them - with tk. Add tests for all 3 validation functions. Original patch by G - Polo. Tests added by Cheryl Sabella. - -Tools/Demos ------------ - -- bpo-30983: gdb integration commands (py-bt, etc.) work on optimized shared - builds now, too. :pep:`523` introduced _PyEval_EvalFrameDefault which - inlines PyEval_EvalFrameEx on non-debug shared builds. This broke the - ability to use py-bt, py-up, and a few other Python-specific gdb - integrations. The problem is fixed by only looking for - _PyEval_EvalFrameDefault frames in python-gdb.py. Original patch by Bruno - "Polaco" Penteado. - - -What's New in Python 3.6.2 final? -================================= - -*Release date: 2017-07-17* - -No changes since release candidate 2 - - - -What's New in Python 3.6.2 release candidate 2? -=============================================== - -*Release date: 2017-07-07* - -Security --------- - -- bpo-30730: Prevent environment variables injection in subprocess on - Windows. Prevent passing other environment variables and command - arguments. - -- bpo-30694: Upgrade expat copy from 2.2.0 to 2.2.1 to get fixes of multiple - security vulnerabilities including: CVE-2017-9233 (External entity - infinite loop DoS), CVE-2016-9063 (Integer overflow, re-fix), - CVE-2016-0718 (Fix regression bugs from 2.2.0's fix to CVE-2016-0718) and - CVE-2012-0876 (Counter hash flooding with SipHash). Note: the - CVE-2016-5300 (Use os-specific entropy sources like getrandom) doesn't - impact Python, since Python already gets entropy from the OS to set the - expat secret using ``XML_SetHashSalt()``. - -- bpo-30500: Fix urllib.parse.splithost() to correctly parse fragments. For - example, ``splithost('//127.0.0.1#@evil.com/')`` now correctly returns the - ``127.0.0.1`` host, instead of treating ``@evil.com`` as the host in an - authentication (``login@host``). - - -What's New in Python 3.6.2 release candidate 1? -=============================================== - -*Release date: 2017-06-17* - -Security --------- - -- bpo-29591: Update expat copy from 2.1.1 to 2.2.0 to get fixes of - CVE-2016-0718 and CVE-2016-4472. See - https://sourceforge.net/p/expat/bugs/537/ for more information. - -Core and Builtins ------------------ - -- bpo-30682: Removed a too-strict assertion that failed for certain - f-strings, such as eval("f'\\\n'") and eval("f'\\\r'"). - -- bpo-30604: Move co_extra_freefuncs to not be per-thread to avoid crashes - -- bpo-29104: Fixed parsing backslashes in f-strings. - -- bpo-27945: Fixed various segfaults with dict when input collections are - mutated during searching, inserting or comparing. Based on patches by - Duane Griffin and Tim Mitchell. - -- bpo-25794: Fixed type.__setattr__() and type.__delattr__() for - non-interned attribute names. Based on patch by Eryk Sun. - -- bpo-30039: If a KeyboardInterrupt happens when the interpreter is in the - middle of resuming a chain of nested 'yield from' or 'await' calls, it's - now correctly delivered to the innermost frame. - -- bpo-12414: sys.getsizeof() on a code object now returns the sizes which - includes the code struct and sizes of objects which it references. Patch - by Dong-hee Na. - -- bpo-29949: Fix memory usage regression of set and frozenset object. - -- bpo-29935: Fixed error messages in the index() method of tuple, list and - deque when pass indices of wrong type. - -- bpo-29859: Show correct error messages when any of the pthread_* calls in - thread_pthread.h fails. - -- bpo-28876: ``bool(range)`` works even if ``len(range)`` raises - :exc:`OverflowError`. - -- bpo-29600: Fix wrapping coroutine return values in StopIteration. - -- bpo-28856: Fix an oversight that %b format for bytes should support - objects follow the buffer protocol. - -- bpo-29714: Fix a regression that bytes format may fail when containing - zero bytes inside. - -- bpo-29478: If max_line_length=None is specified while using the Compat32 - policy, it is no longer ignored. Patch by Mircea Cosbuc. - -Library -------- - -- bpo-30616: Functional API of enum allows to create empty enums. Patched by - Dong-hee Na - -- bpo-30038: Fix race condition between signal delivery and wakeup file - descriptor. Patch by Nathaniel Smith. - -- bpo-23894: lib2to3 now recognizes ``rb'...'`` and ``f'...'`` strings. - -- bpo-23890: unittest.TestCase.assertRaises() now manually breaks a - reference cycle to not keep objects alive longer than expected. - -- bpo-30149: inspect.signature() now supports callables with - variable-argument parameters wrapped with partialmethod. Patch by Dong-hee - Na. - -- bpo-30645: Fix path calculation in imp.load_package(), fixing it for cases - when a package is only shipped with bytecodes. Patch by Alexandru - Ardelean. - -- bpo-29931: Fixed comparison check for ipaddress.ip_interface objects. - Patch by Sanjay Sundaresan. - -- bpo-30605: re.compile() no longer raises a BytesWarning when compiling a - bytes instance with misplaced inline modifier. Patch by Roy Williams. - -- bpo-24484: Avoid race condition in multiprocessing cleanup (#2159) - -- bpo-28994: The traceback no longer displayed for SystemExit raised in a - callback registered by atexit. - -- bpo-30508: Don't log exceptions if Task/Future "cancel()" method was - called. - -- bpo-28556: Updates to typing module: Add generic AsyncContextManager, add - support for ContextManager on all versions. Original PRs by Jelle Zijlstra - and Ivan Levkivskyi - -- bpo-29870: Fix ssl sockets leaks when connection is aborted in asyncio/ssl - implementation. Patch by Michaël Sghaïer. - -- bpo-29743: Closing transport during handshake process leaks open socket. - Patch by Nikolay Kim - -- bpo-27585: Fix waiter cancellation in asyncio.Lock. Patch by Mathieu - Sornay. - -- bpo-30418: On Windows, subprocess.Popen.communicate() now also ignore - EINVAL on stdin.write() if the child process is still running but closed - the pipe. - -- bpo-29822: inspect.isabstract() now works during __init_subclass__. Patch - by Nate Soares. - -- bpo-29581: ABCMeta.__new__ now accepts ``**kwargs``, allowing abstract - base classes to use keyword parameters in __init_subclass__. Patch by Nate - Soares. - -- bpo-30557: faulthandler now correctly filters and displays exception codes - on Windows - -- bpo-30378: Fix the problem that logging.handlers.SysLogHandler cannot - handle IPv6 addresses. - -- bpo-29960: Preserve generator state when _random.Random.setstate() raises - an exception. Patch by Bryan Olson. - -- bpo-30414: multiprocessing.Queue._feed background running thread do not - break from main loop on exception. - -- bpo-30003: Fix handling escape characters in HZ codec. Based on patch by - Ma Lin. - -- bpo-30301: Fix AttributeError when using SimpleQueue.empty() under *spawn* - and *forkserver* start methods. - -- bpo-30329: imaplib and poplib now catch the Windows socket WSAEINVAL error - (code 10022) on shutdown(SHUT_RDWR): An invalid operation was attempted. - This error occurs sometimes on SSL connections. - -- bpo-30375: Warnings emitted when compile a regular expression now always - point to the line in the user code. Previously they could point into - inners of the re module if emitted from inside of groups or conditionals. - -- bpo-30048: Fixed ``Task.cancel()`` can be ignored when the task is running - coroutine and the coroutine returned without any more ``await``. - -- bpo-30266: contextlib.AbstractContextManager now supports - anti-registration by setting __enter__ = None or __exit__ = None, - following the pattern introduced in bpo-25958. Patch by Jelle Zijlstra. - -- bpo-30298: Weaken the condition of deprecation warnings for inline - modifiers. Now allowed several subsequential inline modifiers at the start - of the pattern (e.g. ``'(?i)(?s)...'``). In verbose mode whitespaces and - comments now are allowed before and between inline modifiers (e.g. ``'(?x) - (?i) (?s)...'``). - -- bpo-29990: Fix range checking in GB18030 decoder. Original patch by Ma - Lin. - -- bpo-26293: Change resulted because of zipfile breakage. (See also: - bpo-29094) - -- bpo-30243: Removed the __init__ methods of _json's scanner and encoder. - Misusing them could cause memory leaks or crashes. Now scanner and - encoder objects are completely initialized in the __new__ methods. - -- bpo-30185: Avoid KeyboardInterrupt tracebacks in forkserver helper process - when Ctrl-C is received. - -- bpo-28556: Various updates to typing module: add typing.NoReturn type, use - WrapperDescriptorType, minor bug-fixes. Original PRs by Jim - Fasarakis-Hilliard and Ivan Levkivskyi. - -- bpo-30205: Fix getsockname() for unbound AF_UNIX sockets on Linux. - -- bpo-30070: Fixed leaks and crashes in errors handling in the parser - module. - -- bpo-30061: Fixed crashes in IOBase methods __next__() and readlines() when - readline() or __next__() respectively return non-sizeable object. Fixed - possible other errors caused by not checking results of PyObject_Size(), - PySequence_Size(), or PyMapping_Size(). - -- bpo-30017: Allowed calling the close() method of the zip entry writer - object multiple times. Writing to a closed writer now always produces a - ValueError. - -- bpo-30068: _io._IOBase.readlines will check if it's closed first when hint - is present. - -- bpo-29694: Fixed race condition in pathlib mkdir with flags parents=True. - Patch by Armin Rigo. - -- bpo-29692: Fixed arbitrary unchaining of RuntimeError exceptions in - contextlib.contextmanager. Patch by Siddharth Velankar. - -- bpo-29998: Pickling and copying ImportError now preserves name and path - attributes. - -- bpo-29953: Fixed memory leaks in the replace() method of datetime and time - objects when pass out of bound fold argument. - -- bpo-29942: Fix a crash in itertools.chain.from_iterable when encountering - long runs of empty iterables. - -- bpo-27863: Fixed multiple crashes in ElementTree caused by race conditions - and wrong types. - -- bpo-28699: Fixed a bug in pools in multiprocessing.pool that raising an - exception at the very first of an iterable may swallow the exception or - make the program hang. Patch by Davin Potts and Xiang Zhang. - -- bpo-25803: Avoid incorrect errors raised by Path.mkdir(exist_ok=True) when - the OS gives priority to errors such as EACCES over EEXIST. - -- bpo-29861: Release references to tasks, their arguments and their results - as soon as they are finished in multiprocessing.Pool. - -- bpo-29884: faulthandler: Restore the old sigaltstack during teardown. - Patch by Christophe Zeitouny. - -- bpo-25455: Fixed crashes in repr of recursive buffered file-like objects. - -- bpo-29800: Fix crashes in partial.__repr__ if the keys of partial.keywords - are not strings. Patch by Michael Seifert. - -- bpo-29742: get_extra_info() raises exception if get called on closed ssl - transport. Patch by Nikolay Kim. - -- bpo-8256: Fixed possible failing or crashing input() if attributes - "encoding" or "errors" of sys.stdin or sys.stdout are not set or are not - strings. - -- bpo-28298: Fix a bug that prevented array 'Q', 'L' and 'I' from accepting - big intables (objects that have __int__) as elements. Patch by Oren - Milman. - -- bpo-28231: The zipfile module now accepts path-like objects for external - paths. - -- bpo-26915: index() and count() methods of collections.abc.Sequence now - check identity before checking equality when do comparisons. - -- bpo-29615: SimpleXMLRPCDispatcher no longer chains KeyError (or any other - exception) to exception(s) raised in the dispatched methods. Patch by Petr - Motejlek. - -- bpo-30177: path.resolve(strict=False) no longer cuts the path after the - first element not present in the filesystem. Patch by Antoine Pietri. - -IDLE ----- - -- bpo-15786: Fix several problems with IDLE's autocompletion box. The - following should now work: clicking on selection box items; using the - scrollbar; selecting an item by hitting Return. Hangs on MacOSX should no - longer happen. Patch by Louie Lu. - -- bpo-25514: Add doc subsubsection about IDLE failure to start. Popup - no-connection message directs users to this section. - -- bpo-30642: Fix reference leaks in IDLE tests. Patches by Louie Lu and - Terry Jan Reedy. - -- bpo-30495: Add docstrings for textview.py and use PEP8 names. Patches by - Cheryl Sabella and Terry Jan Reedy. - -- bpo-30290: Help-about: use pep8 names and add tests. Increase coverage to - 100%. Patches by Louie Lu, Cheryl Sabella, and Terry Jan Reedy. - -- bpo-30303: Add _utest option to textview; add new tests. Increase coverage - to 100%. Patches by Louie Lu and Terry Jan Reedy. - -C API ------ - -- bpo-27867: Function PySlice_GetIndicesEx() no longer replaced with a macro - if Py_LIMITED_API is not set. - -Build ------ - -- bpo-29941: Add ``--with-assertions`` configure flag to explicitly enable C - ``assert()`` checks. Defaults to off. ``--with-pydebug`` implies - ``--with-assertions``. - -- bpo-28787: Fix out-of-tree builds of Python when configured with - ``--with--dtrace``. - -- bpo-29243: Prevent unnecessary rebuilding of Python during ``make test``, - ``make install`` and some other make targets when configured with - ``--enable-optimizations``. - -- bpo-23404: Don't regenerate generated files based on file modification - time anymore: the action is now explicit. Replace ``make touch`` with - ``make regen-all``. - -- bpo-29643: Fix ``--enable-optimization`` didn't work. - -Documentation -------------- - -- bpo-30176: Add missing attribute related constants in curses - documentation. - -- bpo-30052: the link targets for :func:`bytes` and :func:`bytearray` are - now their respective type definitions, rather than the corresponding - builtin function entries. Use :ref:`bytes <func-bytes>` and - :ref:`bytearray <func-bytearray>` to reference the latter. In order to - ensure this and future cross-reference updates are applied automatically, - the daily documentation builds now disable the default output caching - features in Sphinx. - -- bpo-26985: Add missing info of code object in inspect documentation. - -Tools/Demos ------------ - -- bpo-29367: python-gdb.py now supports also ``method-wrapper`` - (``wrapperobject``) objects. - -Tests ------ - -- bpo-30357: test_thread: setUp() now uses support.threading_setup() and - support.threading_cleanup() to wait until threads complete to avoid random - side effects on following tests. Initial patch written by Grzegorz - Grzywacz. - -- bpo-30197: Enhanced functions swap_attr() and swap_item() in the - test.support module. They now work when delete replaced attribute or item - inside the with statement. The old value of the attribute or item (or - None if it doesn't exist) now will be assigned to the target of the "as" - clause, if there is one. - -Windows -------- - -- bpo-30687: Locate msbuild.exe on Windows when building rather than - vcvarsall.bat - -- bpo-30450: The build process on Windows no longer depends on Subversion, - instead pulling external code from GitHub via a Python script. If Python - 3.6 is not found on the system (via ``py -3.6``), NuGet is used to - download a copy of 32-bit Python. - - -What's New in Python 3.6.1 final? -================================= - -*Release date: 2017-03-21* - -Core and Builtins ------------------ - -- bpo-29723: The ``sys.path[0]`` initialization change for bpo-29139 caused - a regression by revealing an inconsistency in how sys.path is initialized - when executing ``__main__`` from a zipfile, directory, or other import - location. The interpreter now consistently avoids ever adding the import - location's parent directory to ``sys.path``, and ensures no other - ``sys.path`` entries are inadvertently modified when inserting the import - location named on the command line. - -Build ------ - -- bpo-27593: fix format of git information used in sys.version - -- Fix incompatible comment in python.h - - -What's New in Python 3.6.1 release candidate 1? -=============================================== - -*Release date: 2017-03-04* - -Core and Builtins ------------------ - -- bpo-28893: Set correct __cause__ for errors about invalid awaitables - returned from __aiter__ and __anext__. - -- bpo-29683: Fixes to memory allocation in _PyCode_SetExtra. Patch by Brian - Coleman. - -- bpo-29684: Fix minor regression of PyEval_CallObjectWithKeywords. It - should raise TypeError when kwargs is not a dict. But it might cause segv - when args=NULL and kwargs is not a dict. - -- bpo-28598: Support __rmod__ for subclasses of str being called before - str.__mod__. Patch by Martijn Pieters. - -- bpo-29607: Fix stack_effect computation for CALL_FUNCTION_EX. Patch by - Matthieu Dartiailh. - -- bpo-29602: Fix incorrect handling of signed zeros in complex constructor - for complex subclasses and for inputs having a __complex__ method. Patch - by Serhiy Storchaka. - -- bpo-29347: Fixed possibly dereferencing undefined pointers when creating - weakref objects. - -- bpo-29438: Fixed use-after-free problem in key sharing dict. - -- bpo-29319: Prevent RunMainFromImporter overwriting sys.path[0]. - -- bpo-29337: Fixed possible BytesWarning when compare the code objects. - Warnings could be emitted at compile time. - -- bpo-29327: Fixed a crash when pass the iterable keyword argument to - sorted(). - -- bpo-29034: Fix memory leak and use-after-free in os module - (path_converter). - -- bpo-29159: Fix regression in bytes(x) when x.__index__() raises Exception. - -- bpo-28932: Do not include <sys/random.h> if it does not exist. - -- bpo-25677: Correct the positioning of the syntax error caret for indented - blocks. Based on patch by Michael Layzell. - -- bpo-29000: Fixed bytes formatting of octals with zero padding in alternate - form. - -- bpo-26919: On Android, operating system data is now always encoded/decoded - to/from UTF-8, instead of the locale encoding to avoid inconsistencies - with os.fsencode() and os.fsdecode() which are already using UTF-8. - -- bpo-28991: functools.lru_cache() was susceptible to an obscure reentrancy - bug triggerable by a monkey-patched len() function. - -- bpo-28739: f-string expressions are no longer accepted as docstrings and - by ast.literal_eval() even if they do not include expressions. - -- bpo-28512: Fixed setting the offset attribute of SyntaxError by - PyErr_SyntaxLocationEx() and PyErr_SyntaxLocationObject(). - -- bpo-28918: Fix the cross compilation of xxlimited when Python has been - built with Py_DEBUG defined. - -- bpo-28731: Optimize _PyDict_NewPresized() to create correct size dict. - Improve speed of dict literal with constant keys up to 30%. - -Library -------- - -- bpo-29169: Update zlib to 1.2.11. - -- bpo-29623: Allow use of path-like object as a single argument in - ConfigParser.read(). Patch by David Ellis. - -- bpo-28963: Fix out of bound iteration in - asyncio.Future.remove_done_callback implemented in C. - -- bpo-29704: asyncio.subprocess.SubprocessStreamProtocol no longer closes - before all pipes are closed. - -- bpo-29271: Fix Task.current_task and Task.all_tasks implemented in C to - accept None argument as their pure Python implementation. - -- bpo-29703: Fix asyncio to support instantiation of new event loops in - child processes. - -- bpo-29376: Fix assertion error in threading._DummyThread.is_alive(). - -- bpo-28624: Add a test that checks that cwd parameter of Popen() accepts - PathLike objects. Patch by Sayan Chowdhury. - -- bpo-28518: Start a transaction implicitly before a DML statement. Patch by - Aviv Palivoda. - -- bpo-29532: Altering a kwarg dictionary passed to functools.partial() no - longer affects a partial object after creation. - -- bpo-29110: Fix file object leak in aifc.open() when file is given as a - filesystem path and is not in valid AIFF format. Patch by Anthony Zhang. - -- bpo-28556: Various updates to typing module: typing.Counter, - typing.ChainMap, improved ABC caching, etc. Original PRs by Jelle - Zijlstra, Ivan Levkivskyi, Manuel Krebber, and Łukasz Langa. - -- bpo-29100: Fix datetime.fromtimestamp() regression introduced in Python - 3.6.0: check minimum and maximum years. - -- bpo-29519: Fix weakref spewing exceptions during interpreter shutdown when - used with a rare combination of multiprocessing and custom codecs. - -- bpo-29416: Prevent infinite loop in pathlib.Path.mkdir - -- bpo-29444: Fixed out-of-bounds buffer access in the group() method of the - match object. Based on patch by WGH. - -- bpo-29335: Fix subprocess.Popen.wait() when the child process has exited - to a stopped instead of terminated state (ex: when under ptrace). - -- bpo-29290: Fix a regression in argparse that help messages would wrap at - non-breaking spaces. - -- bpo-28735: Fixed the comparison of mock.MagickMock with mock.ANY. - -- bpo-29316: Restore the provisional status of typing module, add - corresponding note to documentation. Patch by Ivan L. - -- bpo-29219: Fixed infinite recursion in the repr of uninitialized - ctypes.CDLL instances. - -- bpo-29011: Fix an important omission by adding Deque to the typing module. - -- bpo-28969: Fixed race condition in C implementation of - functools.lru_cache. KeyError could be raised when cached function with - full cache was simultaneously called from different threads with the same - uncached arguments. - -- bpo-29142: In urllib.request, suffixes in no_proxy environment variable - with leading dots could match related hostnames again (e.g. .b.c matches - a.b.c). Patch by Milan Oberkirch. - -- bpo-28961: Fix unittest.mock._Call helper: don't ignore the name parameter - anymore. Patch written by Jiajun Huang. - -- bpo-29203: functools.lru_cache() now respects :pep:`468` and preserves the - order of keyword arguments. f(a=1, b=2) is now cached separately from - f(b=2, a=1) since both calls could potentially give different results. - -- bpo-15812: inspect.getframeinfo() now correctly shows the first line of a - context. Patch by Sam Breese. - -- bpo-29094: Offsets in a ZIP file created with extern file object and modes - "w" and "x" now are relative to the start of the file. - -- bpo-29085: Allow random.Random.seed() to use high quality OS randomness - rather than the pid and time. - -- bpo-29061: Fixed bug in secrets.randbelow() which would hang when given a - negative input. Patch by Brendan Donegan. - -- bpo-29079: Prevent infinite loop in pathlib.resolve() on Windows - -- bpo-13051: Fixed recursion errors in large or resized - curses.textpad.Textbox. Based on patch by Tycho Andersen. - -- bpo-29119: Fix weakrefs in the pure python version of - collections.OrderedDict move_to_end() method. Contributed by Andra - Bogildea. - -- bpo-9770: curses.ascii predicates now work correctly with negative - integers. - -- bpo-28427: old keys should not remove new values from WeakValueDictionary - when collecting from another thread. - -- bpo-28923: Remove editor artifacts from Tix.py. - -- bpo-29055: Neaten-up empty population error on random.choice() by - suppressing the upstream exception. - -- bpo-28871: Fixed a crash when deallocate deep ElementTree. - -- bpo-19542: Fix bugs in WeakValueDictionary.setdefault() and - WeakValueDictionary.pop() when a GC collection happens in another thread. - -- bpo-20191: Fixed a crash in resource.prlimit() when passing a sequence - that doesn't own its elements as limits. - -- bpo-28779: multiprocessing.set_forkserver_preload() would crash the - forkserver process if a preloaded module instantiated some multiprocessing - objects such as locks. - -- bpo-28847: dbm.dumb now supports reading read-only files and no longer - writes the index file when it is not changed. - -- bpo-26937: The chown() method of the tarfile.TarFile class does not fail - now when the grp module cannot be imported, as for example on Android - platforms. - -IDLE ----- - -- bpo-29071: IDLE colors f-string prefixes (but not invalid ur prefixes). - -- bpo-28572: Add 10% to coverage of IDLE's test_configdialog. Update and - augment description of the configuration system. - -Windows -------- - -- bpo-29579: Removes readme.txt from the installer - -- bpo-29326: Ignores blank lines in ._pth files (Patch by Alexey Izbyshev) - -- bpo-28164: Correctly handle special console filenames (patch by Eryk Sun) - -- bpo-29409: Implement :pep:`529` for io.FileIO (Patch by Eryk Sun) - -- bpo-29392: Prevent crash when passing invalid arguments into msvcrt - module. - -- bpo-25778: winreg does not truncate string correctly (Patch by Eryk Sun) - -- bpo-28896: Deprecate WindowsRegistryFinder and disable it by default. - -C API ------ - -- bpo-27867: Function PySlice_GetIndicesEx() is replaced with a macro if - Py_LIMITED_API is not set or set to the value between 0x03050400 and - 0x03060000 (not including) or 0x03060100 or higher. - -- bpo-29083: Fixed the declaration of some public API functions. - PyArg_VaParse() and PyArg_VaParseTupleAndKeywords() were not available in - limited API. PyArg_ValidateKeywordArguments(), PyArg_UnpackTuple() and - Py_BuildValue() were not available in limited API of version < 3.3 when - PY_SSIZE_T_CLEAN is defined. - -- bpo-29058: All stable API extensions added after Python 3.2 are now - available only when Py_LIMITED_API is set to the PY_VERSION_HEX value of - the minimum Python version supporting this API. - -Documentation -------------- - -- bpo-28929: Link the documentation to its source file on GitHub. - -- bpo-25008: Document smtpd.py as effectively deprecated and add a pointer - to aiosmtpd, a third-party asyncio-based replacement. - -- bpo-26355: Add canonical header link on each page to corresponding major - version of the documentation. Patch by Matthias Bussonnier. - -- bpo-29349: Fix Python 2 syntax in code for building the documentation. - -Tests ------ - -- bpo-28087: Skip test_asyncore and test_eintr poll failures on macOS. Skip - some tests of select.poll when running on macOS due to unresolved issues - with the underlying system poll function on some macOS versions. - -- bpo-29571: to match the behaviour of the ``re.LOCALE`` flag, - test_re.test_locale_flag now uses ``locale.getpreferredencoding(False)`` - to determine the candidate encoding for the test regex (allowing it to - correctly skip the test when the default locale encoding is a multi-byte - encoding) - -- bpo-28950: Disallow -j0 to be combined with -T/-l in regrtest command line - arguments. - -- bpo-28683: Fix the tests that bind() a unix socket and raise - PermissionError on Android for a non-root user. - -- bpo-26939: Add the support.setswitchinterval() function to fix - test_functools hanging on the Android armv7 qemu emulator. - -Build ------ - -- bpo-27593: sys.version and the platform module python_build(), - python_branch(), and python_revision() functions now use git information - rather than hg when building from a repo. - -- bpo-29572: Update Windows build and OS X installers to use OpenSSL 1.0.2k. - -- bpo-26851: Set Android compilation and link flags. - -- bpo-28768: Fix implicit declaration of function _setmode. Patch by - Masayuki Yamamoto - -- bpo-29080: Removes hard dependency on hg.exe from PCBuild/build.bat - -- bpo-23903: Added missed names to PC/python3.def. - -- bpo-28762: lockf() is available on Android API level 24, but the F_LOCK - macro is not defined in android-ndk-r13. - -- bpo-28538: Fix the compilation error that occurs because if_nameindex() is - available on Android API level 24, but the if_nameindex structure is not - defined. - -- bpo-20211: Do not add the directory for installing C header files and the - directory for installing object code libraries to the cross compilation - search paths. Original patch by Thomas Petazzoni. - -- bpo-28849: Do not define sys.implementation._multiarch on Android. - - -What's New in Python 3.6.0 final? -================================= - -*Release date: 2016-12-23* - -No changes since release candidate 2 - - - -What's New in Python 3.6.0 release candidate 2? -=============================================== - -*Release date: 2016-12-16* - -Core and Builtins ------------------ - -- bpo-28147: Fix a memory leak in split-table dictionaries: setattr() must - not convert combined table into split table. Patch written by INADA Naoki. - -- bpo-28990: Fix asyncio SSL hanging if connection is closed before - handshake is completed. (Patch by HoHo-Ho) - -Tools/Demos ------------ - -- bpo-28770: Fix python-gdb.py for fastcalls. - -Windows -------- - -- bpo-28896: Deprecate WindowsRegistryFinder. - -Build ------ - -- bpo-28898: Prevent gdb build errors due to HAVE_LONG_LONG redefinition. - - -What's New in Python 3.6.0 release candidate 1? -=============================================== - -*Release date: 2016-12-06* - -Core and Builtins ------------------ - -- bpo-23722: Rather than silently producing a class that doesn't support - zero-argument ``super()`` in methods, failing to pass the new - ``__classcell__`` namespace entry up to ``type.__new__`` now results in a - ``DeprecationWarning`` and a class that supports zero-argument - ``super()``. - -- bpo-28797: Modifying the class __dict__ inside the __set_name__ method of - a descriptor that is used inside that class no longer prevents calling the - __set_name__ method of other descriptors. - -- bpo-28782: Fix a bug in the implementation ``yield from`` when checking if - the next instruction is YIELD_FROM. Regression introduced by WORDCODE - (issue #26647). - -Library -------- - -- bpo-27030: Unknown escapes in re.sub() replacement template are allowed - again. But they still are deprecated and will be disabled in 3.7. - -- bpo-28835: Fix a regression introduced in warnings.catch_warnings(): call - warnings.showwarning() if it was overridden inside the context manager. - -- bpo-27172: To assist with upgrades from 2.7, the previously documented - deprecation of ``inspect.getfullargspec()`` has been reversed. This - decision may be revisited again after the Python 2.7 branch is no longer - officially supported. - -- bpo-26273: Add new :data:`socket.TCP_CONGESTION` (Linux 2.6.13) and - :data:`socket.TCP_USER_TIMEOUT` (Linux 2.6.37) constants. Patch written by - Omar Sandoval. - -- bpo-24142: Reading a corrupt config file left configparser in an invalid - state. Original patch by Florian Höch. - -- bpo-28843: Fix asyncio C Task to handle exceptions __traceback__. - -C API ------ - -- bpo-28808: PyUnicode_CompareWithASCIIString() now never raises exceptions. - -Documentation -------------- - -- bpo-23722: The data model reference and the porting section in the What's - New guide now cover the additional ``__classcell__`` handling needed for - custom metaclasses to fully support :pep:`487` and zero-argument - ``super()``. - -Tools/Demos ------------ - -- bpo-28023: Fix python-gdb.py didn't support new dict implementation. - - -What's New in Python 3.6.0 beta 4? -================================== - -*Release date: 2016-11-21* - -Core and Builtins ------------------ - -- bpo-28532: Show sys.version when -V option is supplied twice. - -- bpo-27100: The with-statement now checks for __enter__ before it checks - for __exit__. This gives less confusing error messages when both methods - are missing. Patch by Jonathan Ellington. - -- bpo-28746: Fix the set_inheritable() file descriptor method on platforms - that do not have the ioctl FIOCLEX and FIONCLEX commands. - -- bpo-26920: Fix not getting the locale's charset upon initializing the - interpreter, on platforms that do not have langinfo. - -- bpo-28648: Fixed crash in Py_DecodeLocale() in debug build on Mac OS X - when decode astral characters. Patch by Xiang Zhang. - -- bpo-19398: Extra slash no longer added to sys.path components in case of - empty compile-time PYTHONPATH components. - -- bpo-28665: Improve speed of the STORE_DEREF opcode by 40%. - -- bpo-28583: PyDict_SetDefault didn't combine split table when needed. Patch - by Xiang Zhang. - -- bpo-27243: Change PendingDeprecationWarning -> DeprecationWarning. As it - was agreed in the issue, __aiter__ returning an awaitable should result in - PendingDeprecationWarning in 3.5 and in DeprecationWarning in 3.6. - -- bpo-26182: Fix a refleak in code that raises DeprecationWarning. - -- bpo-28721: Fix asynchronous generators aclose() and athrow() to handle - StopAsyncIteration propagation properly. - -Library -------- - -- bpo-28752: Restored the __reduce__() methods of datetime objects. - -- bpo-28727: Regular expression patterns, _sre.SRE_Pattern objects created - by re.compile(), become comparable (only x==y and x!=y operators). This - change should fix the issue #18383: don't duplicate warning filters when - the warnings module is reloaded (thing usually only done in unit tests). - -- bpo-20572: The subprocess.Popen.wait method's undocumented endtime - parameter now raises a DeprecationWarning. - -- bpo-25659: In ctypes, prevent a crash calling the from_buffer() and - from_buffer_copy() methods on abstract classes like Array. - -- bpo-19717: Makes Path.resolve() succeed on paths that do not exist. Patch - by Vajrasky Kok - -- bpo-28563: Fixed possible DoS and arbitrary code execution when handle - plural form selections in the gettext module. The expression parser now - supports exact syntax supported by GNU gettext. - -- bpo-28387: Fixed possible crash in _io.TextIOWrapper deallocator when the - garbage collector is invoked in other thread. Based on patch by Sebastian - Cufre. - -- bpo-28600: Optimize loop.call_soon. - -- bpo-28613: Fix get_event_loop() return the current loop if called from - coroutines/callbacks. - -- bpo-28634: Fix asyncio.isfuture() to support unittest.Mock. - -- bpo-26081: Fix refleak in _asyncio.Future.__iter__().throw. - -- bpo-28639: Fix inspect.isawaitable to always return bool Patch by Justin - Mayfield. - -- bpo-28652: Make loop methods reject socket kinds they do not support. - -- bpo-28653: Fix a refleak in functools.lru_cache. - -- bpo-28703: Fix asyncio.iscoroutinefunction to handle Mock objects. - -- bpo-28704: Fix create_unix_server to support Path-like objects (PEP 519). - -- bpo-28720: Add collections.abc.AsyncGenerator. - -Documentation -------------- - -- bpo-28513: Documented command-line interface of zipfile. - -Tests ------ - -- bpo-28666: Now test.support.rmtree is able to remove unwritable or - unreadable directories. - -- bpo-23839: Various caches now are cleared before running every test file. - -Build ------ - -- bpo-10656: Fix out-of-tree building on AIX. Patch by Tristan Carel and - Michael Haubenwallner. - -- bpo-26359: Rename --with-optimiations to --enable-optimizations. - -- bpo-28676: Prevent missing 'getentropy' declaration warning on macOS. - Patch by Gareth Rees. - - -What's New in Python 3.6.0 beta 3? -================================== - -*Release date: 2016-10-31* - -Core and Builtins ------------------ - -- bpo-28128: Deprecation warning for invalid str and byte escape sequences - now prints better information about where the error occurs. Patch by - Serhiy Storchaka and Eric Smith. - -- bpo-28509: dict.update() no longer allocate unnecessary large memory. - -- bpo-28426: Fixed potential crash in PyUnicode_AsDecodedObject() in debug - build. - -- bpo-28517: Fixed of-by-one error in the peephole optimizer that caused - keeping unreachable code. - -- bpo-28214: Improved exception reporting for problematic __set_name__ - attributes. - -- bpo-23782: Fixed possible memory leak in _PyTraceback_Add() and exception - loss in PyTraceBack_Here(). - -- bpo-28471: Fix "Python memory allocator called without holding the GIL" - crash in socket.setblocking. - -Library -------- - -- bpo-27517: LZMA compressor and decompressor no longer raise exceptions if - given empty data twice. Patch by Benjamin Fogle. - -- bpo-28549: Fixed segfault in curses's addch() with ncurses6. - -- bpo-28449: tarfile.open() with mode "r" or "r:" now tries to open a tar - file with compression before trying to open it without compression. - Otherwise it had 50% chance failed with ignore_zeros=True. - -- bpo-23262: The webbrowser module now supports Firefox 36+ and derived - browsers. Based on patch by Oleg Broytman. - -- bpo-27939: Fixed bugs in tkinter.ttk.LabeledScale and tkinter.Scale caused - by representing the scale as float value internally in Tk. tkinter.IntVar - now works if float value is set to underlying Tk variable. - -- bpo-18844: The various ways of specifying weights for random.choices() now - produce the same result sequences. - -- bpo-28255: calendar.TextCalendar().prmonth() no longer prints a space at - the start of new line after printing a month's calendar. Patch by Xiang - Zhang. - -- bpo-20491: The textwrap.TextWrapper class now honors non-breaking spaces. - Based on patch by Kaarle Ritvanen. - -- bpo-28353: os.fwalk() no longer fails on broken links. - -- bpo-28430: Fix iterator of C implemented asyncio.Future doesn't accept - non-None value is passed to it.send(val). - -- bpo-27025: Generated names for Tkinter widgets now start by the "!" prefix - for readability. - -- bpo-25464: Fixed HList.header_exists() in tkinter.tix module by addin a - workaround to Tix library bug. - -- bpo-28488: shutil.make_archive() no longer adds entry "./" to ZIP archive. - -- bpo-25953: re.sub() now raises an error for invalid numerical group - reference in replacement template even if the pattern is not found in the - string. Error message for invalid group reference now includes the group - index and the position of the reference. Based on patch by SilentGhost. - -- bpo-18219: Optimize csv.DictWriter for large number of columns. Patch by - Mariatta Wijaya. - -- bpo-28448: Fix C implemented asyncio.Future didn't work on Windows. - -- bpo-28480: Fix error building socket module when multithreading is - disabled. - -- bpo-24452: Make webbrowser support Chrome on Mac OS X. - -- bpo-20766: Fix references leaked by pdb in the handling of SIGINT - handlers. - -- bpo-28492: Fix how StopIteration exception is raised in _asyncio.Future. - -- bpo-28500: Fix asyncio to handle async gens GC from another thread. - -- bpo-26923: Fix asyncio.Gather to refuse being cancelled once all children - are done. Patch by Johannes Ebke. - -- bpo-26796: Don't configure the number of workers for default threadpool - executor. Initial patch by Hans Lawrenz. - -- bpo-28544: Implement asyncio.Task in C. - -Windows -------- - -- bpo-28522: Fixes mishandled buffer reallocation in getpathp.c - -Build ------ - -- bpo-28444: Fix missing extensions modules when cross compiling. - -- bpo-28208: Update Windows build and OS X installers to use SQLite 3.14.2. - -- bpo-28248: Update Windows build and OS X installers to use OpenSSL 1.0.2j. - -Tests ------ - -- bpo-26944: Fix test_posix for Android where 'id -G' is entirely wrong or - missing the effective gid. - -- bpo-28409: regrtest: fix the parser of command line arguments. - - -What's New in Python 3.6.0 beta 2? -================================== - -*Release date: 2016-10-10* - -Core and Builtins ------------------ - -- bpo-28183: Optimize and cleanup dict iteration. - -- bpo-26081: Added C implementation of asyncio.Future. Original patch by - Yury Selivanov. - -- bpo-28379: Added sanity checks and tests for PyUnicode_CopyCharacters(). - Patch by Xiang Zhang. - -- bpo-28376: The type of long range iterator is now registered as Iterator. - Patch by Oren Milman. - -- bpo-28376: Creating instances of range_iterator by calling range_iterator - type now is deprecated. Patch by Oren Milman. - -- bpo-28376: The constructor of range_iterator now checks that step is not - 0. Patch by Oren Milman. - -- bpo-26906: Resolving special methods of uninitialized type now causes - implicit initialization of the type instead of a fail. - -- bpo-18287: PyType_Ready() now checks that tp_name is not NULL. Original - patch by Niklas Koep. - -- bpo-24098: Fixed possible crash when AST is changed in process of - compiling it. - -- bpo-28201: Dict reduces possibility of 2nd conflict in hash table when - hashes have same lower bits. - -- bpo-28350: String constants with null character no longer interned. - -- bpo-26617: Fix crash when GC runs during weakref callbacks. - -- bpo-27942: String constants now interned recursively in tuples and - frozensets. - -- bpo-21578: Fixed misleading error message when ImportError called with - invalid keyword args. - -- bpo-28203: Fix incorrect type in complex(1.0, {2:3}) error message. Patch - by Soumya Sharma. - -- bpo-28086: Single var-positional argument of tuple subtype was passed - unscathed to the C-defined function. Now it is converted to exact tuple. - -- bpo-28214: Now __set_name__ is looked up on the class instead of the - instance. - -- bpo-27955: Fallback on reading /dev/urandom device when the getrandom() - syscall fails with EPERM, for example when blocked by SECCOMP. - -- bpo-28192: Don't import readline in isolated mode. - -- Upgrade internal unicode databases to Unicode version 9.0.0. - -- bpo-28131: Fix a regression in zipimport's compile_source(). zipimport - should use the same optimization level as the interpreter. - -- bpo-28126: Replace Py_MEMCPY with memcpy(). Visual Studio can properly - optimize memcpy(). - -- bpo-28120: Fix dict.pop() for splitted dictionary when trying to remove a - "pending key" (Not yet inserted in split-table). Patch by Xiang Zhang. - -- bpo-26182: Raise DeprecationWarning when async and await keywords are used - as variable/attribute/class/function name. - -Library -------- - -- bpo-27998: Fixed bytes path support in os.scandir() on Windows. Patch by - Eryk Sun. - -- bpo-28317: The disassembler now decodes FORMAT_VALUE argument. - -- bpo-26293: Fixed writing ZIP files that starts not from the start of the - file. Offsets in ZIP file now are relative to the start of the archive in - conforming to the specification. - -- bpo-28380: unittest.mock Mock autospec functions now properly support - assert_called, assert_not_called, and assert_called_once. - -- bpo-27181: remove statistics.geometric_mean and defer until 3.7. - -- bpo-28229: lzma module now supports pathlib. - -- bpo-28321: Fixed writing non-BMP characters with binary format in - plistlib. - -- bpo-28225: bz2 module now supports pathlib. Initial patch by Ethan - Furman. - -- bpo-28227: gzip now supports pathlib. Patch by Ethan Furman. - -- bpo-27358: Optimized merging var-keyword arguments and improved error - message when passing a non-mapping as a var-keyword argument. - -- bpo-28257: Improved error message when passing a non-iterable as a - var-positional argument. Added opcode BUILD_TUPLE_UNPACK_WITH_CALL. - -- bpo-28322: Fixed possible crashes when unpickle itertools objects from - incorrect pickle data. Based on patch by John Leitch. - -- bpo-28228: imghdr now supports pathlib. - -- bpo-28226: compileall now supports pathlib. - -- bpo-28314: Fix function declaration (C flags) for the getiterator() method - of xml.etree.ElementTree.Element. - -- bpo-28148: Stop using localtime() and gmtime() in the time module. - Introduced platform independent _PyTime_localtime API that is similar to - POSIX localtime_r, but available on all platforms. Patch by Ed Schouten. - -- bpo-28253: Fixed calendar functions for extreme months: 0001-01 and - 9999-12. Methods itermonthdays() and itermonthdays2() are reimplemented so - that they don't call itermonthdates() which can cause datetime.date - under/overflow. - -- bpo-28275: Fixed possible use after free in the decompress() methods of - the LZMADecompressor and BZ2Decompressor classes. Original patch by John - Leitch. - -- bpo-27897: Fixed possible crash in sqlite3.Connection.create_collation() - if pass invalid string-like object as a name. Patch by Xiang Zhang. - -- bpo-18844: random.choices() now has k as a keyword-only argument to - improve the readability of common cases and come into line with the - signature used in other languages. - -- bpo-18893: Fix invalid exception handling in Lib/ctypes/macholib/dyld.py. - Patch by Madison May. - -- bpo-27611: Fixed support of default root window in the tkinter.tix module. - Added the master parameter in the DisplayStyle constructor. - -- bpo-27348: In the traceback module, restore the formatting of exception - messages like "Exception: None". This fixes a regression introduced in - 3.5a2. - -- bpo-25651: Allow falsy values to be used for msg parameter of subTest(). - -- bpo-27778: Fix a memory leak in os.getrandom() when the getrandom() is - interrupted by a signal and a signal handler raises a Python exception. - -- bpo-28200: Fix memory leak on Windows in the os module (fix - path_converter() function). - -- bpo-25400: RobotFileParser now correctly returns default values for - crawl_delay and request_rate. Initial patch by Peter Wirtz. - -- bpo-27932: Prevent memory leak in win32_ver(). - -- Fix UnboundLocalError in socket._sendfile_use_sendfile. - -- bpo-28075: Check for ERROR_ACCESS_DENIED in Windows implementation of - os.stat(). Patch by Eryk Sun. - -- bpo-22493: Warning message emitted by using inline flags in the middle of - regular expression now contains a (truncated) regex pattern. Patch by Tim - Graham. - -- bpo-25270: Prevent codecs.escape_encode() from raising SystemError when an - empty bytestring is passed. - -- bpo-28181: Get antigravity over HTTPS. Patch by Kaartic Sivaraam. - -- bpo-25895: Enable WebSocket URL schemes in urllib.parse.urljoin. Patch by - Gergely Imreh and Markus Holtermann. - -- bpo-28114: Fix a crash in parse_envlist() when env contains byte strings. - Patch by Eryk Sun. - -- bpo-27599: Fixed buffer overrun in binascii.b2a_qp() and - binascii.a2b_qp(). - -- bpo-27906: Fix socket accept exhaustion during high TCP traffic. Patch by - Kevin Conway. - -- bpo-28174: Handle when SO_REUSEPORT isn't properly supported. Patch by - Seth Michael Larson. - -- bpo-26654: Inspect functools.partial in asyncio.Handle.__repr__. Patch by - iceboy. - -- bpo-26909: Fix slow pipes IO in asyncio. Patch by INADA Naoki. - -- bpo-28176: Fix callbacks race in asyncio.SelectorLoop.sock_connect. - -- bpo-27759: Fix selectors incorrectly retain invalid file descriptors. - Patch by Mark Williams. - -- bpo-28368: Refuse monitoring processes if the child watcher has no loop - attached. Patch by Vincent Michel. - -- bpo-28369: Raise RuntimeError when transport's FD is used with add_reader, - add_writer, etc. - -- bpo-28370: Speedup asyncio.StreamReader.readexactly. Patch by Коренберг - Марк. - -- bpo-28371: Deprecate passing asyncio.Handles to run_in_executor. - -- bpo-28372: Fix asyncio to support formatting of non-python coroutines. - -- bpo-28399: Remove UNIX socket from FS before binding. Patch by Коренберг - Марк. - -- bpo-27972: Prohibit Tasks to await on themselves. - -Windows -------- - -- bpo-28402: Adds signed catalog files for stdlib on Windows. - -- bpo-28333: Enables Unicode for ps1/ps2 and input() prompts. (Patch by Eryk - Sun) - -- bpo-28251: Improvements to help manuals on Windows. - -- bpo-28110: launcher.msi has different product codes between 32-bit and - 64-bit - -- bpo-28161: Opening CON for write access fails - -- bpo-28162: WindowsConsoleIO readall() fails if first line starts with - Ctrl+Z - -- bpo-28163: WindowsConsoleIO fileno() passes wrong flags to _open_osfhandle - -- bpo-28164: _PyIO_get_console_type fails for various paths - -- bpo-28137: Renames Windows path file to ._pth - -- bpo-28138: Windows ._pth file should allow import site - -C API ------ - -- bpo-28426: Deprecated undocumented functions PyUnicode_AsEncodedObject(), - PyUnicode_AsDecodedObject(), PyUnicode_AsDecodedUnicode() and - PyUnicode_AsEncodedUnicode(). - -Build ------ - -- bpo-28258: Fixed build with Estonian locale (python-config and distclean - targets in Makefile). Patch by Arfrever Frehtes Taifersar Arahesis. - -- bpo-26661: setup.py now detects system libffi with multiarch wrapper. - -- bpo-15819: Remove redundant include search directory option for building - outside the source tree. - -Tests ------ - -- bpo-28217: Adds _testconsole module to test console input. - - -What's New in Python 3.6.0 beta 1? -================================== - -*Release date: 2016-09-12* - -Core and Builtins ------------------ - -- bpo-23722: The __class__ cell used by zero-argument super() is now - initialized from type.__new__ rather than __build_class__, so class - methods relying on that will now work correctly when called from metaclass - methods during class creation. Patch by Martin Teichmann. - -- bpo-25221: Fix corrupted result from PyLong_FromLong(0) when Python is - compiled with NSMALLPOSINTS = 0. - -- bpo-27080: Implement formatting support for :pep:`515`. Initial patch by - Chris Angelico. - -- bpo-27199: In tarfile, expose copyfileobj bufsize to improve throughput. - Patch by Jason Fried. - -- bpo-27948: In f-strings, only allow backslashes inside the braces (where - the expressions are). This is a breaking change from the 3.6 alpha - releases, where backslashes are allowed anywhere in an f-string. Also, - require that expressions inside f-strings be enclosed within literal - braces, and not escapes like ``f'\x7b"hi"\x7d'``. - -- bpo-28046: Remove platform-specific directories from sys.path. - -- bpo-28071: Add early-out for differencing from an empty set. - -- bpo-25758: Prevents zipimport from unnecessarily encoding a filename - (patch by Eryk Sun) - -- bpo-25856: The __module__ attribute of extension classes and functions now - is interned. This leads to more compact pickle data with protocol 4. - -- bpo-27213: Rework CALL_FUNCTION* opcodes to produce shorter and more - efficient bytecode. Patch by Demur Rumed, design by Serhiy Storchaka, - reviewed by Serhiy Storchaka and Victor Stinner. - -- bpo-26331: Implement tokenizing support for :pep:`515`. Patch by Georg - Brandl. - -- bpo-27999: Make "global after use" a SyntaxError, and ditto for nonlocal. - Patch by Ivan Levkivskyi. - -- bpo-28003: Implement :pep:`525` -- Asynchronous Generators. - -- bpo-27985: Implement :pep:`526` -- Syntax for Variable Annotations. Patch - by Ivan Levkivskyi. - -- bpo-26058: Add a new private version to the builtin dict type, incremented - at each dictionary creation and at each dictionary change. Implementation - of the PEP 509. - -- bpo-27364: A backslash-character pair that is not a valid escape sequence - now generates a DeprecationWarning. Patch by Emanuel Barry. - -- bpo-27350: `dict` implementation is changed like PyPy. It is more compact - and preserves insertion order. (Concept developed by Raymond Hettinger and - patch by Inada Naoki.) - -- bpo-27911: Remove unnecessary error checks in - ``exec_builtin_or_dynamic()``. - -- bpo-27078: Added BUILD_STRING opcode. Optimized f-strings evaluation. - -- bpo-17884: Python now requires systems with inttypes.h and stdint.h - -- bpo-27961: Require platforms to support ``long long``. Python hasn't - compiled without ``long long`` for years, so this is basically a - formality. - -- bpo-27355: Removed support for Windows CE. It was never finished, and - Windows CE is no longer a relevant platform for Python. - -- Implement :pep:`523`. - -- bpo-27870: A left shift of zero by a large integer no longer attempts to - allocate large amounts of memory. - -- bpo-25402: In int-to-decimal-string conversion, improve the estimate of - the intermediate memory required, and remove an unnecessarily strict - overflow check. Patch by Serhiy Storchaka. - -- bpo-27214: In long_invert, be more careful about modifying object returned - by long_add, and remove an unnecessary check for small longs. Thanks Oren - Milman for analysis and patch. - -- bpo-27506: Support passing the bytes/bytearray.translate() "delete" - argument by keyword. - -- bpo-27812: Properly clear out a generator's frame's backreference to the - generator to prevent crashes in frame.clear(). - -- bpo-27811: Fix a crash when a coroutine that has not been awaited is - finalized with warnings-as-errors enabled. - -- bpo-27587: Fix another issue found by PVS-Studio: Null pointer check after - use of 'def' in _PyState_AddModule(). Initial patch by Christian Heimes. - -- bpo-27792: The modulo operation applied to ``bool`` and other ``int`` - subclasses now always returns an ``int``. Previously the return type - depended on the input values. Patch by Xiang Zhang. - -- bpo-26984: int() now always returns an instance of exact int. - -- bpo-25604: Fix a minor bug in integer true division; this bug could - potentially have caused off-by-one-ulp results on platforms with - unreliable ldexp implementations. - -- bpo-24254: Make class definition namespace ordered by default. - -- bpo-27662: Fix an overflow check in ``List_New``: the original code was - checking against ``Py_SIZE_MAX`` instead of the correct upper bound of - ``Py_SSIZE_T_MAX``. Patch by Xiang Zhang. - -- bpo-27782: Multi-phase extension module import now correctly allows the - ``m_methods`` field to be used to add module level functions to instances - of non-module types returned from ``Py_create_mod``. Patch by Xiang Zhang. - -- bpo-27936: The round() function accepted a second None argument for some - types but not for others. Fixed the inconsistency by accepting None for - all numeric types. - -- bpo-27487: Warn if a submodule argument to "python -m" or - runpy.run_module() is found in sys.modules after parent packages are - imported, but before the submodule is executed. - -- bpo-27157: Make only type() itself accept the one-argument form. Patch by - Eryk Sun and Emanuel Barry. - -- bpo-27558: Fix a SystemError in the implementation of "raise" statement. - In a brand new thread, raise a RuntimeError since there is no active - exception to reraise. Patch written by Xiang Zhang. - -- bpo-28008: Implement :pep:`530` -- asynchronous comprehensions. - -- bpo-27942: Fix memory leak in codeobject.c - -Library -------- - -- bpo-28732: Fix crash in os.spawnv() with no elements in args - -- bpo-28485: Always raise ValueError for negative - compileall.compile_dir(workers=...) parameter, even when multithreading is - unavailable. - -- bpo-28037: Use sqlite3_get_autocommit() instead of setting - Connection->inTransaction manually. - -- bpo-25283: Attributes tm_gmtoff and tm_zone are now available on all - platforms in the return values of time.localtime() and time.gmtime(). - -- bpo-24454: Regular expression match object groups are now accessible using - __getitem__. "mo[x]" is equivalent to "mo.group(x)". - -- bpo-10740: sqlite3 no longer implicitly commit an open transaction before - DDL statements. - -- bpo-17941: Add a *module* parameter to collections.namedtuple(). - -- bpo-22493: Inline flags now should be used only at the start of the - regular expression. Deprecation warning is emitted if uses them in the - middle of the regular expression. - -- bpo-26885: xmlrpc now supports unmarshalling additional data types used by - Apache XML-RPC implementation for numerics and None. - -- bpo-28070: Fixed parsing inline verbose flag in regular expressions. - -- bpo-19500: Add client-side SSL session resumption to the ssl module. - -- bpo-28022: Deprecate ssl-related arguments in favor of SSLContext. The - deprecation include manual creation of SSLSocket and certfile/keyfile (or - similar) in ftplib, httplib, imaplib, smtplib, poplib and urllib. - -- bpo-28043: SSLContext has improved default settings: OP_NO_SSLv2, - OP_NO_SSLv3, OP_NO_COMPRESSION, OP_CIPHER_SERVER_PREFERENCE, - OP_SINGLE_DH_USE, OP_SINGLE_ECDH_USE and HIGH ciphers without MD5. - -- bpo-24693: Changed some RuntimeError's in the zipfile module to more - appropriate types. Improved some error messages and debugging output. - -- bpo-17909: ``json.load`` and ``json.loads`` now support binary input - encoded as UTF-8, UTF-16 or UTF-32. Patch by Serhiy Storchaka. - -- bpo-27137: the pure Python fallback implementation of - ``functools.partial`` now matches the behaviour of its accelerated C - counterpart for subclassing, pickling and text representation purposes. - Patch by Emanuel Barry and Serhiy Storchaka. - -- Fix possible integer overflows and crashes in the mmap module with unusual - usage patterns. - -- bpo-1703178: Fix the ability to pass the --link-objects option to the - distutils build_ext command. - -- bpo-28019: itertools.count() no longer rounds non-integer step in range - between 1.0 and 2.0 to 1. - -- bpo-18401: Pdb now supports the 'readrc' keyword argument to control - whether .pdbrc files should be read. Patch by Martin Matusiak and Sam - Kimbrel. - -- bpo-25969: Update the lib2to3 grammar to handle the unpacking - generalizations added in 3.5. - -- bpo-14977: mailcap now respects the order of the lines in the mailcap - files ("first match"), as required by RFC 1542. Patch by Michael Lazar. - -- bpo-28082: Convert re flag constants to IntFlag. - -- bpo-28025: Convert all ssl module constants to IntEnum and IntFlags. - SSLContext properties now return flags and enums. - -- bpo-23591: Add Flag, IntFlag, and auto() to enum module. - -- bpo-433028: Added support of modifier spans in regular expressions. - -- bpo-24594: Validates persist parameter when opening MSI database - -- bpo-17582: xml.etree.ElementTree nows preserves whitespaces in attributes - (Patch by Duane Griffin. Reviewed and approved by Stefan Behnel.) - -- bpo-28047: Fixed calculation of line length used for the base64 CTE in the - new email policies. - -- bpo-27576: Fix call order in OrderedDict.__init__(). - -- email.generator.DecodedGenerator now supports the policy keyword. - -- bpo-28027: Remove undocumented modules from ``Lib/plat-*``: IN, CDROM, - DLFCN, TYPES, CDIO, and STROPTS. - -- bpo-27445: Don't pass str(_charset) to MIMEText.set_payload(). Patch by - Claude Paroz. - -- bpo-24277: The new email API is no longer provisional, and the docs have - been reorganized and rewritten to emphasize the new API. - -- bpo-22450: urllib now includes an ``Accept: */*`` header among the default - headers. This makes the results of REST API requests more consistent and - predictable especially when proxy servers are involved. - -- lib2to3.pgen3.driver.load_grammar() now creates a stable cache file - between runs given the same Grammar.txt input regardless of the hash - randomization setting. - -- bpo-28005: Allow ImportErrors in encoding implementation to propagate. - -- bpo-26667: Support path-like objects in importlib.util. - -- bpo-27570: Avoid zero-length memcpy() etc calls with null source pointers - in the "ctypes" and "array" modules. - -- bpo-22233: Break email header lines *only* on the RFC specified CR and LF - characters, not on arbitrary unicode line breaks. This also fixes a bug - in HTTP header parsing. - -- bpo-27331: The email.mime classes now all accept an optional policy - keyword. - -- bpo-27988: Fix email iter_attachments incorrect mutation of payload list. - -- bpo-16113: Add SHA-3 and SHAKE support to hashlib module. - -- Eliminate a tautological-pointer-compare warning in _scproxy.c. - -- bpo-27776: The :func:`os.urandom` function does now block on Linux 3.17 - and newer until the system urandom entropy pool is initialized to increase - the security. This change is part of the :pep:`524`. - -- bpo-27778: Expose the Linux ``getrandom()`` syscall as a new - :func:`os.getrandom` function. This change is part of the :pep:`524`. - -- bpo-27691: Fix ssl module's parsing of GEN_RID subject alternative name - fields in X.509 certs. - -- bpo-18844: Add random.choices(). - -- bpo-25761: Improved error reporting about truncated pickle data in C - implementation of unpickler. UnpicklingError is now raised instead of - AttributeError and ValueError in some cases. - -- bpo-26798: Add BLAKE2 (blake2b and blake2s) to hashlib. - -- bpo-26032: Optimized globbing in pathlib by using os.scandir(); it is now - about 1.5--4 times faster. - -- bpo-25596: Optimized glob() and iglob() functions in the glob module; they - are now about 3--6 times faster. - -- bpo-27928: Add scrypt (password-based key derivation function) to hashlib - module (requires OpenSSL 1.1.0). - -- bpo-27850: Remove 3DES from ssl module's default cipher list to counter - measure sweet32 attack (CVE-2016-2183). - -- bpo-27766: Add ChaCha20 Poly1305 to ssl module's default cipher list. - (Required OpenSSL 1.1.0 or LibreSSL). - -- bpo-25387: Check return value of winsound.MessageBeep. - -- bpo-27866: Add SSLContext.get_ciphers() method to get a list of all - enabled ciphers. - -- bpo-27744: Add AF_ALG (Linux Kernel crypto) to socket module. - -- bpo-26470: Port ssl and hashlib module to OpenSSL 1.1.0. - -- bpo-11620: Fix support for SND_MEMORY in winsound.PlaySound. Based on a - patch by Tim Lesher. - -- bpo-11734: Add support for IEEE 754 half-precision floats to the struct - module. Based on a patch by Eli Stevens. - -- bpo-27919: Deprecated ``extra_path`` distribution option in distutils - packaging. - -- bpo-23229: Add new ``cmath`` constants: ``cmath.inf`` and ``cmath.nan`` to - match ``math.inf`` and ``math.nan``, and also ``cmath.infj`` and - ``cmath.nanj`` to match the format used by complex repr. - -- bpo-27842: The csv.DictReader now returns rows of type OrderedDict. - (Contributed by Steve Holden.) - -- Remove support for passing a file descriptor to os.access. It never worked - but previously didn't raise. - -- bpo-12885: Fix error when distutils encounters symlink. - -- bpo-27881: Fixed possible bugs when setting - sqlite3.Connection.isolation_level. Based on patch by Xiang Zhang. - -- bpo-27861: Fixed a crash in sqlite3.Connection.cursor() when a factory - creates not a cursor. Patch by Xiang Zhang. - -- bpo-19884: Avoid spurious output on OS X with Gnu Readline. - -- bpo-27706: Restore deterministic behavior of random.Random().seed() for - string seeds using seeding version 1. Allows sequences of calls to - random() to exactly match those obtained in Python 2. Patch by Nofar - Schnider. - -- bpo-10513: Fix a regression in Connection.commit(). Statements should not - be reset after a commit. - -- bpo-12319: Chunked transfer encoding support added to - http.client.HTTPConnection requests. The - urllib.request.AbstractHTTPHandler class does not enforce a Content-Length - header any more. If a HTTP request has a file or iterable body, but no - Content-Length header, the library now falls back to use chunked - transfer-encoding. - -- A new version of typing.py from https://github.com/python/typing: - - Collection (only for 3.6) (Issue #27598) - Add FrozenSet to __all__ - (upstream #261) - fix crash in _get_type_vars() (upstream #259) - Remove - the dict constraint in ForwardRef._eval_type (upstream #252) - -- bpo-27832: Make ``_normalize`` parameter to ``Fraction`` constructor - keyword-only, so that ``Fraction(2, 3, 4)`` now raises ``TypeError``. - -- bpo-27539: Fix unnormalised ``Fraction.__pow__`` result in the case of - negative exponent and negative base. - -- bpo-21718: cursor.description is now available for queries using CTEs. - -- bpo-27819: In distutils sdists, simply produce the "gztar" (gzipped tar - format) distributions on all platforms unless "formats" is supplied. - -- bpo-2466: posixpath.ismount now correctly recognizes mount points which - the user does not have permission to access. - -- bpo-9998: On Linux, ctypes.util.find_library now looks in LD_LIBRARY_PATH - for shared libraries. - -- bpo-27573: exit message for code.interact is now configurable. - -- bpo-27930: Improved behaviour of logging.handlers.QueueListener. Thanks to - Paulo Andrade and Petr Viktorin for the analysis and patch. - -- bpo-6766: Distributed reference counting added to multiprocessing to - support nesting of shared values / proxy objects. - -- bpo-21201: Improves readability of multiprocessing error message. Thanks - to Wojciech Walczak for patch. - -- asyncio: Add set_protocol / get_protocol to Transports. - -- bpo-27456: asyncio: Set TCP_NODELAY by default. - -IDLE ----- - -- bpo-15308: Add 'interrupt execution' (^C) to Shell menu. Patch by Roger - Serwy, updated by Bayard Randel. - -- bpo-27922: Stop IDLE tests from 'flashing' gui widgets on the screen. - -- bpo-27891: Consistently group and sort imports within idlelib modules. - -- bpo-17642: add larger font sizes for classroom projection. - -- Add version to title of IDLE help window. - -- bpo-25564: In section on IDLE -- console differences, mention that using - exec means that __builtins__ is defined for each statement. - -- bpo-27821: Fix 3.6.0a3 regression that prevented custom key sets from - being selected when no custom theme was defined. - -C API ------ - -- bpo-26900: Excluded underscored names and other private API from limited - API. - -- bpo-26027: Add support for path-like objects in PyUnicode_FSConverter() & - PyUnicode_FSDecoder(). - -Tests ------ - -- bpo-27427: Additional tests for the math module. Patch by Francisco Couzo. - -- bpo-27953: Skip math and cmath tests that fail on OS X 10.4 due to a poor - libm implementation of tan. - -- bpo-26040: Improve test_math and test_cmath coverage and rigour. Patch by - Jeff Allen. - -- bpo-27787: Call gc.collect() before checking each test for "dangling - threads", since the dangling threads are weak references. - -Build ------ - -- bpo-27566: Fix clean target in freeze makefile (patch by Lisa Roach) - -- bpo-27705: Update message in validate_ucrtbase.py - -- bpo-27976: Deprecate building _ctypes with the bundled copy of libffi on - non-OSX UNIX platforms. - -- bpo-27983: Cause lack of llvm-profdata tool when using clang as required - for PGO linking to be a configure time error rather than make time when - ``--with-optimizations`` is enabled. Also improve our ability to find the - llvm-profdata tool on MacOS and some Linuxes. - -- bpo-21590: Support for DTrace and SystemTap probes. - -- bpo-26307: The profile-opt build now applies PGO to the built-in modules. - -- bpo-26359: Add the --with-optimizations flag to turn on LTO and PGO build - support when available. - -- bpo-27917: Set platform triplets for Android builds. - -- bpo-25825: Update references to the $(LIBPL) installation path on AIX. - This path was changed in 3.2a4. - -- Update OS X installer to use SQLite 3.14.1 and XZ 5.2.2. - -- bpo-21122: Fix LTO builds on OS X. - -- bpo-17128: Build OS X installer with a private copy of OpenSSL. Also - provide a sample Install Certificates command script to install a set of - root certificates from the third-party certifi module. - -Tools/Demos ------------ - -- bpo-27952: Get Tools/scripts/fixcid.py working with Python 3 and the - current "re" module, avoid invalid Python backslash escapes, and fix a bug - parsing escaped C quote signs. - -Windows -------- - -- bpo-28065: Update xz dependency to 5.2.2 and build it from source. - -- bpo-25144: Ensures TargetDir is set before continuing with custom install. - -- bpo-1602: Windows console doesn't input or print Unicode (PEP 528) - -- bpo-27781: Change file system encoding on Windows to UTF-8 (PEP 529) - -- bpo-27731: Opt-out of MAX_PATH on Windows 10 - -- bpo-6135: Adds encoding and errors parameters to subprocess. - -- bpo-27959: Adds oem encoding, alias ansi to mbcs, move aliasmbcs to codec - lookup. - -- bpo-27982: The functions of the winsound module now accept keyword - arguments. - -- bpo-20366: Build full text search support into SQLite on Windows. - -- bpo-27756: Adds new icons for Python files and processes on Windows. - Designs by Cherry Wang. - -- bpo-27883: Update sqlite to 3.14.1.0 on Windows. - - -What's New in Python 3.6.0 alpha 4? -=================================== - -*Release date: 2016-08-15* - -Core and Builtins ------------------ - -- bpo-27704: Optimized creating bytes and bytearray from byte-like objects - and iterables. Speed up to 3 times for short objects. Original patch by - Naoki Inada. - -- bpo-26823: Large sections of repeated lines in tracebacks are now - abbreviated as "[Previous line repeated {count} more times]" by the - builtin traceback rendering. Patch by Emanuel Barry. - -- bpo-27574: Decreased an overhead of parsing keyword arguments in functions - implemented with using Argument Clinic. - -- bpo-22557: Now importing already imported modules is up to 2.5 times - faster. - -- bpo-17596: Include <wincrypt.h> to help with Min GW building. - -- bpo-17599: On Windows, rename the privately defined REPARSE_DATA_BUFFER - structure to avoid conflicting with the definition from Min GW. - -- bpo-27507: Add integer overflow check in bytearray.extend(). Patch by - Xiang Zhang. - -- bpo-27581: Don't rely on wrapping for overflow check in - PySequence_Tuple(). Patch by Xiang Zhang. - -- bpo-1621: Avoid signed integer overflow in list and tuple operations. - Patch by Xiang Zhang. - -- bpo-27419: Standard __import__() no longer look up "__import__" in globals - or builtins for importing submodules or "from import". Fixed a crash if - raise a warning about unabling to resolve package from __spec__ or - __package__. - -- bpo-27083: Respect the PYTHONCASEOK environment variable under Windows. - -- bpo-27514: Make having too many statically nested blocks a SyntaxError - instead of SystemError. - -- bpo-27366: Implemented :pep:`487` (Simpler customization of class - creation). Upon subclassing, the __init_subclass__ classmethod is called - on the base class. Descriptors are initialized with __set_name__ after - class creation. - -Library -------- - -- bpo-26027: Add :pep:`519`/__fspath__() support to the os and os.path - modules. Includes code from Jelle Zijlstra. (See also: bpo-27524) - -- bpo-27598: Add Collections to collections.abc. Patch by Ivan Levkivskyi, - docs by Neil Girdhar. - -- bpo-25958: Support "anti-registration" of special methods from various - ABCs, like __hash__, __iter__ or __len__. All these (and several more) - can be set to None in an implementation class and the behavior will be as - if the method is not defined at all. (Previously, this mechanism existed - only for __hash__, to make mutable classes unhashable.) Code contributed - by Andrew Barnert and Ivan Levkivskyi. - -- bpo-16764: Support keyword arguments to zlib.decompress(). Patch by Xiang - Zhang. - -- bpo-27736: Prevent segfault after interpreter re-initialization due to ref - count problem introduced in code for Issue #27038 in 3.6.0a3. Patch by - Xiang Zhang. - -- bpo-25628: The *verbose* and *rename* parameters for - collections.namedtuple are now keyword-only. - -- bpo-12345: Add mathematical constant tau to math and cmath. See also - :pep:`628`. - -- bpo-26823: traceback.StackSummary.format now abbreviates large sections of - repeated lines as "[Previous line repeated {count} more times]" (this - change then further affects other traceback display operations in the - module). Patch by Emanuel Barry. - -- bpo-27664: Add to concurrent.futures.thread.ThreadPoolExecutor() the - ability to specify a thread name prefix. - -- bpo-27181: Add geometric_mean and harmonic_mean to statistics module. - -- bpo-27573: code.interact now prints an message when exiting. - -- bpo-6422: Add autorange method to timeit.Timer objects. - -- bpo-27773: Correct some memory management errors server_hostname in - _ssl.wrap_socket(). - -- bpo-26750: unittest.mock.create_autospec() now works properly for - subclasses of property() and other data descriptors. Removes the never - publicly used, never documented unittest.mock.DescriptorTypes tuple. - -- bpo-26754: Undocumented support of general bytes-like objects as path in - compile() and similar functions is now deprecated. - -- bpo-26800: Undocumented support of general bytes-like objects as paths in - os functions is now deprecated. - -- bpo-26981: Add _order_ compatibility shim to enum.Enum for Python 2/3 code - bases. - -- bpo-27661: Added tzinfo keyword argument to datetime.combine. - -- In the curses module, raise an error if window.getstr() or window.instr() - is passed a negative value. - -- bpo-27783: Fix possible usage of uninitialized memory in - operator.methodcaller. - -- bpo-27774: Fix possible Py_DECREF on unowned object in _sre. - -- bpo-27760: Fix possible integer overflow in binascii.b2a_qp. - -- bpo-27758: Fix possible integer overflow in the _csv module for large - record lengths. - -- bpo-27568: Prevent HTTPoxy attack (CVE-2016-1000110). Ignore the - HTTP_PROXY variable when REQUEST_METHOD environment is set, which - indicates that the script is in CGI mode. - -- bpo-7063: Remove dead code from the "array" module's slice handling. Patch - by Chuck. - -- bpo-27656: Do not assume sched.h defines any SCHED_* constants. - -- bpo-27130: In the "zlib" module, fix handling of large buffers (typically - 4 GiB) when compressing and decompressing. Previously, inputs were - limited to 4 GiB, and compression and decompression operations did not - properly handle results of 4 GiB. - -- bpo-24773: Implemented :pep:`495` (Local Time Disambiguation). - -- Expose the EPOLLEXCLUSIVE constant (when it is defined) in the select - module. - -- bpo-27567: Expose the EPOLLRDHUP and POLLRDHUP constants in the select - module. - -- bpo-1621: Avoid signed int negation overflow in the "audioop" module. - -- bpo-27533: Release GIL in nt._isdir - -- bpo-17711: Fixed unpickling by the persistent ID with protocol 0. Original - patch by Alexandre Vassalotti. - -- bpo-27522: Avoid an unintentional reference cycle in email.feedparser. - -- bpo-27512: Fix a segfault when os.fspath() called an __fspath__() method - that raised an exception. Patch by Xiang Zhang. - -IDLE ----- - -- bpo-27714: text_textview and test_autocomplete now pass when re-run in the - same process. This occurs when test_idle fails when run with the -w - option but without -jn. Fix warning from test_config. - -- bpo-27621: Put query response validation error messages in the query box - itself instead of in a separate messagebox. Redo tests to match. Add Mac - OSX refinements. Original patch by Mark Roseman. - -- bpo-27620: Escape key now closes Query box as cancelled. - -- bpo-27609: IDLE: tab after initial whitespace should tab, not - autocomplete. This fixes problem with writing docstrings at least twice - indented. - -- bpo-27609: Explicitly return None when there are also non-None returns. In - a few cases, reverse a condition and eliminate a return. - -- bpo-25507: IDLE no longer runs buggy code because of its tkinter imports. - Users must include the same imports required to run directly in Python. - -- bpo-27173: Add 'IDLE Modern Unix' to the built-in key sets. Make the - default key set depend on the platform. Add tests for the changes to the - config module. - -- bpo-27452: add line counter and crc to IDLE configHandler test dump. - -Tests ------ - -- bpo-25805: Skip a test in test_pkgutil as needed that doesn't work when - ``__name__ == __main__``. Patch by SilentGhost. - -- bpo-27472: Add test.support.unix_shell as the path to the default shell. - -- bpo-27369: In test_pyexpat, avoid testing an error message detail that - changed in Expat 2.2.0. - -- bpo-27594: Prevent assertion error when running test_ast with coverage - enabled: ensure code object has a valid first line number. Patch suggested - by Ivan Levkivskyi. - -Windows -------- - -- bpo-27647: Update bundled Tcl/Tk to 8.6.6. - -- bpo-27610: Adds :pep:`514` metadata to Windows installer - -- bpo-27469: Adds a shell extension to the launcher so that drag and drop - works correctly. - -- bpo-27309: Enables proper Windows styles in python[w].exe manifest. - -Build ------ - -- bpo-27713: Suppress spurious build warnings when updating importlib's - bootstrap files. Patch by Xiang Zhang - -- bpo-25825: Correct the references to Modules/python.exp, which is required - on AIX. The references were accidentally changed in 3.5.0a1. - -- bpo-27453: CPP invocation in configure must use CPPFLAGS. Patch by Chi - Hsuan Yen. - -- bpo-27641: The configure script now inserts comments into the makefile to - prevent the pgen and _freeze_importlib executables from being - cross-compiled. - -- bpo-26662: Set PYTHON_FOR_GEN in configure as the Python program to be - used for file generation during the build. - -- bpo-10910: Avoid C++ compilation errors on FreeBSD and OS X. Also update - FreedBSD version checks for the original ctype UTF-8 workaround. - - -What's New in Python 3.6.0 alpha 3? -=================================== - -*Release date: 2016-07-11* - -Security --------- - -- bpo-27278: Fix os.urandom() implementation using getrandom() on Linux. - Truncate size to INT_MAX and loop until we collected enough random bytes, - instead of casting a directly Py_ssize_t to int. - -- bpo-22636: Avoid shell injection problems with ctypes.util.find_library(). - -Core and Builtins ------------------ - -- bpo-27473: Fixed possible integer overflow in bytes and bytearray - concatenations. Patch by Xiang Zhang. - -- bpo-23034: The output of a special Python build with defined COUNT_ALLOCS, - SHOW_ALLOC_COUNT or SHOW_TRACK_COUNT macros is now off by default. It - can be re-enabled using the "-X showalloccount" option. It now outputs to - stderr instead of stdout. - -- bpo-27443: __length_hint__() of bytearray iterators no longer return a - negative integer for a resized bytearray. - -- bpo-27007: The fromhex() class methods of bytes and bytearray subclasses - now return an instance of corresponding subclass. - -Library -------- - -- bpo-26844: Fix error message for imp.find_module() to refer to 'path' - instead of 'name'. Patch by Lev Maximov. - -- bpo-23804: Fix SSL zero-length recv() calls to not block and not raise an - error about unclean EOF. - -- bpo-27466: Change time format returned by http.cookie.time2netscape, - confirming the netscape cookie format and making it consistent with - documentation. - -- bpo-21708: Deprecated dbm.dumb behavior that differs from common dbm - behavior: creating a database in 'r' and 'w' modes and modifying a - database in 'r' mode. - -- bpo-26721: Change the socketserver.StreamRequestHandler.wfile attribute to - implement BufferedIOBase. In particular, the write() method no longer does - partial writes. - -- bpo-22115: Added methods trace_add, trace_remove and trace_info in the - tkinter.Variable class. They replace old methods trace_variable, trace, - trace_vdelete and trace_vinfo that use obsolete Tcl commands and might not - work in future versions of Tcl. Fixed old tracing methods: - trace_vdelete() with wrong mode no longer break tracing, trace_vinfo() now - always returns a list of pairs of strings, tracing in the "u" mode now - works. - -- bpo-26243: Only the level argument to zlib.compress() is keyword argument - now. The first argument is positional-only. - -- bpo-27038: Expose the DirEntry type as os.DirEntry. Code patch by Jelle - Zijlstra. - -- bpo-27186: Update os.fspath()/PyOS_FSPath() to check the return value of - __fspath__() to be either str or bytes. - -- bpo-18726: All optional parameters of the dump(), dumps(), load() and - loads() functions and JSONEncoder and JSONDecoder class constructors in - the json module are now keyword-only. - -- bpo-27319: Methods selection_set(), selection_add(), selection_remove() - and selection_toggle() of ttk.TreeView now allow passing multiple items as - multiple arguments instead of passing them as a tuple. Deprecated - undocumented ability of calling the selection() method with arguments. - -- bpo-27079: Fixed curses.ascii functions isblank(), iscntrl() and - ispunct(). - -- bpo-27294: Numerical state in the repr for Tkinter event objects is now - represented as a combination of known flags. - -- bpo-27177: Match objects in the re module now support index-like objects - as group indices. Based on patches by Jeroen Demeyer and Xiang Zhang. - -- bpo-26754: Some functions (compile() etc) accepted a filename argument - encoded as an iterable of integers. Now only strings and byte-like objects - are accepted. - -- bpo-26536: socket.ioctl now supports SIO_LOOPBACK_FAST_PATH. Patch by - Daniel Stokes. - -- bpo-27048: Prevents distutils failing on Windows when environment - variables contain non-ASCII characters - -- bpo-27330: Fixed possible leaks in the ctypes module. - -- bpo-27238: Got rid of bare excepts in the turtle module. Original patch - by Jelle Zijlstra. - -- bpo-27122: When an exception is raised within the context being managed by - a contextlib.ExitStack() and one of the exit stack generators catches and - raises it in a chain, do not re-raise the original exception when exiting, - let the new chained one through. This avoids the :pep:`479` bug described - in issue25782. - -- bpo-16864: sqlite3.Cursor.lastrowid now supports REPLACE statement. - Initial patch by Alex LordThorsen. - -- bpo-26386: Fixed ttk.TreeView selection operations with item id's - containing spaces. - -- bpo-8637: Honor a pager set by the env var MANPAGER (in preference to one - set by the env var PAGER). - -- bpo-16182: Fix various functions in the "readline" module to use the - locale encoding, and fix get_begidx() and get_endidx() to return code - point indexes. - -- bpo-27392: Add loop.connect_accepted_socket(). Patch by Jim Fulton. - -IDLE ----- - -- bpo-27477: IDLE search dialogs now use ttk widgets. - -- bpo-27173: Add 'IDLE Modern Unix' to the built-in key sets. Make the - default key set depend on the platform. Add tests for the changes to the - config module. - -- bpo-27452: make command line "idle-test> python test_help.py" work. - __file__ is relative when python is started in the file's directory. - -- bpo-27452: add line counter and crc to IDLE configHandler test dump. - -- bpo-27380: IDLE: add query.py with base Query dialog and ttk widgets. - Module had subclasses SectionName, ModuleName, and HelpSource, which are - used to get information from users by configdialog and file =>Load Module. - Each subclass has itw own validity checks. Using ModuleName allows users - to edit bad module names instead of starting over. Add tests and delete - the two files combined into the new one. - -- bpo-27372: Test_idle no longer changes the locale. - -- bpo-27365: Allow non-ascii chars in IDLE NEWS.txt, for contributor names. - -- bpo-27245: IDLE: Cleanly delete custom themes and key bindings. - Previously, when IDLE was started from a console or by import, a cascade - of warnings was emitted. Patch by Serhiy Storchaka. - -- bpo-24137: Run IDLE, test_idle, and htest with tkinter default root - disabled. Fix code and tests that fail with this restriction. Fix htests - to not create a second and redundant root and mainloop. - -- bpo-27310: Fix IDLE.app failure to launch on OS X due to vestigial import. - -C API ------ - -- bpo-26754: PyUnicode_FSDecoder() accepted a filename argument encoded as - an iterable of integers. Now only strings and byte-like objects are - accepted. - -Build ------ - -- bpo-28066: Fix the logic that searches build directories for generated - include files when building outside the source tree. - -- bpo-27442: Expose the Android API level that python was built against, in - sysconfig.get_config_vars() as 'ANDROID_API_LEVEL'. - -- bpo-27434: The interpreter that runs the cross-build, found in PATH, must - now be of the same feature version (e.g. 3.6) as the source being built. - -- bpo-26930: Update Windows builds to use OpenSSL 1.0.2h. - -- bpo-23968: Rename the platform directory from plat-$(MACHDEP) to - plat-$(PLATFORM_TRIPLET). Rename the config directory (LIBPL) from - config-$(LDVERSION) to config-$(LDVERSION)-$(PLATFORM_TRIPLET). Install - the platform specific _sysconfigdata module into the platform directory - and rename it to include the ABIFLAGS. - -- Don't use largefile support for GNU/Hurd. - -Tools/Demos ------------ - -- bpo-27332: Fixed the type of the first argument of module-level functions - generated by Argument Clinic. Patch by Petr Viktorin. - -- bpo-27418: Fixed Tools/importbench/importbench.py. - -Documentation -------------- - -- bpo-19489: Moved the search box from the sidebar to the header and footer - of each page. Patch by Ammar Askar. - -- bpo-27285: Update documentation to reflect the deprecation of ``pyvenv`` - and normalize on the term "virtual environment". Patch by Steve Piercy. - -Tests ------ - -- bpo-27027: Added test.support.is_android that is True when this is an - Android build. - - -What's New in Python 3.6.0 alpha 2? -=================================== - -*Release date: 2016-06-13* - -Security --------- - -- bpo-26556: Update expat to 2.1.1, fixes CVE-2015-1283. - -- Fix TLS stripping vulnerability in smtplib, CVE-2016-0772. Reported by - Team Oststrom. - -- bpo-26839: On Linux, :func:`os.urandom` now calls ``getrandom()`` with - ``GRND_NONBLOCK`` to fall back on reading ``/dev/urandom`` if the urandom - entropy pool is not initialized yet. Patch written by Colm Buckley. - -Core and Builtins ------------------ - -- bpo-27095: Simplified MAKE_FUNCTION and removed MAKE_CLOSURE opcodes. - Patch by Demur Rumed. - -- bpo-27190: Raise NotSupportedError if sqlite3 is older than 3.3.1. Patch - by Dave Sawyer. - -- bpo-27286: Fixed compiling BUILD_MAP_UNPACK_WITH_CALL opcode. Calling - function with generalized unpacking (PEP 448) and conflicting keyword - names could cause undefined behavior. - -- bpo-27140: Added BUILD_CONST_KEY_MAP opcode. - -- bpo-27186: Add support for os.PathLike objects to open() (part of - :pep:`519`). - -- bpo-27066: Fixed SystemError if a custom opener (for open()) returns a - negative number without setting an exception. - -- bpo-26983: float() now always return an instance of exact float. The - deprecation warning is emitted if __float__ returns an instance of a - strict subclass of float. In a future versions of Python this can be an - error. - -- bpo-27097: Python interpreter is now about 7% faster due to optimized - instruction decoding. Based on patch by Demur Rumed. - -- bpo-26647: Python interpreter now uses 16-bit wordcode instead of - bytecode. Patch by Demur Rumed. - -- bpo-23275: Allow assigning to an empty target list in round brackets: () = - iterable. - -- bpo-27243: Update the __aiter__ protocol: instead of returning an - awaitable that resolves to an asynchronous iterator, the asynchronous - iterator should be returned directly. Doing the former will trigger a - PendingDeprecationWarning. - -Library -------- - -- Comment out socket (SO_REUSEPORT) and posix (O_SHLOCK, O_EXLOCK) constants - exposed on the API which are not implemented on GNU/Hurd. They would not - work at runtime anyway. - -- bpo-27025: Generated names for Tkinter widgets are now more meaningful and - recognizable. - -- bpo-25455: Fixed crashes in repr of recursive ElementTree.Element and - functools.partial objects. - -- bpo-27294: Improved repr for Tkinter event objects. - -- bpo-20508: Improve exception message of IPv{4,6}Network.__getitem__. Patch - by Gareth Rees. - -- bpo-21386: Implement missing IPv4Address.is_global property. It was - documented since 07a5610bae9d. Initial patch by Roger Luethi. - -- bpo-27029: Removed deprecated support of universal newlines mode from - ZipFile.open(). - -- bpo-27030: Unknown escapes consisting of ``'\'`` and an ASCII letter in - regular expressions now are errors. The re.LOCALE flag now can be used - only with bytes patterns. - -- bpo-27186: Add os.PathLike support to DirEntry (part of :pep:`519`). - Initial patch by Jelle Zijlstra. - -- bpo-20900: distutils register command now decodes HTTP responses - correctly. Initial patch by ingrid. - -- bpo-27186: Add os.PathLike support to pathlib, removing its provisional - status (part of PEP 519). Initial patch by Dusty Phillips. - -- bpo-27186: Add support for os.PathLike objects to os.fsencode() and - os.fsdecode() (part of :pep:`519`). - -- bpo-27186: Introduce os.PathLike and os.fspath() (part of :pep:`519`). - -- 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). - -- bpo-25738: Stop http.server.BaseHTTPRequestHandler.send_error() from - sending a message body for 205 Reset Content. Also, don't send Content - header fields in responses that don't have a body. Patch by Susumu - Koshiba. - -- bpo-21313: Fix the "platform" module to tolerate when sys.version contains - truncated build information. - -- bpo-23883: Added missing APIs to __all__ to match the documented APIs for - the following modules: cgi, mailbox, mimetypes, plistlib and smtpd. - Patches by Jacek Kołodziej. - -- bpo-27164: In the zlib module, allow decompressing raw Deflate streams - with a predefined zdict. Based on patch by Xiang Zhang. - -- bpo-24291: Fix wsgiref.simple_server.WSGIRequestHandler to completely - write data to the client. Previously it could do partial writes and - truncate data. Also, wsgiref.handler.ServerHandler can now handle stdout - doing partial writes, but this is deprecated. - -- bpo-21272: Use _sysconfigdata.py to initialize distutils.sysconfig. - -- bpo-19611: :mod:`inspect` now reports the implicit ``.0`` parameters - generated by the compiler for comprehension and generator expression - scopes as if they were positional-only parameters called ``implicit0``. - Patch by Jelle Zijlstra. - -- bpo-26809: Add ``__all__`` to :mod:`string`. Patch by Emanuel Barry. - -- bpo-26373: subprocess.Popen.communicate now correctly ignores - BrokenPipeError when the child process dies before .communicate() is - called in more/all circumstances. - -- signal, socket, and ssl module IntEnum constant name lookups now return a - consistent name for values having multiple names. Ex: signal.Signals(6) - now refers to itself as signal.SIGALRM rather than flipping between that - and signal.SIGIOT based on the interpreter's hash randomization seed. - -- bpo-27167: Clarify the subprocess.CalledProcessError error message text - when the child process died due to a signal. - -- bpo-25931: Don't define socketserver.Forking* names on platforms such as - Windows that do not support os.fork(). - -- bpo-21776: distutils.upload now correctly handles HTTPError. Initial patch - by Claudiu Popa. - -- bpo-26526: Replace custom parse tree validation in the parser module with - a simple DFA validator. - -- bpo-27114: Fix SSLContext._load_windows_store_certs fails with - PermissionError - -- bpo-18383: Avoid creating duplicate filters when using filterwarnings and - simplefilter. Based on patch by Alex Shkop. - -- bpo-23026: winreg.QueryValueEx() now return an integer for REG_QWORD type. - -- bpo-26741: subprocess.Popen destructor now emits a ResourceWarning warning - if the child process is still running. - -- bpo-27056: Optimize pickle.load() and pickle.loads(), up to 10% faster to - deserialize a lot of small objects. - -- bpo-21271: New keyword only parameters in reset_mock call. - -IDLE ----- - -- bpo-5124: Paste with text selected now replaces the selection on X11. This - matches how paste works on Windows, Mac, most modern Linux apps, and ttk - widgets. Original patch by Serhiy Storchaka. - -- bpo-24750: Switch all scrollbars in IDLE to ttk versions. Where needed, - minimal tests are added to cover changes. - -- bpo-24759: IDLE requires tk 8.5 and availability ttk widgets. Delete now - unneeded tk version tests and code for older versions. Add test for IDLE - syntax colorizer. - -- bpo-27239: idlelib.macosx.isXyzTk functions initialize as needed. - -- bpo-27262: move Aqua unbinding code, which enable context menus, to - macosx. - -- bpo-24759: Make clear in idlelib.idle_test.__init__ that the directory is - a private implementation of test.test_idle and tool for maintainers. - -- bpo-27196: Stop 'ThemeChanged' warnings when running IDLE tests. These - persisted after other warnings were suppressed in #20567. Apply Serhiy - Storchaka's update_idletasks solution to four test files. Record this - additional advice in idle_test/README.txt - -- bpo-20567: Revise idle_test/README.txt with advice about avoiding tk - warning messages from tests. Apply advice to several IDLE tests. - -- bpo-24225: Update idlelib/README.txt with new file names and event - handlers. - -- bpo-27156: Remove obsolete code not used by IDLE. - -- bpo-27117: Make colorizer htest and turtledemo work with dark themes. Move - code for configuring text widget colors to a new function. - -- bpo-24225: Rename many `idlelib/*.py` and `idle_test/test_*.py` files. - Edit files to replace old names with new names when the old name referred - to the module rather than the class it contained. See the issue and IDLE - section in What's New in 3.6 for more. - -- bpo-26673: When tk reports font size as 0, change to size 10. Such fonts - on Linux prevented the configuration dialog from opening. - -- bpo-21939: Add test for IDLE's percolator. Original patch by Saimadhav - Heblikar. - -- bpo-21676: Add test for IDLE's replace dialog. Original patch by Saimadhav - Heblikar. - -- bpo-18410: Add test for IDLE's search dialog. Original patch by Westley - Martínez. - -- bpo-21703: Add test for undo delegator. Patch mostly by Saimadhav - Heblikar . - -- bpo-27044: Add ConfigDialog.remove_var_callbacks to stop memory leaks. - -- bpo-23977: Add more asserts to test_delegator. - -Documentation -------------- - -- bpo-16484: Change the default PYTHONDOCS URL to "https:", and fix the - resulting links to use lowercase. Patch by Sean Rodman, test by Kaushik - Nadikuditi. - -- bpo-24136: Document the new :pep:`448` unpacking syntax of 3.5. - -- bpo-22558: Add remaining doc links to source code for Python-coded - modules. Patch by Yoni Lavi. - -Tests ------ - -- bpo-25285: regrtest now uses subprocesses when the -j1 command line option - is used: each test file runs in a fresh child process. Before, the -j1 - option was ignored. - -- bpo-25285: Tools/buildbot/test.bat script now uses -j1 by default to run - each test file in fresh child process. - -Windows -------- - -- bpo-27064: The py.exe launcher now defaults to Python 3. The Windows - launcher ``py.exe`` no longer prefers an installed Python 2 version over - Python 3 by default when used interactively. - -- bpo-17500: Remove unused and outdated icons. (See also: - https://github.com/python/pythondotorg/issues/945) - -Build ------ - -- bpo-27229: Fix the cross-compiling pgen rule for in-tree builds. Patch by - Xavier de Gaye. - -- bpo-26930: Update OS X 10.5+ 32-bit-only installer to build and link with - OpenSSL 1.0.2h. - -C API ------ - -- bpo-27186: Add the PyOS_FSPath() function (part of :pep:`519`). - -- bpo-26282: PyArg_ParseTupleAndKeywords() now supports positional-only - parameters. - -Tools/Demos ------------ - -- bpo-26282: Argument Clinic now supports positional-only and keyword - parameters in the same function. - - -What's New in Python 3.6.0 alpha 1? -=================================== - -*Release date: 2016-05-16* - -Security --------- - -- bpo-26657: Fix directory traversal vulnerability with http.server on - Windows. This fixes a regression that was introduced in 3.3.4rc1 and - 3.4.0rc1. Based on patch by Philipp Hagemeister. - -- bpo-26313: ssl.py _load_windows_store_certs fails if windows cert store is - empty. Patch by Baji. - -- bpo-25939: On Windows open the cert store readonly in - ssl.enum_certificates. - -Core and Builtins ------------------ - -- bpo-20041: Fixed TypeError when frame.f_trace is set to None. Patch by - Xavier de Gaye. - -- bpo-26168: Fixed possible refleaks in failing Py_BuildValue() with the "N" - format unit. - -- bpo-26991: Fix possible refleak when creating a function with annotations. - -- bpo-27039: Fixed bytearray.remove() for values greater than 127. Based on - patch by Joe Jevnik. - -- bpo-23640: int.from_bytes() no longer bypasses constructors for - subclasses. - -- bpo-27005: Optimized the float.fromhex() class method for exact float. It - is now 2 times faster. - -- bpo-18531: Single var-keyword argument of dict subtype was passed - unscathed to the C-defined function. Now it is converted to exact dict. - -- bpo-26811: gc.get_objects() no longer contains a broken tuple with NULL - pointer. - -- bpo-20120: Use RawConfigParser for .pypirc parsing, removing support for - interpolation unintentionally added with move to Python 3. Behavior no - longer does any interpolation in .pypirc files, matching behavior in - Python 2.7 and Setuptools 19.0. - -- bpo-26249: Memory functions of the :c:func:`PyMem_Malloc` domain - (:c:data:`PYMEM_DOMAIN_MEM`) now use the :ref:`pymalloc allocator - <pymalloc>` rather than system :c:func:`malloc`. Applications calling - :c:func:`PyMem_Malloc` without holding the GIL can now crash: use - ``PYTHONMALLOC=debug`` environment variable to validate the usage of - memory allocators in your application. - -- bpo-26802: Optimize function calls only using unpacking like - ``func(*tuple)`` (no other positional argument, no keyword): avoid copying - the tuple. Patch written by Joe Jevnik. - -- bpo-26659: Make the builtin slice type support cycle collection. - -- bpo-26718: super.__init__ no longer leaks memory if called multiple times. - NOTE: A direct call of super.__init__ is not endorsed! - -- bpo-27138: Fix the doc comment for FileFinder.find_spec(). - -- bpo-27147: Mention :pep:`420` in the importlib docs. - -- bpo-25339: PYTHONIOENCODING now has priority over locale in setting the - error handler for stdin and stdout. - -- bpo-26494: Fixed crash on iterating exhausting iterators. Affected classes - are generic sequence iterators, iterators of str, bytes, bytearray, list, - tuple, set, frozenset, dict, OrderedDict, corresponding views and - os.scandir() iterator. - -- bpo-26574: Optimize ``bytes.replace(b'', b'.')`` and - ``bytearray.replace(b'', b'.')``. Patch written by Josh Snider. - -- bpo-26581: If coding cookie is specified multiple times on a line in - Python source code file, only the first one is taken to account. - -- bpo-19711: Add tests for reloading namespace packages. - -- bpo-21099: Switch applicable importlib tests to use :pep:`451` API. - -- bpo-26563: Debug hooks on Python memory allocators now raise a fatal error - if functions of the :c:func:`PyMem_Malloc` family are called without - holding the GIL. - -- bpo-26564: On error, the debug hooks on Python memory allocators now use - the :mod:`tracemalloc` module to get the traceback where a memory block - was allocated. - -- bpo-26558: The debug hooks on Python memory allocator - :c:func:`PyObject_Malloc` now detect when functions are called without - holding the GIL. - -- bpo-26516: Add :envvar:`PYTHONMALLOC` environment variable to set the - Python memory allocators and/or install debug hooks. - -- bpo-26516: The :c:func:`PyMem_SetupDebugHooks` function can now also be - used on Python compiled in release mode. - -- bpo-26516: The :envvar:`PYTHONMALLOCSTATS` environment variable can now - also be used on Python compiled in release mode. It now has no effect if - set to an empty string. - -- bpo-26516: In debug mode, debug hooks are now also installed on Python - memory allocators when Python is configured without pymalloc. - -- bpo-26464: Fix str.translate() when string is ASCII and first replacements - removes character, but next replacement uses a non-ASCII character or a - string longer than 1 character. Regression introduced in Python 3.5.0. - -- bpo-22836: Ensure exception reports from PyErr_Display() and - PyErr_WriteUnraisable() are sensible even when formatting them produces - secondary errors. This affects the reports produced by - sys.__excepthook__() and when __del__() raises an exception. - -- bpo-26302: Correct behavior to reject comma as a legal character for - cookie names. - -- bpo-26136: Upgrade the warning when a generator raises StopIteration from - PendingDeprecationWarning to DeprecationWarning. Patch by Anish Shah. - -- bpo-26204: The compiler now ignores all constant statements: bytes, str, - int, float, complex, name constants (None, False, True), Ellipsis and - ast.Constant; not only str and int. For example, ``1.0`` is now ignored in - ``def f(): 1.0``. - -- bpo-4806: Avoid masking the original TypeError exception when using star - (``*``) unpacking in function calls. Based on patch by Hagen Fürstenau - and Daniel Urban. - -- bpo-26146: Add a new kind of AST node: ``ast.Constant``. It can be used by - external AST optimizers, but the compiler does not emit directly such - node. - -- bpo-23601: Sped-up allocation of dict key objects by using Python's small - object allocator. (Contributed by Julian Taylor.) - -- bpo-18018: Import raises ImportError instead of SystemError if a relative - import is attempted without a known parent package. - -- bpo-25843: When compiling code, don't merge constants if they are equal - but have a different types. For example, ``f1, f2 = lambda: 1, lambda: - 1.0`` is now correctly compiled to two different functions: ``f1()`` - returns ``1`` (``int``) and ``f2()`` returns ``1.0`` (``float``), even if - ``1`` and ``1.0`` are equal. - -- bpo-26107: The format of the ``co_lnotab`` attribute of code objects - changes to support negative line number delta. - -- bpo-26154: Add a new private _PyThreadState_UncheckedGet() function to get - the current Python thread state, but don't issue a fatal error if it is - NULL. This new function must be used instead of accessing directly the - _PyThreadState_Current variable. The variable is no more exposed since - Python 3.5.1 to hide the exact implementation of atomic C types, to avoid - compiler issues. - -- bpo-25791: If __package__ != __spec__.parent or if neither __package__ or - __spec__ are defined then ImportWarning is raised. - -- bpo-22995: [UPDATE] Comment out the one of the pickleability tests in - _PyObject_GetState() due to regressions observed in Cython-based projects. - -- bpo-25961: Disallowed null characters in the type name. - -- bpo-25973: Fix segfault when an invalid nonlocal statement binds a name - starting with two underscores. - -- bpo-22995: Instances of extension types with a state that aren't - subclasses of list or dict and haven't implemented any pickle-related - methods (__reduce__, __reduce_ex__, __getnewargs__, __getnewargs_ex__, or - __getstate__), can no longer be pickled. Including memoryview. - -- bpo-20440: Massive replacing unsafe attribute setting code with special - macro Py_SETREF. - -- bpo-25766: Special method __bytes__() now works in str subclasses. - -- bpo-25421: __sizeof__ methods of builtin types now use dynamic basic size. - This allows sys.getsize() to work correctly with their subclasses with - __slots__ defined. - -- bpo-25709: Fixed problem with in-place string concatenation and utf-8 - cache. - -- bpo-5319: New Py_FinalizeEx() API allowing Python to set an exit status of - 120 on failure to flush buffered streams. - -- bpo-25485: telnetlib.Telnet is now a context manager. - -- bpo-24097: Fixed crash in object.__reduce__() if slot name is freed inside - __getattr__. - -- bpo-24731: Fixed crash on converting objects with special methods - __bytes__, __trunc__, and __float__ returning instances of subclasses of - bytes, int, and float to subclasses of bytes, int, and float - correspondingly. - -- bpo-25630: Fix a possible segfault during argument parsing in functions - that accept filesystem paths. - -- bpo-23564: Fixed a partially broken sanity check in the _posixsubprocess - internals regarding how fds_to_pass were passed to the child. The bug had - no actual impact as subprocess.py already avoided it. - -- bpo-25388: Fixed tokenizer crash when processing undecodable source code - with a null byte. - -- bpo-25462: The hash of the key now is calculated only once in most - operations in C implementation of OrderedDict. - -- bpo-22995: Default implementation of __reduce__ and __reduce_ex__ now - rejects builtin types with not defined __new__. - -- bpo-24802: Avoid buffer overreads when int(), float(), compile(), exec() - and eval() are passed bytes-like objects. These objects are not - necessarily terminated by a null byte, but the functions assumed they - were. - -- bpo-25555: Fix parser and AST: fill lineno and col_offset of "arg" node - when compiling AST from Python objects. - -- bpo-24726: Fixed a crash and leaking NULL in repr() of OrderedDict that - was mutated by direct calls of dict methods. - -- bpo-25449: Iterating OrderedDict with keys with unstable hash now raises - KeyError in C implementations as well as in Python implementation. - -- bpo-25395: Fixed crash when highly nested OrderedDict structures were - garbage collected. - -- bpo-25401: Optimize bytes.fromhex() and bytearray.fromhex(): they are now - between 2x and 3.5x faster. - -- bpo-25399: Optimize bytearray % args using the new private _PyBytesWriter - API. Formatting is now between 2.5 and 5 times faster. - -- bpo-25274: sys.setrecursionlimit() now raises a RecursionError if the new - recursion limit is too low depending at the current recursion depth. - Modify also the "lower-water mark" formula to make it monotonic. This mark - is used to decide when the overflowed flag of the thread state is reset. - -- bpo-24402: Fix input() to prompt to the redirected stdout when - sys.stdout.fileno() fails. - -- bpo-25349: Optimize bytes % args using the new private _PyBytesWriter API. - Formatting is now up to 2 times faster. - -- bpo-24806: Prevent builtin types that are not allowed to be subclassed - from being subclassed through multiple inheritance. - -- bpo-25301: The UTF-8 decoder is now up to 15 times as fast for error - handlers: ``ignore``, ``replace`` and ``surrogateescape``. - -- bpo-24848: Fixed a number of bugs in UTF-7 decoding of misformed data. - -- bpo-25267: The UTF-8 encoder is now up to 75 times as fast for error - handlers: ``ignore``, ``replace``, ``surrogateescape``, ``surrogatepass``. - Patch co-written with Serhiy Storchaka. - -- bpo-25280: Import trace messages emitted in verbose (-v) mode are no - longer formatted twice. - -- bpo-25227: Optimize ASCII and latin1 encoders with the ``surrogateescape`` - error handler: the encoders are now up to 3 times as fast. Initial patch - written by Serhiy Storchaka. - -- bpo-25003: On Solaris 11.3 or newer, os.urandom() now uses the getrandom() - function instead of the getentropy() function. The getentropy() function - is blocking to generate very good quality entropy, os.urandom() doesn't - need such high-quality entropy. - -- bpo-9232: Modify Python's grammar to allow trailing commas in the argument - list of a function declaration. For example, "def f(\*, a = 3,): pass" is - now legal. Patch from Mark Dickinson. - -- bpo-24965: Implement :pep:`498` "Literal String Interpolation". This - allows you to embed expressions inside f-strings, which are converted to - normal strings at run time. Given x=3, then f'value={x}' == 'value=3'. - Patch by Eric V. Smith. - -- bpo-26478: Fix semantic bugs when using binary operators with dictionary - views and tuples. - -- bpo-26171: Fix possible integer overflow and heap corruption in - zipimporter.get_data(). - -- bpo-25660: Fix TAB key behaviour in REPL with readline. - -- bpo-26288: Optimize PyLong_AsDouble. - -- bpo-26289: Optimize floor and modulo division for single-digit longs. - Microbenchmarks show 2-2.5x improvement. Built-in 'divmod' function is - now also ~10% faster. (See also: bpo-26315) - -- bpo-25887: Raise a RuntimeError when a coroutine object is awaited more - than once. - -Library -------- - -- bpo-27057: Fix os.set_inheritable() on Android, ioctl() is blocked by - SELinux and fails with EACCESS. The function now falls back to fcntl(). - Patch written by Michał Bednarski. - -- bpo-27014: Fix infinite recursion using typing.py. Thanks to Kalle Tuure! - -- bpo-27031: Removed dummy methods in Tkinter widget classes: tk_menuBar() - and tk_bindForTraversal(). - -- bpo-14132: Fix urllib.request redirect handling when the target only has a - query string. Original fix by Ján Janech. - -- bpo-17214: The "urllib.request" module now percent-encodes non-ASCII bytes - found in redirect target URLs. Some servers send Location header fields - with non-ASCII bytes, but "http.client" requires the request target to be - ASCII-encodable, otherwise a UnicodeEncodeError is raised. Based on patch - by Christian Heimes. - -- bpo-27033: The default value of the decode_data parameter for - smtpd.SMTPChannel and smtpd.SMTPServer constructors is changed to False. - -- bpo-27034: Removed deprecated class asynchat.fifo. - -- bpo-26870: Added readline.set_auto_history(), which can stop entries being - automatically added to the history list. Based on patch by Tyler - Crompton. - -- bpo-26039: zipfile.ZipFile.open() can now be used to write data into a ZIP - file, as well as for extracting data. Patch by Thomas Kluyver. - -- bpo-26892: Honor debuglevel flag in urllib.request.HTTPHandler. Patch - contributed by Chi Hsuan Yen. - -- bpo-22274: In the subprocess module, allow stderr to be redirected to - stdout even when stdout is not redirected. Patch by Akira Li. - -- bpo-26807: mock_open 'files' no longer error on readline at end of file. - Patch from Yolanda Robla. - -- bpo-25745: Fixed leaking a userptr in curses panel destructor. - -- bpo-26977: Removed unnecessary, and ignored, call to sum of squares helper - in statistics.pvariance. - -- bpo-26002: Use bisect in statistics.median instead of a linear search. - Patch by Upendra Kuma. - -- bpo-25974: Make use of new Decimal.as_integer_ratio() method in statistics - module. Patch by Stefan Krah. - -- bpo-26996: Add secrets module as described in :pep:`506`. - -- bpo-26881: The modulefinder module now supports extended opcode arguments. - -- bpo-23815: Fixed crashes related to directly created instances of types in - _tkinter and curses.panel modules. - -- bpo-17765: weakref.ref() no longer silently ignores keyword arguments. - Patch by Georg Brandl. - -- bpo-26873: xmlrpc now raises ResponseError on unsupported type tags - instead of silently return incorrect result. - -- bpo-26915: The __contains__ methods in the collections ABCs now check for - identity before checking equality. This better matches the behavior of - the concrete classes, allows sensible handling of NaNs, and makes it - easier to reason about container invariants. - -- bpo-26711: Fixed the comparison of plistlib.Data with other types. - -- bpo-24114: Fix an uninitialized variable in `ctypes.util`. The bug only - occurs on SunOS when the ctypes implementation searches for the `crle` - program. Patch by Xiang Zhang. Tested on SunOS by Kees Bos. - -- bpo-26864: In urllib.request, change the proxy bypass host checking - against no_proxy to be case-insensitive, and to not match unrelated host - names that happen to have a bypassed hostname as a suffix. Patch by Xiang - Zhang. - -- bpo-24902: Print server URL on http.server startup. Initial patch by - Felix Kaiser. - -- bpo-25788: fileinput.hook_encoded() now supports an "errors" argument for - passing to open. Original patch by Joseph Hackman. - -- bpo-26634: recursive_repr() now sets __qualname__ of wrapper. Patch by - Xiang Zhang. - -- bpo-26804: urllib.request will prefer lower_case proxy environment - variables over UPPER_CASE or Mixed_Case ones. Patch contributed by - Hans-Peter Jansen. - -- bpo-26837: assertSequenceEqual() now correctly outputs non-stringified - differing items (like bytes in the -b mode). This affects - assertListEqual() and assertTupleEqual(). - -- bpo-26041: Remove "will be removed in Python 3.7" from deprecation - messages of platform.dist() and platform.linux_distribution(). Patch by - Kumaripaba Miyurusara Athukorala. - -- bpo-26822: itemgetter, attrgetter and methodcaller objects no longer - silently ignore keyword arguments. - -- bpo-26733: Disassembling a class now disassembles class and static - methods. Patch by Xiang Zhang. - -- bpo-26801: Fix error handling in :func:`shutil.get_terminal_size`, catch - :exc:`AttributeError` instead of :exc:`NameError`. Patch written by - Emanuel Barry. - -- bpo-24838: tarfile's ustar and gnu formats now correctly calculate name - and link field limits for multibyte character encodings like utf-8. - -- bpo-26717: Stop encoding Latin-1-ized WSGI paths with UTF-8. Patch by - Anthony Sottile. - -- bpo-26782: Add STARTUPINFO to subprocess.__all__ on Windows. - -- bpo-26404: Add context manager to socketserver. Patch by Aviv Palivoda. - -- bpo-26735: Fix :func:`os.urandom` on Solaris 11.3 and newer when reading - more than 1,024 bytes: call ``getrandom()`` multiple times with a limit of - 1024 bytes per call. - -- bpo-26585: Eliminate http.server._quote_html() and use - html.escape(quote=False). Patch by Xiang Zhang. - -- bpo-26685: Raise OSError if closing a socket fails. - -- bpo-16329: Add .webm to mimetypes.types_map. Patch by Giampaolo Rodola'. - -- bpo-13952: Add .csv to mimetypes.types_map. Patch by Geoff Wilson. - -- bpo-26587: the site module now allows .pth files to specify files to be - added to sys.path (e.g. zip files). - -- bpo-25609: Introduce contextlib.AbstractContextManager and - typing.ContextManager. - -- bpo-26709: Fixed Y2038 problem in loading binary PLists. - -- bpo-23735: Handle terminal resizing with Readline 6.3+ by installing our - own SIGWINCH handler. Patch by Eric Price. - -- bpo-25951: Change SSLSocket.sendall() to return None, as explicitly - documented for plain socket objects. Patch by Aviv Palivoda. - -- bpo-26586: In http.server, respond with "413 Request header fields too - large" if there are too many header fields to parse, rather than killing - the connection and raising an unhandled exception. Patch by Xiang Zhang. - -- bpo-26676: Added missing XMLPullParser to ElementTree.__all__. - -- bpo-22854: Change BufferedReader.writable() and BufferedWriter.readable() - to always return False. - -- bpo-26492: Exhausted iterator of array.array now conforms with the - behavior of iterators of other mutable sequences: it lefts exhausted even - if iterated array is extended. - -- bpo-26641: doctest.DocFileTest and doctest.testfile() now support packages - (module splitted into multiple directories) for the package parameter. - -- bpo-25195: Fix a regression in mock.MagicMock. _Call is a subclass of - tuple (changeset 3603bae63c13 only works for classes) so we need to - implement __ne__ ourselves. Patch by Andrew Plummer. - -- bpo-26644: Raise ValueError rather than SystemError when a negative length - is passed to SSLSocket.recv() or read(). - -- bpo-23804: Fix SSL recv(0) and read(0) methods to return zero bytes - instead of up to 1024. - -- bpo-26616: Fixed a bug in datetime.astimezone() method. - -- bpo-26637: The :mod:`importlib` module now emits an :exc:`ImportError` - rather than a :exc:`TypeError` if :func:`__import__` is tried during the - Python shutdown process but :data:`sys.path` is already cleared (set to - ``None``). - -- bpo-21925: :func:`warnings.formatwarning` now catches exceptions when - calling :func:`linecache.getline` and - :func:`tracemalloc.get_object_traceback` to be able to log - :exc:`ResourceWarning` emitted late during the Python shutdown process. - -- bpo-23848: On Windows, faulthandler.enable() now also installs an - exception handler to dump the traceback of all Python threads on any - Windows exception, not only on UNIX signals (SIGSEGV, SIGFPE, SIGABRT). - -- bpo-26530: Add C functions :c:func:`_PyTraceMalloc_Track` and - :c:func:`_PyTraceMalloc_Untrack` to track memory blocks using the - :mod:`tracemalloc` module. Add :c:func:`_PyTraceMalloc_GetTraceback` to - get the traceback of an object. - -- bpo-26588: The _tracemalloc now supports tracing memory allocations of - multiple address spaces (domains). - -- bpo-24266: Ctrl+C during Readline history search now cancels the search - mode when compiled with Readline 7. - -- bpo-26590: Implement a safe finalizer for the _socket.socket type. It now - releases the GIL to close the socket. - -- bpo-18787: spwd.getspnam() now raises a PermissionError if the user - doesn't have privileges. - -- bpo-26560: Avoid potential ValueError in BaseHandler.start_response. - Initial patch by Peter Inglesby. - -- bpo-26567: Add a new function :c:func:`PyErr_ResourceWarning` function to - pass the destroyed object. Add a *source* attribute to - :class:`warnings.WarningMessage`. Add warnings._showwarnmsg() which uses - tracemalloc to get the traceback where source object was allocated. - -- bpo-26569: Fix :func:`pyclbr.readmodule` and :func:`pyclbr.readmodule_ex` - to support importing packages. - -- bpo-26499: Account for remaining Content-Length in HTTPResponse.readline() - and read1(). Based on patch by Silent Ghost. Also document that - HTTPResponse now supports these methods. - -- bpo-25320: Handle sockets in directories unittest discovery is scanning. - Patch from Victor van den Elzen. - -- bpo-16181: cookiejar.http2time() now returns None if year is higher than - datetime.MAXYEAR. - -- bpo-26513: Fixes platform module detection of Windows Server - -- bpo-23718: Fixed parsing time in week 0 before Jan 1. Original patch by - Tamás Bence Gedai. - -- bpo-26323: Add Mock.assert_called() and Mock.assert_called_once() methods - to unittest.mock. Patch written by Amit Saha. - -- bpo-20589: Invoking Path.owner() and Path.group() on Windows now raise - NotImplementedError instead of ImportError. - -- bpo-26177: Fixed the keys() method for Canvas and Scrollbar widgets. - -- bpo-15068: Got rid of excessive buffering in fileinput. The bufsize - parameter is now deprecated and ignored. - -- bpo-19475: Added an optional argument timespec to the datetime isoformat() - method to choose the precision of the time component. - -- bpo-2202: Fix UnboundLocalError in - AbstractDigestAuthHandler.get_algorithm_impls. Initial patch by Mathieu - Dupuy. - -- bpo-26167: Minimized overhead in copy.copy() and copy.deepcopy(). - Optimized copying and deepcopying bytearrays, NotImplemented, slices, - short lists, tuples, dicts, sets. - -- bpo-25718: Fixed pickling and copying the accumulate() iterator with total - is None. - -- bpo-26475: Fixed debugging output for regular expressions with the (?x) - flag. - -- bpo-26482: Allowed pickling recursive dequeues. - -- bpo-26335: Make mmap.write() return the number of bytes written like other - write methods. Patch by Jakub Stasiak. - -- bpo-26457: Fixed the subnets() methods in IP network classes for the case - when resulting prefix length is equal to maximal prefix length. Based on - patch by Xiang Zhang. - -- bpo-26385: Remove the file if the internal open() call in - NamedTemporaryFile() fails. Patch by Silent Ghost. - -- bpo-26402: Fix XML-RPC client to retry when the server shuts down a - persistent connection. This was a regression related to the new - http.client.RemoteDisconnected exception in 3.5.0a4. - -- bpo-25913: Leading ``<~`` is optional now in base64.a85decode() with - adobe=True. Patch by Swati Jaiswal. - -- bpo-26186: Remove an invalid type check in importlib.util.LazyLoader. - -- bpo-26367: importlib.__import__() raises ImportError like - builtins.__import__() when ``level`` is specified but without an - accompanying package specified. - -- bpo-26309: In the "socketserver" module, shut down the request (closing - the connected socket) when verify_request() returns false. Patch by Aviv - Palivoda. - -- bpo-23430: Change the socketserver module to only catch exceptions raised - from a request handler that are derived from Exception (instead of - BaseException). Therefore SystemExit and KeyboardInterrupt no longer - trigger the handle_error() method, and will now to stop a single-threaded - server. - -- bpo-25995: os.walk() no longer uses FDs proportional to the tree depth. - -- bpo-25994: Added the close() method and the support of the context manager - protocol for the os.scandir() iterator. - -- bpo-23992: multiprocessing: make MapResult not fail-fast upon exception. - -- bpo-26243: Support keyword arguments to zlib.compress(). Patch by Aviv - Palivoda. - -- bpo-26117: The os.scandir() iterator now closes file descriptor not only - when the iteration is finished, but when it was failed with error. - -- bpo-25949: __dict__ for an OrderedDict instance is now created only when - needed. - -- bpo-25911: Restored support of bytes paths in os.walk() on Windows. - -- bpo-26045: Add UTF-8 suggestion to error message when posting a - non-Latin-1 string with http.client. - -- bpo-26039: Added zipfile.ZipInfo.from_file() and zipinfo.ZipInfo.is_dir(). - Patch by Thomas Kluyver. - -- bpo-12923: Reset FancyURLopener's redirect counter even if there is an - exception. Based on patches by Brian Brazil and Daniel Rocco. - -- bpo-25945: Fixed a crash when unpickle the functools.partial object with - wrong state. Fixed a leak in failed functools.partial constructor. "args" - and "keywords" attributes of functools.partial have now always types tuple - and dict correspondingly. - -- bpo-26202: copy.deepcopy() now correctly copies range() objects with - non-atomic attributes. - -- bpo-23076: Path.glob() now raises a ValueError if it's called with an - invalid pattern. Patch by Thomas Nyberg. - -- bpo-19883: Fixed possible integer overflows in zipimport. - -- bpo-26227: On Windows, getnameinfo(), gethostbyaddr() and - gethostbyname_ex() functions of the socket module now decode the hostname - from the ANSI code page rather than UTF-8. - -- bpo-26099: The site module now writes an error into stderr if - sitecustomize module can be imported but executing the module raise an - ImportError. Same change for usercustomize. - -- bpo-26147: xmlrpc now works with strings not encodable with used non-UTF-8 - encoding. - -- bpo-25935: Garbage collector now breaks reference loops with OrderedDict. - -- bpo-16620: Fixed AttributeError in msilib.Directory.glob(). - -- bpo-26013: Added compatibility with broken protocol 2 pickles created in - old Python 3 versions (3.4.3 and lower). - -- bpo-26129: Deprecated accepting non-integers in grp.getgrgid(). - -- bpo-25850: Use cross-compilation by default for 64-bit Windows. - -- bpo-25822: Add docstrings to the fields of urllib.parse results. Patch - contributed by Swati Jaiswal. - -- bpo-22642: Convert trace module option parsing mechanism to argparse. - Patch contributed by SilentGhost. - -- bpo-24705: Fix sysconfig._parse_makefile not expanding ${} vars appearing - before $() vars. - -- bpo-26069: Remove the deprecated apis in the trace module. - -- bpo-22138: Fix mock.patch behavior when patching descriptors. Restore - original values after patching. Patch contributed by Sean McCully. - -- bpo-25672: In the ssl module, enable the SSL_MODE_RELEASE_BUFFERS mode - option if it is safe to do so. - -- bpo-26012: Don't traverse into symlinks for ``**`` pattern in - pathlib.Path.[r]glob(). - -- bpo-24120: Ignore PermissionError when traversing a tree with - pathlib.Path.[r]glob(). Patch by Ulrich Petri. - -- bpo-21815: Accept ] characters in the data portion of imap responses, in - order to handle the flags with square brackets accepted and produced by - servers such as gmail. - -- bpo-25447: fileinput now uses sys.stdin as-is if it does not have a buffer - attribute (restores backward compatibility). - -- bpo-25971: Optimized creating Fractions from floats by 2 times and from - Decimals by 3 times. - -- bpo-25802: Document as deprecated the remaining implementations of - importlib.abc.Loader.load_module(). - -- bpo-25928: Add Decimal.as_integer_ratio(). - -- bpo-25447: Copying the lru_cache() wrapper object now always works, - independently from the type of the wrapped object (by returning the - original object unchanged). - -- bpo-25768: Have the functions in compileall return booleans instead of - ints and add proper documentation and tests for the return values. - -- bpo-24103: Fixed possible use after free in ElementTree.XMLPullParser. - -- bpo-25860: os.fwalk() no longer skips remaining directories when error - occurs. Original patch by Samson Lee. - -- bpo-25914: Fixed and simplified OrderedDict.__sizeof__. - -- bpo-25869: Optimized deepcopying ElementTree; it is now 20 times faster. - -- bpo-25873: Optimized iterating ElementTree. Iterating elements - Element.iter() is now 40% faster, iterating text Element.itertext() is now - up to 2.5 times faster. - -- bpo-25902: Fixed various refcount issues in ElementTree iteration. - -- bpo-22227: The TarFile iterator is reimplemented using generator. This - implementation is simpler that using class. - -- bpo-25638: Optimized ElementTree.iterparse(); it is now 2x faster. - Optimized ElementTree parsing; it is now 10% faster. - -- bpo-25761: Improved detecting errors in broken pickle data. - -- bpo-25717: Restore the previous behaviour of tolerating most fstat() - errors when opening files. This was a regression in 3.5a1, and stopped - anonymous temporary files from working in special cases. - -- bpo-24903: Fix regression in number of arguments compileall accepts when - '-d' is specified. The check on the number of arguments has been dropped - completely as it never worked correctly anyway. - -- bpo-25764: In the subprocess module, preserve any exception caused by - fork() failure when preexec_fn is used. - -- bpo-25771: Tweak the exception message for importlib.util.resolve_name() - when 'package' isn't specified but necessary. - -- bpo-6478: _strptime's regexp cache now is reset after changing timezone - with time.tzset(). - -- bpo-14285: When executing a package with the "python -m package" option, - and package initialization fails, a proper traceback is now reported. The - "runpy" module now lets exceptions from package initialization pass back - to the caller, rather than raising ImportError. - -- bpo-19771: Also in runpy and the "-m" option, omit the irrelevant message - ". . . is a package and cannot be directly executed" if the package could - not even be initialized (e.g. due to a bad ``*.pyc`` file). - -- bpo-25177: Fixed problem with the mean of very small and very large - numbers. As a side effect, statistics.mean and statistics.variance should - be significantly faster. - -- bpo-25718: Fixed copying object with state with boolean value is false. - -- bpo-10131: Fixed deep copying of minidom documents. Based on patch by - Marian Ganisin. - -- bpo-7990: dir() on ElementTree.Element now lists properties: "tag", - "text", "tail" and "attrib". Original patch by Santoso Wijaya. - -- bpo-25725: Fixed a reference leak in pickle.loads() when unpickling - invalid data including tuple instructions. - -- bpo-25663: In the Readline completer, avoid listing duplicate global - names, and search the global namespace before searching builtins. - -- bpo-25688: Fixed file leak in ElementTree.iterparse() raising an error. - -- bpo-23914: Fixed SystemError raised by unpickler on broken pickle data. - -- bpo-25691: Fixed crash on deleting ElementTree.Element attributes. - -- bpo-25624: ZipFile now always writes a ZIP_STORED header for directory - entries. Patch by Dingyuan Wang. - -- bpo-25626: Change three zlib functions to accept sizes that fit in - Py_ssize_t, but internally cap those sizes to UINT_MAX. This resolves a - regression in 3.5 where GzipFile.read() failed to read chunks larger than - 2 or 4 GiB. The change affects the zlib.Decompress.decompress() - max_length parameter, the zlib.decompress() bufsize parameter, and the - zlib.Decompress.flush() length parameter. - -- bpo-25583: Avoid incorrect errors raised by os.makedirs(exist_ok=True) - when the OS gives priority to errors such as EACCES over EEXIST. - -- bpo-25593: Change semantics of EventLoop.stop() in asyncio. - -- bpo-6973: When we know a subprocess.Popen process has died, do not allow - the send_signal(), terminate(), or kill() methods to do anything as they - could potentially signal a different process. - -- bpo-23883: Added missing APIs to __all__ to match the documented APIs for - the following modules: calendar, csv, enum, fileinput, ftplib, logging, - optparse, tarfile, threading and wave. Also added a - test.support.check__all__() helper. Patches by Jacek Kołodziej, Mauro S. - M. Rodrigues and Joel Taddei. - -- bpo-25590: In the Readline completer, only call getattr() once per - attribute. Also complete names of attributes such as properties and slots - which are listed by dir() but not yet created on an instance. - -- bpo-25498: Fix a crash when garbage-collecting ctypes objects created by - wrapping a memoryview. This was a regression made in 3.5a1. Based on - patch by Eryksun. - -- bpo-25584: Added "escape" to the __all__ list in the glob module. - -- bpo-25584: Fixed recursive glob() with patterns starting with ``**``. - -- bpo-25446: Fix regression in smtplib's AUTH LOGIN support. - -- bpo-18010: Fix the pydoc web server's module search function to handle - exceptions from importing packages. - -- bpo-25554: Got rid of circular references in regular expression parsing. - -- bpo-18973: Command-line interface of the calendar module now uses argparse - instead of optparse. - -- bpo-25510: fileinput.FileInput.readline() now returns b'' instead of '' at - the end if the FileInput was opened with binary mode. Patch by Ryosuke - Ito. - -- bpo-25503: Fixed inspect.getdoc() for inherited docstrings of properties. - Original patch by John Mark Vandenberg. - -- bpo-25515: Always use os.urandom as a source of randomness in uuid.uuid4. - -- bpo-21827: Fixed textwrap.dedent() for the case when largest common - whitespace is a substring of smallest leading whitespace. Based on patch - by Robert Li. - -- bpo-25447: The lru_cache() wrapper objects now can be copied and pickled - (by returning the original object unchanged). - -- bpo-25390: typing: Don't crash on Union[str, Pattern]. - -- bpo-25441: asyncio: Raise error from drain() when socket is closed. - -- bpo-25410: Cleaned up and fixed minor bugs in C implementation of - OrderedDict. - -- bpo-25411: Improved Unicode support in SMTPHandler through better use of - the email package. Thanks to user simon04 for the patch. - -- Move the imp module from a PendingDeprecationWarning to - DeprecationWarning. - -- bpo-25407: Remove mentions of the formatter module being removed in Python - 3.6. - -- bpo-25406: Fixed a bug in C implementation of OrderedDict.move_to_end() - that caused segmentation fault or hang in iterating after moving several - items to the start of ordered dict. - -- bpo-25382: pickletools.dis() now outputs implicit memo index for the - MEMOIZE opcode. - -- bpo-25357: Add an optional newline parameter to binascii.b2a_base64(). - base64.b64encode() uses it to avoid a memory copy. - -- bpo-24164: Objects that need calling ``__new__`` with keyword arguments, - can now be pickled using pickle protocols older than protocol version 4. - -- bpo-25364: zipfile now works in threads disabled builds. - -- bpo-25328: smtpd's SMTPChannel now correctly raises a ValueError if both - decode_data and enable_SMTPUTF8 are set to true. - -- bpo-16099: RobotFileParser now supports Crawl-delay and Request-rate - extensions. Patch by Nikolay Bogoychev. - -- bpo-25316: distutils raises OSError instead of DistutilsPlatformError when - MSVC is not installed. - -- bpo-25380: Fixed protocol for the STACK_GLOBAL opcode in - pickletools.opcodes. - -- bpo-23972: Updates asyncio datagram create method allowing reuseport and - reuseaddr socket options to be set prior to binding the socket. Mirroring - the existing asyncio create_server method the reuseaddr option for - datagram sockets defaults to True if the O/S is 'posix' (except if the - platform is Cygwin). Patch by Chris Laws. - -- bpo-25304: Add asyncio.run_coroutine_threadsafe(). This lets you submit a - coroutine to a loop from another thread, returning a - concurrent.futures.Future. By Vincent Michel. - -- bpo-25232: Fix CGIRequestHandler to split the query from the URL at the - first question mark (?) rather than the last. Patch from Xiang Zhang. - -- bpo-24657: Prevent CGIRequestHandler from collapsing slashes in the query - part of the URL as if it were a path. Patch from Xiang Zhang. - -- bpo-25287: Don't add crypt.METHOD_CRYPT to crypt.methods if it's not - supported. Check if it is supported, it may not be supported on OpenBSD - for example. - -- bpo-23600: Default implementation of tzinfo.fromutc() was returning wrong - results in some cases. - -- bpo-25203: Failed readline.set_completer_delims() no longer left the - module in inconsistent state. - -- bpo-25011: rlcompleter now omits private and special attribute names - unless the prefix starts with underscores. - -- bpo-25209: rlcompleter now can add a space or a colon after completed - keyword. - -- bpo-22241: timezone.utc name is now plain 'UTC', not 'UTC-00:00'. - -- bpo-23517: fromtimestamp() and utcfromtimestamp() methods of - datetime.datetime now round microseconds to nearest with ties going to - nearest even integer (ROUND_HALF_EVEN), as round(float), instead of - rounding towards -Infinity (ROUND_FLOOR). - -- bpo-23552: Timeit now warns when there is substantial (4x) variance - between best and worst times. Patch from Serhiy Storchaka. - -- bpo-24633: site-packages/README -> README.txt. - -- bpo-24879: help() and pydoc can now list named tuple fields in the order - they were defined rather than alphabetically. The ordering is determined - by the _fields attribute if present. - -- bpo-24874: Improve speed of itertools.cycle() and make its pickle more - compact. - -- Fix crash in itertools.cycle.__setstate__() when the first argument wasn't - a list. - -- bpo-20059: urllib.parse raises ValueError on all invalid ports. Patch by - Martin Panter. - -- bpo-24360: Improve __repr__ of argparse.Namespace() for invalid - identifiers. Patch by Matthias Bussonnier. - -- bpo-23426: run_setup was broken in distutils. Patch from Alexander - Belopolsky. - -- bpo-13938: 2to3 converts StringTypes to a tuple. Patch from Mark Hammond. - -- bpo-2091: open() accepted a 'U' mode string containing '+', but 'U' can - only be used with 'r'. Patch from Jeff Balogh and John O'Connor. - -- bpo-8585: improved tests for zipimporter2. Patch from Mark Lawrence. - -- bpo-18622: unittest.mock.mock_open().reset_mock would recurse infinitely. - Patch from Nicola Palumbo and Laurent De Buyst. - -- bpo-24426: Fast searching optimization in regular expressions now works - for patterns that starts with capturing groups. Fast searching - optimization now can't be disabled at compile time. - -- bpo-23661: unittest.mock side_effects can now be exceptions again. This - was a regression vs Python 3.4. Patch from Ignacio Rossi - -- bpo-13248: Remove deprecated inspect.getmoduleinfo function. - -- bpo-25578: Fix (another) memory leak in SSLSocket.getpeercer(). - -- bpo-25530: Disable the vulnerable SSLv3 protocol by default when creating - ssl.SSLContext. - -- bpo-25569: Fix memory leak in SSLSocket.getpeercert(). - -- bpo-25471: Sockets returned from accept() shouldn't appear to be - nonblocking. - -- bpo-25319: When threading.Event is reinitialized, the underlying condition - should use a regular lock rather than a recursive lock. - -- Skip getaddrinfo if host is already resolved. Patch by A. Jesse Jiryu - Davis. - -- bpo-26050: Add asyncio.StreamReader.readuntil() method. Patch by Марк - Коренберг. - -- bpo-25924: Avoid unnecessary serialization of getaddrinfo(3) calls on OS X - versions 10.5 or higher. Original patch by A. Jesse Jiryu Davis. - -- bpo-26406: Avoid unnecessary serialization of getaddrinfo(3) calls on - current versions of OpenBSD and NetBSD. Patch by A. Jesse Jiryu Davis. - -- bpo-26848: Fix asyncio/subprocess.communicate() to handle empty input. - Patch by Jack O'Connor. - -- bpo-27040: Add loop.get_exception_handler method - -- bpo-27041: asyncio: Add loop.create_future method - -IDLE ----- - -- bpo-20640: Add tests for idlelib.configHelpSourceEdit. Patch by Saimadhav - Heblikar. - -- In the 'IDLE-console differences' section of the IDLE doc, clarify how - running with IDLE affects sys.modules and the standard streams. - -- bpo-25507: fix incorrect change in IOBinding that prevented printing. - Augment IOBinding htest to include all major IOBinding functions. - -- bpo-25905: Revert unwanted conversion of ' to ’ RIGHT SINGLE QUOTATION - MARK in README.txt and open this and NEWS.txt with 'ascii'. Re-encode - CREDITS.txt to utf-8 and open it with 'utf-8'. - -- bpo-15348: Stop the debugger engine (normally in a user process) before - closing the debugger window (running in the IDLE process). This prevents - the RuntimeErrors that were being caught and ignored. - -- bpo-24455: Prevent IDLE from hanging when a) closing the shell while the - debugger is active (15347); b) closing the debugger with the [X] button - (15348); and c) activating the debugger when already active (24455). The - patch by Mark Roseman does this by making two changes. 1. Suspend and - resume the gui.interaction method with the tcl vwait mechanism intended - for this purpose (instead of root.mainloop & .quit). 2. In gui.run, allow - any existing interaction to terminate first. - -- Change 'The program' to 'Your program' in an IDLE 'kill program?' message - to make it clearer that the program referred to is the currently running - user program, not IDLE itself. - -- bpo-24750: Improve the appearance of the IDLE editor window status bar. - Patch by Mark Roseman. - -- bpo-25313: Change the handling of new built-in text color themes to better - address the compatibility problem introduced by the addition of IDLE Dark. - Consistently use the revised idleConf.CurrentTheme everywhere in idlelib. - -- bpo-24782: Extension configuration is now a tab in the IDLE Preferences - dialog rather than a separate dialog. The former tabs are now a sorted - list. Patch by Mark Roseman. - -- bpo-22726: Re-activate the config dialog help button with some content - about the other buttons and the new IDLE Dark theme. - -- bpo-24820: IDLE now has an 'IDLE Dark' built-in text color theme. It is - more or less IDLE Classic inverted, with a cobalt blue background. - Strings, comments, keywords, ... are still green, red, orange, ... . To - use it with IDLEs released before November 2015, hit the 'Save as New - Custom Theme' button and enter a new name, such as 'Custom Dark'. The - custom theme will work with any IDLE release, and can be modified. - -- bpo-25224: README.txt is now an idlelib index for IDLE developers and - curious users. The previous user content is now in the IDLE doc chapter. - 'IDLE' now means 'Integrated Development and Learning Environment'. - -- bpo-24820: Users can now set breakpoint colors in Settings -> Custom - Highlighting. Original patch by Mark Roseman. - -- bpo-24972: Inactive selection background now matches active selection - background, as configured by users, on all systems. Found items are now - always highlighted on Windows. Initial patch by Mark Roseman. - -- bpo-24570: Idle: make calltip and completion boxes appear on Macs affected - by a tk regression. Initial patch by Mark Roseman. - -- bpo-24988: Idle ScrolledList context menus (used in debugger) now work on - Mac Aqua. Patch by Mark Roseman. - -- bpo-24801: Make right-click for context menu work on Mac Aqua. Patch by - Mark Roseman. - -- bpo-25173: Associate tkinter messageboxes with a specific widget. For Mac - OSX, make them a 'sheet'. Patch by Mark Roseman. - -- bpo-25198: Enhance the initial html viewer now used for Idle Help. - Properly indent fixed-pitch text (patch by Mark Roseman). Give code - snippet a very Sphinx-like light blueish-gray background. Re-use initial - width and height set by users for shell and editor. When the Table of - Contents (TOC) menu is used, put the section header at the top of the - screen. - -- bpo-25225: Condense and rewrite Idle doc section on text colors. - -- bpo-21995: Explain some differences between IDLE and console Python. - -- bpo-22820: Explain need for *print* when running file from Idle editor. - -- bpo-25224: Doc: augment Idle feature list and no-subprocess section. - -- bpo-25219: Update doc for Idle command line options. Some were missing and - notes were not correct. - -- bpo-24861: Most of idlelib is private and subject to change. Use - idleib.idle.* to start Idle. See idlelib.__init__.__doc__. - -- bpo-25199: Idle: add synchronization comments for future maintainers. - -- bpo-16893: Replace help.txt with help.html for Idle doc display. The new - idlelib/help.html is rstripped Doc/build/html/library/idle.html. It looks - better than help.txt and will better document Idle as released. The - tkinter html viewer that works for this file was written by Rose Roseman. - The now unused EditorWindow.HelpDialog class and helt.txt file are - deprecated. - -- bpo-24199: Deprecate unused idlelib.idlever with possible removal in 3.6. - -- bpo-24790: Remove extraneous code (which also create 2 & 3 conflicts). - -Documentation -------------- - -- bpo-26736: Used HTTPS for external links in the documentation if possible. - -- bpo-6953: Rework the Readline module documentation to group related - functions together, and add more details such as what underlying Readline - functions and variables are accessed. - -- bpo-23606: Adds note to ctypes documentation regarding cdll.msvcrt. - -- bpo-24952: Clarify the default size argument of stack_size() in the - "threading" and "_thread" modules. Patch from Mattip. - -- bpo-26014: Update 3.x packaging documentation: * "See also" links to the - new docs are now provided in the legacy pages * links to setuptools - documentation have been updated - -Tests ------ - -- bpo-21916: Added tests for the turtle module. Patch by ingrid, Gregory - Loyse and Jelle Zijlstra. - -- bpo-26295: When using "python3 -m test --testdir=TESTDIR", regrtest - doesn't add "test." prefix to test module names. - -- bpo-26523: The multiprocessing thread pool (multiprocessing.dummy.Pool) - was untested. - -- bpo-26015: Added new tests for pickling iterators of mutable sequences. - -- bpo-26325: Added test.support.check_no_resource_warning() to check that no - ResourceWarning is emitted. - -- bpo-25940: Changed test_ssl to use its internal local server more. This - avoids relying on svn.python.org, which recently changed root certificate. - -- bpo-25616: Tests for OrderedDict are extracted from test_collections into - separate file test_ordered_dict. - -- bpo-25449: Added tests for OrderedDict subclasses. - -- bpo-25188: Add -P/--pgo to test.regrtest to suppress error output when - running the test suite for the purposes of a PGO build. Initial patch by - Alecsandru Patrascu. - -- bpo-22806: Add ``python -m test --list-tests`` command to list tests. - -- bpo-18174: ``python -m test --huntrleaks ...`` now also checks for leak of - file descriptors. Patch written by Richard Oudkerk. - -- bpo-25260: Fix ``python -m test --coverage`` on Windows. Remove the list - of ignored directories. - -- ``PCbuild\rt.bat`` now accepts an unlimited number of arguments to pass - along to regrtest.py. Previously there was a limit of 9. - -- bpo-26583: Skip test_timestamp_overflow in test_import if bytecode files - cannot be written. - -Build ------ - -- bpo-21277: Don't try to link _ctypes with a ffi_convenience library. - -- bpo-26884: Fix linking extension modules for cross builds. Patch by Xavier - de Gaye. - -- bpo-26932: Fixed support of RTLD_* constants defined as enum values, not - via macros (in particular on Android). Patch by Chi Hsuan Yen. - -- bpo-22359: Disable the rules for running _freeze_importlib and pgen when - cross-compiling. The output of these programs is normally saved with the - source code anyway, and is still regenerated when doing a native build. - Patch by Xavier de Gaye. - -- bpo-21668: Link audioop, _datetime, _ctypes_test modules to libm, except - on Mac OS X. Patch written by Chi Hsuan Yen. - -- bpo-25702: A --with-lto configure option has been added that will enable - link time optimizations at build time during a make profile-opt. Some - compilers and toolchains are known to not produce stable code when using - LTO, be sure to test things thoroughly before relying on it. It can - provide a few % speed up over profile-opt alone. - -- bpo-26624: Adds validation of ucrtbase[d].dll version with warning for old - versions. - -- bpo-17603: Avoid error about nonexistent fileblocks.o file by using a - lower-level check for st_blocks in struct stat. - -- bpo-26079: Fixing the build output folder for tix-8.4.3.6. Patch by Bjoern - Thiel. - -- bpo-26465: Update Windows builds to use OpenSSL 1.0.2g. - -- bpo-25348: Added ``--pgo`` and ``--pgo-job`` arguments to - ``PCbuild\build.bat`` for building with Profile-Guided Optimization. The - old ``PCbuild\build_pgo.bat`` script is removed. - -- bpo-25827: Add support for building with ICC to ``configure``, including a - new ``--with-icc`` flag. - -- bpo-25696: Fix installation of Python on UNIX with make -j9. - -- bpo-24986: It is now possible to build Python on Windows without errors - when external libraries are not available. - -- bpo-24421: Compile Modules/_math.c once, before building extensions. - Previously it could fail to compile properly if the math and cmath builds - were concurrent. - -- bpo-26465: Update OS X 10.5+ 32-bit-only installer to build and link with - OpenSSL 1.0.2g. - -- bpo-26268: Update Windows builds to use OpenSSL 1.0.2f. - -- bpo-25136: Support Apple Xcode 7's new textual SDK stub libraries. - -- bpo-24324: Do not enable unreachable code warnings when using gcc as the - option does not work correctly in older versions of gcc and has been - silently removed as of gcc-4.5. - -Windows -------- - -- bpo-27053: Updates make_zip.py to correctly generate library ZIP file. - -- bpo-26268: Update the prepare_ssl.py script to handle OpenSSL releases - that don't include the contents of the include directory (that is, 1.0.2e - and later). - -- bpo-26071: bdist_wininst created binaries fail to start and find 32bit - Python - -- bpo-26073: Update the list of magic numbers in launcher - -- bpo-26065: Excludes venv from library when generating embeddable distro. - -- bpo-25022: Removed very outdated PC/example_nt/ directory. - -Tools/Demos ------------ - -- bpo-26799: Fix python-gdb.py: don't get C types once when the Python code - is loaded, but get C types on demand. The C types can change if - python-gdb.py is loaded before the Python executable. Patch written by - Thomas Ilsche. - -- bpo-26271: Fix the Freeze tool to properly use flags passed through - configure. Patch by Daniel Shaulov. - -- bpo-26489: Add dictionary unpacking support to Tools/parser/unparse.py. - Patch by Guo Ci Teo. - -- bpo-26316: Fix variable name typo in Argument Clinic. - -- bpo-25440: Fix output of python-config --extension-suffix. - -- bpo-25154: The pyvenv script has been deprecated in favour of `python3 -m - venv`. - -C API ------ - -- bpo-26312: SystemError is now raised in all programming bugs with using - PyArg_ParseTupleAndKeywords(). RuntimeError did raised before in some - programming bugs. - -- bpo-26198: ValueError is now raised instead of TypeError on buffer - overflow in parsing "es#" and "et#" format units. SystemError is now - raised instead of TypeError on programmatical error in parsing format - string. - - -What's New in Python 3.5.5 final? -================================= - -*Release date: 2018-02-04* - -There were no new changes in version 3.5.5. - - - -What's New in Python 3.5.5 release candidate 1? -=============================================== - -*Release date: 2018-01-23* - -Security --------- - -- bpo-32551: The ``sys.path[0]`` initialization change for bpo-29139 caused - a regression by revealing an inconsistency in how sys.path is initialized - when executing ``__main__`` from a zipfile, directory, or other import - location. This is considered a potential security issue, as it may lead to - privileged processes unexpectedly loading code from user controlled - directories in situations where that was not previously the case. The - interpreter now consistently avoids ever adding the import location's - parent directory to ``sys.path``, and ensures no other ``sys.path`` - entries are inadvertently modified when inserting the import location - named on the command line. (Originally reported as bpo-29723 against - Python 3.6rc1, but it was missed at the time that the then upcoming Python - 3.5.4 release would also be affected) - -- bpo-30657: Fixed possible integer overflow in PyBytes_DecodeEscape, - CVE-2017-1000158. Original patch by Jay Bosamiya; rebased to Python 3 by - Miro Hrončok. - -- bpo-30947: Upgrade libexpat embedded copy from version 2.2.1 to 2.2.3 to - get security fixes. - -Core and Builtins ------------------ - -- bpo-31095: Fix potential crash during GC caused by ``tp_dealloc`` which - doesn't call ``PyObject_GC_UnTrack()``. - -Library -------- - -- 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-31170: expat: Update libexpat from 2.2.3 to 2.2.4. Fix copying of - partial characters for UTF-8 input (libexpat bug 115): - https://github.com/libexpat/libexpat/issues/115 - - -What's New in Python 3.5.4 final? -================================= - -*Release date: 2017-08-07* - -Library -------- - -- bpo-30119: ftplib.FTP.putline() now throws ValueError on commands that - contains CR or LF. Patch by Dong-hee Na. - - -What's New in Python 3.5.4 release candidate 1? -=============================================== - -*Release date: 2017-07-23* - -Security --------- - -- bpo-30730: Prevent environment variables injection in subprocess on - Windows. Prevent passing other environment variables and command - arguments. - -- bpo-30694: Upgrade expat copy from 2.2.0 to 2.2.1 to get fixes of multiple - security vulnerabilities including: CVE-2017-9233 (External entity - infinite loop DoS), CVE-2016-9063 (Integer overflow, re-fix), - CVE-2016-0718 (Fix regression bugs from 2.2.0's fix to CVE-2016-0718) and - CVE-2012-0876 (Counter hash flooding with SipHash). Note: the - CVE-2016-5300 (Use os-specific entropy sources like getrandom) doesn't - impact Python, since Python already gets entropy from the OS to set the - expat secret using ``XML_SetHashSalt()``. - -- bpo-30500: Fix urllib.parse.splithost() to correctly parse fragments. For - example, ``splithost('//127.0.0.1#@evil.com/')`` now correctly returns the - ``127.0.0.1`` host, instead of treating ``@evil.com`` as the host in an - authentication (``login@host``). - -- bpo-29591: Update expat copy from 2.1.1 to 2.2.0 to get fixes of - CVE-2016-0718 and CVE-2016-4472. See - https://sourceforge.net/p/expat/bugs/537/ for more information. - -Core and Builtins ------------------ - -- bpo-30876: Relative import from unloaded package now reimports the package - instead of failing with SystemError. Relative import from non-package now - fails with ImportError rather than SystemError. - -- bpo-30765: Avoid blocking in pthread_mutex_lock() when - PyThread_acquire_lock() is asked not to block. - -- bpo-27945: Fixed various segfaults with dict when input collections are - mutated during searching, inserting or comparing. Based on patches by - Duane Griffin and Tim Mitchell. - -- bpo-25794: Fixed type.__setattr__() and type.__delattr__() for - non-interned attribute names. Based on patch by Eryk Sun. - -- bpo-29935: Fixed error messages in the index() method of tuple, list and - deque when pass indices of wrong type. - -- bpo-28876: ``bool(range)`` works even if ``len(range)`` raises - :exc:`OverflowError`. - -- bpo-29600: Fix wrapping coroutine return values in StopIteration. - -- bpo-29537: Restore runtime compatibility with bytecode files generated by - CPython 3.5.0 to 3.5.2, and adjust the eval loop to avoid the problems - that could be caused by the malformed variant of the - BUILD_MAP_UNPACK_WITH_CALL opcode that they may contain. Patch by Petr - Viktorin, Serhiy Storchaka, and Nick Coghlan. - -- bpo-28598: Support __rmod__ for subclasses of str being called before - str.__mod__. Patch by Martijn Pieters. - -- bpo-29602: Fix incorrect handling of signed zeros in complex constructor - for complex subclasses and for inputs having a __complex__ method. Patch - by Serhiy Storchaka. - -- bpo-29347: Fixed possibly dereferencing undefined pointers when creating - weakref objects. - -- bpo-29438: Fixed use-after-free problem in key sharing dict. - -- bpo-29319: Prevent RunMainFromImporter overwriting sys.path[0]. - -- bpo-29337: Fixed possible BytesWarning when compare the code objects. - Warnings could be emitted at compile time. - -- bpo-29478: If max_line_length=None is specified while using the Compat32 - policy, it is no longer ignored. Patch by Mircea Cosbuc. - -Library -------- - -- bpo-29403: Fix ``unittest.mock``'s autospec to not fail on method-bound - builtin functions. Patch by Aaron Gallagher. - -- bpo-30961: Fix decrementing a borrowed reference in tracemalloc. - -- bpo-30886: Fix multiprocessing.Queue.join_thread(): it now waits until the - thread completes, even if the thread was started by the same process which - created the queue. - -- bpo-29854: Fix segfault in readline when using readline's history-size - option. Patch by Nir Soffer. - -- bpo-30807: signal.setitimer() may disable the timer when passed a tiny - value. Tiny values (such as 1e-6) are valid non-zero values for - setitimer(), which is specified as taking microsecond-resolution - intervals. However, on some platform, our conversion routine could convert - 1e-6 into a zero interval, therefore disabling the timer instead of - (re-)scheduling it. - -- bpo-30441: Fix bug when modifying os.environ while iterating over it - -- bpo-30532: Fix email header value parser dropping folding white space in - certain cases. - -- bpo-29169: Update zlib to 1.2.11. - -- bpo-30879: os.listdir() and os.scandir() now emit bytes names when called - with bytes-like argument. - -- bpo-30746: Prohibited the '=' character in environment variable names in - ``os.putenv()`` and ``os.spawn*()``. - -- bpo-29755: Fixed the lgettext() family of functions in the gettext module. - They now always return bytes. - -- bpo-30645: Fix path calculation in imp.load_package(), fixing it for cases - when a package is only shipped with bytecodes. Patch by Alexandru - Ardelean. - -- bpo-23890: unittest.TestCase.assertRaises() now manually breaks a - reference cycle to not keep objects alive longer than expected. - -- bpo-30149: inspect.signature() now supports callables with - variable-argument parameters wrapped with partialmethod. Patch by Dong-hee - Na. - -- bpo-29931: Fixed comparison check for ipaddress.ip_interface objects. - Patch by Sanjay Sundaresan. - -- bpo-24484: Avoid race condition in multiprocessing cleanup. - -- bpo-28994: The traceback no longer displayed for SystemExit raised in a - callback registered by atexit. - -- bpo-30508: Don't log exceptions if Task/Future "cancel()" method was - called. - -- bpo-28556: Updates to typing module: Add generic AsyncContextManager, add - support for ContextManager on all versions. Original PRs by Jelle Zijlstra - and Ivan Levkivskyi - -- bpo-29870: Fix ssl sockets leaks when connection is aborted in asyncio/ssl - implementation. Patch by Michaël Sghaïer. - -- bpo-29743: Closing transport during handshake process leaks open socket. - Patch by Nikolay Kim - -- bpo-27585: Fix waiter cancellation in asyncio.Lock. Patch by Mathieu - Sornay. - -- bpo-30418: On Windows, subprocess.Popen.communicate() now also ignore - EINVAL on stdin.write() if the child process is still running but closed - the pipe. - -- bpo-30378: Fix the problem that logging.handlers.SysLogHandler cannot - handle IPv6 addresses. - -- bpo-29960: Preserve generator state when _random.Random.setstate() raises - an exception. Patch by Bryan Olson. - -- bpo-30414: multiprocessing.Queue._feed background running thread do not - break from main loop on exception. - -- bpo-30003: Fix handling escape characters in HZ codec. Based on patch by - Ma Lin. - -- bpo-30301: Fix AttributeError when using SimpleQueue.empty() under *spawn* - and *forkserver* start methods. - -- bpo-30329: imaplib and poplib now catch the Windows socket WSAEINVAL error - (code 10022) on shutdown(SHUT_RDWR): An invalid operation was attempted. - This error occurs sometimes on SSL connections. - -- bpo-30375: Warnings emitted when compile a regular expression now always - point to the line in the user code. Previously they could point into - inners of the re module if emitted from inside of groups or conditionals. - -- bpo-30048: Fixed ``Task.cancel()`` can be ignored when the task is running - coroutine and the coroutine returned without any more ``await``. - -- bpo-29990: Fix range checking in GB18030 decoder. Original patch by Ma - Lin. - -- bpo-26293: Change resulted because of zipfile breakage. (See also: - bpo-29094) - -- bpo-30243: Removed the __init__ methods of _json's scanner and encoder. - Misusing them could cause memory leaks or crashes. Now scanner and - encoder objects are completely initialized in the __new__ methods. - -- bpo-30185: Avoid KeyboardInterrupt tracebacks in forkserver helper process - when Ctrl-C is received. - -- bpo-28556: Various updates to typing module: add typing.NoReturn type, use - WrapperDescriptorType, minor bug-fixes. Original PRs by Jim - Fasarakis-Hilliard and Ivan Levkivskyi. - -- bpo-30205: Fix getsockname() for unbound AF_UNIX sockets on Linux. - -- bpo-30070: Fixed leaks and crashes in errors handling in the parser - module. - -- bpo-30061: Fixed crashes in IOBase methods __next__() and readlines() when - readline() or __next__() respectively return non-sizeable object. Fixed - possible other errors caused by not checking results of PyObject_Size(), - PySequence_Size(), or PyMapping_Size(). - -- bpo-30068: _io._IOBase.readlines will check if it's closed first when hint - is present. - -- bpo-29694: Fixed race condition in pathlib mkdir with flags parents=True. - Patch by Armin Rigo. - -- bpo-29692: Fixed arbitrary unchaining of RuntimeError exceptions in - contextlib.contextmanager. Patch by Siddharth Velankar. - -- bpo-29998: Pickling and copying ImportError now preserves name and path - attributes. - -- bpo-29942: Fix a crash in itertools.chain.from_iterable when encountering - long runs of empty iterables. - -- bpo-27863: Fixed multiple crashes in ElementTree caused by race conditions - and wrong types. - -- bpo-28699: Fixed a bug in pools in multiprocessing.pool that raising an - exception at the very first of an iterable may swallow the exception or - make the program hang. Patch by Davin Potts and Xiang Zhang. - -- bpo-25803: Avoid incorrect errors raised by Path.mkdir(exist_ok=True) when - the OS gives priority to errors such as EACCES over EEXIST. - -- bpo-29861: Release references to tasks, their arguments and their results - as soon as they are finished in multiprocessing.Pool. - -- bpo-29884: faulthandler: Restore the old sigaltstack during teardown. - Patch by Christophe Zeitouny. - -- bpo-25455: Fixed crashes in repr of recursive buffered file-like objects. - -- bpo-29800: Fix crashes in partial.__repr__ if the keys of partial.keywords - are not strings. Patch by Michael Seifert. - -- bpo-29742: get_extra_info() raises exception if get called on closed ssl - transport. Patch by Nikolay Kim. - -- bpo-8256: Fixed possible failing or crashing input() if attributes - "encoding" or "errors" of sys.stdin or sys.stdout are not set or are not - strings. - -- bpo-28298: Fix a bug that prevented array 'Q', 'L' and 'I' from accepting - big intables (objects that have __int__) as elements. Patch by Oren - Milman. - -- bpo-29615: SimpleXMLRPCDispatcher no longer chains KeyError (or any other - exception) to exception(s) raised in the dispatched methods. Patch by Petr - Motejlek. - -- bpo-29704: asyncio.subprocess.SubprocessStreamProtocol no longer closes - before all pipes are closed. - -- bpo-29703: Fix asyncio to support instantiation of new event loops in - child processes. - -- bpo-29376: Fix assertion error in threading._DummyThread.is_alive(). - -- bpo-29110: Fix file object leak in aifc.open() when file is given as a - filesystem path and is not in valid AIFF format. Patch by Anthony Zhang. - -- bpo-28961: Fix unittest.mock._Call helper: don't ignore the name parameter - anymore. Patch written by Jiajun Huang. - -- bpo-29532: Altering a kwarg dictionary passed to functools.partial() no - longer affects a partial object after creation. - -- bpo-28556: Various updates to typing module: typing.Counter, - typing.ChainMap, improved ABC caching, etc. Original PRs by Jelle - Zijlstra, Ivan Levkivskyi, Manuel Krebber, and Łukasz Langa. - -- bpo-29100: Fix datetime.fromtimestamp() regression introduced in Python - 3.6.0: check minimum and maximum years. - -- bpo-29519: Fix weakref spewing exceptions during interpreter shutdown when - used with a rare combination of multiprocessing and custom codecs. - -- bpo-29416: Prevent infinite loop in pathlib.Path.mkdir - -- bpo-29444: Fixed out-of-bounds buffer access in the group() method of the - match object. Based on patch by WGH. - -- bpo-29335: Fix subprocess.Popen.wait() when the child process has exited - to a stopped instead of terminated state (ex: when under ptrace). - -- bpo-29290: Fix a regression in argparse that help messages would wrap at - non-breaking spaces. - -- bpo-28735: Fixed the comparison of mock.MagickMock with mock.ANY. - -- bpo-29011: Fix an important omission by adding Deque to the typing module. - -- bpo-29219: Fixed infinite recursion in the repr of uninitialized - ctypes.CDLL instances. - -- bpo-28969: Fixed race condition in C implementation of - functools.lru_cache. KeyError could be raised when cached function with - full cache was simultaneously called from different threads with the same - uncached arguments. - -- bpo-29142: In urllib.request, suffixes in no_proxy environment variable - with leading dots could match related hostnames again (e.g. .b.c matches - a.b.c). Patch by Milan Oberkirch. - -Documentation -------------- - -- bpo-30176: Add missing attribute related constants in curses - documentation. - -- bpo-26985: Add missing info of code object in inspect documentation. - -- bpo-28929: Link the documentation to its source file on GitHub. - -- bpo-25008: Document smtpd.py as effectively deprecated and add a pointer - to aiosmtpd, a third-party asyncio-based replacement. - -- bpo-26355: Add canonical header link on each page to corresponding major - version of the documentation. Patch by Matthias Bussonnier. - -- bpo-29349: Fix Python 2 syntax in code for building the documentation. - -Tests ------ - -- bpo-30822: Fix regrtest command line parser to allow passing -u - extralargefile to run test_zipfile64. - -- bpo-30383: regrtest: Enhance regrtest and backport features from the - master branch. Add options: --coverage, --testdir, --list-tests (list test - files, don't run them), --list-cases (list test identifiers, don't run - them, :issue:`30523`), --matchfile (load a list of test filters from a - text file, :issue:`30540`), --slowest (alias to --slow). Enhance output: - add timestamp, test result, currently running tests, "Tests result: xxx" - summary with total duration, etc. Fix reference leak hunting in regrtest, - --huntrleaks: regrtest now warms up caches, create explicitly all internal - singletons which are created on demand to prevent false positives when - checking for reference leaks. (:issue:`30675`). - -- bpo-30357: test_thread: setUp() now uses support.threading_setup() and - support.threading_cleanup() to wait until threads complete to avoid random - side effects on following tests. Initial patch written by Grzegorz - Grzywacz. - -- bpo-28087: Skip test_asyncore and test_eintr poll failures on macOS. Skip - some tests of select.poll when running on macOS due to unresolved issues - with the underlying system poll function on some macOS versions. - -- bpo-30197: Enhanced functions swap_attr() and swap_item() in the - test.support module. They now work when delete replaced attribute or item - inside the with statement. The old value of the attribute or item (or - None if it doesn't exist) now will be assigned to the target of the "as" - clause, if there is one. - -- bpo-29571: to match the behaviour of the ``re.LOCALE`` flag, - test_re.test_locale_flag now uses ``locale.getpreferredencoding(False)`` - to determine the candidate encoding for the test regex (allowing it to - correctly skip the test when the default locale encoding is a multi-byte - encoding) - -Build ------ - -- bpo-29243: Prevent unnecessary rebuilding of Python during ``make test``, - ``make install`` and some other make targets when configured with - ``--enable-optimizations``. - -- bpo-23404: Don't regenerate generated files based on file modification - time anymore: the action is now explicit. Replace ``make touch`` with - ``make regen-all``. - -- bpo-29643: Fix ``--enable-optimization`` didn't work. - -Windows -------- - -- bpo-30687: Locate msbuild.exe on Windows when building rather than - vcvarsall.bat - -- bpo-29392: Prevent crash when passing invalid arguments into msvcrt - module. - -C API ------ - -- bpo-27867: Function PySlice_GetIndicesEx() is replaced with a macro if - Py_LIMITED_API is set to the value between 0x03050400 and 0x03060000 (not - including) or 0x03060100 or higher. - -- bpo-29083: Fixed the declaration of some public API functions. - PyArg_VaParse() and PyArg_VaParseTupleAndKeywords() were not available in - limited API. PyArg_ValidateKeywordArguments(), PyArg_UnpackTuple() and - Py_BuildValue() were not available in limited API of version < 3.3 when - PY_SSIZE_T_CLEAN is defined. - - -What's New in Python 3.5.3 final? -================================= - -*Release date: 2017-01-17* - -There were no code changes between 3.5.3rc1 and 3.5.3 final. - - - -What's New in Python 3.5.3 release candidate 1? -=============================================== - -*Release date: 2017-01-02* - -Security --------- - -- bpo-27278: Fix os.urandom() implementation using getrandom() on Linux. - Truncate size to INT_MAX and loop until we collected enough random bytes, - instead of casting a directly Py_ssize_t to int. - -- bpo-22636: Avoid shell injection problems with ctypes.util.find_library(). - -Core and Builtins ------------------ - -- bpo-29073: bytearray formatting no longer truncates on first null byte. - -- bpo-28932: Do not include <sys/random.h> if it does not exist. - -- bpo-28147: Fix a memory leak in split-table dictionaries: setattr() must - not convert combined table into split table. - -- bpo-25677: Correct the positioning of the syntax error caret for indented - blocks. Based on patch by Michael Layzell. - -- bpo-29000: Fixed bytes formatting of octals with zero padding in alternate - form. - -- bpo-28512: Fixed setting the offset attribute of SyntaxError by - PyErr_SyntaxLocationEx() and PyErr_SyntaxLocationObject(). - -- bpo-28991: functools.lru_cache() was susceptible to an obscure reentrancy - bug caused by a monkey-patched len() function. - -- bpo-28648: Fixed crash in Py_DecodeLocale() in debug build on Mac OS X - when decode astral characters. Patch by Xiang Zhang. - -- bpo-19398: Extra slash no longer added to sys.path components in case of - empty compile-time PYTHONPATH components. - -- bpo-28426: Fixed potential crash in PyUnicode_AsDecodedObject() in debug - build. - -- bpo-23782: Fixed possible memory leak in _PyTraceback_Add() and exception - loss in PyTraceBack_Here(). - -- bpo-28379: Added sanity checks and tests for PyUnicode_CopyCharacters(). - Patch by Xiang Zhang. - -- bpo-28376: The type of long range iterator is now registered as Iterator. - Patch by Oren Milman. - -- bpo-28376: The constructor of range_iterator now checks that step is not - 0. Patch by Oren Milman. - -- bpo-26906: Resolving special methods of uninitialized type now causes - implicit initialization of the type instead of a fail. - -- bpo-18287: PyType_Ready() now checks that tp_name is not NULL. Original - patch by Niklas Koep. - -- bpo-24098: Fixed possible crash when AST is changed in process of - compiling it. - -- bpo-28350: String constants with null character no longer interned. - -- bpo-26617: Fix crash when GC runs during weakref callbacks. - -- bpo-27942: String constants now interned recursively in tuples and - frozensets. - -- bpo-21578: Fixed misleading error message when ImportError called with - invalid keyword args. - -- bpo-28203: Fix incorrect type in error message from ``complex(1.0, - {2:3})``. Patch by Soumya Sharma. - -- bpo-27955: Fallback on reading /dev/urandom device when the getrandom() - syscall fails with EPERM, for example when blocked by SECCOMP. - -- bpo-28131: Fix a regression in zipimport's compile_source(). zipimport - should use the same optimization level as the interpreter. - -- bpo-25221: Fix corrupted result from PyLong_FromLong(0) when Python is - compiled with NSMALLPOSINTS = 0. - -- bpo-25758: Prevents zipimport from unnecessarily encoding a filename - (patch by Eryk Sun) - -- bpo-28189: dictitems_contains no longer swallows compare errors. (Patch by - Xiang Zhang) - -- bpo-27812: Properly clear out a generator's frame's backreference to the - generator to prevent crashes in frame.clear(). - -- bpo-27811: Fix a crash when a coroutine that has not been awaited is - finalized with warnings-as-errors enabled. - -- bpo-27587: Fix another issue found by PVS-Studio: Null pointer check after - use of 'def' in _PyState_AddModule(). Initial patch by Christian Heimes. - -- bpo-26020: set literal evaluation order did not match documented - behaviour. - -- bpo-27782: Multi-phase extension module import now correctly allows the - ``m_methods`` field to be used to add module level functions to instances - of non-module types returned from ``Py_create_mod``. Patch by Xiang Zhang. - -- bpo-27936: The round() function accepted a second None argument for some - types but not for others. Fixed the inconsistency by accepting None for - all numeric types. - -- bpo-27487: Warn if a submodule argument to "python -m" or - runpy.run_module() is found in sys.modules after parent packages are - imported, but before the submodule is executed. - -- bpo-27558: Fix a SystemError in the implementation of "raise" statement. - In a brand new thread, raise a RuntimeError since there is no active - exception to reraise. Patch written by Xiang Zhang. - -- bpo-27419: Standard __import__() no longer look up "__import__" in globals - or builtins for importing submodules or "from import". Fixed handling an - error of non-string package name. - -- bpo-27083: Respect the PYTHONCASEOK environment variable under Windows. - -- bpo-27514: Make having too many statically nested blocks a SyntaxError - instead of SystemError. - -- bpo-27473: Fixed possible integer overflow in bytes and bytearray - concatenations. Patch by Xiang Zhang. - -- bpo-27507: Add integer overflow check in bytearray.extend(). Patch by - Xiang Zhang. - -- bpo-27581: Don't rely on wrapping for overflow check in - PySequence_Tuple(). Patch by Xiang Zhang. - -- bpo-27443: __length_hint__() of bytearray iterators no longer return a - negative integer for a resized bytearray. - -- bpo-27942: Fix memory leak in codeobject.c - -Library -------- - -- bpo-15812: inspect.getframeinfo() now correctly shows the first line of a - context. Patch by Sam Breese. - -- bpo-29094: Offsets in a ZIP file created with extern file object and modes - "w" and "x" now are relative to the start of the file. - -- bpo-13051: Fixed recursion errors in large or resized - curses.textpad.Textbox. Based on patch by Tycho Andersen. - -- bpo-29119: Fix weakrefs in the pure python version of - collections.OrderedDict move_to_end() method. Contributed by Andra - Bogildea. - -- bpo-9770: curses.ascii predicates now work correctly with negative - integers. - -- bpo-28427: old keys should not remove new values from WeakValueDictionary - when collecting from another thread. - -- bpo-28923: Remove editor artifacts from Tix.py. - -- bpo-28871: Fixed a crash when deallocate deep ElementTree. - -- bpo-19542: Fix bugs in WeakValueDictionary.setdefault() and - WeakValueDictionary.pop() when a GC collection happens in another thread. - -- bpo-20191: Fixed a crash in resource.prlimit() when pass a sequence that - doesn't own its elements as limits. - -- bpo-28779: multiprocessing.set_forkserver_preload() would crash the - forkserver process if a preloaded module instantiated some multiprocessing - objects such as locks. - -- bpo-28847: dbm.dumb now supports reading read-only files and no longer - writes the index file when it is not changed. - -- bpo-25659: In ctypes, prevent a crash calling the from_buffer() and - from_buffer_copy() methods on abstract classes like Array. - -- bpo-28732: Fix crash in os.spawnv() with no elements in args - -- bpo-28485: Always raise ValueError for negative - compileall.compile_dir(workers=...) parameter, even when multithreading is - unavailable. - -- bpo-28387: Fixed possible crash in _io.TextIOWrapper deallocator when the - garbage collector is invoked in other thread. Based on patch by Sebastian - Cufre. - -- bpo-27517: LZMA compressor and decompressor no longer raise exceptions if - given empty data twice. Patch by Benjamin Fogle. - -- bpo-28549: Fixed segfault in curses's addch() with ncurses6. - -- bpo-28449: tarfile.open() with mode "r" or "r:" now tries to open a tar - file with compression before trying to open it without compression. - Otherwise it had 50% chance failed with ignore_zeros=True. - -- bpo-23262: The webbrowser module now supports Firefox 36+ and derived - browsers. Based on patch by Oleg Broytman. - -- bpo-27939: Fixed bugs in tkinter.ttk.LabeledScale and tkinter.Scale caused - by representing the scale as float value internally in Tk. tkinter.IntVar - now works if float value is set to underlying Tk variable. - -- bpo-28255: calendar.TextCalendar().prmonth() no longer prints a space at - the start of new line after printing a month's calendar. Patch by Xiang - Zhang. - -- bpo-20491: The textwrap.TextWrapper class now honors non-breaking spaces. - Based on patch by Kaarle Ritvanen. - -- bpo-28353: os.fwalk() no longer fails on broken links. - -- bpo-25464: Fixed HList.header_exists() in tkinter.tix module by addin a - workaround to Tix library bug. - -- bpo-28488: shutil.make_archive() no longer add entry "./" to ZIP archive. - -- bpo-24452: Make webbrowser support Chrome on Mac OS X. - -- bpo-20766: Fix references leaked by pdb in the handling of SIGINT - handlers. - -- bpo-26293: Fixed writing ZIP files that starts not from the start of the - file. Offsets in ZIP file now are relative to the start of the archive in - conforming to the specification. - -- bpo-28321: Fixed writing non-BMP characters with binary format in - plistlib. - -- bpo-28322: Fixed possible crashes when unpickle itertools objects from - incorrect pickle data. Based on patch by John Leitch. - -- Fix possible integer overflows and crashes in the mmap module with unusual - usage patterns. - -- bpo-1703178: Fix the ability to pass the --link-objects option to the - distutils build_ext command. - -- bpo-28253: Fixed calendar functions for extreme months: 0001-01 and - 9999-12. Methods itermonthdays() and itermonthdays2() are reimplemented so - that they don't call itermonthdates() which can cause datetime.date - under/overflow. - -- bpo-28275: Fixed possible use after free in the decompress() methods of - the LZMADecompressor and BZ2Decompressor classes. Original patch by John - Leitch. - -- bpo-27897: Fixed possible crash in sqlite3.Connection.create_collation() - if pass invalid string-like object as a name. Patch by Xiang Zhang. - -- bpo-18893: Fix invalid exception handling in Lib/ctypes/macholib/dyld.py. - Patch by Madison May. - -- bpo-27611: Fixed support of default root window in the tkinter.tix module. - -- bpo-27348: In the traceback module, restore the formatting of exception - messages like "Exception: None". This fixes a regression introduced in - 3.5a2. - -- bpo-25651: Allow falsy values to be used for msg parameter of subTest(). - -- bpo-27932: Prevent memory leak in win32_ver(). - -- Fix UnboundLocalError in socket._sendfile_use_sendfile. - -- bpo-28075: Check for ERROR_ACCESS_DENIED in Windows implementation of - os.stat(). Patch by Eryk Sun. - -- bpo-25270: Prevent codecs.escape_encode() from raising SystemError when an - empty bytestring is passed. - -- bpo-28181: Get antigravity over HTTPS. Patch by Kaartic Sivaraam. - -- bpo-25895: Enable WebSocket URL schemes in urllib.parse.urljoin. Patch by - Gergely Imreh and Markus Holtermann. - -- bpo-27599: Fixed buffer overrun in binascii.b2a_qp() and - binascii.a2b_qp(). - -- bpo-19003: m email.generator now replaces only ``\r`` and/or ``\n`` line - endings, per the RFC, instead of all unicode line endings. - -- bpo-28019: itertools.count() no longer rounds non-integer step in range - between 1.0 and 2.0 to 1. - -- bpo-25969: Update the lib2to3 grammar to handle the unpacking - generalizations added in 3.5. - -- bpo-14977: mailcap now respects the order of the lines in the mailcap - files ("first match"), as required by RFC 1542. Patch by Michael Lazar. - -- bpo-24594: Validates persist parameter when opening MSI database - -- bpo-17582: xml.etree.ElementTree nows preserves whitespaces in attributes - (Patch by Duane Griffin. Reviewed and approved by Stefan Behnel.) - -- bpo-28047: Fixed calculation of line length used for the base64 CTE in the - new email policies. - -- bpo-27445: Don't pass str(_charset) to MIMEText.set_payload(). Patch by - Claude Paroz. - -- bpo-22450: urllib now includes an ``Accept: */*`` header among the default - headers. This makes the results of REST API requests more consistent and - predictable especially when proxy servers are involved. - -- lib2to3.pgen3.driver.load_grammar() now creates a stable cache file - between runs given the same Grammar.txt input regardless of the hash - randomization setting. - -- bpo-27570: Avoid zero-length memcpy() etc calls with null source pointers - in the "ctypes" and "array" modules. - -- bpo-22233: Break email header lines *only* on the RFC specified CR and LF - characters, not on arbitrary unicode line breaks. This also fixes a bug - in HTTP header parsing. - -- bpo-27988: Fix email iter_attachments incorrect mutation of payload list. - -- bpo-27691: Fix ssl module's parsing of GEN_RID subject alternative name - fields in X.509 certs. - -- bpo-27850: Remove 3DES from ssl module's default cipher list to counter - measure sweet32 attack (CVE-2016-2183). - -- bpo-27766: Add ChaCha20 Poly1305 to ssl module's default cipher list. - (Required OpenSSL 1.1.0 or LibreSSL). - -- bpo-26470: Port ssl and hashlib module to OpenSSL 1.1.0. - -- Remove support for passing a file descriptor to os.access. It never worked - but previously didn't raise. - -- bpo-12885: Fix error when distutils encounters symlink. - -- bpo-27881: Fixed possible bugs when setting - sqlite3.Connection.isolation_level. Based on patch by Xiang Zhang. - -- bpo-27861: Fixed a crash in sqlite3.Connection.cursor() when a factory - creates not a cursor. Patch by Xiang Zhang. - -- bpo-19884: Avoid spurious output on OS X with Gnu Readline. - -- bpo-27706: Restore deterministic behavior of random.Random().seed() for - string seeds using seeding version 1. Allows sequences of calls to - random() to exactly match those obtained in Python 2. Patch by Nofar - Schnider. - -- bpo-10513: Fix a regression in Connection.commit(). Statements should not - be reset after a commit. - -- A new version of typing.py from https://github.com/python/typing: - Collection (only for 3.6) (Issue #27598). Add FrozenSet to __all__ - (upstream #261). Fix crash in _get_type_vars() (upstream #259). Remove the - dict constraint in ForwardRef._eval_type (upstream #252). - -- bpo-27539: Fix unnormalised ``Fraction.__pow__`` result in the case of - negative exponent and negative base. - -- bpo-21718: cursor.description is now available for queries using CTEs. - -- bpo-2466: posixpath.ismount now correctly recognizes mount points which - the user does not have permission to access. - -- bpo-27773: Correct some memory management errors server_hostname in - _ssl.wrap_socket(). - -- bpo-26750: unittest.mock.create_autospec() now works properly for - subclasses of property() and other data descriptors. - -- In the curses module, raise an error if window.getstr() or window.instr() - is passed a negative value. - -- bpo-27783: Fix possible usage of uninitialized memory in - operator.methodcaller. - -- bpo-27774: Fix possible Py_DECREF on unowned object in _sre. - -- bpo-27760: Fix possible integer overflow in binascii.b2a_qp. - -- bpo-27758: Fix possible integer overflow in the _csv module for large - record lengths. - -- bpo-27568: Prevent HTTPoxy attack (CVE-2016-1000110). Ignore the - HTTP_PROXY variable when REQUEST_METHOD environment is set, which - indicates that the script is in CGI mode. - -- bpo-27656: Do not assume sched.h defines any SCHED_* constants. - -- bpo-27130: In the "zlib" module, fix handling of large buffers (typically - 4 GiB) when compressing and decompressing. Previously, inputs were - limited to 4 GiB, and compression and decompression operations did not - properly handle results of 4 GiB. - -- bpo-27533: Release GIL in nt._isdir - -- bpo-17711: Fixed unpickling by the persistent ID with protocol 0. Original - patch by Alexandre Vassalotti. - -- bpo-27522: Avoid an unintentional reference cycle in email.feedparser. - -- bpo-26844: Fix error message for imp.find_module() to refer to 'path' - instead of 'name'. Patch by Lev Maximov. - -- bpo-23804: Fix SSL zero-length recv() calls to not block and not raise an - error about unclean EOF. - -- bpo-27466: Change time format returned by http.cookie.time2netscape, - confirming the netscape cookie format and making it consistent with - documentation. - -- bpo-26664: Fix activate.fish by removing mis-use of ``$``. - -- bpo-22115: Fixed tracing Tkinter variables: trace_vdelete() with wrong - mode no longer break tracing, trace_vinfo() now always returns a list of - pairs of strings, tracing in the "u" mode now works. - -- Fix a scoping issue in importlib.util.LazyLoader which triggered an - UnboundLocalError when lazy-loading a module that was already put into - sys.modules. - -- bpo-27079: Fixed curses.ascii functions isblank(), iscntrl() and - ispunct(). - -- bpo-26754: Some functions (compile() etc) accepted a filename argument - encoded as an iterable of integers. Now only strings and byte-like objects - are accepted. - -- bpo-27048: Prevents distutils failing on Windows when environment - variables contain non-ASCII characters - -- bpo-27330: Fixed possible leaks in the ctypes module. - -- bpo-27238: Got rid of bare excepts in the turtle module. Original patch - by Jelle Zijlstra. - -- bpo-27122: When an exception is raised within the context being managed by - a contextlib.ExitStack() and one of the exit stack generators catches and - raises it in a chain, do not re-raise the original exception when exiting, - let the new chained one through. This avoids the :pep:`479` bug described - in issue25782. - -- bpo-26386: Fixed ttk.TreeView selection operations with item id's - containing spaces. - -- bpo-16182: Fix various functions in the "readline" module to use the - locale encoding, and fix get_begidx() and get_endidx() to return code - point indexes. - -- bpo-27392: Add loop.connect_accepted_socket(). Patch by Jim Fulton. - -- bpo-27930: Improved behaviour of logging.handlers.QueueListener. Thanks to - Paulo Andrade and Petr Viktorin for the analysis and patch. - -- bpo-21201: Improves readability of multiprocessing error message. Thanks - to Wojciech Walczak for patch. - -- bpo-27456: asyncio: Set TCP_NODELAY by default. - -- bpo-27906: Fix socket accept exhaustion during high TCP traffic. Patch by - Kevin Conway. - -- bpo-28174: Handle when SO_REUSEPORT isn't properly supported. Patch by - Seth Michael Larson. - -- bpo-26654: Inspect functools.partial in asyncio.Handle.__repr__. Patch by - iceboy. - -- bpo-26909: Fix slow pipes IO in asyncio. Patch by INADA Naoki. - -- bpo-28176: Fix callbacks race in asyncio.SelectorLoop.sock_connect. - -- bpo-27759: Fix selectors incorrectly retain invalid file descriptors. - Patch by Mark Williams. - -- bpo-28368: Refuse monitoring processes if the child watcher has no loop - attached. Patch by Vincent Michel. - -- bpo-28369: Raise RuntimeError when transport's FD is used with add_reader, - add_writer, etc. - -- bpo-28370: Speedup asyncio.StreamReader.readexactly. Patch by Коренберг - Марк. - -- bpo-28371: Deprecate passing asyncio.Handles to run_in_executor. - -- bpo-28372: Fix asyncio to support formatting of non-python coroutines. - -- bpo-28399: Remove UNIX socket from FS before binding. Patch by Коренберг - Марк. - -- bpo-27972: Prohibit Tasks to await on themselves. - -- bpo-26923: Fix asyncio.Gather to refuse being cancelled once all children - are done. Patch by Johannes Ebke. - -- bpo-26796: Don't configure the number of workers for default threadpool - executor. Initial patch by Hans Lawrenz. - -- bpo-28600: Optimize loop.call_soon(). - -- bpo-28613: Fix get_event_loop() return the current loop if called from - coroutines/callbacks. - -- bpo-28639: Fix inspect.isawaitable to always return bool Patch by Justin - Mayfield. - -- bpo-28652: Make loop methods reject socket kinds they do not support. - -- bpo-28653: Fix a refleak in functools.lru_cache. - -- bpo-28703: Fix asyncio.iscoroutinefunction to handle Mock objects. - -- bpo-24142: Reading a corrupt config file left the parser in an invalid - state. Original patch by Florian Höch. - -- bpo-28990: Fix SSL hanging if connection is closed before handshake - completed. (Patch by HoHo-Ho) - -IDLE ----- - -- bpo-15308: Add 'interrupt execution' (^C) to Shell menu. Patch by Roger - Serwy, updated by Bayard Randel. - -- bpo-27922: Stop IDLE tests from 'flashing' gui widgets on the screen. - -- Add version to title of IDLE help window. - -- bpo-25564: In section on IDLE -- console differences, mention that using - exec means that __builtins__ is defined for each statement. - -- bpo-27714: text_textview and test_autocomplete now pass when re-run in the - same process. This occurs when test_idle fails when run with the -w - option but without -jn. Fix warning from test_config. - -- bpo-25507: IDLE no longer runs buggy code because of its tkinter imports. - Users must include the same imports required to run directly in Python. - -- bpo-27452: add line counter and crc to IDLE configHandler test dump. - -- bpo-27365: Allow non-ascii chars in IDLE NEWS.txt, for contributor names. - -- bpo-27245: IDLE: Cleanly delete custom themes and key bindings. - Previously, when IDLE was started from a console or by import, a cascade - of warnings was emitted. Patch by Serhiy Storchaka. - -C API ------ - -- bpo-28808: PyUnicode_CompareWithASCIIString() now never raises exceptions. - -- bpo-26754: PyUnicode_FSDecoder() accepted a filename argument encoded as - an iterable of integers. Now only strings and bytes-like objects are - accepted. - -Documentation -------------- - -- bpo-28513: Documented command-line interface of zipfile. - -Tests ------ - -- bpo-28950: Disallow -j0 to be combined with -T/-l/-M in regrtest command - line arguments. - -- bpo-28666: Now test.support.rmtree is able to remove unwritable or - unreadable directories. - -- bpo-23839: Various caches now are cleared before running every test file. - -- bpo-28409: regrtest: fix the parser of command line arguments. - -- bpo-27787: Call gc.collect() before checking each test for "dangling - threads", since the dangling threads are weak references. - -- bpo-27369: In test_pyexpat, avoid testing an error message detail that - changed in Expat 2.2.0. - -Tools/Demos ------------ - -- bpo-27952: Get Tools/scripts/fixcid.py working with Python 3 and the - current "re" module, avoid invalid Python backslash escapes, and fix a bug - parsing escaped C quote signs. - -- bpo-27332: Fixed the type of the first argument of module-level functions - generated by Argument Clinic. Patch by Petr Viktorin. - -- bpo-27418: Fixed Tools/importbench/importbench.py. - -Windows -------- - -- bpo-28251: Improvements to help manuals on Windows. - -- bpo-28110: launcher.msi has different product codes between 32-bit and - 64-bit - -- bpo-25144: Ensures TargetDir is set before continuing with custom install. - -- bpo-27469: Adds a shell extension to the launcher so that drag and drop - works correctly. - -- bpo-27309: Enabled proper Windows styles in python[w].exe manifest. - -Build ------ - -- bpo-29080: Removes hard dependency on hg.exe from PCBuild/build.bat - -- bpo-23903: Added missed names to PC/python3.def. - -- bpo-10656: Fix out-of-tree building on AIX. Patch by Tristan Carel and - Michael Haubenwallner. - -- bpo-26359: Rename --with-optimiations to --enable-optimizations. - -- bpo-28444: Fix missing extensions modules when cross compiling. - -- bpo-28248: Update Windows build and OS X installers to use OpenSSL 1.0.2j. - -- bpo-28258: Fixed build with Estonian locale (python-config and distclean - targets in Makefile). Patch by Arfrever Frehtes Taifersar Arahesis. - -- bpo-26661: setup.py now detects system libffi with multiarch wrapper. - -- bpo-28066: Fix the logic that searches build directories for generated - include files when building outside the source tree. - -- bpo-15819: Remove redundant include search directory option for building - outside the source tree. - -- bpo-27566: Fix clean target in freeze makefile (patch by Lisa Roach) - -- bpo-27705: Update message in validate_ucrtbase.py - -- bpo-27983: Cause lack of llvm-profdata tool when using clang as required - for PGO linking to be a configure time error rather than make time when - --with-optimizations is enabled. Also improve our ability to find the - llvm-profdata tool on MacOS and some Linuxes. - -- bpo-26307: The profile-opt build now applies PGO to the built-in modules. - -- bpo-26359: Add the --with-optimizations configure flag. - -- bpo-27713: Suppress spurious build warnings when updating importlib's - bootstrap files. Patch by Xiang Zhang - -- bpo-25825: Correct the references to Modules/python.exp and ld_so_aix, - which are required on AIX. This updates references to an installation - path that was changed in 3.2a4, and undoes changed references to the build - tree that were made in 3.5.0a1. - -- bpo-27453: CPP invocation in configure must use CPPFLAGS. Patch by Chi - Hsuan Yen. - -- bpo-27641: The configure script now inserts comments into the makefile to - prevent the pgen and _freeze_importlib executables from being - cross-compiled. - -- bpo-26662: Set PYTHON_FOR_GEN in configure as the Python program to be - used for file generation during the build. - -- bpo-10910: Avoid C++ compilation errors on FreeBSD and OS X. Also update - FreedBSD version checks for the original ctype UTF-8 workaround. - -- bpo-28676: Prevent missing 'getentropy' declaration warning on macOS. - Patch by Gareth Rees. - - -What's New in Python 3.5.2 final? -================================= - -*Release date: 2016-06-26* - -Core and Builtins ------------------ - -- bpo-26930: Update Windows builds to use OpenSSL 1.0.2h. - -Tests ------ - -- bpo-26867: Ubuntu's openssl OP_NO_SSLv3 is forced on by default; fix test. - -IDLE ----- - -- bpo-27365: Allow non-ascii in idlelib/NEWS.txt - minimal part for 3.5.2. - - -What's New in Python 3.5.2 release candidate 1? -=============================================== - -*Release date: 2016-06-12* - -Security --------- - -- bpo-26556: Update expat to 2.1.1, fixes CVE-2015-1283. - -- Fix TLS stripping vulnerability in smtplib, CVE-2016-0772. Reported by - Team Oststrom - -- bpo-26839: On Linux, :func:`os.urandom` now calls ``getrandom()`` with - ``GRND_NONBLOCK`` to fall back on reading ``/dev/urandom`` if the urandom - entropy pool is not initialized yet. Patch written by Colm Buckley. - -- bpo-26657: Fix directory traversal vulnerability with http.server on - Windows. This fixes a regression that was introduced in 3.3.4rc1 and - 3.4.0rc1. Based on patch by Philipp Hagemeister. - -- bpo-26313: ssl.py _load_windows_store_certs fails if windows cert store is - empty. Patch by Baji. - -- bpo-25939: On Windows open the cert store readonly in - ssl.enum_certificates. - -Core and Builtins ------------------ - -- bpo-27066: Fixed SystemError if a custom opener (for open()) returns a - negative number without setting an exception. - -- bpo-20041: Fixed TypeError when frame.f_trace is set to None. Patch by - Xavier de Gaye. - -- bpo-26168: Fixed possible refleaks in failing Py_BuildValue() with the "N" - format unit. - -- bpo-26991: Fix possible refleak when creating a function with annotations. - -- bpo-27039: Fixed bytearray.remove() for values greater than 127. Patch by - Joe Jevnik. - -- bpo-23640: int.from_bytes() no longer bypasses constructors for - subclasses. - -- bpo-26811: gc.get_objects() no longer contains a broken tuple with NULL - pointer. - -- bpo-20120: Use RawConfigParser for .pypirc parsing, removing support for - interpolation unintentionally added with move to Python 3. Behavior no - longer does any interpolation in .pypirc files, matching behavior in - Python 2.7 and Setuptools 19.0. - -- bpo-26659: Make the builtin slice type support cycle collection. - -- bpo-26718: super.__init__ no longer leaks memory if called multiple times. - NOTE: A direct call of super.__init__ is not endorsed! - -- bpo-25339: PYTHONIOENCODING now has priority over locale in setting the - error handler for stdin and stdout. - -- bpo-26494: Fixed crash on iterating exhausting iterators. Affected classes - are generic sequence iterators, iterators of str, bytes, bytearray, list, - tuple, set, frozenset, dict, OrderedDict, corresponding views and - os.scandir() iterator. - -- bpo-26581: If coding cookie is specified multiple times on a line in - Python source code file, only the first one is taken to account. - -- bpo-26464: Fix str.translate() when string is ASCII and first replacements - removes character, but next replacement uses a non-ASCII character or a - string longer than 1 character. Regression introduced in Python 3.5.0. - -- bpo-22836: Ensure exception reports from PyErr_Display() and - PyErr_WriteUnraisable() are sensible even when formatting them produces - secondary errors. This affects the reports produced by - sys.__excepthook__() and when __del__() raises an exception. - -- bpo-26302: Correct behavior to reject comma as a legal character for - cookie names. - -- bpo-4806: Avoid masking the original TypeError exception when using star - (``*``) unpacking in function calls. Based on patch by Hagen Fürstenau - and Daniel Urban. - -- bpo-27138: Fix the doc comment for FileFinder.find_spec(). - -- bpo-26154: Add a new private _PyThreadState_UncheckedGet() function to get - the current Python thread state, but don't issue a fatal error if it is - NULL. This new function must be used instead of accessing directly the - _PyThreadState_Current variable. The variable is no more exposed since - Python 3.5.1 to hide the exact implementation of atomic C types, to avoid - compiler issues. - -- bpo-26194: Deque.insert() gave odd results for bounded deques that had - reached their maximum size. Now an IndexError will be raised when - attempting to insert into a full deque. - -- bpo-25843: When compiling code, don't merge constants if they are equal - but have a different types. For example, ``f1, f2 = lambda: 1, lambda: - 1.0`` is now correctly compiled to two different functions: ``f1()`` - returns ``1`` (``int``) and ``f2()`` returns ``1.0`` (``int``), even if - ``1`` and ``1.0`` are equal. - -- bpo-22995: [UPDATE] Comment out the one of the pickleability tests in - _PyObject_GetState() due to regressions observed in Cython-based projects. - -- bpo-25961: Disallowed null characters in the type name. - -- bpo-25973: Fix segfault when an invalid nonlocal statement binds a name - starting with two underscores. - -- bpo-22995: Instances of extension types with a state that aren't - subclasses of list or dict and haven't implemented any pickle-related - methods (__reduce__, __reduce_ex__, __getnewargs__, __getnewargs_ex__, or - __getstate__), can no longer be pickled. Including memoryview. - -- bpo-20440: Massive replacing unsafe attribute setting code with special - macro Py_SETREF. - -- bpo-25766: Special method __bytes__() now works in str subclasses. - -- bpo-25421: __sizeof__ methods of builtin types now use dynamic basic size. - This allows sys.getsize() to work correctly with their subclasses with - __slots__ defined. - -- bpo-25709: Fixed problem with in-place string concatenation and utf-8 - cache. - -- bpo-27147: Mention :pep:`420` in the importlib docs. - -- bpo-24097: Fixed crash in object.__reduce__() if slot name is freed inside - __getattr__. - -- bpo-24731: Fixed crash on converting objects with special methods - __bytes__, __trunc__, and __float__ returning instances of subclasses of - bytes, int, and float to subclasses of bytes, int, and float - correspondingly. - -- bpo-26478: Fix semantic bugs when using binary operators with dictionary - views and tuples. - -- bpo-26171: Fix possible integer overflow and heap corruption in - zipimporter.get_data(). - -- bpo-25660: Fix TAB key behaviour in REPL with readline. - -- bpo-25887: Raise a RuntimeError when a coroutine object is awaited more - than once. - -- bpo-27243: Update the __aiter__ protocol: instead of returning an - awaitable that resolves to an asynchronous iterator, the asynchronous - iterator should be returned directly. Doing the former will trigger a - PendingDeprecationWarning. - -Library -------- - -- bpo-21386: Implement missing IPv4Address.is_global property. It was - documented since 07a5610bae9d. Initial patch by Roger Luethi. - -- bpo-20900: distutils register command now decodes HTTP responses - 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). - -- bpo-25738: Stop http.server.BaseHTTPRequestHandler.send_error() from - sending a message body for 205 Reset Content. Also, don't send Content - header fields in responses that don't have a body. Patch by Susumu - Koshiba. - -- bpo-21313: Fix the "platform" module to tolerate when sys.version contains - truncated build information. - -- bpo-27164: In the zlib module, allow decompressing raw Deflate streams - with a predefined zdict. Based on patch by Xiang Zhang. - -- bpo-24291: Fix wsgiref.simple_server.WSGIRequestHandler to completely - write data to the client. Previously it could do partial writes and - truncate data. Also, wsgiref.handler.ServerHandler can now handle stdout - doing partial writes, but this is deprecated. - -- bpo-26809: Add ``__all__`` to :mod:`string`. Patch by Emanuel Barry. - -- bpo-26373: subprocess.Popen.communicate now correctly ignores - BrokenPipeError when the child process dies before .communicate() is - called in more/all circumstances. - -- bpo-21776: distutils.upload now correctly handles HTTPError. Initial patch - by Claudiu Popa. - -- bpo-27114: Fix SSLContext._load_windows_store_certs fails with - PermissionError - -- bpo-18383: Avoid creating duplicate filters when using filterwarnings and - simplefilter. Based on patch by Alex Shkop. - -- bpo-27057: Fix os.set_inheritable() on Android, ioctl() is blocked by - SELinux and fails with EACCESS. The function now falls back to fcntl(). - Patch written by Michał Bednarski. - -- bpo-27014: Fix infinite recursion using typing.py. Thanks to Kalle Tuure! - -- bpo-14132: Fix urllib.request redirect handling when the target only has a - query string. Original fix by Ján Janech. - -- bpo-17214: The "urllib.request" module now percent-encodes non-ASCII bytes - found in redirect target URLs. Some servers send Location header fields - with non-ASCII bytes, but "http.client" requires the request target to be - ASCII-encodable, otherwise a UnicodeEncodeError is raised. Based on patch - by Christian Heimes. - -- bpo-26892: Honor debuglevel flag in urllib.request.HTTPHandler. Patch - contributed by Chi Hsuan Yen. - -- bpo-22274: In the subprocess module, allow stderr to be redirected to - stdout even when stdout is not redirected. Patch by Akira Li. - -- bpo-26807: mock_open 'files' no longer error on readline at end of file. - Patch from Yolanda Robla. - -- bpo-25745: Fixed leaking a userptr in curses panel destructor. - -- bpo-26977: Removed unnecessary, and ignored, call to sum of squares helper - in statistics.pvariance. - -- bpo-26881: The modulefinder module now supports extended opcode arguments. - -- bpo-23815: Fixed crashes related to directly created instances of types in - _tkinter and curses.panel modules. - -- bpo-17765: weakref.ref() no longer silently ignores keyword arguments. - Patch by Georg Brandl. - -- bpo-26873: xmlrpc now raises ResponseError on unsupported type tags - instead of silently return incorrect result. - -- bpo-26711: Fixed the comparison of plistlib.Data with other types. - -- bpo-24114: Fix an uninitialized variable in `ctypes.util`. The bug only - occurs on SunOS when the ctypes implementation searches for the `crle` - program. Patch by Xiang Zhang. Tested on SunOS by Kees Bos. - -- bpo-26864: In urllib.request, change the proxy bypass host checking - against no_proxy to be case-insensitive, and to not match unrelated host - names that happen to have a bypassed hostname as a suffix. Patch by Xiang - Zhang. - -- bpo-26634: recursive_repr() now sets __qualname__ of wrapper. Patch by - Xiang Zhang. - -- bpo-26804: urllib.request will prefer lower_case proxy environment - variables over UPPER_CASE or Mixed_Case ones. Patch contributed by - Hans-Peter Jansen. - -- bpo-26837: assertSequenceEqual() now correctly outputs non-stringified - differing items (like bytes in the -b mode). This affects - assertListEqual() and assertTupleEqual(). - -- bpo-26041: Remove "will be removed in Python 3.7" from deprecation - messages of platform.dist() and platform.linux_distribution(). Patch by - Kumaripaba Miyurusara Athukorala. - -- bpo-26822: itemgetter, attrgetter and methodcaller objects no longer - silently ignore keyword arguments. - -- bpo-26733: Disassembling a class now disassembles class and static - methods. Patch by Xiang Zhang. - -- bpo-26801: Fix error handling in :func:`shutil.get_terminal_size`, catch - :exc:`AttributeError` instead of :exc:`NameError`. Patch written by - Emanuel Barry. - -- bpo-24838: tarfile's ustar and gnu formats now correctly calculate name - and link field limits for multibyte character encodings like utf-8. - -- bpo-26717: Stop encoding Latin-1-ized WSGI paths with UTF-8. Patch by - Anthony Sottile. - -- bpo-26735: Fix :func:`os.urandom` on Solaris 11.3 and newer when reading - more than 1,024 bytes: call ``getrandom()`` multiple times with a limit of - 1024 bytes per call. - -- bpo-16329: Add .webm to mimetypes.types_map. Patch by Giampaolo Rodola'. - -- bpo-13952: Add .csv to mimetypes.types_map. Patch by Geoff Wilson. - -- bpo-26709: Fixed Y2038 problem in loading binary PLists. - -- bpo-23735: Handle terminal resizing with Readline 6.3+ by installing our - own SIGWINCH handler. Patch by Eric Price. - -- bpo-26586: In http.server, respond with "413 Request header fields too - large" if there are too many header fields to parse, rather than killing - the connection and raising an unhandled exception. Patch by Xiang Zhang. - -- bpo-22854: Change BufferedReader.writable() and BufferedWriter.readable() - to always return False. - -- bpo-25195: Fix a regression in mock.MagicMock. _Call is a subclass of - tuple (changeset 3603bae63c13 only works for classes) so we need to - implement __ne__ ourselves. Patch by Andrew Plummer. - -- bpo-26644: Raise ValueError rather than SystemError when a negative length - is passed to SSLSocket.recv() or read(). - -- bpo-23804: Fix SSL recv(0) and read(0) methods to return zero bytes - instead of up to 1024. - -- bpo-26616: Fixed a bug in datetime.astimezone() method. - -- bpo-21925: :func:`warnings.formatwarning` now catches exceptions on - ``linecache.getline(...)`` to be able to log :exc:`ResourceWarning` - emitted late during the Python shutdown process. - -- bpo-24266: Ctrl+C during Readline history search now cancels the search - mode when compiled with Readline 7. - -- bpo-26560: Avoid potential ValueError in BaseHandler.start_response. - Initial patch by Peter Inglesby. - -- bpo-26569: Fix :func:`pyclbr.readmodule` and :func:`pyclbr.readmodule_ex` - to support importing packages. - -- bpo-26499: Account for remaining Content-Length in HTTPResponse.readline() - and read1(). Based on patch by Silent Ghost. Also document that - HTTPResponse now supports these methods. - -- bpo-25320: Handle sockets in directories unittest discovery is scanning. - Patch from Victor van den Elzen. - -- bpo-16181: cookiejar.http2time() now returns None if year is higher than - datetime.MAXYEAR. - -- bpo-26513: Fixes platform module detection of Windows Server - -- bpo-23718: Fixed parsing time in week 0 before Jan 1. Original patch by - Tamás Bence Gedai. - -- bpo-20589: Invoking Path.owner() and Path.group() on Windows now raise - NotImplementedError instead of ImportError. - -- bpo-26177: Fixed the keys() method for Canvas and Scrollbar widgets. - -- bpo-15068: Got rid of excessive buffering in the fileinput module. The - bufsize parameter is no longer used. - -- bpo-2202: Fix UnboundLocalError in - AbstractDigestAuthHandler.get_algorithm_impls. Initial patch by Mathieu - Dupuy. - -- bpo-25718: Fixed pickling and copying the accumulate() iterator with total - is None. - -- bpo-26475: Fixed debugging output for regular expressions with the (?x) - flag. - -- bpo-26457: Fixed the subnets() methods in IP network classes for the case - when resulting prefix length is equal to maximal prefix length. Based on - patch by Xiang Zhang. - -- bpo-26385: Remove the file if the internal open() call in - NamedTemporaryFile() fails. Patch by Silent Ghost. - -- bpo-26402: Fix XML-RPC client to retry when the server shuts down a - persistent connection. This was a regression related to the new - http.client.RemoteDisconnected exception in 3.5.0a4. - -- bpo-25913: Leading ``<~`` is optional now in base64.a85decode() with - adobe=True. Patch by Swati Jaiswal. - -- bpo-26186: Remove an invalid type check in importlib.util.LazyLoader. - -- bpo-26367: importlib.__import__() raises SystemError like - builtins.__import__() when ``level`` is specified but without an - accompanying package specified. - -- bpo-26309: In the "socketserver" module, shut down the request (closing - the connected socket) when verify_request() returns false. Patch by Aviv - Palivoda. - -- bpo-25995: os.walk() no longer uses FDs proportional to the tree depth. - -- bpo-26117: The os.scandir() iterator now closes file descriptor not only - when the iteration is finished, but when it was failed with error. - -- bpo-25911: Restored support of bytes paths in os.walk() on Windows. - -- bpo-26045: Add UTF-8 suggestion to error message when posting a - non-Latin-1 string with http.client. - -- bpo-12923: Reset FancyURLopener's redirect counter even if there is an - exception. Based on patches by Brian Brazil and Daniel Rocco. - -- bpo-25945: Fixed a crash when unpickle the functools.partial object with - wrong state. Fixed a leak in failed functools.partial constructor. "args" - and "keywords" attributes of functools.partial have now always types tuple - and dict correspondingly. - -- bpo-26202: copy.deepcopy() now correctly copies range() objects with - non-atomic attributes. - -- bpo-23076: Path.glob() now raises a ValueError if it's called with an - invalid pattern. Patch by Thomas Nyberg. - -- bpo-19883: Fixed possible integer overflows in zipimport. - -- bpo-26227: On Windows, getnameinfo(), gethostbyaddr() and - gethostbyname_ex() functions of the socket module now decode the hostname - from the ANSI code page rather than UTF-8. - -- bpo-26147: xmlrpc now works with strings not encodable with used non-UTF-8 - encoding. - -- bpo-25935: Garbage collector now breaks reference loops with OrderedDict. - -- bpo-16620: Fixed AttributeError in msilib.Directory.glob(). - -- bpo-26013: Added compatibility with broken protocol 2 pickles created in - old Python 3 versions (3.4.3 and lower). - -- bpo-25850: Use cross-compilation by default for 64-bit Windows. - -- bpo-17633: Improve zipimport's support for namespace packages. - -- bpo-24705: Fix sysconfig._parse_makefile not expanding ${} vars appearing - before $() vars. - -- bpo-22138: Fix mock.patch behavior when patching descriptors. Restore - original values after patching. Patch contributed by Sean McCully. - -- bpo-25672: In the ssl module, enable the SSL_MODE_RELEASE_BUFFERS mode - option if it is safe to do so. - -- bpo-26012: Don't traverse into symlinks for ``**`` pattern in - pathlib.Path.[r]glob(). - -- bpo-24120: Ignore PermissionError when traversing a tree with - pathlib.Path.[r]glob(). Patch by Ulrich Petri. - -- bpo-25447: fileinput now uses sys.stdin as-is if it does not have a buffer - attribute (restores backward compatibility). - -- bpo-25447: Copying the lru_cache() wrapper object now always works, - independently from the type of the wrapped object (by returning the - original object unchanged). - -- bpo-24103: Fixed possible use after free in ElementTree.XMLPullParser. - -- bpo-25860: os.fwalk() no longer skips remaining directories when error - occurs. Original patch by Samson Lee. - -- bpo-25914: Fixed and simplified OrderedDict.__sizeof__. - -- bpo-25902: Fixed various refcount issues in ElementTree iteration. - -- bpo-25717: Restore the previous behaviour of tolerating most fstat() - errors when opening files. This was a regression in 3.5a1, and stopped - anonymous temporary files from working in special cases. - -- bpo-24903: Fix regression in number of arguments compileall accepts when - '-d' is specified. The check on the number of arguments has been dropped - completely as it never worked correctly anyway. - -- bpo-25764: In the subprocess module, preserve any exception caused by - fork() failure when preexec_fn is used. - -- bpo-6478: _strptime's regexp cache now is reset after changing timezone - with time.tzset(). - -- bpo-14285: When executing a package with the "python -m package" option, - and package initialization fails, a proper traceback is now reported. The - "runpy" module now lets exceptions from package initialization pass back - to the caller, rather than raising ImportError. - -- bpo-19771: Also in runpy and the "-m" option, omit the irrelevant message - ". . . is a package and cannot be directly executed" if the package could - not even be initialized (e.g. due to a bad ``*.pyc`` file). - -- bpo-25177: Fixed problem with the mean of very small and very large - numbers. As a side effect, statistics.mean and statistics.variance should - be significantly faster. - -- bpo-25718: Fixed copying object with state with boolean value is false. - -- bpo-10131: Fixed deep copying of minidom documents. Based on patch by - Marian Ganisin. - -- bpo-25725: Fixed a reference leak in pickle.loads() when unpickling - invalid data including tuple instructions. - -- bpo-25663: In the Readline completer, avoid listing duplicate global - names, and search the global namespace before searching builtins. - -- bpo-25688: Fixed file leak in ElementTree.iterparse() raising an error. - -- bpo-23914: Fixed SystemError raised by unpickler on broken pickle data. - -- bpo-25691: Fixed crash on deleting ElementTree.Element attributes. - -- bpo-25624: ZipFile now always writes a ZIP_STORED header for directory - entries. Patch by Dingyuan Wang. - -- Skip getaddrinfo if host is already resolved. Patch by A. Jesse Jiryu - Davis. - -- bpo-26050: Add asyncio.StreamReader.readuntil() method. Patch by Марк - Коренберг. - -- bpo-25924: Avoid unnecessary serialization of getaddrinfo(3) calls on OS X - versions 10.5 or higher. Original patch by A. Jesse Jiryu Davis. - -- bpo-26406: Avoid unnecessary serialization of getaddrinfo(3) calls on - current versions of OpenBSD and NetBSD. Patch by A. Jesse Jiryu Davis. - -- bpo-26848: Fix asyncio/subprocess.communicate() to handle empty input. - Patch by Jack O'Connor. - -- bpo-27040: Add loop.get_exception_handler method - -- bpo-27041: asyncio: Add loop.create_future method - -- bpo-27223: asyncio: Fix _read_ready and _write_ready to respect - _conn_lost. Patch by Łukasz Langa. - -- bpo-22970: asyncio: Fix inconsistency cancelling Condition.wait. Patch by - David Coles. - -IDLE ----- - -- bpo-5124: Paste with text selected now replaces the selection on X11. This - matches how paste works on Windows, Mac, most modern Linux apps, and ttk - widgets. Original patch by Serhiy Storchaka. - -- bpo-24759: Make clear in idlelib.idle_test.__init__ that the directory is - a private implementation of test.test_idle and tool for maintainers. - -- bpo-27196: Stop 'ThemeChanged' warnings when running IDLE tests. These - persisted after other warnings were suppressed in #20567. Apply Serhiy - Storchaka's update_idletasks solution to four test files. Record this - additional advice in idle_test/README.txt - -- bpo-20567: Revise idle_test/README.txt with advice about avoiding tk - warning messages from tests. Apply advice to several IDLE tests. - -- bpo-27117: Make colorizer htest and turtledemo work with dark themes. Move - code for configuring text widget colors to a new function. - -- bpo-26673: When tk reports font size as 0, change to size 10. Such fonts - on Linux prevented the configuration dialog from opening. - -- bpo-21939: Add test for IDLE's percolator. Original patch by Saimadhav - Heblikar. - -- bpo-21676: Add test for IDLE's replace dialog. Original patch by Saimadhav - Heblikar. - -- bpo-18410: Add test for IDLE's search dialog. Original patch by Westley - Martínez. - -- bpo-21703: Add test for IDLE's undo delegator. Original patch by Saimadhav - Heblikar . - -- bpo-27044: Add ConfigDialog.remove_var_callbacks to stop memory leaks. - -- bpo-23977: Add more asserts to test_delegator. - -- bpo-20640: Add tests for idlelib.configHelpSourceEdit. Patch by Saimadhav - Heblikar. - -- In the 'IDLE-console differences' section of the IDLE doc, clarify how - running with IDLE affects sys.modules and the standard streams. - -- bpo-25507: fix incorrect change in IOBinding that prevented printing. - Augment IOBinding htest to include all major IOBinding functions. - -- bpo-25905: Revert unwanted conversion of ' to ’ RIGHT SINGLE QUOTATION - MARK in README.txt and open this and NEWS.txt with 'ascii'. Re-encode - CREDITS.txt to utf-8 and open it with 'utf-8'. - -Documentation -------------- - -- bpo-19489: Moved the search box from the sidebar to the header and footer - of each page. Patch by Ammar Askar. - -- bpo-24136: Document the new :pep:`448` unpacking syntax of 3.5. - -- bpo-26736: Used HTTPS for external links in the documentation if possible. - -- bpo-6953: Rework the Readline module documentation to group related - functions together, and add more details such as what underlying Readline - functions and variables are accessed. - -- bpo-23606: Adds note to ctypes documentation regarding cdll.msvcrt. - -- bpo-25500: Fix documentation to not claim that __import__ is searched for - in the global scope. - -- bpo-26014: Update 3.x packaging documentation: * "See also" links to the - new docs are now provided in the legacy pages * links to setuptools - documentation have been updated - -Tests ------ - -- bpo-21916: Added tests for the turtle module. Patch by ingrid, Gregory - Loyse and Jelle Zijlstra. - -- bpo-26523: The multiprocessing thread pool (multiprocessing.dummy.Pool) - was untested. - -- bpo-26015: Added new tests for pickling iterators of mutable sequences. - -- bpo-26325: Added test.support.check_no_resource_warning() to check that no - ResourceWarning is emitted. - -- bpo-25940: Changed test_ssl to use self-signed.pythontest.net. This - avoids relying on svn.python.org, which recently changed root certificate. - -- bpo-25616: Tests for OrderedDict are extracted from test_collections into - separate file test_ordered_dict. - -- bpo-26583: Skip test_timestamp_overflow in test_import if bytecode files - cannot be written. - -Build ------ - -- bpo-26884: Fix linking extension modules for cross builds. Patch by Xavier - de Gaye. - -- bpo-22359: Disable the rules for running _freeze_importlib and pgen when - cross-compiling. The output of these programs is normally saved with the - source code anyway, and is still regenerated when doing a native build. - Patch by Xavier de Gaye. - -- bpo-27229: Fix the cross-compiling pgen rule for in-tree builds. Patch by - Xavier de Gaye. - -- bpo-21668: Link audioop, _datetime, _ctypes_test modules to libm, except - on Mac OS X. Patch written by Xavier de Gaye. - -- bpo-25702: A --with-lto configure option has been added that will enable - link time optimizations at build time during a make profile-opt. Some - compilers and toolchains are known to not produce stable code when using - LTO, be sure to test things thoroughly before relying on it. It can - provide a few % speed up over profile-opt alone. - -- bpo-26624: Adds validation of ucrtbase[d].dll version with warning for old - versions. - -- bpo-17603: Avoid error about nonexistent fileblocks.o file by using a - lower-level check for st_blocks in struct stat. - -- bpo-26079: Fixing the build output folder for tix-8.4.3.6. Patch by Bjoern - Thiel. - -- bpo-26465: Update Windows builds to use OpenSSL 1.0.2g. - -- bpo-24421: Compile Modules/_math.c once, before building extensions. - Previously it could fail to compile properly if the math and cmath builds - were concurrent. - -- bpo-25348: Added ``--pgo`` and ``--pgo-job`` arguments to - ``PCbuild\build.bat`` for building with Profile-Guided Optimization. The - old ``PCbuild\build_pgo.bat`` script is now deprecated, and simply calls - ``PCbuild\build.bat --pgo %*``. - -- bpo-25827: Add support for building with ICC to ``configure``, including a - new ``--with-icc`` flag. - -- bpo-25696: Fix installation of Python on UNIX with make -j9. - -- bpo-26930: Update OS X 10.5+ 32-bit-only installer to build and link with - OpenSSL 1.0.2h. - -- bpo-26268: Update Windows builds to use OpenSSL 1.0.2f. - -- bpo-25136: Support Apple Xcode 7's new textual SDK stub libraries. - -- bpo-24324: Do not enable unreachable code warnings when using gcc as the - option does not work correctly in older versions of gcc and has been - silently removed as of gcc-4.5. - -Windows -------- - -- bpo-27053: Updates make_zip.py to correctly generate library ZIP file. - -- bpo-26268: Update the prepare_ssl.py script to handle OpenSSL releases - that don't include the contents of the include directory (that is, 1.0.2e - and later). - -- bpo-26071: bdist_wininst created binaries fail to start and find 32bit - Python - -- bpo-26073: Update the list of magic numbers in launcher - -- bpo-26065: Excludes venv from library when generating embeddable distro. - -- bpo-17500: Remove unused and outdated icons. (See also: - https://github.com/python/pythondotorg/issues/945) - -Tools/Demos ------------ - -- bpo-26799: Fix python-gdb.py: don't get C types once when the Python code - is loaded, but get C types on demand. The C types can change if - python-gdb.py is loaded before the Python executable. Patch written by - Thomas Ilsche. - -- bpo-26271: Fix the Freeze tool to properly use flags passed through - configure. Patch by Daniel Shaulov. - -- bpo-26489: Add dictionary unpacking support to Tools/parser/unparse.py. - Patch by Guo Ci Teo. - -- bpo-26316: Fix variable name typo in Argument Clinic. - - -What's New in Python 3.5.1 final? -================================= - -*Release date: 2015-12-06* - -Core and Builtins ------------------ - -- bpo-25709: Fixed problem with in-place string concatenation and utf-8 - cache. - -Windows -------- - -- bpo-25715: Python 3.5.1 installer shows wrong upgrade path and incorrect - logic for launcher detection. - - -What's New in Python 3.5.1 release candidate 1? -=============================================== - -*Release date: 2015-11-22* - -Core and Builtins ------------------ - -- bpo-25630: Fix a possible segfault during argument parsing in functions - that accept filesystem paths. - -- bpo-23564: Fixed a partially broken sanity check in the _posixsubprocess - internals regarding how fds_to_pass were passed to the child. The bug had - no actual impact as subprocess.py already avoided it. - -- bpo-25388: Fixed tokenizer crash when processing undecodable source code - with a null byte. - -- bpo-25462: The hash of the key now is calculated only once in most - operations in C implementation of OrderedDict. - -- bpo-22995: Default implementation of __reduce__ and __reduce_ex__ now - rejects builtin types with not defined __new__. - -- bpo-25555: Fix parser and AST: fill lineno and col_offset of "arg" node - when compiling AST from Python objects. - -- bpo-24802: Avoid buffer overreads when int(), float(), compile(), exec() - and eval() are passed bytes-like objects. These objects are not - necessarily terminated by a null byte, but the functions assumed they - were. - -- bpo-24726: Fixed a crash and leaking NULL in repr() of OrderedDict that - was mutated by direct calls of dict methods. - -- bpo-25449: Iterating OrderedDict with keys with unstable hash now raises - KeyError in C implementations as well as in Python implementation. - -- bpo-25395: Fixed crash when highly nested OrderedDict structures were - garbage collected. - -- bpo-25274: sys.setrecursionlimit() now raises a RecursionError if the new - recursion limit is too low depending at the current recursion depth. - Modify also the "lower-water mark" formula to make it monotonic. This mark - is used to decide when the overflowed flag of the thread state is reset. - -- bpo-24402: Fix input() to prompt to the redirected stdout when - sys.stdout.fileno() fails. - -- bpo-24806: Prevent builtin types that are not allowed to be subclassed - from being subclassed through multiple inheritance. - -- bpo-24848: Fixed a number of bugs in UTF-7 decoding of misformed data. - -- bpo-25280: Import trace messages emitted in verbose (-v) mode are no - longer formatted twice. - -- bpo-25003: On Solaris 11.3 or newer, os.urandom() now uses the getrandom() - function instead of the getentropy() function. The getentropy() function - is blocking to generate very good quality entropy, os.urandom() doesn't - need such high-quality entropy. - -- bpo-25182: The stdprinter (used as sys.stderr before the io module is - imported at startup) now uses the backslashreplace error handler. - -- bpo-25131: Make the line number and column offset of set/dict literals and - comprehensions correspond to the opening brace. - -- bpo-25150: Hide the private _Py_atomic_xxx symbols from the public - Python.h header to fix a compilation error with OpenMP. - PyThreadState_GET() becomes an alias to PyThreadState_Get() to avoid ABI - incompatibilities. - -Library -------- - -- bpo-25626: Change three zlib functions to accept sizes that fit in - Py_ssize_t, but internally cap those sizes to UINT_MAX. This resolves a - regression in 3.5 where GzipFile.read() failed to read chunks larger than - 2 or 4 GiB. The change affects the zlib.Decompress.decompress() - max_length parameter, the zlib.decompress() bufsize parameter, and the - zlib.Decompress.flush() length parameter. - -- bpo-25583: Avoid incorrect errors raised by os.makedirs(exist_ok=True) - when the OS gives priority to errors such as EACCES over EEXIST. - -- bpo-25593: Change semantics of EventLoop.stop() in asyncio. - -- bpo-6973: When we know a subprocess.Popen process has died, do not allow - the send_signal(), terminate(), or kill() methods to do anything as they - could potentially signal a different process. - -- bpo-25590: In the Readline completer, only call getattr() once per - attribute. - -- bpo-25498: Fix a crash when garbage-collecting ctypes objects created by - wrapping a memoryview. This was a regression made in 3.5a1. Based on - patch by Eryksun. - -- bpo-25584: Added "escape" to the __all__ list in the glob module. - -- bpo-25584: Fixed recursive glob() with patterns starting with ``**``. - -- bpo-25446: Fix regression in smtplib's AUTH LOGIN support. - -- bpo-18010: Fix the pydoc web server's module search function to handle - exceptions from importing packages. - -- bpo-25554: Got rid of circular references in regular expression parsing. - -- bpo-25510: fileinput.FileInput.readline() now returns b'' instead of '' at - the end if the FileInput was opened with binary mode. Patch by Ryosuke - Ito. - -- bpo-25503: Fixed inspect.getdoc() for inherited docstrings of properties. - Original patch by John Mark Vandenberg. - -- bpo-25515: Always use os.urandom as a source of randomness in uuid.uuid4. - -- bpo-21827: Fixed textwrap.dedent() for the case when largest common - whitespace is a substring of smallest leading whitespace. Based on patch - by Robert Li. - -- bpo-25447: The lru_cache() wrapper objects now can be copied and pickled - (by returning the original object unchanged). - -- bpo-25390: typing: Don't crash on Union[str, Pattern]. - -- bpo-25441: asyncio: Raise error from drain() when socket is closed. - -- bpo-25410: Cleaned up and fixed minor bugs in C implementation of - OrderedDict. - -- bpo-25411: Improved Unicode support in SMTPHandler through better use of - the email package. Thanks to user simon04 for the patch. - -- bpo-25407: Remove mentions of the formatter module being removed in Python - 3.6. - -- bpo-25406: Fixed a bug in C implementation of OrderedDict.move_to_end() - that caused segmentation fault or hang in iterating after moving several - items to the start of ordered dict. - -- bpo-25364: zipfile now works in threads disabled builds. - -- bpo-25328: smtpd's SMTPChannel now correctly raises a ValueError if both - decode_data and enable_SMTPUTF8 are set to true. - -- bpo-25316: distutils raises OSError instead of DistutilsPlatformError when - MSVC is not installed. - -- bpo-25380: Fixed protocol for the STACK_GLOBAL opcode in - pickletools.opcodes. - -- bpo-23972: Updates asyncio datagram create method allowing reuseport and - reuseaddr socket options to be set prior to binding the socket. Mirroring - the existing asyncio create_server method the reuseaddr option for - datagram sockets defaults to True if the O/S is 'posix' (except if the - platform is Cygwin). Patch by Chris Laws. - -- bpo-25304: Add asyncio.run_coroutine_threadsafe(). This lets you submit a - coroutine to a loop from another thread, returning a - concurrent.futures.Future. By Vincent Michel. - -- bpo-25232: Fix CGIRequestHandler to split the query from the URL at the - first question mark (?) rather than the last. Patch from Xiang Zhang. - -- bpo-24657: Prevent CGIRequestHandler from collapsing slashes in the query - part of the URL as if it were a path. Patch from Xiang Zhang. - -- bpo-24483: C implementation of functools.lru_cache() now calculates key's - hash only once. - -- bpo-22958: Constructor and update method of weakref.WeakValueDictionary - now accept the self and the dict keyword arguments. - -- bpo-22609: Constructor of collections.UserDict now accepts the self - keyword argument. - -- bpo-25111: Fixed comparison of traceback.FrameSummary. - -- bpo-25262: Added support for BINBYTES8 opcode in Python implementation of - unpickler. Highest 32 bits of 64-bit size for BINUNICODE8 and BINBYTES8 - opcodes no longer silently ignored on 32-bit platforms in C - implementation. - -- bpo-25034: Fix string.Formatter problem with auto-numbering and nested - format_specs. Patch by Anthon van der Neut. - -- bpo-25233: Rewrite the guts of asyncio.Queue and asyncio.Semaphore to be - more understandable and correct. - -- bpo-25203: Failed readline.set_completer_delims() no longer left the - module in inconsistent state. - -- bpo-23600: Default implementation of tzinfo.fromutc() was returning wrong - results in some cases. - -- bpo-23329: Allow the ssl module to be built with older versions of - LibreSSL. - -- Prevent overflow in _Unpickler_Read. - -- bpo-25047: The XML encoding declaration written by Element Tree now - respects the letter case given by the user. This restores the ability to - write encoding names in uppercase like "UTF-8", which worked in Python 2. - -- bpo-25135: Make deque_clear() safer by emptying the deque before clearing. - This helps avoid possible reentrancy issues. - -- bpo-19143: platform module now reads Windows version from kernel32.dll to - avoid compatibility shims. - -- bpo-25092: Fix datetime.strftime() failure when errno was already set to - EINVAL. - -- bpo-23517: Fix rounding in fromtimestamp() and utcfromtimestamp() methods - of datetime.datetime: microseconds are now rounded to nearest with ties - going to nearest even integer (ROUND_HALF_EVEN), instead of being rounding - towards minus infinity (ROUND_FLOOR). It's important that these methods - use the same rounding mode than datetime.timedelta to keep the property: - (datetime(1970,1,1) + timedelta(seconds=t)) == - datetime.utcfromtimestamp(t). It also the rounding mode used by - round(float) for example. - -- bpo-25155: Fix datetime.datetime.now() and datetime.datetime.utcnow() on - Windows to support date after year 2038. It was a regression introduced in - Python 3.5.0. - -- bpo-25108: Omitted internal frames in traceback functions print_stack(), - format_stack(), and extract_stack() called without arguments. - -- bpo-25118: Fix a regression of Python 3.5.0 in os.waitpid() on Windows. - -- bpo-24684: socket.socket.getaddrinfo() now calls - PyUnicode_AsEncodedString() instead of calling the encode() method of the - host, to handle correctly custom string with an encode() method which - doesn't return a byte string. The encoder of the IDNA codec is now called - directly instead of calling the encode() method of the string. - -- bpo-25060: Correctly compute stack usage of the BUILD_MAP opcode. - -- bpo-24857: Comparing call_args to a long sequence now correctly returns a - boolean result instead of raising an exception. Patch by A Kaptur. - -- bpo-23144: Make sure that HTMLParser.feed() returns all the data, even - when convert_charrefs is True. - -- bpo-24982: shutil.make_archive() with the "zip" format now adds entries - for directories (including empty directories) in ZIP file. - -- bpo-25019: Fixed a crash caused by setting non-string key of expat parser. - Based on patch by John Leitch. - -- bpo-16180: Exit pdb if file has syntax error, instead of trapping user in - an infinite loop. Patch by Xavier de Gaye. - -- bpo-24891: Fix a race condition at Python startup if the file descriptor - of stdin (0), stdout (1) or stderr (2) is closed while Python is creating - sys.stdin, sys.stdout and sys.stderr objects. These attributes are now set - to None if the creation of the object failed, instead of raising an - OSError exception. Initial patch written by Marco Paolini. - -- bpo-24992: Fix error handling and a race condition (related to garbage - collection) in collections.OrderedDict constructor. - -- bpo-24881: Fixed setting binary mode in Python implementation of FileIO on - Windows and Cygwin. Patch from Akira Li. - -- bpo-25578: Fix (another) memory leak in SSLSocket.getpeercer(). - -- bpo-25530: Disable the vulnerable SSLv3 protocol by default when creating - ssl.SSLContext. - -- bpo-25569: Fix memory leak in SSLSocket.getpeercert(). - -- bpo-25471: Sockets returned from accept() shouldn't appear to be - nonblocking. - -- bpo-25319: When threading.Event is reinitialized, the underlying condition - should use a regular lock rather than a recursive lock. - -- bpo-21112: Fix regression in unittest.expectedFailure on subclasses. Patch - from Berker Peksag. - -- bpo-24764: cgi.FieldStorage.read_multi() now ignores the Content-Length - header in part headers. Patch written by Peter Landry and reviewed by - Pierre Quentel. - -- bpo-24913: Fix overrun error in deque.index(). Found by John Leitch and - Bryce Darling. - -- bpo-24774: Fix docstring in http.server.test. Patch from Chiu-Hsiang Hsu. - -- bpo-21159: Improve message in - configparser.InterpolationMissingOptionError. Patch from Łukasz Langa. - -- bpo-20362: Honour TestCase.longMessage correctly in assertRegex. Patch - from Ilia Kurenkov. - -- bpo-23572: Fixed functools.singledispatch on classes with falsy - metaclasses. Patch by Ethan Furman. - -- asyncio: ensure_future() now accepts awaitable objects. - -IDLE ----- - -- bpo-15348: Stop the debugger engine (normally in a user process) before - closing the debugger window (running in the IDLE process). This prevents - the RuntimeErrors that were being caught and ignored. - -- bpo-24455: Prevent IDLE from hanging when a) closing the shell while the - debugger is active (15347); b) closing the debugger with the [X] button - (15348); and c) activating the debugger when already active (24455). The - patch by Mark Roseman does this by making two changes. 1. Suspend and - resume the gui.interaction method with the tcl vwait mechanism intended - for this purpose (instead of root.mainloop & .quit). 2. In gui.run, allow - any existing interaction to terminate first. - -- Change 'The program' to 'Your program' in an IDLE 'kill program?' message - to make it clearer that the program referred to is the currently running - user program, not IDLE itself. - -- bpo-24750: Improve the appearance of the IDLE editor window status bar. - Patch by Mark Roseman. - -- bpo-25313: Change the handling of new built-in text color themes to better - address the compatibility problem introduced by the addition of IDLE Dark. - Consistently use the revised idleConf.CurrentTheme everywhere in idlelib. - -- bpo-24782: Extension configuration is now a tab in the IDLE Preferences - dialog rather than a separate dialog. The former tabs are now a sorted - list. Patch by Mark Roseman. - -- bpo-22726: Re-activate the config dialog help button with some content - about the other buttons and the new IDLE Dark theme. - -- bpo-24820: IDLE now has an 'IDLE Dark' built-in text color theme. It is - more or less IDLE Classic inverted, with a cobalt blue background. - Strings, comments, keywords, ... are still green, red, orange, ... . To - use it with IDLEs released before November 2015, hit the 'Save as New - Custom Theme' button and enter a new name, such as 'Custom Dark'. The - custom theme will work with any IDLE release, and can be modified. - -- bpo-25224: README.txt is now an idlelib index for IDLE developers and - curious users. The previous user content is now in the IDLE doc chapter. - 'IDLE' now means 'Integrated Development and Learning Environment'. - -- bpo-24820: Users can now set breakpoint colors in Settings -> Custom - Highlighting. Original patch by Mark Roseman. - -- bpo-24972: Inactive selection background now matches active selection - background, as configured by users, on all systems. Found items are now - always highlighted on Windows. Initial patch by Mark Roseman. - -- bpo-24570: Idle: make calltip and completion boxes appear on Macs affected - by a tk regression. Initial patch by Mark Roseman. - -- bpo-24988: Idle ScrolledList context menus (used in debugger) now work on - Mac Aqua. Patch by Mark Roseman. - -- bpo-24801: Make right-click for context menu work on Mac Aqua. Patch by - Mark Roseman. - -- bpo-25173: Associate tkinter messageboxes with a specific widget. For Mac - OSX, make them a 'sheet'. Patch by Mark Roseman. - -- bpo-25198: Enhance the initial html viewer now used for Idle Help. - Properly indent fixed-pitch text (patch by Mark Roseman). Give code - snippet a very Sphinx-like light blueish-gray background. Re-use initial - width and height set by users for shell and editor. When the Table of - Contents (TOC) menu is used, put the section header at the top of the - screen. - -- bpo-25225: Condense and rewrite Idle doc section on text colors. - -- bpo-21995: Explain some differences between IDLE and console Python. - -- bpo-22820: Explain need for *print* when running file from Idle editor. - -- bpo-25224: Doc: augment Idle feature list and no-subprocess section. - -- bpo-25219: Update doc for Idle command line options. Some were missing and - notes were not correct. - -- bpo-24861: Most of idlelib is private and subject to change. Use - idleib.idle.* to start Idle. See idlelib.__init__.__doc__. - -- bpo-25199: Idle: add synchronization comments for future maintainers. - -- bpo-16893: Replace help.txt with help.html for Idle doc display. The new - idlelib/help.html is rstripped Doc/build/html/library/idle.html. It looks - better than help.txt and will better document Idle as released. The - tkinter html viewer that works for this file was written by Mark Roseman. - The now unused EditorWindow.HelpDialog class and helt.txt file are - deprecated. - -- bpo-24199: Deprecate unused idlelib.idlever with possible removal in 3.6. - -- bpo-24790: Remove extraneous code (which also create 2 & 3 conflicts). - -Documentation -------------- - -- bpo-22558: Add remaining doc links to source code for Python-coded - modules. Patch by Yoni Lavi. - -- bpo-12067: Rewrite Comparisons section in the Expressions chapter of the - language reference. Some of the details of comparing mixed types were - incorrect or ambiguous. NotImplemented is only relevant at a lower level - than the Expressions chapter. Added details of comparing range() objects, - and default behaviour and consistency suggestions for user-defined - classes. Patch from Andy Maier. - -- bpo-24952: Clarify the default size argument of stack_size() in the - "threading" and "_thread" modules. Patch from Mattip. - -- bpo-23725: Overhaul tempfile docs. Note deprecated status of mktemp. Patch - from Zbigniew Jędrzejewski-Szmek. - -- bpo-24808: Update the types of some PyTypeObject fields. Patch by Joseph - Weston. - -- bpo-22812: Fix unittest discovery examples. Patch from Pam McA'Nulty. - -Tests ------ - -- bpo-25449: Added tests for OrderedDict subclasses. - -- bpo-25099: Make test_compileall not fail when an entry on sys.path cannot - be written to (commonly seen in administrative installs on Windows). - -- bpo-23919: Prevents assert dialogs appearing in the test suite. - -- ``PCbuild\rt.bat`` now accepts an unlimited number of arguments to pass - along to regrtest.py. Previously there was a limit of 9. - -Build ------ - -- bpo-24915: Add LLVM support for PGO builds and use the test suite to - generate the profile data. Initial patch by Alecsandru Patrascu of Intel. - -- bpo-24910: Windows MSIs now have unique display names. - -- bpo-24986: It is now possible to build Python on Windows without errors - when external libraries are not available. - -Windows -------- - -- bpo-25450: Updates shortcuts to start Python in installation directory. - -- bpo-25164: Changes default all-users install directory to match per-user - directory. - -- bpo-25143: Improves installer error messages for unsupported platforms. - -- bpo-25163: Display correct directory in installer when using non-default - settings. - -- bpo-25361: Disables use of SSE2 instructions in Windows 32-bit build - -- bpo-25089: Adds logging to installer for case where launcher is not - selected on upgrade. - -- bpo-25165: Windows uninstallation should not remove launcher if other - versions remain - -- bpo-25112: py.exe launcher is missing icons - -- bpo-25102: Windows installer does not precompile for -O or -OO. - -- bpo-25081: Makes Back button in installer go back to upgrade page when - upgrading. - -- bpo-25091: Increases font size of the installer. - -- bpo-25126: Clarifies that the non-web installer will download some - components. - -- bpo-25213: Restores requestedExecutionLevel to manifest to disable UAC - virtualization. - -- bpo-25022: Removed very outdated PC/example_nt/ directory. - -Tools/Demos ------------ - -- bpo-25440: Fix output of python-config --extension-suffix. - - -What's New in Python 3.5.0 final? -================================= - -*Release date: 2015-09-13* - -Build ------ - -- bpo-25071: Windows installer should not require TargetDir parameter when - installing quietly. - - -What's New in Python 3.5.0 release candidate 4? -=============================================== - -*Release date: 2015-09-09* - -Library -------- - -- bpo-25029: Fixes MemoryError in test_strptime. - -Build ------ - -- bpo-25027: Reverts partial-static build options and adds vcruntime140.dll - to Windows installation. - - -What's New in Python 3.5.0 release candidate 3? -=============================================== - -*Release date: 2015-09-07* - -Core and Builtins ------------------ - -- bpo-24305: Prevent import subsystem stack frames from being counted by the - warnings.warn(stacklevel=) parameter. - -- bpo-24912: Prevent __class__ assignment to immutable built-in objects. - -- bpo-24975: Fix AST compilation for :pep:`448` syntax. - -Library -------- - -- bpo-24917: time_strftime() buffer over-read. - -- bpo-24748: To resolve a compatibility problem found with py2exe and - pywin32, imp.load_dynamic() once again ignores previously loaded modules - to support Python modules replacing themselves with extension modules. - Patch by Petr Viktorin. - -- bpo-24635: Fixed a bug in typing.py where isinstance([], typing.Iterable) - would return True once, then False on subsequent calls. - -- bpo-24989: Fixed buffer overread in BytesIO.readline() if a position is - set beyond size. Based on patch by John Leitch. - -- bpo-24913: Fix overrun error in deque.index(). Found by John Leitch and - Bryce Darling. - - -What's New in Python 3.5.0 release candidate 2? -=============================================== - -*Release date: 2015-08-25* - -Core and Builtins ------------------ - -- bpo-24769: Interpreter now starts properly when dynamic loading is - disabled. Patch by Petr Viktorin. - -- bpo-21167: NAN operations are now handled correctly when python is - compiled with ICC even if -fp-model strict is not specified. - -- bpo-24492: A "package" lacking a __name__ attribute when trying to perform - a ``from .. import ...`` statement will trigger an ImportError instead of - an AttributeError. - -Library -------- - -- bpo-24847: Removes vcruntime140.dll dependency from Tcl/Tk. - -- bpo-24839: platform._syscmd_ver raises DeprecationWarning - -- bpo-24867: Fix Task.get_stack() for 'async def' coroutines - - -What's New in Python 3.5.0 release candidate 1? -=============================================== - -*Release date: 2015-08-09* - -Core and Builtins ------------------ - -- bpo-24667: Resize odict in all cases that the underlying dict resizes. - -Library -------- - -- bpo-24824: Signatures of codecs.encode() and codecs.decode() now are - compatible with pydoc. - -- bpo-24634: Importing uuid should not try to load libc on Windows - -- bpo-24798: _msvccompiler.py doesn't properly support manifests - -- bpo-4395: Better testing and documentation of binary operators. Patch by - Martin Panter. - -- bpo-23973: Update typing.py from GitHub repo. - -- bpo-23004: mock_open() now reads binary data correctly when the type of - read_data is bytes. Initial patch by Aaron Hill. - -- bpo-23888: Handle fractional time in cookie expiry. Patch by ssh. - -- bpo-23652: Make it possible to compile the select module against the libc - headers from the Linux Standard Base, which do not include some EPOLL - macros. Patch by Matt Frank. - -- bpo-22932: Fix timezones in email.utils.formatdate. Patch from Dmitry - Shachnev. - -- bpo-23779: imaplib raises TypeError if authenticator tries to abort. Patch - from Craig Holmquist. - -- bpo-23319: Fix ctypes.BigEndianStructure, swap correctly bytes. Patch - written by Matthieu Gautier. - -- bpo-23254: Document how to close the TCPServer listening socket. Patch - from Martin Panter. - -- bpo-19450: Update Windows and OS X installer builds to use SQLite 3.8.11. - -- bpo-17527: Add PATCH to wsgiref.validator. Patch from Luca Sbardella. - -- bpo-24791: Fix grammar regression for call syntax: 'g(\*a or b)'. - -IDLE ----- - -- bpo-23672: Allow Idle to edit and run files with astral chars in name. - Patch by Mohd Sanad Zaki Rizvi. - -- bpo-24745: Idle editor default font. Switch from Courier to - platform-sensitive TkFixedFont. This should not affect current customized - font selections. If there is a problem, edit - $HOME/.idlerc/config-main.cfg and remove 'fontxxx' entries from [Editor - Window]. Patch by Mark Roseman. - -- bpo-21192: Idle editor. When a file is run, put its name in the restart - bar. Do not print false prompts. Original patch by Adnan Umer. - -- bpo-13884: Idle menus. Remove tearoff lines. Patch by Roger Serwy. - -Documentation -------------- - -- bpo-24129: Clarify the reference documentation for name resolution. This - includes removing the assumption that readers will be familiar with the - name resolution scheme Python used prior to the introduction of lexical - scoping for function namespaces. Patch by Ivan Levkivskyi. - -- bpo-20769: Improve reload() docs. Patch by Dorian Pula. - -- bpo-23589: Remove duplicate sentence from the FAQ. Patch by Yongzhi Pan. - -- bpo-24729: Correct IO tutorial to match implementation regarding encoding - parameter to open function. - -Tests ------ - -- bpo-24751: When running regrtest with the ``-w`` command line option, a - test run is no longer marked as a failure if all tests succeed when - re-run. - - -What's New in Python 3.5.0 beta 4? -================================== - -*Release date: 2015-07-26* - -Core and Builtins ------------------ - -- bpo-23573: Restored optimization of bytes.rfind() and bytearray.rfind() - for single-byte argument on Linux. - -- bpo-24569: Make :pep:`448` dictionary evaluation more consistent. - -- bpo-24583: Fix crash when set is mutated while being updated. - -- bpo-24407: Fix crash when dict is mutated while being updated. - -- bpo-24619: New approach for tokenizing async/await. As a consequence, it - is now possible to have one-line 'async def foo(): await ..' functions. - -- bpo-24687: Plug refleak on SyntaxError in function parameters annotations. - -- bpo-15944: memoryview: Allow arbitrary formats when casting to bytes. - Patch by Martin Panter. - -Library -------- - -- bpo-23441: rcompleter now prints a tab character instead of displaying - possible completions for an empty word. Initial patch by Martin Sekera. - -- bpo-24683: Fixed crashes in _json functions called with arguments of - inappropriate type. - -- bpo-21697: shutil.copytree() now correctly handles symbolic links that - point to directories. Patch by Eduardo Seabra and Thomas Kluyver. - -- bpo-14373: Fixed segmentation fault when gc.collect() is called during - constructing lru_cache (C implementation). - -- bpo-24695: Fix a regression in traceback.print_exception(). If - exc_traceback is None we shouldn't print a traceback header like described - in the documentation. - -- bpo-24620: Random.setstate() now validates the value of state last - element. - -- bpo-22485: Fixed an issue that caused `inspect.getsource` to return - incorrect results on nested functions. - -- bpo-22153: Improve unittest docs. Patch from Martin Panter and evilzero. - -- bpo-24580: Symbolic group references to open group in re patterns now are - explicitly forbidden as well as numeric group references. - -- bpo-24206: Fixed __eq__ and __ne__ methods of inspect classes. - -- bpo-24631: Fixed regression in the timeit module with multiline setup. - -- bpo-18622: unittest.mock.mock_open().reset_mock would recurse infinitely. - Patch from Nicola Palumbo and Laurent De Buyst. - -- bpo-23661: unittest.mock side_effects can now be exceptions again. This - was a regression vs Python 3.4. Patch from Ignacio Rossi - -- bpo-24608: chunk.Chunk.read() now always returns bytes, not str. - -- bpo-18684: Fixed reading out of the buffer in the re module. - -- bpo-24259: tarfile now raises a ReadError if an archive is truncated - inside a data segment. - -- bpo-15014: SMTP.auth() and SMTP.login() now support RFC 4954's optional - initial-response argument to the SMTP AUTH command. - -- bpo-24669: Fix inspect.getsource() for 'async def' functions. Patch by Kai - Groner. - -- bpo-24688: ast.get_docstring() for 'async def' functions. - -Build ------ - -- bpo-24603: Update Windows builds and OS X 10.5 installer to use OpenSSL - 1.0.2d. - - -What's New in Python 3.5.0 beta 3? -================================== - -*Release date: 2015-07-05* - -Core and Builtins ------------------ - -- bpo-24467: Fixed possible buffer over-read in bytearray. The bytearray - object now always allocates place for trailing null byte and it's buffer - now is always null-terminated. - -- Upgrade to Unicode 8.0.0. - -- bpo-24345: Add Py_tp_finalize slot for the stable ABI. - -- bpo-24400: Introduce a distinct type for :pep:`492` coroutines; add - types.CoroutineType, inspect.getcoroutinestate, - inspect.getcoroutinelocals; coroutines no longer use CO_GENERATOR flag; - sys.set_coroutine_wrapper works only for 'async def' coroutines; - inspect.iscoroutine no longer uses collections.abc.Coroutine, it's - intended to test for pure 'async def' coroutines only; add new opcode: - GET_YIELD_FROM_ITER; fix generators wrapper used in types.coroutine to be - instance of collections.abc.Generator; collections.abc.Awaitable and - collections.abc.Coroutine can no longer be used to detect generator-based - coroutines--use inspect.isawaitable instead. - -- bpo-24450: Add gi_yieldfrom to generators and cr_await to coroutines. - Contributed by Benno Leslie and Yury Selivanov. - -- bpo-19235: Add new RecursionError exception. Patch by Georg Brandl. - -Library -------- - -- bpo-21750: mock_open.read_data can now be read from each instance, as it - could in Python 3.3. - -- bpo-24552: Fix use after free in an error case of the _pickle module. - -- bpo-24514: tarfile now tolerates number fields consisting of only - whitespace. - -- bpo-19176: Fixed doctype() related bugs in C implementation of - ElementTree. A deprecation warning no longer issued by XMLParser subclass - with default doctype() method. Direct call of doctype() now issues a - warning. Parser's doctype() now is not called if target's doctype() is - called. Based on patch by Martin Panter. - -- bpo-20387: Restore semantic round-trip correctness in tokenize/untokenize - for tab-indented blocks. - -- bpo-24456: Fixed possible buffer over-read in adpcm2lin() and lin2adpcm() - functions of the audioop module. - -- bpo-24336: The contextmanager decorator now works with functions with - keyword arguments called "func" and "self". Patch by Martin Panter. - -- bpo-24522: Fix possible integer overflow in json accelerator module. - -- bpo-24489: ensure a previously set C errno doesn't disturb cmath.polar(). - -- bpo-24408: Fixed AttributeError in measure() and metrics() methods of - tkinter.Font. - -- bpo-14373: C implementation of functools.lru_cache() now can be used with - methods. - -- bpo-24347: Set KeyError if PyDict_GetItemWithError returns NULL. - -- bpo-24348: Drop superfluous incref/decref. - -- bpo-24359: Check for changed OrderedDict size during iteration. - -- bpo-24368: Support keyword arguments in OrderedDict methods. - -- bpo-24362: Simplify the C OrderedDict fast nodes resize logic. - -- bpo-24377: Fix a ref leak in OrderedDict.__repr__. - -- bpo-24369: Defend against key-changes during iteration. - -Tests ------ - -- bpo-24373: _testmultiphase and xxlimited now use tp_traverse and - tp_finalize to avoid reference leaks encountered when combining tp_dealloc - with PyType_FromSpec (see issue #16690 for details) - -Documentation -------------- - -- bpo-24458: Update documentation to cover multi-phase initialization for - extension modules (PEP 489). Patch by Petr Viktorin. - -- bpo-24351: Clarify what is meant by "identifier" in the context of - string.Template instances. - -Build ------ - -- bpo-24432: Update Windows builds and OS X 10.5 installer to use OpenSSL - 1.0.2c. - - -What's New in Python 3.5.0 beta 2? -================================== - -*Release date: 2015-05-31* - -Core and Builtins ------------------ - -- bpo-24284: The startswith and endswith methods of the str class no longer - return True when finding the empty string and the indexes are completely - out of range. - -- bpo-24115: Update uses of PyObject_IsTrue(), PyObject_Not(), - PyObject_IsInstance(), PyObject_RichCompareBool() and _PyDict_Contains() - to check for and handle errors correctly. - -- bpo-24328: Fix importing one character extension modules. - -- bpo-11205: In dictionary displays, evaluate the key before the value. - -- bpo-24285: Fixed regression that prevented importing extension modules - from inside packages. Patch by Petr Viktorin. - -Library -------- - -- bpo-23247: Fix a crash in the StreamWriter.reset() of CJK codecs. - -- bpo-24270: Add math.isclose() and cmath.isclose() functions as per - :pep:`485`. Contributed by Chris Barker and Tal Einat. - -- bpo-5633: Fixed timeit when the statement is a string and the setup is - not. - -- bpo-24326: Fixed audioop.ratecv() with non-default weightB argument. - Original patch by David Moore. - -- bpo-16991: Add a C implementation of OrderedDict. - -- bpo-23934: Fix inspect.signature to fail correctly for builtin types - lacking signature information. Initial patch by James Powell. - - -What's New in Python 3.5.0 beta 1? -================================== - -*Release date: 2015-05-24* - -Core and Builtins ------------------ - -- bpo-24276: Fixed optimization of property descriptor getter. - -- bpo-24268: PEP 489: Multi-phase extension module initialization. Patch by - Petr Viktorin. - -- bpo-23955: Add pyvenv.cfg option to suppress registry/environment lookup - for generating sys.path on Windows. - -- bpo-24257: Fixed system error in the comparison of faked - types.SimpleNamespace. - -- bpo-22939: Fixed integer overflow in iterator object. Patch by Clement - Rouault. - -- bpo-23985: Fix a possible buffer overrun when deleting a slice from the - front of a bytearray and then appending some other bytes data. - -- bpo-24102: Fixed exception type checking in standard error handlers. - -- bpo-15027: The UTF-32 encoder is now 3x to 7x faster. - -- bpo-23290: Optimize set_merge() for cases where the target is empty. - (Contributed by Serhiy Storchaka.) - -- bpo-2292: PEP 448: Additional Unpacking Generalizations. - -- bpo-24096: Make warnings.warn_explicit more robust against mutation of the - warnings.filters list. - -- bpo-23996: Avoid a crash when a delegated generator raises an unnormalized - StopIteration exception. Patch by Stefan Behnel. - -- bpo-23910: Optimize property() getter calls. Patch by Joe Jevnik. - -- bpo-23911: Move path-based importlib bootstrap code to a separate frozen - module. - -- bpo-24192: Fix namespace package imports. - -- bpo-24022: Fix tokenizer crash when processing undecodable source code. - -- bpo-9951: Added a hex() method to bytes, bytearray, and memoryview. - -- bpo-22906: PEP 479: Change StopIteration handling inside generators. - -- bpo-24017: PEP 492: Coroutines with async and await syntax. - -Library -------- - -- bpo-14373: Added C implementation of functools.lru_cache(). Based on - patches by Matt Joiner and Alexey Kachayev. - -- bpo-24230: The tempfile module now accepts bytes for prefix, suffix and - dir parameters and returns bytes in such situations (matching the os - module APIs). - -- bpo-22189: collections.UserString now supports __getnewargs__(), - __rmod__(), casefold(), format_map(), isprintable(), and maketrans(). - Patch by Joe Jevnik. - -- bpo-24244: Prevents termination when an invalid format string is - encountered on Windows in strftime. - -- bpo-23973: PEP 484: Add the typing module. - -- bpo-23086: The collections.abc.Sequence() abstract base class added - *start* and *stop* parameters to the index() mixin. Patch by Devin - Jeanpierre. - -- bpo-20035: Replaced the ``tkinter._fix`` module used for setting up the - Tcl/Tk environment on Windows with a private function in the ``_tkinter`` - module that makes no permanent changes to the environment. - -- bpo-24257: Fixed segmentation fault in sqlite3.Row constructor with faked - cursor type. - -- bpo-15836: assertRaises(), assertRaisesRegex(), assertWarns() and - assertWarnsRegex() assertments now check the type of the first argument to - prevent possible user error. Based on patch by Daniel Wagner-Hall. - -- bpo-9858: Add missing method stubs to _io.RawIOBase. Patch by Laura - Rupprecht. - -- bpo-22955: attrgetter, itemgetter and methodcaller objects in the operator - module now support pickling. Added readable and evaluable repr for these - objects. Based on patch by Josh Rosenberg. - -- bpo-22107: tempfile.gettempdir() and tempfile.mkdtemp() now try again when - a directory with the chosen name already exists on Windows as well as on - Unix. tempfile.mkstemp() now fails early if parent directory is not valid - (not exists or is a file) on Windows. - -- bpo-23780: Improved error message in os.path.join() with single argument. - -- bpo-6598: Increased time precision and random number range in - email.utils.make_msgid() to strengthen the uniqueness of the message ID. - -- bpo-24091: Fixed various crashes in corner cases in C implementation of - ElementTree. - -- bpo-21931: msilib.FCICreate() now raises TypeError in the case of a bad - argument instead of a ValueError with a bogus FCI error number. Patch by - Jeffrey Armstrong. - -- bpo-13866: *quote_via* argument added to urllib.parse.urlencode. - -- bpo-20098: New mangle_from policy option for email, default True for - compat32, but False for all other policies. - -- bpo-24211: The email library now supports RFC 6532: it can generate - headers using utf-8 instead of encoded words. - -- bpo-16314: Added support for the LZMA compression in distutils. - -- bpo-21804: poplib now supports RFC 6856 (UTF8). - -- bpo-18682: Optimized pprint functions for builtin scalar types. - -- bpo-22027: smtplib now supports RFC 6531 (SMTPUTF8). - -- bpo-23488: Random generator objects now consume 2x less memory on 64-bit. - -- bpo-1322: platform.dist() and platform.linux_distribution() functions are - now deprecated. Initial patch by Vajrasky Kok. - -- bpo-22486: Added the math.gcd() function. The fractions.gcd() function - now is deprecated. Based on patch by Mark Dickinson. - -- bpo-24064: Property() docstrings are now writeable. (Patch by Berker - Peksag.) - -- bpo-22681: Added support for the koi8_t encoding. - -- bpo-22682: Added support for the kz1048 encoding. - -- bpo-23796: peek and read1 methods of BufferedReader now raise ValueError - if they called on a closed object. Patch by John Hergenroeder. - -- bpo-21795: smtpd now supports the 8BITMIME extension whenever the new - *decode_data* constructor argument is set to False. - -- bpo-24155: optimize heapq.heapify() for better cache performance when - heapifying large lists. - -- bpo-21800: imaplib now supports RFC 5161 (enable), RFC 6855 - (utf8/internationalized email) and automatically encodes non-ASCII - usernames and passwords to UTF8. - -- bpo-20274: When calling a _sqlite.Connection, it now complains if passed - any keyword arguments. Previously it silently ignored them. - -- bpo-20274: Remove ignored and erroneous "kwargs" parameters from three - METH_VARARGS methods on _sqlite.Connection. - -- bpo-24134: assertRaises(), assertRaisesRegex(), assertWarns() and - assertWarnsRegex() checks now emits a deprecation warning when callable is - None or keyword arguments except msg is passed in the context manager - mode. - -- bpo-24018: Add a collections.abc.Generator abstract base class. - Contributed by Stefan Behnel. - -- bpo-23880: Tkinter's getint() and getdouble() now support Tcl_Obj. - Tkinter's getdouble() now supports any numbers (in particular int). - -- bpo-22619: Added negative limit support in the traceback module. Based on - patch by Dmitry Kazakov. - -- bpo-24094: Fix possible crash in json.encode with poorly behaved dict - subclasses. - -- bpo-9246: On POSIX, os.getcwd() now supports paths longer than 1025 bytes. - Patch written by William Orr. - -- bpo-17445: add difflib.diff_bytes() to support comparison of byte strings - (fixes a regression from Python 2). - -- bpo-23917: Fall back to sequential compilation when ProcessPoolExecutor - doesn't exist. Patch by Claudiu Popa. - -- bpo-23008: Fixed resolving attributes with boolean value is False in - pydoc. - -- Fix asyncio issue 235: LifoQueue and PriorityQueue's put didn't increment - unfinished tasks (this bug was introduced when JoinableQueue was merged - with Queue). - -- bpo-23908: os functions now reject paths with embedded null character on - Windows instead of silently truncating them. - -- bpo-23728: binascii.crc_hqx() could return an integer outside of the range - 0-0xffff for empty data. - -- bpo-23887: urllib.error.HTTPError now has a proper repr() representation. - Patch by Berker Peksag. - -- asyncio: New event loop APIs: set_task_factory() and get_task_factory(). - -- asyncio: async() function is deprecated in favour of ensure_future(). - -- bpo-24178: asyncio.Lock, Condition, Semaphore, and BoundedSemaphore - support new 'async with' syntax. Contributed by Yury Selivanov. - -- bpo-24179: Support 'async for' for asyncio.StreamReader. Contributed by - Yury Selivanov. - -- bpo-24184: Add AsyncIterator and AsyncIterable ABCs to collections.abc. - Contributed by Yury Selivanov. - -- bpo-22547: Implement informative __repr__ for inspect.BoundArguments. - Contributed by Yury Selivanov. - -- bpo-24190: Implement inspect.BoundArgument.apply_defaults() method. - Contributed by Yury Selivanov. - -- bpo-20691: Add 'follow_wrapped' argument to - inspect.Signature.from_callable() and inspect.signature(). Contributed by - Yury Selivanov. - -- bpo-24248: Deprecate inspect.Signature.from_function() and - inspect.Signature.from_builtin(). - -- bpo-23898: Fix inspect.classify_class_attrs() to support attributes with - overloaded __eq__ and __bool__. Patch by Mike Bayer. - -- bpo-24298: Fix inspect.signature() to correctly unwrap wrappers around - bound methods. - -IDLE ----- - -- bpo-23184: remove unused names and imports in idlelib. Initial patch by Al - Sweigart. - -Tests ------ - -- bpo-21520: test_zipfile no longer fails if the word 'bad' appears anywhere - in the name of the current directory. - -- bpo-9517: Move script_helper into the support package. Patch by Christie - Wilson. - -Documentation -------------- - -- bpo-22155: Add File Handlers subsection with createfilehandler to tkinter - doc. Remove obsolete example from FAQ. Patch by Martin Panter. - -- bpo-24029: Document the name binding behavior for submodule imports. - -- bpo-24077: Fix typo in man page for -I command option: -s, not -S - -Tools/Demos ------------ - -- bpo-24000: Improved Argument Clinic's mapping of converters to legacy - "format units". Updated the documentation to match. - -- bpo-24001: Argument Clinic converters now use accept={type} instead of - types={'type'} to specify the types the converter accepts. - -- bpo-23330: h2py now supports arbitrary filenames in #include. - -- bpo-24031: make patchcheck now supports git checkouts, too. - - -What's New in Python 3.5.0 alpha 4? -=================================== - -*Release date: 2015-04-19* - -Core and Builtins ------------------ - -- bpo-22980: Under Linux, GNU/KFreeBSD and the Hurd, C extensions now - include the architecture triplet in the extension name, to make it easy to - test builds for different ABIs in the same working tree. Under OS X, the - extension name now includes :pep:`3149`-style information. - -- bpo-22631: Added Linux-specific socket constant CAN_RAW_FD_FRAMES. Patch - courtesy of Joe Jevnik. - -- bpo-23731: Implement :pep:`488`: removal of .pyo files. - -- bpo-23726: Don't enable GC for user subclasses of non-GC types that don't - add any new fields. Patch by Eugene Toder. - -- bpo-23309: Avoid a deadlock at shutdown if a daemon thread is aborted - while it is holding a lock to a buffered I/O object, and the main thread - tries to use the same I/O object (typically stdout or stderr). A fatal - error is emitted instead. - -- bpo-22977: Fixed formatting Windows error messages on Wine. Patch by - Martin Panter. - -- bpo-23466: %c, %o, %x, and %X in bytes formatting now raise TypeError on - non-integer input. - -- bpo-24044: Fix possible null pointer dereference in list.sort in out of - memory conditions. - -- bpo-21354: PyCFunction_New function is exposed by python DLL again. - -Library -------- - -- bpo-23840: tokenize.open() now closes the temporary binary file on error - to fix a resource warning. - -- bpo-16914: new debuglevel 2 in smtplib adds timestamps to debug output. - -- bpo-7159: urllib.request now supports sending auth credentials - automatically after the first 401. This enhancement is a superset of the - enhancement from issue #19494 and supersedes that change. - -- bpo-23703: Fix a regression in urljoin() introduced in 901e4e52b20a. Patch - by Demian Brecht. - -- bpo-4254: Adds _curses.update_lines_cols(). Patch by Arnon Yaari - -- bpo-19933: Provide default argument for ndigits in round. Patch by - Vajrasky Kok. - -- bpo-23193: Add a numeric_owner parameter to tarfile.TarFile.extract and - tarfile.TarFile.extractall. Patch by Michael Vogt and Eric Smith. - -- bpo-23342: Add a subprocess.run() function than returns a CalledProcess - instance for a more consistent API than the existing call* functions. - -- bpo-21217: inspect.getsourcelines() now tries to compute the start and end - lines from the code object, fixing an issue when a lambda function is used - as decorator argument. Patch by Thomas Ballinger and Allison Kaptur. - -- bpo-24521: Fix possible integer overflows in the pickle module. - -- bpo-22931: Allow '[' and ']' in cookie values. - -- The keywords attribute of functools.partial is now always a dictionary. - -- bpo-23811: Add missing newline to the PyCompileError error message. Patch - by Alex Shkop. - -- bpo-21116: Avoid blowing memory when allocating a multiprocessing shared - array that's larger than 50% of the available RAM. Patch by Médéric - Boquien. - -- bpo-22982: Improve BOM handling when seeking to multiple positions of a - writable text file. - -- bpo-23464: Removed deprecated asyncio JoinableQueue. - -- bpo-23529: Limit the size of decompressed data when reading from GzipFile, - BZ2File or LZMAFile. This defeats denial of service attacks using - compressed bombs (i.e. compressed payloads which decompress to a huge - size). Patch by Martin Panter and Nikolaus Rath. - -- bpo-21859: Added Python implementation of io.FileIO. - -- bpo-23865: close() methods in multiple modules now are idempotent and more - robust at shutdown. If they need to release multiple resources, all are - released even if errors occur. - -- bpo-23400: Raise same exception on both Python 2 and 3 if sem_open is not - available. Patch by Davin Potts. - -- bpo-10838: The subprocess now module includes SubprocessError and - TimeoutError in its list of exported names for the users wild enough to - use ``from subprocess import *``. - -- bpo-23411: Added DefragResult, ParseResult, SplitResult, - DefragResultBytes, ParseResultBytes, and SplitResultBytes to - urllib.parse.__all__. Patch by Martin Panter. - -- bpo-23881: urllib.request.ftpwrapper constructor now closes the socket if - the FTP connection failed to fix a ResourceWarning. - -- bpo-23853: :meth:`socket.socket.sendall` does no more reset the socket - timeout each time data is sent successfully. The socket timeout is now the - maximum total duration to send all data. - -- bpo-22721: An order of multiline pprint output of set or dict containing - orderable and non-orderable elements no longer depends on iteration order - of set or dict. - -- bpo-15133: _tkinter.tkapp.getboolean() now supports Tcl_Obj and always - returns bool. tkinter.BooleanVar now validates input values (accepted - bool, int, str, and Tcl_Obj). tkinter.BooleanVar.get() now always returns - bool. - -- bpo-10590: xml.sax.parseString() now supports string argument. - -- bpo-23338: Fixed formatting ctypes error messages on Cygwin. Patch by - Makoto Kato. - -- bpo-15582: inspect.getdoc() now follows inheritance chains. - -- bpo-2175: SAX parsers now support a character stream of InputSource - object. - -- bpo-16840: Tkinter now supports 64-bit integers added in Tcl 8.4 and - arbitrary precision integers added in Tcl 8.5. - -- bpo-23834: Fix socket.sendto(), use the C Py_ssize_t type to store the - result of sendto() instead of the C int type. - -- bpo-23618: :meth:`socket.socket.connect` now waits until the connection - completes instead of raising :exc:`InterruptedError` if the connection is - interrupted by signals, signal handlers don't raise an exception and the - socket is blocking or has a timeout. :meth:`socket.socket.connect` still - raise :exc:`InterruptedError` for non-blocking sockets. - -- bpo-21526: Tkinter now supports new boolean type in Tcl 8.5. - -- bpo-23836: Fix the faulthandler module to handle reentrant calls to its - signal handlers. - -- bpo-23838: linecache now clears the cache and returns an empty result on - MemoryError. - -- bpo-10395: Added os.path.commonpath(). Implemented in posixpath and - ntpath. Based on patch by Rafik Draoui. - -- bpo-23611: Serializing more "lookupable" objects (such as unbound methods - or nested classes) now are supported with pickle protocols < 4. - -- bpo-13583: sqlite3.Row now supports slice indexing. - -- bpo-18473: Fixed 2to3 and 3to2 compatible pickle mappings. Fixed - ambiguous reverse mappings. Added many new mappings. Import mapping is - no longer applied to modules already mapped with full name mapping. - -- bpo-23485: select.select() is now retried automatically with the - recomputed timeout when interrupted by a signal, except if the signal - handler raises an exception. This change is part of the :pep:`475`. - -- bpo-23752: When built from an existing file descriptor, io.FileIO() now - only calls fstat() once. Before fstat() was called twice, which was not - necessary. - -- bpo-23704: collections.deque() objects now support __add__, __mul__, and - __imul__(). - -- bpo-23171: csv.Writer.writerow() now supports arbitrary iterables. - -- bpo-23745: The new email header parser now handles duplicate MIME - parameter names without error, similar to how get_param behaves. - -- bpo-22117: Fix os.utime(), it now rounds the timestamp towards minus - infinity (-inf) instead of rounding towards zero. - -- bpo-23310: Fix MagicMock's initializer to work with __methods__, just like - configure_mock(). Patch by Kasia Jachim. - -Build ------ - -- bpo-23817: FreeBSD now uses "1.0" in the SOVERSION as other operating - systems, instead of just "1". - -- bpo-23501: Argument Clinic now generates code into separate files by - default. - -Tests ------ - -- bpo-23799: Added test.support.start_threads() for running and cleaning up - multiple threads. - -- bpo-22390: test.regrtest now emits a warning if temporary files or - directories are left after running a test. - -Tools/Demos ------------ - -- bpo-18128: pygettext now uses standard +NNNN format in the - POT-Creation-Date header. - -- bpo-23935: Argument Clinic's understanding of format units accepting - bytes, bytearrays, and buffers is now consistent with both the - documentation and the implementation. - -- bpo-23944: Argument Clinic now wraps long impl prototypes at column 78. - -- bpo-20586: Argument Clinic now ensures that functions without docstrings - have signatures. - -- bpo-23492: Argument Clinic now generates argument parsing code with - PyArg_Parse instead of PyArg_ParseTuple if possible. - -- bpo-23500: Argument Clinic is now smarter about generating the "#ifndef" - (empty) definition of the methoddef macro: it's only generated once, even - if Argument Clinic processes the same symbol multiple times, and it's - emitted at the end of all processing rather than immediately after the - first use. - -C API ------ - -- bpo-23998: PyImport_ReInitLock() now checks for lock allocation error - - -What's New in Python 3.5.0 alpha 3? -=================================== - -*Release date: 2015-03-28* - -Core and Builtins ------------------ - -- bpo-23573: Increased performance of string search operations (str.find, - str.index, str.count, the in operator, str.split, str.partition) with - arguments of different kinds (UCS1, UCS2, UCS4). - -- bpo-23753: Python doesn't support anymore platforms without stat() or - fstat(), these functions are always required. - -- bpo-23681: The -b option now affects comparisons of bytes with int. - -- bpo-23632: Memoryviews now allow tuple indexing (including for - multi-dimensional memoryviews). - -- bpo-23192: Fixed generator lambdas. Patch by Bruno Cauet. - -- bpo-23629: Fix the default __sizeof__ implementation for variable-sized - objects. - -Library -------- - -- bpo-14260: The groupindex attribute of regular expression pattern object - now is non-modifiable mapping. - -- bpo-23792: Ignore KeyboardInterrupt when the pydoc pager is active. This - mimics the behavior of the standard unix pagers, and prevents pipepager - from shutting down while the pager itself is still running. - -- bpo-23775: pprint() of OrderedDict now outputs the same representation as - repr(). - -- bpo-23765: Removed IsBadStringPtr calls in ctypes - -- bpo-22364: Improved some re error messages using regex for hints. - -- bpo-23742: ntpath.expandvars() no longer loses unbalanced single quotes. - -- bpo-21717: The zipfile.ZipFile.open function now supports 'x' (exclusive - creation) mode. - -- bpo-21802: The reader in BufferedRWPair now is closed even when closing - writer failed in BufferedRWPair.close(). - -- bpo-23622: Unknown escapes in regular expressions that consist of ``'\'`` - and ASCII letter now raise a deprecation warning and will be forbidden in - Python 3.6. - -- bpo-23671: string.Template now allows specifying the "self" parameter as a - keyword argument. string.Formatter now allows specifying the "self" and - the "format_string" parameters as keyword arguments. - -- bpo-23502: The pprint module now supports mapping proxies. - -- bpo-17530: pprint now wraps long bytes objects and bytearrays. - -- bpo-22687: Fixed some corner cases in breaking words in tetxtwrap. Got rid - of quadratic complexity in breaking long words. - -- bpo-4727: The copy module now uses pickle protocol 4 (PEP 3154) and - supports copying of instances of classes whose __new__ method takes - keyword-only arguments. - -- bpo-23491: Added a zipapp module to support creating executable zip file - archives of Python code. Registered ".pyz" and ".pyzw" extensions on - Windows for these archives (PEP 441). - -- bpo-23657: Avoid explicit checks for str in zipapp, adding support for - pathlib.Path objects as arguments. - -- bpo-23688: Added support of arbitrary bytes-like objects and avoided - unnecessary copying of memoryview in gzip.GzipFile.write(). Original patch - by Wolfgang Maier. - -- bpo-23252: Added support for writing ZIP files to unseekable streams. - -- bpo-23647: Increase imaplib's MAXLINE to accommodate modern mailbox sizes. - -- bpo-23539: If body is None, http.client.HTTPConnection.request now sets - Content-Length to 0 for PUT, POST, and PATCH headers to avoid 411 errors - from some web servers. - -- bpo-22351: The nntplib.NNTP constructor no longer leaves the connection - and socket open until the garbage collector cleans them up. Patch by - Martin Panter. - -- bpo-23704: collections.deque() objects now support methods for index(), - insert(), and copy(). This allows deques to be registered as a - MutableSequence and it improves their substitutability for lists. - -- bpo-23715: :func:`signal.sigwaitinfo` and :func:`signal.sigtimedwait` are - now retried when interrupted by a signal not in the *sigset* parameter, if - the signal handler does not raise an exception. signal.sigtimedwait() - recomputes the timeout with a monotonic clock when it is retried. - -- bpo-23001: Few functions in modules mmap, ossaudiodev, socket, ssl, and - codecs, that accepted only read-only bytes-like object now accept writable - bytes-like object too. - -- bpo-23646: If time.sleep() is interrupted by a signal, the sleep is now - retried with the recomputed delay, except if the signal handler raises an - exception (PEP 475). - -- bpo-23136: _strptime now uniformly handles all days in week 0, including - Dec 30 of previous year. Based on patch by Jim Carroll. - -- bpo-23700: Iterator of NamedTemporaryFile now keeps a reference to - NamedTemporaryFile instance. Patch by Bohuslav Kabrda. - -- bpo-22903: The fake test case created by unittest.loader when it fails - importing a test module is now picklable. - -- bpo-22181: On Linux, os.urandom() now uses the new getrandom() syscall if - available, syscall introduced in the Linux kernel 3.17. It is more - reliable and more secure, because it avoids the need of a file descriptor - and waits until the kernel has enough entropy. - -- bpo-2211: Updated the implementation of the http.cookies.Morsel class. - Setting attributes key, value and coded_value directly now is deprecated. - update() and setdefault() now transform and check keys. Comparing for - equality now takes into account attributes key, value and coded_value. - copy() now returns a Morsel, not a dict. repr() now contains all - attributes. Optimized checking keys and quoting values. Added new tests. - Original patch by Demian Brecht. - -- bpo-18983: Allow selection of output units in timeit. Patch by Julian - Gindi. - -- bpo-23631: Fix traceback.format_list when a traceback has been mutated. - -- bpo-23568: Add rdivmod support to MagicMock() objects. Patch by Håkan - Lövdahl. - -- bpo-2052: Add charset parameter to HtmlDiff.make_file(). - -- bpo-23668: Support os.truncate and os.ftruncate on Windows. - -- bpo-23138: Fixed parsing cookies with absent keys or values in cookiejar. - Patch by Demian Brecht. - -- bpo-23051: multiprocessing.Pool methods imap() and imap_unordered() now - handle exceptions raised by an iterator. Patch by Alon Diamant and Davin - Potts. - -- bpo-23581: Add matmul support to MagicMock. Patch by Håkan Lövdahl. - -- bpo-23566: enable(), register(), dump_traceback() and - dump_traceback_later() functions of faulthandler now accept file - descriptors. Patch by Wei Wu. - -- bpo-22928: Disabled HTTP header injections in http.client. Original patch - by Demian Brecht. - -- bpo-23615: Modules bz2, tarfile and tokenize now can be reloaded with - imp.reload(). Patch by Thomas Kluyver. - -- bpo-23605: os.walk() now calls os.scandir() instead of os.listdir(). The - usage of os.scandir() reduces the number of calls to os.stat(). Initial - patch written by Ben Hoyt. - -Build ------ - -- bpo-23585: make patchcheck will ensure the interpreter is built. - -Tests ------ - -- bpo-23583: Added tests for standard IO streams in IDLE. - -- bpo-22289: Prevent test_urllib2net failures due to ftp connection timeout. - -Tools/Demos ------------ - -- bpo-22826: The result of open() in Tools/freeze/bkfile.py is now better - compatible with regular files (in particular it now supports the context - management protocol). - - -What's New in Python 3.5.0 alpha 2? -=================================== - -*Release date: 2015-03-09* - -Core and Builtins ------------------ - -- bpo-23571: PyObject_Call() and PyCFunction_Call() now raise a SystemError - if a function returns a result and raises an exception. The SystemError is - chained to the previous exception. - -Library -------- - -- bpo-22524: New os.scandir() function, part of the :pep:`471`: - "os.scandir() function -- a better and faster directory iterator". Patch - written by Ben Hoyt. - -- bpo-23103: Reduced the memory consumption of IPv4Address and IPv6Address. - -- bpo-21793: BaseHTTPRequestHandler again logs response code as numeric, not - as stringified enum. Patch by Demian Brecht. - -- bpo-23476: In the ssl module, enable OpenSSL's X509_V_FLAG_TRUSTED_FIRST - flag on certificate stores when it is available. - -- bpo-23576: Avoid stalling in SSL reads when EOF has been reached in the - SSL layer but the underlying connection hasn't been closed. - -- bpo-23504: Added an __all__ to the types module. - -- bpo-23563: Optimized utility functions in urllib.parse. - -- bpo-7830: Flatten nested functools.partial. - -- bpo-20204: Added the __module__ attribute to _tkinter classes. - -- bpo-19980: Improved help() for non-recognized strings. help('') now shows - the help on str. help('help') now shows the help on help(). Original - patch by Mark Lawrence. - -- bpo-23521: Corrected pure python implementation of timedelta division. - Eliminated OverflowError from ``timedelta * float`` for some floats; - Corrected rounding in timedelta true division. - -- bpo-21619: Popen objects no longer leave a zombie after exit in the with - statement if the pipe was broken. Patch by Martin Panter. - -- bpo-22936: Make it possible to show local variables in tracebacks for both - the traceback module and unittest. - -- bpo-15955: Add an option to limit the output size in bz2.decompress(). - Patch by Nikolaus Rath. - -- bpo-6639: Module-level turtle functions no longer raise TclError after - closing the window. - -- bpo-814253: Group references and conditional group references now work in - lookbehind assertions in regular expressions. (See also: bpo-9179) - -- bpo-23215: Multibyte codecs with custom error handlers that ignores errors - consumed too much memory and raised SystemError or MemoryError. Original - patch by Aleksi Torhamo. - -- bpo-5700: io.FileIO() called flush() after closing the file. flush() was - not called in close() if closefd=False. - -- bpo-23374: Fixed pydoc failure with non-ASCII files when stdout encoding - differs from file system encoding (e.g. on Mac OS). - -- bpo-23481: Remove RC4 from the SSL module's default cipher list. - -- bpo-21548: Fix pydoc.synopsis() and pydoc.apropos() on modules with empty - docstrings. - -- bpo-22885: Fixed arbitrary code execution vulnerability in the dbm.dumb - module. Original patch by Claudiu Popa. - -- bpo-23239: ssl.match_hostname() now supports matching of IP addresses. - -- bpo-23146: Fix mishandling of absolute Windows paths with forward slashes - in pathlib. - -- bpo-23096: Pickle representation of floats with protocol 0 now is the same - for both Python and C implementations. - -- bpo-19105: pprint now more efficiently uses free space at the right. - -- bpo-14910: Add allow_abbrev parameter to argparse.ArgumentParser. Patch by - Jonathan Paugh, Steven Bethard, paul j3 and Daniel Eriksson. - -- bpo-21717: tarfile.open() now supports 'x' (exclusive creation) mode. - -- bpo-23344: marshal.dumps() is now 20-25% faster on average. - -- bpo-20416: marshal.dumps() with protocols 3 and 4 is now 40-50% faster on - average. - -- bpo-23421: Fixed compression in tarfile CLI. Patch by wdv4758h. - -- bpo-23367: Fix possible overflows in the unicodedata module. - -- bpo-23361: Fix possible overflow in Windows subprocess creation code. - -- logging.handlers.QueueListener now takes a respect_handler_level keyword - argument which, if set to True, will pass messages to handlers taking - handler levels into account. - -- bpo-19705: turtledemo now has a visual sorting algorithm demo. Original - patch from Jason Yeo. - -- bpo-23801: Fix issue where cgi.FieldStorage did not always ignore the - entire preamble to a multipart body. - -Build ------ - -- bpo-23445: pydebug builds now use "gcc -Og" where possible, to make the - resulting executable faster. - -- bpo-23686: Update OS X 10.5 installer build to use OpenSSL 1.0.2a. - -C API ------ - -- bpo-20204: Deprecation warning is now raised for builtin types without the - __module__ attribute. - -Windows -------- - -- bpo-23465: Implement :pep:`486` - Make the Python Launcher aware of - virtual environments. Patch by Paul Moore. - -- bpo-23437: Make user scripts directory versioned on Windows. Patch by Paul - Moore. - - -What's New in Python 3.5.0 alpha 1? -=================================== - -*Release date: 2015-02-08* - -Core and Builtins ------------------ - -- bpo-23285: PEP 475 - EINTR handling. - -- bpo-22735: Fix many edge cases (including crashes) involving custom mro() - implementations. - -- bpo-22896: Avoid using PyObject_AsCharBuffer(), PyObject_AsReadBuffer() - and PyObject_AsWriteBuffer(). - -- bpo-21295: Revert some changes (issue #16795) to AST line numbers and - column offsets that constituted a regression. - -- bpo-22986: Allow changing an object's __class__ between a dynamic type and - static type in some cases. - -- bpo-15859: PyUnicode_EncodeFSDefault(), PyUnicode_EncodeMBCS() and - PyUnicode_EncodeCodePage() now raise an exception if the object is not a - Unicode object. For PyUnicode_EncodeFSDefault(), it was already the case - on platforms other than Windows. Patch written by Campbell Barton. - -- bpo-21408: The default __ne__() now returns NotImplemented if __eq__() - returned NotImplemented. Original patch by Martin Panter. - -- bpo-23321: Fixed a crash in str.decode() when error handler returned - replacement string longer than malformed input data. - -- bpo-22286: The "backslashreplace" error handlers now works with decoding - and translating. - -- bpo-23253: Delay-load ShellExecute[AW] in os.startfile for reduced startup - overhead on Windows. - -- bpo-22038: pyatomic.h now uses stdatomic.h or GCC built-in functions for - atomic memory access if available. Patch written by Vitor de Lima and - Gustavo Temple. - -- bpo-20284: %-interpolation (aka printf) formatting added for bytes and - bytearray. - -- bpo-23048: Fix jumping out of an infinite while loop in the pdb. - -- bpo-20335: bytes constructor now raises TypeError when encoding or errors - is specified with non-string argument. Based on patch by Renaud Blanch. - -- bpo-22834: If the current working directory ends up being set to a - non-existent directory then import will no longer raise FileNotFoundError. - -- bpo-22869: Move the interpreter startup & shutdown code to a new dedicated - pylifecycle.c module - -- bpo-22847: Improve method cache efficiency. - -- bpo-22335: Fix crash when trying to enlarge a bytearray to 0x7fffffff - bytes on a 32-bit platform. - -- bpo-22653: Fix an assertion failure in debug mode when doing a reentrant - dict insertion in debug mode. - -- bpo-22643: Fix integer overflow in Unicode case operations (upper, lower, - title, swapcase, casefold). - -- bpo-17636: Circular imports involving relative imports are now supported. - -- bpo-22604: Fix assertion error in debug mode when dividing a complex - number by (nan+0j). - -- bpo-21052: Do not raise ImportWarning when sys.path_hooks or sys.meta_path - are set to None. - -- bpo-16518: Use 'bytes-like object required' in error messages that - previously used the far more cryptic "'x' does not support the buffer - protocol. - -- bpo-22470: Fixed integer overflow issues in "backslashreplace", - "xmlcharrefreplace", and "surrogatepass" error handlers. - -- bpo-22540: speed up `PyObject_IsInstance` and `PyObject_IsSubclass` in the - common case that the second argument has metaclass `type`. - -- bpo-18711: Add a new `PyErr_FormatV` function, similar to `PyErr_Format` - but accepting a `va_list` argument. - -- bpo-22520: Fix overflow checking when generating the repr of a unicode - object. - -- bpo-22519: Fix overflow checking in PyBytes_Repr. - -- bpo-22518: Fix integer overflow issues in latin-1 encoding. - -- bpo-16324: _charset parameter of MIMEText now also accepts - email.charset.Charset instances. Initial patch by Claude Paroz. - -- bpo-1764286: Fix inspect.getsource() to support decorated functions. Patch - by Claudiu Popa. - -- bpo-18554: os.__all__ includes posix functions. - -- bpo-21391: Use os.path.abspath in the shutil module. - -- bpo-11471: avoid generating a JUMP_FORWARD instruction at the end of an - if-block if there is no else-clause. Original patch by Eugene Toder. - -- bpo-22215: Now ValueError is raised instead of TypeError when str or bytes - argument contains not permitted null character or byte. - -- bpo-22258: Fix the internal function set_inheritable() on Illumos. This - platform exposes the function ``ioctl(FIOCLEX)``, but calling it fails - with errno is ENOTTY: "Inappropriate ioctl for device". set_inheritable() - now falls back to the slower ``fcntl()`` (``F_GETFD`` and then - ``F_SETFD``). - -- bpo-21389: Displaying the __qualname__ of the underlying function in the - repr of a bound method. - -- bpo-22206: Using pthread, PyThread_create_key() now sets errno to ENOMEM - and returns -1 (error) on integer overflow. - -- bpo-20184: Argument Clinic based signature introspection added for 30 of - the builtin functions. - -- bpo-22116: C functions and methods (of the 'builtin_function_or_method' - type) can now be weakref'ed. Patch by Wei Wu. - -- bpo-22077: Improve index error messages for bytearrays, bytes, lists, and - tuples by adding 'or slices'. Added ', not <typename>' for bytearrays. - Original patch by Claudiu Popa. - -- bpo-20179: Apply Argument Clinic to bytes and bytearray. Patch by Tal - Einat. - -- bpo-22082: Clear interned strings in slotdefs. - -- Upgrade Unicode database to Unicode 7.0.0. - -- bpo-21897: Fix a crash with the f_locals attribute with closure variables - when frame.clear() has been called. - -- bpo-21205: Add a new ``__qualname__`` attribute to generator, the - qualified name, and use it in the representation of a generator - (``repr(gen)``). The default name of the generator (``__name__`` - attribute) is now get from the function instead of the code. Use - ``gen.gi_code.co_name`` to get the name of the code. - -- bpo-21669: With the aid of heuristics in SyntaxError.__init__, the parser - now attempts to generate more meaningful (or at least more search engine - friendly) error messages when "exec" and "print" are used as statements. - -- bpo-21642: In the conditional if-else expression, allow an integer written - with no space between itself and the ``else`` keyword (e.g. ``True if - 42else False``) to be valid syntax. - -- bpo-21523: Fix over-pessimistic computation of the stack effect of some - opcodes in the compiler. This also fixes a quadratic compilation time - issue noticeable when compiling code with a large number of "and" and "or" - operators. - -- bpo-21418: Fix a crash in the builtin function super() when called without - argument and without current frame (ex: embedded Python). - -- bpo-21425: Fix flushing of standard streams in the interactive - interpreter. - -- bpo-21435: In rare cases, when running finalizers on objects in cyclic - trash a bad pointer dereference could occur due to a subtle flaw in - internal iteration logic. - -- bpo-21377: PyBytes_Concat() now tries to concatenate in-place when the - first argument has a reference count of 1. Patch by Nikolaus Rath. - -- bpo-20355: -W command line options now have higher priority than the - PYTHONWARNINGS environment variable. Patch by Arfrever. - -- bpo-21274: Define PATH_MAX for GNU/Hurd in Python/pythonrun.c. - -- bpo-20904: Support setting FPU precision on m68k. - -- bpo-21209: Fix sending tuples to custom generator objects with the yield - from syntax. - -- bpo-21193: pow(a, b, c) now raises ValueError rather than TypeError when b - is negative. Patch by Josh Rosenberg. - -- bpo-21176: PEP 465: Add the '@' operator for matrix multiplication. - -- bpo-21134: Fix segfault when str is called on an uninitialized - UnicodeEncodeError, UnicodeDecodeError, or UnicodeTranslateError object. - -- bpo-19537: Fix PyUnicode_DATA() alignment under m68k. Patch by Andreas - Schwab. - -- bpo-20929: Add a type cast to avoid shifting a negative number. - -- bpo-20731: Properly position in source code files even if they are opened - in text mode. Patch by Serhiy Storchaka. - -- bpo-20637: Key-sharing now also works for instance dictionaries of - subclasses. Patch by Peter Ingebretson. - -- bpo-8297: Attributes missing from modules now include the module name in - the error text. Original patch by ysj.ray. - -- bpo-19995: %c, %o, %x, and %X now raise TypeError on non-integer input. - -- bpo-19655: The ASDL parser - used by the build process to generate code - for managing the Python AST in C - was rewritten. The new parser is self - contained and does not require to carry long the spark.py parser-generator - library; spark.py was removed from the source base. - -- bpo-12546: Allow ``\x00`` to be used as a fill character when using str, - int, float, and complex __format__ methods. - -- bpo-20480: Add ipaddress.reverse_pointer. Patch by Leon Weber. - -- bpo-13598: Modify string.Formatter to support auto-numbering of - replacement fields. It now matches the behavior of str.format() in this - regard. Patches by Phil Elson and Ramchandra Apte. - -- bpo-8931: Make alternate formatting ('#') for type 'c' raise an exception. - In versions prior to 3.5, '#' with 'c' had no effect. Now specifying it is - an error. Patch by Torsten Landschoff. - -- bpo-23165: Perform overflow checks before allocating memory in the - _Py_char2wchar function. - -Library -------- - -- bpo-23399: pyvenv creates relative symlinks where possible. - -- bpo-20289: cgi.FieldStorage() now supports the context management - protocol. - -- bpo-13128: Print response headers for CONNECT requests when debuglevel > - 0. Patch by Demian Brecht. - -- bpo-15381: Optimized io.BytesIO to make less allocations and copyings. - -- bpo-22818: Splitting on a pattern that could match an empty string now - raises a warning. Patterns that can only match empty strings are now - rejected. - -- bpo-23099: Closing io.BytesIO with exported buffer is rejected now to - prevent corrupting exported buffer. - -- bpo-23326: Removed __ne__ implementations. Since fixing default __ne__ - implementation in issue #21408 they are redundant. - -- bpo-23363: Fix possible overflow in itertools.permutations. - -- bpo-23364: Fix possible overflow in itertools.product. - -- bpo-23366: Fixed possible integer overflow in itertools.combinations. - -- bpo-23369: Fixed possible integer overflow in - _json.encode_basestring_ascii. - -- bpo-23353: Fix the exception handling of generators in - PyEval_EvalFrameEx(). At entry, save or swap the exception state even if - PyEval_EvalFrameEx() is called with throwflag=0. At exit, the exception - state is now always restored or swapped, not only if why is WHY_YIELD or - WHY_RETURN. Patch co-written with Antoine Pitrou. - -- bpo-14099: Restored support of writing ZIP files to tellable but - non-seekable streams. - -- bpo-14099: Writing to ZipFile and reading multiple ZipExtFiles is - threadsafe now. - -- bpo-19361: JSON decoder now raises JSONDecodeError instead of ValueError. - -- bpo-18518: timeit now rejects statements which can't be compiled outside a - function or a loop (e.g. "return" or "break"). - -- bpo-23094: Fixed readline with frames in Python implementation of pickle. - -- bpo-23268: Fixed bugs in the comparison of ipaddress classes. - -- bpo-21408: Removed incorrect implementations of __ne__() which didn't - returned NotImplemented if __eq__() returned NotImplemented. The default - __ne__() now works correctly. - -- bpo-19996: :class:`email.feedparser.FeedParser` now handles (malformed) - headers with no key rather than assuming the body has started. - -- bpo-20188: Support Application-Layer Protocol Negotiation (ALPN) in the - ssl module. - -- bpo-23133: Pickling of ipaddress objects now produces more compact and - portable representation. - -- bpo-23248: Update ssl error codes from latest OpenSSL git master. - -- bpo-23266: Much faster implementation of ipaddress.collapse_addresses() - when there are many non-consecutive addresses. - -- bpo-23098: 64-bit dev_t is now supported in the os module. - -- bpo-21817: When an exception is raised in a task submitted to a - ProcessPoolExecutor, the remote traceback is now displayed in the parent - process. Patch by Claudiu Popa. - -- bpo-15955: Add an option to limit output size when decompressing LZMA - data. Patch by Nikolaus Rath and Martin Panter. - -- bpo-23250: In the http.cookies module, capitalize "HttpOnly" and "Secure" - as they are written in the standard. - -- bpo-23063: In the distutils' check command, fix parsing of reST with code - or code-block directives. - -- bpo-23209: selectors.BaseSelector.get_key() now raises a RuntimeError if - the selector is closed. And selectors.BaseSelector.close() now clears its - internal reference to the selector mapping to break a reference cycle. - Initial patch written by Martin Richard. (See also: bpo-23225) - -- bpo-17911: Provide a way to seed the linecache for a PEP-302 module - without actually loading the code. - -- bpo-17911: Provide a new object API for traceback, including the ability - to not lookup lines at all until the traceback is actually rendered, - without any trace of the original objects being kept alive. - -- bpo-19777: Provide a home() classmethod on Path objects. Contributed by - Victor Salgado and Mayank Tripathi. - -- bpo-23206: Make ``json.dumps(..., ensure_ascii=False)`` as fast as the - default case of ``ensure_ascii=True``. Patch by Naoki Inada. - -- bpo-23185: Add math.inf and math.nan constants. - -- bpo-23186: Add ssl.SSLObject.shared_ciphers() and - ssl.SSLSocket.shared_ciphers() to fetch the client's list ciphers sent at - handshake. - -- bpo-23143: Remove compatibility with OpenSSLs older than 0.9.8. - -- bpo-23132: Improve performance and introspection support of comparison - methods created by functool.total_ordering. - -- bpo-19776: Add an expanduser() method on Path objects. - -- bpo-23112: Fix SimpleHTTPServer to correctly carry the query string and - fragment when it redirects to add a trailing slash. - -- bpo-21793: Added http.HTTPStatus enums (i.e. HTTPStatus.OK, - HTTPStatus.NOT_FOUND). Patch by Demian Brecht. - -- bpo-23093: In the io, module allow more operations to work on detached - streams. - -- bpo-23111: In the ftplib, make ssl.PROTOCOL_SSLv23 the default protocol - version. - -- bpo-22585: On OpenBSD 5.6 and newer, os.urandom() now calls getentropy(), - instead of reading /dev/urandom, to get pseudo-random bytes. - -- bpo-19104: pprint now produces evaluable output for wrapped strings. - -- bpo-23071: Added missing names to codecs.__all__. Patch by Martin Panter. - -- bpo-22783: Pickling now uses the NEWOBJ opcode instead of the NEWOBJ_EX - opcode if possible. - -- bpo-15513: Added a __sizeof__ implementation for pickle classes. - -- bpo-19858: pickletools.optimize() now aware of the MEMOIZE opcode, can - produce more compact result and no longer produces invalid output if input - data contains MEMOIZE opcodes together with PUT or BINPUT opcodes. - -- bpo-22095: Fixed HTTPConnection.set_tunnel with default port. The port - value in the host header was set to "None". Patch by Demian Brecht. - -- bpo-23016: A warning no longer produces an AttributeError when the program - is run with pythonw.exe. - -- bpo-21775: shutil.copytree(): fix crash when copying to VFAT. An exception - handler assumed that OSError objects always have a 'winerror' attribute. - That is not the case, so the exception handler itself raised - AttributeError when run on Linux (and, presumably, any other non-Windows - OS). Patch by Greg Ward. - -- bpo-1218234: Fix inspect.getsource() to load updated source of reloaded - module. Initial patch by Berker Peksag. - -- bpo-21740: Support wrapped callables in doctest. Patch by Claudiu Popa. - -- bpo-23009: Make sure selectors.EpollSelector.select() works when no FD is - registered. - -- bpo-22959: In the constructor of http.client.HTTPSConnection, prefer the - context's check_hostname attribute over the *check_hostname* parameter. - -- bpo-22696: Add function :func:`sys.is_finalizing` to know about - interpreter shutdown. - -- bpo-16043: Add a default limit for the amount of data - xmlrpclib.gzip_decode will return. This resolves CVE-2013-1753. - -- bpo-14099: ZipFile.open() no longer reopen the underlying file. Objects - returned by ZipFile.open() can now operate independently of the ZipFile - even if the ZipFile was created by passing in a file-like object as the - first argument to the constructor. - -- bpo-22966: Fix __pycache__ pyc file name clobber when pyc_compile is asked - to compile a source file containing multiple dots in the source file name. - -- bpo-21971: Update turtledemo doc and add module to the index. - -- bpo-21032: Fixed socket leak if HTTPConnection.getresponse() fails. - Original patch by Martin Panter. - -- bpo-22407: Deprecated the use of re.LOCALE flag with str patterns or - re.ASCII. It was newer worked. - -- bpo-22902: The "ip" command is now used on Linux to determine MAC address - in uuid.getnode(). Pach by Bruno Cauet. - -- bpo-22960: Add a context argument to xmlrpclib.ServerProxy constructor. - -- bpo-22389: Add contextlib.redirect_stderr(). - -- bpo-21356: Make ssl.RAND_egd() optional to support LibreSSL. The - availability of the function is checked during the compilation. Patch - written by Bernard Spil. - -- bpo-22915: SAX parser now supports files opened with file descriptor or - bytes path. - -- bpo-22609: Constructors and update methods of mapping classes in the - collections module now accept the self keyword argument. - -- bpo-22940: Add readline.append_history_file. - -- bpo-19676: Added the "namereplace" error handler. - -- bpo-22788: Add *context* parameter to logging.handlers.HTTPHandler. - -- bpo-22921: Allow SSLContext to take the *hostname* parameter even if - OpenSSL doesn't support SNI. - -- bpo-22894: TestCase.subTest() would cause the test suite to be stopped - when in failfast mode, even in the absence of failures. - -- bpo-22796: HTTP cookie parsing is now stricter, in order to protect - against potential injection attacks. - -- bpo-22370: Windows detection in pathlib is now more robust. - -- bpo-22841: Reject coroutines in asyncio add_signal_handler(). Patch by - Ludovic.Gasc. - -- bpo-19494: Added urllib.request.HTTPBasicPriorAuthHandler. Patch by Matej - Cepl. - -- bpo-22578: Added attributes to the re.error class. - -- bpo-22849: Fix possible double free in the io.TextIOWrapper constructor. - -- bpo-12728: Different Unicode characters having the same uppercase but - different lowercase are now matched in case-insensitive regular - expressions. - -- bpo-22821: Fixed fcntl() with integer argument on 64-bit big-endian - platforms. - -- bpo-21650: Add an `--sort-keys` option to json.tool CLI. - -- bpo-22824: Updated reprlib output format for sets to use set literals. - Patch contributed by Berker Peksag. - -- bpo-22824: Updated reprlib output format for arrays to display empty - arrays without an unnecessary empty list. Suggested by Serhiy Storchaka. - -- bpo-22406: Fixed the uu_codec codec incorrectly ported to 3.x. Based on - patch by Martin Panter. - -- bpo-17293: uuid.getnode() now determines MAC address on AIX using netstat. - Based on patch by Aivars Kalvāns. - -- bpo-22769: Fixed ttk.Treeview.tag_has() when called without arguments. - -- bpo-22417: Verify certificates by default in httplib (PEP 476). - -- bpo-22775: Fixed unpickling of http.cookies.SimpleCookie with protocol 2 - and above. Patch by Tim Graham. - -- bpo-22776: Brought excluded code into the scope of a try block in - SysLogHandler.emit(). - -- bpo-22665: Add missing get_terminal_size and SameFileError to - shutil.__all__. - -- bpo-6623: Remove deprecated Netrc class in the ftplib module. Patch by - Matt Chaput. - -- bpo-17381: Fixed handling of case-insensitive ranges in regular - expressions. - -- bpo-22410: Module level functions in the re module now cache compiled - locale-dependent regular expressions taking into account the locale. - -- bpo-22759: Query methods on pathlib.Path() (exists(), is_dir(), etc.) now - return False when the underlying stat call raises NotADirectoryError. - -- bpo-8876: distutils now falls back to copying files when hard linking - doesn't work. This allows use with special filesystems such as VirtualBox - shared folders. - -- bpo-22217: Implemented reprs of classes in the zipfile module. - -- bpo-22457: Honour load_tests in the start_dir of discovery. - -- bpo-18216: gettext now raises an error when a .mo file has an unsupported - major version number. Patch by Aaron Hill. - -- bpo-13918: Provide a locale.delocalize() function which can remove - locale-specific number formatting from a string representing a number, - without then converting it to a specific type. Patch by Cédric Krier. - -- bpo-22676: Make the pickling of global objects which don't have a - __module__ attribute less slow. - -- bpo-18853: Fixed ResourceWarning in shlex.__nain__. - -- bpo-9351: Defaults set with set_defaults on an argparse subparser are no - longer ignored when also set on the parent parser. - -- bpo-7559: unittest test loading ImportErrors are reported as import errors - with their import exception rather than as attribute errors after the - import has already failed. - -- bpo-19746: Make it possible to examine the errors from unittest discovery - without executing the test suite. The new `errors` attribute on TestLoader - exposes these non-fatal errors encountered during discovery. - -- bpo-21991: Make email.headerregistry's header 'params' attributes be - read-only (MappingProxyType). Previously the dictionary was modifiable - but a new one was created on each access of the attribute. - -- bpo-22638: SSLv3 is now disabled throughout the standard library. It can - still be enabled by instantiating a SSLContext manually. - -- bpo-22641: In asyncio, the default SSL context for client connections is - now created using ssl.create_default_context(), for stronger security. - -- bpo-17401: Include closefd in io.FileIO repr. - -- bpo-21338: Add silent mode for compileall. quiet parameters of - compile_{dir, file, path} functions now have a multilevel value. Also, -q - option of the CLI now have a multilevel value. Patch by Thomas Kluyver. - -- bpo-20152: Convert the array and cmath modules to Argument Clinic. - -- bpo-18643: Add socket.socketpair() on Windows. - -- bpo-22435: Fix a file descriptor leak when socketserver bind fails. - -- bpo-13096: Fixed segfault in CTypes POINTER handling of large values. - -- bpo-11694: Raise ConversionError in xdrlib as documented. Patch by Filip - Gruszczyński and Claudiu Popa. - -- bpo-19380: Optimized parsing of regular expressions. - -- bpo-1519638: Now unmatched groups are replaced with empty strings in - re.sub() and re.subn(). - -- bpo-18615: sndhdr.what/whathdr now return a namedtuple. - -- bpo-22462: Fix pyexpat's creation of a dummy frame to make it appear in - exception tracebacks. - -- bpo-21965: Add support for in-memory SSL to the ssl module. Patch by - Geert Jansen. - -- bpo-21173: Fix len() on a WeakKeyDictionary when .clear() was called with - an iterator alive. - -- bpo-11866: Eliminated race condition in the computation of names for new - threads. - -- bpo-21905: Avoid RuntimeError in pickle.whichmodule() when sys.modules is - mutated while iterating. Patch by Olivier Grisel. - -- bpo-11271: concurrent.futures.Executor.map() now takes a *chunksize* - argument to allow batching of tasks in child processes and improve - performance of ProcessPoolExecutor. Patch by Dan O'Reilly. - -- bpo-21883: os.path.join() and os.path.relpath() now raise a TypeError with - more helpful error message for unsupported or mismatched types of - arguments. - -- bpo-22219: The zipfile module CLI now adds entries for directories - (including empty directories) in ZIP file. - -- bpo-22449: In the ssl.SSLContext.load_default_certs, consult the - environmental variables SSL_CERT_DIR and SSL_CERT_FILE on Windows. - -- bpo-22508: The email.__version__ variable has been removed; the email code - is no longer shipped separately from the stdlib, and __version__ hasn't - been updated in several releases. - -- bpo-20076: Added non derived UTF-8 aliases to locale aliases table. - -- bpo-20079: Added locales supported in glibc 2.18 to locale alias table. - -- bpo-20218: Added convenience methods read_text/write_text and read_bytes/ - write_bytes to pathlib.Path objects. - -- bpo-22396: On 32-bit AIX platform, don't expose os.posix_fadvise() nor - os.posix_fallocate() because their prototypes in system headers are wrong. - -- bpo-22517: When an io.BufferedRWPair object is deallocated, clear its - weakrefs. - -- bpo-22437: Number of capturing groups in regular expression is no longer - limited by 100. - -- bpo-17442: InteractiveInterpreter now displays the full chained traceback - in its showtraceback method, to match the built in interactive - interpreter. - -- bpo-23392: Added tests for marshal C API that works with FILE*. - -- bpo-10510: distutils register and upload methods now use HTML standards - compliant CRLF line endings. - -- bpo-9850: Fixed macpath.join() for empty first component. Patch by Oleg - Oshmyan. - -- bpo-5309: distutils' build and build_ext commands now accept a ``-j`` - option to enable parallel building of extension modules. - -- bpo-22448: Improve canceled timer handles cleanup to prevent unbound - memory usage. Patch by Joshua Moore-Oliva. - -- bpo-22427: TemporaryDirectory no longer attempts to clean up twice when - used in the with statement in generator. - -- bpo-22362: Forbidden ambiguous octal escapes out of range 0-0o377 in - regular expressions. - -- bpo-20912: Now directories added to ZIP file have correct Unix and MS-DOS - directory attributes. - -- bpo-21866: ZipFile.close() no longer writes ZIP64 central directory - records if allowZip64 is false. - -- bpo-22278: Fix urljoin problem with relative urls, a regression observed - after changes to issue22118 were submitted. - -- bpo-22415: Fixed debugging output of the GROUPREF_EXISTS opcode in the re - module. Removed trailing spaces in debugging output. - -- bpo-22423: Unhandled exception in thread no longer causes unhandled - AttributeError when sys.stderr is None. - -- bpo-21332: Ensure that ``bufsize=1`` in subprocess.Popen() selects line - buffering, rather than block buffering. Patch by Akira Li. - -- bpo-21091: Fix API bug: email.message.EmailMessage.is_attachment is now a - method. - -- bpo-21079: Fix email.message.EmailMessage.is_attachment to return the - correct result when the header has parameters as well as a value. - -- bpo-22247: Add NNTPError to nntplib.__all__. - -- bpo-22366: urllib.request.urlopen will accept a context object - (SSLContext) as an argument which will then be used for HTTPS connection. - Patch by Alex Gaynor. - -- bpo-4180: The warnings registries are now reset when the filters are - modified. - -- bpo-22419: Limit the length of incoming HTTP request in wsgiref server to - 65536 bytes and send a 414 error code for higher lengths. Patch - contributed by Devin Cook. - -- Lax cookie parsing in http.cookies could be a security issue when combined - with non-standard cookie handling in some web browsers. Reported by - Sergey Bobrov. - -- bpo-20537: logging methods now accept an exception instance as well as a - Boolean value or exception tuple. Thanks to Yury Selivanov for the patch. - -- bpo-22384: An exception in Tkinter callback no longer crashes the program - when it is run with pythonw.exe. - -- bpo-22168: Prevent turtle AttributeError with non-default Canvas on OS X. - -- bpo-21147: sqlite3 now raises an exception if the request contains a null - character instead of truncating it. Based on patch by Victor Stinner. - -- bpo-13968: The glob module now supports recursive search in subdirectories - using the ``**`` pattern. - -- bpo-21951: Fixed a crash in Tkinter on AIX when called Tcl command with - empty string or tuple argument. - -- bpo-21951: Tkinter now most likely raises MemoryError instead of crash if - the memory allocation fails. - -- bpo-22338: Fix a crash in the json module on memory allocation failure. - -- bpo-12410: imaplib.IMAP4 now supports the context management protocol. - Original patch by Tarek Ziadé. - -- bpo-21270: We now override tuple methods in mock.call objects so that they - can be used as normal call attributes. - -- bpo-16662: load_tests() is now unconditionally run when it is present in a - package's __init__.py. TestLoader.loadTestsFromModule() still accepts - use_load_tests, but it is deprecated and ignored. A new keyword-only - attribute `pattern` is added and documented. Patch given by Robert - Collins, tweaked by Barry Warsaw. - -- bpo-22226: First letter no longer is stripped from the "status" key in the - result of Treeview.heading(). - -- bpo-19524: Fixed resource leak in the HTTP connection when an invalid - response is received. Patch by Martin Panter. - -- bpo-20421: Add a .version() method to SSL sockets exposing the actual - protocol version in use. - -- bpo-19546: configparser exceptions no longer expose implementation - details. Chained KeyErrors are removed, which leads to cleaner tracebacks. - Patch by Claudiu Popa. - -- bpo-22051: turtledemo no longer reloads examples to re-run them. - Initialization of variables and gui setup should be done in main(), which - is called each time a demo is run, but not on import. - -- bpo-21933: Turtledemo users can change the code font size with a menu - selection or control(command) '-' or '+' or control-mousewheel. Original - patch by Lita Cho. - -- bpo-21597: The separator between the turtledemo text pane and the drawing - canvas can now be grabbed and dragged with a mouse. The code text pane - can be widened to easily view or copy the full width of the text. The - canvas can be widened on small screens. Original patches by Jan Kanis and - Lita Cho. - -- bpo-18132: Turtledemo buttons no longer disappear when the window is - shrunk. Original patches by Jan Kanis and Lita Cho. - -- bpo-22043: time.monotonic() is now always available. - ``threading.Lock.acquire()``, ``threading.RLock.acquire()`` and socket - operations now use a monotonic clock, instead of the system clock, when a - timeout is used. - -- bpo-21527: Add a default number of workers to ThreadPoolExecutor equal to - 5 times the number of CPUs. Patch by Claudiu Popa. - -- bpo-22216: smtplib now resets its state more completely after a quit. The - most obvious consequence of the previous behavior was a STARTTLS failure - during a connect/starttls/quit/connect/starttls sequence. - -- bpo-22098: ctypes' BigEndianStructure and LittleEndianStructure now define - an empty __slots__ so that subclasses don't always get an instance dict. - Patch by Claudiu Popa. - -- bpo-22185: Fix an occasional RuntimeError in threading.Condition.wait() - caused by mutation of the waiters queue without holding the lock. Patch - by Doug Zongker. - -- bpo-22287: On UNIX, _PyTime_gettimeofday() now uses - clock_gettime(CLOCK_REALTIME) if available. As a side effect, Python now - depends on the librt library on Solaris and on Linux (only with glibc - older than 2.17). - -- bpo-22182: Use e.args to unpack exceptions correctly in - distutils.file_util.move_file. Patch by Claudiu Popa. - -- The webbrowser module now uses subprocess's start_new_session=True rather - than a potentially risky preexec_fn=os.setsid call. - -- bpo-22042: signal.set_wakeup_fd(fd) now raises an exception if the file - descriptor is in blocking mode. - -- bpo-16808: inspect.stack() now returns a named tuple instead of a tuple. - Patch by Daniel Shahaf. - -- bpo-22236: Fixed Tkinter images copying operations in NoDefaultRoot mode. - -- bpo-2527: Add a *globals* argument to timeit functions, in order to - override the globals namespace in which the timed code is executed. Patch - by Ben Roberts. - -- bpo-22118: Switch urllib.parse to use RFC 3986 semantics for the - resolution of relative URLs, rather than RFCs 1808 and 2396. Patch by - Demian Brecht. - -- bpo-21549: Added the "members" parameter to TarFile.list(). - -- bpo-19628: Allow compileall recursion depth to be specified with a -r - option. - -- bpo-15696: Add a __sizeof__ implementation for mmap objects on Windows. - -- bpo-22068: Avoided reference loops with Variables and Fonts in Tkinter. - -- bpo-22165: SimpleHTTPRequestHandler now supports undecodable file names. - -- bpo-15381: Optimized line reading in io.BytesIO. - -- bpo-8797: Raise HTTPError on failed Basic Authentication immediately. - Initial patch by Sam Bull. - -- bpo-20729: Restored the use of lazy iterkeys()/itervalues()/iteritems() in - the mailbox module. - -- bpo-21448: Changed FeedParser feed() to avoid O(N\ :sup:`2`) behavior when - parsing long line. Original patch by Raymond Hettinger. - -- bpo-22184: The functools LRU Cache decorator factory now gives an earlier - and clearer error message when the user forgets the required parameters. - -- bpo-17923: glob() patterns ending with a slash no longer match non-dirs on - AIX. Based on patch by Delhallt. - -- bpo-21725: Added support for RFC 6531 (SMTPUTF8) in smtpd. - -- bpo-22176: Update the ctypes module's libffi to v3.1. This release adds - support for the Linux AArch64 and POWERPC ELF ABIv2 little endian - architectures. - -- bpo-5411: Added support for the "xztar" format in the shutil module. - -- bpo-21121: Don't force 3rd party C extensions to be built with - -Werror=declaration-after-statement. - -- bpo-21975: Fixed crash when using uninitialized sqlite3.Row (in particular - when unpickling pickled sqlite3.Row). sqlite3.Row is now initialized in - the __new__() method. - -- bpo-20170: Convert posixmodule to use Argument Clinic. - -- bpo-21539: Add an *exists_ok* argument to `Pathlib.mkdir()` to mimic - `mkdir -p` and `os.makedirs()` functionality. When true, ignore - FileExistsErrors. Patch by Berker Peksag. - -- bpo-22127: Bypass IDNA for pure-ASCII host names in the socket module (in - particular for numeric IPs). - -- bpo-21047: set the default value for the *convert_charrefs* argument of - HTMLParser to True. Patch by Berker Peksag. - -- Add an __all__ to html.entities. - -- bpo-15114: the strict mode and argument of HTMLParser, HTMLParser.error, - and the HTMLParserError exception have been removed. - -- bpo-22085: Dropped support of Tk 8.3 in Tkinter. - -- bpo-21580: Now Tkinter correctly handles bytes arguments passed to Tk. In - particular this allows initializing images from binary data. - -- bpo-22003: When initialized from a bytes object, io.BytesIO() now defers - making a copy until it is mutated, improving performance and memory use on - some use cases. Patch by David Wilson. - -- bpo-22018: On Windows, signal.set_wakeup_fd() now also supports sockets. A - side effect is that Python depends to the WinSock library. - -- bpo-22054: Add os.get_blocking() and os.set_blocking() functions to get - and set the blocking mode of a file descriptor (False if the O_NONBLOCK - flag is set, True otherwise). These functions are not available on - Windows. - -- bpo-17172: Make turtledemo start as active on OS X even when run with - subprocess. Patch by Lita Cho. - -- bpo-21704: Fix build error for _multiprocessing when semaphores are not - available. Patch by Arfrever Frehtes Taifersar Arahesis. - -- bpo-20173: Convert sha1, sha256, sha512 and md5 to ArgumentClinic. Patch - by Vajrasky Kok. - -- Fix repr(_socket.socket) on Windows 64-bit: don't fail with OverflowError - on closed socket. repr(socket.socket) already works fine. - -- bpo-22033: Reprs of most Python implemented classes now contain actual - class name instead of hardcoded one. - -- bpo-21947: The dis module can now disassemble generator-iterator objects - based on their gi_code attribute. Patch by Clement Rouault. - -- bpo-16133: The asynchat.async_chat.handle_read() method now ignores - BlockingIOError exceptions. - -- bpo-22044: Fixed premature DECREF in call_tzinfo_method. Patch by Tom - Flanagan. - -- bpo-19884: readline: Disable the meta modifier key if stdout is not a - terminal to not write the ANSI sequence ``"\033[1034h"`` into stdout. This - sequence is used on some terminal (ex: TERM=xterm-256color") to enable - support of 8 bit characters. - -- bpo-4350: Removed a number of out-of-dated and non-working for a long time - Tkinter methods. - -- bpo-6167: Scrollbar.activate() now returns the name of active element if - the argument is not specified. Scrollbar.set() now always accepts only 2 - arguments. - -- bpo-15275: Clean up and speed up the ntpath module. - -- bpo-21888: plistlib's load() and loads() now work if the fmt parameter is - specified. - -- bpo-22032: __qualname__ instead of __name__ is now always used to format - fully qualified class names of Python implemented classes. - -- bpo-22031: Reprs now always use hexadecimal format with the "0x" prefix - when contain an id in form " at 0x...". - -- bpo-22018: signal.set_wakeup_fd() now raises an OSError instead of a - ValueError on ``fstat()`` failure. - -- bpo-21044: tarfile.open() now handles fileobj with an integer 'name' - attribute. Based on patch by Antoine Pietri. - -- bpo-21966: Respect -q command-line option when code module is ran. - -- bpo-19076: Don't pass the redundant 'file' argument to self.error(). - -- bpo-16382: Improve exception message of warnings.warn() for bad category. - Initial patch by Phil Elson. - -- bpo-21932: os.read() now uses a :c:func:`Py_ssize_t` type instead of - :c:expr:`int` for the size to support reading more than 2 GB at once. On - Windows, the size is truncated to INT_MAX. As any call to os.read(), the - OS may read less bytes than the number of requested bytes. - -- bpo-21942: Fixed source file viewing in pydoc's server mode on Windows. - -- bpo-11259: asynchat.async_chat().set_terminator() now raises a ValueError - if the number of received bytes is negative. - -- bpo-12523: asynchat.async_chat.push() now raises a TypeError if it doesn't - get a bytes string - -- bpo-21707: Add missing kwonlyargcount argument to - ModuleFinder.replace_paths_in_code(). - -- bpo-20639: calling Path.with_suffix('') allows removing the suffix again. - Patch by July Tikhonov. - -- bpo-21714: Disallow the construction of invalid paths using - Path.with_name(). Original patch by Antony Lee. - -- bpo-15014: Added 'auth' method to smtplib to make implementing auth - mechanisms simpler, and used it internally in the login method. - -- bpo-21151: Fixed a segfault in the winreg module when ``None`` is passed - as a ``REG_BINARY`` value to SetValueEx. Patch by John Ehresman. - -- bpo-21090: io.FileIO.readall() does not ignore I/O errors anymore. Before, - it ignored I/O errors if at least the first C call read() succeed. - -- bpo-5800: headers parameter of wsgiref.headers.Headers is now optional. - Initial patch by Pablo Torres Navarrete and SilentGhost. - -- bpo-21781: ssl.RAND_add() now supports strings longer than 2 GB. - -- bpo-21679: Prevent extraneous fstat() calls during open(). Patch by - Bohuslav Kabrda. - -- bpo-21863: cProfile now displays the module name of C extension functions, - in addition to their own name. - -- bpo-11453: asyncore: emit a ResourceWarning when an unclosed file_wrapper - object is destroyed. The destructor now closes the file if needed. The - close() method can now be called twice: the second call does nothing. - -- bpo-21858: Better handling of Python exceptions in the sqlite3 module. - -- bpo-21476: Make sure the email.parser.BytesParser TextIOWrapper is - discarded after parsing, so the input file isn't unexpectedly closed. - -- bpo-20295: imghdr now recognizes OpenEXR format images. - -- bpo-21729: Used the "with" statement in the dbm.dumb module to ensure - files closing. Patch by Claudiu Popa. - -- bpo-21491: socketserver: Fix a race condition in child processes reaping. - -- bpo-21719: Added the ``st_file_attributes`` field to os.stat_result on - Windows. - -- bpo-21832: Require named tuple inputs to be exact strings. - -- bpo-21722: The distutils "upload" command now exits with a non-zero return - code when uploading fails. Patch by Martin Dengler. - -- bpo-21723: asyncio.Queue: support any type of number (ex: float) for the - maximum size. Patch written by Vajrasky Kok. - -- bpo-21711: support for "site-python" directories has now been removed from - the site module (it was deprecated in 3.4). - -- bpo-17552: new socket.sendfile() method allowing a file to be sent over a - socket by using high-performance os.sendfile() on UNIX. Patch by Giampaolo - Rodola'. - -- bpo-18039: dbm.dump.open() now always creates a new database when the flag - has the value 'n'. Patch by Claudiu Popa. - -- bpo-21326: Add a new is_closed() method to asyncio.BaseEventLoop. - run_forever() and run_until_complete() methods of asyncio.BaseEventLoop - now raise an exception if the event loop was closed. - -- bpo-21766: Prevent a security hole in CGIHTTPServer by URL unquoting paths - before checking for a CGI script at that path. - -- bpo-21310: Fixed possible resource leak in failed open(). - -- bpo-21256: Printout of keyword args should be in deterministic order in a - mock function call. This will help to write better doctests. - -- bpo-21677: Fixed chaining nonnormalized exceptions in io close() methods. - -- bpo-11709: Fix the pydoc.help function to not fail when sys.stdin is not a - valid file. - -- bpo-21515: tempfile.TemporaryFile now uses os.O_TMPFILE flag is available. - -- bpo-13223: Fix pydoc.writedoc so that the HTML documentation for methods - that use 'self' in the example code is generated correctly. - -- bpo-21463: In urllib.request, fix pruning of the FTP cache. - -- bpo-21618: The subprocess module could fail to close open fds that were - inherited by the calling process and already higher than POSIX resource - limits would otherwise allow. On systems with a functioning /proc/self/fd - or /dev/fd interface the max is now ignored and all fds are closed. - -- bpo-20383: Introduce importlib.util.module_from_spec() as the preferred - way to create a new module. - -- bpo-21552: Fixed possible integer overflow of too long string lengths in - the tkinter module on 64-bit platforms. - -- bpo-14315: The zipfile module now ignores extra fields in the central - directory that are too short to be parsed instead of letting a - struct.unpack error bubble up as this "bad data" appears in many real - world zip files in the wild and is ignored by other zip tools. - -- bpo-13742: Added "key" and "reverse" parameters to heapq.merge(). (First - draft of patch contributed by Simon Sapin.) - -- bpo-21402: tkinter.ttk now works when default root window is not set. - -- bpo-3015: _tkinter.create() now creates tkapp object with wantobject=1 by - default. - -- bpo-10203: sqlite3.Row now truly supports sequence protocol. In - particular it supports reverse() and negative indices. Original patch by - Claudiu Popa. - -- bpo-18807: If copying (no symlinks) specified for a venv, then the python - interpreter aliases (python, python3) are now created by copying rather - than symlinking. - -- bpo-20197: Added support for the WebP image type in the imghdr module. - Patch by Fabrice Aneche and Claudiu Popa. - -- bpo-21513: Speedup some properties of IP addresses (IPv4Address, - IPv6Address) such as .is_private or .is_multicast. - -- bpo-21137: Improve the repr for threading.Lock() and its variants by - showing the "locked" or "unlocked" status. Patch by Berker Peksag. - -- bpo-21538: The plistlib module now supports loading of binary plist files - when reference or offset size is not a power of two. - -- bpo-21455: Add a default backlog to socket.listen(). - -- bpo-21525: Most Tkinter methods which accepted tuples now accept lists - too. - -- bpo-22166: With the assistance of a new internal _codecs._forget_codec - helping function, test_codecs now clears the encoding caches to avoid the - appearance of a reference leak - -- bpo-22236: Tkinter tests now don't reuse default root window. New root - window is created for every test class. - -- bpo-10744: Fix :pep:`3118` format strings on ctypes objects with a - nontrivial shape. - -- bpo-20826: Optimize ipaddress.collapse_addresses(). - -- bpo-21487: Optimize ipaddress.summarize_address_range() and - ipaddress.{IPv4Network,IPv6Network}.subnets(). - -- bpo-21486: Optimize parsing of netmasks in ipaddress.IPv4Network and - ipaddress.IPv6Network. - -- bpo-13916: Disallowed the surrogatepass error handler for non UTF-\* - encodings. - -- bpo-20998: Fixed re.fullmatch() of repeated single character pattern with - ignore case. Original patch by Matthew Barnett. - -- bpo-21075: fileinput.FileInput now reads bytes from standard stream if - binary mode is specified. Patch by Sam Kimbrel. - -- bpo-19775: Add a samefile() method to pathlib Path objects. Initial patch - by Vajrasky Kok. - -- bpo-21226: Set up modules properly in PyImport_ExecCodeModuleObject (and - friends). - -- bpo-21398: Fix a unicode error in the pydoc pager when the documentation - contains characters not encodable to the stdout encoding. - -- bpo-16531: ipaddress.IPv4Network and ipaddress.IPv6Network now accept an - (address, netmask) tuple argument, so as to easily construct network - objects from existing addresses. - -- bpo-21156: importlib.abc.InspectLoader.source_to_code() is now a - staticmethod. - -- bpo-21424: Simplified and optimized heaqp.nlargest() and nmsmallest() to - make fewer tuple comparisons. - -- bpo-21396: Fix TextIOWrapper(..., write_through=True) to not force a - flush() on the underlying binary stream. Patch by akira. - -- bpo-18314: Unlink now removes junctions on Windows. Patch by Kim Gräsman - -- bpo-21088: Bugfix for curses.window.addch() regression in 3.4.0. In - porting to Argument Clinic, the first two arguments were reversed. - -- bpo-21407: _decimal: The module now supports function signatures. - -- bpo-10650: Remove the non-standard 'watchexp' parameter from the - Decimal.quantize() method in the Python version. It had never been - present in the C version. - -- bpo-21469: Reduced the risk of false positives in robotparser by checking - to make sure that robots.txt has been read or does not exist prior to - returning True in can_fetch(). - -- bpo-19414: Have the OrderedDict mark deleted links as unusable. This gives - an early failure if the link is deleted during iteration. - -- bpo-21421: Add __slots__ to the MappingViews ABC. Patch by Josh Rosenberg. - -- bpo-21101: Eliminate double hashing in the C speed-up code for - collections.Counter(). - -- bpo-21321: itertools.islice() now releases the reference to the source - iterator when the slice is exhausted. Patch by Anton Afanasyev. - -- bpo-21057: TextIOWrapper now allows the underlying binary stream's read() - or read1() method to return an arbitrary bytes-like object (such as a - memoryview). Patch by Nikolaus Rath. - -- bpo-20951: SSLSocket.send() now raises either SSLWantReadError or - SSLWantWriteError on a non-blocking socket if the operation would block. - Previously, it would return 0. Patch by Nikolaus Rath. - -- bpo-13248: removed previously deprecated asyncore.dispatcher __getattr__ - cheap inheritance hack. - -- bpo-9815: assertRaises now tries to clear references to local variables in - the exception's traceback. - -- bpo-19940: ssl.cert_time_to_seconds() now interprets the given time string - in the UTC timezone (as specified in RFC 5280), not the local timezone. - -- bpo-13204: Calling sys.flags.__new__ would crash the interpreter, now it - raises a TypeError. - -- bpo-19385: Make operations on a closed dbm.dumb database always raise the - same exception. - -- bpo-21207: Detect when the os.urandom cached fd has been closed or - replaced, and open it anew. - -- bpo-21291: subprocess's Popen.wait() is now thread safe so that multiple - threads may be calling wait() or poll() on a Popen instance at the same - time without losing the Popen.returncode value. - -- bpo-21127: Path objects can now be instantiated from str subclass - instances (such as ``numpy.str_``). - -- bpo-15002: urllib.response object to use _TemporaryFileWrapper (and - _TemporaryFileCloser) facility. Provides a better way to handle file - descriptor close. Patch contributed by Christian Theune. - -- bpo-12220: mindom now raises a custom ValueError indicating it doesn't - support spaces in URIs instead of letting a 'split' ValueError bubble up. - -- bpo-21068: The ssl.PROTOCOL* constants are now enum members. - -- bpo-21276: posixmodule: Don't define USE_XATTRS on KFreeBSD and the Hurd. - -- bpo-21262: New method assert_not_called for Mock. It raises AssertionError - if the mock has been called. - -- bpo-21238: New keyword argument `unsafe` to Mock. It raises - `AttributeError` incase of an attribute startswith assert or assret. - -- bpo-20896: ssl.get_server_certificate() now uses PROTOCOL_SSLv23, not - PROTOCOL_SSLv3, for maximum compatibility. - -- bpo-21239: patch.stopall() didn't work deterministically when the same - name was patched more than once. - -- bpo-21203: Updated fileConfig and dictConfig to remove inconsistencies. - Thanks to Jure Koren for the patch. - -- bpo-21222: Passing name keyword argument to mock.create_autospec now - works. - -- bpo-21197: Add lib64 -> lib symlink in venvs on 64-bit non-OS X POSIX. - -- bpo-17498: Some SMTP servers disconnect after certain errors, violating - strict RFC conformance. Instead of losing the error code when we issue - the subsequent RSET, smtplib now returns the error code and defers raising - the SMTPServerDisconnected error until the next command is issued. - -- bpo-17826: setting an iterable side_effect on a mock function created by - create_autospec now works. Patch by Kushal Das. - -- bpo-7776: Fix ``Host:`` header and reconnection when using - http.client.HTTPConnection.set_tunnel(). Patch by Nikolaus Rath. - -- bpo-20968: unittest.mock.MagicMock now supports division. Patch by - Johannes Baiter. - -- bpo-21529: Fix arbitrary memory access in JSONDecoder.raw_decode with a - negative second parameter. Bug reported by Guido Vranken. (See also: - CVE-2014-4616) - -- bpo-21169: getpass now handles non-ascii characters that the input stream - encoding cannot encode by re-encoding using the replace error handler. - -- bpo-21171: Fixed undocumented filter API of the rot13 codec. Patch by - Berker Peksag. - -- bpo-20539: Improved math.factorial error message for large positive inputs - and changed exception type (OverflowError -> ValueError) for large - negative inputs. - -- bpo-21172: isinstance check relaxed from dict to collections.Mapping. - -- bpo-21155: asyncio.EventLoop.create_unix_server() now raises a ValueError - if path and sock are specified at the same time. - -- bpo-21136: Avoid unnecessary normalization of Fractions resulting from - power and other operations. Patch by Raymond Hettinger. - -- bpo-17621: Introduce importlib.util.LazyLoader. - -- bpo-21076: signal module constants were turned into enums. Patch by - Giampaolo Rodola'. - -- bpo-20636: Improved the repr of Tkinter widgets. - -- bpo-19505: The items, keys, and values views of OrderedDict now support - reverse iteration using reversed(). - -- bpo-21149: Improved thread-safety in logging cleanup during interpreter - shutdown. Thanks to Devin Jeanpierre for the patch. - -- bpo-21058: Fix a leak of file descriptor in - :func:`tempfile.NamedTemporaryFile`, close the file descriptor if - :func:`io.open` fails - -- bpo-21200: Return None from pkgutil.get_loader() when __spec__ is missing. - -- bpo-21013: Enhance ssl.create_default_context() when used for server side - sockets to provide better security by default. - -- bpo-20145: `assertRaisesRegex` and `assertWarnsRegex` now raise a - TypeError if the second argument is not a string or compiled regex. - -- bpo-20633: Replace relative import by absolute import. - -- bpo-20980: Stop wrapping exception when using ThreadPool. - -- bpo-21082: In os.makedirs, do not set the process-wide umask. Note this - changes behavior of makedirs when exist_ok=True. - -- bpo-20990: Fix issues found by pyflakes for multiprocessing. - -- bpo-21015: SSL contexts will now automatically select an elliptic curve - for ECDH key exchange on OpenSSL 1.0.2 and later, and otherwise default to - "prime256v1". - -- bpo-21000: Improve the command-line interface of json.tool. - -- bpo-20995: Enhance default ciphers used by the ssl module to enable better - security and prioritize perfect forward secrecy. - -- bpo-20884: Don't assume that __file__ is defined on importlib.__init__. - -- bpo-21499: Ignore __builtins__ in several test_importlib.test_api tests. - -- bpo-20627: xmlrpc.client.ServerProxy is now a context manager. - -- bpo-19165: The formatter module now raises DeprecationWarning instead of - PendingDeprecationWarning. - -- bpo-13936: Remove the ability of datetime.time instances to be considered - false in boolean contexts. - -- bpo-18931: selectors module now supports /dev/poll on Solaris. Patch by - Giampaolo Rodola'. - -- bpo-19977: When the ``LC_TYPE`` locale is the POSIX locale (``C`` locale), - :py:data:`sys.stdin` and :py:data:`sys.stdout` are now using the - ``surrogateescape`` error handler, instead of the ``strict`` error - handler. - -- bpo-20574: Implement incremental decoder for cp65001 code (Windows code - page 65001, Microsoft UTF-8). - -- bpo-20879: Delay the initialization of encoding and decoding tables for - base32, ascii85 and base85 codecs in the base64 module, and delay the - initialization of the unquote_to_bytes() table of the urllib.parse module, - to not waste memory if these modules are not used. - -- bpo-19157: Include the broadcast address in the usuable hosts for IPv6 in - ipaddress. - -- bpo-11599: When an external command (e.g. compiler) fails, distutils now - prints out the whole command line (instead of just the command name) if - the environment variable DISTUTILS_DEBUG is set. - -- bpo-4931: distutils should not produce unhelpful "error: None" messages - anymore. distutils.util.grok_environment_error is kept but doc-deprecated. - -- bpo-20875: Prevent possible gzip "'read' is not defined" NameError. Patch - by Claudiu Popa. - -- bpo-11558: ``email.message.Message.attach`` now returns a more useful - error message if ``attach`` is called on a message for which - ``is_multipart`` is False. - -- bpo-20283: RE pattern methods now accept the string keyword parameters as - documented. The pattern and source keyword parameters are left as - deprecated aliases. - -- bpo-20778: Fix modulefinder to work with bytecode-only modules. - -- bpo-20791: copy.copy() now doesn't make a copy when the input is a bytes - object. Initial patch by Peter Otten. - -- bpo-19748: On AIX, time.mktime() now raises an OverflowError for year - outsize range [1902; 2037]. - -- bpo-19573: inspect.signature: Use enum for parameter kind constants. - -- bpo-20726: inspect.signature: Make Signature and Parameter picklable. - -- bpo-17373: Add inspect.Signature.from_callable method. - -- bpo-20378: Improve repr of inspect.Signature and inspect.Parameter. - -- bpo-20816: Fix inspect.getcallargs() to raise correct TypeError for - missing keyword-only arguments. Patch by Jeremiah Lowin. - -- bpo-20817: Fix inspect.getcallargs() to fail correctly if more than 3 - arguments are missing. Patch by Jeremiah Lowin. - -- bpo-6676: Ensure a meaningful exception is raised when attempting to parse - more than one XML document per pyexpat xmlparser instance. (Original - patches by Hirokazu Yamamoto and Amaury Forgeot d'Arc, with suggested - wording by David Gutteridge) - -- bpo-21117: Fix inspect.signature to better support functools.partial. Due - to the specifics of functools.partial implementation, - positional-or-keyword arguments passed as keyword arguments become - keyword-only. - -- bpo-20334: inspect.Signature and inspect.Parameter are now hashable. - Thanks to Antony Lee for bug reports and suggestions. - -- bpo-15916: doctest.DocTestSuite returns an empty unittest.TestSuite - instead of raising ValueError if it finds no tests - -- bpo-21209: Fix asyncio.tasks.CoroWrapper to workaround a bug in yield-from - implementation in CPythons prior to 3.4.1. - -- asyncio: Add gi_{frame,running,code} properties to CoroWrapper (upstream - issue #163). - -- bpo-21311: Avoid exception in _osx_support with non-standard compiler - configurations. Patch by John Szakmeister. - -- bpo-11571: Ensure that the turtle window becomes the topmost window when - launched on OS X. - -- bpo-21801: Validate that __signature__ is None or an instance of - Signature. - -- bpo-21923: Prevent AttributeError in - distutils.sysconfig.customize_compiler due to possible uninitialized - _config_vars. - -- bpo-21323: Fix http.server to again handle scripts in CGI subdirectories, - broken by the fix for security issue #19435. Patch by Zach Byrne. - -- bpo-22733: Fix ffi_prep_args not zero-extending argument values correctly - on 64-bit Windows. - -- bpo-23302: Default to TCP_NODELAY=1 upon establishing an HTTPConnection. - Removed use of hard-coded MSS as it's an optimization that's no longer - needed with Nagle disabled. - -IDLE ----- - -- bpo-20577: Configuration of the max line length for the FormatParagraph - extension has been moved from the General tab of the Idle preferences - dialog to the FormatParagraph tab of the Config Extensions dialog. Patch - by Tal Einat. - -- bpo-16893: Update Idle doc chapter to match current Idle and add new - information. - -- bpo-3068: Add Idle extension configuration dialog to Options menu. Changes - are written to HOME/.idlerc/config-extensions.cfg. Original patch by Tal - Einat. - -- bpo-16233: A module browser (File : Class Browser, Alt+C) requires an - editor window with a filename. When Class Browser is requested otherwise, - from a shell, output window, or 'Untitled' editor, Idle no longer displays - an error box. It now pops up an Open Module box (Alt+M). If a valid name - is entered and a module is opened, a corresponding browser is also opened. - -- bpo-4832: Save As to type Python files automatically adds .py to the name - you enter (even if your system does not display it). Some systems - automatically add .txt when type is Text files. - -- bpo-21986: Code objects are not normally pickled by the pickle module. To - match this, they are no longer pickled when running under Idle. - -- bpo-17390: Adjust Editor window title; remove 'Python', move version to - end. - -- bpo-14105: Idle debugger breakpoints no longer disappear when inserting or - deleting lines. - -- bpo-17172: Turtledemo can now be run from Idle. Currently, the entry is on - the Help menu, but it may move to Run. Patch by Ramchandra Apt and Lita - Cho. - -- bpo-21765: Add support for non-ascii identifiers to HyperParser. - -- bpo-21940: Add unittest for WidgetRedirector. Initial patch by Saimadhav - Heblikar. - -- bpo-18592: Add unittest for SearchDialogBase. Patch by Phil Webster. - -- bpo-21694: Add unittest for ParenMatch. Patch by Saimadhav Heblikar. - -- bpo-21686: add unittest for HyperParser. Original patch by Saimadhav - Heblikar. - -- bpo-12387: Add missing upper(lower)case versions of default Windows key - bindings for Idle so Caps Lock does not disable them. Patch by Roger - Serwy. - -- bpo-21695: Closing a Find-in-files output window while the search is still - in progress no longer closes Idle. - -- bpo-18910: Add unittest for textView. Patch by Phil Webster. - -- bpo-18292: Add unittest for AutoExpand. Patch by Saihadhav Heblikar. - -- bpo-18409: Add unittest for AutoComplete. Patch by Phil Webster. - -- bpo-21477: htest.py - Improve framework, complete set of tests. Patches by - Saimadhav Heblikar - -- bpo-18104: Add idlelib/idle_test/htest.py with a few sample tests to begin - consolidating and improving human-validated tests of Idle. Change other - files as needed to work with htest. Running the module as __main__ runs - all tests. - -- bpo-21139: Change default paragraph width to 72, the :pep:`8` - recommendation. - -- bpo-21284: Paragraph reformat test passes after user changes reformat - width. - -- bpo-17654: Ensure IDLE menus are customized properly on OS X for - non-framework builds and for all variants of Tk. - -- bpo-23180: Rename IDLE "Windows" menu item to "Window". Patch by Al - Sweigart. - -Build ------ - -- bpo-15506: Use standard PKG_PROG_PKG_CONFIG autoconf macro in the - configure script. - -- bpo-22935: Allow the ssl module to be compiled if openssl doesn't support - SSL 3. - -- bpo-22592: Drop support of the Borland C compiler to build Python. The - distutils module still supports it to build extensions. - -- bpo-22591: Drop support of MS-DOS, especially of the DJGPP compiler - (MS-DOS port of GCC). - -- bpo-16537: Check whether self.extensions is empty in setup.py. Patch by - Jonathan Hosmer. - -- bpo-22359: Remove incorrect uses of recursive make. Patch by Jonas - Wagner. - -- bpo-21958: Define HAVE_ROUND when building with Visual Studio 2013 and - above. Patch by Zachary Turner. - -- bpo-18093: the programs that embed the CPython runtime are now in a - separate "Programs" directory, rather than being kept in the Modules - directory. - -- bpo-15759: "make suspicious", "make linkcheck" and "make doctest" in Doc/ - now display special message when and only when there are failures. - -- bpo-21141: The Windows build process no longer attempts to find Perl, - instead relying on OpenSSL source being configured and ready to build. - The ``PCbuild\build_ssl.py`` script has been re-written and re-named to - ``PCbuild\prepare_ssl.py``, and takes care of configuring OpenSSL source - for both 32 and 64 bit platforms. OpenSSL sources obtained from - svn.python.org will always be pre-configured and ready to build. - -- bpo-21037: Add a build option to enable AddressSanitizer support. - -- bpo-19962: The Windows build process now creates "python.bat" in the root - of the source tree, which passes all arguments through to the most - recently built interpreter. - -- bpo-21285: Refactor and fix curses configure check to always search in a - ncursesw directory. - -- bpo-15234: For BerkeleyDB and Sqlite, only add the found library and - include directories if they aren't already being searched. This avoids an - explicit runtime library dependency. - -- bpo-17861: Tools/scripts/generate_opcode_h.py automatically regenerates - Include/opcode.h from Lib/opcode.py if the latter gets any change. - -- bpo-20644: OS X installer build support for documentation build changes in - 3.4.1: assume externally supplied sphinx-build is available in /usr/bin. - -- bpo-20022: Eliminate use of deprecated bundlebuilder in OS X builds. - -- bpo-15968: Incorporated Tcl, Tk, and Tix builds into the Windows build - solution. - -- bpo-17095: Fix Modules/Setup *shared* support. - -- bpo-21811: Anticipated fixes to support OS X versions > 10.9. - -- bpo-21166: Prevent possible segfaults and other random failures of python - --generate-posix-vars in pybuilddir.txt build target. - -- bpo-18096: Fix library order returned by python-config. - -- bpo-17219: Add library build dir for Python extension cross-builds. - -- bpo-22919: Windows build updated to support VC 14.0 (Visual Studio 2015), - which will be used for the official release. - -- bpo-21236: Build _msi.pyd with cabinet.lib instead of fci.lib - -- bpo-17128: Use private version of OpenSSL for OS X 10.5+ installer. - -C API ------ - -- bpo-14203: Remove obsolete support for view==NULL in PyBuffer_FillInfo(), - bytearray_getbuffer(), bytesiobuf_getbuffer() and array_buffer_getbuf(). - All functions now raise BufferError in that case. - -- bpo-22445: PyBuffer_IsContiguous() now implements precise contiguity - tests, compatible with NumPy's NPY_RELAXED_STRIDES_CHECKING compilation - flag. Previously the function reported false negatives for corner cases. - -- bpo-22079: PyType_Ready() now checks that statically allocated type has no - dynamically allocated bases. - -- bpo-22453: Removed non-documented macro PyObject_REPR(). - -- bpo-18395: Rename ``_Py_char2wchar()`` to :c:func:`Py_DecodeLocale`, - rename ``_Py_wchar2char()`` to :c:func:`Py_EncodeLocale`, and document - these functions. - -- bpo-21233: Add new C functions: PyMem_RawCalloc(), PyMem_Calloc(), - PyObject_Calloc(), _PyObject_GC_Calloc(). bytes(int) is now using - ``calloc()`` instead of ``malloc()`` for large objects which is faster and - use less memory. - -- bpo-20942: PyImport_ImportFrozenModuleObject() no longer sets __file__ to - match what importlib does; this affects _frozen_importlib as well as any - module loaded using imp.init_frozen(). - -Documentation -------------- - -- bpo-19548: Update the codecs module documentation to better cover the - distinction between text encodings and other codecs, together with other - clarifications. Patch by Martin Panter. - -- bpo-22394: Doc/Makefile now supports ``make venv PYTHON=../python`` to - create a venv for generating the documentation, e.g., ``make html - PYTHON=venv/bin/python3``. - -- bpo-21514: The documentation of the json module now refers to new JSON RFC - 7159 instead of obsoleted RFC 4627. - -- bpo-21777: The binary sequence methods on bytes and bytearray are now - documented explicitly, rather than assuming users will be able to derive - the expected behaviour from the behaviour of the corresponding str - methods. - -- bpo-6916: undocument deprecated asynchat.fifo class. - -- bpo-17386: Expanded functionality of the ``Doc/make.bat`` script to make - it much more comparable to ``Doc/Makefile``. - -- bpo-21312: Update the thread_foobar.h template file to include newer - threading APIs. Patch by Jack McCracken. - -- bpo-21043: Remove the recommendation for specific CA organizations and to - mention the ability to load the OS certificates. - -- bpo-20765: Add missing documentation for PurePath.with_name() and - PurePath.with_suffix(). - -- bpo-19407: New package installation and distribution guides based on the - Python Packaging Authority tools. Existing guides have been retained as - legacy links from the distutils docs, as they still contain some required - reference material for tool developers that isn't recorded anywhere else. - -- bpo-19697: Document cases where __main__.__spec__ is None. - -Tests ------ - -- bpo-18982: Add tests for CLI of the calendar module. - -- bpo-19548: Added some additional checks to test_codecs to ensure that - statements in the updated documentation remain accurate. Patch by Martin - Panter. - -- bpo-22838: All test_re tests now work with unittest test discovery. - -- bpo-22173: Update lib2to3 tests to use unittest test discovery. - -- bpo-16000: Convert test_curses to use unittest. - -- bpo-21456: Skip two tests in test_urllib2net.py if _ssl module not - present. Patch by Remi Pointel. - -- bpo-20746: Fix test_pdb to run in refleak mode (-R). Patch by Xavier de - Gaye. - -- bpo-22060: test_ctypes has been somewhat cleaned up and simplified; it now - uses unittest test discovery to find its tests. - -- bpo-22104: regrtest.py no longer holds a reference to the suite of tests - loaded from test modules that don't define test_main(). - -- bpo-22111: Assorted cleanups in test_imaplib. Patch by Milan Oberkirch. - -- bpo-22002: Added ``load_package_tests`` function to test.support and used - it to implement/augment test discovery in test_asyncio, test_email, - test_importlib, test_json, and test_tools. - -- bpo-21976: Fix test_ssl to accept LibreSSL version strings. Thanks to - William Orr. - -- bpo-21918: Converted test_tools from a module to a package containing - separate test files for each tested script. - -- bpo-9554: Use modern unittest features in test_argparse. Initial patch by - Denver Coneybeare and Radu Voicilas. - -- bpo-20155: Changed HTTP method names in failing tests in test_httpservers - so that packet filtering software (specifically Windows Base Filtering - Engine) does not interfere with the transaction semantics expected by the - tests. - -- bpo-19493: Refactored the ctypes test package to skip tests explicitly - rather than silently. - -- bpo-18492: All resources are now allowed when tests are not run by - regrtest.py. - -- bpo-21634: Fix pystone micro-benchmark: use floor division instead of true - division to benchmark integers instead of floating point numbers. Set - pystone version to 1.2. Patch written by Lennart Regebro. - -- bpo-21605: Added tests for Tkinter images. - -- bpo-21493: Added test for ntpath.expanduser(). Original patch by Claudiu - Popa. - -- bpo-19925: Added tests for the spwd module. Original patch by Vajrasky - Kok. - -- bpo-21522: Added Tkinter tests for Listbox.itemconfigure(), - PanedWindow.paneconfigure(), and Menu.entryconfigure(). - -- bpo-17756: Fix test_code test when run from the installed location. - -- bpo-17752: Fix distutils tests when run from the installed location. - -- bpo-18604: Consolidated checks for GUI availability. All platforms now at - least check whether Tk can be instantiated when the GUI resource is - requested. - -- bpo-21275: Fix a socket test on KFreeBSD. - -- bpo-21223: Pass test_site/test_startup_imports when some of the extensions - are built as builtins. - -- bpo-20635: Added tests for Tk geometry managers. - -- Add test case for freeze. - -- bpo-20743: Fix a reference leak in test_tcl. - -- bpo-21097: Move test_namespace_pkgs into test_importlib. - -- bpo-21503: Use test_both() consistently in test_importlib. - -- bpo-20939: Avoid various network test failures due to new redirect of - http://www.python.org/ to https://www.python.org: use - http://www.example.com instead. - -- bpo-20668: asyncio tests no longer rely on tests.txt file. (Patch by - Vajrasky Kok) - -- bpo-21093: Prevent failures of ctypes test_macholib on OS X if a copy of - libz exists in $HOME/lib or /usr/local/lib. - -- bpo-22770: Prevent some Tk segfaults on OS X when running gui tests. - -- bpo-23211: Workaround test_logging failure on some OS X 10.6 systems. - -- bpo-23345: Prevent test_ssl failures with large OpenSSL patch level values - (like 0.9.8zc). - -Tools/Demos ------------ - -- bpo-22314: pydoc now works when the LINES environment variable is set. - -- bpo-22615: Argument Clinic now supports the "type" argument for the int - converter. This permits using the int converter with enums and typedefs. - -- bpo-20076: The makelocalealias.py script no longer ignores UTF-8 mapping. - -- bpo-20079: The makelocalealias.py script now can parse the SUPPORTED file - from glibc sources and supports command line options for source paths. - -- bpo-22201: Command-line interface of the zipfile module now correctly - extracts ZIP files with directory entries. Patch by Ryan Wilson. - -- bpo-22120: For functions using an unsigned integer return converter, - Argument Clinic now generates a cast to that type for the comparison to -1 - in the generated code. (This suppresses a compilation warning.) - -- bpo-18974: Tools/scripts/diff.py now uses argparse instead of optparse. - -- bpo-21906: Make Tools/scripts/md5sum.py work in Python 3. Patch by Zachary - Ware. - -- bpo-21629: Fix Argument Clinic's "--converters" feature. - -- Add support for ``yield from`` to 2to3. - -- Add support for the :pep:`465` matrix multiplication operator to 2to3. - -- bpo-16047: Fix module exception list and __file__ handling in freeze. - Patch by Meador Inge. - -- bpo-11824: Consider ABI tags in freeze. Patch by Meador Inge. - -- bpo-20535: PYTHONWARNING no longer affects the run_tests.py script. Patch - by Arfrever Frehtes Taifersar Arahesis. - -Windows -------- - -- bpo-23260: Update Windows installer - -- The bundled version of Tcl/Tk has been updated to 8.6.3. The most visible - result of this change is the addition of new native file dialogs when - running on Windows Vista or newer. See Tcl/Tk's TIP 432 for more - information. Also, this version of Tcl/Tk includes support for Windows - 10. - -- bpo-17896: The Windows build scripts now expect external library sources - to be in ``PCbuild\..\externals`` rather than ``PCbuild\..\..``. - -- bpo-17717: The Windows build scripts now use a copy of NASM pulled from - svn.python.org to build OpenSSL. - -- bpo-21907: Improved the batch scripts provided for building Python. - -- bpo-22644: The bundled version of OpenSSL has been updated to 1.0.1j. - -- bpo-10747: Use versioned labels in the Windows start menu. Patch by Olive - Kilburn. - -- bpo-22980: .pyd files with a version and platform tag (for example, - ".cp35-win32.pyd") will now be loaded in preference to those without tags. - - -**(For information about older versions, consult the HISTORY file.)** diff --git a/Misc/NEWS.d/3.10.0a1.rst b/Misc/NEWS.d/3.10.0a1.rst new file mode 100644 index 00000000..62538d73 --- /dev/null +++ b/Misc/NEWS.d/3.10.0a1.rst @@ -0,0 +1,3509 @@ +.. bpo: 41304 +.. date: 2020-07-15-20-15-08 +.. nonce: vNEeYA +.. release date: 2020-10-05 +.. section: Security + +Fixes `python3x._pth` being ignored on Windows, caused by the fix for +:issue:`29778` (CVE-2020-15801). + +.. + +.. bpo: 41162 +.. date: 2020-07-03-20-41-29 +.. nonce: tb8pVj +.. section: Security + +Audit hooks are now cleared later during finalization to avoid missing +events. + +.. + +.. bpo: 29778 +.. date: 2020-07-03-17-21-37 +.. nonce: cR_fGS +.. section: Security + +Ensure :file:`python3.dll` is loaded from correct locations when Python is +embedded (CVE-2020-15523). + +.. + +.. bpo: 41004 +.. date: 2020-06-29-16-02-29 +.. nonce: ovF0KZ +.. section: Security + +The __hash__() methods of ipaddress.IPv4Interface and +ipaddress.IPv6Interface incorrectly generated constant hash values of 32 and +128 respectively. This resulted in always causing hash collisions. The fix +uses hash() to generate hash values for the tuple of (address, mask length, +network address). + +.. + +.. bpo: 39603 +.. date: 2020-02-12-14-17-39 +.. nonce: Gt3RSg +.. section: Security + +Prevent http header injection by rejecting control characters in +http.client.putrequest(...). + +.. + +.. bpo: 41909 +.. date: 2020-10-04-10-55-12 +.. nonce: BqHPcm +.. section: Core and Builtins + +Fixed stack overflow in :func:`issubclass` and :func:`isinstance` when +getting the ``__bases__`` attribute leads to infinite recursion. + +.. + +.. bpo: 41922 +.. date: 2020-10-04-01-02-58 +.. nonce: kHGT8I +.. section: Core and Builtins + +Speed up calls to ``reversed()`` by using the :pep:`590` ``vectorcall`` +calling convention. Patch by Donghee Na. + +.. + +.. bpo: 41873 +.. date: 2020-09-28-08-58-28 +.. nonce: VzEDhA +.. section: Core and Builtins + +Calls to ``float()`` are now faster due to the ``vectorcall`` calling +convention. Patch by Dennis Sweeney. + +.. + +.. bpo: 41870 +.. date: 2020-09-27-22-23-14 +.. nonce: 2v6_v4 +.. section: Core and Builtins + +Speed up calls to ``bool()`` by using the :pep:`590` ``vectorcall`` calling +convention. Patch by Donghee Na. + +.. + +.. bpo: 1635741 +.. date: 2020-09-26-14-43-30 +.. nonce: aJS9B3 +.. section: Core and Builtins + +Port the :mod:`_bisect` module to the multi-phase initialization API +(:pep:`489`). + +.. + +.. bpo: 39934 +.. date: 2020-09-24-12-15-45 +.. nonce: YVHTCF +.. section: Core and Builtins + +Correctly count control blocks in 'except' in compiler. Ensures that a +syntax error, rather a fatal error, occurs for deeply nested, named +exception handlers. + +.. + +.. bpo: 41780 +.. date: 2020-09-15-23-29-49 +.. nonce: bOBUIH +.. section: Core and Builtins + +Fix :meth:`__dir__` of :class:`types.GenericAlias`. Patch by Batuhan +Taskaya. + +.. + +.. bpo: 1635741 +.. date: 2020-09-12-18-34-34 +.. nonce: lh335O +.. section: Core and Builtins + +Port the :mod:`_lsprof` extension module to multi-phase initialization +(:pep:`489`). + +.. + +.. bpo: 1635741 +.. date: 2020-09-08-21-58-47 +.. nonce: vdjSLH +.. section: Core and Builtins + +Port the :mod:`cmath` extension module to multi-phase initialization +(:pep:`489`). + +.. + +.. bpo: 1635741 +.. date: 2020-09-08-20-39-43 +.. nonce: jiXmyT +.. section: Core and Builtins + +Port the :mod:`_scproxy` extension module to multi-phase initialization +(:pep:`489`). + +.. + +.. bpo: 1635741 +.. date: 2020-09-07-11-35-02 +.. nonce: rvIexb +.. section: Core and Builtins + +Port the :mod:`termios` extension module to multi-phase initialization +(:pep:`489`). + +.. + +.. bpo: 1635741 +.. date: 2020-09-07-09-45-47 +.. nonce: QuDIut +.. section: Core and Builtins + +Convert the :mod:`_sha256` extension module types to heap types. + +.. + +.. bpo: 41690 +.. date: 2020-09-02-12-00-57 +.. nonce: Ny-Sfy +.. section: Core and Builtins + +Fix a possible stack overflow in the parser when parsing functions and +classes with a huge amount of arguments. Patch by Pablo Galindo. + +.. + +.. bpo: 1635741 +.. date: 2020-09-01-17-22-35 +.. nonce: CnRME3 +.. section: Core and Builtins + +Port the :mod:`_overlapped` extension module to multi-phase initialization +(:pep:`489`). + +.. + +.. bpo: 1635741 +.. date: 2020-09-01-17-08-07 +.. nonce: X9CZgo +.. section: Core and Builtins + +Port the :mod:`_curses_panel` extension module to multi-phase initialization +(:pep:`489`). + +.. + +.. bpo: 1635741 +.. date: 2020-09-01-17-06-02 +.. nonce: 5jZymK +.. section: Core and Builtins + +Port the :mod:`_opcode` extension module to multi-phase initialization +(:pep:`489`). + +.. + +.. bpo: 41681 +.. date: 2020-08-31-17-49-02 +.. nonce: 3-VJiH +.. section: Core and Builtins + +Fixes the wrong error description in the error raised by using 2 `,` in +format string in f-string and :meth:`str.format`. + +.. + +.. bpo: 41675 +.. date: 2020-08-31-14-53-17 +.. nonce: VSoqWU +.. section: Core and Builtins + +The implementation of :func:`signal.siginterrupt` now uses +:c:func:`!sigaction` (if it is available in the system) instead of the +deprecated :c:func:`!siginterrupt`. Patch by Pablo Galindo. + +.. + +.. bpo: 41670 +.. date: 2020-08-31-11-37-59 +.. nonce: vmRJRx +.. section: Core and Builtins + +Prevent line trace being skipped on platforms not compiled with +``USE_COMPUTED_GOTOS``. Fixes issue where some lines nested within a +try-except block were not being traced on Windows. + +.. + +.. bpo: 41654 +.. date: 2020-08-30-20-38-33 +.. nonce: HtnhAM +.. section: Core and Builtins + +Fix a crash that occurred when destroying subclasses of +:class:`MemoryError`. Patch by Pablo Galindo. + +.. + +.. bpo: 1635741 +.. date: 2020-08-28-20-54-04 +.. nonce: 7ijlcI +.. section: Core and Builtins + +Port the :mod:`zlib` extension module to multi-phase initialization +(:pep:`489`). + +.. + +.. bpo: 41631 +.. date: 2020-08-26-11-23-31 +.. nonce: 3jZcd9 +.. section: Core and Builtins + +The ``_ast`` module uses again a global state. Using a module state per +module instance is causing subtle practical problems. For example, the +Mercurial project replaces the ``__import__()`` function to implement lazy +import, whereas Python expected that ``import _ast`` always return a fully +initialized ``_ast`` module. + +.. + +.. bpo: 40077 +.. date: 2020-08-25-22-43-33 +.. nonce: vcxSUa +.. section: Core and Builtins + +Convert :mod:`_operator` to use :c:func:`PyType_FromSpec`. + +.. + +.. bpo: 1653741 +.. date: 2020-08-13-07-19-21 +.. nonce: fubBkb +.. section: Core and Builtins + +Port :mod:`_sha3` to multi-phase init. Convert static types to heap types. + +.. + +.. bpo: 1635741 +.. date: 2020-08-13-07-18-05 +.. nonce: FC13e7 +.. section: Core and Builtins + +Port the :mod:`_blake2` extension module to the multi-phase initialization +API (:pep:`489`). + +.. + +.. bpo: 41533 +.. date: 2020-08-12-20-29-57 +.. nonce: 4pcVAc +.. section: Core and Builtins + +Free the stack allocated in ``va_build_stack`` if ``do_mkstack`` fails and +the stack is not a ``small_stack``. + +.. + +.. bpo: 41531 +.. date: 2020-08-12-19-32-15 +.. nonce: WgPzjT +.. section: Core and Builtins + +Fix a bug that was dropping keys when compiling dict literals with more than +0xFFFF elements. Patch by Pablo Galindo. + +.. + +.. bpo: 41525 +.. date: 2020-08-12-07-35-07 +.. nonce: d9q3XL +.. section: Core and Builtins + +The output of ``python --help`` contains now only ASCII characters. + +.. + +.. bpo: 1635741 +.. date: 2020-08-10-16-11-32 +.. nonce: O0d3ym +.. section: Core and Builtins + +Port the :mod:`_sha1`, :mod:`_sha512`, and :mod:`_md5` extension modules to +multi-phase initialization API (:pep:`489`). + +.. + +.. bpo: 41431 +.. date: 2020-08-02-15-53-12 +.. nonce: TblUBT +.. section: Core and Builtins + +Optimize ``dict_merge()`` for copying dict (e.g. ``dict(d)`` and +``{}.update(d)``). + +.. + +.. bpo: 41428 +.. date: 2020-07-28-22-43-27 +.. nonce: FM6xsI +.. section: Core and Builtins + +Implement PEP 604. This supports (int | str) etc. in place of Union[str, +int]. + +.. + +.. bpo: 41340 +.. date: 2020-07-27-01-50-06 +.. nonce: pZXfcF +.. section: Core and Builtins + +Removed fallback implementation for ``strdup``. + +.. + +.. bpo: 38156 +.. date: 2020-07-20-17-01-17 +.. nonce: ptcdRy +.. section: Core and Builtins + +Handle interrupts that come after EOF correctly in ``PyOS_StdioReadline``. + +.. + +.. bpo: 41342 +.. date: 2020-07-19-15-40-52 +.. nonce: RRk_m_ +.. section: Core and Builtins + +:func:`round` with integer argument is now faster (9--60%). + +.. + +.. bpo: 41334 +.. date: 2020-07-18-18-01-10 +.. nonce: t5xMGp +.. section: Core and Builtins + +Constructors :func:`str`, :func:`bytes` and :func:`bytearray` are now faster +(around 30--40% for small objects). + +.. + +.. bpo: 41295 +.. date: 2020-07-18-08-15-32 +.. nonce: pu8Ezo +.. section: Core and Builtins + +Resolve a regression in CPython 3.8.4 where defining "__setattr__" in a +multi-inheritance setup and calling up the hierarchy chain could fail if +builtins/extension types were involved in the base types. + +.. + +.. bpo: 41323 +.. date: 2020-07-17-11-31-54 +.. nonce: ChbZHh +.. section: Core and Builtins + +Bytecode optimizations are performed directly on the control flow graph. +This will result in slightly more compact code objects in some +circumstances. + +.. + +.. bpo: 41247 +.. date: 2020-07-08-22-03-54 +.. nonce: PndYIk +.. section: Core and Builtins + +Always cache the running loop holder when running +``asyncio.set_running_loop``. + +.. + +.. bpo: 41252 +.. date: 2020-07-08-21-55-23 +.. nonce: nBWL-Y +.. section: Core and Builtins + +Fix incorrect refcounting in _ssl.c's ``_servername_callback()``. + +.. + +.. bpo: 1635741 +.. date: 2020-07-07-16-10-52 +.. nonce: zU-H_n +.. section: Core and Builtins + +Port :mod:`multiprocessing` to multi-phase initialization + +.. + +.. bpo: 1635741 +.. date: 2020-07-06-20-43-19 +.. nonce: LYhsni +.. section: Core and Builtins + +Port :mod:`winapi` to multiphase initialization + +.. + +.. bpo: 41215 +.. date: 2020-07-06-18-36-33 +.. nonce: vFGFIz +.. section: Core and Builtins + +Use non-NULL default values in the PEG parser keyword list to overcome a bug +that was preventing Python from being properly compiled when using the XLC +compiler. Patch by Pablo Galindo. + +.. + +.. bpo: 41218 +.. date: 2020-07-06-13-35-17 +.. nonce: oKnSr2 +.. section: Core and Builtins + +Python 3.8.3 had a regression where compiling with +ast.PyCF_ALLOW_TOP_LEVEL_AWAIT would aggressively mark list comprehension +with CO_COROUTINE. Now only list comprehension making use of async/await +will tagged as so. + +.. + +.. bpo: 1635741 +.. date: 2020-07-03-23-10-02 +.. nonce: F5coWe +.. section: Core and Builtins + +Port :mod:`faulthandler` to multiphase initialization. + +.. + +.. bpo: 1635741 +.. date: 2020-07-01-20-17-38 +.. nonce: -AtPYu +.. section: Core and Builtins + +Port :mod:`sha256` to multiphase initialization + +.. + +.. bpo: 41175 +.. date: 2020-06-30-20-17-31 +.. nonce: acJoXB +.. section: Core and Builtins + +Guard against a NULL pointer dereference within bytearrayobject triggered by +the ``bytearray() + bytearray()`` operation. + +.. + +.. bpo: 41100 +.. date: 2020-06-30-04-44-29 +.. nonce: PJwA6F +.. section: Core and Builtins + +add arm64 to the allowable Mac OS arches in mpdecimal.h + +.. + +.. bpo: 41094 +.. date: 2020-06-23-23-26-42 +.. nonce: zEIJse +.. section: Core and Builtins + +Fix decoding errors with audit when open files with non-ASCII names on +non-UTF-8 locale. + +.. + +.. bpo: 39960 +.. date: 2020-06-23-18-32-41 +.. nonce: Kez3fP +.. section: Core and Builtins + +The "hackcheck" that prevents sneaking around a type's __setattr__() by +calling the superclass method was rewritten to allow C implemented heap +types. + +.. + +.. bpo: 41084 +.. date: 2020-06-23-15-10-19 +.. nonce: pt3y7F +.. section: Core and Builtins + +Prefix the error message with 'f-string: ', when parsing an f-string +expression which throws a :exc:`SyntaxError`. + +.. + +.. bpo: 40521 +.. date: 2020-06-23-07-35-11 +.. nonce: dMNA6k +.. section: Core and Builtins + +Empty frozensets are no longer singletons. + +.. + +.. bpo: 41076 +.. date: 2020-06-22-13-22-30 +.. nonce: eWYw2N +.. section: Core and Builtins + +Pre-feed the parser with the location of the f-string expression, not the +f-string itself, which allows us to skip the shifting of the AST node +locations after the parsing is completed. + +.. + +.. bpo: 41056 +.. date: 2020-06-21-19-53-33 +.. nonce: IDu_EK +.. section: Core and Builtins + +Fixes a reference to deallocated stack space during startup when +constructing sys.path involving a relative symlink when code was supplied +via -c. (discovered via Coverity) + +.. + +.. bpo: 41061 +.. date: 2020-06-21-10-54-02 +.. nonce: AHf9MU +.. section: Core and Builtins + +Fix incorrect expressions and asserts in hashtable code and tests. + +.. + +.. bpo: 41052 +.. date: 2020-06-20-22-46-18 +.. nonce: 46MPeF +.. section: Core and Builtins + +Opt out serialization/deserialization for _random.Random + +.. + +.. bpo: 40939 +.. date: 2020-06-20-19-27-47 +.. nonce: jxJ4yn +.. section: Core and Builtins + +Rename `PyPegen*` functions to `PyParser*`, so that we can remove the old +set of `PyParser*` functions that were using the old parser, but keep +everything backwards-compatible. + +.. + +.. bpo: 35975 +.. date: 2020-06-20-17-00-44 +.. nonce: UDHCHp +.. section: Core and Builtins + +Stefan Behnel reported that cf_feature_version is used even when +PyCF_ONLY_AST is not set. This is against the intention and against the +documented behavior, so it's been fixed. + +.. + +.. bpo: 40939 +.. date: 2020-06-20-16-59-02 +.. nonce: 6810Ak +.. section: Core and Builtins + +Remove the remaining files from the old parser and the :mod:`symbol` module. + +.. + +.. bpo: 40077 +.. date: 2020-06-18-19-04-30 +.. nonce: _yI-ax +.. section: Core and Builtins + +Convert :mod:`_bz2` to use :c:func:`PyType_FromSpec`. + +.. + +.. bpo: 41006 +.. date: 2020-06-18-00-07-09 +.. nonce: H-wN-d +.. section: Core and Builtins + +The ``encodings.latin_1`` module is no longer imported at startup. Now it is +only imported when it is the filesystem encoding or the stdio encoding. + +.. + +.. bpo: 40636 +.. date: 2020-06-17-10-27-17 +.. nonce: MYaCIe +.. section: Core and Builtins + +:func:`zip` now supports :pep:`618`'s ``strict`` parameter, which raises a +:exc:`ValueError` if the arguments are exhausted at different lengths. Patch +by Brandt Bucher. + +.. + +.. bpo: 1635741 +.. date: 2020-06-17-00-52-21 +.. nonce: 61iyYh +.. section: Core and Builtins + +Port :mod:`_gdbm` to multiphase initialization. + +.. + +.. bpo: 40985 +.. date: 2020-06-15-16-29-55 +.. nonce: IIN_xX +.. section: Core and Builtins + +Fix a bug that caused the :exc:`SyntaxError` text to be empty when a file +ends with a line ending in a line continuation character (i.e. backslash). +The error text should contain the text of the last line. + +.. + +.. bpo: 40958 +.. date: 2020-06-15-01-20-44 +.. nonce: 7O2Wh1 +.. section: Core and Builtins + +Fix a possible buffer overflow in the PEG parser when gathering information +for emitting syntax errors. Patch by Pablo Galindo. + +.. + +.. bpo: 1635741 +.. date: 2020-06-12-22-56-17 +.. nonce: mmlp3Q +.. section: Core and Builtins + +Port :mod:`_dbm` to multiphase initialization. + +.. + +.. bpo: 40957 +.. date: 2020-06-12-12-21-54 +.. nonce: Z8n6I6 +.. section: Core and Builtins + +Fix refleak in _Py_fopen_obj() when PySys_Audit() fails + +.. + +.. bpo: 40950 +.. date: 2020-06-12-00-12-28 +.. nonce: tzMy7m +.. section: Core and Builtins + +Add a state to the :mod:`nis` module (:pep:`3121`) and apply the multiphase +initialization. Patch by Donghee Na. + +.. + +.. bpo: 40947 +.. date: 2020-06-11-16-06-49 +.. nonce: 72cZcR +.. section: Core and Builtins + +The Python :ref:`Path Configuration <init-path-config>` now takes +:c:member:`PyConfig.platlibdir` in account. + +.. + +.. bpo: 40939 +.. date: 2020-06-10-11-27-15 +.. nonce: DO-wAI +.. section: Core and Builtins + +Remove the old parser, the :mod:`parser` module and all associated support +code, command-line options and environment variables. Patch by Pablo +Galindo. + +.. + +.. bpo: 40847 +.. date: 2020-06-09-23-52-32 +.. nonce: 4XAACw +.. section: Core and Builtins + +Fix a bug where a line with only a line continuation character is not +considered a blank line at tokenizer level. In such cases, more than a +single `NEWLINE` token was emitted. The old parser was working around the +issue, but the new parser threw a :exc:`SyntaxError` for valid input due to +this. For example, an empty line following a line continuation character was +interpreted as a :exc:`SyntaxError`. + +.. + +.. bpo: 40890 +.. date: 2020-06-09-00-20-13 +.. nonce: LoRV-g +.. section: Core and Builtins + +Each dictionary view now has a ``mapping`` attribute that provides a +:class:`types.MappingProxyType` wrapping the original dictionary. Patch +contributed by Dennis Sweeney. + +.. + +.. bpo: 40889 +.. date: 2020-06-08-22-46-33 +.. nonce: vIBl-W +.. section: Core and Builtins + +Improved the performance of symmetric difference operations on dictionary +item views. Patch by Dennis Sweeney. + +.. + +.. bpo: 40904 +.. date: 2020-06-08-01-08-57 +.. nonce: 76qQzo +.. section: Core and Builtins + +Fix possible segfault in the new PEG parser when parsing f-string containing +yield statements with no value (:code:`f"{yield}"`). Patch by Pablo Galindo + +.. + +.. bpo: 40903 +.. date: 2020-06-07-22-50-10 +.. nonce: 7dWejS +.. section: Core and Builtins + +Fixed a possible segfault in the new PEG parser when producing error +messages for invalid assignments of the form :code:`p=p=`. Patch by Pablo +Galindo + +.. + +.. bpo: 40880 +.. date: 2020-06-06-00-23-19 +.. nonce: fjdzSh +.. section: Core and Builtins + +Fix invalid memory read in the new parser when checking newlines in string +literals. Patch by Pablo Galindo. + +.. + +.. bpo: 40883 +.. date: 2020-06-05-23-25-00 +.. nonce: M6sQ-Q +.. section: Core and Builtins + +Fix memory leak in when parsing f-strings in the new parser. Patch by Pablo +Galindo + +.. + +.. bpo: 40870 +.. date: 2020-06-05-12-48-28 +.. nonce: 9cd2sk +.. section: Core and Builtins + +Raise :exc:`ValueError` when validating custom AST's where the constants +``True``, ``False`` and ``None`` are used within a :class:`ast.Name` node. + +.. + +.. bpo: 40854 +.. date: 2020-06-03-13-53-24 +.. nonce: O6vfQU +.. section: Core and Builtins + +Allow overriding :data:`sys.platlibdir` via a new :envvar:`PYTHONPLATLIBDIR` +environment variable. + +.. + +.. bpo: 40826 +.. date: 2020-06-01-20-31-07 +.. nonce: XCI4M2 +.. section: Core and Builtins + +Fix GIL usage in :c:func:`PyOS_Readline`: lock the GIL to set an exception +and pass the Python thread state when checking if there is a pending signal. + +.. + +.. bpo: 1635741 +.. date: 2020-05-30-23-23-35 +.. nonce: 0D-laM +.. section: Core and Builtins + +Port :mod:`fcntl` to multiphase initialization. + +.. + +.. bpo: 19468 +.. date: 2020-05-30-23-18-35 +.. nonce: S-TA7p +.. section: Core and Builtins + +Delete unnecessary instance check in importlib.reload(). Patch by Furkan +Önder. + +.. + +.. bpo: 40824 +.. date: 2020-05-30-14-37-18 +.. nonce: XR3V5s +.. section: Core and Builtins + +Unexpected errors in calling the ``__iter__`` method are no longer masked by +``TypeError`` in the :keyword:`in` operator and functions +:func:`~operator.contains`, :func:`~operator.indexOf` and +:func:`~operator.countOf` of the :mod:`operator` module. + +.. + +.. bpo: 40792 +.. date: 2020-05-27-22-37-58 +.. nonce: WEDqqU +.. section: Core and Builtins + +Attributes ``start``, ``stop`` and ``step`` of the :class:`range` object now +always has exact type :class:`int`. Previously, they could have been an +instance of a subclass of ``int``. + +.. + +.. bpo: 40780 +.. date: 2020-05-26-17-43-58 +.. nonce: 3Ckdgm +.. section: Core and Builtins + +Fix a corner case where g-style string formatting of a float failed to +remove trailing zeros. + +.. + +.. bpo: 38964 +.. date: 2020-05-25-21-49-11 +.. nonce: lrml90 +.. section: Core and Builtins + +When there's a :exc:`SyntaxError` in the expression part of an fstring, the +filename attribute of the :exc:`SyntaxError` gets correctly set to the name +of the file the fstring resides in. + +.. + +.. bpo: 40750 +.. date: 2020-05-24-02-42-26 +.. nonce: ZmO9Ev +.. section: Core and Builtins + +Support the "-d" debug flag in the new PEG parser. Patch by Pablo Galindo + +.. + +.. bpo: 40217 +.. date: 2020-05-23-01-15-51 +.. nonce: jZsHTc +.. section: Core and Builtins + +Instances of types created with :c:func:`PyType_FromSpecWithBases` will no +longer automatically visit their class object when traversing references in +the garbage collector. The user is expected to manually visit the object's +class. Patch by Pablo Galindo. + +.. + +.. bpo: 39573 +.. date: 2020-05-22-00-34-34 +.. nonce: QO2QHj +.. section: Core and Builtins + +:c:func:`Py_TYPE()` is changed to the inline static function. Patch by +Donghee Na. + +.. + +.. bpo: 40696 +.. date: 2020-05-21-01-54-00 +.. nonce: u3n8Wx +.. section: Core and Builtins + +Fix a hang that can arise after :meth:`generator.throw` due to a cycle in +the exception context chain. + +.. + +.. bpo: 40521 +.. date: 2020-05-20-01-17-34 +.. nonce: wvAehI +.. section: Core and Builtins + +Each interpreter now its has own free lists, singletons and caches: + +* Free lists: float, tuple, list, dict, frame, context, + asynchronous generator, MemoryError. +* Singletons: empty tuple, empty bytes string, empty Unicode string, + single byte character, single Unicode (latin1) character. +* Slice cache. + +They are no longer shared by all interpreters. + +.. + +.. bpo: 40679 +.. date: 2020-05-19-19-39-49 +.. nonce: SVzz9p +.. section: Core and Builtins + +Certain :exc:`TypeError` messages about missing or extra arguments now +include the function's :term:`qualified name`. Patch by Dennis Sweeney. + +.. + +.. bpo: 29590 +.. date: 2020-05-03-22-26-00 +.. nonce: aRz3l7 +.. section: Core and Builtins + +Make the stack trace correct after calling :meth:`generator.throw` on a +generator that has yielded from a ``yield from``. + +.. + +.. bpo: 4022 +.. date: 2020-04-11-13-07-49 +.. nonce: Ctpn_F +.. section: Core and Builtins + +Improve performance of generators by not raising internal StopIteration. + +.. + +.. bpo: 1635741 +.. date: 2020-04-10-23-54-57 +.. nonce: ZURqoN +.. section: Core and Builtins + +Port :mod:`mmap` to multiphase initialization. + +.. + +.. bpo: 1635741 +.. date: 2020-04-05-02-35-08 +.. nonce: Kfe9fT +.. section: Core and Builtins + +Port :mod:`_lzma` to multiphase initialization. + +.. + +.. bpo: 37999 +.. date: 2019-09-01-14-26-02 +.. nonce: XPl6dn +.. section: Core and Builtins + +Builtin and extension functions that take integer arguments no longer accept +:class:`~decimal.Decimal`\ s, :class:`~fractions.Fraction`\ s and other +objects that can be converted to integers only with a loss (e.g. that have +the :meth:`~object.__int__` method but do not have the +:meth:`~object.__index__` method). + +.. + +.. bpo: 29882 +.. date: 2019-06-02-11-29-15 +.. nonce: AkRzjb +.. section: Core and Builtins + +Add :meth:`int.bit_count()`, counting the number of ones in the binary +representation of an integer. Patch by Niklas Fiekas. + +.. + +.. bpo: 36982 +.. date: 2019-05-25-05-27-39 +.. nonce: 0UHgfB +.. section: Core and Builtins + +Use ncurses extended color functions when available to support terminals +with 256 colors, and add the new function +:func:`curses.has_extended_color_support` to indicate whether extended color +support is provided by the underlying ncurses library. + +.. + +.. bpo: 19569 +.. date: 2018-08-29-15-57-07 +.. nonce: RGu2Kb +.. section: Core and Builtins + +Add the private macros ``_Py_COMP_DIAG_PUSH``, +``_Py_COMP_DIAG_IGNORE_DEPR_DECLS``, and ``_Py_COMP_DIAG_POP``. + +.. + +.. bpo: 26680 +.. date: 2018-03-15-11-51-36 +.. nonce: wOWYps +.. section: Core and Builtins + +The int type now supports the x.is_integer() method for compatibility with +float. + +.. + +.. bpo: 41900 +.. date: 2020-10-01-10-50-12 +.. nonce: Cho7oh +.. section: Library + +C14N 2.0 serialisation in xml.etree.ElementTree failed for unprefixed +attributes when a default namespace was defined. + +.. + +.. bpo: 41887 +.. date: 2020-09-30-23-49-42 +.. nonce: -ee2S- +.. section: Library + +Strip leading spaces and tabs on :func:`ast.literal_eval`. Also document +stripping of spaces and tabs for :func:`eval`. + +.. + +.. bpo: 41773 +.. date: 2020-09-28-23-22-25 +.. nonce: oKkus0 +.. section: Library + +Note in documentation that :func:`random.choices` doesn't support non-finite +weights, raise :exc:`ValueError` when given non-finite weights. + +.. + +.. bpo: 41840 +.. date: 2020-09-23-23-17-59 +.. nonce: QRFr4L +.. section: Library + +Fix a bug in the :mod:`symtable` module that was causing module-scope global +variables to not be reported as both local and global. Patch by Pablo +Galindo. + +.. + +.. bpo: 41842 +.. date: 2020-09-23-22-52-24 +.. nonce: lIuhC9 +.. section: Library + +Add :func:`codecs.unregister` function to unregister a codec search +function. + +.. + +.. bpo: 40564 +.. date: 2020-09-23-03-33-37 +.. nonce: iXQqMq +.. section: Library + +In ``zipfile.Path``, mutate the passed ZipFile object type instead of making +a copy. Prevents issues when both the local copy and the caller’s copy +attempt to close the same file handle. + +.. + +.. bpo: 40670 +.. date: 2020-09-22-14-55-34 +.. nonce: R5sm68 +.. section: Library + +More reliable validation of statements in :class:`timeit.Timer`. It now +accepts "empty" statements (only whitespaces and comments) and rejects +misindentent statements. + +.. + +.. bpo: 41833 +.. date: 2020-09-22-13-51-14 +.. nonce: 6HVDjT +.. section: Library + +The :class:`threading.Thread` constructor now uses the target name if the +*target* argument is specified but the *name* argument is omitted. + +.. + +.. bpo: 41817 +.. date: 2020-09-22-00-23-30 +.. nonce: bnh-VG +.. section: Library + +fix `tkinter.EventType` Enum so all members are strings, and none are tuples + +.. + +.. bpo: 41810 +.. date: 2020-09-20-15-14-05 +.. nonce: 7l8lyV +.. section: Library + +:data:`types.EllipsisType`, :data:`types.NotImplementedType` and +:data:`types.NoneType` have been reintroduced, providing a new set of types +readily interpretable by static type checkers. + +.. + +.. bpo: 41815 +.. date: 2020-09-19-23-14-54 +.. nonce: RNpuX3 +.. section: Library + +Fix SQLite3 segfault when backing up closed database. Patch contributed by +Peter David McCormick. + +.. + +.. bpo: 41816 +.. date: 2020-09-19-12-22-08 +.. nonce: ynynXJ +.. section: Library + +StrEnum added: it ensures that all members are already strings or string +candidates + +.. + +.. bpo: 41517 +.. date: 2020-09-15-22-43-30 +.. nonce: sLBH7g +.. section: Library + +fix bug allowing Enums to be extended via multiple inheritance + +.. + +.. bpo: 39587 +.. date: 2020-09-15-14-56-13 +.. nonce: 69xzuh +.. section: Library + +use the correct mix-in data type when constructing Enums + +.. + +.. bpo: 41792 +.. date: 2020-09-15-07-55-35 +.. nonce: qMpSlU +.. section: Library + +Add is_typeddict function to typing.py to check if a type is a TypedDict +class + +Previously there was no way to check that without using private API. See the +`relevant issue in python/typing +<https://github.com/python/typing/issues/751>` + +.. + +.. bpo: 41789 +.. date: 2020-09-14-19-27-46 +.. nonce: pI_uZQ +.. section: Library + +Honor `object` overrides in `Enum` class creation (specifically, `__str__`, +`__repr__`, `__format__`, and `__reduce_ex__`). + +.. + +.. bpo: 32218 +.. date: 2020-09-12-16-18-42 +.. nonce: IpYkEe +.. section: Library + +`enum.Flag` and `enum.IntFlag` members are now iterable + +.. + +.. bpo: 39651 +.. date: 2020-09-11-12-38-55 +.. nonce: JMp9l2 +.. section: Library + +Fix a race condition in the ``call_soon_threadsafe()`` method of +``asyncio.ProactorEventLoop``: do nothing if the self-pipe socket has been +closed. + +.. + +.. bpo: 1635741 +.. date: 2020-09-08-13-55-34 +.. nonce: 56MLP- +.. section: Library + +Port the ``mashal`` extension module to the multi-phase initialization API +(:pep:`489`). + +.. + +.. bpo: 1635741 +.. date: 2020-09-08-13-51-16 +.. nonce: wkPeoT +.. section: Library + +Port the ``_string`` extension module to the multi-phase initialization API +(:pep:`489`). + +.. + +.. bpo: 41732 +.. date: 2020-09-06-20-27-10 +.. nonce: 1SKv26 +.. section: Library + +Added an :term:`iterator` to :class:`memoryview`. + +.. + +.. bpo: 41720 +.. date: 2020-09-04-20-45-38 +.. nonce: PW9MzZ +.. section: Library + +Fixed :meth:`turtle.Vec2D.__rmul__` for arguments which are not int or +float. + +.. + +.. bpo: 41696 +.. date: 2020-09-03-01-35-32 +.. nonce: zkYGre +.. section: Library + +Fix handling of debug mode in :func:`asyncio.run`. This allows setting +``PYTHONASYNCIODEBUG`` or ``-X dev`` to enable asyncio debug mode when using +:func:`asyncio.run`. + +.. + +.. bpo: 41687 +.. date: 2020-09-01-15-57-51 +.. nonce: m1b1KA +.. section: Library + +Fix implementation of sendfile to be compatible with Solaris. + +.. + +.. bpo: 41662 +.. date: 2020-08-30-21-38-57 +.. nonce: 6e9iZn +.. section: Library + +No longer override exceptions raised in ``__len__()`` of a sequence of +parameters in :mod:`sqlite3` with :exc:`~sqlite3.ProgrammingError`. + +.. + +.. bpo: 39010 +.. date: 2020-08-30-10-24-26 +.. nonce: _mzXJW +.. section: Library + +Restarting a ``ProactorEventLoop`` on Windows no longer logs spurious +``ConnectionResetErrors``. + +.. + +.. bpo: 41638 +.. date: 2020-08-29-16-45-12 +.. nonce: iZfW5N +.. section: Library + +:exc:`~sqlite3.ProgrammingError` message for absent parameter in +:mod:`sqlite3` contains now the name of the parameter instead of its index +when parameters are supplied as a dict. + +.. + +.. bpo: 41662 +.. date: 2020-08-29-16-07-36 +.. nonce: Mn79zh +.. section: Library + +Fixed crash when mutate list of parameters during iteration in +:mod:`sqlite3`. + +.. + +.. bpo: 41513 +.. date: 2020-08-23-14-23-18 +.. nonce: DGqc_I +.. section: Library + +Improved the accuracy of math.hypot(). Internally, each step is computed +with extra precision so that the result is now almost always correctly +rounded. + +.. + +.. bpo: 41609 +.. date: 2020-08-21-15-51-15 +.. nonce: JmiUKG +.. section: Library + +The pdb whatis command correctly reports instance methods as 'Method' rather +than 'Function'. + +.. + +.. bpo: 39994 +.. date: 2020-08-15-18-17-21 +.. nonce: dOgPOh +.. section: Library + +Fixed pprint's handling of dict subclasses that override __repr__. + +.. + +.. bpo: 32751 +.. date: 2020-08-15-15-50-12 +.. nonce: 85je5X +.. section: Library + +When cancelling the task due to a timeout, :meth:`asyncio.wait_for` will now +wait until the cancellation is complete also in the case when *timeout* is +<= 0, like it does with positive timeouts. + +.. + +.. bpo: 37658 +.. date: 2020-08-15-15-21-40 +.. nonce: f9nivB +.. section: Library + +:meth:`asyncio.wait_for` now properly handles races between cancellation of +itself and the completion of the wrapped awaitable. + +.. + +.. bpo: 40782 +.. date: 2020-08-13-08-07-25 +.. nonce: aGZqmB +.. section: Library + +Change the method asyncio.AbstractEventLoop.run_in_executor to not be a +coroutine. + +.. + +.. bpo: 41520 +.. date: 2020-08-12-13-25-16 +.. nonce: BEUWa4 +.. section: Library + +Fix :mod:`codeop` regression that prevented turning compile warnings into +errors. + +.. + +.. bpo: 41528 +.. date: 2020-08-12-07-43-31 +.. nonce: bu83oD +.. section: Library + +turtle uses math module functions to convert degrees to radians and vice +versa and to calculate vector norm + +.. + +.. bpo: 41513 +.. date: 2020-08-09-18-16-05 +.. nonce: e6K6EK +.. section: Library + +Minor algorithmic improvement to math.hypot() and math.dist() giving small +gains in speed and accuracy. + +.. + +.. bpo: 41503 +.. date: 2020-08-07-15-18-16 +.. nonce: IYftcu +.. section: Library + +Fixed a race between setTarget and flush in logging.handlers.MemoryHandler. + +.. + +.. bpo: 41497 +.. date: 2020-08-07-06-06-29 +.. nonce: aBtsWz +.. section: Library + +Fix potential UnicodeDecodeError in dis module. + +.. + +.. bpo: 41467 +.. date: 2020-08-04-00-20-30 +.. nonce: Z8DgTL +.. section: Library + +On Windows, fix asyncio ``recv_into()`` return value when the socket/pipe is +closed (:exc:`BrokenPipeError`): return ``0`` rather than an empty byte +string (``b''``). + +.. + +.. bpo: 41425 +.. date: 2020-08-03-01-59-48 +.. nonce: KJo6zF +.. section: Library + +Make tkinter doc example runnable. + +.. + +.. bpo: 41421 +.. date: 2020-08-01-00-51-15 +.. nonce: dHKRVB +.. section: Library + +Make an algebraic simplification to random.paretovariate(). It now is +slightly less subject to round-off error and is slightly faster. Inputs that +used to cause ZeroDivisionError now cause an OverflowError instead. + +.. + +.. bpo: 41440 +.. date: 2020-07-30-14-56-58 +.. nonce: rju34k +.. section: Library + +Add :func:`os.cpu_count()` support for VxWorks RTOS. + +.. + +.. bpo: 41316 +.. date: 2020-07-28-12-08-58 +.. nonce: bSCbK4 +.. section: Library + +Fix the :mod:`tarfile` module to write only basename of TAR file to GZIP +compression header. + +.. + +.. bpo: 41384 +.. date: 2020-07-26-21-18-43 +.. nonce: MlzIgV +.. section: Library + +Raise TclError instead of TypeError when an unknown option is passed to +tkinter.OptionMenu. + +.. + +.. bpo: 41317 +.. date: 2020-07-23-01-18-34 +.. nonce: O17Z6x +.. section: Library + +Use add_done_callback() in asyncio.loop.sock_accept() to unsubscribe reader +early on cancellation. + +.. + +.. bpo: 41364 +.. date: 2020-07-21-21-45-55 +.. nonce: 5O-k7A +.. section: Library + +Reduce import overhead of :mod:`uuid`. + +.. + +.. bpo: 35328 +.. date: 2020-07-21-16-20-55 +.. nonce: jXovHb +.. section: Library + +Set the environment variable ``VIRTUAL_ENV_PROMPT`` at :mod:`venv` +activation. + +.. + +.. bpo: 41341 +.. date: 2020-07-20-19-13-17 +.. nonce: wqrj8C +.. section: Library + +Recursive evaluation of `typing.ForwardRef` in `get_type_hints`. + +.. + +.. bpo: 41344 +.. date: 2020-07-20-13-27-48 +.. nonce: iKipNd +.. section: Library + +Prevent creating :class:`shared_memory.SharedMemory` objects with +:code:`size=0`. + +.. + +.. bpo: 41333 +.. date: 2020-07-18-18-07-40 +.. nonce: upkHIm +.. section: Library + +:meth:`collections.OrderedDict.pop` is now 2 times faster. + +.. + +.. bpo: 41288 +.. date: 2020-07-13-15-06-35 +.. nonce: 8mn5P- +.. section: Library + +Unpickling invalid NEWOBJ_EX opcode with the C implementation raises now +UnpicklingError instead of crashing. + +.. + +.. bpo: 39017 +.. date: 2020-07-12-22-16-58 +.. nonce: x3Cg-9 +.. section: Library + +Avoid infinite loop when reading specially crafted TAR files using the +tarfile module (CVE-2019-20907). + +.. + +.. bpo: 41273 +.. date: 2020-07-11-00-15-01 +.. nonce: SVrsJh +.. section: Library + +Speed up any transport using ``_ProactorReadPipeTransport`` by calling +``recv_into`` instead of ``recv``, thus not creating a new buffer for each +``recv`` call in the transport's read loop. + +.. + +.. bpo: 41235 +.. date: 2020-07-07-21-56-26 +.. nonce: H2csMU +.. section: Library + +Fix the error handling in :meth:`ssl.SSLContext.load_dh_params`. + +.. + +.. bpo: 41207 +.. date: 2020-07-06-16-58-53 +.. nonce: Emw7Nk +.. section: Library + +In distutils.spawn, restore expectation that DistutilsExecError is raised +when the command is not found. + +.. + +.. bpo: 29727 +.. date: 2020-07-05-19-16-02 +.. nonce: Q6Z2rg +.. section: Library + +Register :class:`array.array` as a +:class:`~collections.abc.MutableSequence`. Patch by Pablo Galindo. + +.. + +.. bpo: 39168 +.. date: 2020-07-04-21-56-46 +.. nonce: DQWsXj +.. section: Library + +Remove the ``__new__`` method of :class:`typing.Generic`. + +.. + +.. bpo: 41194 +.. date: 2020-07-03-13-15-08 +.. nonce: djrKjs +.. section: Library + +Fix a crash in the ``_ast`` module: it can no longer be loaded more than +once. It now uses a global state rather than a module state. + +.. + +.. bpo: 41195 +.. date: 2020-07-02-15-03-04 +.. nonce: cEnpO3 +.. section: Library + +Add read-only ssl.SSLContext.security_level attribute to retrieve the +context's security level. + +.. + +.. bpo: 41193 +.. date: 2020-07-02-11-53-45 +.. nonce: 8-Tnql +.. section: Library + +The ``write_history()`` atexit function of the readline completer now +ignores any :exc:`OSError` to ignore error if the filesystem is read-only, +instead of only ignoring :exc:`FileNotFoundError` and +:exc:`PermissionError`. + +.. + +.. bpo: 41182 +.. date: 2020-07-01-17-33-50 +.. nonce: FPFI0N +.. section: Library + +selector: use DefaultSelector based upon implementation + +.. + +.. bpo: 41161 +.. date: 2020-06-30-20-50-51 +.. nonce: QTdJjz +.. section: Library + +The decimal module now requires libmpdec-2.5.0. Users of +--with-system-libmpdec should update their system library. + +.. + +.. bpo: 40874 +.. date: 2020-06-28-21-16-51 +.. nonce: YImvzA +.. section: Library + +The decimal module now requires libmpdec-2.5.0. + +.. + +.. bpo: 41138 +.. date: 2020-06-27-13-51-36 +.. nonce: bIpf7g +.. section: Library + +Fixed the :mod:`trace` module CLI for Python source files with non-UTF-8 +encoding. + +.. + +.. bpo: 31082 +.. date: 2020-06-25-10-11-47 +.. nonce: HsgDkx +.. section: Library + +Use the term "iterable" in the docstring for :func:`functools.reduce`. + +.. + +.. bpo: 40521 +.. date: 2020-06-23-06-09-59 +.. nonce: HUfxP7 +.. section: Library + +Remove freelist from collections.deque(). + +.. + +.. bpo: 31938 +.. date: 2020-06-22-20-08-40 +.. nonce: EVuko9 +.. section: Library + +Fix default-value signatures of several functions in the :mod:`select` +module - by Anthony Sottile. + +.. + +.. bpo: 41068 +.. date: 2020-06-22-10-25-39 +.. nonce: _bX2BW +.. section: Library + +Fixed reading files with non-ASCII names from ZIP archive directly after +writing them. + +.. + +.. bpo: 41058 +.. date: 2020-06-20-21-03-55 +.. nonce: gztdZy +.. section: Library + +:func:`pdb.find_function` now correctly determines the source file encoding. + +.. + +.. bpo: 41056 +.. date: 2020-06-20-18-37-29 +.. nonce: d9v_uL +.. section: Library + +Invalid file descriptor values are now prevented from being passed to +os.fpathconf. (discovered by Coverity) + +.. + +.. bpo: 41056 +.. date: 2020-06-20-18-35-43 +.. nonce: Garcle +.. section: Library + +Fix a NULL pointer dereference within the ssl module during a MemoryError in +the keylog callback. (discovered by Coverity) + +.. + +.. bpo: 41056 +.. date: 2020-06-20-18-33-03 +.. nonce: gTH4Bq +.. section: Library + +Fixed an instance where a MemoryError within the zoneinfo module might not +be reported or not reported at its source. (found by Coverity) + +.. + +.. bpo: 41048 +.. date: 2020-06-20-10-16-57 +.. nonce: hEXB-B +.. section: Library + +:func:`mimetypes.read_mime_types` function reads the rule file using UTF-8 +encoding, not the locale encoding. Patch by Srinivas Reddy Thatiparthy. + +.. + +.. bpo: 41043 +.. date: 2020-06-20-00-19-30 +.. nonce: p-Pk-H +.. section: Library + +Fixed the use of :func:`~glob.glob` in the stdlib: literal part of the path +is now always correctly escaped. + +.. + +.. bpo: 41025 +.. date: 2020-06-18-10-34-59 +.. nonce: elf_nz +.. section: Library + +Fixed an issue preventing the C implementation of :class:`zoneinfo.ZoneInfo` +from being subclassed. + +.. + +.. bpo: 35018 +.. date: 2020-06-17-23-49-45 +.. nonce: NP5_Qk +.. section: Library + +Add the :class:`xml.sax.handler.LexicalHandler` class that is present in +other SAX XML implementations. + +.. + +.. bpo: 41002 +.. date: 2020-06-17-17-26-24 +.. nonce: NPBItE +.. section: Library + +Improve performance of HTTPResponse.read with a given amount. Patch by Bruce +Merry. + +.. + +.. bpo: 40448 +.. date: 2020-06-15-12-22-53 +.. nonce: 1dk8Bu +.. section: Library + +:mod:`ensurepip` now disables the use of `pip` cache when installing the +bundled versions of `pip` and `setuptools`. Patch by Krzysztof Konopko. + +.. + +.. bpo: 40967 +.. date: 2020-06-15-00-13-57 +.. nonce: _dx3OO +.. section: Library + +Removed :meth:`asyncio.Task.current_task` and +:meth:`asyncio.Task.all_tasks`. Patch contributed by Rémi Lapeyre. + +.. + +.. bpo: 40924 +.. date: 2020-06-13-12-04-50 +.. nonce: SM_luS +.. section: Library + +Ensure ``importlib.resources.path`` returns an extant path for the +SourceFileLoader's resource reader. Avoids the regression identified in +master while a long-term solution is devised. + +.. + +.. bpo: 40955 +.. date: 2020-06-12-11-55-30 +.. nonce: huixCg +.. section: Library + +Fix a minor memory leak in :mod:`subprocess` module when extra_groups was +specified. + +.. + +.. bpo: 40855 +.. date: 2020-06-12-10-44-15 +.. nonce: jSot83 +.. section: Library + +The standard deviation and variance functions in the statistics module were +ignoring their mu and xbar arguments. + +.. + +.. bpo: 40939 +.. date: 2020-06-11-11-07-10 +.. nonce: -D5Asl +.. section: Library + +Use the new PEG parser when generating the stdlib :mod:`keyword` module. + +.. + +.. bpo: 23427 +.. date: 2020-06-08-18-59-16 +.. nonce: ilg1Cz +.. section: Library + +Add :data:`sys.orig_argv` attribute: the list of the original command line +arguments passed to the Python executable. + +.. + +.. bpo: 33689 +.. date: 2020-06-06-14-09-55 +.. nonce: EFUDH7 +.. section: Library + +Ignore empty or whitespace-only lines in .pth files. This matches the +documentated behavior. Before, empty lines caused the site-packages dir to +appear multiple times in sys.path. By Ido Michael, contributors Malcolm +Smith and Tal Einat. + +.. + +.. bpo: 40884 +.. date: 2020-06-06-02-42-26 +.. nonce: n7fOwS +.. section: Library + +Added a `defaults` parameter to :class:`logging.Formatter`, to allow +specifying default values for custom fields. Patch by Asaf Alon and Bar +Harel. + +.. + +.. bpo: 40876 +.. date: 2020-06-05-20-00-18 +.. nonce: zDhiZj +.. section: Library + +Clarify error message in the :mod:`csv` module. + +.. + +.. bpo: 39791 +.. date: 2020-06-05-19-29-10 +.. nonce: _CcO3d +.. section: Library + +Refresh importlib.metadata from importlib_metadata 1.6.1. + +.. + +.. bpo: 40807 +.. date: 2020-06-04-16-25-15 +.. nonce: yYyLWx +.. section: Library + +Stop codeop._maybe_compile, used by code.InteractiveInterpreter (and IDLE). +from emitting each warning three times. + +.. + +.. bpo: 32604 +.. date: 2020-06-02-23-49-07 +.. nonce: ZN4V4l +.. section: Library + +Fix reference leak in the :mod:`select` module when the module is imported +in a subinterpreter. + +.. + +.. bpo: 39791 +.. date: 2020-06-02-02-16-02 +.. nonce: StCJlA +.. section: Library + +Built-in loaders (SourceFileLoader and ZipImporter) now supply +``TraversableResources`` implementations for ``ResourceReader``, and the +fallback function has been removed. + +.. + +.. bpo: 39314 +.. date: 2020-06-01-02-16-29 +.. nonce: 0T9hlA +.. section: Library + +:class:`rlcompleter.Completer` and the standard Python shell now close the +parenthesis for functions that take no arguments. Patch contributed by Rémi +Lapeyre. + +.. + +.. bpo: 17005 +.. date: 2020-05-31-23-32-36 +.. nonce: JlRUGB +.. section: Library + +The topological sort functionality that was introduced initially in the +:mod:`functools` module has been moved to a new :mod:`graphlib` module to +better accommodate the new tools and keep the original scope of the +:mod:`functools` module. Patch by Pablo Galindo + +.. + +.. bpo: 40834 +.. date: 2020-05-31-15-52-18 +.. nonce: MO9_hb +.. section: Library + +Fix truncate when sending str object with_xxsubinterpreters.channel_send. + +.. + +.. bpo: 40755 +.. date: 2020-05-30-18-48-58 +.. nonce: IyOe2J +.. section: Library + +Add rich comparisons to collections.Counter(). + +.. + +.. bpo: 26407 +.. date: 2020-05-30-14-19-47 +.. nonce: MjWLO1 +.. section: Library + +Unexpected errors in calling the ``__iter__`` method are no longer masked by +``TypeError`` in :func:`csv.reader`, :func:`csv.writer.writerow` and +:meth:`csv.writer.writerows`. + +.. + +.. bpo: 39384 +.. date: 2020-05-30-12-44-29 +.. nonce: Iqxy3q +.. section: Library + +Fixed email.contentmanager to allow set_content() to set a null string. + +.. + +.. bpo: 40744 +.. date: 2020-05-30-08-10-23 +.. nonce: jKURVV +.. section: Library + +The :mod:`sqlite3` module uses SQLite API functions that require SQLite +v3.7.3 or higher. This patch removes support for older SQLite versions, and +explicitly requires SQLite 3.7.3 both at build, compile and runtime. Patch +by Sergey Fedoseev and Erlend E. Aasland. + +.. + +.. bpo: 40777 +.. date: 2020-05-28-17-32-29 +.. nonce: 1kJU6N +.. section: Library + +Initialize PyDateTime_IsoCalendarDateType.tp_base at run-time to avoid +errors on some compilers. + +.. + +.. bpo: 38488 +.. date: 2020-05-28-16-51-00 +.. nonce: hFQNgA +.. section: Library + +Update ensurepip to install pip 20.1.1 and setuptools 47.1.0. + +.. + +.. bpo: 40792 +.. date: 2020-05-27-22-19-42 +.. nonce: 87Yx01 +.. section: Library + +The result of :func:`operator.index` now always has exact type :class:`int`. +Previously, the result could have been an instance of a subclass of ``int``. + +.. + +.. bpo: 40767 +.. date: 2020-05-27-21-27-01 +.. nonce: L5MnVV +.. section: Library + +:mod:`webbrowser` now properly finds the default browser in pure Wayland +systems by checking the WAYLAND_DISPLAY environment variable. Patch +contributed by Jérémy Attali. + +.. + +.. bpo: 40791 +.. date: 2020-05-27-18-04-52 +.. nonce: IzpNor +.. section: Library + +:func:`hashlib.compare_digest` uses OpenSSL's ``CRYPTO_memcmp()`` function +when OpenSSL is available. + +.. + +.. bpo: 40795 +.. date: 2020-05-27-17-00-18 +.. nonce: eZSnHA +.. section: Library + +:mod:`ctypes` module: If ctypes fails to convert the result of a callback or +if a ctypes callback function raises an exception, sys.unraisablehook is now +called with an exception set. Previously, the error was logged into stderr +by :c:func:`PyErr_Print`. + +.. + +.. bpo: 16995 +.. date: 2020-05-27-00-09-52 +.. nonce: 4niOT7 +.. section: Library + +Add :func:`base64.b32hexencode` and :func:`base64.b32hexdecode` to support +the Base32 Encoding with Extended Hex Alphabet. + +.. + +.. bpo: 30008 +.. date: 2020-05-25-22-18-38 +.. nonce: CKC3td +.. section: Library + +Fix :mod:`ssl` code to be compatible with OpenSSL 1.1.x builds that use +``no-deprecated`` and ``--api=1.1.0``. + +.. + +.. bpo: 30064 +.. date: 2020-05-25-11-52-23 +.. nonce: 6CICsH +.. section: Library + +Fix asyncio ``loop.sock_*`` race condition issue + +.. + +.. bpo: 40759 +.. date: 2020-05-24-23-52-35 +.. nonce: DdZdaw +.. section: Library + +Deprecate the :mod:`symbol` module. + +.. + +.. bpo: 40756 +.. date: 2020-05-24-11-06-37 +.. nonce: 7ZH83z +.. section: Library + +The second argument (extra) of ``LoggerAdapter.__init__`` now defaults to +None. + +.. + +.. bpo: 37129 +.. date: 2020-05-23-04-18-00 +.. nonce: YoYoYo +.. section: Library + +Add a new :const:`os.RWF_APPEND` flag for :func:`os.pwritev`. + +.. + +.. bpo: 40737 +.. date: 2020-05-23-00-22-11 +.. nonce: iph-CM +.. section: Library + +Fix possible reference leak for :mod:`sqlite3` initialization. + +.. + +.. bpo: 40726 +.. date: 2020-05-22-12-45-58 +.. nonce: 7oBdMw +.. section: Library + +Handle cases where the ``end_lineno`` is ``None`` on +:func:`ast.increment_lineno`. + +.. + +.. bpo: 40698 +.. date: 2020-05-20-14-38-04 +.. nonce: zwl5Hc +.. section: Library + +``distutils`` upload creates SHA2-256 and Blake2b-256 digests. MD5 +digests is skipped if platform blocks MD5. + +.. + +.. bpo: 40695 +.. date: 2020-05-20-13-03-28 +.. nonce: lr4aIS +.. section: Library + +:mod:`hashlib` no longer falls back to builtin hash implementations when +OpenSSL provides a hash digest and the algorithm is blocked by security +policy. + +.. + +.. bpo: 9216 +.. date: 2020-05-20-12-53-20 +.. nonce: ps7Yf1 +.. section: Library + +func:`hashlib.new` passed ``usedforsecurity`` to OpenSSL EVP constructor +``_hashlib.new()``. test_hashlib and test_smtplib handle strict security +policy better. + +.. + +.. bpo: 40614 +.. date: 2020-05-18-22-41-02 +.. nonce: 8j3kmq +.. section: Library + +:func:`ast.parse` will not parse self documenting expressions in f-strings +when passed ``feature_version`` is less than ``(3, 8)``. + +.. + +.. bpo: 40626 +.. date: 2020-05-18-17-29-30 +.. nonce: NeZufF +.. section: Library + +Add h5 file extension as MIME Type application/x-hdf5, as per HDF Group +recommendation for HDF5 formatted data files. Patch contributed by Mark +Schwab. + +.. + +.. bpo: 25920 +.. date: 2020-05-18-15-38-25 +.. nonce: PxrLY8 +.. section: Library + +On macOS, when building Python for macOS 10.4 and older, which wasn't the +case for python.org macOS installer, :func:`socket.getaddrinfo` no longer +uses an internal lock to prevent race conditions when calling +``getaddrinfo()`` which is thread-safe since macOS 10.5. Python 3.9 requires +macOS 10.6 or newer. The internal lock caused random hang on fork when +another thread was calling :func:`socket.getaddrinfo`. The lock was also +used on FreeBSD older than 5.3, OpenBSD older than 201311 and NetBSD older +than 4. + +.. + +.. bpo: 40671 +.. date: 2020-05-18-15-26-31 +.. nonce: NeZ9Cy +.. section: Library + +Prepare ``_hashlib`` for :pep:`489` and use :c:func:`PyModule_AddType`. + +.. + +.. bpo: 32309 +.. date: 2020-05-17-02-03-09 +.. nonce: KM9psl +.. section: Library + +Added a new :term:`coroutine` :func:`asyncio.to_thread`. It is mainly used +for running IO-bound functions in a separate thread to avoid blocking the +event loop, and essentially works as a high-level version of +:meth:`~asyncio.loop.run_in_executor` that can directly take keyword +arguments. + +.. + +.. bpo: 36543 +.. date: 2020-05-15-21-14-45 +.. nonce: Jt-eSX +.. section: Library + +Restored the deprecated :mod:`xml.etree.cElementTree` module. + +.. + +.. bpo: 40611 +.. date: 2020-05-13-16-28-33 +.. nonce: ZCk0_c +.. section: Library + +:const:`~mmap.MAP_POPULATE` constant has now been added to the list of +exported :mod:`mmap` module flags. + +.. + +.. bpo: 39881 +.. date: 2020-05-07-22-00-12 +.. nonce: E1xsNv +.. section: Library + +PEP 554 for use in the test suite. (Patch By Joannah Nanjekye) + +.. + +.. bpo: 13097 +.. date: 2020-05-06-02-01-25 +.. nonce: Wh5xSK +.. section: Library + +``ctypes`` now raises an ``ArgumentError`` when a callback is invoked with +more than 1024 arguments. + +.. + +.. bpo: 39385 +.. date: 2020-04-23-18-21-19 +.. nonce: MIAyS7 +.. section: Library + +A new test assertion context-manager, :func:`unittest.assertNoLogs` will +ensure a given block of code emits no log messages using the logging module. +Contributed by Kit Yan Choi. + +.. + +.. bpo: 23082 +.. date: 2020-04-20-22-08-36 +.. nonce: iX90Id +.. section: Library + +Updated the error message and docs of PurePath.relative_to() to better +reflect the function behaviour. + +.. + +.. bpo: 40318 +.. date: 2020-04-18-14-16-02 +.. nonce: K2UdRx +.. section: Library + +Use SQLite3 trace v2 API, if it is available. + +.. + +.. bpo: 40105 +.. date: 2020-04-03-16-13-59 +.. nonce: hfM2c0 +.. section: Library + +ZipFile truncates files to avoid corruption when a shorter comment is +provided in append ("a") mode. Patch by Jan Mazur. + +.. + +.. bpo: 40084 +.. date: 2020-03-29-21-32-00 +.. nonce: MCYwcv +.. section: Library + +Fix ``Enum.__dir__``: dir(Enum.member) now includes attributes as well as +methods. + +.. + +.. bpo: 31122 +.. date: 2020-03-11-07-44-06 +.. nonce: zIQ80l +.. section: Library + +ssl.wrap_socket() now raises ssl.SSLEOFError rather than OSError when peer +closes connection during TLS negotiation + +.. + +.. bpo: 39728 +.. date: 2020-02-24-10-58-34 +.. nonce: kOOaHn +.. section: Library + +fix default `_missing_` so a duplicate `ValueError` is not set as the +`__context__` of the original `ValueError` + +.. + +.. bpo: 39244 +.. date: 2020-02-23-15-09-47 +.. nonce: aBK5IM +.. section: Library + +Fixed :class:`multiprocessing.context.get_all_start_methods` to properly +return the default method first on macOS. + +.. + +.. bpo: 39040 +.. date: 2019-12-15-18-47-20 +.. nonce: tKa0Qs +.. section: Library + +Fix parsing of invalid mime headers parameters by collapsing whitespace +between encoded words in a bare-quote-string. + +.. + +.. bpo: 38731 +.. date: 2019-11-13-07-37-11 +.. nonce: 9qmcSx +.. section: Library + +Add ``--quiet`` option to command-line interface of :mod:`py_compile`. Patch +by Gregory Schevchenko. + +.. + +.. bpo: 35714 +.. date: 2019-10-25-23-45-49 +.. nonce: fw3xb7 +.. section: Library + +:exc:`struct.error` is now raised if there is a null character in a +:mod:`struct` format string. + +.. + +.. bpo: 38144 +.. date: 2019-09-12-21-34-03 +.. nonce: 8uQCdd +.. section: Library + +Added the *root_dir* and *dir_fd* parameters in :func:`glob.glob`. + +.. + +.. bpo: 26543 +.. date: 2019-08-11-16-28-03 +.. nonce: X-TJZO +.. section: Library + +Fix :meth:`IMAP4.noop()` when debug mode is enabled (ex: ``imaplib.Debug = +3``). + +.. + +.. bpo: 12178 +.. date: 2019-05-31-23-54-28 +.. nonce: N6FLCZ +.. section: Library + +:func:`csv.writer` now correctly escapes *escapechar* when input contains +*escapechar*. Patch by Catalin Iacob, Berker Peksag, and Itay Elbirt. + +.. + +.. bpo: 36290 +.. date: 2019-03-17-19-01-53 +.. nonce: 7VXo_K +.. section: Library + +AST nodes are now raising :exc:`TypeError` on conflicting keyword arguments. +Patch contributed by Rémi Lapeyre. + +.. + +.. bpo: 33944 +.. date: 2019-03-01-01-56-23 +.. nonce: -82Pkt +.. section: Library + +Added site.py site-packages tracing in verbose mode. + +.. + +.. bpo: 35078 +.. date: 2018-10-27-09-37-03 +.. nonce: kweA3R +.. section: Library + +Refactor formatweekday, formatmonthname methods in LocaleHTMLCalendar and +LocaleTextCalendar classes in calendar module to call the base class +methods.This enables customizable CSS classes for LocaleHTMLCalendar. Patch +by Srinivas Reddy Thatiparthy + +.. + +.. bpo: 29620 +.. date: 2018-08-21-16-20-33 +.. nonce: xxx666 +.. section: Library + +:func:`~unittest.TestCase.assertWarns` no longer raises a +``RuntimeException`` when accessing a module's ``__warningregistry__`` +causes importation of a new module, or when a new module is imported in +another thread. Patch by Kernc. + +.. + +.. bpo: 31844 +.. date: 2018-07-30-12-48-17 +.. nonce: 0_GKsD +.. section: Library + +Remove ``ParserBase.error()`` method from the private and undocumented +``_markupbase`` module. :class:`html.parser.HTMLParser` is the only +subclass of ``ParserBase`` and its ``error()`` implementation was deprecated +in Python 3.4 and removed in Python 3.5. + +.. + +.. bpo: 34226 +.. date: 2018-07-29-12-14-54 +.. nonce: BE7zbu +.. section: Library + +Fix `cgi.parse_multipart` without content_length. Patch by Roger Duran + +.. + +.. bpo: 33660 +.. date: 2018-06-12-23-30-41 +.. nonce: AdDn5Z +.. section: Library + +Fix pathlib.PosixPath to resolve a relative path located on the root +directory properly. + +.. + +.. bpo: 28557 +.. date: 2018-06-07-22-04-01 +.. nonce: ViNJnK +.. section: Library + +Improve the error message for a misbehaving ``rawio.readinto`` + +.. + +.. bpo: 26680 +.. date: 2018-03-15-11-56-48 +.. nonce: Udkhn4 +.. section: Library + +The d.is_integer() method is added to the Decimal type, for compatibility +with other number types. + +.. + +.. bpo: 26680 +.. date: 2018-03-15-11-55-04 +.. nonce: eKAi85 +.. section: Library + +The x.is_integer() method is incorporated into the abstract types of the +numeric tower, Real, Rational and Integral, with appropriate default +implementations. + +.. + +.. bpo: 41428 +.. date: 2020-10-03-18-20-46 +.. nonce: _ju1NE +.. section: Documentation + +Add documentation for :pep:`604` (Allow writing union types as ``X | Y``). + +.. + +.. bpo: 41774 +.. date: 2020-09-24-15-35-13 +.. nonce: 5IqdGP +.. section: Documentation + +In Programming FAQ "Sequences (Tuples/Lists)" section, add "How do you +remove multiple items from a list". + +.. + +.. bpo: 35293 +.. date: 2020-09-12-17-37-13 +.. nonce: _cOwPD +.. section: Documentation + +Fix RemovedInSphinx40Warning when building the documentation. Patch by +Donghee Na. + +.. + +.. bpo: 37149 +.. date: 2020-09-10-07-48-02 +.. nonce: VD0rCv +.. section: Documentation + +Change Shipman tkinter doc link from archive.org to TkDocs. (The doc has +been removed from the NMT server.) The new link responds much faster and +includes a short explanatory note. + +.. + +.. bpo: 41726 +.. date: 2020-09-08-16-57-09 +.. nonce: g0UXrn +.. section: Documentation + +Update the refcounts info of ``PyType_FromModuleAndSpec``. + +.. + +.. bpo: 41624 +.. date: 2020-08-25-15-11-23 +.. nonce: ddjJlN +.. section: Documentation + +Fix the signature of :class:`typing.Coroutine`. + +.. + +.. bpo: 40204 +.. date: 2020-08-12-18-35-40 +.. nonce: C8A_pe +.. section: Documentation + +Enable Sphinx 3.2 ``c_allow_pre_v3`` option and disable +``c_warn_on_allowed_pre_v3`` option to make the documentation compatible +with Sphinx 2 and Sphinx 3. + +.. + +.. bpo: 41045 +.. date: 2020-07-27-20-46-17 +.. nonce: GFF6Ul +.. section: Documentation + +Add documentation for debug feature of f-strings. + +.. + +.. bpo: 41314 +.. date: 2020-07-25-14-20-00 +.. nonce: yrjko0 +.. section: Documentation + +Changed the release when ``from __future__ import annotations`` becomes the +default from ``4.0`` to ``3.10`` (following a change in PEP 563). + +.. + +.. bpo: 40979 +.. date: 2020-07-21-15-23-30 +.. nonce: pLA8rO +.. section: Documentation + +Refactored typing.rst, arranging more than 70 classes, functions, and +decorators into new sub-sections. + +.. + +.. bpo: 40552 +.. date: 2020-05-09-12-10-31 +.. nonce: _0uB73 +.. section: Documentation + +Fix in tutorial section 4.2. Code snippet is now correct. + +.. + +.. bpo: 39883 +.. date: 2020-03-07-03-53-39 +.. nonce: 1tnb4- +.. section: Documentation + +Make code, examples, and recipes in the Python documentation be licensed +under the more permissive BSD0 license in addition to the existing Python +2.0 license. + +.. + +.. bpo: 37703 +.. date: 2019-08-16-20-25-42 +.. nonce: Qm_l_H +.. section: Documentation + +Updated Documentation to comprehensively elaborate on the behaviour of +gather.cancel() + +.. + +.. bpo: 41939 +.. date: 2020-10-05-09-37-43 +.. nonce: P4OlbA +.. section: Tests + +Fix test_site.test_license_exists_at_url(): call +``urllib.request.urlcleanup()`` to reset the global +``urllib.request._opener``. Patch by Victor Stinner. + +.. + +.. bpo: 41731 +.. date: 2020-09-11-19-12-31 +.. nonce: Ivxh4U +.. section: Tests + +Make test_cmd_line_script pass with option '-vv'. + +.. + +.. bpo: 41602 +.. date: 2020-08-25-19-25-36 +.. nonce: Z64s0I +.. section: Tests + +Add tests for SIGINT handling in the runpy module. + +.. + +.. bpo: 41521 +.. date: 2020-08-11-14-59-13 +.. nonce: w2UYK7 +.. section: Tests + +:mod:`test.support`: Rename ``blacklist`` parameter of +:func:`~test.support.check__all__` to ``not_exported``. + +.. + +.. bpo: 41477 +.. date: 2020-08-07-17-28-49 +.. nonce: GrFexU +.. section: Tests + +Make ctypes optional in test_genericalias. + +.. + +.. bpo: 41085 +.. date: 2020-06-23-12-02-45 +.. nonce: JZKsyz +.. section: Tests + +Fix integer overflow in the :meth:`array.array.index` method on 64-bit +Windows for index larger than ``2**31``. + +.. + +.. bpo: 41069 +.. date: 2020-06-22-00-21-12 +.. nonce: bLZkX- +.. section: Tests + +:data:`test.support.TESTFN` and the current directory for tests when run via +``test.regrtest`` contain now non-ascii characters if possible. + +.. + +.. bpo: 38377 +.. date: 2020-06-17-18-00-21 +.. nonce: jfg4TH +.. section: Tests + +On Linux, skip tests using multiprocessing if the current user cannot create +a file in ``/dev/shm/`` directory. Add the +:func:`~test.support.skip_if_broken_multiprocessing_synchronize` function to +the :mod:`test.support` module. + +.. + +.. bpo: 41009 +.. date: 2020-06-17-17-27-07 +.. nonce: Rvn6OQ +.. section: Tests + +Fix use of ``support.require_{linux|mac|freebsd}_version()`` decorators as +class decorator. + +.. + +.. bpo: 41003 +.. date: 2020-06-17-15-07-14 +.. nonce: tiH_Fy +.. section: Tests + +Fix ``test_copyreg`` when ``numpy`` is installed: ``test.pickletester`` now +saves/restores warnings filters when importing ``numpy``, to ignore filters +installed by ``numpy``. + +.. + +.. bpo: 40964 +.. date: 2020-06-12-20-46-23 +.. nonce: OBzf2c +.. section: Tests + +Disable remote :mod:`imaplib` tests, host cyrus.andrew.cmu.edu is blocking +incoming connections. + +.. + +.. bpo: 40927 +.. date: 2020-06-09-18-48-18 +.. nonce: 67ylLg +.. section: Tests + +Fix test_binhex when run twice: it now uses import_fresh_module() to ensure +that it raises DeprecationWarning each time. + +.. + +.. bpo: 17258 +.. date: 2020-05-26-07-53-31 +.. nonce: X_IKTQ +.. section: Tests + +Skip some :mod:`multiprocessing` tests when MD5 hash digest is blocked. + +.. + +.. bpo: 31904 +.. date: 2020-04-09-15-40-03 +.. nonce: TJ4k3d +.. section: Tests + +Increase LOOPBACK_TIMEOUT to 10 for VxWorks RTOS. + +.. + +.. bpo: 38169 +.. date: 2019-09-14-13-20-27 +.. nonce: hurq4B +.. section: Tests + +Increase code coverage for SharedMemory and ShareableList + +.. + +.. bpo: 34401 +.. date: 2018-08-20-09-38-52 +.. nonce: eGxMPm +.. section: Tests + +Make test_gdb properly run on HP-UX. Patch by Michael Osipov. + +.. + +.. bpo: 38249 +.. date: 2020-09-28-21-56-51 +.. nonce: uzMCaZ +.. section: Build + +Update :c:macro:`Py_UNREACHABLE` to use __builtin_unreachable() if only the +compiler is able to use it. Patch by Donghee Na. + +.. + +.. bpo: 41617 +.. date: 2020-08-24-18-34-01 +.. nonce: sKKXz7 +.. section: Build + +Fix ``pycore_bitutils.h`` header file to support old clang versions: +``__builtin_bswap16()`` is not available in LLVM clang 3.0. + +.. + +.. bpo: 40204 +.. date: 2020-06-25-06-59-13 +.. nonce: GpD04D +.. section: Build + +Pin Sphinx version to 2.3.1 in ``Doc/Makefile``. + +.. + +.. bpo: 36020 +.. date: 2020-06-15-22-14-25 +.. nonce: wbiv0P +.. section: Build + +The C99 functions :c:func:`snprintf` and :c:func:`vsnprintf` are now +required to build Python. + +.. + +.. bpo: 40684 +.. date: 2020-06-08-19-57-05 +.. nonce: WIY2-i +.. section: Build + +``make install`` now uses the ``PLATLIBDIR`` variable for the destination +``lib-dynload/`` directory when ``./configure --with-platlibdir`` is used. + +.. + +.. bpo: 40683 +.. date: 2020-05-19-10-54-08 +.. nonce: W8JHrr +.. section: Build + +Fixed an issue where the :mod:`zoneinfo` module and its tests were not +included when Python is installed with ``make``. + +.. + +.. bpo: 41744 +.. date: 2020-09-11-17-59-33 +.. nonce: e_ugDQ +.. section: Windows + +Fixes automatic import of props file when using the Nuget package. + +.. + +.. bpo: 41627 +.. date: 2020-09-04-21-35-28 +.. nonce: sx2KN1 +.. section: Windows + +The user site directory for 32-bit now includes a ``-32`` suffix to +distinguish it from the 64-bit interpreter's directory. + +.. + +.. bpo: 41526 +.. date: 2020-08-13-22-40-58 +.. nonce: -i2bwb +.. section: Windows + +Fixed layout of final page of the installer by removing the special thanks +to Mark Hammond (with his permission). + +.. + +.. bpo: 41492 +.. date: 2020-08-06-16-59-10 +.. nonce: 2FQ9cM +.. section: Windows + +Fixes the description that appears in UAC prompts. + +.. + +.. bpo: 40948 +.. date: 2020-07-28-12-39-32 +.. nonce: ISUFO6 +.. section: Windows + +Improve post-install message to direct people to the "py" command. + +.. + +.. bpo: 41412 +.. date: 2020-07-28-11-55-43 +.. nonce: ME20KB +.. section: Windows + +The installer will now fail to install on Windows 7 and Windows 8. Further, +the UCRT dependency is now always downloaded on demand. + +.. + +.. bpo: 40741 +.. date: 2020-07-20-23-26-26 +.. nonce: C9sc_d +.. section: Windows + +Update Windows release to include SQLite 3.32.3. + +.. + +.. bpo: 41142 +.. date: 2020-06-28-12-40-41 +.. nonce: jpZzzh +.. section: Windows + +:mod:`msilib` now supports creating CAB files with non-ASCII file path and +adding files with non-ASCII file path to them. + +.. + +.. bpo: 41074 +.. date: 2020-06-24-21-30-42 +.. nonce: gaQc3C +.. section: Windows + +Fixed support of non-ASCII names in functions :func:`msilib.OpenDatabase` +and :func:`msilib.init_database` and non-ASCII SQL in method +:meth:`msilib.Database.OpenView`. + +.. + +.. bpo: 41039 +.. date: 2020-06-23-03-12-57 +.. nonce: 0hgd0s +.. section: Windows + +Stable ABI redirection DLL (python3.dll) now uses ``#pragma +comment(linker)`` for re-exporting. + +.. + +.. bpo: 40164 +.. date: 2020-06-12-13-13-44 +.. nonce: SPrSn5 +.. section: Windows + +Updates Windows OpenSSL to 1.1.1g + +.. + +.. bpo: 39631 +.. date: 2020-05-19-14-43-33 +.. nonce: Z5yXam +.. section: Windows + +Changes the registered MIME type for ``.py`` files on Windows to +``text/x-python`` instead of ``text/plain``. + +.. + +.. bpo: 40677 +.. date: 2020-05-19-04-11-12 +.. nonce: qQbLW8 +.. section: Windows + +Manually define IO_REPARSE_TAG_APPEXECLINK in case some old Windows SDK +doesn't have it. + +.. + +.. bpo: 37556 +.. date: 2019-07-11-06-11-09 +.. nonce: sygMUU +.. section: Windows + +Extend py.exe help to mention overrides via venv, shebang, environmental +variables & ini files. + +.. + +.. bpo: 41557 +.. date: 2020-08-26-09-31-37 +.. nonce: mcQ75z +.. section: macOS + +Update macOS installer to use SQLite 3.33.0. + +.. + +.. bpo: 39580 +.. date: 2020-06-25-06-09-00 +.. nonce: N_vJ9h +.. section: macOS + +Avoid opening Finder window if running installer from the command line. +Patch contributed by Rick Heil. + +.. + +.. bpo: 41100 +.. date: 2020-06-24-13-51-57 +.. nonce: mcHdc5 +.. section: macOS + +Fix configure error when building on macOS 11. Note that the current Python +release was released shortly after the first developer preview of macOS 11 +(Big Sur); there are other known issues with building and running on the +developer preview. Big Sur is expected to be fully supported in a future +bugfix release of Python 3.8.x and with 3.9.0. + +.. + +.. bpo: 40741 +.. date: 2020-06-19-14-19-08 +.. nonce: L7yTbm +.. section: macOS + +Update macOS installer to use SQLite 3.32.3. + +.. + +.. bpo: 41005 +.. date: 2020-06-17-13-45-15 +.. nonce: zZegdV +.. section: macOS + +fixed an XDG settings issue not allowing macos to open browser in +webbrowser.py + +.. + +.. bpo: 40741 +.. date: 2020-06-07-20-10-56 +.. nonce: 80A2BW +.. section: macOS + +Update macOS installer to use SQLite 3.32.2. + +.. + +.. bpo: 41775 +.. date: 2020-09-24-14-31-16 +.. nonce: sB8Vre +.. section: IDLE + +Use 'IDLE Shell' as shell title + +.. + +.. bpo: 35764 +.. date: 2020-09-22-11-13-45 +.. nonce: VoNa8y +.. section: IDLE + +Rewrite the Calltips doc section. + +.. + +.. bpo: 40181 +.. date: 2020-09-22-00-45-40 +.. nonce: hhQi3z +.. section: IDLE + +In calltips, stop reminding that '/' marks the end of positional-only +arguments. + +.. + +.. bpo: 41468 +.. date: 2020-08-09-13-42-55 +.. nonce: zkP0_Y +.. section: IDLE + +Improve IDLE run crash error message (which users should never see). + +.. + +.. bpo: 41373 +.. date: 2020-07-24-17-49-58 +.. nonce: YQIPu_ +.. section: IDLE + +Save files loaded with no line ending, as when blank, or different line +endings, by setting its line ending to the system default. Fix regression in +3.8.4 and 3.9.0b4. + +.. + +.. bpo: 41300 +.. date: 2020-07-16-17-39-06 +.. nonce: wRixNb +.. section: IDLE + +Save files with non-ascii chars. Fix regression released in 3.9.0b4 and +3.8.4. + +.. + +.. bpo: 37765 +.. date: 2020-07-07-18-44-30 +.. nonce: umc1o8 +.. section: IDLE + +Add keywords to module name completion list. Rewrite Completions section of +IDLE doc. + +.. + +.. bpo: 41152 +.. date: 2020-06-29-14-51-15 +.. nonce: d6mV0C +.. section: IDLE + +The encoding of ``stdin``, ``stdout`` and ``stderr`` in IDLE is now always +UTF-8. + +.. + +.. bpo: 41144 +.. date: 2020-06-27-17-02-00 +.. nonce: JoFGIX +.. section: IDLE + +Make Open Module open a special module such as os.path. + +.. + +.. bpo: 39885 +.. date: 2020-05-29-18-21-58 +.. nonce: zB_-bN +.. section: IDLE + +Make context menu Cut and Copy work again when right-clicking within a +selection. + +.. + +.. bpo: 40723 +.. date: 2020-05-24-06-19-43 +.. nonce: AJLd4U +.. section: IDLE + +Make test_idle pass when run after import. + +.. + +.. bpo: 41936 +.. date: 2020-10-05-01-25-23 +.. nonce: 1gb5ra +.. section: C API + +Removed undocumented macros ``Py_ALLOW_RECURSION`` and +``Py_END_ALLOW_RECURSION`` and the ``recursion_critical`` field of the +:c:type:`PyInterpreterState` structure. + +.. + +.. bpo: 41692 +.. date: 2020-10-02-00-57-34 +.. nonce: fDScsF +.. section: C API + +The ``PyUnicode_InternImmortal()`` function is now deprecated and will be +removed in Python 3.12: use :c:func:`PyUnicode_InternInPlace` instead. Patch +by Victor Stinner. + +.. + +.. bpo: 41842 +.. date: 2020-09-27-20-43-16 +.. nonce: bCakAj +.. section: C API + +Add :c:func:`PyCodec_Unregister` function to unregister a codec search +function. + +.. + +.. bpo: 41834 +.. date: 2020-09-22-14-47-12 +.. nonce: nrOrDU +.. section: C API + +Remove the ``_Py_CheckRecursionLimit`` variable: it has been replaced by +``ceval.recursion_limit`` of the :c:type:`PyInterpreterState` structure. +Patch by Victor Stinner. + +.. + +.. bpo: 41689 +.. date: 2020-09-01-23-39-45 +.. nonce: zxHbLB +.. section: C API + +Types created with :c:func:`PyType_FromSpec` now make any signature in their +``tp_doc`` slot accessible from ``__text_signature__``. + +.. + +.. bpo: 41524 +.. date: 2020-08-12-17-09-06 +.. nonce: u6Xfr2 +.. section: C API + +Fix bug in PyOS_mystrnicmp and PyOS_mystricmp that incremented pointers +beyond the end of a string. + +.. + +.. bpo: 41324 +.. date: 2020-08-10-16-05-08 +.. nonce: waZD35 +.. section: C API + +Add a minimal decimal capsule API. The API supports fast conversions +between Decimals up to 38 digits and their triple representation as a C +struct. + +.. + +.. bpo: 30155 +.. date: 2020-07-26-19-39-45 +.. nonce: rHZRJ_ +.. section: C API + +Add :c:func:`PyDateTime_DATE_GET_TZINFO` and +:c:func:`PyDateTime_TIME_GET_TZINFO` macros for accessing the ``tzinfo`` +attributes of :class:`datetime.datetime` and :class:`datetime.time` objects. + +.. + +.. bpo: 40170 +.. date: 2020-07-08-10-14-52 +.. nonce: N6Qx1i +.. section: C API + +Revert :c:func:`PyType_HasFeature` change: it reads again directly the +:c:member:`PyTypeObject.tp_flags` member when the limited C API is not used, +rather than always calling :c:func:`PyType_GetFlags` which hides +implementation details. + +.. + +.. bpo: 41123 +.. date: 2020-06-29-15-49-36 +.. nonce: wYY4E1 +.. section: C API + +Remove ``PyUnicode_AsUnicodeCopy``. + +.. + +.. bpo: 41123 +.. date: 2020-06-29-11-33-49 +.. nonce: qFevek +.. section: C API + +Removed ``PyLong_FromUnicode()``. + +.. + +.. bpo: 41123 +.. date: 2020-06-28-11-39-22 +.. nonce: sjJWjQ +.. section: C API + +Removed ``PyUnicode_GetMax()``. + +.. + +.. bpo: 41123 +.. date: 2020-06-26-13-29-25 +.. nonce: bRa1oy +.. section: C API + +Removed ``Py_UNICODE_str*`` functions manipulating ``Py_UNICODE*`` strings. + +.. + +.. bpo: 41103 +.. date: 2020-06-24-22-57-07 +.. nonce: doojgE +.. section: C API + +``PyObject_AsCharBuffer()``, ``PyObject_AsReadBuffer()``, +``PyObject_CheckReadBuffer()``, and ``PyObject_AsWriteBuffer()`` are +removed. Please migrate to new buffer protocol; :c:func:`PyObject_GetBuffer` +and :c:func:`PyBuffer_Release`. + +.. + +.. bpo: 36346 +.. date: 2020-06-17-20-31-12 +.. nonce: mwIyxi +.. section: C API + +Raises DeprecationWarning for ``PyUnicode_FromUnicode(NULL, size)`` and +``PyUnicode_FromStringAndSize(NULL, size)`` with ``size > 0``. + +.. + +.. bpo: 36346 +.. date: 2020-06-17-11-24-00 +.. nonce: fTMr3S +.. section: C API + +Mark ``Py_UNICODE_COPY``, ``Py_UNICODE_FILL``, ``PyUnicode_WSTR_LENGTH``, +``PyUnicode_FromUnicode``, ``PyUnicode_AsUnicode``, and +``PyUnicode_AsUnicodeAndSize`` as deprecated in C. Remove +``Py_UNICODE_MATCH`` which was deprecated and broken since Python 3.3. + +.. + +.. bpo: 40989 +.. date: 2020-06-15-23-17-51 +.. nonce: tlzG3r +.. section: C API + +The :c:func:`PyObject_INIT` and :c:func:`PyObject_INIT_VAR` macros become +aliases to, respectively, :c:func:`PyObject_Init` and +:c:func:`PyObject_InitVar` functions. + +.. + +.. bpo: 36020 +.. date: 2020-06-15-16-46-01 +.. nonce: djI6jw +.. section: C API + +On Windows, ``#include "pyerrors.h"`` no longer defines ``snprintf`` and +``vsnprintf`` macros. + +.. + +.. bpo: 40943 +.. date: 2020-06-10-18-37-26 +.. nonce: i4q7rK +.. section: C API + +The ``PY_SSIZE_T_CLEAN`` macro must now be defined to use +:c:func:`PyArg_ParseTuple` and :c:func:`Py_BuildValue` formats which use +``#``: ``es#``, ``et#``, ``s#``, ``u#``, ``y#``, ``z#``, ``U#`` and ``Z#``. +See :ref:`Parsing arguments and building values <arg-parsing>` and the +:pep:`353`. + +.. + +.. bpo: 40910 +.. date: 2020-06-08-15-59-06 +.. nonce: L56oI0 +.. section: C API + +Export explicitly the :c:func:`Py_GetArgcArgv` function to the C API and +document the function. Previously, it was exported implicitly which no +longer works since Python is built with ``-fvisibility=hidden``. + +.. + +.. bpo: 40724 +.. date: 2020-06-04-08-01-23 +.. nonce: qIIdSi +.. section: C API + +Allow defining buffer slots in type specs. + +.. + +.. bpo: 40679 +.. date: 2020-06-03-17-48-13 +.. nonce: 3sgWma +.. section: C API + +Fix a ``_PyEval_EvalCode()`` crash if *qualname* argument is NULL. + +.. + +.. bpo: 40839 +.. date: 2020-06-01-20-47-49 +.. nonce: bAi52Z +.. section: C API + +Calling :c:func:`PyDict_GetItem` without :term:`GIL` held had been allowed +for historical reason. It is no longer allowed. + +.. + +.. bpo: 40826 +.. date: 2020-06-01-16-12-37 +.. nonce: zQzFoK +.. section: C API + +:c:func:`PyOS_InterruptOccurred` now fails with a fatal error if it is +called with the GIL released. + +.. + +.. bpo: 40792 +.. date: 2020-05-27-11-02-15 +.. nonce: pBw2Bb +.. section: C API + +The result of :c:func:`PyNumber_Index` now always has exact type +:class:`int`. Previously, the result could have been an instance of a +subclass of ``int``. + +.. + +.. bpo: 39573 +.. date: 2020-05-26-16-21-47 +.. nonce: depAgq +.. section: C API + +Convert :c:func:`Py_REFCNT` and :c:func:`Py_SIZE` macros to static inline +functions. They cannot be used as l-value anymore: use +:c:func:`Py_SET_REFCNT` and :c:func:`Py_SET_SIZE` to set an object reference +count and size. This change is backward incompatible on purpose, to prepare +the C API for an opaque :c:type:`PyObject` structure. + +.. + +.. bpo: 40703 +.. date: 2020-05-20-19-11-12 +.. nonce: qQXfW8 +.. section: C API + +The PyType_FromSpec*() functions no longer overwrite the type's "__module__" +attribute if it is set via "Py_tp_members" or "Py_tp_getset". + +.. + +.. bpo: 39583 +.. date: 2020-02-08-08-01-35 +.. nonce: qURKSl +.. section: C API + +Remove superfluous "extern C" declarations from ``Include/cpython/*.h``. diff --git a/Misc/NEWS.d/3.10.0a2.rst b/Misc/NEWS.d/3.10.0a2.rst new file mode 100644 index 00000000..78f43776 --- /dev/null +++ b/Misc/NEWS.d/3.10.0a2.rst @@ -0,0 +1,912 @@ +.. bpo: 42103 +.. date: 2020-10-23-19-19-30 +.. nonce: cILT66 +.. release date: 2020-11-03 +.. section: Security + +Prevented potential DoS attack via CPU and RAM exhaustion when processing +malformed Apple Property List files in binary format. + +.. + +.. bpo: 42051 +.. date: 2020-10-19-10-56-27 +.. nonce: EU_B7u +.. section: Security + +The :mod:`plistlib` module no longer accepts entity declarations in XML +plist files to avoid XML vulnerabilities. This should not affect users as +entity declarations are not used in regular plist files. + +.. + +.. bpo: 42236 +.. date: 2020-11-01-21-21-38 +.. nonce: MPx-NK +.. section: Core and Builtins + +If the ``nl_langinfo(CODESET)`` function returns an empty string, Python now +uses UTF-8 as the filesystem encoding. Patch by Victor Stinner. + +.. + +.. bpo: 42218 +.. date: 2020-10-31-17-50-23 +.. nonce: Dp_Z3v +.. section: Core and Builtins + +Fixed a bug in the PEG parser that was causing crashes in debug mode. Now +errors are checked in left-recursive rules to avoid cases where such errors +do not get handled in time and appear as long-distance crashes in other +places. + +.. + +.. bpo: 42214 +.. date: 2020-10-30-22-16-30 +.. nonce: lXskM_ +.. section: Core and Builtins + +Fixed a possible crash in the PEG parser when checking for the '!=' token in +the ``barry_as_flufl`` rule. Patch by Pablo Galindo. + +.. + +.. bpo: 42206 +.. date: 2020-10-30-13-11-01 +.. nonce: xxssR8 +.. section: Core and Builtins + +Propagate and raise the errors caused by :c:func:`PyAST_Validate` in the +parser. + +.. + +.. bpo: 41796 +.. date: 2020-10-29-12-49-08 +.. nonce: tkGdHq +.. section: Core and Builtins + +The :mod:`ast` module internal state is now per interpreter. Patch by Victor +Stinner. + +.. + +.. bpo: 42143 +.. date: 2020-10-27-21-34-05 +.. nonce: N6KXUO +.. section: Core and Builtins + +Fix handling of errors during creation of ``PyFunctionObject``, which +resulted in operations on uninitialized memory. Patch by Yonatan +Goldschmidt. + +.. + +.. bpo: 41659 +.. date: 2020-10-27-18-32-49 +.. nonce: d4a-8o +.. section: Core and Builtins + +Fix a bug in the parser, where a curly brace following a `primary` didn't +fail immediately. This led to invalid expressions like `a {b}` to throw a +:exc:`SyntaxError` with a wrong offset, or invalid expressions ending with a +curly brace like `a {` to not fail immediately in the REPL. + +.. + +.. bpo: 42150 +.. date: 2020-10-25-21-14-18 +.. nonce: b70u_T +.. section: Core and Builtins + +Fix possible buffer overflow in the new parser when checking for +continuation lines. Patch by Pablo Galindo. + +.. + +.. bpo: 42123 +.. date: 2020-10-23-02-43-24 +.. nonce: 64gJWC +.. section: Core and Builtins + +Run the parser two times. On the first run, disable all the rules that only +generate better error messages to gain performance. If there's a parse +failure, run the parser a second time with those enabled. + +.. + +.. bpo: 42093 +.. date: 2020-10-20-04-24-07 +.. nonce: ooZZNh +.. section: Core and Builtins + +The ``LOAD_ATTR`` instruction now uses new "per opcode cache" mechanism and +it is about 36% faster now. Patch by Pablo Galindo and Yury Selivanov. + +.. + +.. bpo: 42030 +.. date: 2020-10-15-21-55-32 +.. nonce: PmU2CA +.. section: Core and Builtins + +Support for the legacy AIX-specific shared library loading support has been +removed. All versions of AIX since 4.3 have supported and defaulted to using +the common Unix mechanism instead. + +.. + +.. bpo: 41984 +.. date: 2020-10-14-16-19-43 +.. nonce: SEtKMr +.. section: Core and Builtins + +The garbage collector now tracks all user-defined classes. Patch by Brandt +Bucher. + +.. + +.. bpo: 41993 +.. date: 2020-10-10-13-53-52 +.. nonce: YMzixQ +.. section: Core and Builtins + +Fixed potential issues with removing not completely initialized module from +``sys.modules`` when import fails. + +.. + +.. bpo: 41979 +.. date: 2020-10-09-10-55-50 +.. nonce: ImXIk2 +.. section: Core and Builtins + +Star-unpacking is now allowed for with item's targets in the PEG parser. + +.. + +.. bpo: 41974 +.. date: 2020-10-08-09-58-19 +.. nonce: 8B-q8O +.. section: Core and Builtins + +Removed special methods ``__int__``, ``__float__``, ``__floordiv__``, +``__mod__``, ``__divmod__``, ``__rfloordiv__``, ``__rmod__`` and +``__rdivmod__`` of the :class:`complex` class. They always raised a +:exc:`TypeError`. + +.. + +.. bpo: 41902 +.. date: 2020-10-02-13-32-05 +.. nonce: ZKTxzW +.. section: Core and Builtins + +Micro optimization when compute :c:member:`~PySequenceMethods.sq_item` and +:c:member:`~PyMappingMethods.mp_subscript` of :class:`range`. Patch by +Donghee Na. + +.. + +.. bpo: 41894 +.. date: 2020-10-02-11-35-33 +.. nonce: ffmtOt +.. section: Core and Builtins + +When loading a native module and a load failure occurs, prevent a possible +UnicodeDecodeError when not running in a UTF-8 locale by decoding the load +error message using the current locale's encoding. + +.. + +.. bpo: 41902 +.. date: 2020-10-01-22-44-23 +.. nonce: iLoMVF +.. section: Core and Builtins + +Micro optimization for range.index if step is 1. Patch by Donghee Na. + +.. + +.. bpo: 41435 +.. date: 2020-08-07-13-42-48 +.. nonce: qPWjJA +.. section: Core and Builtins + +Add `sys._current_exceptions()` function to retrieve a dictionary mapping +each thread's identifier to the topmost exception currently active in that +thread at the time the function is called. + +.. + +.. bpo: 38605 +.. date: 2020-05-27-16-08-16 +.. nonce: rcs2uK +.. section: Core and Builtins + +Enable ``from __future__ import annotations`` (:pep:`563`) by default. The +values found in :attr:`__annotations__` dicts are now strings, e.g. ``{"x": +"int"}`` instead of ``{"x": int}``. + +.. + +.. bpo: 35455 +.. date: 2020-11-02-14-10-48 +.. nonce: Q1xTIo +.. section: Library + +On Solaris, :func:`~time.thread_time` is now implemented with +``gethrvtime()`` because ``clock_gettime(CLOCK_THREAD_CPUTIME_ID)`` is not +always available. Patch by Jakub Kulik. + +.. + +.. bpo: 42233 +.. date: 2020-11-02-01-31-15 +.. nonce: YxRj-h +.. section: Library + +The :func:`repr` of :mod:`typing` types containing :ref:`Generic Alias Types +<types-genericalias>` previously did not show the parameterized types in the +``GenericAlias``. They have now been changed to do so. + +.. + +.. bpo: 29566 +.. date: 2020-10-31-13-28-36 +.. nonce: 6aDbty +.. section: Library + +``binhex.binhex()`` consistently writes macOS 9 line endings. + +.. + +.. bpo: 26789 +.. date: 2020-10-31-01-16-49 +.. nonce: 9BdNAt +.. section: Library + +The :class:`logging.FileHandler` class now keeps a reference to the builtin +:func:`open` function to be able to open or reopen the file during Python +finalization. Fix errors like: ``NameError: name 'open' is not defined``. +Patch by Victor Stinner. + +.. + +.. bpo: 42157 +.. date: 2020-10-26-23-29-16 +.. nonce: 4wuwTe +.. section: Library + +Removed the ``unicodedata.ucnhash_CAPI`` attribute which was an internal +PyCapsule object. The related private ``_PyUnicode_Name_CAPI`` structure was +moved to the internal C API. Patch by Victor Stinner. + +.. + +.. bpo: 42157 +.. date: 2020-10-26-19-08-07 +.. nonce: Bdpa04 +.. section: Library + +Convert the :mod:`unicodedata` extension module to the multiphase +initialization API (:pep:`489`) and convert the ``unicodedata.UCD`` static +type to a heap type. Patch by Mohamed Koubaa and Victor Stinner. + +.. + +.. bpo: 42146 +.. date: 2020-10-25-19-25-02 +.. nonce: 6A8uvS +.. section: Library + +Fix memory leak in :func:`subprocess.Popen` in case an uid (gid) specified +in `user` (`group`, `extra_groups`) overflows `uid_t` (`gid_t`). + +.. + +.. bpo: 42103 +.. date: 2020-10-23-19-20-14 +.. nonce: C5obK2 +.. section: Library + +:exc:`~plistlib.InvalidFileException` and :exc:`RecursionError` are now the +only errors caused by loading malformed binary Plist file (previously +ValueError and TypeError could be raised in some specific cases). + +.. + +.. bpo: 41490 +.. date: 2020-10-23-08-54-47 +.. nonce: -Yk6OD +.. section: Library + +In ``importlib.resources``, ``.path`` method is more aggressive about +releasing handles to zipfile objects early, enabling use-cases like certifi +to leave the context open but delete the underlying zip file. + +.. + +.. bpo: 41052 +.. date: 2020-10-21-23-45-02 +.. nonce: 3N7J2J +.. section: Library + +Pickling heap types implemented in C with protocols 0 and 1 raises now an +error instead of producing incorrect data. + +.. + +.. bpo: 42089 +.. date: 2020-10-19-16-53-19 +.. nonce: R1dthW +.. section: Library + +In ``importlib.metadata.PackageNotFoundError``, make reference to the +package metadata being missing to improve the user experience. + +.. + +.. bpo: 41491 +.. date: 2020-10-19-14-02-09 +.. nonce: d1BUWH +.. section: Library + +plistlib: fix parsing XML plists with hexadecimal integer values + +.. + +.. bpo: 42065 +.. date: 2020-10-17-23-17-18 +.. nonce: 85BsRA +.. section: Library + +Fix an incorrectly formatted error from :meth:`_codecs.charmap_decode` when +called with a mapped value outside the range of valid Unicode code points. +PR by Max Bernstein. + +.. + +.. bpo: 41966 +.. date: 2020-10-17-07-52-53 +.. nonce: gwEQRZ +.. section: Library + +Fix pickling pure Python :class:`datetime.time` subclasses. Patch by Dean +Inwood. + +.. + +.. bpo: 19270 +.. date: 2020-10-16-22-48-01 +.. nonce: jd_gkA +.. section: Library + +:meth:`sched.scheduler.cancel()` will now cancel the correct event, if two +events with same priority are scheduled for the same time. Patch by Bar +Harel. + +.. + +.. bpo: 28660 +.. date: 2020-10-16-16-08-04 +.. nonce: eX9pvD +.. section: Library + +:func:`textwrap.wrap` now attempts to break long words after hyphens when +``break_long_words=True`` and ``break_on_hyphens=True``. + +.. + +.. bpo: 35823 +.. date: 2020-10-16-07-45-35 +.. nonce: SNQo56 +.. section: Library + +Use ``vfork()`` instead of ``fork()`` for :func:`subprocess.Popen` on Linux +to improve performance in cases where it is deemed safe. + +.. + +.. bpo: 42043 +.. date: 2020-10-15-17-20-37 +.. nonce: OS0p_v +.. section: Library + +Add support for ``zipfile.Path`` inheritance. ``zipfile.Path.is_file()`` now +returns False for non-existent names. ``zipfile.Path`` objects now expose a +``.filename`` attribute and rely on that to resolve ``.name`` and +``.parent`` when the ``Path`` object is at the root of the zipfile. + +.. + +.. bpo: 42021 +.. date: 2020-10-12-21-21-24 +.. nonce: 8yv_8- +.. section: Library + +Fix possible ref leaks in :mod:`sqlite3` module init. + +.. + +.. bpo: 39101 +.. date: 2020-10-11-21-43-03 +.. nonce: -I49Pm +.. section: Library + +Fixed tests using IsolatedAsyncioTestCase from hanging on BaseExceptions. + +.. + +.. bpo: 41976 +.. date: 2020-10-08-18-22-28 +.. nonce: Svm0wb +.. section: Library + +Fixed a bug that was causing :func:`ctypes.util.find_library` to return +``None`` when triying to locate a library in an environment when gcc>=9 is +available and ``ldconfig`` is not. Patch by Pablo Galindo + +.. + +.. bpo: 41943 +.. date: 2020-10-07-18-36-03 +.. nonce: Pt55fT +.. section: Library + +Fix bug where TestCase.assertLogs doesn't correctly filter messages by +level. + +.. + +.. bpo: 41923 +.. date: 2020-10-03-23-14-50 +.. nonce: Buonw9 +.. section: Library + +Implement :pep:`613`, introducing :data:`typing.TypeAlias` annotation. + +.. + +.. bpo: 41905 +.. date: 2020-10-01-21-11-03 +.. nonce: _JpjR4 +.. section: Library + +A new function in abc: *update_abstractmethods* to re-calculate an abstract +class's abstract status. In addition, *dataclass* has been changed to call +this function. + +.. + +.. bpo: 23706 +.. date: 2020-09-30-11-05-11 +.. nonce: dHTGjF +.. section: Library + +Added *newline* parameter to ``pathlib.Path.write_text()``. + +.. + +.. bpo: 41876 +.. date: 2020-09-29-16-23-54 +.. nonce: QicdDU +.. section: Library + +Tkinter font class repr uses font name + +.. + +.. bpo: 41831 +.. date: 2020-09-22-11-07-50 +.. nonce: k-Eop_ +.. section: Library + +``str()`` for the ``type`` attribute of the ``tkinter.Event`` object always +returns now the numeric code returned by Tk instead of the name of the event +type. + +.. + +.. bpo: 39337 +.. date: 2020-09-13-02-02-18 +.. nonce: L3NXTt +.. section: Library + +:func:`encodings.normalize_encoding` now ignores non-ASCII characters. + +.. + +.. bpo: 41747 +.. date: 2020-09-08-23-41-29 +.. nonce: M6wLKv +.. section: Library + +Ensure all methods that generated from :func:`dataclasses.dataclass` objects +now have the proper ``__qualname__`` attribute referring to the class they +belong to. Patch by Batuhan Taskaya. + +.. + +.. bpo: 30681 +.. date: 2020-09-04-17-33-04 +.. nonce: LR4fnY +.. section: Library + +Handle exceptions caused by unparsable date headers when using email +"default" policy. Patch by Tim Bell, Georges Toth + +.. + +.. bpo: 41586 +.. date: 2020-08-19-08-32-13 +.. nonce: IYjmjK +.. section: Library + +Add F_SETPIPE_SZ and F_GETPIPE_SZ to fcntl module. Allow setting pipesize on +subprocess.Popen. + +.. + +.. bpo: 41229 +.. date: 2020-07-19-20-10-41 +.. nonce: p8rJa2 +.. section: Library + +Add ``contextlib.aclosing`` for deterministic cleanup of async generators +which is analogous to ``contextlib.closing`` for non-async generators. Patch +by Joongi Kim and John Belmonte. + +.. + +.. bpo: 16396 +.. date: 2020-07-08-09-45-00 +.. nonce: z8o8Pn +.. section: Library + +Allow ``ctypes.wintypes`` to be imported on non-Windows systems. + +.. + +.. bpo: 4356 +.. date: 2020-05-31-10-48-47 +.. nonce: P8kXqp +.. section: Library + +Add a key function to the bisect module. + +.. + +.. bpo: 40592 +.. date: 2020-05-14-16-01-34 +.. nonce: Cmk855 +.. section: Library + +:func:`shutil.which` now ignores empty entries in :envvar:`PATHEXT` instead +of treating them as a match. + +.. + +.. bpo: 40492 +.. date: 2020-05-04-12-16-00 +.. nonce: ONk9Na +.. section: Library + +Fix ``--outfile`` for :mod:`cProfile` / :mod:`profile` not writing the +output file in the original directory when the program being profiled +changes the working directory. PR by Anthony Sottile. + +.. + +.. bpo: 34204 +.. date: 2020-04-21-17-18-33 +.. nonce: 9wXTtY +.. section: Library + +The :mod:`shelve` module now uses :const:`pickle.DEFAULT_PROTOCOL` by default +instead of :mod:`pickle` protocol ``3``. + +.. + +.. bpo: 27321 +.. date: 2020-01-19-18-40-26 +.. nonce: 8e6SpM +.. section: Library + +Fixed KeyError exception when flattening an email to a string attempts to +replace a non-existent Content-Transfer-Encoding header. + +.. + +.. bpo: 38976 +.. date: 2019-12-05-05-22-49 +.. nonce: 5MG7Uu +.. section: Library + +The :mod:`http.cookiejar` module now supports the parsing of cookies in +CURL-style cookiejar files through MozillaCookieJar on all platforms. +Previously, such cookie entries would be silently ignored when loading a +cookiejar with such entries. + +Additionally, the HTTP Only attribute is persisted in the object, and will +be correctly written to file if the MozillaCookieJar object is subsequently +dumped. + +.. + +.. bpo: 42061 +.. date: 2020-10-28-21-39-45 +.. nonce: _x-0sg +.. section: Documentation + +Document __format__ functionality for IP addresses. + +.. + +.. bpo: 41910 +.. date: 2020-10-21-14-40-54 +.. nonce: CzBMit +.. section: Documentation + +Document the default implementation of `object.__eq__`. + +.. + +.. bpo: 42010 +.. date: 2020-10-21-02-21-14 +.. nonce: 76vJ0u +.. section: Documentation + +Clarify that subscription expressions are also valid for certain +:term:`classes <class>` and :term:`types <type>` in the standard library, +and for user-defined classes and types if the classmethod +:meth:`__class_getitem__` is provided. + +.. + +.. bpo: 41805 +.. date: 2020-10-10-01-36-37 +.. nonce: l-CGv5 +.. section: Documentation + +Documented :ref:`generic alias type <types-genericalias>` and +:data:`types.GenericAlias`. Also added an entry in glossary for +:term:`generic types <generic type>`. + +.. + +.. bpo: 39693 +.. date: 2020-02-24-09-02-05 +.. nonce: QXw0Fm +.. section: Documentation + +Fix tarfile's extractfile documentation + +.. + +.. bpo: 39416 +.. date: 2020-01-22-05-14-53 +.. nonce: uYjhEm +.. section: Documentation + +Document some restrictions on the default string representations of numeric +classes. + +.. + +.. bpo: 41739 +.. date: 2020-10-12-00-11-47 +.. nonce: wSCc4K +.. section: Tests + +Fix test_logging.test_race_between_set_target_and_flush(): the test now +waits until all threads complete to avoid leaking running threads. + +.. + +.. bpo: 41970 +.. date: 2020-10-08-14-00-17 +.. nonce: aZ8QFf +.. section: Tests + +Avoid a test failure in ``test_lib2to3`` if the module has already imported +at the time the test executes. Patch by Pablo Galindo. + +.. + +.. bpo: 41944 +.. date: 2020-10-05-17-43-46 +.. nonce: rf1dYb +.. section: Tests + +Tests for CJK codecs no longer call ``eval()`` on content received via HTTP. + +.. + +.. bpo: 41306 +.. date: 2020-08-03-13-44-37 +.. nonce: VDoWXI +.. section: Tests + +Fixed a failure in ``test_tk.test_widgets.ScaleTest`` happening when +executing the test with Tk 8.6.10. + +.. + +.. bpo: 38980 +.. date: 2020-10-21-18-31-54 +.. nonce: xz7BNd +.. section: Build + +Add ``-fno-semantic-interposition`` to both the compile and link line when +building with ``--enable-optimizations``. Patch by Victor Stinner and Pablo +Galindo. + +.. + +.. bpo: 38439 +.. date: 2020-10-20-13-19-42 +.. nonce: eMLi-t +.. section: Windows + +Updates the icons for IDLE in the Windows Store package. + +.. + +.. bpo: 38252 +.. date: 2020-10-18-18-43-45 +.. nonce: 7Nlepg +.. section: Windows + +Use 8-byte step to detect ASCII sequence in 64-bit Windows build. + +.. + +.. bpo: 39107 +.. date: 2020-09-24-23-09-40 +.. nonce: GbUZvD +.. section: Windows + +Update Tcl and Tk to 8.6.10 in Windows installer. + +.. + +.. bpo: 41557 +.. date: 2020-08-26-09-35-06 +.. nonce: vt00cQ +.. section: Windows + +Update Windows installer to use SQLite 3.33.0. + +.. + +.. bpo: 38324 +.. date: 2020-05-30-02-46-43 +.. nonce: 476M-5 +.. section: Windows + +Avoid Unicode errors when accessing certain locale data on Windows. + +.. + +.. bpo: 41471 +.. date: 2020-10-19-12-25-19 +.. nonce: gwA7un +.. section: macOS + +Ignore invalid prefix lengths in system proxy excludes. + +.. + +.. bpo: 33987 +.. date: 2020-10-24-21-27-37 +.. nonce: fIh9JL +.. section: IDLE + +Mostly finish using ttk widgets, mainly for editor, settings, and searches. +Some patches by Mark Roseman. + +.. + +.. bpo: 40511 +.. date: 2020-06-16-12-16-13 +.. nonce: XkihpM +.. section: IDLE + +Typing opening and closing parentheses inside the parentheses of a function +call will no longer cause unnecessary "flashing" off and on of an existing +open call-tip, e.g. when typed in a string literal. + +.. + +.. bpo: 38439 +.. date: 2020-04-22-09-37-40 +.. nonce: ieXL-c +.. section: IDLE + +Add a 256×256 pixel IDLE icon to the Windows .ico file. Created by Andrew +Clover. Remove the low-color gif variations from the .ico file. + +.. + +.. bpo: 42157 +.. date: 2020-10-16-10-47-17 +.. nonce: e3BcPM +.. section: C API + +The private ``_PyUnicode_Name_CAPI`` structure of the PyCapsule API +``unicodedata.ucnhash_CAPI`` has been moved to the internal C API. Patch by +Victor Stinner. + +.. + +.. bpo: 42015 +.. date: 2020-10-12-20-13-58 +.. nonce: X4H2_V +.. section: C API + +Fix potential crash in deallocating method objects when dynamically +allocated :c:type:`PyMethodDef`'s lifetime is managed through the ``self`` argument +of a :c:type:`PyCFunction`. + +.. + +.. bpo: 40423 +.. date: 2020-10-11-19-17-44 +.. nonce: GsmgEj +.. section: C API + +The :mod:`subprocess` module and ``os.closerange`` will now use the +``close_range(low, high, flags)`` syscall when it is available for more +efficient closing of ranges of descriptors. + +.. + +.. bpo: 41845 +.. date: 2020-10-11-05-05-53 +.. nonce: ZFvuQM +.. section: C API + +:c:func:`PyObject_GenericGetDict` is available again in the limited API when +targeting 3.10 or later. + +.. + +.. bpo: 40422 +.. date: 2020-10-10-14-05-24 +.. nonce: sh8IDY +.. section: C API + +Add `_Py_closerange` function to provide performant closing of a range of +file descriptors. + +.. + +.. bpo: 41986 +.. date: 2020-10-09-22-50-46 +.. nonce: JUPE59 +.. section: C API + +:c:data:`!Py_FileSystemDefaultEncodeErrors` and :c:data:`!Py_UTF8Mode` are +available again in limited API. + +.. + +.. bpo: 41756 +.. date: 2020-09-28-14-31-07 +.. nonce: ZZ5wJG +.. section: C API + +Add `PyIter_Send` function to allow sending value into +generator/coroutine/iterator without raising StopIteration exception to +signal return. + +.. + +.. bpo: 41784 +.. date: 2020-09-14-10-17-00 +.. nonce: Yl4gI2 +.. section: C API + +Added ``PyUnicode_AsUTF8AndSize`` to the limited C API. diff --git a/Misc/NEWS.d/3.10.0a3.rst b/Misc/NEWS.d/3.10.0a3.rst new file mode 100644 index 00000000..0e89984d --- /dev/null +++ b/Misc/NEWS.d/3.10.0a3.rst @@ -0,0 +1,1504 @@ +.. bpo: 40791 +.. date: 2020-05-28-06-06-47 +.. nonce: QGZClX +.. release date: 2020-12-07 +.. section: Security + +Add ``volatile`` to the accumulator variable in ``hmac.compare_digest``, +making constant-time-defeating optimizations less likely. + +.. + +.. bpo: 42576 +.. date: 2020-12-05-22-34-47 +.. nonce: lEeEl7 +.. section: Core and Builtins + +``types.GenericAlias`` will now raise a ``TypeError`` when attempting to +initialize with a keyword argument. Previously, this would cause the +interpreter to crash if the interpreter was compiled with debug symbols. +This does not affect interpreters compiled for release. Patch by Ken Jin. + +.. + +.. bpo: 42536 +.. date: 2020-12-02-20-23-31 +.. nonce: Kx3ZOu +.. section: Core and Builtins + +Several built-in and standard library types now ensure that their internal +result tuples are always tracked by the :term:`garbage collector <garbage +collection>`: + +- :meth:`collections.OrderedDict.items() <collections.OrderedDict>` + +- :meth:`dict.items` + +- :func:`enumerate` + +- :func:`functools.reduce` + +- :func:`itertools.combinations` + +- :func:`itertools.combinations_with_replacement` + +- :func:`itertools.permutations` + +- :func:`itertools.product` + +- :func:`itertools.zip_longest` + +- :func:`zip` + +Previously, they could have become untracked by a prior garbage collection. +Patch by Brandt Bucher. + +.. + +.. bpo: 42500 +.. date: 2020-11-30-14-27-29 +.. nonce: excVKU +.. section: Core and Builtins + +Improve handling of exceptions near recursion limit. Converts a number of +Fatal Errors in RecursionErrors. + +.. + +.. bpo: 42246 +.. date: 2020-11-24-14-01-43 +.. nonce: c9k9hj +.. section: Core and Builtins + +PEP 626: After a return, the f_lineno attribute of a frame is always the +last line executed. + +.. + +.. bpo: 42435 +.. date: 2020-11-22-14-34-55 +.. nonce: uwlB2W +.. section: Core and Builtins + +Speed up comparison of bytes objects with non-bytes objects when option +:option:`-b` is specified. Speed up comparison of bytarray objects with +non-buffer object. + +.. + +.. bpo: 1635741 +.. date: 2020-11-18-23-46-31 +.. nonce: GVOQ-m +.. section: Core and Builtins + +Port the ``_warnings`` extension module to the multi-phase initialization +API (:pep:`489`). Patch by Victor Stinner. + +.. + +.. bpo: 41686 +.. date: 2020-11-17-16-25-50 +.. nonce: hX77kL +.. section: Core and Builtins + +On Windows, the ``SIGINT`` event, ``_PyOS_SigintEvent()``, is now created +even if Python is configured to not install signal handlers (if +:c:member:`PyConfig.install_signal_handlers` equals to 0, or +``Py_InitializeEx(0)``). + +.. + +.. bpo: 42381 +.. date: 2020-11-16-23-45-56 +.. nonce: G4AWxL +.. section: Core and Builtins + +Allow assignment expressions in set literals and set comprehensions as per +PEP 572. Patch by Pablo Galindo. + +.. + +.. bpo: 42202 +.. date: 2020-11-16-18-13-07 +.. nonce: ZxenYD +.. section: Core and Builtins + +Change function parameters annotations internal representation to tuple of +strings. Patch provided by Yurii Karabas. + +.. + +.. bpo: 42374 +.. date: 2020-11-16-17-57-09 +.. nonce: t7np1E +.. section: Core and Builtins + +Fix a regression introduced by the new parser, where an unparenthesized +walrus operator was not allowed within generator expressions. + +.. + +.. bpo: 42316 +.. date: 2020-11-16-17-30-03 +.. nonce: _DdmpQ +.. section: Core and Builtins + +Allow an unparenthesized walrus in subscript indexes. + +.. + +.. bpo: 42349 +.. date: 2020-11-13-17-25-44 +.. nonce: JdWxez +.. section: Core and Builtins + +Make sure that the compiler front-end produces a well-formed control flow +graph. Be be more aggressive in the compiler back-end, as it is now safe to +do so. + +.. + +.. bpo: 42296 +.. date: 2020-11-13-13-53-11 +.. nonce: DuGrLJ +.. section: Core and Builtins + +On Windows, fix a regression in signal handling which prevented to interrupt +a program using CTRL+C. The signal handler can be run in a thread different +than the Python thread, in which case the test deciding if the thread can +handle signals is wrong. + +.. + +.. bpo: 42332 +.. date: 2020-11-12-23-16-14 +.. nonce: fEQIdk +.. section: Core and Builtins + +:class:`types.GenericAlias` objects can now be the targets of weakrefs. + +.. + +.. bpo: 42282 +.. date: 2020-11-07-21-02-05 +.. nonce: M1W4Wj +.. section: Core and Builtins + +Optimise constant subexpressions that appear as part of named expressions +(previously the AST optimiser did not descend into named expressions). Patch +by Nick Coghlan. + +.. + +.. bpo: 42266 +.. date: 2020-11-04-23-03-25 +.. nonce: G4hGDe +.. section: Core and Builtins + +Fixed a bug with the LOAD_ATTR opcode cache that was not respecting +monkey-patching a class-level attribute to make it a descriptor. Patch by +Pablo Galindo. + +.. + +.. bpo: 40077 +.. date: 2020-11-03-21-58-27 +.. nonce: a9qM1j +.. section: Core and Builtins + +Convert :mod:`queue` to use heap types. + +.. + +.. bpo: 42246 +.. date: 2020-11-02-15-48-17 +.. nonce: 3CNQEX +.. section: Core and Builtins + +Improved accuracy of line tracing events and f_lineno attribute of Frame +objects. See PEP 626 for details. + +.. + +.. bpo: 40077 +.. date: 2020-11-02-14-39-48 +.. nonce: grY9TG +.. section: Core and Builtins + +Convert :mod:`mmap` to use heap types. + +.. + +.. bpo: 42233 +.. date: 2020-11-01-23-34-56 +.. nonce: zOSzja +.. section: Core and Builtins + +Allow ``GenericAlias`` objects to use :ref:`union type expressions +<types-union>`. This allows expressions like ``list[int] | dict[float, +str]`` where previously a ``TypeError`` would have been thrown. This also +fixes union type expressions not de-duplicating ``GenericAlias`` objects. +(Contributed by Ken Jin in :issue:`42233`.) + +.. + +.. bpo: 26131 +.. date: 2020-10-22-17-27-08 +.. nonce: B-Veg7 +.. section: Core and Builtins + +The import system triggers a `ImportWarning` when it falls back to using +`load_module()`. + +.. + +.. bpo: 5054 +.. date: 2020-12-04-03-51-12 +.. nonce: 53StYZ +.. section: Library + +CGIHTTPRequestHandler.run_cgi() HTTP_ACCEPT improperly parsed. Replace the +special purpose getallmatchingheaders with generic get_all method and add +relevant tests. + +Original Patch by Martin Panter. Modified by Senthil Kumaran. + +.. + +.. bpo: 42562 +.. date: 2020-12-03-22-42-03 +.. nonce: 2hPmhi +.. section: Library + +Fix issue when dis failed to parse function that has no line numbers. Patch +provided by Yurii Karabas. + +.. + +.. bpo: 17735 +.. date: 2020-12-03-22-22-24 +.. nonce: Qsaaue +.. section: Library + +:func:`inspect.findsource` now raises :exc:`OSError` instead of +:exc:`IndexError` when :attr:`co_lineno` of a code object is greater than +the file length. This can happen, for example, when a file is edited after +it was imported. PR by Irit Katriel. + +.. + +.. bpo: 42116 +.. date: 2020-12-03-15-42-32 +.. nonce: yIwroP +.. section: Library + +Fix handling of trailing comments by :func:`inspect.getsource`. + +.. + +.. bpo: 42532 +.. date: 2020-12-02-07-37-59 +.. nonce: ObNep_ +.. section: Library + +Remove unexpected call of ``__bool__`` when passing a ``spec_arg`` argument +to a Mock. + +.. + +.. bpo: 38200 +.. date: 2020-11-28-22-52-57 +.. nonce: DuWGlW +.. section: Library + +Added itertools.pairwise() + +.. + +.. bpo: 41818 +.. date: 2020-11-28-06-34-53 +.. nonce: mFSMc2 +.. section: Library + +Fix test_master_read() so that it succeeds on all platforms that either +raise OSError or return b"" upon reading from master. + +.. + +.. bpo: 42487 +.. date: 2020-11-28-04-31-20 +.. nonce: iqtC4L +.. section: Library + +ChainMap.__iter__ no longer calls __getitem__ on underlying maps + +.. + +.. bpo: 42482 +.. date: 2020-11-27-16-46-58 +.. nonce: EJC3sd +.. section: Library + +:class:`~traceback.TracebackException` no longer holds a reference to the +exception's traceback object. Consequently, instances of TracebackException +for equivalent but non-equal exceptions now compare as equal. + +.. + +.. bpo: 41818 +.. date: 2020-11-27-09-19-43 +.. nonce: KWYUbL +.. section: Library + +Make test_openpty() avoid unexpected success due to number of rows and/or +number of columns being == 0. + +.. + +.. bpo: 42392 +.. date: 2020-11-26-12-40-16 +.. nonce: GbmdHE +.. section: Library + +Remove loop parameter from ``asyncio.subprocess`` and ``asyncio.tasks`` +functions. Patch provided by Yurii Karabas. + +.. + +.. bpo: 42392 +.. date: 2020-11-25-22-44-59 +.. nonce: T_DAEl +.. section: Library + +Remove loop parameter from ``asyncio.open_connection`` and +``asyncio.start_server`` functions. Patch provided by Yurii Karabas. + +.. + +.. bpo: 28468 +.. date: 2020-11-24-13-18-05 +.. nonce: 8Gh2d4 +.. section: Library + +Add :func:`platform.freedesktop_os_release` function to parse +freedesktop.org ``os-release`` files. + +.. + +.. bpo: 42299 +.. date: 2020-11-23-23-42-08 +.. nonce: Fdn4Wf +.. section: Library + +Removed the ``formatter`` module, which was deprecated in Python 3.4. It is +somewhat obsolete, little used, and not tested. It was originally scheduled +to be removed in Python 3.6, but such removals were delayed until after +Python 2.7 EOL. Existing users should copy whatever classes they use into +their code. Patch by Donghee Na and and Terry J. Reedy. + +.. + +.. bpo: 26131 +.. date: 2020-11-22-12-30-26 +.. nonce: -HsFPG +.. section: Library + +Deprecate zipimport.zipimporter.load_module() in favour of exec_module(). + +.. + +.. bpo: 41818 +.. date: 2020-11-20-14-44-07 +.. nonce: 33soAw +.. section: Library + +Updated tests for the pty library. test_basic() has been changed to +test_openpty(); this additionally checks if slave termios and slave winsize +are being set properly by pty.openpty(). In order to add support for +FreeBSD, NetBSD, OpenBSD, and Darwin, this also adds test_master_read(), +which demonstrates that pty.spawn() should not depend on an OSError to exit +from its copy loop. + +.. + +.. bpo: 42392 +.. date: 2020-11-20-14-01-29 +.. nonce: -OUzvl +.. section: Library + +Remove loop parameter from ``__init__`` in all ``asyncio.locks`` and +``asyncio.Queue`` classes. Patch provided by Yurii Karabas. + +.. + +.. bpo: 15450 +.. date: 2020-11-20-10-38-34 +.. nonce: E-y9PA +.. section: Library + +Make :class:`filecmp.dircmp` respect subclassing. Now the +:attr:`filecmp.dircmp.subdirs` behaves as expected when subclassing dircmp. + +.. + +.. bpo: 42413 +.. date: 2020-11-19-20-27-51 +.. nonce: fjHrHx +.. section: Library + +The exception :exc:`socket.timeout` is now an alias of :exc:`TimeoutError`. + +.. + +.. bpo: 31904 +.. date: 2020-11-19-16-14-36 +.. nonce: 83kf9d +.. section: Library + +Support signal module on VxWorks. + +.. + +.. bpo: 42406 +.. date: 2020-11-19-10-44-41 +.. nonce: r9rNCj +.. section: Library + +We fixed an issue in `pickle.whichmodule` in which importing +`multiprocessing` could change the how pickle identifies which module an +object belongs to, potentially breaking the unpickling of those objects. + +.. + +.. bpo: 42403 +.. date: 2020-11-19-10-12-39 +.. nonce: t7q5AX +.. section: Library + +Simplify the :mod:`importlib` external bootstrap code: +``importlib._bootstrap_external`` now uses regular imports to import builtin +modules. When it is imported, the builtin :func:`__import__()` function is +already fully working and so can be used to import builtin modules like +:mod:`sys`. Patch by Victor Stinner. + +.. + +.. bpo: 1635741 +.. date: 2020-11-19-09-59-07 +.. nonce: 7cMypH +.. section: Library + +Convert _sre module types to heap types (PEP 384). Patch by Erlend E. +Aasland. + +.. + +.. bpo: 42375 +.. date: 2020-11-19-04-13-53 +.. nonce: U8bp4s +.. section: Library + +subprocess module update for DragonFlyBSD support. + +.. + +.. bpo: 41713 +.. date: 2020-11-17-23-00-27 +.. nonce: -Us0tf +.. section: Library + +Port the ``_signal`` extension module to the multi-phase initialization API +(:pep:`489`). Patch by Victor Stinner and Mohamed Koubaa. + +.. + +.. bpo: 37205 +.. date: 2020-11-16-15-08-12 +.. nonce: Wh5svI +.. section: Library + +:func:`time.time()`, :func:`time.perf_counter()` and +:func:`time.monotonic()` functions can no longer fail with a Python fatal +error, instead raise a regular Python exception on failure. + +.. + +.. bpo: 42328 +.. date: 2020-11-15-17-02-00 +.. nonce: bqpPlR +.. section: Library + +Fixed :meth:`tkinter.ttk.Style.map`. The function accepts now the +representation of the default state as empty sequence (as returned by +``Style.map()``). The structure of the result is now the same on all +platform and does not depend on the value of ``wantobjects``. + +.. + +.. bpo: 42345 +.. date: 2020-11-15-15-23-34 +.. nonce: hiIR7x +.. section: Library + +Fix various issues with ``typing.Literal`` parameter handling (flatten, +deduplicate, use type to cache key). Patch provided by Yurii Karabas. + +.. + +.. bpo: 37205 +.. date: 2020-11-14-14-34-32 +.. nonce: iDbHrw +.. section: Library + +:func:`time.perf_counter()` on Windows and :func:`time.monotonic()` on macOS +are now system-wide. Previously, they used an offset computed at startup to +reduce the precision loss caused by the float type. Use +:func:`time.perf_counter_ns()` and :func:`time.monotonic_ns()` added in +Python 3.7 to avoid this precision loss. + +.. + +.. bpo: 42318 +.. date: 2020-11-14-13-46-27 +.. nonce: wYAcBD +.. section: Library + +Fixed support of non-BMP characters in :mod:`tkinter` on macOS. + +.. + +.. bpo: 42350 +.. date: 2020-11-13-18-53-50 +.. nonce: rsql7V +.. section: Library + +Fix the :class:`threading.Thread` class at fork: do nothing if the thread is +already stopped (ex: fork called at Python exit). Previously, an error was +logged in the child process. + +.. + +.. bpo: 42333 +.. date: 2020-11-12-18-21-15 +.. nonce: J9vFmV +.. section: Library + +Port _ssl extension module to heap types. + +.. + +.. bpo: 42014 +.. date: 2020-11-10-15-40-56 +.. nonce: ShM37l +.. section: Library + +The ``onerror`` callback from ``shutil.rmtree`` now receives correct +function when ``os.open`` fails. + +.. + +.. bpo: 42237 +.. date: 2020-11-10-14-27-49 +.. nonce: F363jO +.. section: Library + +Fix `os.sendfile()` on illumos. + +.. + +.. bpo: 42308 +.. date: 2020-11-10-12-09-13 +.. nonce: yaJHH9 +.. section: Library + +Add :data:`threading.__excepthook__` to allow retrieving the original value +of :func:`threading.excepthook` in case it is set to a broken or a different +value. Patch by Mario Corchero. + +.. + +.. bpo: 42131 +.. date: 2020-11-06-18-20-47 +.. nonce: l2rjjG +.. section: Library + +Implement PEP 451/spec methods on zipimport.zipimporter: find_spec(), +create_module(), and exec_module(). + +This also allows for the documented deprecation of find_loader(), +find_module(), and load_module(). + +.. + +.. bpo: 41877 +.. date: 2020-11-05-16-00-03 +.. nonce: FHbngM +.. section: Library + +Mock objects which are not unsafe will now raise an AttributeError if an +attribute with the prefix asert, aseert, or assrt is accessed, in addition +to this already happening for the prefixes assert or assret. + +.. + +.. bpo: 42264 +.. date: 2020-11-05-13-32-41 +.. nonce: r4KYUU +.. section: Library + +``sqlite3.OptimizedUnicode`` has been undocumented and obsolete since Python +3.3, when it was made an alias to :class:`str`. It is now deprecated, +scheduled for removal in Python 3.12. + +.. + +.. bpo: 42251 +.. date: 2020-11-03-14-15-35 +.. nonce: 6TC32V +.. section: Library + +Added :func:`threading.gettrace` and :func:`threading.getprofile` to +retrieve the functions set by :func:`threading.settrace` and +:func:`threading.setprofile` respectively. Patch by Mario Corchero. + +.. + +.. bpo: 42249 +.. date: 2020-11-03-09-22-56 +.. nonce: vfNO2u +.. section: Library + +Fixed writing binary Plist files larger than 4 GiB. + +.. + +.. bpo: 42236 +.. date: 2020-11-02-23-05-17 +.. nonce: aJ6ZBR +.. section: Library + +On Unix, the :func:`os.device_encoding` function now returns ``'UTF-8'`` +rather than the device encoding if the :ref:`Python UTF-8 Mode <utf8-mode>` +is enabled. + +.. + +.. bpo: 41754 +.. date: 2020-11-01-15-07-20 +.. nonce: DraSZh +.. section: Library + +webbrowser: Ignore *NotADirectoryError* when calling ``xdg-settings``. + +.. + +.. bpo: 42183 +.. date: 2020-10-29-11-17-35 +.. nonce: 50ZcIi +.. section: Library + +Fix a stack overflow error for asyncio Task or Future repr(). + +The overflow occurs under some circumstances when a Task or Future +recursively returns itself. + +.. + +.. bpo: 42140 +.. date: 2020-10-24-04-02-36 +.. nonce: miLqvb +.. section: Library + +Improve asyncio.wait function to create the futures set just one time. + +.. + +.. bpo: 42133 +.. date: 2020-10-23-15-47-47 +.. nonce: BzizYV +.. section: Library + +Update various modules in the stdlib to fall back on `__spec__.loader` when +`__loader__` isn't defined on a module. + +.. + +.. bpo: 26131 +.. date: 2020-10-22-17-26-35 +.. nonce: CAsI3O +.. section: Library + +The `load_module()` methods found in importlib now trigger a +DeprecationWarning. + +.. + +.. bpo: 39825 +.. date: 2020-10-20-08-28-26 +.. nonce: n6KnG0 +.. section: Library + +Windows: Change ``sysconfig.get_config_var('EXT_SUFFIX')`` to the expected +full ``platform_tag.extension`` format. Previously it was hard-coded to +``.pyd``, now it is compatible with ``distutils.sysconfig`` and will result +in something like ``.cp38-win_amd64.pyd``. This brings windows into +conformance with the other platforms. + +.. + +.. bpo: 26389 +.. date: 2020-10-08-23-51-55 +.. nonce: uga44e +.. section: Library + +The :func:`traceback.format_exception`, +:func:`traceback.format_exception_only`, and +:func:`traceback.print_exception` functions can now take an exception object +as a positional-only argument. + +.. + +.. bpo: 41889 +.. date: 2020-10-01-16-17-11 +.. nonce: qLkNh8 +.. section: Library + +Enum: fix regression involving inheriting a multiply inherited enum + +.. + +.. bpo: 41861 +.. date: 2020-10-01-15-44-52 +.. nonce: YTqJ7z +.. section: Library + +Convert :mod:`sqlite3` to use heap types (PEP 384). Patch by Erlend E. +Aasland. + +.. + +.. bpo: 40624 +.. date: 2020-09-08-03-19-04 +.. nonce: 0-gYfx +.. section: Library + +Added support for the XPath ``!=`` operator in xml.etree + +.. + +.. bpo: 28850 +.. date: 2020-09-06-21-55-44 +.. nonce: HJNggD +.. section: Library + +Fix :meth:`pprint.PrettyPrinter.format` overrides being ignored for contents +of small containers. The :func:`pprint._safe_repr` function was removed. + +.. + +.. bpo: 41625 +.. date: 2020-08-24-16-59-04 +.. nonce: Cc967V +.. section: Library + +Expose the :c:func:`splice` as :func:`os.splice` in the :mod:`os` module. +Patch by Pablo Galindo + +.. + +.. bpo: 34215 +.. date: 2020-08-19-20-17-51 +.. nonce: _Cv8c- +.. section: Library + +Clarify the error message for :exc:`asyncio.IncompleteReadError` when +``expected`` is ``None``. + +.. + +.. bpo: 41543 +.. date: 2020-08-14-00-39-04 +.. nonce: RpcRjb +.. section: Library + +Add async context manager support for contextlib.nullcontext. + +.. + +.. bpo: 21041 +.. date: 2020-08-10-15-06-55 +.. nonce: cYz1eL +.. section: Library + +:attr:`pathlib.PurePath.parents` now supports negative indexing. Patch +contributed by Yaroslav Pankovych. + +.. + +.. bpo: 41332 +.. date: 2020-07-18-17-39-28 +.. nonce: QRGmA5 +.. section: Library + +Added missing connect_accepted_socket() method to +``asyncio.AbstractEventLoop``. + +.. + +.. bpo: 12800 +.. date: 2020-07-09-11-32-28 +.. nonce: fNgWwx +.. section: Library + +Extracting a symlink from a tarball should succeed and overwrite the symlink +if it already exists. The fix is to remove the existing file or symlink +before extraction. Based on patch by Chris AtLee, Jeffrey Kintscher, and +Senthil Kumaran. + +.. + +.. bpo: 40968 +.. date: 2020-06-18-11-35-16 +.. nonce: R8Edbv +.. section: Library + +:mod:`urllib.request` and :mod:`http.client` now send ``http/1.1`` ALPN +extension during TLS handshake when no custom context is supplied. + +.. + +.. bpo: 41001 +.. date: 2020-06-17-12-24-26 +.. nonce: 5mi7b0 +.. section: Library + +Add func:`os.eventfd` to provide a low level interface for Linux's event +notification file descriptor. + +.. + +.. bpo: 40816 +.. date: 2020-05-29-15-25-41 +.. nonce: w61Pob +.. section: Library + +Add AsyncContextDecorator to contextlib to support async context manager as +a decorator. + +.. + +.. bpo: 40550 +.. date: 2020-05-08-21-30-54 +.. nonce: i7GWkb +.. section: Library + +Fix time-of-check/time-of-action issue in subprocess.Popen.send_signal. + +.. + +.. bpo: 39411 +.. date: 2020-01-21-16-38-25 +.. nonce: 9uHFqT +.. section: Library + +Add an ``is_async`` identifier to :mod:`pyclbr`'s ``Function`` objects. +Patch by Batuhan Taskaya + +.. + +.. bpo: 35498 +.. date: 2018-12-14-13-29-17 +.. nonce: LEJHl7 +.. section: Library + +Add slice support to :attr:`pathlib.PurePath.parents`. + +.. + +.. bpo: 42238 +.. date: 2020-11-24-22-54-49 +.. nonce: 62EOTu +.. section: Documentation + +Tentative to deprecate ``make suspicious`` by first removing it from the CI +and documentation builds, but keeping it around for manual uses. + +.. + +.. bpo: 42153 +.. date: 2020-11-15-13-46-31 +.. nonce: KjBhx3 +.. section: Documentation + +Fix the URL for the IMAP protocol documents. + +.. + +.. bpo: 41028 +.. date: 2020-06-18-23-37-03 +.. nonce: vM8bC8 +.. section: Documentation + +Language and version switchers, previously maintained in every cpython +branches, are now handled by docsbuild-script. + +.. + +.. bpo: 41473 +.. date: 2020-12-04-11-47-09 +.. nonce: W_updK +.. section: Tests + +Re-enable test_gdb on gdb 9.2 and newer: +https://bugzilla.redhat.com/show_bug.cgi?id=1866884 bug is fixed in gdb +10.1. + +.. + +.. bpo: 42553 +.. date: 2020-12-03-13-32-44 +.. nonce: 2TRE2N +.. section: Tests + +Fix ``test_asyncio.test_call_later()`` race condition: don't measure asyncio +performance in the ``call_later()`` unit test. The test failed randomly on +the CI. + +.. + +.. bpo: 31904 +.. date: 2020-12-01-15-51-19 +.. nonce: iwetj4 +.. section: Tests + +Fix test_netrc on VxWorks: create temporary directories using temp_cwd(). + +.. + +.. bpo: 31904 +.. date: 2020-11-26-11-13-13 +.. nonce: ay4g89 +.. section: Tests + +skip test_getaddrinfo_ipv6_scopeid_symbolic and +test_getnameinfo_ipv6_scopeid_symbolic on VxWorks + +.. + +.. bpo: 31904 +.. date: 2020-11-25-17-00-53 +.. nonce: ue4hd9 +.. section: Tests + +skip test_test of test_mailcap on VxWorks + +.. + +.. bpo: 31904 +.. date: 2020-11-24-17-26-41 +.. nonce: eug834 +.. section: Tests + +add shell requirement for test_pipes + +.. + +.. bpo: 31904 +.. date: 2020-11-23-11-11-29 +.. nonce: V3sUZk +.. section: Tests + +skip some tests related to fifo on VxWorks + +.. + +.. bpo: 31904 +.. date: 2020-11-20-15-07-18 +.. nonce: EBJXjJ +.. section: Tests + +Fix test_doctest.py failures for VxWorks. + +.. + +.. bpo: 40754 +.. date: 2020-11-13-21-51-34 +.. nonce: Ekoxkg +.. section: Tests + +Include ``_testinternalcapi`` module in Windows installer for test suite + +.. + +.. bpo: 41561 +.. date: 2020-09-18-16-14-03 +.. nonce: uPnwrW +.. section: Tests + +test_ssl: skip test_min_max_version_mismatch when TLS 1.0 is not available + +.. + +.. bpo: 31904 +.. date: 2020-05-20-17-28-46 +.. nonce: yt83Ge +.. section: Tests + +Fix os module failures for VxWorks RTOS. + +.. + +.. bpo: 31904 +.. date: 2020-05-20-14-28-48 +.. nonce: yJik6k +.. section: Tests + +Fix fifo test cases for VxWorks RTOS. + +.. + +.. bpo: 31904 +.. date: 2020-11-19-17-01-50 +.. nonce: 894dk2 +.. section: Build + +remove libnet dependency from detect_socket() for VxWorks + +.. + +.. bpo: 42398 +.. date: 2020-11-18-11-58-44 +.. nonce: Yt5wO8 +.. section: Build + +Fix a race condition in "make regen-all" when make -jN option is used to run +jobs in parallel. The clinic.py script now only use atomic write to write +files. Moveover, generated files are now left unchanged if the content does +not change, to not change the file modification time. + +.. + +.. bpo: 41617 +.. date: 2020-11-13-15-04-53 +.. nonce: 98_oaE +.. section: Build + +Fix building ``pycore_bitutils.h`` internal header on old clang version +without ``__builtin_bswap16()`` (ex: Xcode 4.6.3 on Mac OS X 10.7). Patch by +Joshua Root and Victor Stinner. + +.. + +.. bpo: 38823 +.. date: 2020-11-12-13-45-15 +.. nonce: C0z_Fe +.. section: Build + +It is no longer possible to build the ``_ctypes`` extension module without +:c:type:`wchar_t` type: remove ``CTYPES_UNICODE`` macro. Anyway, the +:c:type:`wchar_t` type is required to build Python. Patch by Victor Stinner. + +.. + +.. bpo: 42087 +.. date: 2020-10-19-15-41-05 +.. nonce: 2AhRFP +.. section: Build + +Support was removed for AIX 5.3 and below. See :issue:`40680`. + +.. + +.. bpo: 40998 +.. date: 2020-06-17-09-05-02 +.. nonce: sgqmg9 +.. section: Build + +Addressed three compiler warnings found by undefined behavior sanitizer +(ubsan). + +.. + +.. bpo: 42120 +.. date: 2020-11-16-22-41-02 +.. nonce: 9scgko +.. section: Windows + +Remove macro definition of ``copysign`` (to ``_copysign``) in headers. + +.. + +.. bpo: 38506 +.. date: 2020-11-15-23-01-14 +.. nonce: hhdnuP +.. section: Windows + +The Windows launcher now properly handles Python 3.10 when listing installed +Python versions. + +.. + +.. bpo: 42504 +.. date: 2020-12-02-15-48-40 +.. nonce: RQmMOR +.. section: macOS + +Fix build on macOS Big Sur when MACOSX_DEPLOYMENT_TARGET=11 + +.. + +.. bpo: 41116 +.. date: 2020-11-15-16-43-45 +.. nonce: oCkbrF +.. section: macOS + +Ensure distutils.unixxcompiler.find_library_file can find system provided +libraries on macOS 11. + +.. + +.. bpo: 41100 +.. date: 2020-11-01-16-40-23 +.. nonce: BApztP +.. section: macOS + +Add support for macOS 11 and Apple Silicon systems. + +It is now possible to build "Universal 2" binaries using +"--enable-universalsdk --with-universal-archs=universal2". + +Binaries build on later macOS versions can be deployed back to older +versions (tested up to macOS 10.9), when using the correct deployment +target. This is tested using Xcode 11 and later. + +.. + +.. bpo: 42232 +.. date: 2020-11-01-15-10-28 +.. nonce: 2zI1GN +.. section: macOS + +Added Darwin specific madvise options to mmap module. + +.. + +.. bpo: 38443 +.. date: 2020-10-23-10-26-53 +.. nonce: vu64tl +.. section: macOS + +The ``--enable-universalsdk`` and ``--with-universal-archs`` options for the +configure script now check that the specified architectures can be used. + +.. + +.. bpo: 42508 +.. date: 2020-11-30-19-46-05 +.. nonce: fE7w4M +.. section: IDLE + +Keep IDLE running on macOS. Remove obsolete workaround that prevented +running files with shortcuts when using new universal2 installers built on +macOS 11. + +.. + +.. bpo: 42426 +.. date: 2020-11-21-17-21-21 +.. nonce: kNnPoC +.. section: IDLE + +Fix reporting offset of the RE error in searchengine. + +.. + +.. bpo: 42415 +.. date: 2020-11-20-01-30-27 +.. nonce: CyD-va +.. section: IDLE + +Get docstrings for IDLE calltips more often by using inspect.getdoc. + +.. + +.. bpo: 42212 +.. date: 2020-11-20-15-11-05 +.. nonce: sjzgOf +.. section: Tools/Demos + +The smelly.py script now also checks the Python dynamic library and +extension modules, not only the Python static library. Make also the script +more verbose: explain what it does. + +.. + +.. bpo: 36310 +.. date: 2020-05-03-01-30-46 +.. nonce: xDxxwY +.. section: Tools/Demos + +Allow :file:`Tools/i18n/pygettext.py` to detect calls to ``gettext`` in +f-strings. + +.. + +.. bpo: 42423 +.. date: 2020-11-21-12-27-19 +.. nonce: ByJHhY +.. section: C API + +The :c:func:`PyType_FromSpecWithBases` and +:c:func:`PyType_FromModuleAndSpec` functions now accept a single class as +the *bases* argument. + +.. + +.. bpo: 1635741 +.. date: 2020-11-19-17-44-36 +.. nonce: qBZc3o +.. section: C API + +Port :mod:`select` extension module to multiphase initialization +(:pep:`489`). + +.. + +.. bpo: 1635741 +.. date: 2020-11-19-16-54-16 +.. nonce: 9tVsZt +.. section: C API + +Port _posixsubprocess extension module to multiphase initialization +(:pep:`489`). + +.. + +.. bpo: 1635741 +.. date: 2020-11-19-15-33-42 +.. nonce: 9tVsZt +.. section: C API + +Port _posixshmem extension module to multiphase initialization (:pep:`489`) + +.. + +.. bpo: 1635741 +.. date: 2020-11-19-12-06-43 +.. nonce: KEfZpn +.. section: C API + +Port _struct extension module to multiphase initialization (:pep:`489`) + +.. + +.. bpo: 1635741 +.. date: 2020-11-19-09-17-01 +.. nonce: 6F9o6L +.. section: C API + +Port :mod:`spwd` extension module to multiphase initialization (:pep:`489`) + +.. + +.. bpo: 1635741 +.. date: 2020-11-18-20-33-35 +.. nonce: B4ztSk +.. section: C API + +Port :mod:`gc` extension module to multiphase initialization (:pep:`489`) + +.. + +.. bpo: 1635741 +.. date: 2020-11-18-20-11-13 +.. nonce: fe3iRb +.. section: C API + +Port _queue extension module to multiphase initialization (:pep:`489`) + +.. + +.. bpo: 39573 +.. date: 2020-11-18-15-21-59 +.. nonce: VB3G2y +.. section: C API + +Convert :c:func:`Py_TYPE` and :c:func:`Py_SIZE` back to macros to allow +using them as an l-value. Many third party C extension modules rely on the +ability of using Py_TYPE() and Py_SIZE() to set an object type and size: +``Py_TYPE(obj) = type;`` and ``Py_SIZE(obj) = size;``. + +.. + +.. bpo: 1635741 +.. date: 2020-11-18-10-52-38 +.. nonce: FrWAwJ +.. section: C API + +Port :mod:`symtable` extension module to multiphase initialization +(:pep:`489`) + +.. + +.. bpo: 1635741 +.. date: 2020-11-18-09-46-35 +.. nonce: SH8OIT +.. section: C API + +Port :mod:`grp` and :mod:`pwd` extension modules to multiphase +initialization (:pep:`489`) + +.. + +.. bpo: 1635741 +.. date: 2020-11-18-09-16-23 +.. nonce: gkoI7Y +.. section: C API + +Port _random extension module to multiphase initialization (:pep:`489`) + +.. + +.. bpo: 1635741 +.. date: 2020-11-18-08-45-36 +.. nonce: VLZfiY +.. section: C API + +Port _hashlib extension module to multiphase initialization (:pep:`489`) + +.. + +.. bpo: 41713 +.. date: 2020-11-17-15-39-10 +.. nonce: Rq99Vc +.. section: C API + +Removed the undocumented ``PyOS_InitInterrupts()`` function. Initializing +Python already implicitly installs signal handlers: see +:c:member:`PyConfig.install_signal_handlers`. Patch by Victor Stinner. + +.. + +.. bpo: 40170 +.. date: 2020-11-13-01-40-28 +.. nonce: uh8lEf +.. section: C API + +The ``Py_TRASHCAN_BEGIN`` macro no longer accesses PyTypeObject attributes, +but now can get the condition by calling the new private +:c:func:`_PyTrash_cond()` function which hides implementation details. + +.. + +.. bpo: 42260 +.. date: 2020-11-10-14-27-39 +.. nonce: -Br3Co +.. section: C API + +:c:func:`Py_GetPath`, :c:func:`Py_GetPrefix`, :c:func:`Py_GetExecPrefix`, +:c:func:`Py_GetProgramFullPath`, :c:func:`Py_GetPythonHome` and +:c:func:`Py_GetProgramName` functions now return ``NULL`` if called before +:c:func:`Py_Initialize` (before Python is initialized). Use the new +:ref:`Python Initialization Configuration API <init-config>` to get the +:ref:`Python Path Configuration. <init-path-config>`. Patch by Victor +Stinner. + +.. + +.. bpo: 42260 +.. date: 2020-11-05-18-02-07 +.. nonce: pAeaNR +.. section: C API + +The :c:func:`PyConfig_Read` function now only parses +:c:member:`PyConfig.argv` arguments once: :c:member:`PyConfig.parse_argv` is +set to ``2`` after arguments are parsed. Since Python arguments are +strippped from :c:member:`PyConfig.argv`, parsing arguments twice would +parse the application options as Python options. + +.. + +.. bpo: 42262 +.. date: 2020-11-04-17-22-36 +.. nonce: fCWzBb +.. section: C API + +Added :c:func:`Py_NewRef` and :c:func:`Py_XNewRef` functions to increment +the reference count of an object and return the object. Patch by Victor +Stinner. + +.. + +.. bpo: 42260 +.. date: 2020-11-04-16-31-55 +.. nonce: CmgHtF +.. section: C API + +When :c:func:`Py_Initialize` is called twice, the second call now updates +more :mod:`sys` attributes for the configuration, rather than only +:data:`sys.argv`. Patch by Victor Stinner. + +.. + +.. bpo: 41832 +.. date: 2020-11-03-19-47-06 +.. nonce: dL1VJJ +.. section: C API + +The :c:func:`PyType_FromModuleAndSpec` function now accepts NULL ``tp_doc`` +slot. + +.. + +.. bpo: 1635741 +.. date: 2020-11-03-11-52-27 +.. nonce: aDYJKB +.. section: C API + +Added :c:func:`PyModule_AddObjectRef` function: similar to +:c:func:`PyModule_AddObject` but don't steal a reference to the value on +success. Patch by Victor Stinner. + +.. + +.. bpo: 42171 +.. date: 2020-10-27-21-10-14 +.. nonce: S3FWTP +.. section: C API + +The :c:macro:`METH_FASTCALL` calling convention is added to the limited API. +The functions :c:func:`PyModule_AddType`, +:c:func:`PyType_FromModuleAndSpec`, :c:func:`PyType_GetModule` and +:c:func:`PyType_GetModuleState` are added to the limited API on Windows. + +.. + +.. bpo: 42085 +.. date: 2020-10-19-15-58-16 +.. nonce: NhEf3W +.. section: C API + +Add dedicated entry to PyAsyncMethods for sending values + +.. + +.. bpo: 41073 +.. date: 2020-07-08-21-01-49 +.. nonce: VqQZON +.. section: C API + +:c:func:`PyType_GetSlot()` can now accept static types. + +.. + +.. bpo: 30459 +.. date: 2020-05-06-23-54-57 +.. nonce: N9_Jai +.. section: C API + +:c:func:`PyList_SET_ITEM`, :c:func:`PyTuple_SET_ITEM` and +:c:func:`PyCell_SET` macros can no longer be used as l-value or r-value. For +example, ``x = PyList_SET_ITEM(a, b, c)`` and ``PyList_SET_ITEM(a, b, c) = +x`` now fail with a compiler error. It prevents bugs like ``if +(PyList_SET_ITEM (a, b, c) < 0) ...`` test. Patch by Zackery Spytz and +Victor Stinner. diff --git a/Misc/NEWS.d/3.10.0a4.rst b/Misc/NEWS.d/3.10.0a4.rst new file mode 100644 index 00000000..414823f1 --- /dev/null +++ b/Misc/NEWS.d/3.10.0a4.rst @@ -0,0 +1,995 @@ +.. bpo: 42814 +.. date: 2021-01-03-04-41-25 +.. nonce: sDvVbb +.. release date: 2021-01-04 +.. section: Core and Builtins + +Fix undefined behavior in ``Objects/genericaliasobject.c``. + +.. + +.. bpo: 42806 +.. date: 2021-01-03-00-20-38 +.. nonce: mLAobJ +.. section: Core and Builtins + +Fix the column offsets for f-strings :mod:`ast` nodes surrounded by +parentheses and for nodes that spawn multiple lines. Patch by Pablo Galindo. + +.. + +.. bpo: 40631 +.. date: 2020-12-31-20-58-22 +.. nonce: deRMCx +.. section: Core and Builtins + +Fix regression where a single parenthesized starred expression was a valid +assignment target. + +.. + +.. bpo: 27794 +.. date: 2020-12-27-18-07-43 +.. nonce: sxgfGi +.. section: Core and Builtins + +Improve the error message for failed writes/deletes to property objects. +When possible, the attribute name is now shown. Patch provided by Yurii +Karabas. + +.. + +.. bpo: 42745 +.. date: 2020-12-25-23-30-58 +.. nonce: XsFoHS +.. section: Core and Builtins + +Make the type attribute lookup cache per-interpreter. Patch by Victor +Stinner. + +.. + +.. bpo: 42246 +.. date: 2020-12-22-20-30-11 +.. nonce: 7BrPLg +.. section: Core and Builtins + +Jumps to jumps are not eliminated when it would break PEP 626. + +.. + +.. bpo: 42246 +.. date: 2020-12-16-14-44-21 +.. nonce: RtIEY7 +.. section: Core and Builtins + +Make sure that the ``f_lasti`` and ``f_lineno`` attributes of a frame are +set correctly when an exception is raised or re-raised. Required for PEP +626. + +.. + +.. bpo: 32381 +.. date: 2020-12-15-18-43-43 +.. nonce: 3tIofL +.. section: Core and Builtins + +The coding cookie (ex: ``# coding: latin1``) is now ignored in the command +passed to the :option:`-c` command line option. Patch by Victor Stinner. + +.. + +.. bpo: 30858 +.. date: 2020-12-13-15-23-09 +.. nonce: -f9G4z +.. section: Core and Builtins + +Improve error location in expressions that contain assignments. Patch by +Pablo Galindo and Lysandros Nikolaou. + +.. + +.. bpo: 42615 +.. date: 2020-12-10-17-06-52 +.. nonce: Je6Q-r +.. section: Core and Builtins + +Remove jump commands made redundant by the deletion of unreachable bytecode +blocks + +.. + +.. bpo: 42639 +.. date: 2020-12-09-01-55-10 +.. nonce: 5pI5HG +.. section: Core and Builtins + +Make the :mod:`atexit` module state per-interpreter. It is now safe have +more than one :mod:`atexit` module instance. Patch by Donghee Na and Victor +Stinner. + +.. + +.. bpo: 32381 +.. date: 2020-12-04-17-17-44 +.. nonce: NY5t2S +.. section: Core and Builtins + +Fix encoding name when running a ``.pyc`` file on Windows: +:c:func:`PyRun_SimpleFileExFlags()` now uses the correct encoding to decode +the filename. + +.. + +.. bpo: 42195 +.. date: 2020-11-20-00-57-47 +.. nonce: HeqcpS +.. section: Core and Builtins + +The ``__args__`` of the parameterized generics for :data:`typing.Callable` +and :class:`collections.abc.Callable` are now consistent. The ``__args__`` +for :class:`collections.abc.Callable` are now flattened while +:data:`typing.Callable`'s have not changed. To allow this change, +:class:`types.GenericAlias` can now be subclassed and +``collections.abc.Callable``'s ``__class_getitem__`` will now return a +subclass of ``types.GenericAlias``. Tests for typing were also updated to +not subclass things like ``Callable[..., T]`` as that is not a valid base +class. Finally, both ``Callable``\ s no longer validate their ``argtypes``, +in ``Callable[[argtypes], resulttype]`` to prepare for :pep:`612`. Patch by +Ken Jin. + +.. + +.. bpo: 40137 +.. date: 2020-11-19-23-12-57 +.. nonce: bihl9O +.. section: Core and Builtins + +Convert functools module to use :c:func:`PyType_FromModuleAndSpec`. + +.. + +.. bpo: 40077 +.. date: 2020-11-03-13-46-10 +.. nonce: NfAIdj +.. section: Core and Builtins + +Convert :mod:`array` to use heap types, and establish module state for +these. + +.. + +.. bpo: 42008 +.. date: 2020-10-12-14-51-59 +.. nonce: ijWw2I +.. section: Core and Builtins + +Fix _random.Random() seeding. + +.. + +.. bpo: 1635741 +.. date: 2020-09-12-19-21-52 +.. nonce: F2kDrU +.. section: Core and Builtins + +Port the :mod:`pyexpat` extension module to multi-phase initialization +(:pep:`489`). + +.. + +.. bpo: 40521 +.. date: 2020-05-14-02-55-39 +.. nonce: dIlXsZ +.. section: Core and Builtins + +Make the Unicode dictionary of interned strings compatible with +subinterpreters. Patch by Victor Stinner. + +.. + +.. bpo: 39465 +.. date: 2020-05-13-18-50-27 +.. nonce: j7nl6A +.. section: Core and Builtins + +Make :c:func:`_PyUnicode_FromId` function compatible with subinterpreters. +Each interpreter now has an array of identifier objects (interned strings +decoded from UTF-8). Patch by Victor Stinner. + +.. + +.. bpo: 42257 +.. date: 2020-12-31-23-05-53 +.. nonce: ALQy7B +.. section: Library + +Handle empty string in variable executable in platform.libc_ver() + +.. + +.. bpo: 42772 +.. date: 2020-12-30-17-16-43 +.. nonce: Xe7WFV +.. section: Library + +randrange() now raises a TypeError when step is specified without a stop +argument. Formerly, it silently ignored the step argument. + +.. + +.. bpo: 42759 +.. date: 2020-12-27-22-19-26 +.. nonce: lGi_03 +.. section: Library + +Fixed equality comparison of :class:`tkinter.Variable` and +:class:`tkinter.font.Font`. Objects which belong to different Tcl +interpreters are now always different, even if they have the same name. + +.. + +.. bpo: 42756 +.. date: 2020-12-27-21-22-01 +.. nonce: dHMPJ9 +.. section: Library + +Configure LMTP Unix-domain socket to use socket global default timeout when +a timeout is not explicitly provided. + +.. + +.. bpo: 23328 +.. date: 2020-12-27-18-47-01 +.. nonce: _xqepZ +.. section: Library + +Allow / character in username, password fields on _PROXY envars. + +.. + +.. bpo: 42740 +.. date: 2020-12-25-23-23-11 +.. nonce: F0rQ_E +.. section: Library + +:func:`typing.get_args` and :func:`typing.get_origin` now support :pep:`604` +union types and :pep:`612` additions to ``Callable``. + +.. + +.. bpo: 42655 +.. date: 2020-12-25-12-32-47 +.. nonce: W5ytpV +.. section: Library + +:mod:`subprocess` *extra_groups* is now correctly passed into setgroups() +system call. + +.. + +.. bpo: 42727 +.. date: 2020-12-23-19-43-06 +.. nonce: WH3ODh +.. section: Library + +``EnumMeta.__prepare__`` now accepts ``**kwds`` to properly support +``__init_subclass__`` + +.. + +.. bpo: 38308 +.. date: 2020-12-23-15-16-12 +.. nonce: lB4Sv0 +.. section: Library + +Add optional *weights* to *statistics.harmonic_mean()*. + +.. + +.. bpo: 42721 +.. date: 2020-12-22-22-47-22 +.. nonce: I5Ai5L +.. section: Library + +When simple query dialogs (:mod:`tkinter.simpledialog`), message boxes +(:mod:`tkinter.messagebox`) or color choose dialog +(:mod:`tkinter.colorchooser`) are created without arguments *master* and +*parent*, and the default root window is not yet created, and +:func:`~tkinter.NoDefaultRoot` was not called, a new temporal hidden root +window will be created automatically. It will not be set as the default root +window and will be destroyed right after closing the dialog window. It will +help to use these simple dialog windows in programs which do not need other +GUI. + +.. + +.. bpo: 25246 +.. date: 2020-12-22-13-16-43 +.. nonce: GhhCTl +.. section: Library + +Optimized :meth:`collections.deque.remove`. + +.. + +.. bpo: 35728 +.. date: 2020-12-21-23-34-57 +.. nonce: 9m-azF +.. section: Library + +Added a root parameter to :func:`tkinter.font.nametofont`. + +.. + +.. bpo: 15303 +.. date: 2020-12-21-22-59-26 +.. nonce: zozVrq +.. section: Library + +:mod:`tkinter` supports now widgets with boolean value False. + +.. + +.. bpo: 42681 +.. date: 2020-12-20-22-50-15 +.. nonce: lDO6jb +.. section: Library + +Fixed range checks for color and pair numbers in :mod:`curses`. + +.. + +.. bpo: 42685 +.. date: 2020-12-19-17-32-43 +.. nonce: kwZlwp +.. section: Library + +Improved placing of simple query windows in Tkinter (such as +:func:`tkinter.simpledialog.askinteger`). They are now centered at the +center of the parent window if it is specified and shown, otherwise at the +center of the screen. + +.. + +.. bpo: 9694 +.. date: 2020-12-19-12-33-38 +.. nonce: CkKK9V +.. section: Library + +Argparse help no longer uses the confusing phrase, "optional arguments". It +uses "options" instead. + +.. + +.. bpo: 1635741 +.. date: 2020-12-16-23-28-52 +.. nonce: Quy3zn +.. section: Library + +Port the :mod:`_thread` extension module to the multiphase initialization +API (:pep:`489`) and convert its static types to heap types. + +.. + +.. bpo: 37961 +.. date: 2020-12-16-16-16-33 +.. nonce: jrESEq +.. section: Library + +Fix crash in :func:`tracemalloc.Traceback.__repr__` (regressed in Python +3.9). + +.. + +.. bpo: 42630 +.. date: 2020-12-15-17-51-27 +.. nonce: jf4jBl +.. section: Library + +:mod:`tkinter` functions and constructors which need a default root window +raise now :exc:`RuntimeError` with descriptive message instead of obscure +:exc:`AttributeError` or :exc:`NameError` if it is not created yet or cannot +be created automatically. + +.. + +.. bpo: 42639 +.. date: 2020-12-15-15-14-29 +.. nonce: uJ3h8I +.. section: Library + +:func:`atexit._run_exitfuncs` now logs callback exceptions using +:data:`sys.unraisablehook`, rather than logging them directly into +:data:`sys.stderr` and raise the last exception. + +.. + +.. bpo: 42644 +.. date: 2020-12-15-10-00-04 +.. nonce: XgLCNx +.. section: Library + +``logging.disable`` will now validate the types and value of its parameter. +It also now accepts strings representing the levels (as does +``loging.setLevel``) instead of only the numerical values. + +.. + +.. bpo: 42639 +.. date: 2020-12-14-22-31-22 +.. nonce: 5Z3iWX +.. section: Library + +At Python exit, if a callback registered with :func:`atexit.register` fails, +its exception is now logged. Previously, only some exceptions were logged, +and the last exception was always silently ignored. + +.. + +.. bpo: 36541 +.. date: 2020-12-14-08-23-57 +.. nonce: qdEtZv +.. section: Library + +Fixed lib2to3.pgen2 to be able to parse PEP-570 positional only argument +syntax. + +.. + +.. bpo: 42382 +.. date: 2020-12-13-22-05-35 +.. nonce: 2YtKo5 +.. section: Library + +In ``importlib.metadata``: - ``EntryPoint`` objects now expose a ``.dist`` +object referencing the ``Distribution`` when constructed from a +``Distribution``. - Add support for package discovery under package +normalization rules. - The object returned by ``metadata()`` now has a +formally defined protocol called ``PackageMetadata`` with declared support +for the ``.get_all()`` method. - Synced with importlib_metadata 3.3. + +.. + +.. bpo: 41877 +.. date: 2020-12-10-19-49-52 +.. nonce: wiVlPc +.. section: Library + +A check is added against misspellings of autospect, auto_spec and set_spec +being passed as arguments to patch, patch.object and create_autospec. + +.. + +.. bpo: 39717 +.. date: 2020-12-10-18-36-52 +.. nonce: sK2u0w +.. section: Library + +[tarfile] update nested exception raising to use ``from None`` or ``from e`` + +.. + +.. bpo: 41877 +.. date: 2020-12-10-09-24-44 +.. nonce: iJSCvM +.. section: Library + +AttributeError for suspected misspellings of assertions on mocks are now +pointing out that the cause are misspelled assertions and also what to do if +the misspelling is actually an intended attribute name. The unittest.mock +document is also updated to reflect the current set of recognised +misspellings. + +.. + +.. bpo: 41559 +.. date: 2020-12-10-00-09-40 +.. nonce: 1l4yjP +.. section: Library + +Implemented :pep:`612`: added ``ParamSpec`` and ``Concatenate`` to +:mod:`typing`. Patch by Ken Jin. + +.. + +.. bpo: 42385 +.. date: 2020-12-09-19-45-32 +.. nonce: boGbjo +.. section: Library + +StrEnum: fix _generate_next_value_ to return a str + +.. + +.. bpo: 31904 +.. date: 2020-12-09-15-23-28 +.. nonce: g3k5k3 +.. section: Library + +Define THREAD_STACK_SIZE for VxWorks. + +.. + +.. bpo: 34750 +.. date: 2020-12-09-14-15-48 +.. nonce: x8TASR +.. section: Library + +[Enum] `_EnumDict.update()` is now supported + +.. + +.. bpo: 42517 +.. date: 2020-12-09-10-59-16 +.. nonce: FKEVcZ +.. section: Library + +Enum: private names do not become members / do not generate errors -- they +remain normal attributes + +.. + +.. bpo: 42678 +.. date: 2020-12-08-22-43-35 +.. nonce: ba9ktU +.. section: Library + +``Enum``: call ``__init_subclass__`` after members have been added + +.. + +.. bpo: 28964 +.. date: 2020-12-07-13-21-00 +.. nonce: UTQikc +.. section: Library + +:func:`ast.literal_eval` adds line number information (if available) in +error message for malformed nodes. + +.. + +.. bpo: 42470 +.. date: 2020-12-06-12-00-00 +.. nonce: iqtC4L +.. section: Library + +:func:`random.sample` no longer warns on a sequence which is also a set. + +.. + +.. bpo: 31904 +.. date: 2020-11-27-18-09-59 +.. nonce: g8k43d +.. section: Library + +:func:`posixpath.expanduser` returns the input *path* unchanged if user home +directory is None on VxWorks. + +.. + +.. bpo: 42388 +.. date: 2020-11-22-11-22-28 +.. nonce: LMgM6B +.. section: Library + +Fix subprocess.check_output(..., input=None) behavior when text=True to be +consistent with that of the documentation and universal_newlines=True. + +.. + +.. bpo: 34463 +.. date: 2020-11-20-19-00-27 +.. nonce: aJcm56 +.. section: Library + +Fixed discrepancy between :mod:`traceback` and the interpreter in formatting +of SyntaxError with lineno not set (:mod:`traceback` was changed to match +interpreter). + +.. + +.. bpo: 42393 +.. date: 2020-11-17-22-06-15 +.. nonce: BB0oXc +.. section: Library + +Raise :exc:`OverflowError` instead of silent truncation in +:meth:`socket.ntohs` and :meth:`socket.htons`. Silent truncation was +deprecated in Python 3.7. Patch by Erlend E. Aasland + +.. + +.. bpo: 42222 +.. date: 2020-10-31-10-28-32 +.. nonce: Cfl1eR +.. section: Library + +Harmonized :func:`random.randrange` argument handling to match :func:`range`. + +* The integer test and conversion in ``randrange()`` now uses + :func:`operator.index`. +* Non-integer arguments to ``randrange()`` are deprecated. +* The ``ValueError`` is deprecated in favor of a ``TypeError``. +* It now runs a little faster than before. + +(Contributed by Raymond Hettinger and Serhiy Storchaka.) + +.. + +.. bpo: 42163 +.. date: 2020-10-29-09-22-56 +.. nonce: O4VcCY +.. section: Library + +Restore compatibility for ``uname_result`` around deepcopy and _replace. + +.. + +.. bpo: 42090 +.. date: 2020-10-25-14-48-57 +.. nonce: Ubuc0j +.. section: Library + +``zipfile.Path.joinpath`` now accepts arbitrary arguments, same as +``pathlib.Path.joinpath``. + +.. + +.. bpo: 1635741 +.. date: 2020-10-20-23-28-55 +.. nonce: Iyka3r +.. section: Library + +Port the _csv module to the multi-phase initialization API (:pep:`489`). + +.. + +.. bpo: 42059 +.. date: 2020-10-17-12-42-08 +.. nonce: ZGMZ3D +.. section: Library + +:class:`typing.TypedDict` types created using the alternative call-style +syntax now correctly respect the ``total`` keyword argument when setting +their ``__required_keys__`` and ``__optional_keys__`` class attributes. + +.. + +.. bpo: 41960 +.. date: 2020-10-06-23-59-20 +.. nonce: icQ7Xd +.. section: Library + +Add ``globalns`` and ``localns`` parameters to the :func:`inspect.signature` +and :meth:`inspect.Signature.from_callable`. + +.. + +.. bpo: 41907 +.. date: 2020-10-02-10-19-49 +.. nonce: wiIEsz +.. section: Library + +fix ``format()`` behavior for ``IntFlag`` + +.. + +.. bpo: 41891 +.. date: 2020-09-30-13-35-29 +.. nonce: pNAeYI +.. section: Library + +Ensure asyncio.wait_for waits for task completion + +.. + +.. bpo: 24792 +.. date: 2020-09-11-16-07-00 +.. nonce: Z-ARra +.. section: Library + +Fixed bug where :mod:`zipimporter` sometimes reports an incorrect cause of +import errors. + +.. + +.. bpo: 31904 +.. date: 2020-08-11-17-44-07 +.. nonce: cb13ea +.. section: Library + +Fix site and sysconfig modules for VxWorks RTOS which has no home +directories. + +.. + +.. bpo: 41462 +.. date: 2020-08-03-17-54-32 +.. nonce: ek38d_ +.. section: Library + +Add :func:`os.set_blocking()` support for VxWorks RTOS. + +.. + +.. bpo: 40219 +.. date: 2020-07-13-19-43-11 +.. nonce: MUoJEP +.. section: Library + +Lowered :class:`tkinter.ttk.LabeledScale` dummy widget to prevent hiding +part of the content label. + +.. + +.. bpo: 37193 +.. date: 2020-06-12-21-23-20 +.. nonce: wJximU +.. section: Library + +Fixed memory leak in ``socketserver.ThreadingMixIn`` introduced in Python +3.7. + +.. + +.. bpo: 39068 +.. date: 2019-12-16-17-55-31 +.. nonce: Ti3f9P +.. section: Library + +Fix initialization race condition in :func:`a85encode` and :func:`b85encode` +in :mod:`base64`. Patch by Brandon Stansbury. + +.. + +.. bpo: 17140 +.. date: 2020-12-16-21-06-16 +.. nonce: 1leSEg +.. section: Documentation + +Add documentation for the :class:`multiprocessing.pool.ThreadPool` class. + +.. + +.. bpo: 34398 +.. date: 2019-03-04-18-51-21 +.. nonce: YedUqW +.. section: Documentation + +Prominently feature listings from the glossary in documentation search +results. Patch by Ammar Askar. + +.. + +.. bpo: 42794 +.. date: 2021-01-01-08-52-36 +.. nonce: -7-XGz +.. section: Tests + +Update test_nntplib to use official group name of news.aioe.org for testing. +Patch by Donghee Na. + +.. + +.. bpo: 31904 +.. date: 2020-12-17-15-42-44 +.. nonce: d8g3l0d5 +.. section: Tests + +Skip some asyncio tests on VxWorks. + +.. + +.. bpo: 42641 +.. date: 2020-12-15-17-38-04 +.. nonce: uzwlF_ +.. section: Tests + +Enhance ``test_select.test_select()``: it now takes 500 milliseconds rather than 10 +seconds. Use Python rather than a shell to make the test more portable. + +.. + +.. bpo: 31904 +.. date: 2020-12-09-15-23-28 +.. nonce: ghj38d +.. section: Tests + +Skip some tests in _test_all_chown_common() on VxWorks. + +.. + +.. bpo: 42199 +.. date: 2020-10-29-21-26-46 +.. nonce: KksGCV +.. section: Tests + +Fix bytecode helper assertNotInBytecode. + +.. + +.. bpo: 41443 +.. date: 2020-07-30-18-43-05 +.. nonce: 834gyg +.. section: Tests + +Add more attribute checking in test_posix.py + +.. + +.. bpo: 31904 +.. date: 2020-07-30-18-06-15 +.. nonce: y3d8dk +.. section: Tests + +Disable os.popen and impacted tests on VxWorks + +.. + +.. bpo: 41439 +.. date: 2020-07-30-14-08-58 +.. nonce: yhteoi +.. section: Tests + +Port test_ssl and test_uuid to VxWorks RTOS. + +.. + +.. bpo: 42692 +.. date: 2021-01-04-05-07-30 +.. nonce: OO11SN +.. section: Build + +Fix __builtin_available check on older compilers. Patch by Joshua Root. + +.. + +.. bpo: 27640 +.. date: 2020-12-22-17-57-04 +.. nonce: j3a8r0 +.. section: Build + +Added ``--disable-test-modules`` option to the ``configure`` script: don't +build nor install test modules. Patch by Xavier de Gaye, Thomas Petazzoni +and Peixing Xin. + +.. + +.. bpo: 42604 +.. date: 2020-12-20-02-35-28 +.. nonce: gRd89w +.. section: Build + +Now all platforms use a value for the "EXT_SUFFIX" build variable derived +from SOABI (for instance in freeBSD, "EXT_SUFFIX" is now ".cpython-310d.so" +instead of ".so"). Previously only Linux, Mac and VxWorks were using a value +for "EXT_SUFFIX" that included "SOABI". + +.. + +.. bpo: 42598 +.. date: 2020-12-13-14-43-10 +.. nonce: 7ipr5H +.. section: Build + +Fix implicit function declarations in configure which could have resulted in +incorrect configuration checks. Patch contributed by Joshua Root. + +.. + +.. bpo: 31904 +.. date: 2020-12-11-18-04-38 +.. nonce: j3j6d8 +.. section: Build + +Enable libpython3.so for VxWorks. + +.. + +.. bpo: 29076 +.. date: 2020-02-28-14-33-15 +.. nonce: Gtixi5 +.. section: Build + +Add fish shell support to macOS installer. + +.. + +.. bpo: 42361 +.. date: 2021-01-04-01-17-17 +.. nonce: eolZAi +.. section: macOS + +Update macOS installer build to use Tcl/Tk 8.6.11 (rc2, expected to be final +release). + +.. + +.. bpo: 41837 +.. date: 2021-01-04-00-48-08 +.. nonce: dX-unJ +.. section: macOS + +Update macOS installer build to use OpenSSL 1.1.1i. + +.. + +.. bpo: 42584 +.. date: 2020-12-07-11-37-35 +.. nonce: LygmqQ +.. section: macOS + +Update macOS installer to use SQLite 3.34.0. + +.. + +.. bpo: 42726 +.. date: 2020-12-23-19-42-11 +.. nonce: a5EkTv +.. section: Tools/Demos + +Fixed Python 3 compatibility issue with gdb/libpython.py handling of +attribute dictionaries. + +.. + +.. bpo: 42613 +.. date: 2020-12-16-09-10-32 +.. nonce: J-jnm5 +.. section: Tools/Demos + +Fix ``freeze.py`` tool to use the prope config and library directories. +Patch by Victor Stinner. + +.. + +.. bpo: 42591 +.. date: 2020-12-10-10-43-03 +.. nonce: CXNY8G +.. section: C API + +Export the :c:func:`Py_FrozenMain` function: fix a Python 3.9.0 regression. +Python 3.9 uses ``-fvisibility=hidden`` and the function was not exported +explicitly and so not exported. + +.. + +.. bpo: 32381 +.. date: 2020-12-09-00-35-25 +.. nonce: Je08Ny +.. section: C API + +Remove the private :c:func:`_Py_fopen` function which is no longer needed. +Use :c:func:`_Py_wfopen` or :c:func:`_Py_fopen_obj` instead. Patch by Victor +Stinner. + +.. + +.. bpo: 1635741 +.. date: 2020-11-22-13-46-06 +.. nonce: -fJLzA +.. section: C API + +Port :mod:`resource` extension module to module state + +.. + +.. bpo: 42111 +.. date: 2020-10-21-18-43-06 +.. nonce: 9pvtrc +.. section: C API + +Update the ``xxlimited`` module to be a better example of how to use the +limited C API. + +.. + +.. bpo: 40052 +.. date: 2020-03-24-09-27-10 +.. nonce: 27P2KG +.. section: C API + +Fix an alignment build warning/error in function +``PyVectorcall_Function()``. Patch by Andreas Schneider, Antoine Pitrou and +Petr Viktorin. diff --git a/Misc/NEWS.d/3.10.0a5.rst b/Misc/NEWS.d/3.10.0a5.rst new file mode 100644 index 00000000..dc95e8ce --- /dev/null +++ b/Misc/NEWS.d/3.10.0a5.rst @@ -0,0 +1,670 @@ +.. bpo: 42938 +.. date: 2021-01-18-09-27-31 +.. nonce: 4Zn4Mp +.. release date: 2021-02-02 +.. section: Security + +Avoid static buffers when computing the repr of :class:`ctypes.c_double` and +:class:`ctypes.c_longdouble` values. + +.. + +.. bpo: 42990 +.. date: 2021-01-30-11-31-44 +.. nonce: 69h_zK +.. section: Core and Builtins + +Refactor the ``PyEval_`` family of functions. + +* An new function ``_PyEval_Vector`` is added to simplify calls to Python from C. +* ``_PyEval_EvalCodeWithName`` is removed +* ``PyEval_EvalCodeEx`` is retained as part of the API, but is not used internally + +.. + +.. bpo: 38631 +.. date: 2021-01-29-17-48-44 +.. nonce: jR-3kC +.. section: Core and Builtins + +Replace :c:func:`Py_FatalError` calls in the compiler with regular +:exc:`SystemError` exceptions. Patch by Victor Stinner. + +.. + +.. bpo: 42997 +.. date: 2021-01-24-20-19-55 +.. nonce: QUOPgP +.. section: Core and Builtins + +Improve error message for missing ":" before blocks. Patch by Pablo Galindo. + +.. + +.. bpo: 43017 +.. date: 2021-01-24-18-02-05 +.. nonce: emEcXX +.. section: Core and Builtins + +Improve error message in the parser when using un-parenthesised tuples in +comprehensions. Patch by Pablo Galindo. + +.. + +.. bpo: 42986 +.. date: 2021-01-20-23-44-15 +.. nonce: sWoaGf +.. section: Core and Builtins + +Fix parser crash when reporting syntax errors in f-string with newlines. +Patch by Pablo Galindo. + +.. + +.. bpo: 40176 +.. date: 2021-01-20-22-31-01 +.. nonce: anjyWw +.. section: Core and Builtins + +Syntax errors for unterminated string literals now point to the start of the +string instead of reporting EOF/EOL. + +.. + +.. bpo: 42927 +.. date: 2021-01-15-20-05-56 +.. nonce: GI-l-7 +.. section: Core and Builtins + +The inline cache for ``LOAD_ATTR`` now also optimizes access to attributes +defined by ``__slots__``. This makes reading such attribute up to 30% +faster. + +.. + +.. bpo: 42864 +.. date: 2021-01-14-23-15-34 +.. nonce: QgOAQ1 +.. section: Core and Builtins + +Improve error messages in the parser when parentheses are not closed. Patch +by Pablo Galindo. + +.. + +.. bpo: 42924 +.. date: 2021-01-13-14-06-01 +.. nonce: _WS1Ok +.. section: Core and Builtins + +Fix ``bytearray`` repetition incorrectly copying data from the start of the +buffer, even if the data is offset within the buffer (e.g. after reassigning +a slice at the start of the ``bytearray`` to a shorter byte string). + +.. + +.. bpo: 42882 +.. date: 2021-01-11-17-58-52 +.. nonce: WfTdfg +.. section: Core and Builtins + +Fix the :c:func:`_PyUnicode_FromId` function (_Py_IDENTIFIER(var) API) when +:c:func:`Py_Initialize` / :c:func:`Py_Finalize` is called multiple times: +preserve ``_PyRuntime.unicode_ids.next_index`` value. + +.. + +.. bpo: 42827 +.. date: 2021-01-06-17-06-37 +.. nonce: jtRR0D +.. section: Core and Builtins + +Fix a crash when working out the error line of a :exc:`SyntaxError` in some +multi-line expressions. + +.. + +.. bpo: 42823 +.. date: 2021-01-04-18-17-07 +.. nonce: dcSynu +.. section: Core and Builtins + +frame.f_lineno is correct even if frame.f_trace is set to True + +.. + +.. bpo: 37324 +.. date: 2020-12-12-20-09-12 +.. nonce: jB-9_U +.. section: Core and Builtins + +Remove deprecated aliases to :ref:`collections-abstract-base-classes` from +the :mod:`collections` module. + +.. + +.. bpo: 41994 +.. date: 2020-10-10-14-16-03 +.. nonce: Xop8sV +.. section: Core and Builtins + +Fixed possible leak in ``import`` when ``sys.modules`` is not a ``dict``. + +.. + +.. bpo: 27772 +.. date: 2018-12-20-23-59-23 +.. nonce: idHEcj +.. section: Core and Builtins + +In string formatting, preceding the *width* field by ``'0'`` no longer +affects the default alignment for strings. + +.. + +.. bpo: 43108 +.. date: 2021-02-02-20-23-31 +.. nonce: lqcCZ6 +.. section: Library + +Fixed a reference leak in the :mod:`curses` module. Patch by Pablo Galindo + +.. + +.. bpo: 43077 +.. date: 2021-01-30-15-20-06 +.. nonce: Owk61z +.. section: Library + +Update the bundled pip to 21.0.1 and setuptools to 52.0.0. + +.. + +.. bpo: 41282 +.. date: 2021-01-27-20-49-32 +.. nonce: SEPdV0 +.. section: Library + +Deprecate ``distutils`` in documentation and add warning on import. + +.. + +.. bpo: 43014 +.. date: 2021-01-24-00-37-40 +.. nonce: BVPhEr +.. section: Library + +Improve performance of :mod:`tokenize` by 20-30%. Patch by Anthony Sottile. + +.. + +.. bpo: 42323 +.. date: 2021-01-20-12-10-47 +.. nonce: PONB8e +.. section: Library + +Fix :func:`math.nextafter` for NaN on AIX. + +.. + +.. bpo: 42955 +.. date: 2021-01-18-11-59-46 +.. nonce: CSWLC9 +.. section: Library + +Add :data:`sys.stdlib_module_names`, containing the list of the standard +library module names. Patch by Victor Stinner. + +.. + +.. bpo: 42944 +.. date: 2021-01-18-10-41-44 +.. nonce: RrONvy +.. section: Library + +Fix ``random.Random.sample`` when ``counts`` argument is not ``None``. + +.. + +.. bpo: 42934 +.. date: 2021-01-15-11-48-00 +.. nonce: ILKoOI +.. section: Library + +Use :class:`~traceback.TracebackException`'s new ``compact`` param in +:class:`~unittest.TestResult` to reduce time and memory consumed by +traceback formatting. + +.. + +.. bpo: 42931 +.. date: 2021-01-15-00-23-50 +.. nonce: QD6U2B +.. section: Library + +Add :func:`randbytes` to ``random.__all__``. + +.. + +.. bpo: 38250 +.. date: 2021-01-14-15-07-16 +.. nonce: 1fvhOk +.. section: Library + +[Enum] Flags consisting of a single bit are now considered canonical, and +will be the only flags returned from listing and iterating over a Flag class +or a Flag member. Multi-bit flags are considered aliases; they will be +returned from lookups and operations that result in their value. Iteration +for both Flag and Flag members is in definition order. + +.. + +.. bpo: 42877 +.. date: 2021-01-13-12-55-41 +.. nonce: Fi1zEG +.. section: Library + +Added the ``compact`` parameter to the constructor of +:class:`traceback.TracebackException` to reduce time and memory for use +cases that only need to call :func:`TracebackException.format` and +:func:`TracebackException.format_exception_only`. + +.. + +.. bpo: 42923 +.. date: 2021-01-13-12-15-13 +.. nonce: zBiNls +.. section: Library + +The :c:func:`Py_FatalError` function and the :mod:`faulthandler` module now +dump the list of extension modules on a fatal error. + +.. + +.. bpo: 42848 +.. date: 2021-01-12-19-34-06 +.. nonce: 5G8oBl +.. section: Library + +Removed recursion from :class:`~traceback.TracebackException` to allow it to +handle long exception chains. + +.. + +.. bpo: 42901 +.. date: 2021-01-11-17-36-59 +.. nonce: gFd-ta +.. section: Library + +[Enum] move member creation from ``EnumMeta.__new__`` to +``_proto_member.__set_name__``, allowing members to be created and visible +in ``__init_subclass__``. + +.. + +.. bpo: 42780 +.. date: 2021-01-08-15-49-20 +.. nonce: rtqi6B +.. section: Library + +Fix os.set_inheritable() for O_PATH file descriptors on Linux. + +.. + +.. bpo: 42866 +.. date: 2021-01-08-10-57-21 +.. nonce: Y1DnrO +.. section: Library + +Fix a reference leak in the ``getcodec()`` function of CJK codecs. Patch by +Victor Stinner. + +.. + +.. bpo: 42846 +.. date: 2021-01-07-23-31-17 +.. nonce: kukDjw +.. section: Library + +Convert the 6 CJK codec extension modules (_codecs_cn, _codecs_hk, +_codecs_iso2022, _codecs_jp, _codecs_kr and _codecs_tw) to the multiphase +initialization API (:pep:`489`). Patch by Victor Stinner. + +.. + +.. bpo: 42851 +.. date: 2021-01-07-11-44-22 +.. nonce: uyQFyd +.. section: Library + +remove __init_subclass__ support for Enum members + +.. + +.. bpo: 42834 +.. date: 2021-01-05-23-55-24 +.. nonce: LxRnZC +.. section: Library + +Make internal caches of the ``_json`` module compatible with +subinterpreters. + +.. + +.. bpo: 41748 +.. date: 2021-01-05-21-26-29 +.. nonce: KdC0w3 +.. section: Library + +Fix HTMLParser parsing rules for element attributes containing commas with +spaces. Patch by Karl Dubost. + +.. + +.. bpo: 40810 +.. date: 2021-01-05-00-52-30 +.. nonce: JxQqPe +.. section: Library + +Require SQLite 3.7.15 or newer. Patch by Erlend E. Aasland. + +.. + +.. bpo: 1635741 +.. date: 2021-01-04-15-05-40 +.. nonce: EOCfZY +.. section: Library + +Convert the _multibytecodec extension module (CJK codecs) to multi-phase +initialization (:pep:`489`). Patch by Erlend E. Aasland. + +.. + +.. bpo: 42802 +.. date: 2021-01-01-15-29-16 +.. nonce: Lw-bzl +.. section: Library + +The distutils ``bdist_wininst`` command deprecated in Python 3.8 has been +removed. The distutils ``bdist_wheel`` command is now recommended to +distribute binary packages on Windows. + +.. + +.. bpo: 24464 +.. date: 2020-12-30-14-56-25 +.. nonce: vbNVHe +.. section: Library + +The undocumented built-in function ``sqlite3.enable_shared_cache`` is now +deprecated, scheduled for removal in Python 3.12. Its use is strongly +discouraged by the SQLite3 documentation. Patch by Erlend E. Aasland. + +.. + +.. bpo: 42384 +.. date: 2020-11-17-14-32-39 +.. nonce: 1ZnQSn +.. section: Library + +Make pdb populate sys.path[0] exactly the same as regular python execution. + +.. + +.. bpo: 42383 +.. date: 2020-11-17-14-30-12 +.. nonce: ubl0Y_ +.. section: Library + +Fix pdb: previously pdb would fail to restart the debugging target if it was +specified using a relative path and the current directory changed. + +.. + +.. bpo: 42005 +.. date: 2020-10-11-13-48-03 +.. nonce: Jq6Az- +.. section: Library + +Fix CLI of :mod:`cProfile` and :mod:`profile` to catch +:exc:`BrokenPipeError`. + +.. + +.. bpo: 41604 +.. date: 2020-08-21-15-24-14 +.. nonce: rTXleO +.. section: Library + +Don't decrement the reference count of the previous user_ptr when +set_panel_userptr fails. + +.. + +.. bpo: 41149 +.. date: 2020-06-28-16-13-02 +.. nonce: jiZWtJ +.. section: Library + +Allow executing callables that have a boolean value of ``False`` when passed +to :class:`Threading.thread` as the target. Patch contributed by Barney +Stratford. + +.. + +.. bpo: 38307 +.. date: 2020-03-16-03-03-21 +.. nonce: 2cmw2i +.. section: Library + +Add an 'end_lineno' attribute to the Class and Function objects that appear +in the tree returned by pyclbr functions. This and the existing 'lineno' +attribute define the extent of class and def statements. Patch by Aviral +Srivastava. + +.. + +.. bpo: 39273 +.. date: 2020-01-13-23-37-58 +.. nonce: m5hzxV +.. section: Library + +The ``BUTTON5_*`` constants are now exposed in the :mod:`curses` module if +available. + +.. + +.. bpo: 33289 +.. date: 2018-04-23-13-44-10 +.. nonce: anBnUr +.. section: Library + +Correct call to :mod:`tkinter.colorchooser` to return RGB triplet of ints +instead of floats. Patch by Cheryl Sabella. + +.. + +.. bpo: 40304 +.. date: 2021-01-20-23-03-49 +.. nonce: -LK7Ps +.. section: Documentation + +Fix doc for type(name, bases, dict). Patch by Boris Verkhovskiy and Éric +Araujo. + +.. + +.. bpo: 42811 +.. date: 2021-01-04-22-14-22 +.. nonce: HY2beA +.. section: Documentation + +Updated importlib.util.resolve_name() doc to use __spec__.parent instead of +__package__. (Thanks Yair Frid.) + +.. + +.. bpo: 40823 +.. date: 2020-05-30-13-39-22 +.. nonce: yB7K5w +.. section: Tests + +Use :meth:`unittest.TestLoader().loadTestsFromTestCase` instead of +:meth:`unittest.makeSuite` in :mod:`sqlite3` tests. Patch by Erlend E. +Aasland. + +.. + +.. bpo: 40810 +.. date: 2020-05-30-10-56-38 +.. nonce: LPqDLQ +.. section: Tests + +In :mod:`sqlite3`, fix ``CheckTraceCallbackContent`` for SQLite pre 3.7.15. + +.. + +.. bpo: 43031 +.. date: 2021-01-26-14-48-40 +.. nonce: 44nK9U +.. section: Build + +Pass ``--timeout=$(TESTTIMEOUT)`` option to the default profile task +``./python -m test --pgo`` command. + +.. + +.. bpo: 36143 +.. date: 2021-01-18-20-52-06 +.. nonce: kgnIYo +.. section: Build + +``make regen-all`` now also runs ``regen-keyword``. Patch by Victor Stinner. + +.. + +.. bpo: 42874 +.. date: 2021-01-12-10-06-50 +.. nonce: XKK61g +.. section: Build + +Removed the grep -q and -E flags in the tzpath validation section of the +configure script to better accommodate users of some platforms (specifically +Solaris 10). + +.. + +.. bpo: 31904 +.. date: 2021-01-11-23-26-00 +.. nonce: ty8f3h +.. section: Build + +Add library search path by wr-cc in add_cross_compiling_paths() for VxWorks. + +.. + +.. bpo: 42856 +.. date: 2021-01-07-12-51-38 +.. nonce: n3cMHV +.. section: Build + +Add ``--with-wheel-pkg-dir=PATH`` option to the ``./configure`` script. If +specified, the :mod:`ensurepip` module looks for ``setuptools`` and ``pip`` +wheel packages in this directory: if both are present, these wheel packages +are used instead of ensurepip bundled wheel packages. + +Some Linux distribution packaging policies recommend against bundling +dependencies. For example, Fedora installs wheel packages in the +``/usr/share/python-wheels/`` directory and don't install the +``ensurepip._bundled`` package. + +.. + +.. bpo: 41837 +.. date: 2021-01-05-20-36-40 +.. nonce: bmS7vB +.. section: Windows + +Updated Windows installer to include OpenSSL 1.1.1i + +.. + +.. bpo: 42584 +.. date: 2020-12-07-11-40-52 +.. nonce: AsYnVX +.. section: Windows + +Upgrade Windows installer to use SQLite 3.34.0. + +.. + +.. bpo: 42504 +.. date: 2021-01-26-14-36-11 +.. nonce: ZxWt71 +.. section: macOS + +Ensure that the value of +sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') is always a string, +even in when the value is parsable as an integer. + +.. + +.. bpo: 43008 +.. date: 2021-01-26-18-12-17 +.. nonce: mbQUc7 +.. section: IDLE + +Make IDLE invoke :func:`sys.excepthook` in normal, 2-process mode. Patch by +Ken Hilton. + +.. + +.. bpo: 33065 +.. date: 2021-01-10-01-25-43 +.. nonce: zmyHYJ +.. section: IDLE + +Fix problem debugging user classes with __repr__ method. + +.. + +.. bpo: 23544 +.. date: 2019-11-14-23-41-07 +.. nonce: 3etemb +.. section: IDLE + +Disable Debug=>Stack Viewer when user code is running or Debugger is active, +to prevent hang or crash. Patch by Zackery Spytz. + +.. + +.. bpo: 32631 +.. date: 2019-06-30-20-31-09 +.. nonce: e7_4BG +.. section: IDLE + +Finish zzdummy example extension module: make menu entries work; add +docstrings and tests with 100% coverage. + +.. + +.. bpo: 42979 +.. date: 2021-01-28-01-11-59 +.. nonce: JrGkrm +.. section: C API + +When Python is built in debug mode (with C assertions), calling a type slot +like ``sq_length`` (``__len__()`` in Python) now fails with a fatal error if +the slot succeeded with an exception set, or failed with no exception set. +The error message contains the slot, the type name, and the current +exception (if an exception is set). Patch by Victor Stinner. + +.. + +.. bpo: 43030 +.. date: 2021-01-27-10-27-47 +.. nonce: loDcD_ +.. section: C API + +Fixed a compiler warning in :c:func:`Py_UNICODE_ISSPACE()` on platforms with +signed :c:type:`wchar_t`. diff --git a/Misc/NEWS.d/3.10.0a6.rst b/Misc/NEWS.d/3.10.0a6.rst new file mode 100644 index 00000000..c379b968 --- /dev/null +++ b/Misc/NEWS.d/3.10.0a6.rst @@ -0,0 +1,538 @@ +.. bpo: 42967 +.. date: 2021-02-14-15-59-16 +.. nonce: YApqDS +.. release date: 2021-03-01 +.. section: Security + +Fix web cache poisoning vulnerability by defaulting the query args separator +to ``&``, and allowing the user to choose a custom separator. + +.. + +.. bpo: 43321 +.. date: 2021-02-26-13-17-52 +.. nonce: TCS3ph +.. section: Core and Builtins + +Fix ``SystemError`` raised when ``PyArg_Parse*()`` is used with ``#`` but +without ``PY_SSIZE_T_CLEAN`` defined. + +.. + +.. bpo: 36346 +.. date: 2021-02-22-19-00-00 +.. nonce: uAoni0 +.. section: Core and Builtins + +``PyArg_Parse*()`` functions now emits ``DeprecationWarning`` when ``u`` or +``Z`` format is used. See :pep:`623` for detail. + +.. + +.. bpo: 43277 +.. date: 2021-02-20-16-50-22 +.. nonce: FXkRXk +.. section: Core and Builtins + +Add a new :c:func:`PySet_CheckExact` function to the C-API to check if an +object is an instance of :class:`set` but not an instance of a subtype. +Patch by Pablo Galindo. + +.. + +.. bpo: 42990 +.. date: 2021-02-18-15-12-30 +.. nonce: toAqBH +.. section: Core and Builtins + +The :data:`types.FunctionType` constructor now inherits the current builtins +if the *globals* dictionary has no ``"__builtins__"`` key, rather than using +``{"None": None}`` as builtins: same behavior as :func:`eval` and +:func:`exec` functions. Defining a function with ``def function(...): ...`` +in Python is not affected, globals cannot be overridden with this syntax: it +also inherits the current builtins. Patch by Victor Stinner. + +.. + +.. bpo: 42990 +.. date: 2021-02-17-19-02-21 +.. nonce: SKXHiI +.. section: Core and Builtins + +Functions have a new ``__builtins__`` attribute which is used to look for +builtin symbols when a function is executed, instead of looking into +``__globals__['__builtins__']``. Patch by Mark Shannon and Victor Stinner. + +.. + +.. bpo: 43149 +.. date: 2021-02-07-03-27-14 +.. nonce: 0umPKD +.. section: Core and Builtins + +Improve the error message in the parser for exception groups without +parentheses. Patch by Pablo Galindo. + +.. + +.. bpo: 43121 +.. date: 2021-02-03-22-33-05 +.. nonce: jqcViq +.. section: Core and Builtins + +Fixed an incorrect :exc:`SyntaxError` message for missing comma in literals. +Patch by Pablo Galindo. + +.. + +.. bpo: 42819 +.. date: 2021-01-04-23-54-34 +.. nonce: 4KO6wU +.. section: Core and Builtins + +:mod:`readline`: Explicitly disable bracketed paste in the interactive +interpreter, even if it's set in the inputrc, is enabled by default (eg GNU +Readline 8.1), or a user calls ``readline.read_init_file()``. The Python +REPL has not implemented bracketed paste support. Also, bracketed mode +writes the ``"\x1b[?2004h"`` escape sequence into stdout which causes test +failures in applications that don't support it. It can still be explicitly +enabled by calling ``readline.parse_and_bind("set enable-bracketed-paste +on")``. Patch by Dustin Rodrigues. + +.. + +.. bpo: 42808 +.. date: 2021-01-02-05-10-58 +.. nonce: AOxgxl +.. section: Core and Builtins + +Simple calls to ``type(object)`` are now faster due to the ``vectorcall`` +calling convention. Patch by Dennis Sweeney. + +.. + +.. bpo: 42217 +.. date: 2020-10-31-16-54-00 +.. nonce: GdcHe5 +.. section: Core and Builtins + +Make the compiler merges same co_code and co_linetable objects in a module +like already did for co_consts. + +.. + +.. bpo: 41972 +.. date: 2020-10-23-23-17-23 +.. nonce: kbAwg4 +.. section: Core and Builtins + +Substring search functions such as ``str1 in str2`` and ``str2.find(str1)`` +now sometimes use the "Two-Way" string comparison algorithm to avoid +quadratic behavior on long strings. + +.. + +.. bpo: 42128 +.. date: 2020-10-23-08-54-04 +.. nonce: SWmVEm +.. section: Core and Builtins + +Implement :pep:`634` (structural pattern matching). Patch by Brandt Bucher. + +.. + +.. bpo: 40692 +.. date: 2020-05-19-22-10-05 +.. nonce: ajEhrR +.. section: Core and Builtins + +In the :class:`concurrent.futures.ProcessPoolExecutor`, validate that +:func:`multiprocess.synchronize` is available on a given platform and rely +on that check in the :mod:`concurrent.futures` test suite so we can run +tests that are unrelated to :class:`ProcessPoolExecutor` on those platforms. + +.. + +.. bpo: 38302 +.. date: 2019-09-28-12-23-23 +.. nonce: hsCNgX +.. section: Core and Builtins + +If :func:`object.__ipow__` returns :const:`NotImplemented`, the operator +will correctly fall back to :func:`object.__pow__` and +:func:`object.__rpow__` as expected. + +.. + +.. bpo: 43316 +.. date: 2021-02-25-09-44-36 +.. nonce: k9Gyqn +.. section: Library + +The ``python -m gzip`` command line application now properly fails when +detecting an unsupported extension. It exits with a non-zero exit code and +prints an error message to stderr. + +.. + +.. bpo: 43317 +.. date: 2021-02-25-09-08-55 +.. nonce: qrOOpB +.. section: Library + +Set the chunk size for the ``gzip`` module main function to +io.DEFAULT_BUFFER_SIZE. This is slightly faster than the 1024 bytes constant +that was used previously. + +.. + +.. bpo: 43146 +.. date: 2021-02-23-17-20-16 +.. nonce: JAFplg +.. section: Library + +Handle None in single-arg versions of :func:`~traceback.print_exception` and +:func:`~traceback.format_exception`. + +.. + +.. bpo: 43260 +.. date: 2021-02-20-12-15-29 +.. nonce: 6znAas +.. section: Library + +Fix TextIOWrapper can not flush internal buffer forever after very large +text is written. + +.. + +.. bpo: 43258 +.. date: 2021-02-18-23-30-52 +.. nonce: LeU-q8 +.. section: Library + +Prevent needless allocation of :mod:`sqlite3` aggregate function context +when no rows match an aggregate query. Patch by Erlend E. Aasland. + +.. + +.. bpo: 43251 +.. date: 2021-02-18-14-24-42 +.. nonce: n6WZDw +.. section: Library + +Improve :mod:`sqlite3` error handling: ``sqlite3_column_name()`` failures +now result in :exc:`MemoryError`. Patch by Erlend E. Aasland. + +.. + +.. bpo: 40956 +.. date: 2021-02-10-23-29-50 +.. nonce: LcAbwG +.. section: Library + +Fix segfault in :meth:`sqlite3.Connection.backup` if no argument was +provided. The regression was introduced by PR 23838. Patch by Erlend E. +Aasland. + +.. + +.. bpo: 43172 +.. date: 2021-02-10-06-00-53 +.. nonce: ZMCJni +.. section: Library + +The readline module now passes its tests when built directly against +libedit. Existing irreconcilable API differences remain in +:func:`readline.get_begidx` and :func:`readline.get_endidx` behavior based +on libreadline vs libedit use. + +.. + +.. bpo: 43163 +.. date: 2021-02-08-21-13-51 +.. nonce: E2MgzH +.. section: Library + +Fix a bug in :mod:`codeop` that was causing it to not ask for more input +when multi-line snippets have unclosed parentheses. Patch by Pablo Galindo + +.. + +.. bpo: 43162 +.. date: 2021-02-08-16-27-00 +.. nonce: t-W7h3 +.. section: Library + +deprecate unsupported ability to access enum members as attributes of other +enum members + +.. + +.. bpo: 43146 +.. date: 2021-02-06-21-21-35 +.. nonce: MHtb2v +.. section: Library + +Fix recent regression in None argument handling in :mod:`~traceback` module +functions. + +.. + +.. bpo: 43102 +.. date: 2021-02-03-22-55-27 +.. nonce: TSlZ6J +.. section: Library + +The namedtuple __new__ method had its __builtins__ set to None instead of an +actual dictionary. This created problems for introspection tools. + +.. + +.. bpo: 43106 +.. date: 2021-02-03-17-06-38 +.. nonce: SwcSuU +.. section: Library + +Added :const:`~os.O_EVTONLY`, :const:`~os.O_FSYNC`, :const:`~os.O_SYMLINK` and +:const:`~os.O_NOFOLLOW_ANY` for macOS. Patch by Donghee Na. + +.. + +.. bpo: 42960 +.. date: 2021-01-18-21-07-20 +.. nonce: a7Dote +.. section: Library + +Adds :const:`resource.RLIMIT_KQUEUES` constant from FreeBSD to the +:mod:`resource` module. + +.. + +.. bpo: 42151 +.. date: 2020-10-26-18-01-09 +.. nonce: et5f7s +.. section: Library + +Make the pure Python implementation of :mod:`xml.etree.ElementTree` behave +the same as the C implementation (:mod:`_elementree`) regarding default +attribute values (by not setting ``specified_attributes=1``). + +.. + +.. bpo: 29753 +.. date: 2020-05-02-01-01-30 +.. nonce: n2M-AF +.. section: Library + +In ctypes, now packed bitfields are calculated properly and the first item +of packed bitfields is now shrank correctly. + +.. + +.. bpo: 27646 +.. date: 2021-02-20-00-09-13 +.. nonce: HRsmo- +.. section: Documentation + +Clarify that 'yield from <expr>' works with any iterable, not just +iterators. + +.. + +.. bpo: 36346 +.. date: 2020-06-15-10-45-45 +.. nonce: H0sS_i +.. section: Documentation + +Update some deprecated unicode APIs which are documented as "will be removed +in 4.0" to "3.12". See :pep:`623` for detail. + +.. + +.. bpo: 43288 +.. date: 2021-02-21-11-11-53 +.. nonce: LfTvL- +.. section: Tests + +Fix test_importlib to correctly skip Unicode file tests if the filesystem +does not support them. + +.. + +.. bpo: 43174 +.. date: 2021-02-10-14-11-53 +.. nonce: F9zwXQ +.. section: Build + +Windows build now uses ``/utf-8`` compiler option. + +.. + +.. bpo: 43103 +.. date: 2021-02-02-16-26-44 +.. nonce: VWeyP_ +.. section: Build + +Add a new configure ``--without-static-libpython`` option to not build the +``libpythonMAJOR.MINOR.a`` static library and not install the ``python.o`` +object file. + +.. + +.. bpo: 13501 +.. date: 2021-01-10-22-25-23 +.. nonce: g4L-6R +.. section: Build + +The configure script can now use *libedit* instead of *readline* with the +command line option ``--with-readline=editline``. + +.. + +.. bpo: 42603 +.. date: 2020-12-08-19-25-20 +.. nonce: mXs2dB +.. section: Build + +Make configure script use pkg-config to detect the location of Tcl/Tk +headers and libraries, used to build tkinter. + +On macOS, a Tcl/Tk configuration provided by pkg-config will be preferred +over Tcl/Tk frameworks installed in ``/{System/,}Library/Frameworks``. If +both exist and the latter is preferred, the appropriate ``--with-tcltk-*`` +configuration options need to be explicitly set. + +.. + +.. bpo: 39448 +.. date: 2020-01-24-12-54-22 +.. nonce: k4pv14 +.. section: Build + +Add the "regen-frozen" makefile target that regenerates the code for the +frozen ``__hello__`` module. + +.. + +.. bpo: 43155 +.. date: 2021-02-10-04-16-51 +.. nonce: O1tURk +.. section: Windows + +:c:func:`PyCMethod_New` is now present in ``python3.lib``. + +.. + +.. bpo: 41837 +.. date: 2021-02-28-22-49-46 +.. nonce: 9fqyXC +.. section: macOS + +Update macOS installer build to use OpenSSL 1.1.1j. + +.. + +.. bpo: 43283 +.. date: 2021-02-21-16-30-10 +.. nonce: DLBwYn +.. section: IDLE + +Document why printing to IDLE's Shell is often slower than printing to a +system terminal and that it can be made faster by pre-formatting a single +string before printing. + +.. + +.. bpo: 43278 +.. date: 2021-02-21-15-30-38 +.. nonce: DMPaWH +.. section: C API + +Always put compiler and system information on the first line of the REPL +welcome message. + +.. + +.. bpo: 43270 +.. date: 2021-02-19-14-28-26 +.. nonce: UKx4XN +.. section: C API + +Remove the private ``_PyErr_OCCURRED()`` macro: use the public +:c:func:`PyErr_Occurred` function instead. + +.. + +.. bpo: 35134 +.. date: 2021-02-18-18-46-42 +.. nonce: dFpEDT +.. section: C API + +Move odictobject.h, parser_interface.h, picklebufobject.h, pydebug.h, and +pyfpe.h into the cpython/ directory. They must not be included directly, as +they are already included by Python.h: :ref:`Include Files <api-includes>`. + +.. + +.. bpo: 35134 +.. date: 2021-02-17-18-51-26 +.. nonce: YoQdk8 +.. section: C API + +Move pyarena.h, pyctype.h, and pytime.h into the cpython/ directory. They +must not be included directly, as they are already included by Python.h: +:ref:`Include Files <api-includes>`. + +.. + +.. bpo: 40170 +.. date: 2021-02-16-22-29-39 +.. nonce: ahHmOo +.. section: C API + +:c:func:`PyExceptionClass_Name` is now always declared as a function, in +order to hide implementation details. The macro accessed +:c:member:`PyTypeObject.tp_name` directly. Patch by Erlend E. Aasland. + +.. + +.. bpo: 43239 +.. date: 2021-02-16-17-30-16 +.. nonce: FQqOGz +.. section: C API + +The :c:func:`PyCFunction_New` function is now exported in the ABI when +compiled with ``-fvisibility=hidden``. + +.. + +.. bpo: 40170 +.. date: 2021-02-15-15-06-43 +.. nonce: ZYeSii +.. section: C API + +:c:func:`PyIter_Check` is now always declared as a function, in order to +hide implementation details. The macro accessed +:c:member:`PyTypeObject.tp_iternext` directly. Patch by Erlend E. Aasland. + +.. + +.. bpo: 40170 +.. date: 2021-02-15-13-41-14 +.. nonce: r2FAtl +.. section: C API + +Convert :c:func:`PyDescr_IsData` macro to a function to hide implementation +details: The macro accessed :c:member:`PyTypeObject.tp_descr_set` directly. +Patch by Erlend E. Aasland. + +.. + +.. bpo: 43181 +.. date: 2021-02-11-11-37-14 +.. nonce: ydv33S +.. section: C API + +Convert :c:func:`PyObject_TypeCheck` macro to a static inline function. +Patch by Erlend E. Aasland. diff --git a/Misc/NEWS.d/3.10.0a7.rst b/Misc/NEWS.d/3.10.0a7.rst new file mode 100644 index 00000000..3a1694f4 --- /dev/null +++ b/Misc/NEWS.d/3.10.0a7.rst @@ -0,0 +1,983 @@ +.. bpo: 42988 +.. date: 2021-03-24-14-16-56 +.. nonce: P2aNco +.. release date: 2021-04-05 +.. section: Security + +CVE-2021-3426: Remove the ``getfile`` feature of the :mod:`pydoc` module +which could be abused to read arbitrary files on the disk (directory +traversal vulnerability). Moreover, even source code of Python modules can +contain sensitive data like passwords. Vulnerability reported by David +Schwörer. + +.. + +.. bpo: 43285 +.. date: 2021-03-13-03-48-14 +.. nonce: g-Hah3 +.. section: Security + +:mod:`ftplib` no longer trusts the IP address value returned from the server +in response to the PASV command by default. This prevents a malicious FTP +server from using the response to probe IPv4 address and port combinations +on the client network. + +Code that requires the former vulnerable behavior may set a +``trust_server_pasv_ipv4_address`` attribute on their :class:`ftplib.FTP` +instances to ``True`` to re-enable it. + +.. + +.. bpo: 43439 +.. date: 2021-03-08-23-06-07 +.. nonce: 5U3lXm +.. section: Security + +Add audit hooks for :func:`gc.get_objects`, :func:`gc.get_referrers` and +:func:`gc.get_referents`. Patch by Pablo Galindo. + +.. + +.. bpo: 27129 +.. date: 2021-04-03-22-04-46 +.. nonce: u_ehHb +.. section: Core and Builtins + +Update CPython bytecode magic number. + +.. + +.. bpo: 43672 +.. date: 2021-03-31-09-12-54 +.. nonce: jTT5uG +.. section: Core and Builtins + +Raise ImportWarning when calling find_loader(). + +.. + +.. bpo: 43660 +.. date: 2021-03-29-19-50-34 +.. nonce: scTgag +.. section: Core and Builtins + +Fix crash that happens when replacing ``sys.stderr`` with a callable that +can remove the object while an exception is being printed. Patch by Pablo +Galindo. + +.. + +.. bpo: 27129 +.. date: 2021-03-29-16-20-29 +.. nonce: BF03A5 +.. section: Core and Builtins + +The bytecode interpreter uses instruction, rather byte, offsets internally. +This reduces the number of EXTENDED_ARG instructions needed and streamlines +instruction dispatch a bit. + +.. + +.. bpo: 40645 +.. date: 2021-03-29-11-55-06 +.. nonce: PhaT-B +.. section: Core and Builtins + +Fix reference leak in the :mod:`_hashopenssl` extension. Patch by Pablo +Galindo. + +.. + +.. bpo: 42134 +.. date: 2021-03-26-17-30-19 +.. nonce: G4Sjxg +.. section: Core and Builtins + +Calls to find_module() by the import system now raise ImportWarning. + +.. + +.. bpo: 41064 +.. date: 2021-03-24-00-32-20 +.. nonce: _H0K_g +.. section: Core and Builtins + +Improve the syntax error for invalid usage of double starred elements ('**') +in f-strings. Patch by Pablo Galindo. + +.. + +.. bpo: 43575 +.. date: 2021-03-21-12-26-32 +.. nonce: pl-nSg +.. section: Core and Builtins + +Speed up calls to ``map()`` by using the :pep:`590` ``vectorcall`` calling +convention. Patch by Donghee Na. + +.. + +.. bpo: 42137 +.. date: 2021-03-20-19-54-47 +.. nonce: A8aQvj +.. section: Core and Builtins + +The import system now prefers using ``__spec__`` for ``ModuleType.__repr__`` +over ``module_repr()``. + +.. + +.. bpo: 43452 +.. date: 2021-03-20-01-21-37 +.. nonce: tDVJkc +.. section: Core and Builtins + +Added micro-optimizations to ``_PyType_Lookup()`` to improve cache lookup +performance in the common case of cache hits. + +.. + +.. bpo: 43555 +.. date: 2021-03-19-22-49-40 +.. nonce: ZmhYSA +.. section: Core and Builtins + +Report the column offset for :exc:`SyntaxError` for invalid line +continuation characters. Patch by Pablo Galindo. + +.. + +.. bpo: 43517 +.. date: 2021-03-16-17-12-54 +.. nonce: zAo6Ws +.. section: Core and Builtins + +Fix misdetection of circular imports when using ``from pkg.mod import +attr``, which caused false positives in non-trivial multi-threaded code. + +.. + +.. bpo: 43497 +.. date: 2021-03-15-07-50-30 +.. nonce: Uc5ZCJ +.. section: Core and Builtins + +Emit SyntaxWarnings for assertions with tuple constants, this is a +regression introduced in python3.7 + +.. + +.. bpo: 39316 +.. date: 2021-03-14-16-44-50 +.. nonce: Ns3a_F +.. section: Core and Builtins + +Tracing now has correct line numbers for attribute accesses when the +attribute is on a different line from the object. Improves debugging and +profiling for multi-line method chains. + +.. + +.. bpo: 35883 +.. date: 2021-03-13-13-57-21 +.. nonce: UyGpdG +.. section: Core and Builtins + +Python no longer fails at startup with a fatal error if a command line +argument contains an invalid Unicode character. The +:c:func:`Py_DecodeLocale` function now escapes byte sequences which would be +decoded as Unicode characters outside the [U+0000; U+10ffff] range. + +.. + +.. bpo: 43410 +.. date: 2021-03-05-17-23-36 +.. nonce: lCzIg0 +.. section: Core and Builtins + +Fix a bug that was causing the parser to crash when emitting syntax errors +when reading input from stdin. Patch by Pablo Galindo + +.. + +.. bpo: 43406 +.. date: 2021-03-04-22-53-10 +.. nonce: Na_VpA +.. section: Core and Builtins + +Fix a possible race condition where ``PyErr_CheckSignals`` tries to execute +a non-Python signal handler. + +.. + +.. bpo: 42128 +.. date: 2021-03-03-19-04-23 +.. nonce: VouZjn +.. section: Core and Builtins + +Add ``__match_args__`` to :ref:`struct sequence objects <struct-sequence-objects>`. +Patch by Pablo Galindo. + +.. + +.. bpo: 43390 +.. date: 2021-03-03-17-58-49 +.. nonce: epPpwV +.. section: Core and Builtins + +CPython now sets the ``SA_ONSTACK`` flag in ``PyOS_setsig`` for the VM's +default signal handlers. This is friendlier to other in-process code that +an extension module or embedding use could pull in (such as Golang's cgo) +where tiny thread stacks are the norm and ``sigaltstack()`` has been used to +provide for signal handlers. This is a no-op change for the vast majority +of processes that don't use sigaltstack. + +.. + +.. bpo: 43287 +.. date: 2021-02-22-03-01-02 +.. nonce: aTs6fO +.. section: Core and Builtins + +Speed up calls to ``filter()`` by using the :pep:`590` ``vectorcall`` +calling convention. Patch by Donghee Na. + +.. + +.. bpo: 37448 +.. date: 2021-02-21-14-19-35 +.. nonce: btl7vO +.. section: Core and Builtins + +Add a radix tree based memory map to track in-use obmalloc arenas. Use to +replace the old implementation of address_in_range(). The radix tree +approach makes it easy to increase pool sizes beyond the OS page size. +Boosting the pool and arena size allows obmalloc to handle a significantly +higher percentage of requests from its ultra-fast paths. + +It also has the advantage of eliminating the memory unsanitary behavior of +the previous address_in_range(). The old address_in_range() was marked with +the annotations _Py_NO_SANITIZE_ADDRESS, _Py_NO_SANITIZE_THREAD, and +_Py_NO_SANITIZE_MEMORY. Those annotations are no longer needed. + +To disable the radix tree map, set a preprocessor flag as follows: +`-DWITH_PYMALLOC_RADIX_TREE=0`. + +Co-authored-by: Tim Peters <tim.peters@gmail.com> + +.. + +.. bpo: 29988 +.. date: 2020-02-03-13-23-10 +.. nonce: 8_UB5w +.. section: Core and Builtins + +Only handle asynchronous exceptions and requests to drop the GIL when +returning from a call or on the back edges of loops. Makes sure that +:meth:`__exit__` is always called in with statements, even for interrupts. + +.. + +.. bpo: 43720 +.. date: 2021-04-03-13-45-51 +.. nonce: FDZ5cZ +.. section: Library + +Document various stdlib deprecations in imp, pkgutil, and importlib.util for +removal in Python 3.12. + +.. + +.. bpo: 43433 +.. date: 2021-03-28-23-50-20 +.. nonce: so9j5G +.. section: Library + +:class:`xmlrpc.client.ServerProxy` no longer ignores query and fragment in +the URL of the server. + +.. + +.. bpo: 31956 +.. date: 2021-03-28-16-53-25 +.. nonce: Lt_67U +.. section: Library + +The :meth:`~array.array.index` method of :class:`array.array` now has +optional *start* and *stop* parameters. + +.. + +.. bpo: 40066 +.. date: 2021-03-25-21-26-30 +.. nonce: 7EBQ3_ +.. section: Library + +Enum: adjust ``repr()`` to show only enum and member name (not value, nor +angle brackets) and ``str()`` to show only member name. Update and improve +documentation to match. + +.. + +.. bpo: 42136 +.. date: 2021-03-25-08-44-26 +.. nonce: rRY9e1 +.. section: Library + +Deprecate all module_repr() methods found in importlib as their use is being +phased out by Python 3.12. + +.. + +.. bpo: 35930 +.. date: 2021-03-23-17-18-56 +.. nonce: RZ51pM +.. section: Library + +Raising an exception raised in a "future" instance will create reference +cycles. + +.. + +.. bpo: 41369 +.. date: 2021-03-21-17-50-42 +.. nonce: -fpmYZ +.. section: Library + +Finish updating the vendored libmpdec to version 2.5.1. Patch by Stefan +Krah. + +.. + +.. bpo: 43422 +.. date: 2021-03-21-17-02-52 +.. nonce: POk6cU +.. section: Library + +Revert the _decimal C API which was added in bpo-41324. + +.. + +.. bpo: 43577 +.. date: 2021-03-21-10-13-17 +.. nonce: m7JnAV +.. section: Library + +Fix deadlock when using :class:`ssl.SSLContext` debug callback with +:meth:`ssl.SSLContext.sni_callback`. + +.. + +.. bpo: 43571 +.. date: 2021-03-20-17-40-35 +.. nonce: acAL0W +.. section: Library + +It's now possible to create MPTCP sockets with IPPROTO_MPTCP + +.. + +.. bpo: 43542 +.. date: 2021-03-20-15-43-25 +.. nonce: 6bt2F6 +.. section: Library + +``image/heic`` and ``image/heif`` were added to :mod:`mimetypes`. + +.. + +.. bpo: 40645 +.. date: 2021-03-19-10-22-17 +.. nonce: 5pXhb- +.. section: Library + +The :mod:`hmac` module now uses OpenSSL's HMAC implementation when digestmod +argument is a hash name or builtin hash function. + +.. + +.. bpo: 43510 +.. date: 2021-03-16-17-20-33 +.. nonce: -BeQH_ +.. section: Library + +Implement :pep:`597`: Add ``EncodingWarning`` warning, ``-X +warn_default_encoding`` option, :envvar:`PYTHONWARNDEFAULTENCODING` +environment variable and ``encoding="locale"`` argument value. + +.. + +.. bpo: 43521 +.. date: 2021-03-16-16-05-02 +.. nonce: mRT6fh +.. section: Library + +``ast.unparse`` can now render NaNs and empty sets. + +.. + +.. bpo: 42914 +.. date: 2021-03-14-21-47-28 +.. nonce: 9U1o33 +.. section: Library + +:func:`pprint.pprint` gains a new boolean ``underscore_numbers`` optional +argument to emit integers with thousands separated by an underscore +character for improved readability (for example ``1_000_000`` instead of +``1000000``). + +.. + +.. bpo: 41361 +.. date: 2021-03-13-08-18-01 +.. nonce: lXDIlr +.. section: Library + +:meth:`~collections.deque.rotate` calls are now slightly faster due to +faster argument parsing. + +.. + +.. bpo: 43423 +.. date: 2021-03-11-15-44-18 +.. nonce: rRomRD +.. section: Library + +:func:`subprocess.communicate` no longer raises an IndexError when there is +an empty stdout or stderr IO buffer during a timeout on Windows. + +.. + +.. bpo: 27820 +.. date: 2021-03-10-14-07-44 +.. nonce: Wwdy-r +.. section: Library + +Fixed long-standing bug of smtplib.SMTP where doing AUTH LOGIN with +initial_response_ok=False will fail. + +The cause is that SMTP.auth_login _always_ returns a password if provided +with a challenge string, thus non-compliant with the standard for AUTH +LOGIN. + +Also fixes bug with the test for smtpd. + +.. + +.. bpo: 43445 +.. date: 2021-03-09-11-36-19 +.. nonce: jnj-UB +.. section: Library + +Add frozen modules to :data:`sys.stdlib_module_names`. For example, add +``"_frozen_importlib"`` and ``"_frozen_importlib_external"`` names. + +.. + +.. bpo: 43245 +.. date: 2021-03-08-22-14-37 +.. nonce: nXL-MC +.. section: Library + +Add keyword arguments support to ``ChainMap.new_child()``. + +.. + +.. bpo: 29982 +.. date: 2021-03-07-23-23-03 +.. nonce: Q9iszT +.. section: Library + +Add optional parameter *ignore_cleanup_errors* to +:func:`tempfile.TemporaryDirectory` and allow multiple :func:`cleanup` +attempts. Contributed by C.A.M. Gerlach. + +.. + +.. bpo: 43428 +.. date: 2021-03-07-18-54-39 +.. nonce: br0XmX +.. section: Library + +Include changes from `importlib_metadata 3.7 +<https://importlib-metadata.readthedocs.io/en/latest/history.html#v3-7-0>`_: + +Performance enhancements to distribution discovery. + +``entry_points`` only returns unique distributions. + +Introduces new ``EntryPoints`` object for containing a set of entry points +with convenience methods for selecting entry points by group or name. +``entry_points`` now returns this object if selection parameters are +supplied but continues to return a dict object for compatibility. Users are +encouraged to rely on the selection interface. The dict object result is +likely to be deprecated in the future. + +Added packages_distributions function to return a mapping of packages to the +distributions that provide them. + +.. + +.. bpo: 43332 +.. date: 2021-03-07-11-23-20 +.. nonce: weatsh +.. section: Library + +Improves the networking efficiency of :mod:`http.client` when using a proxy +via :meth:`~HTTPConnection.set_tunnel`. Fewer small send calls are made +during connection setup. + +.. + +.. bpo: 43420 +.. date: 2021-03-07-08-03-31 +.. nonce: cee_X5 +.. section: Library + +Improve performance of :class:`fractions.Fraction` arithmetics for large +components. Contributed by Sergey B. Kirpichev. + +.. + +.. bpo: 43356 +.. date: 2021-03-04-21-51-20 +.. nonce: X7IGBM +.. section: Library + +Allow passing a signal number to ``_thread.interrupt_main()``. + +.. + +.. bpo: 43399 +.. date: 2021-03-04-17-53-46 +.. nonce: Wn95u- +.. section: Library + +Fix ``ElementTree.extend`` not working on iterators when using the Python +implementation + +.. + +.. bpo: 43369 +.. date: 2021-03-02-15-25-28 +.. nonce: F4knlQ +.. section: Library + +Improve :mod:`sqlite3` error handling: If ``sqlite3_column_text()`` and +``sqlite3_column_blob()`` set ``SQLITE_NOMEM``, :exc:`MemoryError` is now +raised. Patch by Erlend E. Aasland. + +.. + +.. bpo: 43368 +.. date: 2021-03-02-13-45-05 +.. nonce: t9XEkQ +.. section: Library + +Fix a regression introduced in PR 24562, where an empty bytestring was +fetched as ``None`` instead of ``b''`` in :mod:`sqlite3`. Patch by Mariusz +Felisiak. + +.. + +.. bpo: 41282 +.. date: 2021-03-02-09-54-22 +.. nonce: xL4h94 +.. section: Library + +Fixed stacklevel of ``DeprecationWarning`` emitted from ``import +distutils``. + +.. + +.. bpo: 42129 +.. date: 2021-02-28-04-21-35 +.. nonce: V0KifQ +.. section: Library + +``importlib.resources`` now honors namespace packages, merging resources +from each location in the namespace as introduced in ``importlib_resources`` +3.2 and including incidental changes through 5.0.3. + +.. + +.. bpo: 43295 +.. date: 2021-02-22-22-54-40 +.. nonce: h_ffu7 +.. section: Library + +:meth:`datetime.datetime.strptime` now raises ``ValueError`` instead of +``IndexError`` when matching ``'z'`` with the ``%z`` format specifier. + +.. + +.. bpo: 43125 +.. date: 2021-02-07-19-13-30 +.. nonce: AqNoMa +.. section: Library + +Return empty string if base64mime.body_encode receive empty bytes + +.. + +.. bpo: 43084 +.. date: 2021-01-31-17-31-13 +.. nonce: i8nLpK +.. section: Library + +:func:`curses.window.enclose` returns now ``True`` or ``False`` (as was +documented) instead of ``1`` or ``0``. + +.. + +.. bpo: 42994 +.. date: 2021-01-21-16-58-34 +.. nonce: El0Ksp +.. section: Library + +Add MIME types for opus, AAC, 3gpp and 3gpp2 + +.. + +.. bpo: 14678 +.. date: 2021-01-07-21-25-49 +.. nonce: 1zniCH +.. section: Library + +Add an invalidate_caches() method to the zipimport.zipimporter class to +support importlib.invalidate_caches(). Patch by Desmond Cheong. + +.. + +.. bpo: 42782 +.. date: 2020-12-29-13-46-57 +.. nonce: 3r0HFY +.. section: Library + +Fail fast in :func:`shutil.move()` to avoid creating destination directories +on failure. + +.. + +.. bpo: 40066 +.. date: 2020-09-23-21-58-34 +.. nonce: f1dr_5 +.. section: Library + +Enum's `repr()` and `str()` have changed: `repr()` is now +*EnumClass.MemberName* and `str()` is *MemberName*. Additionally, stdlib +Enum's whose contents are available as module attributes, such as +`RegexFlag.IGNORECASE`, have their `repr()` as *module.name*, e.g. +`re.IGNORECASE`. + +.. + +.. bpo: 26053 +.. date: 2020-09-01-10-12-13 +.. nonce: hXikw_ +.. section: Library + +Fixed bug where the :mod:`pdb` interactive run command echoed the args from +the shell command line, even if those have been overridden at the pdb +prompt. + +.. + +.. bpo: 24160 +.. date: 2020-08-28-23-07-53 +.. nonce: MSGnKr +.. section: Library + +Fixed bug where breakpoints did not persist across multiple debugger +sessions in :mod:`pdb`'s interactive mode. + +.. + +.. bpo: 40701 +.. date: 2020-05-27-05-42-39 +.. nonce: PBIgW1 +.. section: Library + +When the :data:`tempfile.tempdir` global variable is set to a value of type +bytes, it is now handled consistently. Previously exceptions could be +raised from some tempfile APIs when the directory did not already exist in +this situation. Also ensures that the :func:`tempfile.gettempdir()` and +:func:`tempfile.gettempdirb()` functions *always* return ``str`` and +``bytes`` respectively. + +.. + +.. bpo: 39342 +.. date: 2020-01-15-11-15-35 +.. nonce: S8PuJO +.. section: Library + +Expose ``X509_V_FLAG_ALLOW_PROXY_CERTS`` as +:const:`~ssl.VERIFY_ALLOW_PROXY_CERTS` to allow proxy certificate validation +as explained in +https://www.openssl.org/docs/man1.1.1/man7/proxy-certificates.html. + +.. + +.. bpo: 31861 +.. date: 2018-08-24-01-08-09 +.. nonce: -q9RKJ +.. section: Library + +Add builtins.aiter and builtins.anext. Patch by Joshua Bronson (@jab), +Daniel Pope (@lordmauve), and Justin Wang (@justin39). + +.. + +.. bpo: 43199 +.. date: 2021-03-13-18-43-54 +.. nonce: ZWA6KX +.. section: Documentation + +Answer "Why is there no goto?" in the Design and History FAQ. + +.. + +.. bpo: 43407 +.. date: 2021-03-04-22-53-03 +.. nonce: x570l5 +.. section: Documentation + +Clarified that a result from :func:`time.monotonic`, +:func:`time.perf_counter`, :func:`time.process_time`, or +:func:`time.thread_time` can be compared with the result from any following +call to the same function - not just the next immediate call. + +.. + +.. bpo: 43354 +.. date: 2021-03-02-12-55-34 +.. nonce: ezZYkx +.. section: Documentation + +Fix type documentation for ``Fault.faultCode``; the type has to be ``int`` +instead of ``str``. + +.. + +.. bpo: 41933 +.. date: 2020-10-05-20-04-43 +.. nonce: Pff94- +.. section: Documentation + +Clarified wording of s * n in the Common Sequence Operations + +.. + +.. bpo: 37945 +.. date: 2021-03-31-11-38-42 +.. nonce: HTUYhv +.. section: Tests + +Fix test_getsetlocale_issue1813() of test_locale: skip the test if +``setlocale()`` fails. Patch by Victor Stinner. + +.. + +.. bpo: 41561 +.. date: 2021-03-18-10-34-42 +.. nonce: pDg4w- +.. section: Tests + +Add workaround for Ubuntu's custom OpenSSL security level policy. + +.. + +.. bpo: 43179 +.. date: 2021-03-31-12-20-23 +.. nonce: Qbe1OD +.. section: Build + +Introduce and correctly use ALIGNOF_X in place of SIZEOF_X for +alignment-related code in optimized string routines. Patch by Jessica +Clarke. + +.. + +.. bpo: 43631 +.. date: 2021-03-26-09-16-34 +.. nonce: msJyPi +.. section: Build + +Update macOS, Windows, and CI to OpenSSL 1.1.1k. + +.. + +.. bpo: 43617 +.. date: 2021-03-24-16-55-55 +.. nonce: d69KAv +.. section: Build + +Improve configure.ac: Check for presence of autoconf-archive package and +remove our copies of M4 macros. + +.. + +.. bpo: 43466 +.. date: 2021-03-11-00-14-47 +.. nonce: N861Z5 +.. section: Build + +The ``configure`` script now supports ``--with-openssl-rpath`` option. + +.. + +.. bpo: 43372 +.. date: 2021-03-04-17-13-57 +.. nonce: FfqDVL +.. section: Build + +Use ``_freeze_importlib`` to generate code for the ``__hello__`` module. +This approach ensures the code matches the interpreter version. Previously, +PYTHON_FOR_REGEN was used to generate the code, which might be wrong. The +marshal format for code objects has changed with bpo-42246, commit 877df851. +Update the code and the expected code sizes in ctypes test_frozentable. + +.. + +.. bpo: 43440 +.. date: 2021-03-09-11-15-41 +.. nonce: igy2Mn +.. section: Windows + +Build :mod:`sqlite3` with the ``R*Tree`` module enabled. Patch by Erlend E. +Aasland. + +.. + +.. bpo: 42225 +.. date: 2021-03-29-16-22-27 +.. nonce: iIeiLg +.. section: IDLE + +Document that IDLE can fail on Unix either from misconfigured IP masquerade +rules or failure displaying complex colored (non-ascii) characters. + +.. + +.. bpo: 43688 +.. date: 2021-04-01-09-10-42 +.. nonce: G4gs6k +.. section: C API + +The limited C API is now supported if Python is built in debug mode (if the +``Py_DEBUG`` macro is defined). In the limited C API, the +:c:func:`Py_INCREF` and :c:func:`Py_DECREF` functions are now implemented as +opaque function calls, rather than accessing directly the +:c:member:`PyObject.ob_refcnt` member, if Python is built in debug mode and +the ``Py_LIMITED_API`` macro targets Python 3.10 or newer. It became +possible to support the limited C API in debug mode because the +:c:type:`PyObject` structure is the same in release and debug mode since +Python 3.8 (see :issue:`36465`). + +The limited C API is still not supported in the ``--with-trace-refs`` +special build (``Py_TRACE_REFS`` macro). + +Patch by Victor Stinner. + +.. + +.. bpo: 43244 +.. date: 2021-03-24-01-22-14 +.. nonce: 31-97x +.. section: C API + +Remove the ``pyarena.h`` header file with functions: + +* ``PyArena_New()`` +* ``PyArena_Free()`` +* ``PyArena_Malloc()`` +* ``PyArena_AddPyObject()`` + +These functions were undocumented, excluded from the limited C API, and were +only used internally by the compiler. Patch by Victor Stinner. + +.. + +.. bpo: 43244 +.. date: 2021-03-23-20-53-41 +.. nonce: VK3sLH +.. section: C API + +Remove the compiler and parser functions using ``struct _mod`` type, because +the public AST C API was removed: + +* ``PyAST_Compile()`` +* ``PyAST_CompileEx()`` +* ``PyAST_CompileObject()`` +* ``PyFuture_FromAST()`` +* ``PyFuture_FromASTObject()`` +* ``PyParser_ASTFromFile()`` +* ``PyParser_ASTFromFileObject()`` +* ``PyParser_ASTFromFilename()`` +* ``PyParser_ASTFromString()`` +* ``PyParser_ASTFromStringObject()`` + +These functions were undocumented and excluded from the limited C API. Patch +by Victor Stinner. + +.. + +.. bpo: 43244 +.. date: 2021-03-19-12-56-11 +.. nonce: VuIyOD +.. section: C API + +Remove ``ast.h``, ``asdl.h``, and ``Python-ast.h`` header files. These +functions were undocumented and excluded from the limited C API. Most names +defined by these header files were not prefixed by ``Py`` and so could +create names conflicts. For example, ``Python-ast.h`` defined a ``Yield`` +macro which was conflict with the ``Yield`` name used by the Windows +``<winbase.h>`` header. Use the Python :mod:`ast` module instead. Patch by +Victor Stinner. + +.. + +.. bpo: 43541 +.. date: 2021-03-18-12-44-33 +.. nonce: ICigzd +.. section: C API + +Fix a ``PyEval_EvalCodeEx()`` regression: fix reference counting on +builtins. Patch by Victor Stinner. + +.. + +.. bpo: 43244 +.. date: 2021-03-17-23-53-14 +.. nonce: kfPqA_ +.. section: C API + +Remove the ``symtable.h`` header file and the undocumented functions: + +* ``PyST_GetScope()`` +* ``PySymtable_Build()`` +* ``PySymtable_BuildObject()`` +* ``PySymtable_Free()`` +* ``Py_SymtableString()`` +* ``Py_SymtableStringObject()`` + +The ``Py_SymtableString()`` function was part the stable ABI by mistake but +it could not be used, because the ``symtable.h`` header file was excluded +from the limited C API. + +The Python :mod:`symtable` module remains available and is unchanged. + +Patch by Victor Stinner. + +.. + +.. bpo: 43244 +.. date: 2021-03-17-23-20-07 +.. nonce: diyn2C +.. section: C API + +Remove the ``PyAST_Validate()`` function. It is no longer possible to build +a AST object (``mod_ty`` type) with the public C API. The function was +already excluded from the limited C API (:pep:`384`). Patch by Victor +Stinner. diff --git a/Misc/NEWS.d/3.10.0b1.rst b/Misc/NEWS.d/3.10.0b1.rst new file mode 100644 index 00000000..e7b6b93d --- /dev/null +++ b/Misc/NEWS.d/3.10.0b1.rst @@ -0,0 +1,1808 @@ +.. bpo: 43434 +.. date: 2021-05-02-17-50-23 +.. nonce: cy7xz6 +.. release date: 2021-05-03 +.. section: Security + +Creating :class:`sqlite3.Connection` objects now also produces +``sqlite3.connect`` and ``sqlite3.connect/handle`` :ref:`auditing events +<auditing>`. Previously these events were only produced by +:func:`sqlite3.connect` calls. Patch by Erlend E. Aasland. + +.. + +.. bpo: 43998 +.. date: 2021-05-01-13-13-40 +.. nonce: xhmWD7 +.. section: Security + +The :mod:`ssl` module sets more secure cipher suites defaults. Ciphers +without forward secrecy and with SHA-1 MAC are disabled by default. Security +level 2 prohibits weak RSA, DH, and ECC keys with less than 112 bits of +security. :class:`~ssl.SSLContext` defaults to minimum protocol version TLS +1.2. Settings are based on Hynek Schlawack's research. + +.. + +.. bpo: 43882 +.. date: 2021-04-25-07-46-37 +.. nonce: Jpwx85 +.. section: Security + +The presence of newline or tab characters in parts of a URL could allow some +forms of attacks. + +Following the controlling specification for URLs defined by WHATWG +:func:`urllib.parse` now removes ASCII newlines and tabs from URLs, +preventing such attacks. + +.. + +.. bpo: 43472 +.. date: 2021-04-21-22-53-31 +.. nonce: gjLBTb +.. section: Security + +Ensures interpreter-level audit hooks receive the +``cpython.PyInterpreterState_New`` event when called through the +``_xxsubinterpreters`` module. + +.. + +.. bpo: 43362 +.. date: 2021-04-18-00-56-44 +.. nonce: __5aiP +.. section: Security + +Fix invalid free in _sha3 module. The issue was introduced in 3.10.0a1. +Python 3.9 and earlier are not affected. + +.. + +.. bpo: 43762 +.. date: 2021-04-07-12-57-41 +.. nonce: 7lMtpT +.. section: Security + +Add audit events for :func:`sqlite3.connect/handle`, +:meth:`sqlite3.Connection.enable_load_extension`, and +:meth:`sqlite3.Connection.load_extension`. Patch by Erlend E. Aasland. + +.. + +.. bpo: 43756 +.. date: 2021-04-06-18-07-48 +.. nonce: DLBNqQ +.. section: Security + +Add new audit event ``glob.glob/2`` to incorporate the new *root_dir* and +*dir_fd* arguments added to :func:`glob.glob` and :func:`glob.iglob`. + +.. + +.. bpo: 36384 +.. date: 2021-03-30-16-29-51 +.. nonce: sCAmLs +.. section: Security + +:mod:`ipaddress` module no longer accepts any leading zeros in IPv4 address +strings. Leading zeros are ambiguous and interpreted as octal notation by +some libraries. For example the legacy function :func:`socket.inet_aton` +treats leading zeros as octal notation. glibc implementation of modern +:func:`~socket.inet_pton` does not accept any leading zeros. For a while the +:mod:`ipaddress` module used to accept ambiguous leading zeros. + +.. + +.. bpo: 43075 +.. date: 2021-01-31-05-28-14 +.. nonce: DoAXqO +.. section: Security + +Fix Regular Expression Denial of Service (ReDoS) vulnerability in +:class:`urllib.request.AbstractBasicAuthHandler`. The ReDoS-vulnerable +regex has quadratic worst-case complexity and it allows cause a denial of +service when identifying crafted invalid RFCs. This ReDoS issue is on the +client side and needs remote attackers to control the HTTP server. + +.. + +.. bpo: 42800 +.. date: 2021-01-09-17-07-36 +.. nonce: _dtZvW +.. section: Security + +Audit hooks are now fired for frame.f_code, traceback.tb_frame, and +generator code/frame attribute access. + +.. + +.. bpo: 37363 +.. date: 2020-07-04-22-14-46 +.. nonce: NDjHNw +.. section: Security + +Add audit events to the :mod:`http.client` module. + +.. + +.. bpo: 43977 +.. date: 2021-05-02-11-59-00 +.. nonce: R0hSDo +.. section: Core and Builtins + +Prevent classes being both a sequence and a mapping when pattern matching. + +.. + +.. bpo: 43977 +.. date: 2021-04-29-17-40-25 +.. nonce: FrQhge +.. section: Core and Builtins + +Use :c:member:`~PyTypeObject.tp_flags` on the class object to determine if +the subject is a sequence or mapping when pattern matching. Avoids the need +to import :mod:`collections.abc` when pattern matching. + +.. + +.. bpo: 43892 +.. date: 2021-04-29-16-00-28 +.. nonce: WXIehI +.. section: Core and Builtins + +Restore proper validation of complex literal value patterns when parsing +:keyword:`!match` blocks. + +.. + +.. bpo: 43933 +.. date: 2021-04-29-13-49-57 +.. nonce: TueFdQ +.. section: Core and Builtins + +Set frame.f_lineno to the line number of the 'with' kweyword when executing +the call to ``__exit__``. + +.. + +.. bpo: 43933 +.. date: 2021-04-29-13-11-44 +.. nonce: mvoV6O +.. section: Core and Builtins + +If the current position in a frame has no line number then set the f_lineno +attribute to None, instead of -1, to conform to PEP 626. This should not +normally be possible, but might occur in some unusual circumstances. + +.. + +.. bpo: 43963 +.. date: 2021-04-28-01-23-38 +.. nonce: u5Y6bS +.. section: Core and Builtins + +Importing the :mod:`_signal` module in a subinterpreter has no longer side +effects. + +.. + +.. bpo: 42739 +.. date: 2021-04-27-10-59-10 +.. nonce: PrVkKM +.. section: Core and Builtins + +The internal representation of line number tables is changed to not use +sentinels, and an explicit length parameter is added to the out of process +API function ``PyLineTable_InitAddressRange``. This makes the handling of +line number tables more robust in some circumstances. + +.. + +.. bpo: 43908 +.. date: 2021-04-26-21-20-41 +.. nonce: 2L51nO +.. section: Core and Builtins + +Make :mod:`re` types immutable. Patch by Erlend E. Aasland. + +.. + +.. bpo: 43908 +.. date: 2021-04-26-20-59-17 +.. nonce: -COW4- +.. section: Core and Builtins + +Make the :class:`array.array` type immutable. Patch by Erlend E. Aasland. + +.. + +.. bpo: 43901 +.. date: 2021-04-25-22-50-47 +.. nonce: oKjG5E +.. section: Core and Builtins + +Change class and module objects to lazy-create empty annotations dicts on +demand. The annotations dicts are stored in the object's __dict__ for +backwards compatibility. + +.. + +.. bpo: 43892 +.. date: 2021-04-25-08-35-11 +.. nonce: hr5Ke2 +.. section: Core and Builtins + +Match patterns now use new dedicated AST nodes (``MatchValue``, +``MatchSingleton``, ``MatchSequence``, ``MatchStar``, ``MatchMapping``, +``MatchClass``) rather than reusing expression AST nodes. ``MatchAs`` and +``MatchOr`` are now defined as pattern nodes rather than as expression +nodes. Patch by Nick Coghlan. + +.. + +.. bpo: 42725 +.. date: 2021-04-25-05-40-51 +.. nonce: WGloYm +.. section: Core and Builtins + +Usage of ``await``/``yield``/``yield from`` and named expressions within an +annotation is now forbidden when PEP 563 is activated. + +.. + +.. bpo: 43754 +.. date: 2021-04-24-16-40-23 +.. nonce: 9SzHWG +.. section: Core and Builtins + +When performing structural pattern matching (:pep:`634`), captured names are +now left unbound until the *entire* pattern has matched successfully. + +.. + +.. bpo: 42737 +.. date: 2021-04-22-22-48-30 +.. nonce: lsJ7pD +.. section: Core and Builtins + +Annotations for complex targets (everything beside simple names) no longer +cause any runtime effects with ``from __future__ import annotations``. + +.. + +.. bpo: 43914 +.. date: 2021-04-22-19-09-58 +.. nonce: 0Ik1AM +.. section: Core and Builtins + +:exc:`SyntaxError` exceptions raised by the interpreter will highlight the +full error range of the expression that consistutes the syntax error itself, +instead of just where the problem is detected. Patch by Pablo Galindo. + +.. + +.. bpo: 38605 +.. date: 2021-04-20-22-17-47 +.. nonce: 9eeCNZ +.. section: Core and Builtins + +Revert making ``from __future__ import annotations`` the default. This +follows the Steering Council decision to postpone PEP 563 changes to at +least Python 3.11. See the original email for more information regarding the +decision: +https://mail.python.org/archives/list/python-dev@python.org/thread/CLVXXPQ2T2LQ5MP2Y53VVQFCXYWQJHKZ/. +Patch by Pablo Galindo. + +.. + +.. bpo: 43475 +.. date: 2021-04-20-20-10-46 +.. nonce: oV8Mbs +.. section: Core and Builtins + +Hashes of NaN values now depend on object identity. Formerly, they always +hashed to 0 even though NaN values are not equal to one another. Having the +same hash for unequal values caused pile-ups in hash tables. + +.. + +.. bpo: 43859 +.. date: 2021-04-16-01-26-57 +.. nonce: QfqjFL +.. section: Core and Builtins + +Improve the error message for :exc:`IndentationError` exceptions. Patch by +Pablo Galindo + +.. + +.. bpo: 41323 +.. date: 2021-04-15-10-19-59 +.. nonce: nsvpSg +.. section: Core and Builtins + +Constant tuple folding in bytecode optimizer now reuses tuple in constant +table. + +.. + +.. bpo: 43846 +.. date: 2021-04-14-13-53-08 +.. nonce: 2jO97c +.. section: Core and Builtins + +Data stack usage is much reduced for large literal and call expressions. + +.. + +.. bpo: 38530 +.. date: 2021-04-14-03-53-06 +.. nonce: rNI_G1 +.. section: Core and Builtins + +When printing :exc:`NameError` raised by the interpreter, +:c:func:`PyErr_Display` will offer suggestions of similar variable names in +the function that the exception was raised from. Patch by Pablo Galindo + +.. + +.. bpo: 43823 +.. date: 2021-04-13-03-06-09 +.. nonce: xpuHBi +.. section: Core and Builtins + +Improve syntax errors for invalid dictionary literals. Patch by Pablo +Galindo. + +.. + +.. bpo: 43822 +.. date: 2021-04-13-02-32-18 +.. nonce: lej0OO +.. section: Core and Builtins + +Improve syntax errors in the parser for missing commas between expressions. +Patch by Pablo Galindo. + +.. + +.. bpo: 43798 +.. date: 2021-04-10-00-01-43 +.. nonce: p_nJFM +.. section: Core and Builtins + +:class:`ast.alias` nodes now include source location metadata attributes +e.g. lineno, col_offset. + +.. + +.. bpo: 43797 +.. date: 2021-04-09-19-12-48 +.. nonce: HfRqNP +.. section: Core and Builtins + +Improve ``SyntaxError`` error messages for invalid comparisons. Patch by +Pablo Galindo. + +.. + +.. bpo: 43760 +.. date: 2021-04-08-12-20-29 +.. nonce: tBIsD8 +.. section: Core and Builtins + +Move the flag for checking whether tracing is enabled to the C stack, from +the heap. Should speed up dispatch in the interpreter. + +.. + +.. bpo: 43682 +.. date: 2021-04-08-01-06-22 +.. nonce: eUn4p5 +.. section: Core and Builtins + +Static methods (:func:`@staticmethod <staticmethod>`) and class methods +(:func:`@classmethod <classmethod>`) now inherit the method attributes +(``__module__``, ``__name__``, ``__qualname__``, ``__doc__``, +``__annotations__``) and have a new ``__wrapped__`` attribute. Patch by +Victor Stinner. + +.. + +.. bpo: 43751 +.. date: 2021-04-07-18-00-05 +.. nonce: 8fHsqQ +.. section: Core and Builtins + +Fixed a bug where ``anext(ait, default)`` would erroneously return None. + +.. + +.. bpo: 42128 +.. date: 2021-04-05-17-38-08 +.. nonce: 1uVeGK +.. section: Core and Builtins + +:data:`~object.__match_args__` is no longer allowed to be a list. + +.. + +.. bpo: 43683 +.. date: 2021-04-01-12-30-30 +.. nonce: AjxOx2 +.. section: Core and Builtins + +Add GEN_START opcode. Marks start of generator, including async, or +coroutine and handles sending values to a newly created generator or +coroutine. + +.. + +.. bpo: 43105 +.. date: 2021-03-31-20-35-11 +.. nonce: PBVmHm +.. section: Core and Builtins + +Importlib now resolves relative paths when creating module spec objects from +file locations. + +.. + +.. bpo: 43682 +.. date: 2021-03-31-16-32-57 +.. nonce: VSF3vg +.. section: Core and Builtins + +Static methods (:func:`@staticmethod <staticmethod>`) are now callable as +regular functions. Patch by Victor Stinner. + +.. + +.. bpo: 42609 +.. date: 2020-12-12-14-28-31 +.. nonce: Qcd54b +.. section: Core and Builtins + +Prevented crashes in the AST validator and optimizer when compiling some +absurdly long expressions like ``"+0"*1000000``. :exc:`RecursionError` is +now raised instead. + +.. + +.. bpo: 38530 +.. date: 2019-10-27-20-20-07 +.. nonce: ZyoDNn +.. section: Core and Builtins + +When printing :exc:`AttributeError`, :c:func:`PyErr_Display` will offer +suggestions of similar attribute names in the object that the exception was +raised from. Patch by Pablo Galindo + +.. + +.. bpo: 44015 +.. date: 2021-05-03-03-03-49 +.. nonce: V5936k +.. section: Library + +In @dataclass(), raise a TypeError if KW_ONLY is specified more than once. + +.. + +.. bpo: 25478 +.. date: 2021-05-02-19-17-20 +.. nonce: AwlwdA +.. section: Library + +Added a *total()* method to collections.Counter() to compute the sum of the +counts. + +.. + +.. bpo: 43733 +.. date: 2021-05-01-22-59-20 +.. nonce: gJWwEQ +.. section: Library + +Change :class:`netrc.netrc` to use UTF-8 encoding before using locale +encoding. + +.. + +.. bpo: 43979 +.. date: 2021-05-01-01-36-51 +.. nonce: 43oJ9L +.. section: Library + +Removed an unnecessary list comprehension before looping from +:func:`urllib.parse.parse_qsl`. Patch by Christoph Zwerschke and Donghee +Na. + +.. + +.. bpo: 43993 +.. date: 2021-04-30-19-23-45 +.. nonce: T7_yoq +.. section: Library + +Update bundled pip to 21.1.1. + +.. + +.. bpo: 43957 +.. date: 2021-04-27-12-13-51 +.. nonce: 6EaPD- +.. section: Library + +[Enum] Deprecate ``TypeError`` when non-member is used in a containment +check; In 3.12 ``True`` or ``False`` will be returned instead, and +containment will return ``True`` if the value is either a member of that +enum or one of its members' value. + +.. + +.. bpo: 42904 +.. date: 2021-04-26-23-39-47 +.. nonce: ejjsyR +.. section: Library + +For backwards compatibility with previous minor versions of Python, if +:func:`typing.get_type_hints` receives no namespace dictionary arguments, +:func:`typing.get_type_hints` will search through the global then local +namespaces during evaluation of stringized type annotations (string forward +references) inside a class. + +.. + +.. bpo: 43945 +.. date: 2021-04-26-20-52-16 +.. nonce: NgERXO +.. section: Library + +[Enum] Deprecate non-standard mixin format() behavior: in 3.12 the enum +member, not the member's value, will be used for format() calls. + +.. + +.. bpo: 41139 +.. date: 2021-04-26-17-47-48 +.. nonce: ROhn1k +.. section: Library + +Deprecate undocumented ``cgi.log()`` API. + +.. + +.. bpo: 43937 +.. date: 2021-04-25-13-34-13 +.. nonce: isx95l +.. section: Library + +Fixed the :mod:`turtle` module working with non-default root window. + +.. + +.. bpo: 43930 +.. date: 2021-04-24-14-23-07 +.. nonce: R7ah0m +.. section: Library + +Update bundled pip to 21.1 and setuptools to 56.0.0 + +.. + +.. bpo: 43907 +.. date: 2021-04-23-20-57-20 +.. nonce: 3RJEjv +.. section: Library + +Fix a bug in the pure-Python pickle implementation when using protocol 5, +where bytearray instances that occur several time in the pickled object +graph would incorrectly unpickle into repeated copies of the bytearray +object. + +.. + +.. bpo: 43926 +.. date: 2021-04-23-17-48-55 +.. nonce: HMUlGU +.. section: Library + +In ``importlib.metadata``, provide a uniform interface to ``Description``, +allow for any field to be encoded with multiline values, remove continuation +lines from multiline values, and add a ``.json`` property for easy access to +the PEP 566 JSON-compatible form. Sync with ``importlib_metadata 4.0``. + +.. + +.. bpo: 43920 +.. date: 2021-04-23-11-54-38 +.. nonce: cJMQ2D +.. section: Library + +OpenSSL 3.0.0: :meth:`~ssl.SSLContext.load_verify_locations` now returns a +consistent error message when cadata contains no valid certificate. + +.. + +.. bpo: 43607 +.. date: 2021-04-22-22-39-58 +.. nonce: 7IYDkG +.. section: Library + +:mod:`urllib` can now convert Windows paths with ``\\?\`` prefixes into URL +paths. + +.. + +.. bpo: 43817 +.. date: 2021-04-22-04-12-13 +.. nonce: FQ-XlH +.. section: Library + +Add :func:`inspect.get_annotations`, which safely computes the annotations +defined on an object. It works around the quirks of accessing the +annotations from various types of objects, and makes very few assumptions +about the object passed in. :func:`inspect.get_annotations` can also +correctly un-stringize stringized annotations. + +:func:`inspect.signature`, :func:`inspect.from_callable`, and +:func:`inspect.from_function` now call :func:`inspect.get_annotations` to +retrieve annotations. This means :func:`inspect.signature` and +:func:`inspect.from_callable` can now un-stringize stringized annotations, +too. + +.. + +.. bpo: 43284 +.. date: 2021-04-21-14-50-57 +.. nonce: 2QZn2T +.. section: Library + +platform.win32_ver derives the windows version from +sys.getwindowsversion().platform_version which in turn derives the version +from kernel32.dll (which can be of a different version than Windows itself). +Therefore change the platform.win32_ver to determine the version using the +platform module's _syscmd_ver private function to return an accurate +version. + +.. + +.. bpo: 42854 +.. date: 2021-04-19-03-54-29 +.. nonce: Y4M7Tv +.. section: Library + +The :mod:`ssl` module now uses ``SSL_read_ex`` and ``SSL_write_ex`` +internally. The functions support reading and writing of data larger than 2 +GB. Writing zero-length data no longer fails with a protocol violation +error. + +.. + +.. bpo: 42333 +.. date: 2021-04-17-19-31-17 +.. nonce: cgbtZO +.. section: Library + +Port ``_ssl`` extension module to multiphase initialization. + +.. + +.. bpo: 43880 +.. date: 2021-04-17-13-53-33 +.. nonce: -fC2JD +.. section: Library + +:mod:`ssl` now raises DeprecationWarning for OP_NO_SSL/TLS* options, old TLS +versions, old protocols, and other features that have been deprecated since +Python 3.6, 3.7, or OpenSSL 1.1.0. + +.. + +.. bpo: 41559 +.. date: 2021-04-17-10-49-57 +.. nonce: caIwt9 +.. section: Library + +:pep:`612` is now implemented purely in Python; builtin +``types.GenericAlias`` objects no longer include ``typing.ParamSpec`` in +``__parameters__`` (with the exception of ``collections.abc.Callable``\ 's +``GenericAlias``). This means previously invalid uses of ``ParamSpec`` (such +as ``list[P]``) which worked in earlier versions of Python 3.10 alpha, will +now raise ``TypeError`` during substitution. + +.. + +.. bpo: 43867 +.. date: 2021-04-16-16-46-44 +.. nonce: xT9QjF +.. section: Library + +The :mod:`multiprocessing` ``Server`` class now explicitly catches +:exc:`SystemExit` and closes the client connection in this case. It happens +when the ``Server.serve_client()`` method reaches the end of file (EOF). + +.. + +.. bpo: 40443 +.. date: 2021-04-16-02-03-00 +.. nonce: Io6FHL +.. section: Library + +Remove unused imports: pyclbr no longer uses copy, and typing no longer uses +ast. Patch by Victor Stinner. + +.. + +.. bpo: 43820 +.. date: 2021-04-12-18-01-10 +.. nonce: YkqYW4 +.. section: Library + +Remove an unneeded copy of the namespace passed to +dataclasses.make_dataclass(). + +.. + +.. bpo: 43787 +.. date: 2021-04-12-15-15-50 +.. nonce: wCy_Wd +.. section: Library + +Add ``__iter__()`` method to :class:`bz2.BZ2File`, :class:`gzip.GzipFile`, +and :class:`lzma.LZMAFile`. It makes iterating them about 2x faster. Patch +by Inada Naoki. + +.. + +.. bpo: 43680 +.. date: 2021-04-12-11-20-34 +.. nonce: SR0Epv +.. section: Library + +Deprecate io.OpenWrapper and _pyio.OpenWrapper: use io.open and _pyio.open +instead. Until Python 3.9, _pyio.open was not a static method and +builtins.open was set to OpenWrapper to not become a bound method when set +to a class variable. _io.open is a built-in function whereas _pyio.open is a +Python function. In Python 3.10, _pyio.open() is now a static method, and +builtins.open() is now io.open(). + +.. + +.. bpo: 43680 +.. date: 2021-04-12-09-57-37 +.. nonce: o1zEk_ +.. section: Library + +The Python :func:`_pyio.open` function becomes a static method to behave as +:func:`io.open` built-in function: don't become a bound method when stored +as a class variable. It becomes possible since static methods are now +callable in Python 3.10. Moreover, :func:`_pyio.OpenWrapper` becomes a +simple alias to :func:`_pyio.open`. Patch by Victor Stinner. + +.. + +.. bpo: 41515 +.. date: 2021-04-12-06-01-10 +.. nonce: YaVReb +.. section: Library + +Fix :exc:`KeyError` raised in :func:`typing.get_type_hints` due to synthetic +modules that don't appear in ``sys.modules``. + +.. + +.. bpo: 43776 +.. date: 2021-04-12-00-00-00 +.. nonce: p14y7a +.. section: Library + +When :class:`subprocess.Popen` args are provided as a string or as +:class:`pathlib.Path`, the Popen instance repr now shows the right thing. + +.. + +.. bpo: 42248 +.. date: 2021-04-11-21-10-57 +.. nonce: pedB1E +.. section: Library + +[Enum] ensure exceptions raised in ``_missing__`` are released + +.. + +.. bpo: 43744 +.. date: 2021-04-11-20-52-32 +.. nonce: uf0E68 +.. section: Library + +fix issue with enum member name matching the start of a private variable +name + +.. + +.. bpo: 43772 +.. date: 2021-04-10-19-14-49 +.. nonce: Bxq0zQ +.. section: Library + +Fixed the return value of ``TypeVar.__ror__``. Patch by Jelle Zijlstra. + +.. + +.. bpo: 43764 +.. date: 2021-04-10-18-23-09 +.. nonce: Le5KJp +.. section: Library + +Add match_args parameter to @dataclass decorator to allow suppression of +__match_args__ generation. + +.. + +.. bpo: 43799 +.. date: 2021-04-10-11-35-50 +.. nonce: 1iV4pX +.. section: Library + +OpenSSL 3.0.0: define ``OPENSSL_API_COMPAT`` 1.1.1 to suppress deprecation +warnings. Python requires OpenSSL 1.1.1 APIs. + +.. + +.. bpo: 43478 +.. date: 2021-04-10-03-30-36 +.. nonce: iZcBTq +.. section: Library + +Mocks can no longer be used as the specs for other Mocks. As a result, an +already-mocked object cannot have an attribute mocked using +``autospec=True`` or be the subject of a ``create_autospec(...)`` call. This +can uncover bugs in tests since these Mock-derived Mocks will always pass +certain tests (e.g. :func:`isinstance`) and builtin assert functions (e.g. +assert_called_once_with) will unconditionally pass. + +.. + +.. bpo: 43794 +.. date: 2021-04-09-16-14-22 +.. nonce: -1XPDH +.. section: Library + +Add :const:`ssl.OP_IGNORE_UNEXPECTED_EOF` constants (OpenSSL 3.0.0) + +.. + +.. bpo: 43785 +.. date: 2021-04-09-14-51-58 +.. nonce: 1mM5xE +.. section: Library + +Improve ``bz2.BZ2File`` performance by removing the RLock from BZ2File. This +makes BZ2File thread unsafe in the face of multiple simultaneous readers or +writers, just like its equivalent classes in :mod:`gzip` and :mod:`lzma` +have always been. Patch by Inada Naoki. + +.. + +.. bpo: 43789 +.. date: 2021-04-09-14-08-03 +.. nonce: eaHlAm +.. section: Library + +OpenSSL 3.0.0: Don't call the password callback function a second time when +first call has signaled an error condition. + +.. + +.. bpo: 43788 +.. date: 2021-04-09-12-08-01 +.. nonce: YsvInM +.. section: Library + +The header files for :mod:`ssl` error codes are now OpenSSL +version-specific. Exceptions will now show correct reason and library codes. +The ``make_ssl_data.py`` script has been rewritten to use OpenSSL's text +file with error codes. + +.. + +.. bpo: 43766 +.. date: 2021-04-09-00-16-22 +.. nonce: nYNQP0 +.. section: Library + +Implement :pep:`647` in the :mod:`typing` module by adding +:data:`TypeGuard`. + +.. + +.. bpo: 25264 +.. date: 2021-04-08-22-11-27 +.. nonce: b33fa0 +.. section: Library + +:func:`os.path.realpath` now accepts a *strict* keyword-only argument. When +set to ``True``, :exc:`OSError` is raised if a path doesn't exist or a +symlink loop is encountered. + +.. + +.. bpo: 43780 +.. date: 2021-04-08-20-04-46 +.. nonce: hUOgCh +.. section: Library + +In ``importlib.metadata``, incorporate changes from importlib_metadata 3.10: +Add mtime-based caching during distribution discovery. Flagged use of dict +result from ``entry_points()`` as deprecated. + +.. + +.. gh: 47383 +.. date: 2021-04-08-19-32-26 +.. nonce: YI1hdL +.. section: Library + +The ``P.args`` and ``P.kwargs`` attributes of :class:`typing.ParamSpec` are +now instances of the new classes :class:`typing.ParamSpecArgs` and +:class:`typing.ParamSpecKwargs`, which enables a more useful ``repr()``. +Patch by Jelle Zijlstra. + +.. + +.. bpo: 43731 +.. date: 2021-04-08-15-19-20 +.. nonce: nnVd3h +.. section: Library + +Add an ``encoding`` parameter :func:`logging.fileConfig()`. + +.. + +.. bpo: 43712 +.. date: 2021-04-08-12-25-08 +.. nonce: f8WXCX +.. section: Library + +Add ``encoding`` and ``errors`` parameters to :func:`fileinput.input` and +:class:`fileinput.FileInput`. + +.. + +.. bpo: 38659 +.. date: 2021-04-08-11-47-31 +.. nonce: r_HFnU +.. section: Library + +A ``simple_enum`` decorator is added to the ``enum`` module to convert a +normal class into an Enum. ``test_simple_enum`` added to test simple enums +against a corresponding normal Enum. Standard library modules updated to +use ``simple_enum``. + +.. + +.. bpo: 43764 +.. date: 2021-04-08-09-59-20 +.. nonce: tHjO60 +.. section: Library + +Fix an issue where :data:`~object.__match_args__` generation could fail for +some :mod:`dataclasses`. + +.. + +.. bpo: 43752 +.. date: 2021-04-06-21-18-29 +.. nonce: K7qmAF +.. section: Library + +Fix :mod:`sqlite3` regression for zero-sized blobs with converters, where +``b""`` was returned instead of ``None``. The regression was introduced by +PR 24723. Patch by Erlend E. Aasland. + +.. + +.. bpo: 43655 +.. date: 2021-04-04-20-51-19 +.. nonce: LwGy8R +.. section: Library + +:mod:`tkinter` dialog windows are now recognized as dialogs by window +managers on macOS and X Window. + +.. + +.. bpo: 43723 +.. date: 2021-04-03-18-03-44 +.. nonce: uBhBZS +.. section: Library + +The following ``threading`` methods are now deprecated and should be +replaced: + +- ``currentThread`` => :func:`threading.current_thread` + +- ``activeCount`` => :func:`threading.active_count` + +- ``Condition.notifyAll`` => :meth:`threading.Condition.notify_all` + +- ``Event.isSet`` => :meth:`threading.Event.is_set` + +- ``Thread.setName`` => :attr:`threading.Thread.name` + +- ``thread.getName`` => :attr:`threading.Thread.name` + +- ``Thread.isDaemon`` => :attr:`threading.Thread.daemon` + +- ``Thread.setDaemon`` => :attr:`threading.Thread.daemon` + +Patch by Jelle Zijlstra. + +.. + +.. bpo: 2135 +.. date: 2021-04-03-15-24-59 +.. nonce: xmDAYJ +.. section: Library + +Deprecate find_module() and find_loader() implementations in importlib and +zipimport. + +.. + +.. bpo: 43534 +.. date: 2021-03-18-15-46-08 +.. nonce: vPE9Us +.. section: Library + +:func:`turtle.textinput` and :func:`turtle.numinput` create now a transient +window working on behalf of the canvas window. + +.. + +.. bpo: 43532 +.. date: 2021-03-17-19-06-45 +.. nonce: W2Ntnm +.. section: Library + +Add the ability to specify keyword-only fields to dataclasses. These fields +will become keyword-only arguments to the generated __init__. + +.. + +.. bpo: 43522 +.. date: 2021-03-16-22-37-32 +.. nonce: dhNwOu +.. section: Library + +Fix problem with :attr:`~ssl.SSLContext.hostname_checks_common_name`. +OpenSSL does not copy hostflags from *struct SSL_CTX* to *struct SSL*. + +.. + +.. bpo: 8978 +.. date: 2021-03-13-14-02-07 +.. nonce: CRxG-O +.. section: Library + +Improve error message for :func:`tarfile.open` when :mod:`lzma` / :mod:`bz2` +are unavailable. Patch by Anthony Sottile. + +.. + +.. bpo: 42967 +.. date: 2021-03-11-00-31-41 +.. nonce: 2PeQRw +.. section: Library + +Allow :class:`bytes` ``separator`` argument in ``urllib.parse.parse_qs`` and +``urllib.parse.parse_qsl`` when parsing :class:`str` query strings. +Previously, this raised a ``TypeError``. + +.. + +.. bpo: 43296 +.. date: 2021-03-01-13-01-33 +.. nonce: p_gU6T +.. section: Library + +Improve :mod:`sqlite3` error handling: ``sqlite3_value_blob()`` errors that +set ``SQLITE_NOMEM`` now raise :exc:`MemoryError`. Patch by Erlend E. +Aasland. + +.. + +.. bpo: 43312 +.. date: 2021-02-25-14-43-59 +.. nonce: 6dg9_2 +.. section: Library + +New functions :func:`sysconfig.get_preferred_scheme` and +:func:`sysconfig.get_default_scheme` are added to query a platform for its +preferred "user", "home", and "prefix" (default) scheme names. + +.. + +.. bpo: 43265 +.. date: 2021-02-19-22-24-33 +.. nonce: MyAzCH +.. section: Library + +Improve :meth:`sqlite3.Connection.backup` error handling. The error message +for non-existent target database names is now ``unknown database <database +name>`` instead of ``SQL logic error``. Patch by Erlend E. Aasland. + +.. + +.. bpo: 41282 +.. date: 2021-02-16-13-18-38 +.. nonce: GK9a0l +.. section: Library + +Install schemes in ``distutils.command.install`` are now loaded from +:mod:`sysconfig`. + +.. + +.. bpo: 41282 +.. date: 2021-02-15-12-52-23 +.. nonce: SenEje +.. section: Library + +``distutils.sysconfig`` has been merged to :mod:`sysconfig`. + +.. + +.. bpo: 43176 +.. date: 2021-02-09-07-24-29 +.. nonce: bocNQn +.. section: Library + +Fixed processing of a dataclass that inherits from a frozen dataclass with +no fields. It is now correctly detected as an error. + +.. + +.. bpo: 43080 +.. date: 2021-01-31-00-23-13 +.. nonce: -fDg4Q +.. section: Library + +:mod:`pprint` now has support for :class:`dataclasses.dataclass`. Patch by +Lewis Gaul. + +.. + +.. bpo: 39950 +.. date: 2021-01-22-00-15-37 +.. nonce: NzLVaR +.. section: Library + +Add `pathlib.Path.hardlink_to()` method that supersedes `link_to()`. The new +method has the same argument order as `symlink_to()`. + +.. + +.. bpo: 42904 +.. date: 2021-01-12-23-17-02 +.. nonce: -4qkTD +.. section: Library + +:func:`typing.get_type_hints` now checks the local namespace of a class when +evaluating :pep:`563` annotations inside said class. + +.. + +.. bpo: 42269 +.. date: 2021-01-08-22-32-13 +.. nonce: W5v8z4 +.. section: Library + +Add ``slots`` parameter to ``dataclasses.dataclass`` decorator to +automatically generate ``__slots__`` for class. Patch provided by Yurii +Karabas. + +.. + +.. bpo: 39529 +.. date: 2020-12-06-20-21-16 +.. nonce: 9Zrg43 +.. section: Library + +Deprecated use of :func:`asyncio.get_event_loop` without running event loop. +Emit deprecation warning for :mod:`asyncio` functions which implicitly +create a :class:`~asyncio.Future` or :class:`~asyncio.Task` objects if there +is no running event loop and no explicit *loop* argument is passed: +:func:`~asyncio.ensure_future`, :func:`~asyncio.wrap_future`, +:func:`~asyncio.gather`, :func:`~asyncio.shield`, +:func:`~asyncio.as_completed` and constructors of :class:`~asyncio.Future`, +:class:`~asyncio.Task`, :class:`~asyncio.StreamReader`, +:class:`~asyncio.StreamReaderProtocol`. + +.. + +.. bpo: 18369 +.. date: 2020-11-19-09-52-24 +.. nonce: qzvYH2 +.. section: Library + +Certificate and PrivateKey classes were added to the ssl module. +Certificates and keys can now be loaded from memory buffer, too. + +.. + +.. bpo: 41486 +.. date: 2020-10-16-15-34-30 +.. nonce: Mu9Iit +.. section: Library + +Use a new output buffer management code for :mod:`bz2` / :mod:`lzma` / +:mod:`zlib` modules, and add ``.readall()`` function to +``_compression.DecompressReader`` class. These bring some performance +improvements. Patch by Ma Lin. + +.. + +.. bpo: 31870 +.. date: 2020-09-15-23-44-07 +.. nonce: nVwd38 +.. section: Library + +The :func:`ssl.get_server_certificate` function now has a *timeout* +parameter. + +.. + +.. bpo: 41735 +.. date: 2020-09-07-11-15-15 +.. nonce: NKqGKy +.. section: Library + +Fix thread locks in zlib module may go wrong in rare case. Patch by Ma Lin. + +.. + +.. bpo: 36470 +.. date: 2020-06-13-23-33-32 +.. nonce: oi6Kdb +.. section: Library + +Fix dataclasses with ``InitVar``\s and :func:`~dataclasses.replace()`. Patch +by Claudiu Popa. + +.. + +.. bpo: 40849 +.. date: 2020-06-02-21-32-33 +.. nonce: zpeKx3 +.. section: Library + +Expose X509_V_FLAG_PARTIAL_CHAIN ssl flag + +.. + +.. bpo: 35114 +.. date: 2020-05-17-14-10-24 +.. nonce: uLIHfn +.. section: Library + +:func:`ssl.RAND_status` now returns a boolean value (as documented) instead +of ``1`` or ``0``. + +.. + +.. bpo: 39906 +.. date: 2020-03-30-00-13-27 +.. nonce: eaR3fN +.. section: Library + +:meth:`pathlib.Path.stat` and :meth:`~pathlib.Path.chmod` now accept a +*follow_symlinks* keyword-only argument for consistency with corresponding +functions in the :mod:`os` module. + +.. + +.. bpo: 39899 +.. date: 2020-03-09-20-36-07 +.. nonce: 9adF3E +.. section: Library + +:func:`os.path.expanduser()` now refuses to guess Windows home directories +if the basename of current user's home directory does not match their +username. + +:meth:`pathlib.Path.expanduser()` and :meth:`~pathlib.Path.home()` now +consistently raise :exc:`RuntimeError` exception when a home directory +cannot be resolved. Previously a :exc:`KeyError` exception could be raised +on Windows when the ``"USERNAME"`` environment variable was unset. + +.. + +.. bpo: 36076 +.. date: 2019-10-16-17-21-53 +.. nonce: FGeQQT +.. section: Library + +Added SNI support to :func:`ssl.get_server_certificate`. + +.. + +.. bpo: 38490 +.. date: 2019-10-16-08-08-14 +.. nonce: QbDXEF +.. section: Library + +Covariance, Pearson's correlation, and simple linear regression +functionality was added to statistics module. Patch by Tymoteusz Wołodźko. + +.. + +.. bpo: 33731 +.. date: 2019-08-14-13-19-50 +.. nonce: 9esS0d +.. section: Library + +Provide a locale.localize() function, which converts a normalized number +string into a locale format. + +.. + +.. bpo: 32745 +.. date: 2018-08-09-23-47-10 +.. nonce: iQi9hI +.. section: Library + +Fix a regression in the handling of ctypes' :data:`ctypes.c_wchar_p` type: +embedded null characters would cause a :exc:`ValueError` to be raised. Patch +by Zackery Spytz. + +.. + +.. bpo: 43987 +.. date: 2021-04-30-04-27-02 +.. nonce: 1DftVa +.. section: Documentation + +Add "Annotations Best Practices" document as a new HOWTO. + +.. + +.. bpo: 43977 +.. date: 2021-04-29-15-06-03 +.. nonce: K5aSl1 +.. section: Documentation + +Document the new :c:macro:`Py_TPFLAGS_MAPPING` and +:c:macro:`Py_TPFLAGS_SEQUENCE` type flags. + +.. + +.. bpo: 43959 +.. date: 2021-04-27-22-22-22 +.. nonce: n2261q +.. section: Documentation + +The documentation on the PyContextVar C-API was clarified. + +.. + +.. bpo: 43938 +.. date: 2021-04-25-22-44-27 +.. nonce: nC660q +.. section: Documentation + +Update dataclasses documentation to express that FrozenInstanceError is +derived from AttributeError. + +.. + +.. bpo: 43778 +.. date: 2021-04-08-22-42-02 +.. nonce: MszRnY +.. section: Documentation + +Fix the Sphinx glossary_search extension: create the _static/ sub-directory +if it doesn't exist. + +.. + +.. bpo: 43755 +.. date: 2021-04-06-14-55-45 +.. nonce: 1m0fGq +.. section: Documentation + +Update documentation to reflect that unparenthesized lambda expressions can +no longer be the expression part in an ``if`` clause in comprehensions and +generator expressions since Python 3.9. + +.. + +.. bpo: 43739 +.. date: 2021-04-06-07-05-49 +.. nonce: L4HjiX +.. section: Documentation + +Fixing the example code in Doc/extending/extending.rst to declare and +initialize the pmodule variable to be of the right type. + +.. + +.. bpo: 43961 +.. date: 2021-04-28-13-21-52 +.. nonce: gNchls +.. section: Tests + +Fix test_logging.test_namer_rotator_inheritance() on Windows: use +:func:`os.replace` rather than :func:`os.rename`. Patch by Victor Stinner. + +.. + +.. bpo: 43842 +.. date: 2021-04-16-14-07-40 +.. nonce: w60GAH +.. section: Tests + +Fix a race condition in the SMTP test of test_logging. Don't close a file +descriptor (socket) from a different thread while asyncore.loop() is polling +the file descriptor. Patch by Victor Stinner. + +.. + +.. bpo: 43843 +.. date: 2021-04-14-13-22-44 +.. nonce: ruIQKD +.. section: Tests + +:mod:`test.libregrtest` now marks a test as ENV_CHANGED (altered the +execution environment) if a thread raises an exception but does not catch +it. It sets a hook on :func:`threading.excepthook`. Use +``--fail-env-changed`` option to mark the test as failed. Patch by Victor +Stinner. + +.. + +.. bpo: 43811 +.. date: 2021-04-12-11-14-28 +.. nonce: vGNbnD +.. section: Tests + +Tests multiple OpenSSL versions on GitHub Actions. Use ccache to speed up +testing. + +.. + +.. bpo: 43791 +.. date: 2021-04-09-15-10-38 +.. nonce: 4KxiXK +.. section: Tests + +OpenSSL 3.0.0: Disable testing of legacy protocols TLS 1.0 and 1.1. Tests +are failing with TLSV1_ALERT_INTERNAL_ERROR. + +.. + +.. bpo: 43567 +.. date: 2021-03-31-19-50-01 +.. nonce: vd0a-p +.. section: Build + +Improved generated code refresh (AST/tokens/opcodes/keywords) on Windows. + +.. + +.. bpo: 43669 +.. date: 2021-03-30-14-19-39 +.. nonce: lWMUYx +.. section: Build + +Implement :pep:`644`. Python now requires OpenSSL 1.1.1 or newer. + +.. + +.. bpo: 35306 +.. date: 2021-04-22-21-37-41 +.. nonce: 10kSR- +.. section: Windows + +Adds additional arguments to :func:`os.startfile` function. + +.. + +.. bpo: 43538 +.. date: 2021-04-22-20-39-49 +.. nonce: F0Cg6X +.. section: Windows + +Avoid raising errors from :meth:`pathlib.Path.exists()` when passed an +invalid filename. + +.. + +.. bpo: 38822 +.. date: 2021-04-22-19-49-20 +.. nonce: jgdPmq +.. section: Windows + +Fixed :func:`os.stat` failing on inaccessible directories with a trailing +slash, rather than falling back to the parent directory's metadata. This +implicitly affected :func:`os.path.exists` and :func:`os.path.isdir`. + +.. + +.. bpo: 26227 +.. date: 2021-04-21-23-37-34 +.. nonce: QMY_eA +.. section: Windows + +Fixed decoding of host names in :func:`socket.gethostbyaddr` and +:func:`socket.gethostbyname_ex`. + +.. + +.. bpo: 40432 +.. date: 2021-04-20-23-07-22 +.. nonce: 9OFpoq +.. section: Windows + +Updated pegen regeneration script on Windows to find and use Python 3.8 or +higher. Prior to this, pegen regeneration already required 3.8 or higher, +but the script may have used lower versions of Python. + +.. + +.. bpo: 43745 +.. date: 2021-04-06-12-27-33 +.. nonce: rdKNda +.. section: Windows + +Actually updates Windows release to OpenSSL 1.1.1k. Earlier releases were +mislabelled and actually included 1.1.1i again. + +.. + +.. bpo: 43652 +.. date: 2021-04-03-18-54-31 +.. nonce: gNmfVN +.. section: Windows + +Update Tcl and Tk to 8.6.11 in Windows installer. + +.. + +.. bpo: 43492 +.. date: 2021-03-15-11-34-33 +.. nonce: AsYnVX +.. section: Windows + +Upgrade Windows installer to use SQLite 3.35.5. + +.. + +.. bpo: 30555 +.. date: 2017-12-16-12-23-51 +.. nonce: 3ybjly +.. section: Windows + +Fix ``WindowsConsoleIO`` errors in the presence of fd redirection. Patch by +Segev Finer. + +.. + +.. bpo: 42119 +.. date: 2021-05-02-21-03-27 +.. nonce: Y7BSX_ +.. section: macOS + +Fix check for macOS SDK paths when building Python. Narrow search to match +contents of SDKs, namely only files in ``/System/Library``, +``/System/IOSSupport``, and ``/usr`` other than ``/usr/local``. Previously, +anything under ``/System`` was assumed to be in an SDK which causes problems +with the new file system layout in 10.15+ where user file systems may appear +to be mounted under ``/System``. Paths in ``/Library`` were also +incorrectly treated as SDK locations. + +.. + +.. bpo: 43568 +.. date: 2021-05-02-19-50-52 +.. nonce: AeLNBd +.. section: macOS + +Drop support for MACOSX_DEPLOYMENT_TARGET < 10.3 + +.. + +.. bpo: 44009 +.. date: 2021-05-02-03-45-30 +.. nonce: uvhmlh +.. section: macOS + +Provide "python3.x-intel64" executable to allow reliably forcing macOS +universal2 framework builds to run under Rosetta 2 Intel-64 emulation on +Apple Silicon Macs. This can be useful for testing or when universal2 +wheels are not yet available. + +.. + +.. bpo: 43851 +.. date: 2021-04-15-01-20-45 +.. nonce: sDI60Y +.. section: macOS + +Build SQLite with ``SQLITE_OMIT_AUTOINIT`` on macOS. Patch by Erlend E. +Aasland. + +.. + +.. bpo: 43492 +.. date: 2021-03-15-11-32-23 +.. nonce: 1ZRcV9 +.. section: macOS + +Update macOS installer to use SQLite 3.35.4. + +.. + +.. bpo: 42235 +.. date: 2020-11-01-17-37-16 +.. nonce: A97_BN +.. section: macOS + +``Mac/BuildScript/build-installer.py`` will now use "--enable-optimizations" +and ``--with-lto`` when building on macOS 10.15 or later. + +.. + +.. bpo: 37903 +.. date: 2021-05-02-20-25-53 +.. nonce: VQ6VTU +.. section: IDLE + +Add mouse actions to the shell sidebar. Left click and optional drag +selects one or more lines, as with the editor line number sidebar. Right +click after selecting raises a context menu with 'copy with prompts'. This +zips together prompts from the sidebar with lines from the selected text. + +.. + +.. bpo: 43981 +.. date: 2021-04-30-17-59-56 +.. nonce: 3EFl1H +.. section: IDLE + +Fix reference leak in test_sidebar and test_squeezer. +Patches by Terry Jan Reedy and Pablo Galindo + +.. + +.. bpo: 37892 +.. date: 2021-04-29-02-40-41 +.. nonce: bgW2fk +.. section: IDLE + +Indent IDLE Shell input with spaces instead of tabs + +.. + +.. bpo: 43655 +.. date: 2021-04-04-20-52-07 +.. nonce: HSyaKH +.. section: IDLE + +IDLE dialog windows are now recognized as dialogs by window managers on +macOS and X Window. + +.. + +.. bpo: 37903 +.. date: 2019-08-24-23-49-36 +.. nonce: 4xjast +.. section: IDLE + +IDLE's shell now shows prompts in a separate side-bar. + +.. + +.. bpo: 43916 +.. date: 2021-04-29-17-35-48 +.. nonce: wvWt23 +.. section: C API + +Add a new :c:macro:`Py_TPFLAGS_DISALLOW_INSTANTIATION` type flag to disallow +creating type instances. Patch by Victor Stinner. + +.. + +.. bpo: 43774 +.. date: 2021-04-29-10-17-21 +.. nonce: 5MGfgN +.. section: C API + +Remove the now unused ``PYMALLOC_DEBUG`` macro. Debug hooks on memory +allocators are now installed by default if Python is built in debug mode (if +``Py_DEBUG`` macro is defined). Moreover, they can now be used on Python +build in release mode (ex: using ``PYTHONMALLOC=debug`` environment +variable). + +.. + +.. bpo: 43962 +.. date: 2021-04-28-13-13-07 +.. nonce: 9Jzs5X +.. section: C API + +_PyInterpreterState_IDIncref() now calls _PyInterpreterState_IDInitref() and +always increments id_refcount. Previously, calling +_xxsubinterpreters.get_current() could create an id_refcount inconsistency +when a _xxsubinterpreters.InterpreterID object was deallocated. Patch by +Victor Stinner. + +.. + +.. bpo: 28254 +.. date: 2021-04-28-12-33-44 +.. nonce: a2561e +.. section: C API + +Add new C-API functions to control the state of the garbage collector: +:c:func:`PyGC_Enable()`, :c:func:`PyGC_Disable()`, +:c:func:`PyGC_IsEnabled()`, corresponding to the functions in the :mod:`gc` +module. + +.. + +.. bpo: 43908 +.. date: 2021-04-22-10-46-40 +.. nonce: Co3YhZ +.. section: C API + +Introduce :c:macro:`Py_TPFLAGS_IMMUTABLETYPE` flag for immutable type objects, +and modify :c:func:`PyType_Ready` to set it for static types. Patch by +Erlend E. Aasland. + +.. + +.. bpo: 43795 +.. date: 2021-04-20-15-06-29 +.. nonce: y0IP4c +.. section: C API + +:c:func:`PyMem_Calloc` is now available in the limited C API +(``Py_LIMITED_API``). + +.. + +.. bpo: 43868 +.. date: 2021-04-16-18-15-56 +.. nonce: twQ7KH +.. section: C API + +:c:func:`PyOS_ReadlineFunctionPointer` is no longer exported by limited C +API headers and by ``python3.dll`` on Windows. Like any function that takes +``FILE*``, it is not part of the stable ABI. + +.. + +.. bpo: 43795 +.. date: 2021-04-09-18-19-07 +.. nonce: l0yobT +.. section: C API + +Stable ABI and limited API definitions are generated from a central manifest +(:pep:`652`). + +.. + +.. bpo: 43753 +.. date: 2021-04-06-20-52-44 +.. nonce: xUsHp1 +.. section: C API + +Add the :c:func:`Py_Is(x, y) <Py_Is>` function to test if the *x* object is +the *y* object, the same as ``x is y`` in Python. Add also the +:c:func:`Py_IsNone`, :c:func:`Py_IsTrue`, :c:func:`Py_IsFalse` functions to +test if an object is, respectively, the ``None`` singleton, the ``True`` +singleton or the ``False`` singleton. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/3.11.0a1.rst b/Misc/NEWS.d/3.11.0a1.rst new file mode 100644 index 00000000..45fb725a --- /dev/null +++ b/Misc/NEWS.d/3.11.0a1.rst @@ -0,0 +1,5098 @@ +.. bpo: 42278 +.. date: 2021-08-29-12-39-44 +.. nonce: jvmQz_ +.. release date: 2021-10-05 +.. section: Security + +Replaced usage of :func:`tempfile.mktemp` with +:class:`~tempfile.TemporaryDirectory` to avoid a potential race condition. + +.. + +.. bpo: 44600 +.. date: 2021-07-25-20-04-54 +.. nonce: 0WMldg +.. section: Security + +Fix incorrect line numbers while tracing some failed patterns in :ref:`match +<match>` statements. Patch by Charles Burkland. + +.. + +.. bpo: 41180 +.. date: 2021-06-29-23-40-22 +.. nonce: uTWHv_ +.. section: Security + +Add auditing events to the :mod:`marshal` module, and stop raising +``code.__init__`` events for every unmarshalled code object. Directly +instantiated code objects will continue to raise an event, and audit event +handlers should inspect or collect the raw marshal data. This reduces a +significant performance overhead when loading from ``.pyc`` files. + +.. + +.. bpo: 44394 +.. date: 2021-06-29-02-45-53 +.. nonce: A220N1 +.. section: Security + +Update the vendored copy of libexpat to 2.4.1 (from 2.2.8) to get the fix +for the CVE-2013-0340 "Billion Laughs" vulnerability. This copy is most used +on Windows and macOS. + +.. + +.. bpo: 43124 +.. date: 2021-05-08-11-50-46 +.. nonce: 2CTM6M +.. section: Security + +Made the internal ``putcmd`` function in :mod:`smtplib` sanitize input for +presence of ``\r`` and ``\n`` characters to avoid (unlikely) command +injection. + +.. + +.. bpo: 44022 +.. date: 2021-05-05-17-37-04 +.. nonce: bS3XJ9 +.. section: Security + +:mod:`http.client` now avoids infinitely reading potential HTTP headers +after a ``100 Continue`` status response from the server. + +.. + +.. bpo: 43760 +.. date: 2021-10-04-16-11-50 +.. nonce: R9QoUv +.. section: Core and Builtins + +The number of hardware branches per instruction dispatch is reduced from two +to one by adding a special instruction for tracing. Patch by Mark Shannon. + +.. + +.. bpo: 45061 +.. date: 2021-09-21-22-27-25 +.. nonce: 5IOUf0 +.. section: Core and Builtins + +Add a deallocator to the bool type to detect refcount bugs in C extensions +which call Py_DECREF(Py_True) or Py_DECREF(Py_False) by mistake. Detect also +refcount bugs when the empty tuple singleton or the Unicode empty string +singleton is destroyed by mistake. Patch by Victor Stinner. + +.. + +.. bpo: 24076 +.. date: 2021-09-20-10-02-12 +.. nonce: ZFgFSj +.. section: Core and Builtins + +sum() was further optimised for summing up single digit integers. + +.. + +.. bpo: 45190 +.. date: 2021-09-14-10-02-12 +.. nonce: ZFRgSj +.. section: Core and Builtins + +Update Unicode databases to Unicode 14.0.0. + +.. + +.. bpo: 45167 +.. date: 2021-09-14-09-23-59 +.. nonce: CPSSoV +.. section: Core and Builtins + +Fix deepcopying of :class:`types.GenericAlias` objects. + +.. + +.. bpo: 45155 +.. date: 2021-09-09-15-05-17 +.. nonce: JRw9TG +.. section: Core and Builtins + +:meth:`int.to_bytes` and :meth:`int.from_bytes` now take a default value of +``"big"`` for the ``byteorder`` argument. :meth:`int.to_bytes` also takes a +default value of ``1`` for the ``length`` argument. + +.. + +.. bpo: 44219 +.. date: 2021-09-09-10-32-33 +.. nonce: WiYyjz +.. section: Core and Builtins + +Release the GIL while performing ``isatty`` system calls on arbitrary file +descriptors. In particular, this affects :func:`os.isatty`, +:func:`os.device_encoding` and :class:`io.TextIOWrapper`. By extension, +:func:`io.open` in text mode is also affected. This change solves a deadlock +in :func:`os.isatty`. Patch by Vincent Michel in :issue:`44219`. + +.. + +.. bpo: 44959 +.. date: 2021-09-08-08-29-41 +.. nonce: OSwwPf +.. section: Core and Builtins + +Added fallback to extension modules with '.sl' suffix on HP-UX + +.. + +.. bpo: 45121 +.. date: 2021-09-07-17-10-16 +.. nonce: iG-Hsf +.. section: Core and Builtins + +Fix issue where ``Protocol.__init__`` raises ``RecursionError`` when it's +called directly or via ``super()``. Patch provided by Yurii Karabas. + +.. + +.. bpo: 44348 +.. date: 2021-09-07-00-21-04 +.. nonce: f8w_Td +.. section: Core and Builtins + +The deallocator function of the :exc:`BaseException` type now uses the +trashcan mechanism to prevent stack overflow. For example, when a +:exc:`RecursionError` instance is raised, it can be linked to another +RecursionError through the ``__context__`` attribute or the +``__traceback__`` attribute, and then a chain of exceptions is created. When +the chain is destroyed, nested deallocator function calls can crash with a +stack overflow if the chain is too long compared to the available stack +memory. Patch by Victor Stinner. + +.. + +.. bpo: 45123 +.. date: 2021-09-06-21-52-45 +.. nonce: 8Eh9iI +.. section: Core and Builtins + +Fix PyAiter_Check to only check for the __anext__ presence (not for +__aiter__). Rename PyAiter_Check to PyAIter_Check, PyObject_GetAiter -> +PyObject_GetAIter. + +.. + +.. bpo: 1514420 +.. date: 2021-09-03-16-18-10 +.. nonce: 2Lumpj +.. section: Core and Builtins + +Interpreter no longer attempts to open files with names in angle brackets +(like "<string>" or "<stdin>") when formatting an exception. + +.. + +.. bpo: 41031 +.. date: 2021-09-03-12-35-17 +.. nonce: yPSJEs +.. section: Core and Builtins + +Match C and Python code formatting of unprintable exceptions and exceptions +in the :mod:`__main__` module. + +.. + +.. bpo: 37330 +.. date: 2021-09-02-01-28-01 +.. nonce: QDjM_l +.. section: Core and Builtins + +:func:`open`, :func:`io.open`, :func:`codecs.open` and +:class:`fileinput.FileInput` no longer accept ``'U'`` ("universal newline") +in the file mode. This flag was deprecated since Python 3.3. Patch by Victor +Stinner. + +.. + +.. bpo: 45083 +.. date: 2021-09-01-23-55-49 +.. nonce: cLi9G3 +.. section: Core and Builtins + +When the interpreter renders an exception, its name now has a complete +qualname. Previously only the class name was concatenated to the module +name, which sometimes resulted in an incorrect full name being displayed. + +(This issue impacted only the C code exception rendering, the +:mod:`traceback` module was using qualname already). + +.. + +.. bpo: 34561 +.. date: 2021-09-01-19-21-48 +.. nonce: uMAVA- +.. section: Core and Builtins + +List sorting now uses the merge-ordering strategy from Munro and Wild's +``powersort()``. Unlike the former strategy, this is provably near-optimal +in the entropy of the distribution of run lengths. Most uses of +``list.sort()`` probably won't see a significant time difference, but may +see significant improvements in cases where the former strategy was +exceptionally poor. However, as these are all fast linear-time +approximations to a problem that's inherently at best quadratic-time to +solve truly optimally, it's also possible to contrive cases where the former +strategy did better. + +.. + +.. bpo: 45056 +.. date: 2021-09-01-16-55-43 +.. nonce: 7AK2d9 +.. section: Core and Builtins + +Compiler now removes trailing unused constants from co_consts. + +.. + +.. bpo: 45020 +.. date: 2021-08-31-17-44-51 +.. nonce: ZPI_3L +.. section: Core and Builtins + +Add a new command line option, "-X frozen_modules=[on|off]" to opt out of +(or into) using optional frozen modules. This defaults to "on" (or "off" if +it's running out of the source tree). + +.. + +.. bpo: 45012 +.. date: 2021-08-31-11-09-52 +.. nonce: ueeOcx +.. section: Core and Builtins + +In :mod:`posix`, release GIL during ``stat()``, ``lstat()``, and +``fstatat()`` syscalls made by :func:`os.DirEntry.stat`. Patch by Stanisław +Skonieczny. + +.. + +.. bpo: 45018 +.. date: 2021-08-26-18-44-03 +.. nonce: pu8H9L +.. section: Core and Builtins + +Fixed pickling of range iterators that iterated for over ``2**32`` times. + +.. + +.. bpo: 45000 +.. date: 2021-08-25-23-17-32 +.. nonce: XjmyLl +.. section: Core and Builtins + +A :exc:`SyntaxError` is now raised when trying to delete :const:`__debug__`. +Patch by Donghee Na. + +.. + +.. bpo: 44963 +.. date: 2021-08-25-23-07-10 +.. nonce: 5EET8y +.. section: Core and Builtins + +Implement ``send()`` and ``throw()`` methods for ``anext_awaitable`` +objects. Patch by Pablo Galindo. + +.. + +.. bpo: 44962 +.. date: 2021-08-23-19-55-08 +.. nonce: J00ftt +.. section: Core and Builtins + +Fix a race in WeakKeyDictionary, WeakValueDictionary and WeakSet when two +threads attempt to commit the last pending removal. This fixes +asyncio.create_task and fixes a data loss in asyncio.run where +shutdown_asyncgens is not run + +.. + +.. bpo: 24234 +.. date: 2021-08-23-10-36-55 +.. nonce: MGVUQi +.. section: Core and Builtins + +Implement the :meth:`__bytes__` special method on the :class:`bytes` type, +so a bytes object ``b`` passes an ``isinstance(b, typing.SupportsBytes)`` +check. + +.. + +.. bpo: 24234 +.. date: 2021-08-22-12-28-50 +.. nonce: n3oTdx +.. section: Core and Builtins + +Implement the :meth:`__complex__` special method on the :class:`complex` +type, so a complex number ``z`` passes an ``isinstance(z, +typing.SupportsComplex)`` check. + +.. + +.. bpo: 44954 +.. date: 2021-08-19-14-43-24 +.. nonce: dLn3lg +.. section: Core and Builtins + +Fixed a corner case bug where the result of ``float.fromhex('0x.8p-1074')`` +was rounded the wrong way. + +.. + +.. bpo: 44947 +.. date: 2021-08-18-19-09-28 +.. nonce: mcvGdS +.. section: Core and Builtins + +Refine the syntax error for trailing commas in import statements. Patch by +Pablo Galindo. + +.. + +.. bpo: 44945 +.. date: 2021-08-18-11-14-38 +.. nonce: CO3s77 +.. section: Core and Builtins + +Specialize the BINARY_ADD instruction using the PEP 659 machinery. Adds five +new instructions: + +* BINARY_ADD_ADAPTIVE +* BINARY_ADD_FLOAT +* BINARY_ADD_INT +* BINARY_ADD_UNICODE +* BINARY_ADD_UNICODE_INPLACE_FAST + +.. + +.. bpo: 44929 +.. date: 2021-08-16-23-16-17 +.. nonce: qpMEky +.. section: Core and Builtins + +Fix some edge cases of ``enum.Flag`` string representation in the REPL. +Patch by Pablo Galindo. + +.. + +.. bpo: 44914 +.. date: 2021-08-16-11-36-02 +.. nonce: 6Lgrx3 +.. section: Core and Builtins + +Class version tags are no longer recycled. + +This means that a version tag serves as a unique identifier for the state of +a class. We rely on this for effective specialization of the LOAD_ATTR and +other instructions. + +.. + +.. bpo: 44698 +.. date: 2021-08-15-10-39-06 +.. nonce: lITKNc +.. section: Core and Builtins + +Restore behaviour of complex exponentiation with integer-valued exponent of +type :class:`float` or :class:`complex`. + +.. + +.. bpo: 44895 +.. date: 2021-08-14-20-13-21 +.. nonce: Ic9m90 +.. section: Core and Builtins + +A debug variable :envvar:`PYTHONDUMPREFSFILE` is added for creating a dump +file which is generated by :option:`--with-trace-refs`. Patch by Donghee +Na. + +.. + +.. bpo: 44900 +.. date: 2021-08-12-14-00-57 +.. nonce: w2gpwy +.. section: Core and Builtins + +Add five superinstructions for PEP 659 quickening: + +* LOAD_FAST LOAD_FAST +* STORE_FAST LOAD_FAST +* LOAD_FAST LOAD_CONST +* LOAD_CONST LOAD_FAST +* STORE_FAST STORE_FAST + +.. + +.. bpo: 44889 +.. date: 2021-08-11-20-45-02 +.. nonce: 2T3nTn +.. section: Core and Builtins + +Initial implementation of adaptive specialization of ``LOAD_METHOD``. The +following specialized forms were added: + +* ``LOAD_METHOD_CACHED`` + +* ``LOAD_METHOD_MODULE`` + +* ``LOAD_METHOD_CLASS`` + +.. + +.. bpo: 44890 +.. date: 2021-08-11-16-46-27 +.. nonce: PwNg8N +.. section: Core and Builtins + +Specialization stats are always collected in debug builds. + +.. + +.. bpo: 44885 +.. date: 2021-08-11-15-39-57 +.. nonce: i4noUO +.. section: Core and Builtins + +Correct the ast locations of f-strings with format specs and repeated +expressions. Patch by Pablo Galindo + +.. + +.. bpo: 44878 +.. date: 2021-08-11-14-12-41 +.. nonce: pAbBfc +.. section: Core and Builtins + +Remove the loop from the bytecode interpreter. All instructions end with a +DISPATCH macro, so the loop is now redundant. + +.. + +.. bpo: 44878 +.. date: 2021-08-11-12-03-52 +.. nonce: nEhjLi +.. section: Core and Builtins + +Remove switch statement for interpreter loop when using computed gotos. This +makes sure that we only have one dispatch table in the interpreter. + +.. + +.. bpo: 44874 +.. date: 2021-08-09-19-05-20 +.. nonce: oOcfU4 +.. section: Core and Builtins + +Deprecate the old trashcan macros +(``Py_TRASHCAN_SAFE_BEGIN``/``Py_TRASHCAN_SAFE_END``). They should be +replaced by the new macros ``Py_TRASHCAN_BEGIN`` and ``Py_TRASHCAN_END``. + +.. + +.. bpo: 44872 +.. date: 2021-08-09-16-16-03 +.. nonce: OKRlhK +.. section: Core and Builtins + +Use new trashcan macros (Py_TRASHCAN_BEGIN/END) in frameobject.c instead of +the old ones (Py_TRASHCAN_SAFE_BEGIN/END). + +.. + +.. bpo: 33930 +.. date: 2021-08-09-14-29-52 +.. nonce: --5LQ- +.. section: Core and Builtins + +Fix segmentation fault with deep recursion when cleaning method objects. +Patch by Augusto Goulart and Pablo Galindo. + +.. + +.. bpo: 25782 +.. date: 2021-08-07-21-39-19 +.. nonce: B22lMx +.. section: Core and Builtins + +Fix bug where ``PyErr_SetObject`` hangs when the current exception has a +cycle in its context chain. + +.. + +.. bpo: 44856 +.. date: 2021-08-07-01-26-12 +.. nonce: 9rk3li +.. section: Core and Builtins + +Fix reference leaks in the error paths of ``update_bases()`` and +``__build_class__``. Patch by Pablo Galindo. + +.. + +.. bpo: 44826 +.. date: 2021-08-05-17-49-55 +.. nonce: zQsyK5 +.. section: Core and Builtins + +Initial implementation of adaptive specialization of STORE_ATTR + +Three specialized forms of STORE_ATTR are added: + +* STORE_ATTR_SLOT + +* STORE_ATTR_SPLIT_KEYS + +* STORE_ATTR_WITH_HINT + +.. + +.. bpo: 44838 +.. date: 2021-08-05-17-42-03 +.. nonce: r_Lkj_ +.. section: Core and Builtins + +Fixed a bug that was causing the parser to raise an incorrect custom +:exc:`SyntaxError` for invalid 'if' expressions. Patch by Pablo Galindo. + +.. + +.. bpo: 44821 +.. date: 2021-08-04-11-37-38 +.. nonce: 67YHGI +.. section: Core and Builtins + +Create instance dictionaries (__dict__) eagerly, to improve regularity of +object layout and assist specialization. + +.. + +.. bpo: 44792 +.. date: 2021-07-31-12-12-57 +.. nonce: mOReTW +.. section: Core and Builtins + +Improve syntax errors for if expressions. Patch by Miguel Brito + +.. + +.. bpo: 34013 +.. date: 2021-07-27-11-14-22 +.. nonce: SjLFe- +.. section: Core and Builtins + +Generalize the invalid legacy statement custom error message (like the one +generated when "print" is called without parentheses) to include more +generic expressions. Patch by Pablo Galindo + +.. + +.. bpo: 44732 +.. date: 2021-07-26-15-27-03 +.. nonce: IxObt3 +.. section: Core and Builtins + +Rename ``types.Union`` to ``types.UnionType``. + +.. + +.. bpo: 44725 +.. date: 2021-07-23-15-17-01 +.. nonce: qcuKaa +.. section: Core and Builtins + +Expose specialization stats in python via +:func:`_opcode.get_specialization_stats`. + +.. + +.. bpo: 44717 +.. date: 2021-07-23-01-52-13 +.. nonce: -vVmAh +.. section: Core and Builtins + +Improve AttributeError on circular imports of submodules. + +.. + +.. bpo: 44698 +.. date: 2021-07-21-15-26-56 +.. nonce: DA4_0o +.. section: Core and Builtins + +Fix undefined behaviour in complex object exponentiation. + +.. + +.. bpo: 44653 +.. date: 2021-07-19-20-49-06 +.. nonce: WcqGyI +.. section: Core and Builtins + +Support :mod:`typing` types in parameter substitution in the union type. + +.. + +.. bpo: 44676 +.. date: 2021-07-19-19-53-46 +.. nonce: WgIMvh +.. section: Core and Builtins + +Add ability to serialise ``types.Union`` objects. Patch provided by Yurii +Karabas. + +.. + +.. bpo: 44633 +.. date: 2021-07-17-21-04-04 +.. nonce: 5-zKeI +.. section: Core and Builtins + +Parameter substitution of the union type with wrong types now raises +``TypeError`` instead of returning ``NotImplemented``. + +.. + +.. bpo: 44661 +.. date: 2021-07-17-14-20-59 +.. nonce: BQbXiH +.. section: Core and Builtins + +Update ``property_descr_set`` to use vectorcall if possible. Patch by +Donghee Na. + +.. + +.. bpo: 44662 +.. date: 2021-07-17-13-41-58 +.. nonce: q22kWR +.. section: Core and Builtins + +Add ``__module__`` to ``types.Union``. This also fixes ``types.Union`` +issues with ``typing.Annotated``. Patch provided by Yurii Karabas. + +.. + +.. bpo: 44655 +.. date: 2021-07-16-21-35-14 +.. nonce: 95I7M6 +.. section: Core and Builtins + +Include the name of the type in unset __slots__ attribute errors. Patch by +Pablo Galindo + +.. + +.. bpo: 44655 +.. date: 2021-07-16-20-25-37 +.. nonce: I3wRjL +.. section: Core and Builtins + +Don't include a missing attribute with the same name as the failing one when +offering suggestions for missing attributes. Patch by Pablo Galindo + +.. + +.. bpo: 44646 +.. date: 2021-07-16-09-59-13 +.. nonce: Yb6s05 +.. section: Core and Builtins + +Fix the hash of the union type: it no longer depends on the order of +arguments. + +.. + +.. bpo: 44636 +.. date: 2021-07-16-09-36-12 +.. nonce: ZWebi8 +.. section: Core and Builtins + +Collapse union of equal types. E.g. the result of ``int | int`` is now +``int``. Fix comparison of the union type with non-hashable objects. E.g. +``int | str == {}`` no longer raises a TypeError. + +.. + +.. bpo: 44611 +.. date: 2021-07-16-01-01-11 +.. nonce: LcfHN- +.. section: Core and Builtins + +On Windows, :func:`os.urandom`: uses BCryptGenRandom API instead of +CryptGenRandom API which is deprecated from Microsoft Windows API. Patch by +Donghee Na. + +.. + +.. bpo: 44635 +.. date: 2021-07-14-13-54-07 +.. nonce: 7ZMAdB +.. section: Core and Builtins + +Convert ``None`` to ``type(None)`` in the union type constructor. + +.. + +.. bpo: 26280 +.. date: 2021-07-14-10-31-10 +.. nonce: cgpM4B +.. section: Core and Builtins + +Implement adaptive specialization for BINARY_SUBSCR + +Three specialized forms of BINARY_SUBSCR are added: + +* BINARY_SUBSCR_LIST_INT + +* BINARY_SUBSCR_TUPLE_INT + +* BINARY_SUBSCR_DICT + +.. + +.. bpo: 44589 +.. date: 2021-07-13-23-19-41 +.. nonce: 59OH8T +.. section: Core and Builtins + +Mapping patterns in ``match`` statements with two or more equal literal keys +will now raise a :exc:`SyntaxError` at compile-time. + +.. + +.. bpo: 44606 +.. date: 2021-07-13-20-22-12 +.. nonce: S3Bv2w +.. section: Core and Builtins + +Fix ``__instancecheck__`` and ``__subclasscheck__`` for the union type. + +.. + +.. bpo: 42073 +.. date: 2021-07-13-17-47-32 +.. nonce: 9wopiC +.. section: Core and Builtins + +The ``@classmethod`` decorator can now wrap other classmethod-like +descriptors. + +.. + +.. bpo: 41972 +.. date: 2021-07-12-04-06-57 +.. nonce: nDX5k_ +.. section: Core and Builtins + +Tuned the string-searching algorithm of fastsearch.h to have a shorter inner +loop for most cases. + +.. + +.. bpo: 44590 +.. date: 2021-07-09-12-08-17 +.. nonce: a2ntVX +.. section: Core and Builtins + +All necessary data for executing a Python function (local variables, stack, +etc) is now kept in a per-thread stack. Frame objects are lazily allocated +on demand. This increases performance by about 7% on the standard benchmark +suite. Introspection and debugging are unaffected as frame objects are +always available when needed. Patch by Mark Shannon. + +.. + +.. bpo: 44584 +.. date: 2021-07-08-12-18-56 +.. nonce: qKnSqV +.. section: Core and Builtins + +The threading debug (:envvar:`PYTHONTHREADDEBUG` environment variable) is +deprecated in Python 3.10 and will be removed in Python 3.12. This feature +requires a debug build of Python. Patch by Victor Stinner. + +.. + +.. bpo: 43895 +.. date: 2021-07-07-16-05-35 +.. nonce: JFjR0- +.. section: Core and Builtins + +An obsolete internal cache of shared object file handles added in 1995 that +attempted, but did not guarantee, that a .so would not be dlopen'ed twice to +work around flaws in mid-1990s posix-ish operating systems has been removed +from dynload_shlib.c. + +.. + +.. bpo: 44490 +.. date: 2021-07-06-22-22-15 +.. nonce: BJxPbZ +.. section: Core and Builtins + +:mod:`typing` now searches for type parameters in ``types.Union`` objects. +``get_type_hints`` will also properly resolve annotations with nested +``types.Union`` objects. Patch provided by Yurii Karabas. + +.. + +.. bpo: 43950 +.. date: 2021-07-06-15-27-11 +.. nonce: LhL2-q +.. section: Core and Builtins + +Code objects can now provide the column information for instructions when +available. This is levaraged during traceback printing to show the +expressions responsible for errors. + +Contributed by Pablo Galindo, Batuhan Taskaya and Ammar Askar as part of +:pep:`657`. + +.. + +.. bpo: 44562 +.. date: 2021-07-04-23-38-51 +.. nonce: QdeRQo +.. section: Core and Builtins + +Remove uses of :c:func:`PyObject_GC_Del` in error path when initializing +:class:`types.GenericAlias`. + +.. + +.. bpo: 41486 +.. date: 2021-07-04-17-41-47 +.. nonce: DiM24a +.. section: Core and Builtins + +Fix a memory consumption and copying performance regression in earlier 3.10 +beta releases if someone used an output buffer larger than 4GiB with +zlib.decompress on input data that expands that large. + +.. + +.. bpo: 43908 +.. date: 2021-07-03-00-20-39 +.. nonce: YHuV_s +.. section: Core and Builtins + +Heap types with the :c:macro:`Py_TPFLAGS_IMMUTABLETYPE` flag can now inherit +the :pep:`590` vectorcall protocol. Previously, this was only possible for +:ref:`static types <static-types>`. Patch by Erlend E. Aasland. + +.. + +.. bpo: 44553 +.. date: 2021-07-02-22-54-41 +.. nonce: l9YqGg +.. section: Core and Builtins + +Implement GC methods for ``types.Union`` to break reference cycles and +prevent memory leaks. + +.. + +.. bpo: 44490 +.. date: 2021-07-01-11-59-34 +.. nonce: xY80VR +.. section: Core and Builtins + +Add ``__parameters__`` attribute and ``__getitem__`` operator to +``types.Union``. Patch provided by Yurii Karabas. + +.. + +.. bpo: 44523 +.. date: 2021-06-29-11-49-29 +.. nonce: 67-ZIP +.. section: Core and Builtins + +Remove the pass-through for :func:`hash` of :class:`weakref.proxy` objects +to prevent unintended consequences when the original referred object dies +while the proxy is part of a hashable object. Patch by Pablo Galindo. + +.. + +.. bpo: 44483 +.. date: 2021-06-22-19-08-19 +.. nonce: eq2f7T +.. section: Core and Builtins + +Fix a crash in ``types.Union`` objects when creating a union of an object +with bad ``__module__`` field. + +.. + +.. bpo: 44486 +.. date: 2021-06-22-10-55-23 +.. nonce: wct-9X +.. section: Core and Builtins + +Modules will always have a dictionary, even when created by +``types.ModuleType.__new__()`` + +.. + +.. bpo: 44472 +.. date: 2021-06-21-11-19-54 +.. nonce: Vvm1yn +.. section: Core and Builtins + +Fix ltrace functionality when exceptions are raised. Patch by Pablo Galindo + +.. + +.. bpo: 12022 +.. date: 2021-06-20-10-53-21 +.. nonce: SW240M +.. section: Core and Builtins + +A :exc:`TypeError` is now raised instead of an :exc:`AttributeError` in +:keyword:`with` and :keyword:`async with` statements for objects which do +not support the :term:`context manager` or :term:`asynchronous context +manager` protocols correspondingly. + +.. + +.. bpo: 44297 +.. date: 2021-06-19-12-41-13 +.. nonce: F53vHj +.. section: Core and Builtins + +Make sure that the line number is set when entering a comprehension scope. +Ensures that backtraces inclusing generator expressions show the correct +line number. + +.. + +.. bpo: 44456 +.. date: 2021-06-18-22-08-25 +.. nonce: L0Rhko +.. section: Core and Builtins + +Improve the syntax error when mixing positional and keyword patterns. Patch +by Pablo Galindo. + +.. + +.. bpo: 44409 +.. date: 2021-06-13-23-12-18 +.. nonce: eW4LS- +.. section: Core and Builtins + +Fix error location information for tokenizer errors raised on initialization +of the tokenizer. Patch by Pablo Galindo. + +.. + +.. bpo: 44396 +.. date: 2021-06-11-18-17-42 +.. nonce: Z9EKim +.. section: Core and Builtins + +Fix a possible crash in the tokenizer when raising syntax errors for +unclosed strings. Patch by Pablo Galindo. + +.. + +.. bpo: 44376 +.. date: 2021-06-11-17-37-15 +.. nonce: zhM1UW +.. section: Core and Builtins + +Exact integer exponentiation (like ``i**2`` or ``pow(i, 2)``) with a small +exponent is much faster, due to reducing overhead in such cases. + +.. + +.. bpo: 44313 +.. date: 2021-06-10-16-10-39 +.. nonce: 34RjI8 +.. section: Core and Builtins + +Directly imported objects and modules (through import and from import +statements) don't generate ``LOAD_METHOD``/``CALL_METHOD`` for directly +accessed objects on their namespace. They now use the regular +``LOAD_ATTR``/``CALL_FUNCTION``. + +.. + +.. bpo: 44338 +.. date: 2021-06-10-10-06-18 +.. nonce: c4Myr4 +.. section: Core and Builtins + +Implement adaptive specialization for LOAD_GLOBAL + +Two specialized forms of LOAD_GLOBAL are added: + +* LOAD_GLOBAL_MODULE + +* LOAD_GLOBAL_BUILTIN + +.. + +.. bpo: 44368 +.. date: 2021-06-09-22-56-59 +.. nonce: vgT0Cx +.. section: Core and Builtins + +Improve syntax errors for invalid "as" targets. Patch by Pablo Galindo + +.. + +.. bpo: 44349 +.. date: 2021-06-08-22-49-06 +.. nonce: xgEgeA +.. section: Core and Builtins + +Fix an edge case when displaying text from files with encoding in syntax +errors. Patch by Pablo Galindo. + +.. + +.. bpo: 44337 +.. date: 2021-06-08-10-22-46 +.. nonce: RTjmIt +.. section: Core and Builtins + +Initial implementation of adaptive specialization of LOAD_ATTR + +Four specialized forms of LOAD_ATTR are added: + +* LOAD_ATTR_SLOT + +* LOAD_ATTR_SPLIT_KEYS + +* LOAD_ATTR_WITH_HINT + +* LOAD_ATTR_MODULE + +.. + +.. bpo: 44335 +.. date: 2021-06-08-01-13-47 +.. nonce: GQTTkl +.. section: Core and Builtins + +Fix a regression when identifying incorrect characters in syntax errors. +Patch by Pablo Galindo + +.. + +.. bpo: 43693 +.. date: 2021-06-07-15-13-44 +.. nonce: c_zDeY +.. section: Core and Builtins + +Computation of the offsets of cell variables is done in the compiler instead +of at runtime. This reduces the overhead of handling cell and free +variables, especially in the case where a variable is both an argument and +cell variable. + +.. + +.. bpo: 44317 +.. date: 2021-06-06-00-29-14 +.. nonce: xPPhcZ +.. section: Core and Builtins + +Improve tokenizer error with improved locations. Patch by Pablo Galindo. + +.. + +.. bpo: 44304 +.. date: 2021-06-05-02-34-57 +.. nonce: _MAoPc +.. section: Core and Builtins + +Fix a crash in the :mod:`sqlite3` module that happened when the garbage +collector clears :class:`sqlite.Statement` objects. Patch by Pablo Galindo + +.. + +.. bpo: 44305 +.. date: 2021-06-03-22-51-50 +.. nonce: 66dVDG +.. section: Core and Builtins + +Improve error message for ``try`` blocks without ``except`` or ``finally`` +blocks. Patch by Pablo Galindo. + +.. + +.. bpo: 43413 +.. date: 2021-05-30-16-37-47 +.. nonce: vYFPPC +.. section: Core and Builtins + +Constructors of subclasses of some builtin classes (e.g. :class:`tuple`, +:class:`list`, :class:`frozenset`) no longer accept arbitrary keyword +arguments. [reverted in 3.11a4] Subclass of :class:`set` can now define a ``__new__()`` method +with additional keyword parameters without overriding also ``__init__()``. + +.. + +.. bpo: 43667 +.. date: 2021-05-27-17-34-29 +.. nonce: ND9jP3 +.. section: Core and Builtins + +Improve Unicode support in non-UTF locales on Oracle Solaris. This issue +does not affect other Solaris systems. + +.. + +.. bpo: 43693 +.. date: 2021-05-26-19-10-47 +.. nonce: 1KSG9u +.. section: Core and Builtins + +A new opcode MAKE_CELL has been added that effectively moves some of the +work done on function entry into the compiler and into the eval loop. In +addition to creating the required cell objects, the new opcode converts +relevant arguments (and other locals) to cell variables on function entry. + +.. + +.. bpo: 44232 +.. date: 2021-05-25-18-20-10 +.. nonce: DMcCCf +.. section: Core and Builtins + +Fix a regression in :func:`type` when a metaclass raises an exception. The C +function :c:func:`type_new` must properly report the exception when a +metaclass constructor raises an exception and the winner class is not the +metaclass. Patch by Victor Stinner. + +.. + +.. bpo: 44201 +.. date: 2021-05-21-21-16-03 +.. nonce: bGaSjt +.. section: Core and Builtins + +Avoid side effects of checking for specialized syntax errors in the REPL +that was causing it to ask for extra tokens after a syntax error had been +detected. Patch by Pablo Galindo + +.. + +.. bpo: 43693 +.. date: 2021-05-21-20-53-49 +.. nonce: -NN3J_ +.. section: Core and Builtins + +``PyCodeObject`` gained ``co_fastlocalnames`` and ``co_fastlocalkinds`` as +the authoritative source of fast locals info. Marshaled code objects +have changed accordingly. + +.. + +.. bpo: 44184 +.. date: 2021-05-21-01-42-45 +.. nonce: 9qOptC +.. section: Core and Builtins + +Fix a crash at Python exit when a deallocator function removes the last +strong reference to a heap type. Patch by Victor Stinner. + +.. + +.. bpo: 44187 +.. date: 2021-05-20-12-43-04 +.. nonce: 3lk0L1 +.. section: Core and Builtins + +Implement quickening in the interpreter. This offers no advantages as yet, +but is an enabler of future optimizations. See PEP 659 for full explanation. + +.. + +.. bpo: 44180 +.. date: 2021-05-19-20-33-36 +.. nonce: mQVaAs +.. section: Core and Builtins + +The parser doesn't report generic syntax errors that happen in a position +further away that the one it reached in the first pass. Patch by Pablo +Galindo + +.. + +.. bpo: 44168 +.. date: 2021-05-18-11-27-02 +.. nonce: mgB-rt +.. section: Core and Builtins + +Fix error message in the parser involving keyword arguments with invalid +expressions. Patch by Pablo Galindo + +.. + +.. bpo: 44156 +.. date: 2021-05-17-20-44-45 +.. nonce: 8KSp9l +.. section: Core and Builtins + +String caches in ``compile.c`` are now subinterpreter compatible. + +.. + +.. bpo: 44143 +.. date: 2021-05-15-17-30-57 +.. nonce: 7UTS6H +.. section: Core and Builtins + +Fixed a crash in the parser that manifest when raising tokenizer errors when +an existing exception was present. Patch by Pablo Galindo. + +.. + +.. bpo: 44032 +.. date: 2021-05-14-20-03-32 +.. nonce: OzT1ob +.. section: Core and Builtins + +Move 'fast' locals and other variables from the frame object to a per-thread +datastack. + +.. + +.. bpo: 44114 +.. date: 2021-05-12-14-26-16 +.. nonce: p-WfAE +.. section: Core and Builtins + +Fix incorrect dictkeys_reversed and dictitems_reversed function signatures +in C code, which broke webassembly builds. + +.. + +.. bpo: 44110 +.. date: 2021-05-11-21-52-44 +.. nonce: VqbAsB +.. section: Core and Builtins + +Improve :func:`str.__getitem__` error message + +.. + +.. bpo: 26110 +.. date: 2021-05-10-18-49-13 +.. nonce: EQzqqA +.. section: Core and Builtins + +Add ``CALL_METHOD_KW`` opcode to speed up method calls with keyword +arguments. Idea originated from PyPy. A side effect is executing +``CALL_METHOD`` is now branchless in the evaluation loop. + +.. + +.. bpo: 28307 +.. date: 2021-05-08-19-54-57 +.. nonce: 7ysaVW +.. section: Core and Builtins + +Compiler now optimizes simple C-style formatting with literal format +containing only format codes %s, %r and %a by converting them to f-string +expressions. + +.. + +.. bpo: 43149 +.. date: 2021-05-08-17-18-37 +.. nonce: Kp5FxD +.. section: Core and Builtins + +Correct the syntax error message regarding multiple exception types to not +refer to "exception groups". Patch by Pablo Galindo + +.. + +.. bpo: 43822 +.. date: 2021-05-04-01-01-04 +.. nonce: 9VeCg0 +.. section: Core and Builtins + +The parser will prioritize tokenizer errors over custom syntax errors when +raising exceptions. Patch by Pablo Galindo. + +.. + +.. bpo: 40222 +.. date: 2021-04-30-15-48-36 +.. nonce: j3VxeX +.. section: Core and Builtins + +"Zero cost" exception handling. + +* Uses a lookup table to determine how to handle exceptions. +* Removes SETUP_FINALLY and POP_TOP block instructions, eliminating the runtime overhead of try statements. +* Reduces the size of the frame object by about 60%. + +Patch by Mark Shannon + +.. + +.. bpo: 43918 +.. date: 2021-04-23-03-46-45 +.. nonce: nNDY3S +.. section: Core and Builtins + +Document the signature and ``default`` argument in the docstring of the new +``anext`` builtin. + +.. + +.. bpo: 43833 +.. date: 2021-04-18-18-07-33 +.. nonce: oChkCi +.. section: Core and Builtins + +Emit a deprecation warning if the numeric literal is immediately followed by +one of keywords: and, else, for, if, in, is, or. Raise a syntax error with +more informative message if it is immediately followed by other keyword or +identifier. + +.. + +.. bpo: 43879 +.. date: 2021-04-17-16-08-00 +.. nonce: zkyJgh +.. section: Core and Builtins + +Add native_thread_id to PyThreadState. Patch by Gabriele N. Tornetta. + +.. + +.. bpo: 43693 +.. date: 2021-04-02-15-02-16 +.. nonce: l3Ureu +.. section: Core and Builtins + +Compute cell offsets relative to locals in compiler. Allows the interpreter +to treats locals and cells a single array, which is slightly more efficient. +Also make the LOAD_CLOSURE opcode an alias for LOAD_FAST. Preserving +LOAD_CLOSURE helps keep bytecode a bit more readable. + +.. + +.. bpo: 17792 +.. date: 2021-03-22-17-50-30 +.. nonce: _zssjS +.. section: Core and Builtins + +More accurate error messages for access of unbound locals or free vars. + +.. + +.. bpo: 28146 +.. date: 2021-01-13-19-34-41 +.. nonce: AZBBkH +.. section: Core and Builtins + +Fix a confusing error message in :func:`str.format`. + +.. + +.. bpo: 11105 +.. date: 2020-06-02-13-21-14 +.. nonce: wceryW +.. section: Core and Builtins + +When compiling :class:`ast.AST` objects with recursive references through +:func:`compile`, the interpreter doesn't crash anymore instead it raises a +:exc:`RecursionError`. + +.. + +.. bpo: 39091 +.. date: 2019-12-21-14-18-32 +.. nonce: dOexgQ +.. section: Core and Builtins + +Fix crash when using passing a non-exception to a generator's ``throw()`` +method. Patch by Noah Oxer + +.. + +.. bpo: 33346 +.. date: 2018-05-11-12-44-03 +.. nonce: ZgBkvB +.. section: Core and Builtins + +Asynchronous comprehensions are now allowed inside comprehensions in +asynchronous functions. Outer comprehensions implicitly become +asynchronous. + +.. + +.. bpo: 45371 +.. date: 2021-10-05-11-03-48 +.. nonce: NOwcDJ +.. section: Library + +Fix clang rpath issue in ``distutils``. The UnixCCompiler now uses +correct clang option to add a runtime library directory (rpath) to a shared +library. + +.. + +.. bpo: 45329 +.. date: 2021-10-01-13-09-53 +.. nonce: 9iMYaO +.. section: Library + +Fix freed memory access in :class:`pyexpat.xmlparser` when building it with +an installed expat library <= 2.2.0. + +.. + +.. bpo: 41710 +.. date: 2021-09-30-23-00-18 +.. nonce: svuloZ +.. section: Library + +On Unix, if the ``sem_clockwait()`` function is available in the C library +(glibc 2.30 and newer), the :meth:`threading.Lock.acquire` method now uses +the monotonic clock (:const:`time.CLOCK_MONOTONIC`) for the timeout, rather +than using the system clock (:const:`time.CLOCK_REALTIME`), to not be +affected by system clock changes. Patch by Victor Stinner. + +.. + +.. bpo: 1596321 +.. date: 2021-09-24-17-20-23 +.. nonce: 3nhPUk +.. section: Library + +Fix the :func:`threading._shutdown` function when the :mod:`threading` +module was imported first from a thread different than the main thread: no +longer log an error at Python exit. + +.. + +.. bpo: 45274 +.. date: 2021-09-23-22-17-26 +.. nonce: gPpa4E +.. section: Library + +Fix a race condition in the :meth:`Thread.join() <threading.Thread.join>` +method of the :mod:`threading` module. If the function is interrupted by a +signal and the signal handler raises an exception, make sure that the thread +remains in a consistent state to prevent a deadlock. Patch by Victor +Stinner. + +.. + +.. bpo: 21302 +.. date: 2021-09-22-23-56-15 +.. nonce: vvQ3Su +.. section: Library + +In Unix operating systems, :func:`time.sleep` now uses the ``nanosleep()`` +function, if ``clock_nanosleep()`` is not available but ``nanosleep()`` is +available. ``nanosleep()`` allows to sleep with nanosecond precision. + +.. + +.. bpo: 21302 +.. date: 2021-09-20-22-46-40 +.. nonce: h56430 +.. section: Library + +On Windows, :func:`time.sleep` now uses a waitable timer which has a +resolution of 100 nanoseconds (10\ :sup:`-7` seconds). Previously, it had a +resolution of 1 millisecond (10\ :sup:`-3` seconds). Patch by Benjamin Szőke and +Victor Stinner. + +.. + +.. bpo: 45238 +.. date: 2021-09-18-16-56-33 +.. nonce: Hng_9V +.. section: Library + +Fix :meth:`unittest.IsolatedAsyncioTestCase.debug`: it runs now asynchronous +methods and callbacks. + +.. + +.. bpo: 36674 +.. date: 2021-09-18-13-14-57 +.. nonce: a2k5Zb +.. section: Library + +:meth:`unittest.TestCase.debug` raises now a :class:`unittest.SkipTest` if +the class or the test method are decorated with the skipping decorator. + +.. + +.. bpo: 45235 +.. date: 2021-09-17-16-55-37 +.. nonce: sXnmPA +.. section: Library + +Fix an issue where argparse would not preserve values in a provided +namespace when using a subparser with defaults. + +.. + +.. bpo: 45183 +.. date: 2021-09-17-15-58-53 +.. nonce: Vv_vch +.. section: Library + +Have zipimport.zipimporter.find_spec() not raise an exception when the +underlying zip file has been deleted and the internal cache has been reset +via invalidate_cache(). + +.. + +.. bpo: 45234 +.. date: 2021-09-17-11-20-55 +.. nonce: qUcTVt +.. section: Library + +Fixed a regression in :func:`~shutil.copyfile`, :func:`~shutil.copy`, +:func:`~shutil.copy2` raising :exc:`FileNotFoundError` when source is a +directory, which should raise :exc:`IsADirectoryError` + +.. + +.. bpo: 45228 +.. date: 2021-09-17-09-59-33 +.. nonce: WV1dcT +.. section: Library + +Fix stack buffer overflow in parsing J1939 network address. + +.. + +.. bpo: 45225 +.. date: 2021-09-16-19-02-14 +.. nonce: xmKV4i +.. section: Library + +use map function instead of genexpr in capwords. + +.. + +.. bpo: 42135 +.. date: 2021-09-13-19-32-58 +.. nonce: 1ZAHqR +.. section: Library + +Fix typo: ``importlib.find_loader`` is really slated for removal in Python +3.12 not 3.10, like the others in PR 25169. + +Patch by Hugo van Kemenade. + +.. + +.. bpo: 20524 +.. date: 2021-09-13-14-59-01 +.. nonce: PMQ1Fh +.. section: Library + +Improves error messages on ``.format()`` operation for ``str``, ``float``, +``int``, and ``complex``. New format now shows the problematic pattern and +the object type. + +.. + +.. bpo: 45168 +.. date: 2021-09-13-14-28-49 +.. nonce: Z1mfW4 +.. section: Library + +Change :func:`dis.dis` output to omit op arg values that cannot be resolved +due to ``co_consts``, ``co_names`` etc not being provided. Previously the +oparg itself was repeated in the value field, which is not useful and can be +confusing. + +.. + +.. bpo: 21302 +.. date: 2021-09-11-18-44-40 +.. nonce: QxHRpR +.. section: Library + +In Unix operating systems, :func:`time.sleep` now uses the +``clock_nanosleep()`` function, if available, which allows to sleep for an +interval specified with nanosecond precision. + +.. + +.. bpo: 45173 +.. date: 2021-09-11-17-46-20 +.. nonce: UptGAn +.. section: Library + +Remove from the :mod:`configparser` module: the :class:`SafeConfigParser` +class, the :attr:`filename` property of the :class:`ParsingError` class, the +:meth:`readfp` method of the :class:`ConfigParser` class, deprecated since +Python 3.2. + +Patch by Hugo van Kemenade. + +.. + +.. bpo: 44987 +.. date: 2021-09-11-14-41-02 +.. nonce: Mt8DiX +.. section: Library + +Pure ASCII strings are now normalized in constant time by +:func:`unicodedata.normalize`. Patch by Donghee Na. + +.. + +.. bpo: 35474 +.. date: 2021-09-11-10-45-12 +.. nonce: tEY3SD +.. section: Library + +Calling :func:`mimetypes.guess_all_extensions` with ``strict=False`` no +longer affects the result of the following call with ``strict=True``. Also, +mutating the returned list no longer affects the global state. + +.. + +.. bpo: 45166 +.. date: 2021-09-10-21-35-53 +.. nonce: UHipXF +.. section: Library + +:func:`typing.get_type_hints` now works with :data:`~typing.Final` wrapped +in :class:`~typing.ForwardRef`. + +.. + +.. bpo: 45162 +.. date: 2021-09-10-13-20-53 +.. nonce: 2Jh-lq +.. section: Library + +Remove many old deprecated :mod:`unittest` features: + +* "``fail*``" and "``assert*``" aliases of :class:`~unittest.TestCase` methods. +* Broken from start :class:`~unittest.TestCase` method ``assertDictContainsSubset()``. +* Ignored :meth:`<unittest.TestLoader.loadTestsFromModule> TestLoader.loadTestsFromModule` parameter *use_load_tests*. +* Old alias ``_TextTestResult`` of :class:`~unittest.TextTestResult`. + +.. + +.. bpo: 38371 +.. date: 2021-09-08-13-19-29 +.. nonce: y1kEfP +.. section: Library + +Remove the deprecated ``split()`` method of :class:`_tkinter.TkappType`. +Patch by Erlend E. Aasland. + +.. + +.. bpo: 20499 +.. date: 2021-09-08-01-19-31 +.. nonce: tSxx8Y +.. section: Library + +Improve the speed and accuracy of statistics.pvariance(). + +.. + +.. bpo: 45132 +.. date: 2021-09-07-16-33-51 +.. nonce: WI9zQY +.. section: Library + +Remove :meth:`__getitem__` methods of +:class:`xml.dom.pulldom.DOMEventStream`, :class:`wsgiref.util.FileWrapper` +and :class:`fileinput.FileInput`, deprecated since Python 3.9. + +Patch by Hugo van Kemenade. + +.. + +.. bpo: 45129 +.. date: 2021-09-07-14-27-39 +.. nonce: vXH0gw +.. section: Library + +Due to significant security concerns, the *reuse_address* parameter of +:meth:`asyncio.loop.create_datagram_endpoint`, disabled in Python 3.9, is +now entirely removed. This is because of the behavior of the socket option +``SO_REUSEADDR`` in UDP. + +Patch by Hugo van Kemenade. + +.. + +.. bpo: 45124 +.. date: 2021-09-07-09-13-27 +.. nonce: Kw5AUs +.. section: Library + +The ``bdist_msi`` command, deprecated in Python 3.9, is now removed. + +Use ``bdist_wheel`` (wheel packages) instead. + +Patch by Hugo van Kemenade. + +.. + +.. bpo: 30856 +.. date: 2021-09-05-21-37-28 +.. nonce: jj86y0 +.. section: Library + +:class:`unittest.TestResult` methods +:meth:`~unittest.TestResult.addFailure`, +:meth:`~unittest.TestResult.addError`, :meth:`~unittest.TestResult.addSkip` +and :meth:`~unittest.TestResult.addSubTest` are now called immediately after +raising an exception in test or finishing a subtest. Previously they were +called only after finishing the test clean up. + +.. + +.. bpo: 45034 +.. date: 2021-09-05-20-33-25 +.. nonce: 62NLD5 +.. section: Library + +Changes how error is formatted for ``struct.pack`` with ``'H'`` and ``'h'`` +modes and too large / small numbers. Now it shows the actual numeric limits, +while previously it was showing arithmetic expressions. + +.. + +.. bpo: 25894 +.. date: 2021-09-05-13-15-08 +.. nonce: zjbi2f +.. section: Library + +:mod:`unittest` now always reports skipped and failed subtests separately: +separate characters in default mode and separate lines in verbose mode. Also +the test description is now output for errors in test method, class and +module cleanups. + +.. + +.. bpo: 45081 +.. date: 2021-09-02-12-42-25 +.. nonce: tOjJ1k +.. section: Library + +Fix issue when dataclasses that inherit from ``typing.Protocol`` subclasses +have wrong ``__init__``. Patch provided by Yurii Karabas. + +.. + +.. bpo: 45085 +.. date: 2021-09-02-00-47-14 +.. nonce: mMnaDv +.. section: Library + +The ``binhex`` module, deprecated in Python 3.9, is now removed. The +following :mod:`binascii` functions, deprecated in Python 3.9, are now also +removed: + +* ``a2b_hqx()``, ``b2a_hqx()``; +* ``rlecode_hqx()``, ``rledecode_hqx()``. + +The :func:`binascii.crc_hqx` function remains available. + +Patch by Victor Stinner. + +.. + +.. bpo: 40360 +.. date: 2021-09-02-00-18-32 +.. nonce: 9nmMtB +.. section: Library + +The :mod:`lib2to3` package is now deprecated and may not be able to parse +Python 3.10 or newer. See the :pep:`617` (New PEG parser for CPython). Patch +by Victor Stinner. + +.. + +.. bpo: 45075 +.. date: 2021-09-01-15-27-00 +.. nonce: 9xUpvt +.. section: Library + +Rename :meth:`traceback.StackSummary.format_frame` to +:meth:`traceback.StackSummary.format_frame_summary`. This method was added +for 3.11 so it was not released yet. + +Updated code and docs to better distinguish frame and FrameSummary. + +.. + +.. bpo: 31299 +.. date: 2021-08-30-13-55-09 +.. nonce: 9QzjZs +.. section: Library + +Add option to completely drop frames from a traceback by returning ``None`` +from a :meth:`~traceback.StackSummary.format_frame` override. + +.. + +.. bpo: 41620 +.. date: 2021-08-29-14-49-22 +.. nonce: WJ6PFL +.. section: Library + +:meth:`~unittest.TestCase.run` now always return a +:class:`~unittest.TestResult` instance. Previously it returned ``None`` if +the test class or method was decorated with a skipping decorator. + +.. + +.. bpo: 45021 +.. date: 2021-08-28-13-00-12 +.. nonce: rReeaj +.. section: Library + +Fix a potential deadlock at shutdown of forked children when using +:mod:`concurrent.futures` module + +.. + +.. bpo: 43913 +.. date: 2021-08-27-23-40-51 +.. nonce: Uo1Gt5 +.. section: Library + +Fix bugs in cleaning up classes and modules in :mod:`unittest`: + +* Functions registered with :func:`~unittest.addModuleCleanup` were not called unless the user defines ``tearDownModule()`` in their test module. +* Functions registered with :meth:`~unittest.TestCase.addClassCleanup` were not called if ``tearDownClass`` is set to ``None``. +* Buffering in :class:`~unittest.TestResult` did not work with functions registered with ``addClassCleanup()`` and ``addModuleCleanup()``. +* Errors in functions registered with ``addClassCleanup()`` and ``addModuleCleanup()`` were not handled correctly in buffered and debug modes. +* Errors in ``setUpModule()`` and functions registered with ``addModuleCleanup()`` were reported in wrong order. +* And several lesser bugs. + +.. + +.. bpo: 45030 +.. date: 2021-08-27-19-01-23 +.. nonce: tAmBbY +.. section: Library + +Fix integer overflow in pickling and copying the range iterator. + +.. + +.. bpo: 45001 +.. date: 2021-08-26-16-25-48 +.. nonce: tn_dKp +.. section: Library + +Made email date parsing more robust against malformed input, namely a +whitespace-only ``Date:`` header. Patch by Wouter Bolsterlee. + +.. + +.. bpo: 45010 +.. date: 2021-08-26-09-54-14 +.. nonce: Cn23bQ +.. section: Library + +Remove support of special method ``__div__`` in :mod:`unittest.mock`. It is +not used in Python 3. + +.. + +.. bpo: 39218 +.. date: 2021-08-25-20-18-31 +.. nonce: BlO6jW +.. section: Library + +Improve accuracy of variance calculations by using ``x*x`` instead of +``x**2``. + +.. + +.. bpo: 43613 +.. date: 2021-08-25-10-28-49 +.. nonce: WkYmI0 +.. section: Library + +Improve the speed of :func:`gzip.compress` and :func:`gzip.decompress` by +compressing and decompressing at once in memory instead of in a streamed +fashion. + +.. + +.. bpo: 37596 +.. date: 2021-08-23-21-39-59 +.. nonce: ojRcwB +.. section: Library + +Ensure that :class:`set` and :class:`frozenset` objects are always +:mod:`marshalled <marshal>` reproducibly. + +.. + +.. bpo: 44019 +.. date: 2021-08-22-13-25-17 +.. nonce: BN8HDy +.. section: Library + +A new function ``operator.call`` has been added, such that +``operator.call(obj, *args, **kwargs) == obj(*args, **kwargs)``. + +.. + +.. bpo: 42255 +.. date: 2021-08-19-23-49-10 +.. nonce: ofe3ms +.. section: Library + +:class:`webbrowser.MacOSX` is deprecated and will be removed in Python 3.13. +It is untested and undocumented and also not used by webbrowser itself. +Patch by Donghee Na. + +.. + +.. bpo: 44955 +.. date: 2021-08-19-15-03-54 +.. nonce: 1mxFQS +.. section: Library + +Method :meth:`~unittest.TestResult.stopTestRun` is now always called in pair +with method :meth:`~unittest.TestResult.startTestRun` for +:class:`~unittest.TestResult` objects implicitly created in +:meth:`~unittest.TestCase.run`. Previously it was not called for test +methods and classes decorated with a skipping decorator. + +.. + +.. bpo: 39039 +.. date: 2021-08-18-10-36-14 +.. nonce: A63LYh +.. section: Library + +tarfile.open raises :exc:`~tarfile.ReadError` when a zlib error occurs +during file extraction. + +.. + +.. bpo: 44935 +.. date: 2021-08-17-16-01-44 +.. nonce: roUl0G +.. section: Library + +:mod:`subprocess` on Solaris now also uses :func:`os.posix_spawn()` for +better performance. + +.. + +.. bpo: 44911 +.. date: 2021-08-14-00-55-16 +.. nonce: uk3hYk +.. section: Library + +:class:`~unittest.IsolatedAsyncioTestCase` will no longer throw an exception +while cancelling leaked tasks. Patch by Bar Harel. + +.. + +.. bpo: 41322 +.. date: 2021-08-12-16-22-16 +.. nonce: utscTd +.. section: Library + +Added ``DeprecationWarning`` for tests and async tests that return a +value!=None (as this may indicate an improperly written test, for example a +test written as a generator function). + +.. + +.. bpo: 44524 +.. date: 2021-08-10-16-57-10 +.. nonce: dk9QX4 +.. section: Library + +Make exception message more useful when subclass from typing special form +alias. Patch provided by Yurii Karabas. + +.. + +.. bpo: 38956 +.. date: 2021-08-09-13-17-10 +.. nonce: owWLNv +.. section: Library + +:class:`argparse.BooleanOptionalAction`'s default value is no longer printed +twice when used with :class:`argparse.ArgumentDefaultsHelpFormatter`. + +.. + +.. bpo: 44860 +.. date: 2021-08-07-22-51-32 +.. nonce: PTvRrU +.. section: Library + +Fix the ``posix_user`` scheme in :mod:`sysconfig` to not depend on +:data:`sys.platlibdir`. + +.. + +.. bpo: 44859 +.. date: 2021-08-07-17-28-56 +.. nonce: CCopjk +.. section: Library + +Improve error handling in :mod:`sqlite3` and raise more accurate exceptions. + +* :exc:`MemoryError` is now raised instead of :exc:`sqlite3.Warning` when memory is not enough for encoding a statement to UTF-8 in ``Connection.__call__()`` and ``Cursor.execute()``. +* :exc:`UnicodEncodeError` is now raised instead of :exc:`sqlite3.Warning` when the statement contains surrogate characters in ``Connection.__call__()`` and ``Cursor.execute()``. +* :exc:`TypeError` is now raised instead of :exc:`ValueError` for non-string script argument in ``Cursor.executescript()``. +* :exc:`ValueError` is now raised for script containing the null character instead of truncating it in ``Cursor.executescript()``. +* Correctly handle exceptions raised when getting boolean value of the result of the progress handler. +* Add many tests covering different corner cases. + +.. + +.. bpo: 44581 +.. date: 2021-08-06-19-15-52 +.. nonce: oFDBTB +.. section: Library + +Upgrade bundled pip to 21.2.3 and setuptools to 57.4.0 + +.. + +.. bpo: 44849 +.. date: 2021-08-06-13-00-28 +.. nonce: O78F_f +.. section: Library + +Fix the :func:`os.set_inheritable` function on FreeBSD 14 for file +descriptor opened with the :const:`~os.O_PATH` flag: ignore the +:const:`~errno.EBADF` error on ``ioctl()``, fallback on the ``fcntl()`` +implementation. Patch by Victor Stinner. + +.. + +.. bpo: 44605 +.. date: 2021-08-06-09-43-50 +.. nonce: q4YSBZ +.. section: Library + +The @functools.total_ordering() decorator now works with metaclasses. + +.. + +.. bpo: 44524 +.. date: 2021-08-05-18-20-17 +.. nonce: 9T1tfe +.. section: Library + +Fixed an issue wherein the ``__name__`` and ``__qualname__`` attributes of +subscribed specialforms could be ``None``. + +.. + +.. bpo: 44839 +.. date: 2021-08-05-14-59-39 +.. nonce: MURNL9 +.. section: Library + +:class:`MemoryError` raised in user-defined functions will now produce a +``MemoryError`` in :mod:`sqlite3`. :class:`OverflowError` will now be +converted to :class:`~sqlite3.DataError`. Previously +:class:`~sqlite3.OperationalError` was produced in these cases. + +.. + +.. bpo: 44822 +.. date: 2021-08-04-12-29-00 +.. nonce: zePNXA +.. section: Library + +:mod:`sqlite3` user-defined functions and aggregators returning +:class:`strings <str>` with embedded NUL characters are no longer truncated. +Patch by Erlend E. Aasland. + +.. + +.. bpo: 44801 +.. date: 2021-08-03-20-37-45 +.. nonce: i49Aug +.. section: Library + +Ensure that the :class:`~typing.ParamSpec` variable in Callable can only be +substituted with a parameters expression (a list of types, an ellipsis, +ParamSpec or Concatenate). + +.. + +.. bpo: 44806 +.. date: 2021-08-02-14-37-32 +.. nonce: wOW_Qn +.. section: Library + +Non-protocol subclasses of :class:`typing.Protocol` ignore now the +``__init__`` method inherited from protocol base classes. + +.. + +.. bpo: 27275 +.. date: 2021-08-01-19-49-09 +.. nonce: QsvE0k +.. section: Library + +:meth:`collections.OrderedDict.popitem` and +:meth:`collections.OrderedDict.pop` no longer call ``__getitem__`` and +``__delitem__`` methods of the OrderedDict subclasses. + +.. + +.. bpo: 44793 +.. date: 2021-07-31-20-28-20 +.. nonce: woaQSg +.. section: Library + +Fix checking the number of arguments when subscribe a generic type with +``ParamSpec`` parameter. + +.. + +.. bpo: 44784 +.. date: 2021-07-31-08-45-31 +.. nonce: fIMIDS +.. section: Library + +In importlib.metadata tests, override warnings behavior under expected +DeprecationWarnings (importlib_metadata 4.6.3). + +.. + +.. bpo: 44667 +.. date: 2021-07-30-23-27-30 +.. nonce: tu0Xrv +.. section: Library + +The :func:`tokenize.tokenize` doesn't incorrectly generate a ``NEWLINE`` +token if the source doesn't end with a new line character but the last line +is a comment, as the function is already generating a ``NL`` token. Patch by +Pablo Galindo + +.. + +.. bpo: 44771 +.. date: 2021-07-28-22-53-18 +.. nonce: BvLdnU +.. section: Library + +Added ``importlib.simple`` module implementing adapters from a low-level +resources reader interface to a ``TraversableResources`` interface. Legacy +API (``path``, ``contents``, ...) is now supported entirely by the +``.files()`` API with a compatibility shim supplied for resource loaders +without that functionality. Feature parity with ``importlib_resources`` 5.2. + +.. + +.. bpo: 44752 +.. date: 2021-07-27-22-11-29 +.. nonce: _bvbrZ +.. section: Library + +:mod:`rcompleter` does not call :func:`getattr` on :class:`property` objects +to avoid the side-effect of evaluating the corresponding method. + +.. + +.. bpo: 44747 +.. date: 2021-07-27-12-06-19 +.. nonce: epUzZz +.. section: Library + +Refactor usage of ``sys._getframe`` in ``typing`` module. Patch provided by +Yurii Karabas. + +.. + +.. bpo: 42378 +.. date: 2021-07-25-08-17-55 +.. nonce: WIhUZK +.. section: Library + +Fixes the issue with log file being overwritten when +:class:`logging.FileHandler` is used in :mod:`atexit` with *filemode* set to +``'w'``. Note this will cause the message in *atexit* not being logged if +the log stream is already closed due to shutdown of logging. + +.. + +.. bpo: 44720 +.. date: 2021-07-24-02-17-59 +.. nonce: shU5Qm +.. section: Library + +``weakref.proxy`` objects referencing non-iterators now raise ``TypeError`` +rather than dereferencing the null ``tp_iternext`` slot and crashing. + +.. + +.. bpo: 44704 +.. date: 2021-07-21-23-16-30 +.. nonce: iqHLxQ +.. section: Library + +The implementation of ``collections.abc.Set._hash()`` now matches that of +``frozenset.__hash__()``. + +.. + +.. bpo: 44666 +.. date: 2021-07-21-10-43-22 +.. nonce: CEThkv +.. section: Library + +Fixed issue in :func:`compileall.compile_file` when ``sys.stdout`` is +redirected. Patch by Stefan Hölzl. + +.. + +.. bpo: 44688 +.. date: 2021-07-20-23-28-26 +.. nonce: buFgz3 +.. section: Library + +:meth:`sqlite3.Connection.create_collation` now accepts non-ASCII collation +names. Patch by Erlend E. Aasland. + +.. + +.. bpo: 44690 +.. date: 2021-07-20-22-03-24 +.. nonce: tV7Zjg +.. section: Library + +Adopt *binacii.a2b_base64*'s strict mode in *base64.b64decode*. + +.. + +.. bpo: 42854 +.. date: 2021-07-20-21-51-35 +.. nonce: ThuDMI +.. section: Library + +Fixed a bug in the :mod:`_ssl` module that was throwing :exc:`OverflowError` +when using :meth:`_ssl._SSLSocket.write` and :meth:`_ssl._SSLSocket.read` +for a big value of the ``len`` parameter. Patch by Pablo Galindo + +.. + +.. bpo: 44686 +.. date: 2021-07-20-19-35-49 +.. nonce: ucCGhu +.. section: Library + +Replace ``unittest.mock._importer`` with ``pkgutil.resolve_name``. + +.. + +.. bpo: 44353 +.. date: 2021-07-20-18-34-16 +.. nonce: ATuYq4 +.. section: Library + +Make ``NewType.__call__`` faster by implementing it in C. Patch provided by +Yurii Karabas. + +.. + +.. bpo: 44682 +.. date: 2021-07-20-00-11-47 +.. nonce: 3m2qVV +.. section: Library + +Change the :mod:`pdb` *commands* directive to disallow setting commands for +an invalid breakpoint and to display an appropriate error. + +.. + +.. bpo: 44353 +.. date: 2021-07-19-22-43-15 +.. nonce: HF81_Q +.. section: Library + +Refactor ``typing.NewType`` from function into callable class. Patch +provided by Yurii Karabas. + +.. + +.. bpo: 44678 +.. date: 2021-07-19-18-45-00 +.. nonce: YMEAu0 +.. section: Library + +Added a separate error message for discontinuous padding in +*binascii.a2b_base64* strict mode. + +.. + +.. bpo: 44524 +.. date: 2021-07-19-14-04-42 +.. nonce: Nbf2JC +.. section: Library + +Add missing ``__name__`` and ``__qualname__`` attributes to ``typing`` +module classes. Patch provided by Yurii Karabas. + +.. + +.. bpo: 40897 +.. date: 2021-07-16-13-40-31 +.. nonce: aveAre +.. section: Library + +Give priority to using the current class constructor in +:func:`inspect.signature`. Patch by Weipeng Hong. + +.. + +.. bpo: 44638 +.. date: 2021-07-16-08-57-27 +.. nonce: EwYKne +.. section: Library + +Add a reference to the zipp project and hint as to how to use it. + +.. + +.. bpo: 44648 +.. date: 2021-07-15-16-51-32 +.. nonce: 2o49TB +.. section: Library + +Fixed wrong error being thrown by :func:`inspect.getsource` when examining a +class in the interactive session. Instead of :exc:`TypeError`, it should be +:exc:`OSError` with appropriate error message. + +.. + +.. bpo: 44608 +.. date: 2021-07-13-09-01-33 +.. nonce: R3IcM1 +.. section: Library + +Fix memory leak in :func:`_tkinter._flatten` if it is called with a sequence +or set, but not list or tuple. + +.. + +.. bpo: 44594 +.. date: 2021-07-12-10-32-48 +.. nonce: eEa5zi +.. section: Library + +Fix an edge case of :class:`ExitStack` and :class:`AsyncExitStack` exception +chaining. They will now match ``with`` block behavior when ``__context__`` +is explicitly set to ``None`` when the exception is in flight. + +.. + +.. bpo: 42799 +.. date: 2021-07-10-19-55-13 +.. nonce: ad4tq8 +.. section: Library + +In :mod:`fnmatch`, the cache size for compiled regex patterns +(:func:`functools.lru_cache`) was bumped up from 256 to 32768, affecting +functions: :func:`fnmatch.fnmatch`, :func:`fnmatch.fnmatchcase`, +:func:`fnmatch.filter`. + +.. + +.. bpo: 41928 +.. date: 2021-07-09-07-14-37 +.. nonce: Q1jMrr +.. section: Library + +Update :func:`shutil.copyfile` to raise :exc:`FileNotFoundError` instead of +confusing :exc:`IsADirectoryError` when a path ending with a +:const:`os.path.sep` does not exist; :func:`shutil.copy` and +:func:`shutil.copy2` are also affected. + +.. + +.. bpo: 44569 +.. date: 2021-07-08-12-22-54 +.. nonce: KZ02v9 +.. section: Library + +Added the :func:`StackSummary.format_frame` function in :mod:`traceback`. +This allows users to customize the way individual lines are formatted in +tracebacks without re-implementing logic to handle recursive tracebacks. + +.. + +.. bpo: 44566 +.. date: 2021-07-05-18-13-25 +.. nonce: o51Bd1 +.. section: Library + +handle StopIteration subclass raised from @contextlib.contextmanager +generator + +.. + +.. bpo: 44558 +.. date: 2021-07-04-21-16-53 +.. nonce: cm7Slv +.. section: Library + +Make the implementation consistency of :func:`~operator.indexOf` between C +and Python versions. Patch by Donghee Na. + +.. + +.. bpo: 41249 +.. date: 2021-07-04-11-33-34 +.. nonce: sHdwBE +.. section: Library + +Fixes ``TypedDict`` to work with ``typing.get_type_hints()`` and postponed +evaluation of annotations across modules. + +.. + +.. bpo: 44554 +.. date: 2021-07-02-18-17-56 +.. nonce: aBUmJo +.. section: Library + +Refactor argument processing in :func:`pdb.main` to simplify detection of +errors in input loading and clarify behavior around module or script +invocation. + +.. + +.. bpo: 34798 +.. date: 2021-06-30-13-29-49 +.. nonce: t7FCa0 +.. section: Library + +Break up paragraph about :class:`pprint.PrettyPrinter` construction +parameters to make it easier to read. + +.. + +.. bpo: 44539 +.. date: 2021-06-30-11-34-35 +.. nonce: nP0Xi4 +.. section: Library + +Added support for recognizing JPEG files without JFIF or Exif markers. + +.. + +.. bpo: 44461 +.. date: 2021-06-29-21-17-17 +.. nonce: acqRnV +.. section: Library + +Fix bug with :mod:`pdb`'s handling of import error due to a package which +does not have a ``__main__`` module + +.. + +.. bpo: 43625 +.. date: 2021-06-29-07-27-08 +.. nonce: ZlAxhp +.. section: Library + +Fix a bug in the detection of CSV file headers by +:meth:`csv.Sniffer.has_header` and improve documentation of same. + +.. + +.. bpo: 44516 +.. date: 2021-06-26-12-27-14 +.. nonce: BVyX_y +.. section: Library + +Update vendored pip to 21.1.3 + +.. + +.. bpo: 42892 +.. date: 2021-06-24-19-16-20 +.. nonce: qvRNhI +.. section: Library + +Fixed an exception thrown while parsing a malformed multipart email by +:class:`email.message.EmailMessage`. + +.. + +.. bpo: 44468 +.. date: 2021-06-23-19-02-00 +.. nonce: -klV5- +.. section: Library + +:func:`typing.get_type_hints` now finds annotations in classes and base +classes with unexpected ``__module__``. Previously, it skipped those MRO +elements. + +.. + +.. bpo: 44491 +.. date: 2021-06-23-01-33-01 +.. nonce: tiOlr5 +.. section: Library + +Allow clearing the :mod:`sqlite3` authorizer callback by passing +:const:`None` to :meth:`~sqlite3.Connection.set_authorizer`. Patch by Erlend +E. Aasland. + +.. + +.. bpo: 43977 +.. date: 2021-06-22-16-45-48 +.. nonce: bamAGF +.. section: Library + +Set the proper :c:macro:`Py_TPFLAGS_MAPPING` and :c:macro:`Py_TPFLAGS_SEQUENCE` +flags for subclasses created before a parent has been registered as a +:class:`collections.abc.Mapping` or :class:`collections.abc.Sequence`. + +.. + +.. bpo: 44482 +.. date: 2021-06-22-08-43-04 +.. nonce: U9GznK +.. section: Library + +Fix very unlikely resource leak in :mod:`glob` in alternate Python +implementations. + +.. + +.. bpo: 44466 +.. date: 2021-06-21-12-43-04 +.. nonce: NSm6mv +.. section: Library + +The :mod:`faulthandler` module now detects if a fatal error occurs during a +garbage collector collection. Patch by Victor Stinner. + +.. + +.. bpo: 44471 +.. date: 2021-06-21-10-46-58 +.. nonce: 2QjXv_ +.. section: Library + +A :exc:`TypeError` is now raised instead of an :exc:`AttributeError` in +:meth:`contextlib.ExitStack.enter_context` and +:meth:`contextlib.AsyncExitStack.enter_async_context` for objects which do +not support the :term:`context manager` or :term:`asynchronous context +manager` protocols correspondingly. + +.. + +.. bpo: 44404 +.. date: 2021-06-20-19-01-11 +.. nonce: McfrYB +.. section: Library + +:mod:`tkinter`'s ``after()`` method now supports callables without the +``__name__`` attribute. + +.. + +.. bpo: 41546 +.. date: 2021-06-20-14-03-18 +.. nonce: lO1jXU +.. section: Library + +Make :mod:`pprint` (like the builtin ``print``) not attempt to write to +``stdout`` when it is ``None``. + +.. + +.. bpo: 44458 +.. date: 2021-06-20-07-14-46 +.. nonce: myqCQ0 +.. section: Library + +``BUFFER_BLOCK_SIZE`` is now declared static, to avoid linking collisions +when bz2, lmza or zlib are statically linked. + +.. + +.. bpo: 44464 +.. date: 2021-06-19-21-52-27 +.. nonce: U2oa-a +.. section: Library + +Remove exception for flake8 in deprecated importlib.metadata interfaces. +Sync with importlib_metadata 4.6. + +.. + +.. bpo: 44446 +.. date: 2021-06-17-22-39-34 +.. nonce: qwdRic +.. section: Library + +Take into account that ``lineno`` might be ``None`` in +:class:`traceback.FrameSummary`. + +.. + +.. bpo: 44439 +.. date: 2021-06-17-15-01-51 +.. nonce: 1S7QhT +.. section: Library + +Fix in :meth:`bz2.BZ2File.write` / :meth:`lzma.LZMAFile.write` methods, when +the input data is an object that supports the buffer protocol, the file +length may be wrong. + +.. + +.. bpo: 44434 +.. date: 2021-06-16-16-52-14 +.. nonce: SQS4Pg +.. section: Library + +_thread.start_new_thread() no longer calls PyThread_exit_thread() explicitly +at the thread exit, the call was redundant. On Linux with the glibc, +pthread_exit() aborts the whole process if dlopen() fails to open +libgcc_s.so file (ex: EMFILE error). Patch by Victor Stinner. + +.. + +.. bpo: 42972 +.. date: 2021-06-15-13-51-25 +.. nonce: UnyYo1 +.. section: Library + +The _thread.RLock type now fully implement the GC protocol: add a traverse +function and the :c:macro:`Py_TPFLAGS_HAVE_GC` flag. Patch by Victor Stinner. + +.. + +.. bpo: 44422 +.. date: 2021-06-14-23-28-17 +.. nonce: BlWOgv +.. section: Library + +The :func:`threading.enumerate` function now uses a reentrant lock to +prevent a hang on reentrant call. Patch by Victor Stinner. + +.. + +.. bpo: 38291 +.. date: 2021-06-14-14-19-11 +.. nonce: ee4cSX +.. section: Library + +Importing typing.io or typing.re now prints a ``DeprecationWarning``. + +.. + +.. bpo: 37880 +.. date: 2021-06-13-00-16-56 +.. nonce: 5bTrkw +.. section: Library + +argparse actions store_const and append_const each receive a default value +of None when the ``const`` kwarg is not provided. Previously, this raised a +:exc:`TypeError`. + +.. + +.. bpo: 44389 +.. date: 2021-06-12-22-58-20 +.. nonce: WTRnoC +.. section: Library + +Fix deprecation of :data:`ssl.OP_NO_TLSv1_3` + +.. + +.. bpo: 27827 +.. date: 2021-06-12-21-25-35 +.. nonce: TMWh1i +.. section: Library + +:meth:`pathlib.PureWindowsPath.is_reserved` now identifies a greater range +of reserved filenames, including those with trailing spaces or colons. + +.. + +.. bpo: 44395 +.. date: 2021-06-12-10-08-14 +.. nonce: PcW6Sx +.. section: Library + +Fix :meth:`~email.message.MIMEPart.as_string` to pass unixfrom properly. +Patch by Donghee Na. + +.. + +.. bpo: 34266 +.. date: 2021-06-10-21-53-46 +.. nonce: k3fxnm +.. section: Library + +Handle exceptions from parsing the arg of :mod:`pdb`'s run/restart command. + +.. + +.. bpo: 44362 +.. date: 2021-06-10-20-07-32 +.. nonce: oVOMfd +.. section: Library + +Improve :mod:`ssl` module's deprecation messages, error reporting, and +documentation for deprecations. + +.. + +.. bpo: 44342 +.. date: 2021-06-10-15-06-47 +.. nonce: qqkGlj +.. section: Library + +[Enum] Change pickling from by-value to by-name. + +.. + +.. bpo: 44356 +.. date: 2021-06-10-08-35-38 +.. nonce: 6oDFhO +.. section: Library + +[Enum] Allow multiple data-type mixins if they are all the same. + +.. + +.. bpo: 44351 +.. date: 2021-06-10-07-26-12 +.. nonce: rvyf2v +.. section: Library + +Restore back :func:`parse_makefile` in ``distutils.sysconfig`` because it +behaves differently than the similar implementation in :mod:`sysconfig`. + +.. + +.. bpo: 35800 +.. date: 2021-06-09-10-08-32 +.. nonce: 3hmkWw +.. section: Library + +:class:`smtpd.MailmanProxy` is now removed as it is unusable without an +external module, ``mailman``. Patch by Donghee Na. + +.. + +.. bpo: 44357 +.. date: 2021-06-09-08-32-39 +.. nonce: 70Futb +.. section: Library + +Added a function that returns cube root of the given number +:func:`math.cbrt` + +.. + +.. bpo: 44339 +.. date: 2021-06-08-17-47-38 +.. nonce: 9JwMSc +.. section: Library + +Change ``math.pow(±0.0, -math.inf)`` to return ``inf`` instead of raising +``ValueError``. This brings the special-case handling of ``math.pow`` into +compliance with the IEEE 754 standard. + +.. + +.. bpo: 44242 +.. date: 2021-06-07-10-26-14 +.. nonce: MKeMCQ +.. section: Library + +Remove missing flag check from Enum creation and move into a ``verify`` +decorator. + +.. + +.. bpo: 44246 +.. date: 2021-05-31-11-34-56 +.. nonce: yHAkF0 +.. section: Library + +In ``importlib.metadata``, restore compatibility in the result from +``Distribution.entry_points`` (``EntryPoints``) to honor expectations in +older implementations and issuing deprecation warnings for these cases: A. +``EntryPoints`` objects are once again mutable, allowing for ``sort()`` +and other list-based mutation operations. Avoid deprecation warnings by +casting to a mutable sequence (e.g. ``list(dist.entry_points).sort()``). +B. ``EntryPoints`` results once again allow for access by index. To avoid +deprecation warnings, cast the result to a Sequence first (e.g. +``tuple(dist.entry_points)[0]``). + +.. + +.. bpo: 44246 +.. date: 2021-05-31-11-28-03 +.. nonce: nhmt-v +.. section: Library + +In importlib.metadata.entry_points, de-duplication of distributions no +longer requires loading the full metadata for PathDistribution objects, +improving entry point loading performance by ~10x. + +.. + +.. bpo: 43858 +.. date: 2021-05-31-04-51-02 +.. nonce: r7LOu6 +.. section: Library + +Added a function that returns a copy of a dict of logging levels: +:func:`logging.getLevelNamesMapping` + +.. + +.. bpo: 44260 +.. date: 2021-05-30-13-32-09 +.. nonce: ROEbVd +.. section: Library + +The :class:`random.Random` constructor no longer reads system entropy +without need. + +.. + +.. bpo: 44254 +.. date: 2021-05-29-01-05-43 +.. nonce: f06xDm +.. section: Library + +On Mac, give turtledemo button text a color that works on both light or dark +background. Programmers cannot control the latter. + +.. + +.. bpo: 44258 +.. date: 2021-05-28-09-43-33 +.. nonce: nh5F7R +.. section: Library + +Support PEP 515 for Fraction's initialization from string. + +.. + +.. bpo: 44235 +.. date: 2021-05-26-22-04-40 +.. nonce: qFBYpp +.. section: Library + +Remove deprecated functions in the :mod:`gettext`. Patch by Donghee Na. + +.. + +.. bpo: 38693 +.. date: 2021-05-26-14-50-06 +.. nonce: NkMacJ +.. section: Library + +Prefer f-strings to ``.format`` in importlib.resources. + +.. + +.. bpo: 33693 +.. date: 2021-05-26-13-34-37 +.. nonce: 3okzdo +.. section: Library + +Importlib.metadata now prefers f-strings to .format. + +.. + +.. bpo: 44241 +.. date: 2021-05-26-13-15-51 +.. nonce: TBqej8 +.. section: Library + +Incorporate minor tweaks from importlib_metadata 4.1: SimplePath protocol, +support for Metadata 2.2. + +.. + +.. bpo: 43216 +.. date: 2021-05-25-23-26-38 +.. nonce: xTUyyX +.. section: Library + +Remove the :func:`@asyncio.coroutine <asyncio.coroutine>` :term:`decorator` +enabling legacy generator-based coroutines to be compatible with async/await +code; remove :class:`asyncio.coroutines.CoroWrapper` used for wrapping +legacy coroutine objects in the debug mode. The decorator has been +deprecated since Python 3.8 and the removal was initially scheduled for +Python 3.10. Patch by Illia Volochii. + +.. + +.. bpo: 44210 +.. date: 2021-05-21-21-23-43 +.. nonce: 5afQ3K +.. section: Library + +Make importlib.metadata._meta.PackageMetadata public. + +.. + +.. bpo: 43643 +.. date: 2021-05-21-12-12-35 +.. nonce: GWnmcF +.. section: Library + +Declare readers.MultiplexedPath.name as a property per the spec. + +.. + +.. bpo: 27334 +.. date: 2021-05-18-00-17-21 +.. nonce: 32EJZi +.. section: Library + +The :mod:`sqlite3` context manager now performs a rollback (thus releasing +the database lock) if commit failed. Patch by Luca Citi and Erlend E. +Aasland. + +.. + +.. bpo: 4928 +.. date: 2021-05-17-21-05-06 +.. nonce: Ot2yjO +.. section: Library + +Documented existing behavior on POSIX: NamedTemporaryFiles are not deleted +when creating process is killed with SIGKILL + +.. + +.. bpo: 44154 +.. date: 2021-05-17-07-24-24 +.. nonce: GRI5bf +.. section: Library + +Optimize :class:`fractions.Fraction` pickling for large components. + +.. + +.. bpo: 33433 +.. date: 2021-05-16-17-48-24 +.. nonce: MyzO71 +.. section: Library + +For IPv4 mapped IPv6 addresses (:rfc:`4291` Section 2.5.5.2), the +:mod:`ipaddress.IPv6Address.is_private` check is deferred to the mapped IPv4 +address. This solves a bug where public mapped IPv4 addresses were +considered private by the IPv6 check. + +.. + +.. bpo: 44150 +.. date: 2021-05-16-11-57-38 +.. nonce: xAhhik +.. section: Library + +Add optional *weights* argument to statistics.fmean(). + +.. + +.. bpo: 44142 +.. date: 2021-05-16-02-24-23 +.. nonce: t-XU8k +.. section: Library + +:func:`ast.unparse` will now drop the redundant parentheses when tuples used +as assignment targets (e.g in for loops). + +.. + +.. bpo: 44145 +.. date: 2021-05-16-00-00-38 +.. nonce: ko5SJ7 +.. section: Library + +:mod:`hmac` computations were not releasing the GIL while calling the +OpenSSL ``HMAC_Update`` C API (a new feature in 3.9). This unintentionally +prevented parallel computation as other :mod:`hashlib` algorithms support. + +.. + +.. bpo: 44095 +.. date: 2021-05-14-16-06-02 +.. nonce: v_pLwY +.. section: Library + +:class:`zipfile.Path` now supports :attr:`zipfile.Path.stem`, +:attr:`zipfile.Path.suffixes`, and :attr:`zipfile.Path.suffix` attributes. + +.. + +.. bpo: 44077 +.. date: 2021-05-13-19-44-38 +.. nonce: 04b2a4 +.. section: Library + +It's now possible to receive the type of service (ToS), a.k.a. +differentiated services (DS), a.k.a. differentiated services code point +(DSCP) and explicit congestion notification (ECN) IP header fields with +``socket.IP_RECVTOS``. + +.. + +.. bpo: 37788 +.. date: 2021-05-13-19-07-28 +.. nonce: adeFcf +.. section: Library + +Fix a reference leak when a Thread object is never joined. + +.. + +.. bpo: 38908 +.. date: 2021-05-12-16-43-21 +.. nonce: nM2_rO +.. section: Library + +Subclasses of ``typing.Protocol`` which only have data variables declared +will now raise a ``TypeError`` when checked with ``isinstance`` unless they +are decorated with :func:`runtime_checkable`. Previously, these checks +passed silently. Patch provided by Yurii Karabas. + +.. + +.. bpo: 44098 +.. date: 2021-05-10-17-45-00 +.. nonce: _MoxuZ +.. section: Library + +``typing.ParamSpec`` will no longer be found in the ``__parameters__`` of +most :mod:`typing` generics except in valid use locations specified by +:pep:`612`. This prevents incorrect usage like ``typing.List[P][int]``. This +change means incorrect usage which may have passed silently in 3.10 beta 1 +and earlier will now error. + +.. + +.. bpo: 44089 +.. date: 2021-05-09-22-52-34 +.. nonce: IoANsN +.. section: Library + +Allow subclassing ``csv.Error`` in 3.10 (it was allowed in 3.9 and earlier +but was disallowed in early versions of 3.10). + +.. + +.. bpo: 44081 +.. date: 2021-05-09-03-26-31 +.. nonce: A-Mrto +.. section: Library + +:func:`ast.unparse` now doesn't use redundant spaces to separate ``lambda`` +and the ``:`` if there are no parameters. + +.. + +.. bpo: 44061 +.. date: 2021-05-07-08-39-23 +.. nonce: MvElG6 +.. section: Library + +Fix regression in previous release when calling :func:`pkgutil.iter_modules` +with a list of :class:`pathlib.Path` objects + +.. + +.. bpo: 44059 +.. date: 2021-05-06-16-01-55 +.. nonce: GF5r6O +.. section: Library + +Register the SerenityOS Browser in the :mod:`webbrowser` module. + +.. + +.. bpo: 36515 +.. date: 2021-05-05-11-44-49 +.. nonce: uOSa3q +.. section: Library + +The :mod:`hashlib` module no longer does unaligned memory accesses when +compiled for ARM platforms. + +.. + +.. bpo: 40465 +.. date: 2021-05-03-19-59-14 +.. nonce: 1tB4Y0 +.. section: Library + +Remove random module features deprecated in Python 3.9. + +.. + +.. bpo: 44018 +.. date: 2021-05-03-10-07-43 +.. nonce: VDyW8f +.. section: Library + +random.seed() no longer mutates bytearray inputs. + +.. + +.. bpo: 38352 +.. date: 2021-05-02-13-54-25 +.. nonce: N9MlhV +.. section: Library + +Add ``IO``, ``BinaryIO``, ``TextIO``, ``Match``, and ``Pattern`` to +``typing.__all__``. Patch by Jelle Zijlstra. + +.. + +.. bpo: 44002 +.. date: 2021-05-01-15-43-37 +.. nonce: KLT_wd +.. section: Library + +:mod:`urllib.parse` now uses :func:`functool.lru_cache` for its internal URL +splitting and quoting caches instead of rolling its own like its the '90s. + +The undocumented internal :mod:`urllib.parse` ``Quoted`` class API is now +deprecated, for removal in 3.14. + +.. + +.. bpo: 43972 +.. date: 2021-04-30-16-58-24 +.. nonce: Y2r9lg +.. section: Library + +When :class:`http.server.SimpleHTTPRequestHandler` sends a ``301 (Moved +Permanently)`` for a directory path not ending with `/`, add a +``Content-Length: 0`` header. This improves the behavior for certain +clients. + +.. + +.. bpo: 28528 +.. date: 2021-04-29-00-48-00 +.. nonce: JLAVWj +.. section: Library + +Fix a bug in :mod:`pdb` where :meth:`~pdb.Pdb.checkline` raises +:exc:`AttributeError` if it is called after :meth:`~pdb.Pdb.reset`. + +.. + +.. bpo: 43853 +.. date: 2021-04-15-12-02-17 +.. nonce: XXCVAp +.. section: Library + +Improved string handling for :mod:`sqlite3` user-defined functions and +aggregates: + +* It is now possible to pass strings with embedded null characters to UDFs +* Conversion failures now correctly raise :exc:`MemoryError` + +Patch by Erlend E. Aasland. + +.. + +.. bpo: 43666 +.. date: 2021-03-30-08-39-08 +.. nonce: m72tlH +.. section: Library + +AIX: `Lib/_aix_support.get_platform()` may fail in an AIX WPAR. The fileset +bos.rte appears to have a builddate in both LPAR and WPAR so this fileset is +queried rather than bos.mp64. To prevent a similar situation (no builddate +in ODM) a value (9988) sufficient for completing a build is provided. Patch +by M Felt. + +.. + +.. bpo: 43650 +.. date: 2021-03-29-00-23-30 +.. nonce: v01tic +.. section: Library + +Fix :exc:`MemoryError` in :func:`shutil.unpack_archive` which fails inside +:func:`shutil._unpack_zipfile` on large files. Patch by Igor Bolshakov. + +.. + +.. bpo: 43612 +.. date: 2021-03-24-09-40-02 +.. nonce: vMGZ4y +.. section: Library + +:func:`zlib.compress` now accepts a wbits parameter which allows users to +compress data as a raw deflate block without zlib headers and trailers in +one go. Previously this required instantiating a ``zlib.compressobj``. It +also provides a faster alternative to ``gzip.compress`` when wbits=31 is +used. + +.. + +.. bpo: 43392 +.. date: 2021-03-03-13-32-37 +.. nonce: QQumou +.. section: Library + +:func:`importlib._bootstrap._find_and_load` now implements a two-step check +to avoid locking when modules have been already imported and are ready. This +improves performance of repeated calls to :func:`importlib.import_module` +and :func:`importlib.__import__`. + +.. + +.. bpo: 43318 +.. date: 2021-02-25-08-32-06 +.. nonce: bZJw6V +.. section: Library + +Fix a bug where :mod:`pdb` does not always echo cleared breakpoints. + +.. + +.. bpo: 43234 +.. date: 2021-02-15-22-14-31 +.. nonce: F-vKAT +.. section: Library + +Prohibit passing non-:class:`concurrent.futures.ThreadPoolExecutor` +executors to :meth:`loop.set_default_executor` following a deprecation in +Python 3.8. Patch by Illia Volochii. + +.. + +.. bpo: 43232 +.. date: 2021-02-15-21-17-46 +.. nonce: awc4yZ +.. section: Library + +Prohibit previously deprecated potentially disruptive operations on +:class:`asyncio.trsock.TransportSocket`. Patch by Illia Volochii. + +.. + +.. bpo: 30077 +.. date: 2021-02-04-23-16-03 +.. nonce: v6TqAi +.. section: Library + +Added support for Apple's aifc/sowt pseudo-compression + +.. + +.. bpo: 42971 +.. date: 2021-02-02-20-11-14 +.. nonce: OpVoFu +.. section: Library + +Add definition of ``errno.EQFULL`` for platforms that define this constant +(such as macOS). + +.. + +.. bpo: 43086 +.. date: 2021-01-31-18-24-54 +.. nonce: 2_P-SH +.. section: Library + +Added a new optional :code:`strict_mode` parameter to *binascii.a2b_base64*. +When :code:`scrict_mode` is set to :code:`True`, the *a2b_base64* function +will accept only valid base64 content. More details about what "valid base64 +content" is, can be found in the function's documentation. + +.. + +.. bpo: 43024 +.. date: 2021-01-25-21-24-55 +.. nonce: vAUrIi +.. section: Library + +Improve the help signature of :func:`traceback.print_exception`, +:func:`traceback.format_exception` and +:func:`traceback.format_exception_only`. + +.. + +.. bpo: 33809 +.. date: 2021-01-16-18-36-00 +.. nonce: BiMK6V +.. section: Library + +Add the :meth:`traceback.TracebackException.print` method which prints the +formatted exception information. + +.. + +.. bpo: 42862 +.. date: 2021-01-13-00-02-44 +.. nonce: Z6ACLN +.. section: Library + +:mod:`sqlite3` now utilizes :meth:`functools.lru_cache` to implement the +connection statement cache. As a small optimisation, the default statement +cache size has been increased from 100 to 128. Patch by Erlend E. Aasland. + +.. + +.. bpo: 41818 +.. date: 2020-12-08-01-08-58 +.. nonce: zO8vV7 +.. section: Library + +Soumendra Ganguly: add termios.tcgetwinsize(), termios.tcsetwinsize(). + +.. + +.. bpo: 40497 +.. date: 2020-10-18-09-42-53 +.. nonce: CRz2sG +.. section: Library + +:meth:`subprocess.check_output` now raises :exc:`ValueError` when the +invalid keyword argument *check* is passed by user code. Previously such use +would fail later with a :exc:`TypeError`. Patch by Rémi Lapeyre. + +.. + +.. bpo: 37449 +.. date: 2020-10-11-20-23-48 +.. nonce: f-t3V6 +.. section: Library + +``ensurepip`` now uses ``importlib.resources.files()`` traversable APIs + +.. + +.. bpo: 40956 +.. date: 2020-10-01-21-46-34 +.. nonce: _tvsZ7 +.. section: Library + +Use Argument Clinic in :mod:`sqlite3`. Patches by Erlend E. Aasland. + +.. + +.. bpo: 41730 +.. date: 2020-09-10-07-23-24 +.. nonce: DyKFi9 +.. section: Library + +``DeprecationWarning`` is now raised when importing :mod:`tkinter.tix`, +which has been deprecated in documentation since Python 3.6. + +.. + +.. bpo: 20684 +.. date: 2020-07-30-14-37-15 +.. nonce: qV35GU +.. section: Library + +Remove unused ``_signature_get_bound_param`` function from :mod:`inspect` - +by Anthony Sottile. + +.. + +.. bpo: 41402 +.. date: 2020-07-26-18-17-30 +.. nonce: YRkVkp +.. section: Library + +Fix :meth:`email.message.EmailMessage.set_content` when called with binary +data and ``7bit`` content transfer encoding. + +.. + +.. bpo: 32695 +.. date: 2020-07-13-23-46-59 +.. nonce: tTqqXe +.. section: Library + +The *compresslevel* and *preset* keyword arguments of :func:`tarfile.open` +are now both documented and tested. + +.. + +.. bpo: 41137 +.. date: 2020-07-01-17-42-41 +.. nonce: AnqbP- +.. section: Library + +Use utf-8 encoding while reading .pdbrc files. Patch by Srinivas Reddy +Thatiparthy + +.. + +.. bpo: 24391 +.. date: 2020-05-30-10-48-04 +.. nonce: ZCTnhX +.. section: Library + +Improved reprs of :mod:`threading` synchronization objects: +:class:`~threading.Semaphore`, :class:`~threading.BoundedSemaphore`, +:class:`~threading.Event` and :class:`~threading.Barrier`. + +.. + +.. bpo: 5846 +.. date: 2020-05-25-23-58-29 +.. nonce: O9BIfm +.. section: Library + +Deprecated the following :mod:`unittest` functions, scheduled for removal in +Python 3.13: + +* :func:`~unittest.findTestCases` +* :func:`~unittest.makeSuite` +* :func:`~unittest.getTestCaseNames` + +Use :class:`~unittest.TestLoader` methods instead: + +* :meth:`unittest.TestLoader.loadTestsFromModule` +* :meth:`unittest.TestLoader.loadTestsFromTestCase` +* :meth:`unittest.TestLoader.getTestCaseNames` + +Patch by Erlend E. Aasland. + +.. + +.. bpo: 40563 +.. date: 2020-05-21-01-42-32 +.. nonce: fDn5bP +.. section: Library + +Support pathlike objects on dbm/shelve. Patch by Hakan Çelik and +Henry-Joseph Audéoud. + +.. + +.. bpo: 34990 +.. date: 2020-04-24-20-39-38 +.. nonce: 3SmL9M +.. section: Library + +Fixed a Y2k38 bug in the compileall module where it would fail to compile +files with a modification time after the year 2038. + +.. + +.. bpo: 39549 +.. date: 2020-02-03-21-18-31 +.. nonce: l4a8uH +.. section: Library + +Whereas the code for reprlib.Repr had previously used a hardcoded string +value of '...', this PR updates it to use of a “fillvalue” attribute, whose +value defaults to '...' and can be reset in either individual reprlib.Repr +instances or in subclasses thereof. + +.. + +.. bpo: 37022 +.. date: 2020-01-25-12-58-20 +.. nonce: FUZI25 +.. section: Library + +:mod:`pdb` now displays exceptions from ``repr()`` with its ``p`` and ``pp`` +commands. + +.. + +.. bpo: 38840 +.. date: 2020-01-16-23-41-16 +.. nonce: VzzYZz +.. section: Library + +Fix ``test___all__`` on platforms lacking a shared memory implementation. + +.. + +.. bpo: 39359 +.. date: 2020-01-16-13-54-28 +.. nonce: hzTu0h +.. section: Library + +Add one missing check that the password is a bytes object for an encrypted +zipfile. + +.. + +.. bpo: 38741 +.. date: 2019-11-12-18-59-33 +.. nonce: W7IYkq +.. section: Library + +:mod:`configparser`: using ']' inside a section header will no longer cut +the section name short at the ']' + +.. + +.. bpo: 38415 +.. date: 2019-10-08-14-08-59 +.. nonce: N1bUw6 +.. section: Library + +Added missing behavior to :func:`contextlib.asynccontextmanager` to match +:func:`contextlib.contextmanager` so decorated functions can themselves be +decorators. + +.. + +.. bpo: 30256 +.. date: 2019-09-25-13-54-41 +.. nonce: wBkzox +.. section: Library + +Pass multiprocessing BaseProxy argument ``manager_owned`` through AutoProxy. + +.. + +.. bpo: 27513 +.. date: 2019-06-03-23-53-25 +.. nonce: qITN7d +.. section: Library + +:func:`email.utils.getaddresses` now accepts :class:`email.header.Header` +objects along with string values. Patch by Zackery Spytz. + +.. + +.. bpo: 16379 +.. date: 2019-05-08-15-14-32 +.. nonce: rN5JVe +.. section: Library + +Add SQLite error code and name to :mod:`sqlite3` exceptions. Patch by Aviv +Palivoda, Daniel Shahaf, and Erlend E. Aasland. + +.. + +.. bpo: 26228 +.. date: 2019-02-26-09-31-59 +.. nonce: wyrHKc +.. section: Library + +pty.spawn no longer hangs on FreeBSD, macOS, and Solaris. + +.. + +.. bpo: 33349 +.. date: 2018-04-24-14-25-07 +.. nonce: Y_0LIr +.. section: Library + +lib2to3 now recognizes async generators everywhere. + +.. + +.. bpo: 29298 +.. date: 2017-09-20-14-43-03 +.. nonce: _78CSN +.. section: Library + +Fix ``TypeError`` when required subparsers without ``dest`` do not receive +arguments. Patch by Anthony Sottile. + +.. + +.. bpo: 45216 +.. date: 2021-09-18-13-45-19 +.. nonce: o56nyt +.. section: Documentation + +Remove extra documentation listing methods in ``difflib``. It was rendering +twice in pydoc and was outdated in some places. + +.. + +.. bpo: 45024 +.. date: 2021-09-08-17-20-19 +.. nonce: dkNPNi +.. section: Documentation + +:mod:`collections.abc` documentation has been expanded to explicitly cover +how instance and subclass checks work, with additional doctest examples and +an exhaustive list of ABCs which test membership purely by presence of the +right :term:`special method`\s. Patch by Raymond Hettinger. + +.. + +.. bpo: 44957 +.. date: 2021-08-19-15-53-08 +.. nonce: imqrh3 +.. section: Documentation + +Promote PEP 604 union syntax by using it where possible. Also, mention ``X | +Y`` more prominently in section about ``Union`` and mention ``X | None`` at +all in section about ``Optional``. + +.. + +.. bpo: 16580 +.. date: 2021-08-13-20-17-59 +.. nonce: MZ_iK9 +.. section: Documentation + +Added code equivalents for the :meth:`int.to_bytes` and +:meth:`int.from_bytes` methods, as well as tests ensuring that these code +equivalents are valid. + +.. + +.. bpo: 44903 +.. date: 2021-08-13-19-08-03 +.. nonce: aJuvQF +.. section: Documentation + +Removed the othergui.rst file, any references to it, and the list of GUI +frameworks in the FAQ. In their place I've added links to the Python Wiki +`page on GUI frameworks <https://wiki.python.org/moin/GuiProgramming>`. + +.. + +.. bpo: 33479 +.. date: 2021-08-11-18-02-06 +.. nonce: rCe4c5 +.. section: Documentation + +Tkinter documentation has been greatly expanded with new "Architecture" and +"Threading model" sections. + +.. + +.. bpo: 36700 +.. date: 2021-08-09-19-58-45 +.. nonce: WPNW5f +.. section: Documentation + +:mod:`base64` RFC references were updated to point to :rfc:`4648`; a section +was added to point users to the new "security considerations" section of the +RFC. + +.. + +.. bpo: 44740 +.. date: 2021-07-26-23-48-31 +.. nonce: zMFGMV +.. section: Documentation + +Replaced occurrences of uppercase "Web" and "Internet" with lowercase +versions per the 2016 revised Associated Press Style Book. + +.. + +.. bpo: 44693 +.. date: 2021-07-25-23-04-15 +.. nonce: JuCbNq +.. section: Documentation + +Update the definition of __future__ in the glossary by replacing the +confusing word "pseudo-module" with a more accurate description. + +.. + +.. bpo: 35183 +.. date: 2021-07-22-08-28-03 +.. nonce: p9BWTB +.. section: Documentation + +Add typical examples to os.path.splitext docs + +.. + +.. bpo: 30511 +.. date: 2021-07-20-21-03-18 +.. nonce: eMFkRi +.. section: Documentation + +Clarify that :func:`shutil.make_archive` is not thread-safe due to reliance +on changing the current working directory. + +.. + +.. bpo: 44561 +.. date: 2021-07-18-22-43-14 +.. nonce: T7HpWm +.. section: Documentation + +Update of three expired hyperlinks in Doc/distributing/index.rst: "Project +structure", "Building and packaging the project", and "Uploading the project +to the Python Packaging Index". + +.. + +.. bpo: 44651 +.. date: 2021-07-18-22-26-02 +.. nonce: SjT9iY +.. section: Documentation + +Delete entry "coercion" in Doc/glossary.rst for its outdated definition. + +.. + +.. bpo: 42958 +.. date: 2021-07-15-11-19-03 +.. nonce: gC5IHM +.. section: Documentation + +Updated the docstring and docs of :func:`filecmp.cmp` to be more accurate +and less confusing especially in respect to *shallow* arg. + +.. + +.. bpo: 44631 +.. date: 2021-07-13-22-25-13 +.. nonce: qkGwe4 +.. section: Documentation + +Refactored the ``repr()`` code of the ``_Environ`` (os module). + +.. + +.. bpo: 44613 +.. date: 2021-07-12-11-39-20 +.. nonce: DIXNzc +.. section: Documentation + +importlib.metadata is no longer provisional. + +.. + +.. bpo: 44558 +.. date: 2021-07-03-18-25-17 +.. nonce: 0pTknl +.. section: Documentation + +Match the docstring and python implementation of :func:`~operator.countOf` +to the behavior of its c implementation. + +.. + +.. bpo: 44544 +.. date: 2021-07-02-14-02-29 +.. nonce: _5_aCz +.. section: Documentation + +List all kwargs for :func:`textwrap.wrap`, :func:`textwrap.fill`, and +:func:`textwrap.shorten`. Now, there are nav links to attributes of +:class:`TextWrap`, which makes navigation much easier while minimizing +duplication in the documentation. + +.. + +.. bpo: 38062 +.. date: 2021-06-28-12-13-48 +.. nonce: 9Ehp9O +.. section: Documentation + +Clarify that atexit uses equality comparisons internally. + +.. + +.. bpo: 40620 +.. date: 2021-06-26-17-41-06 +.. nonce: PAYDrB +.. section: Documentation + +Convert examples in tutorial controlflow.rst section 4.3 to be +interpreter-demo style. + +.. + +.. bpo: 43066 +.. date: 2021-06-24-14-37-16 +.. nonce: Ti7ahX +.. section: Documentation + +Added a warning to :mod:`zipfile` docs: filename arg with a leading slash +may cause archive to be un-openable on Windows systems. + +.. + +.. bpo: 39452 +.. date: 2021-06-23-15-21-36 +.. nonce: o_I-6d +.. section: Documentation + +Rewrote ``Doc/library/__main__.rst``. Broadened scope of the document to +explicitly discuss and differentiate between ``__main__.py`` in packages +versus the ``__name__ == '__main__'`` expression (and the idioms that +surround it). + +.. + +.. bpo: 13814 +.. date: 2021-06-21-15-46-32 +.. nonce: LDcslu +.. section: Documentation + +In the Design FAQ, answer "Why don't generators support the with statement?" + +.. + +.. bpo: 27752 +.. date: 2021-06-18-18-04-53 +.. nonce: NEByNk +.. section: Documentation + +Documentation of csv.Dialect is more descriptive. + +.. + +.. bpo: 44453 +.. date: 2021-06-18-06-44-45 +.. nonce: 3PIkj2 +.. section: Documentation + +Fix documentation for the return type of :func:`sysconfig.get_path`. + +.. + +.. bpo: 44392 +.. date: 2021-06-16-18-09-49 +.. nonce: 6RF1Sc +.. section: Documentation + +Added a new section in the C API documentation for types used in type +hinting. Documented ``Py_GenericAlias`` and ``Py_GenericAliasType``. + +.. + +.. bpo: 38291 +.. date: 2021-06-14-09-20-37 +.. nonce: VMYa_Q +.. section: Documentation + +Mark ``typing.io`` and ``typing.re`` as deprecated since Python 3.8 in the +documentation. They were never properly supported by type checkers. + +.. + +.. bpo: 44322 +.. date: 2021-06-06-14-12-00 +.. nonce: K0PHfE +.. section: Documentation + +Document that SyntaxError args have a details tuple and that details are +adjusted for errors in f-string field replacement expressions. + +.. + +.. bpo: 42392 +.. date: 2021-05-26-11-16-33 +.. nonce: oxRx6E +.. section: Documentation + +Document the deprecation and removal of the ``loop`` parameter for many +functions and classes in :mod:`asyncio`. + +.. + +.. bpo: 44195 +.. date: 2021-05-23-09-11-28 +.. nonce: 1bqkOs +.. section: Documentation + +Corrected references to ``TraversableResources`` in docs. There is no +``TraversableReader``. + +.. + +.. bpo: 41963 +.. date: 2021-05-17-20-03-47 +.. nonce: eUz9_o +.. section: Documentation + +Document that ``ConfigParser`` strips off comments when reading +configuration files. + +.. + +.. bpo: 44072 +.. date: 2021-05-08-09-48-05 +.. nonce: fb2x5I +.. section: Documentation + +Correct where in the numeric ABC hierarchy ``**`` support is added, i.e., in +numbers.Complex, not numbers.Integral. + +.. + +.. bpo: 43558 +.. date: 2021-05-07-12-27-09 +.. nonce: UGhA8R +.. section: Documentation + +Add the remark to :mod:`dataclasses` documentation that the :meth:`__init__` +of any base class has to be called in :meth:`__post_init__`, along with a +code example. + +.. + +.. bpo: 44025 +.. date: 2021-05-03-22-08-08 +.. nonce: gcB7iP +.. section: Documentation + +Clarify when '_' in match statements is a keyword, and when not. + +.. + +.. bpo: 41706 +.. date: 2020-09-03-13-37-19 +.. nonce: _zXWOR +.. section: Documentation + +Fix docs about how methods like ``__add__`` are invoked when evaluating +operator expressions. + +.. + +.. bpo: 41621 +.. date: 2020-08-24-13-35-04 +.. nonce: nqaw9G +.. section: Documentation + +Document that :class:`collections.defaultdict` parameter ``default_factory`` +defaults to None and is positional-only. + +.. + +.. bpo: 41576 +.. date: 2020-08-21-22-59-37 +.. nonce: 7a6CQR +.. section: Documentation + +document BaseException in favor of bare except + +.. + +.. bpo: 21760 +.. date: 2020-03-21-01-19-28 +.. nonce: CqofIc +.. section: Documentation + +The description for __file__ fixed. Patch by Furkan Onder + +.. + +.. bpo: 39498 +.. date: 2020-01-30-05-18-48 +.. nonce: Nu3sFL +.. section: Documentation + +Add a "Security Considerations" index which links to standard library +modules that have explicitly documented security considerations. + +.. + +.. bpo: 33479 +.. date: 2018-05-19-15-59-29 +.. nonce: 4cLlxo +.. section: Documentation + +Remove the unqualified claim that tkinter is threadsafe. It has not been +true for several years and likely never was. An explanation of what is true +may be added later, after more discussion, and possibly after patching +_tkinter.c, + +.. + +.. bpo: 40173 +.. date: 2021-09-30-16-54-39 +.. nonce: J_slCw +.. section: Tests + +Fix :func:`test.support.import_helper.import_fresh_module`. + +.. + +.. bpo: 45280 +.. date: 2021-09-25-11-05-31 +.. nonce: 3MA6lC +.. section: Tests + +Add a test case for empty :class:`typing.NamedTuple`. + +.. + +.. bpo: 45269 +.. date: 2021-09-24-10-41-49 +.. nonce: 8jKEr8 +.. section: Tests + +Cover case when invalid ``markers`` type is supplied to ``c_make_encoder``. + +.. + +.. bpo: 45128 +.. date: 2021-09-16-17-22-35 +.. nonce: Jz6fl2 +.. section: Tests + +Fix ``test_multiprocessing_fork`` failure due to ``test_logging`` and +``sys.modules`` manipulation. + +.. + +.. bpo: 45209 +.. date: 2021-09-15-23-32-39 +.. nonce: 55ntL5 +.. section: Tests + +Fix ``UserWarning: resource_tracker`` warning in +``_test_multiprocessing._TestSharedMemory.test_shared_memory_cleaned_after_process_termination`` + +.. + +.. bpo: 45185 +.. date: 2021-09-14-14-54-04 +.. nonce: qFx5I6 +.. section: Tests + +Enables ``TestEnumerations`` test cases in ``test_ssl`` suite. + +.. + +.. bpo: 45195 +.. date: 2021-09-14-13-16-18 +.. nonce: EyQR1G +.. section: Tests + +Fix test_readline.test_nonascii(): sometimes, the newline character is not +written at the end, so don't expect it in the output. Patch by Victor +Stinner. + +.. + +.. bpo: 45156 +.. date: 2021-09-13-00-28-17 +.. nonce: 8oomV3 +.. section: Tests + +Fixes infinite loop on :func:`unittest.mock.seal` of mocks created by +:func:`~unittest.create_autospec`. + +.. + +.. bpo: 45125 +.. date: 2021-09-11-22-08-18 +.. nonce: FVSzs2 +.. section: Tests + +Improves pickling tests and docs of ``SharedMemory`` and ``SharableList`` +objects. + +.. + +.. bpo: 44860 +.. date: 2021-09-08-13-01-37 +.. nonce: qXd0kx +.. section: Tests + +Update ``test_sysconfig.test_user_similar()`` for the posix_user scheme: +``platlib`` doesn't use :data:`sys.platlibdir`. Patch by Victor Stinner. + +.. + +.. bpo: 45052 +.. date: 2021-09-06-19-00-29 +.. nonce: yrOK3J +.. section: Tests + +``WithProcessesTestSharedMemory.test_shared_memory_basics`` test was +ignored, because ``self.assertEqual(sms.size, sms2.size)`` line was failing. +It is now removed and test is unskipped. + +The main motivation for this line to be removed from the test is that the +``size`` of ``SharedMemory`` is not ever guaranteed to be the same. It is +decided by the platform. + +.. + +.. bpo: 44895 +.. date: 2021-09-01-17-17-44 +.. nonce: kV7H77 +.. section: Tests + +libregrtest now clears the type cache later to reduce the risk of false +alarm when checking for reference leaks. Previously, the type cache was +cleared too early and libregrtest raised a false alarm about reference leaks +under very specific conditions. Patch by Irit Katriel and Victor Stinner. + +.. + +.. bpo: 45042 +.. date: 2021-08-30-11-54-14 +.. nonce: QMz3X8 +.. section: Tests + +Fixes that test classes decorated with +``@hashlib_helper.requires_hashdigest`` were skipped all the time. + +.. + +.. bpo: 25130 +.. date: 2021-08-27-22-37-19 +.. nonce: ig4oJe +.. section: Tests + +Add calls of :func:`gc.collect` in tests to support PyPy. + +.. + +.. bpo: 45011 +.. date: 2021-08-26-14-20-44 +.. nonce: mQZdXU +.. section: Tests + +Made tests relying on the :mod:`_asyncio` C extension module optional to +allow running on alternative Python implementations. Patch by Serhiy +Storchaka. + +.. + +.. bpo: 44949 +.. date: 2021-08-18-18-30-12 +.. nonce: VE5ENv +.. section: Tests + +Fix auto history tests of test_readline: sometimes, the newline character is +not written at the end, so don't expect it in the output. + +.. + +.. bpo: 44891 +.. date: 2021-08-13-12-11-06 +.. nonce: T9_mBT +.. section: Tests + +Tests were added to clarify :func:`id` is preserved when ``obj * 1`` is used +on :class:`str` and :class:`bytes` objects. Patch by Nikita Sobolev. + +.. + +.. bpo: 44852 +.. date: 2021-08-06-18-36-04 +.. nonce: sUL8YX +.. section: Tests + +Add ability to wholesale silence DeprecationWarnings while running the +regression test suite. + +.. + +.. bpo: 40928 +.. date: 2021-08-06-00-07-15 +.. nonce: aIwb6G +.. section: Tests + +Notify users running test_decimal regression tests on macOS of potential +harmless "malloc can't allocate region" messages spewed by test_decimal. + +.. + +.. bpo: 44734 +.. date: 2021-07-24-20-09-15 +.. nonce: KKsNOV +.. section: Tests + +Fixed floating point precision issue in turtle tests. + +.. + +.. bpo: 44708 +.. date: 2021-07-22-16-38-39 +.. nonce: SYNaac +.. section: Tests + +Regression tests, when run with -w, are now re-running only the affected +test methods instead of re-running the entire test file. + +.. + +.. bpo: 42095 +.. date: 2021-07-17-11-41-20 +.. nonce: kCB7oj +.. section: Tests + +Added interop tests for Apple plists: generate plist files with Python +plistlib and parse with Apple plutil; and the other way round. + +.. + +.. bpo: 44647 +.. date: 2021-07-16-14-02-33 +.. nonce: 5LzqIy +.. section: Tests + +Added a permanent Unicode-valued environment variable to regression tests to +ensure they handle this use case in the future. If your test environment +breaks because of that, report a bug to us, and temporarily set +PYTHONREGRTEST_UNICODE_GUARD=0 in your test environment. + +.. + +.. bpo: 44515 +.. date: 2021-06-26-18-37-36 +.. nonce: e9fO6f +.. section: Tests + +Adjust recently added contextlib tests to avoid assuming the use of a +refcounted GC + +.. + +.. bpo: 44287 +.. date: 2021-06-21-17-53-41 +.. nonce: YON57s +.. section: Tests + +Fix asyncio test_popen() of test_windows_utils by using a longer timeout. +Use military grade battle-tested :data:`test.support.SHORT_TIMEOUT` timeout +rather than a hardcoded timeout of 10 seconds: it's 30 seconds by default, +but it is made longer on slow buildbots. Patch by Victor Stinner. + +.. + +.. bpo: 44451 +.. date: 2021-06-18-15-19-35 +.. nonce: aj5pqE +.. section: Tests + +Reset ``DeprecationWarning`` filters in +``test.test_importlib.test_metadata_api.APITests.test_entry_points_by_index`` +to avoid ``StopIteration`` error if ``DeprecationWarnings`` are ignored. + +.. + +.. bpo: 44363 +.. date: 2021-06-10-11-19-43 +.. nonce: -K9jD0 +.. section: Tests + +Account for address sanitizer in test_capi. test_capi now passes when run +GCC address sanitizer. + +.. + +.. bpo: 44364 +.. date: 2021-06-09-15-32-05 +.. nonce: zu9Zee +.. section: Tests + +Add non integral tests for :func:`math.sqrt` function. + +.. + +.. bpo: 43921 +.. date: 2021-06-03-03-29-34 +.. nonce: nwH1FS +.. section: Tests + +Fix test_ssl.test_wrong_cert_tls13(): use ``suppress_ragged_eofs=False``, +since ``read()`` can raise :exc:`ssl.SSLEOFError` on Windows. Patch by +Victor Stinner. + +.. + +.. bpo: 43921 +.. date: 2021-06-02-17-41-42 +.. nonce: xP7yZ4 +.. section: Tests + +Fix test_pha_required_nocert() of test_ssl: catch two more EOF cases (when +the ``recv()`` method returns an empty string). Patch by Victor Stinner. + +.. + +.. bpo: 44131 +.. date: 2021-05-14-14-13-44 +.. nonce: YPizoC +.. section: Tests + +Add test_frozenmain to test_embed to test the :c:func:`Py_FrozenMain` C +function. Patch by Victor Stinner. + +.. + +.. bpo: 31904 +.. date: 2021-05-07-15-46-04 +.. nonce: 8dk3la +.. section: Tests + +Ignore error string case in test_file_not_exists(). + +.. + +.. bpo: 42083 +.. date: 2021-05-04-18-10-57 +.. nonce: EMS2TK +.. section: Tests + +Add test to check that ``PyStructSequence_NewType`` accepts a +``PyStructSequence_Desc`` with ``doc`` field set to ``NULL``. + +.. + +.. bpo: 35753 +.. date: 2020-10-25-19-20-26 +.. nonce: 2LT-hO +.. section: Tests + +Fix crash in doctest when doctest parses modules that include unwrappable +functions by skipping those functions. + +.. + +.. bpo: 30256 +.. date: 2019-09-25-18-10-10 +.. nonce: A5i76Q +.. section: Tests + +Add test for nested queues when using ``multiprocessing`` shared objects +``AutoProxy[Queue]`` inside ``ListProxy`` and ``DictProxy`` + +.. + +.. bpo: 45220 +.. date: 2021-09-16-18-00-43 +.. nonce: TgbkvW +.. section: Build + +Avoid building with the Windows 11 SDK previews automatically. This may be +overridden by setting the ``DefaultWindowsSDKVersion`` environment variable +before building. + +.. + +.. bpo: 45020 +.. date: 2021-09-14-10-07-23 +.. nonce: _VGGPv +.. section: Build + +Freeze stdlib modules that are imported during startup. This provides +significant performance improvements to startup. If necessary, use the +previously added "-X frozen_modules=off" commandline option to force +importing the source modules. + +.. + +.. bpo: 45188 +.. date: 2021-09-14-00-47-57 +.. nonce: MNbo_T +.. section: Build + +Windows builds now regenerate frozen modules as the first part of the build. +Previously the regeneration was later in the build, which would require it +to be restarted if any modules had changed. + +.. + +.. bpo: 45163 +.. date: 2021-09-11-06-05-23 +.. nonce: q7xT93 +.. section: Build + +Fixes Haiku platform build. + +.. + +.. bpo: 45067 +.. date: 2021-09-09-16-45-26 +.. nonce: mFmY92 +.. section: Build + +The ncurses function extended_color_content was introduced in 2017 + +(https://invisible-island.net/ncurses/NEWS.html#index-t20170401). The + +ncurses-devel package in CentOS 7 had a older version ncurses resulted in +compilation error. For compiling ncurses with extended color support, we +verify the version of the ncurses library >= 20170401. + +.. + +.. bpo: 45019 +.. date: 2021-08-26-13-10-46 +.. nonce: e0mo49 +.. section: Build + +Generate lines in relevant files for frozen modules. Up until now each of +the files had to be edited manually. This change makes it easier to add to +and modify the frozen modules. + +.. + +.. bpo: 44340 +.. date: 2021-07-19-01-09-56 +.. nonce: JNeOf4 +.. section: Build + +Add support for building with clang thin lto via --with-lto=thin/full. Patch +by Donghee Na and Brett Holman. + +.. + +.. bpo: 44535 +.. date: 2021-06-30-02-32-46 +.. nonce: M9iN4- +.. section: Build + +Enable building using a Visual Studio 2022 install on Windows. + +.. + +.. bpo: 43298 +.. date: 2021-06-19-11-50-03 +.. nonce: 9ircMb +.. section: Build + +Improved error message when building without a Windows SDK installed. + +.. + +.. bpo: 44381 +.. date: 2021-06-10-18-08-44 +.. nonce: Xpc1iX +.. section: Build + +The Windows build now accepts :envvar:`EnableControlFlowGuard` set to +``guard`` to enable CFG. + +.. + +.. bpo: 41282 +.. date: 2021-05-24-03-31-17 +.. nonce: L8nP44 +.. section: Build + +Fix broken ``make install`` that caused standard library extension modules +to be unnecessarily and incorrectly rebuilt during the install phase of +cpython. + +.. + +.. bpo: 45375 +.. date: 2021-10-05-12-41-53 +.. nonce: CohPP- +.. section: Windows + +Fixes an assertion failure due to searching for the standard library in +unnormalised paths. + +.. + +.. bpo: 45022 +.. date: 2021-09-03-18-05-21 +.. nonce: bgpD_r +.. section: Windows + +Update Windows release to include libffi 3.4.2 + +.. + +.. bpo: 45007 +.. date: 2021-08-27-23-50-02 +.. nonce: NIBlVG +.. section: Windows + +Update to OpenSSL 1.1.1l in Windows build + +.. + +.. bpo: 44848 +.. date: 2021-08-06-10-11-07 +.. nonce: ib3Jcz +.. section: Windows + +Upgrade Windows installer to use SQLite 3.36.0. + +.. + +.. bpo: 44572 +.. date: 2021-07-13-15-32-49 +.. nonce: gXvhDc +.. section: Windows + +Avoid consuming standard input in the :mod:`platform` module + +.. + +.. bpo: 44582 +.. date: 2021-07-07-21-07-18 +.. nonce: 4Mm6Hh +.. section: Windows + +Accelerate speed of :mod:`mimetypes` initialization using a native +implementation of the registry scan. + +.. + +.. bpo: 41299 +.. date: 2021-06-06-16-36-13 +.. nonce: Rg-vb_ +.. section: Windows + +Fix 16 milliseconds jitter when using timeouts in :mod:`threading`, such as +with :meth:`threading.Lock.acquire` or :meth:`threading.Condition.wait`. + +.. + +.. bpo: 42686 +.. date: 2021-01-01-21-21-03 +.. nonce: G_f-TC +.. section: Windows + +Build :mod:`sqlite3` with math functions enabled. Patch by Erlend E. +Aasland. + +.. + +.. bpo: 40263 +.. date: 2020-04-13-15-20-28 +.. nonce: 1KKEbu +.. section: Windows + +This is a follow-on bug from https://bugs.python.org/issue26903. Once that +is applied we run into an off-by-one assertion problem. The assert was not +correct. + +.. + +.. bpo: 45007 +.. date: 2021-08-30-00-04-10 +.. nonce: pixqUB +.. section: macOS + +Update macOS installer builds to use OpenSSL 1.1.1l. + +.. + +.. bpo: 34602 +.. date: 2021-08-27-16-55-10 +.. nonce: ZjHsYJ +.. section: macOS + +When building CPython on macOS with ``./configure +--with-undefined-behavior-sanitizer --with-pydebug``, the stack size is now +quadrupled to allow for the entire test suite to pass. + +.. + +.. bpo: 44848 +.. date: 2021-08-06-10-08-41 +.. nonce: 0uYXsE +.. section: macOS + +Update macOS installer to use SQLite 3.36.0. + +.. + +.. bpo: 44689 +.. date: 2021-07-20-22-27-01 +.. nonce: mmT_xH +.. section: macOS + +:meth:`ctypes.util.find_library` now works correctly on macOS 11 Big Sur +even if Python is built on an older version of macOS. Previously, when +built on older macOS systems, ``find_library`` was not able to find macOS +system libraries when running on Big Sur due to changes in how system +libraries are stored. + +.. + +.. bpo: 41972 +.. date: 2021-07-12-15-42-02 +.. nonce: yUjE8j +.. section: macOS + +The framework build's user header path in sysconfig is changed to add a +'pythonX.Y' component to match distutils's behavior. + +.. + +.. bpo: 43109 +.. date: 2021-05-24-21-15-41 +.. nonce: npKJ9c +.. section: macOS + +Allow --with-lto configure option to work with Apple-supplied Xcode or +Command Line Tools. + +.. + +.. bpo: 34932 +.. date: 2021-03-29-21-11-23 +.. nonce: f3Hdyd +.. section: macOS + +Add socket.TCP_KEEPALIVE support for macOS. Patch by Shane Harvey. + +.. + +.. bpo: 45296 +.. date: 2021-09-27-01-21-59 +.. nonce: 9H8rdY +.. section: IDLE + +On Windows, change exit/quit message to suggest Ctrl-D, which works, instead +of <Ctrl-Z Return>, which does not work in IDLE. + +.. + +.. bpo: 45193 +.. date: 2021-09-15-03-20-06 +.. nonce: G61_GV +.. section: IDLE + +Make completion boxes appear on Ubuntu again. + +.. + +.. bpo: 40128 +.. date: 2021-06-11-17-43-39 +.. nonce: 7vDN3U +.. section: IDLE + +Mostly fix completions on macOS when not using tcl/tk 8.6.11 (as with 3.9). +The added update_idletask call should be harmless and possibly helpful +otherwise. + +.. + +.. bpo: 33962 +.. date: 2021-06-10-00-50-02 +.. nonce: ikAUNg +.. section: IDLE + +Move the indent space setting from the Font tab to the new Windows tab. +Patch by Mark Roseman and Terry Jan Reedy. + +.. + +.. bpo: 40468 +.. date: 2021-06-08-03-04-51 +.. nonce: tUCGUb +.. section: IDLE + +Split the settings dialog General tab into Windows and Shell/ED tabs. Move +help sources, which extend the Help menu, to the Extensions tab. Make space +for new options and shorten the dialog. The latter makes the dialog better +fit small screens. + +.. + +.. bpo: 41611 +.. date: 2021-05-27-18-22-46 +.. nonce: jOKpfc +.. section: IDLE + +Avoid uncaught exceptions in ``AutoCompleteWindow.winconfig_event()``. + +.. + +.. bpo: 41611 +.. date: 2021-05-27-13-39-43 +.. nonce: liNQqj +.. section: IDLE + +Fix IDLE sometimes freezing upon tab-completion on macOS. + +.. + +.. bpo: 44010 +.. date: 2021-05-09-09-02-09 +.. nonce: TaLe9x +.. section: IDLE + +Highlight the new :ref:`match <match>` statement's :ref:`soft keywords +<soft-keywords>`: :keyword:`match`, :keyword:`case <match>`, and :keyword:`_ +<wildcard-patterns>`. However, this highlighting is not perfect and will be +incorrect in some rare cases, including some ``_``-s in ``case`` patterns. + +.. + +.. bpo: 44026 +.. date: 2021-05-05-09-45-24 +.. nonce: m2Z0zR +.. section: IDLE + +Include interpreter's typo fix suggestions in message line for NameErrors +and AttributeErrors. Patch by E. Paine. + +.. + +.. bpo: 44786 +.. date: 2021-09-14-11-44-26 +.. nonce: DU0LC0 +.. section: Tools/Demos + +Fix a warning in regular expression in the c-analyzer script. + +.. + +.. bpo: 44967 +.. date: 2021-08-26-11-57-31 +.. nonce: UT1RMV +.. section: Tools/Demos + +pydoc now returns a non-zero status code when a module cannot be found. + +.. + +.. bpo: 44978 +.. date: 2021-08-22-11-45-31 +.. nonce: QupKV3 +.. section: Tools/Demos + +Allow the Argument Clinic tool to handle ``__complex__`` special methods. + +.. + +.. bpo: 43425 +.. date: 2021-07-01-22-21-25 +.. nonce: t65len +.. section: Tools/Demos + +Removed the 'test2to3' demo project that demonstrated using lib2to3 to +support Python 2.x and Python 3.x from a single source in a distutils +package. Patch by Donghee Na + +.. + +.. bpo: 44074 +.. date: 2021-05-08-13-57-00 +.. nonce: F09kCK +.. section: Tools/Demos + +Make patchcheck automatically detect the correct base branch name +(previously it was hardcoded to 'master') + +.. + +.. bpo: 20291 +.. date: 2020-02-25-18-22-09 +.. nonce: AyrDiZ +.. section: Tools/Demos + +Added support for variadic positional parameters in Argument Clinic. + +.. + +.. bpo: 41710 +.. date: 2021-09-30-03-14-35 +.. nonce: DDWJKx +.. section: C API + +The PyThread_acquire_lock_timed() function now clamps the timeout if it is +too large, rather than aborting the process. Patch by Victor Stinner. + +.. + +.. bpo: 44687 +.. date: 2021-09-19-17-18-25 +.. nonce: 3fqDRC +.. section: C API + +:meth:`BufferedReader.peek` no longer raises :exc:`ValueError` when the +entire file has already been buffered. + +.. + +.. bpo: 45116 +.. date: 2021-09-16-18-05-20 +.. nonce: WxXewl +.. section: C API + +Add the :c:macro:`Py_ALWAYS_INLINE` macro to ask the compiler to always +inline a static inline function. The compiler can ignore it and decides to +not inline the function. Patch by Victor Stinner. + +.. + +.. bpo: 45094 +.. date: 2021-09-03-15-53-43 +.. nonce: tinXwL +.. section: C API + +Add the :c:macro:`Py_NO_INLINE` macro to disable inlining on a function. +Patch by Victor Stinner. + +.. + +.. bpo: 45061 +.. date: 2021-08-31-15-21-36 +.. nonce: ZH0HVe +.. section: C API + +Add a deallocator to the :class:`bool` type to detect refcount bugs in C +extensions which call ``Py_DECREF(Py_True);`` or ``Py_DECREF(Py_False);`` by +mistake. Patch by Victor Stinner. + +.. + +.. bpo: 42035 +.. date: 2021-08-02-20-49-36 +.. nonce: HTBcZt +.. section: C API + +Add a new :c:func:`PyType_GetQualName` function to get type's qualified +name. + +.. + +.. bpo: 41103 +.. date: 2021-07-29-16-04-28 +.. nonce: hiKKcF +.. section: C API + +Reverts removal of the old buffer protocol because they are part of stable +ABI. + +.. + +.. bpo: 44751 +.. date: 2021-07-27-17-29-12 +.. nonce: 4qmbDG +.. section: C API + +Remove ``crypt.h`` include from the public ``Python.h`` header. + +.. + +.. bpo: 42747 +.. date: 2021-07-20-16-21-06 +.. nonce: rRxjUY +.. section: C API + +The ``Py_TPFLAGS_HAVE_VERSION_TAG`` type flag now does nothing. The +``Py_TPFLAGS_HAVE_AM_SEND`` flag (which was added in 3.10) is removed. Both +were unnecessary because it is not possible to have type objects with the +relevant fields missing. + +.. + +.. bpo: 44530 +.. date: 2021-06-28-23-44-47 +.. nonce: qij7YC +.. section: C API + +Added the ``co_qualname`` to the ``PyCodeObject`` structure to propagate the +qualified name from the compiler to code objects. + +Patch by Gabriele N. Tornetta + +.. + +.. bpo: 44441 +.. date: 2021-06-23-12-12-04 +.. nonce: 3p14JB +.. section: C API + +:c:func:`Py_RunMain` now resets :c:data:`PyImport_Inittab` to its initial +value at exit. It must be possible to call :c:func:`PyImport_AppendInittab` +or :c:func:`PyImport_ExtendInittab` at each Python initialization. Patch by +Victor Stinner. + +.. + +.. bpo: 39947 +.. date: 2021-06-23-10-31-45 +.. nonce: je_HMo +.. section: C API + +Remove 4 private trashcan C API functions which were only kept for the +backward compatibility of the stable ABI with Python 3.8 and older, since +the trashcan API was not usable with the limited C API on Python 3.8 and +older. The trashcan API was excluded from the limited C API in Python 3.9. + +Removed functions: + +* _PyTrash_deposit_object() +* _PyTrash_destroy_chain() +* _PyTrash_thread_deposit_object() +* _PyTrash_thread_destroy_chain() + +The trashcan C API was never usable with the limited C API, since old +trashcan macros accessed directly :c:type:`PyThreadState` members like +``_tstate->trash_delete_nesting``, whereas the :c:type:`PyThreadState` +structure is opaque in the limited C API. + +Exclude also the ``PyTrash_UNWIND_LEVEL`` constant from the C API. + +Patch by Victor Stinner. + +.. + +.. bpo: 40939 +.. date: 2021-06-22-17-00-06 +.. nonce: CGB0I5 +.. section: C API + +Removed documentation for the removed ``PyParser_*`` C API. + +.. + +.. bpo: 43795 +.. date: 2021-06-15-16-28-18 +.. nonce: fy0AXK +.. section: C API + +The list in :ref:`limited-api-list` now shows the public name +:c:struct:`PyFrameObject` rather than ``_frame``. The non-existing entry +``_node`` no longer appears in the list. + +.. + +.. bpo: 44378 +.. date: 2021-06-10-15-22-31 +.. nonce: jGYakF +.. section: C API + +:c:func:`Py_IS_TYPE` no longer uses :c:func:`Py_TYPE` to avoid a compiler +warning: no longer cast ``const PyObject*`` to ``PyObject*``. Patch by +Victor Stinner. + +.. + +.. bpo: 39573 +.. date: 2021-06-03-00-59-48 +.. nonce: -elHTJ +.. section: C API + +Convert the :c:func:`Py_TYPE` and :c:func:`Py_SIZE` macros to static inline +functions. The :c:func:`Py_SET_TYPE` and :c:func:`Py_SET_SIZE` functions +must now be used to set an object type and size. Patch by Victor Stinner. + +.. + +.. bpo: 44263 +.. date: 2021-05-31-11-31-13 +.. nonce: 8mIOfV +.. section: C API + +The :c:func:`PyType_Ready` function now raises an error if a type is defined +with the :c:macro:`Py_TPFLAGS_HAVE_GC` flag set but has no traverse function +(:c:member:`PyTypeObject.tp_traverse`). Patch by Victor Stinner. + +.. + +.. bpo: 43795 +.. date: 2021-05-19-15-09-47 +.. nonce: WAHRxt +.. section: C API + +The undocumented function :c:func:`Py_FrozenMain` is removed from the +Limited API. + +.. + +.. bpo: 44113 +.. date: 2021-05-12-12-24-45 +.. nonce: DcgOqE +.. section: C API + +Deprecate the following functions to configure the Python initialization: + +* :c:func:`!PySys_AddWarnOptionUnicode` +* :c:func:`!PySys_AddWarnOption` +* :c:func:`!PySys_AddXOption` +* :c:func:`!PySys_HasWarnOptions` +* :c:func:`!Py_SetPath` +* :c:func:`!Py_SetProgramName` +* :c:func:`!Py_SetPythonHome` +* :c:func:`!Py_SetStandardStreamEncoding` +* :c:func:`!_Py_SetProgramFullPath` + +Use the new :c:type:`PyConfig` API of the :ref:`Python Initialization +Configuration <init-config>` instead (:pep:`587`). + +.. + +.. bpo: 44094 +.. date: 2021-05-10-14-34-22 +.. nonce: HayXZO +.. section: C API + +Remove ``PyErr_SetFromErrnoWithUnicodeFilename()``, +``PyErr_SetFromWindowsErrWithUnicodeFilename()``, and +``PyErr_SetExcFromWindowsErrWithUnicodeFilename()``. They are not documented +and have been deprecated since Python 3.3. + +.. + +.. bpo: 43795 +.. date: 2021-05-05-19-04-50 +.. nonce: 9Ojj73 +.. section: C API + +:c:func:`PyCodec_Unregister` is now properly exported as a function in the +Windows Stable ABI DLL. + +.. + +.. bpo: 44029 +.. date: 2021-05-04-17-43-39 +.. nonce: ayX4PR +.. section: C API + +Remove deprecated ``Py_UNICODE`` APIs: ``PyUnicode_Encode``, +``PyUnicode_EncodeUTF7``, ``PyUnicode_EncodeUTF8``, +``PyUnicode_EncodeUTF16``, ``PyUnicode_EncodeUTF32``, +``PyUnicode_EncodeLatin1``, ``PyUnicode_EncodeMBCS``, +``PyUnicode_EncodeDecimal``, ``PyUnicode_EncodeRawUnicodeEscape``, +``PyUnicode_EncodeCharmap``, ``PyUnicode_EncodeUnicodeEscape``, +``PyUnicode_TransformDecimalToASCII``, ``PyUnicode_TranslateCharmap``, +``PyUnicodeEncodeError_Create``, ``PyUnicodeTranslateError_Create``. See +:pep:`393` and :pep:`624` for reference. + +.. + +.. bpo: 42035 +.. date: 2020-12-23-01-28-50 +.. nonce: S9eUm0 +.. section: C API + +Add a new :c:func:`PyType_GetName` function to get type's short name. diff --git a/Misc/NEWS.d/3.11.0a2.rst b/Misc/NEWS.d/3.11.0a2.rst new file mode 100644 index 00000000..503e489b --- /dev/null +++ b/Misc/NEWS.d/3.11.0a2.rst @@ -0,0 +1,1334 @@ +.. bpo: 45716 +.. date: 2021-11-04-20-19-07 +.. nonce: 5C0pA1 +.. release date: 2021-11-05 +.. section: Core and Builtins + +Improve the :exc:`SyntaxError` message when using ``True``, ``None`` or +``False`` as keywords in a function call. Patch by Pablo Galindo. + +.. + +.. bpo: 45688 +.. date: 2021-11-02-09-27-46 +.. nonce: v5Der1 +.. section: Core and Builtins + +:data:`sys.stdlib_module_names` now contains the macOS-specific module +:mod:`_scproxy`. + +.. + +.. bpo: 45379 +.. date: 2021-10-23-13-49-00 +.. nonce: ZF7G3n +.. section: Core and Builtins + +Clarify :exc:`ImportError` message when we try to explicitly import a frozen +module but frozen modules are disabled. + +.. + +.. bpo: 44525 +.. date: 2021-10-20-11-57-31 +.. nonce: veL4lJ +.. section: Core and Builtins + +Specialize simple calls to Python functions (no starargs, keyowrd dict, or +closure) + +.. + +.. bpo: 45530 +.. date: 2021-10-20-01-28-26 +.. nonce: 5r7n4m +.. section: Core and Builtins + +Cases of sorting using tuples as keys may now be significantly faster in +some cases. Patch by Tim Peters. + +The order of the result may differ from earlier releases if the tuple +elements don't define a total ordering (see +:ref:`expressions-value-comparisons` for information on total ordering). +It's generally true that the result of sorting simply isn't well-defined in +the absence of a total ordering on list elements. + +.. + +.. bpo: 45526 +.. date: 2021-10-19-10-29-47 +.. nonce: WQnvW9 +.. section: Core and Builtins + +In obmalloc, set ADDRESS_BITS to not ignore any bits (ignored 16 before). +That is safer in the case that the kernel gives user-space virtual addresses +that span a range greater than 48 bits. + +.. + +.. bpo: 30570 +.. date: 2021-10-19-01-04-08 +.. nonce: _G30Ms +.. section: Core and Builtins + +Fixed a crash in ``issubclass()`` from infinite recursion when searching +pathological ``__bases__`` tuples. + +.. + +.. bpo: 45521 +.. date: 2021-10-18-22-40-33 +.. nonce: GdMiuW +.. section: Core and Builtins + +Fix a bug in the obmalloc radix tree code. On 64-bit machines, the bug +causes the tree to hold 46-bits of virtual addresses, rather than the +intended 48-bits. + +.. + +.. bpo: 45494 +.. date: 2021-10-16-17-27-48 +.. nonce: vMt1g4 +.. section: Core and Builtins + +Fix parser crash when reporting errors involving invalid continuation +characters. Patch by Pablo Galindo. + +.. + +.. bpo: 45445 +.. date: 2021-10-12-14-41-39 +.. nonce: _F5cMf +.. section: Core and Builtins + +Python now fails to initialize if it finds an invalid :option:`-X` option in +the command line. Patch by Pablo Galindo. + +.. + +.. bpo: 45340 +.. date: 2021-10-08-09-47-38 +.. nonce: ukHgDb +.. section: Core and Builtins + +Object attributes are held in an array instead of a dictionary. An object's +dictionary are created lazily, only when needed. Reduces the memory +consumption of a typical Python object by about 30%. Patch by Mark Shannon. + +.. + +.. bpo: 45408 +.. date: 2021-10-07-21-26-44 +.. nonce: qUqzcd +.. section: Core and Builtins + +Fix a crash in the parser when reporting tokenizer errors that occur at the +same time unclosed parentheses are detected. Patch by Pablo Galindo. + +.. + +.. bpo: 29410 +.. date: 2021-10-07-19-09-12 +.. nonce: bg5SYp +.. section: Core and Builtins + +Add SipHash13 for string hash algorithm and use it by default. + +.. + +.. bpo: 45385 +.. date: 2021-10-06-21-20-11 +.. nonce: CTUT8s +.. section: Core and Builtins + +Fix reference leak from descr_check. Patch by Donghee Na. + +.. + +.. bpo: 45367 +.. date: 2021-10-05-03-49-07 +.. nonce: _astoU +.. section: Core and Builtins + +Specialized the ``BINARY_MULTIPLY`` opcode to ``BINARY_MULTIPLY_INT`` and +``BINARY_MULTIPLY_FLOAT`` using the PEP 659 machinery. + +.. + +.. bpo: 21736 +.. date: 2021-10-01-09-21-02 +.. nonce: RI47BU +.. section: Core and Builtins + +Frozen stdlib modules now have ``__file__`` to the .py file they would +otherwise be loaded from, if possible. For packages, ``__path__`` now has +the correct entry instead of being an empty list, which allows unfrozen +submodules to be imported. These are set only if the stdlib directory is +known when the runtime is initialized. Note that the file at ``__file__`` +is not guaranteed to exist. None of this affects non-stdlib frozen modules +nor, for now, frozen modules imported using +``PyImport_ImportFrozenModule()``. Also, at the moment ``co_filename`` is +not updated for the module. + +.. + +.. bpo: 45020 +.. date: 2021-10-01-09-06-54 +.. nonce: Cj5VQN +.. section: Core and Builtins + +For frozen stdlib modules, record the original module name as +``module.__spec__.loader_state.origname``. If the value is different than +``module.__spec__.name`` then the module was defined as an alias in +Tools/scripts/freeze_modules.py. If it is ``None`` then the module comes +from a source file outside the stdlib. + +.. + +.. bpo: 45324 +.. date: 2021-09-29-12-02-39 +.. nonce: BTQElX +.. section: Core and Builtins + +In FrozenImporter.find_spec(), we now preserve the information needed in +exec_module() to load the module. This change mostly impacts internal +details, rather than changing the importer's behavior. + +.. + +.. bpo: 45292 +.. date: 2021-09-26-18-18-50 +.. nonce: aX5HVr +.. section: Core and Builtins + +Implement :pep:`654`. Add :class:`ExceptionGroup` and +:class:`BaseExceptionGroup`. Update traceback display code. + +.. + +.. bpo: 40116 +.. date: 2021-09-23-14-00-05 +.. nonce: KaoeFs +.. section: Core and Builtins + +Change to the implementation of split dictionaries. Classes where the +instances differ either in the exact set of attributes, or in the order in +which those attributes are set, can still share keys. This should have no +observable effect on users of Python or the C-API. Patch by Mark Shannon. + +.. + +.. bpo: 44050 +.. date: 2021-09-08-00-30-09 +.. nonce: mFI15u +.. section: Core and Builtins + +Extensions that indicate they use global state (by setting ``m_size`` to -1) +can again be used in multiple interpreters. This reverts to behavior of +Python 3.8. + +.. + +.. bpo: 44525 +.. date: 2021-06-28-22-23-59 +.. nonce: sSvUKG +.. section: Core and Builtins + +Setup initial specialization infrastructure for the ``CALL_FUNCTION`` +opcode. Implemented initial specializations for C function calls: + +* ``CALL_FUNCTION_BUILTIN_O`` for ``METH_O`` flag. + +* ``CALL_FUNCTION_BUILTIN_FAST`` for ``METH_FASTCALL`` flag without keywords. + +* ``CALL_FUNCTION_LEN`` for ``len(o)``. + +* ``CALL_FUNCTION_ISINSTANCE`` for ``isinstance(o, t)``. + +.. + +.. bpo: 44511 +.. date: 2021-06-26-16-55-08 +.. nonce: k8sMvV +.. section: Core and Builtins + +Improve the generated bytecode for class and mapping patterns. + +.. + +.. bpo: 43706 +.. date: 2021-04-03-02-44-15 +.. nonce: jjsXlT +.. section: Core and Builtins + +Speed up calls to ``enumerate()`` by using the :pep:`590` ``vectorcall`` +calling convention. Patch by Donghee Na. + +.. + +.. bpo: 45679 +.. date: 2021-10-30-21-11-37 +.. nonce: Dq8Cpu +.. section: Library + +Fix caching of multi-value :data:`typing.Literal`. ``Literal[True, 2]`` is +no longer equal to ``Literal[1, 2]``. + +.. + +.. bpo: 42064 +.. date: 2021-10-27-13-28-52 +.. nonce: UK4jgV +.. section: Library + +Convert :mod:`sqlite3` to multi-phase initialisation (PEP 489). Patches by +Erlend E. Aasland. + +.. + +.. bpo: 45438 +.. date: 2021-10-27-10-05-39 +.. nonce: Xz5lGU +.. section: Library + +Fix typing.Signature string representation for generic builtin types. + +.. + +.. bpo: 45613 +.. date: 2021-10-26-14-29-54 +.. nonce: 55Ie3c +.. section: Library + +:mod:`sqlite3` now sets :attr:`sqlite3.threadsafety` based on the default +threading mode the underlying SQLite library has been compiled with. Patch +by Erlend E. Aasland. + +.. + +.. bpo: 45574 +.. date: 2021-10-22-23-06-33 +.. nonce: svqA84 +.. section: Library + +Fix warning about ``print_escape`` being unused. + +.. + +.. bpo: 45581 +.. date: 2021-10-22-21-57-02 +.. nonce: rlH6ay +.. section: Library + +:meth:`sqlite3.connect` now correctly raises :exc:`MemoryError` if the +underlying SQLite API signals memory error. Patch by Erlend E. Aasland. + +.. + +.. bpo: 45557 +.. date: 2021-10-21-16-18-51 +.. nonce: 4MQt4r +.. section: Library + +pprint.pprint() now handles underscore_numbers correctly. Previously it was +always setting it to False. + +.. + +.. bpo: 44019 +.. date: 2021-10-21-10-14-22 +.. nonce: Xk4Ncr +.. section: Library + +Add :func:`operator.call` to ``operator.__all__``. Patch by Kreusada. + +.. + +.. bpo: 42174 +.. date: 2021-10-19-01-30-57 +.. nonce: O2w9bi +.. section: Library + +:meth:`shutil.get_terminal_size` now falls back to sane values if the column +or line count are 0. + +.. + +.. bpo: 35673 +.. date: 2021-10-18-18-12-47 +.. nonce: KOkHWe +.. section: Library + +Improve the introspectability of the ``__loader__`` attribute for namespace +packages. :class:`importlib.machinery.NamespaceLoader` is now public, and +implements the :class:`importlib.abc.InspectLoader` interface. +``_NamespaceLoader`` is kept for backward compatibility. + +.. + +.. bpo: 45515 +.. date: 2021-10-18-14-52-48 +.. nonce: aXdvm_ +.. section: Library + +Add references to :mod:`zoneinfo` in the :mod:`datetime` documentation, +mostly replacing outdated references to ``dateutil.tz``. Change by Paul +Ganssle. + +.. + +.. bpo: 45475 +.. date: 2021-10-18-10-46-47 +.. nonce: sb9KDF +.. section: Library + +Reverted optimization of iterating :class:`gzip.GzipFile`, +:class:`bz2.BZ2File`, and :class:`lzma.LZMAFile` (see bpo-43787) because it +caused regression when user iterate them without having reference of them. +Patch by Inada Naoki. + +.. + +.. bpo: 45489 +.. date: 2021-10-16-23-46-39 +.. nonce: QB0rhG +.. section: Library + +Update :class:`~typing.ForwardRef` to support ``|`` operator. Patch by +Donghee Na. + +.. + +.. bpo: 42222 +.. date: 2021-10-15-11-30-11 +.. nonce: hdHyac +.. section: Library + +Removed deprecated support for float arguments in *randrange()*. + +.. + +.. bpo: 45428 +.. date: 2021-10-14-18-04-17 +.. nonce: mM2War +.. section: Library + +Fix a regression in py_compile when reading filenames from standard input. + +.. + +.. bpo: 45467 +.. date: 2021-10-14-13-31-19 +.. nonce: Q7Ma6A +.. section: Library + +Fix incremental decoder and stream reader in the "raw-unicode-escape" codec. +Previously they failed if the escape sequence was split. + +.. + +.. bpo: 45461 +.. date: 2021-10-14-00-19-02 +.. nonce: 4LB_tJ +.. section: Library + +Fix incremental decoder and stream reader in the "unicode-escape" codec. +Previously they failed if the escape sequence was split. + +.. + +.. bpo: 45239 +.. date: 2021-10-13-17-52-48 +.. nonce: 7li1_0 +.. section: Library + +Fixed :func:`email.utils.parsedate_tz` crashing with +:exc:`UnboundLocalError` on certain invalid input instead of returning +``None``. Patch by Ben Hoyt. + +.. + +.. bpo: 45417 +.. date: 2021-10-12-20-35-06 +.. nonce: gQM-O7 +.. section: Library + +Fix quadratic behaviour in the enum module: Creation of enum classes with a +lot of entries was quadratic. + +.. + +.. bpo: 45249 +.. date: 2021-10-10-16-14-33 +.. nonce: xqLliz +.. section: Library + +Fix the behaviour of :func:`traceback.print_exc` when displaying the caret +when the ``end_offset`` in the exception is set to 0. Patch by Pablo Galindo + +.. + +.. bpo: 45416 +.. date: 2021-10-10-09-42-34 +.. nonce: n35O0_ +.. section: Library + +Fix use of :class:`asyncio.Condition` with explicit :class:`asyncio.Lock` +objects, which was a regression due to removal of explicit loop arguments. +Patch by Joongi Kim. + +.. + +.. bpo: 20028 +.. date: 2021-10-10-00-25-36 +.. nonce: bPx4Z8 +.. section: Library + +Empty escapechar/quotechar is not allowed when initializing +:class:`csv.Dialect`. Patch by Vajrasky Kok and Donghee Na. + +.. + +.. bpo: 44904 +.. date: 2021-10-09-18-42-27 +.. nonce: RlW5h8 +.. section: Library + +Fix bug in the :mod:`doctest` module that caused it to fail if a docstring +included an example with a ``classmethod`` ``property``. Patch by Alex +Waygood. + +.. + +.. bpo: 45406 +.. date: 2021-10-08-19-24-48 +.. nonce: Qh_Mz4 +.. section: Library + +Make :func:`inspect.getmodule` catch ``FileNotFoundError`` raised by +:'func:`inspect.getabsfile`, and return ``None`` to indicate that the module +could not be determined. + +.. + +.. bpo: 45411 +.. date: 2021-10-08-11-29-29 +.. nonce: 4jR--U +.. section: Library + +Add extensions for files containing subtitles - .srt & .vtt - to the +mimetypes.py module. + +.. + +.. bpo: 10716 +.. date: 2021-10-08-04-11-55 +.. nonce: QSRVK2 +.. section: Library + +Migrated pydoc to HTML5 (without changing the look of it). Side effect is to +update xmlrpc's ``ServerHTMLDoc`` which now uses the CSS too. cgitb now +relies less on pydoc (as it can't use the CSS file). + +.. + +.. bpo: 27580 +.. date: 2021-10-07-21-11-48 +.. nonce: tGcBTH +.. section: Library + +Add support of null characters in :mod:`csv`. + +.. + +.. bpo: 45262 +.. date: 2021-10-07-14-04-10 +.. nonce: HqF71Z +.. section: Library + +Prevent use-after-free in asyncio. Make sure the cached running loop holder +gets cleared on dealloc to prevent use-after-free in get_running_loop + +.. + +.. bpo: 45386 +.. date: 2021-10-07-00-05-05 +.. nonce: q9ORpA +.. section: Library + +Make :mod:`xmlrpc.client` more robust to C runtimes where the underlying C +``strftime`` function results in a ``ValueError`` when testing for year +formatting options. + +.. + +.. bpo: 20028 +.. date: 2021-10-03-21-14-37 +.. nonce: zBA4RK +.. section: Library + +Improve error message of :class:`csv.Dialect` when initializing. Patch by +Vajrasky Kok and Donghee Na. + +.. + +.. bpo: 45343 +.. date: 2021-10-01-23-07-02 +.. nonce: ixmctD +.. section: Library + +Update bundled pip to 21.2.4 and setuptools to 58.1.0 + +.. + +.. bpo: 45328 +.. date: 2021-09-30-08-22-44 +.. nonce: 8Z-Q0B +.. section: Library + +Fixed :class:`http.client.HTTPConnection` to work properly in OSs that don't +support the ``TCP_NODELAY`` socket option. + +.. + +.. bpo: 45243 +.. date: 2021-09-20-01-25-09 +.. nonce: 0pJf0U +.. section: Library + +Add :meth:`~sqlite3.Connection.setlimit` and +:meth:`~sqlite3.Connection.getlimit` to :class:`sqlite3.Connection` for +setting and getting SQLite limits by connection basis. Patch by Erlend E. +Aasland. + +.. + +.. bpo: 45320 +.. date: 2021-09-15-10-21-10 +.. nonce: 4qaf5x +.. section: Library + +Removed from the :mod:`inspect` module: + +* the ``getargspec`` function, deprecated since Python 3.0; + use :func:`inspect.signature` or :func:`inspect.getfullargspec` instead. + +* the ``formatargspec`` function, deprecated since Python 3.5; + use the :func:`inspect.signature` function and :class:`Signature` object + directly. + +* the undocumented ``Signature.from_builtin`` and ``Signature.from_function`` + functions, deprecated since Python 3.5; use the + :meth:`Signature.from_callable() <inspect.Signature.from_callable>` method + instead. + +Patch by Hugo van Kemenade. + +.. + +.. bpo: 45192 +.. date: 2021-09-14-15-52-47 +.. nonce: DjA-BI +.. section: Library + +Fix the ``tempfile._infer_return_type`` function so that the ``dir`` +argument of the :mod:`tempfile` functions accepts an object implementing the +``os.PathLike`` protocol. + +Patch by Kyungmin Lee. + +.. + +.. bpo: 45160 +.. date: 2021-09-11-14-47-05 +.. nonce: VzMXbW +.. section: Library + +When tracing a tkinter variable used by a ttk OptionMenu, callbacks are no +longer made twice. + +.. + +.. bpo: 25625 +.. date: 2021-09-10-12-53-28 +.. nonce: SzcBCw +.. section: Library + +Added non parallel-safe :func:`~contextlib.chdir` context manager to change +the current working directory and then restore it on exit. Simple wrapper +around :func:`~os.chdir`. + +.. + +.. bpo: 24139 +.. date: 2021-08-30-23-10-48 +.. nonce: e38czf +.. section: Library + +Add support for SQLite extended result codes in :exc:`sqlite3.Error`. Patch +by Erlend E. Aasland. + +.. + +.. bpo: 24444 +.. date: 2021-08-30-00-19-23 +.. nonce: Ki4bgz +.. section: Library + +Fixed an error raised in :mod:`argparse` help display when help for an +option is set to 1+ blank spaces or when *choices* arg is an empty +container. + +.. + +.. bpo: 44547 +.. date: 2021-08-20-10-52-40 +.. nonce: eu0iJq +.. section: Library + +Implement ``Fraction.__int__``, so that a :class:`fractions.Fraction` +instance ``f`` passes an ``isinstance(f, typing.SupportsInt)`` check. + +.. + +.. bpo: 40321 +.. date: 2021-07-22-21-25-56 +.. nonce: gBlFmw +.. section: Library + +Adds support for HTTP 308 redirects to :mod:`urllib`. See :rfc:`7538` for +details. Patch by Jochem Schulenklopper. + +.. + +.. bpo: 41374 +.. date: 2020-07-27-19-21-05 +.. nonce: cd-kFL +.. section: Library + +Ensure that ``socket.TCP_*`` constants are exposed on Cygwin 3.1.6 and +greater. + +.. + +.. bpo: 35970 +.. date: 2019-02-11-19-06-10 +.. nonce: ZRvh51 +.. section: Library + +Add help flag to the base64 module's command line interface. Patch +contributed by Robert Kuska. + +.. + +.. bpo: 45726 +.. date: 2021-11-05-12-15-24 +.. nonce: GwRr7e +.. section: Documentation + +Improve documentation for :func:`functools.singledispatch` and +:class:`functools.singledispatchmethod`. + +.. + +.. bpo: 45680 +.. date: 2021-11-03-14-51-03 +.. nonce: 9_NTFU +.. section: Documentation + +Amend the docs on ``GenericAlias`` objects to clarify that non-container +classes can also implement ``__class_getitem__``. Patch contributed by Alex +Waygood. + +.. + +.. bpo: 45618 +.. date: 2021-10-31-20-35-06 +.. nonce: RTcNXF +.. section: Documentation + +Update Sphinx version used to build the documentation to 4.2.0. Patch by +Maciej Olko. + +.. + +.. bpo: 45655 +.. date: 2021-10-28-19-22-55 +.. nonce: aPYGaS +.. section: Documentation + +Add a new "relevant PEPs" section to the top of the documentation for the +``typing`` module. Patch by Alex Waygood. + +.. + +.. bpo: 45604 +.. date: 2021-10-26-10-00-45 +.. nonce: Dm-YhV +.. section: Documentation + +Add ``level`` argument to ``multiprocessing.log_to_stderr`` function docs. + +.. + +.. bpo: 45516 +.. date: 2021-10-22-21-57-42 +.. nonce: 7_RMEX +.. section: Documentation + +Add protocol description to the :class:`importlib.abc.TraversableResources` +documentation. + +.. + +.. bpo: 45464 +.. date: 2021-10-20-16-26-53 +.. nonce: mOISBs +.. section: Documentation + +Mention in the documentation of :ref:`Built-in Exceptions +<bltin-exceptions>` that inheriting from multiple exception types in a +single subclass is not recommended due to possible memory layout +incompatibility. + +.. + +.. bpo: 45449 +.. date: 2021-10-19-01-41-40 +.. nonce: fjHZJc +.. section: Documentation + +Add note about :pep:`585` in :mod:`collections.abc`. + +.. + +.. bpo: 45516 +.. date: 2021-10-18-20-12-18 +.. nonce: EJh4K8 +.. section: Documentation + +Add protocol description to the :class:`importlib.abc.Traversable` +documentation. + +.. + +.. bpo: 20692 +.. date: 2021-10-13-00-42-54 +.. nonce: K5rGtP +.. section: Documentation + +Add Programming FAQ entry explaining that int literal attribute access +requires either a space after or parentheses around the literal. + +.. + +.. bpo: 45678 +.. date: 2021-11-04-20-03-32 +.. nonce: 1xNMjN +.. section: Tests + +Add tests for scenarios in which :class:`functools.singledispatchmethod` is +stacked on top of a method that has already been wrapped by two other +decorators. Patch by Alex Waygood. + +.. + +.. bpo: 45578 +.. date: 2021-10-30-19-00-25 +.. nonce: bvu6X2 +.. section: Tests + +Add tests for :func:`dis.distb` + +.. + +.. bpo: 45678 +.. date: 2021-10-30-13-12-20 +.. nonce: bKrYeS +.. section: Tests + +Add tests to ensure that ``functools.singledispatchmethod`` correctly wraps +the attributes of the target function. + +.. + +.. bpo: 45668 +.. date: 2021-10-29-17-18-56 +.. nonce: MfAw4i +.. section: Tests + +PGO tests now pass when Python is built without test extension modules. + +.. + +.. bpo: 45577 +.. date: 2021-10-22-19-44-13 +.. nonce: dSaNvK +.. section: Tests + +Add subtests for all ``pickle`` protocols in ``test_zoneinfo``. + +.. + +.. bpo: 45566 +.. date: 2021-10-22-12-05-21 +.. nonce: 2gQ3ZB +.. section: Tests + +Fix ``test_frozen_pickle`` in ``test_dataclasses`` to check all ``pickle`` +versions. + +.. + +.. bpo: 43592 +.. date: 2021-10-21-17-22-26 +.. nonce: kHRsra +.. section: Tests + +:mod:`test.libregrtest` now raises the soft resource limit for the maximum +number of file descriptors when the default is too low for our test suite as +was often the case on macOS. + +.. + +.. bpo: 39679 +.. date: 2021-10-18-16-18-41 +.. nonce: F18qcE +.. section: Tests + +Add more test cases for `@functools.singledispatchmethod` when combined with +`@classmethod` or `@staticmethod`. + +.. + +.. bpo: 45410 +.. date: 2021-10-08-14-03-20 +.. nonce: Ex9xe2 +.. section: Tests + +When libregrtest spawns a worker process, stderr is now written into stdout +to keep messages order. Use a single pipe for stdout and stderr, rather than +two pipes. Previously, messages were out of order which made analysis of +buildbot logs harder Patch by Victor Stinner. + +.. + +.. bpo: 45402 +.. date: 2021-10-07-13-43-01 +.. nonce: jlQvep +.. section: Tests + +Fix test_tools.test_sundry() when Python is built out of tree: fix how the +freeze_modules.py tool locates the _freeze_module program. Patch by Victor +Stinner. + +.. + +.. bpo: 45403 +.. date: 2021-10-07-13-27-12 +.. nonce: 7QiDvw +.. section: Tests + +Fix test_sys.test_stdlib_dir() when Python is built outside the source tree: +compare normalized paths. Patch by Victor Stinner. + +.. + +.. bpo: 45400 +.. date: 2021-10-07-13-11-45 +.. nonce: h3iT7V +.. section: Tests + +Fix test_name_error_suggestions_do_not_trigger_for_too_many_locals() of +test_exceptions if a directory name contains "a1" (like "Python-3.11.0a1"): +use a stricter regular expression. Patch by Victor Stinner. + +.. + +.. bpo: 10572 +.. date: 2021-01-07-01-25-38 +.. nonce: gEEZ9z +.. section: Tests + +Rename :mod:`sqlite3` tests from ``test_sqlite`` to ``test_sqlite3``, and +relocate them to ``Lib/test/test_sqlite3``. Patch by Erlend E. Aasland. + +.. + +.. bpo: 43158 +.. date: 2021-11-01-12-51-46 +.. nonce: fghS6w +.. section: Build + +``setup.py`` now uses values from configure script to build the ``_uuid`` +extension module. Configure now detects util-linux's ``libuuid``, too. + +.. + +.. bpo: 45666 +.. date: 2021-10-29-12-54-53 +.. nonce: w2G63u +.. section: Build + +Fix warning of ``swprintf`` and ``%s`` usage in ``_testembed.c`` + +.. + +.. bpo: 45548 +.. date: 2021-10-28-14-47-22 +.. nonce: mdCBxB +.. section: Build + +``Modules/Setup`` and ``Modules/makesetup`` have been improved. The +``Setup`` file now contains working rules for all extensions. Outdated +comments have been removed. Rules defined by ``makesetup`` track +dependencies correctly. + +.. + +.. bpo: 45548 +.. date: 2021-10-24-21-49-49 +.. nonce: UWx0UC +.. section: Build + +The :mod:`math` and :mod:`cmath` implementation now require a C99 compatible +``libm`` and no longer ship with workarounds for missing acosh, asinh, +atanh, expm1, and log1p functions. + +.. + +.. bpo: 45595 +.. date: 2021-10-24-11-02-43 +.. nonce: WI_5YU +.. section: Build + +``setup.py`` and ``makesetup`` now track build dependencies on all Python +header files and module specific header files. + +.. + +.. bpo: 45571 +.. date: 2021-10-22-15-28-29 +.. nonce: yY8NsJ +.. section: Build + +``Modules/Setup`` now use ``PY_CFLAGS_NODIST`` instead of ``PY_CFLAGS`` to +compile shared modules. + +.. + +.. bpo: 45570 +.. date: 2021-10-22-14-45-40 +.. nonce: 61gM2A +.. section: Build + +:mod:`pyexpat` and :mod:`_elementtree` no longer define obsolete macros +``HAVE_EXPAT_CONFIG_H`` and ``USE_PYEXPAT_CAPI``. ``XML_POOR_ENTROPY`` is +now defined in ``expat_config.h``. + +.. + +.. bpo: 43974 +.. date: 2021-10-22-14-00-44 +.. nonce: HHZtbx +.. section: Build + +``setup.py`` no longer defines ``Py_BUILD_CORE_MODULE``. Instead every +module, that uses the internal API, defines the macro. + +.. + +.. bpo: 45548 +.. date: 2021-10-20-17-02-56 +.. nonce: BoggEf +.. section: Build + +Fill in missing entries in Modules/Setup. + +.. + +.. bpo: 45532 +.. date: 2021-10-20-16-07-39 +.. nonce: kyhvis +.. section: Build + +Update :data:`sys.version` to use ``main`` as fallback information. Patch by +Jeong YunWon. + +.. + +.. bpo: 45536 +.. date: 2021-10-20-12-42-39 +.. nonce: oQNYHB +.. section: Build + +The ``configure`` script now checks whether OpenSSL headers and libraries +provide required APIs. Most common APIs are verified. The check detects +outdated or missing OpenSSL. Failures do not stop configure. + +.. + +.. bpo: 45221 +.. date: 2021-10-18-10-25-56 +.. nonce: rnulhf +.. section: Build + +Fixed regression in handling of ``LDFLAGS`` and ``CPPFLAGS`` options where +:meth:`argparse.parse_known_args` could interpret an option as one of the +built-in command line argument, for example ``-h`` for help. + +.. + +.. bpo: 45440 +.. date: 2021-10-12-02-13-08 +.. nonce: -zYgDb +.. section: Build + +Building Python now requires a C99 ``<math.h>`` header file providing the +following functions: ``copysign()``, ``hypot()``, ``isfinite()``, +``isinf()``, ``isnan()``, ``round()``. Patch by Victor Stinner. + +.. + +.. bpo: 45405 +.. date: 2021-10-11-16-27-38 +.. nonce: iSfdW5 +.. section: Build + +Prevent ``internal configure error`` when running ``configure`` with recent +versions of non-Apple clang. Patch by David Bohman. + +.. + +.. bpo: 45433 +.. date: 2021-10-11-16-08-37 +.. nonce: pVDkMV +.. section: Build + +Avoid linking libpython with libcrypt. + +.. + +.. bpo: 43652 +.. date: 2021-11-04-00-41-50 +.. nonce: RnqV7I +.. section: Windows + +Update Tcl/Tk to 8.6.11, actually this time. The previous update incorrectly +included 8.6.10. + +.. + +.. bpo: 45337 +.. date: 2021-09-30-23-17-27 +.. nonce: qg7U_h +.. section: Windows + +venv now warns when the created environment may need to be accessed at a +different path, due to redirections, links or junctions. It also now +correctly installs or upgrades components when the alternate path is +required. + +.. + +.. bpo: 43851 +.. date: 2021-04-15-01-23-10 +.. nonce: qgU0gy +.. section: Windows + +Build SQLite ``SQLITE_OMIT_AUTOINIT`` on Windows. Patch by Erlend E. +Aasland. + +.. + +.. bpo: 44828 +.. date: 2021-10-25-02-02-21 +.. nonce: XBdXlJ +.. section: macOS + +Avoid tkinter file dialog failure on macOS 12 Monterey when using the Tk +8.6.11 provided by python.org macOS installers. Patch by Marc Culler of the +Tk project. + +.. + +.. bpo: 45495 +.. date: 2021-10-16-17-20-32 +.. nonce: ST8RFt +.. section: IDLE + +Add context keywords 'case' and 'match' to completions list. + +.. + +.. bpo: 29103 +.. date: 2021-10-20-18-41-17 +.. nonce: CMRLyq +.. section: C API + +:c:func:`PyType_FromSpec* <PyType_FromModuleAndSpec>` now copies the class +name from the spec to a buffer owned by the class, so the original can be +safely deallocated. Patch by Petr Viktorin. + +.. + +.. bpo: 45522 +.. date: 2021-10-19-13-07-46 +.. nonce: kGAwmZ +.. section: C API + +The internal freelists for frame, float, list, dict, async generators, and +context objects can now be disabled. + +.. + +.. bpo: 35134 +.. date: 2021-10-19-00-20-40 +.. nonce: Z0Zk_m +.. section: C API + +Exclude :c:func:`PyWeakref_GET_OBJECT` from the limited C API. It never +worked since the :c:type:`PyWeakReference` structure is opaque in the +limited C API. + +.. + +.. bpo: 35081 +.. date: 2021-10-15-09-29-59 +.. nonce: 2teFD3 +.. section: C API + +Move the ``interpreteridobject.h`` header file from ``Include/`` to +``Include/internal/``. It only provides private functions. Patch by Victor +Stinner. + +.. + +.. bpo: 35134 +.. date: 2021-10-15-00-11-51 +.. nonce: eX4zqy +.. section: C API + +The non-limited API files ``cellobject.h``, ``classobject.h``, +``context.h``, ``funcobject.h``, ``genobject.h`` and ``longintrepr.h`` have +been moved to the ``Include/cpython`` directory. Moreover, the ``eval.h`` +header file was removed. These files must not be included directly, as they +are already included in ``Python.h``: :ref:`Include Files <api-includes>`. +If they have been included directly, consider including ``Python.h`` +instead. Patch by Victor Stinner. + +.. + +.. bpo: 45474 +.. date: 2021-10-14-22-16-56 +.. nonce: 1OkJQh +.. section: C API + +The following items are no longer available when ``Py_LIMITED_API`` is +defined: + +* :c:func:`PyMarshal_WriteLongToFile` +* :c:func:`PyMarshal_WriteObjectToFile` +* :c:func:`PyMarshal_ReadObjectFromString` +* :c:func:`PyMarshal_WriteObjectToString` +* the ``Py_MARSHAL_VERSION`` macro + +These are not part of the :ref:`limited API <limited-api-list>`. + +Patch by Victor Stinner. + +.. + +.. bpo: 45434 +.. date: 2021-10-13-14-42-46 +.. nonce: INNEEt +.. section: C API + +Remove the ``pystrhex.h`` header file. It only contains private functions. C +extensions should only include the main ``<Python.h>`` header file. Patch by +Victor Stinner. + +.. + +.. bpo: 45440 +.. date: 2021-10-12-02-13-41 +.. nonce: Gf94rE +.. section: C API + +Remove the ``Py_FORCE_DOUBLE()`` macro. It was used by the +``Py_IS_INFINITY()`` macro. Patch by Victor Stinner. + +.. + +.. bpo: 45434 +.. date: 2021-10-11-23-03-49 +.. nonce: tsS8I_ +.. section: C API + +``<Python.h>`` no longer includes the header files ``<stdlib.h>``, +``<stdio.h>``, ``<errno.h>`` and ``<string.h>`` when the ``Py_LIMITED_API`` +macro is set to ``0x030b0000`` (Python 3.11) or higher. C extensions should +explicitly include the header files after ``#include <Python.h>``. Patch by +Victor Stinner. + +.. + +.. bpo: 41123 +.. date: 2021-10-11-22-58-33 +.. nonce: myrlIp +.. section: C API + +Remove ``Py_UNICODE_COPY()`` and ``Py_UNICODE_FILL()`` macros, deprecated +since Python 3.3. Use ``PyUnicode_CopyCharacters()`` or ``memcpy()`` +(``wchar_t*`` string), and ``PyUnicode_Fill()`` functions instead. Patch by +Victor Stinner. + +.. + +.. bpo: 45412 +.. date: 2021-10-08-15-54-07 +.. nonce: KHyJCT +.. section: C API + +Remove the following math macros using the ``errno`` variable: + +* ``Py_ADJUST_ERANGE1()`` +* ``Py_ADJUST_ERANGE2()`` +* ``Py_OVERFLOWED()`` +* ``Py_SET_ERANGE_IF_OVERFLOW()`` +* ``Py_SET_ERRNO_ON_MATH_ERROR()`` + +Patch by Victor Stinner. + +.. + +.. bpo: 45395 +.. date: 2021-10-06-15-54-40 +.. nonce: yVhdAl +.. section: C API + +Custom frozen modules (the array set to ``PyImport_FrozenModules``) are now +treated as additions, rather than replacing all the default frozen modules. +Frozen stdlib modules can still be disabled by setting the "code" field of +the custom array entry to NULL. + +.. + +.. bpo: 43760 +.. date: 2021-09-24-11-12-21 +.. nonce: Bfxd1- +.. section: C API + +Add new :c:func:`PyThreadState_EnterTracing`, and +:c:func:`PyThreadState_LeaveTracing` functions to the limited C API to +suspend and resume tracing and profiling. Patch by Victor Stinner. + +.. + +.. bpo: 44220 +.. date: 2021-05-24-22-12-40 +.. nonce: H9CUGl +.. section: C API + +:c:var:`PyStructSequence_UnnamedField` is added to the Stable ABI. diff --git a/Misc/NEWS.d/3.11.0a3.rst b/Misc/NEWS.d/3.11.0a3.rst new file mode 100644 index 00000000..41a3a4b9 --- /dev/null +++ b/Misc/NEWS.d/3.11.0a3.rst @@ -0,0 +1,1277 @@ +.. bpo: 46009 +.. date: 2021-12-08-11-06-53 +.. nonce: cL8pH0 +.. release date: 2021-12-08 +.. section: Core and Builtins + +Restore behavior from 3.9 and earlier when sending non-None to newly started +generator. In 3.9 this did not affect the state of the generator. In 3.10.0 +and 3.10.1 ``gen_func().send(0)`` is equivalent to +``gen_func().throw(TypeError(...)`` which exhausts the generator. In 3.10.2 +onward, the behavior has been reverted to that of 3.9. + +.. + +.. bpo: 46004 +.. date: 2021-12-07-11-24-24 +.. nonce: TTEU1p +.. section: Core and Builtins + +Fix the :exc:`SyntaxError` location for errors involving for loops with +invalid targets. Patch by Pablo Galindo + +.. + +.. bpo: 45711 +.. date: 2021-12-05-17-36-08 +.. nonce: 3TmTSw +.. section: Core and Builtins + +:c:func:`_PyErr_ChainStackItem` no longer normalizes ``exc_info`` (including +setting the traceback on the exception instance) because ``exc_info`` is +always normalized. + +.. + +.. bpo: 45607 +.. date: 2021-12-01-15-38-04 +.. nonce: JhuF8b +.. section: Core and Builtins + +The ``__note__`` field was added to :exc:`BaseException`. It is ``None`` by +default but can be set to a string which is added to the exception's +traceback. + +.. + +.. bpo: 45947 +.. date: 2021-12-01-14-06-36 +.. nonce: 1XPPm_ +.. section: Core and Builtins + +Place pointers to dict and values immediately before GC header. This reduces +number of dependent memory loads to access either dict or values from 3 to +1. + +.. + +.. bpo: 45915 +.. date: 2021-11-28-11-25-08 +.. nonce: TSGcLF +.. section: Core and Builtins + +``is_valid_fd`` now uses faster ``fcntl(fd, F_GETFD)`` on Linux, macOS, and +Windows. + +.. + +.. bpo: 44530 +.. date: 2021-11-26-23-26-25 +.. nonce: EZ0gel +.. section: Core and Builtins + +Reverts a change to the ``code.__new__`` :ref:`audit event <audit-events>` +from an earlier prerelease. + +.. + +.. bpo: 42268 +.. date: 2021-11-26-22-31-22 +.. nonce: 3wl-09 +.. section: Core and Builtins + +Fail the configure step if the selected compiler doesn't support memory +sanitizer. Patch by Pablo Galindo + +.. + +.. bpo: 45711 +.. date: 2021-11-25-17-51-29 +.. nonce: D2igmz +.. section: Core and Builtins + +The three values of ``exc_info`` are now always consistent with each other. +In particular, the ``type`` and ``traceback`` fields are now derived from +the exception instance. This impacts the return values of +:func:`sys.exc_info` and :c:func:`PyErr_GetExcInfo()` if the exception +instance is modified while the exception is handled, as well as +:c:func:`PyErr_SetExcInfo()`, which now ignores the ``type`` and +``traceback`` arguments provided to it. + +.. + +.. bpo: 45727 +.. date: 2021-11-24-18-24-49 +.. nonce: _xVbbo +.. section: Core and Builtins + +Refine the custom syntax error that suggests that a comma may be missing to +trigger only when the expressions are detected between parentheses or +brackets. Patch by Pablo Galindo + +.. + +.. bpo: 45885 +.. date: 2021-11-23-21-01-56 +.. nonce: 3IxeCX +.. section: Core and Builtins + +Specialized the ``COMPARE_OP`` opcode using the PEP 659 machinery. + +.. + +.. bpo: 45786 +.. date: 2021-11-23-15-25-00 +.. nonce: UdEciD +.. section: Core and Builtins + +Allocate space for the interpreter frame in the frame object, to avoid an +additional allocation when the frame object outlives the frame activation. + +.. + +.. bpo: 45614 +.. date: 2021-11-23-12-06-41 +.. nonce: fIekgI +.. section: Core and Builtins + +Fix :mod:`traceback` display for exceptions with invalid module name. + +.. + +.. bpo: 45813 +.. date: 2021-11-22-11-28-13 +.. nonce: ZMaWE2 +.. section: Core and Builtins + +Fix crash when calling coro.cr_frame.clear() after coroutine has been freed. + +.. + +.. bpo: 45811 +.. date: 2021-11-20-02-25-06 +.. nonce: B-1Gsr +.. section: Core and Builtins + +Improve the tokenizer errors when encountering invisible control characters +in the parser. Patch by Pablo Galindo + +.. + +.. bpo: 45848 +.. date: 2021-11-19-22-57-42 +.. nonce: HgVBJ5 +.. section: Core and Builtins + +Allow the parser to obtain error lines directly from encoded files. Patch by +Pablo Galindo + +.. + +.. bpo: 45709 +.. date: 2021-11-19-13-17-47 +.. nonce: H_t7ut +.. section: Core and Builtins + +Restore behavior from 3.10 when tracing an exception raised within a with +statement. + +.. + +.. bpo: 44525 +.. date: 2021-11-18-10-02-02 +.. nonce: M4xwn_ +.. section: Core and Builtins + +Adds new :opcode:`COPY_FREE_VARS` opcode, to make copying of free variables +from function to frame explicit. Helps optimization of calls to Python +function. + +.. + +.. bpo: 45829 +.. date: 2021-11-17-10-14-35 +.. nonce: 5Cf6fY +.. section: Core and Builtins + +Specialize :opcode:`BINARY_SUBSCR` for classes with a ``__getitem__`` method +implemented in Python + +.. + +.. bpo: 45826 +.. date: 2021-11-17-08-05-27 +.. nonce: OERoTm +.. section: Core and Builtins + +Fixed a crash when calling ``.with_traceback(None)`` on ``NameError``. This +occurs internally in ``unittest.TestCase.assertRaises()``. + +.. + +.. bpo: 45822 +.. date: 2021-11-16-19-41-04 +.. nonce: OT6ueS +.. section: Core and Builtins + +Fixed a bug in the parser that was causing it to not respect :pep:`263` +coding cookies when no flags are provided. Patch by Pablo Galindo + +.. + +.. bpo: 45820 +.. date: 2021-11-16-19-00-27 +.. nonce: 2X6Psr +.. section: Core and Builtins + +Fix a segfault when the parser fails without reading any input. Patch by +Pablo Galindo + +.. + +.. bpo: 45636 +.. date: 2021-11-15-13-32-54 +.. nonce: RDlTdL +.. section: Core and Builtins + +Simplify the implementation of :opcode:`BINARY_OP` by indexing into an array +of function pointers (rather than switching on the oparg). + +.. + +.. bpo: 42540 +.. date: 2021-11-15-12-08-27 +.. nonce: V2w107 +.. section: Core and Builtins + +Fix crash when :func:`os.fork` is called with an active non-default memory +allocator. + +.. + +.. bpo: 45738 +.. date: 2021-11-14-00-14-45 +.. nonce: e0cgKd +.. section: Core and Builtins + +Fix computation of error location for invalid continuation characters in the +parser. Patch by Pablo Galindo. + +.. + +.. bpo: 45636 +.. date: 2021-11-11-19-11-57 +.. nonce: 2fyIVm +.. section: Core and Builtins + +Remove an existing "fast path" for old-style string formatting, since it no +longer appears to have any measurable impact. + +.. + +.. bpo: 45753 +.. date: 2021-11-11-17-14-21 +.. nonce: nEBFcC +.. section: Core and Builtins + +Make recursion checks a bit more efficient by tracking amount of calls left +before overflow. + +.. + +.. bpo: 45773 +.. date: 2021-11-09-13-01-35 +.. nonce: POU8A4 +.. section: Core and Builtins + +Fix a compiler hang when attempting to optimize certain jump patterns. + +.. + +.. bpo: 45764 +.. date: 2021-11-09-12-19-22 +.. nonce: 8RLhWL +.. section: Core and Builtins + +The parser now gives a better error message when leaving out the opening +parenthesis ``(`` after a ``def``-statement:: + + >>> def f: + File "<stdin>", line 1 + def f: + ^ + SyntaxError: expected '(' + +.. + +.. bpo: 45609 +.. date: 2021-10-27-21-00-49 +.. nonce: L1GKPX +.. section: Core and Builtins + +Specialized the ``STORE_SUBSCR`` opcode using the PEP 659 machinery. + +.. + +.. bpo: 45636 +.. date: 2021-10-27-15-14-31 +.. nonce: K2X7QS +.. section: Core and Builtins + +Replace all numeric ``BINARY_*`` and ``INPLACE_*`` instructions with a +single :opcode:`BINARY_OP` implementation. + +.. + +.. bpo: 45582 +.. date: 2021-10-23-00-39-31 +.. nonce: YONPuo +.. section: Core and Builtins + +Path calculation (known as ``getpath``) has been reimplemented as a frozen +Python module. This should have no visible impact, but may affect +calculation of all paths referenced in :mod:`sys` and :mod:`sysconfig`. + +.. + +.. bpo: 45450 +.. date: 2021-10-12-18-22-44 +.. nonce: d9a-bX +.. section: Core and Builtins + +Improve the syntax error message for parenthesized arguments. Patch by Pablo +Galindo. + +.. + +.. bpo: 27946 +.. date: 2021-12-04-20-08-42 +.. nonce: -Vuarf +.. section: Library + +Fix possible crash when getting an attribute of +class:`xml.etree.ElementTree.Element` simultaneously with replacing the +``attrib`` dict. + +.. + +.. bpo: 45711 +.. date: 2021-12-02-17-22-06 +.. nonce: D6jsdv +.. section: Library + +Make :mod:`asyncio` normalize exceptions as soon as they are captured with +:c:func:`PyErr_Fetch`, and before they are stored as an exc_info triplet. +This brings :mod:`asyncio` in line with the rest of the codebase, where an +exc_info triplet is always normalized. + +.. + +.. bpo: 23819 +.. date: 2021-12-02-14-37-30 +.. nonce: An6vkT +.. section: Library + +Replaced asserts with exceptions in asyncio, patch by Kumar Aditya. + +.. + +.. bpo: 13236 +.. date: 2021-11-30-13-52-02 +.. nonce: FmJIkO +.. section: Library + +:class:`unittest.TextTestResult` and :class:`unittest.TextTestRunner` flush +now the output stream more often. + +.. + +.. bpo: 45917 +.. date: 2021-11-28-17-24-11 +.. nonce: J5TIrd +.. section: Library + +Added :func:`math.exp2`:, which returns 2 raised to the power of x. + +.. + +.. bpo: 37658 +.. date: 2021-11-28-15-30-34 +.. nonce: 8Hno7d +.. section: Library + +Fix issue when on certain conditions ``asyncio.wait_for()`` may allow a +coroutine to complete successfully, but fail to return the result, +potentially causing memory leaks or other issues. + +.. + +.. bpo: 45876 +.. date: 2021-11-23-15-36-56 +.. nonce: NO8Yaj +.. section: Library + +Improve the accuracy of stdev() and pstdev() in the statistics module. When +the inputs are floats or fractions, the output is a correctly rounded float + +.. + +.. bpo: 44649 +.. date: 2021-11-21-20-50-42 +.. nonce: E8M936 +.. section: Library + +Handle dataclass(slots=True) with a field that has default a default value, +but for which init=False. + +.. + +.. bpo: 45803 +.. date: 2021-11-20-17-04-25 +.. nonce: wSgFOy +.. section: Library + +Added missing kw_only parameter to dataclasses.make_dataclass(). + +.. + +.. bpo: 45837 +.. date: 2021-11-18-13-13-19 +.. nonce: aGyr1I +.. section: Library + +The :meth:`turtle.RawTurtle.settiltangle` is deprecated since Python 3.1, it +now emits a deprecation warning and will be removed in Python 3.13. + +Use :meth:`turtle.RawTurtle.tiltangle` instead. + +:meth:`turtle.RawTurtle.tiltangle` was earlier incorrectly marked as +deprecated, its docstring has been corrected. + +Patch by Hugo van Kemenade. + +.. + +.. bpo: 45831 +.. date: 2021-11-17-19-25-37 +.. nonce: 9-TojK +.. section: Library + +:mod:`faulthandler` can now write ASCII-only strings (like filenames and +function names) with a single write() syscall when dumping a traceback. It +reduces the risk of getting an unreadable dump when two threads or two +processes dump a traceback to the same file (like stderr) at the same time. +Patch by Victor Stinner. + +.. + +.. bpo: 45828 +.. date: 2021-11-17-11-40-21 +.. nonce: kQU35U +.. section: Library + +:mod:`sqlite` C callbacks now use unraisable exceptions if callback +tracebacks are enabled. Patch by Erlend E. Aasland. + +.. + +.. bpo: 41735 +.. date: 2021-11-16-18-13-49 +.. nonce: D72UY1 +.. section: Library + +Fix thread lock in ``zlib.Decompress.flush()`` method before +``PyObject_GetBuffer``. + +.. + +.. bpo: 45235 +.. date: 2021-11-11-13-03-17 +.. nonce: 8ZbkHa +.. section: Library + +Reverted an argparse bugfix that caused regression in the handling of +default arguments for subparsers. This prevented leaf level arguments from +taking precedence over root level arguments. + +.. + +.. bpo: 45754 +.. date: 2021-11-09-15-48-38 +.. nonce: c-JDto +.. section: Library + +Fix a regression in Python 3.11a1 and 3.11a2 where :mod:`sqlite3` +incorrectly would use ``SQLITE_LIMIT_LENGTH`` when checking SQL statement +lengths. Now, ``SQLITE_LIMIT_SQL_LENGTH`` is used. Patch by Erlend E. +Aasland. + +.. + +.. bpo: 45766 +.. date: 2021-11-09-09-18-06 +.. nonce: dvbcMf +.. section: Library + +Added *proportional* option to :meth:`statistics.linear_regression`. + +.. + +.. bpo: 45765 +.. date: 2021-11-09-09-04-19 +.. nonce: JVobxK +.. section: Library + +In importlib.metadata, fix distribution discovery for an empty path. + +.. + +.. bpo: 45757 +.. date: 2021-11-08-23-22-14 +.. nonce: MHZHt3 +.. section: Library + +Fix bug where :mod:`dis` produced an incorrect oparg when +:opcode:`EXTENDED_ARG` is followed by an opcode that does not use its +argument. + +.. + +.. bpo: 45644 +.. date: 2021-11-06-17-47-46 +.. nonce: ZMqHD_ +.. section: Library + +In-place JSON file formatting using ``python3 -m json.tool infile infile`` +now works correctly, previously it left the file empty. Patch by Chris +Wesseling. + +.. + +.. bpo: 45703 +.. date: 2021-11-03-13-41-49 +.. nonce: 35AagL +.. section: Library + +When a namespace package is imported before another module from the same +namespace is created/installed in a different :data:`sys.path` location +while the program is running, calling the +:func:`importlib.invalidate_caches` function will now also guarantee the new +module is noticed. + +.. + +.. bpo: 45535 +.. date: 2021-10-29-16-28-06 +.. nonce: n8NiOE +.. section: Library + +Improve output of ``dir()`` with Enums. + +.. + +.. bpo: 45664 +.. date: 2021-10-28-23-40-54 +.. nonce: 7dqtxQ +.. section: Library + +Fix :func:`types.resolve_bases` and :func:`types.new_class` for +:class:`types.GenericAlias` instance as a base. + +.. + +.. bpo: 45663 +.. date: 2021-10-28-23-11-59 +.. nonce: J90N5R +.. section: Library + +Fix :func:`dataclasses.is_dataclass` for dataclasses which are subclasses of +:class:`types.GenericAlias`. + +.. + +.. bpo: 45662 +.. date: 2021-10-28-22-58-14 +.. nonce: sJd7Ir +.. section: Library + +Fix the repr of :data:`dataclasses.InitVar` with a type alias to the +built-in class, e.g. ``InitVar[list[int]]``. + +.. + +.. bpo: 43137 +.. date: 2021-10-25-12-51-02 +.. nonce: apo7jY +.. section: Library + +Launch GNOME web browsers via gio tool instead of obsolete gvfs-open + +.. + +.. bpo: 45429 +.. date: 2021-10-25-01-22-49 +.. nonce: VaEyN9 +.. section: Library + +On Windows, :func:`time.sleep` now uses a waitable timer which supports +high-resolution timers. Patch by Donghee Na and Eryk Sun. + +.. + +.. bpo: 37295 +.. date: 2021-10-18-16-08-55 +.. nonce: wBEWH2 +.. section: Library + +Optimize :func:`math.comb` and :func:`math.perm`. + +.. + +.. bpo: 45514 +.. date: 2021-10-18-14-25-35 +.. nonce: YmlzIl +.. section: Library + +Deprecated legacy functions in :mod:`importlib.resources`. + +.. + +.. bpo: 45507 +.. date: 2021-10-18-14-00-01 +.. nonce: lDotNV +.. section: Library + +Add tests for truncated/missing trailers in gzip.decompress implementation. + +.. + +.. bpo: 45359 +.. date: 2021-10-03-22-27-35 +.. nonce: LX_uxe +.. section: Library + +Implement :pep:`585` for :class:`graphlib.TopologicalSorter`. + +.. + +.. bpo: 44733 +.. date: 2021-07-26-13-33-37 +.. nonce: 88LrP1 +.. section: Library + +Add ``max_tasks_per_child`` to +:class:`concurrent.futures.ProcessPoolExecutor`. This allows users to +specify the maximum number of tasks a single process should execute before +the process needs to be restarted. + +.. + +.. bpo: 28806 +.. date: 2021-05-24-13-48-34 +.. nonce: PkNw5D +.. section: Library + +Improve netrc library. netrc file no longer needs to contain all tokens. And +if the login name is anonymous, security check is no longer need. + +.. + +.. bpo: 43498 +.. date: 2021-04-20-14-14-16 +.. nonce: L_Hq-8 +.. section: Library + +Avoid a possible *"RuntimeError: dictionary changed size during iteration"* +when adjusting the process count of :class:`ProcessPoolExecutor`. + +.. + +.. bpo: 42158 +.. date: 2020-11-10-17-46-12 +.. nonce: OhxAiH +.. section: Library + +Add MIME types for N-quads, N-triples, Notation3 and TriG to ``mimetypes``. + +.. + +.. bpo: 30533 +.. date: 2020-06-16-18-00-56 +.. nonce: StL57t +.. section: Library + +Add :func:`inspect.getmembers_static` , it return all members without +triggering dynamic lookup via the descriptor protocol. Patch by Weipeng +Hong. + +.. + +.. bpo: 42238 +.. date: 2021-11-20-02-46-39 +.. nonce: hlfMIc +.. section: Documentation + +``make -C Doc suspicious`` will be removed soon in favor of ``make -C Doc +check``, mark it as deprecated. + +.. + +.. bpo: 45840 +.. date: 2021-11-19-02-02-32 +.. nonce: A51B2S +.. section: Documentation + +Improve cross-references in the documentation for the data model. + +.. + +.. bpo: 45640 +.. date: 2021-11-18-16-44-12 +.. nonce: lSpc2A +.. section: Documentation + +Properly marked-up grammar tokens in the documentation are now clickable and +take you to the definition of a given piece of grammar. Patch by Arthur +Milchior. + +.. + +.. bpo: 45788 +.. date: 2021-11-18-00-07-40 +.. nonce: qibUoB +.. section: Documentation + +Link doc for sys.prefix to sysconfig doc on installation paths. + +.. + +.. bpo: 45772 +.. date: 2021-11-09-13-10-55 +.. nonce: EdrM3t +.. section: Documentation + +``socket.socket`` documentation is corrected to a class from a function. + +.. + +.. bpo: 45392 +.. date: 2021-11-06-10-54-17 +.. nonce: JZnVOz +.. section: Documentation + +Update the docstring of the :class:`type` built-in to remove a redundant +line and to mention keyword arguments for the constructor. + +.. + +.. bpo: 45250 +.. date: 2021-10-22-12-09-18 +.. nonce: Iit5-Y +.. section: Documentation + +Update the documentation to note that CPython does not consistently require +iterators to define ``__iter__``. + +.. + +.. bpo: 25381 +.. date: 2021-06-21-17-51-51 +.. nonce: 7Kn-_H +.. section: Documentation + +In the extending chapter of the extending doc, update a paragraph about the +global variables containing exception information. + +.. + +.. bpo: 43905 +.. date: 2021-05-24-05-00-12 +.. nonce: tBIndE +.. section: Documentation + +Expanded :func:`~dataclasses.astuple` and :func:`~dataclasses.asdict` docs, +warning about deepcopy being applied and providing a workaround. + +.. + +.. bpo: 45695 +.. date: 2021-12-03-14-19-16 +.. nonce: QKBn2E +.. section: Tests + +Out-of-tree builds with a read-only source directory are now tested by CI. + +.. + +.. bpo: 19460 +.. date: 2021-11-28-15-25-02 +.. nonce: lr0aWs +.. section: Tests + +Add new Test for ``Lib/email/mime/nonmultipart.py::MIMENonMultipart``. + +.. + +.. bpo: 45835 +.. date: 2021-11-17-14-28-08 +.. nonce: Mgyhjx +.. section: Tests + +Fix race condition in test_queue tests with multiple "feeder" threads. + +.. + +.. bpo: 45783 +.. date: 2021-11-11-13-56-00 +.. nonce: 8k1Rng +.. section: Tests + +The test for the freeze tool now handles file moves and deletions. + +.. + +.. bpo: 45745 +.. date: 2021-11-10-12-01-28 +.. nonce: wX5B3K +.. section: Tests + +Remove the ``--findleaks`` command line option of regrtest: use the +``--fail-env-changed`` option instead. Since Python 3.7, it was a deprecated +alias to the ``--fail-env-changed`` option. + +.. + +.. bpo: 45701 +.. date: 2021-10-31-10-58-45 +.. nonce: r0LAUL +.. section: Tests + +Add tests with ``tuple`` type with :func:`functools.lru_cache` to +``test_functools``. + +.. + +.. bpo: 44035 +.. date: 2021-12-06-09-31-27 +.. nonce: BiO4XC +.. section: Build + +CI now verifies that autoconf files have been regenerated with a current and +unpatched autoconf package. + +.. + +.. bpo: 45950 +.. date: 2021-12-01-17-28-39 +.. nonce: eEVLoz +.. section: Build + +The build system now uses a :program:`_bootstrap_python` interpreter for +freezing and deepfreezing again. To speed up build process the build tools +:program:`_bootstrap_python` and :program:`_freeze_module` are no longer +build with LTO. + +.. + +.. bpo: 45881 +.. date: 2021-11-29-16-32-55 +.. nonce: 7597J6 +.. section: Build + +The :program:`configure` script now accepts ``--with-build-python`` and +``--with-freeze-module`` options to make cross compiling easier. + +.. + +.. bpo: 40280 +.. date: 2021-11-29-14-37-29 +.. nonce: UlTMR8 +.. section: Build + +Emscripten platform now uses ``.wasm`` suffix by default. + +.. + +.. bpo: 40280 +.. date: 2021-11-29-11-24-45 +.. nonce: Knx7d7 +.. section: Build + +Disable unusable core extension modules on WASM/Emscripten targets. + +.. + +.. bpo: 40280 +.. date: 2021-11-26-14-09-04 +.. nonce: ZLpwQf +.. section: Build + +``configure`` now checks for socket ``shutdown`` function. The check makes +it possible to disable ``SYS_shutdown`` with ``ac_cv_func_shutdown=no`` in +CONFIG_SITE. + +.. + +.. bpo: 40280 +.. date: 2021-11-26-09-10-19 +.. nonce: xmiMJl +.. section: Build + +``configure`` now checks for functions ``fork1, getegid, geteuid, getgid, +getppid, getuid, opendir, pipe, system, wait, ttyname``. + +.. + +.. bpo: 33393 +.. date: 2021-11-25-20-26-06 +.. nonce: 24YNtM +.. section: Build + +Update ``config.guess`` to 2021-06-03 and ``config.sub`` to 2021-08-14. +``Makefile`` now has an ``update-config`` target to make updating more +convenient. + +.. + +.. bpo: 45866 +.. date: 2021-11-25-13-53-36 +.. nonce: ZH1W8N +.. section: Build + +``make regen-all`` now produces the same output when run from a directory +other than the source tree: when building Python out of the source tree. +pegen now strips directory of the "generated by pygen from <FILENAME>" +header Patch by Victor Stinner. + +.. + +.. bpo: 40280 +.. date: 2021-11-25-10-55-03 +.. nonce: E9-gsQ +.. section: Build + +``configure`` now accepts machine ``wasm32`` or ``wasm64`` and OS ``wasi`` +or ``emscripten`` for cross building, e.g. ``wasm32-unknown-emscripten``, +``wasm32-wasi``, or ``wasm32-unknown-wasi``. + +.. + +.. bpo: 41498 +.. date: 2021-11-25-09-15-04 +.. nonce: qAk5eo +.. section: Build + +Python now compiles on platforms without ``sigset_t``. Several functions in +:mod:`signal` are not available when ``sigset_t`` is missing. + +Based on patch by Roman Yurchak for pyodide. + +.. + +.. bpo: 45881 +.. date: 2021-11-24-17-14-06 +.. nonce: GTXXLk +.. section: Build + +``setup.py`` now uses ``CC`` from environment first to discover multiarch +and cross compile paths. + +.. + +.. bpo: 45886 +.. date: 2021-11-23-23-37-49 +.. nonce: _Ulnh- +.. section: Build + +The ``_freeze_module`` program path can now be overridden on the command +line, e.g. ``make FREEZE_MODULE=../x86_64/Program/_freeze_module``. + +.. + +.. bpo: 45873 +.. date: 2021-11-23-04-28-40 +.. nonce: 9dldZ4 +.. section: Build + +Get rid of the ``_bootstrap_python`` build step. The deepfreeze.py script is +now run using ``$(PYTHON_FOR_REGEN)`` which can be Python 3.7 or newer (on +Windows, 3.8 or newer). + +.. + +.. bpo: 45847 +.. date: 2021-11-19-17-57-57 +.. nonce: 9phcpd +.. section: Build + +Port builtin hashlib extensions to ``PY_STDLIB_MOD`` macro and ``addext()``. + +.. + +.. bpo: 45723 +.. date: 2021-11-19-15-42-27 +.. nonce: vwIJWI +.. section: Build + +Add ``autoconf`` helpers for saving and restoring environment variables: + +* ``SAVE_ENV``: Save ``$CFLAGS``, ``$LDFLAGS``, ``$LIBS``, and + ``$CPPFLAGS``. +* ``RESTORE_ENV``: Restore ``$CFLAGS``, ``$LDFLAGS``, ``$LIBS``, and + ``$CPPFLAGS``. +* ``WITH_SAVE_ENV([SCRIPT])``: Run ``SCRIPT`` wrapped with ``SAVE_ENV`` and + ``RESTORE_ENV``. + +Patch by Erlend E. Aasland. + +.. + +.. bpo: 45573 +.. date: 2021-11-18-13-31-02 +.. nonce: LCjGB8 +.. section: Build + +Mandatory core modules, that are required to bootstrap Python, are now in +``Modules/Setup.bootstrap``. + +.. + +.. bpo: 45573 +.. date: 2021-11-18-12-18-43 +.. nonce: xsMZzn +.. section: Build + +``configure`` now creates ``Modules/Setup.stdlib`` with conditionally +enabled/disabled extension module lines. The file is not used, yet. + +.. + +.. bpo: 45573 +.. date: 2021-11-17-19-02-51 +.. nonce: GMNdun +.. section: Build + +``configure`` now uses a unified format to set state, compiler flags, and +linker flags in Makefile. The new macro ``PY_STDLIB_MOD`` sets three +variables that are consumed by ``Modules/Setup`` and ``setup.py``. + +.. + +.. bpo: 45816 +.. date: 2021-11-16-14-44-06 +.. nonce: nbdmVK +.. section: Build + +Python now supports building with Visual Studio 2022 (MSVC v143, VS Version +17.0). Patch by Jeremiah Vivian. + +.. + +.. bpo: 45800 +.. date: 2021-11-13-16-40-05 +.. nonce: 5Hz6nr +.. section: Build + +Settings for :mod:`pyexpat` C extension are now detected by ``configure``. +The bundled ``expat`` library is built in ``Makefile``. + +.. + +.. bpo: 45798 +.. date: 2021-11-13-10-18-22 +.. nonce: IraaTs +.. section: Build + +Settings for :mod:`decimal` internal C extension are now detected by +``configure``. The bundled ``libmpdec`` library is built in ``Makefile``. + +.. + +.. bpo: 45723 +.. date: 2021-11-10-16-13-02 +.. nonce: B5gCB1 +.. section: Build + +:program:`configure` has a new option ``--with-pkg-config`` to disable or +require pkg-config. + +.. + +.. bpo: 45774 +.. date: 2021-11-09-23-30-12 +.. nonce: Mwm3ZR +.. section: Build + +The build dependencies for :mod:`sqlite3` are now detected by ``configure`` +and ``pkg-config``. Patch by Erlend E. Aasland. + +.. + +.. bpo: 45763 +.. date: 2021-11-09-10-15-33 +.. nonce: gP-vrX +.. section: Build + +The build dependencies for :mod:`zlib`, :mod:`bz2`, and :mod:`lzma` are now +detected by ``configure``. + +.. + +.. bpo: 45747 +.. date: 2021-11-08-11-31-48 +.. nonce: AODmk_ +.. section: Build + +gdbm and dbm build dependencies are now detected by ``configure``. + +.. + +.. bpo: 45743 +.. date: 2021-11-08-08-58-06 +.. nonce: fZ8CTi +.. section: Build + +On macOS, the build system no longer passes ``search_paths_first`` to the +linker. The flag has been the default since Xcode 4 / macOS 10.6. + +.. + +.. bpo: 45723 +.. date: 2021-11-07-10-45-40 +.. nonce: AreusF +.. section: Build + +``configure.ac`` is now compatible with autoconf 2.71. Deprecated checks +``STDC_HEADERS`` and ``AC_HEADER_TIME`` have been removed. + +.. + +.. bpo: 45723 +.. date: 2021-11-07-10-36-12 +.. nonce: JNwKSG +.. section: Build + +``configure`` now prints a warning when pkg-config is missing. + +.. + +.. bpo: 45731 +.. date: 2021-11-05-20-56-29 +.. nonce: 9SDnDf +.. section: Build + +``configure --enable-loadable-sqlite-extensions`` is now handled by new +``PY_SQLITE_ENABLE_LOAD_EXTENSION`` macro instead of logic in setup.py. + +.. + +.. bpo: 45723 +.. date: 2021-11-05-15-09-49 +.. nonce: gfSxur +.. section: Build + +configure.ac now uses custom helper macros and ``AC_CACHE_CHECK`` to +simplify and speed up configure runs. + +.. + +.. bpo: 45696 +.. date: 2021-11-03-00-19-50 +.. nonce: eKs46f +.. section: Build + +Skip the marshal step for frozen modules by generating C code that produces +a set of ready-to-use code objects. This speeds up startup time by another +10% or more. + +.. + +.. bpo: 45561 +.. date: 2021-10-21-14-38-30 +.. nonce: PVqhZE +.. section: Build + +Run smelly.py tool from $(srcdir). + +.. + +.. bpo: 46105 +.. date: 2021-12-08-16-36-20 +.. nonce: t1mJ6Q +.. section: Windows + +Fixed calculation of :data:`sys.path` in a venv on Windows. + +.. + +.. bpo: 45901 +.. date: 2021-11-26-18-17-41 +.. nonce: c5IBqM +.. section: Windows + +When installed through the Microsoft Store and set as the default app for +:file:`*.py` files, command line arguments will now be passed to Python when +invoking a script without explicitly launching Python (that is, ``script.py +args`` rather than ``python script.py args``). + +.. + +.. bpo: 45616 +.. date: 2021-11-23-11-44-42 +.. nonce: K52PLZ +.. section: Windows + +Fix Python Launcher's ability to distinguish between versions 3.1 and 3.10 +when either one is explicitly requested. Previously, 3.1 would be used if +3.10 was requested but not installed, and 3.10 would be used if 3.1 was +requested but 3.10 was installed. + +.. + +.. bpo: 45850 +.. date: 2021-11-20-00-06-59 +.. nonce: q9lofz +.. section: Windows + +Implement changes to build with deep-frozen modules on Windows. Note that we +now require Python 3.10 as the "bootstrap" or "host" Python. + +.. + +.. bpo: 45732 +.. date: 2021-11-08-21-53-11 +.. nonce: idl5kx +.. section: Windows + +Updates bundled Tcl/Tk to 8.6.12. + +.. + +.. bpo: 45720 +.. date: 2021-11-05-01-05-46 +.. nonce: 47Nc5I +.. section: Windows + +Internal reference to :file:`shlwapi.dll` was dropped to help improve +startup time. This DLL will no longer be loaded at the start of every Python +process. + +.. + +.. bpo: 45732 +.. date: 2021-12-05-23-52-03 +.. nonce: -BWrnh +.. section: macOS + +Update python.org macOS installer to use Tcl/Tk 8.6.12. + +.. + +.. bpo: 39026 +.. date: 2021-11-09-15-42-11 +.. nonce: sUnYWn +.. section: C API + +Fix Python.h to build C extensions with Xcode: remove a relative include +from ``Include/cpython/pystate.h``. diff --git a/Misc/NEWS.d/3.11.0a4.rst b/Misc/NEWS.d/3.11.0a4.rst new file mode 100644 index 00000000..3dd33592 --- /dev/null +++ b/Misc/NEWS.d/3.11.0a4.rst @@ -0,0 +1,1177 @@ +.. bpo: 46070 +.. date: 2022-01-13-17-58-56 +.. nonce: q8IGth +.. release date: 2022-01-13 +.. section: Core and Builtins + +:c:func:`Py_EndInterpreter` now explicitly untracks all objects currently +tracked by the GC. Previously, if an object was used later by another +interpreter, calling :c:func:`PyObject_GC_UnTrack` on the object crashed if +the previous or the next object of the :c:type:`PyGC_Head` structure became +a dangling pointer. Patch by Victor Stinner. + +.. + +.. bpo: 46347 +.. date: 2022-01-11-13-57-00 +.. nonce: Gd8M-S +.. section: Core and Builtins + +Fix memory leak in PyEval_EvalCodeEx. + +.. + +.. bpo: 46339 +.. date: 2022-01-11-11-50-19 +.. nonce: OVumDZ +.. section: Core and Builtins + +Fix a crash in the parser when retrieving the error text for multi-line +f-strings expressions that do not start in the first line of the string. +Patch by Pablo Galindo + +.. + +.. bpo: 46331 +.. date: 2022-01-10-16-21-54 +.. nonce: h1AC-i +.. section: Core and Builtins + +Do not set line number of instruction storing doc-string. Fixes regression +introduced in 3.11 alpha. + +.. + +.. bpo: 46314 +.. date: 2022-01-10-12-34-17 +.. nonce: jId9Ky +.. section: Core and Builtins + +Remove spurious "call" event when creating a lambda function that was +accidentally introduced in 3.11a4. + +.. + +.. bpo: 46289 +.. date: 2022-01-07-23-32-03 +.. nonce: NnjpVc +.. section: Core and Builtins + +ASDL declaration of ``FormattedValue`` has changed to reflect ``conversion`` +field is not optional. + +.. + +.. bpo: 46297 +.. date: 2022-01-07-22-13-59 +.. nonce: 83ThTl +.. section: Core and Builtins + +Fixed an interpreter crash on bootup with multiple PythonPaths set in the +Windows registry. Patch by Derzsi Dániel. + +.. + +.. bpo: 46237 +.. date: 2022-01-07-19-33-05 +.. nonce: 9A6Hpq +.. section: Core and Builtins + +Fix the line number of tokenizer errors inside f-strings. Patch by Pablo +Galindo. + +.. + +.. bpo: 46263 +.. date: 2022-01-06-10-54-07 +.. nonce: 60dRZb +.. section: Core and Builtins + +We always expect the "use_frozen_modules" config to be set, now that +getpath.c was rewritten in pure Python and the logic improved. + +.. + +.. bpo: 46006 +.. date: 2022-01-05-17-13-47 +.. nonce: hdH5Vn +.. section: Core and Builtins + +Fix a regression when a type method like ``__init__()`` is modified in a +subinterpreter. Fix a regression in ``_PyUnicode_EqualToASCIIId()`` and type +``update_slot()``. Revert the change which made the Unicode dictionary of +interned strings compatible with subinterpreters: the internal interned +dictionary is shared again by all interpreters. Patch by Victor Stinner. + +.. + +.. bpo: 45923 +.. date: 2022-01-04-14-08-10 +.. nonce: rBp7r1 +.. section: Core and Builtins + +Add RESUME opcode. This is a logical no-op. It is emitted by the compiler +anywhere a Python function can be entered. It is used by the interpreter to +perform tracing and optimizer checks. + +.. + +.. bpo: 46208 +.. date: 2022-01-04-01-53-35 +.. nonce: i00Vz5 +.. section: Core and Builtins + +Fix the regression of os.path.normpath("A/../../B") not returning expected +"../B" but "B". + +.. + +.. bpo: 46240 +.. date: 2022-01-03-23-31-25 +.. nonce: 8lGjeK +.. section: Core and Builtins + +Correct the error message for unclosed parentheses when the tokenizer +doesn't reach the end of the source when the error is reported. Patch by +Pablo Galindo + +.. + +.. bpo: 46009 +.. date: 2022-01-03-11-36-34 +.. nonce: QZGrov +.. section: Core and Builtins + +Remove the ``GEN_START`` opcode. + +.. + +.. bpo: 46235 +.. date: 2022-01-02-23-55-13 +.. nonce: gUjp2v +.. section: Core and Builtins + +Certain sequence multiplication operations like ``[0] * 1_000`` are now +faster due to reference-counting optimizations. Patch by Dennis Sweeney. + +.. + +.. bpo: 46221 +.. date: 2022-01-01-14-23-57 +.. nonce: 7oGp-I +.. section: Core and Builtins + +:opcode:`PREP_RERAISE_STAR` no longer pushes ``lasti`` to the stack. + +.. + +.. bpo: 46202 +.. date: 2021-12-30-11-06-27 +.. nonce: IKx4v6 +.. section: Core and Builtins + +Remove :opcode:`POP_EXCEPT_AND_RERAISE` and replace it by an equivalent +sequence of other opcodes. + +.. + +.. bpo: 46085 +.. date: 2021-12-30-00-23-41 +.. nonce: bDuJqu +.. section: Core and Builtins + +Fix iterator cache mechanism of :class:`OrderedDict`. + +.. + +.. bpo: 46055 +.. date: 2021-12-24-20-21-45 +.. nonce: R0QMVQ +.. section: Core and Builtins + +Speed up shifting operation involving integers less than +:c:macro:`PyLong_BASE`. Patch by Xinhang Xu. + +.. + +.. bpo: 46110 +.. date: 2021-12-18-02-37-07 +.. nonce: B6hAfu +.. section: Core and Builtins + +Add a maximum recursion check to the PEG parser to avoid stack overflow. +Patch by Pablo Galindo + +.. + +.. bpo: 46107 +.. date: 2021-12-16-23-27-05 +.. nonce: 7q5an0 +.. section: Core and Builtins + +Fix bug where :meth:`ExceptionGroup.split` and +:meth:`ExceptionGroup.subgroup` did not copy the exception group's +``__note__`` field to the parts. + +.. + +.. bpo: 45711 +.. date: 2021-12-15-15-17-04 +.. nonce: QK4QrB +.. section: Core and Builtins + +The interpreter state's representation of handled exceptions (a.k.a +exc_info, or _PyErr_StackItem) now has only the ``exc_value`` field, +``exc_type`` and ``exc_traceback`` have been removed as their values can be +derived from ``exc_value``. + +.. + +.. bpo: 44525 +.. date: 2021-12-13-17-12-16 +.. nonce: 4-FiSf +.. section: Core and Builtins + +Replace the four call bytecode instructions which one pre-call instruction +and two call instructions. + +Removes ``CALL_FUNCTION``, ``CALL_FUNCTION_KW``, ``CALL_METHOD`` and +``CALL_METHOD_KW``. + +Adds ``CALL_NO_KW`` and ``CALL_KW`` call instructions, and +``PRECALL_METHOD`` prefix for pairing with ``LOAD_METHOD``. + +.. + +.. bpo: 46039 +.. date: 2021-12-13-17-01-13 +.. nonce: TrCBbF +.. section: Core and Builtins + +Remove the ``YIELD_FROM`` instruction and replace it with the ``SEND`` +instruction which performs the same operation, but without the loop. + +.. + +.. bpo: 45635 +.. date: 2021-12-12-15-52-41 +.. nonce: ADVaPT +.. section: Core and Builtins + +The code called from :c:func:`_PyErr_Display` was refactored to improve +error handling. It now exits immediately upon an unrecoverable error. + +.. + +.. bpo: 46054 +.. date: 2021-12-12-05-30-21 +.. nonce: 2P-foG +.. section: Core and Builtins + +Fix parser error when parsing non-utf8 characters in source files. Patch by +Pablo Galindo. + +.. + +.. bpo: 46042 +.. date: 2021-12-11-17-40-34 +.. nonce: aqYxku +.. section: Core and Builtins + +Improve the location of the caret in :exc:`SyntaxError` exceptions emitted +by the symbol table. Patch by Pablo Galindo. + +.. + +.. bpo: 46049 +.. date: 2021-12-11-13-49-19 +.. nonce: 9dNto2 +.. section: Core and Builtins + +Ensure :file:`._pth` files work as intended on platforms other than Windows. + +.. + +.. bpo: 46048 +.. date: 2021-12-11-13-14-42 +.. nonce: _-OGD9 +.. section: Core and Builtins + +Fixes parsing of :file:`._pth` files on startup so that single-character +paths are correctly read. + +.. + +.. bpo: 37971 +.. date: 2021-12-10-13-42-17 +.. nonce: 6BC1Tx +.. section: Core and Builtins + +Fix a bug where the line numbers given in a traceback when a decorator +application raised an exception were wrong. + +.. + +.. bpo: 46031 +.. date: 2021-12-10-09-10-32 +.. nonce: rM7JOX +.. section: Core and Builtins + +Add :opcode:`POP_JUMP_IF_NOT_NONE` and :opcode:`POP_JUMP_IF_NONE` opcodes to +speed up conditional jumps. + +.. + +.. bpo: 45654 +.. date: 2021-12-09-11-57-43 +.. nonce: MZc7ei +.. section: Core and Builtins + +Deepfreeze :mod:`runpy`, patch by Kumar Aditya. + +.. + +.. bpo: 46025 +.. date: 2021-12-09-11-41-35 +.. nonce: pkEvW9 +.. section: Core and Builtins + +Fix a crash in the :mod:`atexit` module involving functions that unregister +themselves before raising exceptions. Patch by Pablo Galindo. + +.. + +.. bpo: 46000 +.. date: 2021-12-07-11-42-44 +.. nonce: v_ru3k +.. section: Core and Builtins + +Improve compatibility of the :mod:`curses` module with NetBSD curses. + +.. + +.. bpo: 44525 +.. date: 2021-12-07-11-04-21 +.. nonce: 6OWCgr +.. section: Core and Builtins + +Specialize the CALL_FUNCTION instruction for calls to builtin types with a +single argument. Speeds up ``range(x)``, ``list(x)``, and specifically +``type(obj)``. + +.. + +.. bpo: 42918 +.. date: 2021-12-06-15-32-12 +.. nonce: Czpgtg +.. section: Core and Builtins + +Fix bug where the built-in :func:`compile` function did not always raise a +:exc:`SyntaxError` when passed multiple statements in 'single' mode. Patch +by Weipeng Hong. + +.. + +.. bpo: 45953 +.. date: 2021-12-01-11-54-27 +.. nonce: 2znR0E +.. section: Core and Builtins + +The main interpreter in _PyRuntimeState.interpreters is now statically +allocated (as part of _PyRuntime). Likewise for the initial thread state of +each interpreter. This means less allocation during runtime init, as well +as better memory locality for these key state objects. + +.. + +.. bpo: 45292 +.. date: 2021-11-22-13-05-32 +.. nonce: pfEouJ +.. section: Core and Builtins + +Complete the :pep:`654` implementation: add ``except*``. + +.. + +.. bpo: 43413 +.. date: 2021-05-30-16-37-47 +.. nonce: vYFPPC1 +.. section: Core and Builtins + +Revert changes in ``set.__init__``. Subclass of :class:`set` needs to define +a ``__init__()`` method if it defines a ``__new__()`` method with additional +keyword parameters. + +.. + +.. bpo: 43931 +.. date: 2021-04-24-15-39-23 +.. nonce: zpChDi +.. section: Core and Builtins + +Added the :c:data:`Py_Version` constant which bears the same value as +:c:macro:`PY_VERSION_HEX`. Patch by Gabriele N. Tornetta. + +.. + +.. bpo: 46342 +.. date: 2022-01-11-04-28-09 +.. nonce: 5QVEH1 +.. section: Library + +The ``@typing.final`` decorator now sets the ``__final__`` attribute on the +decorated object to allow runtime introspection. Patch by Jelle Zijlstra. + +.. + +.. bpo: 46328 +.. date: 2022-01-10-11-53-15 +.. nonce: 6i9Wvq +.. section: Library + +Added the :meth:`sys.exception` method which returns the active exception +instance. + +.. + +.. bpo: 46307 +.. date: 2022-01-10-07-51-43 +.. nonce: SKvOIY +.. section: Library + +Add :meth:`string.Template.is_valid` and +:meth:`string.Template.get_identifiers` methods. + +.. + +.. bpo: 46306 +.. date: 2022-01-08-13-53-25 +.. nonce: 1_es8z +.. section: Library + +Assume that :class:`types.CodeType` always has +:attr:`types.CodeType.co_firstlineno` in :mod:`doctest`. + +.. + +.. bpo: 40479 +.. date: 2022-01-07-15-20-19 +.. nonce: EKfr3F +.. section: Library + +Fix :mod:`hashlib` *usedforsecurity* option to work correctly with OpenSSL +3.0.0 in FIPS mode. + +.. + +.. bpo: 46070 +.. date: 2022-01-07-13-51-22 +.. nonce: -axLUW +.. section: Library + +Fix possible segfault when importing the :mod:`asyncio` module from +different sub-interpreters in parallel. Patch by Erlend E. Aasland. + +.. + +.. bpo: 46244 +.. date: 2022-01-06-21-31-14 +.. nonce: hjyfJj +.. section: Library + +Removed ``__slots__`` from :class:`typing.ParamSpec` and +:class:`typing.TypeVar`. They served no purpose. Patch by Arie Bovenberg. + +.. + +.. bpo: 46278 +.. date: 2022-01-06-13-38-00 +.. nonce: wILA80 +.. section: Library + +Reflect ``context`` argument in ``AbstractEventLoop.call_*()`` methods. Loop +implementations already support it. + +.. + +.. bpo: 46269 +.. date: 2022-01-05-18-16-13 +.. nonce: K16Z1S +.. section: Library + +Remove special-casing of ``__new__`` in :meth:`enum.Enum.__dir__`. + +.. + +.. bpo: 46266 +.. date: 2022-01-05-12-48-18 +.. nonce: ACQCgX +.. section: Library + +Improve day constants in :mod:`calendar`. + +Now all constants (`MONDAY` ... `SUNDAY`) are documented, tested, and added +to ``__all__``. + +.. + +.. bpo: 46257 +.. date: 2022-01-04-11-04-20 +.. nonce: _o2ADe +.. section: Library + +Optimized the mean, variance, and stdev functions in the statistics module. +If the input is an iterator, it is consumed in a single pass rather than +eating memory by conversion to a list. The single pass algorithm is about +twice as fast as the previous two pass code. + +.. + +.. bpo: 41011 +.. date: 2022-01-03-21-03-50 +.. nonce: uULmGi +.. section: Library + +Added two new variables to *pyvenv.cfg* which is generated by :mod:`venv` +module: *executable* for the executable and *command* for the command line +used to create the environment. + +.. + +.. bpo: 46239 +.. date: 2022-01-03-12-59-20 +.. nonce: ySVSEy +.. section: Library + +Improve error message when importing :mod:`asyncio.windows_events` on +non-Windows. + +.. + +.. bpo: 46238 +.. date: 2022-01-03-12-19-10 +.. nonce: lANhCi +.. section: Library + +Reuse ``_winapi`` constants in ``asyncio.windows_events``. + +.. + +.. bpo: 46222 +.. date: 2022-01-01-17-34-32 +.. nonce: s2fzZU +.. section: Library + +Adding ``SF_NOCACHE`` sendfile constant for FreeBSD for the posixmodule. + +.. + +.. bpo: 37295 +.. date: 2021-12-27-15-52-28 +.. nonce: s3LPo0 +.. section: Library + +Add fast path for ``0 <= k <= n <= 67`` for :func:`math.comb`. + +.. + +.. bpo: 46176 +.. date: 2021-12-25-11-11-21 +.. nonce: EOY9wd +.. section: Library + +Adding the ``MAP_STACK`` constant for the mmap module. + +.. + +.. bpo: 43424 +.. date: 2021-12-23-14-36-58 +.. nonce: d9x2JZ +.. section: Library + +Deprecate :attr:`webbrowser.MacOSXOSAScript._name` and use ``name`` instead. + +.. + +.. bpo: 45321 +.. date: 2021-12-19-00-00-48 +.. nonce: OyuhaY +.. section: Library + +Added missing error codes to module ``xml.parsers.expat.errors``. + +.. + +.. bpo: 46125 +.. date: 2021-12-18-18-29-07 +.. nonce: LLmcox +.. section: Library + +Refactor tests to test traversable API directly. Includes changes from +importlib 5.4.0. + +.. + +.. bpo: 46118 +.. date: 2021-12-17-16-27-44 +.. nonce: euAy0E +.. section: Library + +Moved importlib.resources and its related functionality to a package. + +.. + +.. bpo: 37578 +.. date: 2021-12-17-13-22-37 +.. nonce: _tluuR +.. section: Library + +Add *include_hidden* parameter to :func:`~glob.glob` and :func:`~glob.iglob` +to match hidden files and directories when using special characters like +``*``, ``**``, ``?`` and ``[]``. + +.. + +.. bpo: 20369 +.. date: 2021-12-17-12-06-40 +.. nonce: zzLuBz +.. section: Library + +:func:`concurrent.futures.wait` no longer blocks forever when given +duplicate Futures. Patch by Kumar Aditya. + +.. + +.. bpo: 46105 +.. date: 2021-12-16-14-30-36 +.. nonce: pprB1K +.. section: Library + +Honor spec when generating requirement specs with urls and extras +(importlib_metadata 4.8.3). + +.. + +.. bpo: 44893 +.. date: 2021-12-16-13-54-55 +.. nonce: I7aLiW +.. section: Library + +EntryPoint objects are no longer tuples. Recommended means to access is by +attribute ('.name', '.group') or accessor ('.load()'). Access by index is +deprecated and will raise deprecation warning. + +.. + +.. bpo: 22815 +.. date: 2021-12-16-12-54-21 +.. nonce: 0NRH8s +.. section: Library + +Print unexpected successes together with failures and errors in summary in +:class:`unittest.TextTestResult`. + +.. + +.. bpo: 22047 +.. date: 2021-12-15-19-24-54 +.. nonce: gBV4vT +.. section: Library + +Calling :meth:`add_argument_group` on an argument group is deprecated. +Calling :meth:`add_argument_group` or :meth:`add_mutually_exclusive_group` +on a mutually exclusive group is deprecated. + +These features were never supported and do not always work correctly. The +functions exist on the API by accident through inheritance and will be +removed in the future. + +.. + +.. bpo: 26952 +.. date: 2021-12-14-13-18-45 +.. nonce: hjhISq +.. section: Library + +:mod:`argparse` raises :exc:`ValueError` with clear message when trying to +render usage for an empty mutually exclusive group. Previously it raised a +cryptic :exc:`IndexError`. + +.. + +.. bpo: 45615 +.. date: 2021-12-13-15-51-16 +.. nonce: hVx83Q +.. section: Library + +Functions in the :mod:`traceback` module raise :exc:`TypeError` rather than +:exc:`AttributeError` when an exception argument is not of type +:exc:`BaseException`. + +.. + +.. bpo: 16594 +.. date: 2021-12-12-13-41-47 +.. nonce: yfC7L4 +.. section: Library + +Add allow allow_reuse_port flag in socketserver. + +.. + +.. bpo: 27718 +.. date: 2021-12-11-22-51-30 +.. nonce: MgQiGl +.. section: Library + +Fix help for the :mod:`signal` module. Some functions (e.g. ``signal()`` and +``getsignal()``) were omitted. + +.. + +.. bpo: 46032 +.. date: 2021-12-11-15-45-07 +.. nonce: HmciLT +.. section: Library + +The ``registry()`` method of :func:`functools.singledispatch` functions +checks now the first argument or the first parameter annotation and raises a +TypeError if it is not supported. Previously unsupported "types" were +ignored (e.g. ``typing.List[int]``) or caused an error at calling time (e.g. +``list[int]``). + +.. + +.. bpo: 46014 +.. date: 2021-12-10-03-13-57 +.. nonce: 3xYdST +.. section: Library + +Add ability to use ``typing.Union`` and ``types.UnionType`` as dispatch +argument to ``functools.singledispatch``. Patch provided by Yurii Karabas. + +.. + +.. bpo: 27062 +.. date: 2021-12-09-11-50-32 +.. nonce: R5vii6 +.. section: Library + +Add :attr:`__all__` to :mod:`inspect`, patch by Kumar Aditya. + +.. + +.. bpo: 46018 +.. date: 2021-12-09-00-44-42 +.. nonce: hkTI7v +.. section: Library + +Ensure that :func:`math.expm1` does not raise on underflow. + +.. + +.. bpo: 46016 +.. date: 2021-12-08-19-15-03 +.. nonce: s9PuyF +.. section: Library + +Adding :attr:`F_DUP2FD` and :attr:`F_DUP2FD_CLOEXEC` constants from FreeBSD +into the fcntl module. + +.. + +.. bpo: 45755 +.. date: 2021-12-07-21-55-22 +.. nonce: bRqKGa +.. section: Library + +:mod:`typing` generic aliases now reveal the class attributes of the +original generic class when passed to ``dir()``. This was the behavior up to +Python 3.6, but was changed in 3.7-3.9. + +.. + +.. bpo: 45874 +.. date: 2021-12-02-11-55-45 +.. nonce: dtJIsN +.. section: Library + +The empty query string, consisting of no query arguments, is now handled +correctly in ``urllib.parse.parse_qsl``. This caused problems before when +strict parsing was enabled. + +.. + +.. bpo: 44674 +.. date: 2021-11-29-19-37-20 +.. nonce: NijWLt +.. section: Library + +Change how dataclasses disallows mutable default values. It used to use a +list of known types (list, dict, set). Now it disallows unhashable objects +to be defaults. It's using unhashability as a proxy for mutability. Patch +by Eric V. Smith, idea by Raymond Hettinger. + +.. + +.. bpo: 23882 +.. date: 2021-11-24-19-09-14 +.. nonce: _tctCv +.. section: Library + +Remove namespace package (PEP 420) support from unittest discovery. It was +introduced in Python 3.4 but has been broken since Python 3.7. + +.. + +.. bpo: 25066 +.. date: 2021-11-24-12-25-42 +.. nonce: YIcIkn +.. section: Library + +Added a :meth:`__repr__` method to :class:`multiprocessing.Event` objects, +patch by Kumar Aditya. + +.. + +.. bpo: 45643 +.. date: 2021-10-28-11-40-59 +.. nonce: jeiPiX +.. section: Library + +Added :const:`signal.SIGSTKFLT` on platforms where this signal is defined. + +.. + +.. bpo: 44092 +.. date: 2021-05-19-12-35-49 +.. nonce: hiSlI5 +.. section: Library + +Fetch across rollback no longer raises :exc:`~sqlite3.InterfaceError`. +Instead we leave it to the SQLite library to handle these cases. Patch by +Erlend E. Aasland. + +.. + +.. bpo: 42413 +.. date: 2020-11-26-10-23-46 +.. nonce: HFikOl +.. section: Library + +Replace ``concurrent.futures.TimeoutError`` and ``asyncio.TimeoutError`` +with builtin :exc:`TimeoutError`, keep these names as deprecated aliases. + +.. + +.. bpo: 46196 +.. date: 2021-12-30-19-12-24 +.. nonce: UvQ8Sq +.. section: Documentation + +Document method :meth:`cmd.Cmd.columnize`. + +.. + +.. bpo: 46120 +.. date: 2021-12-21-12-45-57 +.. nonce: PE0DmJ +.. section: Documentation + +State that ``|`` is preferred for readability over ``Union`` in the +:mod:`typing` docs. + +.. + +.. bpo: 46109 +.. date: 2021-12-16-21-13-55 +.. nonce: 0-RNzu +.. section: Documentation + +Extracted ``importlib.resources`` and ``importlib.resources.abc`` +documentation into separate files. + +.. + +.. bpo: 19737 +.. date: 2021-11-28-22-43-21 +.. nonce: cOOubB +.. section: Documentation + +Update the documentation for the :func:`globals` function. + +.. + +.. bpo: 46296 +.. date: 2022-01-08-00-00-38 +.. nonce: vqxgTm +.. section: Tests + +Add a test case for :mod:`enum` with ``_use_args_ == True`` and +``_member_type_ == object``. + +.. + +.. bpo: 46205 +.. date: 2022-01-07-14-06-12 +.. nonce: dnc2OC +.. section: Tests + +Fix hang in runtest_mp due to race condition + +.. + +.. bpo: 46263 +.. date: 2022-01-06-15-45-34 +.. nonce: bJXek6 +.. section: Tests + +Fix test_capi on FreeBSD 14-dev: instruct jemalloc to not fill freed memory +with junk byte. + +.. + +.. bpo: 46262 +.. date: 2022-01-05-01-38-45 +.. nonce: MhiLWP +.. section: Tests + +Cover ``ValueError`` path in tests for :meth:`enum.Flag._missing_`. + +.. + +.. bpo: 46150 +.. date: 2021-12-23-13-42-15 +.. nonce: RhtADs +.. section: Tests + +Now ``fakename`` in ``test_pathlib.PosixPathTest.test_expanduser`` is +checked to be non-existent. + +.. + +.. bpo: 46129 +.. date: 2021-12-19-12-20-57 +.. nonce: I3MunH +.. section: Tests + +Rewrite ``asyncio.locks`` tests with +:class:`unittest.IsolatedAsyncioTestCase` usage. + +.. + +.. bpo: 23819 +.. date: 2021-12-19-08-44-32 +.. nonce: 9ueiII +.. section: Tests + +Fixed :mod:`asyncio` tests in python optimized mode. Patch by Kumar Aditya. + +.. + +.. bpo: 46114 +.. date: 2021-12-17-14-46-19 +.. nonce: 9iyZ_9 +.. section: Tests + +Fix test case for OpenSSL 3.0.1 version. OpenSSL 3.0 uses ``0xMNN00PP0L``. + +.. + +.. bpo: 44133 +.. date: 2022-01-12-13-42-16 +.. nonce: NgyNAh +.. section: Build + +When Python is configured with :option:`--without-static-libpython`, the +Python static library (libpython.a) is no longer built. Patch by Victor +Stinner. + +.. + +.. bpo: 44133 +.. date: 2022-01-12-13-34-52 +.. nonce: HYCNXb +.. section: Build + +When Python is built without :option:`--enable-shared`, the ``python`` +program is now linked to object files, rather than being linked to the +Python static library (libpython.a), to make sure that all symbols are +exported. Previously, the linker omitted some symbols like the +:c:func:`Py_FrozenMain` function. Patch by Victor Stinner. + +.. + +.. bpo: 40280 +.. date: 2022-01-12-10-22-23 +.. nonce: 5maBz8 +.. section: Build + +The ``configure`` script has a new option ``--with-emscripten-target`` to +select browser or node as Emscripten build target. + +.. + +.. bpo: 46315 +.. date: 2022-01-09-15-48-49 +.. nonce: NdCRLu +.. section: Build + +Added and fixed ``#ifdef HAVE_FEATURE`` checks for functionality that is not +available on WASI platform. + +.. + +.. bpo: 45723 +.. date: 2022-01-07-08-33-45 +.. nonce: uq2nBU +.. section: Build + +Fixed a regression in ``configure`` check for :func:`select.epoll`. + +.. + +.. bpo: 46263 +.. date: 2022-01-05-02-58-10 +.. nonce: xiv8NU +.. section: Build + +``configure`` no longer sets ``MULTIARCH`` on FreeBSD platforms. + +.. + +.. bpo: 46106 +.. date: 2021-12-20-07-10-41 +.. nonce: 5qcv3L +.. section: Build + +Updated OpenSSL to 1.1.1m in Windows builds, macOS installer builds, and CI. +Patch by Kumar Aditya. + +.. + +.. bpo: 46088 +.. date: 2021-12-16-14-18-07 +.. nonce: 8UUuAd +.. section: Build + +Automatically detect or install bootstrap Python runtime when building from +Visual Studio. + +.. + +.. bpo: 46072 +.. date: 2021-12-15-10-37-44 +.. nonce: GgeAU3 +.. section: Build + +Add a --with-pystats configure option to turn on internal statistics +gathering. + +.. + +.. bpo: 40280 +.. date: 2021-12-13-21-03-52 +.. nonce: b7NG4Y +.. section: Build + +A new directory ``Tools/wasm`` contains WebAssembly-related helpers like +``config.site`` override for wasm32-emscripten, wasm assets generator to +bundle the stdlib, and a README. + +.. + +.. bpo: 46023 +.. date: 2021-12-09-10-25-11 +.. nonce: PLpNB6 +.. section: Build + +:program:`makesetup` no longer builds extensions that have been marked as +*disabled*. This allows users to disable modules in ``Modules/Setup.local``. + +.. + +.. bpo: 45949 +.. date: 2021-12-02-23-21-18 +.. nonce: OTSo9X +.. section: Build + +Use pure Python ``freeze_module`` for all but importlib bootstrap files. +``--with-freeze-module`` :program:`configure` option is no longer needed for +cross builds. + +.. + +.. bpo: 46217 +.. date: 2022-01-07-22-55-11 +.. nonce: tgJEsB +.. section: Windows + +Removed parameter that is unsupported on Windows 8.1 and early Windows 10 +and may have caused build or runtime failures. + +.. + +.. bpo: 40477 +.. date: 2022-01-02-21-56-53 +.. nonce: W3nnM6 +.. section: macOS + +The Python Launcher app for macOS now properly launches scripts and, if +necessary, the Terminal app when running on recent macOS releases. + +.. + +.. bpo: 46236 +.. date: 2022-01-05-10-16-16 +.. nonce: pcmVQw +.. section: C API + +Fix a bug in :c:func:`PyFunction_GetAnnotations` that caused it to return a +``tuple`` instead of a ``dict``. + +.. + +.. bpo: 46140 +.. date: 2021-12-21-22-56-36 +.. nonce: dvXkYK +.. section: C API + +:c:func:`PyBuffer_GetPointer`, :c:func:`PyBuffer_FromContiguous`, +:c:func:`PyBuffer_ToContiguous` and :c:func:`PyMemoryView_FromBuffer` now +take buffer info by ``const Py_buffer *`` instead of ``Py_buffer *``, as +they do not need mutability. :c:func:`PyBuffer_FromContiguous` also now +takes the source buffer as ``const void *``, and similarly +:c:func:`PyBuffer_GetPointer` takes the strides as ``const Py_ssize_t *``. + +.. + +.. bpo: 45855 +.. date: 2021-12-12-10-09-02 +.. nonce: MVsTDj +.. section: C API + +Document that the *no_block* argument to :c:func:`PyCapsule_Import` is a +no-op now. + +.. + +.. bpo: 45855 +.. date: 2021-12-11-08-41-36 +.. nonce: Lq2_gR +.. section: C API + +Replaced deprecated usage of :c:func:`PyImport_ImportModuleNoBlock` with +:c:func:`PyImport_ImportModule` in stdlib modules. Patch by Kumar Aditya. + +.. + +.. bpo: 46007 +.. date: 2021-12-08-12-41-51 +.. nonce: sMgDLz +.. section: C API + +The :c:func:`PyUnicode_CHECK_INTERNED` macro has been excluded from the +limited C API. It was never usable there, because it used internal +structures which are not available in the limited C API. Patch by Victor +Stinner. diff --git a/Misc/NEWS.d/3.11.0a5.rst b/Misc/NEWS.d/3.11.0a5.rst new file mode 100644 index 00000000..08d94e82 --- /dev/null +++ b/Misc/NEWS.d/3.11.0a5.rst @@ -0,0 +1,986 @@ +.. bpo: 45773 +.. date: 2022-02-01-14-30-56 +.. nonce: Up77LD +.. release date: 2022-02-03 +.. section: Core and Builtins + +Remove two invalid "peephole" optimizations from the bytecode compiler. + +.. + +.. bpo: 46564 +.. date: 2022-02-01-10-23-21 +.. nonce: 6Xc2_H +.. section: Core and Builtins + +Do not create frame objects when creating :class:`super` object. Patch by +Kumar Aditya. + +.. + +.. bpo: 45885 +.. date: 2022-02-01-01-17-28 +.. nonce: CjyNf_ +.. section: Core and Builtins + +Added more fined-grained specialization failure stats regarding the +``COMPARE_OP`` bytecode. + +.. + +.. bpo: 44977 +.. date: 2022-01-30-18-23-08 +.. nonce: BQV_zS +.. section: Core and Builtins + +The delegation of :func:`int` to :meth:`__trunc__` is now deprecated. +Calling ``int(a)`` when ``type(a)`` implements :meth:`__trunc__` but not +:meth:`__int__` or :meth:`__index__` now raises a :exc:`DeprecationWarning`. + +.. + +.. bpo: 46458 +.. date: 2022-01-27-10-49-34 +.. nonce: 5Gm3Gv +.. section: Core and Builtins + +Reorder code emitted by the compiler for a :keyword:`try`-:keyword:`except` +block so that the :keyword:`else` block's code immediately follows the +:keyword:`try` body (without a jump). This is more optimal for the happy +path. + +.. + +.. bpo: 46527 +.. date: 2022-01-25-19-34-55 +.. nonce: mQLNPk +.. section: Core and Builtins + +Allow passing ``iterable`` as a keyword argument to :func:`enumerate` again. +Patch by Jelle Zijlstra. + +.. + +.. bpo: 46528 +.. date: 2022-01-25-17-40-07 +.. nonce: 2Qmni9 +.. section: Core and Builtins + +Replace several stack manipulation instructions (``DUP_TOP``, +``DUP_TOP_TWO``, ``ROT_TWO``, ``ROT_THREE``, ``ROT_FOUR``, and ``ROT_N``) +with new :opcode:`COPY` and :opcode:`SWAP` instructions. + +.. + +.. bpo: 46329 +.. date: 2022-01-25-11-44-17 +.. nonce: SEhynE +.. section: Core and Builtins + +Use two or three bytecodes to implement most calls. + +Calls without named arguments are implemented as a sequence of two +instructions: ``PRECALL; CALL``. Calls with named arguments are implemented +as a sequence of three instructions: ``PRECALL; KW_NAMES; CALL``. There are +two different ``PRECALL`` instructions: ``PRECALL_FUNTION`` and +``PRECALL_METHOD``. The latter pairs with ``LOAD_METHOD``. + +This partition into pre-call and call allows better specialization, and thus +better performance ultimately. + +There is no change in semantics. + +.. + +.. bpo: 46503 +.. date: 2022-01-24-21-24-41 +.. nonce: 4UrPsE +.. section: Core and Builtins + +Fix an assert when parsing some invalid \N escape sequences in f-strings. + +.. + +.. bpo: 46431 +.. date: 2022-01-24-16-58-01 +.. nonce: N6mKAx +.. section: Core and Builtins + +Improve error message on invalid calls to +:meth:`BaseExceptionGroup.__new__`. + +.. + +.. bpo: 46476 +.. date: 2022-01-24-15-39-34 +.. nonce: cvP1Mr +.. section: Core and Builtins + +Fix memory leak in code objects generated by deepfreeze. Patch by Kumar +Aditya. + +.. + +.. bpo: 46481 +.. date: 2022-01-23-06-56-33 +.. nonce: X_FfnB +.. section: Core and Builtins + +Speed up calls to :meth:`weakref.ref.__call__` by using the :pep:`590` +``vectorcall`` calling convention. Patch by Donghee Na. + +.. + +.. bpo: 46417 +.. date: 2022-01-22-14-39-23 +.. nonce: 3U5SfN +.. section: Core and Builtins + +Fix a race condition on setting a type ``__bases__`` attribute: the internal +function ``add_subclass()`` now gets the ``PyTypeObject.tp_subclasses`` +member after calling :c:func:`PyWeakref_NewRef` which can trigger a garbage +collection which can indirectly modify ``PyTypeObject.tp_subclasses``. Patch +by Victor Stinner. + +.. + +.. bpo: 46417 +.. date: 2022-01-21-12-24-14 +.. nonce: i3IqMf +.. section: Core and Builtins + +``python -X showrefcount`` now shows the total reference count after +clearing and destroyed the main Python interpreter. Previously, it was shown +before. Patch by Victor Stinner. + +.. + +.. bpo: 43683 +.. date: 2022-01-20-17-13-49 +.. nonce: BqQ26Z +.. section: Core and Builtins + +Add ASYNC_GEN_WRAP opcode to wrap the value to be yielded in async +generators. Removes the need to special case async generators in the +``YIELD_VALUE`` instruction. + +.. + +.. bpo: 46407 +.. date: 2022-01-17-23-12-01 +.. nonce: 2_5a7R +.. section: Core and Builtins + +Optimize some modulo operations in ``Objects/longobject.c``. Patch by +Jeremiah Vivian. + +.. + +.. bpo: 46409 +.. date: 2022-01-17-12-57-27 +.. nonce: HouS6m +.. section: Core and Builtins + +Add new ``RETURN_GENERATOR`` bytecode to make generators. Simplifies calling +Python functions in the VM, as they no longer any need to special case +generator functions. + +Also add ``JUMP_NO_INTERRUPT`` bytecode that acts like ``JUMP_ABSOLUTE``, +but does not check for interrupts. + +.. + +.. bpo: 46406 +.. date: 2022-01-16-15-40-11 +.. nonce: g0mke- +.. section: Core and Builtins + +The integer division ``//`` implementation has been optimized to better let +the compiler understand its constraints. It can be 20% faster on the amd64 +platform when dividing an int by a value smaller than ``2**30``. + +.. + +.. bpo: 46383 +.. date: 2022-01-14-20-55-34 +.. nonce: v8MTl4 +.. section: Core and Builtins + +Fix invalid signature of ``_zoneinfo``'s ``module_free`` function to resolve +a crash on wasm32-emscripten platform. + +.. + +.. bpo: 46361 +.. date: 2022-01-12-17-15-17 +.. nonce: mgI_j_ +.. section: Core and Builtins + +Ensure that "small" integers created by :meth:`int.from_bytes` and +:class:`decimal.Decimal` are properly cached. + +.. + +.. bpo: 46161 +.. date: 2021-12-23-12-32-45 +.. nonce: EljBmu +.. section: Core and Builtins + +Fix the class building error when the arguments are constants and +CALL_FUNCTION_EX is used. + +.. + +.. bpo: 46028 +.. date: 2021-12-16-15-04-58 +.. nonce: zfWacB +.. section: Core and Builtins + +Fixes calculation of :data:`sys._base_executable` when inside a virtual +environment that uses symlinks with different binary names than the base +environment provides. + +.. + +.. bpo: 46091 +.. date: 2021-12-16-00-24-00 +.. nonce: rJ_e_e +.. section: Core and Builtins + +Correctly calculate indentation levels for lines with whitespace character +that are ended by line continuation characters. Patch by Pablo Galindo + +.. + +.. bpo: 30512 +.. date: 2021-12-12-00-49-19 +.. nonce: nU9E9V +.. section: Core and Builtins + +Add CAN Socket support for NetBSD. + +.. + +.. bpo: 46045 +.. date: 2021-12-11-11-36-48 +.. nonce: sfThay +.. section: Core and Builtins + +Do not use POSIX semaphores on NetBSD + +.. + +.. bpo: 44024 +.. date: 2021-05-04-21-55-49 +.. nonce: M9m8Qd +.. section: Core and Builtins + +Improve the exc:`TypeError` message for non-string second arguments passed +to the built-in functions :func:`getattr` and :func:`hasattr`. Patch by Géry +Ogam. + +.. + +.. bpo: 46624 +.. date: 2022-02-03-12-07-41 +.. nonce: f_Qqh0 +.. section: Library + +Restore support for non-integer arguments of :func:`random.randrange` and +:func:`random.randint`. + +.. + +.. bpo: 46591 +.. date: 2022-01-31-15-40-38 +.. nonce: prBD1M +.. section: Library + +Make the IDLE doc URL on the About IDLE dialog clickable. + +.. + +.. bpo: 46565 +.. date: 2022-01-28-19-48-31 +.. nonce: bpZXO4 +.. section: Library + +Remove loop variables that are leaking into modules' namespaces. + +.. + +.. bpo: 46553 +.. date: 2022-01-28-08-47-53 +.. nonce: f7Uc96 +.. section: Library + +In :func:`typing.get_type_hints`, support evaluating bare stringified +``ClassVar`` annotations. Patch by Gregory Beauregard. + +.. + +.. bpo: 46544 +.. date: 2022-01-27-13-30-02 +.. nonce: oFDVWj +.. section: Library + +Don't leak ``x`` & ``uspace`` intermediate vars in +:class:`textwrap.TextWrapper`. + +.. + +.. bpo: 46487 +.. date: 2022-01-27-12-24-38 +.. nonce: UDkN2z +.. section: Library + +Add the ``get_write_buffer_limits`` method to +:class:`asyncio.transports.WriteTransport` and to the SSL transport. + +.. + +.. bpo: 45173 +.. date: 2022-01-27-11-16-59 +.. nonce: wreRF2 +.. section: Library + +Note the configparser deprecations will be removed in Python 3.12. + +.. + +.. bpo: 45162 +.. date: 2022-01-26-23-58-48 +.. nonce: 4Jmg_j +.. section: Library + +The deprecated :mod:`unittest` APIs removed in 3.11a1 have been temporarily +restored to be removed in 3.12 while cleanups in external projects go in. + +.. + +.. bpo: 46539 +.. date: 2022-01-26-20-36-30 +.. nonce: 23iW1d +.. section: Library + +In :func:`typing.get_type_hints`, support evaluating stringified +``ClassVar`` and ``Final`` annotations inside ``Annotated``. Patch by +Gregory Beauregard. + +.. + +.. bpo: 46510 +.. date: 2022-01-25-10-59-41 +.. nonce: PM5svI +.. section: Library + +Add missing test for :class:`types.TracebackType` and +:class:`types.FrameType`. Calculate them directly from the caught exception +without calling :func:`sys.exc_info`. + +.. + +.. bpo: 46491 +.. date: 2022-01-24-23-55-30 +.. nonce: jmIKHo +.. section: Library + +Allow :data:`typing.Annotated` to wrap :data:`typing.Final` and +:data:`typing.ClassVar`. Patch by Gregory Beauregard. + +.. + +.. bpo: 46483 +.. date: 2022-01-24-13-00-09 +.. nonce: 9XnmKp +.. section: Library + +Remove :meth:`~object.__class_getitem__` from :class:`pathlib.PurePath` as +this class was not supposed to be generic. + +.. + +.. bpo: 46436 +.. date: 2022-01-23-19-37-00 +.. nonce: Biz1p9 +.. section: Library + +Fix command-line option ``-d``/``--directory`` in module :mod:`http.server` +which is ignored when combined with command-line option ``--cgi``. Patch by +Géry Ogam. + +.. + +.. bpo: 41403 +.. date: 2022-01-23-18-04-45 +.. nonce: SgoHqV +.. section: Library + +Make :meth:`mock.patch` raise a :exc:`TypeError` with a relevant error +message on invalid arg. Previously it allowed a cryptic +:exc:`AttributeError` to escape. + +.. + +.. bpo: 46474 +.. date: 2022-01-22-14-49-10 +.. nonce: eKQhvx +.. section: Library + +In ``importlib.metadata.EntryPoint.pattern``, avoid potential REDoS by +limiting ambiguity in consecutive whitespace. + +.. + +.. bpo: 46474 +.. date: 2022-01-22-14-45-46 +.. nonce: 2DUC62 +.. section: Library + +Removed private method from ``importlib.metadata.Path``. Sync with +importlib_metadata 4.10.0. + +.. + +.. bpo: 46470 +.. date: 2022-01-22-13-17-35 +.. nonce: MnNhgU +.. section: Library + +Remove unused branch from ``typing._remove_dups_flatten`` + +.. + +.. bpo: 46469 +.. date: 2022-01-22-05-05-08 +.. nonce: plUab5 +.. section: Library + +:mod:`asyncio` generic classes now return :class:`types.GenericAlias` in +``__class_getitem__`` instead of the same class. + +.. + +.. bpo: 41906 +.. date: 2022-01-21-18-19-45 +.. nonce: YBaquj +.. section: Library + +Support passing filter instances in the ``filters`` values of ``handlers`` +and ``loggers`` in the dictionary passed to +:func:`logging.config.dictConfig`. + +.. + +.. bpo: 46422 +.. date: 2022-01-20-10-35-50 +.. nonce: 1UAEHL +.. section: Library + +Use ``dis.Positions`` in ``dis.Instruction`` instead of a regular ``tuple``. + +.. + +.. bpo: 46434 +.. date: 2022-01-20-10-35-10 +.. nonce: geS-aP +.. section: Library + +:mod:`pdb` now gracefully handles ``help`` when :attr:`__doc__` is missing, +for example when run with pregenerated optimized ``.pyc`` files. + +.. + +.. bpo: 43869 +.. date: 2022-01-18-17-24-21 +.. nonce: NayN12 +.. section: Library + +Python uses the same time Epoch on all platforms. Add an explicit unit test +to ensure that it's the case. Patch by Victor Stinner. + +.. + +.. bpo: 46414 +.. date: 2022-01-17-10-00-02 +.. nonce: Ld0b_y +.. section: Library + +Add :func:`typing.reveal_type`. Patch by Jelle Zijlstra. + +.. + +.. bpo: 40280 +.. date: 2022-01-16-14-07-14 +.. nonce: LtFHfF +.. section: Library + +:mod:`subprocess` now imports Windows-specific imports when ``msvcrt`` +module is available, and POSIX-specific imports on all other platforms. This +gives a clean exception when ``_posixsubprocess`` is not available (e.g. +Emscripten browser target). + +.. + +.. bpo: 40066 +.. date: 2022-01-13-11-41-24 +.. nonce: 1QuVli +.. section: Library + +``IntEnum``, ``IntFlag``, and ``StrEnum`` use the mixed-in type for their +``str()`` and ``format()`` output. + +.. + +.. bpo: 46316 +.. date: 2022-01-09-15-04-56 +.. nonce: AMTyd0 +.. section: Library + +Optimize :meth:`pathlib.Path.iterdir` by removing an unnecessary check for +special entries. + +.. + +.. bpo: 29688 +.. date: 2022-01-05-03-21-21 +.. nonce: W06bSH +.. section: Library + +Document :meth:`pathlib.Path.absolute` (which has always existed). + +.. + +.. bpo: 43012 +.. date: 2022-01-05-03-09-29 +.. nonce: RVhLIL +.. section: Library + +The pathlib module's obsolete and internal ``_Accessor`` class has been +removed to prepare the terrain for upcoming enhancements to the module. + +.. + +.. bpo: 46258 +.. date: 2022-01-04-18-05-25 +.. nonce: DYgwRo +.. section: Library + +Speed up :func:`math.isqrt` for small positive integers by replacing two +division steps with a lookup table. + +.. + +.. bpo: 46242 +.. date: 2022-01-03-16-25-06 +.. nonce: f4l_CL +.. section: Library + +Improve error message when creating a new :class:`enum.Enum` type +subclassing an existing ``Enum`` with ``_member_names_`` using +:meth:`enum.Enum.__call__`. + +.. + +.. bpo: 43118 +.. date: 2021-12-29-14-42-09 +.. nonce: BoVi_5 +.. section: Library + +Fix a bug in :func:`inspect.signature` that was causing it to fail on some +subclasses of classes with a ``__text_signature__`` referencing module +globals. Patch by Weipeng Hong. + +.. + +.. bpo: 26552 +.. date: 2021-12-29-13-42-55 +.. nonce: 1BqeAn +.. section: Library + +Fixed case where failing :func:`asyncio.ensure_future` did not close the +coroutine. Patch by Kumar Aditya. + +.. + +.. bpo: 21987 +.. date: 2021-12-28-11-55-10 +.. nonce: avBK-p +.. section: Library + +Fix an issue with :meth:`tarfile.TarFile.getmember` getting a directory name +with a trailing slash. + +.. + +.. bpo: 46124 +.. date: 2021-12-18-18-41-30 +.. nonce: ESPrb7 +.. section: Library + +Update :mod:`zoneinfo` to rely on importlib.resources traversable API. + +.. + +.. bpo: 46103 +.. date: 2021-12-16-23-42-54 +.. nonce: LMnZAN +.. section: Library + +Now :func:`inspect.getmembers` only gets :attr:`__bases__` attribute from +class type. Patch by Weipeng Hong. + +.. + +.. bpo: 46080 +.. date: 2021-12-15-06-29-00 +.. nonce: AuQpLt +.. section: Library + +Fix exception in argparse help text generation if a +:class:`argparse.BooleanOptionalAction` argument's default is +``argparse.SUPPRESS`` and it has ``help`` specified. Patch by Felix +Fontein. + +.. + +.. bpo: 44791 +.. date: 2021-07-31-23-18-50 +.. nonce: 4jFdpO +.. section: Library + +Fix substitution of :class:`~typing.ParamSpec` in +:data:`~typing.Concatenate` with different parameter expressions. +Substitution with a list of types returns now a tuple of types. Substitution +with ``Concatenate`` returns now a ``Concatenate`` with concatenated lists +of arguments. + +.. + +.. bpo: 46463 +.. date: 2022-01-21-21-33-48 +.. nonce: fBbdTG +.. section: Documentation + +Fixes :file:`escape4chm.py` script used when building the CHM documentation +file + +.. + +.. bpo: 43478 +.. date: 2022-02-03-00-21-32 +.. nonce: 0nfcam +.. section: Tests + +Mocks can no longer be provided as the specs for other Mocks. As a result, +an already-mocked object cannot be passed to `mock.Mock()`. This can uncover +bugs in tests since these Mock-derived Mocks will always pass certain tests +(e.g. isinstance) and builtin assert functions (e.g. +assert_called_once_with) will unconditionally pass. + +.. + +.. bpo: 46616 +.. date: 2022-02-02-18-14-38 +.. nonce: URvBtE +.. section: Tests + +Ensures ``test_importlib.test_windows`` cleans up registry keys after +completion. + +.. + +.. bpo: 44359 +.. date: 2022-02-02-02-24-04 +.. nonce: kPPSmN +.. section: Tests + +test_ftplib now silently ignores socket errors to prevent logging unhandled +threading exceptions. Patch by Victor Stinner. + +.. + +.. bpo: 46600 +.. date: 2022-02-01-17-13-53 +.. nonce: FMCk8Z +.. section: Tests + +Fix test_gdb.test_pycfunction() for Python built with ``clang -Og``. +Tolerate inlined functions in the gdb traceback. Patch by Victor Stinner. + +.. + +.. bpo: 46542 +.. date: 2022-01-31-17-34-13 +.. nonce: RTMm1T +.. section: Tests + +Fix a Python crash in test_lib2to3 when using Python built in debug mode: +limit the recursion limit. Patch by Victor Stinner. + +.. + +.. bpo: 46576 +.. date: 2022-01-29-12-37-53 +.. nonce: -prRaV +.. section: Tests + +test_peg_generator now disables compiler optimization when testing +compilation of its own C extensions to significantly speed up the testing on +non-debug builds of CPython. + +.. + +.. bpo: 46542 +.. date: 2022-01-28-01-17-10 +.. nonce: xRLTdj +.. section: Tests + +Fix ``test_json`` tests checking for :exc:`RecursionError`: modify these +tests to use ``support.infinite_recursion()``. Patch by Victor Stinner. + +.. + +.. bpo: 13886 +.. date: 2022-01-17-13-10-04 +.. nonce: 5mZH4b +.. section: Tests + +Skip test_builtin PTY tests on non-ASCII characters if the readline module +is loaded. The readline module changes input() behavior, but test_builtin is +not intented to test the readline module. Patch by Victor Stinner. + +.. + +.. bpo: 40280 +.. date: 2022-01-16-14-11-57 +.. nonce: fNnFfx +.. section: Tests + +Add :func:`test.support.requires_fork` decorators to mark tests that require +a working :func:`os.fork`. + +.. + +.. bpo: 40280 +.. date: 2022-01-14-23-22-41 +.. nonce: nHLWoD +.. section: Tests + +Add :func:`test.support.requires_subprocess` decorator to mark tests which +require working :mod:`subprocess` module or ``os.spawn*``. The +wasm32-emscripten platform has no support for processes. + +.. + +.. bpo: 46126 +.. date: 2021-12-18-22-23-50 +.. nonce: 0LH3Yb +.. section: Tests + +Disable 'descriptions' when running tests internally. + +.. + +.. bpo: 46602 +.. date: 2022-02-02-02-06-07 +.. nonce: 8GaOZ2 +.. section: Build + +Tidied up configure.ac so that conftest.c is truncated rather than appended. +This assists in the case where the 'rm' of conftest.c fails to happen +between tests. Downstream issues such as a clobbered SOABI can result. + +.. + +.. bpo: 46600 +.. date: 2022-02-01-14-07-37 +.. nonce: NNLnfj +.. section: Build + +Fix the test checking if the C compiler supports ``-Og`` option in the +``./configure`` script to also use ``-Og`` on clang which supports it. Patch +by Victor Stinner. + +.. + +.. bpo: 38472 +.. date: 2022-01-26-22-59-12 +.. nonce: RxfLho +.. section: Build + +Fix GCC detection in setup.py when cross-compiling. The C compiler is now +run with LC_ALL=C. Previously, the detection failed with a German locale. + +.. + +.. bpo: 46513 +.. date: 2022-01-25-12-32-37 +.. nonce: mPm9B4 +.. section: Build + +:program:`configure` no longer uses ``AC_C_CHAR_UNSIGNED`` macro and +``pyconfig.h`` no longer defines reserved symbol ``__CHAR_UNSIGNED__``. + +.. + +.. bpo: 46471 +.. date: 2022-01-22-11-06-23 +.. nonce: 03snrE +.. section: Build + +Use global singletons for single byte bytes objects in deepfreeze. + +.. + +.. bpo: 46443 +.. date: 2022-01-20-05-27-07 +.. nonce: udCVII +.. section: Build + +Deepfreeze now uses cached small integers as it saves some space for common +small integers. + +.. + +.. bpo: 46429 +.. date: 2022-01-19-04-36-15 +.. nonce: y0OtVL +.. section: Build + +Merge all deep-frozen files into one for space savings. Patch by Kumar +Aditya. + +.. + +.. bpo: 45569 +.. date: 2022-01-09-11-24-54 +.. nonce: zCIENy +.. section: Build + +The build now defaults to using 30-bit digits for Python integers. +Previously either 15-bit or 30-bit digits would be selected, depending on +the platform. 15-bit digits may still be selected using the +``--enable-big-digits=15`` option to the ``configure`` script, or by +defining ``PYLONG_BITS_IN_DIGIT`` in ``pyconfig.h``. + +.. + +.. bpo: 45925 +.. date: 2022-01-08-12-43-31 +.. nonce: 38F3NO +.. section: Build + +Update Windows installer to use SQLite 3.37.2. + +.. + +.. bpo: 43112 +.. date: 2021-02-10-17-54-04 +.. nonce: H5Lat6 +.. section: Build + +Detect musl libc as a separate SOABI (tagged as ``linux-musl``). + +.. + +.. bpo: 33125 +.. date: 2022-01-25-14-48-39 +.. nonce: 5WyY_J +.. section: Windows + +The traditional EXE/MSI based installer for Windows is now available for +ARM64 + +.. + +.. bpo: 46362 +.. date: 2022-01-13-22-31-09 +.. nonce: f2cuEb +.. section: Windows + +os.path.abspath("C:\CON") is now fixed to return "\\.\CON", not the same +path. The regression was true of all legacy DOS devices such as COM1, LPT1, +or NUL. + +.. + +.. bpo: 44934 +.. date: 2021-09-01-10-48-11 +.. nonce: W1xPATH +.. section: Windows + +The installer now offers a command-line only option to add the installation +directory to the end of :envvar:`PATH` instead of at the start. + +.. + +.. bpo: 45925 +.. date: 2022-01-26-12-04-09 +.. nonce: yBSiYO +.. section: macOS + +Update macOS installer to SQLite 3.37.2. + +.. + +.. bpo: 45296 +.. date: 2022-01-26-19-33-55 +.. nonce: LzZKdU +.. section: IDLE + +Clarify close, quit, and exit in IDLE. In the File menu, 'Close' and 'Exit' +are now 'Close Window' (the current one) and 'Exit' is now 'Exit IDLE' (by +closing all windows). In Shell, 'quit()' and 'exit()' mean 'close Shell'. +If there are no other windows, this also exits IDLE. + +.. + +.. bpo: 40170 +.. date: 2022-01-27-02-51-22 +.. nonce: uPolek +.. section: C API + +Remove the ``PyHeapType_GET_MEMBERS()`` macro. It was exposed in the public +C API by mistake, it must only be used by Python internally. Use the +``PyTypeObject.tp_members`` member instead. Patch by Victor Stinner. + +.. + +.. bpo: 40170 +.. date: 2022-01-27-02-37-18 +.. nonce: XxQB0i +.. section: C API + +Move _Py_GetAllocatedBlocks() and _PyObject_DebugMallocStats() private +functions to the internal C API. Patch by Victor Stinner. + +.. + +.. bpo: 46433 +.. date: 2022-01-19-16-51-54 +.. nonce: Er9ApS +.. section: C API + +The internal function _PyType_GetModuleByDef now correctly handles +inheritance patterns involving static types. + +.. + +.. bpo: 45459 +.. date: 2021-10-18-16-54-24 +.. nonce: Y1pEZs +.. section: C API + +:c:type:`Py_buffer` and various ``Py_buffer`` related functions are now part +of the limited API and stable ABI. + +.. + +.. bpo: 14916 +.. date: 2020-09-11-02-50-41 +.. nonce: QN1Y03 +.. section: C API + +Fixed bug in the tokenizer that prevented ``PyRun_InteractiveOne`` from +parsing from the provided FD. diff --git a/Misc/NEWS.d/3.11.0a6.rst b/Misc/NEWS.d/3.11.0a6.rst new file mode 100644 index 00000000..52055b3f --- /dev/null +++ b/Misc/NEWS.d/3.11.0a6.rst @@ -0,0 +1,1206 @@ +.. bpo: 46940 +.. date: 2022-03-06-20-16-13 +.. nonce: _X47Hx +.. release date: 2022-03-07 +.. section: Core and Builtins + +Avoid overriding :exc:`AttributeError` metadata information for nested +attribute access calls. Patch by Pablo Galindo. + +.. + +.. bpo: 46927 +.. date: 2022-03-05-12-23-58 +.. nonce: URbHBi +.. section: Core and Builtins + +Include the type's name in the error message for subscripting non-generic +types. + +.. + +.. bpo: 46921 +.. date: 2022-03-05-00-43-22 +.. nonce: tyuPeB +.. section: Core and Builtins + +Support vectorcall for ``super()``. Patch by Ken Jin. + +.. + +.. bpo: 46841 +.. date: 2022-03-03-14-31-53 +.. nonce: agf-3X +.. section: Core and Builtins + +Fix incorrect handling of inline cache entries when specializing +:opcode:`BINARY_OP`. + +.. + +.. bpo: 46841 +.. date: 2022-03-03-12-36-15 +.. nonce: apPev2 +.. section: Core and Builtins + +Use an oparg to simplify the construction of helpful error messages in +:opcode:`GET_AWAITABLE`. + +.. + +.. bpo: 46903 +.. date: 2022-03-03-12-02-41 +.. nonce: OzgaFZ +.. section: Core and Builtins + +Make sure that str subclasses can be used as attribute names for instances +with virtual dictionaries. Fixes regression in 3.11alpha + +.. + +.. bpo: 46841 +.. date: 2022-03-03-10-46-13 +.. nonce: 7CkuZx +.. section: Core and Builtins + +Add more detailed specialization failure stats for :opcode:`COMPARE_OP` +followed by :opcode:`EXTENDED_ARG`. + +.. + +.. bpo: 46891 +.. date: 2022-03-02-15-04-08 +.. nonce: aIAgTD +.. section: Core and Builtins + +Fix bug introduced during 3.11alpha where subclasses of ``types.ModuleType`` +with ``__slots__`` were not initialized correctly, resulting in an +interpreter crash. + +.. + +.. bpo: 46841 +.. date: 2022-03-01-17-47-58 +.. nonce: inYQlU +.. section: Core and Builtins + +Use inline caching for :opcode:`LOAD_ATTR`, :opcode:`LOAD_METHOD`, and +:opcode:`STORE_ATTR`. + +.. + +.. bpo: 46841 +.. date: 2022-02-28-15-46-36 +.. nonce: MDQoty +.. section: Core and Builtins + +Use inline cache for :opcode:`BINARY_SUBSCR`. + +.. + +.. bpo: 46841 +.. date: 2022-02-28-12-01-04 +.. nonce: r60AMJ +.. section: Core and Builtins + +Use inline caching for :opcode:`COMPARE_OP`. + +.. + +.. bpo: 46864 +.. date: 2022-02-26-19-26-36 +.. nonce: EmLgFp +.. section: Core and Builtins + +Deprecate ``PyBytesObject.ob_shash``. It will be removed in Python 3.13. + +.. + +.. bpo: 46841 +.. date: 2022-02-25-15-18-40 +.. nonce: tmLpgC +.. section: Core and Builtins + +Use inline caching for :opcode:`UNPACK_SEQUENCE`. + +.. + +.. bpo: 46845 +.. date: 2022-02-25-14-57-21 +.. nonce: TUvaMG +.. section: Core and Builtins + +Reduces dict size by removing hash value from hash table when all inserted +keys are Unicode. For example, ``sys.getsizeof(dict.fromkeys("abcdefg"))`` +becomes 272 bytes from 352 bytes on 64bit platform. + +.. + +.. bpo: 46841 +.. date: 2022-02-25-13-18-18 +.. nonce: 86QiQu +.. section: Core and Builtins + +Use inline cache for :opcode:`LOAD_GLOBAL`. + +.. + +.. bpo: 46852 +.. date: 2022-02-25-02-01-42 +.. nonce: _3zg8D +.. section: Core and Builtins + +Rename the private undocumented ``float.__set_format__()`` method to +``float.__setformat__()`` to fix a typo introduced in Python 3.7. The method +is only used by test_float. Patch by Victor Stinner. + +.. + +.. bpo: 46852 +.. date: 2022-02-25-01-42-45 +.. nonce: nkRDvV +.. section: Core and Builtins + +Remove the undocumented private ``float.__set_format__()`` method, +previously known as ``float.__setformat__()`` in Python 3.7. Its docstring +said: "You probably don't want to use this function. It exists mainly to be +used in Python's test suite." Patch by Victor Stinner. + +.. + +.. bpo: 40116 +.. date: 2022-02-24-16-34-17 +.. nonce: AeVGG2 +.. section: Core and Builtins + +Fix regression that dict.update(other) may don't respect iterate order of +other when other is key sharing dict. + +.. + +.. bpo: 46712 +.. date: 2022-02-24-07-50-43 +.. nonce: pw7vQV +.. section: Core and Builtins + +Share global string identifiers in deep-frozen modules. + +.. + +.. bpo: 46430 +.. date: 2022-02-24-07-33-29 +.. nonce: c91TAg +.. section: Core and Builtins + +Fix memory leak in interned strings of deep-frozen modules. + +.. + +.. bpo: 46841 +.. date: 2022-02-23-18-17-30 +.. nonce: fns8HB +.. section: Core and Builtins + +Store :opcode:`BINARY_OP` caches inline using a new :opcode:`CACHE` +instruction. + +.. + +.. bpo: 45107 +.. date: 2022-02-23-15-26-02 +.. nonce: axcgHn +.. section: Core and Builtins + +Specialize ``LOAD_METHOD`` for instances with a dict. + +.. + +.. bpo: 44337 +.. date: 2022-02-22-17-19-45 +.. nonce: XA-egu +.. section: Core and Builtins + +Reduce the memory usage of specialized :opcode:`LOAD_ATTR` and +:opcode:`STORE_ATTR` instructions. + +.. + +.. bpo: 46729 +.. date: 2022-02-22-17-18-36 +.. nonce: ZwGTFq +.. section: Core and Builtins + +Add number of sub-exceptions to :meth:`BaseException.__str__`. + +.. + +.. bpo: 45885 +.. date: 2022-02-22-15-48-32 +.. nonce: W2vkaI +.. section: Core and Builtins + +Don't un-adapt :opcode:`COMPARE_OP` when collecting specialization stats. + +.. + +.. bpo: 46329 +.. date: 2022-02-22-14-03-56 +.. nonce: RX_AzJ +.. section: Core and Builtins + +Fix specialization stats gathering for :opcode:`PRECALL` instructions. + +.. + +.. bpo: 46794 +.. date: 2022-02-22-12-07-53 +.. nonce: 6WvJ9o +.. section: Core and Builtins + +Bump up the libexpat version into 2.4.6 + +.. + +.. bpo: 46823 +.. date: 2022-02-22-05-14-25 +.. nonce: z9NZC9 +.. section: Core and Builtins + +Implement a specialized combined opcode +``LOAD_FAST__LOAD_ATTR_INSTANCE_VALUE``. Patch by Dennis Sweeney. + +.. + +.. bpo: 46820 +.. date: 2022-02-21-21-55-23 +.. nonce: 4RfUZh +.. section: Core and Builtins + +Fix parsing a numeric literal immediately (without spaces) followed by "not +in" keywords, like in ``1not in x``. Now the parser only emits a warning, +not a syntax error. + +.. + +.. bpo: 46329 +.. date: 2022-02-21-10-29-20 +.. nonce: cbkt7u +.. section: Core and Builtins + +Move ``KW_NAMES`` before ``PRECALL`` instruction in call sequence. Change +``operand`` of ``CALL`` to match ``PRECALL`` for easier specialization. + +.. + +.. bpo: 46808 +.. date: 2022-02-20-23-10-14 +.. nonce: vouNSF +.. section: Core and Builtins + +Remove the ``NEXT_BLOCK`` macro from compile.c, and make the compiler +automatically generate implicit blocks when they are needed. + +.. + +.. bpo: 46329 +.. date: 2022-02-16-13-15-16 +.. nonce: 8aIuz9 +.. section: Core and Builtins + +Add ``PUSH_NULL`` instruction. This is used as a prefix when evaluating a +callable, so that the stack has the same shape for methods and other calls. +``PRECALL_FUNCTION`` and ``PRECALL_METHOD`` are merged into a single +``PRECALL`` instruction. + +There is no change in semantics. + +.. + +.. bpo: 46762 +.. date: 2022-02-15-20-26-46 +.. nonce: 1H7vab +.. section: Core and Builtins + +Fix an assert failure in debug builds when a '<', '>', or '=' is the last +character in an f-string that's missing a closing right brace. + +.. + +.. bpo: 46730 +.. date: 2022-02-14-21-04-43 +.. nonce: rYJ1w5 +.. section: Core and Builtins + +Message of AttributeError caused by getting, setting or deleting a property +without the corresponding function now mentions that the attribute is in +fact a property and also specifies type of the class that it belongs to. + +.. + +.. bpo: 46724 +.. date: 2022-02-14-14-44-06 +.. nonce: jym_K6 +.. section: Core and Builtins + +Make sure that all backwards jumps use the ``JUMP_ABSOLUTE`` instruction, +rather than ``JUMP_FORWARD`` with an argument of ``(2**32)+offset``. + +.. + +.. bpo: 46732 +.. date: 2022-02-12-11-16-40 +.. nonce: 3Z_qxd +.. section: Core and Builtins + +Correct the docstring for the :meth:`~object.__bool__` method. Patch by Jelle +Zijlstra. + +.. + +.. bpo: 46072 +.. date: 2022-02-11-13-47-58 +.. nonce: PDS6Ke +.. section: Core and Builtins + +Add more detailed specialization failure statistics for :opcode:`BINARY_OP`. + +.. + +.. bpo: 46707 +.. date: 2022-02-10-03-13-18 +.. nonce: xeSEh0 +.. section: Core and Builtins + +Avoid potential exponential backtracking when producing some syntax errors +involving lots of brackets. Patch by Pablo Galindo. + +.. + +.. bpo: 46323 +.. date: 2022-02-10-02-29-12 +.. nonce: HK_cs0 +.. section: Core and Builtins + +:mod:`ctypes` now allocates memory on the stack instead of on the heap to +pass arguments while calling a Python callback function. Patch by Donghee +Na. + +.. + +.. bpo: 45923 +.. date: 2022-02-09-20-21-43 +.. nonce: tJ4gDX +.. section: Core and Builtins + +Add a quickened form of :opcode:`RESUME` that skips quickening checks. + +.. + +.. bpo: 46702 +.. date: 2022-02-09-16-36-11 +.. nonce: LcaEuC +.. section: Core and Builtins + +Specialize :opcode:`UNPACK_SEQUENCE` for :class:`tuple` and :class:`list` +unpackings. + +.. + +.. bpo: 46072 +.. date: 2022-02-07-14-38-54 +.. nonce: 6ebLyN +.. section: Core and Builtins + +Opcode pair stats are now gathered with ``--enable-pystats``. Defining +``DYNAMIC_EXECUTION_PROFILE`` or ``DXPAIRS`` no longer has any effect. + +.. + +.. bpo: 46675 +.. date: 2022-02-07-14-33-45 +.. nonce: ZPbdMp +.. section: Core and Builtins + +Allow more than 16 items in a split dict before it is combined. The limit is +now 254. + +.. + +.. bpo: 40479 +.. date: 2022-02-06-23-08-30 +.. nonce: zED3Zu +.. section: Core and Builtins + +Add a missing call to ``va_end()`` in ``Modules/_hashopenssl.c``. + +.. + +.. bpo: 46323 +.. date: 2022-02-05-14-46-21 +.. nonce: FC1OJg +.. section: Core and Builtins + +Use :c:func:`PyObject_Vectorcall` while calling ctypes callback function. +Patch by Donghee Na. + +.. + +.. bpo: 46615 +.. date: 2022-02-04-04-33-18 +.. nonce: puArY9 +.. section: Core and Builtins + +When iterating over sets internally in ``setobject.c``, acquire strong +references to the resulting items from the set. This prevents crashes in +corner-cases of various set operations where the set gets mutated. + +.. + +.. bpo: 45828 +.. date: 2022-01-27-14-20-18 +.. nonce: kzk4fl +.. section: Core and Builtins + +The bytecode compiler now attempts to apply runtime stack manipulations at +compile-time (whenever it is feasible to do so). + +.. + +.. bpo: 30496 +.. date: 2022-01-09-11-59-04 +.. nonce: KvuuGT +.. section: Core and Builtins + +Fixed a minor portability issue in the implementation of +:c:func:`PyLong_FromLong`, and added a fast path for single-digit integers +to :c:func:`PyLong_FromLongLong`. + +.. + +.. bpo: 25707 +.. date: 2022-03-05-09-43-53 +.. nonce: gTlclP +.. section: Library + +Fixed a file leak in :func:`xml.etree.ElementTree.iterparse` when the +iterator is not exhausted. Patch by Jacob Walls. + +.. + +.. bpo: 46877 +.. date: 2022-03-03-06-58-52 +.. nonce: BKgjpD +.. section: Library + +Export :func:`unittest.doModuleCleanups` in :mod:`unittest`. Patch by Kumar +Aditya. + +.. + +.. bpo: 46848 +.. date: 2022-03-01-01-16-13 +.. nonce: BB01Fr +.. section: Library + +For performance, use the optimized string-searching implementations from +:meth:`~bytes.find` and :meth:`~bytes.rfind` for :meth:`~mmap.find` and +:meth:`~mmap.rfind`. + +.. + +.. bpo: 46736 +.. date: 2022-02-24-01-49-38 +.. nonce: NJcoWO +.. section: Library + +:class:`~http.server.SimpleHTTPRequestHandler` now uses HTML5 grammar. Patch +by Donghee Na. + +.. + +.. bpo: 44886 +.. date: 2022-02-23-00-55-59 +.. nonce: I40Mbr +.. section: Library + +Inherit asyncio proactor datagram transport from +:class:`asyncio.DatagramTransport`. + +.. + +.. bpo: 46827 +.. date: 2022-02-22-15-08-30 +.. nonce: hvj38S +.. section: Library + +Support UDP sockets in :meth:`asyncio.loop.sock_connect` for selector-based +event loops. Patch by Thomas Grainger. + +.. + +.. bpo: 46811 +.. date: 2022-02-20-21-03-31 +.. nonce: 8BxgdQ +.. section: Library + +Make test suite support Expat >=2.4.5 + +.. + +.. bpo: 46252 +.. date: 2022-02-20-12-59-46 +.. nonce: KG1SqA +.. section: Library + +Raise :exc:`TypeError` if :class:`ssl.SSLSocket` is passed to +transport-based APIs. + +.. + +.. bpo: 46784 +.. date: 2022-02-18-22-10-30 +.. nonce: SVOQJx +.. section: Library + +Fix libexpat symbols collisions with user dynamically loaded or statically +linked libexpat in embedded Python. + +.. + +.. bpo: 46786 +.. date: 2022-02-18-12-10-26 +.. nonce: P0xRvS +.. section: Library + +The HTML serialisation in xml.etree.ElementTree now writes ``embed``, +``source``, ``track`` and ``wbr`` as empty tags, as defined in HTML 5. + +.. + +.. bpo: 39327 +.. date: 2022-02-17-13-10-50 +.. nonce: ytIT7Z +.. section: Library + +:func:`shutil.rmtree` can now work with VirtualBox shared folders when +running from the guest operating-system. + +.. + +.. bpo: 45390 +.. date: 2022-02-17-11-00-16 +.. nonce: sVhG6M +.. section: Library + +Propagate :exc:`asyncio.CancelledError` message from inner task to outer +awaiter. + +.. + +.. bpo: 46756 +.. date: 2022-02-15-11-57-53 +.. nonce: AigSPi +.. section: Library + +Fix a bug in :meth:`urllib.request.HTTPPasswordMgr.find_user_password` and +:meth:`urllib.request.HTTPPasswordMgrWithPriorAuth.is_authenticated` which +allowed to bypass authorization. For example, access to URI +``example.org/foobar`` was allowed if the user was authorized for URI +``example.org/foo``. + +.. + +.. bpo: 46737 +.. date: 2022-02-15-07-39-43 +.. nonce: 6Pnblt +.. section: Library + +:func:`random.gauss` and :func:`random.normalvariate` now have default +arguments. + +.. + +.. bpo: 46752 +.. date: 2022-02-14-21-21-49 +.. nonce: m6ldTm +.. section: Library + +Add task groups to asyncio (structured concurrency, inspired by Trio's +nurseries). This also introduces a change to task cancellation, where a +cancelled task can't be cancelled again until it calls .uncancel(). + +.. + +.. bpo: 46724 +.. date: 2022-02-11-20-41-17 +.. nonce: eU52_N +.. section: Library + +Fix :mod:`dis` behavior on negative jump offsets. + +.. + +.. bpo: 46333 +.. date: 2022-02-11-20-01-49 +.. nonce: PMTBY9 +.. section: Library + +The :meth:`__repr__` method of :class:`typing.ForwardRef` now includes the +``module`` parameter of :class:`typing.ForwardRef` when it is set. + +.. + +.. bpo: 46643 +.. date: 2022-02-09-22-40-11 +.. nonce: aBlIx1 +.. section: Library + +In :func:`typing.get_type_hints`, support evaluating stringified +``ParamSpecArgs`` and ``ParamSpecKwargs`` annotations. Patch by Gregory +Beauregard. + +.. + +.. bpo: 45863 +.. date: 2022-02-09-00-53-23 +.. nonce: zqQXVv +.. section: Library + +When the :mod:`tarfile` module creates a pax format archive, it will put an +integer representation of timestamps in the ustar header (if possible) for +the benefit of older unarchivers, in addition to the existing full-precision +timestamps in the pax extended header. + +.. + +.. bpo: 46066 +.. date: 2022-02-08-16-42-20 +.. nonce: m32Hl0 +.. section: Library + +Deprecate kwargs-based syntax for :class:`typing.TypedDict` definitions. It +had confusing semantics when specifying totality, and was largely unused. +Patch by Jingchen Ye. + +.. + +.. bpo: 46676 +.. date: 2022-02-07-19-20-42 +.. nonce: 3Aws1o +.. section: Library + +Make :data:`typing.ParamSpec` args and kwargs equal to themselves. Patch by +Gregory Beauregard. + +.. + +.. bpo: 46323 +.. date: 2022-02-07-13-27-59 +.. nonce: 7UENAj +.. section: Library + +``ctypes.CFUNCTYPE()`` and ``ctypes.WINFUNCTYPE()`` now fail to create the +type if its ``_argtypes_`` member contains too many arguments. Previously, +the error was only raised when calling a function. Patch by Victor Stinner. + +.. + +.. bpo: 46672 +.. date: 2022-02-07-13-15-16 +.. nonce: 4swIjx +.. section: Library + +Fix ``NameError`` in :func:`asyncio.gather` when initial type check fails. + +.. + +.. bpo: 46659 +.. date: 2022-02-06-19-13-02 +.. nonce: q-vNL9 +.. section: Library + +The :class:`calendar.LocaleTextCalendar` and +:class:`calendar.LocaleHTMLCalendar` classes now use +:func:`locale.getlocale`, instead of using :func:`locale.getdefaultlocale`, +if no locale is specified. Patch by Victor Stinner. + +.. + +.. bpo: 46659 +.. date: 2022-02-06-17-57-45 +.. nonce: zTmkoQ +.. section: Library + +The :func:`locale.getdefaultlocale` function is deprecated and will be +removed in Python 3.13. Use :func:`locale.setlocale`, +:func:`locale.getpreferredencoding(False) <locale.getpreferredencoding>` and +:func:`locale.getlocale` functions instead. Patch by Victor Stinner. + +.. + +.. bpo: 46655 +.. date: 2022-02-06-08-54-03 +.. nonce: DiLzYv +.. section: Library + +In :func:`typing.get_type_hints`, support evaluating bare stringified +``TypeAlias`` annotations. Patch by Gregory Beauregard. + +.. + +.. bpo: 45948 +.. date: 2022-02-05-18-22-05 +.. nonce: w4mCnE +.. section: Library + +Fixed a discrepancy in the C implementation of the +:mod:`xml.etree.ElementTree` module. Now, instantiating an +:class:`xml.etree.ElementTree.XMLParser` with a ``target=None`` keyword +provides a default :class:`xml.etree.ElementTree.TreeBuilder` target as the +Python implementation does. + +.. + +.. bpo: 46626 +.. date: 2022-02-03-10-22-42 +.. nonce: r2e-n_ +.. section: Library + +Expose Linux's ``IP_BIND_ADDRESS_NO_PORT`` option in :mod:`socket`. + +.. + +.. bpo: 46521 +.. date: 2022-02-01-19-34-28 +.. nonce: IMUIrs +.. section: Library + +Fix a bug in the :mod:`codeop` module that was incorrectly identifying +invalid code involving string quotes as valid code. + +.. + +.. bpo: 46571 +.. date: 2022-02-01-11-21-34 +.. nonce: L40xUJ +.. section: Library + +Improve :func:`typing.no_type_check`. + +Now it does not modify external classes and functions. We also now correctly +mark classmethods as not to be type checked. + +.. + +.. bpo: 46400 +.. date: 2022-01-30-15-16-12 +.. nonce: vweUiO +.. section: Library + +expat: Update libexpat from 2.4.1 to 2.4.4 + +.. + +.. bpo: 46556 +.. date: 2022-01-27-23-20-30 +.. nonce: tlpAgS +.. section: Library + +Deprecate undocumented support for using a :class:`pathlib.Path` object as a +context manager. + +.. + +.. bpo: 46534 +.. date: 2022-01-26-18-06-08 +.. nonce: vhzUM4 +.. section: Library + +Implement :pep:`673` :class:`typing.Self`. Patch by James Hilton-Balfe. + +.. + +.. bpo: 46522 +.. date: 2022-01-25-15-31-04 +.. nonce: tYAlX4 +.. section: Library + +Make various module ``__getattr__`` AttributeErrors more closely match a +typical AttributeError + +.. + +.. bpo: 46475 +.. date: 2022-01-23-15-35-07 +.. nonce: UCe18S +.. section: Library + +Add :data:`typing.Never` and :func:`typing.assert_never`. Patch by Jelle +Zijlstra. + +.. + +.. bpo: 46333 +.. date: 2022-01-11-15-54-15 +.. nonce: B1faiF +.. section: Library + +The :meth:`__eq__` and :meth:`__hash__` methods of +:class:`typing.ForwardRef` now honor the ``module`` parameter of +:class:`typing.ForwardRef`. Forward references from different modules are +now differentiated. + +.. + +.. bpo: 46246 +.. date: 2022-01-07-13-27-53 +.. nonce: CTLx32 +.. section: Library + +Add missing ``__slots__`` to ``importlib.metadata.DeprecatedList``. Patch by +Arie Bovenberg. + +.. + +.. bpo: 46232 +.. date: 2022-01-03-09-46-44 +.. nonce: s0KlyI +.. section: Library + +The :mod:`ssl` module now handles certificates with bit strings in DN +correctly. + +.. + +.. bpo: 46195 +.. date: 2021-12-30-21-38-51 +.. nonce: jFKGq_ +.. section: Library + +:func:`typing.get_type_hints` no longer adds ``Optional`` to parameters with +``None`` as a default. This aligns to changes to PEP 484 in +https://github.com/python/peps/pull/689 + +.. + +.. bpo: 31369 +.. date: 2021-12-27-18-28-44 +.. nonce: b9yM94 +.. section: Library + +Add :class:`~re.RegexFlag` to ``re.__all__`` and documented it. Add +:data:`~re.RegexFlag.NOFLAG` to indicate no flags being set. + +.. + +.. bpo: 45898 +.. date: 2021-11-26-10-46-09 +.. nonce: UIfhsb +.. section: Library + +:mod:`ctypes` no longer defines ``ffi_type_*`` symbols in ``cfield.c``. The +symbols have been provided by libffi for over a decade. + +.. + +.. bpo: 44953 +.. date: 2021-08-19-09-29-43 +.. nonce: 27ZyUd +.. section: Library + +Calling ``operator.itemgetter`` objects and ``operator.attrgetter`` objects +is now faster due to use of the vectorcall calling convention. + +.. + +.. bpo: 44289 +.. date: 2021-06-02-19-47-46 +.. nonce: xC5kuV +.. section: Library + +Fix an issue with :meth:`~tarfile.is_tarfile` method when using *fileobj* +argument: position in the *fileobj* was advanced forward which made it +unreadable with :meth:`tarfile.TarFile.open`. + +.. + +.. bpo: 44011 +.. date: 2021-05-02-23-44-21 +.. nonce: hd8iUO +.. section: Library + +Reimplement SSL/TLS support in asyncio, borrow the implementation from +uvloop library. + +.. + +.. bpo: 41086 +.. date: 2020-06-23-01-50-24 +.. nonce: YnOvpS +.. section: Library + +Make the :class:`configparser.ConfigParser` constructor raise +:exc:`TypeError` if the ``interpolation`` parameter is not of type +:class:`configparser.Interpolation` + +.. + +.. bpo: 29418 +.. date: 2020-03-31-20-53-11 +.. nonce: 8Qa9cQ +.. section: Library + +Implement :func:`inspect.ismethodwrapper` and fix :func:`inspect.isroutine` +for cases where methodwrapper is given. Patch by Hakan Çelik. + +.. + +.. bpo: 14156 +.. date: 2019-05-07-14-25-45 +.. nonce: 0FaHXE +.. section: Library + +argparse.FileType now supports an argument of '-' in binary mode, returning +the .buffer attribute of sys.stdin/sys.stdout as appropriate. Modes +including 'x' and 'a' are treated equivalently to 'w' when argument is '-'. +Patch contributed by Josh Rosenberg + +.. + +.. bpo: 42238 +.. date: 2022-02-03-11-24-59 +.. nonce: yJcMa8 +.. section: Documentation + +``Doc/tools/rstlint.py`` has moved to its own repository and is now packaged +on PyPI as ``sphinx-lint``. + +.. + +.. bpo: 46913 +.. date: 2022-03-03-17-36-24 +.. nonce: vxETIE +.. section: Tests + +Fix test_faulthandler.test_sigfpe() if Python is built with undefined +behavior sanitizer (UBSAN): disable UBSAN on the faulthandler_sigfpe() +function. Patch by Victor Stinner. + +.. + +.. bpo: 46760 +.. date: 2022-02-16-10-38-18 +.. nonce: O3ovJo +.. section: Tests + +Remove bytecode offsets from expected values in test.test_dis module. +Reduces the obstacles to modifying the VM or compiler. + +.. + +.. bpo: 46708 +.. date: 2022-02-10-14-33-47 +.. nonce: avLfCb +.. section: Tests + +Prevent default asyncio event loop policy modification warning after +``test_asyncio`` execution. + +.. + +.. bpo: 46678 +.. date: 2022-02-07-12-40-45 +.. nonce: zfOrgL +.. section: Tests + +The function ``make_legacy_pyc`` in ``Lib/test/support/import_helper.py`` no +longer fails when ``PYTHONPYCACHEPREFIX`` is set to a directory on a +different device from where tempfiles are stored. + +.. + +.. bpo: 46623 +.. date: 2022-02-03-09-45-26 +.. nonce: vxzuhV +.. section: Tests + +Skip test_pair() and test_speech128() of test_zlib on s390x since they fail +if zlib uses the s390x hardware accelerator. Patch by Victor Stinner. + +.. + +.. bpo: 46860 +.. date: 2022-02-25-16-19-40 +.. nonce: jfciLG +.. section: Build + +Respect `--with-suffix` when building on case-insensitive file systems. + +.. + +.. bpo: 46656 +.. date: 2022-02-25-00-51-16 +.. nonce: MD783M +.. section: Build + +Building Python now requires a C11 compiler. Optional C11 features are not +required. +Patch by Victor Stinner. + +.. + +.. bpo: 46656 +.. date: 2022-02-06-14-04-20 +.. nonce: ajJjkh +.. section: Build + +Building Python now requires support for floating point Not-a-Number (NaN): +remove the ``Py_NO_NAN`` macro. Patch by Victor Stinner. + +.. + +.. bpo: 46640 +.. date: 2022-02-04-21-26-50 +.. nonce: HXUmQp +.. section: Build + +Building Python now requires a C99 ``<math.h>`` header file providing a +``NAN`` constant, or the ``__builtin_nan()`` built-in function. Patch by +Victor Stinner. + +.. + +.. bpo: 46608 +.. date: 2022-02-02-11-26-46 +.. nonce: cXH9po +.. section: Build + +Exclude marshalled-frozen data if deep-freezing to save 300 KB disk space. +This includes adding a new ``is_package`` field to :c:struct:`_frozen`. +Patch by Kumar Aditya. + +.. + +.. bpo: 40280 +.. date: 2022-01-31-15-15-08 +.. nonce: r1AYNW +.. section: Build + +Fix wasm32-emscripten test failures and platform issues. - Disable syscalls +that are not supported or don't work, e.g. wait, getrusage, prlimit, +mkfifo, mknod, setres[gu]id, setgroups. - Use fd_count to cound open fds. - +Add more checks for subprocess and fork. - Add workarounds for missing +_multiprocessing and failing socket.accept(). - Enable bzip2. - Disable +large file support. - Disable signal.alarm. + +.. + +.. bpo: 46430 +.. date: 2022-01-19-11-08-32 +.. nonce: k403m_ +.. section: Build + +Intern strings in deep-frozen modules. Patch by Kumar Aditya. + +.. + +.. bpo: 46744 +.. date: 2022-03-04-00-24-55 +.. nonce: tneWFr +.. section: Windows + +The default all users install directory for ARM64 is now under the native +``Program Files`` folder, rather than ``Program Files (Arm)`` which is +intended for ARM (32-bit) files. + +.. + +.. bpo: 46567 +.. date: 2022-02-25-01-22-31 +.. nonce: 37WEue +.. section: Windows + +Adds Tcl and Tk support for Windows ARM64. This also adds IDLE to the +installation. + +.. + +.. bpo: 46638 +.. date: 2022-02-04-18-02-33 +.. nonce: mSJOSX +.. section: Windows + +Ensures registry virtualization is consistently disabled. For 3.10 and +earlier, it remains enabled (some registry writes are protected), while for +3.11 and later it is disabled (registry modifications affect all +applications). + +.. + +.. bpo: 46630 +.. date: 2022-02-03-15-47-53 +.. nonce: tREOjo +.. section: IDLE + +Make query dialogs on Windows start with a cursor in the entry box. + +.. + +.. bpo: 45447 +.. date: 2021-10-14-16-55-03 +.. nonce: FhiH5P +.. section: IDLE + +Apply IDLE syntax highlighting to `.pyi` files. Patch by Alex Waygood and +Terry Jan Reedy. + +.. + +.. bpo: 46748 +.. date: 2022-02-24-13-13-16 +.. nonce: aG1zb3 +.. section: C API + +Python's public headers no longer import ``<stdbool.h>``, leaving code that +embedd/extends Python free to define ``bool``, ``true`` and ``false``. + +.. + +.. bpo: 46836 +.. date: 2022-02-23-16-13-17 +.. nonce: ZYyPF_ +.. section: C API + +Move the :c:type:`PyFrameObject` type definition (``struct _frame``) to the +internal C API ``pycore_frame.h`` header file. Patch by Victor Stinner. + +.. + +.. bpo: 45459 +.. date: 2022-02-07-18-47-00 +.. nonce: 0FCWM8 +.. section: C API + +Rename ``Include/buffer.h`` header file to ``Include/pybuffer.h`` to avoid +conflits with projects having an existing ``buffer.h`` header file. Patch by +Victor Stinner. + +.. + +.. bpo: 45412 +.. date: 2022-02-06-20-14-21 +.. nonce: XJVaGW +.. section: C API + +Remove the ``HAVE_PY_SET_53BIT_PRECISION`` macro (moved to the internal C +API). Patch by Victor Stinner. + +.. + +.. bpo: 46613 +.. date: 2022-02-02-17-58-49 +.. nonce: __ZdpH +.. section: C API + +Added function :c:func:`PyType_GetModuleByDef`, which allows accesss to +module state when a method's defining class is not available. diff --git a/Misc/NEWS.d/3.11.0a7.rst b/Misc/NEWS.d/3.11.0a7.rst new file mode 100644 index 00000000..20f2aa3c --- /dev/null +++ b/Misc/NEWS.d/3.11.0a7.rst @@ -0,0 +1,1614 @@ +.. bpo: 47212 +.. date: 2022-04-05-11-29-21 +.. nonce: leF4pz +.. release date: 2022-04-05 +.. section: Core and Builtins + +Raise :exc:`IndentationError` instead of :exc:`SyntaxError` for a bare +``except`` with no following indent. Improve :exc:`SyntaxError` locations +for an un-parenthesized generator used as arguments. Patch by Matthieu +Dartiailh. + +.. + +.. bpo: 47186 +.. date: 2022-04-04-17-41-10 +.. nonce: aQWoSh +.. section: Core and Builtins + +Replace :opcode:`JUMP_IF_NOT_EG_MATCH` by :opcode:`CHECK_EG_MATCH` + jump. + +.. + +.. bpo: 47176 +.. date: 2022-04-02-14-32-21 +.. nonce: kTygYI +.. section: Core and Builtins + +Emscripten builds cannot handle signals in the usual way due to platform +limitations. Python can now handle signals. To use, set +Module.Py_EmscriptenSignalBuffer to be a single byte SharedArrayBuffer and +set Py_EMSCRIPTEN_SIGNAL_HANDLING to 1. Writing a number into the +SharedArrayBuffer will cause the corresponding signal to be raised into the +Python thread. + +.. + +.. bpo: 47186 +.. date: 2022-04-01-11-53-59 +.. nonce: RBCPk8 +.. section: Core and Builtins + +Replace :opcode:`JUMP_IF_NOT_EXC_MATCH` by :opcode:`CHECK_EXC_MATCH` + jump. + +.. + +.. bpo: 47120 +.. date: 2022-03-31-21-43-57 +.. nonce: NgxQbA +.. section: Core and Builtins + +Replace the absolute jump opcode :opcode:`JUMP_NO_INTERRUPT` by the relative +:opcode:`JUMP_BACKWARD_NO_INTERRUPT`. + +.. + +.. bpo: 46841 +.. date: 2022-03-31-15-57-42 +.. nonce: U-25Z6 +.. section: Core and Builtins + +Avoid unnecessary allocations when comparing code objects. + +.. + +.. bpo: 47182 +.. date: 2022-03-31-15-37-02 +.. nonce: e_4SsC +.. section: Core and Builtins + +Fix a crash when using a named unicode character like ``"\N{digit nine}"`` +after the main interpreter has been initialized a second time. + +.. + +.. bpo: 47162 +.. date: 2022-03-30-13-13-25 +.. nonce: yDJMUm +.. section: Core and Builtins + +WebAssembly cannot deal with bad function pointer casts (different count or +types of arguments). Python can now use call trampolines to mitigate the +problem. Define :c:macro:`PY_CALL_TRAMPOLINE` to enable call trampolines. + +.. + +.. bpo: 46775 +.. date: 2022-03-30-02-36-25 +.. nonce: e3Oxqf +.. section: Core and Builtins + +Some Windows system error codes(>= 10000) are now mapped into the correct +errno and may now raise a subclass of :exc:`OSError`. Patch by Donghee Na. + +.. + +.. bpo: 47129 +.. date: 2022-03-26-16-35-57 +.. nonce: hDg2Vt +.. section: Core and Builtins + +Improve error messages in f-string syntax errors concerning empty +expressions. + +.. + +.. bpo: 47117 +.. date: 2022-03-26-15-45-57 +.. nonce: 60W6GQ +.. section: Core and Builtins + +Fix a crash if we fail to decode characters in interactive mode if the +tokenizer buffers are uninitialized. Patch by Pablo Galindo. + +.. + +.. bpo: 47127 +.. date: 2022-03-26-12-21-53 +.. nonce: Mh86RB +.. section: Core and Builtins + +Speed up calls to c functions with keyword arguments by 25% with +specialization. Patch by Kumar Aditya. + +.. + +.. bpo: 47120 +.. date: 2022-03-25-21-51-10 +.. nonce: 9YJ-Xw +.. section: Core and Builtins + +Replaced :opcode:`JUMP_ABSOLUTE` by the relative jump +:opcode:`JUMP_BACKWARD`. + +.. + +.. bpo: 42197 +.. date: 2022-03-22-15-12-28 +.. nonce: SwrrFO +.. section: Core and Builtins + +:c:func:`PyFrame_FastToLocalsWithError` and :c:func:`PyFrame_LocalsToFast` +are no longer called during profiling nor tracing. C code can access the +``f_locals`` attribute of :c:type:`PyFrameObject` by calling +:c:func:`PyFrame_GetLocals`. + +.. + +.. bpo: 47070 +.. date: 2022-03-19-21-50-59 +.. nonce: wPcsQh +.. section: Core and Builtins + +Improve performance of ``array_inplace_repeat`` by reducing the number of +invocations of ``memcpy``. Refactor the ``repeat`` and inplace ``repeat`` +methods of ``array``, ``bytes``, ``bytearray`` and ``unicodeobject`` to use +the common ``_PyBytes_Repeat``. + +.. + +.. bpo: 47053 +.. date: 2022-03-17-22-47-29 +.. nonce: QAXk8Q +.. section: Core and Builtins + +Reduce de-optimization in the specialized ``BINARY_OP_INPLACE_ADD_UNICODE`` +opcode. + +.. + +.. bpo: 47045 +.. date: 2022-03-17-16-25-57 +.. nonce: xQgHul +.. section: Core and Builtins + +Remove the ``f_state`` field from the _PyInterpreterFrame struct. Add the +``owner`` field to the _PyInterpreterFrame struct to make ownership explicit +to simplify clearing and deallocing frames and generators. + +.. + +.. bpo: 46968 +.. date: 2022-03-17-14-22-23 +.. nonce: 4gz4NA +.. section: Core and Builtins + +Check for the existence of the "sys/auxv.h" header in :mod:`faulthandler` to +avoid compilation problems in systems where this header doesn't exist. Patch +by Pablo Galindo + +.. + +.. bpo: 46329 +.. date: 2022-03-16-12-19-25 +.. nonce: 9oS0HT +.. section: Core and Builtins + +Use low bit of ``LOAD_GLOBAL`` to indicate whether to push a ``NULL`` before +the global. Helps streamline the call sequence a bit. + +.. + +.. bpo: 46841 +.. date: 2022-03-16-11-05-35 +.. nonce: yUoIHg +.. section: Core and Builtins + +Quicken bytecode in-place by storing it as part of the corresponding +``PyCodeObject``. + +.. + +.. bpo: 47012 +.. date: 2022-03-14-11-15-11 +.. nonce: 5L6NoE +.. section: Core and Builtins + +Speed up iteration of :class:`bytes` and :class:`bytearray` by 30%. Patch by +Kumar Aditya. + +.. + +.. bpo: 47009 +.. date: 2022-03-14-09-45-10 +.. nonce: ZI05b5 +.. section: Core and Builtins + +Improved the performance of :meth:`list.append()` and list comprehensions by +optimizing for the common case, where no resize is needed. Patch by Dennis +Sweeney. + +.. + +.. bpo: 47005 +.. date: 2022-03-13-21-04-20 +.. nonce: OHBfCc +.. section: Core and Builtins + +Improve performance of ``bytearray_repeat`` and ``bytearray_irepeat`` by +reducing the number of invocations of ``memcpy``. + +.. + +.. bpo: 46829 +.. date: 2022-03-12-21-07-21 +.. nonce: cpGoPV +.. section: Core and Builtins + +Deprecate passing a message into :meth:`asyncio.Future.cancel` and +:meth:`asyncio.Task.cancel` + +.. + +.. bpo: 46993 +.. date: 2022-03-12-09-44-31 +.. nonce: -13hGo +.. section: Core and Builtins + +Speed up :class:`bytearray` creation from :class:`list` and :class:`tuple` +by 40%. Patch by Kumar Aditya. + +.. + +.. bpo: 39829 +.. date: 2022-03-11-09-39-01 +.. nonce: mlW3Su +.. section: Core and Builtins + +Removed the ``__len__()`` call when initializing a list and moved +initializing to ``list_extend``. Patch by Jeremiah Pascual. + +.. + +.. bpo: 46944 +.. date: 2022-03-08-10-50-42 +.. nonce: cnaIK3 +.. section: Core and Builtins + +Speed up throwing exception in generator with :c:macro:`METH_FASTCALL` calling +convention. Patch by Kumar Aditya. + +.. + +.. bpo: 46841 +.. date: 2022-03-07-15-54-39 +.. nonce: 7wG92r +.. section: Core and Builtins + +Modify :opcode:`STORE_SUBSCR` to use an inline cache entry (rather than its +oparg) as an adaptive counter. + +.. + +.. bpo: 46841 +.. date: 2022-03-06-10-37-36 +.. nonce: O12Pba +.. section: Core and Builtins + +Use inline caching for :opcode:`PRECALL` and :opcode:`CALL`, and remove the +internal machinery for managing the (now unused) non-inline caches. + +.. + +.. bpo: 46881 +.. date: 2022-03-03-09-08-17 +.. nonce: ckD4tT +.. section: Core and Builtins + +Statically allocate and initialize the latin1 characters. + +.. + +.. bpo: 46838 +.. date: 2022-02-25-22-42-30 +.. nonce: RB6kEy +.. section: Core and Builtins + +Improve syntax errors for incorrect function definitions. Patch by Pablo +Galindo + +.. + +.. bpo: 43721 +.. date: 2022-02-01-10-05-27 +.. nonce: -1XAIo +.. section: Core and Builtins + +Fix docstrings of :attr:`~property.getter`, :attr:`~property.setter`, and +:attr:`~property.deleter` to clarify that they create a new copy of the +property. + +.. + +.. bpo: 43224 +.. date: 2022-01-20-16-48-09 +.. nonce: WDihrT +.. section: Core and Builtins + +Make grammar changes required for PEP 646. + +.. + +.. bpo: 47208 +.. date: 2022-04-04-08-54-31 +.. nonce: cOh9xZ +.. section: Library + +Allow vendors to override :const:`CTYPES_MAX_ARGCOUNT`. + +.. + +.. bpo: 23689 +.. date: 2022-04-03-13-19-08 +.. nonce: TFSc3E +.. section: Library + +:mod:`re` module: fix memory leak when a match is terminated by a signal or +memory allocation failure. Patch by Ma Lin. + +.. + +.. bpo: 47167 +.. date: 2022-03-30-18-35-50 +.. nonce: nCNHsB +.. section: Library + +Allow overriding a future compliance check in :class:`asyncio.Task`. + +.. + +.. bpo: 47151 +.. date: 2022-03-30-01-17-43 +.. nonce: z-nQkR +.. section: Library + +When subprocess tries to use vfork, it now falls back to fork if vfork +returns an error. This allows use in situations where vfork isn't allowed by +the OS kernel. + +.. + +.. bpo: 47152 +.. date: 2022-03-29-19-14-53 +.. nonce: 5rl5ZK +.. section: Library + +Convert the :mod:`re` module into a package. Deprecate modules +``sre_compile``, ``sre_constants`` and ``sre_parse``. + +.. + +.. bpo: 4833 +.. date: 2022-03-28-20-16-37 +.. nonce: 2vSUE5 +.. section: Library + +Add :meth:`ZipFile.mkdir` + +.. + +.. bpo: 27929 +.. date: 2022-03-28-13-35-50 +.. nonce: j5mAmV +.. section: Library + +Fix :meth:`asyncio.loop.sock_connect` to only resolve names for +:const:`socket.AF_INET` or :const:`socket.AF_INET6` families. Resolution may +not make sense for other families, like :const:`socket.AF_BLUETOOTH` and +:const:`socket.AF_UNIX`. + +.. + +.. bpo: 14265 +.. date: 2022-03-27-10-41-24 +.. nonce: OBMlAi +.. section: Library + +Adds the fully qualified test name to unittest output + +.. + +.. bpo: 47061 +.. date: 2022-03-26-13-14-43 +.. nonce: QLxbC6 +.. section: Library + +Deprecate the aifc module. + +.. + +.. bpo: 39622 +.. date: 2022-03-25-01-27-25 +.. nonce: ieBIMp +.. section: Library + +Handle Ctrl+C in asyncio programs to interrupt the main task. + +.. + +.. bpo: 47101 +.. date: 2022-03-23-15-31-02 +.. nonce: rVSld- +.. section: Library + +:const:`hashlib.algorithms_available` now lists only algorithms that are +provided by activated crypto providers on OpenSSL 3.0. Legacy algorithms are +not listed unless the legacy provider has been loaded into the default OSSL +context. + +.. + +.. bpo: 47099 +.. date: 2022-03-23-14-16-38 +.. nonce: 2raait +.. section: Library + +All :exc:`URLError` exception messages raised in +:class:`urllib.request.URLopener` now contain a colon between ``ftp error`` +and the rest of the message. Previously, +:func:`~urllib.request.URLopener.open_ftp` missed the colon. Patch by Oleg +Iarygin. + +.. + +.. bpo: 47099 +.. date: 2022-03-23-13-55-41 +.. nonce: P6quRP +.. section: Library + +Exception chaining is changed from +:func:`Exception.with_traceback`/:func:`sys.exc_info` to :pep:`3134`. Patch +by Oleg Iarygin. + +.. + +.. bpo: 47095 +.. date: 2022-03-23-12-07-26 +.. nonce: P3YTrh +.. section: Library + +:mod:`hashlib`'s internal ``_blake2`` module now prefers ``libb2`` from +https://www.blake2.net/ over Python's vendored copy of blake2. + +.. + +.. bpo: 47098 +.. date: 2022-03-23-10-07-41 +.. nonce: 7AN_qp +.. section: Library + +The Keccak Code Package for :mod:`hashlib`'s internal ``_sha3`` module has +been replaced with tiny_sha3. The module is used as fallback when Python is +built without OpenSSL. + +.. + +.. bpo: 47088 +.. date: 2022-03-22-19-18-31 +.. nonce: JM1kNI +.. section: Library + +Implement :data:`typing.LiteralString`, part of :pep:`675`. Patch by Jelle +Zijlstra. + +.. + +.. bpo: 42885 +.. date: 2022-03-21-08-32-19 +.. nonce: LCnTTp +.. section: Library + +Optimize :func:`re.search`, :func:`re.split`, :func:`re.findall`, +:func:`re.finditer` and :func:`re.sub` for regular expressions starting with +``\A`` or ``^``. + +.. + +.. bpo: 23691 +.. date: 2022-03-20-22-13-24 +.. nonce: Nc2TrW +.. section: Library + +Protect the :func:`re.finditer` iterator from re-entering. + +.. + +.. bpo: 47067 +.. date: 2022-03-20-17-15-56 +.. nonce: XXLnje +.. section: Library + +Optimize calling ``GenericAlias`` objects by using :pep:`590` ``vectorcall`` +and by replacing ``PyObject_SetAttrString`` with ``PyObject_SetAttr``. + +.. + +.. bpo: 28080 +.. date: 2022-03-20-15-54-41 +.. nonce: kn35Vk +.. section: Library + +Add the *metadata_encoding* parameter in the :class:`zipfile.ZipFile` +constructor and the ``--metadata-encoding`` option in the :mod:`zipfile` CLI +to allow reading zipfiles using non-standard codecs to encode the filenames +within the archive. + +.. + +.. bpo: 47000 +.. date: 2022-03-20-13-00-08 +.. nonce: p8HpG0 +.. section: Library + +Make :func:`io.text_encoding` returns "utf-8" when UTF-8 mode is enabled. + +.. + +.. bpo: 42369 +.. date: 2022-03-19-19-56-04 +.. nonce: Ok828t +.. section: Library + +Fix thread safety of :meth:`zipfile._SharedFile.tell` to avoid a +"zipfile.BadZipFile: Bad CRC-32 for file" exception when reading a +:class:`ZipFile` from multiple threads. + +.. + +.. bpo: 38256 +.. date: 2022-03-19-15-54-41 +.. nonce: FoMbjE +.. section: Library + +Fix :func:`binascii.crc32` when it is compiled to use zlib'c crc32 to work +properly on inputs 4+GiB in length instead of returning the wrong result. +The workaround prior to this was to always feed the function data in +increments smaller than 4GiB or to just call the zlib module function. + +We also have :func:`binascii.crc32` release the GIL when computing on larger +inputs as :func:`zlib.crc32` and :mod:`hashlib` do. + +This also boosts performance on Windows as it now uses the zlib crc32 +implementation for :func:`binascii.crc32` for a 2-3x speedup. + +That the stdlib has a crc32 API in two modules is a known historical oddity. +This moves us closer to a single implementation behind them. + +.. + +.. bpo: 47066 +.. date: 2022-03-19-14-12-23 +.. nonce: we3YFx +.. section: Library + +Global inline flags (e.g. ``(?i)``) can now only be used at the start of the +regular expressions. Using them not at the start of expression was +deprecated since Python 3.6. + +.. + +.. bpo: 39394 +.. date: 2022-03-19-13-38-29 +.. nonce: 7j6WL6 +.. section: Library + +A warning about inline flags not at the start of the regular expression now +contains the position of the flag. + +.. + +.. bpo: 433030 +.. date: 2022-03-19-08-42-57 +.. nonce: UTwRX7 +.. section: Library + +Add support of atomic grouping (``(?>...)``) and possessive quantifiers +(``*+``, ``++``, ``?+``, ``{m,n}+``) in :mod:`regular expressions <re>`. + +.. + +.. bpo: 47062 +.. date: 2022-03-18-22-46-18 +.. nonce: RNc99_ +.. section: Library + +Implement :class:`asyncio.Runner` context manager. + +.. + +.. bpo: 46382 +.. date: 2022-03-18-17-25-57 +.. nonce: zQUJ66 +.. section: Library + +:func:`~dataclasses.dataclass` ``slots=True`` now correctly omits slots +already defined in base classes. Patch by Arie Bovenberg. + +.. + +.. bpo: 47057 +.. date: 2022-03-18-14-22-38 +.. nonce: n-IHbt +.. section: Library + +Use FASTCALL convention for ``FutureIter.throw()`` + +.. + +.. bpo: 47061 +.. date: 2022-03-18-13-30-40 +.. nonce: etLHK5 +.. section: Library + +Deprecate the various modules listed by :pep:`594`: + +aifc, asynchat, asyncore, audioop, cgi, cgitb, chunk, crypt, imghdr, msilib, +nntplib, nis, ossaudiodev, pipes, smtpd, sndhdr, spwd, sunau, telnetlib, uu, +xdrlib + +.. + +.. bpo: 34790 +.. date: 2022-03-17-19-38-40 +.. nonce: zQIiVJ +.. section: Library + +Remove passing coroutine objects to :func:`asyncio.wait`. + +.. + +.. bpo: 47039 +.. date: 2022-03-17-01-54-13 +.. nonce: 0Yxv0K +.. section: Library + +Normalize ``repr()`` of asyncio future and task objects. + +.. + +.. bpo: 2604 +.. date: 2022-03-16-18-25-19 +.. nonce: jeopdL +.. section: Library + +Fix bug where doctests using globals would fail when run multiple times. + +.. + +.. bpo: 45150 +.. date: 2022-03-16-11-52-52 +.. nonce: kYbIME +.. section: Library + +Add :func:`hashlib.file_digest` helper for efficient hashing of file object. + +.. + +.. bpo: 34861 +.. date: 2022-03-16-08-49-12 +.. nonce: p8ugVg +.. section: Library + +Made cumtime the default sorting key for cProfile + +.. + +.. bpo: 45997 +.. date: 2022-03-15-18-32-12 +.. nonce: 4n2aVU +.. section: Library + +Fix :class:`asyncio.Semaphore` re-aquiring FIFO order. + +.. + +.. bpo: 47022 +.. date: 2022-03-15-09-29-52 +.. nonce: uaEDcI +.. section: Library + +The :mod:`asynchat`, :mod:`asyncore` and :mod:`smtpd` modules have been +deprecated since at least Python 3.6. Their documentation and deprecation +warnings and have now been updated to note they will removed in Python 3.12 +(:pep:`594`). + +.. + +.. bpo: 43253 +.. date: 2022-03-15-07-53-45 +.. nonce: rjdLFj +.. section: Library + +Fix a crash when closing transports where the underlying socket handle is +already invalid on the Proactor event loop. + +.. + +.. bpo: 40280 +.. date: 2022-03-14-09-26-42 +.. nonce: 2-k8TV +.. section: Library + +:func:`select.select` now passes ``NULL`` to ``select`` for each empty +fdset. + +.. + +.. bpo: 47004 +.. date: 2022-03-13-15-04-05 +.. nonce: SyYpxd +.. section: Library + +Apply bugfixes from importlib_metadata 4.11.3, including bugfix for +EntryPoint.extras, which was returning match objects and not the extras +strings. + +.. + +.. bpo: 46998 +.. date: 2022-03-13-08-52-58 +.. nonce: cHh-9O +.. section: Library + +Allow subclassing of :class:`typing.Any`. Patch by Shantanu Jain. + +.. + +.. bpo: 46995 +.. date: 2022-03-12-13-50-42 +.. nonce: 2kdNDg +.. section: Library + +Deprecate missing :meth:`asyncio.Task.set_name` for third-party task +implementations, schedule making it mandatory in Python 3.13. + +.. + +.. bpo: 46994 +.. date: 2022-03-12-12-34-13 +.. nonce: d7hPdz +.. section: Library + +Accept explicit contextvars.Context in :func:`asyncio.create_task` and +:meth:`asyncio.loop.create_task`. + +.. + +.. bpo: 46981 +.. date: 2022-03-12-11-30-42 +.. nonce: ltWCxH +.. section: Library + +``typing.get_args(typing.Tuple[()])`` now returns ``()`` instead of +``((),)``. + +.. + +.. bpo: 46968 +.. date: 2022-03-11-17-56-25 +.. nonce: pPVvNo +.. section: Library + +Add ``os.sysconf_names['SC_MINSIGSTKSZ']``. + +.. + +.. bpo: 46985 +.. date: 2022-03-11-13-34-16 +.. nonce: BgoMr2 +.. section: Library + +Upgrade pip wheel bundled with ensurepip (pip 22.0.4) + +.. + +.. bpo: 46968 +.. date: 2022-03-10-14-51-11 +.. nonce: ym2QxL +.. section: Library + +:mod:`faulthandler`: On Linux 5.14 and newer, dynamically determine size of +signal handler stack size CPython allocates using +``getauxval(AT_MINSIGSTKSZ)``. This changes allows for Python extension's +request to Linux kernel to use AMX_TILE instruction set on Sapphire Rapids +Xeon processor to succeed, unblocking use of the ISA in frameworks. + +.. + +.. bpo: 46917 +.. date: 2022-03-10-14-47-16 +.. nonce: s19zcy +.. section: Library + +The :data:`math.nan` value is now always available. Patch by Victor Stinner. + +.. + +.. bpo: 46955 +.. date: 2022-03-08-22-41-59 +.. nonce: IOoonN +.. section: Library + +Expose :class:`asyncio.base_events.Server` as :class:`asyncio.Server`. Patch +by Stefan Zabka. + +.. + +.. bpo: 23325 +.. date: 2022-03-08-11-34-06 +.. nonce: 3VQnfo +.. section: Library + +The :mod:`signal` module no longer assumes that :const:`~signal.SIG_IGN` and +:const:`~signal.SIG_DFL` are small int singletons. + +.. + +.. bpo: 46932 +.. date: 2022-03-07-20-20-34 +.. nonce: xbarAs +.. section: Library + +Update bundled libexpat to 2.4.7 + +.. + +.. bpo: 46933 +.. date: 2022-03-05-21-51-31 +.. nonce: 6yzWtb +.. section: Library + +The :mod:`pwd` module is now optional. :func:`os.path.expanduser` returns +the path when the :mod:`pwd` module is not available. + +.. + +.. bpo: 40059 +.. date: 2022-02-23-01-11-08 +.. nonce: Iwc9UH +.. section: Library + +:pep:`680`, the :mod:`tomllib` module. Adds support for parsing TOML. + +.. + +.. bpo: 464471 +.. date: 2022-02-21-11-41-23 +.. nonce: fL06TV +.. section: Library + +:func:`asyncio.timeout` and :func:`asyncio.timeout_at` context managers +added. Patch by Tin Tvrtković and Andrew Svetlov. + +.. + +.. bpo: 46805 +.. date: 2022-02-20-23-03-32 +.. nonce: HZ8xWG +.. section: Library + +Added raw datagram socket functions for asyncio: +:meth:`~asyncio.AbstractEventLoop.sock_sendto`, +:meth:`~asyncio.AbstractEventLoop.sock_recvfrom` and +:meth:`~asyncio.AbstractEventLoop.sock_recvfrom_into`. + +.. + +.. bpo: 46644 +.. date: 2022-02-05-22-14-44 +.. nonce: P--1Cz +.. section: Library + +No longer require valid typeforms to be callable. This allows +:data:`typing.Annotated` to wrap :data:`typing.ParamSpecArgs` and +:data:`dataclasses.InitVar`. Patch by Gregory Beauregard. + +.. + +.. bpo: 46581 +.. date: 2022-02-01-11-32-47 +.. nonce: t7Zw65 +.. section: Library + +Brings :class:`ParamSpec` propagation for :class:`GenericAlias` in line with +:class:`Concatenate` (and others). + +.. + +.. bpo: 45413 +.. date: 2022-01-31-15-19-38 +.. nonce: 1vaS0V +.. section: Library + +Define *posix_venv* and *nt_venv* :ref:`sysconfig installation schemes +<installation_paths>` to be used for bootstrapping new virtual environments. +Add *venv* sysconfig installation scheme to get the appropriate one of the +above. The schemes are identical to the pre-existing *posix_prefix* and *nt* +install schemes. The :mod:`venv` module now uses the *venv* scheme to create +new virtual environments instead of hardcoding the paths depending only on +the platform. Downstream Python distributors customizing the *posix_prefix* +or *nt* install scheme in a way that is not compatible with the install +scheme used in virtual environments are encouraged not to customize the +*venv* schemes. When Python itself runs in a virtual environment, +:func:`sysconfig.get_default_scheme` and +:func:`sysconfig.get_preferred_scheme` with ``key="prefix"`` returns *venv*. + +.. + +.. bpo: 43224 +.. date: 2022-01-30-22-05-53 +.. nonce: E-eT22 +.. section: Library + +Implement support for PEP 646 in typing.py. + +.. + +.. bpo: 43224 +.. date: 2022-01-30-20-32-40 +.. nonce: zqrQsj +.. section: Library + +Allow unpacking types.GenericAlias objects, e.g. ``*tuple[int, str]``. + +.. + +.. bpo: 46557 +.. date: 2022-01-28-01-23-25 +.. nonce: XSbhyQ +.. section: Library + +Warnings captured by the logging module are now logged without a format +string to prevent systems that group logs by the msg argument from grouping +captured warnings together. + +.. + +.. bpo: 41370 +.. date: 2022-01-27-11-54-16 +.. nonce: gYxCPE +.. section: Library + +:func:`typing.get_type_hints` now supports evaluating strings as forward +references in :ref:`PEP 585 generic aliases <types-genericalias>`. + +.. + +.. bpo: 46607 +.. date: 2022-01-26-18-30-34 +.. nonce: xnhT4a +.. section: Library + +Add :exc:`DeprecationWarning` to :class:`LegacyInterpolation`, deprecated in +the docstring since Python 3.2. Will be removed in Python 3.13. Use +:class:`BasicInterpolation` or :class:`ExtendedInterpolation` instead. + +.. + +.. bpo: 26120 +.. date: 2022-01-25-15-45-04 +.. nonce: YzrBMO +.. section: Library + +:mod:`pydoc` now excludes __future__ imports from the module's data items. + +.. + +.. bpo: 46480 +.. date: 2022-01-23-16-33-07 +.. nonce: E4jHlh +.. section: Library + +Add :func:`typing.assert_type`. Patch by Jelle Zijlstra. + +.. + +.. bpo: 46421 +.. date: 2022-01-18-01-29-38 +.. nonce: 9LdmNr +.. section: Library + +Fix a unittest issue where if the command was invoked as ``python -m +unittest`` and the filename(s) began with a dot (.), a ``ValueError`` is +returned. + +.. + +.. bpo: 46245 +.. date: 2022-01-03-20-12-14 +.. nonce: 3w4RlA +.. section: Library + +Add optional parameter *dir_fd* in :func:`shutil.rmtree`. + +.. + +.. bpo: 22859 +.. date: 2021-12-29-19-37-49 +.. nonce: AixHW7 +.. section: Library + +:meth:`~unittest.TestProgram.usageExit` is marked deprecated, to be removed +in 3.13. + +.. + +.. bpo: 46170 +.. date: 2021-12-26-14-45-51 +.. nonce: AQ7kSM +.. section: Library + +Improve the error message when you try to subclass an instance of +:class:`typing.NewType`. + +.. + +.. bpo: 40296 +.. date: 2021-12-25-14-13-14 +.. nonce: p0YVGB +.. section: Library + +Fix supporting generic aliases in :mod:`pydoc`. + +.. + +.. bpo: 20392 +.. date: 2021-12-22-12-02-27 +.. nonce: CLAFIp +.. section: Library + +Fix inconsistency with uppercase file extensions in +:meth:`MimeTypes.guess_type`. Patch by Kumar Aditya. + +.. + +.. bpo: 46030 +.. date: 2021-12-10-07-07-47 +.. nonce: UN349J +.. section: Library + +Add ``LOCAL_CREDS``, ``LOCAL_CREDS_PERSISTENT`` and ``SCM_CREDS2`` FreeBSD +constants to the socket module. + +.. + +.. bpo: 44439 +.. date: 2021-11-08-20-27-41 +.. nonce: I_8qro +.. section: Library + +Fix ``.write()`` method of a member file in ``ZipFile``, when the input data +is an object that supports the buffer protocol, the file length may be +wrong. + +.. + +.. bpo: 45171 +.. date: 2021-09-11-16-06-54 +.. nonce: ec597j +.. section: Library + +Fix handling of the ``stacklevel`` argument to logging functions in the +:mod:`logging` module so that it is consistent across all logging functions +and, as advertised, similar to the ``stacklevel`` argument used in +:meth:`~warnings.warn`. + +.. + +.. bpo: 24959 +.. date: 2021-09-06-15-46-53 +.. nonce: UVFgiO +.. section: Library + +Fix bug where :mod:`unittest` sometimes drops frames from tracebacks of +exceptions raised in tests. + +.. + +.. bpo: 44859 +.. date: 2021-08-10-00-05-53 +.. nonce: 9e9_3V +.. section: Library + +Raise more accurate and :pep:`249` compatible exceptions in :mod:`sqlite3`. + +* Raise :exc:`~sqlite3.InterfaceError` instead of + :exc:`~sqlite3.ProgrammingError` for ``SQLITE_MISUSE`` errors. +* Don't overwrite :exc:`BufferError` with :exc:`ValueError` when conversion to + BLOB fails. +* Raise :exc:`~sqlite3.ProgrammingError` instead of :exc:`~sqlite3.Warning` if + user tries to :meth:`~sqlite3.Cursor.execute()` more than one SQL statement. +* Raise :exc:`~sqlite3.ProgrammingError` instead of :exc:`ValueError` if an SQL + query contains null characters. + +.. + +.. bpo: 44493 +.. date: 2021-07-26-10-46-49 +.. nonce: xp3CRH +.. section: Library + +Add missing terminated NUL in sockaddr_un's length + +This was potentially observable when using non-abstract AF_UNIX datagram +sockets to processes written in another programming language. + +.. + +.. bpo: 41930 +.. date: 2021-06-17-00-02-58 +.. nonce: JS6fsd +.. section: Library + +Add :meth:`~sqlite3.Connection.serialize` and +:meth:`~sqlite3.Connection.deserialize` support to :mod:`sqlite3`. Patch by +Erlend E. Aasland. + +.. + +.. bpo: 33178 +.. date: 2021-04-20-16-48-07 +.. nonce: kSnWwb +.. section: Library + +Added :class:`ctypes.BigEndianUnion` and :class:`ctypes.LittleEndianUnion` +classes, as originally documented in the library docs but not yet +implemented. + +.. + +.. bpo: 43352 +.. date: 2021-03-31-15-22-45 +.. nonce: nSjMuE +.. section: Library + +Add an Barrier object in synchronization primitives of *asyncio* Lib in +order to be consistant with Barrier from *threading* and *multiprocessing* +libs* + +.. + +.. bpo: 35859 +.. date: 2019-03-14-09-08-25 +.. nonce: 8lFdLe +.. section: Library + +:mod:`re` module, fix a few bugs about capturing group. In rare cases, +capturing group gets an incorrect string. Patch by Ma Lin. + +.. + +.. bpo: 45099 +.. date: 2022-03-29-13-25-49 +.. nonce: dagdhx +.. section: Documentation + +Document internal :mod:`asyncio` API. + +.. + +.. bpo: 47126 +.. date: 2022-03-26-12-20-16 +.. nonce: p6_Ovm +.. section: Documentation + +Update PEP URLs to :pep:`676`'s new canonical form. + +.. + +.. bpo: 47040 +.. date: 2022-03-17-13-35-28 +.. nonce: 4Dn48U +.. section: Documentation + +Clarified the old Python versions compatiblity note of +:func:`binascii.crc32` / :func:`zlib.adler32` / :func:`zlib.crc32` +functions. + +.. + +.. bpo: 46033 +.. date: 2022-01-03-18-50-39 +.. nonce: 7WeF0f +.. section: Documentation + +Clarify ``for`` statement execution in its doc. + +.. + +.. bpo: 45790 +.. date: 2021-11-12-11-03-55 +.. nonce: 6yuhe8 +.. section: Documentation + +Adjust inaccurate phrasing in :doc:`../extending/newtypes_tutorial` about +the ``ob_base`` field and the macros used to access its contents. + +.. + +.. bpo: 42340 +.. date: 2020-11-12-21-26-31 +.. nonce: apumUL +.. section: Documentation + +Document that in some circumstances :exc:`KeyboardInterrupt` may cause the +code to enter an inconsistent state. Provided a sample workaround to avoid +it if needed. + +.. + +.. bpo: 41233 +.. date: 2020-07-07-22-54-51 +.. nonce: lyUJ8L +.. section: Documentation + +Link the errnos referenced in ``Doc/library/exceptions.rst`` to their +respective section in ``Doc/library/errno.rst``, and vice versa. Previously +this was only done for EINTR and InterruptedError. Patch by Yan "yyyyyyyan" +Orestes. + +.. + +.. bpo: 47205 +.. date: 2022-04-03-14-38-21 +.. nonce: hbbTnh +.. section: Tests + +Skip test for :func:`~os.sched_getaffinity` and +:func:`~os.sched_setaffinity` error case on FreeBSD. + +.. + +.. bpo: 46126 +.. date: 2022-03-26-11-41-19 +.. nonce: q14Ioy +.. section: Tests + +Restore 'descriptions' when running tests internally. + +.. + +.. bpo: 47104 +.. date: 2022-03-23-22-45-51 +.. nonce: _esUq8 +.. section: Tests + +Rewrite :func:`asyncio.to_thread` tests to use +:class:`unittest.IsolatedAsyncioTestCase`. + +.. + +.. bpo: 40280 +.. date: 2022-03-19-10-25-04 +.. nonce: wBRSel +.. section: Tests + +The test suite is now passing on the Emscripten platform. All fork, socket, +and subprocess-based tests are skipped. + +.. + +.. bpo: 47037 +.. date: 2022-03-16-21-29-30 +.. nonce: xcrLpJ +.. section: Tests + +Skip ``strftime("%4Y")`` feature test on Windows. It can cause an assertion +error in debug builds. + +.. + +.. bpo: 46587 +.. date: 2022-03-14-17-10-35 +.. nonce: ASDsJX +.. section: Tests + +Skip tests if platform's ``strftime`` does not support non-portable glibc +extensions. + +.. + +.. bpo: 47015 +.. date: 2022-03-13-23-43-40 +.. nonce: FjmCsz +.. section: Tests + +A test case for :func:`os.sendfile` is converted from deprecated +:mod:`asyncore` (see :pep:`594`) to :mod:`asyncio`. Patch by Oleg Iarygin. + +.. + +.. bpo: 40280 +.. date: 2022-04-02-17-52-38 +.. nonce: U8Dd0H +.. section: Build + +Add configure option :option:`--enable-wasm-dynamic-linking` to enable +``dlopen`` and MAIN_MODULE / SIDE_MODULE on ``wasm32-emscripten``. + +.. + +.. bpo: 46023 +.. date: 2022-04-01-16-12-53 +.. nonce: 1Z1OcC +.. section: Build + +``makesetup`` now detects and skips all duplicated module definitions. The +first entry wins. + +.. + +.. bpo: 40280 +.. date: 2022-03-24-12-12-35 +.. nonce: eAQWrM +.. section: Build + +Add SOABI ``wasm32-emscripten`` for Emscripten and ``wasm32-wasi`` for WASI +on 32bit WASM as well as ``wasm64`` counter parts. + +.. + +.. bpo: 47032 +.. date: 2022-03-16-00-37-40 +.. nonce: tsS9KE +.. section: Build + +Ensure Windows install builds fail correctly with a non-zero exit code when +part of the build fails. + +.. + +.. bpo: 47024 +.. date: 2022-03-15-09-28-55 +.. nonce: t7-dcu +.. section: Build + +Update OpenSSL to 1.1.1n for macOS installers and all Windows builds. + +.. + +.. bpo: 46996 +.. date: 2022-03-12-18-09-31 +.. nonce: SygzVz +.. section: Build + +The :mod:`tkinter` package now requires Tcl/Tk version 8.5.12 or newer. + +.. + +.. bpo: 46973 +.. date: 2022-03-10-14-30-39 +.. nonce: _LEvnc +.. section: Build + +Add ``regen-configure`` make target to regenerate configure script with +Christian's container image ``quay.io/tiran/cpython_autoconf:269``. + +.. + +.. bpo: 46917 +.. date: 2022-03-10-09-37-05 +.. nonce: fry4aK +.. section: Build + +Building Python now requires support of IEEE 754 floating point numbers. +Patch by Victor Stinner. + +.. + +.. bpo: 45774 +.. date: 2022-03-04-21-24-02 +.. nonce: 9AhC0r +.. section: Build + +``configure`` now verifies that all SQLite C APIs needed for the +:mod:`sqlite3` extension module are found. + +.. + +.. bpo: 47194 +.. date: 2022-04-01-14-57-40 +.. nonce: IB0XL4 +.. section: Windows + +Update ``zlib`` to v1.2.12 to resolve CVE-2018-25032. + +.. + +.. bpo: 47171 +.. date: 2022-03-30-19-55-00 +.. nonce: MbqCWn +.. section: Windows + +Enables installing the :file:`py.exe` launcher on Windows ARM64. + +.. + +.. bpo: 46566 +.. date: 2022-03-23-12-51-46 +.. nonce: 4x4a7e +.. section: Windows + +Upgraded :ref:`launcher` to support a new ``-V:company/tag`` argument for +full :pep:`514` support and to detect ARM64 installs. The ``-64`` suffix on +arguments is deprecated, but still selects any non-32-bit install. Setting +:envvar:`PYLAUNCHER_ALLOW_INSTALL` and specifying a version that is not +installed will attempt to install the requested version from the Microsoft +Store. + +.. + +.. bpo: 47086 +.. date: 2022-03-21-20-45-01 +.. nonce: bIuKlF +.. section: Windows + +The installer for Windows now includes documentation as loose HTML files +rather than a single compiled :file:`.chm` file. + +.. + +.. bpo: 46907 +.. date: 2022-03-13-11-18-41 +.. nonce: YLzxBM +.. section: Windows + +Update Windows installer to use SQLite 3.38.1. + +.. + +.. bpo: 44549 +.. date: 2022-03-07-17-46-40 +.. nonce: SPrGS9 +.. section: Windows + +Update bzip2 to 1.0.8 in Windows builds to mitigate CVE-2016-3189 and +CVE-2019-12900 + +.. + +.. bpo: 46948 +.. date: 2022-03-07-16-34-11 +.. nonce: Ufd4tG +.. section: Windows + +Prevent CVE-2022-26488 by ensuring the Add to PATH option in the Windows +installer uses the correct path when being repaired. + +.. + +.. bpo: 46890 +.. date: 2022-03-17-09-55-02 +.. nonce: GX-3OO +.. section: macOS + +Fix a regression in the setting of ``sys._base_executable`` in framework +builds, and thereby fix a regression in :mod:`venv` virtual environments +with such builds. + +.. + +.. bpo: 46907 +.. date: 2022-03-13-11-11-31 +.. nonce: Ql0z1E +.. section: macOS + +Update macOS installer to SQLite 3.38.1. + +.. + +.. bpo: 40280 +.. date: 2022-04-03-11-47-45 +.. nonce: Q_IJik +.. section: Tools/Demos + +Replace Emscripten's limited shell with Katie Bell's browser-ui REPL from +python-wasm project. + +.. + +.. bpo: 40421 +.. date: 2022-03-25-13-40-46 +.. nonce: wJREl2 +.. section: C API + +Add ``PyFrame_GetBuiltins``, ``PyFrame_GetGenerator`` and +``PyFrame_GetGlobals`` C-API functions to access frame object attributes +safely from C code. + +.. + +.. bpo: 46850 +.. date: 2022-03-22-16-59-34 +.. nonce: lmEKLy +.. section: C API + +Move the private ``_PyFrameEvalFunction`` type, and private +``_PyInterpreterState_GetEvalFrameFunc()`` and +``_PyInterpreterState_SetEvalFrameFunc()`` functions to the internal C API. +The ``_PyFrameEvalFunction`` callback function type now uses the +``_PyInterpreterFrame`` type which is part of the internal C API. Patch by +Victor Stinner. + +.. + +.. bpo: 46850 +.. date: 2022-03-22-16-48-02 +.. nonce: 7M5dO7 +.. section: C API + +Move the private undocumented ``_PyEval_EvalFrameDefault()`` function to the +internal C API. The function now uses the ``_PyInterpreterFrame`` type which +is part of the internal C API. Patch by Victor Stinner. + +.. + +.. bpo: 46850 +.. date: 2022-03-21-02-26-27 +.. nonce: hU3c-O +.. section: C API + +Remove the private undocumented function ``_PyEval_CallTracing()`` from the +C API. Call the public :func:`sys.call_tracing` function instead. Patch by +Victor Stinner. + +.. + +.. bpo: 46850 +.. date: 2022-03-21-01-30-14 +.. nonce: Tfxde5 +.. section: C API + +Remove the private undocumented function +``_PyEval_GetCoroutineOriginTrackingDepth()`` from the C API. Call the +public :func:`sys.get_coroutine_origin_tracking_depth` function instead. +Patch by Victor Stinner. + +.. + +.. bpo: 46850 +.. date: 2022-03-21-00-41-29 +.. nonce: rOt771 +.. section: C API + +Remove the following private undocumented functions from the C API: + +* ``_PyEval_GetAsyncGenFirstiter()`` +* ``_PyEval_GetAsyncGenFinalizer()`` +* ``_PyEval_SetAsyncGenFirstiter()`` +* ``_PyEval_SetAsyncGenFinalizer()`` + +Call the public :func:`sys.get_asyncgen_hooks` and +:func:`sys.set_asyncgen_hooks` functions instead. Patch by Victor Stinner. + +.. + +.. bpo: 46987 +.. date: 2022-03-12-18-37-06 +.. nonce: LWcwyN +.. section: C API + +Remove private functions ``_PySys_GetObjectId()`` and +``_PySys_SetObjectId()``. Patch by Donghee Na. + +.. + +.. bpo: 46906 +.. date: 2022-03-03-11-12-33 +.. nonce: -olyBI +.. section: C API + +Add new functions to pack and unpack C double (serialize and deserialize): +:c:func:`PyFloat_Pack2`, :c:func:`PyFloat_Pack4`, :c:func:`PyFloat_Pack8`, +:c:func:`PyFloat_Unpack2`, :c:func:`PyFloat_Unpack4` and +:c:func:`PyFloat_Unpack8`. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/3.11.0b1.rst b/Misc/NEWS.d/3.11.0b1.rst new file mode 100644 index 00000000..c663ca8d --- /dev/null +++ b/Misc/NEWS.d/3.11.0b1.rst @@ -0,0 +1,2146 @@ +.. date: 2022-05-04-14-32-24 +.. gh-issue: 57684 +.. nonce: HrlDrM +.. release date: 2022-05-06 +.. section: Security + +Add the :option:`-P` command line option and the :envvar:`PYTHONSAFEPATH` +environment variable to not prepend a potentially unsafe path to +:data:`sys.path`. Patch by Victor Stinner. + +.. + +.. date: 2022-05-06-02-29-53 +.. gh-issue: 89519 +.. nonce: 4OfkRE +.. section: Core and Builtins + +Chaining classmethod descriptors (introduced in bpo-19072) is deprecated. It +can no longer be used to wrap other descriptors such as property(). The +core design of this feature was flawed, and it caused a number of downstream +problems. + +.. + +.. date: 2022-05-05-20-05-41 +.. gh-issue: 92345 +.. nonce: lnN_RA +.. section: Core and Builtins + +``pymain_run_python()`` now imports ``readline`` and ``rlcompleter`` before +sys.path is extended to include the current working directory of an +interactive interpreter. Non-interactive interpreters are not affected. + +.. + +.. bpo: 43857 +.. date: 2022-05-04-11-37-20 +.. nonce: WuX8p3 +.. section: Core and Builtins + +Improve the :exc:`AttributeError` message when deleting a missing attribute. +Patch by Géry Ogam. + +.. + +.. date: 2022-05-03-14-55-40 +.. gh-issue: 92245 +.. nonce: G17-5i +.. section: Core and Builtins + +Make sure that PEP 523 is respected in all cases. In 3.11a7, specialization +may have prevented Python-to-Python calls respecting PEP 523. + +.. + +.. date: 2022-05-02-17-12-49 +.. gh-issue: 92203 +.. nonce: -igcjS +.. section: Core and Builtins + +Add a closure keyword-only parameter to exec(). It can only be specified +when exec-ing a code object that uses free variables. When specified, it +must be a tuple, with exactly the number of cell variables referenced by the +code object. closure has a default value of None, and it must be None if the +code object doesn't refer to any free variables. + +.. + +.. date: 2022-05-02-12-40-18 +.. gh-issue: 91173 +.. nonce: k_Dr6z +.. section: Core and Builtins + +Disable frozen modules in debug builds. Patch by Kumar Aditya. + +.. + +.. date: 2022-05-01-16-40-07 +.. gh-issue: 92114 +.. nonce: 5xTlLt +.. section: Core and Builtins + +Improve error message when subscript a type with ``__class_getitem__`` set +to ``None``. + +.. + +.. date: 2022-05-01-10-58-38 +.. gh-issue: 92112 +.. nonce: lLJemu +.. section: Core and Builtins + +Fix crash triggered by an evil custom ``mro()`` on a metaclass. + +.. + +.. date: 2022-04-30-04-26-01 +.. gh-issue: 92063 +.. nonce: vHnhf6 +.. section: Core and Builtins + +The ``PRECALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS`` instruction now ensures +methods are called only on objects of the correct type. + +.. + +.. date: 2022-04-29-02-50-41 +.. gh-issue: 92031 +.. nonce: 2PpaIN +.. section: Core and Builtins + +Deoptimize statically allocated code objects during ``Py_FINALIZE()`` so +that future ``_PyCode_Quicken`` calls always start with unquickened code. + +.. + +.. date: 2022-04-28-23-37-30 +.. gh-issue: 92036 +.. nonce: GZJAC9 +.. section: Core and Builtins + +Fix a crash in subinterpreters related to the garbage collector. When a +subinterpreter is deleted, untrack all objects tracked by its GC. To prevent +a crash in deallocator functions expecting objects to be tracked by the GC, +leak a strong reference to these objects on purpose, so they are never +deleted and their deallocator functions are not called. Patch by Victor +Stinner. + +.. + +.. date: 2022-04-28-20-19-49 +.. gh-issue: 92032 +.. nonce: ef-UfM +.. section: Core and Builtins + +The interpreter can now autocomplete soft keywords, as of now ``match``, +``case``, and ``_`` (wildcard pattern) from :pep:`634`. + +.. + +.. date: 2022-04-27-10-36-43 +.. gh-issue: 87999 +.. nonce: YSPHfO +.. section: Core and Builtins + +The warning emitted by the Python parser for a numeric literal immediately +followed by keyword has been changed from deprecation warning to syntax +warning. + +.. + +.. date: 2022-04-26-05-05-32 +.. gh-issue: 91869 +.. nonce: ELbTXl +.. section: Core and Builtins + +Fix an issue where specialized opcodes with extended arguments could produce +incorrect tracing output or lead to assertion failures. + +.. + +.. date: 2022-04-23-22-08-34 +.. gh-issue: 91603 +.. nonce: GcWEkK +.. section: Core and Builtins + +Speed up :class:`types.UnionType` instantiation. Based on patch provided by +Yurii Karabas. + +.. + +.. date: 2022-04-21-16-15-24 +.. gh-issue: 89373 +.. nonce: A1jgLx +.. section: Core and Builtins + +If Python is built in debug mode, Python now ensures that deallocator +functions leave the current exception unchanged. Patch by Victor Stinner. + +.. + +.. date: 2022-04-20-14-43-37 +.. gh-issue: 91632 +.. nonce: cvUhsZ +.. section: Core and Builtins + +Fix a minor memory leak at exit: release the memory of the +:class:`generic_alias_iterator` type. Patch by Donghee Na. + +.. + +.. date: 2022-04-18-20-25-01 +.. gh-issue: 81548 +.. nonce: n3VYgp +.. section: Core and Builtins + +Octal escapes with value larger than ``0o377`` now produce a +:exc:`DeprecationWarning`. In a future Python version they will be a +:exc:`SyntaxWarning` and eventually a :exc:`SyntaxError`. + +.. + +.. bpo: 43950 +.. date: 2022-04-18-15-22-56 +.. nonce: qrTvWL +.. section: Core and Builtins + +Use a single compact table for line starts, ends and column offsets. Reduces +memory consumption for location info by half + +.. + +.. date: 2022-04-18-07-23-48 +.. gh-issue: 91102 +.. nonce: vm-6g1 +.. section: Core and Builtins + +Use Argument Clinic for :class:`EncodingMap`. Patch by Oleg Iarygin. + +.. + +.. date: 2022-04-18-02-45-40 +.. gh-issue: 91636 +.. nonce: 6DFdy_ +.. section: Core and Builtins + +Fixed a crash in a garbage-collection edge-case, in which a +``PyFunction_Type.tp_clear`` function could leave a python function object +in an inconsistent state. + +.. + +.. date: 2022-04-17-11-03-45 +.. gh-issue: 91603 +.. nonce: hYw1Lv +.. section: Core and Builtins + +Speed up :func:`isinstance` and :func:`issubclass` checks for +:class:`types.UnionType`. Patch by Yurii Karabas. + +.. + +.. date: 2022-04-17-02-55-38 +.. gh-issue: 91625 +.. nonce: 80CrC7 +.. section: Core and Builtins + +Fixed a bug in which adaptive opcodes ignored any preceding +``EXTENDED_ARG``\ s on specialization failure. + +.. + +.. date: 2022-04-16-21-54-31 +.. gh-issue: 78607 +.. nonce: _Y7bMm +.. section: Core and Builtins + +The LLTRACE special build now looks for the name ``__lltrace__`` defined in +module globals, rather than the name ``__ltrace__``, which had been +introduced as a typo. + +.. + +.. date: 2022-04-15-16-57-23 +.. gh-issue: 91576 +.. nonce: adoDj_ +.. section: Core and Builtins + +Speed up iteration of ascii strings by 50%. Patch by Kumar Aditya. + +.. + +.. date: 2022-04-13-22-03-04 +.. gh-issue: 89279 +.. nonce: -jAVxZ +.. section: Core and Builtins + +Improve interpreter performance on Windows by inlining a few specific +macros. + +.. + +.. date: 2022-04-13-11-15-09 +.. gh-issue: 91502 +.. nonce: 11YXHQ +.. section: Core and Builtins + +Add a new :c:func:`_PyFrame_IsEntryFrame` API function, to check if a +:c:type:`PyFrameObject` is an entry frame. Patch by Pablo Galindo. + +.. + +.. date: 2022-04-13-07-14-30 +.. gh-issue: 91266 +.. nonce: 6Vkzzt +.. section: Core and Builtins + +Refactor the ``bytearray`` strip methods ``strip``, ``lstrip`` and +``rstrip`` to use a common implementation. + +.. + +.. date: 2022-04-12-11-56-23 +.. gh-issue: 91479 +.. nonce: -dyGJX +.. section: Core and Builtins + +Replaced the ``__note__`` field of :exc:`BaseException` (added in an earlier +version of 3.11) with the final design of :pep:`678`. Namely, +:exc:`BaseException` gets an :meth:`add_note` method, and its ``__notes__`` +field is created when necessary. + +.. + +.. date: 2022-04-12-09-40-57 +.. gh-issue: 46055 +.. nonce: IPb1HA +.. section: Core and Builtins + +Speed up right shift of negative integers, by removing unnecessary creation +of temporaries. Original patch by Xinhang Xu, reworked by Mark Dickinson. + +.. + +.. date: 2022-04-12-00-44-14 +.. gh-issue: 91462 +.. nonce: t8oxyd +.. section: Core and Builtins + +Make the interpreter's low-level tracing (lltrace) feature output more +readable by displaying opcode names (rather than just numbers), and by +displaying stack contents before each opcode. + +.. + +.. date: 2022-04-11-18-44-19 +.. gh-issue: 89455 +.. nonce: d0qMYd +.. section: Core and Builtins + +Fixed an uninitialized bool value in the traceback printing code path that +was introduced by the initial bpo-45292 exception groups work. + +.. + +.. date: 2022-04-10-22-57-27 +.. gh-issue: 91421 +.. nonce: dHhv6U +.. section: Core and Builtins + +Fix a potential integer overflow in _Py_DecodeUTF8Ex. + +.. + +.. date: 2022-04-10-18-47-21 +.. gh-issue: 91428 +.. nonce: ZewV-M +.. section: Core and Builtins + +Add ``static const char *const _PyOpcode_OpName[256] = {...};`` to +``opcode.h`` for debug builds to assist in debugging the Python interpreter. +It is now more convenient to make various forms of debugging output more +human-readable by including opcode names rather than just the corresponding +decimal digits. + +.. + +.. bpo: 47120 +.. date: 2022-04-06-22-50-31 +.. nonce: mbfHs5 +.. section: Core and Builtins + +Make :opcode:`POP_JUMP_IF_TRUE`, :opcode:`POP_JUMP_IF_FALSE`, +:opcode:`POP_JUMP_IF_NONE` and :opcode:`POP_JUMP_IF_NOT_NONE` virtual, +mapping to new relative jump opcodes. + +.. + +.. bpo: 45317 +.. date: 2022-04-04-15-12-38 +.. nonce: UDLOt8 +.. section: Core and Builtins + +Add internal documentation explaining design of new (for 3.11) frame stack. + +.. + +.. bpo: 47197 +.. date: 2022-04-03-17-21-04 +.. nonce: Ji_c30 +.. section: Core and Builtins + +ctypes used to mishandle ``void`` return types, so that for instance a +function declared like ``ctypes.CFUNCTYPE(None, ctypes.c_int)`` would be +called with signature ``int f(int)`` instead of ``void f(int)``. Wasm +targets require function pointers to be called with the correct signatures +so this led to crashes. The problem is now fixed. + +.. + +.. bpo: 47120 +.. date: 2022-03-31-14-33-48 +.. nonce: 6S_uoU +.. section: Core and Builtins + +Make opcodes :opcode:`JUMP_IF_TRUE_OR_POP` and +:opcode:`JUMP_IF_FALSE_OR_POP` relative rather than absolute. + +.. + +.. bpo: 47177 +.. date: 2022-03-31-01-30-03 +.. nonce: fQqaov +.. section: Core and Builtins + +Replace the ``f_lasti`` member of the internal ``_PyInterpreterFrame`` +structure with a ``prev_instr`` pointer, which reduces overhead in the main +interpreter loop. The ``f_lasti`` attribute of Python-layer frame objects is +preserved for backward-compatibility. + +.. + +.. bpo: 46961 +.. date: 2022-03-13-08-23-17 +.. nonce: SgGCkG +.. section: Core and Builtins + +Integer mod/remainder operations, including the three-argument form of +:func:`pow`, now consistently return ints from the global small integer +cache when applicable. + +.. + +.. bpo: 46962 +.. date: 2022-03-08-21-59-57 +.. nonce: UomDfz +.. section: Core and Builtins + +Classes and functions that unconditionally declared their docstrings +ignoring the `--without-doc-strings` compilation flag no longer do so. + +The classes affected are :class:`ctypes.UnionType`, +:class:`pickle.PickleBuffer`, :class:`testcapi.RecursingInfinitelyError`, +and :class:`types.GenericAlias`. + +The functions affected are 24 methods in :mod:`ctypes`. + +Patch by Oleg Iarygin. + +.. + +.. bpo: 46942 +.. date: 2022-03-07-11-51-51 +.. nonce: 57obVi +.. section: Core and Builtins + +Use Argument Clinic for the :class:`types.MethodType` constructor. Patch by +Oleg Iarygin. + +.. + +.. bpo: 46764 +.. date: 2022-02-16-03-23-38 +.. nonce: wEY4bS +.. section: Core and Builtins + +Fix wrapping bound methods with @classmethod + +.. + +.. bpo: 43464 +.. date: 2022-02-13-21-53-29 +.. nonce: yupHjd +.. section: Core and Builtins + +Optimize :meth:`set.intersection` for non-set arguments. + +.. + +.. bpo: 46721 +.. date: 2022-02-11-17-16-30 +.. nonce: JkHaLF +.. section: Core and Builtins + +Optimize :meth:`set.issuperset` for non-set argument. + +.. + +.. bpo: 46509 +.. date: 2022-01-25-05-39-38 +.. nonce: ljrqrc +.. section: Core and Builtins + +Add type-specialized versions of the ``Py_DECREF()``, and use them for +``float``, ``int``, ``str``, ``bool``, and ``None`` to avoid pointer-chasing +at runtime where types are known at C compile time. + +.. + +.. bpo: 46045 +.. date: 2021-12-11-11-36-48 +.. nonce: sfThay +.. section: Core and Builtins + +Do not use POSIX semaphores on NetBSD + +.. + +.. bpo: 36819 +.. date: 2021-09-28-10-58-30 +.. nonce: cyV50C +.. section: Core and Builtins + +Fix crashes in built-in encoders with error handlers that return position +less or equal than the starting position of non-encodable characters. + +.. + +.. bpo: 34093 +.. date: 2018-07-14-16-58-00 +.. nonce: WaVD-f +.. section: Core and Builtins + +``marshal.dumps()`` uses ``FLAG_REF`` for all interned strings. This makes +output more deterministic and helps reproducible build. + +.. + +.. bpo: 26579 +.. date: 2017-07-23-11-28-45 +.. nonce: lpCY8R +.. section: Core and Builtins + +Added ``object.__getstate__`` which provides the default implementation of +the ``__getstate__()`` method. + +Copying and pickling instances of subclasses of builtin types bytearray, +set, frozenset, collections.OrderedDict, collections.deque, weakref.WeakSet, +and datetime.tzinfo now copies and pickles instance attributes implemented +as slots. + +.. + +.. date: 2022-05-06-13-53-10 +.. gh-issue: 87901 +.. nonce: NnkUVr +.. section: Library + +Add the *encoding* parameter to :func:`os.popen`. + +.. + +.. date: 2022-05-06-09-48-07 +.. gh-issue: 90997 +.. nonce: 4PmCgX +.. section: Library + +Fix an issue where :mod:`dis` utilities may interpret populated inline cache +entries as valid instructions. + +.. + +.. date: 2022-05-05-22-46-52 +.. gh-issue: 92332 +.. nonce: Fv9CJx +.. section: Library + +Deprecate :class:`typing.Text` (removal of the class is currently not +planned). Patch by Alex Waygood. + +.. + +.. gh: 78157 +.. date: 2022-05-05-20-40-45 +.. nonce: IA_9na +.. section: Library + +Deprecate nested classes in enum definitions becoming members -- in 3.13 +they will be normal classes; add `member` and `nonmember` functions to allow +control over results now. + +.. + +.. date: 2022-05-05-19-25-09 +.. gh-issue: 92356 +.. nonce: uvxWdu +.. section: Library + +Fixed a performance regression in ctypes function calls. + +.. + +.. date: 2022-05-05-17-35-01 +.. gh-issue: 90997 +.. nonce: UV5_s0 +.. section: Library + +Show the actual named values stored in inline caches when +``show_caches=True`` is passed to :mod:`dis` utilities. + +.. + +.. date: 2022-05-04-11-54-37 +.. gh-issue: 92301 +.. nonce: eqjoYX +.. section: Library + +Prefer ``close_range()`` to iterating over procfs for file descriptor +closing in :mod:`subprocess` for better performance. + +.. + +.. date: 2022-05-03-19-06-38 +.. gh-issue: 67248 +.. nonce: DK61Go +.. section: Library + +Sort the miscellaneous topics in Cmd.do_help() + +.. + +.. date: 2022-05-03-17-33-46 +.. gh-issue: 92210 +.. nonce: csDOQM +.. section: Library + +Port ``socket.__init__`` to Argument Clinic. Patch by Cinder. + +.. + +.. date: 2022-05-03-12-11-27 +.. gh-issue: 80010 +.. nonce: yG54RE +.. section: Library + +Add support for generalized ISO 8601 parsing to +:meth:`datetime.datetime.fromisoformat`, :meth:`datetime.date.fromisoformat` +and :meth:`datetime.time.fromisoformat`. Patch by Paul Ganssle. + +.. + +.. date: 2022-05-02-23-08-02 +.. gh-issue: 92118 +.. nonce: 9Mm9g4 +.. section: Library + +Fix a 3.11 regression in :func:`~contextlib.contextmanager`, which caused it +to propagate exceptions with incorrect tracebacks. + +.. + +.. date: 2022-05-02-18-19-46 +.. gh-issue: 90887 +.. nonce: zQsmfp +.. section: Library + +Adding ``COPYFILE_STAT``, ``COPYFILE_ACL`` and ``COPYFILE_XATTR`` constants +for :func:`os.fcopyfile` available in macOs. + +.. + +.. date: 2022-05-02-09-09-47 +.. gh-issue: 91215 +.. nonce: l1p7CJ +.. section: Library + +For @dataclass, add weakref_slot. Default is False. If True, and if +slots=True, add a slot named "__weakref__", which will allow instances to be +weakref'd. Contributed by Eric V. Smith + +.. + +.. date: 2022-05-02-03-56-50 +.. gh-issue: 85984 +.. nonce: RBivvc +.. section: Library + +New function os.login_tty() for Unix. + +.. + +.. date: 2022-05-01-21-45-41 +.. gh-issue: 92128 +.. nonce: Di7VbE +.. section: Library + +Add :meth:`~object.__class_getitem__` to :class:`logging.LoggerAdapter` and +:class:`logging.StreamHandler`, allowing them to be parameterized at +runtime. Patch by Alex Waygood. + +.. + +.. date: 2022-04-30-10-53-10 +.. gh-issue: 92049 +.. nonce: 5SEKoh +.. section: Library + +Forbid pickling constants ``re._constants.SUCCESS`` etc. Previously, +pickling did not fail, but the result could not be unpickled. + +.. + +.. date: 2022-04-29-18-15-23 +.. gh-issue: 92062 +.. nonce: X2c_Rj +.. section: Library + +:class:`inspect.Parameter` now raises :exc:`ValueError` if ``name`` is a +keyword, in addition to the existing check that it is an identifier. + +.. + +.. date: 2022-04-29-16-41-08 +.. gh-issue: 87390 +.. nonce: 3LNNCv +.. section: Library + +Add an ``__unpacked__`` attribute to :class:`types.GenericAlias`. Patch by +Jelle Zijlstra. + +.. + +.. date: 2022-04-28-18-45-58 +.. gh-issue: 88089 +.. nonce: hu9kRk +.. section: Library + +Add support for generic :class:`typing.NamedTuple`. + +.. + +.. date: 2022-04-27-19-45-58 +.. gh-issue: 91996 +.. nonce: YEEIzk +.. section: Library + +New http.HTTPMethod enum to represent all the available HTTP request methods +in a convenient way + +.. + +.. date: 2022-04-27-18-30-00 +.. gh-issue: 91984 +.. nonce: LxAB11 +.. section: Library + +Modified test strings in test_argparse.py to not contain trailing spaces +before end of line. + +.. + +.. date: 2022-04-27-18-04-24 +.. gh-issue: 91952 +.. nonce: 9A4RXx +.. section: Library + +Add ``encoding="locale"`` support to :meth:`TextIOWrapper.reconfigure`. + +.. + +.. date: 2022-04-27-13-30-26 +.. gh-issue: 91954 +.. nonce: cC7ga_ +.. section: Library + +Add *encoding* and *errors* arguments to :func:`subprocess.getoutput` and +:func:`subprocess.getstatusoutput`. + +.. + +.. bpo: 47029 +.. date: 2022-04-26-19-01-13 +.. nonce: qkT42X +.. section: Library + +Always close the read end of the pipe used by :class:`multiprocessing.Queue` +*after* the last write of buffered data to the write end of the pipe to +avoid :exc:`BrokenPipeError` at garbage collection and at +:meth:`multiprocessing.Queue.close` calls. Patch by Géry Ogam. + +.. + +.. date: 2022-04-26-18-02-44 +.. gh-issue: 91928 +.. nonce: V0YveU +.. section: Library + +Add `datetime.UTC` alias for `datetime.timezone.utc`. + +Patch by Kabir Kwatra. + +.. + +.. date: 2022-04-26-09-09-07 +.. gh-issue: 68966 +.. nonce: roapI2 +.. section: Library + +The :mod:`mailcap` module is now deprecated and will be removed in Python +3.13. See :pep:`594` for the rationale and the :mod:`mimetypes` module for +an alternative. Patch by Victor Stinner. + +.. + +.. date: 2022-04-25-21-33-48 +.. gh-issue: 91401 +.. nonce: _Jo4Bu +.. section: Library + +Provide a way to disable :mod:`subprocess` use of ``vfork()`` just in case +it is ever needed and document the existing mechanism for ``posix_spawn()``. + +.. + +.. date: 2022-04-25-18-30-20 +.. gh-issue: 64783 +.. nonce: HFtERN +.. section: Library + +Fix :const:`signal.NSIG` value on FreeBSD to accept signal numbers greater +than 32, like :const:`signal.SIGRTMIN` and :const:`signal.SIGRTMAX`. Patch by +Victor Stinner. + +.. + +.. date: 2022-04-25-14-18-01 +.. gh-issue: 91910 +.. nonce: kY-JR0 +.. section: Library + +Add missing f prefix to f-strings in error messages from the +:mod:`multiprocessing` and :mod:`asyncio` modules. + +.. + +.. date: 2022-04-23-08-06-36 +.. gh-issue: 91860 +.. nonce: ityDjK +.. section: Library + +Add :func:`typing.dataclass_transform`, implementing :pep:`681`. Patch by +Jelle Zijlstra. + +.. + +.. date: 2022-04-23-03-24-00 +.. gh-issue: 91832 +.. nonce: TyLi65 +.. section: Library + +Add ``required`` attribute to :class:`argparse.Action` repr output. + +.. + +.. date: 2022-04-22-19-11-31 +.. gh-issue: 91827 +.. nonce: 6P3gOI +.. section: Library + +In the :mod:`tkinter` module add method ``info_patchlevel()`` which returns +the exact version of the Tcl library as a named tuple similar to +:data:`sys.version_info`. + +.. + +.. date: 2022-04-22-13-01-20 +.. gh-issue: 84461 +.. nonce: rsCiTH +.. section: Library + +Add :option:`--enable-wasm-pthreads` to enable pthreads support for WASM +builds. ``Emscripten/node`` no longer has threading enabled by default. +Include additional file systems. + +.. + +.. date: 2022-04-22-08-25-18 +.. gh-issue: 91821 +.. nonce: XwMkj0 +.. section: Library + +Fix unstable ``test_from_tuple`` test in ``test_decimal.py``. + +.. + +.. date: 2022-04-21-21-06-54 +.. gh-issue: 91217 +.. nonce: 2cVma_ +.. section: Library + +Deprecate the xdrlib module. + +.. + +.. date: 2022-04-21-21-04-08 +.. gh-issue: 91217 +.. nonce: BZVEki +.. section: Library + +Deprecate the uu module. + +.. + +.. date: 2022-04-21-19-46-03 +.. gh-issue: 91760 +.. nonce: zDtv1E +.. section: Library + +More strict rules will be applied for numerical group references and group +names in regular expressions. For now, a deprecation warning is emitted for +group references and group names which will be errors in future Python +versions. + +.. + +.. date: 2022-04-21-11-57-23 +.. gh-issue: 84461 +.. nonce: S7dbt4 +.. section: Library + +Add provisional :data:`sys._emscripten_info` named tuple with build-time and +run-time information about Emscripten platform. + +.. + +.. date: 2022-04-20-18-47-27 +.. gh-issue: 90623 +.. nonce: 5fROpX +.. section: Library + +:func:`signal.raise_signal` and :func:`os.kill` now check immediately for +pending signals. Patch by Victor Stinner. + +.. + +.. date: 2022-04-20-09-49-33 +.. gh-issue: 91734 +.. nonce: 4Dj4Gy +.. section: Library + +Fix OSS audio support on Solaris. + +.. + +.. date: 2022-04-19-19-50-10 +.. gh-issue: 90633 +.. nonce: Youov0 +.. section: Library + +Include the passed value in the exception thrown by +:func:`typing.assert_never`. Patch by Jelle Zijlstra. + +.. + +.. date: 2022-04-19-17-30-17 +.. gh-issue: 91700 +.. nonce: MRJi6m +.. section: Library + +Compilation of regular expression containing a conditional expression +``(?(group)...)`` now raises an appropriate :exc:`re.error` if the group +number refers to not defined group. Previously an internal RuntimeError was +raised. + +.. + +.. date: 2022-04-19-15-30-06 +.. gh-issue: 91231 +.. nonce: AWy4Cs +.. section: Library + +Add an optional keyword *shutdown_timeout* parameter to the +:class:`multiprocessing.BaseManager` constructor. Kill the process if +terminate() takes longer than the timeout. Patch by Victor Stinner. + +.. + +.. date: 2022-04-18-18-55-21 +.. gh-issue: 91621 +.. nonce: ACNlda +.. section: Library + +Fix :func:`typing.get_type_hints` for :class:`collections.abc.Callable`. +Patch by Shantanu Jain. + +.. + +.. date: 2022-04-18-16-31-33 +.. gh-issue: 90568 +.. nonce: 9kiU7o +.. section: Library + +Parsing ``\N`` escapes of Unicode Named Character Sequences in a +:mod:`regular expression <re>` raises now :exc:`re.error` instead of +``TypeError``. + +.. + +.. date: 2022-04-18-15-23-24 +.. gh-issue: 91670 +.. nonce: 6eyChw +.. section: Library + +Remove deprecated ``SO`` config variable in :mod:`sysconfig`. + +.. + +.. date: 2022-04-17-12-41-52 +.. gh-issue: 91217 +.. nonce: 3wnHSX +.. section: Library + +Deprecate the telnetlib module. + +.. + +.. date: 2022-04-17-12-38-31 +.. gh-issue: 91217 +.. nonce: 55714p +.. section: Library + +Deprecate the sunau module. + +.. + +.. date: 2022-04-17-12-32-40 +.. gh-issue: 91217 +.. nonce: ms49Rg +.. section: Library + +Deprecate the spwd module. + +.. + +.. date: 2022-04-17-12-27-46 +.. gh-issue: 91217 +.. nonce: tNDWtK +.. section: Library + +Deprecate the sndhdr module, as well as inline needed functionality for +``email.mime.MIMEAudio``. + +.. + +.. date: 2022-04-17-12-27-25 +.. gh-issue: 91616 +.. nonce: gSQg69 +.. section: Library + +:mod:`re` module, fix :meth:`~re.Pattern.fullmatch` mismatch when using +Atomic Grouping or Possessive Quantifiers. + +.. + +.. date: 2022-04-17-12-07-50 +.. gh-issue: 91217 +.. nonce: TIvrsq +.. section: Library + +Deprecate the 'pipes' module. + +.. + +.. date: 2022-04-17-11-56-17 +.. gh-issue: 91217 +.. nonce: McJre3 +.. section: Library + +Deprecate the ossaudiodev module. + +.. + +.. bpo: 47256 +.. date: 2022-04-16-11-39-59 +.. nonce: 1cygyd +.. section: Library + +:mod:`re` module, limit the maximum capturing group to 1,073,741,823 in +64-bit build, this increases the depth of backtracking. + +.. + +.. date: 2022-04-16-09-33-14 +.. gh-issue: 91217 +.. nonce: nt9JFs +.. section: Library + +Deprecate the nis module. + +.. + +.. date: 2022-04-16-05-12-13 +.. gh-issue: 91595 +.. nonce: CocJBv +.. section: Library + +Fix the comparison of character and integer inside +:func:`Tools.gdb.libpython.write_repr`. Patch by Yu Liu. + +.. + +.. date: 2022-04-15-20-56-31 +.. gh-issue: 74166 +.. nonce: 70KlvL +.. section: Library + +Add option to raise all errors from :meth:`~socket.create_connection` in an +:exc:`ExceptionGroup` when it fails to create a connection. The default +remains to raise only the last error that had occurred when multiple +addresses were tried. + +.. + +.. date: 2022-04-15-19-34-02 +.. gh-issue: 91487 +.. nonce: 2aqguF +.. section: Library + +Optimize asyncio UDP speed, over 100 times faster when transferring a large +file. + +.. + +.. date: 2022-04-15-18-38-21 +.. gh-issue: 91575 +.. nonce: fSyAxS +.. section: Library + +Update case-insensitive matching in the :mod:`re` module to the latest +Unicode version. + +.. + +.. date: 2022-04-15-18-32-38 +.. gh-issue: 90622 +.. nonce: WQjFDe +.. section: Library + +In ``concurrent.futures.process.ProcessPoolExecutor`` disallow the "fork" +multiprocessing start method when the new ``max_tasks_per_child`` feature is +used as the mix of threads+fork can hang the child processes. Default to +using the safe "spawn" start method in that circumstance if no +``mp_context`` was supplied. + +.. + +.. date: 2022-04-15-17-06-09 +.. gh-issue: 89022 +.. nonce: DgdQCa +.. section: Library + +In :mod:`sqlite3`, ``SQLITE_MISUSE`` result codes are now mapped to +:exc:`~sqlite3.InterfaceError` instead of :exc:`~sqlite3.ProgrammingError`. +Also, more accurate exceptions are raised when binding parameters fail. +Patch by Erlend E. Aasland. + +.. + +.. date: 2022-04-14-18-06-00 +.. gh-issue: 91526 +.. nonce: cwfhSB +.. section: Library + +Stop calling ``os.device_encoding(file.fileno())`` in +:class:`TextIOWrapper`. It was complex, never documented, and didn't work +for most cases. (Patch by Inada Naoki.) + +.. + +.. date: 2022-04-14-13-11-37 +.. gh-issue: 88116 +.. nonce: j_SybE +.. section: Library + +Change the frame-related functions in the :mod:`inspect` module to return a +regular object (that is backwards compatible with the old tuple-like +interface) that include the extended :pep:`657` position information (end +line number, column and end column). The affected functions are: +:func:`inspect.getframeinfo`, :func:`inspect.getouterframes`, +:func:`inspect.getinnerframes`, :func:`inspect.stack` and +:func:`inspect.trace`. Patch by Pablo Galindo. + +.. + +.. date: 2022-04-14-01-00-31 +.. gh-issue: 69093 +.. nonce: bmlMwI +.. section: Library + +Add indexing and slicing support to :class:`sqlite3.Blob`. Patch by Aviv +Palivoda and Erlend E. Aasland. + +.. + +.. date: 2022-04-14-00-59-01 +.. gh-issue: 69093 +.. nonce: bmlMwI +.. section: Library + +Add :term:`context manager` support to :class:`sqlite3.Blob`. Patch by Aviv +Palivoda and Erlend E. Aasland. + +.. + +.. date: 2022-04-12-20-19-10 +.. gh-issue: 91217 +.. nonce: acd4h9 +.. section: Library + +Deprecate nntplib. + +.. + +.. date: 2022-04-12-19-42-20 +.. gh-issue: 91217 +.. nonce: b9_Rz9 +.. section: Library + +Deprecate msilib. + +.. + +.. date: 2022-04-12-19-08-13 +.. gh-issue: 91404 +.. nonce: zjqYHo +.. section: Library + +Improve the performance of :mod:`re` matching by using computed gotos (or +"threaded code") on supported platforms and removing expensive pointer +indirections. + +.. + +.. date: 2022-04-11-17-04-38 +.. gh-issue: 91217 +.. nonce: QVDLOq +.. section: Library + +Deprecate the imghdr module. + +.. + +.. date: 2022-04-11-16-13-26 +.. gh-issue: 91217 +.. nonce: 2rf8rc +.. section: Library + +Deprecate the crypt module. + +.. + +.. date: 2022-04-11-13-07-30 +.. gh-issue: 91276 +.. nonce: Vttu15 +.. section: Library + +Make space for longer opcodes in :mod:`dis` output. + +.. + +.. bpo: 47000 +.. date: 2022-04-10-17-50-18 +.. nonce: JlQkFx +.. section: Library + +Make :class:`TextIOWrapper` uses locale encoding when ``encoding="locale"`` +is specified even in UTF-8 mode. + +.. + +.. date: 2022-04-10-17-12-23 +.. gh-issue: 91230 +.. nonce: T1d_fG +.. section: Library + +:func:`warnings.catch_warnings` now accepts arguments for +:func:`warnings.simplefilter`, providing a more concise way to locally +ignore warnings or convert them to errors. + +.. + +.. date: 2022-04-10-11-11-33 +.. gh-issue: 91217 +.. nonce: K82AuH +.. section: Library + +Deprecate the chunk module. + +.. + +.. gh: 91498 +.. date: 2022-04-10-08-39-44 +.. nonce: 8oII92 +.. section: Library + +Add the ``TCP_CONNECTION_INFO`` option (available on macOS) to +:mod:`socket`. + +.. + +.. bpo: 47260 +.. date: 2022-04-08-14-30-53 +.. nonce: TtcNxI +.. section: Library + +Fix ``os.closerange()`` potentially being a no-op in a Linux seccomp +sandbox. + +.. + +.. bpo: 47087 +.. date: 2022-04-08-08-55-36 +.. nonce: Q5C3EI +.. section: Library + +Implement ``typing.Required`` and ``typing.NotRequired`` (:pep:`655`). Patch +by David Foster and Jelle Zijlstra. + +.. + +.. bpo: 47061 +.. date: 2022-04-07-20-32-47 +.. nonce: TOufgh +.. section: Library + +Deprecate cgi and cgitb. + +.. + +.. bpo: 47061 +.. date: 2022-04-06-18-01-28 +.. nonce: qoVTR9 +.. section: Library + +Deprecate audioop. + +.. + +.. bpo: 47000 +.. date: 2022-04-06-11-54-53 +.. nonce: 2nmAR1 +.. section: Library + +Add :func:`locale.getencoding` to get the current locale encoding. It is +similar to ``locale.getpreferredencoding(False)`` but ignores the +:ref:`Python UTF-8 Mode <utf8-mode>`. + +.. + +.. bpo: 42012 +.. date: 2022-04-05-17-18-13 +.. nonce: zMocQz +.. section: Library + +Add :mod:`wsgiref.types`, containing WSGI-specific types for static type +checking. + +.. + +.. bpo: 47227 +.. date: 2022-04-05-15-53-58 +.. nonce: 1HWdp9 +.. section: Library + +Suppress expression chaining for more :mod:`re` parsing errors. + +.. + +.. bpo: 47211 +.. date: 2022-04-04-11-58-07 +.. nonce: W4GFkB +.. section: Library + +Remove undocumented and never working function ``re.template()`` and flag +``re.TEMPLATE``. +This was later reverted in 3.11.0b2 and deprecated instead. + +.. + +.. bpo: 47135 +.. date: 2022-04-01-21-44-00 +.. nonce: TvkKB- +.. section: Library + +:meth:`decimal.localcontext` now accepts context attributes via keyword +arguments + +.. + +.. bpo: 43323 +.. date: 2022-03-27-12-40-16 +.. nonce: 9mFPuI +.. section: Library + +Fix errors in the :mod:`email` module if the charset itself contains +undecodable/unencodable characters. + +.. + +.. bpo: 46841 +.. date: 2022-03-25-22-18-45 +.. nonce: NUEsXW +.. section: Library + +Disassembly of quickened code. + +.. + +.. bpo: 46681 +.. date: 2022-03-21-13-50-07 +.. nonce: RRhopn +.. section: Library + +Forward gzip.compress() compresslevel to zlib. + +.. + +.. bpo: 45100 +.. date: 2022-03-06-18-15-32 +.. nonce: B_lHu0 +.. section: Library + +Add :func:`typing.get_overloads` and :func:`typing.clear_overloads`. Patch +by Jelle Zijlstra. + +.. + +.. bpo: 44807 +.. date: 2022-03-02-04-25-58 +.. nonce: gHNC9J +.. section: Library + +:class:`typing.Protocol` no longer silently replaces :meth:`__init__` +methods defined on subclasses. Patch by Adrian Garcia Badaracco. + +.. + +.. bpo: 46787 +.. date: 2022-02-18-20-09-29 +.. nonce: juwWc0 +.. section: Library + +Fix :class:`concurrent.futures.ProcessPoolExecutor` exception memory leak + +.. + +.. bpo: 46720 +.. date: 2022-02-11-23-11-35 +.. nonce: nY8spB +.. section: Library + +Add support for path-like objects to :func:`multiprocessing.set_executable` +for Windows to be on a par with Unix-like systems. Patch by Géry Ogam. + +.. + +.. bpo: 46696 +.. date: 2022-02-09-21-40-02 +.. nonce: nPXRno +.. section: Library + +Add ``SO_INCOMING_CPU`` constant to :mod:`socket`. + +.. + +.. bpo: 46053 +.. date: 2022-02-06-12-59-32 +.. nonce: sHFo3S +.. section: Library + +Fix OSS audio support on NetBSD. + +.. + +.. bpo: 45639 +.. date: 2022-02-02-04-51-39 +.. nonce: N8XrGO +.. section: Library + +``image/avif`` and ``image/webp`` were added to :mod:`mimetypes`. + +.. + +.. bpo: 46285 +.. date: 2022-01-29-00-23-00 +.. nonce: pt84qm +.. section: Library + +Add command-line option ``-p``/``--protocol`` to module :mod:`http.server` +which specifies the HTTP version to which the server is conformant (HTTP/1.1 +conformant servers can now be run from the command-line interface of module +:mod:`http.server`). Patch by Géry Ogam. + +.. + +.. bpo: 44791 +.. date: 2022-01-27-14-46-15 +.. nonce: tR1JFG +.. section: Library + +Accept ellipsis as the last argument of :data:`typing.Concatenate`. + +.. + +.. bpo: 46547 +.. date: 2022-01-27-14-41-55 +.. nonce: JMyYz9 +.. section: Library + +Remove variables leaking into ``pydoc.Helper`` class namespace. + +.. + +.. bpo: 46415 +.. date: 2022-01-17-16-53-30 +.. nonce: 6wSYg- +.. section: Library + +Fix ipaddress.ip_{address,interface,network} raising TypeError instead of +ValueError if given invalid tuple as address parameter. + +.. + +.. bpo: 46075 +.. date: 2021-12-14-21-19-04 +.. nonce: KDtcU- +.. section: Library + +``CookieJar`` with ``DefaultCookiePolicy`` now can process cookies from +localhost with domain=localhost explicitly specified in Set-Cookie header. + +.. + +.. bpo: 45995 +.. date: 2021-12-14-13-15-41 +.. nonce: Am9pNL +.. section: Library + +Add a "z" option to the string formatting specification that coerces +negative zero floating-point values to positive zero after rounding to the +format precision. Contributed by John Belmonte. + +.. + +.. bpo: 26175 +.. date: 2021-11-14-01-35-04 +.. nonce: LNlOfI +.. section: Library + +Fully implement the :class:`io.BufferedIOBase` or :class:`io.TextIOBase` +interface for :class:`tempfile.SpooledTemporaryFile` objects. This lets them +work correctly with higher-level layers (like compression modules). Patch by +Carey Metcalfe. + +.. + +.. bpo: 45138 +.. date: 2021-09-08-16-21-03 +.. nonce: yghUrK +.. section: Library + +Fix a regression in the :mod:`sqlite3` trace callback where bound parameters +were not expanded in the passed statement string. The regression was +introduced in Python 3.10 by :issue:`40318`. Patch by Erlend E. Aasland. + +.. + +.. bpo: 44863 +.. date: 2021-09-03-07-56-48 +.. nonce: udgz95 +.. section: Library + +Allow :class:`~typing.TypedDict` subclasses to also include +:class:`~typing.Generic` as a base class in class based syntax. Thereby +allowing the user to define a generic ``TypedDict``, just like a +user-defined generic but with ``TypedDict`` semantics. + +.. + +.. bpo: 44587 +.. date: 2021-08-17-21-41-39 +.. nonce: 57OKSz +.. section: Library + +Fix BooleanOptionalAction to not automatically add a default string. If a +default string is desired, use a formatter to add it. + +.. + +.. bpo: 43827 +.. date: 2021-04-16-17-32-44 +.. nonce: uJaXdP +.. section: Library + +All positional-or-keyword parameters to ``ABCMeta.__new__`` are now +positional-only to avoid conflicts with keyword arguments to be passed to +:meth:`__init_subclass__`. + +.. + +.. bpo: 43218 +.. date: 2021-02-14-20-55-53 +.. nonce: VZv2M4 +.. section: Library + +Prevent creation of a venv whose path contains the PATH separator. This +could affect the usage of the activate script. Patch by Dustin Rodrigues. + +.. + +.. bpo: 38435 +.. date: 2020-12-24-19-11-53 +.. nonce: rEHTAR +.. section: Library + +Add a ``process_group`` parameter to :class:`subprocess.Popen` to help move +more things off of the unsafe ``preexec_fn`` parameter. + +.. + +.. bpo: 42066 +.. date: 2020-10-19-08-50-41 +.. nonce: DsB-R6 +.. section: Library + +Fix cookies getting sorted in :func:`CookieJar.__iter__` which is an extra +behavior and not mentioned in RFC 2965 or Netscape cookie protocol. Now the +cookies in ``CookieJar`` follows the order of the ``Set-Cookie`` header. +Patch by Iman Kermani. + +.. + +.. bpo: 40617 +.. date: 2020-05-24-23-52-03 +.. nonce: lycF9q +.. section: Library + +Add :meth:`~sqlite3.Connection.create_window_function` to +:class:`sqlite3.Connection` for creating aggregate window functions. Patch +by Erlend E. Aasland. + +.. + +.. bpo: 40676 +.. date: 2020-05-19-01-40-51 +.. nonce: yJfq1J +.. section: Library + +Convert :mod:`csv` to use Argument Clinic for :func:`csv.field_size_limit`, +:func:`csv.get_dialect`, :func:`csv.unregister_dialect` and +:func:`csv.list_dialects`. + +.. + +.. bpo: 39716 +.. date: 2020-02-22-12-02-11 +.. nonce: z2WhDQ +.. section: Library + +Raise an ArgumentError when the same subparser name is added twice to an +`argparse.ArgumentParser`. This is consistent with the (default) behavior +when the same option string is added twice to an ArgumentParser. + +.. + +.. bpo: 36073 +.. date: 2019-06-22-11-01-45 +.. nonce: ED8mB9 +.. section: Library + +Raise :exc:`~sqlite3.ProgrammingError` instead of segfaulting on recursive +usage of cursors in :mod:`sqlite3` converters. Patch by Sergey Fedoseev. + +.. + +.. bpo: 34975 +.. date: 2019-05-06-23-36-34 +.. nonce: eb49jr +.. section: Library + +Adds a ``start_tls()`` method to :class:`~asyncio.streams.StreamWriter`, +which upgrades the connection with TLS using the given +:class:`~ssl.SSLContext`. + +.. + +.. bpo: 22276 +.. date: 2018-11-11-04-41-11 +.. nonce: Tt19TW +.. section: Library + +:class:`~pathlib.Path` methods :meth:`~pathlib.Path.glob` and +:meth:`~pathlib.Path.rglob` return only directories if *pattern* ends with a +pathname components separator (``/`` or :data:`~os.sep`). Patch by Eisuke +Kawashima. + +.. + +.. bpo: 24905 +.. date: 2018-04-18-16-15-55 +.. nonce: jYqjYx +.. section: Library + +Add :meth:`~sqlite3.Connection.blobopen` to :class:`sqlite3.Connection`. +:class:`sqlite3.Blob` allows incremental I/O operations on blobs. Patch by +Aviv Palivoda and Erlend E. Aasland. + +.. + +.. date: 2022-04-24-22-09-31 +.. gh-issue: 91888 +.. nonce: kTjJLx +.. section: Documentation + +Add a new `gh` role to the documentation to link to GitHub issues. + +.. + +.. date: 2022-04-23-00-22-54 +.. gh-issue: 91783 +.. nonce: N09dRR +.. section: Documentation + +Document security issues concerning the use of the function +:meth:`shutil.unpack_archive` + +.. + +.. date: 2022-04-19-20-16-00 +.. gh-issue: 91547 +.. nonce: LsNWER +.. section: Documentation + +Remove "Undocumented modules" page. + +.. + +.. date: 2022-04-17-03-19-51 +.. gh-issue: 91298 +.. nonce: NT9qHi +.. section: Documentation + +In ``importlib.resources.abc``, refined the documentation of the Traversable +Protocol, applying changes from importlib_resources 5.7.1. + +.. + +.. bpo: 44347 +.. date: 2022-04-10-20-28-20 +.. nonce: Q1m3DM +.. section: Documentation + +Clarify the meaning of *dirs_exist_ok*, a kwarg of :func:`shutil.copytree`. + +.. + +.. bpo: 36329 +.. date: 2022-04-06-11-53-41 +.. nonce: EVtAtK +.. section: Documentation + +Remove 'make -C Doc serve' in favour of 'make -C Doc htmlview' + +.. + +.. bpo: 47189 +.. date: 2022-04-01-23-56-13 +.. nonce: Nss0Y3 +.. section: Documentation + +Add a What's New in Python 3.11 entry for the Faster CPython project. +Documentation by Ken Jin and Kumar Aditya. + +.. + +.. bpo: 38668 +.. date: 2022-04-01-09-28-31 +.. nonce: j4mrqW +.. section: Documentation + +Update the introduction to documentation for :mod:`os.path` to remove +warnings that became irrelevant after the implementations of :pep:`383` and +:pep:`529`. + +.. + +.. bpo: 47115 +.. date: 2022-03-30-17-08-12 +.. nonce: R3wt3i +.. section: Documentation + +The documentation now lists which members of C structs are part of the +:ref:`Limited API/Stable ABI <stable>`. + +.. + +.. bpo: 46962 +.. date: 2022-03-08-22-10-38 +.. nonce: FIVe9I +.. section: Documentation + +All docstrings in code snippets are now wrapped into :c:macro:`PyDoc_STR` to +follow the guideline of `PEP 7's Documentation Strings paragraph +<https://www.python.org/dev/peps/pep-0007/#documentation-strings>`_. Patch +by Oleg Iarygin. + +.. + +.. bpo: 26792 +.. date: 2022-01-23-20-44-53 +.. nonce: dQ1v1W +.. section: Documentation + +Improve the docstrings of :func:`runpy.run_module` and +:func:`runpy.run_path`. Original patch by Andrew Brezovsky. + +.. + +.. date: 2022-05-02-20-57-04 +.. gh-issue: 92169 +.. nonce: Xi4NGV +.. section: Tests + +Use ``warnings_helper.import_deprecated()`` to import deprecated modules +uniformly in tests. Patch by Hugo van Kemenade. + +.. + +.. date: 2022-05-02-20-15-54 +.. gh-issue: 84461 +.. nonce: DhxllI +.. section: Tests + +When multiprocessing is enabled, libregrtest can now use a Python executable +other than :code:`sys.executable` via the ``--python`` flag. + +.. + +.. date: 2022-04-25-11-16-36 +.. gh-issue: 91904 +.. nonce: 13Uvrz +.. section: Tests + +Fix initialization of :envvar:`PYTHONREGRTEST_UNICODE_GUARD` which prevented +running regression tests on non-UTF-8 locale. + +.. + +.. date: 2022-04-22-19-00-00 +.. gh-issue: 91752 +.. nonce: Ji27dd +.. section: Tests + +Added @requires_zlib to test.test_tools.test_freeze.TestFreeze. + +.. + +.. date: 2022-04-16-17-54-05 +.. gh-issue: 91607 +.. nonce: FnXjtW +.. section: Tests + +Fix ``test_concurrent_futures`` to test the correct multiprocessing start +method context in several cases where the test logic mixed this up. + +.. + +.. bpo: 40280 +.. date: 2022-04-06-10-16-27 +.. nonce: KT5Apg +.. section: Tests + +Threading tests are now skipped on WASM targets without pthread support. + +.. + +.. bpo: 47109 +.. date: 2022-03-24-13-35-01 +.. nonce: FjKQCE +.. section: Tests + +Test for :mod:`ctypes.macholib.dyld`, :mod:`ctypes.macholib.dylib`, and +:mod:`ctypes.macholib.framework` are brought from manual pre-:mod:`unittest` +times to :mod:`ctypes.test` location and structure. Patch by Oleg Iarygin. + +.. + +.. bpo: 29890 +.. date: 2022-01-24-21-31-09 +.. nonce: zEG-ra +.. section: Tests + +Add tests for :class:`ipaddress.IPv4Interface` and +:class:`ipaddress.IPv6Interface` construction with tuple arguments. Original +patch and tests by louisom. + +.. + +.. date: 2022-05-03-03-36-47 +.. gh-issue: 89452 +.. nonce: NIY0fF +.. section: Build + +gdbm-compat is now preferred over ndbm if both are available on the system. +This allows avoiding the problematic ndbm.h on macOS. + +.. + +.. date: 2022-04-20-11-14-51 +.. gh-issue: 91731 +.. nonce: zRoPcJ +.. section: Build + +Python is now built with ``-std=c11`` compiler option, rather than +``-std=c99``. Patch by Victor Stinner. + +.. + +.. bpo: 47152 +.. date: 2022-04-10-16-33-31 +.. nonce: TLkxKm +.. section: Build + +Add script and make target for generating ``sre_constants.h``. + +.. + +.. bpo: 47103 +.. date: 2022-03-23-20-01-16 +.. nonce: b4-00F +.. section: Build + +Windows ``PGInstrument`` builds now copy a required DLL into the output +directory, making it easier to run the profile stage of a PGO build. + +.. + +.. bpo: 46907 +.. date: 2022-04-27-19-36-56 +.. nonce: lfurlP +.. section: Windows + +Update Windows installer to use SQLite 3.38.3. + +.. + +.. bpo: 47239 +.. date: 2022-04-06-15-16-37 +.. nonce: B1HP7i +.. section: Windows + +Fixed --list and --list-paths output for :ref:`launcher` when used in an +active virtual environment. + +.. + +.. bpo: 46907 +.. date: 2022-03-28-07-01-31 +.. nonce: Ou3G6Z +.. section: Windows + +Update Windows installer to use SQLite 3.38.2. + +.. + +.. bpo: 46785 +.. date: 2022-03-13-20-35-41 +.. nonce: Pnknyl +.. section: Windows + +Fix race condition between :func:`os.stat` and unlinking a file on Windows, +by using errors codes returned by ``FindFirstFileW()`` when appropriate in +``win32_xstat_impl``. + +.. + +.. bpo: 40859 +.. date: 2020-06-04-10-42-04 +.. nonce: isKSw7 +.. section: Windows + +Update Windows build to use xz-5.2.5 + +.. + +.. bpo: 46907 +.. date: 2022-05-05-06-21-39 +.. nonce: dkgFPk +.. section: macOS + +Update macOS installer to SQLite 3.38.4. + +.. + +.. date: 2022-04-20-14-26-14 +.. gh-issue: 91583 +.. nonce: 200qI0 +.. section: Tools/Demos + +Fix regression in the code generated by Argument Clinic for functions with +the ``defining_class`` parameter. + +.. + +.. date: 2022-04-18-12-52-16 +.. gh-issue: 91575 +.. nonce: fK1TEh +.. section: Tools/Demos + +Add script ``Tools/scripts/generate_re_casefix.py`` and the make target +``regen-re`` for generating additional data for case-insensitive matching +according to the current Unicode version. + +.. + +.. date: 2022-04-14-18-11-46 +.. gh-issue: 91551 +.. nonce: l_nNT- +.. section: Tools/Demos + +Remove the ancient Pynche color editor. It has moved to +https://gitlab.com/warsaw/pynche + +.. + +.. date: 2022-05-06-04-55-17 +.. gh-issue: 88279 +.. nonce: 3mQ54t +.. section: C API + +Deprecate the C functions: :c:func:`PySys_SetArgv`, +:c:func:`PySys_SetArgvEx`, :c:func:`PySys_SetPath`. Patch by Victor Stinner. + +.. + +.. date: 2022-05-03-20-08-35 +.. gh-issue: 92154 +.. nonce: IqMcAJ +.. section: C API + +Added the :c:func:`PyCode_GetCode` function. This function does the +equivalent of the Python code ``getattr(code_object, 'co_code')``. + +.. + +.. date: 2022-05-02-12-39-33 +.. gh-issue: 92173 +.. nonce: len2Is +.. section: C API + +Fix the ``closure`` argument to :c:func:`PyEval_EvalCodeEx`. + +.. + +.. date: 2022-04-26-16-51-31 +.. gh-issue: 91320 +.. nonce: QDHmTv +.. section: C API + +Fix C++ compiler warnings about "old-style cast" (``g++ -Wold-style-cast``) +in the Python C API. Use C++ ``reinterpret_cast<>`` and ``static_cast<>`` +casts when the Python C API is used in C++. Patch by Victor Stinner. + +.. + +.. date: 2022-04-21-23-11-35 +.. gh-issue: 80527 +.. nonce: Cx-95G +.. section: C API + +Mark functions as deprecated by :pep:`623`: :c:func:`!PyUnicode_AS_DATA`, +:c:func:`!PyUnicode_AS_UNICODE`, :c:func:`!PyUnicode_GET_DATA_SIZE`, +:c:func:`!PyUnicode_GET_SIZE`. Patch by Victor Stinner. + +.. + +.. date: 2022-04-21-01-48-22 +.. gh-issue: 91768 +.. nonce: x_aKzv +.. section: C API + +:c:func:`Py_REFCNT`, :c:func:`Py_TYPE`, :c:func:`Py_SIZE` and +:c:func:`Py_IS_TYPE` functions argument type is now ``PyObject*``, rather +than ``const PyObject*``. Patch by Victor Stinner. + +.. + +.. date: 2022-04-19-17-05-39 +.. gh-issue: 91020 +.. nonce: BVJ8F3 +.. section: C API + +Add ``PyBytes_Type.tp_alloc`` to initialize ``PyBytesObject.ob_shash`` for +bytes subclasses. + +.. + +.. bpo: 40421 +.. date: 2022-04-08-11-29-36 +.. nonce: H0ORmT +.. section: C API + +Add ``PyFrame_GetLasti`` C-API function to access frame object's ``f_lasti`` +attribute safely from C code. + +.. + +.. bpo: 35134 +.. date: 2022-04-07-00-53-51 +.. nonce: zSjIzk +.. section: C API + +Remove the ``Include/code.h`` header file. C extensions should only include +the main ``<Python.h>`` header file. Patch by Victor Stinner. + +.. + +.. bpo: 47169 +.. date: 2022-04-06-16-54-39 +.. nonce: EGzX4B +.. section: C API + +:c:func:`PyOS_CheckStack` is now exported in the Stable ABI on Windows. + +.. + +.. bpo: 47169 +.. date: 2022-04-06-16-29-14 +.. nonce: wVv2bT +.. section: C API + +:c:func:`PyThread_get_thread_native_id` is excluded from the stable ABI on +platforms where it doesn't exist (like Solaris). + +.. + +.. bpo: 46343 +.. date: 2022-01-11-12-52-37 +.. nonce: JQJWhZ +.. section: C API + +Added :c:func:`PyErr_GetHandledException` and +:c:func:`PyErr_SetHandledException` as simpler alternatives to +:c:func:`PyErr_GetExcInfo` and :c:func:`PyErr_SetExcInfo`. + +They are included in the stable ABI. diff --git a/Misc/NEWS.d/3.12.0.rst b/Misc/NEWS.d/3.12.0.rst new file mode 100644 index 00000000..70af5905 --- /dev/null +++ b/Misc/NEWS.d/3.12.0.rst @@ -0,0 +1,74 @@ +.. date: 2023-09-25-14-28-14 +.. gh-issue: 109823 +.. nonce: kbVTKF +.. release date: 2023-10-02 +.. section: Core and Builtins + +Fix bug where compiler does not adjust labels when removing an empty basic +block which is a jump target. + +.. + +.. date: 2023-09-22-13-38-17 +.. gh-issue: 109719 +.. nonce: fx5OTz +.. section: Core and Builtins + +Fix missing jump target labels when compiler reorders cold/warm blocks. + +.. + +.. date: 2023-09-20-23-04-15 +.. gh-issue: 109627 +.. nonce: xxe7De +.. section: Core and Builtins + +Fix bug where the compiler does not assign a new jump target label to a +duplicated small exit block. + +.. + +.. date: 2023-09-28-18-08-02 +.. gh-issue: 110045 +.. nonce: 0YIGKv +.. section: Library + +Update the :mod:`symtable` module to support the new scopes introduced by +:pep:`695`. + +.. + +.. date: 2023-09-10-02-39-06 +.. gh-issue: 109209 +.. nonce: 0LBewo +.. section: Documentation + +The minimum Sphinx version required for the documentation is now 4.2. + +.. + +.. date: 2023-09-28-17-09-23 +.. gh-issue: 109991 +.. nonce: CIMftz +.. section: Windows + +Update Windows build to use OpenSSL 3.0.11. + +.. + +.. date: 2023-09-27-22-35-22 +.. gh-issue: 109991 +.. nonce: -xJzaF +.. section: macOS + +Update macOS installer to use OpenSSL 3.0.11. + +.. + +.. date: 2023-09-27-23-31-54 +.. gh-issue: 109991 +.. nonce: sUUYY8 +.. section: Tools/Demos + +Update GitHub CI workflows to use OpenSSL 3.0.11 and multissltests to use +1.1.1w, 3.0.11, and 3.1.3. diff --git a/Misc/NEWS.d/3.12.0a1.rst b/Misc/NEWS.d/3.12.0a1.rst new file mode 100644 index 00000000..15630b59 --- /dev/null +++ b/Misc/NEWS.d/3.12.0a1.rst @@ -0,0 +1,6193 @@ +.. date: 2022-09-28-17-09-37 +.. gh-issue: 97616 +.. nonce: K1e3Xs +.. release date: 2022-10-25 +.. section: Security + +Fix multiplying a list by an integer (``list *= int``): detect the integer +overflow when the new allocated length is close to the maximum size. Issue +reported by Jordan Limor. Patch by Victor Stinner. + +.. + +.. date: 2022-09-07-10-42-00 +.. gh-issue: 97514 +.. nonce: Yggdsl +.. section: Security + +On Linux the :mod:`multiprocessing` module returns to using filesystem +backed unix domain sockets for communication with the *forkserver* process +instead of the Linux abstract socket namespace. Only code that chooses to +use the :ref:`"forkserver" start method <multiprocessing-start-methods>` is +affected. + +Abstract sockets have no permissions and could allow any user on the system +in the same `network namespace +<https://man7.org/linux/man-pages/man7/network_namespaces.7.html>`_ (often +the whole system) to inject code into the multiprocessing *forkserver* +process. This was a potential privilege escalation. Filesystem based socket +permissions restrict this to the *forkserver* process user as was the +default in Python 3.8 and earlier. + +This prevents Linux `CVE-2022-42919 +<https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-42919>`_. + +.. + +.. date: 2022-06-15-20-09-23 +.. gh-issue: 87389 +.. nonce: QVaC3f +.. section: Security + +:mod:`http.server`: Fix an open redirection vulnerability in the HTTP server +when an URI path starts with ``//``. Vulnerability discovered, and initial +fix proposed, by Hamza Avvan. + +.. + +.. date: 2022-06-03-12-52-53 +.. gh-issue: 79096 +.. nonce: YVoxgC +.. section: Security + +LWPCookieJar and MozillaCookieJar create files with file mode 600 instead of +644 (Microsoft Windows is not affected) + +.. + +.. date: 2022-05-19-08-53-07 +.. gh-issue: 92888 +.. nonce: TLtR9W +.. section: Security + +Fix ``memoryview`` use after free when accessing the backing buffer in +certain cases. + +.. + +.. date: 2022-04-27-18-25-30 +.. gh-issue: 68966 +.. nonce: gjS8zs +.. section: Security + +The deprecated mailcap module now refuses to inject unsafe text (filenames, +MIME types, parameters) into shell commands. Instead of using such text, it +will warn and act as if a match was not found (or for test commands, as if +the test failed). + +.. + +.. date: 2022-10-19-23-48-46 +.. gh-issue: 98374 +.. nonce: eOBh8M +.. section: Core and Builtins + +Suppress ImportError for invalid query for help() command. Patch by Donghee +Na. + +.. + +.. date: 2022-10-19-20-53-38 +.. gh-issue: 98461 +.. nonce: iNmPDV +.. section: Core and Builtins + +Fix source location in bytecode for list, set and dict comprehensions as +well as generator expressions. + +.. + +.. date: 2022-10-19-18-03-28 +.. gh-issue: 98354 +.. nonce: GRGta3 +.. section: Core and Builtins + +Added unicode check for ``name`` attribute of ``spec`` argument passed in +:func:`_imp.create_builtin` function. + +.. + +.. date: 2022-10-18-16-17-44 +.. gh-issue: 98398 +.. nonce: x4rYK_ +.. section: Core and Builtins + +Fix source location of 'assert' bytecodes. + +.. + +.. date: 2022-10-18-14-11-32 +.. gh-issue: 98390 +.. nonce: H1sxJu +.. section: Core and Builtins + +Fix location of sub-expressions of boolean expressions, by reducing their +scope to that of the sub-expression. + +.. + +.. date: 2022-10-13-23-23-01 +.. gh-issue: 98254 +.. nonce: bC8IKt +.. section: Core and Builtins + +Modules from the standard library are now potentially suggested as part of +the error messages displayed by the interpreter when an :exc:`NameError` is +raised to the top level. Patch by Pablo Galindo + +.. + +.. date: 2022-10-06-23-13-34 +.. gh-issue: 97997 +.. nonce: JQaJKF +.. section: Core and Builtins + +Add running column offset to the tokenizer state to avoid calculating AST +column information with pointer arithmetic. + +.. + +.. date: 2022-10-06-20-41-29 +.. gh-issue: 97973 +.. nonce: gB-xWi +.. section: Core and Builtins + +Modify the tokenizer to return all necessary information the parser needs to +set location information in the AST nodes, so that the parser does not have +to calculate those doing pointer arithmetic. + +.. + +.. date: 2022-10-06-15-45-57 +.. gh-issue: 96078 +.. nonce: fS-6mU +.. section: Core and Builtins + +:func:`os.sched_yield` now release the GIL while calling sched_yield(2). +Patch by Donghee Na. + +.. + +.. date: 2022-10-06-14-14-28 +.. gh-issue: 97955 +.. nonce: Nq5VXD +.. section: Core and Builtins + +Migrate :mod:`zoneinfo` to Argument Clinic. + +.. + +.. date: 2022-10-06-06-36-29 +.. gh-issue: 97912 +.. nonce: jGRJpa +.. section: Core and Builtins + +The compiler now avoids quadratic behavior when finding which instructions +should use the :opcode:`LOAD_FAST_CHECK` opcode. + +.. + +.. date: 2022-10-06-02-11-34 +.. gh-issue: 97002 +.. nonce: Zvsk71 +.. section: Core and Builtins + +Fix an issue where several frame objects could be backed by the same +interpreter frame, possibly leading to corrupted memory and hard crashes of +the interpreter. + +.. + +.. date: 2022-10-05-17-02-22 +.. gh-issue: 97943 +.. nonce: LYAWlE +.. section: Core and Builtins + +Bugfix: :c:func:`PyFunction_GetAnnotations` should return a borrowed +reference. It was returning a new reference. + +.. + +.. date: 2022-10-05-11-37-15 +.. gh-issue: 97922 +.. nonce: Zu9Bge +.. section: Core and Builtins + +The Garbage Collector now runs only on the eval breaker mechanism of the +Python bytecode evaluation loop instead on object allocations. The GC can +also run when :c:func:`PyErr_CheckSignals` is called so C extensions that +need to run for a long time without executing any Python code also have a +chance to execute the GC periodically. + +.. + +.. date: 2022-10-05-00-37-27 +.. gh-issue: 65961 +.. nonce: z0Ys0y +.. section: Core and Builtins + +When ``__package__`` is different than ``__spec__.parent``, raise a +``DeprecationWarning`` instead of ``ImportWarning``. + +Also remove ``importlib.util.set_package()`` which was scheduled for +removal. + +.. + +.. date: 2022-10-04-17-02-18 +.. gh-issue: 97850 +.. nonce: E3QTRA +.. section: Core and Builtins + +Long deprecated, ``module_repr()`` should now be completely eradicated. + +.. + +.. date: 2022-10-04-14-04-40 +.. gh-issue: 86298 +.. nonce: QVM7G1 +.. section: Core and Builtins + +In cases where ``warnings.warn_explicit()`` consults the module's loader, an +``DeprecationWarning`` is issued when ``m.__loader__`` differs from +``m.__spec__.loader``. + +.. + +.. date: 2022-10-04-02-00-10 +.. gh-issue: 97779 +.. nonce: f3N1hI +.. section: Core and Builtins + +Ensure that all Python frame objects are backed by "complete" frames. + +.. + +.. date: 2022-10-03-16-12-39 +.. gh-issue: 91052 +.. nonce: MsYL9d +.. section: Core and Builtins + +Add API for subscribing to modification events on selected dictionaries. + +.. + +.. date: 2022-10-03-13-35-48 +.. gh-issue: 97752 +.. nonce: 0xTjJY +.. section: Core and Builtins + +Fix possible data corruption or crashes when accessing the ``f_back`` member +of newly-created generator or coroutine frames. + +.. + +.. date: 2022-10-01-08-55-09 +.. gh-issue: 97591 +.. nonce: pw6kkH +.. section: Core and Builtins + +Fixed a missing incref/decref pair in ``Exception.__setstate__()``. Patch by +Ofey Chan. + +.. + +.. date: 2022-09-30-13-26-58 +.. gh-issue: 97670 +.. nonce: n61vMR +.. section: Core and Builtins + +Remove the :func:`sys.getdxp` function and the +``Tools/scripts/analyze_dxp.py`` script. DXP stands for "dynamic execution +pairs". They were related to ``DYNAMIC_EXECUTION_PROFILE`` and ``DXPAIRS`` +macros which have been removed in Python 3.11. Python can now be built with +:option:`./configure --enable-pystats <--enable-pystats>` to gather +statistics on Python opcodes. Patch by Victor Stinner. + +.. + +.. date: 2022-09-29-15-19-29 +.. gh-issue: 94526 +.. nonce: wq5m6T +.. section: Core and Builtins + +Fix the Python path configuration used to initialized :data:`sys.path` at +Python startup. Paths are no longer encoded to UTF-8/strict to avoid +encoding errors if it contains surrogate characters (bytes paths are decoded +with the surrogateescape error handler). Patch by Victor Stinner. + +.. + +.. date: 2022-09-27-11-59-13 +.. gh-issue: 96670 +.. nonce: XrBBit +.. section: Core and Builtins + +The parser now raises :exc:`SyntaxError` when parsing source code containing +null bytes. Patch by Pablo Galindo + +.. + +.. date: 2022-09-21-16-06-37 +.. gh-issue: 96975 +.. nonce: BmE0XY +.. section: Core and Builtins + +Fix a crash occurring when :c:func:`PyEval_GetFrame` is called while the +topmost Python frame is in a partially-initialized state. + +.. + +.. date: 2022-09-21-14-38-31 +.. gh-issue: 96848 +.. nonce: WuoLzU +.. section: Core and Builtins + +Fix command line parsing: reject :option:`-X int_max_str_digits <-X>` option +with no value (invalid) when the :envvar:`PYTHONINTMAXSTRDIGITS` environment +variable is set to a valid limit. Patch by Victor Stinner. + +.. + +.. date: 2022-09-20-11-06-45 +.. gh-issue: 95921 +.. nonce: dkcRQn +.. section: Core and Builtins + +Fix overly-broad source position information for chained comparisons used as +branching conditions. + +.. + +.. date: 2022-09-19-03-35-01 +.. gh-issue: 96821 +.. nonce: izK6JA +.. section: Core and Builtins + +Fix undefined behaviour in ``audioop.c``. + +.. + +.. date: 2022-09-18-08-47-40 +.. gh-issue: 96821 +.. nonce: Co2iOq +.. section: Core and Builtins + +Fix undefined behaviour in ``_testcapimodule.c``. + +.. + +.. date: 2022-09-16-19-02-40 +.. gh-issue: 95778 +.. nonce: cJmnst +.. section: Core and Builtins + +When :exc:`ValueError` is raised if an integer is larger than the limit, +mention the :func:`sys.set_int_max_str_digits` function in the error +message. Patch by Victor Stinner. + +.. + +.. date: 2022-09-16-16-54-35 +.. gh-issue: 96387 +.. nonce: GRzewg +.. section: Core and Builtins + +At Python exit, sometimes a thread holding the GIL can wait forever for a +thread (usually a daemon thread) which requested to drop the GIL, whereas +the thread already exited. To fix the race condition, the thread which +requested the GIL drop now resets its request before exiting. Issue +discovered and analyzed by Mingliang ZHAO. Patch by Victor Stinner. + +.. + +.. date: 2022-09-16-12-36-13 +.. gh-issue: 96864 +.. nonce: PLU3i8 +.. section: Core and Builtins + +Fix a possible assertion failure, fatal error, or :exc:`SystemError` if a +line tracing event raises an exception while opcode tracing is enabled. + +.. + +.. date: 2022-09-13-21-45-07 +.. gh-issue: 95778 +.. nonce: Oll4_5 +.. section: Core and Builtins + +The ``PyLong_FromString`` function was refactored to make it more +maintainable and extensible. + +.. + +.. date: 2022-09-13-12-06-46 +.. gh-issue: 96678 +.. nonce: NqGFyb +.. section: Core and Builtins + +Fix undefined behaviour in C code of null pointer arithmetic. + +.. + +.. date: 2022-09-12-16-58-22 +.. gh-issue: 96754 +.. nonce: 0GRme5 +.. section: Core and Builtins + +Make sure that all frame objects created are created from valid interpreter +frames. Prevents the possibility of invalid frames in backtraces and signal +handlers. + +.. + +.. date: 2022-09-12-15-15-04 +.. gh-issue: 90997 +.. nonce: sZO8c9 +.. section: Core and Builtins + +Improve the performance of reading and writing inline bytecode caches on +some platforms. + +.. + +.. date: 2022-09-11-12-43-43 +.. gh-issue: 96751 +.. nonce: anRT6a +.. section: Core and Builtins + +Remove dead code from ``CALL_FUNCTION_EX`` opcode. + +.. + +.. date: 2022-09-11-00-37-50 +.. gh-issue: 90751 +.. nonce: VE8-zf +.. section: Core and Builtins + +:class:`memoryview` now supports half-floats. Patch by Donghee Na and +Antoine Pitrou. + +.. + +.. date: 2022-09-09-13-13-27 +.. gh-issue: 96678 +.. nonce: vMxi9F +.. section: Core and Builtins + +Fix case of undefined behavior in ceval.c + +.. + +.. date: 2022-09-08-20-58-10 +.. gh-issue: 64373 +.. nonce: AfCi36 +.. section: Core and Builtins + +Convert :mod:`_functools` to argument clinic. + +.. + +.. date: 2022-09-07-13-38-37 +.. gh-issue: 96641 +.. nonce: wky0Fc +.. section: Core and Builtins + +Do not expose ``KeyWrapper`` in :mod:`_functools`. + +.. + +.. date: 2022-09-07-12-02-11 +.. gh-issue: 96636 +.. nonce: YvN-K6 +.. section: Core and Builtins + +Ensure that tracing, ``sys.setrace()``, is turned on immediately. In +pre-release versions of 3.11, some tracing events might have been lost when +turning on tracing in a ``__del__`` method or interrupt. + +.. + +.. date: 2022-09-06-16-54-49 +.. gh-issue: 96572 +.. nonce: 8DRsaW +.. section: Core and Builtins + +Fix use after free in trace refs build mode. Patch by Kumar Aditya. + +.. + +.. date: 2022-09-06-16-22-13 +.. gh-issue: 96611 +.. nonce: 14wIX8 +.. section: Core and Builtins + +When loading a file with invalid UTF-8 inside a multi-line string, a correct +SyntaxError is emitted. + +.. + +.. date: 2022-09-06-14-26-36 +.. gh-issue: 96612 +.. nonce: P4ZbeY +.. section: Core and Builtins + +Make sure that incomplete frames do not show up in tracemalloc traces. + +.. + +.. date: 2022-09-06-11-19-03 +.. gh-issue: 90230 +.. nonce: YOtzs5 +.. section: Core and Builtins + +Fix compiler warnings and test failures when building with +``--enable-pystats``. + +.. + +.. date: 2022-09-05-19-20-44 +.. gh-issue: 96587 +.. nonce: bVxhX2 +.. section: Core and Builtins + +Correctly raise ``SyntaxError`` on exception groups (:pep:`654`) on python +versions prior to 3.11 + +.. + +.. date: 2022-09-05-16-43-44 +.. gh-issue: 96569 +.. nonce: 9lmTCC +.. section: Core and Builtins + +Remove two cases of undefined behavoir, by adding NULL checks. + +.. + +.. date: 2022-09-05-15-07-25 +.. gh-issue: 96582 +.. nonce: HEsL5s +.. section: Core and Builtins + +Fix possible ``NULL`` pointer dereference in ``_PyThread_CurrentFrames``. +Patch by Kumar Aditya. + +.. + +.. date: 2022-09-05-09-56-32 +.. gh-issue: 91079 +.. nonce: H4-DdU +.. section: Core and Builtins + +Separate Python recursion checking from C recursion checking which reduces +the chance of C stack overflow and allows the recursion limit to be +increased safely. + +.. + +.. date: 2022-09-02-16-47-52 +.. gh-issue: 93911 +.. nonce: vF-GWe +.. section: Core and Builtins + +Fix an issue that could prevent :opcode:`LOAD_ATTR` from specializing +properly when accessing properties. + +.. + +.. date: 2022-08-31-18-46-13 +.. gh-issue: 96348 +.. nonce: xzCoTP +.. section: Core and Builtins + +Emit a DeprecationWarning when :meth:`~generator.throw`, +:meth:`~coroutine.throw` or :meth:`~agen.athrow` are called with more than +one argument. + +.. + +.. date: 2022-08-29-13-06-58 +.. gh-issue: 95196 +.. nonce: eGRR4b +.. section: Core and Builtins + +Disable incorrect pickling of the C implemented classmethod descriptors. + +.. + +.. date: 2022-08-29-00-37-21 +.. gh-issue: 96364 +.. nonce: c-IVyb +.. section: Core and Builtins + +Fix text signatures of ``list.__getitem__`` and ``dict.__getitem__``. + +.. + +.. date: 2022-08-28-10-51-19 +.. gh-issue: 96352 +.. nonce: jTLD2d +.. section: Core and Builtins + +Fix :exc:`AttributeError` missing ``name`` and ``obj`` attributes in +:meth:`object.__getattribute__`. Patch by Philip Georgi. + +.. + +.. date: 2022-08-26-18-46-32 +.. gh-issue: 93554 +.. nonce: QEaCcK +.. section: Core and Builtins + +Change the jump opcodes so that all conditional jumps are forward jumps. +Backward jumps are converted by the assembler into a conditional forward +jump whose target is the fallthrough block (and with a reversed condition), +followed by an unconditional backward jump. For example: + +``POP_JUMP_IF_TRUE BACKWARD_TARGET`` becomes ``POP_JUMP_IF_FALSE NEXT_BLOCK; +JUMP BACKWARD_TARGET``. + +All the directed conditional jump opcodes were removed: +``POP_JUMP_FORWARD_IF_TRUE``, ``POP_JUMP_BACKWARD_IF_TRUE``, +``POP_JUMP_FORWARD_IF_FALSE``, ``POP_JUMP_BACKWARD_IF_FALSE``, +``POP_JUMP_FORWARD_IF_NONE``, ``POP_JUMP_BACKWARD_IF_NONE``, +``POP_JUMP_FORWARD_IF_NOT_NONE``, ``POP_JUMP_BACKWARD_IF_NOT_NONE``. + +The corresponding opcodes without direction are no longer +pseudo-instructions, and they implement the forward conditional jumps. + +.. + +.. date: 2022-08-25-10-19-34 +.. gh-issue: 96268 +.. nonce: AbYrLB +.. section: Core and Builtins + +Loading a file with invalid UTF-8 will now report the broken character at +the correct location. + +.. + +.. date: 2022-08-24-14-30-26 +.. gh-issue: 96237 +.. nonce: msif5f +.. section: Core and Builtins + +The internal field ``_PyInterpreterFrame.f_func`` is renamed to +``_PyInterpreterFrame.f_funcobj`` and may be any object. The ``f_globals`` +and ``f_builtin`` fields may hold junk values. + +It is safest to treat the ``_PyInterpreterFrame`` struct as opaque. + +.. + +.. date: 2022-08-22-21-33-28 +.. gh-issue: 96187 +.. nonce: W_6SRG +.. section: Core and Builtins + +Fixed a bug that caused ``_PyCode_GetExtra`` to return garbage for negative +indexes. Patch by Pablo Galindo + +.. + +.. date: 2022-08-20-18-36-40 +.. gh-issue: 96143 +.. nonce: nh3GFM +.. section: Core and Builtins + +Add a new ``-X perf`` Python command line option as well as +:func:`sys.activate_stack_trampoline` and +:func:`sys.deactivate_stack_trampoline` function in the :mod:`sys` module +that allows to set/unset the interpreter in a way that the Linux ``perf`` +profiler can detect Python calls. The new +:func:`sys.is_stack_trampoline_active` function allows to query the state of +the perf trampoline. Design by Pablo Galindo. Patch by Pablo Galindo and +Christian Heimes with contributions from Gregory P. Smith [Google] and Mark +Shannon. + +.. + +.. date: 2022-08-19-06-51-17 +.. gh-issue: 96071 +.. nonce: mVgPAo +.. section: Core and Builtins + +Fix a deadlock in :c:func:`PyGILState_Ensure` when allocating new thread +state. Patch by Kumar Aditya. + +.. + +.. date: 2022-08-18-13-47-59 +.. gh-issue: 96046 +.. nonce: 5Hqbka +.. section: Core and Builtins + +:c:func:`PyType_Ready` now initializes ``ht_cached_keys`` and performs +additional checks to ensure that type objects are properly configured. This +avoids crashes in 3rd party packages that don't use regular API to create +new types. + +.. + +.. date: 2022-08-15-21-08-11 +.. gh-issue: 96005 +.. nonce: 6eoc8k +.. section: Core and Builtins + +On WASI :const:`~errno.ENOTCAPABLE` is now mapped to :exc:`PermissionError`. +The :mod:`errno` modules exposes the new error number. ``getpath.py`` now +ignores :exc:`PermissionError` when it cannot open landmark files +``pybuilddir.txt`` and ``pyenv.cfg``. + +.. + +.. date: 2022-08-15-20-52-41 +.. gh-issue: 93678 +.. nonce: X7GuIJ +.. section: Core and Builtins + +Added test a harness for direct unit tests of the compiler's optimization +stage. The ``_testinternalcapi.optimize_cfg()`` function runs the optimiser +on a sequence of instructions. The ``CfgOptimizationTestCase`` class in +``test.support`` has utilities for invoking the optimizer and checking the +output. + +.. + +.. date: 2022-08-15-12-41-14 +.. gh-issue: 95245 +.. nonce: N4gOUV +.. section: Core and Builtins + +Reduces the size of a "simple" Python object from 8 to 6 words by moving the +weakreflist pointer into the pre-header directly before the object's +dict/values pointer. + +.. + +.. date: 2022-08-15-11-58-05 +.. gh-issue: 90997 +.. nonce: bWwV8Q +.. section: Core and Builtins + +Compile virtual :keyword:`try`/:keyword:`except` blocks to handle exceptions +raised during :meth:`~generator.close` or :meth:`~generator.throw` calls +through a suspended frame. + +.. + +.. date: 2022-08-14-10-04-44 +.. gh-issue: 95977 +.. nonce: gCTZb9 +.. section: Core and Builtins + +Optimized calling :meth:`~object.__get__` with vectorcall. Patch by Kumar +Aditya. + +.. + +.. date: 2022-08-12-18-13-49 +.. gh-issue: 91210 +.. nonce: AWMSLj +.. section: Core and Builtins + +Improve error message when a parameter without a default value follows one +with a default value, and show the same message, even when the +non-default/default sequence is preceded by positional-only parameters. + +.. + +.. date: 2022-08-12-13-04-25 +.. gh-issue: 95922 +.. nonce: YNCtyX +.. section: Core and Builtins + +Fixed bug where the compiler's ``eliminate_empty_basic_blocks`` function +ignores the last block of the code unit. + +.. + +.. date: 2022-08-11-11-01-56 +.. gh-issue: 95818 +.. nonce: iClLdl +.. section: Core and Builtins + +Skip over incomplete frames in :c:func:`PyThreadState_GetFrame`. + +.. + +.. date: 2022-08-11-09-19-55 +.. gh-issue: 95876 +.. nonce: YpQfoV +.. section: Core and Builtins + +Fix format string in ``_PyPegen_raise_error_known_location`` that can lead +to memory corruption on some 64bit systems. The function was building a +tuple with ``i`` (int) instead of ``n`` (Py_ssize_t) for Py_ssize_t +arguments. + +.. + +.. date: 2022-08-04-18-46-54 +.. gh-issue: 95605 +.. nonce: FbpCoG +.. section: Core and Builtins + +Fix misleading contents of error message when converting an all-whitespace +string to :class:`float`. + +.. + +.. date: 2022-07-31-13-23-12 +.. gh-issue: 95150 +.. nonce: 67FXVo +.. section: Core and Builtins + +Update code object hashing and equality to consider all debugging and +exception handling tables. This fixes an issue where certain non-identical +code objects could be "deduplicated" during compilation. + +.. + +.. date: 2022-07-31-03-22-58 +.. gh-issue: 91146 +.. nonce: Y2Hziy +.. section: Core and Builtins + +Reduce allocation size of :class:`list` from :meth:`str.split` and +:meth:`str.rsplit`. Patch by Donghee Na and Inada Naoki. + +.. + +.. date: 2022-07-28-19-07-06 +.. gh-issue: 87092 +.. nonce: 73IPS1 +.. section: Core and Builtins + +Create a 'jump target label' abstraction in the compiler so that the +compiler's codegen stage does not work directly with basic blocks. This +prepares the code for changes to the underlying CFG generation mechanism. + +.. + +.. date: 2022-07-28-08-33-31 +.. gh-issue: 95355 +.. nonce: yN4XVk +.. section: Core and Builtins + +``_PyPegen_Parser_New`` now properly detects token memory allocation errors. +Patch by Honglin Zhu. + +.. + +.. date: 2022-07-27-14-21-57 +.. gh-issue: 90081 +.. nonce: HVAS5x +.. section: Core and Builtins + +Run Python code in tracer/profiler function at full speed. Fixes slowdown in +earlier versions of 3.11. + +.. + +.. date: 2022-07-27-14-05-07 +.. gh-issue: 95324 +.. nonce: 28Q5u7 +.. section: Core and Builtins + +Emit a warning in debug mode if an object does not call +:c:func:`PyObject_GC_UnTrack` before deallocation. Patch by Pablo Galindo. + +.. + +.. date: 2022-07-26-12-59-03 +.. gh-issue: 95245 +.. nonce: GHWczn +.. section: Core and Builtins + +Merge managed dict and values pointer into a single tagged pointer to save +one word in the pre-header. + +.. + +.. date: 2022-07-26-09-31-12 +.. gh-issue: 93678 +.. nonce: W8vvgT +.. section: Core and Builtins + +Add cfg_builder struct and refactor the relevant code so that a cfg can be +constructed without an instance of the compiler struct. + +.. + +.. date: 2022-07-24-00-27-47 +.. gh-issue: 95185 +.. nonce: ghYTZx +.. section: Core and Builtins + +Prevented crashes in the AST constructor when compiling some absurdly long +expressions like ``"+0"*1000000``. :exc:`RecursionError` is now raised +instead. Patch by Pablo Galindo + +.. + +.. date: 2022-07-23-19-16-25 +.. gh-issue: 93351 +.. nonce: 0Jyvu- +.. section: Core and Builtins + +:class:`ast.AST` node positions are now validated when provided to +:func:`compile` and other related functions. If invalid positions are +detected, a :exc:`ValueError` will be raised. + +.. + +.. date: 2022-07-22-12-53-34 +.. gh-issue: 94438 +.. nonce: hNqACc +.. section: Core and Builtins + +Fix an issue that caused extended opcode arguments and some conditional pops +to be ignored when calculating valid jump targets for assignments to the +``f_lineno`` attribute of frame objects. In some cases, this could cause +inconsistent internal state, resulting in a hard crash of the interpreter. + +.. + +.. date: 2022-07-21-19-19-20 +.. gh-issue: 95060 +.. nonce: 4xdT1f +.. section: Core and Builtins + +Undocumented ``PyCode_Addr2Location`` function now properly returns when +``addrq`` argument is less than zero. + +.. + +.. date: 2022-07-21-17-54-52 +.. gh-issue: 95113 +.. nonce: NnSLpT +.. section: Core and Builtins + +Replace all ``EXTENDED_ARG_QUICK`` instructions with basic +:opcode:`EXTENDED_ARG` instructions in unquickened code. Consumers of +non-adaptive bytecode should be able to handle extended arguments the same +way they were handled in CPython 3.10 and older. + +.. + +.. date: 2022-07-20-13-46-01 +.. gh-issue: 91409 +.. nonce: dhL8Zo +.. section: Core and Builtins + +Fix incorrect source location info caused by certain optimizations in the +bytecode compiler. + +.. + +.. date: 2022-07-20-09-04-55 +.. gh-issue: 95023 +.. nonce: bs-xd7 +.. section: Core and Builtins + +Implement :func:`os.setns` and :func:`os.unshare` for Linux. Patch by Noam +Cohen. + +.. + +.. date: 2022-07-19-16-30-59 +.. gh-issue: 94036 +.. nonce: _6Utkm +.. section: Core and Builtins + +Fix incorrect source location info for some multi-line attribute accesses +and method calls. + +.. + +.. date: 2022-07-19-09-41-55 +.. gh-issue: 94938 +.. nonce: xYBlM7 +.. section: Core and Builtins + +Fix error detection in some builtin functions when keyword argument name is +an instance of a str subclass with overloaded ``__eq__`` and ``__hash__``. +Previously it could cause SystemError or other undesired behavior. + +.. + +.. date: 2022-07-19-04-34-56 +.. gh-issue: 94996 +.. nonce: dV564A +.. section: Core and Builtins + +:func:`ast.parse` will no longer parse function definitions with +positional-only params when passed ``feature_version`` less than ``(3, 8)``. +Patch by Shantanu Jain. + +.. + +.. date: 2022-07-18-14-19-21 +.. gh-issue: 94739 +.. nonce: NQJQi7 +.. section: Core and Builtins + +Allow jumping within, out of, and across exception handlers in the debugger. + +.. + +.. date: 2022-07-18-05-10-29 +.. gh-issue: 94949 +.. nonce: OsZ7_s +.. section: Core and Builtins + +:func:`ast.parse` will no longer parse parenthesized context managers when +passed ``feature_version`` less than ``(3, 9)``. Patch by Shantanu Jain. + +.. + +.. date: 2022-07-18-04-48-34 +.. gh-issue: 94947 +.. nonce: df9gUw +.. section: Core and Builtins + +:func:`ast.parse` will no longer parse assignment expressions when passed +``feature_version`` less than ``(3, 8)``. Patch by Shantanu Jain. + +.. + +.. date: 2022-07-17-15-54-29 +.. gh-issue: 91256 +.. nonce: z7i7Q5 +.. section: Core and Builtins + +Ensures the program name is known for help text during interpreter startup. + +.. + +.. date: 2022-07-16-08-14-17 +.. gh-issue: 94869 +.. nonce: eRwMsX +.. section: Core and Builtins + +Fix the column offsets for some expressions in multi-line f-strings +:mod:`ast` nodes. Patch by Pablo Galindo. + +.. + +.. date: 2022-07-15-22-47-44 +.. gh-issue: 94893 +.. nonce: YiJYcW +.. section: Core and Builtins + +Fix an issue where frame object manipulations could corrupt inline bytecode +caches. + +.. + +.. date: 2022-07-15-22-16-08 +.. gh-issue: 94822 +.. nonce: zRRzBN +.. section: Core and Builtins + +Fix an issue where lookups of metaclass descriptors may be ignored when an +identically-named attribute also exists on the class itself. + +.. + +.. date: 2022-07-15-16-15-04 +.. gh-issue: 91153 +.. nonce: HiBmtt +.. section: Core and Builtins + +Fix an issue where a :class:`bytearray` item assignment could crash if it's +resized by the new value's :meth:`__index__` method. + +.. + +.. date: 2022-07-14-10-07-53 +.. gh-issue: 90699 +.. nonce: x3aG9m +.. section: Core and Builtins + +Fix reference counting bug in :meth:`bool.__repr__`. Patch by Kumar Aditya. + +.. + +.. date: 2022-07-08-16-44-11 +.. gh-issue: 94694 +.. nonce: VkL2CM +.. section: Core and Builtins + +Fix an issue that could cause code with multi-line method lookups to have +misleading or incorrect column offset information. In some cases (when +compiling a hand-built AST) this could have resulted in a hard crash of the +interpreter. + +.. + +.. date: 2022-07-08-11-44-45 +.. gh-issue: 93252 +.. nonce: i2358c +.. section: Core and Builtins + +Fix an issue that caused internal frames to outlive failed Python function +calls, possibly resulting in memory leaks or hard interpreter crashes. + +.. + +.. date: 2022-07-07-21-13-25 +.. gh-issue: 94215 +.. nonce: _Sv9Ms +.. section: Core and Builtins + +Fix an issue where exceptions raised by line-tracing events would cause +frames to be left in an invalid state, possibly resulting in a hard crash of +the interpreter. + +.. + +.. date: 2022-07-06-14-02-26 +.. gh-issue: 92228 +.. nonce: 44Cbly +.. section: Core and Builtins + +Disable the compiler's inline-small-exit-blocks optimization for exit blocks +that are associated with source code lines. This fixes a bug where the +debugger cannot tell where an exception handler ends and the following code +block begins. + +.. + +.. date: 2022-07-01-20-00-19 +.. gh-issue: 94485 +.. nonce: mo5st7 +.. section: Core and Builtins + +Line number of a module's ``RESUME`` instruction is set to 0 as specified in +:pep:`626`. + +.. + +.. date: 2022-06-30-15-07-26 +.. gh-issue: 94438 +.. nonce: btzHSk +.. section: Core and Builtins + +Account for instructions that can push NULL to the stack when setting line +number in a frame. Prevents some (unlikely) crashes. + +.. + +.. date: 2022-06-29-22-18-36 +.. gh-issue: 91719 +.. nonce: 3APYYI +.. section: Core and Builtins + +Reload ``opcode`` when raising ``unknown opcode error`` in the interpreter +main loop, for C compilers to generate dispatching code independently. + +.. + +.. date: 2022-06-29-15-45-04 +.. gh-issue: 94329 +.. nonce: olUQyk +.. section: Core and Builtins + +Compile and run code with unpacking of extremely large sequences (1000s of +elements). Such code failed to compile. It now compiles and runs correctly. + +.. + +.. date: 2022-06-28-14-20-36 +.. gh-issue: 94360 +.. nonce: DiEnen +.. section: Core and Builtins + +Fixed a tokenizer crash when reading encoded files with syntax errors from +``stdin`` with non utf-8 encoded text. Patch by Pablo Galindo + +.. + +.. date: 2022-06-28-12-41-17 +.. gh-issue: 88116 +.. nonce: A7fEl_ +.. section: Core and Builtins + +Fix an issue when reading line numbers from code objects if the encoded line +numbers are close to ``INT_MIN``. Patch by Pablo Galindo + +.. + +.. date: 2022-06-28-10-08-06 +.. gh-issue: 94262 +.. nonce: m-HWUZ +.. section: Core and Builtins + +Don't create frame objects for incomplete frames. Prevents the creation of +generators and closures from being observable to Python and C extensions, +restoring the behavior of 3.10 and earlier. + +.. + +.. date: 2022-06-26-14-37-03 +.. gh-issue: 94192 +.. nonce: ab7tn7 +.. section: Core and Builtins + +Fix error for dictionary literals with invalid expression as value. + +.. + +.. date: 2022-06-25-10-19-43 +.. gh-issue: 87995 +.. nonce: aMDHnp +.. section: Core and Builtins + +:class:`types.MappingProxyType` instances are now hashable if the underlying +mapping is hashable. + +.. + +.. date: 2022-06-24-14-06-20 +.. gh-issue: 93883 +.. nonce: 8jVQQ4 +.. section: Core and Builtins + +Revise the display strategy of traceback enhanced error locations. The +indicators are only shown when the location doesn't span the whole line. + +.. + +.. date: 2022-06-23-12-10-39 +.. gh-issue: 94163 +.. nonce: SqAfQq +.. section: Core and Builtins + +Add :opcode:`BINARY_SLICE` and :opcode:`STORE_SLICE` instructions for more +efficient handling and better specialization of slicing operations, where +the slice is explicit in the source code. + +.. + +.. date: 2022-06-20-13-48-57 +.. gh-issue: 94021 +.. nonce: o78q3G +.. section: Core and Builtins + +Fix unreachable code warning in ``Python/specialize.c``. + +.. + +.. date: 2022-06-18-17-00-33 +.. gh-issue: 93911 +.. nonce: y286of +.. section: Core and Builtins + +Specialize ``LOAD_ATTR`` for objects with custom ``__getattribute__``. + +.. + +.. date: 2022-06-17-16-30-24 +.. gh-issue: 93955 +.. nonce: LmiAe9 +.. section: Core and Builtins + +Improve performance of attribute lookups on objects with custom +``__getattribute__`` and ``__getattr__``. Patch by Ken Jin. + +.. + +.. date: 2022-06-16-16-53-22 +.. gh-issue: 93911 +.. nonce: RDwIiK +.. section: Core and Builtins + +Specialize ``LOAD_ATTR`` for ``property()`` attributes. + +.. + +.. date: 2022-06-15-16-45-53 +.. gh-issue: 93678 +.. nonce: 1I_ZT3 +.. section: Core and Builtins + +Refactor compiler optimisation code so that it no longer needs the ``struct +assembler`` and ``struct compiler`` passed around. Instead, each function +takes the CFG and other data that it actually needs. This will make it +possible to test this code directly. + +.. + +.. date: 2022-06-15-11-16-13 +.. gh-issue: 93841 +.. nonce: 06zqX3 +.. section: Core and Builtins + +When built with ``-enable-pystats``, ``sys._stats_on()``, +``sys._stats_off()``, ``sys._stats_clear()`` and ``sys._stats_dump()`` +functions have been added to enable gathering stats for parts of programs. + +.. + +.. date: 2022-06-13-13-55-34 +.. gh-issue: 93516 +.. nonce: HILrDl +.. section: Core and Builtins + +Store offset of first traceable instruction in code object to avoid having +to recompute it for each instruction when tracing. + +.. + +.. date: 2022-06-13-10-48-09 +.. gh-issue: 93516 +.. nonce: yJSait +.. section: Core and Builtins + +Lazily create a table mapping bytecode offsets to line numbers to speed up +calculation of line numbers when tracing. + +.. + +.. date: 2022-06-12-19-31-56 +.. gh-issue: 89828 +.. nonce: bq02M7 +.. section: Core and Builtins + +:class:`types.GenericAlias` no longer relays the ``__class__`` attribute. +For example, ``isinstance(list[int], type)`` no longer returns ``True``. + +.. + +.. date: 2022-06-10-16-57-35 +.. gh-issue: 93678 +.. nonce: 1WBnHt +.. section: Core and Builtins + +Refactor the compiler to reduce boilerplate and repetition. + +.. + +.. date: 2022-06-10-12-03-17 +.. gh-issue: 93671 +.. nonce: idkQqG +.. section: Core and Builtins + +Fix some exponential backtrace case happening with deeply nested sequence +patterns in match statements. Patch by Pablo Galindo + +.. + +.. date: 2022-06-10-10-31-18 +.. gh-issue: 93662 +.. nonce: -7RSC1 +.. section: Core and Builtins + +Make sure that the end column offsets are correct in multi-line method +calls. Previously, the end column could precede the column offset. + +.. + +.. date: 2022-06-09-19-19-02 +.. gh-issue: 93461 +.. nonce: 5DqP1e +.. section: Core and Builtins + +:func:`importlib.invalidate_caches` now drops entries from +:data:`sys.path_importer_cache` with a relative path as name. This solves a +caching issue when a process changes its current working directory. + +``FileFinder`` no longer inserts a dot in the path, e.g. ``/egg/./spam`` is +now ``/egg/spam``. + +.. + +.. date: 2022-06-09-09-08-29 +.. gh-issue: 93621 +.. nonce: -_Pn1d +.. section: Core and Builtins + +Change order of bytecode instructions emitted for :keyword:`with` and +:keyword:`async with` to reduce the number of entries in the exception +table. + +.. + +.. date: 2022-06-06-14-28-24 +.. gh-issue: 93533 +.. nonce: lnC0CC +.. section: Core and Builtins + +Reduce the size of the inline cache for ``LOAD_METHOD`` by 2 bytes. + +.. + +.. date: 2022-06-02-23-00-08 +.. gh-issue: 93444 +.. nonce: m63DIs +.. section: Core and Builtins + +Removed redundant fields from the compiler's basicblock struct: +``b_nofallthrough``, ``b_exit``, ``b_return``. They can be easily calculated +from the opcode of the last instruction of the block. + +.. + +.. date: 2022-06-02-08-28-55 +.. gh-issue: 93429 +.. nonce: DZTWHx +.. section: Core and Builtins + +``LOAD_METHOD`` instruction has been removed. It was merged back into +``LOAD_ATTR``. + +.. + +.. date: 2022-06-01-17-47-40 +.. gh-issue: 93418 +.. nonce: 24dJuc +.. section: Core and Builtins + +Fixed an assert where an f-string has an equal sign '=' following an +expression, but there's no trailing brace. For example, f"{i=". + +.. + +.. date: 2022-05-31-16-36-30 +.. gh-issue: 93382 +.. nonce: Jf6gAj +.. section: Core and Builtins + +Cache the result of :c:func:`PyCode_GetCode` function to restore the O(1) +lookup of the :attr:`~types.CodeType.co_code` attribute. + +.. + +.. date: 2022-05-30-19-00-38 +.. gh-issue: 93359 +.. nonce: zXV3A0 +.. section: Core and Builtins + +Ensure that custom :mod:`ast` nodes without explicit end positions can be +compiled. Patch by Pablo Galindo. + +.. + +.. date: 2022-05-30-15-51-11 +.. gh-issue: 93356 +.. nonce: l5wnzW +.. section: Core and Builtins + +Code for exception handlers is emitted at the end of the code unit's +bytecode. This avoids one jump when no exception is raised. + +.. + +.. date: 2022-05-30-15-35-42 +.. gh-issue: 93354 +.. nonce: RZk8gs +.. section: Core and Builtins + +Use exponential backoff for specialization counters in the interpreter. Can +reduce the number of failed specializations significantly and avoid slowdown +for those parts of a program that are not suitable for specialization. + +.. + +.. date: 2022-05-30-14-50-03 +.. gh-issue: 93283 +.. nonce: XDO2ZQ +.. section: Core and Builtins + +Improve error message for invalid syntax of conversion character in f-string +expressions. + +.. + +.. date: 2022-05-30-10-22-46 +.. gh-issue: 93345 +.. nonce: gi1A4L +.. section: Core and Builtins + +Fix a crash in substitution of a ``TypeVar`` in nested generic alias after +``TypeVarTuple``. + +.. + +.. date: 2022-05-25-21-56-25 +.. gh-issue: 93223 +.. nonce: gTOGVZ +.. section: Core and Builtins + +When a bytecode instruction jumps to an unconditional jump instruction, the +first instruction can often be optimized to target the unconditional jump's +target directly. For tracing reasons, this would previously only occur if +both instructions have the same line number. This also now occurs if the +unconditional jump is artificial, i.e., if it has no associated line number. + +.. + +.. date: 2022-05-25-12-30-12 +.. gh-issue: 84694 +.. nonce: 5sjy2w +.. section: Core and Builtins + +The ``--experimental-isolated-subinterpreters`` configure option and +``EXPERIMENTAL_ISOLATED_SUBINTERPRETERS`` macro have been removed. + +.. + +.. date: 2022-05-25-04-07-22 +.. gh-issue: 91924 +.. nonce: -UyO4q +.. section: Core and Builtins + +Fix ``__lltrace__`` debug feature if the stdout encoding is not UTF-8. Patch +by Victor Stinner. + +.. + +.. date: 2022-05-24-14-35-48 +.. gh-issue: 93040 +.. nonce: 9X6Ofu +.. section: Core and Builtins + +Wraps unused parameters in ``Objects/obmalloc.c`` with ``Py_UNUSED``. + +.. + +.. date: 2022-05-23-18-36-07 +.. gh-issue: 93143 +.. nonce: X1Yqxm +.. section: Core and Builtins + +Avoid ``NULL`` checks for uninitialized local variables by determining at +compile time which variables must be initialized. + +.. + +.. date: 2022-05-22-02-37-50 +.. gh-issue: 93061 +.. nonce: r70Imp +.. section: Core and Builtins + +Backward jumps after ``async for`` loops are no longer given dubious line +numbers. + +.. + +.. date: 2022-05-21-23-21-37 +.. gh-issue: 93065 +.. nonce: 5I18WC +.. section: Core and Builtins + +Fix contextvars HAMT implementation to handle iteration over deep trees. + +The bug was discovered and fixed by Eli Libman. See +`MagicStack/immutables#84 +<https://github.com/MagicStack/immutables/issues/84>`_ for more details. + +.. + +.. date: 2022-05-20-13-32-24 +.. gh-issue: 93012 +.. nonce: e9B-pv +.. section: Core and Builtins + +Added the new function :c:func:`PyType_FromMetaclass`, which generalizes the +existing :c:func:`PyType_FromModuleAndSpec` using an additional metaclass +argument. This is useful for language binding tools, where it can be used to +intercept type-related operations like subclassing or static attribute +access by specifying a metaclass with custom slots. + +Importantly, :c:func:`PyType_FromMetaclass` is available in the Limited API, +which provides a path towards migrating more binding tools onto the Stable +ABI. + +.. + +.. date: 2022-05-20-09-25-34 +.. gh-issue: 93021 +.. nonce: k3Aji2 +.. section: Core and Builtins + +Fix the :attr:`__text_signature__` for :meth:`__get__` methods implemented +in C. Patch by Jelle Zijlstra. + +.. + +.. date: 2022-05-19-15-29-53 +.. gh-issue: 89914 +.. nonce: 8bAffH +.. section: Core and Builtins + +The operand of the ``YIELD_VALUE`` instruction is set to the stack depth. +This is done to help frame handling on ``yield`` and may assist debuggers. + +.. + +.. date: 2022-05-19-13-25-50 +.. gh-issue: 92955 +.. nonce: kmNV33 +.. section: Core and Builtins + +Fix memory leak in code object's lines and positions iterators as they were +not finalized at exit. Patch by Kumar Aditya. + +.. + +.. date: 2022-05-18-18-34-45 +.. gh-issue: 92930 +.. nonce: kpYPOb +.. section: Core and Builtins + +Fixed a crash in ``_pickle.c`` from mutating collections during +``__reduce__`` or ``persistent_id``. + +.. + +.. date: 2022-05-18-12-55-35 +.. gh-issue: 90690 +.. nonce: TKuoTa +.. section: Core and Builtins + +The PRECALL instruction has been removed. It offered only a small advantage +for specialization and is not needed in the vast majority of cases. + +.. + +.. date: 2022-05-18-08-32-33 +.. gh-issue: 92914 +.. nonce: tJUeTD +.. section: Core and Builtins + +Always round the allocated size for lists up to the nearest even number. + +.. + +.. date: 2022-05-17-20-41-43 +.. gh-issue: 92858 +.. nonce: eIXJTn +.. section: Core and Builtins + +Improve error message for some suites with syntax error before ':' + +.. + +.. date: 2022-05-15-15-25-05 +.. gh-issue: 90473 +.. nonce: MoPHYW +.. section: Core and Builtins + +Decrease default recursion limit on WASI to address limited call stack size. + +.. + +.. date: 2022-05-14-13-22-11 +.. gh-issue: 92804 +.. nonce: rAqpI2 +.. section: Core and Builtins + +Fix memory leak in ``memoryview`` iterator as it was not finalized at exit. +Patch by Kumar Aditya. + +.. + +.. date: 2022-05-13-12-36-10 +.. gh-issue: 92777 +.. nonce: Odo4vP +.. section: Core and Builtins + +Specialize ``LOAD_METHOD`` for objects with lazy dictionaries. Patch by Ken +Jin. + +.. + +.. date: 2022-05-13-00-57-18 +.. gh-issue: 92658 +.. nonce: YdhFE2 +.. section: Core and Builtins + +Add support for connecting and binding to Hyper-V sockets on Windows Hyper-V +hosts and guests. + +.. + +.. date: 2022-05-12-13-23-19 +.. gh-issue: 92236 +.. nonce: sDRzUe +.. section: Core and Builtins + +Remove spurious "LINE" event when starting a generator or coroutine, visible +tracing functions implemented in C. + +.. + +.. date: 2022-05-11-09-16-54 +.. gh-issue: 91102 +.. nonce: lenv9h +.. section: Core and Builtins + +:meth:`_warnings.warn_explicit` is ported to Argument Clinic. + +.. + +.. date: 2022-05-10-11-34-35 +.. gh-issue: 92619 +.. nonce: u0V0lY +.. section: Core and Builtins + +Make the compiler duplicate an exit block only if none of its instructions +have a lineno (previously only the first instruction in the block was +checked, leading to unnecessarily duplicated blocks). + +.. + +.. date: 2022-05-08-19-43-31 +.. gh-issue: 88750 +.. nonce: 1BjJg- +.. section: Core and Builtins + +The deprecated debug build only ``PYTHONTHREADDEBUG`` environment variable +no longer does anything. + +.. + +.. date: 2022-05-03-20-12-18 +.. gh-issue: 92261 +.. nonce: aigLnb +.. section: Core and Builtins + +Fix hang when trying to iterate over a ``typing.Union``. + +.. + +.. date: 2022-04-24-02-22-10 +.. gh-issue: 91432 +.. nonce: YPJAK6 +.. section: Core and Builtins + +Specialized the :opcode:`FOR_ITER` opcode using the PEP 659 machinery + +.. + +.. date: 2022-04-16-15-37-55 +.. gh-issue: 91399 +.. nonce: trLbK6 +.. section: Core and Builtins + +Removed duplicate '{0, 0, 0, 0, 0, 0}' entry in 'Objects/unicodetype_db.h'. + +.. + +.. date: 2022-04-15-22-12-53 +.. gh-issue: 91578 +.. nonce: rDOtyK +.. section: Core and Builtins + +Updates the error message for abstract class. + +.. + +.. bpo: 47091 +.. date: 2022-03-22-13-12-27 +.. nonce: tJcy-P +.. section: Core and Builtins + +Improve performance of repetition of :class:`list` and :class:`tuple` by +using ``memcpy`` to copy data and performing the reference increments in one +step. + +.. + +.. bpo: 46142 +.. date: 2022-01-02-14-53-59 +.. nonce: WayjgT +.. section: Core and Builtins + +Make ``--help`` output shorter by moving some info to the new ``--help-env`` +and ``--help-xoptions`` command-line options. Also add ``--help-all`` option +to print complete usage. + +.. + +.. bpo: 42316 +.. date: 2020-11-15-02-08-43 +.. nonce: LqdkWK +.. section: Core and Builtins + +Document some places where an assignment expression needs parentheses. + +.. + +.. date: 2022-10-23-18-30-39 +.. gh-issue: 89237 +.. nonce: kBui30 +.. section: Library + +Fix hang on Windows in ``subprocess.wait_closed()`` in :mod:`asyncio` with +:class:`~asyncio.ProactorEventLoop`. Patch by Kumar Aditya. + +.. + +.. date: 2022-10-19-09-29-12 +.. gh-issue: 97928 +.. nonce: xj3im7 +.. section: Library + +:meth:`tkinter.Text.count` raises now an exception for options starting with +"-" instead of silently ignoring them. + +.. + +.. date: 2022-10-18-15-41-37 +.. gh-issue: 98393 +.. nonce: vhPu4L +.. section: Library + +The :mod:`os` module no longer accepts bytes-like paths, like +:class:`bytearray` and :class:`memoryview` types: only the exact +:class:`bytes` type is accepted for bytes strings. Patch by Victor Stinner. + +.. + +.. date: 2022-10-17-12-49-02 +.. gh-issue: 98363 +.. nonce: aFmSP- +.. section: Library + +Added itertools.batched() to batch data into lists of a given length with +the last list possibly being shorter than the others. + +.. + +.. date: 2022-10-16-15-31-50 +.. gh-issue: 98331 +.. nonce: Y5kPOX +.. section: Library + +Update the bundled copies of pip and setuptools to versions 22.3 and 65.5.0 +respectively. + +.. + +.. date: 2022-10-16-06-18-59 +.. gh-issue: 98307 +.. nonce: b2_CDu +.. section: Library + +A :meth:`~logging.handlers.SysLogHandler.createSocket` method was added to +:class:`~logging.handlers.SysLogHandler`. + +.. + +.. date: 2022-10-14-19-57-37 +.. gh-issue: 96035 +.. nonce: 0xcX-p +.. section: Library + +Fix bug in :func:`urllib.parse.urlparse` that causes certain port numbers +containing whitespace, underscores, plus and minus signs, or non-ASCII +digits to be incorrectly accepted. + +.. + +.. date: 2022-10-14-12-29-05 +.. gh-issue: 98257 +.. nonce: aMSMs2 +.. section: Library + +Make :func:`sys.setprofile` and :func:`sys.settrace` functions reentrant. +They can no long fail with: ``RuntimeError("Cannot install a trace function +while another trace function is being installed")``. Patch by Victor +Stinner. + +.. + +.. date: 2022-10-14-11-46-31 +.. gh-issue: 98251 +.. nonce: Uxc9al +.. section: Library + +Allow :mod:`venv` to pass along :envvar:`PYTHON*` variables to ``ensurepip`` +and ``pip`` when they do not impact path resolution + +.. + +.. date: 2022-10-12-11-20-54 +.. gh-issue: 94597 +.. nonce: GYJZlb +.. section: Library + +Deprecated :meth:`asyncio.AbstractEventLoopPolicy.get_child_watcher` and +:meth:`asyncio.AbstractEventLoopPolicy.set_child_watcher` methods to be +removed in Python 3.14. Patch by Kumar Aditya. + +.. + +.. date: 2022-10-12-10-00-40 +.. gh-issue: 98178 +.. nonce: hspH51 +.. section: Library + +On macOS, fix a crash in :func:`syslog.syslog` in multi-threaded +applications. On macOS, the libc ``syslog()`` function is not thread-safe, +so :func:`syslog.syslog` no longer releases the GIL to call it. Patch by +Victor Stinner. + +.. + +.. date: 2022-10-10-09-52-21 +.. gh-issue: 44098 +.. nonce: okcqJt +.. section: Library + +Release the GIL when creating :class:`mmap.mmap` objects on Unix. + +.. + +.. date: 2022-10-09-12-12-38 +.. gh-issue: 87730 +.. nonce: ClgP3f +.. section: Library + +Wrap network errors consistently in urllib FTP support, so the test suite +doesn't fail when a network is available but the public internet is not +reachable. + +.. + +.. date: 2022-10-08-06-59-46 +.. gh-issue: 94597 +.. nonce: TsS0oT +.. section: Library + +The child watcher classes :class:`~asyncio.MultiLoopChildWatcher`, +:class:`~asyncio.FastChildWatcher` and :class:`~asyncio.SafeChildWatcher` +are deprecated and will be removed in Python 3.14. Patch by Kumar Aditya. + +.. + +.. date: 2022-10-07-09-52-37 +.. gh-issue: 98023 +.. nonce: aliEcl +.. section: Library + +Change default child watcher to :class:`~asyncio.PidfdChildWatcher` on Linux +systems which supports it. Patch by Kumar Aditya. + +.. + +.. date: 2022-10-06-23-42-00 +.. gh-issue: 90985 +.. nonce: s280JY +.. section: Library + +Earlier in 3.11 we deprecated ``asyncio.Task.cancel("message")``. We +realized we were too harsh, and have undeprecated it. + +.. + +.. date: 2022-10-06-17-59-22 +.. gh-issue: 65961 +.. nonce: SXlQnI +.. section: Library + +Do not rely solely on ``__cached__`` on modules; code will also support +``__spec__.cached``. + +.. + +.. date: 2022-10-05-20-52-17 +.. gh-issue: 97646 +.. nonce: Q4fVww +.. section: Library + +Replace deprecated ``application/javascript`` with ``text/javascript`` in +:mod:`mimetypes`. See :rfc:`9239`. Patch by Noam Cohen. + +.. + +.. date: 2022-10-05-16-10-24 +.. gh-issue: 97930 +.. nonce: NPSrzE +.. section: Library + +Apply changes from importlib_resources 5.8 and 5.9: ``Traversable.joinpath`` +provides a concrete implementation. ``as_file`` now supports directories of +resources. + +.. + +.. date: 2022-10-05-11-40-02 +.. gh-issue: 97850 +.. nonce: NzdREm +.. section: Library + +Remove deprecated :func:`!importlib.util.set_loader` and +:func:`!importlib.util.module_for_loader` from :mod:`importlib.util`. + +.. + +.. date: 2022-10-04-21-21-41 +.. gh-issue: 97837 +.. nonce: 19q-eg +.. section: Library + +Change deprecate warning message in :mod:`unittest` from + +``It is deprecated to return a value!=None`` + +to + +``It is deprecated to return a value that is not None from a test case`` + +.. + +.. date: 2022-10-04-07-55-19 +.. gh-issue: 97825 +.. nonce: mNdv1l +.. section: Library + +Fixes :exc:`AttributeError` when :meth:`subprocess.check_output` is used +with argument ``input=None`` and either of the arguments *encoding* or +*errors* are used. + +.. + +.. date: 2022-10-04-00-43-43 +.. gh-issue: 97008 +.. nonce: 3rjtt6 +.. section: Library + +:exc:`NameError` and :exc:`AttributeError` spelling suggestions provided +since :gh:`82711` are now also emitted by the pure Python :mod:`traceback` +module. Tests for those suggestions now exercise both implementations to +ensure they are equivalent. Patch by Carl Friedrich Bolz-Tereick and Łukasz +Langa. + +.. + +.. date: 2022-10-03-14-42-13 +.. gh-issue: 97799 +.. nonce: Y1iJvf +.. section: Library + +:mod:`dataclass` now uses :func:`inspect.get_annotations` to examine the +annotations on class objects. + +.. + +.. date: 2022-10-03-13-25-19 +.. gh-issue: 97781 +.. nonce: gCLLef +.. section: Library + +Removed deprecated interfaces in ``importlib.metadata`` (entry points +accessed as dictionary, implicit dictionary construction of sequence of +``EntryPoint`` objects, mutablility of ``EntryPoints`` result, access of +entry point by index). ``entry_points`` now has a simpler, more +straightforward API (returning ``EntryPoints``). + +.. + +.. date: 2022-09-30-15-56-20 +.. gh-issue: 96827 +.. nonce: lzy1iw +.. section: Library + +Avoid spurious tracebacks from :mod:`asyncio` when default executor cleanup +is delayed until after the event loop is closed (e.g. as the result of a +keyboard interrupt). + +.. + +.. date: 2022-09-30-09-22-37 +.. gh-issue: 95534 +.. nonce: ndEfPj +.. section: Library + +:meth:`gzip.GzipFile.read` reads 10% faster. + +.. + +.. date: 2022-09-29-23-22-24 +.. gh-issue: 97592 +.. nonce: tpJg_J +.. section: Library + +Avoid a crash in the C version of +:meth:`asyncio.Future.remove_done_callback` when an evil argument is passed. + +.. + +.. date: 2022-09-29-08-15-55 +.. gh-issue: 97639 +.. nonce: JSjWYW +.. section: Library + +Remove ``tokenize.NL`` check from :mod:`tabnanny`. + +.. + +.. date: 2022-09-25-23-24-52 +.. gh-issue: 97545 +.. nonce: HZLSNt +.. section: Library + +Make Semaphore run faster. + +.. + +.. date: 2022-09-25-20-42-33 +.. gh-issue: 73588 +.. nonce: uVtjEA +.. section: Library + +Fix generation of the default name of :class:`tkinter.Checkbutton`. +Previously, checkbuttons in different parent widgets could have the same +short name and share the same state if arguments "name" and "variable" are +not specified. Now they are globally unique. + +.. + +.. date: 2022-09-24-18-56-23 +.. gh-issue: 96865 +.. nonce: o9WUkW +.. section: Library + +fix Flag to use boundary CONFORM + +This restores previous Flag behavior of allowing flags with non-sequential +values to be combined; e.g. + +class Skip(Flag): TWO = 2 EIGHT = 8 + +Skip.TWO | Skip.EIGHT -> <Skip.TWO|EIGHT: 10> + +.. + +.. date: 2022-09-22-14-35-02 +.. gh-issue: 97005 +.. nonce: yf21Q7 +.. section: Library + +Update bundled libexpat to 2.4.9 + +.. + +.. date: 2022-09-22-11-50-29 +.. gh-issue: 85760 +.. nonce: DETTPd +.. section: Library + +Fix race condition in :mod:`asyncio` where +:meth:`~asyncio.SubprocessProtocol.process_exited` called before the +:meth:`~asyncio.SubprocessProtocol.pipe_data_received` leading to +inconsistent output. Patch by Kumar Aditya. + +.. + +.. date: 2022-09-18-04-51-30 +.. gh-issue: 96704 +.. nonce: DmamRX +.. section: Library + +Pass the correct ``contextvars.Context`` when a ``asyncio`` exception +handler is called on behalf of a task or callback handle. This adds a new +``Task`` method, ``get_context``, and also a new ``Handle`` method with the +same name. If this method is not found on a task object (perhaps because it +is a third-party library that does not yet provide this method), the context +prevailing at the time the exception handler is called is used. + +.. + +.. date: 2022-09-17-13-15-10 +.. gh-issue: 96819 +.. nonce: 6RfqM7 +.. section: Library + +Fixed check in :mod:`multiprocessing.resource_tracker` that guarantees that +the length of a write to a pipe is not greater than ``PIPE_BUF``. + +.. + +.. date: 2022-09-16-07-53-29 +.. gh-issue: 95865 +.. nonce: oHjX0A +.. section: Library + +Reduce :func:`urllib.parse.quote_from_bytes` memory use on large values. + +Contributed by Dennis Sweeney. + +.. + +.. date: 2022-09-15-00-37-33 +.. gh-issue: 96741 +.. nonce: 4b6czN +.. section: Library + +Corrected type annotation for dataclass attribute +``pstats.FunctionProfile.ncalls`` to be ``str``. + +.. + +.. date: 2022-09-13-15-12-31 +.. gh-issue: 96734 +.. nonce: G08vjz +.. section: Library + +Update :mod:`unicodedata` database to Unicode 15.0.0. + +.. + +.. date: 2022-09-10-16-46-16 +.. gh-issue: 96735 +.. nonce: 0YzJuG +.. section: Library + +Fix undefined behaviour in :func:`struct.unpack`. + +.. + +.. date: 2022-09-08-20-12-48 +.. gh-issue: 46412 +.. nonce: r_cfTh +.. section: Library + +Improve performance of ``bool(db)`` for large ndb/gdb databases. Previously +this would call ``len(db)`` which would iterate over all keys -- the answer +(empty or not) is known after the first key. + +.. + +.. date: 2022-09-07-22-49-37 +.. gh-issue: 96652 +.. nonce: YqOKxI +.. section: Library + +Fix the faulthandler implementation of ``faulthandler.register(signal, +chain=True)`` if the ``sigaction()`` function is not available: don't call +the previous signal handler if it's NULL. Patch by Victor Stinner. + +.. + +.. date: 2022-09-04-12-32-52 +.. gh-issue: 68163 +.. nonce: h6TJCc +.. section: Library + +Correct conversion of :class:`numbers.Rational`'s to :class:`float`. + +.. + +.. date: 2022-09-03-18-39-05 +.. gh-issue: 96538 +.. nonce: W156-D +.. section: Library + +Speed up ``bisect.bisect()`` functions by taking advantage of +type-stability. + +.. + +.. date: 2022-09-01-13-54-38 +.. gh-issue: 96465 +.. nonce: 0IJmrH +.. section: Library + +Fraction hashes are now cached. + +.. + +.. date: 2022-08-31-11-10-21 +.. gh-issue: 96079 +.. nonce: uqrXdJ +.. section: Library + +In :mod:`typing`, fix missing field ``name`` and incorrect ``__module__`` in +_AnnotatedAlias. + +.. + +.. date: 2022-08-30-12-32-00 +.. gh-issue: 96415 +.. nonce: 6W7ORH +.. section: Library + +Remove ``types._cell_factory`` from module namespace. + +.. + +.. date: 2022-08-30-11-46-36 +.. gh-issue: 95987 +.. nonce: CV7_u4 +.. section: Library + +Fix ``repr`` of ``Any`` subclasses. + +.. + +.. date: 2022-08-29-16-54-36 +.. gh-issue: 96388 +.. nonce: dCpJcu +.. section: Library + +Work around missing socket functions in :class:`~socket.socket`'s +``__repr__``. + +.. + +.. date: 2022-08-29-15-28-39 +.. gh-issue: 96385 +.. nonce: uLRTsf +.. section: Library + +Fix ``TypeVarTuple.__typing_prepare_subst__``. ``TypeError`` was not raised +when using more than one ``TypeVarTuple``, like ``[*T, *V]`` in type alias +substitutions. + +.. + +.. date: 2022-08-29-12-49-30 +.. gh-issue: 96142 +.. nonce: PdCMez +.. section: Library + +Add ``match_args``, ``kw_only``, ``slots``, and ``weakref_slot`` to +``_DataclassParams``. + +.. + +.. date: 2022-08-29-12-35-28 +.. gh-issue: 96073 +.. nonce: WaGstf +.. section: Library + +In :mod:`inspect`, fix overeager replacement of "``typing.``" in formatting +annotations. + +.. + +.. date: 2022-08-29-07-04-03 +.. gh-issue: 89258 +.. nonce: ri7ncj +.. section: Library + +Added a :meth:`~logging.Logger.getChildren` method to +:class:`logging.Logger`, to get the immediate child loggers of a logger. + +.. + +.. date: 2022-08-27-23-16-09 +.. gh-issue: 96346 +.. nonce: jJX14I +.. section: Library + +Use double caching for compiled RE patterns. + +.. + +.. date: 2022-08-27-21-26-52 +.. gh-issue: 96349 +.. nonce: XyYLlO +.. section: Library + +Fixed a minor performance regression in :func:`threading.Event.__init__` + +.. + +.. date: 2022-08-27-14-38-49 +.. gh-issue: 90467 +.. nonce: VOOB0p +.. section: Library + +Fix :class:`asyncio.streams.StreamReaderProtocol` to keep a strong reference +to the created task, so that it's not garbage collected + +.. + +.. date: 2022-08-23-13-30-30 +.. gh-issue: 96172 +.. nonce: 7WTHer +.. section: Library + +Fix a bug in ``unicodedata``: ``east_asian_width`` used to return the wrong +value for unassigned characters; and for yet unassigned, but reserved +characters. + +.. + +.. date: 2022-08-22-18-42-17 +.. gh-issue: 96159 +.. nonce: 3bFU39 +.. section: Library + +Fix a performance regression in logging TimedRotatingFileHandler. Only check +for special files when the rollover time has passed. + +.. + +.. date: 2022-08-22-13-54-20 +.. gh-issue: 96175 +.. nonce: bH7zGU +.. section: Library + +Fix unused ``localName`` parameter in the ``Attr`` class in +:mod:`xml.dom.minidom`. + +.. + +.. date: 2022-08-20-12-56-15 +.. gh-issue: 96145 +.. nonce: 8ah3pE +.. section: Library + +Add AttrDict to JSON module for use with object_hook. + +.. + +.. date: 2022-08-20-10-31-01 +.. gh-issue: 96052 +.. nonce: a6FhaD +.. section: Library + +Fix handling compiler warnings (SyntaxWarning and DeprecationWarning) in +:func:`codeop.compile_command` when checking for incomplete input. +Previously it emitted warnings and raised a SyntaxError. Now it always +returns ``None`` for incomplete input without emitting any warnings. + +.. + +.. date: 2022-08-19-18-21-01 +.. gh-issue: 96125 +.. nonce: ODcF1Y +.. section: Library + +Fix incorrect condition that causes ``sys.thread_info.name`` to be wrong on +pthread platforms. + +.. + +.. date: 2022-08-19-10-19-32 +.. gh-issue: 96019 +.. nonce: b7uAVP +.. section: Library + +Fix a bug in the ``makeunicodedata.py`` script leading to about 13 KiB of +space saving in the ``unicodedata`` module, specifically the character +decomposition data. + +.. + +.. date: 2022-08-18-14-53-53 +.. gh-issue: 95463 +.. nonce: GpP05c +.. section: Library + +Remove an incompatible change from :issue:`28080` that caused a regression +that ignored the utf8 in ``ZipInfo.flag_bits``. Patch by Pablo Galindo. + +.. + +.. date: 2022-08-14-18-59-54 +.. gh-issue: 69142 +.. nonce: 6is5Pq +.. section: Library + +Add ``%:z`` strftime format code (generates tzoffset with colons as +separator), see :ref:`strftime-strptime-behavior`. + +.. + +.. date: 2022-08-11-18-52-17 +.. gh-issue: 95899 +.. nonce: _Bi4uG +.. section: Library + +Fix :class:`asyncio.Runner` to call :func:`asyncio.set_event_loop` only once +to avoid calling :meth:`~asyncio.AbstractChildWatcher.attach_loop` multiple +times on child watchers. Patch by Kumar Aditya. + +.. + +.. date: 2022-08-11-18-22-29 +.. gh-issue: 95736 +.. nonce: LzRZXe +.. section: Library + +Fix :class:`unittest.IsolatedAsyncioTestCase` to set event loop before +calling setup functions. Patch by Kumar Aditya. + +.. + +.. date: 2022-08-11-03-16-48 +.. gh-issue: 95865 +.. nonce: 0IOkFP +.. section: Library + +Speed up :func:`urllib.parse.quote_from_bytes` by replacing a list +comprehension with ``map()``. + +.. + +.. date: 2022-08-10-17-34-07 +.. gh-issue: 95861 +.. nonce: qv-T5s +.. section: Library + +Add support for computing Spearman's correlation coefficient to the existing +statistics.correlation() function. + +.. + +.. date: 2022-08-10-11-54-04 +.. gh-issue: 95804 +.. nonce: i5FCFK +.. section: Library + +Fix ``logging`` shutdown handler so it respects +``MemoryHandler.flushOnClose``. + +.. + +.. date: 2022-08-08-01-42-11 +.. gh-issue: 95704 +.. nonce: MOPFfX +.. section: Library + +When a task catches :exc:`asyncio.CancelledError` and raises some other +error, the other error should generally not silently be suppressed. + +.. + +.. date: 2022-08-07-14-56-23 +.. gh-issue: 95149 +.. nonce: U0c6Ib +.. section: Library + +The :class:`HTTPStatus <http.HTTPStatus>` enum offers a couple of properties +to indicate the HTTP status category e.g. ``HTTPStatus.OK.is_success``. + +.. + +.. date: 2022-08-03-21-01-17 +.. gh-issue: 95609 +.. nonce: xxyjyX +.. section: Library + +Update bundled pip to 22.2.2. + +.. + +.. date: 2022-08-03-16-52-32 +.. gh-issue: 95289 +.. nonce: FMnHlV +.. section: Library + +Fix :class:`asyncio.TaskGroup` to propagate exception when +:exc:`asyncio.CancelledError` was replaced with another exception by a +context manger. Patch by Kumar Aditya and Guido van Rossum. + +.. + +.. date: 2022-07-29-20-58-37 +.. gh-issue: 94909 +.. nonce: YjMusj +.. section: Library + +Fix incorrect joining of relative Windows paths with drives in +:class:`pathlib.PurePath` initializer. + +.. + +.. date: 2022-07-28-17-14-38 +.. gh-issue: 95385 +.. nonce: 6YlsDI +.. section: Library + +Faster ``json.dumps()`` when sorting of keys is not requested (default). + +.. + +.. date: 2022-07-27-19-47-51 +.. gh-issue: 83901 +.. nonce: OSw06c +.. section: Library + +Improve :meth:`Signature.bind <inspect.Signature.bind>` error message for +missing keyword-only arguments. + +.. + +.. date: 2022-07-27-19-43-07 +.. gh-issue: 95339 +.. nonce: NuVQ68 +.. section: Library + +Update bundled pip to 22.2.1. + +.. + +.. date: 2022-07-27-11-35-45 +.. gh-issue: 95045 +.. nonce: iysT-Q +.. section: Library + +Fix GC crash when deallocating ``_lsprof.Profiler`` by untracking it before +calling any callbacks. Patch by Kumar Aditya. + +.. + +.. date: 2022-07-25-15-45-06 +.. gh-issue: 95231 +.. nonce: i807-g +.. section: Library + +Fail gracefully if :const:`~errno.EPERM` or :const:`~errno.ENOSYS` is raised +when loading :mod:`crypt` methods. This may happen when trying to load +``MD5`` on a Linux kernel with :abbr:`FIPS (Federal Information Processing +Standard)` enabled. + +.. + +.. date: 2022-07-24-18-00-42 +.. gh-issue: 95097 +.. nonce: lu5qNf +.. section: Library + +Fix :func:`asyncio.run` for :class:`asyncio.Task` implementations without +:meth:`~asyncio.Task.uncancel` method. Patch by Kumar Aditya. + +.. + +.. date: 2022-07-24-12-59-02 +.. gh-issue: 95087 +.. nonce: VvqXkN +.. section: Library + +Fix IndexError in parsing invalid date in the :mod:`email` module. + +.. + +.. date: 2022-07-24-12-00-06 +.. gh-issue: 95199 +.. nonce: -5A64k +.. section: Library + +Upgrade bundled setuptools to 63.2.0. + +.. + +.. date: 2022-07-24-09-15-35 +.. gh-issue: 95194 +.. nonce: ERVmqG +.. section: Library + +Upgrade bundled pip to 22.2. + +.. + +.. date: 2022-07-23-10-50-05 +.. gh-issue: 93899 +.. nonce: VT34A5 +.. section: Library + +Fix check for existence of :const:`os.EFD_CLOEXEC`, :const:`os.EFD_NONBLOCK` +and :const:`os.EFD_SEMAPHORE` flags on older kernel versions where these +flags are not present. Patch by Kumar Aditya. + +.. + +.. date: 2022-07-23-10-42-05 +.. gh-issue: 95166 +.. nonce: xw6p3C +.. section: Library + +Fix :meth:`concurrent.futures.Executor.map` to cancel the currently waiting +on future on an error - e.g. TimeoutError or KeyboardInterrupt. + +.. + +.. date: 2022-07-22-21-18-17 +.. gh-issue: 95132 +.. nonce: n9anlw +.. section: Library + +Fix a :mod:`sqlite3` regression where ``*args`` and ``**kwds`` were +incorrectly relayed from :py:func:`~sqlite3.connect` to the +:class:`~sqlite3.Connection` factory. The regression was introduced in +3.11a1 with PR 24421 (:gh:`85128`). Patch by Erlend E. Aasland.` + +.. + +.. date: 2022-07-22-17-19-57 +.. gh-issue: 93157 +.. nonce: RXByAk +.. section: Library + +Fix :mod:`fileinput` module didn't support ``errors`` option when +``inplace`` is true. + +.. + +.. date: 2022-07-22-09-09-08 +.. gh-issue: 91212 +.. nonce: 53O8Ab +.. section: Library + +Fixed flickering of the turtle window when the tracer is turned off. Patch +by Shin-myoung-serp. + +.. + +.. date: 2022-07-22-00-58-49 +.. gh-issue: 95077 +.. nonce: 4Z6CNC +.. section: Library + +Add deprecation warning for enum ``member.member`` access (e.g. +``Color.RED.BLUE``). Remove ``EnumMeta.__getattr__``. + +.. + +.. date: 2022-07-21-22-59-22 +.. gh-issue: 95109 +.. nonce: usxA9r +.. section: Library + +Ensure that timeouts scheduled with :class:`asyncio.Timeout` that have +already expired are delivered promptly. + +.. + +.. date: 2022-07-21-19-55-49 +.. gh-issue: 95105 +.. nonce: BIX2Km +.. section: Library + +:meth:`wsgiref.types.InputStream.__iter__` should return +``Iterator[bytes]``, not ``Iterable[bytes]``. Patch by Shantanu Jain. + +.. + +.. date: 2022-07-20-22-49-48 +.. gh-issue: 95066 +.. nonce: TuCu0E +.. section: Library + +Replaced assert with exception in :func:`ast.parse`, when +``feature_version`` has an invalid major version. Patch by Shantanu Jain. + +.. + +.. date: 2022-07-20-00-23-58 +.. gh-issue: 77617 +.. nonce: XGaqSQ +.. section: Library + +Add :mod:`sqlite3` :ref:`command-line interface <sqlite3-cli>`. Patch by +Erlend Aasland. + +.. + +.. date: 2022-07-19-15-37-11 +.. gh-issue: 95005 +.. nonce: iRmZ74 +.. section: Library + +Replace :c:expr:`_PyAccu` with :c:expr:`_PyUnicodeWriter` in JSON encoder +and StringIO and remove the :c:expr:`_PyAccu` implementation. + +.. + +.. date: 2022-07-17-22-31-32 +.. gh-issue: 90085 +.. nonce: c4FWcS +.. section: Library + +Remove ``-c/--clock`` and ``-t/--time`` CLI options of :mod:`timeit`. The +options had been deprecated since Python 3.3 and the functionality was +removed in Python 3.7. Patch by Shantanu Jain. + +.. + +.. date: 2022-07-15-08-13-51 +.. gh-issue: 94857 +.. nonce: 9_KvZJ +.. section: Library + +Fix refleak in ``_io.TextIOWrapper.reconfigure``. Patch by Kumar Aditya. + +.. + +.. date: 2022-07-14-00-43-52 +.. gh-issue: 94821 +.. nonce: e17ghU +.. section: Library + +Fix binding of unix socket to empty address on Linux to use an available +address from the abstract namespace, instead of "\0". + +.. + +.. date: 2022-07-11-10-41-48 +.. gh-issue: 94736 +.. nonce: EbsgeK +.. section: Library + +Fix crash when deallocating an instance of a subclass of +``_multiprocessing.SemLock``. Patch by Kumar Aditya. + +.. + +.. date: 2022-07-09-15-17-02 +.. gh-issue: 81620 +.. nonce: L0O_bV +.. section: Library + +Add random.binomialvariate(). + +.. + +.. date: 2022-07-09-08-55-04 +.. gh-issue: 74116 +.. nonce: 0XwYC1 +.. section: Library + +Allow :meth:`asyncio.StreamWriter.drain` to be awaited concurrently by +multiple tasks. Patch by Kumar Aditya. + +.. + +.. date: 2022-07-08-17-49-12 +.. gh-issue: 87822 +.. nonce: F9dzkf +.. section: Library + +When called with ``capture_locals=True``, the :mod:`traceback` module +functions swallow exceptions raised from calls to ``repr()`` on local +variables of frames. This is in order to prioritize the original exception +over rendering errors. An indication of the failure is printed in place of +the missing value. (Patch by Simon-Martin Schroeder). + +.. + +.. date: 2022-07-08-08-39-35 +.. gh-issue: 88050 +.. nonce: 0aOC_m +.. section: Library + +Fix :mod:`asyncio` subprocess transport to kill process cleanly when process +is blocked and avoid ``RuntimeError`` when loop is closed. Patch by Kumar +Aditya. + +.. + +.. date: 2022-07-07-15-46-55 +.. gh-issue: 94637 +.. nonce: IYEiUM +.. section: Library + +:meth:`SSLContext.set_default_verify_paths` now releases the GIL around +``SSL_CTX_set_default_verify_paths`` call. The function call performs I/O +and CPU intensive work. + +.. + +.. date: 2022-07-06-22-41-51 +.. gh-issue: 94309 +.. nonce: _XswsX +.. section: Library + +Deprecate aliases :class:`typing.Hashable` and :class:`typing.Sized` + +.. + +.. date: 2022-07-06-21-24-03 +.. gh-issue: 92546 +.. nonce: s5Upkh +.. section: Library + +An undocumented ``python -m pprint`` benchmark is moved into ``pprint`` +suite of pyperformance. Patch by Oleg Iarygin. + +.. + +.. date: 2022-07-06-16-01-08 +.. gh-issue: 94607 +.. nonce: Q6RYfz +.. section: Library + +Fix subclassing complex generics with type variables in :mod:`typing`. +Previously an error message saying ``Some type variables ... are not listed +in Generic[...]`` was shown. :mod:`typing` no longer populates +``__parameters__`` with the ``__parameters__`` of a Python class. + +.. + +.. date: 2022-07-06-14-57-33 +.. gh-issue: 94619 +.. nonce: PRqKVX +.. section: Library + +Remove the long-deprecated ``module_repr()`` from :mod:`importlib`. + +.. + +.. date: 2022-07-06-14-45-12 +.. gh-issue: 93910 +.. nonce: iZcp67 +.. section: Library + +The ability to access the other values of an enum on an enum (e.g. +``Color.RED.BLUE``) has been restored in order to fix a performance +regression. + +.. + +.. date: 2022-07-06-06-02-02 +.. gh-issue: 93896 +.. nonce: vIgWGr +.. section: Library + +Fix :func:`asyncio.run` and :class:`unittest.IsolatedAsyncioTestCase` to +always the set event loop as it was done in Python 3.10 and earlier. Patch +by Kumar Aditya. + +.. + +.. date: 2022-07-05-17-22-00 +.. gh-issue: 94343 +.. nonce: kf4H5r +.. section: Library + +Allow setting the attributes of ``reprlib.Repr`` during object +initialization + +.. + +.. date: 2022-07-03-16-41-03 +.. gh-issue: 94382 +.. nonce: zuVZeM +.. section: Library + +Port static types of ``_multiprocessing`` module to heap types. Patch by +Kumar Aditya. + +.. + +.. date: 2022-07-03-16-26-35 +.. gh-issue: 78724 +.. nonce: XNiJzf +.. section: Library + +Fix crash in :class:`struct.Struct` when it was not completely initialized +by initializing it in :meth:`~object.__new__``. Patch by Kumar Aditya. + +.. + +.. date: 2022-07-02-19-46-30 +.. gh-issue: 94510 +.. nonce: xOatDC +.. section: Library + +Re-entrant calls to :func:`sys.setprofile` and :func:`sys.settrace` now +raise :exc:`RuntimeError`. Patch by Pablo Galindo. + +.. + +.. date: 2022-06-29-09-48-37 +.. gh-issue: 92336 +.. nonce: otA6c6 +.. section: Library + +Fix bug where :meth:`linecache.getline` fails on bad files with +:exc:`UnicodeDecodeError` or :exc:`SyntaxError`. It now returns an empty +string as per the documentation. + +.. + +.. date: 2022-06-29-04-42-56 +.. gh-issue: 94398 +.. nonce: YOq_bJ +.. section: Library + +Once a :class:`asyncio.TaskGroup` has started shutting down (i.e., at least +one task has failed and the task group has started cancelling the remaining +tasks), it should not be possible to add new tasks to the task group. + +.. + +.. date: 2022-06-28-14-41-22 +.. gh-issue: 94383 +.. nonce: CXnquo +.. section: Library + +:mod:`xml.etree`: Remove the ``ElementTree.Element.copy()`` method of the +pure Python implementation, deprecated in Python 3.10, use the +:func:`copy.copy` function instead. The C implementation of :mod:`xml.etree` +has no ``copy()`` method, only a ``__copy__()`` method. Patch by Victor +Stinner. + +.. + +.. date: 2022-06-28-14-29-21 +.. gh-issue: 94379 +.. nonce: RrgKfh +.. section: Library + +:mod:`zipimport`: Remove ``find_loader()`` and ``find_module()`` methods, +deprecated in Python 3.10: use the ``find_spec()`` method instead. See +:pep:`451` for the rationale. Patch by Victor Stinner. + +.. + +.. date: 2022-06-28-00-24-48 +.. gh-issue: 94352 +.. nonce: JY1Ayt +.. section: Library + +:func:`shlex.split`: Passing ``None`` for *s* argument now raises an +exception, rather than reading :data:`sys.stdin`. The feature was deprecated +in Python 3.9. Patch by Victor Stinner. + +.. + +.. date: 2022-06-27-10-33-18 +.. gh-issue: 94318 +.. nonce: jR4_QV +.. section: Library + +Strip trailing spaces in :mod:`pydoc` text output. + +.. + +.. date: 2022-06-26-10-59-15 +.. gh-issue: 89988 +.. nonce: K8rnmt +.. section: Library + +Fix memory leak in :class:`pickle.Pickler` when looking up +:attr:`dispatch_table`. Patch by Kumar Aditya. + +.. + +.. date: 2022-06-25-23-44-44 +.. gh-issue: 90016 +.. nonce: EB409s +.. section: Library + +Deprecate :mod:`sqlite3` :ref:`default adapters and converters +<sqlite3-default-converters>`. Patch by Erlend E. Aasland. + +.. + +.. date: 2022-06-25-16-27-02 +.. gh-issue: 94254 +.. nonce: beP16v +.. section: Library + +Fixed types of :mod:`struct` module to be immutable. Patch by Kumar Aditya. + +.. + +.. date: 2022-06-25-13-38-53 +.. gh-issue: 93259 +.. nonce: FAGw-2 +.. section: Library + +Now raise ``ValueError`` when ``None`` or an empty string are passed to +``Distribution.from_name`` (and other callers). + +.. + +.. date: 2022-06-25-09-12-23 +.. gh-issue: 74696 +.. nonce: fxC9ua +.. section: Library + +:func:`shutil.make_archive` now passes the *root_dir* argument to custom +archivers which support it. + +.. + +.. date: 2022-06-24-20-00-57 +.. gh-issue: 94216 +.. nonce: hxnQPu +.. section: Library + +The :mod:`dis` module now has the opcodes for pseudo instructions (those +which are used by the compiler during code generation but then removed or +replaced by real opcodes before the final bytecode is emitted). + +.. + +.. date: 2022-06-24-19-40-40 +.. gh-issue: 93096 +.. nonce: 3RlK2d +.. section: Library + +Removed undocumented ``python -m codecs``. Use ``python -m unittest +test.test_codecs.EncodedFileTest`` instead. + +.. + +.. date: 2022-06-24-19-23-59 +.. gh-issue: 94207 +.. nonce: VhS1eS +.. section: Library + +Made :class:`_struct.Struct` GC-tracked in order to fix a reference leak in +the :mod:`_struct` module. + +.. + +.. date: 2022-06-24-19-16-09 +.. gh-issue: 93096 +.. nonce: r1_oIc +.. section: Library + +Removed undocumented ``-t`` argument of ``python -m base64``. Use ``python +-m unittest test.test_base64.LegacyBase64TestCase.test_encodebytes`` +instead. + +.. + +.. date: 2022-06-24-18-20-42 +.. gh-issue: 94226 +.. nonce: 8ZL4Fm +.. section: Library + +Remove the :func:`locale.format` function, deprecated in Python 3.7: use +:func:`locale.format_string` instead. Patch by Victor Stinner. + +.. + +.. date: 2022-06-24-17-11-33 +.. gh-issue: 94199 +.. nonce: 7releN +.. section: Library + +Remove the :func:`ssl.match_hostname` function. The +:func:`ssl.match_hostname` was deprecated in Python 3.7. OpenSSL performs +hostname matching since Python 3.7, Python no longer uses the +:func:`ssl.match_hostname` function. Patch by Victor Stinner. + +.. + +.. date: 2022-06-24-14-25-26 +.. gh-issue: 94214 +.. nonce: 03pXR5 +.. section: Library + +Document the ``context`` object used in the ``venv.EnvBuilder`` class, and +add the new environment's library path to it. + +.. + +.. date: 2022-06-24-10-39-56 +.. gh-issue: 94199 +.. nonce: MIuckY +.. section: Library + +Remove the :func:`ssl.wrap_socket` function, deprecated in Python 3.7: +instead, create a :class:`ssl.SSLContext` object and call its +:class:`ssl.SSLContext.wrap_socket` method. Any package that still uses +:func:`ssl.wrap_socket` is broken and insecure. The function neither sends a +SNI TLS extension nor validates server hostname. Code is subject to `CWE-295 +<https://cwe.mitre.org/data/definitions/295.html>`_: Improper Certificate +Validation. Patch by Victor Stinner. + +.. + +.. date: 2022-06-24-10-29-19 +.. gh-issue: 94199 +.. nonce: pfehmz +.. section: Library + +Remove the :func:`ssl.RAND_pseudo_bytes` function, deprecated in Python 3.6: +use :func:`os.urandom` or :func:`ssl.RAND_bytes` instead. Patch by Victor +Stinner. + +.. + +.. date: 2022-06-24-10-18-59 +.. gh-issue: 94199 +.. nonce: kYOo8g +.. section: Library + +:mod:`hashlib`: Remove the pure Python implementation of +:func:`hashlib.pbkdf2_hmac()`, deprecated in Python 3.10. Python 3.10 and +newer requires OpenSSL 1.1.1 (:pep:`644`): this OpenSSL version provides a C +implementation of :func:`~hashlib.pbkdf2_hmac()` which is faster. Patch by +Victor Stinner. + +.. + +.. date: 2022-06-24-09-41-41 +.. gh-issue: 94196 +.. nonce: r2KyfS +.. section: Library + +:mod:`gzip`: Remove the ``filename`` attribute of :class:`gzip.GzipFile`, +deprecated since Python 2.6, use the :attr:`~gzip.GzipFile.name` attribute +instead. In write mode, the ``filename`` attribute added ``'.gz'`` file +extension if it was not present. Patch by Victor Stinner. + +.. + +.. date: 2022-06-24-08-49-47 +.. gh-issue: 94182 +.. nonce: Wknau0 +.. section: Library + +run the :class:`asyncio.PidfdChildWatcher` on the running loop, this allows +event loops to run subprocesses when there is no default event loop running +on the main thread + +.. + +.. date: 2022-06-23-14-35-10 +.. gh-issue: 94169 +.. nonce: jeba90 +.. section: Library + +Remove ``io.OpenWrapper`` and ``_pyio.OpenWrapper``, deprecated in Python +3.10: just use :func:`open` instead. The :func:`open` (:func:`io.open`) +function is a built-in function. Since Python 3.10, :func:`_pyio.open` is +also a static method. Patch by Victor Stinner. + +.. + +.. date: 2022-06-23-13-12-05 +.. gh-issue: 91742 +.. nonce: sNytVX +.. section: Library + +Fix :mod:`pdb` crash after jump caused by a null pointer dereference. Patch +by Kumar Aditya. + +.. + +.. date: 2022-06-22-11-16-11 +.. gh-issue: 94101 +.. nonce: V9vDG8 +.. section: Library + +Manual instantiation of :class:`ssl.SSLSession` objects is no longer allowed +as it lead to misconfigured instances that crashed the interpreter when +attributes where accessed on them. + +.. + +.. date: 2022-06-21-11-40-31 +.. gh-issue: 84753 +.. nonce: FW1pxO +.. section: Library + +:func:`inspect.iscoroutinefunction`, :func:`inspect.isgeneratorfunction`, +and :func:`inspect.isasyncgenfunction` now properly return ``True`` for +duck-typed function-like objects like instances of +:class:`unittest.mock.AsyncMock`. + +This makes :func:`inspect.iscoroutinefunction` consistent with the behavior +of :func:`asyncio.iscoroutinefunction`. Patch by Mehdi ABAAKOUK. + +.. + +.. date: 2022-06-20-23-14-43 +.. gh-issue: 94028 +.. nonce: UofEcX +.. section: Library + +Fix a regression in the :mod:`sqlite3` where statement objects were not +properly cleared and reset after use in cursor iters. The regression was +introduced by PR 27884 in Python 3.11a1. Patch by Erlend E. Aasland. + +.. + +.. date: 2022-06-18-15-06-54 +.. gh-issue: 93973 +.. nonce: 4y6UQT +.. section: Library + +Add keyword argument ``all_errors`` to ``asyncio.create_connection`` so that +multiple connection errors can be raised as an ``ExceptionGroup``. + +.. + +.. date: 2022-06-17-16-00-55 +.. gh-issue: 93963 +.. nonce: 8YYZ-2 +.. section: Library + +Officially deprecate from ``importlib.abc`` classes moved to +``importlib.resources.abc``. + +.. + +.. date: 2022-06-17-12-02-30 +.. gh-issue: 93858 +.. nonce: R49ARc +.. section: Library + +Prevent error when activating venv in nested fish instances. + +.. + +.. date: 2022-06-16-11-16-53 +.. gh-issue: 93820 +.. nonce: 00X0Y5 +.. section: Library + +Pickle :class:`enum.Flag` by name. + +.. + +.. date: 2022-06-16-09-24-50 +.. gh-issue: 93847 +.. nonce: kuv8bN +.. section: Library + +Fix repr of enum of generic aliases. + +.. + +.. date: 2022-06-15-21-35-11 +.. gh-issue: 91404 +.. nonce: 39TZzW +.. section: Library + +Revert the :mod:`re` memory leak when a match is terminated by a signal or +memory allocation failure as the implemented fix caused a major performance +regression. + +.. + +.. date: 2022-06-15-21-28-16 +.. gh-issue: 83499 +.. nonce: u3DQJ- +.. section: Library + +Fix double closing of file description in :mod:`tempfile`. + +.. + +.. date: 2022-06-15-21-20-02 +.. gh-issue: 93820 +.. nonce: FAMLY8 +.. section: Library + +Fixed a regression when :func:`copy.copy`-ing :class:`enum.Flag` with +multiple flag members. + +.. + +.. date: 2022-06-11-13-32-17 +.. gh-issue: 79512 +.. nonce: A1KTDr +.. section: Library + +Fixed names and ``__module__`` value of :mod:`weakref` classes +:class:`~weakref.ReferenceType`, :class:`~weakref.ProxyType`, +:class:`~weakref.CallableProxyType`. It makes them pickleable. + +.. + +.. date: 2022-06-09-17-15-26 +.. gh-issue: 91389 +.. nonce: OE4vS5 +.. section: Library + +Fix an issue where :mod:`dis` utilities could report missing or incorrect +position information in the presence of ``CACHE`` entries. + +.. + +.. date: 2022-06-09-14-44-21 +.. gh-issue: 93626 +.. nonce: sfghs46 +.. section: Library + +Set ``__future__.annotations`` to have a ``None`` mandatoryRelease to +indicate that it is currently 'TBD'. + +.. + +.. date: 2022-06-09-10-12-55 +.. gh-issue: 90473 +.. nonce: 683m_C +.. section: Library + +Emscripten and WASI have no home directory and cannot provide :pep:`370` +user site directory. + +.. + +.. date: 2022-06-08-20-11-02 +.. gh-issue: 90494 +.. nonce: LIZT85 +.. section: Library + +:func:`copy.copy` and :func:`copy.deepcopy` now always raise a TypeError if +``__reduce__()`` returns a tuple with length 6 instead of silently ignore +the 6th item or produce incorrect result. + +.. + +.. date: 2022-06-07-14-53-46 +.. gh-issue: 90549 +.. nonce: T4FMKY +.. section: Library + +Fix a multiprocessing bug where a global named resource (such as a +semaphore) could leak when a child process is spawned (as opposed to +forked). + +.. + +.. date: 2022-06-06-13-19-43 +.. gh-issue: 93521 +.. nonce: _vE8m9 +.. section: Library + +Fixed a case where dataclasses would try to add ``__weakref__`` into the +``__slots__`` for a dataclass that specified ``weakref_slot=True`` when it +was already defined in one of its bases. This resulted in a ``TypeError`` +upon the new class being created. + +.. + +.. date: 2022-06-06-12-58-27 +.. gh-issue: 79579 +.. nonce: e8rB-M +.. section: Library + +:mod:`sqlite3` now correctly detects DML queries with leading comments. +Patch by Erlend E. Aasland. + +.. + +.. date: 2022-06-05-22-22-42 +.. gh-issue: 93421 +.. nonce: 43UO_8 +.. section: Library + +Update :data:`sqlite3.Cursor.rowcount` when a DML statement has run to +completion. This fixes the row count for SQL queries like ``UPDATE ... +RETURNING``. Patch by Erlend E. Aasland. + +.. + +.. date: 2022-06-04-00-11-54 +.. gh-issue: 93475 +.. nonce: vffFw1 +.. section: Library + +Expose ``FICLONE`` and ``FICLONERANGE`` constants in :mod:`fcntl`. Patch by +Illia Volochii. + +.. + +.. date: 2022-06-03-22-13-28 +.. gh-issue: 93370 +.. nonce: tjfu9L +.. section: Library + +Deprecate :data:`sqlite3.version` and :data:`sqlite3.version_info`. + +.. + +.. date: 2022-06-02-08-40-58 +.. gh-issue: 91810 +.. nonce: Gtk44w +.. section: Library + +Suppress writing an XML declaration in open files in ``ElementTree.write()`` +with ``encoding='unicode'`` and ``xml_declaration=None``. + +.. + +.. date: 2022-06-01-11-24-13 +.. gh-issue: 91162 +.. nonce: NxvU_u +.. section: Library + +Support splitting of unpacked arbitrary-length tuple over ``TypeVar`` and +``TypeVarTuple`` parameters. For example: + +* ``A[T, *Ts][*tuple[int, ...]]`` -> ``A[int, *tuple[int, ...]]`` +* ``A[*Ts, T][*tuple[int, ...]]`` -> ``A[*tuple[int, ...], int]`` + +.. + +.. date: 2022-05-31-14-58-40 +.. gh-issue: 93353 +.. nonce: 9Hvm6o +.. section: Library + +Fix the :func:`importlib.resources.as_file` context manager to remove the +temporary file if destroyed late during Python finalization: keep a local +reference to the :func:`os.remove` function. Patch by Victor Stinner. + +.. + +.. date: 2022-05-30-21-42-50 +.. gh-issue: 83658 +.. nonce: 01Ntx0 +.. section: Library + +Make :class:`multiprocessing.Pool` raise an exception if +``maxtasksperchild`` is not ``None`` or a positive int. + +.. + +.. date: 2022-05-28-08-02-55 +.. gh-issue: 93312 +.. nonce: HY0Uzj +.. section: Library + +Add :const:`os.PIDFD_NONBLOCK` flag to open a file descriptor for a process +with :func:`os.pidfd_open` in non-blocking mode. Patch by Kumar Aditya. + +.. + +.. date: 2022-05-27-22-17-11 +.. gh-issue: 88123 +.. nonce: mkYl5q +.. section: Library + +Implement Enum __contains__ that returns True or False to replace the +deprecated behaviour that would sometimes raise a TypeError. + +.. + +.. date: 2022-05-27-13-18-18 +.. gh-issue: 93297 +.. nonce: e2zuHz +.. section: Library + +Make asyncio task groups prevent child tasks from being GCed + +.. + +.. date: 2022-05-27-10-52-06 +.. gh-issue: 85308 +.. nonce: K6r-tJ +.. section: Library + +Changed :class:`argparse.ArgumentParser` to use :term:`filesystem encoding +and error handler` instead of default text encoding to read arguments from +file (e.g. ``fromfile_prefix_chars`` option). This change affects Windows; +argument file should be encoded with UTF-8 instead of ANSI Codepage. + +.. + +.. date: 2022-05-26-23-10-55 +.. gh-issue: 93156 +.. nonce: 4XfDVN +.. section: Library + +Accessing the :attr:`pathlib.PurePath.parents` sequence of an absolute path +using negative index values produced incorrect results. + +.. + +.. date: 2022-05-26-09-24-41 +.. gh-issue: 93162 +.. nonce: W1VuhU +.. section: Library + +Add the ability for :func:`logging.config.dictConfig` to usefully configure +:class:`~logging.handlers.QueueHandler` and +:class:`~logging.handlers.QueueListener` as a pair, and add +:func:`logging.getHandlerByName` and :func:`logging.getHandlerNames` APIs to +allow access to handlers by name. + +.. + +.. date: 2022-05-26-08-41-34 +.. gh-issue: 93243 +.. nonce: uw6x5z +.. section: Library + +The :mod:`smtpd` module was removed per the schedule in :pep:`594`. + +.. + +.. date: 2022-05-25-22-09-38 +.. gh-issue: 92886 +.. nonce: ylwDSc +.. section: Library + +Replace ``assert`` statements with ``raise AssertionError()`` in +:class:`~wsgiref.BaseHandler` so that the tested behaviour is maintained +running with optimizations ``(-O)``. + +.. + +.. date: 2022-05-25-15-57-39 +.. gh-issue: 90155 +.. nonce: YMstB5 +.. section: Library + +Fix broken :class:`asyncio.Semaphore` when acquire is cancelled. + +.. + +.. date: 2022-05-25-02-45-41 +.. gh-issue: 90817 +.. nonce: yxANgU +.. section: Library + +The :func:`locale.resetlocale` function is deprecated and will be removed in +Python 3.13. Use ``locale.setlocale(locale.LC_ALL, "")`` instead. Patch by +Victor Stinner. + +.. + +.. date: 2022-05-25-00-21-28 +.. gh-issue: 91513 +.. nonce: 9VyCT4 +.. section: Library + +Added ``taskName`` attribute to :mod:`logging` module for use with +:mod:`asyncio` tasks. + +.. + +.. date: 2022-05-24-11-19-04 +.. gh-issue: 74696 +.. nonce: -cnf-A +.. section: Library + +:func:`shutil.make_archive` no longer temporarily changes the current +working directory during creation of standard ``.zip`` or tar archives. + +.. + +.. date: 2022-05-24-10-59-02 +.. gh-issue: 92728 +.. nonce: zxTifq +.. section: Library + +The :func:`re.template` function and the corresponding :const:`re.TEMPLATE` +and :const:`re.T` flags are restored after they were removed in 3.11.0b1, +but they are now deprecated, so they might be removed from Python 3.13. + +.. + +.. date: 2022-05-22-23-46-18 +.. gh-issue: 93033 +.. nonce: wZfiL- +.. section: Library + +Search in some strings (platform dependent i.e [U+0xFFFF, U+0x0100] on +Windows or [U+0xFFFFFFFF, U+0x00010000] on Linux 64-bit) are now up to 10 +times faster. + +.. + +.. date: 2022-05-22-16-08-01 +.. gh-issue: 89973 +.. nonce: jc-Q4g +.. section: Library + +Fix :exc:`re.error` raised in :mod:`fnmatch` if the pattern contains a +character range with upper bound lower than lower bound (e.g. ``[c-a]``). +Now such ranges are interpreted as empty ranges. + +.. + +.. date: 2022-05-21-13-16-16 +.. gh-issue: 93044 +.. nonce: eJ_XkZ +.. section: Library + +No longer convert the database argument of :func:`sqlite3.connect` to bytes +before passing it to the factory. + +.. + +.. date: 2022-05-20-15-52-43 +.. gh-issue: 93010 +.. nonce: WF-cAc +.. section: Library + +In a very special case, the email package tried to append the nonexistent +``InvalidHeaderError`` to the defect list. It should have been +``InvalidHeaderDefect``. + +.. + +.. date: 2022-05-19-22-34-42 +.. gh-issue: 92986 +.. nonce: e6uKxj +.. section: Library + +Fix :func:`ast.unparse` when ``ImportFrom.level`` is None + +.. + +.. date: 2022-05-19-17-49-58 +.. gh-issue: 92932 +.. nonce: o2peTh +.. section: Library + +Now :func:`~dis.dis` and :func:`~dis.get_instructions` handle operand values +for instructions prefixed by ``EXTENDED_ARG_QUICK``. Patch by Sam Gross and +Donghee Na. + +.. + +.. date: 2022-05-19-13-33-18 +.. gh-issue: 92675 +.. nonce: ZeerMZ +.. section: Library + +Fix :func:`venv.ensure_directories` to accept :class:`pathlib.Path` +arguments in addition to :class:`str` paths. Patch by David Foster. + +.. + +.. date: 2022-05-18-21-04-09 +.. gh-issue: 87901 +.. nonce: lnf041 +.. section: Library + +Removed the ``encoding`` argument from :func:`os.popen` that was added in +3.11b1. + +.. + +.. date: 2022-05-18-17-18-41 +.. gh-issue: 91922 +.. nonce: DwWIsJ +.. section: Library + +Fix function :func:`sqlite.connect` and the :class:`sqlite.Connection` +constructor on non-UTF-8 locales. Also, they now support bytes paths +non-decodable with the current FS encoding. + +.. + +.. date: 2022-05-17-06-27-39 +.. gh-issue: 92869 +.. nonce: t8oBkw +.. section: Library + +Added :class:`~ctypes.c_time_t` to :mod:`ctypes`, which has the same size as +the :c:type:`time_t` type in C. + +.. + +.. date: 2022-05-16-14-35-39 +.. gh-issue: 92839 +.. nonce: owSMyo +.. section: Library + +Fixed crash resulting from calling bisect.insort() or bisect.insort_left() +with the key argument not equal to None. + +.. + +.. date: 2022-05-14-11-41-23 +.. gh-issue: 90473 +.. nonce: kPdOZl +.. section: Library + +:mod:`subprocess` now fails early on Emscripten and WASI platforms to work +around missing :func:`os.pipe` on WASI. + +.. + +.. date: 2022-05-14-09-01-38 +.. gh-issue: 89325 +.. nonce: ys-2BZ +.. section: Library + +Removed many old deprecated :mod:`unittest` features: +:class:`~unittest.TestCase` method aliases, undocumented and broken +:class:`~unittest.TestCase` method ``assertDictContainsSubset``, +undocumented :meth:`TestLoader.loadTestsFromModule +<unittest.TestLoader.loadTestsFromModule>` parameter *use_load_tests*, and +an underscored alias of the :class:`~unittest.TextTestResult` class. + +.. + +.. date: 2022-05-12-15-19-00 +.. gh-issue: 92734 +.. nonce: d0wjDt +.. section: Library + +Allow multi-element reprs emitted by :mod:`reprlib` to be pretty-printed +using configurable indentation. + +.. + +.. date: 2022-05-11-19-33-27 +.. gh-issue: 92671 +.. nonce: KE4v6a +.. section: Library + +Fixed :func:`ast.unparse` for empty tuples in the assignment target context. + +.. + +.. date: 2022-05-11-14-34-09 +.. gh-issue: 91581 +.. nonce: glkou2 +.. section: Library + +:meth:`~datetime.datetime.utcfromtimestamp` no longer attempts to resolve +``fold`` in the pure Python implementation, since the fold is never 1 in +UTC. In addition to being slightly faster in the common case, this also +prevents some errors when the timestamp is close to :attr:`datetime.min +<datetime.datetime.min>`. Patch by Paul Ganssle. + +.. + +.. date: 2022-05-11-10-06-31 +.. gh-issue: 86388 +.. nonce: 7ivUtT +.. section: Library + +Removed randrange() functionality deprecated since Python 3.10. Formerly, +randrange(10.0) losslessly converted to randrange(10). Now, it raises a +TypeError. Also, the exception raised for non-integral values such as +randrange(10.5) or randrange('10') has been changed from ValueError to +TypeError. + +.. + +.. date: 2022-05-10-16-30-40 +.. gh-issue: 90385 +.. nonce: 1_wBRQ +.. section: Library + +Add :meth:`pathlib.Path.walk` as an alternative to :func:`os.walk`. + +.. + +.. date: 2022-05-10-07-57-27 +.. gh-issue: 92550 +.. nonce: Rk_UzM +.. section: Library + +Fix :meth:`pathlib.Path.rglob` for empty pattern. + +.. + +.. date: 2022-05-09-22-27-11 +.. gh-issue: 92591 +.. nonce: V7RCk2 +.. section: Library + +Allow :mod:`logging` filters to return a :class:`logging.LogRecord` instance +so that filters attached to :class:`logging.Handler`\ s can enrich records +without side effects on other handlers. + +.. + +.. date: 2022-05-09-21-31-41 +.. gh-issue: 92445 +.. nonce: tJosdm +.. section: Library + +Fix a bug in :mod:`argparse` where ``nargs="*"`` would raise an error +instead of returning an empty list when 0 arguments were supplied if choice +was also defined in ``parser.add_argument``. + +.. + +.. date: 2022-05-09-11-55-04 +.. gh-issue: 92547 +.. nonce: CzVZft +.. section: Library + +Remove undocumented :mod:`sqlite3` features deprecated in Python 3.10: + +* ``sqlite3.enable_shared_cache()`` +* ``sqlite3.OptimizedUnicode`` + +Patch by Erlend E. Aasland. + +.. + +.. date: 2022-05-09-09-28-02 +.. gh-issue: 92530 +.. nonce: M4Q1RS +.. section: Library + +Fix an issue that occurred after interrupting +:func:`threading.Condition.notify`. + +.. + +.. date: 2022-05-09-01-27-25 +.. gh-issue: 92531 +.. nonce: vV7S_O +.. section: Library + +The statistics.median_grouped() function now always return a float. +Formerly, it did not convert the input type when for sequences of length +one. + +.. + +.. date: 2022-05-08-19-21-14 +.. gh-issue: 84131 +.. nonce: rG5kI7 +.. section: Library + +The :class:`pathlib.Path` deprecated method ``link_to`` has been removed. +Use 3.10's :meth:`~pathlib.Path.hardlink_to` method instead as its semantics +are consistent with that of :meth:`~pathlib.Path.symlink_to`. + +.. + +.. date: 2022-05-08-18-51-14 +.. gh-issue: 89336 +.. nonce: TL6ip7 +.. section: Library + +Removed :mod:`configparser` module APIs: the ``SafeConfigParser`` class +alias, the ``ParsingError.filename`` property and parameter, and the +``ConfigParser.readfp`` method, all of which were deprecated since Python +3.2. + +.. + +.. date: 2022-05-06-13-00-57 +.. gh-issue: 92391 +.. nonce: s-Lase +.. section: Library + +Add :meth:`~object.__class_getitem__` to :class:`csv.DictReader` and +:class:`csv.DictWriter`, allowing them to be parameterized at runtime. Patch +by Marc Mueller. + +.. + +.. date: 2022-04-26-18-37-24 +.. gh-issue: 91968 +.. nonce: fuuH1_ +.. section: Library + +Add ``SO_RTABLE`` and ``SO_USER_COOKIE`` constants to :mod:`socket`. + +.. + +.. date: 2022-04-25-10-23-01 +.. gh-issue: 91810 +.. nonce: DOHa6B +.. section: Library + +:class:`~xml.etree.ElementTree.ElementTree` method +:meth:`~xml.etree.ElementTree.ElementTree.write` and function +:func:`~xml.etree.ElementTree.tostring` now use the text file's encoding +("UTF-8" if not available) instead of locale encoding in XML declaration +when ``encoding="unicode"`` is specified. + +.. + +.. date: 2022-04-24-22-26-45 +.. gh-issue: 81790 +.. nonce: M5Rvpm +.. section: Library + +:func:`os.path.splitdrive` now understands DOS device paths with UNC links +(beginning ``\\?\UNC\``). Contributed by Barney Gale. + +.. + +.. date: 2022-04-21-19-14-29 +.. gh-issue: 91760 +.. nonce: 54AR-m +.. section: Library + +Apply more strict rules for numerical group references and group names in +regular expressions. Only sequence of ASCII digits is now accepted as a +numerical reference. The group name in bytes patterns and replacement +strings can now only contain ASCII letters and digits and underscore. + +.. + +.. date: 2022-04-15-22-07-36 +.. gh-issue: 90622 +.. nonce: 0C6l8h +.. section: Library + +Worker processes for :class:`concurrent.futures.ProcessPoolExecutor` are no +longer spawned on demand (a feature added in 3.9) when the multiprocessing +context start method is ``"fork"`` as that can lead to deadlocks in the +child processes due to a fork happening while threads are running. + +.. + +.. date: 2022-04-15-17-38-55 +.. gh-issue: 91577 +.. nonce: Ah7cLL +.. section: Library + +Move imports in :class:`~multiprocessing.SharedMemory` methods to module +level so that they can be executed late in python finalization. + +.. + +.. date: 2022-04-15-13-16-25 +.. gh-issue: 91581 +.. nonce: 9OGsrN +.. section: Library + +Remove an unhandled error case in the C implementation of calls to +:meth:`datetime.fromtimestamp <datetime.datetime.fromtimestamp>` with no +time zone (i.e. getting a local time from an epoch timestamp). This should +have no user-facing effect other than giving a possibly more accurate error +message when called with timestamps that fall on 10000-01-01 in the local +time. Patch by Paul Ganssle. + +.. + +.. date: 2022-04-15-11-29-38 +.. gh-issue: 91539 +.. nonce: 7WgVuA +.. section: Library + +Improve performance of ``urllib.request.getproxies_environment`` when there +are many environment variables + +.. + +.. date: 2022-04-14-08-37-16 +.. gh-issue: 91524 +.. nonce: g8PiIu +.. section: Library + +Speed up the regular expression substitution (functions :func:`re.sub` and +:func:`re.subn` and corresponding :class:`re.Pattern` methods) for +replacement strings containing group references by 2--3 times. + +.. + +.. date: 2022-04-12-18-05-40 +.. gh-issue: 91447 +.. nonce: N_Fs4H +.. section: Library + +Fix findtext in the xml module to only give an empty string when the text +attribute is set to None. + +.. + +.. date: 2022-04-11-16-55-41 +.. gh-issue: 91456 +.. nonce: DK3KKl +.. section: Library + +Deprecate current default auto() behavior: In 3.13 the default will be for +for auto() to always return the largest member value incremented by 1, and +to raise if incompatible value types are used. + +.. + +.. bpo: 47231 +.. date: 2022-04-08-22-12-11 +.. nonce: lvyglt +.. section: Library + +Fixed an issue with inconsistent trailing slashes in tarfile longname +directories. + +.. + +.. bpo: 39064 +.. date: 2022-04-03-19-40-09 +.. nonce: 76PbIz +.. section: Library + +:class:`zipfile.ZipFile` now raises :exc:`zipfile.BadZipFile` instead of +``ValueError`` when reading a corrupt zip file in which the central +directory offset is negative. + +.. + +.. bpo: 41287 +.. date: 2022-04-03-11-25-02 +.. nonce: 8CTdwf +.. section: Library + +Fix handling of the ``doc`` argument in subclasses of :func:`property`. + +.. + +.. date: 2022-04-01-12-35-44 +.. gh-issue: 90005 +.. nonce: pvaLHQ +.. section: Library + +:mod:`ctypes` dependency ``libffi`` is now detected with ``pkg-config``. + +.. + +.. bpo: 32547 +.. date: 2022-04-01-09-43-54 +.. nonce: NIUiNC +.. section: Library + +The constructors for :class:`~csv.DictWriter` and :class:`~csv.DictReader` +now coerce the ``fieldnames`` argument to a :class:`list` if it is an +iterator. + +.. + +.. bpo: 35540 +.. date: 2022-03-22-18-28-55 +.. nonce: nyijX9 +.. section: Library + +Fix :func:`dataclasses.asdict` crash when :class:`collections.defaultdict` +is present in the attributes. + +.. + +.. bpo: 47063 +.. date: 2022-03-19-04-41-42 +.. nonce: nwRfUo +.. section: Library + +Add an index_pages parameter to support using non-default index page names. + +.. + +.. bpo: 47025 +.. date: 2022-03-16-14-24-14 +.. nonce: qtT3CE +.. section: Library + +Drop support for :class:`bytes` on :data:`sys.path`. + +.. + +.. bpo: 46951 +.. date: 2022-03-08-04-46-44 +.. nonce: SWAz97 +.. section: Library + +Order the contents of zipapp archives, to make builds more reproducible. + +.. + +.. bpo: 42777 +.. date: 2022-02-21-01-37-00 +.. nonce: nWK3E6 +.. section: Library + +Implement :meth:`pathlib.Path.is_mount` for Windows paths. + +.. + +.. bpo: 46755 +.. date: 2022-02-15-12-40-48 +.. nonce: zePJfx +.. section: Library + +In :class:`QueueHandler`, clear ``stack_info`` from :class:`LogRecord` to +prevent stack trace from being written twice. + +.. + +.. bpo: 45393 +.. date: 2022-02-09-23-44-27 +.. nonce: 9v5Y8U +.. section: Library + +Fix the formatting for ``await x`` and ``not x`` in the operator precedence +table when using the :func:`help` system. + +.. + +.. bpo: 46642 +.. date: 2022-02-05-18-46-54 +.. nonce: YI6nHQ +.. section: Library + +Improve error message when trying to subclass an instance of +:data:`typing.TypeVar`, :data:`typing.ParamSpec`, +:data:`typing.TypeVarTuple`, etc. Based on patch by Gregory Beauregard. + +.. + +.. bpo: 46364 +.. date: 2022-01-14-10-49-20 +.. nonce: SzhlU9 +.. section: Library + +Restrict use of sockets instead of pipes for stdin of subprocesses created +by :mod:`asyncio` to AIX platform only. + +.. + +.. bpo: 28249 +.. date: 2022-01-09-14-23-00 +.. nonce: 4dzB80 +.. section: Library + +Set :attr:`doctest.DocTest.lineno` to ``None`` when object does not have +:attr:`__doc__`. + +.. + +.. bpo: 46197 +.. date: 2022-01-03-15-07-06 +.. nonce: Z0djv6 +.. section: Library + +Fix :mod:`ensurepip` environment isolation for subprocess running ``pip``. + +.. + +.. bpo: 45924 +.. date: 2021-12-27-15-32-15 +.. nonce: 0ZpHX2 +.. section: Library + +Fix :mod:`asyncio` incorrect traceback when future's exception is raised +multiple times. Patch by Kumar Aditya. + +.. + +.. bpo: 45046 +.. date: 2021-08-29-19-59-16 +.. nonce: eGq0NC +.. section: Library + +Add support of context managers in :mod:`unittest`: methods +:meth:`~unittest.TestCase.enterContext` and +:meth:`~unittest.TestCase.enterClassContext` of class +:class:`~unittest.TestCase`, method +:meth:`~unittest.IsolatedAsyncioTestCase.enterAsyncContext` of class +:class:`~unittest.IsolatedAsyncioTestCase` and function +:func:`unittest.enterModuleContext`. + +.. + +.. bpo: 44173 +.. date: 2021-08-27-18-07-35 +.. nonce: oW92Ev +.. section: Library + +Enable fast seeking of uncompressed unencrypted :class:`zipfile.ZipExtFile` + +.. + +.. bpo: 42627 +.. date: 2021-05-22-07-58-59 +.. nonce: EejtD0 +.. section: Library + +Fix incorrect parsing of Windows registry proxy settings + +.. + +.. bpo: 42047 +.. date: 2020-10-15-18-37-12 +.. nonce: XDdoSF +.. section: Library + +Add :func:`threading.get_native_id` support for DragonFly BSD. Patch by +David Carlier. + +.. + +.. bpo: 14243 +.. date: 2020-09-28-04-56-04 +.. nonce: YECnxv +.. section: Library + +The :class:`tempfile.NamedTemporaryFile` function has a new optional +parameter *delete_on_close* + +.. + +.. bpo: 41246 +.. date: 2020-07-08-20-32-13 +.. nonce: 2trYf3 +.. section: Library + +Give the same callback function for when the overlapped operation is done to +the functions ``recv``, ``recv_into``, ``recvfrom``, ``sendto``, ``send`` +and ``sendfile`` inside ``IocpProactor``. + +.. + +.. bpo: 39264 +.. date: 2020-01-09-01-57-12 +.. nonce: GsBL9- +.. section: Library + +Fixed :meth:`collections.UserDict.get` to not call :meth:`__missing__` when +a value is not found. This matches the behavior of :class:`dict`. Patch by +Bar Harel. + +.. + +.. bpo: 38693 +.. date: 2019-11-04-22-21-27 +.. nonce: w_OAov +.. section: Library + +:mod:`importlib` now uses f-strings internally instead of ``str.format``. + +.. + +.. bpo: 38267 +.. date: 2019-09-25-00-37-51 +.. nonce: X9Jb5V +.. section: Library + +Add *timeout* parameter to :meth:`asyncio.loop.shutdown_default_executor`. +The default value is ``None``, which means the executor will be given an +unlimited amount of time. When called from :class:`asyncio.Runner` or +:func:`asyncio.run`, the default timeout is 5 minutes. + +.. + +.. bpo: 34828 +.. date: 2018-09-28-22-18-03 +.. nonce: 5Zyi_S +.. section: Library + +:meth:`sqlite3.Connection.iterdump` now handles databases that use +``AUTOINCREMENT`` in one or more tables. + +.. + +.. bpo: 32990 +.. date: 2018-09-23-07-47-29 +.. nonce: 2FVVTU +.. section: Library + +Support reading wave files with the ``WAVE_FORMAT_EXTENSIBLE`` format in the +:mod:`wave` module. + +.. + +.. bpo: 26253 +.. date: 2017-07-31-13-35-28 +.. nonce: 8v_sCs +.. section: Library + +Allow adjustable compression level for tarfile streams in +:func:`tarfile.open`. + +.. + +.. date: 2022-10-16-17-34-45 +.. gh-issue: 85525 +.. nonce: DvkD0v +.. section: Documentation + +Remove extra row + +.. + +.. date: 2022-10-11-09-40-50 +.. gh-issue: 86404 +.. nonce: dEAb8W +.. section: Documentation + +Deprecated tools ``make suspicious`` and ``rstlint.py`` are now removed. +They have been replaced by `spinx-lint +<https://pypi.org/project/sphinx-lint/>`_. + +.. + +.. date: 2022-10-02-10-58-52 +.. gh-issue: 97741 +.. nonce: 39l023 +.. section: Documentation + +Fix ``!`` in c domain ref target syntax via a ``conf.py`` patch, so it works +as intended to disable ref target resolution. + +.. + +.. date: 2022-09-01-17-03-04 +.. gh-issue: 96432 +.. nonce: 1EJ1-4 +.. section: Documentation + +Fraction literals now support whitespace around the forward slash, +``Fraction('2 / 3')``. + +.. + +.. date: 2022-08-19-17-07-45 +.. gh-issue: 96098 +.. nonce: nDp43u +.. section: Documentation + +Improve discoverability of the higher level concurrent.futures module by +providing clearer links from the lower level threading and multiprocessing +modules. + +.. + +.. date: 2022-08-13-20-34-51 +.. gh-issue: 95957 +.. nonce: W9ZZAx +.. section: Documentation + +What's New 3.11 now has instructions for how to provide compiler and linker +flags for Tcl/Tk and OpenSSL on RHEL 7 and CentOS 7. + +.. + +.. date: 2022-08-12-01-12-52 +.. gh-issue: 95588 +.. nonce: PA0FI7 +.. section: Documentation + +Clarified the conflicting advice given in the :mod:`ast` documentation about +:func:`ast.literal_eval` being "safe" for use on untrusted input while at +the same time warning that it can crash the process. The latter statement is +true and is deemed unfixable without a large amount of work unsuitable for a +bugfix. So we keep the warning and no longer claim that ``literal_eval`` is +safe. + +.. + +.. date: 2022-08-03-13-35-08 +.. gh-issue: 91207 +.. nonce: eJ4pPf +.. section: Documentation + +Fix stylesheet not working in Windows CHM htmlhelp docs and add warning that +they are deprecated. Contributed by C.A.M. Gerlach. + +.. + +.. date: 2022-07-30-00-23-11 +.. gh-issue: 95454 +.. nonce: we7AFm +.. section: Documentation + +Replaced incorrectly written true/false values in documentiation. Patch by +Robert O'Shea + +.. + +.. date: 2022-07-29-23-02-19 +.. gh-issue: 95451 +.. nonce: -tgB93 +.. section: Documentation + +Update library documentation with :ref:`availability information +<wasm-availability>` on WebAssembly platforms ``wasm32-emscripten`` and +``wasm32-wasi``. + +.. + +.. date: 2022-07-29-09-04-02 +.. gh-issue: 95415 +.. nonce: LKTyw6 +.. section: Documentation + +Use consistent syntax for platform availability. The directive now supports +a content body and emits a warning when it encounters an unknown platform. + +.. + +.. date: 2022-07-07-08-42-05 +.. gh-issue: 94321 +.. nonce: pmCIPb +.. section: Documentation + +Document the :pep:`246` style protocol type +:class:`sqlite3.PrepareProtocol`. + +.. + +.. date: 2022-06-19-18-18-22 +.. gh-issue: 86128 +.. nonce: 39DDTD +.. section: Documentation + +Document a limitation in ThreadPoolExecutor where its exit handler is +executed before any handlers in atexit. + +.. + +.. date: 2022-06-16-10-10-59 +.. gh-issue: 61162 +.. nonce: 1ypkG8 +.. section: Documentation + +Clarify :mod:`sqlite3` behavior when +:ref:`sqlite3-connection-context-manager`. + +.. + +.. date: 2022-06-15-12-12-49 +.. gh-issue: 87260 +.. nonce: epyI7D +.. section: Documentation + +Align :mod:`sqlite3` argument specs with the actual implementation. + +.. + +.. date: 2022-05-29-21-22-54 +.. gh-issue: 86986 +.. nonce: lFXw8j +.. section: Documentation + +The minimum Sphinx version required to build the documentation is now 3.2. + +.. + +.. date: 2022-05-26-14-51-25 +.. gh-issue: 88831 +.. nonce: 5Cccr5 +.. section: Documentation + +Augmented documentation of asyncio.create_task(). Clarified the need to keep +strong references to tasks and added a code snippet detailing how to do this. + +.. + +.. date: 2022-05-26-11-33-23 +.. gh-issue: 86438 +.. nonce: kEGGmK +.. section: Documentation + +Clarify that :option:`-W` and :envvar:`PYTHONWARNINGS` are matched literally +and case-insensitively, rather than as regular expressions, in +:mod:`warnings`. + +.. + +.. date: 2022-05-20-18-42-10 +.. gh-issue: 93031 +.. nonce: c2RdJe +.. section: Documentation + +Update tutorial introduction output to use 3.10+ SyntaxError invalid range. + +.. + +.. date: 2022-05-18-23-58-26 +.. gh-issue: 92240 +.. nonce: bHvYiz +.. section: Documentation + +Added release dates for "What's New in Python 3.X" for 3.0, 3.1, 3.2, 3.8 +and 3.10 + +.. + +.. bpo: 47161 +.. date: 2022-03-30-17-56-01 +.. nonce: gesHfS +.. section: Documentation + +Document that :class:`pathlib.PurePath` does not collapse initial double +slashes because they denote UNC paths. + +.. + +.. bpo: 40838 +.. date: 2022-01-13-16-03-15 +.. nonce: k3NVCf +.. section: Documentation + +Document that :func:`inspect.getdoc`, :func:`inspect.getmodule`, and +:func:`inspect.getsourcefile` might return ``None``. + +.. + +.. bpo: 43689 +.. date: 2021-04-01-08-09-34 +.. nonce: mqCfLe +.. section: Documentation + +The ``Differ`` documentation now also mentions other whitespace characters, +which make it harder to understand the diff output. + +.. + +.. bpo: 38056 +.. date: 2019-09-12-08-28-17 +.. nonce: 6ktYkc +.. section: Documentation + +Overhaul the :ref:`error-handlers` documentation in :mod:`codecs`. + +.. + +.. bpo: 13553 +.. date: 2017-12-10-19-13-39 +.. nonce: gQbZs4 +.. section: Documentation + +Document tkinter.Tk args. + +.. + +.. date: 2022-10-20-17-49-50 +.. gh-issue: 95027 +.. nonce: viRpJB +.. section: Tests + +On Windows, when the Python test suite is run with the ``-jN`` option, the +ANSI code page is now used as the encoding for the stdout temporary file, +rather than using UTF-8 which can lead to decoding errors. Patch by Victor +Stinner. + +.. + +.. date: 2022-09-08-18-31-26 +.. gh-issue: 96624 +.. nonce: 5cANM1 +.. section: Tests + +Fixed the failure of repeated runs of ``test.test_unittest`` caused by side +effects in ``test_dotted_but_module_not_loaded``. + +.. + +.. date: 2022-08-22-14-59-42 +.. gh-issue: 95243 +.. nonce: DeD66V +.. section: Tests + +Mitigate the inherent race condition from using find_unused_port() in +testSockName() by trying to find an unused port a few times before failing. +Patch by Ross Burton. + +.. + +.. date: 2022-08-05-09-57-43 +.. gh-issue: 95573 +.. nonce: edMdQB +.. section: Tests + +:source:`Lib/test/test_asyncio/test_ssl.py` exposed a bug in the macOS +kernel where intense concurrent load on non-blocking sockets occasionally +causes :const:`errno.ENOBUFS` ("No buffer space available") to be emitted. +FB11063974 filed with Apple, in the mean time as a workaround buffer size +used in tests on macOS is decreased to avoid intermittent failures. Patch +by Fantix King. + +.. + +.. date: 2022-07-26-15-22-19 +.. gh-issue: 95280 +.. nonce: h8HvbP +.. section: Tests + +Fix problem with ``test_ssl`` ``test_get_ciphers`` on systems that require +perfect forward secrecy (PFS) ciphers. + +.. + +.. date: 2022-07-24-20-19-05 +.. gh-issue: 95212 +.. nonce: fHiU4e +.. section: Tests + +Make multiprocessing test case ``test_shared_memory_recreate`` +parallel-safe. + +.. + +.. date: 2022-07-24-17-24-42 +.. gh-issue: 95218 +.. nonce: zfBLtu +.. section: Tests + +Move tests for importlib.resources into test_importlib.resources. + +.. + +.. date: 2022-07-24-16-28-31 +.. gh-issue: 93963 +.. nonce: UB9azu +.. section: Tests + +Updated tests to use preferred location for ``importlib.resources`` ABCs. + +.. + +.. date: 2022-07-08-12-22-00 +.. gh-issue: 94675 +.. nonce: IiTs5f +.. section: Tests + +Add a regression test for :mod:`re` exponentional slowdown when using +rjsmin. + +.. + +.. date: 2022-07-05-17-53-13 +.. gh-issue: 91330 +.. nonce: Qys5IL +.. section: Tests + +Added more tests for :mod:`dataclasses` to cover behavior with data +descriptor-based fields. + +.. + +.. date: 2022-06-27-21-27-20 +.. gh-issue: 94208 +.. nonce: VR6HX- +.. section: Tests + +``test_ssl`` is now checking for supported TLS version and protocols in more +tests. + +.. + +.. date: 2022-06-27-08-53-40 +.. gh-issue: 94315 +.. nonce: MoZT9t +.. section: Tests + +Tests now check for DAC override capability instead of relying on +:func:`os.geteuid`. + +.. + +.. date: 2022-06-21-17-37-46 +.. gh-issue: 54781 +.. nonce: BjVAVg +.. section: Tests + +Rename test_tk to test_tkinter, and rename test_ttk_guionly to test_ttk. +Patch by Victor Stinner. + +.. + +.. date: 2022-06-20-23-04-52 +.. gh-issue: 93839 +.. nonce: OE3Ybk +.. section: Tests + +Move ``Lib/ctypes/test/`` to ``Lib/test/test_ctypes/``. Patch by Victor +Stinner. + +.. + +.. date: 2022-06-17-15-20-09 +.. gh-issue: 93951 +.. nonce: CW1Vv4 +.. section: Tests + +In test_bdb.StateTestCase.test_skip, avoid including auxiliary importers. + +.. + +.. date: 2022-06-17-13-55-11 +.. gh-issue: 93957 +.. nonce: X4ovYV +.. section: Tests + +Provide nicer error reporting from subprocesses in +test_venv.EnsurePipTest.test_with_pip. + +.. + +.. date: 2022-06-17-13-27-21 +.. gh-issue: 93884 +.. nonce: 5pvPvl +.. section: Tests + +Add test cases for :c:func:`PyNumber_ToBase` that take a large number or a +non-int object as parameter. + +.. + +.. date: 2022-06-16-21-38-18 +.. gh-issue: 93852 +.. nonce: U_Hl6s +.. section: Tests + +test_asyncio, test_logging, test_socket and test_socketserver now create +AF_UNIX domains in the current directory to no longer fail with +``OSError("AF_UNIX path too long")`` if the temporary directory (the +:envvar:`TMPDIR` environment variable) is too long. Patch by Victor Stinner. + +.. + +.. date: 2022-06-16-17-50-58 +.. gh-issue: 93353 +.. nonce: JdpATx +.. section: Tests + +regrtest now checks if a test leaks temporary files or directories if run +with -jN option. Patch by Victor Stinner. + +.. + +.. date: 2022-06-10-21-18-14 +.. gh-issue: 84461 +.. nonce: 9TAb26 +.. section: Tests + +``run_tests.py`` now handles cross compiling env vars correctly and pass +``HOSTRUNNER`` to regression tests. + +.. + +.. date: 2022-06-08-22-32-56 +.. gh-issue: 93616 +.. nonce: e5Kkx2 +.. section: Tests + +``test_modulefinder`` now creates a temporary directory in +``ModuleFinderTest.setUp()`` instead of module scope. + +.. + +.. date: 2022-06-08-14-17-59 +.. gh-issue: 93575 +.. nonce: Xb2LNB +.. section: Tests + +Fix issue with test_unicode test_raiseMemError. The test case now use +``test.support.calcobjsize`` to calculate size of PyUnicode structs. +:func:`sys.getsizeof` may return different size when string has UTF-8 +memory. + +.. + +.. date: 2022-06-05-10-16-45 +.. gh-issue: 90473 +.. nonce: QMu7A8 +.. section: Tests + +WASI does not have a ``chmod(2)`` syscall. :func:`os.chmod` is now a dummy +function on WASI. Skip all tests that depend on working :func:`os.chmod`. + +.. + +.. date: 2022-06-04-12-05-31 +.. gh-issue: 90473 +.. nonce: RSpjF7 +.. section: Tests + +Skip tests on WASI that require symlinks with absolute paths. + +.. + +.. date: 2022-06-03-16-26-04 +.. gh-issue: 57539 +.. nonce: HxWgYO +.. section: Tests + +Increase calendar test coverage for +:meth:`calendar.LocaleTextCalendar.formatweekday`. + +.. + +.. date: 2022-06-03-14-18-37 +.. gh-issue: 90473 +.. nonce: 7iXVRK +.. section: Tests + +Skip symlink tests on WASI. wasmtime uses ``openat2(2)`` with +``RESOLVE_BENEATH`` flag, which prevents symlinks with absolute paths. + +.. + +.. date: 2022-06-03-12-22-44 +.. gh-issue: 89858 +.. nonce: ftBvjE +.. section: Tests + +Fix ``test_embed`` for out-of-tree builds. Patch by Kumar Aditya. + +.. + +.. date: 2022-05-25-23-07-15 +.. gh-issue: 92886 +.. nonce: Aki63_ +.. section: Tests + +Fixing tests that fail when running with optimizations (``-O``) in +``test_imaplib.py``. + +.. + +.. date: 2022-05-25-23-00-35 +.. gh-issue: 92886 +.. nonce: Y-vrWj +.. section: Tests + +Fixing tests that fail when running with optimizations (``-O``) in +``test_zipimport.py`` + +.. + +.. date: 2022-05-25-22-53-30 +.. gh-issue: 92886 +.. nonce: mIfdtz +.. section: Tests + +Fixing tests that fail when running with optimizations (``-O``) in +``test_py_compile.py`` + +.. + +.. date: 2022-05-25-22-43-11 +.. gh-issue: 92886 +.. nonce: 9HQb9e +.. section: Tests + +Fixing tests that fail when running with optimizations (``-O``) in +``test_sys_settrace.py``. + +.. + +.. date: 2022-05-25-22-34-10 +.. gh-issue: 92886 +.. nonce: 1Lkt8S +.. section: Tests + +Fixing tests that fail when running with optimizations (``-O``) in +``_test_multiprocessing.py`` + +.. + +.. date: 2022-05-12-05-51-06 +.. gh-issue: 92670 +.. nonce: 7L43Z_ +.. section: Tests + +Skip ``test_shutil.TestCopy.test_copyfile_nonexistent_dir`` test on AIX as +the test uses a trailing slash to force the OS consider the path as a +directory, but on AIX the trailing slash has no effect and is considered as +a file. + +.. + +.. date: 2022-05-08-15-40-41 +.. gh-issue: 92514 +.. nonce: Xbf5JY +.. section: Tests + +Remove unused ``test.support.BasicTestRunner``. Patch by Jelle Zijlstra. + +.. + +.. bpo: 47016 +.. date: 2022-03-14-23-28-17 +.. nonce: K-t2QX +.. section: Tests + +Create a GitHub Actions workflow for verifying bundled pip and setuptools. +Patch by Illia Volochii and Adam Turner. + +.. + +.. date: 2022-09-20-12-43-44 +.. gh-issue: 96761 +.. nonce: IF29kR +.. section: Build + +Fix the build process of clang compiler for :program:`_bootstrap_python` if +LTO optimization is applied. Patch by Matthias Görgens and Donghee Na. + +.. + +.. date: 2022-09-17-11-19-24 +.. gh-issue: 96883 +.. nonce: p_gr62 +.. section: Build + +``wasm32-emscripten`` builds for browsers now include +:mod:`concurrent.futures` for :mod:`asyncio` and :mod:`unittest.mock`. + +.. + +.. date: 2022-09-12-18-34-51 +.. gh-issue: 85936 +.. nonce: tX4VCU +.. section: Build + +CPython now uses the ThinLTO option as the default policy if the Clang +compiler accepts the flag. Patch by Donghee Na. + +.. + +.. date: 2022-09-11-14-23-49 +.. gh-issue: 96729 +.. nonce: W4uBWL +.. section: Build + +Ensure that Windows releases built with ``Tools\msi\buildrelease.bat`` are +upgradable to and from official Python releases. + +.. + +.. date: 2022-08-26-11-50-03 +.. gh-issue: 96269 +.. nonce: x_J5h0 +.. section: Build + +Shared module targets now depend on new ``MODULE_DEPS`` variable, which +includes ``EXPORTSYMS``. This fixes a build order issue on unsupported AIX +platform. + +.. + +.. date: 2022-08-26-11-09-11 +.. gh-issue: 84461 +.. nonce: Nsdn_R +.. section: Build + +``wasm32-emscripten`` platform no longer builds :mod:`resource` module, +:func:`~os.getresuid`, :func:`~os.getresgid`, and their setters. The APIs +are stubs and not functional. + +.. + +.. date: 2022-08-15-10-56-07 +.. gh-issue: 95973 +.. nonce: Bsswsc +.. section: Build + +Add a new ``--with-dsymutil`` configure option to link debug information +in macOS. Patch by Pablo Galindo. + +.. + +.. date: 2022-08-12-13-06-03 +.. gh-issue: 90536 +.. nonce: qMpF6p +.. section: Build + +Use the BOLT post-link optimizer to improve performance, particularly on +medium-to-large applications. + +.. + +.. date: 2022-08-04-15-29-35 +.. gh-issue: 93744 +.. nonce: svRuqm +.. section: Build + +Remove the ``configure --with-cxx-main`` build option: it didn't work for +many years. Remove the ``MAINCC`` variable from ``configure`` and +``Makefile``. Patch by Victor Stinner. + +.. + +.. date: 2022-07-26-18-13-34 +.. gh-issue: 94801 +.. nonce: 9fREfy +.. section: Build + +Fix a regression in ``configure`` script that caused some header checks to +ignore custom ``CPPFLAGS``. The regression was introduced in :gh:`94802`. + +.. + +.. date: 2022-07-25-09-48-43 +.. gh-issue: 95145 +.. nonce: ZNS3dj +.. section: Build + +wasm32-wasi builds no longer depend on WASIX's pthread stubs. Python now has +its own stubbed pthread API. + +.. + +.. date: 2022-07-25-08-59-35 +.. gh-issue: 95174 +.. nonce: g8woUW +.. section: Build + +Python now detects missing ``dup`` function in WASI and works around some +missing :mod:`errno`, :mod:`select`, and :mod:`socket` constants. + +.. + +.. date: 2022-07-23-21-39-09 +.. gh-issue: 95174 +.. nonce: 7cYMZR +.. section: Build + +Python now skips missing :mod:`socket` functions and methods on WASI. WASI +can only create sockets from existing fd / accept and has no netdb. + +.. + +.. date: 2022-07-21-09-17-01 +.. gh-issue: 95085 +.. nonce: E9x2S_ +.. section: Build + +Platforms ``wasm32-unknown-emscripten`` and ``wasm32-unknown-wasi`` have +been promoted to :pep:`11` tier 3 platform support. + +.. + +.. date: 2022-07-14-11-13-26 +.. gh-issue: 94847 +.. nonce: s3Kr5p +.. section: Build + +Fixed ``_decimal`` module build issue on GCC when compiling with LTO and +pydebug. Debug builds no longer force inlining of functions. + +.. + +.. date: 2022-07-14-02-45-44 +.. gh-issue: 94841 +.. nonce: lLRTdf +.. section: Build + +Fix the possible performance regression of :c:func:`PyObject_Free` compiled +with MSVC version 1932. + +.. + +.. date: 2022-07-13-10-13-10 +.. gh-issue: 94801 +.. nonce: 3xUB24 +.. section: Build + +``configure`` now uses custom flags like ``ZLIB_CFLAGS`` and ``ZLIB_LIBS`` +when searching for headers and libraries. + +.. + +.. date: 2022-07-12-13-39-18 +.. gh-issue: 94773 +.. nonce: koHKm5 +.. section: Build + +``deepfreeze.py`` now supports code object with frozensets that contain +incompatible, unsortable types. + +.. + +.. date: 2022-07-08-10-28-23 +.. gh-issue: 94682 +.. nonce: ZtGt_0 +.. section: Build + +Build and test with OpenSSL 1.1.1q + +.. + +.. date: 2022-06-30-17-18-23 +.. gh-issue: 90005 +.. nonce: EIOOla +.. section: Build + +Dependencies of :mod:`readline` and :mod:`curses` module are now detected in +``configure`` script with ``pkg-config``. Only ``ncurses`` / ``ncursesw`` +are detected automatically. The old ``curses`` library is not configured +automatically. Workaround for missing ``termcap`` or ``tinfo`` library has +been removed. + +.. + +.. date: 2022-06-30-17-00-54 +.. gh-issue: 90005 +.. nonce: iiq5qD +.. section: Build + +Fix building ``_ctypes`` extension without ``pkg-config``. + +.. + +.. date: 2022-06-30-09-57-39 +.. gh-issue: 90005 +.. nonce: 9-pQyR +.. section: Build + +``_dbm`` module dependencies are now detected by configure. + +.. + +.. date: 2022-06-29-08-58-31 +.. gh-issue: 94404 +.. nonce: 3MadM6 +.. section: Build + +``makesetup`` now works around an issue with sed on macOS and uses correct +CFLAGS for object files that end up in a shared extension. Module CFLAGS are +used before PY_STDMODULE_CFLAGS to avoid clashes with system headers. + +.. + +.. date: 2022-06-28-09-42-10 +.. gh-issue: 93939 +.. nonce: _VWxKW +.. section: Build + +C extension modules are now built by ``configure`` and ``make`` instead of +``distutils`` and ``setup.py``. + +.. + +.. date: 2022-06-27-11-57-15 +.. gh-issue: 93939 +.. nonce: rv7s8W +.. section: Build + +The ``2to3``, ``idle``, and ``pydoc`` scripts are now generated and +installed by ``Makefile`` instead of ``setup.py``. + +.. + +.. date: 2022-06-25-23-25-47 +.. gh-issue: 94280 +.. nonce: YhEyW_ +.. section: Build + +Updated pegen regeneration script on Windows to find and use Python 3.9 or +higher. Prior to this, pegen regeneration already required 3.9 or higher, +but the script may have used lower versions of Python. + +.. + +.. date: 2022-06-08-14-28-03 +.. gh-issue: 93584 +.. nonce: 0xfHOK +.. section: Build + +Address race condition in ``Makefile`` when installing a PGO build. All +``test`` and ``install`` targets now depend on ``all`` target. + +.. + +.. date: 2022-06-04-12-53-53 +.. gh-issue: 93491 +.. nonce: ehM211 +.. section: Build + +``configure`` now detects and reports :pep:`11` support tiers. + +.. + +.. date: 2022-05-31-18-04-58 +.. gh-issue: 69093 +.. nonce: 6lSa0C +.. section: Build + +Fix ``Modules/Setup.stdlib.in`` rule for ``_sqlite3`` extension. + +.. + +.. date: 2022-05-25-13-56-00 +.. gh-issue: 93207 +.. nonce: B9Rubf +.. section: Build + +``va_start()`` with two parameters, like ``va_start(args, format),`` is now +required to build Python. ``va_start()`` is no longer called with a single +parameter. Patch by Kumar Aditya. + +.. + +.. date: 2022-05-25-05-46-00 +.. gh-issue: 93202 +.. nonce: T37jtj +.. section: Build + +Python now always use the ``%zu`` and ``%zd`` printf formats to format a +:c:type:`size_t` or ``Py_ssize_t`` number. Building Python 3.12 requires a C11 +compiler, so these printf formats are now always supported. Patch by Victor +Stinner. + +.. + +.. date: 2022-05-12-10-19-15 +.. gh-issue: 90473 +.. nonce: -syvqK +.. section: Build + +Disable pymalloc and increase stack size on ``wasm32-wasi``. + +.. + +.. bpo: 34449 +.. date: 2018-08-21-11-10-18 +.. nonce: Z3qm3c +.. section: Build + +Drop invalid compiler switch ``-fPIC`` for HP aCC on HP-UX. Patch by Michael +Osipov. + +.. + +.. date: 2022-10-19-20-00-28 +.. gh-issue: 98360 +.. nonce: O2m6YG +.. section: Windows + +Fixes :mod:`multiprocessing` spawning child processes on Windows from a +virtual environment to ensure that child processes that also use +:mod:`multiprocessing` to spawn more children will recognize that they are +in a virtual environment. + +.. + +.. date: 2022-10-19-19-35-37 +.. gh-issue: 98414 +.. nonce: FbHZuS +.. section: Windows + +Fix :file:`py.exe` launcher handling of :samp:`-V:{<company>}/` option when +default preferences have been set in environment variables or configuration +files. + +.. + +.. date: 2022-10-02-11-59-23 +.. gh-issue: 97728 +.. nonce: dIdlPE +.. section: Windows + +Fix possible crashes caused by the use of uninitialized variables when pass +invalid arguments in :func:`os.system` on Windows and in Windows-specific +modules (like ``winreg``). + +.. + +.. date: 2022-09-29-23-08-49 +.. gh-issue: 90989 +.. nonce: no89Q2 +.. section: Windows + +Made :ref:`launcher` install per-user by default (unless an all users +install already exists), and clarify some text in the installer. + +.. + +.. date: 2022-09-29-22-27-04 +.. gh-issue: 97649 +.. nonce: bI7OQU +.. section: Windows + +The ``Tools`` directory is no longer installed on Windows + +.. + +.. date: 2022-09-23-15-40-04 +.. gh-issue: 96965 +.. nonce: CsnEGs +.. section: Windows + +Update libffi to 3.4.3 + +.. + +.. date: 2022-09-07-00-11-33 +.. gh-issue: 96577 +.. nonce: kV4K_1 +.. section: Windows + +Fixes a potential buffer overrun in :mod:`msilib`. + +.. + +.. date: 2022-09-05-18-32-47 +.. gh-issue: 96559 +.. nonce: 561sUd +.. section: Windows + +Fixes the Windows launcher not using the compatible interpretation of +default tags found in configuration files when no tag was passed to the +command. + +.. + +.. date: 2022-08-30-12-01-51 +.. gh-issue: 94781 +.. nonce: OxO-Gr +.. section: Windows + +Fix :file:`pcbuild.proj` to clean previous instances of output files in +``Python\deepfreeze`` and ``Python\frozen_modules`` directories on Windows. +Patch by Charlie Zhao. + +.. + +.. date: 2022-08-26-00-11-18 +.. gh-issue: 89545 +.. nonce: zmJMY_ +.. section: Windows + +Updates :mod:`platform` code getting the Windows version to use native +Windows Management Instrumentation (WMI) queries to determine OS version, +type, and architecture. + +.. + +.. date: 2022-08-10-22-46-48 +.. gh-issue: 95733 +.. nonce: 2_urOp +.. section: Windows + +Make certain requirements of the Windows Store package optional to allow +installing on earlier updates of Windows. + +.. + +.. date: 2022-08-04-18-47-54 +.. gh-issue: 95656 +.. nonce: VJ1d13 +.. section: Windows + +Enable the :meth:`~sqlite3.Connection.enable_load_extension` :mod:`sqlite3` +API. + +.. + +.. date: 2022-08-04-01-12-27 +.. gh-issue: 95587 +.. nonce: Fvdv5q +.. section: Windows + +Fixes some issues where the Windows installer would incorrectly detect +certain features of an existing install when upgrading. + +.. + +.. date: 2022-08-03-00-49-46 +.. gh-issue: 94399 +.. nonce: KvxHc0 +.. section: Windows + +Restores the behaviour of :ref:`launcher` for ``/usr/bin/env`` shebang +lines, which will now search :envvar:`PATH` for an executable matching the +given command. If none is found, the usual search process is used. + +.. + +.. date: 2022-07-30-14-18-33 +.. gh-issue: 95445 +.. nonce: mjrTaq +.. section: Windows + +Fixes the unsuccessful removal of the HTML document directory when +uninstalling with Windows msi. + +.. + +.. date: 2022-07-28-20-21-38 +.. gh-issue: 95359 +.. nonce: ywMrgu +.. section: Windows + +Fix :ref:`launcher` handling of :file:`py.ini` commands (it was incorrectly +expecting a ``py_`` prefix on keys) and crashes when reading per-user +configuration file. + +.. + +.. date: 2022-07-26-20-33-12 +.. gh-issue: 95285 +.. nonce: w6fa22 +.. section: Windows + +Fix :ref:`launcher` handling of command lines where it is only passed a +short executable name. + +.. + +.. date: 2022-07-16-16-18-32 +.. gh-issue: 90844 +.. nonce: vwITT3 +.. section: Windows + +Allow virtual environments to correctly launch when they have spaces in the +path. + +.. + +.. date: 2022-07-12-20-45-43 +.. gh-issue: 94772 +.. nonce: uNMmdG +.. section: Windows + +Fix incorrect handling of shebang lines in py.exe launcher + +.. + +.. date: 2022-06-20-22-32-14 +.. gh-issue: 94018 +.. nonce: bycC3A +.. section: Windows + +:mod:`zipfile` will now remove trailing spaces from path components when +extracting files on Windows. + +.. + +.. date: 2022-06-15-01-03-52 +.. gh-issue: 93824 +.. nonce: mR4mxu +.. section: Windows + +Drag and drop of files onto Python files in Windows Explorer has been +enabled for Windows ARM64. + +.. + +.. date: 2022-05-28-19-36-13 +.. gh-issue: 43414 +.. nonce: NGMJ3g +.. section: Windows + +:func:`os.get_terminal_size` now attempts to read the size from any provided +handle, rather than only supporting file descriptors 0, 1 and 2. + +.. + +.. date: 2022-05-19-21-44-25 +.. gh-issue: 92817 +.. nonce: Jrf-Kv +.. section: Windows + +Ensures that :file:`py.exe` will prefer an active virtual environment over +default tags specified with environment variables or through a +:file:`py.ini` file. + +.. + +.. date: 2022-05-19-14-01-30 +.. gh-issue: 92984 +.. nonce: Dsxnlr +.. section: Windows + +Explicitly disable incremental linking for non-Debug builds + +.. + +.. date: 2022-05-16-11-45-06 +.. gh-issue: 92841 +.. nonce: NQx107 +.. section: Windows + +:mod:`asyncio` no longer throws ``RuntimeError: Event loop is closed`` on +interpreter exit after asynchronous socket activity. Patch by Oleg Iarygin. + +.. + +.. bpo: 46907 +.. date: 2022-05-05-06-27-59 +.. nonce: IW-uvT +.. section: Windows + +Update Windows installer to use SQLite 3.38.4. + +.. + +.. date: 2022-04-12-18-35-20 +.. gh-issue: 91061 +.. nonce: x40hSK +.. section: Windows + +Accept os.PathLike for the argument to winsound.PlaySound + +.. + +.. bpo: 42658 +.. date: 2022-03-20-15-47-35 +.. nonce: 16eXtb +.. section: Windows + +Support native Windows case-insensitive path comparisons by using +``LCMapStringEx`` instead of :func:`str.lower` in :func:`ntpath.normcase`. +Add ``LCMapStringEx`` to the :mod:`_winapi` module. + +.. + +.. bpo: 38704 +.. date: 2020-01-10-23-33-03 +.. nonce: 2Idtdn +.. section: Windows + +Prevent installation on unsupported Windows versions. + +.. + +.. date: 2022-10-05-15-26-58 +.. gh-issue: 97897 +.. nonce: Rf-C6u +.. section: macOS + +The macOS 13 SDK includes support for the ``mkfifoat`` and ``mknodat`` +system calls. Using the ``dir_fd`` option with either :func:`os.mkfifo` or +:func:`os.mknod` could result in a segfault if cpython is built with the +macOS 13 SDK but run on an earlier version of macOS. Prevent this by adding +runtime support for detection of these system calls ("weaklinking") as is +done for other newer syscalls on macOS. + +.. + +.. date: 2022-10-15-21-20-40 +.. gh-issue: 97527 +.. nonce: otAHJM +.. section: IDLE + +Fix a bug in the previous bugfix that caused IDLE to not start when run with +3.10.8, 3.12.0a1, and at least Microsoft Python 3.10.2288.0 installed +without the Lib/test package. 3.11.0 was never affected. + +.. + +.. date: 2022-08-04-20-07-51 +.. gh-issue: 65802 +.. nonce: xnThWe +.. section: IDLE + +Document handling of extensions in Save As dialogs. + +.. + +.. date: 2022-08-01-23-31-48 +.. gh-issue: 95191 +.. nonce: U7vryB +.. section: IDLE + +Include prompts when saving Shell (interactive input and output). + +.. + +.. date: 2022-07-31-22-15-14 +.. gh-issue: 95511 +.. nonce: WX6PmB +.. section: IDLE + +Fix the Shell context menu copy-with-prompts bug of copying an extra line +when one selects whole lines. + +.. + +.. date: 2022-07-30-15-10-39 +.. gh-issue: 95471 +.. nonce: z3scVG +.. section: IDLE + +In the Edit menu, move ``Select All`` and add a new separator. + +.. + +.. date: 2022-07-29-11-08-52 +.. gh-issue: 95411 +.. nonce: dazlqH +.. section: IDLE + +Enable using IDLE's module browser with .pyw files. + +.. + +.. date: 2022-07-28-18-56-57 +.. gh-issue: 89610 +.. nonce: hcosiM +.. section: IDLE + +Add .pyi as a recognized extension for IDLE on macOS. This allows opening +stub files by double clicking on them in the Finder. + +.. + +.. date: 2022-10-07-22-06-11 +.. gh-issue: 68686 +.. nonce: 6KNIQ4 +.. section: Tools/Demos + +Remove ptags and eptags scripts. + +.. + +.. date: 2022-09-30-18-35-11 +.. gh-issue: 97681 +.. nonce: -KO1Ba +.. section: Tools/Demos + +Remove the ``Tools/demo/`` directory which contained old demo scripts. A +copy can be found in the `old-demos project +<https://github.com/gvanrossum/old-demos>`_. Patch by Victor Stinner. + +.. + +.. date: 2022-09-30-14-30-12 +.. gh-issue: 97669 +.. nonce: gvbgcg +.. section: Tools/Demos + +Remove outdated example scripts of the ``Tools/scripts/`` directory. A copy +can be found in the `old-demos project +<https://github.com/gvanrossum/old-demos>`_. Patch by Victor Stinner. + +.. + +.. date: 2022-08-29-17-25-13 +.. gh-issue: 95853 +.. nonce: Ce17cT +.. section: Tools/Demos + +The ``wasm_build.py`` script now pre-builds Emscripten ports, checks for +broken EMSDK versions, and warns about pkg-config env vars. + +.. + +.. date: 2022-08-10-17-08-43 +.. gh-issue: 95853 +.. nonce: HCjC2m +.. section: Tools/Demos + +The new tool ``Tools/wasm/wasm_builder.py`` automates configure, compile, +and test steps for building CPython on WebAssembly platforms. + +.. + +.. date: 2022-08-05-23-25-59 +.. gh-issue: 95731 +.. nonce: N2KohU +.. section: Tools/Demos + +Fix handling of module docstrings in :file:`Tools/i18n/pygettext.py`. + +.. + +.. date: 2022-07-04-10-02-02 +.. gh-issue: 93939 +.. nonce: U6sW6H +.. section: Tools/Demos + +Add script ``Tools/scripts/check_modules.py`` to check and validate builtin +and shared extension modules. The script also handles ``Modules/Setup`` and +will eventually replace ``setup.py``. + +.. + +.. date: 2022-07-04-01-37-42 +.. gh-issue: 94538 +.. nonce: 1rgy1Y +.. section: Tools/Demos + +Fix Argument Clinic output to custom file destinations. Patch by Erlend E. +Aasland. + +.. + +.. date: 2022-06-29-22-47-11 +.. gh-issue: 94430 +.. nonce: hdov8L +.. section: Tools/Demos + +Allow parameters named ``module`` and ``self`` with custom C names in +Argument Clinic. Patch by Erlend E. Aasland + +.. + +.. date: 2022-06-19-14-56-33 +.. gh-issue: 86087 +.. nonce: R8MkRy +.. section: Tools/Demos + +The ``Tools/scripts/parseentities.py`` script used to parse HTML4 entities +has been removed. + +.. + +.. date: 2022-10-18-16-16-27 +.. gh-issue: 98393 +.. nonce: 55u4BF +.. section: C API + +The :c:func:`PyUnicode_FSDecoder` function no longer accepts bytes-like +paths, like :class:`bytearray` and :class:`memoryview` types: only the exact +:class:`bytes` type is accepted for bytes strings. Patch by Victor Stinner. + +.. + +.. date: 2022-10-05-10-43-32 +.. gh-issue: 91051 +.. nonce: ODDRsQ +.. section: C API + +Add :c:func:`PyType_Watch` and related APIs to allow callbacks on +:c:func:`PyType_Modified`. + +.. + +.. date: 2022-10-03-20-33-24 +.. gh-issue: 95756 +.. nonce: SSmXlG +.. section: C API + +Lazily create and cache ``co_`` attributes for better performance for code +getters. + +.. + +.. date: 2022-09-20-01-04-57 +.. gh-issue: 96512 +.. nonce: msZTjF +.. section: C API + +Configuration for the :ref:`integer string conversion length limitation +<int_max_str_digits>` now lives in the PyConfig C API struct. + +.. + +.. date: 2022-08-16-16-54-42 +.. gh-issue: 95589 +.. nonce: 6xE1ar +.. section: C API + +Extensions classes that set ``tp_dictoffset`` and ``tp_weaklistoffset`` lose +the support for multiple inheritance, but are now safe. Extension classes +should use :c:macro:`Py_TPFLAGS_MANAGED_DICT` and +:c:macro:`Py_TPFLAGS_MANAGED_WEAKREF` instead. + +.. + +.. date: 2022-08-08-14-36-31 +.. gh-issue: 95781 +.. nonce: W_G8YW +.. section: C API + +An unrecognized format character in :c:func:`PyUnicode_FromFormat` and +:c:func:`PyUnicode_FromFormatV` now sets a :exc:`SystemError`. In previous +versions it caused all the rest of the format string to be copied as-is to +the result string, and any extra arguments discarded. + +.. + +.. date: 2022-08-03-14-39-08 +.. gh-issue: 92678 +.. nonce: ozFTEx +.. section: C API + +Restore the 3.10 behavior for multiple inheritance of C extension classes +that store their dictionary at the end of the struct. + +.. + +.. date: 2022-08-03-13-01-57 +.. gh-issue: 92678 +.. nonce: DLwONN +.. section: C API + +Support C extensions using managed dictionaries by setting the +``Py_TPFLAGS_MANAGED_DICT`` flag. + +.. + +.. date: 2022-08-01-16-21-39 +.. gh-issue: 93274 +.. nonce: QoDHEu +.. section: C API + +API for implementing vectorcall (:c:macro:`Py_TPFLAGS_HAVE_VECTORCALL`, +:c:func:`PyVectorcall_NARGS` and :c:func:`PyVectorcall_Call`) was added to +the limited API and stable ABI. + +.. + +.. date: 2022-07-31-21-58-27 +.. gh-issue: 95504 +.. nonce: wy7B1F +.. section: C API + +Fix sign placement when specifying width or precision in +:c:func:`PyUnicode_FromFormat` and :c:func:`PyUnicode_FromFormatV`. Patch by +Philip Georgi. + +.. + +.. date: 2022-07-29-15-24-45 +.. gh-issue: 93012 +.. nonce: -DdGEy +.. section: C API + +The :c:macro:`Py_TPFLAGS_HAVE_VECTORCALL` flag is now removed from a class +when the class's :py:meth:`~object.__call__` method is reassigned. This +makes vectorcall safe to use with mutable types (i.e. heap types without the +:const:`immutable <Py_TPFLAGS_IMMUTABLETYPE>` flag). Mutable types that do +not override :c:member:`~PyTypeObject.tp_call` now inherit the +:c:macro:`Py_TPFLAGS_HAVE_VECTORCALL` flag. + +.. + +.. date: 2022-07-29-10-41-59 +.. gh-issue: 95388 +.. nonce: aiRSgr +.. section: C API + +Creating :c:macro:`immutable types <Py_TPFLAGS_IMMUTABLETYPE>` with mutable +bases is deprecated and is planned to be disabled in Python 3.14. + +.. + +.. date: 2022-07-25-15-54-27 +.. gh-issue: 92678 +.. nonce: ziZpxz +.. section: C API + +Adds unstable C-API functions ``_PyObject_VisitManagedDict`` and +``_PyObject_ClearManagedDict`` to allow C extensions to allow the VM to +manage their object's dictionaries. + +.. + +.. date: 2022-07-19-22-37-40 +.. gh-issue: 94936 +.. nonce: LGlmKv +.. section: C API + +Added :c:func:`PyCode_GetVarnames`, :c:func:`PyCode_GetCellvars` and +:c:func:`PyCode_GetFreevars` for accessing ``co_varnames``, ``co_cellvars`` +and ``co_freevars`` respectively via the C API. + +.. + +.. date: 2022-07-17-18-21-40 +.. gh-issue: 94930 +.. nonce: gPFGDL +.. section: C API + +Fix ``SystemError`` raised when :c:func:`PyArg_ParseTupleAndKeywords` is +used with ``#`` in ``(...)`` but without ``PY_SSIZE_T_CLEAN`` defined. + +.. + +.. date: 2022-07-12-17-39-32 +.. gh-issue: 94731 +.. nonce: 9CPJNU +.. section: C API + +Python again uses C-style casts for most casting operations when compiled +with C++. This may trigger compiler warnings, if they are enabled with e.g. +``-Wold-style-cast`` or ``-Wzero-as-null-pointer-constant`` options for +``g++``. + +.. + +.. date: 2022-06-17-13-41-38 +.. gh-issue: 93937 +.. nonce: uKVTEh +.. section: C API + +The following frame functions and type are now directly available with +``#include <Python.h>``, it's no longer needed to add ``#include +<frameobject.h>``: + +* :c:func:`PyFrame_Check` +* :c:func:`PyFrame_GetBack` +* :c:func:`PyFrame_GetBuiltins` +* :c:func:`PyFrame_GetGenerator` +* :c:func:`PyFrame_GetGlobals` +* :c:func:`PyFrame_GetLasti` +* :c:func:`PyFrame_GetLocals` +* :c:type:`PyFrame_Type` + +Patch by Victor Stinner. + +.. + +.. date: 2022-06-13-21-37-31 +.. gh-issue: 91321 +.. nonce: DgJFvS +.. section: C API + +Fix the compatibility of the Python C API with C++ older than C++11. Patch +by Victor Stinner. + +.. + +.. date: 2022-06-10-23-41-48 +.. gh-issue: 91731 +.. nonce: fhYUQG +.. section: C API + +Avoid defining the ``static_assert`` when compiling with C++ 11, where this +is a keyword and redefining it can lead to undefined behavior. Patch by +Pablo Galindo + +.. + +.. date: 2022-06-10-16-50-27 +.. gh-issue: 89546 +.. nonce: mX1f10 +.. section: C API + +:c:func:`PyType_FromMetaclass` (and other ``PyType_From*`` functions) now +check that offsets and the base class's +:c:member:`~PyTypeObject.tp_basicsize` fit in the new class's +``tp_basicsize``. + +.. + +.. date: 2022-06-06-16-04-14 +.. gh-issue: 93503 +.. nonce: MHJTu8 +.. section: C API + +Add two new public functions to the public C-API, +:c:func:`PyEval_SetProfileAllThreads` and +:c:func:`PyEval_SetTraceAllThreads`, that allow to set tracing and profiling +functions in all running threads in addition to the calling one. Also, two +analogous functions to the :mod:`threading` module +(:func:`threading.setprofile_all_threads` and +:func:`threading.settrace_all_threads`) that allow to do the same from +Python. Patch by Pablo Galindo + +.. + +.. date: 2022-06-04-13-15-41 +.. gh-issue: 93442 +.. nonce: 4M4NDb +.. section: C API + +Add C++ overloads for _Py_CAST_impl() to handle 0/NULL. This will allow C++ +extensions that pass 0 or NULL to macros using _Py_CAST() to continue to +compile. + +.. + +.. date: 2022-06-03-14-54-41 +.. gh-issue: 93466 +.. nonce: DDtH0X +.. section: C API + +Slot IDs in PyType_Spec may not be repeated. The documentation was updated +to mention this. For some cases of repeated slots, PyType_FromSpec and +related functions will now raise an exception. + +.. + +.. date: 2022-05-23-15-22-18 +.. gh-issue: 92898 +.. nonce: Qjc9d3 +.. section: C API + +Fix C++ compiler warnings when casting function arguments to ``PyObject*``. +Patch by Serge Guelton. + +.. + +.. date: 2022-05-23-13-33-18 +.. gh-issue: 93103 +.. nonce: ooD3Eb +.. section: C API + +Deprecate global configuration variables, like +:c:var:`Py_IgnoreEnvironmentFlag`, in the documentation: the +:c:func:`Py_InitializeFromConfig` API should be instead. Patch by Victor +Stinner. + +.. + +.. date: 2022-05-23-12-31-04 +.. gh-issue: 77782 +.. nonce: ugC8dn +.. section: C API + +Deprecate global configuration variable like +:c:var:`Py_IgnoreEnvironmentFlag`: the :c:func:`Py_InitializeFromConfig` API +should be instead. Patch by Victor Stinner. + +.. + +.. date: 2022-05-19-18-05-51 +.. gh-issue: 92913 +.. nonce: Ass1Hv +.. section: C API + +Ensures changes to :c:member:`PyConfig.module_search_paths` are ignored +unless :c:member:`PyConfig.module_search_paths_set` is set + +.. + +.. date: 2022-05-13-18-17-48 +.. gh-issue: 92781 +.. nonce: TVDr3- +.. section: C API + +Avoid mixing declarations and code in the C API to fix the compiler warning: +"ISO C90 forbids mixed declarations and code" +[-Werror=declaration-after-statement]. Patch by Victor Stinner. + +.. + +.. date: 2022-05-11-02-33-10 +.. gh-issue: 92651 +.. nonce: FIXLf0 +.. section: C API + +Remove the ``token.h`` header file. There was never any public tokenizer C +API. The ``token.h`` header file was only designed to be used by Python +internals. Patch by Victor Stinner. + +.. + +.. date: 2022-05-10-12-35-42 +.. gh-issue: 92536 +.. nonce: cAoRCZ +.. section: C API + +Remove legacy Unicode APIs based on ``Py_UNICODE*``. + +.. + +.. date: 2022-05-09-23-16-38 +.. gh-issue: 85858 +.. nonce: VIcNDL +.. section: C API + +Remove the ``PyUnicode_InternImmortal()`` function and the +``SSTATE_INTERNED_IMMORTAL`` macro. Patch by Victor Stinner. + +.. + +.. date: 2022-05-03-19-35-37 +.. gh-issue: 92193 +.. nonce: 61VoFL +.. section: C API + +Add new function :c:func:`PyFunction_SetVectorcall` to the C API which sets +the vectorcall field of a given :c:type:`PyFunctionObject`. + +Warning: extensions using this API must preserve the behavior of the +unaltered function! + +.. + +.. date: 2022-04-13-16-10-55 +.. gh-issue: 59121 +.. nonce: -B7mKp +.. section: C API + +Fixed an assert that prevented ``PyRun_InteractiveOne`` from providing +tracebacks when parsing from the provided FD. + +.. + +.. bpo: 45383 +.. date: 2021-10-05-21-59-43 +.. nonce: TVClgf +.. section: C API + +The :c:func:`PyType_FromSpec` API will now find and use a metaclass based on +the provided bases. An error will be raised if there is a metaclass +conflict. diff --git a/Misc/NEWS.d/3.12.0a2.rst b/Misc/NEWS.d/3.12.0a2.rst new file mode 100644 index 00000000..1a04ed47 --- /dev/null +++ b/Misc/NEWS.d/3.12.0a2.rst @@ -0,0 +1,1102 @@ +.. date: 2022-11-04-09-29-36 +.. gh-issue: 98433 +.. nonce: l76c5G +.. release date: 2022-11-14 +.. section: Security + +The IDNA codec decoder used on DNS hostnames by :mod:`socket` or +:mod:`asyncio` related name resolution functions no longer involves a +quadratic algorithm. This prevents a potential CPU denial of service if an +out-of-spec excessive length hostname involving bidirectional characters +were decoded. Some protocols such as :mod:`urllib` http :samp:`3{xx}` redirects +potentially allow for an attacker to supply such a name. + +Individual labels within an IDNA encoded DNS name will now raise an error +early during IDNA decoding if they are longer than 1024 unicode characters +given that each decoded DNS label must be 63 or fewer characters and the +entire decoded DNS name is limited to 255. Only an application presenting a +hostname or label consisting primarily of :rfc:`3454` section 3.1 "Nothing" +characters to be removed would run into of this new limit. See also +:rfc:`5894` section 6 and :rfc:`3491`. + +.. + +.. date: 2022-10-26-21-04-23 +.. gh-issue: 98739 +.. nonce: keBWcY +.. section: Security + +Update bundled libexpat to 2.5.0 + +.. + +.. date: 2022-11-11-14-48-17 +.. gh-issue: 81057 +.. nonce: ik4iOv +.. section: Core and Builtins + +The docs clearly say that ``PyImport_Inittab``, +:c:func:`PyImport_AppendInittab`, and :c:func:`PyImport_ExtendInittab` +should not be used after :c:func:`Py_Initialize` has been called. We now +enforce this for the two functions. Additionally, the runtime now uses an +internal copy of ``PyImport_Inittab``, to guard against modification. + +.. + +.. date: 2022-11-09-12-07-24 +.. gh-issue: 99298 +.. nonce: NeArAJ +.. section: Core and Builtins + +Fix an issue that could potentially cause incorrect error handling for some +bytecode instructions. + +.. + +.. date: 2022-11-08-17-47-10 +.. gh-issue: 99254 +.. nonce: RSvyFt +.. section: Core and Builtins + +The compiler now removes all unused constants from code objects (except the +first one, which may be a docstring). + +.. + +.. date: 2022-11-08-16-35-25 +.. gh-issue: 99205 +.. nonce: 2YOoFT +.. section: Core and Builtins + +Fix an issue that prevented :c:type:`PyThreadState` and +:c:type:`PyInterpreterState` memory from being freed properly. + +.. + +.. date: 2022-11-07-14-16-59 +.. gh-issue: 81057 +.. nonce: 3uKlLQ +.. section: Core and Builtins + +The 18 global C variables holding the state of the allocators have been +moved to ``_PyRuntimeState``. This is a strictly internal change with no +change in behavior. + +.. + +.. date: 2022-11-07-10-29-41 +.. gh-issue: 99181 +.. nonce: bfG4bI +.. section: Core and Builtins + +Fix failure in :keyword:`except* <except_star>` with unhashable exceptions. + +.. + +.. date: 2022-11-07-08-17-12 +.. gh-issue: 99204 +.. nonce: Mf4hMD +.. section: Core and Builtins + +Fix calculation of :data:`sys._base_executable` when inside a POSIX virtual +environment using copies of the python binary when the base installation +does not provide the executable name used by the venv. Calculation will fall +back to alternative names ("python<MAJOR>", "python<MAJOR>.<MINOR>"). + +.. + +.. date: 2022-11-06-22-59-02 +.. gh-issue: 96055 +.. nonce: TmQuJn +.. section: Core and Builtins + +Update :mod:`faulthandler` to emit an error message with the proper +unexpected signal number. Patch by Donghee Na. + +.. + +.. date: 2022-11-06-13-25-01 +.. gh-issue: 99153 +.. nonce: uE3CVL +.. section: Core and Builtins + +Fix location of :exc:`SyntaxError` for a :keyword:`try` block with both +:keyword:`except` and :keyword:`except* <except_star>`. + +.. + +.. date: 2022-11-06-00-47-11 +.. gh-issue: 98686 +.. nonce: DBDy6U +.. section: Core and Builtins + +Merge the adaptive opcode logic into each instruction's unquickened variant, +and merge the logic in ``EXTENDED_ARG_QUICK`` into :opcode:`EXTENDED_ARG`. +With these changes, the quickening that happens at code object creation is +now only responsible for initializing warmup counters and inserting +superinstructions. + +.. + +.. date: 2022-11-06-00-17-58 +.. gh-issue: 99103 +.. nonce: bFA9BX +.. section: Core and Builtins + +Fix the error reporting positions of specialized traceback anchors when the +source line contains Unicode characters. + +.. + +.. date: 2022-11-05-18-36-27 +.. gh-issue: 99139 +.. nonce: cI9vV1 +.. section: Core and Builtins + +Improve the error suggestion for :exc:`NameError` exceptions for instances. +Now if a :exc:`NameError` is raised in a method and the instance has an +attribute that's exactly equal to the name in the exception, the suggestion +will include ``self.<NAME>`` instead of the closest match in the method +scope. Patch by Pablo Galindo + +.. + +.. date: 2022-11-03-13-11-17 +.. gh-issue: 98401 +.. nonce: CBS4nv +.. section: Core and Builtins + +Octal escapes with value larger than ``0o377`` (ex: ``"\477"``), deprecated +in Python 3.11, now produce a :exc:`SyntaxWarning`, instead of +:exc:`DeprecationWarning`. In a future Python version they will be +eventually a :exc:`SyntaxError`. Patch by Victor Stinner. + +.. + +.. date: 2022-11-02-17-02-06 +.. gh-issue: 98401 +.. nonce: y-dbVW +.. section: Core and Builtins + +A backslash-character pair that is not a valid escape sequence now generates +a :exc:`SyntaxWarning`, instead of :exc:`DeprecationWarning`. For example, +``re.compile("\d+\.\d+")`` now emits a :exc:`SyntaxWarning` (``"\d"`` is an +invalid escape sequence), use raw strings for regular expression: +``re.compile(r"\d+\.\d+")``. In a future Python version, :exc:`SyntaxError` +will eventually be raised, instead of :exc:`SyntaxWarning`. Patch by Victor +Stinner. + +.. + +.. date: 2022-11-02-14-42-35 +.. gh-issue: 96793 +.. nonce: q0Oi74 +.. section: Core and Builtins + +Handle StopIteration and StopAsyncIteration raised in generator or +coroutines in the bytecode, rather than in wrapping C code. + +.. + +.. date: 2022-10-31-22-55-34 +.. gh-issue: 98931 +.. nonce: AoWZ-4 +.. section: Core and Builtins + +Improve the :exc:`SyntaxError` error message when the user types ``import x +from y`` instead of ``from y import x``. Patch by Pablo Galindo + +.. + +.. date: 2022-10-31-21-01-35 +.. gh-issue: 98852 +.. nonce: MYaRN6 +.. section: Core and Builtins + +Fix subscription of type aliases containing bare generic types or types like +:class:`~typing.TypeVar`: for example ``tuple[A, T][int]`` and +``tuple[TypeVar, T][int]``, where ``A`` is a generic type, and ``T`` is a +type variable. + +.. + +.. date: 2022-10-31-18-03-10 +.. gh-issue: 98925 +.. nonce: zpdjVd +.. section: Core and Builtins + +Lower the recursion depth for marshal on WASI to support (in-development) +wasmtime 2.0. + +.. + +.. date: 2022-10-28-14-52-55 +.. gh-issue: 98783 +.. nonce: iG0kMs +.. section: Core and Builtins + +Fix multiple crashes in debug mode when ``str`` subclasses are used instead +of ``str`` itself. + +.. + +.. date: 2022-10-28-13-59-51 +.. gh-issue: 98811 +.. nonce: XQypJa +.. section: Core and Builtins + +Use complete source locations to simplify detection of ``__future__`` +imports which are not at the beginning of the file. Also corrects the offset +in the exception raised in one case, which was off by one and impeded +highlighting. + +.. + +.. date: 2022-10-28-09-42-51 +.. gh-issue: 96793 +.. nonce: ucBfWO +.. section: Core and Builtins + +Add specialization of :opcode:`FOR_ITER` for generators. Saves multiple +layers of dispatch and checking to get from the :opcode:`FOR_ITER` +instruction in the caller to the :opcode:`RESUME` in the generator. + +.. + +.. date: 2022-10-27-16-42-16 +.. gh-issue: 98762 +.. nonce: Eb2kzg +.. section: Core and Builtins + +Fix source locations of :keyword:`match` sub-patterns. + +.. + +.. date: 2022-10-24-10-30-30 +.. gh-issue: 98586 +.. nonce: Tha5Iy +.. section: Core and Builtins + +Added the methods :c:func:`PyObject_Vectorcall` and +:c:func:`PyObject_VectorcallMethod` to the :ref:`Limited API <stable>` along +with the auxiliary macro constant :c:macro:`PY_VECTORCALL_ARGUMENTS_OFFSET`. + +The availability of these functions enables more efficient :PEP:`590` vector +calls from binary extension modules that avoid argument boxing/unboxing +overheads. + +.. + +.. date: 2022-10-21-11-28-53 +.. gh-issue: 99257 +.. nonce: nmcuf- +.. section: Core and Builtins + +Fix an issue where member descriptors (such as those for +:attr:`~object.__slots__`) could behave incorrectly or crash instead of +raising a :exc:`TypeError` when accessed via an instance of an invalid type. + +.. + +.. date: 2022-10-19-23-54-43 +.. gh-issue: 93143 +.. nonce: 1wCYub +.. section: Core and Builtins + +Rather than changing :attr:`~types.CodeType.co_code`, the interpreter will +now display a :exc:`RuntimeWarning` and assign :const:`None` to any fast +locals that are left unbound after jumps or :keyword:`del` statements +executed while tracing. + +.. + +.. date: 2022-10-19-15-59-08 +.. gh-issue: 96421 +.. nonce: e22y3r +.. section: Core and Builtins + +When calling into Python code from C code, through +:c:func:`PyEval_EvalFrameEx` or a related C-API function, a shim frame in +inserted into the call stack. This occurs in the +``_PyEval_EvalFrameDefault()`` function. The extra frame should be invisible +to all Python and most C extensions, but out-of-process profilers and +debuggers need to be aware of it. These shim frames can be detected by +checking ``frame->owner == FRAME_OWNED_BY_CSTACK``. + +Extensions implementing their own interpreters using PEP 523 need to be +aware of this shim frame and the changes to the semantics of +:opcode:`RETURN_VALUE`, :opcode:`YIELD_VALUE`, and +:opcode:`RETURN_GENERATOR`, which now clear the frame. + +.. + +.. date: 2022-10-19-01-01-08 +.. gh-issue: 98415 +.. nonce: ZS2eWh +.. section: Core and Builtins + +Fix detection of MAC addresses for :mod:`uuid` on certain OSs. Patch by +Chaim Sanders + +.. + +.. date: 2022-10-16-13-26-46 +.. gh-issue: 98686 +.. nonce: D9Gu_Q +.. section: Core and Builtins + +Quicken all code objects, and specialize adaptive bytecode instructions more +aggressively. + +.. + +.. date: 2022-10-15-23-15-14 +.. gh-issue: 92119 +.. nonce: PMSwwG +.. section: Core and Builtins + +Print exception class name instead of its string representation when raising +errors from :mod:`ctypes` calls. + +.. + +.. date: 2022-10-15-22-25-20 +.. gh-issue: 91058 +.. nonce: Uo2kW- +.. section: Core and Builtins + +:exc:`ImportError` raised from failed ``from <module> import <name>`` now +include suggestions for the value of ``<name>`` based on the available names +in ``<module>``. Patch by Pablo Galindo + +.. + +.. date: 2022-09-13-14-07-06 +.. gh-issue: 96793 +.. nonce: 7DLRSm +.. section: Core and Builtins + +The :opcode:`FOR_ITER` now leaves the iterator on the stack on termination +of the loop. This is to assist specialization of loops for generators. + +.. + +.. date: 2022-09-09-16-32-58 +.. gh-issue: 90716 +.. nonce: z4yuYq +.. section: Core and Builtins + +Add _pylong.py module. It includes asymptotically faster algorithms that +can be used for operations on integers with many digits. It is used by +longobject.c to speed up some operations. + +.. + +.. date: 2022-07-30-14-10-27 +.. gh-issue: 95389 +.. nonce: nSGEkG +.. section: Core and Builtins + +Expose :const:`~socket.ETH_P_ALL` and some of the :ref:`ETHERTYPE_* constants +<socket-ethernet-types>` in :mod:`socket`. Patch by Noam Cohen. + +.. + +.. date: 2022-06-10-16-37-44 +.. gh-issue: 93696 +.. nonce: 65BI2R +.. section: Core and Builtins + +Allow :mod:`pdb` to locate source for frozen modules in the standard +library. + +.. + +.. date: 2022-11-12-15-45-51 +.. gh-issue: 99418 +.. nonce: FxfAXS +.. section: Library + +Fix bug in :func:`urllib.parse.urlparse` that causes URL schemes that begin +with a digit, a plus sign, or a minus sign to be parsed incorrectly. + +.. + +.. date: 2022-11-11-18-23-41 +.. gh-issue: 94597 +.. nonce: m6vMDK +.. section: Library + +Deprecate :class:`asyncio.AbstractChildWatcher` to be removed in Python +3.14. Patch by Kumar Aditya. + +.. + +.. date: 2022-11-10-11-51-39 +.. gh-issue: 99305 +.. nonce: 6LzQc3 +.. section: Library + +Improve performance of :func:`secrets.token_hex`. + +.. + +.. date: 2022-11-09-20-48-42 +.. gh-issue: 74044 +.. nonce: zBj26K +.. section: Library + +Fixed bug where :func:`inspect.signature` reported incorrect arguments for +decorated methods. + +.. + +.. date: 2022-11-09-12-16-35 +.. gh-issue: 99275 +.. nonce: klOqoL +.. section: Library + +Fix ``SystemError`` in :mod:`ctypes` when exception was not set during +``__initsubclass__``. + +.. + +.. date: 2022-11-09-08-40-52 +.. gh-issue: 99277 +.. nonce: J1P44O +.. section: Library + +Remove older version of ``_SSLProtocolTransport.get_write_buffer_limits`` in +:mod:`!asyncio.sslproto` + +.. + +.. date: 2022-11-08-11-15-37 +.. gh-issue: 99248 +.. nonce: 1vt8xI +.. section: Library + +fix negative numbers failing in verify() + +.. + +.. date: 2022-11-06-12-44-51 +.. gh-issue: 99155 +.. nonce: vLZOzi +.. section: Library + +Fix :class:`statistics.NormalDist` pickle with ``0`` and ``1`` protocols. + +.. + +.. date: 2022-11-05-23-16-15 +.. gh-issue: 93464 +.. nonce: ucd4vP +.. section: Library + +``enum.auto()`` is now correctly activated when combined with other +assignment values. E.g. ``ONE = auto(), 'some text'`` will now evaluate as +``(1, 'some text')``. + +.. + +.. date: 2022-11-05-17-16-40 +.. gh-issue: 99134 +.. nonce: Msgspf +.. section: Library + +Update the bundled copy of pip to version 22.3.1. + +.. + +.. date: 2022-11-03-15-28-07 +.. gh-issue: 92584 +.. nonce: m5ctkm +.. section: Library + +Remove the ``distutils`` package. It was deprecated in Python 3.10 by +:pep:`632` "Deprecate distutils module". For projects still using +``distutils`` and cannot be updated to something else, the ``setuptools`` +project can be installed: it still provides ``distutils``. Patch by Victor +Stinner. + +.. + +.. date: 2022-11-02-18-27-13 +.. gh-issue: 98999 +.. nonce: Ai2KDh +.. section: Library + +Now :mod:`_pyio` is consistent with :mod:`_io` in raising ``ValueError`` +when executing methods over closed buffers. + +.. + +.. date: 2022-11-02-05-54-02 +.. gh-issue: 83004 +.. nonce: 0v8iyw +.. section: Library + +Clean up refleak on failed module initialisation in :mod:`_zoneinfo` + +.. + +.. date: 2022-11-02-05-53-25 +.. gh-issue: 83004 +.. nonce: qc_KHr +.. section: Library + +Clean up refleaks on failed module initialisation in :mod:`_pickle` + +.. + +.. date: 2022-11-02-05-52-36 +.. gh-issue: 83004 +.. nonce: LBl79O +.. section: Library + +Clean up refleak on failed module initialisation in :mod:`_io`. + +.. + +.. date: 2022-10-31-12-34-03 +.. gh-issue: 98897 +.. nonce: rgNn4x +.. section: Library + +Fix memory leak in :func:`math.dist` when both points don't have the same +dimension. Patch by Kumar Aditya. + +.. + +.. date: 2022-10-30-22-42-48 +.. gh-issue: 98878 +.. nonce: fgrykp +.. section: Library + +Use the frame bound builtins when offering a name suggestion in +:mod:`traceback` to prevent crashing when ``__builtins__`` is not a dict. + +.. + +.. date: 2022-10-30-15-26-33 +.. gh-issue: 98139 +.. nonce: qtm-9T +.. section: Library + +In :mod:`importlib._bootstrap`, enhance namespace package repr to `<module +'x' (namespace) from ['path']>`. + +.. + +.. date: 2022-10-29-09-42-20 +.. gh-issue: 90352 +.. nonce: t8QEPt +.. section: Library + +Fix ``_SelectorDatagramTransport`` to inherit from +:class:`~asyncio.DatagramTransport` in :mod:`asyncio`. Patch by Kumar +Aditya. + +.. + +.. date: 2022-10-29-03-40-18 +.. gh-issue: 98793 +.. nonce: WSPB4A +.. section: Library + +Fix argument typechecks in :func:`!_overlapped.WSAConnect` and +:func:`!_overlapped.Overlapped.WSASendTo` functions. + +.. + +.. date: 2022-10-28-23-44-17 +.. gh-issue: 98744 +.. nonce: sGHDWm +.. section: Library + +Prevent crashing in :mod:`traceback` when retrieving the byte-offset for +some source files that contain certain unicode characters. + +.. + +.. date: 2022-10-27-12-56-38 +.. gh-issue: 98740 +.. nonce: ZoqqGM +.. section: Library + +Fix internal error in the :mod:`re` module which in very rare circumstances +prevented compilation of a regular expression containing a :ref:`conditional +expression <re-conditional-expression>` without the "else" branch. + +.. + +.. date: 2022-10-26-07-51-55 +.. gh-issue: 98703 +.. nonce: 0hW773 +.. section: Library + +Fix :meth:`asyncio.StreamWriter.drain` to call ``protocol.connection_lost`` +callback only once on Windows. + +.. + +.. date: 2022-10-25-20-17-34 +.. gh-issue: 98624 +.. nonce: YQUPFy +.. section: Library + +Add a mutex to unittest.mock.NonCallableMock to protect concurrent access to +mock attributes. + +.. + +.. date: 2022-10-25-07-00-31 +.. gh-issue: 98658 +.. nonce: nGABW9 +.. section: Library + +The :class:`array.array` class now supports subscripting, making it a +:term:`generic type`. + +.. + +.. date: 2022-10-15-10-43-45 +.. gh-issue: 98284 +.. nonce: SaVHTd +.. section: Library + +Improved :class:`TypeError` message for undefined abstract methods of a +:class:`abc.ABC` instance. The names of the missing methods are surrounded +by single-quotes to highlight them. + +.. + +.. date: 2022-10-10-07-07-31 +.. gh-issue: 96151 +.. nonce: K9fwoq +.. section: Library + +Allow ``BUILTINS`` to be a valid field name for frozen dataclasses. + +.. + +.. date: 2022-10-08-19-39-27 +.. gh-issue: 98086 +.. nonce: y---WC +.. section: Library + +Make sure ``patch.dict()`` can be applied on async functions. + +.. + +.. date: 2022-09-05-17-08-56 +.. gh-issue: 72719 +.. nonce: jUpzF3 +.. section: Library + +Remove modules :mod:`asyncore` and :mod:`asynchat`, which were deprecated by +:pep:`594`. + +.. + +.. date: 2022-08-23-03-13-18 +.. gh-issue: 96192 +.. nonce: TJywOF +.. section: Library + +Fix handling of ``bytes`` :term:`path-like objects <path-like object>` in +:func:`os.ismount()`. + +.. + +.. date: 2022-06-23-15-36-49 +.. gh-issue: 94172 +.. nonce: DzQk0s +.. section: Library + +:mod:`ftplib`: Remove the ``FTP_TLS.ssl_version`` class attribute: use the +*context* parameter instead. Patch by Victor Stinner + +.. + +.. date: 2022-06-23-15-31-49 +.. gh-issue: 94172 +.. nonce: AXE2IZ +.. section: Library + +Remove the *keyfile* and *certfile* parameters from the +:mod:`ftplib`, :mod:`imaplib`, :mod:`poplib` and :mod:`smtplib` modules, +and the *key_file*, *cert_file* and *check_hostname* parameters from the +:mod:`http.client` module, +all deprecated since Python 3.6. Use the *context* +parameter (*ssl_context* in :mod:`imaplib`) instead. Patch by Victor +Stinner. + +.. + +.. date: 2022-06-14-22-46-05 +.. gh-issue: 83638 +.. nonce: 73xfGK +.. section: Library + +Add the :attr:`~sqlite3.Connection.autocommit` attribute to +:class:`sqlite3.Connection` and the *autocommit* parameter to +:func:`sqlite3.connect` to control :pep:`249`-compliant :ref:`transaction +handling <sqlite3-transaction-control-autocommit>`. Patch by Erlend E. +Aasland. + +.. + +.. date: 2022-05-08-08-47-32 +.. gh-issue: 92452 +.. nonce: 3pNHe6 +.. section: Library + +Fixed a race condition that could cause :func:`sysconfig.get_config_var` to +incorrectly return :const:`None` in multi-threaded programs. + +.. + +.. date: 2022-05-03-11-32-29 +.. gh-issue: 91803 +.. nonce: pI4Juv +.. section: Library + +Fix an error when using a method of objects mocked with +:func:`unittest.mock.create_autospec` after it was sealed with +:func:`unittest.mock.seal` function. + +.. + +.. bpo: 38523 +.. date: 2020-10-23-22-20-52 +.. nonce: CrkxLh +.. section: Library + +:func:`shutil.copytree` now applies the *ignore_dangling_symlinks* argument +recursively. + +.. + +.. bpo: 40358 +.. date: 2020-04-30-02-15-08 +.. nonce: A4ygqe +.. section: Library + +Add walk_up argument in :meth:`pathlib.PurePath.relative_to`. + +.. + +.. bpo: 36267 +.. date: 2019-09-03-15-45-19 +.. nonce: z42Ex7 +.. section: Library + +Fix IndexError in :class:`argparse.ArgumentParser` when a ``store_true`` +action is given an explicit argument. + +.. + +.. date: 2022-10-29-02-33-46 +.. gh-issue: 98832 +.. nonce: DudEIH +.. section: Documentation + +Changes wording of docstring for :func:`pathlib.Path.iterdir`. + +.. + +.. date: 2022-10-06-13-00-28 +.. gh-issue: 97966 +.. nonce: fz7kFg +.. section: Documentation + +Update uname docs to clarify the special nature of the platform attribute +and to indicate when it became late-bound. + +.. + +.. date: 2022-10-31-14-47-49 +.. gh-issue: 98903 +.. nonce: 7KinCV +.. section: Tests + +The Python test suite now fails wit exit code 4 if no tests ran. It should +help detecting typos in test names and test methods. + +.. + +.. date: 2022-10-26-15-19-20 +.. gh-issue: 98713 +.. nonce: Lnu32R +.. section: Tests + +Fix a bug in the :mod:`typing` tests where a test relying on +CPython-specific implementation details was not decorated with +``@cpython_only`` and was not skipped on other implementations. + +.. + +.. date: 2022-10-15-07-46-48 +.. gh-issue: 87390 +.. nonce: asR-Zo +.. section: Tests + +Add tests for star-unpacking with PEP 646, and some other miscellaneous PEP +646 tests. + +.. + +.. date: 2022-10-12-14-57-06 +.. gh-issue: 96853 +.. nonce: ANe-bw +.. section: Tests + +Added explicit coverage of ``Py_Initialize`` (and hence ``Py_InitializeEx``) +back to the embedding tests (all other embedding tests migrated to +``Py_InitializeFromConfig`` in Python 3.11) + +.. + +.. bpo: 34272 +.. date: 2018-07-29-15-59-51 +.. nonce: lVX2uR +.. section: Tests + +Some C API tests were moved into the new Lib/test/test_capi/ directory. + +.. + +.. date: 2022-11-04-02-58-10 +.. gh-issue: 99086 +.. nonce: DV_4Br +.. section: Build + +Fix ``-Wimplicit-int`` compiler warning in :program:`configure` check for +``PTHREAD_SCOPE_SYSTEM``. + +.. + +.. date: 2022-11-02-19-25-07 +.. gh-issue: 99016 +.. nonce: R05NkD +.. section: Build + +Fix build with ``PYTHON_FOR_REGEN=python3.8``. + +.. + +.. date: 2022-11-02-18-45-35 +.. gh-issue: 97731 +.. nonce: zKpTlj +.. section: Build + +Specify the full path to the source location for ``make docclean`` (needed +for cross-builds). + +.. + +.. date: 2022-11-02-10-56-40 +.. gh-issue: 98949 +.. nonce: 3SRD8C +.. section: Build + +Drop unused build dependency on ``readelf``. + +.. + +.. date: 2022-11-01-21-45-58 +.. gh-issue: 98989 +.. nonce: tMxbdB +.. section: Build + +Use ``python3.11``, if available, for regeneration and freezing. + +.. + +.. date: 2022-10-28-22-24-26 +.. gh-issue: 98831 +.. nonce: IXRCRX +.. section: Build + +Add new tooling, in ``Tools/cases_generator``, to generate the interpreter +switch statement from a list of opcode definitions. This only affects +adding, modifying or removing instruction definitions. The instruction +definitions now live in ``Python/bytecodes.c``, in the form of a `custom DSL +(under development) +<https://github.com/faster-cpython/ideas/blob/main/3.12/interpreter_definition.md>`__. +The tooling reads this file and writes ``Python/generated_cases.c.h``, which +is then included by ``Python/ceval.c`` to provide most of the cases of the +main interpreter switch. + +.. + +.. date: 2022-10-28-18-53-40 +.. gh-issue: 98817 +.. nonce: oPqrtt +.. section: Build + +Remove PCbuild/lib.pyproj: it's not used for anything, is only a minor +convenience for Visual Studio users (who probably mostly don't even know +about it), and it takes a lot of maintenance effort to keep updated. + +.. + +.. date: 2022-10-27-19-47-31 +.. gh-issue: 98776 +.. nonce: lt_UOG +.. section: Build + +Fix ``make regen-test-levenshtein`` for out-of-tree builds. + +.. + +.. date: 2022-10-26-12-37-52 +.. gh-issue: 98707 +.. nonce: eVXGEx +.. section: Build + +Don't use vendored ``libmpdec`` headers if :option:`--with-system-libmpdec` +is passed to :program:`configure`. Don't use vendored ``libexpat`` headers +if :option:`--with-system-expat` is passed to :program:`configure`. + +.. + +.. date: 2022-11-01-11-07-33 +.. gh-issue: 98689 +.. nonce: 0f6e_N +.. section: Windows + +Update Windows builds to zlib v1.2.13. v1.2.12 has CVE-2022-37434, but the +vulnerable ``inflateGetHeader`` API is not used by Python. + +.. + +.. date: 2022-11-01-00-37-13 +.. gh-issue: 98790 +.. nonce: fpaPAx +.. section: Windows + +Assumes that a missing ``DLLs`` directory means that standard extension +modules are in the executable's directory. + +.. + +.. date: 2022-10-27-20-30-16 +.. gh-issue: 98745 +.. nonce: v06p4r +.. section: Windows + +Update :file:`py.exe` launcher to install 3.11 by default and 3.12 on +request. + +.. + +.. date: 2022-10-26-17-43-09 +.. gh-issue: 98692 +.. nonce: bOopfZ +.. section: Windows + +Fix the :ref:`launcher` ignoring unrecognized shebang lines instead of +treating them as local paths + +.. + +.. date: 2022-10-25-10-34-17 +.. gh-issue: 94328 +.. nonce: 19NhdU +.. section: Windows + +Update Windows installer to use SQLite 3.39.4. + +.. + +.. date: 2022-10-25-10-32-23 +.. gh-issue: 94328 +.. nonce: W3YNC_ +.. section: macOS + +Update macOS installer to SQLite 3.39.4. + +.. + +.. date: 2022-11-04-16-13-35 +.. gh-issue: 98724 +.. nonce: p0urWO +.. section: C API + +The :c:macro:`Py_CLEAR`, :c:macro:`Py_SETREF` and :c:macro:`Py_XSETREF` +macros now only evaluate their argument once. If the argument has side +effects, these side effects are no longer duplicated. Patch by Victor +Stinner. + +.. + +.. date: 2022-11-03-17-46-41 +.. gh-issue: 98978 +.. nonce: KJjBvv +.. section: C API + +Fix use-after-free in ``Py_SetPythonHome(NULL)``, +``Py_SetProgramName(NULL)`` and ``_Py_SetProgramFullPath(NULL)`` function +calls. Issue reported by Benedikt Reinartz. Patch by Victor Stinner. + +.. + +.. date: 2022-10-25-17-50-43 +.. gh-issue: 98410 +.. nonce: NSXYfm +.. section: C API + +Add ``getbufferproc`` and ``releasebufferproc`` to the stable API. + +.. + +.. date: 2022-10-24-12-09-17 +.. gh-issue: 98610 +.. nonce: PLX2Np +.. section: C API + +Some configurable capabilities of sub-interpreters have changed. They always +allow subprocesses (:mod:`subprocess`) now, whereas before subprocesses +could be optionally disallowed for a sub-interpreter. Instead +:func:`os.exec` can now be disallowed. Disallowing daemon threads is now +supported. Disallowing all threads is still allowed, but is never done by +default. Note that the optional restrictions are only available through +``_Py_NewInterpreterFromConfig()``, which isn't a public API. They do not +affect the main interpreter, nor :c:func:`Py_NewInterpreter`. + +.. + +.. date: 2022-10-24-11-26-55 +.. gh-issue: 98608 +.. nonce: _Q2lNV +.. section: C API + +A ``_PyInterpreterConfig`` has been added and ``_Py_NewInterpreter()`` has +been renamed to ``_Py_NewInterpreterFromConfig()``. The +"isolated_subinterpreters" argument is now a granular config that captures +the previous behavior. Note that this is all "private" API. + +.. + +.. date: 2022-10-16-15-00-25 +.. gh-issue: 96853 +.. nonce: V0wiXP +.. section: C API + +``Py_InitializeEx`` now correctly calls ``PyConfig_Clear`` after +initializing the interpreter (the omission didn't cause a memory leak only +because none of the dynamically allocated config fields are populated by the +wrapper function) + +.. + +.. date: 2022-08-05-15-26-12 +.. gh-issue: 91248 +.. nonce: ujirJJ +.. section: C API + +Add :c:func:`PyFrame_GetVar` and :c:func:`PyFrame_GetVarString` functions to +get a frame variable by its name. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/3.12.0a3.rst b/Misc/NEWS.d/3.12.0a3.rst new file mode 100644 index 00000000..ce128fd5 --- /dev/null +++ b/Misc/NEWS.d/3.12.0a3.rst @@ -0,0 +1,836 @@ +.. date: 2022-12-05-01-39-10 +.. gh-issue: 100001 +.. nonce: uD05Fc +.. release date: 2022-12-06 +.. section: Security + +``python -m http.server`` no longer allows terminal control characters sent +within a garbage request to be printed to the stderr server log. + +This is done by changing the :mod:`http.server` +:class:`BaseHTTPRequestHandler` ``.log_message`` method to replace control +characters with a :samp:`\\x{HH}` hex escape before printing. + +.. + +.. date: 2022-11-11-12-50-28 +.. gh-issue: 87604 +.. nonce: OtwH5L +.. section: Security + +Avoid publishing list of active per-interpreter audit hooks via the +:mod:`gc` module + +.. + +.. date: 2022-11-30-11-09-40 +.. gh-issue: 99891 +.. nonce: 9VomwB +.. section: Core and Builtins + +Fix a bug in the tokenizer that could cause infinite recursion when showing +syntax warnings that happen in the first line of the source. Patch by Pablo +Galindo + +.. + +.. date: 2022-11-27-13-50-13 +.. gh-issue: 91054 +.. nonce: oox_kW +.. section: Core and Builtins + +Add :c:func:`PyCode_AddWatcher` and :c:func:`PyCode_ClearWatcher` APIs to +register callbacks to receive notification on creation and destruction of +code objects. + +.. + +.. date: 2022-11-26-04-00-41 +.. gh-issue: 99729 +.. nonce: A3ovwQ +.. section: Core and Builtins + +Fix an issue that could cause frames to be visible to Python code as they +are being torn down, possibly leading to memory corruption or hard crashes +of the interpreter. + +.. + +.. date: 2022-11-23-18-16-18 +.. gh-issue: 99708 +.. nonce: 7MuaiR +.. section: Core and Builtins + +Fix bug where compiler crashes on an if expression with an empty body block. + +.. + +.. date: 2022-11-21-11-27-14 +.. gh-issue: 99578 +.. nonce: DcKoBJ +.. section: Core and Builtins + +Fix a reference bug in :func:`_imp.create_builtin()` after the creation of +the first sub-interpreter for modules ``builtins`` and ``sys``. Patch by +Victor Stinner. + +.. + +.. date: 2022-11-19-22-27-52 +.. gh-issue: 99581 +.. nonce: yKYPbf +.. section: Core and Builtins + +Fixed a bug that was causing a buffer overflow if the tokenizer copies a +line missing the newline caracter from a file that is as long as the +available tokenizer buffer. Patch by Pablo galindo + +.. + +.. date: 2022-11-18-11-24-25 +.. gh-issue: 99553 +.. nonce: F64h-n +.. section: Core and Builtins + +Fix bug where an :exc:`ExceptionGroup` subclass can wrap a +:exc:`BaseException`. + +.. + +.. date: 2022-11-16-21-35-30 +.. gh-issue: 99547 +.. nonce: p_c_bp +.. section: Core and Builtins + +Add a function to os.path to check if a path is a junction: isjunction. Add +similar functionality to pathlib.Path as is_junction. + +.. + +.. date: 2022-11-12-01-39-57 +.. gh-issue: 99370 +.. nonce: _cu32j +.. section: Core and Builtins + +Fix zip path for venv created from a non-installed python on POSIX +platforms. + +.. + +.. date: 2022-11-11-14-04-01 +.. gh-issue: 99377 +.. nonce: -CJvWn +.. section: Core and Builtins + +Add audit events for thread creation and clear operations. + +.. + +.. date: 2022-11-10-17-09-16 +.. gh-issue: 98686 +.. nonce: bmAKwr +.. section: Core and Builtins + +Remove the ``BINARY_OP_GENERIC`` and ``COMPARE_OP_GENERIC`` +"specializations". + +.. + +.. date: 2022-11-10-16-53-40 +.. gh-issue: 99298 +.. nonce: HqRJES +.. section: Core and Builtins + +Remove the remaining error paths for attribute specializations, and refuse +to specialize attribute accesses on types that haven't had +:c:func:`PyType_Ready` called on them yet. + +.. + +.. date: 2022-11-05-22-26-35 +.. gh-issue: 99127 +.. nonce: Btk7ih +.. section: Core and Builtins + +Allow some features of :mod:`syslog` to the main interpreter only. Patch by +Donghee Na. + +.. + +.. date: 2022-10-05-11-44-52 +.. gh-issue: 91053 +.. nonce: f5Bo3p +.. section: Core and Builtins + +Optimizing interpreters and JIT compilers may need to invalidate internal +metadata when functions are modified. This change adds the ability to +provide a callback that will be invoked each time a function is created, +modified, or destroyed. + +.. + +.. date: 2022-09-17-17-08-01 +.. gh-issue: 90994 +.. nonce: f0H2Yd +.. section: Core and Builtins + +Improve error messages when there's a syntax error with call arguments. The +following three cases are covered: - No value is assigned to a named +argument, eg ``foo(a=)``. - A value is assigned to a star argument, eg +``foo(*args=[0])``. - A value is assigned to a double-star keyword argument, +eg ``foo(**kwarg={'a': 0})``. + +.. + +.. bpo: 45026 +.. date: 2021-08-29-15-55-19 +.. nonce: z7nTA3 +.. section: Core and Builtins + +Optimize the :class:`range` object iterator. It is now smaller, faster +iteration of ranges containing large numbers. Smaller pickles, faster +unpickling. + +.. + +.. bpo: 31718 +.. date: 2020-02-23-23-48-15 +.. nonce: sXko5e +.. section: Core and Builtins + +Raise :exc:`ValueError` instead of :exc:`SystemError` when methods of +uninitialized :class:`io.IncrementalNewlineDecoder` objects are called. +Patch by Oren Milman. + +.. + +.. bpo: 38031 +.. date: 2019-09-04-19-09-49 +.. nonce: Yq4L72 +.. section: Core and Builtins + +Fix a possible assertion failure in :class:`io.FileIO` when the opener +returns an invalid file descriptor. + +.. + +.. date: 2022-12-05-13-40-15 +.. gh-issue: 100001 +.. nonce: 78ReYp +.. section: Library + +Also \ escape \s in the http.server BaseHTTPRequestHandler.log_message so +that it is technically possible to parse the line and reconstruct what the +original data was. Without this a \xHH is ambiguious as to if it is a hex +replacement we put in or the characters r"\x" came through in the original +request line. + +.. + +.. date: 2022-12-03-05-58-48 +.. gh-issue: 99957 +.. nonce: jLYYgN +.. section: Library + +Add ``frozen_default`` parameter to :func:`typing.dataclass_transform`. + +.. + +.. date: 2022-11-22-19-31-26 +.. gh-issue: 79033 +.. nonce: MW6kHq +.. section: Library + +Fix :func:`asyncio.Server.wait_closed` to actually do what the docs promise +-- wait for all existing connections to complete, after closing the server. + +.. + +.. date: 2022-11-21-17-56-18 +.. gh-issue: 51524 +.. nonce: nTykx8 +.. section: Library + +Fix bug when calling trace.CoverageResults with valid infile. + +.. + +.. date: 2022-11-21-13-49-03 +.. gh-issue: 99645 +.. nonce: 9w1QKq +.. section: Library + +Fix a bug in handling class cleanups in :class:`unittest.TestCase`. Now +``addClassCleanup()`` uses separate lists for different ``TestCase`` +subclasses, and ``doClassCleanups()`` only cleans up the particular class. + +.. + +.. date: 2022-11-21-10-45-54 +.. gh-issue: 99508 +.. nonce: QqVbby +.. section: Library + +Fix ``TypeError`` in ``Lib/importlib/_bootstrap_external.py`` while calling +``_imp.source_hash()``. + +.. + +.. date: 2022-11-17-10-56-47 +.. gh-issue: 66285 +.. nonce: KvjlaB +.. section: Library + +Fix :mod:`asyncio` to not share event loop and signal wakeupfd in forked +processes. Patch by Kumar Aditya. + +.. + +.. date: 2022-11-15-10-55-24 +.. gh-issue: 97001 +.. nonce: KeQuVF +.. section: Library + +Release the GIL when calling termios APIs to avoid blocking threads. + +.. + +.. date: 2022-11-15-04-08-25 +.. gh-issue: 92647 +.. nonce: cZcjnJ +.. section: Library + +Use final status of an enum to determine lookup or creation branch of +functional API. + +.. + +.. date: 2022-11-14-08-21-56 +.. gh-issue: 99388 +.. nonce: UWSlwp +.. section: Library + +Add *loop_factory* parameter to :func:`asyncio.run` to allow specifying a +custom event loop factory. Patch by Kumar Aditya. + +.. + +.. date: 2022-11-13-02-06-56 +.. gh-issue: 99341 +.. nonce: 8-OlwB +.. section: Library + +Fix :func:`ast.increment_lineno` to also cover :class:`ast.TypeIgnore` when +changing line numbers. + +.. + +.. date: 2022-11-12-12-15-30 +.. gh-issue: 99382 +.. nonce: dKg_rW +.. section: Library + +Check the number of arguments in substitution in user generics containing a +:class:`~typing.TypeVarTuple` and one or more :class:`~typing.TypeVar`. + +.. + +.. date: 2022-11-12-12-10-23 +.. gh-issue: 99379 +.. nonce: bcGhxF +.. section: Library + +Fix substitution of :class:`~typing.ParamSpec` followed by +:class:`~typing.TypeVarTuple` in generic aliases. + +.. + +.. date: 2022-11-12-12-08-34 +.. gh-issue: 99344 +.. nonce: 7M_u8G +.. section: Library + +Fix substitution of :class:`~typing.TypeVarTuple` and +:class:`~typing.ParamSpec` together in user generics. + +.. + +.. date: 2022-11-09-12-36-12 +.. gh-issue: 99284 +.. nonce: 9p4J2l +.. section: Library + +Remove ``_use_broken_old_ctypes_structure_semantics_`` old untested and +undocumented hack from :mod:`ctypes`. + +.. + +.. date: 2022-11-09-03-34-29 +.. gh-issue: 99201 +.. nonce: lDJ7xI +.. section: Library + +Fix :exc:`IndexError` when initializing the config variables on Windows if +``HAVE_DYNAMIC_LOADING`` is not set. + +.. + +.. date: 2022-11-08-15-54-43 +.. gh-issue: 99240 +.. nonce: MhYwcz +.. section: Library + +Fix double-free bug in Argument Clinic ``str_converter`` by extracting +memory clean up to a new ``post_parsing`` section. + +.. + +.. date: 2022-11-08-11-18-51 +.. gh-issue: 64490 +.. nonce: VcBgrN +.. section: Library + +Fix refcount error when arguments are packed to tuple in Argument Clinic. + +.. + +.. date: 2022-11-02-23-47-07 +.. gh-issue: 99029 +.. nonce: 7uCiIB +.. section: Library + +:meth:`pathlib.PurePath.relative_to()` now treats naked Windows drive paths +as relative. This brings its behaviour in line with other parts of pathlib. + +.. + +.. date: 2022-10-24-11-01-05 +.. gh-issue: 98253 +.. nonce: HVd5v4 +.. section: Library + +The implementation of the typing module is now more resilient to reference +leaks in binary extension modules. + +Previously, a reference leak in a typed C API-based extension module could +leak internals of the typing module, which could in turn introduce leaks in +essentially any other package with typed function signatures. Although the +typing package is not the original source of the problem, such non-local +dependences exacerbate debugging of large-scale projects, and the +implementation was therefore changed to reduce harm by providing better +isolation. + +.. + +.. date: 2022-10-19-18-31-53 +.. gh-issue: 98458 +.. nonce: vwyq7O +.. section: Library + +Fix infinite loop in unittest when a self-referencing chained exception is +raised + +.. + +.. date: 2022-10-19-13-37-23 +.. gh-issue: 93453 +.. nonce: wTB_sH +.. section: Library + +:func:`asyncio.get_event_loop` and many other :mod:`asyncio` functions like +:func:`asyncio.ensure_future`, :func:`asyncio.shield` or +:func:`asyncio.gather`, and also the +:meth:`~asyncio.BaseDefaultEventLoopPolicy.get_event_loop` method of +:class:`asyncio.BaseDefaultEventLoopPolicy` now raise a :exc:`RuntimeError` +if called when there is no running event loop and the current event loop was +not set. Previously they implicitly created and set a new current event +loop. :exc:`DeprecationWarning` is no longer emitted if there is no running +event loop but the current event loop was set. + +.. + +.. date: 2022-10-16-18-52-00 +.. gh-issue: 97966 +.. nonce: humlhz +.. section: Library + +On ``uname_result``, restored expectation that ``_fields`` and ``_asdict`` +would include all six properties including ``processor``. + +.. + +.. date: 2022-10-13-22-13-54 +.. gh-issue: 98248 +.. nonce: lwyygy +.. section: Library + +Provide informative error messages in :func:`struct.pack` when its integral +arguments are not in range. + +.. + +.. date: 2022-10-08-19-20-33 +.. gh-issue: 98108 +.. nonce: WUObqM +.. section: Library + +``zipfile.Path`` is now pickleable if its initialization parameters were +pickleable (e.g. for file system paths). + +.. + +.. date: 2022-10-08-15-41-00 +.. gh-issue: 98098 +.. nonce: DugpWi +.. section: Library + +Created packages from zipfile and test_zipfile modules, separating +``zipfile.Path`` functionality. + +.. + +.. date: 2022-10-02-12-38-22 +.. gh-issue: 82836 +.. nonce: OvYLmC +.. section: Library + +Fix :attr:`~ipaddress.IPv4Address.is_private` properties in the +:mod:`ipaddress` module. Previously non-private networks (0.0.0.0/0) would +return True from this method; now they correctly return False. + +.. + +.. date: 2022-09-14-21-56-15 +.. gh-issue: 96828 +.. nonce: ZoOY5G +.. section: Library + +Add an :const:`~ssl.OP_ENABLE_KTLS` option for enabling the use of the kernel +TLS (kTLS). Patch by Illia Volochii. + +.. + +.. date: 2022-08-06-12-18-07 +.. gh-issue: 88863 +.. nonce: NnqsuJ +.. section: Library + +To avoid apparent memory leaks when :func:`asyncio.open_connection` raises, +break reference cycles generated by local exception and future instances +(which has exception instance as its member var). Patch by Dong Uk, Kang. + +.. + +.. date: 2022-04-23-03-46-37 +.. gh-issue: 91078 +.. nonce: 87-hkp +.. section: Library + +:meth:`TarFile.next` now returns ``None`` when called on an empty tarfile. + +.. + +.. bpo: 47220 +.. date: 2022-04-04-22-54-11 +.. nonce: L9jYu4 +.. section: Library + +Document the optional *callback* parameter of :class:`WeakMethod`. Patch by +Géry Ogam. + +.. + +.. bpo: 44817 +.. date: 2021-08-03-05-31-00 +.. nonce: wOW_Qn +.. section: Library + +Ignore WinError 53 (ERROR_BAD_NETPATH), 65 (ERROR_NETWORK_ACCESS_DENIED) and +161 (ERROR_BAD_PATHNAME) when using ntpath.realpath(). + +.. + +.. bpo: 41260 +.. date: 2020-08-02-23-46-22 +.. nonce: Q2BNzY +.. section: Library + +Rename the *fmt* parameter of the pure Python implementation of +:meth:`datetime.date.strftime` to *format*. + +.. + +.. bpo: 15999 +.. date: 2019-08-30-10-48-53 +.. nonce: QqsRRi +.. section: Library + +All built-in functions now accept arguments of any type instead of just +``bool`` and ``int`` for boolean parameters. + +.. + +.. date: 2022-12-02-17-08-08 +.. gh-issue: 99931 +.. nonce: wC46hE +.. section: Documentation + +Use `sphinxext-opengraph <https://sphinxext-opengraph.readthedocs.io/>`__ to +generate `OpenGraph metadata <https://ogp.me/>`__. + +.. + +.. date: 2022-11-26-21-43-05 +.. gh-issue: 89682 +.. nonce: DhKoTM +.. section: Documentation + +Reworded docstring of the default ``__contains__`` to clarify that it +returns a :class:`bool`. + +.. + +.. date: 2022-11-26-15-51-23 +.. gh-issue: 88330 +.. nonce: B_wFq8 +.. section: Documentation + +Improved the description of what a resource is in importlib.resources docs. + +.. + +.. date: 2022-11-16-12-52-23 +.. gh-issue: 92892 +.. nonce: TS-P0j +.. section: Documentation + +Document that calling variadic functions with ctypes requires special care +on macOS/arm64 (and possibly other platforms). + +.. + +.. bpo: 41825 +.. date: 2020-09-22-12-32-16 +.. nonce: npcaCb +.. section: Documentation + +Restructured the documentation for the :func:`os.wait* <os.wait>` family of +functions, and improved the docs for :func:`os.waitid` with more explanation +of the possible argument constants. + +.. + +.. date: 2022-12-05-16-12-56 +.. gh-issue: 99892 +.. nonce: sz_eW8 +.. section: Tests + +Skip test_normalization() of test_unicodedata if it fails to download +NormalizationTest.txt file from pythontest.net. Patch by Victor Stinner. + +.. + +.. date: 2022-12-01-18-55-18 +.. gh-issue: 99934 +.. nonce: Ox3Fqf +.. section: Tests + +Correct test_marsh on (32 bit) x86: test_deterministic sets was failing. + +.. + +.. date: 2022-11-23-18-32-16 +.. gh-issue: 99741 +.. nonce: q4R7NH +.. section: Tests + +We've implemented multi-phase init (PEP 489/630/687) for the internal (for +testing) _xxsubinterpreters module. + +.. + +.. date: 2022-11-21-19-21-30 +.. gh-issue: 99659 +.. nonce: 4gP0nm +.. section: Tests + +Optional big memory tests in ``test_sqlite3`` now catch the correct +:exc:`sqlite.DataError` exception type in case of too large strings and/or +blobs passed. + +.. + +.. date: 2022-11-19-13-34-28 +.. gh-issue: 99593 +.. nonce: 8ZfCkj +.. section: Tests + +Cover the Unicode C API with tests. + +.. + +.. date: 2022-08-22-15-49-14 +.. gh-issue: 96002 +.. nonce: 4UE9UE +.. section: Tests + +Add functional test for Argument Clinic. + +.. + +.. date: 2022-11-24-02-58-10 +.. gh-issue: 99086 +.. nonce: DV_4Br +.. section: Build + +Fix ``-Wimplicit-int``, ``-Wstrict-prototypes``, and +``-Wimplicit-function-declaration`` compiler warnings in +:program:`configure` checks. + +.. + +.. date: 2022-11-15-08-40-22 +.. gh-issue: 99337 +.. nonce: 5LoQDE +.. section: Build + +Fix a compilation issue with GCC 12 on macOS. + +.. + +.. date: 2022-11-09-14-42-48 +.. gh-issue: 99289 +.. nonce: X7wFE1 +.. section: Build + +Add a ``COMPILEALL_OPTS`` variable in Makefile to override :mod:`compileall` +options (default: ``-j0``) in ``make install``. Also merged the +``compileall`` commands into a single command building .pyc files for the +all optimization levels (0, 1, 2) at once. Patch by Victor Stinner. + +.. + +.. date: 2022-11-03-08-10-49 +.. gh-issue: 98872 +.. nonce: gdsR8X +.. section: Build + +Fix a possible fd leak in ``Programs/_freeze_module.c`` introduced in Python +3.11. + +.. + +.. date: 2022-10-16-12-49-24 +.. gh-issue: 88226 +.. nonce: BsnQ4k +.. section: Build + +Always define ``TARGET_*`` labels in ``Python/ceval.c``, even if +``USE_COMPUTED_GOTOS`` is disabled. This allows breakpoints to be set at +those labels in (for instance) ``gdb``. + +.. + +.. date: 2022-11-23-17-17-16 +.. gh-issue: 99345 +.. nonce: jOa3-f +.. section: Windows + +Use faster initialization functions to detect install location for Windows +Store package + +.. + +.. date: 2022-11-21-19-50-18 +.. gh-issue: 98629 +.. nonce: tMmB_B +.. section: Windows + +Fix initialization of :data:`sys.version` and ``sys._git`` on Windows + +.. + +.. date: 2022-11-16-19-03-21 +.. gh-issue: 99442 +.. nonce: 6Dgk3Q +.. section: Windows + +Fix handling in :ref:`launcher` when ``argv[0]`` does not include a file +extension. + +.. + +.. bpo: 40882 +.. date: 2020-06-06-15-10-37 +.. nonce: UvNbdj +.. section: Windows + +Fix a memory leak in :class:`multiprocessing.shared_memory.SharedMemory` on +Windows. + +.. + +.. date: 2022-11-25-09-23-20 +.. gh-issue: 87235 +.. nonce: SifjCD +.. section: macOS + +On macOS ``python3 /dev/fd/9 9</path/to/script.py`` failed for any script +longer than a couple of bytes. + +.. + +.. date: 2022-11-01-10-32-23 +.. gh-issue: 98940 +.. nonce: W3YzC_ +.. section: macOS + +Fix ``Mac/Extras.install.py`` file filter bug. + +.. + +.. date: 2022-08-11-09-58-15 +.. gh-issue: 64490 +.. nonce: PjwhM4 +.. section: Tools/Demos + +Argument Clinic varargs bugfixes + +* Fix out-of-bounds error in :c:func:`!_PyArg_UnpackKeywordsWithVararg`. +* Fix incorrect check which allowed more than one varargs in clinic.py. +* Fix miscalculation of ``noptargs`` in generated code. +* Do not generate ``noptargs`` when there is a vararg argument and no optional argument. + +.. + +.. date: 2022-12-05-17-30-13 +.. gh-issue: 98680 +.. nonce: FiMCxZ +.. section: C API + +``PyBUF_*`` constants were marked as part of Limited API of Python 3.11+. +These were available in 3.11.0 with :c:macro:`Py_LIMITED_API` defined for +3.11, and are necessary to use the buffer API. + +.. + +.. date: 2022-11-20-09-52-50 +.. gh-issue: 99612 +.. nonce: eBHksg +.. section: C API + +Fix :c:func:`PyUnicode_DecodeUTF8Stateful` for ASCII-only data: +``*consumed`` was not set. + +.. + +.. date: 2022-11-02-16-51-24 +.. gh-issue: 47146 +.. nonce: dsYDtI +.. section: C API + +The ``structmember.h`` header is deprecated. Its non-deprecated contents are +now available just by including ``Python.h``, with a ``Py_`` prefix added if +it was missing. (Deprecated contents are :c:macro:`T_OBJECT`, +:c:macro:`T_NONE`, and no-op flags.) Patch by Petr Viktorin, based on +earlier work by Alexander Belopolsky and Matthias Braun. diff --git a/Misc/NEWS.d/3.12.0a4.rst b/Misc/NEWS.d/3.12.0a4.rst new file mode 100644 index 00000000..75246f3f --- /dev/null +++ b/Misc/NEWS.d/3.12.0a4.rst @@ -0,0 +1,1132 @@ +.. date: 2023-01-06-02-02-11 +.. gh-issue: 100776 +.. nonce: pP8xux +.. release date: 2023-01-10 +.. section: Core and Builtins + +Fix misleading default value in :func:`input`'s ``__text_signature__``. + +.. + +.. date: 2023-01-05-17-54-29 +.. gh-issue: 99005 +.. nonce: cmGwxv +.. section: Core and Builtins + +Remove :opcode:`UNARY_POSITIVE`, :opcode:`ASYNC_GEN_WRAP` and +:opcode:`LIST_TO_TUPLE`, replacing them with intrinsics. + +.. + +.. date: 2023-01-05-13-54-00 +.. gh-issue: 99005 +.. nonce: D7H6j4 +.. section: Core and Builtins + +Add new :opcode:`CALL_INTRINSIC_1` instruction. Remove +:opcode:`IMPORT_STAR`, :opcode:`PRINT_EXPR` and +:opcode:`STOPITERATION_ERROR`, replacing them with the +:opcode:`CALL_INTRINSIC_1` instruction. + +.. + +.. date: 2023-01-04-16-40-55 +.. gh-issue: 100288 +.. nonce: hRSRaT +.. section: Core and Builtins + +Remove the LOAD_ATTR_METHOD_WITH_DICT specialized instruction. Stats show it +is not useful. + +.. + +.. date: 2023-01-03-16-50-42 +.. gh-issue: 100720 +.. nonce: UhE7P- +.. section: Core and Builtins + +Added ``_PyFrame_NumSlotsForCodeObject``, which returns the number of slots +needed in a frame for a given code object. + +.. + +.. date: 2023-01-03-16-38-18 +.. gh-issue: 100719 +.. nonce: 2C--ko +.. section: Core and Builtins + +Removed the co_nplaincellvars field from the code object, as it is +redundant. + +.. + +.. date: 2023-01-01-15-59-48 +.. gh-issue: 100637 +.. nonce: M2n6Kg +.. section: Core and Builtins + +Fix :func:`int.__sizeof__` calculation to include the 1 element ob_digit +array for 0 and False. + +.. + +.. date: 2022-12-31-23-32-09 +.. gh-issue: 100649 +.. nonce: C0fY4S +.. section: Core and Builtins + +Update the native_thread_id field of PyThreadState after fork. + +.. + +.. date: 2022-12-29-04-39-38 +.. gh-issue: 100126 +.. nonce: pfFJd- +.. section: Core and Builtins + +Fix an issue where "incomplete" frames could be briefly visible to C code +while other frames are being torn down, possibly resulting in corruption or +hard crashes of the interpreter while running finalizers. + +.. + +.. date: 2022-12-28-15-02-53 +.. gh-issue: 87447 +.. nonce: 7-aekA +.. section: Core and Builtins + +Fix :exc:`SyntaxError` on comprehension rebind checking with names that are +not actually redefined. + +Now reassigning ``b`` in ``[(b := 1) for a, b.prop in some_iter]`` is +allowed. Reassigning ``a`` is still disallowed as per :pep:`572`. + +.. + +.. date: 2022-12-22-21-56-08 +.. gh-issue: 100268 +.. nonce: xw_phB +.. section: Core and Builtins + +Add :meth:`int.is_integer` to improve duck type compatibility between +:class:`int` and :class:`float`. + +.. + +.. date: 2022-12-21-22-48-41 +.. gh-issue: 100425 +.. nonce: U64yLu +.. section: Core and Builtins + +Improve the accuracy of ``sum()`` with compensated summation. + +.. + +.. date: 2022-12-20-16-14-19 +.. gh-issue: 100374 +.. nonce: YRrVHT +.. section: Core and Builtins + +Fix incorrect result and delay in :func:`socket.getfqdn`. Patch by Dominic +Socular. + +.. + +.. date: 2022-12-20-09-56-56 +.. gh-issue: 100357 +.. nonce: hPyTwY +.. section: Core and Builtins + +Convert ``vars``, ``dir``, ``next``, ``getattr``, and ``iter`` to argument +clinic. + +.. + +.. date: 2022-12-17-19-44-57 +.. gh-issue: 100117 +.. nonce: yRWQ1y +.. section: Core and Builtins + +Improve the output of ``co_lines`` by emitting only one entry for each line +range. + +.. + +.. date: 2022-12-15-00-50-25 +.. gh-issue: 90043 +.. nonce: gyoKdx +.. section: Core and Builtins + +Handle NaNs when specializing :opcode:`COMPARE_OP` for :class:`float` +values. + +.. + +.. date: 2022-12-13-16-05-18 +.. gh-issue: 100222 +.. nonce: OVVvYe +.. section: Core and Builtins + +Redefine the ``_Py_CODEUNIT`` typedef as a union to describe its layout to +the C compiler, avoiding type punning and improving clarity. + +.. + +.. date: 2022-12-12-11-27-54 +.. gh-issue: 99955 +.. nonce: Ix5Rrg +.. section: Core and Builtins + +Internal compiler functions (in compile.c) now consistently return -1 on +error and 0 on success. + +.. + +.. date: 2022-12-12-05-30-12 +.. gh-issue: 100188 +.. nonce: sGCSMR +.. section: Core and Builtins + +The ``BINARY_SUBSCR_LIST_INT`` and ``BINARY_SUBSCR_TUPLE_INT`` instructions +are no longer used for negative integers because those instructions always +miss when encountering negative integers. + +.. + +.. date: 2022-12-12-01-05-16 +.. gh-issue: 99110 +.. nonce: 1JqtIg +.. section: Core and Builtins + +Initialize frame->previous in frameobject.c to fix a segmentation fault when +accessing frames created by :c:func:`PyFrame_New`. + +.. + +.. date: 2022-12-12-00-59-11 +.. gh-issue: 94155 +.. nonce: LWE9y_ +.. section: Core and Builtins + +Improved the hashing algorithm for code objects, mitigating some hash +collisions. + +.. + +.. date: 2022-12-10-20-00-13 +.. gh-issue: 99540 +.. nonce: ZZZHeP +.. section: Core and Builtins + +``None`` now hashes to a constant value. This is not a requirements change. + +.. + +.. date: 2022-12-09-14-27-36 +.. gh-issue: 100143 +.. nonce: 5g9rb4 +.. section: Core and Builtins + +When built with ``--enable-pystats``, stats collection is now off by +default. To enable it early at startup, pass the ``-Xpystats`` flag. Stats +are now always dumped, even if switched off. + +.. + +.. date: 2022-12-09-13-18-42 +.. gh-issue: 100146 +.. nonce: xLVKg0 +.. section: Core and Builtins + +Improve ``BUILD_LIST`` opcode so that it works similarly to the +``BUILD_TUPLE`` opcode, by stealing references from the stack rather than +repeatedly using stack operations to set list elements. Implementation +details are in a new private API :c:func:`_PyList_FromArraySteal`. + +.. + +.. date: 2022-12-08-12-26-34 +.. gh-issue: 100110 +.. nonce: ertac- +.. section: Core and Builtins + +Specialize ``FOR_ITER`` for tuples. + +.. + +.. date: 2022-12-06-22-24-01 +.. gh-issue: 100050 +.. nonce: lcrPqQ +.. section: Core and Builtins + +Honor existing errors obtained when searching for mismatching parentheses in +the tokenizer. Patch by Pablo Galindo + +.. + +.. date: 2022-12-04-00-38-33 +.. gh-issue: 92216 +.. nonce: CJXuWB +.. section: Core and Builtins + +Improve the performance of :func:`hasattr` for type objects with a missing +attribute. + +.. + +.. date: 2022-11-19-01-11-06 +.. gh-issue: 99582 +.. nonce: wvOBVy +.. section: Core and Builtins + +Freeze :mod:`zipimport` module into ``_bootstrap_python``. + +.. + +.. date: 2022-11-16-05-57-24 +.. gh-issue: 99554 +.. nonce: A_Ywd2 +.. section: Core and Builtins + +Pack debugging location tables more efficiently during bytecode compilation. + +.. + +.. date: 2022-10-21-16-10-39 +.. gh-issue: 98522 +.. nonce: s_SixG +.. section: Core and Builtins + +Add an internal version number to code objects, to give better versioning of +inner functions and comprehensions, and thus better specialization of those +functions. This change is invisible to both Python and C extensions. + +.. + +.. date: 2022-07-06-18-44-00 +.. gh-issue: 94603 +.. nonce: Q_03xV +.. section: Core and Builtins + +Improve performance of ``list.pop`` for small lists. + +.. + +.. date: 2022-06-17-08-00-34 +.. gh-issue: 89051 +.. nonce: yP4Na0 +.. section: Core and Builtins + +Add :const:`ssl.OP_LEGACY_SERVER_CONNECT` + +.. + +.. bpo: 32782 +.. date: 2018-02-06-23-21-13 +.. nonce: EJVSfR +.. section: Core and Builtins + +``ctypes`` arrays of length 0 now report a correct itemsize when a +``memoryview`` is constructed from them, rather than always giving a value +of 0. + +.. + +.. date: 2023-01-08-12-10-17 +.. gh-issue: 100833 +.. nonce: f6cT7E +.. section: Library + +Speed up :func:`math.fsum` by removing defensive ``volatile`` qualifiers. + +.. + +.. date: 2023-01-07-15-13-47 +.. gh-issue: 100805 +.. nonce: 05rBz9 +.. section: Library + +Modify :func:`random.choice` implementation to once again work with NumPy +arrays. + +.. + +.. date: 2023-01-06-22-36-27 +.. gh-issue: 100813 +.. nonce: mHRdQn +.. section: Library + +Add :const:`socket.IP_PKTINFO` constant. + +.. + +.. date: 2023-01-06-14-05-15 +.. gh-issue: 100792 +.. nonce: CEOJth +.. section: Library + +Make :meth:`email.message.Message.__contains__` twice as fast. + +.. + +.. date: 2023-01-05-23-04-15 +.. gh-issue: 91851 +.. nonce: AuCzU5 +.. section: Library + +Microoptimizations for :meth:`fractions.Fraction.__round__`, +:meth:`fractions.Fraction.__ceil__` and +:meth:`fractions.Fraction.__floor__`. + +.. + +.. date: 2023-01-04-22-10-31 +.. gh-issue: 90104 +.. nonce: yZk5EX +.. section: Library + +Avoid RecursionError on ``repr`` if a dataclass field definition has a +cyclic reference. + +.. + +.. date: 2023-01-04-12-58-59 +.. gh-issue: 100689 +.. nonce: Ce0ITG +.. section: Library + +Fix crash in :mod:`pyexpat` by statically allocating ``PyExpat_CAPI`` +capsule. + +.. + +.. date: 2023-01-04-09-53-38 +.. gh-issue: 100740 +.. nonce: -j5UjI +.. section: Library + +Fix ``unittest.mock.Mock`` not respecting the spec for attribute names +prefixed with ``assert``. + +.. + +.. date: 2023-01-03-11-06-28 +.. gh-issue: 91219 +.. nonce: s5IFCw +.. section: Library + +Change ``SimpleHTTPRequestHandler`` to support subclassing to provide a +different set of index file names instead of using ``__init__`` parameters. + +.. + +.. date: 2023-01-02-16-59-49 +.. gh-issue: 100690 +.. nonce: 2EgWPS +.. section: Library + +``Mock`` objects which are not unsafe will now raise an ``AttributeError`` +when accessing an attribute that matches the name of an assertion but +without the prefix ``assert_``, e.g. accessing ``called_once`` instead of +``assert_called_once``. This is in addition to this already happening for +accessing attributes with prefixes ``assert``, ``assret``, ``asert``, +``aseert``, and ``assrt``. + +.. + +.. date: 2023-01-01-23-57-00 +.. gh-issue: 89727 +.. nonce: ojedHN +.. section: Library + +Simplify and optimize :func:`os.walk` by using :func:`isinstance` checks to +check the top of the stack. + +.. + +.. date: 2023-01-01-21-54-46 +.. gh-issue: 100485 +.. nonce: geNrHS +.. section: Library + +Add math.sumprod() to compute the sum of products. + +.. + +.. date: 2022-12-30-07-49-08 +.. gh-issue: 86508 +.. nonce: nGZDzC +.. section: Library + +Fix :func:`asyncio.open_connection` to skip binding to local addresses of +different family. Patch by Kumar Aditya. + +.. + +.. date: 2022-12-29-11-45-22 +.. gh-issue: 97930 +.. nonce: hrtmJe +.. section: Library + +``importlib.resources.files`` now accepts a module as an anchor instead of +only accepting packages. If a module is passed, resources are resolved +adjacent to that module (in the same package or at the package root). The +parameter was renamed from ``package`` to ``anchor`` with a compatibility +shim for those passing by keyword. Additionally, the new ``anchor`` +parameter is now optional and will default to the caller's module. + +.. + +.. date: 2022-12-28-17-38-39 +.. gh-issue: 100585 +.. nonce: BiiTlG +.. section: Library + +Fixed a bug where importlib.resources.as_file was leaving file pointers open + +.. + +.. date: 2022-12-28-00-28-43 +.. gh-issue: 100562 +.. nonce: Hic0Z0 +.. section: Library + +Improve performance of :meth:`pathlib.Path.absolute` by nearly 2x. This +comes at the cost of a performance regression in :meth:`pathlib.Path.cwd`, +which is generally used less frequently in user code. + +.. + +.. date: 2022-12-24-16-39-53 +.. gh-issue: 100519 +.. nonce: G_dZLP +.. section: Library + +Small simplification of :func:`http.cookiejar.eff_request_host` that +improves readability and better matches the RFC wording. + +.. + +.. date: 2022-12-24-08-42-05 +.. gh-issue: 100287 +.. nonce: n0oEuG +.. section: Library + +Fix the interaction of :func:`unittest.mock.seal` with +:class:`unittest.mock.AsyncMock`. + +.. + +.. date: 2022-12-24-04-13-54 +.. gh-issue: 100488 +.. nonce: Ut8HbE +.. section: Library + +Add :meth:`Fraction.is_integer` to check whether a +:class:`fractions.Fraction` is an integer. This improves duck type +compatibility with :class:`float` and :class:`int`. + +.. + +.. date: 2022-12-23-21-02-43 +.. gh-issue: 100474 +.. nonce: gppA4U +.. section: Library + +:mod:`http.server` now checks that an index page is actually a regular file +before trying to serve it. This avoids issues with directories named +``index.html``. + +.. + +.. date: 2022-12-20-11-07-30 +.. gh-issue: 100363 +.. nonce: Wo_Beg +.. section: Library + +Speed up :func:`asyncio.get_running_loop` by removing redundant ``getpid`` +checks. Patch by Kumar Aditya. + +.. + +.. date: 2022-12-19-20-54-04 +.. gh-issue: 78878 +.. nonce: JrkYqJ +.. section: Library + +Fix crash when creating an instance of :class:`!_ctypes.CField`. + +.. + +.. date: 2022-12-19-19-30-06 +.. gh-issue: 100348 +.. nonce: o7IAHh +.. section: Library + +Fix ref cycle in :class:`!asyncio._SelectorSocketTransport` by removing +``_read_ready_cb`` in ``close``. + +.. + +.. date: 2022-12-19-12-18-28 +.. gh-issue: 100344 +.. nonce: lfCqpE +.. section: Library + +Provide C implementation for :func:`asyncio.current_task` for a 4x-6x +speedup. + +.. + +.. date: 2022-12-15-18-28-13 +.. gh-issue: 100272 +.. nonce: D1O9Ey +.. section: Library + +Fix JSON serialization of OrderedDict. It now preserves the order of keys. + +.. + +.. date: 2022-12-14-17-37-01 +.. gh-issue: 83076 +.. nonce: NaYzWT +.. section: Library + +Instantiation of ``Mock()`` and ``AsyncMock()`` is now 3.8x faster. + +.. + +.. date: 2022-12-14-11-45-38 +.. gh-issue: 100234 +.. nonce: kn6yWV +.. section: Library + +Set a default value of 1.0 for the ``lambd`` parameter in +random.expovariate(). + +.. + +.. date: 2022-12-13-17-29-09 +.. gh-issue: 100228 +.. nonce: bgtzMV +.. section: Library + +A :exc:`DeprecationWarning` may be raised when :func:`os.fork()` or +:func:`os.forkpty()` is called from multi-threaded processes. Forking with +threads is unsafe and can cause deadlocks, crashes and subtle problems. Lack +of a warning does not indicate that the fork call was actually safe, as +Python may not be aware of all threads. + +.. + +.. date: 2022-12-10-20-52-28 +.. gh-issue: 100039 +.. nonce: zDqjT4 +.. section: Library + +Improve signatures for enums and flags. + +.. + +.. date: 2022-12-10-08-36-07 +.. gh-issue: 100133 +.. nonce: g-zQlp +.. section: Library + +Fix regression in :mod:`asyncio` where a subprocess would sometimes lose +data received from pipe. + +.. + +.. bpo: 44592 +.. date: 2022-12-09-10-35-36 +.. nonce: z-P3oe +.. section: Library + +Fixes inconsistent handling of case sensitivity of *extrasaction* arg in +:class:`csv.DictWriter`. + +.. + +.. date: 2022-12-08-06-18-06 +.. gh-issue: 100098 +.. nonce: uBvPlp +.. section: Library + +Fix ``tuple`` subclasses being cast to ``tuple`` when used as enum values. + +.. + +.. date: 2022-12-04-16-12-04 +.. gh-issue: 85432 +.. nonce: l_ehmI +.. section: Library + +Rename the *fmt* parameter of the pure-Python implementation of +:meth:`datetime.time.strftime` to *format*. Rename the *t* parameter of +:meth:`datetime.datetime.fromtimestamp` to *timestamp*. These changes mean +the parameter names in the pure-Python implementation now match the +parameter names in the C implementation. Patch by Alex Waygood. + +.. + +.. date: 2022-12-03-20-06-16 +.. gh-issue: 98778 +.. nonce: t5U9uc +.. section: Library + +Update :exc:`~urllib.error.HTTPError` to be initialized properly, even if +the ``fp`` is ``None``. Patch by Donghee Na. + +.. + +.. date: 2022-12-01-15-44-58 +.. gh-issue: 99925 +.. nonce: x4y6pF +.. section: Library + +Unify error messages in JSON serialization between +``json.dumps(float('nan'), allow_nan=False)`` and ``json.dumps(float('nan'), +allow_nan=False, indent=<SOMETHING>)``. Now both include the representation +of the value that could not be serialized. + +.. + +.. date: 2022-11-29-20-44-54 +.. gh-issue: 89727 +.. nonce: UJZjkk +.. section: Library + +Fix issue with :func:`os.walk` where a :exc:`RecursionError` would occur on +deep directory structures by adjusting the implementation of :func:`os.walk` +to be iterative instead of recursive. + +.. + +.. date: 2022-11-23-23-58-45 +.. gh-issue: 94943 +.. nonce: Oog0Zo +.. section: Library + +Add :ref:`enum-dataclass-support` to the :class:`~enum.Enum` +:meth:`~enum.Enum.__repr__`. When inheriting from a +:class:`~dataclasses.dataclass`, only show the field names in the value +section of the member :func:`repr`, and not the dataclass' class name. + +.. + +.. date: 2022-11-21-16-24-01 +.. gh-issue: 83035 +.. nonce: qZIujU +.. section: Library + +Fix :func:`inspect.getsource` handling of decorator calls with nested +parentheses. + +.. + +.. date: 2022-11-20-11-59-54 +.. gh-issue: 99576 +.. nonce: ZD7jU6 +.. section: Library + +Fix ``.save()`` method for ``LWPCookieJar`` and ``MozillaCookieJar``: saved +file was not truncated on repeated save. + +.. + +.. date: 2022-11-17-10-02-18 +.. gh-issue: 94912 +.. nonce: G2aa-E +.. section: Library + +Add :func:`inspect.markcoroutinefunction` decorator which manually marks a +function as a coroutine for the benefit of :func:`iscoroutinefunction`. + +.. + +.. date: 2022-11-15-18-45-01 +.. gh-issue: 99509 +.. nonce: FLK0xU +.. section: Library + +Add :pep:`585` support for :class:`multiprocessing.queues.Queue`. + +.. + +.. date: 2022-11-14-19-58-36 +.. gh-issue: 99482 +.. nonce: XmZyUr +.. section: Library + +Remove ``Jython`` partial compatibility code from several stdlib modules. + +.. + +.. date: 2022-11-13-15-32-19 +.. gh-issue: 99433 +.. nonce: Ys6y0A +.. section: Library + +Fix :mod:`doctest` failure on :class:`types.MethodWrapperType` in modules. + +.. + +.. date: 2022-10-28-07-24-34 +.. gh-issue: 85267 +.. nonce: xUy_Wm +.. section: Library + +Several improvements to :func:`inspect.signature`'s handling of +``__text_signature``. - Fixes a case where :func:`inspect.signature` dropped +parameters - Fixes a case where :func:`inspect.signature` raised +:exc:`tokenize.TokenError` - Allows :func:`inspect.signature` to understand +defaults involving binary operations of constants - +:func:`inspect.signature` is documented as only raising :exc:`TypeError` or +:exc:`ValueError`, but sometimes raised :exc:`RuntimeError`. These cases now +raise :exc:`ValueError` - Removed a dead code path + +.. + +.. date: 2022-10-24-07-31-11 +.. gh-issue: 91166 +.. nonce: -IG06R +.. section: Library + +:mod:`asyncio` is optimized to avoid excessive copying when writing to +socket and use :meth:`~socket.socket.sendmsg` if the platform supports it. +Patch by Kumar Aditya. + +.. + +.. date: 2022-10-07-18-16-00 +.. gh-issue: 98030 +.. nonce: 2oQCZy +.. section: Library + +Add missing TCP socket options from Linux: ``TCP_MD5SIG``, +``TCP_THIN_LINEAR_TIMEOUTS``, ``TCP_THIN_DUPACK``, ``TCP_REPAIR``, +``TCP_REPAIR_QUEUE``, ``TCP_QUEUE_SEQ``, ``TCP_REPAIR_OPTIONS``, +``TCP_TIMESTAMP``, ``TCP_CC_INFO``, ``TCP_SAVE_SYN``, ``TCP_SAVED_SYN``, +``TCP_REPAIR_WINDOW``, ``TCP_FASTOPEN_CONNECT``, ``TCP_ULP``, +``TCP_MD5SIG_EXT``, ``TCP_FASTOPEN_KEY``, ``TCP_FASTOPEN_NO_COOKIE``, +``TCP_ZEROCOPY_RECEIVE``, ``TCP_INQ``, ``TCP_TX_DELAY``. + +.. + +.. date: 2022-09-16-08-21-46 +.. gh-issue: 88500 +.. nonce: jQ0pCc +.. section: Library + +Reduced the memory usage of :func:`urllib.parse.unquote` and +:func:`urllib.parse.unquote_to_bytes` on large values. + +.. + +.. date: 2022-08-27-10-35-50 +.. gh-issue: 96127 +.. nonce: 8RdLre +.. section: Library + +``inspect.signature`` was raising ``TypeError`` on call with mock objects. +Now it correctly returns ``(*args, **kwargs)`` as infered signature. + +.. + +.. date: 2022-08-11-10-02-19 +.. gh-issue: 95882 +.. nonce: FsUr72 +.. section: Library + +Fix a 3.11 regression in :func:`~contextlib.asynccontextmanager`, which +caused it to propagate exceptions with incorrect tracebacks and fix a 3.11 +regression in :func:`~contextlib.contextmanager`, which caused it to +propagate exceptions with incorrect tracebacks for :exc:`StopIteration`. + +.. + +.. date: 2022-07-01-00-01-22 +.. gh-issue: 78707 +.. nonce: fHGSuM +.. section: Library + +Deprecate passing more than one positional argument to +:meth:`pathlib.PurePath.relative_to` and +:meth:`~pathlib.PurePath.is_relative_to`. + +.. + +.. date: 2022-05-06-01-53-34 +.. gh-issue: 92122 +.. nonce: 96Lf2p +.. section: Library + +Fix reStructuredText syntax errors in docstrings in the :mod:`enum` module. + +.. + +.. date: 2022-04-23-08-12-14 +.. gh-issue: 91851 +.. nonce: Jd47V6 +.. section: Library + +Optimize the :class:`~fractions.Fraction` arithmetics for small components. + +.. + +.. bpo: 24132 +.. date: 2022-03-05-02-14-09 +.. nonce: W6iORO +.. section: Library + +Make :class:`pathlib.PurePath` and :class:`~pathlib.Path` subclassable +(private to start). Previously, attempting to instantiate a subclass +resulted in an :exc:`AttributeError` being raised. Patch by Barney Gale. + +.. + +.. bpo: 40447 +.. date: 2020-05-03-12-55-55 +.. nonce: oKR0Lj +.. section: Library + +Accept :class:`os.PathLike` (such as :class:`pathlib.Path`) in the +``stripdir`` arguments of :meth:`compileall.compile_file` and +:meth:`compileall.compile_dir`. + +.. + +.. bpo: 36880 +.. date: 2019-05-13-11-37-30 +.. nonce: ZgBgH0 +.. section: Library + +Fix a reference counting issue when a :mod:`ctypes` callback with return +type :class:`~ctypes.py_object` returns ``None``, which could cause crashes. + +.. + +.. date: 2022-12-30-00-42-23 +.. gh-issue: 100616 +.. nonce: eu80ij +.. section: Documentation + +Document existing ``attr`` parameter to :func:`curses.window.vline` function +in :mod:`curses`. + +.. + +.. date: 2022-12-23-21-42-26 +.. gh-issue: 100472 +.. nonce: NNixfO +.. section: Documentation + +Remove claim in documentation that the ``stripdir``, ``prependdir`` and +``limit_sl_dest`` parameters of :func:`compileall.compile_dir` and +:func:`compileall.compile_file` could be :class:`bytes`. + +.. + +.. bpo: 25377 +.. date: 2020-06-17-14-47-48 +.. nonce: CTxC6o +.. section: Documentation + +Clarify use of octal format of mode argument in help(os.chmod) as well as +help(os.fchmod) + +.. + +.. date: 2022-12-23-13-29-55 +.. gh-issue: 100454 +.. nonce: 3no0cW +.. section: Tests + +Start running SSL tests with OpenSSL 3.1.0-beta1. + +.. + +.. date: 2022-12-08-00-03-37 +.. gh-issue: 100086 +.. nonce: 1zYpto +.. section: Tests + +The Python test runner (libregrtest) now logs Python build information like +"debug" vs "release" build, or LTO and PGO optimizations. Patch by Victor +Stinner. + +.. + +.. date: 2022-06-16-13-26-31 +.. gh-issue: 93018 +.. nonce: wvNx76 +.. section: Tests + +Make two tests forgiving towards host system libexpat with backported +security fixes applied. + +.. + +.. date: 2022-12-26-15-07-48 +.. gh-issue: 100540 +.. nonce: l6ToSY +.. section: Build + +Removed the ``--with-system-ffi`` ``configure`` option; ``libffi`` must now +always be supplied by the system on all non-Windows platforms. The option +has had no effect on non-Darwin platforms for several releases, and in 3.11 +only had the non-obvious effect of invoking ``pkg-config`` to find +``libffi`` and never setting ``-DUSING_APPLE_OS_LIBFFI``. Now on Darwin +platforms ``configure`` will first check for the OS ``libffi`` and then fall +back to the same processing as other platforms if it is not found. + +.. + +.. date: 2022-12-08-14-00-04 +.. gh-issue: 88267 +.. nonce: MqtRbm +.. section: Build + +Avoid exporting Python symbols in linked Windows applications when the core +is built as static. + +.. + +.. bpo: 41916 +.. date: 2022-03-04-10-47-23 +.. nonce: 1d2GLU +.. section: Build + +Allow override of ac_cv_cxx_thread so that cross compiled python can set +-pthread for CXX. + +.. + +.. date: 2023-01-09-23-03-57 +.. gh-issue: 100180 +.. nonce: b5phrg +.. section: Windows + +Update Windows installer to OpenSSL 1.1.1s + +.. + +.. date: 2022-12-20-18-36-17 +.. gh-issue: 99191 +.. nonce: 0cfRja +.. section: Windows + +Use ``_MSVC_LANG >= 202002L`` instead of less-precise ``_MSC_VER >=1929`` to +more accurately test for C++20 support in :file:`PC/_wmimodule.cpp`. + +.. + +.. date: 2022-12-09-22-47-42 +.. gh-issue: 79218 +.. nonce: Yiot2e +.. section: Windows + +Define ``MS_WIN64`` for Mingw-w64 64bit, fix cython compilation failure. + +.. + +.. date: 2022-12-06-11-16-46 +.. gh-issue: 99941 +.. nonce: GmUQ6o +.. section: Windows + +Ensure that :func:`asyncio.Protocol.data_received` receives an immutable +:class:`bytes` object (as documented), instead of :class:`bytearray`. + +.. + +.. bpo: 43984 +.. date: 2021-05-02-15-29-33 +.. nonce: U92jiv +.. section: Windows + +:meth:`winreg.SetValueEx` now leaves the target value untouched in the case +of conversion errors. Previously, ``-1`` would be written in case of such +errors. + +.. + +.. bpo: 34816 +.. date: 2021-04-08-00-36-37 +.. nonce: 4Xe0id +.. section: Windows + +``hasattr(ctypes.windll, 'nonexistant')`` now returns ``False`` instead of +raising :exc:`OSError`. + +.. + +.. date: 2023-01-09-22-04-21 +.. gh-issue: 100180 +.. nonce: WVhCny +.. section: macOS + +Update macOS installer to OpenSSL 1.1.1s + +.. + +.. date: 2022-12-26-14-52-37 +.. gh-issue: 100540 +.. nonce: kYZLtX +.. section: macOS + +Removed obsolete ``dlfcn.h`` shim from the ``_ctypes`` extension module, +which has not been necessary since Mac OS X 10.2. + +.. + +.. bpo: 45256 +.. date: 2022-12-29-19-22-11 +.. nonce: a0ee_H +.. section: Tools/Demos + +Fix a bug that caused an :exc:`AttributeError` to be raised in +``python-gdb.py`` when ``py-locals`` is used without a frame. + +.. + +.. date: 2022-12-19-10-08-53 +.. gh-issue: 100342 +.. nonce: qDFlQG +.. section: Tools/Demos + +Add missing ``NULL`` check for possible allocation failure in ``*args`` +parsing in Argument Clinic. + +.. + +.. date: 2022-12-02-09-31-19 +.. gh-issue: 99947 +.. nonce: Ski7OC +.. section: C API + +Raising SystemError on import will now have its cause be set to the original +unexpected exception. + +.. + +.. date: 2022-11-30-16-39-22 +.. gh-issue: 99240 +.. nonce: 67nAX- +.. section: C API + +In argument parsing, after deallocating newly allocated memory, reset its +pointer to NULL. + +.. + +.. date: 2022-11-04-16-13-35 +.. gh-issue: 98724 +.. nonce: p0urWO +.. section: C API + +The :c:macro:`Py_CLEAR`, :c:macro:`Py_SETREF` and :c:macro:`Py_XSETREF` +macros now only evaluate their arguments once. If an argument has side +effects, these side effects are no longer duplicated. Patch by Victor +Stinner. diff --git a/Misc/NEWS.d/3.12.0a5.rst b/Misc/NEWS.d/3.12.0a5.rst new file mode 100644 index 00000000..8cf90b0e --- /dev/null +++ b/Misc/NEWS.d/3.12.0a5.rst @@ -0,0 +1,664 @@ +.. date: 2022-11-08-12-06-52 +.. gh-issue: 99108 +.. nonce: 4Wrsuh +.. release date: 2023-02-07 +.. section: Security + +Replace the builtin :mod:`hashlib` implementations of SHA2-224 and SHA2-256 +originally from LibTomCrypt with formally verified, side-channel resistant +code from the `HACL* <https://github.com/hacl-star/hacl-star/>`_ project. +The builtins remain a fallback only used when OpenSSL does not provide them. + +.. + +.. date: 2023-02-06-20-13-36 +.. gh-issue: 92173 +.. nonce: RQE0mk +.. section: Core and Builtins + +Fix the ``defs`` and ``kwdefs`` arguments to :c:func:`PyEval_EvalCodeEx` and +a reference leak in that function. + +.. + +.. date: 2023-01-30-11-56-09 +.. gh-issue: 59956 +.. nonce: 7xqnC_ +.. section: Core and Builtins + +The GILState API is now partially compatible with subinterpreters. +Previously, ``PyThreadState_GET()`` and ``PyGILState_GetThisThreadState()`` +would get out of sync, causing inconsistent behavior and crashes. + +.. + +.. date: 2023-01-30-08-59-47 +.. gh-issue: 101400 +.. nonce: Di_ZFm +.. section: Core and Builtins + +Fix wrong lineno in exception message on :keyword:`continue` or +:keyword:`break` which are not in a loop. Patch by Donghee Na. + +.. + +.. date: 2023-01-28-20-31-42 +.. gh-issue: 101372 +.. nonce: 8BcpCC +.. section: Core and Builtins + +Fix :func:`~unicodedata.is_normalized` to properly handle the UCD 3.2.0 +cases. Patch by Donghee Na. + +.. + +.. date: 2023-01-28-13-11-52 +.. gh-issue: 101266 +.. nonce: AxV3OF +.. section: Core and Builtins + +Fix :func:`sys.getsizeof` reporting for :class:`int` subclasses. + +.. + +.. date: 2023-01-24-17-13-32 +.. gh-issue: 101291 +.. nonce: Yr6u_c +.. section: Core and Builtins + +Refactor the ``PyLongObject`` struct into a normal Python object header and +a ``PyLongValue`` struct. + +.. + +.. date: 2023-01-15-03-26-04 +.. gh-issue: 101046 +.. nonce: g2CM4S +.. section: Core and Builtins + +Fix a possible memory leak in the parser when raising :exc:`MemoryError`. +Patch by Pablo Galindo + +.. + +.. date: 2023-01-14-17-03-08 +.. gh-issue: 101037 +.. nonce: 9ATNuf +.. section: Core and Builtins + +Fix potential memory underallocation issue for instances of :class:`int` +subclasses with value zero. + +.. + +.. date: 2023-01-13-12-56-20 +.. gh-issue: 100762 +.. nonce: YvHaQJ +.. section: Core and Builtins + +Record the (virtual) exception block depth in the oparg of +:opcode:`YIELD_VALUE`. Use this to avoid the expensive ``throw()`` when +closing generators (and coroutines) that can be closed trivially. + +.. + +.. date: 2023-01-12-13-46-49 +.. gh-issue: 100982 +.. nonce: mJ234s +.. section: Core and Builtins + +Adds a new :opcode:`COMPARE_AND_BRANCH` instruction. This is a bit more +efficient when performing a comparison immediately followed by a branch, and +restores the design intent of PEP 659 that specializations are local to a +single instruction. + +.. + +.. date: 2023-01-11-22-52-19 +.. gh-issue: 100942 +.. nonce: ontOy_ +.. section: Core and Builtins + +Fixed segfault in property.getter/setter/deleter that occurred when a +property subclass overrode the ``__new__`` method to return a non-property +instance. + +.. + +.. date: 2023-01-10-16-59-33 +.. gh-issue: 100923 +.. nonce: ypJAX- +.. section: Core and Builtins + +Remove the ``mask`` cache entry for the :opcode:`COMPARE_OP` instruction and +embed the mask into the oparg. + +.. + +.. date: 2023-01-10-14-11-17 +.. gh-issue: 100892 +.. nonce: qfBVYI +.. section: Core and Builtins + +Fix race while iterating over thread states in clearing +:class:`threading.local`. Patch by Kumar Aditya. + +.. + +.. date: 2023-01-06-09-22-21 +.. gh-issue: 91351 +.. nonce: iq2vZ_ +.. section: Core and Builtins + +Fix a case where re-entrant imports could corrupt the import deadlock +detection code and cause a :exc:`KeyError` to be raised out of +:mod:`importlib/_bootstrap`. In addition to the straightforward cases, this +could also happen when garbage collection leads to a warning being emitted +-- as happens when it collects an open socket or file) + +.. + +.. date: 2023-01-03-20-59-20 +.. gh-issue: 100726 +.. nonce: W9huFl +.. section: Core and Builtins + +Optimize construction of ``range`` object for medium size integers. + +.. + +.. date: 2023-01-03-14-33-23 +.. gh-issue: 100712 +.. nonce: po6xyB +.. section: Core and Builtins + +Added option to build cpython with specialization disabled, by setting +``ENABLE_SPECIALIZATION=False`` in :mod:`opcode`, followed by ``make +regen-all``. + +.. + +.. bpo: 32780 +.. date: 2018-02-05-21-54-46 +.. nonce: Dtiz8z +.. section: Core and Builtins + +Inter-field padding is now inserted into the PEP3118 format strings obtained +from :class:`ctypes.Structure` objects, reflecting their true representation +in memory. + +.. + +.. date: 2023-02-05-14-39-49 +.. gh-issue: 101541 +.. nonce: Mo3ppp +.. section: Library + +[Enum] - fix psuedo-flag creation + +.. + +.. date: 2023-02-04-21-01-49 +.. gh-issue: 101570 +.. nonce: lbtUsD +.. section: Library + +Upgrade pip wheel bundled with ensurepip (pip 23.0) + +.. + +.. date: 2023-01-26-06-44-35 +.. gh-issue: 101323 +.. nonce: h8Hk11 +.. section: Library + +Fix a bug where errors where not thrown by zlib._ZlibDecompressor if +encountered during decompressing. + +.. + +.. date: 2023-01-26-01-25-56 +.. gh-issue: 101317 +.. nonce: vWaS1x +.. section: Library + +Add *ssl_shutdown_timeout* parameter for +:meth:`asyncio.StreamWriter.start_tls`. + +.. + +.. date: 2023-01-25-18-07-20 +.. gh-issue: 101326 +.. nonce: KL4SFv +.. section: Library + +Fix regression when passing ``None`` as second or third argument to +``FutureIter.throw``. + +.. + +.. date: 2023-01-24-12-53-59 +.. gh-issue: 92123 +.. nonce: jf6TO5 +.. section: Library + +Adapt the ``_elementtree`` extension module to multi-phase init +(:pep:`489`). Patches by Erlend E. Aasland. + +.. + +.. date: 2023-01-21-16-50-22 +.. gh-issue: 100795 +.. nonce: NPMZf7 +.. section: Library + +Avoid potential unexpected ``freeaddrinfo`` call (double free) in +:mod:`socket` when when a libc ``getaddrinfo()`` implementation leaves +garbage in an output pointer when returning an error. Original patch by +Sergey G. Brester. + +.. + +.. date: 2023-01-20-10-46-59 +.. gh-issue: 101143 +.. nonce: hJo8hu +.. section: Library + +Remove unused references to :class:`~asyncio.TimerHandle` in +``asyncio.base_events.BaseEventLoop._add_callback``. + +.. + +.. date: 2023-01-18-17-58-50 +.. gh-issue: 101144 +.. nonce: FHd8Un +.. section: Library + +Make :func:`zipfile.Path.open` and :func:`zipfile.Path.read_text` also +accept ``encoding`` as a positional argument. This was the behavior in +Python 3.9 and earlier. 3.10 introduced a regression where supplying it as +a positional argument would lead to a :exc:`TypeError`. + +.. + +.. date: 2023-01-15-09-11-30 +.. gh-issue: 94518 +.. nonce: jvxtxm +.. section: Library + +Group-related variables of ``_posixsubprocess`` module are renamed to stress +that supplimentary group affinity is added to a fork, not replace the +inherited ones. Patch by Oleg Iarygin. + +.. + +.. date: 2023-01-14-12-58-21 +.. gh-issue: 101015 +.. nonce: stWFid +.. section: Library + +Fix :func:`typing.get_type_hints` on ``'*tuple[...]'`` and ``*tuple[...]``. +It must not drop the ``Unpack`` part. + +.. + +.. date: 2023-01-12-21-22-20 +.. gh-issue: 101000 +.. nonce: wz4Xgc +.. section: Library + +Add :func:`os.path.splitroot()`, which splits a path into a 3-item tuple +``(drive, root, tail)``. This new function is used by :mod:`pathlib` to +improve the performance of path construction by up to a third. + +.. + +.. date: 2023-01-12-01-18-13 +.. gh-issue: 100573 +.. nonce: KDskqo +.. section: Library + +Fix a Windows :mod:`asyncio` bug with named pipes where a client doing +``os.stat()`` on the pipe would cause an error in the server that disabled +serving future requests. + +.. + +.. date: 2023-01-08-00-12-44 +.. gh-issue: 39615 +.. nonce: gn4PhB +.. section: Library + +:func:`warnings.warn` now has the ability to skip stack frames based on code +filename prefix rather than only a numeric ``stacklevel`` via the new +``skip_file_prefixes`` keyword argument. + +.. + +.. date: 2023-01-04-14-42-59 +.. gh-issue: 100750 +.. nonce: iFJs5Y +.. section: Library + +pass encoding kwarg to subprocess in platform + +.. + +.. date: 2022-12-21-17-49-50 +.. gh-issue: 100160 +.. nonce: N0NHRj +.. section: Library + +Emit a deprecation warning in +:meth:`asyncio.DefaultEventLoopPolicy.get_event_loop` if there is no current +event loop set and it decides to create one. + +.. + +.. date: 2022-12-19-23-19-26 +.. gh-issue: 96290 +.. nonce: qFjsi6 +.. section: Library + +Fix handling of partial and invalid UNC drives in ``ntpath.splitdrive()``, +and in ``ntpath.normpath()`` on non-Windows systems. Paths such as +'\\server' and '\\' are now considered by ``splitdrive()`` to contain only a +drive, and consequently are not modified by ``normpath()`` on non-Windows +systems. The behaviour of ``normpath()`` on Windows systems is unaffected, +as native OS APIs are used. Patch by Eryk Sun, with contributions by Barney +Gale. + +.. + +.. date: 2022-12-11-14-38-59 +.. gh-issue: 99952 +.. nonce: IYGLzr +.. section: Library + +Fix a reference undercounting issue in :class:`ctypes.Structure` with +``from_param()`` results larger than a C pointer. + +.. + +.. date: 2022-12-10-15-30-17 +.. gh-issue: 67790 +.. nonce: P9YUZM +.. section: Library + +Add float-style formatting support for :class:`fractions.Fraction` +instances. + +.. + +.. date: 2022-11-24-21-52-31 +.. gh-issue: 99266 +.. nonce: 88GcV9 +.. section: Library + +Preserve more detailed error messages in :mod:`ctypes`. + +.. + +.. date: 2022-11-15-23-30-39 +.. gh-issue: 86682 +.. nonce: gK9i1N +.. section: Library + +Ensure runtime-created collections have the correct module name using the +newly added (internal) :func:`sys._getframemodulename`. + +.. + +.. date: 2022-11-14-03-06-03 +.. gh-issue: 88597 +.. nonce: EYJA-Q +.. section: Library + +:mod:`uuid` now has a command line interface. Try ``python -m uuid -h``. + +.. + +.. date: 2022-09-26-21-18-47 +.. gh-issue: 60580 +.. nonce: 0hBgde +.. section: Library + +:data:`ctypes.wintypes.BYTE` definition changed from :data:`~ctypes.c_byte` +to :data:`~ctypes.c_ubyte` to match Windows SDK. Patch by Anatoly Techtonik +and Oleg Iarygin. + +.. + +.. date: 2022-07-22-13-38-37 +.. gh-issue: 94518 +.. nonce: _ZP0cz +.. section: Library + +``_posixsubprocess`` now initializes all UID and GID variables using a +reserved ``-1`` value instead of a separate flag. Patch by Oleg Iarygin. + +.. + +.. bpo: 38941 +.. date: 2022-02-05-12-01-58 +.. nonce: 8IhvyG +.. section: Library + +The :mod:`xml.etree.ElementTree` module now emits :exc:`DeprecationWarning` +when testing the truth value of an :class:`xml.etree.ElementTree.Element`. +Before, the Python implementation emitted :exc:`FutureWarning`, and the C +implementation emitted nothing. + +.. + +.. bpo: 40077 +.. date: 2020-11-20-21-06-08 +.. nonce: M-iZq3 +.. section: Library + +Convert :mod:`elementtree` types to heap types. Patch by Erlend E. Aasland. + +.. + +.. bpo: 29847 +.. date: 2020-04-18-17-45-03 +.. nonce: Uxtbq0 +.. section: Library + +Fix a bug where :class:`pathlib.Path` accepted and ignored keyword +arguments. Patch provided by Yurii Karabas. + +.. + +.. date: 2018-05-21-17-18-00 +.. gh-issue: 77772 +.. nonce: Fhg84L +.. section: Library + +:class:`ctypes.CDLL`, :class:`ctypes.OleDLL`, :class:`ctypes.WinDLL`, and +:class:`ctypes.PyDLL` now accept :term:`path-like objects <path-like +object>` as their ``name`` argument. Patch by Robert Hoelzl. + +.. + +.. date: 2022-06-19-22-04-47 +.. gh-issue: 88324 +.. nonce: GHhSQ1 +.. section: Documentation + +Reword :mod:`subprocess` to emphasize default behavior of *stdin*, *stdout*, +and *stderr* arguments. Remove inaccurate statement about child file handle +inheritance. + +.. + +.. date: 2023-02-04-17-24-33 +.. gh-issue: 101334 +.. nonce: _yOqwg +.. section: Tests + +``test_tarfile`` has been updated to pass when run as a high UID. + +.. + +.. date: 2023-02-04-06-59-07 +.. gh-issue: 101282 +.. nonce: 7sQz5l +.. section: Build + +Update BOLT configration not to use depreacted usage of ``--split +functions``. Patch by Donghee Na. + +.. + +.. date: 2023-02-02-23-43-46 +.. gh-issue: 101522 +.. nonce: lnUDta +.. section: Build + +Allow overriding Windows dependencies versions and paths using MSBuild +properties. + +.. + +.. date: 2023-01-26-19-02-11 +.. gh-issue: 77532 +.. nonce: cXD8bg +.. section: Build + +Minor fixes to allow building with ``PlatformToolset=ClangCL`` on Windows. + +.. + +.. date: 2023-01-21-10-31-35 +.. gh-issue: 101152 +.. nonce: xvM8pL +.. section: Build + +In accordance with :PEP:`699`, the ``ma_version_tag`` field in +:c:type:`PyDictObject` is deprecated for extension modules. Accessing this +field will generate a compiler warning at compile time. This field will be +removed in Python 3.14. + +.. + +.. date: 2023-01-17-21-32-51 +.. gh-issue: 100340 +.. nonce: i9zRGM +.. section: Build + +Allows -Wno-int-conversion for wasm-sdk 17 and onwards, thus enables +building WASI builds once against the latest sdk. + +.. + +.. date: 2023-01-15-11-22-15 +.. gh-issue: 101060 +.. nonce: 0mYk9E +.. section: Build + +Conditionally add ``-fno-reorder-blocks-and-partition`` in configure. +Effectively fixes ``--enable-bolt`` when using Clang, as this appears to be +a GCC-only flag. + +.. + +.. date: 2022-10-27-09-57-12 +.. gh-issue: 98705 +.. nonce: H11XmR +.. section: Build + +``__bool__`` is defined in AIX system header files which breaks the build in +AIX, so undefine it. + +.. + +.. date: 2022-10-25-11-53-55 +.. gh-issue: 98636 +.. nonce: e0RPAr +.. section: Build + +Fix a regression in detecting ``gdbm_compat`` library for the ``_gdbm`` +module build. + +.. + +.. date: 2022-08-30-10-16-31 +.. gh-issue: 96305 +.. nonce: 274i8B +.. section: Build + +``_aix_support`` now uses a simple code to get platform details rather than +the now non-existent ``_bootsubprocess`` during bootstrap. + +.. + +.. date: 2023-02-03-17-53-06 +.. gh-issue: 101543 +.. nonce: cORAT4 +.. section: Windows + +Ensure the install path in the registry is only used when the standard +library hasn't been located in any other way. + +.. + +.. date: 2023-01-31-16-50-07 +.. gh-issue: 101467 +.. nonce: ye9t-L +.. section: Windows + +The ``py.exe`` launcher now correctly filters when only a single runtime is +installed. It also correctly handles prefix matches on tags so that ``-3.1`` +does not match ``3.11``, but would still match ``3.1-32``. + +.. + +.. date: 2023-01-25-00-23-31 +.. gh-issue: 99834 +.. nonce: WN41lc +.. section: Windows + +Updates bundled copy of Tcl/Tk to 8.6.13.0 + +.. + +.. date: 2023-01-18-18-25-18 +.. gh-issue: 101135 +.. nonce: HF9VlG +.. section: Windows + +Restore ability to launch older 32-bit versions from the :file:`py.exe` +launcher when both 32-bit and 64-bit installs of the same version are +available. + +.. + +.. date: 2023-01-17-18-17-58 +.. gh-issue: 82052 +.. nonce: mWyysT +.. section: Windows + +Fixed an issue where writing more than 32K of Unicode output to the console +screen in one go can result in mojibake. + +.. + +.. date: 2023-01-11-16-28-09 +.. gh-issue: 100320 +.. nonce: 2DU2it +.. section: Windows + +Ensures the ``PythonPath`` registry key from an install is used when +launching from a different copy of Python that relies on an existing install +to provide a copy of its modules and standard library. + +.. + +.. date: 2023-01-11-14-42-11 +.. gh-issue: 100247 +.. nonce: YfEmSz +.. section: Windows + +Restores support for the :file:`py.exe` launcher finding shebang commands in +its configuration file using the full command name. diff --git a/Misc/NEWS.d/3.12.0a6.rst b/Misc/NEWS.d/3.12.0a6.rst new file mode 100644 index 00000000..5bd600cd --- /dev/null +++ b/Misc/NEWS.d/3.12.0a6.rst @@ -0,0 +1,821 @@ +.. date: 2023-02-17-10-42-48 +.. gh-issue: 99108 +.. nonce: MKA8-f +.. release date: 2023-03-07 +.. section: Security + +Replace builtin hashlib implementations of MD5 and SHA1 with verified ones +from the HACL* project. + +.. + +.. date: 2023-02-08-22-03-04 +.. gh-issue: 101727 +.. nonce: 9P5eZz +.. section: Security + +Updated the OpenSSL version used in Windows and macOS binary release builds +to 1.1.1t to address CVE-2023-0286, CVE-2022-4303, and CVE-2022-4303 per +`the OpenSSL 2023-02-07 security advisory +<https://www.openssl.org/news/secadv/20230207.txt>`_. + +.. + +.. date: 2023-02-08-12-57-35 +.. gh-issue: 99108 +.. nonce: 6tnmhA +.. section: Security + +Replace the builtin :mod:`hashlib` implementations of SHA2-384 and SHA2-512 +originally from LibTomCrypt with formally verified, side-channel resistant +code from the `HACL* <https://github.com/hacl-star/hacl-star/>`_ project. +The builtins remain a fallback only used when OpenSSL does not provide them. + +.. + +.. date: 2023-01-24-16-12-00 +.. gh-issue: 101283 +.. nonce: 9tqu39 +.. section: Security + +:class:`subprocess.Popen` now uses a safer approach to find ``cmd.exe`` when +launching with ``shell=True``. Patch by Eryk Sun, based on a patch by Oleg +Iarygin. + +.. + +.. date: 2023-03-07-16-56-28 +.. gh-issue: 102493 +.. nonce: gTXrcD +.. section: Core and Builtins + +Fix regression in semantics of normalisation in ``PyErr_SetObject``. + +.. + +.. date: 2023-03-06-13-05-33 +.. gh-issue: 102416 +.. nonce: dz6K5f +.. section: Core and Builtins + +Do not memoize incorrectly automatically generated loop rules in the parser. +Patch by Pablo Galindo. + +.. + +.. date: 2023-03-04-20-56-12 +.. gh-issue: 102356 +.. nonce: 07KvUd +.. section: Core and Builtins + +Fix a bug that caused a crash when deallocating deeply nested filter +objects. Patch by Marta Gómez Macías. + +.. + +.. date: 2023-02-28-21-17-03 +.. gh-issue: 102336 +.. nonce: -wL3Tm +.. section: Core and Builtins + +Cleanup Windows 7 specific special handling. Patch by Max Bachmann. + +.. + +.. date: 2023-02-26-23-10-32 +.. gh-issue: 102250 +.. nonce: 7MUKoC +.. section: Core and Builtins + +Fixed a segfault occurring when the interpreter calls a ``__bool__`` method +that raises. + +.. + +.. date: 2023-02-24-17-59-39 +.. gh-issue: 102126 +.. nonce: HTT8Vc +.. section: Core and Builtins + +Fix deadlock at shutdown when clearing thread states if any finalizer tries +to acquire the runtime head lock. Patch by Kumar Aditya. + +.. + +.. date: 2023-02-22-15-15-32 +.. gh-issue: 102027 +.. nonce: Km4G-d +.. section: Core and Builtins + +Use ``GetCurrentProcessId`` on Windows when ``getpid`` is unavailable. Patch +by Max Bachmann. + +.. + +.. date: 2023-02-20-15-18-33 +.. gh-issue: 102056 +.. nonce: uHKuwH +.. section: Core and Builtins + +Fix error handling bugs in interpreter's exception printing code, which +could cause a crash on infinite recursion. + +.. + +.. date: 2023-02-17-10-12-13 +.. gh-issue: 100982 +.. nonce: mJGJQw +.. section: Core and Builtins + +Restrict the scope of the :opcode:`FOR_ITER_RANGE` instruction to the scope +of the original :opcode:`FOR_ITER` instruction, to allow instrumentation. + +.. + +.. date: 2023-02-16-23-19-01 +.. gh-issue: 101967 +.. nonce: Kqr1dz +.. section: Core and Builtins + +Fix possible segfault in ``positional_only_passed_as_keyword`` function, +when new list created. + +.. + +.. date: 2023-02-16-16-57-23 +.. gh-issue: 101952 +.. nonce: Zo1dlq +.. section: Core and Builtins + +Fix possible segfault in ``BUILD_SET`` opcode, when new set created. + +.. + +.. date: 2023-02-13-22-21-58 +.. gh-issue: 74895 +.. nonce: esMNtq +.. section: Core and Builtins + +:mod:`socket.getaddrinfo` no longer raises :class:`OverflowError` for +:class:`int` **port** values outside of the C long range. Out of range +values are left up to the underlying string based C library API to report. A +:class:`socket.gaierror` ``SAI_SERVICE`` may occur instead, or no error at +all as not all platform C libraries generate an error. + +.. + +.. date: 2023-02-13-18-21-14 +.. gh-issue: 101799 +.. nonce: wpHbCn +.. section: Core and Builtins + +Add :opcode:`CALL_INTRINSIC_2` and use it instead of +:opcode:`PREP_RERAISE_STAR`. + +.. + +.. date: 2023-02-12-22-40-22 +.. gh-issue: 101857 +.. nonce: _bribG +.. section: Core and Builtins + +Fix xattr support detection on Linux systems by widening the check to linux, +not just glibc. This fixes support for musl. + +.. + +.. date: 2023-02-11-23-14-06 +.. gh-issue: 84783 +.. nonce: _P5sMa +.. section: Core and Builtins + +Make the slice object hashable. Patch by Will Bradshaw and Furkan Onder. + +.. + +.. date: 2023-02-10-15-54-57 +.. gh-issue: 87849 +.. nonce: IUVvPz +.. section: Core and Builtins + +Change the ``SEND`` instruction to leave the receiver on the stack. This +allows the specialized form of ``SEND`` to skip the chain of C calls and +jump directly to the ``RESUME`` in the generator or coroutine. + +.. + +.. date: 2023-02-10-07-21-47 +.. gh-issue: 101765 +.. nonce: MO5LlC +.. section: Core and Builtins + +Fix SystemError / segmentation fault in iter ``__reduce__`` when internal +access of ``builtins.__dict__`` keys mutates the iter object. + +.. + +.. date: 2023-02-10-01-15-57 +.. gh-issue: 101430 +.. nonce: T3Gegb +.. section: Core and Builtins + +Update :mod:`tracemalloc` to handle presize of object properly. Patch by +Donghee Na. + +.. + +.. date: 2023-02-08-17-13-31 +.. gh-issue: 101696 +.. nonce: seJhTt +.. section: Core and Builtins + +Invalidate type version tag in ``_PyStaticType_Dealloc`` for static types, +avoiding bug where a false cache hit could crash the interpreter. Patch by +Kumar Aditya. + +.. + +.. date: 2023-02-07-14-56-43 +.. gh-issue: 101632 +.. nonce: Fd1yxk +.. section: Core and Builtins + +Adds a new :opcode:`RETURN_CONST` instruction. + +.. + +.. date: 2023-01-04-12-49-33 +.. gh-issue: 100719 +.. nonce: uRPccL +.. section: Core and Builtins + +Remove gi_code field from generator (and coroutine and async generator) +objects as it is redundant. The frame already includes a reference to the +code object. + +.. + +.. date: 2022-11-02-20-23-47 +.. gh-issue: 98627 +.. nonce: VJkdRM +.. section: Core and Builtins + +When an interpreter is configured to check (and only then), importing an +extension module will now fail when the extension does not support multiple +interpreters (i.e. doesn't implement PEP 489 multi-phase init). This does +not apply to the main interpreter, nor to subinterpreters created with +``Py_NewInterpreter()``. + +.. + +.. date: 2023-03-04-14-46-47 +.. gh-issue: 102302 +.. nonce: -b_s6Z +.. section: Library + +Micro-optimise hashing of :class:`inspect.Parameter`, reducing the time it +takes to hash an instance by around 40%. + +.. + +.. date: 2023-02-28-09-52-25 +.. gh-issue: 101979 +.. nonce: or3hXV +.. section: Library + +Fix a bug where parentheses in the ``metavar`` argument to +:meth:`argparse.ArgumentParser.add_argument` were dropped. Patch by Yeojin +Kim. + +.. + +.. date: 2023-02-26-12-37-17 +.. gh-issue: 91038 +.. nonce: S4rFH_ +.. section: Library + +:meth:`platform.platform` now has boolean default arguments. + +.. + +.. date: 2023-02-23-20-39-52 +.. gh-issue: 81652 +.. nonce: Vxz0Mr +.. section: Library + +Add :const:`mmap.MAP_ALIGNED_SUPER` FreeBSD and :const:`mmap.MAP_CONCEAL` +OpenBSD constants to :mod:`mmap`. Patch by Yeojin Kim. + +.. + +.. date: 2023-02-23-15-06-01 +.. gh-issue: 102179 +.. nonce: P6KQ4c +.. section: Library + +Fix :func:`os.dup2` error message for negative fds. + +.. + +.. date: 2023-02-21-10-05-33 +.. gh-issue: 101961 +.. nonce: 7e56jh +.. section: Library + +For the binary mode, :func:`fileinput.hookcompressed` doesn't set the +``encoding`` value even if the value is ``None``. Patch by Gihwan Kim. + +.. + +.. date: 2023-02-21-07-15-41 +.. gh-issue: 101936 +.. nonce: QVOxHH +.. section: Library + +The default value of ``fp`` becomes :class:`io.BytesIO` if +:exc:`~urllib.error.HTTPError` is initialized without a designated ``fp`` +parameter. Patch by Long Vo. + +.. + +.. date: 2023-02-17-20-24-15 +.. gh-issue: 101566 +.. nonce: FjgWBt +.. section: Library + +In zipfile, sync Path with `zipp 3.14 +<https://zipp.readthedocs.io/en/latest/history.html#v3-14-0>`_, including +fix for extractall on the underlying zipfile after being wrapped in +``Path``. + +.. + +.. date: 2023-02-17-19-00-58 +.. gh-issue: 97930 +.. nonce: C_nQjb +.. section: Library + +Apply changes from `importlib_resources 5.12 +<https://importlib-resources.readthedocs.io/en/latest/history.html#v5-12-0>`_, +including fix for ``MultiplexedPath`` to support directories in multiple +namespaces (python/importlib_resources#265). + +.. + +.. date: 2023-02-17-18-44-27 +.. gh-issue: 101997 +.. nonce: A6_blD +.. section: Library + +Upgrade pip wheel bundled with ensurepip (pip 23.0.1) + +.. + +.. date: 2023-02-15-01-54-06 +.. gh-issue: 99108 +.. nonce: rjTSic +.. section: Library + +The built-in extension modules for :mod:`hashlib` SHA2 algorithms, used when +OpenSSL does not provide them, now live in a single internal ``_sha2`` +module instead of separate ``_sha256`` and ``_sha512`` modules. + +.. + +.. date: 2023-02-14-09-08-48 +.. gh-issue: 101892 +.. nonce: FMos8l +.. section: Library + +Callable iterators no longer raise :class:`SystemError` when the callable +object exhausts the iterator but forgets to either return a sentinel value +or raise :class:`StopIteration`. + +.. + +.. date: 2023-02-13-12-55-48 +.. gh-issue: 87634 +.. nonce: q-SBhJ +.. section: Library + +Remove locking behavior from :func:`functools.cached_property`. + +.. + +.. date: 2023-02-11-13-23-29 +.. gh-issue: 97786 +.. nonce: QjvQ1B +.. section: Library + +Fix potential undefined behaviour in corner cases of floating-point-to-time +conversions. + +.. + +.. date: 2023-02-10-16-02-29 +.. gh-issue: 101517 +.. nonce: r7S2u8 +.. section: Library + +Fixed bug where :mod:`bdb` looks up the source line with :mod:`linecache` +with a ``lineno=None``, which causes it to fail with an unhandled exception. + +.. + +.. date: 2023-02-10-11-59-13 +.. gh-issue: 101773 +.. nonce: J_kI7y +.. section: Library + +Optimize :class:`fractions.Fraction` for small components. The private +argument ``_normalize`` of the :class:`fractions.Fraction` constructor has +been removed. + +.. + +.. date: 2023-02-08-18-20-58 +.. gh-issue: 101693 +.. nonce: 4_LPXj +.. section: Library + +In :meth:`sqlite3.Cursor.execute`, :exc:`DeprecationWarning` is now emitted +when :ref:`named placeholders <sqlite3-placeholders>` are used together with +parameters supplied as a :term:`sequence` instead of as a :class:`dict`. +Starting from Python 3.14, using named placeholders with parameters supplied +as a sequence will raise a :exc:`~sqlite3.ProgrammingError`. Patch by Erlend +E. Aasland. + +.. + +.. date: 2023-02-07-22-21-46 +.. gh-issue: 101446 +.. nonce: -c0FdK +.. section: Library + +Change repr of :class:`collections.OrderedDict` to use regular dictionary +formating instead of pairs of keys and values. + +.. + +.. date: 2023-02-07-22-20-32 +.. gh-issue: 101362 +.. nonce: Jlk6mt +.. section: Library + +Speed up :class:`pathlib.PurePath` construction by handling arguments more +uniformly. When a :class:`pathlib.Path` argument is supplied, we use its +string representation rather than joining its parts with +:func:`os.path.join`. + +.. + +.. date: 2023-02-07-21-16-41 +.. gh-issue: 101362 +.. nonce: KMQllM +.. section: Library + +Speed up :class:`pathlib.PurePath` construction by calling +:func:`os.path.join` only when two or more arguments are given. + +.. + +.. date: 2023-02-07-20-46-08 +.. gh-issue: 101362 +.. nonce: 2ckZ6R +.. section: Library + +Speed up :class:`pathlib.Path` construction by running the path flavour +compatibility check only when pathlib is imported. + +.. + +.. date: 2023-02-05-21-40-15 +.. gh-issue: 85984 +.. nonce: Kfzbb2 +.. section: Library + +Refactored the implementation of :func:`pty.fork` to use +:func:`os.login_tty`. + +A :exc:`DeprecationWarning` is now raised by ``pty.master_open()`` and +``pty.slave_open()``. They were undocumented and deprecated long long ago in +the docstring in favor of :func:`pty.openpty`. + +.. + +.. date: 2023-02-04-16-35-46 +.. gh-issue: 101561 +.. nonce: Xo6pIZ +.. section: Library + +Add a new decorator :func:`typing.override`. See :pep:`698` for details. +Patch by Steven Troxler. + +.. + +.. date: 2023-02-01-10-42-16 +.. gh-issue: 63301 +.. nonce: XNxSFh +.. section: Library + +Set exit code when :mod:`tabnanny` CLI exits on error. + +.. + +.. date: 2023-01-27-02-53-50 +.. gh-issue: 101360 +.. nonce: bPB7SL +.. section: Library + +Fix anchor matching in :meth:`pathlib.PureWindowsPath.match`. Path and +pattern anchors are now matched with :mod:`fnmatch`, just like other path +parts. This allows patterns such as ``"*:/Users/*"`` to be matched. + +.. + +.. date: 2023-01-25-00-14-52 +.. gh-issue: 101277 +.. nonce: FceHX7 +.. section: Library + +Remove global state from :mod:`itertools` module (:pep:`687`). Patches by +Erlend E. Aasland. + +.. + +.. date: 2023-01-06-21-14-41 +.. gh-issue: 100809 +.. nonce: I697UT +.. section: Library + +Fix handling of drive-relative paths (like 'C:' and 'C:foo') in +:meth:`pathlib.Path.absolute`. This method now uses the OS API to retrieve +the correct current working directory for the drive. + +.. + +.. date: 2023-01-02-22-41-44 +.. gh-issue: 99138 +.. nonce: 17hp9U +.. section: Library + +Apply :pep:`687` to :mod:`zoneinfo`. Patch by Erlend E. Aasland. + +.. + +.. date: 2022-10-22-09-26-43 +.. gh-issue: 96764 +.. nonce: Dh9Y5L +.. section: Library + +:func:`asyncio.wait_for` now uses :func:`asyncio.timeout` as its underlying +implementation. Patch by Kumar Aditya. + +.. + +.. date: 2022-09-05-12-17-34 +.. gh-issue: 88233 +.. nonce: gff9qJ +.. section: Library + +Correctly preserve "extra" fields in ``zipfile`` regardless of their +ordering relative to a zip64 "extra." + +.. + +.. bpo: 23224 +.. date: 2018-06-20-09-12-21 +.. nonce: zxCQ13 +.. section: Library + +Fix segfaults when creating :class:`lzma.LZMADecompressor` and +:class:`bz2.BZ2Decompressor` objects without calling ``__init__()``, and fix +leakage of locks and internal buffers when calling the ``__init__()`` +methods of :class:`lzma.LZMADecompressor`, :class:`lzma.LZMACompressor`, +:class:`bz2.BZ2Compressor`, and :class:`bz2.BZ2Decompressor` objects +multiple times. + +.. + +.. date: 2023-02-19-10-33-01 +.. gh-issue: 85417 +.. nonce: kYO8u3 +.. section: Documentation + +Update :mod:`cmath` documentation to clarify behaviour on branch cuts. + +.. + +.. date: 2023-02-07-21-43-24 +.. gh-issue: 97725 +.. nonce: cuY7Cd +.. section: Documentation + +Fix :meth:`asyncio.Task.print_stack` description for ``file=None``. Patch by +Oleg Iarygin. + +.. + +.. date: 2023-02-18-10-51-02 +.. gh-issue: 102019 +.. nonce: 0797SJ +.. section: Tests + +Fix deadlock on shutdown if ``test_current_{exception,frames}`` fails. Patch +by Jacob Bower. + +.. + +.. date: 2023-02-11-22-36-10 +.. gh-issue: 85984 +.. nonce: EVXjT9 +.. section: Tests + +Utilize new "winsize" functions from termios in pty tests. + +.. + +.. date: 2023-02-11-20-28-08 +.. gh-issue: 89792 +.. nonce: S-Y5BZ +.. section: Tests + +``test_tools`` now copies up to 10x less source data to a temporary +directory during the ``freeze`` test by ignoring git metadata and other +artifacts. It also limits its python build parallelism based on +os.cpu_count instead of hard coding it as 8 cores. + +.. + +.. date: 2023-01-12-00-49-16 +.. gh-issue: 99942 +.. nonce: DUR8b4 +.. section: Build + +On Android, in a static build, python-config in embed mode no longer +incorrectly reports a library to link to. + +.. + +.. date: 2022-12-20-01-06-17 +.. gh-issue: 99942 +.. nonce: lbmzYj +.. section: Build + +On Android, python.pc now correctly reports the library to link to, the same +as python-config.sh. + +.. + +.. date: 2022-12-18-08-33-28 +.. gh-issue: 100221 +.. nonce: K94Ct3 +.. section: Build + +Fix creating install directories in ``make sharedinstall`` if they exist +outside ``DESTDIR`` already. + +.. + +.. date: 2022-09-14-10-38-15 +.. gh-issue: 96821 +.. nonce: Zk2a9c +.. section: Build + +Explicitly mark C extension modules that need defined signed integer +overflow, and add a configure option :option:`--with-strict-overflow`. Patch +by Matthias Görgens and Shantanu Jain. + +.. + +.. date: 2023-03-01-01-36-39 +.. gh-issue: 102344 +.. nonce: Dgfux4 +.. section: Windows + +Implement ``winreg.QueryValue`` using ``QueryValueEx`` and +``winreg.SetValue`` using ``SetValueEx``. Patch by Max Bachmann. + +.. + +.. date: 2023-02-15-11-08-10 +.. gh-issue: 101881 +.. nonce: fScr3m +.. section: Windows + +Handle read and write operations on non-blocking pipes properly on Windows. + +.. + +.. date: 2023-02-13-18-05-49 +.. gh-issue: 101881 +.. nonce: _TnHzN +.. section: Windows + +Add support for the os.get_blocking() and os.set_blocking() functions on +Windows. + +.. + +.. date: 2023-02-13-16-32-50 +.. gh-issue: 101849 +.. nonce: 7lm_53 +.. section: Windows + +Ensures installer will correctly upgrade existing ``py.exe`` launcher +installs. + +.. + +.. date: 2023-02-10-14-26-05 +.. gh-issue: 101763 +.. nonce: RPaj7r +.. section: Windows + +Updates copy of libffi bundled with Windows installs to 3.4.4. + +.. + +.. date: 2023-02-09-22-09-27 +.. gh-issue: 101759 +.. nonce: zFlqSH +.. section: Windows + +Update Windows installer to SQLite 3.40.1. + +.. + +.. date: 2023-02-07-18-22-54 +.. gh-issue: 101614 +.. nonce: NjVP0n +.. section: Windows + +Correctly handle extensions built against debug binaries that reference +``python3_d.dll``. + +.. + +.. date: 2023-01-25-11-33-54 +.. gh-issue: 101196 +.. nonce: wAX_2g +.. section: Windows + +The functions ``os.path.isdir``, ``os.path.isfile``, ``os.path.islink`` and +``os.path.exists`` are now 13% to 28% faster on Windows, by making fewer +Win32 API calls. + +.. + +.. date: 2023-02-09-22-07-17 +.. gh-issue: 101759 +.. nonce: B0JP2H +.. section: macOS + +Update macOS installer to SQLite 3.40.1. + +.. + +.. date: 2023-02-14-15-53-01 +.. gh-issue: 101907 +.. nonce: HgF1N2 +.. section: C API + +Removes use of non-standard C++ extension in public header files. + +.. + +.. date: 2023-02-09-10-38-20 +.. gh-issue: 99293 +.. nonce: mFqfpp +.. section: C API + +Document that the Py_TPFLAGS_VALID_VERSION_TAG is an internal feature, +should not be used, and will be removed. + +.. + +.. date: 2023-02-06-16-14-30 +.. gh-issue: 101578 +.. nonce: PW5fA9 +.. section: C API + +Add :c:func:`PyErr_GetRaisedException` and +:c:func:`PyErr_SetRaisedException` for saving and restoring the current +exception. These functions return and accept a single exception object, +rather than the triple arguments of the now-deprecated :c:func:`PyErr_Fetch` +and :c:func:`PyErr_Restore`. This is less error prone and a bit more +efficient. + +Add :c:func:`PyException_GetArgs` and :c:func:`PyException_SetArgs` as +convenience functions for retrieving and modifying the +:attr:`~BaseException.args` passed to the exception's constructor. + +.. + +.. date: 2022-04-21-17-25-22 +.. gh-issue: 91744 +.. nonce: FgvaMi +.. section: C API + +Introduced the *Unstable C API tier*, marking APi that is allowed to change +in minor releases without a deprecation period. See :pep:`689` for details. diff --git a/Misc/NEWS.d/3.12.0a7.rst b/Misc/NEWS.d/3.12.0a7.rst new file mode 100644 index 00000000..1ef81747 --- /dev/null +++ b/Misc/NEWS.d/3.12.0a7.rst @@ -0,0 +1,745 @@ +.. date: 2023-03-31-12-22-25 +.. gh-issue: 102192 +.. nonce: gYxJP_ +.. release date: 2023-04-04 +.. section: Core and Builtins + +Deprecated ``_PyErr_ChainExceptions`` in favour of +``_PyErr_ChainExceptions1``. + +.. + +.. date: 2023-03-24-02-50-33 +.. gh-issue: 89987 +.. nonce: oraTzh +.. section: Core and Builtins + +Reduce the number of inline :opcode:`CACHE` entries for +:opcode:`BINARY_SUBSCR`. + +.. + +.. date: 2023-03-21-00-46-36 +.. gh-issue: 102859 +.. nonce: PRkGca +.. section: Core and Builtins + +Removed :opcode:`JUMP_IF_FALSE_OR_POP` and :opcode:`JUMP_IF_TRUE_OR_POP` +instructions. + +.. + +.. date: 2023-03-18-02-36-39 +.. gh-issue: 101975 +.. nonce: HwMR1d +.. section: Core and Builtins + +Fixed ``stacktop`` value on tracing entries to avoid corruption on garbage +collection. + +.. + +.. date: 2023-03-17-13-43-34 +.. gh-issue: 102778 +.. nonce: ANDv8I +.. section: Core and Builtins + +Add :data:`sys.last_exc` and deprecate :data:`sys.last_type`, +:data:`sys.last_value` and :data:`sys.last_traceback`, which hold the same +information in its legacy form. + +.. + +.. date: 2023-03-17-12-09-45 +.. gh-issue: 100982 +.. nonce: Pf_BI6 +.. section: Core and Builtins + +Replace all occurrences of ``COMPARE_AND_BRANCH`` with :opcode:`COMPARE_OP`. + +.. + +.. date: 2023-03-16-17-24-44 +.. gh-issue: 102701 +.. nonce: iNGVaS +.. section: Core and Builtins + +Fix overflow when creating very large dict. + +.. + +.. date: 2023-03-16-14-44-29 +.. gh-issue: 102755 +.. nonce: j1GxlV +.. section: Core and Builtins + +Add :c:func:`PyErr_DisplayException` which takes just an exception instance, +to replace the legacy :c:func:`PyErr_Display` which takes the ``(typ, exc, +tb)`` triplet. + +.. + +.. date: 2023-03-14-00-11-46 +.. gh-issue: 102594 +.. nonce: BjU-m2 +.. section: Core and Builtins + +Add note to exception raised in ``PyErr_SetObject`` when normalization +fails. + +.. + +.. date: 2023-03-09-13-57-35 +.. gh-issue: 90997 +.. nonce: J-Yhn2 +.. section: Core and Builtins + +Shrink the number of inline :opcode:`CACHE` entries used by +:opcode:`LOAD_GLOBAL`. + +.. + +.. date: 2023-03-08-08-37-36 +.. gh-issue: 102491 +.. nonce: SFvvsC +.. section: Core and Builtins + +Improve import time of ``platform`` by removing IronPython version parsing. +The IronPython version parsing was not functional (see +https://github.com/IronLanguages/ironpython3/issues/1667). + +.. + +.. date: 2023-03-06-10-02-22 +.. gh-issue: 101291 +.. nonce: 0FT2QS +.. section: Core and Builtins + +Rearrage bits in first field (after header) of PyLongObject. * Bits 0 and 1: +1 - sign. I.e. 0 for positive numbers, 1 for zero and 2 for negative +numbers. * Bit 2 reserved (probably for the immortal bit) * Bits 3+ the +unsigned size. + +This makes a few operations slightly more efficient, and will enable a more +compact and faster 2s-complement representation of most ints in future. + +.. + +.. date: 2023-03-04-06-48-34 +.. gh-issue: 102397 +.. nonce: ACJaOf +.. section: Core and Builtins + +Fix segfault from race condition in signal handling during garbage +collection. Patch by Kumar Aditya. + +.. + +.. date: 2023-03-03-23-21-16 +.. gh-issue: 102406 +.. nonce: XLqYO3 +.. section: Core and Builtins + +:mod:`codecs` encoding/decoding errors now get the context information +(which operation and which codecs) attached as :pep:`678` notes instead of +through chaining a new instance of the exception. + +.. + +.. date: 2023-03-02-13-49-21 +.. gh-issue: 102281 +.. nonce: QCuu2N +.. section: Core and Builtins + +Fix potential nullptr dereference and use of uninitialized memory in +fileutils. Patch by Max Bachmann. + +.. + +.. date: 2023-02-27-15-48-31 +.. gh-issue: 102300 +.. nonce: 8o-_Mt +.. section: Core and Builtins + +Reuse operands with refcount of 1 in float specializations of BINARY_OP. + +.. + +.. date: 2023-02-26-13-12-55 +.. gh-issue: 102213 +.. nonce: fTH8X7 +.. section: Core and Builtins + +Fix performance loss when accessing an object's attributes with +``__getattr__`` defined. + +.. + +.. date: 2023-02-26-11-43-56 +.. gh-issue: 102255 +.. nonce: cRnI5x +.. section: Core and Builtins + +Improve build support for the Xbox. Patch by Max Bachmann. + +.. + +.. date: 2023-02-21-23-42-39 +.. gh-issue: 102027 +.. nonce: fQARG0 +.. section: Core and Builtins + +Fix SSE2 and SSE3 detection in ``_blake2`` internal module. Patch by Max +Bachmann. + +.. + +.. date: 2023-02-21-17-22-06 +.. gh-issue: 101865 +.. nonce: fwrTOA +.. section: Core and Builtins + +Deprecate ``co_lnotab`` in code objects, schedule it for removal in Python +3.14 + +.. + +.. bpo: 1635741 +.. date: 2020-07-04-09-04-41 +.. nonce: ZsP31Y +.. section: Core and Builtins + +Adapt :mod:`!_pickle` to :pep:`687`. Patch by Mohamed Koubaa and Erlend +Aasland. + +.. + +.. date: 2023-03-28-15-12-53 +.. gh-issue: 103085 +.. nonce: DqNehf +.. section: Library + +Pure python :func:`locale.getencoding()` will not warn deprecation. + +.. + +.. date: 2023-03-28-05-14-59 +.. gh-issue: 103068 +.. nonce: YQTmrA +.. section: Library + +It's no longer possible to register conditional breakpoints in +:class:`~pdb.Pdb` that raise :exc:`SyntaxError`. Patch by Tian Gao. + +.. + +.. date: 2023-03-27-19-21-51 +.. gh-issue: 102549 +.. nonce: NQ6Nlv +.. section: Library + +Don't ignore exceptions in member type creation. + +.. + +.. date: 2023-03-27-15-01-16 +.. gh-issue: 103056 +.. nonce: -Efh5Q +.. section: Library + +Ensure final ``_generate_next_value_`` is a ``staticmethod``. + +.. + +.. date: 2023-03-26-20-54-57 +.. gh-issue: 103046 +.. nonce: xBlA2l +.. section: Library + +Display current line label correctly in :mod:`dis` when ``show_caches`` is +False and ``lasti`` points to a CACHE entry. + +.. + +.. date: 2023-03-25-16-57-18 +.. gh-issue: 102433 +.. nonce: L-7x2Q +.. section: Library + +:func:`isinstance` checks against :func:`runtime-checkable protocols +<typing.runtime_checkable>` now use :func:`inspect.getattr_static` rather +than :func:`hasattr` to lookup whether attributes exist. This means that +descriptors and :meth:`~object.__getattr__` methods are no longer +unexpectedly evaluated during ``isinstance()`` checks against +runtime-checkable protocols. However, it may also mean that some objects +which used to be considered instances of a runtime-checkable protocol may no +longer be considered instances of that protocol on Python 3.12+, and vice +versa. Most users are unlikely to be affected by this change. Patch by Alex +Waygood. + +.. + +.. date: 2023-03-25-02-08-05 +.. gh-issue: 103023 +.. nonce: Qfn7Hl +.. section: Library + +It's no longer possible to register expressions to display in +:class:`~pdb.Pdb` that raise :exc:`SyntaxError`. Patch by Tian Gao. + +.. + +.. date: 2023-03-23-13-34-33 +.. gh-issue: 102947 +.. nonce: cTwcpU +.. section: Library + +Improve traceback when :func:`dataclasses.fields` is called on a +non-dataclass. Patch by Alex Waygood + +.. + +.. date: 2023-03-22-16-15-18 +.. gh-issue: 102780 +.. nonce: NEcljy +.. section: Library + +The :class:`asyncio.Timeout` context manager now works reliably even when +performing cleanup due to task cancellation. Previously it could raise a +:exc:`~asyncio.CancelledError` instead of an :exc:`~asyncio.TimeoutError` in +such cases. + +.. + +.. date: 2023-03-21-15-17-07 +.. gh-issue: 102871 +.. nonce: U9mchn +.. section: Library + +Remove support for obsolete browsers from :mod:`webbrowser`. Removed +browsers include Grail, Mosaic, Netscape, Galeon, Skipstone, Iceape, +Firebird, and Firefox versions 35 and below. + +.. + +.. date: 2023-03-20-12-21-19 +.. gh-issue: 102839 +.. nonce: RjRi12 +.. section: Library + +Improve performance of :func:`math.log` arguments handling by removing the +argument clinic. + +.. + +.. date: 2023-03-19-15-30-59 +.. gh-issue: 102828 +.. nonce: NKClXg +.. section: Library + +Add the ``onexc`` arg to :func:`shutil.rmtree`, which is like ``onerror`` +but expects an exception instance rather than an exc_info tuple. Deprecate +``onerror``. + +.. + +.. date: 2023-03-18-14-59-21 +.. gh-issue: 88965 +.. nonce: kA70Km +.. section: Library + +typing: Fix a bug relating to substitution in custom classes generic over a +:class:`~typing.ParamSpec`. Previously, if the ``ParamSpec`` was substituted +with a parameters list that itself contained a :class:`~typing.TypeVar`, the +``TypeVar`` in the parameters list could not be subsequently substituted. +This is now fixed. + +Patch by Nikita Sobolev. + +.. + +.. date: 2023-03-17-19-14-26 +.. gh-issue: 76846 +.. nonce: KEamjK +.. section: Library + +Fix issue where ``__new__()`` and ``__init__()`` methods of +:class:`pathlib.PurePath` and :class:`~pathlib.Path` subclasses were not +called in some circumstances. + +.. + +.. date: 2023-03-16-16-43-04 +.. gh-issue: 78530 +.. nonce: Lr8eq_ +.. section: Library + +:func:`asyncio.wait` now accepts generators yielding tasks. Patch by Kumar +Aditya. + +.. + +.. date: 2023-03-16-08-17-29 +.. gh-issue: 102748 +.. nonce: WNACpI +.. section: Library + +:func:`asyncio.iscoroutine` now returns ``False`` for generators as +:mod:`asyncio` does not support legacy generator-based coroutines. Patch by +Kumar Aditya. + +.. + +.. date: 2023-03-13-18-27-00 +.. gh-issue: 102670 +.. nonce: GyoThv +.. section: Library + +Optimized fmean(), correlation(), covariance(), and linear_regression() +using the new math.sumprod() function. + +.. + +.. date: 2023-03-13-12-05-55 +.. gh-issue: 102615 +.. nonce: NcA_ZL +.. section: Library + +Typing: Improve the ``repr`` of generic aliases for classes generic over a +:class:`~typing.ParamSpec`. (Use square brackets to represent a parameter +list.) + +.. + +.. date: 2023-03-10-13-51-21 +.. gh-issue: 100112 +.. nonce: VHh4mw +.. section: Library + +:meth:`asyncio.Task.get_coro` now always returns a coroutine when wrapping +an awaitable object. Patch by Kumar Aditya. + +.. + +.. date: 2023-03-10-13-21-16 +.. gh-issue: 102578 +.. nonce: -gujoI +.. section: Library + +Speed up setting or deleting mutable attributes on non-dataclass subclasses +of frozen dataclasses. Due to the implementation of ``__setattr__`` and +``__delattr__`` for frozen dataclasses, this previously had a time +complexity of ``O(n)``. It now has a time complexity of ``O(1)``. + +.. + +.. date: 2023-03-08-23-08-38 +.. gh-issue: 102519 +.. nonce: wlcsFI +.. section: Library + +Add :func:`os.listdrives`, :func:`os.listvolumes` and :func:`os.listmounts` +functions on Windows for enumerating drives, volumes and mount points + +.. + +.. date: 2023-03-04-20-58-29 +.. gh-issue: 74468 +.. nonce: Ac5Ew_ +.. section: Library + +Attribute name of the extracted :mod:`tarfile` file object now holds +filename of itself rather than of the archive it is contained in. Patch by +Oleg Iarygin. + +.. + +.. date: 2023-03-03-19-53-08 +.. gh-issue: 102378 +.. nonce: kRdOZc +.. section: Library + +Private helper method ``inspect._signature_strip_non_python_syntax`` will no +longer strip ``/`` from the input string. + +.. + +.. date: 2023-02-26-17-29-57 +.. gh-issue: 79940 +.. nonce: SAfmAy +.. section: Library + +Add :func:`inspect.getasyncgenstate` and :func:`inspect.getasyncgenlocals`. +Patch by Thomas Krennwallner. + +.. + +.. date: 2023-02-21-11-56-16 +.. gh-issue: 102103 +.. nonce: Dj0WEj +.. section: Library + +Add ``module`` argument to :func:`dataclasses.make_dataclass` and make +classes produced by it pickleable. + +.. + +.. date: 2023-02-20-16-47-56 +.. gh-issue: 102069 +.. nonce: FS7f1j +.. section: Library + +Fix ``__weakref__`` descriptor generation for custom dataclasses. + +.. + +.. date: 2023-02-19-01-49-46 +.. gh-issue: 102038 +.. nonce: n3if3D +.. section: Library + +Skip a ``stat`` in :mod:`site` if we have already found a ``pyvenv.cfg`` + +.. + +.. date: 2023-02-18-23-03-50 +.. gh-issue: 98886 +.. nonce: LkKGWv +.. section: Library + +Fix issues when defining dataclasses that have fields with specific +underscore names that aren't clearly reserved by :mod:`dataclasses`. + +.. + +.. date: 2023-02-09-19-40-41 +.. gh-issue: 101673 +.. nonce: mX-Ppq +.. section: Library + +Fix a :mod:`pdb` bug where ``ll`` clears the changes to local variables. + +.. + +.. date: 2023-01-27-14-51-07 +.. gh-issue: 101313 +.. nonce: 10AEXh +.. section: Library + +Added -h and --help arguments to the webbrowser CLI + +.. + +.. date: 2022-12-20-10-55-14 +.. gh-issue: 100372 +.. nonce: utfP65 +.. section: Library + +:meth:`ssl.SSLContext.load_verify_locations` no longer incorrectly accepts +some cases of trailing data when parsing DER. + +.. + +.. date: 2022-12-16-10-27-58 +.. gh-issue: 89727 +.. nonce: y64ZLM +.. section: Library + +Fix pathlib.Path.walk RecursionError on deep directory trees by rewriting it +using iteration instead of recursion. + +.. + +.. date: 2022-12-09-11-21-38 +.. gh-issue: 100131 +.. nonce: v863yR +.. section: Library + +Added an optional ``delete`` keyword argument to +:class:`tempfile.TemporaryDirectory`. + +.. + +.. date: 2022-11-24-13-23-07 +.. gh-issue: 48330 +.. nonce: 6uAX9F +.. section: Library + +Added ``--durations`` command line option, showing the N slowest test cases. +:class:`unittest.TextTestRunner` and :class:`unittest.TextTestResult` +constructors accept a new *durations* keyword argument. Subclasses should +take this into account or accept ``**kwargs``. Added +:meth:`unittest.TestResult.addDuration` method and +:attr:`unittest.TestResult.collectedDurations` attribute. + +(Contributed by Giampaolo Rodola) + +.. + +.. date: 2022-10-10-19-14-51 +.. gh-issue: 98169 +.. nonce: DBWIxL +.. section: Library + +Fix :func:`dataclasses.astuple` crash when :class:`collections.defaultdict` +is present in the attributes. + +.. + +.. date: 2022-09-19-08-12-58 +.. gh-issue: 96931 +.. nonce: x0WQhh +.. section: Library + +Fix incorrect results from :meth:`ssl.SSLSocket.shared_ciphers` + +.. + +.. date: 2022-07-30-23-01-43 +.. gh-issue: 95495 +.. nonce: RA-q1d +.. section: Library + +When built against OpenSSL 3.0, the :mod:`ssl` module had a bug where it +reported unauthenticated EOFs (i.e. without close_notify) as a clean +TLS-level EOF. It now raises :exc:`~ssl.SSLEOFError`, matching the behavior +in previous versions of OpenSSL. The :attr:`~ssl.SSLContext.options` +attribute on :class:`~ssl.SSLContext` also no longer includes +:const:`~ssl.OP_IGNORE_UNEXPECTED_EOF` by default. This option may be set to +specify the previous OpenSSL 3.0 behavior. + +.. + +.. date: 2022-07-09-13-07-30 +.. gh-issue: 94684 +.. nonce: nV5yno +.. section: Library + +Now :func:`uuid.uuid3` and :func:`uuid.uuid5` functions support +:class:`bytes` objects as their *name* argument. + +.. + +.. date: 2022-06-30-21-28-41 +.. gh-issue: 94440 +.. nonce: LtgX0d +.. section: Library + +Fix a :mod:`concurrent.futures.process` bug where ``ProcessPoolExecutor`` +shutdown could hang after a future has been quickly submitted and canceled. + +.. + +.. date: 2022-04-11-18-34-33 +.. gh-issue: 72346 +.. nonce: pC7gnM +.. section: Library + +Added deprecation warning to *isdst* parameter of +:func:`email.utils.localtime`. + +.. + +.. bpo: 36305 +.. date: 2019-03-15-22-50-27 +.. nonce: Pbkv6u +.. section: Library + +Fix handling of Windows filenames that resemble drives, such as ``./a:b``, +in :mod:`pathlib`. + +.. + +.. date: 2023-03-29-14-51-39 +.. gh-issue: 103112 +.. nonce: XgGSEO +.. section: Documentation + +Add docstring to :meth:`http.client.HTTPResponse.read` to fix ``pydoc`` +output. + +.. + +.. date: 2023-03-23-23-25-18 +.. gh-issue: 102980 +.. nonce: Zps4QF +.. section: Tests + +Improve test coverage on :mod:`pdb`. + +.. + +.. date: 2023-03-08-13-54-20 +.. gh-issue: 102537 +.. nonce: Vfplpb +.. section: Tests + +Adjust the error handling strategy in +``test_zoneinfo.TzPathTest.python_tzpath_context``. Patch by Paul Ganssle. + +.. + +.. date: 2023-01-27-18-10-40 +.. gh-issue: 101377 +.. nonce: IJGpqh +.. section: Tests + +Improved test_locale_calendar_formatweekday of calendar. + +.. + +.. date: 2023-03-23-20-58-56 +.. gh-issue: 102973 +.. nonce: EaJUrw +.. section: Build + +Add a dev container (along with accompanying Dockerfile) for development +purposes. + +.. + +.. date: 2023-03-15-02-03-39 +.. gh-issue: 102711 +.. nonce: zTkjts +.. section: Build + +Fix ``-Wstrict-prototypes`` compiler warnings. + +.. + +.. date: 2023-03-14-10-52-43 +.. gh-issue: 102690 +.. nonce: sbXtqk +.. section: Windows + +Update :mod:`webbrowser` to fall back to Microsoft Edge instead of Internet +Explorer. + +.. + +.. date: 2023-02-22-17-26-10 +.. gh-issue: 99726 +.. nonce: 76t957 +.. section: Windows + +Improves correctness of stat results for Windows, and uses faster API when +available + +.. + +.. date: 2023-03-21-01-27-07 +.. gh-issue: 102809 +.. nonce: 2F1Byz +.. section: Tools/Demos + +``Misc/gdbinit`` was removed. + +.. + +.. date: 2023-02-18-00-55-14 +.. gh-issue: 102013 +.. nonce: 83mrtI +.. section: C API + +Add a new (unstable) C-API function for iterating over GC'able objects using +a callback: ``PyUnstable_VisitObjects``. diff --git a/Misc/NEWS.d/3.12.0b1.rst b/Misc/NEWS.d/3.12.0b1.rst new file mode 100644 index 00000000..4bd2c52b --- /dev/null +++ b/Misc/NEWS.d/3.12.0b1.rst @@ -0,0 +1,2402 @@ +.. date: 2023-05-02-17-56-32 +.. gh-issue: 99889 +.. nonce: l664SU +.. release date: 2023-05-22 +.. section: Security + +Fixed a security in flaw in :func:`uu.decode` that could allow for directory +traversal based on the input if no ``out_file`` was specified. + +.. + +.. date: 2023-05-01-15-03-25 +.. gh-issue: 104049 +.. nonce: b01Y3g +.. section: Security + +Do not expose the local on-disk location in directory indexes produced by +:class:`http.client.SimpleHTTPRequestHandler`. + +.. + +.. date: 2023-04-17-14-38-12 +.. gh-issue: 99108 +.. nonce: 720lG8 +.. section: Security + +Upgrade built-in :mod:`hashlib` SHA3 implementation to a verified +implementation from the ``HACL*`` project. Used when OpenSSL is not present +or lacks SHA3. + +.. + +.. date: 2023-03-07-20-59-17 +.. gh-issue: 102153 +.. nonce: 14CLSZ +.. section: Security + +:func:`urllib.parse.urlsplit` now strips leading C0 control and space +characters following the specification for URLs defined by WHATWG in +response to CVE-2023-24329. Patch by Illia Volochii. + +.. + +.. date: 2023-05-20-23-08-48 +.. gh-issue: 102856 +.. nonce: Knv9WT +.. section: Core and Builtins + +Implement PEP 701 changes in the :mod:`tokenize` module. Patch by Marta +Gómez Macías and Pablo Galindo Salgado + +.. + +.. date: 2023-05-18-13-00-21 +.. gh-issue: 104615 +.. nonce: h_rtw2 +.. section: Core and Builtins + +Fix wrong ordering of assignments in code like ``a, a = x, y``. Contributed +by Carl Meyer. + +.. + +.. date: 2023-05-16-19-17-48 +.. gh-issue: 104572 +.. nonce: eBZQYS +.. section: Core and Builtins + +Improve syntax error message for invalid constructs in :pep:`695` contexts +and in annotations when ``from __future__ import annotations`` is active. + +.. + +.. date: 2023-05-14-18-56-54 +.. gh-issue: 104482 +.. nonce: yaQsv8 +.. section: Core and Builtins + +Fix three error handling bugs in ast.c's validation of pattern matching +statements. + +.. + +.. date: 2023-05-12-13-30-04 +.. gh-issue: 102818 +.. nonce: rnv1mH +.. section: Core and Builtins + +Do not add a frame to the traceback in the ``sys.setprofile`` and +``sys.settrace`` trampoline functions. This ensures that frames are not +duplicated if an exception is raised in the callback function, and ensures +that frames are not omitted if a C callback is used and that does not add +the frame. + +.. + +.. date: 2023-05-11-15-56-07 +.. gh-issue: 104405 +.. nonce: tXV5fn +.. section: Core and Builtins + +Fix an issue where some :term:`bytecode` instructions could ignore +:pep:`523` when "inlining" calls. + +.. + +.. date: 2023-05-10-20-52-29 +.. gh-issue: 103082 +.. nonce: y3LG5Q +.. section: Core and Builtins + +Change behavior of ``sys.monitoring.events.LINE`` events in +``sys.monitoring``: Line events now occur when a new line is reached +dynamically, instead of using a static approximation, as before. This makes +the behavior very similar to that of "line" events in ``sys.settrace``. This +should ease porting of tools from 3.11 to 3.12. + +.. + +.. date: 2023-05-08-10-34-55 +.. gh-issue: 104263 +.. nonce: ctHWI8 +.. section: Core and Builtins + +Fix ``float("nan")`` to produce a quiet NaN on platforms (like MIPS) where +the meaning of the signalling / quiet bit is inverted from its usual +meaning. Also introduce a new macro ``Py_INFINITY`` matching C99's +``INFINITY``, and refactor internals to rely on C99's ``NAN`` and +``INFINITY`` macros instead of hard-coding bit patterns for infinities and +NaNs. Thanks Sebastian Berg. + +.. + +.. date: 2023-05-05-13-18-56 +.. gh-issue: 99113 +.. nonce: hT1ajK +.. section: Core and Builtins + +Multi-phase init extension modules may now indicate that they support +running in subinterpreters that have their own GIL. This is done by using +``Py_MOD_PER_INTERPRETER_GIL_SUPPORTED`` as the value for the +``Py_mod_multiple_interpreters`` module def slot. Otherwise the module, by +default, cannot be imported in such subinterpreters. (This does not affect +the main interpreter or subinterpreters that do not have their own GIL.) In +addition to the isolation that multi-phase init already normally requires, +support for per-interpreter GIL involves one additional constraint: +thread-safety. If the module has external (linked) dependencies and those +libraries have any state that isn't thread-safe then the module must do the +additional work to add thread-safety. This should be an uncommon case. + +.. + +.. date: 2023-05-05-12-14-47 +.. gh-issue: 99113 +.. nonce: -RAdnv +.. section: Core and Builtins + +The GIL is now (optionally) per-interpreter. This is the fundamental change +for PEP 684. This is all made possible by virtue of the isolated state of +each interpreter in the process. The behavior of the main interpreter +remains unchanged. Likewise, interpreters created using +``Py_NewInterpreter()`` are not affected. To get an interpreter with its +own GIL, call ``Py_NewInterpreterFromConfig()``. + +.. + +.. date: 2023-05-03-17-46-47 +.. gh-issue: 104108 +.. nonce: GOxAYt +.. section: Core and Builtins + +Multi-phase init extension modules may now indicate whether or not they +actually support multiple interpreters. By default such modules are +expected to support use in multiple interpreters. In the uncommon case that +one does not, it may use the new ``Py_mod_multiple_interpreters`` module def +slot. A value of ``0`` means the module does not support them. ``1`` means +it does. The default is ``1``. + +.. + +.. date: 2023-05-02-18-29-49 +.. gh-issue: 104142 +.. nonce: _5Et6I +.. section: Core and Builtins + +Fix an issue where :class:`list` or :class:`tuple` repetition could fail to +respect :pep:`683`. + +.. + +.. date: 2023-05-01-21-05-47 +.. gh-issue: 104078 +.. nonce: vRaBsU +.. section: Core and Builtins + +Improve the performance of :c:func:`PyObject_HasAttrString` + +.. + +.. date: 2023-05-01-14-48-29 +.. gh-issue: 104066 +.. nonce: pzoUZQ +.. section: Core and Builtins + +Improve the performance of :func:`hasattr` for module objects with a missing +attribute. + +.. + +.. date: 2023-05-01-14-10-38 +.. gh-issue: 104028 +.. nonce: dxfh13 +.. section: Core and Builtins + +Reduce object creation while calling callback function from gc. Patch by +Donghee Na. + +.. + +.. date: 2023-05-01-12-03-52 +.. gh-issue: 104018 +.. nonce: PFxGS4 +.. section: Core and Builtins + +Disallow the "z" format specifier in %-format of bytes objects. + +.. + +.. date: 2023-05-01-08-08-05 +.. gh-issue: 102213 +.. nonce: nfH-4C +.. section: Core and Builtins + +Fix performance loss when accessing an object's attributes with +``__getattr__`` defined. + +.. + +.. date: 2023-04-26-17-56-18 +.. gh-issue: 103895 +.. nonce: ESB6tn +.. section: Core and Builtins + +Improve handling of edge cases in showing ``Exception.__notes__``. Ensures +that the messages always end with a newline and that string/bytes are not +exploded over multiple lines. Patch by Carey Metcalfe. + +.. + +.. date: 2023-04-26-16-26-35 +.. gh-issue: 103907 +.. nonce: kiONZQ +.. section: Core and Builtins + +Don't modify the refcounts of known immortal objects (:const:`True`, +:const:`False`, and :const:`None`) in the main interpreter loop. + +.. + +.. date: 2023-04-26-15-14-23 +.. gh-issue: 103899 +.. nonce: 1pqKPF +.. section: Core and Builtins + +Provide a helpful hint in the :exc:`TypeError` message when accidentally +calling a :term:`module` object that has a callable attribute of the same +name (such as :func:`dis.dis` or :class:`datetime.datetime`). + +.. + +.. date: 2023-04-25-20-56-01 +.. gh-issue: 103845 +.. nonce: V7NYFn +.. section: Core and Builtins + +Remove both line and instruction instrumentation before adding new ones for +monitoring, to avoid newly added instrumentation being removed immediately. + +.. + +.. date: 2023-04-25-08-43-11 +.. gh-issue: 103763 +.. nonce: ZLBZk1 +.. section: Core and Builtins + +Implement :pep:`695`, adding syntactic support for generic classes, generic +functions, and type aliases. + +A new ``type X = ...`` syntax is added for type aliases, which resolves at +runtime to an instance of the new class ``typing.TypeAliasType``. The value +is lazily evaluated and is accessible through the ``.__value__`` attribute. +This is implemented as a new AST node ``ast.TypeAlias``. + +New syntax (``class X[T]: ...``, ``def func[T](): ...``) is added for +defining generic functions and classes. This is implemented as a new +``type_params`` attribute on the AST nodes for classes and functions. This +node holds instances of the new AST classes ``ast.TypeVar``, +``ast.ParamSpec``, and ``ast.TypeVarTuple``. + +``typing.TypeVar``, ``typing.ParamSpec``, ``typing.ParamSpecArgs``, +``typing.ParamSpecKwargs``, ``typing.TypeVarTuple``, and ``typing.Generic`` +are now implemented in C rather than Python. + +There are new bytecode instructions ``LOAD_LOCALS``, +``LOAD_CLASSDICT_OR_GLOBAL``, and ``LOAD_CLASSDICT_OR_DEREF`` to support +correct resolution of names in class namespaces. + +Patch by Eric Traut, Larry Hastings, and Jelle Zijlstra. + +.. + +.. date: 2023-04-24-21-47-38 +.. gh-issue: 103801 +.. nonce: WaBanq +.. section: Core and Builtins + +Adds three minor linting fixes to the wasm module caught that were caught by +ruff. + +.. + +.. date: 2023-04-24-14-38-16 +.. gh-issue: 103793 +.. nonce: kqoH6Q +.. section: Core and Builtins + +Optimized asyncio Task creation by deferring expensive string formatting +(task name generation) from Task creation to the first time ``get_name`` is +called. This makes asyncio benchmarks up to 5% faster. + +.. + +.. date: 2023-04-21-17-03-14 +.. gh-issue: 102310 +.. nonce: anLjDx +.. section: Core and Builtins + +Change the error range for invalid bytes literals. + +.. + +.. date: 2023-04-21-16-12-41 +.. gh-issue: 103590 +.. nonce: 7DHDOE +.. section: Core and Builtins + +Do not wrap a single exception raised from a ``try-except*`` construct in an +:exc:`ExceptionGroup`. + +.. + +.. date: 2023-04-20-16-17-51 +.. gh-issue: 103650 +.. nonce: K1MFXR +.. section: Core and Builtins + +Change the perf map format to remove the '0x' prefix from the addresses + +.. + +.. date: 2023-04-17-16-00-32 +.. gh-issue: 102856 +.. nonce: UunJ7y +.. section: Core and Builtins + +Implement the required C tokenizer changes for PEP 701. Patch by Pablo +Galindo Salgado, Lysandros Nikolaou, Batuhan Taskaya, Marta Gómez Macías and +sunmy2019. + +.. + +.. date: 2023-04-16-14-38-39 +.. gh-issue: 100530 +.. nonce: OR6-sn +.. section: Core and Builtins + +Clarify the error message raised when the called part of a class pattern +isn't actually a class. + +.. + +.. date: 2023-04-14-22-35-23 +.. gh-issue: 101517 +.. nonce: 5EqM-S +.. section: Core and Builtins + +Fix bug in line numbers of instructions emitted for :keyword:`except* +<except_star>`. + +.. + +.. date: 2023-04-13-00-58-55 +.. gh-issue: 103492 +.. nonce: P4k0Ay +.. section: Core and Builtins + +Clarify :exc:`SyntaxWarning` with literal ``is`` comparison by specifying +which literal is problematic, since comparisons using ``is`` with e.g. None +and bool literals are idiomatic. + +.. + +.. date: 2023-04-12-20-22-03 +.. gh-issue: 87729 +.. nonce: 99A7UO +.. section: Core and Builtins + +Add :opcode:`LOAD_SUPER_ATTR` (and a specialization for +``super().method()``) to speed up ``super().method()`` and ``super().attr``. +This makes ``super().method()`` roughly 2.3x faster and brings it within 20% +of the performance of a simple method call. Patch by Vladimir Matveev and +Carl Meyer. + +.. + +.. date: 2023-04-12-20-18-51 +.. gh-issue: 103488 +.. nonce: vYvlHD +.. section: Core and Builtins + +Change the internal offset distinguishing yield and return target addresses, +so that the instruction pointer is correct for exception handling and other +stack unwinding. + +.. + +.. date: 2023-04-12-19-55-24 +.. gh-issue: 82012 +.. nonce: FlcJAh +.. section: Core and Builtins + +The bitwise inversion operator (``~``) on bool is deprecated. It returns the +bitwise inversion of the underlying ``int`` representation such that +``bool(~True) == True``, which can be confusing. Use ``not`` for logical +negation of bools. In the rare case that you really need the bitwise +inversion of the underlying ``int``, convert to int explicitly ``~int(x)``. + +.. + +.. date: 2023-04-09-22-21-57 +.. gh-issue: 77757 +.. nonce: _Ow-u2 +.. section: Core and Builtins + +Exceptions raised in a typeobject's ``__set_name__`` method are no longer +wrapped by a :exc:`RuntimeError`. Context information is added to the +exception as a :pep:`678` note. + +.. + +.. date: 2023-04-09-04-30-02 +.. gh-issue: 103333 +.. nonce: gKOetS +.. section: Core and Builtins + +:exc:`AttributeError` now retains the ``name`` attribute when pickled and +unpickled. + +.. + +.. date: 2023-04-08-17-13-07 +.. gh-issue: 103242 +.. nonce: ysI1b3 +.. section: Core and Builtins + +Migrate :meth:`~ssl.SSLContext.set_ecdh_curve` method not to use deprecated +OpenSSL APIs. Patch by Donghee Na. + +.. + +.. date: 2023-04-07-12-18-41 +.. gh-issue: 103323 +.. nonce: 9802br +.. section: Core and Builtins + +We've replaced our use of ``_PyRuntime.tstate_current`` with a thread-local +variable. This is a fairly low-level implementation detail, and there +should be no change in behavior. + +.. + +.. date: 2023-04-02-22-14-57 +.. gh-issue: 84436 +.. nonce: hvMgwF +.. section: Core and Builtins + +The implementation of PEP-683 which adds Immortal Objects by using a fixed +reference count that skips reference counting to make objects truly +immutable. + +.. + +.. date: 2023-04-01-00-46-31 +.. gh-issue: 102700 +.. nonce: 493NB4 +.. section: Core and Builtins + +Allow built-in modules to be submodules. This allows submodules to be +statically linked into a CPython binary. + +.. + +.. date: 2023-03-31-17-24-03 +.. gh-issue: 103082 +.. nonce: isRUcV +.. section: Core and Builtins + +Implement :pep:`669` Low Impact Monitoring for CPython. + +.. + +.. date: 2023-03-25-23-24-38 +.. gh-issue: 88691 +.. nonce: 2SWBd1 +.. section: Core and Builtins + +Reduce the number of inline :opcode:`CACHE` entries for :opcode:`CALL`. + +.. + +.. date: 2023-03-07-17-37-00 +.. gh-issue: 102500 +.. nonce: RUSQhz +.. section: Core and Builtins + +Make the buffer protocol accessible in Python code using the new +``__buffer__`` and ``__release_buffer__`` magic methods. See :pep:`688` for +details. Patch by Jelle Zijlstra. + +.. + +.. date: 2023-01-30-15-40-29 +.. gh-issue: 97933 +.. nonce: nUlp3r +.. section: Core and Builtins + +:pep:`709`: inline list, dict and set comprehensions to improve performance +and reduce bytecode size. + +.. + +.. date: 2022-11-08-12-36-25 +.. gh-issue: 99184 +.. nonce: KIaqzz +.. section: Core and Builtins + +Bypass instance attribute access of ``__name__`` in ``repr`` of +:class:`weakref.ref`. + +.. + +.. date: 2022-10-06-23-32-11 +.. gh-issue: 98003 +.. nonce: xWE0Yu +.. section: Core and Builtins + +Complex function calls are now faster and consume no C stack space. + +.. + +.. bpo: 39610 +.. date: 2020-02-11-15-54-40 +.. nonce: fvgsCl +.. section: Core and Builtins + +``len()`` for 0-dimensional :class:`memoryview`` objects (such as +``memoryview(ctypes.c_uint8(42))``) now raises a :exc:`TypeError`. +Previously this returned ``1``, which was not consistent with ``mem_0d[0]`` +raising an :exc:`IndexError``. + +.. + +.. bpo: 31821 +.. date: 2019-12-01-12-58-31 +.. nonce: 1FNmwk +.. section: Core and Builtins + +Fix :func:`!pause_reading` to work when called from :func:`!connection_made` +in :mod:`asyncio`. + +.. + +.. date: 2023-05-17-21-01-48 +.. gh-issue: 104600 +.. nonce: E6CK35 +.. section: Library + +:func:`functools.update_wrapper` now sets the ``__type_params__`` attribute +(added by :pep:`695`). + +.. + +.. date: 2023-05-17-20-03-01 +.. gh-issue: 104340 +.. nonce: kp_XmX +.. section: Library + +When an ``asyncio`` pipe protocol loses its connection due to an error, and +the caller doesn't await ``wait_closed()`` on the corresponding +``StreamWriter``, don't log a warning about an exception that was never +retrieved. After all, according to the ``StreamWriter.close()`` docs, the +``wait_closed()`` call is optional ("not mandatory"). + +.. + +.. date: 2023-05-17-16-58-23 +.. gh-issue: 104555 +.. nonce: 5rb5oM +.. section: Library + +Fix issue where an :func:`issubclass` check comparing a class ``X`` against +a :func:`runtime-checkable protocol <typing.runtime_checkable>` ``Y`` with +non-callable members would not cause :exc:`TypeError` to be raised if an +:func:`isinstance` call had previously been made comparing an instance of +``X`` to ``Y``. This issue was present in edge cases on Python 3.11, but +became more prominent in 3.12 due to some unrelated changes that were made +to runtime-checkable protocols. Patch by Alex Waygood. + +.. + +.. date: 2023-05-17-08-01-36 +.. gh-issue: 104372 +.. nonce: jpoWs6 +.. section: Library + +Refactored the ``_posixsubprocess`` internals to avoid Python C API usage +between fork and exec when marking ``pass_fds=`` file descriptors +inheritable. + +.. + +.. date: 2023-05-17-03-14-07 +.. gh-issue: 104484 +.. nonce: y6KxL6 +.. section: Library + +Added *case_sensitive* argument to :meth:`pathlib.PurePath.match` + +.. + +.. date: 2023-05-16-11-02-44 +.. gh-issue: 75367 +.. nonce: qLWR35 +.. section: Library + +Fix data descriptor detection in :func:`inspect.getattr_static`. + +.. + +.. date: 2023-05-16-10-07-16 +.. gh-issue: 104536 +.. nonce: hFWD8f +.. section: Library + +Fix a race condition in the internal :mod:`multiprocessing.process` cleanup +logic that could manifest as an unintended ``AttributeError`` when calling +``process.close()``. + +.. + +.. date: 2023-05-12-19-29-28 +.. gh-issue: 103857 +.. nonce: 0IzSxr +.. section: Library + +Update datetime deprecations' stracktrace to point to the calling line + +.. + +.. date: 2023-05-11-21-32-18 +.. gh-issue: 101520 +.. nonce: l9MjRE +.. section: Library + +Move the core functionality of the ``tracemalloc`` module in the ``Python/`` +folder, leaving just the module wrapper in ``Modules/``. + +.. + +.. date: 2023-05-11-07-50-00 +.. gh-issue: 104392 +.. nonce: YSllzt +.. section: Library + +Remove undocumented and unused ``_paramspec_tvars`` attribute from some +classes in :mod:`typing`. + +.. + +.. date: 2023-05-11-01-07-42 +.. gh-issue: 102613 +.. nonce: uMsokt +.. section: Library + +Fix issue where :meth:`pathlib.Path.glob` raised :exc:`RecursionError` when +walking deep directory trees. + +.. + +.. date: 2023-05-10-19-33-36 +.. gh-issue: 103000 +.. nonce: j0KSfD +.. section: Library + +Improve performance of :func:`dataclasses.asdict` for the common case where +*dict_factory* is ``dict``. Patch by David C Ellis. + +.. + +.. date: 2023-05-09-18-46-24 +.. gh-issue: 104301 +.. nonce: gNnbId +.. section: Library + +Allow leading whitespace in disambiguated statements in :mod:`pdb`. + +.. + +.. date: 2023-05-08-23-01-59 +.. gh-issue: 104139 +.. nonce: 83Tnt- +.. section: Library + +Teach :func:`urllib.parse.unsplit` to retain the ``"//"`` when assembling +``itms-services://?action=generate-bugs`` style `Apple Platform Deployment +<https://support.apple.com/en-gb/guide/deployment/depce7cefc4d/web>`_ URLs. + +.. + +.. date: 2023-05-08-20-57-17 +.. gh-issue: 104307 +.. nonce: DSB93G +.. section: Library + +:func:`socket.getnameinfo` now releases the GIL while contacting the DNS +server + +.. + +.. date: 2023-05-08-15-50-59 +.. gh-issue: 104310 +.. nonce: fXVSPY +.. section: Library + +Users may now use ``importlib.util.allowing_all_extensions()`` (a context +manager) to temporarily disable the strict compatibility checks for +importing extension modules in subinterpreters. + +.. + +.. date: 2023-05-08-15-39-00 +.. gh-issue: 87695 +.. nonce: f6iO7v +.. section: Library + +Fix issue where :meth:`pathlib.Path.glob` raised :exc:`OSError` when it +encountered a symlink to an overly long path. + +.. + +.. date: 2023-05-07-19-56-45 +.. gh-issue: 104265 +.. nonce: fVblry +.. section: Library + +Prevent possible crash by disallowing instantiation of the +:class:`!_csv.Reader` and :class:`!_csv.Writer` types. The regression was +introduced in 3.10.0a4 with PR 23224 (:issue:`14935`). Patch by Radislav +Chugunov. + +.. + +.. date: 2023-05-06-20-37-46 +.. gh-issue: 102613 +.. nonce: QZG9iX +.. section: Library + +Improve performance of :meth:`pathlib.Path.glob` when expanding recursive +wildcards ("``**``") by merging adjacent wildcards and de-duplicating +results only when necessary. + +.. + +.. date: 2023-05-05-18-52-22 +.. gh-issue: 65772 +.. nonce: w5P5Wv +.. section: Library + +Remove unneeded comments and code in turtle.py. + +.. + +.. date: 2023-05-03-19-22-24 +.. gh-issue: 90208 +.. nonce: tI00da +.. section: Library + +Fixed issue where :meth:`pathlib.Path.glob` returned incomplete results when +it encountered a :exc:`PermissionError`. This method now suppresses all +:exc:`OSError` exceptions, except those raised from calling +:meth:`~pathlib.Path.is_dir` on the top-level path. + +.. + +.. date: 2023-05-03-16-51-53 +.. gh-issue: 104144 +.. nonce: 653Q0P +.. section: Library + +Optimize :class:`asyncio.TaskGroup` when using +:func:`asyncio.eager_task_factory`. Skip scheduling a done callback if a +TaskGroup task completes eagerly. + +.. + +.. date: 2023-05-03-16-50-24 +.. gh-issue: 104144 +.. nonce: yNkjL8 +.. section: Library + +Optimize :func:`asyncio.gather` when using +:func:`asyncio.eager_task_factory` to complete eagerly if all fututres +completed eagerly. Avoid scheduling done callbacks for futures that complete +eagerly. + +.. + +.. date: 2023-05-03-03-14-33 +.. gh-issue: 104114 +.. nonce: RG26RD +.. section: Library + +Fix issue where :meth:`pathlib.Path.glob` returns paths using the case of +non-wildcard segments for corresponding path segments, rather than the real +filesystem case. + +.. + +.. date: 2023-05-02-21-05-30 +.. gh-issue: 104104 +.. nonce: 9tjplT +.. section: Library + +Improve performance of :meth:`pathlib.Path.glob` by using +:const:`re.IGNORECASE` to implement case-insensitive matching. + +.. + +.. date: 2023-05-02-20-43-03 +.. gh-issue: 104102 +.. nonce: vgSdEJ +.. section: Library + +Improve performance of :meth:`pathlib.Path.glob` when evaluating patterns +that contain ``'../'`` segments. + +.. + +.. date: 2023-05-02-04-49-45 +.. gh-issue: 103822 +.. nonce: m0QdAO +.. section: Library + +Update the return type of ``weekday`` to the newly added Day attribute + +.. + +.. date: 2023-05-01-19-10-05 +.. gh-issue: 103629 +.. nonce: 81bpZz +.. section: Library + +Update the ``repr`` of :class:`typing.Unpack` according to :pep:`692`. + +.. + +.. date: 2023-05-01-17-58-28 +.. gh-issue: 103963 +.. nonce: XWlHx7 +.. section: Library + +Make :mod:`dis` display the names of the args for +:opcode:`CALL_INTRINSIC_*`. + +.. + +.. date: 2023-05-01-16-43-28 +.. gh-issue: 104035 +.. nonce: MrJBw8 +.. section: Library + +Do not ignore user-defined ``__getstate__`` and ``__setstate__`` methods for +slotted frozen dataclasses. + +.. + +.. date: 2023-04-29-18-23-16 +.. gh-issue: 103987 +.. nonce: sRgALL +.. section: Library + +In :mod:`mmap`, fix several bugs that could lead to access to memory-mapped +files after they have been invalidated. + +.. + +.. date: 2023-04-28-19-08-50 +.. gh-issue: 103977 +.. nonce: msF70A +.. section: Library + +Improve import time of :mod:`platform` module. + +.. + +.. date: 2023-04-28-18-04-23 +.. gh-issue: 88773 +.. nonce: xXCNJw +.. section: Library + +Added :func:`turtle.teleport` to the :mod:`turtle` module to move a turtle +to a new point without tracing a line, visible or invisible. Patch by Liam +Gersten. + +.. + +.. date: 2023-04-27-20-03-08 +.. gh-issue: 103935 +.. nonce: Uaf2M0 +.. section: Library + +Use :func:`io.open_code` for files to be executed instead of raw +:func:`open` + +.. + +.. date: 2023-04-27-18-46-31 +.. gh-issue: 68968 +.. nonce: E3tnhy +.. section: Library + +Fixed garbled output of :meth:`~unittest.TestCase.assertEqual` when an input +lacks final newline. + +.. + +.. date: 2023-04-27-00-45-41 +.. gh-issue: 100370 +.. nonce: MgZ3KY +.. section: Library + +Fix potential :exc:`OverflowError` in :meth:`sqlite3.Connection.blobopen` +for 32-bit builds. Patch by Erlend E. Aasland. + +.. + +.. date: 2023-04-27-00-05-32 +.. gh-issue: 102628 +.. nonce: X230E- +.. section: Library + +Substitute CTRL-D with CTRL-Z in :mod:`sqlite3` CLI banner when running on +Windows. + +.. + +.. date: 2023-04-26-18-12-13 +.. gh-issue: 103636 +.. nonce: -KvCgO +.. section: Library + +Module-level attributes ``January`` and ``February`` are deprecated from +:mod:`calendar`. + +.. + +.. date: 2023-04-26-15-14-36 +.. gh-issue: 103583 +.. nonce: iCMDFt +.. section: Library + +Isolate :mod:`!_multibytecodec` and codecs extension modules. Patches by +Erlend E. Aasland. + +.. + +.. date: 2023-04-26-09-54-25 +.. gh-issue: 103848 +.. nonce: aDSnpR +.. section: Library + +Add checks to ensure that ``[`` bracketed ``]`` hosts found by +:func:`urllib.parse.urlsplit` are of IPv6 or IPvFuture format. + +.. + +.. date: 2023-04-26-09-38-47 +.. gh-issue: 103872 +.. nonce: 8LBsDz +.. section: Library + +Update the bundled copy of pip to version 23.1.2. + +.. + +.. date: 2023-04-25-22-59-06 +.. gh-issue: 99944 +.. nonce: pst8iT +.. section: Library + +Make :mod:`dis` display the value of oparg of :opcode:`KW_NAMES`. + +.. + +.. date: 2023-04-25-22-06-00 +.. gh-issue: 74940 +.. nonce: TOacQ9 +.. section: Library + +The C.UTF-8 locale is no longer converted to en_US.UTF-8, enabling the use +of UTF-8 encoding on systems which have no locales installed. + +.. + +.. date: 2023-04-25-19-58-13 +.. gh-issue: 103861 +.. nonce: JeozgD +.. section: Library + +Fix ``zipfile.Zipfile`` creating invalid zip files when ``force_zip64`` was +used to add files to them. Patch by Carey Metcalfe. + +.. + +.. date: 2023-04-25-17-03-18 +.. gh-issue: 103857 +.. nonce: Mr2Cak +.. section: Library + +Deprecated :meth:`datetime.datetime.utcnow` and +:meth:`datetime.datetime.utcfromtimestamp`. (Patch by Paul Ganssle) + +.. + +.. date: 2023-04-25-16-31-00 +.. gh-issue: 103839 +.. nonce: tpyLhI +.. section: Library + +Avoid compilation error due to tommath.h not being found when building +Tkinter against Tcl 8.7 built with bundled libtommath. + +.. + +.. date: 2023-04-24-23-07-56 +.. gh-issue: 103791 +.. nonce: bBPWdS +.. section: Library + +:class:`contextlib.suppress` now supports suppressing exceptions raised as +part of an :exc:`ExceptionGroup`. If other exceptions exist on the group, +they are re-raised in a group that does not contain the suppressed +exceptions. + +.. + +.. date: 2023-04-24-16-00-28 +.. gh-issue: 90750 +.. nonce: da0Xi8 +.. section: Library + +Use :meth:`datetime.datetime.fromisocalendar` in the implementation of +:meth:`datetime.datetime.strptime`, which should now accept only valid ISO +dates. (Patch by Paul Ganssle) + +.. + +.. date: 2023-04-24-00-34-23 +.. gh-issue: 103685 +.. nonce: U14jBM +.. section: Library + +Prepare :meth:`tkinter.Menu.index` for Tk 8.7 so that it does not raise +``TclError: expected integer but got ""`` when it should return ``None``. + +.. + +.. date: 2023-04-23-15-39-17 +.. gh-issue: 81403 +.. nonce: zVz9Td +.. section: Library + +:class:`urllib.request.CacheFTPHandler` no longer raises :class:`URLError` +if a cached FTP instance is reused. ftplib's endtransfer method calls +voidresp to drain the connection to handle FTP instance reuse properly. + +.. + +.. date: 2023-04-22-22-37-39 +.. gh-issue: 103699 +.. nonce: NizCjc +.. section: Library + +Add ``__orig_bases__`` to non-generic TypedDicts, call-based TypedDicts, and +call-based NamedTuples. Other TypedDicts and NamedTuples already had the +attribute. + +.. + +.. date: 2023-04-22-21-34-13 +.. gh-issue: 103693 +.. nonce: SBtuLQ +.. section: Library + +Add convenience variable feature to :mod:`pdb` + +.. + +.. date: 2023-04-22-12-30-10 +.. gh-issue: 92248 +.. nonce: NcVTKR +.. section: Library + +Deprecate ``type``, ``choices``, and ``metavar`` parameters of +``argparse.BooleanOptionalAction``. + +.. + +.. date: 2023-04-22-11-20-27 +.. gh-issue: 89415 +.. nonce: YHk760 +.. section: Library + +Add :mod:`socket` constants for source-specific multicast. Patch by Reese +Hyde. + +.. + +.. date: 2023-04-22-02-41-06 +.. gh-issue: 103673 +.. nonce: oE7S_k +.. section: Library + +:mod:`socketserver` gains ``ForkingUnixStreamServer`` and +``ForkingUnixDatagramServer`` classes. Patch by Jay Berry. + +.. + +.. date: 2023-04-21-10-25-39 +.. gh-issue: 103636 +.. nonce: YK6NEa +.. section: Library + +Added Enum for months and days in the calendar module. + +.. + +.. date: 2023-04-19-16-08-53 +.. gh-issue: 84976 +.. nonce: HwbzlD +.. section: Library + +Create a new ``Lib/_pydatetime.py`` file that defines the Python version of +the ``datetime`` module, and make ``datetime`` import the contents of the +new library only if the C implementation is missing. Currently, the full +Python implementation is defined and then deleted if the C implementation is +not available, slowing down ``import datetime`` unnecessarily. + +.. + +.. date: 2023-04-17-14-47-28 +.. gh-issue: 103596 +.. nonce: ME1y3_ +.. section: Library + +Attributes/methods are no longer shadowed by same-named enum members, +although they may be shadowed by enum.property's. + +.. + +.. date: 2023-04-16-19-48-21 +.. gh-issue: 103584 +.. nonce: 3mBTuM +.. section: Library + +Updated ``importlib.metadata`` with changes from ``importlib_metadata`` 5.2 +through 6.5.0, including: Support ``installed-files.txt`` for +``Distribution.files`` when present. ``PackageMetadata`` now stipulates an +additional ``get`` method allowing for easy querying of metadata keys that +may not be present. ``packages_distributions`` now honors packages and +modules with Python modules that not ``.py`` sources (e.g. ``.pyc``, +``.so``). Expand protocol for ``PackageMetadata.get_all`` to match the +upstream implementation of ``email.message.Message.get_all`` in +python/typeshed#9620. Deprecated use of ``Distribution`` without defining +abstract methods. Deprecated expectation that +``PackageMetadata.__getitem__`` will return ``None`` for missing keys. In +the future, it will raise a ``KeyError``. + +.. + +.. date: 2023-04-16-18-29-04 +.. gh-issue: 103578 +.. nonce: fly1wc +.. section: Library + +Fixed a bug where :mod:`pdb` crashes when reading source file with different +encoding by replacing :func:`io.open` with :func:`io.open_code`. The new +method would also call into the hook set by :c:func:`PyFile_SetOpenCodeHook`. + +.. + +.. date: 2023-04-15-12-19-14 +.. gh-issue: 103556 +.. nonce: TEf-2m +.. section: Library + +Now creating :class:`inspect.Signature` objects with positional-only +parameter with a default followed by a positional-or-keyword parameter +without one is impossible. + +.. + +.. date: 2023-04-15-11-21-38 +.. gh-issue: 103559 +.. nonce: a9rYHG +.. section: Library + +Update the bundled copy of pip to version 23.1.1. + +.. + +.. date: 2023-04-14-21-16-05 +.. gh-issue: 103548 +.. nonce: lagdpp +.. section: Library + +Improve performance of :meth:`pathlib.Path.absolute` and +:meth:`~pathlib.Path.cwd` by joining paths only when necessary. Also improve +performance of :meth:`pathlib.PurePath.is_absolute` on Posix by skipping +path parsing and normalization. + +.. + +.. date: 2023-04-14-21-12-32 +.. gh-issue: 103538 +.. nonce: M4FK_v +.. section: Library + +Remove ``_tkinter`` module code guarded by definition of the ``TK_AQUA`` +macro which was only needed for Tk 8.4.7 or earlier and was never actually +defined by any build system or documented for manual use. + +.. + +.. date: 2023-04-14-06-32-54 +.. gh-issue: 103533 +.. nonce: n_AfcS +.. section: Library + +Update :mod:`cProfile` to use PEP 669 API + +.. + +.. date: 2023-04-13-19-43-15 +.. gh-issue: 103525 +.. nonce: uY4VYg +.. section: Library + +Fix misleading exception message when mixed ``str`` and ``bytes`` arguments +are supplied to :class:`pathlib.PurePath` and :class:`~pathlib.Path`. + +.. + +.. date: 2023-04-13-13-17-47 +.. gh-issue: 103489 +.. nonce: ZSZgmu +.. section: Library + +Add :meth:`~sqlite3.Connection.getconfig` and +:meth:`~sqlite3.Connection.setconfig` to :class:`~sqlite3.Connection` to +make configuration changes to a database connection. Patch by Erlend E. +Aasland. + +.. + +.. date: 2023-04-12-17-59-55 +.. gh-issue: 103365 +.. nonce: UBEE0U +.. section: Library + +Set default Flag boundary to ``STRICT`` and fix bitwise operations. + +.. + +.. date: 2023-04-12-13-04-16 +.. gh-issue: 103472 +.. nonce: C6bOHv +.. section: Library + +Avoid a potential :exc:`ResourceWarning` in +:class:`http.client.HTTPConnection` by closing the proxy / tunnel's CONNECT +response explicitly. + +.. + +.. date: 2023-04-12-06-00-02 +.. gh-issue: 103462 +.. nonce: w6yBlM +.. section: Library + +Fixed an issue with using :meth:`~asyncio.WriteTransport.writelines` in +:mod:`asyncio` to send very large payloads that exceed the amount of data +that can be written in one call to :meth:`socket.socket.send` or +:meth:`socket.socket.sendmsg`, resulting in the remaining buffer being left +unwritten. + +.. + +.. date: 2023-04-11-21-38-39 +.. gh-issue: 103449 +.. nonce: -nxmhb +.. section: Library + +Fix a bug in doc string generation in :func:`dataclasses.dataclass`. + +.. + +.. date: 2023-04-09-06-59-36 +.. gh-issue: 103092 +.. nonce: vskbro +.. section: Library + +Isolate :mod:`!_collections` (apply :pep:`687`). Patch by Erlend E. Aasland. + +.. + +.. date: 2023-04-08-01-33-12 +.. gh-issue: 103357 +.. nonce: vjin28 +.. section: Library + +Added support for :class:`logging.Formatter` ``defaults`` parameter to +:func:`logging.config.dictConfig` and :func:`logging.config.fileConfig`. +Patch by Bar Harel. + +.. + +.. date: 2023-04-08-00-48-40 +.. gh-issue: 103092 +.. nonce: 5EFts0 +.. section: Library + +Adapt the :mod:`winreg` extension module to :pep:`687`. + +.. + +.. date: 2023-04-07-15-15-40 +.. gh-issue: 74690 +.. nonce: un84hh +.. section: Library + +The performance of :func:`isinstance` checks against +:func:`runtime-checkable protocols <typing.runtime_checkable>` has been +considerably improved for protocols that only have a few members. To achieve +this improvement, several internal implementation details of the +:mod:`typing` module have been refactored, including +``typing._ProtocolMeta.__instancecheck__``, +``typing._is_callable_members_only``, and ``typing._get_protocol_attrs``. +Patches by Alex Waygood. + +.. + +.. date: 2023-04-07-15-09-26 +.. gh-issue: 74690 +.. nonce: 0f886b +.. section: Library + +The members of a runtime-checkable protocol are now considered "frozen" at +runtime as soon as the class has been created. See :ref:`"What's new in +Python 3.12" <whatsnew-typing-py312>` for more details. + +.. + +.. date: 2023-04-06-17-28-36 +.. gh-issue: 103256 +.. nonce: 1syxfs +.. section: Library + +Fixed a bug that caused :mod:`hmac` to raise an exception when the requested +hash algorithm was not available in OpenSSL despite being available +separately as part of ``hashlib`` itself. It now falls back properly to the +built-in. This could happen when, for example, your OpenSSL does not include +SHA3 support and you want to compute ``hmac.digest(b'K', b'M', +'sha3_256')``. + +.. + +.. date: 2023-04-06-16-55-51 +.. gh-issue: 102778 +.. nonce: BWeAmE +.. section: Library + +Support ``sys.last_exc`` in :mod:`idlelib`. + +.. + +.. date: 2023-04-06-04-35-59 +.. gh-issue: 103285 +.. nonce: rCZ9-G +.. section: Library + +Improve performance of :func:`ast.get_source_segment`. + +.. + +.. date: 2023-04-05-01-28-53 +.. gh-issue: 103225 +.. nonce: QD3JVU +.. section: Library + +Fix a bug in :mod:`pdb` when displaying line numbers of module-level source +code. + +.. + +.. date: 2023-04-04-21-44-25 +.. gh-issue: 103092 +.. nonce: Dz0_Xn +.. section: Library + +Adapt the :mod:`msvcrt` extension module to :pep:`687`. + +.. + +.. date: 2023-04-04-21-27-51 +.. gh-issue: 103092 +.. nonce: 7s7Bzf +.. section: Library + +Adapt the :mod:`winsound` extension module to :pep:`687`. + +.. + +.. date: 2023-04-04-12-43-38 +.. gh-issue: 93910 +.. nonce: jurMzv +.. section: Library + +Remove deprecation of enum ``memmber.member`` access. + +.. + +.. date: 2023-04-03-23-44-34 +.. gh-issue: 102978 +.. nonce: gy9eVk +.. section: Library + +Fixes :func:`unittest.mock.patch` not enforcing function signatures for +methods decorated with ``@classmethod`` or ``@staticmethod`` when patch is +called with ``autospec=True``. + +.. + +.. date: 2023-04-03-23-43-12 +.. gh-issue: 103092 +.. nonce: 3xqk4y +.. section: Library + +Isolate :mod:`!_socket` (apply :pep:`687`). Patch by Erlend E. Aasland. + +.. + +.. date: 2023-04-03-22-02-35 +.. gh-issue: 100479 +.. nonce: kNBjQm +.. section: Library + +Add :meth:`pathlib.PurePath.with_segments`, which creates a path object from +arguments. This method is called whenever a derivative path is created, such +as from :attr:`pathlib.PurePath.parent`. Subclasses may override this method +to share information between path objects. + +.. + +.. date: 2023-04-03-21-08-53 +.. gh-issue: 103220 +.. nonce: OW_Bj5 +.. section: Library + +Fix issue where :func:`os.path.join` added a slash when joining onto an +incomplete UNC drive with a trailing slash on Windows. + +.. + +.. date: 2023-04-02-23-05-22 +.. gh-issue: 103204 +.. nonce: bbDmu0 +.. section: Library + +Fixes :mod:`http.server` accepting HTTP requests with HTTP version numbers +preceded by '+', or '-', or with digit-separating '_' characters. The +length of the version numbers is also constrained. + +.. + +.. date: 2023-04-02-22-04-26 +.. gh-issue: 75586 +.. nonce: 526iJm +.. section: Library + +Fix various Windows-specific issues with ``shutil.which``. + +.. + +.. date: 2023-04-02-17-51-08 +.. gh-issue: 103193 +.. nonce: xrZbM1 +.. section: Library + +Improve performance of :func:`inspect.getattr_static`. Patch by Alex +Waygood. + +.. + +.. date: 2023-04-01-23-01-31 +.. gh-issue: 103176 +.. nonce: FBsdxa +.. section: Library + +:func:`sys._current_exceptions` now returns a mapping from thread-id to an +exception instance, rather than to a ``(typ, exc, tb)`` tuple. + +.. + +.. date: 2023-03-31-01-13-00 +.. gh-issue: 103143 +.. nonce: 6eMluy +.. section: Library + +Polish the help messages and docstrings of :mod:`pdb`. + +.. + +.. date: 2023-03-28-09-13-31 +.. gh-issue: 103015 +.. nonce: ETTfNf +.. section: Library + +Add *entrypoint* keyword-only parameter to +:meth:`sqlite3.Connection.load_extension`, for overriding the SQLite +extension entry point. Patch by Erlend E. Aasland. + +.. + +.. date: 2023-03-24-20-49-48 +.. gh-issue: 103000 +.. nonce: 6eVNZI +.. section: Library + +Improve performance of :func:`dataclasses.astuple` and +:func:`dataclasses.asdict` in cases where the contents are common Python +types. + +.. + +.. date: 2023-03-23-15-24-38 +.. gh-issue: 102953 +.. nonce: YR4KaK +.. section: Library + +The extraction methods in :mod:`tarfile`, and :func:`shutil.unpack_archive`, +have a new a *filter* argument that allows limiting tar features than may be +surprising or dangerous, such as creating files outside the destination +directory. See :ref:`tarfile-extraction-filter` for details. + +.. + +.. date: 2023-03-15-12-18-07 +.. gh-issue: 97696 +.. nonce: DtnpIC +.. section: Library + +Implemented an eager task factory in asyncio. When used as a task factory on +an event loop, it performs eager execution of coroutines. Coroutines that +are able to complete synchronously (e.g. return or raise without blocking) +are returned immediately as a finished task, and the task is never scheduled +to the event loop. If the coroutine blocks, the (pending) task is scheduled +and returned. + +.. + +.. date: 2023-03-15-00-37-43 +.. gh-issue: 81079 +.. nonce: heTAod +.. section: Library + +Add *case_sensitive* keyword-only argument to :meth:`pathlib.Path.glob` and +:meth:`~pathlib.Path.rglob`. + +.. + +.. date: 2023-03-14-11-20-19 +.. gh-issue: 101819 +.. nonce: 0-h0it +.. section: Library + +Isolate the :mod:`io` extension module by applying :pep:`687`. Patch by +Kumar Aditya, Victor Stinner, and Erlend E. Aasland. + +.. + +.. date: 2023-03-08-02-45-46 +.. gh-issue: 91896 +.. nonce: kgON_a +.. section: Library + +Deprecate :class:`collections.abc.ByteString` + +.. + +.. date: 2023-03-06-18-49-57 +.. gh-issue: 101362 +.. nonce: eSSy6L +.. section: Library + +Speed up :class:`pathlib.Path` construction by omitting the path anchor from +the internal list of path parts. + +.. + +.. date: 2023-02-21-14-57-34 +.. gh-issue: 102114 +.. nonce: uUDQzb +.. section: Library + +Functions in the :mod:`dis` module that accept a source code string as +argument now print a more concise traceback when the string contains a +syntax or indentation error. + +.. + +.. date: 2023-02-19-12-37-08 +.. gh-issue: 62432 +.. nonce: GnBFIB +.. section: Library + +The :mod:`unittest` runner will now exit with status code 5 if no tests were +run. It is common for test runner misconfiguration to fail to find any +tests, this should be an error. + +.. + +.. date: 2023-02-17-21-14-40 +.. gh-issue: 78079 +.. nonce: z3Szr6 +.. section: Library + +Fix incorrect normalization of UNC device path roots, and partial UNC share +path roots, in :class:`pathlib.PurePath`. Pathlib no longer appends a +trailing slash to such paths. + +.. + +.. date: 2023-02-11-21-18-10 +.. gh-issue: 85984 +.. nonce: nvzOD0 +.. section: Library + +Add :func:`tty.cfmakeraw` and :func:`tty.cfmakecbreak` to :mod:`tty` and +modernize, the behavior of :func:`tty.setraw` and :func:`tty.setcbreak` to +use POSIX.1-2017 Chapter 11 "General Terminal Interface" flag masks by +default. + +.. + +.. date: 2023-02-11-15-01-32 +.. gh-issue: 101688 +.. nonce: kwXmfM +.. section: Library + +Implement :func:`types.get_original_bases` to provide further introspection +for types. + +.. + +.. date: 2023-02-09-22-24-34 +.. gh-issue: 101640 +.. nonce: oFuEpB +.. section: Library + +:class:`argparse.ArgumentParser` now catches errors when writing messages, +such as when :data:`sys.stderr` is ``None``. Patch by Oleg Iarygin. + +.. + +.. date: 2023-02-06-16-45-18 +.. gh-issue: 83861 +.. nonce: mMbIU3 +.. section: Library + +Fix datetime.astimezone method return value when invoked on a naive datetime +instance that represents local time falling in a timezone transition gap. +PEP 495 requires that instances with fold=1 produce earlier times than those +with fold=0 in this case. + +.. + +.. date: 2023-01-22-14-53-12 +.. gh-issue: 89550 +.. nonce: c1U23f +.. section: Library + +Decrease execution time of some :mod:`gzip` file writes by 15% by adding +more appropriate buffering. + +.. + +.. date: 2023-01-14-17-54-56 +.. gh-issue: 95299 +.. nonce: vUhpKz +.. section: Library + +Remove the bundled setuptools wheel from ``ensurepip``, and stop installing +setuptools in environments created by ``venv``. + +.. + +.. date: 2022-11-10-16-26-47 +.. gh-issue: 99353 +.. nonce: DQFjnt +.. section: Library + +Respect the :class:`http.client.HTTPConnection` ``.debuglevel`` flag in +:class:`urllib.request.AbstractHTTPHandler` when its constructor parameter +``debuglevel`` is not set. And do the same for ``*HTTPS*``. + +.. + +.. date: 2022-10-21-17-20-57 +.. gh-issue: 98040 +.. nonce: 3btbmA +.. section: Library + +Remove the long-deprecated ``imp`` module. + +.. + +.. date: 2022-10-21-16-23-31 +.. gh-issue: 97850 +.. nonce: N46coo +.. section: Library + +Deprecate :func:`pkgutil.find_loader` and :func:`pkgutil.get_loader` in +favor of :func:`importlib.util.find_spec`. + +.. + +.. date: 2022-10-20-14-03-58 +.. gh-issue: 94473 +.. nonce: pzGX73 +.. section: Library + +Flatten arguments in :meth:`tkinter.Canvas.coords`. It now accepts not only +``x1, y1, x2, y2, ...`` and ``[x1, y1, x2, y2, ...]``, but also ``(x1, y1), +(x2, y2), ...`` and ``[(x1, y1), (x2, y2), ...]``. + +.. + +.. date: 2022-10-09-14-47-42 +.. gh-issue: 98040 +.. nonce: IN3qab +.. section: Library + +Remove more deprecated importlib APIs: ``find_loader()``, ``find_module()``, +``importlib.abc.Finder``, ``pkgutil.ImpImporter``, ``pkgutil.ImpLoader``. + +.. + +.. date: 2022-09-07-09-32-07 +.. gh-issue: 96522 +.. nonce: t73oqp +.. section: Library + +Fix potential deadlock in pty.spawn() + +.. + +.. date: 2022-09-03-09-24-02 +.. gh-issue: 96534 +.. nonce: EU4Oxv +.. section: Library + +Support divert(4) added in FreeBSD 14. + +.. + +.. date: 2022-08-27-21-41-41 +.. gh-issue: 87474 +.. nonce: 9X-kxt +.. section: Library + +Fix potential file descriptor leaks in :class:`subprocess.Popen`. + +.. + +.. date: 2022-07-16-17-15-29 +.. gh-issue: 94906 +.. nonce: C4G8DG +.. section: Library + +Support multiple steps in :func:`math.nextafter`. Patch by Shantanu Jain and +Matthias Gorgens. + +.. + +.. date: 2022-07-06-11-10-37 +.. gh-issue: 51574 +.. nonce: sveUeD +.. section: Library + +Make :func:`tempfile.mkdtemp` return absolute paths when its *dir* parameter +is relative. + +.. + +.. date: 2022-07-03-23-13-28 +.. gh-issue: 94518 +.. nonce: 511Tbh +.. section: Library + +Convert private :meth:`_posixsubprocess.fork_exec` to use Argument Clinic. + +.. + +.. date: 2022-05-02-16-21-05 +.. gh-issue: 92184 +.. nonce: hneGVW +.. section: Library + +When creating zip files using :mod:`zipfile`, ``os.altsep``, if not +``None``, will always be treated as a path separator even when it is not +``/``. Patch by Carey Metcalfe. + +.. + +.. bpo: 46797 +.. date: 2022-02-19-14-19-34 +.. nonce: 6BXZX4 +.. section: Library + +Deprecation warnings are now emitted for :class:`!ast.Num`, +:class:`!ast.Bytes`, :class:`!ast.Str`, :class:`!ast.NameConstant` and +:class:`!ast.Ellipsis`. These have been documented as deprecated since +Python 3.8, and will be removed in Python 3.14. + +.. + +.. bpo: 44844 +.. date: 2021-12-03-23-00-56 +.. nonce: tvg2VY +.. section: Library + +Enables :mod:`webbrowser` to detect and launch Microsoft Edge browser. + +.. + +.. bpo: 45606 +.. date: 2021-11-19-23-37-18 +.. nonce: UW5XE1 +.. section: Library + +Fixed the bug in :meth:`pathlib.Path.glob` -- previously a dangling symlink +would not be found by this method when the pattern is an exact match, but +would be found when the pattern contains a wildcard or the recursive +wildcard (``**``). With this change, a dangling symlink will be found in +both cases. + +.. + +.. bpo: 23041 +.. date: 2021-11-07-15-31-25 +.. nonce: 564i32 +.. section: Library + +Add :const:`~csv.QUOTE_STRINGS` and :const:`~csv.QUOTE_NOTNULL` to the suite +of :mod:`csv` module quoting styles. + +.. + +.. bpo: 24964 +.. date: 2021-05-16-14-28-30 +.. nonce: Oa5Ie_ +.. section: Library + +Added :meth:`http.client.HTTPConnection.get_proxy_response_headers` that +provides access to the HTTP headers on a proxy server response to the +``CONNECT`` request. + +.. + +.. bpo: 17258 +.. date: 2020-05-25-12-42-36 +.. nonce: lf2554 +.. section: Library + +:mod:`multiprocessing` now supports stronger HMAC algorithms for +inter-process connection authentication rather than only HMAC-MD5. + +.. + +.. bpo: 39744 +.. date: 2020-02-25-00-43-22 +.. nonce: hgK689 +.. section: Library + +Make :func:`asyncio.subprocess.Process.communicate` close the subprocess's +stdin even when called with ``input=None``. + +.. + +.. bpo: 22708 +.. date: 2018-07-16-14-10-29 +.. nonce: 592iRR +.. section: Library + +http.client CONNECT method tunnel improvements: Use HTTP 1.1 protocol; send +a matching Host: header with CONNECT, if one is not provided; convert IDN +domain names to Punycode. Patch by Michael Handler. + +.. + +.. date: 2023-05-14-12-11-28 +.. gh-issue: 67056 +.. nonce: nVC2Rf +.. section: Documentation + +Document that the effect of registering or unregistering an :mod:`atexit` +cleanup function from within a registered cleanup function is undefined. + +.. + +.. date: 2023-04-26-23-55-31 +.. gh-issue: 103629 +.. nonce: -0reqn +.. section: Documentation + +Mention the new way of typing ``**kwargs`` with ``Unpack`` and ``TypedDict`` +introduced in :pep:`692`. + +.. + +.. date: 2023-04-25-22-58-08 +.. gh-issue: 48241 +.. nonce: l1Gxxh +.. section: Documentation + +Clarifying documentation about the url parameter to urllib.request.urlopen +and urllib.request.Request needing to be encoded properly. + +.. + +.. date: 2023-03-10-04-59-35 +.. gh-issue: 86094 +.. nonce: zOYdy8 +.. section: Documentation + +Add support for Unicode Path Extra Field in ZipFile. Patch by Yeojin Kim and +Andrea Giudiceandrea + +.. + +.. date: 2023-03-07-23-30-29 +.. gh-issue: 99202 +.. nonce: hhiAJF +.. section: Documentation + +Fix extension type from documentation for compiling in C++20 mode + +.. + +.. date: 2023-05-15-02-22-44 +.. gh-issue: 104494 +.. nonce: Bkrbfn +.. section: Tests + +Update ``test_pack_configure_in`` and ``test_place_configure_in`` for +changes to error message formatting in Tk 8.7. + +.. + +.. date: 2023-05-14-03-00-00 +.. gh-issue: 104461 +.. nonce: Rmex11 +.. section: Tests + +Run test_configure_screen on X11 only, since the ``DISPLAY`` environment +variable and ``-screen`` option for toplevels are not useful on Tk for Win32 +or Aqua. + +.. + +.. date: 2023-04-25-12-19-37 +.. gh-issue: 86275 +.. nonce: -RoLIt +.. section: Tests + +Added property-based tests to the :mod:`zoneinfo` tests, along with stubs +for the ``hypothesis`` interface. (Patch by Paul Ganssle) + +.. + +.. date: 2023-04-08-00-50-23 +.. gh-issue: 103329 +.. nonce: M38tqF +.. section: Tests + +Regression tests for the behaviour of ``unittest.mock.PropertyMock`` were +added. + +.. + +.. date: 2023-03-17-22-00-47 +.. gh-issue: 102795 +.. nonce: z21EoC +.. section: Tests + +fix use of poll in test_epoll's test_control_and_wait + +.. + +.. date: 2022-11-06-18-42-38 +.. gh-issue: 75729 +.. nonce: uGYJrv +.. section: Tests + +Fix the :func:`os.spawn* <os.spawnl>` tests failing on Windows when the +working directory or interpreter path contains spaces. + +.. + +.. date: 2023-05-20-16-09-59 +.. gh-issue: 101282 +.. nonce: FvRARb +.. section: Build + +BOLT optimization is now applied to the libpython shared library if building +a shared library. BOLT instrumentation and application settings can now be +influenced via the ``BOLT_INSTRUMENT_FLAGS`` and ``BOLT_APPLY_FLAGS`` +configure variables. + +.. + +.. date: 2023-05-15-09-34-08 +.. gh-issue: 99017 +.. nonce: nToOQu +.. section: Build + +``PYTHON_FOR_REGEN`` now require Python 3.10 or newer. + +.. + +.. date: 2023-05-14-19-00-19 +.. gh-issue: 104490 +.. nonce: 1tA4AF +.. section: Build + +Define ``.PHONY`` / virtual make targets consistently and properly. + +.. + +.. date: 2023-05-04-10-56-14 +.. gh-issue: 104106 +.. nonce: -W9BJS +.. section: Build + +Add gcc fallback of mkfifoat/mknodat for macOS. Patch by Donghee Na. + +.. + +.. date: 2023-04-14-10-24-37 +.. gh-issue: 103532 +.. nonce: H1djkd +.. section: Build + +The ``TKINTER_PROTECT_LOADTK`` macro is no longer defined or used in the +``_tkinter`` module. It was previously only defined when building against +Tk 8.4.13 and older, but Tk older than 8.5.12 has been unsupported since +gh-issue-91152. + +.. + +.. date: 2023-02-11-05-31-05 +.. gh-issue: 99069 +.. nonce: X4LDvY +.. section: Build + +Extended workaround defining ``static_assert`` when missing from the libc +headers to all clang and gcc builds. In particular, this fixes building on +macOS <= 10.10. + +.. + +.. date: 2022-12-18-07-24-44 +.. gh-issue: 100220 +.. nonce: BgSV7C +.. section: Build + +Changed the default value of the ``SHELL`` Makefile variable from +``/bin/sh`` to ``/bin/sh -e`` to ensure that complex recipes correctly fail +after an error. Previously, ``make install`` could fail to install some +files and yet return a successful result. + +.. + +.. date: 2022-06-20-15-15-11 +.. gh-issue: 90656 +.. nonce: kFBbKe +.. section: Build + +Add platform triplets for 64-bit LoongArch: + +* loongarch64-linux-gnusf +* loongarch64-linux-gnuf32 +* loongarch64-linux-gnu + +Patch by Zhang Na. + +.. + +.. date: 2023-05-18-22-46-03 +.. gh-issue: 104623 +.. nonce: HJZhm1 +.. section: Windows + +Update Windows installer to use SQLite 3.42.0. + +.. + +.. date: 2023-04-24-15-51-11 +.. gh-issue: 82814 +.. nonce: GI3UkZ +.. section: Windows + +Fix a potential ``[Errno 13] Permission denied`` when using +:func:`shutil.copystat` within Windows Subsystem for Linux (WSL) on a +mounted filesystem by adding ``errno.EACCES`` to the list of ignored errors +within the internal implementation. + +.. + +.. date: 2023-04-12-10-49-21 +.. gh-issue: 103088 +.. nonce: Yjj-qJ +.. section: Windows + +Fix virtual environment :file:`activate` script having incorrect line +endings for Cygwin. + +.. + +.. date: 2023-04-11-09-22-22 +.. gh-issue: 103088 +.. nonce: 6AJEuR +.. section: Windows + +Fixes venvs not working in bash on Windows across different disks + +.. + +.. date: 2023-03-24-11-25-28 +.. gh-issue: 102997 +.. nonce: dredy2 +.. section: Windows + +Update Windows installer to use SQLite 3.41.2. + +.. + +.. date: 2023-03-18-21-38-00 +.. gh-issue: 88013 +.. nonce: Z3loxC +.. section: Windows + +Fixed a bug where :exc:`TypeError` was raised when calling +:func:`ntpath.realpath` with a bytes parameter in some cases. + +.. + +.. date: 2023-05-21-23-54-52 +.. gh-issue: 99834 +.. nonce: 6ANPts +.. section: macOS + +Update macOS installer to Tcl/Tk 8.6.13. + +.. + +.. date: 2023-05-18-22-31-49 +.. gh-issue: 104623 +.. nonce: 6h7Xfx +.. section: macOS + +Update macOS installer to SQLite 3.42.0. + +.. + +.. date: 2023-05-18-08-52-04 +.. gh-issue: 103545 +.. nonce: pi5k2N +.. section: macOS + +Add ``os.PRIO_DARWIN_THREAD``, ``os.PRIO_DARWIN_PROCESS``, +``os.PRIO_DARWIN_BG`` and ``os.PRIO_DARWIN_NONUI``. These can be used with +``os.setpriority`` to run the process at a lower priority and make use of +the efficiency cores on Apple Silicon systems. + +.. + +.. date: 2023-05-04-21-47-59 +.. gh-issue: 104180 +.. nonce: lEJCwd +.. section: macOS + +Support reading SOCKS proxy configuration from macOS System Configuration. +Patch by Sam Schott. + +.. + +.. date: 2023-04-24-18-37-48 +.. gh-issue: 60436 +.. nonce: in-IyF +.. section: macOS + +update curses textbox to additionally handle backspace using the +``curses.ascii.DEL`` key press. + +.. + +.. date: 2023-03-24-11-20-47 +.. gh-issue: 102997 +.. nonce: ZgQkbq +.. section: macOS + +Update macOS installer to SQLite 3.41.2. + +.. + +.. date: 2023-05-17-17-32-21 +.. gh-issue: 104499 +.. nonce: hNeqV4 +.. section: IDLE + +Fix completions for Tk Aqua 8.7 (currently blank). + +.. + +.. date: 2023-05-17-15-11-11 +.. gh-issue: 104496 +.. nonce: wjav-y +.. section: IDLE + +About prints both tcl and tk versions if different (expected someday). + +.. + +.. date: 2023-04-30-20-01-18 +.. gh-issue: 88496 +.. nonce: y65vUb +.. section: IDLE + +Fix IDLE test hang on macOS. + +.. + +.. date: 2023-05-11-15-12-11 +.. gh-issue: 104389 +.. nonce: EiOhB3 +.. section: Tools/Demos + +Argument Clinic C converters now accept the ``unused`` keyword, for wrapping +a parameter with :c:macro:`Py_UNUSED`. Patch by Erlend E. Aasland. + +.. + +.. date: 2023-05-18-20-53-05 +.. gh-issue: 101291 +.. nonce: ZBh9aR +.. section: C API + +Added unstable C API for extracting the value of "compact" integers: +:c:func:`PyUnstable_Long_IsCompact` and +:c:func:`PyUnstable_Long_CompactValue`. + +.. + +.. date: 2023-05-02-21-05-54 +.. gh-issue: 104109 +.. nonce: 0tnDZV +.. section: C API + +We've added ``Py_NewInterpreterFromConfig()`` and ``PyInterpreterConfig`` to +the public C-API (but not the stable ABI; not yet at least). The new +function may be used to create a new interpreter with various features +configured. The function was added to support PEP 684 (per-interpreter +GIL). + +.. + +.. date: 2023-04-28-18-04-38 +.. gh-issue: 103968 +.. nonce: EnVvOx +.. section: C API + +:c:func:`PyType_FromSpec` and its variants now allow creating classes whose +metaclass overrides :c:member:`~PyTypeObject.tp_new`. The ``tp_new`` is +ignored. This behavior is deprecated and will be disallowed in 3.14+. The +new :c:func:`PyType_FromMetaclass` already disallows it. + +.. + +.. date: 2023-04-24-10-31-59 +.. gh-issue: 103743 +.. nonce: 2xYA1K +.. section: C API + +Add :c:func:`PyUnstable_Object_GC_NewWithExtraData` function that can be +used to allocate additional memory after an object for data not managed by +Python. + +.. + +.. date: 2023-04-14-23-05-52 +.. gh-issue: 103295 +.. nonce: GRHY1Z +.. section: C API + +Introduced :c:func:`PyUnstable_WritePerfMapEntry`, +:c:func:`PyUnstable_PerfMapState_Init` and +:c:func:`PyUnstable_PerfMapState_Fini`. These allow extension modules (JIT +compilers in particular) to write to perf-map files in a thread safe manner. +The :doc:`../howto/perf_profiling` also uses these APIs to write entries in +the perf-map file. + +.. + +.. date: 2023-04-13-16-54-00 +.. gh-issue: 103509 +.. nonce: A26Qu8 +.. section: C API + +Added C API for extending types whose instance memory layout is opaque: +:c:member:`PyType_Spec.basicsize` can now be zero or negative, +:c:func:`PyObject_GetTypeData` can be used to get subclass-specific data, +and :c:macro:`Py_TPFLAGS_ITEMS_AT_END` can be used to safely extend +variable-size objects. See :pep:`697` for details. + +.. + +.. date: 2023-03-28-12-31-51 +.. gh-issue: 103091 +.. nonce: CzZyaZ +.. section: C API + +Add a new C-API function to eagerly assign a version tag to a PyTypeObject: +``PyUnstable_Type_AssignVersionTag()``. + +.. + +.. date: 2023-02-09-23-09-29 +.. gh-issue: 101408 +.. nonce: _paFIF +.. section: C API + +:c:func:`PyObject_GC_Resize` should calculate preheader size if needed. +Patch by Donghee Na. + +.. + +.. date: 2022-10-29-10-13-20 +.. gh-issue: 98836 +.. nonce: Cy5h_z +.. section: C API + +Add support of more formatting options (left aligning, octals, uppercase +hexadecimals, :c:type:`intmax_t`, :c:type:`ptrdiff_t`, :c:type:`wchar_t` C +strings, variable width and precision) in :c:func:`PyUnicode_FromFormat` and +:c:func:`PyUnicode_FromFormatV`. + +.. + +.. date: 2022-09-15-15-21-34 +.. gh-issue: 96803 +.. nonce: ynBKIS +.. section: C API + +Add unstable C-API functions to get the code object, lasti and line number +from the internal ``_PyInterpreterFrame`` in the limited API. The functions +are: + +* ``PyCodeObject * PyUnstable_InterpreterFrame_GetCode(struct _PyInterpreterFrame *frame)`` +* ``int PyUnstable_InterpreterFrame_GetLasti(struct _PyInterpreterFrame *frame)`` +* ``int PyUnstable_InterpreterFrame_GetLine(struct _PyInterpreterFrame *frame)`` diff --git a/Misc/NEWS.d/3.12.0b2.rst b/Misc/NEWS.d/3.12.0b2.rst new file mode 100644 index 00000000..482ea875 --- /dev/null +++ b/Misc/NEWS.d/3.12.0b2.rst @@ -0,0 +1,530 @@ +.. date: 2023-06-01-03-24-58 +.. gh-issue: 103142 +.. nonce: GLWDMX +.. release date: 2023-06-06 +.. section: Security + +The version of OpenSSL used in our binary builds has been upgraded to 1.1.1u +to address several CVEs. + +.. + +.. date: 2023-05-24-09-29-08 +.. gh-issue: 99108 +.. nonce: hwS2cr +.. section: Security + +Refresh our new HACL* built-in :mod:`hashlib` code from upstream. Built-in +SHA2 should be faster and an issue with SHA3 on 32-bit platforms is fixed. + +.. + +.. date: 2023-06-06-11-37-53 +.. gh-issue: 105259 +.. nonce: E2BGKL +.. section: Core and Builtins + +Don't include newline character for trailing ``NEWLINE`` tokens emitted in +the :mod:`tokenize` module. Patch by Pablo Galindo + +.. + +.. date: 2023-06-05-17-35-50 +.. gh-issue: 105324 +.. nonce: BqhiJJ +.. section: Core and Builtins + +Fix the main function of the :mod:`tokenize` module when reading from +``sys.stdin``. Patch by Pablo Galindo + +.. + +.. date: 2023-06-02-17-39-19 +.. gh-issue: 98963 +.. nonce: J4wJgk +.. section: Core and Builtins + +Restore the ability for a subclass of :class:`property` to define +``__slots__`` or otherwise be dict-less by ignoring failures to set a +docstring on such a class. This behavior had regressed in 3.12beta1. An +:exc:`AttributeError` where there had not previously been one was disruptive +to existing code. + +.. + +.. date: 2023-06-02-11-37-12 +.. gh-issue: 105194 +.. nonce: 4eu56B +.. section: Core and Builtins + +Do not escape with backslashes f-string format specifiers. Patch by Pablo +Galindo + +.. + +.. date: 2023-06-01-11-37-03 +.. gh-issue: 105162 +.. nonce: r8VCXk +.. section: Core and Builtins + +Fixed bug in generator.close()/throw() where an inner iterator would be +ignored when the outer iterator was instrumented. + +.. + +.. date: 2023-05-31-19-35-22 +.. gh-issue: 105164 +.. nonce: 6Wajph +.. section: Core and Builtins + +Ensure annotations are set up correctly if the only annotation in a block is +within a :keyword:`match` block. Patch by Jelle Zijlstra. + +.. + +.. date: 2023-05-31-08-10-59 +.. gh-issue: 104799 +.. nonce: 8kDWti +.. section: Core and Builtins + +Attributes of :mod:`ast` nodes that are lists now default to the empty list +if omitted. This means that some code that previously raised +:exc:`TypeError` when the AST node was used will now proceed with the empty +list instead. Patch by Jelle Zijlstra. + +.. + +.. date: 2023-05-30-08-09-43 +.. gh-issue: 105035 +.. nonce: OWUlHy +.. section: Core and Builtins + +Fix :func:`super` calls on types with custom :attr:`tp_getattro` +implementation (e.g. meta-types.) + +.. + +.. date: 2023-05-27-21-50-48 +.. gh-issue: 105017 +.. nonce: 4sDyDV +.. section: Core and Builtins + +Show CRLF lines in the tokenize string attribute in both NL and NEWLINE +tokens. Patch by Marta Gómez. + +.. + +.. date: 2023-05-27-16-57-11 +.. gh-issue: 105013 +.. nonce: IsDgDY +.. section: Core and Builtins + +Fix handling of multiline parenthesized lambdas in +:func:`inspect.getsource`. Patch by Pablo Galindo + +.. + +.. date: 2023-05-27-16-23-16 +.. gh-issue: 105017 +.. nonce: KQrsC0 +.. section: Core and Builtins + +Do not include an additional final ``NL`` token when parsing files having +CRLF lines. Patch by Marta Gómez. + +.. + +.. date: 2023-05-26-15-16-11 +.. gh-issue: 104976 +.. nonce: 6dLitD +.. section: Core and Builtins + +Ensure that trailing ``DEDENT`` :class:`tokenize.TokenInfo` objects emitted +by the :mod:`tokenize` module are reported as in Python 3.11. Patch by Pablo +Galindo + +.. + +.. date: 2023-05-26-14-09-47 +.. gh-issue: 104972 +.. nonce: El2UjE +.. section: Core and Builtins + +Ensure that the ``line`` attribute in :class:`tokenize.TokenInfo` objects in +the :mod:`tokenize` module are always correct. Patch by Pablo Galindo + +.. + +.. date: 2023-05-25-21-40-39 +.. gh-issue: 104955 +.. nonce: LZx7jf +.. section: Core and Builtins + +Fix signature for the new :meth:`~object.__release_buffer__` slot. Patch by +Jelle Zijlstra. + +.. + +.. date: 2023-05-24-12-10-54 +.. gh-issue: 104690 +.. nonce: HX3Jou +.. section: Core and Builtins + +Starting new threads and process creation through :func:`os.fork` during +interpreter shutdown (such as from :mod:`atexit` handlers) is no longer +supported. It can lead to race condition between the main Python runtime +thread freeing thread states while internal :mod:`threading` routines are +trying to allocate and use the state of just created threads. Or forked +children trying to use the mid-shutdown runtime and thread state in the +child process. + +.. + +.. date: 2023-05-24-10-19-35 +.. gh-issue: 104879 +.. nonce: v-29NL +.. section: Core and Builtins + +Fix crash when accessing the ``__module__`` attribute of type aliases +defined outside a module. Patch by Jelle Zijlstra. + +.. + +.. date: 2023-05-24-09-59-56 +.. gh-issue: 104825 +.. nonce: mQesie +.. section: Core and Builtins + +Tokens emitted by the :mod:`tokenize` module do not include an implicit +``\n`` character in the ``line`` attribute anymore. Patch by Pablo Galindo + +.. + +.. date: 2023-06-04-12-16-47 +.. gh-issue: 105280 +.. nonce: srRbCe +.. section: Library + +Fix bug where ``isinstance([], collections.abc.Mapping)`` could evaluate to +``True`` if garbage collection happened at the wrong time. The bug was +caused by changes to the implementation of :class:`typing.Protocol` in +Python 3.12. + +.. + +.. date: 2023-06-02-14-57-11 +.. gh-issue: 105239 +.. nonce: SAmuuj +.. section: Library + +Fix longstanding bug where ``issubclass(object, typing.Protocol)`` would +evaluate to ``True`` in some edge cases. Patch by Alex Waygood. + +.. + +.. date: 2023-06-02-02-38-26 +.. gh-issue: 105080 +.. nonce: 2imGMg +.. section: Library + +Fixed inconsistent signature on derived classes for +:func:`inspect.signature` + +.. + +.. date: 2023-05-31-16-58-42 +.. gh-issue: 105144 +.. nonce: Oqfn0V +.. section: Library + +Fix a recent regression in the :mod:`typing` module. The regression meant +that doing ``class Foo(X, typing.Protocol)``, where ``X`` was a class that +had :class:`abc.ABCMeta` as its metaclass, would then cause subsequent +``isinstance(1, X)`` calls to erroneously raise :exc:`TypeError`. Patch by +Alex Waygood. + +.. + +.. date: 2023-05-30-21-27-41 +.. gh-issue: 105113 +.. nonce: bDUPl_ +.. section: Library + +Improve performance of :meth:`pathlib.PurePath.match` by compiling an +:class:`re.Pattern` object for the entire pattern. + +.. + +.. date: 2023-05-26-01-31-30 +.. gh-issue: 101588 +.. nonce: RaqxFy +.. section: Library + +Deprecate undocumented copy/deepcopy/pickle support for itertools. + +.. + +.. date: 2023-05-25-23-34-54 +.. gh-issue: 103631 +.. nonce: x5Urye +.. section: Library + +Fix ``pathlib.PurePosixPath(pathlib.PureWindowsPath(...))`` not converting +path separators to restore 3.11 compatible behavior. + +.. + +.. date: 2023-05-25-22-54-20 +.. gh-issue: 104947 +.. nonce: hi6TUr +.. section: Library + +Make comparisons between :class:`pathlib.PureWindowsPath` objects consistent +across Windows and Posix to match 3.11 behavior. + +.. + +.. date: 2023-05-25-08-50-47 +.. gh-issue: 104935 +.. nonce: -rm1BR +.. section: Library + +Fix bugs with the interaction between :func:`typing.runtime_checkable` and +:class:`typing.Generic` that were introduced by the :pep:`695` +implementation. Patch by Jelle Zijlstra. + +.. + +.. date: 2023-05-24-09-34-23 +.. gh-issue: 104874 +.. nonce: oqyJSy +.. section: Library + +Document the ``__name__`` and ``__supertype__`` attributes of +:class:`typing.NewType`. Patch by Jelle Zijlstra. + +.. + +.. date: 2023-05-23-18-31-49 +.. gh-issue: 104799 +.. nonce: MJYOw6 +.. section: Library + +Adjust the location of the (see :pep:`695`) ``type_params`` field on +:class:`ast.ClassDef`, :class:`ast.AsyncFunctionDef`, and +:class:`ast.FunctionDef` to better preserve backward compatibility. Patch by +Jelle Zijlstra + +.. + +.. date: 2023-05-23-17-43-52 +.. gh-issue: 104797 +.. nonce: NR7KzF +.. section: Library + +Allow :class:`typing.Protocol` classes to inherit from +:class:`collections.abc.Buffer`. Patch by Jelle Zijlstra. + +.. + +.. date: 2023-05-22-18-39-53 +.. gh-issue: 104372 +.. nonce: 7tDRaK +.. section: Library + +On Linux where :mod:`subprocess` can use the ``vfork()`` syscall for faster +spawning, prevent the parent process from blocking other threads by dropping +the GIL while it waits for the vfork'ed child process ``exec()`` outcome. +This prevents spawning a binary from a slow filesystem from blocking the +rest of the application. + +.. + +.. date: 2023-05-19-19-46-22 +.. gh-issue: 99108 +.. nonce: wqCg0t +.. section: Library + +We now release the GIL around built-in :mod:`hashlib` computations of +reasonable size for the SHA families and MD5 hash functions, matching what +our OpenSSL backed hash computations already does. + +.. + +.. date: 2023-05-11-23-03-00 +.. gh-issue: 104399 +.. nonce: MMatTP +.. section: Library + +Prepare the ``_tkinter`` module for building with Tcl 9.0 and future +libtommath by replacing usage of deprecated functions +:c:func:`mp_to_unsigned_bin_n` and :c:func:`mp_unsigned_bin_size` when +necessary. + +.. + +.. date: 2023-02-18-22-55-48 +.. gh-issue: 102024 +.. nonce: RUmg_D +.. section: Library + +Reduce calls of ``_idle_semaphore.release()`` in +:func:`concurrent.futures.thread._worker`. + +.. + +.. date: 2023-05-28-21-01-00 +.. gh-issue: 89455 +.. nonce: qAKRrA +.. section: Documentation + +Add missing documentation for the ``max_group_depth`` and +``max_group_width`` parameters and the ``exceptions`` attribute of the +:class:`traceback.TracebackException` class. + +.. + +.. date: 2023-05-28-19-08-42 +.. gh-issue: 89412 +.. nonce: j4cg7K +.. section: Documentation + +Add missing documentation for the ``end_lineno`` and ``end_offset`` +attributes of the :class:`traceback.TracebackException` class. + +.. + +.. date: 2023-05-25-22-34-31 +.. gh-issue: 104943 +.. nonce: J2v1Pc +.. section: Documentation + +Remove mentions of old Python versions in :class:`typing.NamedTuple`. + +.. + +.. date: 2023-06-06-09-08-10 +.. gh-issue: 90005 +.. nonce: 8mmeJQ +.. section: Build + +Fix a regression in :file:`configure` where we could end up unintentionally +linking with ``libbsd``. + +.. + +.. date: 2023-05-26-15-44-20 +.. gh-issue: 89886 +.. nonce: _iSW-p +.. section: Build + +Autoconf 2.71 and aclocal 1.16.4 is now required to regenerate +:file:`!configure`. + +.. + +.. date: 2023-05-31-16-14-31 +.. gh-issue: 105146 +.. nonce: gNjqq8 +.. section: Windows + +Updated the links at the end of the installer to point to Discourse rather +than the mailing lists. + +.. + +.. date: 2023-05-29-17-09-31 +.. gh-issue: 103646 +.. nonce: U8oGQx +.. section: Windows + +When installed from the Microsoft Store, ``pip`` no longer defaults to +per-user installs. However, as the install directory is unwritable, it +should automatically decide to do a per-user install anyway. This should +resolve issues when ``pip`` is passed an option that conflicts with +``--user``. + +.. + +.. date: 2023-05-29-11-38-53 +.. gh-issue: 88745 +.. nonce: cldf9G +.. section: Windows + +Improve performance of :func:`shutil.copy2` by using the operating system's +``CopyFile2`` function. This may result in subtle changes to metadata copied +along with some files, bringing them in line with normal OS behavior. + +.. + +.. date: 2023-05-24-21-00-57 +.. gh-issue: 104820 +.. nonce: ibyrpp +.. section: Windows + +Fixes :func:`~os.stat` and related functions on file systems that do not +support file ID requests. This includes FAT32 and exFAT. + +.. + +.. date: 2023-05-23-19-26-28 +.. gh-issue: 104803 +.. nonce: gqxYml +.. section: Windows + +Add :func:`os.path.isdevdrive` to detect whether a path is on a Windows Dev +Drive. Returns ``False`` on platforms that do not support Dev Drive, and is +absent on non-Windows platforms. + +.. + +.. date: 2023-05-30-23-30-46 +.. gh-issue: 103142 +.. nonce: 55lMXQ +.. section: macOS + +Update macOS installer to use OpenSSL 1.1.1u. + +.. + +.. date: 2023-05-23-17-19-49 +.. gh-issue: 104719 +.. nonce: rvYXH- +.. section: IDLE + +Remove IDLE's modification of tokenize.tabsize and test other uses of +tokenize data and methods. + +.. + +.. date: 2023-05-30-17-45-32 +.. gh-issue: 105115 +.. nonce: iRho1K +.. section: C API + +``PyTypeObject.tp_bases`` (and ``tp_mro``) for builtin static types are now +shared by all interpreters, whereas in 3.12-beta1 they were stored on +``PyInterpreterState``. Also note that now the tuples are immortal objects. + +.. + +.. date: 2023-05-30-10-15-13 +.. gh-issue: 105071 +.. nonce: dPtp7c +.. section: C API + +Add ``PyUnstable_Exc_PrepReraiseStar`` to the unstable C api to expose the +implementation of :keyword:`except* <except_star>`. + +.. + +.. date: 2023-05-19-10-22-34 +.. gh-issue: 104668 +.. nonce: MLX1g9 +.. section: C API + +Don't call :c:var:`PyOS_InputHook` or :c:var:`PyOS_ReadlineFunctionPointer` +in subinterpreters, since it's generally difficult to avoid using global +state in their registered callbacks. This also avoids situations where +extensions may find themselves running in a subinterpreter they don't +support (or haven't yet been loaded in). diff --git a/Misc/NEWS.d/3.12.0b3.rst b/Misc/NEWS.d/3.12.0b3.rst new file mode 100644 index 00000000..2b26ac74 --- /dev/null +++ b/Misc/NEWS.d/3.12.0b3.rst @@ -0,0 +1,411 @@ +.. date: 2023-06-15-22-11-43 +.. gh-issue: 105840 +.. nonce: Fum_g_ +.. release date: 2023-06-19 +.. section: Core and Builtins + +Fix possible crashes when specializing function calls with too many +``__defaults__``. + +.. + +.. date: 2023-06-15-15-54-47 +.. gh-issue: 105831 +.. nonce: -MC9Zs +.. section: Core and Builtins + +Fix an f-string bug, where using a debug expression (the ``=`` sign) that +appears in the last line of a file results to the debug buffer that holds +the expression text being one character too small. + +.. + +.. date: 2023-06-14-22-52-06 +.. gh-issue: 105800 +.. nonce: hdpPzZ +.. section: Core and Builtins + +Correctly issue :exc:`SyntaxWarning` in f-strings if invalid sequences are +used. Patch by Pablo Galindo + +.. + +.. date: 2023-06-10-21-38-49 +.. gh-issue: 105587 +.. nonce: rL3rzv +.. section: Core and Builtins + +The runtime can't guarantee that immortal objects will not be mutated by +Extensions. Thus, this modifies _PyStaticObject_CheckRefcnt to warn instead +of asserting. + +.. + +.. date: 2023-06-09-15-25-12 +.. gh-issue: 105564 +.. nonce: sFdUu4 +.. section: Core and Builtins + +Don't include artificil newlines in the ``line`` attribute of tokens in the +APIs of the :mod:`tokenize` module. Patch by Pablo Galindo + +.. + +.. date: 2023-06-09-12-59-18 +.. gh-issue: 105549 +.. nonce: PYfTNp +.. section: Core and Builtins + +Tokenize separately ``NUMBER`` and ``NAME`` tokens that are not ambiguous. +Patch by Pablo Galindo. + +.. + +.. date: 2023-06-09-11-19-51 +.. gh-issue: 105588 +.. nonce: Y5ovpY +.. section: Core and Builtins + +Fix an issue that could result in crashes when compiling malformed +:mod:`ast` nodes. + +.. + +.. date: 2023-06-08-10-10-07 +.. gh-issue: 105375 +.. nonce: 35VGDd +.. section: Core and Builtins + +Fix bugs in the :mod:`builtins` module where exceptions could end up being +overwritten. + +.. + +.. date: 2023-06-08-09-54-37 +.. gh-issue: 105375 +.. nonce: kqKT3E +.. section: Core and Builtins + +Fix bug in the compiler where an exception could end up being overwritten. + +.. + +.. date: 2023-06-08-09-25-52 +.. gh-issue: 105375 +.. nonce: ocB7fT +.. section: Core and Builtins + +Improve error handling in :c:func:`PyUnicode_BuildEncodingMap` where an +exception could end up being overwritten. + +.. + +.. date: 2023-06-07-12-20-59 +.. gh-issue: 105435 +.. nonce: 6VllI0 +.. section: Core and Builtins + +Fix spurious newline character if file ends on a comment without a newline. +Patch by Pablo Galindo + +.. + +.. date: 2023-06-06-17-10-42 +.. gh-issue: 105390 +.. nonce: DvqI-e +.. section: Core and Builtins + +Correctly raise :exc:`tokenize.TokenError` exceptions instead of +:exc:`SyntaxError` for tokenize errors such as incomplete input. Patch by +Pablo Galindo + +.. + +.. date: 2023-06-02-15-15-41 +.. gh-issue: 104812 +.. nonce: dfZiG5 +.. section: Core and Builtins + +The "pending call" machinery now works for all interpreters, not just the +main interpreter, and runs in all threads, not just the main thread. Some +calls are still only done in the main thread, ergo in the main interpreter. +This change does not affect signal handling nor the existing public C-API +(``Py_AddPendingCall()``), which both still only target the main thread. The +new functionality is meant strictly for internal use for now, since +consequences of its use are not well understood yet outside some very +restricted cases. This change brings the capability in line with the +intention when the state was made per-interpreter several years ago. + +.. + +.. date: 2023-06-19-11-31-55 +.. gh-issue: 105808 +.. nonce: NL-quu +.. section: Library + +Fix a regression introduced in GH-101251 for 3.12, causing +:meth:`gzip.GzipFile.flush` to not flush the compressor (nor pass along the +``zip_mode`` argument). + +.. + +.. date: 2023-06-15-18-11-47 +.. gh-issue: 104799 +.. nonce: BcLzbP +.. section: Library + +Enable :func:`ast.unparse` to unparse function and class definitions created +without the new ``type_params`` field from :pep:`695`. Patch by Jelle +Zijlstra. + +.. + +.. date: 2023-06-14-10-27-34 +.. gh-issue: 105745 +.. nonce: l1ttOQ +.. section: Library + +Fix ``webbrowser.Konqueror.open`` method. + +.. + +.. date: 2023-06-11-22-46-06 +.. gh-issue: 105375 +.. nonce: YkhSNt +.. section: Library + +Fix a bug in :c:func:`!_Unpickler_SetInputStream` where an exception could +end up being overwritten in case of failure. + +.. + +.. date: 2023-06-09-23-46-23 +.. gh-issue: 105375 +.. nonce: 9KaioS +.. section: Library + +Fix bugs in :mod:`sys` where exceptions could end up being overwritten +because of deferred error handling. + +.. + +.. date: 2023-06-09-23-00-13 +.. gh-issue: 105605 +.. nonce: YuwqxY +.. section: Library + +Harden :mod:`pyexpat` error handling during module initialisation to prevent +exceptions from possibly being overwritten, and objects from being +dereferenced twice. + +.. + +.. date: 2023-06-09-22-52-45 +.. gh-issue: 105375 +.. nonce: 6igkhn +.. section: Library + +Fix bug in :mod:`decimal` where an exception could end up being overwritten. + +.. + +.. date: 2023-06-09-22-45-26 +.. gh-issue: 105375 +.. nonce: 9rp6tG +.. section: Library + +Fix bugs in :mod:`!_datetime` where exceptions could be overwritten in case +of module initialisation failure. + +.. + +.. date: 2023-06-09-22-16-46 +.. gh-issue: 105375 +.. nonce: EgVJOP +.. section: Library + +Fix bugs in :mod:`!_ssl` initialisation which could lead to leaked +references and overwritten exceptions. + +.. + +.. date: 2023-06-09-21-46-52 +.. gh-issue: 105375 +.. nonce: yrJelV +.. section: Library + +Fix a bug in :class:`array.array` where an exception could end up being +overwritten. + +.. + +.. date: 2023-06-09-21-40-45 +.. gh-issue: 105375 +.. nonce: _sZilh +.. section: Library + +Fix bugs in :mod:`_ctypes` where exceptions could end up being overwritten. + +.. + +.. date: 2023-06-09-21-30-59 +.. gh-issue: 105375 +.. nonce: eewafp +.. section: Library + +Fix a bug in the :mod:`posix` module where an exception could be +overwritten. + +.. + +.. date: 2023-06-09-21-25-14 +.. gh-issue: 105375 +.. nonce: 95g1eI +.. section: Library + +Fix bugs in :mod:`!_elementtree` where exceptions could be overwritten. + +.. + +.. date: 2023-06-09-21-11-28 +.. gh-issue: 105375 +.. nonce: 4Mxn7t +.. section: Library + +Fix bugs in :mod:`zoneinfo` where exceptions could be overwritten. + +.. + +.. date: 2023-06-09-21-04-39 +.. gh-issue: 105375 +.. nonce: bTcqS9 +.. section: Library + +Fix bugs in :mod:`errno` where exceptions could be overwritten. + +.. + +.. date: 2023-06-08-08-58-36 +.. gh-issue: 105375 +.. nonce: bTcqS9 +.. section: Library + +Fix bugs in :mod:`pickle` where exceptions could be overwritten. + +.. + +.. date: 2023-06-07-00-09-52 +.. gh-issue: 105375 +.. nonce: Y_9D4n +.. section: Library + +Fix a bug in :mod:`sqlite3` where an exception could be overwritten in the +:meth:`collation <sqlite3.Connection.create_collation>` callback. + +.. + +.. date: 2023-06-06-11-50-33 +.. gh-issue: 105332 +.. nonce: tmpgRA +.. section: Library + +Revert pickling method from by-name back to by-value. + +.. + +.. date: 2023-06-02-14-23-41 +.. gh-issue: 104310 +.. nonce: UamCOB +.. section: Library + +In the beta 1 release we added a utility function for extension module +authors, to use when testing their module for support in multiple +interpreters or under a per-interpreter GIL. The name of that function has +changed from ``allowing_all_extensions`` to +``_incompatible_extension_module_restrictions``. The default for the +"disable_check" argument has change from ``True`` to ``False``, to better +match the new function name. + +.. + +.. date: 2023-05-26-21-24-06 +.. gh-issue: 104996 +.. nonce: aaW78g +.. section: Library + +Improve performance of :class:`pathlib.PurePath` initialisation by deferring +joining of paths when multiple arguments are given. + +.. + +.. date: 2023-03-12-01-17-15 +.. gh-issue: 102541 +.. nonce: LK1adc +.. section: Library + +Hide traceback in :func:`help` prompt, when import failed. + +.. + +.. date: 2023-05-29-14-49-46 +.. gh-issue: 105084 +.. nonce: lvVvoj +.. section: Tests + +When the Python build is configured ``--with-wheel-pkg-dir``, tests +requiring the ``setuptools`` and ``wheel`` wheels will search for the wheels +in ``WHEEL_PKG_DIR``. + +.. + +.. date: 2023-06-08-11-30-17 +.. gh-issue: 105436 +.. nonce: 1qlDxw +.. section: Windows + +Ensure that an empty environment block is terminated by two null characters, +as is required by Windows. + +.. + +.. date: 2023-06-09-23-34-25 +.. gh-issue: 105375 +.. nonce: n7amiF +.. section: C API + +Fix a bug in :c:func:`PyErr_WarnExplicit` where an exception could end up +being overwritten if the API failed internally. + +.. + +.. date: 2023-06-09-19-16-57 +.. gh-issue: 105603 +.. nonce: -z6G22 +.. section: C API + +We've renamed the new (in 3.12) ``PyInterpreterConfig.own_gil`` to +``PyInterpreterConfig.gil`` and changed the meaning of the value from "bool" +to an integer with supported values of ``PyInterpreterConfig_DEFAULT_GIL``, +``PyInterpreterConfig_SHARED_GIL``, and ``PyInterpreterConfig_OWN_GIL``. The +default is "shared". + +.. + +.. date: 2023-06-09-12-35-55 +.. gh-issue: 105387 +.. nonce: wM_oL- +.. section: C API + +In the limited C API version 3.12, :c:func:`Py_INCREF` and +:c:func:`Py_DECREF` functions are now implemented as opaque function calls +to hide implementation details. Patch by Victor Stinner. + +.. + +.. date: 2023-06-06-14-14-41 +.. gh-issue: 103968 +.. nonce: BTO6II +.. section: C API + +:c:func:`PyType_FromMetaclass` now allows metaclasses with ``tp_new`` set to +``NULL``. diff --git a/Misc/NEWS.d/3.12.0b4.rst b/Misc/NEWS.d/3.12.0b4.rst new file mode 100644 index 00000000..5212f359 --- /dev/null +++ b/Misc/NEWS.d/3.12.0b4.rst @@ -0,0 +1,318 @@ +.. date: 2023-06-13-20-52-24 +.. gh-issue: 102988 +.. nonce: Kei7Vf +.. release date: 2023-07-11 +.. section: Security + +CVE-2023-27043: Prevent :func:`email.utils.parseaddr` and +:func:`email.utils.getaddresses` from returning the realname portion of an +invalid RFC2822 email header in the email address portion of the 2-tuple +returned after being parsed by :class:`email._parseaddr.AddressList`. + +.. + +.. date: 2023-07-04-09-51-45 +.. gh-issue: 106396 +.. nonce: DmYp7x +.. section: Core and Builtins + +When the format specification of an f-string expression is empty, the parser +now generates an empty :class:`ast.JoinedStr` node for it instead of an +one-element :class:`ast.JoinedStr` with an empty string +:class:`ast.Constant`. + +.. + +.. date: 2023-06-29-09-46-41 +.. gh-issue: 106145 +.. nonce: QC6-Kq +.. section: Core and Builtins + +Make ``end_lineno`` and ``end_col_offset`` required on ``type_param`` ast +nodes. + +.. + +.. date: 2023-06-22-19-16-24 +.. gh-issue: 105979 +.. nonce: TDP2CU +.. section: Core and Builtins + +Fix crash in :func:`!_imp.get_frozen_object` due to improper exception +handling. + +.. + +.. date: 2023-06-22-14-19-17 +.. gh-issue: 98931 +.. nonce: PPgvSF +.. section: Core and Builtins + +Ensure custom :exc:`SyntaxError` error messages are raised for invalid +imports with multiple targets. Patch by Pablo Galindo + +.. + +.. date: 2023-06-19-11-04-01 +.. gh-issue: 105908 +.. nonce: 7oanny +.. section: Core and Builtins + +Fixed bug where :gh:`99111` breaks future import ``barry_as_FLUFL`` in the +Python REPL. + +.. + +.. date: 2023-06-12-16-38-31 +.. gh-issue: 105340 +.. nonce: _jRHXe +.. section: Core and Builtins + +Include the comprehension iteration variable in ``locals()`` inside a +module- or class-scope comprehension. + +.. + +.. date: 2023-06-08-09-10-15 +.. gh-issue: 105486 +.. nonce: dev-WS +.. section: Core and Builtins + +Change the repr of ``ParamSpec`` list of args in ``types.GenericAlias``. + +.. + +.. date: 2023-01-13-11-37-41 +.. gh-issue: 101006 +.. nonce: fuLvn2 +.. section: Core and Builtins + +Improve error handling when read :mod:`marshal` data. + +.. + +.. date: 2023-07-07-17-44-03 +.. gh-issue: 106524 +.. nonce: XkBV8h +.. section: Library + +Fix crash in :func:`!_sre.template` with templates containing invalid group +indices. + +.. + +.. date: 2023-07-07-13-47-28 +.. gh-issue: 106510 +.. nonce: 9n5BdC +.. section: Library + +Improve debug output for atomic groups in regular expressions. + +.. + +.. date: 2023-07-07-03-05-58 +.. gh-issue: 106503 +.. nonce: ltfeiH +.. section: Library + +Fix ref cycle in :class:`!asyncio._SelectorSocketTransport` by removing +``_write_ready`` in ``close``. + +.. + +.. date: 2023-07-05-14-34-10 +.. gh-issue: 105497 +.. nonce: HU5u89 +.. section: Library + +Fix flag mask inversion when unnamed flags exist. + +.. + +.. date: 2023-07-05-13-08-23 +.. gh-issue: 90876 +.. nonce: Qvlkfl +.. section: Library + +Prevent :mod:`multiprocessing.spawn` from failing to *import* in +environments where ``sys.executable`` is ``None``. This regressed in 3.11 +with the addition of support for path-like objects in multiprocessing. + +.. + +.. date: 2023-07-03-15-09-44 +.. gh-issue: 106292 +.. nonce: 3npldV +.. section: Library + +Check for an instance-dict cached value in the :meth:`__get__` method of +:func:`functools.cached_property`. This better matches the pre-3.12 behavior +and improves compatibility for users subclassing +:func:`functools.cached_property` and adding a :meth:`__set__` method. + +.. + +.. date: 2023-07-02-10-56-41 +.. gh-issue: 106330 +.. nonce: QSkIUH +.. section: Library + +Fix incorrect matching of empty paths in :meth:`pathlib.PurePath.match`. +This bug was introduced in Python 3.12.0 beta 1. + +.. + +.. date: 2023-07-01-16-40-54 +.. gh-issue: 102541 +.. nonce: C1ahtk +.. section: Library + +Make pydoc.doc catch bad module ImportError when output stream is not None. + +.. + +.. date: 2023-06-27-23-22-37 +.. gh-issue: 106152 +.. nonce: ya5jBT +.. section: Library + +Added PY_THROW event hook for :mod:`cProfile` for generators + +.. + +.. date: 2023-06-25-12-28-55 +.. gh-issue: 106075 +.. nonce: W7tMRb +.. section: Library + +Added `asyncio.taskgroups.__all__` to `asyncio.__all__` for export in star +imports. + +.. + +.. date: 2023-06-22-15-21-11 +.. gh-issue: 105987 +.. nonce: T7Kzrb +.. section: Library + +Fix crash due to improper reference counting in :mod:`asyncio` eager task +factory internal routines. + +.. + +.. date: 2023-06-21-19-04-27 +.. gh-issue: 105974 +.. nonce: M47n3t +.. section: Library + +Fix bug where a :class:`typing.Protocol` class that had one or more +non-callable members would raise :exc:`TypeError` when :func:`issubclass` +was called against it, even if it defined a custom ``__subclasshook__`` +method. The behaviour in Python 3.11 and lower -- which has now been +restored -- was not to raise :exc:`TypeError` in these situations if a +custom ``__subclasshook__`` method was defined. Patch by Alex Waygood. + +.. + +.. date: 2023-06-20-23-18-45 +.. gh-issue: 96145 +.. nonce: o5dTRM +.. section: Library + +Reverted addition of ``json.AttrDict``. + +.. + +.. date: 2023-06-08-17-49-46 +.. gh-issue: 105497 +.. nonce: K6Q8nU +.. section: Library + +Fix flag inversion when alias/mask members exist. + +.. + +.. date: 2023-06-05-14-43-56 +.. gh-issue: 104554 +.. nonce: pwfKIo +.. section: Library + +Add RTSPS scheme support in urllib.parse + +.. + +.. date: 2022-07-12-18-45-13 +.. gh-issue: 94777 +.. nonce: mOybx7 +.. section: Library + +Fix hanging :mod:`multiprocessing` ``ProcessPoolExecutor`` when a child +process crashes while data is being written in the call queue. + +.. + +.. date: 2023-06-30-19-28-59 +.. gh-issue: 106232 +.. nonce: hQ4-tz +.. section: Documentation + +Make timeit doc command lines compatible with Windows by using double quotes +for arguments. This works on linux and macOS also. + +.. + +.. date: 2023-06-28-02-51-08 +.. gh-issue: 101634 +.. nonce: Rayczr +.. section: Tests + +When running the Python test suite with ``-jN`` option, if a worker stdout +cannot be decoded from the locale encoding report a failed testn so the +exitcode is non-zero. Patch by Victor Stinner. + +.. + +.. date: 2023-06-26-21-56-29 +.. gh-issue: 106118 +.. nonce: 0cCfhl +.. section: Build + +Fix compilation for platforms without :data:`!O_CLOEXEC`. The issue was +introduced with Python 3.12b1 in :gh:`103295`. Patch by Erlend Aasland. + +.. + +.. date: 2023-05-20-23-49-30 +.. gh-issue: 104692 +.. nonce: s5UIu5 +.. section: Build + +Include ``commoninstall`` as a prerequisite for ``bininstall`` + +This ensures that ``commoninstall`` is completed before ``bininstall`` is +started when parallel builds are used (``make -j install``), and so the +``python3`` symlink is only installed after all standard library modules are +installed. + +.. + +.. date: 2023-07-03-14-06-19 +.. gh-issue: 106359 +.. nonce: RfJuR0 +.. section: Tools/Demos + +Argument Clinic now explicitly forbids "kwarg splats" in function calls used +as annotations. + +.. + +.. date: 2023-06-13-14-24-55 +.. gh-issue: 105227 +.. nonce: HDL9aF +.. section: C API + +The new :c:func:`PyType_GetDict` provides the dictionary for the given type +object that is normally exposed by ``cls.__dict__``. Normally it's +sufficient to use :c:member:`~PyTypeObject.tp_dict`, but for the static +builtin types :c:member:`!tp_dict` is now always ``NULL``. +:c:func:`!PyType_GetDict()` provides the correct dict object instead. diff --git a/Misc/NEWS.d/3.12.0rc1.rst b/Misc/NEWS.d/3.12.0rc1.rst new file mode 100644 index 00000000..ca826cf2 --- /dev/null +++ b/Misc/NEWS.d/3.12.0rc1.rst @@ -0,0 +1,495 @@ +.. date: 2023-06-13-20-52-24 +.. gh-issue: 102988 +.. nonce: Kei7Vf +.. release date: 2023-08-05 +.. section: Security + +Reverted the :mod:`email.utils` security improvement change released in +3.12beta4 that unintentionally caused :mod:`email.utils.getaddresses` to +fail to parse email addresses with a comma in the quoted name field. See +:gh:`106669`. + +.. + +.. date: 2023-03-07-21-46-29 +.. gh-issue: 102509 +.. nonce: 5ouaH_ +.. section: Security + +Start initializing ``ob_digit`` during creation of :c:type:`PyLongObject` +objects. Patch by Illia Volochii. + +.. + +.. date: 2023-07-30-05-20-16 +.. gh-issue: 107263 +.. nonce: q0IU2M +.. section: Core and Builtins + +Increase C recursion limit for functions other than the main interpreter +from 800 to 1500. This should allow functions like ``list.__repr__`` and +``json.dumps`` to handle all the inputs that they could prior to 3.12 + +.. + +.. date: 2023-07-27-11-47-29 +.. gh-issue: 104432 +.. nonce: oGHF-z +.. section: Core and Builtins + +Fix potential unaligned memory access on C APIs involving returned sequences +of `char *` pointers within the :mod:`grp` and :mod:`socket` modules. These +were revealed using a ``-fsaniziter=alignment`` build on ARM macOS. Patch by +Christopher Chavez. + +.. + +.. date: 2023-07-26-21-28-06 +.. gh-issue: 106898 +.. nonce: 8Wjuiv +.. section: Core and Builtins + +Add the exception as the third argument to ``PY_UNIND`` callbacks in +``sys.monitoring``. This makes the ``PY_UNWIND`` callback consistent with +the other exception hanlding callbacks. + +.. + +.. date: 2023-07-26-18-53-34 +.. gh-issue: 106895 +.. nonce: DdEwV8 +.. section: Core and Builtins + +Raise a ``ValueError`` when a monitoring callback funtion returns +``DISABLE`` for events that cannot be disabled locally. + +.. + +.. date: 2023-07-26-12-18-10 +.. gh-issue: 106897 +.. nonce: EsGurc +.. section: Core and Builtins + +Add a ``RERAISE`` event to ``sys.monitoring``, which occurs when an +exception is reraised, either explicitly by a plain ``raise`` statement, or +implicitly in an ``except`` or ``finally`` block. + +.. + +.. date: 2023-07-24-11-11-41 +.. gh-issue: 104621 +.. nonce: vM8Y_l +.. section: Core and Builtins + +Unsupported modules now always fail to be imported. + +.. + +.. date: 2023-07-21-14-37-48 +.. gh-issue: 106917 +.. nonce: 1jWp_m +.. section: Core and Builtins + +Fix classmethod-style :func:`super` method calls (i.e., where the second +argument to :func:`super`, or the implied second argument drawn from +``self/cls`` in the case of zero-arg super, is a type) when the target of +the call is not a classmethod. + +.. + +.. date: 2023-07-20-15-15-57 +.. gh-issue: 105699 +.. nonce: DdqHFg +.. section: Core and Builtins + +Python no longer crashes due an infrequent race when initialzing +per-interpreter interned strings. The crash would manifest when the +interpreter was finalized. + +.. + +.. date: 2023-07-20-12-21-37 +.. gh-issue: 105699 +.. nonce: 08ywGV +.. section: Core and Builtins + +Python no longer crashes due to an infrequent race in setting +``Py_FileSystemDefaultEncoding`` and ``Py_FileSystemDefaultEncodeErrors`` +(both deprecated), when simultaneously initializing two isolated +subinterpreters. Now they are only set during runtime initialization. + +.. + +.. date: 2023-07-18-16-13-51 +.. gh-issue: 106092 +.. nonce: bObgRM +.. section: Core and Builtins + +Fix a segmentation fault caused by a use-after-free bug in ``frame_dealloc`` +when the trashcan delays the deallocation of a ``PyFrameObject``. + +.. + +.. date: 2023-07-13-15-59-07 +.. gh-issue: 106719 +.. nonce: jmVrsv +.. section: Core and Builtins + +No longer suppress arbitrary errors in the ``__annotations__`` getter and +setter in the type and module types. + +.. + +.. date: 2023-07-13-14-55-45 +.. gh-issue: 106723 +.. nonce: KsMufQ +.. section: Core and Builtins + +Propagate ``frozen_modules`` to multiprocessing spawned process +interpreters. + +.. + +.. date: 2023-06-02-19-37-29 +.. gh-issue: 105235 +.. nonce: fgFGTi +.. section: Core and Builtins + +Prevent out-of-bounds memory access during ``mmap.find()`` calls. + +.. + +.. date: 2023-08-03-12-52-19 +.. gh-issue: 107077 +.. nonce: -pzHD6 +.. section: Library + +Seems that in some conditions, OpenSSL will return ``SSL_ERROR_SYSCALL`` +instead of ``SSL_ERROR_SSL`` when a certification verification has failed, +but the error parameters will still contain ``ERR_LIB_SSL`` and +``SSL_R_CERTIFICATE_VERIFY_FAILED``. We are now detecting this situation and +raising the appropiate ``ssl.SSLCertVerificationError``. Patch by Pablo +Galindo + +.. + +.. date: 2023-08-03-11-31-11 +.. gh-issue: 107576 +.. nonce: pO_s9I +.. section: Library + +Fix :func:`types.get_original_bases` to only return :attr:`!__orig_bases__` +if it is present on ``cls`` directly. Patch by James Hilton-Balfe. + +.. + +.. date: 2023-07-24-01-21-16 +.. gh-issue: 46376 +.. nonce: w-xuDL +.. section: Library + +Prevent memory leak and use-after-free when using pointers to pointers with +ctypes + +.. + +.. date: 2023-07-23-12-26-23 +.. gh-issue: 62519 +.. nonce: w8-81X +.. section: Library + +Make :func:`gettext.pgettext` search plural definitions when translation is +not found. + +.. + +.. date: 2023-07-22-15-51-33 +.. gh-issue: 83006 +.. nonce: 21zaCz +.. section: Library + +Document behavior of :func:`shutil.disk_usage` for non-mounted filesystems +on Unix. + +.. + +.. date: 2023-07-22-13-09-28 +.. gh-issue: 106186 +.. nonce: EIsUNG +.. section: Library + +Do not report ``MultipartInvariantViolationDefect`` defect when the +:class:`email.parser.Parser` class is used to parse emails with +``headersonly=True``. + +.. + +.. date: 2023-07-22-12-53-53 +.. gh-issue: 105002 +.. nonce: gkfsW0 +.. section: Library + +Fix invalid result from :meth:`PurePath.relative_to` method when attempting +to walk a "``..``" segment in *other* with *walk_up* enabled. A +:exc:`ValueError` exception is now raised in this case. + +.. + +.. date: 2023-07-17-21-45-15 +.. gh-issue: 106831 +.. nonce: RqVq9X +.. section: Library + +Fix potential missing ``NULL`` check of ``d2i_SSL_SESSION`` result in +``_ssl.c``. + +.. + +.. date: 2023-07-15-10-24-56 +.. gh-issue: 106774 +.. nonce: FJcqCj +.. section: Library + +Update the bundled copy of pip to version 23.2.1. + +.. + +.. date: 2023-07-14-16-54-13 +.. gh-issue: 106752 +.. nonce: BT1Yxw +.. section: Library + +Fixed several bugs in zipfile.Path, including: in ``Path.match`, Windows +separators are no longer honored (and never were meant to be); Fixed +``name``/``suffix``/``suffixes``/``stem`` operations when no filename is +present and the Path is not at the root of the zipfile; Reworked glob for +performance and more correct matching behavior. + +.. + +.. date: 2023-07-12-04-58-45 +.. gh-issue: 106602 +.. nonce: dGCcXe +.. section: Library + +Add __copy__ and __deepcopy__ in :mod:`enum` + +.. + +.. date: 2023-07-11-09-25-40 +.. gh-issue: 106530 +.. nonce: VgXrMx +.. section: Library + +Revert a change to :func:`colorsys.rgb_to_hls` that caused division by zero +for certain almost-white inputs. Patch by Terry Jan Reedy. + +.. + +.. date: 2023-07-04-07-25-30 +.. gh-issue: 106403 +.. nonce: GmefbV +.. section: Library + +Instances of :class:`typing.TypeVar`, :class:`typing.ParamSpec`, +:class:`typing.ParamSpecArgs`, :class:`typing.ParamSpecKwargs`, and +:class:`typing.TypeVarTuple` once again support weak references, fixing a +regression introduced in Python 3.12.0 beta 1. Patch by Jelle Zijlstra. + +.. + +.. date: 2023-07-03-03-46-20 +.. gh-issue: 106350 +.. nonce: LLcTEe +.. section: Library + +Detect possible memory allocation failure in the libtommath function +:c:func:`mp_init` used by the ``_tkinter`` module. + +.. + +.. date: 2023-06-30-16-42-44 +.. gh-issue: 106263 +.. nonce: tk-t93 +.. section: Library + +Fix crash when calling ``repr`` with a manually constructed SignalDict +object. Patch by Charlie Zhao. + +.. + +.. date: 2023-06-10-12-20-17 +.. gh-issue: 105626 +.. nonce: XyZein +.. section: Library + +Change the default return value of +:meth:`http.client.HTTPConnection.get_proxy_response_headers` to be ``None`` +and not ``{}``. + +.. + +.. bpo: 18319 +.. date: 2020-05-03-00-33-15 +.. nonce: faPTlx +.. section: Library + +Ensure `gettext(msg)` retrieve translations even if a plural form exists. In +other words: `gettext(msg) == ngettext(msg, '', 1)`. + +.. + +.. date: 2023-07-26-16-33-04 +.. gh-issue: 107305 +.. nonce: qB2LS4 +.. section: Documentation + +Add documentation for :c:type:`PyInterpreterConfig` and +:c:func:`Py_NewInterpreterFromConfig`. Also clarify some of the nearby docs +relative to per-interpreter GIL. + +.. + +.. date: 2023-07-22-15-14-13 +.. gh-issue: 107008 +.. nonce: 3JQ1Vt +.. section: Documentation + +Document the :mod:`curses` module variables :const:`~curses.LINES` and +:const:`~curses.COLS`. + +.. + +.. date: 2023-07-21-11-51-57 +.. gh-issue: 106948 +.. nonce: K_JQ7j +.. section: Documentation + +Add a number of standard external names to ``nitpick_ignore``. + +.. + +.. date: 2023-05-16-22-08-24 +.. gh-issue: 54738 +.. nonce: mJvCnj +.. section: Documentation + +Add documentation on how to localize the :mod:`argparse` module. + +.. + +.. date: 2023-07-25-14-36-33 +.. gh-issue: 107237 +.. nonce: y1pY79 +.. section: Tests + +``test_logging``: Fix ``test_udp_reconnection()`` by increasing the timeout +from 100 ms to 5 minutes (LONG_TIMEOUT). Patch by Victor Stinner. + +.. + +.. date: 2023-07-22-13-49-40 +.. gh-issue: 106714 +.. nonce: btYI5S +.. section: Tests + +test_capi: Fix test_no_FatalError_infinite_loop() to no longer write a +coredump, by using test.support.SuppressCrashReport. Patch by Victor +Stinner. + +.. + +.. date: 2023-07-16-02-57-08 +.. gh-issue: 104090 +.. nonce: cKtK7g +.. section: Tests + +Avoid creating a reference to the test object in +:meth:`~unittest.TestResult.collectedDurations`. + +.. + +.. date: 2023-07-14-16-20-06 +.. gh-issue: 106752 +.. nonce: gd1i6D +.. section: Tests + +Moved tests for ``zipfile.Path`` into ``Lib/test/test_zipfile/_path``. Made +``zipfile._path`` a package. + +.. + +.. date: 2023-07-28-18-17-33 +.. gh-issue: 106881 +.. nonce: U3Ezdq +.. section: Build + +Check for `linux/limits.h` before including it in `Modules/posixmodule.c`. + +.. + +.. date: 2023-07-23-00-38-51 +.. gh-issue: 106962 +.. nonce: VVYrWB +.. section: Build + +Detect MPI compilers in :file:`configure`. + +.. + +.. date: 2023-02-03-21-36-42 +.. gh-issue: 101538 +.. nonce: sF5F6S +.. section: Build + +Add experimental wasi-threads support. Patch by Takashi Yamamoto. + +.. + +.. date: 2023-07-11-20-48-17 +.. gh-issue: 99079 +.. nonce: CIMftz +.. section: Windows + +Update Windows build to use OpenSSL 3.0.9 + +.. + +.. date: 2023-07-30-23-42-20 +.. gh-issue: 99079 +.. nonce: JAtoh1 +.. section: macOS + +Update macOS installer to use OpenSSL 3.0.9. + +.. + +.. date: 2023-07-21-23-16-05 +.. gh-issue: 106970 +.. nonce: NLRnml +.. section: Tools/Demos + +Fix bugs in the Argument Clinic ``destination <name> clear`` command; the +destination buffers would never be cleared, and the ``destination`` +directive parser would simply continue to the fault handler after processing +the command. Patch by Erlend E. Aasland. + +.. + +.. date: 2023-04-05-07-19-36 +.. gh-issue: 103186 +.. nonce: yEozgK +.. section: Tools/Demos + +``freeze`` now fetches ``CONFIG_ARGS`` from the original CPython instance +the Makefile uses to call utility scripts. Patch by Ijtaba Hussain. + +.. + +.. date: 2023-07-25-13-41-09 +.. gh-issue: 107226 +.. nonce: N919zH +.. section: C API + +:c:func:`PyModule_AddObjectRef` is now only available in the limited API +version 3.10 or later. diff --git a/Misc/NEWS.d/3.12.0rc2.rst b/Misc/NEWS.d/3.12.0rc2.rst new file mode 100644 index 00000000..6ca7cc63 --- /dev/null +++ b/Misc/NEWS.d/3.12.0rc2.rst @@ -0,0 +1,510 @@ +.. date: 2023-08-22-17-39-12 +.. gh-issue: 108310 +.. nonce: fVM3sg +.. release date: 2023-09-05 +.. section: Security + +Fixed an issue where instances of :class:`ssl.SSLSocket` were vulnerable to +a bypass of the TLS handshake and included protections (like certificate +verification) and treating sent unencrypted data as if it were +post-handshake TLS encrypted data. Security issue reported as +`CVE-2023-40217 +<https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-40217>`_ by Aapo +Oksman. Patch by Gregory P. Smith. + +.. + +.. date: 2023-08-05-03-51-05 +.. gh-issue: 107774 +.. nonce: VPjaTR +.. section: Security + +PEP 669 specifies that ``sys.monitoring.register_callback`` will generate an +audit event. Pre-releases of Python 3.12 did not generate the audit event. +This is now fixed. + +.. + +.. date: 2023-08-30-15-41-47 +.. gh-issue: 108520 +.. nonce: u0ZGP_ +.. section: Core and Builtins + +Fix :meth:`multiprocessing.synchronize.SemLock.__setstate__` to properly +initialize :attr:`multiprocessing.synchronize.SemLock._is_fork_ctx`. This +fixes a regression when passing a SemLock accross nested processes. + +Rename :attr:`multiprocessing.synchronize.SemLock.is_fork_ctx` to +:attr:`multiprocessing.synchronize.SemLock._is_fork_ctx` to avoid exposing +it as public API. + +.. + +.. date: 2023-08-29-17-53-12 +.. gh-issue: 108654 +.. nonce: jbkDVo +.. section: Core and Builtins + +Restore locals shadowed by an inlined comprehension if the comprehension +raises an exception. + +.. + +.. date: 2023-08-26-04-33-18 +.. gh-issue: 108487 +.. nonce: aUFxqf +.. section: Core and Builtins + +Change an assert that would cause a spurious crash in a devious case that +should only trigger deoptimization. + +.. + +.. date: 2023-08-25-14-51-06 +.. gh-issue: 106176 +.. nonce: D1EA2a +.. section: Core and Builtins + +Use a ``WeakValueDictionary`` to track the lists containing the modules each +thread is currently importing. This helps avoid a reference leak from +keeping the list around longer than necessary. Weakrefs are used as GC can't +interrupt the cleanup. + +.. + +.. date: 2023-08-21-21-13-30 +.. gh-issue: 107901 +.. nonce: hszvdk +.. section: Core and Builtins + +Fix missing line number on :opcode:`JUMP_BACKWARD` at the end of a for loop. + +.. + +.. date: 2023-08-13-17-18-22 +.. gh-issue: 108390 +.. nonce: TkBccC +.. section: Core and Builtins + +Raise an exception when setting a non-local event (``RAISE``, +``EXCEPTION_HANDLED``, etc.) in ``sys.monitoring.set_local_events``. + +Fixes crash when tracing in recursive calls to Python classes. + +.. + +.. date: 2023-08-10-17-36-27 +.. gh-issue: 91051 +.. nonce: LfaeNW +.. section: Core and Builtins + +Fix abort / segfault when using all eight type watcher slots, on platforms +where ``char`` is signed by default. + +.. + +.. date: 2023-08-04-21-25-26 +.. gh-issue: 107724 +.. nonce: EbBXMr +.. section: Core and Builtins + +In pre-release versions of 3.12, up to rc1, the sys.monitoring callback +function for the ``PY_THROW`` event was missing the third, exception +argument. That is now fixed. + +.. + +.. date: 2023-08-02-12-24-51 +.. gh-issue: 107080 +.. nonce: PNolFU +.. section: Core and Builtins + +Trace refs builds (``--with-trace-refs``) were crashing when used with +isolated subinterpreters. The problematic global state has been isolated to +each interpreter. Other fixing the crashes, this change does not affect +users. + +.. + +.. date: 2023-07-25-22-35-35 +.. gh-issue: 77377 +.. nonce: EHAbXx +.. section: Core and Builtins + +Ensure that multiprocessing synchronization objects created in a fork +context are not sent to a different process created in a spawn context. This +changes a segfault into an actionable RuntimeError in the parent process. + +.. + +.. date: 2023-09-03-04-37-52 +.. gh-issue: 108469 +.. nonce: kusj40 +.. section: Library + +:func:`ast.unparse` now supports new :term:`f-string` syntax introduced in +Python 3.12. Note that the :term:`f-string` quotes are reselected for +simplicity under the new syntax. (Patch by Steven Sun) + +.. + +.. date: 2023-08-30-20-10-28 +.. gh-issue: 108682 +.. nonce: c2gzLQ +.. section: Library + +Enum: raise :exc:`TypeError` if ``super().__new__()`` is called from a +custom ``__new__``. + +.. + +.. date: 2023-08-26-08-38-57 +.. gh-issue: 108295 +.. nonce: Pn0QRM +.. section: Library + +Fix crashes related to use of weakrefs on :data:`typing.TypeVar`. + +.. + +.. date: 2023-08-22-22-29-42 +.. gh-issue: 64662 +.. nonce: jHl_Bt +.. section: Library + +Fix support for virtual tables in :meth:`sqlite3.Connection.iterdump`. Patch +by Aviv Palivoda. + +.. + +.. date: 2023-08-22-17-27-12 +.. gh-issue: 108111 +.. nonce: N7a4u_ +.. section: Library + +Fix a regression introduced in GH-101251 for 3.12, resulting in an incorrect +offset calculation in :meth:`gzip.GzipFile.seek`. + +.. + +.. date: 2023-08-17-14-45-25 +.. gh-issue: 105736 +.. nonce: NJsH7r +.. section: Library + +Harmonized the pure Python version of :class:`~collections.OrderedDict` with +the C version. Now, both versions set up their internal state in +``__new__``. Formerly, the pure Python version did the set up in +``__init__``. + +.. + +.. date: 2023-08-17-12-59-35 +.. gh-issue: 108083 +.. nonce: 9J7UcT +.. section: Library + +Fix bugs in the constructor of :mod:`sqlite3.Connection` and +:meth:`sqlite3.Connection.close` where exceptions could be leaked. Patch by +Erlend E. Aasland. + +.. + +.. date: 2023-08-15-18-20-00 +.. gh-issue: 107963 +.. nonce: 20g5BG +.. section: Library + +Fix :func:`multiprocessing.set_forkserver_preload` to check the given list +of modules names. Patch by Donghee Na. + +.. + +.. date: 2023-08-14-23-11-11 +.. gh-issue: 106242 +.. nonce: 71HMym +.. section: Library + +Fixes :func:`os.path.normpath` to handle embedded null characters without +truncating the path. + +.. + +.. date: 2023-08-14-11-18-13 +.. gh-issue: 107913 +.. nonce: 4ooY6i +.. section: Library + +Fix possible losses of ``errno`` and ``winerror`` values in :exc:`OSError` +exceptions if they were cleared or modified by the cleanup code before +creating the exception object. + +.. + +.. date: 2023-08-10-17-36-22 +.. gh-issue: 107845 +.. nonce: dABiMJ +.. section: Library + +:func:`tarfile.data_filter` now takes the location of symlinks into account +when determining their target, so it will no longer reject some valid +tarballs with ``LinkOutsideDestinationError``. + +.. + +.. date: 2023-08-09-13-49-37 +.. gh-issue: 107805 +.. nonce: ezem0k +.. section: Library + +Fix signatures of module-level generated functions in :mod:`turtle`. + +.. + +.. date: 2023-08-07-14-12-07 +.. gh-issue: 107715 +.. nonce: 238r2f +.. section: Library + +Fix :meth:`doctest.DocTestFinder.find` in presence of class names with +special characters. Patch by Gertjan van Zwieten. + +.. + +.. date: 2023-08-06-15-29-00 +.. gh-issue: 100814 +.. nonce: h195gW +.. section: Library + +Passing a callable object as an option value to a Tkinter image now raises +the expected TclError instead of an AttributeError. + +.. + +.. date: 2023-08-05-05-10-41 +.. gh-issue: 106684 +.. nonce: P9zRXb +.. section: Library + +Close :class:`asyncio.StreamWriter` when it is not closed by application +leading to memory leaks. Patch by Kumar Aditya. + +.. + +.. date: 2023-07-31-07-36-24 +.. gh-issue: 107396 +.. nonce: 3_Kh6D +.. section: Library + +tarfiles; Fixed use before assignment of self.exception for gzip +decompression + +.. + +.. date: 2023-07-07-14-52-31 +.. gh-issue: 106052 +.. nonce: ak8nbs +.. section: Library + +:mod:`re` module: fix the matching of possessive quantifiers in the case of +a subpattern containing backtracking. + +.. + +.. date: 2023-03-14-01-19-57 +.. gh-issue: 100061 +.. nonce: CiXJYn +.. section: Library + +Fix a bug that causes wrong matches for regular expressions with possessive +qualifier. + +.. + +.. date: 2022-11-26-22-05-22 +.. gh-issue: 99203 +.. nonce: j0DUae +.. section: Library + +Restore following CPython <= 3.10.5 behavior of :func:`shutil.make_archive`: +do not create an empty archive if ``root_dir`` is not a directory, and, in +that case, raise :class:`FileNotFoundError` or :class:`NotADirectoryError` +regardless of ``format`` choice. Beyond the brought-back behavior, the +function may now also raise these exceptions in ``dry_run`` mode. + +.. + +.. date: 2023-05-29-14-10-24 +.. gh-issue: 105052 +.. nonce: MGFwbm +.. section: Documentation + +Update ``timeit`` doc to specify that time in seconds is just the default. + +.. + +.. date: 2023-09-04-15-18-14 +.. gh-issue: 89392 +.. nonce: 8A4T5p +.. section: Tests + +Removed support of ``test_main()`` function in tests. They now always use +normal unittest test runner. + +.. + +.. date: 2023-08-24-06-10-36 +.. gh-issue: 108388 +.. nonce: YCVB0D +.. section: Tests + +Convert test_concurrent_futures to a package of 7 sub-tests. Patch by Victor +Stinner. + +.. + +.. date: 2023-08-24-04-23-35 +.. gh-issue: 108388 +.. nonce: mr0MeE +.. section: Tests + +Split test_multiprocessing_fork, test_multiprocessing_forkserver and +test_multiprocessing_spawn into test packages. Each package is made of 4 +sub-tests: processes, threads, manager and misc. It allows running more +tests in parallel and so reduce the total test duration. Patch by Victor +Stinner. + +.. + +.. date: 2023-08-23-04-08-18 +.. gh-issue: 105776 +.. nonce: oE6wp_ +.. section: Tests + +Fix test_cppext when the C compiler command ``-std=c11`` option: remove +``-std=`` options from the compiler command. Patch by Victor Stinner. + +.. + +.. date: 2023-07-24-16-56-59 +.. gh-issue: 107178 +.. nonce: Gq1usE +.. section: Tests + +Add the C API test for functions in the Mapping Protocol, the Sequence +Protocol and some functions in the Object Protocol. + +.. + +.. date: 2023-09-02-18-04-15 +.. gh-issue: 63760 +.. nonce: r8hJ6q +.. section: Build + +Fix Solaris build: no longer redefine the ``gethostname()`` function. +Solaris defines the function since 2005. Patch by Victor Stinner, original +patch by Jakub Kulík. + +.. + +.. date: 2023-08-09-17-05-33 +.. gh-issue: 107814 +.. nonce: c0Oapq +.. section: Build + +When calling ``find_python.bat`` with ``-q`` it did not properly silence the +output of nuget. That is now fixed. + +.. + +.. date: 2023-09-05-10-08-47 +.. gh-issue: 107565 +.. nonce: CIMftz +.. section: Windows + +Update Windows build to use OpenSSL 3.0.10. + +.. + +.. date: 2023-08-22-00-36-57 +.. gh-issue: 106242 +.. nonce: q24ITw +.. section: Windows + +Fixes :func:`~os.path.realpath` to behave consistently when passed a path +containing an embedded null character on Windows. In strict mode, it now +raises :exc:`OSError` instead of the unexpected :exc:`ValueError`, and in +non-strict mode will make the path absolute. + +.. + +.. date: 2023-07-18-13-01-26 +.. gh-issue: 106844 +.. nonce: mci4xO +.. section: Windows + +Fix integer overflow and truncating by the null character in +:func:`!_winapi.LCMapStringEx` which affects :func:`ntpath.normcase`. + +.. + +.. date: 2023-08-12-13-33-57 +.. gh-issue: 107565 +.. nonce: SJwqf4 +.. section: macOS + +Update macOS installer to use OpenSSL 3.0.10. + +.. + +.. date: 2023-08-12-13-18-15 +.. gh-issue: 107565 +.. nonce: Tv22Ne +.. section: Tools/Demos + +Update multissltests and GitHub CI workflows to use OpenSSL 1.1.1v, 3.0.10, +and 3.1.2. + +.. + +.. date: 2023-08-07-16-30-48 +.. gh-issue: 95065 +.. nonce: -im4R5 +.. section: Tools/Demos + +Argument Clinic now supports overriding automatically generated signature by +using directive ``@text_signature``. + +.. + +.. date: 2023-08-14-10-59-03 +.. gh-issue: 107916 +.. nonce: KH4Muo +.. section: C API + +C API functions :c:func:`PyErr_SetFromErrnoWithFilename`, +:c:func:`PyErr_SetExcFromWindowsErrWithFilename` and +:c:func:`PyErr_SetFromWindowsErrWithFilename` save now the error code before +calling :c:func:`PyUnicode_DecodeFSDefault`. + +.. + +.. date: 2023-08-13-12-33-00 +.. gh-issue: 107915 +.. nonce: jQ0wOi +.. section: C API + +Such C API functions as ``PyErr_SetString()``, ``PyErr_Format()``, +``PyErr_SetFromErrnoWithFilename()`` and many others no longer crash or +ignore errors if it failed to format the error message or decode the +filename. Instead, they keep a corresponding error. + +.. + +.. date: 2023-08-10-11-12-25 +.. gh-issue: 107810 +.. nonce: oJ40Qx +.. section: C API + +Improve :exc:`DeprecationWarning` for uses of :c:type:`PyType_Spec` with +metaclasses that have custom ``tp_new``. diff --git a/Misc/NEWS.d/3.12.0rc3.rst b/Misc/NEWS.d/3.12.0rc3.rst new file mode 100644 index 00000000..8fe0dd29 --- /dev/null +++ b/Misc/NEWS.d/3.12.0rc3.rst @@ -0,0 +1,319 @@ +.. date: 2023-09-18-15-35-08 +.. gh-issue: 109496 +.. nonce: Kleoz3 +.. release date: 2023-09-18 +.. section: Core and Builtins + +On a Python built in debug mode, :c:func:`Py_DECREF()` now calls +``_Py_NegativeRefcount()`` if the object is a dangling pointer to +deallocated memory: memory filled with ``0xDD`` "dead byte" by the debug +hook on memory allocators. The fix is to check the reference count *before* +checking for ``_Py_IsImmortal()``. Patch by Victor Stinner. + +.. + +.. date: 2023-09-13-21-04-04 +.. gh-issue: 109371 +.. nonce: HPEJr8 +.. section: Core and Builtins + +Deopted instructions correctly for tool initialization and modified the +incorrect assertion in instrumentation, when a previous tool already sets +INSTRUCTION events + +.. + +.. date: 2023-09-13-19-16-51 +.. gh-issue: 105658 +.. nonce: z2nR2u +.. section: Core and Builtins + +Fix bug where the line trace of an except block ending with a conditional +includes an excess event with the line of the conditional expression. + +.. + +.. date: 2023-09-13-08-42-45 +.. gh-issue: 109219 +.. nonce: UiN8sc +.. section: Core and Builtins + +Fix compiling type param scopes that use a name which is also free in an +inner scope. + +.. + +.. date: 2023-09-12-15-45-49 +.. gh-issue: 109341 +.. nonce: 4V5bkm +.. section: Core and Builtins + +Fix crash when compiling an invalid AST involving a :class:`ast.TypeAlias`. + +.. + +.. date: 2023-09-11-15-51-55 +.. gh-issue: 109195 +.. nonce: iwxmuo +.. section: Core and Builtins + +Fix source location for the ``LOAD_*`` instruction preceding a +``LOAD_SUPER_ATTR`` to load the ``super`` global (or shadowing variable) so +that it encompasses only the name ``super`` and not the following +parentheses. + +.. + +.. date: 2023-09-09-12-49-46 +.. gh-issue: 109118 +.. nonce: gx0X4h +.. section: Core and Builtins + +Disallow nested scopes (lambdas, generator expressions, and comprehensions) +within PEP 695 annotation scopes that are nested within classes. + +.. + +.. date: 2023-09-08-01-50-41 +.. gh-issue: 109114 +.. nonce: adqgtb +.. section: Core and Builtins + +Relax the detection of the error message for invalid lambdas inside +f-strings to not search for arbitrary replacement fields to avoid false +positives. Patch by Pablo Galindo + +.. + +.. date: 2023-09-07-18-24-42 +.. gh-issue: 109118 +.. nonce: yPXRAe +.. section: Core and Builtins + +Fix interpreter crash when a NameError is raised inside the type parameters +of a generic class. + +.. + +.. date: 2023-09-06-22-50-25 +.. gh-issue: 108976 +.. nonce: MUKaIJ +.. section: Core and Builtins + +Fix crash that occurs after de-instrumenting a code object in a monitoring +callback. + +.. + +.. date: 2023-09-06-13-28-42 +.. gh-issue: 108732 +.. nonce: I6DkEQ +.. section: Core and Builtins + +Make iteration variables of module- and class-scoped comprehensions visible +to pdb and other tools that use ``frame.f_locals`` again. + +.. + +.. date: 2023-09-05-20-52-17 +.. gh-issue: 108959 +.. nonce: 6z45Sy +.. section: Core and Builtins + +Fix caret placement for error locations for subscript and binary operations +that involve non-semantic parentheses and spaces. Patch by Pablo Galindo + +.. + +.. date: 2023-09-06-19-33-41 +.. gh-issue: 108682 +.. nonce: 35Xnc5 +.. section: Library + +Enum: require ``names=()`` or ``type=...`` to create an empty enum using the +functional syntax. + +.. + +.. date: 2023-09-06-06-17-23 +.. gh-issue: 108843 +.. nonce: WJMhsS +.. section: Library + +Fix an issue in :func:`ast.unparse` when unparsing f-strings containing many +quote types. + +.. + +.. date: 2023-03-19-09-39-31 +.. gh-issue: 102823 +.. nonce: OzsOz0 +.. section: Documentation + +Document the return type of ``x // y`` when ``x`` and ``y`` have type +:class:`float`. + +.. + +.. date: 2023-09-14-22-58-47 +.. gh-issue: 109396 +.. nonce: J1a4jR +.. section: Tests + +Fix ``test_socket.test_hmac_sha1()`` in FIPS mode. Use a longer key: FIPS +mode requires at least of at least 112 bits. The previous key was only 32 +bits. Patch by Victor Stinner. + +.. + +.. date: 2023-09-13-05-58-09 +.. gh-issue: 104736 +.. nonce: lA25Fu +.. section: Tests + +Fix test_gdb on Python built with LLVM clang 16 on Linux ppc64le (ex: Fedora +38). Search patterns in gdb "bt" command output to detect when gdb fails to +retrieve the traceback. For example, skip a test if ``Backtrace stopped: +frame did not save the PC`` is found. Patch by Victor Stinner. + +.. + +.. date: 2023-09-10-22-32-20 +.. gh-issue: 109237 +.. nonce: SvgKwD +.. section: Tests + +Fix ``test_site.test_underpth_basic()`` when the working directory contains +at least one non-ASCII character: encode the ``._pth`` file to UTF-8 and +enable the UTF-8 Mode to use UTF-8 for the child process stdout. Patch by +Victor Stinner. + +.. + +.. date: 2023-09-10-19-59-57 +.. gh-issue: 109230 +.. nonce: SRNLFQ +.. section: Tests + +Fix ``test_pyexpat.test_exception()``: it can now be run from a directory +different than Python source code directory. Before, the test failed in this +case. Skip the test if Modules/pyexpat.c source is not available. Skip also +the test on Python implementations other than CPython. Patch by Victor +Stinner. + +.. + +.. date: 2023-09-06-18-27-53 +.. gh-issue: 109015 +.. nonce: 1dS1AQ +.. section: Tests + +Fix test_asyncio, test_imaplib and test_socket tests on FreeBSD if the TCP +blackhole is enabled (``sysctl net.inet.tcp.blackhole``). Skip the few tests +which failed with ``ETIMEDOUT`` which such non standard configuration. +Currently, the `FreeBSD GCP image enables TCP and UDP blackhole +<https://reviews.freebsd.org/D41751>`_ (``sysctl net.inet.tcp.blackhole=2`` +and ``sysctl net.inet.udp.blackhole=1``). Patch by Victor Stinner. + +.. + +.. date: 2023-09-06-15-36-51 +.. gh-issue: 91960 +.. nonce: P3nD5v +.. section: Tests + +Skip ``test_gdb`` if gdb is unable to retrieve Python frame objects: if a +frame is ``<optimized out>``. When Python is built with "clang -Og", gdb can +fail to retrive the *frame* parameter of ``_PyEval_EvalFrameDefault()``. In +this case, tests like ``py_bt()`` are likely to fail. Without getting access +to Python frames, ``python-gdb.py`` is mostly clueless on retrieving the +Python traceback. Moreover, ``test_gdb`` is no longer skipped on macOS if +Python is built with Clang. Patch by Victor Stinner. + +.. + +.. date: 2023-09-05-23-00-09 +.. gh-issue: 108962 +.. nonce: R4NwuU +.. section: Tests + +Skip ``test_tempfile.test_flags()`` if ``chflags()`` fails with "OSError: +[Errno 45] Operation not supported" (ex: on FreeBSD 13). Patch by Victor +Stinner. + +.. + +.. date: 2023-09-03-21-41-10 +.. gh-issue: 108851 +.. nonce: xFTYOE +.. section: Tests + +Fix ``test_tomllib`` recursion tests for WASI buildbots: reduce the +recursion limit and compute the maximum nested array/dict depending on the +current available recursion limit. Patch by Victor Stinner. + +.. + +.. date: 2023-09-03-21-18-35 +.. gh-issue: 108851 +.. nonce: CCuHyI +.. section: Tests + +Add ``get_recursion_available()`` and ``get_recursion_depth()`` functions to +the :mod:`test.support` module. Patch by Victor Stinner. + +.. + +.. date: 2023-09-03-20-15-49 +.. gh-issue: 108834 +.. nonce: Osvmhf +.. section: Tests + +Add ``--fail-rerun option`` option to regrtest: if a test failed when then +passed when rerun in verbose mode, exit the process with exit code 2 +(error), instead of exit code 0 (success). Patch by Victor Stinner. + +.. + +.. date: 2023-09-03-06-17-12 +.. gh-issue: 108834 +.. nonce: fjV-CJ +.. section: Tests + +Rename regrtest ``--verbose2`` option (``-w``) to ``--rerun``. Keep +``--verbose2`` as a deprecated alias. Patch by Victor Stinner. + +.. + +.. date: 2023-09-03-02-01-55 +.. gh-issue: 108834 +.. nonce: iAwXzj +.. section: Tests + +When regrtest reruns failed tests in verbose mode (``./python -m test +--rerun``), tests are now rerun in fresh worker processes rather than being +executed in the main process. If a test does crash or is killed by a +timeout, the main process can detect and handle the killed worker process. +Tests are rerun in parallel if the ``-jN`` option is used to run tests in +parallel. Patch by Victor Stinner. + +.. + +.. date: 2023-04-05-06-45-20 +.. gh-issue: 103186 +.. nonce: 640Eg- +.. section: Tests + +Suppress and assert expected RuntimeWarnings in test_sys_settrace.py + +.. + +.. date: 2023-09-01-01-39-26 +.. gh-issue: 108740 +.. nonce: JHExAQ +.. section: Build + +Fix a race condition in ``make regen-all``. The ``deepfreeze.c`` source and +files generated by Argument Clinic are now generated or updated before +generating "global objects". Previously, some identifiers may miss depending +on the order in which these files were generated. Patch by Victor Stinner. diff --git a/Misc/NEWS.d/3.5.0.rst b/Misc/NEWS.d/3.5.0.rst new file mode 100644 index 00000000..94999742 --- /dev/null +++ b/Misc/NEWS.d/3.5.0.rst @@ -0,0 +1,8 @@ +.. bpo: 25071 +.. date: 9305 +.. nonce: EwjXl1 +.. release date: 2015-09-13 +.. section: Build + +Windows installer should not require TargetDir parameter when installing +quietly. diff --git a/Misc/NEWS.d/3.5.0a1.rst b/Misc/NEWS.d/3.5.0a1.rst new file mode 100644 index 00000000..96e59206 --- /dev/null +++ b/Misc/NEWS.d/3.5.0a1.rst @@ -0,0 +1,5869 @@ +.. bpo: 23285 +.. date: 8948 +.. nonce: bJJA8B +.. release date: 2015-02-08 +.. section: Core and Builtins + +PEP 475 - EINTR handling. + +.. + +.. bpo: 22735 +.. date: 8947 +.. nonce: mFEX9n +.. section: Core and Builtins + +Fix many edge cases (including crashes) involving custom mro() +implementations. + +.. + +.. bpo: 22896 +.. date: 8946 +.. nonce: xSDAHK +.. section: Core and Builtins + +Avoid using PyObject_AsCharBuffer(), PyObject_AsReadBuffer() and +PyObject_AsWriteBuffer(). + +.. + +.. bpo: 21295 +.. date: 8945 +.. nonce: LYq9nF +.. section: Core and Builtins + +Revert some changes (issue #16795) to AST line numbers and column offsets +that constituted a regression. + +.. + +.. bpo: 22986 +.. date: 8944 +.. nonce: yay2Lv +.. section: Core and Builtins + +Allow changing an object's __class__ between a dynamic type and static type +in some cases. + +.. + +.. bpo: 15859 +.. date: 8943 +.. nonce: Fs5mE2 +.. section: Core and Builtins + +PyUnicode_EncodeFSDefault(), PyUnicode_EncodeMBCS() and +PyUnicode_EncodeCodePage() now raise an exception if the object is not a +Unicode object. For PyUnicode_EncodeFSDefault(), it was already the case on +platforms other than Windows. Patch written by Campbell Barton. + +.. + +.. bpo: 21408 +.. date: 8942 +.. nonce: Lz6P3P +.. section: Core and Builtins + +The default __ne__() now returns NotImplemented if __eq__() returned +NotImplemented. Original patch by Martin Panter. + +.. + +.. bpo: 23321 +.. date: 8941 +.. nonce: HQelge +.. section: Core and Builtins + +Fixed a crash in str.decode() when error handler returned replacement string +longer than malformed input data. + +.. + +.. bpo: 22286 +.. date: 8940 +.. nonce: l6Qyy1 +.. section: Core and Builtins + +The "backslashreplace" error handlers now works with decoding and +translating. + +.. + +.. bpo: 23253 +.. date: 8939 +.. nonce: p4B1H- +.. section: Core and Builtins + +Delay-load ShellExecute[AW] in os.startfile for reduced startup overhead on +Windows. + +.. + +.. bpo: 22038 +.. date: 8938 +.. nonce: BMZUHx +.. section: Core and Builtins + +pyatomic.h now uses stdatomic.h or GCC built-in functions for atomic memory +access if available. Patch written by Vitor de Lima and Gustavo Temple. + +.. + +.. bpo: 20284 +.. date: 8937 +.. nonce: CH8wpD +.. section: Core and Builtins + +%-interpolation (aka printf) formatting added for bytes and bytearray. + +.. + +.. bpo: 23048 +.. date: 8936 +.. nonce: X5BUd3 +.. section: Core and Builtins + +Fix jumping out of an infinite while loop in the pdb. + +.. + +.. bpo: 20335 +.. date: 8935 +.. nonce: YcAPOs +.. section: Core and Builtins + +bytes constructor now raises TypeError when encoding or errors is specified +with non-string argument. Based on patch by Renaud Blanch. + +.. + +.. bpo: 22834 +.. date: 8934 +.. nonce: N1kAXN +.. section: Core and Builtins + +If the current working directory ends up being set to a non-existent +directory then import will no longer raise FileNotFoundError. + +.. + +.. bpo: 22869 +.. date: 8933 +.. nonce: rAWg-V +.. section: Core and Builtins + +Move the interpreter startup & shutdown code to a new dedicated +pylifecycle.c module + +.. + +.. bpo: 22847 +.. date: 8932 +.. nonce: 6baj9f +.. section: Core and Builtins + +Improve method cache efficiency. + +.. + +.. bpo: 22335 +.. date: 8931 +.. nonce: DWsXiy +.. section: Core and Builtins + +Fix crash when trying to enlarge a bytearray to 0x7fffffff bytes on a 32-bit +platform. + +.. + +.. bpo: 22653 +.. date: 8930 +.. nonce: pCNlpv +.. section: Core and Builtins + +Fix an assertion failure in debug mode when doing a reentrant dict insertion +in debug mode. + +.. + +.. bpo: 22643 +.. date: 8929 +.. nonce: xv8xev +.. section: Core and Builtins + +Fix integer overflow in Unicode case operations (upper, lower, title, +swapcase, casefold). + +.. + +.. bpo: 17636 +.. date: 8928 +.. nonce: wiqnhw +.. section: Core and Builtins + +Circular imports involving relative imports are now supported. + +.. + +.. bpo: 22604 +.. date: 8927 +.. nonce: yii-It +.. section: Core and Builtins + +Fix assertion error in debug mode when dividing a complex number by +(nan+0j). + +.. + +.. bpo: 21052 +.. date: 8926 +.. nonce: -sf3tp +.. section: Core and Builtins + +Do not raise ImportWarning when sys.path_hooks or sys.meta_path are set to +None. + +.. + +.. bpo: 16518 +.. date: 8925 +.. nonce: UADwcN +.. section: Core and Builtins + +Use 'bytes-like object required' in error messages that previously used the +far more cryptic "'x' does not support the buffer protocol. + +.. + +.. bpo: 22470 +.. date: 8924 +.. nonce: igrgN2 +.. section: Core and Builtins + +Fixed integer overflow issues in "backslashreplace", "xmlcharrefreplace", +and "surrogatepass" error handlers. + +.. + +.. bpo: 22540 +.. date: 8923 +.. nonce: FM72m- +.. section: Core and Builtins + +speed up `PyObject_IsInstance` and `PyObject_IsSubclass` in the common case +that the second argument has metaclass `type`. + +.. + +.. bpo: 18711 +.. date: 8922 +.. nonce: ds5wQa +.. section: Core and Builtins + +Add a new `PyErr_FormatV` function, similar to `PyErr_Format` but accepting +a `va_list` argument. + +.. + +.. bpo: 22520 +.. date: 8921 +.. nonce: ZPJXSq +.. section: Core and Builtins + +Fix overflow checking when generating the repr of a unicode object. + +.. + +.. bpo: 22519 +.. date: 8920 +.. nonce: xvJVg0 +.. section: Core and Builtins + +Fix overflow checking in PyBytes_Repr. + +.. + +.. bpo: 22518 +.. date: 8919 +.. nonce: C9T6ed +.. section: Core and Builtins + +Fix integer overflow issues in latin-1 encoding. + +.. + +.. bpo: 16324 +.. date: 8918 +.. nonce: YfrBNz +.. section: Core and Builtins + +_charset parameter of MIMEText now also accepts email.charset.Charset +instances. Initial patch by Claude Paroz. + +.. + +.. bpo: 1764286 +.. date: 8917 +.. nonce: L4seL2 +.. section: Core and Builtins + +Fix inspect.getsource() to support decorated functions. Patch by Claudiu +Popa. + +.. + +.. bpo: 18554 +.. date: 8916 +.. nonce: hxnaui +.. section: Core and Builtins + +os.__all__ includes posix functions. + +.. + +.. bpo: 21391 +.. date: 8915 +.. nonce: 3jntPd +.. section: Core and Builtins + +Use os.path.abspath in the shutil module. + +.. + +.. bpo: 11471 +.. date: 8914 +.. nonce: Uu752F +.. section: Core and Builtins + +avoid generating a JUMP_FORWARD instruction at the end of an if-block if +there is no else-clause. Original patch by Eugene Toder. + +.. + +.. bpo: 22215 +.. date: 8913 +.. nonce: IBFi6H +.. section: Core and Builtins + +Now ValueError is raised instead of TypeError when str or bytes argument +contains not permitted null character or byte. + +.. + +.. bpo: 22258 +.. date: 8912 +.. nonce: 4FszMt +.. section: Core and Builtins + +Fix the internal function set_inheritable() on Illumos. This platform +exposes the function ``ioctl(FIOCLEX)``, but calling it fails with errno is +ENOTTY: "Inappropriate ioctl for device". set_inheritable() now falls back +to the slower ``fcntl()`` (``F_GETFD`` and then ``F_SETFD``). + +.. + +.. bpo: 21389 +.. date: 8911 +.. nonce: dnWZBn +.. section: Core and Builtins + +Displaying the __qualname__ of the underlying function in the repr of a +bound method. + +.. + +.. bpo: 22206 +.. date: 8910 +.. nonce: 0i_ihB +.. section: Core and Builtins + +Using pthread, PyThread_create_key() now sets errno to ENOMEM and returns -1 +(error) on integer overflow. + +.. + +.. bpo: 20184 +.. date: 8909 +.. nonce: bb3uHY +.. section: Core and Builtins + +Argument Clinic based signature introspection added for 30 of the builtin +functions. + +.. + +.. bpo: 22116 +.. date: 8908 +.. nonce: auVmIt +.. section: Core and Builtins + +C functions and methods (of the 'builtin_function_or_method' type) can now +be weakref'ed. Patch by Wei Wu. + +.. + +.. bpo: 22077 +.. date: 8907 +.. nonce: KZUDR- +.. section: Core and Builtins + +Improve index error messages for bytearrays, bytes, lists, and tuples by +adding 'or slices'. Added ', not <typename>' for bytearrays. Original patch +by Claudiu Popa. + +.. + +.. bpo: 20179 +.. date: 8906 +.. nonce: Nvhffc +.. section: Core and Builtins + +Apply Argument Clinic to bytes and bytearray. Patch by Tal Einat. + +.. + +.. bpo: 22082 +.. date: 8905 +.. nonce: 6X8Qmg +.. section: Core and Builtins + +Clear interned strings in slotdefs. + +.. + +.. bpo: 0 +.. date: 8904 +.. nonce: tuMnCc +.. section: Core and Builtins + +Upgrade Unicode database to Unicode 7.0.0. + +.. + +.. bpo: 21897 +.. date: 8903 +.. nonce: kiOGHe +.. section: Core and Builtins + +Fix a crash with the f_locals attribute with closure variables when +frame.clear() has been called. + +.. + +.. bpo: 21205 +.. date: 8902 +.. nonce: wZsx1K +.. section: Core and Builtins + +Add a new ``__qualname__`` attribute to generator, the qualified name, and +use it in the representation of a generator (``repr(gen)``). The default +name of the generator (``__name__`` attribute) is now get from the function +instead of the code. Use ``gen.gi_code.co_name`` to get the name of the +code. + +.. + +.. bpo: 21669 +.. date: 8901 +.. nonce: DFDrBA +.. section: Core and Builtins + +With the aid of heuristics in SyntaxError.__init__, the parser now attempts +to generate more meaningful (or at least more search engine friendly) error +messages when "exec" and "print" are used as statements. + +.. + +.. bpo: 21642 +.. date: 8900 +.. nonce: -lWoKz +.. section: Core and Builtins + +In the conditional if-else expression, allow an integer written with no +space between itself and the ``else`` keyword (e.g. ``True if 42else +False``) to be valid syntax. + +.. + +.. bpo: 21523 +.. date: 8899 +.. nonce: f_PPYO +.. section: Core and Builtins + +Fix over-pessimistic computation of the stack effect of some opcodes in the +compiler. This also fixes a quadratic compilation time issue noticeable +when compiling code with a large number of "and" and "or" operators. + +.. + +.. bpo: 21418 +.. date: 8898 +.. nonce: z9jp1_ +.. section: Core and Builtins + +Fix a crash in the builtin function super() when called without argument and +without current frame (ex: embedded Python). + +.. + +.. bpo: 21425 +.. date: 8897 +.. nonce: i3Teb8 +.. section: Core and Builtins + +Fix flushing of standard streams in the interactive interpreter. + +.. + +.. bpo: 21435 +.. date: 8896 +.. nonce: ZojVOT +.. section: Core and Builtins + +In rare cases, when running finalizers on objects in cyclic trash a bad +pointer dereference could occur due to a subtle flaw in internal iteration +logic. + +.. + +.. bpo: 21377 +.. date: 8895 +.. nonce: OawYfl +.. section: Core and Builtins + +PyBytes_Concat() now tries to concatenate in-place when the first argument +has a reference count of 1. Patch by Nikolaus Rath. + +.. + +.. bpo: 20355 +.. date: 8894 +.. nonce: OrCNkZ +.. section: Core and Builtins + +-W command line options now have higher priority than the PYTHONWARNINGS +environment variable. Patch by Arfrever. + +.. + +.. bpo: 21274 +.. date: 8893 +.. nonce: fVGfwq +.. section: Core and Builtins + +Define PATH_MAX for GNU/Hurd in Python/pythonrun.c. + +.. + +.. bpo: 20904 +.. date: 8892 +.. nonce: fAGdj2 +.. section: Core and Builtins + +Support setting FPU precision on m68k. + +.. + +.. bpo: 21209 +.. date: 8891 +.. nonce: nMljFr +.. section: Core and Builtins + +Fix sending tuples to custom generator objects with the yield from syntax. + +.. + +.. bpo: 21193 +.. date: 8890 +.. nonce: Dg98Oo +.. section: Core and Builtins + +pow(a, b, c) now raises ValueError rather than TypeError when b is negative. +Patch by Josh Rosenberg. + +.. + +.. bpo: 21176 +.. date: 8889 +.. nonce: mitDhW +.. section: Core and Builtins + +PEP 465: Add the '@' operator for matrix multiplication. + +.. + +.. bpo: 21134 +.. date: 8888 +.. nonce: ZL4SKo +.. section: Core and Builtins + +Fix segfault when str is called on an uninitialized UnicodeEncodeError, +UnicodeDecodeError, or UnicodeTranslateError object. + +.. + +.. bpo: 19537 +.. date: 8887 +.. nonce: AkuC_J +.. section: Core and Builtins + +Fix PyUnicode_DATA() alignment under m68k. Patch by Andreas Schwab. + +.. + +.. bpo: 20929 +.. date: 8886 +.. nonce: 9NlUR7 +.. section: Core and Builtins + +Add a type cast to avoid shifting a negative number. + +.. + +.. bpo: 20731 +.. date: 8885 +.. nonce: _03SZg +.. section: Core and Builtins + +Properly position in source code files even if they are opened in text mode. +Patch by Serhiy Storchaka. + +.. + +.. bpo: 20637 +.. date: 8884 +.. nonce: ppYU0o +.. section: Core and Builtins + +Key-sharing now also works for instance dictionaries of subclasses. Patch +by Peter Ingebretson. + +.. + +.. bpo: 8297 +.. date: 8883 +.. nonce: _XdGON +.. section: Core and Builtins + +Attributes missing from modules now include the module name in the error +text. Original patch by ysj.ray. + +.. + +.. bpo: 19995 +.. date: 8882 +.. nonce: mnHEzX +.. section: Core and Builtins + +%c, %o, %x, and %X now raise TypeError on non-integer input. + +.. + +.. bpo: 19655 +.. date: 8881 +.. nonce: JgVdes +.. section: Core and Builtins + +The ASDL parser - used by the build process to generate code for managing +the Python AST in C - was rewritten. The new parser is self contained and +does not require to carry long the spark.py parser-generator library; +spark.py was removed from the source base. + +.. + +.. bpo: 12546 +.. date: 8880 +.. nonce: 09naZ9 +.. section: Core and Builtins + +Allow ``\x00`` to be used as a fill character when using str, int, float, +and complex __format__ methods. + +.. + +.. bpo: 20480 +.. date: 8879 +.. nonce: TIYPLo +.. section: Core and Builtins + +Add ipaddress.reverse_pointer. Patch by Leon Weber. + +.. + +.. bpo: 13598 +.. date: 8878 +.. nonce: GJelrw +.. section: Core and Builtins + +Modify string.Formatter to support auto-numbering of replacement fields. It +now matches the behavior of str.format() in this regard. Patches by Phil +Elson and Ramchandra Apte. + +.. + +.. bpo: 8931 +.. date: 8877 +.. nonce: M05x4f +.. section: Core and Builtins + +Make alternate formatting ('#') for type 'c' raise an exception. In versions +prior to 3.5, '#' with 'c' had no effect. Now specifying it is an error. +Patch by Torsten Landschoff. + +.. + +.. bpo: 23165 +.. date: 8876 +.. nonce: lk8uCE +.. section: Core and Builtins + +Perform overflow checks before allocating memory in the _Py_char2wchar +function. + +.. + +.. bpo: 23399 +.. date: 8875 +.. nonce: hXMYgA +.. section: Library + +pyvenv creates relative symlinks where possible. + +.. + +.. bpo: 20289 +.. date: 8874 +.. nonce: nio1N- +.. section: Library + +cgi.FieldStorage() now supports the context management protocol. + +.. + +.. bpo: 13128 +.. date: 8873 +.. nonce: vqEcsy +.. section: Library + +Print response headers for CONNECT requests when debuglevel > 0. Patch by +Demian Brecht. + +.. + +.. bpo: 15381 +.. date: 8872 +.. nonce: Xv-wu8 +.. section: Library + +Optimized io.BytesIO to make less allocations and copyings. + +.. + +.. bpo: 22818 +.. date: 8871 +.. nonce: NYdAc9 +.. section: Library + +Splitting on a pattern that could match an empty string now raises a +warning. Patterns that can only match empty strings are now rejected. + +.. + +.. bpo: 23099 +.. date: 8870 +.. nonce: ZASrUo +.. section: Library + +Closing io.BytesIO with exported buffer is rejected now to prevent +corrupting exported buffer. + +.. + +.. bpo: 23326 +.. date: 8869 +.. nonce: 8VzlZD +.. section: Library + +Removed __ne__ implementations. Since fixing default __ne__ implementation +in issue #21408 they are redundant. + +.. + +.. bpo: 23363 +.. date: 8868 +.. nonce: -koaol +.. section: Library + +Fix possible overflow in itertools.permutations. + +.. + +.. bpo: 23364 +.. date: 8867 +.. nonce: 3yBV-6 +.. section: Library + +Fix possible overflow in itertools.product. + +.. + +.. bpo: 23366 +.. date: 8866 +.. nonce: tyAfm8 +.. section: Library + +Fixed possible integer overflow in itertools.combinations. + +.. + +.. bpo: 23369 +.. date: 8865 +.. nonce: nqChyE +.. section: Library + +Fixed possible integer overflow in _json.encode_basestring_ascii. + +.. + +.. bpo: 23353 +.. date: 8864 +.. nonce: Iytkpc +.. section: Library + +Fix the exception handling of generators in PyEval_EvalFrameEx(). At entry, +save or swap the exception state even if PyEval_EvalFrameEx() is called with +throwflag=0. At exit, the exception state is now always restored or swapped, +not only if why is WHY_YIELD or WHY_RETURN. Patch co-written with Antoine +Pitrou. + +.. + +.. bpo: 14099 +.. date: 8863 +.. nonce: t9-HVE +.. section: Library + +Restored support of writing ZIP files to tellable but non-seekable streams. + +.. + +.. bpo: 14099 +.. date: 8862 +.. nonce: Myxxww +.. section: Library + +Writing to ZipFile and reading multiple ZipExtFiles is threadsafe now. + +.. + +.. bpo: 19361 +.. date: 8861 +.. nonce: 2mvrV3 +.. section: Library + +JSON decoder now raises JSONDecodeError instead of ValueError. + +.. + +.. bpo: 18518 +.. date: 8860 +.. nonce: JXgicC +.. section: Library + +timeit now rejects statements which can't be compiled outside a function or +a loop (e.g. "return" or "break"). + +.. + +.. bpo: 23094 +.. date: 8859 +.. nonce: -8AXSi +.. section: Library + +Fixed readline with frames in Python implementation of pickle. + +.. + +.. bpo: 23268 +.. date: 8858 +.. nonce: ATtRa5 +.. section: Library + +Fixed bugs in the comparison of ipaddress classes. + +.. + +.. bpo: 21408 +.. date: 8857 +.. nonce: 0rI6tx +.. section: Library + +Removed incorrect implementations of __ne__() which didn't returned +NotImplemented if __eq__() returned NotImplemented. The default __ne__() +now works correctly. + +.. + +.. bpo: 19996 +.. date: 8856 +.. nonce: 2-SiMf +.. section: Library + +:class:`email.feedparser.FeedParser` now handles (malformed) headers with no +key rather than assuming the body has started. + +.. + +.. bpo: 20188 +.. date: 8855 +.. nonce: xocY-2 +.. section: Library + +Support Application-Layer Protocol Negotiation (ALPN) in the ssl module. + +.. + +.. bpo: 23133 +.. date: 8854 +.. nonce: 8p2Wnl +.. section: Library + +Pickling of ipaddress objects now produces more compact and portable +representation. + +.. + +.. bpo: 23248 +.. date: 8853 +.. nonce: FjcyCP +.. section: Library + +Update ssl error codes from latest OpenSSL git master. + +.. + +.. bpo: 23266 +.. date: 8852 +.. nonce: Mo7alR +.. section: Library + +Much faster implementation of ipaddress.collapse_addresses() when there are +many non-consecutive addresses. + +.. + +.. bpo: 23098 +.. date: 8851 +.. nonce: 7VwF3K +.. section: Library + +64-bit dev_t is now supported in the os module. + +.. + +.. bpo: 21817 +.. date: 8850 +.. nonce: xYUW-9 +.. section: Library + +When an exception is raised in a task submitted to a ProcessPoolExecutor, +the remote traceback is now displayed in the parent process. Patch by +Claudiu Popa. + +.. + +.. bpo: 15955 +.. date: 8849 +.. nonce: uvpBL4 +.. section: Library + +Add an option to limit output size when decompressing LZMA data. Patch by +Nikolaus Rath and Martin Panter. + +.. + +.. bpo: 23250 +.. date: 8848 +.. nonce: qNGAUf +.. section: Library + +In the http.cookies module, capitalize "HttpOnly" and "Secure" as they are +written in the standard. + +.. + +.. bpo: 23063 +.. date: 8847 +.. nonce: 9-UJRs +.. section: Library + +In the distutils' check command, fix parsing of reST with code or code-block +directives. + +.. + +.. bpo: 23209 +.. date: 8846 +.. nonce: I0bCCH +.. section: Library + +selectors.BaseSelector.get_key() now raises a RuntimeError if the selector +is closed. And selectors.BaseSelector.close() now clears its internal +reference to the selector mapping to break a reference cycle. Initial patch +written by Martin Richard. (See also: bpo-23225) + +.. + +.. bpo: 17911 +.. date: 8845 +.. nonce: yg65Iu +.. section: Library + +Provide a way to seed the linecache for a PEP-302 module without actually +loading the code. + +.. + +.. bpo: 17911 +.. date: 8844 +.. nonce: qeTePa +.. section: Library + +Provide a new object API for traceback, including the ability to not lookup +lines at all until the traceback is actually rendered, without any trace of +the original objects being kept alive. + +.. + +.. bpo: 19777 +.. date: 8843 +.. nonce: H_NDIA +.. section: Library + +Provide a home() classmethod on Path objects. Contributed by Victor Salgado +and Mayank Tripathi. + +.. + +.. bpo: 23206 +.. date: 8842 +.. nonce: xSiYwq +.. section: Library + +Make ``json.dumps(..., ensure_ascii=False)`` as fast as the default case of +``ensure_ascii=True``. Patch by Naoki Inada. + +.. + +.. bpo: 23185 +.. date: 8841 +.. nonce: KHyoSO +.. section: Library + +Add math.inf and math.nan constants. + +.. + +.. bpo: 23186 +.. date: 8840 +.. nonce: KzWLP2 +.. section: Library + +Add ssl.SSLObject.shared_ciphers() and ssl.SSLSocket.shared_ciphers() to +fetch the client's list ciphers sent at handshake. + +.. + +.. bpo: 23143 +.. date: 8839 +.. nonce: AWxJXV +.. section: Library + +Remove compatibility with OpenSSLs older than 0.9.8. + +.. + +.. bpo: 23132 +.. date: 8838 +.. nonce: pbQcut +.. section: Library + +Improve performance and introspection support of comparison methods created +by functool.total_ordering. + +.. + +.. bpo: 19776 +.. date: 8837 +.. nonce: BxNgxd +.. section: Library + +Add an expanduser() method on Path objects. + +.. + +.. bpo: 23112 +.. date: 8836 +.. nonce: dZGf82 +.. section: Library + +Fix SimpleHTTPServer to correctly carry the query string and fragment when +it redirects to add a trailing slash. + +.. + +.. bpo: 21793 +.. date: 8835 +.. nonce: T1kQBL +.. section: Library + +Added http.HTTPStatus enums (i.e. HTTPStatus.OK, HTTPStatus.NOT_FOUND). +Patch by Demian Brecht. + +.. + +.. bpo: 23093 +.. date: 8834 +.. nonce: cP7OqD +.. section: Library + +In the io, module allow more operations to work on detached streams. + +.. + +.. bpo: 23111 +.. date: 8833 +.. nonce: A34IA4 +.. section: Library + +In the ftplib, make ssl.PROTOCOL_SSLv23 the default protocol version. + +.. + +.. bpo: 22585 +.. date: 8832 +.. nonce: F4BkNo +.. section: Library + +On OpenBSD 5.6 and newer, os.urandom() now calls getentropy(), instead of +reading /dev/urandom, to get pseudo-random bytes. + +.. + +.. bpo: 19104 +.. date: 8831 +.. nonce: _eIThy +.. section: Library + +pprint now produces evaluable output for wrapped strings. + +.. + +.. bpo: 23071 +.. date: 8830 +.. nonce: 3BSqF7 +.. section: Library + +Added missing names to codecs.__all__. Patch by Martin Panter. + +.. + +.. bpo: 22783 +.. date: 8829 +.. nonce: OfYxBd +.. section: Library + +Pickling now uses the NEWOBJ opcode instead of the NEWOBJ_EX opcode if +possible. + +.. + +.. bpo: 15513 +.. date: 8828 +.. nonce: 7yVnRE +.. section: Library + +Added a __sizeof__ implementation for pickle classes. + +.. + +.. bpo: 19858 +.. date: 8827 +.. nonce: cqOlIt +.. section: Library + +pickletools.optimize() now aware of the MEMOIZE opcode, can produce more +compact result and no longer produces invalid output if input data contains +MEMOIZE opcodes together with PUT or BINPUT opcodes. + +.. + +.. bpo: 22095 +.. date: 8826 +.. nonce: iISzxM +.. section: Library + +Fixed HTTPConnection.set_tunnel with default port. The port value in the +host header was set to "None". Patch by Demian Brecht. + +.. + +.. bpo: 23016 +.. date: 8825 +.. nonce: LyrPd_ +.. section: Library + +A warning no longer produces an AttributeError when the program is run with +pythonw.exe. + +.. + +.. bpo: 21775 +.. date: 8824 +.. nonce: ELR_Al +.. section: Library + +shutil.copytree(): fix crash when copying to VFAT. An exception handler +assumed that OSError objects always have a 'winerror' attribute. That is not +the case, so the exception handler itself raised AttributeError when run on +Linux (and, presumably, any other non-Windows OS). Patch by Greg Ward. + +.. + +.. bpo: 1218234 +.. date: 8823 +.. nonce: 4GcoQK +.. section: Library + +Fix inspect.getsource() to load updated source of reloaded module. Initial +patch by Berker Peksag. + +.. + +.. bpo: 21740 +.. date: 8822 +.. nonce: TtAApO +.. section: Library + +Support wrapped callables in doctest. Patch by Claudiu Popa. + +.. + +.. bpo: 23009 +.. date: 8821 +.. nonce: -sW7gk +.. section: Library + +Make sure selectors.EpollSelector.select() works when no FD is registered. + +.. + +.. bpo: 22959 +.. date: 8820 +.. nonce: Vxt3EP +.. section: Library + +In the constructor of http.client.HTTPSConnection, prefer the context's +check_hostname attribute over the *check_hostname* parameter. + +.. + +.. bpo: 22696 +.. date: 8819 +.. nonce: pvdcxs +.. section: Library + +Add function :func:`sys.is_finalizing` to know about interpreter shutdown. + +.. + +.. bpo: 16043 +.. date: 8818 +.. nonce: TGIC7t +.. section: Library + +Add a default limit for the amount of data xmlrpclib.gzip_decode will +return. This resolves CVE-2013-1753. + +.. + +.. bpo: 14099 +.. date: 8817 +.. nonce: GJ5meQ +.. section: Library + +ZipFile.open() no longer reopen the underlying file. Objects returned by +ZipFile.open() can now operate independently of the ZipFile even if the +ZipFile was created by passing in a file-like object as the first argument +to the constructor. + +.. + +.. bpo: 22966 +.. date: 8816 +.. nonce: zIxDrT +.. section: Library + +Fix __pycache__ pyc file name clobber when pyc_compile is asked to compile a +source file containing multiple dots in the source file name. + +.. + +.. bpo: 21971 +.. date: 8815 +.. nonce: XlTc22 +.. section: Library + +Update turtledemo doc and add module to the index. + +.. + +.. bpo: 21032 +.. date: 8814 +.. nonce: wxT_41 +.. section: Library + +Fixed socket leak if HTTPConnection.getresponse() fails. Original patch by +Martin Panter. + +.. + +.. bpo: 22407 +.. date: 8813 +.. nonce: CWi1wX +.. section: Library + +Deprecated the use of re.LOCALE flag with str patterns or re.ASCII. It was +newer worked. + +.. + +.. bpo: 22902 +.. date: 8812 +.. nonce: ZqXriA +.. section: Library + +The "ip" command is now used on Linux to determine MAC address in +uuid.getnode(). Pach by Bruno Cauet. + +.. + +.. bpo: 22960 +.. date: 8811 +.. nonce: 2VDILT +.. section: Library + +Add a context argument to xmlrpclib.ServerProxy constructor. + +.. + +.. bpo: 22389 +.. date: 8810 +.. nonce: 82DuwD +.. section: Library + +Add contextlib.redirect_stderr(). + +.. + +.. bpo: 21356 +.. date: 8809 +.. nonce: 8NY75J +.. section: Library + +Make ssl.RAND_egd() optional to support LibreSSL. The availability of the +function is checked during the compilation. Patch written by Bernard Spil. + +.. + +.. bpo: 22915 +.. date: 8808 +.. nonce: 709UAo +.. section: Library + +SAX parser now supports files opened with file descriptor or bytes path. + +.. + +.. bpo: 22609 +.. date: 8807 +.. nonce: mmLoeb +.. section: Library + +Constructors and update methods of mapping classes in the collections module +now accept the self keyword argument. + +.. + +.. bpo: 22940 +.. date: 8806 +.. nonce: SP99Nf +.. section: Library + +Add readline.append_history_file. + +.. + +.. bpo: 19676 +.. date: 8805 +.. nonce: Wijwr8 +.. section: Library + +Added the "namereplace" error handler. + +.. + +.. bpo: 22788 +.. date: 8804 +.. nonce: vofL9e +.. section: Library + +Add *context* parameter to logging.handlers.HTTPHandler. + +.. + +.. bpo: 22921 +.. date: 8803 +.. nonce: a4wx1C +.. section: Library + +Allow SSLContext to take the *hostname* parameter even if OpenSSL doesn't +support SNI. + +.. + +.. bpo: 22894 +.. date: 8802 +.. nonce: 4AkwPA +.. section: Library + +TestCase.subTest() would cause the test suite to be stopped when in failfast +mode, even in the absence of failures. + +.. + +.. bpo: 22796 +.. date: 8801 +.. nonce: _pFPFA +.. section: Library + +HTTP cookie parsing is now stricter, in order to protect against potential +injection attacks. + +.. + +.. bpo: 22370 +.. date: 8800 +.. nonce: j4y21u +.. section: Library + +Windows detection in pathlib is now more robust. + +.. + +.. bpo: 22841 +.. date: 8799 +.. nonce: 8wpk7T +.. section: Library + +Reject coroutines in asyncio add_signal_handler(). Patch by Ludovic.Gasc. + +.. + +.. bpo: 19494 +.. date: 8798 +.. nonce: 7O5O8k +.. section: Library + +Added urllib.request.HTTPBasicPriorAuthHandler. Patch by Matej Cepl. + +.. + +.. bpo: 22578 +.. date: 8797 +.. nonce: 6XZ0Jf +.. section: Library + +Added attributes to the re.error class. + +.. + +.. bpo: 22849 +.. date: 8796 +.. nonce: AqBPyj +.. section: Library + +Fix possible double free in the io.TextIOWrapper constructor. + +.. + +.. bpo: 12728 +.. date: 8795 +.. nonce: rHZmXO +.. section: Library + +Different Unicode characters having the same uppercase but different +lowercase are now matched in case-insensitive regular expressions. + +.. + +.. bpo: 22821 +.. date: 8794 +.. nonce: 30cQ-U +.. section: Library + +Fixed fcntl() with integer argument on 64-bit big-endian platforms. + +.. + +.. bpo: 21650 +.. date: 8793 +.. nonce: 62MLqr +.. section: Library + +Add an `--sort-keys` option to json.tool CLI. + +.. + +.. bpo: 22824 +.. date: 8792 +.. nonce: d5Txvr +.. section: Library + +Updated reprlib output format for sets to use set literals. Patch +contributed by Berker Peksag. + +.. + +.. bpo: 22824 +.. date: 8791 +.. nonce: H_r9uH +.. section: Library + +Updated reprlib output format for arrays to display empty arrays without an +unnecessary empty list. Suggested by Serhiy Storchaka. + +.. + +.. bpo: 22406 +.. date: 8790 +.. nonce: sPlVbI +.. section: Library + +Fixed the uu_codec codec incorrectly ported to 3.x. Based on patch by Martin +Panter. + +.. + +.. bpo: 17293 +.. date: 8789 +.. nonce: Hk06bO +.. section: Library + +uuid.getnode() now determines MAC address on AIX using netstat. Based on +patch by Aivars Kalvāns. + +.. + +.. bpo: 22769 +.. date: 8788 +.. nonce: PunnvQ +.. section: Library + +Fixed ttk.Treeview.tag_has() when called without arguments. + +.. + +.. bpo: 22417 +.. date: 8787 +.. nonce: To4b7U +.. section: Library + +Verify certificates by default in httplib (PEP 476). + +.. + +.. bpo: 22775 +.. date: 8786 +.. nonce: V5aCUz +.. section: Library + +Fixed unpickling of http.cookies.SimpleCookie with protocol 2 and above. +Patch by Tim Graham. + +.. + +.. bpo: 22776 +.. date: 8785 +.. nonce: xNcRse +.. section: Library + +Brought excluded code into the scope of a try block in SysLogHandler.emit(). + +.. + +.. bpo: 22665 +.. date: 8784 +.. nonce: j6Jlp8 +.. section: Library + +Add missing get_terminal_size and SameFileError to shutil.__all__. + +.. + +.. bpo: 6623 +.. date: 8783 +.. nonce: 6LOidS +.. section: Library + +Remove deprecated Netrc class in the ftplib module. Patch by Matt Chaput. + +.. + +.. bpo: 17381 +.. date: 8782 +.. nonce: 4J5yv7 +.. section: Library + +Fixed handling of case-insensitive ranges in regular expressions. + +.. + +.. bpo: 22410 +.. date: 8781 +.. nonce: 99YFdd +.. section: Library + +Module level functions in the re module now cache compiled locale-dependent +regular expressions taking into account the locale. + +.. + +.. bpo: 22759 +.. date: 8780 +.. nonce: BJPdiL +.. section: Library + +Query methods on pathlib.Path() (exists(), is_dir(), etc.) now return False +when the underlying stat call raises NotADirectoryError. + +.. + +.. bpo: 8876 +.. date: 8779 +.. nonce: A83Av4 +.. section: Library + +distutils now falls back to copying files when hard linking doesn't work. +This allows use with special filesystems such as VirtualBox shared folders. + +.. + +.. bpo: 22217 +.. date: 8778 +.. nonce: nXzGur +.. section: Library + +Implemented reprs of classes in the zipfile module. + +.. + +.. bpo: 22457 +.. date: 8777 +.. nonce: Xd2Mk- +.. section: Library + +Honour load_tests in the start_dir of discovery. + +.. + +.. bpo: 18216 +.. date: 8776 +.. nonce: trTZw4 +.. section: Library + +gettext now raises an error when a .mo file has an unsupported major version +number. Patch by Aaron Hill. + +.. + +.. bpo: 13918 +.. date: 8775 +.. nonce: -OnUhD +.. section: Library + +Provide a locale.delocalize() function which can remove locale-specific +number formatting from a string representing a number, without then +converting it to a specific type. Patch by Cédric Krier. + +.. + +.. bpo: 22676 +.. date: 8774 +.. nonce: d2v8QM +.. section: Library + +Make the pickling of global objects which don't have a __module__ attribute +less slow. + +.. + +.. bpo: 18853 +.. date: 8773 +.. nonce: 76DrPD +.. section: Library + +Fixed ResourceWarning in shlex.__nain__. + +.. + +.. bpo: 9351 +.. date: 8772 +.. nonce: u5UI-6 +.. section: Library + +Defaults set with set_defaults on an argparse subparser are no longer +ignored when also set on the parent parser. + +.. + +.. bpo: 7559 +.. date: 8771 +.. nonce: QG35ZP +.. section: Library + +unittest test loading ImportErrors are reported as import errors with their +import exception rather than as attribute errors after the import has +already failed. + +.. + +.. bpo: 19746 +.. date: 8770 +.. nonce: S1dg1K +.. section: Library + +Make it possible to examine the errors from unittest discovery without +executing the test suite. The new `errors` attribute on TestLoader exposes +these non-fatal errors encountered during discovery. + +.. + +.. bpo: 21991 +.. date: 8769 +.. nonce: Mkm0IN +.. section: Library + +Make email.headerregistry's header 'params' attributes be read-only +(MappingProxyType). Previously the dictionary was modifiable but a new one +was created on each access of the attribute. + +.. + +.. bpo: 22638 +.. date: 8768 +.. nonce: Ur73gJ +.. section: Library + +SSLv3 is now disabled throughout the standard library. It can still be +enabled by instantiating a SSLContext manually. + +.. + +.. bpo: 22641 +.. date: 8767 +.. nonce: m0ldtl +.. section: Library + +In asyncio, the default SSL context for client connections is now created +using ssl.create_default_context(), for stronger security. + +.. + +.. bpo: 17401 +.. date: 8766 +.. nonce: SZd19P +.. section: Library + +Include closefd in io.FileIO repr. + +.. + +.. bpo: 21338 +.. date: 8765 +.. nonce: evDyHD +.. section: Library + +Add silent mode for compileall. quiet parameters of compile_{dir, file, +path} functions now have a multilevel value. Also, -q option of the CLI now +have a multilevel value. Patch by Thomas Kluyver. + +.. + +.. bpo: 20152 +.. date: 8764 +.. nonce: 9_o92A +.. section: Library + +Convert the array and cmath modules to Argument Clinic. + +.. + +.. bpo: 18643 +.. date: 8763 +.. nonce: 6Qdc0J +.. section: Library + +Add socket.socketpair() on Windows. + +.. + +.. bpo: 22435 +.. date: 8762 +.. nonce: s2U7Zm +.. section: Library + +Fix a file descriptor leak when socketserver bind fails. + +.. + +.. bpo: 13096 +.. date: 8761 +.. nonce: rsailB +.. section: Library + +Fixed segfault in CTypes POINTER handling of large values. + +.. + +.. bpo: 11694 +.. date: 8760 +.. nonce: JuDrch +.. section: Library + +Raise ConversionError in xdrlib as documented. Patch by Filip Gruszczyński +and Claudiu Popa. + +.. + +.. bpo: 19380 +.. date: 8759 +.. nonce: nqgoRQ +.. section: Library + +Optimized parsing of regular expressions. + +.. + +.. bpo: 1519638 +.. date: 8758 +.. nonce: 2pbuog +.. section: Library + +Now unmatched groups are replaced with empty strings in re.sub() and +re.subn(). + +.. + +.. bpo: 18615 +.. date: 8757 +.. nonce: 65TxnY +.. section: Library + +sndhdr.what/whathdr now return a namedtuple. + +.. + +.. bpo: 22462 +.. date: 8756 +.. nonce: 1h4Kpr +.. section: Library + +Fix pyexpat's creation of a dummy frame to make it appear in exception +tracebacks. + +.. + +.. bpo: 21965 +.. date: 8755 +.. nonce: n_jnXs +.. section: Library + +Add support for in-memory SSL to the ssl module. Patch by Geert Jansen. + +.. + +.. bpo: 21173 +.. date: 8754 +.. nonce: egkbEx +.. section: Library + +Fix len() on a WeakKeyDictionary when .clear() was called with an iterator +alive. + +.. + +.. bpo: 11866 +.. date: 8753 +.. nonce: xrvbIC +.. section: Library + +Eliminated race condition in the computation of names for new threads. + +.. + +.. bpo: 21905 +.. date: 8752 +.. nonce: coKyRo +.. section: Library + +Avoid RuntimeError in pickle.whichmodule() when sys.modules is mutated while +iterating. Patch by Olivier Grisel. + +.. + +.. bpo: 11271 +.. date: 8751 +.. nonce: ZYiJru +.. section: Library + +concurrent.futures.Executor.map() now takes a *chunksize* argument to allow +batching of tasks in child processes and improve performance of +ProcessPoolExecutor. Patch by Dan O'Reilly. + +.. + +.. bpo: 21883 +.. date: 8750 +.. nonce: qpuQu6 +.. section: Library + +os.path.join() and os.path.relpath() now raise a TypeError with more helpful +error message for unsupported or mismatched types of arguments. + +.. + +.. bpo: 22219 +.. date: 8749 +.. nonce: l9Enh9 +.. section: Library + +The zipfile module CLI now adds entries for directories (including empty +directories) in ZIP file. + +.. + +.. bpo: 22449 +.. date: 8748 +.. nonce: nFW_Fl +.. section: Library + +In the ssl.SSLContext.load_default_certs, consult the environmental +variables SSL_CERT_DIR and SSL_CERT_FILE on Windows. + +.. + +.. bpo: 22508 +.. date: 8747 +.. nonce: 2LbnGQ +.. section: Library + +The email.__version__ variable has been removed; the email code is no longer +shipped separately from the stdlib, and __version__ hasn't been updated in +several releases. + +.. + +.. bpo: 20076 +.. date: 8746 +.. nonce: -7OIVB +.. section: Library + +Added non derived UTF-8 aliases to locale aliases table. + +.. + +.. bpo: 20079 +.. date: 8745 +.. nonce: qM949O +.. section: Library + +Added locales supported in glibc 2.18 to locale alias table. + +.. + +.. bpo: 20218 +.. date: 8744 +.. nonce: CMgOyE +.. section: Library + +Added convenience methods read_text/write_text and read_bytes/ write_bytes +to pathlib.Path objects. + +.. + +.. bpo: 22396 +.. date: 8743 +.. nonce: cQSizA +.. section: Library + +On 32-bit AIX platform, don't expose os.posix_fadvise() nor +os.posix_fallocate() because their prototypes in system headers are wrong. + +.. + +.. bpo: 22517 +.. date: 8742 +.. nonce: qT6-aB +.. section: Library + +When an io.BufferedRWPair object is deallocated, clear its weakrefs. + +.. + +.. bpo: 22437 +.. date: 8741 +.. nonce: MRVnmQ +.. section: Library + +Number of capturing groups in regular expression is no longer limited by +100. + +.. + +.. bpo: 17442 +.. date: 8740 +.. nonce: rnc87D +.. section: Library + +InteractiveInterpreter now displays the full chained traceback in its +showtraceback method, to match the built in interactive interpreter. + +.. + +.. bpo: 23392 +.. date: 8739 +.. nonce: Pe7_WK +.. section: Library + +Added tests for marshal C API that works with FILE*. + +.. + +.. bpo: 10510 +.. date: 8738 +.. nonce: N-ntcD +.. section: Library + +distutils register and upload methods now use HTML standards compliant CRLF +line endings. + +.. + +.. bpo: 9850 +.. date: 8737 +.. nonce: D-UnVi +.. section: Library + +Fixed macpath.join() for empty first component. Patch by Oleg Oshmyan. + +.. + +.. bpo: 5309 +.. date: 8736 +.. nonce: pVMmQ8 +.. section: Library + +distutils' build and build_ext commands now accept a ``-j`` option to enable +parallel building of extension modules. + +.. + +.. bpo: 22448 +.. date: 8735 +.. nonce: fAapvE +.. section: Library + +Improve canceled timer handles cleanup to prevent unbound memory usage. +Patch by Joshua Moore-Oliva. + +.. + +.. bpo: 22427 +.. date: 8734 +.. nonce: TZ5S_u +.. section: Library + +TemporaryDirectory no longer attempts to clean up twice when used in the +with statement in generator. + +.. + +.. bpo: 22362 +.. date: 8733 +.. nonce: xIBThN +.. section: Library + +Forbidden ambiguous octal escapes out of range 0-0o377 in regular +expressions. + +.. + +.. bpo: 20912 +.. date: 8732 +.. nonce: cAq3mZ +.. section: Library + +Now directories added to ZIP file have correct Unix and MS-DOS directory +attributes. + +.. + +.. bpo: 21866 +.. date: 8731 +.. nonce: hSc4wM +.. section: Library + +ZipFile.close() no longer writes ZIP64 central directory records if +allowZip64 is false. + +.. + +.. bpo: 22278 +.. date: 8730 +.. nonce: abqBXZ +.. section: Library + +Fix urljoin problem with relative urls, a regression observed after changes +to issue22118 were submitted. + +.. + +.. bpo: 22415 +.. date: 8729 +.. nonce: xJLAvI +.. section: Library + +Fixed debugging output of the GROUPREF_EXISTS opcode in the re module. +Removed trailing spaces in debugging output. + +.. + +.. bpo: 22423 +.. date: 8728 +.. nonce: Rtb4oT +.. section: Library + +Unhandled exception in thread no longer causes unhandled AttributeError when +sys.stderr is None. + +.. + +.. bpo: 21332 +.. date: 8727 +.. nonce: Gwxwlr +.. section: Library + +Ensure that ``bufsize=1`` in subprocess.Popen() selects line buffering, +rather than block buffering. Patch by Akira Li. + +.. + +.. bpo: 21091 +.. date: 8726 +.. nonce: M5hAtT +.. section: Library + +Fix API bug: email.message.EmailMessage.is_attachment is now a method. + +.. + +.. bpo: 21079 +.. date: 8725 +.. nonce: czVcL8 +.. section: Library + +Fix email.message.EmailMessage.is_attachment to return the correct result +when the header has parameters as well as a value. + +.. + +.. bpo: 22247 +.. date: 8724 +.. nonce: sGIpR3 +.. section: Library + +Add NNTPError to nntplib.__all__. + +.. + +.. bpo: 22366 +.. date: 8723 +.. nonce: Dd1eFj +.. section: Library + +urllib.request.urlopen will accept a context object (SSLContext) as an +argument which will then be used for HTTPS connection. Patch by Alex Gaynor. + +.. + +.. bpo: 4180 +.. date: 8722 +.. nonce: QBx0JK +.. section: Library + +The warnings registries are now reset when the filters are modified. + +.. + +.. bpo: 22419 +.. date: 8721 +.. nonce: FqH4aC +.. section: Library + +Limit the length of incoming HTTP request in wsgiref server to 65536 bytes +and send a 414 error code for higher lengths. Patch contributed by Devin +Cook. + +.. + +.. bpo: 0 +.. date: 8720 +.. nonce: y7r3O2 +.. section: Library + +Lax cookie parsing in http.cookies could be a security issue when combined +with non-standard cookie handling in some web browsers. Reported by Sergey +Bobrov. + +.. + +.. bpo: 20537 +.. date: 8719 +.. nonce: E0CE54 +.. section: Library + +logging methods now accept an exception instance as well as a Boolean value +or exception tuple. Thanks to Yury Selivanov for the patch. + +.. + +.. bpo: 22384 +.. date: 8718 +.. nonce: -Nl4He +.. section: Library + +An exception in Tkinter callback no longer crashes the program when it is +run with pythonw.exe. + +.. + +.. bpo: 22168 +.. date: 8717 +.. nonce: vLeKWC +.. section: Library + +Prevent turtle AttributeError with non-default Canvas on OS X. + +.. + +.. bpo: 21147 +.. date: 8716 +.. nonce: w9DE17 +.. section: Library + +sqlite3 now raises an exception if the request contains a null character +instead of truncating it. Based on patch by Victor Stinner. + +.. + +.. bpo: 13968 +.. date: 8715 +.. nonce: 1okGqm +.. section: Library + +The glob module now supports recursive search in subdirectories using the +``**`` pattern. + +.. + +.. bpo: 21951 +.. date: 8714 +.. nonce: 3vS4LK +.. section: Library + +Fixed a crash in Tkinter on AIX when called Tcl command with empty string or +tuple argument. + +.. + +.. bpo: 21951 +.. date: 8713 +.. nonce: _CCC4v +.. section: Library + +Tkinter now most likely raises MemoryError instead of crash if the memory +allocation fails. + +.. + +.. bpo: 22338 +.. date: 8712 +.. nonce: rKlCMz +.. section: Library + +Fix a crash in the json module on memory allocation failure. + +.. + +.. bpo: 12410 +.. date: 8711 +.. nonce: oFf-cB +.. section: Library + +imaplib.IMAP4 now supports the context management protocol. Original patch +by Tarek Ziadé. + +.. + +.. bpo: 21270 +.. date: 8710 +.. nonce: qMBaY- +.. section: Library + +We now override tuple methods in mock.call objects so that they can be used +as normal call attributes. + +.. + +.. bpo: 16662 +.. date: 8709 +.. nonce: Nghn-Y +.. section: Library + +load_tests() is now unconditionally run when it is present in a package's +__init__.py. TestLoader.loadTestsFromModule() still accepts use_load_tests, +but it is deprecated and ignored. A new keyword-only attribute `pattern` is +added and documented. Patch given by Robert Collins, tweaked by Barry +Warsaw. + +.. + +.. bpo: 22226 +.. date: 8708 +.. nonce: T1ZMPY +.. section: Library + +First letter no longer is stripped from the "status" key in the result of +Treeview.heading(). + +.. + +.. bpo: 19524 +.. date: 8707 +.. nonce: EQJjlF +.. section: Library + +Fixed resource leak in the HTTP connection when an invalid response is +received. Patch by Martin Panter. + +.. + +.. bpo: 20421 +.. date: 8706 +.. nonce: iR0S1s +.. section: Library + +Add a .version() method to SSL sockets exposing the actual protocol version +in use. + +.. + +.. bpo: 19546 +.. date: 8705 +.. nonce: 8VdYBK +.. section: Library + +configparser exceptions no longer expose implementation details. Chained +KeyErrors are removed, which leads to cleaner tracebacks. Patch by Claudiu +Popa. + +.. + +.. bpo: 22051 +.. date: 8704 +.. nonce: cUjFqL +.. section: Library + +turtledemo no longer reloads examples to re-run them. Initialization of +variables and gui setup should be done in main(), which is called each time +a demo is run, but not on import. + +.. + +.. bpo: 21933 +.. date: 8703 +.. nonce: IhMjN1 +.. section: Library + +Turtledemo users can change the code font size with a menu selection or +control(command) '-' or '+' or control-mousewheel. Original patch by Lita +Cho. + +.. + +.. bpo: 21597 +.. date: 8702 +.. nonce: aPTCWJ +.. section: Library + +The separator between the turtledemo text pane and the drawing canvas can +now be grabbed and dragged with a mouse. The code text pane can be widened +to easily view or copy the full width of the text. The canvas can be +widened on small screens. Original patches by Jan Kanis and Lita Cho. + +.. + +.. bpo: 18132 +.. date: 8701 +.. nonce: 2R2nwM +.. section: Library + +Turtledemo buttons no longer disappear when the window is shrunk. Original +patches by Jan Kanis and Lita Cho. + +.. + +.. bpo: 22043 +.. date: 8700 +.. nonce: Q6RvGL +.. section: Library + +time.monotonic() is now always available. ``threading.Lock.acquire()``, +``threading.RLock.acquire()`` and socket operations now use a monotonic +clock, instead of the system clock, when a timeout is used. + +.. + +.. bpo: 21527 +.. date: 8699 +.. nonce: N5WPxr +.. section: Library + +Add a default number of workers to ThreadPoolExecutor equal to 5 times the +number of CPUs. Patch by Claudiu Popa. + +.. + +.. bpo: 22216 +.. date: 8698 +.. nonce: Cmalu6 +.. section: Library + +smtplib now resets its state more completely after a quit. The most obvious +consequence of the previous behavior was a STARTTLS failure during a +connect/starttls/quit/connect/starttls sequence. + +.. + +.. bpo: 22098 +.. date: 8697 +.. nonce: 5JYiQN +.. section: Library + +ctypes' BigEndianStructure and LittleEndianStructure now define an empty +__slots__ so that subclasses don't always get an instance dict. Patch by +Claudiu Popa. + +.. + +.. bpo: 22185 +.. date: 8696 +.. nonce: 1SCCIK +.. section: Library + +Fix an occasional RuntimeError in threading.Condition.wait() caused by +mutation of the waiters queue without holding the lock. Patch by Doug +Zongker. + +.. + +.. bpo: 22287 +.. date: 8695 +.. nonce: awH2AI +.. section: Library + +On UNIX, _PyTime_gettimeofday() now uses clock_gettime(CLOCK_REALTIME) if +available. As a side effect, Python now depends on the librt library on +Solaris and on Linux (only with glibc older than 2.17). + +.. + +.. bpo: 22182 +.. date: 8694 +.. nonce: 5EG1Bc +.. section: Library + +Use e.args to unpack exceptions correctly in distutils.file_util.move_file. +Patch by Claudiu Popa. + +.. + +.. bpo: 0 +.. date: 8693 +.. nonce: zBfe8J +.. section: Library + +The webbrowser module now uses subprocess's start_new_session=True rather +than a potentially risky preexec_fn=os.setsid call. + +.. + +.. bpo: 22042 +.. date: 8692 +.. nonce: WZvb8s +.. section: Library + +signal.set_wakeup_fd(fd) now raises an exception if the file descriptor is +in blocking mode. + +.. + +.. bpo: 16808 +.. date: 8691 +.. nonce: kPy_5U +.. section: Library + +inspect.stack() now returns a named tuple instead of a tuple. Patch by +Daniel Shahaf. + +.. + +.. bpo: 22236 +.. date: 8690 +.. nonce: 1utXkg +.. section: Library + +Fixed Tkinter images copying operations in NoDefaultRoot mode. + +.. + +.. bpo: 2527 +.. date: 8689 +.. nonce: fR2GS6 +.. section: Library + +Add a *globals* argument to timeit functions, in order to override the +globals namespace in which the timed code is executed. Patch by Ben Roberts. + +.. + +.. bpo: 22118 +.. date: 8688 +.. nonce: 3gdkOF +.. section: Library + +Switch urllib.parse to use RFC 3986 semantics for the resolution of relative +URLs, rather than RFCs 1808 and 2396. Patch by Demian Brecht. + +.. + +.. bpo: 21549 +.. date: 8687 +.. nonce: i1LVvg +.. section: Library + +Added the "members" parameter to TarFile.list(). + +.. + +.. bpo: 19628 +.. date: 8686 +.. nonce: ssQVP8 +.. section: Library + +Allow compileall recursion depth to be specified with a -r option. + +.. + +.. bpo: 15696 +.. date: 8685 +.. nonce: PTwXYJ +.. section: Library + +Add a __sizeof__ implementation for mmap objects on Windows. + +.. + +.. bpo: 22068 +.. date: 8684 +.. nonce: wCdaW0 +.. section: Library + +Avoided reference loops with Variables and Fonts in Tkinter. + +.. + +.. bpo: 22165 +.. date: 8683 +.. nonce: J1np4o +.. section: Library + +SimpleHTTPRequestHandler now supports undecodable file names. + +.. + +.. bpo: 15381 +.. date: 8682 +.. nonce: Ia8pf6 +.. section: Library + +Optimized line reading in io.BytesIO. + +.. + +.. bpo: 8797 +.. date: 8681 +.. nonce: aJcIPu +.. section: Library + +Raise HTTPError on failed Basic Authentication immediately. Initial patch by +Sam Bull. + +.. + +.. bpo: 20729 +.. date: 8680 +.. nonce: I-1Lap +.. section: Library + +Restored the use of lazy iterkeys()/itervalues()/iteritems() in the mailbox +module. + +.. + +.. bpo: 21448 +.. date: 8679 +.. nonce: THJSYB +.. section: Library + +Changed FeedParser feed() to avoid O(N\ :sup:`2`) behavior when parsing long line. +Original patch by Raymond Hettinger. + +.. + +.. bpo: 22184 +.. date: 8678 +.. nonce: UCbSOt +.. section: Library + +The functools LRU Cache decorator factory now gives an earlier and clearer +error message when the user forgets the required parameters. + +.. + +.. bpo: 17923 +.. date: 8677 +.. nonce: YI_QjG +.. section: Library + +glob() patterns ending with a slash no longer match non-dirs on AIX. Based +on patch by Delhallt. + +.. + +.. bpo: 21725 +.. date: 8676 +.. nonce: eIu-2N +.. section: Library + +Added support for RFC 6531 (SMTPUTF8) in smtpd. + +.. + +.. bpo: 22176 +.. date: 8675 +.. nonce: rgbRyg +.. section: Library + +Update the ctypes module's libffi to v3.1. This release adds support for +the Linux AArch64 and POWERPC ELF ABIv2 little endian architectures. + +.. + +.. bpo: 5411 +.. date: 8674 +.. nonce: 5Utapn +.. section: Library + +Added support for the "xztar" format in the shutil module. + +.. + +.. bpo: 21121 +.. date: 8673 +.. nonce: ZLsRil +.. section: Library + +Don't force 3rd party C extensions to be built with +-Werror=declaration-after-statement. + +.. + +.. bpo: 21975 +.. date: 8672 +.. nonce: MI8ntO +.. section: Library + +Fixed crash when using uninitialized sqlite3.Row (in particular when +unpickling pickled sqlite3.Row). sqlite3.Row is now initialized in the +__new__() method. + +.. + +.. bpo: 20170 +.. date: 8671 +.. nonce: 8QfhN7 +.. section: Library + +Convert posixmodule to use Argument Clinic. + +.. + +.. bpo: 21539 +.. date: 8670 +.. nonce: YccmZF +.. section: Library + +Add an *exists_ok* argument to `Pathlib.mkdir()` to mimic `mkdir -p` and +`os.makedirs()` functionality. When true, ignore FileExistsErrors. Patch +by Berker Peksag. + +.. + +.. bpo: 22127 +.. date: 8669 +.. nonce: 0l2OO5 +.. section: Library + +Bypass IDNA for pure-ASCII host names in the socket module (in particular +for numeric IPs). + +.. + +.. bpo: 21047 +.. date: 8668 +.. nonce: XfUQG3 +.. section: Library + +set the default value for the *convert_charrefs* argument of HTMLParser to +True. Patch by Berker Peksag. + +.. + +.. bpo: 0 +.. date: 8667 +.. nonce: 56bAnQ +.. section: Library + +Add an __all__ to html.entities. + +.. + +.. bpo: 15114 +.. date: 8666 +.. nonce: jXwseC +.. section: Library + +the strict mode and argument of HTMLParser, HTMLParser.error, and the +HTMLParserError exception have been removed. + +.. + +.. bpo: 22085 +.. date: 8665 +.. nonce: 3JM_Aw +.. section: Library + +Dropped support of Tk 8.3 in Tkinter. + +.. + +.. bpo: 21580 +.. date: 8664 +.. nonce: 3ssycS +.. section: Library + +Now Tkinter correctly handles bytes arguments passed to Tk. In particular +this allows initializing images from binary data. + +.. + +.. bpo: 22003 +.. date: 8663 +.. nonce: 4ZIDS1 +.. section: Library + +When initialized from a bytes object, io.BytesIO() now defers making a copy +until it is mutated, improving performance and memory use on some use cases. +Patch by David Wilson. + +.. + +.. bpo: 22018 +.. date: 8662 +.. nonce: 6ApxSH +.. section: Library + +On Windows, signal.set_wakeup_fd() now also supports sockets. A side effect +is that Python depends to the WinSock library. + +.. + +.. bpo: 22054 +.. date: 8661 +.. nonce: zp6Svw +.. section: Library + +Add os.get_blocking() and os.set_blocking() functions to get and set the +blocking mode of a file descriptor (False if the O_NONBLOCK flag is set, +True otherwise). These functions are not available on Windows. + +.. + +.. bpo: 17172 +.. date: 8660 +.. nonce: R_LI_2 +.. section: Library + +Make turtledemo start as active on OS X even when run with subprocess. +Patch by Lita Cho. + +.. + +.. bpo: 21704 +.. date: 8659 +.. nonce: gL3ikj +.. section: Library + +Fix build error for _multiprocessing when semaphores are not available. +Patch by Arfrever Frehtes Taifersar Arahesis. + +.. + +.. bpo: 20173 +.. date: 8658 +.. nonce: FAL-4L +.. section: Library + +Convert sha1, sha256, sha512 and md5 to ArgumentClinic. Patch by Vajrasky +Kok. + +.. + +.. bpo: 0 +.. date: 8657 +.. nonce: G25tq3 +.. section: Library + +Fix repr(_socket.socket) on Windows 64-bit: don't fail with OverflowError on +closed socket. repr(socket.socket) already works fine. + +.. + +.. bpo: 22033 +.. date: 8656 +.. nonce: nkBNci +.. section: Library + +Reprs of most Python implemented classes now contain actual class name +instead of hardcoded one. + +.. + +.. bpo: 21947 +.. date: 8655 +.. nonce: mlisu- +.. section: Library + +The dis module can now disassemble generator-iterator objects based on their +gi_code attribute. Patch by Clement Rouault. + +.. + +.. bpo: 16133 +.. date: 8654 +.. nonce: tYuYQF +.. section: Library + +The asynchat.async_chat.handle_read() method now ignores BlockingIOError +exceptions. + +.. + +.. bpo: 22044 +.. date: 8653 +.. nonce: t09GRU +.. section: Library + +Fixed premature DECREF in call_tzinfo_method. Patch by Tom Flanagan. + +.. + +.. bpo: 19884 +.. date: 8652 +.. nonce: v73gSn +.. section: Library + +readline: Disable the meta modifier key if stdout is not a terminal to not +write the ANSI sequence ``"\033[1034h"`` into stdout. This sequence is used +on some terminal (ex: TERM=xterm-256color") to enable support of 8 bit +characters. + +.. + +.. bpo: 4350 +.. date: 8651 +.. nonce: nrTzJn +.. section: Library + +Removed a number of out-of-dated and non-working for a long time Tkinter +methods. + +.. + +.. bpo: 6167 +.. date: 8650 +.. nonce: n9dV_D +.. section: Library + +Scrollbar.activate() now returns the name of active element if the argument +is not specified. Scrollbar.set() now always accepts only 2 arguments. + +.. + +.. bpo: 15275 +.. date: 8649 +.. nonce: jk0tTI +.. section: Library + +Clean up and speed up the ntpath module. + +.. + +.. bpo: 21888 +.. date: 8648 +.. nonce: danlpz +.. section: Library + +plistlib's load() and loads() now work if the fmt parameter is specified. + +.. + +.. bpo: 22032 +.. date: 8647 +.. nonce: UklzQW +.. section: Library + +__qualname__ instead of __name__ is now always used to format fully +qualified class names of Python implemented classes. + +.. + +.. bpo: 22031 +.. date: 8646 +.. nonce: 9aazp1 +.. section: Library + +Reprs now always use hexadecimal format with the "0x" prefix when contain an +id in form " at 0x...". + +.. + +.. bpo: 22018 +.. date: 8645 +.. nonce: b_JTHH +.. section: Library + +signal.set_wakeup_fd() now raises an OSError instead of a ValueError on +``fstat()`` failure. + +.. + +.. bpo: 21044 +.. date: 8644 +.. nonce: 16xo9u +.. section: Library + +tarfile.open() now handles fileobj with an integer 'name' attribute. Based +on patch by Antoine Pietri. + +.. + +.. bpo: 21966 +.. date: 8643 +.. nonce: hHD9MK +.. section: Library + +Respect -q command-line option when code module is ran. + +.. + +.. bpo: 19076 +.. date: 8642 +.. nonce: xCoIai +.. section: Library + +Don't pass the redundant 'file' argument to self.error(). + +.. + +.. bpo: 16382 +.. date: 8641 +.. nonce: -XBK7z +.. section: Library + +Improve exception message of warnings.warn() for bad category. Initial patch +by Phil Elson. + +.. + +.. bpo: 21932 +.. date: 8640 +.. nonce: LK_5S1 +.. section: Library + +os.read() now uses a :c:func:`Py_ssize_t` type instead of :c:expr:`int` for +the size to support reading more than 2 GB at once. On Windows, the size is +truncated to INT_MAX. As any call to os.read(), the OS may read less bytes +than the number of requested bytes. + +.. + +.. bpo: 21942 +.. date: 8639 +.. nonce: TLOS41 +.. section: Library + +Fixed source file viewing in pydoc's server mode on Windows. + +.. + +.. bpo: 11259 +.. date: 8638 +.. nonce: GxfYnE +.. section: Library + +asynchat.async_chat().set_terminator() now raises a ValueError if the number +of received bytes is negative. + +.. + +.. bpo: 12523 +.. date: 8637 +.. nonce: XBdAky +.. section: Library + +asynchat.async_chat.push() now raises a TypeError if it doesn't get a bytes +string + +.. + +.. bpo: 21707 +.. date: 8636 +.. nonce: rrY_wd +.. section: Library + +Add missing kwonlyargcount argument to ModuleFinder.replace_paths_in_code(). + +.. + +.. bpo: 20639 +.. date: 8635 +.. nonce: YdvOpp +.. section: Library + +calling Path.with_suffix('') allows removing the suffix again. Patch by +July Tikhonov. + +.. + +.. bpo: 21714 +.. date: 8634 +.. nonce: HhkGXW +.. section: Library + +Disallow the construction of invalid paths using Path.with_name(). Original +patch by Antony Lee. + +.. + +.. bpo: 15014 +.. date: 8633 +.. nonce: dB50zb +.. section: Library + +Added 'auth' method to smtplib to make implementing auth mechanisms simpler, +and used it internally in the login method. + +.. + +.. bpo: 21151 +.. date: 8632 +.. nonce: o7IuiD +.. section: Library + +Fixed a segfault in the winreg module when ``None`` is passed as a +``REG_BINARY`` value to SetValueEx. Patch by John Ehresman. + +.. + +.. bpo: 21090 +.. date: 8631 +.. nonce: 20Ooif +.. section: Library + +io.FileIO.readall() does not ignore I/O errors anymore. Before, it ignored +I/O errors if at least the first C call read() succeed. + +.. + +.. bpo: 5800 +.. date: 8630 +.. nonce: ZJiLZP +.. section: Library + +headers parameter of wsgiref.headers.Headers is now optional. Initial patch +by Pablo Torres Navarrete and SilentGhost. + +.. + +.. bpo: 21781 +.. date: 8629 +.. nonce: u_oiv9 +.. section: Library + +ssl.RAND_add() now supports strings longer than 2 GB. + +.. + +.. bpo: 21679 +.. date: 8628 +.. nonce: CTVT9A +.. section: Library + +Prevent extraneous fstat() calls during open(). Patch by Bohuslav Kabrda. + +.. + +.. bpo: 21863 +.. date: 8627 +.. nonce: BzbwSL +.. section: Library + +cProfile now displays the module name of C extension functions, in addition +to their own name. + +.. + +.. bpo: 11453 +.. date: 8626 +.. nonce: 53Gr_R +.. section: Library + +asyncore: emit a ResourceWarning when an unclosed file_wrapper object is +destroyed. The destructor now closes the file if needed. The close() method +can now be called twice: the second call does nothing. + +.. + +.. bpo: 21858 +.. date: 8625 +.. nonce: 0hbFBG +.. section: Library + +Better handling of Python exceptions in the sqlite3 module. + +.. + +.. bpo: 21476 +.. date: 8624 +.. nonce: VN-5pW +.. section: Library + +Make sure the email.parser.BytesParser TextIOWrapper is discarded after +parsing, so the input file isn't unexpectedly closed. + +.. + +.. bpo: 20295 +.. date: 8623 +.. nonce: U1MPhw +.. section: Library + +imghdr now recognizes OpenEXR format images. + +.. + +.. bpo: 21729 +.. date: 8622 +.. nonce: dk7o_U +.. section: Library + +Used the "with" statement in the dbm.dumb module to ensure files closing. +Patch by Claudiu Popa. + +.. + +.. bpo: 21491 +.. date: 8621 +.. nonce: Zxmut- +.. section: Library + +socketserver: Fix a race condition in child processes reaping. + +.. + +.. bpo: 21719 +.. date: 8620 +.. nonce: DhQz3I +.. section: Library + +Added the ``st_file_attributes`` field to os.stat_result on Windows. + +.. + +.. bpo: 21832 +.. date: 8619 +.. nonce: PBA0Uu +.. section: Library + +Require named tuple inputs to be exact strings. + +.. + +.. bpo: 21722 +.. date: 8618 +.. nonce: WTHuRy +.. section: Library + +The distutils "upload" command now exits with a non-zero return code when +uploading fails. Patch by Martin Dengler. + +.. + +.. bpo: 21723 +.. date: 8617 +.. nonce: r86fwb +.. section: Library + +asyncio.Queue: support any type of number (ex: float) for the maximum size. +Patch written by Vajrasky Kok. + +.. + +.. bpo: 21711 +.. date: 8616 +.. nonce: JWPFQZ +.. section: Library + +support for "site-python" directories has now been removed from the site +module (it was deprecated in 3.4). + +.. + +.. bpo: 17552 +.. date: 8615 +.. nonce: NunErD +.. section: Library + +new socket.sendfile() method allowing a file to be sent over a socket by +using high-performance os.sendfile() on UNIX. Patch by Giampaolo Rodola'. + +.. + +.. bpo: 18039 +.. date: 8614 +.. nonce: vC9hNy +.. section: Library + +dbm.dump.open() now always creates a new database when the flag has the +value 'n'. Patch by Claudiu Popa. + +.. + +.. bpo: 21326 +.. date: 8613 +.. nonce: Y6iW3s +.. section: Library + +Add a new is_closed() method to asyncio.BaseEventLoop. run_forever() and +run_until_complete() methods of asyncio.BaseEventLoop now raise an exception +if the event loop was closed. + +.. + +.. bpo: 21766 +.. date: 8612 +.. nonce: 0xk_xC +.. section: Library + +Prevent a security hole in CGIHTTPServer by URL unquoting paths before +checking for a CGI script at that path. + +.. + +.. bpo: 21310 +.. date: 8611 +.. nonce: 2mjByJ +.. section: Library + +Fixed possible resource leak in failed open(). + +.. + +.. bpo: 21256 +.. date: 8610 +.. nonce: dGq6cw +.. section: Library + +Printout of keyword args should be in deterministic order in a mock function +call. This will help to write better doctests. + +.. + +.. bpo: 21677 +.. date: 8609 +.. nonce: 58CDDD +.. section: Library + +Fixed chaining nonnormalized exceptions in io close() methods. + +.. + +.. bpo: 11709 +.. date: 8608 +.. nonce: JdObvL +.. section: Library + +Fix the pydoc.help function to not fail when sys.stdin is not a valid file. + +.. + +.. bpo: 21515 +.. date: 8607 +.. nonce: D9TLJF +.. section: Library + +tempfile.TemporaryFile now uses os.O_TMPFILE flag is available. + +.. + +.. bpo: 13223 +.. date: 8606 +.. nonce: 9AzEbN +.. section: Library + +Fix pydoc.writedoc so that the HTML documentation for methods that use +'self' in the example code is generated correctly. + +.. + +.. bpo: 21463 +.. date: 8605 +.. nonce: 09PsgH +.. section: Library + +In urllib.request, fix pruning of the FTP cache. + +.. + +.. bpo: 21618 +.. date: 8604 +.. nonce: 3Z7WS3 +.. section: Library + +The subprocess module could fail to close open fds that were inherited by +the calling process and already higher than POSIX resource limits would +otherwise allow. On systems with a functioning /proc/self/fd or /dev/fd +interface the max is now ignored and all fds are closed. + +.. + +.. bpo: 20383 +.. date: 8603 +.. nonce: pSPFpW +.. section: Library + +Introduce importlib.util.module_from_spec() as the preferred way to create a +new module. + +.. + +.. bpo: 21552 +.. date: 8602 +.. nonce: uVy4tM +.. section: Library + +Fixed possible integer overflow of too long string lengths in the tkinter +module on 64-bit platforms. + +.. + +.. bpo: 14315 +.. date: 8601 +.. nonce: YzZzS8 +.. section: Library + +The zipfile module now ignores extra fields in the central directory that +are too short to be parsed instead of letting a struct.unpack error bubble +up as this "bad data" appears in many real world zip files in the wild and +is ignored by other zip tools. + +.. + +.. bpo: 13742 +.. date: 8600 +.. nonce: QJiVSC +.. section: Library + +Added "key" and "reverse" parameters to heapq.merge(). (First draft of patch +contributed by Simon Sapin.) + +.. + +.. bpo: 21402 +.. date: 8599 +.. nonce: 51vDXt +.. section: Library + +tkinter.ttk now works when default root window is not set. + +.. + +.. bpo: 3015 +.. date: 8598 +.. nonce: FE_PII +.. section: Library + +_tkinter.create() now creates tkapp object with wantobject=1 by default. + +.. + +.. bpo: 10203 +.. date: 8597 +.. nonce: zgr0hh +.. section: Library + +sqlite3.Row now truly supports sequence protocol. In particular it supports +reverse() and negative indices. Original patch by Claudiu Popa. + +.. + +.. bpo: 18807 +.. date: 8596 +.. nonce: XP7p8B +.. section: Library + +If copying (no symlinks) specified for a venv, then the python interpreter +aliases (python, python3) are now created by copying rather than symlinking. + +.. + +.. bpo: 20197 +.. date: 8595 +.. nonce: nYR9fq +.. section: Library + +Added support for the WebP image type in the imghdr module. Patch by Fabrice +Aneche and Claudiu Popa. + +.. + +.. bpo: 21513 +.. date: 8594 +.. nonce: ro4AOe +.. section: Library + +Speedup some properties of IP addresses (IPv4Address, IPv6Address) such as +.is_private or .is_multicast. + +.. + +.. bpo: 21137 +.. date: 8593 +.. nonce: wgHb_F +.. section: Library + +Improve the repr for threading.Lock() and its variants by showing the +"locked" or "unlocked" status. Patch by Berker Peksag. + +.. + +.. bpo: 21538 +.. date: 8592 +.. nonce: Q60FWA +.. section: Library + +The plistlib module now supports loading of binary plist files when +reference or offset size is not a power of two. + +.. + +.. bpo: 21455 +.. date: 8591 +.. nonce: 6-Uvv4 +.. section: Library + +Add a default backlog to socket.listen(). + +.. + +.. bpo: 21525 +.. date: 8590 +.. nonce: hAKOve +.. section: Library + +Most Tkinter methods which accepted tuples now accept lists too. + +.. + +.. bpo: 22166 +.. date: 8589 +.. nonce: sZYhmv +.. section: Library + +With the assistance of a new internal _codecs._forget_codec helping +function, test_codecs now clears the encoding caches to avoid the appearance +of a reference leak + +.. + +.. bpo: 22236 +.. date: 8588 +.. nonce: ginJSI +.. section: Library + +Tkinter tests now don't reuse default root window. New root window is +created for every test class. + +.. + +.. bpo: 10744 +.. date: 8587 +.. nonce: kfV0wm +.. section: Library + +Fix :pep:`3118` format strings on ctypes objects with a nontrivial shape. + +.. + +.. bpo: 20826 +.. date: 8586 +.. nonce: 3rXqMC +.. section: Library + +Optimize ipaddress.collapse_addresses(). + +.. + +.. bpo: 21487 +.. date: 8585 +.. nonce: sX8YmK +.. section: Library + +Optimize ipaddress.summarize_address_range() and +ipaddress.{IPv4Network,IPv6Network}.subnets(). + +.. + +.. bpo: 21486 +.. date: 8584 +.. nonce: CeFKRP +.. section: Library + +Optimize parsing of netmasks in ipaddress.IPv4Network and +ipaddress.IPv6Network. + +.. + +.. bpo: 13916 +.. date: 8583 +.. nonce: D77YVH +.. section: Library + +Disallowed the surrogatepass error handler for non UTF-\* encodings. + +.. + +.. bpo: 20998 +.. date: 8582 +.. nonce: fkxpXI +.. section: Library + +Fixed re.fullmatch() of repeated single character pattern with ignore case. +Original patch by Matthew Barnett. + +.. + +.. bpo: 21075 +.. date: 8581 +.. nonce: f_hmEh +.. section: Library + +fileinput.FileInput now reads bytes from standard stream if binary mode is +specified. Patch by Sam Kimbrel. + +.. + +.. bpo: 19775 +.. date: 8580 +.. nonce: yxxD_R +.. section: Library + +Add a samefile() method to pathlib Path objects. Initial patch by Vajrasky +Kok. + +.. + +.. bpo: 21226 +.. date: 8579 +.. nonce: pzGmG1 +.. section: Library + +Set up modules properly in PyImport_ExecCodeModuleObject (and friends). + +.. + +.. bpo: 21398 +.. date: 8578 +.. nonce: guSBXt +.. section: Library + +Fix a unicode error in the pydoc pager when the documentation contains +characters not encodable to the stdout encoding. + +.. + +.. bpo: 16531 +.. date: 8577 +.. nonce: AhrY_v +.. section: Library + +ipaddress.IPv4Network and ipaddress.IPv6Network now accept an (address, +netmask) tuple argument, so as to easily construct network objects from +existing addresses. + +.. + +.. bpo: 21156 +.. date: 8576 +.. nonce: 3dmBEp +.. section: Library + +importlib.abc.InspectLoader.source_to_code() is now a staticmethod. + +.. + +.. bpo: 21424 +.. date: 8575 +.. nonce: 8CJBqW +.. section: Library + +Simplified and optimized heaqp.nlargest() and nmsmallest() to make fewer +tuple comparisons. + +.. + +.. bpo: 21396 +.. date: 8574 +.. nonce: cqO6DN +.. section: Library + +Fix TextIOWrapper(..., write_through=True) to not force a flush() on the +underlying binary stream. Patch by akira. + +.. + +.. bpo: 18314 +.. date: 8573 +.. nonce: NCd_KF +.. section: Library + +Unlink now removes junctions on Windows. Patch by Kim Gräsman + +.. + +.. bpo: 21088 +.. date: 8572 +.. nonce: WOg7Xy +.. section: Library + +Bugfix for curses.window.addch() regression in 3.4.0. In porting to Argument +Clinic, the first two arguments were reversed. + +.. + +.. bpo: 21407 +.. date: 8571 +.. nonce: cZjFde +.. section: Library + +_decimal: The module now supports function signatures. + +.. + +.. bpo: 10650 +.. date: 8570 +.. nonce: HYT4Oe +.. section: Library + +Remove the non-standard 'watchexp' parameter from the Decimal.quantize() +method in the Python version. It had never been present in the C version. + +.. + +.. bpo: 21469 +.. date: 8569 +.. nonce: _fFGuq +.. section: Library + +Reduced the risk of false positives in robotparser by checking to make sure +that robots.txt has been read or does not exist prior to returning True in +can_fetch(). + +.. + +.. bpo: 19414 +.. date: 8568 +.. nonce: bAAw4D +.. section: Library + +Have the OrderedDict mark deleted links as unusable. This gives an early +failure if the link is deleted during iteration. + +.. + +.. bpo: 21421 +.. date: 8567 +.. nonce: 5AKAat +.. section: Library + +Add __slots__ to the MappingViews ABC. Patch by Josh Rosenberg. + +.. + +.. bpo: 21101 +.. date: 8566 +.. nonce: Lj-_P4 +.. section: Library + +Eliminate double hashing in the C speed-up code for collections.Counter(). + +.. + +.. bpo: 21321 +.. date: 8565 +.. nonce: wUkTON +.. section: Library + +itertools.islice() now releases the reference to the source iterator when +the slice is exhausted. Patch by Anton Afanasyev. + +.. + +.. bpo: 21057 +.. date: 8564 +.. nonce: 0TC4Xl +.. section: Library + +TextIOWrapper now allows the underlying binary stream's read() or read1() +method to return an arbitrary bytes-like object (such as a memoryview). +Patch by Nikolaus Rath. + +.. + +.. bpo: 20951 +.. date: 8563 +.. nonce: tF0dJi +.. section: Library + +SSLSocket.send() now raises either SSLWantReadError or SSLWantWriteError on +a non-blocking socket if the operation would block. Previously, it would +return 0. Patch by Nikolaus Rath. + +.. + +.. bpo: 13248 +.. date: 8562 +.. nonce: 7vtGj0 +.. section: Library + +removed previously deprecated asyncore.dispatcher __getattr__ cheap +inheritance hack. + +.. + +.. bpo: 9815 +.. date: 8561 +.. nonce: 52FPlI +.. section: Library + +assertRaises now tries to clear references to local variables in the +exception's traceback. + +.. + +.. bpo: 19940 +.. date: 8560 +.. nonce: 2qtBQ8 +.. section: Library + +ssl.cert_time_to_seconds() now interprets the given time string in the UTC +timezone (as specified in RFC 5280), not the local timezone. + +.. + +.. bpo: 13204 +.. date: 8559 +.. nonce: ZPKA5g +.. section: Library + +Calling sys.flags.__new__ would crash the interpreter, now it raises a +TypeError. + +.. + +.. bpo: 19385 +.. date: 8558 +.. nonce: PexO_g +.. section: Library + +Make operations on a closed dbm.dumb database always raise the same +exception. + +.. + +.. bpo: 21207 +.. date: 8557 +.. nonce: Hr72AB +.. section: Library + +Detect when the os.urandom cached fd has been closed or replaced, and open +it anew. + +.. + +.. bpo: 21291 +.. date: 8556 +.. nonce: 5sSLWN +.. section: Library + +subprocess's Popen.wait() is now thread safe so that multiple threads may be +calling wait() or poll() on a Popen instance at the same time without losing +the Popen.returncode value. + +.. + +.. bpo: 21127 +.. date: 8555 +.. nonce: A1aBjG +.. section: Library + +Path objects can now be instantiated from str subclass instances (such as +``numpy.str_``). + +.. + +.. bpo: 15002 +.. date: 8554 +.. nonce: qorYDe +.. section: Library + +urllib.response object to use _TemporaryFileWrapper (and +_TemporaryFileCloser) facility. Provides a better way to handle file +descriptor close. Patch contributed by Christian Theune. + +.. + +.. bpo: 12220 +.. date: 8553 +.. nonce: U25uE9 +.. section: Library + +mindom now raises a custom ValueError indicating it doesn't support spaces +in URIs instead of letting a 'split' ValueError bubble up. + +.. + +.. bpo: 21068 +.. date: 8552 +.. nonce: 9k6N9m +.. section: Library + +The ssl.PROTOCOL* constants are now enum members. + +.. + +.. bpo: 21276 +.. date: 8551 +.. nonce: JkfhvQ +.. section: Library + +posixmodule: Don't define USE_XATTRS on KFreeBSD and the Hurd. + +.. + +.. bpo: 21262 +.. date: 8550 +.. nonce: 1J5ylk +.. section: Library + +New method assert_not_called for Mock. It raises AssertionError if the mock +has been called. + +.. + +.. bpo: 21238 +.. date: 8549 +.. nonce: 5CDoox +.. section: Library + +New keyword argument `unsafe` to Mock. It raises `AttributeError` incase of +an attribute startswith assert or assret. + +.. + +.. bpo: 20896 +.. date: 8548 +.. nonce: oWwAb1 +.. section: Library + +ssl.get_server_certificate() now uses PROTOCOL_SSLv23, not PROTOCOL_SSLv3, +for maximum compatibility. + +.. + +.. bpo: 21239 +.. date: 8547 +.. nonce: EalCNt +.. section: Library + +patch.stopall() didn't work deterministically when the same name was patched +more than once. + +.. + +.. bpo: 21203 +.. date: 8546 +.. nonce: 1IMs-Z +.. section: Library + +Updated fileConfig and dictConfig to remove inconsistencies. Thanks to Jure +Koren for the patch. + +.. + +.. bpo: 21222 +.. date: 8545 +.. nonce: G6MQBP +.. section: Library + +Passing name keyword argument to mock.create_autospec now works. + +.. + +.. bpo: 21197 +.. date: 8544 +.. nonce: Gzfqdl +.. section: Library + +Add lib64 -> lib symlink in venvs on 64-bit non-OS X POSIX. + +.. + +.. bpo: 17498 +.. date: 8543 +.. nonce: LR9xyb +.. section: Library + +Some SMTP servers disconnect after certain errors, violating strict RFC +conformance. Instead of losing the error code when we issue the subsequent +RSET, smtplib now returns the error code and defers raising the +SMTPServerDisconnected error until the next command is issued. + +.. + +.. bpo: 17826 +.. date: 8542 +.. nonce: z0zMRV +.. section: Library + +setting an iterable side_effect on a mock function created by +create_autospec now works. Patch by Kushal Das. + +.. + +.. bpo: 7776 +.. date: 8541 +.. nonce: K5S2Pe +.. section: Library + +Fix ``Host:`` header and reconnection when using +http.client.HTTPConnection.set_tunnel(). Patch by Nikolaus Rath. + +.. + +.. bpo: 20968 +.. date: 8540 +.. nonce: 53Aagz +.. section: Library + +unittest.mock.MagicMock now supports division. Patch by Johannes Baiter. + +.. + +.. bpo: 21529 +.. date: 8539 +.. nonce: 57R_Fc +.. section: Library + +Fix arbitrary memory access in JSONDecoder.raw_decode with a negative second +parameter. Bug reported by Guido Vranken. (See also: CVE-2014-4616) + +.. + +.. bpo: 21169 +.. date: 8538 +.. nonce: KE7B0M +.. section: Library + +getpass now handles non-ascii characters that the input stream encoding +cannot encode by re-encoding using the replace error handler. + +.. + +.. bpo: 21171 +.. date: 8537 +.. nonce: iUbV9S +.. section: Library + +Fixed undocumented filter API of the rot13 codec. Patch by Berker Peksag. + +.. + +.. bpo: 20539 +.. date: 8536 +.. nonce: 62nbEb +.. section: Library + +Improved math.factorial error message for large positive inputs and changed +exception type (OverflowError -> ValueError) for large negative inputs. + +.. + +.. bpo: 21172 +.. date: 8535 +.. nonce: dQ7yY7 +.. section: Library + +isinstance check relaxed from dict to collections.Mapping. + +.. + +.. bpo: 21155 +.. date: 8534 +.. nonce: JSKEE7 +.. section: Library + +asyncio.EventLoop.create_unix_server() now raises a ValueError if path and +sock are specified at the same time. + +.. + +.. bpo: 21136 +.. date: 8533 +.. nonce: JZAKv3 +.. section: Library + +Avoid unnecessary normalization of Fractions resulting from power and other +operations. Patch by Raymond Hettinger. + +.. + +.. bpo: 17621 +.. date: 8532 +.. nonce: 1x0mvJ +.. section: Library + +Introduce importlib.util.LazyLoader. + +.. + +.. bpo: 21076 +.. date: 8531 +.. nonce: upxQc6 +.. section: Library + +signal module constants were turned into enums. Patch by Giampaolo Rodola'. + +.. + +.. bpo: 20636 +.. date: 8530 +.. nonce: KGh-BD +.. section: Library + +Improved the repr of Tkinter widgets. + +.. + +.. bpo: 19505 +.. date: 8529 +.. nonce: VEtIE6 +.. section: Library + +The items, keys, and values views of OrderedDict now support reverse +iteration using reversed(). + +.. + +.. bpo: 21149 +.. date: 8528 +.. nonce: cnjwMR +.. section: Library + +Improved thread-safety in logging cleanup during interpreter shutdown. +Thanks to Devin Jeanpierre for the patch. + +.. + +.. bpo: 21058 +.. date: 8527 +.. nonce: IhluPP +.. section: Library + +Fix a leak of file descriptor in :func:`tempfile.NamedTemporaryFile`, close +the file descriptor if :func:`io.open` fails + +.. + +.. bpo: 21200 +.. date: 8526 +.. nonce: Kht8yD +.. section: Library + +Return None from pkgutil.get_loader() when __spec__ is missing. + +.. + +.. bpo: 21013 +.. date: 8525 +.. nonce: 3s8Ic0 +.. section: Library + +Enhance ssl.create_default_context() when used for server side sockets to +provide better security by default. + +.. + +.. bpo: 20145 +.. date: 8524 +.. nonce: FP5FY0 +.. section: Library + +`assertRaisesRegex` and `assertWarnsRegex` now raise a TypeError if the +second argument is not a string or compiled regex. + +.. + +.. bpo: 20633 +.. date: 8523 +.. nonce: 6kaPjT +.. section: Library + +Replace relative import by absolute import. + +.. + +.. bpo: 20980 +.. date: 8522 +.. nonce: cYszHY +.. section: Library + +Stop wrapping exception when using ThreadPool. + +.. + +.. bpo: 21082 +.. date: 8521 +.. nonce: GLzGlV +.. section: Library + +In os.makedirs, do not set the process-wide umask. Note this changes +behavior of makedirs when exist_ok=True. + +.. + +.. bpo: 20990 +.. date: 8520 +.. nonce: PBfjW3 +.. section: Library + +Fix issues found by pyflakes for multiprocessing. + +.. + +.. bpo: 21015 +.. date: 8519 +.. nonce: xnwWAH +.. section: Library + +SSL contexts will now automatically select an elliptic curve for ECDH key +exchange on OpenSSL 1.0.2 and later, and otherwise default to "prime256v1". + +.. + +.. bpo: 21000 +.. date: 8518 +.. nonce: JUyyVV +.. section: Library + +Improve the command-line interface of json.tool. + +.. + +.. bpo: 20995 +.. date: 8517 +.. nonce: KSORJT +.. section: Library + +Enhance default ciphers used by the ssl module to enable better security and +prioritize perfect forward secrecy. + +.. + +.. bpo: 20884 +.. date: 8516 +.. nonce: qNmub_ +.. section: Library + +Don't assume that __file__ is defined on importlib.__init__. + +.. + +.. bpo: 21499 +.. date: 8515 +.. nonce: wU4OBi +.. section: Library + +Ignore __builtins__ in several test_importlib.test_api tests. + +.. + +.. bpo: 20627 +.. date: 8514 +.. nonce: fgfQ1x +.. section: Library + +xmlrpc.client.ServerProxy is now a context manager. + +.. + +.. bpo: 19165 +.. date: 8513 +.. nonce: sAkUjU +.. section: Library + +The formatter module now raises DeprecationWarning instead of +PendingDeprecationWarning. + +.. + +.. bpo: 13936 +.. date: 8512 +.. nonce: _Q0Yog +.. section: Library + +Remove the ability of datetime.time instances to be considered false in +boolean contexts. + +.. + +.. bpo: 18931 +.. date: 8511 +.. nonce: mq4Mud +.. section: Library + +selectors module now supports /dev/poll on Solaris. Patch by Giampaolo +Rodola'. + +.. + +.. bpo: 19977 +.. date: 8510 +.. nonce: A-sQ_V +.. section: Library + +When the ``LC_TYPE`` locale is the POSIX locale (``C`` locale), +:py:data:`sys.stdin` and :py:data:`sys.stdout` are now using the +``surrogateescape`` error handler, instead of the ``strict`` error handler. + +.. + +.. bpo: 20574 +.. date: 8509 +.. nonce: KaKqSs +.. section: Library + +Implement incremental decoder for cp65001 code (Windows code page 65001, +Microsoft UTF-8). + +.. + +.. bpo: 20879 +.. date: 8508 +.. nonce: myeYdq +.. section: Library + +Delay the initialization of encoding and decoding tables for base32, ascii85 +and base85 codecs in the base64 module, and delay the initialization of the +unquote_to_bytes() table of the urllib.parse module, to not waste memory if +these modules are not used. + +.. + +.. bpo: 19157 +.. date: 8507 +.. nonce: V1-XhC +.. section: Library + +Include the broadcast address in the usuable hosts for IPv6 in ipaddress. + +.. + +.. bpo: 11599 +.. date: 8506 +.. nonce: 9QOXf4 +.. section: Library + +When an external command (e.g. compiler) fails, distutils now prints out the +whole command line (instead of just the command name) if the environment +variable DISTUTILS_DEBUG is set. + +.. + +.. bpo: 4931 +.. date: 8505 +.. nonce: uF10hr +.. section: Library + +distutils should not produce unhelpful "error: None" messages anymore. +distutils.util.grok_environment_error is kept but doc-deprecated. + +.. + +.. bpo: 20875 +.. date: 8504 +.. nonce: IjfI5V +.. section: Library + +Prevent possible gzip "'read' is not defined" NameError. Patch by Claudiu +Popa. + +.. + +.. bpo: 11558 +.. date: 8503 +.. nonce: pxrsmq +.. section: Library + +``email.message.Message.attach`` now returns a more useful error message if +``attach`` is called on a message for which ``is_multipart`` is False. + +.. + +.. bpo: 20283 +.. date: 8502 +.. nonce: v0Vs9V +.. section: Library + +RE pattern methods now accept the string keyword parameters as documented. +The pattern and source keyword parameters are left as deprecated aliases. + +.. + +.. bpo: 20778 +.. date: 8501 +.. nonce: g_fAGI +.. section: Library + +Fix modulefinder to work with bytecode-only modules. + +.. + +.. bpo: 20791 +.. date: 8500 +.. nonce: n_zrkc +.. section: Library + +copy.copy() now doesn't make a copy when the input is a bytes object. +Initial patch by Peter Otten. + +.. + +.. bpo: 19748 +.. date: 8499 +.. nonce: kiA171 +.. section: Library + +On AIX, time.mktime() now raises an OverflowError for year outsize range +[1902; 2037]. + +.. + +.. bpo: 19573 +.. date: 8498 +.. nonce: QJvX_V +.. section: Library + +inspect.signature: Use enum for parameter kind constants. + +.. + +.. bpo: 20726 +.. date: 8497 +.. nonce: 0yfRDI +.. section: Library + +inspect.signature: Make Signature and Parameter picklable. + +.. + +.. bpo: 17373 +.. date: 8496 +.. nonce: ECwuJO +.. section: Library + +Add inspect.Signature.from_callable method. + +.. + +.. bpo: 20378 +.. date: 8495 +.. nonce: l9M3H- +.. section: Library + +Improve repr of inspect.Signature and inspect.Parameter. + +.. + +.. bpo: 20816 +.. date: 8494 +.. nonce: DFMEgN +.. section: Library + +Fix inspect.getcallargs() to raise correct TypeError for missing +keyword-only arguments. Patch by Jeremiah Lowin. + +.. + +.. bpo: 20817 +.. date: 8493 +.. nonce: O5XyZB +.. section: Library + +Fix inspect.getcallargs() to fail correctly if more than 3 arguments are +missing. Patch by Jeremiah Lowin. + +.. + +.. bpo: 6676 +.. date: 8492 +.. nonce: CJu5On +.. section: Library + +Ensure a meaningful exception is raised when attempting to parse more than +one XML document per pyexpat xmlparser instance. (Original patches by +Hirokazu Yamamoto and Amaury Forgeot d'Arc, with suggested wording by David +Gutteridge) + +.. + +.. bpo: 21117 +.. date: 8491 +.. nonce: hyH7EK +.. section: Library + +Fix inspect.signature to better support functools.partial. Due to the +specifics of functools.partial implementation, positional-or-keyword +arguments passed as keyword arguments become keyword-only. + +.. + +.. bpo: 20334 +.. date: 8490 +.. nonce: 0yFmfQ +.. section: Library + +inspect.Signature and inspect.Parameter are now hashable. Thanks to Antony +Lee for bug reports and suggestions. + +.. + +.. bpo: 15916 +.. date: 8489 +.. nonce: _vhKPn +.. section: Library + +doctest.DocTestSuite returns an empty unittest.TestSuite instead of raising +ValueError if it finds no tests + +.. + +.. bpo: 21209 +.. date: 8488 +.. nonce: wRE7Dn +.. section: Library + +Fix asyncio.tasks.CoroWrapper to workaround a bug in yield-from +implementation in CPythons prior to 3.4.1. + +.. + +.. bpo: 0 +.. date: 8487 +.. nonce: Q1I78Z +.. section: Library + +asyncio: Add gi_{frame,running,code} properties to CoroWrapper (upstream +issue #163). + +.. + +.. bpo: 21311 +.. date: 8486 +.. nonce: JsDF8H +.. section: Library + +Avoid exception in _osx_support with non-standard compiler configurations. +Patch by John Szakmeister. + +.. + +.. bpo: 11571 +.. date: 8485 +.. nonce: RPeGNo +.. section: Library + +Ensure that the turtle window becomes the topmost window when launched on OS +X. + +.. + +.. bpo: 21801 +.. date: 8484 +.. nonce: rzfhYl +.. section: Library + +Validate that __signature__ is None or an instance of Signature. + +.. + +.. bpo: 21923 +.. date: 8483 +.. nonce: hXnoZa +.. section: Library + +Prevent AttributeError in distutils.sysconfig.customize_compiler due to +possible uninitialized _config_vars. + +.. + +.. bpo: 21323 +.. date: 8482 +.. nonce: quiWfl +.. section: Library + +Fix http.server to again handle scripts in CGI subdirectories, broken by the +fix for security issue #19435. Patch by Zach Byrne. + +.. + +.. bpo: 22733 +.. date: 8481 +.. nonce: 21gJBp +.. section: Library + +Fix ffi_prep_args not zero-extending argument values correctly on 64-bit +Windows. + +.. + +.. bpo: 23302 +.. date: 8480 +.. nonce: X2dabK +.. section: Library + +Default to TCP_NODELAY=1 upon establishing an HTTPConnection. Removed use of +hard-coded MSS as it's an optimization that's no longer needed with Nagle +disabled. + +.. + +.. bpo: 20577 +.. date: 8479 +.. nonce: Y71IMj +.. section: IDLE + +Configuration of the max line length for the FormatParagraph extension has +been moved from the General tab of the Idle preferences dialog to the +FormatParagraph tab of the Config Extensions dialog. Patch by Tal Einat. + +.. + +.. bpo: 16893 +.. date: 8478 +.. nonce: JfHAA4 +.. section: IDLE + +Update Idle doc chapter to match current Idle and add new information. + +.. + +.. bpo: 3068 +.. date: 8477 +.. nonce: TYjXTA +.. section: IDLE + +Add Idle extension configuration dialog to Options menu. Changes are written +to HOME/.idlerc/config-extensions.cfg. Original patch by Tal Einat. + +.. + +.. bpo: 16233 +.. date: 8476 +.. nonce: sOadNo +.. section: IDLE + +A module browser (File : Class Browser, Alt+C) requires an editor window +with a filename. When Class Browser is requested otherwise, from a shell, +output window, or 'Untitled' editor, Idle no longer displays an error box. +It now pops up an Open Module box (Alt+M). If a valid name is entered and a +module is opened, a corresponding browser is also opened. + +.. + +.. bpo: 4832 +.. date: 8475 +.. nonce: GRKi9M +.. section: IDLE + +Save As to type Python files automatically adds .py to the name you enter +(even if your system does not display it). Some systems automatically add +.txt when type is Text files. + +.. + +.. bpo: 21986 +.. date: 8474 +.. nonce: 04GUv2 +.. section: IDLE + +Code objects are not normally pickled by the pickle module. To match this, +they are no longer pickled when running under Idle. + +.. + +.. bpo: 17390 +.. date: 8473 +.. nonce: I4vHFh +.. section: IDLE + +Adjust Editor window title; remove 'Python', move version to end. + +.. + +.. bpo: 14105 +.. date: 8472 +.. nonce: -FZwYH +.. section: IDLE + +Idle debugger breakpoints no longer disappear when inserting or deleting +lines. + +.. + +.. bpo: 17172 +.. date: 8471 +.. nonce: R8jkU1 +.. section: IDLE + +Turtledemo can now be run from Idle. Currently, the entry is on the Help +menu, but it may move to Run. Patch by Ramchandra Apt and Lita Cho. + +.. + +.. bpo: 21765 +.. date: 8470 +.. nonce: JyiDbd +.. section: IDLE + +Add support for non-ascii identifiers to HyperParser. + +.. + +.. bpo: 21940 +.. date: 8469 +.. nonce: VlIRz7 +.. section: IDLE + +Add unittest for WidgetRedirector. Initial patch by Saimadhav Heblikar. + +.. + +.. bpo: 18592 +.. date: 8468 +.. nonce: sMG-SZ +.. section: IDLE + +Add unittest for SearchDialogBase. Patch by Phil Webster. + +.. + +.. bpo: 21694 +.. date: 8467 +.. nonce: 1oLmRo +.. section: IDLE + +Add unittest for ParenMatch. Patch by Saimadhav Heblikar. + +.. + +.. bpo: 21686 +.. date: 8466 +.. nonce: TAkFB0 +.. section: IDLE + +add unittest for HyperParser. Original patch by Saimadhav Heblikar. + +.. + +.. bpo: 12387 +.. date: 8465 +.. nonce: XO7Ozk +.. section: IDLE + +Add missing upper(lower)case versions of default Windows key bindings for +Idle so Caps Lock does not disable them. Patch by Roger Serwy. + +.. + +.. bpo: 21695 +.. date: 8464 +.. nonce: g-t0Tm +.. section: IDLE + +Closing a Find-in-files output window while the search is still in progress +no longer closes Idle. + +.. + +.. bpo: 18910 +.. date: 8463 +.. nonce: ke8lMK +.. section: IDLE + +Add unittest for textView. Patch by Phil Webster. + +.. + +.. bpo: 18292 +.. date: 8462 +.. nonce: ks_3wm +.. section: IDLE + +Add unittest for AutoExpand. Patch by Saihadhav Heblikar. + +.. + +.. bpo: 18409 +.. date: 8461 +.. nonce: 7fe-aK +.. section: IDLE + +Add unittest for AutoComplete. Patch by Phil Webster. + +.. + +.. bpo: 21477 +.. date: 8460 +.. nonce: 33NOe0 +.. section: IDLE + +htest.py - Improve framework, complete set of tests. Patches by Saimadhav +Heblikar + +.. + +.. bpo: 18104 +.. date: 8459 +.. nonce: 8Fj9Pf +.. section: IDLE + +Add idlelib/idle_test/htest.py with a few sample tests to begin +consolidating and improving human-validated tests of Idle. Change other +files as needed to work with htest. Running the module as __main__ runs all +tests. + +.. + +.. bpo: 21139 +.. date: 8458 +.. nonce: kqetng +.. section: IDLE + +Change default paragraph width to 72, the :pep:`8` recommendation. + +.. + +.. bpo: 21284 +.. date: 8457 +.. nonce: KKJfmv +.. section: IDLE + +Paragraph reformat test passes after user changes reformat width. + +.. + +.. bpo: 17654 +.. date: 8456 +.. nonce: NbzhNS +.. section: IDLE + +Ensure IDLE menus are customized properly on OS X for non-framework builds +and for all variants of Tk. + +.. + +.. bpo: 23180 +.. date: 8455 +.. nonce: cE_89F +.. section: IDLE + +Rename IDLE "Windows" menu item to "Window". Patch by Al Sweigart. + +.. + +.. bpo: 15506 +.. date: 8454 +.. nonce: nh8KlR +.. section: Build + +Use standard PKG_PROG_PKG_CONFIG autoconf macro in the configure script. + +.. + +.. bpo: 22935 +.. date: 8453 +.. nonce: -vY3lc +.. section: Build + +Allow the ssl module to be compiled if openssl doesn't support SSL 3. + +.. + +.. bpo: 22592 +.. date: 8452 +.. nonce: O_IE9W +.. section: Build + +Drop support of the Borland C compiler to build Python. The distutils module +still supports it to build extensions. + +.. + +.. bpo: 22591 +.. date: 8451 +.. nonce: wwBlG8 +.. section: Build + +Drop support of MS-DOS, especially of the DJGPP compiler (MS-DOS port of +GCC). + +.. + +.. bpo: 16537 +.. date: 8450 +.. nonce: llFo71 +.. section: Build + +Check whether self.extensions is empty in setup.py. Patch by Jonathan +Hosmer. + +.. + +.. bpo: 22359 +.. date: 8449 +.. nonce: YYFOFG +.. section: Build + +Remove incorrect uses of recursive make. Patch by Jonas Wagner. + +.. + +.. bpo: 21958 +.. date: 8448 +.. nonce: 3rq4qR +.. section: Build + +Define HAVE_ROUND when building with Visual Studio 2013 and above. Patch by +Zachary Turner. + +.. + +.. bpo: 18093 +.. date: 8447 +.. nonce: gnZieo +.. section: Build + +the programs that embed the CPython runtime are now in a separate "Programs" +directory, rather than being kept in the Modules directory. + +.. + +.. bpo: 15759 +.. date: 8446 +.. nonce: iGLR6O +.. section: Build + +"make suspicious", "make linkcheck" and "make doctest" in Doc/ now display +special message when and only when there are failures. + +.. + +.. bpo: 21141 +.. date: 8445 +.. nonce: 669LzK +.. section: Build + +The Windows build process no longer attempts to find Perl, instead relying +on OpenSSL source being configured and ready to build. The +``PCbuild\build_ssl.py`` script has been re-written and re-named to +``PCbuild\prepare_ssl.py``, and takes care of configuring OpenSSL source for +both 32 and 64 bit platforms. OpenSSL sources obtained from svn.python.org +will always be pre-configured and ready to build. + +.. + +.. bpo: 21037 +.. date: 8444 +.. nonce: v1rZzo +.. section: Build + +Add a build option to enable AddressSanitizer support. + +.. + +.. bpo: 19962 +.. date: 8443 +.. nonce: HDlwsE +.. section: Build + +The Windows build process now creates "python.bat" in the root of the source +tree, which passes all arguments through to the most recently built +interpreter. + +.. + +.. bpo: 21285 +.. date: 8442 +.. nonce: cU9p2E +.. section: Build + +Refactor and fix curses configure check to always search in a ncursesw +directory. + +.. + +.. bpo: 15234 +.. date: 8441 +.. nonce: vlM720 +.. section: Build + +For BerkeleyDB and Sqlite, only add the found library and include directories +if they aren't already being searched. This avoids an explicit runtime +library dependency. + +.. + +.. bpo: 17861 +.. date: 8440 +.. nonce: jCi44U +.. section: Build + +Tools/scripts/generate_opcode_h.py automatically regenerates +Include/opcode.h from Lib/opcode.py if the latter gets any change. + +.. + +.. bpo: 20644 +.. date: 8439 +.. nonce: aV0zq7 +.. section: Build + +OS X installer build support for documentation build changes in 3.4.1: +assume externally supplied sphinx-build is available in /usr/bin. + +.. + +.. bpo: 20022 +.. date: 8438 +.. nonce: EqSCTW +.. section: Build + +Eliminate use of deprecated bundlebuilder in OS X builds. + +.. + +.. bpo: 15968 +.. date: 8437 +.. nonce: vxUxHK +.. section: Build + +Incorporated Tcl, Tk, and Tix builds into the Windows build solution. + +.. + +.. bpo: 17095 +.. date: 8436 +.. nonce: -XEBIU +.. section: Build + +Fix Modules/Setup *shared* support. + +.. + +.. bpo: 21811 +.. date: 8435 +.. nonce: 3_Xyr- +.. section: Build + +Anticipated fixes to support OS X versions > 10.9. + +.. + +.. bpo: 21166 +.. date: 8434 +.. nonce: KAl7aO +.. section: Build + +Prevent possible segfaults and other random failures of python +--generate-posix-vars in pybuilddir.txt build target. + +.. + +.. bpo: 18096 +.. date: 8433 +.. nonce: ELyAUJ +.. section: Build + +Fix library order returned by python-config. + +.. + +.. bpo: 17219 +.. date: 8432 +.. nonce: q8ueQ0 +.. section: Build + +Add library build dir for Python extension cross-builds. + +.. + +.. bpo: 22919 +.. date: 8431 +.. nonce: 1XThL9 +.. section: Build + +Windows build updated to support VC 14.0 (Visual Studio 2015), which will be +used for the official release. + +.. + +.. bpo: 21236 +.. date: 8430 +.. nonce: 84LXxj +.. section: Build + +Build _msi.pyd with cabinet.lib instead of fci.lib + +.. + +.. bpo: 17128 +.. date: 8429 +.. nonce: U2biLA +.. section: Build + +Use private version of OpenSSL for OS X 10.5+ installer. + +.. + +.. bpo: 14203 +.. date: 8428 +.. nonce: 3hv0TX +.. section: C API + +Remove obsolete support for view==NULL in PyBuffer_FillInfo(), +bytearray_getbuffer(), bytesiobuf_getbuffer() and array_buffer_getbuf(). All +functions now raise BufferError in that case. + +.. + +.. bpo: 22445 +.. date: 8427 +.. nonce: s0AOAS +.. section: C API + +PyBuffer_IsContiguous() now implements precise contiguity tests, compatible +with NumPy's NPY_RELAXED_STRIDES_CHECKING compilation flag. Previously the +function reported false negatives for corner cases. + +.. + +.. bpo: 22079 +.. date: 8426 +.. nonce: zhs2qM +.. section: C API + +PyType_Ready() now checks that statically allocated type has no dynamically +allocated bases. + +.. + +.. bpo: 22453 +.. date: 8425 +.. nonce: XoO4ns +.. section: C API + +Removed non-documented macro PyObject_REPR(). + +.. + +.. bpo: 18395 +.. date: 8424 +.. nonce: YC9B06 +.. section: C API + +Rename ``_Py_char2wchar()`` to :c:func:`Py_DecodeLocale`, rename +``_Py_wchar2char()`` to :c:func:`Py_EncodeLocale`, and document these +functions. + +.. + +.. bpo: 21233 +.. date: 8423 +.. nonce: 98hZAt +.. section: C API + +Add new C functions: PyMem_RawCalloc(), PyMem_Calloc(), PyObject_Calloc(), +_PyObject_GC_Calloc(). bytes(int) is now using ``calloc()`` instead of +``malloc()`` for large objects which is faster and use less memory. + +.. + +.. bpo: 20942 +.. date: 8422 +.. nonce: qHLJ5- +.. section: C API + +PyImport_ImportFrozenModuleObject() no longer sets __file__ to match what +importlib does; this affects _frozen_importlib as well as any module loaded +using imp.init_frozen(). + +.. + +.. bpo: 19548 +.. date: 8421 +.. nonce: yOX8sS +.. section: Documentation + +Update the codecs module documentation to better cover the distinction +between text encodings and other codecs, together with other clarifications. +Patch by Martin Panter. + +.. + +.. bpo: 22394 +.. date: 8420 +.. nonce: 6bJywY +.. section: Documentation + +Doc/Makefile now supports ``make venv PYTHON=../python`` to create a venv +for generating the documentation, e.g., ``make html +PYTHON=venv/bin/python3``. + +.. + +.. bpo: 21514 +.. date: 8419 +.. nonce: 1H16T6 +.. section: Documentation + +The documentation of the json module now refers to new JSON RFC 7159 instead +of obsoleted RFC 4627. + +.. + +.. bpo: 21777 +.. date: 8418 +.. nonce: dtQCWV +.. section: Documentation + +The binary sequence methods on bytes and bytearray are now documented +explicitly, rather than assuming users will be able to derive the expected +behaviour from the behaviour of the corresponding str methods. + +.. + +.. bpo: 6916 +.. date: 8417 +.. nonce: 4sm3nE +.. section: Documentation + +undocument deprecated asynchat.fifo class. + +.. + +.. bpo: 17386 +.. date: 8416 +.. nonce: ivaGLb +.. section: Documentation + +Expanded functionality of the ``Doc/make.bat`` script to make it much more +comparable to ``Doc/Makefile``. + +.. + +.. bpo: 21312 +.. date: 8415 +.. nonce: 6IqcV4 +.. section: Documentation + +Update the thread_foobar.h template file to include newer threading APIs. +Patch by Jack McCracken. + +.. + +.. bpo: 21043 +.. date: 8414 +.. nonce: oEOC8O +.. section: Documentation + +Remove the recommendation for specific CA organizations and to mention the +ability to load the OS certificates. + +.. + +.. bpo: 20765 +.. date: 8413 +.. nonce: Rv3GgV +.. section: Documentation + +Add missing documentation for PurePath.with_name() and +PurePath.with_suffix(). + +.. + +.. bpo: 19407 +.. date: 8412 +.. nonce: mRyNnG +.. section: Documentation + +New package installation and distribution guides based on the Python +Packaging Authority tools. Existing guides have been retained as legacy +links from the distutils docs, as they still contain some required reference +material for tool developers that isn't recorded anywhere else. + +.. + +.. bpo: 19697 +.. date: 8411 +.. nonce: 2jMQBP +.. section: Documentation + +Document cases where __main__.__spec__ is None. + +.. + +.. bpo: 18982 +.. date: 8410 +.. nonce: TynSM6 +.. section: Tests + +Add tests for CLI of the calendar module. + +.. + +.. bpo: 19548 +.. date: 8409 +.. nonce: 25Kxq_ +.. section: Tests + +Added some additional checks to test_codecs to ensure that statements in the +updated documentation remain accurate. Patch by Martin Panter. + +.. + +.. bpo: 22838 +.. date: 8408 +.. nonce: VZBtZg +.. section: Tests + +All test_re tests now work with unittest test discovery. + +.. + +.. bpo: 22173 +.. date: 8407 +.. nonce: dxIIVx +.. section: Tests + +Update lib2to3 tests to use unittest test discovery. + +.. + +.. bpo: 16000 +.. date: 8406 +.. nonce: Y7O6TP +.. section: Tests + +Convert test_curses to use unittest. + +.. + +.. bpo: 21456 +.. date: 8405 +.. nonce: Axsw43 +.. section: Tests + +Skip two tests in test_urllib2net.py if _ssl module not present. Patch by +Remi Pointel. + +.. + +.. bpo: 20746 +.. date: 8404 +.. nonce: N2pzAY +.. section: Tests + +Fix test_pdb to run in refleak mode (-R). Patch by Xavier de Gaye. + +.. + +.. bpo: 22060 +.. date: 8403 +.. nonce: TduJNO +.. section: Tests + +test_ctypes has been somewhat cleaned up and simplified; it now uses +unittest test discovery to find its tests. + +.. + +.. bpo: 22104 +.. date: 8402 +.. nonce: -YYDup +.. section: Tests + +regrtest.py no longer holds a reference to the suite of tests loaded from +test modules that don't define test_main(). + +.. + +.. bpo: 22111 +.. date: 8401 +.. nonce: 0XlFAU +.. section: Tests + +Assorted cleanups in test_imaplib. Patch by Milan Oberkirch. + +.. + +.. bpo: 22002 +.. date: 8400 +.. nonce: jpiaA2 +.. section: Tests + +Added ``load_package_tests`` function to test.support and used it to +implement/augment test discovery in test_asyncio, test_email, +test_importlib, test_json, and test_tools. + +.. + +.. bpo: 21976 +.. date: 8399 +.. nonce: Slq6se +.. section: Tests + +Fix test_ssl to accept LibreSSL version strings. Thanks to William Orr. + +.. + +.. bpo: 21918 +.. date: 8398 +.. nonce: QTFFSj +.. section: Tests + +Converted test_tools from a module to a package containing separate test +files for each tested script. + +.. + +.. bpo: 9554 +.. date: 8397 +.. nonce: VsP0Ve +.. section: Tests + +Use modern unittest features in test_argparse. Initial patch by Denver +Coneybeare and Radu Voicilas. + +.. + +.. bpo: 20155 +.. date: 8396 +.. nonce: nphzS3 +.. section: Tests + +Changed HTTP method names in failing tests in test_httpservers so that +packet filtering software (specifically Windows Base Filtering Engine) does +not interfere with the transaction semantics expected by the tests. + +.. + +.. bpo: 19493 +.. date: 8395 +.. nonce: SwbzLQ +.. section: Tests + +Refactored the ctypes test package to skip tests explicitly rather than +silently. + +.. + +.. bpo: 18492 +.. date: 8394 +.. nonce: ylPRU7 +.. section: Tests + +All resources are now allowed when tests are not run by regrtest.py. + +.. + +.. bpo: 21634 +.. date: 8393 +.. nonce: Eng06F +.. section: Tests + +Fix pystone micro-benchmark: use floor division instead of true division to +benchmark integers instead of floating point numbers. Set pystone version to +1.2. Patch written by Lennart Regebro. + +.. + +.. bpo: 21605 +.. date: 8392 +.. nonce: qsLV8d +.. section: Tests + +Added tests for Tkinter images. + +.. + +.. bpo: 21493 +.. date: 8391 +.. nonce: NqhRsy +.. section: Tests + +Added test for ntpath.expanduser(). Original patch by Claudiu Popa. + +.. + +.. bpo: 19925 +.. date: 8390 +.. nonce: dhMx08 +.. section: Tests + +Added tests for the spwd module. Original patch by Vajrasky Kok. + +.. + +.. bpo: 21522 +.. date: 8389 +.. nonce: b-VwFW +.. section: Tests + +Added Tkinter tests for Listbox.itemconfigure(), +PanedWindow.paneconfigure(), and Menu.entryconfigure(). + +.. + +.. bpo: 17756 +.. date: 8388 +.. nonce: LLfbfU +.. section: Tests + +Fix test_code test when run from the installed location. + +.. + +.. bpo: 17752 +.. date: 8387 +.. nonce: P8iG44 +.. section: Tests + +Fix distutils tests when run from the installed location. + +.. + +.. bpo: 18604 +.. date: 8386 +.. nonce: Q00Xrj +.. section: Tests + +Consolidated checks for GUI availability. All platforms now at least check +whether Tk can be instantiated when the GUI resource is requested. + +.. + +.. bpo: 21275 +.. date: 8385 +.. nonce: lI5FkX +.. section: Tests + +Fix a socket test on KFreeBSD. + +.. + +.. bpo: 21223 +.. date: 8384 +.. nonce: lMY6ka +.. section: Tests + +Pass test_site/test_startup_imports when some of the extensions are built as +builtins. + +.. + +.. bpo: 20635 +.. date: 8383 +.. nonce: mzWmoS +.. section: Tests + +Added tests for Tk geometry managers. + +.. + +.. bpo: 0 +.. date: 8382 +.. nonce: E5XNqr +.. section: Tests + +Add test case for freeze. + +.. + +.. bpo: 20743 +.. date: 8381 +.. nonce: hxZQUf +.. section: Tests + +Fix a reference leak in test_tcl. + +.. + +.. bpo: 21097 +.. date: 8380 +.. nonce: gsUesm +.. section: Tests + +Move test_namespace_pkgs into test_importlib. + +.. + +.. bpo: 21503 +.. date: 8379 +.. nonce: H9TPCg +.. section: Tests + +Use test_both() consistently in test_importlib. + +.. + +.. bpo: 20939 +.. date: 8378 +.. nonce: x3KQ35 +.. section: Tests + +Avoid various network test failures due to new redirect of +http://www.python.org/ to https://www.python.org: use http://www.example.com +instead. + +.. + +.. bpo: 20668 +.. date: 8377 +.. nonce: IWjOSC +.. section: Tests + +asyncio tests no longer rely on tests.txt file. (Patch by Vajrasky Kok) + +.. + +.. bpo: 21093 +.. date: 8376 +.. nonce: CcpRim +.. section: Tests + +Prevent failures of ctypes test_macholib on OS X if a copy of libz exists in +$HOME/lib or /usr/local/lib. + +.. + +.. bpo: 22770 +.. date: 8375 +.. nonce: FxAh91 +.. section: Tests + +Prevent some Tk segfaults on OS X when running gui tests. + +.. + +.. bpo: 23211 +.. date: 8374 +.. nonce: Bc-QfJ +.. section: Tests + +Workaround test_logging failure on some OS X 10.6 systems. + +.. + +.. bpo: 23345 +.. date: 8373 +.. nonce: HIGBKx +.. section: Tests + +Prevent test_ssl failures with large OpenSSL patch level values (like +0.9.8zc). + +.. + +.. bpo: 22314 +.. date: 8372 +.. nonce: ws6xsH +.. section: Tools/Demos + +pydoc now works when the LINES environment variable is set. + +.. + +.. bpo: 22615 +.. date: 8371 +.. nonce: My3DWN +.. section: Tools/Demos + +Argument Clinic now supports the "type" argument for the int converter. +This permits using the int converter with enums and typedefs. + +.. + +.. bpo: 20076 +.. date: 8370 +.. nonce: ZNuBrC +.. section: Tools/Demos + +The makelocalealias.py script no longer ignores UTF-8 mapping. + +.. + +.. bpo: 20079 +.. date: 8369 +.. nonce: ogPXcK +.. section: Tools/Demos + +The makelocalealias.py script now can parse the SUPPORTED file from glibc +sources and supports command line options for source paths. + +.. + +.. bpo: 22201 +.. date: 8368 +.. nonce: k1Awbh +.. section: Tools/Demos + +Command-line interface of the zipfile module now correctly extracts ZIP +files with directory entries. Patch by Ryan Wilson. + +.. + +.. bpo: 22120 +.. date: 8367 +.. nonce: KmBUj- +.. section: Tools/Demos + +For functions using an unsigned integer return converter, Argument Clinic +now generates a cast to that type for the comparison to -1 in the generated +code. (This suppresses a compilation warning.) + +.. + +.. bpo: 18974 +.. date: 8366 +.. nonce: I3DdAo +.. section: Tools/Demos + +Tools/scripts/diff.py now uses argparse instead of optparse. + +.. + +.. bpo: 21906 +.. date: 8365 +.. nonce: ZsKy9v +.. section: Tools/Demos + +Make Tools/scripts/md5sum.py work in Python 3. Patch by Zachary Ware. + +.. + +.. bpo: 21629 +.. date: 8364 +.. nonce: 9kZmQl +.. section: Tools/Demos + +Fix Argument Clinic's "--converters" feature. + +.. + +.. bpo: 0 +.. date: 8363 +.. nonce: _-ge-g +.. section: Tools/Demos + +Add support for ``yield from`` to 2to3. + +.. + +.. bpo: 0 +.. date: 8362 +.. nonce: dpFbyZ +.. section: Tools/Demos + +Add support for the :pep:`465` matrix multiplication operator to 2to3. + +.. + +.. bpo: 16047 +.. date: 8361 +.. nonce: IsgTzm +.. section: Tools/Demos + +Fix module exception list and __file__ handling in freeze. Patch by Meador +Inge. + +.. + +.. bpo: 11824 +.. date: 8360 +.. nonce: OBWc3T +.. section: Tools/Demos + +Consider ABI tags in freeze. Patch by Meador Inge. + +.. + +.. bpo: 20535 +.. date: 8359 +.. nonce: 0qkvZZ +.. section: Tools/Demos + +PYTHONWARNING no longer affects the run_tests.py script. Patch by Arfrever +Frehtes Taifersar Arahesis. + +.. + +.. bpo: 23260 +.. date: 8358 +.. nonce: aZ5VLH +.. section: Windows + +Update Windows installer + +.. + +.. bpo: 0 +.. date: 8357 +.. nonce: _aEUNt +.. section: Windows + +The bundled version of Tcl/Tk has been updated to 8.6.3. The most visible +result of this change is the addition of new native file dialogs when +running on Windows Vista or newer. See Tcl/Tk's TIP 432 for more +information. Also, this version of Tcl/Tk includes support for Windows 10. + +.. + +.. bpo: 17896 +.. date: 8356 +.. nonce: o79rHM +.. section: Windows + +The Windows build scripts now expect external library sources to be in +``PCbuild\..\externals`` rather than ``PCbuild\..\..``. + +.. + +.. bpo: 17717 +.. date: 8355 +.. nonce: y1zoye +.. section: Windows + +The Windows build scripts now use a copy of NASM pulled from svn.python.org +to build OpenSSL. + +.. + +.. bpo: 21907 +.. date: 8354 +.. nonce: jm1smN +.. section: Windows + +Improved the batch scripts provided for building Python. + +.. + +.. bpo: 22644 +.. date: 8353 +.. nonce: gosBki +.. section: Windows + +The bundled version of OpenSSL has been updated to 1.0.1j. + +.. + +.. bpo: 10747 +.. date: 8352 +.. nonce: LTWhLn +.. section: Windows + +Use versioned labels in the Windows start menu. Patch by Olive Kilburn. + +.. + +.. bpo: 22980 +.. date: 8351 +.. nonce: -UypE5 +.. section: Windows + +.pyd files with a version and platform tag (for example, ".cp35-win32.pyd") +will now be loaded in preference to those without tags. diff --git a/Misc/NEWS.d/3.5.0a2.rst b/Misc/NEWS.d/3.5.0a2.rst new file mode 100644 index 00000000..ebce6674 --- /dev/null +++ b/Misc/NEWS.d/3.5.0a2.rst @@ -0,0 +1,405 @@ +.. bpo: 23571 +.. date: 8990 +.. nonce: GTkAkq +.. release date: 2015-03-09 +.. section: Core and Builtins + +PyObject_Call() and PyCFunction_Call() now raise a SystemError if a function +returns a result and raises an exception. The SystemError is chained to the +previous exception. + +.. + +.. bpo: 22524 +.. date: 8989 +.. nonce: Ks6_2x +.. section: Library + +New os.scandir() function, part of the :pep:`471`: "os.scandir() function -- a +better and faster directory iterator". Patch written by Ben Hoyt. + +.. + +.. bpo: 23103 +.. date: 8988 +.. nonce: I3RLIV +.. section: Library + +Reduced the memory consumption of IPv4Address and IPv6Address. + +.. + +.. bpo: 21793 +.. date: 8987 +.. nonce: GQtYMM +.. section: Library + +BaseHTTPRequestHandler again logs response code as numeric, not as +stringified enum. Patch by Demian Brecht. + +.. + +.. bpo: 23476 +.. date: 8986 +.. nonce: 82QV9I +.. section: Library + +In the ssl module, enable OpenSSL's X509_V_FLAG_TRUSTED_FIRST flag on +certificate stores when it is available. + +.. + +.. bpo: 23576 +.. date: 8985 +.. nonce: 98F-PP +.. section: Library + +Avoid stalling in SSL reads when EOF has been reached in the SSL layer but +the underlying connection hasn't been closed. + +.. + +.. bpo: 23504 +.. date: 8984 +.. nonce: o31h5I +.. section: Library + +Added an __all__ to the types module. + +.. + +.. bpo: 23563 +.. date: 8983 +.. nonce: iQB-ba +.. section: Library + +Optimized utility functions in urllib.parse. + +.. + +.. bpo: 7830 +.. date: 8982 +.. nonce: irvPdC +.. section: Library + +Flatten nested functools.partial. + +.. + +.. bpo: 20204 +.. date: 8981 +.. nonce: DorA4b +.. section: Library + +Added the __module__ attribute to _tkinter classes. + +.. + +.. bpo: 19980 +.. date: 8980 +.. nonce: whwzL_ +.. section: Library + +Improved help() for non-recognized strings. help('') now shows the help on +str. help('help') now shows the help on help(). Original patch by Mark +Lawrence. + +.. + +.. bpo: 23521 +.. date: 8979 +.. nonce: HvwFfd +.. section: Library + +Corrected pure python implementation of timedelta division. +Eliminated OverflowError from ``timedelta * float`` for some floats; +Corrected rounding in timedelta true division. + +.. + +.. bpo: 21619 +.. date: 8978 +.. nonce: uL0SZh +.. section: Library + +Popen objects no longer leave a zombie after exit in the with statement if +the pipe was broken. Patch by Martin Panter. + +.. + +.. bpo: 22936 +.. date: 8977 +.. nonce: JrhGYd +.. section: Library + +Make it possible to show local variables in tracebacks for both the +traceback module and unittest. + +.. + +.. bpo: 15955 +.. date: 8976 +.. nonce: _8nYPy +.. section: Library + +Add an option to limit the output size in bz2.decompress(). Patch by +Nikolaus Rath. + +.. + +.. bpo: 6639 +.. date: 8975 +.. nonce: rmjUmG +.. section: Library + +Module-level turtle functions no longer raise TclError after closing the +window. + +.. + +.. bpo: 814253 +.. date: 8974 +.. nonce: icZb-I +.. section: Library + +Group references and conditional group references now work in lookbehind +assertions in regular expressions. (See also: bpo-9179) + +.. + +.. bpo: 23215 +.. date: 8973 +.. nonce: VHVSVX +.. section: Library + +Multibyte codecs with custom error handlers that ignores errors consumed too +much memory and raised SystemError or MemoryError. Original patch by Aleksi +Torhamo. + +.. + +.. bpo: 5700 +.. date: 8972 +.. nonce: iA5yzL +.. section: Library + +io.FileIO() called flush() after closing the file. flush() was not called in +close() if closefd=False. + +.. + +.. bpo: 23374 +.. date: 8971 +.. nonce: 8A9LuZ +.. section: Library + +Fixed pydoc failure with non-ASCII files when stdout encoding differs from +file system encoding (e.g. on Mac OS). + +.. + +.. bpo: 23481 +.. date: 8970 +.. nonce: ZWwliG +.. section: Library + +Remove RC4 from the SSL module's default cipher list. + +.. + +.. bpo: 21548 +.. date: 8969 +.. nonce: CmO_Yh +.. section: Library + +Fix pydoc.synopsis() and pydoc.apropos() on modules with empty docstrings. + +.. + +.. bpo: 22885 +.. date: 8968 +.. nonce: p8FnYk +.. section: Library + +Fixed arbitrary code execution vulnerability in the dbm.dumb module. +Original patch by Claudiu Popa. + +.. + +.. bpo: 23239 +.. date: 8967 +.. nonce: PGUq7T +.. section: Library + +ssl.match_hostname() now supports matching of IP addresses. + +.. + +.. bpo: 23146 +.. date: 8966 +.. nonce: PW-O3u +.. section: Library + +Fix mishandling of absolute Windows paths with forward slashes in pathlib. + +.. + +.. bpo: 23096 +.. date: 8965 +.. nonce: Ftrmf3 +.. section: Library + +Pickle representation of floats with protocol 0 now is the same for both +Python and C implementations. + +.. + +.. bpo: 19105 +.. date: 8964 +.. nonce: ZK07Ff +.. section: Library + +pprint now more efficiently uses free space at the right. + +.. + +.. bpo: 14910 +.. date: 8963 +.. nonce: zueIhP +.. section: Library + +Add allow_abbrev parameter to argparse.ArgumentParser. Patch by Jonathan +Paugh, Steven Bethard, paul j3 and Daniel Eriksson. + +.. + +.. bpo: 21717 +.. date: 8962 +.. nonce: Knut81 +.. section: Library + +tarfile.open() now supports 'x' (exclusive creation) mode. + +.. + +.. bpo: 23344 +.. date: 8961 +.. nonce: ieu8C1 +.. section: Library + +marshal.dumps() is now 20-25% faster on average. + +.. + +.. bpo: 20416 +.. date: 8960 +.. nonce: cwEgkL +.. section: Library + +marshal.dumps() with protocols 3 and 4 is now 40-50% faster on average. + +.. + +.. bpo: 23421 +.. date: 8959 +.. nonce: eckzoV +.. section: Library + +Fixed compression in tarfile CLI. Patch by wdv4758h. + +.. + +.. bpo: 23367 +.. date: 8958 +.. nonce: kHnFiz +.. section: Library + +Fix possible overflows in the unicodedata module. + +.. + +.. bpo: 23361 +.. date: 8957 +.. nonce: I_w0-z +.. section: Library + +Fix possible overflow in Windows subprocess creation code. + +.. + +.. bpo: 0 +.. date: 8956 +.. nonce: sfmjTs +.. section: Library + +logging.handlers.QueueListener now takes a respect_handler_level keyword +argument which, if set to True, will pass messages to handlers taking +handler levels into account. + +.. + +.. bpo: 19705 +.. date: 8955 +.. nonce: WLzTRV +.. section: Library + +turtledemo now has a visual sorting algorithm demo. Original patch from +Jason Yeo. + +.. + +.. bpo: 23801 +.. date: 8954 +.. nonce: jyJK3z +.. section: Library + +Fix issue where cgi.FieldStorage did not always ignore the entire preamble +to a multipart body. + +.. + +.. bpo: 23445 +.. date: 8953 +.. nonce: 7fmkYO +.. section: Build + +pydebug builds now use "gcc -Og" where possible, to make the resulting +executable faster. + +.. + +.. bpo: 23686 +.. date: 8952 +.. nonce: B7jDXY +.. section: Build + +Update OS X 10.5 installer build to use OpenSSL 1.0.2a. + +.. + +.. bpo: 20204 +.. date: 8951 +.. nonce: M_jcNK +.. section: C API + +Deprecation warning is now raised for builtin types without the __module__ +attribute. + +.. + +.. bpo: 23465 +.. date: 8950 +.. nonce: qBauCy +.. section: Windows + +Implement :pep:`486` - Make the Python Launcher aware of virtual environments. +Patch by Paul Moore. + +.. + +.. bpo: 23437 +.. date: 8949 +.. nonce: ro9X8r +.. section: Windows + +Make user scripts directory versioned on Windows. Patch by Paul Moore. diff --git a/Misc/NEWS.d/3.5.0a3.rst b/Misc/NEWS.d/3.5.0a3.rst new file mode 100644 index 00000000..a81d67ae --- /dev/null +++ b/Misc/NEWS.d/3.5.0a3.rst @@ -0,0 +1,518 @@ +.. bpo: 23573 +.. date: 9042 +.. nonce: ZpM4D- +.. release date: 2015-03-28 +.. section: Core and Builtins + +Increased performance of string search operations (str.find, str.index, +str.count, the in operator, str.split, str.partition) with arguments of +different kinds (UCS1, UCS2, UCS4). + +.. + +.. bpo: 23753 +.. date: 9041 +.. nonce: CREjLC +.. section: Core and Builtins + +Python doesn't support anymore platforms without stat() or fstat(), these +functions are always required. + +.. + +.. bpo: 23681 +.. date: 9040 +.. nonce: kh02TF +.. section: Core and Builtins + +The -b option now affects comparisons of bytes with int. + +.. + +.. bpo: 23632 +.. date: 9039 +.. nonce: UVdIZY +.. section: Core and Builtins + +Memoryviews now allow tuple indexing (including for multi-dimensional +memoryviews). + +.. + +.. bpo: 23192 +.. date: 9038 +.. nonce: QKqdow +.. section: Core and Builtins + +Fixed generator lambdas. Patch by Bruno Cauet. + +.. + +.. bpo: 23629 +.. date: 9037 +.. nonce: r9Mt2C +.. section: Core and Builtins + +Fix the default __sizeof__ implementation for variable-sized objects. + +.. + +.. bpo: 14260 +.. date: 9036 +.. nonce: b5M04V +.. section: Library + +The groupindex attribute of regular expression pattern object now is +non-modifiable mapping. + +.. + +.. bpo: 23792 +.. date: 9035 +.. nonce: Kfm9-f +.. section: Library + +Ignore KeyboardInterrupt when the pydoc pager is active. This mimics the +behavior of the standard unix pagers, and prevents pipepager from shutting +down while the pager itself is still running. + +.. + +.. bpo: 23775 +.. date: 9034 +.. nonce: xKGrSQ +.. section: Library + +pprint() of OrderedDict now outputs the same representation as repr(). + +.. + +.. bpo: 23765 +.. date: 9033 +.. nonce: 2ta_C4 +.. section: Library + +Removed IsBadStringPtr calls in ctypes + +.. + +.. bpo: 22364 +.. date: 9032 +.. nonce: ejtoKl +.. section: Library + +Improved some re error messages using regex for hints. + +.. + +.. bpo: 23742 +.. date: 9031 +.. nonce: _EkAIa +.. section: Library + +ntpath.expandvars() no longer loses unbalanced single quotes. + +.. + +.. bpo: 21717 +.. date: 9030 +.. nonce: pKndpx +.. section: Library + +The zipfile.ZipFile.open function now supports 'x' (exclusive creation) +mode. + +.. + +.. bpo: 21802 +.. date: 9029 +.. nonce: ygSM2A +.. section: Library + +The reader in BufferedRWPair now is closed even when closing writer failed +in BufferedRWPair.close(). + +.. + +.. bpo: 23622 +.. date: 9028 +.. nonce: 9-ZRqj +.. section: Library + +Unknown escapes in regular expressions that consist of ``'\'`` and ASCII +letter now raise a deprecation warning and will be forbidden in Python 3.6. + +.. + +.. bpo: 23671 +.. date: 9027 +.. nonce: zWPm-a +.. section: Library + +string.Template now allows specifying the "self" parameter as a keyword +argument. string.Formatter now allows specifying the "self" and the +"format_string" parameters as keyword arguments. + +.. + +.. bpo: 23502 +.. date: 9026 +.. nonce: AH20IQ +.. section: Library + +The pprint module now supports mapping proxies. + +.. + +.. bpo: 17530 +.. date: 9025 +.. nonce: PUp8rL +.. section: Library + +pprint now wraps long bytes objects and bytearrays. + +.. + +.. bpo: 22687 +.. date: 9024 +.. nonce: zEJPd9 +.. section: Library + +Fixed some corner cases in breaking words in tetxtwrap. Got rid of quadratic +complexity in breaking long words. + +.. + +.. bpo: 4727 +.. date: 9023 +.. nonce: iDQSpi +.. section: Library + +The copy module now uses pickle protocol 4 (PEP 3154) and supports copying +of instances of classes whose __new__ method takes keyword-only arguments. + +.. + +.. bpo: 23491 +.. date: 9022 +.. nonce: P_WKrt +.. section: Library + +Added a zipapp module to support creating executable zip file archives of +Python code. Registered ".pyz" and ".pyzw" extensions on Windows for these +archives (PEP 441). + +.. + +.. bpo: 23657 +.. date: 9021 +.. nonce: y1OaV- +.. section: Library + +Avoid explicit checks for str in zipapp, adding support for pathlib.Path +objects as arguments. + +.. + +.. bpo: 23688 +.. date: 9020 +.. nonce: d6LVy3 +.. section: Library + +Added support of arbitrary bytes-like objects and avoided unnecessary +copying of memoryview in gzip.GzipFile.write(). Original patch by Wolfgang +Maier. + +.. + +.. bpo: 23252 +.. date: 9019 +.. nonce: Goi18g +.. section: Library + +Added support for writing ZIP files to unseekable streams. + +.. + +.. bpo: 23647 +.. date: 9018 +.. nonce: pX2qrx +.. section: Library + +Increase imaplib's MAXLINE to accommodate modern mailbox sizes. + +.. + +.. bpo: 23539 +.. date: 9017 +.. nonce: 5BVUim +.. section: Library + +If body is None, http.client.HTTPConnection.request now sets Content-Length +to 0 for PUT, POST, and PATCH headers to avoid 411 errors from some web +servers. + +.. + +.. bpo: 22351 +.. date: 9016 +.. nonce: agB8Y3 +.. section: Library + +The nntplib.NNTP constructor no longer leaves the connection and socket open +until the garbage collector cleans them up. Patch by Martin Panter. + +.. + +.. bpo: 23704 +.. date: 9015 +.. nonce: LTyyxL +.. section: Library + +collections.deque() objects now support methods for index(), insert(), and +copy(). This allows deques to be registered as a MutableSequence and it +improves their substitutability for lists. + +.. + +.. bpo: 23715 +.. date: 9014 +.. nonce: Yap3tU +.. section: Library + +:func:`signal.sigwaitinfo` and :func:`signal.sigtimedwait` are now retried +when interrupted by a signal not in the *sigset* parameter, if the signal +handler does not raise an exception. signal.sigtimedwait() recomputes the +timeout with a monotonic clock when it is retried. + +.. + +.. bpo: 23001 +.. date: 9013 +.. nonce: YSFnam +.. section: Library + +Few functions in modules mmap, ossaudiodev, socket, ssl, and codecs, that +accepted only read-only bytes-like object now accept writable bytes-like +object too. + +.. + +.. bpo: 23646 +.. date: 9012 +.. nonce: Tljc1S +.. section: Library + +If time.sleep() is interrupted by a signal, the sleep is now retried with +the recomputed delay, except if the signal handler raises an exception (PEP +475). + +.. + +.. bpo: 23136 +.. date: 9011 +.. nonce: 1bnpnb +.. section: Library + +_strptime now uniformly handles all days in week 0, including Dec 30 of +previous year. Based on patch by Jim Carroll. + +.. + +.. bpo: 23700 +.. date: 9010 +.. nonce: VfnWwi +.. section: Library + +Iterator of NamedTemporaryFile now keeps a reference to NamedTemporaryFile +instance. Patch by Bohuslav Kabrda. + +.. + +.. bpo: 22903 +.. date: 9009 +.. nonce: 2GjTHY +.. section: Library + +The fake test case created by unittest.loader when it fails importing a test +module is now picklable. + +.. + +.. bpo: 22181 +.. date: 9008 +.. nonce: 7mnxea +.. section: Library + +On Linux, os.urandom() now uses the new getrandom() syscall if available, +syscall introduced in the Linux kernel 3.17. It is more reliable and more +secure, because it avoids the need of a file descriptor and waits until the +kernel has enough entropy. + +.. + +.. bpo: 2211 +.. date: 9007 +.. nonce: 17Iz5U +.. section: Library + +Updated the implementation of the http.cookies.Morsel class. Setting +attributes key, value and coded_value directly now is deprecated. update() +and setdefault() now transform and check keys. Comparing for equality now +takes into account attributes key, value and coded_value. copy() now returns +a Morsel, not a dict. repr() now contains all attributes. Optimized +checking keys and quoting values. Added new tests. Original patch by Demian +Brecht. + +.. + +.. bpo: 18983 +.. date: 9006 +.. nonce: vF4i2S +.. section: Library + +Allow selection of output units in timeit. Patch by Julian Gindi. + +.. + +.. bpo: 23631 +.. date: 9005 +.. nonce: GfSqNI +.. section: Library + +Fix traceback.format_list when a traceback has been mutated. + +.. + +.. bpo: 23568 +.. date: 9004 +.. nonce: ffzJc7 +.. section: Library + +Add rdivmod support to MagicMock() objects. Patch by Håkan Lövdahl. + +.. + +.. bpo: 2052 +.. date: 9003 +.. nonce: ujNgna +.. section: Library + +Add charset parameter to HtmlDiff.make_file(). + +.. + +.. bpo: 23668 +.. date: 9002 +.. nonce: nF_jnN +.. section: Library + +Support os.truncate and os.ftruncate on Windows. + +.. + +.. bpo: 23138 +.. date: 9001 +.. nonce: 4vMoMZ +.. section: Library + +Fixed parsing cookies with absent keys or values in cookiejar. Patch by +Demian Brecht. + +.. + +.. bpo: 23051 +.. date: 9000 +.. nonce: Vi5tCZ +.. section: Library + +multiprocessing.Pool methods imap() and imap_unordered() now handle +exceptions raised by an iterator. Patch by Alon Diamant and Davin Potts. + +.. + +.. bpo: 23581 +.. date: 8999 +.. nonce: D4Lknl +.. section: Library + +Add matmul support to MagicMock. Patch by Håkan Lövdahl. + +.. + +.. bpo: 23566 +.. date: 8998 +.. nonce: F6LSyk +.. section: Library + +enable(), register(), dump_traceback() and dump_traceback_later() functions +of faulthandler now accept file descriptors. Patch by Wei Wu. + +.. + +.. bpo: 22928 +.. date: 8997 +.. nonce: q2TmY0 +.. section: Library + +Disabled HTTP header injections in http.client. Original patch by Demian +Brecht. + +.. + +.. bpo: 23615 +.. date: 8996 +.. nonce: 5Kx9k5 +.. section: Library + +Modules bz2, tarfile and tokenize now can be reloaded with imp.reload(). +Patch by Thomas Kluyver. + +.. + +.. bpo: 23605 +.. date: 8995 +.. nonce: JUOA_X +.. section: Library + +os.walk() now calls os.scandir() instead of os.listdir(). The usage of +os.scandir() reduces the number of calls to os.stat(). Initial patch written +by Ben Hoyt. + +.. + +.. bpo: 23585 +.. date: 8994 +.. nonce: DTIIoI +.. section: Build + +make patchcheck will ensure the interpreter is built. + +.. + +.. bpo: 23583 +.. date: 8993 +.. nonce: bY8AbM +.. section: Tests + +Added tests for standard IO streams in IDLE. + +.. + +.. bpo: 22289 +.. date: 8992 +.. nonce: ybGcC- +.. section: Tests + +Prevent test_urllib2net failures due to ftp connection timeout. + +.. + +.. bpo: 22826 +.. date: 8991 +.. nonce: 3bcoDL +.. section: Tools/Demos + +The result of open() in Tools/freeze/bkfile.py is now better compatible with +regular files (in particular it now supports the context management +protocol). diff --git a/Misc/NEWS.d/3.5.0a4.rst b/Misc/NEWS.d/3.5.0a4.rst new file mode 100644 index 00000000..f60aa0a2 --- /dev/null +++ b/Misc/NEWS.d/3.5.0a4.rst @@ -0,0 +1,665 @@ +.. bpo: 22980 +.. date: 9109 +.. nonce: Lu_y6y +.. release date: 2015-04-19 +.. section: Core and Builtins + +Under Linux, GNU/KFreeBSD and the Hurd, C extensions now include the +architecture triplet in the extension name, to make it easy to test builds +for different ABIs in the same working tree. Under OS X, the extension name +now includes :pep:`3149`-style information. + +.. + +.. bpo: 22631 +.. date: 9108 +.. nonce: nTx_ZF +.. section: Core and Builtins + +Added Linux-specific socket constant CAN_RAW_FD_FRAMES. Patch courtesy of +Joe Jevnik. + +.. + +.. bpo: 23731 +.. date: 9107 +.. nonce: FOXb37 +.. section: Core and Builtins + +Implement :pep:`488`: removal of .pyo files. + +.. + +.. bpo: 23726 +.. date: 9106 +.. nonce: ZopTQ0 +.. section: Core and Builtins + +Don't enable GC for user subclasses of non-GC types that don't add any new +fields. Patch by Eugene Toder. + +.. + +.. bpo: 23309 +.. date: 9105 +.. nonce: Wfnsnz +.. section: Core and Builtins + +Avoid a deadlock at shutdown if a daemon thread is aborted while it is +holding a lock to a buffered I/O object, and the main thread tries to use +the same I/O object (typically stdout or stderr). A fatal error is emitted +instead. + +.. + +.. bpo: 22977 +.. date: 9104 +.. nonce: hutEse +.. section: Core and Builtins + +Fixed formatting Windows error messages on Wine. Patch by Martin Panter. + +.. + +.. bpo: 23466 +.. date: 9103 +.. nonce: KhMltK +.. section: Core and Builtins + +%c, %o, %x, and %X in bytes formatting now raise TypeError on non-integer +input. + +.. + +.. bpo: 24044 +.. date: 9102 +.. nonce: H7vb6- +.. section: Core and Builtins + +Fix possible null pointer dereference in list.sort in out of memory +conditions. + +.. + +.. bpo: 21354 +.. date: 9101 +.. nonce: ZZTe1E +.. section: Core and Builtins + +PyCFunction_New function is exposed by python DLL again. + +.. + +.. bpo: 23840 +.. date: 9100 +.. nonce: mtSbqO +.. section: Library + +tokenize.open() now closes the temporary binary file on error to fix a +resource warning. + +.. + +.. bpo: 16914 +.. date: 9099 +.. nonce: GrP2Jr +.. section: Library + +new debuglevel 2 in smtplib adds timestamps to debug output. + +.. + +.. bpo: 7159 +.. date: 9098 +.. nonce: KCgOUm +.. section: Library + +urllib.request now supports sending auth credentials automatically after the +first 401. This enhancement is a superset of the enhancement from issue +#19494 and supersedes that change. + +.. + +.. bpo: 23703 +.. date: 9097 +.. nonce: kYybxm +.. section: Library + +Fix a regression in urljoin() introduced in 901e4e52b20a. Patch by Demian +Brecht. + +.. + +.. bpo: 4254 +.. date: 9096 +.. nonce: eUC_2H +.. section: Library + +Adds _curses.update_lines_cols(). Patch by Arnon Yaari + +.. + +.. bpo: 19933 +.. date: 9095 +.. nonce: Qq8utk +.. section: Library + +Provide default argument for ndigits in round. Patch by Vajrasky Kok. + +.. + +.. bpo: 23193 +.. date: 9094 +.. nonce: n5ahcG +.. section: Library + +Add a numeric_owner parameter to tarfile.TarFile.extract and +tarfile.TarFile.extractall. Patch by Michael Vogt and Eric Smith. + +.. + +.. bpo: 23342 +.. date: 9093 +.. nonce: CbSzYI +.. section: Library + +Add a subprocess.run() function than returns a CalledProcess instance for a +more consistent API than the existing call* functions. + +.. + +.. bpo: 21217 +.. date: 9092 +.. nonce: TkFTlk +.. section: Library + +inspect.getsourcelines() now tries to compute the start and end lines from +the code object, fixing an issue when a lambda function is used as decorator +argument. Patch by Thomas Ballinger and Allison Kaptur. + +.. + +.. bpo: 24521 +.. date: 9091 +.. nonce: bn4U-y +.. section: Library + +Fix possible integer overflows in the pickle module. + +.. + +.. bpo: 22931 +.. date: 9090 +.. nonce: 4CuWYD +.. section: Library + +Allow '[' and ']' in cookie values. + +.. + +.. bpo: 0 +.. date: 9089 +.. nonce: fgX8Qe +.. section: Library + +The keywords attribute of functools.partial is now always a dictionary. + +.. + +.. bpo: 23811 +.. date: 9088 +.. nonce: B6tzf9 +.. section: Library + +Add missing newline to the PyCompileError error message. Patch by Alex +Shkop. + +.. + +.. bpo: 21116 +.. date: 9087 +.. nonce: Orft3K +.. section: Library + +Avoid blowing memory when allocating a multiprocessing shared array that's +larger than 50% of the available RAM. Patch by Médéric Boquien. + +.. + +.. bpo: 22982 +.. date: 9086 +.. nonce: xYmG62 +.. section: Library + +Improve BOM handling when seeking to multiple positions of a writable text +file. + +.. + +.. bpo: 23464 +.. date: 9085 +.. nonce: _XGkBk +.. section: Library + +Removed deprecated asyncio JoinableQueue. + +.. + +.. bpo: 23529 +.. date: 9084 +.. nonce: Hr7AHH +.. section: Library + +Limit the size of decompressed data when reading from GzipFile, BZ2File or +LZMAFile. This defeats denial of service attacks using compressed bombs +(i.e. compressed payloads which decompress to a huge size). Patch by Martin +Panter and Nikolaus Rath. + +.. + +.. bpo: 21859 +.. date: 9083 +.. nonce: GYrUNP +.. section: Library + +Added Python implementation of io.FileIO. + +.. + +.. bpo: 23865 +.. date: 9082 +.. nonce: PtSLgU +.. section: Library + +close() methods in multiple modules now are idempotent and more robust at +shutdown. If they need to release multiple resources, all are released even +if errors occur. + +.. + +.. bpo: 23400 +.. date: 9081 +.. nonce: JSh9Z3 +.. section: Library + +Raise same exception on both Python 2 and 3 if sem_open is not available. +Patch by Davin Potts. + +.. + +.. bpo: 10838 +.. date: 9080 +.. nonce: p9tSPC +.. section: Library + +The subprocess now module includes SubprocessError and TimeoutError in its +list of exported names for the users wild enough to use ``from subprocess +import *``. + +.. + +.. bpo: 23411 +.. date: 9079 +.. nonce: 0im3Qw +.. section: Library + +Added DefragResult, ParseResult, SplitResult, DefragResultBytes, +ParseResultBytes, and SplitResultBytes to urllib.parse.__all__. Patch by +Martin Panter. + +.. + +.. bpo: 23881 +.. date: 9078 +.. nonce: yZjl4b +.. section: Library + +urllib.request.ftpwrapper constructor now closes the socket if the FTP +connection failed to fix a ResourceWarning. + +.. + +.. bpo: 23853 +.. date: 9077 +.. nonce: mNY1eI +.. section: Library + +:meth:`socket.socket.sendall` does no more reset the socket timeout each +time data is sent successfully. The socket timeout is now the maximum total +duration to send all data. + +.. + +.. bpo: 22721 +.. date: 9076 +.. nonce: MVfBL9 +.. section: Library + +An order of multiline pprint output of set or dict containing orderable and +non-orderable elements no longer depends on iteration order of set or dict. + +.. + +.. bpo: 15133 +.. date: 9075 +.. nonce: C0QfV8 +.. section: Library + +_tkinter.tkapp.getboolean() now supports Tcl_Obj and always returns bool. +tkinter.BooleanVar now validates input values (accepted bool, int, str, and +Tcl_Obj). tkinter.BooleanVar.get() now always returns bool. + +.. + +.. bpo: 10590 +.. date: 9074 +.. nonce: nkxXfU +.. section: Library + +xml.sax.parseString() now supports string argument. + +.. + +.. bpo: 23338 +.. date: 9073 +.. nonce: ZYMGN1 +.. section: Library + +Fixed formatting ctypes error messages on Cygwin. Patch by Makoto Kato. + +.. + +.. bpo: 15582 +.. date: 9072 +.. nonce: 26wJNk +.. section: Library + +inspect.getdoc() now follows inheritance chains. + +.. + +.. bpo: 2175 +.. date: 9071 +.. nonce: cHiVOp +.. section: Library + +SAX parsers now support a character stream of InputSource object. + +.. + +.. bpo: 16840 +.. date: 9070 +.. nonce: kKIhPm +.. section: Library + +Tkinter now supports 64-bit integers added in Tcl 8.4 and arbitrary +precision integers added in Tcl 8.5. + +.. + +.. bpo: 23834 +.. date: 9069 +.. nonce: fX3TF4 +.. section: Library + +Fix socket.sendto(), use the C Py_ssize_t type to store the result of +sendto() instead of the C int type. + +.. + +.. bpo: 23618 +.. date: 9068 +.. nonce: Of_q5t +.. section: Library + +:meth:`socket.socket.connect` now waits until the connection completes +instead of raising :exc:`InterruptedError` if the connection is interrupted +by signals, signal handlers don't raise an exception and the socket is +blocking or has a timeout. :meth:`socket.socket.connect` still raise +:exc:`InterruptedError` for non-blocking sockets. + +.. + +.. bpo: 21526 +.. date: 9067 +.. nonce: QQEXrR +.. section: Library + +Tkinter now supports new boolean type in Tcl 8.5. + +.. + +.. bpo: 23836 +.. date: 9066 +.. nonce: zrEmlR +.. section: Library + +Fix the faulthandler module to handle reentrant calls to its signal +handlers. + +.. + +.. bpo: 23838 +.. date: 9065 +.. nonce: IX6FPX +.. section: Library + +linecache now clears the cache and returns an empty result on MemoryError. + +.. + +.. bpo: 10395 +.. date: 9064 +.. nonce: fi_lZp +.. section: Library + +Added os.path.commonpath(). Implemented in posixpath and ntpath. Based on +patch by Rafik Draoui. + +.. + +.. bpo: 23611 +.. date: 9063 +.. nonce: QkBJVB +.. section: Library + +Serializing more "lookupable" objects (such as unbound methods or nested +classes) now are supported with pickle protocols < 4. + +.. + +.. bpo: 13583 +.. date: 9062 +.. nonce: -MPBjZ +.. section: Library + +sqlite3.Row now supports slice indexing. + +.. + +.. bpo: 18473 +.. date: 9061 +.. nonce: 89RHm- +.. section: Library + +Fixed 2to3 and 3to2 compatible pickle mappings. Fixed ambiguous reverse +mappings. Added many new mappings. Import mapping is no longer applied to +modules already mapped with full name mapping. + +.. + +.. bpo: 23485 +.. date: 9060 +.. nonce: kQWN6L +.. section: Library + +select.select() is now retried automatically with the recomputed timeout +when interrupted by a signal, except if the signal handler raises an +exception. This change is part of the :pep:`475`. + +.. + +.. bpo: 23752 +.. date: 9059 +.. nonce: 5fbVNb +.. section: Library + +When built from an existing file descriptor, io.FileIO() now only calls +fstat() once. Before fstat() was called twice, which was not necessary. + +.. + +.. bpo: 23704 +.. date: 9058 +.. nonce: Ggjvm8 +.. section: Library + +collections.deque() objects now support __add__, __mul__, and __imul__(). + +.. + +.. bpo: 23171 +.. date: 9057 +.. nonce: b6PBzM +.. section: Library + +csv.Writer.writerow() now supports arbitrary iterables. + +.. + +.. bpo: 23745 +.. date: 9056 +.. nonce: E00Bml +.. section: Library + +The new email header parser now handles duplicate MIME parameter names +without error, similar to how get_param behaves. + +.. + +.. bpo: 22117 +.. date: 9055 +.. nonce: bTO0xx +.. section: Library + +Fix os.utime(), it now rounds the timestamp towards minus infinity (-inf) +instead of rounding towards zero. + +.. + +.. bpo: 23310 +.. date: 9054 +.. nonce: GXmFMR +.. section: Library + +Fix MagicMock's initializer to work with __methods__, just like +configure_mock(). Patch by Kasia Jachim. + +.. + +.. bpo: 23817 +.. date: 9053 +.. nonce: DTmVan +.. section: Build + +FreeBSD now uses "1.0" in the SOVERSION as other operating systems, instead +of just "1". + +.. + +.. bpo: 23501 +.. date: 9052 +.. nonce: iz10e6 +.. section: Build + +Argument Clinic now generates code into separate files by default. + +.. + +.. bpo: 23799 +.. date: 9051 +.. nonce: XU2xDw +.. section: Tests + +Added test.support.start_threads() for running and cleaning up multiple +threads. + +.. + +.. bpo: 22390 +.. date: 9050 +.. nonce: UPVFnq +.. section: Tests + +test.regrtest now emits a warning if temporary files or directories are left +after running a test. + +.. + +.. bpo: 18128 +.. date: 9049 +.. nonce: lx2V5a +.. section: Tools/Demos + +pygettext now uses standard +NNNN format in the POT-Creation-Date header. + +.. + +.. bpo: 23935 +.. date: 9048 +.. nonce: JSYowT +.. section: Tools/Demos + +Argument Clinic's understanding of format units accepting bytes, bytearrays, +and buffers is now consistent with both the documentation and the +implementation. + +.. + +.. bpo: 23944 +.. date: 9047 +.. nonce: Q8ZL2s +.. section: Tools/Demos + +Argument Clinic now wraps long impl prototypes at column 78. + +.. + +.. bpo: 20586 +.. date: 9046 +.. nonce: 7BiEkx +.. section: Tools/Demos + +Argument Clinic now ensures that functions without docstrings have +signatures. + +.. + +.. bpo: 23492 +.. date: 9045 +.. nonce: kjIcQW +.. section: Tools/Demos + +Argument Clinic now generates argument parsing code with PyArg_Parse instead +of PyArg_ParseTuple if possible. + +.. + +.. bpo: 23500 +.. date: 9044 +.. nonce: H6_dX_ +.. section: Tools/Demos + +Argument Clinic is now smarter about generating the "#ifndef" (empty) +definition of the methoddef macro: it's only generated once, even if +Argument Clinic processes the same symbol multiple times, and it's emitted +at the end of all processing rather than immediately after the first use. + +.. + +.. bpo: 23998 +.. date: 9043 +.. nonce: z7mlLW +.. section: C API + +PyImport_ReInitLock() now checks for lock allocation error diff --git a/Misc/NEWS.d/3.5.0b1.rst b/Misc/NEWS.d/3.5.0b1.rst new file mode 100644 index 00000000..edecd79f --- /dev/null +++ b/Misc/NEWS.d/3.5.0b1.rst @@ -0,0 +1,848 @@ +.. bpo: 24276 +.. date: 9197 +.. nonce: awsxJJ +.. release date: 2015-05-24 +.. section: Core and Builtins + +Fixed optimization of property descriptor getter. + +.. + +.. bpo: 24268 +.. date: 9196 +.. nonce: nS7uea +.. section: Core and Builtins + +PEP 489: Multi-phase extension module initialization. Patch by Petr +Viktorin. + +.. + +.. bpo: 23955 +.. date: 9195 +.. nonce: hBHSaU +.. section: Core and Builtins + +Add pyvenv.cfg option to suppress registry/environment lookup for generating +sys.path on Windows. + +.. + +.. bpo: 24257 +.. date: 9194 +.. nonce: UBxshR +.. section: Core and Builtins + +Fixed system error in the comparison of faked types.SimpleNamespace. + +.. + +.. bpo: 22939 +.. date: 9193 +.. nonce: DWA9ls +.. section: Core and Builtins + +Fixed integer overflow in iterator object. Patch by Clement Rouault. + +.. + +.. bpo: 23985 +.. date: 9192 +.. nonce: eezPxO +.. section: Core and Builtins + +Fix a possible buffer overrun when deleting a slice from the front of a +bytearray and then appending some other bytes data. + +.. + +.. bpo: 24102 +.. date: 9191 +.. nonce: 9T6h3m +.. section: Core and Builtins + +Fixed exception type checking in standard error handlers. + +.. + +.. bpo: 15027 +.. date: 9190 +.. nonce: wi9sCd +.. section: Core and Builtins + +The UTF-32 encoder is now 3x to 7x faster. + +.. + +.. bpo: 23290 +.. date: 9189 +.. nonce: 57aqLU +.. section: Core and Builtins + +Optimize set_merge() for cases where the target is empty. (Contributed by +Serhiy Storchaka.) + +.. + +.. bpo: 2292 +.. date: 9188 +.. nonce: h4sibO +.. section: Core and Builtins + +PEP 448: Additional Unpacking Generalizations. + +.. + +.. bpo: 24096 +.. date: 9187 +.. nonce: a_Rap7 +.. section: Core and Builtins + +Make warnings.warn_explicit more robust against mutation of the +warnings.filters list. + +.. + +.. bpo: 23996 +.. date: 9186 +.. nonce: znqcT8 +.. section: Core and Builtins + +Avoid a crash when a delegated generator raises an unnormalized +StopIteration exception. Patch by Stefan Behnel. + +.. + +.. bpo: 23910 +.. date: 9185 +.. nonce: _gDzaj +.. section: Core and Builtins + +Optimize property() getter calls. Patch by Joe Jevnik. + +.. + +.. bpo: 23911 +.. date: 9184 +.. nonce: 0FnTHk +.. section: Core and Builtins + +Move path-based importlib bootstrap code to a separate frozen module. + +.. + +.. bpo: 24192 +.. date: 9183 +.. nonce: 6ZxJ_R +.. section: Core and Builtins + +Fix namespace package imports. + +.. + +.. bpo: 24022 +.. date: 9182 +.. nonce: 1l8YBm +.. section: Core and Builtins + +Fix tokenizer crash when processing undecodable source code. + +.. + +.. bpo: 9951 +.. date: 9181 +.. nonce: wGztNC +.. section: Core and Builtins + +Added a hex() method to bytes, bytearray, and memoryview. + +.. + +.. bpo: 22906 +.. date: 9180 +.. nonce: WN_kQ6 +.. section: Core and Builtins + +PEP 479: Change StopIteration handling inside generators. + +.. + +.. bpo: 24017 +.. date: 9179 +.. nonce: QJa1SC +.. section: Core and Builtins + +PEP 492: Coroutines with async and await syntax. + +.. + +.. bpo: 14373 +.. date: 9178 +.. nonce: 0sk6kE +.. section: Library + +Added C implementation of functools.lru_cache(). Based on patches by Matt +Joiner and Alexey Kachayev. + +.. + +.. bpo: 24230 +.. date: 9177 +.. nonce: b-kgme +.. section: Library + +The tempfile module now accepts bytes for prefix, suffix and dir parameters +and returns bytes in such situations (matching the os module APIs). + +.. + +.. bpo: 22189 +.. date: 9176 +.. nonce: 8epgat +.. section: Library + +collections.UserString now supports __getnewargs__(), __rmod__(), +casefold(), format_map(), isprintable(), and maketrans(). Patch by Joe +Jevnik. + +.. + +.. bpo: 24244 +.. date: 9175 +.. nonce: OKE_3R +.. section: Library + +Prevents termination when an invalid format string is encountered on Windows +in strftime. + +.. + +.. bpo: 23973 +.. date: 9174 +.. nonce: EK6awi +.. section: Library + +PEP 484: Add the typing module. + +.. + +.. bpo: 23086 +.. date: 9173 +.. nonce: Aix6Nv +.. section: Library + +The collections.abc.Sequence() abstract base class added *start* and *stop* +parameters to the index() mixin. Patch by Devin Jeanpierre. + +.. + +.. bpo: 20035 +.. date: 9172 +.. nonce: UNZzw6 +.. section: Library + +Replaced the ``tkinter._fix`` module used for setting up the Tcl/Tk +environment on Windows with a private function in the ``_tkinter`` module +that makes no permanent changes to the environment. + +.. + +.. bpo: 24257 +.. date: 9171 +.. nonce: L_efq0 +.. section: Library + +Fixed segmentation fault in sqlite3.Row constructor with faked cursor type. + +.. + +.. bpo: 15836 +.. date: 9170 +.. nonce: gU3Rmx +.. section: Library + +assertRaises(), assertRaisesRegex(), assertWarns() and assertWarnsRegex() +assertments now check the type of the first argument to prevent possible +user error. Based on patch by Daniel Wagner-Hall. + +.. + +.. bpo: 9858 +.. date: 9169 +.. nonce: uke9pa +.. section: Library + +Add missing method stubs to _io.RawIOBase. Patch by Laura Rupprecht. + +.. + +.. bpo: 22955 +.. date: 9168 +.. nonce: Jw_B9_ +.. section: Library + +attrgetter, itemgetter and methodcaller objects in the operator module now +support pickling. Added readable and evaluable repr for these objects. +Based on patch by Josh Rosenberg. + +.. + +.. bpo: 22107 +.. date: 9167 +.. nonce: 2F8k4W +.. section: Library + +tempfile.gettempdir() and tempfile.mkdtemp() now try again when a directory +with the chosen name already exists on Windows as well as on Unix. +tempfile.mkstemp() now fails early if parent directory is not valid (not +exists or is a file) on Windows. + +.. + +.. bpo: 23780 +.. date: 9166 +.. nonce: jFPVcN +.. section: Library + +Improved error message in os.path.join() with single argument. + +.. + +.. bpo: 6598 +.. date: 9165 +.. nonce: JdZNDt +.. section: Library + +Increased time precision and random number range in email.utils.make_msgid() +to strengthen the uniqueness of the message ID. + +.. + +.. bpo: 24091 +.. date: 9164 +.. nonce: Jw0-wj +.. section: Library + +Fixed various crashes in corner cases in C implementation of ElementTree. + +.. + +.. bpo: 21931 +.. date: 9163 +.. nonce: t6lGxY +.. section: Library + +msilib.FCICreate() now raises TypeError in the case of a bad argument +instead of a ValueError with a bogus FCI error number. Patch by Jeffrey +Armstrong. + +.. + +.. bpo: 13866 +.. date: 9162 +.. nonce: n5NAj0 +.. section: Library + +*quote_via* argument added to urllib.parse.urlencode. + +.. + +.. bpo: 20098 +.. date: 9161 +.. nonce: Y4otaf +.. section: Library + +New mangle_from policy option for email, default True for compat32, but +False for all other policies. + +.. + +.. bpo: 24211 +.. date: 9160 +.. nonce: j3Afpc +.. section: Library + +The email library now supports RFC 6532: it can generate headers using utf-8 +instead of encoded words. + +.. + +.. bpo: 16314 +.. date: 9159 +.. nonce: Xc4d1O +.. section: Library + +Added support for the LZMA compression in distutils. + +.. + +.. bpo: 21804 +.. date: 9158 +.. nonce: lEhTlc +.. section: Library + +poplib now supports RFC 6856 (UTF8). + +.. + +.. bpo: 18682 +.. date: 9157 +.. nonce: 6Pnfte +.. section: Library + +Optimized pprint functions for builtin scalar types. + +.. + +.. bpo: 22027 +.. date: 9156 +.. nonce: _aeUQS +.. section: Library + +smtplib now supports RFC 6531 (SMTPUTF8). + +.. + +.. bpo: 23488 +.. date: 9155 +.. nonce: 7gs3Cm +.. section: Library + +Random generator objects now consume 2x less memory on 64-bit. + +.. + +.. bpo: 1322 +.. date: 9154 +.. nonce: 495nFL +.. section: Library + +platform.dist() and platform.linux_distribution() functions are now +deprecated. Initial patch by Vajrasky Kok. + +.. + +.. bpo: 22486 +.. date: 9153 +.. nonce: Yxov5m +.. section: Library + +Added the math.gcd() function. The fractions.gcd() function now is +deprecated. Based on patch by Mark Dickinson. + +.. + +.. bpo: 24064 +.. date: 9152 +.. nonce: zXC7OL +.. section: Library + +Property() docstrings are now writeable. (Patch by Berker Peksag.) + +.. + +.. bpo: 22681 +.. date: 9151 +.. nonce: 2rIoA2 +.. section: Library + +Added support for the koi8_t encoding. + +.. + +.. bpo: 22682 +.. date: 9150 +.. nonce: cP4i3L +.. section: Library + +Added support for the kz1048 encoding. + +.. + +.. bpo: 23796 +.. date: 9149 +.. nonce: JJmUnc +.. section: Library + +peek and read1 methods of BufferedReader now raise ValueError if they called +on a closed object. Patch by John Hergenroeder. + +.. + +.. bpo: 21795 +.. date: 9148 +.. nonce: BDLMS4 +.. section: Library + +smtpd now supports the 8BITMIME extension whenever the new *decode_data* +constructor argument is set to False. + +.. + +.. bpo: 24155 +.. date: 9147 +.. nonce: FZx5c2 +.. section: Library + +optimize heapq.heapify() for better cache performance when heapifying large +lists. + +.. + +.. bpo: 21800 +.. date: 9146 +.. nonce: evGSKc +.. section: Library + +imaplib now supports RFC 5161 (enable), RFC 6855 (utf8/internationalized +email) and automatically encodes non-ASCII usernames and passwords to UTF8. + +.. + +.. bpo: 20274 +.. date: 9145 +.. nonce: uVHogg +.. section: Library + +When calling a _sqlite.Connection, it now complains if passed any keyword +arguments. Previously it silently ignored them. + +.. + +.. bpo: 20274 +.. date: 9144 +.. nonce: hBst4M +.. section: Library + +Remove ignored and erroneous "kwargs" parameters from three METH_VARARGS +methods on _sqlite.Connection. + +.. + +.. bpo: 24134 +.. date: 9143 +.. nonce: Ajw0S- +.. section: Library + +assertRaises(), assertRaisesRegex(), assertWarns() and assertWarnsRegex() +checks now emits a deprecation warning when callable is None or keyword +arguments except msg is passed in the context manager mode. + +.. + +.. bpo: 24018 +.. date: 9142 +.. nonce: hk7Rcn +.. section: Library + +Add a collections.abc.Generator abstract base class. Contributed by Stefan +Behnel. + +.. + +.. bpo: 23880 +.. date: 9141 +.. nonce: QtKupC +.. section: Library + +Tkinter's getint() and getdouble() now support Tcl_Obj. Tkinter's +getdouble() now supports any numbers (in particular int). + +.. + +.. bpo: 22619 +.. date: 9140 +.. nonce: 1gJEqV +.. section: Library + +Added negative limit support in the traceback module. Based on patch by +Dmitry Kazakov. + +.. + +.. bpo: 24094 +.. date: 9139 +.. nonce: 7T-u7k +.. section: Library + +Fix possible crash in json.encode with poorly behaved dict subclasses. + +.. + +.. bpo: 9246 +.. date: 9138 +.. nonce: oM-Ikk +.. section: Library + +On POSIX, os.getcwd() now supports paths longer than 1025 bytes. Patch +written by William Orr. + +.. + +.. bpo: 17445 +.. date: 9137 +.. nonce: Z-QYh5 +.. section: Library + +add difflib.diff_bytes() to support comparison of byte strings (fixes a +regression from Python 2). + +.. + +.. bpo: 23917 +.. date: 9136 +.. nonce: uMVPV7 +.. section: Library + +Fall back to sequential compilation when ProcessPoolExecutor doesn't exist. +Patch by Claudiu Popa. + +.. + +.. bpo: 23008 +.. date: 9135 +.. nonce: OZFCd- +.. section: Library + +Fixed resolving attributes with boolean value is False in pydoc. + +.. + +.. bpo: 0 +.. date: 9134 +.. nonce: 6tJNf2 +.. section: Library + +Fix asyncio issue 235: LifoQueue and PriorityQueue's put didn't increment +unfinished tasks (this bug was introduced when JoinableQueue was merged with +Queue). + +.. + +.. bpo: 23908 +.. date: 9133 +.. nonce: ATdNG- +.. section: Library + +os functions now reject paths with embedded null character on Windows +instead of silently truncating them. + +.. + +.. bpo: 23728 +.. date: 9132 +.. nonce: YBmQmV +.. section: Library + +binascii.crc_hqx() could return an integer outside of the range 0-0xffff for +empty data. + +.. + +.. bpo: 23887 +.. date: 9131 +.. nonce: _XpjPN +.. section: Library + +urllib.error.HTTPError now has a proper repr() representation. Patch by +Berker Peksag. + +.. + +.. bpo: 0 +.. date: 9130 +.. nonce: MjNdSC +.. section: Library + +asyncio: New event loop APIs: set_task_factory() and get_task_factory(). + +.. + +.. bpo: 0 +.. date: 9129 +.. nonce: rVcHXp +.. section: Library + +asyncio: async() function is deprecated in favour of ensure_future(). + +.. + +.. bpo: 24178 +.. date: 9128 +.. nonce: -enO4y +.. section: Library + +asyncio.Lock, Condition, Semaphore, and BoundedSemaphore support new 'async +with' syntax. Contributed by Yury Selivanov. + +.. + +.. bpo: 24179 +.. date: 9127 +.. nonce: wDy_WZ +.. section: Library + +Support 'async for' for asyncio.StreamReader. Contributed by Yury Selivanov. + +.. + +.. bpo: 24184 +.. date: 9126 +.. nonce: El74TU +.. section: Library + +Add AsyncIterator and AsyncIterable ABCs to collections.abc. Contributed by +Yury Selivanov. + +.. + +.. bpo: 22547 +.. date: 9125 +.. nonce: _ikCaj +.. section: Library + +Implement informative __repr__ for inspect.BoundArguments. Contributed by +Yury Selivanov. + +.. + +.. bpo: 24190 +.. date: 9124 +.. nonce: 1a3vWW +.. section: Library + +Implement inspect.BoundArgument.apply_defaults() method. Contributed by Yury +Selivanov. + +.. + +.. bpo: 20691 +.. date: 9123 +.. nonce: -raLyf +.. section: Library + +Add 'follow_wrapped' argument to inspect.Signature.from_callable() and +inspect.signature(). Contributed by Yury Selivanov. + +.. + +.. bpo: 24248 +.. date: 9122 +.. nonce: IxWooo +.. section: Library + +Deprecate inspect.Signature.from_function() and +inspect.Signature.from_builtin(). + +.. + +.. bpo: 23898 +.. date: 9121 +.. nonce: OSiZie +.. section: Library + +Fix inspect.classify_class_attrs() to support attributes with overloaded +__eq__ and __bool__. Patch by Mike Bayer. + +.. + +.. bpo: 24298 +.. date: 9120 +.. nonce: u_TaxI +.. section: Library + +Fix inspect.signature() to correctly unwrap wrappers around bound methods. + +.. + +.. bpo: 23184 +.. date: 9119 +.. nonce: G_Cp9v +.. section: IDLE + +remove unused names and imports in idlelib. Initial patch by Al Sweigart. + +.. + +.. bpo: 21520 +.. date: 9118 +.. nonce: FKtvmQ +.. section: Tests + +test_zipfile no longer fails if the word 'bad' appears anywhere in the name +of the current directory. + +.. + +.. bpo: 9517 +.. date: 9117 +.. nonce: W0Ag2V +.. section: Tests + +Move script_helper into the support package. Patch by Christie Wilson. + +.. + +.. bpo: 22155 +.. date: 9116 +.. nonce: 9EbOit +.. section: Documentation + +Add File Handlers subsection with createfilehandler to tkinter doc. Remove +obsolete example from FAQ. Patch by Martin Panter. + +.. + +.. bpo: 24029 +.. date: 9115 +.. nonce: M2Bnks +.. section: Documentation + +Document the name binding behavior for submodule imports. + +.. + +.. bpo: 24077 +.. date: 9114 +.. nonce: 2Og2j- +.. section: Documentation + +Fix typo in man page for -I command option: -s, not -S + +.. + +.. bpo: 24000 +.. date: 9113 +.. nonce: MJyXRr +.. section: Tools/Demos + +Improved Argument Clinic's mapping of converters to legacy "format units". +Updated the documentation to match. + +.. + +.. bpo: 24001 +.. date: 9112 +.. nonce: m74vst +.. section: Tools/Demos + +Argument Clinic converters now use accept={type} instead of types={'type'} +to specify the types the converter accepts. + +.. + +.. bpo: 23330 +.. date: 9111 +.. nonce: LTlKDp +.. section: Tools/Demos + +h2py now supports arbitrary filenames in #include. + +.. + +.. bpo: 24031 +.. date: 9110 +.. nonce: duGo88 +.. section: Tools/Demos + +make patchcheck now supports git checkouts, too. diff --git a/Misc/NEWS.d/3.5.0b2.rst b/Misc/NEWS.d/3.5.0b2.rst new file mode 100644 index 00000000..43bf4a8b --- /dev/null +++ b/Misc/NEWS.d/3.5.0b2.rst @@ -0,0 +1,104 @@ +.. bpo: 24284 +.. date: 9208 +.. nonce: NvtEnc +.. release date: 2015-05-31 +.. section: Core and Builtins + +The startswith and endswith methods of the str class no longer return True +when finding the empty string and the indexes are completely out of range. + +.. + +.. bpo: 24115 +.. date: 9207 +.. nonce: y9e_MO +.. section: Core and Builtins + +Update uses of PyObject_IsTrue(), PyObject_Not(), PyObject_IsInstance(), +PyObject_RichCompareBool() and _PyDict_Contains() to check for and handle +errors correctly. + +.. + +.. bpo: 24328 +.. date: 9206 +.. nonce: 5gL8or +.. section: Core and Builtins + +Fix importing one character extension modules. + +.. + +.. bpo: 11205 +.. date: 9205 +.. nonce: bikrRP +.. section: Core and Builtins + +In dictionary displays, evaluate the key before the value. + +.. + +.. bpo: 24285 +.. date: 9204 +.. nonce: wvJumr +.. section: Core and Builtins + +Fixed regression that prevented importing extension modules from inside +packages. Patch by Petr Viktorin. + +.. + +.. bpo: 23247 +.. date: 9203 +.. nonce: nN-K74 +.. section: Library + +Fix a crash in the StreamWriter.reset() of CJK codecs. + +.. + +.. bpo: 24270 +.. date: 9202 +.. nonce: M2rJNs +.. section: Library + +Add math.isclose() and cmath.isclose() functions as per :pep:`485`. Contributed +by Chris Barker and Tal Einat. + +.. + +.. bpo: 5633 +.. date: 9201 +.. nonce: JNzKZq +.. section: Library + +Fixed timeit when the statement is a string and the setup is not. + +.. + +.. bpo: 24326 +.. date: 9200 +.. nonce: 4t_6Gy +.. section: Library + +Fixed audioop.ratecv() with non-default weightB argument. Original patch by +David Moore. + +.. + +.. bpo: 16991 +.. date: 9199 +.. nonce: 19_Zmj +.. section: Library + +Add a C implementation of OrderedDict. + +.. + +.. bpo: 23934 +.. date: 9198 +.. nonce: esb-45 +.. section: Library + +Fix inspect.signature to fail correctly for builtin types lacking signature +information. Initial patch by James Powell. diff --git a/Misc/NEWS.d/3.5.0b3.rst b/Misc/NEWS.d/3.5.0b3.rst new file mode 100644 index 00000000..742814b7 --- /dev/null +++ b/Misc/NEWS.d/3.5.0b3.rst @@ -0,0 +1,273 @@ +.. bpo: 24467 +.. date: 9236 +.. nonce: BAJ80- +.. release date: 2015-07-05 +.. section: Core and Builtins + +Fixed possible buffer over-read in bytearray. The bytearray object now +always allocates place for trailing null byte and it's buffer now is always +null-terminated. + +.. + +.. bpo: 0 +.. date: 9235 +.. nonce: 944IUY +.. section: Core and Builtins + +Upgrade to Unicode 8.0.0. + +.. + +.. bpo: 24345 +.. date: 9234 +.. nonce: fVcTaB +.. section: Core and Builtins + +Add Py_tp_finalize slot for the stable ABI. + +.. + +.. bpo: 24400 +.. date: 9233 +.. nonce: 2mNeD8 +.. section: Core and Builtins + +Introduce a distinct type for :pep:`492` coroutines; add types.CoroutineType, +inspect.getcoroutinestate, inspect.getcoroutinelocals; coroutines no longer +use CO_GENERATOR flag; sys.set_coroutine_wrapper works only for 'async def' +coroutines; inspect.iscoroutine no longer uses collections.abc.Coroutine, +it's intended to test for pure 'async def' coroutines only; add new opcode: +GET_YIELD_FROM_ITER; fix generators wrapper used in types.coroutine to be +instance of collections.abc.Generator; collections.abc.Awaitable and +collections.abc.Coroutine can no longer be used to detect generator-based +coroutines--use inspect.isawaitable instead. + +.. + +.. bpo: 24450 +.. date: 9232 +.. nonce: lF0S5c +.. section: Core and Builtins + +Add gi_yieldfrom to generators and cr_await to coroutines. Contributed by +Benno Leslie and Yury Selivanov. + +.. + +.. bpo: 19235 +.. date: 9231 +.. nonce: 0kW4n5 +.. section: Core and Builtins + +Add new RecursionError exception. Patch by Georg Brandl. + +.. + +.. bpo: 21750 +.. date: 9230 +.. nonce: _Ycvgi +.. section: Library + +mock_open.read_data can now be read from each instance, as it could in +Python 3.3. + +.. + +.. bpo: 24552 +.. date: 9229 +.. nonce: VTO6sf +.. section: Library + +Fix use after free in an error case of the _pickle module. + +.. + +.. bpo: 24514 +.. date: 9228 +.. nonce: _xRb2r +.. section: Library + +tarfile now tolerates number fields consisting of only whitespace. + +.. + +.. bpo: 19176 +.. date: 9227 +.. nonce: 8V6nOK +.. section: Library + +Fixed doctype() related bugs in C implementation of ElementTree. A +deprecation warning no longer issued by XMLParser subclass with default +doctype() method. Direct call of doctype() now issues a warning. Parser's +doctype() now is not called if target's doctype() is called. Based on patch +by Martin Panter. + +.. + +.. bpo: 20387 +.. date: 9226 +.. nonce: aAbWbQ +.. section: Library + +Restore semantic round-trip correctness in tokenize/untokenize for +tab-indented blocks. + +.. + +.. bpo: 24456 +.. date: 9225 +.. nonce: yYSd2u +.. section: Library + +Fixed possible buffer over-read in adpcm2lin() and lin2adpcm() functions of +the audioop module. + +.. + +.. bpo: 24336 +.. date: 9224 +.. nonce: 4a5y1m +.. section: Library + +The contextmanager decorator now works with functions with keyword arguments +called "func" and "self". Patch by Martin Panter. + +.. + +.. bpo: 24522 +.. date: 9223 +.. nonce: PkcqCA +.. section: Library + +Fix possible integer overflow in json accelerator module. + +.. + +.. bpo: 24489 +.. date: 9222 +.. nonce: GJnMcW +.. section: Library + +ensure a previously set C errno doesn't disturb cmath.polar(). + +.. + +.. bpo: 24408 +.. date: 9221 +.. nonce: vPb5UK +.. section: Library + +Fixed AttributeError in measure() and metrics() methods of tkinter.Font. + +.. + +.. bpo: 14373 +.. date: 9220 +.. nonce: CTYZ4J +.. section: Library + +C implementation of functools.lru_cache() now can be used with methods. + +.. + +.. bpo: 24347 +.. date: 9219 +.. nonce: CPPDb8 +.. section: Library + +Set KeyError if PyDict_GetItemWithError returns NULL. + +.. + +.. bpo: 24348 +.. date: 9218 +.. nonce: U11rhr +.. section: Library + +Drop superfluous incref/decref. + +.. + +.. bpo: 24359 +.. date: 9217 +.. nonce: -IRNG9 +.. section: Library + +Check for changed OrderedDict size during iteration. + +.. + +.. bpo: 24368 +.. date: 9216 +.. nonce: 550kDT +.. section: Library + +Support keyword arguments in OrderedDict methods. + +.. + +.. bpo: 24362 +.. date: 9215 +.. nonce: cHYce5 +.. section: Library + +Simplify the C OrderedDict fast nodes resize logic. + +.. + +.. bpo: 24377 +.. date: 9214 +.. nonce: Gp1Bqr +.. section: Library + +Fix a ref leak in OrderedDict.__repr__. + +.. + +.. bpo: 24369 +.. date: 9213 +.. nonce: qFl7lZ +.. section: Library + +Defend against key-changes during iteration. + +.. + +.. bpo: 24373 +.. date: 9212 +.. nonce: 6TL2XG +.. section: Tests + +_testmultiphase and xxlimited now use tp_traverse and tp_finalize to avoid +reference leaks encountered when combining tp_dealloc with PyType_FromSpec +(see issue #16690 for details) + +.. + +.. bpo: 24458 +.. date: 9211 +.. nonce: 1egApX +.. section: Documentation + +Update documentation to cover multi-phase initialization for extension +modules (PEP 489). Patch by Petr Viktorin. + +.. + +.. bpo: 24351 +.. date: 9210 +.. nonce: XeSVl5 +.. section: Documentation + +Clarify what is meant by "identifier" in the context of string.Template +instances. + +.. + +.. bpo: 24432 +.. date: 9209 +.. nonce: IvUSiN +.. section: Build + +Update Windows builds and OS X 10.5 installer to use OpenSSL 1.0.2c. diff --git a/Misc/NEWS.d/3.5.0b4.rst b/Misc/NEWS.d/3.5.0b4.rst new file mode 100644 index 00000000..2b1b98a4 --- /dev/null +++ b/Misc/NEWS.d/3.5.0b4.rst @@ -0,0 +1,255 @@ +.. bpo: 23573 +.. date: 9263 +.. nonce: HdJPs7 +.. release date: 2015-07-26 +.. section: Core and Builtins + +Restored optimization of bytes.rfind() and bytearray.rfind() for single-byte +argument on Linux. + +.. + +.. bpo: 24569 +.. date: 9262 +.. nonce: bqh6PQ +.. section: Core and Builtins + +Make :pep:`448` dictionary evaluation more consistent. + +.. + +.. bpo: 24583 +.. date: 9261 +.. nonce: Ooq0Tn +.. section: Core and Builtins + +Fix crash when set is mutated while being updated. + +.. + +.. bpo: 24407 +.. date: 9260 +.. nonce: GmCBB3 +.. section: Core and Builtins + +Fix crash when dict is mutated while being updated. + +.. + +.. bpo: 24619 +.. date: 9259 +.. nonce: cnfZGo +.. section: Core and Builtins + +New approach for tokenizing async/await. As a consequence, it is now +possible to have one-line 'async def foo(): await ..' functions. + +.. + +.. bpo: 24687 +.. date: 9258 +.. nonce: 0UaXFe +.. section: Core and Builtins + +Plug refleak on SyntaxError in function parameters annotations. + +.. + +.. bpo: 15944 +.. date: 9257 +.. nonce: 4GuwqX +.. section: Core and Builtins + +memoryview: Allow arbitrary formats when casting to bytes. Patch by Martin +Panter. + +.. + +.. bpo: 23441 +.. date: 9256 +.. nonce: JXt2Yt +.. section: Library + +rcompleter now prints a tab character instead of displaying possible +completions for an empty word. Initial patch by Martin Sekera. + +.. + +.. bpo: 24683 +.. date: 9255 +.. nonce: aJdWEv +.. section: Library + +Fixed crashes in _json functions called with arguments of inappropriate +type. + +.. + +.. bpo: 21697 +.. date: 9254 +.. nonce: jpATha +.. section: Library + +shutil.copytree() now correctly handles symbolic links that point to +directories. Patch by Eduardo Seabra and Thomas Kluyver. + +.. + +.. bpo: 14373 +.. date: 9253 +.. nonce: Je0yDg +.. section: Library + +Fixed segmentation fault when gc.collect() is called during constructing +lru_cache (C implementation). + +.. + +.. bpo: 24695 +.. date: 9252 +.. nonce: QjZzFb +.. section: Library + +Fix a regression in traceback.print_exception(). If exc_traceback is None +we shouldn't print a traceback header like described in the documentation. + +.. + +.. bpo: 24620 +.. date: 9251 +.. nonce: rrnxB- +.. section: Library + +Random.setstate() now validates the value of state last element. + +.. + +.. bpo: 22485 +.. date: 9250 +.. nonce: HvJf6T +.. section: Library + +Fixed an issue that caused `inspect.getsource` to return incorrect results +on nested functions. + +.. + +.. bpo: 22153 +.. date: 9249 +.. nonce: 6n6yld +.. section: Library + +Improve unittest docs. Patch from Martin Panter and evilzero. + +.. + +.. bpo: 24580 +.. date: 9248 +.. nonce: AGi4Gm +.. section: Library + +Symbolic group references to open group in re patterns now are explicitly +forbidden as well as numeric group references. + +.. + +.. bpo: 24206 +.. date: 9247 +.. nonce: ffkVHH +.. section: Library + +Fixed __eq__ and __ne__ methods of inspect classes. + +.. + +.. bpo: 24631 +.. date: 9246 +.. nonce: uljPxM +.. section: Library + +Fixed regression in the timeit module with multiline setup. + +.. + +.. bpo: 18622 +.. date: 9245 +.. nonce: i6nCCW +.. section: Library + +unittest.mock.mock_open().reset_mock would recurse infinitely. Patch from +Nicola Palumbo and Laurent De Buyst. + +.. + +.. bpo: 23661 +.. date: 9244 +.. nonce: 5VHJmh +.. section: Library + +unittest.mock side_effects can now be exceptions again. This was a +regression vs Python 3.4. Patch from Ignacio Rossi + +.. + +.. bpo: 24608 +.. date: 9243 +.. nonce: 0TndL0 +.. section: Library + +chunk.Chunk.read() now always returns bytes, not str. + +.. + +.. bpo: 18684 +.. date: 9242 +.. nonce: S2es0F +.. section: Library + +Fixed reading out of the buffer in the re module. + +.. + +.. bpo: 24259 +.. date: 9241 +.. nonce: vMAi1A +.. section: Library + +tarfile now raises a ReadError if an archive is truncated inside a data +segment. + +.. + +.. bpo: 15014 +.. date: 9240 +.. nonce: hwXwCH +.. section: Library + +SMTP.auth() and SMTP.login() now support RFC 4954's optional +initial-response argument to the SMTP AUTH command. + +.. + +.. bpo: 24669 +.. date: 9239 +.. nonce: kFThK0 +.. section: Library + +Fix inspect.getsource() for 'async def' functions. Patch by Kai Groner. + +.. + +.. bpo: 24688 +.. date: 9238 +.. nonce: -yWfcO +.. section: Library + +ast.get_docstring() for 'async def' functions. + +.. + +.. bpo: 24603 +.. date: 9237 +.. nonce: PyHyF5 +.. section: Build + +Update Windows builds and OS X 10.5 installer to use OpenSSL 1.0.2d. diff --git a/Misc/NEWS.d/3.5.0rc1.rst b/Misc/NEWS.d/3.5.0rc1.rst new file mode 100644 index 00000000..64e9435b --- /dev/null +++ b/Misc/NEWS.d/3.5.0rc1.rst @@ -0,0 +1,241 @@ +.. bpo: 24667 +.. date: 9288 +.. nonce: tdwszf +.. release date: 2015-08-09 +.. section: Core and Builtins + +Resize odict in all cases that the underlying dict resizes. + +.. + +.. bpo: 24824 +.. date: 9287 +.. nonce: Eoc4lq +.. section: Library + +Signatures of codecs.encode() and codecs.decode() now are compatible with +pydoc. + +.. + +.. bpo: 24634 +.. date: 9286 +.. nonce: 7bnVgr +.. section: Library + +Importing uuid should not try to load libc on Windows + +.. + +.. bpo: 24798 +.. date: 9285 +.. nonce: zDXL5R +.. section: Library + +_msvccompiler.py doesn't properly support manifests + +.. + +.. bpo: 4395 +.. date: 9284 +.. nonce: JpT0k7 +.. section: Library + +Better testing and documentation of binary operators. Patch by Martin +Panter. + +.. + +.. bpo: 23973 +.. date: 9283 +.. nonce: wT59Vh +.. section: Library + +Update typing.py from GitHub repo. + +.. + +.. bpo: 23004 +.. date: 9282 +.. nonce: xswcPm +.. section: Library + +mock_open() now reads binary data correctly when the type of read_data is +bytes. Initial patch by Aaron Hill. + +.. + +.. bpo: 23888 +.. date: 9281 +.. nonce: 7gw4oO +.. section: Library + +Handle fractional time in cookie expiry. Patch by ssh. + +.. + +.. bpo: 23652 +.. date: 9280 +.. nonce: DKQ_7t +.. section: Library + +Make it possible to compile the select module against the libc headers from +the Linux Standard Base, which do not include some EPOLL macros. Patch by +Matt Frank. + +.. + +.. bpo: 22932 +.. date: 9279 +.. nonce: mPclSJ +.. section: Library + +Fix timezones in email.utils.formatdate. Patch from Dmitry Shachnev. + +.. + +.. bpo: 23779 +.. date: 9278 +.. nonce: ET4JJP +.. section: Library + +imaplib raises TypeError if authenticator tries to abort. Patch from Craig +Holmquist. + +.. + +.. bpo: 23319 +.. date: 9277 +.. nonce: FXyUH- +.. section: Library + +Fix ctypes.BigEndianStructure, swap correctly bytes. Patch written by +Matthieu Gautier. + +.. + +.. bpo: 23254 +.. date: 9276 +.. nonce: zNiy1X +.. section: Library + +Document how to close the TCPServer listening socket. Patch from Martin +Panter. + +.. + +.. bpo: 19450 +.. date: 9275 +.. nonce: VG7T-L +.. section: Library + +Update Windows and OS X installer builds to use SQLite 3.8.11. + +.. + +.. bpo: 17527 +.. date: 9274 +.. nonce: ve9fyw +.. section: Library + +Add PATCH to wsgiref.validator. Patch from Luca Sbardella. + +.. + +.. bpo: 24791 +.. date: 9273 +.. nonce: Ok-3nA +.. section: Library + +Fix grammar regression for call syntax: 'g(\*a or b)'. + +.. + +.. bpo: 23672 +.. date: 9272 +.. nonce: 8td2se +.. section: IDLE + +Allow Idle to edit and run files with astral chars in name. Patch by Mohd +Sanad Zaki Rizvi. + +.. + +.. bpo: 24745 +.. date: 9271 +.. nonce: edbziT +.. section: IDLE + +Idle editor default font. Switch from Courier to platform-sensitive +TkFixedFont. This should not affect current customized font selections. If +there is a problem, edit $HOME/.idlerc/config-main.cfg and remove ':samp:`font{xxx}`' +entries from [Editor Window]. Patch by Mark Roseman. + +.. + +.. bpo: 21192 +.. date: 9270 +.. nonce: CdbipH +.. section: IDLE + +Idle editor. When a file is run, put its name in the restart bar. Do not +print false prompts. Original patch by Adnan Umer. + +.. + +.. bpo: 13884 +.. date: 9269 +.. nonce: vVcO1E +.. section: IDLE + +Idle menus. Remove tearoff lines. Patch by Roger Serwy. + +.. + +.. bpo: 24129 +.. date: 9268 +.. nonce: Imr54z +.. section: Documentation + +Clarify the reference documentation for name resolution. This includes +removing the assumption that readers will be familiar with the name +resolution scheme Python used prior to the introduction of lexical scoping +for function namespaces. Patch by Ivan Levkivskyi. + +.. + +.. bpo: 20769 +.. date: 9267 +.. nonce: ZUc9z9 +.. section: Documentation + +Improve reload() docs. Patch by Dorian Pula. + +.. + +.. bpo: 23589 +.. date: 9266 +.. nonce: rjU421 +.. section: Documentation + +Remove duplicate sentence from the FAQ. Patch by Yongzhi Pan. + +.. + +.. bpo: 24729 +.. date: 9265 +.. nonce: PH3A9p +.. section: Documentation + +Correct IO tutorial to match implementation regarding encoding parameter to +open function. + +.. + +.. bpo: 24751 +.. date: 9264 +.. nonce: pL2pbj +.. section: Tests + +When running regrtest with the ``-w`` command line option, a test run is no +longer marked as a failure if all tests succeed when re-run. diff --git a/Misc/NEWS.d/3.5.0rc2.rst b/Misc/NEWS.d/3.5.0rc2.rst new file mode 100644 index 00000000..2a8a52a1 --- /dev/null +++ b/Misc/NEWS.d/3.5.0rc2.rst @@ -0,0 +1,56 @@ +.. bpo: 24769 +.. date: 9294 +.. nonce: XgRA0n +.. release date: 2015-08-25 +.. section: Core and Builtins + +Interpreter now starts properly when dynamic loading is disabled. Patch by +Petr Viktorin. + +.. + +.. bpo: 21167 +.. date: 9293 +.. nonce: uom-Dq +.. section: Core and Builtins + +NAN operations are now handled correctly when python is compiled with ICC +even if -fp-model strict is not specified. + +.. + +.. bpo: 24492 +.. date: 9292 +.. nonce: LKDAIu +.. section: Core and Builtins + +A "package" lacking a __name__ attribute when trying to perform a ``from .. +import ...`` statement will trigger an ImportError instead of an +AttributeError. + +.. + +.. bpo: 24847 +.. date: 9291 +.. nonce: SHiiO_ +.. section: Library + +Removes vcruntime140.dll dependency from Tcl/Tk. + +.. + +.. bpo: 24839 +.. date: 9290 +.. nonce: 7_iQZl +.. section: Library + +platform._syscmd_ver raises DeprecationWarning + +.. + +.. bpo: 24867 +.. date: 9289 +.. nonce: rxJIl7 +.. section: Library + +Fix Task.get_stack() for 'async def' coroutines diff --git a/Misc/NEWS.d/3.5.0rc3.rst b/Misc/NEWS.d/3.5.0rc3.rst new file mode 100644 index 00000000..2f770a01 --- /dev/null +++ b/Misc/NEWS.d/3.5.0rc3.rst @@ -0,0 +1,76 @@ +.. bpo: 24305 +.. date: 9302 +.. nonce: QeF4A8 +.. release date: 2015-09-07 +.. section: Core and Builtins + +Prevent import subsystem stack frames from being counted by the +warnings.warn(stacklevel=) parameter. + +.. + +.. bpo: 24912 +.. date: 9301 +.. nonce: ubSi5J +.. section: Core and Builtins + +Prevent __class__ assignment to immutable built-in objects. + +.. + +.. bpo: 24975 +.. date: 9300 +.. nonce: 2gLdfN +.. section: Core and Builtins + +Fix AST compilation for :pep:`448` syntax. + +.. + +.. bpo: 24917 +.. date: 9299 +.. nonce: xaQocz +.. section: Library + +time_strftime() buffer over-read. + +.. + +.. bpo: 24748 +.. date: 9298 +.. nonce: 83NuO8 +.. section: Library + +To resolve a compatibility problem found with py2exe and pywin32, +imp.load_dynamic() once again ignores previously loaded modules to support +Python modules replacing themselves with extension modules. Patch by Petr +Viktorin. + +.. + +.. bpo: 24635 +.. date: 9297 +.. nonce: EiJPPf +.. section: Library + +Fixed a bug in typing.py where isinstance([], typing.Iterable) would return +True once, then False on subsequent calls. + +.. + +.. bpo: 24989 +.. date: 9296 +.. nonce: 9BJLiy +.. section: Library + +Fixed buffer overread in BytesIO.readline() if a position is set beyond +size. Based on patch by John Leitch. + +.. + +.. bpo: 24913 +.. date: 9295 +.. nonce: p2ZAJ4 +.. section: Library + +Fix overrun error in deque.index(). Found by John Leitch and Bryce Darling. diff --git a/Misc/NEWS.d/3.5.0rc4.rst b/Misc/NEWS.d/3.5.0rc4.rst new file mode 100644 index 00000000..a6d9454f --- /dev/null +++ b/Misc/NEWS.d/3.5.0rc4.rst @@ -0,0 +1,17 @@ +.. bpo: 25029 +.. date: 9304 +.. nonce: Zf97rk +.. release date: 2015-09-09 +.. section: Library + +Fixes MemoryError in test_strptime. + +.. + +.. bpo: 25027 +.. date: 9303 +.. nonce: Zaib78 +.. section: Build + +Reverts partial-static build options and adds vcruntime140.dll to Windows +installation. diff --git a/Misc/NEWS.d/3.5.1.rst b/Misc/NEWS.d/3.5.1.rst new file mode 100644 index 00000000..45df6f9b --- /dev/null +++ b/Misc/NEWS.d/3.5.1.rst @@ -0,0 +1,17 @@ +.. bpo: 25709 +.. date: 9452 +.. nonce: OPX2TS +.. release date: 2015-12-06 +.. section: Core and Builtins + +Fixed problem with in-place string concatenation and utf-8 cache. + +.. + +.. bpo: 25715 +.. date: 9451 +.. nonce: 3LLYLj +.. section: Windows + +Python 3.5.1 installer shows wrong upgrade path and incorrect logic for +launcher detection. diff --git a/Misc/NEWS.d/3.5.1rc1.rst b/Misc/NEWS.d/3.5.1rc1.rst new file mode 100644 index 00000000..05e1ecfa --- /dev/null +++ b/Misc/NEWS.d/3.5.1rc1.rst @@ -0,0 +1,1451 @@ +.. bpo: 25630 +.. date: 9450 +.. nonce: ZxzcoY +.. release date: 2015-11-22 +.. section: Core and Builtins + +Fix a possible segfault during argument parsing in functions that accept +filesystem paths. + +.. + +.. bpo: 23564 +.. date: 9449 +.. nonce: XHarGG +.. section: Core and Builtins + +Fixed a partially broken sanity check in the _posixsubprocess internals +regarding how fds_to_pass were passed to the child. The bug had no actual +impact as subprocess.py already avoided it. + +.. + +.. bpo: 25388 +.. date: 9448 +.. nonce: zm3uuQ +.. section: Core and Builtins + +Fixed tokenizer crash when processing undecodable source code with a null +byte. + +.. + +.. bpo: 25462 +.. date: 9447 +.. nonce: eXDzgO +.. section: Core and Builtins + +The hash of the key now is calculated only once in most operations in C +implementation of OrderedDict. + +.. + +.. bpo: 22995 +.. date: 9446 +.. nonce: 90kpuP +.. section: Core and Builtins + +Default implementation of __reduce__ and __reduce_ex__ now rejects builtin +types with not defined __new__. + +.. + +.. bpo: 25555 +.. date: 9445 +.. nonce: MUpG-j +.. section: Core and Builtins + +Fix parser and AST: fill lineno and col_offset of "arg" node when compiling +AST from Python objects. + +.. + +.. bpo: 24802 +.. date: 9444 +.. nonce: Qie066 +.. section: Core and Builtins + +Avoid buffer overreads when int(), float(), compile(), exec() and eval() are +passed bytes-like objects. These objects are not necessarily terminated by +a null byte, but the functions assumed they were. + +.. + +.. bpo: 24726 +.. date: 9443 +.. nonce: AHk4v2 +.. section: Core and Builtins + +Fixed a crash and leaking NULL in repr() of OrderedDict that was mutated by +direct calls of dict methods. + +.. + +.. bpo: 25449 +.. date: 9442 +.. nonce: VqTOFi +.. section: Core and Builtins + +Iterating OrderedDict with keys with unstable hash now raises KeyError in C +implementations as well as in Python implementation. + +.. + +.. bpo: 25395 +.. date: 9441 +.. nonce: htkE3W +.. section: Core and Builtins + +Fixed crash when highly nested OrderedDict structures were garbage +collected. + +.. + +.. bpo: 25274 +.. date: 9440 +.. nonce: QCGvAF +.. section: Core and Builtins + +sys.setrecursionlimit() now raises a RecursionError if the new recursion +limit is too low depending at the current recursion depth. Modify also the +"lower-water mark" formula to make it monotonic. This mark is used to decide +when the overflowed flag of the thread state is reset. + +.. + +.. bpo: 24402 +.. date: 9439 +.. nonce: MAgi3X +.. section: Core and Builtins + +Fix input() to prompt to the redirected stdout when sys.stdout.fileno() +fails. + +.. + +.. bpo: 24806 +.. date: 9438 +.. nonce: Nb0znT +.. section: Core and Builtins + +Prevent builtin types that are not allowed to be subclassed from being +subclassed through multiple inheritance. + +.. + +.. bpo: 24848 +.. date: 9437 +.. nonce: HlUSuy +.. section: Core and Builtins + +Fixed a number of bugs in UTF-7 decoding of misformed data. + +.. + +.. bpo: 25280 +.. date: 9436 +.. nonce: ivTMwd +.. section: Core and Builtins + +Import trace messages emitted in verbose (-v) mode are no longer formatted +twice. + +.. + +.. bpo: 25003 +.. date: 9435 +.. nonce: _ban92 +.. section: Core and Builtins + +On Solaris 11.3 or newer, os.urandom() now uses the getrandom() function +instead of the getentropy() function. The getentropy() function is blocking +to generate very good quality entropy, os.urandom() doesn't need such +high-quality entropy. + +.. + +.. bpo: 25182 +.. date: 9434 +.. nonce: gBDq-T +.. section: Core and Builtins + +The stdprinter (used as sys.stderr before the io module is imported at +startup) now uses the backslashreplace error handler. + +.. + +.. bpo: 25131 +.. date: 9433 +.. nonce: j5hH6a +.. section: Core and Builtins + +Make the line number and column offset of set/dict literals and +comprehensions correspond to the opening brace. + +.. + +.. bpo: 25150 +.. date: 9432 +.. nonce: 0Gh-Ty +.. section: Core and Builtins + +Hide the private :samp:`_Py_atomic_{xxx}` symbols from the public Python.h header to +fix a compilation error with OpenMP. PyThreadState_GET() becomes an alias to +PyThreadState_Get() to avoid ABI incompatibilities. + +.. + +.. bpo: 25626 +.. date: 9431 +.. nonce: TQ3fvb +.. section: Library + +Change three zlib functions to accept sizes that fit in Py_ssize_t, but +internally cap those sizes to UINT_MAX. This resolves a regression in 3.5 +where GzipFile.read() failed to read chunks larger than 2 or 4 GiB. The +change affects the zlib.Decompress.decompress() max_length parameter, the +zlib.decompress() bufsize parameter, and the zlib.Decompress.flush() length +parameter. + +.. + +.. bpo: 25583 +.. date: 9430 +.. nonce: Gk-cim +.. section: Library + +Avoid incorrect errors raised by os.makedirs(exist_ok=True) when the OS +gives priority to errors such as EACCES over EEXIST. + +.. + +.. bpo: 25593 +.. date: 9429 +.. nonce: 56uegI +.. section: Library + +Change semantics of EventLoop.stop() in asyncio. + +.. + +.. bpo: 6973 +.. date: 9428 +.. nonce: nl5cHt +.. section: Library + +When we know a subprocess.Popen process has died, do not allow the +send_signal(), terminate(), or kill() methods to do anything as they could +potentially signal a different process. + +.. + +.. bpo: 25590 +.. date: 9427 +.. nonce: aCt-yW +.. section: Library + +In the Readline completer, only call getattr() once per attribute. + +.. + +.. bpo: 25498 +.. date: 9426 +.. nonce: AvqEBl +.. section: Library + +Fix a crash when garbage-collecting ctypes objects created by wrapping a +memoryview. This was a regression made in 3.5a1. Based on patch by +Eryksun. + +.. + +.. bpo: 25584 +.. date: 9425 +.. nonce: 124mYw +.. section: Library + +Added "escape" to the __all__ list in the glob module. + +.. + +.. bpo: 25584 +.. date: 9424 +.. nonce: ZeWX0J +.. section: Library + +Fixed recursive glob() with patterns starting with ``**``. + +.. + +.. bpo: 25446 +.. date: 9423 +.. nonce: k1DByx +.. section: Library + +Fix regression in smtplib's AUTH LOGIN support. + +.. + +.. bpo: 18010 +.. date: 9422 +.. nonce: Azyf1C +.. section: Library + +Fix the pydoc web server's module search function to handle exceptions from +importing packages. + +.. + +.. bpo: 25554 +.. date: 9421 +.. nonce: UM9MlR +.. section: Library + +Got rid of circular references in regular expression parsing. + +.. + +.. bpo: 25510 +.. date: 9420 +.. nonce: 79g7LA +.. section: Library + +fileinput.FileInput.readline() now returns b'' instead of '' at the end if +the FileInput was opened with binary mode. Patch by Ryosuke Ito. + +.. + +.. bpo: 25503 +.. date: 9419 +.. nonce: Zea0Y7 +.. section: Library + +Fixed inspect.getdoc() for inherited docstrings of properties. Original +patch by John Mark Vandenberg. + +.. + +.. bpo: 25515 +.. date: 9418 +.. nonce: fQsyYG +.. section: Library + +Always use os.urandom as a source of randomness in uuid.uuid4. + +.. + +.. bpo: 21827 +.. date: 9417 +.. nonce: k2oreR +.. section: Library + +Fixed textwrap.dedent() for the case when largest common whitespace is a +substring of smallest leading whitespace. Based on patch by Robert Li. + +.. + +.. bpo: 25447 +.. date: 9416 +.. nonce: eDYc4t +.. section: Library + +The lru_cache() wrapper objects now can be copied and pickled (by returning +the original object unchanged). + +.. + +.. bpo: 25390 +.. date: 9415 +.. nonce: 6mSgRq +.. section: Library + +typing: Don't crash on Union[str, Pattern]. + +.. + +.. bpo: 25441 +.. date: 9414 +.. nonce: d7zph6 +.. section: Library + +asyncio: Raise error from drain() when socket is closed. + +.. + +.. bpo: 25410 +.. date: 9413 +.. nonce: QAs_3B +.. section: Library + +Cleaned up and fixed minor bugs in C implementation of OrderedDict. + +.. + +.. bpo: 25411 +.. date: 9412 +.. nonce: qsJTCb +.. section: Library + +Improved Unicode support in SMTPHandler through better use of the email +package. Thanks to user simon04 for the patch. + +.. + +.. bpo: 25407 +.. date: 9411 +.. nonce: ukNt1D +.. section: Library + +Remove mentions of the formatter module being removed in Python 3.6. + +.. + +.. bpo: 25406 +.. date: 9410 +.. nonce: 5MZKU_ +.. section: Library + +Fixed a bug in C implementation of OrderedDict.move_to_end() that caused +segmentation fault or hang in iterating after moving several items to the +start of ordered dict. + +.. + +.. bpo: 25364 +.. date: 9409 +.. nonce: u_1Wi6 +.. section: Library + +zipfile now works in threads disabled builds. + +.. + +.. bpo: 25328 +.. date: 9408 +.. nonce: Rja1Xg +.. section: Library + +smtpd's SMTPChannel now correctly raises a ValueError if both decode_data +and enable_SMTPUTF8 are set to true. + +.. + +.. bpo: 25316 +.. date: 9407 +.. nonce: dHQHWI +.. section: Library + +distutils raises OSError instead of DistutilsPlatformError when MSVC is not +installed. + +.. + +.. bpo: 25380 +.. date: 9406 +.. nonce: sKZ6-I +.. section: Library + +Fixed protocol for the STACK_GLOBAL opcode in pickletools.opcodes. + +.. + +.. bpo: 23972 +.. date: 9405 +.. nonce: s2g30g +.. section: Library + +Updates asyncio datagram create method allowing reuseport and reuseaddr +socket options to be set prior to binding the socket. Mirroring the existing +asyncio create_server method the reuseaddr option for datagram sockets +defaults to True if the O/S is 'posix' (except if the platform is Cygwin). +Patch by Chris Laws. + +.. + +.. bpo: 25304 +.. date: 9404 +.. nonce: CsmLyI +.. section: Library + +Add asyncio.run_coroutine_threadsafe(). This lets you submit a coroutine to +a loop from another thread, returning a concurrent.futures.Future. By +Vincent Michel. + +.. + +.. bpo: 25232 +.. date: 9403 +.. nonce: KhKjCE +.. section: Library + +Fix CGIRequestHandler to split the query from the URL at the first question +mark (?) rather than the last. Patch from Xiang Zhang. + +.. + +.. bpo: 24657 +.. date: 9402 +.. nonce: h2Ag7y +.. section: Library + +Prevent CGIRequestHandler from collapsing slashes in the query part of the +URL as if it were a path. Patch from Xiang Zhang. + +.. + +.. bpo: 24483 +.. date: 9401 +.. nonce: WPLGSJ +.. section: Library + +C implementation of functools.lru_cache() now calculates key's hash only +once. + +.. + +.. bpo: 22958 +.. date: 9400 +.. nonce: Ebu7Gl +.. section: Library + +Constructor and update method of weakref.WeakValueDictionary now accept the +self and the dict keyword arguments. + +.. + +.. bpo: 22609 +.. date: 9399 +.. nonce: fV7hdV +.. section: Library + +Constructor of collections.UserDict now accepts the self keyword argument. + +.. + +.. bpo: 25111 +.. date: 9398 +.. nonce: azL4qE +.. section: Library + +Fixed comparison of traceback.FrameSummary. + +.. + +.. bpo: 25262 +.. date: 9397 +.. nonce: pQS5cB +.. section: Library + +Added support for BINBYTES8 opcode in Python implementation of unpickler. +Highest 32 bits of 64-bit size for BINUNICODE8 and BINBYTES8 opcodes no +longer silently ignored on 32-bit platforms in C implementation. + +.. + +.. bpo: 25034 +.. date: 9396 +.. nonce: eGvOIb +.. section: Library + +Fix string.Formatter problem with auto-numbering and nested format_specs. +Patch by Anthon van der Neut. + +.. + +.. bpo: 25233 +.. date: 9395 +.. nonce: EdZV9x +.. section: Library + +Rewrite the guts of asyncio.Queue and asyncio.Semaphore to be more +understandable and correct. + +.. + +.. bpo: 25203 +.. date: 9394 +.. nonce: IgDEbt +.. section: Library + +Failed readline.set_completer_delims() no longer left the module in +inconsistent state. + +.. + +.. bpo: 23600 +.. date: 9393 +.. nonce: 7J_RD5 +.. section: Library + +Default implementation of tzinfo.fromutc() was returning wrong results in +some cases. + +.. + +.. bpo: 23329 +.. date: 9392 +.. nonce: yccJBE +.. section: Library + +Allow the ssl module to be built with older versions of LibreSSL. + +.. + +.. bpo: 0 +.. date: 9391 +.. nonce: ww9QSm +.. section: Library + +Prevent overflow in _Unpickler_Read. + +.. + +.. bpo: 25047 +.. date: 9390 +.. nonce: kc8tqx +.. section: Library + +The XML encoding declaration written by Element Tree now respects the letter +case given by the user. This restores the ability to write encoding names in +uppercase like "UTF-8", which worked in Python 2. + +.. + +.. bpo: 25135 +.. date: 9389 +.. nonce: gVHNy- +.. section: Library + +Make deque_clear() safer by emptying the deque before clearing. This helps +avoid possible reentrancy issues. + +.. + +.. bpo: 19143 +.. date: 9388 +.. nonce: 76SBSO +.. section: Library + +platform module now reads Windows version from kernel32.dll to avoid +compatibility shims. + +.. + +.. bpo: 25092 +.. date: 9387 +.. nonce: fQ37Ac +.. section: Library + +Fix datetime.strftime() failure when errno was already set to EINVAL. + +.. + +.. bpo: 23517 +.. date: 9386 +.. nonce: 3ABmf1 +.. section: Library + +Fix rounding in fromtimestamp() and utcfromtimestamp() methods of +datetime.datetime: microseconds are now rounded to nearest with ties going +to nearest even integer (ROUND_HALF_EVEN), instead of being rounding towards +minus infinity (ROUND_FLOOR). It's important that these methods use the same +rounding mode than datetime.timedelta to keep the property: +(datetime(1970,1,1) + timedelta(seconds=t)) == datetime.utcfromtimestamp(t). +It also the rounding mode used by round(float) for example. + +.. + +.. bpo: 25155 +.. date: 9385 +.. nonce: JiETzD +.. section: Library + +Fix datetime.datetime.now() and datetime.datetime.utcnow() on Windows to +support date after year 2038. It was a regression introduced in Python +3.5.0. + +.. + +.. bpo: 25108 +.. date: 9384 +.. nonce: zGPbgA +.. section: Library + +Omitted internal frames in traceback functions print_stack(), +format_stack(), and extract_stack() called without arguments. + +.. + +.. bpo: 25118 +.. date: 9383 +.. nonce: wGm1u6 +.. section: Library + +Fix a regression of Python 3.5.0 in os.waitpid() on Windows. + +.. + +.. bpo: 24684 +.. date: 9382 +.. nonce: t4T77O +.. section: Library + +socket.socket.getaddrinfo() now calls PyUnicode_AsEncodedString() instead of +calling the encode() method of the host, to handle correctly custom string +with an encode() method which doesn't return a byte string. The encoder of +the IDNA codec is now called directly instead of calling the encode() method +of the string. + +.. + +.. bpo: 25060 +.. date: 9381 +.. nonce: zLdvIk +.. section: Library + +Correctly compute stack usage of the BUILD_MAP opcode. + +.. + +.. bpo: 24857 +.. date: 9380 +.. nonce: PpJWZ9 +.. section: Library + +Comparing call_args to a long sequence now correctly returns a boolean +result instead of raising an exception. Patch by A Kaptur. + +.. + +.. bpo: 23144 +.. date: 9379 +.. nonce: cLf67X +.. section: Library + +Make sure that HTMLParser.feed() returns all the data, even when +convert_charrefs is True. + +.. + +.. bpo: 24982 +.. date: 9378 +.. nonce: sGMMAR +.. section: Library + +shutil.make_archive() with the "zip" format now adds entries for directories +(including empty directories) in ZIP file. + +.. + +.. bpo: 25019 +.. date: 9377 +.. nonce: JQJlOZ +.. section: Library + +Fixed a crash caused by setting non-string key of expat parser. Based on +patch by John Leitch. + +.. + +.. bpo: 16180 +.. date: 9376 +.. nonce: 6IUcNS +.. section: Library + +Exit pdb if file has syntax error, instead of trapping user in an infinite +loop. Patch by Xavier de Gaye. + +.. + +.. bpo: 24891 +.. date: 9375 +.. nonce: ddVmHS +.. section: Library + +Fix a race condition at Python startup if the file descriptor of stdin (0), +stdout (1) or stderr (2) is closed while Python is creating sys.stdin, +sys.stdout and sys.stderr objects. These attributes are now set to None if +the creation of the object failed, instead of raising an OSError exception. +Initial patch written by Marco Paolini. + +.. + +.. bpo: 24992 +.. date: 9374 +.. nonce: 5sqF74 +.. section: Library + +Fix error handling and a race condition (related to garbage collection) in +collections.OrderedDict constructor. + +.. + +.. bpo: 24881 +.. date: 9373 +.. nonce: ZoVZXu +.. section: Library + +Fixed setting binary mode in Python implementation of FileIO on Windows and +Cygwin. Patch from Akira Li. + +.. + +.. bpo: 25578 +.. date: 9372 +.. nonce: G6S-ft +.. section: Library + +Fix (another) memory leak in SSLSocket.getpeercer(). + +.. + +.. bpo: 25530 +.. date: 9371 +.. nonce: hDFkwu +.. section: Library + +Disable the vulnerable SSLv3 protocol by default when creating +ssl.SSLContext. + +.. + +.. bpo: 25569 +.. date: 9370 +.. nonce: CfvQjK +.. section: Library + +Fix memory leak in SSLSocket.getpeercert(). + +.. + +.. bpo: 25471 +.. date: 9369 +.. nonce: T0A02M +.. section: Library + +Sockets returned from accept() shouldn't appear to be nonblocking. + +.. + +.. bpo: 25319 +.. date: 9368 +.. nonce: iyuglv +.. section: Library + +When threading.Event is reinitialized, the underlying condition should use a +regular lock rather than a recursive lock. + +.. + +.. bpo: 21112 +.. date: 9367 +.. nonce: vSFU1r +.. section: Library + +Fix regression in unittest.expectedFailure on subclasses. Patch from Berker +Peksag. + +.. + +.. bpo: 24764 +.. date: 9366 +.. nonce: QwFZ2S +.. section: Library + +cgi.FieldStorage.read_multi() now ignores the Content-Length header in part +headers. Patch written by Peter Landry and reviewed by Pierre Quentel. + +.. + +.. bpo: 24913 +.. date: 9365 +.. nonce: p2ZAJ4 +.. section: Library + +Fix overrun error in deque.index(). Found by John Leitch and Bryce Darling. + +.. + +.. bpo: 24774 +.. date: 9364 +.. nonce: xLbskG +.. section: Library + +Fix docstring in http.server.test. Patch from Chiu-Hsiang Hsu. + +.. + +.. bpo: 21159 +.. date: 9363 +.. nonce: ochL5W +.. section: Library + +Improve message in configparser.InterpolationMissingOptionError. Patch from +Łukasz Langa. + +.. + +.. bpo: 20362 +.. date: 9362 +.. nonce: 5aP_Ri +.. section: Library + +Honour TestCase.longMessage correctly in assertRegex. Patch from Ilia +Kurenkov. + +.. + +.. bpo: 23572 +.. date: 9361 +.. nonce: QhQ9RD +.. section: Library + +Fixed functools.singledispatch on classes with false metaclasses. Patch by +Ethan Furman. + +.. + +.. bpo: 0 +.. date: 9360 +.. nonce: DO1sFa +.. section: Library + +asyncio: ensure_future() now accepts awaitable objects. + +.. + +.. bpo: 15348 +.. date: 9359 +.. nonce: d1Fg01 +.. section: IDLE + +Stop the debugger engine (normally in a user process) before closing the +debugger window (running in the IDLE process). This prevents the +RuntimeErrors that were being caught and ignored. + +.. + +.. bpo: 24455 +.. date: 9358 +.. nonce: x6YqtE +.. section: IDLE + +Prevent IDLE from hanging when a) closing the shell while the debugger is +active (15347); b) closing the debugger with the [X] button (15348); and c) +activating the debugger when already active (24455). The patch by Mark +Roseman does this by making two changes. 1. Suspend and resume the +gui.interaction method with the tcl vwait mechanism intended for this +purpose (instead of root.mainloop & .quit). 2. In gui.run, allow any +existing interaction to terminate first. + +.. + +.. bpo: 0 +.. date: 9357 +.. nonce: Yp9LRY +.. section: IDLE + +Change 'The program' to 'Your program' in an IDLE 'kill program?' message to +make it clearer that the program referred to is the currently running user +program, not IDLE itself. + +.. + +.. bpo: 24750 +.. date: 9356 +.. nonce: xgsi-K +.. section: IDLE + +Improve the appearance of the IDLE editor window status bar. Patch by Mark +Roseman. + +.. + +.. bpo: 25313 +.. date: 9355 +.. nonce: xMXHpO +.. section: IDLE + +Change the handling of new built-in text color themes to better address the +compatibility problem introduced by the addition of IDLE Dark. Consistently +use the revised idleConf.CurrentTheme everywhere in idlelib. + +.. + +.. bpo: 24782 +.. date: 9354 +.. nonce: RgIPYE +.. section: IDLE + +Extension configuration is now a tab in the IDLE Preferences dialog rather +than a separate dialog. The former tabs are now a sorted list. Patch by +Mark Roseman. + +.. + +.. bpo: 22726 +.. date: 9353 +.. nonce: x8T0dA +.. section: IDLE + +Re-activate the config dialog help button with some content about the other +buttons and the new IDLE Dark theme. + +.. + +.. bpo: 24820 +.. date: 9352 +.. nonce: TFPJhr +.. section: IDLE + +IDLE now has an 'IDLE Dark' built-in text color theme. It is more or less +IDLE Classic inverted, with a cobalt blue background. Strings, comments, +keywords, ... are still green, red, orange, ... . To use it with IDLEs +released before November 2015, hit the 'Save as New Custom Theme' button and +enter a new name, such as 'Custom Dark'. The custom theme will work with +any IDLE release, and can be modified. + +.. + +.. bpo: 25224 +.. date: 9351 +.. nonce: 5Llwo4 +.. section: IDLE + +README.txt is now an idlelib index for IDLE developers and curious users. +The previous user content is now in the IDLE doc chapter. 'IDLE' now means +'Integrated Development and Learning Environment'. + +.. + +.. bpo: 24820 +.. date: 9350 +.. nonce: ZUz9Fn +.. section: IDLE + +Users can now set breakpoint colors in Settings -> Custom Highlighting. +Original patch by Mark Roseman. + +.. + +.. bpo: 24972 +.. date: 9349 +.. nonce: uc0uNo +.. section: IDLE + +Inactive selection background now matches active selection background, as +configured by users, on all systems. Found items are now always highlighted +on Windows. Initial patch by Mark Roseman. + +.. + +.. bpo: 24570 +.. date: 9348 +.. nonce: s3EkNn +.. section: IDLE + +Idle: make calltip and completion boxes appear on Macs affected by a tk +regression. Initial patch by Mark Roseman. + +.. + +.. bpo: 24988 +.. date: 9347 +.. nonce: tXqq4T +.. section: IDLE + +Idle ScrolledList context menus (used in debugger) now work on Mac Aqua. +Patch by Mark Roseman. + +.. + +.. bpo: 24801 +.. date: 9346 +.. nonce: -bj_Ou +.. section: IDLE + +Make right-click for context menu work on Mac Aqua. Patch by Mark Roseman. + +.. + +.. bpo: 25173 +.. date: 9345 +.. nonce: EZzrPg +.. section: IDLE + +Associate tkinter messageboxes with a specific widget. For Mac OSX, make +them a 'sheet'. Patch by Mark Roseman. + +.. + +.. bpo: 25198 +.. date: 9344 +.. nonce: -j_BV7 +.. section: IDLE + +Enhance the initial html viewer now used for Idle Help. Properly indent +fixed-pitch text (patch by Mark Roseman). Give code snippet a very +Sphinx-like light blueish-gray background. Re-use initial width and height +set by users for shell and editor. When the Table of Contents (TOC) menu is +used, put the section header at the top of the screen. + +.. + +.. bpo: 25225 +.. date: 9343 +.. nonce: 9pvdq6 +.. section: IDLE + +Condense and rewrite Idle doc section on text colors. + +.. + +.. bpo: 21995 +.. date: 9342 +.. nonce: C5Rmzx +.. section: IDLE + +Explain some differences between IDLE and console Python. + +.. + +.. bpo: 22820 +.. date: 9341 +.. nonce: hix_8X +.. section: IDLE + +Explain need for *print* when running file from Idle editor. + +.. + +.. bpo: 25224 +.. date: 9340 +.. nonce: UVMYQq +.. section: IDLE + +Doc: augment Idle feature list and no-subprocess section. + +.. + +.. bpo: 25219 +.. date: 9339 +.. nonce: 8_9DYg +.. section: IDLE + +Update doc for Idle command line options. Some were missing and notes were +not correct. + +.. + +.. bpo: 24861 +.. date: 9338 +.. nonce: Ecg2yT +.. section: IDLE + +Most of idlelib is private and subject to change. Use idleib.idle.* to start +Idle. See idlelib.__init__.__doc__. + +.. + +.. bpo: 25199 +.. date: 9337 +.. nonce: ih7yY3 +.. section: IDLE + +Idle: add synchronization comments for future maintainers. + +.. + +.. bpo: 16893 +.. date: 9336 +.. nonce: bZtPgJ +.. section: IDLE + +Replace help.txt with help.html for Idle doc display. The new +idlelib/help.html is rstripped Doc/build/html/library/idle.html. It looks +better than help.txt and will better document Idle as released. The tkinter +html viewer that works for this file was written by Mark Roseman. The now +unused EditorWindow.HelpDialog class and helt.txt file are deprecated. + +.. + +.. bpo: 24199 +.. date: 9335 +.. nonce: VKnZEv +.. section: IDLE + +Deprecate unused idlelib.idlever with possible removal in 3.6. + +.. + +.. bpo: 24790 +.. date: 9334 +.. nonce: hD1hlj +.. section: IDLE + +Remove extraneous code (which also create 2 & 3 conflicts). + +.. + +.. bpo: 22558 +.. date: 9333 +.. nonce: Pk02YC +.. section: Documentation + +Add remaining doc links to source code for Python-coded modules. Patch by +Yoni Lavi. + +.. + +.. bpo: 12067 +.. date: 9332 +.. nonce: nLD2M- +.. section: Documentation + +Rewrite Comparisons section in the Expressions chapter of the language +reference. Some of the details of comparing mixed types were incorrect or +ambiguous. NotImplemented is only relevant at a lower level than the +Expressions chapter. Added details of comparing range() objects, and default +behaviour and consistency suggestions for user-defined classes. Patch from +Andy Maier. + +.. + +.. bpo: 24952 +.. date: 9331 +.. nonce: RHhFPE +.. section: Documentation + +Clarify the default size argument of stack_size() in the "threading" and +"_thread" modules. Patch from Mattip. + +.. + +.. bpo: 23725 +.. date: 9330 +.. nonce: 49TZ5f +.. section: Documentation + +Overhaul tempfile docs. Note deprecated status of mktemp. Patch from +Zbigniew Jędrzejewski-Szmek. + +.. + +.. bpo: 24808 +.. date: 9329 +.. nonce: MGjc3F +.. section: Documentation + +Update the types of some PyTypeObject fields. Patch by Joseph Weston. + +.. + +.. bpo: 22812 +.. date: 9328 +.. nonce: kLCF0G +.. section: Documentation + +Fix unittest discovery examples. Patch from Pam McA'Nulty. + +.. + +.. bpo: 25449 +.. date: 9327 +.. nonce: MP6KNs +.. section: Tests + +Added tests for OrderedDict subclasses. + +.. + +.. bpo: 25099 +.. date: 9326 +.. nonce: tJQOWx +.. section: Tests + +Make test_compileall not fail when an entry on sys.path cannot be written to +(commonly seen in administrative installs on Windows). + +.. + +.. bpo: 23919 +.. date: 9325 +.. nonce: vJnjaq +.. section: Tests + +Prevents assert dialogs appearing in the test suite. + +.. + +.. bpo: 0 +.. date: 9324 +.. nonce: X-Bk5l +.. section: Tests + +``PCbuild\rt.bat`` now accepts an unlimited number of arguments to pass +along to regrtest.py. Previously there was a limit of 9. + +.. + +.. bpo: 24915 +.. date: 9323 +.. nonce: PgD3Cx +.. section: Build + +Add LLVM support for PGO builds and use the test suite to generate the +profile data. Initial patch by Alecsandru Patrascu of Intel. + +.. + +.. bpo: 24910 +.. date: 9322 +.. nonce: ZZdfl0 +.. section: Build + +Windows MSIs now have unique display names. + +.. + +.. bpo: 24986 +.. date: 9321 +.. nonce: 1WyXeU +.. section: Build + +It is now possible to build Python on Windows without errors when external +libraries are not available. + +.. + +.. bpo: 25450 +.. date: 9320 +.. nonce: X4xlWf +.. section: Windows + +Updates shortcuts to start Python in installation directory. + +.. + +.. bpo: 25164 +.. date: 9319 +.. nonce: FHVOOA +.. section: Windows + +Changes default all-users install directory to match per-user directory. + +.. + +.. bpo: 25143 +.. date: 9318 +.. nonce: hmxsia +.. section: Windows + +Improves installer error messages for unsupported platforms. + +.. + +.. bpo: 25163 +.. date: 9317 +.. nonce: uCRe8H +.. section: Windows + +Display correct directory in installer when using non-default settings. + +.. + +.. bpo: 25361 +.. date: 9316 +.. nonce: GETaSY +.. section: Windows + +Disables use of SSE2 instructions in Windows 32-bit build + +.. + +.. bpo: 25089 +.. date: 9315 +.. nonce: n_YJgw +.. section: Windows + +Adds logging to installer for case where launcher is not selected on +upgrade. + +.. + +.. bpo: 25165 +.. date: 9314 +.. nonce: aUTN1e +.. section: Windows + +Windows uninstallation should not remove launcher if other versions remain + +.. + +.. bpo: 25112 +.. date: 9313 +.. nonce: frdKij +.. section: Windows + +py.exe launcher is missing icons + +.. + +.. bpo: 25102 +.. date: 9312 +.. nonce: 6y6Akl +.. section: Windows + +Windows installer does not precompile for -O or -OO. + +.. + +.. bpo: 25081 +.. date: 9311 +.. nonce: dcRCTO +.. section: Windows + +Makes Back button in installer go back to upgrade page when upgrading. + +.. + +.. bpo: 25091 +.. date: 9310 +.. nonce: 1u-VKy +.. section: Windows + +Increases font size of the installer. + +.. + +.. bpo: 25126 +.. date: 9309 +.. nonce: ANx3DW +.. section: Windows + +Clarifies that the non-web installer will download some components. + +.. + +.. bpo: 25213 +.. date: 9308 +.. nonce: KGmXoe +.. section: Windows + +Restores requestedExecutionLevel to manifest to disable UAC virtualization. + +.. + +.. bpo: 25022 +.. date: 9307 +.. nonce: vAt_zr +.. section: Windows + +Removed very outdated PC/example_nt/ directory. + +.. + +.. bpo: 25440 +.. date: 9306 +.. nonce: 5xhyGr +.. section: Tools/Demos + +Fix output of python-config --extension-suffix. diff --git a/Misc/NEWS.d/3.5.2.rst b/Misc/NEWS.d/3.5.2.rst new file mode 100644 index 00000000..982b2279 --- /dev/null +++ b/Misc/NEWS.d/3.5.2.rst @@ -0,0 +1,25 @@ +.. bpo: 26930 +.. date: 9676 +.. nonce: 9JUeSD +.. release date: 2016-06-26 +.. section: Core and Builtins + +Update Windows builds to use OpenSSL 1.0.2h. + +.. + +.. bpo: 26867 +.. date: 9675 +.. nonce: QPSyP5 +.. section: Tests + +Ubuntu's openssl OP_NO_SSLv3 is forced on by default; fix test. + +.. + +.. bpo: 27365 +.. date: 9674 +.. nonce: ipkJ_M +.. section: IDLE + +Allow non-ascii in idlelib/NEWS.txt - minimal part for 3.5.2. diff --git a/Misc/NEWS.d/3.5.2rc1.rst b/Misc/NEWS.d/3.5.2rc1.rst new file mode 100644 index 00000000..01fcd866 --- /dev/null +++ b/Misc/NEWS.d/3.5.2rc1.rst @@ -0,0 +1,2203 @@ +.. bpo: 26556 +.. date: 9636 +.. nonce: v5j2uL +.. release date: 2016-06-12 +.. original section: Library +.. section: Security + +Update expat to 2.1.1, fixes CVE-2015-1283. + +.. + +.. bpo: 0 +.. date: 9635 +.. nonce: E4ochz +.. original section: Library +.. section: Security + +Fix TLS stripping vulnerability in smtplib, CVE-2016-0772. Reported by Team +Oststrom + +.. + +.. bpo: 26839 +.. date: 9629 +.. nonce: yVvy7R +.. original section: Library +.. section: Security + +On Linux, :func:`os.urandom` now calls ``getrandom()`` with +``GRND_NONBLOCK`` to fall back on reading ``/dev/urandom`` if the urandom +entropy pool is not initialized yet. Patch written by Colm Buckley. + +.. + +.. bpo: 26657 +.. date: 9597 +.. nonce: C_-XFg +.. original section: Library +.. section: Security + +Fix directory traversal vulnerability with http.server on Windows. This +fixes a regression that was introduced in 3.3.4rc1 and 3.4.0rc1. Based on +patch by Philipp Hagemeister. + +.. + +.. bpo: 26313 +.. date: 9581 +.. nonce: LjZAjy +.. original section: Library +.. section: Security + +ssl.py _load_windows_store_certs fails if windows cert store is empty. Patch +by Baji. + +.. + +.. bpo: 25939 +.. date: 9561 +.. nonce: X49Fqd +.. original section: Library +.. section: Security + +On Windows open the cert store readonly in ssl.enum_certificates. + +.. + +.. bpo: 27066 +.. date: 9673 +.. nonce: SNExZi +.. section: Core and Builtins + +Fixed SystemError if a custom opener (for open()) returns a negative number +without setting an exception. + +.. + +.. bpo: 20041 +.. date: 9672 +.. nonce: TypyGp +.. section: Core and Builtins + +Fixed TypeError when frame.f_trace is set to None. Patch by Xavier de Gaye. + +.. + +.. bpo: 26168 +.. date: 9671 +.. nonce: -nPBL6 +.. section: Core and Builtins + +Fixed possible refleaks in failing Py_BuildValue() with the "N" format unit. + +.. + +.. bpo: 26991 +.. date: 9670 +.. nonce: yWGNhz +.. section: Core and Builtins + +Fix possible refleak when creating a function with annotations. + +.. + +.. bpo: 27039 +.. date: 9669 +.. nonce: Zj7tV7 +.. section: Core and Builtins + +Fixed bytearray.remove() for values greater than 127. Patch by Joe Jevnik. + +.. + +.. bpo: 23640 +.. date: 9668 +.. nonce: kvNC4c +.. section: Core and Builtins + +int.from_bytes() no longer bypasses constructors for subclasses. + +.. + +.. bpo: 26811 +.. date: 9667 +.. nonce: oNzUWt +.. section: Core and Builtins + +gc.get_objects() no longer contains a broken tuple with NULL pointer. + +.. + +.. bpo: 20120 +.. date: 9666 +.. nonce: c-FZZc +.. section: Core and Builtins + +Use RawConfigParser for .pypirc parsing, removing support for interpolation +unintentionally added with move to Python 3. Behavior no longer does any +interpolation in .pypirc files, matching behavior in Python 2.7 and +Setuptools 19.0. + +.. + +.. bpo: 26659 +.. date: 9665 +.. nonce: 5PRa83 +.. section: Core and Builtins + +Make the builtin slice type support cycle collection. + +.. + +.. bpo: 26718 +.. date: 9664 +.. nonce: K5PQ8j +.. section: Core and Builtins + +super.__init__ no longer leaks memory if called multiple times. NOTE: A +direct call of super.__init__ is not endorsed! + +.. + +.. bpo: 25339 +.. date: 9663 +.. nonce: ZcaC2E +.. section: Core and Builtins + +PYTHONIOENCODING now has priority over locale in setting the error handler +for stdin and stdout. + +.. + +.. bpo: 26494 +.. date: 9662 +.. nonce: G6eXIi +.. section: Core and Builtins + +Fixed crash on iterating exhausting iterators. Affected classes are generic +sequence iterators, iterators of str, bytes, bytearray, list, tuple, set, +frozenset, dict, OrderedDict, corresponding views and os.scandir() iterator. + +.. + +.. bpo: 26581 +.. date: 9661 +.. nonce: yNA7nm +.. section: Core and Builtins + +If coding cookie is specified multiple times on a line in Python source code +file, only the first one is taken to account. + +.. + +.. bpo: 26464 +.. date: 9660 +.. nonce: 7BreGz +.. section: Core and Builtins + +Fix str.translate() when string is ASCII and first replacements removes +character, but next replacement uses a non-ASCII character or a string +longer than 1 character. Regression introduced in Python 3.5.0. + +.. + +.. bpo: 22836 +.. date: 9659 +.. nonce: cimt1y +.. section: Core and Builtins + +Ensure exception reports from PyErr_Display() and PyErr_WriteUnraisable() +are sensible even when formatting them produces secondary errors. This +affects the reports produced by sys.__excepthook__() and when __del__() +raises an exception. + +.. + +.. bpo: 26302 +.. date: 9658 +.. nonce: UD9XQt +.. section: Core and Builtins + +Correct behavior to reject comma as a legal character for cookie names. + +.. + +.. bpo: 4806 +.. date: 9657 +.. nonce: i9m3hj +.. section: Core and Builtins + +Avoid masking the original TypeError exception when using star (``*``) +unpacking in function calls. Based on patch by Hagen Fürstenau and Daniel +Urban. + +.. + +.. bpo: 27138 +.. date: 9656 +.. nonce: ifYEro +.. section: Core and Builtins + +Fix the doc comment for FileFinder.find_spec(). + +.. + +.. bpo: 26154 +.. date: 9655 +.. nonce: MtnRAH +.. section: Core and Builtins + +Add a new private _PyThreadState_UncheckedGet() function to get the current +Python thread state, but don't issue a fatal error if it is NULL. This new +function must be used instead of accessing directly the +_PyThreadState_Current variable. The variable is no more exposed since +Python 3.5.1 to hide the exact implementation of atomic C types, to avoid +compiler issues. + +.. + +.. bpo: 26194 +.. date: 9654 +.. nonce: j9zand +.. section: Core and Builtins + +Deque.insert() gave odd results for bounded deques that had reached their +maximum size. Now an IndexError will be raised when attempting to insert +into a full deque. + +.. + +.. bpo: 25843 +.. date: 9653 +.. nonce: t2kGug +.. section: Core and Builtins + +When compiling code, don't merge constants if they are equal but have a +different types. For example, ``f1, f2 = lambda: 1, lambda: 1.0`` is now +correctly compiled to two different functions: ``f1()`` returns ``1`` +(``int``) and ``f2()`` returns ``1.0`` (``int``), even if ``1`` and ``1.0`` +are equal. + +.. + +.. bpo: 22995 +.. date: 9652 +.. nonce: KYNKvs +.. section: Core and Builtins + +[UPDATE] Comment out the one of the pickleability tests in +_PyObject_GetState() due to regressions observed in Cython-based projects. + +.. + +.. bpo: 25961 +.. date: 9651 +.. nonce: Hdjjw0 +.. section: Core and Builtins + +Disallowed null characters in the type name. + +.. + +.. bpo: 25973 +.. date: 9650 +.. nonce: Ud__ZP +.. section: Core and Builtins + +Fix segfault when an invalid nonlocal statement binds a name starting with +two underscores. + +.. + +.. bpo: 22995 +.. date: 9649 +.. nonce: Wq0E86 +.. section: Core and Builtins + +Instances of extension types with a state that aren't subclasses of list or +dict and haven't implemented any pickle-related methods (__reduce__, +__reduce_ex__, __getnewargs__, __getnewargs_ex__, or __getstate__), can no +longer be pickled. Including memoryview. + +.. + +.. bpo: 20440 +.. date: 9648 +.. nonce: GCwOfH +.. section: Core and Builtins + +Massive replacing unsafe attribute setting code with special macro +Py_SETREF. + +.. + +.. bpo: 25766 +.. date: 9647 +.. nonce: jn93Yu +.. section: Core and Builtins + +Special method __bytes__() now works in str subclasses. + +.. + +.. bpo: 25421 +.. date: 9646 +.. nonce: c47YEL +.. section: Core and Builtins + +__sizeof__ methods of builtin types now use dynamic basic size. This allows +sys.getsize() to work correctly with their subclasses with __slots__ +defined. + +.. + +.. bpo: 25709 +.. date: 9645 +.. nonce: WwGm2k +.. section: Core and Builtins + +Fixed problem with in-place string concatenation and utf-8 cache. + +.. + +.. bpo: 27147 +.. date: 9644 +.. nonce: tCCgmH +.. section: Core and Builtins + +Mention :pep:`420` in the importlib docs. + +.. + +.. bpo: 24097 +.. date: 9643 +.. nonce: Vt4E-i +.. section: Core and Builtins + +Fixed crash in object.__reduce__() if slot name is freed inside __getattr__. + +.. + +.. bpo: 24731 +.. date: 9642 +.. nonce: h9-hnz +.. section: Core and Builtins + +Fixed crash on converting objects with special methods __bytes__, __trunc__, +and __float__ returning instances of subclasses of bytes, int, and float to +subclasses of bytes, int, and float correspondingly. + +.. + +.. bpo: 26478 +.. date: 9641 +.. nonce: n0dB8e +.. section: Core and Builtins + +Fix semantic bugs when using binary operators with dictionary views and +tuples. + +.. + +.. bpo: 26171 +.. date: 9640 +.. nonce: 8SaQEa +.. section: Core and Builtins + +Fix possible integer overflow and heap corruption in zipimporter.get_data(). + +.. + +.. bpo: 25660 +.. date: 9639 +.. nonce: 93DzBo +.. section: Core and Builtins + +Fix TAB key behaviour in REPL with readline. + +.. + +.. bpo: 25887 +.. date: 9638 +.. nonce: PtVIX7 +.. section: Core and Builtins + +Raise a RuntimeError when a coroutine object is awaited more than once. + +.. + +.. bpo: 27243 +.. date: 9637 +.. nonce: U36M4E +.. section: Core and Builtins + +Update the __aiter__ protocol: instead of returning an awaitable that +resolves to an asynchronous iterator, the asynchronous iterator should be +returned directly. Doing the former will trigger a +PendingDeprecationWarning. + +.. + +.. bpo: 21386 +.. date: 9634 +.. nonce: DjV72U +.. section: Library + +Implement missing IPv4Address.is_global property. It was documented since +07a5610bae9d. Initial patch by Roger Luethi. + +.. + +.. bpo: 20900 +.. date: 9633 +.. nonce: H5YQPR +.. section: Library + +distutils register command now decodes HTTP responses correctly. Initial +patch by ingrid. + +.. + +.. bpo: 0 +.. date: 9632 +.. nonce: iYIeng +.. section: Library + +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). + +.. + +.. bpo: 25738 +.. date: 9631 +.. nonce: mED9w4 +.. section: Library + +Stop http.server.BaseHTTPRequestHandler.send_error() from sending a message +body for 205 Reset Content. Also, don't send Content header fields in +responses that don't have a body. Patch by Susumu Koshiba. + +.. + +.. bpo: 21313 +.. date: 9630 +.. nonce: W30MBr +.. section: Library + +Fix the "platform" module to tolerate when sys.version contains truncated +build information. + +.. + +.. bpo: 27164 +.. date: 9628 +.. nonce: 6wmjx2 +.. section: Library + +In the zlib module, allow decompressing raw Deflate streams with a +predefined zdict. Based on patch by Xiang Zhang. + +.. + +.. bpo: 24291 +.. date: 9627 +.. nonce: Ac6HvL +.. section: Library + +Fix wsgiref.simple_server.WSGIRequestHandler to completely write data to the +client. Previously it could do partial writes and truncate data. Also, +wsgiref.handler.ServerHandler can now handle stdout doing partial writes, +but this is deprecated. + +.. + +.. bpo: 26809 +.. date: 9626 +.. nonce: ya7JMb +.. section: Library + +Add ``__all__`` to :mod:`string`. Patch by Emanuel Barry. + +.. + +.. bpo: 26373 +.. date: 9625 +.. nonce: P6qz6o +.. section: Library + +subprocess.Popen.communicate now correctly ignores BrokenPipeError when the +child process dies before .communicate() is called in more/all +circumstances. + +.. + +.. bpo: 21776 +.. date: 9624 +.. nonce: 04eQfa +.. section: Library + +distutils.upload now correctly handles HTTPError. Initial patch by Claudiu +Popa. + +.. + +.. bpo: 27114 +.. date: 9623 +.. nonce: bGCuAM +.. section: Library + +Fix SSLContext._load_windows_store_certs fails with PermissionError + +.. + +.. bpo: 18383 +.. date: 9622 +.. nonce: jr-b0l +.. section: Library + +Avoid creating duplicate filters when using filterwarnings and simplefilter. +Based on patch by Alex Shkop. + +.. + +.. bpo: 27057 +.. date: 9621 +.. nonce: YzTA_Q +.. section: Library + +Fix os.set_inheritable() on Android, ioctl() is blocked by SELinux and fails +with EACCESS. The function now falls back to fcntl(). Patch written by +Michał Bednarski. + +.. + +.. bpo: 27014 +.. date: 9620 +.. nonce: ui7Khn +.. section: Library + +Fix infinite recursion using typing.py. Thanks to Kalle Tuure! + +.. + +.. bpo: 14132 +.. date: 9619 +.. nonce: 5wR9MN +.. section: Library + +Fix urllib.request redirect handling when the target only has a query +string. Original fix by Ján Janech. + +.. + +.. bpo: 17214 +.. date: 9618 +.. nonce: lUbZOV +.. section: Library + +The "urllib.request" module now percent-encodes non-ASCII bytes found in +redirect target URLs. Some servers send Location header fields with +non-ASCII bytes, but "http.client" requires the request target to be +ASCII-encodable, otherwise a UnicodeEncodeError is raised. Based on patch by +Christian Heimes. + +.. + +.. bpo: 26892 +.. date: 9617 +.. nonce: XIXb0h +.. section: Library + +Honor debuglevel flag in urllib.request.HTTPHandler. Patch contributed by +Chi Hsuan Yen. + +.. + +.. bpo: 22274 +.. date: 9616 +.. nonce: 0RHDMN +.. section: Library + +In the subprocess module, allow stderr to be redirected to stdout even when +stdout is not redirected. Patch by Akira Li. + +.. + +.. bpo: 26807 +.. date: 9615 +.. nonce: LXSPP6 +.. section: Library + +mock_open 'files' no longer error on readline at end of file. Patch from +Yolanda Robla. + +.. + +.. bpo: 25745 +.. date: 9614 +.. nonce: -n8acU +.. section: Library + +Fixed leaking a userptr in curses panel destructor. + +.. + +.. bpo: 26977 +.. date: 9613 +.. nonce: 5G4HtL +.. section: Library + +Removed unnecessary, and ignored, call to sum of squares helper in +statistics.pvariance. + +.. + +.. bpo: 26881 +.. date: 9612 +.. nonce: mdiq_L +.. section: Library + +The modulefinder module now supports extended opcode arguments. + +.. + +.. bpo: 23815 +.. date: 9611 +.. nonce: _krNe8 +.. section: Library + +Fixed crashes related to directly created instances of types in _tkinter and +curses.panel modules. + +.. + +.. bpo: 17765 +.. date: 9610 +.. nonce: hiSVS1 +.. section: Library + +weakref.ref() no longer silently ignores keyword arguments. Patch by Georg +Brandl. + +.. + +.. bpo: 26873 +.. date: 9609 +.. nonce: cYXRcH +.. section: Library + +xmlrpc now raises ResponseError on unsupported type tags instead of silently +return incorrect result. + +.. + +.. bpo: 26711 +.. date: 9608 +.. nonce: Eu85Qw +.. section: Library + +Fixed the comparison of plistlib.Data with other types. + +.. + +.. bpo: 24114 +.. date: 9607 +.. nonce: RMRMtM +.. section: Library + +Fix an uninitialized variable in `ctypes.util`. +The bug only occurs on SunOS when the ctypes implementation searches for the +`crle` program. Patch by Xiang Zhang. Tested on SunOS by Kees Bos. + +.. + +.. bpo: 26864 +.. date: 9606 +.. nonce: 1KgGds +.. section: Library + +In urllib.request, change the proxy bypass host checking against no_proxy to +be case-insensitive, and to not match unrelated host names that happen to +have a bypassed hostname as a suffix. Patch by Xiang Zhang. + +.. + +.. bpo: 26634 +.. date: 9605 +.. nonce: FZvsSb +.. section: Library + +recursive_repr() now sets __qualname__ of wrapper. Patch by Xiang Zhang. + +.. + +.. bpo: 26804 +.. date: 9604 +.. nonce: 9Orp-G +.. section: Library + +urllib.request will prefer lower_case proxy environment variables over +UPPER_CASE or Mixed_Case ones. Patch contributed by Hans-Peter Jansen. + +.. + +.. bpo: 26837 +.. date: 9603 +.. nonce: 2FXGsD +.. section: Library + +assertSequenceEqual() now correctly outputs non-stringified differing items +(like bytes in the -b mode). This affects assertListEqual() and +assertTupleEqual(). + +.. + +.. bpo: 26041 +.. date: 9602 +.. nonce: bVem-p +.. section: Library + +Remove "will be removed in Python 3.7" from deprecation messages of +platform.dist() and platform.linux_distribution(). Patch by Kumaripaba +Miyurusara Athukorala. + +.. + +.. bpo: 26822 +.. date: 9601 +.. nonce: rYSL4W +.. section: Library + +itemgetter, attrgetter and methodcaller objects no longer silently ignore +keyword arguments. + +.. + +.. bpo: 26733 +.. date: 9600 +.. nonce: YxaJmL +.. section: Library + +Disassembling a class now disassembles class and static methods. Patch by +Xiang Zhang. + +.. + +.. bpo: 26801 +.. date: 9599 +.. nonce: TQGY-7 +.. section: Library + +Fix error handling in :func:`shutil.get_terminal_size`, catch +:exc:`AttributeError` instead of :exc:`NameError`. Patch written by Emanuel +Barry. + +.. + +.. bpo: 24838 +.. date: 9598 +.. nonce: 3Pfx8T +.. section: Library + +tarfile's ustar and gnu formats now correctly calculate name and link field +limits for multibyte character encodings like utf-8. + +.. + +.. bpo: 26717 +.. date: 9596 +.. nonce: jngTdu +.. section: Library + +Stop encoding Latin-1-ized WSGI paths with UTF-8. Patch by Anthony Sottile. + +.. + +.. bpo: 26735 +.. date: 9595 +.. nonce: riSl3b +.. section: Library + +Fix :func:`os.urandom` on Solaris 11.3 and newer when reading more than +1,024 bytes: call ``getrandom()`` multiple times with a limit of 1024 bytes +per call. + +.. + +.. bpo: 16329 +.. date: 9594 +.. nonce: nuXD8W +.. section: Library + +Add .webm to mimetypes.types_map. Patch by Giampaolo Rodola'. + +.. + +.. bpo: 13952 +.. date: 9593 +.. nonce: SOoTVE +.. section: Library + +Add .csv to mimetypes.types_map. Patch by Geoff Wilson. + +.. + +.. bpo: 26709 +.. date: 9592 +.. nonce: luOPbP +.. section: Library + +Fixed Y2038 problem in loading binary PLists. + +.. + +.. bpo: 23735 +.. date: 9591 +.. nonce: Y5oQ9r +.. section: Library + +Handle terminal resizing with Readline 6.3+ by installing our own SIGWINCH +handler. Patch by Eric Price. + +.. + +.. bpo: 26586 +.. date: 9590 +.. nonce: V5pZNa +.. section: Library + +In http.server, respond with "413 Request header fields too large" if there +are too many header fields to parse, rather than killing the connection and +raising an unhandled exception. Patch by Xiang Zhang. + +.. + +.. bpo: 22854 +.. date: 9589 +.. nonce: K3rMEH +.. section: Library + +Change BufferedReader.writable() and BufferedWriter.readable() to always +return False. + +.. + +.. bpo: 25195 +.. date: 9588 +.. nonce: EOc4Po +.. section: Library + +Fix a regression in mock.MagicMock. _Call is a subclass of tuple (changeset +3603bae63c13 only works for classes) so we need to implement __ne__ +ourselves. Patch by Andrew Plummer. + +.. + +.. bpo: 26644 +.. date: 9587 +.. nonce: 7tt1tk +.. section: Library + +Raise ValueError rather than SystemError when a negative length is passed to +SSLSocket.recv() or read(). + +.. + +.. bpo: 23804 +.. date: 9586 +.. nonce: PP63Ff +.. section: Library + +Fix SSL recv(0) and read(0) methods to return zero bytes instead of up to +1024. + +.. + +.. bpo: 26616 +.. date: 9585 +.. nonce: v3QwdD +.. section: Library + +Fixed a bug in datetime.astimezone() method. + +.. + +.. bpo: 21925 +.. date: 9584 +.. nonce: _fr69L +.. section: Library + +:func:`warnings.formatwarning` now catches exceptions on +``linecache.getline(...)`` to be able to log :exc:`ResourceWarning` emitted +late during the Python shutdown process. + +.. + +.. bpo: 24266 +.. date: 9583 +.. nonce: YZgVyM +.. section: Library + +Ctrl+C during Readline history search now cancels the search mode when +compiled with Readline 7. + +.. + +.. bpo: 26560 +.. date: 9582 +.. nonce: A4WXNz +.. section: Library + +Avoid potential ValueError in BaseHandler.start_response. Initial patch by +Peter Inglesby. + +.. + +.. bpo: 26569 +.. date: 9580 +.. nonce: EX8vF1 +.. section: Library + +Fix :func:`pyclbr.readmodule` and :func:`pyclbr.readmodule_ex` to support +importing packages. + +.. + +.. bpo: 26499 +.. date: 9579 +.. nonce: NP08PI +.. section: Library + +Account for remaining Content-Length in HTTPResponse.readline() and read1(). +Based on patch by Silent Ghost. Also document that HTTPResponse now supports +these methods. + +.. + +.. bpo: 25320 +.. date: 9578 +.. nonce: V96LIy +.. section: Library + +Handle sockets in directories unittest discovery is scanning. Patch from +Victor van den Elzen. + +.. + +.. bpo: 16181 +.. date: 9577 +.. nonce: P7lLvo +.. section: Library + +cookiejar.http2time() now returns None if year is higher than +datetime.MAXYEAR. + +.. + +.. bpo: 26513 +.. date: 9576 +.. nonce: HoPepy +.. section: Library + +Fixes platform module detection of Windows Server + +.. + +.. bpo: 23718 +.. date: 9575 +.. nonce: AMPC0o +.. section: Library + +Fixed parsing time in week 0 before Jan 1. Original patch by Tamás Bence +Gedai. + +.. + +.. bpo: 20589 +.. date: 9574 +.. nonce: NsQ_I1 +.. section: Library + +Invoking Path.owner() and Path.group() on Windows now raise +NotImplementedError instead of ImportError. + +.. + +.. bpo: 26177 +.. date: 9573 +.. nonce: HlSWer +.. section: Library + +Fixed the keys() method for Canvas and Scrollbar widgets. + +.. + +.. bpo: 15068 +.. date: 9572 +.. nonce: bcHtiw +.. section: Library + +Got rid of excessive buffering in the fileinput module. The bufsize +parameter is no longer used. + +.. + +.. bpo: 2202 +.. date: 9571 +.. nonce: dk9sd0 +.. section: Library + +Fix UnboundLocalError in AbstractDigestAuthHandler.get_algorithm_impls. +Initial patch by Mathieu Dupuy. + +.. + +.. bpo: 25718 +.. date: 9570 +.. nonce: 4EjZyv +.. section: Library + +Fixed pickling and copying the accumulate() iterator with total is None. + +.. + +.. bpo: 26475 +.. date: 9569 +.. nonce: JXVccY +.. section: Library + +Fixed debugging output for regular expressions with the (?x) flag. + +.. + +.. bpo: 26457 +.. date: 9568 +.. nonce: Xe6Clh +.. section: Library + +Fixed the subnets() methods in IP network classes for the case when +resulting prefix length is equal to maximal prefix length. Based on patch by +Xiang Zhang. + +.. + +.. bpo: 26385 +.. date: 9567 +.. nonce: 50bDXm +.. section: Library + +Remove the file if the internal open() call in NamedTemporaryFile() fails. +Patch by Silent Ghost. + +.. + +.. bpo: 26402 +.. date: 9566 +.. nonce: k7DVuU +.. section: Library + +Fix XML-RPC client to retry when the server shuts down a persistent +connection. This was a regression related to the new +http.client.RemoteDisconnected exception in 3.5.0a4. + +.. + +.. bpo: 25913 +.. date: 9565 +.. nonce: 5flb95 +.. section: Library + +Leading ``<~`` is optional now in base64.a85decode() with adobe=True. Patch +by Swati Jaiswal. + +.. + +.. bpo: 26186 +.. date: 9564 +.. nonce: R9rfiL +.. section: Library + +Remove an invalid type check in importlib.util.LazyLoader. + +.. + +.. bpo: 26367 +.. date: 9563 +.. nonce: ckpNeU +.. section: Library + +importlib.__import__() raises SystemError like builtins.__import__() when +``level`` is specified but without an accompanying package specified. + +.. + +.. bpo: 26309 +.. date: 9562 +.. nonce: ubEeiz +.. section: Library + +In the "socketserver" module, shut down the request (closing the connected +socket) when verify_request() returns false. Patch by Aviv Palivoda. + +.. + +.. bpo: 25995 +.. date: 9560 +.. nonce: NfcimP +.. section: Library + +os.walk() no longer uses FDs proportional to the tree depth. + +.. + +.. bpo: 26117 +.. date: 9559 +.. nonce: ne6p11 +.. section: Library + +The os.scandir() iterator now closes file descriptor not only when the +iteration is finished, but when it was failed with error. + +.. + +.. bpo: 25911 +.. date: 9558 +.. nonce: d4Zadh +.. section: Library + +Restored support of bytes paths in os.walk() on Windows. + +.. + +.. bpo: 26045 +.. date: 9557 +.. nonce: WmzUrX +.. section: Library + +Add UTF-8 suggestion to error message when posting a non-Latin-1 string with +http.client. + +.. + +.. bpo: 12923 +.. date: 9556 +.. nonce: HPAu-B +.. section: Library + +Reset FancyURLopener's redirect counter even if there is an exception. +Based on patches by Brian Brazil and Daniel Rocco. + +.. + +.. bpo: 25945 +.. date: 9555 +.. nonce: guNgNM +.. section: Library + +Fixed a crash when unpickle the functools.partial object with wrong state. +Fixed a leak in failed functools.partial constructor. "args" and "keywords" +attributes of functools.partial have now always types tuple and dict +correspondingly. + +.. + +.. bpo: 26202 +.. date: 9554 +.. nonce: LPIXLg +.. section: Library + +copy.deepcopy() now correctly copies range() objects with non-atomic +attributes. + +.. + +.. bpo: 23076 +.. date: 9553 +.. nonce: 8rphoP +.. section: Library + +Path.glob() now raises a ValueError if it's called with an invalid pattern. +Patch by Thomas Nyberg. + +.. + +.. bpo: 19883 +.. date: 9552 +.. nonce: z9TsO6 +.. section: Library + +Fixed possible integer overflows in zipimport. + +.. + +.. bpo: 26227 +.. date: 9551 +.. nonce: Fe6oiB +.. section: Library + +On Windows, getnameinfo(), gethostbyaddr() and gethostbyname_ex() functions +of the socket module now decode the hostname from the ANSI code page rather +than UTF-8. + +.. + +.. bpo: 26147 +.. date: 9550 +.. nonce: i-Jc01 +.. section: Library + +xmlrpc now works with strings not encodable with used non-UTF-8 encoding. + +.. + +.. bpo: 25935 +.. date: 9549 +.. nonce: cyni91 +.. section: Library + +Garbage collector now breaks reference loops with OrderedDict. + +.. + +.. bpo: 16620 +.. date: 9548 +.. nonce: rxpn_Y +.. section: Library + +Fixed AttributeError in msilib.Directory.glob(). + +.. + +.. bpo: 26013 +.. date: 9547 +.. nonce: 93RKNz +.. section: Library + +Added compatibility with broken protocol 2 pickles created in old Python 3 +versions (3.4.3 and lower). + +.. + +.. bpo: 25850 +.. date: 9546 +.. nonce: jwFPxj +.. section: Library + +Use cross-compilation by default for 64-bit Windows. + +.. + +.. bpo: 17633 +.. date: 9545 +.. nonce: 9mpbUO +.. section: Library + +Improve zipimport's support for namespace packages. + +.. + +.. bpo: 24705 +.. date: 9544 +.. nonce: IZYwjR +.. section: Library + +Fix sysconfig._parse_makefile not expanding ${} vars appearing before $() +vars. + +.. + +.. bpo: 22138 +.. date: 9543 +.. nonce: nRNYkc +.. section: Library + +Fix mock.patch behavior when patching descriptors. Restore original values +after patching. Patch contributed by Sean McCully. + +.. + +.. bpo: 25672 +.. date: 9542 +.. nonce: fw9RJP +.. section: Library + +In the ssl module, enable the SSL_MODE_RELEASE_BUFFERS mode option if it is +safe to do so. + +.. + +.. bpo: 26012 +.. date: 9541 +.. nonce: IFSXNm +.. section: Library + +Don't traverse into symlinks for ``**`` pattern in pathlib.Path.[r]glob(). + +.. + +.. bpo: 24120 +.. date: 9540 +.. nonce: Yiwa0h +.. section: Library + +Ignore PermissionError when traversing a tree with pathlib.Path.[r]glob(). +Patch by Ulrich Petri. + +.. + +.. bpo: 25447 +.. date: 9539 +.. nonce: -4m4xO +.. section: Library + +fileinput now uses sys.stdin as-is if it does not have a buffer attribute +(restores backward compatibility). + +.. + +.. bpo: 25447 +.. date: 9538 +.. nonce: AtHkWA +.. section: Library + +Copying the lru_cache() wrapper object now always works, independently from +the type of the wrapped object (by returning the original object unchanged). + +.. + +.. bpo: 24103 +.. date: 9537 +.. nonce: WufqrQ +.. section: Library + +Fixed possible use after free in ElementTree.XMLPullParser. + +.. + +.. bpo: 25860 +.. date: 9536 +.. nonce: 0hActb +.. section: Library + +os.fwalk() no longer skips remaining directories when error occurs. +Original patch by Samson Lee. + +.. + +.. bpo: 25914 +.. date: 9535 +.. nonce: h0V61F +.. section: Library + +Fixed and simplified OrderedDict.__sizeof__. + +.. + +.. bpo: 25902 +.. date: 9534 +.. nonce: 6t2FmH +.. section: Library + +Fixed various refcount issues in ElementTree iteration. + +.. + +.. bpo: 25717 +.. date: 9533 +.. nonce: 0_xjaK +.. section: Library + +Restore the previous behaviour of tolerating most fstat() errors when +opening files. This was a regression in 3.5a1, and stopped anonymous +temporary files from working in special cases. + +.. + +.. bpo: 24903 +.. date: 9532 +.. nonce: 3LBdzb +.. section: Library + +Fix regression in number of arguments compileall accepts when '-d' is +specified. The check on the number of arguments has been dropped completely +as it never worked correctly anyway. + +.. + +.. bpo: 25764 +.. date: 9531 +.. nonce: 7WWG07 +.. section: Library + +In the subprocess module, preserve any exception caused by fork() failure +when preexec_fn is used. + +.. + +.. bpo: 6478 +.. date: 9530 +.. nonce: -Bi9Hb +.. section: Library + +_strptime's regexp cache now is reset after changing timezone with +time.tzset(). + +.. + +.. bpo: 14285 +.. date: 9529 +.. nonce: UyG8Hj +.. section: Library + +When executing a package with the "python -m package" option, and package +initialization fails, a proper traceback is now reported. The "runpy" +module now lets exceptions from package initialization pass back to the +caller, rather than raising ImportError. + +.. + +.. bpo: 19771 +.. date: 9528 +.. nonce: 5NG-bg +.. section: Library + +Also in runpy and the "-m" option, omit the irrelevant message ". . . is a +package and cannot be directly executed" if the package could not even be +initialized (e.g. due to a bad ``*.pyc`` file). + +.. + +.. bpo: 25177 +.. date: 9527 +.. nonce: aNR4Ha +.. section: Library + +Fixed problem with the mean of very small and very large numbers. As a side +effect, statistics.mean and statistics.variance should be significantly +faster. + +.. + +.. bpo: 25718 +.. date: 9526 +.. nonce: D9mHZF +.. section: Library + +Fixed copying object with state with boolean value is false. + +.. + +.. bpo: 10131 +.. date: 9525 +.. nonce: a7tptz +.. section: Library + +Fixed deep copying of minidom documents. Based on patch by Marian Ganisin. + +.. + +.. bpo: 25725 +.. date: 9524 +.. nonce: XIKv3R +.. section: Library + +Fixed a reference leak in pickle.loads() when unpickling invalid data +including tuple instructions. + +.. + +.. bpo: 25663 +.. date: 9523 +.. nonce: Ofwfqa +.. section: Library + +In the Readline completer, avoid listing duplicate global names, and search +the global namespace before searching builtins. + +.. + +.. bpo: 25688 +.. date: 9522 +.. nonce: 8P1HOv +.. section: Library + +Fixed file leak in ElementTree.iterparse() raising an error. + +.. + +.. bpo: 23914 +.. date: 9521 +.. nonce: 1sEz4J +.. section: Library + +Fixed SystemError raised by unpickler on broken pickle data. + +.. + +.. bpo: 25691 +.. date: 9520 +.. nonce: ZEaapY +.. section: Library + +Fixed crash on deleting ElementTree.Element attributes. + +.. + +.. bpo: 25624 +.. date: 9519 +.. nonce: ed-fM0 +.. section: Library + +ZipFile now always writes a ZIP_STORED header for directory entries. Patch +by Dingyuan Wang. + +.. + +.. bpo: 0 +.. date: 9518 +.. nonce: rtZyid +.. section: Library + +Skip getaddrinfo if host is already resolved. Patch by A. Jesse Jiryu Davis. + +.. + +.. bpo: 26050 +.. date: 9517 +.. nonce: sclyvk +.. section: Library + +Add asyncio.StreamReader.readuntil() method. Patch by Марк Коренберг. + +.. + +.. bpo: 25924 +.. date: 9516 +.. nonce: Uxr2vt +.. section: Library + +Avoid unnecessary serialization of getaddrinfo(3) calls on OS X versions +10.5 or higher. Original patch by A. Jesse Jiryu Davis. + +.. + +.. bpo: 26406 +.. date: 9515 +.. nonce: ihvhF4 +.. section: Library + +Avoid unnecessary serialization of getaddrinfo(3) calls on current versions +of OpenBSD and NetBSD. Patch by A. Jesse Jiryu Davis. + +.. + +.. bpo: 26848 +.. date: 9514 +.. nonce: ChBOpQ +.. section: Library + +Fix asyncio/subprocess.communicate() to handle empty input. Patch by Jack +O'Connor. + +.. + +.. bpo: 27040 +.. date: 9513 +.. nonce: UASyCC +.. section: Library + +Add loop.get_exception_handler method + +.. + +.. bpo: 27041 +.. date: 9512 +.. nonce: p3893U +.. section: Library + +asyncio: Add loop.create_future method + +.. + +.. bpo: 27223 +.. date: 9511 +.. nonce: PRf4I6 +.. section: Library + +asyncio: Fix _read_ready and _write_ready to respect _conn_lost. Patch by +Łukasz Langa. + +.. + +.. bpo: 22970 +.. date: 9510 +.. nonce: WhdhyM +.. section: Library + +asyncio: Fix inconsistency cancelling Condition.wait. Patch by David Coles. + +.. + +.. bpo: 5124 +.. date: 9509 +.. nonce: 4kwBvM +.. section: IDLE + +Paste with text selected now replaces the selection on X11. This matches how +paste works on Windows, Mac, most modern Linux apps, and ttk widgets. +Original patch by Serhiy Storchaka. + +.. + +.. bpo: 24759 +.. date: 9508 +.. nonce: ccmySu +.. section: IDLE + +Make clear in idlelib.idle_test.__init__ that the directory is a private +implementation of test.test_idle and tool for maintainers. + +.. + +.. bpo: 27196 +.. date: 9507 +.. nonce: 3yp8TF +.. section: IDLE + +Stop 'ThemeChanged' warnings when running IDLE tests. These persisted after +other warnings were suppressed in #20567. Apply Serhiy Storchaka's +update_idletasks solution to four test files. Record this additional advice +in idle_test/README.txt + +.. + +.. bpo: 20567 +.. date: 9506 +.. nonce: hhT32b +.. section: IDLE + +Revise idle_test/README.txt with advice about avoiding tk warning messages +from tests. Apply advice to several IDLE tests. + +.. + +.. bpo: 27117 +.. date: 9505 +.. nonce: YrLPf4 +.. section: IDLE + +Make colorizer htest and turtledemo work with dark themes. Move code for +configuring text widget colors to a new function. + +.. + +.. bpo: 26673 +.. date: 9504 +.. nonce: dh0_Ij +.. section: IDLE + +When tk reports font size as 0, change to size 10. Such fonts on Linux +prevented the configuration dialog from opening. + +.. + +.. bpo: 21939 +.. date: 9503 +.. nonce: pWz-OK +.. section: IDLE + +Add test for IDLE's percolator. Original patch by Saimadhav Heblikar. + +.. + +.. bpo: 21676 +.. date: 9502 +.. nonce: hqy6Qh +.. section: IDLE + +Add test for IDLE's replace dialog. Original patch by Saimadhav Heblikar. + +.. + +.. bpo: 18410 +.. date: 9501 +.. nonce: DLSPZo +.. section: IDLE + +Add test for IDLE's search dialog. Original patch by Westley Martínez. + +.. + +.. bpo: 21703 +.. date: 9500 +.. nonce: BAZfDM +.. section: IDLE + +Add test for IDLE's undo delegator. Original patch by Saimadhav Heblikar . + +.. + +.. bpo: 27044 +.. date: 9499 +.. nonce: 4y7tyM +.. section: IDLE + +Add ConfigDialog.remove_var_callbacks to stop memory leaks. + +.. + +.. bpo: 23977 +.. date: 9498 +.. nonce: miDjj8 +.. section: IDLE + +Add more asserts to test_delegator. + +.. + +.. bpo: 20640 +.. date: 9497 +.. nonce: PmI-G8 +.. section: IDLE + +Add tests for idlelib.configHelpSourceEdit. Patch by Saimadhav Heblikar. + +.. + +.. bpo: 0 +.. date: 9496 +.. nonce: _YJfG7 +.. section: IDLE + +In the 'IDLE-console differences' section of the IDLE doc, clarify how +running with IDLE affects sys.modules and the standard streams. + +.. + +.. bpo: 25507 +.. date: 9495 +.. nonce: i8bNpk +.. section: IDLE + +fix incorrect change in IOBinding that prevented printing. Augment IOBinding +htest to include all major IOBinding functions. + +.. + +.. bpo: 25905 +.. date: 9494 +.. nonce: FzNb3B +.. section: IDLE + +Revert unwanted conversion of ' to ’ RIGHT SINGLE QUOTATION MARK in +README.txt and open this and NEWS.txt with 'ascii'. Re-encode CREDITS.txt to +utf-8 and open it with 'utf-8'. + +.. + +.. bpo: 19489 +.. date: 9493 +.. nonce: jvzuO7 +.. section: Documentation + +Moved the search box from the sidebar to the header and footer of each page. +Patch by Ammar Askar. + +.. + +.. bpo: 24136 +.. date: 9492 +.. nonce: MUK0zK +.. section: Documentation + +Document the new :pep:`448` unpacking syntax of 3.5. + +.. + +.. bpo: 26736 +.. date: 9491 +.. nonce: U_Hyqo +.. section: Documentation + +Used HTTPS for external links in the documentation if possible. + +.. + +.. bpo: 6953 +.. date: 9490 +.. nonce: Zk6rno +.. section: Documentation + +Rework the Readline module documentation to group related functions +together, and add more details such as what underlying Readline functions +and variables are accessed. + +.. + +.. bpo: 23606 +.. date: 9489 +.. nonce: 9MhIso +.. section: Documentation + +Adds note to ctypes documentation regarding cdll.msvcrt. + +.. + +.. bpo: 25500 +.. date: 9488 +.. nonce: AV47eF +.. section: Documentation + +Fix documentation to not claim that __import__ is searched for in the global +scope. + +.. + +.. bpo: 26014 +.. date: 9487 +.. nonce: ptdZ_I +.. section: Documentation + +Update 3.x packaging documentation: * "See also" links to the new docs are +now provided in the legacy pages * links to setuptools documentation have +been updated + +.. + +.. bpo: 21916 +.. date: 9486 +.. nonce: muwCyp +.. section: Tests + +Added tests for the turtle module. Patch by ingrid, Gregory Loyse and Jelle +Zijlstra. + +.. + +.. bpo: 26523 +.. date: 9485 +.. nonce: em_Uzt +.. section: Tests + +The multiprocessing thread pool (multiprocessing.dummy.Pool) was untested. + +.. + +.. bpo: 26015 +.. date: 9484 +.. nonce: p3oWK3 +.. section: Tests + +Added new tests for pickling iterators of mutable sequences. + +.. + +.. bpo: 26325 +.. date: 9483 +.. nonce: KOUc82 +.. section: Tests + +Added test.support.check_no_resource_warning() to check that no +ResourceWarning is emitted. + +.. + +.. bpo: 25940 +.. date: 9482 +.. nonce: PgiLVN +.. section: Tests + +Changed test_ssl to use self-signed.pythontest.net. This avoids relying on +svn.python.org, which recently changed root certificate. + +.. + +.. bpo: 25616 +.. date: 9481 +.. nonce: Qr-60p +.. section: Tests + +Tests for OrderedDict are extracted from test_collections into separate file +test_ordered_dict. + +.. + +.. bpo: 26583 +.. date: 9480 +.. nonce: Up7hTl +.. section: Tests + +Skip test_timestamp_overflow in test_import if bytecode files cannot be +written. + +.. + +.. bpo: 26884 +.. date: 9479 +.. nonce: O8-azL +.. section: Build + +Fix linking extension modules for cross builds. Patch by Xavier de Gaye. + +.. + +.. bpo: 22359 +.. date: 9478 +.. nonce: HDjM4s +.. section: Build + +Disable the rules for running _freeze_importlib and pgen when +cross-compiling. The output of these programs is normally saved with the +source code anyway, and is still regenerated when doing a native build. +Patch by Xavier de Gaye. + +.. + +.. bpo: 27229 +.. date: 9477 +.. nonce: C2NDch +.. section: Build + +Fix the cross-compiling pgen rule for in-tree builds. Patch by Xavier de +Gaye. + +.. + +.. bpo: 21668 +.. date: 9476 +.. nonce: 4sMAa1 +.. section: Build + +Link audioop, _datetime, _ctypes_test modules to libm, except on Mac OS X. +Patch written by Xavier de Gaye. + +.. + +.. bpo: 25702 +.. date: 9475 +.. nonce: ipxyJs +.. section: Build + +A --with-lto configure option has been added that will enable link time +optimizations at build time during a make profile-opt. Some compilers and +toolchains are known to not produce stable code when using LTO, be sure to +test things thoroughly before relying on it. It can provide a few % speed up +over profile-opt alone. + +.. + +.. bpo: 26624 +.. date: 9474 +.. nonce: 4fGrTl +.. section: Build + +Adds validation of ucrtbase[d].dll version with warning for old versions. + +.. + +.. bpo: 17603 +.. date: 9473 +.. nonce: 102DA- +.. section: Build + +Avoid error about nonexistent fileblocks.o file by using a lower-level check +for st_blocks in struct stat. + +.. + +.. bpo: 26079 +.. date: 9472 +.. nonce: mEzW0O +.. section: Build + +Fixing the build output folder for tix-8.4.3.6. Patch by Bjoern Thiel. + +.. + +.. bpo: 26465 +.. date: 9471 +.. nonce: _YR608 +.. section: Build + +Update Windows builds to use OpenSSL 1.0.2g. + +.. + +.. bpo: 24421 +.. date: 9470 +.. nonce: 2zY7vM +.. section: Build + +Compile Modules/_math.c once, before building extensions. Previously it +could fail to compile properly if the math and cmath builds were concurrent. + +.. + +.. bpo: 25348 +.. date: 9469 +.. nonce: u6_BaQ +.. section: Build + +Added ``--pgo`` and ``--pgo-job`` arguments to ``PCbuild\build.bat`` for +building with Profile-Guided Optimization. The old +``PCbuild\build_pgo.bat`` script is now deprecated, and simply calls +``PCbuild\build.bat --pgo %*``. + +.. + +.. bpo: 25827 +.. date: 9468 +.. nonce: yg3DMM +.. section: Build + +Add support for building with ICC to ``configure``, including a new +``--with-icc`` flag. + +.. + +.. bpo: 25696 +.. date: 9467 +.. nonce: 2R_wIv +.. section: Build + +Fix installation of Python on UNIX with make -j9. + +.. + +.. bpo: 26930 +.. date: 9466 +.. nonce: Sqz2O3 +.. section: Build + +Update OS X 10.5+ 32-bit-only installer to build and link with OpenSSL +1.0.2h. + +.. + +.. bpo: 26268 +.. date: 9465 +.. nonce: I3-YLh +.. section: Build + +Update Windows builds to use OpenSSL 1.0.2f. + +.. + +.. bpo: 25136 +.. date: 9464 +.. nonce: Vi-fmO +.. section: Build + +Support Apple Xcode 7's new textual SDK stub libraries. + +.. + +.. bpo: 24324 +.. date: 9463 +.. nonce: m6DZMx +.. section: Build + +Do not enable unreachable code warnings when using gcc as the option does +not work correctly in older versions of gcc and has been silently removed as +of gcc-4.5. + +.. + +.. bpo: 27053 +.. date: 9462 +.. nonce: 1IRbae +.. section: Windows + +Updates make_zip.py to correctly generate library ZIP file. + +.. + +.. bpo: 26268 +.. date: 9461 +.. nonce: Z-lJEh +.. section: Windows + +Update the prepare_ssl.py script to handle OpenSSL releases that don't +include the contents of the include directory (that is, 1.0.2e and later). + +.. + +.. bpo: 26071 +.. date: 9460 +.. nonce: wLxL2l +.. section: Windows + +bdist_wininst created binaries fail to start and find 32bit Python + +.. + +.. bpo: 26073 +.. date: 9459 +.. nonce: XwWgHp +.. section: Windows + +Update the list of magic numbers in launcher + +.. + +.. bpo: 26065 +.. date: 9458 +.. nonce: SkVLJp +.. section: Windows + +Excludes venv from library when generating embeddable distro. + +.. + +.. bpo: 17500 +.. date: 9453 +.. nonce: QTZbRV +.. section: Windows + +Remove unused and outdated icons. (See also: +https://github.com/python/pythondotorg/issues/945) + +.. + +.. bpo: 26799 +.. date: 9457 +.. nonce: gK2VXX +.. section: Tools/Demos + +Fix python-gdb.py: don't get C types once when the Python code is loaded, +but get C types on demand. The C types can change if python-gdb.py is loaded +before the Python executable. Patch written by Thomas Ilsche. + +.. + +.. bpo: 26271 +.. date: 9456 +.. nonce: wg-rzr +.. section: Tools/Demos + +Fix the Freeze tool to properly use flags passed through configure. Patch by +Daniel Shaulov. + +.. + +.. bpo: 26489 +.. date: 9455 +.. nonce: rJ_U5S +.. section: Tools/Demos + +Add dictionary unpacking support to Tools/parser/unparse.py. Patch by Guo Ci +Teo. + +.. + +.. bpo: 26316 +.. date: 9454 +.. nonce: QJvVOi +.. section: Tools/Demos + +Fix variable name typo in Argument Clinic. diff --git a/Misc/NEWS.d/3.5.3.rst b/Misc/NEWS.d/3.5.3.rst new file mode 100644 index 00000000..c3fcb67a --- /dev/null +++ b/Misc/NEWS.d/3.5.3.rst @@ -0,0 +1,7 @@ +.. bpo: 0 +.. date: 9899 +.. no changes: True +.. nonce: zYPqUK +.. release date: 2017-01-17 + +There were no code changes between 3.5.3rc1 and 3.5.3 final. diff --git a/Misc/NEWS.d/3.5.3rc1.rst b/Misc/NEWS.d/3.5.3rc1.rst new file mode 100644 index 00000000..bf4ef930 --- /dev/null +++ b/Misc/NEWS.d/3.5.3rc1.rst @@ -0,0 +1,2163 @@ +.. release date: 2017-01-02 +.. bpo: 27278 +.. date: 9755 +.. nonce: y_HkGw +.. original section: Library +.. section: Security + +Fix os.urandom() implementation using getrandom() on Linux. Truncate size +to INT_MAX and loop until we collected enough random bytes, instead of +casting a directly Py_ssize_t to int. + +.. + +.. bpo: 22636 +.. date: 9753 +.. nonce: 3fQW_g +.. original section: Library +.. section: Security + +Avoid shell injection problems with ctypes.util.find_library(). + +.. + +.. bpo: 29073 +.. date: 9898 +.. nonce: EFpHQ7 +.. section: Core and Builtins + +bytearray formatting no longer truncates on first null byte. + +.. + +.. bpo: 28932 +.. date: 9897 +.. nonce: QnLx8A +.. section: Core and Builtins + +Do not include <sys/random.h> if it does not exist. + +.. + +.. bpo: 28147 +.. date: 9896 +.. nonce: EV4bm6 +.. section: Core and Builtins + +Fix a memory leak in split-table dictionaries: setattr() must not convert +combined table into split table. + +.. + +.. bpo: 25677 +.. date: 9895 +.. nonce: RWhZrb +.. section: Core and Builtins + +Correct the positioning of the syntax error caret for indented blocks. +Based on patch by Michael Layzell. + +.. + +.. bpo: 29000 +.. date: 9894 +.. nonce: K6wQ-3 +.. section: Core and Builtins + +Fixed bytes formatting of octals with zero padding in alternate form. + +.. + +.. bpo: 28512 +.. date: 9893 +.. nonce: i-pv6d +.. section: Core and Builtins + +Fixed setting the offset attribute of SyntaxError by +PyErr_SyntaxLocationEx() and PyErr_SyntaxLocationObject(). + +.. + +.. bpo: 28991 +.. date: 9892 +.. nonce: -qOTxS +.. section: Core and Builtins + +functools.lru_cache() was susceptible to an obscure reentrancy bug caused by +a monkey-patched len() function. + +.. + +.. bpo: 28648 +.. date: 9891 +.. nonce: z7B52W +.. section: Core and Builtins + +Fixed crash in Py_DecodeLocale() in debug build on Mac OS X when decode +astral characters. Patch by Xiang Zhang. + +.. + +.. bpo: 19398 +.. date: 9890 +.. nonce: RYbEGH +.. section: Core and Builtins + +Extra slash no longer added to sys.path components in case of empty +compile-time PYTHONPATH components. + +.. + +.. bpo: 28426 +.. date: 9889 +.. nonce: E_quyK +.. section: Core and Builtins + +Fixed potential crash in PyUnicode_AsDecodedObject() in debug build. + +.. + +.. bpo: 23782 +.. date: 9888 +.. nonce: lonDzj +.. section: Core and Builtins + +Fixed possible memory leak in _PyTraceback_Add() and exception loss in +PyTraceBack_Here(). + +.. + +.. bpo: 28379 +.. date: 9887 +.. nonce: DuXlco +.. section: Core and Builtins + +Added sanity checks and tests for PyUnicode_CopyCharacters(). Patch by Xiang +Zhang. + +.. + +.. bpo: 28376 +.. date: 9886 +.. nonce: oPD-5D +.. section: Core and Builtins + +The type of long range iterator is now registered as Iterator. Patch by Oren +Milman. + +.. + +.. bpo: 28376 +.. date: 9885 +.. nonce: fLeHM2 +.. section: Core and Builtins + +The constructor of range_iterator now checks that step is not 0. Patch by +Oren Milman. + +.. + +.. bpo: 26906 +.. date: 9884 +.. nonce: YBjcwI +.. section: Core and Builtins + +Resolving special methods of uninitialized type now causes implicit +initialization of the type instead of a fail. + +.. + +.. bpo: 18287 +.. date: 9883 +.. nonce: k6jffS +.. section: Core and Builtins + +PyType_Ready() now checks that tp_name is not NULL. Original patch by Niklas +Koep. + +.. + +.. bpo: 24098 +.. date: 9882 +.. nonce: XqlP_1 +.. section: Core and Builtins + +Fixed possible crash when AST is changed in process of compiling it. + +.. + +.. bpo: 28350 +.. date: 9881 +.. nonce: 8M5Eg9 +.. section: Core and Builtins + +String constants with null character no longer interned. + +.. + +.. bpo: 26617 +.. date: 9880 +.. nonce: Gh5LvN +.. section: Core and Builtins + +Fix crash when GC runs during weakref callbacks. + +.. + +.. bpo: 27942 +.. date: 9879 +.. nonce: ZGuhns +.. section: Core and Builtins + +String constants now interned recursively in tuples and frozensets. + +.. + +.. bpo: 21578 +.. date: 9878 +.. nonce: GI1bhj +.. section: Core and Builtins + +Fixed misleading error message when ImportError called with invalid keyword +args. + +.. + +.. bpo: 28203 +.. date: 9877 +.. nonce: kOgvtp +.. section: Core and Builtins + +Fix incorrect type in error message from ``complex(1.0, {2:3})``. Patch by +Soumya Sharma. + +.. + +.. bpo: 27955 +.. date: 9876 +.. nonce: HC4pZ4 +.. section: Core and Builtins + +Fallback on reading /dev/urandom device when the getrandom() syscall fails +with EPERM, for example when blocked by SECCOMP. + +.. + +.. bpo: 28131 +.. date: 9875 +.. nonce: owq0wW +.. section: Core and Builtins + +Fix a regression in zipimport's compile_source(). zipimport should use the +same optimization level as the interpreter. + +.. + +.. bpo: 25221 +.. date: 9874 +.. nonce: Zvkz9i +.. section: Core and Builtins + +Fix corrupted result from PyLong_FromLong(0) when Python is compiled with +NSMALLPOSINTS = 0. + +.. + +.. bpo: 25758 +.. date: 9873 +.. nonce: yR-YTD +.. section: Core and Builtins + +Prevents zipimport from unnecessarily encoding a filename (patch by Eryk +Sun) + +.. + +.. bpo: 28189 +.. date: 9872 +.. nonce: c_nbR_ +.. section: Core and Builtins + +dictitems_contains no longer swallows compare errors. (Patch by Xiang Zhang) + +.. + +.. bpo: 27812 +.. date: 9871 +.. nonce: sidcs8 +.. section: Core and Builtins + +Properly clear out a generator's frame's backreference to the generator to +prevent crashes in frame.clear(). + +.. + +.. bpo: 27811 +.. date: 9870 +.. nonce: T4AuBo +.. section: Core and Builtins + +Fix a crash when a coroutine that has not been awaited is finalized with +warnings-as-errors enabled. + +.. + +.. bpo: 27587 +.. date: 9869 +.. nonce: mbavY2 +.. section: Core and Builtins + +Fix another issue found by PVS-Studio: Null pointer check after use of 'def' +in _PyState_AddModule(). Initial patch by Christian Heimes. + +.. + +.. bpo: 26020 +.. date: 9868 +.. nonce: niLbLa +.. section: Core and Builtins + +set literal evaluation order did not match documented behaviour. + +.. + +.. bpo: 27782 +.. date: 9867 +.. nonce: C8OBQD +.. section: Core and Builtins + +Multi-phase extension module import now correctly allows the ``m_methods`` +field to be used to add module level functions to instances of non-module +types returned from ``Py_create_mod``. Patch by Xiang Zhang. + +.. + +.. bpo: 27936 +.. date: 9866 +.. nonce: AdOann +.. section: Core and Builtins + +The round() function accepted a second None argument for some types but not +for others. Fixed the inconsistency by accepting None for all numeric +types. + +.. + +.. bpo: 27487 +.. date: 9865 +.. nonce: jeTQNr +.. section: Core and Builtins + +Warn if a submodule argument to "python -m" or runpy.run_module() is found +in sys.modules after parent packages are imported, but before the submodule +is executed. + +.. + +.. bpo: 27558 +.. date: 9864 +.. nonce: VmltMh +.. section: Core and Builtins + +Fix a SystemError in the implementation of "raise" statement. In a brand new +thread, raise a RuntimeError since there is no active exception to reraise. +Patch written by Xiang Zhang. + +.. + +.. bpo: 27419 +.. date: 9863 +.. nonce: JZ94ju +.. section: Core and Builtins + +Standard __import__() no longer look up "__import__" in globals or builtins +for importing submodules or "from import". Fixed handling an error of +non-string package name. + +.. + +.. bpo: 27083 +.. date: 9862 +.. nonce: F4ZT1C +.. section: Core and Builtins + +Respect the PYTHONCASEOK environment variable under Windows. + +.. + +.. bpo: 27514 +.. date: 9861 +.. nonce: NLbwPG +.. section: Core and Builtins + +Make having too many statically nested blocks a SyntaxError instead of +SystemError. + +.. + +.. bpo: 27473 +.. date: 9860 +.. nonce: _nOtTA +.. section: Core and Builtins + +Fixed possible integer overflow in bytes and bytearray concatenations. +Patch by Xiang Zhang. + +.. + +.. bpo: 27507 +.. date: 9859 +.. nonce: 3pX0Be +.. section: Core and Builtins + +Add integer overflow check in bytearray.extend(). Patch by Xiang Zhang. + +.. + +.. bpo: 27581 +.. date: 9858 +.. nonce: KezjNt +.. section: Core and Builtins + +Don't rely on wrapping for overflow check in PySequence_Tuple(). Patch by +Xiang Zhang. + +.. + +.. bpo: 27443 +.. date: 9857 +.. nonce: 87ZwZ1 +.. section: Core and Builtins + +__length_hint__() of bytearray iterators no longer return a negative integer +for a resized bytearray. + +.. + +.. bpo: 27942 +.. date: 9856 +.. nonce: wCAkW5 +.. section: Core and Builtins + +Fix memory leak in codeobject.c + +.. + +.. bpo: 15812 +.. date: 9855 +.. nonce: R1U-Ec +.. section: Library + +inspect.getframeinfo() now correctly shows the first line of a context. +Patch by Sam Breese. + +.. + +.. bpo: 29094 +.. date: 9854 +.. nonce: 460ZQo +.. section: Library + +Offsets in a ZIP file created with extern file object and modes "w" and "x" +now are relative to the start of the file. + +.. + +.. bpo: 13051 +.. date: 9853 +.. nonce: YzC1Te +.. section: Library + +Fixed recursion errors in large or resized curses.textpad.Textbox. Based on +patch by Tycho Andersen. + +.. + +.. bpo: 29119 +.. date: 9852 +.. nonce: Ov69fr +.. section: Library + +Fix weakrefs in the pure python version of collections.OrderedDict +move_to_end() method. Contributed by Andra Bogildea. + +.. + +.. bpo: 9770 +.. date: 9851 +.. nonce: WJJnwP +.. section: Library + +curses.ascii predicates now work correctly with negative integers. + +.. + +.. bpo: 28427 +.. date: 9850 +.. nonce: vUd-va +.. section: Library + +old keys should not remove new values from WeakValueDictionary when +collecting from another thread. + +.. + +.. bpo: 28923 +.. date: 9849 +.. nonce: naVULD +.. section: Library + +Remove editor artifacts from Tix.py. + +.. + +.. bpo: 28871 +.. date: 9848 +.. nonce: cPMXCJ +.. section: Library + +Fixed a crash when deallocate deep ElementTree. + +.. + +.. bpo: 19542 +.. date: 9847 +.. nonce: 5tCkaK +.. section: Library + +Fix bugs in WeakValueDictionary.setdefault() and WeakValueDictionary.pop() +when a GC collection happens in another thread. + +.. + +.. bpo: 20191 +.. date: 9846 +.. nonce: P_EZ7c +.. section: Library + +Fixed a crash in resource.prlimit() when pass a sequence that doesn't own +its elements as limits. + +.. + +.. bpo: 28779 +.. date: 9845 +.. nonce: t-mjED +.. section: Library + +multiprocessing.set_forkserver_preload() would crash the forkserver process +if a preloaded module instantiated some multiprocessing objects such as +locks. + +.. + +.. bpo: 28847 +.. date: 9844 +.. nonce: J7d3nG +.. section: Library + +dbm.dumb now supports reading read-only files and no longer writes the index +file when it is not changed. + +.. + +.. bpo: 25659 +.. date: 9843 +.. nonce: lE2IlT +.. section: Library + +In ctypes, prevent a crash calling the from_buffer() and from_buffer_copy() +methods on abstract classes like Array. + +.. + +.. bpo: 28732 +.. date: 9842 +.. nonce: xkG8k7 +.. section: Library + +Fix crash in os.spawnv() with no elements in args + +.. + +.. bpo: 28485 +.. date: 9841 +.. nonce: WuKqKh +.. section: Library + +Always raise ValueError for negative compileall.compile_dir(workers=...) +parameter, even when multithreading is unavailable. + +.. + +.. bpo: 28387 +.. date: 9840 +.. nonce: 1clJu7 +.. section: Library + +Fixed possible crash in _io.TextIOWrapper deallocator when the garbage +collector is invoked in other thread. Based on patch by Sebastian Cufre. + +.. + +.. bpo: 27517 +.. date: 9839 +.. nonce: 1CYM8A +.. section: Library + +LZMA compressor and decompressor no longer raise exceptions if given empty +data twice. Patch by Benjamin Fogle. + +.. + +.. bpo: 28549 +.. date: 9838 +.. nonce: ShnM2y +.. section: Library + +Fixed segfault in curses's addch() with ncurses6. + +.. + +.. bpo: 28449 +.. date: 9837 +.. nonce: 5JK6ES +.. section: Library + +tarfile.open() with mode "r" or "r:" now tries to open a tar file with +compression before trying to open it without compression. Otherwise it had +50% chance failed with ignore_zeros=True. + +.. + +.. bpo: 23262 +.. date: 9836 +.. nonce: 6EVB7N +.. section: Library + +The webbrowser module now supports Firefox 36+ and derived browsers. Based +on patch by Oleg Broytman. + +.. + +.. bpo: 27939 +.. date: 9835 +.. nonce: mTfADV +.. section: Library + +Fixed bugs in tkinter.ttk.LabeledScale and tkinter.Scale caused by +representing the scale as float value internally in Tk. tkinter.IntVar now +works if float value is set to underlying Tk variable. + +.. + +.. bpo: 28255 +.. date: 9834 +.. nonce: _ZH4wm +.. section: Library + +calendar.TextCalendar().prmonth() no longer prints a space at the start of +new line after printing a month's calendar. Patch by Xiang Zhang. + +.. + +.. bpo: 20491 +.. date: 9833 +.. nonce: ObgnQ2 +.. section: Library + +The textwrap.TextWrapper class now honors non-breaking spaces. Based on +patch by Kaarle Ritvanen. + +.. + +.. bpo: 28353 +.. date: 9832 +.. nonce: sKGbLL +.. section: Library + +os.fwalk() no longer fails on broken links. + +.. + +.. bpo: 25464 +.. date: 9831 +.. nonce: HDUTCu +.. section: Library + +Fixed HList.header_exists() in tkinter.tix module by addin a workaround to +Tix library bug. + +.. + +.. bpo: 28488 +.. date: 9830 +.. nonce: NlkjBM +.. section: Library + +shutil.make_archive() no longer add entry "./" to ZIP archive. + +.. + +.. bpo: 24452 +.. date: 9829 +.. nonce: m9Kyg3 +.. section: Library + +Make webbrowser support Chrome on Mac OS X. + +.. + +.. bpo: 20766 +.. date: 9828 +.. nonce: 4kvCzx +.. section: Library + +Fix references leaked by pdb in the handling of SIGINT handlers. + +.. + +.. bpo: 26293 +.. date: 9827 +.. nonce: 2mjvwX +.. section: Library + +Fixed writing ZIP files that starts not from the start of the file. Offsets +in ZIP file now are relative to the start of the archive in conforming to +the specification. + +.. + +.. bpo: 28321 +.. date: 9826 +.. nonce: bQ-IIX +.. section: Library + +Fixed writing non-BMP characters with binary format in plistlib. + +.. + +.. bpo: 28322 +.. date: 9825 +.. nonce: l9hzap +.. section: Library + +Fixed possible crashes when unpickle itertools objects from incorrect pickle +data. Based on patch by John Leitch. + +.. + +.. bpo: 0 +.. date: 9824 +.. nonce: 81jNns +.. section: Library + +Fix possible integer overflows and crashes in the mmap module with unusual +usage patterns. + +.. + +.. bpo: 1703178 +.. date: 9823 +.. nonce: meb49K +.. section: Library + +Fix the ability to pass the --link-objects option to the distutils build_ext +command. + +.. + +.. bpo: 28253 +.. date: 9822 +.. nonce: aLfmhe +.. section: Library + +Fixed calendar functions for extreme months: 0001-01 and 9999-12. +Methods itermonthdays() and itermonthdays2() are reimplemented so that they +don't call itermonthdates() which can cause datetime.date under/overflow. + +.. + +.. bpo: 28275 +.. date: 9821 +.. nonce: EhWIsz +.. section: Library + +Fixed possible use after free in the decompress() methods of the +LZMADecompressor and BZ2Decompressor classes. Original patch by John Leitch. + +.. + +.. bpo: 27897 +.. date: 9820 +.. nonce: I0Ppmx +.. section: Library + +Fixed possible crash in sqlite3.Connection.create_collation() if pass +invalid string-like object as a name. Patch by Xiang Zhang. + +.. + +.. bpo: 18893 +.. date: 9819 +.. nonce: osiX5c +.. section: Library + +Fix invalid exception handling in Lib/ctypes/macholib/dyld.py. Patch by +Madison May. + +.. + +.. bpo: 27611 +.. date: 9818 +.. nonce: qL-UVQ +.. section: Library + +Fixed support of default root window in the tkinter.tix module. + +.. + +.. bpo: 27348 +.. date: 9817 +.. nonce: tDx7Vw +.. section: Library + +In the traceback module, restore the formatting of exception messages like +"Exception: None". This fixes a regression introduced in 3.5a2. + +.. + +.. bpo: 25651 +.. date: 9816 +.. nonce: 3UhyPo +.. section: Library + +Allow false values to be used for msg parameter of subTest(). + +.. + +.. bpo: 27932 +.. date: 9815 +.. nonce: mtgl-6 +.. section: Library + +Prevent memory leak in win32_ver(). + +.. + +.. bpo: 0 +.. date: 9814 +.. nonce: iPpjqX +.. section: Library + +Fix UnboundLocalError in socket._sendfile_use_sendfile. + +.. + +.. bpo: 28075 +.. date: 9813 +.. nonce: aLiUs9 +.. section: Library + +Check for ERROR_ACCESS_DENIED in Windows implementation of os.stat(). Patch +by Eryk Sun. + +.. + +.. bpo: 25270 +.. date: 9812 +.. nonce: jrZruM +.. section: Library + +Prevent codecs.escape_encode() from raising SystemError when an empty +bytestring is passed. + +.. + +.. bpo: 28181 +.. date: 9811 +.. nonce: NGc4Yv +.. section: Library + +Get antigravity over HTTPS. Patch by Kaartic Sivaraam. + +.. + +.. bpo: 25895 +.. date: 9810 +.. nonce: j92qoQ +.. section: Library + +Enable WebSocket URL schemes in urllib.parse.urljoin. Patch by Gergely Imreh +and Markus Holtermann. + +.. + +.. bpo: 27599 +.. date: 9809 +.. nonce: itvm8T +.. section: Library + +Fixed buffer overrun in binascii.b2a_qp() and binascii.a2b_qp(). + +.. + +.. bpo: 19003 +.. date: 9808 +.. nonce: UUcK_F +.. section: Library + +m email.generator now replaces only ``\r`` and/or ``\n`` line endings, per +the RFC, instead of all unicode line endings. + +.. + +.. bpo: 28019 +.. date: 9807 +.. nonce: KUhBaS +.. section: Library + +itertools.count() no longer rounds non-integer step in range between 1.0 and +2.0 to 1. + +.. + +.. bpo: 25969 +.. date: 9806 +.. nonce: qSPkl- +.. section: Library + +Update the lib2to3 grammar to handle the unpacking generalizations added in +3.5. + +.. + +.. bpo: 14977 +.. date: 9805 +.. nonce: 4MvALg +.. section: Library + +mailcap now respects the order of the lines in the mailcap files ("first +match"), as required by RFC 1542. Patch by Michael Lazar. + +.. + +.. bpo: 24594 +.. date: 9804 +.. nonce: 9CnFVS +.. section: Library + +Validates persist parameter when opening MSI database + +.. + +.. bpo: 17582 +.. date: 9803 +.. nonce: MXEHxQ +.. section: Library + +xml.etree.ElementTree nows preserves whitespaces in attributes (Patch by +Duane Griffin. Reviewed and approved by Stefan Behnel.) + +.. + +.. bpo: 28047 +.. date: 9802 +.. nonce: pDu3Fm +.. section: Library + +Fixed calculation of line length used for the base64 CTE in the new email +policies. + +.. + +.. bpo: 27445 +.. date: 9801 +.. nonce: wOG0C0 +.. section: Library + +Don't pass str(_charset) to MIMEText.set_payload(). Patch by Claude Paroz. + +.. + +.. bpo: 22450 +.. date: 9800 +.. nonce: T3Sn_J +.. section: Library + +urllib now includes an ``Accept: */*`` header among the default headers. +This makes the results of REST API requests more consistent and predictable +especially when proxy servers are involved. + +.. + +.. bpo: 0 +.. date: 9799 +.. nonce: PVZStR +.. section: Library + +lib2to3.pgen3.driver.load_grammar() now creates a stable cache file between +runs given the same Grammar.txt input regardless of the hash randomization +setting. + +.. + +.. bpo: 27570 +.. date: 9798 +.. nonce: pU0Zie +.. section: Library + +Avoid zero-length memcpy() etc calls with null source pointers in the +"ctypes" and "array" modules. + +.. + +.. bpo: 22233 +.. date: 9797 +.. nonce: uXSN0R +.. section: Library + +Break email header lines *only* on the RFC specified CR and LF characters, +not on arbitrary unicode line breaks. This also fixes a bug in HTTP header +parsing. + +.. + +.. bpo: 27988 +.. date: 9796 +.. nonce: VfMzZH +.. section: Library + +Fix email iter_attachments incorrect mutation of payload list. + +.. + +.. bpo: 27691 +.. date: 9795 +.. nonce: TMYF5_ +.. section: Library + +Fix ssl module's parsing of GEN_RID subject alternative name fields in X.509 +certs. + +.. + +.. bpo: 27850 +.. date: 9794 +.. nonce: kIVQ0m +.. section: Library + +Remove 3DES from ssl module's default cipher list to counter measure sweet32 +attack (CVE-2016-2183). + +.. + +.. bpo: 27766 +.. date: 9793 +.. nonce: WI70Tc +.. section: Library + +Add ChaCha20 Poly1305 to ssl module's default cipher list. (Required OpenSSL +1.1.0 or LibreSSL). + +.. + +.. bpo: 26470 +.. date: 9792 +.. nonce: QGu_wo +.. section: Library + +Port ssl and hashlib module to OpenSSL 1.1.0. + +.. + +.. bpo: 0 +.. date: 9791 +.. nonce: 6TjEgz +.. section: Library + +Remove support for passing a file descriptor to os.access. It never worked +but previously didn't raise. + +.. + +.. bpo: 12885 +.. date: 9790 +.. nonce: r-IV1g +.. section: Library + +Fix error when distutils encounters symlink. + +.. + +.. bpo: 27881 +.. date: 9789 +.. nonce: fkETd9 +.. section: Library + +Fixed possible bugs when setting sqlite3.Connection.isolation_level. Based +on patch by Xiang Zhang. + +.. + +.. bpo: 27861 +.. date: 9788 +.. nonce: DBYuo9 +.. section: Library + +Fixed a crash in sqlite3.Connection.cursor() when a factory creates not a +cursor. Patch by Xiang Zhang. + +.. + +.. bpo: 19884 +.. date: 9787 +.. nonce: MO8AWH +.. section: Library + +Avoid spurious output on OS X with Gnu Readline. + +.. + +.. bpo: 27706 +.. date: 9786 +.. nonce: ZY67yu +.. section: Library + +Restore deterministic behavior of random.Random().seed() for string seeds +using seeding version 1. Allows sequences of calls to random() to exactly +match those obtained in Python 2. Patch by Nofar Schnider. + +.. + +.. bpo: 10513 +.. date: 9785 +.. nonce: tQIQD_ +.. section: Library + +Fix a regression in Connection.commit(). Statements should not be reset +after a commit. + +.. + +.. bpo: 0 +.. date: 9784 +.. nonce: cYraeH +.. section: Library + +A new version of typing.py from https://github.com/python/typing: +Collection (only for 3.6) (Issue #27598). Add FrozenSet to __all__ +(upstream #261). Fix crash in _get_type_vars() (upstream #259). Remove the +dict constraint in ForwardRef._eval_type (upstream #252). + +.. + +.. bpo: 27539 +.. date: 9783 +.. nonce: S4L1cq +.. section: Library + +Fix unnormalised ``Fraction.__pow__`` result in the case of negative +exponent and negative base. + +.. + +.. bpo: 21718 +.. date: 9782 +.. nonce: FUJd-7 +.. section: Library + +cursor.description is now available for queries using CTEs. + +.. + +.. bpo: 2466 +.. date: 9781 +.. nonce: VRNlkg +.. section: Library + +posixpath.ismount now correctly recognizes mount points which the user does +not have permission to access. + +.. + +.. bpo: 27773 +.. date: 9780 +.. nonce: hMSSeX +.. section: Library + +Correct some memory management errors server_hostname in _ssl.wrap_socket(). + +.. + +.. bpo: 26750 +.. date: 9779 +.. nonce: rv76vt +.. section: Library + +unittest.mock.create_autospec() now works properly for subclasses of +property() and other data descriptors. + +.. + +.. bpo: 0 +.. date: 9778 +.. nonce: Ny9oPv +.. section: Library + +In the curses module, raise an error if window.getstr() or window.instr() is +passed a negative value. + +.. + +.. bpo: 27783 +.. date: 9777 +.. nonce: cR1jXH +.. section: Library + +Fix possible usage of uninitialized memory in operator.methodcaller. + +.. + +.. bpo: 27774 +.. date: 9776 +.. nonce: FDcik1 +.. section: Library + +Fix possible Py_DECREF on unowned object in _sre. + +.. + +.. bpo: 27760 +.. date: 9775 +.. nonce: gxMjp4 +.. section: Library + +Fix possible integer overflow in binascii.b2a_qp. + +.. + +.. bpo: 27758 +.. date: 9774 +.. nonce: 0NRV03 +.. section: Library + +Fix possible integer overflow in the _csv module for large record lengths. + +.. + +.. bpo: 27568 +.. date: 9773 +.. nonce: OnuO9s +.. section: Library + +Prevent HTTPoxy attack (CVE-2016-1000110). Ignore the HTTP_PROXY variable +when REQUEST_METHOD environment is set, which indicates that the script is +in CGI mode. + +.. + +.. bpo: 27656 +.. date: 9772 +.. nonce: joTscM +.. section: Library + +Do not assume sched.h defines any SCHED_* constants. + +.. + +.. bpo: 27130 +.. date: 9771 +.. nonce: SUxwXZ +.. section: Library + +In the "zlib" module, fix handling of large buffers (typically 4 GiB) when +compressing and decompressing. Previously, inputs were limited to 4 GiB, +and compression and decompression operations did not properly handle results +of 4 GiB. + +.. + +.. bpo: 27533 +.. date: 9770 +.. nonce: iDmKzV +.. section: Library + +Release GIL in nt._isdir + +.. + +.. bpo: 17711 +.. date: 9769 +.. nonce: 47AILJ +.. section: Library + +Fixed unpickling by the persistent ID with protocol 0. Original patch by +Alexandre Vassalotti. + +.. + +.. bpo: 27522 +.. date: 9768 +.. nonce: 8vVz_t +.. section: Library + +Avoid an unintentional reference cycle in email.feedparser. + +.. + +.. bpo: 26844 +.. date: 9767 +.. nonce: I0wdnY +.. section: Library + +Fix error message for imp.find_module() to refer to 'path' instead of +'name'. Patch by Lev Maximov. + +.. + +.. bpo: 23804 +.. date: 9766 +.. nonce: ipFvxc +.. section: Library + +Fix SSL zero-length recv() calls to not block and not raise an error about +unclean EOF. + +.. + +.. bpo: 27466 +.. date: 9765 +.. nonce: C_3a8E +.. section: Library + +Change time format returned by http.cookie.time2netscape, confirming the +netscape cookie format and making it consistent with documentation. + +.. + +.. bpo: 26664 +.. date: 9764 +.. nonce: OzsSzf +.. section: Library + +Fix activate.fish by removing mis-use of ``$``. + +.. + +.. bpo: 22115 +.. date: 9763 +.. nonce: apoFQ9 +.. section: Library + +Fixed tracing Tkinter variables: trace_vdelete() with wrong mode no longer +break tracing, trace_vinfo() now always returns a list of pairs of strings, +tracing in the "u" mode now works. + +.. + +.. bpo: 0 +.. date: 9762 +.. nonce: oZOeFE +.. section: Library + +Fix a scoping issue in importlib.util.LazyLoader which triggered an +UnboundLocalError when lazy-loading a module that was already put into +sys.modules. + +.. + +.. bpo: 27079 +.. date: 9761 +.. nonce: c7d0Ym +.. section: Library + +Fixed curses.ascii functions isblank(), iscntrl() and ispunct(). + +.. + +.. bpo: 26754 +.. date: 9760 +.. nonce: J3n0QW +.. section: Library + +Some functions (compile() etc) accepted a filename argument encoded as an +iterable of integers. Now only strings and byte-like objects are accepted. + +.. + +.. bpo: 27048 +.. date: 9759 +.. nonce: EVe-Bk +.. section: Library + +Prevents distutils failing on Windows when environment variables contain +non-ASCII characters + +.. + +.. bpo: 27330 +.. date: 9758 +.. nonce: GJaFCV +.. section: Library + +Fixed possible leaks in the ctypes module. + +.. + +.. bpo: 27238 +.. date: 9757 +.. nonce: Q6v6Qv +.. section: Library + +Got rid of bare excepts in the turtle module. Original patch by Jelle +Zijlstra. + +.. + +.. bpo: 27122 +.. date: 9756 +.. nonce: 06t7zN +.. section: Library + +When an exception is raised within the context being managed by a +contextlib.ExitStack() and one of the exit stack generators catches and +raises it in a chain, do not re-raise the original exception when exiting, +let the new chained one through. This avoids the :pep:`479` bug described in +issue25782. + +.. + +.. bpo: 26386 +.. date: 9754 +.. nonce: 9L3Ut4 +.. section: Library + +Fixed ttk.TreeView selection operations with item id's containing spaces. + +.. + +.. bpo: 16182 +.. date: 9752 +.. nonce: RgFXyr +.. section: Library + +Fix various functions in the "readline" module to use the locale encoding, +and fix get_begidx() and get_endidx() to return code point indexes. + +.. + +.. bpo: 27392 +.. date: 9751 +.. nonce: obfni7 +.. section: Library + +Add loop.connect_accepted_socket(). Patch by Jim Fulton. + +.. + +.. bpo: 27930 +.. date: 9750 +.. nonce: BkOfSi +.. section: Library + +Improved behaviour of logging.handlers.QueueListener. Thanks to Paulo +Andrade and Petr Viktorin for the analysis and patch. + +.. + +.. bpo: 21201 +.. date: 9749 +.. nonce: wLCKiA +.. section: Library + +Improves readability of multiprocessing error message. Thanks to Wojciech +Walczak for patch. + +.. + +.. bpo: 27456 +.. date: 9748 +.. nonce: lI_IE7 +.. section: Library + +asyncio: Set TCP_NODELAY by default. + +.. + +.. bpo: 27906 +.. date: 9747 +.. nonce: TBBXrv +.. section: Library + +Fix socket accept exhaustion during high TCP traffic. Patch by Kevin Conway. + +.. + +.. bpo: 28174 +.. date: 9746 +.. nonce: CV1UdI +.. section: Library + +Handle when SO_REUSEPORT isn't properly supported. Patch by Seth Michael +Larson. + +.. + +.. bpo: 26654 +.. date: 9745 +.. nonce: XtzTE9 +.. section: Library + +Inspect functools.partial in asyncio.Handle.__repr__. Patch by iceboy. + +.. + +.. bpo: 26909 +.. date: 9744 +.. nonce: ASiakT +.. section: Library + +Fix slow pipes IO in asyncio. Patch by INADA Naoki. + +.. + +.. bpo: 28176 +.. date: 9743 +.. nonce: sU8R6L +.. section: Library + +Fix callbacks race in asyncio.SelectorLoop.sock_connect. + +.. + +.. bpo: 27759 +.. date: 9742 +.. nonce: qpMDGq +.. section: Library + +Fix selectors incorrectly retain invalid file descriptors. Patch by Mark +Williams. + +.. + +.. bpo: 28368 +.. date: 9741 +.. nonce: n594X4 +.. section: Library + +Refuse monitoring processes if the child watcher has no loop attached. Patch +by Vincent Michel. + +.. + +.. bpo: 28369 +.. date: 9740 +.. nonce: 8DTANe +.. section: Library + +Raise RuntimeError when transport's FD is used with add_reader, add_writer, +etc. + +.. + +.. bpo: 28370 +.. date: 9739 +.. nonce: 18jBuZ +.. section: Library + +Speedup asyncio.StreamReader.readexactly. Patch by Коренберг Марк. + +.. + +.. bpo: 28371 +.. date: 9738 +.. nonce: U9Zqdk +.. section: Library + +Deprecate passing asyncio.Handles to run_in_executor. + +.. + +.. bpo: 28372 +.. date: 9737 +.. nonce: njcIPk +.. section: Library + +Fix asyncio to support formatting of non-python coroutines. + +.. + +.. bpo: 28399 +.. date: 9736 +.. nonce: QKIqRX +.. section: Library + +Remove UNIX socket from FS before binding. Patch by Коренберг Марк. + +.. + +.. bpo: 27972 +.. date: 9735 +.. nonce: ZK-GFm +.. section: Library + +Prohibit Tasks to await on themselves. + +.. + +.. bpo: 26923 +.. date: 9734 +.. nonce: 8dh3AV +.. section: Library + +Fix asyncio.Gather to refuse being cancelled once all children are done. +Patch by Johannes Ebke. + +.. + +.. bpo: 26796 +.. date: 9733 +.. nonce: TZyAfJ +.. section: Library + +Don't configure the number of workers for default threadpool executor. +Initial patch by Hans Lawrenz. + +.. + +.. bpo: 28600 +.. date: 9732 +.. nonce: 2ThUQV +.. section: Library + +Optimize loop.call_soon(). + +.. + +.. bpo: 28613 +.. date: 9731 +.. nonce: sqUPrv +.. section: Library + +Fix get_event_loop() return the current loop if called from +coroutines/callbacks. + +.. + +.. bpo: 28639 +.. date: 9730 +.. nonce: WUPo1o +.. section: Library + +Fix inspect.isawaitable to always return bool Patch by Justin Mayfield. + +.. + +.. bpo: 28652 +.. date: 9729 +.. nonce: f5M8FG +.. section: Library + +Make loop methods reject socket kinds they do not support. + +.. + +.. bpo: 28653 +.. date: 9728 +.. nonce: S5bA9i +.. section: Library + +Fix a refleak in functools.lru_cache. + +.. + +.. bpo: 28703 +.. date: 9727 +.. nonce: CRLTJc +.. section: Library + +Fix asyncio.iscoroutinefunction to handle Mock objects. + +.. + +.. bpo: 24142 +.. date: 9726 +.. nonce: _BgogI +.. section: Library + +Reading a corrupt config file left the parser in an invalid state. Original +patch by Florian Höch. + +.. + +.. bpo: 28990 +.. date: 9725 +.. nonce: W8tuYZ +.. section: Library + +Fix SSL hanging if connection is closed before handshake completed. (Patch +by HoHo-Ho) + +.. + +.. bpo: 15308 +.. date: 9724 +.. nonce: zZxn8m +.. section: IDLE + +Add 'interrupt execution' (^C) to Shell menu. Patch by Roger Serwy, updated +by Bayard Randel. + +.. + +.. bpo: 27922 +.. date: 9723 +.. nonce: UEtEv9 +.. section: IDLE + +Stop IDLE tests from 'flashing' gui widgets on the screen. + +.. + +.. bpo: 0 +.. date: 9722 +.. nonce: zWZs6o +.. section: IDLE + +Add version to title of IDLE help window. + +.. + +.. bpo: 25564 +.. date: 9721 +.. nonce: GN0p14 +.. section: IDLE + +In section on IDLE -- console differences, mention that using exec means +that __builtins__ is defined for each statement. + +.. + +.. bpo: 27714 +.. date: 9720 +.. nonce: bUEDsI +.. section: IDLE + +text_textview and test_autocomplete now pass when re-run in the same +process. This occurs when test_idle fails when run with the -w option but +without -jn. Fix warning from test_config. + +.. + +.. bpo: 25507 +.. date: 9719 +.. nonce: lxf68d +.. section: IDLE + +IDLE no longer runs buggy code because of its tkinter imports. Users must +include the same imports required to run directly in Python. + +.. + +.. bpo: 27452 +.. date: 9718 +.. nonce: RtWnyR +.. section: IDLE + +add line counter and crc to IDLE configHandler test dump. + +.. + +.. bpo: 27365 +.. date: 9717 +.. nonce: y7ys_A +.. section: IDLE + +Allow non-ascii chars in IDLE NEWS.txt, for contributor names. + +.. + +.. bpo: 27245 +.. date: 9716 +.. nonce: u9aKO1 +.. section: IDLE + +IDLE: Cleanly delete custom themes and key bindings. Previously, when IDLE +was started from a console or by import, a cascade of warnings was emitted. +Patch by Serhiy Storchaka. + +.. + +.. bpo: 28808 +.. date: 9715 +.. nonce: A03X6r +.. section: C API + +PyUnicode_CompareWithASCIIString() now never raises exceptions. + +.. + +.. bpo: 26754 +.. date: 9714 +.. nonce: j2czHF +.. section: C API + +PyUnicode_FSDecoder() accepted a filename argument encoded as an iterable of +integers. Now only strings and bytes-like objects are accepted. + +.. + +.. bpo: 28513 +.. date: 9713 +.. nonce: L3joAz +.. section: Documentation + +Documented command-line interface of zipfile. + +.. + +.. bpo: 28950 +.. date: 9712 +.. nonce: 9_vY6R +.. section: Tests + +Disallow -j0 to be combined with -T/-l/-M in regrtest command line +arguments. + +.. + +.. bpo: 28666 +.. date: 9711 +.. nonce: RtTk-4 +.. section: Tests + +Now test.support.rmtree is able to remove unwritable or unreadable +directories. + +.. + +.. bpo: 23839 +.. date: 9710 +.. nonce: zsT_L9 +.. section: Tests + +Various caches now are cleared before running every test file. + +.. + +.. bpo: 28409 +.. date: 9709 +.. nonce: Q2IlxJ +.. section: Tests + +regrtest: fix the parser of command line arguments. + +.. + +.. bpo: 27787 +.. date: 9708 +.. nonce: kf0YAt +.. section: Tests + +Call gc.collect() before checking each test for "dangling threads", since +the dangling threads are weak references. + +.. + +.. bpo: 27369 +.. date: 9707 +.. nonce: LG7U2D +.. section: Tests + +In test_pyexpat, avoid testing an error message detail that changed in Expat +2.2.0. + +.. + +.. bpo: 27952 +.. date: 9706 +.. nonce: WX9Ufc +.. section: Tools/Demos + +Get Tools/scripts/fixcid.py working with Python 3 and the current "re" +module, avoid invalid Python backslash escapes, and fix a bug parsing +escaped C quote signs. + +.. + +.. bpo: 27332 +.. date: 9705 +.. nonce: OuRZp9 +.. section: Tools/Demos + +Fixed the type of the first argument of module-level functions generated by +Argument Clinic. Patch by Petr Viktorin. + +.. + +.. bpo: 27418 +.. date: 9704 +.. nonce: W2m_8I +.. section: Tools/Demos + +Fixed Tools/importbench/importbench.py. + +.. + +.. bpo: 28251 +.. date: 9703 +.. nonce: tR_AFs +.. section: Windows + +Improvements to help manuals on Windows. + +.. + +.. bpo: 28110 +.. date: 9702 +.. nonce: cnkP5F +.. section: Windows + +launcher.msi has different product codes between 32-bit and 64-bit + +.. + +.. bpo: 25144 +.. date: 9701 +.. nonce: iUha52 +.. section: Windows + +Ensures TargetDir is set before continuing with custom install. + +.. + +.. bpo: 27469 +.. date: 9700 +.. nonce: 0GwDkX +.. section: Windows + +Adds a shell extension to the launcher so that drag and drop works +correctly. + +.. + +.. bpo: 27309 +.. date: 9699 +.. nonce: 4DPjhF +.. section: Windows + +Enabled proper Windows styles in python[w].exe manifest. + +.. + +.. bpo: 29080 +.. date: 9698 +.. nonce: b3qLQT +.. section: Build + +Removes hard dependency on hg.exe from PCBuild/build.bat + +.. + +.. bpo: 23903 +.. date: 9697 +.. nonce: JXJ889 +.. section: Build + +Added missed names to PC/python3.def. + +.. + +.. bpo: 10656 +.. date: 9696 +.. nonce: pR8FFU +.. section: Build + +Fix out-of-tree building on AIX. Patch by Tristan Carel and Michael +Haubenwallner. + +.. + +.. bpo: 26359 +.. date: 9695 +.. nonce: CLz6qy +.. section: Build + +Rename --with-optimiations to --enable-optimizations. + +.. + +.. bpo: 28444 +.. date: 9694 +.. nonce: zkc9nT +.. section: Build + +Fix missing extensions modules when cross compiling. + +.. + +.. bpo: 28248 +.. date: 9693 +.. nonce: KY_-en +.. section: Build + +Update Windows build and OS X installers to use OpenSSL 1.0.2j. + +.. + +.. bpo: 28258 +.. date: 9692 +.. nonce: iKtAHd +.. section: Build + +Fixed build with Estonian locale (python-config and distclean targets in +Makefile). Patch by Arfrever Frehtes Taifersar Arahesis. + +.. + +.. bpo: 26661 +.. date: 9691 +.. nonce: Z_HNbs +.. section: Build + +setup.py now detects system libffi with multiarch wrapper. + +.. + +.. bpo: 28066 +.. date: 9690 +.. nonce: _3xImV +.. section: Build + +Fix the logic that searches build directories for generated include files +when building outside the source tree. + +.. + +.. bpo: 15819 +.. date: 9689 +.. nonce: QVDr3E +.. section: Build + +Remove redundant include search directory option for building outside the +source tree. + +.. + +.. bpo: 27566 +.. date: 9688 +.. nonce: xDWjEb +.. section: Build + +Fix clean target in freeze makefile (patch by Lisa Roach) + +.. + +.. bpo: 27705 +.. date: 9687 +.. nonce: 8C2Ms3 +.. section: Build + +Update message in validate_ucrtbase.py + +.. + +.. bpo: 27983 +.. date: 9686 +.. nonce: jL_1n8 +.. section: Build + +Cause lack of llvm-profdata tool when using clang as required for PGO +linking to be a configure time error rather than make time when +--with-optimizations is enabled. Also improve our ability to find the +llvm-profdata tool on MacOS and some Linuxes. + +.. + +.. bpo: 26307 +.. date: 9685 +.. nonce: Puk2rd +.. section: Build + +The profile-opt build now applies PGO to the built-in modules. + +.. + +.. bpo: 26359 +.. date: 9684 +.. nonce: WXBL-Y +.. section: Build + +Add the --with-optimizations configure flag. + +.. + +.. bpo: 27713 +.. date: 9683 +.. nonce: _3DgXG +.. section: Build + +Suppress spurious build warnings when updating importlib's bootstrap files. +Patch by Xiang Zhang + +.. + +.. bpo: 25825 +.. date: 9682 +.. nonce: JD8aRp +.. section: Build + +Correct the references to Modules/python.exp and ld_so_aix, which are +required on AIX. This updates references to an installation path that was +changed in 3.2a4, and undoes changed references to the build tree that were +made in 3.5.0a1. + +.. + +.. bpo: 27453 +.. date: 9681 +.. nonce: Pb5DBi +.. section: Build + +CPP invocation in configure must use CPPFLAGS. Patch by Chi Hsuan Yen. + +.. + +.. bpo: 27641 +.. date: 9680 +.. nonce: eGzgCk +.. section: Build + +The configure script now inserts comments into the makefile to prevent the +pgen and _freeze_importlib executables from being cross-compiled. + +.. + +.. bpo: 26662 +.. date: 9679 +.. nonce: XkwRxM +.. section: Build + +Set PYTHON_FOR_GEN in configure as the Python program to be used for file +generation during the build. + +.. + +.. bpo: 10910 +.. date: 9678 +.. nonce: ZdRayb +.. section: Build + +Avoid C++ compilation errors on FreeBSD and OS X. Also update FreedBSD +version checks for the original ctype UTF-8 workaround. + +.. + +.. bpo: 28676 +.. date: 9677 +.. nonce: Wxf6Ds +.. section: Build + +Prevent missing 'getentropy' declaration warning on macOS. Patch by Gareth +Rees. diff --git a/Misc/NEWS.d/3.5.4.rst b/Misc/NEWS.d/3.5.4.rst new file mode 100644 index 00000000..7839fa27 --- /dev/null +++ b/Misc/NEWS.d/3.5.4.rst @@ -0,0 +1,8 @@ +.. bpo: 30119 +.. date: 2017-07-26-15-11-17 +.. nonce: DZ6C_S +.. release date: 2017-08-07 +.. section: Library + +ftplib.FTP.putline() now throws ValueError on commands that contains CR or +LF. Patch by Donghee Na. diff --git a/Misc/NEWS.d/3.5.4rc1.rst b/Misc/NEWS.d/3.5.4rc1.rst new file mode 100644 index 00000000..d65d5d14 --- /dev/null +++ b/Misc/NEWS.d/3.5.4rc1.rst @@ -0,0 +1,1131 @@ +.. bpo: 30730 +.. date: 084 +.. nonce: rJsyTH +.. original section: Library +.. release date: 2017-07-23 +.. section: Security + +Prevent environment variables injection in subprocess on Windows. Prevent +passing other environment variables and command arguments. + +.. + +.. bpo: 30694 +.. date: 083 +.. nonce: WkMWM_ +.. original section: Library +.. section: Security + +Upgrade expat copy from 2.2.0 to 2.2.1 to get fixes of multiple security +vulnerabilities including: CVE-2017-9233 (External entity infinite loop +DoS), CVE-2016-9063 (Integer overflow, re-fix), CVE-2016-0718 (Fix +regression bugs from 2.2.0's fix to CVE-2016-0718) and CVE-2012-0876 +(Counter hash flooding with SipHash). Note: the CVE-2016-5300 (Use +os-specific entropy sources like getrandom) doesn't impact Python, since Python +already gets entropy from the OS to set the expat secret using +``XML_SetHashSalt()``. + +.. + +.. bpo: 30500 +.. date: 081 +.. nonce: 1VG7R- +.. original section: Library +.. section: Security + +Fix urllib.parse.splithost() to correctly parse fragments. For example, +``splithost('//127.0.0.1#@evil.com/')`` now correctly returns the +``127.0.0.1`` host, instead of treating ``@evil.com`` as the host in an +authentication (``login@host``). + +.. + +.. bpo: 29591 +.. date: 076 +.. nonce: ExKblw +.. original section: Library +.. section: Security + +Update expat copy from 2.1.1 to 2.2.0 to get fixes of CVE-2016-0718 and +CVE-2016-4472. See https://sourceforge.net/p/expat/bugs/537/ for more +information. + +.. + +.. bpo: 30876 +.. date: 2017-07-11-06-31-32 +.. nonce: x35jZX +.. section: Core and Builtins + +Relative import from unloaded package now reimports the package instead of +failing with SystemError. Relative import from non-package now fails with +ImportError rather than SystemError. + +.. + +.. bpo: 30765 +.. date: 2017-06-26-14-29-50 +.. nonce: Q5iBmf +.. section: Core and Builtins + +Avoid blocking in pthread_mutex_lock() when PyThread_acquire_lock() is asked +not to block. + +.. + +.. bpo: 27945 +.. date: 100 +.. nonce: p29r3O +.. section: Core and Builtins + +Fixed various segfaults with dict when input collections are mutated during +searching, inserting or comparing. Based on patches by Duane Griffin and +Tim Mitchell. + +.. + +.. bpo: 25794 +.. date: 099 +.. nonce: xfPwqm +.. section: Core and Builtins + +Fixed type.__setattr__() and type.__delattr__() for non-interned attribute +names. Based on patch by Eryk Sun. + +.. + +.. bpo: 29935 +.. date: 098 +.. nonce: vgjdJo +.. section: Core and Builtins + +Fixed error messages in the index() method of tuple, list and deque when +pass indices of wrong type. + +.. + +.. bpo: 28876 +.. date: 097 +.. nonce: cU-sGT +.. section: Core and Builtins + +``bool(range)`` works even if ``len(range)`` raises :exc:`OverflowError`. + +.. + +.. bpo: 29600 +.. date: 096 +.. nonce: 77wQ6C +.. section: Core and Builtins + +Fix wrapping coroutine return values in StopIteration. + +.. + +.. bpo: 29537 +.. date: 095 +.. nonce: lu1ysY +.. section: Core and Builtins + +Restore runtime compatibility with bytecode files generated by CPython 3.5.0 +to 3.5.2, and adjust the eval loop to avoid the problems that could be +caused by the malformed variant of the BUILD_MAP_UNPACK_WITH_CALL opcode +that they may contain. Patch by Petr Viktorin, Serhiy Storchaka, and Nick +Coghlan. + +.. + +.. bpo: 28598 +.. date: 094 +.. nonce: QxbzQn +.. section: Core and Builtins + +Support __rmod__ for subclasses of str being called before str.__mod__. +Patch by Martijn Pieters. + +.. + +.. bpo: 29602 +.. date: 093 +.. nonce: qyyskC +.. section: Core and Builtins + +Fix incorrect handling of signed zeros in complex constructor for complex +subclasses and for inputs having a __complex__ method. Patch by Serhiy +Storchaka. + +.. + +.. bpo: 29347 +.. date: 092 +.. nonce: 1RPPGN +.. section: Core and Builtins + +Fixed possibly dereferencing undefined pointers when creating weakref +objects. + +.. + +.. bpo: 29438 +.. date: 091 +.. nonce: IKxD6I +.. section: Core and Builtins + +Fixed use-after-free problem in key sharing dict. + +.. + +.. bpo: 29319 +.. date: 090 +.. nonce: KLDUZf +.. section: Core and Builtins + +Prevent RunMainFromImporter overwriting sys.path[0]. + +.. + +.. bpo: 29337 +.. date: 089 +.. nonce: bjX8AE +.. section: Core and Builtins + +Fixed possible BytesWarning when compare the code objects. Warnings could be +emitted at compile time. + +.. + +.. bpo: 29478 +.. date: 088 +.. nonce: rTQ-qy +.. section: Core and Builtins + +If max_line_length=None is specified while using the Compat32 policy, it is +no longer ignored. Patch by Mircea Cosbuc. + +.. + +.. bpo: 29403 +.. date: 2017-07-20-02-29-49 +.. nonce: 3RinCV +.. section: Library + +Fix ``unittest.mock``'s autospec to not fail on method-bound builtin +functions. Patch by Aaron Gallagher. + +.. + +.. bpo: 30961 +.. date: 2017-07-18-23-47-51 +.. nonce: 064jz0 +.. section: Library + +Fix decrementing a borrowed reference in tracemalloc. + +.. + +.. bpo: 30886 +.. date: 2017-07-10-12-14-22 +.. nonce: nqQj34 +.. section: Library + +Fix multiprocessing.Queue.join_thread(): it now waits until the thread +completes, even if the thread was started by the same process which created +the queue. + +.. + +.. bpo: 29854 +.. date: 2017-07-07-02-18-57 +.. nonce: J8wKb_ +.. section: Library + +Fix segfault in readline when using readline's history-size option. Patch +by Nir Soffer. + +.. + +.. bpo: 30807 +.. date: 2017-06-29-22-04-44 +.. nonce: sLtjY- +.. section: Library + +signal.setitimer() may disable the timer when passed a tiny value. +Tiny values (such as 1e-6) are valid non-zero values for setitimer(), which +is specified as taking microsecond-resolution intervals. However, on some +platform, our conversion routine could convert 1e-6 into a zero interval, +therefore disabling the timer instead of (re-)scheduling it. + +.. + +.. bpo: 30441 +.. date: 2017-06-29-14-25-14 +.. nonce: 3Wh9kc +.. section: Library + +Fix bug when modifying os.environ while iterating over it + +.. + +.. bpo: 30532 +.. date: 2017-06-26-11-01-59 +.. nonce: qTeL1o +.. section: Library + +Fix email header value parser dropping folding white space in certain cases. + +.. + +.. bpo: 29169 +.. date: 087 +.. nonce: 8ypApm +.. section: Library + +Update zlib to 1.2.11. + +.. + +.. bpo: 30879 +.. date: 086 +.. nonce: N3KI-o +.. section: Library + +os.listdir() and os.scandir() now emit bytes names when called with +bytes-like argument. + +.. + +.. bpo: 30746 +.. date: 085 +.. nonce: 7drQI0 +.. section: Library + +Prohibited the '=' character in environment variable names in +``os.putenv()`` and ``os.spawn*()``. + +.. + +.. bpo: 29755 +.. date: 082 +.. nonce: diQcY_ +.. section: Library + +Fixed the lgettext() family of functions in the gettext module. They now +always return bytes. + +.. + +.. bpo: 30645 +.. date: 080 +.. nonce: oYzbbW +.. section: Library + +Fix path calculation in imp.load_package(), fixing it for cases when a +package is only shipped with bytecodes. Patch by Alexandru Ardelean. + +.. + +.. bpo: 23890 +.. date: 079 +.. nonce: GCFAAZ +.. section: Library + +unittest.TestCase.assertRaises() now manually breaks a reference cycle to +not keep objects alive longer than expected. + +.. + +.. bpo: 30149 +.. date: 078 +.. nonce: hE649r +.. section: Library + +inspect.signature() now supports callables with variable-argument parameters +wrapped with partialmethod. Patch by Donghee Na. + +.. + +.. bpo: 29931 +.. date: 077 +.. nonce: tfcTwK +.. section: Library + +Fixed comparison check for ipaddress.ip_interface objects. Patch by Sanjay +Sundaresan. + +.. + +.. bpo: 24484 +.. date: 075 +.. nonce: vFem8K +.. section: Library + +Avoid race condition in multiprocessing cleanup. + +.. + +.. bpo: 28994 +.. date: 074 +.. nonce: 9vzun1 +.. section: Library + +The traceback no longer displayed for SystemExit raised in a callback +registered by atexit. + +.. + +.. bpo: 30508 +.. date: 073 +.. nonce: wNWRS2 +.. section: Library + +Don't log exceptions if Task/Future "cancel()" method was called. + +.. + +.. bpo: 28556 +.. date: 072 +.. nonce: mESP7G +.. section: Library + +Updates to typing module: Add generic AsyncContextManager, add support for +ContextManager on all versions. Original PRs by Jelle Zijlstra and Ivan +Levkivskyi + +.. + +.. bpo: 29870 +.. date: 071 +.. nonce: p960Ih +.. section: Library + +Fix ssl sockets leaks when connection is aborted in asyncio/ssl +implementation. Patch by Michaël Sghaïer. + +.. + +.. bpo: 29743 +.. date: 070 +.. nonce: en2P4s +.. section: Library + +Closing transport during handshake process leaks open socket. Patch by +Nikolay Kim + +.. + +.. bpo: 27585 +.. date: 069 +.. nonce: 0Ugqqu +.. section: Library + +Fix waiter cancellation in asyncio.Lock. Patch by Mathieu Sornay. + +.. + +.. bpo: 30418 +.. date: 068 +.. nonce: EwISQm +.. section: Library + +On Windows, subprocess.Popen.communicate() now also ignore EINVAL on +stdin.write() if the child process is still running but closed the pipe. + +.. + +.. bpo: 30378 +.. date: 067 +.. nonce: R_19_5 +.. section: Library + +Fix the problem that logging.handlers.SysLogHandler cannot handle IPv6 +addresses. + +.. + +.. bpo: 29960 +.. date: 066 +.. nonce: g0wr3r +.. section: Library + +Preserve generator state when _random.Random.setstate() raises an exception. +Patch by Bryan Olson. + +.. + +.. bpo: 30414 +.. date: 065 +.. nonce: jGl1Lb +.. section: Library + +multiprocessing.Queue._feed background running thread do not break from main +loop on exception. + +.. + +.. bpo: 30003 +.. date: 064 +.. nonce: BOl9HE +.. section: Library + +Fix handling escape characters in HZ codec. Based on patch by Ma Lin. + +.. + +.. bpo: 30301 +.. date: 063 +.. nonce: ywOkjN +.. section: Library + +Fix AttributeError when using SimpleQueue.empty() under *spawn* and +*forkserver* start methods. + +.. + +.. bpo: 30329 +.. date: 062 +.. nonce: EuT36N +.. section: Library + +imaplib and poplib now catch the Windows socket WSAEINVAL error (code 10022) +on shutdown(SHUT_RDWR): An invalid operation was attempted. This error +occurs sometimes on SSL connections. + +.. + +.. bpo: 30375 +.. date: 061 +.. nonce: 9c8qM7 +.. section: Library + +Warnings emitted when compile a regular expression now always point to the +line in the user code. Previously they could point into inners of the re +module if emitted from inside of groups or conditionals. + +.. + +.. bpo: 30048 +.. date: 060 +.. nonce: ELRx8R +.. section: Library + +Fixed ``Task.cancel()`` can be ignored when the task is running coroutine +and the coroutine returned without any more ``await``. + +.. + +.. bpo: 29990 +.. date: 059 +.. nonce: HWV6KE +.. section: Library + +Fix range checking in GB18030 decoder. Original patch by Ma Lin. + +.. + +.. bpo: 26293 +.. date: 058 +.. nonce: wig0YG +.. section: Library + +Change resulted because of zipfile breakage. (See also: bpo-29094) + +.. + +.. bpo: 30243 +.. date: 057 +.. nonce: RHQt0v +.. section: Library + +Removed the __init__ methods of _json's scanner and encoder. Misusing them +could cause memory leaks or crashes. Now scanner and encoder objects are +completely initialized in the __new__ methods. + +.. + +.. bpo: 30185 +.. date: 056 +.. nonce: Tiu1n8 +.. section: Library + +Avoid KeyboardInterrupt tracebacks in forkserver helper process when Ctrl-C +is received. + +.. + +.. bpo: 28556 +.. date: 055 +.. nonce: 51gjbP +.. section: Library + +Various updates to typing module: add typing.NoReturn type, use +WrapperDescriptorType, minor bug-fixes. Original PRs by Jim +Fasarakis-Hilliard and Ivan Levkivskyi. + +.. + +.. bpo: 30205 +.. date: 054 +.. nonce: BsxO34 +.. section: Library + +Fix getsockname() for unbound AF_UNIX sockets on Linux. + +.. + +.. bpo: 30070 +.. date: 053 +.. nonce: XM_B41 +.. section: Library + +Fixed leaks and crashes in errors handling in the parser module. + +.. + +.. bpo: 30061 +.. date: 052 +.. nonce: 2w_dX9 +.. section: Library + +Fixed crashes in IOBase methods __next__() and readlines() when readline() +or __next__() respectively return non-sizeable object. Fixed possible other +errors caused by not checking results of PyObject_Size(), PySequence_Size(), +or PyMapping_Size(). + +.. + +.. bpo: 30068 +.. date: 051 +.. nonce: n4q47r +.. section: Library + +_io._IOBase.readlines will check if it's closed first when hint is present. + +.. + +.. bpo: 29694 +.. date: 050 +.. nonce: LWKxb1 +.. section: Library + +Fixed race condition in pathlib mkdir with flags parents=True. Patch by +Armin Rigo. + +.. + +.. bpo: 29692 +.. date: 049 +.. nonce: oyWrAE +.. section: Library + +Fixed arbitrary unchaining of RuntimeError exceptions in +contextlib.contextmanager. Patch by Siddharth Velankar. + +.. + +.. bpo: 29998 +.. date: 048 +.. nonce: poeIKD +.. section: Library + +Pickling and copying ImportError now preserves name and path attributes. + +.. + +.. bpo: 29942 +.. date: 047 +.. nonce: CsGNuT +.. section: Library + +Fix a crash in itertools.chain.from_iterable when encountering long runs of +empty iterables. + +.. + +.. bpo: 27863 +.. date: 046 +.. nonce: pPYHHI +.. section: Library + +Fixed multiple crashes in ElementTree caused by race conditions and wrong +types. + +.. + +.. bpo: 28699 +.. date: 045 +.. nonce: wZztZP +.. section: Library + +Fixed a bug in pools in multiprocessing.pool that raising an exception at +the very first of an iterable may swallow the exception or make the program +hang. Patch by Davin Potts and Xiang Zhang. + +.. + +.. bpo: 25803 +.. date: 044 +.. nonce: CPDR0W +.. section: Library + +Avoid incorrect errors raised by Path.mkdir(exist_ok=True) when the OS gives +priority to errors such as EACCES over EEXIST. + +.. + +.. bpo: 29861 +.. date: 043 +.. nonce: t2ZoRK +.. section: Library + +Release references to tasks, their arguments and their results as soon as +they are finished in multiprocessing.Pool. + +.. + +.. bpo: 29884 +.. date: 042 +.. nonce: kWXR8W +.. section: Library + +faulthandler: Restore the old sigaltstack during teardown. Patch by +Christophe Zeitouny. + +.. + +.. bpo: 25455 +.. date: 041 +.. nonce: ZsahHN +.. section: Library + +Fixed crashes in repr of recursive buffered file-like objects. + +.. + +.. bpo: 29800 +.. date: 040 +.. nonce: d2xASa +.. section: Library + +Fix crashes in partial.__repr__ if the keys of partial.keywords are not +strings. Patch by Michael Seifert. + +.. + +.. bpo: 29742 +.. date: 039 +.. nonce: 8hqfEO +.. section: Library + +get_extra_info() raises exception if get called on closed ssl transport. +Patch by Nikolay Kim. + +.. + +.. bpo: 8256 +.. date: 038 +.. nonce: jAwGQH +.. section: Library + +Fixed possible failing or crashing input() if attributes "encoding" or +"errors" of sys.stdin or sys.stdout are not set or are not strings. + +.. + +.. bpo: 28298 +.. date: 037 +.. nonce: xfm84U +.. section: Library + +Fix a bug that prevented array 'Q', 'L' and 'I' from accepting big intables +(objects that have __int__) as elements. Patch by Oren Milman. + +.. + +.. bpo: 29615 +.. date: 036 +.. nonce: OpFKzg +.. section: Library + +SimpleXMLRPCDispatcher no longer chains KeyError (or any other exception) to +exception(s) raised in the dispatched methods. Patch by Petr Motejlek. + +.. + +.. bpo: 29704 +.. date: 035 +.. nonce: WHbx27 +.. section: Library + +asyncio.subprocess.SubprocessStreamProtocol no longer closes before all +pipes are closed. + +.. + +.. bpo: 29703 +.. date: 034 +.. nonce: ZdsPCR +.. section: Library + +Fix asyncio to support instantiation of new event loops in child processes. + +.. + +.. bpo: 29376 +.. date: 033 +.. nonce: rrJhJy +.. section: Library + +Fix assertion error in threading._DummyThread.is_alive(). + +.. + +.. bpo: 29110 +.. date: 032 +.. nonce: wmE-_T +.. section: Library + +Fix file object leak in aifc.open() when file is given as a filesystem path +and is not in valid AIFF format. Patch by Anthony Zhang. + +.. + +.. bpo: 28961 +.. date: 031 +.. nonce: Rt93vg +.. section: Library + +Fix unittest.mock._Call helper: don't ignore the name parameter anymore. +Patch written by Jiajun Huang. + +.. + +.. bpo: 29532 +.. date: 030 +.. nonce: YCwVQn +.. section: Library + +Altering a kwarg dictionary passed to functools.partial() no longer affects +a partial object after creation. + +.. + +.. bpo: 28556 +.. date: 029 +.. nonce: p6967e +.. section: Library + +Various updates to typing module: typing.Counter, typing.ChainMap, improved +ABC caching, etc. Original PRs by Jelle Zijlstra, Ivan Levkivskyi, Manuel +Krebber, and Łukasz Langa. + +.. + +.. bpo: 29100 +.. date: 028 +.. nonce: LAAERS +.. section: Library + +Fix datetime.fromtimestamp() regression introduced in Python 3.6.0: check +minimum and maximum years. + +.. + +.. bpo: 29519 +.. date: 027 +.. nonce: oGGgZ4 +.. section: Library + +Fix weakref spewing exceptions during interpreter shutdown when used with a +rare combination of multiprocessing and custom codecs. + +.. + +.. bpo: 29416 +.. date: 026 +.. nonce: KJGyI_ +.. section: Library + +Prevent infinite loop in pathlib.Path.mkdir + +.. + +.. bpo: 29444 +.. date: 025 +.. nonce: cEwgmk +.. section: Library + +Fixed out-of-bounds buffer access in the group() method of the match object. +Based on patch by WGH. + +.. + +.. bpo: 29335 +.. date: 024 +.. nonce: _KC7IK +.. section: Library + +Fix subprocess.Popen.wait() when the child process has exited to a stopped +instead of terminated state (ex: when under ptrace). + +.. + +.. bpo: 29290 +.. date: 023 +.. nonce: XBqptF +.. section: Library + +Fix a regression in argparse that help messages would wrap at non-breaking +spaces. + +.. + +.. bpo: 28735 +.. date: 022 +.. nonce: admHLO +.. section: Library + +Fixed the comparison of mock.MagickMock with mock.ANY. + +.. + +.. bpo: 29011 +.. date: 021 +.. nonce: MI5f2R +.. section: Library + +Fix an important omission by adding Deque to the typing module. + +.. + +.. bpo: 29219 +.. date: 020 +.. nonce: kxui7t +.. section: Library + +Fixed infinite recursion in the repr of uninitialized ctypes.CDLL instances. + +.. + +.. bpo: 28969 +.. date: 019 +.. nonce: j3HJYO +.. section: Library + +Fixed race condition in C implementation of functools.lru_cache. KeyError +could be raised when cached function with full cache was simultaneously +called from different threads with the same uncached arguments. + +.. + +.. bpo: 29142 +.. date: 018 +.. nonce: xo6kAv +.. section: Library + +In urllib.request, suffixes in no_proxy environment variable with leading +dots could match related hostnames again (e.g. .b.c matches a.b.c). Patch by +Milan Oberkirch. + +.. + +.. bpo: 30176 +.. date: 013 +.. nonce: VivmCg +.. section: Documentation + +Add missing attribute related constants in curses documentation. + +.. + +.. bpo: 26985 +.. date: 012 +.. nonce: NB5_9S +.. section: Documentation + +Add missing info of code object in inspect documentation. + +.. + +.. bpo: 28929 +.. date: 011 +.. nonce: Md7kb0 +.. section: Documentation + +Link the documentation to its source file on GitHub. + +.. + +.. bpo: 25008 +.. date: 010 +.. nonce: CeIzyU +.. section: Documentation + +Document smtpd.py as effectively deprecated and add a pointer to aiosmtpd, a +third-party asyncio-based replacement. + +.. + +.. bpo: 26355 +.. date: 009 +.. nonce: SDq_8Y +.. section: Documentation + +Add canonical header link on each page to corresponding major version of the +documentation. Patch by Matthias Bussonnier. + +.. + +.. bpo: 29349 +.. date: 008 +.. nonce: PjSo-t +.. section: Documentation + +Fix Python 2 syntax in code for building the documentation. + +.. + +.. bpo: 30822 +.. date: 2017-07-20-14-29-54 +.. nonce: X0wREo +.. section: Tests + +Fix regrtest command line parser to allow passing -u extralargefile to run +test_zipfile64. + +.. + +.. bpo: 30383 +.. date: 2017-06-27-13-52-43 +.. nonce: rCmrv7 +.. section: Tests + +regrtest: Enhance regrtest and backport features from the master branch. +Add options: --coverage, --testdir, --list-tests (list test files, don't run +them), --list-cases (list test identifiers, don't run them, :issue:`30523`), +--matchfile (load a list of test filters from a text file, :issue:`30540`), +--slowest (alias to --slow). +Enhance output: add timestamp, test result, currently running tests, "Tests +result: xxx" summary with total duration, etc. +Fix reference leak hunting in regrtest, --huntrleaks: regrtest now warms up +caches, create explicitly all internal singletons which are created on +demand to prevent false positives when checking for reference leaks. +(:issue:`30675`). + +.. + +.. bpo: 30357 +.. date: 004 +.. nonce: n4CPEa +.. section: Tests + +test_thread: setUp() now uses support.threading_setup() and +support.threading_cleanup() to wait until threads complete to avoid random +side effects on following tests. Initial patch written by Grzegorz Grzywacz. + +.. + +.. bpo: 28087 +.. date: 003 +.. nonce: m8dc4R +.. section: Tests + +Skip test_asyncore and test_eintr poll failures on macOS. Skip some tests of +select.poll when running on macOS due to unresolved issues with the +underlying system poll function on some macOS versions. + +.. + +.. bpo: 30197 +.. date: 002 +.. nonce: c5wRfu +.. section: Tests + +Enhanced functions swap_attr() and swap_item() in the test.support module. +They now work when delete replaced attribute or item inside the with +statement. The old value of the attribute or item (or None if it doesn't +exist) now will be assigned to the target of the "as" clause, if there is +one. + +.. + +.. bpo: 29571 +.. date: 001 +.. nonce: r6Dixr +.. section: Tests + +to match the behaviour of the ``re.LOCALE`` flag, test_re.test_locale_flag +now uses ``locale.getpreferredencoding(False)`` to determine the candidate +encoding for the test regex (allowing it to correctly skip the test when the +default locale encoding is a multi-byte encoding) + +.. + +.. bpo: 29243 +.. date: 007 +.. nonce: WDK4hT +.. section: Build + +Prevent unnecessary rebuilding of Python during ``make test``, ``make +install`` and some other make targets when configured with +``--enable-optimizations``. + +.. + +.. bpo: 23404 +.. date: 006 +.. nonce: PdYVWg +.. section: Build + +Don't regenerate generated files based on file modification time anymore: +the action is now explicit. Replace ``make touch`` with ``make regen-all``. + +.. + +.. bpo: 29643 +.. date: 005 +.. nonce: 4WLIJQ +.. section: Build + +Fix ``--enable-optimization`` didn't work. + +.. + +.. bpo: 30687 +.. date: 017 +.. nonce: 8mqHnu +.. section: Windows + +Locate msbuild.exe on Windows when building rather than vcvarsall.bat + +.. + +.. bpo: 29392 +.. date: 016 +.. nonce: OtqS5t +.. section: Windows + +Prevent crash when passing invalid arguments into msvcrt module. + +.. + +.. bpo: 27867 +.. date: 015 +.. nonce: VMCoJU +.. section: C API + +Function PySlice_GetIndicesEx() is replaced with a macro if Py_LIMITED_API +is set to the value between 0x03050400 and 0x03060000 (not including) or +0x03060100 or higher. + +.. + +.. bpo: 29083 +.. date: 014 +.. nonce: tGTjr_ +.. section: C API + +Fixed the declaration of some public API functions. PyArg_VaParse() and +PyArg_VaParseTupleAndKeywords() were not available in limited API. +PyArg_ValidateKeywordArguments(), PyArg_UnpackTuple() and Py_BuildValue() +were not available in limited API of version < 3.3 when PY_SSIZE_T_CLEAN is +defined. diff --git a/Misc/NEWS.d/3.5.5.rst b/Misc/NEWS.d/3.5.5.rst new file mode 100644 index 00000000..9d739259 --- /dev/null +++ b/Misc/NEWS.d/3.5.5.rst @@ -0,0 +1,8 @@ +.. bpo: 0 +.. date: 2018-02-04 +.. no changes: True +.. nonce: G9yme3 +.. release date: 2018-02-04 +.. section: Library + +There were no new changes in version 3.5.5. diff --git a/Misc/NEWS.d/3.5.5rc1.rst b/Misc/NEWS.d/3.5.5rc1.rst new file mode 100644 index 00000000..9ccbf7b8 --- /dev/null +++ b/Misc/NEWS.d/3.5.5rc1.rst @@ -0,0 +1,72 @@ +.. bpo: 32551 +.. date: 2018-01-16-16-05-37 +.. nonce: U0z4W- +.. release date: 2018-01-23 +.. section: Security + +The ``sys.path[0]`` initialization change for bpo-29139 caused a regression +by revealing an inconsistency in how sys.path is initialized when executing +``__main__`` from a zipfile, directory, or other import location. This is +considered a potential security issue, as it may lead to privileged +processes unexpectedly loading code from user controlled directories in +situations where that was not previously the case. +The interpreter now consistently avoids ever adding the import location's +parent directory to ``sys.path``, and ensures no other ``sys.path`` entries +are inadvertently modified when inserting the import location named on the +command line. (Originally reported as bpo-29723 against Python 3.6rc1, but +it was missed at the time that the then upcoming Python 3.5.4 release would +also be affected) + +.. + +.. bpo: 30657 +.. date: 2017-12-01-18-51-03 +.. nonce: Fd8kId +.. section: Security + +Fixed possible integer overflow in PyBytes_DecodeEscape, CVE-2017-1000158. +Original patch by Jay Bosamiya; rebased to Python 3 by Miro Hrončok. + +.. + +.. bpo: 30947 +.. date: 2017-09-05-20-34-44 +.. nonce: iNMmm4 +.. section: Security + +Upgrade libexpat embedded copy from version 2.2.1 to 2.2.3 to get security +fixes. + +.. + +.. bpo: 31095 +.. date: 2017-08-01-18-48-30 +.. nonce: bXWZDb +.. section: Core and Builtins + +Fix potential crash during GC caused by ``tp_dealloc`` which doesn't call +``PyObject_GC_UnTrack()``. + +.. + +.. bpo: 32072 +.. date: 2017-11-18-21-13-52 +.. nonce: nwDV8L +.. section: Library + +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: 31170 +.. date: 2017-09-05-20-35-21 +.. nonce: QGmJ1t +.. section: Library + +expat: Update libexpat from 2.2.3 to 2.2.4. Fix copying of partial +characters for UTF-8 input (libexpat bug 115): +https://github.com/libexpat/libexpat/issues/115 diff --git a/Misc/NEWS.d/3.6.0.rst b/Misc/NEWS.d/3.6.0.rst new file mode 100644 index 00000000..f9805cab --- /dev/null +++ b/Misc/NEWS.d/3.6.0.rst @@ -0,0 +1,7 @@ +.. bpo: 0 +.. date: 9796 +.. no changes: True +.. nonce: F9ENBV +.. release date: 2016-12-23 + +No changes since release candidate 2 diff --git a/Misc/NEWS.d/3.6.0a1.rst b/Misc/NEWS.d/3.6.0a1.rst new file mode 100644 index 00000000..98f1215f --- /dev/null +++ b/Misc/NEWS.d/3.6.0a1.rst @@ -0,0 +1,3940 @@ +.. release date: 2016-05-16 +.. bpo: 26657 +.. date: 9135 +.. nonce: C_-XFg +.. original section: Library +.. section: Security + +Fix directory traversal vulnerability with http.server on Windows. This +fixes a regression that was introduced in 3.3.4rc1 and 3.4.0rc1. Based on +patch by Philipp Hagemeister. + +.. + +.. bpo: 26313 +.. date: 9102 +.. nonce: LjZAjy +.. original section: Library +.. section: Security + +ssl.py _load_windows_store_certs fails if windows cert store is empty. Patch +by Baji. + +.. + +.. bpo: 25939 +.. date: 9076 +.. nonce: X49Fqd +.. original section: Library +.. section: Security + +On Windows open the cert store readonly in ssl.enum_certificates. + +.. + +.. bpo: 20041 +.. date: 9253 +.. nonce: TypyGp +.. section: Core and Builtins + +Fixed TypeError when frame.f_trace is set to None. Patch by Xavier de Gaye. + +.. + +.. bpo: 26168 +.. date: 9252 +.. nonce: -nPBL6 +.. section: Core and Builtins + +Fixed possible refleaks in failing Py_BuildValue() with the "N" format unit. + +.. + +.. bpo: 26991 +.. date: 9251 +.. nonce: yWGNhz +.. section: Core and Builtins + +Fix possible refleak when creating a function with annotations. + +.. + +.. bpo: 27039 +.. date: 9250 +.. nonce: oO-wLV +.. section: Core and Builtins + +Fixed bytearray.remove() for values greater than 127. Based on patch by Joe +Jevnik. + +.. + +.. bpo: 23640 +.. date: 9249 +.. nonce: kvNC4c +.. section: Core and Builtins + +int.from_bytes() no longer bypasses constructors for subclasses. + +.. + +.. bpo: 27005 +.. date: 9248 +.. nonce: ZtcJf- +.. section: Core and Builtins + +Optimized the float.fromhex() class method for exact float. It is now 2 +times faster. + +.. + +.. bpo: 18531 +.. date: 9247 +.. nonce: PkXgtO +.. section: Core and Builtins + +Single var-keyword argument of dict subtype was passed unscathed to the +C-defined function. Now it is converted to exact dict. + +.. + +.. bpo: 26811 +.. date: 9246 +.. nonce: oNzUWt +.. section: Core and Builtins + +gc.get_objects() no longer contains a broken tuple with NULL pointer. + +.. + +.. bpo: 20120 +.. date: 9245 +.. nonce: c-FZZc +.. section: Core and Builtins + +Use RawConfigParser for .pypirc parsing, removing support for interpolation +unintentionally added with move to Python 3. Behavior no longer does any +interpolation in .pypirc files, matching behavior in Python 2.7 and +Setuptools 19.0. + +.. + +.. bpo: 26249 +.. date: 9244 +.. nonce: ZbpWF3 +.. section: Core and Builtins + +Memory functions of the :c:func:`PyMem_Malloc` domain +(:c:macro:`PYMEM_DOMAIN_MEM`) now use the :ref:`pymalloc allocator +<pymalloc>` rather than system :c:func:`malloc`. Applications calling +:c:func:`PyMem_Malloc` without holding the GIL can now crash: use +``PYTHONMALLOC=debug`` environment variable to validate the usage of memory +allocators in your application. + +.. + +.. bpo: 26802 +.. date: 9243 +.. nonce: hWpU4v +.. section: Core and Builtins + +Optimize function calls only using unpacking like ``func(*tuple)`` (no other +positional argument, no keyword): avoid copying the tuple. Patch written by +Joe Jevnik. + +.. + +.. bpo: 26659 +.. date: 9242 +.. nonce: 5PRa83 +.. section: Core and Builtins + +Make the builtin slice type support cycle collection. + +.. + +.. bpo: 26718 +.. date: 9241 +.. nonce: K5PQ8j +.. section: Core and Builtins + +super.__init__ no longer leaks memory if called multiple times. NOTE: A +direct call of super.__init__ is not endorsed! + +.. + +.. bpo: 27138 +.. date: 9240 +.. nonce: ifYEro +.. section: Core and Builtins + +Fix the doc comment for FileFinder.find_spec(). + +.. + +.. bpo: 27147 +.. date: 9239 +.. nonce: tCCgmH +.. section: Core and Builtins + +Mention :pep:`420` in the importlib docs. + +.. + +.. bpo: 25339 +.. date: 9238 +.. nonce: ZcaC2E +.. section: Core and Builtins + +PYTHONIOENCODING now has priority over locale in setting the error handler +for stdin and stdout. + +.. + +.. bpo: 26494 +.. date: 9237 +.. nonce: G6eXIi +.. section: Core and Builtins + +Fixed crash on iterating exhausting iterators. Affected classes are generic +sequence iterators, iterators of str, bytes, bytearray, list, tuple, set, +frozenset, dict, OrderedDict, corresponding views and os.scandir() iterator. + +.. + +.. bpo: 26574 +.. date: 9236 +.. nonce: D2YL_w +.. section: Core and Builtins + +Optimize ``bytes.replace(b'', b'.')`` and ``bytearray.replace(b'', b'.')``. +Patch written by Josh Snider. + +.. + +.. bpo: 26581 +.. date: 9235 +.. nonce: yNA7nm +.. section: Core and Builtins + +If coding cookie is specified multiple times on a line in Python source code +file, only the first one is taken to account. + +.. + +.. bpo: 19711 +.. date: 9234 +.. nonce: gDDPJE +.. section: Core and Builtins + +Add tests for reloading namespace packages. + +.. + +.. bpo: 21099 +.. date: 9233 +.. nonce: CuMWZJ +.. section: Core and Builtins + +Switch applicable importlib tests to use :pep:`451` API. + +.. + +.. bpo: 26563 +.. date: 9232 +.. nonce: lyrB2Q +.. section: Core and Builtins + +Debug hooks on Python memory allocators now raise a fatal error if functions +of the :c:func:`PyMem_Malloc` family are called without holding the GIL. + +.. + +.. bpo: 26564 +.. date: 9231 +.. nonce: xeRXaz +.. section: Core and Builtins + +On error, the debug hooks on Python memory allocators now use the +:mod:`tracemalloc` module to get the traceback where a memory block was +allocated. + +.. + +.. bpo: 26558 +.. date: 9230 +.. nonce: s05jz7 +.. section: Core and Builtins + +The debug hooks on Python memory allocator :c:func:`PyObject_Malloc` now +detect when functions are called without holding the GIL. + +.. + +.. bpo: 26516 +.. date: 9229 +.. nonce: OjekqZ +.. section: Core and Builtins + +Add :envvar:`PYTHONMALLOC` environment variable to set the Python memory +allocators and/or install debug hooks. + +.. + +.. bpo: 26516 +.. date: 9228 +.. nonce: chNJuF +.. section: Core and Builtins + +The :c:func:`PyMem_SetupDebugHooks` function can now also be used on Python +compiled in release mode. + +.. + +.. bpo: 26516 +.. date: 9227 +.. nonce: q7fu1f +.. section: Core and Builtins + +The :envvar:`PYTHONMALLOCSTATS` environment variable can now also be used on +Python compiled in release mode. It now has no effect if set to an empty +string. + +.. + +.. bpo: 26516 +.. date: 9226 +.. nonce: 2k9k6R +.. section: Core and Builtins + +In debug mode, debug hooks are now also installed on Python memory +allocators when Python is configured without pymalloc. + +.. + +.. bpo: 26464 +.. date: 9225 +.. nonce: 7BreGz +.. section: Core and Builtins + +Fix str.translate() when string is ASCII and first replacements removes +character, but next replacement uses a non-ASCII character or a string +longer than 1 character. Regression introduced in Python 3.5.0. + +.. + +.. bpo: 22836 +.. date: 9224 +.. nonce: cimt1y +.. section: Core and Builtins + +Ensure exception reports from PyErr_Display() and PyErr_WriteUnraisable() +are sensible even when formatting them produces secondary errors. This +affects the reports produced by sys.__excepthook__() and when __del__() +raises an exception. + +.. + +.. bpo: 26302 +.. date: 9223 +.. nonce: UD9XQt +.. section: Core and Builtins + +Correct behavior to reject comma as a legal character for cookie names. + +.. + +.. bpo: 26136 +.. date: 9222 +.. nonce: eZ0t1K +.. section: Core and Builtins + +Upgrade the warning when a generator raises StopIteration from +PendingDeprecationWarning to DeprecationWarning. Patch by Anish Shah. + +.. + +.. bpo: 26204 +.. date: 9221 +.. nonce: x3Zp8E +.. section: Core and Builtins + +The compiler now ignores all constant statements: bytes, str, int, float, +complex, name constants (None, False, True), Ellipsis and ast.Constant; not +only str and int. For example, ``1.0`` is now ignored in ``def f(): 1.0``. + +.. + +.. bpo: 4806 +.. date: 9220 +.. nonce: i9m3hj +.. section: Core and Builtins + +Avoid masking the original TypeError exception when using star (``*``) +unpacking in function calls. Based on patch by Hagen Fürstenau and Daniel +Urban. + +.. + +.. bpo: 26146 +.. date: 9219 +.. nonce: HKrUth +.. section: Core and Builtins + +Add a new kind of AST node: ``ast.Constant``. It can be used by external AST +optimizers, but the compiler does not emit directly such node. + +.. + +.. bpo: 23601 +.. date: 9218 +.. nonce: 2E4seG +.. section: Core and Builtins + +Sped-up allocation of dict key objects by using Python's small object +allocator. (Contributed by Julian Taylor.) + +.. + +.. bpo: 18018 +.. date: 9217 +.. nonce: XKKap3 +.. section: Core and Builtins + +Import raises ImportError instead of SystemError if a relative import is +attempted without a known parent package. + +.. + +.. bpo: 25843 +.. date: 9216 +.. nonce: NtJZie +.. section: Core and Builtins + +When compiling code, don't merge constants if they are equal but have a +different types. For example, ``f1, f2 = lambda: 1, lambda: 1.0`` is now +correctly compiled to two different functions: ``f1()`` returns ``1`` +(``int``) and ``f2()`` returns ``1.0`` (``float``), even if ``1`` and +``1.0`` are equal. + +.. + +.. bpo: 26107 +.. date: 9215 +.. nonce: q0LBMY +.. section: Core and Builtins + +The format of the ``co_lnotab`` attribute of code objects changes to support +negative line number delta. + +.. + +.. bpo: 26154 +.. date: 9214 +.. nonce: MtnRAH +.. section: Core and Builtins + +Add a new private _PyThreadState_UncheckedGet() function to get the current +Python thread state, but don't issue a fatal error if it is NULL. This new +function must be used instead of accessing directly the +_PyThreadState_Current variable. The variable is no more exposed since +Python 3.5.1 to hide the exact implementation of atomic C types, to avoid +compiler issues. + +.. + +.. bpo: 25791 +.. date: 9213 +.. nonce: gllzPw +.. section: Core and Builtins + +If __package__ != __spec__.parent or if neither __package__ or __spec__ are +defined then ImportWarning is raised. + +.. + +.. bpo: 22995 +.. date: 9212 +.. nonce: KYNKvs +.. section: Core and Builtins + +[UPDATE] Comment out the one of the pickleability tests in +_PyObject_GetState() due to regressions observed in Cython-based projects. + +.. + +.. bpo: 25961 +.. date: 9211 +.. nonce: Hdjjw0 +.. section: Core and Builtins + +Disallowed null characters in the type name. + +.. + +.. bpo: 25973 +.. date: 9210 +.. nonce: Ud__ZP +.. section: Core and Builtins + +Fix segfault when an invalid nonlocal statement binds a name starting with +two underscores. + +.. + +.. bpo: 22995 +.. date: 9209 +.. nonce: Wq0E86 +.. section: Core and Builtins + +Instances of extension types with a state that aren't subclasses of list or +dict and haven't implemented any pickle-related methods (__reduce__, +__reduce_ex__, __getnewargs__, __getnewargs_ex__, or __getstate__), can no +longer be pickled. Including memoryview. + +.. + +.. bpo: 20440 +.. date: 9208 +.. nonce: GCwOfH +.. section: Core and Builtins + +Massive replacing unsafe attribute setting code with special macro +Py_SETREF. + +.. + +.. bpo: 25766 +.. date: 9207 +.. nonce: jn93Yu +.. section: Core and Builtins + +Special method __bytes__() now works in str subclasses. + +.. + +.. bpo: 25421 +.. date: 9206 +.. nonce: c47YEL +.. section: Core and Builtins + +__sizeof__ methods of builtin types now use dynamic basic size. This allows +sys.getsize() to work correctly with their subclasses with __slots__ +defined. + +.. + +.. bpo: 25709 +.. date: 9205 +.. nonce: WwGm2k +.. section: Core and Builtins + +Fixed problem with in-place string concatenation and utf-8 cache. + +.. + +.. bpo: 5319 +.. date: 9204 +.. nonce: HxlGwI +.. section: Core and Builtins + +New Py_FinalizeEx() API allowing Python to set an exit status of 120 on +failure to flush buffered streams. + +.. + +.. bpo: 25485 +.. date: 9203 +.. nonce: 9qnaPt +.. section: Core and Builtins + +telnetlib.Telnet is now a context manager. + +.. + +.. bpo: 24097 +.. date: 9202 +.. nonce: Vt4E-i +.. section: Core and Builtins + +Fixed crash in object.__reduce__() if slot name is freed inside __getattr__. + +.. + +.. bpo: 24731 +.. date: 9201 +.. nonce: h9-hnz +.. section: Core and Builtins + +Fixed crash on converting objects with special methods __bytes__, __trunc__, +and __float__ returning instances of subclasses of bytes, int, and float to +subclasses of bytes, int, and float correspondingly. + +.. + +.. bpo: 25630 +.. date: 9200 +.. nonce: ZxzcoY +.. section: Core and Builtins + +Fix a possible segfault during argument parsing in functions that accept +filesystem paths. + +.. + +.. bpo: 23564 +.. date: 9199 +.. nonce: XHarGG +.. section: Core and Builtins + +Fixed a partially broken sanity check in the _posixsubprocess internals +regarding how fds_to_pass were passed to the child. The bug had no actual +impact as subprocess.py already avoided it. + +.. + +.. bpo: 25388 +.. date: 9198 +.. nonce: zm3uuQ +.. section: Core and Builtins + +Fixed tokenizer crash when processing undecodable source code with a null +byte. + +.. + +.. bpo: 25462 +.. date: 9197 +.. nonce: eXDzgO +.. section: Core and Builtins + +The hash of the key now is calculated only once in most operations in C +implementation of OrderedDict. + +.. + +.. bpo: 22995 +.. date: 9196 +.. nonce: 90kpuP +.. section: Core and Builtins + +Default implementation of __reduce__ and __reduce_ex__ now rejects builtin +types with not defined __new__. + +.. + +.. bpo: 24802 +.. date: 9195 +.. nonce: Qie066 +.. section: Core and Builtins + +Avoid buffer overreads when int(), float(), compile(), exec() and eval() are +passed bytes-like objects. These objects are not necessarily terminated by +a null byte, but the functions assumed they were. + +.. + +.. bpo: 25555 +.. date: 9194 +.. nonce: MUpG-j +.. section: Core and Builtins + +Fix parser and AST: fill lineno and col_offset of "arg" node when compiling +AST from Python objects. + +.. + +.. bpo: 24726 +.. date: 9193 +.. nonce: AHk4v2 +.. section: Core and Builtins + +Fixed a crash and leaking NULL in repr() of OrderedDict that was mutated by +direct calls of dict methods. + +.. + +.. bpo: 25449 +.. date: 9192 +.. nonce: VqTOFi +.. section: Core and Builtins + +Iterating OrderedDict with keys with unstable hash now raises KeyError in C +implementations as well as in Python implementation. + +.. + +.. bpo: 25395 +.. date: 9191 +.. nonce: htkE3W +.. section: Core and Builtins + +Fixed crash when highly nested OrderedDict structures were garbage +collected. + +.. + +.. bpo: 25401 +.. date: 9190 +.. nonce: ofrAtd +.. section: Core and Builtins + +Optimize bytes.fromhex() and bytearray.fromhex(): they are now between 2x +and 3.5x faster. + +.. + +.. bpo: 25399 +.. date: 9189 +.. nonce: dNKIhY +.. section: Core and Builtins + +Optimize bytearray % args using the new private _PyBytesWriter API. +Formatting is now between 2.5 and 5 times faster. + +.. + +.. bpo: 25274 +.. date: 9188 +.. nonce: QCGvAF +.. section: Core and Builtins + +sys.setrecursionlimit() now raises a RecursionError if the new recursion +limit is too low depending at the current recursion depth. Modify also the +"lower-water mark" formula to make it monotonic. This mark is used to decide +when the overflowed flag of the thread state is reset. + +.. + +.. bpo: 24402 +.. date: 9187 +.. nonce: MAgi3X +.. section: Core and Builtins + +Fix input() to prompt to the redirected stdout when sys.stdout.fileno() +fails. + +.. + +.. bpo: 25349 +.. date: 9186 +.. nonce: 7lBgJ8 +.. section: Core and Builtins + +Optimize bytes % args using the new private _PyBytesWriter API. Formatting +is now up to 2 times faster. + +.. + +.. bpo: 24806 +.. date: 9185 +.. nonce: Nb0znT +.. section: Core and Builtins + +Prevent builtin types that are not allowed to be subclassed from being +subclassed through multiple inheritance. + +.. + +.. bpo: 25301 +.. date: 9184 +.. nonce: hUTCfr +.. section: Core and Builtins + +The UTF-8 decoder is now up to 15 times as fast for error handlers: +``ignore``, ``replace`` and ``surrogateescape``. + +.. + +.. bpo: 24848 +.. date: 9183 +.. nonce: HlUSuy +.. section: Core and Builtins + +Fixed a number of bugs in UTF-7 decoding of misformed data. + +.. + +.. bpo: 25267 +.. date: 9182 +.. nonce: SW8Gs6 +.. section: Core and Builtins + +The UTF-8 encoder is now up to 75 times as fast for error handlers: +``ignore``, ``replace``, ``surrogateescape``, ``surrogatepass``. Patch +co-written with Serhiy Storchaka. + +.. + +.. bpo: 25280 +.. date: 9181 +.. nonce: ivTMwd +.. section: Core and Builtins + +Import trace messages emitted in verbose (-v) mode are no longer formatted +twice. + +.. + +.. bpo: 25227 +.. date: 9180 +.. nonce: 19v5rp +.. section: Core and Builtins + +Optimize ASCII and latin1 encoders with the ``surrogateescape`` error +handler: the encoders are now up to 3 times as fast. Initial patch written +by Serhiy Storchaka. + +.. + +.. bpo: 25003 +.. date: 9179 +.. nonce: _ban92 +.. section: Core and Builtins + +On Solaris 11.3 or newer, os.urandom() now uses the getrandom() function +instead of the getentropy() function. The getentropy() function is blocking +to generate very good quality entropy, os.urandom() doesn't need such +high-quality entropy. + +.. + +.. bpo: 9232 +.. date: 9178 +.. nonce: pjsmWw +.. section: Core and Builtins + +Modify Python's grammar to allow trailing commas in the argument list of a +function declaration. For example, "def f(\*, a = 3,): pass" is now legal. +Patch from Mark Dickinson. + +.. + +.. bpo: 24965 +.. date: 9177 +.. nonce: wfyxbB +.. section: Core and Builtins + +Implement :pep:`498` "Literal String Interpolation". This allows you to embed +expressions inside f-strings, which are converted to normal strings at run +time. Given x=3, then f'value={x}' == 'value=3'. Patch by Eric V. Smith. + +.. + +.. bpo: 26478 +.. date: 9176 +.. nonce: n0dB8e +.. section: Core and Builtins + +Fix semantic bugs when using binary operators with dictionary views and +tuples. + +.. + +.. bpo: 26171 +.. date: 9175 +.. nonce: 8SaQEa +.. section: Core and Builtins + +Fix possible integer overflow and heap corruption in zipimporter.get_data(). + +.. + +.. bpo: 25660 +.. date: 9174 +.. nonce: 93DzBo +.. section: Core and Builtins + +Fix TAB key behaviour in REPL with readline. + +.. + +.. bpo: 26288 +.. date: 9173 +.. nonce: f67RLk +.. section: Core and Builtins + +Optimize PyLong_AsDouble. + +.. + +.. bpo: 26289 +.. date: 9172 +.. nonce: uG9ozG +.. section: Core and Builtins + +Optimize floor and modulo division for single-digit longs. Microbenchmarks +show 2-2.5x improvement. Built-in 'divmod' function is now also ~10% +faster. (See also: bpo-26315) + +.. + +.. bpo: 25887 +.. date: 9171 +.. nonce: PtVIX7 +.. section: Core and Builtins + +Raise a RuntimeError when a coroutine object is awaited more than once. + +.. + +.. bpo: 27057 +.. date: 9170 +.. nonce: YzTA_Q +.. section: Library + +Fix os.set_inheritable() on Android, ioctl() is blocked by SELinux and fails +with EACCESS. The function now falls back to fcntl(). Patch written by +Michał Bednarski. + +.. + +.. bpo: 27014 +.. date: 9169 +.. nonce: ui7Khn +.. section: Library + +Fix infinite recursion using typing.py. Thanks to Kalle Tuure! + +.. + +.. bpo: 27031 +.. date: 9168 +.. nonce: FtvDPs +.. section: Library + +Removed dummy methods in Tkinter widget classes: tk_menuBar() and +tk_bindForTraversal(). + +.. + +.. bpo: 14132 +.. date: 9167 +.. nonce: 5wR9MN +.. section: Library + +Fix urllib.request redirect handling when the target only has a query +string. Original fix by Ján Janech. + +.. + +.. bpo: 17214 +.. date: 9166 +.. nonce: lUbZOV +.. section: Library + +The "urllib.request" module now percent-encodes non-ASCII bytes found in +redirect target URLs. Some servers send Location header fields with +non-ASCII bytes, but "http.client" requires the request target to be +ASCII-encodable, otherwise a UnicodeEncodeError is raised. Based on patch by +Christian Heimes. + +.. + +.. bpo: 27033 +.. date: 9165 +.. nonce: o4XIPr +.. section: Library + +The default value of the decode_data parameter for smtpd.SMTPChannel and +smtpd.SMTPServer constructors is changed to False. + +.. + +.. bpo: 27034 +.. date: 9164 +.. nonce: ptzz_S +.. section: Library + +Removed deprecated class asynchat.fifo. + +.. + +.. bpo: 26870 +.. date: 9163 +.. nonce: 5tCUlp +.. section: Library + +Added readline.set_auto_history(), which can stop entries being +automatically added to the history list. Based on patch by Tyler Crompton. + +.. + +.. bpo: 26039 +.. date: 9162 +.. nonce: JnXjiE +.. section: Library + +zipfile.ZipFile.open() can now be used to write data into a ZIP file, as +well as for extracting data. Patch by Thomas Kluyver. + +.. + +.. bpo: 26892 +.. date: 9161 +.. nonce: XIXb0h +.. section: Library + +Honor debuglevel flag in urllib.request.HTTPHandler. Patch contributed by +Chi Hsuan Yen. + +.. + +.. bpo: 22274 +.. date: 9160 +.. nonce: 0RHDMN +.. section: Library + +In the subprocess module, allow stderr to be redirected to stdout even when +stdout is not redirected. Patch by Akira Li. + +.. + +.. bpo: 26807 +.. date: 9159 +.. nonce: LXSPP6 +.. section: Library + +mock_open 'files' no longer error on readline at end of file. Patch from +Yolanda Robla. + +.. + +.. bpo: 25745 +.. date: 9158 +.. nonce: -n8acU +.. section: Library + +Fixed leaking a userptr in curses panel destructor. + +.. + +.. bpo: 26977 +.. date: 9157 +.. nonce: 5G4HtL +.. section: Library + +Removed unnecessary, and ignored, call to sum of squares helper in +statistics.pvariance. + +.. + +.. bpo: 26002 +.. date: 9156 +.. nonce: bVD4pW +.. section: Library + +Use bisect in statistics.median instead of a linear search. Patch by Upendra +Kuma. + +.. + +.. bpo: 25974 +.. date: 9155 +.. nonce: cpOy5R +.. section: Library + +Make use of new Decimal.as_integer_ratio() method in statistics module. +Patch by Stefan Krah. + +.. + +.. bpo: 26996 +.. date: 9154 +.. nonce: LR__VD +.. section: Library + +Add secrets module as described in :pep:`506`. + +.. + +.. bpo: 26881 +.. date: 9153 +.. nonce: mdiq_L +.. section: Library + +The modulefinder module now supports extended opcode arguments. + +.. + +.. bpo: 23815 +.. date: 9152 +.. nonce: _krNe8 +.. section: Library + +Fixed crashes related to directly created instances of types in _tkinter and +curses.panel modules. + +.. + +.. bpo: 17765 +.. date: 9151 +.. nonce: hiSVS1 +.. section: Library + +weakref.ref() no longer silently ignores keyword arguments. Patch by Georg +Brandl. + +.. + +.. bpo: 26873 +.. date: 9150 +.. nonce: cYXRcH +.. section: Library + +xmlrpc now raises ResponseError on unsupported type tags instead of silently +return incorrect result. + +.. + +.. bpo: 26915 +.. date: 9149 +.. nonce: GoQKUL +.. section: Library + +The __contains__ methods in the collections ABCs now check for identity +before checking equality. This better matches the behavior of the concrete +classes, allows sensible handling of NaNs, and makes it easier to reason +about container invariants. + +.. + +.. bpo: 26711 +.. date: 9148 +.. nonce: Eu85Qw +.. section: Library + +Fixed the comparison of plistlib.Data with other types. + +.. + +.. bpo: 24114 +.. date: 9147 +.. nonce: RMRMtM +.. section: Library + +Fix an uninitialized variable in `ctypes.util`. +The bug only occurs on SunOS when the ctypes implementation searches for the +`crle` program. Patch by Xiang Zhang. Tested on SunOS by Kees Bos. + +.. + +.. bpo: 26864 +.. date: 9146 +.. nonce: 1KgGds +.. section: Library + +In urllib.request, change the proxy bypass host checking against no_proxy to +be case-insensitive, and to not match unrelated host names that happen to +have a bypassed hostname as a suffix. Patch by Xiang Zhang. + +.. + +.. bpo: 24902 +.. date: 9145 +.. nonce: bwWpLj +.. section: Library + +Print server URL on http.server startup. Initial patch by Felix Kaiser. + +.. + +.. bpo: 25788 +.. date: 9144 +.. nonce: 9weIV5 +.. section: Library + +fileinput.hook_encoded() now supports an "errors" argument for passing to +open. Original patch by Joseph Hackman. + +.. + +.. bpo: 26634 +.. date: 9143 +.. nonce: FZvsSb +.. section: Library + +recursive_repr() now sets __qualname__ of wrapper. Patch by Xiang Zhang. + +.. + +.. bpo: 26804 +.. date: 9142 +.. nonce: 9Orp-G +.. section: Library + +urllib.request will prefer lower_case proxy environment variables over +UPPER_CASE or Mixed_Case ones. Patch contributed by Hans-Peter Jansen. + +.. + +.. bpo: 26837 +.. date: 9141 +.. nonce: 2FXGsD +.. section: Library + +assertSequenceEqual() now correctly outputs non-stringified differing items +(like bytes in the -b mode). This affects assertListEqual() and +assertTupleEqual(). + +.. + +.. bpo: 26041 +.. date: 9140 +.. nonce: bVem-p +.. section: Library + +Remove "will be removed in Python 3.7" from deprecation messages of +platform.dist() and platform.linux_distribution(). Patch by Kumaripaba +Miyurusara Athukorala. + +.. + +.. bpo: 26822 +.. date: 9139 +.. nonce: rYSL4W +.. section: Library + +itemgetter, attrgetter and methodcaller objects no longer silently ignore +keyword arguments. + +.. + +.. bpo: 26733 +.. date: 9138 +.. nonce: YxaJmL +.. section: Library + +Disassembling a class now disassembles class and static methods. Patch by +Xiang Zhang. + +.. + +.. bpo: 26801 +.. date: 9137 +.. nonce: TQGY-7 +.. section: Library + +Fix error handling in :func:`shutil.get_terminal_size`, catch +:exc:`AttributeError` instead of :exc:`NameError`. Patch written by Emanuel +Barry. + +.. + +.. bpo: 24838 +.. date: 9136 +.. nonce: 3Pfx8T +.. section: Library + +tarfile's ustar and gnu formats now correctly calculate name and link field +limits for multibyte character encodings like utf-8. + +.. + +.. bpo: 26717 +.. date: 9134 +.. nonce: jngTdu +.. section: Library + +Stop encoding Latin-1-ized WSGI paths with UTF-8. Patch by Anthony Sottile. + +.. + +.. bpo: 26782 +.. date: 9133 +.. nonce: JWLPrH +.. section: Library + +Add STARTUPINFO to subprocess.__all__ on Windows. + +.. + +.. bpo: 26404 +.. date: 9132 +.. nonce: hXw7Bs +.. section: Library + +Add context manager to socketserver. Patch by Aviv Palivoda. + +.. + +.. bpo: 26735 +.. date: 9131 +.. nonce: riSl3b +.. section: Library + +Fix :func:`os.urandom` on Solaris 11.3 and newer when reading more than +1,024 bytes: call ``getrandom()`` multiple times with a limit of 1024 bytes +per call. + +.. + +.. bpo: 26585 +.. date: 9130 +.. nonce: kfb749 +.. section: Library + +Eliminate http.server._quote_html() and use html.escape(quote=False). Patch +by Xiang Zhang. + +.. + +.. bpo: 26685 +.. date: 9129 +.. nonce: sI_1Ff +.. section: Library + +Raise OSError if closing a socket fails. + +.. + +.. bpo: 16329 +.. date: 9128 +.. nonce: nuXD8W +.. section: Library + +Add .webm to mimetypes.types_map. Patch by Giampaolo Rodola'. + +.. + +.. bpo: 13952 +.. date: 9127 +.. nonce: SOoTVE +.. section: Library + +Add .csv to mimetypes.types_map. Patch by Geoff Wilson. + +.. + +.. bpo: 26587 +.. date: 9126 +.. nonce: Qo-B6C +.. section: Library + +the site module now allows .pth files to specify files to be added to +sys.path (e.g. zip files). + +.. + +.. bpo: 25609 +.. date: 9125 +.. nonce: t1ydQM +.. section: Library + +Introduce contextlib.AbstractContextManager and typing.ContextManager. + +.. + +.. bpo: 26709 +.. date: 9124 +.. nonce: luOPbP +.. section: Library + +Fixed Y2038 problem in loading binary PLists. + +.. + +.. bpo: 23735 +.. date: 9123 +.. nonce: Y5oQ9r +.. section: Library + +Handle terminal resizing with Readline 6.3+ by installing our own SIGWINCH +handler. Patch by Eric Price. + +.. + +.. bpo: 25951 +.. date: 9122 +.. nonce: 1CUASJ +.. section: Library + +Change SSLSocket.sendall() to return None, as explicitly documented for +plain socket objects. Patch by Aviv Palivoda. + +.. + +.. bpo: 26586 +.. date: 9121 +.. nonce: V5pZNa +.. section: Library + +In http.server, respond with "413 Request header fields too large" if there +are too many header fields to parse, rather than killing the connection and +raising an unhandled exception. Patch by Xiang Zhang. + +.. + +.. bpo: 26676 +.. date: 9120 +.. nonce: zLRFed +.. section: Library + +Added missing XMLPullParser to ElementTree.__all__. + +.. + +.. bpo: 22854 +.. date: 9119 +.. nonce: K3rMEH +.. section: Library + +Change BufferedReader.writable() and BufferedWriter.readable() to always +return False. + +.. + +.. bpo: 26492 +.. date: 9118 +.. nonce: YN18iz +.. section: Library + +Exhausted iterator of array.array now conforms with the behavior of +iterators of other mutable sequences: it lefts exhausted even if iterated +array is extended. + +.. + +.. bpo: 26641 +.. date: 9117 +.. nonce: 1ICQz0 +.. section: Library + +doctest.DocFileTest and doctest.testfile() now support packages (module +splitted into multiple directories) for the package parameter. + +.. + +.. bpo: 25195 +.. date: 9116 +.. nonce: EOc4Po +.. section: Library + +Fix a regression in mock.MagicMock. _Call is a subclass of tuple (changeset +3603bae63c13 only works for classes) so we need to implement __ne__ +ourselves. Patch by Andrew Plummer. + +.. + +.. bpo: 26644 +.. date: 9115 +.. nonce: 7tt1tk +.. section: Library + +Raise ValueError rather than SystemError when a negative length is passed to +SSLSocket.recv() or read(). + +.. + +.. bpo: 23804 +.. date: 9114 +.. nonce: PP63Ff +.. section: Library + +Fix SSL recv(0) and read(0) methods to return zero bytes instead of up to +1024. + +.. + +.. bpo: 26616 +.. date: 9113 +.. nonce: v3QwdD +.. section: Library + +Fixed a bug in datetime.astimezone() method. + +.. + +.. bpo: 26637 +.. date: 9112 +.. nonce: ttiUf7 +.. section: Library + +The :mod:`importlib` module now emits an :exc:`ImportError` rather than a +:exc:`TypeError` if :func:`__import__` is tried during the Python shutdown +process but :data:`sys.path` is already cleared (set to ``None``). + +.. + +.. bpo: 21925 +.. date: 9111 +.. nonce: xFz-hR +.. section: Library + +:func:`warnings.formatwarning` now catches exceptions when calling +:func:`linecache.getline` and :func:`tracemalloc.get_object_traceback` to be +able to log :exc:`ResourceWarning` emitted late during the Python shutdown +process. + +.. + +.. bpo: 23848 +.. date: 9110 +.. nonce: RkKqPi +.. section: Library + +On Windows, faulthandler.enable() now also installs an exception handler to +dump the traceback of all Python threads on any Windows exception, not only +on UNIX signals (SIGSEGV, SIGFPE, SIGABRT). + +.. + +.. bpo: 26530 +.. date: 9109 +.. nonce: RWN1jR +.. section: Library + +Add C functions :c:func:`_PyTraceMalloc_Track` and +:c:func:`_PyTraceMalloc_Untrack` to track memory blocks using the +:mod:`tracemalloc` module. Add :c:func:`_PyTraceMalloc_GetTraceback` to get +the traceback of an object. + +.. + +.. bpo: 26588 +.. date: 9108 +.. nonce: uen0XP +.. section: Library + +The _tracemalloc now supports tracing memory allocations of multiple address +spaces (domains). + +.. + +.. bpo: 24266 +.. date: 9107 +.. nonce: YZgVyM +.. section: Library + +Ctrl+C during Readline history search now cancels the search mode when +compiled with Readline 7. + +.. + +.. bpo: 26590 +.. date: 9106 +.. nonce: qEy91x +.. section: Library + +Implement a safe finalizer for the _socket.socket type. It now releases the +GIL to close the socket. + +.. + +.. bpo: 18787 +.. date: 9105 +.. nonce: rWyzgA +.. section: Library + +spwd.getspnam() now raises a PermissionError if the user doesn't have +privileges. + +.. + +.. bpo: 26560 +.. date: 9104 +.. nonce: A4WXNz +.. section: Library + +Avoid potential ValueError in BaseHandler.start_response. Initial patch by +Peter Inglesby. + +.. + +.. bpo: 26567 +.. date: 9103 +.. nonce: kcC99B +.. section: Library + +Add a new function :c:func:`PyErr_ResourceWarning` function to pass the +destroyed object. Add a *source* attribute to +:class:`warnings.WarningMessage`. Add warnings._showwarnmsg() which uses +tracemalloc to get the traceback where source object was allocated. + +.. + +.. bpo: 26569 +.. date: 9101 +.. nonce: EX8vF1 +.. section: Library + +Fix :func:`pyclbr.readmodule` and :func:`pyclbr.readmodule_ex` to support +importing packages. + +.. + +.. bpo: 26499 +.. date: 9100 +.. nonce: NP08PI +.. section: Library + +Account for remaining Content-Length in HTTPResponse.readline() and read1(). +Based on patch by Silent Ghost. Also document that HTTPResponse now supports +these methods. + +.. + +.. bpo: 25320 +.. date: 9099 +.. nonce: V96LIy +.. section: Library + +Handle sockets in directories unittest discovery is scanning. Patch from +Victor van den Elzen. + +.. + +.. bpo: 16181 +.. date: 9098 +.. nonce: P7lLvo +.. section: Library + +cookiejar.http2time() now returns None if year is higher than +datetime.MAXYEAR. + +.. + +.. bpo: 26513 +.. date: 9097 +.. nonce: HoPepy +.. section: Library + +Fixes platform module detection of Windows Server + +.. + +.. bpo: 23718 +.. date: 9096 +.. nonce: AMPC0o +.. section: Library + +Fixed parsing time in week 0 before Jan 1. Original patch by Tamás Bence +Gedai. + +.. + +.. bpo: 26323 +.. date: 9095 +.. nonce: KkZqEj +.. section: Library + +Add Mock.assert_called() and Mock.assert_called_once() methods to +unittest.mock. Patch written by Amit Saha. + +.. + +.. bpo: 20589 +.. date: 9094 +.. nonce: NsQ_I1 +.. section: Library + +Invoking Path.owner() and Path.group() on Windows now raise +NotImplementedError instead of ImportError. + +.. + +.. bpo: 26177 +.. date: 9093 +.. nonce: HlSWer +.. section: Library + +Fixed the keys() method for Canvas and Scrollbar widgets. + +.. + +.. bpo: 15068 +.. date: 9092 +.. nonce: xokEVC +.. section: Library + +Got rid of excessive buffering in fileinput. The bufsize parameter is now +deprecated and ignored. + +.. + +.. bpo: 19475 +.. date: 9091 +.. nonce: MH2HH9 +.. section: Library + +Added an optional argument timespec to the datetime isoformat() method to +choose the precision of the time component. + +.. + +.. bpo: 2202 +.. date: 9090 +.. nonce: dk9sd0 +.. section: Library + +Fix UnboundLocalError in AbstractDigestAuthHandler.get_algorithm_impls. +Initial patch by Mathieu Dupuy. + +.. + +.. bpo: 26167 +.. date: 9089 +.. nonce: 3F-d12 +.. section: Library + +Minimized overhead in copy.copy() and copy.deepcopy(). Optimized copying and +deepcopying bytearrays, NotImplemented, slices, short lists, tuples, dicts, +sets. + +.. + +.. bpo: 25718 +.. date: 9088 +.. nonce: 4EjZyv +.. section: Library + +Fixed pickling and copying the accumulate() iterator with total is None. + +.. + +.. bpo: 26475 +.. date: 9087 +.. nonce: JXVccY +.. section: Library + +Fixed debugging output for regular expressions with the (?x) flag. + +.. + +.. bpo: 26482 +.. date: 9086 +.. nonce: d635gW +.. section: Library + +Allowed pickling recursive dequeues. + +.. + +.. bpo: 26335 +.. date: 9085 +.. nonce: iXw5Yb +.. section: Library + +Make mmap.write() return the number of bytes written like other write +methods. Patch by Jakub Stasiak. + +.. + +.. bpo: 26457 +.. date: 9084 +.. nonce: Xe6Clh +.. section: Library + +Fixed the subnets() methods in IP network classes for the case when +resulting prefix length is equal to maximal prefix length. Based on patch by +Xiang Zhang. + +.. + +.. bpo: 26385 +.. date: 9083 +.. nonce: 50bDXm +.. section: Library + +Remove the file if the internal open() call in NamedTemporaryFile() fails. +Patch by Silent Ghost. + +.. + +.. bpo: 26402 +.. date: 9082 +.. nonce: k7DVuU +.. section: Library + +Fix XML-RPC client to retry when the server shuts down a persistent +connection. This was a regression related to the new +http.client.RemoteDisconnected exception in 3.5.0a4. + +.. + +.. bpo: 25913 +.. date: 9081 +.. nonce: 5flb95 +.. section: Library + +Leading ``<~`` is optional now in base64.a85decode() with adobe=True. Patch +by Swati Jaiswal. + +.. + +.. bpo: 26186 +.. date: 9080 +.. nonce: R9rfiL +.. section: Library + +Remove an invalid type check in importlib.util.LazyLoader. + +.. + +.. bpo: 26367 +.. date: 9079 +.. nonce: Qct-9S +.. section: Library + +importlib.__import__() raises ImportError like builtins.__import__() when +``level`` is specified but without an accompanying package specified. + +.. + +.. bpo: 26309 +.. date: 9078 +.. nonce: ubEeiz +.. section: Library + +In the "socketserver" module, shut down the request (closing the connected +socket) when verify_request() returns false. Patch by Aviv Palivoda. + +.. + +.. bpo: 23430 +.. date: 9077 +.. nonce: s_mLiA +.. section: Library + +Change the socketserver module to only catch exceptions raised from a +request handler that are derived from Exception (instead of BaseException). +Therefore SystemExit and KeyboardInterrupt no longer trigger the +handle_error() method, and will now to stop a single-threaded server. + +.. + +.. bpo: 25995 +.. date: 9075 +.. nonce: NfcimP +.. section: Library + +os.walk() no longer uses FDs proportional to the tree depth. + +.. + +.. bpo: 25994 +.. date: 9074 +.. nonce: ga9rT- +.. section: Library + +Added the close() method and the support of the context manager protocol for +the os.scandir() iterator. + +.. + +.. bpo: 23992 +.. date: 9073 +.. nonce: O0Hhvc +.. section: Library + +multiprocessing: make MapResult not fail-fast upon exception. + +.. + +.. bpo: 26243 +.. date: 9072 +.. nonce: 41WSpF +.. section: Library + +Support keyword arguments to zlib.compress(). Patch by Aviv Palivoda. + +.. + +.. bpo: 26117 +.. date: 9071 +.. nonce: ne6p11 +.. section: Library + +The os.scandir() iterator now closes file descriptor not only when the +iteration is finished, but when it was failed with error. + +.. + +.. bpo: 25949 +.. date: 9070 +.. nonce: -Lh9vz +.. section: Library + +__dict__ for an OrderedDict instance is now created only when needed. + +.. + +.. bpo: 25911 +.. date: 9069 +.. nonce: d4Zadh +.. section: Library + +Restored support of bytes paths in os.walk() on Windows. + +.. + +.. bpo: 26045 +.. date: 9068 +.. nonce: WmzUrX +.. section: Library + +Add UTF-8 suggestion to error message when posting a non-Latin-1 string with +http.client. + +.. + +.. bpo: 26039 +.. date: 9067 +.. nonce: a5Bxm4 +.. section: Library + +Added zipfile.ZipInfo.from_file() and zipinfo.ZipInfo.is_dir(). Patch by +Thomas Kluyver. + +.. + +.. bpo: 12923 +.. date: 9066 +.. nonce: HPAu-B +.. section: Library + +Reset FancyURLopener's redirect counter even if there is an exception. +Based on patches by Brian Brazil and Daniel Rocco. + +.. + +.. bpo: 25945 +.. date: 9065 +.. nonce: guNgNM +.. section: Library + +Fixed a crash when unpickle the functools.partial object with wrong state. +Fixed a leak in failed functools.partial constructor. "args" and "keywords" +attributes of functools.partial have now always types tuple and dict +correspondingly. + +.. + +.. bpo: 26202 +.. date: 9064 +.. nonce: LPIXLg +.. section: Library + +copy.deepcopy() now correctly copies range() objects with non-atomic +attributes. + +.. + +.. bpo: 23076 +.. date: 9063 +.. nonce: 8rphoP +.. section: Library + +Path.glob() now raises a ValueError if it's called with an invalid pattern. +Patch by Thomas Nyberg. + +.. + +.. bpo: 19883 +.. date: 9062 +.. nonce: z9TsO6 +.. section: Library + +Fixed possible integer overflows in zipimport. + +.. + +.. bpo: 26227 +.. date: 9061 +.. nonce: Fe6oiB +.. section: Library + +On Windows, getnameinfo(), gethostbyaddr() and gethostbyname_ex() functions +of the socket module now decode the hostname from the ANSI code page rather +than UTF-8. + +.. + +.. bpo: 26099 +.. date: 9060 +.. nonce: CH5jer +.. section: Library + +The site module now writes an error into stderr if sitecustomize module can +be imported but executing the module raise an ImportError. Same change for +usercustomize. + +.. + +.. bpo: 26147 +.. date: 9059 +.. nonce: i-Jc01 +.. section: Library + +xmlrpc now works with strings not encodable with used non-UTF-8 encoding. + +.. + +.. bpo: 25935 +.. date: 9058 +.. nonce: cyni91 +.. section: Library + +Garbage collector now breaks reference loops with OrderedDict. + +.. + +.. bpo: 16620 +.. date: 9057 +.. nonce: rxpn_Y +.. section: Library + +Fixed AttributeError in msilib.Directory.glob(). + +.. + +.. bpo: 26013 +.. date: 9056 +.. nonce: 93RKNz +.. section: Library + +Added compatibility with broken protocol 2 pickles created in old Python 3 +versions (3.4.3 and lower). + +.. + +.. bpo: 26129 +.. date: 9055 +.. nonce: g4RQZd +.. section: Library + +Deprecated accepting non-integers in grp.getgrgid(). + +.. + +.. bpo: 25850 +.. date: 9054 +.. nonce: jwFPxj +.. section: Library + +Use cross-compilation by default for 64-bit Windows. + +.. + +.. bpo: 25822 +.. date: 9053 +.. nonce: 0Eafyi +.. section: Library + +Add docstrings to the fields of urllib.parse results. Patch contributed by +Swati Jaiswal. + +.. + +.. bpo: 22642 +.. date: 9052 +.. nonce: PEgS9F +.. section: Library + +Convert trace module option parsing mechanism to argparse. Patch contributed +by SilentGhost. + +.. + +.. bpo: 24705 +.. date: 9051 +.. nonce: IZYwjR +.. section: Library + +Fix sysconfig._parse_makefile not expanding ${} vars appearing before $() +vars. + +.. + +.. bpo: 26069 +.. date: 9050 +.. nonce: NaF4lN +.. section: Library + +Remove the deprecated apis in the trace module. + +.. + +.. bpo: 22138 +.. date: 9049 +.. nonce: nRNYkc +.. section: Library + +Fix mock.patch behavior when patching descriptors. Restore original values +after patching. Patch contributed by Sean McCully. + +.. + +.. bpo: 25672 +.. date: 9048 +.. nonce: fw9RJP +.. section: Library + +In the ssl module, enable the SSL_MODE_RELEASE_BUFFERS mode option if it is +safe to do so. + +.. + +.. bpo: 26012 +.. date: 9047 +.. nonce: IFSXNm +.. section: Library + +Don't traverse into symlinks for ``**`` pattern in pathlib.Path.[r]glob(). + +.. + +.. bpo: 24120 +.. date: 9046 +.. nonce: Yiwa0h +.. section: Library + +Ignore PermissionError when traversing a tree with pathlib.Path.[r]glob(). +Patch by Ulrich Petri. + +.. + +.. bpo: 21815 +.. date: 9045 +.. nonce: h7-UY8 +.. section: Library + +Accept ] characters in the data portion of imap responses, in order to +handle the flags with square brackets accepted and produced by servers such +as gmail. + +.. + +.. bpo: 25447 +.. date: 9044 +.. nonce: -4m4xO +.. section: Library + +fileinput now uses sys.stdin as-is if it does not have a buffer attribute +(restores backward compatibility). + +.. + +.. bpo: 25971 +.. date: 9043 +.. nonce: vhMeG0 +.. section: Library + +Optimized creating Fractions from floats by 2 times and from Decimals by 3 +times. + +.. + +.. bpo: 25802 +.. date: 9042 +.. nonce: Y2KOnA +.. section: Library + +Document as deprecated the remaining implementations of +importlib.abc.Loader.load_module(). + +.. + +.. bpo: 25928 +.. date: 9041 +.. nonce: JsQfKK +.. section: Library + +Add Decimal.as_integer_ratio(). + +.. + +.. bpo: 25447 +.. date: 9040 +.. nonce: ajPRDy +.. section: Library + +Copying the lru_cache() wrapper object now always works, independently from +the type of the wrapped object (by returning the original object unchanged). + +.. + +.. bpo: 25768 +.. date: 9039 +.. nonce: GDj2ip +.. section: Library + +Have the functions in compileall return booleans instead of ints and add +proper documentation and tests for the return values. + +.. + +.. bpo: 24103 +.. date: 9038 +.. nonce: WufqrQ +.. section: Library + +Fixed possible use after free in ElementTree.XMLPullParser. + +.. + +.. bpo: 25860 +.. date: 9037 +.. nonce: 0hActb +.. section: Library + +os.fwalk() no longer skips remaining directories when error occurs. +Original patch by Samson Lee. + +.. + +.. bpo: 25914 +.. date: 9036 +.. nonce: h0V61F +.. section: Library + +Fixed and simplified OrderedDict.__sizeof__. + +.. + +.. bpo: 25869 +.. date: 9035 +.. nonce: eAnRH5 +.. section: Library + +Optimized deepcopying ElementTree; it is now 20 times faster. + +.. + +.. bpo: 25873 +.. date: 9034 +.. nonce: L4Fgjm +.. section: Library + +Optimized iterating ElementTree. Iterating elements Element.iter() is now +40% faster, iterating text Element.itertext() is now up to 2.5 times faster. + +.. + +.. bpo: 25902 +.. date: 9033 +.. nonce: 6t2FmH +.. section: Library + +Fixed various refcount issues in ElementTree iteration. + +.. + +.. bpo: 22227 +.. date: 9032 +.. nonce: 5utM-Q +.. section: Library + +The TarFile iterator is reimplemented using generator. This implementation +is simpler that using class. + +.. + +.. bpo: 25638 +.. date: 9031 +.. nonce: yitRj4 +.. section: Library + +Optimized ElementTree.iterparse(); it is now 2x faster. Optimized +ElementTree parsing; it is now 10% faster. + +.. + +.. bpo: 25761 +.. date: 9030 +.. nonce: JGgMOP +.. section: Library + +Improved detecting errors in broken pickle data. + +.. + +.. bpo: 25717 +.. date: 9029 +.. nonce: 0_xjaK +.. section: Library + +Restore the previous behaviour of tolerating most fstat() errors when +opening files. This was a regression in 3.5a1, and stopped anonymous +temporary files from working in special cases. + +.. + +.. bpo: 24903 +.. date: 9028 +.. nonce: 3LBdzb +.. section: Library + +Fix regression in number of arguments compileall accepts when '-d' is +specified. The check on the number of arguments has been dropped completely +as it never worked correctly anyway. + +.. + +.. bpo: 25764 +.. date: 9027 +.. nonce: 7WWG07 +.. section: Library + +In the subprocess module, preserve any exception caused by fork() failure +when preexec_fn is used. + +.. + +.. bpo: 25771 +.. date: 9026 +.. nonce: It-7Qf +.. section: Library + +Tweak the exception message for importlib.util.resolve_name() when 'package' +isn't specified but necessary. + +.. + +.. bpo: 6478 +.. date: 9025 +.. nonce: -Bi9Hb +.. section: Library + +_strptime's regexp cache now is reset after changing timezone with +time.tzset(). + +.. + +.. bpo: 14285 +.. date: 9024 +.. nonce: UyG8Hj +.. section: Library + +When executing a package with the "python -m package" option, and package +initialization fails, a proper traceback is now reported. The "runpy" +module now lets exceptions from package initialization pass back to the +caller, rather than raising ImportError. + +.. + +.. bpo: 19771 +.. date: 9023 +.. nonce: 5NG-bg +.. section: Library + +Also in runpy and the "-m" option, omit the irrelevant message ". . . is a +package and cannot be directly executed" if the package could not even be +initialized (e.g. due to a bad ``*.pyc`` file). + +.. + +.. bpo: 25177 +.. date: 9022 +.. nonce: aNR4Ha +.. section: Library + +Fixed problem with the mean of very small and very large numbers. As a side +effect, statistics.mean and statistics.variance should be significantly +faster. + +.. + +.. bpo: 25718 +.. date: 9021 +.. nonce: D9mHZF +.. section: Library + +Fixed copying object with state with boolean value is false. + +.. + +.. bpo: 10131 +.. date: 9020 +.. nonce: a7tptz +.. section: Library + +Fixed deep copying of minidom documents. Based on patch by Marian Ganisin. + +.. + +.. bpo: 7990 +.. date: 9019 +.. nonce: fpvQxH +.. section: Library + +dir() on ElementTree.Element now lists properties: "tag", "text", "tail" and +"attrib". Original patch by Santoso Wijaya. + +.. + +.. bpo: 25725 +.. date: 9018 +.. nonce: XIKv3R +.. section: Library + +Fixed a reference leak in pickle.loads() when unpickling invalid data +including tuple instructions. + +.. + +.. bpo: 25663 +.. date: 9017 +.. nonce: Ofwfqa +.. section: Library + +In the Readline completer, avoid listing duplicate global names, and search +the global namespace before searching builtins. + +.. + +.. bpo: 25688 +.. date: 9016 +.. nonce: 8P1HOv +.. section: Library + +Fixed file leak in ElementTree.iterparse() raising an error. + +.. + +.. bpo: 23914 +.. date: 9015 +.. nonce: 1sEz4J +.. section: Library + +Fixed SystemError raised by unpickler on broken pickle data. + +.. + +.. bpo: 25691 +.. date: 9014 +.. nonce: ZEaapY +.. section: Library + +Fixed crash on deleting ElementTree.Element attributes. + +.. + +.. bpo: 25624 +.. date: 9013 +.. nonce: ed-fM0 +.. section: Library + +ZipFile now always writes a ZIP_STORED header for directory entries. Patch +by Dingyuan Wang. + +.. + +.. bpo: 25626 +.. date: 9012 +.. nonce: TQ3fvb +.. section: Library + +Change three zlib functions to accept sizes that fit in Py_ssize_t, but +internally cap those sizes to UINT_MAX. This resolves a regression in 3.5 +where GzipFile.read() failed to read chunks larger than 2 or 4 GiB. The +change affects the zlib.Decompress.decompress() max_length parameter, the +zlib.decompress() bufsize parameter, and the zlib.Decompress.flush() length +parameter. + +.. + +.. bpo: 25583 +.. date: 9011 +.. nonce: Gk-cim +.. section: Library + +Avoid incorrect errors raised by os.makedirs(exist_ok=True) when the OS +gives priority to errors such as EACCES over EEXIST. + +.. + +.. bpo: 25593 +.. date: 9010 +.. nonce: 56uegI +.. section: Library + +Change semantics of EventLoop.stop() in asyncio. + +.. + +.. bpo: 6973 +.. date: 9009 +.. nonce: nl5cHt +.. section: Library + +When we know a subprocess.Popen process has died, do not allow the +send_signal(), terminate(), or kill() methods to do anything as they could +potentially signal a different process. + +.. + +.. bpo: 23883 +.. date: 9008 +.. nonce: OQS5sS +.. section: Library + +Added missing APIs to __all__ to match the documented APIs for the following +modules: calendar, csv, enum, fileinput, ftplib, logging, optparse, tarfile, +threading and wave. Also added a test.support.check__all__() helper. +Patches by Jacek Kołodziej, Mauro S. M. Rodrigues and Joel Taddei. + +.. + +.. bpo: 25590 +.. date: 9007 +.. nonce: KPcnfv +.. section: Library + +In the Readline completer, only call getattr() once per attribute. Also +complete names of attributes such as properties and slots which are listed +by dir() but not yet created on an instance. + +.. + +.. bpo: 25498 +.. date: 9006 +.. nonce: AvqEBl +.. section: Library + +Fix a crash when garbage-collecting ctypes objects created by wrapping a +memoryview. This was a regression made in 3.5a1. Based on patch by +Eryksun. + +.. + +.. bpo: 25584 +.. date: 9005 +.. nonce: 124mYw +.. section: Library + +Added "escape" to the __all__ list in the glob module. + +.. + +.. bpo: 25584 +.. date: 9004 +.. nonce: ZeWX0J +.. section: Library + +Fixed recursive glob() with patterns starting with ``**``. + +.. + +.. bpo: 25446 +.. date: 9003 +.. nonce: k1DByx +.. section: Library + +Fix regression in smtplib's AUTH LOGIN support. + +.. + +.. bpo: 18010 +.. date: 9002 +.. nonce: Azyf1C +.. section: Library + +Fix the pydoc web server's module search function to handle exceptions from +importing packages. + +.. + +.. bpo: 25554 +.. date: 9001 +.. nonce: UM9MlR +.. section: Library + +Got rid of circular references in regular expression parsing. + +.. + +.. bpo: 18973 +.. date: 9000 +.. nonce: Am9jFL +.. section: Library + +Command-line interface of the calendar module now uses argparse instead of +optparse. + +.. + +.. bpo: 25510 +.. date: 8999 +.. nonce: 79g7LA +.. section: Library + +fileinput.FileInput.readline() now returns b'' instead of '' at the end if +the FileInput was opened with binary mode. Patch by Ryosuke Ito. + +.. + +.. bpo: 25503 +.. date: 8998 +.. nonce: Zea0Y7 +.. section: Library + +Fixed inspect.getdoc() for inherited docstrings of properties. Original +patch by John Mark Vandenberg. + +.. + +.. bpo: 25515 +.. date: 8997 +.. nonce: fQsyYG +.. section: Library + +Always use os.urandom as a source of randomness in uuid.uuid4. + +.. + +.. bpo: 21827 +.. date: 8996 +.. nonce: k2oreR +.. section: Library + +Fixed textwrap.dedent() for the case when largest common whitespace is a +substring of smallest leading whitespace. Based on patch by Robert Li. + +.. + +.. bpo: 25447 +.. date: 8995 +.. nonce: eDYc4t +.. section: Library + +The lru_cache() wrapper objects now can be copied and pickled (by returning +the original object unchanged). + +.. + +.. bpo: 25390 +.. date: 8994 +.. nonce: 6mSgRq +.. section: Library + +typing: Don't crash on Union[str, Pattern]. + +.. + +.. bpo: 25441 +.. date: 8993 +.. nonce: d7zph6 +.. section: Library + +asyncio: Raise error from drain() when socket is closed. + +.. + +.. bpo: 25410 +.. date: 8992 +.. nonce: QAs_3B +.. section: Library + +Cleaned up and fixed minor bugs in C implementation of OrderedDict. + +.. + +.. bpo: 25411 +.. date: 8991 +.. nonce: qsJTCb +.. section: Library + +Improved Unicode support in SMTPHandler through better use of the email +package. Thanks to user simon04 for the patch. + +.. + +.. bpo: 0 +.. date: 8990 +.. nonce: pFHJ0i +.. section: Library + +Move the imp module from a PendingDeprecationWarning to DeprecationWarning. + +.. + +.. bpo: 25407 +.. date: 8989 +.. nonce: ukNt1D +.. section: Library + +Remove mentions of the formatter module being removed in Python 3.6. + +.. + +.. bpo: 25406 +.. date: 8988 +.. nonce: 5MZKU_ +.. section: Library + +Fixed a bug in C implementation of OrderedDict.move_to_end() that caused +segmentation fault or hang in iterating after moving several items to the +start of ordered dict. + +.. + +.. bpo: 25382 +.. date: 8987 +.. nonce: XQ44yE +.. section: Library + +pickletools.dis() now outputs implicit memo index for the MEMOIZE opcode. + +.. + +.. bpo: 25357 +.. date: 8986 +.. nonce: ebqGy- +.. section: Library + +Add an optional newline parameter to binascii.b2a_base64(). base64.b64encode() +uses it to avoid a memory copy. + +.. + +.. bpo: 24164 +.. date: 8985 +.. nonce: oi6H3E +.. section: Library + +Objects that need calling ``__new__`` with keyword arguments, can now be +pickled using pickle protocols older than protocol version 4. + +.. + +.. bpo: 25364 +.. date: 8984 +.. nonce: u_1Wi6 +.. section: Library + +zipfile now works in threads disabled builds. + +.. + +.. bpo: 25328 +.. date: 8983 +.. nonce: Rja1Xg +.. section: Library + +smtpd's SMTPChannel now correctly raises a ValueError if both decode_data +and enable_SMTPUTF8 are set to true. + +.. + +.. bpo: 16099 +.. date: 8982 +.. nonce: _MTt3k +.. section: Library + +RobotFileParser now supports Crawl-delay and Request-rate extensions. Patch +by Nikolay Bogoychev. + +.. + +.. bpo: 25316 +.. date: 8981 +.. nonce: dHQHWI +.. section: Library + +distutils raises OSError instead of DistutilsPlatformError when MSVC is not +installed. + +.. + +.. bpo: 25380 +.. date: 8980 +.. nonce: sKZ6-I +.. section: Library + +Fixed protocol for the STACK_GLOBAL opcode in pickletools.opcodes. + +.. + +.. bpo: 23972 +.. date: 8979 +.. nonce: s2g30g +.. section: Library + +Updates asyncio datagram create method allowing reuseport and reuseaddr +socket options to be set prior to binding the socket. Mirroring the existing +asyncio create_server method the reuseaddr option for datagram sockets +defaults to True if the O/S is 'posix' (except if the platform is Cygwin). +Patch by Chris Laws. + +.. + +.. bpo: 25304 +.. date: 8978 +.. nonce: CsmLyI +.. section: Library + +Add asyncio.run_coroutine_threadsafe(). This lets you submit a coroutine to +a loop from another thread, returning a concurrent.futures.Future. By +Vincent Michel. + +.. + +.. bpo: 25232 +.. date: 8977 +.. nonce: KhKjCE +.. section: Library + +Fix CGIRequestHandler to split the query from the URL at the first question +mark (?) rather than the last. Patch from Xiang Zhang. + +.. + +.. bpo: 24657 +.. date: 8976 +.. nonce: h2Ag7y +.. section: Library + +Prevent CGIRequestHandler from collapsing slashes in the query part of the +URL as if it were a path. Patch from Xiang Zhang. + +.. + +.. bpo: 25287 +.. date: 8975 +.. nonce: KhzzMW +.. section: Library + +Don't add crypt.METHOD_CRYPT to crypt.methods if it's not supported. Check +if it is supported, it may not be supported on OpenBSD for example. + +.. + +.. bpo: 23600 +.. date: 8974 +.. nonce: 7J_RD5 +.. section: Library + +Default implementation of tzinfo.fromutc() was returning wrong results in +some cases. + +.. + +.. bpo: 25203 +.. date: 8973 +.. nonce: IgDEbt +.. section: Library + +Failed readline.set_completer_delims() no longer left the module in +inconsistent state. + +.. + +.. bpo: 25011 +.. date: 8972 +.. nonce: VcaCd6 +.. section: Library + +rlcompleter now omits private and special attribute names unless the prefix +starts with underscores. + +.. + +.. bpo: 25209 +.. date: 8971 +.. nonce: WxKcdJ +.. section: Library + +rlcompleter now can add a space or a colon after completed keyword. + +.. + +.. bpo: 22241 +.. date: 8970 +.. nonce: a-Mtw2 +.. section: Library + +timezone.utc name is now plain 'UTC', not 'UTC-00:00'. + +.. + +.. bpo: 23517 +.. date: 8969 +.. nonce: 0ABp8q +.. section: Library + +fromtimestamp() and utcfromtimestamp() methods of datetime.datetime now +round microseconds to nearest with ties going to nearest even integer +(ROUND_HALF_EVEN), as round(float), instead of rounding towards -Infinity +(ROUND_FLOOR). + +.. + +.. bpo: 23552 +.. date: 8968 +.. nonce: I0T-M- +.. section: Library + +Timeit now warns when there is substantial (4x) variance between best and +worst times. Patch from Serhiy Storchaka. + +.. + +.. bpo: 24633 +.. date: 8967 +.. nonce: 6Unn9B +.. section: Library + +site-packages/README -> README.txt. + +.. + +.. bpo: 24879 +.. date: 8966 +.. nonce: YUzg_z +.. section: Library + +help() and pydoc can now list named tuple fields in the order they were +defined rather than alphabetically. The ordering is determined by the +_fields attribute if present. + +.. + +.. bpo: 24874 +.. date: 8965 +.. nonce: luBfgA +.. section: Library + +Improve speed of itertools.cycle() and make its pickle more compact. + +.. + +.. bpo: 0 +.. date: 8964 +.. nonce: mD-_3v +.. section: Library + +Fix crash in itertools.cycle.__setstate__() when the first argument wasn't a +list. + +.. + +.. bpo: 20059 +.. date: 8963 +.. nonce: SHv0Ji +.. section: Library + +urllib.parse raises ValueError on all invalid ports. Patch by Martin Panter. + +.. + +.. bpo: 24360 +.. date: 8962 +.. nonce: 5RwH-e +.. section: Library + +Improve __repr__ of argparse.Namespace() for invalid identifiers. Patch by +Matthias Bussonnier. + +.. + +.. bpo: 23426 +.. date: 8961 +.. nonce: PUV-Cx +.. section: Library + +run_setup was broken in distutils. Patch from Alexander Belopolsky. + +.. + +.. bpo: 13938 +.. date: 8960 +.. nonce: e5NSE1 +.. section: Library + +2to3 converts StringTypes to a tuple. Patch from Mark Hammond. + +.. + +.. bpo: 2091 +.. date: 8959 +.. nonce: bp56pO +.. section: Library + +open() accepted a 'U' mode string containing '+', but 'U' can only be used +with 'r'. Patch from Jeff Balogh and John O'Connor. + +.. + +.. bpo: 8585 +.. date: 8958 +.. nonce: 78hPc2 +.. section: Library + +improved tests for zipimporter2. Patch from Mark Lawrence. + +.. + +.. bpo: 18622 +.. date: 8957 +.. nonce: i6nCCW +.. section: Library + +unittest.mock.mock_open().reset_mock would recurse infinitely. Patch from +Nicola Palumbo and Laurent De Buyst. + +.. + +.. bpo: 24426 +.. date: 8956 +.. nonce: yCtQfT +.. section: Library + +Fast searching optimization in regular expressions now works for patterns +that starts with capturing groups. Fast searching optimization now can't be +disabled at compile time. + +.. + +.. bpo: 23661 +.. date: 8955 +.. nonce: 5VHJmh +.. section: Library + +unittest.mock side_effects can now be exceptions again. This was a +regression vs Python 3.4. Patch from Ignacio Rossi + +.. + +.. bpo: 13248 +.. date: 8954 +.. nonce: SA2hvu +.. section: Library + +Remove deprecated inspect.getmoduleinfo function. + +.. + +.. bpo: 25578 +.. date: 8953 +.. nonce: G6S-ft +.. section: Library + +Fix (another) memory leak in SSLSocket.getpeercer(). + +.. + +.. bpo: 25530 +.. date: 8952 +.. nonce: hDFkwu +.. section: Library + +Disable the vulnerable SSLv3 protocol by default when creating +ssl.SSLContext. + +.. + +.. bpo: 25569 +.. date: 8951 +.. nonce: CfvQjK +.. section: Library + +Fix memory leak in SSLSocket.getpeercert(). + +.. + +.. bpo: 25471 +.. date: 8950 +.. nonce: T0A02M +.. section: Library + +Sockets returned from accept() shouldn't appear to be nonblocking. + +.. + +.. bpo: 25319 +.. date: 8949 +.. nonce: iyuglv +.. section: Library + +When threading.Event is reinitialized, the underlying condition should use a +regular lock rather than a recursive lock. + +.. + +.. bpo: 0 +.. date: 8948 +.. nonce: rtZyid +.. section: Library + +Skip getaddrinfo if host is already resolved. Patch by A. Jesse Jiryu Davis. + +.. + +.. bpo: 26050 +.. date: 8947 +.. nonce: sclyvk +.. section: Library + +Add asyncio.StreamReader.readuntil() method. Patch by Марк Коренберг. + +.. + +.. bpo: 25924 +.. date: 8946 +.. nonce: Uxr2vt +.. section: Library + +Avoid unnecessary serialization of getaddrinfo(3) calls on OS X versions +10.5 or higher. Original patch by A. Jesse Jiryu Davis. + +.. + +.. bpo: 26406 +.. date: 8945 +.. nonce: ihvhF4 +.. section: Library + +Avoid unnecessary serialization of getaddrinfo(3) calls on current versions +of OpenBSD and NetBSD. Patch by A. Jesse Jiryu Davis. + +.. + +.. bpo: 26848 +.. date: 8944 +.. nonce: ChBOpQ +.. section: Library + +Fix asyncio/subprocess.communicate() to handle empty input. Patch by Jack +O'Connor. + +.. + +.. bpo: 27040 +.. date: 8943 +.. nonce: UASyCC +.. section: Library + +Add loop.get_exception_handler method + +.. + +.. bpo: 27041 +.. date: 8942 +.. nonce: p3893U +.. section: Library + +asyncio: Add loop.create_future method + +.. + +.. bpo: 20640 +.. date: 8941 +.. nonce: PmI-G8 +.. section: IDLE + +Add tests for idlelib.configHelpSourceEdit. Patch by Saimadhav Heblikar. + +.. + +.. bpo: 0 +.. date: 8940 +.. nonce: _YJfG7 +.. section: IDLE + +In the 'IDLE-console differences' section of the IDLE doc, clarify how +running with IDLE affects sys.modules and the standard streams. + +.. + +.. bpo: 25507 +.. date: 8939 +.. nonce: i8bNpk +.. section: IDLE + +fix incorrect change in IOBinding that prevented printing. Augment IOBinding +htest to include all major IOBinding functions. + +.. + +.. bpo: 25905 +.. date: 8938 +.. nonce: FzNb3B +.. section: IDLE + +Revert unwanted conversion of ' to ’ RIGHT SINGLE QUOTATION MARK in +README.txt and open this and NEWS.txt with 'ascii'. Re-encode CREDITS.txt to +utf-8 and open it with 'utf-8'. + +.. + +.. bpo: 15348 +.. date: 8937 +.. nonce: d1Fg01 +.. section: IDLE + +Stop the debugger engine (normally in a user process) before closing the +debugger window (running in the IDLE process). This prevents the +RuntimeErrors that were being caught and ignored. + +.. + +.. bpo: 24455 +.. date: 8936 +.. nonce: x6YqtE +.. section: IDLE + +Prevent IDLE from hanging when a) closing the shell while the debugger is +active (15347); b) closing the debugger with the [X] button (15348); and c) +activating the debugger when already active (24455). The patch by Mark +Roseman does this by making two changes. 1. Suspend and resume the +gui.interaction method with the tcl vwait mechanism intended for this +purpose (instead of root.mainloop & .quit). 2. In gui.run, allow any +existing interaction to terminate first. + +.. + +.. bpo: 0 +.. date: 8935 +.. nonce: Yp9LRY +.. section: IDLE + +Change 'The program' to 'Your program' in an IDLE 'kill program?' message to +make it clearer that the program referred to is the currently running user +program, not IDLE itself. + +.. + +.. bpo: 24750 +.. date: 8934 +.. nonce: xgsi-K +.. section: IDLE + +Improve the appearance of the IDLE editor window status bar. Patch by Mark +Roseman. + +.. + +.. bpo: 25313 +.. date: 8933 +.. nonce: xMXHpO +.. section: IDLE + +Change the handling of new built-in text color themes to better address the +compatibility problem introduced by the addition of IDLE Dark. Consistently +use the revised idleConf.CurrentTheme everywhere in idlelib. + +.. + +.. bpo: 24782 +.. date: 8932 +.. nonce: RgIPYE +.. section: IDLE + +Extension configuration is now a tab in the IDLE Preferences dialog rather +than a separate dialog. The former tabs are now a sorted list. Patch by +Mark Roseman. + +.. + +.. bpo: 22726 +.. date: 8931 +.. nonce: x8T0dA +.. section: IDLE + +Re-activate the config dialog help button with some content about the other +buttons and the new IDLE Dark theme. + +.. + +.. bpo: 24820 +.. date: 8930 +.. nonce: TFPJhr +.. section: IDLE + +IDLE now has an 'IDLE Dark' built-in text color theme. It is more or less +IDLE Classic inverted, with a cobalt blue background. Strings, comments, +keywords, ... are still green, red, orange, ... . To use it with IDLEs +released before November 2015, hit the 'Save as New Custom Theme' button and +enter a new name, such as 'Custom Dark'. The custom theme will work with +any IDLE release, and can be modified. + +.. + +.. bpo: 25224 +.. date: 8929 +.. nonce: 5Llwo4 +.. section: IDLE + +README.txt is now an idlelib index for IDLE developers and curious users. +The previous user content is now in the IDLE doc chapter. 'IDLE' now means +'Integrated Development and Learning Environment'. + +.. + +.. bpo: 24820 +.. date: 8928 +.. nonce: ZUz9Fn +.. section: IDLE + +Users can now set breakpoint colors in Settings -> Custom Highlighting. +Original patch by Mark Roseman. + +.. + +.. bpo: 24972 +.. date: 8927 +.. nonce: uc0uNo +.. section: IDLE + +Inactive selection background now matches active selection background, as +configured by users, on all systems. Found items are now always highlighted +on Windows. Initial patch by Mark Roseman. + +.. + +.. bpo: 24570 +.. date: 8926 +.. nonce: s3EkNn +.. section: IDLE + +Idle: make calltip and completion boxes appear on Macs affected by a tk +regression. Initial patch by Mark Roseman. + +.. + +.. bpo: 24988 +.. date: 8925 +.. nonce: tXqq4T +.. section: IDLE + +Idle ScrolledList context menus (used in debugger) now work on Mac Aqua. +Patch by Mark Roseman. + +.. + +.. bpo: 24801 +.. date: 8924 +.. nonce: -bj_Ou +.. section: IDLE + +Make right-click for context menu work on Mac Aqua. Patch by Mark Roseman. + +.. + +.. bpo: 25173 +.. date: 8923 +.. nonce: EZzrPg +.. section: IDLE + +Associate tkinter messageboxes with a specific widget. For Mac OSX, make +them a 'sheet'. Patch by Mark Roseman. + +.. + +.. bpo: 25198 +.. date: 8922 +.. nonce: -j_BV7 +.. section: IDLE + +Enhance the initial html viewer now used for Idle Help. Properly indent +fixed-pitch text (patch by Mark Roseman). Give code snippet a very +Sphinx-like light blueish-gray background. Re-use initial width and height set by +users for shell and editor. When the Table of Contents (TOC) menu is used, +put the section header at the top of the screen. + +.. + +.. bpo: 25225 +.. date: 8921 +.. nonce: 9pvdq6 +.. section: IDLE + +Condense and rewrite Idle doc section on text colors. + +.. + +.. bpo: 21995 +.. date: 8920 +.. nonce: C5Rmzx +.. section: IDLE + +Explain some differences between IDLE and console Python. + +.. + +.. bpo: 22820 +.. date: 8919 +.. nonce: hix_8X +.. section: IDLE + +Explain need for *print* when running file from Idle editor. + +.. + +.. bpo: 25224 +.. date: 8918 +.. nonce: UVMYQq +.. section: IDLE + +Doc: augment Idle feature list and no-subprocess section. + +.. + +.. bpo: 25219 +.. date: 8917 +.. nonce: 8_9DYg +.. section: IDLE + +Update doc for Idle command line options. Some were missing and notes were +not correct. + +.. + +.. bpo: 24861 +.. date: 8916 +.. nonce: Ecg2yT +.. section: IDLE + +Most of idlelib is private and subject to change. Use idleib.idle.* to start +Idle. See idlelib.__init__.__doc__. + +.. + +.. bpo: 25199 +.. date: 8915 +.. nonce: ih7yY3 +.. section: IDLE + +Idle: add synchronization comments for future maintainers. + +.. + +.. bpo: 16893 +.. date: 8914 +.. nonce: uIi1oB +.. section: IDLE + +Replace help.txt with help.html for Idle doc display. The new +idlelib/help.html is rstripped Doc/build/html/library/idle.html. It looks +better than help.txt and will better document Idle as released. The tkinter +html viewer that works for this file was written by Rose Roseman. The now +unused EditorWindow.HelpDialog class and helt.txt file are deprecated. + +.. + +.. bpo: 24199 +.. date: 8913 +.. nonce: VKnZEv +.. section: IDLE + +Deprecate unused idlelib.idlever with possible removal in 3.6. + +.. + +.. bpo: 24790 +.. date: 8912 +.. nonce: hD1hlj +.. section: IDLE + +Remove extraneous code (which also create 2 & 3 conflicts). + +.. + +.. bpo: 26736 +.. date: 8911 +.. nonce: U_Hyqo +.. section: Documentation + +Used HTTPS for external links in the documentation if possible. + +.. + +.. bpo: 6953 +.. date: 8910 +.. nonce: Zk6rno +.. section: Documentation + +Rework the Readline module documentation to group related functions +together, and add more details such as what underlying Readline functions +and variables are accessed. + +.. + +.. bpo: 23606 +.. date: 8909 +.. nonce: 9MhIso +.. section: Documentation + +Adds note to ctypes documentation regarding cdll.msvcrt. + +.. + +.. bpo: 24952 +.. date: 8908 +.. nonce: RHhFPE +.. section: Documentation + +Clarify the default size argument of stack_size() in the "threading" and +"_thread" modules. Patch from Mattip. + +.. + +.. bpo: 26014 +.. date: 8907 +.. nonce: ptdZ_I +.. section: Documentation + +Update 3.x packaging documentation: * "See also" links to the new docs are +now provided in the legacy pages * links to setuptools documentation have +been updated + +.. + +.. bpo: 21916 +.. date: 8906 +.. nonce: muwCyp +.. section: Tests + +Added tests for the turtle module. Patch by ingrid, Gregory Loyse and Jelle +Zijlstra. + +.. + +.. bpo: 26295 +.. date: 8905 +.. nonce: sYBtj5 +.. section: Tests + +When using "python3 -m test --testdir=TESTDIR", regrtest doesn't add "test." +prefix to test module names. + +.. + +.. bpo: 26523 +.. date: 8904 +.. nonce: em_Uzt +.. section: Tests + +The multiprocessing thread pool (multiprocessing.dummy.Pool) was untested. + +.. + +.. bpo: 26015 +.. date: 8903 +.. nonce: p3oWK3 +.. section: Tests + +Added new tests for pickling iterators of mutable sequences. + +.. + +.. bpo: 26325 +.. date: 8902 +.. nonce: KOUc82 +.. section: Tests + +Added test.support.check_no_resource_warning() to check that no +ResourceWarning is emitted. + +.. + +.. bpo: 25940 +.. date: 8901 +.. nonce: MvBwSe +.. section: Tests + +Changed test_ssl to use its internal local server more. This avoids relying +on svn.python.org, which recently changed root certificate. + +.. + +.. bpo: 25616 +.. date: 8900 +.. nonce: Qr-60p +.. section: Tests + +Tests for OrderedDict are extracted from test_collections into separate file +test_ordered_dict. + +.. + +.. bpo: 25449 +.. date: 8899 +.. nonce: MP6KNs +.. section: Tests + +Added tests for OrderedDict subclasses. + +.. + +.. bpo: 25188 +.. date: 8898 +.. nonce: lnLnIW +.. section: Tests + +Add -P/--pgo to test.regrtest to suppress error output when running the test +suite for the purposes of a PGO build. Initial patch by Alecsandru Patrascu. + +.. + +.. bpo: 22806 +.. date: 8897 +.. nonce: _QHyyV +.. section: Tests + +Add ``python -m test --list-tests`` command to list tests. + +.. + +.. bpo: 18174 +.. date: 8896 +.. nonce: TzH9d_ +.. section: Tests + +``python -m test --huntrleaks ...`` now also checks for leak of file +descriptors. Patch written by Richard Oudkerk. + +.. + +.. bpo: 25260 +.. date: 8895 +.. nonce: jw3p83 +.. section: Tests + +Fix ``python -m test --coverage`` on Windows. Remove the list of ignored +directories. + +.. + +.. bpo: 0 +.. date: 8894 +.. nonce: X-Bk5l +.. section: Tests + +``PCbuild\rt.bat`` now accepts an unlimited number of arguments to pass +along to regrtest.py. Previously there was a limit of 9. + +.. + +.. bpo: 26583 +.. date: 8893 +.. nonce: Up7hTl +.. section: Tests + +Skip test_timestamp_overflow in test_import if bytecode files cannot be +written. + +.. + +.. bpo: 21277 +.. date: 8892 +.. nonce: 7y1j9a +.. section: Build + +Don't try to link _ctypes with a ffi_convenience library. + +.. + +.. bpo: 26884 +.. date: 8891 +.. nonce: O8-azL +.. section: Build + +Fix linking extension modules for cross builds. Patch by Xavier de Gaye. + +.. + +.. bpo: 26932 +.. date: 8890 +.. nonce: 5kzaG9 +.. section: Build + +Fixed support of RTLD_* constants defined as enum values, not via macros (in +particular on Android). Patch by Chi Hsuan Yen. + +.. + +.. bpo: 22359 +.. date: 8889 +.. nonce: HDjM4s +.. section: Build + +Disable the rules for running _freeze_importlib and pgen when +cross-compiling. The output of these programs is normally saved with the source +code anyway, and is still regenerated when doing a native build. Patch by +Xavier de Gaye. + +.. + +.. bpo: 21668 +.. date: 8888 +.. nonce: qWwBui +.. section: Build + +Link audioop, _datetime, _ctypes_test modules to libm, except on Mac OS X. +Patch written by Chi Hsuan Yen. + +.. + +.. bpo: 25702 +.. date: 8887 +.. nonce: ipxyJs +.. section: Build + +A --with-lto configure option has been added that will enable link time +optimizations at build time during a make profile-opt. Some compilers and +toolchains are known to not produce stable code when using LTO, be sure to +test things thoroughly before relying on it. It can provide a few % speed up +over profile-opt alone. + +.. + +.. bpo: 26624 +.. date: 8886 +.. nonce: 4fGrTl +.. section: Build + +Adds validation of ucrtbase[d].dll version with warning for old versions. + +.. + +.. bpo: 17603 +.. date: 8885 +.. nonce: 102DA- +.. section: Build + +Avoid error about nonexistent fileblocks.o file by using a lower-level check +for st_blocks in struct stat. + +.. + +.. bpo: 26079 +.. date: 8884 +.. nonce: mEzW0O +.. section: Build + +Fixing the build output folder for tix-8.4.3.6. Patch by Bjoern Thiel. + +.. + +.. bpo: 26465 +.. date: 8883 +.. nonce: _YR608 +.. section: Build + +Update Windows builds to use OpenSSL 1.0.2g. + +.. + +.. bpo: 25348 +.. date: 8882 +.. nonce: FLSPfp +.. section: Build + +Added ``--pgo`` and ``--pgo-job`` arguments to ``PCbuild\build.bat`` for +building with Profile-Guided Optimization. The old +``PCbuild\build_pgo.bat`` script is removed. + +.. + +.. bpo: 25827 +.. date: 8881 +.. nonce: yg3DMM +.. section: Build + +Add support for building with ICC to ``configure``, including a new +``--with-icc`` flag. + +.. + +.. bpo: 25696 +.. date: 8880 +.. nonce: 2R_wIv +.. section: Build + +Fix installation of Python on UNIX with make -j9. + +.. + +.. bpo: 24986 +.. date: 8879 +.. nonce: 1WyXeU +.. section: Build + +It is now possible to build Python on Windows without errors when external +libraries are not available. + +.. + +.. bpo: 24421 +.. date: 8878 +.. nonce: 2zY7vM +.. section: Build + +Compile Modules/_math.c once, before building extensions. Previously it +could fail to compile properly if the math and cmath builds were concurrent. + +.. + +.. bpo: 26465 +.. date: 8877 +.. nonce: PkIaV8 +.. section: Build + +Update OS X 10.5+ 32-bit-only installer to build and link with OpenSSL +1.0.2g. + +.. + +.. bpo: 26268 +.. date: 8876 +.. nonce: I3-YLh +.. section: Build + +Update Windows builds to use OpenSSL 1.0.2f. + +.. + +.. bpo: 25136 +.. date: 8875 +.. nonce: Vi-fmO +.. section: Build + +Support Apple Xcode 7's new textual SDK stub libraries. + +.. + +.. bpo: 24324 +.. date: 8874 +.. nonce: m6DZMx +.. section: Build + +Do not enable unreachable code warnings when using gcc as the option does +not work correctly in older versions of gcc and has been silently removed as +of gcc-4.5. + +.. + +.. bpo: 27053 +.. date: 8873 +.. nonce: 1IRbae +.. section: Windows + +Updates make_zip.py to correctly generate library ZIP file. + +.. + +.. bpo: 26268 +.. date: 8872 +.. nonce: Z-lJEh +.. section: Windows + +Update the prepare_ssl.py script to handle OpenSSL releases that don't +include the contents of the include directory (that is, 1.0.2e and later). + +.. + +.. bpo: 26071 +.. date: 8871 +.. nonce: wLxL2l +.. section: Windows + +bdist_wininst created binaries fail to start and find 32bit Python + +.. + +.. bpo: 26073 +.. date: 8870 +.. nonce: XwWgHp +.. section: Windows + +Update the list of magic numbers in launcher + +.. + +.. bpo: 26065 +.. date: 8869 +.. nonce: SkVLJp +.. section: Windows + +Excludes venv from library when generating embeddable distro. + +.. + +.. bpo: 25022 +.. date: 8868 +.. nonce: vAt_zr +.. section: Windows + +Removed very outdated PC/example_nt/ directory. + +.. + +.. bpo: 26799 +.. date: 8867 +.. nonce: gK2VXX +.. section: Tools/Demos + +Fix python-gdb.py: don't get C types once when the Python code is loaded, +but get C types on demand. The C types can change if python-gdb.py is loaded +before the Python executable. Patch written by Thomas Ilsche. + +.. + +.. bpo: 26271 +.. date: 8866 +.. nonce: wg-rzr +.. section: Tools/Demos + +Fix the Freeze tool to properly use flags passed through configure. Patch by +Daniel Shaulov. + +.. + +.. bpo: 26489 +.. date: 8865 +.. nonce: rJ_U5S +.. section: Tools/Demos + +Add dictionary unpacking support to Tools/parser/unparse.py. Patch by Guo Ci +Teo. + +.. + +.. bpo: 26316 +.. date: 8864 +.. nonce: QJvVOi +.. section: Tools/Demos + +Fix variable name typo in Argument Clinic. + +.. + +.. bpo: 25440 +.. date: 8863 +.. nonce: 5xhyGr +.. section: Tools/Demos + +Fix output of python-config --extension-suffix. + +.. + +.. bpo: 25154 +.. date: 8862 +.. nonce: yLO-r4 +.. section: Tools/Demos + +The pyvenv script has been deprecated in favour of `python3 -m venv`. + +.. + +.. bpo: 26312 +.. date: 8861 +.. nonce: h1T61B +.. section: C API + +SystemError is now raised in all programming bugs with using +PyArg_ParseTupleAndKeywords(). RuntimeError did raised before in some +programming bugs. + +.. + +.. bpo: 26198 +.. date: 8860 +.. nonce: lVn1HX +.. section: C API + +ValueError is now raised instead of TypeError on buffer overflow in parsing +"es#" and "et#" format units. SystemError is now raised instead of +TypeError on programmatical error in parsing format string. diff --git a/Misc/NEWS.d/3.6.0a2.rst b/Misc/NEWS.d/3.6.0a2.rst new file mode 100644 index 00000000..1b336d7b --- /dev/null +++ b/Misc/NEWS.d/3.6.0a2.rst @@ -0,0 +1,792 @@ +.. release date: 2016-06-13 +.. bpo: 26556 +.. date: 9316 +.. nonce: v5j2uL +.. original section: Library +.. section: Security + +Update expat to 2.1.1, fixes CVE-2015-1283. + +.. + +.. bpo: 0 +.. date: 9315 +.. nonce: PHOAdg +.. original section: Library +.. section: Security + +Fix TLS stripping vulnerability in smtplib, CVE-2016-0772. Reported by Team +Oststrom. + +.. + +.. bpo: 26839 +.. date: 9303 +.. nonce: yVvy7R +.. original section: Library +.. section: Security + +On Linux, :func:`os.urandom` now calls ``getrandom()`` with +``GRND_NONBLOCK`` to fall back on reading ``/dev/urandom`` if the urandom +entropy pool is not initialized yet. Patch written by Colm Buckley. + +.. + +.. bpo: 27095 +.. date: 9332 +.. nonce: 92UoyH +.. section: Core and Builtins + +Simplified MAKE_FUNCTION and removed MAKE_CLOSURE opcodes. Patch by Demur +Rumed. + +.. + +.. bpo: 27190 +.. date: 9331 +.. nonce: DHDFeD +.. section: Core and Builtins + +Raise NotSupportedError if sqlite3 is older than 3.3.1. Patch by Dave +Sawyer. + +.. + +.. bpo: 27286 +.. date: 9330 +.. nonce: U8q6B1 +.. section: Core and Builtins + +Fixed compiling BUILD_MAP_UNPACK_WITH_CALL opcode. Calling function with +generalized unpacking (PEP 448) and conflicting keyword names could cause +undefined behavior. + +.. + +.. bpo: 27140 +.. date: 9329 +.. nonce: uc39-1 +.. section: Core and Builtins + +Added BUILD_CONST_KEY_MAP opcode. + +.. + +.. bpo: 27186 +.. date: 9328 +.. nonce: EAnCS7 +.. section: Core and Builtins + +Add support for os.PathLike objects to open() (part of :pep:`519`). + +.. + +.. bpo: 27066 +.. date: 9327 +.. nonce: SNExZi +.. section: Core and Builtins + +Fixed SystemError if a custom opener (for open()) returns a negative number +without setting an exception. + +.. + +.. bpo: 26983 +.. date: 9326 +.. nonce: A0f3fK +.. section: Core and Builtins + +float() now always return an instance of exact float. The deprecation +warning is emitted if __float__ returns an instance of a strict subclass of +float. In a future versions of Python this can be an error. + +.. + +.. bpo: 27097 +.. date: 9325 +.. nonce: woRKey +.. section: Core and Builtins + +Python interpreter is now about 7% faster due to optimized instruction +decoding. Based on patch by Demur Rumed. + +.. + +.. bpo: 26647 +.. date: 9324 +.. nonce: DLSzRi +.. section: Core and Builtins + +Python interpreter now uses 16-bit wordcode instead of bytecode. Patch by +Demur Rumed. + +.. + +.. bpo: 23275 +.. date: 9323 +.. nonce: YGPb_y +.. section: Core and Builtins + +Allow assigning to an empty target list in round brackets: () = iterable. + +.. + +.. bpo: 27243 +.. date: 9322 +.. nonce: U36M4E +.. section: Core and Builtins + +Update the __aiter__ protocol: instead of returning an awaitable that +resolves to an asynchronous iterator, the asynchronous iterator should be +returned directly. Doing the former will trigger a +PendingDeprecationWarning. + +.. + +.. bpo: 0 +.. date: 9321 +.. nonce: nBpVM1 +.. section: Library + +Comment out socket (SO_REUSEPORT) and posix (O_SHLOCK, O_EXLOCK) constants +exposed on the API which are not implemented on GNU/Hurd. They would not +work at runtime anyway. + +.. + +.. bpo: 27025 +.. date: 9320 +.. nonce: ffzxpX +.. section: Library + +Generated names for Tkinter widgets are now more meaningful and recognizable. + +.. + +.. bpo: 25455 +.. date: 9319 +.. nonce: k10GoO +.. section: Library + +Fixed crashes in repr of recursive ElementTree.Element and functools.partial +objects. + +.. + +.. bpo: 27294 +.. date: 9318 +.. nonce: XPCURr +.. section: Library + +Improved repr for Tkinter event objects. + +.. + +.. bpo: 20508 +.. date: 9317 +.. nonce: 3NMbT2 +.. section: Library + +Improve exception message of IPv{4,6}Network.__getitem__. Patch by Gareth +Rees. + +.. + +.. bpo: 21386 +.. date: 9314 +.. nonce: DjV72U +.. section: Library + +Implement missing IPv4Address.is_global property. It was documented since +07a5610bae9d. Initial patch by Roger Luethi. + +.. + +.. bpo: 27029 +.. date: 9313 +.. nonce: dmycvw +.. section: Library + +Removed deprecated support of universal newlines mode from ZipFile.open(). + +.. + +.. bpo: 27030 +.. date: 9312 +.. nonce: p29J7m +.. section: Library + +Unknown escapes consisting of ``'\'`` and an ASCII letter in regular +expressions now are errors. The re.LOCALE flag now can be used only with +bytes patterns. + +.. + +.. bpo: 27186 +.. date: 9311 +.. nonce: UYiwoh +.. section: Library + +Add os.PathLike support to DirEntry (part of :pep:`519`). Initial patch by +Jelle Zijlstra. + +.. + +.. bpo: 20900 +.. date: 9310 +.. nonce: H5YQPR +.. section: Library + +distutils register command now decodes HTTP responses correctly. Initial +patch by ingrid. + +.. + +.. bpo: 27186 +.. date: 9309 +.. nonce: Xo4c_F +.. section: Library + +Add os.PathLike support to pathlib, removing its provisional status (part of +PEP 519). Initial patch by Dusty Phillips. + +.. + +.. bpo: 27186 +.. date: 9308 +.. nonce: ZD1wpp +.. section: Library + +Add support for os.PathLike objects to os.fsencode() and os.fsdecode() (part +of :pep:`519`). + +.. + +.. bpo: 27186 +.. date: 9307 +.. nonce: y7YRfj +.. section: Library + +Introduce os.PathLike and os.fspath() (part of :pep:`519`). + +.. + +.. bpo: 0 +.. date: 9306 +.. nonce: iYIeng +.. section: Library + +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). + +.. + +.. bpo: 25738 +.. date: 9305 +.. nonce: mED9w4 +.. section: Library + +Stop http.server.BaseHTTPRequestHandler.send_error() from sending a message +body for 205 Reset Content. Also, don't send Content header fields in +responses that don't have a body. Patch by Susumu Koshiba. + +.. + +.. bpo: 21313 +.. date: 9304 +.. nonce: W30MBr +.. section: Library + +Fix the "platform" module to tolerate when sys.version contains truncated +build information. + +.. + +.. bpo: 23883 +.. date: 9302 +.. nonce: tsZUiM +.. section: Library + +Added missing APIs to __all__ to match the documented APIs for the following +modules: cgi, mailbox, mimetypes, plistlib and smtpd. Patches by Jacek +Kołodziej. + +.. + +.. bpo: 27164 +.. date: 9301 +.. nonce: 6wmjx2 +.. section: Library + +In the zlib module, allow decompressing raw Deflate streams with a +predefined zdict. Based on patch by Xiang Zhang. + +.. + +.. bpo: 24291 +.. date: 9300 +.. nonce: Ac6HvL +.. section: Library + +Fix wsgiref.simple_server.WSGIRequestHandler to completely write data to the +client. Previously it could do partial writes and truncate data. Also, +wsgiref.handler.ServerHandler can now handle stdout doing partial writes, +but this is deprecated. + +.. + +.. bpo: 21272 +.. date: 9299 +.. nonce: unScIG +.. section: Library + +Use _sysconfigdata.py to initialize distutils.sysconfig. + +.. + +.. bpo: 19611 +.. date: 9298 +.. nonce: MT-Qga +.. section: Library + +:mod:`inspect` now reports the implicit ``.0`` parameters generated by the +compiler for comprehension and generator expression scopes as if they were +positional-only parameters called ``implicit0``. Patch by Jelle Zijlstra. + +.. + +.. bpo: 26809 +.. date: 9297 +.. nonce: ya7JMb +.. section: Library + +Add ``__all__`` to :mod:`string`. Patch by Emanuel Barry. + +.. + +.. bpo: 26373 +.. date: 9296 +.. nonce: P6qz6o +.. section: Library + +subprocess.Popen.communicate now correctly ignores BrokenPipeError when the +child process dies before .communicate() is called in more/all +circumstances. + +.. + +.. bpo: 0 +.. date: 9295 +.. nonce: eKchPz +.. section: Library + +signal, socket, and ssl module IntEnum constant name lookups now return a +consistent name for values having multiple names. Ex: signal.Signals(6) now +refers to itself as signal.SIGALRM rather than flipping between that and +signal.SIGIOT based on the interpreter's hash randomization seed. + +.. + +.. bpo: 27167 +.. date: 9294 +.. nonce: orA_j0 +.. section: Library + +Clarify the subprocess.CalledProcessError error message text when the child +process died due to a signal. + +.. + +.. bpo: 25931 +.. date: 9293 +.. nonce: W7h6Am +.. section: Library + +Don't define socketserver.Forking* names on platforms such as Windows that +do not support os.fork(). + +.. + +.. bpo: 21776 +.. date: 9292 +.. nonce: 04eQfa +.. section: Library + +distutils.upload now correctly handles HTTPError. Initial patch by Claudiu +Popa. + +.. + +.. bpo: 26526 +.. date: 9291 +.. nonce: ScewjJ +.. section: Library + +Replace custom parse tree validation in the parser module with a simple DFA +validator. + +.. + +.. bpo: 27114 +.. date: 9290 +.. nonce: bGCuAM +.. section: Library + +Fix SSLContext._load_windows_store_certs fails with PermissionError + +.. + +.. bpo: 18383 +.. date: 9289 +.. nonce: jr-b0l +.. section: Library + +Avoid creating duplicate filters when using filterwarnings and simplefilter. +Based on patch by Alex Shkop. + +.. + +.. bpo: 23026 +.. date: 9288 +.. nonce: V2rgYX +.. section: Library + +winreg.QueryValueEx() now return an integer for REG_QWORD type. + +.. + +.. bpo: 26741 +.. date: 9287 +.. nonce: fsbb42 +.. section: Library + +subprocess.Popen destructor now emits a ResourceWarning warning if the child +process is still running. + +.. + +.. bpo: 27056 +.. date: 9286 +.. nonce: rk-BBL +.. section: Library + +Optimize pickle.load() and pickle.loads(), up to 10% faster to deserialize a +lot of small objects. + +.. + +.. bpo: 21271 +.. date: 9285 +.. nonce: bHIfFA +.. section: Library + +New keyword only parameters in reset_mock call. + +.. + +.. bpo: 5124 +.. date: 9284 +.. nonce: 4kwBvM +.. section: IDLE + +Paste with text selected now replaces the selection on X11. This matches how +paste works on Windows, Mac, most modern Linux apps, and ttk widgets. +Original patch by Serhiy Storchaka. + +.. + +.. bpo: 24750 +.. date: 9283 +.. nonce: wA-pc9 +.. section: IDLE + +Switch all scrollbars in IDLE to ttk versions. Where needed, minimal tests +are added to cover changes. + +.. + +.. bpo: 24759 +.. date: 9282 +.. nonce: 76HB4w +.. section: IDLE + +IDLE requires tk 8.5 and availability ttk widgets. Delete now unneeded tk +version tests and code for older versions. Add test for IDLE syntax +colorizer. + +.. + +.. bpo: 27239 +.. date: 9281 +.. nonce: fToURh +.. section: IDLE + +idlelib.macosx.isXyzTk functions initialize as needed. + +.. + +.. bpo: 27262 +.. date: 9280 +.. nonce: t7ckly +.. section: IDLE + +move Aqua unbinding code, which enable context menus, to macosx. + +.. + +.. bpo: 24759 +.. date: 9279 +.. nonce: ccmySu +.. section: IDLE + +Make clear in idlelib.idle_test.__init__ that the directory is a private +implementation of test.test_idle and tool for maintainers. + +.. + +.. bpo: 27196 +.. date: 9278 +.. nonce: 3yp8TF +.. section: IDLE + +Stop 'ThemeChanged' warnings when running IDLE tests. These persisted after +other warnings were suppressed in #20567. Apply Serhiy Storchaka's +update_idletasks solution to four test files. Record this additional advice +in idle_test/README.txt + +.. + +.. bpo: 20567 +.. date: 9277 +.. nonce: hhT32b +.. section: IDLE + +Revise idle_test/README.txt with advice about avoiding tk warning messages +from tests. Apply advice to several IDLE tests. + +.. + +.. bpo: 24225 +.. date: 9276 +.. nonce: NxQCka +.. section: IDLE + +Update idlelib/README.txt with new file names and event handlers. + +.. + +.. bpo: 27156 +.. date: 9275 +.. nonce: j1N9br +.. section: IDLE + +Remove obsolete code not used by IDLE. + +.. + +.. bpo: 27117 +.. date: 9274 +.. nonce: YrLPf4 +.. section: IDLE + +Make colorizer htest and turtledemo work with dark themes. Move code for +configuring text widget colors to a new function. + +.. + +.. bpo: 24225 +.. date: 9273 +.. nonce: RbyFuV +.. section: IDLE + +Rename many `idlelib/*.py` and `idle_test/test_*.py` files. Edit files to +replace old names with new names when the old name referred to the module +rather than the class it contained. See the issue and IDLE section in What's +New in 3.6 for more. + +.. + +.. bpo: 26673 +.. date: 9272 +.. nonce: dh0_Ij +.. section: IDLE + +When tk reports font size as 0, change to size 10. Such fonts on Linux +prevented the configuration dialog from opening. + +.. + +.. bpo: 21939 +.. date: 9271 +.. nonce: pWz-OK +.. section: IDLE + +Add test for IDLE's percolator. Original patch by Saimadhav Heblikar. + +.. + +.. bpo: 21676 +.. date: 9270 +.. nonce: hqy6Qh +.. section: IDLE + +Add test for IDLE's replace dialog. Original patch by Saimadhav Heblikar. + +.. + +.. bpo: 18410 +.. date: 9269 +.. nonce: DLSPZo +.. section: IDLE + +Add test for IDLE's search dialog. Original patch by Westley Martínez. + +.. + +.. bpo: 21703 +.. date: 9268 +.. nonce: bEU8sP +.. section: IDLE + +Add test for undo delegator. Patch mostly by Saimadhav Heblikar . + +.. + +.. bpo: 27044 +.. date: 9267 +.. nonce: 4y7tyM +.. section: IDLE + +Add ConfigDialog.remove_var_callbacks to stop memory leaks. + +.. + +.. bpo: 23977 +.. date: 9266 +.. nonce: miDjj8 +.. section: IDLE + +Add more asserts to test_delegator. + +.. + +.. bpo: 16484 +.. date: 9265 +.. nonce: ITzcGg +.. section: Documentation + +Change the default PYTHONDOCS URL to "https:", and fix the resulting links +to use lowercase. Patch by Sean Rodman, test by Kaushik Nadikuditi. + +.. + +.. bpo: 24136 +.. date: 9264 +.. nonce: MUK0zK +.. section: Documentation + +Document the new :pep:`448` unpacking syntax of 3.5. + +.. + +.. bpo: 22558 +.. date: 9263 +.. nonce: Pk02YC +.. section: Documentation + +Add remaining doc links to source code for Python-coded modules. Patch by +Yoni Lavi. + +.. + +.. bpo: 25285 +.. date: 9262 +.. nonce: 6CxIBo +.. section: Tests + +regrtest now uses subprocesses when the -j1 command line option is used: +each test file runs in a fresh child process. Before, the -j1 option was +ignored. + +.. + +.. bpo: 25285 +.. date: 9261 +.. nonce: ENYqUQ +.. section: Tests + +Tools/buildbot/test.bat script now uses -j1 by default to run each test file +in fresh child process. + +.. + +.. bpo: 27064 +.. date: 9260 +.. nonce: xeY1WF +.. section: Windows + +The py.exe launcher now defaults to Python 3. The Windows launcher +``py.exe`` no longer prefers an installed Python 2 version over Python 3 by +default when used interactively. + +.. + +.. bpo: 17500 +.. date: 9257 +.. nonce: QTZbRV +.. section: Windows + +Remove unused and outdated icons. (See also: +https://github.com/python/pythondotorg/issues/945) + +.. + +.. bpo: 27229 +.. date: 9259 +.. nonce: C2NDch +.. section: Build + +Fix the cross-compiling pgen rule for in-tree builds. Patch by Xavier de +Gaye. + +.. + +.. bpo: 26930 +.. date: 9258 +.. nonce: Sqz2O3 +.. section: Build + +Update OS X 10.5+ 32-bit-only installer to build and link with OpenSSL +1.0.2h. + +.. + +.. bpo: 27186 +.. date: 9256 +.. nonce: Ll8R-t +.. section: C API + +Add the PyOS_FSPath() function (part of :pep:`519`). + +.. + +.. bpo: 26282 +.. date: 9255 +.. nonce: Rp-R6L +.. section: C API + +PyArg_ParseTupleAndKeywords() now supports positional-only parameters. + +.. + +.. bpo: 26282 +.. date: 9254 +.. nonce: DRRV-- +.. section: Tools/Demos + +Argument Clinic now supports positional-only and keyword parameters in the +same function. diff --git a/Misc/NEWS.d/3.6.0a3.rst b/Misc/NEWS.d/3.6.0a3.rst new file mode 100644 index 00000000..62892b59 --- /dev/null +++ b/Misc/NEWS.d/3.6.0a3.rst @@ -0,0 +1,537 @@ +.. release date: 2016-07-11 +.. bpo: 27278 +.. date: 9361 +.. nonce: y_HkGw +.. original section: Library +.. section: Security + +Fix os.urandom() implementation using getrandom() on Linux. Truncate size +to INT_MAX and loop until we collected enough random bytes, instead of +casting a directly Py_ssize_t to int. + +.. + +.. bpo: 22636 +.. date: 9357 +.. nonce: 3fQW_g +.. original section: Library +.. section: Security + +Avoid shell injection problems with ctypes.util.find_library(). + +.. + +.. bpo: 27473 +.. date: 9385 +.. nonce: _nOtTA +.. section: Core and Builtins + +Fixed possible integer overflow in bytes and bytearray concatenations. +Patch by Xiang Zhang. + +.. + +.. bpo: 23034 +.. date: 9384 +.. nonce: GWaUqn +.. section: Core and Builtins + +The output of a special Python build with defined COUNT_ALLOCS, +SHOW_ALLOC_COUNT or SHOW_TRACK_COUNT macros is now off by default. It can +be re-enabled using the "-X showalloccount" option. It now outputs to +stderr instead of stdout. + +.. + +.. bpo: 27443 +.. date: 9383 +.. nonce: 87ZwZ1 +.. section: Core and Builtins + +__length_hint__() of bytearray iterators no longer return a negative integer +for a resized bytearray. + +.. + +.. bpo: 27007 +.. date: 9382 +.. nonce: Gg8Um4 +.. section: Core and Builtins + +The fromhex() class methods of bytes and bytearray subclasses now return an +instance of corresponding subclass. + +.. + +.. bpo: 26844 +.. date: 9381 +.. nonce: I0wdnY +.. section: Library + +Fix error message for imp.find_module() to refer to 'path' instead of +'name'. Patch by Lev Maximov. + +.. + +.. bpo: 23804 +.. date: 9380 +.. nonce: ipFvxc +.. section: Library + +Fix SSL zero-length recv() calls to not block and not raise an error about +unclean EOF. + +.. + +.. bpo: 27466 +.. date: 9379 +.. nonce: C_3a8E +.. section: Library + +Change time format returned by http.cookie.time2netscape, confirming the +netscape cookie format and making it consistent with documentation. + +.. + +.. bpo: 21708 +.. date: 9378 +.. nonce: RpPYiv +.. section: Library + +Deprecated dbm.dumb behavior that differs from common dbm behavior: creating +a database in 'r' and 'w' modes and modifying a database in 'r' mode. + +.. + +.. bpo: 26721 +.. date: 9377 +.. nonce: L37Y7r +.. section: Library + +Change the socketserver.StreamRequestHandler.wfile attribute to implement +BufferedIOBase. In particular, the write() method no longer does partial +writes. + +.. + +.. bpo: 22115 +.. date: 9376 +.. nonce: vG5UQW +.. section: Library + +Added methods trace_add, trace_remove and trace_info in the tkinter.Variable +class. They replace old methods trace_variable, trace, trace_vdelete and +trace_vinfo that use obsolete Tcl commands and might not work in future +versions of Tcl. Fixed old tracing methods: trace_vdelete() with wrong mode +no longer break tracing, trace_vinfo() now always returns a list of pairs of +strings, tracing in the "u" mode now works. + +.. + +.. bpo: 26243 +.. date: 9375 +.. nonce: dBtlhI +.. section: Library + +Only the level argument to zlib.compress() is keyword argument now. The +first argument is positional-only. + +.. + +.. bpo: 27038 +.. date: 9374 +.. nonce: yGMV4h +.. section: Library + +Expose the DirEntry type as os.DirEntry. Code patch by Jelle Zijlstra. + +.. + +.. bpo: 27186 +.. date: 9373 +.. nonce: OtorpF +.. section: Library + +Update os.fspath()/PyOS_FSPath() to check the return value of __fspath__() +to be either str or bytes. + +.. + +.. bpo: 18726 +.. date: 9372 +.. nonce: eIXHIl +.. section: Library + +All optional parameters of the dump(), dumps(), load() and loads() functions +and JSONEncoder and JSONDecoder class constructors in the json module are +now keyword-only. + +.. + +.. bpo: 27319 +.. date: 9371 +.. nonce: vDl2zm +.. section: Library + +Methods selection_set(), selection_add(), selection_remove() and +selection_toggle() of ttk.TreeView now allow passing multiple items as +multiple arguments instead of passing them as a tuple. Deprecated +undocumented ability of calling the selection() method with arguments. + +.. + +.. bpo: 27079 +.. date: 9370 +.. nonce: c7d0Ym +.. section: Library + +Fixed curses.ascii functions isblank(), iscntrl() and ispunct(). + +.. + +.. bpo: 27294 +.. date: 9369 +.. nonce: 0WSp9y +.. section: Library + +Numerical state in the repr for Tkinter event objects is now represented as +a combination of known flags. + +.. + +.. bpo: 27177 +.. date: 9368 +.. nonce: U6jRnd +.. section: Library + +Match objects in the re module now support index-like objects as group +indices. Based on patches by Jeroen Demeyer and Xiang Zhang. + +.. + +.. bpo: 26754 +.. date: 9367 +.. nonce: J3n0QW +.. section: Library + +Some functions (compile() etc) accepted a filename argument encoded as an +iterable of integers. Now only strings and byte-like objects are accepted. + +.. + +.. bpo: 26536 +.. date: 9366 +.. nonce: DgLWm- +.. section: Library + +socket.ioctl now supports SIO_LOOPBACK_FAST_PATH. Patch by Daniel Stokes. + +.. + +.. bpo: 27048 +.. date: 9365 +.. nonce: EVe-Bk +.. section: Library + +Prevents distutils failing on Windows when environment variables contain +non-ASCII characters + +.. + +.. bpo: 27330 +.. date: 9364 +.. nonce: GJaFCV +.. section: Library + +Fixed possible leaks in the ctypes module. + +.. + +.. bpo: 27238 +.. date: 9363 +.. nonce: Q6v6Qv +.. section: Library + +Got rid of bare excepts in the turtle module. Original patch by Jelle +Zijlstra. + +.. + +.. bpo: 27122 +.. date: 9362 +.. nonce: 06t7zN +.. section: Library + +When an exception is raised within the context being managed by a +contextlib.ExitStack() and one of the exit stack generators catches and +raises it in a chain, do not re-raise the original exception when exiting, +let the new chained one through. This avoids the :pep:`479` bug described in +issue25782. + +.. + +.. bpo: 16864 +.. date: 9360 +.. nonce: W7tJDa +.. section: Library + +sqlite3.Cursor.lastrowid now supports REPLACE statement. Initial patch by +Alex LordThorsen. + +.. + +.. bpo: 26386 +.. date: 9359 +.. nonce: 9L3Ut4 +.. section: Library + +Fixed ttk.TreeView selection operations with item id's containing spaces. + +.. + +.. bpo: 8637 +.. date: 9358 +.. nonce: lHiUSA +.. section: Library + +Honor a pager set by the env var MANPAGER (in preference to one set by the +env var PAGER). + +.. + +.. bpo: 16182 +.. date: 9356 +.. nonce: RgFXyr +.. section: Library + +Fix various functions in the "readline" module to use the locale encoding, +and fix get_begidx() and get_endidx() to return code point indexes. + +.. + +.. bpo: 27392 +.. date: 9355 +.. nonce: obfni7 +.. section: Library + +Add loop.connect_accepted_socket(). Patch by Jim Fulton. + +.. + +.. bpo: 27477 +.. date: 9354 +.. nonce: iEuL-9 +.. section: IDLE + +IDLE search dialogs now use ttk widgets. + +.. + +.. bpo: 27173 +.. date: 9353 +.. nonce: M-fYaV +.. section: IDLE + +Add 'IDLE Modern Unix' to the built-in key sets. Make the default key set +depend on the platform. Add tests for the changes to the config module. + +.. + +.. bpo: 27452 +.. date: 9352 +.. nonce: dLxZ8W +.. section: IDLE + +make command line "idle-test> python test_help.py" work. __file__ is +relative when python is started in the file's directory. + +.. + +.. bpo: 27452 +.. date: 9351 +.. nonce: RtWnyR +.. section: IDLE + +add line counter and crc to IDLE configHandler test dump. + +.. + +.. bpo: 27380 +.. date: 9350 +.. nonce: Q39r9U +.. section: IDLE + +IDLE: add query.py with base Query dialog and ttk widgets. Module had +subclasses SectionName, ModuleName, and HelpSource, which are used to get +information from users by configdialog and file =>Load Module. Each subclass +has itw own validity checks. Using ModuleName allows users to edit bad +module names instead of starting over. Add tests and delete the two files +combined into the new one. + +.. + +.. bpo: 27372 +.. date: 9349 +.. nonce: k3Wj2V +.. section: IDLE + +Test_idle no longer changes the locale. + +.. + +.. bpo: 27365 +.. date: 9348 +.. nonce: y7ys_A +.. section: IDLE + +Allow non-ascii chars in IDLE NEWS.txt, for contributor names. + +.. + +.. bpo: 27245 +.. date: 9347 +.. nonce: u9aKO1 +.. section: IDLE + +IDLE: Cleanly delete custom themes and key bindings. Previously, when IDLE +was started from a console or by import, a cascade of warnings was emitted. +Patch by Serhiy Storchaka. + +.. + +.. bpo: 24137 +.. date: 9346 +.. nonce: v8o-IT +.. section: IDLE + +Run IDLE, test_idle, and htest with tkinter default root disabled. Fix code +and tests that fail with this restriction. Fix htests to not create a +second and redundant root and mainloop. + +.. + +.. bpo: 27310 +.. date: 9345 +.. nonce: KiURpC +.. section: IDLE + +Fix IDLE.app failure to launch on OS X due to vestigial import. + +.. + +.. bpo: 26754 +.. date: 9344 +.. nonce: Qm_N79 +.. section: C API + +PyUnicode_FSDecoder() accepted a filename argument encoded as an iterable of +integers. Now only strings and byte-like objects are accepted. + +.. + +.. bpo: 28066 +.. date: 9343 +.. nonce: _3xImV +.. section: Build + +Fix the logic that searches build directories for generated include files +when building outside the source tree. + +.. + +.. bpo: 27442 +.. date: 9342 +.. nonce: S2M0cz +.. section: Build + +Expose the Android API level that python was built against, in +sysconfig.get_config_vars() as 'ANDROID_API_LEVEL'. + +.. + +.. bpo: 27434 +.. date: 9341 +.. nonce: 4nRZmn +.. section: Build + +The interpreter that runs the cross-build, found in PATH, must now be of the +same feature version (e.g. 3.6) as the source being built. + +.. + +.. bpo: 26930 +.. date: 9340 +.. nonce: 9JUeSD +.. section: Build + +Update Windows builds to use OpenSSL 1.0.2h. + +.. + +.. bpo: 23968 +.. date: 9339 +.. nonce: 7AuSK9 +.. section: Build + +Rename the platform directory from plat-$(MACHDEP) to +plat-$(PLATFORM_TRIPLET). Rename the config directory (LIBPL) from +config-$(LDVERSION) to config-$(LDVERSION)-$(PLATFORM_TRIPLET). Install the +platform specific _sysconfigdata module into the platform directory and +rename it to include the ABIFLAGS. + +.. + +.. bpo: 0 +.. date: 9338 +.. nonce: U46i2u +.. section: Build + +Don't use largefile support for GNU/Hurd. + +.. + +.. bpo: 27332 +.. date: 9337 +.. nonce: OuRZp9 +.. section: Tools/Demos + +Fixed the type of the first argument of module-level functions generated by +Argument Clinic. Patch by Petr Viktorin. + +.. + +.. bpo: 27418 +.. date: 9336 +.. nonce: W2m_8I +.. section: Tools/Demos + +Fixed Tools/importbench/importbench.py. + +.. + +.. bpo: 19489 +.. date: 9335 +.. nonce: jvzuO7 +.. section: Documentation + +Moved the search box from the sidebar to the header and footer of each page. +Patch by Ammar Askar. + +.. + +.. bpo: 27285 +.. date: 9334 +.. nonce: wZur0b +.. section: Documentation + +Update documentation to reflect the deprecation of ``pyvenv`` and normalize +on the term "virtual environment". Patch by Steve Piercy. + +.. + +.. bpo: 27027 +.. date: 9333 +.. nonce: 5oRSGL +.. section: Tests + +Added test.support.is_android that is True when this is an Android build. diff --git a/Misc/NEWS.d/3.6.0a4.rst b/Misc/NEWS.d/3.6.0a4.rst new file mode 100644 index 00000000..d613fd5d --- /dev/null +++ b/Misc/NEWS.d/3.6.0a4.rst @@ -0,0 +1,685 @@ +.. bpo: 27704 +.. date: 9455 +.. nonce: RUxzHf +.. release date: 2016-08-15 +.. section: Core and Builtins + +Optimized creating bytes and bytearray from byte-like objects and iterables. +Speed up to 3 times for short objects. Original patch by Naoki Inada. + +.. + +.. bpo: 26823 +.. date: 9454 +.. nonce: UWORiU +.. section: Core and Builtins + +Large sections of repeated lines in tracebacks are now abbreviated as +"[Previous line repeated {count} more times]" by the builtin traceback +rendering. Patch by Emanuel Barry. + +.. + +.. bpo: 27574 +.. date: 9453 +.. nonce: q73Tss +.. section: Core and Builtins + +Decreased an overhead of parsing keyword arguments in functions implemented +with using Argument Clinic. + +.. + +.. bpo: 22557 +.. date: 9452 +.. nonce: Hta2Rz +.. section: Core and Builtins + +Now importing already imported modules is up to 2.5 times faster. + +.. + +.. bpo: 17596 +.. date: 9451 +.. nonce: XgbA9V +.. section: Core and Builtins + +Include <wincrypt.h> to help with Min GW building. + +.. + +.. bpo: 17599 +.. date: 9450 +.. nonce: noy7o1 +.. section: Core and Builtins + +On Windows, rename the privately defined REPARSE_DATA_BUFFER structure to +avoid conflicting with the definition from Min GW. + +.. + +.. bpo: 27507 +.. date: 9449 +.. nonce: 3pX0Be +.. section: Core and Builtins + +Add integer overflow check in bytearray.extend(). Patch by Xiang Zhang. + +.. + +.. bpo: 27581 +.. date: 9448 +.. nonce: KezjNt +.. section: Core and Builtins + +Don't rely on wrapping for overflow check in PySequence_Tuple(). Patch by +Xiang Zhang. + +.. + +.. bpo: 1621 +.. date: 9447 +.. nonce: _FZWTr +.. section: Core and Builtins + +Avoid signed integer overflow in list and tuple operations. Patch by Xiang +Zhang. + +.. + +.. bpo: 27419 +.. date: 9446 +.. nonce: YaGodL +.. section: Core and Builtins + +Standard __import__() no longer look up "__import__" in globals or builtins +for importing submodules or "from import". Fixed a crash if raise a warning +about unabling to resolve package from __spec__ or __package__. + +.. + +.. bpo: 27083 +.. date: 9445 +.. nonce: F4ZT1C +.. section: Core and Builtins + +Respect the PYTHONCASEOK environment variable under Windows. + +.. + +.. bpo: 27514 +.. date: 9444 +.. nonce: NLbwPG +.. section: Core and Builtins + +Make having too many statically nested blocks a SyntaxError instead of +SystemError. + +.. + +.. bpo: 27366 +.. date: 9443 +.. nonce: VrInsj +.. section: Core and Builtins + +Implemented :pep:`487` (Simpler customization of class creation). Upon +subclassing, the __init_subclass__ classmethod is called on the base class. +Descriptors are initialized with __set_name__ after class creation. + +.. + +.. bpo: 26027 +.. date: 9442 +.. nonce: nfVMKM +.. section: Library + +Add :pep:`519`/__fspath__() support to the os and os.path modules. Includes +code from Jelle Zijlstra. (See also: bpo-27524) + +.. + +.. bpo: 27598 +.. date: 9441 +.. nonce: y7PtEV +.. section: Library + +Add Collections to collections.abc. Patch by Ivan Levkivskyi, docs by Neil +Girdhar. + +.. + +.. bpo: 25958 +.. date: 9440 +.. nonce: X-V4U1 +.. section: Library + +Support "anti-registration" of special methods from various ABCs, like +__hash__, __iter__ or __len__. All these (and several more) can be set to +None in an implementation class and the behavior will be as if the method is +not defined at all. (Previously, this mechanism existed only for __hash__, +to make mutable classes unhashable.) Code contributed by Andrew Barnert and +Ivan Levkivskyi. + +.. + +.. bpo: 16764 +.. date: 9439 +.. nonce: cPbNjL +.. section: Library + +Support keyword arguments to zlib.decompress(). Patch by Xiang Zhang. + +.. + +.. bpo: 27736 +.. date: 9438 +.. nonce: 8kMhpQ +.. section: Library + +Prevent segfault after interpreter re-initialization due to ref count +problem introduced in code for Issue #27038 in 3.6.0a3. Patch by Xiang +Zhang. + +.. + +.. bpo: 25628 +.. date: 9437 +.. nonce: UcQnHF +.. section: Library + +The *verbose* and *rename* parameters for collections.namedtuple are now +keyword-only. + +.. + +.. bpo: 12345 +.. date: 9436 +.. nonce: nbAEM8 +.. section: Library + +Add mathematical constant tau to math and cmath. See also :pep:`628`. + +.. + +.. bpo: 26823 +.. date: 9435 +.. nonce: HcO8tR +.. section: Library + +traceback.StackSummary.format now abbreviates large sections of repeated +lines as "[Previous line repeated {count} more times]" (this change then +further affects other traceback display operations in the module). Patch by +Emanuel Barry. + +.. + +.. bpo: 27664 +.. date: 9434 +.. nonce: 6DJPxw +.. section: Library + +Add to concurrent.futures.thread.ThreadPoolExecutor() the ability to specify +a thread name prefix. + +.. + +.. bpo: 27181 +.. date: 9433 +.. nonce: 8aw9TZ +.. section: Library + +Add geometric_mean and harmonic_mean to statistics module. + +.. + +.. bpo: 27573 +.. date: 9432 +.. nonce: B7XhTs +.. section: Library + +code.interact now prints an message when exiting. + +.. + +.. bpo: 6422 +.. date: 9431 +.. nonce: iBSc45 +.. section: Library + +Add autorange method to timeit.Timer objects. + +.. + +.. bpo: 27773 +.. date: 9430 +.. nonce: hMSSeX +.. section: Library + +Correct some memory management errors server_hostname in _ssl.wrap_socket(). + +.. + +.. bpo: 26750 +.. date: 9429 +.. nonce: OQn3fr +.. section: Library + +unittest.mock.create_autospec() now works properly for subclasses of +property() and other data descriptors. Removes the never publicly used, +never documented unittest.mock.DescriptorTypes tuple. + +.. + +.. bpo: 26754 +.. date: 9428 +.. nonce: XZqomf +.. section: Library + +Undocumented support of general bytes-like objects as path in compile() and +similar functions is now deprecated. + +.. + +.. bpo: 26800 +.. date: 9427 +.. nonce: QDcK8u +.. section: Library + +Undocumented support of general bytes-like objects as paths in os functions +is now deprecated. + +.. + +.. bpo: 26981 +.. date: 9426 +.. nonce: yhNTCf +.. section: Library + +Add _order_ compatibility shim to enum.Enum for Python 2/3 code bases. + +.. + +.. bpo: 27661 +.. date: 9425 +.. nonce: 3JZckO +.. section: Library + +Added tzinfo keyword argument to datetime.combine. + +.. + +.. bpo: 0 +.. date: 9424 +.. nonce: Ny9oPv +.. section: Library + +In the curses module, raise an error if window.getstr() or window.instr() is +passed a negative value. + +.. + +.. bpo: 27783 +.. date: 9423 +.. nonce: cR1jXH +.. section: Library + +Fix possible usage of uninitialized memory in operator.methodcaller. + +.. + +.. bpo: 27774 +.. date: 9422 +.. nonce: FDcik1 +.. section: Library + +Fix possible Py_DECREF on unowned object in _sre. + +.. + +.. bpo: 27760 +.. date: 9421 +.. nonce: gxMjp4 +.. section: Library + +Fix possible integer overflow in binascii.b2a_qp. + +.. + +.. bpo: 27758 +.. date: 9420 +.. nonce: 0NRV03 +.. section: Library + +Fix possible integer overflow in the _csv module for large record lengths. + +.. + +.. bpo: 27568 +.. date: 9419 +.. nonce: OnuO9s +.. section: Library + +Prevent HTTPoxy attack (CVE-2016-1000110). Ignore the HTTP_PROXY variable +when REQUEST_METHOD environment is set, which indicates that the script is +in CGI mode. + +.. + +.. bpo: 7063 +.. date: 9418 +.. nonce: nXsVKB +.. section: Library + +Remove dead code from the "array" module's slice handling. Patch by Chuck. + +.. + +.. bpo: 27656 +.. date: 9417 +.. nonce: joTscM +.. section: Library + +Do not assume sched.h defines any SCHED_* constants. + +.. + +.. bpo: 27130 +.. date: 9416 +.. nonce: SUxwXZ +.. section: Library + +In the "zlib" module, fix handling of large buffers (typically 4 GiB) when +compressing and decompressing. Previously, inputs were limited to 4 GiB, +and compression and decompression operations did not properly handle results +of 4 GiB. + +.. + +.. bpo: 24773 +.. date: 9415 +.. nonce: IDW05R +.. section: Library + +Implemented :pep:`495` (Local Time Disambiguation). + +.. + +.. bpo: 0 +.. date: 9414 +.. nonce: lOkwM8 +.. section: Library + +Expose the EPOLLEXCLUSIVE constant (when it is defined) in the select +module. + +.. + +.. bpo: 27567 +.. date: 9413 +.. nonce: bYOgyw +.. section: Library + +Expose the EPOLLRDHUP and POLLRDHUP constants in the select module. + +.. + +.. bpo: 1621 +.. date: 9412 +.. nonce: 0nclmI +.. section: Library + +Avoid signed int negation overflow in the "audioop" module. + +.. + +.. bpo: 27533 +.. date: 9411 +.. nonce: iDmKzV +.. section: Library + +Release GIL in nt._isdir + +.. + +.. bpo: 17711 +.. date: 9410 +.. nonce: 47AILJ +.. section: Library + +Fixed unpickling by the persistent ID with protocol 0. Original patch by +Alexandre Vassalotti. + +.. + +.. bpo: 27522 +.. date: 9409 +.. nonce: 8vVz_t +.. section: Library + +Avoid an unintentional reference cycle in email.feedparser. + +.. + +.. bpo: 27512 +.. date: 9408 +.. nonce: FaGwup +.. section: Library + +Fix a segfault when os.fspath() called an __fspath__() method that raised an +exception. Patch by Xiang Zhang. + +.. + +.. bpo: 27714 +.. date: 9407 +.. nonce: bUEDsI +.. section: IDLE + +text_textview and test_autocomplete now pass when re-run in the same +process. This occurs when test_idle fails when run with the -w option but +without -jn. Fix warning from test_config. + +.. + +.. bpo: 27621 +.. date: 9406 +.. nonce: BcpOPU +.. section: IDLE + +Put query response validation error messages in the query box itself instead +of in a separate messagebox. Redo tests to match. Add Mac OSX refinements. +Original patch by Mark Roseman. + +.. + +.. bpo: 27620 +.. date: 9405 +.. nonce: TXRR6x +.. section: IDLE + +Escape key now closes Query box as cancelled. + +.. + +.. bpo: 27609 +.. date: 9404 +.. nonce: MbTuKa +.. section: IDLE + +IDLE: tab after initial whitespace should tab, not autocomplete. This fixes +problem with writing docstrings at least twice indented. + +.. + +.. bpo: 27609 +.. date: 9403 +.. nonce: OBYgv_ +.. section: IDLE + +Explicitly return None when there are also non-None returns. In a few cases, +reverse a condition and eliminate a return. + +.. + +.. bpo: 25507 +.. date: 9402 +.. nonce: lxf68d +.. section: IDLE + +IDLE no longer runs buggy code because of its tkinter imports. Users must +include the same imports required to run directly in Python. + +.. + +.. bpo: 27173 +.. date: 9401 +.. nonce: M-fYaV +.. section: IDLE + +Add 'IDLE Modern Unix' to the built-in key sets. Make the default key set +depend on the platform. Add tests for the changes to the config module. + +.. + +.. bpo: 27452 +.. date: 9400 +.. nonce: RtWnyR +.. section: IDLE + +add line counter and crc to IDLE configHandler test dump. + +.. + +.. bpo: 25805 +.. date: 9399 +.. nonce: 9SVxXQ +.. section: Tests + +Skip a test in test_pkgutil as needed that doesn't work when ``__name__ == +__main__``. Patch by SilentGhost. + +.. + +.. bpo: 27472 +.. date: 9398 +.. nonce: NS3L93 +.. section: Tests + +Add test.support.unix_shell as the path to the default shell. + +.. + +.. bpo: 27369 +.. date: 9397 +.. nonce: LG7U2D +.. section: Tests + +In test_pyexpat, avoid testing an error message detail that changed in Expat +2.2.0. + +.. + +.. bpo: 27594 +.. date: 9396 +.. nonce: w3F57B +.. section: Tests + +Prevent assertion error when running test_ast with coverage enabled: ensure +code object has a valid first line number. Patch suggested by Ivan +Levkivskyi. + +.. + +.. bpo: 27647 +.. date: 9395 +.. nonce: -1HUR6 +.. section: Windows + +Update bundled Tcl/Tk to 8.6.6. + +.. + +.. bpo: 27610 +.. date: 9394 +.. nonce: O0o0mB +.. section: Windows + +Adds :pep:`514` metadata to Windows installer + +.. + +.. bpo: 27469 +.. date: 9393 +.. nonce: 0GwDkX +.. section: Windows + +Adds a shell extension to the launcher so that drag and drop works +correctly. + +.. + +.. bpo: 27309 +.. date: 9392 +.. nonce: chiOo6 +.. section: Windows + +Enables proper Windows styles in python[w].exe manifest. + +.. + +.. bpo: 27713 +.. date: 9391 +.. nonce: _3DgXG +.. section: Build + +Suppress spurious build warnings when updating importlib's bootstrap files. +Patch by Xiang Zhang + +.. + +.. bpo: 25825 +.. date: 9390 +.. nonce: MLbdVU +.. section: Build + +Correct the references to Modules/python.exp, which is required on AIX. The +references were accidentally changed in 3.5.0a1. + +.. + +.. bpo: 27453 +.. date: 9389 +.. nonce: Pb5DBi +.. section: Build + +CPP invocation in configure must use CPPFLAGS. Patch by Chi Hsuan Yen. + +.. + +.. bpo: 27641 +.. date: 9388 +.. nonce: eGzgCk +.. section: Build + +The configure script now inserts comments into the makefile to prevent the +pgen and _freeze_importlib executables from being cross-compiled. + +.. + +.. bpo: 26662 +.. date: 9387 +.. nonce: XkwRxM +.. section: Build + +Set PYTHON_FOR_GEN in configure as the Python program to be used for file +generation during the build. + +.. + +.. bpo: 10910 +.. date: 9386 +.. nonce: ZdRayb +.. section: Build + +Avoid C++ compilation errors on FreeBSD and OS X. Also update FreedBSD +version checks for the original ctype UTF-8 workaround. diff --git a/Misc/NEWS.d/3.6.0b1.rst b/Misc/NEWS.d/3.6.0b1.rst new file mode 100644 index 00000000..3fbae5c6 --- /dev/null +++ b/Misc/NEWS.d/3.6.0b1.rst @@ -0,0 +1,1608 @@ +.. bpo: 23722 +.. date: 9619 +.. nonce: C-8boi +.. release date: 2016-09-12 +.. section: Core and Builtins + +The __class__ cell used by zero-argument super() is now initialized from +type.__new__ rather than __build_class__, so class methods relying on that +will now work correctly when called from metaclass methods during class +creation. Patch by Martin Teichmann. + +.. + +.. bpo: 25221 +.. date: 9618 +.. nonce: 9YbOxB +.. section: Core and Builtins + +Fix corrupted result from PyLong_FromLong(0) when Python is compiled with +NSMALLPOSINTS = 0. + +.. + +.. bpo: 27080 +.. date: 9617 +.. nonce: Te4Tjb +.. section: Core and Builtins + +Implement formatting support for :pep:`515`. Initial patch by Chris Angelico. + +.. + +.. bpo: 27199 +.. date: 9616 +.. nonce: GheADD +.. section: Core and Builtins + +In tarfile, expose copyfileobj bufsize to improve throughput. Patch by Jason +Fried. + +.. + +.. bpo: 27948 +.. date: 9615 +.. nonce: Rpw5nq +.. section: Core and Builtins + +In f-strings, only allow backslashes inside the braces (where the +expressions are). This is a breaking change from the 3.6 alpha releases, +where backslashes are allowed anywhere in an f-string. Also, require that +expressions inside f-strings be enclosed within literal braces, and not +escapes like ``f'\x7b"hi"\x7d'``. + +.. + +.. bpo: 28046 +.. date: 9614 +.. nonce: liHxFW +.. section: Core and Builtins + +Remove platform-specific directories from sys.path. + +.. + +.. bpo: 28071 +.. date: 9613 +.. nonce: PffE44 +.. section: Core and Builtins + +Add early-out for differencing from an empty set. + +.. + +.. bpo: 25758 +.. date: 9612 +.. nonce: yR-YTD +.. section: Core and Builtins + +Prevents zipimport from unnecessarily encoding a filename (patch by Eryk +Sun) + +.. + +.. bpo: 25856 +.. date: 9611 +.. nonce: neCvXl +.. section: Core and Builtins + +The __module__ attribute of extension classes and functions now is interned. +This leads to more compact pickle data with protocol 4. + +.. + +.. bpo: 27213 +.. date: 9610 +.. nonce: VCfkkp +.. section: Core and Builtins + +Rework CALL_FUNCTION* opcodes to produce shorter and more efficient +bytecode. Patch by Demur Rumed, design by Serhiy Storchaka, reviewed by +Serhiy Storchaka and Victor Stinner. + +.. + +.. bpo: 26331 +.. date: 9609 +.. nonce: TdJp8_ +.. section: Core and Builtins + +Implement tokenizing support for :pep:`515`. Patch by Georg Brandl. + +.. + +.. bpo: 27999 +.. date: 9608 +.. nonce: 8aacQj +.. section: Core and Builtins + +Make "global after use" a SyntaxError, and ditto for nonlocal. Patch by Ivan +Levkivskyi. + +.. + +.. bpo: 28003 +.. date: 9607 +.. nonce: noeoav +.. section: Core and Builtins + +Implement :pep:`525` -- Asynchronous Generators. + +.. + +.. bpo: 27985 +.. date: 9606 +.. nonce: 0ayJ5k +.. section: Core and Builtins + +Implement :pep:`526` -- Syntax for Variable Annotations. Patch by Ivan +Levkivskyi. + +.. + +.. bpo: 26058 +.. date: 9605 +.. nonce: UR_ojv +.. section: Core and Builtins + +Add a new private version to the builtin dict type, incremented at each +dictionary creation and at each dictionary change. Implementation of the PEP +509. + +.. + +.. bpo: 27364 +.. date: 9604 +.. nonce: 8u_LoD +.. section: Core and Builtins + +A backslash-character pair that is not a valid escape sequence now generates +a DeprecationWarning. Patch by Emanuel Barry. + +.. + +.. bpo: 27350 +.. date: 9603 +.. nonce: aABzcL +.. section: Core and Builtins + +`dict` implementation is changed like PyPy. It is more compact and preserves +insertion order. (Concept developed by Raymond Hettinger and patch by Inada +Naoki.) + +.. + +.. bpo: 27911 +.. date: 9602 +.. nonce: 1eaHRd +.. section: Core and Builtins + +Remove unnecessary error checks in ``exec_builtin_or_dynamic()``. + +.. + +.. bpo: 27078 +.. date: 9601 +.. nonce: ZevPQR +.. section: Core and Builtins + +Added BUILD_STRING opcode. Optimized f-strings evaluation. + +.. + +.. bpo: 17884 +.. date: 9600 +.. nonce: wGy0dr +.. section: Core and Builtins + +Python now requires systems with inttypes.h and stdint.h + +.. + +.. bpo: 27961 +.. date: 9599 +.. nonce: EYS8oe +.. section: Core and Builtins + +Require platforms to support ``long long``. Python hasn't compiled without +``long long`` for years, so this is basically a formality. + +.. + +.. bpo: 27355 +.. date: 9598 +.. nonce: qdIpxm +.. section: Core and Builtins + +Removed support for Windows CE. It was never finished, and Windows CE is no +longer a relevant platform for Python. + +.. + +.. bpo: 0 +.. date: 9597 +.. nonce: rdhhVw +.. section: Core and Builtins + +Implement :pep:`523`. + +.. + +.. bpo: 27870 +.. date: 9596 +.. nonce: Y0u34u +.. section: Core and Builtins + +A left shift of zero by a large integer no longer attempts to allocate large +amounts of memory. + +.. + +.. bpo: 25402 +.. date: 9595 +.. nonce: naeRHq +.. section: Core and Builtins + +In int-to-decimal-string conversion, improve the estimate of the +intermediate memory required, and remove an unnecessarily strict overflow +check. Patch by Serhiy Storchaka. + +.. + +.. bpo: 27214 +.. date: 9594 +.. nonce: CDh8S4 +.. section: Core and Builtins + +In long_invert, be more careful about modifying object returned by long_add, +and remove an unnecessary check for small longs. Thanks Oren Milman for +analysis and patch. + +.. + +.. bpo: 27506 +.. date: 9593 +.. nonce: eK87PI +.. section: Core and Builtins + +Support passing the bytes/bytearray.translate() "delete" argument by +keyword. + +.. + +.. bpo: 27812 +.. date: 9592 +.. nonce: sidcs8 +.. section: Core and Builtins + +Properly clear out a generator's frame's backreference to the generator to +prevent crashes in frame.clear(). + +.. + +.. bpo: 27811 +.. date: 9591 +.. nonce: T4AuBo +.. section: Core and Builtins + +Fix a crash when a coroutine that has not been awaited is finalized with +warnings-as-errors enabled. + +.. + +.. bpo: 27587 +.. date: 9590 +.. nonce: mbavY2 +.. section: Core and Builtins + +Fix another issue found by PVS-Studio: Null pointer check after use of 'def' +in _PyState_AddModule(). Initial patch by Christian Heimes. + +.. + +.. bpo: 27792 +.. date: 9589 +.. nonce: Np6_Hl +.. section: Core and Builtins + +The modulo operation applied to ``bool`` and other ``int`` subclasses now +always returns an ``int``. Previously the return type depended on the input +values. Patch by Xiang Zhang. + +.. + +.. bpo: 26984 +.. date: 9588 +.. nonce: 7--80J +.. section: Core and Builtins + +int() now always returns an instance of exact int. + +.. + +.. bpo: 25604 +.. date: 9587 +.. nonce: UkeHGy +.. section: Core and Builtins + +Fix a minor bug in integer true division; this bug could potentially have +caused off-by-one-ulp results on platforms with unreliable ldexp +implementations. + +.. + +.. bpo: 24254 +.. date: 9586 +.. nonce: 368r1U +.. section: Core and Builtins + +Make class definition namespace ordered by default. + +.. + +.. bpo: 27662 +.. date: 9585 +.. nonce: a8cBpq +.. section: Core and Builtins + +Fix an overflow check in ``List_New``: the original code was checking +against ``Py_SIZE_MAX`` instead of the correct upper bound of +``Py_SSIZE_T_MAX``. Patch by Xiang Zhang. + +.. + +.. bpo: 27782 +.. date: 9584 +.. nonce: C8OBQD +.. section: Core and Builtins + +Multi-phase extension module import now correctly allows the ``m_methods`` +field to be used to add module level functions to instances of non-module +types returned from ``Py_create_mod``. Patch by Xiang Zhang. + +.. + +.. bpo: 27936 +.. date: 9583 +.. nonce: AdOann +.. section: Core and Builtins + +The round() function accepted a second None argument for some types but not +for others. Fixed the inconsistency by accepting None for all numeric +types. + +.. + +.. bpo: 27487 +.. date: 9582 +.. nonce: jeTQNr +.. section: Core and Builtins + +Warn if a submodule argument to "python -m" or runpy.run_module() is found +in sys.modules after parent packages are imported, but before the submodule +is executed. + +.. + +.. bpo: 27157 +.. date: 9581 +.. nonce: Wf_eFE +.. section: Core and Builtins + +Make only type() itself accept the one-argument form. Patch by Eryk Sun and +Emanuel Barry. + +.. + +.. bpo: 27558 +.. date: 9580 +.. nonce: VmltMh +.. section: Core and Builtins + +Fix a SystemError in the implementation of "raise" statement. In a brand new +thread, raise a RuntimeError since there is no active exception to reraise. +Patch written by Xiang Zhang. + +.. + +.. bpo: 28008 +.. date: 9579 +.. nonce: 0DdIrA +.. section: Core and Builtins + +Implement :pep:`530` -- asynchronous comprehensions. + +.. + +.. bpo: 27942 +.. date: 9578 +.. nonce: wCAkW5 +.. section: Core and Builtins + +Fix memory leak in codeobject.c + +.. + +.. bpo: 28732 +.. date: 9577 +.. nonce: xkG8k7 +.. section: Library + +Fix crash in os.spawnv() with no elements in args + +.. + +.. bpo: 28485 +.. date: 9576 +.. nonce: WuKqKh +.. section: Library + +Always raise ValueError for negative compileall.compile_dir(workers=...) +parameter, even when multithreading is unavailable. + +.. + +.. bpo: 28037 +.. date: 9575 +.. nonce: -3u7zq +.. section: Library + +Use sqlite3_get_autocommit() instead of setting Connection->inTransaction +manually. + +.. + +.. bpo: 25283 +.. date: 9574 +.. nonce: qwQDX2 +.. section: Library + +Attributes tm_gmtoff and tm_zone are now available on all platforms in the +return values of time.localtime() and time.gmtime(). + +.. + +.. bpo: 24454 +.. date: 9573 +.. nonce: pUTKOA +.. section: Library + +Regular expression match object groups are now accessible using __getitem__. +"mo[x]" is equivalent to "mo.group(x)". + +.. + +.. bpo: 10740 +.. date: 9572 +.. nonce: 8iGFan +.. section: Library + +sqlite3 no longer implicitly commit an open transaction before DDL +statements. + +.. + +.. bpo: 17941 +.. date: 9571 +.. nonce: E9rm_o +.. section: Library + +Add a *module* parameter to collections.namedtuple(). + +.. + +.. bpo: 22493 +.. date: 9570 +.. nonce: yDfUrj +.. section: Library + +Inline flags now should be used only at the start of the regular expression. +Deprecation warning is emitted if uses them in the middle of the regular +expression. + +.. + +.. bpo: 26885 +.. date: 9569 +.. nonce: TJ779X +.. section: Library + +xmlrpc now supports unmarshalling additional data types used by Apache +XML-RPC implementation for numerics and None. + +.. + +.. bpo: 28070 +.. date: 9568 +.. nonce: Kot8Hu +.. section: Library + +Fixed parsing inline verbose flag in regular expressions. + +.. + +.. bpo: 19500 +.. date: 9567 +.. nonce: H7q5im +.. section: Library + +Add client-side SSL session resumption to the ssl module. + +.. + +.. bpo: 28022 +.. date: 9566 +.. nonce: 08kTMg +.. section: Library + +Deprecate ssl-related arguments in favor of SSLContext. The deprecation +include manual creation of SSLSocket and certfile/keyfile (or similar) in +ftplib, httplib, imaplib, smtplib, poplib and urllib. + +.. + +.. bpo: 28043 +.. date: 9565 +.. nonce: 588Oy3 +.. section: Library + +SSLContext has improved default settings: OP_NO_SSLv2, OP_NO_SSLv3, +OP_NO_COMPRESSION, OP_CIPHER_SERVER_PREFERENCE, OP_SINGLE_DH_USE, +OP_SINGLE_ECDH_USE and HIGH ciphers without MD5. + +.. + +.. bpo: 24693 +.. date: 9564 +.. nonce: a63Shp +.. section: Library + +Changed some RuntimeError's in the zipfile module to more appropriate types. +Improved some error messages and debugging output. + +.. + +.. bpo: 17909 +.. date: 9563 +.. nonce: SMNkt6 +.. section: Library + +``json.load`` and ``json.loads`` now support binary input encoded as UTF-8, +UTF-16 or UTF-32. Patch by Serhiy Storchaka. + +.. + +.. bpo: 27137 +.. date: 9562 +.. nonce: frjG8W +.. section: Library + +the pure Python fallback implementation of ``functools.partial`` now matches +the behaviour of its accelerated C counterpart for subclassing, pickling and +text representation purposes. Patch by Emanuel Barry and Serhiy Storchaka. + +.. + +.. bpo: 0 +.. date: 9561 +.. nonce: 81jNns +.. section: Library + +Fix possible integer overflows and crashes in the mmap module with unusual +usage patterns. + +.. + +.. bpo: 1703178 +.. date: 9560 +.. nonce: meb49K +.. section: Library + +Fix the ability to pass the --link-objects option to the distutils build_ext +command. + +.. + +.. bpo: 28019 +.. date: 9559 +.. nonce: KUhBaS +.. section: Library + +itertools.count() no longer rounds non-integer step in range between 1.0 and +2.0 to 1. + +.. + +.. bpo: 18401 +.. date: 9558 +.. nonce: _12WDV +.. section: Library + +Pdb now supports the 'readrc' keyword argument to control whether .pdbrc +files should be read. Patch by Martin Matusiak and Sam Kimbrel. + +.. + +.. bpo: 25969 +.. date: 9557 +.. nonce: qSPkl- +.. section: Library + +Update the lib2to3 grammar to handle the unpacking generalizations added in +3.5. + +.. + +.. bpo: 14977 +.. date: 9556 +.. nonce: 4MvALg +.. section: Library + +mailcap now respects the order of the lines in the mailcap files ("first +match"), as required by RFC 1542. Patch by Michael Lazar. + +.. + +.. bpo: 28082 +.. date: 9555 +.. nonce: EICw4d +.. section: Library + +Convert re flag constants to IntFlag. + +.. + +.. bpo: 28025 +.. date: 9554 +.. nonce: YxcZHY +.. section: Library + +Convert all ssl module constants to IntEnum and IntFlags. SSLContext +properties now return flags and enums. + +.. + +.. bpo: 23591 +.. date: 9553 +.. nonce: 7gSXAN +.. section: Library + +Add Flag, IntFlag, and auto() to enum module. + +.. + +.. bpo: 433028 +.. date: 9552 +.. nonce: yGjT0q +.. section: Library + +Added support of modifier spans in regular expressions. + +.. + +.. bpo: 24594 +.. date: 9551 +.. nonce: 9CnFVS +.. section: Library + +Validates persist parameter when opening MSI database + +.. + +.. bpo: 17582 +.. date: 9550 +.. nonce: MXEHxQ +.. section: Library + +xml.etree.ElementTree nows preserves whitespaces in attributes (Patch by +Duane Griffin. Reviewed and approved by Stefan Behnel.) + +.. + +.. bpo: 28047 +.. date: 9549 +.. nonce: pDu3Fm +.. section: Library + +Fixed calculation of line length used for the base64 CTE in the new email +policies. + +.. + +.. bpo: 27576 +.. date: 9548 +.. nonce: tqZxYv +.. section: Library + +Fix call order in OrderedDict.__init__(). + +.. + +.. bpo: 0 +.. date: 9547 +.. nonce: cxHuUo +.. section: Library + +email.generator.DecodedGenerator now supports the policy keyword. + +.. + +.. bpo: 28027 +.. date: 9546 +.. nonce: v39s1z +.. section: Library + +Remove undocumented modules from ``Lib/plat-*``: IN, CDROM, DLFCN, TYPES, +CDIO, and STROPTS. + +.. + +.. bpo: 27445 +.. date: 9545 +.. nonce: wOG0C0 +.. section: Library + +Don't pass str(_charset) to MIMEText.set_payload(). Patch by Claude Paroz. + +.. + +.. bpo: 24277 +.. date: 9544 +.. nonce: OgDA28 +.. section: Library + +The new email API is no longer provisional, and the docs have been +reorganized and rewritten to emphasize the new API. + +.. + +.. bpo: 22450 +.. date: 9543 +.. nonce: T3Sn_J +.. section: Library + +urllib now includes an ``Accept: */*`` header among the default headers. +This makes the results of REST API requests more consistent and predictable +especially when proxy servers are involved. + +.. + +.. bpo: 0 +.. date: 9542 +.. nonce: PVZStR +.. section: Library + +lib2to3.pgen3.driver.load_grammar() now creates a stable cache file between +runs given the same Grammar.txt input regardless of the hash randomization +setting. + +.. + +.. bpo: 28005 +.. date: 9541 +.. nonce: oJLK1w +.. section: Library + +Allow ImportErrors in encoding implementation to propagate. + +.. + +.. bpo: 26667 +.. date: 9540 +.. nonce: hWs9wA +.. section: Library + +Support path-like objects in importlib.util. + +.. + +.. bpo: 27570 +.. date: 9539 +.. nonce: pU0Zie +.. section: Library + +Avoid zero-length memcpy() etc calls with null source pointers in the +"ctypes" and "array" modules. + +.. + +.. bpo: 22233 +.. date: 9538 +.. nonce: uXSN0R +.. section: Library + +Break email header lines *only* on the RFC specified CR and LF characters, +not on arbitrary unicode line breaks. This also fixes a bug in HTTP header +parsing. + +.. + +.. bpo: 27331 +.. date: 9537 +.. nonce: akOxfh +.. section: Library + +The email.mime classes now all accept an optional policy keyword. + +.. + +.. bpo: 27988 +.. date: 9536 +.. nonce: VfMzZH +.. section: Library + +Fix email iter_attachments incorrect mutation of payload list. + +.. + +.. bpo: 16113 +.. date: 9535 +.. nonce: jyKRxs +.. section: Library + +Add SHA-3 and SHAKE support to hashlib module. + +.. + +.. bpo: 0 +.. date: 9534 +.. nonce: j7npJi +.. section: Library + +Eliminate a tautological-pointer-compare warning in _scproxy.c. + +.. + +.. bpo: 27776 +.. date: 9533 +.. nonce: dOJcUU +.. section: Library + +The :func:`os.urandom` function does now block on Linux 3.17 and newer until +the system urandom entropy pool is initialized to increase the security. +This change is part of the :pep:`524`. + +.. + +.. bpo: 27778 +.. date: 9532 +.. nonce: gvbf3F +.. section: Library + +Expose the Linux ``getrandom()`` syscall as a new :func:`os.getrandom` +function. This change is part of the :pep:`524`. + +.. + +.. bpo: 27691 +.. date: 9531 +.. nonce: TMYF5_ +.. section: Library + +Fix ssl module's parsing of GEN_RID subject alternative name fields in X.509 +certs. + +.. + +.. bpo: 18844 +.. date: 9530 +.. nonce: OZnLOi +.. section: Library + +Add random.choices(). + +.. + +.. bpo: 25761 +.. date: 9529 +.. nonce: qd--Ta +.. section: Library + +Improved error reporting about truncated pickle data in C implementation of +unpickler. UnpicklingError is now raised instead of AttributeError and +ValueError in some cases. + +.. + +.. bpo: 26798 +.. date: 9528 +.. nonce: he58yl +.. section: Library + +Add BLAKE2 (blake2b and blake2s) to hashlib. + +.. + +.. bpo: 26032 +.. date: 9527 +.. nonce: v5ByZW +.. section: Library + +Optimized globbing in pathlib by using os.scandir(); it is now about 1.5--4 +times faster. + +.. + +.. bpo: 25596 +.. date: 9526 +.. nonce: TFtyjC +.. section: Library + +Optimized glob() and iglob() functions in the glob module; they are now +about 3--6 times faster. + +.. + +.. bpo: 27928 +.. date: 9525 +.. nonce: vG2f6q +.. section: Library + +Add scrypt (password-based key derivation function) to hashlib module +(requires OpenSSL 1.1.0). + +.. + +.. bpo: 27850 +.. date: 9524 +.. nonce: kIVQ0m +.. section: Library + +Remove 3DES from ssl module's default cipher list to counter measure sweet32 +attack (CVE-2016-2183). + +.. + +.. bpo: 27766 +.. date: 9523 +.. nonce: WI70Tc +.. section: Library + +Add ChaCha20 Poly1305 to ssl module's default cipher list. (Required OpenSSL +1.1.0 or LibreSSL). + +.. + +.. bpo: 25387 +.. date: 9522 +.. nonce: -wsV59 +.. section: Library + +Check return value of winsound.MessageBeep. + +.. + +.. bpo: 27866 +.. date: 9521 +.. nonce: FM3-BZ +.. section: Library + +Add SSLContext.get_ciphers() method to get a list of all enabled ciphers. + +.. + +.. bpo: 27744 +.. date: 9520 +.. nonce: 2cVMpG +.. section: Library + +Add AF_ALG (Linux Kernel crypto) to socket module. + +.. + +.. bpo: 26470 +.. date: 9519 +.. nonce: QGu_wo +.. section: Library + +Port ssl and hashlib module to OpenSSL 1.1.0. + +.. + +.. bpo: 11620 +.. date: 9518 +.. nonce: JyL-Po +.. section: Library + +Fix support for SND_MEMORY in winsound.PlaySound. Based on a patch by Tim +Lesher. + +.. + +.. bpo: 11734 +.. date: 9517 +.. nonce: AQoy-q +.. section: Library + +Add support for IEEE 754 half-precision floats to the struct module. Based +on a patch by Eli Stevens. + +.. + +.. bpo: 27919 +.. date: 9516 +.. nonce: NRqNEW +.. section: Library + +Deprecated ``extra_path`` distribution option in distutils packaging. + +.. + +.. bpo: 23229 +.. date: 9515 +.. nonce: gXhSFh +.. section: Library + +Add new ``cmath`` constants: ``cmath.inf`` and ``cmath.nan`` to match +``math.inf`` and ``math.nan``, and also ``cmath.infj`` and ``cmath.nanj`` to +match the format used by complex repr. + +.. + +.. bpo: 27842 +.. date: 9514 +.. nonce: qlhp0- +.. section: Library + +The csv.DictReader now returns rows of type OrderedDict. (Contributed by +Steve Holden.) + +.. + +.. bpo: 0 +.. date: 9513 +.. nonce: 6TjEgz +.. section: Library + +Remove support for passing a file descriptor to os.access. It never worked +but previously didn't raise. + +.. + +.. bpo: 12885 +.. date: 9512 +.. nonce: r-IV1g +.. section: Library + +Fix error when distutils encounters symlink. + +.. + +.. bpo: 27881 +.. date: 9511 +.. nonce: fkETd9 +.. section: Library + +Fixed possible bugs when setting sqlite3.Connection.isolation_level. Based +on patch by Xiang Zhang. + +.. + +.. bpo: 27861 +.. date: 9510 +.. nonce: DBYuo9 +.. section: Library + +Fixed a crash in sqlite3.Connection.cursor() when a factory creates not a +cursor. Patch by Xiang Zhang. + +.. + +.. bpo: 19884 +.. date: 9509 +.. nonce: MO8AWH +.. section: Library + +Avoid spurious output on OS X with Gnu Readline. + +.. + +.. bpo: 27706 +.. date: 9508 +.. nonce: ZY67yu +.. section: Library + +Restore deterministic behavior of random.Random().seed() for string seeds +using seeding version 1. Allows sequences of calls to random() to exactly +match those obtained in Python 2. Patch by Nofar Schnider. + +.. + +.. bpo: 10513 +.. date: 9507 +.. nonce: tQIQD_ +.. section: Library + +Fix a regression in Connection.commit(). Statements should not be reset +after a commit. + +.. + +.. bpo: 12319 +.. date: 9506 +.. nonce: Wc4oUu +.. section: Library + +Chunked transfer encoding support added to http.client.HTTPConnection +requests. The urllib.request.AbstractHTTPHandler class does not enforce a +Content-Length header any more. If a HTTP request has a file or iterable +body, but no Content-Length header, the library now falls back to use +chunked transfer-encoding. + +.. + +.. bpo: 0 +.. date: 9505 +.. nonce: cYraeH +.. section: Library + +A new version of typing.py from https://github.com/python/typing: - +Collection (only for 3.6) (Issue #27598) - Add FrozenSet to __all__ +(upstream #261) - fix crash in _get_type_vars() (upstream #259) - Remove the +dict constraint in ForwardRef._eval_type (upstream #252) + +.. + +.. bpo: 27832 +.. date: 9504 +.. nonce: hxh6_h +.. section: Library + +Make ``_normalize`` parameter to ``Fraction`` constructor keyword-only, so +that ``Fraction(2, 3, 4)`` now raises ``TypeError``. + +.. + +.. bpo: 27539 +.. date: 9503 +.. nonce: S4L1cq +.. section: Library + +Fix unnormalised ``Fraction.__pow__`` result in the case of negative +exponent and negative base. + +.. + +.. bpo: 21718 +.. date: 9502 +.. nonce: FUJd-7 +.. section: Library + +cursor.description is now available for queries using CTEs. + +.. + +.. bpo: 27819 +.. date: 9501 +.. nonce: -A_u1x +.. section: Library + +In distutils sdists, simply produce the "gztar" (gzipped tar format) +distributions on all platforms unless "formats" is supplied. + +.. + +.. bpo: 2466 +.. date: 9500 +.. nonce: VRNlkg +.. section: Library + +posixpath.ismount now correctly recognizes mount points which the user does +not have permission to access. + +.. + +.. bpo: 9998 +.. date: 9499 +.. nonce: SNIoPr +.. section: Library + +On Linux, ctypes.util.find_library now looks in LD_LIBRARY_PATH for shared +libraries. + +.. + +.. bpo: 27573 +.. date: 9498 +.. nonce: yuXLnW +.. section: Library + +exit message for code.interact is now configurable. + +.. + +.. bpo: 27930 +.. date: 9497 +.. nonce: BkOfSi +.. section: Library + +Improved behaviour of logging.handlers.QueueListener. Thanks to Paulo +Andrade and Petr Viktorin for the analysis and patch. + +.. + +.. bpo: 6766 +.. date: 9496 +.. nonce: _zO4cV +.. section: Library + +Distributed reference counting added to multiprocessing to support nesting +of shared values / proxy objects. + +.. + +.. bpo: 21201 +.. date: 9495 +.. nonce: wLCKiA +.. section: Library + +Improves readability of multiprocessing error message. Thanks to Wojciech +Walczak for patch. + +.. + +.. bpo: 0 +.. date: 9494 +.. nonce: hgCs-W +.. section: Library + +asyncio: Add set_protocol / get_protocol to Transports. + +.. + +.. bpo: 27456 +.. date: 9493 +.. nonce: lI_IE7 +.. section: Library + +asyncio: Set TCP_NODELAY by default. + +.. + +.. bpo: 15308 +.. date: 9492 +.. nonce: zZxn8m +.. section: IDLE + +Add 'interrupt execution' (^C) to Shell menu. Patch by Roger Serwy, updated +by Bayard Randel. + +.. + +.. bpo: 27922 +.. date: 9491 +.. nonce: UEtEv9 +.. section: IDLE + +Stop IDLE tests from 'flashing' gui widgets on the screen. + +.. + +.. bpo: 27891 +.. date: 9490 +.. nonce: 7W5cAj +.. section: IDLE + +Consistently group and sort imports within idlelib modules. + +.. + +.. bpo: 17642 +.. date: 9489 +.. nonce: B0BNOB +.. section: IDLE + +add larger font sizes for classroom projection. + +.. + +.. bpo: 0 +.. date: 9488 +.. nonce: zWZs6o +.. section: IDLE + +Add version to title of IDLE help window. + +.. + +.. bpo: 25564 +.. date: 9487 +.. nonce: GN0p14 +.. section: IDLE + +In section on IDLE -- console differences, mention that using exec means +that __builtins__ is defined for each statement. + +.. + +.. bpo: 27821 +.. date: 9486 +.. nonce: Vzr42u +.. section: IDLE + +Fix 3.6.0a3 regression that prevented custom key sets from being selected +when no custom theme was defined. + +.. + +.. bpo: 26900 +.. date: 9485 +.. nonce: 0erSIc +.. section: C API + +Excluded underscored names and other private API from limited API. + +.. + +.. bpo: 26027 +.. date: 9484 +.. nonce: 5uVb7n +.. section: C API + +Add support for path-like objects in PyUnicode_FSConverter() & +PyUnicode_FSDecoder(). + +.. + +.. bpo: 27427 +.. date: 9483 +.. nonce: OGhkYQ +.. section: Tests + +Additional tests for the math module. Patch by Francisco Couzo. + +.. + +.. bpo: 27953 +.. date: 9482 +.. nonce: oP3nuf +.. section: Tests + +Skip math and cmath tests that fail on OS X 10.4 due to a poor libm +implementation of tan. + +.. + +.. bpo: 26040 +.. date: 9481 +.. nonce: RvSU5I +.. section: Tests + +Improve test_math and test_cmath coverage and rigour. Patch by Jeff Allen. + +.. + +.. bpo: 27787 +.. date: 9480 +.. nonce: kf0YAt +.. section: Tests + +Call gc.collect() before checking each test for "dangling threads", since +the dangling threads are weak references. + +.. + +.. bpo: 27566 +.. date: 9479 +.. nonce: xDWjEb +.. section: Build + +Fix clean target in freeze makefile (patch by Lisa Roach) + +.. + +.. bpo: 27705 +.. date: 9478 +.. nonce: 8C2Ms3 +.. section: Build + +Update message in validate_ucrtbase.py + +.. + +.. bpo: 27976 +.. date: 9477 +.. nonce: z0CT-3 +.. section: Build + +Deprecate building _ctypes with the bundled copy of libffi on non-OSX UNIX +platforms. + +.. + +.. bpo: 27983 +.. date: 9476 +.. nonce: jL_1n8 +.. section: Build + +Cause lack of llvm-profdata tool when using clang as required for PGO +linking to be a configure time error rather than make time when +``--with-optimizations`` is enabled. Also improve our ability to find the +llvm-profdata tool on MacOS and some Linuxes. + +.. + +.. bpo: 21590 +.. date: 9475 +.. nonce: haPolL +.. section: Build + +Support for DTrace and SystemTap probes. + +.. + +.. bpo: 26307 +.. date: 9474 +.. nonce: Puk2rd +.. section: Build + +The profile-opt build now applies PGO to the built-in modules. + +.. + +.. bpo: 26359 +.. date: 9473 +.. nonce: uxKCqR +.. section: Build + +Add the --with-optimizations flag to turn on LTO and PGO build support when +available. + +.. + +.. bpo: 27917 +.. date: 9472 +.. nonce: 8V2esX +.. section: Build + +Set platform triplets for Android builds. + +.. + +.. bpo: 25825 +.. date: 9471 +.. nonce: PwGiUI +.. section: Build + +Update references to the $(LIBPL) installation path on AIX. This path was +changed in 3.2a4. + +.. + +.. bpo: 0 +.. date: 9470 +.. nonce: G27B6T +.. section: Build + +Update OS X installer to use SQLite 3.14.1 and XZ 5.2.2. + +.. + +.. bpo: 21122 +.. date: 9469 +.. nonce: 98ovv8 +.. section: Build + +Fix LTO builds on OS X. + +.. + +.. bpo: 17128 +.. date: 9468 +.. nonce: jd3Cll +.. section: Build + +Build OS X installer with a private copy of OpenSSL. Also provide a sample +Install Certificates command script to install a set of root certificates +from the third-party certifi module. + +.. + +.. bpo: 27952 +.. date: 9467 +.. nonce: WX9Ufc +.. section: Tools/Demos + +Get Tools/scripts/fixcid.py working with Python 3 and the current "re" +module, avoid invalid Python backslash escapes, and fix a bug parsing +escaped C quote signs. + +.. + +.. bpo: 28065 +.. date: 9466 +.. nonce: TUW63o +.. section: Windows + +Update xz dependency to 5.2.2 and build it from source. + +.. + +.. bpo: 25144 +.. date: 9465 +.. nonce: iUha52 +.. section: Windows + +Ensures TargetDir is set before continuing with custom install. + +.. + +.. bpo: 1602 +.. date: 9464 +.. nonce: 5Kowx0 +.. section: Windows + +Windows console doesn't input or print Unicode (PEP 528) + +.. + +.. bpo: 27781 +.. date: 9463 +.. nonce: 21eQH2 +.. section: Windows + +Change file system encoding on Windows to UTF-8 (PEP 529) + +.. + +.. bpo: 27731 +.. date: 9462 +.. nonce: U2HSrC +.. section: Windows + +Opt-out of MAX_PATH on Windows 10 + +.. + +.. bpo: 6135 +.. date: 9461 +.. nonce: pACuPJ +.. section: Windows + +Adds encoding and errors parameters to subprocess. + +.. + +.. bpo: 27959 +.. date: 9460 +.. nonce: JamSoC +.. section: Windows + +Adds oem encoding, alias ansi to mbcs, move aliasmbcs to codec lookup. + +.. + +.. bpo: 27982 +.. date: 9459 +.. nonce: xrUa9R +.. section: Windows + +The functions of the winsound module now accept keyword arguments. + +.. + +.. bpo: 20366 +.. date: 9458 +.. nonce: s6b-ut +.. section: Windows + +Build full text search support into SQLite on Windows. + +.. + +.. bpo: 27756 +.. date: 9457 +.. nonce: PDAoGy +.. section: Windows + +Adds new icons for Python files and processes on Windows. Designs by Cherry +Wang. + +.. + +.. bpo: 27883 +.. date: 9456 +.. nonce: vyOnxj +.. section: Windows + +Update sqlite to 3.14.1.0 on Windows. diff --git a/Misc/NEWS.d/3.6.0b2.rst b/Misc/NEWS.d/3.6.0b2.rst new file mode 100644 index 00000000..9413c6e0 --- /dev/null +++ b/Misc/NEWS.d/3.6.0b2.rst @@ -0,0 +1,838 @@ +.. bpo: 28183 +.. date: 9707 +.. nonce: MJZeNd +.. release date: 2016-10-10 +.. section: Core and Builtins + +Optimize and cleanup dict iteration. + +.. + +.. bpo: 26081 +.. date: 9706 +.. nonce: _x5vjl +.. section: Core and Builtins + +Added C implementation of asyncio.Future. Original patch by Yury Selivanov. + +.. + +.. bpo: 28379 +.. date: 9705 +.. nonce: DuXlco +.. section: Core and Builtins + +Added sanity checks and tests for PyUnicode_CopyCharacters(). Patch by Xiang +Zhang. + +.. + +.. bpo: 28376 +.. date: 9704 +.. nonce: oPD-5D +.. section: Core and Builtins + +The type of long range iterator is now registered as Iterator. Patch by Oren +Milman. + +.. + +.. bpo: 28376 +.. date: 9703 +.. nonce: YEy-uG +.. section: Core and Builtins + +Creating instances of range_iterator by calling range_iterator type now is +deprecated. Patch by Oren Milman. + +.. + +.. bpo: 28376 +.. date: 9702 +.. nonce: fLeHM2 +.. section: Core and Builtins + +The constructor of range_iterator now checks that step is not 0. Patch by +Oren Milman. + +.. + +.. bpo: 26906 +.. date: 9701 +.. nonce: YBjcwI +.. section: Core and Builtins + +Resolving special methods of uninitialized type now causes implicit +initialization of the type instead of a fail. + +.. + +.. bpo: 18287 +.. date: 9700 +.. nonce: k6jffS +.. section: Core and Builtins + +PyType_Ready() now checks that tp_name is not NULL. Original patch by Niklas +Koep. + +.. + +.. bpo: 24098 +.. date: 9699 +.. nonce: XqlP_1 +.. section: Core and Builtins + +Fixed possible crash when AST is changed in process of compiling it. + +.. + +.. bpo: 28201 +.. date: 9698 +.. nonce: GWUxAy +.. section: Core and Builtins + +Dict reduces possibility of 2nd conflict in hash table when hashes have same +lower bits. + +.. + +.. bpo: 28350 +.. date: 9697 +.. nonce: 8M5Eg9 +.. section: Core and Builtins + +String constants with null character no longer interned. + +.. + +.. bpo: 26617 +.. date: 9696 +.. nonce: Gh5LvN +.. section: Core and Builtins + +Fix crash when GC runs during weakref callbacks. + +.. + +.. bpo: 27942 +.. date: 9695 +.. nonce: ZGuhns +.. section: Core and Builtins + +String constants now interned recursively in tuples and frozensets. + +.. + +.. bpo: 21578 +.. date: 9694 +.. nonce: GI1bhj +.. section: Core and Builtins + +Fixed misleading error message when ImportError called with invalid keyword +args. + +.. + +.. bpo: 28203 +.. date: 9693 +.. nonce: LRn5vp +.. section: Core and Builtins + +Fix incorrect type in complex(1.0, {2:3}) error message. Patch by Soumya +Sharma. + +.. + +.. bpo: 28086 +.. date: 9692 +.. nonce: JsQPMQ +.. section: Core and Builtins + +Single var-positional argument of tuple subtype was passed unscathed to the +C-defined function. Now it is converted to exact tuple. + +.. + +.. bpo: 28214 +.. date: 9691 +.. nonce: zQF8Em +.. section: Core and Builtins + +Now __set_name__ is looked up on the class instead of the instance. + +.. + +.. bpo: 27955 +.. date: 9690 +.. nonce: HC4pZ4 +.. section: Core and Builtins + +Fallback on reading /dev/urandom device when the getrandom() syscall fails +with EPERM, for example when blocked by SECCOMP. + +.. + +.. bpo: 28192 +.. date: 9689 +.. nonce: eR6stU +.. section: Core and Builtins + +Don't import readline in isolated mode. + +.. + +.. bpo: 0 +.. date: 9688 +.. nonce: 9EbOiD +.. section: Core and Builtins + +Upgrade internal unicode databases to Unicode version 9.0.0. + +.. + +.. bpo: 28131 +.. date: 9687 +.. nonce: owq0wW +.. section: Core and Builtins + +Fix a regression in zipimport's compile_source(). zipimport should use the +same optimization level as the interpreter. + +.. + +.. bpo: 28126 +.. date: 9686 +.. nonce: Qf6-uQ +.. section: Core and Builtins + +Replace Py_MEMCPY with memcpy(). Visual Studio can properly optimize +memcpy(). + +.. + +.. bpo: 28120 +.. date: 9685 +.. nonce: e5xc1i +.. section: Core and Builtins + +Fix dict.pop() for splitted dictionary when trying to remove a "pending key" +(Not yet inserted in split-table). Patch by Xiang Zhang. + +.. + +.. bpo: 26182 +.. date: 9684 +.. nonce: jYlqTO +.. section: Core and Builtins + +Raise DeprecationWarning when async and await keywords are used as +variable/attribute/class/function name. + +.. + +.. bpo: 27998 +.. date: 9683 +.. nonce: CPhy4H +.. section: Library + +Fixed bytes path support in os.scandir() on Windows. Patch by Eryk Sun. + +.. + +.. bpo: 28317 +.. date: 9682 +.. nonce: LgHleA +.. section: Library + +The disassembler now decodes FORMAT_VALUE argument. + +.. + +.. bpo: 26293 +.. date: 9681 +.. nonce: 2mjvwX +.. section: Library + +Fixed writing ZIP files that starts not from the start of the file. Offsets +in ZIP file now are relative to the start of the archive in conforming to +the specification. + +.. + +.. bpo: 28380 +.. date: 9680 +.. nonce: jKPMzH +.. section: Library + +unittest.mock Mock autospec functions now properly support assert_called, +assert_not_called, and assert_called_once. + +.. + +.. bpo: 27181 +.. date: 9679 +.. nonce: SQyDpC +.. section: Library + +remove statistics.geometric_mean and defer until 3.7. + +.. + +.. bpo: 28229 +.. date: 9678 +.. nonce: BKAxcS +.. section: Library + +lzma module now supports pathlib. + +.. + +.. bpo: 28321 +.. date: 9677 +.. nonce: bQ-IIX +.. section: Library + +Fixed writing non-BMP characters with binary format in plistlib. + +.. + +.. bpo: 28225 +.. date: 9676 +.. nonce: 6N28nu +.. section: Library + +bz2 module now supports pathlib. Initial patch by Ethan Furman. + +.. + +.. bpo: 28227 +.. date: 9675 +.. nonce: 7lUz8i +.. section: Library + +gzip now supports pathlib. Patch by Ethan Furman. + +.. + +.. bpo: 27358 +.. date: 9674 +.. nonce: t288Iv +.. section: Library + +Optimized merging var-keyword arguments and improved error message when +passing a non-mapping as a var-keyword argument. + +.. + +.. bpo: 28257 +.. date: 9673 +.. nonce: SVD_IH +.. section: Library + +Improved error message when passing a non-iterable as a var-positional +argument. Added opcode BUILD_TUPLE_UNPACK_WITH_CALL. + +.. + +.. bpo: 28322 +.. date: 9672 +.. nonce: l9hzap +.. section: Library + +Fixed possible crashes when unpickle itertools objects from incorrect pickle +data. Based on patch by John Leitch. + +.. + +.. bpo: 28228 +.. date: 9671 +.. nonce: 1qBwdM +.. section: Library + +imghdr now supports pathlib. + +.. + +.. bpo: 28226 +.. date: 9670 +.. nonce: nMXiwU +.. section: Library + +compileall now supports pathlib. + +.. + +.. bpo: 28314 +.. date: 9669 +.. nonce: N7YrkN +.. section: Library + +Fix function declaration (C flags) for the getiterator() method of +xml.etree.ElementTree.Element. + +.. + +.. bpo: 28148 +.. date: 9668 +.. nonce: Flzndx +.. section: Library + +Stop using localtime() and gmtime() in the time module. +Introduced platform independent _PyTime_localtime API that is similar to +POSIX localtime_r, but available on all platforms. Patch by Ed Schouten. + +.. + +.. bpo: 28253 +.. date: 9667 +.. nonce: aLfmhe +.. section: Library + +Fixed calendar functions for extreme months: 0001-01 and 9999-12. +Methods itermonthdays() and itermonthdays2() are reimplemented so that they +don't call itermonthdates() which can cause datetime.date under/overflow. + +.. + +.. bpo: 28275 +.. date: 9666 +.. nonce: EhWIsz +.. section: Library + +Fixed possible use after free in the decompress() methods of the +LZMADecompressor and BZ2Decompressor classes. Original patch by John Leitch. + +.. + +.. bpo: 27897 +.. date: 9665 +.. nonce: I0Ppmx +.. section: Library + +Fixed possible crash in sqlite3.Connection.create_collation() if pass +invalid string-like object as a name. Patch by Xiang Zhang. + +.. + +.. bpo: 18844 +.. date: 9664 +.. nonce: fQsEdn +.. section: Library + +random.choices() now has k as a keyword-only argument to improve the +readability of common cases and come into line with the signature used in +other languages. + +.. + +.. bpo: 18893 +.. date: 9663 +.. nonce: osiX5c +.. section: Library + +Fix invalid exception handling in Lib/ctypes/macholib/dyld.py. Patch by +Madison May. + +.. + +.. bpo: 27611 +.. date: 9662 +.. nonce: A_ArH_ +.. section: Library + +Fixed support of default root window in the tkinter.tix module. Added the +master parameter in the DisplayStyle constructor. + +.. + +.. bpo: 27348 +.. date: 9661 +.. nonce: tDx7Vw +.. section: Library + +In the traceback module, restore the formatting of exception messages like +"Exception: None". This fixes a regression introduced in 3.5a2. + +.. + +.. bpo: 25651 +.. date: 9660 +.. nonce: 3UhyPo +.. section: Library + +Allow false values to be used for msg parameter of subTest(). + +.. + +.. bpo: 27778 +.. date: 9659 +.. nonce: Yyo1aP +.. section: Library + +Fix a memory leak in os.getrandom() when the getrandom() is interrupted by a +signal and a signal handler raises a Python exception. + +.. + +.. bpo: 28200 +.. date: 9658 +.. nonce: 4IEbr7 +.. section: Library + +Fix memory leak on Windows in the os module (fix path_converter() function). + +.. + +.. bpo: 25400 +.. date: 9657 +.. nonce: d9Qn0E +.. section: Library + +RobotFileParser now correctly returns default values for crawl_delay and +request_rate. Initial patch by Peter Wirtz. + +.. + +.. bpo: 27932 +.. date: 9656 +.. nonce: mtgl-6 +.. section: Library + +Prevent memory leak in win32_ver(). + +.. + +.. bpo: 0 +.. date: 9655 +.. nonce: iPpjqX +.. section: Library + +Fix UnboundLocalError in socket._sendfile_use_sendfile. + +.. + +.. bpo: 28075 +.. date: 9654 +.. nonce: aLiUs9 +.. section: Library + +Check for ERROR_ACCESS_DENIED in Windows implementation of os.stat(). Patch +by Eryk Sun. + +.. + +.. bpo: 22493 +.. date: 9653 +.. nonce: Mv_hZf +.. section: Library + +Warning message emitted by using inline flags in the middle of regular +expression now contains a (truncated) regex pattern. Patch by Tim Graham. + +.. + +.. bpo: 25270 +.. date: 9652 +.. nonce: jrZruM +.. section: Library + +Prevent codecs.escape_encode() from raising SystemError when an empty +bytestring is passed. + +.. + +.. bpo: 28181 +.. date: 9651 +.. nonce: NGc4Yv +.. section: Library + +Get antigravity over HTTPS. Patch by Kaartic Sivaraam. + +.. + +.. bpo: 25895 +.. date: 9650 +.. nonce: j92qoQ +.. section: Library + +Enable WebSocket URL schemes in urllib.parse.urljoin. Patch by Gergely Imreh +and Markus Holtermann. + +.. + +.. bpo: 28114 +.. date: 9649 +.. nonce: gmFXsA +.. section: Library + +Fix a crash in parse_envlist() when env contains byte strings. Patch by Eryk +Sun. + +.. + +.. bpo: 27599 +.. date: 9648 +.. nonce: itvm8T +.. section: Library + +Fixed buffer overrun in binascii.b2a_qp() and binascii.a2b_qp(). + +.. + +.. bpo: 27906 +.. date: 9647 +.. nonce: TBBXrv +.. section: Library + +Fix socket accept exhaustion during high TCP traffic. Patch by Kevin Conway. + +.. + +.. bpo: 28174 +.. date: 9646 +.. nonce: CV1UdI +.. section: Library + +Handle when SO_REUSEPORT isn't properly supported. Patch by Seth Michael +Larson. + +.. + +.. bpo: 26654 +.. date: 9645 +.. nonce: XtzTE9 +.. section: Library + +Inspect functools.partial in asyncio.Handle.__repr__. Patch by iceboy. + +.. + +.. bpo: 26909 +.. date: 9644 +.. nonce: ASiakT +.. section: Library + +Fix slow pipes IO in asyncio. Patch by INADA Naoki. + +.. + +.. bpo: 28176 +.. date: 9643 +.. nonce: sU8R6L +.. section: Library + +Fix callbacks race in asyncio.SelectorLoop.sock_connect. + +.. + +.. bpo: 27759 +.. date: 9642 +.. nonce: qpMDGq +.. section: Library + +Fix selectors incorrectly retain invalid file descriptors. Patch by Mark +Williams. + +.. + +.. bpo: 28368 +.. date: 9641 +.. nonce: fGl9y4 +.. section: Library + +Refuse monitoring processes if the child watcher has no loop attached. Patch +by Vincent Michel. + +.. + +.. bpo: 28369 +.. date: 9640 +.. nonce: 8DTANe +.. section: Library + +Raise RuntimeError when transport's FD is used with add_reader, add_writer, +etc. + +.. + +.. bpo: 28370 +.. date: 9639 +.. nonce: 18jBuZ +.. section: Library + +Speedup asyncio.StreamReader.readexactly. Patch by Коренберг Марк. + +.. + +.. bpo: 28371 +.. date: 9638 +.. nonce: U9Zqdk +.. section: Library + +Deprecate passing asyncio.Handles to run_in_executor. + +.. + +.. bpo: 28372 +.. date: 9637 +.. nonce: njcIPk +.. section: Library + +Fix asyncio to support formatting of non-python coroutines. + +.. + +.. bpo: 28399 +.. date: 9636 +.. nonce: QKIqRX +.. section: Library + +Remove UNIX socket from FS before binding. Patch by Коренберг Марк. + +.. + +.. bpo: 27972 +.. date: 9635 +.. nonce: ZK-GFm +.. section: Library + +Prohibit Tasks to await on themselves. + +.. + +.. bpo: 28402 +.. date: 9634 +.. nonce: v9zETJ +.. section: Windows + +Adds signed catalog files for stdlib on Windows. + +.. + +.. bpo: 28333 +.. date: 9633 +.. nonce: KnpeO4 +.. section: Windows + +Enables Unicode for ps1/ps2 and input() prompts. (Patch by Eryk Sun) + +.. + +.. bpo: 28251 +.. date: 9632 +.. nonce: tR_AFs +.. section: Windows + +Improvements to help manuals on Windows. + +.. + +.. bpo: 28110 +.. date: 9631 +.. nonce: cnkP5F +.. section: Windows + +launcher.msi has different product codes between 32-bit and 64-bit + +.. + +.. bpo: 28161 +.. date: 9630 +.. nonce: hF91LI +.. section: Windows + +Opening CON for write access fails + +.. + +.. bpo: 28162 +.. date: 9629 +.. nonce: 3FHPVD +.. section: Windows + +WindowsConsoleIO readall() fails if first line starts with Ctrl+Z + +.. + +.. bpo: 28163 +.. date: 9628 +.. nonce: -DUgJw +.. section: Windows + +WindowsConsoleIO fileno() passes wrong flags to _open_osfhandle + +.. + +.. bpo: 28164 +.. date: 9627 +.. nonce: 5MfN0J +.. section: Windows + +_PyIO_get_console_type fails for various paths + +.. + +.. bpo: 28137 +.. date: 9626 +.. nonce: C1uvzY +.. section: Windows + +Renames Windows path file to ._pth + +.. + +.. bpo: 28138 +.. date: 9625 +.. nonce: pNdv64 +.. section: Windows + +Windows ._pth file should allow import site + +.. + +.. bpo: 28426 +.. date: 9624 +.. nonce: zPwvbI +.. section: C API + +Deprecated undocumented functions PyUnicode_AsEncodedObject(), +PyUnicode_AsDecodedObject(), PyUnicode_AsDecodedUnicode() and +PyUnicode_AsEncodedUnicode(). + +.. + +.. bpo: 28258 +.. date: 9623 +.. nonce: iKtAHd +.. section: Build + +Fixed build with Estonian locale (python-config and distclean targets in +Makefile). Patch by Arfrever Frehtes Taifersar Arahesis. + +.. + +.. bpo: 26661 +.. date: 9622 +.. nonce: Z_HNbs +.. section: Build + +setup.py now detects system libffi with multiarch wrapper. + +.. + +.. bpo: 15819 +.. date: 9621 +.. nonce: QVDr3E +.. section: Build + +Remove redundant include search directory option for building outside the +source tree. + +.. + +.. bpo: 28217 +.. date: 9620 +.. nonce: Y37OKV +.. section: Tests + +Adds _testconsole module to test console input. diff --git a/Misc/NEWS.d/3.6.0b3.rst b/Misc/NEWS.d/3.6.0b3.rst new file mode 100644 index 00000000..4233708a --- /dev/null +++ b/Misc/NEWS.d/3.6.0b3.rst @@ -0,0 +1,355 @@ +.. bpo: 28128 +.. date: 9744 +.. nonce: Lc2sFu +.. release date: 2016-10-31 +.. section: Core and Builtins + +Deprecation warning for invalid str and byte escape sequences now prints +better information about where the error occurs. Patch by Serhiy Storchaka +and Eric Smith. + +.. + +.. bpo: 28509 +.. date: 9743 +.. nonce: _Fa4Uq +.. section: Core and Builtins + +dict.update() no longer allocate unnecessary large memory. + +.. + +.. bpo: 28426 +.. date: 9742 +.. nonce: E_quyK +.. section: Core and Builtins + +Fixed potential crash in PyUnicode_AsDecodedObject() in debug build. + +.. + +.. bpo: 28517 +.. date: 9741 +.. nonce: ExPkm9 +.. section: Core and Builtins + +Fixed of-by-one error in the peephole optimizer that caused keeping +unreachable code. + +.. + +.. bpo: 28214 +.. date: 9740 +.. nonce: 6ECJox +.. section: Core and Builtins + +Improved exception reporting for problematic __set_name__ attributes. + +.. + +.. bpo: 23782 +.. date: 9739 +.. nonce: lonDzj +.. section: Core and Builtins + +Fixed possible memory leak in _PyTraceback_Add() and exception loss in +PyTraceBack_Here(). + +.. + +.. bpo: 28471 +.. date: 9738 +.. nonce: Vd5pv7 +.. section: Core and Builtins + +Fix "Python memory allocator called without holding the GIL" crash in +socket.setblocking. + +.. + +.. bpo: 27517 +.. date: 9737 +.. nonce: 1CYM8A +.. section: Library + +LZMA compressor and decompressor no longer raise exceptions if given empty +data twice. Patch by Benjamin Fogle. + +.. + +.. bpo: 28549 +.. date: 9736 +.. nonce: ShnM2y +.. section: Library + +Fixed segfault in curses's addch() with ncurses6. + +.. + +.. bpo: 28449 +.. date: 9735 +.. nonce: 5JK6ES +.. section: Library + +tarfile.open() with mode "r" or "r:" now tries to open a tar file with +compression before trying to open it without compression. Otherwise it had +50% chance failed with ignore_zeros=True. + +.. + +.. bpo: 23262 +.. date: 9734 +.. nonce: 6EVB7N +.. section: Library + +The webbrowser module now supports Firefox 36+ and derived browsers. Based +on patch by Oleg Broytman. + +.. + +.. bpo: 27939 +.. date: 9733 +.. nonce: mTfADV +.. section: Library + +Fixed bugs in tkinter.ttk.LabeledScale and tkinter.Scale caused by +representing the scale as float value internally in Tk. tkinter.IntVar now +works if float value is set to underlying Tk variable. + +.. + +.. bpo: 18844 +.. date: 9732 +.. nonce: oif1-H +.. section: Library + +The various ways of specifying weights for random.choices() now produce the +same result sequences. + +.. + +.. bpo: 28255 +.. date: 9731 +.. nonce: _ZH4wm +.. section: Library + +calendar.TextCalendar().prmonth() no longer prints a space at the start of +new line after printing a month's calendar. Patch by Xiang Zhang. + +.. + +.. bpo: 20491 +.. date: 9730 +.. nonce: ObgnQ2 +.. section: Library + +The textwrap.TextWrapper class now honors non-breaking spaces. Based on +patch by Kaarle Ritvanen. + +.. + +.. bpo: 28353 +.. date: 9729 +.. nonce: sKGbLL +.. section: Library + +os.fwalk() no longer fails on broken links. + +.. + +.. bpo: 28430 +.. date: 9728 +.. nonce: 4MiEYT +.. section: Library + +Fix iterator of C implemented asyncio.Future doesn't accept non-None value +is passed to it.send(val). + +.. + +.. bpo: 27025 +.. date: 9727 +.. nonce: foAViS +.. section: Library + +Generated names for Tkinter widgets now start by the "!" prefix for +readability. + +.. + +.. bpo: 25464 +.. date: 9726 +.. nonce: HDUTCu +.. section: Library + +Fixed HList.header_exists() in tkinter.tix module by addin a workaround to +Tix library bug. + +.. + +.. bpo: 28488 +.. date: 9725 +.. nonce: TgO112 +.. section: Library + +shutil.make_archive() no longer adds entry "./" to ZIP archive. + +.. + +.. bpo: 25953 +.. date: 9724 +.. nonce: EKKJAQ +.. section: Library + +re.sub() now raises an error for invalid numerical group reference in +replacement template even if the pattern is not found in the string. Error +message for invalid group reference now includes the group index and the +position of the reference. Based on patch by SilentGhost. + +.. + +.. bpo: 18219 +.. date: 9723 +.. nonce: 1ANQN1 +.. section: Library + +Optimize csv.DictWriter for large number of columns. Patch by Mariatta +Wijaya. + +.. + +.. bpo: 28448 +.. date: 9722 +.. nonce: 5bduWe +.. section: Library + +Fix C implemented asyncio.Future didn't work on Windows. + +.. + +.. bpo: 28480 +.. date: 9721 +.. nonce: 9lHw6m +.. section: Library + +Fix error building socket module when multithreading is disabled. + +.. + +.. bpo: 24452 +.. date: 9720 +.. nonce: m9Kyg3 +.. section: Library + +Make webbrowser support Chrome on Mac OS X. + +.. + +.. bpo: 20766 +.. date: 9719 +.. nonce: 4kvCzx +.. section: Library + +Fix references leaked by pdb in the handling of SIGINT handlers. + +.. + +.. bpo: 28492 +.. date: 9718 +.. nonce: pFRLQE +.. section: Library + +Fix how StopIteration exception is raised in _asyncio.Future. + +.. + +.. bpo: 28500 +.. date: 9717 +.. nonce: NINKzZ +.. section: Library + +Fix asyncio to handle async gens GC from another thread. + +.. + +.. bpo: 26923 +.. date: 9716 +.. nonce: 8dh3AV +.. section: Library + +Fix asyncio.Gather to refuse being cancelled once all children are done. +Patch by Johannes Ebke. + +.. + +.. bpo: 26796 +.. date: 9715 +.. nonce: TZyAfJ +.. section: Library + +Don't configure the number of workers for default threadpool executor. +Initial patch by Hans Lawrenz. + +.. + +.. bpo: 28544 +.. date: 9714 +.. nonce: KD1oFP +.. section: Library + +Implement asyncio.Task in C. + +.. + +.. bpo: 28522 +.. date: 9713 +.. nonce: XHMQa7 +.. section: Windows + +Fixes mishandled buffer reallocation in getpathp.c + +.. + +.. bpo: 28444 +.. date: 9712 +.. nonce: zkc9nT +.. section: Build + +Fix missing extensions modules when cross compiling. + +.. + +.. bpo: 28208 +.. date: 9711 +.. nonce: DtoP1i +.. section: Build + +Update Windows build and OS X installers to use SQLite 3.14.2. + +.. + +.. bpo: 28248 +.. date: 9710 +.. nonce: KY_-en +.. section: Build + +Update Windows build and OS X installers to use OpenSSL 1.0.2j. + +.. + +.. bpo: 26944 +.. date: 9709 +.. nonce: ChZ_BO +.. section: Tests + +Fix test_posix for Android where 'id -G' is entirely wrong or missing the +effective gid. + +.. + +.. bpo: 28409 +.. date: 9708 +.. nonce: Q2IlxJ +.. section: Tests + +regrtest: fix the parser of command line arguments. diff --git a/Misc/NEWS.d/3.6.0b4.rst b/Misc/NEWS.d/3.6.0b4.rst new file mode 100644 index 00000000..a8e40861 --- /dev/null +++ b/Misc/NEWS.d/3.6.0b4.rst @@ -0,0 +1,327 @@ +.. bpo: 28532 +.. date: 9778 +.. nonce: KEYJny +.. release date: 2016-11-21 +.. section: Core and Builtins + +Show sys.version when -V option is supplied twice. + +.. + +.. bpo: 27100 +.. date: 9777 +.. nonce: poVjXq +.. section: Core and Builtins + +The with-statement now checks for __enter__ before it checks for __exit__. +This gives less confusing error messages when both methods are missing. +Patch by Jonathan Ellington. + +.. + +.. bpo: 28746 +.. date: 9776 +.. nonce: r5MXdB +.. section: Core and Builtins + +Fix the set_inheritable() file descriptor method on platforms that do not +have the ioctl FIOCLEX and FIONCLEX commands. + +.. + +.. bpo: 26920 +.. date: 9775 +.. nonce: 1URwGb +.. section: Core and Builtins + +Fix not getting the locale's charset upon initializing the interpreter, on +platforms that do not have langinfo. + +.. + +.. bpo: 28648 +.. date: 9774 +.. nonce: z7B52W +.. section: Core and Builtins + +Fixed crash in Py_DecodeLocale() in debug build on Mac OS X when decode +astral characters. Patch by Xiang Zhang. + +.. + +.. bpo: 19398 +.. date: 9773 +.. nonce: RYbEGH +.. section: Core and Builtins + +Extra slash no longer added to sys.path components in case of empty +compile-time PYTHONPATH components. + +.. + +.. bpo: 28665 +.. date: 9772 +.. nonce: v4nx86 +.. section: Core and Builtins + +Improve speed of the STORE_DEREF opcode by 40%. + +.. + +.. bpo: 28583 +.. date: 9771 +.. nonce: F-QAx1 +.. section: Core and Builtins + +PyDict_SetDefault didn't combine split table when needed. Patch by Xiang +Zhang. + +.. + +.. bpo: 27243 +.. date: 9770 +.. nonce: 61E6K5 +.. section: Core and Builtins + +Change PendingDeprecationWarning -> DeprecationWarning. As it was agreed in +the issue, __aiter__ returning an awaitable should result in +PendingDeprecationWarning in 3.5 and in DeprecationWarning in 3.6. + +.. + +.. bpo: 26182 +.. date: 9769 +.. nonce: a8JXK2 +.. section: Core and Builtins + +Fix a refleak in code that raises DeprecationWarning. + +.. + +.. bpo: 28721 +.. date: 9768 +.. nonce: BO9BUF +.. section: Core and Builtins + +Fix asynchronous generators aclose() and athrow() to handle +StopAsyncIteration propagation properly. + +.. + +.. bpo: 28752 +.. date: 9767 +.. nonce: Q-4oRE +.. section: Library + +Restored the __reduce__() methods of datetime objects. + +.. + +.. bpo: 28727 +.. date: 9766 +.. nonce: ubZP_b +.. section: Library + +Regular expression patterns, _sre.SRE_Pattern objects created by +re.compile(), become comparable (only x==y and x!=y operators). This change +should fix the issue #18383: don't duplicate warning filters when the +warnings module is reloaded (thing usually only done in unit tests). + +.. + +.. bpo: 20572 +.. date: 9765 +.. nonce: lGXaH9 +.. section: Library + +The subprocess.Popen.wait method's undocumented endtime parameter now raises +a DeprecationWarning. + +.. + +.. bpo: 25659 +.. date: 9764 +.. nonce: lE2IlT +.. section: Library + +In ctypes, prevent a crash calling the from_buffer() and from_buffer_copy() +methods on abstract classes like Array. + +.. + +.. bpo: 19717 +.. date: 9763 +.. nonce: HXCAIz +.. section: Library + +Makes Path.resolve() succeed on paths that do not exist. Patch by Vajrasky +Kok + +.. + +.. bpo: 28563 +.. date: 9762 +.. nonce: iweEiw +.. section: Library + +Fixed possible DoS and arbitrary code execution when handle plural form +selections in the gettext module. The expression parser now supports exact +syntax supported by GNU gettext. + +.. + +.. bpo: 28387 +.. date: 9761 +.. nonce: 1clJu7 +.. section: Library + +Fixed possible crash in _io.TextIOWrapper deallocator when the garbage +collector is invoked in other thread. Based on patch by Sebastian Cufre. + +.. + +.. bpo: 28600 +.. date: 9760 +.. nonce: wMVrjN +.. section: Library + +Optimize loop.call_soon. + +.. + +.. bpo: 28613 +.. date: 9759 +.. nonce: sqUPrv +.. section: Library + +Fix get_event_loop() return the current loop if called from +coroutines/callbacks. + +.. + +.. bpo: 28634 +.. date: 9758 +.. nonce: YlRydz +.. section: Library + +Fix asyncio.isfuture() to support unittest.Mock. + +.. + +.. bpo: 26081 +.. date: 9757 +.. nonce: 2Y8-a9 +.. section: Library + +Fix refleak in _asyncio.Future.__iter__().throw. + +.. + +.. bpo: 28639 +.. date: 9756 +.. nonce: WUPo1o +.. section: Library + +Fix inspect.isawaitable to always return bool Patch by Justin Mayfield. + +.. + +.. bpo: 28652 +.. date: 9755 +.. nonce: f5M8FG +.. section: Library + +Make loop methods reject socket kinds they do not support. + +.. + +.. bpo: 28653 +.. date: 9754 +.. nonce: S5bA9i +.. section: Library + +Fix a refleak in functools.lru_cache. + +.. + +.. bpo: 28703 +.. date: 9753 +.. nonce: CRLTJc +.. section: Library + +Fix asyncio.iscoroutinefunction to handle Mock objects. + +.. + +.. bpo: 28704 +.. date: 9752 +.. nonce: EFWBII +.. section: Library + +Fix create_unix_server to support Path-like objects (PEP 519). + +.. + +.. bpo: 28720 +.. date: 9751 +.. nonce: Fsz-Lf +.. section: Library + +Add collections.abc.AsyncGenerator. + +.. + +.. bpo: 28513 +.. date: 9750 +.. nonce: L3joAz +.. section: Documentation + +Documented command-line interface of zipfile. + +.. + +.. bpo: 28666 +.. date: 9749 +.. nonce: RtTk-4 +.. section: Tests + +Now test.support.rmtree is able to remove unwritable or unreadable +directories. + +.. + +.. bpo: 23839 +.. date: 9748 +.. nonce: zsT_L9 +.. section: Tests + +Various caches now are cleared before running every test file. + +.. + +.. bpo: 10656 +.. date: 9747 +.. nonce: pR8FFU +.. section: Build + +Fix out-of-tree building on AIX. Patch by Tristan Carel and Michael +Haubenwallner. + +.. + +.. bpo: 26359 +.. date: 9746 +.. nonce: CLz6qy +.. section: Build + +Rename --with-optimiations to --enable-optimizations. + +.. + +.. bpo: 28676 +.. date: 9745 +.. nonce: Wxf6Ds +.. section: Build + +Prevent missing 'getentropy' declaration warning on macOS. Patch by Gareth +Rees. diff --git a/Misc/NEWS.d/3.6.0rc1.rst b/Misc/NEWS.d/3.6.0rc1.rst new file mode 100644 index 00000000..658f8c90 --- /dev/null +++ b/Misc/NEWS.d/3.6.0rc1.rst @@ -0,0 +1,122 @@ +.. bpo: 23722 +.. date: 9790 +.. nonce: e8BH5h +.. release date: 2016-12-06 +.. section: Core and Builtins + +Rather than silently producing a class that doesn't support zero-argument +``super()`` in methods, failing to pass the new ``__classcell__`` namespace +entry up to ``type.__new__`` now results in a ``DeprecationWarning`` and a +class that supports zero-argument ``super()``. + +.. + +.. bpo: 28797 +.. date: 9789 +.. nonce: _A0_Z5 +.. section: Core and Builtins + +Modifying the class __dict__ inside the __set_name__ method of a descriptor +that is used inside that class no longer prevents calling the __set_name__ +method of other descriptors. + +.. + +.. bpo: 28782 +.. date: 9788 +.. nonce: foJV_E +.. section: Core and Builtins + +Fix a bug in the implementation ``yield from`` when checking if the next +instruction is YIELD_FROM. Regression introduced by WORDCODE (issue #26647). + +.. + +.. bpo: 27030 +.. date: 9787 +.. nonce: 88FOrz +.. section: Library + +Unknown escapes in re.sub() replacement template are allowed again. But +they still are deprecated and will be disabled in 3.7. + +.. + +.. bpo: 28835 +.. date: 9786 +.. nonce: Fv7Dr1 +.. section: Library + +Fix a regression introduced in warnings.catch_warnings(): call +warnings.showwarning() if it was overridden inside the context manager. + +.. + +.. bpo: 27172 +.. date: 9785 +.. nonce: mVKfLT +.. section: Library + +To assist with upgrades from 2.7, the previously documented deprecation of +``inspect.getfullargspec()`` has been reversed. This decision may be +revisited again after the Python 2.7 branch is no longer officially +supported. + +.. + +.. bpo: 26273 +.. date: 9784 +.. nonce: ilNIWN +.. section: Library + +Add new :const:`socket.TCP_CONGESTION` (Linux 2.6.13) and +:const:`socket.TCP_USER_TIMEOUT` (Linux 2.6.37) constants. Patch written by +Omar Sandoval. + +.. + +.. bpo: 24142 +.. date: 9783 +.. nonce: IrZnFs +.. section: Library + +Reading a corrupt config file left configparser in an invalid state. +Original patch by Florian Höch. + +.. + +.. bpo: 28843 +.. date: 9782 +.. nonce: O7M0LE +.. section: Library + +Fix asyncio C Task to handle exceptions __traceback__. + +.. + +.. bpo: 28808 +.. date: 9781 +.. nonce: A03X6r +.. section: C API + +PyUnicode_CompareWithASCIIString() now never raises exceptions. + +.. + +.. bpo: 23722 +.. date: 9780 +.. nonce: 6HX6fk +.. section: Documentation + +The data model reference and the porting section in the What's New guide now +cover the additional ``__classcell__`` handling needed for custom +metaclasses to fully support :pep:`487` and zero-argument ``super()``. + +.. + +.. bpo: 28023 +.. date: 9779 +.. nonce: 4gzSGp +.. section: Tools/Demos + +Fix python-gdb.py didn't support new dict implementation. diff --git a/Misc/NEWS.d/3.6.0rc2.rst b/Misc/NEWS.d/3.6.0rc2.rst new file mode 100644 index 00000000..4a786941 --- /dev/null +++ b/Misc/NEWS.d/3.6.0rc2.rst @@ -0,0 +1,45 @@ +.. bpo: 28147 +.. date: 9795 +.. nonce: CnK_xf +.. release date: 2016-12-16 +.. section: Core and Builtins + +Fix a memory leak in split-table dictionaries: setattr() must not convert +combined table into split table. Patch written by INADA Naoki. + +.. + +.. bpo: 28990 +.. date: 9794 +.. nonce: m8xRMJ +.. section: Core and Builtins + +Fix asyncio SSL hanging if connection is closed before handshake is +completed. (Patch by HoHo-Ho) + +.. + +.. bpo: 28770 +.. date: 9793 +.. nonce: N9GQsz +.. section: Tools/Demos + +Fix python-gdb.py for fastcalls. + +.. + +.. bpo: 28896 +.. date: 9792 +.. nonce: ymAbmH +.. section: Windows + +Deprecate WindowsRegistryFinder. + +.. + +.. bpo: 28898 +.. date: 9791 +.. nonce: YGUd_i +.. section: Build + +Prevent gdb build errors due to HAVE_LONG_LONG redefinition. diff --git a/Misc/NEWS.d/3.6.1.rst b/Misc/NEWS.d/3.6.1.rst new file mode 100644 index 00000000..a7bf84ef --- /dev/null +++ b/Misc/NEWS.d/3.6.1.rst @@ -0,0 +1,31 @@ +.. bpo: 29723 +.. date: 9895 +.. nonce: M5omgP +.. release date: 2017-03-21 +.. section: Core and Builtins + +The ``sys.path[0]`` initialization change for bpo-29139 caused a regression +by revealing an inconsistency in how sys.path is initialized when executing +``__main__`` from a zipfile, directory, or other import location. The +interpreter now consistently avoids ever adding the import location's parent +directory to ``sys.path``, and ensures no other ``sys.path`` entries are +inadvertently modified when inserting the import location named on the +command line. + +.. + +.. bpo: 27593 +.. date: 9894 +.. nonce: nk7Etn +.. section: Build + +fix format of git information used in sys.version + +.. + +.. bpo: 0 +.. date: 9893 +.. nonce: usKKNQ +.. section: Build + +Fix incompatible comment in python.h diff --git a/Misc/NEWS.d/3.6.1rc1.rst b/Misc/NEWS.d/3.6.1rc1.rst new file mode 100644 index 00000000..58fd1b06 --- /dev/null +++ b/Misc/NEWS.d/3.6.1rc1.rst @@ -0,0 +1,940 @@ +.. bpo: 28893 +.. date: 9892 +.. nonce: WTKnpj +.. release date: 2017-03-04 +.. section: Core and Builtins + +Set correct __cause__ for errors about invalid awaitables returned from +__aiter__ and __anext__. + +.. + +.. bpo: 29683 +.. date: 9891 +.. nonce: G5iS-P +.. section: Core and Builtins + +Fixes to memory allocation in _PyCode_SetExtra. Patch by Brian Coleman. + +.. + +.. bpo: 29684 +.. date: 9890 +.. nonce: wTgEoh +.. section: Core and Builtins + +Fix minor regression of PyEval_CallObjectWithKeywords. It should raise +TypeError when kwargs is not a dict. But it might cause segv when args=NULL +and kwargs is not a dict. + +.. + +.. bpo: 28598 +.. date: 9889 +.. nonce: QxbzQn +.. section: Core and Builtins + +Support __rmod__ for subclasses of str being called before str.__mod__. +Patch by Martijn Pieters. + +.. + +.. bpo: 29607 +.. date: 9888 +.. nonce: 7NvBA1 +.. section: Core and Builtins + +Fix stack_effect computation for CALL_FUNCTION_EX. Patch by Matthieu +Dartiailh. + +.. + +.. bpo: 29602 +.. date: 9887 +.. nonce: qyyskC +.. section: Core and Builtins + +Fix incorrect handling of signed zeros in complex constructor for complex +subclasses and for inputs having a __complex__ method. Patch by Serhiy +Storchaka. + +.. + +.. bpo: 29347 +.. date: 9886 +.. nonce: 1RPPGN +.. section: Core and Builtins + +Fixed possibly dereferencing undefined pointers when creating weakref +objects. + +.. + +.. bpo: 29438 +.. date: 9885 +.. nonce: IKxD6I +.. section: Core and Builtins + +Fixed use-after-free problem in key sharing dict. + +.. + +.. bpo: 29319 +.. date: 9884 +.. nonce: KLDUZf +.. section: Core and Builtins + +Prevent RunMainFromImporter overwriting sys.path[0]. + +.. + +.. bpo: 29337 +.. date: 9883 +.. nonce: bjX8AE +.. section: Core and Builtins + +Fixed possible BytesWarning when compare the code objects. Warnings could be +emitted at compile time. + +.. + +.. bpo: 29327 +.. date: 9882 +.. nonce: XXQarW +.. section: Core and Builtins + +Fixed a crash when pass the iterable keyword argument to sorted(). + +.. + +.. bpo: 29034 +.. date: 9881 +.. nonce: 7-uEDT +.. section: Core and Builtins + +Fix memory leak and use-after-free in os module (path_converter). + +.. + +.. bpo: 29159 +.. date: 9880 +.. nonce: gEn_kP +.. section: Core and Builtins + +Fix regression in bytes(x) when x.__index__() raises Exception. + +.. + +.. bpo: 28932 +.. date: 9879 +.. nonce: QnLx8A +.. section: Core and Builtins + +Do not include <sys/random.h> if it does not exist. + +.. + +.. bpo: 25677 +.. date: 9878 +.. nonce: RWhZrb +.. section: Core and Builtins + +Correct the positioning of the syntax error caret for indented blocks. +Based on patch by Michael Layzell. + +.. + +.. bpo: 29000 +.. date: 9877 +.. nonce: K6wQ-3 +.. section: Core and Builtins + +Fixed bytes formatting of octals with zero padding in alternate form. + +.. + +.. bpo: 26919 +.. date: 9876 +.. nonce: Cm7MSa +.. section: Core and Builtins + +On Android, operating system data is now always encoded/decoded to/from +UTF-8, instead of the locale encoding to avoid inconsistencies with +os.fsencode() and os.fsdecode() which are already using UTF-8. + +.. + +.. bpo: 28991 +.. date: 9875 +.. nonce: lGA0FK +.. section: Core and Builtins + +functools.lru_cache() was susceptible to an obscure reentrancy bug +triggerable by a monkey-patched len() function. + +.. + +.. bpo: 28739 +.. date: 9874 +.. nonce: w1fvhk +.. section: Core and Builtins + +f-string expressions are no longer accepted as docstrings and by +ast.literal_eval() even if they do not include expressions. + +.. + +.. bpo: 28512 +.. date: 9873 +.. nonce: i-pv6d +.. section: Core and Builtins + +Fixed setting the offset attribute of SyntaxError by +PyErr_SyntaxLocationEx() and PyErr_SyntaxLocationObject(). + +.. + +.. bpo: 28918 +.. date: 9872 +.. nonce: SFVuPz +.. section: Core and Builtins + +Fix the cross compilation of xxlimited when Python has been built with +Py_DEBUG defined. + +.. + +.. bpo: 28731 +.. date: 9871 +.. nonce: oNF59u +.. section: Core and Builtins + +Optimize _PyDict_NewPresized() to create correct size dict. Improve speed of +dict literal with constant keys up to 30%. + +.. + +.. bpo: 29169 +.. date: 9870 +.. nonce: 8ypApm +.. section: Library + +Update zlib to 1.2.11. + +.. + +.. bpo: 29623 +.. date: 9869 +.. nonce: D3-NP2 +.. section: Library + +Allow use of path-like object as a single argument in ConfigParser.read(). +Patch by David Ellis. + +.. + +.. bpo: 28963 +.. date: 9868 +.. nonce: tPl8dq +.. section: Library + +Fix out of bound iteration in asyncio.Future.remove_done_callback +implemented in C. + +.. + +.. bpo: 29704 +.. date: 9867 +.. nonce: r-kWqv +.. section: Library + +asyncio.subprocess.SubprocessStreamProtocol no longer closes before all +pipes are closed. + +.. + +.. bpo: 29271 +.. date: 9866 +.. nonce: y8Vj2v +.. section: Library + +Fix Task.current_task and Task.all_tasks implemented in C to accept None +argument as their pure Python implementation. + +.. + +.. bpo: 29703 +.. date: 9865 +.. nonce: ZdsPCR +.. section: Library + +Fix asyncio to support instantiation of new event loops in child processes. + +.. + +.. bpo: 29376 +.. date: 9864 +.. nonce: rrJhJy +.. section: Library + +Fix assertion error in threading._DummyThread.is_alive(). + +.. + +.. bpo: 28624 +.. date: 9863 +.. nonce: 43TJib +.. section: Library + +Add a test that checks that cwd parameter of Popen() accepts PathLike +objects. Patch by Sayan Chowdhury. + +.. + +.. bpo: 28518 +.. date: 9862 +.. nonce: o-Q2Nw +.. section: Library + +Start a transaction implicitly before a DML statement. Patch by Aviv +Palivoda. + +.. + +.. bpo: 29532 +.. date: 9861 +.. nonce: YCwVQn +.. section: Library + +Altering a kwarg dictionary passed to functools.partial() no longer affects +a partial object after creation. + +.. + +.. bpo: 29110 +.. date: 9860 +.. nonce: wmE-_T +.. section: Library + +Fix file object leak in aifc.open() when file is given as a filesystem path +and is not in valid AIFF format. Patch by Anthony Zhang. + +.. + +.. bpo: 28556 +.. date: 9859 +.. nonce: p6967e +.. section: Library + +Various updates to typing module: typing.Counter, typing.ChainMap, improved +ABC caching, etc. Original PRs by Jelle Zijlstra, Ivan Levkivskyi, Manuel +Krebber, and Łukasz Langa. + +.. + +.. bpo: 29100 +.. date: 9858 +.. nonce: LAAERS +.. section: Library + +Fix datetime.fromtimestamp() regression introduced in Python 3.6.0: check +minimum and maximum years. + +.. + +.. bpo: 29519 +.. date: 9857 +.. nonce: oGGgZ4 +.. section: Library + +Fix weakref spewing exceptions during interpreter shutdown when used with a +rare combination of multiprocessing and custom codecs. + +.. + +.. bpo: 29416 +.. date: 9856 +.. nonce: KJGyI_ +.. section: Library + +Prevent infinite loop in pathlib.Path.mkdir + +.. + +.. bpo: 29444 +.. date: 9855 +.. nonce: cEwgmk +.. section: Library + +Fixed out-of-bounds buffer access in the group() method of the match object. +Based on patch by WGH. + +.. + +.. bpo: 29335 +.. date: 9854 +.. nonce: _KC7IK +.. section: Library + +Fix subprocess.Popen.wait() when the child process has exited to a stopped +instead of terminated state (ex: when under ptrace). + +.. + +.. bpo: 29290 +.. date: 9853 +.. nonce: XBqptF +.. section: Library + +Fix a regression in argparse that help messages would wrap at non-breaking +spaces. + +.. + +.. bpo: 28735 +.. date: 9852 +.. nonce: admHLO +.. section: Library + +Fixed the comparison of mock.MagickMock with mock.ANY. + +.. + +.. bpo: 29316 +.. date: 9851 +.. nonce: OeOQw5 +.. section: Library + +Restore the provisional status of typing module, add corresponding note to +documentation. Patch by Ivan L. + +.. + +.. bpo: 29219 +.. date: 9850 +.. nonce: kxui7t +.. section: Library + +Fixed infinite recursion in the repr of uninitialized ctypes.CDLL instances. + +.. + +.. bpo: 29011 +.. date: 9849 +.. nonce: MI5f2R +.. section: Library + +Fix an important omission by adding Deque to the typing module. + +.. + +.. bpo: 28969 +.. date: 9848 +.. nonce: j3HJYO +.. section: Library + +Fixed race condition in C implementation of functools.lru_cache. KeyError +could be raised when cached function with full cache was simultaneously +called from different threads with the same uncached arguments. + +.. + +.. bpo: 29142 +.. date: 9847 +.. nonce: xo6kAv +.. section: Library + +In urllib.request, suffixes in no_proxy environment variable with leading +dots could match related hostnames again (e.g. .b.c matches a.b.c). Patch by +Milan Oberkirch. + +.. + +.. bpo: 28961 +.. date: 9846 +.. nonce: Rt93vg +.. section: Library + +Fix unittest.mock._Call helper: don't ignore the name parameter anymore. +Patch written by Jiajun Huang. + +.. + +.. bpo: 29203 +.. date: 9845 +.. nonce: kN5S6v +.. section: Library + +functools.lru_cache() now respects :pep:`468` and preserves the order of +keyword arguments. f(a=1, b=2) is now cached separately from f(b=2, a=1) +since both calls could potentially give different results. + +.. + +.. bpo: 15812 +.. date: 9844 +.. nonce: R1U-Ec +.. section: Library + +inspect.getframeinfo() now correctly shows the first line of a context. +Patch by Sam Breese. + +.. + +.. bpo: 29094 +.. date: 9843 +.. nonce: 460ZQo +.. section: Library + +Offsets in a ZIP file created with extern file object and modes "w" and "x" +now are relative to the start of the file. + +.. + +.. bpo: 29085 +.. date: 9842 +.. nonce: bm3gkx +.. section: Library + +Allow random.Random.seed() to use high quality OS randomness rather than the +pid and time. + +.. + +.. bpo: 29061 +.. date: 9841 +.. nonce: YKq0Ba +.. section: Library + +Fixed bug in secrets.randbelow() which would hang when given a negative +input. Patch by Brendan Donegan. + +.. + +.. bpo: 29079 +.. date: 9840 +.. nonce: g4YLix +.. section: Library + +Prevent infinite loop in pathlib.resolve() on Windows + +.. + +.. bpo: 13051 +.. date: 9839 +.. nonce: YzC1Te +.. section: Library + +Fixed recursion errors in large or resized curses.textpad.Textbox. Based on +patch by Tycho Andersen. + +.. + +.. bpo: 29119 +.. date: 9838 +.. nonce: Ov69fr +.. section: Library + +Fix weakrefs in the pure python version of collections.OrderedDict +move_to_end() method. Contributed by Andra Bogildea. + +.. + +.. bpo: 9770 +.. date: 9837 +.. nonce: WJJnwP +.. section: Library + +curses.ascii predicates now work correctly with negative integers. + +.. + +.. bpo: 28427 +.. date: 9836 +.. nonce: vUd-va +.. section: Library + +old keys should not remove new values from WeakValueDictionary when +collecting from another thread. + +.. + +.. bpo: 28923 +.. date: 9835 +.. nonce: naVULD +.. section: Library + +Remove editor artifacts from Tix.py. + +.. + +.. bpo: 29055 +.. date: 9834 +.. nonce: -r_9jc +.. section: Library + +Neaten-up empty population error on random.choice() by suppressing the +upstream exception. + +.. + +.. bpo: 28871 +.. date: 9833 +.. nonce: cPMXCJ +.. section: Library + +Fixed a crash when deallocate deep ElementTree. + +.. + +.. bpo: 19542 +.. date: 9832 +.. nonce: 5tCkaK +.. section: Library + +Fix bugs in WeakValueDictionary.setdefault() and WeakValueDictionary.pop() +when a GC collection happens in another thread. + +.. + +.. bpo: 20191 +.. date: 9831 +.. nonce: Q7uZCS +.. section: Library + +Fixed a crash in resource.prlimit() when passing a sequence that doesn't own +its elements as limits. + +.. + +.. bpo: 28779 +.. date: 9830 +.. nonce: t-mjED +.. section: Library + +multiprocessing.set_forkserver_preload() would crash the forkserver process +if a preloaded module instantiated some multiprocessing objects such as +locks. + +.. + +.. bpo: 28847 +.. date: 9829 +.. nonce: J7d3nG +.. section: Library + +dbm.dumb now supports reading read-only files and no longer writes the index +file when it is not changed. + +.. + +.. bpo: 26937 +.. date: 9828 +.. nonce: c9kgiA +.. section: Library + +The chown() method of the tarfile.TarFile class does not fail now when the +grp module cannot be imported, as for example on Android platforms. + +.. + +.. bpo: 29071 +.. date: 9827 +.. nonce: FCOpJn +.. section: IDLE + +IDLE colors f-string prefixes (but not invalid ur prefixes). + +.. + +.. bpo: 28572 +.. date: 9826 +.. nonce: 1_duKY +.. section: IDLE + +Add 10% to coverage of IDLE's test_configdialog. Update and augment +description of the configuration system. + +.. + +.. bpo: 29579 +.. date: 9825 +.. nonce: Ih-G2Q +.. section: Windows + +Removes readme.txt from the installer + +.. + +.. bpo: 29326 +.. date: 9824 +.. nonce: 4qDQzs +.. section: Windows + +Ignores blank lines in ._pth files (Patch by Alexey Izbyshev) + +.. + +.. bpo: 28164 +.. date: 9823 +.. nonce: h4CFX8 +.. section: Windows + +Correctly handle special console filenames (patch by Eryk Sun) + +.. + +.. bpo: 29409 +.. date: 9822 +.. nonce: bhvrJ2 +.. section: Windows + +Implement :pep:`529` for io.FileIO (Patch by Eryk Sun) + +.. + +.. bpo: 29392 +.. date: 9821 +.. nonce: OtqS5t +.. section: Windows + +Prevent crash when passing invalid arguments into msvcrt module. + +.. + +.. bpo: 25778 +.. date: 9820 +.. nonce: 8uKJ82 +.. section: Windows + +winreg does not truncate string correctly (Patch by Eryk Sun) + +.. + +.. bpo: 28896 +.. date: 9819 +.. nonce: VMi9w0 +.. section: Windows + +Deprecate WindowsRegistryFinder and disable it by default. + +.. + +.. bpo: 27867 +.. date: 9818 +.. nonce: UC5ohc +.. section: C API + +Function PySlice_GetIndicesEx() is replaced with a macro if Py_LIMITED_API +is not set or set to the value between 0x03050400 and 0x03060000 (not +including) or 0x03060100 or higher. + +.. + +.. bpo: 29083 +.. date: 9817 +.. nonce: tGTjr_ +.. section: C API + +Fixed the declaration of some public API functions. PyArg_VaParse() and +PyArg_VaParseTupleAndKeywords() were not available in limited API. +PyArg_ValidateKeywordArguments(), PyArg_UnpackTuple() and Py_BuildValue() +were not available in limited API of version < 3.3 when PY_SSIZE_T_CLEAN is +defined. + +.. + +.. bpo: 29058 +.. date: 9816 +.. nonce: 0wNVP8 +.. section: C API + +All stable API extensions added after Python 3.2 are now available only when +Py_LIMITED_API is set to the PY_VERSION_HEX value of the minimum Python +version supporting this API. + +.. + +.. bpo: 28929 +.. date: 9815 +.. nonce: Md7kb0 +.. section: Documentation + +Link the documentation to its source file on GitHub. + +.. + +.. bpo: 25008 +.. date: 9814 +.. nonce: CeIzyU +.. section: Documentation + +Document smtpd.py as effectively deprecated and add a pointer to aiosmtpd, a +third-party asyncio-based replacement. + +.. + +.. bpo: 26355 +.. date: 9813 +.. nonce: SDq_8Y +.. section: Documentation + +Add canonical header link on each page to corresponding major version of the +documentation. Patch by Matthias Bussonnier. + +.. + +.. bpo: 29349 +.. date: 9812 +.. nonce: PjSo-t +.. section: Documentation + +Fix Python 2 syntax in code for building the documentation. + +.. + +.. bpo: 28087 +.. date: 9811 +.. nonce: m8dc4R +.. section: Tests + +Skip test_asyncore and test_eintr poll failures on macOS. Skip some tests of +select.poll when running on macOS due to unresolved issues with the +underlying system poll function on some macOS versions. + +.. + +.. bpo: 29571 +.. date: 9810 +.. nonce: r6Dixr +.. section: Tests + +to match the behaviour of the ``re.LOCALE`` flag, test_re.test_locale_flag +now uses ``locale.getpreferredencoding(False)`` to determine the candidate +encoding for the test regex (allowing it to correctly skip the test when the +default locale encoding is a multi-byte encoding) + +.. + +.. bpo: 28950 +.. date: 9809 +.. nonce: 1W8Glo +.. section: Tests + +Disallow -j0 to be combined with -T/-l in regrtest command line arguments. + +.. + +.. bpo: 28683 +.. date: 9808 +.. nonce: Fp-Hdq +.. section: Tests + +Fix the tests that bind() a unix socket and raise PermissionError on Android +for a non-root user. + +.. + +.. bpo: 26939 +.. date: 9807 +.. nonce: 7j_W5R +.. section: Tests + +Add the support.setswitchinterval() function to fix test_functools hanging +on the Android armv7 qemu emulator. + +.. + +.. bpo: 27593 +.. date: 9806 +.. nonce: v87xEr +.. section: Build + +sys.version and the platform module python_build(), python_branch(), and +python_revision() functions now use git information rather than hg when +building from a repo. + +.. + +.. bpo: 29572 +.. date: 9805 +.. nonce: iZ1XKK +.. section: Build + +Update Windows build and OS X installers to use OpenSSL 1.0.2k. + +.. + +.. bpo: 26851 +.. date: 9804 +.. nonce: R5243g +.. section: Build + +Set Android compilation and link flags. + +.. + +.. bpo: 28768 +.. date: 9803 +.. nonce: b9_a6E +.. section: Build + +Fix implicit declaration of function _setmode. Patch by Masayuki Yamamoto + +.. + +.. bpo: 29080 +.. date: 9802 +.. nonce: b3qLQT +.. section: Build + +Removes hard dependency on hg.exe from PCBuild/build.bat + +.. + +.. bpo: 23903 +.. date: 9801 +.. nonce: JXJ889 +.. section: Build + +Added missed names to PC/python3.def. + +.. + +.. bpo: 28762 +.. date: 9800 +.. nonce: Ru0YN_ +.. section: Build + +lockf() is available on Android API level 24, but the F_LOCK macro is not +defined in android-ndk-r13. + +.. + +.. bpo: 28538 +.. date: 9799 +.. nonce: FqtN7v +.. section: Build + +Fix the compilation error that occurs because if_nameindex() is available on +Android API level 24, but the if_nameindex structure is not defined. + +.. + +.. bpo: 20211 +.. date: 9798 +.. nonce: gpNptI +.. section: Build + +Do not add the directory for installing C header files and the directory for +installing object code libraries to the cross compilation search paths. +Original patch by Thomas Petazzoni. + +.. + +.. bpo: 28849 +.. date: 9797 +.. nonce: AzRRF5 +.. section: Build + +Do not define sys.implementation._multiarch on Android. diff --git a/Misc/NEWS.d/3.6.2.rst b/Misc/NEWS.d/3.6.2.rst new file mode 100644 index 00000000..dba43d14 --- /dev/null +++ b/Misc/NEWS.d/3.6.2.rst @@ -0,0 +1,7 @@ +.. bpo: 0 +.. date: 9993 +.. no changes: True +.. nonce: F9ENBV +.. release date: 2017-07-17 + +No changes since release candidate 2 diff --git a/Misc/NEWS.d/3.6.2rc1.rst b/Misc/NEWS.d/3.6.2rc1.rst new file mode 100644 index 00000000..28eb88f7 --- /dev/null +++ b/Misc/NEWS.d/3.6.2rc1.rst @@ -0,0 +1,941 @@ +.. release date: 2017-06-17 +.. bpo: 29591 +.. date: 9966 +.. nonce: ExKblw +.. original section: Library +.. section: Security + +Update expat copy from 2.1.1 to 2.2.0 to get fixes of CVE-2016-0718 and +CVE-2016-4472. See https://sourceforge.net/p/expat/bugs/537/ for more +information. + +.. + +.. bpo: 30682 +.. date: 9989 +.. nonce: zZm88E +.. section: Core and Builtins + +Removed a too-strict assertion that failed for certain f-strings, such as +eval("f'\\\n'") and eval("f'\\\r'"). + +.. + +.. bpo: 30604 +.. date: 9988 +.. nonce: W47hPY +.. section: Core and Builtins + +Move co_extra_freefuncs to not be per-thread to avoid crashes + +.. + +.. bpo: 29104 +.. date: 9987 +.. nonce: u26yCx +.. section: Core and Builtins + +Fixed parsing backslashes in f-strings. + +.. + +.. bpo: 27945 +.. date: 9986 +.. nonce: p29r3O +.. section: Core and Builtins + +Fixed various segfaults with dict when input collections are mutated during +searching, inserting or comparing. Based on patches by Duane Griffin and +Tim Mitchell. + +.. + +.. bpo: 25794 +.. date: 9985 +.. nonce: xfPwqm +.. section: Core and Builtins + +Fixed type.__setattr__() and type.__delattr__() for non-interned attribute +names. Based on patch by Eryk Sun. + +.. + +.. bpo: 30039 +.. date: 9984 +.. nonce: e0u4DG +.. section: Core and Builtins + +If a KeyboardInterrupt happens when the interpreter is in the middle of +resuming a chain of nested 'yield from' or 'await' calls, it's now correctly +delivered to the innermost frame. + +.. + +.. bpo: 12414 +.. date: 9983 +.. nonce: T9ix8O +.. section: Core and Builtins + +sys.getsizeof() on a code object now returns the sizes which includes the +code struct and sizes of objects which it references. Patch by Donghee Na. + +.. + +.. bpo: 29949 +.. date: 9982 +.. nonce: DevGPS +.. section: Core and Builtins + +Fix memory usage regression of set and frozenset object. + +.. + +.. bpo: 29935 +.. date: 9981 +.. nonce: vgjdJo +.. section: Core and Builtins + +Fixed error messages in the index() method of tuple, list and deque when +pass indices of wrong type. + +.. + +.. bpo: 29859 +.. date: 9980 +.. nonce: Z1MLcA +.. section: Core and Builtins + +Show correct error messages when any of the pthread_* calls in +thread_pthread.h fails. + +.. + +.. bpo: 28876 +.. date: 9979 +.. nonce: cU-sGT +.. section: Core and Builtins + +``bool(range)`` works even if ``len(range)`` raises :exc:`OverflowError`. + +.. + +.. bpo: 29600 +.. date: 9978 +.. nonce: 77wQ6C +.. section: Core and Builtins + +Fix wrapping coroutine return values in StopIteration. + +.. + +.. bpo: 28856 +.. date: 9977 +.. nonce: AFRmo4 +.. section: Core and Builtins + +Fix an oversight that %b format for bytes should support objects follow the +buffer protocol. + +.. + +.. bpo: 29714 +.. date: 9976 +.. nonce: z-BhVd +.. section: Core and Builtins + +Fix a regression that bytes format may fail when containing zero bytes +inside. + +.. + +.. bpo: 29478 +.. date: 9975 +.. nonce: rTQ-qy +.. section: Core and Builtins + +If max_line_length=None is specified while using the Compat32 policy, it is +no longer ignored. Patch by Mircea Cosbuc. + +.. + +.. bpo: 30616 +.. date: 9974 +.. nonce: I2mDTz +.. section: Library + +Functional API of enum allows to create empty enums. Patched by Donghee Na + +.. + +.. bpo: 30038 +.. date: 9973 +.. nonce: vb4DWk +.. section: Library + +Fix race condition between signal delivery and wakeup file descriptor. +Patch by Nathaniel Smith. + +.. + +.. bpo: 23894 +.. date: 9972 +.. nonce: k2pADV +.. section: Library + +lib2to3 now recognizes ``rb'...'`` and ``f'...'`` strings. + +.. + +.. bpo: 23890 +.. date: 9971 +.. nonce: GCFAAZ +.. section: Library + +unittest.TestCase.assertRaises() now manually breaks a reference cycle to +not keep objects alive longer than expected. + +.. + +.. bpo: 30149 +.. date: 9970 +.. nonce: hE649r +.. section: Library + +inspect.signature() now supports callables with variable-argument parameters +wrapped with partialmethod. Patch by Donghee Na. + +.. + +.. bpo: 30645 +.. date: 9969 +.. nonce: oYzbbW +.. section: Library + +Fix path calculation in imp.load_package(), fixing it for cases when a +package is only shipped with bytecodes. Patch by Alexandru Ardelean. + +.. + +.. bpo: 29931 +.. date: 9968 +.. nonce: tfcTwK +.. section: Library + +Fixed comparison check for ipaddress.ip_interface objects. Patch by Sanjay +Sundaresan. + +.. + +.. bpo: 30605 +.. date: 9967 +.. nonce: XqGz1r +.. section: Library + +re.compile() no longer raises a BytesWarning when compiling a bytes instance +with misplaced inline modifier. Patch by Roy Williams. + +.. + +.. bpo: 24484 +.. date: 9965 +.. nonce: fNS32j +.. section: Library + +Avoid race condition in multiprocessing cleanup (#2159) + +.. + +.. bpo: 28994 +.. date: 9964 +.. nonce: 9vzun1 +.. section: Library + +The traceback no longer displayed for SystemExit raised in a callback +registered by atexit. + +.. + +.. bpo: 30508 +.. date: 9963 +.. nonce: wNWRS2 +.. section: Library + +Don't log exceptions if Task/Future "cancel()" method was called. + +.. + +.. bpo: 28556 +.. date: 9962 +.. nonce: mESP7G +.. section: Library + +Updates to typing module: Add generic AsyncContextManager, add support for +ContextManager on all versions. Original PRs by Jelle Zijlstra and Ivan +Levkivskyi + +.. + +.. bpo: 29870 +.. date: 9961 +.. nonce: p960Ih +.. section: Library + +Fix ssl sockets leaks when connection is aborted in asyncio/ssl +implementation. Patch by Michaël Sghaïer. + +.. + +.. bpo: 29743 +.. date: 9960 +.. nonce: en2P4s +.. section: Library + +Closing transport during handshake process leaks open socket. Patch by +Nikolay Kim + +.. + +.. bpo: 27585 +.. date: 9959 +.. nonce: 0Ugqqu +.. section: Library + +Fix waiter cancellation in asyncio.Lock. Patch by Mathieu Sornay. + +.. + +.. bpo: 30418 +.. date: 9958 +.. nonce: EwISQm +.. section: Library + +On Windows, subprocess.Popen.communicate() now also ignore EINVAL on +stdin.write() if the child process is still running but closed the pipe. + +.. + +.. bpo: 29822 +.. date: 9957 +.. nonce: G7dX13 +.. section: Library + +inspect.isabstract() now works during __init_subclass__. Patch by Nate +Soares. + +.. + +.. bpo: 29581 +.. date: 9956 +.. nonce: gHCrxP +.. section: Library + +ABCMeta.__new__ now accepts ``**kwargs``, allowing abstract base classes to +use keyword parameters in __init_subclass__. Patch by Nate Soares. + +.. + +.. bpo: 30557 +.. date: 9955 +.. nonce: uykrLf +.. section: Library + +faulthandler now correctly filters and displays exception codes on Windows + +.. + +.. bpo: 30378 +.. date: 9954 +.. nonce: R_19_5 +.. section: Library + +Fix the problem that logging.handlers.SysLogHandler cannot handle IPv6 +addresses. + +.. + +.. bpo: 29960 +.. date: 9953 +.. nonce: g0wr3r +.. section: Library + +Preserve generator state when _random.Random.setstate() raises an exception. +Patch by Bryan Olson. + +.. + +.. bpo: 30414 +.. date: 9952 +.. nonce: jGl1Lb +.. section: Library + +multiprocessing.Queue._feed background running thread do not break from main +loop on exception. + +.. + +.. bpo: 30003 +.. date: 9951 +.. nonce: BOl9HE +.. section: Library + +Fix handling escape characters in HZ codec. Based on patch by Ma Lin. + +.. + +.. bpo: 30301 +.. date: 9950 +.. nonce: ywOkjN +.. section: Library + +Fix AttributeError when using SimpleQueue.empty() under *spawn* and +*forkserver* start methods. + +.. + +.. bpo: 30329 +.. date: 9949 +.. nonce: EuT36N +.. section: Library + +imaplib and poplib now catch the Windows socket WSAEINVAL error (code 10022) +on shutdown(SHUT_RDWR): An invalid operation was attempted. This error +occurs sometimes on SSL connections. + +.. + +.. bpo: 30375 +.. date: 9948 +.. nonce: 9c8qM7 +.. section: Library + +Warnings emitted when compile a regular expression now always point to the +line in the user code. Previously they could point into inners of the re +module if emitted from inside of groups or conditionals. + +.. + +.. bpo: 30048 +.. date: 9947 +.. nonce: ELRx8R +.. section: Library + +Fixed ``Task.cancel()`` can be ignored when the task is running coroutine +and the coroutine returned without any more ``await``. + +.. + +.. bpo: 30266 +.. date: 9946 +.. nonce: YJzHAH +.. section: Library + +contextlib.AbstractContextManager now supports anti-registration by setting +__enter__ = None or __exit__ = None, following the pattern introduced in +bpo-25958. Patch by Jelle Zijlstra. + +.. + +.. bpo: 30298 +.. date: 9945 +.. nonce: ZN-bWo +.. section: Library + +Weaken the condition of deprecation warnings for inline modifiers. Now +allowed several subsequential inline modifiers at the start of the pattern +(e.g. ``'(?i)(?s)...'``). In verbose mode whitespaces and comments now are +allowed before and between inline modifiers (e.g. ``'(?x) (?i) (?s)...'``). + +.. + +.. bpo: 29990 +.. date: 9944 +.. nonce: HWV6KE +.. section: Library + +Fix range checking in GB18030 decoder. Original patch by Ma Lin. + +.. + +.. bpo: 26293 +.. date: 9943 +.. nonce: wig0YG +.. section: Library + +Change resulted because of zipfile breakage. (See also: bpo-29094) + +.. + +.. bpo: 30243 +.. date: 9942 +.. nonce: RHQt0v +.. section: Library + +Removed the __init__ methods of _json's scanner and encoder. Misusing them +could cause memory leaks or crashes. Now scanner and encoder objects are +completely initialized in the __new__ methods. + +.. + +.. bpo: 30185 +.. date: 9941 +.. nonce: Tiu1n8 +.. section: Library + +Avoid KeyboardInterrupt tracebacks in forkserver helper process when Ctrl-C +is received. + +.. + +.. bpo: 28556 +.. date: 9940 +.. nonce: 51gjbP +.. section: Library + +Various updates to typing module: add typing.NoReturn type, use +WrapperDescriptorType, minor bug-fixes. Original PRs by Jim +Fasarakis-Hilliard and Ivan Levkivskyi. + +.. + +.. bpo: 30205 +.. date: 9939 +.. nonce: BsxO34 +.. section: Library + +Fix getsockname() for unbound AF_UNIX sockets on Linux. + +.. + +.. bpo: 30070 +.. date: 9938 +.. nonce: XM_B41 +.. section: Library + +Fixed leaks and crashes in errors handling in the parser module. + +.. + +.. bpo: 30061 +.. date: 9937 +.. nonce: 2w_dX9 +.. section: Library + +Fixed crashes in IOBase methods __next__() and readlines() when readline() +or __next__() respectively return non-sizeable object. Fixed possible other +errors caused by not checking results of PyObject_Size(), PySequence_Size(), +or PyMapping_Size(). + +.. + +.. bpo: 30017 +.. date: 9936 +.. nonce: cKBuhU +.. section: Library + +Allowed calling the close() method of the zip entry writer object multiple +times. Writing to a closed writer now always produces a ValueError. + +.. + +.. bpo: 30068 +.. date: 9935 +.. nonce: n4q47r +.. section: Library + +_io._IOBase.readlines will check if it's closed first when hint is present. + +.. + +.. bpo: 29694 +.. date: 9934 +.. nonce: LWKxb1 +.. section: Library + +Fixed race condition in pathlib mkdir with flags parents=True. Patch by +Armin Rigo. + +.. + +.. bpo: 29692 +.. date: 9933 +.. nonce: oyWrAE +.. section: Library + +Fixed arbitrary unchaining of RuntimeError exceptions in +contextlib.contextmanager. Patch by Siddharth Velankar. + +.. + +.. bpo: 29998 +.. date: 9932 +.. nonce: poeIKD +.. section: Library + +Pickling and copying ImportError now preserves name and path attributes. + +.. + +.. bpo: 29953 +.. date: 9931 +.. nonce: Q1hSt- +.. section: Library + +Fixed memory leaks in the replace() method of datetime and time objects when +pass out of bound fold argument. + +.. + +.. bpo: 29942 +.. date: 9930 +.. nonce: CsGNuT +.. section: Library + +Fix a crash in itertools.chain.from_iterable when encountering long runs of +empty iterables. + +.. + +.. bpo: 27863 +.. date: 9929 +.. nonce: pPYHHI +.. section: Library + +Fixed multiple crashes in ElementTree caused by race conditions and wrong +types. + +.. + +.. bpo: 28699 +.. date: 9928 +.. nonce: wZztZP +.. section: Library + +Fixed a bug in pools in multiprocessing.pool that raising an exception at +the very first of an iterable may swallow the exception or make the program +hang. Patch by Davin Potts and Xiang Zhang. + +.. + +.. bpo: 25803 +.. date: 9927 +.. nonce: CPDR0W +.. section: Library + +Avoid incorrect errors raised by Path.mkdir(exist_ok=True) when the OS gives +priority to errors such as EACCES over EEXIST. + +.. + +.. bpo: 29861 +.. date: 9926 +.. nonce: t2ZoRK +.. section: Library + +Release references to tasks, their arguments and their results as soon as +they are finished in multiprocessing.Pool. + +.. + +.. bpo: 29884 +.. date: 9925 +.. nonce: kWXR8W +.. section: Library + +faulthandler: Restore the old sigaltstack during teardown. Patch by +Christophe Zeitouny. + +.. + +.. bpo: 25455 +.. date: 9924 +.. nonce: ZsahHN +.. section: Library + +Fixed crashes in repr of recursive buffered file-like objects. + +.. + +.. bpo: 29800 +.. date: 9923 +.. nonce: d2xASa +.. section: Library + +Fix crashes in partial.__repr__ if the keys of partial.keywords are not +strings. Patch by Michael Seifert. + +.. + +.. bpo: 29742 +.. date: 9922 +.. nonce: 8hqfEO +.. section: Library + +get_extra_info() raises exception if get called on closed ssl transport. +Patch by Nikolay Kim. + +.. + +.. bpo: 8256 +.. date: 9921 +.. nonce: jAwGQH +.. section: Library + +Fixed possible failing or crashing input() if attributes "encoding" or +"errors" of sys.stdin or sys.stdout are not set or are not strings. + +.. + +.. bpo: 28298 +.. date: 9920 +.. nonce: xfm84U +.. section: Library + +Fix a bug that prevented array 'Q', 'L' and 'I' from accepting big intables +(objects that have __int__) as elements. Patch by Oren Milman. + +.. + +.. bpo: 28231 +.. date: 9919 +.. nonce: MG1X09 +.. section: Library + +The zipfile module now accepts path-like objects for external paths. + +.. + +.. bpo: 26915 +.. date: 9918 +.. nonce: qShJZO +.. section: Library + +index() and count() methods of collections.abc.Sequence now check identity +before checking equality when do comparisons. + +.. + +.. bpo: 29615 +.. date: 9917 +.. nonce: OpFKzg +.. section: Library + +SimpleXMLRPCDispatcher no longer chains KeyError (or any other exception) to +exception(s) raised in the dispatched methods. Patch by Petr Motejlek. + +.. + +.. bpo: 30177 +.. date: 9916 +.. nonce: JGIJNL +.. section: Library + +path.resolve(strict=False) no longer cuts the path after the first element +not present in the filesystem. Patch by Antoine Pietri. + +.. + +.. bpo: 15786 +.. date: 9915 +.. nonce: _XRbaR +.. section: IDLE + +Fix several problems with IDLE's autocompletion box. The following should +now work: clicking on selection box items; using the scrollbar; selecting an +item by hitting Return. Hangs on MacOSX should no longer happen. Patch by +Louie Lu. + +.. + +.. bpo: 25514 +.. date: 9914 +.. nonce: 882pXa +.. section: IDLE + +Add doc subsubsection about IDLE failure to start. Popup no-connection +message directs users to this section. + +.. + +.. bpo: 30642 +.. date: 9913 +.. nonce: 3Zujzt +.. section: IDLE + +Fix reference leaks in IDLE tests. Patches by Louie Lu and Terry Jan Reedy. + +.. + +.. bpo: 30495 +.. date: 9912 +.. nonce: I3i5vL +.. section: IDLE + +Add docstrings for textview.py and use PEP8 names. Patches by Cheryl Sabella +and Terry Jan Reedy. + +.. + +.. bpo: 30290 +.. date: 9911 +.. nonce: fZ3kod +.. section: IDLE + +Help-about: use pep8 names and add tests. Increase coverage to 100%. Patches +by Louie Lu, Cheryl Sabella, and Terry Jan Reedy. + +.. + +.. bpo: 30303 +.. date: 9910 +.. nonce: 2L2F-4 +.. section: IDLE + +Add _utest option to textview; add new tests. Increase coverage to 100%. +Patches by Louie Lu and Terry Jan Reedy. + +.. + +.. bpo: 27867 +.. date: 9909 +.. nonce: B46BRE +.. section: C API + +Function PySlice_GetIndicesEx() no longer replaced with a macro if +Py_LIMITED_API is not set. + +.. + +.. bpo: 29941 +.. date: 9908 +.. nonce: ylh45A +.. section: Build + +Add ``--with-assertions`` configure flag to explicitly enable C ``assert()`` +checks. Defaults to off. ``--with-pydebug`` implies ``--with-assertions``. + +.. + +.. bpo: 28787 +.. date: 9907 +.. nonce: vhH_6a +.. section: Build + +Fix out-of-tree builds of Python when configured with ``--with--dtrace``. + +.. + +.. bpo: 29243 +.. date: 9906 +.. nonce: WDK4hT +.. section: Build + +Prevent unnecessary rebuilding of Python during ``make test``, ``make +install`` and some other make targets when configured with +``--enable-optimizations``. + +.. + +.. bpo: 23404 +.. date: 9905 +.. nonce: PdYVWg +.. section: Build + +Don't regenerate generated files based on file modification time anymore: +the action is now explicit. Replace ``make touch`` with ``make regen-all``. + +.. + +.. bpo: 29643 +.. date: 9904 +.. nonce: 4WLIJQ +.. section: Build + +Fix ``--enable-optimization`` didn't work. + +.. + +.. bpo: 30176 +.. date: 9903 +.. nonce: VivmCg +.. section: Documentation + +Add missing attribute related constants in curses documentation. + +.. + +.. bpo: 30052 +.. date: 9902 +.. nonce: TpmpaF +.. section: Documentation + +the link targets for :func:`bytes` and :func:`bytearray` are now their +respective type definitions, rather than the corresponding builtin function +entries. Use :ref:`bytes <func-bytes>` and :ref:`bytearray <func-bytearray>` +to reference the latter. +In order to ensure this and future cross-reference updates are applied +automatically, the daily documentation builds now disable the default output +caching features in Sphinx. + +.. + +.. bpo: 26985 +.. date: 9901 +.. nonce: NB5_9S +.. section: Documentation + +Add missing info of code object in inspect documentation. + +.. + +.. bpo: 29367 +.. date: 9900 +.. nonce: 4dOKL0 +.. section: Tools/Demos + +python-gdb.py now supports also ``method-wrapper`` (``wrapperobject``) +objects. + +.. + +.. bpo: 30357 +.. date: 9899 +.. nonce: n4CPEa +.. section: Tests + +test_thread: setUp() now uses support.threading_setup() and +support.threading_cleanup() to wait until threads complete to avoid random +side effects on following tests. Initial patch written by Grzegorz Grzywacz. + +.. + +.. bpo: 30197 +.. date: 9898 +.. nonce: c5wRfu +.. section: Tests + +Enhanced functions swap_attr() and swap_item() in the test.support module. +They now work when delete replaced attribute or item inside the with +statement. The old value of the attribute or item (or None if it doesn't +exist) now will be assigned to the target of the "as" clause, if there is +one. + +.. + +.. bpo: 30687 +.. date: 9897 +.. nonce: 8mqHnu +.. section: Windows + +Locate msbuild.exe on Windows when building rather than vcvarsall.bat + +.. + +.. bpo: 30450 +.. date: 9896 +.. nonce: qsaK8y +.. section: Windows + +The build process on Windows no longer depends on Subversion, instead +pulling external code from GitHub via a Python script. If Python 3.6 is not +found on the system (via ``py -3.6``), NuGet is used to download a copy of +32-bit Python. diff --git a/Misc/NEWS.d/3.6.2rc2.rst b/Misc/NEWS.d/3.6.2rc2.rst new file mode 100644 index 00000000..8c6545f6 --- /dev/null +++ b/Misc/NEWS.d/3.6.2rc2.rst @@ -0,0 +1,39 @@ +.. bpo: 30730 +.. date: 9992 +.. nonce: rJsyTH +.. original section: Library +.. release date: 2017-07-07 +.. section: Security + +Prevent environment variables injection in subprocess on Windows. Prevent +passing other environment variables and command arguments. + +.. + +.. bpo: 30694 +.. date: 9991 +.. nonce: WkMWM_ +.. original section: Library +.. section: Security + +Upgrade expat copy from 2.2.0 to 2.2.1 to get fixes of multiple security +vulnerabilities including: CVE-2017-9233 (External entity infinite loop +DoS), CVE-2016-9063 (Integer overflow, re-fix), CVE-2016-0718 (Fix +regression bugs from 2.2.0's fix to CVE-2016-0718) and CVE-2012-0876 +(Counter hash flooding with SipHash). Note: the CVE-2016-5300 (Use +os-specific entropy sources like getrandom) doesn't impact Python, since +Python already gets entropy from the OS to set the expat secret using +``XML_SetHashSalt()``. + +.. + +.. bpo: 30500 +.. date: 9990 +.. nonce: 1VG7R- +.. original section: Library +.. section: Security + +Fix urllib.parse.splithost() to correctly parse fragments. For example, +``splithost('//127.0.0.1#@evil.com/')`` now correctly returns the +``127.0.0.1`` host, instead of treating ``@evil.com`` as the host in an +authentication (``login@host``). diff --git a/Misc/NEWS.d/3.6.3.rst b/Misc/NEWS.d/3.6.3.rst new file mode 100644 index 00000000..4d591d77 --- /dev/null +++ b/Misc/NEWS.d/3.6.3.rst @@ -0,0 +1,27 @@ +.. bpo: 31641 +.. date: 2017-10-03-01-05-11 +.. nonce: vlQEq5 +.. release date: 2017-10-03 +.. section: Library + +Re-allow arbitrary iterables in `concurrent.futures.as_completed()`. Fixes +regression in 3.6.3rc1. + +.. + +.. bpo: 31662 +.. date: 2017-10-03-01-06-24 +.. nonce: 8l2jEz +.. section: Build + +Fix typos in Windows ``uploadrelease.bat`` script. Fix Windows Doc build +issues in ``Doc/make.bat``. + +.. + +.. bpo: 31423 +.. date: 2017-10-03-01-01-52 +.. nonce: uKvPYA +.. section: Build + +Fix building the PDF documentation with newer versions of Sphinx. diff --git a/Misc/NEWS.d/3.6.3rc1.rst b/Misc/NEWS.d/3.6.3rc1.rst new file mode 100644 index 00000000..4b2aae9d --- /dev/null +++ b/Misc/NEWS.d/3.6.3rc1.rst @@ -0,0 +1,1243 @@ +.. bpo: 29781 +.. date: 2017-09-05-15-26-30 +.. nonce: LwYtBP +.. release date: 2017-09-18 +.. section: Security + +SSLObject.version() now correctly returns None when handshake over BIO has +not been performed yet. + +.. + +.. bpo: 30947 +.. date: 2017-08-16-16-35-59 +.. nonce: iNMmm4 +.. section: Security + +Upgrade libexpat embedded copy from version 2.2.1 to 2.2.3 to get security +fixes. + +.. + +.. bpo: 31471 +.. date: 2017-09-14-19-47-57 +.. nonce: 0yiA5Q +.. section: Core and Builtins + +Fix an assertion failure in `subprocess.Popen()` on Windows, in case the env +argument has a bad keys() method. Patch by Oren Milman. + +.. + +.. bpo: 31418 +.. date: 2017-09-13-13-03-52 +.. nonce: rS-FlC +.. section: Core and Builtins + +Fix an assertion failure in `PyErr_WriteUnraisable()` in case of an +exception with a bad ``__module__`` attribute. Patch by Oren Milman. + +.. + +.. bpo: 31416 +.. date: 2017-09-11-12-54-35 +.. nonce: 2hlQFd +.. section: Core and Builtins + +Fix assertion failures in case of a bad warnings.filters or +warnings.defaultaction. Patch by Oren Milman. + +.. + +.. bpo: 31411 +.. date: 2017-09-11-08-50-41 +.. nonce: HZz82I +.. section: Core and Builtins + +Raise a TypeError instead of SystemError in case warnings.onceregistry is +not a dictionary. Patch by Oren Milman. + +.. + +.. bpo: 31373 +.. date: 2017-09-06-15-25-59 +.. nonce: dC4jd4 +.. section: Core and Builtins + +Fix several possible instances of undefined behavior due to floating-point +demotions. + +.. + +.. bpo: 30465 +.. date: 2017-09-06-10-47-29 +.. nonce: oe-3GD +.. section: Core and Builtins + +Location information (``lineno`` and ``col_offset``) in f-strings is now +(mostly) correct. This fixes tools like flake8 from showing warnings on the +wrong line (typically the first line of the file). + +.. + +.. bpo: 31343 +.. date: 2017-09-04-14-57-27 +.. nonce: Kl_fS5 +.. section: Core and Builtins + +Include sys/sysmacros.h for major(), minor(), and makedev(). GNU C libray +plans to remove the functions from sys/types.h. + +.. + +.. bpo: 31291 +.. date: 2017-08-28-11-51-29 +.. nonce: t8QggK +.. section: Core and Builtins + +Fix an assertion failure in `zipimport.zipimporter.get_data` on Windows, +when the return value of ``pathname.replace('/','\\')`` isn't a string. +Patch by Oren Milman. + +.. + +.. bpo: 31271 +.. date: 2017-08-25-20-43-22 +.. nonce: YMduKF +.. section: Core and Builtins + +Fix an assertion failure in the write() method of `io.TextIOWrapper`, when +the encoder doesn't return a bytes object. Patch by Oren Milman. + +.. + +.. bpo: 31243 +.. date: 2017-08-24-13-34-49 +.. nonce: dRJzqR +.. section: Core and Builtins + +Fix a crash in some methods of `io.TextIOWrapper`, when the decoder's state +is invalid. Patch by Oren Milman. + +.. + +.. bpo: 30721 +.. date: 2017-08-18-15-15-20 +.. nonce: Hmc56z +.. section: Core and Builtins + +``print`` now shows correct usage hint for using Python 2 redirection +syntax. Patch by Sanyam Khurana. + +.. + +.. bpo: 31070 +.. date: 2017-08-09-09-40-54 +.. nonce: oDyLiI +.. section: Core and Builtins + +Fix a race condition in importlib _get_module_lock(). + +.. + +.. bpo: 31095 +.. date: 2017-08-01-18-48-30 +.. nonce: bXWZDb +.. section: Core and Builtins + +Fix potential crash during GC caused by ``tp_dealloc`` which doesn't call +``PyObject_GC_UnTrack()``. + +.. + +.. bpo: 31071 +.. date: 2017-07-31-13-28-53 +.. nonce: P9UBDy +.. section: Core and Builtins + +Avoid masking original TypeError in call with * unpacking when other +arguments are passed. + +.. + +.. bpo: 30978 +.. date: 2017-07-21-07-39-05 +.. nonce: f0jODc +.. section: Core and Builtins + +str.format_map() now passes key lookup exceptions through. Previously any +exception was replaced with a KeyError exception. + +.. + +.. bpo: 30808 +.. date: 2017-07-17-12-12-59 +.. nonce: bA3zOv +.. section: Core and Builtins + +Use _Py_atomic API for concurrency-sensitive signal state. + +.. + +.. bpo: 30876 +.. date: 2017-07-11-06-31-32 +.. nonce: x35jZX +.. section: Core and Builtins + +Relative import from unloaded package now reimports the package instead of +failing with SystemError. Relative import from non-package now fails with +ImportError rather than SystemError. + +.. + +.. bpo: 30703 +.. date: 2017-06-28-21-07-32 +.. nonce: ULCdFp +.. section: Core and Builtins + +Improve signal delivery. +Avoid using Py_AddPendingCall from signal handler, to avoid calling +signal-unsafe functions. The tests I'm adding here fail without the rest of +the patch, on Linux and OS X. This means our signal delivery logic had +defects (some signals could be lost). + +.. + +.. bpo: 30765 +.. date: 2017-06-26-14-29-50 +.. nonce: Q5iBmf +.. section: Core and Builtins + +Avoid blocking in pthread_mutex_lock() when PyThread_acquire_lock() is asked +not to block. + +.. + +.. bpo: 31161 +.. date: 06 +.. nonce: FcUAA0 +.. section: Core and Builtins + +Make sure the 'Missing parentheses' syntax error message is only applied to +SyntaxError, not to subclasses. Patch by Martijn Pieters. + +.. + +.. bpo: 30814 +.. date: 05 +.. nonce: HcYsfM +.. section: Core and Builtins + +Fixed a race condition when import a submodule from a package. + +.. + +.. bpo: 30597 +.. date: 04 +.. nonce: 7erHiP +.. section: Core and Builtins + +``print`` now shows expected input in custom error message when used as a +Python 2 statement. Patch by Sanyam Khurana. + +.. + +.. bpo: 31499 +.. date: 2017-09-18-10-57-04 +.. nonce: BydYhf +.. section: Library + +xml.etree: Fix a crash when a parser is part of a reference cycle. + +.. + +.. bpo: 28556 +.. date: 2017-09-14-11-02-56 +.. nonce: EUOiYs +.. section: Library + +typing.get_type_hints now finds the right globalns for classes and modules +by default (when no ``globalns`` was specified by the caller). + +.. + +.. bpo: 28556 +.. date: 2017-09-13-23-27-39 +.. nonce: UmTQvv +.. section: Library + +Speed improvements to the ``typing`` module. Original PRs by Ivan +Levkivskyi and Mitar. + +.. + +.. bpo: 31544 +.. date: 2017-09-13-19-55-35 +.. nonce: beTh6t +.. section: Library + +The C accelerator module of ElementTree ignored exceptions raised when +looking up TreeBuilder target methods in XMLParser(). + +.. + +.. bpo: 31234 +.. date: 2017-09-13-18-05-56 +.. nonce: lGkcPg +.. section: Library + +socket.create_connection() now fixes manually a reference cycle: clear the +variable storing the last exception on success. + +.. + +.. bpo: 31457 +.. date: 2017-09-13-13-33-39 +.. nonce: bIVBtI +.. section: Library + +LoggerAdapter objects can now be nested. + +.. + +.. bpo: 31400 +.. date: 2017-09-08-14-19-57 +.. nonce: YOTPKi +.. section: Library + +Improves SSL error handling to avoid losing error numbers. + +.. + +.. bpo: 28958 +.. date: 2017-09-06-19-41-01 +.. nonce: x4-K5F +.. section: Library + +ssl.SSLContext() now uses OpenSSL error information when a context cannot be +instantiated. + +.. + +.. bpo: 27340 +.. date: 2017-09-06-06-50-41 +.. nonce: GgekV5 +.. section: Library + +SSLSocket.sendall() now uses memoryview to create slices of data. This fixes +support for all bytes-like object. It is also more efficient and avoids +costly copies. + +.. + +.. bpo: 31178 +.. date: 2017-09-05-14-55-28 +.. nonce: JrSFo7 +.. section: Library + +Fix string concatenation bug in rare error path in the subprocess module + +.. + +.. bpo: 31350 +.. date: 2017-09-05-10-30-48 +.. nonce: dXJ-7N +.. section: Library + +Micro-optimize :func:`asyncio._get_running_loop` to become up to 10% faster. + +.. + +.. bpo: 31170 +.. date: 2017-09-04-23-41-35 +.. nonce: QGmJ1t +.. section: Library + +expat: Update libexpat from 2.2.3 to 2.2.4. Fix copying of partial +characters for UTF-8 input (libexpat bug 115): +https://github.com/libexpat/libexpat/issues/115 + +.. + +.. bpo: 29136 +.. date: 2017-09-04-16-39-49 +.. nonce: vSn1oR +.. section: Library + +Add TLS 1.3 cipher suites and OP_NO_TLSv1_3. + +.. + +.. bpo: 29212 +.. date: 2017-09-03-14-31-00 +.. nonce: bicycl +.. section: Library + +Fix concurrent.futures.thread.ThreadPoolExecutor threads to have a non +repr() based thread name by default when no thread_name_prefix is supplied. +They will now identify themselves as "ThreadPoolExecutor-y_n". + +.. + +.. bpo: 9146 +.. date: 2017-09-03-14-10-00 +.. nonce: _-oo-_ +.. section: Library + +Fix a segmentation fault in _hashopenssl when standard hash functions such +as md5 are not available in the linked OpenSSL library. As in some special +FIPS-140 build environments. + +.. + +.. bpo: 27144 +.. date: 2017-08-30-11-26-14 +.. nonce: PEDJsE +.. section: Library + +The ``map()`` and ``as_completed()`` iterators in ``concurrent.futures`` now +avoid keeping a reference to yielded objects. + +.. + +.. bpo: 10746 +.. date: 2017-08-28-13-01-05 +.. nonce: nmAvfu +.. section: Library + +Fix ctypes producing wrong :pep:`3118` type codes for integer types. + +.. + +.. bpo: 22536 +.. date: 2017-08-23 +.. nonce: _narf_ +.. section: Library + +The subprocess module now sets the filename when FileNotFoundError is raised +on POSIX systems due to the executable or cwd not being found. + +.. + +.. bpo: 31249 +.. date: 2017-08-22-12-44-48 +.. nonce: STPbb9 +.. section: Library + +concurrent.futures: WorkItem.run() used by ThreadPoolExecutor now breaks a +reference cycle between an exception object and the WorkItem object. + +.. + +.. bpo: 31247 +.. date: 2017-08-21-17-50-27 +.. nonce: 8S3zJp +.. section: Library + +xmlrpc.server now explicitly breaks reference cycles when using +sys.exc_info() in code handling exceptions. + +.. + +.. bpo: 30102 +.. date: 2017-08-16-21-14-31 +.. nonce: 1sPqmc +.. section: Library + +The ssl and hashlib modules now call OPENSSL_add_all_algorithms_noconf() on +OpenSSL < 1.1.0. The function detects CPU features and enables optimizations +on some CPU architectures such as POWER8. Patch is based on research from +Gustavo Serra Scalet. + +.. + +.. bpo: 31185 +.. date: 2017-08-11-19-30-00 +.. nonce: i6TPgL +.. section: Library + +Fixed miscellaneous errors in asyncio speedup module. + +.. + +.. bpo: 31135 +.. date: 2017-08-08-14-44-37 +.. nonce: HH94xR +.. section: Library + +ttk: fix the destroy() method of LabeledScale and OptionMenu classes. Call +the parent destroy() method even if the used attribute doesn't exist. The +LabeledScale.destroy() method now also explicitly clears label and scale +attributes to help the garbage collector to destroy all widgets. + +.. + +.. bpo: 31107 +.. date: 2017-08-02-12-48-15 +.. nonce: 1t2hn5 +.. section: Library + +Fix `copyreg._slotnames()` mangled attribute calculation for classes whose +name begins with an underscore. Patch by Shane Harvey. + +.. + +.. bpo: 31061 +.. date: 2017-08-01-09-32-58 +.. nonce: husAYX +.. section: Library + +Fixed a crash when using asyncio and threads. + +.. + +.. bpo: 30502 +.. date: 2017-07-27-11-33-58 +.. nonce: GJlfU8 +.. section: Library + +Fix handling of long oids in ssl. Based on patch by Christian Heimes. + +.. + +.. bpo: 30119 +.. date: 2017-07-26-15-15-00 +.. nonce: DZ6C_S +.. section: Library + +ftplib.FTP.putline() now throws ValueError on commands that contains CR or +LF. Patch by Donghee Na. + +.. + +.. bpo: 30595 +.. date: 2017-07-26-04-46-12 +.. nonce: -zJ7d8 +.. section: Library + +multiprocessing.Queue.get() with a timeout now polls its reader in +non-blocking mode if it succeeded to acquire the lock but the acquire took +longer than the timeout. + +.. + +.. bpo: 29403 +.. date: 2017-07-20-02-29-49 +.. nonce: 3RinCV +.. section: Library + +Fix ``unittest.mock``'s autospec to not fail on method-bound builtin +functions. Patch by Aaron Gallagher. + +.. + +.. bpo: 30961 +.. date: 2017-07-18-23-47-51 +.. nonce: 064jz0 +.. section: Library + +Fix decrementing a borrowed reference in tracemalloc. + +.. + +.. bpo: 25684 +.. date: 2017-07-17-11-35-00 +.. nonce: usELVx +.. section: Library + +Change ``ttk.OptionMenu`` radiobuttons to be unique across instances of +``OptionMenu``. + +.. + +.. bpo: 30886 +.. date: 2017-07-10-12-14-22 +.. nonce: nqQj34 +.. section: Library + +Fix multiprocessing.Queue.join_thread(): it now waits until the thread +completes, even if the thread was started by the same process which created +the queue. + +.. + +.. bpo: 29854 +.. date: 2017-07-07-02-18-57 +.. nonce: J8wKb_ +.. section: Library + +Fix segfault in readline when using readline's history-size option. Patch +by Nir Soffer. + +.. + +.. bpo: 30319 +.. date: 2017-07-04-13-48-21 +.. nonce: hg_3TX +.. section: Library + +socket.close() now ignores ECONNRESET error. + +.. + +.. bpo: 30828 +.. date: 2017-07-04-13-10-52 +.. nonce: CLvEvV +.. section: Library + +Fix out of bounds write in `asyncio.CFuture.remove_done_callback()`. + +.. + +.. bpo: 30807 +.. date: 2017-06-29-22-04-44 +.. nonce: sLtjY- +.. section: Library + +signal.setitimer() may disable the timer when passed a tiny value. +Tiny values (such as 1e-6) are valid non-zero values for setitimer(), which +is specified as taking microsecond-resolution intervals. However, on some +platform, our conversion routine could convert 1e-6 into a zero interval, +therefore disabling the timer instead of (re-)scheduling it. + +.. + +.. bpo: 30441 +.. date: 2017-06-29-14-25-14 +.. nonce: 3Wh9kc +.. section: Library + +Fix bug when modifying os.environ while iterating over it + +.. + +.. bpo: 30532 +.. date: 2017-06-26-11-01-59 +.. nonce: qTeL1o +.. section: Library + +Fix email header value parser dropping folding white space in certain cases. + +.. + +.. bpo: 30879 +.. date: 03 +.. nonce: N3KI-o +.. section: Library + +os.listdir() and os.scandir() now emit bytes names when called with +bytes-like argument. + +.. + +.. bpo: 30746 +.. date: 02 +.. nonce: 7drQI0 +.. section: Library + +Prohibited the '=' character in environment variable names in +``os.putenv()`` and ``os.spawn*()``. + +.. + +.. bpo: 29755 +.. date: 01 +.. nonce: diQcY_ +.. section: Library + +Fixed the lgettext() family of functions in the gettext module. They now +always return bytes. + +.. + +.. bpo: 31294 +.. date: 2017-09-07-20-49-09 +.. nonce: WgI18w +.. section: Documentation + +Fix incomplete code snippet in the ZeroMQSocketListener and +ZeroMQSocketHandler examples and adapt them to Python 3. + +.. + +.. bpo: 21649 +.. date: 2017-09-06-10-11-57 +.. nonce: EUvqA9 +.. section: Documentation + +Add RFC 7525 and Mozilla server side TLS links to SSL documentation. + +.. + +.. bpo: 30803 +.. date: 2017-07-29-14-55-50 +.. nonce: 6hutqQ +.. section: Documentation + +Clarify doc on truth value testing. Original patch by Peter Thomassen. + +.. + +.. bpo: 31320 +.. date: 2017-09-05-14-23-35 +.. nonce: JRDHx7 +.. section: Tests + +Silence traceback in test_ssl + +.. + +.. bpo: 25674 +.. date: 2017-09-04-13-03-55 +.. nonce: whVTXh +.. section: Tests + +Remove sha256.tbs-internet.com ssl test + +.. + +.. bpo: 30715 +.. date: 2017-07-25-15-27-44 +.. nonce: Sp7bTF +.. section: Tests + +Address ALPN callback changes for OpenSSL 1.1.0f. The latest version behaves +like OpenSSL 1.0.2 and no longer aborts handshake. + +.. + +.. bpo: 30822 +.. date: 2017-07-20-14-29-54 +.. nonce: X0wREo +.. section: Tests + +regrtest: Exclude tzdata from regrtest --all. When running the test suite +using --use=all / -u all, exclude tzdata since it makes test_datetime too +slow (15-20 min on some buildbots) which then times out on some buildbots. +Fix also regrtest command line parser to allow passing -u extralargefile to +run test_zipfile64. + +.. + +.. bpo: 30854 +.. date: 2017-07-05-16-54-59 +.. nonce: sPADRI +.. section: Build + +Fix compile error when compiling --without-threads. Patch by Masayuki +Yamamoto. + +.. + +.. bpo: 30389 +.. date: 2017-09-06-17-14-54 +.. nonce: 9Dizrx +.. section: Windows + +Adds detection of Visual Studio 2017 to distutils on Windows. + +.. + +.. bpo: 31340 +.. date: 2017-09-04-13-19-05 +.. nonce: MbkzLi +.. section: Windows + +Change to building with MSVC v141 (included with Visual Studio 2017) + +.. + +.. bpo: 30581 +.. date: 2017-08-04-10-05-19 +.. nonce: OQhR7l +.. section: Windows + +os.cpu_count() now returns the correct number of processors on Windows when +the number of logical processors is greater than 64. + +.. + +.. bpo: 30731 +.. date: 2017-07-13-11-22-53 +.. nonce: nmMDwI +.. section: Windows + +Add a missing xmlns to python.manifest so that it matches the schema. + +.. + +.. bpo: 31493 +.. date: 2017-09-16-23-43-39 +.. nonce: nmHMCR +.. section: IDLE + +IDLE code context -- fix code update and font update timers. +Canceling timers prevents a warning message when test_idle completes. + +.. + +.. bpo: 31488 +.. date: 2017-09-16-01-21-20 +.. nonce: 0rtXIT +.. section: IDLE + +IDLE - Update non-key options in former extension classes. When applying +configdialog changes, call .reload for each feature class. Change ParenMatch +so updated options affect existing instances attached to existing editor +windows. + +.. + +.. bpo: 31477 +.. date: 2017-09-15-12-38-47 +.. nonce: n__6sa +.. section: IDLE + +IDLE - Improve rstrip entry in doc. Strip trailing whitespace strips more +than blank spaces. Multiline string literals are not skipped. + +.. + +.. bpo: 31480 +.. date: 2017-09-14-17-53-53 +.. nonce: 4WJ0pl +.. section: IDLE + +IDLE - make tests pass with zzdummy extension disabled by default. + +.. + +.. bpo: 31421 +.. date: 2017-09-12-08-38-27 +.. nonce: mYfQNq +.. section: IDLE + +Document how IDLE runs tkinter programs. IDLE calls tcl/tk update in the +background in order to make live +interaction and experimentation with tkinter applications much easier. + +.. + +.. bpo: 31414 +.. date: 2017-09-11-15-46-05 +.. nonce: wiepgK +.. section: IDLE + +IDLE -- fix tk entry box tests by deleting first. Adding to an int entry is +not the same as deleting and inserting because int('') will fail. + +.. + +.. bpo: 31051 +.. date: 2017-08-30-00-06-58 +.. nonce: 50Jp_Q +.. section: IDLE + +Rearrange IDLE configdialog GenPage into Window, Editor, and Help sections. + +.. + +.. bpo: 30617 +.. date: 2017-08-27-16-49-36 +.. nonce: UHnswr +.. section: IDLE + +IDLE - Add docstrings and tests for outwin subclass of editor. +Move some data and functions from the class to module level. Patch by Cheryl +Sabella. + +.. + +.. bpo: 31287 +.. date: 2017-08-27-15-31-33 +.. nonce: aZERfI +.. section: IDLE + +IDLE - Do not modify tkinter.message in test_configdialog. + +.. + +.. bpo: 27099 +.. date: 2017-08-24-13-48-16 +.. nonce: rENefC +.. section: IDLE + +Convert IDLE's built-in 'extensions' to regular features. +About 10 IDLE features were implemented as supposedly optional extensions. +Their different behavior could be confusing or worse for users and not good +for maintenance. Hence the conversion. +The main difference for users is that user configurable key bindings for +builtin features are now handled uniformly. Now, editing a binding in a +keyset only affects its value in the keyset. All bindings are defined +together in the system-specific default keysets in config-extensions.def. +All custom keysets are saved as a whole in config-extension.cfg. All take +effect as soon as one clicks Apply or Ok. +The affected events are '<<force-open-completions>>', '<<expand-word>>', +'<<force-open-calltip>>', '<<flash-paren>>', '<<format-paragraph>>', +'<<run-module>>', '<<check-module>>', and '<<zoom-height>>'. Any (global) +customizations made before 3.6.3 will not affect their keyset-specific +customization after 3.6.3. and vice versa. +Initial patch by Charles Wohlganger. + +.. + +.. bpo: 31206 +.. date: 2017-08-18-14-13-42 +.. nonce: F1-tKK +.. section: IDLE + +IDLE: Factor HighPage(Frame) class from ConfigDialog. Patch by Cheryl +Sabella. + +.. + +.. bpo: 31001 +.. date: 2017-08-17-15-00-20 +.. nonce: KLxYHC +.. section: IDLE + +Add tests for configdialog highlight tab. Patch by Cheryl Sabella. + +.. + +.. bpo: 31205 +.. date: 2017-08-15-12-58-23 +.. nonce: iuziZ5 +.. section: IDLE + +IDLE: Factor KeysPage(Frame) class from ConfigDialog. The slightly modified +tests continue to pass. Patch by Cheryl Sabella. + +.. + +.. bpo: 31130 +.. date: 2017-08-07-14-02-56 +.. nonce: FbsC7f +.. section: IDLE + +IDLE -- stop leaks in test_configdialog. Initial patch by Victor Stinner. + +.. + +.. bpo: 31002 +.. date: 2017-08-03-17-54-02 +.. nonce: kUSgTE +.. section: IDLE + +Add tests for configdialog keys tab. Patch by Cheryl Sabella. + +.. + +.. bpo: 19903 +.. date: 2017-08-03-14-08-42 +.. nonce: sqE1FS +.. section: IDLE + +IDLE: Calltips use `inspect.signature` instead of `inspect.getfullargspec`. +This improves calltips for builtins converted to use Argument Clinic. Patch +by Louie Lu. + +.. + +.. bpo: 31083 +.. date: 2017-07-31-23-20-51 +.. nonce: 991FXm +.. section: IDLE + +IDLE - Add an outline of a TabPage class in configdialog. Update existing +classes to match outline. Initial patch by Cheryl Sabella. + +.. + +.. bpo: 31050 +.. date: 2017-07-30-17-39-59 +.. nonce: AXR3kP +.. section: IDLE + +Factor GenPage(Frame) class from ConfigDialog. The slightly modified tests +continue to pass. Patch by Cheryl Sabella. + +.. + +.. bpo: 31004 +.. date: 2017-07-30-01-00-58 +.. nonce: m8cc1t +.. section: IDLE + +IDLE - Factor FontPage(Frame) class from ConfigDialog. +Slightly modified tests continue to pass. Fix General tests. Patch mostly by +Cheryl Sabella. + +.. + +.. bpo: 30781 +.. date: 2017-07-28-18-59-06 +.. nonce: ud5m18 +.. section: IDLE + +IDLE - Use ttk widgets in ConfigDialog. Patches by Terry Jan Reedy and +Cheryl Sabella. + +.. + +.. bpo: 31060 +.. date: 2017-07-27-14-48-42 +.. nonce: GdY_VY +.. section: IDLE + +IDLE - Finish rearranging methods of ConfigDialog Grouping methods +pertaining to each tab and the buttons will aid writing tests and improving +the tabs and will enable splitting the groups into classes. + +.. + +.. bpo: 30853 +.. date: 2017-07-27-10-01-14 +.. nonce: enPvvc +.. section: IDLE + +IDLE -- Factor a VarTrace class out of ConfigDialog. +Instance tracers manages pairs consisting of a tk variable and a callback +function. When tracing is turned on, setting the variable calls the +function. Test coverage for the new class is 100%. + +.. + +.. bpo: 31003 +.. date: 2017-07-25-01-28-35 +.. nonce: bYINVH +.. section: IDLE + +IDLE: Add more tests for General tab. + +.. + +.. bpo: 30993 +.. date: 2017-07-22-18-08-41 +.. nonce: 34vJkB +.. section: IDLE + +IDLE - Improve configdialog font page and tests. +In configdialog: Document causal pathways in create_font_tab docstring. +Simplify some attribute names. Move set_samples calls to var_changed_font +(idea from Cheryl Sabella). Move related functions to positions after the +create widgets function. +In test_configdialog: Fix test_font_set so not order dependent. Fix renamed +test_indent_scale so it tests the widget. Adjust tests for movement of +set_samples call. Add tests for load functions. Put all font tests in one +class and tab indent tests in another. Except for two lines, these tests +completely cover the related functions. + +.. + +.. bpo: 30981 +.. date: 2017-07-21-01-55-14 +.. nonce: ZFvQPt +.. section: IDLE + +IDLE -- Add more configdialog font page tests. + +.. + +.. bpo: 28523 +.. date: 2017-07-21-00-54-52 +.. nonce: OPcqYJ +.. section: IDLE + +IDLE: replace 'colour' with 'color' in configdialog. + +.. + +.. bpo: 30917 +.. date: 2017-07-17-23-35-57 +.. nonce: hSiuuO +.. section: IDLE + +Add tests for idlelib.config.IdleConf. Increase coverage from 46% to 96%. +Patch by Louie Lu. + +.. + +.. bpo: 30934 +.. date: 2017-07-15-22-26-57 +.. nonce: BanuSB +.. section: IDLE + +Document coverage details for idlelib tests. +Add section to idlelib/idle-test/README.txt. +Include check that branches are taken both ways. +Exclude IDLE-specific code that does not run during unit tests. + +.. + +.. bpo: 30913 +.. date: 2017-07-13-23-07-33 +.. nonce: aezn_e +.. section: IDLE + +IDLE: Document ConfigDialog tk Vars, methods, and widgets in docstrings This +will facilitate improving the dialog and splitting up the class. Original +patch by Cheryl Sabella. + +.. + +.. bpo: 30899 +.. date: 2017-07-11-02-26-17 +.. nonce: SQmVO8 +.. section: IDLE + +IDLE: Add tests for ConfigParser subclasses in config. Patch by Louie Lu. + +.. + +.. bpo: 30881 +.. date: 2017-07-11-02-21-42 +.. nonce: 4KAq_9 +.. section: IDLE + +IDLE: Add docstrings to browser.py. Patch by Cheryl Sabella. + +.. + +.. bpo: 30851 +.. date: 2017-07-09-23-53-00 +.. nonce: AHXBYa +.. section: IDLE + +IDLE: Remove unused variables in configdialog. One is a duplicate, one is +set but cannot be altered by users. Patch by Cheryl Sabella. + +.. + +.. bpo: 30870 +.. date: 2017-07-08-17-57-04 +.. nonce: IcR2pf +.. section: IDLE + +IDLE: In Settings dialog, select font with Up, Down keys as well as mouse. +Initial patch by Louie Lu. + +.. + +.. bpo: 8231 +.. date: 2017-07-07-21-10-55 +.. nonce: yEge3L +.. section: IDLE + +IDLE: call config.IdleConf.GetUserCfgDir only once. + +.. + +.. bpo: 30779 +.. date: 2017-07-07-20-26-37 +.. nonce: 8KXEXN +.. section: IDLE + +IDLE: Factor ConfigChanges class from configdialog, put in config; test. * +In config, put dump test code in a function; run it and unittest in 'if +__name__ == '__main__'. * Add class config.ConfigChanges based on +changes_class_v4.py on bpo issue. * Add class test_config.ChangesTest, +partly using configdialog_tests_v1.py. * Revise configdialog to use +ConfigChanges; see tracker msg297804. * Revise test_configdialog to match +configdialog changes. * Remove configdialog functions unused or moved to +ConfigChanges. Cheryl Sabella contributed parts of the patch. + +.. + +.. bpo: 30777 +.. date: 2017-07-04-22-45-46 +.. nonce: uxzlMB +.. section: IDLE + +IDLE: configdialog - Add docstrings and fix comments. Patch by Cheryl +Sabella. + +.. + +.. bpo: 30495 +.. date: 2017-06-29-18-23-06 +.. nonce: qIWgc4 +.. section: IDLE + +IDLE: Improve textview with docstrings, PEP8 names, and more tests. Patch by +Cheryl Sabella. + +.. + +.. bpo: 30723 +.. date: 2017-06-27-19-05-40 +.. nonce: rQh06y +.. section: IDLE + +IDLE: Make several improvements to parenmatch. Add 'parens' style to +highlight both opener and closer. Make 'default' style, which is not +default, a synonym for 'opener'. Make time-delay work the same with all +styles. Add help for config dialog extensions tab, including help for +parenmatch. Add new tests. Original patch by Charles Wohlganger. + +.. + +.. bpo: 30674 +.. date: 2017-06-27-01-40-34 +.. nonce: ppK_q8 +.. section: IDLE + +IDLE: add docstrings to grep module. Patch by Cheryl Sabella + +.. + +.. bpo: 21519 +.. date: 2017-06-27-00-29-56 +.. nonce: fTj9T0 +.. section: IDLE + +IDLE's basic custom key entry dialog now detects duplicates properly. +Original patch by Saimadhav Heblikar. + +.. + +.. bpo: 29910 +.. date: 2017-06-26-22-45-27 +.. nonce: mqHh7u +.. section: IDLE + +IDLE no longer deletes a character after commenting out a region by a key +shortcut. Add ``return 'break'`` for this and other potential conflicts +between IDLE and default key bindings. + +.. + +.. bpo: 30728 +.. date: 2017-06-26-15-47-13 +.. nonce: qH4TGL +.. section: IDLE + +Review and change idlelib.configdialog names. Lowercase method and attribute +names. Replace 'colour' with 'color', expand overly cryptic names, delete +unneeded underscores. Replace ``import *`` with specific imports. Patches by +Cheryl Sabella. + +.. + +.. bpo: 6739 +.. date: 2017-06-26-00-28-59 +.. nonce: x5MfhB +.. section: IDLE + +IDLE: Verify user-entered key sequences by trying to bind them with tk. Add +tests for all 3 validation functions. Original patch by G Polo. Tests added +by Cheryl Sabella. + +.. + +.. bpo: 30983 +.. date: 2017-08-18-17-19-23 +.. nonce: ggGz9z +.. section: Tools/Demos + +gdb integration commands (py-bt, etc.) work on optimized shared builds now, +too. :pep:`523` introduced _PyEval_EvalFrameDefault which inlines +PyEval_EvalFrameEx on non-debug shared builds. This broke the ability to +use py-bt, py-up, and a few other Python-specific gdb integrations. The +problem is fixed by only looking for _PyEval_EvalFrameDefault frames in +python-gdb.py. Original patch by Bruno "Polaco" Penteado. diff --git a/Misc/NEWS.d/3.6.4.rst b/Misc/NEWS.d/3.6.4.rst new file mode 100644 index 00000000..cf231010 --- /dev/null +++ b/Misc/NEWS.d/3.6.4.rst @@ -0,0 +1,8 @@ +.. bpo: 0 +.. date: 2017-12-18 +.. no changes: True +.. nonce: qH8KPG +.. release date: 2017-12-18 +.. section: Library + +There were no new code changes in version 3.6.4 since v3.6.4rc1. diff --git a/Misc/NEWS.d/3.6.4rc1.rst b/Misc/NEWS.d/3.6.4rc1.rst new file mode 100644 index 00000000..dc9ab7ad --- /dev/null +++ b/Misc/NEWS.d/3.6.4rc1.rst @@ -0,0 +1,1129 @@ +.. bpo: 32176 +.. date: 2017-12-02-21-37-22 +.. nonce: Wt25-N +.. release date: 2017-12-05 +.. section: Core and Builtins + +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 +.. date: 2017-11-05-16-11-07 +.. nonce: 2yNC_z +.. section: Core and Builtins + +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 +.. date: 2017-10-28-22-06-03 +.. nonce: lhC3HE +.. section: Core and Builtins + +Fix the interactive interpreter looping endlessly when no memory. + +.. + +.. bpo: 20047 +.. date: 2017-10-28-19-11-05 +.. nonce: GuNAto +.. section: Core and Builtins + +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 +.. date: 2017-10-27-19-18-44 +.. nonce: P_4cVr +.. section: Core and Builtins + +Fix a segmentation fault caused by a combination of the async soft keyword +and continuation lines. + +.. + +.. bpo: 21720 +.. date: 2017-10-25-15-51-37 +.. nonce: BwIKLP +.. section: Core and Builtins + +BytesWarning no longer emitted when the *fromlist* argument of +``__import__()`` or the ``__all__`` attribute of the module contain bytes +instances. + +.. + +.. bpo: 31825 +.. date: 2017-10-20-14-07-46 +.. nonce: gJvmGW +.. section: Core and Builtins + +Fixed OverflowError in the 'unicode-escape' codec and in +codecs.escape_decode() when decode an escaped non-ascii byte. + +.. + +.. bpo: 28603 +.. date: 2017-10-17-13-29-19 +.. nonce: _-oia3 +.. section: Core and Builtins + +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 +.. date: 2017-10-15-23-44-57 +.. nonce: XwdEP4 +.. section: Core and Builtins + +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 +.. date: 2017-10-08-10-00-55 +.. nonce: 1IKqgs +.. section: Core and Builtins + +Restored blocking "from package import module" by setting +sys.modules["package.module"] to None. + +.. + +.. bpo: 31626 +.. date: 2017-10-01-15-48-03 +.. nonce: reLPxY +.. section: Core and Builtins + +Fixed a bug in debug memory allocator. There was a write to freed memory +after shrinking a memory block. + +.. + +.. bpo: 31619 +.. date: 2017-09-29-20-32-24 +.. nonce: 6gQ1kv +.. section: Core and Builtins + +Fixed a ValueError when convert a string with large number of underscores to +integer with binary base. + +.. + +.. bpo: 31592 +.. date: 2017-09-26-16-05-04 +.. nonce: IFBZj9 +.. section: Core and Builtins + +Fixed an assertion failure in Python parser in case of a bad +`unicodedata.normalize()`. Patch by Oren Milman. + +.. + +.. bpo: 31588 +.. date: 2017-09-26-13-03-16 +.. nonce: wT9Iy7 +.. section: Core and Builtins + +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 +.. date: 2017-09-24-09-57-04 +.. nonce: OxwINs +.. section: Core and Builtins + +Fix an assertion failure in `_warnings.warn()` in case of a bad ``__name__`` +global. Patch by Oren Milman. + +.. + +.. bpo: 31505 +.. date: 2017-09-18-12-07-39 +.. nonce: VomaFa +.. section: Core and Builtins + +Fix an assertion failure in `json`, in case `_json.make_encoder()` received +a bad `encoder()` argument. Patch by Oren Milman. + +.. + +.. bpo: 31492 +.. date: 2017-09-16-22-49-16 +.. nonce: RtyteL +.. section: Core and Builtins + +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 +.. date: 2017-09-16-13-32-35 +.. nonce: r7m2sj +.. section: Core and Builtins + +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 +.. date: 2017-09-15-09-13-07 +.. nonce: o06iKD +.. section: Core and Builtins + +Fix an assertion failure in `_random.Random.seed()` in case the argument has +a bad ``__abs__()`` method. Patch by Oren Milman. + +.. + +.. bpo: 31315 +.. date: 2017-09-01-00-40-58 +.. nonce: ZX20bl +.. section: Core and Builtins + +Fix an assertion failure in imp.create_dynamic(), when spec.name is not a +string. Patch by Oren Milman. + +.. + +.. bpo: 31311 +.. date: 2017-08-31-17-52-56 +.. nonce: bNE2l- +.. section: Core and Builtins + +Fix a crash in the ``__setstate__()`` method of `ctypes._CData`, in case of +a bad ``__dict__``. Patch by Oren Milman. + +.. + +.. bpo: 31293 +.. date: 2017-08-28-17-51-42 +.. nonce: eMYZXj +.. section: Core and Builtins + +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 +.. date: 2017-08-27-21-18-30 +.. nonce: 7lzaKV +.. section: Core and Builtins + +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 +.. date: 2017-07-01-15-11-13 +.. nonce: j7ZvN_ +.. section: Core and Builtins + +`PyErr_PrintEx()` clears now the ignored exception that may be raised by +`_PySys_SetObjectId()`, for example when no memory. + +.. + +.. bpo: 28556 +.. date: 2017-12-05-02-03-07 +.. nonce: 9Z_PsJ +.. section: Library + +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 +.. date: 2017-12-02-16-06-00 +.. nonce: Kji34M +.. section: Library + +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 +.. date: 2017-11-30-20-38-16 +.. nonce: O42bVe +.. section: Library + +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 +.. date: 2017-11-24-14-07-55 +.. nonce: Nj3A0x +.. section: Library + +Make :meth:`msilib.SummaryInformation.GetProperty` return ``None`` when the +value of property is ``VT_EMPTY``. Initial patch by Mark Mc Mahon. + +.. + +.. bpo: 31325 +.. date: 2017-11-23-22-12-11 +.. nonce: 8jAUxN +.. section: Library + +Fix wrong usage of :func:`collections.namedtuple` in the +:meth:`RobotFileParser.parse() <urllib.robotparser.RobotFileParser.parse>` +method. +Initial patch by Robin Wellner. + +.. + +.. bpo: 12382 +.. date: 2017-11-23-21-47-36 +.. nonce: xWT9k0 +.. section: Library + +: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 +.. date: 2017-11-22-09-44-15 +.. nonce: VJa9bo +.. section: Library + +``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 +.. date: 2017-11-18-21-13-52 +.. nonce: nwDV8L +.. section: Library + +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 +.. date: 2017-11-15-13-44-28 +.. nonce: uHAOmu +.. section: Library + +Make asyncio.IncompleteReadError and LimitOverrunError pickleable. + +.. + +.. bpo: 32015 +.. date: 2017-11-13-17-48-33 +.. nonce: 4nqRTD +.. section: Library + +Fixed the looping of asyncio in the case of reconnection the socket during +waiting async read/write from/to the socket. + +.. + +.. bpo: 32011 +.. date: 2017-11-12-20-47-59 +.. nonce: NzVDdZ +.. section: Library + +Restored support of loading marshal files with the TYPE_INT64 code. These +files can be produced in Python 2.7. + +.. + +.. bpo: 31970 +.. date: 2017-11-07-14-20-09 +.. nonce: x4EN_9 +.. section: Library + +Reduce performance overhead of asyncio debug mode. + +.. + +.. bpo: 9678 +.. date: 2017-11-03-22-05-47 +.. nonce: oD51q6 +.. section: Library + +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 +.. date: 2017-11-03-19-11-43 +.. nonce: NCaijI +.. section: Library + +Fix potential missed signal in signal.signal(). + +.. + +.. bpo: 31933 +.. date: 2017-11-03-08-36-03 +.. nonce: UrtoMP +.. section: Library + +Fix Blake2 params leaf_size and node_offset on big endian platforms. Patch +by Jack O'Connor. + +.. + +.. bpo: 31927 +.. date: 2017-11-02-18-26-40 +.. nonce: 40K6kp +.. section: Library + +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 +.. date: 2017-11-01-18-13-42 +.. nonce: j2zRnF +.. section: Library + +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 +.. date: 2017-10-30-11-04-56 +.. nonce: yjwdEb +.. section: Library + +plistlib now catches more errors when read binary plists and raises +InvalidFileException instead of unexpected exceptions. + +.. + +.. bpo: 25720 +.. date: 2017-10-29-17-52-40 +.. nonce: vSvb5h +.. section: Library + +Fix the method for checking pad state of curses WINDOW. Patch by Masayuki +Yamamoto. + +.. + +.. bpo: 31893 +.. date: 2017-10-29-13-51-01 +.. nonce: 8LZKEz +.. section: Library + +Fixed the layout of the kqueue_event structure on OpenBSD and NetBSD. Fixed +the comparison of the kqueue_event objects. + +.. + +.. bpo: 31891 +.. date: 2017-10-29-11-23-24 +.. nonce: 9kAPha +.. section: Library + +Fixed building the curses module on NetBSD. + +.. + +.. bpo: 28416 +.. date: 2017-10-23-12-05-33 +.. nonce: Ldnw8X +.. section: Library + +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 +.. date: 2017-10-22-11-06-02 +.. nonce: rxh7L4 +.. section: Library + +Fix multiprocessing.Process when stdout and/or stderr is closed or None. + +.. + +.. bpo: 31457 +.. date: 2017-10-18-19-05-17 +.. nonce: KlE6r8 +.. section: Library + +If nested log adapters are used, the inner ``process()`` methods are no +longer omitted. + +.. + +.. bpo: 31457 +.. date: 2017-10-18-16-48-09 +.. nonce: _ovmzp +.. section: Library + +The ``manager`` property on LoggerAdapter objects is now properly settable. + +.. + +.. bpo: 31806 +.. date: 2017-10-17-23-27-03 +.. nonce: TzphdL +.. section: Library + +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 +.. date: 2017-10-17-12-29-18 +.. nonce: tGuX2C +.. section: Library + +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 +.. date: 2017-10-12-19-00-53 +.. nonce: cENtry +.. section: Library + +Fixed buffer overflow in select.kqueue.control(). + +.. + +.. bpo: 31770 +.. date: 2017-10-12-18-45-38 +.. nonce: GV3MPx +.. section: Library + +Prevent a crash when calling the ``__init__()`` method of a +``sqlite3.Cursor`` object more than once. Patch by Oren Milman. + +.. + +.. bpo: 31672 +.. date: 2017-10-12-02-47-16 +.. nonce: DaOkVd +.. section: Library + +``idpattern`` in ``string.Template`` matched some non-ASCII characters. Now +it uses ``-i`` regular expression local flag to avoid non-ASCII characters. + +.. + +.. bpo: 31764 +.. date: 2017-10-11-22-18-04 +.. nonce: EMyIkK +.. section: Library + +Prevent a crash in ``sqlite3.Cursor.close()`` in case the ``Cursor`` object +is uninitialized. Patch by Oren Milman. + +.. + +.. bpo: 31752 +.. date: 2017-10-11-00-45-01 +.. nonce: DhWevN +.. section: Library + +Fix possible crash in timedelta constructor called with custom integers. + +.. + +.. bpo: 31701 +.. date: 2017-10-09-17-42-30 +.. nonce: NRrVel +.. section: Library + +On Windows, faulthandler.enable() now ignores MSC and COM exceptions. + +.. + +.. bpo: 31728 +.. date: 2017-10-08-23-28-30 +.. nonce: XrVMME +.. section: Library + +Prevent crashes in `_elementtree` due to unsafe cleanup of `Element.text` +and `Element.tail`. Patch by Oren Milman. + +.. + +.. bpo: 31620 +.. date: 2017-10-06-04-35-31 +.. nonce: gksLA1 +.. section: Library + +an empty asyncio.Queue now doesn't leak memory when queue.get pollers +timeout + +.. + +.. bpo: 31632 +.. date: 2017-10-04-11-37-14 +.. nonce: LiOC3C +.. section: Library + +Fix method set_protocol() of class _SSLProtocolTransport in asyncio module. +This method was previously modifying a wrong reference to the protocol. + +.. + +.. bpo: 31675 +.. date: 2017-10-03-15-06-24 +.. nonce: Nh7jJ3 +.. section: Library + +Fixed memory leaks in Tkinter's methods splitlist() and split() when pass a +string larger than 2 GiB. + +.. + +.. bpo: 31673 +.. date: 2017-10-03-14-37-46 +.. nonce: RFCrka +.. section: Library + +Fixed typo in the name of Tkinter's method adderrorinfo(). + +.. + +.. bpo: 30806 +.. date: 2017-09-29 +.. nonce: lP5GrH +.. section: Library + +Fix the string representation of a netrc object. + +.. + +.. bpo: 15037 +.. date: 2017-09-29-19-19-36 +.. nonce: ykimLK +.. section: Library + +Added a workaround for getkey() in curses for ncurses 5.7 and earlier. + +.. + +.. bpo: 25351 +.. date: 2017-09-28-23-10-51 +.. nonce: 2JmFpF +.. section: Library + +Avoid venv activate failures with undefined variables + +.. + +.. bpo: 25532 +.. date: 2017-09-27-08-11-38 +.. nonce: ey4Yez +.. section: Library + +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 +.. date: 2017-09-25-14-04-30 +.. nonce: B4--_D +.. section: Library + +Stop crashes when concurrently iterate over itertools.groupby() iterators. + +.. + +.. bpo: 31516 +.. date: 2017-09-20-18-43-01 +.. nonce: 23Yuq3 +.. section: Library + +``threading.current_thread()`` should not return a dummy thread at shutdown. + +.. + +.. bpo: 31351 +.. date: 2017-09-17-15-24-25 +.. nonce: yQdKv- +.. section: Library + +python -m ensurepip now exits with non-zero exit code if pip bootstrapping +has failed. + +.. + +.. bpo: 31482 +.. date: 2017-09-16-01-53-11 +.. nonce: 39s5dS +.. section: Library + +``random.seed()`` now works with bytes in version=1 + +.. + +.. bpo: 31334 +.. date: 2017-09-04-00-22-31 +.. nonce: 9WYRfi +.. section: Library + +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 +.. date: 2017-08-30-18-23-54 +.. nonce: 7D1UNt +.. section: Library + +multiprocessing's semaphore tracker should be launched again if crashed. + +.. + +.. bpo: 31308 +.. date: 2017-08-30-17-59-36 +.. nonce: KbexyC +.. section: Library + +Make multiprocessing's forkserver process immune to Ctrl-C and other user +interruptions. If it crashes, restart it when necessary. + +.. + +.. bpo: 32105 +.. date: 2017-11-21-10-54-16 +.. nonce: 91mhWm +.. section: Documentation + +Added asyncio.BaseEventLoop.connect_accepted_socket versionadded marker. + +.. + +.. bpo: 31537 +.. date: 2017-10-08-23-02-14 +.. nonce: SiFNM8 +.. section: Documentation + +Fix incorrect usage of ``get_history_length`` in readline documentation +example code. Patch by Brad Smith. + +.. + +.. bpo: 30085 +.. date: 2017-09-14-18-44-50 +.. nonce: 0J9w-u +.. section: Documentation + +The operator functions without double underscores are preferred for clarity. +The one with underscores are only kept for back-compatibility. + +.. + +.. bpo: 31380 +.. date: 2017-12-04-23-19-16 +.. nonce: VlMmHW +.. section: Tests + +Skip test_httpservers test_undecodable_file on macOS: fails on APFS. + +.. + +.. bpo: 31705 +.. date: 2017-11-30-12-27-10 +.. nonce: yULW7O +.. section: Tests + +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 +.. date: 2017-10-24-11-36-10 +.. nonce: xCvXcr +.. section: Tests + +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 +.. date: 2017-06-30-11-20-20 +.. nonce: lo7FQX +.. section: Tests + +Add the `set_nomemory(start, stop)` and `remove_mem_hooks()` functions to +the _testcapi module. + +.. + +.. bpo: 32059 +.. date: 2017-11-18-11-19-28 +.. nonce: a0Hxgp +.. section: Build + +``detect_modules()`` in ``setup.py`` now also searches the sysroot paths +when cross-compiling. + +.. + +.. bpo: 31957 +.. date: 2017-11-06-11-53-39 +.. nonce: S_1jFK +.. section: Build + +Fixes Windows SDK version detection when building for Windows. + +.. + +.. bpo: 31609 +.. date: 2017-11-04-15-35-08 +.. nonce: k7_nBR +.. section: Build + +Fixes quotes in PCbuild/clean.bat + +.. + +.. bpo: 31934 +.. date: 2017-11-03-15-17-50 +.. nonce: 8bUlpv +.. section: Build + +Abort the build when building out of a not clean source tree. + +.. + +.. bpo: 31926 +.. date: 2017-11-03-10-07-14 +.. nonce: 57wE98 +.. section: Build + +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 +.. date: 2017-11-02-20-30-57 +.. nonce: VaE3o8 +.. section: Build + +Update Windows builds to use SQLite 3.21.0. + +.. + +.. bpo: 28791 +.. date: 2017-11-02-20-13-46 +.. nonce: STt3jL +.. section: Build + +Update OS X installer to use SQLite 3.21.0. + +.. + +.. bpo: 22140 +.. date: 2017-09-26-22-39-58 +.. nonce: ZRf7Wn +.. section: Build + +Prevent double substitution of prefix in python-config.sh. + +.. + +.. bpo: 31536 +.. date: 2017-09-20-21-32-21 +.. nonce: KUDjno +.. section: Build + +Avoid wholesale rebuild after `make regen-all` if nothing changed. + +.. + +.. bpo: 1102 +.. date: 2017-11-19-09-46-27 +.. nonce: NY-g1F +.. section: Windows + +Return ``None`` when ``View.Fetch()`` returns ``ERROR_NO_MORE_ITEMS`` +instead of raising ``MSIError``. +Initial patch by Anthony Tuininga. + +.. + +.. bpo: 31944 +.. date: 2017-11-04-15-29-47 +.. nonce: 0Bx8tZ +.. section: Windows + +Fixes Modify button in Apps and Features dialog. + +.. + +.. bpo: 31392 +.. date: 2017-12-04-21-57-43 +.. nonce: f8huBC +.. section: macOS + +Update macOS installer to use OpenSSL 1.0.2m + +.. + +.. bpo: 32207 +.. date: 2017-12-04-15-04-43 +.. nonce: IzyAJo +.. section: IDLE + +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 +.. date: 2017-11-28-21-47-15 +.. nonce: 2T2Na8 +.. section: IDLE + +Delete unused file idlelib/tabbedpages.py. Use of TabbedPageSet in +configdialog was replaced by ttk.Notebook. + +.. + +.. bpo: 32100 +.. date: 2017-11-21-08-26-08 +.. nonce: P43qx2 +.. section: IDLE + +IDLE: Fix old and new bugs in pathbrowser; improve tests. Patch mostly by +Cheryl Sabella. + +.. + +.. bpo: 31858 +.. date: 2017-10-26-20-20-19 +.. nonce: VuSA_e +.. section: IDLE + +IDLE -- Restrict shell prompt manipulation 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 +.. date: 2017-10-24-16-21-50 +.. nonce: gECuWx +.. section: IDLE + +The font sample in the IDLE configuration dialog is now editable. Changes +persist while IDLE remains open + +.. + +.. bpo: 31836 +.. date: 2017-10-21-15-41-53 +.. nonce: fheLME +.. section: IDLE + +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 +.. date: 2017-10-17-13-26-13 +.. nonce: TMEQfp +.. section: IDLE + +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 +.. date: 2017-10-12-00-51-29 +.. nonce: VwjZRD +.. section: IDLE + +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 +.. date: 2017-09-30-19-03-26 +.. nonce: HpveI6 +.. section: IDLE + +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 +.. date: 2017-09-30-13-59-18 +.. nonce: LxN4Vb +.. section: IDLE + +IDLE - Make _htest, _utest parameters keyword only. + +.. + +.. bpo: 31559 +.. date: 2017-09-23-12-52-24 +.. nonce: ydckYX +.. section: IDLE + +Remove test order dependence in idle_test.test_browser. + +.. + +.. bpo: 31459 +.. date: 2017-09-22-20-26-23 +.. nonce: L0pnH9 +.. section: IDLE + +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 +.. date: 2017-09-18-10-43-03 +.. nonce: Y_YDxA +.. section: IDLE + +Default fonts now are scaled on HiDPI displays. + +.. + +.. bpo: 1612262 +.. date: 2017-08-14-15-13-50 +.. nonce: -x_Oyq +.. section: IDLE + +IDLE module browser now shows nested classes and functions. Original patches +for code and tests by Guilherme Polo and Cheryl Sabella, respectively. + +.. + +.. bpo: 30722 +.. date: 2017-10-23-19-45-52 +.. nonce: ioRlAu +.. section: Tools/Demos + +Make redemo work with Python 3.6 and newer versions. +Also, remove the ``LOCALE`` option since it doesn't work with string +patterns in Python 3. +Patch by Christoph Sarnowski. + +.. + +.. bpo: 20891 +.. date: 2017-11-30-18-13-45 +.. nonce: wBnMdF +.. section: C API + +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 +.. date: 2017-09-20-21-59-52 +.. nonce: s9Cw9_ +.. section: C API + +Fix memory corruption due to allocator mix in getpath.c between Py_GetPath() +and Py_SetPath() + +.. + +.. bpo: 30697 +.. date: 2017-06-30-11-58-01 +.. nonce: Q3T_8n +.. section: C API + +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. diff --git a/Misc/NEWS.d/3.6.5.rst b/Misc/NEWS.d/3.6.5.rst new file mode 100644 index 00000000..ded13aeb --- /dev/null +++ b/Misc/NEWS.d/3.6.5.rst @@ -0,0 +1,16 @@ +.. bpo: 32872 +.. date: 2018-03-28-01-35-02 +.. nonce: J5NDUj +.. release date: 2018-03-28 +.. section: Tests + +Avoid regrtest compatibility issue with namespace packages. + +.. + +.. bpo: 33163 +.. date: 2018-03-28-04-15-03 +.. nonce: hfpWuU +.. section: Build + +Upgrade pip to 9.0.3 and setuptools to v39.0.1. diff --git a/Misc/NEWS.d/3.6.5rc1.rst b/Misc/NEWS.d/3.6.5rc1.rst new file mode 100644 index 00000000..448baed5 --- /dev/null +++ b/Misc/NEWS.d/3.6.5rc1.rst @@ -0,0 +1,866 @@ +.. bpo: 33001 +.. date: 2018-03-05-10-09-51 +.. nonce: elj4Aa +.. release date: 2018-03-13 +.. section: Security + +Minimal fix to prevent buffer overrun in os.symlink on Windows + +.. + +.. bpo: 32981 +.. date: 2018-03-02-10-24-52 +.. nonce: O_qDyj +.. section: Security + +Regexes in difflib and poplib were vulnerable to catastrophic backtracking. +These regexes formed potential DOS vectors (REDOS). They have been +refactored. This resolves CVE-2018-1060 and CVE-2018-1061. Patch by Jamie +Davis. + +.. + +.. bpo: 33026 +.. date: 2018-03-08-09-48-38 +.. nonce: QZA3Ba +.. section: Core and Builtins + +Fixed jumping out of "with" block by setting f_lineno. + +.. + +.. bpo: 17288 +.. date: 2018-02-27-13-36-21 +.. nonce: Gdj24S +.. section: Core and Builtins + +Prevent jumps from 'return' and 'exception' trace events. + +.. + +.. bpo: 32889 +.. date: 2018-02-20-21-53-48 +.. nonce: J6eWy5 +.. section: Core and Builtins + +Update Valgrind suppression list to account for the rename of +``Py_ADDRESS_IN_RANG`` to ``address_in_range``. + +.. + +.. bpo: 32650 +.. date: 2018-01-28-23-01-39 +.. nonce: Bbi7ek +.. section: Core and Builtins + +Pdb and other debuggers dependent on bdb.py will correctly step over (next +command) native coroutines. Patch by Pablo Galindo. + +.. + +.. bpo: 32685 +.. date: 2018-01-28-12-25-06 +.. nonce: nGctze +.. section: Core and Builtins + +Improve suggestion when the Python 2 form of print statement is either +present on the same line as the header of a compound statement or else +terminated by a semi-colon instead of a newline. Patch by Nitish Chandra. + +.. + +.. bpo: 32583 +.. date: 2018-01-26-21-20-21 +.. nonce: Fh3fau +.. section: Core and Builtins + +Fix possible crashing in builtin Unicode decoders caused by write +out-of-bound errors when using customized decode error handlers. + +.. + +.. bpo: 26163 +.. date: 2018-01-14-20-32-47 +.. nonce: xv9Iuv +.. section: Core and Builtins + +Improved frozenset() hash to create more distinct hash values when faced +with datasets containing many similar values. + +.. + +.. bpo: 27169 +.. date: 2017-12-15-11-50-06 +.. nonce: VO84fQ +.. section: Core and Builtins + +The ``__debug__`` constant is now optimized out at compile time. This fixes +also bpo-22091. + +.. + +.. bpo: 32329 +.. date: 2017-12-15-00-55-35 +.. nonce: XL1O99 +.. section: Core and Builtins + +``sys.flags.hash_randomization`` is now properly set to 0 when hash +randomization is turned off by ``PYTHONHASHSEED=0``. + +.. + +.. bpo: 30416 +.. date: 2017-12-14-11-48-19 +.. nonce: hlHo_9 +.. section: Core and Builtins + +The optimizer is now protected from spending much time doing complex +calculations and consuming much memory for creating large constants in +constant folding. + +.. + +.. bpo: 18533 +.. date: 2017-12-13-16-46-23 +.. nonce: Dlk8d7 +.. section: Core and Builtins + +``repr()`` on a dict containing its own ``values()`` or ``items()`` no +longer raises ``RecursionError``; OrderedDict similarly. Instead, use +``...``, as for other recursive structures. Patch by Ben North. + +.. + +.. bpo: 32028 +.. date: 2017-12-03-22-29-13 +.. nonce: KC2w4Q +.. section: Core and Builtins + +Leading whitespace is now correctly ignored when generating suggestions for +converting Py2 print statements to Py3 builtin print function calls. Patch +by Sanyam Khurana. + +.. + +.. bpo: 32137 +.. date: 2017-11-26-14-36-30 +.. nonce: Stj5nL +.. section: Core and Builtins + +The repr of deeply nested dict now raises a RecursionError instead of +crashing due to a stack overflow. + +.. + +.. bpo: 33064 +.. date: 2018-03-12-19-58-25 +.. nonce: LO2KIY +.. section: Library + +lib2to3 now properly supports trailing commas after ``*args`` and +``**kwargs`` in function signatures. + +.. + +.. bpo: 31804 +.. date: 2018-03-11-19-03-52 +.. nonce: i8KUMp +.. section: Library + +Avoid failing in multiprocessing.Process if the standard streams are closed +or None at exit. + +.. + +.. bpo: 33037 +.. date: 2018-03-09-23-07-07 +.. nonce: nAJ3at +.. section: Library + +Skip sending/receiving data after SSL transport closing. + +.. + +.. bpo: 30353 +.. date: 2018-03-08-09-54-01 +.. nonce: XdE5aM +.. section: Library + +Fix ctypes pass-by-value for structs on 64-bit Cygwin/MinGW. + +.. + +.. bpo: 33009 +.. date: 2018-03-06-11-54-59 +.. nonce: -Ekysb +.. section: Library + +Fix inspect.signature() for single-parameter partialmethods. + +.. + +.. bpo: 32969 +.. date: 2018-03-06-00-19-41 +.. nonce: rGTKa0 +.. section: Library + +Expose several missing constants in zlib and fix corresponding +documentation. + +.. + +.. bpo: 32713 +.. date: 2018-02-26-13-16-36 +.. nonce: 55yegW +.. section: Library + +Fixed tarfile.itn handling of out-of-bounds float values. Patch by Joffrey +Fuhrer. + +.. + +.. bpo: 30622 +.. date: 2018-02-24-21-40-42 +.. nonce: dQjxSe +.. section: Library + +The ssl module now detects missing NPN support in LibreSSL. + +.. + +.. bpo: 32922 +.. date: 2018-02-23-19-12-04 +.. nonce: u-xe0B +.. section: Library + +dbm.open() now encodes filename with the filesystem encoding rather than +default encoding. + +.. + +.. bpo: 32859 +.. date: 2018-02-19-17-46-31 +.. nonce: kAT-Xp +.. section: Library + +In ``os.dup2``, don't check every call whether the ``dup3`` syscall exists +or not. + +.. + +.. bpo: 21060 +.. date: 2018-02-17-19-20-19 +.. nonce: S1Z-x6 +.. section: Library + +Rewrite confusing message from setup.py upload from "No dist file created in +earlier command" to the more helpful "Must create and upload files in one +command". + +.. + +.. bpo: 32857 +.. date: 2018-02-16-14-37-14 +.. nonce: -XljAx +.. section: Library + +In :mod:`tkinter`, ``after_cancel(None)`` now raises a :exc:`ValueError` +instead of canceling the first scheduled function. Patch by Cheryl Sabella. + +.. + +.. bpo: 32852 +.. date: 2018-02-15-12-04-29 +.. nonce: HDqIxM +.. section: Library + +Make sure sys.argv remains as a list when running trace. + +.. + +.. bpo: 32841 +.. date: 2018-02-14-00-21-24 +.. nonce: bvHDOc +.. section: Library + +Fixed `asyncio.Condition` issue which silently ignored cancellation after +notifying and cancelling a conditional lock. Patch by Bar Harel. + +.. + +.. bpo: 31787 +.. date: 2018-02-09-21-41-56 +.. nonce: owSZ2t +.. section: Library + +Fixed refleaks of ``__init__()`` methods in various modules. (Contributed by +Oren Milman) + +.. + +.. bpo: 30157 +.. date: 2018-02-09-14-44-43 +.. nonce: lEiiAK +.. section: Library + +Fixed guessing quote and delimiter in csv.Sniffer.sniff() when only the last +field is quoted. Patch by Jake Davis. + +.. + +.. bpo: 32394 +.. date: 2018-02-08-08-18-26 +.. nonce: 6E_7X7 +.. section: Library + +socket: Remove TCP_FASTOPEN, TCP_KEEPCNT flags on older version Windows +during run-time. + +.. + +.. bpo: 32777 +.. date: 2018-02-05-21-28-28 +.. nonce: C-wIXF +.. section: Library + +Fix a rare but potential pre-exec child process deadlock in subprocess on +POSIX systems when marking file descriptors inheritable on exec in the child +process. This bug appears to have been introduced in 3.4. + +.. + +.. bpo: 32647 +.. date: 2018-02-05-13-31-42 +.. nonce: ktmfR_ +.. section: Library + +The ctypes module used to depend on indirect linking for dlopen. The shared +extension is now explicitly linked against libdl on platforms with dl. + +.. + +.. bpo: 32734 +.. date: 2018-02-01-01-34-47 +.. nonce: gCV9AD +.. section: Library + +Fixed ``asyncio.Lock()`` safety issue which allowed acquiring and locking +the same lock multiple times, without it being free. Patch by Bar Harel. + +.. + +.. bpo: 32727 +.. date: 2018-01-30-17-46-18 +.. nonce: aHVsRC +.. section: Library + +Do not include name field in SMTP envelope from address. Patch by Stéphane +Wirtel + +.. + +.. bpo: 27931 +.. date: 2018-01-25-21-04-11 +.. nonce: e4r52t +.. section: Library + +Fix email address header parsing error when the username is an empty quoted +string. Patch by Xiang Zhang. + +.. + +.. bpo: 32304 +.. date: 2018-01-21-16-33-53 +.. nonce: TItrNv +.. section: Library + +distutils' upload command no longer corrupts tar files ending with a CR +byte, and no longer tries to convert CR to CRLF in any of the upload text +fields. + +.. + +.. bpo: 32502 +.. date: 2018-01-20-17-15-34 +.. nonce: OXJfn7 +.. section: Library + +uuid.uuid1 no longer raises an exception if a 64-bit hardware address is +encountered. + +.. + +.. bpo: 31848 +.. date: 2018-01-18-23-34-17 +.. nonce: M2cldy +.. section: Library + +Fix the error handling in Aifc_read.initfp() when the SSND chunk is not +found. Patch by Zackery Spytz. + +.. + +.. bpo: 32555 +.. date: 2018-01-15-17-52-47 +.. nonce: CMq2zF +.. section: Library + +On FreeBSD and Solaris, os.strerror() now always decode the byte string from +the current locale encoding, rather than using ASCII/surrogateescape in some +cases. + +.. + +.. bpo: 32521 +.. date: 2018-01-15-12-53-13 +.. nonce: IxX4Ba +.. section: Library + +The nis module is now compatible with new libnsl and headers location. + +.. + +.. bpo: 32473 +.. date: 2018-01-10-20-37-59 +.. nonce: mP_yJG +.. section: Library + +Improve ABCMeta._dump_registry() output readability + +.. + +.. bpo: 32521 +.. date: 2018-01-08-18-02-33 +.. nonce: Kh-KoN +.. section: Library + +glibc has removed Sun RPC. Use replacement libtirpc headers and library in +nis module. + +.. + +.. bpo: 32228 +.. date: 2017-12-22-16-47-41 +.. nonce: waPx3q +.. section: Library + +Ensure that ``truncate()`` preserves the file position (as reported by +``tell()``) after writes longer than the buffer size. + +.. + +.. bpo: 26133 +.. date: 2017-12-21-11-08-42 +.. nonce: mt81QV +.. section: Library + +Don't unsubscribe signals in asyncio UNIX event loop on interpreter +shutdown. + +.. + +.. bpo: 32185 +.. date: 2017-12-20-09-25-10 +.. nonce: IL0cMt +.. section: Library + +The SSL module no longer sends IP addresses in SNI TLS extension on +platforms with OpenSSL 1.0.2+ or inet_pton. + +.. + +.. bpo: 32323 +.. date: 2017-12-14-10-10-10 +.. nonce: ideco +.. section: Library + +:func:`urllib.parse.urlsplit()` does not convert zone-id (scope) to lower +case for scoped IPv6 addresses in hostnames now. + +.. + +.. bpo: 32302 +.. date: 2017-12-13-22-38-08 +.. nonce: othtTr +.. section: Library + +Fix bdist_wininst of distutils for CRT v142: it binary compatible with CRT +v140. + +.. + +.. bpo: 32255 +.. date: 2017-12-12-07-29-06 +.. nonce: 2bfNmM +.. section: Library + +A single empty field is now always quoted when written into a CSV file. This +allows to distinguish an empty row from a row consisting of a single empty +field. Patch by Licht Takeuchi. + +.. + +.. bpo: 32277 +.. date: 2017-12-11-09-53-14 +.. nonce: jkKiVC +.. section: Library + +Raise ``NotImplementedError`` instead of ``SystemError`` on platforms where +``chmod(..., follow_symlinks=False)`` is not supported. Patch by Anthony +Sottile. + +.. + +.. bpo: 32199 +.. date: 2017-12-04-12-23-26 +.. nonce: nGof4v +.. section: Library + +The getnode() ip getter now uses 'ip link' instead of 'ip link list'. + +.. + +.. bpo: 27456 +.. date: 2017-11-02-11-57-41 +.. nonce: snzyTC +.. section: Library + +Ensure TCP_NODELAY is set on Linux. Tests by Victor Stinner. + +.. + +.. bpo: 31900 +.. date: 2017-10-30-15-55-32 +.. nonce: -S9xc4 +.. section: Library + +The :func:`locale.localeconv` function now sets temporarily the ``LC_CTYPE`` +locale to the ``LC_NUMERIC`` locale to decode ``decimal_point`` and +``thousands_sep`` byte strings if they are non-ASCII or longer than 1 byte, +and the ``LC_NUMERIC`` locale is different than the ``LC_CTYPE`` locale. +This temporary change affects other threads. +Same change for the :meth:`str.format` method when formatting a number +(:class:`int`, :class:`float`, :class:`float` and subclasses) with the ``n`` +type (ex: ``'{:n}'.format(1234)``). + +.. + +.. bpo: 31802 +.. date: 2017-10-17-14-52-14 +.. nonce: sYj2Zv +.. section: Library + +Importing native path module (``posixpath``, ``ntpath``) now works even if +the ``os`` module still is not imported. + +.. + +.. bpo: 17232 +.. date: 2018-02-23-12-48-03 +.. nonce: tmuTKL +.. section: Documentation + +Clarify docs for -O and -OO. Patch by Terry Reedy. + +.. + +.. bpo: 32800 +.. date: 2018-02-10-15-16-04 +.. nonce: FyrqCk +.. section: Documentation + +Update link to w3c doc for xml default namespaces. + +.. + +.. bpo: 8722 +.. date: 2018-02-03-06-11-37 +.. nonce: MPyVyj +.. section: Documentation + +Document :meth:`__getattr__` behavior when property :meth:`get` method +raises :exc:`AttributeError`. + +.. + +.. bpo: 32614 +.. date: 2018-02-02-07-41-57 +.. nonce: LSqzGw +.. section: Documentation + +Modify RE examples in documentation to use raw strings to prevent +:exc:`DeprecationWarning` and add text to REGEX HOWTO to highlight the +deprecation. + +.. + +.. bpo: 31972 +.. date: 2018-01-25-14-23-12 +.. nonce: w1m_8r +.. section: Documentation + +Improve docstrings for `pathlib.PurePath` subclasses. + +.. + +.. bpo: 17799 +.. date: 2018-01-22-21-13-46 +.. nonce: rdZ-Vk +.. section: Documentation + +Explain real behaviour of sys.settrace and sys.setprofile and their C-API +counterparts regarding which type of events are received in each function. +Patch by Pablo Galindo Salgado. + +.. + +.. bpo: 32517 +.. date: 2018-03-09-07-05-12 +.. nonce: ugc1iW +.. section: Tests + +Fix failing ``test_asyncio`` on macOS 10.12.2+ due to transport of +``KqueueSelector`` loop was not being closed. + +.. + +.. bpo: 32721 +.. date: 2018-01-29-21-30-44 +.. nonce: 2Bebm1 +.. section: Tests + +Fix test_hashlib to not fail if the _md5 module is not built. + +.. + +.. bpo: 32252 +.. date: 2017-12-11-13-31-33 +.. nonce: YnFw7J +.. section: Tests + +Fix faulthandler_suppress_crash_report() used to prevent core dump files +when testing crashes. getrlimit() returns zero on success. + +.. + +.. bpo: 31518 +.. date: 2017-09-19-20-48-50 +.. nonce: KwTMMz +.. section: Tests + +Debian Unstable has disabled TLS 1.0 and 1.1 for SSLv23_METHOD(). Change +TLS/SSL protocol of some tests to PROTOCOL_TLS or PROTOCOL_TLSv1_2 to make +them pass on Debian. + +.. + +.. bpo: 32635 +.. date: 2018-01-23-15-33-40 +.. nonce: qHwIZy +.. section: Build + +Fix segfault of the crypt module when libxcrypt is provided instead of +libcrypt at the system. + +.. + +.. bpo: 33016 +.. date: 2018-03-07-01-33-33 +.. nonce: Z_Med0 +.. section: Windows + +Fix potential use of uninitialized memory in nt._getfinalpathname + +.. + +.. bpo: 32903 +.. date: 2018-02-28-11-03-24 +.. nonce: 1SXY4t +.. section: Windows + +Fix a memory leak in os.chdir() on Windows if the current directory is set +to a UNC path. + +.. + +.. bpo: 31966 +.. date: 2018-02-19-13-54-42 +.. nonce: _Q3HPb +.. section: Windows + +Fixed WindowsConsoleIO.write() for writing empty data. + +.. + +.. bpo: 32409 +.. date: 2018-02-19-10-00-57 +.. nonce: nocuDg +.. section: Windows + +Ensures activate.bat can handle Unicode contents. + +.. + +.. bpo: 32457 +.. date: 2018-02-19-08-54-06 +.. nonce: vVP0Iz +.. section: Windows + +Improves handling of denormalized executable path when launching Python. + +.. + +.. bpo: 32370 +.. date: 2018-02-10-15-38-19 +.. nonce: kcKuct +.. section: Windows + +Use the correct encoding for ipconfig output in the uuid module. Patch by +Segev Finer. + +.. + +.. bpo: 29248 +.. date: 2018-02-07-17-50-48 +.. nonce: Xzwj-6 +.. section: Windows + +Fix :func:`os.readlink` on Windows, which was mistakenly treating the +``PrintNameOffset`` field of the reparse data buffer as a number of +characters instead of bytes. Patch by Craig Holmquist and SSE4. + +.. + +.. bpo: 32588 +.. date: 2018-01-18-14-56-45 +.. nonce: vHww6F +.. section: Windows + +Create standalone _distutils_findvs module. + +.. + +.. bpo: 32726 +.. date: 2018-03-13-21-00-20 +.. nonce: Mticyn +.. section: macOS + +Provide an additional, more modern macOS installer variant that supports +macOS 10.9+ systems in 64-bit mode only. Upgrade the supplied third-party +libraries to OpenSSL 1.0.2n, XZ 5.2.3, and SQLite 3.22.0. The 10.9+ +installer now links with and supplies its own copy of Tcl/Tk 8.6.8. + +.. + +.. bpo: 32984 +.. date: 2018-03-05-01-29-05 +.. nonce: NGjgT4 +.. section: IDLE + +Set ``__file__`` while running a startup file. Like Python, IDLE optionally +runs one startup file in the Shell window before presenting the first +interactive input prompt. For IDLE, ``-s`` runs a file named in +environmental variable :envvar:`IDLESTARTUP` or :envvar:`PYTHONSTARTUP`; +``-r file`` runs ``file``. Python sets ``__file__`` to the startup file +name before running the file and unsets it before the first prompt. IDLE +now does the same when run normally, without the ``-n`` option. + +.. + +.. bpo: 32940 +.. date: 2018-02-24-18-20-50 +.. nonce: ZaJ1Rf +.. section: IDLE + +Simplify and rename StringTranslatePseudoMapping in pyparse. + +.. + +.. bpo: 32916 +.. date: 2018-02-23-07-32-36 +.. nonce: 4MsQ5F +.. section: IDLE + +Change ``str`` to ``code`` in pyparse. + +.. + +.. bpo: 32905 +.. date: 2018-02-22-00-09-27 +.. nonce: VlXj0x +.. section: IDLE + +Remove unused code in pyparse module. + +.. + +.. bpo: 32874 +.. date: 2018-02-19-10-56-41 +.. nonce: 6pZ9Gv +.. section: IDLE + +Add tests for pyparse. + +.. + +.. bpo: 32837 +.. date: 2018-02-12-17-22-48 +.. nonce: -33QPl +.. section: IDLE + +Using the system and place-dependent default encoding for open() is a bad +idea for IDLE's system and location-independent files. + +.. + +.. bpo: 32826 +.. date: 2018-02-12-11-05-22 +.. nonce: IxNZrk +.. section: IDLE + +Add "encoding=utf-8" to open() in IDLE's test_help_about. GUI test +test_file_buttons() only looks at initial ascii-only lines, but failed on +systems where open() defaults to 'ascii' because readline() internally reads +and decodes far enough ahead to encounter a non-ascii character in +CREDITS.txt. + +.. + +.. bpo: 32765 +.. date: 2018-02-04-17-52-54 +.. nonce: qm0eCu +.. section: IDLE + +Update configdialog General tab docstring to add new widgets to the widget +list. + +.. + +.. bpo: 24960 +.. date: 2017-12-22-09-25-51 +.. nonce: TGdAgO +.. section: Tools/Demos + +2to3 and lib2to3 can now read pickled grammar files using pkgutil.get_data() +rather than probing the filesystem. This lets 2to3 and lib2to3 work when run +from a zipfile. + +.. + +.. bpo: 32222 +.. date: 2017-12-07-20-51-20 +.. nonce: hPBcGT +.. section: Tools/Demos + +Fix pygettext not extracting docstrings for functions with type annotated +arguments. Patch by Toby Harradine. + +.. + +.. bpo: 29084 +.. date: 2017-12-16-09-59-35 +.. nonce: ZGJ-LJ +.. section: C API + +Undocumented C API for OrderedDict has been excluded from the limited C API. +It was added by mistake and actually never worked in the limited C API. diff --git a/Misc/NEWS.d/3.6.6.rst b/Misc/NEWS.d/3.6.6.rst new file mode 100644 index 00000000..da9f6470 --- /dev/null +++ b/Misc/NEWS.d/3.6.6.rst @@ -0,0 +1,8 @@ +.. bpo: 0 +.. date: 2018-06-27 +.. no changes: True +.. nonce: IWyX1H +.. release date: 2018-06-27 +.. section: Library + +There were no new changes in version 3.6.6. diff --git a/Misc/NEWS.d/3.6.6rc1.rst b/Misc/NEWS.d/3.6.6rc1.rst new file mode 100644 index 00000000..9624195c --- /dev/null +++ b/Misc/NEWS.d/3.6.6rc1.rst @@ -0,0 +1,885 @@ +.. bpo: 33786 +.. date: 2018-06-06-23-24-40 +.. nonce: lBvT8z +.. release date: 2018-06-11 +.. section: Core and Builtins + +Fix asynchronous generators to handle GeneratorExit in athrow() correctly + +.. + +.. bpo: 30654 +.. date: 2018-05-28-12-28-53 +.. nonce: 9fDJye +.. section: Core and Builtins + +Fixed reset of the SIGINT handler to SIG_DFL on interpreter shutdown even +when there was a custom handler set previously. Patch by Philipp Kerling. + +.. + +.. bpo: 33622 +.. date: 2018-05-23-20-46-14 +.. nonce: xPucO9 +.. section: Core and Builtins + +Fixed a leak when the garbage collector fails to add an object with the +``__del__`` method or referenced by it into the :data:`gc.garbage` list. +:c:func:`PyGC_Collect` can now be called when an exception is set and +preserves it. + +.. + +.. bpo: 31849 +.. date: 2018-05-14-11-00-00 +.. nonce: EmHaH4 +.. section: Core and Builtins + +Fix signed/unsigned comparison warning in pyhash.c. + +.. + +.. bpo: 33391 +.. date: 2018-05-02-08-36-03 +.. nonce: z4a7rb +.. section: Core and Builtins + +Fix a leak in set_symmetric_difference(). + +.. + +.. bpo: 28055 +.. date: 2018-04-25-20-44-42 +.. nonce: f49kfC +.. section: Core and Builtins + +Fix unaligned accesses in siphash24(). Patch by Rolf Eike Beer. + +.. + +.. bpo: 33231 +.. date: 2018-04-05-22-20-44 +.. nonce: 3Jmo0q +.. section: Core and Builtins + +Fix potential memory leak in ``normalizestring()``. + +.. + +.. bpo: 29922 +.. date: 2018-04-03-00-30-25 +.. nonce: CdLuMl +.. section: Core and Builtins + +Improved error messages in 'async with' when ``__aenter__()`` or +``__aexit__()`` return non-awaitable object. + +.. + +.. bpo: 33199 +.. date: 2018-04-02-09-32-40 +.. nonce: TPnxQu +.. section: Core and Builtins + +Fix ``ma_version_tag`` in dict implementation is uninitialized when copying +from key-sharing dict. + +.. + +.. bpo: 33041 +.. date: 2018-03-18-13-56-14 +.. nonce: XwPhI2 +.. section: Core and Builtins + +Fixed jumping when the function contains an ``async for`` loop. + +.. + +.. bpo: 32282 +.. date: 2017-12-12-14-02-28 +.. nonce: xFVMTn +.. section: Core and Builtins + +Fix an unnecessary ifdef in the include of VersionHelpers.h in socketmodule +on Windows. + +.. + +.. bpo: 21983 +.. date: 2017-10-02-21-02-14 +.. nonce: UoC319 +.. section: Core and Builtins + +Fix a crash in `ctypes.cast()` in case the type argument is a ctypes +structured data type. Patch by Eryk Sun and Oren Milman. + +.. + +.. bpo: 30167 +.. date: 2018-06-10-19-29-17 +.. nonce: G5EgC5 +.. section: Library + +Prevent site.main() exception if PYTHONSTARTUP is set. Patch by Steve Weber. + +.. + +.. bpo: 33812 +.. date: 2018-06-10-13-26-02 +.. nonce: frGAOr +.. section: Library + +Datetime instance d with non-None tzinfo, but with d.tzinfo.utcoffset(d) +returning None is now treated as naive by the astimezone() method. + +.. + +.. bpo: 30805 +.. date: 2018-06-08-17-34-16 +.. nonce: 3qCWa0 +.. section: Library + +Avoid race condition with debug logging + +.. + +.. bpo: 33767 +.. date: 2018-06-03-22-41-59 +.. nonce: 2e82g3 +.. section: Library + +The concatenation (``+``) and repetition (``*``) sequence operations now +raise :exc:`TypeError` instead of :exc:`SystemError` when performed on +:class:`mmap.mmap` objects. Patch by Zackery Spytz. + +.. + +.. bpo: 32684 +.. date: 2018-05-29-12-51-18 +.. nonce: ZEIism +.. section: Library + +Fix gather to propagate cancellation of itself even with return_exceptions. + +.. + +.. bpo: 33674 +.. date: 2018-05-28-22-49-59 +.. nonce: 6LFFj7 +.. section: Library + +Fix a race condition in SSLProtocol.connection_made() of asyncio.sslproto: +start immediately the handshake instead of using call_soon(). Previously, +data_received() could be called before the handshake started, causing the +handshake to hang or fail. + +.. + +.. bpo: 31647 +.. date: 2018-05-28-18-40-26 +.. nonce: s4Fad3 +.. section: Library + +Fixed bug where calling write_eof() on a _SelectorSocketTransport after it's +already closed raises AttributeError. + +.. + +.. bpo: 33672 +.. date: 2018-05-28-17-45-06 +.. nonce: GM_Xm_ +.. section: Library + +Fix Task.__repr__ crash with Cython's bogus coroutines + +.. + +.. bpo: 33469 +.. date: 2018-05-28-15-55-12 +.. nonce: hmXBpY +.. section: Library + +Fix RuntimeError after closing loop that used run_in_executor + +.. + +.. bpo: 11874 +.. date: 2018-05-23-00-26-27 +.. nonce: glK5iP +.. section: Library + +Use a better regex when breaking usage into wrappable parts. Avoids bogus +assertion errors from custom metavar strings. + +.. + +.. bpo: 30877 +.. date: 2018-05-22-13-05-12 +.. nonce: JZEGjI +.. section: Library + +Fixed a bug in the Python implementation of the JSON decoder that prevented +the cache of parsed strings from clearing after finishing the decoding. +Based on patch by c-fos. + +.. + +.. bpo: 33548 +.. date: 2018-05-16-17-05-48 +.. nonce: xWslmx +.. section: Library + +tempfile._candidate_tempdir_list should consider common TEMP locations + +.. + +.. bpo: 33542 +.. date: 2018-05-16-09-30-27 +.. nonce: idNAcs +.. section: Library + +Prevent ``uuid.get_node`` from using a DUID instead of a MAC on Windows. +Patch by Zvi Effron + +.. + +.. bpo: 26819 +.. date: 2018-05-16-05-24-43 +.. nonce: taxbVT +.. section: Library + +Fix race condition with `ReadTransport.resume_reading` in Windows proactor +event loop. + +.. + +.. bpo: 28556 +.. date: 2018-05-10-14-51-19 +.. nonce: y3zK6I +.. section: Library + +Minor fixes in typing module: add annotations to ``NamedTuple.__new__``, +pass ``*args`` and ``**kwds`` in ``Generic.__new__``. Original PRs by +Paulius Šarka and Chad Dombrova. + +.. + +.. bpo: 20087 +.. date: 2018-05-05-18-02-24 +.. nonce: lJrvXL +.. section: Library + +Updated alias mapping with glibc 2.27 supported locales. + +.. + +.. bpo: 33422 +.. date: 2018-05-05-09-53-05 +.. nonce: 4FtQ0q +.. section: Library + +Fix trailing quotation marks getting deleted when looking up byte/string +literals on pydoc. Patch by Andrés Delfino. + +.. + +.. bpo: 33197 +.. date: 2018-04-29-23-56-20 +.. nonce: dgRLqr +.. section: Library + +Update error message when constructing invalid inspect.Parameters Patch by +Donghee Na. + +.. + +.. bpo: 33383 +.. date: 2018-04-29-11-15-38 +.. nonce: g32YWn +.. section: Library + +Fixed crash in the get() method of the :mod:`dbm.ndbm` database object when +it is called with a single argument. + +.. + +.. bpo: 33329 +.. date: 2018-04-23-13-21-39 +.. nonce: lQ-Eod +.. section: Library + +Fix multiprocessing regression on newer glibcs + +.. + +.. bpo: 991266 +.. date: 2018-04-21-00-24-08 +.. nonce: h93TP_ +.. section: Library + +Fix quoting of the ``Comment`` attribute of +:class:`http.cookies.SimpleCookie`. + +.. + +.. bpo: 33131 +.. date: 2018-04-20-10-43-17 +.. nonce: L2E977 +.. section: Library + +Upgrade bundled version of pip to 10.0.1. + +.. + +.. bpo: 33308 +.. date: 2018-04-18-19-12-25 +.. nonce: fW75xi +.. section: Library + +Fixed a crash in the :mod:`parser` module when converting an ST object to a +tree of tuples or lists with ``line_info=False`` and ``col_info=True``. + +.. + +.. bpo: 33263 +.. date: 2018-04-11-20-29-19 +.. nonce: B56Hc1 +.. section: Library + +Fix FD leak in `_SelectorSocketTransport` Patch by Vlad Starostin. + +.. + +.. bpo: 33256 +.. date: 2018-04-10-20-57-14 +.. nonce: ndHkqu +.. section: Library + +Fix display of ``<module>`` call in the html produced by ``cgitb.html()``. +Patch by Stéphane Blondon. + +.. + +.. bpo: 33203 +.. date: 2018-04-05-11-09-45 +.. nonce: Hje9Py +.. section: Library + +``random.Random.choice()`` now raises ``IndexError`` for empty sequences +consistently even when called from subclasses without a ``getrandbits()`` +implementation. + +.. + +.. bpo: 33224 +.. date: 2018-04-04-23-41-30 +.. nonce: pyR0jB +.. section: Library + +Update difflib.mdiff() for :pep:`479`. Convert an uncaught StopIteration in a +generator into a return-statement. + +.. + +.. bpo: 33209 +.. date: 2018-04-03-10-37-13 +.. nonce: 9sGWE_ +.. section: Library + +End framing at the end of C implementation of :func:`pickle.Pickler.dump`. + +.. + +.. bpo: 32861 +.. date: 2018-04-02-20-44-54 +.. nonce: HeBjzN +.. section: Library + +The urllib.robotparser's ``__str__`` representation now includes wildcard +entries and the "Crawl-delay" and "Request-rate" fields. Patch by Michael +Lazar. + +.. + +.. bpo: 33096 +.. date: 2018-03-25-13-18-16 +.. nonce: ofdbe7 +.. section: Library + +Allow ttk.Treeview.insert to insert iid that has a false boolean value. Note +iid=0 and iid=False would be same. Patch by Garvit Khatri. + +.. + +.. bpo: 33127 +.. date: 2018-03-24-15-08-24 +.. nonce: olJmHv +.. section: Library + +The ssl module now compiles with LibreSSL 2.7.1. + +.. + +.. bpo: 33021 +.. date: 2018-03-12-00-27-56 +.. nonce: m19B9T +.. section: Library + +Release the GIL during fstat() calls, avoiding hang of all threads when +calling mmap.mmap(), os.urandom(), and random.seed(). Patch by Nir Soffer. + +.. + +.. bpo: 27683 +.. date: 2018-03-07-22-28-17 +.. nonce: 572Rv4 +.. section: Library + +Fix a regression in :mod:`ipaddress` that result of :meth:`hosts` is empty +when the network is constructed by a tuple containing an integer mask and +only 1 bit left for addresses. + +.. + +.. bpo: 32844 +.. date: 2018-02-28-13-08-00 +.. nonce: u8tnAe +.. section: Library + +Fix wrong redirection of a low descriptor (0 or 1) to stderr in subprocess +if another low descriptor is closed. + +.. + +.. bpo: 31908 +.. date: 2017-10-31 +.. nonce: g4xh8x +.. section: Library + +Fix output of cover files for ``trace`` module command-line tool. Previously +emitted cover files only when ``--missing`` option was used. Patch by +Michael Selik. + +.. + +.. bpo: 31457 +.. date: 2017-10-18-19-05-17 +.. nonce: KlE6r8 +.. section: Library + +If nested log adapters are used, the inner ``process()`` methods are no +longer omitted. + +.. + +.. bpo: 16865 +.. date: 2017-09-29-16-40-38 +.. nonce: l-f6I_ +.. section: Library + +Support arrays >=2GiB in :mod:`ctypes`. Patch by Segev Finer. + +.. + +.. bpo: 31238 +.. date: 2017-08-21-12-31-53 +.. nonce: Gg0LRH +.. section: Library + +pydoc: the stop() method of the private ServerThread class now waits until +DocServer.serve_until_quit() completes and then explicitly sets its +docserver attribute to None to break a reference cycle. + +.. + +.. bpo: 33503 +.. date: 2018-05-14-20-08-58 +.. nonce: Wvt0qg +.. section: Documentation + +Fix broken pypi link + +.. + +.. bpo: 33421 +.. date: 2018-05-14-15-23-51 +.. nonce: 3GU_QO +.. section: Documentation + +Add missing documentation for ``typing.AsyncContextManager``. + +.. + +.. bpo: 33378 +.. date: 2018-04-29-04-02-18 +.. nonce: -anAHN +.. section: Documentation + +Add Korean language switcher for https://docs.python.org/3/ + +.. + +.. bpo: 33276 +.. date: 2018-04-20-14-09-36 +.. nonce: rA1z_3 +.. section: Documentation + +Clarify that the ``__path__`` attribute on modules cannot be just any value. + +.. + +.. bpo: 33201 +.. date: 2018-04-01-21-03-41 +.. nonce: aa8Lkl +.. section: Documentation + +Modernize documentation for writing C extension types. + +.. + +.. bpo: 33195 +.. date: 2018-04-01-14-30-36 +.. nonce: dRS-XX +.. section: Documentation + +Deprecate ``Py_UNICODE`` usage in ``c-api/arg`` document. ``Py_UNICODE`` +related APIs are deprecated since Python 3.3, but it is missed in the +document. + +.. + +.. bpo: 33126 +.. date: 2018-03-28-17-03-17 +.. nonce: 5UGkNv +.. section: Documentation + +Document PyBuffer_ToContiguous(). + +.. + +.. bpo: 27212 +.. date: 2018-03-22-19-23-04 +.. nonce: wrE5KR +.. section: Documentation + +Modify documentation for the :func:`islice` recipe to consume initial values +up to the start index. + +.. + +.. bpo: 28247 +.. date: 2018-03-20-20-11-05 +.. nonce: -V-WS- +.. section: Documentation + +Update :mod:`zipapp` documentation to describe how to make standalone +applications. + +.. + +.. bpo: 18802 +.. date: 2018-03-11-18-53-47 +.. nonce: JhAqH3 +.. section: Documentation + +Documentation changes for ipaddress. Patch by Jon Foster and Berker Peksag. + +.. + +.. bpo: 27428 +.. date: 2018-03-11-00-16-56 +.. nonce: B7A8FT +.. section: Documentation + +Update documentation to clarify that ``WindowsRegistryFinder`` implements +``MetaPathFinder``. (Patch by Himanshu Lakhara) + +.. + +.. bpo: 8243 +.. date: 2018-01-13-20-30-53 +.. nonce: s98r28 +.. section: Documentation + +Add a note about curses.addch and curses.addstr exception behavior when +writing outside a window, or pad. + +.. + +.. bpo: 31432 +.. date: 2017-09-13-07-14-59 +.. nonce: yAY4Z3 +.. section: Documentation + +Clarify meaning of CERT_NONE, CERT_OPTIONAL, and CERT_REQUIRED flags for +ssl.SSLContext.verify_mode. + +.. + +.. bpo: 33655 +.. date: 2018-05-26-16-01-40 +.. nonce: Frb4LA +.. section: Tests + +Ignore test_posix_fallocate failures on BSD platforms that might be due to +running on ZFS. + +.. + +.. bpo: 19417 +.. date: 2018-01-08-13-33-47 +.. nonce: 2asoXy +.. section: Tests + +Add test_bdb.py. + +.. + +.. bpo: 5755 +.. date: 2018-06-04-21-34-34 +.. nonce: 65GmCj +.. section: Build + +Move ``-Wstrict-prototypes`` option to ``CFLAGS_NODIST`` from ``OPT``. This +option emitted annoying warnings when building extension modules written in +C++. + +.. + +.. bpo: 33614 +.. date: 2018-05-28-11-40-22 +.. nonce: 28e0sE +.. section: Build + +Ensures module definition files for the stable ABI on Windows are correctly +regenerated. + +.. + +.. bpo: 33522 +.. date: 2018-05-15-12-44-50 +.. nonce: mJoNcA +.. section: Build + +Enable CI builds on Visual Studio Team Services at +https://python.visualstudio.com/cpython + +.. + +.. bpo: 33012 +.. date: 2018-05-10-21-10-01 +.. nonce: 5Zfjac +.. section: Build + +Add ``-Wno-cast-function-type`` for gcc 8 for silencing warnings about +function casts like casting to PyCFunction in method definition lists. + +.. + +.. bpo: 33394 +.. date: 2018-04-30-17-36-46 +.. nonce: _Vdi4t +.. section: Build + +Enable the verbose build for extension modules, when GNU make is passed +macros on the command line. + +.. + +.. bpo: 33184 +.. date: 2018-04-13-11-39-28 +.. nonce: aEohx0 +.. section: Windows + +Update Windows installer to OpenSSL 1.0.2o. + +.. + +.. bpo: 33184 +.. date: 2018-04-07-00-58-50 +.. nonce: rMTiqu +.. section: macOS + +Update macOS installer build to use OpenSSL 1.0.2o. + +.. + +.. bpo: 33656 +.. date: 2018-06-10-17-59-36 +.. nonce: 60ZqJS +.. section: IDLE + +On Windows, add API call saying that tk scales for DPI. On Windows 8.1+ or +10, with DPI compatibility properties of the Python binary unchanged, and a +monitor resolution greater than 96 DPI, this should make text and lines +sharper. It should otherwise have no effect. + +.. + +.. bpo: 33768 +.. date: 2018-06-04-19-23-11 +.. nonce: I_2qpV +.. section: IDLE + +Clicking on a context line moves that line to the top of the editor window. + +.. + +.. bpo: 33763 +.. date: 2018-06-03-20-12-57 +.. nonce: URiFlE +.. section: IDLE + +IDLE: Use read-only text widget for code context instead of label widget. + +.. + +.. bpo: 33664 +.. date: 2018-06-03-09-13-28 +.. nonce: PZzQyL +.. section: IDLE + +Scroll IDLE editor text by lines. Previously, the mouse wheel and scrollbar +slider moved text by a fixed number of pixels, resulting in partial lines at +the top of the editor box. The change also applies to the shell and grep +output windows, but not to read-only text views. + +.. + +.. bpo: 33679 +.. date: 2018-05-29-07-14-37 +.. nonce: MgX_Ui +.. section: IDLE + +Enable theme-specific color configuration for Code Context. Use the +Highlights tab to see the setting for built-in themes or add settings to +custom themes. + +.. + +.. bpo: 33642 +.. date: 2018-05-24-20-42-44 +.. nonce: J0VQbS +.. section: IDLE + +Display up to maxlines non-blank lines for Code Context. If there is no +current context, show a single blank line. + +.. + +.. bpo: 33628 +.. date: 2018-05-23-19-51-07 +.. nonce: sLlFLO +.. section: IDLE + +IDLE: Cleanup codecontext.py and its test. + +.. + +.. bpo: 33564 +.. date: 2018-05-17-19-41-12 +.. nonce: XzHZJe +.. section: IDLE + +IDLE's code context now recognizes async as a block opener. + +.. + +.. bpo: 29706 +.. date: 2018-05-15-17-01-10 +.. nonce: id4H5i +.. section: IDLE + +IDLE now colors async and await as keywords in 3.6. They become full +keywords in 3.7. + +.. + +.. bpo: 21474 +.. date: 2018-04-29-16-13-02 +.. nonce: bglg-F +.. section: IDLE + +Update word/identifier definition from ascii to unicode. In text and entry +boxes, this affects selection by double-click, movement left/right by +control-left/right, and deletion left/right by control-BACKSPACE/DEL. + +.. + +.. bpo: 33204 +.. date: 2018-04-02-00-28-13 +.. nonce: NBsuIv +.. section: IDLE + +IDLE: consistently color invalid string prefixes. A 'u' string prefix cannot +be paired with either 'r' or 'f'. Consistently color as much of the prefix, +starting at the right, as is valid. Revise and extend colorizer test. + +.. + +.. bpo: 32831 +.. date: 2018-02-12-08-08-45 +.. nonce: srDRvU +.. section: IDLE + +Add docstrings and tests for codecontext. + +.. + +.. bpo: 33189 +.. date: 2018-04-03-18-10-00 +.. nonce: QrXR00 +.. section: Tools/Demos + +:program:`pygettext.py` now recognizes only literal strings as docstrings +and translatable strings, and rejects bytes literals and f-string +expressions. + +.. + +.. bpo: 31920 +.. date: 2018-03-26-18-54-24 +.. nonce: u_WKsT +.. section: Tools/Demos + +Fixed handling directories as arguments in the ``pygettext`` script. Based +on patch by Oleg Krasnikov. + +.. + +.. bpo: 29673 +.. date: 2018-03-16-17-25-05 +.. nonce: m8QtaW +.. section: Tools/Demos + +Fix pystackv and pystack gdbinit macros. + +.. + +.. bpo: 32885 +.. date: 2018-02-20-12-16-47 +.. nonce: dL5x7C +.. section: Tools/Demos + +Add an ``-n`` flag for ``Tools/scripts/pathfix.py`` to disable automatic +backup creation (files with ``~`` suffix). + +.. + +.. bpo: 31583 +.. date: 2017-09-26-10-11-21 +.. nonce: TM90_H +.. section: Tools/Demos + +Fix 2to3 for using with --add-suffix option but without --output-dir option +for relative path to files in current directory. + +.. + +.. bpo: 32374 +.. date: 2018-01-09-17-03-54 +.. nonce: SwwLoz +.. section: C API + +Document that m_traverse for multi-phase initialized modules can be called +with m_state=NULL, and add a sanity check diff --git a/Misc/NEWS.d/3.7.0.rst b/Misc/NEWS.d/3.7.0.rst new file mode 100644 index 00000000..41a93165 --- /dev/null +++ b/Misc/NEWS.d/3.7.0.rst @@ -0,0 +1,17 @@ +.. bpo: 33851 +.. date: 2018-06-13-15-12-25 +.. nonce: SVbqlz +.. release date: 2018-06-27 +.. section: Library + +Fix :func:`ast.get_docstring` for a node that lacks a docstring. + +.. + +.. bpo: 33932 +.. date: 2018-06-21-15-29-59 +.. nonce: VSlXyS +.. section: C API + +Calling Py_Initialize() twice does nothing, instead of failing with a fatal +error: restore the Python 3.6 behaviour. diff --git a/Misc/NEWS.d/3.7.0a1.rst b/Misc/NEWS.d/3.7.0a1.rst new file mode 100644 index 00000000..bee42424 --- /dev/null +++ b/Misc/NEWS.d/3.7.0a1.rst @@ -0,0 +1,6432 @@ +.. bpo: 29781 +.. date: 2017-09-05-15-26-30 +.. nonce: LwYtBP +.. release date: 2017-09-19 +.. section: Security + +SSLObject.version() now correctly returns None when handshake over BIO has +not been performed yet. + +.. + +.. bpo: 29505 +.. date: 2017-08-23-17-02-55 +.. nonce: BL6Yt8 +.. section: Security + +Add fuzz tests for float(str), int(str), unicode(str); for oss-fuzz. + +.. + +.. bpo: 30947 +.. date: 2017-08-16-16-35-59 +.. nonce: iNMmm4 +.. section: Security + +Upgrade libexpat embedded copy from version 2.2.1 to 2.2.3 to get security +fixes. + +.. + +.. bpo: 30730 +.. date: 0347 +.. nonce: rJsyTH +.. original section: Library +.. section: Security + +Prevent environment variables injection in subprocess on Windows. Prevent +passing other environment variables and command arguments. + +.. + +.. bpo: 30694 +.. date: 0344 +.. nonce: WkMWM_ +.. original section: Library +.. section: Security + +Upgrade expat copy from 2.2.0 to 2.2.1 to get fixes of multiple security +vulnerabilities including: CVE-2017-9233 (External entity infinite loop +DoS), CVE-2016-9063 (Integer overflow, re-fix), CVE-2016-0718 (Fix +regression bugs from 2.2.0's fix to CVE-2016-0718) and CVE-2012-0876 +(Counter hash flooding with SipHash). Note: the CVE-2016-5300 (Use +os-specific entropy sources like getrandom) doesn't impact Python, since Python +already gets entropy from the OS to set the expat secret using +``XML_SetHashSalt()``. + +.. + +.. bpo: 30500 +.. date: 0342 +.. nonce: 1VG7R- +.. original section: Library +.. section: Security + +Fix urllib.parse.splithost() to correctly parse fragments. For example, +``splithost('//127.0.0.1#@evil.com/')`` now correctly returns the +``127.0.0.1`` host, instead of treating ``@evil.com`` as the host in an +authentication (``login@host``). + +.. + +.. bpo: 29591 +.. date: 0338 +.. nonce: ExKblw +.. original section: Library +.. section: Security + +Update expat copy from 2.1.1 to 2.2.0 to get fixes of CVE-2016-0718 and +CVE-2016-4472. See https://sourceforge.net/p/expat/bugs/537/ for more +information. + +.. + +.. bpo: 31490 +.. date: 2017-09-16-13-32-35 +.. nonce: r7m2sj +.. section: Core and Builtins + +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: 31471 +.. date: 2017-09-14-19-47-57 +.. nonce: 0yiA5Q +.. section: Core and Builtins + +Fix an assertion failure in `subprocess.Popen()` on Windows, in case the env +argument has a bad keys() method. Patch by Oren Milman. + +.. + +.. bpo: 31418 +.. date: 2017-09-13-13-03-52 +.. nonce: rS-FlC +.. section: Core and Builtins + +Fix an assertion failure in `PyErr_WriteUnraisable()` in case of an +exception with a bad ``__module__`` attribute. Patch by Oren Milman. + +.. + +.. bpo: 31416 +.. date: 2017-09-11-12-54-35 +.. nonce: 2hlQFd +.. section: Core and Builtins + +Fix assertion failures in case of a bad warnings.filters or +warnings.defaultaction. Patch by Oren Milman. + +.. + +.. bpo: 28411 +.. date: 2017-09-11-09-24-21 +.. nonce: 12SpAm +.. section: Core and Builtins + +Change direct usage of PyInterpreterState.modules to +PyImport_GetModuleDict(). Also introduce more uniformity in other code that +deals with sys.modules. This helps reduce complications when working on +sys.modules. + +.. + +.. bpo: 28411 +.. date: 2017-09-11-09-11-20 +.. nonce: Ax91lz +.. section: Core and Builtins + +Switch to the abstract API when dealing with ``PyInterpreterState.modules``. +This allows later support for all dict subclasses and other Mapping +implementations. Also add a ``PyImport_GetModule()`` function to reduce a +bunch of duplicated code. + +.. + +.. bpo: 31411 +.. date: 2017-09-11-08-50-41 +.. nonce: HZz82I +.. section: Core and Builtins + +Raise a TypeError instead of SystemError in case warnings.onceregistry is +not a dictionary. Patch by Oren Milman. + +.. + +.. bpo: 31344 +.. date: 2017-09-06-20-25-47 +.. nonce: XpFs-q +.. section: Core and Builtins + +For finer control of tracing behaviour when testing the interpreter, two new +frame attributes have been added to control the emission of particular trace +events: ``f_trace_lines`` (``True`` by default) to turn off per-line trace +events; and ``f_trace_opcodes`` (``False`` by default) to turn on per-opcode +trace events. + +.. + +.. bpo: 31373 +.. date: 2017-09-06-15-25-59 +.. nonce: dC4jd4 +.. section: Core and Builtins + +Fix several possible instances of undefined behavior due to floating-point +demotions. + +.. + +.. bpo: 30465 +.. date: 2017-09-06-10-47-29 +.. nonce: oe-3GD +.. section: Core and Builtins + +Location information (``lineno`` and ``col_offset``) in f-strings is now +(mostly) correct. This fixes tools like flake8 from showing warnings on the +wrong line (typically the first line of the file). + +.. + +.. bpo: 30860 +.. date: 2017-09-05-13-47-49 +.. nonce: MROpZw +.. section: Core and Builtins + +Consolidate CPython's global runtime state under a single struct. This +improves discoverability of the runtime state. + +.. + +.. bpo: 31347 +.. date: 2017-09-04-16-35-06 +.. nonce: KDuf2w +.. section: Core and Builtins + +Fix possible undefined behavior in _PyObject_FastCall_Prepend. + +.. + +.. bpo: 31343 +.. date: 2017-09-04-14-57-27 +.. nonce: Kl_fS5 +.. section: Core and Builtins + +Include sys/sysmacros.h for major(), minor(), and makedev(). GNU C libray +plans to remove the functions from sys/types.h. + +.. + +.. bpo: 31291 +.. date: 2017-08-28-11-51-29 +.. nonce: t8QggK +.. section: Core and Builtins + +Fix an assertion failure in `zipimport.zipimporter.get_data` on Windows, +when the return value of ``pathname.replace('/','\\')`` isn't a string. +Patch by Oren Milman. + +.. + +.. bpo: 31271 +.. date: 2017-08-25-20-43-22 +.. nonce: YMduKF +.. section: Core and Builtins + +Fix an assertion failure in the write() method of `io.TextIOWrapper`, when +the encoder doesn't return a bytes object. Patch by Oren Milman. + +.. + +.. bpo: 31243 +.. date: 2017-08-24-13-34-49 +.. nonce: dRJzqR +.. section: Core and Builtins + +Fix a crash in some methods of `io.TextIOWrapper`, when the decoder's state +is invalid. Patch by Oren Milman. + +.. + +.. bpo: 30721 +.. date: 2017-08-18-15-15-20 +.. nonce: Hmc56z +.. section: Core and Builtins + +``print`` now shows correct usage hint for using Python 2 redirection +syntax. Patch by Sanyam Khurana. + +.. + +.. bpo: 31070 +.. date: 2017-08-09-09-40-54 +.. nonce: oDyLiI +.. section: Core and Builtins + +Fix a race condition in importlib _get_module_lock(). + +.. + +.. bpo: 30747 +.. date: 2017-08-08-12-00-29 +.. nonce: g2kZRT +.. section: Core and Builtins + +Add a non-dummy implementation of _Py_atomic_store and _Py_atomic_load on +MSVC. + +.. + +.. bpo: 31095 +.. date: 2017-08-01-18-48-30 +.. nonce: bXWZDb +.. section: Core and Builtins + +Fix potential crash during GC caused by ``tp_dealloc`` which doesn't call +``PyObject_GC_UnTrack()``. + +.. + +.. bpo: 31071 +.. date: 2017-07-31-13-28-53 +.. nonce: P9UBDy +.. section: Core and Builtins + +Avoid masking original TypeError in call with * unpacking when other +arguments are passed. + +.. + +.. bpo: 30978 +.. date: 2017-07-21-07-39-05 +.. nonce: f0jODc +.. section: Core and Builtins + +str.format_map() now passes key lookup exceptions through. Previously any +exception was replaced with a KeyError exception. + +.. + +.. bpo: 30808 +.. date: 2017-07-17-12-12-59 +.. nonce: bA3zOv +.. section: Core and Builtins + +Use _Py_atomic API for concurrency-sensitive signal state. + +.. + +.. bpo: 30876 +.. date: 2017-07-11-06-31-32 +.. nonce: x35jZX +.. section: Core and Builtins + +Relative import from unloaded package now reimports the package instead of +failing with SystemError. Relative import from non-package now fails with +ImportError rather than SystemError. + +.. + +.. bpo: 30703 +.. date: 2017-06-28-21-07-32 +.. nonce: ULCdFp +.. section: Core and Builtins + +Improve signal delivery. +Avoid using Py_AddPendingCall from signal handler, to avoid calling +signal-unsafe functions. The tests I'm adding here fail without the rest of the +patch, on Linux and OS X. This means our signal delivery logic had defects +(some signals could be lost). + +.. + +.. bpo: 30765 +.. date: 2017-06-26-14-29-50 +.. nonce: Q5iBmf +.. section: Core and Builtins + +Avoid blocking in pthread_mutex_lock() when PyThread_acquire_lock() is asked +not to block. + +.. + +.. bpo: 31161 +.. date: 0470 +.. nonce: FcUAA0 +.. section: Core and Builtins + +Make sure the 'Missing parentheses' syntax error message is only applied to +SyntaxError, not to subclasses. Patch by Martijn Pieters. + +.. + +.. bpo: 30814 +.. date: 0469 +.. nonce: HcYsfM +.. section: Core and Builtins + +Fixed a race condition when import a submodule from a package. + +.. + +.. bpo: 30736 +.. date: 0468 +.. nonce: kA4J9v +.. section: Core and Builtins + +The internal unicodedata database has been upgraded to Unicode 10.0. + +.. + +.. bpo: 30604 +.. date: 0467 +.. nonce: zGPGoX +.. section: Core and Builtins + +Move co_extra_freefuncs from per-thread to per-interpreter to avoid crashes. + +.. + +.. bpo: 30597 +.. date: 0466 +.. nonce: 7erHiP +.. section: Core and Builtins + +``print`` now shows expected input in custom error message when used as a +Python 2 statement. Patch by Sanyam Khurana. + +.. + +.. bpo: 30682 +.. date: 0465 +.. nonce: zZm88E +.. section: Core and Builtins + +Removed a too-strict assertion that failed for certain f-strings, such as +eval("f'\\\n'") and eval("f'\\\r'"). + +.. + +.. bpo: 30501 +.. date: 0464 +.. nonce: BWJByG +.. section: Core and Builtins + +The compiler now produces more optimal code for complex condition +expressions in the "if", "while" and "assert" statement, the "if" +expression, and generator expressions and comprehensions. + +.. + +.. bpo: 28180 +.. date: 0463 +.. nonce: f_IHor +.. section: Core and Builtins + +Implement :pep:`538` (legacy C locale coercion). This means that when a +suitable coercion target locale is available, both the core interpreter and +locale-aware C extensions will assume the use of UTF-8 as the default text +encoding, rather than ASCII. + +.. + +.. bpo: 30486 +.. date: 0462 +.. nonce: KZi3nB +.. section: Core and Builtins + +Allows setting cell values for __closure__. Patch by Lisa Roach. + +.. + +.. bpo: 30537 +.. date: 0461 +.. nonce: sGC27r +.. section: Core and Builtins + +itertools.islice now accepts integer-like objects (having an __index__ +method) as start, stop, and slice arguments + +.. + +.. bpo: 25324 +.. date: 0460 +.. nonce: l12VjO +.. section: Core and Builtins + +Tokens needed for parsing in Python moved to C. ``COMMENT``, ``NL`` and +``ENCODING``. This way the tokens and tok_names in the token module don't +get changed when you import the tokenize module. + +.. + +.. bpo: 29104 +.. date: 0459 +.. nonce: u26yCx +.. section: Core and Builtins + +Fixed parsing backslashes in f-strings. + +.. + +.. bpo: 27945 +.. date: 0458 +.. nonce: p29r3O +.. section: Core and Builtins + +Fixed various segfaults with dict when input collections are mutated during +searching, inserting or comparing. Based on patches by Duane Griffin and +Tim Mitchell. + +.. + +.. bpo: 25794 +.. date: 0457 +.. nonce: xfPwqm +.. section: Core and Builtins + +Fixed type.__setattr__() and type.__delattr__() for non-interned attribute +names. Based on patch by Eryk Sun. + +.. + +.. bpo: 30039 +.. date: 0456 +.. nonce: e0u4DG +.. section: Core and Builtins + +If a KeyboardInterrupt happens when the interpreter is in the middle of +resuming a chain of nested 'yield from' or 'await' calls, it's now correctly +delivered to the innermost frame. + +.. + +.. bpo: 28974 +.. date: 0455 +.. nonce: jVewS0 +.. section: Core and Builtins + +``object.__format__(x, '')`` is now equivalent to ``str(x)`` rather than +``format(str(self), '')``. + +.. + +.. bpo: 30024 +.. date: 0454 +.. nonce: kSOlED +.. section: Core and Builtins + +Circular imports involving absolute imports with binding a submodule to a +name are now supported. + +.. + +.. bpo: 12414 +.. date: 0453 +.. nonce: T9ix8O +.. section: Core and Builtins + +sys.getsizeof() on a code object now returns the sizes which includes the +code struct and sizes of objects which it references. Patch by Donghee Na. + +.. + +.. bpo: 29839 +.. date: 0452 +.. nonce: rUmfay +.. section: Core and Builtins + +len() now raises ValueError rather than OverflowError if __len__() returned +a large negative integer. + +.. + +.. bpo: 11913 +.. date: 0451 +.. nonce: 5uiMX9 +.. section: Core and Builtins + +README.rst is now included in the list of distutils standard READMEs and +therefore included in source distributions. + +.. + +.. bpo: 29914 +.. date: 0450 +.. nonce: nqFSRR +.. section: Core and Builtins + +Fixed default implementations of __reduce__ and __reduce_ex__(). +object.__reduce__() no longer takes arguments, object.__reduce_ex__() now +requires one argument. + +.. + +.. bpo: 29949 +.. date: 0449 +.. nonce: DevGPS +.. section: Core and Builtins + +Fix memory usage regression of set and frozenset object. + +.. + +.. bpo: 29935 +.. date: 0448 +.. nonce: vgjdJo +.. section: Core and Builtins + +Fixed error messages in the index() method of tuple, list and deque when +pass indices of wrong type. + +.. + +.. bpo: 29816 +.. date: 0447 +.. nonce: 0H75Nl +.. section: Core and Builtins + +Shift operation now has less opportunity to raise OverflowError. ValueError +always is raised rather than OverflowError for negative counts. Shifting +zero with non-negative count always returns zero. + +.. + +.. bpo: 24821 +.. date: 0446 +.. nonce: 4DINGV +.. section: Core and Builtins + +Fixed the slowing down to 25 times in the searching of some unlucky Unicode +characters. + +.. + +.. bpo: 29102 +.. date: 0445 +.. nonce: AW4YPj +.. section: Core and Builtins + +Add a unique ID to PyInterpreterState. This makes it easier to identify +each subinterpreter. + +.. + +.. bpo: 29894 +.. date: 0444 +.. nonce: Vev6t- +.. section: Core and Builtins + +The deprecation warning is emitted if __complex__ returns an instance of a +strict subclass of complex. In a future versions of Python this can be an +error. + +.. + +.. bpo: 29859 +.. date: 0443 +.. nonce: Z1MLcA +.. section: Core and Builtins + +Show correct error messages when any of the pthread_* calls in +thread_pthread.h fails. + +.. + +.. bpo: 29849 +.. date: 0442 +.. nonce: hafvBD +.. section: Core and Builtins + +Fix a memory leak when an ImportError is raised during from import. + +.. + +.. bpo: 28856 +.. date: 0441 +.. nonce: AFRmo4 +.. section: Core and Builtins + +Fix an oversight that %b format for bytes should support objects follow the +buffer protocol. + +.. + +.. bpo: 29723 +.. date: 0440 +.. nonce: M5omgP +.. section: Core and Builtins + +The ``sys.path[0]`` initialization change for bpo-29139 caused a regression +by revealing an inconsistency in how sys.path is initialized when executing +``__main__`` from a zipfile, directory, or other import location. The +interpreter now consistently avoids ever adding the import location's parent +directory to ``sys.path``, and ensures no other ``sys.path`` entries are +inadvertently modified when inserting the import location named on the +command line. + +.. + +.. bpo: 29568 +.. date: 0439 +.. nonce: 3EtOC- +.. section: Core and Builtins + +Escaped percent "%%" in the format string for classic string formatting no +longer allows any characters between two percents. + +.. + +.. bpo: 29714 +.. date: 0438 +.. nonce: z-BhVd +.. section: Core and Builtins + +Fix a regression that bytes format may fail when containing zero bytes +inside. + +.. + +.. bpo: 29695 +.. date: 0437 +.. nonce: z75xXa +.. section: Core and Builtins + +bool(), float(), list() and tuple() no longer take keyword arguments. The +first argument of int() can now be passes only as positional argument. + +.. + +.. bpo: 28893 +.. date: 0436 +.. nonce: WTKnpj +.. section: Core and Builtins + +Set correct __cause__ for errors about invalid awaitables returned from +__aiter__ and __anext__. + +.. + +.. bpo: 28876 +.. date: 0435 +.. nonce: cU-sGT +.. section: Core and Builtins + +``bool(range)`` works even if ``len(range)`` raises :exc:`OverflowError`. + +.. + +.. bpo: 29683 +.. date: 0434 +.. nonce: G5iS-P +.. section: Core and Builtins + +Fixes to memory allocation in _PyCode_SetExtra. Patch by Brian Coleman. + +.. + +.. bpo: 29684 +.. date: 0433 +.. nonce: wTgEoh +.. section: Core and Builtins + +Fix minor regression of PyEval_CallObjectWithKeywords. It should raise +TypeError when kwargs is not a dict. But it might cause segv when args=NULL +and kwargs is not a dict. + +.. + +.. bpo: 28598 +.. date: 0432 +.. nonce: QxbzQn +.. section: Core and Builtins + +Support __rmod__ for subclasses of str being called before str.__mod__. +Patch by Martijn Pieters. + +.. + +.. bpo: 29607 +.. date: 0431 +.. nonce: 7NvBA1 +.. section: Core and Builtins + +Fix stack_effect computation for CALL_FUNCTION_EX. Patch by Matthieu +Dartiailh. + +.. + +.. bpo: 29602 +.. date: 0430 +.. nonce: qyyskC +.. section: Core and Builtins + +Fix incorrect handling of signed zeros in complex constructor for complex +subclasses and for inputs having a __complex__ method. Patch by Serhiy +Storchaka. + +.. + +.. bpo: 29347 +.. date: 0429 +.. nonce: 1RPPGN +.. section: Core and Builtins + +Fixed possibly dereferencing undefined pointers when creating weakref +objects. + +.. + +.. bpo: 29463 +.. date: 0428 +.. nonce: h2bg8A +.. section: Core and Builtins + +Add ``docstring`` field to Module, ClassDef, FunctionDef, and +AsyncFunctionDef ast nodes. docstring is not first stmt in their body +anymore. It affects ``co_firstlineno`` and ``co_lnotab`` of code object for +module and class. (Reverted in :issue:`32911`.) + +.. + +.. bpo: 29438 +.. date: 0427 +.. nonce: IKxD6I +.. section: Core and Builtins + +Fixed use-after-free problem in key sharing dict. + +.. + +.. bpo: 29546 +.. date: 0426 +.. nonce: PS1I1T +.. section: Core and Builtins + +Set the 'path' and 'name' attribute on ImportError for ``from ... import +...``. + +.. + +.. bpo: 29546 +.. date: 0425 +.. nonce: O1rmG_ +.. section: Core and Builtins + +Improve from-import error message with location + +.. + +.. bpo: 29478 +.. date: 0424 +.. nonce: rTQ-qy +.. section: Core and Builtins + +If max_line_length=None is specified while using the Compat32 policy, it is +no longer ignored. Patch by Mircea Cosbuc. + +.. + +.. bpo: 29319 +.. date: 0423 +.. nonce: KLDUZf +.. section: Core and Builtins + +Prevent RunMainFromImporter overwriting sys.path[0]. + +.. + +.. bpo: 29337 +.. date: 0422 +.. nonce: bjX8AE +.. section: Core and Builtins + +Fixed possible BytesWarning when compare the code objects. Warnings could be +emitted at compile time. + +.. + +.. bpo: 29327 +.. date: 0421 +.. nonce: XXQarW +.. section: Core and Builtins + +Fixed a crash when pass the iterable keyword argument to sorted(). + +.. + +.. bpo: 29034 +.. date: 0420 +.. nonce: 7-uEDT +.. section: Core and Builtins + +Fix memory leak and use-after-free in os module (path_converter). + +.. + +.. bpo: 29159 +.. date: 0419 +.. nonce: gEn_kP +.. section: Core and Builtins + +Fix regression in bytes(x) when x.__index__() raises Exception. + +.. + +.. bpo: 29049 +.. date: 0418 +.. nonce: KpVXBw +.. section: Core and Builtins + +Call _PyObject_GC_TRACK() lazily when calling Python function. Calling +function is up to 5% faster. + +.. + +.. bpo: 28927 +.. date: 0417 +.. nonce: 9fxf6y +.. section: Core and Builtins + +bytes.fromhex() and bytearray.fromhex() now ignore all ASCII whitespace, not +only spaces. Patch by Robert Xiao. + +.. + +.. bpo: 28932 +.. date: 0416 +.. nonce: QnLx8A +.. section: Core and Builtins + +Do not include <sys/random.h> if it does not exist. + +.. + +.. bpo: 25677 +.. date: 0415 +.. nonce: RWhZrb +.. section: Core and Builtins + +Correct the positioning of the syntax error caret for indented blocks. Based +on patch by Michael Layzell. + +.. + +.. bpo: 29000 +.. date: 0414 +.. nonce: K6wQ-3 +.. section: Core and Builtins + +Fixed bytes formatting of octals with zero padding in alternate form. + +.. + +.. bpo: 18896 +.. date: 0413 +.. nonce: Pqe0bg +.. section: Core and Builtins + +Python function can now have more than 255 parameters. +collections.namedtuple() now supports tuples with more than 255 elements. + +.. + +.. bpo: 28596 +.. date: 0412 +.. nonce: snIJRd +.. section: Core and Builtins + +The preferred encoding is UTF-8 on Android. Patch written by Chi Hsuan Yen. + +.. + +.. bpo: 22257 +.. date: 0411 +.. nonce: 2a8zxB +.. section: Core and Builtins + +Clean up interpreter startup (see :pep:`432`). + +.. + +.. bpo: 26919 +.. date: 0410 +.. nonce: Cm7MSa +.. section: Core and Builtins + +On Android, operating system data is now always encoded/decoded to/from +UTF-8, instead of the locale encoding to avoid inconsistencies with +os.fsencode() and os.fsdecode() which are already using UTF-8. + +.. + +.. bpo: 28991 +.. date: 0409 +.. nonce: lGA0FK +.. section: Core and Builtins + +functools.lru_cache() was susceptible to an obscure reentrancy bug +triggerable by a monkey-patched len() function. + +.. + +.. bpo: 28147 +.. date: 0408 +.. nonce: CnK_xf +.. section: Core and Builtins + +Fix a memory leak in split-table dictionaries: setattr() must not convert +combined table into split table. Patch written by INADA Naoki. + +.. + +.. bpo: 28739 +.. date: 0407 +.. nonce: w1fvhk +.. section: Core and Builtins + +f-string expressions are no longer accepted as docstrings and by +ast.literal_eval() even if they do not include expressions. + +.. + +.. bpo: 28512 +.. date: 0406 +.. nonce: i-pv6d +.. section: Core and Builtins + +Fixed setting the offset attribute of SyntaxError by +PyErr_SyntaxLocationEx() and PyErr_SyntaxLocationObject(). + +.. + +.. bpo: 28918 +.. date: 0405 +.. nonce: SFVuPz +.. section: Core and Builtins + +Fix the cross compilation of xxlimited when Python has been built with +Py_DEBUG defined. + +.. + +.. bpo: 23722 +.. date: 0404 +.. nonce: e8BH5h +.. section: Core and Builtins + +Rather than silently producing a class that doesn't support zero-argument +``super()`` in methods, failing to pass the new ``__classcell__`` namespace +entry up to ``type.__new__`` now results in a ``DeprecationWarning`` and a +class that supports zero-argument ``super()``. + +.. + +.. bpo: 28797 +.. date: 0403 +.. nonce: _A0_Z5 +.. section: Core and Builtins + +Modifying the class __dict__ inside the __set_name__ method of a descriptor +that is used inside that class no longer prevents calling the __set_name__ +method of other descriptors. + +.. + +.. bpo: 28799 +.. date: 0402 +.. nonce: cP6V1N +.. section: Core and Builtins + +Remove the ``PyEval_GetCallStats()`` function and deprecate the untested and +undocumented ``sys.callstats()`` function. Remove the ``CALL_PROFILE`` +special build: use the :func:`sys.setprofile` function, :mod:`cProfile` or +:mod:`profile` to profile function calls. + +.. + +.. bpo: 12844 +.. date: 0401 +.. nonce: pdr3gY +.. section: Core and Builtins + +More than 255 arguments can now be passed to a function. + +.. + +.. bpo: 28782 +.. date: 0400 +.. nonce: foJV_E +.. section: Core and Builtins + +Fix a bug in the implementation ``yield from`` when checking if the next +instruction is YIELD_FROM. Regression introduced by WORDCODE (issue #26647). + +.. + +.. bpo: 28774 +.. date: 0399 +.. nonce: cEehAr +.. section: Core and Builtins + +Fix error position of the unicode error in ASCII and Latin1 encoders when a +string returned by the error handler contains multiple non-encodable +characters (non-ASCII for the ASCII codec, characters out of the +U+0000-U+00FF range for Latin1). + +.. + +.. bpo: 28731 +.. date: 0398 +.. nonce: oNF59u +.. section: Core and Builtins + +Optimize _PyDict_NewPresized() to create correct size dict. Improve speed of +dict literal with constant keys up to 30%. + +.. + +.. bpo: 28532 +.. date: 0397 +.. nonce: KEYJny +.. section: Core and Builtins + +Show sys.version when -V option is supplied twice. + +.. + +.. bpo: 27100 +.. date: 0396 +.. nonce: poVjXq +.. section: Core and Builtins + +The with-statement now checks for __enter__ before it checks for __exit__. +This gives less confusing error messages when both methods are missing. +Patch by Jonathan Ellington. + +.. + +.. bpo: 28746 +.. date: 0395 +.. nonce: r5MXdB +.. section: Core and Builtins + +Fix the set_inheritable() file descriptor method on platforms that do not +have the ioctl FIOCLEX and FIONCLEX commands. + +.. + +.. bpo: 26920 +.. date: 0394 +.. nonce: 1URwGb +.. section: Core and Builtins + +Fix not getting the locale's charset upon initializing the interpreter, on +platforms that do not have langinfo. + +.. + +.. bpo: 28648 +.. date: 0393 +.. nonce: z7B52W +.. section: Core and Builtins + +Fixed crash in Py_DecodeLocale() in debug build on Mac OS X when decode +astral characters. Patch by Xiang Zhang. + +.. + +.. bpo: 28665 +.. date: 0392 +.. nonce: v4nx86 +.. section: Core and Builtins + +Improve speed of the STORE_DEREF opcode by 40%. + +.. + +.. bpo: 19398 +.. date: 0391 +.. nonce: RYbEGH +.. section: Core and Builtins + +Extra slash no longer added to sys.path components in case of empty +compile-time PYTHONPATH components. + +.. + +.. bpo: 28621 +.. date: 0390 +.. nonce: eCD7n- +.. section: Core and Builtins + +Sped up converting int to float by reusing faster bits counting +implementation. Patch by Adrian Wielgosik. + +.. + +.. bpo: 28580 +.. date: 0389 +.. nonce: 8bqBmG +.. section: Core and Builtins + +Optimize iterating split table values. Patch by Xiang Zhang. + +.. + +.. bpo: 28583 +.. date: 0388 +.. nonce: F-QAx1 +.. section: Core and Builtins + +PyDict_SetDefault didn't combine split table when needed. Patch by Xiang +Zhang. + +.. + +.. bpo: 28128 +.. date: 0387 +.. nonce: Lc2sFu +.. section: Core and Builtins + +Deprecation warning for invalid str and byte escape sequences now prints +better information about where the error occurs. Patch by Serhiy Storchaka +and Eric Smith. + +.. + +.. bpo: 28509 +.. date: 0386 +.. nonce: _Fa4Uq +.. section: Core and Builtins + +dict.update() no longer allocate unnecessary large memory. + +.. + +.. bpo: 28426 +.. date: 0385 +.. nonce: E_quyK +.. section: Core and Builtins + +Fixed potential crash in PyUnicode_AsDecodedObject() in debug build. + +.. + +.. bpo: 28517 +.. date: 0384 +.. nonce: ExPkm9 +.. section: Core and Builtins + +Fixed of-by-one error in the peephole optimizer that caused keeping +unreachable code. + +.. + +.. bpo: 28214 +.. date: 0383 +.. nonce: 6ECJox +.. section: Core and Builtins + +Improved exception reporting for problematic __set_name__ attributes. + +.. + +.. bpo: 23782 +.. date: 0382 +.. nonce: lonDzj +.. section: Core and Builtins + +Fixed possible memory leak in _PyTraceback_Add() and exception loss in +PyTraceBack_Here(). + +.. + +.. bpo: 28183 +.. date: 0381 +.. nonce: MJZeNd +.. section: Core and Builtins + +Optimize and cleanup dict iteration. + +.. + +.. bpo: 26081 +.. date: 0380 +.. nonce: _x5vjl +.. section: Core and Builtins + +Added C implementation of asyncio.Future. Original patch by Yury Selivanov. + +.. + +.. bpo: 28379 +.. date: 0379 +.. nonce: DuXlco +.. section: Core and Builtins + +Added sanity checks and tests for PyUnicode_CopyCharacters(). Patch by Xiang +Zhang. + +.. + +.. bpo: 28376 +.. date: 0378 +.. nonce: oPD-5D +.. section: Core and Builtins + +The type of long range iterator is now registered as Iterator. Patch by Oren +Milman. + +.. + +.. bpo: 28376 +.. date: 0377 +.. nonce: yTEhEo +.. section: Core and Builtins + +Creating instances of range_iterator by calling range_iterator type now is +disallowed. Calling iter() on range instance is the only way. Patch by Oren +Milman. + +.. + +.. bpo: 26906 +.. date: 0376 +.. nonce: YBjcwI +.. section: Core and Builtins + +Resolving special methods of uninitialized type now causes implicit +initialization of the type instead of a fail. + +.. + +.. bpo: 18287 +.. date: 0375 +.. nonce: k6jffS +.. section: Core and Builtins + +PyType_Ready() now checks that tp_name is not NULL. Original patch by Niklas +Koep. + +.. + +.. bpo: 24098 +.. date: 0374 +.. nonce: XqlP_1 +.. section: Core and Builtins + +Fixed possible crash when AST is changed in process of compiling it. + +.. + +.. bpo: 28201 +.. date: 0373 +.. nonce: GWUxAy +.. section: Core and Builtins + +Dict reduces possibility of 2nd conflict in hash table when hashes have same +lower bits. + +.. + +.. bpo: 28350 +.. date: 0372 +.. nonce: 8M5Eg9 +.. section: Core and Builtins + +String constants with null character no longer interned. + +.. + +.. bpo: 26617 +.. date: 0371 +.. nonce: Gh5LvN +.. section: Core and Builtins + +Fix crash when GC runs during weakref callbacks. + +.. + +.. bpo: 27942 +.. date: 0370 +.. nonce: ZGuhns +.. section: Core and Builtins + +String constants now interned recursively in tuples and frozensets. + +.. + +.. bpo: 28289 +.. date: 0369 +.. nonce: l1kHlV +.. section: Core and Builtins + +ImportError.__init__ now resets not specified attributes. + +.. + +.. bpo: 21578 +.. date: 0368 +.. nonce: GI1bhj +.. section: Core and Builtins + +Fixed misleading error message when ImportError called with invalid keyword +args. + +.. + +.. bpo: 28203 +.. date: 0367 +.. nonce: LRn5vp +.. section: Core and Builtins + +Fix incorrect type in complex(1.0, {2:3}) error message. Patch by Soumya +Sharma. + +.. + +.. bpo: 28086 +.. date: 0366 +.. nonce: JsQPMQ +.. section: Core and Builtins + +Single var-positional argument of tuple subtype was passed unscathed to the +C-defined function. Now it is converted to exact tuple. + +.. + +.. bpo: 28214 +.. date: 0365 +.. nonce: zQF8Em +.. section: Core and Builtins + +Now __set_name__ is looked up on the class instead of the instance. + +.. + +.. bpo: 27955 +.. date: 0364 +.. nonce: HC4pZ4 +.. section: Core and Builtins + +Fallback on reading /dev/urandom device when the getrandom() syscall fails +with EPERM, for example when blocked by SECCOMP. + +.. + +.. bpo: 28192 +.. date: 0363 +.. nonce: eR6stU +.. section: Core and Builtins + +Don't import readline in isolated mode. + +.. + +.. bpo: 27441 +.. date: 0362 +.. nonce: scPKax +.. section: Core and Builtins + +Remove some redundant assignments to ob_size in longobject.c. Thanks Oren +Milman. + +.. + +.. bpo: 27222 +.. date: 0361 +.. nonce: 74PvFk +.. section: Core and Builtins + +Clean up redundant code in long_rshift function. Thanks Oren Milman. + +.. + +.. bpo: 0 +.. date: 0360 +.. nonce: 9EbOiD +.. section: Core and Builtins + +Upgrade internal unicode databases to Unicode version 9.0.0. + +.. + +.. bpo: 28131 +.. date: 0359 +.. nonce: owq0wW +.. section: Core and Builtins + +Fix a regression in zipimport's compile_source(). zipimport should use the +same optimization level as the interpreter. + +.. + +.. bpo: 28126 +.. date: 0358 +.. nonce: Qf6-uQ +.. section: Core and Builtins + +Replace Py_MEMCPY with memcpy(). Visual Studio can properly optimize +memcpy(). + +.. + +.. bpo: 28120 +.. date: 0357 +.. nonce: e5xc1i +.. section: Core and Builtins + +Fix dict.pop() for splitted dictionary when trying to remove a "pending key" +(Not yet inserted in split-table). Patch by Xiang Zhang. + +.. + +.. bpo: 26182 +.. date: 0356 +.. nonce: jYlqTO +.. section: Core and Builtins + +Raise DeprecationWarning when async and await keywords are used as +variable/attribute/class/function name. + +.. + +.. bpo: 26182 +.. date: 0355 +.. nonce: a8JXK2 +.. section: Core and Builtins + +Fix a refleak in code that raises DeprecationWarning. + +.. + +.. bpo: 28721 +.. date: 0354 +.. nonce: BO9BUF +.. section: Core and Builtins + +Fix asynchronous generators aclose() and athrow() to handle +StopAsyncIteration propagation properly. + +.. + +.. bpo: 26110 +.. date: 0353 +.. nonce: KRaID6 +.. section: Core and Builtins + +Speed-up method calls: add LOAD_METHOD and CALL_METHOD opcodes. + +.. + +.. bpo: 31499 +.. date: 2017-09-18-10-57-04 +.. nonce: BydYhf +.. section: Library + +xml.etree: Fix a crash when a parser is part of a reference cycle. + +.. + +.. bpo: 31482 +.. date: 2017-09-16-01-53-11 +.. nonce: 39s5dS +.. section: Library + +``random.seed()`` now works with bytes in version=1 + +.. + +.. bpo: 28556 +.. date: 2017-09-14-11-02-56 +.. nonce: EUOiYs +.. section: Library + +typing.get_type_hints now finds the right globalns for classes and modules +by default (when no ``globalns`` was specified by the caller). + +.. + +.. bpo: 28556 +.. date: 2017-09-13-23-27-39 +.. nonce: UmTQvv +.. section: Library + +Speed improvements to the ``typing`` module. Original PRs by Ivan +Levkivskyi and Mitar. + +.. + +.. bpo: 31544 +.. date: 2017-09-13-19-55-35 +.. nonce: beTh6t +.. section: Library + +The C accelerator module of ElementTree ignored exceptions raised when +looking up TreeBuilder target methods in XMLParser(). + +.. + +.. bpo: 31234 +.. date: 2017-09-13-18-05-56 +.. nonce: lGkcPg +.. section: Library + +socket.create_connection() now fixes manually a reference cycle: clear the +variable storing the last exception on success. + +.. + +.. bpo: 31457 +.. date: 2017-09-13-13-33-39 +.. nonce: bIVBtI +.. section: Library + +LoggerAdapter objects can now be nested. + +.. + +.. bpo: 31431 +.. date: 2017-09-13-07-37-20 +.. nonce: dj994R +.. section: Library + +SSLContext.check_hostname now automatically sets SSLContext.verify_mode to +ssl.CERT_REQUIRED instead of failing with a ValueError. + +.. + +.. bpo: 31233 +.. date: 2017-09-13-02-17-11 +.. nonce: r-IPIu +.. section: Library + +socketserver.ThreadingMixIn now keeps a list of non-daemonic threads to wait +until all these threads complete in server_close(). + +.. + +.. bpo: 28638 +.. date: 2017-09-08-14-31-15 +.. nonce: lfbVyH +.. section: Library + +Changed the implementation strategy for collections.namedtuple() to +substantially reduce the use of exec() in favor of precomputed methods. As a +result, the *verbose* parameter and *_source* attribute are no longer +supported. The benefits include 1) having a smaller memory footprint for +applications using multiple named tuples, 2) faster creation of the named +tuple class (approx 4x to 6x depending on how it is measured), and 3) minor +speed-ups for instance creation using __new__, _make, and _replace. (The +primary patch contributor is Jelle Zijlstra with further improvements by +INADA Naoki, Serhiy Storchaka, and Raymond Hettinger.) + +.. + +.. bpo: 31400 +.. date: 2017-09-08-14-19-57 +.. nonce: YOTPKi +.. section: Library + +Improves SSL error handling to avoid losing error numbers. + +.. + +.. bpo: 27629 +.. date: 2017-09-07-12-15-56 +.. nonce: 7xJXEy +.. section: Library + +Make return types of SSLContext.wrap_bio() and SSLContext.wrap_socket() +customizable. + +.. + +.. bpo: 28958 +.. date: 2017-09-06-19-41-01 +.. nonce: x4-K5F +.. section: Library + +ssl.SSLContext() now uses OpenSSL error information when a context cannot be +instantiated. + +.. + +.. bpo: 28182 +.. date: 2017-09-06-18-49-16 +.. nonce: hRP8Bk +.. section: Library + +The SSL module now raises SSLCertVerificationError when OpenSSL fails to +verify the peer's certificate. The exception contains more information about +the error. + +.. + +.. bpo: 27340 +.. date: 2017-09-06-06-50-41 +.. nonce: GgekV5 +.. section: Library + +SSLSocket.sendall() now uses memoryview to create slices of data. This fixes +support for all bytes-like object. It is also more efficient and avoids +costly copies. + +.. + +.. bpo: 14191 +.. date: 2017-09-05-17-43-00 +.. nonce: vhh2xx +.. section: Library + +A new function ``argparse.ArgumentParser.parse_intermixed_args`` provides +the ability to parse command lines where there user intermixes options and +positional arguments. + +.. + +.. bpo: 31178 +.. date: 2017-09-05-14-55-28 +.. nonce: JrSFo7 +.. section: Library + +Fix string concatenation bug in rare error path in the subprocess module + +.. + +.. bpo: 31350 +.. date: 2017-09-05-10-30-48 +.. nonce: dXJ-7N +.. section: Library + +Micro-optimize :func:`asyncio._get_running_loop` to become up to 10% faster. + +.. + +.. bpo: 31170 +.. date: 2017-09-04-23-41-35 +.. nonce: QGmJ1t +.. section: Library + +expat: Update libexpat from 2.2.3 to 2.2.4. Fix copying of partial +characters for UTF-8 input (libexpat bug 115): +https://github.com/libexpat/libexpat/issues/115 + +.. + +.. bpo: 29136 +.. date: 2017-09-04-16-39-49 +.. nonce: vSn1oR +.. section: Library + +Add TLS 1.3 cipher suites and OP_NO_TLSv1_3. + +.. + +.. bpo: 1198569 +.. date: 2017-09-04-10-53-06 +.. nonce: vhh2nY +.. section: Library + +``string.Template`` subclasses can optionally define ``braceidpattern`` if +they want to specify different placeholder patterns inside and outside the +braces. If None (the default) it falls back to ``idpattern``. + +.. + +.. bpo: 31326 +.. date: 2017-09-01-18-48-06 +.. nonce: TB05tV +.. section: Library + +concurrent.futures.ProcessPoolExecutor.shutdown() now explicitly closes the +call queue. Moreover, shutdown(wait=True) now also join the call queue +thread, to prevent leaking a dangling thread. + +.. + +.. bpo: 27144 +.. date: 2017-08-30-11-26-14 +.. nonce: PEDJsE +.. section: Library + +The ``map()`` and ``as_completed()`` iterators in ``concurrent.futures`` now +avoid keeping a reference to yielded objects. + +.. + +.. bpo: 31281 +.. date: 2017-08-29-07-14-14 +.. nonce: DcFyNs +.. section: Library + +Fix ``fileinput.FileInput(files, inplace=True)`` when ``files`` contain +``pathlib.Path`` objects. + +.. + +.. bpo: 10746 +.. date: 2017-08-28-13-01-05 +.. nonce: nmAvfu +.. section: Library + +Fix ctypes producing wrong :pep:`3118` type codes for integer types. + +.. + +.. bpo: 27584 +.. date: 2017-08-24-14-03-14 +.. nonce: r11JHZ +.. section: Library + +``AF_VSOCK`` has been added to the socket interface which allows +communication between virtual machines and their host. + +.. + +.. bpo: 22536 +.. date: 2017-08-23 +.. nonce: _narf_ +.. section: Library + +The subprocess module now sets the filename when FileNotFoundError is raised +on POSIX systems due to the executable or cwd not being found. + +.. + +.. bpo: 29741 +.. date: 2017-08-23-00-31-32 +.. nonce: EBn_DM +.. section: Library + +Update some methods in the _pyio module to also accept integer types. Patch +by Oren Milman. + +.. + +.. bpo: 31249 +.. date: 2017-08-22-12-44-48 +.. nonce: STPbb9 +.. section: Library + +concurrent.futures: WorkItem.run() used by ThreadPoolExecutor now breaks a +reference cycle between an exception object and the WorkItem object. + +.. + +.. bpo: 31247 +.. date: 2017-08-21-17-50-27 +.. nonce: 8S3zJp +.. section: Library + +xmlrpc.server now explicitly breaks reference cycles when using +sys.exc_info() in code handling exceptions. + +.. + +.. bpo: 23835 +.. date: 2017-08-21-16-06-19 +.. nonce: da_4Kz +.. section: Library + +configparser: reading defaults in the ``ConfigParser()`` constructor is now +using ``read_dict()``, making its behavior consistent with the rest of the +parser. Non-string keys and values in the defaults dictionary are now being +implicitly converted to strings. Patch by James Tocknell. + +.. + +.. bpo: 31238 +.. date: 2017-08-21-12-31-53 +.. nonce: Gg0LRH +.. section: Library + +pydoc: the stop() method of the private ServerThread class now waits until +DocServer.serve_until_quit() completes and then explicitly sets its +docserver attribute to None to break a reference cycle. + +.. + +.. bpo: 5001 +.. date: 2017-08-18-17-16-38 +.. nonce: gwnthq +.. section: Library + +Many asserts in `multiprocessing` are now more informative, and some error +types have been changed to more specific ones. + +.. + +.. bpo: 31109 +.. date: 2017-08-17-20-29-45 +.. nonce: 7qtC64 +.. section: Library + +Convert zipimport to use Argument Clinic. + +.. + +.. bpo: 30102 +.. date: 2017-08-16-21-14-31 +.. nonce: 1sPqmc +.. section: Library + +The ssl and hashlib modules now call OPENSSL_add_all_algorithms_noconf() on +OpenSSL < 1.1.0. The function detects CPU features and enables optimizations +on some CPU architectures such as POWER8. Patch is based on research from +Gustavo Serra Scalet. + +.. + +.. bpo: 18966 +.. date: 2017-08-16-20-28-06 +.. nonce: mjHWk2 +.. section: Library + +Non-daemonic threads created by a multiprocessing.Process are now joined on +child exit. + +.. + +.. bpo: 31183 +.. date: 2017-08-13-09-17-01 +.. nonce: -2_YGj +.. section: Library + +`dis` now works with asynchronous generator and coroutine objects. Patch by +George Collins based on diagnosis by Luciano Ramalho. + +.. + +.. bpo: 5001 +.. date: 2017-08-12-09-25-55 +.. nonce: huQi2Y +.. section: Library + +There are a number of uninformative asserts in the `multiprocessing` module, +as noted in issue 5001. This change fixes two of the most potentially +problematic ones, since they are in error-reporting code, in the +`multiprocessing.managers.convert_to_error` function. (It also makes more +informative a ValueError message.) The only potentially problematic change +is that the AssertionError is now a TypeError; however, this should also +help distinguish it from an AssertionError being *reported* by the +function/its caller (such as in issue 31169). - Patch by Allen W. Smith +(drallensmith on github). + +.. + +.. bpo: 31185 +.. date: 2017-08-11-19-30-00 +.. nonce: i6TPgL +.. section: Library + +Fixed miscellaneous errors in asyncio speedup module. + +.. + +.. bpo: 31151 +.. date: 2017-08-10-13-20-02 +.. nonce: 730VBI +.. section: Library + +socketserver.ForkingMixIn.server_close() now waits until all child processes +completed to prevent leaking zombie processes. + +.. + +.. bpo: 31072 +.. date: 2017-08-09-13-45-23 +.. nonce: NLXDPV +.. section: Library + +Add an ``include_file`` parameter to ``zipapp.create_archive()`` + +.. + +.. bpo: 24700 +.. date: 2017-08-08-15-14-34 +.. nonce: 44mvNV +.. section: Library + +Optimize array.array comparison. It is now from 10x up to 70x faster when +comparing arrays holding values of the same integer type. + +.. + +.. bpo: 31135 +.. date: 2017-08-08-14-44-37 +.. nonce: HH94xR +.. section: Library + +ttk: fix the destroy() method of LabeledScale and OptionMenu classes. Call +the parent destroy() method even if the used attribute doesn't exist. The +LabeledScale.destroy() method now also explicitly clears label and scale +attributes to help the garbage collector to destroy all widgets. + +.. + +.. bpo: 31107 +.. date: 2017-08-02-12-48-15 +.. nonce: 1t2hn5 +.. section: Library + +Fix `copyreg._slotnames()` mangled attribute calculation for classes whose +name begins with an underscore. Patch by Shane Harvey. + +.. + +.. bpo: 31080 +.. date: 2017-08-01-18-26-55 +.. nonce: 2CFVCO +.. section: Library + +Allow `logging.config.fileConfig` to accept kwargs and/or args. + +.. + +.. bpo: 30897 +.. date: 2017-08-01-15-56-50 +.. nonce: OuT1-Y +.. section: Library + +``pathlib.Path`` objects now include an ``is_mount()`` method (only +implemented on POSIX). This is similar to ``os.path.ismount(p)``. Patch by +Cooper Ry Lees. + +.. + +.. bpo: 31061 +.. date: 2017-08-01-09-32-58 +.. nonce: husAYX +.. section: Library + +Fixed a crash when using asyncio and threads. + +.. + +.. bpo: 30987 +.. date: 2017-07-30-22-00-12 +.. nonce: 228rW0 +.. section: Library + +Added support for CAN ISO-TP protocol in the socket module. + +.. + +.. bpo: 30522 +.. date: 2017-07-30-10-07-58 +.. nonce: gAX1N- +.. section: Library + +Added a ``setStream`` method to ``logging.StreamHandler`` to allow the +stream to be set after creation. + +.. + +.. bpo: 30502 +.. date: 2017-07-27-11-33-58 +.. nonce: GJlfU8 +.. section: Library + +Fix handling of long oids in ssl. Based on patch by Christian Heimes. + +.. + +.. bpo: 5288 +.. date: 2017-07-26-13-18-29 +.. nonce: o_xEGj +.. section: Library + +Support tzinfo objects with sub-minute offsets. + +.. + +.. bpo: 30919 +.. date: 2017-07-23-11-33-10 +.. nonce: 5dYRru +.. section: Library + +Fix shared memory performance regression in multiprocessing in 3.x. +Shared memory used anonymous memory mappings in 2.x, while 3.x mmaps actual +files. Try to be careful to do as little disk I/O as possible. + +.. + +.. bpo: 26732 +.. date: 2017-07-22-12-12-42 +.. nonce: lYLWBH +.. section: Library + +Fix too many fds in processes started with the "forkserver" method. +A child process would inherit as many fds as the number of still-running +children. + +.. + +.. bpo: 29403 +.. date: 2017-07-20-02-29-49 +.. nonce: 3RinCV +.. section: Library + +Fix ``unittest.mock``'s autospec to not fail on method-bound builtin +functions. Patch by Aaron Gallagher. + +.. + +.. bpo: 30961 +.. date: 2017-07-18-23-47-51 +.. nonce: 064jz0 +.. section: Library + +Fix decrementing a borrowed reference in tracemalloc. + +.. + +.. bpo: 19896 +.. date: 2017-07-18-13-24-50 +.. nonce: -S0IWu +.. section: Library + +Fix multiprocessing.sharedctypes to recognize typecodes ``'q'`` and ``'Q'``. + +.. + +.. bpo: 30946 +.. date: 2017-07-17-12-32-47 +.. nonce: DUo-uA +.. section: Library + +Remove obsolete code in readline module for platforms where GNU readline is +older than 2.1 or where select() is not available. + +.. + +.. bpo: 25684 +.. date: 2017-07-17-11-35-00 +.. nonce: usELVx +.. section: Library + +Change ``ttk.OptionMenu`` radiobuttons to be unique across instances of +``OptionMenu``. + +.. + +.. bpo: 30886 +.. date: 2017-07-10-12-14-22 +.. nonce: nqQj34 +.. section: Library + +Fix multiprocessing.Queue.join_thread(): it now waits until the thread +completes, even if the thread was started by the same process which created +the queue. + +.. + +.. bpo: 29854 +.. date: 2017-07-07-02-18-57 +.. nonce: J8wKb_ +.. section: Library + +Fix segfault in readline when using readline's history-size option. Patch +by Nir Soffer. + +.. + +.. bpo: 30794 +.. date: 2017-07-04-22-00-20 +.. nonce: qFwozm +.. section: Library + +Added multiprocessing.Process.kill method to terminate using the SIGKILL +signal on Unix. + +.. + +.. bpo: 30319 +.. date: 2017-07-04-13-48-21 +.. nonce: hg_3TX +.. section: Library + +socket.close() now ignores ECONNRESET error. + +.. + +.. bpo: 30828 +.. date: 2017-07-04-13-10-52 +.. nonce: CLvEvV +.. section: Library + +Fix out of bounds write in `asyncio.CFuture.remove_done_callback()`. + +.. + +.. bpo: 30302 +.. date: 2017-06-30-23-05-47 +.. nonce: itwK_k +.. section: Library + +Use keywords in the ``repr`` of ``datetime.timedelta``. + +.. + +.. bpo: 30807 +.. date: 2017-06-29-22-04-44 +.. nonce: sLtjY- +.. section: Library + +signal.setitimer() may disable the timer when passed a tiny value. +Tiny values (such as 1e-6) are valid non-zero values for setitimer(), which +is specified as taking microsecond-resolution intervals. However, on some +platform, our conversion routine could convert 1e-6 into a zero interval, +therefore disabling the timer instead of (re-)scheduling it. + +.. + +.. bpo: 30441 +.. date: 2017-06-29-14-25-14 +.. nonce: 3Wh9kc +.. section: Library + +Fix bug when modifying os.environ while iterating over it + +.. + +.. bpo: 29585 +.. date: 2017-06-29-00-17-38 +.. nonce: x2V0my +.. section: Library + +Avoid importing ``sysconfig`` from ``site`` to improve startup speed. Python +startup is about 5% faster on Linux and 30% faster on macOS. + +.. + +.. bpo: 29293 +.. date: 2017-06-29-00-07-22 +.. nonce: Z6WZjD +.. section: Library + +Add missing parameter "n" on multiprocessing.Condition.notify(). +The doc claims multiprocessing.Condition behaves like threading.Condition, +but its notify() method lacked the optional "n" argument (to specify the +number of sleepers to wake up) that threading.Condition.notify() accepts. + +.. + +.. bpo: 30532 +.. date: 2017-06-26-11-01-59 +.. nonce: qTeL1o +.. section: Library + +Fix email header value parser dropping folding white space in certain cases. + +.. + +.. bpo: 30596 +.. date: 2017-06-24-18-55-58 +.. nonce: VhB8iG +.. section: Library + +Add a ``close()`` method to ``multiprocessing.Process``. + +.. + +.. bpo: 9146 +.. date: 2017-05-24-00-00-00 +.. nonce: pinky_ +.. section: Library + +Fix a segmentation fault in _hashopenssl when standard hash functions such +as md5 are not available in the linked OpenSSL library. As in some special +FIPS-140 build environments. + +.. + +.. bpo: 29169 +.. date: 0352 +.. nonce: 8ypApm +.. section: Library + +Update zlib to 1.2.11. + +.. + +.. bpo: 30119 +.. date: 0351 +.. nonce: 4UMLNh +.. section: Library + +ftplib.FTP.putline() now throws ValueError on commands that contains CR or +LF. Patch by Donghee Na. + +.. + +.. bpo: 30879 +.. date: 0350 +.. nonce: N3KI-o +.. section: Library + +os.listdir() and os.scandir() now emit bytes names when called with +bytes-like argument. + +.. + +.. bpo: 30746 +.. date: 0349 +.. nonce: 7drQI0 +.. section: Library + +Prohibited the '=' character in environment variable names in +``os.putenv()`` and ``os.spawn*()``. + +.. + +.. bpo: 30664 +.. date: 0348 +.. nonce: oyqiUl +.. section: Library + +The description of a unittest subtest now preserves the order of keyword +arguments of TestCase.subTest(). + +.. + +.. bpo: 21071 +.. date: 0346 +.. nonce: Sw37rs +.. section: Library + +struct.Struct.format type is now :class:`str` instead of :class:`bytes`. + +.. + +.. bpo: 29212 +.. date: 0345 +.. nonce: HmTdef +.. section: Library + +Fix concurrent.futures.thread.ThreadPoolExecutor threads to have a non +repr() based thread name by default when no thread_name_prefix is supplied. +They will now identify themselves as "ThreadPoolExecutor-y_n". + +.. + +.. bpo: 29755 +.. date: 0343 +.. nonce: diQcY_ +.. section: Library + +Fixed the lgettext() family of functions in the gettext module. They now +always return bytes. + +.. + +.. bpo: 30616 +.. date: 0341 +.. nonce: I2mDTz +.. section: Library + +Functional API of enum allows to create empty enums. Patched by Donghee Na + +.. + +.. bpo: 30038 +.. date: 0340 +.. nonce: vb4DWk +.. section: Library + +Fix race condition between signal delivery and wakeup file descriptor. Patch +by Nathaniel Smith. + +.. + +.. bpo: 23894 +.. date: 0339 +.. nonce: k2pADV +.. section: Library + +lib2to3 now recognizes ``rb'...'`` and ``f'...'`` strings. + +.. + +.. bpo: 24744 +.. date: 0337 +.. nonce: NKxUj3 +.. section: Library + +pkgutil.walk_packages function now raises ValueError if *path* is a string. +Patch by Sanyam Khurana. + +.. + +.. bpo: 24484 +.. date: 0336 +.. nonce: vFem8K +.. section: Library + +Avoid race condition in multiprocessing cleanup. + +.. + +.. bpo: 30589 +.. date: 0335 +.. nonce: xyZGM0 +.. section: Library + +Fix multiprocessing.Process.exitcode to return the opposite of the signal +number when the process is killed by a signal (instead of 255) when using +the "forkserver" method. + +.. + +.. bpo: 28994 +.. date: 0334 +.. nonce: 9vzun1 +.. section: Library + +The traceback no longer displayed for SystemExit raised in a callback +registered by atexit. + +.. + +.. bpo: 30508 +.. date: 0333 +.. nonce: wNWRS2 +.. section: Library + +Don't log exceptions if Task/Future "cancel()" method was called. + +.. + +.. bpo: 30645 +.. date: 0332 +.. nonce: xihJ4Y +.. section: Library + +Fix path calculation in `imp.load_package()`, fixing it for cases when a +package is only shipped with bytecodes. Patch by Alexandru Ardelean. + +.. + +.. bpo: 11822 +.. date: 0331 +.. nonce: GQmKw3 +.. section: Library + +The dis.dis() function now is able to disassemble nested code objects. + +.. + +.. bpo: 30624 +.. date: 0330 +.. nonce: g5oVSn +.. section: Library + +selectors does not take KeyboardInterrupt and SystemExit into account, +leaving a fd in a bad state in case of error. Patch by Giampaolo Rodola'. + +.. + +.. bpo: 30595 +.. date: 0329 +.. nonce: d0nRRA +.. section: Library + +multiprocessing.Queue.get() with a timeout now polls its reader in +non-blocking mode if it succeeded to acquire the lock but the acquire took +longer than the timeout. + +.. + +.. bpo: 28556 +.. date: 0328 +.. nonce: mESP7G +.. section: Library + +Updates to typing module: Add generic AsyncContextManager, add support for +ContextManager on all versions. Original PRs by Jelle Zijlstra and Ivan +Levkivskyi + +.. + +.. bpo: 30605 +.. date: 0327 +.. nonce: XqGz1r +.. section: Library + +re.compile() no longer raises a BytesWarning when compiling a bytes instance +with misplaced inline modifier. Patch by Roy Williams. + +.. + +.. bpo: 29870 +.. date: 0326 +.. nonce: p960Ih +.. section: Library + +Fix ssl sockets leaks when connection is aborted in asyncio/ssl +implementation. Patch by Michaël Sghaïer. + +.. + +.. bpo: 29743 +.. date: 0325 +.. nonce: en2P4s +.. section: Library + +Closing transport during handshake process leaks open socket. Patch by +Nikolay Kim + +.. + +.. bpo: 27585 +.. date: 0324 +.. nonce: 0Ugqqu +.. section: Library + +Fix waiter cancellation in asyncio.Lock. Patch by Mathieu Sornay. + +.. + +.. bpo: 30014 +.. date: 0323 +.. nonce: x7Yx6o +.. section: Library + +modify() method of poll(), epoll() and devpoll() based classes of selectors +module is around 10% faster. Patch by Giampaolo Rodola'. + +.. + +.. bpo: 30418 +.. date: 0322 +.. nonce: EwISQm +.. section: Library + +On Windows, subprocess.Popen.communicate() now also ignore EINVAL on +stdin.write() if the child process is still running but closed the pipe. + +.. + +.. bpo: 30463 +.. date: 0321 +.. nonce: CdOuSl +.. section: Library + +Addded empty __slots__ to abc.ABC. This allows subclassers to deny __dict__ +and __weakref__ creation. Patch by Aaron Hall. + +.. + +.. bpo: 30520 +.. date: 0320 +.. nonce: VYzaSn +.. section: Library + +Loggers are now pickleable. + +.. + +.. bpo: 30557 +.. date: 0319 +.. nonce: uykrLf +.. section: Library + +faulthandler now correctly filters and displays exception codes on Windows + +.. + +.. bpo: 30526 +.. date: 0318 +.. nonce: 7zTG30 +.. section: Library + +Add TextIOWrapper.reconfigure() and a TextIOWrapper.write_through attribute. + +.. + +.. bpo: 30245 +.. date: 0317 +.. nonce: Xoa_8Y +.. section: Library + +Fix possible overflow when organize struct.pack_into error message. Patch +by Yuan Liu. + +.. + +.. bpo: 30378 +.. date: 0316 +.. nonce: R_19_5 +.. section: Library + +Fix the problem that logging.handlers.SysLogHandler cannot handle IPv6 +addresses. + +.. + +.. bpo: 16500 +.. date: 0315 +.. nonce: 9ypo9k +.. section: Library + +Allow registering at-fork handlers. + +.. + +.. bpo: 30470 +.. date: 0314 +.. nonce: wAYhUc +.. section: Library + +Deprecate invalid ctypes call protection on Windows. Patch by Mariatta +Wijaya. + +.. + +.. bpo: 30414 +.. date: 0313 +.. nonce: jGl1Lb +.. section: Library + +multiprocessing.Queue._feed background running thread do not break from main +loop on exception. + +.. + +.. bpo: 30003 +.. date: 0312 +.. nonce: BOl9HE +.. section: Library + +Fix handling escape characters in HZ codec. Based on patch by Ma Lin. + +.. + +.. bpo: 30149 +.. date: 0311 +.. nonce: hE649r +.. section: Library + +inspect.signature() now supports callables with variable-argument parameters +wrapped with partialmethod. Patch by Donghee Na. + +.. + +.. bpo: 30436 +.. date: 0310 +.. nonce: b3zqE7 +.. section: Library + +importlib.find_spec() raises ModuleNotFoundError instead of AttributeError +if the specified parent module is not a package (i.e. lacks a __path__ +attribute). + +.. + +.. bpo: 30301 +.. date: 0309 +.. nonce: ywOkjN +.. section: Library + +Fix AttributeError when using SimpleQueue.empty() under *spawn* and +*forkserver* start methods. + +.. + +.. bpo: 30375 +.. date: 0308 +.. nonce: 9c8qM7 +.. section: Library + +Warnings emitted when compile a regular expression now always point to the +line in the user code. Previously they could point into inners of the re +module if emitted from inside of groups or conditionals. + +.. + +.. bpo: 30329 +.. date: 0307 +.. nonce: EuT36N +.. section: Library + +imaplib and poplib now catch the Windows socket WSAEINVAL error (code 10022) +on shutdown(SHUT_RDWR): An invalid operation was attempted. This error +occurs sometimes on SSL connections. + +.. + +.. bpo: 29196 +.. date: 0306 +.. nonce: qBq9eB +.. section: Library + +Removed previously deprecated in Python 2.4 classes Plist, Dict and +_InternalDict in the plistlib module. Dict values in the result of +functions readPlist() and readPlistFromBytes() are now normal dicts. You no +longer can use attribute access to access items of these dictionaries. + +.. + +.. bpo: 9850 +.. date: 0305 +.. nonce: c6SMxt +.. section: Library + +The :mod:`macpath` is now deprecated and will be removed in Python 3.8. + +.. + +.. bpo: 30299 +.. date: 0304 +.. nonce: O-5d4A +.. section: Library + +Compiling regular expression in debug mode on CPython now displays the +compiled bytecode in human readable form. + +.. + +.. bpo: 30048 +.. date: 0303 +.. nonce: ELRx8R +.. section: Library + +Fixed ``Task.cancel()`` can be ignored when the task is running coroutine +and the coroutine returned without any more ``await``. + +.. + +.. bpo: 30266 +.. date: 0302 +.. nonce: YJzHAH +.. section: Library + +contextlib.AbstractContextManager now supports anti-registration by setting +__enter__ = None or __exit__ = None, following the pattern introduced in +bpo-25958. Patch by Jelle Zijlstra. + +.. + +.. bpo: 30340 +.. date: 0301 +.. nonce: kvtGm- +.. section: Library + +Enhanced regular expressions optimization. This increased the performance of +matching some patterns up to 25 times. + +.. + +.. bpo: 30298 +.. date: 0300 +.. nonce: ZN-bWo +.. section: Library + +Weaken the condition of deprecation warnings for inline modifiers. Now +allowed several subsequential inline modifiers at the start of the pattern +(e.g. ``'(?i)(?s)...'``). In verbose mode whitespaces and comments now are +allowed before and between inline modifiers (e.g. ``'(?x) (?i) (?s)...'``). + +.. + +.. bpo: 30285 +.. date: 0299 +.. nonce: s1vpsO +.. section: Library + +Optimized case-insensitive matching and searching of regular expressions. + +.. + +.. bpo: 29990 +.. date: 0298 +.. nonce: HWV6KE +.. section: Library + +Fix range checking in GB18030 decoder. Original patch by Ma Lin. + +.. + +.. bpo: 29979 +.. date: 0297 +.. nonce: jGBMyE +.. section: Library + +rewrite cgi.parse_multipart, reusing the FieldStorage class and making its +results consistent with those of FieldStorage for multipart/form-data +requests. Patch by Pierre Quentel. + +.. + +.. bpo: 30243 +.. date: 0296 +.. nonce: RHQt0v +.. section: Library + +Removed the __init__ methods of _json's scanner and encoder. Misusing them +could cause memory leaks or crashes. Now scanner and encoder objects are +completely initialized in the __new__ methods. + +.. + +.. bpo: 30215 +.. date: 0295 +.. nonce: SY8738 +.. section: Library + +Compiled regular expression objects with the re.LOCALE flag no longer depend +on the locale at compile time. Only the locale at matching time affects the +result of matching. + +.. + +.. bpo: 30185 +.. date: 0294 +.. nonce: Tiu1n8 +.. section: Library + +Avoid KeyboardInterrupt tracebacks in forkserver helper process when Ctrl-C +is received. + +.. + +.. bpo: 30103 +.. date: 0293 +.. nonce: mmPjf5 +.. section: Library + +binascii.b2a_uu() and uu.encode() now support using ``'`'`` as zero instead +of space. + +.. + +.. bpo: 28556 +.. date: 0292 +.. nonce: 51gjbP +.. section: Library + +Various updates to typing module: add typing.NoReturn type, use +WrapperDescriptorType, minor bug-fixes. Original PRs by Jim +Fasarakis-Hilliard and Ivan Levkivskyi. + +.. + +.. bpo: 30205 +.. date: 0291 +.. nonce: BsxO34 +.. section: Library + +Fix getsockname() for unbound AF_UNIX sockets on Linux. + +.. + +.. bpo: 30228 +.. date: 0290 +.. nonce: nF8Ov4 +.. section: Library + +The seek() and tell() methods of io.FileIO now set the internal seekable +attribute to avoid one syscall on open() (in buffered or text mode). + +.. + +.. bpo: 30190 +.. date: 0289 +.. nonce: 5E7Hyb +.. section: Library + +unittest's assertAlmostEqual and assertNotAlmostEqual provide a better +message in case of failure which includes the difference between left and +right arguments. (patch by Giampaolo Rodola') + +.. + +.. bpo: 30101 +.. date: 0288 +.. nonce: hxUqSL +.. section: Library + +Add support for curses.A_ITALIC. + +.. + +.. bpo: 29822 +.. date: 0287 +.. nonce: G7dX13 +.. section: Library + +inspect.isabstract() now works during __init_subclass__. Patch by Nate +Soares. + +.. + +.. bpo: 29960 +.. date: 0286 +.. nonce: g0wr3r +.. section: Library + +Preserve generator state when _random.Random.setstate() raises an exception. +Patch by Bryan Olson. + +.. + +.. bpo: 30070 +.. date: 0285 +.. nonce: XM_B41 +.. section: Library + +Fixed leaks and crashes in errors handling in the parser module. + +.. + +.. bpo: 22352 +.. date: 0284 +.. nonce: gIQ5qC +.. section: Library + +Column widths in the output of dis.dis() are now adjusted for large line +numbers and instruction offsets. + +.. + +.. bpo: 30061 +.. date: 0283 +.. nonce: 2w_dX9 +.. section: Library + +Fixed crashes in IOBase methods __next__() and readlines() when readline() +or __next__() respectively return non-sizeable object. Fixed possible other +errors caused by not checking results of PyObject_Size(), PySequence_Size(), +or PyMapping_Size(). + +.. + +.. bpo: 30218 +.. date: 0282 +.. nonce: ab5oIg +.. section: Library + +Fix PathLike support for shutil.unpack_archive. Patch by Jelle Zijlstra. + +.. + +.. bpo: 10076 +.. date: 0281 +.. nonce: qCnwly +.. section: Library + +Compiled regular expression and match objects in the re module now support +copy.copy() and copy.deepcopy() (they are considered atomic). + +.. + +.. bpo: 30068 +.. date: 0280 +.. nonce: n4q47r +.. section: Library + +_io._IOBase.readlines will check if it's closed first when hint is present. + +.. + +.. bpo: 29694 +.. date: 0279 +.. nonce: LWKxb1 +.. section: Library + +Fixed race condition in pathlib mkdir with flags parents=True. Patch by +Armin Rigo. + +.. + +.. bpo: 29692 +.. date: 0278 +.. nonce: oyWrAE +.. section: Library + +Fixed arbitrary unchaining of RuntimeError exceptions in +contextlib.contextmanager. Patch by Siddharth Velankar. + +.. + +.. bpo: 26187 +.. date: 0277 +.. nonce: aViyiR +.. section: Library + +Test that sqlite3 trace callback is not called multiple times when schema is +changing. Indirectly fixed by switching to use sqlite3_prepare_v2() in +bpo-9303. Patch by Aviv Palivoda. + +.. + +.. bpo: 30017 +.. date: 0276 +.. nonce: cKBuhU +.. section: Library + +Allowed calling the close() method of the zip entry writer object multiple +times. Writing to a closed writer now always produces a ValueError. + +.. + +.. bpo: 29998 +.. date: 0275 +.. nonce: poeIKD +.. section: Library + +Pickling and copying ImportError now preserves name and path attributes. + +.. + +.. bpo: 29995 +.. date: 0274 +.. nonce: b3mOqx +.. section: Library + +re.escape() now escapes only regex special characters. + +.. + +.. bpo: 29962 +.. date: 0273 +.. nonce: r-ibsN +.. section: Library + +Add math.remainder operation, implementing remainder as specified in IEEE +754. + +.. + +.. bpo: 29649 +.. date: 0272 +.. nonce: 2eIxQ8 +.. section: Library + +Improve struct.pack_into() exception messages for problems with the buffer +size and offset. Patch by Andrew Nester. + +.. + +.. bpo: 29654 +.. date: 0271 +.. nonce: xRFPge +.. section: Library + +Support If-Modified-Since HTTP header (browser cache). Patch by Pierre +Quentel. + +.. + +.. bpo: 29931 +.. date: 0270 +.. nonce: tfcTwK +.. section: Library + +Fixed comparison check for ipaddress.ip_interface objects. Patch by Sanjay +Sundaresan. + +.. + +.. bpo: 29953 +.. date: 0269 +.. nonce: Q1hSt- +.. section: Library + +Fixed memory leaks in the replace() method of datetime and time objects when +pass out of bound fold argument. + +.. + +.. bpo: 29942 +.. date: 0268 +.. nonce: CsGNuT +.. section: Library + +Fix a crash in itertools.chain.from_iterable when encountering long runs of +empty iterables. + +.. + +.. bpo: 10030 +.. date: 0267 +.. nonce: ZdhU3k +.. section: Library + +Sped up reading encrypted ZIP files by 2 times. + +.. + +.. bpo: 29204 +.. date: 0266 +.. nonce: 8Hbqn2 +.. section: Library + +Element.getiterator() and the html parameter of XMLParser() were deprecated +only in the documentation (since Python 3.2 and 3.4 correspondingly). Now +using them emits a deprecation warning. + +.. + +.. bpo: 27863 +.. date: 0265 +.. nonce: pPYHHI +.. section: Library + +Fixed multiple crashes in ElementTree caused by race conditions and wrong +types. + +.. + +.. bpo: 25996 +.. date: 0264 +.. nonce: L2_giP +.. section: Library + +Added support of file descriptors in os.scandir() on Unix. os.fwalk() is +sped up by 2 times by using os.scandir(). + +.. + +.. bpo: 28699 +.. date: 0263 +.. nonce: wZztZP +.. section: Library + +Fixed a bug in pools in multiprocessing.pool that raising an exception at +the very first of an iterable may swallow the exception or make the program +hang. Patch by Davin Potts and Xiang Zhang. + +.. + +.. bpo: 23890 +.. date: 0262 +.. nonce: GCFAAZ +.. section: Library + +unittest.TestCase.assertRaises() now manually breaks a reference cycle to +not keep objects alive longer than expected. + +.. + +.. bpo: 29901 +.. date: 0261 +.. nonce: QdgMvW +.. section: Library + +The zipapp module now supports general path-like objects, not just +pathlib.Path. + +.. + +.. bpo: 25803 +.. date: 0260 +.. nonce: CPDR0W +.. section: Library + +Avoid incorrect errors raised by Path.mkdir(exist_ok=True) when the OS gives +priority to errors such as EACCES over EEXIST. + +.. + +.. bpo: 29861 +.. date: 0259 +.. nonce: t2ZoRK +.. section: Library + +Release references to tasks, their arguments and their results as soon as +they are finished in multiprocessing.Pool. + +.. + +.. bpo: 19930 +.. date: 0258 +.. nonce: QCjO6A +.. section: Library + +The mode argument of os.makedirs() no longer affects the file permission +bits of newly created intermediate-level directories. + +.. + +.. bpo: 29884 +.. date: 0257 +.. nonce: kWXR8W +.. section: Library + +faulthandler: Restore the old sigaltstack during teardown. Patch by +Christophe Zeitouny. + +.. + +.. bpo: 25455 +.. date: 0256 +.. nonce: ZsahHN +.. section: Library + +Fixed crashes in repr of recursive buffered file-like objects. + +.. + +.. bpo: 29800 +.. date: 0255 +.. nonce: d2xASa +.. section: Library + +Fix crashes in partial.__repr__ if the keys of partial.keywords are not +strings. Patch by Michael Seifert. + +.. + +.. bpo: 8256 +.. date: 0254 +.. nonce: jAwGQH +.. section: Library + +Fixed possible failing or crashing input() if attributes "encoding" or +"errors" of sys.stdin or sys.stdout are not set or are not strings. + +.. + +.. bpo: 28692 +.. date: 0253 +.. nonce: CDt-Gb +.. section: Library + +Using non-integer value for selecting a plural form in gettext is now +deprecated. + +.. + +.. bpo: 26121 +.. date: 0252 +.. nonce: LX-pQA +.. section: Library + +Use C library implementation for math functions erf() and erfc(). + +.. + +.. bpo: 29619 +.. date: 0251 +.. nonce: WIGVxO +.. section: Library + +os.stat() and os.DirEntry.inode() now convert inode (st_ino) using unsigned +integers. + +.. + +.. bpo: 28298 +.. date: 0250 +.. nonce: PNOPsT +.. section: Library + +Fix a bug that prevented array 'Q', 'L' and 'I' from accepting big intables +(objects that have __int__) as elements. + +.. + +.. bpo: 29645 +.. date: 0249 +.. nonce: XCxTHM +.. section: Library + +Speed up importing the webbrowser module. webbrowser.register() is now +thread-safe. + +.. + +.. bpo: 28231 +.. date: 0248 +.. nonce: MG1X09 +.. section: Library + +The zipfile module now accepts path-like objects for external paths. + +.. + +.. bpo: 26915 +.. date: 0247 +.. nonce: qShJZO +.. section: Library + +index() and count() methods of collections.abc.Sequence now check identity +before checking equality when do comparisons. + +.. + +.. bpo: 28682 +.. date: 0246 +.. nonce: hUxdej +.. section: Library + +Added support for bytes paths in os.fwalk(). + +.. + +.. bpo: 29728 +.. date: 0245 +.. nonce: 37jMwb +.. section: Library + +Add new :const:`socket.TCP_NOTSENT_LOWAT` (Linux 3.12) constant. Patch by +Nathaniel J. Smith. + +.. + +.. bpo: 29623 +.. date: 0244 +.. nonce: D3-NP2 +.. section: Library + +Allow use of path-like object as a single argument in ConfigParser.read(). +Patch by David Ellis. + +.. + +.. bpo: 9303 +.. date: 0243 +.. nonce: kDZRSd +.. section: Library + +Migrate sqlite3 module to _v2 API. Patch by Aviv Palivoda. + +.. + +.. bpo: 28963 +.. date: 0242 +.. nonce: tPl8dq +.. section: Library + +Fix out of bound iteration in asyncio.Future.remove_done_callback +implemented in C. + +.. + +.. bpo: 29704 +.. date: 0241 +.. nonce: WHbx27 +.. section: Library + +asyncio.subprocess.SubprocessStreamProtocol no longer closes before all +pipes are closed. + +.. + +.. bpo: 29271 +.. date: 0240 +.. nonce: y8Vj2v +.. section: Library + +Fix Task.current_task and Task.all_tasks implemented in C to accept None +argument as their pure Python implementation. + +.. + +.. bpo: 29703 +.. date: 0239 +.. nonce: ZdsPCR +.. section: Library + +Fix asyncio to support instantiation of new event loops in child processes. + +.. + +.. bpo: 29615 +.. date: 0238 +.. nonce: OpFKzg +.. section: Library + +SimpleXMLRPCDispatcher no longer chains KeyError (or any other exception) to +exception(s) raised in the dispatched methods. Patch by Petr Motejlek. + +.. + +.. bpo: 7769 +.. date: 0237 +.. nonce: xGRJWh +.. section: Library + +Method register_function() of xmlrpc.server.SimpleXMLRPCDispatcher and its +subclasses can now be used as a decorator. + +.. + +.. bpo: 29376 +.. date: 0236 +.. nonce: rrJhJy +.. section: Library + +Fix assertion error in threading._DummyThread.is_alive(). + +.. + +.. bpo: 28624 +.. date: 0235 +.. nonce: 43TJib +.. section: Library + +Add a test that checks that cwd parameter of Popen() accepts PathLike +objects. Patch by Sayan Chowdhury. + +.. + +.. bpo: 28518 +.. date: 0234 +.. nonce: o-Q2Nw +.. section: Library + +Start a transaction implicitly before a DML statement. Patch by Aviv +Palivoda. + +.. + +.. bpo: 29742 +.. date: 0233 +.. nonce: 8hqfEO +.. section: Library + +get_extra_info() raises exception if get called on closed ssl transport. +Patch by Nikolay Kim. + +.. + +.. bpo: 16285 +.. date: 0232 +.. nonce: 4f5gbp +.. section: Library + +urllib.parse.quote is now based on RFC 3986 and hence includes '~' in the +set of characters that is not quoted by default. Patch by Christian Theune +and Ratnadeep Debnath. + +.. + +.. bpo: 29532 +.. date: 0231 +.. nonce: YCwVQn +.. section: Library + +Altering a kwarg dictionary passed to functools.partial() no longer affects +a partial object after creation. + +.. + +.. bpo: 29110 +.. date: 0230 +.. nonce: wmE-_T +.. section: Library + +Fix file object leak in aifc.open() when file is given as a filesystem path +and is not in valid AIFF format. Patch by Anthony Zhang. + +.. + +.. bpo: 22807 +.. date: 0229 +.. nonce: VmoSkZ +.. section: Library + +Add uuid.SafeUUID and uuid.UUID.is_safe to relay information from the +platform about whether generated UUIDs are generated with a multiprocessing +safe method. + +.. + +.. bpo: 29576 +.. date: 0228 +.. nonce: F-b8_5 +.. section: Library + +Improve some deprecations in importlib. Some deprecated methods now emit +DeprecationWarnings and have better descriptive messages. + +.. + +.. bpo: 29534 +.. date: 0227 +.. nonce: Ug3HPU +.. section: Library + +Fixed different behaviour of Decimal.from_float() for _decimal and +_pydecimal. Thanks Andrew Nester. + +.. + +.. bpo: 10379 +.. date: 0226 +.. nonce: mRlZsT +.. section: Library + +locale.format_string now supports the 'monetary' keyword argument, and +locale.format is deprecated. + +.. + +.. bpo: 29851 +.. date: 0225 +.. nonce: jqs_5s +.. section: Library + +importlib.reload() now raises ModuleNotFoundError if the module lacks a +spec. + +.. + +.. bpo: 28556 +.. date: 0224 +.. nonce: p6967e +.. section: Library + +Various updates to typing module: typing.Counter, typing.ChainMap, improved +ABC caching, etc. Original PRs by Jelle Zijlstra, Ivan Levkivskyi, Manuel +Krebber, and Łukasz Langa. + +.. + +.. bpo: 29100 +.. date: 0223 +.. nonce: LAAERS +.. section: Library + +Fix datetime.fromtimestamp() regression introduced in Python 3.6.0: check +minimum and maximum years. + +.. + +.. bpo: 29416 +.. date: 0222 +.. nonce: KJGyI_ +.. section: Library + +Prevent infinite loop in pathlib.Path.mkdir + +.. + +.. bpo: 29444 +.. date: 0221 +.. nonce: cEwgmk +.. section: Library + +Fixed out-of-bounds buffer access in the group() method of the match object. +Based on patch by WGH. + +.. + +.. bpo: 29377 +.. date: 0220 +.. nonce: 4AvSrC +.. section: Library + +Add WrapperDescriptorType, MethodWrapperType, and MethodDescriptorType +built-in types to types module. Original patch by Manuel Krebber. + +.. + +.. bpo: 29218 +.. date: 0219 +.. nonce: -Qoti0 +.. section: Library + +Unused install_misc command is now removed. It has been documented as +unused since 2000. Patch by Eric N. Vander Weele. + +.. + +.. bpo: 29368 +.. date: 0218 +.. nonce: nTtA_V +.. section: Library + +The extend() method is now called instead of the append() method when +unpickle collections.deque and other list-like objects. This can speed up +unpickling to 2 times. + +.. + +.. bpo: 29338 +.. date: 0217 +.. nonce: EpvQJl +.. section: Library + +The help of a builtin or extension class now includes the constructor +signature if __text_signature__ is provided for the class. + +.. + +.. bpo: 29335 +.. date: 0216 +.. nonce: _KC7IK +.. section: Library + +Fix subprocess.Popen.wait() when the child process has exited to a stopped +instead of terminated state (ex: when under ptrace). + +.. + +.. bpo: 29290 +.. date: 0215 +.. nonce: XBqptF +.. section: Library + +Fix a regression in argparse that help messages would wrap at non-breaking +spaces. + +.. + +.. bpo: 28735 +.. date: 0214 +.. nonce: admHLO +.. section: Library + +Fixed the comparison of mock.MagickMock with mock.ANY. + +.. + +.. bpo: 29197 +.. date: 0213 +.. nonce: sZssFZ +.. section: Library + +Removed deprecated function ntpath.splitunc(). + +.. + +.. bpo: 29210 +.. date: 0212 +.. nonce: y1UHWf +.. section: Library + +Removed support of deprecated argument "exclude" in tarfile.TarFile.add(). + +.. + +.. bpo: 29219 +.. date: 0211 +.. nonce: kxui7t +.. section: Library + +Fixed infinite recursion in the repr of uninitialized ctypes.CDLL instances. + +.. + +.. bpo: 29192 +.. date: 0210 +.. nonce: mY31H8 +.. section: Library + +Removed deprecated features in the http.cookies module. + +.. + +.. bpo: 29193 +.. date: 0209 +.. nonce: CgcjEx +.. section: Library + +A format string argument for string.Formatter.format() is now +positional-only. + +.. + +.. bpo: 29195 +.. date: 0208 +.. nonce: vK5LjU +.. section: Library + +Removed support of deprecated undocumented keyword arguments in methods of +regular expression objects. + +.. + +.. bpo: 28969 +.. date: 0207 +.. nonce: j3HJYO +.. section: Library + +Fixed race condition in C implementation of functools.lru_cache. KeyError +could be raised when cached function with full cache was simultaneously +called from different threads with the same uncached arguments. + +.. + +.. bpo: 20804 +.. date: 0206 +.. nonce: XyZhvi +.. section: Library + +The unittest.mock.sentinel attributes now preserve their identity when they +are copied or pickled. + +.. + +.. bpo: 29142 +.. date: 0205 +.. nonce: xo6kAv +.. section: Library + +In urllib.request, suffixes in no_proxy environment variable with leading +dots could match related hostnames again (e.g. .b.c matches a.b.c). Patch by +Milan Oberkirch. + +.. + +.. bpo: 28961 +.. date: 0204 +.. nonce: Rt93vg +.. section: Library + +Fix unittest.mock._Call helper: don't ignore the name parameter anymore. +Patch written by Jiajun Huang. + +.. + +.. bpo: 15812 +.. date: 0203 +.. nonce: R1U-Ec +.. section: Library + +inspect.getframeinfo() now correctly shows the first line of a context. +Patch by Sam Breese. + +.. + +.. bpo: 28985 +.. date: 0202 +.. nonce: TMWJFg +.. section: Library + +Update authorizer constants in sqlite3 module. Patch by Dingyuan Wang. + +.. + +.. bpo: 29079 +.. date: 0201 +.. nonce: g4YLix +.. section: Library + +Prevent infinite loop in pathlib.resolve() on Windows + +.. + +.. bpo: 13051 +.. date: 0200 +.. nonce: YzC1Te +.. section: Library + +Fixed recursion errors in large or resized curses.textpad.Textbox. Based on +patch by Tycho Andersen. + +.. + +.. bpo: 9770 +.. date: 0199 +.. nonce: WJJnwP +.. section: Library + +curses.ascii predicates now work correctly with negative integers. + +.. + +.. bpo: 28427 +.. date: 0198 +.. nonce: vUd-va +.. section: Library + +old keys should not remove new values from WeakValueDictionary when +collecting from another thread. + +.. + +.. bpo: 28923 +.. date: 0197 +.. nonce: naVULD +.. section: Library + +Remove editor artifacts from Tix.py. + +.. + +.. bpo: 28871 +.. date: 0196 +.. nonce: cPMXCJ +.. section: Library + +Fixed a crash when deallocate deep ElementTree. + +.. + +.. bpo: 19542 +.. date: 0195 +.. nonce: 5tCkaK +.. section: Library + +Fix bugs in WeakValueDictionary.setdefault() and WeakValueDictionary.pop() +when a GC collection happens in another thread. + +.. + +.. bpo: 20191 +.. date: 0194 +.. nonce: Q7uZCS +.. section: Library + +Fixed a crash in resource.prlimit() when passing a sequence that doesn't own +its elements as limits. + +.. + +.. bpo: 16255 +.. date: 0193 +.. nonce: p2YA85 +.. section: Library + +subprocess.Popen uses /system/bin/sh on Android as the shell, instead of +/bin/sh. + +.. + +.. bpo: 28779 +.. date: 0192 +.. nonce: t-mjED +.. section: Library + +multiprocessing.set_forkserver_preload() would crash the forkserver process +if a preloaded module instantiated some multiprocessing objects such as +locks. + +.. + +.. bpo: 26937 +.. date: 0191 +.. nonce: c9kgiA +.. section: Library + +The chown() method of the tarfile.TarFile class does not fail now when the +grp module cannot be imported, as for example on Android platforms. + +.. + +.. bpo: 28847 +.. date: 0190 +.. nonce: GiWd9w +.. section: Library + +dbm.dumb now supports reading read-only files and no longer writes the index +file when it is not changed. A deprecation warning is now emitted if the +index file is missed and recreated in the 'r' and 'w' modes (will be an +error in future Python releases). + +.. + +.. bpo: 27030 +.. date: 0189 +.. nonce: GoGlFH +.. section: Library + +Unknown escapes consisting of ``'\'`` and an ASCII letter in re.sub() +replacement templates regular expressions now are errors. + +.. + +.. bpo: 28835 +.. date: 0188 +.. nonce: iWBYH7 +.. section: Library + +Fix a regression introduced in warnings.catch_warnings(): call +warnings.showwarning() if it was overridden inside the context manager. + +.. + +.. bpo: 27172 +.. date: 0187 +.. nonce: mVKfLT +.. section: Library + +To assist with upgrades from 2.7, the previously documented deprecation of +``inspect.getfullargspec()`` has been reversed. This decision may be +revisited again after the Python 2.7 branch is no longer officially +supported. + +.. + +.. bpo: 28740 +.. date: 0186 +.. nonce: rY8kz- +.. section: Library + +Add sys.getandroidapilevel(): return the build time API version of Android +as an integer. Function only available on Android. + +.. + +.. bpo: 26273 +.. date: 0185 +.. nonce: ilNIWN +.. section: Library + +Add new :const:`socket.TCP_CONGESTION` (Linux 2.6.13) and +:const:`socket.TCP_USER_TIMEOUT` (Linux 2.6.37) constants. Patch written by +Omar Sandoval. + +.. + +.. bpo: 28752 +.. date: 0184 +.. nonce: Q-4oRE +.. section: Library + +Restored the __reduce__() methods of datetime objects. + +.. + +.. bpo: 28727 +.. date: 0183 +.. nonce: ubZP_b +.. section: Library + +Regular expression patterns, _sre.SRE_Pattern objects created by +re.compile(), become comparable (only x==y and x!=y operators). This change +should fix the issue #18383: don't duplicate warning filters when the +warnings module is reloaded (thing usually only done in unit tests). + +.. + +.. bpo: 20572 +.. date: 0182 +.. nonce: NCRmvz +.. section: Library + +Remove the subprocess.Popen.wait endtime parameter. It was deprecated in +3.4 and undocumented prior to that. + +.. + +.. bpo: 25659 +.. date: 0181 +.. nonce: lE2IlT +.. section: Library + +In ctypes, prevent a crash calling the from_buffer() and from_buffer_copy() +methods on abstract classes like Array. + +.. + +.. bpo: 28548 +.. date: 0180 +.. nonce: IeNrnG +.. section: Library + +In the "http.server" module, parse the protocol version if possible, to +avoid using HTTP 0.9 in some error responses. + +.. + +.. bpo: 19717 +.. date: 0179 +.. nonce: HXCAIz +.. section: Library + +Makes Path.resolve() succeed on paths that do not exist. Patch by Vajrasky +Kok + +.. + +.. bpo: 28563 +.. date: 0178 +.. nonce: iweEiw +.. section: Library + +Fixed possible DoS and arbitrary code execution when handle plural form +selections in the gettext module. The expression parser now supports exact +syntax supported by GNU gettext. + +.. + +.. bpo: 28387 +.. date: 0177 +.. nonce: 1clJu7 +.. section: Library + +Fixed possible crash in _io.TextIOWrapper deallocator when the garbage +collector is invoked in other thread. Based on patch by Sebastian Cufre. + +.. + +.. bpo: 27517 +.. date: 0176 +.. nonce: 1CYM8A +.. section: Library + +LZMA compressor and decompressor no longer raise exceptions if given empty +data twice. Patch by Benjamin Fogle. + +.. + +.. bpo: 28549 +.. date: 0175 +.. nonce: ShnM2y +.. section: Library + +Fixed segfault in curses's addch() with ncurses6. + +.. + +.. bpo: 28449 +.. date: 0174 +.. nonce: 5JK6ES +.. section: Library + +tarfile.open() with mode "r" or "r:" now tries to open a tar file with +compression before trying to open it without compression. Otherwise it had +50% chance failed with ignore_zeros=True. + +.. + +.. bpo: 23262 +.. date: 0173 +.. nonce: 6EVB7N +.. section: Library + +The webbrowser module now supports Firefox 36+ and derived browsers. Based +on patch by Oleg Broytman. + +.. + +.. bpo: 24241 +.. date: 0172 +.. nonce: y7N12p +.. section: Library + +The webbrowser in an X environment now prefers using the default browser +directly. Also, the webbrowser register() function now has a documented +'preferred' argument, to specify browsers to be returned by get() with no +arguments. Patch by David Steele + +.. + +.. bpo: 27939 +.. date: 0171 +.. nonce: mTfADV +.. section: Library + +Fixed bugs in tkinter.ttk.LabeledScale and tkinter.Scale caused by +representing the scale as float value internally in Tk. tkinter.IntVar now +works if float value is set to underlying Tk variable. + +.. + +.. bpo: 28255 +.. date: 0170 +.. nonce: G3iOPm +.. section: Library + +calendar.TextCalendar.prweek() no longer prints a space after a weeks's +calendar. calendar.TextCalendar.pryear() no longer prints redundant newline +after a year's calendar. Based on patch by Xiang Zhang. + +.. + +.. bpo: 28255 +.. date: 0169 +.. nonce: fHNZu0 +.. section: Library + +calendar.TextCalendar.prmonth() no longer prints a space at the start of new +line after printing a month's calendar. Patch by Xiang Zhang. + +.. + +.. bpo: 20491 +.. date: 0168 +.. nonce: ObgnQ2 +.. section: Library + +The textwrap.TextWrapper class now honors non-breaking spaces. Based on +patch by Kaarle Ritvanen. + +.. + +.. bpo: 28353 +.. date: 0167 +.. nonce: sKGbLL +.. section: Library + +os.fwalk() no longer fails on broken links. + +.. + +.. bpo: 28430 +.. date: 0166 +.. nonce: 4MiEYT +.. section: Library + +Fix iterator of C implemented asyncio.Future doesn't accept non-None value +is passed to it.send(val). + +.. + +.. bpo: 27025 +.. date: 0165 +.. nonce: foAViS +.. section: Library + +Generated names for Tkinter widgets now start by the "!" prefix for +readability. + +.. + +.. bpo: 25464 +.. date: 0164 +.. nonce: HDUTCu +.. section: Library + +Fixed HList.header_exists() in tkinter.tix module by addin a workaround to +Tix library bug. + +.. + +.. bpo: 28488 +.. date: 0163 +.. nonce: TgO112 +.. section: Library + +shutil.make_archive() no longer adds entry "./" to ZIP archive. + +.. + +.. bpo: 25953 +.. date: 0162 +.. nonce: EKKJAQ +.. section: Library + +re.sub() now raises an error for invalid numerical group reference in +replacement template even if the pattern is not found in the string. Error +message for invalid group reference now includes the group index and the +position of the reference. Based on patch by SilentGhost. + +.. + +.. bpo: 28469 +.. date: 0161 +.. nonce: QZW1Np +.. section: Library + +timeit now uses the sequence 1, 2, 5, 10, 20, 50,... instead of 1, 10, +100,... for autoranging. + +.. + +.. bpo: 28115 +.. date: 0160 +.. nonce: 4FIjIE +.. section: Library + +Command-line interface of the zipfile module now uses argparse. Added +support of long options. + +.. + +.. bpo: 18219 +.. date: 0159 +.. nonce: 1ANQN1 +.. section: Library + +Optimize csv.DictWriter for large number of columns. Patch by Mariatta +Wijaya. + +.. + +.. bpo: 28448 +.. date: 0158 +.. nonce: 5bduWe +.. section: Library + +Fix C implemented asyncio.Future didn't work on Windows. + +.. + +.. bpo: 23214 +.. date: 0157 +.. nonce: -4Q5Z7 +.. section: Library + +In the "io" module, the argument to BufferedReader and BytesIO's read1() +methods is now optional and can be -1, matching the BufferedIOBase +specification. + +.. + +.. bpo: 28480 +.. date: 0156 +.. nonce: 9lHw6m +.. section: Library + +Fix error building socket module when multithreading is disabled. + +.. + +.. bpo: 28240 +.. date: 0155 +.. nonce: hqzQvS +.. section: Library + +timeit: remove ``-c/--clock`` and ``-t/--time`` command line options which +were deprecated since Python 3.3. + +.. + +.. bpo: 28240 +.. date: 0154 +.. nonce: IwQMgd +.. section: Library + +timeit now repeats the benchmarks 5 times instead of only 3 to make +benchmarks more reliable. + +.. + +.. bpo: 28240 +.. date: 0153 +.. nonce: cXljq- +.. section: Library + +timeit autorange now uses a single loop iteration if the benchmark takes +less than 10 seconds, instead of 10 iterations. "python3 -m timeit -s +'import time' 'time.sleep(1)'" now takes 4 seconds instead of 40 seconds. + +.. + +.. bpo: 0 +.. date: 0152 +.. nonce: 5Y0ngw +.. section: Library + +Distutils.sdist now looks for README and setup.py files with case +sensitivity. This behavior matches that found in Setuptools 6.0 and later. +See `setuptools 100 <https://github.com/pypa/setuptools/issues/100>`_ for +rationale. + +.. + +.. bpo: 24452 +.. date: 0151 +.. nonce: pVsjt0 +.. section: Library + +Make webbrowser support Chrome on Mac OS X. Patch by Ned Batchelder. + +.. + +.. bpo: 20766 +.. date: 0150 +.. nonce: 4kvCzx +.. section: Library + +Fix references leaked by pdb in the handling of SIGINT handlers. + +.. + +.. bpo: 27998 +.. date: 0149 +.. nonce: CPhy4H +.. section: Library + +Fixed bytes path support in os.scandir() on Windows. Patch by Eryk Sun. + +.. + +.. bpo: 28317 +.. date: 0148 +.. nonce: LgHleA +.. section: Library + +The disassembler now decodes FORMAT_VALUE argument. + +.. + +.. bpo: 28380 +.. date: 0147 +.. nonce: jKPMzH +.. section: Library + +unittest.mock Mock autospec functions now properly support assert_called, +assert_not_called, and assert_called_once. + +.. + +.. bpo: 28229 +.. date: 0146 +.. nonce: BKAxcS +.. section: Library + +lzma module now supports pathlib. + +.. + +.. bpo: 28321 +.. date: 0145 +.. nonce: bQ-IIX +.. section: Library + +Fixed writing non-BMP characters with binary format in plistlib. + +.. + +.. bpo: 28225 +.. date: 0144 +.. nonce: 6N28nu +.. section: Library + +bz2 module now supports pathlib. Initial patch by Ethan Furman. + +.. + +.. bpo: 28227 +.. date: 0143 +.. nonce: 7lUz8i +.. section: Library + +gzip now supports pathlib. Patch by Ethan Furman. + +.. + +.. bpo: 28332 +.. date: 0142 +.. nonce: Ed8fNk +.. section: Library + +Deprecated silent truncations in socket.htons and socket.ntohs. Original +patch by Oren Milman. + +.. + +.. bpo: 27358 +.. date: 0141 +.. nonce: t288Iv +.. section: Library + +Optimized merging var-keyword arguments and improved error message when +passing a non-mapping as a var-keyword argument. + +.. + +.. bpo: 28257 +.. date: 0140 +.. nonce: SVD_IH +.. section: Library + +Improved error message when passing a non-iterable as a var-positional +argument. Added opcode BUILD_TUPLE_UNPACK_WITH_CALL. + +.. + +.. bpo: 28322 +.. date: 0139 +.. nonce: l9hzap +.. section: Library + +Fixed possible crashes when unpickle itertools objects from incorrect pickle +data. Based on patch by John Leitch. + +.. + +.. bpo: 28228 +.. date: 0138 +.. nonce: 1qBwdM +.. section: Library + +imghdr now supports pathlib. + +.. + +.. bpo: 28226 +.. date: 0137 +.. nonce: nMXiwU +.. section: Library + +compileall now supports pathlib. + +.. + +.. bpo: 28314 +.. date: 0136 +.. nonce: N7YrkN +.. section: Library + +Fix function declaration (C flags) for the getiterator() method of +xml.etree.ElementTree.Element. + +.. + +.. bpo: 28148 +.. date: 0135 +.. nonce: Flzndx +.. section: Library + +Stop using localtime() and gmtime() in the time module. +Introduced platform independent _PyTime_localtime API that is similar to +POSIX localtime_r, but available on all platforms. Patch by Ed Schouten. + +.. + +.. bpo: 28253 +.. date: 0134 +.. nonce: aLfmhe +.. section: Library + +Fixed calendar functions for extreme months: 0001-01 and 9999-12. +Methods itermonthdays() and itermonthdays2() are reimplemented so that they +don't call itermonthdates() which can cause datetime.date under/overflow. + +.. + +.. bpo: 28275 +.. date: 0133 +.. nonce: EhWIsz +.. section: Library + +Fixed possible use after free in the decompress() methods of the +LZMADecompressor and BZ2Decompressor classes. Original patch by John Leitch. + +.. + +.. bpo: 27897 +.. date: 0132 +.. nonce: I0Ppmx +.. section: Library + +Fixed possible crash in sqlite3.Connection.create_collation() if pass +invalid string-like object as a name. Patch by Xiang Zhang. + +.. + +.. bpo: 18844 +.. date: 0131 +.. nonce: fQsEdn +.. section: Library + +random.choices() now has k as a keyword-only argument to improve the +readability of common cases and come into line with the signature used in +other languages. + +.. + +.. bpo: 18893 +.. date: 0130 +.. nonce: osiX5c +.. section: Library + +Fix invalid exception handling in Lib/ctypes/macholib/dyld.py. Patch by +Madison May. + +.. + +.. bpo: 27611 +.. date: 0129 +.. nonce: A_ArH_ +.. section: Library + +Fixed support of default root window in the tkinter.tix module. Added the +master parameter in the DisplayStyle constructor. + +.. + +.. bpo: 27348 +.. date: 0128 +.. nonce: tDx7Vw +.. section: Library + +In the traceback module, restore the formatting of exception messages like +"Exception: None". This fixes a regression introduced in 3.5a2. + +.. + +.. bpo: 25651 +.. date: 0127 +.. nonce: 3UhyPo +.. section: Library + +Allow false values to be used for msg parameter of subTest(). + +.. + +.. bpo: 27778 +.. date: 0126 +.. nonce: Yyo1aP +.. section: Library + +Fix a memory leak in os.getrandom() when the getrandom() is interrupted by a +signal and a signal handler raises a Python exception. + +.. + +.. bpo: 28200 +.. date: 0125 +.. nonce: 4IEbr7 +.. section: Library + +Fix memory leak on Windows in the os module (fix path_converter() function). + +.. + +.. bpo: 25400 +.. date: 0124 +.. nonce: d9Qn0E +.. section: Library + +RobotFileParser now correctly returns default values for crawl_delay and +request_rate. Initial patch by Peter Wirtz. + +.. + +.. bpo: 27932 +.. date: 0123 +.. nonce: mtgl-6 +.. section: Library + +Prevent memory leak in win32_ver(). + +.. + +.. bpo: 0 +.. date: 0122 +.. nonce: iPpjqX +.. section: Library + +Fix UnboundLocalError in socket._sendfile_use_sendfile. + +.. + +.. bpo: 28075 +.. date: 0121 +.. nonce: aLiUs9 +.. section: Library + +Check for ERROR_ACCESS_DENIED in Windows implementation of os.stat(). Patch +by Eryk Sun. + +.. + +.. bpo: 22493 +.. date: 0120 +.. nonce: Mv_hZf +.. section: Library + +Warning message emitted by using inline flags in the middle of regular +expression now contains a (truncated) regex pattern. Patch by Tim Graham. + +.. + +.. bpo: 25270 +.. date: 0119 +.. nonce: jrZruM +.. section: Library + +Prevent codecs.escape_encode() from raising SystemError when an empty +bytestring is passed. + +.. + +.. bpo: 28181 +.. date: 0118 +.. nonce: NGc4Yv +.. section: Library + +Get antigravity over HTTPS. Patch by Kaartic Sivaraam. + +.. + +.. bpo: 25895 +.. date: 0117 +.. nonce: j92qoQ +.. section: Library + +Enable WebSocket URL schemes in urllib.parse.urljoin. Patch by Gergely Imreh +and Markus Holtermann. + +.. + +.. bpo: 28114 +.. date: 0116 +.. nonce: gmFXsA +.. section: Library + +Fix a crash in parse_envlist() when env contains byte strings. Patch by Eryk +Sun. + +.. + +.. bpo: 27599 +.. date: 0115 +.. nonce: itvm8T +.. section: Library + +Fixed buffer overrun in binascii.b2a_qp() and binascii.a2b_qp(). + +.. + +.. bpo: 27906 +.. date: 0114 +.. nonce: TBBXrv +.. section: Library + +Fix socket accept exhaustion during high TCP traffic. Patch by Kevin Conway. + +.. + +.. bpo: 28174 +.. date: 0113 +.. nonce: CV1UdI +.. section: Library + +Handle when SO_REUSEPORT isn't properly supported. Patch by Seth Michael +Larson. + +.. + +.. bpo: 26654 +.. date: 0112 +.. nonce: XtzTE9 +.. section: Library + +Inspect functools.partial in asyncio.Handle.__repr__. Patch by iceboy. + +.. + +.. bpo: 26909 +.. date: 0111 +.. nonce: ASiakT +.. section: Library + +Fix slow pipes IO in asyncio. Patch by INADA Naoki. + +.. + +.. bpo: 28176 +.. date: 0110 +.. nonce: sU8R6L +.. section: Library + +Fix callbacks race in asyncio.SelectorLoop.sock_connect. + +.. + +.. bpo: 27759 +.. date: 0109 +.. nonce: qpMDGq +.. section: Library + +Fix selectors incorrectly retain invalid file descriptors. Patch by Mark +Williams. + +.. + +.. bpo: 28325 +.. date: 0108 +.. nonce: wAHmnK +.. section: Library + +Remove vestigial MacOS 9 macurl2path module and its tests. + +.. + +.. bpo: 28368 +.. date: 0107 +.. nonce: n594X4 +.. section: Library + +Refuse monitoring processes if the child watcher has no loop attached. Patch +by Vincent Michel. + +.. + +.. bpo: 28369 +.. date: 0106 +.. nonce: 8DTANe +.. section: Library + +Raise RuntimeError when transport's FD is used with add_reader, add_writer, +etc. + +.. + +.. bpo: 28370 +.. date: 0105 +.. nonce: 18jBuZ +.. section: Library + +Speedup asyncio.StreamReader.readexactly. Patch by Коренберг Марк. + +.. + +.. bpo: 28371 +.. date: 0104 +.. nonce: U9Zqdk +.. section: Library + +Deprecate passing asyncio.Handles to run_in_executor. + +.. + +.. bpo: 28372 +.. date: 0103 +.. nonce: njcIPk +.. section: Library + +Fix asyncio to support formatting of non-python coroutines. + +.. + +.. bpo: 28399 +.. date: 0102 +.. nonce: QKIqRX +.. section: Library + +Remove UNIX socket from FS before binding. Patch by Коренберг Марк. + +.. + +.. bpo: 27972 +.. date: 0101 +.. nonce: ZK-GFm +.. section: Library + +Prohibit Tasks to await on themselves. + +.. + +.. bpo: 24142 +.. date: 0100 +.. nonce: IrZnFs +.. section: Library + +Reading a corrupt config file left configparser in an invalid state. +Original patch by Florian Höch. + +.. + +.. bpo: 29581 +.. date: 0099 +.. nonce: gHCrxP +.. section: Library + +ABCMeta.__new__ now accepts ``**kwargs``, allowing abstract base classes to +use keyword parameters in __init_subclass__. Patch by Nate Soares. + +.. + +.. bpo: 25532 +.. date: 0098 +.. nonce: ey4Yez +.. section: Library + +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: 30177 +.. date: 0097 +.. nonce: JGIJNL +.. section: Library + +path.resolve(strict=False) no longer cuts the path after the first element +not present in the filesystem. Patch by Antoine Pietri. + +.. + +.. bpo: 31294 +.. date: 2017-09-07-20-49-09 +.. nonce: WgI18w +.. section: Documentation + +Fix incomplete code snippet in the ZeroMQSocketListener and +ZeroMQSocketHandler examples and adapt them to Python 3. + +.. + +.. bpo: 21649 +.. date: 2017-09-06-10-11-57 +.. nonce: EUvqA9 +.. section: Documentation + +Add RFC 7525 and Mozilla server side TLS links to SSL documentation. + +.. + +.. bpo: 31128 +.. date: 2017-08-31 +.. nonce: uoa3cr +.. section: Documentation + +Allow the pydoc server to bind to arbitrary hostnames. + +.. + +.. bpo: 30803 +.. date: 2017-07-29-14-55-50 +.. nonce: 6hutqQ +.. section: Documentation + +Clarify doc on truth value testing. Original patch by Peter Thomassen. + +.. + +.. bpo: 30176 +.. date: 0060 +.. nonce: VivmCg +.. section: Documentation + +Add missing attribute related constants in curses documentation. + +.. + +.. bpo: 30052 +.. date: 0059 +.. nonce: TpmpaF +.. section: Documentation + +the link targets for :func:`bytes` and :func:`bytearray` are now their +respective type definitions, rather than the corresponding builtin function +entries. Use :ref:`bytes <func-bytes>` and :ref:`bytearray <func-bytearray>` +to reference the latter. +In order to ensure this and future cross-reference updates are applied +automatically, the daily documentation builds now disable the default output +caching features in Sphinx. + +.. + +.. bpo: 26985 +.. date: 0058 +.. nonce: NB5_9S +.. section: Documentation + +Add missing info of code object in inspect documentation. + +.. + +.. bpo: 19824 +.. date: 0057 +.. nonce: We9an6 +.. section: Documentation + +Improve the documentation for, and links to, template strings by emphasizing +their utility for internationalization, and by clarifying some usage +constraints. (See also: bpo-20314, bpo-12518) + +.. + +.. bpo: 28929 +.. date: 0056 +.. nonce: Md7kb0 +.. section: Documentation + +Link the documentation to its source file on GitHub. + +.. + +.. bpo: 25008 +.. date: 0055 +.. nonce: CeIzyU +.. section: Documentation + +Document smtpd.py as effectively deprecated and add a pointer to aiosmtpd, a +third-party asyncio-based replacement. + +.. + +.. bpo: 26355 +.. date: 0054 +.. nonce: SDq_8Y +.. section: Documentation + +Add canonical header link on each page to corresponding major version of the +documentation. Patch by Matthias Bussonnier. + +.. + +.. bpo: 29349 +.. date: 0053 +.. nonce: PjSo-t +.. section: Documentation + +Fix Python 2 syntax in code for building the documentation. + +.. + +.. bpo: 23722 +.. date: 0052 +.. nonce: nFjY3C +.. section: Documentation + +The data model reference and the porting section in the 3.6 What's New guide +now cover the additional ``__classcell__`` handling needed for custom +metaclasses to fully support :pep:`487` and zero-argument ``super()``. + +.. + +.. bpo: 28513 +.. date: 0051 +.. nonce: L3joAz +.. section: Documentation + +Documented command-line interface of zipfile. + +.. + +.. bpo: 29639 +.. date: 2017-09-08-15-59-07 +.. nonce: yIZecp +.. section: Tests + +test.support.HOST is now "localhost", a new HOSTv4 constant has been added +for your ``127.0.0.1`` needs, similar to the existing HOSTv6 constant. + +.. + +.. bpo: 31320 +.. date: 2017-09-05-14-23-35 +.. nonce: JRDHx7 +.. section: Tests + +Silence traceback in test_ssl + +.. + +.. bpo: 31346 +.. date: 2017-09-04-16-21-18 +.. nonce: xni1VR +.. section: Tests + +Prefer PROTOCOL_TLS_CLIENT and PROTOCOL_TLS_SERVER protocols for SSLContext. + +.. + +.. bpo: 25674 +.. date: 2017-09-04-13-03-55 +.. nonce: whVTXh +.. section: Tests + +Remove sha256.tbs-internet.com ssl test + +.. + +.. bpo: 30715 +.. date: 2017-07-25-15-27-44 +.. nonce: Sp7bTF +.. section: Tests + +Address ALPN callback changes for OpenSSL 1.1.0f. The latest version behaves +like OpenSSL 1.0.2 and no longer aborts handshake. + +.. + +.. bpo: 30822 +.. date: 2017-07-20-14-29-54 +.. nonce: X0wREo +.. section: Tests + +regrtest: Exclude tzdata from regrtest --all. When running the test suite +using --use=all / -u all, exclude tzdata since it makes test_datetime too +slow (15-20 min on some buildbots) which then times out on some buildbots. +Fix also regrtest command line parser to allow passing -u extralargefile to +run test_zipfile64. + +.. + +.. bpo: 30695 +.. date: 2017-06-30-11-20-20 +.. nonce: lo7FQX +.. section: Tests + +Add the `set_nomemory(start, stop)` and `remove_mem_hooks()` functions to +the _testcapi module. + +.. + +.. bpo: 30357 +.. date: 0012 +.. nonce: n4CPEa +.. section: Tests + +test_thread: setUp() now uses support.threading_setup() and +support.threading_cleanup() to wait until threads complete to avoid random +side effects on following tests. Initial patch written by Grzegorz Grzywacz. + +.. + +.. bpo: 30197 +.. date: 0011 +.. nonce: c5wRfu +.. section: Tests + +Enhanced functions swap_attr() and swap_item() in the test.support module. +They now work when delete replaced attribute or item inside the with +statement. The old value of the attribute or item (or None if it doesn't +exist) now will be assigned to the target of the "as" clause, if there is +one. + +.. + +.. bpo: 24932 +.. date: 0010 +.. nonce: XLTzvR +.. section: Tests + +Use proper command line parsing in _testembed + +.. + +.. bpo: 28950 +.. date: 0009 +.. nonce: 1W8Glo +.. section: Tests + +Disallow -j0 to be combined with -T/-l in regrtest command line arguments. + +.. + +.. bpo: 28683 +.. date: 0008 +.. nonce: Fp-Hdq +.. section: Tests + +Fix the tests that bind() a unix socket and raise PermissionError on Android +for a non-root user. + +.. + +.. bpo: 26936 +.. date: 0007 +.. nonce: XSZSVS +.. section: Tests + +Fix the test_socket failures on Android - getservbyname(), getservbyport() +and getaddrinfo() are broken on some Android API levels. + +.. + +.. bpo: 28666 +.. date: 0006 +.. nonce: RtTk-4 +.. section: Tests + +Now test.support.rmtree is able to remove unwritable or unreadable +directories. + +.. + +.. bpo: 23839 +.. date: 0005 +.. nonce: zsT_L9 +.. section: Tests + +Various caches now are cleared before running every test file. + +.. + +.. bpo: 26944 +.. date: 0004 +.. nonce: ChZ_BO +.. section: Tests + +Fix test_posix for Android where 'id -G' is entirely wrong or missing the +effective gid. + +.. + +.. bpo: 28409 +.. date: 0003 +.. nonce: Q2IlxJ +.. section: Tests + +regrtest: fix the parser of command line arguments. + +.. + +.. bpo: 28217 +.. date: 0002 +.. nonce: Y37OKV +.. section: Tests + +Adds _testconsole module to test console input. + +.. + +.. bpo: 26939 +.. date: 0001 +.. nonce: 7j_W5R +.. section: Tests + +Add the support.setswitchinterval() function to fix test_functools hanging +on the Android armv7 qemu emulator. + +.. + +.. bpo: 31354 +.. date: 2017-09-08-11-48-11 +.. nonce: 4f-VJK +.. section: Build + +Allow --with-lto to be used on all builds, not just `make profile-opt`. + +.. + +.. bpo: 31370 +.. date: 2017-09-06-23-14-08 +.. nonce: -j4kN4 +.. section: Build + +Remove support for building --without-threads. +This option is not really useful anymore in the 21st century. Removing lots +of conditional paths allows us to simplify the code base, including in +difficult to maintain low-level internal code. + +.. + +.. bpo: 31341 +.. date: 2017-09-04-14-43-46 +.. nonce: XLuZFk +.. section: Build + +Per :pep:`11`, support for the IRIX operating system was removed. + +.. + +.. bpo: 30854 +.. date: 2017-07-05-16-54-59 +.. nonce: sPADRI +.. section: Build + +Fix compile error when compiling --without-threads. Patch by Masayuki +Yamamoto. + +.. + +.. bpo: 30687 +.. date: 0050 +.. nonce: 8mqHnu +.. section: Build + +Locate msbuild.exe on Windows when building rather than vcvarsall.bat + +.. + +.. bpo: 20210 +.. date: 0049 +.. nonce: MN_n-r +.. section: Build + +Support the *disabled* marker in Setup files. Extension modules listed after +this marker are not built at all, neither by the Makefile nor by setup.py. + +.. + +.. bpo: 29941 +.. date: 0048 +.. nonce: ylh45A +.. section: Build + +Add ``--with-assertions`` configure flag to explicitly enable C ``assert()`` +checks. Defaults to off. ``--with-pydebug`` implies ``--with-assertions``. + +.. + +.. bpo: 28787 +.. date: 0047 +.. nonce: vhH_6a +.. section: Build + +Fix out-of-tree builds of Python when configured with ``--with--dtrace``. + +.. + +.. bpo: 29243 +.. date: 0046 +.. nonce: WDK4hT +.. section: Build + +Prevent unnecessary rebuilding of Python during ``make test``, ``make +install`` and some other make targets when configured with +``--enable-optimizations``. + +.. + +.. bpo: 23404 +.. date: 0045 +.. nonce: PdYVWg +.. section: Build + +Don't regenerate generated files based on file modification time anymore: +the action is now explicit. Replace ``make touch`` with ``make regen-all``. + +.. + +.. bpo: 29643 +.. date: 0044 +.. nonce: 4WLIJQ +.. section: Build + +Fix ``--enable-optimization`` didn't work. + +.. + +.. bpo: 27593 +.. date: 0043 +.. nonce: v87xEr +.. section: Build + +sys.version and the platform module python_build(), python_branch(), and +python_revision() functions now use git information rather than hg when +building from a repo. + +.. + +.. bpo: 29572 +.. date: 0042 +.. nonce: iZ1XKK +.. section: Build + +Update Windows build and OS X installers to use OpenSSL 1.0.2k. + +.. + +.. bpo: 27659 +.. date: 0041 +.. nonce: i8UzRC +.. section: Build + +Prohibit implicit C function declarations: use +``-Werror=implicit-function-declaration`` when possible (GCC and Clang, +but it depends on the compiler version). Patch written by Chi Hsuan Yen. + +.. + +.. bpo: 29384 +.. date: 0040 +.. nonce: v3IqBE +.. section: Build + +Remove old Be OS helper scripts. + +.. + +.. bpo: 26851 +.. date: 0039 +.. nonce: R5243g +.. section: Build + +Set Android compilation and link flags. + +.. + +.. bpo: 28768 +.. date: 0038 +.. nonce: b9_a6E +.. section: Build + +Fix implicit declaration of function _setmode. Patch by Masayuki Yamamoto + +.. + +.. bpo: 29080 +.. date: 0037 +.. nonce: b3qLQT +.. section: Build + +Removes hard dependency on hg.exe from PCBuild/build.bat + +.. + +.. bpo: 23903 +.. date: 0036 +.. nonce: JXJ889 +.. section: Build + +Added missed names to PC/python3.def. + +.. + +.. bpo: 28762 +.. date: 0035 +.. nonce: Ru0YN_ +.. section: Build + +lockf() is available on Android API level 24, but the F_LOCK macro is not +defined in android-ndk-r13. + +.. + +.. bpo: 28538 +.. date: 0034 +.. nonce: FqtN7v +.. section: Build + +Fix the compilation error that occurs because if_nameindex() is available on +Android API level 24, but the if_nameindex structure is not defined. + +.. + +.. bpo: 20211 +.. date: 0033 +.. nonce: gpNptI +.. section: Build + +Do not add the directory for installing C header files and the directory for +installing object code libraries to the cross compilation search paths. +Original patch by Thomas Petazzoni. + +.. + +.. bpo: 28849 +.. date: 0032 +.. nonce: AzRRF5 +.. section: Build + +Do not define sys.implementation._multiarch on Android. + +.. + +.. bpo: 10656 +.. date: 0031 +.. nonce: pR8FFU +.. section: Build + +Fix out-of-tree building on AIX. Patch by Tristan Carel and Michael +Haubenwallner. + +.. + +.. bpo: 26359 +.. date: 0030 +.. nonce: CLz6qy +.. section: Build + +Rename --with-optimiations to --enable-optimizations. + +.. + +.. bpo: 28444 +.. date: 0029 +.. nonce: zkc9nT +.. section: Build + +Fix missing extensions modules when cross compiling. + +.. + +.. bpo: 28208 +.. date: 0028 +.. nonce: DtoP1i +.. section: Build + +Update Windows build and OS X installers to use SQLite 3.14.2. + +.. + +.. bpo: 28248 +.. date: 0027 +.. nonce: KY_-en +.. section: Build + +Update Windows build and OS X installers to use OpenSSL 1.0.2j. + +.. + +.. bpo: 21124 +.. date: 0026 +.. nonce: 1bbArU +.. section: Build + +Fix building the _struct module on Cygwin by passing ``NULL`` instead of +``&PyType_Type`` to PyVarObject_HEAD_INIT. Patch by Masayuki Yamamoto. + +.. + +.. bpo: 13756 +.. date: 0025 +.. nonce: sslhpC +.. section: Build + +Fix building extensions modules on Cygwin. Patch by Roumen Petrov, based on +original patch by Jason Tishler. + +.. + +.. bpo: 21085 +.. date: 0024 +.. nonce: 2VvyUF +.. section: Build + +Add configure check for siginfo_t.si_band, which Cygwin does not provide. +Patch by Masayuki Yamamoto with review and rebase by Erik Bray. + +.. + +.. bpo: 28258 +.. date: 0023 +.. nonce: iKtAHd +.. section: Build + +Fixed build with Estonian locale (python-config and distclean targets in +Makefile). Patch by Arfrever Frehtes Taifersar Arahesis. + +.. + +.. bpo: 26661 +.. date: 0022 +.. nonce: Z_HNbs +.. section: Build + +setup.py now detects system libffi with multiarch wrapper. + +.. + +.. bpo: 27979 +.. date: 0021 +.. nonce: fR0KgM +.. section: Build + +A full copy of libffi is no longer bundled for use when building _ctypes on +non-OSX UNIX platforms. An installed copy of libffi is now required when +building _ctypes on such platforms. + +.. + +.. bpo: 15819 +.. date: 0020 +.. nonce: QVDr3E +.. section: Build + +Remove redundant include search directory option for building outside the +source tree. + +.. + +.. bpo: 28676 +.. date: 0019 +.. nonce: Wxf6Ds +.. section: Build + +Prevent missing 'getentropy' declaration warning on macOS. Patch by Gareth +Rees. + +.. + +.. bpo: 31392 +.. date: 2017-09-07-20-09-04 +.. nonce: h92bWF +.. section: Windows + +Update Windows build to use OpenSSL 1.1.0f + +.. + +.. bpo: 30389 +.. date: 2017-09-06-17-14-54 +.. nonce: 9Dizrx +.. section: Windows + +Adds detection of Visual Studio 2017 to distutils on Windows. + +.. + +.. bpo: 31358 +.. date: 2017-09-05-19-46-52 +.. nonce: n1Fjxc +.. section: Windows + +zlib is no longer bundled in the CPython source, instead it is downloaded on +demand just like bz2, lzma, OpenSSL, Tcl/Tk, and SQLite. + +.. + +.. bpo: 31340 +.. date: 2017-09-04-13-19-05 +.. nonce: MbkzLi +.. section: Windows + +Change to building with MSVC v141 (included with Visual Studio 2017) + +.. + +.. bpo: 30581 +.. date: 2017-08-04-10-05-19 +.. nonce: OQhR7l +.. section: Windows + +os.cpu_count() now returns the correct number of processors on Windows when +the number of logical processors is greater than 64. + +.. + +.. bpo: 30916 +.. date: 2017-07-15-00-40-12 +.. nonce: BpCrro +.. section: Windows + +Pre-build OpenSSL, Tcl and Tk and include the binaries in the build. + +.. + +.. bpo: 30731 +.. date: 2017-07-13-11-22-53 +.. nonce: nmMDwI +.. section: Windows + +Add a missing xmlns to python.manifest so that it matches the schema. + +.. + +.. bpo: 30291 +.. date: 2017-06-28-03-20-48 +.. nonce: zBpOl6 +.. section: Windows + +Allow requiring 64-bit interpreters from py.exe using -64 suffix. +Contributed by Steve (Gadget) Barnes. + +.. + +.. bpo: 30362 +.. date: 2017-06-28-03-08-22 +.. nonce: XxeVMB +.. section: Windows + +Adds list options (-0, -0p) to py.exe launcher. Contributed by Steve Barnes. + +.. + +.. bpo: 23451 +.. date: 2017-06-27-07-04-06 +.. nonce: bl_QOB +.. section: Windows + +Fix socket deprecation warnings in socketmodule.c. Patch by Segev Finer. + +.. + +.. bpo: 30450 +.. date: 0088 +.. nonce: qsaK8y +.. section: Windows + +The build process on Windows no longer depends on Subversion, instead +pulling external code from GitHub via a Python script. If Python 3.6 is not +found on the system (via ``py -3.6``), NuGet is used to download a copy of +32-bit Python. + +.. + +.. bpo: 29579 +.. date: 0087 +.. nonce: 07B-FQ +.. section: Windows + +Removes readme.txt from the installer. + +.. + +.. bpo: 25778 +.. date: 0086 +.. nonce: 8uKJ82 +.. section: Windows + +winreg does not truncate string correctly (Patch by Eryk Sun) + +.. + +.. bpo: 28896 +.. date: 0085 +.. nonce: qOcBBL +.. section: Windows + +Deprecate WindowsRegistryFinder and disable it by default + +.. + +.. bpo: 28522 +.. date: 0084 +.. nonce: XHMQa7 +.. section: Windows + +Fixes mishandled buffer reallocation in getpathp.c + +.. + +.. bpo: 28402 +.. date: 0083 +.. nonce: v9zETJ +.. section: Windows + +Adds signed catalog files for stdlib on Windows. + +.. + +.. bpo: 28333 +.. date: 0082 +.. nonce: KnpeO4 +.. section: Windows + +Enables Unicode for ps1/ps2 and input() prompts. (Patch by Eryk Sun) + +.. + +.. bpo: 28251 +.. date: 0081 +.. nonce: tR_AFs +.. section: Windows + +Improvements to help manuals on Windows. + +.. + +.. bpo: 28110 +.. date: 0080 +.. nonce: cnkP5F +.. section: Windows + +launcher.msi has different product codes between 32-bit and 64-bit + +.. + +.. bpo: 28161 +.. date: 0079 +.. nonce: hF91LI +.. section: Windows + +Opening CON for write access fails + +.. + +.. bpo: 28162 +.. date: 0078 +.. nonce: 3FHPVD +.. section: Windows + +WindowsConsoleIO readall() fails if first line starts with Ctrl+Z + +.. + +.. bpo: 28163 +.. date: 0077 +.. nonce: -DUgJw +.. section: Windows + +WindowsConsoleIO fileno() passes wrong flags to _open_osfhandle + +.. + +.. bpo: 28164 +.. date: 0076 +.. nonce: 5MfN0J +.. section: Windows + +_PyIO_get_console_type fails for various paths + +.. + +.. bpo: 28137 +.. date: 0075 +.. nonce: C1uvzY +.. section: Windows + +Renames Windows path file to ._pth + +.. + +.. bpo: 28138 +.. date: 0074 +.. nonce: pNdv64 +.. section: Windows + +Windows ._pth file should allow import site + +.. + +.. bpo: 31493 +.. date: 2017-09-16-23-43-39 +.. nonce: nmHMCR +.. section: IDLE + +IDLE code context -- fix code update and font update timers. +Canceling timers prevents a warning message when test_idle completes. + +.. + +.. bpo: 31488 +.. date: 2017-09-16-01-21-20 +.. nonce: 0rtXIT +.. section: IDLE + +IDLE - Update non-key options in former extension classes. When applying +configdialog changes, call .reload for each feature class. Change ParenMatch +so updated options affect existing instances attached to existing editor +windows. + +.. + +.. bpo: 31477 +.. date: 2017-09-15-12-38-47 +.. nonce: n__6sa +.. section: IDLE + +IDLE - Improve rstrip entry in doc. Strip trailing whitespace strips more +than blank spaces. Multiline string literals are not skipped. + +.. + +.. bpo: 31480 +.. date: 2017-09-14-17-53-53 +.. nonce: 4WJ0pl +.. section: IDLE + +IDLE - make tests pass with zzdummy extension disabled by default. + +.. + +.. bpo: 31421 +.. date: 2017-09-12-08-38-27 +.. nonce: mYfQNq +.. section: IDLE + +Document how IDLE runs tkinter programs. IDLE calls tcl/tk update in the +background in order to make live +interaction and experimentation with tkinter applications much easier. + +.. + +.. bpo: 31414 +.. date: 2017-09-11-15-46-05 +.. nonce: wiepgK +.. section: IDLE + +IDLE -- fix tk entry box tests by deleting first. Adding to an int entry is +not the same as deleting and inserting because int('') will fail. + +.. + +.. bpo: 31051 +.. date: 2017-08-30-00-06-58 +.. nonce: 50Jp_Q +.. section: IDLE + +Rearrange IDLE configdialog GenPage into Window, Editor, and Help sections. + +.. + +.. bpo: 30617 +.. date: 2017-08-27-16-49-36 +.. nonce: UHnswr +.. section: IDLE + +IDLE - Add docstrings and tests for outwin subclass of editor. +Move some data and functions from the class to module level. Patch by Cheryl +Sabella. + +.. + +.. bpo: 31287 +.. date: 2017-08-27-15-31-33 +.. nonce: aZERfI +.. section: IDLE + +IDLE - Do not modify tkinter.message in test_configdialog. + +.. + +.. bpo: 27099 +.. date: 2017-08-24-13-48-16 +.. nonce: rENefC +.. section: IDLE + +Convert IDLE's built-in 'extensions' to regular features. +About 10 IDLE features were implemented as supposedly optional extensions. +Their different behavior could be confusing or worse for users and not good +for maintenance. Hence the conversion. +The main difference for users is that user configurable key bindings for +builtin features are now handled uniformly. Now, editing a binding in a +keyset only affects its value in the keyset. All bindings are defined +together in the system-specific default keysets in config-extensions.def. +All custom keysets are saved as a whole in config-extension.cfg. All take +effect as soon as one clicks Apply or Ok. +The affected events are '<<force-open-completions>>', '<<expand-word>>', +'<<force-open-calltip>>', '<<flash-paren>>', '<<format-paragraph>>', +'<<run-module>>', '<<check-module>>', and '<<zoom-height>>'. Any (global) +customizations made before 3.6.3 will not affect their keyset-specific +customization after 3.6.3. and vice versa. +Initial patch by Charles Wohlganger. + +.. + +.. bpo: 31206 +.. date: 2017-08-18-14-13-42 +.. nonce: F1-tKK +.. section: IDLE + +IDLE: Factor HighPage(Frame) class from ConfigDialog. Patch by Cheryl +Sabella. + +.. + +.. bpo: 31001 +.. date: 2017-08-17-15-00-20 +.. nonce: KLxYHC +.. section: IDLE + +Add tests for configdialog highlight tab. Patch by Cheryl Sabella. + +.. + +.. bpo: 31205 +.. date: 2017-08-15-12-58-23 +.. nonce: iuziZ5 +.. section: IDLE + +IDLE: Factor KeysPage(Frame) class from ConfigDialog. The slightly modified +tests continue to pass. Patch by Cheryl Sabella. + +.. + +.. bpo: 31130 +.. date: 2017-08-07-14-02-56 +.. nonce: FbsC7f +.. section: IDLE + +IDLE -- stop leaks in test_configdialog. Initial patch by Victor Stinner. + +.. + +.. bpo: 31002 +.. date: 2017-08-03-17-54-02 +.. nonce: kUSgTE +.. section: IDLE + +Add tests for configdialog keys tab. Patch by Cheryl Sabella. + +.. + +.. bpo: 19903 +.. date: 2017-08-03-14-08-42 +.. nonce: sqE1FS +.. section: IDLE + +IDLE: Calltips use `inspect.signature` instead of `inspect.getfullargspec`. +This improves calltips for builtins converted to use Argument Clinic. Patch +by Louie Lu. + +.. + +.. bpo: 31083 +.. date: 2017-07-31-23-20-51 +.. nonce: 991FXm +.. section: IDLE + +IDLE - Add an outline of a TabPage class in configdialog. Update existing +classes to match outline. Initial patch by Cheryl Sabella. + +.. + +.. bpo: 31050 +.. date: 2017-07-30-17-39-59 +.. nonce: AXR3kP +.. section: IDLE + +Factor GenPage(Frame) class from ConfigDialog. The slightly modified tests +continue to pass. Patch by Cheryl Sabella. + +.. + +.. bpo: 31004 +.. date: 2017-07-30-01-00-58 +.. nonce: m8cc1t +.. section: IDLE + +IDLE - Factor FontPage(Frame) class from ConfigDialog. +Slightly modified tests continue to pass. Fix General tests. Patch mostly by +Cheryl Sabella. + +.. + +.. bpo: 30781 +.. date: 2017-07-28-18-59-06 +.. nonce: ud5m18 +.. section: IDLE + +IDLE - Use ttk widgets in ConfigDialog. Patches by Terry Jan Reedy and +Cheryl Sabella. + +.. + +.. bpo: 31060 +.. date: 2017-07-27-14-48-42 +.. nonce: GdY_VY +.. section: IDLE + +IDLE - Finish rearranging methods of ConfigDialog Grouping methods +pertaining to each tab and the buttons will aid writing tests and improving +the tabs and will enable splitting the groups into classes. + +.. + +.. bpo: 30853 +.. date: 2017-07-27-10-01-14 +.. nonce: enPvvc +.. section: IDLE + +IDLE -- Factor a VarTrace class out of ConfigDialog. +Instance tracers manages pairs consisting of a tk variable and a callback +function. When tracing is turned on, setting the variable calls the +function. Test coverage for the new class is 100%. + +.. + +.. bpo: 31003 +.. date: 2017-07-25-01-28-35 +.. nonce: bYINVH +.. section: IDLE + +IDLE: Add more tests for General tab. + +.. + +.. bpo: 30993 +.. date: 2017-07-22-18-08-41 +.. nonce: 34vJkB +.. section: IDLE + +IDLE - Improve configdialog font page and tests. +In configdialog: Document causal pathways in create_font_tab docstring. +Simplify some attribute names. Move set_samples calls to var_changed_font +(idea from Cheryl Sabella). Move related functions to positions after the +create widgets function. +In test_configdialog: Fix test_font_set so not order dependent. Fix renamed +test_indent_scale so it tests the widget. Adjust tests for movement of +set_samples call. Add tests for load functions. Put all font tests in one +class and tab indent tests in another. Except for two lines, these tests +completely cover the related functions. + +.. + +.. bpo: 30981 +.. date: 2017-07-21-01-55-14 +.. nonce: ZFvQPt +.. section: IDLE + +IDLE -- Add more configdialog font page tests. + +.. + +.. bpo: 28523 +.. date: 2017-07-21-00-54-52 +.. nonce: OPcqYJ +.. section: IDLE + +IDLE: replace 'colour' with 'color' in configdialog. + +.. + +.. bpo: 30917 +.. date: 2017-07-17-23-35-57 +.. nonce: hSiuuO +.. section: IDLE + +Add tests for idlelib.config.IdleConf. Increase coverage from 46% to 96%. +Patch by Louie Lu. + +.. + +.. bpo: 30934 +.. date: 2017-07-15-22-26-57 +.. nonce: BanuSB +.. section: IDLE + +Document coverage details for idlelib tests. +Add section to idlelib/idle-test/README.txt. +Include check that branches are taken both ways. +Exclude IDLE-specific code that does not run during unit tests. + +.. + +.. bpo: 30913 +.. date: 2017-07-13-23-07-33 +.. nonce: aezn_e +.. section: IDLE + +IDLE: Document ConfigDialog tk Vars, methods, and widgets in docstrings This +will facilitate improving the dialog and splitting up the class. Original +patch by Cheryl Sabella. + +.. + +.. bpo: 30899 +.. date: 2017-07-11-02-26-17 +.. nonce: SQmVO8 +.. section: IDLE + +IDLE: Add tests for ConfigParser subclasses in config. Patch by Louie Lu. + +.. + +.. bpo: 30881 +.. date: 2017-07-11-02-21-42 +.. nonce: 4KAq_9 +.. section: IDLE + +IDLE: Add docstrings to browser.py. Patch by Cheryl Sabella. + +.. + +.. bpo: 30851 +.. date: 2017-07-09-23-53-00 +.. nonce: AHXBYa +.. section: IDLE + +IDLE: Remove unused variables in configdialog. One is a duplicate, one is +set but cannot be altered by users. Patch by Cheryl Sabella. + +.. + +.. bpo: 30870 +.. date: 2017-07-08-17-57-04 +.. nonce: IcR2pf +.. section: IDLE + +IDLE: In Settings dialog, select font with Up, Down keys as well as mouse. +Initial patch by Louie Lu. + +.. + +.. bpo: 8231 +.. date: 2017-07-07-21-10-55 +.. nonce: yEge3L +.. section: IDLE + +IDLE: call config.IdleConf.GetUserCfgDir only once. + +.. + +.. bpo: 30779 +.. date: 2017-07-07-20-26-37 +.. nonce: 8KXEXN +.. section: IDLE + +IDLE: Factor ConfigChanges class from configdialog, put in config; test. * +In config, put dump test code in a function; run it and unittest in 'if +__name__ == '__main__'. * Add class config.ConfigChanges based on +changes_class_v4.py on bpo issue. * Add class test_config.ChangesTest, +partly using configdialog_tests_v1.py. * Revise configdialog to use +ConfigChanges; see tracker msg297804. * Revise test_configdialog to match +configdialog changes. * Remove configdialog functions unused or moved to +ConfigChanges. Cheryl Sabella contributed parts of the patch. + +.. + +.. bpo: 30777 +.. date: 2017-07-04-22-45-46 +.. nonce: uxzlMB +.. section: IDLE + +IDLE: configdialog - Add docstrings and fix comments. Patch by Cheryl +Sabella. + +.. + +.. bpo: 30495 +.. date: 2017-06-29-18-23-06 +.. nonce: qIWgc4 +.. section: IDLE + +IDLE: Improve textview with docstrings, PEP8 names, and more tests. Patch by +Cheryl Sabella. + +.. + +.. bpo: 30723 +.. date: 2017-06-27-19-05-40 +.. nonce: rQh06y +.. section: IDLE + +IDLE: Make several improvements to parenmatch. Add 'parens' style to +highlight both opener and closer. Make 'default' style, which is not +default, a synonym for 'opener'. Make time-delay work the same with all +styles. Add help for config dialog extensions tab, including help for +parenmatch. Add new tests. Original patch by Charles Wohlganger. + +.. + +.. bpo: 30674 +.. date: 2017-06-27-01-40-34 +.. nonce: ppK_q8 +.. section: IDLE + +IDLE: add docstrings to grep module. Patch by Cheryl Sabella + +.. + +.. bpo: 21519 +.. date: 2017-06-27-00-29-56 +.. nonce: fTj9T0 +.. section: IDLE + +IDLE's basic custom key entry dialog now detects duplicates properly. +Original patch by Saimadhav Heblikar. + +.. + +.. bpo: 29910 +.. date: 2017-06-26-22-45-27 +.. nonce: mqHh7u +.. section: IDLE + +IDLE no longer deletes a character after commenting out a region by a key +shortcut. Add ``return 'break'`` for this and other potential conflicts +between IDLE and default key bindings. + +.. + +.. bpo: 30728 +.. date: 2017-06-26-15-47-13 +.. nonce: qH4TGL +.. section: IDLE + +Review and change idlelib.configdialog names. Lowercase method and attribute +names. Replace 'colour' with 'color', expand overly cryptic names, delete +unneeded underscores. Replace ``import *`` with specific imports. Patches by +Cheryl Sabella. + +.. + +.. bpo: 6739 +.. date: 2017-06-26-00-28-59 +.. nonce: x5MfhB +.. section: IDLE + +IDLE: Verify user-entered key sequences by trying to bind them with tk. Add +tests for all 3 validation functions. Original patch by G Polo. Tests added +by Cheryl Sabella. + +.. + +.. bpo: 15786 +.. date: 0096 +.. nonce: _XRbaR +.. section: IDLE + +Fix several problems with IDLE's autocompletion box. The following should +now work: clicking on selection box items; using the scrollbar; selecting an +item by hitting Return. Hangs on MacOSX should no longer happen. Patch by +Louie Lu. + +.. + +.. bpo: 25514 +.. date: 0095 +.. nonce: 882pXa +.. section: IDLE + +Add doc subsubsection about IDLE failure to start. Popup no-connection +message directs users to this section. + +.. + +.. bpo: 30642 +.. date: 0094 +.. nonce: 3Zujzt +.. section: IDLE + +Fix reference leaks in IDLE tests. Patches by Louie Lu and Terry Jan Reedy. + +.. + +.. bpo: 30495 +.. date: 0093 +.. nonce: I3i5vL +.. section: IDLE + +Add docstrings for textview.py and use PEP8 names. Patches by Cheryl Sabella +and Terry Jan Reedy. + +.. + +.. bpo: 30290 +.. date: 0092 +.. nonce: fZ3kod +.. section: IDLE + +Help-about: use pep8 names and add tests. Increase coverage to 100%. Patches +by Louie Lu, Cheryl Sabella, and Terry Jan Reedy. + +.. + +.. bpo: 30303 +.. date: 0091 +.. nonce: 2L2F-4 +.. section: IDLE + +Add _utest option to textview; add new tests. Increase coverage to 100%. +Patches by Louie Lu and Terry Jan Reedy. + +.. + +.. bpo: 29071 +.. date: 0090 +.. nonce: FCOpJn +.. section: IDLE + +IDLE colors f-string prefixes (but not invalid ur prefixes). + +.. + +.. bpo: 28572 +.. date: 0089 +.. nonce: 1_duKY +.. section: IDLE + +Add 10% to coverage of IDLE's test_configdialog. Update and augment +description of the configuration system. + +.. + +.. bpo: 30983 +.. date: 2017-08-18-17-19-23 +.. nonce: ggGz9z +.. section: Tools/Demos + +gdb integration commands (py-bt, etc.) work on optimized shared builds now, +too. :pep:`523` introduced _PyEval_EvalFrameDefault which inlines +PyEval_EvalFrameEx on non-debug shared builds. This broke the ability to +use py-bt, py-up, and a few other Python-specific gdb integrations. The +problem is fixed by only looking for _PyEval_EvalFrameDefault frames in +python-gdb.py. Original patch by Bruno "Polaco" Penteado. + +.. + +.. bpo: 29748 +.. date: 0018 +.. nonce: 6pV6s9 +.. section: Tools/Demos + +Added the slice index converter in Argument Clinic. + +.. + +.. bpo: 24037 +.. date: 0017 +.. nonce: KPFC7o +.. section: Tools/Demos + +Argument Clinic now uses the converter `bool(accept={int})` rather than +`int` for semantical booleans. This avoids repeating the default value for +Python and C and will help in converting to `bool` in future. + +.. + +.. bpo: 29367 +.. date: 0016 +.. nonce: 4dOKL0 +.. section: Tools/Demos + +python-gdb.py now supports also ``method-wrapper`` (``wrapperobject``) +objects. + +.. + +.. bpo: 28023 +.. date: 0015 +.. nonce: 4gzSGp +.. section: Tools/Demos + +Fix python-gdb.py didn't support new dict implementation. + +.. + +.. bpo: 15369 +.. date: 0014 +.. nonce: bdZ3n- +.. section: Tools/Demos + +The pybench and pystone microbenchmark have been removed from Tools. Please +use the new Python benchmark suite https://github.com/python/pyperformance +which is more reliable and includes a portable version of pybench working on +Python 2 and Python 3. + +.. + +.. bpo: 28102 +.. date: 0013 +.. nonce: 5fKaek +.. section: Tools/Demos + +The zipfile module CLI now prints usage to stderr. Patch by Stephen J. +Turnbull. + +.. + +.. bpo: 31338 +.. date: 2017-09-05-17-51-12 +.. nonce: LjA43Y +.. section: C API + +Added the ``Py_UNREACHABLE()`` macro for code paths which are never expected +to be reached. This and a few other useful macros are now documented in the +C API manual. + +.. + +.. bpo: 30832 +.. date: 2017-07-03-17-25-40 +.. nonce: PcTAEP +.. section: C API + +Remove own implementation for thread-local storage. +CPython has provided the own implementation for thread-local storage (TLS) +on Python/thread.c, it's used in the case which a platform has not supplied +native TLS. However, currently all supported platforms (Windows and +pthreads) have provided native TLS and defined the Py_HAVE_NATIVE_TLS macro +with unconditional in any case. + +.. + +.. bpo: 30708 +.. date: 0073 +.. nonce: np-l1j +.. section: C API + +PyUnicode_AsWideCharString() now raises a ValueError if the second argument +is NULL and the wchar_t\* string contains null characters. + +.. + +.. bpo: 16500 +.. date: 0072 +.. nonce: lRpooa +.. section: C API + +Deprecate PyOS_AfterFork() and add PyOS_BeforeFork(), +PyOS_AfterFork_Parent() and PyOS_AfterFork_Child(). + +.. + +.. bpo: 6532 +.. date: 0071 +.. nonce: qcH6k1 +.. section: C API + +The type of results of PyThread_start_new_thread() and +PyThread_get_thread_ident(), and the id parameter of +PyThreadState_SetAsyncExc() changed from "long" to "unsigned long". + +.. + +.. bpo: 27867 +.. date: 0070 +.. nonce: J-8CGo +.. section: C API + +Function PySlice_GetIndicesEx() is deprecated and replaced with a macro if +Py_LIMITED_API is not set or set to the value between 0x03050400 and +0x03060000 (not including) or 0x03060100 or higher. Added functions +PySlice_Unpack() and PySlice_AdjustIndices(). + +.. + +.. bpo: 29083 +.. date: 0069 +.. nonce: tGTjr_ +.. section: C API + +Fixed the declaration of some public API functions. PyArg_VaParse() and +PyArg_VaParseTupleAndKeywords() were not available in limited API. +PyArg_ValidateKeywordArguments(), PyArg_UnpackTuple() and Py_BuildValue() +were not available in limited API of version < 3.3 when PY_SSIZE_T_CLEAN is +defined. + +.. + +.. bpo: 28769 +.. date: 0068 +.. nonce: Ecmtn8 +.. section: C API + +The result of PyUnicode_AsUTF8AndSize() and PyUnicode_AsUTF8() is now of +type ``const char *`` rather of ``char *``. + +.. + +.. bpo: 29058 +.. date: 0067 +.. nonce: 0wNVP8 +.. section: C API + +All stable API extensions added after Python 3.2 are now available only when +Py_LIMITED_API is set to the PY_VERSION_HEX value of the minimum Python +version supporting this API. + +.. + +.. bpo: 28822 +.. date: 0066 +.. nonce: gMqwvb +.. section: C API + +The index parameters *start* and *end* of PyUnicode_FindChar() are now +adjusted to behave like ``str[start:end]``. + +.. + +.. bpo: 28808 +.. date: 0065 +.. nonce: A03X6r +.. section: C API + +PyUnicode_CompareWithASCIIString() now never raises exceptions. + +.. + +.. bpo: 28761 +.. date: 0064 +.. nonce: iOgCoX +.. section: C API + +The fields name and doc of structures PyMemberDef, PyGetSetDef, +PyStructSequence_Field, PyStructSequence_Desc, and wrapperbase are now of +type ``const char *`` rather of ``char *``. + +.. + +.. bpo: 28748 +.. date: 0063 +.. nonce: AMgb_G +.. section: C API + +Private variable _Py_PackageContext is now of type ``const char *`` rather +of ``char *``. + +.. + +.. bpo: 19569 +.. date: 0062 +.. nonce: IPke0J +.. section: C API + +Compiler warnings are now emitted if use most of deprecated functions. + +.. + +.. bpo: 28426 +.. date: 0061 +.. nonce: zPwvbI +.. section: C API + +Deprecated undocumented functions PyUnicode_AsEncodedObject(), +PyUnicode_AsDecodedObject(), PyUnicode_AsDecodedUnicode() and +PyUnicode_AsEncodedUnicode(). diff --git a/Misc/NEWS.d/3.7.0a2.rst b/Misc/NEWS.d/3.7.0a2.rst new file mode 100644 index 00000000..0f107d8c --- /dev/null +++ b/Misc/NEWS.d/3.7.0a2.rst @@ -0,0 +1,683 @@ +.. bpo: 31558 +.. date: 2017-10-16-14-27-25 +.. nonce: K-uRRm +.. release date: 2017-10-16 +.. section: Core and Builtins + +``gc.freeze()`` is a new API that allows for moving all objects currently +tracked by the garbage collector to a permanent generation, effectively +removing them from future collection events. This can be used to protect +those objects from having their PyGC_Head mutated. In effect, this enables +great copy-on-write stability at fork(). + +.. + +.. bpo: 31642 +.. date: 2017-10-08-10-00-55 +.. nonce: 1IKqgs +.. section: Core and Builtins + +Restored blocking "from package import module" by setting +sys.modules["package.module"] to None. + +.. + +.. bpo: 31708 +.. date: 2017-10-06-02-10-48 +.. nonce: 66CCVU +.. section: Core and Builtins + +Allow use of asynchronous generator expressions in synchronous functions. + +.. + +.. bpo: 31709 +.. date: 2017-10-06-00-27-04 +.. nonce: _PmU51 +.. section: Core and Builtins + +Drop support of asynchronous __aiter__. + +.. + +.. bpo: 30404 +.. date: 2017-10-03-23-46-39 +.. nonce: _9Yi5u +.. section: Core and Builtins + +The -u option now makes the stdout and stderr streams unbuffered rather than +line-buffered. + +.. + +.. bpo: 31619 +.. date: 2017-09-29-20-32-24 +.. nonce: 6gQ1kv +.. section: Core and Builtins + +Fixed a ValueError when convert a string with large number of underscores to +integer with binary base. + +.. + +.. bpo: 31602 +.. date: 2017-09-27-09-30-03 +.. nonce: MtgLCn +.. section: Core and Builtins + +Fix an assertion failure in `zipimporter.get_source()` in case of a bad +`zlib.decompress()`. Patch by Oren Milman. + +.. + +.. bpo: 31592 +.. date: 2017-09-26-16-05-04 +.. nonce: IFBZj9 +.. section: Core and Builtins + +Fixed an assertion failure in Python parser in case of a bad +`unicodedata.normalize()`. Patch by Oren Milman. + +.. + +.. bpo: 31588 +.. date: 2017-09-26-13-03-16 +.. nonce: wT9Iy7 +.. section: Core and Builtins + +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: 31574 +.. date: 2017-09-25-12-35-48 +.. nonce: 5yX5r5 +.. section: Core and Builtins + +Importlib was instrumented with two dtrace probes to profile import timing. + +.. + +.. bpo: 31566 +.. date: 2017-09-24-09-57-04 +.. nonce: OxwINs +.. section: Core and Builtins + +Fix an assertion failure in `_warnings.warn()` in case of a bad ``__name__`` +global. Patch by Oren Milman. + +.. + +.. bpo: 31506 +.. date: 2017-09-19-10-29-36 +.. nonce: pRVTRB +.. section: Core and Builtins + +Improved the error message logic for object.__new__ and object.__init__. + +.. + +.. bpo: 31505 +.. date: 2017-09-18-12-07-39 +.. nonce: VomaFa +.. section: Core and Builtins + +Fix an assertion failure in `json`, in case `_json.make_encoder()` received +a bad `encoder()` argument. Patch by Oren Milman. + +.. + +.. bpo: 31492 +.. date: 2017-09-16-22-49-16 +.. nonce: RtyteL +.. section: Core and Builtins + +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: 31478 +.. date: 2017-09-15-09-13-07 +.. nonce: o06iKD +.. section: Core and Builtins + +Fix an assertion failure in `_random.Random.seed()` in case the argument has +a bad ``__abs__()`` method. Patch by Oren Milman. + +.. + +.. bpo: 31336 +.. date: 2017-09-13-12-04-23 +.. nonce: gi2ahY +.. section: Core and Builtins + +Speed up class creation by 10-20% by reducing the overhead in the necessary +special method lookups. Patch by Stefan Behnel. + +.. + +.. bpo: 31415 +.. date: 2017-09-11-14-28-56 +.. nonce: GBdz7o +.. section: Core and Builtins + +Add ``-X importtime`` option to show how long each import takes. It can be +used to optimize application's startup time. Support the +:envvar:`PYTHONPROFILEIMPORTTIME` as an equivalent way to enable this. + +.. + +.. bpo: 31410 +.. date: 2017-09-10-20-58-51 +.. nonce: wD_RbH +.. section: Core and Builtins + +Optimized calling wrapper and classmethod descriptors. + +.. + +.. bpo: 31353 +.. date: 2017-09-05-14-19-02 +.. nonce: oGZUeJ +.. section: Core and Builtins + +:pep:`553` - Add a new built-in called ``breakpoint()`` which calls +``sys.breakpointhook()``. By default this imports ``pdb`` and calls +``pdb.set_trace()``, but users may override ``sys.breakpointhook()`` to call +whatever debugger they want. The original value of the hook is saved in +``sys.__breakpointhook__``. + +.. + +.. bpo: 17852 +.. date: 2017-09-04-12-46-25 +.. nonce: OxAtCg +.. section: Core and Builtins + +Maintain a list of open buffered files, flush them before exiting the +interpreter. Based on a patch from Armin Rigo. + +.. + +.. bpo: 31315 +.. date: 2017-09-01-00-40-58 +.. nonce: ZX20bl +.. section: Core and Builtins + +Fix an assertion failure in imp.create_dynamic(), when spec.name is not a +string. Patch by Oren Milman. + +.. + +.. bpo: 31311 +.. date: 2017-08-31-17-52-56 +.. nonce: bNE2l- +.. section: Core and Builtins + +Fix a crash in the ``__setstate__()`` method of `ctypes._CData`, in case of +a bad ``__dict__``. Patch by Oren Milman. + +.. + +.. bpo: 31293 +.. date: 2017-08-28-17-51-42 +.. nonce: eMYZXj +.. section: Core and Builtins + +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 +.. date: 2017-08-27-21-18-30 +.. nonce: 7lzaKV +.. section: Core and Builtins + +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: 30406 +.. date: 2017-07-20-22-03-44 +.. nonce: _kr47t +.. section: Core and Builtins + +Make ``async`` and ``await`` proper keywords, as specified in :pep:`492`. + +.. + +.. bpo: 30058 +.. date: 2017-10-12-19-00-53 +.. nonce: cENtry +.. section: Library + +Fixed buffer overflow in select.kqueue.control(). + +.. + +.. bpo: 31672 +.. date: 2017-10-12-02-47-16 +.. nonce: DaOkVd +.. section: Library + +``idpattern`` in ``string.Template`` matched some non-ASCII characters. Now +it uses ``-i`` regular expression local flag to avoid non-ASCII characters. + +.. + +.. bpo: 31701 +.. date: 2017-10-09-17-42-30 +.. nonce: NRrVel +.. section: Library + +On Windows, faulthandler.enable() now ignores MSC and COM exceptions. + +.. + +.. bpo: 31728 +.. date: 2017-10-08-23-28-30 +.. nonce: XrVMME +.. section: Library + +Prevent crashes in `_elementtree` due to unsafe cleanup of `Element.text` +and `Element.tail`. Patch by Oren Milman. + +.. + +.. bpo: 31671 +.. date: 2017-10-04-21-28-44 +.. nonce: E-zfc9 +.. section: Library + +Now ``re.compile()`` converts passed RegexFlag to normal int object before +compiling. bm_regex_compile benchmark shows 14% performance improvements. + +.. + +.. bpo: 30397 +.. date: 2017-10-03-22-45-50 +.. nonce: e4F7Kr +.. section: Library + +The types of compiled regular objects and match objects are now exposed as +`re.Pattern` and `re.Match`. This adds information in pydoc output for the +re module. + +.. + +.. bpo: 31675 +.. date: 2017-10-03-15-06-24 +.. nonce: Nh7jJ3 +.. section: Library + +Fixed memory leaks in Tkinter's methods splitlist() and split() when pass a +string larger than 2 GiB. + +.. + +.. bpo: 31673 +.. date: 2017-10-03-14-37-46 +.. nonce: RFCrka +.. section: Library + +Fixed typo in the name of Tkinter's method adderrorinfo(). + +.. + +.. bpo: 31648 +.. date: 2017-09-30-10-45-12 +.. nonce: Cai7ji +.. section: Library + +Improvements to path predicates in ElementTree: +Allow whitespace around predicate parts, i.e. "[a = 'text']" instead of requiring the less readable "[a='text']". +Add support for text comparison of the current node, like "[.='text']". +Patch by Stefan Behnel. + +.. + +.. bpo: 30806 +.. date: 2017-09-29 +.. nonce: lP5GrH +.. section: Library + +Fix the string representation of a netrc object. + +.. + +.. bpo: 31638 +.. date: 2017-09-29-07-14-28 +.. nonce: jElfhl +.. section: Library + +Add optional argument ``compressed`` to ``zipapp.create_archive``, and add +option ``--compress`` to the command line interface of ``zipapp``. + +.. + +.. bpo: 25351 +.. date: 2017-09-28-23-10-51 +.. nonce: 2JmFpF +.. section: Library + +Avoid venv activate failures with undefined variables + +.. + +.. bpo: 20519 +.. date: 2017-09-28-13-17-33 +.. nonce: FteeQQ +.. section: Library + +Avoid ctypes use (if possible) and improve import time for uuid. + +.. + +.. bpo: 28293 +.. date: 2017-09-26-17-51-17 +.. nonce: UC5pm4 +.. section: Library + +The regular expression cache is no longer completely dumped when it is full. + +.. + +.. bpo: 31596 +.. date: 2017-09-26-11-38-52 +.. nonce: 50Eyel +.. section: Library + +Added pthread_getcpuclockid() to the time module + +.. + +.. bpo: 27494 +.. date: 2017-09-26-01-43-17 +.. nonce: 37QnaT +.. section: Library + +Make 2to3 accept a trailing comma in generator expressions. For example, +``set(x for x in [],)`` is now allowed. + +.. + +.. bpo: 30347 +.. date: 2017-09-25-14-04-30 +.. nonce: B4--_D +.. section: Library + +Stop crashes when concurrently iterate over itertools.groupby() iterators. + +.. + +.. bpo: 30346 +.. date: 2017-09-24-13-08-46 +.. nonce: Csse77 +.. section: Library + +An iterator produced by itertools.groupby() iterator now becomes exhausted +after advancing the groupby iterator. + +.. + +.. bpo: 31556 +.. date: 2017-09-22-23-48-49 +.. nonce: 9J0u5H +.. section: Library + +Cancel asyncio.wait_for future faster if timeout <= 0 + +.. + +.. bpo: 31540 +.. date: 2017-09-22-16-02-00 +.. nonce: ybDHT5 +.. section: Library + +Allow passing a context object in +:class:`concurrent.futures.ProcessPoolExecutor` constructor. Also, free job +resources in :class:`concurrent.futures.ProcessPoolExecutor` earlier to +improve memory usage when a worker waits for new jobs. + +.. + +.. bpo: 31516 +.. date: 2017-09-20-18-43-01 +.. nonce: 23Yuq3 +.. section: Library + +``threading.current_thread()`` should not return a dummy thread at shutdown. + +.. + +.. bpo: 31525 +.. date: 2017-09-19-18-48-21 +.. nonce: O2TIL2 +.. section: Library + +In the sqlite module, require the sqlite3_prepare_v2 API. Thus, the sqlite +module now requires sqlite version at least 3.3.9. + +.. + +.. bpo: 26510 +.. date: 2017-09-19-13-29-29 +.. nonce: oncW6V +.. section: Library + +argparse subparsers are now required by default. This matches behaviour in +Python 2. For optional subparsers, use the new parameter +``add_subparsers(required=False)``. Patch by Anthony Sottile. +(As of 3.7.0rc1, the default was changed to not required as had been the case +since Python 3.3.) + +.. + +.. bpo: 27541 +.. date: 2017-09-17-19-59-04 +.. nonce: cIMFJW +.. section: Library + +Reprs of subclasses of some collection and iterator classes (`bytearray`, +`array.array`, `collections.deque`, `collections.defaultdict`, +`itertools.count`, `itertools.repeat`) now contain actual type name insteads +of hardcoded name of the base class. + +.. + +.. bpo: 31351 +.. date: 2017-09-17-15-24-25 +.. nonce: yQdKv- +.. section: Library + +python -m ensurepip now exits with non-zero exit code if pip bootstrapping +has failed. + +.. + +.. bpo: 31389 +.. date: 2017-09-07-15-31-47 +.. nonce: jNFYqB +.. section: Library + +``pdb.set_trace()`` now takes an optional keyword-only argument ``header``. +If given, this is printed to the console just before debugging begins. + +.. + +.. bpo: 31537 +.. date: 2017-10-08-23-02-14 +.. nonce: SiFNM8 +.. section: Documentation + +Fix incorrect usage of ``get_history_length`` in readline documentation +example code. Patch by Brad Smith. + +.. + +.. bpo: 30085 +.. date: 2017-09-14-18-44-50 +.. nonce: 0J9w-u +.. section: Documentation + +The operator functions without double underscores are preferred for clarity. +The one with underscores are only kept for back-compatibility. + +.. + +.. bpo: 31696 +.. date: 2017-10-04-23-40-32 +.. nonce: Y3_aBV +.. section: Build + +Improve compiler version information in :data:`sys.version` when Python is +built with Clang. + +.. + +.. bpo: 31625 +.. date: 2017-09-28-23-21-20 +.. nonce: Bb2NXr +.. section: Build + +Stop using ranlib on static libraries. Instead, we assume ar supports the +'s' flag. + +.. + +.. bpo: 31624 +.. date: 2017-09-28-20-54-52 +.. nonce: 11w91_ +.. section: Build + +Remove support for BSD/OS. + +.. + +.. bpo: 22140 +.. date: 2017-09-26-22-39-58 +.. nonce: ZRf7Wn +.. section: Build + +Prevent double substitution of prefix in python-config.sh. + +.. + +.. bpo: 31569 +.. date: 2017-09-25-00-25-23 +.. nonce: TS49pM +.. section: Build + +Correct PCBuild/ case to PCbuild/ in build scripts and documentation. + +.. + +.. bpo: 31536 +.. date: 2017-09-20-21-32-21 +.. nonce: KUDjno +.. section: Build + +Avoid wholesale rebuild after `make regen-all` if nothing changed. + +.. + +.. bpo: 31460 +.. date: 2017-09-30-19-03-26 +.. nonce: HpveI6 +.. section: IDLE + +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 +.. date: 2017-09-30-13-59-18 +.. nonce: LxN4Vb +.. section: IDLE + +IDLE - Make _htest, _utest parameters keyword only. + +.. + +.. bpo: 31559 +.. date: 2017-09-23-12-52-24 +.. nonce: ydckYX +.. section: IDLE + +Remove test order dependence in idle_test.test_browser. + +.. + +.. bpo: 31459 +.. date: 2017-09-22-20-26-23 +.. nonce: L0pnH9 +.. section: IDLE + +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 +.. date: 2017-09-18-10-43-03 +.. nonce: Y_YDxA +.. section: IDLE + +Default fonts now are scaled on HiDPI displays. + +.. + +.. bpo: 1612262 +.. date: 2017-08-14-15-13-50 +.. nonce: -x_Oyq +.. section: IDLE + +IDLE module browser now shows nested classes and functions. Original patches +for code and tests by Guilherme Polo and Cheryl Sabella, respectively. + +.. + +.. bpo: 28280 +.. date: 2017-09-30-19-41-44 +.. nonce: K_EjpO +.. section: C API + +Make `PyMapping_Keys()`, `PyMapping_Values()` and `PyMapping_Items()` always +return a `list` (rather than a `list` or a `tuple`). Patch by Oren Milman. + +.. + +.. bpo: 31532 +.. date: 2017-09-20-21-59-52 +.. nonce: s9Cw9_ +.. section: C API + +Fix memory corruption due to allocator mix in getpath.c between Py_GetPath() +and Py_SetPath() + +.. + +.. bpo: 25658 +.. date: 2017-06-24-14-30-44 +.. nonce: vm8vGE +.. section: C API + +Implement :pep:`539` for Thread Specific Storage (TSS) API: it is a new Thread +Local Storage (TLS) API to CPython which would supersede use of the existing +TLS API within the CPython interpreter, while deprecating the existing API. +PEP written by Erik M. Bray, patch by Masayuki Yamamoto. diff --git a/Misc/NEWS.d/3.7.0a3.rst b/Misc/NEWS.d/3.7.0a3.rst new file mode 100644 index 00000000..69db9fcd --- /dev/null +++ b/Misc/NEWS.d/3.7.0a3.rst @@ -0,0 +1,1615 @@ +.. bpo: 32176 +.. date: 2017-12-02-21-37-22 +.. nonce: Wt25-N +.. release date: 2017-12-05 +.. section: Core and Builtins + +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: 10544 +.. date: 2017-11-27-08-37-34 +.. nonce: 07nioT +.. section: Core and Builtins + +Yield expressions are now deprecated in comprehensions and generator +expressions. They are still permitted in the definition of the outermost +iterable, as that is evaluated directly in the enclosing scope. + +.. + +.. bpo: 32137 +.. date: 2017-11-26-14-36-30 +.. nonce: Stj5nL +.. section: Core and Builtins + +The repr of deeply nested dict now raises a RecursionError instead of +crashing due to a stack overflow. + +.. + +.. bpo: 32096 +.. date: 2017-11-24-01-13-58 +.. nonce: CQTHXJ +.. section: Core and Builtins + +Revert memory allocator changes in the C API: move structures back from +_PyRuntime to Objects/obmalloc.c. The memory allocators are once again +initialized statically, and so PyMem_RawMalloc() and Py_DecodeLocale() can +be called before _PyRuntime_Initialize(). + +.. + +.. bpo: 32043 +.. date: 2017-11-16-03-44-08 +.. nonce: AAzwpZ +.. section: Core and Builtins + +Add a new "developer mode": new "-X dev" command line option to enable debug +checks at runtime. + +.. + +.. bpo: 32023 +.. date: 2017-11-15-10-49-35 +.. nonce: XnCGT5 +.. section: Core and Builtins + +SyntaxError is now correctly raised when a generator expression without +parenthesis is used instead of an inheritance list in a class definition. +The duplication of the parentheses can be omitted only on calls. + +.. + +.. bpo: 32012 +.. date: 2017-11-13-00-37-11 +.. nonce: Kprjqe +.. section: Core and Builtins + +SyntaxError is now correctly raised when a generator expression without +parenthesis is passed as an argument, but followed by a trailing comma. A +generator expression always needs to be directly inside a set of parentheses +and cannot have a comma on either side. + +.. + +.. bpo: 28180 +.. date: 2017-11-12-11-44-22 +.. nonce: HQX000 +.. section: Core and Builtins + +A new internal ``_Py_SetLocaleFromEnv(category)`` helper function has been +added in order to improve the consistency of behaviour across different +``libc`` implementations (e.g. Android doesn't support setting the locale +from the environment by default). + +.. + +.. bpo: 31949 +.. date: 2017-11-05-16-11-07 +.. nonce: 2yNC_z +.. section: Core and Builtins + +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 +.. date: 2017-10-28-22-06-03 +.. nonce: lhC3HE +.. section: Core and Builtins + +Fix the interactive interpreter looping endlessly when no memory. + +.. + +.. bpo: 20047 +.. date: 2017-10-28-19-11-05 +.. nonce: GuNAto +.. section: Core and Builtins + +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: 21720 +.. date: 2017-10-25-15-51-37 +.. nonce: BwIKLP +.. section: Core and Builtins + +BytesWarning no longer emitted when the *fromlist* argument of +``__import__()`` or the ``__all__`` attribute of the module contain bytes +instances. + +.. + +.. bpo: 31845 +.. date: 2017-10-24-21-27-32 +.. nonce: 8OS-k3 +.. section: Core and Builtins + +Environment variables are once more read correctly at interpreter startup. + +.. + +.. bpo: 28936 +.. date: 2017-10-23-23-39-26 +.. nonce: C288Jh +.. section: Core and Builtins + +Ensure that lexically first syntax error involving a parameter and +``global`` or ``nonlocal`` is detected first at a given scope. Patch by Ivan +Levkivskyi. + +.. + +.. bpo: 31825 +.. date: 2017-10-20-14-07-46 +.. nonce: gJvmGW +.. section: Core and Builtins + +Fixed OverflowError in the 'unicode-escape' codec and in +codecs.escape_decode() when decode an escaped non-ascii byte. + +.. + +.. bpo: 31618 +.. date: 2017-10-18-19-41-12 +.. nonce: liLDiS +.. section: Core and Builtins + +The per-frame tracing logic added in 3.7a1 has been altered so that +``frame->f_lineno`` is updated before either ``"line"`` or ``"opcode"`` +events are emitted. Previously, opcode events were emitted first, and +therefore would occasionally see stale line numbers on the frame. The +behavior of this feature has changed slightly as a result: when both +``f_trace_lines`` and ``f_trace_opcodes`` are enabled, line events now occur +first. + +.. + +.. bpo: 28603 +.. date: 2017-10-17-13-29-19 +.. nonce: _-oia3 +.. section: Core and Builtins + +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 +.. date: 2017-10-15-23-44-57 +.. nonce: XwdEP4 +.. section: Core and Builtins + +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: 31781 +.. date: 2017-10-13-20-01-47 +.. nonce: cXE9SM +.. section: Core and Builtins + +Prevent crashes when calling methods of an uninitialized +``zipimport.zipimporter`` object. Patch by Oren Milman. + +.. + +.. bpo: 30399 +.. date: 2017-10-12-22-21-01 +.. nonce: 45f1gv +.. section: Core and Builtins + +Standard repr() of BaseException with a single argument no longer contains +redundant trailing comma. + +.. + +.. bpo: 31626 +.. date: 2017-10-01-15-48-03 +.. nonce: reLPxY +.. section: Core and Builtins + +Fixed a bug in debug memory allocator. There was a write to freed memory +after shrinking a memory block. + +.. + +.. bpo: 30817 +.. date: 2017-07-01-15-11-13 +.. nonce: j7ZvN_ +.. section: Core and Builtins + +`PyErr_PrintEx()` clears now the ignored exception that may be raised by +`_PySys_SetObjectId()`, for example when no memory. + +.. + +.. bpo: 28556 +.. date: 2017-12-05-02-03-07 +.. nonce: 9Z_PsJ +.. section: Library + +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: 32214 +.. date: 2017-12-04-15-51-57 +.. nonce: uozdNj +.. section: Library + +PEP 557, Data Classes. Provides a decorator which adds boilerplate methods +to classes which use type annotations so specify fields. + +.. + +.. bpo: 27240 +.. date: 2017-12-02-16-06-00 +.. nonce: Kji34M +.. section: Library + +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 +.. date: 2017-11-30-20-38-16 +.. nonce: O42bVe +.. section: Library + +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: 32101 +.. date: 2017-11-29-00-42-47 +.. nonce: -axD5l +.. section: Library + +Add :attr:`sys.flags.dev_mode` flag + +.. + +.. bpo: 32154 +.. date: 2017-11-28-15-27-10 +.. nonce: kDox7L +.. section: Library + +The ``asyncio.windows_utils.socketpair()`` function has been removed: use +directly :func:`socket.socketpair` which is available on all platforms since +Python 3.5 (before, it wasn't available on Windows). +``asyncio.windows_utils.socketpair()`` was just an alias to +``socket.socketpair`` on Python 3.5 and newer. + +.. + +.. bpo: 32089 +.. date: 2017-11-27-11-29-34 +.. nonce: 6ydDYv +.. section: Library + +warnings: In development (-X dev) and debug mode (pydebug build), use the +"default" action for ResourceWarning, rather than the "always" action, in +the default warnings filters. + +.. + +.. bpo: 32107 +.. date: 2017-11-26-18-48-17 +.. nonce: h2ph2K +.. section: Library + +``uuid.getnode()`` now preferentially returns universally administered MAC +addresses if available, over locally administered MAC addresses. This makes +a better guarantee for global uniqueness of UUIDs returned from +``uuid.uuid1()``. If only locally administered MAC addresses are available, +the first such one found is returned. + +.. + +.. bpo: 23033 +.. date: 2017-11-26-17-00-52 +.. nonce: YGXRWT +.. section: Library + +Wildcard is now supported in hostname when it is one and only character in +the left most segment of hostname in second argument of +:meth:`ssl.match_hostname`. Patch by Mandeep Singh. + +.. + +.. bpo: 12239 +.. date: 2017-11-24-14-07-55 +.. nonce: Nj3A0x +.. section: Library + +Make :meth:`msilib.SummaryInformation.GetProperty` return ``None`` when the +value of property is ``VT_EMPTY``. Initial patch by Mark Mc Mahon. + +.. + +.. bpo: 28334 +.. date: 2017-11-24-11-50-41 +.. nonce: 3gGGlt +.. section: Library + +Use :func:`os.path.expanduser` to find the ``~/.netrc`` file in +:class:`netrc.netrc`. If it does not exist, :exc:`FileNotFoundError` is +raised. Patch by Dimitri Merejkowsky. + +.. + +.. bpo: 32121 +.. date: 2017-11-24-00-59-12 +.. nonce: ePbmwC +.. section: Library + +Made ``tracemalloc.Traceback`` behave more like the traceback module, +sorting the frames from oldest to most recent. ``Traceback.format()`` now +accepts negative *limit*, truncating the result to the ``abs(limit)`` oldest +frames. To get the old behaviour, one can use the new *most_recent_first* +argument to ``Traceback.format()``. (Patch by Jesse Bakker.) + +.. + +.. bpo: 31325 +.. date: 2017-11-23-22-12-11 +.. nonce: 8jAUxN +.. section: Library + +Fix wrong usage of :func:`collections.namedtuple` in the +:meth:`RobotFileParser.parse() <urllib.robotparser.RobotFileParser.parse>` +method. +Initial patch by Robin Wellner. + +.. + +.. bpo: 12382 +.. date: 2017-11-23-21-47-36 +.. nonce: xWT9k0 +.. section: Library + +: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: 19610 +.. date: 2017-11-23-16-15-55 +.. nonce: Dlca2P +.. section: Library + +``setup()`` now warns about invalid types for some fields. +The ``distutils.dist.Distribution`` class now warns when ``classifiers``, +``keywords`` and ``platforms`` fields are not specified as a list or a +string. + +.. + +.. bpo: 32071 +.. date: 2017-11-22-19-52-17 +.. nonce: 4WNhUH +.. section: Library + +Added the ``-k`` command-line option to ``python -m unittest`` to run only +tests that match the given pattern(s). + +.. + +.. bpo: 10049 +.. date: 2017-11-22-17-21-01 +.. nonce: ttsBqb +.. section: Library + +Added *nullcontext* no-op context manager to contextlib. This provides a +simpler and faster alternative to ExitStack() when handling optional context +managers. + +.. + +.. bpo: 28684 +.. date: 2017-11-22-12-54-46 +.. nonce: NLiDKZ +.. section: Library + +The new test.support.skip_unless_bind_unix_socket() decorator is used here +to skip asyncio tests that fail because the platform lacks a functional +bind() function for unix domain sockets (as it is the case for non root +users on the recent Android versions that run now SELinux in enforcing +mode). + +.. + +.. bpo: 32110 +.. date: 2017-11-22-09-44-15 +.. nonce: VJa9bo +.. section: Library + +``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: 27535 +.. date: 2017-11-21-16-05-35 +.. nonce: JLhcNz +.. section: Library + +The warnings module doesn't leak memory anymore in the hidden warnings +registry for the "ignore" action of warnings filters. warn_explicit() +function doesn't add the warning key to the registry anymore for the +"ignore" action. + +.. + +.. bpo: 32088 +.. date: 2017-11-20-15-28-31 +.. nonce: mV-4Nu +.. section: Library + +warnings: When Python is build is debug mode (``Py_DEBUG``), +:exc:`DeprecationWarning`, :exc:`PendingDeprecationWarning` and +:exc:`ImportWarning` warnings are now displayed by default. + +.. + +.. bpo: 1647489 +.. date: 2017-11-20-01-29-46 +.. nonce: -ZNNkh +.. section: Library + +Fixed searching regular expression patterns that could match an empty +string. Non-empty string can now be correctly found after matching an empty +string. + +.. + +.. bpo: 25054 +.. date: 2017-11-20-01-01-01 +.. nonce: rOlRV6 +.. section: Library + +Added support of splitting on a pattern that could match an empty string. + +.. + +.. bpo: 32072 +.. date: 2017-11-18-21-13-52 +.. nonce: nwDV8L +.. section: Library + +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: 32069 +.. date: 2017-11-18-17-09-01 +.. nonce: S0wyy4 +.. section: Library + +Drop legacy SSL transport from asyncio, ssl.MemoryBIO is always used anyway. + +.. + +.. bpo: 32066 +.. date: 2017-11-17-18-28-53 +.. nonce: OMQFLH +.. section: Library + +asyncio: Support pathlib.Path in create_unix_connection; sock arg should be +optional + +.. + +.. bpo: 32046 +.. date: 2017-11-16-20-09-45 +.. nonce: 9sGDtw +.. section: Library + +Updates 2to3 to convert from operator.isCallable(obj) to callable(obj). +Patch by Donghee Na. + +.. + +.. bpo: 32018 +.. date: 2017-11-16-02-32-41 +.. nonce: YMQ7Q2 +.. section: Library + +inspect.signature should follow :pep:`8`, if the parameter has an annotation +and a default value. Patch by Donghee Na. + +.. + +.. bpo: 32025 +.. date: 2017-11-15-20-03-45 +.. nonce: lnIKYT +.. section: Library + +Add time.thread_time() and time.thread_time_ns() + +.. + +.. bpo: 32037 +.. date: 2017-11-15-19-04-22 +.. nonce: r8-5Nk +.. section: Library + +Integers that fit in a signed 32-bit integer will be now pickled with +protocol 0 using the INT opcode. This will decrease the size of a pickle, +speed up pickling and unpickling, and make these integers be unpickled as +int instances in Python 2. + +.. + +.. bpo: 32034 +.. date: 2017-11-15-13-44-28 +.. nonce: uHAOmu +.. section: Library + +Make asyncio.IncompleteReadError and LimitOverrunError pickleable. + +.. + +.. bpo: 32015 +.. date: 2017-11-13-17-48-33 +.. nonce: 4nqRTD +.. section: Library + +Fixed the looping of asyncio in the case of reconnection the socket during +waiting async read/write from/to the socket. + +.. + +.. bpo: 32011 +.. date: 2017-11-12-20-47-59 +.. nonce: NzVDdZ +.. section: Library + +Restored support of loading marshal files with the TYPE_INT64 code. These +files can be produced in Python 2.7. + +.. + +.. bpo: 28369 +.. date: 2017-11-10-16-27-26 +.. nonce: IS74nd +.. section: Library + +Enhance add_reader/writer check that socket is not used by some transport. +Before, only cases when add_reader/writer were called with an int FD were +supported. Now the check is implemented correctly for all file-like +objects. + +.. + +.. bpo: 31976 +.. date: 2017-11-09-21-36-32 +.. nonce: EOA7qY +.. section: Library + +Fix race condition when flushing a file is slow, which can cause a segfault +if closing the file from another thread. + +.. + +.. bpo: 31985 +.. date: 2017-11-08-16-51-52 +.. nonce: dE_fOB +.. section: Library + +Formally deprecated aifc.openfp, sunau.openfp, and wave.openfp. Since change +7bc817d5ba917528e8bd07ec461c635291e7b06a in 1993, openfp in each of the +three modules had been pointing to that module's open function as a matter +of backwards compatibility, though it had been both untested and +undocumented. + +.. + +.. bpo: 21862 +.. date: 2017-11-07-15-19-52 +.. nonce: RwietE +.. section: Library + +cProfile command line now accepts `-m module_name` as an alternative to +script path. Patch by Sanyam Khurana. + +.. + +.. bpo: 31970 +.. date: 2017-11-07-14-20-09 +.. nonce: x4EN_9 +.. section: Library + +Reduce performance overhead of asyncio debug mode. + +.. + +.. bpo: 31843 +.. date: 2017-11-07-00-37-50 +.. nonce: lM2gkR +.. section: Library + +*database* argument of sqlite3.connect() now accepts a :term:`path-like +object`, instead of just a string. + +.. + +.. bpo: 31945 +.. date: 2017-11-05-01-17-12 +.. nonce: TLPBtS +.. section: Library + +Add Configurable *blocksize* to ``HTTPConnection`` and ``HTTPSConnection`` +for improved upload throughput. Patch by Nir Soffer. + +.. + +.. bpo: 31943 +.. date: 2017-11-04-19-28-08 +.. nonce: bxw5gM +.. section: Library + +Add a ``cancelled()`` method to :class:`asyncio.Handle`. Patch by Marat +Sharafutdinov. + +.. + +.. bpo: 9678 +.. date: 2017-11-03-22-05-47 +.. nonce: oD51q6 +.. section: Library + +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 +.. date: 2017-11-03-19-11-43 +.. nonce: NCaijI +.. section: Library + +Fix potential missed signal in signal.signal(). + +.. + +.. bpo: 31933 +.. date: 2017-11-03-08-36-03 +.. nonce: UrtoMP +.. section: Library + +Fix Blake2 params leaf_size and node_offset on big endian platforms. Patch +by Jack O'Connor. + +.. + +.. bpo: 21423 +.. date: 2017-11-02-22-26-16 +.. nonce: hw5mEh +.. section: Library + +Add an initializer argument to {Process,Thread}PoolExecutor + +.. + +.. bpo: 31927 +.. date: 2017-11-02-18-26-40 +.. nonce: 40K6kp +.. section: Library + +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 +.. date: 2017-11-01-18-13-42 +.. nonce: j2zRnF +.. section: Library + +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: 31917 +.. date: 2017-11-01-03-28-24 +.. nonce: DYQL0g +.. section: Library + +Add 3 new clock identifiers: :const:`time.CLOCK_BOOTTIME`, +:const:`time.CLOCK_PROF` and :const:`time.CLOCK_UPTIME`. + +.. + +.. bpo: 31897 +.. date: 2017-10-30-11-04-56 +.. nonce: yjwdEb +.. section: Library + +plistlib now catches more errors when read binary plists and raises +InvalidFileException instead of unexpected exceptions. + +.. + +.. bpo: 25720 +.. date: 2017-10-29-17-52-40 +.. nonce: vSvb5h +.. section: Library + +Fix the method for checking pad state of curses WINDOW. Patch by Masayuki +Yamamoto. + +.. + +.. bpo: 31893 +.. date: 2017-10-29-13-51-01 +.. nonce: 8LZKEz +.. section: Library + +Fixed the layout of the kqueue_event structure on OpenBSD and NetBSD. Fixed +the comparison of the kqueue_event objects. + +.. + +.. bpo: 31891 +.. date: 2017-10-29-11-23-24 +.. nonce: 9kAPha +.. section: Library + +Fixed building the curses module on NetBSD. + +.. + +.. bpo: 31884 +.. date: 2017-10-27 +.. nonce: bjhre9 +.. section: Library + +added required constants to subprocess module for setting priority on +windows + +.. + +.. bpo: 28281 +.. date: 2017-10-26-14-54-38 +.. nonce: 7ZN5FG +.. section: Library + +Remove year (1-9999) limits on the Calendar.weekday() function. +Patch by Mark Gollahon. + +.. + +.. bpo: 31702 +.. date: 2017-10-24-21-10-44 +.. nonce: SfwJDI +.. section: Library + +crypt.mksalt() now allows to specify the number of rounds for SHA-256 and +SHA-512 hashing. + +.. + +.. bpo: 30639 +.. date: 2017-10-24-12-24-56 +.. nonce: ptNM9a +.. section: Library + +:func:`inspect.getfile` no longer computes the repr of unknown objects to +display in an error message, to protect against badly behaved custom reprs. + +.. + +.. bpo: 30768 +.. date: 2017-10-24-12-00-16 +.. nonce: Om8Yj_ +.. section: Library + +Fix the pthread+semaphore implementation of PyThread_acquire_lock_timed() +when called with timeout > 0 and intr_flag=0: recompute the timeout if +sem_timedwait() is interrupted by a signal (EINTR). See also the :pep:`475`. + +.. + +.. bpo: 31854 +.. date: 2017-10-23 +.. nonce: fh8334f +.. section: Library + +Add ``mmap.ACCESS_DEFAULT`` constant. + +.. + +.. bpo: 31834 +.. date: 2017-10-23-23-27-52 +.. nonce: InwC6O +.. section: Library + +Use optimized code for BLAKE2 only with SSSE3+. The pure SSE2 implementation +is slower than the pure C reference implementation. + +.. + +.. bpo: 28292 +.. date: 2017-10-23-20-03-36 +.. nonce: 1Gkim2 +.. section: Library + +Calendar.itermonthdates() will now consistently raise an exception when a +date falls outside of the 0001-01-01 through 9999-12-31 range. To support +applications that cannot tolerate such exceptions, the new methods +itermonthdays3() and itermonthdays4() are added. The new methods return +tuples and are not restricted by the range supported by datetime.date. + +.. + +.. bpo: 28564 +.. date: 2017-10-23-16-22-54 +.. nonce: Tx-l-I +.. section: Library + +The shutil.rmtree() function has been sped up to 20--40%. This was done +using the os.scandir() function. + +.. + +.. bpo: 28416 +.. date: 2017-10-23-12-05-33 +.. nonce: Ldnw8X +.. section: Library + +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: 31653 +.. date: 2017-10-22-12-43-03 +.. nonce: ttfGvq +.. section: Library + +Don't release the GIL if we can acquire a multiprocessing semaphore +immediately. + +.. + +.. bpo: 28326 +.. date: 2017-10-22-11-06-02 +.. nonce: rxh7L4 +.. section: Library + +Fix multiprocessing.Process when stdout and/or stderr is closed or None. + +.. + +.. bpo: 20825 +.. date: 2017-10-21-09-13-16 +.. nonce: -1MBEy +.. section: Library + +Add `subnet_of` and `superset_of` containment tests to +:class:`ipaddress.IPv6Network` and :class:`ipaddress.IPv4Network`. Patch by +Michel Albert and Cheryl Sabella. + +.. + +.. bpo: 31827 +.. date: 2017-10-20-16-12-01 +.. nonce: 7R8s8s +.. section: Library + +Remove the os.stat_float_times() function. It was introduced in Python 2.3 +for backward compatibility with Python 2.2, and was deprecated since Python +3.1. + +.. + +.. bpo: 31756 +.. date: 2017-10-20-12-57-52 +.. nonce: IxCvGB +.. section: Library + +Add a ``subprocess.Popen(text=False)`` keyword argument to `subprocess` +functions to be more explicit about when the library should attempt to +decode outputs into text. Patch by Andrew Clegg. + +.. + +.. bpo: 31819 +.. date: 2017-10-19-20-03-13 +.. nonce: mw2wF9 +.. section: Library + +Add AbstractEventLoop.sock_recv_into(). + +.. + +.. bpo: 31457 +.. date: 2017-10-18-19-05-17 +.. nonce: KlE6r8 +.. section: Library + +If nested log adapters are used, the inner ``process()`` methods are no +longer omitted. + +.. + +.. bpo: 31457 +.. date: 2017-10-18-16-48-09 +.. nonce: _ovmzp +.. section: Library + +The ``manager`` property on LoggerAdapter objects is now properly settable. + +.. + +.. bpo: 31806 +.. date: 2017-10-17-23-27-03 +.. nonce: TzphdL +.. section: Library + +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: 31803 +.. date: 2017-10-17-22-55-13 +.. nonce: YLL1gJ +.. section: Library + +time.clock() and time.get_clock_info('clock') now emit a DeprecationWarning +warning. + +.. + +.. bpo: 31800 +.. date: 2017-10-17-20-08-19 +.. nonce: foOSCi +.. section: Library + +Extended support for parsing UTC offsets. strptime '%z' can now parse the +output generated by datetime.isoformat, including seconds and microseconds. + +.. + +.. bpo: 28603 +.. date: 2017-10-17-12-29-18 +.. nonce: tGuX2C +.. section: Library + +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: 30541 +.. date: 2017-10-17-12-04-37 +.. nonce: q3BM6C +.. section: Library + +Add new function to seal a mock and prevent the automatically creation of +child mocks. Patch by Mario Corchero. + +.. + +.. bpo: 31784 +.. date: 2017-10-13-23-35-47 +.. nonce: 6e57bd +.. section: Library + +Implement the :pep:`564`, add new 6 new functions with nanosecond resolution +to the :mod:`time` module: :func:`~time.clock_gettime_ns`, +:func:`~time.clock_settime_ns`, :func:`~time.monotonic_ns`, +:func:`~time.perf_counter_ns`, :func:`~time.process_time_ns`, +:func:`~time.time_ns`. + +.. + +.. bpo: 30143 +.. date: 2017-10-12-19-05-54 +.. nonce: 25_hU1 +.. section: Library + +2to3 now generates a code that uses abstract collection classes from +collections.abc rather than collections. + +.. + +.. bpo: 31770 +.. date: 2017-10-12-18-45-38 +.. nonce: GV3MPx +.. section: Library + +Prevent a crash when calling the ``__init__()`` method of a +``sqlite3.Cursor`` object more than once. Patch by Oren Milman. + +.. + +.. bpo: 31764 +.. date: 2017-10-11-22-18-04 +.. nonce: EMyIkK +.. section: Library + +Prevent a crash in ``sqlite3.Cursor.close()`` in case the ``Cursor`` object +is uninitialized. Patch by Oren Milman. + +.. + +.. bpo: 31752 +.. date: 2017-10-11-00-45-01 +.. nonce: DhWevN +.. section: Library + +Fix possible crash in timedelta constructor called with custom integers. + +.. + +.. bpo: 31620 +.. date: 2017-10-06-04-35-31 +.. nonce: gksLA1 +.. section: Library + +an empty asyncio.Queue now doesn't leak memory when queue.get pollers +timeout + +.. + +.. bpo: 31690 +.. date: 2017-10-05-15-14-46 +.. nonce: f0XteV +.. section: Library + +Allow the flags re.ASCII, re.LOCALE, and re.UNICODE to be used as group +flags for regular expressions. + +.. + +.. bpo: 30349 +.. date: 2017-10-05-12-45-29 +.. nonce: 6zKJsF +.. section: Library + +FutureWarning is now emitted if a regular expression contains character set +constructs that will change semantically in the future (nested sets and set +operations). + +.. + +.. bpo: 31664 +.. date: 2017-10-04-20-36-28 +.. nonce: 4VDUzo +.. section: Library + +Added support for the Blowfish hashing in the crypt module. + +.. + +.. bpo: 31632 +.. date: 2017-10-04-11-37-14 +.. nonce: LiOC3C +.. section: Library + +Fix method set_protocol() of class _SSLProtocolTransport in asyncio module. +This method was previously modifying a wrong reference to the protocol. + +.. + +.. bpo: 15037 +.. date: 2017-09-29-19-19-36 +.. nonce: ykimLK +.. section: Library + +Added a workaround for getkey() in curses for ncurses 5.7 and earlier. + +.. + +.. bpo: 31307 +.. date: 2017-09-07-12-50-28 +.. nonce: AVBiNY +.. section: Library + +Allow use of bytes objects for arguments to +:meth:`configparser.ConfigParser.read`. Patch by Vincent Michel. + +.. + +.. bpo: 31334 +.. date: 2017-09-04-00-22-31 +.. nonce: 9WYRfi +.. section: Library + +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 +.. date: 2017-08-30-18-23-54 +.. nonce: 7D1UNt +.. section: Library + +multiprocessing's semaphore tracker should be launched again if crashed. + +.. + +.. bpo: 31308 +.. date: 2017-08-30-17-59-36 +.. nonce: KbexyC +.. section: Library + +Make multiprocessing's forkserver process immune to Ctrl-C and other user +interruptions. If it crashes, restart it when necessary. + +.. + +.. bpo: 31245 +.. date: 2017-08-22-11-05-35 +.. nonce: AniZuz +.. section: Library + +Added support for AF_UNIX socket in asyncio `create_datagram_endpoint`. + +.. + +.. bpo: 30553 +.. date: 2017-07-05-14-48-26 +.. nonce: Oupsxo +.. section: Library + +Add HTTP/2 status code 421 (Misdirected Request) to +:class:`http.HTTPStatus`. Patch by Vitor Pereira. + +.. + +.. bpo: 32105 +.. date: 2017-11-21-10-54-16 +.. nonce: 91mhWm +.. section: Documentation + +Added asyncio.BaseEventLoop.connect_accepted_socket versionadded marker. + +.. + +.. bpo: 31380 +.. date: 2017-12-04-23-19-16 +.. nonce: VlMmHW +.. section: Tests + +Skip test_httpservers test_undecodable_file on macOS: fails on APFS. + +.. + +.. bpo: 31705 +.. date: 2017-11-30-12-27-10 +.. nonce: yULW7O +.. section: Tests + +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: 32138 +.. date: 2017-11-27-16-18-58 +.. nonce: QsTvf- +.. section: Tests + +Skip on Android test_faulthandler tests that raise SIGSEGV and remove the +test.support.requires_android_level decorator. + +.. + +.. bpo: 32136 +.. date: 2017-11-26-17-11-27 +.. nonce: Y11luJ +.. section: Tests + +The runtime embedding tests have been split out from +``Lib/test/test_capi.py`` into a new ``Lib/test/test_embed.py`` file. + +.. + +.. bpo: 28668 +.. date: 2017-11-25-14-53-29 +.. nonce: Y1G6pA +.. section: Tests + +test.support.requires_multiprocessing_queue is removed. Skip tests with +test.support.import_module('multiprocessing.synchronize') instead when the +semaphore implementation is broken or missing. + +.. + +.. bpo: 32126 +.. date: 2017-11-24-18-15-12 +.. nonce: PLmNLn +.. section: Tests + +Skip test_get_event_loop_new_process in test.test_asyncio.test_events when +sem_open() is not functional. + +.. + +.. bpo: 31174 +.. date: 2017-10-24-11-36-10 +.. nonce: xCvXcr +.. section: Tests + +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: 28538 +.. date: 2017-11-21-17-27-59 +.. nonce: DsNBS7 +.. section: Build + +Revert the previous changes, the if_nameindex structure is defined by +Unified Headers. + +.. + +.. bpo: 28762 +.. date: 2017-11-21-17-12-24 +.. nonce: R6uu8w +.. section: Build + +Revert the last commit, the F_LOCK macro is defined by Android Unified +Headers. + +.. + +.. bpo: 29040 +.. date: 2017-11-21-16-56-24 +.. nonce: 14lCSr +.. section: Build + +Support building Android with Unified Headers. The first NDK release to +support Unified Headers is android-ndk-r14. + +.. + +.. bpo: 32059 +.. date: 2017-11-18-11-19-28 +.. nonce: a0Hxgp +.. section: Build + +``detect_modules()`` in ``setup.py`` now also searches the sysroot paths +when cross-compiling. + +.. + +.. bpo: 31957 +.. date: 2017-11-06-11-53-39 +.. nonce: S_1jFK +.. section: Build + +Fixes Windows SDK version detection when building for Windows. + +.. + +.. bpo: 31609 +.. date: 2017-11-04-15-35-08 +.. nonce: k7_nBR +.. section: Build + +Fixes quotes in PCbuild/clean.bat + +.. + +.. bpo: 31934 +.. date: 2017-11-03-15-17-50 +.. nonce: 8bUlpv +.. section: Build + +Abort the build when building out of a not clean source tree. + +.. + +.. bpo: 31926 +.. date: 2017-11-03-10-07-14 +.. nonce: 57wE98 +.. section: Build + +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 +.. date: 2017-11-02-20-30-57 +.. nonce: VaE3o8 +.. section: Build + +Update Windows builds to use SQLite 3.21.0. + +.. + +.. bpo: 28791 +.. date: 2017-11-02-20-13-46 +.. nonce: STt3jL +.. section: Build + +Update OS X installer to use SQLite 3.21.0. + +.. + +.. bpo: 28643 +.. date: 2017-11-01-14-16-27 +.. nonce: 9iPKJy +.. section: Build + +Record profile-opt build progress with stamp files. + +.. + +.. bpo: 31866 +.. date: 2017-10-24-23-21-13 +.. nonce: MkNO66 +.. section: Build + +Finish removing support for AtheOS. + +.. + +.. bpo: 1102 +.. date: 2017-11-19-09-46-27 +.. nonce: NY-g1F +.. section: Windows + +Return ``None`` when ``View.Fetch()`` returns ``ERROR_NO_MORE_ITEMS`` +instead of raising ``MSIError``. +Initial patch by Anthony Tuininga. + +.. + +.. bpo: 31944 +.. date: 2017-11-04-15-29-47 +.. nonce: 0Bx8tZ +.. section: Windows + +Fixes Modify button in Apps and Features dialog. + +.. + +.. bpo: 20486 +.. date: 2017-10-26-23-02-57 +.. nonce: 3IdsZ1 +.. section: Windows + +Implement the ``Database.Close()`` method to help closing MSI database +objects. + +.. + +.. bpo: 31857 +.. date: 2017-10-23-18-35-50 +.. nonce: YwhEvc +.. section: Windows + +Make the behavior of USE_STACKCHECK deterministic in a multi-threaded +environment. + +.. + +.. bpo: 31392 +.. date: 2017-12-04-21-57-43 +.. nonce: f8huBC +.. section: macOS + +Update macOS installer to use OpenSSL 1.0.2m + +.. + +.. bpo: 32207 +.. date: 2017-12-04-15-04-43 +.. nonce: IzyAJo +.. section: IDLE + +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 +.. date: 2017-11-28-21-47-15 +.. nonce: 2T2Na8 +.. section: IDLE + +Delete unused file idlelib/tabbedpages.py. Use of TabbedPageSet in +configdialog was replaced by ttk.Notebook. + +.. + +.. bpo: 32100 +.. date: 2017-11-21-08-26-08 +.. nonce: P43qx2 +.. section: IDLE + +IDLE: Fix old and new bugs in pathbrowser; improve tests. Patch mostly by +Cheryl Sabella. + +.. + +.. bpo: 31858 +.. date: 2017-10-26-20-20-19 +.. nonce: VuSA_e +.. section: IDLE + +IDLE -- Restrict shell prompt manipulation 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 +.. date: 2017-10-24-16-21-50 +.. nonce: gECuWx +.. section: IDLE + +The font sample in the IDLE configuration dialog is now editable. Changes +persist while IDLE remains open + +.. + +.. bpo: 31836 +.. date: 2017-10-21-15-41-53 +.. nonce: fheLME +.. section: IDLE + +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 +.. date: 2017-10-17-13-26-13 +.. nonce: TMEQfp +.. section: IDLE + +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 +.. date: 2017-10-12-00-51-29 +.. nonce: VwjZRD +.. section: IDLE + +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: 32159 +.. date: 2017-11-28-21-24-41 +.. nonce: RSl4QK +.. section: Tools/Demos + +Remove CVS and Subversion tools: remove svneol.py and treesync.py scripts. +CPython migrated from CVS to Subversion, to Mercurial, and then to Git. CVS +and Subversion are no longer used to develop CPython. + +.. + +.. bpo: 30722 +.. date: 2017-10-23-19-45-52 +.. nonce: ioRlAu +.. section: Tools/Demos + +Make redemo work with Python 3.6 and newer versions. +Also, remove the ``LOCALE`` option since it doesn't work with string +patterns in Python 3. +Patch by Christoph Sarnowski. + +.. + +.. bpo: 20891 +.. date: 2017-11-30-18-13-45 +.. nonce: wBnMdF +.. section: C API + +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: 32125 +.. date: 2017-11-24-21-25-43 +.. nonce: K8zWgn +.. section: C API + +The ``Py_UseClassExceptionsFlag`` flag has been removed. It was deprecated +and wasn't used anymore since Python 2.0. + +.. + +.. bpo: 25612 +.. date: 2017-10-22-13-12-28 +.. nonce: 1jnWKT +.. section: C API + +Move the current exception state from the frame object to the co-routine. +This simplifies the interpreter and fixes a couple of obscure bugs caused by +having swap exception state when entering or exiting a generator. + +.. + +.. bpo: 23699 +.. date: 2017-10-19-15-27-04 +.. nonce: -noVVc +.. section: C API + +Add Py_RETURN_RICHCOMPARE macro to reduce boilerplate code in rich +comparison functions. + +.. + +.. bpo: 30697 +.. date: 2017-06-30-11-58-01 +.. nonce: Q3T_8n +.. section: C API + +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. diff --git a/Misc/NEWS.d/3.7.0a4.rst b/Misc/NEWS.d/3.7.0a4.rst new file mode 100644 index 00000000..f19d1a18 --- /dev/null +++ b/Misc/NEWS.d/3.7.0a4.rst @@ -0,0 +1,846 @@ +.. bpo: 31975 +.. date: 2018-01-05-20-54-27 +.. nonce: AmftlU +.. release date: 2018-01-08 +.. section: Core and Builtins + +The default warning filter list now starts with a +"default::DeprecationWarning:__main__" entry, so deprecation warnings are +once again shown by default in single-file scripts and at the interactive +prompt. + +.. + +.. bpo: 32226 +.. date: 2018-01-04-15-06-15 +.. nonce: 7cAvRG +.. section: Core and Builtins + +``__class_getitem__`` is now an automatic class method. + +.. + +.. bpo: 32399 +.. date: 2017-12-22-13-38-17 +.. nonce: wlH12z +.. section: Core and Builtins + +Add AIX uuid library support for RFC4122 using uuid_create() in libc.a + +.. + +.. bpo: 32390 +.. date: 2017-12-22-13-28-07 +.. nonce: QPj083 +.. section: Core and Builtins + +Fix the compilation failure on AIX after the f_fsid field has been added to +the object returned by os.statvfs() (issue #32143). Original patch by +Michael Felt. + +.. + +.. bpo: 32379 +.. date: 2017-12-19-21-14-41 +.. nonce: B7mOmI +.. section: Core and Builtins + +Make MRO computation faster when a class inherits from a single base. + +.. + +.. bpo: 32259 +.. date: 2017-12-16-14-30-21 +.. nonce: GoOJiX +.. section: Core and Builtins + +The error message of a TypeError raised when unpack non-iterable is now more +specific. + +.. + +.. bpo: 27169 +.. date: 2017-12-15-11-50-06 +.. nonce: VO84fQ +.. section: Core and Builtins + +The ``__debug__`` constant is now optimized out at compile time. This fixes +also bpo-22091. + +.. + +.. bpo: 32329 +.. date: 2017-12-15-00-13-04 +.. nonce: q47IN2 +.. section: Core and Builtins + +The :option:`-R` option now turns on hash randomization when the +:envvar:`PYTHONHASHSEED` environment variable is set to ``0``. Previously, +the option was ignored. Moreover, ``sys.flags.hash_randomization`` is now +properly set to 0 when hash randomization is turned off by +``PYTHONHASHSEED=0``. + +.. + +.. bpo: 30416 +.. date: 2017-12-14-11-48-19 +.. nonce: hlHo_9 +.. section: Core and Builtins + +The optimizer is now protected from spending much time doing complex +calculations and consuming much memory for creating large constants in +constant folding. Increased limits for constants that can be produced in +constant folding. + +.. + +.. bpo: 32282 +.. date: 2017-12-12-14-02-28 +.. nonce: xFVMTn +.. section: Core and Builtins + +Fix an unnecessary ifdef in the include of VersionHelpers.h in socketmodule +on Windows. + +.. + +.. bpo: 30579 +.. date: 2017-12-11-01-52-42 +.. nonce: X6cEzf +.. section: Core and Builtins + +Implement TracebackType.__new__ to allow Python-level creation of traceback +objects, and make TracebackType.tb_next mutable. + +.. + +.. bpo: 32260 +.. date: 2017-12-09-11-03-51 +.. nonce: 1DAO-p +.. section: Core and Builtins + +Don't byte swap the input keys to the SipHash algorithm on big-endian +platforms. This should ensure siphash gives consistent results across +platforms. + +.. + +.. bpo: 31506 +.. date: 2017-12-07-23-44-29 +.. nonce: j1U2fU +.. section: Core and Builtins + +Improve the error message logic for object.__new__ and object.__init__. +Patch by Sanyam Khurana. + +.. + +.. bpo: 20361 +.. date: 2017-12-07-17-22-30 +.. nonce: zQUmbi +.. section: Core and Builtins + +``-b`` and ``-bb`` now inject ``'default::BytesWarning'`` and +``error::BytesWarning`` entries into ``sys.warnoptions``, ensuring that they +take precedence over any other warning filters configured via the ``-W`` +option or the ``PYTHONWARNINGS`` environment variable. + +.. + +.. bpo: 32230 +.. date: 2017-12-06-20-18-34 +.. nonce: PgGQaB +.. section: Core and Builtins + +`-X dev` now injects a ``'default'`` entry into sys.warnoptions, ensuring +that it behaves identically to actually passing ``-Wdefault`` at the command +line. + +.. + +.. bpo: 29240 +.. date: 2017-12-05-23-10-58 +.. nonce: qpJP5l +.. section: Core and Builtins + +Add a new UTF-8 mode: implementation of the :pep:`540`. + +.. + +.. bpo: 32226 +.. date: 2017-12-05-21-42-58 +.. nonce: G8fqb6 +.. section: Core and Builtins + +:pep:`560`: Add support for ``__mro_entries__`` and ``__class_getitem__``. Implemented +by Ivan Levkivskyi. + +.. + +.. bpo: 32225 +.. date: 2017-12-05-21-33-47 +.. nonce: ucKjvw +.. section: Core and Builtins + +:pep:`562`: Add support for module ``__getattr__`` and ``__dir__``. Implemented +by Ivan Levkivskyi. + +.. + +.. bpo: 31901 +.. date: 2017-11-28-15-04-14 +.. nonce: mDeCLK +.. section: Core and Builtins + +The `atexit` module now has its callback stored per interpreter. + +.. + +.. bpo: 31650 +.. date: 2017-11-26-14-38-44 +.. nonce: JWf_Im +.. section: Core and Builtins + +Implement :pep:`552` (Deterministic pycs). Python now supports invalidating +bytecode cache files bashed on a source content hash rather than source +last-modified time. + +.. + +.. bpo: 29469 +.. date: 2017-07-26-00-20-15 +.. nonce: potmyI +.. section: Core and Builtins + +Move constant folding from bytecode layer to AST layer. Original patch by +Eugene Toder. + +.. + +.. bpo: 32506 +.. date: 2018-01-07-11-32-42 +.. nonce: MaT-zU +.. section: Library + +Now that dict is defined as keeping insertion order, drop OrderedDict and +just use plain dict. + +.. + +.. bpo: 32279 +.. date: 2018-01-06-16-50-11 +.. nonce: 1xOpU8 +.. section: Library + +Add params to dataclasses.make_dataclasses(): init, repr, eq, order, hash, +and frozen. Pass them through to dataclass(). + +.. + +.. bpo: 32278 +.. date: 2018-01-06-15-15-34 +.. nonce: bGnGc0 +.. section: Library + +Make type information optional on dataclasses.make_dataclass(). If omitted, +the string 'typing.Any' is used. + +.. + +.. bpo: 32499 +.. date: 2018-01-06-10-54-16 +.. nonce: koyY-4 +.. section: Library + +Add dataclasses.is_dataclass(obj), which returns True if obj is a dataclass +or an instance of one. + +.. + +.. bpo: 32468 +.. date: 2017-12-31-20-32-58 +.. nonce: YBs__0 +.. section: Library + +Improve frame repr() to mention filename, code name and current line number. + +.. + +.. bpo: 23749 +.. date: 2017-12-29-00-44-42 +.. nonce: QL1Cxd +.. section: Library + +asyncio: Implement loop.start_tls() + +.. + +.. bpo: 32441 +.. date: 2017-12-28-21-30-40 +.. nonce: LqlboJ +.. section: Library + +Return the new file descriptor (i.e., the second argument) from ``os.dup2``. +Previously, ``None`` was always returned. + +.. + +.. bpo: 32422 +.. date: 2017-12-25-20-22-47 +.. nonce: 5H3Wq2 +.. section: Library + +``functools.lru_cache`` uses less memory (3 words for each cached key) and +takes about 1/3 time for cyclic GC. + +.. + +.. bpo: 31721 +.. date: 2017-12-25-11-09-46 +.. nonce: 5gM972 +.. section: Library + +Prevent Python crash from happening when Future._log_traceback is set to +True manually. Now it can only be set to False, or a ValueError is raised. + +.. + +.. bpo: 32415 +.. date: 2017-12-23-12-45-00 +.. nonce: YufXTU +.. section: Library + +asyncio: Add Task.get_loop() and Future.get_loop() + +.. + +.. bpo: 26133 +.. date: 2017-12-21-11-08-42 +.. nonce: mt81QV +.. section: Library + +Don't unsubscribe signals in asyncio UNIX event loop on interpreter +shutdown. + +.. + +.. bpo: 32363 +.. date: 2017-12-19-00-37-28 +.. nonce: YTeGU0 +.. section: Library + +Make asyncio.Task.set_exception() and set_result() raise +NotImplementedError. Task._step() and Future.__await__() raise proper +exceptions when they are in an invalid state, instead of raising an +AssertionError. + +.. + +.. bpo: 32357 +.. date: 2017-12-18-00-36-41 +.. nonce: t1F3sn +.. section: Library + +Optimize asyncio.iscoroutine() and loop.create_task() for non-native +coroutines (e.g. async/await compiled with Cython). +'loop.create_task(python_coroutine)' used to be 20% faster than +'loop.create_task(cython_coroutine)'. Now, the latter is as fast. + +.. + +.. bpo: 32356 +.. date: 2017-12-17-22-50-51 +.. nonce: roZJpA +.. section: Library + +asyncio.transport.resume_reading() and pause_reading() are now idempotent. +New transport.is_reading() method is added. + +.. + +.. bpo: 32355 +.. date: 2017-12-17-21-42-24 +.. nonce: tbaTWA +.. section: Library + +Optimize asyncio.gather(); now up to 15% faster. + +.. + +.. bpo: 32351 +.. date: 2017-12-17-14-23-23 +.. nonce: 95fh2K +.. section: Library + +Use fastpath in asyncio.sleep if delay<0 (2x boost) + +.. + +.. bpo: 32348 +.. date: 2017-12-16-18-50-57 +.. nonce: 5j__he +.. section: Library + +Optimize asyncio.Future schedule/add/remove callback. The optimization +shows 3-6% performance improvements of async/await code. + +.. + +.. bpo: 32331 +.. date: 2017-12-15-23-48-43 +.. nonce: fIg1Uc +.. section: Library + +Fix socket.settimeout() and socket.setblocking() to keep socket.type as is. +Fix socket.socket() constructor to reset any bit flags applied to socket's +type. This change only affects OSes that have SOCK_NONBLOCK and/or +SOCK_CLOEXEC. + +.. + +.. bpo: 32248 +.. date: 2017-12-15-15-34-12 +.. nonce: zmO8G2 +.. section: Library + +Add :class:`importlib.abc.ResourceReader` as an ABC for loaders to provide a +unified API for reading resources contained within packages. Also add +:mod:`importlib.resources` as the port of ``importlib_resources``. + +.. + +.. bpo: 32311 +.. date: 2017-12-14-17-28-54 +.. nonce: DL5Ytn +.. section: Library + +Implement asyncio.create_task(coro) shortcut + +.. + +.. bpo: 32327 +.. date: 2017-12-14-16-00-25 +.. nonce: bbkSxA +.. section: Library + +Convert asyncio functions that were documented as coroutines to coroutines. +Affected functions: loop.sock_sendall, loop.sock_recv, loop.sock_accept, +loop.getaddrinfo, loop.getnameinfo. + +.. + +.. bpo: 32323 +.. date: 2017-12-14-10-10-10 +.. nonce: ideco +.. section: Library + +:func:`urllib.parse.urlsplit()` does not convert zone-id (scope) to lower +case for scoped IPv6 addresses in hostnames now. + +.. + +.. bpo: 32302 +.. date: 2017-12-13-22-38-08 +.. nonce: othtTr +.. section: Library + +Fix bdist_wininst of distutils for CRT v142: it binary compatible with CRT +v140. + +.. + +.. bpo: 29711 +.. date: 2017-12-13-22-10-36 +.. nonce: hJjghA +.. section: Library + +Fix ``stop_serving`` in asyncio proactor loop kill all listening servers + +.. + +.. bpo: 32308 +.. date: 2017-12-13-20-31-30 +.. nonce: CUbsb2 +.. section: Library + +:func:`re.sub()` now replaces empty matches adjacent to a previous non-empty +match. + +.. + +.. bpo: 29970 +.. date: 2017-12-13-19-02-38 +.. nonce: uxVOpk +.. section: Library + +Abort asyncio SSLProtocol connection if handshake not complete within 10 seconds. + +.. + +.. bpo: 32314 +.. date: 2017-12-13-16-47-38 +.. nonce: W4_U2j +.. section: Library + +Implement asyncio.run(). + +.. + +.. bpo: 17852 +.. date: 2017-12-13-00-00-37 +.. nonce: Q8BP8N +.. section: Library + +Revert incorrect fix based on misunderstanding of _Py_PyAtExit() semantics. + +.. + +.. bpo: 32296 +.. date: 2017-12-12-18-01-01 +.. nonce: bwscHz +.. section: Library + +Implement asyncio._get_running_loop() and get_event_loop() in C. This makes +them 4x faster. + +.. + +.. bpo: 32250 +.. date: 2017-12-12-16-58-20 +.. nonce: UljTa0 +.. section: Library + +Implement ``asyncio.current_task()`` and ``asyncio.all_tasks()``. Add +helpers intended to be used by alternative task implementations: +``asyncio._register_task``, ``asyncio._enter_task``, ``asyncio._leave_task`` +and ``asyncio._unregister_task``. Deprecate ``asyncio.Task.current_task()`` +and ``asyncio.Task.all_tasks()``. + +.. + +.. bpo: 32255 +.. date: 2017-12-12-07-29-06 +.. nonce: 2bfNmM +.. section: Library + +A single empty field is now always quoted when written into a CSV file. This +allows to distinguish an empty row from a row consisting of a single empty +field. Patch by Licht Takeuchi. + +.. + +.. bpo: 32277 +.. date: 2017-12-11-09-53-14 +.. nonce: jkKiVC +.. section: Library + +Raise ``NotImplementedError`` instead of ``SystemError`` on platforms where +``chmod(..., follow_symlinks=False)`` is not supported. Patch by Anthony +Sottile. + +.. + +.. bpo: 30050 +.. date: 2017-12-10-23-44-56 +.. nonce: 4SZ3lY +.. section: Library + +New argument warn_on_full_buffer to signal.set_wakeup_fd lets you control +whether Python prints a warning on stderr when the wakeup fd buffer +overflows. + +.. + +.. bpo: 29137 +.. date: 2017-12-10-21-19-14 +.. nonce: CFcON1 +.. section: Library + +The ``fpectl`` library has been removed. It was never enabled by default, +never worked correctly on x86-64, and it changed the Python ABI in ways that +caused unexpected breakage of C extensions. + +.. + +.. bpo: 32273 +.. date: 2017-12-10-19-14-55 +.. nonce: 5KKlCv +.. section: Library + +Move asyncio.test_utils to test.test_asyncio. + +.. + +.. bpo: 32272 +.. date: 2017-12-10-18-59-13 +.. nonce: Mu84Am +.. section: Library + +Remove asyncio.async() function. + +.. + +.. bpo: 32269 +.. date: 2017-12-10-12-30-13 +.. nonce: Q85pKj +.. section: Library + +Add asyncio.get_running_loop() function. + +.. + +.. bpo: 32265 +.. date: 2017-12-10-00-57-51 +.. nonce: kELtTE +.. section: Library + +All class and static methods of builtin types now are correctly classified +by inspect.classify_class_attrs() and grouped in pydoc ouput. Added +types.ClassMethodDescriptorType for unbound class methods of builtin types. + +.. + +.. bpo: 32253 +.. date: 2017-12-09-11-30-35 +.. nonce: TQHSYF +.. section: Library + +Deprecate ``yield from lock``, ``await lock``, ``with (yield from lock)`` +and ``with await lock`` for asyncio synchronization primitives. + +.. + +.. bpo: 22589 +.. date: 2017-12-08-15-09-41 +.. nonce: 8ouqI6 +.. section: Library + +Changed MIME type of .bmp from 'image/x-ms-bmp' to 'image/bmp' + +.. + +.. bpo: 32193 +.. date: 2017-12-08-11-02-26 +.. nonce: NJe_TQ +.. section: Library + +Convert asyncio to use *async/await* syntax. Old styled ``yield from`` is +still supported too. + +.. + +.. bpo: 32206 +.. date: 2017-12-07-13-14-40 +.. nonce: obm4OM +.. section: Library + +Add support to run modules with pdb + +.. + +.. bpo: 32227 +.. date: 2017-12-05-13-25-15 +.. nonce: 3vnWFS +.. section: Library + +``functools.singledispatch`` now supports registering implementations using +type annotations. + +.. + +.. bpo: 15873 +.. date: 2017-12-04-17-41-40 +.. nonce: -T4TRK +.. section: Library + +Added new alternate constructors :meth:`datetime.datetime.fromisoformat`, +:meth:`datetime.time.fromisoformat` and :meth:`datetime.date.fromisoformat` +as the inverse operation of each classes's respective ``isoformat`` methods. + +.. + +.. bpo: 32199 +.. date: 2017-12-04-12-23-26 +.. nonce: nGof4v +.. section: Library + +The getnode() ip getter now uses 'ip link' instead of 'ip link list'. + +.. + +.. bpo: 32143 +.. date: 2017-11-26-17-28-26 +.. nonce: o7YdXL +.. section: Library + +os.statvfs() includes the f_fsid field from statvfs(2) + +.. + +.. bpo: 26439 +.. date: 2017-11-24-08-35-43 +.. nonce: IC45_f +.. section: Library + +Fix ctypes.util.find_library() for AIX by implementing +ctypes._aix.find_library() Patch by: Michael Felt + +.. + +.. bpo: 31993 +.. date: 2017-11-10-00-05-08 +.. nonce: -OMNg8 +.. section: Library + +The pickler now uses less memory when serializing large bytes and str +objects into a file. Pickles created with protocol 4 will require less +memory for unpickling large bytes and str objects. + +.. + +.. bpo: 27456 +.. date: 2017-11-02-11-57-41 +.. nonce: snzyTC +.. section: Library + +Ensure TCP_NODELAY is set on Linux. Tests by Victor Stinner. + +.. + +.. bpo: 31778 +.. date: 2017-10-18-17-29-30 +.. nonce: B6vAkP +.. section: Library + +ast.literal_eval() is now more strict. Addition and subtraction of arbitrary +numbers no longer allowed. + +.. + +.. bpo: 31802 +.. date: 2017-10-17-14-52-14 +.. nonce: sYj2Zv +.. section: Library + +Importing native path module (``posixpath``, ``ntpath``) now works even if +the ``os`` module still is not imported. + +.. + +.. bpo: 30241 +.. date: 2017-10-10-18-56-46 +.. nonce: F_go20 +.. section: Library + +Add contextlib.AbstractAsyncContextManager. Patch by Jelle Zijlstra. + +.. + +.. bpo: 31699 +.. date: 2017-10-05-11-06-32 +.. nonce: MF47Y6 +.. section: Library + +Fix deadlocks in :class:`concurrent.futures.ProcessPoolExecutor` when task +arguments or results cause pickling or unpickling errors. This should make +sure that calls to the :class:`ProcessPoolExecutor` API always eventually +return. + +.. + +.. bpo: 15216 +.. date: 2017-09-16-02-56-33 +.. nonce: lqXCTT +.. section: Library + +``TextIOWrapper.reconfigure()`` supports changing *encoding*, *errors*, and +*newline*. + +.. + +.. bpo: 32418 +.. date: 2017-12-24-17-29-37 +.. nonce: eZe-ID +.. section: Documentation + +Add get_loop() method to Server and AbstractServer classes. + +.. + +.. bpo: 32252 +.. date: 2017-12-11-13-31-33 +.. nonce: YnFw7J +.. section: Tests + +Fix faulthandler_suppress_crash_report() used to prevent core dump files +when testing crashes. getrlimit() returns zero on success. + +.. + +.. bpo: 32002 +.. date: 2017-11-11-16-35-18 +.. nonce: itDxIo +.. section: Tests + +Adjust C locale coercion testing for the empty locale and POSIX locale cases +to more readily adjust to platform dependent behaviour. + +.. + +.. bpo: 19764 +.. date: 2017-08-18-18-00-24 +.. nonce: ODpc9y +.. section: Windows + +Implement support for `subprocess.Popen(close_fds=True)` on Windows. Patch +by Segev Finer. + +.. + +.. bpo: 24960 +.. date: 2017-12-22-09-25-51 +.. nonce: TGdAgO +.. section: Tools/Demos + +2to3 and lib2to3 can now read pickled grammar files using pkgutil.get_data() +rather than probing the filesystem. This lets 2to3 and lib2to3 work when run +from a zipfile. + +.. + +.. bpo: 32030 +.. date: 2017-12-20-23-22-32 +.. nonce: d1dcwh +.. section: C API + +Py_Initialize() doesn't reset the memory allocators to default if the +``PYTHONMALLOC`` environment variable is not set. + +.. + +.. bpo: 29084 +.. date: 2017-12-16-09-59-35 +.. nonce: ZGJ-LJ +.. section: C API + +Undocumented C API for OrderedDict has been excluded from the limited C API. +It was added by mistake and actually never worked in the limited C API. + +.. + +.. bpo: 32264 +.. date: 2017-12-12-23-09-46 +.. nonce: ahRlOI +.. section: C API + +Moved the pygetopt.h header into internal/, since it has no public APIs. + +.. + +.. bpo: 32241 +.. date: 2017-12-07-15-58-15 +.. nonce: LbyQt6 +.. section: C API + +:c:func:`Py_SetProgramName` and :c:func:`Py_SetPythonHome` now take the +``const wchar *`` arguments instead of ``wchar *``. diff --git a/Misc/NEWS.d/3.7.0b1.rst b/Misc/NEWS.d/3.7.0b1.rst new file mode 100644 index 00000000..d1beec9c --- /dev/null +++ b/Misc/NEWS.d/3.7.0b1.rst @@ -0,0 +1,878 @@ +.. bpo: 32703 +.. date: 2018-01-29-01-15-17 +.. nonce: mwrF4- +.. release date: 2018-01-30 +.. section: Core and Builtins + +Fix coroutine's ResourceWarning when there's an active error set when it's +being finalized. + +.. + +.. bpo: 32650 +.. date: 2018-01-28-23-01-39 +.. nonce: Bbi7ek +.. section: Core and Builtins + +Pdb and other debuggers dependent on bdb.py will correctly step over (next +command) native coroutines. Patch by Pablo Galindo. + +.. + +.. bpo: 28685 +.. date: 2018-01-28-15-09-33 +.. nonce: cHThLM +.. section: Core and Builtins + +Optimize list.sort() and sorted() by using type specialized comparisons when +possible. + +.. + +.. bpo: 32685 +.. date: 2018-01-28-12-25-06 +.. nonce: nGctze +.. section: Core and Builtins + +Improve suggestion when the Python 2 form of print statement is either +present on the same line as the header of a compound statement or else +terminated by a semi-colon instead of a newline. Patch by Nitish Chandra. + +.. + +.. bpo: 32697 +.. date: 2018-01-28-09-52-12 +.. nonce: RHlu6k +.. section: Core and Builtins + +Python now explicitly preserves the definition order of keyword-only +parameters. It's always preserved their order, but this behavior was never +guaranteed before; this behavior is now guaranteed and tested. + +.. + +.. bpo: 32690 +.. date: 2018-01-28-09-26-07 +.. nonce: 8i9g5P +.. section: Core and Builtins + +The locals() dictionary now displays in the lexical order that variables +were defined. Previously, the order was reversed. + +.. + +.. bpo: 32677 +.. date: 2018-01-26-20-11-09 +.. nonce: xTGfCq +.. section: Core and Builtins + +Add ``.isascii()`` method to ``str``, ``bytes`` and ``bytearray``. It can be +used to test that string contains only ASCII characters. + +.. + +.. bpo: 32670 +.. date: 2018-01-25-17-03-46 +.. nonce: YsqJUC +.. section: Core and Builtins + +Enforce :pep:`479` for all code. +This means that manually raising a StopIteration exception from a generator +is prohibited for all code, regardless of whether 'from __future__ import +generator_stop' was used or not. + +.. + +.. bpo: 32591 +.. date: 2018-01-20-00-50-33 +.. nonce: 666kl6 +.. section: Core and Builtins + +Added built-in support for tracking the origin of coroutine objects; see +sys.set_coroutine_origin_tracking_depth and CoroutineType.cr_origin. This +replaces the asyncio debug mode's use of coroutine wrapping for native +coroutine objects. + +.. + +.. bpo: 31368 +.. date: 2018-01-19-01-54-22 +.. nonce: kzKqUR +.. section: Core and Builtins + +Expose preadv and pwritev system calls in the os module. Patch by Pablo +Galindo + +.. + +.. bpo: 32544 +.. date: 2018-01-16-18-51-58 +.. nonce: ga-cFE +.. section: Core and Builtins + +``hasattr(obj, name)`` and ``getattr(obj, name, default)`` are about 4 times +faster than before when ``name`` is not found and ``obj`` doesn't override +``__getattr__`` or ``__getattribute__``. + +.. + +.. bpo: 26163 +.. date: 2018-01-14-20-32-47 +.. nonce: xv9Iuv +.. section: Core and Builtins + +Improved frozenset() hash to create more distinct hash values when faced +with datasets containing many similar values. + +.. + +.. bpo: 32550 +.. date: 2018-01-14-12-42-17 +.. nonce: k0EK-4 +.. section: Core and Builtins + +Remove the STORE_ANNOTATION bytecode. + +.. + +.. bpo: 20104 +.. date: 2018-01-06-01-14-53 +.. nonce: 9DkKb8 +.. section: Core and Builtins + +Expose posix_spawn as a low level API in the os module. +(removed before 3.7.0rc1) + +.. + +.. bpo: 24340 +.. date: 2018-01-01-21-59-31 +.. nonce: hmKBvg +.. section: Core and Builtins + +Fixed estimation of the code stack size. + +.. + +.. bpo: 32436 +.. date: 2017-12-28-00-20-42 +.. nonce: H159Jv +.. section: Core and Builtins + +Implement :pep:`567` Context Variables. + +.. + +.. bpo: 18533 +.. date: 2017-12-13-16-46-23 +.. nonce: Dlk8d7 +.. section: Core and Builtins + +``repr()`` on a dict containing its own ``values()`` or ``items()`` no +longer raises ``RecursionError``; OrderedDict similarly. Instead, use +``...``, as for other recursive structures. Patch by Ben North. + +.. + +.. bpo: 20891 +.. date: 2017-12-04-18-34-11 +.. nonce: C2TsfR +.. section: Core and Builtins + +Py_Initialize() now creates the GIL. The GIL is no longer created "on +demand" to fix a race condition when PyGILState_Ensure() is called in a +non-Python thread. + +.. + +.. bpo: 32028 +.. date: 2017-12-03-22-29-13 +.. nonce: KC2w4Q +.. section: Core and Builtins + +Leading whitespace is now correctly ignored when generating suggestions for +converting Py2 print statements to Py3 builtin print function calls. Patch +by Sanyam Khurana. + +.. + +.. bpo: 31179 +.. date: 2017-08-10-17-32-48 +.. nonce: XcgLYI +.. section: Core and Builtins + +Make dict.copy() up to 5.5 times faster. + +.. + +.. bpo: 31113 +.. date: 2017-08-07-16-46-56 +.. nonce: XgNEFg +.. section: Core and Builtins + +Get rid of recursion in the compiler for normal control flow. + +.. + +.. bpo: 25988 +.. date: 2018-01-28-23-48-45 +.. nonce: I9uBct +.. section: Library + +Deprecate exposing the contents of collections.abc in the regular +collections module. + +.. + +.. bpo: 31429 +.. date: 2018-01-28-22-40-05 +.. nonce: qNt8rQ +.. section: Library + +The default cipher suite selection of the ssl module now uses a blacklist +approach rather than a hard-coded whitelist. Python no longer re-enables +ciphers that have been blocked by OpenSSL security update. Default cipher +suite selection can be configured on compile time. + +.. + +.. bpo: 30306 +.. date: 2018-01-28-14-10-51 +.. nonce: TmKMXi +.. section: Library + +contextlib.contextmanager now releases the arguments passed to the +underlying generator as soon as the context manager is entered. Previously +it would keep them alive for as long as the context manager was alive, even +when not being used as a function decorator. Patch by Martin Teichmann. + +.. + +.. bpo: 21417 +.. date: 2018-01-28-07-55-10 +.. nonce: JFnV99 +.. section: Library + +Added support for setting the compression level for zipfile.ZipFile. + +.. + +.. bpo: 32251 +.. date: 2018-01-28-01-21-47 +.. nonce: fOA5qB +.. section: Library + +Implement asyncio.BufferedProtocol (provisional API). + +.. + +.. bpo: 32513 +.. date: 2018-01-27-11-20-16 +.. nonce: ak-iD2 +.. section: Library + +In dataclasses, allow easier overriding of dunder methods without specifying +decorator parameters. + +.. + +.. bpo: 32660 +.. date: 2018-01-26-01-26-00 +.. nonce: tVJIWV +.. section: Library + +:mod:`termios` makes available ``FIONREAD``, ``FIONCLEX``, ``FIOCLEX``, +``FIOASYNC`` and ``FIONBIO`` also under Solaris/derivatives. + +.. + +.. bpo: 27931 +.. date: 2018-01-25-21-04-11 +.. nonce: e4r52t +.. section: Library + +Fix email address header parsing error when the username is an empty quoted +string. Patch by Xiang Zhang. + +.. + +.. bpo: 32659 +.. date: 2018-01-25-03-46-00 +.. nonce: VHYoON +.. section: Library + +Under Solaris and derivatives, :class:`os.stat_result` provides a st_fstype +attribute. + +.. + +.. bpo: 32662 +.. date: 2018-01-25-01-45-30 +.. nonce: oabhd8 +.. section: Library + +Implement Server.start_serving(), Server.serve_forever(), and +Server.is_serving() methods. Add 'start_serving' keyword parameter to +loop.create_server() and loop.create_unix_server(). + +.. + +.. bpo: 32391 +.. date: 2018-01-24-15-20-12 +.. nonce: 0f8MY9 +.. section: Library + +Implement :meth:`asyncio.StreamWriter.wait_closed` and +:meth:`asyncio.StreamWriter.is_closing` methods + +.. + +.. bpo: 32643 +.. date: 2018-01-24-00-32-58 +.. nonce: VWipsW +.. section: Library + +Make Task._step, Task._wakeup and Future._schedule_callbacks methods +private. + +.. + +.. bpo: 32630 +.. date: 2018-01-23-01-57-36 +.. nonce: 6KRHBs +.. section: Library + +Refactor decimal module to use contextvars to store decimal context. + +.. + +.. bpo: 32622 +.. date: 2018-01-22-18-18-44 +.. nonce: A1D6FP +.. section: Library + +Add :meth:`asyncio.AbstractEventLoop.sendfile` method. + +.. + +.. bpo: 32304 +.. date: 2018-01-21-16-33-53 +.. nonce: TItrNv +.. section: Library + +distutils' upload command no longer corrupts tar files ending with a CR +byte, and no longer tries to convert CR to CRLF in any of the upload text +fields. + +.. + +.. bpo: 32502 +.. date: 2018-01-20-17-15-34 +.. nonce: OXJfn7 +.. section: Library + +uuid.uuid1 no longer raises an exception if a 64-bit hardware address is +encountered. + +.. + +.. bpo: 32596 +.. date: 2018-01-19-19-57-45 +.. nonce: 4aVIie +.. section: Library + +``concurrent.futures`` imports ``ThreadPoolExecutor`` and +``ProcessPoolExecutor`` lazily (using :pep:`562`). It makes ``import +asyncio`` about 15% faster because asyncio uses only ``ThreadPoolExecutor`` +by default. + +.. + +.. bpo: 31801 +.. date: 2018-01-18-13-47-40 +.. nonce: 3UGH1h +.. section: Library + +Add ``_ignore_`` to ``Enum`` so temporary variables can be used during class +construction without being turned into members. + +.. + +.. bpo: 32576 +.. date: 2018-01-17-13-04-16 +.. nonce: iDL09t +.. section: Library + +Use queue.SimpleQueue() in places where it can be invoked from a weakref +callback. + +.. + +.. bpo: 32574 +.. date: 2018-01-16-20-37-28 +.. nonce: ru8eZ9 +.. section: Library + +Fix memory leak in asyncio.Queue, when the queue has limited size and it is +full, the cancelation of queue.put() can cause a memory leak. Patch by: José +Melero. + +.. + +.. bpo: 32521 +.. date: 2018-01-15-12-53-13 +.. nonce: IxX4Ba +.. section: Library + +The nis module is now compatible with new libnsl and headers location. + +.. + +.. bpo: 32467 +.. date: 2018-01-11-00-33-42 +.. nonce: YVEOv6 +.. section: Library + +collections.abc.ValuesView now inherits from collections.abc.Collection. + +.. + +.. bpo: 32473 +.. date: 2018-01-10-20-37-59 +.. nonce: mP_yJG +.. section: Library + +Improve ABCMeta._dump_registry() output readability + +.. + +.. bpo: 32102 +.. date: 2018-01-10-18-04-21 +.. nonce: 9-CZgD +.. section: Library + +New argument ``capture_output`` for subprocess.run + +.. + +.. bpo: 32521 +.. date: 2018-01-08-18-02-33 +.. nonce: Kh-KoN +.. section: Library + +glibc has removed Sun RPC. Use replacement libtirpc headers and library in +nis module. + +.. + +.. bpo: 32493 +.. date: 2018-01-08-15-53-37 +.. nonce: vTXxGN +.. section: Library + +UUID module fixes build for FreeBSD/OpenBSD + +.. + +.. bpo: 32503 +.. date: 2018-01-07-09-22-26 +.. nonce: ViMxpD +.. section: Library + +Pickling with protocol 4 no longer creates too small frames. + +.. + +.. bpo: 29237 +.. date: 2018-01-04-14-45-33 +.. nonce: zenYA6 +.. section: Library + +Create enum for pstats sorting options + +.. + +.. bpo: 32454 +.. date: 2017-12-30-10-38-05 +.. nonce: wsZnl- +.. section: Library + +Add close(fd) function to the socket module. + +.. + +.. bpo: 25942 +.. date: 2017-12-27-20-15-51 +.. nonce: Giyr8v +.. section: Library + +The subprocess module is now more graceful when handling a Ctrl-C +KeyboardInterrupt during subprocess.call, subprocess.run, or a Popen context +manager. It now waits a short amount of time for the child (presumed to +have also gotten the SIGINT) to exit, before continuing the +KeyboardInterrupt exception handling. This still includes a SIGKILL in the +call() and run() APIs, but at least the child had a chance first. + +.. + +.. bpo: 32433 +.. date: 2017-12-27-20-09-27 +.. nonce: vmxsVI +.. section: Library + +The hmac module now has hmac.digest(), which provides an optimized HMAC +digest. + +.. + +.. bpo: 28134 +.. date: 2017-12-24-20-01-09 +.. nonce: HJ8Beb +.. section: Library + +Sockets now auto-detect family, type and protocol from file descriptor by +default. + +.. + +.. bpo: 32404 +.. date: 2017-12-23-14-54-05 +.. nonce: yJqtlJ +.. section: Library + +Fix bug where :meth:`datetime.datetime.fromtimestamp` did not call __new__ +in :class:`datetime.datetime` subclasses. + +.. + +.. bpo: 32403 +.. date: 2017-12-23-14-51-46 +.. nonce: CVFapH +.. section: Library + +Improved speed of :class:`datetime.date` and :class:`datetime.datetime` +alternate constructors. + +.. + +.. bpo: 32228 +.. date: 2017-12-22-16-47-41 +.. nonce: waPx3q +.. section: Library + +Ensure that ``truncate()`` preserves the file position (as reported by +``tell()``) after writes longer than the buffer size. + +.. + +.. bpo: 32410 +.. date: 2017-12-22-16-05-01 +.. nonce: 8JzhvH +.. section: Library + +Implement ``loop.sock_sendfile`` for asyncio event loop. + +.. + +.. bpo: 22908 +.. date: 2017-12-21-22-00-11 +.. nonce: cVm89I +.. section: Library + +Added seek and tell to the ZipExtFile class. This only works if the file +object used to open the zipfile is seekable. + +.. + +.. bpo: 32373 +.. date: 2017-12-19-09-23-46 +.. nonce: 8qAkoW +.. section: Library + +Add socket.getblocking() method. + +.. + +.. bpo: 32248 +.. date: 2017-12-15-15-34-12 +.. nonce: zmO8G2 +.. section: Library + +Add :mod:`importlib.resources` and :class:`importlib.abc.ResourceReader` as +the unified API for reading resources contained within packages. Loaders +wishing to support resource reading must implement the +:meth:`get_resource_reader()` method. File-based and zipimport-based +loaders both implement these APIs. :class:`importlib.abc.ResourceLoader` is +deprecated in favor of these new APIs. + +.. + +.. bpo: 32320 +.. date: 2017-12-14-01-36-25 +.. nonce: jwOZlr +.. section: Library + +collections.namedtuple() now supports default values. + +.. + +.. bpo: 29302 +.. date: 2017-12-11-15-14-55 +.. nonce: Nczj9l +.. section: Library + +Add contextlib.AsyncExitStack. Patch by Alexander Mohr and Ilya Kulakov. + +.. + +.. bpo: 31961 +.. date: 2017-11-08-03-38-20 +.. nonce: x5Sv0R +.. section: Library + +*Removed in Python 3.7.0b2.* +The *args* argument of subprocess.Popen can now be a :term:`path-like +object`. If *args* is given as a sequence, it's first element can now be a +:term:`path-like object` as well. + +.. + +.. bpo: 31900 +.. date: 2017-10-30-15-55-32 +.. nonce: -S9xc4 +.. section: Library + +The :func:`locale.localeconv` function now sets temporarily the ``LC_CTYPE`` +locale to the ``LC_NUMERIC`` locale to decode ``decimal_point`` and +``thousands_sep`` byte strings if they are non-ASCII or longer than 1 byte, +and the ``LC_NUMERIC`` locale is different than the ``LC_CTYPE`` locale. +This temporary change affects other threads. +Same change for the :meth:`str.format` method when formatting a number +(:class:`int`, :class:`float`, :class:`float` and subclasses) with the ``n`` +type (ex: ``'{:n}'.format(1234)``). + +.. + +.. bpo: 31853 +.. date: 2017-10-23-22-55-51 +.. nonce: h5fjrP +.. section: Library + +Use super().method instead of socket.method in SSLSocket. They were there +most likely for legacy reasons. + +.. + +.. bpo: 31399 +.. date: 2017-09-08-14-05-33 +.. nonce: FtBrrt +.. section: Library + +The ssl module now uses OpenSSL's X509_VERIFY_PARAM_set1_host() and +X509_VERIFY_PARAM_set1_ip() API to verify hostname and IP addresses. Subject +common name fallback can be disabled with +SSLContext.hostname_checks_common_name. + +.. + +.. bpo: 14976 +.. date: 2017-09-07-19-12-47 +.. nonce: dx0Zxb +.. section: Library + +Add a queue.SimpleQueue class, an unbounded FIFO queue with a reentrant C +implementation of put(). + +.. + +.. bpo: 32724 +.. date: 2018-01-30-09-00-19 +.. nonce: qPIaM- +.. section: Documentation + +Add references to some commands in the documentation of Pdb. Patch by +Stéphane Wirtel + +.. + +.. bpo: 32649 +.. date: 2018-01-27-23-36-31 +.. nonce: o7qOjF +.. section: Documentation + +Complete the C API documentation, profiling and tracing part with the newly +added per-opcode events. + +.. + +.. bpo: 17799 +.. date: 2018-01-22-21-13-46 +.. nonce: rdZ-Vk +.. section: Documentation + +Explain real behaviour of sys.settrace and sys.setprofile and their C-API +counterparts regarding which type of events are received in each function. +Patch by Pablo Galindo Salgado. + +.. + +.. bpo: 32721 +.. date: 2018-01-29-21-30-44 +.. nonce: 2Bebm1 +.. section: Tests + +Fix test_hashlib to not fail if the _md5 module is not built. + +.. + +.. bpo: 28414 +.. date: 2018-01-28-21-19-13 +.. nonce: a6Onzt +.. section: Tests + +Add test cases for IDNA 2003 and 2008 host names. IDNA 2003 +internationalized host names are working since bpo-31399 has landed. IDNA +2008 are still broken. + +.. + +.. bpo: 32604 +.. date: 2018-01-26-21-29-09 +.. nonce: 7iazNx +.. section: Tests + +Add a new "_xxsubinterpreters" extension module that exposes the existing +subinterpreter C-API and a new cross-interpreter data sharing mechanism. The +module is primarily intended for more thorough testing of the existing +subinterpreter support. +Note that the _xxsubinterpreters module has been removed in 3.7.0rc1. + +.. + +.. bpo: 32602 +.. date: 2018-01-19-20-47-11 +.. nonce: dz41pq +.. section: Tests + +Add test certs and test for ECDSA cert and EC/RSA dual mode. + +.. + +.. bpo: 32549 +.. date: 2018-01-14-11-40-22 +.. nonce: fLwbVA +.. section: Tests + +On Travis CI, Python now Compiles and uses a local copy of OpenSSL 1.1.0g +for testing. + +.. + +.. bpo: 32635 +.. date: 2018-01-23-15-33-40 +.. nonce: qHwIZy +.. section: Build + +Fix segfault of the crypt module when libxcrypt is provided instead of +libcrypt at the system. + +.. + +.. bpo: 32598 +.. date: 2018-01-19-14-50-19 +.. nonce: hP7bMV +.. section: Build + +Use autoconf to detect OpenSSL libs, headers and supported features. The +ax_check_openssl M4 macro uses pkg-config to locate OpenSSL and falls back +to manual search. + +.. + +.. bpo: 32593 +.. date: 2018-01-18-11-10-52 +.. nonce: XIrf3v +.. section: Build + +Drop support of FreeBSD 9 and older. + +.. + +.. bpo: 29708 +.. date: 2018-01-16-08-32-49 +.. nonce: YCaHEx +.. section: Build + +If the :envvar:`SOURCE_DATE_EPOCH` environment variable is set, +:mod:`py_compile` will always create hash-based ``.pyc`` files. + +.. + +.. bpo: 32588 +.. date: 2018-01-18-14-56-45 +.. nonce: vHww6F +.. section: Windows + +Create standalone _distutils_findvs module and add missing _queue module to +installer. + +.. + +.. bpo: 29911 +.. date: 2018-01-07-12-33-21 +.. nonce: ewSJKb +.. section: Windows + +Ensure separate Modify and Uninstall buttons are displayed. + +.. + +.. bpo: 32507 +.. date: 2018-01-07-12-32-49 +.. nonce: vB4gxk +.. section: Windows + +Use app-local UCRT install rather than the proper update for old versions of +Windows. + +.. + +.. bpo: 32726 +.. date: 2018-01-30-07-13-10 +.. nonce: tcARLK +.. section: macOS + +Provide an additional, more modern macOS installer variant that supports +macOS 10.9+ systems in 64-bit mode only. Upgrade the supplied third-party +libraries to OpenSSL 1.1.0g and to SQLite 3.22.0. The 10.9+ installer now +links with and supplies its own copy of Tcl/Tk 8.6. + +.. + +.. bpo: 28440 +.. date: 2018-01-30-04-40-12 +.. nonce: W_BUWU +.. section: macOS + +No longer add /Library/Python/3.x/site-packages to sys.path for macOS +framework builds to avoid future conflicts. + +.. + +.. bpo: 32681 +.. date: 2018-01-26-17-29-29 +.. nonce: N1ruWa +.. section: C API + +Fix uninitialized variable 'res' in the C implementation of os.dup2. Patch +by Stéphane Wirtel + +.. + +.. bpo: 10381 +.. date: 2017-12-28-15-22-05 +.. nonce: a1E6aF +.. section: C API + +Add C API access to the ``datetime.timezone`` constructor and +``datetime.timzone.UTC`` singleton. diff --git a/Misc/NEWS.d/3.7.0b2.rst b/Misc/NEWS.d/3.7.0b2.rst new file mode 100644 index 00000000..95909145 --- /dev/null +++ b/Misc/NEWS.d/3.7.0b2.rst @@ -0,0 +1,654 @@ +.. bpo: 28414 +.. date: 2017-08-06-14-43-45 +.. nonce: mzZ6vD +.. release date: 2018-02-27 +.. section: Security + +The ssl module now allows users to perform their own IDN en/decoding when +using SNI. + +.. + +.. bpo: 32889 +.. date: 2018-02-20-21-53-48 +.. nonce: J6eWy5 +.. section: Core and Builtins + +Update Valgrind suppression list to account for the rename of +``Py_ADDRESS_IN_RANG`` to ``address_in_range``. + +.. + +.. bpo: 31356 +.. date: 2018-02-02-08-50-46 +.. nonce: MNwUOQ +.. section: Core and Builtins + +Remove the new API added in bpo-31356 (gc.ensure_disabled() context +manager). + +.. + +.. bpo: 32305 +.. date: 2018-02-01-10-56-41 +.. nonce: dkU9Qa +.. section: Core and Builtins + +For namespace packages, ensure that both ``__file__`` and +``__spec__.origin`` are set to None. + +.. + +.. bpo: 32303 +.. date: 2018-02-01-10-16-28 +.. nonce: VsvhSl +.. section: Core and Builtins + +Make sure ``__spec__.loader`` matches ``__loader__`` for namespace packages. + +.. + +.. bpo: 32711 +.. date: 2018-01-29-14-36-37 +.. nonce: 8hQFJP +.. section: Core and Builtins + +Fix the warning messages for Python/ast_unparse.c. Patch by Stéphane Wirtel + +.. + +.. bpo: 32583 +.. date: 2018-01-26-21-20-21 +.. nonce: Fh3fau +.. section: Core and Builtins + +Fix possible crashing in builtin Unicode decoders caused by write +out-of-bound errors when using customized decode error handlers. + +.. + +.. bpo: 32960 +.. date: 2018-02-26-20-04-40 +.. nonce: 48r0Ml +.. section: Library + +For dataclasses, disallow inheriting frozen from non-frozen classes, and +also disallow inheriting non-frozen from frozen classes. This restriction +will be relaxed at a future date. + +.. + +.. bpo: 32713 +.. date: 2018-02-26-13-16-36 +.. nonce: 55yegW +.. section: Library + +Fixed tarfile.itn handling of out-of-bounds float values. Patch by Joffrey +Fuhrer. + +.. + +.. bpo: 32951 +.. date: 2018-02-25-18-22-01 +.. nonce: gHrCXq +.. section: Library + +Direct instantiation of SSLSocket and SSLObject objects is now prohibited. +The constructors were never documented, tested, or designed as public +constructors. Users were suppose to use ssl.wrap_socket() or SSLContext. + +.. + +.. bpo: 32929 +.. date: 2018-02-25-13-47-48 +.. nonce: X2gTDH +.. section: Library + +Remove the tri-state parameter "hash", and add the boolean "unsafe_hash". If +unsafe_hash is True, add a __hash__ function, but if a __hash__ exists, +raise TypeError. If unsafe_hash is False, add a __hash__ based on the +values of eq= and frozen=. The unsafe_hash=False behavior is the same as +the old hash=None behavior. unsafe_hash=False is the default, just as +hash=None used to be. + +.. + +.. bpo: 32947 +.. date: 2018-02-25-13-06-21 +.. nonce: mqStVW +.. section: Library + +Add OP_ENABLE_MIDDLEBOX_COMPAT and test workaround for TLSv1.3 for future +compatibility with OpenSSL 1.1.1. + +.. + +.. bpo: 30622 +.. date: 2018-02-24-21-40-42 +.. nonce: dQjxSe +.. section: Library + +The ssl module now detects missing NPN support in LibreSSL. + +.. + +.. bpo: 32922 +.. date: 2018-02-23-19-12-04 +.. nonce: u-xe0B +.. section: Library + +dbm.open() now encodes filename with the filesystem encoding rather than +default encoding. + +.. + +.. bpo: 32859 +.. date: 2018-02-19-17-46-31 +.. nonce: kAT-Xp +.. section: Library + +In ``os.dup2``, don't check every call whether the ``dup3`` syscall exists +or not. + +.. + +.. bpo: 32556 +.. date: 2018-02-19-14-27-51 +.. nonce: CsRsgr +.. section: Library + +nt._getfinalpathname, nt._getvolumepathname and nt._getdiskusage now +correctly convert from bytes. + +.. + +.. bpo: 25988 +.. date: 2018-02-18-13-04-59 +.. nonce: ACidKC +.. section: Library + +Emit a :exc:`DeprecationWarning` when using or importing an ABC directly +from :mod:`collections` rather than from :mod:`collections.abc`. + +.. + +.. bpo: 21060 +.. date: 2018-02-17-19-20-19 +.. nonce: S1Z-x6 +.. section: Library + +Rewrite confusing message from setup.py upload from "No dist file created in +earlier command" to the more helpful "Must create and upload files in one +command". + +.. + +.. bpo: 32852 +.. date: 2018-02-15-12-04-29 +.. nonce: HDqIxM +.. section: Library + +Make sure sys.argv remains as a list when running trace. + +.. + +.. bpo: 31333 +.. date: 2018-02-15-08-18-52 +.. nonce: 4fF-gM +.. section: Library + +``_abc`` module is added. It is a speedup module with C implementations for +various functions and methods in ``abc``. Creating an ABC subclass and +calling ``isinstance`` or ``issubclass`` with an ABC subclass are up to 1.5x +faster. In addition, this makes Python start-up up to 10% faster. +Note that the new implementation hides internal registry and caches, +previously accessible via private attributes ``_abc_registry``, +``_abc_cache``, and ``_abc_negative_cache``. There are three debugging +helper methods that can be used instead ``_dump_registry``, +``_abc_registry_clear``, and ``_abc_caches_clear``. + +.. + +.. bpo: 32841 +.. date: 2018-02-14-00-21-24 +.. nonce: bvHDOc +.. section: Library + +Fixed `asyncio.Condition` issue which silently ignored cancellation after +notifying and cancelling a conditional lock. Patch by Bar Harel. + +.. + +.. bpo: 32819 +.. date: 2018-02-11-15-54-41 +.. nonce: ZTRX2Q +.. section: Library + +ssl.match_hostname() has been simplified and no longer depends on re and +ipaddress module for wildcard and IP addresses. Error reporting for invalid +wildcards has been improved. + +.. + +.. bpo: 32394 +.. date: 2018-02-10-13-51-56 +.. nonce: dFM9SI +.. section: Library + +socket: Remove TCP_FASTOPEN,TCP_KEEPCNT,TCP_KEEPIDLE,TCP_KEEPINTVL flags on +older version Windows during run-time. + +.. + +.. bpo: 31787 +.. date: 2018-02-09-21-41-56 +.. nonce: owSZ2t +.. section: Library + +Fixed refleaks of ``__init__()`` methods in various modules. (Contributed by +Oren Milman) + +.. + +.. bpo: 30157 +.. date: 2018-02-09-14-44-43 +.. nonce: lEiiAK +.. section: Library + +Fixed guessing quote and delimiter in csv.Sniffer.sniff() when only the last +field is quoted. Patch by Jake Davis. + +.. + +.. bpo: 32792 +.. date: 2018-02-08-00-47-07 +.. nonce: NtyDb4 +.. section: Library + +collections.ChainMap() preserves the order of the underlying mappings. + +.. + +.. bpo: 32775 +.. date: 2018-02-07-19-12-10 +.. nonce: -T77_c +.. section: Library + +:func:`fnmatch.translate()` no longer produces patterns which contain set +operations. Sets starting with '[' or containing '--', '&&', '~~' or '||' +will be interpreted differently in regular expressions in future versions. +Currently they emit warnings. fnmatch.translate() now avoids producing +patterns containing such sets by accident. + +.. + +.. bpo: 32622 +.. date: 2018-02-06-17-58-15 +.. nonce: AE0Jz7 +.. section: Library + +Implement native fast sendfile for Windows proactor event loop. + +.. + +.. bpo: 32777 +.. date: 2018-02-05-21-28-28 +.. nonce: C-wIXF +.. section: Library + +Fix a rare but potential pre-exec child process deadlock in subprocess on +POSIX systems when marking file descriptors inheritable on exec in the child +process. This bug appears to have been introduced in 3.4. + +.. + +.. bpo: 32647 +.. date: 2018-02-05-13-31-42 +.. nonce: ktmfR_ +.. section: Library + +The ctypes module used to depend on indirect linking for dlopen. The shared +extension is now explicitly linked against libdl on platforms with dl. + +.. + +.. bpo: 32741 +.. date: 2018-02-01-17-54-08 +.. nonce: KUvOPL +.. section: Library + +Implement ``asyncio.TimerHandle.when()`` method. + +.. + +.. bpo: 32691 +.. date: 2018-02-01-15-53-35 +.. nonce: VLWVTq +.. section: Library + +Use mod_spec.parent when running modules with pdb + +.. + +.. bpo: 32734 +.. date: 2018-02-01-01-34-47 +.. nonce: gCV9AD +.. section: Library + +Fixed ``asyncio.Lock()`` safety issue which allowed acquiring and locking +the same lock multiple times, without it being free. Patch by Bar Harel. + +.. + +.. bpo: 32727 +.. date: 2018-01-30-17-46-18 +.. nonce: aHVsRC +.. section: Library + +Do not include name field in SMTP envelope from address. Patch by Stéphane +Wirtel + +.. + +.. bpo: 31453 +.. date: 2018-01-21-15-01-50 +.. nonce: cZiZBe +.. section: Library + +Add TLSVersion constants and SSLContext.maximum_version / minimum_version +attributes. The new API wraps OpenSSL 1.1 +https://web.archive.org/web/20180309043602/https://www.openssl.org/docs/man1.1.0/ssl/SSL_CTX_set_min_proto_version.html +feature. + +.. + +.. bpo: 24334 +.. date: 2018-01-20-23-17-25 +.. nonce: GZuQLv +.. section: Library + +Internal implementation details of ssl module were cleaned up. The SSLSocket +has one less layer of indirection. Owner and session information are now +handled by the SSLSocket and SSLObject constructor. Channel binding +implementation has been simplified. + +.. + +.. bpo: 31848 +.. date: 2018-01-18-23-34-17 +.. nonce: M2cldy +.. section: Library + +Fix the error handling in Aifc_read.initfp() when the SSND chunk is not +found. Patch by Zackery Spytz. + +.. + +.. bpo: 32585 +.. date: 2018-01-18-13-09-00 +.. nonce: qpeijr +.. section: Library + +Add Ttk spinbox widget to :mod:`tkinter.ttk`. Patch by Alan D Moore. + +.. + +.. bpo: 32221 +.. date: 2017-12-06-10-10-10 +.. nonce: ideco_ +.. section: Library + +Various functions returning tuple containing IPv6 addresses now omit +``%scope`` part since the same information is already encoded in *scopeid* +tuple item. Especially this speeds up :func:`socket.recvfrom` when it +receives multicast packet since useless resolving of network interface name +is omitted. + +.. + +.. bpo: 30693 +.. date: 2017-11-27-15-09-49 +.. nonce: yC4mJ8 +.. section: Library + +The TarFile class now recurses directories in a reproducible way. + +.. + +.. bpo: 30693 +.. date: 2017-11-27-15-09-49 +.. nonce: yC4mJ7 +.. section: Library + +The ZipFile class now recurses directories in a reproducible way. + +.. + +.. bpo: 28124 +.. date: 2018-02-25-16-33-35 +.. nonce: _uzkgq +.. section: Documentation + +The ssl module function ssl.wrap_socket() has been de-emphasized and +deprecated in favor of the more secure and efficient +SSLContext.wrap_socket() method. + +.. + +.. bpo: 17232 +.. date: 2018-02-23-12-48-03 +.. nonce: tmuTKL +.. section: Documentation + +Clarify docs for -O and -OO. Patch by Terry Reedy. + +.. + +.. bpo: 32436 +.. date: 2018-02-14-11-10-41 +.. nonce: TTJ2jb +.. section: Documentation + +Add documentation for the contextvars module (PEP 567). + +.. + +.. bpo: 32800 +.. date: 2018-02-10-15-16-04 +.. nonce: FyrqCk +.. section: Documentation + +Update link to w3c doc for xml default namespaces. + +.. + +.. bpo: 11015 +.. date: 2018-02-10-12-48-38 +.. nonce: -gUf34 +.. section: Documentation + +Update :mod:`test.support` documentation. + +.. + +.. bpo: 8722 +.. date: 2018-02-03-06-11-37 +.. nonce: MPyVyj +.. section: Documentation + +Document :meth:`__getattr__` behavior when property :meth:`get` method +raises :exc:`AttributeError`. + +.. + +.. bpo: 32614 +.. date: 2018-02-02-07-41-57 +.. nonce: LSqzGw +.. section: Documentation + +Modify RE examples in documentation to use raw strings to prevent +:exc:`DeprecationWarning` and add text to REGEX HOWTO to highlight the +deprecation. + +.. + +.. bpo: 31972 +.. date: 2018-01-25-14-23-12 +.. nonce: w1m_8r +.. section: Documentation + +Improve docstrings for `pathlib.PurePath` subclasses. + +.. + +.. bpo: 31809 +.. date: 2017-10-18-18-07-45 +.. nonce: KlQrkE +.. section: Tests + +Add tests to verify connection with secp ECDH curves. + +.. + +.. bpo: 32898 +.. date: 2018-02-21-12-46-00 +.. nonce: M15bZh +.. section: Build + +Fix the python debug build when using COUNT_ALLOCS. + +.. + +.. bpo: 32901 +.. date: 2018-02-23-00-47-13 +.. nonce: mGKz5_ +.. section: Windows + +Update Tcl and Tk versions to 8.6.8 + +.. + +.. bpo: 31966 +.. date: 2018-02-19-13-54-42 +.. nonce: _Q3HPb +.. section: Windows + +Fixed WindowsConsoleIO.write() for writing empty data. + +.. + +.. bpo: 32409 +.. date: 2018-02-19-10-00-57 +.. nonce: nocuDg +.. section: Windows + +Ensures activate.bat can handle Unicode contents. + +.. + +.. bpo: 32457 +.. date: 2018-02-19-08-54-06 +.. nonce: vVP0Iz +.. section: Windows + +Improves handling of denormalized executable path when launching Python. + +.. + +.. bpo: 32370 +.. date: 2018-02-10-15-38-19 +.. nonce: kcKuct +.. section: Windows + +Use the correct encoding for ipconfig output in the uuid module. Patch by +Segev Finer. + +.. + +.. bpo: 29248 +.. date: 2018-02-07-17-50-48 +.. nonce: Xzwj-6 +.. section: Windows + +Fix :func:`os.readlink` on Windows, which was mistakenly treating the +``PrintNameOffset`` field of the reparse data buffer as a number of +characters instead of bytes. Patch by Craig Holmquist and SSE4. + +.. + +.. bpo: 32901 +.. date: 2018-02-27-17-33-15 +.. nonce: hQu0w3 +.. section: macOS + +Update macOS 10.9+ installer to Tcl/Tk 8.6.8. + +.. + +.. bpo: 32916 +.. date: 2018-02-23-07-32-36 +.. nonce: 4MsQ5F +.. section: IDLE + +Change ``str`` to ``code`` in pyparse. + +.. + +.. bpo: 32905 +.. date: 2018-02-22-00-09-27 +.. nonce: VlXj0x +.. section: IDLE + +Remove unused code in pyparse module. + +.. + +.. bpo: 32874 +.. date: 2018-02-19-10-56-41 +.. nonce: 6pZ9Gv +.. section: IDLE + +Add tests for pyparse. + +.. + +.. bpo: 32837 +.. date: 2018-02-12-17-22-48 +.. nonce: -33QPl +.. section: IDLE + +Using the system and place-dependent default encoding for open() is a bad +idea for IDLE's system and location-independent files. + +.. + +.. bpo: 32826 +.. date: 2018-02-12-11-05-22 +.. nonce: IxNZrk +.. section: IDLE + +Add "encoding=utf-8" to open() in IDLE's test_help_about. GUI test +test_file_buttons() only looks at initial ascii-only lines, but failed on +systems where open() defaults to 'ascii' because readline() internally reads +and decodes far enough ahead to encounter a non-ascii character in +CREDITS.txt. + +.. + +.. bpo: 32765 +.. date: 2018-02-04-17-52-54 +.. nonce: qm0eCu +.. section: IDLE + +Update configdialog General tab docstring to add new widgets to the widget +list. + +.. + +.. bpo: 32222 +.. date: 2017-12-07-20-51-20 +.. nonce: hPBcGT +.. section: Tools/Demos + +Fix pygettext not extracting docstrings for functions with type annotated +arguments. Patch by Toby Harradine. diff --git a/Misc/NEWS.d/3.7.0b3.rst b/Misc/NEWS.d/3.7.0b3.rst new file mode 100644 index 00000000..547fb50f --- /dev/null +++ b/Misc/NEWS.d/3.7.0b3.rst @@ -0,0 +1,541 @@ +.. bpo: 33136 +.. date: 2018-03-25-12-05-43 +.. nonce: TzSN4x +.. release date: 2018-03-29 +.. section: Security + +Harden ssl module against LibreSSL CVE-2018-8970. +X509_VERIFY_PARAM_set1_host() is called with an explicit namelen. A new test +ensures that NULL bytes are not allowed. + +.. + +.. bpo: 33001 +.. date: 2018-03-05-10-09-51 +.. nonce: elj4Aa +.. section: Security + +Minimal fix to prevent buffer overrun in os.symlink on Windows + +.. + +.. bpo: 32981 +.. date: 2018-03-02-10-24-52 +.. nonce: O_qDyj +.. section: Security + +Regexes in difflib and poplib were vulnerable to catastrophic backtracking. +These regexes formed potential DOS vectors (REDOS). They have been +refactored. This resolves CVE-2018-1060 and CVE-2018-1061. Patch by Jamie +Davis. + +.. + +.. bpo: 33053 +.. date: 2018-03-25-19-49-06 +.. nonce: V3xlsH +.. section: Core and Builtins + +When using the -m switch, sys.path[0] is now explicitly expanded as the +*starting* working directory, rather than being left as the empty path +(which allows imports from the current working directory at the time of the +import) + +.. + +.. bpo: 33018 +.. date: 2018-03-22-23-09-06 +.. nonce: 0ncEJV +.. section: Core and Builtins + +Improve consistency of errors raised by ``issubclass()`` when called with a +non-class and an abstract base class as the first and second arguments, +respectively. Patch by Josh Bronson. + +.. + +.. bpo: 33041 +.. date: 2018-03-18-13-56-14 +.. nonce: XwPhI2 +.. section: Core and Builtins + +Fixed jumping when the function contains an ``async for`` loop. + +.. + +.. bpo: 33026 +.. date: 2018-03-08-09-48-38 +.. nonce: QZA3Ba +.. section: Core and Builtins + +Fixed jumping out of "with" block by setting f_lineno. + +.. + +.. bpo: 33005 +.. date: 2018-03-06-12-19-19 +.. nonce: LP-V2U +.. section: Core and Builtins + +Fix a crash on fork when using a custom memory allocator (ex: using +PYTHONMALLOC env var). _PyGILState_Reinit() and _PyInterpreterState_Enable() +now use the default RAW memory allocator to allocate a new interpreters +mutex on fork. + +.. + +.. bpo: 17288 +.. date: 2018-02-27-13-36-21 +.. nonce: Gdj24S +.. section: Core and Builtins + +Prevent jumps from 'return' and 'exception' trace events. + +.. + +.. bpo: 32836 +.. date: 2018-02-14-12-35-47 +.. nonce: bThJnx +.. section: Core and Builtins + +Don't use temporary variables in cases of list/dict/set comprehensions + +.. + +.. bpo: 33141 +.. date: 2018-03-26-12-33-13 +.. nonce: 23wlxf +.. section: Library + +Have Field objects pass through __set_name__ to their default values, if +they have their own __set_name__. + +.. + +.. bpo: 33096 +.. date: 2018-03-25-13-18-16 +.. nonce: ofdbe7 +.. section: Library + +Allow ttk.Treeview.insert to insert iid that has a false boolean value. Note +iid=0 and iid=False would be same. Patch by Garvit Khatri. + +.. + +.. bpo: 32873 +.. date: 2018-03-24-19-54-48 +.. nonce: cHyoAm +.. section: Library + +Treat type variables and special typing forms as immutable by copy and +pickle. This fixes several minor issues and inconsistencies, and improves +backwards compatibility with Python 3.6. + +.. + +.. bpo: 33134 +.. date: 2018-03-24-19-34-26 +.. nonce: hbVeIX +.. section: Library + +When computing dataclass's __hash__, use the lookup table to contain the +function which returns the __hash__ value. This is an improvement over +looking up a string, and then testing that string to see what to do. + +.. + +.. bpo: 33127 +.. date: 2018-03-24-15-08-24 +.. nonce: olJmHv +.. section: Library + +The ssl module now compiles with LibreSSL 2.7.1. + +.. + +.. bpo: 32505 +.. date: 2018-03-22-16-05-56 +.. nonce: YK1N8v +.. section: Library + +Raise TypeError if a member variable of a dataclass is of type Field, but +doesn't have a type annotation. + +.. + +.. bpo: 33078 +.. date: 2018-03-21-17-59-39 +.. nonce: PQOniT +.. section: Library + +Fix the failure on OSX caused by the tests relying on sem_getvalue + +.. + +.. bpo: 33116 +.. date: 2018-03-21-16-52-26 +.. nonce: Tvzerj +.. section: Library + +Add 'Field' to dataclasses.__all__. + +.. + +.. bpo: 32896 +.. date: 2018-03-20-20-53-21 +.. nonce: ewW3Ln +.. section: Library + +Fix an error where subclassing a dataclass with a field that uses a +default_factory would generate an incorrect class. + +.. + +.. bpo: 33100 +.. date: 2018-03-19-20-47-00 +.. nonce: chyIO4 +.. section: Library + +Dataclasses: If a field has a default value that's a MemberDescriptorType, +then it's from that field being in __slots__, not an actual default value. + +.. + +.. bpo: 32953 +.. date: 2018-03-18-17-38-48 +.. nonce: t8WAWN +.. section: Library + +If a non-dataclass inherits from a frozen dataclass, allow attributes to be +added to the derived class. Only attributes from the frozen dataclass +cannot be assigned to. Require all dataclasses in a hierarchy to be either +all frozen or all non-frozen. + +.. + +.. bpo: 33061 +.. date: 2018-03-16-16-07-33 +.. nonce: TRTTek +.. section: Library + +Add missing ``NoReturn`` to ``__all__`` in typing.py + +.. + +.. bpo: 33078 +.. date: 2018-03-15-07-38-00 +.. nonce: RmjUF5 +.. section: Library + +Fix the size handling in multiprocessing.Queue when a pickling error occurs. + +.. + +.. bpo: 33064 +.. date: 2018-03-12-19-58-25 +.. nonce: LO2KIY +.. section: Library + +lib2to3 now properly supports trailing commas after ``*args`` and +``**kwargs`` in function signatures. + +.. + +.. bpo: 33056 +.. date: 2018-03-12-16-40-00 +.. nonce: lNN9Eh +.. section: Library + +FIX properly close leaking fds in concurrent.futures.ProcessPoolExecutor. + +.. + +.. bpo: 33021 +.. date: 2018-03-12-00-27-56 +.. nonce: m19B9T +.. section: Library + +Release the GIL during fstat() calls, avoiding hang of all threads when +calling mmap.mmap(), os.urandom(), and random.seed(). Patch by Nir Soffer. + +.. + +.. bpo: 31804 +.. date: 2018-03-11-19-03-52 +.. nonce: i8KUMp +.. section: Library + +Avoid failing in multiprocessing.Process if the standard streams are closed +or None at exit. + +.. + +.. bpo: 33037 +.. date: 2018-03-09-23-07-07 +.. nonce: nAJ3at +.. section: Library + +Skip sending/receiving data after SSL transport closing. + +.. + +.. bpo: 27683 +.. date: 2018-03-07-22-28-17 +.. nonce: 572Rv4 +.. section: Library + +Fix a regression in :mod:`ipaddress` that result of :meth:`hosts` is empty +when the network is constructed by a tuple containing an integer mask and +only 1 bit left for addresses. + +.. + +.. bpo: 32999 +.. date: 2018-03-06-20-30-20 +.. nonce: lgFXWl +.. section: Library + +Fix C implementation of ``ABC.__subclasscheck__(cls, subclass)`` crashed when +``subclass`` is not a type object. + +.. + +.. bpo: 33009 +.. date: 2018-03-06-11-54-59 +.. nonce: -Ekysb +.. section: Library + +Fix inspect.signature() for single-parameter partialmethods. + +.. + +.. bpo: 32969 +.. date: 2018-03-06-00-19-41 +.. nonce: rGTKa0 +.. section: Library + +Expose several missing constants in zlib and fix corresponding +documentation. + +.. + +.. bpo: 32056 +.. date: 2018-03-01-17-49-56 +.. nonce: IlpfgE +.. section: Library + +Improved exceptions raised for invalid number of channels and sample width +when read an audio file in modules :mod:`aifc`, :mod:`wave` and +:mod:`sunau`. + +.. + +.. bpo: 32844 +.. date: 2018-02-28-13-08-00 +.. nonce: u8tnAe +.. section: Library + +Fix wrong redirection of a low descriptor (0 or 1) to stderr in subprocess +if another low descriptor is closed. + +.. + +.. bpo: 32857 +.. date: 2018-02-16-14-37-14 +.. nonce: -XljAx +.. section: Library + +In :mod:`tkinter`, ``after_cancel(None)`` now raises a :exc:`ValueError` +instead of canceling the first scheduled function. Patch by Cheryl Sabella. + +.. + +.. bpo: 31639 +.. date: 2017-12-27-21-55-19 +.. nonce: l3avDJ +.. section: Library + +http.server now exposes a ThreadedHTTPServer class and uses it when the +module is run with ``-m`` to cope with web browsers pre-opening sockets. + +.. + +.. bpo: 27645 +.. date: 2017-10-05-20-41-48 +.. nonce: 1Y_Wag +.. section: Library + +:class:`sqlite3.Connection` now exposes a +:class:`~sqlite3.Connection.backup` method, if the underlying SQLite library +is at version 3.6.11 or higher. Patch by Lele Gaifax. + +.. + +.. bpo: 33126 +.. date: 2018-03-28-17-03-17 +.. nonce: 5UGkNv +.. section: Documentation + +Document PyBuffer_ToContiguous(). + +.. + +.. bpo: 27212 +.. date: 2018-03-22-19-23-04 +.. nonce: wrE5KR +.. section: Documentation + +Modify documentation for the :func:`islice` recipe to consume initial values +up to the start index. + +.. + +.. bpo: 28247 +.. date: 2018-03-20-20-11-05 +.. nonce: -V-WS- +.. section: Documentation + +Update :mod:`zipapp` documentation to describe how to make standalone +applications. + +.. + +.. bpo: 18802 +.. date: 2018-03-11-18-53-47 +.. nonce: JhAqH3 +.. section: Documentation + +Documentation changes for ipaddress. Patch by Jon Foster and Berker Peksag. + +.. + +.. bpo: 27428 +.. date: 2018-03-11-00-16-56 +.. nonce: B7A8FT +.. section: Documentation + +Update documentation to clarify that ``WindowsRegistryFinder`` implements +``MetaPathFinder``. (Patch by Himanshu Lakhara) + +.. + +.. bpo: 32872 +.. date: 2018-03-28-01-35-02 +.. nonce: J5NDUj +.. section: Tests + +Avoid regrtest compatibility issue with namespace packages. + +.. + +.. bpo: 32517 +.. date: 2018-03-09-07-05-12 +.. nonce: ugc1iW +.. section: Tests + +Fix failing ``test_asyncio`` on macOS 10.12.2+ due to transport of +``KqueueSelector`` loop was not being closed. + +.. + +.. bpo: 19417 +.. date: 2018-01-08-13-33-47 +.. nonce: 2asoXy +.. section: Tests + +Add test_bdb.py. + +.. + +.. bpo: 33163 +.. date: 2018-03-28-04-15-03 +.. nonce: hfpWuU +.. section: Build + +Upgrade pip to 9.0.3 and setuptools to v39.0.1. + +.. + +.. bpo: 33016 +.. date: 2018-03-07-01-33-33 +.. nonce: Z_Med0 +.. section: Windows + +Fix potential use of uninitialized memory in nt._getfinalpathname + +.. + +.. bpo: 32903 +.. date: 2018-02-28-11-03-24 +.. nonce: 1SXY4t +.. section: Windows + +Fix a memory leak in os.chdir() on Windows if the current directory is set +to a UNC path. + +.. + +.. bpo: 32726 +.. date: 2018-03-29-06-56-12 +.. nonce: urS9uX +.. section: macOS + +Build and link with private copy of Tcl/Tk 8.6 for the macOS 10.6+ +installer. The 10.9+ installer variant already does this. This means that +the Python 3.7 provided by the python.org macOS installers no longer need or +use any external versions of Tcl/Tk, either system-provided or +user-installed, such as ActiveTcl. + +.. + +.. bpo: 32984 +.. date: 2018-03-05-01-29-05 +.. nonce: NGjgT4 +.. section: IDLE + +Set ``__file__`` while running a startup file. Like Python, IDLE optionally +runs one startup file in the Shell window before presenting the first +interactive input prompt. For IDLE, ``-s`` runs a file named in +environmental variable :envvar:`IDLESTARTUP` or :envvar:`PYTHONSTARTUP`; +``-r file`` runs ``file``. Python sets ``__file__`` to the startup file +name before running the file and unsets it before the first prompt. IDLE +now does the same when run normally, without the ``-n`` option. + +.. + +.. bpo: 32940 +.. date: 2018-02-24-18-20-50 +.. nonce: ZaJ1Rf +.. section: IDLE + +Simplify and rename StringTranslatePseudoMapping in pyparse. + +.. + +.. bpo: 32885 +.. date: 2018-02-20-12-16-47 +.. nonce: dL5x7C +.. section: Tools/Demos + +Add an ``-n`` flag for ``Tools/scripts/pathfix.py`` to disable automatic +backup creation (files with ``~`` suffix). + +.. + +.. bpo: 33042 +.. date: 2018-03-20-21-43-09 +.. nonce: FPFp64 +.. section: C API + +Embedding applications may once again call PySys_ResetWarnOptions, +PySys_AddWarnOption, and PySys_AddXOption prior to calling Py_Initialize. + +.. + +.. bpo: 32374 +.. date: 2018-01-09-17-03-54 +.. nonce: SwwLoz +.. section: C API + +Document that m_traverse for multi-phase initialized modules can be called +with m_state=NULL, and add a sanity check diff --git a/Misc/NEWS.d/3.7.0b4.rst b/Misc/NEWS.d/3.7.0b4.rst new file mode 100644 index 00000000..1d4fc921 --- /dev/null +++ b/Misc/NEWS.d/3.7.0b4.rst @@ -0,0 +1,465 @@ +.. bpo: 33363 +.. date: 2018-04-26-22-48-28 +.. nonce: 8RCnN2 +.. release date: 2018-05-02 +.. section: Core and Builtins + +Raise a SyntaxError for ``async with`` and ``async for`` statements outside +of async functions. + +.. + +.. bpo: 33128 +.. date: 2018-04-24-22-31-04 +.. nonce: g2yLuf +.. section: Core and Builtins + +Fix a bug that causes PathFinder to appear twice on sys.meta_path. Patch by +Pablo Galindo Salgado. + +.. + +.. bpo: 33312 +.. date: 2018-04-19-08-30-07 +.. nonce: mDe2iL +.. section: Core and Builtins + +Fixed clang ubsan (undefined behavior sanitizer) warnings in dictobject.c by +adjusting how the internal struct _dictkeysobject shared keys structure is +declared. + +.. + +.. bpo: 33231 +.. date: 2018-04-05-22-20-44 +.. nonce: 3Jmo0q +.. section: Core and Builtins + +Fix potential memory leak in ``normalizestring()``. + +.. + +.. bpo: 33205 +.. date: 2018-04-03-00-58-41 +.. nonce: lk2F3r +.. section: Core and Builtins + +Change dict growth function from +``round_up_to_power_2(used*2+hashtable_size/2)`` to +``round_up_to_power_2(used*3)``. Previously, dict is shrinked only when +``used == 0``. Now dict has more chance to be shrinked. + +.. + +.. bpo: 29922 +.. date: 2018-04-03-00-30-25 +.. nonce: CdLuMl +.. section: Core and Builtins + +Improved error messages in 'async with' when ``__aenter__()`` or +``__aexit__()`` return non-awaitable object. + +.. + +.. bpo: 33199 +.. date: 2018-04-02-09-32-40 +.. nonce: TPnxQu +.. section: Core and Builtins + +Fix ``ma_version_tag`` in dict implementation is uninitialized when copying +from key-sharing dict. + +.. + +.. bpo: 33281 +.. date: 2018-05-01-22-35-50 +.. nonce: d4jOt4 +.. section: Library + +Fix ctypes.util.find_library regression on macOS. + +.. + +.. bpo: 33383 +.. date: 2018-04-29-11-15-38 +.. nonce: g32YWn +.. section: Library + +Fixed crash in the get() method of the :mod:`dbm.ndbm` database object when +it is called with a single argument. + +.. + +.. bpo: 33329 +.. date: 2018-04-23-13-21-39 +.. nonce: lQ-Eod +.. section: Library + +Fix multiprocessing regression on newer glibcs + +.. + +.. bpo: 991266 +.. date: 2018-04-21-00-24-08 +.. nonce: h93TP_ +.. section: Library + +Fix quoting of the ``Comment`` attribute of +:class:`http.cookies.SimpleCookie`. + +.. + +.. bpo: 33131 +.. date: 2018-04-20-10-43-17 +.. nonce: L2E977 +.. section: Library + +Upgrade bundled version of pip to 10.0.1. + +.. + +.. bpo: 33308 +.. date: 2018-04-18-19-12-25 +.. nonce: fW75xi +.. section: Library + +Fixed a crash in the :mod:`parser` module when converting an ST object to a +tree of tuples or lists with ``line_info=False`` and ``col_info=True``. + +.. + +.. bpo: 33266 +.. date: 2018-04-16-15-59-21 +.. nonce: w2PAm- +.. section: Library + +lib2to3 now recognizes ``rf'...'`` strings. + +.. + +.. bpo: 11594 +.. date: 2018-04-16-08-42-03 +.. nonce: QLo4vv +.. section: Library + +Ensure line-endings are respected when using lib2to3. + +.. + +.. bpo: 33254 +.. date: 2018-04-13-15-14-47 +.. nonce: DS4KFK +.. section: Library + +Have :func:`importlib.resources.contents` and +:meth:`importlib.abc.ResourceReader.contents` return an :term:`iterable` +instead of an :term:`iterator`. + +.. + +.. bpo: 33256 +.. date: 2018-04-10-20-57-14 +.. nonce: ndHkqu +.. section: Library + +Fix display of ``<module>`` call in the html produced by ``cgitb.html()``. +Patch by Stéphane Blondon. + +.. + +.. bpo: 33185 +.. date: 2018-04-08-22-54-07 +.. nonce: Id-Ba9 +.. section: Library + +Fixed regression when running pydoc with the :option:`-m` switch. (The +regression was introduced in 3.7.0b3 by the resolution of :issue:`33053`) +This fix also changed pydoc to add ``os.getcwd()`` to :data:`sys.path` when +necessary, rather than adding ``"."``. + +.. + +.. bpo: 33169 +.. date: 2018-04-06-14-56-26 +.. nonce: ByhDqb +.. section: Library + +Delete entries of ``None`` in :data:`sys.path_importer_cache` when +:meth:`importlib.machinery.invalidate_caches` is called. + +.. + +.. bpo: 33217 +.. date: 2018-04-05-13-36-09 +.. nonce: FfOKDI +.. section: Library + +Deprecate looking up non-Enum objects in Enum classes and Enum members (will +raise :exc:`TypeError` in 3.8+). + +.. + +.. bpo: 33203 +.. date: 2018-04-05-11-09-45 +.. nonce: Hje9Py +.. section: Library + +``random.Random.choice()`` now raises ``IndexError`` for empty sequences +consistently even when called from subclasses without a ``getrandbits()`` +implementation. + +.. + +.. bpo: 33224 +.. date: 2018-04-04-23-41-30 +.. nonce: pyR0jB +.. section: Library + +Update difflib.mdiff() for :pep:`479`. Convert an uncaught StopIteration in a +generator into a return-statement. + +.. + +.. bpo: 33209 +.. date: 2018-04-03-10-37-13 +.. nonce: 9sGWE_ +.. section: Library + +End framing at the end of C implementation of :func:`pickle.Pickler.dump`. + +.. + +.. bpo: 20104 +.. date: 2018-04-01-19-21-04 +.. nonce: -AKcGa +.. section: Library + +Improved error handling and fixed a reference leak in +:func:`os.posix_spawn()`. + +.. + +.. bpo: 33175 +.. date: 2018-03-29-04-32-25 +.. nonce: _zs1yM +.. section: Library + +In dataclasses, Field.__set_name__ now looks up the __set_name__ special +method on the class, not the instance, of the default value. + +.. + +.. bpo: 33097 +.. date: 2018-03-18-16-48-23 +.. nonce: Yl4gI2 +.. section: Library + +Raise RuntimeError when ``executor.submit`` is called during interpreter +shutdown. + +.. + +.. bpo: 31908 +.. date: 2017-10-31 +.. nonce: g4xh8x +.. section: Library + +Fix output of cover files for ``trace`` module command-line tool. Previously +emitted cover files only when ``--missing`` option was used. Patch by +Michael Selik. + +.. + +.. bpo: 33378 +.. date: 2018-04-29-04-02-18 +.. nonce: -anAHN +.. section: Documentation + +Add Korean language switcher for https://docs.python.org/3/ + +.. + +.. bpo: 33276 +.. date: 2018-04-20-14-09-36 +.. nonce: rA1z_3 +.. section: Documentation + +Clarify that the ``__path__`` attribute on modules cannot be just any value. + +.. + +.. bpo: 33201 +.. date: 2018-04-01-21-03-41 +.. nonce: aa8Lkl +.. section: Documentation + +Modernize documentation for writing C extension types. + +.. + +.. bpo: 33195 +.. date: 2018-04-01-14-30-36 +.. nonce: dRS-XX +.. section: Documentation + +Deprecate ``Py_UNICODE`` usage in ``c-api/arg`` document. ``Py_UNICODE`` +related APIs are deprecated since Python 3.3, but it is missed in the +document. + +.. + +.. bpo: 8243 +.. date: 2018-01-13-20-30-53 +.. nonce: s98r28 +.. section: Documentation + +Add a note about curses.addch and curses.addstr exception behavior when +writing outside a window, or pad. + +.. + +.. bpo: 32337 +.. date: 2017-12-22-17-29-37 +.. nonce: eZe-ID +.. section: Documentation + +Update documentation related with ``dict`` order. + +.. + +.. bpo: 33358 +.. date: 2018-04-27-11-46-35 +.. nonce: _OcR59 +.. section: Tests + +Fix ``test_embed.test_pre_initialization_sys_options()`` when the +interpreter is built with ``--enable-shared``. + +.. + +.. bpo: 33394 +.. date: 2018-04-30-17-36-46 +.. nonce: _Vdi4t +.. section: Build + +Enable the verbose build for extension modules, when GNU make is passed +macros on the command line. + +.. + +.. bpo: 33393 +.. date: 2018-04-30-17-19-37 +.. nonce: HkVCqI +.. section: Build + +Update config.guess and config.sub files. + +.. + +.. bpo: 33377 +.. date: 2018-04-30-16-53-00 +.. nonce: QBh6vP +.. section: Build + +Add new triplets for mips r6 and riscv variants (used in extension +suffixes). + +.. + +.. bpo: 32232 +.. date: 2018-04-17-00-38-19 +.. nonce: o7G_UO +.. section: Build + +By default, modules configured in `Modules/Setup` are no longer built with +`-DPy_BUILD_CORE`. Instead, modules that specifically need that preprocessor +definition include it in their individual entries. + +.. + +.. bpo: 33182 +.. date: 2018-03-30-14-55-48 +.. nonce: CePczb +.. section: Build + +The embedding tests can once again be built with clang 6.0 + +.. + +.. bpo: 33184 +.. date: 2018-04-13-11-28-55 +.. nonce: 7YhqQE +.. section: Windows + +Update Windows installer to use OpenSSL 1.1.0h. + +.. + +.. bpo: 33184 +.. date: 2018-04-07-00-51-34 +.. nonce: 3j208P +.. section: macOS + +Update macOS installer build to use OpenSSL 1.1.0h. + +.. + +.. bpo: 21474 +.. date: 2018-04-29-16-13-02 +.. nonce: bglg-F +.. section: IDLE + +Update word/identifier definition from ascii to unicode. In text and entry +boxes, this affects selection by double-click, movement left/right by +control-left/right, and deletion left/right by control-BACKSPACE/DEL. + +.. + +.. bpo: 33204 +.. date: 2018-04-02-00-28-13 +.. nonce: NBsuIv +.. section: IDLE + +IDLE: consistently color invalid string prefixes. A 'u' string prefix cannot +be paired with either 'r' or 'f'. Consistently color as much of the prefix, +starting at the right, as is valid. Revise and extend colorizer test. + +.. + +.. bpo: 33189 +.. date: 2018-04-03-18-10-00 +.. nonce: QrXR00 +.. section: Tools/Demos + +:program:`pygettext.py` now recognizes only literal strings as docstrings +and translatable strings, and rejects bytes literals and f-string +expressions. + +.. + +.. bpo: 31920 +.. date: 2018-03-26-18-54-24 +.. nonce: u_WKsT +.. section: Tools/Demos + +Fixed handling directories as arguments in the ``pygettext`` script. Based +on patch by Oleg Krasnikov. + +.. + +.. bpo: 29673 +.. date: 2018-03-16-17-25-05 +.. nonce: m8QtaW +.. section: Tools/Demos + +Fix pystackv and pystack gdbinit macros. + +.. + +.. bpo: 31583 +.. date: 2017-09-26-10-11-21 +.. nonce: TM90_H +.. section: Tools/Demos + +Fix 2to3 for using with --add-suffix option but without --output-dir option +for relative path to files in current directory. diff --git a/Misc/NEWS.d/3.7.0b5.rst b/Misc/NEWS.d/3.7.0b5.rst new file mode 100644 index 00000000..fb291098 --- /dev/null +++ b/Misc/NEWS.d/3.7.0b5.rst @@ -0,0 +1,592 @@ +.. bpo: 33622 +.. date: 2018-05-23-20-46-14 +.. nonce: xPucO9 +.. release date: 2018-05-30 +.. section: Core and Builtins + +Fixed a leak when the garbage collector fails to add an object with the +``__del__`` method or referenced by it into the :data:`gc.garbage` list. +:c:func:`PyGC_Collect` can now be called when an exception is set and +preserves it. + +.. + +.. bpo: 33509 +.. date: 2018-05-14-17-31-02 +.. nonce: pIUfTd +.. section: Core and Builtins + +Fix module_globals parameter of warnings.warn_explicit(): don't crash if +module_globals is not a dict. + +.. + +.. bpo: 20104 +.. date: 2018-05-14-11-34-55 +.. nonce: kqBNzv +.. section: Core and Builtins + +The new `os.posix_spawn` added in 3.7.0b1 was removed as we are still +working on what the API should look like. Expect this in 3.8 instead. + +.. + +.. bpo: 33475 +.. date: 2018-05-13-01-26-18 +.. nonce: rI0y1U +.. section: Core and Builtins + +Fixed miscellaneous bugs in converting annotations to strings and optimized +parentheses in the string representation. + +.. + +.. bpo: 33391 +.. date: 2018-05-02-08-36-03 +.. nonce: z4a7rb +.. section: Core and Builtins + +Fix a leak in set_symmetric_difference(). + +.. + +.. bpo: 28055 +.. date: 2018-04-25-20-44-42 +.. nonce: f49kfC +.. section: Core and Builtins + +Fix unaligned accesses in siphash24(). Patch by Rolf Eike Beer. + +.. + +.. bpo: 32911 +.. date: 2018-02-27-20-57-00 +.. nonce: cmKfco +.. section: Core and Builtins + +Due to unexpected compatibility issues discovered during downstream beta +testing, reverted :issue:`29463`. ``docstring`` field is removed from +Module, ClassDef, FunctionDef, and AsyncFunctionDef ast nodes which was +added in 3.7a1. Docstring expression is restored as a first statement in +their body. Based on patch by Inada Naoki. + +.. + +.. bpo: 21983 +.. date: 2017-10-02-21-02-14 +.. nonce: UoC319 +.. section: Core and Builtins + +Fix a crash in `ctypes.cast()` in case the type argument is a ctypes +structured data type. Patch by Eryk Sun and Oren Milman. + +.. + +.. bpo: 32751 +.. date: 2018-05-29-15-32-18 +.. nonce: oBTqr7 +.. section: Library + +When cancelling the task due to a timeout, :meth:`asyncio.wait_for` will now +wait until the cancellation is complete. + +.. + +.. bpo: 32684 +.. date: 2018-05-29-12-51-18 +.. nonce: ZEIism +.. section: Library + +Fix gather to propagate cancellation of itself even with return_exceptions. + +.. + +.. bpo: 33654 +.. date: 2018-05-29-01-13-39 +.. nonce: sa81Si +.. section: Library + +Support protocol type switching in SSLTransport.set_protocol(). + +.. + +.. bpo: 33674 +.. date: 2018-05-29-00-37-56 +.. nonce: 2IkGhL +.. section: Library + +Pause the transport as early as possible to further reduce the risk of +data_received() being called before connection_made(). + +.. + +.. bpo: 33674 +.. date: 2018-05-28-22-49-59 +.. nonce: 6LFFj7 +.. section: Library + +Fix a race condition in SSLProtocol.connection_made() of asyncio.sslproto: +start immediately the handshake instead of using call_soon(). Previously, +data_received() could be called before the handshake started, causing the +handshake to hang or fail. + +.. + +.. bpo: 31647 +.. date: 2018-05-28-18-40-26 +.. nonce: s4Fad3 +.. section: Library + +Fixed bug where calling write_eof() on a _SelectorSocketTransport after it's +already closed raises AttributeError. + +.. + +.. bpo: 32610 +.. date: 2018-05-28-16-40-32 +.. nonce: KvUAsL +.. section: Library + +Make asyncio.all_tasks() return only pending tasks. + +.. + +.. bpo: 32410 +.. date: 2018-05-28-16-19-35 +.. nonce: Z1DZaF +.. section: Library + +Avoid blocking on file IO in sendfile fallback code + +.. + +.. bpo: 33469 +.. date: 2018-05-28-15-55-12 +.. nonce: hmXBpY +.. section: Library + +Fix RuntimeError after closing loop that used run_in_executor + +.. + +.. bpo: 33672 +.. date: 2018-05-28-12-29-54 +.. nonce: GM_Xm_ +.. section: Library + +Fix Task.__repr__ crash with Cython's bogus coroutines + +.. + +.. bpo: 33654 +.. date: 2018-05-26-13-09-34 +.. nonce: IbYWxA +.. section: Library + +Fix transport.set_protocol() to support switching between asyncio.Protocol +and asyncio.BufferedProtocol. Fix loop.start_tls() to work with +asyncio.BufferedProtocols. + +.. + +.. bpo: 33652 +.. date: 2018-05-26-10-13-59 +.. nonce: humFJ1 +.. section: Library + +Pickles of type variables and subscripted generics are now future-proof and +compatible with older Python versions. + +.. + +.. bpo: 32493 +.. date: 2018-05-24-17-41-36 +.. nonce: 5tAoAu +.. section: Library + +Fixed :func:`uuid.uuid1` on FreeBSD. + +.. + +.. bpo: 33618 +.. date: 2018-05-23-20-14-34 +.. nonce: xU39lr +.. section: Library + +Finalize and document preliminary and experimental TLS 1.3 support with +OpenSSL 1.1.1 + +.. + +.. bpo: 33623 +.. date: 2018-05-23-14-58-05 +.. nonce: wAw1cF +.. section: Library + +Fix possible SIGSGV when asyncio.Future is created in __del__ + +.. + +.. bpo: 30877 +.. date: 2018-05-22-13-05-12 +.. nonce: JZEGjI +.. section: Library + +Fixed a bug in the Python implementation of the JSON decoder that prevented +the cache of parsed strings from clearing after finishing the decoding. +Based on patch by c-fos. + +.. + +.. bpo: 33570 +.. date: 2018-05-18-21-50-47 +.. nonce: 7CZy4t +.. section: Library + +Change TLS 1.3 cipher suite settings for compatibility with OpenSSL +1.1.1-pre6 and newer. OpenSSL 1.1.1 will have TLS 1.3 ciphers enabled by +default. + +.. + +.. bpo: 28556 +.. date: 2018-05-17-22-53-08 +.. nonce: C6Hnd1 +.. section: Library + +Do not simplify arguments to `typing.Union`. Now `Union[Manager, Employee]` +is not simplified to `Employee` at runtime. Such simplification previously +caused several bugs and limited possibilities for introspection. + +.. + +.. bpo: 33540 +.. date: 2018-05-16-18-10-38 +.. nonce: wy9LRV +.. section: Library + +Add a new ``block_on_close`` class attribute to ``ForkingMixIn`` and +``ThreadingMixIn`` classes of :mod:`socketserver`. + +.. + +.. bpo: 33548 +.. date: 2018-05-16-17-05-48 +.. nonce: xWslmx +.. section: Library + +tempfile._candidate_tempdir_list should consider common TEMP locations + +.. + +.. bpo: 33109 +.. date: 2018-05-16-14-57-58 +.. nonce: nPLL_S +.. section: Library + +argparse subparsers are once again not required by default, reverting the +change in behavior introduced by bpo-26510 in 3.7.0a2. + +.. + +.. bpo: 33536 +.. date: 2018-05-16-10-07-40 +.. nonce: _s0TE8 +.. section: Library + +dataclasses.make_dataclass now checks for invalid field names and duplicate +fields. Also, added a check for invalid field specifications. + +.. + +.. bpo: 33542 +.. date: 2018-05-16-09-30-27 +.. nonce: idNAcs +.. section: Library + +Prevent ``uuid.get_node`` from using a DUID instead of a MAC on Windows. +Patch by Zvi Effron + +.. + +.. bpo: 26819 +.. date: 2018-05-16-05-24-43 +.. nonce: taxbVT +.. section: Library + +Fix race condition with `ReadTransport.resume_reading` in Windows proactor +event loop. + +.. + +.. bpo: 0 +.. date: 2018-05-15-18-02-03 +.. nonce: pj2Mbb +.. section: Library + +Fix failure in `typing.get_type_hints()` when ClassVar was provided as a +string forward reference. + +.. + +.. bpo: 33505 +.. date: 2018-05-14-18-05-35 +.. nonce: L8pAyt +.. section: Library + +Optimize asyncio.ensure_future() by reordering if checks: 1.17x faster. + +.. + +.. bpo: 33497 +.. date: 2018-05-14-17-49-34 +.. nonce: wWT6XM +.. section: Library + +Add errors param to cgi.parse_multipart and make an encoding in FieldStorage +use the given errors (needed for Twisted). Patch by Amber Brown. + +.. + +.. bpo: 33495 +.. date: 2018-05-14-10-29-03 +.. nonce: TeGTQJ +.. section: Library + +Change dataclasses.Fields repr to use the repr of each of its members, +instead of str. This makes it more clear what each field actually +represents. This is especially true for the 'type' member. + +.. + +.. bpo: 33453 +.. date: 2018-05-12-06-01-02 +.. nonce: Fj-jMD +.. section: Library + +Fix dataclasses to work if using literal string type annotations or if using +PEP 563 "Postponed Evaluation of Annotations". Only specific string +prefixes are detected for both ClassVar ("ClassVar" and "typing.ClassVar") +and InitVar ("InitVar" and "dataclasses.InitVar"). + +.. + +.. bpo: 28556 +.. date: 2018-05-08-16-43-42 +.. nonce: _xr5mp +.. section: Library + +Minor fixes in typing module: add annotations to ``NamedTuple.__new__``, +pass ``*args`` and ``**kwds`` in ``Generic.__new__``. Original PRs by +Paulius Šarka and Chad Dombrova. + +.. + +.. bpo: 20087 +.. date: 2018-05-05-18-02-24 +.. nonce: lJrvXL +.. section: Library + +Updated alias mapping with glibc 2.27 supported locales. + +.. + +.. bpo: 33422 +.. date: 2018-05-05-09-53-05 +.. nonce: 4FtQ0q +.. section: Library + +Fix trailing quotation marks getting deleted when looking up byte/string +literals on pydoc. Patch by Andrés Delfino. + +.. + +.. bpo: 28167 +.. date: 2018-05-02-07-26-29 +.. nonce: 7FwDfN +.. section: Library + +The function ``platform.linux_distribution`` and ``platform.dist`` now +trigger a ``DeprecationWarning`` and have been marked for removal in Python +3.8 + +.. + +.. bpo: 33197 +.. date: 2018-04-29-23-56-20 +.. nonce: dgRLqr +.. section: Library + +Update error message when constructing invalid inspect.Parameters Patch by +Donghee Na. + +.. + +.. bpo: 33263 +.. date: 2018-04-11-20-29-19 +.. nonce: B56Hc1 +.. section: Library + +Fix FD leak in `_SelectorSocketTransport` Patch by Vlad Starostin. + +.. + +.. bpo: 32861 +.. date: 2018-04-02-20-44-54 +.. nonce: HeBjzN +.. section: Library + +The urllib.robotparser's ``__str__`` representation now includes wildcard +entries and the "Crawl-delay" and "Request-rate" fields. Patch by Michael +Lazar. + +.. + +.. bpo: 32257 +.. date: 2018-02-26-09-08-07 +.. nonce: 6ElnUt +.. section: Library + +The ssl module now contains OP_NO_RENEGOTIATION constant, available with +OpenSSL 1.1.0h or 1.1.1. + +.. + +.. bpo: 16865 +.. date: 2017-09-29-16-40-38 +.. nonce: l-f6I_ +.. section: Library + +Support arrays >=2GiB in :mod:`ctypes`. Patch by Segev Finer. + +.. + +.. bpo: 23859 +.. date: 2018-05-29-16-02-31 +.. nonce: E5gba1 +.. section: Documentation + +Document that `asyncio.wait()` does not cancel its futures on timeout. + +.. + +.. bpo: 32436 +.. date: 2018-05-23-11-59-51 +.. nonce: S1LGPa +.. section: Documentation + +Document :pep:`567` changes to asyncio. + +.. + +.. bpo: 33604 +.. date: 2018-05-22-11-47-14 +.. nonce: 5YHTpz +.. section: Documentation + +Update HMAC md5 default to a DeprecationWarning, bump removal to 3.8. + +.. + +.. bpo: 33503 +.. date: 2018-05-14-20-08-58 +.. nonce: Wvt0qg +.. section: Documentation + +Fix broken pypi link + +.. + +.. bpo: 33421 +.. date: 2018-05-14-15-15-41 +.. nonce: 3GU_QO +.. section: Documentation + +Add missing documentation for ``typing.AsyncContextManager``. + +.. + +.. bpo: 33655 +.. date: 2018-05-26-16-01-40 +.. nonce: Frb4LA +.. section: Tests + +Ignore test_posix_fallocate failures on BSD platforms that might be due to +running on ZFS. + +.. + +.. bpo: 32604 +.. date: 2018-05-14-13-32-46 +.. nonce: a_z6D_ +.. section: Tests + +Remove the _xxsubinterpreters module (meant for testing) and associated +helpers. This module was originally added recently in 3.7b1. + +.. + +.. bpo: 33614 +.. date: 2018-05-28-11-40-22 +.. nonce: 28e0sE +.. section: Build + +Ensures module definition files for the stable ABI on Windows are correctly +regenerated. + +.. + +.. bpo: 33522 +.. date: 2018-05-15-12-44-50 +.. nonce: mJoNcA +.. section: Build + +Enable CI builds on Visual Studio Team Services at +https://python.visualstudio.com/cpython + +.. + +.. bpo: 33012 +.. date: 2018-05-10-21-10-01 +.. nonce: 5Zfjac +.. section: Build + +Add ``-Wno-cast-function-type`` for gcc 8 for silencing warnings about +function casts like casting to PyCFunction in method definition lists. + +.. + +.. bpo: 13631 +.. date: 2018-05-16-13-25-58 +.. nonce: UIjDyY +.. section: macOS + +The .editrc file in user's home directory is now processed correctly during +the readline initialization through editline emulation on macOS. + +.. + +.. bpo: 33628 +.. date: 2018-05-23-19-51-07 +.. nonce: sLlFLO +.. section: IDLE + +IDLE: Cleanup codecontext.py and its test. + +.. + +.. bpo: 33564 +.. date: 2018-05-17-19-41-12 +.. nonce: XzHZJe +.. section: IDLE + +IDLE's code context now recognizes async as a block opener. + +.. + +.. bpo: 32831 +.. date: 2018-02-12-08-08-45 +.. nonce: srDRvU +.. section: IDLE + +Add docstrings and tests for codecontext. diff --git a/Misc/NEWS.d/3.7.0rc1.rst b/Misc/NEWS.d/3.7.0rc1.rst new file mode 100644 index 00000000..89457ef5 --- /dev/null +++ b/Misc/NEWS.d/3.7.0rc1.rst @@ -0,0 +1,275 @@ +.. bpo: 33803 +.. date: 2018-06-07-20-18-38 +.. nonce: n-Nq6_ +.. release date: 2018-06-12 +.. section: Core and Builtins + +Fix a crash in hamt.c caused by enabling GC tracking for an object that +hadn't all of its fields set to NULL. + +.. + +.. bpo: 33706 +.. date: 2018-05-31-14-50-04 +.. nonce: ztlH04 +.. section: Core and Builtins + +Fix a crash in Python initialization when parsing the command line options. +Thanks Christoph Gohlke for the bug report and the fix! + +.. + +.. bpo: 30654 +.. date: 2018-05-28-12-28-53 +.. nonce: 9fDJye +.. section: Core and Builtins + +Fixed reset of the SIGINT handler to SIG_DFL on interpreter shutdown even +when there was a custom handler set previously. Patch by Philipp Kerling. + +.. + +.. bpo: 31849 +.. date: 2018-05-14-11-00-00 +.. nonce: EmHaH4 +.. section: Core and Builtins + +Fix signed/unsigned comparison warning in pyhash.c. + +.. + +.. bpo: 30167 +.. date: 2018-06-10-19-29-17 +.. nonce: G5EgC5 +.. section: Library + +Prevent site.main() exception if PYTHONSTARTUP is set. Patch by Steve Weber. + +.. + +.. bpo: 33812 +.. date: 2018-06-10-13-26-02 +.. nonce: frGAOr +.. section: Library + +Datetime instance d with non-None tzinfo, but with d.tzinfo.utcoffset(d) +returning None is now treated as naive by the astimezone() method. + +.. + +.. bpo: 30805 +.. date: 2018-06-08-17-34-16 +.. nonce: 3qCWa0 +.. section: Library + +Avoid race condition with debug logging + +.. + +.. bpo: 33694 +.. date: 2018-06-07-23-51-00 +.. nonce: F1zIR1 +.. section: Library + +asyncio: Fix a race condition causing data loss on +pause_reading()/resume_reading() when using the ProactorEventLoop. + +.. + +.. bpo: 32493 +.. date: 2018-06-07-18-55-35 +.. nonce: 1Bte62 +.. section: Library + +Correct test for ``uuid_enc_be`` availability in ``configure.ac``. Patch by +Michael Felt. + +.. + +.. bpo: 33792 +.. date: 2018-06-07-12-38-12 +.. nonce: 3aKG7u +.. section: Library + +Add asyncio.WindowsSelectorEventLoopPolicy and +asyncio.WindowsProactorEventLoopPolicy. + +.. + +.. bpo: 33778 +.. date: 2018-06-05-20-22-30 +.. nonce: _tSAS6 +.. section: Library + +Update ``unicodedata``'s database to Unicode version 11.0.0. + +.. + +.. bpo: 33770 +.. date: 2018-06-05-11-29-26 +.. nonce: oBhxxw +.. section: Library + +improve base64 exception message for encoded inputs of invalid length + +.. + +.. bpo: 33769 +.. date: 2018-06-04-13-46-39 +.. nonce: D_pxYz +.. section: Library + +asyncio/start_tls: Fix error message; cancel callbacks in case of an +unhandled error; mark SSLTransport as closed if it is aborted. + +.. + +.. bpo: 33767 +.. date: 2018-06-03-22-41-59 +.. nonce: 2e82g3 +.. section: Library + +The concatenation (``+``) and repetition (``*``) sequence operations now +raise :exc:`TypeError` instead of :exc:`SystemError` when performed on +:class:`mmap.mmap` objects. Patch by Zackery Spytz. + +.. + +.. bpo: 33734 +.. date: 2018-06-01-10-55-48 +.. nonce: x1W9x0 +.. section: Library + +asyncio/ssl: Fix AttributeError, increase default handshake timeout + +.. + +.. bpo: 11874 +.. date: 2018-05-23-00-26-27 +.. nonce: glK5iP +.. section: Library + +Use a better regex when breaking usage into wrappable parts. Avoids bogus +assertion errors from custom metavar strings. + +.. + +.. bpo: 33582 +.. date: 2018-05-19-15-58-14 +.. nonce: qBZPmF +.. section: Library + +Emit a deprecation warning for inspect.formatargspec + +.. + +.. bpo: 33409 +.. date: 2018-06-08-23-46-01 +.. nonce: r4z9MM +.. section: Documentation + +Clarified the relationship between :pep:`538`'s PYTHONCOERCECLOCALE and PEP +540's PYTHONUTF8 mode. + +.. + +.. bpo: 33736 +.. date: 2018-06-01-12-27-40 +.. nonce: JVegIu +.. section: Documentation + +Improve the documentation of :func:`asyncio.open_connection`, +:func:`asyncio.start_server` and their UNIX socket counterparts. + +.. + +.. bpo: 31432 +.. date: 2017-09-13-07-14-59 +.. nonce: yAY4Z3 +.. section: Documentation + +Clarify meaning of CERT_NONE, CERT_OPTIONAL, and CERT_REQUIRED flags for +ssl.SSLContext.verify_mode. + +.. + +.. bpo: 5755 +.. date: 2018-06-04-21-34-34 +.. nonce: 65GmCj +.. section: Build + +Move ``-Wstrict-prototypes`` option to ``CFLAGS_NODIST`` from ``OPT``. This +option emitted annoying warnings when building extension modules written in +C++. + +.. + +.. bpo: 33720 +.. date: 2018-06-04-09-20-53 +.. nonce: VKDXHK +.. section: Windows + +Reduces maximum marshal recursion depth on release builds. + +.. + +.. bpo: 33656 +.. date: 2018-06-10-17-59-36 +.. nonce: 60ZqJS +.. section: IDLE + +On Windows, add API call saying that tk scales for DPI. On Windows 8.1+ or +10, with DPI compatibility properties of the Python binary unchanged, and a +monitor resolution greater than 96 DPI, this should make text and lines +sharper. It should otherwise have no effect. + +.. + +.. bpo: 33768 +.. date: 2018-06-04-19-23-11 +.. nonce: I_2qpV +.. section: IDLE + +Clicking on a context line moves that line to the top of the editor window. + +.. + +.. bpo: 33763 +.. date: 2018-06-03-20-12-57 +.. nonce: URiFlE +.. section: IDLE + +IDLE: Use read-only text widget for code context instead of label widget. + +.. + +.. bpo: 33664 +.. date: 2018-06-03-09-13-28 +.. nonce: PZzQyL +.. section: IDLE + +Scroll IDLE editor text by lines. Previously, the mouse wheel and scrollbar +slider moved text by a fixed number of pixels, resulting in partial lines at +the top of the editor box. The change also applies to the shell and grep +output windows, but not to read-only text views. + +.. + +.. bpo: 33679 +.. date: 2018-05-29-07-14-37 +.. nonce: MgX_Ui +.. section: IDLE + +Enable theme-specific color configuration for Code Context. Use the +Highlights tab to see the setting for built-in themes or add settings to +custom themes. + +.. + +.. bpo: 33642 +.. date: 2018-05-24-20-42-44 +.. nonce: J0VQbS +.. section: IDLE + +Display up to maxlines non-blank lines for Code Context. If there is no +current context, show a single blank line. diff --git a/Misc/NEWS.d/3.8.0a1.rst b/Misc/NEWS.d/3.8.0a1.rst new file mode 100644 index 00000000..cb635e61 --- /dev/null +++ b/Misc/NEWS.d/3.8.0a1.rst @@ -0,0 +1,8978 @@ +.. bpo: 35746 +.. date: 2019-01-15-18-16-05 +.. nonce: nMSd0j +.. release date: 2019-02-03 +.. section: Security + +[CVE-2019-5010] Fix a NULL pointer deref in ssl module. The cert parser did +not handle CRL distribution points with empty DP or URI correctly. A +malicious or buggy certificate can result into segfault. Vulnerability +(TALOS-2018-0758) reported by Colin Read and Nicolas Edet of Cisco. + +.. + +.. bpo: 34812 +.. date: 2018-11-23-15-00-23 +.. nonce: 84VQnb +.. section: Security + +The :option:`-I` command line option (run Python in isolated mode) is now +also copied by the :mod:`multiprocessing` and ``distutils`` modules when +spawning child processes. Previously, only :option:`-E` and :option:`-s` +options (enabled by :option:`-I`) were copied. + +.. + +.. bpo: 34791 +.. date: 2018-09-24-18-49-25 +.. nonce: 78GmIG +.. section: Security + +The xml.sax and xml.dom.domreg no longer use environment variables to +override parser implementations when sys.flags.ignore_environment is set by +-E or -I arguments. + +.. + +.. bpo: 17239 +.. date: 2018-09-11-18-30-55 +.. nonce: kOpwK2 +.. section: Security + +The xml.sax and xml.dom.minidom parsers no longer processes external +entities by default. External DTD and ENTITY declarations no longer load +files or create network connections. + +.. + +.. bpo: 34623 +.. date: 2018-09-10-16-05-39 +.. nonce: Ua9jMv +.. section: Security + +CVE-2018-14647: The C accelerated _elementtree module now initializes hash +randomization salt from _Py_HashSecret instead of libexpat's default CSPRNG. + +.. + +.. bpo: 34405 +.. date: 2018-08-15-12-12-47 +.. nonce: qbHTH_ +.. section: Security + +Updated to OpenSSL 1.1.0i for Windows builds. + +.. + +.. bpo: 33871 +.. date: 2018-06-26-19-35-33 +.. nonce: S4HR9n +.. section: Security + +Fixed sending the part of the file in :func:`os.sendfile` on macOS. Using +the *trailers* argument could cause sending more bytes from the input file +than was specified. + +.. + +.. bpo: 32533 +.. date: 2018-05-28-08-55-30 +.. nonce: IzwkBI +.. section: Security + +Fixed thread-safety of error handling in _ssl. + +.. + +.. bpo: 33136 +.. date: 2018-03-25-12-05-43 +.. nonce: TzSN4x +.. section: Security + +Harden ssl module against LibreSSL CVE-2018-8970. +X509_VERIFY_PARAM_set1_host() is called with an explicit namelen. A new test +ensures that NULL bytes are not allowed. + +.. + +.. bpo: 33001 +.. date: 2018-03-05-10-09-51 +.. nonce: elj4Aa +.. section: Security + +Minimal fix to prevent buffer overrun in os.symlink on Windows + +.. + +.. bpo: 32981 +.. date: 2018-03-02-10-24-52 +.. nonce: O_qDyj +.. section: Security + +Regexes in difflib and poplib were vulnerable to catastrophic backtracking. +These regexes formed potential DOS vectors (REDOS). They have been +refactored. This resolves CVE-2018-1060 and CVE-2018-1061. Patch by Jamie +Davis. + +.. + +.. bpo: 28414 +.. date: 2017-08-06-14-43-45 +.. nonce: mzZ6vD +.. section: Security + +The ssl module now allows users to perform their own IDN en/decoding when +using SNI. + +.. + +.. bpo: 35877 +.. date: 2019-02-01-22-38-11 +.. nonce: Jrse8f +.. section: Core and Builtins + +Make parenthesis optional for named expressions in while statement. Patch by +Karthikeyan Singaravelan. + +.. + +.. bpo: 35814 +.. date: 2019-01-24-13-25-21 +.. nonce: r_MjA6 +.. section: Core and Builtins + +Allow same right hand side expressions in annotated assignments as in normal +ones. In particular, ``x: Tuple[int, int] = 1, 2`` (without parentheses on +the right) is now allowed. + +.. + +.. bpo: 35766 +.. date: 2019-01-22-19-17-27 +.. nonce: gh1tHZ +.. section: Core and Builtins + +Add the option to parse PEP 484 type comments in the ast module. (Off by +default.) This is merging the key functionality of the third party fork +thereof, [typed_ast](https://github.com/python/typed_ast). + +.. + +.. bpo: 35713 +.. date: 2019-01-22-18-50-21 +.. nonce: bTeUsa +.. section: Core and Builtins + +Reorganize Python initialization to get working exceptions and sys.stderr +earlier. + +.. + +.. bpo: 33416 +.. date: 2019-01-19-19-41-53 +.. nonce: VDeOU5 +.. section: Core and Builtins + +Add end line and end column position information to the Python AST nodes. +This is a C-level backwards incompatible change. + +.. + +.. bpo: 35720 +.. date: 2019-01-12-23-33-04 +.. nonce: LELKQx +.. section: Core and Builtins + +Fixed a minor memory leak in pymain_parse_cmdline_impl function in +Modules/main.c + +.. + +.. bpo: 35634 +.. date: 2019-01-05-18-39-49 +.. nonce: nVP_gs +.. section: Core and Builtins + +``func(**kwargs)`` will now raise an error when ``kwargs`` is a mapping +containing multiple entries with the same key. An error was already raised +when other keyword arguments are passed before ``**kwargs`` since Python +3.6. + +.. + +.. bpo: 35623 +.. date: 2018-12-31-02-37-20 +.. nonce: 24AQhY +.. section: Core and Builtins + +Fix a crash when sorting very long lists. Patch by Stephan Hohe. + +.. + +.. bpo: 35214 +.. date: 2018-12-30-15-36-23 +.. nonce: GWDQcv +.. section: Core and Builtins + +clang Memory Sanitizer build instrumentation was added to work around false +positives from posix, socket, time, test_io, and test_faulthandler. + +.. + +.. bpo: 35560 +.. date: 2018-12-22-22-19-51 +.. nonce: 9vMWSP +.. section: Core and Builtins + +Fix an assertion error in :func:`format` in debug build for floating point +formatting with "n" format, zero padding and small width. Release build is +not impacted. Patch by Karthikeyan Singaravelan. + +.. + +.. bpo: 35552 +.. date: 2018-12-21-13-29-30 +.. nonce: 1DzQQc +.. section: Core and Builtins + +Format characters ``%s`` and ``%V`` in :c:func:`PyUnicode_FromFormat` and +``%s`` in :c:func:`PyBytes_FromFormat` no longer read memory past the limit +if *precision* is specified. + +.. + +.. bpo: 35504 +.. date: 2018-12-15-14-01-45 +.. nonce: JtKczP +.. section: Core and Builtins + +Fix segfaults and :exc:`SystemError`\ s when deleting certain attributes. +Patch by Zackery Spytz. + +.. + +.. bpo: 35504 +.. date: 2018-12-15-00-47-41 +.. nonce: 9gVuen +.. section: Core and Builtins + +Fixed a SystemError when delete the characters_written attribute of an +OSError. + +.. + +.. bpo: 35494 +.. date: 2018-12-14-18-02-34 +.. nonce: IWOPtb +.. section: Core and Builtins + +Improved syntax error messages for unbalanced parentheses in f-string. + +.. + +.. bpo: 35444 +.. date: 2018-12-09-13-09-39 +.. nonce: 9kYn4V +.. section: Core and Builtins + +Fixed error handling in pickling methods when fail to look up builtin +"getattr". Sped up pickling iterators. + +.. + +.. bpo: 35436 +.. date: 2018-12-07-02-38-01 +.. nonce: 0VW7p9 +.. section: Core and Builtins + +Fix various issues with memory allocation error handling. Patch by Zackery +Spytz. + +.. + +.. bpo: 35423 +.. date: 2018-12-05-16-24-05 +.. nonce: UIie_O +.. section: Core and Builtins + +Separate the signal handling trigger in the eval loop from the "pending +calls" machinery. There is no semantic change and the difference in +performance is insignificant. + +.. + +.. bpo: 35357 +.. date: 2018-12-03-21-20-24 +.. nonce: rhhoiC +.. section: Core and Builtins + +Internal attributes' names of unittest.mock._Call and +unittest.mock.MagicProxy (name, parent & from_kall) are now prefixed with +_mock_ in order to prevent clashes with widely used object attributes. Fixed +minor typo in test function name. + +.. + +.. bpo: 35372 +.. date: 2018-12-01-19-20-53 +.. nonce: RwVJjZ +.. section: Core and Builtins + +Fixed the code page decoder for input longer than 2 GiB containing +undecodable bytes. + +.. + +.. bpo: 35336 +.. date: 2018-11-29-23-59-52 +.. nonce: 8LOz4F +.. section: Core and Builtins + +Fix PYTHONCOERCECLOCALE=1 environment variable: only coerce the C locale if +the LC_CTYPE locale is "C". + +.. + +.. bpo: 31241 +.. date: 2018-11-21-14-05-51 +.. nonce: Kin10- +.. section: Core and Builtins + +The *lineno* and *col_offset* attributes of AST nodes for list +comprehensions, generator expressions and tuples are now point to the +opening parenthesis or square brace. For tuples without parenthesis they +point to the position of the first item. + +.. + +.. bpo: 33954 +.. date: 2018-11-20-22-33-38 +.. nonce: RzSngM +.. section: Core and Builtins + +For :meth:`str.format`, :meth:`float.__format__` and +:meth:`complex.__format__` methods for non-ASCII decimal point when using +the "n" formatter. + +.. + +.. bpo: 35269 +.. date: 2018-11-17-10-18-29 +.. nonce: gjm1LO +.. section: Core and Builtins + +Fix a possible segfault involving a newly created coroutine. Patch by +Zackery Spytz. + +.. + +.. bpo: 35224 +.. date: 2018-11-13-14-26-54 +.. nonce: F0B6UQ +.. section: Core and Builtins + +Implement :pep:`572` (assignment expressions). Patch by Emily Morehouse. + +.. + +.. bpo: 32492 +.. date: 2018-11-13-01-03-10 +.. nonce: voIdcp +.. section: Core and Builtins + +Speed up :func:`namedtuple` attribute access by 1.6x using a C fast-path +for the name descriptors. Patch by Pablo Galindo. + +.. + +.. bpo: 35214 +.. date: 2018-11-13-00-40-35 +.. nonce: OQBjph +.. section: Core and Builtins + +Fixed an out of bounds memory access when parsing a truncated unicode escape +sequence at the end of a string such as ``'\N'``. It would read one byte +beyond the end of the memory allocation. + +.. + +.. bpo: 35214 +.. date: 2018-11-12-11-38-06 +.. nonce: PCHKbX +.. section: Core and Builtins + +The interpreter and extension modules have had annotations added so that +they work properly under clang's Memory Sanitizer. A new configure flag +--with-memory-sanitizer has been added to make test builds of this nature +easier to perform. + +.. + +.. bpo: 35193 +.. date: 2018-11-08-15-00-58 +.. nonce: HzPS6R +.. section: Core and Builtins + +Fix an off by one error in the bytecode peephole optimizer where it could +read bytes beyond the end of bounds of an array when removing unreachable +code. This bug was present in every release of Python 3.6 and 3.7 until now. + +.. + +.. bpo: 35169 +.. date: 2018-11-05-21-19-05 +.. nonce: _FyPI2 +.. section: Core and Builtins + +Improved error messages for forbidden assignments. + +.. + +.. bpo: 34022 +.. date: 2018-11-04-18-13-40 +.. nonce: U3btVj +.. section: Core and Builtins + +Fix handling of hash-based bytecode files in :mod:`zipimport`. Patch by +Elvis Pranskevichus. + +.. + +.. bpo: 28401 +.. date: 2018-11-03-10-37-29 +.. nonce: RprDIg +.. section: Core and Builtins + +Debug builds will no longer to attempt to import extension modules built for +the ABI as they were never compatible to begin with. Patch by Stefano +Rivera. + +.. + +.. bpo: 29341 +.. date: 2018-10-25-20-53-32 +.. nonce: jH-AMF +.. section: Core and Builtins + +Clarify in the docstrings of :mod:`os` methods that path-like objects are +also accepted as input parameters. + +.. + +.. bpo: 35050 +.. date: 2018-10-23-15-03-53 +.. nonce: 49wraS +.. section: Core and Builtins + +:mod:`socket`: Fix off-by-one bug in length check for ``AF_ALG`` name and +type. + +.. + +.. bpo: 29743 +.. date: 2018-10-21-17-43-48 +.. nonce: aeCcKR +.. section: Core and Builtins + +Raise :exc:`ValueError` instead of :exc:`OverflowError` in case of a +negative ``_length_`` in a :class:`ctypes.Array` subclass. Also raise +:exc:`TypeError` instead of :exc:`AttributeError` for non-integer +``_length_``. Original patch by Oren Milman. + +.. + +.. bpo: 16806 +.. date: 2018-10-20-18-05-58 +.. nonce: zr3A9N +.. section: Core and Builtins + +Fix ``lineno`` and ``col_offset`` for multi-line string tokens. + +.. + +.. bpo: 35029 +.. date: 2018-10-20-10-26-15 +.. nonce: t4tZcQ +.. section: Core and Builtins + +:exc:`SyntaxWarning` raised as an exception at code generation time will be +now replaced with a :exc:`SyntaxError` for better error reporting. + +.. + +.. bpo: 34983 +.. date: 2018-10-14-17-26-41 +.. nonce: l8XaZd +.. section: Core and Builtins + +Expose :meth:`symtable.Symbol.is_nonlocal` in the symtable module. Patch by +Pablo Galindo. + +.. + +.. bpo: 34974 +.. date: 2018-10-13-22-24-19 +.. nonce: 7LgTc2 +.. section: Core and Builtins + +:class:`bytes` and :class:`bytearray` constructors no longer convert +unexpected exceptions (e.g. :exc:`MemoryError` and :exc:`KeyboardInterrupt`) +to :exc:`TypeError`. + +.. + +.. bpo: 34939 +.. date: 2018-10-13-17-40-15 +.. nonce: 0gpxlJ +.. section: Core and Builtins + +Allow annotated names in module namespace that are declared global before +the annotation happens. Patch by Pablo Galindo. + +.. + +.. bpo: 34973 +.. date: 2018-10-13-16-42-03 +.. nonce: B5M-3g +.. section: Core and Builtins + +Fixed crash in :func:`bytes` when the :class:`list` argument is mutated +while it is iterated. + +.. + +.. bpo: 34876 +.. date: 2018-10-06-14-02-51 +.. nonce: oBKBA4 +.. section: Core and Builtins + +The *lineno* and *col_offset* attributes of the AST for decorated function +and class refer now to the position of the corresponding ``def``, ``async +def`` and ``class`` instead of the position of the first decorator. This +leads to more correct line reporting in tracing. This is the only case when +the position of child AST nodes can precede the position of the parent AST +node. + +.. + +.. bpo: 34879 +.. date: 2018-10-02-22-55-11 +.. nonce: 7VNH2a +.. section: Core and Builtins + +Fix a possible null pointer dereference in bytesobject.c. Patch by Zackery +Spytz. + +.. + +.. bpo: 34784 +.. date: 2018-10-02-09-10-47 +.. nonce: 07hdgD +.. section: Core and Builtins + +Fix the implementation of PyStructSequence_NewType in order to create heap +allocated StructSequences. + +.. + +.. bpo: 32912 +.. date: 2018-10-01-10-41-53 +.. nonce: JeIOdM +.. section: Core and Builtins + +A :exc:`SyntaxWarning` is now emitted instead of a :exc:`DeprecationWarning` +for invalid escape sequences in string and bytes literals. + +.. + +.. bpo: 34854 +.. date: 2018-09-30-19-27-13 +.. nonce: 6TKTcB +.. section: Core and Builtins + +Fixed a crash in compiling string annotations containing a lambda with a +keyword-only argument that doesn't have a default value. + +.. + +.. bpo: 34850 +.. date: 2018-09-30-11-19-55 +.. nonce: CbgDwb +.. section: Core and Builtins + +The compiler now produces a :exc:`SyntaxWarning` when identity checks +(``is`` and ``is not``) are used with certain types of literals (e.g. +strings, ints). These can often work by accident in CPython, but are not +guaranteed by the language spec. The warning advises users to use equality +tests (``==`` and ``!=``) instead. + +.. + +.. bpo: 34824 +.. date: 2018-09-27-11-10-02 +.. nonce: VLlCaU +.. section: Core and Builtins + +Fix a possible null pointer dereference in Modules/_ssl.c. Patch by Zackery +Spytz. + +.. + +.. bpo: 30156 +.. date: 2018-09-24-17-51-15 +.. nonce: pH0j5j +.. section: Core and Builtins + +The C function ``property_descr_get()`` uses a "cached" tuple to optimize +function calls. But this tuple can be discovered in debug mode with +:func:`sys.getobjects()`. Remove the optimization, it's not really worth it +and it causes 3 different crashes last years. + +.. + +.. bpo: 34762 +.. date: 2018-09-21-11-06-56 +.. nonce: 1nN53m +.. section: Core and Builtins + +Fix contextvars C API to use PyObject* pointer types. + +.. + +.. bpo: 34751 +.. date: 2018-09-20-15-41-58 +.. nonce: Yiv0pV +.. section: Core and Builtins + +The hash function for tuples is now based on xxHash which gives better +collision results on (formerly) pathological cases. Additionally, on 64-bit +systems it improves tuple hashes in general. Patch by Jeroen Demeyer with +substantial contributions by Tim Peters. + +.. + +.. bpo: 34735 +.. date: 2018-09-19-06-57-34 +.. nonce: -3mrSJ +.. section: Core and Builtins + +Fix a memory leak in Modules/timemodule.c. Patch by Zackery Spytz. + +.. + +.. bpo: 34683 +.. date: 2018-09-15-19-32-34 +.. nonce: msCiQE +.. section: Core and Builtins + +Fixed a bug where some SyntaxError error pointed to locations that were +off-by-one. + +.. + +.. bpo: 34651 +.. date: 2018-09-13-12-21-08 +.. nonce: v-bUeV +.. section: Core and Builtins + +Only allow the main interpreter to fork. The avoids the possibility of +affecting the main interpreter, which is critical to operation of the +runtime. + +.. + +.. bpo: 34653 +.. date: 2018-09-13-12-06-09 +.. nonce: z8NE-i +.. section: Core and Builtins + +Remove unused function PyParser_SimpleParseStringFilename. + +.. + +.. bpo: 32236 +.. date: 2018-09-11-23-50-40 +.. nonce: 3RupnN +.. section: Core and Builtins + +Warn that line buffering is not supported if :func:`open` is called with +binary mode and ``buffering=1``. + +.. + +.. bpo: 34641 +.. date: 2018-09-11-23-12-33 +.. nonce: gFBCc9 +.. section: Core and Builtins + +Further restrict the syntax of the left-hand side of keyword arguments in +function calls. In particular, ``f((keyword)=arg)`` is now disallowed. + +.. + +.. bpo: 34637 +.. date: 2018-09-11-17-25-44 +.. nonce: HSLqY4 +.. section: Core and Builtins + +Make the *start* argument to *sum()* visible as a keyword argument. + +.. + +.. bpo: 1621 +.. date: 2018-09-11-15-19-37 +.. nonce: 7o19yG +.. section: Core and Builtins + +Do not assume signed integer overflow behavior (C undefined behavior) when +performing set hash table resizing. + +.. + +.. bpo: 34588 +.. date: 2018-09-05-22-56-52 +.. nonce: UIuPmL +.. section: Core and Builtins + +Fix an off-by-one in the recursive call pruning feature of traceback +formatting. + +.. + +.. bpo: 34485 +.. date: 2018-08-29-11-04-19 +.. nonce: c2AFdp +.. section: Core and Builtins + +On Windows, the LC_CTYPE is now set to the user preferred locale at startup. +Previously, the LC_CTYPE locale was "C" at startup, but changed when calling +setlocale(LC_CTYPE, "") or setlocale(LC_ALL, ""). + +.. + +.. bpo: 34485 +.. date: 2018-08-29-09-27-47 +.. nonce: 5aJCmw +.. section: Core and Builtins + +Standard streams like sys.stdout now use the "surrogateescape" error +handler, instead of "strict", on the POSIX locale (when the C locale is not +coerced and the UTF-8 Mode is disabled). + +.. + +.. bpo: 34485 +.. date: 2018-08-28-23-01-14 +.. nonce: dq1Kqk +.. section: Core and Builtins + +Fix the error handler of standard streams like sys.stdout: +PYTHONIOENCODING=":" is now ignored instead of setting the error handler to +"strict". + +.. + +.. bpo: 34485 +.. date: 2018-08-28-17-48-40 +.. nonce: aFwck2 +.. section: Core and Builtins + +Python now gets the locale encoding with C code to initialize the encoding +of standard streams like sys.stdout. Moreover, the encoding is now +initialized to the Python codec name to get a normalized encoding name and +to ensure that the codec is loaded. The change avoids importing _bootlocale +and _locale modules at startup by default. + +.. + +.. bpo: 34527 +.. date: 2018-08-28-11-53-39 +.. nonce: aBEX9b +.. section: Core and Builtins + +On FreeBSD, Py_DecodeLocale() and Py_EncodeLocale() now also forces the +ASCII encoding if the LC_CTYPE locale is "POSIX", not only if the LC_CTYPE +locale is "C". + +.. + +.. bpo: 34527 +.. date: 2018-08-28-11-52-13 +.. nonce: sh5MQJ +.. section: Core and Builtins + +The UTF-8 Mode is now also enabled by the "POSIX" locale, not only by the +"C" locale. + +.. + +.. bpo: 34403 +.. date: 2018-08-28-10-49-55 +.. nonce: 4Q3LzP +.. section: Core and Builtins + +On HP-UX with C or POSIX locale, sys.getfilesystemencoding() now returns +"ascii" instead of "roman8" (when the UTF-8 Mode is disabled and the C +locale is not coerced). + +.. + +.. bpo: 34523 +.. date: 2018-08-28-01-45-01 +.. nonce: aUUkc3 +.. section: Core and Builtins + +The Python filesystem encoding is now read earlier during the Python +initialization. + +.. + +.. bpo: 12458 +.. date: 2018-08-15-20-46-49 +.. nonce: ApHbx5 +.. section: Core and Builtins + +Tracebacks show now correct line number for subexpressions in multiline +expressions. Tracebacks show now the line number of the first line for +multiline expressions instead of the line number of the last subexpression. + +.. + +.. bpo: 34408 +.. date: 2018-08-14-22-35-19 +.. nonce: aomWYW +.. section: Core and Builtins + +Prevent a null pointer dereference and resource leakage in +``PyInterpreterState_New()``. + +.. + +.. bpo: 34400 +.. date: 2018-08-14-03-52-43 +.. nonce: AJD0bz +.. section: Core and Builtins + +Fix undefined behavior in parsetok.c. Patch by Zackery Spytz. + +.. + +.. bpo: 33073 +.. date: 2018-08-12-16-03-58 +.. nonce: XWu1Jh +.. section: Core and Builtins + +Added as_integer_ratio to ints to make them more interoperable with floats. + +.. + +.. bpo: 34377 +.. date: 2018-08-10-15-05-00 +.. nonce: EJMMY4 +.. section: Core and Builtins + +Update valgrind suppression list to use +``_PyObject_Free``/``_PyObject_Realloc`` instead of +``PyObject_Free``/``PyObject_Realloc``. + +.. + +.. bpo: 34353 +.. date: 2018-08-09-18-42-49 +.. nonce: GIOm_8 +.. section: Core and Builtins + +Added the "socket" option in the `stat.filemode()` Python implementation to +match the C implementation. + +.. + +.. bpo: 34320 +.. date: 2018-08-02-22-34-59 +.. nonce: hNshAA +.. section: Core and Builtins + +Fix ``dict(od)`` didn't copy iteration order of OrderedDict. + +.. + +.. bpo: 34113 +.. date: 2018-07-28-10-34-00 +.. nonce: eZ5FWV +.. section: Core and Builtins + +Fixed crash on debug builds when opcode stack was adjusted with negative +numbers. Patch by Constantin Petrisor. + +.. + +.. bpo: 34100 +.. date: 2018-07-27-20-04-52 +.. nonce: ypJQX1 +.. section: Core and Builtins + +Compiler now merges constants in tuples and frozensets recursively. Code +attributes like ``co_names`` are merged too. + +.. + +.. bpo: 34151 +.. date: 2018-07-25-20-26-02 +.. nonce: Q2pK9Q +.. section: Core and Builtins + +Performance of list concatenation, repetition and slicing operations is +slightly improved. Patch by Sergey Fedoseev. + +.. + +.. bpo: 34170 +.. date: 2018-07-25-19-23-33 +.. nonce: v1h_H2 +.. section: Core and Builtins + +-X dev: it is now possible to override the memory allocator using +PYTHONMALLOC even if the developer mode is enabled. + +.. + +.. bpo: 33237 +.. date: 2018-07-24-12-54-57 +.. nonce: O95mps +.. section: Core and Builtins + +Improved :exc:`AttributeError` message for partially initialized module. + +.. + +.. bpo: 34149 +.. date: 2018-07-23-21-49-05 +.. nonce: WSV-_g +.. section: Core and Builtins + +Fix min and max functions to get default behavior when key is None. + +.. + +.. bpo: 34125 +.. date: 2018-07-23-16-34-03 +.. nonce: jCl2Q2 +.. section: Core and Builtins + +Profiling of unbound built-in methods now works when ``**kwargs`` is given. + +.. + +.. bpo: 34141 +.. date: 2018-07-18-08-36-58 +.. nonce: Fo7Q5r +.. section: Core and Builtins + +Optimized pickling atomic types (None, bool, int, float, bytes, str). + +.. + +.. bpo: 34126 +.. date: 2018-07-16-20-55-29 +.. nonce: mBVmgc +.. section: Core and Builtins + +Fix crashes when profiling certain invalid calls of unbound methods. Patch +by Jeroen Demeyer. + +.. + +.. bpo: 24618 +.. date: 2018-07-14-14-01-37 +.. nonce: iTKjD_ +.. section: Core and Builtins + +Fixed reading invalid memory when create the code object with too small +varnames tuple or too large argument counts. + +.. + +.. bpo: 34068 +.. date: 2018-07-14-08-58-46 +.. nonce: 9xfM55 +.. section: Core and Builtins + +In :meth:`io.IOBase.close`, ensure that the :attr:`~io.IOBase.closed` +attribute is not set with a live exception. Patch by Zackery Spytz and +Serhiy Storchaka. + +.. + +.. bpo: 34087 +.. date: 2018-07-13-22-09-55 +.. nonce: I1Bxfc +.. section: Core and Builtins + +Fix buffer overflow while converting unicode to numeric values. + +.. + +.. bpo: 34080 +.. date: 2018-07-10-11-24-16 +.. nonce: 8t7PtO +.. section: Core and Builtins + +Fixed a memory leak in the compiler when it raised some uncommon errors +during tokenizing. + +.. + +.. bpo: 34066 +.. date: 2018-07-07-20-15-34 +.. nonce: y9vs6s +.. section: Core and Builtins + +Disabled interruption by Ctrl-C between calling ``open()`` and entering a +**with** block in ``with open()``. + +.. + +.. bpo: 34042 +.. date: 2018-07-05-15-51-29 +.. nonce: Gr9XUH +.. section: Core and Builtins + +Fix dict.copy() to maintain correct total refcount (as reported by +sys.gettotalrefcount()). + +.. + +.. bpo: 33418 +.. date: 2018-07-03-19-00-10 +.. nonce: cfGm3n +.. section: Core and Builtins + +Fix potential memory leak in function object when it creates reference +cycle. + +.. + +.. bpo: 33985 +.. date: 2018-06-27-18-56-41 +.. nonce: ILJ3Af +.. section: Core and Builtins + +Implement contextvars.ContextVar.name attribute. + +.. + +.. bpo: 33956 +.. date: 2018-06-25-20-42-44 +.. nonce: 1qoTwD +.. section: Core and Builtins + +Update vendored Expat library copy to version 2.2.5. + +.. + +.. bpo: 24596 +.. date: 2018-06-25-16-54-05 +.. nonce: Rkwova +.. section: Core and Builtins + +Decref the module object in :c:func:`PyRun_SimpleFileExFlags` before calling +:c:func:`PyErr_Print()`. Patch by Zackery Spytz. + +.. + +.. bpo: 33451 +.. date: 2018-06-23-15-32-02 +.. nonce: sWN-1l +.. section: Core and Builtins + +Close directly executed pyc files before calling ``PyEval_EvalCode()``. + +.. + +.. bpo: 1617161 +.. date: 2018-06-21-21-42-15 +.. nonce: tSo2yM +.. section: Core and Builtins + +The hash of :class:`BuiltinMethodType` instances (methods of built-in +classes) now depends on the hash of the identity of *__self__* instead of +its value. The hash and equality of :class:`ModuleType` and +:class:`MethodWrapperType` instances (methods of user-defined classes and +some methods of built-in classes like ``str.__add__``) now depend on the +hash and equality of the identity of *__self__* instead of its value. +:class:`MethodWrapperType` instances no longer support ordering. + +.. + +.. bpo: 33824 +.. date: 2018-06-15-19-39-06 +.. nonce: DfWHT3 +.. section: Core and Builtins + +Fix "LC_ALL=C python3.7 -V": reset properly the command line parser when the +encoding changes after reading the Python configuration. + +.. + +.. bpo: 33803 +.. date: 2018-06-07-20-18-38 +.. nonce: n-Nq6_ +.. section: Core and Builtins + +Fix a crash in hamt.c caused by enabling GC tracking for an object that +hadn't all of its fields set to NULL. + +.. + +.. bpo: 33738 +.. date: 2018-06-07-18-34-19 +.. nonce: ODZS7a +.. section: Core and Builtins + +Seven macro incompatibilities with the Limited API were fixed, and the +macros :c:func:`PyIter_Check`, :c:func:`PyIndex_Check` and +:c:func:`PyExceptionClass_Name` were added as functions. A script for +automatic macro checks was added. + +.. + +.. bpo: 33786 +.. date: 2018-06-06-23-24-40 +.. nonce: lBvT8z +.. section: Core and Builtins + +Fix asynchronous generators to handle GeneratorExit in athrow() correctly + +.. + +.. bpo: 30167 +.. date: 2018-06-05-15-49-02 +.. nonce: e956hA +.. section: Core and Builtins + +``PyRun_SimpleFileExFlags`` removes ``__cached__`` from module in addition +to ``__file__``. + +.. + +.. bpo: 33706 +.. date: 2018-05-31-14-50-04 +.. nonce: ztlH04 +.. section: Core and Builtins + +Fix a crash in Python initialization when parsing the command line options. +Thanks Christoph Gohlke for the bug report and the fix! + +.. + +.. bpo: 33597 +.. date: 2018-05-28-21-17-31 +.. nonce: r0ToM4 +.. section: Core and Builtins + +Reduce ``PyGC_Head`` size from 3 words to 2 words. + +.. + +.. bpo: 30654 +.. date: 2018-05-28-12-28-53 +.. nonce: 9fDJye +.. section: Core and Builtins + +Fixed reset of the SIGINT handler to SIG_DFL on interpreter shutdown even +when there was a custom handler set previously. Patch by Philipp Kerling. + +.. + +.. bpo: 33622 +.. date: 2018-05-23-20-46-14 +.. nonce: xPucO9 +.. section: Core and Builtins + +Fixed a leak when the garbage collector fails to add an object with the +``__del__`` method or referenced by it into the :data:`gc.garbage` list. +:c:func:`PyGC_Collect` can now be called when an exception is set and +preserves it. + +.. + +.. bpo: 33462 +.. date: 2018-05-23-17-18-02 +.. nonce: gurbpbrhe +.. section: Core and Builtins + +Make dict and dict views reversible. Patch by Rémi Lapeyre. + +.. + +.. bpo: 23722 +.. date: 2018-05-17-13-06-36 +.. nonce: xisqZk +.. section: Core and Builtins + +A :exc:`RuntimeError` is now raised when the custom metaclass doesn't +provide the ``__classcell__`` entry in the namespace passed to +``type.__new__``. A :exc:`DeprecationWarning` was emitted in Python +3.6--3.7. + +.. + +.. bpo: 33499 +.. date: 2018-05-15-10-48-47 +.. nonce: uBEc06 +.. section: Core and Builtins + +Add :envvar:`PYTHONPYCACHEPREFIX` environment variable and :option:`-X` +``pycache_prefix`` command-line option to set an alternate root directory +for writing module bytecode cache files. + +.. + +.. bpo: 25711 +.. date: 2018-05-14-18-54-03 +.. nonce: 9xfq-v +.. section: Core and Builtins + +The :mod:`zipimport` module has been rewritten in pure Python. + +.. + +.. bpo: 33509 +.. date: 2018-05-14-17-31-02 +.. nonce: pIUfTd +.. section: Core and Builtins + +Fix module_globals parameter of warnings.warn_explicit(): don't crash if +module_globals is not a dict. + +.. + +.. bpo: 31849 +.. date: 2018-05-14-11-00-00 +.. nonce: EmHaH4 +.. section: Core and Builtins + +Fix signed/unsigned comparison warning in pyhash.c. + +.. + +.. bpo: 33475 +.. date: 2018-05-13-01-26-18 +.. nonce: rI0y1U +.. section: Core and Builtins + +Fixed miscellaneous bugs in converting annotations to strings and optimized +parentheses in the string representation. + +.. + +.. bpo: 20104 +.. date: 2018-05-05-23-26-58 +.. nonce: tDBciE +.. section: Core and Builtins + +Added support for the `setpgroup`, `resetids`, `setsigmask`, `setsigdef` and +`scheduler` parameters of `posix_spawn`. Patch by Pablo Galindo. + +.. + +.. bpo: 33391 +.. date: 2018-05-02-08-36-03 +.. nonce: z4a7rb +.. section: Core and Builtins + +Fix a leak in set_symmetric_difference(). + +.. + +.. bpo: 33363 +.. date: 2018-04-26-22-48-28 +.. nonce: 8RCnN2 +.. section: Core and Builtins + +Raise a SyntaxError for ``async with`` and ``async for`` statements outside +of async functions. + +.. + +.. bpo: 28055 +.. date: 2018-04-25-20-44-42 +.. nonce: f49kfC +.. section: Core and Builtins + +Fix unaligned accesses in siphash24(). Patch by Rolf Eike Beer. + +.. + +.. bpo: 33128 +.. date: 2018-04-24-22-31-04 +.. nonce: g2yLuf +.. section: Core and Builtins + +Fix a bug that causes PathFinder to appear twice on sys.meta_path. Patch by +Pablo Galindo Salgado. + +.. + +.. bpo: 33331 +.. date: 2018-04-22-13-41-59 +.. nonce: s_DxdL +.. section: Core and Builtins + +Modules imported last are now cleared first at interpreter shutdown. + +.. + +.. bpo: 33312 +.. date: 2018-04-19-08-30-07 +.. nonce: mDe2iL +.. section: Core and Builtins + +Fixed clang ubsan (undefined behavior sanitizer) warnings in dictobject.c by +adjusting how the internal struct _dictkeysobject shared keys structure is +declared. + +.. + +.. bpo: 33305 +.. date: 2018-04-18-14-17-44 +.. nonce: 9z3dDH +.. section: Core and Builtins + +Improved syntax error messages for invalid numerical literals. + +.. + +.. bpo: 33306 +.. date: 2018-04-18-12-23-30 +.. nonce: tSM3cp +.. section: Core and Builtins + +Improved syntax error messages for unbalanced parentheses. + +.. + +.. bpo: 33234 +.. date: 2018-04-17-01-24-51 +.. nonce: l9IDtp +.. section: Core and Builtins + +The list constructor will pre-size and not over-allocate when the input +length is known. + +.. + +.. bpo: 33270 +.. date: 2018-04-14-13-12-50 +.. nonce: UmVV6i +.. section: Core and Builtins + +Intern the names for all anonymous code objects. Patch by Zackery Spytz. + +.. + +.. bpo: 30455 +.. date: 2018-04-14-11-02-57 +.. nonce: ANRwjo +.. section: Core and Builtins + +The C and Python code and the documentation related to tokens are now +generated from a single source file :file:`Grammar/Tokens`. + +.. + +.. bpo: 33176 +.. date: 2018-04-13-22-31-09 +.. nonce: PB9com +.. section: Core and Builtins + +Add a ``toreadonly()`` method to memoryviews. + +.. + +.. bpo: 33231 +.. date: 2018-04-05-22-20-44 +.. nonce: 3Jmo0q +.. section: Core and Builtins + +Fix potential memory leak in ``normalizestring()``. + +.. + +.. bpo: 33205 +.. date: 2018-04-03-00-58-41 +.. nonce: lk2F3r +.. section: Core and Builtins + +Change dict growth function from +``round_up_to_power_2(used*2+hashtable_size/2)`` to +``round_up_to_power_2(used*3)``. Previously, dict is shrinked only when +``used == 0``. Now dict has more chance to be shrinked. + +.. + +.. bpo: 29922 +.. date: 2018-04-03-00-30-25 +.. nonce: CdLuMl +.. section: Core and Builtins + +Improved error messages in 'async with' when ``__aenter__()`` or +``__aexit__()`` return non-awaitable object. + +.. + +.. bpo: 33199 +.. date: 2018-04-02-09-32-40 +.. nonce: TPnxQu +.. section: Core and Builtins + +Fix ``ma_version_tag`` in dict implementation is uninitialized when copying +from key-sharing dict. + +.. + +.. bpo: 33053 +.. date: 2018-03-25-19-49-06 +.. nonce: V3xlsH +.. section: Core and Builtins + +When using the -m switch, sys.path[0] is now explicitly expanded as the +*starting* working directory, rather than being left as the empty path +(which allows imports from the current working directory at the time of the +import) + +.. + +.. bpo: 33138 +.. date: 2018-03-25-19-25-14 +.. nonce: aSqudH +.. section: Core and Builtins + +Changed standard error message for non-pickleable and non-copyable types. It +now says "cannot pickle" instead of "can't pickle" or "cannot serialize". + +.. + +.. bpo: 33018 +.. date: 2018-03-22-23-09-06 +.. nonce: 0ncEJV +.. section: Core and Builtins + +Improve consistency of errors raised by ``issubclass()`` when called with a +non-class and an abstract base class as the first and second arguments, +respectively. Patch by Josh Bronson. + +.. + +.. bpo: 33083 +.. date: 2018-03-19-00-59-20 +.. nonce: Htztjl +.. section: Core and Builtins + +``math.factorial`` no longer accepts arguments that are not int-like. Patch +by Pablo Galindo. + +.. + +.. bpo: 33041 +.. date: 2018-03-18-13-56-14 +.. nonce: XwPhI2 +.. section: Core and Builtins + +Added new opcode :opcode:`END_ASYNC_FOR` and fixes the following issues: + +* Setting global :exc:`StopAsyncIteration` no longer breaks ``async for`` + loops. +* Jumping into an ``async for`` loop is now disabled. +* Jumping out of an ``async for`` loop no longer corrupts the stack. + +.. + +.. bpo: 25750 +.. date: 2018-03-14-21-42-17 +.. nonce: lxgkQz +.. section: Core and Builtins + +Fix rare Python crash due to bad refcounting in ``type_getattro()`` if a +descriptor deletes itself from the class. Patch by Jeroen Demeyer. + +.. + +.. bpo: 33041 +.. date: 2018-03-10-15-16-40 +.. nonce: -ak5Fk +.. section: Core and Builtins + +Fixed bytecode generation for "async for" with a complex target. A +StopAsyncIteration raised on assigning or unpacking will be now propagated +instead of stopping the iteration. + +.. + +.. bpo: 33026 +.. date: 2018-03-08-09-48-38 +.. nonce: QZA3Ba +.. section: Core and Builtins + +Fixed jumping out of "with" block by setting f_lineno. + +.. + +.. bpo: 33005 +.. date: 2018-03-06-12-19-19 +.. nonce: LP-V2U +.. section: Core and Builtins + +Fix a crash on fork when using a custom memory allocator (ex: using +PYTHONMALLOC env var). _PyGILState_Reinit() and _PyInterpreterState_Enable() +now use the default RAW memory allocator to allocate a new interpreters +mutex on fork. + +.. + +.. bpo: 32911 +.. date: 2018-02-27-20-57-00 +.. nonce: cmKfco +.. section: Core and Builtins + +Due to unexpected compatibility issues discovered during downstream beta +testing, reverted :issue:`29463`. ``docstring`` field is removed from +Module, ClassDef, FunctionDef, and AsyncFunctionDef ast nodes which was +added in 3.7a1. Docstring expression is restored as a first statement in +their body. Based on patch by Inada Naoki. + +.. + +.. bpo: 17288 +.. date: 2018-02-27-13-36-21 +.. nonce: Gdj24S +.. section: Core and Builtins + +Prevent jumps from 'return' and 'exception' trace events. + +.. + +.. bpo: 32946 +.. date: 2018-02-25-10-52-40 +.. nonce: Lo09rG +.. section: Core and Builtins + +Importing names from already imported module with "from ... import ..." is +now 30% faster if the module is not a package. + +.. + +.. bpo: 32932 +.. date: 2018-02-24-21-51-42 +.. nonce: 2cz31L +.. section: Core and Builtins + +Make error message more revealing when there are non-str objects in +``__all__``. + +.. + +.. bpo: 32925 +.. date: 2018-02-24-00-07-05 +.. nonce: e-7Ufh +.. section: Core and Builtins + +Optimized iterating and containing test for literal lists consisting of +non-constants: ``x in [a, b]`` and ``for x in [a, b]``. The case of all +constant elements already was optimized. + +.. + +.. bpo: 32889 +.. date: 2018-02-20-21-53-48 +.. nonce: J6eWy5 +.. section: Core and Builtins + +Update Valgrind suppression list to account for the rename of +``Py_ADDRESS_IN_RANG`` to ``address_in_range``. + +.. + +.. bpo: 32836 +.. date: 2018-02-14-12-35-47 +.. nonce: bThJnx +.. section: Core and Builtins + +Don't use temporary variables in cases of list/dict/set comprehensions + +.. + +.. bpo: 31356 +.. date: 2018-02-02-08-50-46 +.. nonce: MNwUOQ +.. section: Core and Builtins + +Remove the new API added in bpo-31356 (gc.ensure_disabled() context +manager). + +.. + +.. bpo: 32305 +.. date: 2018-02-01-10-56-41 +.. nonce: dkU9Qa +.. section: Core and Builtins + +For namespace packages, ensure that both ``__file__`` and +``__spec__.origin`` are set to None. + +.. + +.. bpo: 32303 +.. date: 2018-02-01-10-16-28 +.. nonce: VsvhSl +.. section: Core and Builtins + +Make sure ``__spec__.loader`` matches ``__loader__`` for namespace packages. + +.. + +.. bpo: 32711 +.. date: 2018-01-29-14-36-37 +.. nonce: 8hQFJP +.. section: Core and Builtins + +Fix the warning messages for Python/ast_unparse.c. Patch by Stéphane Wirtel + +.. + +.. bpo: 32583 +.. date: 2018-01-26-21-20-21 +.. nonce: Fh3fau +.. section: Core and Builtins + +Fix possible crashing in builtin Unicode decoders caused by write +out-of-bound errors when using customized decode error handlers. + +.. + +.. bpo: 32489 +.. date: 2018-01-03-23-12-43 +.. nonce: SDEPHB +.. section: Core and Builtins + +A :keyword:`continue` statement is now allowed in the :keyword:`finally` +clause. + +.. + +.. bpo: 17611 +.. date: 2017-12-24-19-48-59 +.. nonce: P85kWL +.. section: Core and Builtins + +Simplified the interpreter loop by moving the logic of unrolling the stack +of blocks into the compiler. The compiler emits now explicit instructions +for adjusting the stack of values and calling the cleaning up code for +:keyword:`break`, :keyword:`continue` and :keyword:`return`. + +Removed opcodes :opcode:`BREAK_LOOP`, :opcode:`CONTINUE_LOOP`, +:opcode:`SETUP_LOOP` and :opcode:`SETUP_EXCEPT`. Added new opcodes +:opcode:`ROT_FOUR`, :opcode:`BEGIN_FINALLY` and :opcode:`CALL_FINALLY` and +:opcode:`POP_FINALLY`. Changed the behavior of :opcode:`END_FINALLY` and +:opcode:`WITH_CLEANUP_START`. + +.. + +.. bpo: 32285 +.. date: 2017-12-12-13-43-13 +.. nonce: LzKSwz +.. section: Core and Builtins + +New function unicodedata.is_normalized, which can check whether a string is +in a specific normal form. + +.. + +.. bpo: 10544 +.. date: 2017-11-26-00-59-22 +.. nonce: fHOM3V +.. section: Core and Builtins + +Yield expressions are now disallowed in comprehensions and generator +expressions except the expression for the outermost iterable. + +.. + +.. bpo: 32117 +.. date: 2017-11-22-15-43-14 +.. nonce: -vloh8 +.. section: Core and Builtins + +Iterable unpacking is now allowed without parentheses in yield and return +statements, e.g. ``yield 1, 2, 3, *rest``. Thanks to David Cuthbert for the +change and Jordan Chapman for added tests. + +.. + +.. bpo: 31902 +.. date: 2017-10-30-12-44-50 +.. nonce: a07fa57 +.. section: Core and Builtins + +Fix the ``col_offset`` attribute for ast nodes ``ast.AsyncFor``, +``ast.AsyncFunctionDef``, and ``ast.AsyncWith``. Previously, ``col_offset`` +pointed to the keyword after ``async``. + +.. + +.. bpo: 25862 +.. date: 2017-10-07-10-13-15 +.. nonce: FPYBA5 +.. section: Core and Builtins + +Fix assertion failures in the ``tell()`` method of ``io.TextIOWrapper``. +Patch by Zackery Spytz. + +.. + +.. bpo: 21983 +.. date: 2017-10-02-21-02-14 +.. nonce: UoC319 +.. section: Core and Builtins + +Fix a crash in `ctypes.cast()` in case the type argument is a ctypes +structured data type. Patch by Eryk Sun and Oren Milman. + +.. + +.. bpo: 31577 +.. date: 2017-09-25-20-36-24 +.. nonce: jgYsSA +.. section: Core and Builtins + +Fix a crash in `os.utime()` in case of a bad ns argument. Patch by Oren +Milman. + +.. + +.. bpo: 29832 +.. date: 2017-09-12-08-11-01 +.. nonce: Kuf2M7 +.. section: Core and Builtins + +Remove references to 'getsockaddrarg' from various socket error messages. +Patch by Oren Milman. + +.. + +.. bpo: 35845 +.. date: 2019-02-02-00-04-01 +.. nonce: 1jx2wk +.. section: Library + +Add 'order' parameter to memoryview.tobytes(). + +.. + +.. bpo: 35864 +.. date: 2019-01-30-20-22-36 +.. nonce: ig9KnG +.. section: Library + +The _asdict() method for collections.namedtuple now returns a regular dict +instead of an OrderedDict. + +.. + +.. bpo: 35537 +.. date: 2019-01-29-17-24-52 +.. nonce: Q0ktFC +.. section: Library + +An ExitStack is now used internally within subprocess.Popen to clean up pipe +file handles. No behavior change in normal operation. But if closing one +handle were ever to cause an exception, the others will now be closed +instead of leaked. (patch by Giampaolo Rodola) + +.. + +.. bpo: 35847 +.. date: 2019-01-29-09-11-09 +.. nonce: eiSi4t +.. section: Library + +RISC-V needed the CTYPES_PASS_BY_REF_HACK. Fixes ctypes Structure +test_pass_by_value. + +.. + +.. bpo: 35813 +.. date: 2019-01-23-22-44-37 +.. nonce: Yobj-Y +.. section: Library + +Shared memory submodule added to multiprocessing to avoid need for +serialization between processes + +.. + +.. bpo: 35780 +.. date: 2019-01-19-17-01-43 +.. nonce: CLf7fT +.. section: Library + +Fix lru_cache() errors arising in recursive, reentrant, or multi-threaded +code. These errors could result in orphan links and in the cache being +trapped in a state with fewer than the specified maximum number of links. +Fix handling of negative maxsize which should have been treated as zero. Fix +errors in toggling the "full" status flag. Fix misordering of links when +errors are encountered. Sync-up the C code and pure Python code for the +space saving path in functions with a single positional argument. In this +common case, the space overhead of an lru cache entry is reduced by almost +half. Fix counting of cache misses. In error cases, the miss count was out +of sync with the actual number of times the underlying user function was +called. + +.. + +.. bpo: 35537 +.. date: 2019-01-18-13-44-13 +.. nonce: R1lbTl +.. section: Library + +:func:`os.posix_spawn` and :func:`os.posix_spawnp` now have a *setsid* +parameter. + +.. + +.. bpo: 23846 +.. date: 2019-01-15-13-31-30 +.. nonce: LT_qL8 +.. section: Library + +:class:`asyncio.ProactorEventLoop` now catches and logs send errors when the +self-pipe is full. + +.. + +.. bpo: 34323 +.. date: 2019-01-14-17-34-36 +.. nonce: CRErrt +.. section: Library + +:mod:`asyncio`: Enhance ``IocpProactor.close()`` log: wait 1 second before +the first log, then log every second. Log also the number of seconds since +``close()`` was called. + +.. + +.. bpo: 35674 +.. date: 2019-01-14-14-13-08 +.. nonce: kamWqz +.. section: Library + +Add a new :func:`os.posix_spawnp` function. Patch by Joannah Nanjekye. + +.. + +.. bpo: 35733 +.. date: 2019-01-13-18-42-41 +.. nonce: eFfLiv +.. section: Library + +``ast.Constant(boolean)`` no longer an instance of :class:`ast.Num`. Patch +by Anthony Sottile. + +.. + +.. bpo: 35726 +.. date: 2019-01-13-01-33-00 +.. nonce: dasdas +.. section: Library + +QueueHandler.prepare() now makes a copy of the record before modifying and +enqueueing it, to avoid affecting other handlers in the chain. + +.. + +.. bpo: 35719 +.. date: 2019-01-11-20-21-59 +.. nonce: qyRcpE +.. section: Library + +Sped up multi-argument :mod:`math` functions atan2(), copysign(), +remainder() and hypot() by 1.3--2.5 times. + +.. + +.. bpo: 35717 +.. date: 2019-01-11-17-56-15 +.. nonce: 6TDTB_ +.. section: Library + +Fix KeyError exception raised when using enums and compile. Patch +contributed by Rémi Lapeyre. + +.. + +.. bpo: 35699 +.. date: 2019-01-11-07-09-25 +.. nonce: VDiENF +.. section: Library + +Fixed detection of Visual Studio Build Tools 2017 in distutils + +.. + +.. bpo: 32710 +.. date: 2019-01-10-15-55-10 +.. nonce: KwECPu +.. section: Library + +Fix memory leaks in asyncio ProactorEventLoop on overlapped operation +failure. + +.. + +.. bpo: 35702 +.. date: 2019-01-10-14-03-12 +.. nonce: _ct_0H +.. section: Library + +The :const:`time.CLOCK_UPTIME_RAW` constant is now available for macOS 10.12. + +.. + +.. bpo: 32710 +.. date: 2019-01-08-14-00-52 +.. nonce: Sn5Ujj +.. section: Library + +Fix a memory leak in asyncio in the ProactorEventLoop when ``ReadFile()`` or +``WSASend()`` overlapped operation fail immediately: release the internal +buffer. + +.. + +.. bpo: 35682 +.. date: 2019-01-08-01-54-02 +.. nonce: KDM9lk +.. section: Library + +Fix ``asyncio.ProactorEventLoop.sendfile()``: don't attempt to set the +result of an internal future if it's already done. + +.. + +.. bpo: 35283 +.. date: 2019-01-07-17-17-16 +.. nonce: WClosC +.. section: Library + +Add a deprecated warning for the :meth:`threading.Thread.isAlive` method. +Patch by Donghee Na. + +.. + +.. bpo: 35664 +.. date: 2019-01-04-22-18-25 +.. nonce: Z-Gyyj +.. section: Library + +Improve operator.itemgetter() performance by 33% with optimized argument +handling and with adding a fast path for the common case of a single +non-negative integer index into a tuple (which is the typical use case in +the standard library). + +.. + +.. bpo: 35643 +.. date: 2019-01-02-20-04-49 +.. nonce: DaMiaV +.. section: Library + +Fixed a SyntaxWarning: invalid escape sequence in Modules/_sha3/cleanup.py. +Patch by Mickaël Schoentgen. + +.. + +.. bpo: 35619 +.. date: 2018-12-30-19-50-36 +.. nonce: ZRXdhy +.. section: Library + +Improved support of custom data descriptors in :func:`help` and +:mod:`pydoc`. + +.. + +.. bpo: 28503 +.. date: 2018-12-30-14-56-33 +.. nonce: V4kNN3 +.. section: Library + +The `crypt` module now internally uses the `crypt_r()` library function +instead of `crypt()` when available. + +.. + +.. bpo: 35614 +.. date: 2018-12-30-01-10-50 +.. nonce: cnkM4f +.. section: Library + +Fixed help() on metaclasses. Patch by Sanyam Khurana. + +.. + +.. bpo: 35568 +.. date: 2018-12-27-19-23-00 +.. nonce: PutiOC +.. section: Library + +Expose ``raise(signum)`` as `raise_signal` + +.. + +.. bpo: 35588 +.. date: 2018-12-26-10-55-59 +.. nonce: PSR6Ez +.. section: Library + +The floor division and modulo operations and the :func:`divmod` function on +:class:`fractions.Fraction` types are 2--4x faster. Patch by Stefan Behnel. + +.. + +.. bpo: 35585 +.. date: 2018-12-26-02-28-00 +.. nonce: Lkzd3Z +.. section: Library + +Speed-up building enums by value, e.g. http.HTTPStatus(200). + +.. + +.. bpo: 30561 +.. date: 2018-12-23-22-27-59 +.. nonce: PSRQ2w +.. section: Library + +random.gammavariate(1.0, beta) now computes the same result as +random.expovariate(1.0 / beta). This synchronizes the two algorithms and +eliminates some idiosyncrasies in the old implementation. It does however +produce a difference stream of random variables than it used to. + +.. + +.. bpo: 35537 +.. date: 2018-12-20-16-24-51 +.. nonce: z4E7aA +.. section: Library + +The :mod:`subprocess` module can now use the :func:`os.posix_spawn` function +in some cases for better performance. + +.. + +.. bpo: 35526 +.. date: 2018-12-18-21-12-25 +.. nonce: fYvo6H +.. section: Library + +Delaying the 'joke' of barry_as_FLUFL.mandatory to Python version 4.0 + +.. + +.. bpo: 35523 +.. date: 2018-12-18-13-52-13 +.. nonce: SkoMno +.. section: Library + +Remove :mod:`ctypes` callback workaround: no longer create a callback at +startup. Avoid SELinux alert on ``import ctypes`` and ``import uuid``. + +.. + +.. bpo: 31784 +.. date: 2018-12-17-11-43-11 +.. nonce: W0gDjC +.. section: Library + +:func:`uuid.uuid1` now calls :func:`time.time_ns` rather than +``int(time.time() * 1e9)``. + +.. + +.. bpo: 35513 +.. date: 2018-12-16-23-28-49 +.. nonce: pn-Zh3 +.. section: Library + +:class:`~unittest.runner.TextTestRunner` of :mod:`unittest.runner` now uses +:func:`time.perf_counter` rather than :func:`time.time` to measure the +execution time of a test: :func:`time.time` can go backwards, whereas +:func:`time.perf_counter` is monotonic. + +.. + +.. bpo: 35502 +.. date: 2018-12-14-23-56-48 +.. nonce: gLHuFS +.. section: Library + +Fixed reference leaks in :class:`xml.etree.ElementTree.TreeBuilder` in case +of unfinished building of the tree (in particular when an error was raised +during parsing XML). + +.. + +.. bpo: 35348 +.. date: 2018-12-14-13-27-45 +.. nonce: u3Y2an +.. section: Library + +Make :func:`platform.architecture` parsing of ``file`` command output more +reliable: add the ``-b`` option to the ``file`` command to omit the +filename, force the usage of the C locale, and search also the "shared +object" pattern. + +.. + +.. bpo: 35491 +.. date: 2018-12-14-12-12-15 +.. nonce: jHsNOU +.. section: Library + +:mod:`multiprocessing`: Add ``Pool.__repr__()`` and enhance +``BaseProcess.__repr__()`` (add pid and parent pid) to ease debugging. Pool +state constant values are now strings instead of integers, for example +``RUN`` value becomes ``'RUN'`` instead of ``0``. + +.. + +.. bpo: 35477 +.. date: 2018-12-13-00-10-51 +.. nonce: hHyy06 +.. section: Library + +:meth:`multiprocessing.Pool.__enter__` now fails if the pool is not running: +``with pool:`` fails if used more than once. + +.. + +.. bpo: 31446 +.. date: 2018-12-12-22-52-34 +.. nonce: l--Fjz +.. section: Library + +Copy command line that was passed to CreateProcessW since this function can +change the content of the input buffer. + +.. + +.. bpo: 35471 +.. date: 2018-12-12-16-25-21 +.. nonce: SK8jFC +.. section: Library + +Python 2.4 dropped MacOS 9 support. The macpath module was deprecated in +Python 3.7. The module is now removed. + +.. + +.. bpo: 23057 +.. date: 2018-12-12-16-24-55 +.. nonce: OB4Z1Y +.. section: Library + +Unblock Proactor event loop when keyboard interrupt is received on Windows + +.. + +.. bpo: 35052 +.. date: 2018-12-10-09-48-27 +.. nonce: xE1ymg +.. section: Library + +Fix xml.dom.minidom cloneNode() on a document with an entity: pass the +correct arguments to the user data handler of an entity. + +.. + +.. bpo: 20239 +.. date: 2018-12-09-21-35-49 +.. nonce: V4mWBL +.. section: Library + +Allow repeated assignment deletion of :class:`unittest.mock.Mock` +attributes. Patch by Pablo Galindo. + +.. + +.. bpo: 17185 +.. date: 2018-12-09-17-04-15 +.. nonce: SfSCJF +.. section: Library + +Set ``__signature__`` on mock for :mod:`inspect` to get signature. Patch by +Karthikeyan Singaravelan. + +.. + +.. bpo: 35445 +.. date: 2018-12-09-14-35-49 +.. nonce: LjvtsC +.. section: Library + +Memory errors during creating posix.environ no longer ignored. + +.. + +.. bpo: 35415 +.. date: 2018-12-06-14-44-21 +.. nonce: -HoK3d +.. section: Library + +Validate fileno= argument to socket.socket(). + +.. + +.. bpo: 35424 +.. date: 2018-12-06-02-02-28 +.. nonce: gXxOJU +.. section: Library + +:class:`multiprocessing.Pool` destructor now emits :exc:`ResourceWarning` if +the pool is still running. + +.. + +.. bpo: 35330 +.. date: 2018-12-06-00-43-13 +.. nonce: abB4BN +.. section: Library + +When a :class:`Mock` instance was used to wrap an object, if `side_effect` +is used in one of the mocks of it methods, don't call the original +implementation and return the result of using the side effect the same way +that it is done with return_value. + +.. + +.. bpo: 35346 +.. date: 2018-12-05-22-52-21 +.. nonce: Okm9-S +.. section: Library + +Drop Mac OS 9 and Rhapsody support from the :mod:`platform` module. Rhapsody +last release was in 2000. Mac OS 9 last release was in 2001. + +.. + +.. bpo: 10496 +.. date: 2018-12-05-17-42-49 +.. nonce: laV_IE +.. section: Library + +:func:`~distutils.utils.check_environ` of ``distutils.utils`` now catches +:exc:`KeyError` on calling :func:`pwd.getpwuid`: don't create the ``HOME`` +environment variable in this case. + +.. + +.. bpo: 10496 +.. date: 2018-12-05-13-37-39 +.. nonce: VH-1Lp +.. section: Library + +:func:`posixpath.expanduser` now returns the input *path* unchanged if the +``HOME`` environment variable is not set and the current user has no home +directory (if the current user identifier doesn't exist in the password +database). This change fix the :mod:`site` module if the current user +doesn't exist in the password database (if the user has no home directory). + +.. + +.. bpo: 35389 +.. date: 2018-12-04-12-46-05 +.. nonce: CTZ9iA +.. section: Library + +:func:`platform.libc_ver` now uses ``os.confstr('CS_GNU_LIBC_VERSION')`` if +available and the *executable* parameter is not set. + +.. + +.. bpo: 35394 +.. date: 2018-12-04-12-17-08 +.. nonce: fuTVDk +.. section: Library + +Add empty slots to asyncio abstract protocols. + +.. + +.. bpo: 35310 +.. date: 2018-12-03-19-45-00 +.. nonce: 9k28gR +.. section: Library + +Fix a bug in :func:`select.select` where, in some cases, the file descriptor +sequences were returned unmodified after a signal interruption, even though +the file descriptors might not be ready yet. :func:`select.select` will now +always return empty lists if a timeout has occurred. Patch by Oran Avraham. + +.. + +.. bpo: 35380 +.. date: 2018-12-03-14-41-11 +.. nonce: SdRF9l +.. section: Library + +Enable TCP_NODELAY on Windows for proactor asyncio event loop. + +.. + +.. bpo: 35341 +.. date: 2018-12-02-13-50-52 +.. nonce: 32E8T_ +.. section: Library + +Add generic version of ``collections.OrderedDict`` to the ``typing`` module. +Patch by Ismo Toijala. + +.. + +.. bpo: 35371 +.. date: 2018-12-01-13-44-12 +.. nonce: fTAwlX +.. section: Library + +Fixed possible crash in ``os.utime()`` on Windows when pass incorrect +arguments. + +.. + +.. bpo: 35346 +.. date: 2018-11-29-12-42-13 +.. nonce: OmTY5c +.. section: Library + +:func:`platform.uname` now redirects ``stderr`` to :data:`os.devnull` when +running external programs like ``cmd /c ver``. + +.. + +.. bpo: 35066 +.. date: 2018-11-29-09-38-40 +.. nonce: Nwej2s +.. section: Library + +Previously, calling the strftime() method on a datetime object with a +trailing '%' in the format string would result in an exception. However, +this only occurred when the datetime C module was being used; the python +implementation did not match this behavior. Datetime is now PEP-399 +compliant, and will not throw an exception on a trailing '%'. + +.. + +.. bpo: 35345 +.. date: 2018-11-29-00-55-33 +.. nonce: vepCSJ +.. section: Library + +The function `platform.popen` has been removed, it was deprecated since +Python 3.3: use :func:`os.popen` instead. + +.. + +.. bpo: 35344 +.. date: 2018-11-29-00-23-25 +.. nonce: 4QOPJQ +.. section: Library + +On macOS, :func:`platform.platform` now uses :func:`platform.mac_ver`, if it +returns a non-empty release string, to get the macOS version rather than the +darwin version. + +.. + +.. bpo: 35312 +.. date: 2018-11-25-20-05-33 +.. nonce: wbw0zO +.. section: Library + +Make ``lib2to3.pgen2.parse.ParseError`` round-trip pickle-able. Patch by +Anthony Sottile. + +.. + +.. bpo: 35308 +.. date: 2018-11-24-10-33-42 +.. nonce: 9--2iy +.. section: Library + +Fix regression in ``webbrowser`` where default browsers may be preferred +over browsers in the ``BROWSER`` environment variable. + +.. + +.. bpo: 24746 +.. date: 2018-11-22-15-22-56 +.. nonce: eSLKBE +.. section: Library + +Avoid stripping trailing whitespace in doctest fancy diff. Original patch by +R. David Murray & Jairo Trad. Enhanced by Sanyam Khurana. + +.. + +.. bpo: 28604 +.. date: 2018-11-20-13-34-01 +.. nonce: iiih5h +.. section: Library + +:func:`locale.localeconv` now sets temporarily the ``LC_CTYPE`` locale to +the ``LC_MONETARY`` locale if the two locales are different and monetary +strings are non-ASCII. This temporary change affects other threads. + +.. + +.. bpo: 35277 +.. date: 2018-11-19-07-22-04 +.. nonce: dsD-2E +.. section: Library + +Update ensurepip to install pip 18.1 and setuptools 40.6.2. + +.. + +.. bpo: 24209 +.. date: 2018-11-18-18-44-40 +.. nonce: p3YWOf +.. section: Library + +Adds IPv6 support when invoking http.server directly. + +.. + +.. bpo: 35226 +.. date: 2018-11-15-07-14-32 +.. nonce: wJPEEe +.. section: Library + +Recursively check arguments when testing for equality of +:class:`unittest.mock.call` objects and add note that tracking of parameters +used to create ancestors of mocks in ``mock_calls`` is not possible. + +.. + +.. bpo: 29564 +.. date: 2018-11-12-17-40-04 +.. nonce: SFNBT5 +.. section: Library + +The warnings module now suggests to enable tracemalloc if the source is +specified, the tracemalloc module is available, but tracemalloc is not +tracing memory allocations. + +.. + +.. bpo: 35189 +.. date: 2018-11-09-13-35-36 +.. nonce: gog-sl +.. section: Library + +Modify the following fnctl function to retry if interrupted by a signal +(EINTR): flock, lockf, fnctl + +.. + +.. bpo: 30064 +.. date: 2018-11-09-01-18-51 +.. nonce: IF5mH6 +.. section: Library + +Use add_done_callback() in sock_* asyncio API to unsubscribe reader/writer +early on calcellation. + +.. + +.. bpo: 35186 +.. date: 2018-11-08-14-22-29 +.. nonce: 5m22Mj +.. section: Library + +Removed the "built with" comment added when ``setup.py upload`` is used with +either ``bdist_rpm`` or ``bdist_dumb``. + +.. + +.. bpo: 35152 +.. date: 2018-11-03-10-12-04 +.. nonce: xpqskp +.. section: Library + +Allow sending more than 2 GB at once on a multiprocessing connection on +non-Windows systems. + +.. + +.. bpo: 35062 +.. date: 2018-10-29-23-09-24 +.. nonce: dQS1ng +.. section: Library + +Fix incorrect parsing of :class:`_io.IncrementalNewlineDecoder`'s +*translate* argument. + +.. + +.. bpo: 35065 +.. date: 2018-10-29-10-18-31 +.. nonce: CulMN8 +.. section: Library + +Remove `StreamReaderProtocol._untrack_reader`. The call to `_untrack_reader` +is currently performed too soon, causing the protocol to forget about the +reader before `connection_lost` can run and feed the EOF to the reader. + +.. + +.. bpo: 34160 +.. date: 2018-10-27-21-11-42 +.. nonce: UzyPZf +.. section: Library + +ElementTree and minidom now preserve the attribute order specified by the +user. + +.. + +.. bpo: 35079 +.. date: 2018-10-26-22-53-16 +.. nonce: Tm5jvF +.. section: Library + +Improve difflib.SequenceManager.get_matching_blocks doc by adding +'non-overlapping' and changing '!=' to '<'. + +.. + +.. bpo: 33710 +.. date: 2018-10-26-21-12-55 +.. nonce: Q5oXc6 +.. section: Library + +Deprecated ``l*gettext()`` functions and methods in the :mod:`gettext` +module. They return encoded bytes instead of Unicode strings and are +artifacts from Python 2 times. Also deprecated functions and methods related +to setting the charset for ``l*gettext()`` functions and methods. + +.. + +.. bpo: 35017 +.. date: 2018-10-26-00-11-21 +.. nonce: 6Ez4Cv +.. section: Library + +:meth:`socketserver.BaseServer.serve_forever` now exits immediately if it's +:meth:`~socketserver.BaseServer.shutdown` method is called while it is +polling for new events. + +.. + +.. bpo: 35024 +.. date: 2018-10-25-15-43-32 +.. nonce: ltSrtr +.. section: Library + +`importlib` no longer logs `wrote <bytecode path>` redundantly after +`(created|could not create) <bytecode path>` is already logged. Patch by +Quentin Agren. + +.. + +.. bpo: 35047 +.. date: 2018-10-25-09-59-00 +.. nonce: abbaa +.. section: Library + +``unittest.mock`` now includes mock calls in exception messages if +``assert_not_called``, ``assert_called_once``, or +``assert_called_once_with`` fails. Patch by Petter Strandmark. + +.. + +.. bpo: 31047 +.. date: 2018-10-25-09-37-03 +.. nonce: kBbX8r +.. section: Library + +Fix ``ntpath.abspath`` regression where it didn't remove a trailing +separator on Windows. Patch by Tim Graham. + +.. + +.. bpo: 35053 +.. date: 2018-10-23-18-58-12 +.. nonce: G82qwh +.. section: Library + +tracemalloc now tries to update the traceback when an object is reused from +a "free list" (optimization for faster object creation, used by the builtin +list type for example). + +.. + +.. bpo: 31553 +.. date: 2018-10-23-14-46-47 +.. nonce: JxRkAW +.. section: Library + +Add the --json-lines option to json.tool. Patch by hongweipeng. + +.. + +.. bpo: 34794 +.. date: 2018-10-21-14-53-19 +.. nonce: yt3R4- +.. section: Library + +Fixed a leak in Tkinter when pass the Python wrapper around Tcl_Obj back to +Tcl/Tk. + +.. + +.. bpo: 34909 +.. date: 2018-10-20-00-29-43 +.. nonce: Ew_8DC +.. section: Library + +Enum: fix grandchildren subclassing when parent mixed with concrete data +types. + +.. + +.. bpo: 35022 +.. date: 2018-10-18-17-57-28 +.. nonce: KeEF4T +.. section: Library + +:class:`unittest.mock.MagicMock` now supports the ``__fspath__`` method +(from :class:`os.PathLike`). + +.. + +.. bpo: 35008 +.. date: 2018-10-17-11-54-04 +.. nonce: dotef_ +.. section: Library + +Fixed references leaks when call the ``__setstate__()`` method of +:class:`xml.etree.ElementTree.Element` in the C implementation for already +initialized element. + +.. + +.. bpo: 23420 +.. date: 2018-10-17-11-00-00 +.. nonce: Lq74Uu +.. section: Library + +Verify the value for the parameter '-s' of the cProfile CLI. Patch by Robert +Kuska + +.. + +.. bpo: 33947 +.. date: 2018-10-17-02-15-23 +.. nonce: SRuq3T +.. section: Library + +dataclasses now handle recursive reprs without raising RecursionError. + +.. + +.. bpo: 34890 +.. date: 2018-10-15-23-10-41 +.. nonce: 77E770 +.. section: Library + +Make :func:`inspect.iscoroutinefunction`, +:func:`inspect.isgeneratorfunction` and :func:`inspect.isasyncgenfunction` +work with :func:`functools.partial`. Patch by Pablo Galindo. + +.. + +.. bpo: 34521 +.. date: 2018-10-13-19-15-23 +.. nonce: YPaiTK +.. section: Library + +Use :func:`socket.CMSG_SPACE` to calculate ancillary data size instead of +:func:`socket.CMSG_LEN` in :func:`multiprocessing.reduction.recvfds` as +:rfc:`3542` requires the use of the former for portable applications. + +.. + +.. bpo: 31522 +.. date: 2018-10-13-18-16-20 +.. nonce: rWBb43 +.. section: Library + +The `mailbox.mbox.get_string` function *from_* parameter can now +successfully be set to a non-default value. + +.. + +.. bpo: 34970 +.. date: 2018-10-13-11-14-13 +.. nonce: SrJTY7 +.. section: Library + +Protect tasks weak set manipulation in ``asyncio.all_tasks()`` + +.. + +.. bpo: 34969 +.. date: 2018-10-13-07-46-50 +.. nonce: Mfnhjb +.. section: Library + +gzip: Add --fast, --best on the gzip CLI, these parameters will be used for +the fast compression method (quick) or the best method compress (slower, but +smaller file). Also, change the default compression level to 6 (tradeoff). + +.. + +.. bpo: 16965 +.. date: 2018-10-12-20-30-42 +.. nonce: xo5LAr +.. section: Library + +The :term:`2to3` :2to3fixer:`execfile` fixer now opens the file with mode +``'rb'``. Patch by Zackery Spytz. + +.. + +.. bpo: 34966 +.. date: 2018-10-12-18-57-52 +.. nonce: WZeBHO +.. section: Library + +:mod:`pydoc` now supports aliases not only to methods defined in the end +class, but also to inherited methods. The docstring is not duplicated for +aliases. + +.. + +.. bpo: 34926 +.. date: 2018-10-10-00-22-57 +.. nonce: CA0rqd +.. section: Library + +:meth:`mimetypes.MimeTypes.guess_type` now accepts :term:`path-like object` +in addition to url strings. Patch by Mayank Asthana. + +.. + +.. bpo: 23831 +.. date: 2018-10-09-15-44-04 +.. nonce: 2CL7lL +.. section: Library + +Add ``moveto()`` method to the ``tkinter.Canvas`` widget. Patch by Juliette +Monsel. + +.. + +.. bpo: 34941 +.. date: 2018-10-09-14-42-16 +.. nonce: 1Q5QKv +.. section: Library + +Methods ``find()``, ``findtext()`` and ``findall()`` of the ``Element`` +class in the :mod:`xml.etree.ElementTree` module are now able to find +children which are instances of ``Element`` subclasses. + +.. + +.. bpo: 32680 +.. date: 2018-10-09-14-25-36 +.. nonce: z2FbOp +.. section: Library + +:class:`smtplib.SMTP` objects now always have a `sock` attribute present + +.. + +.. bpo: 34769 +.. date: 2018-10-09-11-01-16 +.. nonce: cSkkZt +.. section: Library + +Fix for async generators not finalizing when event loop is in debug mode and +garbage collector runs in another thread. + +.. + +.. bpo: 34936 +.. date: 2018-10-08-21-05-11 +.. nonce: 3tRqdq +.. section: Library + +Fix ``TclError`` in ``tkinter.Spinbox.selection_element()``. Patch by +Juliette Monsel. + +.. + +.. bpo: 34829 +.. date: 2018-10-08-16-04-36 +.. nonce: B7v7D0 +.. section: Library + +Add methods ``selection_from``, ``selection_range``, ``selection_present`` +and ``selection_to`` to the ``tkinter.Spinbox`` for consistency with the +``tkinter.Entry`` widget. Patch by Juliette Monsel. + +.. + +.. bpo: 34911 +.. date: 2018-10-08-15-22-02 +.. nonce: hCy0Fv +.. section: Library + +Added *secure_protocols* argument to *http.cookiejar.DefaultCookiePolicy* to +allow for tweaking of protocols and also to add support by default for +*wss*, the secure websocket protocol. + +.. + +.. bpo: 34922 +.. date: 2018-10-07-21-18-52 +.. nonce: 37IdsA +.. section: Library + +Fixed integer overflow in the :meth:`~hashlib.shake.digest()` and +:meth:`~hashlib.shake.hexdigest()` methods for the SHAKE algorithm in the +:mod:`hashlib` module. + +.. + +.. bpo: 34925 +.. date: 2018-10-07-20-37-02 +.. nonce: KlkZ-Y +.. section: Library + +25% speedup in argument parsing for the functions in the bisect module. + +.. + +.. bpo: 34900 +.. date: 2018-10-05-05-55-53 +.. nonce: 8RNiFu +.. section: Library + +Fixed :meth:`unittest.TestCase.debug` when used to call test methods with +subtests. Patch by Bruno Oliveira. + +.. + +.. bpo: 34844 +.. date: 2018-10-04-20-44-45 +.. nonce: Hnuxav +.. section: Library + +logging.Formatter enhancement - Ensure styles and fmt matches in +logging.Formatter - Added validate method in each format style class: +StrFormatStyle, PercentStyle, StringTemplateStyle. - This method is called +in the constructor of logging.Formatter class - Also re-raise the KeyError +in the format method of each style class, so it would a bit clear that it's +an error with the invalid format fields. + +.. + +.. bpo: 34897 +.. date: 2018-10-04-20-25-35 +.. nonce: rNE2Cy +.. section: Library + +Adjust test.support.missing_compiler_executable check so that a nominal +command name of "" is ignored. Patch by Michael Felt. + +.. + +.. bpo: 34871 +.. date: 2018-10-04-18-46-54 +.. nonce: t3X-dB +.. section: Library + +Fix inspect module polluted ``sys.modules`` when parsing +``__text_signature__`` of callable. + +.. + +.. bpo: 34898 +.. date: 2018-10-04-17-23-43 +.. nonce: Wo2PoJ +.. section: Library + +Add `mtime` argument to `gzip.compress` for reproducible output. Patch by +Guo Ci Teo. + +.. + +.. bpo: 28441 +.. date: 2018-10-04-15-53-14 +.. nonce: 2sQENe +.. section: Library + +On Cygwin and MinGW, ensure that ``sys.executable`` always includes the full +filename in the path, including the ``.exe`` suffix (unless it is a symbolic +link). + +.. + +.. bpo: 34866 +.. date: 2018-10-03-11-07-28 +.. nonce: ML6KpJ +.. section: Library + +Adding ``max_num_fields`` to ``cgi.FieldStorage`` to make DOS attacks harder +by limiting the number of ``MiniFieldStorage`` objects created by +``FieldStorage``. + +.. + +.. bpo: 34711 +.. date: 2018-10-03-09-25-02 +.. nonce: HeOmKR +.. section: Library + +http.server ensures it reports HTTPStatus.NOT_FOUND when the local path ends +with "/" and is not a directory, even if the underlying OS (e.g. AIX) +accepts such paths as a valid file reference. Patch by Michael Felt. + +.. + +.. bpo: 34872 +.. date: 2018-10-02-19-36-34 +.. nonce: yWZRhI +.. section: Library + +Fix self-cancellation in C implementation of asyncio.Task + +.. + +.. bpo: 34849 +.. date: 2018-09-30-08-08-14 +.. nonce: NXK9Ff +.. section: Library + +Don't log waiting for ``selector.select`` in asyncio loop iteration. The +waiting is pretty normal for any asyncio program, logging its time just adds +a noise to logs without any useful information provided. + +.. + +.. bpo: 34022 +.. date: 2018-09-27-13-14-15 +.. nonce: E2cl0r +.. section: Library + +The :envvar:`SOURCE_DATE_EPOCH` environment variable no longer overrides the +value of the *invalidation_mode* argument to :func:`py_compile.compile`, and +determines its default value instead. + +.. + +.. bpo: 34819 +.. date: 2018-09-27-09-45-00 +.. nonce: 9ZaFyO +.. section: Library + +Use a monotonic clock to compute timeouts in :meth:`Executor.map` and +:func:`as_completed`, in order to prevent timeouts from deviating when the +system clock is adjusted. + +.. + +.. bpo: 34758 +.. date: 2018-09-26-14-09-34 +.. nonce: bRBfAi +.. section: Library + +Add .wasm -> application/wasm to list of recognized file types and content +type headers + +.. + +.. bpo: 34789 +.. date: 2018-09-25-15-48-50 +.. nonce: rPOEj5 +.. section: Library + +:func:`xml.sax.make_parser` now accepts any iterable as its *parser_list* +argument. Patch by Andrés Delfino. + +.. + +.. bpo: 34334 +.. date: 2018-09-25-08-42-34 +.. nonce: rSPBW9 +.. section: Library + +In :class:`QueueHandler`, clear `exc_text` from :class:`LogRecord` to +prevent traceback from being written twice. + +.. + +.. bpo: 34687 +.. date: 2018-09-24-17-14-57 +.. nonce: Fku_8S +.. section: Library + +On Windows, asyncio now uses ProactorEventLoop, instead of +SelectorEventLoop, by default. + +.. + +.. bpo: 5950 +.. date: 2018-09-24-14-21-58 +.. nonce: xH0ekQ +.. section: Library + +Support reading zip files with archive comments in :mod:`zipimport`. + +.. + +.. bpo: 32892 +.. date: 2018-09-20-17-35-05 +.. nonce: TOUBdg +.. section: Library + +The parser now represents all constants as :class:`ast.Constant` instead of +using specific constant AST types (``Num``, ``Str``, ``Bytes``, +``NameConstant`` and ``Ellipsis``). These classes are considered deprecated +and will be removed in future Python versions. + +.. + +.. bpo: 34728 +.. date: 2018-09-20-16-55-43 +.. nonce: CUE8LU +.. section: Library + +Add deprecation warning when `loop` is used in methods: `asyncio.sleep`, +`asyncio.wait` and `asyncio.wait_for`. + +.. + +.. bpo: 34738 +.. date: 2018-09-19-16-51-04 +.. nonce: Pr3-iG +.. section: Library + +ZIP files created by ``distutils`` will now include entries for +directories. + +.. + +.. bpo: 34659 +.. date: 2018-09-16-17-04-16 +.. nonce: CWemzH +.. section: Library + +Add an optional *initial* argument to itertools.accumulate(). + +.. + +.. bpo: 29577 +.. date: 2018-09-14-20-00-47 +.. nonce: RzwKFD +.. section: Library + +Support multiple mixin classes when creating Enums. + +.. + +.. bpo: 34670 +.. date: 2018-09-14-14-29-45 +.. nonce: 17XwGB +.. section: Library + +Add SSLContext.post_handshake_auth and +SSLSocket.verify_client_post_handshake for TLS 1.3's post handshake +authentication feature. + +.. + +.. bpo: 32718 +.. date: 2018-09-14-12-38-49 +.. nonce: ICYQbt +.. section: Library + +The Activate.ps1 script from venv works with PowerShell Core 6.1 and is now +available under all operating systems. + +.. + +.. bpo: 31177 +.. date: 2018-09-14-10-38-18 +.. nonce: Sv91TN +.. section: Library + +Fix bug that prevented using :meth:`reset_mock +<unittest.mock.Mock.reset_mock>` on mock instances with deleted attributes + +.. + +.. bpo: 34672 +.. date: 2018-09-13-21-04-23 +.. nonce: BYuKKS +.. section: Library + +Add a workaround, so the ``'Z'`` :func:`time.strftime` specifier on the musl +C library can work in some cases. + +.. + +.. bpo: 34666 +.. date: 2018-09-13-11-49-52 +.. nonce: 3uLtWv +.. section: Library + +Implement ``asyncio.StreamWriter.awrite`` and +``asyncio.StreamWriter.aclose()`` coroutines. Methods are needed for +providing a consistent stream API with control flow switched on by default. + +.. + +.. bpo: 6721 +.. date: 2018-09-13-10-09-19 +.. nonce: ZUL_F3 +.. section: Library + +Acquire the logging module's commonly used internal locks while fork()ing to +avoid deadlocks in the child process. + +.. + +.. bpo: 34658 +.. date: 2018-09-13-03-59-43 +.. nonce: ykZ-ia +.. section: Library + +Fix a rare interpreter unhandled exception state SystemError only seen when +using subprocess with a preexec_fn while an after_parent handler has been +registered with os.register_at_fork and the fork system call fails. + +.. + +.. bpo: 34652 +.. date: 2018-09-12-14-46-51 +.. nonce: Rt1m1b +.. section: Library + +Ensure :func:`os.lchmod` is never defined on Linux. + +.. + +.. bpo: 34638 +.. date: 2018-09-12-10-33-44 +.. nonce: xaeZX5 +.. section: Library + +Store a weak reference to stream reader to break strong references loop +between reader and protocol. It allows to detect and close the socket if +the stream is deleted (garbage collected) without ``close()`` call. + +.. + +.. bpo: 34536 +.. date: 2018-09-11-15-49-09 +.. nonce: 3IPIH5 +.. section: Library + +`Enum._missing_`: raise `ValueError` if None returned and `TypeError` if +non-member is returned. + +.. + +.. bpo: 34636 +.. date: 2018-09-11-15-04-05 +.. nonce: capCmt +.. section: Library + +Speed up re scanning of many non-matching characters for \s \w and \d within +bytes objects. (microoptimization) + +.. + +.. bpo: 24412 +.. date: 2018-09-11-10-51-16 +.. nonce: i-F_E5 +.. section: Library + +Add :func:`~unittest.addModuleCleanup()` and +:meth:`~unittest.TestCase.addClassCleanup()` to unittest to support cleanups +for :func:`~unittest.setUpModule()` and +:meth:`~unittest.TestCase.setUpClass()`. Patch by Lisa Roach. + +.. + +.. bpo: 34630 +.. date: 2018-09-11-10-00-53 +.. nonce: YbqUS6 +.. section: Library + +Don't log SSL certificate errors in asyncio code (connection error logging +is skipped already). + +.. + +.. bpo: 32490 +.. date: 2018-09-11-01-25-35 +.. nonce: ROIDO1 +.. section: Library + +Prevent filename duplication in :mod:`subprocess` exception messages. Patch +by Zackery Spytz. + +.. + +.. bpo: 34363 +.. date: 2018-09-10-21-09-34 +.. nonce: YuSb0T +.. section: Library + +dataclasses.asdict() and .astuple() now handle namedtuples correctly. + +.. + +.. bpo: 34625 +.. date: 2018-09-10-17-46-51 +.. nonce: D2YfDz +.. section: Library + +Update vendorized expat library version to 2.2.6. + +.. + +.. bpo: 32270 +.. date: 2018-09-10-14-15-53 +.. nonce: wSJjuD +.. section: Library + +The subprocess module no longer mistakenly closes redirected fds even when +they were in pass_fds when outside of the default {0, 1, 2} set. + +.. + +.. bpo: 34622 +.. date: 2018-09-10-13-04-40 +.. nonce: tpv_rN +.. section: Library + +Create a dedicated ``asyncio.CancelledError``, ``asyncio.InvalidStateError`` +and ``asyncio.TimeoutError`` exception classes. Inherit them from +corresponding exceptions from ``concurrent.futures`` package. Extract +``asyncio`` exceptions into a separate file. + +.. + +.. bpo: 34610 +.. date: 2018-09-08-12-57-07 +.. nonce: wmoP5j +.. section: Library + +Fixed iterator of :class:`multiprocessing.managers.DictProxy`. + +.. + +.. bpo: 34421 +.. date: 2018-09-07-10-57-00 +.. nonce: AKJISD +.. section: Library + +Fix distutils logging for non-ASCII strings. This caused installation +issues on Windows. + +.. + +.. bpo: 34604 +.. date: 2018-09-07-10-16-34 +.. nonce: xL7-kG +.. section: Library + +Fix possible mojibake in the error message of `pwd.getpwnam` and +`grp.getgrnam` using string representation because of invisible characters +or trailing whitespaces. Patch by William Grzybowski. + +.. + +.. bpo: 30977 +.. date: 2018-09-06-10-07-46 +.. nonce: bP661V +.. section: Library + +Make uuid.UUID use ``__slots__`` to reduce its memory footprint. Based on +original patch by Wouter Bolsterlee. + +.. + +.. bpo: 34574 +.. date: 2018-09-04-09-32-54 +.. nonce: X4RwYI +.. section: Library + +OrderedDict iterators are not exhausted during pickling anymore. Patch by +Sergey Fedoseev. + +.. + +.. bpo: 8110 +.. date: 2018-09-03-23-54-35 +.. nonce: FExWI_ +.. section: Library + +Refactored :mod:`subprocess` to check for Windows-specific modules rather +than ``sys.platform == 'win32'``. + +.. + +.. bpo: 34530 +.. date: 2018-09-03-23-23-32 +.. nonce: h_Xsu7 +.. section: Library + +``distutils.spawn.find_executable()`` now falls back on :data:`os.defpath` +if the ``PATH`` environment variable is not set. + +.. + +.. bpo: 34563 +.. date: 2018-09-01-20-43-10 +.. nonce: 7NQK7B +.. section: Library + +On Windows, fix multiprocessing.Connection for very large read: fix +_winapi.PeekNamedPipe() and _winapi.ReadFile() for read larger than INT_MAX +(usually ``2**31-1``). + +.. + +.. bpo: 34558 +.. date: 2018-08-31-19-26-55 +.. nonce: MHv582 +.. section: Library + +Correct typo in Lib/ctypes/_aix.py + +.. + +.. bpo: 34282 +.. date: 2018-08-31-06-28-03 +.. nonce: ztyXH8 +.. section: Library + +Move ``Enum._convert`` to ``EnumMeta._convert_`` and fix enum members +getting shadowed by parent attributes. + +.. + +.. bpo: 22872 +.. date: 2018-08-30-14-44-11 +.. nonce: NhIaZ9 +.. section: Library + +When the queue is closed, :exc:`ValueError` is now raised by +:meth:`multiprocessing.Queue.put` and :meth:`multiprocessing.Queue.get` +instead of :exc:`AssertionError` and :exc:`OSError`, respectively. Patch by +Zackery Spytz. + +.. + +.. bpo: 34515 +.. date: 2018-08-27-16-01-22 +.. nonce: S0Irst +.. section: Library + +Fix parsing non-ASCII identifiers in :mod:`lib2to3.pgen2.tokenize` (PEP +3131). + +.. + +.. bpo: 13312 +.. date: 2018-08-24-17-31-27 +.. nonce: 6hA5La +.. section: Library + +Avoids a possible integer underflow (undefined behavior) in the time +module's year handling code when passed a very low negative year value. + +.. + +.. bpo: 34472 +.. date: 2018-08-23-09-25-08 +.. nonce: cGyYrO +.. section: Library + +Improved compatibility for streamed files in :mod:`zipfile`. Previously an +optional signature was not being written and certain ZIP applications were +not supported. Patch by Silas Sewell. + +.. + +.. bpo: 34454 +.. date: 2018-08-22-21-59-08 +.. nonce: z7uG4b +.. section: Library + +Fix the .fromisoformat() methods of datetime types crashing when given +unicode with non-UTF-8-encodable code points. Specifically, +datetime.fromisoformat() now accepts surrogate unicode code points used as +the separator. Report and tests by Alexey Izbyshev, patch by Paul Ganssle. + +.. + +.. bpo: 6700 +.. date: 2018-08-22-17-43-52 +.. nonce: hp7C4B +.. section: Library + +Fix inspect.getsourcelines for module level frames/tracebacks. Patch by +Vladimir Matveev. + +.. + +.. bpo: 34171 +.. date: 2018-08-21-00-29-01 +.. nonce: 6LkWav +.. section: Library + +Running the :mod:`trace` module no longer creates the ``trace.cover`` file. + +.. + +.. bpo: 34441 +.. date: 2018-08-20-16-48-32 +.. nonce: _zx9lU +.. section: Library + +Fix crash when an ``ABC``-derived class with invalid ``__subclasses__`` is +passed as the second argument to :func:`issubclass()`. Patch by Alexey +Izbyshev. + +.. + +.. bpo: 34427 +.. date: 2018-08-20-13-53-10 +.. nonce: tMRQjl +.. section: Library + +Fix infinite loop in ``a.extend(a)`` for ``MutableSequence`` subclasses. + +.. + +.. bpo: 34412 +.. date: 2018-08-16-19-07-05 +.. nonce: NF5Jm2 +.. section: Library + +Make :func:`signal.strsignal` work on HP-UX. Patch by Michael Osipov. + +.. + +.. bpo: 20849 +.. date: 2018-08-16-16-47-15 +.. nonce: YWJECC +.. section: Library + +shutil.copytree now accepts a new ``dirs_exist_ok`` keyword argument. Patch +by Josh Bronson. + +.. + +.. bpo: 31715 +.. date: 2018-08-15-16-22-30 +.. nonce: Iw8jS8 +.. section: Library + +Associate ``.mjs`` file extension with ``application/javascript`` MIME Type. + +.. + +.. bpo: 34384 +.. date: 2018-08-12-08-43-21 +.. nonce: yjofCv +.. section: Library + +:func:`os.readlink` now accepts :term:`path-like <path-like object>` and +:class:`bytes` objects on Windows. + +.. + +.. bpo: 22602 +.. date: 2018-08-12-00-14-54 +.. nonce: ybG9K8 +.. section: Library + +The UTF-7 decoder now raises :exc:`UnicodeDecodeError` for ill-formed +sequences starting with "+" (as specified in RFC 2152). Patch by Zackery +Spytz. + +.. + +.. bpo: 2122 +.. date: 2018-08-06-21-47-03 +.. nonce: GWdmrm +.. section: Library + +The :meth:`mmap.flush() <mmap.mmap.flush>` method now returns ``None`` on +success, raises an exception on error under all platforms. + +.. + +.. bpo: 34341 +.. date: 2018-08-06-11-01-18 +.. nonce: E0b9p2 +.. section: Library + +Appending to the ZIP archive with the ZIP64 extension no longer grows the +size of extra fields of existing entries. + +.. + +.. bpo: 34333 +.. date: 2018-08-04-00-06-28 +.. nonce: 5NHG93 +.. section: Library + +Fix %-formatting in :meth:`pathlib.PurePath.with_suffix` when formatting an +error message. + +.. + +.. bpo: 18540 +.. date: 2018-08-02-21-28-38 +.. nonce: AryoYY +.. section: Library + +The :class:`imaplib.IMAP4` and :class:`imaplib.IMAP4_SSL` classes now +resolve to the local host IP correctly when the default value of *host* +parameter (``''``) is used. + +.. + +.. bpo: 26502 +.. date: 2018-08-02-20-39-32 +.. nonce: eGXr_k +.. section: Library + +Implement ``traceback.FrameSummary.__len__()`` method to preserve +compatibility with the old tuple API. + +.. + +.. bpo: 34318 +.. date: 2018-08-02-14-43-42 +.. nonce: GneiXs +.. section: Library + +:func:`~unittest.TestCase.assertRaises`, +:func:`~unittest.TestCase.assertRaisesRegex`, +:func:`~unittest.TestCase.assertWarns` and +:func:`~unittest.TestCase.assertWarnsRegex` no longer success if the passed +callable is None. They no longer ignore unknown keyword arguments in the +context manager mode. A DeprecationWarning was raised in these cases since +Python 3.5. + +.. + +.. bpo: 9372 +.. date: 2018-08-01-21-26-17 +.. nonce: V8Ou3K +.. section: Library + +Deprecate :meth:`__getitem__` methods of +:class:`xml.dom.pulldom.DOMEventStream`, :class:`wsgiref.util.FileWrapper` +and :class:`fileinput.FileInput`. + +.. + +.. bpo: 33613 +.. date: 2018-07-31-23-33-06 +.. nonce: Cdnt0i +.. section: Library + +Fix a race condition in ``multiprocessing.semaphore_tracker`` when the +tracker receives SIGINT before it can register signal handlers for ignoring +it. + +.. + +.. bpo: 34248 +.. date: 2018-07-31-23-00-09 +.. nonce: 5U6wwc +.. section: Library + +Report filename in the exception raised when the database file cannot be +opened by :func:`dbm.gnu.open` and :func:`dbm.ndbm.open` due to OS-related +error. Patch by Zsolt Cserna. + +.. + +.. bpo: 33089 +.. date: 2018-07-29-21-53-15 +.. nonce: hxbp3g +.. section: Library + +Add math.dist() to compute the Euclidean distance between two points. + +.. + +.. bpo: 34246 +.. date: 2018-07-29-15-25-15 +.. nonce: xiKq-Q +.. section: Library + +:meth:`smtplib.SMTP.send_message` no longer modifies the content of the +*mail_options* argument. Patch by Pablo S. Blum de Aguiar. + +.. + +.. bpo: 31047 +.. date: 2018-07-29-14-12-23 +.. nonce: FSarLs +.. section: Library + +Fix ``ntpath.abspath`` for invalid paths on windows. Patch by Franz +Woellert. + +.. + +.. bpo: 32321 +.. date: 2018-07-29-13-50-32 +.. nonce: hDoNKC +.. section: Library + +Add pure Python fallback for functools.reduce. Patch by Robert Wright. + +.. + +.. bpo: 34270 +.. date: 2018-07-29-11-32-56 +.. nonce: aL6P-3 +.. section: Library + +The default asyncio task class now always has a name which can be get or set +using two new methods (:meth:`~asyncio.Task.get_name()` and +:meth:`~asyncio.Task.set_name`) and is visible in the :func:`repr` output. +An initial name can also be set using the new ``name`` keyword argument to +:func:`asyncio.create_task` or the +:meth:`~asyncio.AbstractEventLoop.create_task` method of the event loop. If +no initial name is set, the default Task implementation generates a name +like ``Task-1`` using a monotonic counter. + +.. + +.. bpo: 34263 +.. date: 2018-07-28-17-00-36 +.. nonce: zUfRsu +.. section: Library + +asyncio's event loop will not pass timeouts longer than one day to +epoll/select etc. + +.. + +.. bpo: 34035 +.. date: 2018-07-28-15-00-31 +.. nonce: 75nW0H +.. section: Library + +Fix several AttributeError in zipfile seek() methods. Patch by Mickaël +Schoentgen. + +.. + +.. bpo: 32215 +.. date: 2018-07-28-12-08-53 +.. nonce: EU68SY +.. section: Library + +Fix performance regression in :mod:`sqlite3` when a DML statement appeared +in a different line than the rest of the SQL query. + +.. + +.. bpo: 34075 +.. date: 2018-07-28-11-49-21 +.. nonce: 9u1bO- +.. section: Library + +Deprecate passing non-ThreadPoolExecutor instances to +:meth:`AbstractEventLoop.set_default_executor`. + +.. + +.. bpo: 34251 +.. date: 2018-07-28-11-47-10 +.. nonce: q3elQ6 +.. section: Library + +Restore ``msilib.Win64`` to preserve backwards compatibility since it's +already used by ``distutils``' ``bdist_msi`` command. + +.. + +.. bpo: 19891 +.. date: 2018-07-26-08-45-49 +.. nonce: Y-3IiB +.. section: Library + +Ignore errors caused by missing / non-writable homedir while writing history +during exit of an interactive session. Patch by Anthony Sottile. + +.. + +.. bpo: 33089 +.. date: 2018-07-25-22-38-54 +.. nonce: C3CB7e +.. section: Library + +Enhanced math.hypot() to support more than two dimensions. + +.. + +.. bpo: 34228 +.. date: 2018-07-25-19-02-39 +.. nonce: 0Ibztw +.. section: Library + +tracemalloc: PYTHONTRACEMALLOC=0 environment variable and -X tracemalloc=0 +command line option are now allowed to disable explicitly tracemalloc at +startup. + +.. + +.. bpo: 13041 +.. date: 2018-07-25-12-08-48 +.. nonce: lNmgDz +.. section: Library + +Use :func:`shutil.get_terminal_size` to calculate the terminal width +correctly in the ``argparse.HelpFormatter`` class. Initial patch by Zbyszek +Jędrzejewski-Szmek. + +.. + +.. bpo: 34213 +.. date: 2018-07-25-00-40-14 +.. nonce: O15MgP +.. section: Library + +Allow frozen dataclasses to have a field named "object". Previously this +conflicted with an internal use of "object". + +.. + +.. bpo: 34052 +.. date: 2018-07-24-16-37-40 +.. nonce: VbbFAE +.. section: Library + +:meth:`sqlite3.Connection.create_aggregate`, +:meth:`sqlite3.Connection.create_function`, +:meth:`sqlite3.Connection.set_authorizer`, +:meth:`sqlite3.Connection.set_progress_handler` methods raises TypeError +when unhashable objects are passed as callable. These methods now don't pass +such objects to SQLite API. Previous behavior could lead to segfaults. Patch +by Sergey Fedoseev. + +.. + +.. bpo: 34197 +.. date: 2018-07-23-14-12-28 +.. nonce: 7yFSP5 +.. section: Library + +Attributes *skipinitialspace*, *doublequote* and *strict* of the *dialect* +attribute of the :mod:`csv` reader are now :class:`bool` instances instead +of integers 0 or 1. + +.. + +.. bpo: 32788 +.. date: 2018-07-23-12-20-02 +.. nonce: R2jSiK +.. section: Library + +Errors other than :exc:`TypeError` raised in methods ``__adapt__()`` and +``__conform__()`` in the :mod:`sqlite3` module are now propagated to the +user. + +.. + +.. bpo: 21446 +.. date: 2018-07-22-09-05-01 +.. nonce: w6g7tn +.. section: Library + +The :2to3fixer:`reload` fixer now uses :func:`importlib.reload` instead of +deprecated :func:`!imp.reload`. + +.. + +.. bpo: 940286 +.. date: 2018-07-22-07-59-32 +.. nonce: NZTzyc +.. section: Library + +pydoc's ``Helper.showtopic()`` method now prints the cross references of a +topic correctly. + +.. + +.. bpo: 34164 +.. date: 2018-07-20-18-06-00 +.. nonce: fNfT-q +.. section: Library + +:func:`base64.b32decode` could raise UnboundLocalError or OverflowError for +incorrect padding. Now it always raises :exc:`base64.Error` in these cases. + +.. + +.. bpo: 33729 +.. date: 2018-07-20-09-11-05 +.. nonce: sO6iTb +.. section: Library + +Fixed issues with arguments parsing in :mod:`hashlib`. + +.. + +.. bpo: 34097 +.. date: 2018-07-13-13-42-10 +.. nonce: F5Dk5o +.. section: Library + +ZipFile can zip files older than 1980-01-01 and newer than 2107-12-31 using +a new ``strict_timestamps`` parameter at the cost of setting the timestamp +to the limit. + +.. + +.. bpo: 34108 +.. date: 2018-07-13-08-44-52 +.. nonce: RjobUC +.. section: Library + +Remove extraneous CR in 2to3 refactor. + +.. + +.. bpo: 34070 +.. date: 2018-07-11-20-51-20 +.. nonce: WpmFAu +.. section: Library + +Make sure to only check if the handle is a tty, when opening a file with +``buffering=-1``. + +.. + +.. bpo: 27494 +.. date: 2018-07-11-10-03-21 +.. nonce: 04OWkW +.. section: Library + +Reverted :issue:`27494`. 2to3 rejects now a trailing comma in generator +expressions. + +.. + +.. bpo: 33967 +.. date: 2018-07-08-18-49-41 +.. nonce: lhaAez +.. section: Library + +functools.singledispatch now raises TypeError instead of IndexError when no +positional arguments are passed. + +.. + +.. bpo: 34041 +.. date: 2018-07-06-15-06-32 +.. nonce: 0zrKLh +.. section: Library + +Add the parameter *deterministic* to the +:meth:`sqlite3.Connection.create_function` method. Patch by Sergey Fedoseev. + +.. + +.. bpo: 34056 +.. date: 2018-07-05-22-45-46 +.. nonce: 86isrU +.. section: Library + +Ensure the loader shim created by ``imp.load_module`` always returns bytes +from its ``get_data()`` function. This fixes using ``imp.load_module`` with +:pep:`552` hash-based pycs. + +.. + +.. bpo: 34054 +.. date: 2018-07-05-18-37-05 +.. nonce: nWRS6M +.. section: Library + +The multiprocessing module now uses the monotonic clock +:func:`time.monotonic` instead of the system clock :func:`time.time` to +implement timeout. + +.. + +.. bpo: 34043 +.. date: 2018-07-04-21-14-35 +.. nonce: 0YJNq9 +.. section: Library + +Optimize tarfile uncompress performance about 15% when gzip is used. + +.. + +.. bpo: 34044 +.. date: 2018-07-04-17-14-26 +.. nonce: KWAu4y +.. section: Library + +``subprocess.Popen`` now copies the *startupinfo* argument to leave it +unchanged: it will modify the copy, so that the same ``STARTUPINFO`` object +can be used multiple times. + +.. + +.. bpo: 34010 +.. date: 2018-07-04-07-36-53 +.. nonce: VNDkde +.. section: Library + +Fixed a performance regression for reading streams with tarfile. The +buffered read should use a list, instead of appending to a bytes object. + +.. + +.. bpo: 34019 +.. date: 2018-07-02-05-59-11 +.. nonce: ZXJIife +.. section: Library + +webbrowser: Correct the arguments passed to Opera Browser when opening a new +URL using the ``webbrowser`` module. Patch by Bumsik Kim. + +.. + +.. bpo: 34003 +.. date: 2018-06-29-13-05-01 +.. nonce: Iu831h +.. section: Library + +csv.DictReader now creates dicts instead of OrderedDicts. Patch by Michael +Selik. + +.. + +.. bpo: 33978 +.. date: 2018-06-29-12-23-34 +.. nonce: y4csIw +.. section: Library + +Closed existing logging handlers before reconfiguration via fileConfig and +dictConfig. Patch by Karthikeyan Singaravelan. + +.. + +.. bpo: 14117 +.. date: 2018-06-29-00-31-36 +.. nonce: 3nvDuR +.. section: Library + +Make minor tweaks to turtledemo. The 'wikipedia' example is now 'rosette', +describing what it draws. The 'penrose' print output is reduced. The'1024' +output of 'tree' is eliminated. + +.. + +.. bpo: 33974 +.. date: 2018-06-28-14-56-44 +.. nonce: SA8nNP +.. section: Library + +Fixed passing lists and tuples of strings containing special characters +``"``, ``\``, ``{``, ``}`` and ``\n`` as options to :mod:`~tkinter.ttk` +widgets. + +.. + +.. bpo: 27500 +.. date: 2018-06-28-13-00-12 +.. nonce: _s1gZ5 +.. section: Library + +Fix getaddrinfo to resolve IPv6 addresses correctly. + +.. + +.. bpo: 24567 +.. date: 2018-06-27-00-31-30 +.. nonce: FuePyY +.. section: Library + +Improve random.choices() to handle subnormal input weights that could +occasionally trigger an IndexError. + +.. + +.. bpo: 33871 +.. date: 2018-06-26-19-03-56 +.. nonce: XhlrGU +.. section: Library + +Fixed integer overflow in :func:`os.readv`, :func:`os.writev`, +:func:`os.preadv` and :func:`os.pwritev` and in :func:`os.sendfile` with +*headers* or *trailers* arguments (on BSD-based OSes and macOS). + +.. + +.. bpo: 25007 +.. date: 2018-06-26-16-55-59 +.. nonce: 6LQWOF +.. section: Library + +Add :func:`copy.copy` and :func:`copy.deepcopy` support to zlib compressors +and decompressors. Patch by Zackery Spytz. + +.. + +.. bpo: 33929 +.. date: 2018-06-26-02-09-18 +.. nonce: OcCLah +.. section: Library + +multiprocessing: Fix a race condition in Popen of +multiprocessing.popen_spawn_win32. The child process now duplicates the read +end of pipe instead of "stealing" it. Previously, the read end of pipe was +"stolen" by the child process, but it leaked a handle if the child process +had been terminated before it could steal the handle from the parent +process. + +.. + +.. bpo: 33899 +.. date: 2018-06-24-01-57-14 +.. nonce: IaOcAr +.. section: Library + +Tokenize module now implicitly emits a NEWLINE when provided with input that +does not have a trailing new line. This behavior now matches what the C +tokenizer does internally. Contributed by Ammar Askar. + +.. + +.. bpo: 33897 +.. date: 2018-06-23-18-09-28 +.. nonce: Hu0yvt +.. section: Library + +Added a 'force' keyword argument to logging.basicConfig(). + +.. + +.. bpo: 33695 +.. date: 2018-06-23-12-47-37 +.. nonce: seRTxh +.. section: Library + +:func:`shutil.copytree` uses :func:`os.scandir` function and all copy +functions depending from it use cached :func:`os.stat` values. The speedup +for copying a directory with 8000 files is around +9% on Linux, +20% on +Windows and + 30% on a Windows SMB share. Also the number of :func:`os.stat` +syscalls is reduced by 38% making :func:`shutil.copytree` especially faster +on network filesystems. (Contributed by Giampaolo Rodola' in +:issue:`33695`.) + +.. + +.. bpo: 33916 +.. date: 2018-06-21-11-35-47 +.. nonce: cZgPCD +.. section: Library + +bz2 and lzma: When Decompressor.__init__() is called twice, free the old +lock to not leak memory. + +.. + +.. bpo: 32568 +.. date: 2018-06-21-09-33-02 +.. nonce: f_meGY +.. section: Library + +Make select.epoll() and its documentation consistent regarding *sizehint* +and *flags*. + +.. + +.. bpo: 33833 +.. date: 2018-06-17-11-46-20 +.. nonce: RnEqvM +.. section: Library + +Fixed bug in asyncio where ProactorSocketTransport logs AssertionError if +force closed during write. + +.. + +.. bpo: 33663 +.. date: 2018-06-17-10-48-03 +.. nonce: sUuGmq +.. section: Library + +Convert content length to string before putting to header. + +.. + +.. bpo: 33721 +.. date: 2018-06-14-17-53-30 +.. nonce: 8i9_9A +.. section: Library + +:mod:`os.path` functions that return a boolean result like +:func:`~os.path.exists`, :func:`~os.path.lexists`, :func:`~os.path.isdir`, +:func:`~os.path.isfile`, :func:`~os.path.islink`, and +:func:`~os.path.ismount`, and :mod:`pathlib.Path` methods that return a +boolean result like :meth:`~pathlib.Path.exists()`, +:meth:`~pathlib.Path.is_dir()`, :meth:`~pathlib.Path.is_file()`, +:meth:`~pathlib.Path.is_mount()`, :meth:`~pathlib.Path.is_symlink()`, +:meth:`~pathlib.Path.is_block_device()`, +:meth:`~pathlib.Path.is_char_device()`, :meth:`~pathlib.Path.is_fifo()`, +:meth:`~pathlib.Path.is_socket()` now return ``False`` instead of raising +:exc:`ValueError` or its subclasses :exc:`UnicodeEncodeError` and +:exc:`UnicodeDecodeError` for paths that contain characters or bytes +unrepresentable at the OS level. + +.. + +.. bpo: 26544 +.. date: 2018-06-13-20-33-29 +.. nonce: hQ1oMt +.. section: Library + +Fixed implementation of :func:`platform.libc_ver`. It almost always returned +version '2.9' for glibc. + +.. + +.. bpo: 33843 +.. date: 2018-06-12-18-59-16 +.. nonce: qVAK8g +.. section: Library + +Remove deprecated ``cgi.escape``, ``cgi.parse_qs`` and ``cgi.parse_qsl``. + +.. + +.. bpo: 33842 +.. date: 2018-06-12-18-34-54 +.. nonce: RZXSGu +.. section: Library + +Remove ``tarfile.filemode`` which is deprecated since Python 3.3. + +.. + +.. bpo: 30167 +.. date: 2018-06-10-19-29-17 +.. nonce: G5EgC5 +.. section: Library + +Prevent site.main() exception if PYTHONSTARTUP is set. Patch by Steve Weber. + +.. + +.. bpo: 33805 +.. date: 2018-06-10-15-14-17 +.. nonce: 5LAz5a +.. section: Library + +Improve error message of dataclasses.replace() when an InitVar is not +specified + +.. + +.. bpo: 33687 +.. date: 2018-06-10-14-08-52 +.. nonce: 1zZdnA +.. section: Library + +Fix the call to ``os.chmod()`` for ``uu.decode()`` if a mode is given or +decoded. Patch by Timo Furrer. + +.. + +.. bpo: 33812 +.. date: 2018-06-10-13-26-02 +.. nonce: frGAOr +.. section: Library + +Datetime instance d with non-None tzinfo, but with d.tzinfo.utcoffset(d) +returning None is now treated as naive by the astimezone() method. + +.. + +.. bpo: 32108 +.. date: 2018-06-10-12-15-26 +.. nonce: iEkvh0 +.. section: Library + +In configparser, don't clear section when it is assigned to itself. + +.. + +.. bpo: 27397 +.. date: 2018-06-10-09-43-54 +.. nonce: 0_fFQR +.. section: Library + +Make email module properly handle invalid-length base64 strings. + +.. + +.. bpo: 33578 +.. date: 2018-06-08-23-55-34 +.. nonce: 7oSsjG +.. section: Library + +Implement multibyte encoder/decoder state methods + +.. + +.. bpo: 30805 +.. date: 2018-06-08-17-34-16 +.. nonce: 3qCWa0 +.. section: Library + +Avoid race condition with debug logging + +.. + +.. bpo: 33476 +.. date: 2018-06-08-00-29-40 +.. nonce: R0Bhlj +.. section: Library + +Fix _header_value_parser.py when address group is missing final ';'. +Contributed by Enrique Perez-Terron + +.. + +.. bpo: 33694 +.. date: 2018-06-07-23-51-00 +.. nonce: F1zIR1 +.. section: Library + +asyncio: Fix a race condition causing data loss on +pause_reading()/resume_reading() when using the ProactorEventLoop. + +.. + +.. bpo: 32493 +.. date: 2018-06-07-18-55-35 +.. nonce: 1Bte62 +.. section: Library + +Correct test for ``uuid_enc_be`` availability in ``configure.ac``. Patch by +Michael Felt. + +.. + +.. bpo: 33792 +.. date: 2018-06-07-12-38-12 +.. nonce: 3aKG7u +.. section: Library + +Add asyncio.WindowsSelectorEventLoopPolicy and +asyncio.WindowsProactorEventLoopPolicy. + +.. + +.. bpo: 33274 +.. date: 2018-06-06-22-01-33 +.. nonce: teYqv8 +.. section: Library + +W3C DOM Level 1 specifies return value of Element.removeAttributeNode() as +"The Attr node that was removed." xml.dom.minidom now complies with this +requirement. + +.. + +.. bpo: 33778 +.. date: 2018-06-05-20-22-30 +.. nonce: _tSAS6 +.. section: Library + +Update ``unicodedata``'s database to Unicode version 11.0.0. + +.. + +.. bpo: 33165 +.. date: 2018-06-05-12-43-25 +.. nonce: 9TIsVf +.. section: Library + +Added a stacklevel parameter to logging calls to allow use of wrapper/helper +functions for logging APIs. + +.. + +.. bpo: 33770 +.. date: 2018-06-05-11-29-26 +.. nonce: oBhxxw +.. section: Library + +improve base64 exception message for encoded inputs of invalid length + +.. + +.. bpo: 33769 +.. date: 2018-06-04-13-46-39 +.. nonce: D_pxYz +.. section: Library + +asyncio/start_tls: Fix error message; cancel callbacks in case of an +unhandled error; mark SSLTransport as closed if it is aborted. + +.. + +.. bpo: 33767 +.. date: 2018-06-03-22-41-59 +.. nonce: 2e82g3 +.. section: Library + +The concatenation (``+``) and repetition (``*``) sequence operations now +raise :exc:`TypeError` instead of :exc:`SystemError` when performed on +:class:`mmap.mmap` objects. Patch by Zackery Spytz. + +.. + +.. bpo: 33734 +.. date: 2018-06-01-10-55-48 +.. nonce: x1W9x0 +.. section: Library + +asyncio/ssl: Fix AttributeError, increase default handshake timeout + +.. + +.. bpo: 31014 +.. date: 2018-05-31-06-48-55 +.. nonce: SNY681 +.. section: Library + +Fixed creating a controller for :mod:`webbrowser` when a user specifies a +path to an entry in the BROWSER environment variable. Based on patch by +John Still. + +.. + +.. bpo: 2504 +.. date: 2018-05-30-16-00-06 +.. nonce: BynUvU +.. section: Library + +Add gettext.pgettext() and variants. + +.. + +.. bpo: 33197 +.. date: 2018-05-30-00-26-05 +.. nonce: XkE2kL +.. section: Library + +Add description property for _ParameterKind + +.. + +.. bpo: 32751 +.. date: 2018-05-29-15-32-18 +.. nonce: oBTqr7 +.. section: Library + +When cancelling the task due to a timeout, :meth:`asyncio.wait_for` will now +wait until the cancellation is complete. + +.. + +.. bpo: 32684 +.. date: 2018-05-29-12-51-18 +.. nonce: ZEIism +.. section: Library + +Fix gather to propagate cancellation of itself even with return_exceptions. + +.. + +.. bpo: 33654 +.. date: 2018-05-29-01-13-39 +.. nonce: sa81Si +.. section: Library + +Support protocol type switching in SSLTransport.set_protocol(). + +.. + +.. bpo: 33674 +.. date: 2018-05-29-00-37-56 +.. nonce: 2IkGhL +.. section: Library + +Pause the transport as early as possible to further reduce the risk of +data_received() being called before connection_made(). + +.. + +.. bpo: 33671 +.. date: 2018-05-28-23-25-17 +.. nonce: GIdKKi +.. section: Library + +:func:`shutil.copyfile`, :func:`shutil.copy`, :func:`shutil.copy2`, +:func:`shutil.copytree` and :func:`shutil.move` use platform-specific +fast-copy syscalls on Linux and macOS in order to copy the file +more efficiently. On Windows :func:`shutil.copyfile` uses a bigger default +buffer size (1 MiB instead of 16 KiB) and a :func:`memoryview`-based variant +of :func:`shutil.copyfileobj` is used. The speedup for copying a 512MiB file +is about +26% on Linux, +50% on macOS and +40% on Windows. Also, much less +CPU cycles are consumed. (Contributed by Giampaolo Rodola' in +:issue:`25427`.) + +.. + +.. bpo: 33674 +.. date: 2018-05-28-22-49-59 +.. nonce: 6LFFj7 +.. section: Library + +Fix a race condition in SSLProtocol.connection_made() of asyncio.sslproto: +start immediately the handshake instead of using call_soon(). Previously, +data_received() could be called before the handshake started, causing the +handshake to hang or fail. + +.. + +.. bpo: 31647 +.. date: 2018-05-28-18-40-26 +.. nonce: s4Fad3 +.. section: Library + +Fixed bug where calling write_eof() on a _SelectorSocketTransport after it's +already closed raises AttributeError. + +.. + +.. bpo: 32610 +.. date: 2018-05-28-16-40-32 +.. nonce: KvUAsL +.. section: Library + +Make asyncio.all_tasks() return only pending tasks. + +.. + +.. bpo: 32410 +.. date: 2018-05-28-16-19-35 +.. nonce: Z1DZaF +.. section: Library + +Avoid blocking on file IO in sendfile fallback code + +.. + +.. bpo: 33469 +.. date: 2018-05-28-15-55-12 +.. nonce: hmXBpY +.. section: Library + +Fix RuntimeError after closing loop that used run_in_executor + +.. + +.. bpo: 33672 +.. date: 2018-05-28-12-29-54 +.. nonce: GM_Xm_ +.. section: Library + +Fix Task.__repr__ crash with Cython's bogus coroutines + +.. + +.. bpo: 33654 +.. date: 2018-05-26-13-09-34 +.. nonce: IbYWxA +.. section: Library + +Fix transport.set_protocol() to support switching between asyncio.Protocol +and asyncio.BufferedProtocol. Fix loop.start_tls() to work with +asyncio.BufferedProtocols. + +.. + +.. bpo: 33652 +.. date: 2018-05-26-10-13-59 +.. nonce: humFJ1 +.. section: Library + +Pickles of type variables and subscripted generics are now future-proof and +compatible with older Python versions. + +.. + +.. bpo: 32493 +.. date: 2018-05-24-17-41-36 +.. nonce: 5tAoAu +.. section: Library + +Fixed :func:`uuid.uuid1` on FreeBSD. + +.. + +.. bpo: 33238 +.. date: 2018-05-24-09-15-52 +.. nonce: ooDfoo +.. section: Library + +Add ``InvalidStateError`` to :mod:`concurrent.futures`. +``Future.set_result`` and ``Future.set_exception`` now raise +``InvalidStateError`` if the futures are not pending or running. Patch by +Jason Haydaman. + +.. + +.. bpo: 33618 +.. date: 2018-05-23-20-14-34 +.. nonce: xU39lr +.. section: Library + +Finalize and document preliminary and experimental TLS 1.3 support with +OpenSSL 1.1.1 + +.. + +.. bpo: 33625 +.. date: 2018-05-23-17-07-54 +.. nonce: nzQgD8 +.. section: Library + +Release GIL on `grp.getgrnam`, `grp.getgrgid`, `pwd.getpwnam` and +`pwd.getpwuid` if reentrant variants of these functions are available. Patch +by William Grzybowski. + +.. + +.. bpo: 33623 +.. date: 2018-05-23-14-58-05 +.. nonce: wAw1cF +.. section: Library + +Fix possible SIGSGV when asyncio.Future is created in __del__ + +.. + +.. bpo: 11874 +.. date: 2018-05-23-00-26-27 +.. nonce: glK5iP +.. section: Library + +Use a better regex when breaking usage into wrappable parts. Avoids bogus +assertion errors from custom metavar strings. + +.. + +.. bpo: 30877 +.. date: 2018-05-22-13-05-12 +.. nonce: JZEGjI +.. section: Library + +Fixed a bug in the Python implementation of the JSON decoder that prevented +the cache of parsed strings from clearing after finishing the decoding. +Based on patch by c-fos. + +.. + +.. bpo: 33604 +.. date: 2018-05-22-11-55-33 +.. nonce: 6V4JcO +.. section: Library + +Remove HMAC default to md5 marked for removal in 3.8 (removal originally +planned in 3.6, bump to 3.8 in PR 7062). + +.. + +.. bpo: 33582 +.. date: 2018-05-19-15-58-14 +.. nonce: qBZPmF +.. section: Library + +Emit a deprecation warning for inspect.formatargspec + +.. + +.. bpo: 21145 +.. date: 2018-05-18-22-52-34 +.. nonce: AiQMDx +.. section: Library + +Add ``functools.cached_property`` decorator, for computed properties cached +for the life of the instance. + +.. + +.. bpo: 33570 +.. date: 2018-05-18-21-50-47 +.. nonce: 7CZy4t +.. section: Library + +Change TLS 1.3 cipher suite settings for compatibility with OpenSSL +1.1.1-pre6 and newer. OpenSSL 1.1.1 will have TLS 1.3 ciphers enabled by +default. + +.. + +.. bpo: 28556 +.. date: 2018-05-17-22-53-08 +.. nonce: C6Hnd1 +.. section: Library + +Do not simplify arguments to `typing.Union`. Now `Union[Manager, Employee]` +is not simplified to `Employee` at runtime. Such simplification previously +caused several bugs and limited possibilities for introspection. + +.. + +.. bpo: 12486 +.. date: 2018-05-17-22-14-58 +.. nonce: HBeh62 +.. section: Library + +:func:`tokenize.generate_tokens` is now documented as a public API to +tokenize unicode strings. It was previously present but undocumented. + +.. + +.. bpo: 33540 +.. date: 2018-05-16-18-10-38 +.. nonce: wy9LRV +.. section: Library + +Add a new ``block_on_close`` class attribute to ``ForkingMixIn`` and +``ThreadingMixIn`` classes of :mod:`socketserver`. + +.. + +.. bpo: 33548 +.. date: 2018-05-16-17-05-48 +.. nonce: xWslmx +.. section: Library + +tempfile._candidate_tempdir_list should consider common TEMP locations + +.. + +.. bpo: 33109 +.. date: 2018-05-16-14-57-58 +.. nonce: nPLL_S +.. section: Library + +argparse subparsers are once again not required by default, reverting the +change in behavior introduced by bpo-26510 in 3.7.0a2. + +.. + +.. bpo: 33541 +.. date: 2018-05-16-12-32-48 +.. nonce: kQORPE +.. section: Library + +Remove unused private method ``_strptime.LocaleTime.__pad`` (a.k.a. +``_LocaleTime__pad``). + +.. + +.. bpo: 33536 +.. date: 2018-05-16-10-07-40 +.. nonce: _s0TE8 +.. section: Library + +dataclasses.make_dataclass now checks for invalid field names and duplicate +fields. Also, added a check for invalid field specifications. + +.. + +.. bpo: 33542 +.. date: 2018-05-16-09-30-27 +.. nonce: idNAcs +.. section: Library + +Prevent ``uuid.get_node`` from using a DUID instead of a MAC on Windows. +Patch by Zvi Effron + +.. + +.. bpo: 26819 +.. date: 2018-05-16-05-24-43 +.. nonce: taxbVT +.. section: Library + +Fix race condition with `ReadTransport.resume_reading` in Windows proactor +event loop. + +.. + +.. bpo: 0 +.. date: 2018-05-15-18-02-03 +.. nonce: pj2Mbb +.. section: Library + +Fix failure in `typing.get_type_hints()` when ClassVar was provided as a +string forward reference. + +.. + +.. bpo: 33516 +.. date: 2018-05-15-17-06-42 +.. nonce: ZzARe4 +.. section: Library + +:class:`unittest.mock.MagicMock` now supports the ``__round__`` magic +method. + +.. + +.. bpo: 28612 +.. date: 2018-05-15-15-03-48 +.. nonce: E9dz39 +.. section: Library + +Added support for Site Maps to urllib's ``RobotFileParser`` as +:meth:`RobotFileParser.site_maps() +<urllib.robotparser.RobotFileParser.site_maps>`. Patch by Lady Red, based on +patch by Peter Wirtz. + +.. + +.. bpo: 28167 +.. date: 2018-05-15-13-49-13 +.. nonce: p4RdQt +.. section: Library + +Remove platform.linux_distribution, which was deprecated since 3.5. + +.. + +.. bpo: 33504 +.. date: 2018-05-15-12-11-13 +.. nonce: czsHFg +.. section: Library + +Switch the default dictionary implementation for :mod:`configparser` from +:class:`collections.OrderedDict` to the standard :class:`dict` type. + +.. + +.. bpo: 33505 +.. date: 2018-05-14-18-05-35 +.. nonce: L8pAyt +.. section: Library + +Optimize asyncio.ensure_future() by reordering if checks: 1.17x faster. + +.. + +.. bpo: 33497 +.. date: 2018-05-14-17-49-34 +.. nonce: wWT6XM +.. section: Library + +Add errors param to cgi.parse_multipart and make an encoding in FieldStorage +use the given errors (needed for Twisted). Patch by Amber Brown. + +.. + +.. bpo: 29235 +.. date: 2018-05-14-15-01-55 +.. nonce: 47Fzwt +.. section: Library + +The :class:`cProfile.Profile` class can now be used as a context manager. +Patch by Scott Sanderson. + +.. + +.. bpo: 33495 +.. date: 2018-05-14-10-29-03 +.. nonce: TeGTQJ +.. section: Library + +Change dataclasses.Fields repr to use the repr of each of its members, +instead of str. This makes it more clear what each field actually +represents. This is especially true for the 'type' member. + +.. + +.. bpo: 26103 +.. date: 2018-05-14-09-07-14 +.. nonce: _zU8E2 +.. section: Library + +Correct ``inspect.isdatadescriptor`` to look for ``__set__`` or +``__delete__``. Patch by Aaron Hall. + +.. + +.. bpo: 29209 +.. date: 2018-05-12-13-06-41 +.. nonce: h5RxYy +.. section: Library + +Removed the ``doctype()`` method and the *html* parameter of the constructor +of :class:`~xml.etree.ElementTree.XMLParser`. The ``doctype()`` method +defined in a subclass will no longer be called. Deprecated methods +``getchildren()`` and ``getiterator()`` in the :mod:`~xml.etree.ElementTree` +module emit now a :exc:`DeprecationWarning` instead of +:exc:`PendingDeprecationWarning`. + +.. + +.. bpo: 33453 +.. date: 2018-05-12-06-01-02 +.. nonce: Fj-jMD +.. section: Library + +Fix dataclasses to work if using literal string type annotations or if using +PEP 563 "Postponed Evaluation of Annotations". Only specific string +prefixes are detected for both ClassVar ("ClassVar" and "typing.ClassVar") +and InitVar ("InitVar" and "dataclasses.InitVar"). + +.. + +.. bpo: 28556 +.. date: 2018-05-08-16-43-42 +.. nonce: _xr5mp +.. section: Library + +Minor fixes in typing module: add annotations to ``NamedTuple.__new__``, +pass ``*args`` and ``**kwds`` in ``Generic.__new__``. Original PRs by +Paulius Å arka and Chad Dombrova. + +.. + +.. bpo: 33365 +.. date: 2018-05-08-15-01-10 +.. nonce: SicsAd +.. section: Library + +Print the header values besides the header keys instead just the header keys +if *debuglevel* is set to >0 in :mod:`http.client`. Patch by Marco Strigl. + +.. + +.. bpo: 20087 +.. date: 2018-05-05-18-02-24 +.. nonce: lJrvXL +.. section: Library + +Updated alias mapping with glibc 2.27 supported locales. + +.. + +.. bpo: 33422 +.. date: 2018-05-05-09-53-05 +.. nonce: 4FtQ0q +.. section: Library + +Fix trailing quotation marks getting deleted when looking up byte/string +literals on pydoc. Patch by Andrés Delfino. + +.. + +.. bpo: 28167 +.. date: 2018-05-02-07-26-29 +.. nonce: 7FwDfN +.. section: Library + +The function ``platform.linux_distribution`` and ``platform.dist`` now +trigger a ``DeprecationWarning`` and have been marked for removal in Python +3.8 + +.. + +.. bpo: 33281 +.. date: 2018-05-01-22-35-50 +.. nonce: d4jOt4 +.. section: Library + +Fix ctypes.util.find_library regression on macOS. + +.. + +.. bpo: 33311 +.. date: 2018-05-01-22-33-14 +.. nonce: 8YPB-k +.. section: Library + +Text and html output generated by cgitb does not display parentheses if the +current call is done directly in the module. Patch by Stéphane Blondon. + +.. + +.. bpo: 27300 +.. date: 2018-05-01-02-24-44 +.. nonce: LdIXvK +.. section: Library + +The file classes in *tempfile* now accept an *errors* parameter that +complements the already existing *encoding*. Patch by Stephan Hohe. + +.. + +.. bpo: 32933 +.. date: 2018-04-30-22-43-31 +.. nonce: M3iI_y +.. section: Library + +:func:`unittest.mock.mock_open` now supports iteration over the file +contents. Patch by Tony Flury. + +.. + +.. bpo: 33217 +.. date: 2018-04-30-13-29-47 +.. nonce: TENDzd +.. section: Library + +Raise :exc:`TypeError` when looking up non-Enum objects in Enum classes and +Enum members. + +.. + +.. bpo: 33197 +.. date: 2018-04-29-23-56-20 +.. nonce: dgRLqr +.. section: Library + +Update error message when constructing invalid inspect.Parameters Patch by +Donghee Na. + +.. + +.. bpo: 33383 +.. date: 2018-04-29-11-15-38 +.. nonce: g32YWn +.. section: Library + +Fixed crash in the get() method of the :mod:`dbm.ndbm` database object when +it is called with a single argument. + +.. + +.. bpo: 33375 +.. date: 2018-04-28-08-11-35 +.. nonce: Dbq1fz +.. section: Library + +The warnings module now finds the Python file associated with a warning from +the code object, rather than the frame's global namespace. This is +consistent with how tracebacks and pdb find filenames, and should work +better for dynamically executed code. + +.. + +.. bpo: 33336 +.. date: 2018-04-27-22-18-38 +.. nonce: T8rxn0 +.. section: Library + +``imaplib`` now allows ``MOVE`` command in ``IMAP4.uid()`` (RFC 6851: IMAP +MOVE Extension) and potentially as a name of supported method of ``IMAP4`` +object. + +.. + +.. bpo: 32455 +.. date: 2018-04-26-13-31-10 +.. nonce: KPWg3K +.. section: Library + +Added *jump* parameter to :func:`dis.stack_effect`. + +.. + +.. bpo: 27485 +.. date: 2018-04-25-14-05-21 +.. nonce: nclVSU +.. section: Library + +Rename and deprecate undocumented functions in :func:`urllib.parse`. + +.. + +.. bpo: 33332 +.. date: 2018-04-23-21-41-30 +.. nonce: Y6OZ8Z +.. section: Library + +Add ``signal.valid_signals()`` to expose the POSIX sigfillset() +functionality. + +.. + +.. bpo: 33251 +.. date: 2018-04-23-18-25-36 +.. nonce: C_K-J9 +.. section: Library + +`ConfigParser.items()` was fixed so that key-value pairs passed in via +`vars` are not included in the resulting output. + +.. + +.. bpo: 33329 +.. date: 2018-04-23-13-21-39 +.. nonce: lQ-Eod +.. section: Library + +Fix multiprocessing regression on newer glibcs + +.. + +.. bpo: 33334 +.. date: 2018-04-22-20-13-21 +.. nonce: 19UMOC +.. section: Library + +:func:`dis.stack_effect` now supports all defined opcodes including NOP and +EXTENDED_ARG. + +.. + +.. bpo: 991266 +.. date: 2018-04-21-00-24-08 +.. nonce: h93TP_ +.. section: Library + +Fix quoting of the ``Comment`` attribute of +:class:`http.cookies.SimpleCookie`. + +.. + +.. bpo: 33131 +.. date: 2018-04-20-10-43-17 +.. nonce: L2E977 +.. section: Library + +Upgrade bundled version of pip to 10.0.1. + +.. + +.. bpo: 33308 +.. date: 2018-04-18-19-12-25 +.. nonce: fW75xi +.. section: Library + +Fixed a crash in the :mod:`parser` module when converting an ST object to a +tree of tuples or lists with ``line_info=False`` and ``col_info=True``. + +.. + +.. bpo: 23403 +.. date: 2018-04-16-16-21-09 +.. nonce: rxR1Q_ +.. section: Library + +lib2to3 now uses pickle protocol 4 for pre-computed grammars. + +.. + +.. bpo: 33266 +.. date: 2018-04-16-15-59-21 +.. nonce: w2PAm- +.. section: Library + +lib2to3 now recognizes ``rf'...'`` strings. + +.. + +.. bpo: 11594 +.. date: 2018-04-16-08-42-03 +.. nonce: QLo4vv +.. section: Library + +Ensure line-endings are respected when using lib2to3. + +.. + +.. bpo: 33254 +.. date: 2018-04-13-15-14-47 +.. nonce: DS4KFK +.. section: Library + +Have :func:`importlib.resources.contents` and +:meth:`importlib.abc.ResourceReader.contents` return an :term:`iterable` +instead of an :term:`iterator`. + +.. + +.. bpo: 33265 +.. date: 2018-04-13-08-12-50 +.. nonce: KPQRk0 +.. section: Library + +``contextlib.ExitStack`` and ``contextlib.AsyncExitStack`` now use a method +instead of a wrapper function for exit callbacks. + +.. + +.. bpo: 33263 +.. date: 2018-04-11-20-29-19 +.. nonce: B56Hc1 +.. section: Library + +Fix FD leak in `_SelectorSocketTransport` Patch by Vlad Starostin. + +.. + +.. bpo: 33256 +.. date: 2018-04-10-20-57-14 +.. nonce: ndHkqu +.. section: Library + +Fix display of ``<module>`` call in the html produced by ``cgitb.html()``. +Patch by Stéphane Blondon. + +.. + +.. bpo: 33144 +.. date: 2018-04-10-14-50-30 +.. nonce: iZr4et +.. section: Library + +``random.Random()`` and its subclassing mechanism got optimized to check +only once at class/subclass instantiation time whether its ``getrandbits()`` +method can be relied on by other methods, including ``randrange()``, for the +generation of arbitrarily large random integers. Patch by Wolfgang Maier. + +.. + +.. bpo: 33185 +.. date: 2018-04-08-22-54-07 +.. nonce: Id-Ba9 +.. section: Library + +Fixed regression when running pydoc with the :option:`-m` switch. (The +regression was introduced in 3.7.0b3 by the resolution of :issue:`33053`) + +This fix also changed pydoc to add ``os.getcwd()`` to :data:`sys.path` when +necessary, rather than adding ``"."``. + +.. + +.. bpo: 29613 +.. date: 2018-04-07-13-49-39 +.. nonce: r6FDnB +.. section: Library + +Added support for the ``SameSite`` cookie flag to the ``http.cookies`` +module. + +.. + +.. bpo: 33169 +.. date: 2018-04-06-14-56-26 +.. nonce: ByhDqb +.. section: Library + +Delete entries of ``None`` in :data:`sys.path_importer_cache` when +:meth:`importlib.machinery.invalidate_caches` is called. + +.. + +.. bpo: 33203 +.. date: 2018-04-05-11-09-45 +.. nonce: Hje9Py +.. section: Library + +``random.Random.choice()`` now raises ``IndexError`` for empty sequences +consistently even when called from subclasses without a ``getrandbits()`` +implementation. + +.. + +.. bpo: 33224 +.. date: 2018-04-04-23-41-30 +.. nonce: pyR0jB +.. section: Library + +Update difflib.mdiff() for :pep:`479`. Convert an uncaught StopIteration in +a generator into a return-statement. + +.. + +.. bpo: 33209 +.. date: 2018-04-03-10-37-13 +.. nonce: 9sGWE_ +.. section: Library + +End framing at the end of C implementation of :func:`pickle.Pickler.dump`. + +.. + +.. bpo: 32861 +.. date: 2018-04-02-20-44-54 +.. nonce: HeBjzN +.. section: Library + +The urllib.robotparser's ``__str__`` representation now includes wildcard +entries and the "Crawl-delay" and "Request-rate" fields. Also removes extra +newlines that were being appended to the end of the string. Patch by Michael +Lazar. + +.. + +.. bpo: 23403 +.. date: 2018-04-02-16-10-12 +.. nonce: KG7ADV +.. section: Library + +``DEFAULT_PROTOCOL`` in :mod:`pickle` was bumped to 4. Protocol 4 is +described in :pep:`3154` and available since Python 3.4. It offers better +performance and smaller size compared to protocol 3 introduced in Python +3.0. + +.. + +.. bpo: 20104 +.. date: 2018-04-01-19-21-04 +.. nonce: -AKcGa +.. section: Library + +Improved error handling and fixed a reference leak in +:func:`os.posix_spawn()`. + +.. + +.. bpo: 33106 +.. date: 2018-03-30-01-20-35 +.. nonce: zncfvW +.. section: Library + +Deleting a key from a read-only dbm database raises module specific error +instead of KeyError. + +.. + +.. bpo: 33175 +.. date: 2018-03-29-04-32-25 +.. nonce: _zs1yM +.. section: Library + +In dataclasses, Field.__set_name__ now looks up the __set_name__ special +method on the class, not the instance, of the default value. + +.. + +.. bpo: 32380 +.. date: 2018-03-29-03-09-22 +.. nonce: NhuGig +.. section: Library + +Create functools.singledispatchmethod to support generic single dispatch on +descriptors and methods. + +.. + +.. bpo: 33141 +.. date: 2018-03-26-12-33-13 +.. nonce: 23wlxf +.. section: Library + +Have Field objects pass through __set_name__ to their default values, if +they have their own __set_name__. + +.. + +.. bpo: 33096 +.. date: 2018-03-25-13-18-16 +.. nonce: ofdbe7 +.. section: Library + +Allow ttk.Treeview.insert to insert iid that has a false boolean value. Note +iid=0 and iid=False would be same. Patch by Garvit Khatri. + +.. + +.. bpo: 32873 +.. date: 2018-03-24-19-54-48 +.. nonce: cHyoAm +.. section: Library + +Treat type variables and special typing forms as immutable by copy and +pickle. This fixes several minor issues and inconsistencies, and improves +backwards compatibility with Python 3.6. + +.. + +.. bpo: 33134 +.. date: 2018-03-24-19-34-26 +.. nonce: hbVeIX +.. section: Library + +When computing dataclass's __hash__, use the lookup table to contain the +function which returns the __hash__ value. This is an improvement over +looking up a string, and then testing that string to see what to do. + +.. + +.. bpo: 33127 +.. date: 2018-03-24-15-08-24 +.. nonce: olJmHv +.. section: Library + +The ssl module now compiles with LibreSSL 2.7.1. + +.. + +.. bpo: 32505 +.. date: 2018-03-22-16-05-56 +.. nonce: YK1N8v +.. section: Library + +Raise TypeError if a member variable of a dataclass is of type Field, but +doesn't have a type annotation. + +.. + +.. bpo: 33078 +.. date: 2018-03-21-17-59-39 +.. nonce: PQOniT +.. section: Library + +Fix the failure on OSX caused by the tests relying on sem_getvalue + +.. + +.. bpo: 33116 +.. date: 2018-03-21-16-52-26 +.. nonce: Tvzerj +.. section: Library + +Add 'Field' to dataclasses.__all__. + +.. + +.. bpo: 32896 +.. date: 2018-03-20-20-53-21 +.. nonce: ewW3Ln +.. section: Library + +Fix an error where subclassing a dataclass with a field that uses a +default_factory would generate an incorrect class. + +.. + +.. bpo: 33100 +.. date: 2018-03-19-20-47-00 +.. nonce: chyIO4 +.. section: Library + +Dataclasses: If a field has a default value that's a MemberDescriptorType, +then it's from that field being in __slots__, not an actual default value. + +.. + +.. bpo: 32953 +.. date: 2018-03-18-17-38-48 +.. nonce: t8WAWN +.. section: Library + +If a non-dataclass inherits from a frozen dataclass, allow attributes to be +added to the derived class. Only attributes from the frozen dataclass +cannot be assigned to. Require all dataclasses in a hierarchy to be either +all frozen or all non-frozen. + +.. + +.. bpo: 33097 +.. date: 2018-03-18-16-48-23 +.. nonce: Yl4gI2 +.. section: Library + +Raise RuntimeError when ``executor.submit`` is called during interpreter +shutdown. + +.. + +.. bpo: 32968 +.. date: 2018-03-18-15-57-32 +.. nonce: E4G7BO +.. section: Library + +Modulo and floor division involving Fraction and float should return float. + +.. + +.. bpo: 33061 +.. date: 2018-03-16-16-07-33 +.. nonce: TRTTek +.. section: Library + +Add missing ``NoReturn`` to ``__all__`` in typing.py + +.. + +.. bpo: 33078 +.. date: 2018-03-15-07-38-00 +.. nonce: RmjUF5 +.. section: Library + +Fix the size handling in multiprocessing.Queue when a pickling error occurs. + +.. + +.. bpo: 33064 +.. date: 2018-03-12-19-58-25 +.. nonce: LO2KIY +.. section: Library + +lib2to3 now properly supports trailing commas after ``*args`` and +``**kwargs`` in function signatures. + +.. + +.. bpo: 33056 +.. date: 2018-03-12-16-40-00 +.. nonce: lNN9Eh +.. section: Library + +FIX properly close leaking fds in concurrent.futures.ProcessPoolExecutor. + +.. + +.. bpo: 33021 +.. date: 2018-03-12-00-27-56 +.. nonce: m19B9T +.. section: Library + +Release the GIL during fstat() calls, avoiding hang of all threads when +calling mmap.mmap(), os.urandom(), and random.seed(). Patch by Nir Soffer. + +.. + +.. bpo: 31804 +.. date: 2018-03-11-19-03-52 +.. nonce: i8KUMp +.. section: Library + +Avoid failing in multiprocessing.Process if the standard streams are closed +or None at exit. + +.. + +.. bpo: 33034 +.. date: 2018-03-11-08-44-12 +.. nonce: bpb23d +.. section: Library + +Providing an explicit error message when casting the port property to +anything that is not an integer value using ``urlparse()`` and +``urlsplit()``. Patch by Matt Eaton. + +.. + +.. bpo: 30249 +.. date: 2018-03-11-00-20-26 +.. nonce: KSkgLB +.. section: Library + +Improve struct.unpack_from() exception messages for problems with the buffer +size and offset. + +.. + +.. bpo: 33037 +.. date: 2018-03-09-23-07-07 +.. nonce: nAJ3at +.. section: Library + +Skip sending/receiving data after SSL transport closing. + +.. + +.. bpo: 27683 +.. date: 2018-03-07-22-28-17 +.. nonce: 572Rv4 +.. section: Library + +Fix a regression in :mod:`ipaddress` that result of :meth:`hosts` is empty +when the network is constructed by a tuple containing an integer mask and +only 1 bit left for addresses. + +.. + +.. bpo: 22674 +.. date: 2018-03-07-19-37-00 +.. nonce: 2sIMmM +.. section: Library + +Add the strsignal() function in the signal module that returns the system +description of the given signal, as returned by strsignal(3). + +.. + +.. bpo: 32999 +.. date: 2018-03-06-20-30-20 +.. nonce: lgFXWl +.. section: Library + +Fix C implementation of ``ABC.__subclasscheck__(cls, subclass)`` crashed +when ``subclass`` is not a type object. + +.. + +.. bpo: 33009 +.. date: 2018-03-06-11-54-59 +.. nonce: -Ekysb +.. section: Library + +Fix inspect.signature() for single-parameter partialmethods. + +.. + +.. bpo: 32969 +.. date: 2018-03-06-00-19-41 +.. nonce: rGTKa0 +.. section: Library + +Expose several missing constants in zlib and fix corresponding +documentation. + +.. + +.. bpo: 32056 +.. date: 2018-03-01-17-49-56 +.. nonce: IlpfgE +.. section: Library + +Improved exceptions raised for invalid number of channels and sample width +when read an audio file in modules :mod:`aifc`, :mod:`wave` and +:mod:`sunau`. + +.. + +.. bpo: 32970 +.. date: 2018-02-28-18-39-48 +.. nonce: IPWtbS +.. section: Library + +Improved disassembly of the MAKE_FUNCTION instruction. + +.. + +.. bpo: 32844 +.. date: 2018-02-28-13-08-00 +.. nonce: u8tnAe +.. section: Library + +Fix wrong redirection of a low descriptor (0 or 1) to stderr in subprocess +if another low descriptor is closed. + +.. + +.. bpo: 32960 +.. date: 2018-02-26-20-04-40 +.. nonce: 48r0Ml +.. section: Library + +For dataclasses, disallow inheriting frozen from non-frozen classes, and +also disallow inheriting non-frozen from frozen classes. This restriction +will be relaxed at a future date. + +.. + +.. bpo: 32713 +.. date: 2018-02-26-13-16-36 +.. nonce: 55yegW +.. section: Library + +Fixed tarfile.itn handling of out-of-bounds float values. Patch by Joffrey +Fuhrer. + +.. + +.. bpo: 32257 +.. date: 2018-02-26-09-08-07 +.. nonce: 6ElnUt +.. section: Library + +The ssl module now contains OP_NO_RENEGOTIATION constant, available with +OpenSSL 1.1.0h or 1.1.1. + +.. + +.. bpo: 32951 +.. date: 2018-02-25-18-22-01 +.. nonce: gHrCXq +.. section: Library + +Direct instantiation of SSLSocket and SSLObject objects is now prohibited. +The constructors were never documented, tested, or designed as public +constructors. Users were suppose to use ssl.wrap_socket() or SSLContext. + +.. + +.. bpo: 32929 +.. date: 2018-02-25-13-47-48 +.. nonce: X2gTDH +.. section: Library + +Remove the tri-state parameter "hash", and add the boolean "unsafe_hash". If +unsafe_hash is True, add a __hash__ function, but if a __hash__ exists, +raise TypeError. If unsafe_hash is False, add a __hash__ based on the +values of eq= and frozen=. The unsafe_hash=False behavior is the same as +the old hash=None behavior. unsafe_hash=False is the default, just as +hash=None used to be. + +.. + +.. bpo: 32947 +.. date: 2018-02-25-13-06-21 +.. nonce: mqStVW +.. section: Library + +Add OP_ENABLE_MIDDLEBOX_COMPAT and test workaround for TLSv1.3 for future +compatibility with OpenSSL 1.1.1. + +.. + +.. bpo: 32146 +.. date: 2018-02-25-10-17-23 +.. nonce: xOzUFW +.. section: Library + +Document the interaction between frozen executables and the spawn and +forkserver start methods in multiprocessing. + +.. + +.. bpo: 30622 +.. date: 2018-02-24-21-40-42 +.. nonce: dQjxSe +.. section: Library + +The ssl module now detects missing NPN support in LibreSSL. + +.. + +.. bpo: 32922 +.. date: 2018-02-23-19-12-04 +.. nonce: u-xe0B +.. section: Library + +dbm.open() now encodes filename with the filesystem encoding rather than +default encoding. + +.. + +.. bpo: 32759 +.. date: 2018-02-23-12-21-41 +.. nonce: M-y9GA +.. section: Library + +Free unused arenas in multiprocessing.heap. + +.. + +.. bpo: 32859 +.. date: 2018-02-19-17-46-31 +.. nonce: kAT-Xp +.. section: Library + +In ``os.dup2``, don't check every call whether the ``dup3`` syscall exists +or not. + +.. + +.. bpo: 32556 +.. date: 2018-02-19-14-27-51 +.. nonce: CsRsgr +.. section: Library + +nt._getfinalpathname, nt._getvolumepathname and nt._getdiskusage now +correctly convert from bytes. + +.. + +.. bpo: 21060 +.. date: 2018-02-17-19-20-19 +.. nonce: S1Z-x6 +.. section: Library + +Rewrite confusing message from setup.py upload from "No dist file created in +earlier command" to the more helpful "Must create and upload files in one +command". + +.. + +.. bpo: 32857 +.. date: 2018-02-16-14-37-14 +.. nonce: -XljAx +.. section: Library + +In :mod:`tkinter`, ``after_cancel(None)`` now raises a :exc:`ValueError` +instead of canceling the first scheduled function. Patch by Cheryl Sabella. + +.. + +.. bpo: 32852 +.. date: 2018-02-15-12-04-29 +.. nonce: HDqIxM +.. section: Library + +Make sure sys.argv remains as a list when running trace. + +.. + +.. bpo: 31333 +.. date: 2018-02-15-08-18-52 +.. nonce: 4fF-gM +.. section: Library + +``_abc`` module is added. It is a speedup module with C implementations for +various functions and methods in ``abc``. Creating an ABC subclass and +calling ``isinstance`` or ``issubclass`` with an ABC subclass are up to 1.5x +faster. In addition, this makes Python start-up up to 10% faster. + +Note that the new implementation hides internal registry and caches, +previously accessible via private attributes ``_abc_registry``, +``_abc_cache``, and ``_abc_negative_cache``. There are three debugging +helper methods that can be used instead ``_dump_registry``, +``_abc_registry_clear``, and ``_abc_caches_clear``. + +.. + +.. bpo: 32841 +.. date: 2018-02-14-00-21-24 +.. nonce: bvHDOc +.. section: Library + +Fixed `asyncio.Condition` issue which silently ignored cancellation after +notifying and cancelling a conditional lock. Patch by Bar Harel. + +.. + +.. bpo: 32819 +.. date: 2018-02-11-15-54-41 +.. nonce: ZTRX2Q +.. section: Library + +ssl.match_hostname() has been simplified and no longer depends on re and +ipaddress module for wildcard and IP addresses. Error reporting for invalid +wildcards has been improved. + +.. + +.. bpo: 19675 +.. date: 2018-02-10-23-41-05 +.. nonce: -dj35- +.. section: Library + +``multiprocessing.Pool`` no longer leaks processes if its initialization +fails. + +.. + +.. bpo: 32394 +.. date: 2018-02-10-13-51-56 +.. nonce: dFM9SI +.. section: Library + +socket: Remove TCP_FASTOPEN,TCP_KEEPCNT,TCP_KEEPIDLE,TCP_KEEPINTVL flags on +older version Windows during run-time. + +.. + +.. bpo: 31787 +.. date: 2018-02-09-21-41-56 +.. nonce: owSZ2t +.. section: Library + +Fixed refleaks of ``__init__()`` methods in various modules. (Contributed by +Oren Milman) + +.. + +.. bpo: 30157 +.. date: 2018-02-09-14-44-43 +.. nonce: lEiiAK +.. section: Library + +Fixed guessing quote and delimiter in csv.Sniffer.sniff() when only the last +field is quoted. Patch by Jake Davis. + +.. + +.. bpo: 30688 +.. date: 2018-02-08-18-59-11 +.. nonce: zBh4TH +.. section: Library + +Added support of ``\N{name}`` escapes in regular expressions. Based on +patch by Jonathan Eunice. + +.. + +.. bpo: 32792 +.. date: 2018-02-08-00-47-07 +.. nonce: NtyDb4 +.. section: Library + +collections.ChainMap() preserves the order of the underlying mappings. + +.. + +.. bpo: 32775 +.. date: 2018-02-07-19-12-10 +.. nonce: -T77_c +.. section: Library + +:func:`fnmatch.translate()` no longer produces patterns which contain set +operations. Sets starting with '[' or containing '--', '&&', '~~' or '||' +will be interpreted differently in regular expressions in future versions. +Currently they emit warnings. fnmatch.translate() now avoids producing +patterns containing such sets by accident. + +.. + +.. bpo: 32622 +.. date: 2018-02-06-17-58-15 +.. nonce: AE0Jz7 +.. section: Library + +Implement native fast sendfile for Windows proactor event loop. + +.. + +.. bpo: 32777 +.. date: 2018-02-05-21-28-28 +.. nonce: C-wIXF +.. section: Library + +Fix a rare but potential pre-exec child process deadlock in subprocess on +POSIX systems when marking file descriptors inheritable on exec in the child +process. This bug appears to have been introduced in 3.4. + +.. + +.. bpo: 32647 +.. date: 2018-02-05-13-31-42 +.. nonce: ktmfR_ +.. section: Library + +The ctypes module used to depend on indirect linking for dlopen. The shared +extension is now explicitly linked against libdl on platforms with dl. + +.. + +.. bpo: 32749 +.. date: 2018-02-02-17-21-24 +.. nonce: u5scIn +.. section: Library + +A :mod:`dbm.dumb` database opened with flags 'r' is now read-only. +:func:`dbm.dumb.open` with flags 'r' and 'w' no longer creates a database if +it does not exist. + +.. + +.. bpo: 32741 +.. date: 2018-02-01-17-54-08 +.. nonce: KUvOPL +.. section: Library + +Implement ``asyncio.TimerHandle.when()`` method. + +.. + +.. bpo: 32691 +.. date: 2018-02-01-15-53-35 +.. nonce: VLWVTq +.. section: Library + +Use mod_spec.parent when running modules with pdb + +.. + +.. bpo: 32734 +.. date: 2018-02-01-01-34-47 +.. nonce: gCV9AD +.. section: Library + +Fixed ``asyncio.Lock()`` safety issue which allowed acquiring and locking +the same lock multiple times, without it being free. Patch by Bar Harel. + +.. + +.. bpo: 32727 +.. date: 2018-01-30-17-46-18 +.. nonce: aHVsRC +.. section: Library + +Do not include name field in SMTP envelope from address. Patch by Stéphane +Wirtel + +.. + +.. bpo: 31453 +.. date: 2018-01-21-15-01-50 +.. nonce: cZiZBe +.. section: Library + +Add TLSVersion constants and SSLContext.maximum_version / minimum_version +attributes. The new API wraps OpenSSL 1.1 +https://web.archive.org/web/20180309043602/https://www.openssl.org/docs/man1.1.0/ssl/SSL_CTX_set_min_proto_version.html +feature. + +.. + +.. bpo: 24334 +.. date: 2018-01-20-23-17-25 +.. nonce: GZuQLv +.. section: Library + +Internal implementation details of ssl module were cleaned up. The SSLSocket +has one less layer of indirection. Owner and session information are now +handled by the SSLSocket and SSLObject constructor. Channel binding +implementation has been simplified. + +.. + +.. bpo: 31848 +.. date: 2018-01-18-23-34-17 +.. nonce: M2cldy +.. section: Library + +Fix the error handling in Aifc_read.initfp() when the SSND chunk is not +found. Patch by Zackery Spytz. + +.. + +.. bpo: 32585 +.. date: 2018-01-18-13-09-00 +.. nonce: qpeijr +.. section: Library + +Add Ttk spinbox widget to :mod:`tkinter.ttk`. Patch by Alan D Moore. + +.. + +.. bpo: 32512 +.. date: 2018-01-07-17-43-10 +.. nonce: flC-dE +.. section: Library + +:mod:`profile` CLI accepts `-m module_name` as an alternative to script +path. + +.. + +.. bpo: 8525 +.. date: 2018-01-01-00-16-59 +.. nonce: Dq8s63 +.. section: Library + +help() on a type now displays builtin subclasses. This is intended primarily +to help with notification of more specific exception subclasses. + +Patch by Sanyam Khurana. + +.. + +.. bpo: 31639 +.. date: 2017-12-27-21-55-19 +.. nonce: l3avDJ +.. section: Library + +http.server now exposes a ThreadingHTTPServer class and uses it when the +module is run with ``-m`` to cope with web browsers pre-opening sockets. + +.. + +.. bpo: 29877 +.. date: 2017-12-16-11-40-52 +.. nonce: SfWhmz +.. section: Library + +compileall: import ProcessPoolExecutor only when needed, preventing hangs on +low resource platforms + +.. + +.. bpo: 32221 +.. date: 2017-12-06-10-10-10 +.. nonce: ideco_ +.. section: Library + +Various functions returning tuple containing IPv6 addresses now omit +``%scope`` part since the same information is already encoded in *scopeid* +tuple item. Especially this speeds up :func:`socket.recvfrom` when it +receives multicast packet since useless resolving of network interface name +is omitted. + +.. + +.. bpo: 32147 +.. date: 2017-11-28-10-23-13 +.. nonce: PI2k1Y +.. section: Library + +:func:`binascii.unhexlify` is now up to 2 times faster. Patch by Sergey +Fedoseev. + +.. + +.. bpo: 30693 +.. date: 2017-11-27-15-09-49 +.. nonce: yC4mJ8 +.. section: Library + +The TarFile class now recurses directories in a reproducible way. + +.. + +.. bpo: 30693 +.. date: 2017-11-27-15-09-49 +.. nonce: yC4mJ7 +.. section: Library + +The ZipFile class now recurses directories in a reproducible way. + +.. + +.. bpo: 31680 +.. date: 2017-11-01-15-44-48 +.. nonce: yO6oSC +.. section: Library + +Added :data:`curses.ncurses_version`. + +.. + +.. bpo: 31908 +.. date: 2017-10-31 +.. nonce: g4xh8x +.. section: Library + +Fix output of cover files for ``trace`` module command-line tool. Previously +emitted cover files only when ``--missing`` option was used. Patch by +Michael Selik. + +.. + +.. bpo: 31608 +.. date: 2017-10-29-10-37-55 +.. nonce: wkp8Nw +.. section: Library + +Raise a ``TypeError`` instead of crashing if a ``collections.deque`` +subclass returns a non-deque from ``__new__``. Patch by Oren Milman. + +.. + +.. bpo: 31425 +.. date: 2017-10-24-10-18-35 +.. nonce: 1lgw47 +.. section: Library + +Add support for sockets of the AF_QIPCRTR address family, supported by the +Linux kernel. This is used to communicate with services, such as GPS or +radio, running on Qualcomm devices. Patch by Bjorn Andersson. + +.. + +.. bpo: 22005 +.. date: 2017-10-12-22-39-55 +.. nonce: lGP-sc +.. section: Library + +Implemented unpickling instances of :class:`~datetime.datetime`, +:class:`~datetime.date` and :class:`~datetime.time` pickled by Python 2. +``encoding='latin1'`` should be used for successful decoding. + +.. + +.. bpo: 27645 +.. date: 2017-10-05-20-41-48 +.. nonce: 1Y_Wag +.. section: Library + +:class:`sqlite3.Connection` now exposes a +:class:`~sqlite3.Connection.backup` method, if the underlying SQLite library +is at version 3.6.11 or higher. Patch by Lele Gaifax. + +.. + +.. bpo: 16865 +.. date: 2017-09-29-16-40-38 +.. nonce: l-f6I_ +.. section: Library + +Support arrays >=2GiB in :mod:`ctypes`. Patch by Segev Finer. + +.. + +.. bpo: 31508 +.. date: 2017-09-19-12-38-31 +.. nonce: pDsFJl +.. section: Library + +Removed support of arguments in `tkinter.ttk.Treeview.selection`. It was +deprecated in 3.6. Use specialized methods like `selection_set` for +changing the selection. + +.. + +.. bpo: 29456 +.. date: 2017-08-24-17-55-39 +.. nonce: XaB3MP +.. section: Library + +Fix bugs in hangul normalization: u1176, u11a7 and u11c3 + +.. + +.. bpo: 21257 +.. date: 2019-01-15-21-45-27 +.. nonce: U9LKkx +.. section: Documentation + +Document :func:`http.client.parse_headers`. + +.. + +.. bpo: 34764 +.. date: 2018-12-23-23-52-31 +.. nonce: DwOGeT +.. section: Documentation + +Improve example of iter() with 2nd sentinel argument. + +.. + +.. bpo: 35564 +.. date: 2018-12-22-22-52-05 +.. nonce: TuEU_D +.. section: Documentation + +Explicitly set master_doc variable in conf.py for compliance with Sphinx 2.0 + +.. + +.. bpo: 35511 +.. date: 2018-12-16-16-14-44 +.. nonce: iVcyav +.. section: Documentation + +Specified that profile.Profile class doesn't not support enable or disable +methods. Also, elaborated that Profile object as a context manager is only +supported in cProfile module. + +.. + +.. bpo: 10536 +.. date: 2018-11-04-22-03-56 +.. nonce: a0IsfE +.. section: Documentation + +Enhance the gettext docs. Patch by Éric Araujo + +.. + +.. bpo: 35089 +.. date: 2018-10-28-16-51-31 +.. nonce: _stCpS +.. section: Documentation + +Remove mention of ``typing.io`` and ``typing.re``. Their types should be +imported from ``typing`` directly. + +.. + +.. bpo: 35038 +.. date: 2018-10-25-17-45-09 +.. nonce: 2eVOYS +.. section: Documentation + +Fix the documentation about an unexisting `f_restricted` attribute in the +frame object. Patch by Stéphane Wirtel + +.. + +.. bpo: 35042 +.. date: 2018-10-22-14-17-57 +.. nonce: 1UGv1a +.. section: Documentation + +Replace PEP XYZ by the pep role and allow to use the direct links to the +PEPs. + +.. + +.. bpo: 35044 +.. date: 2018-10-22-14-09-58 +.. nonce: qjvNtI +.. section: Documentation + +Fix the documentation with the role ``exc`` for the appropriated exception. +Patch by Stéphane Wirtel + +.. + +.. bpo: 35035 +.. date: 2018-10-21-02-20-36 +.. nonce: 4zBObK +.. section: Documentation + +Rename documentation for :mod:`email.utils` to ``email.utils.rst``. + +.. + +.. bpo: 34967 +.. date: 2018-10-13-07-39-57 +.. nonce: E40tFP +.. section: Documentation + +Use app.add_object_type() instead of the deprecated Sphinx function +app.description_unit() + +.. + +.. bpo: 34913 +.. date: 2018-10-10-00-34-08 +.. nonce: kVd1Fv +.. section: Documentation + +Add documentation about the new command line interface of the gzip module. + +.. + +.. bpo: 32174 +.. date: 2018-10-08-19-15-28 +.. nonce: YO9CYm +.. section: Documentation + +chm document displays non-ASCII charaters properly on some MBCS Windows +systems. + +.. + +.. bpo: 11233 +.. date: 2018-10-03-20-39-25 +.. nonce: BX6Gen +.. section: Documentation + +Create availability directive for documentation. Original patch by Georg +Brandl. + +.. + +.. bpo: 34790 +.. date: 2018-09-24-12-47-08 +.. nonce: G2KXIH +.. section: Documentation + +Document how passing coroutines to asyncio.wait() can be confusing. + +.. + +.. bpo: 34552 +.. date: 2018-09-12-10-18-04 +.. nonce: p9PoYv +.. section: Documentation + +Make clear that ``==`` operator sometimes is equivalent to `is`. The ``<``, +``<=``, ``>`` and ``>=`` operators are only defined where they make sense. + +.. + +.. bpo: 28617 +.. date: 2018-09-06-22-39-47 +.. nonce: MjnJLz +.. section: Documentation + +Fixed info in the stdtypes docs concerning the types that support membership +tests. + +.. + +.. bpo: 20177 +.. date: 2018-07-28-17-17-42 +.. nonce: cOZJWp +.. section: Documentation + +Migrate datetime.date.fromtimestamp to Argument Clinic. Patch by Tim +Hoffmann. + +.. + +.. bpo: 34065 +.. date: 2018-07-07-20-38-41 +.. nonce: 1snofM +.. section: Documentation + +Fix wrongly written basicConfig documentation markup syntax + +.. + +.. bpo: 33460 +.. date: 2018-06-22-08-38-29 +.. nonce: kHt4D0 +.. section: Documentation + +replaced ellipsis with correct error codes in tutorial chapter 3. + +.. + +.. bpo: 33847 +.. date: 2018-06-15-14-58-45 +.. nonce: IIDp6t +.. section: Documentation + +Add '@' operator entry to index. + +.. + +.. bpo: 33409 +.. date: 2018-06-08-23-46-01 +.. nonce: r4z9MM +.. section: Documentation + +Clarified the relationship between :pep:`538`'s PYTHONCOERCECLOCALE and PEP +540's PYTHONUTF8 mode. + +.. + +.. bpo: 33197 +.. date: 2018-06-08-23-37-14 +.. nonce: OERTKf +.. section: Documentation + +Add versionadded tag to the documentation of ParameterKind.description + +.. + +.. bpo: 17045 +.. date: 2018-06-07-08-33-45 +.. nonce: ZNx6KU +.. section: Documentation + +Improve the C-API doc for PyTypeObject. This includes adding several +quick-reference tables and a lot of missing slot/typedef entries. The +existing entries were also cleaned up with a slightly more consistent +format. + +.. + +.. bpo: 33736 +.. date: 2018-06-01-12-27-40 +.. nonce: JVegIu +.. section: Documentation + +Improve the documentation of :func:`asyncio.open_connection`, +:func:`asyncio.start_server` and their UNIX socket counterparts. + +.. + +.. bpo: 23859 +.. date: 2018-05-29-16-02-31 +.. nonce: E5gba1 +.. section: Documentation + +Document that `asyncio.wait()` does not cancel its futures on timeout. + +.. + +.. bpo: 32436 +.. date: 2018-05-23-11-59-51 +.. nonce: S1LGPa +.. section: Documentation + +Document :pep:`567` changes to asyncio. + +.. + +.. bpo: 33604 +.. date: 2018-05-22-11-47-14 +.. nonce: 5YHTpz +.. section: Documentation + +Update HMAC md5 default to a DeprecationWarning, bump removal to 3.8. + +.. + +.. bpo: 33594 +.. date: 2018-05-21-14-36-12 +.. nonce: -HRcyX +.. section: Documentation + +Document ``getargspec``, ``from_function`` and ``from_builtin`` as +deprecated in their respective docstring, and include version since +deprecation in DeprecationWarning message. + +.. + +.. bpo: 33503 +.. date: 2018-05-14-20-08-58 +.. nonce: Wvt0qg +.. section: Documentation + +Fix broken pypi link + +.. + +.. bpo: 33421 +.. date: 2018-05-14-15-15-41 +.. nonce: 3GU_QO +.. section: Documentation + +Add missing documentation for ``typing.AsyncContextManager``. + +.. + +.. bpo: 33487 +.. date: 2018-05-13-14-44-30 +.. nonce: iLDzFb +.. section: Documentation + +BZ2file now emit a DeprecationWarning when buffering=None is passed, the +deprecation message and documentation also now explicitly state it is +deprecated since 3.0. + +.. + +.. bpo: 33378 +.. date: 2018-04-29-04-02-18 +.. nonce: -anAHN +.. section: Documentation + +Add Korean language switcher for https://docs.python.org/3/ + +.. + +.. bpo: 33276 +.. date: 2018-04-20-14-09-36 +.. nonce: rA1z_3 +.. section: Documentation + +Clarify that the ``__path__`` attribute on modules cannot be just any value. + +.. + +.. bpo: 33201 +.. date: 2018-04-01-21-03-41 +.. nonce: aa8Lkl +.. section: Documentation + +Modernize documentation for writing C extension types. + +.. + +.. bpo: 33195 +.. date: 2018-04-01-14-30-36 +.. nonce: dRS-XX +.. section: Documentation + +Deprecate ``Py_UNICODE`` usage in ``c-api/arg`` document. ``Py_UNICODE`` +related APIs are deprecated since Python 3.3, but it is missed in the +document. + +.. + +.. bpo: 33126 +.. date: 2018-03-28-17-03-17 +.. nonce: 5UGkNv +.. section: Documentation + +Document PyBuffer_ToContiguous(). + +.. + +.. bpo: 27212 +.. date: 2018-03-22-19-23-04 +.. nonce: wrE5KR +.. section: Documentation + +Modify documentation for the :func:`islice` recipe to consume initial values +up to the start index. + +.. + +.. bpo: 28247 +.. date: 2018-03-20-20-11-05 +.. nonce: -V-WS- +.. section: Documentation + +Update :mod:`zipapp` documentation to describe how to make standalone +applications. + +.. + +.. bpo: 18802 +.. date: 2018-03-11-18-53-47 +.. nonce: JhAqH3 +.. section: Documentation + +Documentation changes for ipaddress. Patch by Jon Foster and Berker Peksag. + +.. + +.. bpo: 27428 +.. date: 2018-03-11-00-16-56 +.. nonce: B7A8FT +.. section: Documentation + +Update documentation to clarify that ``WindowsRegistryFinder`` implements +``MetaPathFinder``. (Patch by Himanshu Lakhara) + +.. + +.. bpo: 28124 +.. date: 2018-02-25-16-33-35 +.. nonce: _uzkgq +.. section: Documentation + +The ssl module function ssl.wrap_socket() has been de-emphasized and +deprecated in favor of the more secure and efficient +SSLContext.wrap_socket() method. + +.. + +.. bpo: 17232 +.. date: 2018-02-23-12-48-03 +.. nonce: tmuTKL +.. section: Documentation + +Clarify docs for -O and -OO. Patch by Terry Reedy. + +.. + +.. bpo: 32436 +.. date: 2018-02-14-11-10-41 +.. nonce: TTJ2jb +.. section: Documentation + +Add documentation for the contextvars module (PEP 567). + +.. + +.. bpo: 32800 +.. date: 2018-02-10-15-16-04 +.. nonce: FyrqCk +.. section: Documentation + +Update link to w3c doc for xml default namespaces. + +.. + +.. bpo: 11015 +.. date: 2018-02-10-12-48-38 +.. nonce: -gUf34 +.. section: Documentation + +Update :mod:`test.support` documentation. + +.. + +.. bpo: 32613 +.. date: 2018-02-05-15-05-53 +.. nonce: TDjgM1 +.. section: Documentation + +Update the faq/windows.html to use the py command from PEP 397 instead of +python. + +.. + +.. bpo: 8722 +.. date: 2018-02-03-06-11-37 +.. nonce: MPyVyj +.. section: Documentation + +Document :meth:`__getattr__` behavior when property :meth:`get` method +raises :exc:`AttributeError`. + +.. + +.. bpo: 32614 +.. date: 2018-02-02-07-41-57 +.. nonce: LSqzGw +.. section: Documentation + +Modify RE examples in documentation to use raw strings to prevent +:exc:`DeprecationWarning` and add text to REGEX HOWTO to highlight the +deprecation. + +.. + +.. bpo: 20709 +.. date: 2018-02-01-10-57-24 +.. nonce: 1flcnc +.. section: Documentation + +Remove the paragraph where we explain that os.utime() does not support a +directory as path under Windows. Patch by Jan-Philip Gehrcke + +.. + +.. bpo: 32722 +.. date: 2018-01-30-11-28-27 +.. nonce: frdp6A +.. section: Documentation + +Remove the bad example in the tutorial of the Generator Expression. Patch by +Stéphane Wirtel + +.. + +.. bpo: 31972 +.. date: 2018-01-25-14-23-12 +.. nonce: w1m_8r +.. section: Documentation + +Improve docstrings for `pathlib.PurePath` subclasses. + +.. + +.. bpo: 30607 +.. date: 2018-01-25-13-58-49 +.. nonce: 4dXxiq +.. section: Documentation + +Use the externalized ``python-docs-theme`` package when building the +documentation. + +.. + +.. bpo: 8243 +.. date: 2018-01-13-20-30-53 +.. nonce: s98r28 +.. section: Documentation + +Add a note about curses.addch and curses.addstr exception behavior when +writing outside a window, or pad. + +.. + +.. bpo: 32337 +.. date: 2017-12-22-17-29-37 +.. nonce: eZe-ID +.. section: Documentation + +Update documentation related with ``dict`` order. + +.. + +.. bpo: 25041 +.. date: 2017-10-23-13-41-12 +.. nonce: iAo2gW +.. section: Documentation + +Document ``AF_PACKET`` in the :mod:`socket` module. + +.. + +.. bpo: 31432 +.. date: 2017-09-13-07-14-59 +.. nonce: yAY4Z3 +.. section: Documentation + +Clarify meaning of CERT_NONE, CERT_OPTIONAL, and CERT_REQUIRED flags for +ssl.SSLContext.verify_mode. + +.. + +.. bpo: 35772 +.. date: 2019-01-18-12-19-19 +.. nonce: sGBbsn +.. section: Tests + +Fix sparse file tests of test_tarfile on ppc64 with the tmpfs filesystem. +Fix the function testing if the filesystem supports sparse files: create a +file which contains data and "holes", instead of creating a file which +contains no data. tmpfs effective block size is a page size (tmpfs lives in +the page cache). RHEL uses 64 KiB pages on aarch64, ppc64, ppc64le, only +s390x and x86_64 use 4 KiB pages, whereas the test punch holes of 4 KiB. + +.. + +.. bpo: 35045 +.. date: 2019-01-10-18-35-42 +.. nonce: qdd6d9 +.. section: Tests + +Make ssl tests less strict and also accept TLSv1 as system default. The +changes unbreaks test_min_max_version on Fedora 29. + +.. + +.. bpo: 32710 +.. date: 2019-01-07-23-34-41 +.. nonce: Hzo1b8 +.. section: Tests + +``test_asyncio/test_sendfile.py`` now resets the event loop policy using +:func:`tearDownModule` as done in other tests, to prevent a warning when +running tests on Windows. + +.. + +.. bpo: 33717 +.. date: 2019-01-07-23-22-44 +.. nonce: GhHXv8 +.. section: Tests + +test.pythoninfo now logs information of all clocks, not only time.time() and +time.perf_counter(). + +.. + +.. bpo: 35488 +.. date: 2019-01-04-21-34-53 +.. nonce: U7JJzP +.. section: Tests + +Add a test to pathlib's Path.match() to verify it does not support +glob-style ** recursive pattern matching. + +.. + +.. bpo: 31731 +.. date: 2018-12-18-23-20-39 +.. nonce: tcv85C +.. section: Tests + +Fix a race condition in ``check_interrupted_write()`` of test_io: create +directly the thread with SIGALRM signal blocked, rather than blocking the +signal later from the thread. Previously, it was possible that the thread +gets the signal before the signal is blocked. + +.. + +.. bpo: 35424 +.. date: 2018-12-18-22-36-53 +.. nonce: 1Pz4IS +.. section: Tests + +Fix test_multiprocessing_main_handling: use :class:`multiprocessing.Pool` +with a context manager and then explicitly join the pool. + +.. + +.. bpo: 35519 +.. date: 2018-12-17-16-41-45 +.. nonce: RR3L_w +.. section: Tests + +Rename :mod:`test.bisect` module to :mod:`test.bisect_cmd` to avoid conflict +with :mod:`bisect` module when running directly a test like ``./python +Lib/test/test_xmlrpc.py``. + +.. + +.. bpo: 35513 +.. date: 2018-12-16-23-36-47 +.. nonce: k4WHlA +.. section: Tests + +Replace :func:`time.time` with :func:`time.monotonic` in tests to measure +time delta. + +.. + +.. bpo: 34279 +.. date: 2018-12-12-18-20-18 +.. nonce: DhKcuP +.. section: Tests + +:func:`test.support.run_unittest` no longer raise :exc:`TestDidNotRun` if +the test result contains skipped tests. The exception is now only raised if +no test have been run and no test have been skipped. + +.. + +.. bpo: 35412 +.. date: 2018-12-12-18-07-58 +.. nonce: kbuJor +.. section: Tests + +Add testcase to ``test_future4``: check unicode literal. + +.. + +.. bpo: 26704 +.. date: 2018-12-10-13-18-37 +.. nonce: DBAN4c +.. section: Tests + +Added test demonstrating double-patching of an instance method. Patch by +Anthony Sottile. + +.. + +.. bpo: 33725 +.. date: 2018-12-09-01-27-29 +.. nonce: TaGayj +.. section: Tests + +test_multiprocessing_fork may crash on recent versions of macOS. Until the +issue is resolved, skip the test on macOS. + +.. + +.. bpo: 35352 +.. date: 2018-11-30-17-18-56 +.. nonce: 8bD7GC +.. section: Tests + +Modify test_asyncio to use the certificate set from the test directory. + +.. + +.. bpo: 35317 +.. date: 2018-11-26-16-54-21 +.. nonce: jByGP2 +.. section: Tests + +Fix ``mktime()`` overflow error in ``test_email``: run +``test_localtime_daylight_true_dst_true()`` and +``test_localtime_daylight_false_dst_true()`` with a specific timezone. + +.. + +.. bpo: 21263 +.. date: 2018-11-04-20-17-09 +.. nonce: T3qo9r +.. section: Tests + +After several reports that test_gdb does not work properly on macOS and +since gdb is not shipped by default anymore, test_gdb is now skipped on +macOS when LLVM Clang has been used to compile Python. Patch by Lysandros +Nikolaou + +.. + +.. bpo: 34279 +.. date: 2018-10-27-13-41-55 +.. nonce: v0Xqxe +.. section: Tests + +regrtest issue a warning when no tests have been executed in a particular +test file. Also, a new final result state is issued if no test have been +executed across all test files. Patch by Pablo Galindo. + +.. + +.. bpo: 34962 +.. date: 2018-10-11-22-34-27 +.. nonce: 0PLBi8 +.. section: Tests + +make docstest in Doc now passes., and is enforced in CI + +.. + +.. bpo: 23596 +.. date: 2018-10-09-23-51-07 +.. nonce: rdnert +.. section: Tests + +Use argparse for the command line of the gzip module. Patch by Antony Lee + +.. + +.. bpo: 34537 +.. date: 2018-09-21-17-33-41 +.. nonce: GImYtZ +.. section: Tests + +Fix ``test_gdb.test_strings()`` when ``LC_ALL=C`` and GDB was compiled with +Python 3.6 or earlier. + +.. + +.. bpo: 34587 +.. date: 2018-09-13-20-58-07 +.. nonce: rCcxp3 +.. section: Tests + +test_socket: Remove RDSTest.testCongestion(). The test tries to fill the +receiver's socket buffer and expects an error. But the RDS protocol doesn't +require that. Moreover, the Linux implementation of RDS expects that the +producer of the messages reduces its rate, it's not the role of the receiver +to trigger an error. The test fails on Fedora 28 by design, so just remove +it. + +.. + +.. bpo: 34661 +.. date: 2018-09-13-09-53-15 +.. nonce: bdTamP +.. section: Tests + +Fix test_shutil if unzip doesn't support -t. + +.. + +.. bpo: 34200 +.. date: 2018-09-12-17-00-34 +.. nonce: dfxYQK +.. section: Tests + +Fixed non-deterministic flakiness of test_pkg by not using the scary +test.support.module_cleanup() logic to save and restore sys.modules contents +between test cases. + +.. + +.. bpo: 34569 +.. date: 2018-09-09-14-36-59 +.. nonce: okj1Xh +.. section: Tests + +The experimental PEP 554 data channels now correctly pass negative PyLong +objects between subinterpreters on 32-bit systems. Patch by Michael Felt. + +.. + +.. bpo: 34594 +.. date: 2018-09-05-23-50-21 +.. nonce: tqL-GS +.. section: Tests + +Fix usage of hardcoded ``errno`` values in the tests. + +.. + +.. bpo: 34579 +.. date: 2018-09-04-15-16-42 +.. nonce: bp4HdM +.. section: Tests + +Fix test_embed for AIX Patch by Michael Felt + +.. + +.. bpo: 34542 +.. date: 2018-08-29-16-30-52 +.. nonce: 9stVAW +.. section: Tests + +Use 3072 RSA keys and SHA-256 signature for test certs and keys. + +.. + +.. bpo: 11193 +.. date: 2018-08-26-13-12-34 +.. nonce: H8fCGa +.. section: Tests + +Remove special condition for AIX in `test_subprocess.test_undecodable_env` + +.. + +.. bpo: 34347 +.. date: 2018-08-25-13-28-18 +.. nonce: IsRDPB +.. section: Tests + +Fix `test_utf8_mode.test_cmd_line` for AIX + +.. + +.. bpo: 34490 +.. date: 2018-08-24-20-23-15 +.. nonce: vb2cx4 +.. section: Tests + +On AIX with AF_UNIX family sockets getsockname() does not provide +'sockname', so skip calls to transport.get_extra_info('sockname') + +.. + +.. bpo: 34391 +.. date: 2018-08-16-18-48-47 +.. nonce: ouNfxC +.. section: Tests + +Fix ftplib test for TLS 1.3 by reading from data socket. + +.. + +.. bpo: 11192 +.. date: 2018-08-14-20-50-07 +.. nonce: g7TwYm +.. section: Tests + +Fix `test_socket` on AIX 6.1 and later IPv6 zone id supports only +supported by inet_pton6_zone() Switch to runtime-based platform.system() to +establish current platform rather than build-time based sys.platform() + +.. + +.. bpo: 34399 +.. date: 2018-08-14-10-47-44 +.. nonce: D_jd1G +.. section: Tests + +Update all RSA keys and DH params to use at least 2048 bits. + +.. + +.. bpo: 34373 +.. date: 2018-08-10-16-17-51 +.. nonce: SKdb1k +.. section: Tests + +Fix ``test_mktime`` and ``test_pthread_getcpuclickid`` tests for AIX Add +range checking for ``_PyTime_localtime`` for AIX Patch by Michael Felt + +.. + +.. bpo: 11191 +.. date: 2018-08-08-22-41-30 +.. nonce: eq9tSH +.. section: Tests + +Skip the distutils test 'test_search_cpp' when using XLC as compiler patch +by aixtools (Michael Felt) + +.. + +.. bpo: 0 +.. date: 2018-07-10-18-53-46 +.. nonce: UBQJBc +.. section: Tests + +Improved an error message when mock assert_has_calls fails. + +.. + +.. bpo: 33746 +.. date: 2018-06-19-17-55-46 +.. nonce: Sz7avn +.. section: Tests + +Fix test_unittest when run in verbose mode. + +.. + +.. bpo: 33901 +.. date: 2018-06-19-14-04-21 +.. nonce: OFW1Sr +.. section: Tests + +Fix test_dbm_gnu on macOS with gdbm 1.15: add a larger value to make sure +that the file size changes. + +.. + +.. bpo: 33873 +.. date: 2018-06-16-01-37-31 +.. nonce: d86vab +.. section: Tests + +Fix a bug in ``regrtest`` that caused an extra test to run if +--huntrleaks/-R was used. Exit with error in case that invalid parameters +are specified to --huntrleaks/-R (at least one warmup run and one repetition +must be used). + +.. + +.. bpo: 33562 +.. date: 2018-06-01-14-25-31 +.. nonce: GutEHf +.. section: Tests + +Check that a global asyncio event loop policy is not left behind by any +tests. + +.. + +.. bpo: 33655 +.. date: 2018-05-26-16-01-40 +.. nonce: Frb4LA +.. section: Tests + +Ignore test_posix_fallocate failures on BSD platforms that might be due to +running on ZFS. + +.. + +.. bpo: 32962 +.. date: 2018-05-10-16-59-15 +.. nonce: S-rcIN +.. section: Tests + +Fixed test_gdb when Python is compiled with flags -mcet -fcf-protection -O0. + +.. + +.. bpo: 33358 +.. date: 2018-04-27-11-46-35 +.. nonce: _OcR59 +.. section: Tests + +Fix ``test_embed.test_pre_initialization_sys_options()`` when the +interpreter is built with ``--enable-shared``. + +.. + +.. bpo: 32872 +.. date: 2018-03-28-01-35-02 +.. nonce: J5NDUj +.. section: Tests + +Avoid regrtest compatibility issue with namespace packages. + +.. + +.. bpo: 32517 +.. date: 2018-03-09-07-05-12 +.. nonce: ugc1iW +.. section: Tests + +Fix failing ``test_asyncio`` on macOS 10.12.2+ due to transport of +``KqueueSelector`` loop was not being closed. + +.. + +.. bpo: 32663 +.. date: 2018-01-25-18-10-47 +.. nonce: IKDsqu +.. section: Tests + +Making sure the `SMTPUTF8SimTests` class of tests gets run in +test_smtplib.py. + +.. + +.. bpo: 27643 +.. date: 2018-01-12-09-05-19 +.. nonce: _6z49y +.. section: Tests + +Test_C test case needs "signed short" bitfields, but the IBM XLC compiler +(on AIX) does not support this Skip the code and test when AIX and XLC are +used + +Applicable to Python2-2.7 and later + +.. + +.. bpo: 19417 +.. date: 2018-01-08-13-33-47 +.. nonce: 2asoXy +.. section: Tests + +Add test_bdb.py. + +.. + +.. bpo: 31809 +.. date: 2017-10-18-18-07-45 +.. nonce: KlQrkE +.. section: Tests + +Add tests to verify connection with secp ECDH curves. + +.. + +.. bpo: 34691 +.. date: 2019-02-02-13-34-05 +.. nonce: B-Lsj4 +.. section: Build + +The _contextvars module is now built into the core Python library on +Windows. + +.. + +.. bpo: 35683 +.. date: 2019-01-10-11-37-18 +.. nonce: pf5Oos +.. section: Build + +Improved Azure Pipelines build steps and now verifying layouts correctly + +.. + +.. bpo: 35642 +.. date: 2019-01-02-11-23-33 +.. nonce: pjkhJe +.. section: Build + +Remove asynciomodule.c from pythoncore.vcxproj + +.. + +.. bpo: 35550 +.. date: 2018-12-29-10-19-43 +.. nonce: BTuu8e +.. section: Build + +Fix incorrect Solaris #ifdef checks to look for __sun && __SVR4 instead of +sun when compiling. + +.. + +.. bpo: 35499 +.. date: 2018-12-14-19-36-05 +.. nonce: 9yAldM +.. section: Build + +``make profile-opt`` no longer replaces ``CFLAGS_NODIST`` with ``CFLAGS``. +It now adds profile-guided optimization (PGO) flags to ``CFLAGS_NODIST``: +existing ``CFLAGS_NODIST`` flags are kept. + +.. + +.. bpo: 35257 +.. date: 2018-12-05-22-28-40 +.. nonce: dmcd_s +.. section: Build + +Avoid leaking the linker flags from Link Time Optimizations (LTO) into +distutils when compiling C extensions. + +.. + +.. bpo: 35351 +.. date: 2018-12-04-15-33-28 +.. nonce: ZhhBfT +.. section: Build + +When building Python with clang and LTO, LTO flags are no longer passed into +CFLAGS to build third-party C extensions through distutils. + +.. + +.. bpo: 35139 +.. date: 2018-11-01-15-01-23 +.. nonce: XZTttb +.. section: Build + +Fix a compiler error when statically linking `pyexpat` in `Modules/Setup`. + +.. + +.. bpo: 35059 +.. date: 2018-10-26-14-49-19 +.. nonce: PKsBxP +.. section: Build + +PCbuild: Set InlineFunctionExpansion to OnlyExplicitInline ("/Ob1" option) +in pyproject.props in Debug mode to expand functions marked as inline. This +change should make Python compiled in Debug mode a little bit faster on +Windows. + +.. + +.. bpo: 35011 +.. date: 2018-10-17-17-38-57 +.. nonce: GgoPIC +.. section: Build + +Restores the use of pyexpatns.h to isolate our embedded copy of the expat C +library so that its symbols do not conflict at link or dynamic loading time +with an embedding application or other extension modules with their own +version of libexpat. + +.. + +.. bpo: 28015 +.. date: 2018-10-16-12-22-36 +.. nonce: ylSgFh +.. section: Build + +Have --with-lto works correctly with clang. + +.. + +.. bpo: 34765 +.. date: 2018-09-26-17-29-10 +.. nonce: AvxdVj +.. section: Build + +Update the outdated install-sh file to the latest revision from automake +v1.16.1 + +.. + +.. bpo: 34585 +.. date: 2018-09-18-16-28-31 +.. nonce: CGMu0h +.. section: Build + +Check for floating-point byte order in configure.ac using compilation tests +instead of executing code, so that these checks work in cross-compiled +builds. + +.. + +.. bpo: 34710 +.. date: 2018-09-17-13-56-12 +.. nonce: ARqIAK +.. section: Build + +Fixed SSL module build with OpenSSL & pedantic CFLAGS. + +.. + +.. bpo: 34582 +.. date: 2018-09-14-09-53-21 +.. nonce: j3omgk +.. section: Build + +Add JUnit XML output for regression tests and update Azure DevOps builds. + +.. + +.. bpo: 34081 +.. date: 2018-09-06-07-15-20 +.. nonce: cuSTnH +.. section: Build + +Make Sphinx warnings as errors in the Docs Makefile. + +.. + +.. bpo: 34555 +.. date: 2018-08-31-19-41-09 +.. nonce: dfQcnm +.. section: Build + +Fix for case where it was not possible to have both +``HAVE_LINUX_VM_SOCKETS_H`` and ``HAVE_SOCKADDR_ALG`` be undefined. + +.. + +.. bpo: 33015 +.. date: 2018-08-24-09-48-25 +.. nonce: s21y74 +.. section: Build + +Fix an undefined behaviour in the pthread implementation of +:c:func:`PyThread_start_new_thread`: add a function wrapper to always return +``NULL``. + +.. + +.. bpo: 34245 +.. date: 2018-07-27-09-52-48 +.. nonce: bBV0NI +.. section: Build + +The Python shared library is now installed with write permission (mode +0755), which is the standard way of installing such libraries. + +.. + +.. bpo: 34121 +.. date: 2018-07-15-16-49-06 +.. nonce: 74G_lo +.. section: Build + +Fix detection of C11 atomic support on clang. + +.. + +.. bpo: 32430 +.. date: 2018-07-10-21-33-25 +.. nonce: UN3Nk8 +.. section: Build + +Rename Modules/Setup.dist to Modules/Setup, and remove the necessity to copy +the former manually to the latter when updating the local source tree. + +.. + +.. bpo: 30345 +.. date: 2018-06-15-18-18-16 +.. nonce: j-xRE1 +.. section: Build + +Add -g to LDFLAGS when compiling with LTO to get debug symbols. + +.. + +.. bpo: 5755 +.. date: 2018-06-04-21-34-34 +.. nonce: 65GmCj +.. section: Build + +Move ``-Wstrict-prototypes`` option to ``CFLAGS_NODIST`` from ``OPT``. This +option emitted annoying warnings when building extension modules written in +C++. + +.. + +.. bpo: 33614 +.. date: 2018-05-28-11-40-22 +.. nonce: 28e0sE +.. section: Build + +Ensures module definition files for the stable ABI on Windows are correctly +regenerated. + +.. + +.. bpo: 33648 +.. date: 2018-05-25-13-05-51 +.. nonce: bJ4JZH +.. section: Build + +The --with-c-locale-warning configuration flag has been removed. It has had +no effect for about a year. + +.. + +.. bpo: 33522 +.. date: 2018-05-15-12-44-50 +.. nonce: mJoNcA +.. section: Build + +Enable CI builds on Visual Studio Team Services at +https://python.visualstudio.com/cpython + +.. + +.. bpo: 33512 +.. date: 2018-05-15-02-07-49 +.. nonce: X4Fy1Q +.. section: Build + +configure's check for "long double" has been simplified + +.. + +.. bpo: 33483 +.. date: 2018-05-13-17-21-54 +.. nonce: WOs-en +.. section: Build + +C compiler is now correctly detected from the standard environment +variables. --without-gcc and --with-icc options have been removed. + +.. + +.. bpo: 33394 +.. date: 2018-04-30-17-36-46 +.. nonce: _Vdi4t +.. section: Build + +Enable the verbose build for extension modules, when GNU make is passed +macros on the command line. + +.. + +.. bpo: 33393 +.. date: 2018-04-30-17-19-37 +.. nonce: HkVCqI +.. section: Build + +Update config.guess and config.sub files. + +.. + +.. bpo: 33377 +.. date: 2018-04-30-16-53-00 +.. nonce: QBh6vP +.. section: Build + +Add new triplets for mips r6 and riscv variants (used in extension +suffixes). + +.. + +.. bpo: 32232 +.. date: 2018-04-17-00-38-19 +.. nonce: o7G_UO +.. section: Build + +By default, modules configured in `Modules/Setup` are no longer built with +`-DPy_BUILD_CORE`. Instead, modules that specifically need that preprocessor +definition include it in their individual entries. + +.. + +.. bpo: 33182 +.. date: 2018-03-30-14-55-48 +.. nonce: CePczb +.. section: Build + +The embedding tests can once again be built with clang 6.0 + +.. + +.. bpo: 33163 +.. date: 2018-03-28-04-15-03 +.. nonce: hfpWuU +.. section: Build + +Upgrade pip to 9.0.3 and setuptools to v39.0.1. + +.. + +.. bpo: 33012 +.. date: 2018-03-08-20-25-29 +.. nonce: k9Fe1q +.. section: Build + +gcc 8 has added a new warning heuristic to detect invalid function casts and +a stock python build seems to hit that warning quite often. The most common +is the cast of a METH_NOARGS function (that uses just one argument) to a +PyCFunction. Fix this by adding a dummy argument to all functions that +implement METH_NOARGS. + +.. + +.. bpo: 32898 +.. date: 2018-02-21-12-46-00 +.. nonce: M15bZh +.. section: Build + +Fix the python debug build when using COUNT_ALLOCS. + +.. + +.. bpo: 29442 +.. date: 2017-09-26-23-08-27 +.. nonce: fD8YTi +.. section: Build + +Replace optparse with argparse in setup.py + +.. + +.. bpo: 35890 +.. date: 2019-02-02-22-12-23 +.. nonce: ccIjHH +.. section: Windows + +Fix API calling consistency of GetVersionEx and wcstok. + +.. + +.. bpo: 32560 +.. date: 2019-02-02-11-02-44 +.. nonce: I5WAGW +.. section: Windows + +The ``py`` launcher now forwards its ``STARTUPINFO`` structure to child +processes. + +.. + +.. bpo: 35854 +.. date: 2019-01-29-15-44-46 +.. nonce: Ww3z19 +.. section: Windows + +Fix EnvBuilder and --symlinks in venv on Windows + +.. + +.. bpo: 35811 +.. date: 2019-01-25-12-46-36 +.. nonce: 2hU-mm +.. section: Windows + +Avoid propagating venv settings when launching via py.exe + +.. + +.. bpo: 35797 +.. date: 2019-01-25-12-29-14 +.. nonce: MzyOK9 +.. section: Windows + +Fix default executable used by the multiprocessing module + +.. + +.. bpo: 35758 +.. date: 2019-01-21-05-18-14 +.. nonce: 8LsY3l +.. section: Windows + +Allow building on ARM with MSVC. + +.. + +.. bpo: 29734 +.. date: 2019-01-12-16-52-38 +.. nonce: 6_OJwI +.. section: Windows + +Fix handle leaks in os.stat on Windows. + +.. + +.. bpo: 35596 +.. date: 2019-01-08-13-56-01 +.. nonce: oFvhcm +.. section: Windows + +Use unchecked PYCs for the embeddable distro to avoid zipimport +restrictions. + +.. + +.. bpo: 35596 +.. date: 2018-12-28-07-25-47 +.. nonce: P9CEY2 +.. section: Windows + +Fix vcruntime140.dll being added to embeddable distro multiple times. + +.. + +.. bpo: 35402 +.. date: 2018-12-13-13-30-04 +.. nonce: n_mXb2 +.. section: Windows + +Update Windows build to use Tcl and Tk 8.6.9 + +.. + +.. bpo: 35401 +.. date: 2018-12-10-15-01-13 +.. nonce: 9L1onG +.. section: Windows + +Updates Windows build to OpenSSL 1.1.0j + +.. + +.. bpo: 34977 +.. date: 2018-12-07-10-00-38 +.. nonce: agQJbD +.. section: Windows + +venv on Windows will now use a python.exe redirector rather than copying the +actual binaries from the base environment. + +.. + +.. bpo: 34977 +.. date: 2018-10-30-13-39-17 +.. nonce: 0l7_QV +.. section: Windows + +Adds support for building a Windows App Store package + +.. + +.. bpo: 35067 +.. date: 2018-10-25-11-29-22 +.. nonce: RHWi7W +.. section: Windows + +Remove _distutils_findvs module and use vswhere.exe instead. + +.. + +.. bpo: 32557 +.. date: 2018-09-25-10-39-27 +.. nonce: Rs1bf9 +.. section: Windows + +Allow shutil.disk_usage to take a file path on Windows + +.. + +.. bpo: 34770 +.. date: 2018-09-22-11-02-35 +.. nonce: 4lEUOd +.. section: Windows + +Fix a possible null pointer dereference in pyshellext.cpp. + +.. + +.. bpo: 34603 +.. date: 2018-09-13-08-29-04 +.. nonce: 2AB7sc +.. section: Windows + +Fix returning structs from functions produced by MSVC + +.. + +.. bpo: 34581 +.. date: 2018-09-04-23-13-19 +.. nonce: lnbC0k +.. section: Windows + +Guard MSVC-specific code in socketmodule.c with ``#ifdef _MSC_VER``. + +.. + +.. bpo: 34532 +.. date: 2018-09-03-01-23-52 +.. nonce: N1HEbE +.. section: Windows + +Fixes exit code of list version arguments for py.exe. + +.. + +.. bpo: 34062 +.. date: 2018-08-21-19-28-23 +.. nonce: 3gxsA3 +.. section: Windows + +Fixed the '--list' and '--list-paths' arguments for the py.exe launcher + +.. + +.. bpo: 34225 +.. date: 2018-07-25-16-13-12 +.. nonce: ngemNL +.. section: Windows + +Ensure INCLUDE and LIB directories do not end with a backslash. + +.. + +.. bpo: 34011 +.. date: 2018-07-11-15-58-06 +.. nonce: Ho_d5T +.. section: Windows + +A suite of code has been changed which copied across DLLs and init.tcl from +the running Python location into a venv being created. These copies are +needed only when running from a Python source build, and the copying code is +now only run when that is the case, rather than whenever a venv is created. + +.. + +.. bpo: 34006 +.. date: 2018-07-02-14-19-32 +.. nonce: 7SgBT_ +.. section: Windows + +Revert line length limit for Windows help docs. The line-length limit is not +needed because the pages appear in a separate app rather than on a browser +tab. It can also interact badly with the DPI setting. + +.. + +.. bpo: 31546 +.. date: 2018-06-27-23-33-54 +.. nonce: zJlap- +.. section: Windows + +Restore running PyOS_InputHook while waiting for user input at the prompt. +The restores integration of interactive GUI windows (such as Matplotlib +figures) with the prompt on Windows. + +.. + +.. bpo: 30237 +.. date: 2018-06-25-09-33-48 +.. nonce: EybiZA +.. section: Windows + +Output error when ReadConsole is canceled by CancelSynchronousIo instead of +crashing. + +.. + +.. bpo: 33895 +.. date: 2018-06-19-11-57-50 +.. nonce: zpblTy +.. section: Windows + +GIL is released while calling functions that acquire Windows loader lock. + +.. + +.. bpo: 33720 +.. date: 2018-06-04-09-20-53 +.. nonce: VKDXHK +.. section: Windows + +Reduces maximum marshal recursion depth on release builds. + +.. + +.. bpo: 29097 +.. date: 2018-05-16-11-31-17 +.. nonce: 9mqEuI +.. section: Windows + +Fix bug where :meth:`datetime.fromtimestamp` erroneously throws an +:exc:`OSError` on Windows for values between 0 and 86400. Patch by Ammar +Askar. + +.. + +.. bpo: 33316 +.. date: 2018-04-20-03-24-07 +.. nonce: 9IiJ8J +.. section: Windows + +PyThread_release_lock always fails + +.. + +.. bpo: 33184 +.. date: 2018-04-13-11-28-55 +.. nonce: 7YhqQE +.. section: Windows + +Update Windows installer to use OpenSSL 1.1.0h. + +.. + +.. bpo: 32890 +.. date: 2018-03-08-20-02-38 +.. nonce: 3jzFzY +.. section: Windows + +Fix usage of GetLastError() instead of errno in os.execve() and +os.truncate(). + +.. + +.. bpo: 33016 +.. date: 2018-03-07-01-33-33 +.. nonce: Z_Med0 +.. section: Windows + +Fix potential use of uninitialized memory in nt._getfinalpathname + +.. + +.. bpo: 32903 +.. date: 2018-02-28-11-03-24 +.. nonce: 1SXY4t +.. section: Windows + +Fix a memory leak in os.chdir() on Windows if the current directory is set +to a UNC path. + +.. + +.. bpo: 32901 +.. date: 2018-02-23-00-47-13 +.. nonce: mGKz5_ +.. section: Windows + +Update Tcl and Tk versions to 8.6.8 + +.. + +.. bpo: 31966 +.. date: 2018-02-19-13-54-42 +.. nonce: _Q3HPb +.. section: Windows + +Fixed WindowsConsoleIO.write() for writing empty data. + +.. + +.. bpo: 32409 +.. date: 2018-02-19-10-00-57 +.. nonce: nocuDg +.. section: Windows + +Ensures activate.bat can handle Unicode contents. + +.. + +.. bpo: 32457 +.. date: 2018-02-19-08-54-06 +.. nonce: vVP0Iz +.. section: Windows + +Improves handling of denormalized executable path when launching Python. + +.. + +.. bpo: 32370 +.. date: 2018-02-10-15-38-19 +.. nonce: kcKuct +.. section: Windows + +Use the correct encoding for ipconfig output in the uuid module. Patch by +Segev Finer. + +.. + +.. bpo: 29248 +.. date: 2018-02-07-17-50-48 +.. nonce: Xzwj-6 +.. section: Windows + +Fix :func:`os.readlink` on Windows, which was mistakenly treating the +``PrintNameOffset`` field of the reparse data buffer as a number of +characters instead of bytes. Patch by Craig Holmquist and SSE4. + +.. + +.. bpo: 1104 +.. date: 2017-11-24-12-53-54 +.. nonce: 1CWSZp +.. section: Windows + +Correctly handle string length in ``msilib.SummaryInfo.GetProperty()`` to +prevent it from truncating the last character. + +.. + +.. bpo: 35401 +.. date: 2018-12-09-13-56-49 +.. nonce: n8B7X1 +.. section: macOS + +Update macOS installer to use OpenSSL 1.1.0j. + +.. + +.. bpo: 35025 +.. date: 2018-10-18-23-54-55 +.. nonce: X4LFJg +.. section: macOS + +Properly guard the use of the ``CLOCK_GETTIME`` et al. macros in +``timemodule`` on macOS. + +.. + +.. bpo: 24658 +.. date: 2018-10-17-14-36-08 +.. nonce: Naddgx +.. section: macOS + +On macOS, fix reading from and writing into a file with a size larger than 2 +GiB. + +.. + +.. bpo: 34405 +.. date: 2018-09-11-08-30-55 +.. nonce: UzIi0n +.. section: macOS + +Update to OpenSSL 1.1.0i for macOS installer builds. + +.. + +.. bpo: 33635 +.. date: 2018-07-31-09-51-01 +.. nonce: KiscE- +.. section: macOS + +In macOS stat on some file descriptors (/dev/fd/3 f.e) will result in bad +file descriptor OSError. Guard against this exception was added in is_dir, +is_file and similar methods. DirEntry.is_dir can also throw this exception +so _RecursiveWildcardSelector._iterate_directories was also extended with +the same error ignoring pattern. + +.. + +.. bpo: 13631 +.. date: 2018-05-16-13-25-58 +.. nonce: UIjDyY +.. section: macOS + +The .editrc file in user's home directory is now processed correctly during +the readline initialization through editline emulation on macOS. + +.. + +.. bpo: 33184 +.. date: 2018-04-07-00-51-34 +.. nonce: 3j208P +.. section: macOS + +Update macOS installer build to use OpenSSL 1.1.0h. + +.. + +.. bpo: 32726 +.. date: 2018-03-29-06-56-12 +.. nonce: urS9uX +.. section: macOS + +Build and link with private copy of Tcl/Tk 8.6 for the macOS 10.6+ +installer. The 10.9+ installer variant already does this. This means that +the Python 3.7 provided by the python.org macOS installers no longer need or +use any external versions of Tcl/Tk, either system-provided or +user-installed, such as ActiveTcl. + +.. + +.. bpo: 32901 +.. date: 2018-02-27-17-33-15 +.. nonce: hQu0w3 +.. section: macOS + +Update macOS 10.9+ installer to Tcl/Tk 8.6.8. + +.. + +.. bpo: 31903 +.. date: 2017-11-01-16-53-12 +.. nonce: K6jCVG +.. section: macOS + +In :mod:`_scproxy`, drop the GIL when calling into ``SystemConfiguration`` +to avoid deadlocks. + +.. + +.. bpo: 35770 +.. date: 2019-01-18-13-04-30 +.. nonce: 2LxJGu +.. section: IDLE + +IDLE macosx deletes Options => Configure IDLE. It previously deleted Window +=> Zoom Height by mistake. (Zoom Height is now on the Options menu). On +Mac, the settings dialog is accessed via Preferences on the IDLE menu. + +.. + +.. bpo: 35769 +.. date: 2019-01-18-01-24-23 +.. nonce: GqsB34 +.. section: IDLE + +Change IDLE's new file name from 'Untitled' to 'untitled' + +.. + +.. bpo: 35660 +.. date: 2019-01-04-19-14-29 +.. nonce: hMxI7N +.. section: IDLE + +Fix imports in idlelib.window. + +.. + +.. bpo: 35641 +.. date: 2019-01-02-22-15-01 +.. nonce: QEaANl +.. section: IDLE + +Proper format `calltip` when the function has no docstring. + +.. + +.. bpo: 33987 +.. date: 2018-12-31-17-04-18 +.. nonce: fD92up +.. section: IDLE + +Use ttk Frame for ttk widgets. + +.. + +.. bpo: 34055 +.. date: 2018-12-28-17-16-33 +.. nonce: TmmpzR +.. section: IDLE + +Fix erroneous 'smart' indents and newlines in IDLE Shell. + +.. + +.. bpo: 35591 +.. date: 2018-12-28-01-19-20 +.. nonce: SFpDj2 +.. section: IDLE + +Find Selection now works when selection not found. + +.. + +.. bpo: 35196 +.. date: 2018-12-27-17-46-42 +.. nonce: 9E-xUh +.. section: IDLE + +Speed up squeezer line counting. + +.. + +.. bpo: 35598 +.. date: 2018-12-27-15-29-11 +.. nonce: FWOOm8 +.. section: IDLE + +Update config_key: use PEP 8 names and ttk widgets, make some objects +global, and add tests. + +.. + +.. bpo: 28097 +.. date: 2018-12-26-13-53-34 +.. nonce: 95I9NT +.. section: IDLE + +Add Previous/Next History entries to Shell menu. + +.. + +.. bpo: 35208 +.. date: 2018-12-23-17-42-11 +.. nonce: J5NOg7 +.. section: IDLE + +Squeezer now properly counts wrapped lines before newlines. + +.. + +.. bpo: 35555 +.. date: 2018-12-21-18-44-30 +.. nonce: M58_K3 +.. section: IDLE + +Gray out Code Context menu entry when it's not applicable. + +.. + +.. bpo: 35521 +.. date: 2018-12-20-00-14-15 +.. nonce: x32BRn +.. section: IDLE + +Document the IDLE editor code context feature. Add some internal references +within the IDLE doc. + +.. + +.. bpo: 22703 +.. date: 2018-12-18-13-56-31 +.. nonce: UlsjKQ +.. section: IDLE + +The Code Context menu label now toggles between Show/Hide Code Context. The +Zoom Height menu now toggles between Zoom/Restore Height. Zoom Height has +moved from the Window menu to the Options menu. + +.. + +.. bpo: 35213 +.. date: 2018-11-12-00-20-01 +.. nonce: cqNgzT +.. section: IDLE + +Where appropriate, use 'macOS' in idlelib. + +.. + +.. bpo: 34864 +.. date: 2018-11-11-17-13-50 +.. nonce: cw0PvO +.. section: IDLE + +On macOS, warn if the system preference "Prefer tabs when opening documents" +is set to "Always". + +.. + +.. bpo: 34864 +.. date: 2018-11-10-21-27-25 +.. nonce: Ci-G2q +.. section: IDLE + +Document two IDLE on MacOS issues. The System Preferences Dock "prefer tabs +always" setting disables some IDLE features. Menus are a bit different than +as described for Windows and Linux. + +.. + +.. bpo: 35202 +.. date: 2018-11-10-09-10-54 +.. nonce: TeJJrt +.. section: IDLE + +Remove unused imports from lib/idlelib + +.. + +.. bpo: 33000 +.. date: 2018-11-06-23-10-54 +.. nonce: pQasCt +.. section: IDLE + +Document that IDLE's shell has no line limit. A program that runs +indefinitely can overfill memory. + +.. + +.. bpo: 23220 +.. date: 2018-11-05-23-23-00 +.. nonce: H3SAWE +.. section: IDLE + +Explain how IDLE's Shell displays output. + +.. + +.. bpo: 35099 +.. date: 2018-11-05-20-43-08 +.. nonce: SVOZXC +.. section: IDLE + +Improve the doc about IDLE running user code. The section is renamed from +"IDLE -- console differences" is renamed "Running user code". It mostly +covers the implications of using custom :samp:`sys.std{xxx}` objects. + +.. + +.. bpo: 35097 +.. date: 2018-10-28-20-17-14 +.. nonce: 07tm66 +.. section: IDLE + +Add IDLE doc subsection explaining editor windows. Topics include opening, +title and status bar, .py* extension, and running. + +.. + +.. bpo: 35093 +.. date: 2018-10-28-15-53-51 +.. nonce: cH-tli +.. section: IDLE + +Document the IDLE document viewer in the IDLE doc. Add a paragraph in "Help +and preferences", "Help sources" subsection. + +.. + +.. bpo: 35088 +.. date: 2018-10-28-00-54-32 +.. nonce: r1lJZd +.. section: IDLE + +Update idlelib.help.copy_string docstring. We now use git and backporting +instead of hg and forward merging. + +.. + +.. bpo: 35087 +.. date: 2018-10-28-00-08-42 +.. nonce: G7gx2- +.. section: IDLE + +Update idlelib help files for the current doc build. The main change is the +elimination of chapter-section numbers. + +.. + +.. bpo: 34548 +.. date: 2018-09-22-20-25-07 +.. nonce: 7pBzjg +.. section: IDLE + +Use configured color theme for read-only text views. + +.. + +.. bpo: 1529353 +.. date: 2018-08-13-16-31-24 +.. nonce: wXfQJk +.. section: IDLE + +Enable "squeezing" of long outputs in the shell, to avoid performance +degradation and to clean up the history without losing it. Squeezed outputs +may be copied, viewed in a separate window, and "unsqueezed". + +.. + +.. bpo: 34047 +.. date: 2018-08-05-15-49-55 +.. nonce: LGKsIm +.. section: IDLE + +Fixed mousewheel scrolling direction on macOS. + +.. + +.. bpo: 34275 +.. date: 2018-08-02-22-16-42 +.. nonce: Iu0d7t +.. section: IDLE + +Make IDLE calltips always visible on Mac. Some MacOS-tk combinations need +.update_idletasks(). Patch by Kevin Walzer. + +.. + +.. bpo: 34120 +.. date: 2018-08-01-23-25-38 +.. nonce: HgsIz- +.. section: IDLE + +Fix unresponsiveness after closing certain windows and dialogs. + +.. + +.. bpo: 33975 +.. date: 2018-06-26-22-53-14 +.. nonce: Ow7alv +.. section: IDLE + +Avoid small type when running htests. Since part of the purpose of +human-viewed tests is to determine that widgets look right, it is important +that they look the same for testing as when running IDLE. + +.. + +.. bpo: 33905 +.. date: 2018-06-21-20-35-33 +.. nonce: W2mhiY +.. section: IDLE + +Add test for idlelib.stackview.StackBrowser. + +.. + +.. bpo: 33924 +.. date: 2018-06-20-22-14-07 +.. nonce: 6Rz1wt +.. section: IDLE + +Change mainmenu.menudefs key 'windows' to 'window'. Every other menudef key +is lowercase version of main menu entry. + +.. + +.. bpo: 33906 +.. date: 2018-06-20-19-16-24 +.. nonce: a1lXq0 +.. section: IDLE + +Rename idlelib.windows as window Match Window on the main menu and remove +last plural module name. + +.. + +.. bpo: 33917 +.. date: 2018-06-20-16-27-48 +.. nonce: ZXHs8x +.. section: IDLE + +Fix and document idlelib/idle_test/template.py. The revised file compiles, +runs, and tests OK. idle_test/README.txt explains how to use it to create +new IDLE test files. + +.. + +.. bpo: 33904 +.. date: 2018-06-20-12-40-54 +.. nonce: qm0eCu +.. section: IDLE + +IDLE: In rstrip, rename class RstripExtension as Rstrip + +.. + +.. bpo: 33907 +.. date: 2018-06-19-22-21-27 +.. nonce: z-_B3N +.. section: IDLE + +For consistency and clarity, rename an IDLE module and classes. Module +calltips and its class CallTips are now calltip and Calltip. In module +calltip_w, class CallTip is now CalltipWindow. + +.. + +.. bpo: 33856 +.. date: 2018-06-16-21-54-45 +.. nonce: TH8WHU +.. section: IDLE + +Add "help" in the welcome message of IDLE + +.. + +.. bpo: 33839 +.. date: 2018-06-14-13-23-55 +.. nonce: ZlJzHa +.. section: IDLE + +IDLE: refactor ToolTip and CallTip and add documentation and tests + +.. + +.. bpo: 33855 +.. date: 2018-06-14-11-35-50 +.. nonce: XL230W +.. section: IDLE + +Minimally test all IDLE modules. Add missing files, import module, +instantiate classes, and check coverage. Check existing files. + +.. + +.. bpo: 33656 +.. date: 2018-06-10-17-59-36 +.. nonce: 60ZqJS +.. section: IDLE + +On Windows, add API call saying that tk scales for DPI. On Windows 8.1+ or +10, with DPI compatibility properties of the Python binary unchanged, and a +monitor resolution greater than 96 DPI, this should make text and lines +sharper. It should otherwise have no effect. + +.. + +.. bpo: 33768 +.. date: 2018-06-04-19-23-11 +.. nonce: I_2qpV +.. section: IDLE + +Clicking on a context line moves that line to the top of the editor window. + +.. + +.. bpo: 33763 +.. date: 2018-06-03-20-12-57 +.. nonce: URiFlE +.. section: IDLE + +IDLE: Use read-only text widget for code context instead of label widget. + +.. + +.. bpo: 33664 +.. date: 2018-06-03-09-13-28 +.. nonce: PZzQyL +.. section: IDLE + +Scroll IDLE editor text by lines. Previously, the mouse wheel and scrollbar +slider moved text by a fixed number of pixels, resulting in partial lines at +the top of the editor box. The change also applies to the shell and grep +output windows, but not to read-only text views. + +.. + +.. bpo: 33679 +.. date: 2018-05-29-07-14-37 +.. nonce: MgX_Ui +.. section: IDLE + +Enable theme-specific color configuration for Code Context. Use the +Highlights tab to see the setting for built-in themes or add settings to +custom themes. + +.. + +.. bpo: 33642 +.. date: 2018-05-24-20-42-44 +.. nonce: J0VQbS +.. section: IDLE + +Display up to maxlines non-blank lines for Code Context. If there is no +current context, show a single blank line. + +.. + +.. bpo: 33628 +.. date: 2018-05-23-19-51-07 +.. nonce: sLlFLO +.. section: IDLE + +IDLE: Cleanup codecontext.py and its test. + +.. + +.. bpo: 33564 +.. date: 2018-05-17-19-41-12 +.. nonce: XzHZJe +.. section: IDLE + +IDLE's code context now recognizes async as a block opener. + +.. + +.. bpo: 21474 +.. date: 2018-04-29-16-13-02 +.. nonce: bglg-F +.. section: IDLE + +Update word/identifier definition from ascii to unicode. In text and entry +boxes, this affects selection by double-click, movement left/right by +control-left/right, and deletion left/right by control-BACKSPACE/DEL. + +.. + +.. bpo: 33204 +.. date: 2018-04-02-00-28-13 +.. nonce: NBsuIv +.. section: IDLE + +IDLE: consistently color invalid string prefixes. A 'u' string prefix cannot +be paired with either 'r' or 'f'. Consistently color as much of the prefix, +starting at the right, as is valid. Revise and extend colorizer test. + +.. + +.. bpo: 32984 +.. date: 2018-03-05-01-29-05 +.. nonce: NGjgT4 +.. section: IDLE + +Set ``__file__`` while running a startup file. Like Python, IDLE optionally +runs one startup file in the Shell window before presenting the first +interactive input prompt. For IDLE, ``-s`` runs a file named in +environmental variable :envvar:`IDLESTARTUP` or :envvar:`PYTHONSTARTUP`; +``-r file`` runs ``file``. Python sets ``__file__`` to the startup file +name before running the file and unsets it before the first prompt. IDLE +now does the same when run normally, without the ``-n`` option. + +.. + +.. bpo: 32940 +.. date: 2018-02-24-18-20-50 +.. nonce: ZaJ1Rf +.. section: IDLE + +Simplify and rename StringTranslatePseudoMapping in pyparse. + +.. + +.. bpo: 32916 +.. date: 2018-02-23-07-32-36 +.. nonce: 4MsQ5F +.. section: IDLE + +Change ``str`` to ``code`` in pyparse. + +.. + +.. bpo: 32905 +.. date: 2018-02-22-00-09-27 +.. nonce: VlXj0x +.. section: IDLE + +Remove unused code in pyparse module. + +.. + +.. bpo: 32874 +.. date: 2018-02-19-10-56-41 +.. nonce: 6pZ9Gv +.. section: IDLE + +Add tests for pyparse. + +.. + +.. bpo: 32837 +.. date: 2018-02-12-17-22-48 +.. nonce: -33QPl +.. section: IDLE + +Using the system and place-dependent default encoding for open() is a bad +idea for IDLE's system and location-independent files. + +.. + +.. bpo: 32826 +.. date: 2018-02-12-11-05-22 +.. nonce: IxNZrk +.. section: IDLE + +Add "encoding=utf-8" to open() in IDLE's test_help_about. GUI test +test_file_buttons() only looks at initial ascii-only lines, but failed on +systems where open() defaults to 'ascii' because readline() internally reads +and decodes far enough ahead to encounter a non-ascii character in +CREDITS.txt. + +.. + +.. bpo: 32831 +.. date: 2018-02-12-08-08-45 +.. nonce: srDRvU +.. section: IDLE + +Add docstrings and tests for codecontext. + +.. + +.. bpo: 32765 +.. date: 2018-02-04-17-52-54 +.. nonce: qm0eCu +.. section: IDLE + +Update configdialog General tab docstring to add new widgets to the widget +list. + +.. + +.. bpo: 35884 +.. date: 2019-02-01-12-22-37 +.. nonce: hJkMRD +.. section: Tools/Demos + +Add a benchmark script for timing various ways to access variables: +``Tools/scripts/var_access_benchmark.py``. + +.. + +.. bpo: 34989 +.. date: 2018-10-15-13-22-28 +.. nonce: hU4fra +.. section: Tools/Demos + +python-gdb.py now handles errors on computing the line number of a Python +frame. + +.. + +.. bpo: 20260 +.. date: 2018-07-24-00-11-44 +.. nonce: klmmqI +.. section: Tools/Demos + +Argument Clinic now has non-bitwise unsigned int converters. + +.. + +.. bpo: 32962 +.. date: 2018-06-14-16-23-07 +.. nonce: Q3Dwns +.. section: Tools/Demos + +python-gdb now catches ``UnicodeDecodeError`` exceptions when calling +``string()``. + +.. + +.. bpo: 32962 +.. date: 2018-06-14-16-16-53 +.. nonce: 2YfdwI +.. section: Tools/Demos + +python-gdb now catches ValueError on read_var(): when Python has no debug +symbols for example. + +.. + +.. bpo: 33189 +.. date: 2018-04-03-18-10-00 +.. nonce: QrXR00 +.. section: Tools/Demos + +:program:`pygettext.py` now recognizes only literal strings as docstrings +and translatable strings, and rejects bytes literals and f-string +expressions. + +.. + +.. bpo: 31920 +.. date: 2018-03-26-18-54-24 +.. nonce: u_WKsT +.. section: Tools/Demos + +Fixed handling directories as arguments in the ``pygettext`` script. Based +on patch by Oleg Krasnikov. + +.. + +.. bpo: 29673 +.. date: 2018-03-16-17-25-05 +.. nonce: m8QtaW +.. section: Tools/Demos + +Fix pystackv and pystack gdbinit macros. + +.. + +.. bpo: 25427 +.. date: 2018-03-02-16-23-31 +.. nonce: 1mgMOG +.. section: Tools/Demos + +Remove the pyvenv script in favor of ``python3 -m venv`` in order to lower +confusion as to what Python interpreter a virtual environment will be +created for. + +.. + +.. bpo: 32885 +.. date: 2018-02-20-12-16-47 +.. nonce: dL5x7C +.. section: Tools/Demos + +Add an ``-n`` flag for ``Tools/scripts/pathfix.py`` to disable automatic +backup creation (files with ``~`` suffix). + +.. + +.. bpo: 32222 +.. date: 2017-12-07-20-51-20 +.. nonce: hPBcGT +.. section: Tools/Demos + +Fix pygettext not extracting docstrings for functions with type annotated +arguments. Patch by Toby Harradine. + +.. + +.. bpo: 31583 +.. date: 2017-09-26-10-11-21 +.. nonce: TM90_H +.. section: Tools/Demos + +Fix 2to3 for using with --add-suffix option but without --output-dir option +for relative path to files in current directory. + +.. + +.. bpo: 35713 +.. date: 2019-01-22-17-04-10 +.. nonce: fmehdG +.. section: C API + +The :c:func:`!PyByteArray_Init` and :c:func:`!PyByteArray_Fini` functions have +been removed. They did nothing since Python 2.7.4 and Python 3.2.0, were +excluded from the limited API (stable ABI), and were not documented. + +.. + +.. bpo: 33817 +.. date: 2019-01-11-11-16-16 +.. nonce: nJ4yIj +.. section: C API + +Fixed :c:func:`_PyBytes_Resize` for empty bytes objects. + +.. + +.. bpo: 35322 +.. date: 2018-11-28-03-20-36 +.. nonce: Qcqsag +.. section: C API + +Fix memory leak in :c:func:`PyUnicode_EncodeLocale` and +:c:func:`PyUnicode_EncodeFSDefault` on error handling. + +.. + +.. bpo: 35059 +.. date: 2018-11-23-11-52-34 +.. nonce: BLSp6y +.. section: C API + +The following C macros have been converted to static inline functions: +:c:func:`Py_INCREF`, :c:func:`Py_DECREF`, :c:func:`Py_XINCREF`, +:c:func:`Py_XDECREF`, :c:func:`PyObject_INIT`, :c:func:`PyObject_INIT_VAR`. + +.. + +.. bpo: 35296 +.. date: 2018-11-22-18-34-23 +.. nonce: nxrIQt +.. section: C API + +``make install`` now also installs the internal API: +``Include/internal/*.h`` header files. + +.. + +.. bpo: 35081 +.. date: 2018-11-22-18-15-46 +.. nonce: FdK9mV +.. section: C API + +Internal APIs surrounded by ``#ifdef Py_BUILD_CORE`` have been moved from +``Include/*.h`` headers to new header files ``Include/internal/pycore_*.h``. + +.. + +.. bpo: 35259 +.. date: 2018-11-22-13-52-36 +.. nonce: p07c61 +.. section: C API + +Conditionally declare :c:func:`Py_FinalizeEx()` (new in 3.6) based on +Py_LIMITED_API. Patch by Arthur Neufeld. + +.. + +.. bpo: 35081 +.. date: 2018-11-13-12-13-04 +.. nonce: gFd85N +.. section: C API + +The :c:func:`!_PyObject_GC_TRACK` and :c:func:`!_PyObject_GC_UNTRACK` macros +have been removed from the public C API. + +.. + +.. bpo: 35134 +.. date: 2018-11-01-13-58-37 +.. nonce: SbZo0o +.. section: C API + +Creation of a new ``Include/cpython/`` subdirectory. + +.. + +.. bpo: 34725 +.. date: 2018-10-13-16-30-54 +.. nonce: j52rIS +.. section: C API + +Adds _Py_SetProgramFullPath so embedders may override sys.executable + +.. + +.. bpo: 34910 +.. date: 2018-10-05-17-06-49 +.. nonce: tSFrls +.. section: C API + +Ensure that :c:func:`PyObject_Print` always returns ``-1`` on error. Patch +by Zackery Spytz. + +.. + +.. bpo: 34523 +.. date: 2018-08-29-18-48-47 +.. nonce: lLQ8rh +.. section: C API + +Py_DecodeLocale() and Py_EncodeLocale() now use the UTF-8 encoding on +Windows if Py_LegacyWindowsFSEncodingFlag is zero. + +.. + +.. bpo: 34193 +.. date: 2018-07-24-11-57-35 +.. nonce: M6ch1Q +.. section: C API + +Fix pluralization in TypeError messages in getargs.c and typeobject.c: '1 +argument' instead of '1 arguments' and '1 element' instead of '1 elements'. + +.. + +.. bpo: 34127 +.. date: 2018-07-22-14-58-06 +.. nonce: qkfnHO +.. section: C API + +Return grammatically correct error message based on argument count. Patch by +Karthikeyan Singaravelan. + +.. + +.. bpo: 23927 +.. date: 2018-07-09-11-39-54 +.. nonce: pDFkxb +.. section: C API + +Fixed :exc:`SystemError` in :c:func:`PyArg_ParseTupleAndKeywords` when the +``w*`` format unit is used for optional parameter. + +.. + +.. bpo: 32455 +.. date: 2018-07-08-12-06-18 +.. nonce: KVHlkz +.. section: C API + +Added :c:func:`PyCompile_OpcodeStackEffectWithJump`. + +.. + +.. bpo: 34008 +.. date: 2018-07-02-10-58-11 +.. nonce: COewz- +.. section: C API + +Py_Main() can again be called after Py_Initialize(), as in Python 3.6. + +.. + +.. bpo: 32500 +.. date: 2018-06-21-17-19-31 +.. nonce: WGCNad +.. section: C API + +Fixed error messages for :c:func:`PySequence_Size`, +:c:func:`PySequence_GetItem`, :c:func:`PySequence_SetItem` and +:c:func:`PySequence_DelItem` called with a mapping and +:c:func:`PyMapping_Size` called with a sequence. + +.. + +.. bpo: 33818 +.. date: 2018-06-10-09-42-31 +.. nonce: 50nlf3 +.. section: C API + +:c:func:`PyExceptionClass_Name` will now return ``const char *`` instead of +``char *``. + +.. + +.. bpo: 33042 +.. date: 2018-03-20-21-43-09 +.. nonce: FPFp64 +.. section: C API + +Embedding applications may once again call PySys_ResetWarnOptions, +PySys_AddWarnOption, and PySys_AddXOption prior to calling Py_Initialize. + +.. + +.. bpo: 32374 +.. date: 2018-01-09-17-03-54 +.. nonce: SwwLoz +.. section: C API + +Document that m_traverse for multi-phase initialized modules can be called +with m_state=NULL, and add a sanity check + +.. + +.. bpo: 30863 +.. date: 2017-10-12-23-24-27 +.. nonce: xrED19 +.. section: C API + +:c:func:`PyUnicode_AsWideChar` and :c:func:`PyUnicode_AsWideCharString` no +longer cache the ``wchar_t*`` representation of string objects. diff --git a/Misc/NEWS.d/3.8.0a2.rst b/Misc/NEWS.d/3.8.0a2.rst new file mode 100644 index 00000000..22312614 --- /dev/null +++ b/Misc/NEWS.d/3.8.0a2.rst @@ -0,0 +1,544 @@ +.. bpo: 36052 +.. date: 2019-02-20-17-57-31 +.. nonce: l8lJSi +.. release date: 2019-02-25 +.. section: Core and Builtins + +Raise a :exc:`SyntaxError` when assigning a value to `__debug__` with the +Assignment Operator. Contributed by Stéphane Wirtel and Pablo Galindo. + +.. + +.. bpo: 36012 +.. date: 2019-02-19-10-47-51 +.. nonce: xq7C9E +.. section: Core and Builtins + +Doubled the speed of class variable writes. When a non-dunder attribute was +updated, there was an unnecessary call to update slots. + +.. + +.. bpo: 35942 +.. date: 2019-02-18-09-30-55 +.. nonce: oLhL2v +.. section: Core and Builtins + +The error message emitted when returning invalid types from ``__fspath__`` +in interfaces that allow passing :class:`~os.PathLike` objects has been +improved and now it does explain the origin of the error. + +.. + +.. bpo: 36016 +.. date: 2019-02-17-20-23-54 +.. nonce: 5Hns-f +.. section: Core and Builtins + +``gc.get_objects`` can now receive an optional parameter indicating a +generation to get objects from. Patch by Pablo Galindo. + +.. + +.. bpo: 1054041 +.. date: 2019-02-16-00-42-32 +.. nonce: BL-WLd +.. section: Core and Builtins + +When the main interpreter exits due to an uncaught KeyboardInterrupt, the +process now exits in the appropriate manner for its parent process to detect +that a SIGINT or ^C terminated the process. This allows shells and batch +scripts to understand that the user has asked them to stop. + +.. + +.. bpo: 35992 +.. date: 2019-02-14-12-01-44 +.. nonce: nG9e2L +.. section: Core and Builtins + +Fix ``__class_getitem__()`` not being called on a class with a custom +non-subscriptable metaclass. + +.. + +.. bpo: 35993 +.. date: 2019-02-14-09-17-54 +.. nonce: Bvm3fP +.. section: Core and Builtins + +Fix a crash on fork when using subinterpreters. Contributed by Stéphane +Wirtel + +.. + +.. bpo: 35991 +.. date: 2019-02-14-00-00-30 +.. nonce: xlbfSk +.. section: Core and Builtins + +Fix a potential double free in Modules/_randommodule.c. + +.. + +.. bpo: 35961 +.. date: 2019-02-12-20-16-34 +.. nonce: 7f7Sne +.. section: Core and Builtins + +Fix a crash in slice_richcompare(): use strong references rather than stolen +references for the two temporary internal tuples. + +.. + +.. bpo: 35911 +.. date: 2019-02-06-17-50-59 +.. nonce: oiWE8 +.. section: Core and Builtins + +Enable the creation of cell objects by adding a ``cell.__new__`` method, and +expose the type ``cell`` in ``Lib/types.py`` under the name CellType. Patch +by Pierre Glaser. + +.. + +.. bpo: 12822 +.. date: 2019-02-05-12-48-23 +.. nonce: 0x2NDx +.. section: Core and Builtins + +Use monotonic clock for ``pthread_cond_timedwait`` when +``pthread_condattr_setclock`` and ``CLOCK_MONOTONIC`` are available. + +.. + +.. bpo: 15248 +.. date: 2019-02-04-21-10-17 +.. nonce: 2sXSZZ +.. section: Core and Builtins + +The compiler emits now syntax warnings in the case when a comma is likely +missed before tuple or list. + +.. + +.. bpo: 35886 +.. date: 2019-02-01-18-12-14 +.. nonce: 0Z-C0V +.. section: Core and Builtins + +The implementation of PyInterpreterState has been moved into the internal +header files (guarded by Py_BUILD_CORE). + +.. + +.. bpo: 31506 +.. date: 2019-01-22-02-06-39 +.. nonce: eJ5FpV +.. section: Core and Builtins + +Clarify the errors reported when ``object.__new__`` and ``object.__init__`` +receive more than one argument. Contributed by Sanyam Khurana. + +.. + +.. bpo: 35724 +.. date: 2019-01-11-14-46-08 +.. nonce: Wv79MG +.. section: Core and Builtins + +Signal-handling is now guaranteed to happen relative to the main +interpreter. + +.. + +.. bpo: 33608 +.. date: 2018-09-15-12-13-46 +.. nonce: avmvVP +.. section: Core and Builtins + +We added a new internal _Py_AddPendingCall() that operates relative to the +provided interpreter. This allows us to use the existing implementation to +ask another interpreter to do work that cannot be done in the current +interpreter, like decref an object the other interpreter owns. The existing +Py_AddPendingCall() only operates relative to the main interpreter. + +.. + +.. bpo: 33989 +.. date: 2018-08-08-20-52-55 +.. nonce: TkLBui +.. section: Core and Builtins + +Fix a possible crash in :meth:`list.sort` when sorting objects with +``ob_type->tp_richcompare == NULL``. Patch by Zackery Spytz. + +.. + +.. bpo: 35512 +.. date: 2019-02-24-00-04-10 +.. nonce: eWDjCJ +.. section: Library + +:func:`unittest.mock.patch.dict` used as a decorator with string target +resolves the target during function call instead of during decorator +construction. Patch by Karthikeyan Singaravelan. + +.. + +.. bpo: 36018 +.. date: 2019-02-21-15-47-00 +.. nonce: qt7QUe +.. section: Library + +Add statistics.NormalDist, a tool for creating and manipulating normal +distributions of random variable. Features a composite class that treats +the mean and standard deviation of measurement data as single entity. + +.. + +.. bpo: 35904 +.. date: 2019-02-16-00-55-52 +.. nonce: V88MCD +.. section: Library + +Added statistics.fmean() as a faster, floating point variant of the existing +mean() function. + +.. + +.. bpo: 35918 +.. date: 2019-02-11-16-23-10 +.. nonce: oGDlpT +.. section: Library + +Removed broken ``has_key`` method from +multiprocessing.managers.SyncManager.dict. Contributed by Rémi Lapeyre. + +.. + +.. bpo: 18283 +.. date: 2019-02-11-09-24-08 +.. nonce: BT3Jhc +.. section: Library + +Add support for bytes to :func:`shutil.which`. + +.. + +.. bpo: 35960 +.. date: 2019-02-10-20-57-12 +.. nonce: bh-6Ja +.. section: Library + +Fix :func:`dataclasses.field` throwing away empty mapping objects passed as +metadata. + +.. + +.. bpo: 35500 +.. date: 2019-02-10-00-00-13 +.. nonce: 1HOMmo +.. section: Library + +Write expected and actual call parameters on separate lines in +:meth:`unittest.mock.Mock.assert_called_with` assertion errors. Contributed +by Susan Su. + +.. + +.. bpo: 35931 +.. date: 2019-02-07-16-22-50 +.. nonce: _63i7B +.. section: Library + +The :mod:`pdb` ``debug`` command now gracefully handles syntax errors. + +.. + +.. bpo: 24209 +.. date: 2019-02-06-01-40-55 +.. nonce: awtwPD +.. section: Library + +In http.server script, rely on getaddrinfo to bind to preferred address +based on the bind parameter. Now default bind or binding to a name may bind +to IPv6 or dual-stack, depending on the environment. + +.. + +.. bpo: 35321 +.. date: 2019-02-02-01-53-36 +.. nonce: 1Y4DU4 +.. section: Library + +Set ``__spec__.origin`` of ``_frozen_importlib`` to frozen so that it +matches the behavior of ``_frozen_importlib_external``. Patch by Nina +Zakharenko. + +.. + +.. bpo: 35378 +.. date: 2019-01-21-02-15-20 +.. nonce: 4oF03i +.. section: Library + +Fix a reference issue inside :class:`multiprocessing.Pool` that caused the +pool to remain alive if it was deleted without being closed or terminated +explicitly. A new strong reference is added to the pool iterators to link +the lifetime of the pool to the lifetime of its iterators so the pool does +not get destroyed if a pool iterator is still alive. + +.. + +.. bpo: 34294 +.. date: 2019-01-14-11-53-10 +.. nonce: 3JFdg2 +.. section: Library + +re module, fix wrong capturing groups in rare cases. :func:`re.search`, +:func:`re.findall`, :func:`re.sub` and other functions that scan through +string looking for a match, should reset capturing groups between two match +attempts. Patch by Ma Lin. + +.. + +.. bpo: 35615 +.. date: 2018-12-30-20-00-05 +.. nonce: Uz1SVh +.. section: Library + +:mod:`weakref`: Fix a RuntimeError when copying a WeakKeyDictionary or a +WeakValueDictionary, due to some keys or values disappearing while +iterating. + +.. + +.. bpo: 35606 +.. date: 2018-12-29-21-59-03 +.. nonce: NjGjou +.. section: Library + +Implement :func:`math.prod` as analogous function to :func:`sum` that +returns the product of a 'start' value (default: 1) times an iterable of +numbers. Patch by Pablo Galindo. + +.. + +.. bpo: 32417 +.. date: 2018-12-04-13-35-36 +.. nonce: _Y9SKM +.. section: Library + +Performing arithmetic between :class:`datetime.datetime` subclasses and +:class:`datetime.timedelta` now returns an object of the same type as the +:class:`datetime.datetime` subclass. As a result, +:meth:`datetime.datetime.astimezone` and alternate constructors like +:meth:`datetime.datetime.now` and :meth:`datetime.fromtimestamp` called with +a ``tz`` argument now *also* retain their subclass. + +.. + +.. bpo: 35153 +.. date: 2018-11-03-12-38-03 +.. nonce: 009pdF +.. section: Library + +Add *headers* optional keyword-only parameter to +:class:`xmlrpc.client.ServerProxy`, :class:`xmlrpc.client.Transport` and +:class:`xmlrpc.client.SafeTransport`. Patch by Cédric Krier. + +.. + +.. bpo: 34572 +.. date: 2018-09-05-03-02-32 +.. nonce: ayisd2 +.. section: Library + +Fix C implementation of pickle.loads to use importlib's locking mechanisms, +and thereby avoid using partially loaded modules. Patch by Tim Burgess. + +.. + +.. bpo: 36083 +.. date: 2019-02-24-12-40-13 +.. nonce: JX7zbv +.. section: Documentation + +Fix formatting of --check-hash-based-pycs options in the manpage Synopsis. + +.. + +.. bpo: 36007 +.. date: 2019-02-15-15-33-41 +.. nonce: OTFrza +.. section: Documentation + +Bump minimum sphinx version to 1.8. Patch by Anthony Sottile. + +.. + +.. bpo: 22062 +.. date: 2018-07-28-12-41-01 +.. nonce: TaN2hn +.. section: Documentation + +Update documentation and docstrings for pathlib. Original patch by Mike +Short. + +.. + +.. bpo: 27313 +.. date: 2019-02-24-01-58-38 +.. nonce: Sj9veH +.. section: Tests + +Avoid test_ttk_guionly ComboboxTest failure with macOS Cocoa Tk. + +.. + +.. bpo: 36019 +.. date: 2019-02-21-14-23-51 +.. nonce: zS_OUi +.. section: Tests + +Add test.support.TEST_HTTP_URL and replace references of +http://www.example.com by this new constant. Contributed by Stéphane Wirtel. + +.. + +.. bpo: 36037 +.. date: 2019-02-19-15-21-14 +.. nonce: 75wG9_ +.. section: Tests + +Fix test_ssl for strict OpenSSL configuration like RHEL8 strict crypto +policy. Use older TLS version for minimum TLS version of the server SSL +context if needed, to test TLS version older than default minimum TLS +version. + +.. + +.. bpo: 35798 +.. date: 2019-02-16-15-19-31 +.. nonce: JF16MP +.. section: Tests + +Added :func:`test.support.check_syntax_warning`. + +.. + +.. bpo: 35505 +.. date: 2019-02-12-01-33-08 +.. nonce: N9ba_K +.. section: Tests + +Make test_imap4_host_default_value independent on whether the local IMAP +server is running. + +.. + +.. bpo: 35917 +.. date: 2019-02-06-18-06-16 +.. nonce: -Clv1L +.. section: Tests + +multiprocessing: provide unit tests for SyncManager and SharedMemoryManager +classes + all the shareable types which are supposed to be supported by +them. (patch by Giampaolo Rodola) + +.. + +.. bpo: 35704 +.. date: 2019-01-10-09-14-58 +.. nonce: FLglYo +.. section: Tests + +Skip ``test_shutil.test_unpack_archive_xztar`` to prevent a MemoryError on +32-bit AIX when MAXDATA setting is less than 0x20000000. + +Patch by Michael Felt (aixtools) + +.. + +.. bpo: 34720 +.. date: 2018-12-26-12-31-16 +.. nonce: T268vz +.. section: Tests + +Assert m_state != NULL to mimic GC traversal functions that do not correctly +handle module creation when the module state has not been created. + +.. + +.. bpo: 35976 +.. date: 2019-02-11-20-07-43 +.. nonce: toap7O +.. section: Windows + +Added ARM build support to Windows build files in PCBuild. + +.. + +.. bpo: 35692 +.. date: 2019-02-02-16-23-57 +.. nonce: cIiiE9 +.. section: Windows + +``pathlib`` no longer raises when checking file and directory existence on +drives that are not ready + +.. + +.. bpo: 35872 +.. date: 2019-02-02-15-57-19 +.. nonce: Bba2n7 +.. section: Windows + +Uses the base Python executable when invoking venv in a virtual environment + +.. + +.. bpo: 35873 +.. date: 2019-02-02-15-56-50 +.. nonce: UW-qS9 +.. section: Windows + +Prevents venv paths being inherited by child processes + +.. + +.. bpo: 35299 +.. date: 2019-02-02-14-47-12 +.. nonce: 1rgEzd +.. section: Windows + +Fix sysconfig detection of the source directory and distutils handling of +pyconfig.h during PGO profiling + +.. + +.. bpo: 24310 +.. date: 2019-02-23-22-31-20 +.. nonce: j_vJQl +.. section: IDLE + +IDLE -- Document settings dialog font tab sample. + +.. + +.. bpo: 35833 +.. date: 2019-02-08-22-14-24 +.. nonce: XKFRvF +.. section: IDLE + +Revise IDLE doc for control codes sent to Shell. Add a code example block. + +.. + +.. bpo: 35689 +.. date: 2019-01-08-17-51-44 +.. nonce: LlaqR8 +.. section: IDLE + +Add docstrings and unittests for colorizer.py. diff --git a/Misc/NEWS.d/3.8.0a3.rst b/Misc/NEWS.d/3.8.0a3.rst new file mode 100644 index 00000000..66308c6b --- /dev/null +++ b/Misc/NEWS.d/3.8.0a3.rst @@ -0,0 +1,872 @@ +.. bpo: 36216 +.. date: 2019-03-06-09-38-40 +.. nonce: 6q1m4a +.. release date: 2019-03-25 +.. section: Security + +Changes urlsplit() to raise ValueError when the URL contains characters that +decompose under IDNA encoding (NFKC-normalization) into characters that +affect how the URL is parsed. + +.. + +.. bpo: 35121 +.. date: 2018-10-31-15-39-17 +.. nonce: EgHv9k +.. section: Security + +Don't send cookies of domain A without Domain attribute to domain B when +domain A is a suffix match of domain B while using a cookiejar with +:class:`http.cookiejar.DefaultCookiePolicy` policy. Patch by Karthikeyan +Singaravelan. + +.. + +.. bpo: 36421 +.. date: 2019-03-24-21-33-22 +.. nonce: gJ2Pv9 +.. section: Core and Builtins + +Fix a possible double decref in _ctypes.c's ``PyCArrayType_new()``. + +.. + +.. bpo: 36412 +.. date: 2019-03-23-19-51-09 +.. nonce: C7acGn +.. section: Core and Builtins + +Fix a possible crash when creating a new dictionary. + +.. + +.. bpo: 36398 +.. date: 2019-03-21-22-19-38 +.. nonce: B_jXGe +.. section: Core and Builtins + +Fix a possible crash in ``structseq_repr()``. + +.. + +.. bpo: 36256 +.. date: 2019-03-21-00-24-18 +.. nonce: OZHa0t +.. section: Core and Builtins + +Fix bug in parsermodule when parsing a state in a DFA that has two or more +arcs with labels of the same type. Patch by Pablo Galindo. + +.. + +.. bpo: 36365 +.. date: 2019-03-19-15-58-23 +.. nonce: jHaErz +.. section: Core and Builtins + +repr(structseq) is no longer limited to 512 bytes. + +.. + +.. bpo: 36374 +.. date: 2019-03-19-15-46-42 +.. nonce: EWKMZE +.. section: Core and Builtins + +Fix a possible null pointer dereference in ``merge_consts_recursive()``. +Patch by Zackery Spytz. + +.. + +.. bpo: 36236 +.. date: 2019-03-19-03-08-26 +.. nonce: 5qN9qK +.. section: Core and Builtins + +At Python initialization, the current directory is no longer prepended to +:data:`sys.path` if it has been removed. + +.. + +.. bpo: 36352 +.. date: 2019-03-19-02-36-40 +.. nonce: qj2trz +.. section: Core and Builtins + +Python initialization now fails with an error, rather than silently +truncating paths, if a path is too long. + +.. + +.. bpo: 36301 +.. date: 2019-03-19-00-54-31 +.. nonce: xvOCJb +.. section: Core and Builtins + +Python initialization now fails if decoding ``pybuilddir.txt`` configuration +file fails at startup. + +.. + +.. bpo: 36333 +.. date: 2019-03-18-10-56-53 +.. nonce: 4dqemZ +.. section: Core and Builtins + +Fix leak in _PyRuntimeState_Fini. Contributed by Stéphane Wirtel. + +.. + +.. bpo: 36332 +.. date: 2019-03-18-09-27-54 +.. nonce: yEC-Vz +.. section: Core and Builtins + +The builtin :func:`compile` can now handle AST objects that contain +assignment expressions. Patch by Pablo Galindo. + +.. + +.. bpo: 36282 +.. date: 2019-03-13-22-47-28 +.. nonce: zs7RKP +.. section: Core and Builtins + +Improved error message for too much positional arguments in some builtin +functions. + +.. + +.. bpo: 30040 +.. date: 2019-03-11-22-30-56 +.. nonce: W9z8X7 +.. section: Core and Builtins + +New empty dict uses fewer memory for now. It used more memory than empty +dict created by ``dict.clear()``. And empty dict creation and deletion is +about 2x faster. Patch by Inada Naoki. + +.. + +.. bpo: 36262 +.. date: 2019-03-11-15-37-33 +.. nonce: v3N6Fz +.. section: Core and Builtins + +Fix an unlikely memory leak on conversion from string to float in the +function ``_Py_dg_strtod()`` used by ``float(str)``, ``complex(str)``, +:func:`pickle.load`, :func:`marshal.load`, etc. + +.. + +.. bpo: 36252 +.. date: 2019-03-09-15-47-05 +.. nonce: sCQFKq +.. section: Core and Builtins + +Update Unicode databases to version 12.0.0. + +.. + +.. bpo: 36218 +.. date: 2019-03-07-13-05-43 +.. nonce: dZemNt +.. section: Core and Builtins + +Fix a segfault occurring when sorting a list of heterogeneous values. Patch +contributed by Rémi Lapeyre and Elliot Gorokhovsky. + +.. + +.. bpo: 36188 +.. date: 2019-03-04-18-05-31 +.. nonce: EuUZNz +.. section: Core and Builtins + +Cleaned up left-over vestiges of Python 2 unbound method handling in method +objects and documentation. Patch by Martijn Pieters + +.. + +.. bpo: 36124 +.. date: 2019-03-01-13-48-01 +.. nonce: Blzxq1 +.. section: Core and Builtins + +Add a new interpreter-specific dict and expose it in the C-API via +PyInterpreterState_GetDict(). This parallels PyThreadState_GetDict(). +However, extension modules should continue using PyModule_GetState() for +their own internal per-interpreter state. + +.. + +.. bpo: 35975 +.. date: 2019-02-27-16-49-08 +.. nonce: IescLY +.. section: Core and Builtins + +Add a ``feature_version`` flag to ``ast.parse()`` (documented) and +``compile()`` (hidden) that allows tweaking the parser to support older +versions of the grammar. In particular, if ``feature_version`` is 5 or 6, +the hacks for the ``async`` and ``await`` keyword from PEP 492 are +reinstated. (For 7 or higher, these are unconditionally treated as keywords, +but they are still special tokens rather than ``NAME`` tokens that the +parser driver recognizes.) + +.. + +.. bpo: 31904 +.. date: 2019-02-26-17-34-49 +.. nonce: R4KSj6 +.. section: Core and Builtins + +Use UTF-8 as the system encoding on VxWorks. + +.. + +.. bpo: 36048 +.. date: 2019-02-20-08-51-04 +.. nonce: I3LJt9 +.. section: Core and Builtins + +The :meth:`~object.__index__` special method will be used instead of +:meth:`~object.__int__` for implicit conversion of Python numbers to C +integers. Using the ``__int__()`` method in implicit conversions has been +deprecated. + +.. + +.. bpo: 35808 +.. date: 2019-02-11-00-50-03 +.. nonce: M12CMH +.. section: Core and Builtins + +Retire pgen and use a modified version of pgen2 to generate the parser. +Patch by Pablo Galindo. + +.. + +.. bpo: 36401 +.. date: 2019-03-23-10-25-07 +.. nonce: hYpVBS +.. section: Library + +The class documentation created by pydoc now has a separate section for +readonly properties. + +.. + +.. bpo: 36320 +.. date: 2019-03-18-01-08-14 +.. nonce: -06b9_ +.. section: Library + +The typing.NamedTuple() class has deprecated the _field_types attribute in +favor of the __annotations__ attribute which carried the same information. +Also, both attributes were converted from OrderedDict to a regular dict. + +.. + +.. bpo: 34745 +.. date: 2019-03-17-16-43-29 +.. nonce: nOfm7_ +.. section: Library + +Fix :mod:`asyncio` ssl memory issues caused by circular references + +.. + +.. bpo: 36324 +.. date: 2019-03-17-01-17-45 +.. nonce: dvNrRe +.. section: Library + +Add method to statistics.NormalDist for computing the inverse cumulative +normal distribution. + +.. + +.. bpo: 36321 +.. date: 2019-03-16-13-40-59 +.. nonce: s6crQx +.. section: Library + +collections.namedtuple() misspelled the name of an attribute. To be +consistent with typing.NamedTuple, the attribute name should have been +"_field_defaults" instead of "_fields_defaults". For backwards +compatibility, both spellings are now created. The misspelled version may +be removed in the future. + +.. + +.. bpo: 36297 +.. date: 2019-03-15-21-41-22 +.. nonce: Gz9ZfU +.. section: Library + +"unicode_internal" codec is removed. It was deprecated since Python 3.3. +Patch by Inada Naoki. + +.. + +.. bpo: 36298 +.. date: 2019-03-15-13-54-07 +.. nonce: amEVK2 +.. section: Library + +Raise ModuleNotFoundError in pyclbr when a module can't be found. Thanks to +'mental' for the bug report. + +.. + +.. bpo: 36268 +.. date: 2019-03-14-16-25-17 +.. nonce: MDXLw6 +.. section: Library + +Switch the default format used for writing tars with mod:`tarfile` to the +modern POSIX.1-2001 pax standard, from the vendor-specific GNU. Contributed +by C.A.M. Gerlach. + +.. + +.. bpo: 36285 +.. date: 2019-03-14-01-09-59 +.. nonce: G-usj8 +.. section: Library + +Fix integer overflows in the array module. Patch by Stephan Hohe. + +.. + +.. bpo: 31904 +.. date: 2019-03-13-14-55-02 +.. nonce: 834kfY +.. section: Library + +Add _signal module support for VxWorks. + +.. + +.. bpo: 36272 +.. date: 2019-03-13-14-14-36 +.. nonce: f3l2IG +.. section: Library + +:mod:`logging` does not silently ignore RecursionError anymore. Patch +contributed by Rémi Lapeyre. + +.. + +.. bpo: 36280 +.. date: 2019-03-12-21-02-55 +.. nonce: mOd3iH +.. section: Library + +Add a kind field to ast.Constant. It is 'u' if the literal has a 'u' prefix +(i.e. a Python 2 style unicode literal), else None. + +.. + +.. bpo: 35931 +.. date: 2019-03-11-22-06-36 +.. nonce: Qp_Tbe +.. section: Library + +The :mod:`pdb` ``debug`` command now gracefully handles all exceptions. + +.. + +.. bpo: 36251 +.. date: 2019-03-09-18-01-24 +.. nonce: zOp9l0 +.. section: Library + +Fix format strings used for stderrprinter and re.Match reprs. Patch by +Stephan Hohe. + +.. + +.. bpo: 36235 +.. date: 2019-03-08-13-32-21 +.. nonce: _M72wU +.. section: Library + +Fix ``CFLAGS`` in ``customize_compiler()`` of ``distutils.sysconfig``: when +the ``CFLAGS`` environment variable is defined, don't override ``CFLAGS`` +variable with the ``OPT`` variable anymore. Initial patch written by David +Malcolm. + +.. + +.. bpo: 35807 +.. date: 2019-03-06-13-21-33 +.. nonce: W7mmu3 +.. section: Library + +Update ensurepip to install pip 19.0.3 and setuptools 40.8.0. + +.. + +.. bpo: 36139 +.. date: 2019-03-06-13-07-29 +.. nonce: 6kedum +.. section: Library + +Release GIL when closing :class:`~mmap.mmap` objects. + +.. + +.. bpo: 36179 +.. date: 2019-03-04-10-42-46 +.. nonce: jEyuI- +.. section: Library + +Fix two unlikely reference leaks in _hashopenssl. The leaks only occur in +out-of-memory cases. + +.. + +.. bpo: 36169 +.. date: 2019-03-03-11-37-09 +.. nonce: 8nWJy7 +.. section: Library + +Add overlap() method to statistics.NormalDist. Computes the overlapping +coefficient for two normal distributions. + +.. + +.. bpo: 36103 +.. date: 2019-03-01-16-10-01 +.. nonce: n6VgXL +.. section: Library + +Default buffer size used by ``shutil.copyfileobj()`` is changed from 16 KiB +to 64 KiB on non-Windows platform to reduce system call overhead. +Contributed by Inada Naoki. + +.. + +.. bpo: 36130 +.. date: 2019-02-26-22-41-38 +.. nonce: _BnZOo +.. section: Library + +Fix ``pdb`` with ``skip=...`` when stepping into a frame without a +``__name__`` global. Patch by Anthony Sottile. + +.. + +.. bpo: 35652 +.. date: 2019-02-26-11-34-44 +.. nonce: 6KRJu_ +.. section: Library + +shutil.copytree(copy_function=...) erroneously pass DirEntry instead of a +path string. + +.. + +.. bpo: 35178 +.. date: 2019-02-25-23-04-00 +.. nonce: NA_rXa +.. section: Library + +Ensure custom :func:`warnings.formatwarning` function can receive `line` as +positional argument. Based on patch by Tashrif Billah. + +.. + +.. bpo: 36106 +.. date: 2019-02-25-13-21-43 +.. nonce: VuhEiQ +.. section: Library + +Resolve potential name clash with libm's sinpi(). Patch by Dmitrii +Pasechnik. + +.. + +.. bpo: 36091 +.. date: 2019-02-23-06-49-06 +.. nonce: 26o4Lc +.. section: Library + +Clean up reference to async generator in Lib/types. Patch by Henry Chen. + +.. + +.. bpo: 36043 +.. date: 2019-02-19-19-53-46 +.. nonce: l867v0 +.. section: Library + +:class:`FileCookieJar` supports :term:`path-like object`. Contributed by +Stéphane Wirtel + +.. + +.. bpo: 35899 +.. date: 2019-02-16-07-11-02 +.. nonce: cjfn5a +.. section: Library + +Enum has been fixed to correctly handle empty strings and strings with +non-Latin characters (ie. 'α', 'א') without crashing. Original patch +contributed by Maxwell. Assisted by Stéphane Wirtel. + +.. + +.. bpo: 21269 +.. date: 2019-02-10-16-49-16 +.. nonce: Fqi7VH +.. section: Library + +Add ``args`` and ``kwargs`` properties to mock call objects. Contributed by +Kumar Akshay. + +.. + +.. bpo: 30670 +.. date: 2019-02-06-12-07-46 +.. nonce: yffB3F +.. section: Library + +`pprint.pp` has been added to pretty-print objects with dictionary keys +being sorted with their insertion order by default. Parameter *sort_dicts* +has been added to `pprint.pprint`, `pprint.pformat` and +`pprint.PrettyPrinter`. Contributed by Rémi Lapeyre. + +.. + +.. bpo: 35843 +.. date: 2019-01-28-10-19-40 +.. nonce: 7rXGQE +.. section: Library + +Implement ``__getitem__`` for ``_NamespacePath``. Patch by Anthony Sottile. + +.. + +.. bpo: 35802 +.. date: 2019-01-21-13-56-55 +.. nonce: 6633PE +.. section: Library + +Clean up code which checked presence of ``os.stat`` / ``os.lstat`` / +``os.chmod`` which are always present. Patch by Anthony Sottile. + +.. + +.. bpo: 35715 +.. date: 2019-01-11-08-47-58 +.. nonce: Wi3gl0 +.. section: Library + +Librates the return value of a ProcessPoolExecutor _process_worker after +it's no longer needed to free memory + +.. + +.. bpo: 35493 +.. date: 2019-01-09-23-43-08 +.. nonce: kEcRGE +.. section: Library + +Use :func:`multiprocessing.connection.wait` instead of polling each 0.2 +seconds for worker updates in :class:`multiprocessing.Pool`. Patch by Pablo +Galindo. + +.. + +.. bpo: 35661 +.. date: 2019-01-05-16-16-20 +.. nonce: H_UOXc +.. section: Library + +Store the venv prompt in pyvenv.cfg. + +.. + +.. bpo: 35121 +.. date: 2018-12-30-14-35-19 +.. nonce: oWmiGU +.. section: Library + +Don't set cookie for a request when the request path is a prefix match of +the cookie's path attribute but doesn't end with "/". Patch by Karthikeyan +Singaravelan. + +.. + +.. bpo: 21478 +.. date: 2018-12-21-09-54-30 +.. nonce: 5gsXtc +.. section: Library + +Calls to a child function created with :func:`unittest.mock.create_autospec` +should propagate to the parent. Patch by Karthikeyan Singaravelan. + +.. + +.. bpo: 35198 +.. date: 2018-11-09-12-45-28 +.. nonce: EJ8keW +.. section: Library + +Fix C++ extension compilation on AIX + +.. + +.. bpo: 36329 +.. date: 2019-03-17-20-01-41 +.. nonce: L5dJPD +.. section: Documentation + +Declare the path of the Python binary for the usage of +``Tools/scripts/serve.py`` when executing ``make -C Doc/ serve``. +Contributed by Stéphane Wirtel + +.. + +.. bpo: 36138 +.. date: 2019-03-02-00-40-57 +.. nonce: yfjNzG +.. section: Documentation + +Improve documentation about converting datetime.timedelta to scalars. + +.. + +.. bpo: 21314 +.. date: 2018-11-21-23-01-37 +.. nonce: PG33VT +.. section: Documentation + +A new entry was added to the Core Language Section of the Programming FAQ, +which explaines the usage of slash(/) in the signature of a function. Patch +by Lysandros Nikolaou + +.. + +.. bpo: 36234 +.. date: 2019-03-08-12-53-37 +.. nonce: NRVK6W +.. section: Tests + +test_posix.PosixUidGidTests: add tests for invalid uid/gid type (str). +Initial patch written by David Malcolm. + +.. + +.. bpo: 29571 +.. date: 2019-02-28-18-33-29 +.. nonce: r6b9fr +.. section: Tests + +Fix ``test_re.test_locale_flag()``: use ``locale.getpreferredencoding()`` +rather than ``locale.getlocale()`` to get the locale encoding. With some +locales, ``locale.getlocale()`` returns the wrong encoding. + +.. + +.. bpo: 36123 +.. date: 2019-02-26-12-51-35 +.. nonce: QRhhRS +.. section: Tests + +Fix race condition in test_socket. + +.. + +.. bpo: 36356 +.. date: 2019-03-18-23-49-15 +.. nonce: WNrwYI +.. section: Build + +Fix leaks that led to build failure when configured with address sanitizer. + +.. + +.. bpo: 36146 +.. date: 2019-03-01-17-49-22 +.. nonce: VeoyG7 +.. section: Build + +Add ``TEST_EXTENSIONS`` constant to ``setup.py`` to allow to not build test +extensions like ``_testcapi``. + +.. + +.. bpo: 36146 +.. date: 2019-02-28-18-09-01 +.. nonce: IwPJVT +.. section: Build + +Fix setup.py on macOS: only add ``/usr/include/ffi`` to include directories +of _ctypes, not for all extensions. + +.. + +.. bpo: 31904 +.. date: 2019-02-21-14-48-31 +.. nonce: J82jY2 +.. section: Build + +Enable build system to cross-build for VxWorks RTOS. + +.. + +.. bpo: 36312 +.. date: 2019-03-16-16-51-17 +.. nonce: Niwm-T +.. section: Windows + +Fixed decoders for the following code pages: 50220, 50221, 50222, 50225, +50227, 50229, 57002 through 57011, 65000 and 42. + +.. + +.. bpo: 36264 +.. date: 2019-03-11-09-33-47 +.. nonce: rTzWce +.. section: Windows + +Don't honor POSIX ``HOME`` in ``os.path.expanduser`` on windows. Patch by +Anthony Sottile. + +.. + +.. bpo: 24643 +.. date: 2019-02-24-07-52-39 +.. nonce: PofyiS +.. section: Windows + +Fix name collisions due to ``#define timezone _timezone`` in PC/pyconfig.h. + +.. + +.. bpo: 36405 +.. date: 2019-03-23-01-45-56 +.. nonce: m7Wv1F +.. section: IDLE + +Use dict unpacking in idlelib. + +.. + +.. bpo: 36396 +.. date: 2019-03-21-22-43-21 +.. nonce: xSTX-I +.. section: IDLE + +Remove fgBg param of idlelib.config.GetHighlight(). This param was only used +twice and changed the return type. + +.. + +.. bpo: 36176 +.. date: 2019-03-10-00-07-46 +.. nonce: jk_vv6 +.. section: IDLE + +Fix IDLE autocomplete & calltip popup colors. Prevent conflicts with Linux +dark themes (and slightly darken calltip background). + +.. + +.. bpo: 23205 +.. date: 2019-03-06-14-47-57 +.. nonce: Vv0gfH +.. section: IDLE + +For the grep module, add tests for findfiles, refactor findfiles to be a +module-level function, and refactor findfiles to use os.walk. + +.. + +.. bpo: 23216 +.. date: 2019-03-02-19-39-53 +.. nonce: ZA7H8H +.. section: IDLE + +Add docstrings to IDLE search modules. + +.. + +.. bpo: 36152 +.. date: 2019-02-28-18-52-40 +.. nonce: 9pkHIU +.. section: IDLE + +Remove colorizer.ColorDelegator.close_when_done and the corresponding +argument of .close(). In IDLE, both have always been None or False since +2007. + +.. + +.. bpo: 32129 +.. date: 2019-02-25-11-40-14 +.. nonce: 4qVCzD +.. section: IDLE + +Avoid blurry IDLE application icon on macOS with Tk 8.6. Patch by Kevin +Walzer. + +.. + +.. bpo: 36096 +.. date: 2019-02-23-17-53-53 +.. nonce: mN5Ly3 +.. section: IDLE + +Refactor class variables to instance variables in colorizer. + +.. + +.. bpo: 30348 +.. date: 2018-06-27-21-18-41 +.. nonce: WbaRJW +.. section: IDLE + +Increase test coverage of idlelib.autocomplete by 30%. Patch by Louie +Lu + +.. + +.. bpo: 35132 +.. date: 2019-03-04-02-09-09 +.. nonce: 1R_pnL +.. section: Tools/Demos + +Fix py-list and py-bt commands of python-gdb.py on gdb7. + +.. + +.. bpo: 32217 +.. date: 2017-12-19-20-42-36 +.. nonce: axXcjA +.. section: Tools/Demos + +Fix freeze script on Windows. + +.. + +.. bpo: 36381 +.. date: 2019-03-20-22-02-40 +.. nonce: xlzDJ2 +.. section: C API + +Raise ``DeprecationWarning`` when '#' formats are used for building or +parsing values without ``PY_SSIZE_T_CLEAN``. + +.. + +.. bpo: 36142 +.. date: 2019-03-01-03-23-48 +.. nonce: 7F6wJd +.. section: C API + +The whole coreconfig.h header is now excluded from Py_LIMITED_API. Move +functions definitions into a new internal pycore_coreconfig.h header. diff --git a/Misc/NEWS.d/3.8.0a4.rst b/Misc/NEWS.d/3.8.0a4.rst new file mode 100644 index 00000000..f19717c8 --- /dev/null +++ b/Misc/NEWS.d/3.8.0a4.rst @@ -0,0 +1,1411 @@ +.. bpo: 36742 +.. date: 2019-04-29-15-34-59 +.. nonce: QCUY0i +.. release date: 2019-05-06 +.. section: Security + +Fixes mishandling of pre-normalization characters in urlsplit(). + +.. + +.. bpo: 30458 +.. date: 2019-04-10-08-53-30 +.. nonce: 51E-DA +.. section: Security + +Address CVE-2019-9740 by disallowing URL paths with embedded whitespace or +control characters through into the underlying http client request. Such +potentially malicious header injection URLs now cause an +http.client.InvalidURL exception to be raised. + +.. + +.. bpo: 35755 +.. date: 2019-01-17-10-03-48 +.. nonce: GmllIs +.. section: Security + +:func:`shutil.which` now uses ``os.confstr("CS_PATH")`` if available and if +the :envvar:`PATH` environment variable is not set. Remove also the current +directory from :data:`posixpath.defpath`. On Unix, :func:`shutil.which` and +the :mod:`subprocess` module no longer search the executable in the current +directory if the :envvar:`PATH` environment variable is not set. + +.. + +.. bpo: 36722 +.. date: 2019-04-25-21-02-40 +.. nonce: 8NApVM +.. section: Core and Builtins + +In debug build, import now also looks for C extensions compiled in release +mode and for C extensions compiled in the stable ABI. + +.. + +.. bpo: 32849 +.. date: 2019-04-16-11-56-12 +.. nonce: aeSg-D +.. section: Core and Builtins + +Fix Python Initialization code on FreeBSD to detect properly when stdin file +descriptor (fd 0) is invalid. + +.. + +.. bpo: 36623 +.. date: 2019-04-13-02-08-44 +.. nonce: HR_xhB +.. section: Core and Builtins + +Remove parser headers and related function declarations that lack +implementations after the removal of pgen. + +.. + +.. bpo: 20180 +.. date: 2019-04-12-15-49-15 +.. nonce: KUqVk7 +.. section: Core and Builtins + +``dict.pop()`` is now up to 33% faster thanks to Argument Clinic. Patch by +Inada Naoki. + +.. + +.. bpo: 36611 +.. date: 2019-04-12-12-32-39 +.. nonce: zbo9WQ +.. section: Core and Builtins + +Debug memory allocators: disable serialno field by default from debug hooks +on Python memory allocators to reduce the memory footprint by 5%. Enable +:mod:`tracemalloc` to get the traceback where a memory block has been +allocated when a fatal memory error is logged to decide where to put a +breakpoint. Compile Python with ``PYMEM_DEBUG_SERIALNO`` defined to get back +the field. + +.. + +.. bpo: 36588 +.. date: 2019-04-11-14-36-55 +.. nonce: wejLoC +.. section: Core and Builtins + +On AIX, :data:`sys.platform` doesn't contain the major version anymore. +Always return ``'aix'``, instead of ``'aix3'`` .. ``'aix7'``. Since older +Python versions include the version number, it is recommended to always use +``sys.platform.startswith('aix')``. Contributed by M. Felt. + +.. + +.. bpo: 36549 +.. date: 2019-04-11-12-41-31 +.. nonce: QSp8of +.. section: Core and Builtins + +Change str.capitalize to use titlecase for the first character instead of +uppercase. + +.. + +.. bpo: 36540 +.. date: 2019-04-06-20-59-19 +.. nonce: SzVUfC +.. section: Core and Builtins + +Implement :pep:`570` (Python positional-only parameters). Patch by Pablo +Galindo. + +.. + +.. bpo: 36475 +.. date: 2019-04-02-20-02-22 +.. nonce: CjRps3 +.. section: Core and Builtins + +:c:func:`!PyEval_AcquireLock` and :c:func:`!PyEval_AcquireThread` now +terminate the current thread if called while the interpreter is finalizing, +making them consistent with :c:func:`PyEval_RestoreThread`, +:c:func:`Py_END_ALLOW_THREADS`, and :c:func:`PyGILState_Ensure`. + +.. + +.. bpo: 36504 +.. date: 2019-04-02-04-10-32 +.. nonce: k_V8Bm +.. section: Core and Builtins + +Fix signed integer overflow in _ctypes.c's ``PyCArrayType_new()``. + +.. + +.. bpo: 20844 +.. date: 2019-03-29-18-47-50 +.. nonce: ge-7SM +.. section: Core and Builtins + +Fix running script with encoding cookie and LF line ending may fail on +Windows. + +.. + +.. bpo: 24214 +.. date: 2019-03-28-15-22-45 +.. nonce: tZ6lYU +.. section: Core and Builtins + +Fixed support of the surrogatepass error handler in the UTF-8 incremental +decoder. + +.. + +.. bpo: 36452 +.. date: 2019-03-27-23-53-00 +.. nonce: xhK2lT +.. section: Core and Builtins + +Changing ``dict`` keys during iteration of the dict itself, ``keys()``, +``values()``, or ``items()`` will now be detected in certain corner cases +where keys are deleted/added so that the number of keys isn't changed. A +`RuntimeError` will be raised after ``len(dict)`` iterations. Contributed by +Thomas Perl. + +.. + +.. bpo: 36459 +.. date: 2019-03-27-22-35-16 +.. nonce: UAvkKp +.. section: Core and Builtins + +Fix a possible double ``PyMem_FREE()`` due to tokenizer.c's ``tok_nextc()``. + +.. + +.. bpo: 36433 +.. date: 2019-03-26-17-23-02 +.. nonce: -8XzZf +.. section: Core and Builtins + +Fixed TypeError message in classmethoddescr_call. + +.. + +.. bpo: 36430 +.. date: 2019-03-25-23-37-26 +.. nonce: sd9xxQ +.. section: Core and Builtins + +Fix a possible reference leak in :func:`itertools.count`. + +.. + +.. bpo: 36440 +.. date: 2019-03-25-13-45-19 +.. nonce: gkvzhi +.. section: Core and Builtins + +Include node names in ``ParserError`` messages, instead of numeric IDs. +Patch by A. Skrobov. + +.. + +.. bpo: 36143 +.. date: 2019-03-20-00-37-24 +.. nonce: fnKoKo +.. section: Core and Builtins + +Regenerate :mod:`keyword` from the Grammar and Tokens file using pgen. Patch +by Pablo Galindo. + +.. + +.. bpo: 18372 +.. date: 2018-12-08-03-40-43 +.. nonce: DT1nR0 +.. section: Core and Builtins + +Add missing :c:func:`PyObject_GC_Track` calls in the :mod:`pickle` module. +Patch by Zackery Spytz. + +.. + +.. bpo: 35952 +.. date: 2019-04-29-11-47-06 +.. nonce: 3uNuyo +.. section: Library + +Fix pythoninfo when the compiler is missing. + +.. + +.. bpo: 28238 +.. date: 2019-04-28-15-01-29 +.. nonce: gdk38f +.. section: Library + +The ``.find*()`` methods of xml.etree.ElementTree can now search for +wildcards like ``{*}tag`` and ``{ns}*`` that match a tag in any namespace or +all tags in a namespace. Patch by Stefan Behnel. + +.. + +.. bpo: 26978 +.. date: 2019-04-28-01-52-39 +.. nonce: Lpm-SI +.. section: Library + +`pathlib.path.link_to()` is now implemented. It creates a hard link pointing +to a path. + +.. + +.. bpo: 1613500 +.. date: 2019-04-27-21-09-33 +.. nonce: Ogp4P0 +.. section: Library + +:class:`fileinput.FileInput` now uses the input file mode to correctly set +the output file mode (previously it was hardcoded to ``'w'``) when +``inplace=True`` is passed to its constructor. + +.. + +.. bpo: 36734 +.. date: 2019-04-26-17-14-20 +.. nonce: p2MaiN +.. section: Library + +Fix compilation of ``faulthandler.c`` on HP-UX. Initialize ``stack_t +current_stack`` to zero using ``memset()``. + +.. + +.. bpo: 13611 +.. date: 2019-04-26-10-10-34 +.. nonce: XEF4bg +.. section: Library + +The xml.etree.ElementTree packages gained support for C14N 2.0 +serialisation. Patch by Stefan Behnel. + +.. + +.. bpo: 36669 +.. date: 2019-04-24-17-08-45 +.. nonce: X4g0fu +.. section: Library + +Add missing matrix multiplication operator support to weakref.proxy. + +.. + +.. bpo: 36676 +.. date: 2019-04-20-13-10-34 +.. nonce: XF4Egb +.. section: Library + +The XMLParser() in xml.etree.ElementTree provides namespace prefix context +to the parser target if it defines the callback methods "start_ns()" and/or +"end_ns()". Patch by Stefan Behnel. + +.. + +.. bpo: 36673 +.. date: 2019-04-20-09-50-32 +.. nonce: XF4Egb +.. section: Library + +The TreeBuilder and XMLPullParser in xml.etree.ElementTree gained support +for parsing comments and processing instructions. Patch by Stefan Behnel. + +.. + +.. bpo: 36650 +.. date: 2019-04-19-15-29-55 +.. nonce: _EVdrz +.. section: Library + +The C version of functools.lru_cache() was treating calls with an empty +``**kwargs`` dictionary as being distinct from calls with no keywords at +all. This did not result in an incorrect answer, but it did trigger an +unexpected cache miss. + +.. + +.. bpo: 28552 +.. date: 2019-04-18-16-10-29 +.. nonce: MW1TLt +.. section: Library + +Fix ``distutils.sysconfig`` if :data:`sys.executable` is ``None`` or an +empty string: use :func:`os.getcwd` to initialize ``project_base``. Fix +also the distutils build command: don't use :data:`sys.executable` if it is +``None`` or an empty string. + +.. + +.. bpo: 35755 +.. date: 2019-04-16-17-50-39 +.. nonce: Fg4EXb +.. section: Library + +:func:`shutil.which` and ``distutils.spawn.find_executable`` now use +``os.confstr("CS_PATH")`` if available instead of :data:`os.defpath`, if the +``PATH`` environment variable is not set. Moreover, don't use +``os.confstr("CS_PATH")`` nor :data:`os.defpath` if the ``PATH`` environment +variable is set to an empty string. + +.. + +.. bpo: 25430 +.. date: 2019-04-15-12-22-09 +.. nonce: 7_8kqc +.. section: Library + +improve performance of ``IPNetwork.__contains__()`` + +.. + +.. bpo: 30485 +.. date: 2019-04-13-23-42-33 +.. nonce: JHhjJS +.. section: Library + +Path expressions in xml.etree.ElementTree can now avoid explicit namespace +prefixes for tags (or the "{namespace}tag" notation) by passing a default +namespace with an empty string prefix. + +.. + +.. bpo: 36613 +.. date: 2019-04-12-13-52-15 +.. nonce: hqT1qn +.. section: Library + +Fix :mod:`asyncio` wait() not removing callback if exception + +.. + +.. bpo: 36598 +.. date: 2019-04-11-22-11-24 +.. nonce: hfzDUl +.. section: Library + +Fix ``isinstance`` check for Mock objects with spec when the code is +executed under tracing. Patch by Karthikeyan Singaravelan. + +.. + +.. bpo: 18748 +.. date: 2019-04-11-16-09-42 +.. nonce: QW7upB +.. section: Library + +In development mode (:option:`-X` ``dev``) and in debug build, the +:class:`io.IOBase` destructor now logs ``close()`` exceptions. These +exceptions are silent by default in release mode. + +.. + +.. bpo: 36575 +.. date: 2019-04-09-22-40-52 +.. nonce: Vg_p92 +.. section: Library + +The ``_lsprof`` module now uses internal timer same to +``time.perf_counter()`` by default. ``gettimeofday(2)`` was used on Unix. +New timer has better resolution on most Unix platforms and timings are no +longer impacted by system clock updates since ``perf_counter()`` is +monotonic. Patch by Inada Naoki. + +.. + +.. bpo: 33461 +.. date: 2019-04-09-14-46-28 +.. nonce: SYJM-E +.. section: Library + +``json.loads`` now emits ``DeprecationWarning`` when ``encoding`` option is +specified. Patch by Matthias Bussonnier. + +.. + +.. bpo: 36559 +.. date: 2019-04-09-12-02-35 +.. nonce: LbDRrw +.. section: Library + +The random module now prefers the lean internal _sha512 module over hashlib +for seed(version=2) to optimize import time. + +.. + +.. bpo: 17561 +.. date: 2019-04-09-04-08-46 +.. nonce: hOhVnh +.. section: Library + +Set backlog=None as the default for socket.create_server. + +.. + +.. bpo: 34373 +.. date: 2019-04-08-14-41-22 +.. nonce: lEAl_- +.. section: Library + +Fix :func:`time.mktime` error handling on AIX for year before 1970. + +.. + +.. bpo: 36232 +.. date: 2019-04-06-20-25-25 +.. nonce: SClmhb +.. section: Library + +Improve error message when trying to open existing DBM database that +actually doesn't exist. Patch by Marco Rougeth. + +.. + +.. bpo: 36546 +.. date: 2019-04-06-14-23-00 +.. nonce: YXjbyY +.. section: Library + +Add statistics.quantiles() + +.. + +.. bpo: 36050 +.. date: 2019-04-05-21-29-53 +.. nonce: x9DRKE +.. section: Library + +Optimized ``http.client.HTTPResponse.read()`` for large response. Patch by +Inada Naoki. + +.. + +.. bpo: 36522 +.. date: 2019-04-03-20-46-47 +.. nonce: g5x3By +.. section: Library + +If *debuglevel* is set to >0 in :mod:`http.client`, print all values for +headers with multiple values for the same header name. Patch by Matt +Houglum. + +.. + +.. bpo: 36492 +.. date: 2019-03-31-10-21-54 +.. nonce: f7vyUs +.. section: Library + +Deprecated passing required arguments like *func* as keyword arguments in +functions which should accept arbitrary keyword arguments and pass them to +other function. Arbitrary keyword arguments (even with names "self" and +"func") can now be passed to these functions if the required arguments are +passed as positional arguments. + +.. + +.. bpo: 27181 +.. date: 2019-03-31-01-18-52 +.. nonce: LVUWcc +.. section: Library + +Add statistics.geometric_mean(). + +.. + +.. bpo: 30427 +.. date: 2019-03-28-21-17-08 +.. nonce: lxzvbw +.. section: Library + +``os.path.normcase()`` relies on ``os.fspath()`` to check the type of its +argument. Redundant checks have been removed from its +``posixpath.normcase()`` and ``ntpath.normcase()`` implementations. Patch by +Wolfgang Maier. + +.. + +.. bpo: 36385 +.. date: 2019-03-27-02-09-22 +.. nonce: we2F45 +.. section: Library + +Stop rejecting IPv4 octets for being ambiguously octal. Leading zeros are +ignored, and no longer are assumed to specify octal octets. Octets are +always decimal numbers. Octets must still be no more than three digits, +including leading zeroes. + +.. + +.. bpo: 36434 +.. date: 2019-03-26-14-20-59 +.. nonce: PTdidw +.. section: Library + +Errors during writing to a ZIP file no longer prevent to properly close it. + +.. + +.. bpo: 36407 +.. date: 2019-03-23-17-16-15 +.. nonce: LG3aC4 +.. section: Library + +Fixed wrong indentation writing for CDATA section in xml.dom.minidom. Patch +by Vladimir Surjaninov. + +.. + +.. bpo: 36326 +.. date: 2019-03-22-13-47-52 +.. nonce: WCnEI5 +.. section: Library + +inspect.getdoc() can now find docstrings for member objects when __slots__ +is a dictionary. + +.. + +.. bpo: 36366 +.. date: 2019-03-20-15-13-18 +.. nonce: n0eav_ +.. section: Library + +Calling ``stop()`` on an unstarted or stopped :func:`unittest.mock.patch` +object will now return `None` instead of raising :exc:`RuntimeError`, making +the method idempotent. Patch by Karthikeyan Singaravelan. + +.. + +.. bpo: 36348 +.. date: 2019-03-18-16-16-55 +.. nonce: E0w_US +.. section: Library + +The :meth:`imap.IMAP4.logout` method no longer ignores silently arbitrary +exceptions. + +.. + +.. bpo: 31904 +.. date: 2019-03-13-16-48-42 +.. nonce: 9sjd38 +.. section: Library + +Add time module support and fix test_time faiures for VxWorks. + +.. + +.. bpo: 36227 +.. date: 2019-03-07-20-02-18 +.. nonce: i2Z1XR +.. section: Library + +Added support for keyword arguments `default_namespace` and +`xml_declaration` in functions ElementTree.tostring() and +ElementTree.tostringlist(). + +.. + +.. bpo: 36004 +.. date: 2019-02-17-12-55-51 +.. nonce: hCt_KK +.. section: Library + +Added new alternate constructors :meth:`datetime.date.fromisocalendar` and +:meth:`datetime.datetime.fromisocalendar`, which construct date objects from +ISO year, week number and weekday; these are the inverse of each class's +``isocalendar`` method. Patch by Paul Ganssle. + +.. + +.. bpo: 35936 +.. date: 2019-02-16-22-19-32 +.. nonce: Ay5WtD +.. section: Library + +:mod:`modulefinder` no longer depends on the deprecated :mod:`imp` module, +and the initializer for :class:`modulefinder.ModuleFinder` now has immutable +default arguments. Patch by Brandt Bucher. + +.. + +.. bpo: 35376 +.. date: 2019-02-13-18-56-27 +.. nonce: UFhYLj +.. section: Library + +:mod:`modulefinder` correctly handles modules that have the same name as a +bad package. Patch by Brandt Bucher. + +.. + +.. bpo: 17396 +.. date: 2019-02-13-18-56-22 +.. nonce: oKRkrD +.. section: Library + +:mod:`modulefinder` no longer crashes when encountering syntax errors in +followed imports. Patch by Brandt Bucher. + +.. + +.. bpo: 35934 +.. date: 2019-02-07-20-25-39 +.. nonce: QmfNmY +.. section: Library + +Added :meth:`~socket.create_server()` and +:meth:`~socket.has_dualstack_ipv6()` convenience functions to automate the +necessary tasks usually involved when creating a server socket, including +accepting both IPv4 and IPv6 connections on the same socket. (Contributed +by Giampaolo Rodola in :issue:`17561`.) + +.. + +.. bpo: 23078 +.. date: 2019-01-18-23-10-10 +.. nonce: l4dFoj +.. section: Library + +Add support for :func:`classmethod` and :func:`staticmethod` to +:func:`unittest.mock.create_autospec`. Initial patch by Felipe Ochoa. + +.. + +.. bpo: 35416 +.. date: 2018-12-05-09-55-05 +.. nonce: XALKZG +.. section: Library + +Fix potential resource warnings in distutils. Patch by Mickaël Schoentgen. + +.. + +.. bpo: 25451 +.. date: 2018-11-07-23-44-25 +.. nonce: re_8db +.. section: Library + +Add transparency methods to :class:`tkinter.PhotoImage`. Patch by Zackery +Spytz. + +.. + +.. bpo: 35082 +.. date: 2018-10-27-11-54-12 +.. nonce: HDj1nr +.. section: Library + +Don't return deleted attributes when calling dir on a +:class:`unittest.mock.Mock`. + +.. + +.. bpo: 34547 +.. date: 2018-10-05-16-01-00 +.. nonce: abbaa +.. section: Library + +:class:`wsgiref.handlers.BaseHandler` now handles abrupt client connection +terminations gracefully. Patch by Petter Strandmark. + +.. + +.. bpo: 31658 +.. date: 2018-07-30-12-00-15 +.. nonce: _bx7a_ +.. section: Library + +:func:`xml.sax.parse` now supports :term:`path-like <path-like object>`. +Patch by Mickaël Schoentgen. + +.. + +.. bpo: 34139 +.. date: 2018-07-18-11-25-34 +.. nonce: tKbmW7 +.. section: Library + +Remove stale unix datagram socket before binding + +.. + +.. bpo: 33530 +.. date: 2018-05-29-18-34-53 +.. nonce: _4Q_bi +.. section: Library + +Implemented Happy Eyeballs in `asyncio.create_connection()`. Added two new +arguments, *happy_eyeballs_delay* and *interleave*, to specify Happy +Eyeballs behavior. + +.. + +.. bpo: 33291 +.. date: 2018-04-11-11-41-52 +.. nonce: -xLGf8 +.. section: Library + +Do not raise AttributeError when calling the inspect functions +isgeneratorfunction, iscoroutinefunction, isasyncgenfunction on a method +created from an arbitrary callable. Instead, return False. + +.. + +.. bpo: 31310 +.. date: 2018-04-06-11-06-23 +.. nonce: eq9ky0 +.. section: Library + +Fix the multiprocessing.semaphore_tracker so it is reused by child processes + +.. + +.. bpo: 31292 +.. date: 2017-08-30-20-27-00 +.. nonce: dKIaZb +.. section: Library + +Fix ``setup.py check --restructuredtext`` for files containing ``include`` +directives. + +.. + +.. bpo: 36625 +.. date: 2019-04-15-12-02-45 +.. nonce: x3LMCF +.. section: Documentation + +Remove obsolete comments from docstrings in fractions.Fraction + +.. + +.. bpo: 30840 +.. date: 2019-04-14-19-46-21 +.. nonce: R-JFzw +.. section: Documentation + +Document relative imports + +.. + +.. bpo: 36523 +.. date: 2019-04-04-19-11-47 +.. nonce: sG1Tr4 +.. section: Documentation + +Add docstring for io.IOBase.writelines(). + +.. + +.. bpo: 36425 +.. date: 2019-03-27-22-46-00 +.. nonce: kG9gx1 +.. section: Documentation + +New documentation translation: `Simplified Chinese +<https://docs.python.org/zh-cn/>`_. + +.. + +.. bpo: 36345 +.. date: 2019-03-26-14-58-34 +.. nonce: r2stx3 +.. section: Documentation + +Avoid the duplication of code from ``Tools/scripts/serve.py`` in using the +:rst:dir:`literalinclude` directive for the basic wsgiref-based web server +in the documentation of :mod:`wsgiref`. Contributed by Stéphane Wirtel. + +.. + +.. bpo: 36345 +.. date: 2019-03-23-09-25-12 +.. nonce: L704Zv +.. section: Documentation + +Using the code of the ``Tools/scripts/serve.py`` script as an example in the +:mod:`wsgiref` documentation. Contributed by Stéphane Wirtel. + +.. + +.. bpo: 36157 +.. date: 2019-03-08-15-39-47 +.. nonce: nF1pP1 +.. section: Documentation + +Added Documention for PyInterpreterState_Main(). + +.. + +.. bpo: 33043 +.. date: 2019-02-24-03-15-10 +.. nonce: 8knWTS +.. section: Documentation + +Updates the docs.python.org page with the addition of a 'Contributing to +Docs' link at the end of the page (between 'Reporting Bugs' and 'About +Documentation'). Updates the 'Found a Bug' page with additional links and +information in the Documentation Bugs section. + +.. + +.. bpo: 35581 +.. date: 2018-12-25-12-56-57 +.. nonce: aA7r6T +.. section: Documentation + +@typing.type_check_only now allows type stubs to mark functions and classes +not available during runtime. + +.. + +.. bpo: 33832 +.. date: 2018-06-15-15-57-37 +.. nonce: xBFhKw +.. section: Documentation + +Add glossary entry for 'magic method'. + +.. + +.. bpo: 32913 +.. date: 2018-02-22-15-48-16 +.. nonce: f3utho +.. section: Documentation + +Added re.Match.groupdict example to regex HOWTO. + +.. + +.. bpo: 36719 +.. date: 2019-04-26-09-02-49 +.. nonce: ys2uqH +.. section: Tests + +regrtest now always detects uncollectable objects. Previously, the check was +only enabled by ``--findleaks``. The check now also works with +``-jN/--multiprocess N``. ``--findleaks`` becomes a deprecated alias to +``--fail-env-changed``. + +.. + +.. bpo: 36725 +.. date: 2019-04-26-04-12-29 +.. nonce: B8-ghi +.. section: Tests + +When using multiprocessing mode (-jN), regrtest now better reports errors if +a worker process fails, and it exits immediately on a worker thread failure +or when interrupted. + +.. + +.. bpo: 36454 +.. date: 2019-04-23-17-48-11 +.. nonce: 0q4lQz +.. section: Tests + +Change test_time.test_monotonic() to test only the lower bound of elapsed +time after a sleep command rather than the upper bound. This prevents +unnecessary test failures on slow buildbots. Patch by Victor Stinner. + +.. + +.. bpo: 32424 +.. date: 2019-04-21-17-55-18 +.. nonce: yDy49h +.. section: Tests + +Improve test coverage for xml.etree.ElementTree. Patch by Gordon P. Hemsley. + +.. + +.. bpo: 32424 +.. date: 2019-04-21-17-53-50 +.. nonce: Q4rBmn +.. section: Tests + +Fix typo in test_cyclic_gc() test for xml.etree.ElementTree. Patch by Gordon +P. Hemsley. + +.. + +.. bpo: 36635 +.. date: 2019-04-15-16-55-49 +.. nonce: __FTq9 +.. section: Tests + +Add a new :mod:`_testinternalcapi` module to test the internal C API. + +.. + +.. bpo: 36629 +.. date: 2019-04-15-11-57-39 +.. nonce: ySnaL3 +.. section: Tests + +Fix ``test_imap4_host_default_value()`` of ``test_imaplib``: catch also +:const:`errno.ENETUNREACH` error. + +.. + +.. bpo: 36611 +.. date: 2019-04-12-12-44-42 +.. nonce: UtorXL +.. section: Tests + +Fix ``test_sys.test_getallocatedblocks()`` when :mod:`tracemalloc` is +enabled. + +.. + +.. bpo: 36560 +.. date: 2019-04-09-14-08-02 +.. nonce: _ejeOr +.. section: Tests + +Fix reference leak hunting in regrtest: compute also deltas (of reference +count, allocated memory blocks, file descriptor count) during warmup, to +ensure that everything is initialized before starting to hunt reference +leaks. + +.. + +.. bpo: 36565 +.. date: 2019-04-08-19-01-21 +.. nonce: 2bxgtU +.. section: Tests + +Fix reference hunting (``python3 -m test -R 3:3``) when Python has no +built-in abc module. + +.. + +.. bpo: 31904 +.. date: 2019-04-08-09-24-36 +.. nonce: ab03ea +.. section: Tests + +Port test_resource to VxWorks: skip tests cases setting RLIMIT_FSIZE and +RLIMIT_CPU. + +.. + +.. bpo: 31904 +.. date: 2019-04-01-16-06-36 +.. nonce: peaceF +.. section: Tests + +Fix test_tabnanny on VxWorks: adjust ENOENT error message. + +.. + +.. bpo: 36436 +.. date: 2019-03-26-13-49-21 +.. nonce: yAtN0V +.. section: Tests + +Fix ``_testcapi.pymem_buffer_overflow()``: handle memory allocation failure. + +.. + +.. bpo: 31904 +.. date: 2019-03-19-17-39-25 +.. nonce: QxhhRx +.. section: Tests + +Fix test_utf8_mode on VxWorks: Python always use UTF-8 on VxWorks. + +.. + +.. bpo: 36341 +.. date: 2019-03-18-10-47-45 +.. nonce: UXlY0P +.. section: Tests + +Fix tests that may fail with PermissionError upon calling bind() on AF_UNIX +sockets. + +.. + +.. bpo: 36747 +.. date: 2019-04-29-09-57-20 +.. nonce: 1YEyu- +.. section: Build + +Remove the stale scriptsinstall Makefile target. + +.. + +.. bpo: 21536 +.. date: 2019-04-25-01-51-52 +.. nonce: ACQkiC +.. section: Build + +On Unix, C extensions are no longer linked to libpython except on Android +and Cygwin. + +It is now possible for a statically linked Python to load a C extension +built using a shared library Python. + +When Python is embedded, ``libpython`` must not be loaded with +``RTLD_LOCAL``, but ``RTLD_GLOBAL`` instead. Previously, using +``RTLD_LOCAL``, it was already not possible to load C extensions which were +not linked to ``libpython``, such as C extensions of the standard library +built by the ``*shared*`` section of ``Modules/Setup``. + +distutils, python-config and python-config.py have been modified. + +.. + +.. bpo: 36707 +.. date: 2019-04-24-02-29-15 +.. nonce: 8ZNB67 +.. section: Build + +``./configure --with-pymalloc`` no longer adds the ``m`` flag to SOABI +(sys.implementation.cache_tag). Enabling or disabling pymalloc has no impact +on the ABI. + +.. + +.. bpo: 36635 +.. date: 2019-04-16-13-58-52 +.. nonce: JKlzkf +.. section: Build + +Change ``PyAPI_FUNC(type)``, ``PyAPI_DATA(type)`` and ``PyMODINIT_FUNC`` +macros of ``pyport.h`` when ``Py_BUILD_CORE_MODULE`` is defined. The +``Py_BUILD_CORE_MODULE`` define must be now be used to build a C extension +as a dynamic library accessing Python internals: export the :samp:`PyInit_{xxx}()` +function in DLL exports on Windows. + +.. + +.. bpo: 31904 +.. date: 2019-04-15-15-01-29 +.. nonce: 38fdkg +.. section: Build + +Don't build the ``_crypt`` extension on VxWorks. + +.. + +.. bpo: 36618 +.. date: 2019-04-12-19-49-10 +.. nonce: gcI9iq +.. section: Build + +Add ``-fmax-type-align=8`` to CFLAGS when clang compiler is detected. The +pymalloc memory allocator aligns memory on 8 bytes. On x86-64, clang expects +alignment on 16 bytes by default and so uses MOVAPS instruction which can +lead to segmentation fault. Instruct clang that Python is limited to +alignment on 8 bytes to use MOVUPS instruction instead: slower but don't +trigger a SIGSEGV if the memory is not aligned on 16 bytes. Sadly, the flag +must be added to ``CFLAGS`` and not just ``CFLAGS_NODIST``, since third +party C extensions can have the same issue. + +.. + +.. bpo: 36605 +.. date: 2019-04-11-18-50-58 +.. nonce: gk5czf +.. section: Build + +``make tags`` and ``make TAGS`` now also parse ``Modules/_io/*.c`` and +``Modules/_io/*.h``. + +.. + +.. bpo: 36465 +.. date: 2019-04-09-18-19-43 +.. nonce: -w6vx6 +.. section: Build + +Release builds and debug builds are now ABI compatible: defining the +``Py_DEBUG`` macro no longer implies the ``Py_TRACE_REFS`` macro, which +introduces the only ABI incompatibility. The ``Py_TRACE_REFS`` macro, which +adds the :func:`sys.getobjects` function and the :envvar:`PYTHONDUMPREFS` +environment variable, can be set using the new ``./configure +--with-trace-refs`` build option. + +.. + +.. bpo: 36577 +.. date: 2019-04-09-17-31-47 +.. nonce: 34kuUW +.. section: Build + +setup.py now correctly reports missing OpenSSL headers and libraries again. + +.. + +.. bpo: 36544 +.. date: 2019-04-06-18-53-03 +.. nonce: hJr2_a +.. section: Build + +Fix regression introduced in bpo-36146 refactoring setup.py + +.. + +.. bpo: 36508 +.. date: 2019-04-02-17-01-23 +.. nonce: SN5Y6N +.. section: Build + +``python-config --ldflags`` no longer includes flags of the +``LINKFORSHARED`` variable. The ``LINKFORSHARED`` variable must only be used +to build executables. + +.. + +.. bpo: 36503 +.. date: 2019-04-02-09-25-23 +.. nonce: 0xzfkQ +.. section: Build + +Remove references to "aix3" and "aix4". Patch by M. Felt. + +.. + +.. bpo: 35920 +.. date: 2019-04-22-16-59-20 +.. nonce: VSfGOI +.. section: Windows + +Added platform.win32_edition() and platform.win32_is_iot(). Added support +for cross-compiling packages for Windows ARM32. Skip tests that are not +expected to work on Windows IoT Core ARM32. + +.. + +.. bpo: 36649 +.. date: 2019-04-17-11-39-24 +.. nonce: arbzIo +.. section: Windows + +Remove trailing spaces for registry keys when installed via the Store. + +.. + +.. bpo: 34144 +.. date: 2019-04-10-04-35-31 +.. nonce: _KzB5z +.. section: Windows + +Fixed activate.bat to correctly update codepage when chcp.com returns dots +in output. Patch by Lorenz Mende. + +.. + +.. bpo: 36509 +.. date: 2019-04-02-10-11-18 +.. nonce: DdaM67 +.. section: Windows + +Added preset-iot layout for Windows IoT ARM containers. This layout doesn't +contain UI components like tkinter or IDLE. It also doesn't contain files to +support on-target builds since Windows ARM32 builds must be cross-compiled +when using MSVC. + +.. + +.. bpo: 35941 +.. date: 2019-03-28-03-51-16 +.. nonce: UnlAEE +.. section: Windows + +enum_certificates function of the ssl module now returns certificates from +all available certificate stores inside windows in a query instead of +returning only certificates from the system wide certificate store. This +includes certificates from these certificate stores: local machine, local +machine enterprise, local machine group policy, current user, current user +group policy, services, users. ssl.enum_crls() function is changed in the +same way to return all certificate revocation lists inside the windows +certificate revocation list stores. + +.. + +.. bpo: 36441 +.. date: 2019-03-26-11-46-15 +.. nonce: lYjGF1 +.. section: Windows + +Fixes creating a venv when debug binaries are installed. + +.. + +.. bpo: 36085 +.. date: 2019-03-18-11-44-49 +.. nonce: mLfxfc +.. section: Windows + +Enable better DLL resolution on Windows by using safe DLL search paths and +adding :func:`os.add_dll_directory`. + +.. + +.. bpo: 36010 +.. date: 2019-03-16-10-24-58 +.. nonce: dttWfp +.. section: Windows + +Add the venv standard library module to the nuget distribution for Windows. + +.. + +.. bpo: 29515 +.. date: 2019-03-05-18-09-43 +.. nonce: vwUTv0 +.. section: Windows + +Add the following socket module constants on Windows: IPPROTO_AH IPPROTO_CBT +IPPROTO_DSTOPTS IPPROTO_EGP IPPROTO_ESP IPPROTO_FRAGMENT IPPROTO_GGP +IPPROTO_HOPOPTS IPPROTO_ICLFXBM IPPROTO_ICMPV6 IPPROTO_IDP IPPROTO_IGMP +IPPROTO_IGP IPPROTO_IPV4 IPPROTO_IPV6 IPPROTO_L2TP IPPROTO_MAX IPPROTO_ND +IPPROTO_NONE IPPROTO_PGM IPPROTO_PIM IPPROTO_PUP IPPROTO_RDP IPPROTO_ROUTING +IPPROTO_SCTP IPPROTO_ST + +.. + +.. bpo: 35947 +.. date: 2019-02-11-14-53-17 +.. nonce: 9vI4hP +.. section: Windows + +Added current version of libffi to cpython-source-deps. Change _ctypes to +use current version of libffi on Windows. + +.. + +.. bpo: 34060 +.. date: 2018-07-20-13-09-19 +.. nonce: v-z87j +.. section: Windows + +Report system load when running test suite on Windows. Patch by Ammar Askar. +Based on prior work by Jeremy Kloth. + +.. + +.. bpo: 31512 +.. date: 2017-10-04-12-40-45 +.. nonce: YQeBt2 +.. section: Windows + +With the Windows 10 Creators Update, non-elevated users can now create +symlinks as long as the computer has Developer Mode enabled. + +.. + +.. bpo: 34602 +.. date: 2019-04-29-10-54-14 +.. nonce: Lrl2zU +.. section: macOS + +Avoid failures setting macOS stack resource limit with resource.setrlimit. +This reverts an earlier fix for bpo-18075 which forced a non-default stack +size when building the interpreter executable on macOS. + +.. + +.. bpo: 36429 +.. date: 2019-03-26-00-09-50 +.. nonce: w-jL2e +.. section: IDLE + +Fix starting IDLE with pyshell. Add idlelib.pyshell alias at top; remove +pyshell alias at bottom. Remove obsolete __name__=='__main__' command. + +.. + +.. bpo: 14546 +.. date: 2019-04-30-14-30-29 +.. nonce: r38Y-6 +.. section: Tools/Demos + +Fix the argument handling in Tools/scripts/lll.py. + +.. + +.. bpo: 36763 +.. date: 2019-05-01-00-42-08 +.. nonce: vghb86 +.. section: C API + +Fix memory leak in :c:func:`Py_SetStandardStreamEncoding`: release memory if +the function is called twice. + +.. + +.. bpo: 36641 +.. date: 2019-04-16-21-18-19 +.. nonce: pz-DIR +.. section: C API + +:c:expr:`PyDoc_VAR(name)` and :c:expr:`PyDoc_STRVAR(name,str)` now create +``static const char name[]`` instead of ``static char name[]``. Patch by +Inada Naoki. + +.. + +.. bpo: 36389 +.. date: 2019-04-11-12-20-35 +.. nonce: P9QFoP +.. section: C API + +Change the value of ``CLEANBYTE``, ``DEADDYTE`` and ``FORBIDDENBYTE`` +internal constants used by debug hooks on Python memory allocators +(:c:func:`PyMem_SetupDebugHooks` function). Byte patterns ``0xCB``, ``0xDB`` +and ``0xFB`` have been replaced with ``0xCD``, ``0xDD`` and ``0xFD`` to use +the same values than Windows CRT debug ``malloc()`` and ``free()``. + +.. + +.. bpo: 36443 +.. date: 2019-03-27-15-58-23 +.. nonce: tAfZR9 +.. section: C API + +Since Python 3.7.0, calling :c:func:`Py_DecodeLocale` before +:c:func:`Py_Initialize` produces mojibake if the ``LC_CTYPE`` locale is +coerced and/or if the UTF-8 Mode is enabled by the user configuration. The +LC_CTYPE coercion and UTF-8 Mode are now disabled by default to fix the +mojibake issue. They must now be enabled explicitly (opt-in) using the new +:c:func:`_Py_PreInitialize` API with ``_PyPreConfig``. + +.. + +.. bpo: 36025 +.. date: 2019-02-19-08-23-42 +.. nonce: tnwylQ +.. section: C API + +Fixed an accidental change to the datetime C API where the arguments to the +:c:func:`PyDate_FromTimestamp` function were incorrectly interpreted as a +single timestamp rather than an arguments tuple, which causes existing code +to start raising :exc:`TypeError`. The backwards-incompatible change was +only present in alpha releases of Python 3.8. Patch by Paul Ganssle. + +.. + +.. bpo: 35810 +.. date: 2019-01-23-12-38-11 +.. nonce: wpbWeb +.. section: C API + +Modify ``PyObject_Init`` to correctly increase the refcount of heap- +allocated Type objects. Also fix the refcounts of the heap-allocated types +that were either doing this manually or not decreasing the type's refcount +in tp_dealloc diff --git a/Misc/NEWS.d/3.8.0b1.rst b/Misc/NEWS.d/3.8.0b1.rst new file mode 100644 index 00000000..f8f180bc --- /dev/null +++ b/Misc/NEWS.d/3.8.0b1.rst @@ -0,0 +1,2052 @@ +.. bpo: 35907 +.. date: 2019-05-21-23-20-18 +.. nonce: NC_zNK +.. release date: 2019-06-04 +.. section: Security + +CVE-2019-9948: Avoid file reading by disallowing ``local-file://`` and +``local_file://`` URL schemes in ``URLopener().open()`` and +``URLopener().retrieve()`` of :mod:`urllib.request`. + +.. + +.. bpo: 33529 +.. date: 2019-02-24-18-48-16 +.. nonce: wpNNBD +.. section: Security + +Prevent fold function used in email header encoding from entering infinite +loop when there are too many non-ASCII characters in a header. + +.. + +.. bpo: 33164 +.. date: 2018-03-30-12-26-47 +.. nonce: aO29Cx +.. section: Security + +Updated blake2 implementation which uses secure memset implementation +provided by platform. + +.. + +.. bpo: 35814 +.. date: 2019-06-03-00-51-02 +.. nonce: Cf7sGY +.. section: Core and Builtins + +Allow unpacking in the right hand side of annotated assignments. In +particular, ``t: Tuple[int, ...] = x, y, *z`` is now allowed. + +.. + +.. bpo: 37126 +.. date: 2019-06-01-20-03-13 +.. nonce: tP6lL4 +.. section: Core and Builtins + +All structseq objects are now tracked by the garbage collector. Patch by +Pablo Galindo. + +.. + +.. bpo: 37122 +.. date: 2019-06-01-16-53-41 +.. nonce: dZ3-NY +.. section: Core and Builtins + +Make the *co_argcount* attribute of code objects represent the total number +of positional arguments (including positional-only arguments). The value of +*co_posonlyargcount* can be used to distinguish which arguments are +positional only, and the difference (*co_argcount* - *co_posonlyargcount*) +is the number of positional-or-keyword arguments. Patch by Pablo Galindo. + +.. + +.. bpo: 20092 +.. date: 2019-05-31-11-55-49 +.. nonce: KIMjBW +.. section: Core and Builtins + +Constructors of :class:`int`, :class:`float` and :class:`complex` will now +use the :meth:`~object.__index__` special method, if available and the +corresponding method :meth:`~object.__int__`, :meth:`~object.__float__` or +:meth:`~object.__complex__` is not available. + +.. + +.. bpo: 37087 +.. date: 2019-05-30-17-33-55 +.. nonce: vElenE +.. section: Core and Builtins + +Add native thread ID (TID) support to OpenBSD. + +.. + +.. bpo: 26219 +.. date: 2019-05-29-22-03-09 +.. nonce: Ovf1Qs +.. section: Core and Builtins + +Implemented per opcode cache mechanism and ``LOAD_GLOBAL`` instruction use +it. ``LOAD_GLOBAL`` is now about 40% faster. Contributed by Yury Selivanov, +and Inada Naoki. + +.. + +.. bpo: 37072 +.. date: 2019-05-28-18-18-55 +.. nonce: 1Hewl3 +.. section: Core and Builtins + +Fix crash in PyAST_FromNodeObject() when flags is NULL. + +.. + +.. bpo: 37029 +.. date: 2019-05-28-17-02-46 +.. nonce: MxpgfJ +.. section: Core and Builtins + +Freeing a great many small objects could take time quadratic in the number +of arenas, due to using linear search to keep ``obmalloc.c``'s list of +usable arenas sorted by order of number of free memory pools. This is +accomplished without search now, leaving the worst-case time linear in the +number of arenas. For programs where this quite visibly matters (typically +with more than 100 thousand small objects alive simultaneously), this can +greatly reduce the time needed to release their memory. + +.. + +.. bpo: 26423 +.. date: 2019-05-27-18-00-19 +.. nonce: RgUOE8 +.. section: Core and Builtins + +Fix possible overflow in ``wrap_lenfunc()`` when ``sizeof(long) < +sizeof(Py_ssize_t)`` (e.g., 64-bit Windows). + +.. + +.. bpo: 37050 +.. date: 2019-05-27-14-46-24 +.. nonce: 7MyZGg +.. section: Core and Builtins + +Improve the AST for "debug" f-strings, which use '=' to print out the source +of the expression being evaluated. Delete expr_text from the FormattedValue +node, and instead use a Constant string node (possibly merged with adjacent +constant expressions inside the f-string). + +.. + +.. bpo: 22385 +.. date: 2019-05-25-17-18-26 +.. nonce: VeVvhJ +.. section: Core and Builtins + +The `bytes.hex`, `bytearray.hex`, and `memoryview.hex` methods as well as +the `binascii.hexlify` and `b2a_hex` functions now have the ability to +include an optional separator between hex bytes. This functionality was +inspired by MicroPython's hexlify implementation. + +.. + +.. bpo: 26836 +.. date: 2019-05-25-08-18-01 +.. nonce: rplYWW +.. section: Core and Builtins + +Add :func:`os.memfd_create`. + +.. + +.. bpo: 37032 +.. date: 2019-05-24-12-38-40 +.. nonce: T8rSH8 +.. section: Core and Builtins + +Added new ``replace()`` method to the code type (:class:`types.CodeType`). + +.. + +.. bpo: 37007 +.. date: 2019-05-23-04-19-13 +.. nonce: d1SOtF +.. section: Core and Builtins + +Implement :func:`socket.if_nameindex()`, :func:`socket.if_nametoindex()`, +and :func:`socket.if_indextoname()` on Windows. + +.. + +.. bpo: 36829 +.. date: 2019-05-22-23-01-29 +.. nonce: MfOcUg +.. section: Core and Builtins + +:c:func:`PyErr_WriteUnraisable` now creates a traceback object if there is +no current traceback. Moreover, call :c:func:`PyErr_NormalizeException` and +:c:func:`PyException_SetTraceback` to normalize the exception value. Ignore +any error. + +.. + +.. bpo: 36878 +.. date: 2019-05-22-11-16-16 +.. nonce: QwLa3P +.. section: Core and Builtins + +Only accept text after `# type: ignore` if the first character is ASCII. +This is to disallow things like `# type: ignoreé`. + +.. + +.. bpo: 36878 +.. date: 2019-05-21-16-21-22 +.. nonce: EFRHZ3 +.. section: Core and Builtins + +Store text appearing after a `# type: ignore` comment in the AST. For +example a type ignore like `# type: ignore[E1000]` will have the string +`"[E1000]"` stored in its AST node. + +.. + +.. bpo: 2180 +.. date: 2019-05-17-18-34-30 +.. nonce: aBqHeW +.. section: Core and Builtins + +Treat line continuation at EOF as a ``SyntaxError`` by Anthony Sottile. + +.. + +.. bpo: 36907 +.. date: 2019-05-17-12-28-24 +.. nonce: rk7kgp +.. section: Core and Builtins + +Fix a crash when calling a C function with a keyword dict (``f(**kwargs)``) +and changing the dict ``kwargs`` while that function is running. + +.. + +.. bpo: 36946 +.. date: 2019-05-16-23-53-45 +.. nonce: qjxr0Y +.. section: Core and Builtins + +Fix possible signed integer overflow when handling slices. + +.. + +.. bpo: 36826 +.. date: 2019-05-15-14-01-09 +.. nonce: GLrO3W +.. section: Core and Builtins + +Add NamedExpression kind support to ast_unparse.c + +.. + +.. bpo: 1875 +.. date: 2019-05-15-01-29-29 +.. nonce: 9oxXFX +.. section: Core and Builtins + +A :exc:`SyntaxError` is now raised if a code blocks that will be optimized +away (e.g. if conditions that are always false) contains syntax errors. +Patch by Pablo Galindo. + +.. + +.. bpo: 36027 +.. date: 2019-05-12-18-46-50 +.. nonce: Q4YatQ +.. section: Core and Builtins + +Allow computation of modular inverses via three-argument ``pow``: the second +argument is now permitted to be negative in the case where the first and +third arguments are relatively prime. + +.. + +.. bpo: 36861 +.. date: 2019-05-08-20-42-40 +.. nonce: 72mvZM +.. section: Core and Builtins + +Update the Unicode database to version 12.1.0. + +.. + +.. bpo: 28866 +.. date: 2019-05-08-16-36-51 +.. nonce: qCv_bj +.. section: Core and Builtins + +Avoid caching attributes of classes which type defines mro() to avoid a hard +cache invalidation problem. + +.. + +.. bpo: 36851 +.. date: 2019-05-08-11-42-06 +.. nonce: J7DiCW +.. section: Core and Builtins + +The ``FrameType`` stack is now correctly cleaned up if the execution ends +with a return and the stack is not empty. + +.. + +.. bpo: 34616 +.. date: 2019-05-07-17-12-37 +.. nonce: 0Y0_9r +.. section: Core and Builtins + +The ``compile()`` builtin functions now support the +``ast.PyCF_ALLOW_TOP_LEVEL_AWAIT`` flag, which allow to compile sources +that contains top-level ``await``, ``async with`` or ``async for``. This is +useful to evaluate async-code from with an already async functions; for +example in a custom REPL. + +.. + +.. bpo: 36842 +.. date: 2019-05-07-16-50-12 +.. nonce: NYww_N +.. section: Core and Builtins + +Implement PEP 578, adding sys.audit, io.open_code and related APIs. + +.. + +.. bpo: 27639 +.. date: 2019-05-07-15-49-17 +.. nonce: b1Ah87 +.. section: Core and Builtins + +Correct return type for UserList slicing operations. Patch by Michael +Blahay, Erick Cervantes, and vaultah + +.. + +.. bpo: 36737 +.. date: 2019-05-07-12-18-11 +.. nonce: XAo6LY +.. section: Core and Builtins + +Move PyRuntimeState.warnings into per-interpreter state (via "module +state"). + +.. + +.. bpo: 36793 +.. date: 2019-05-04-16-15-33 +.. nonce: Izog4Z +.. section: Core and Builtins + +Removed ``__str__`` implementations from builtin types :class:`bool`, +:class:`int`, :class:`float`, :class:`complex` and few classes from the +standard library. They now inherit ``__str__()`` from :class:`object`. + +.. + +.. bpo: 36817 +.. date: 2019-05-02-11-48-08 +.. nonce: ZqbJ1J +.. section: Core and Builtins + +Add a ``=`` feature f-strings for debugging. This can precede ``!s``, +``!r``, or ``!a``. It produces the text of the expression, followed by an +equal sign, followed by the repr of the value of the expression. So +``f'{3*9+15=}'`` would be equal to the string ``'3*9+15=42'``. If ``=`` is +specified, the default conversion is set to ``!r``, unless a format spec is +given, in which case the formatting behavior is unchanged, and __format__ +will be used. + +.. + +.. bpo: 24048 +.. date: 2019-04-29-03-27-22 +.. nonce: vXxUDQ +.. section: Core and Builtins + +Save the live exception during import.c's ``remove_module()``. + +.. + +.. bpo: 27987 +.. date: 2019-04-16-11-52-21 +.. nonce: n2_DcQ +.. section: Core and Builtins + +pymalloc returns memory blocks aligned by 16 bytes, instead of 8 bytes, on +64-bit platforms to conform x86-64 ABI. Recent compilers assume this +alignment more often. Patch by Inada Naoki. + +.. + +.. bpo: 36601 +.. date: 2019-04-13-16-14-16 +.. nonce: mIgS7t +.. section: Core and Builtins + +A long-since-meaningless check for ``getpid() == main_pid`` was removed from +Python's internal C signal handler. + +.. + +.. bpo: 36594 +.. date: 2019-04-10-18-12-11 +.. nonce: fbnJAc +.. section: Core and Builtins + +Fix incorrect use of ``%p`` in format strings. Patch by Zackery Spytz. + +.. + +.. bpo: 36045 +.. date: 2019-02-24-12-44-46 +.. nonce: RO20OV +.. section: Core and Builtins + +builtins.help() now prefixes `async` for async functions + +.. + +.. bpo: 36084 +.. date: 2019-02-22-23-03-20 +.. nonce: 86Eh4X +.. section: Core and Builtins + +Add native thread ID (TID) to threading.Thread objects (supported platforms: +Windows, FreeBSD, Linux, macOS) + +.. + +.. bpo: 36035 +.. date: 2019-02-22-14-30-19 +.. nonce: -6dy1y +.. section: Core and Builtins + +Added fix for broken symlinks in combination with pathlib + +.. + +.. bpo: 35983 +.. date: 2019-02-13-16-47-19 +.. nonce: bNxsXv +.. section: Core and Builtins + +Added new trashcan macros to deal with a double deallocation that could +occur when the `tp_dealloc` of a subclass calls the `tp_dealloc` of a base +class and that base class uses the trashcan mechanism. Patch by Jeroen +Demeyer. + +.. + +.. bpo: 20602 +.. date: 2018-07-04-16-57-59 +.. nonce: sDLElw +.. section: Core and Builtins + +Do not clear :data:`sys.flags` and :data:`sys.float_info` during shutdown. +Patch by Zackery Spytz. + +.. + +.. bpo: 26826 +.. date: 2018-05-30-23-43-03 +.. nonce: NkRzjb +.. section: Core and Builtins + +Expose :func:`copy_file_range` as a low level API in the :mod:`os` module. + +.. + +.. bpo: 32388 +.. date: 2017-12-21-20-37-40 +.. nonce: 6w-i5t +.. section: Core and Builtins + +Remove cross-version binary compatibility requirement in tp_flags. + +.. + +.. bpo: 31862 +.. date: 2017-10-24-17-26-58 +.. nonce: 5Gea8L +.. section: Core and Builtins + +Port binascii to PEP 489 multiphase initialization. Patch by Marcel Plch. + +.. + +.. bpo: 37128 +.. date: 2019-06-01-22-54-03 +.. nonce: oGXBWN +.. section: Library + +Added :func:`math.perm`. + +.. + +.. bpo: 37120 +.. date: 2019-06-01-09-03-32 +.. nonce: FOKQLU +.. section: Library + +Add SSLContext.num_tickets to control the number of TLSv1.3 session tickets. + +.. + +.. bpo: 12202 +.. date: 2019-05-31-15-53-34 +.. nonce: nobzc9 +.. section: Library + +Fix the error handling in :meth:`msilib.SummaryInformation.GetProperty`. +Patch by Zackery Spytz. + +.. + +.. bpo: 26835 +.. date: 2019-05-31-11-33-11 +.. nonce: xGbUX0 +.. section: Library + +The fcntl module now contains file sealing constants for sealing of memfds. + +.. + +.. bpo: 29262 +.. date: 2019-05-30-21-25-14 +.. nonce: LdIzun +.. section: Library + +Add ``get_origin()`` and ``get_args()`` introspection helpers to ``typing`` +module. + +.. + +.. bpo: 12639 +.. date: 2019-05-30-16-16-47 +.. nonce: TQFOR4 +.. section: Library + +:meth:`msilib.Directory.start_component()` no longer fails if *keyfile* is +not ``None``. + +.. + +.. bpo: 36999 +.. date: 2019-05-30-13-30-46 +.. nonce: EjY_L2 +.. section: Library + +Add the ``asyncio.Task.get_coro()`` method to publicly expose the tasks's +coroutine object. + +.. + +.. bpo: 35246 +.. date: 2019-05-28-23-17-35 +.. nonce: oXT21d +.. section: Library + +Make :func:`asyncio.create_subprocess_exec` accept path-like arguments. + +.. + +.. bpo: 35279 +.. date: 2019-05-28-19-14-29 +.. nonce: PX7yl9 +.. section: Library + +Change default *max_workers* of ``ThreadPoolExecutor`` from ``cpu_count() * +5`` to ``min(32, cpu_count() + 4)``. Previous value was unreasonably large +on many cores machines. + +.. + +.. bpo: 37076 +.. date: 2019-05-28-12-17-10 +.. nonce: Bk2xOs +.. section: Library + +:func:`_thread.start_new_thread` now logs uncaught exception raised by the +function using :func:`sys.unraisablehook`, rather than +:func:`sys.excepthook`, so the hook gets access to the function which raised +the exception. + +.. + +.. bpo: 33725 +.. date: 2019-05-28-01-17-42 +.. nonce: fFZoDG +.. section: Library + +On macOS, the :mod:`multiprocessing` module now uses *spawn* start method by +default. + +.. + +.. bpo: 37054 +.. date: 2019-05-28-01-06-44 +.. nonce: sLULGQ +.. section: Library + +Fix destructor :class:`_pyio.BytesIO` and :class:`_pyio.TextIOWrapper`: +initialize their ``_buffer`` attribute as soon as possible (in the class +body), because it's used by ``__del__()`` which calls ``close()``. + +.. + +.. bpo: 37058 +.. date: 2019-05-26-19-05-24 +.. nonce: jmRu_g +.. section: Library + +PEP 544: Add ``Protocol`` and ``@runtime_checkable`` to the ``typing`` +module. + +.. + +.. bpo: 36933 +.. date: 2019-05-26-10-16-55 +.. nonce: 4w3eP9 +.. section: Library + +The functions ``sys.set_coroutine_wrapper`` and +``sys.get_coroutine_wrapper`` that were deprecated and marked for removal in +3.8 have been removed. + +.. + +.. bpo: 37047 +.. date: 2019-05-26-01-20-06 +.. nonce: K9epi8 +.. section: Library + +Handle late binding and attribute access in :class:`unittest.mock.AsyncMock` +setup for autospeccing. Document newly implemented async methods in +:class:`unittest.mock.MagicMock`. + +.. + +.. bpo: 37049 +.. date: 2019-05-25-19-48-42 +.. nonce: an2LXJ +.. section: Library + +PEP 589: Add ``TypedDict`` to the ``typing`` module. + +.. + +.. bpo: 37046 +.. date: 2019-05-25-19-12-53 +.. nonce: iuhQQj +.. section: Library + +PEP 586: Add ``Literal`` to the ``typing`` module. + +.. + +.. bpo: 37045 +.. date: 2019-05-25-18-36-50 +.. nonce: suHdVJ +.. section: Library + +PEP 591: Add ``Final`` qualifier and ``@final`` decorator to the ``typing`` +module. + +.. + +.. bpo: 37035 +.. date: 2019-05-24-18-16-07 +.. nonce: HFbJVT +.. section: Library + +Don't log OSError based exceptions if a fatal error has occurred in asyncio +transport. Peer can generate almost any OSError, user cannot avoid these +exceptions by fixing own code. Errors are still propagated to user code, +it's just logging them is pointless and pollute asyncio logs. + +.. + +.. bpo: 37001 +.. date: 2019-05-23-21-10-57 +.. nonce: DoLvTK +.. section: Library + +:func:`symtable.symtable` now accepts the same input types for source code +as the built-in :func:`compile` function. Patch by Dino Viehland. + +.. + +.. bpo: 37028 +.. date: 2019-05-23-18-57-34 +.. nonce: Vse6Pj +.. section: Library + +Implement asyncio REPL + +.. + +.. bpo: 37027 +.. date: 2019-05-23-18-46-56 +.. nonce: iH4eut +.. section: Library + +Return safe to use proxy socket object from +transport.get_extra_info('socket') + +.. + +.. bpo: 32528 +.. date: 2019-05-23-17-37-22 +.. nonce: sGnkcl +.. section: Library + +Make asyncio.CancelledError a BaseException. + +This will address the common mistake many asyncio users make: an "except +Exception" clause breaking Tasks cancellation. + +In addition to this change, we stop inheriting asyncio.TimeoutError and +asyncio.InvalidStateError from their concurrent.futures.* counterparts. +There's no point for these exceptions to share the inheritance chain. + +.. + +.. bpo: 1230540 +.. date: 2019-05-23-01-48-39 +.. nonce: oKTNEQ +.. section: Library + +Add a new :func:`threading.excepthook` function which handles uncaught +:meth:`threading.Thread.run` exception. It can be overridden to control how +uncaught :meth:`threading.Thread.run` exceptions are handled. + +.. + +.. bpo: 36996 +.. date: 2019-05-22-22-55-18 +.. nonce: XQx08d +.. section: Library + +Handle :func:`unittest.mock.patch` used as a decorator on async functions. + +.. + +.. bpo: 37008 +.. date: 2019-05-22-15-26-08 +.. nonce: WPbv31 +.. section: Library + +Add support for calling :func:`next` with the mock resulting from +:func:`unittest.mock.mock_open` + +.. + +.. bpo: 27737 +.. date: 2019-05-22-02-25-31 +.. nonce: 7bgKpa +.. section: Library + +Allow whitespace only header encoding in ``email.header`` - by Batuhan +Taskaya + +.. + +.. bpo: 36969 +.. date: 2019-05-21-12-31-21 +.. nonce: u7cxu7 +.. section: Library + +PDB command `args` now display positional only arguments. Patch contributed +by Rémi Lapeyre. + +.. + +.. bpo: 36969 +.. date: 2019-05-20-23-31-20 +.. nonce: JkZORP +.. section: Library + +PDB command `args` now display keyword only arguments. Patch contributed by +Rémi Lapeyre. + +.. + +.. bpo: 36983 +.. date: 2019-05-20-20-41-30 +.. nonce: hz-fLr +.. section: Library + +Add missing names to ``typing.__all__``: ``ChainMap``, ``ForwardRef``, +``OrderedDict`` - by Anthony Sottile. + +.. + +.. bpo: 36972 +.. date: 2019-05-20-17-08-26 +.. nonce: 3l3SGc +.. section: Library + +Add SupportsIndex protocol to the typing module to allow type checking to +detect classes that can be passed to `hex()`, `oct()` and `bin()`. + +.. + +.. bpo: 32972 +.. date: 2019-05-20-14-47-55 +.. nonce: LoeUNh +.. section: Library + +Implement ``unittest.IsolatedAsyncioTestCase`` to help testing asyncio-based code. + +.. + +.. bpo: 36952 +.. date: 2019-05-20-11-01-28 +.. nonce: MgZi7- +.. section: Library + +:func:`fileinput.input` and :class:`fileinput.FileInput` **bufsize** +argument has been removed (was deprecated and ignored since Python 3.6), and +as a result the **mode** and **openhook** arguments have been made +keyword-only. + +.. + +.. bpo: 36952 +.. date: 2019-05-20-08-54-41 +.. nonce: I_glok +.. section: Library + +Starting with Python 3.3, importing ABCs from :mod:`collections` is +deprecated, and import should be done from :mod:`collections.abc`. Still +being able to import from :mod:`collections` was marked for removal in 3.8, +but has been delayed to 3.9; documentation and ``DeprecationWarning`` +clarified. + +.. + +.. bpo: 36949 +.. date: 2019-05-19-06-54-26 +.. nonce: jBlG9F +.. section: Library + +Implement __repr__ for WeakSet objects. + +.. + +.. bpo: 36948 +.. date: 2019-05-17-21-42-58 +.. nonce: vnUDvk +.. section: Library + +Fix :exc:`NameError` in :meth:`urllib.request.URLopener.retrieve`. Patch by +Karthikeyan Singaravelan. + +.. + +.. bpo: 33524 +.. date: 2019-05-17-11-44-21 +.. nonce: 8y_xUU +.. section: Library + +Fix the folding of email header when the max_line_length is 0 or None and +the header contains non-ascii characters. Contributed by Licht Takeuchi +(@Licht-T). + +.. + +.. bpo: 24564 +.. date: 2019-05-16-23-40-36 +.. nonce: lIwV_7 +.. section: Library + +:func:`shutil.copystat` now ignores :const:`errno.EINVAL` on +:func:`os.setxattr` which may occur when copying files on filesystems +without extended attributes support. + +Original patch by Giampaolo Rodola, updated by Ying Wang. + +.. + +.. bpo: 36888 +.. date: 2019-05-16-18-02-08 +.. nonce: -H2Dkm +.. section: Library + +Python child processes can now access the status of their parent process +using multiprocessing.process.parent_process + +.. + +.. bpo: 36921 +.. date: 2019-05-15-21-35-23 +.. nonce: kA1306 +.. section: Library + +Deprecate ``@coroutine`` for sake of ``async def``. + +.. + +.. bpo: 25652 +.. date: 2019-05-14-21-39-52 +.. nonce: xLw42k +.. section: Library + +Fix bug in ``__rmod__`` of ``UserString`` - by Batuhan Taskaya. + +.. + +.. bpo: 36916 +.. date: 2019-05-14-15-39-34 +.. nonce: _GPsTt +.. section: Library + +Remove a message about an unhandled exception in a task when writer.write() +is used without await and writer.drain() fails with an exception. + +.. + +.. bpo: 36889 +.. date: 2019-05-14-12-25-44 +.. nonce: MChPqP +.. section: Library + +Introduce :class:`asyncio.Stream` class that merges +:class:`asyncio.StreamReader` and :class:`asyncio.StreamWriter` +functionality. :class:`asyncio.Stream` can work in readonly, writeonly and +readwrite modes. Provide :func:`asyncio.connect`, +:func:`asyncio.connect_unix`, :func:`asyncio.connect_read_pipe` and +:func:`asyncio.connect_write_pipe` factories to open :class:`asyncio.Stream` +connections. Provide :class:`asyncio.StreamServer` and +:class:`UnixStreamServer` to serve servers with asyncio.Stream API. Modify +:func:`asyncio.create_subprocess_shell` and +:func:`asyncio.create_subprocess_exec` to use :class:`asyncio.Stream` +instead of deprecated :class:`StreamReader` and :class:`StreamWriter`. +Deprecate :class:`asyncio.StreamReader` and :class:`asyncio.StreamWriter`. +Deprecate usage of private classes, e.g. :class:`asyncio.FlowControlMixing` +and :class:`asyncio.StreamReaderProtocol` outside of asyncio package. + +.. + +.. bpo: 36845 +.. date: 2019-05-14-07-57-02 +.. nonce: _GtFFf +.. section: Library + +Added validation of integer prefixes to the construction of IP networks and +interfaces in the ipaddress module. + +.. + +.. bpo: 23378 +.. date: 2019-05-14-05-38-22 +.. nonce: R25teI +.. section: Library + +Add an extend action to argparser. + +.. + +.. bpo: 36867 +.. date: 2019-05-13-13-02-43 +.. nonce: Qh-6mX +.. section: Library + +Fix a bug making a SharedMemoryManager instance and its parent process use +two separate resource_tracker processes. + +.. + +.. bpo: 23896 +.. date: 2019-05-13-05-49-15 +.. nonce: 8TtUKo +.. section: Library + +Adds a grammar to lib2to3.pygram that contains exec as a function not as +statement. + +.. + +.. bpo: 36895 +.. date: 2019-05-12-14-49-13 +.. nonce: ZZuuY7 +.. section: Library + +The function ``time.clock()`` was deprecated in 3.3 in favor of +``time.perf_counter()`` and marked for removal in 3.8, it has removed. + +.. + +.. bpo: 35545 +.. date: 2019-05-11-16-21-29 +.. nonce: FcvJvP +.. section: Library + +Fix asyncio discarding IPv6 scopes when ensuring hostname resolutions +internally + +.. + +.. bpo: 36887 +.. date: 2019-05-11-14-50-59 +.. nonce: XD3f22 +.. section: Library + +Add new function :func:`math.isqrt` to compute integer square roots. + +.. + +.. bpo: 34632 +.. date: 2019-05-11-02-30-45 +.. nonce: 8MXa7T +.. section: Library + +Introduce the ``importlib.metadata`` module with (provisional) support for +reading metadata from third-party packages. + +.. + +.. bpo: 36878 +.. date: 2019-05-10-22-00-06 +.. nonce: iigeqk +.. section: Library + +When using `type_comments=True` in `ast.parse`, treat `# type: ignore` +followed by a non-alphanumeric character and then arbitrary text as a type +ignore, instead of requiring nothing but whitespace or another comment. This +is to permit formations such as `# type: ignore[E1000]`. + +.. + +.. bpo: 36778 +.. date: 2019-05-10-01-06-36 +.. nonce: GRqeiS +.. section: Library + +``cp65001`` encoding (Windows code page 65001) becomes an alias to ``utf_8`` +encoding. + +.. + +.. bpo: 36867 +.. date: 2019-05-09-18-12-55 +.. nonce: FuwVTi +.. section: Library + +The multiprocessing.resource_tracker replaces the +multiprocessing.semaphore_tracker module. Other than semaphores, +resource_tracker also tracks shared_memory segments. + +.. + +.. bpo: 30262 +.. date: 2019-05-09-12-38-40 +.. nonce: Tu74ak +.. section: Library + +The ``Cache`` and ``Statement`` objects of the :mod:`sqlite3` module are not +exposed to the user. Patch by Aviv Palivoda. + +.. + +.. bpo: 24538 +.. date: 2019-05-09-08-35-18 +.. nonce: WK8Y-k +.. section: Library + +In `shutil.copystat()`, first copy extended file attributes and then file +permissions, since extended attributes can only be set on the destination +while it is still writeable. + +.. + +.. bpo: 36829 +.. date: 2019-05-08-12-51-37 +.. nonce: 8enFMA +.. section: Library + +Add new :func:`sys.unraisablehook` function which can be overridden to +control how "unraisable exceptions" are handled. It is called when an +exception has occurred but there is no way for Python to handle it. For +example, when a destructor raises an exception or during garbage collection +(:func:`gc.collect`). + +.. + +.. bpo: 36832 +.. date: 2019-05-07-15-00-45 +.. nonce: TExgqb +.. section: Library + +Introducing ``zipfile.Path``, a pathlib-compatible wrapper for traversing +zip files. + +.. + +.. bpo: 36814 +.. date: 2019-05-06-23-13-26 +.. nonce: dSeMz_ +.. section: Library + +Fix an issue where os.posix_spawnp() would incorrectly raise a TypeError +when file_actions is None. + +.. + +.. bpo: 33110 +.. date: 2019-05-06-22-34-47 +.. nonce: rSJSCh +.. section: Library + +Handle exceptions raised by functions added by concurrent.futures +add_done_callback correctly when the Future has already completed. + +.. + +.. bpo: 26903 +.. date: 2019-05-06-19-17-04 +.. nonce: 4payXb +.. section: Library + +Limit `max_workers` in `ProcessPoolExecutor` to 61 to work around a +WaitForMultipleObjects limitation. + +.. + +.. bpo: 36813 +.. date: 2019-05-06-18-28-38 +.. nonce: NXD0KZ +.. section: Library + +Fix :class:`~logging.handlers.QueueListener` to call ``queue.task_done()`` +upon stopping. Patch by Bar Harel. + +.. + +.. bpo: 36806 +.. date: 2019-05-05-16-14-38 +.. nonce: rAzF-x +.. section: Library + +Forbid creation of asyncio stream objects like StreamReader, StreamWriter, +Process, and their protocols outside of asyncio package. + +.. + +.. bpo: 36802 +.. date: 2019-05-05-10-12-23 +.. nonce: HYMc8P +.. section: Library + +Provide both sync and async calls for StreamWriter.write() and +StreamWriter.close() + +.. + +.. bpo: 36801 +.. date: 2019-05-05-09-45-44 +.. nonce: XrlFFs +.. section: Library + +Properly handle SSL connection closing in asyncio StreamWriter.drain() call. + +.. + +.. bpo: 36785 +.. date: 2019-05-03-20-47-55 +.. nonce: PQLnPq +.. section: Library + +Implement PEP 574 (pickle protocol 5 with out-of-band buffers). + +.. + +.. bpo: 36772 +.. date: 2019-05-01-20-41-53 +.. nonce: fV2K0F +.. section: Library + +functools.lru_cache() can now be used as a straight decorator in addition to +its existing usage as a function that returns a decorator. + +.. + +.. bpo: 6584 +.. date: 2019-04-30-04-34-53 +.. nonce: Hzp9-P +.. section: Library + +Add a :exc:`~gzip.BadGzipFile` exception to the :mod:`gzip` module. + +.. + +.. bpo: 36748 +.. date: 2019-04-29-15-18-13 +.. nonce: YBKWps +.. section: Library + +Optimized write buffering in C implementation of ``TextIOWrapper``. Writing +ASCII string to ``TextIOWrapper`` with ascii, latin1, or utf-8 encoding is +about 20% faster. Patch by Inada Naoki. + +.. + +.. bpo: 8138 +.. date: 2019-04-27-02-54-23 +.. nonce: osBRGI +.. section: Library + +Don't mark ``wsgiref.simple_server.SimpleServer`` as multi-threaded since +``wsgiref.simple_server.WSGIServer`` is single-threaded. + +.. + +.. bpo: 22640 +.. date: 2019-04-26-22-13-26 +.. nonce: p3rheW +.. section: Library + +:func:`py_compile.compile` now supports silent mode. Patch by Joannah +Nanjekye + +.. + +.. bpo: 29183 +.. date: 2019-04-22-22-55-29 +.. nonce: MILvsk +.. section: Library + +Fix double exceptions in :class:`wsgiref.handlers.BaseHandler` by calling +its :meth:`~wsgiref.handlers.BaseHandler.close` method only when no +exception is raised. + +.. + +.. bpo: 36548 +.. date: 2019-04-07-14-30-10 +.. nonce: CJQiYw +.. section: Library + +Improved the repr of regular expression flags. + +.. + +.. bpo: 36542 +.. date: 2019-04-06-12-36-09 +.. nonce: Q0qyYV +.. section: Library + +The signature of Python functions can now be overridden by specifying the +``__text_signature__`` attribute. + +.. + +.. bpo: 36533 +.. date: 2019-04-06-00-55-09 +.. nonce: kzMyRH +.. section: Library + +Reinitialize logging.Handler locks in forked child processes instead of +attempting to acquire them all in the parent before forking only to be +released in the child process. The acquire/release pattern was leading to +deadlocks in code that has implemented any form of chained logging handlers +that depend upon one another as the lock acquisition order cannot be +guaranteed. + +.. + +.. bpo: 35252 +.. date: 2019-04-02-19-23-12 +.. nonce: VooTVv +.. section: Library + +Throw a TypeError instead of an AssertionError when using an invalid type +annotation with singledispatch. + +.. + +.. bpo: 35900 +.. date: 2019-03-27-15-09-00 +.. nonce: fh56UU +.. section: Library + +Allow reduction methods to return a 6-item tuple where the 6th item +specifies a custom state-setting method that's called instead of the regular +``__setstate__`` method. + +.. + +.. bpo: 35900 +.. date: 2019-03-22-22-40-00 +.. nonce: oiee0o +.. section: Library + +enable custom reduction callback registration for functions and classes in +_pickle.c, using the new Pickler's attribute ``reducer_override`` + +.. + +.. bpo: 36368 +.. date: 2019-03-21-16-00-00 +.. nonce: zsRT1 +.. section: Library + +Fix a bug crashing SharedMemoryManager instances in interactive sessions +after a ctrl-c (KeyboardInterrupt) was sent + +.. + +.. bpo: 31904 +.. date: 2019-03-18-14-25-36 +.. nonce: ds3d67 +.. section: Library + +Fix mmap fail for VxWorks + +.. + +.. bpo: 27497 +.. date: 2019-03-13-10-57-41 +.. nonce: JDmIe_ +.. section: Library + +:meth:`csv.DictWriter.writeheader` now returns the return value of the +underlying :meth:`csv.Writer.writerow` method. Patch contributed by Ashish +Nitin Patil. + +.. + +.. bpo: 36239 +.. date: 2019-03-09-23-51-27 +.. nonce: BHJ3Ln +.. section: Library + +Parsing .mo files now ignores comments starting and ending with #-#-#-#-#. + +.. + +.. bpo: 26707 +.. date: 2019-03-04-01-28-33 +.. nonce: QY4kRZ +.. section: Library + +Enable plistlib to read and write binary plist files that were created as a +KeyedArchive file. Specifically, this allows the plistlib to process 0x80 +tokens as UID objects. + +.. + +.. bpo: 31904 +.. date: 2019-03-01-17-59-39 +.. nonce: 38djdk +.. section: Library + +Add posix module support for VxWorks. + +.. + +.. bpo: 35125 +.. date: 2019-02-15-17-18-50 +.. nonce: h0xk0f +.. section: Library + +Asyncio: Remove inner callback on outer cancellation in shield + +.. + +.. bpo: 35721 +.. date: 2019-01-18-16-23-00 +.. nonce: d8djAJ +.. section: Library + +Fix :meth:`asyncio.SelectorEventLoop.subprocess_exec()` leaks file +descriptors if ``Popen`` fails and called with ``stdin=subprocess.PIPE``. +Patch by Niklas Fiekas. + +.. + +.. bpo: 31855 +.. date: 2019-01-11-17-09-15 +.. nonce: PlhfsX +.. section: Library + +:func:`unittest.mock.mock_open` results now respects the argument of +read([size]). Patch contributed by Rémi Lapeyre. + +.. + +.. bpo: 35431 +.. date: 2019-01-02-19-48-23 +.. nonce: FhG6QA +.. section: Library + +Implement :func:`math.comb` that returns binomial coefficient, that computes +the number of ways to choose k items from n items without repetition and +without order. Patch by Yash Aggarwal and Keller Fuchs. + +.. + +.. bpo: 26660 +.. date: 2018-11-04-16-39-46 +.. nonce: RdXz8a +.. section: Library + +Fixed permission errors in :class:`~tempfile.TemporaryDirectory` clean up. +Previously ``TemporaryDirectory.cleanup()`` failed when non-writeable or +non-searchable files or directories were created inside a temporary +directory. + +.. + +.. bpo: 34271 +.. date: 2018-10-21-17-39-32 +.. nonce: P15VLM +.. section: Library + +Add debugging helpers to ssl module. It's now possible to dump key material +and to trace TLS protocol. The default and stdlib contexts also support +SSLKEYLOGFILE env var. + +.. + +.. bpo: 26467 +.. date: 2018-09-13-20-33-24 +.. nonce: cahAk3 +.. section: Library + +Added AsyncMock to support using unittest to mock asyncio coroutines. Patch +by Lisa Roach. + +.. + +.. bpo: 33569 +.. date: 2018-08-28-03-00-12 +.. nonce: 45YlGG +.. section: Library + +dataclasses.InitVar: Exposes the type used to create the init var. + +.. + +.. bpo: 34424 +.. date: 2018-08-18-14-47-00 +.. nonce: wAlRuS +.. section: Library + +Fix serialization of messages containing encoded strings when the +policy.linesep is set to a multi-character string. Patch by Jens Troeger. + +.. + +.. bpo: 34303 +.. date: 2018-08-03-09-47-20 +.. nonce: tOE2HP +.. section: Library + +Performance of :func:`functools.reduce` is slightly improved. Patch by +Sergey Fedoseev. + +.. + +.. bpo: 33361 +.. date: 2018-07-13-20-17-17 +.. nonce: dx2NVn +.. section: Library + +Fix a bug in :class:`codecs.StreamRecoder` where seeking might leave old +data in a buffer and break subsequent read calls. Patch by Ammar Askar. + +.. + +.. bpo: 22454 +.. date: 2018-06-10-17-48-07 +.. nonce: qeiy_X +.. section: Library + +The :mod:`shlex` module now exposes :func:`shlex.join`, the inverse of +:func:`shlex.split`. Patch by Bo Bayles. + +.. + +.. bpo: 31922 +.. date: 2018-05-30-01-05-50 +.. nonce: fobsXJ +.. section: Library + +:meth:`asyncio.AbstractEventLoop.create_datagram_endpoint`: Do not connect +UDP socket when broadcast is allowed. This allows to receive replies after a +UDP broadcast. + +.. + +.. bpo: 24882 +.. date: 2018-04-04-14-54-30 +.. nonce: urybpa +.. section: Library + +Change ThreadPoolExecutor to use existing idle threads before spinning up +new ones. + +.. + +.. bpo: 31961 +.. date: 2018-03-27-13-28-16 +.. nonce: GjLoYu +.. section: Library + +Added support for bytes and path-like objects in :func:`subprocess.Popen` on +Windows. The *args* parameter now accepts a :term:`path-like object` if +*shell* is ``False`` and a sequence containing bytes and path-like objects. +The *executable* parameter now accepts a bytes and :term:`path-like object`. +The *cwd* parameter now accepts a bytes object. Based on patch by Anders +Lorentsen. + +.. + +.. bpo: 33123 +.. date: 2018-03-22-19-13-19 +.. nonce: _Y5ooE +.. section: Library + +:class:`pathlib.Path.unlink` now accepts a *missing_ok* parameter to avoid a +:exc:`FileNotFoundError` from being raised. Patch by Robert Buchholz. + +.. + +.. bpo: 32941 +.. date: 2018-03-20-20-57-00 +.. nonce: 9FU0gL +.. section: Library + +Allow :class:`mmap.mmap` objects to access the madvise() system call +(through :meth:`mmap.mmap.madvise`). + +.. + +.. bpo: 22102 +.. date: 2018-03-08-16-15-00 +.. nonce: th33uD +.. section: Library + +Added support for ZIP files with disks set to 0. Such files are commonly +created by builtin tools on Windows when use ZIP64 extension. Patch by +Francisco Facioni. + +.. + +.. bpo: 32515 +.. date: 2018-01-07-21-04-50 +.. nonce: D8_Wcb +.. section: Library + +trace.py can now run modules via python3 -m trace -t --module module_name + +.. + +.. bpo: 32299 +.. date: 2017-12-13-17-49-56 +.. nonce: eqAPWs +.. section: Library + +Changed :func:`unittest.mock.patch.dict` to return the patched dictionary +when used as context manager. Patch by Vadim Tsander. + +.. + +.. bpo: 27141 +.. date: 2017-10-24-00-42-14 +.. nonce: zbAgSs +.. section: Library + +Added a ``__copy__()`` to ``collections.UserList`` and +``collections.UserDict`` in order to correctly implement shallow copying of +the objects. Patch by Bar Harel. + +.. + +.. bpo: 31829 +.. date: 2017-10-21-12-07-56 +.. nonce: 6IhP-O +.. section: Library + +``\r``, ``\0`` and ``\x1a`` (end-of-file on Windows) are now escaped in +protocol 0 pickles of Unicode strings. This allows to load them without loss +from files open in text mode in Python 2. + +.. + +.. bpo: 23395 +.. date: 2016-07-27-11-06-43 +.. nonce: MuCEX9 +.. section: Library + +``_thread.interrupt_main()`` now avoids setting the Python error status if +the ``SIGINT`` signal is ignored or not handled by Python. + +.. + +.. bpo: 36896 +.. date: 2019-05-31-10-46-36 +.. nonce: wkXTW9 +.. section: Documentation + +Clarify that some types have unstable constructor signature between Python +versions. + +.. + +.. bpo: 36686 +.. date: 2019-05-27-17-28-58 +.. nonce: Zot4sx +.. section: Documentation + +Improve documentation of the stdin, stdout, and stderr arguments of the +``asyncio.subprocess_exec`` function to specify which values are supported. +Also mention that decoding as text is not supported. + +Add a few tests to verify that the various values passed to the std* +arguments actually work. + +.. + +.. bpo: 36984 +.. date: 2019-05-20-22-21-17 +.. nonce: IjZlmS +.. section: Documentation + +Improve version added references in ``typing`` module - by Anthony Sottile. + +.. + +.. bpo: 36868 +.. date: 2019-05-11-17-42-15 +.. nonce: yioL0R +.. section: Documentation + +What's new now mentions SSLContext.hostname_checks_common_name instead of +SSLContext.host_flags. + +.. + +.. bpo: 35924 +.. date: 2019-05-08-13-17-44 +.. nonce: lqbNpW +.. section: Documentation + +Add a note to the ``curses.addstr()`` documentation to warn that multiline +strings can cause segfaults because of an ncurses bug. + +.. + +.. bpo: 36783 +.. date: 2019-05-07-02-30-51 +.. nonce: gpC8E2 +.. section: Documentation + +Added C API Documentation for Time_FromTimeAndFold and +PyDateTime_FromDateAndTimeAndFold as per PEP 495. Patch by Edison Abahurire. + +.. + +.. bpo: 36797 +.. date: 2019-05-05-07-58-50 +.. nonce: W1X4On +.. section: Documentation + +More of the legacy distutils documentation has been either pruned, or else +more clearly marked as being retained solely until the setuptools +documentation covers it independently. + +.. + +.. bpo: 22865 +.. date: 2019-02-21-18-13-50 +.. nonce: 6hg6J8 +.. section: Documentation + +Add detail to the documentation on the `pty.spawn` function. + +.. + +.. bpo: 35397 +.. date: 2019-01-09-17-56-35 +.. nonce: ZMreIz +.. section: Documentation + +Remove deprecation and document urllib.parse.unwrap(). Patch contributed by +Rémi Lapeyre. + +.. + +.. bpo: 32995 +.. date: 2018-10-07-03-04-57 +.. nonce: TXN9ur +.. section: Documentation + +Added the context variable in glossary. + +.. + +.. bpo: 33519 +.. date: 2018-05-17-21-02-00 +.. nonce: Q7s2FB +.. section: Documentation + +Clarify that `copy()` is not part of the `MutableSequence` ABC. + +.. + +.. bpo: 33482 +.. date: 2018-05-13-10-36-37 +.. nonce: jalAaQ +.. section: Documentation + +Make `codecs.StreamRecoder.writelines` take a list of bytes. + +.. + +.. bpo: 25735 +.. date: 2018-04-08-19-09-22 +.. nonce: idVQBD +.. section: Documentation + +Added documentation for func factorial to indicate that returns integer +values + +.. + +.. bpo: 20285 +.. date: 2017-12-08-20-30-37 +.. nonce: cfnp0J +.. section: Documentation + +Expand object.__doc__ (docstring) to make it clearer. Modify pydoc.py so +that help(object) lists object methods (for other classes, help omits +methods of the object base class.) + +.. + +.. bpo: 37069 +.. date: 2019-06-03-02-30-36 +.. nonce: rVtdLk +.. section: Tests + +Modify test_coroutines, test_cprofile, test_generators, test_raise, test_ssl +and test_yield_from to use :func:`test.support.catch_unraisable_exception` +rather than :func:`test.support.captured_stderr`. + +.. + +.. bpo: 37098 +.. date: 2019-05-30-10-57-39 +.. nonce: SfXt1M +.. section: Tests + +Fix test_memfd_create on older Linux Kernels. + +.. + +.. bpo: 37081 +.. date: 2019-05-28-17-48-22 +.. nonce: qxB-1l +.. section: Tests + +Test with OpenSSL 1.1.1c + +.. + +.. bpo: 36829 +.. date: 2019-05-22-12-57-15 +.. nonce: e9mRWC +.. section: Tests + +Add :func:`test.support.catch_unraisable_exception`: context manager +catching unraisable exception using :func:`sys.unraisablehook`. + +.. + +.. bpo: 36915 +.. date: 2019-05-14-14-12-24 +.. nonce: 58b7pH +.. section: Tests + +The main regrtest process now always removes all temporary directories of +worker processes even if they crash or if they are killed on +KeyboardInterrupt (CTRL+c). + +.. + +.. bpo: 36719 +.. date: 2019-05-10-01-50-30 +.. nonce: O84ZWv +.. section: Tests + +"python3 -m test -jN ..." now continues the execution of next tests when a +worker process crash (CHILD_ERROR state). Previously, the test suite stopped +immediately. Use --failfast to stop at the first error. + +.. + +.. bpo: 36816 +.. date: 2019-05-08-15-55-46 +.. nonce: WBKRGZ +.. section: Tests + +Update Lib/test/selfsigned_pythontestdotnet.pem to match +self-signed.pythontest.net's new TLS certificate. + +.. + +.. bpo: 35925 +.. date: 2019-05-06-18-29-54 +.. nonce: gwQPuC +.. section: Tests + +Skip httplib and nntplib networking tests when they would otherwise fail due +to a modern OS or distro with a default OpenSSL policy of rejecting +connections to servers with weak certificates. + +.. + +.. bpo: 36782 +.. date: 2019-05-04-21-25-19 +.. nonce: h3oPIb +.. section: Tests + +Add tests for several C API functions in the :mod:`datetime` module. Patch +by Edison Abahurire. + +.. + +.. bpo: 36342 +.. date: 2019-03-23-13-58-49 +.. nonce: q6Quiq +.. section: Tests + +Fix test_multiprocessing in test_venv if platform lacks functioning +sem_open. + +.. + +.. bpo: 36721 +.. date: 2019-05-22-16-19-18 +.. nonce: 9aRwfZ +.. section: Build + +To embed Python into an application, a new ``--embed`` option must be passed +to ``python3-config --libs --embed`` to get ``-lpython3.8`` (link the +application to libpython). To support both 3.8 and older, try +``python3-config --libs --embed`` first and fallback to ``python3-config +--libs`` (without ``--embed``) if the previous command fails. + +Add a pkg-config ``python-3.8-embed`` module to embed Python into an +application: ``pkg-config python-3.8-embed --libs`` includes +``-lpython3.8``. To support both 3.8 and older, try ``pkg-config +python-X.Y-embed --libs`` first and fallback to ``pkg-config python-X.Y +--libs`` (without ``--embed``) if the previous command fails (replace +``X.Y`` with the Python version). + +On the other hand, ``pkg-config python3.8 --libs`` no longer contains +``-lpython3.8``. C extensions must not be linked to libpython (except on +Android, case handled by the script); this change is backward incompatible +on purpose. + +.. + +.. bpo: 36786 +.. date: 2019-05-03-21-08-06 +.. nonce: gOLFbD +.. section: Build + +"make install" now runs compileall in parallel. + +.. + +.. bpo: 36965 +.. date: 2019-05-20-20-26-36 +.. nonce: KsfI-N +.. section: Windows + +include of STATUS_CONTROL_C_EXIT without depending on MSC compiler + +.. + +.. bpo: 35926 +.. date: 2019-03-01-16-43-45 +.. nonce: mLszHo +.. section: Windows + +Update to OpenSSL 1.1.1b for Windows. + +.. + +.. bpo: 29883 +.. date: 2018-09-15-11-36-55 +.. nonce: HErerE +.. section: Windows + +Add Windows support for UDP transports for the Proactor Event Loop. Patch by +Adam Meily. + +.. + +.. bpo: 33407 +.. date: 2018-08-28-17-23-49 +.. nonce: ARG0W_ +.. section: Windows + +The :c:macro:`Py_DEPRECATED()` macro has been implemented for MSVC. + +.. + +.. bpo: 36231 +.. date: 2019-06-03-05-49-49 +.. nonce: RfmW_p +.. section: macOS + +Support building Python on macOS without /usr/include installed. As of macOS +10.14, system header files are only available within an SDK provided by +either the Command Line Tools or the Xcode app. + +.. + +.. bpo: 35610 +.. date: 2019-06-02-14-10-52 +.. nonce: 0w_v6Y +.. section: IDLE + +Replace now redundant .context_use_ps1 with .prompt_last_line. This finishes +change started in bpo-31858. + +.. + +.. bpo: 37038 +.. date: 2019-05-24-18-57-57 +.. nonce: AJ3RwQ +.. section: IDLE + +Make idlelib.run runnable; add test clause. + +.. + +.. bpo: 36958 +.. date: 2019-05-19-22-02-22 +.. nonce: DZUC6G +.. section: IDLE + +Print any argument other than None or int passed to SystemExit or +sys.exit(). + +.. + +.. bpo: 36807 +.. date: 2019-05-05-16-27-53 +.. nonce: AGNWYJ +.. section: IDLE + +When saving a file, call os.fsync() so bits are flushed to e.g. USB drive. + +.. + +.. bpo: 32411 +.. date: 2017-12-25-18-48-50 +.. nonce: vNwDhe +.. section: IDLE + +In browser.py, remove extraneous sorting by line number since dictionary was +created in line number order. + +.. + +.. bpo: 37053 +.. date: 2019-05-26-16-47-06 +.. nonce: -EYRuz +.. section: Tools/Demos + +Handle strings like u"bar" correctly in Tools/parser/unparse.py. Patch by +Chih-Hsuan Yen. + +.. + +.. bpo: 36763 +.. date: 2019-05-27-12-25-25 +.. nonce: bHCA9j +.. section: C API + +Implement the :pep:`587` "Python Initialization Configuration". + +.. + +.. bpo: 36379 +.. date: 2019-05-24-07-11-08 +.. nonce: 8zgoKe +.. section: C API + +Fix crashes when attempting to use the *modulo* parameter when ``__ipow__`` +is implemented in C. + +.. + +.. bpo: 37107 +.. date: 2019-05-22-17-33-52 +.. nonce: 8BVPR- +.. section: C API + +Update :c:func:`PyObject_CallMethodObjArgs` and +``_PyObject_CallMethodIdObjArgs`` to use ``_PyObject_GetMethod`` to avoid +creating a bound method object in many cases. Patch by Michael J. Sullivan. + +.. + +.. bpo: 36974 +.. date: 2019-05-22-15-24-08 +.. nonce: TkySRe +.. section: C API + +Implement :pep:`590`: Vectorcall: a fast calling protocol for CPython. This +is a new protocol to optimize calls of custom callable objects. + +.. + +.. bpo: 36763 +.. date: 2019-05-17-19-23-24 +.. nonce: TswmDy +.. section: C API + +``Py_Main()`` now returns the exitcode rather than calling +``Py_Exit(exitcode)`` when calling ``PyErr_Print()`` if the current +exception type is ``SystemExit``. + +.. + +.. bpo: 36922 +.. date: 2019-05-15-10-46-55 +.. nonce: J3EFK_ +.. section: C API + +Add new type flag ``Py_TPFLAGS_METHOD_DESCRIPTOR`` for objects behaving like +unbound methods. These are objects supporting the optimization given by the +``LOAD_METHOD``/``CALL_METHOD`` opcodes. See PEP 590. + +.. + +.. bpo: 36728 +.. date: 2019-05-11-03-56-23 +.. nonce: FR-dMP +.. section: C API + +The :c:func:`!PyEval_ReInitThreads` function has been removed from the C API. +It should not be called explicitly: use :c:func:`PyOS_AfterFork_Child` +instead. diff --git a/Misc/NEWS.d/3.9.0a1.rst b/Misc/NEWS.d/3.9.0a1.rst new file mode 100644 index 00000000..a4d71d02 --- /dev/null +++ b/Misc/NEWS.d/3.9.0a1.rst @@ -0,0 +1,5772 @@ +.. bpo: 38722 +.. date: 2019-11-18-16-17-56 +.. nonce: x3mECW +.. release date: 2019-11-19 +.. section: Security + +:mod:`runpy` now uses :meth:`io.open_code` to open code files. Patch by +Jason Killen. + +.. + +.. bpo: 38622 +.. date: 2019-11-14-16-13-23 +.. nonce: 3DYkfb +.. section: Security + +Add additional audit events for the :mod:`ctypes` module. + +.. + +.. bpo: 38418 +.. date: 2019-10-08-19-29-55 +.. nonce: QL7s0- +.. section: Security + +Fixes audit event for :func:`os.system` to be named ``os.system``. + +.. + +.. bpo: 38243 +.. date: 2019-09-25-13-21-09 +.. nonce: 1pfz24 +.. section: Security + +Escape the server title of :class:`xmlrpc.server.DocXMLRPCServer` when +rendering the document page as HTML. (Contributed by Donghee Na in +:issue:`38243`.) + +.. + +.. bpo: 38174 +.. date: 2019-09-23-21-02-46 +.. nonce: MeWuJd +.. section: Security + +Update vendorized expat library version to 2.2.8, which resolves +CVE-2019-15903. + +.. + +.. bpo: 37764 +.. date: 2019-08-27-01-13-05 +.. nonce: qv67PQ +.. section: Security + +Fixes email._header_value_parser.get_unstructured going into an infinite +loop for a specific case in which the email header does not have trailing +whitespace, and the case in which it contains an invalid encoded word. Patch +by Ashwin Ramaswami. + +.. + +.. bpo: 37461 +.. date: 2019-07-16-08-11-00 +.. nonce: 1Ahz7O +.. section: Security + +Fix an infinite loop when parsing specially crafted email headers. Patch by +Abhilash Raj. + +.. + +.. bpo: 37363 +.. date: 2019-07-01-10-31-14 +.. nonce: fSjatj +.. section: Security + +Adds audit events for the range of supported run commands (see +:ref:`using-on-general`). + +.. + +.. bpo: 37463 +.. date: 2019-07-01-08-46-14 +.. nonce: 1CHwjE +.. section: Security + +ssl.match_hostname() no longer accepts IPv4 addresses with additional text +after the address and only quad-dotted notation without trailing +whitespaces. Some inet_aton() implementations ignore whitespace and all data +after whitespace, e.g. '127.0.0.1 whatever'. + +.. + +.. bpo: 37363 +.. date: 2019-06-21-15-58-59 +.. nonce: diouyl +.. section: Security + +Adds audit events for :mod:`ensurepip`, :mod:`ftplib`, :mod:`glob`, +:mod:`imaplib`, :mod:`nntplib`, :mod:`pdb`, :mod:`poplib`, :mod:`shutil`, +:mod:`smtplib`, :mod:`sqlite3`, :mod:`subprocess`, :mod:`telnetlib`, +:mod:`tempfile` and :mod:`webbrowser`, as well as :func:`os.listdir`, +:func:`os.scandir` and :func:`breakpoint`. + +.. + +.. bpo: 37364 +.. date: 2019-06-21-14-42-53 +.. nonce: IIRc2s +.. section: Security + +:func:`io.open_code` is now used when reading :file:`.pth` files. + +.. + +.. bpo: 34631 +.. date: 2019-06-17-09-34-25 +.. nonce: DBfM4j +.. section: Security + +Updated OpenSSL to 1.1.1c in Windows installer + +.. + +.. bpo: 34155 +.. date: 2019-05-04-13-33-37 +.. nonce: MJll68 +.. section: Security + +Fix parsing of invalid email addresses with more than one ``@`` (e.g. +a@b@c.com.) to not return the part before 2nd ``@`` as valid email address. +Patch by maxking & jpic. + +.. + +.. bpo: 38631 +.. date: 2019-11-18-17-10-20 +.. nonce: tRHaAk +.. section: Core and Builtins + +Replace ``Py_FatalError()`` call with a regular :exc:`RuntimeError` +exception in :meth:`float.__getformat__`. + +.. + +.. bpo: 38639 +.. date: 2019-10-30-11-31-47 +.. nonce: 9-vKtO +.. section: Core and Builtins + +Optimized :func:`math.floor()`, :func:`math.ceil()` and :func:`math.trunc()` +for floats. + +.. + +.. bpo: 38640 +.. date: 2019-10-30-11-25-25 +.. nonce: 4sAFh5 +.. section: Core and Builtins + +Fixed a bug in the compiler that was causing to raise in the presence of +break statements and continue statements inside always false while loops. +Patch by Pablo Galindo. + +.. + +.. bpo: 38613 +.. date: 2019-10-29-15-44-24 +.. nonce: V_R3NC +.. section: Core and Builtins + +Optimized some set operations (e.g. ``|``, ``^``, and ``-``) of +``dict_keys``. ``d.keys() | other`` was slower than ``set(d) | other`` but +they are almost same performance for now. + +.. + +.. bpo: 28029 +.. date: 2019-10-29-09-38-54 +.. nonce: AmRMEF +.. section: Core and Builtins + +``"".replace("", s, n)`` now returns ``s`` instead of an empty string for +all non-zero ``n``. There are similar changes for :class:`bytes` and +:class:`bytearray` objects. + +.. + +.. bpo: 38535 +.. date: 2019-10-20-12-43-48 +.. nonce: ESMkVN +.. section: Core and Builtins + +Fixed line numbers and column offsets for AST nodes for calls without +arguments in decorators. + +.. + +.. bpo: 38525 +.. date: 2019-10-20-00-36-18 +.. nonce: Vty1cA +.. section: Core and Builtins + +Fix a segmentation fault when using reverse iterators of empty ``dict`` +objects. Patch by Donghee Na and Inada Naoki. + +.. + +.. bpo: 38465 +.. date: 2019-10-19-12-44-13 +.. nonce: V1L8c4 +.. section: Core and Builtins + +:class:`bytearray`, :class:`~array.array` and :class:`~mmap.mmap` objects +allow now to export more than ``2**31`` buffers at a time. + +.. + +.. bpo: 38469 +.. date: 2019-10-13-23-41-38 +.. nonce: 9kmuQj +.. section: Core and Builtins + +Fixed a bug where the scope of named expressions was not being resolved +correctly in the presence of the *global* keyword. Patch by Pablo Galindo. + +.. + +.. bpo: 38437 +.. date: 2019-10-10-20-42-09 +.. nonce: z_0mZp +.. section: Core and Builtins + +Activate the ``GC_DEBUG`` macro for debug builds of the interpreter (when +``Py_DEBUG`` is set). Patch by Pablo Galindo. + +.. + +.. bpo: 38379 +.. date: 2019-10-10-01-41-02 +.. nonce: _q4dhn +.. section: Core and Builtins + +When the garbage collector makes a collection in which some objects +resurrect (they are reachable from outside the isolated cycles after the +finalizers have been executed), do not block the collection of all objects +that are still unreachable. Patch by Pablo Galindo and Tim Peters. + +.. + +.. bpo: 38379 +.. date: 2019-10-09-16-50-52 +.. nonce: oz5qZx +.. section: Core and Builtins + +When cyclic garbage collection (gc) runs finalizers that resurrect +unreachable objects, the current gc run ends, without collecting any cyclic +trash. However, the statistics reported by ``collect()`` and +``get_stats()`` claimed that all cyclic trash found was collected, and that +the resurrected objects were collected. Changed the stats to report that +none were collected. + +.. + +.. bpo: 38392 +.. date: 2019-10-07-22-51-39 +.. nonce: KaXXps +.. section: Core and Builtins + +In debug mode, :c:func:`PyObject_GC_Track` now calls ``tp_traverse()`` of +the object type to ensure that the object is valid: test that objects +visited by ``tp_traverse()`` are valid. + +.. + +.. bpo: 38210 +.. date: 2019-10-06-15-01-57 +.. nonce: Xgc6F_ +.. section: Core and Builtins + +Remove unnecessary intersection and update set operation in dictview with +empty set. (Contributed by Donghee Na in :issue:`38210`.) + +.. + +.. bpo: 38402 +.. date: 2019-10-05-19-36-16 +.. nonce: EZuzgK +.. section: Core and Builtins + +Check the error from the system's underlying ``crypt`` or ``crypt_r``. + +.. + +.. bpo: 37474 +.. date: 2019-10-01-12-46-30 +.. nonce: cB3se1 +.. section: Core and Builtins + +On FreeBSD, Python no longer calls ``fedisableexcept()`` at startup to +control the floating point control mode. The call became useless since +FreeBSD 6: it became the default mode. + +.. + +.. bpo: 38006 +.. date: 2019-09-30-09-33-21 +.. nonce: UYlJum +.. section: Core and Builtins + +Fix a bug due to the interaction of weakrefs and the cyclic garbage +collector. We must clear any weakrefs in garbage in order to prevent their +callbacks from executing and causing a crash. + +.. + +.. bpo: 38317 +.. date: 2019-09-30-00-56-21 +.. nonce: pmqlIQ +.. section: Core and Builtins + +Fix warnings options priority: ``PyConfig.warnoptions`` has the highest +priority, as stated in the :pep:`587`. + +.. + +.. bpo: 38310 +.. date: 2019-09-28-22-54-25 +.. nonce: YDTbEo +.. section: Core and Builtins + +Predict ``BUILD_MAP_UNPACK_WITH_CALL`` -> ``CALL_FUNCTION_EX`` opcode pairs +in the main interpreter loop. Patch by Brandt Bucher. + +.. + +.. bpo: 36871 +.. date: 2019-09-24-18-45-46 +.. nonce: p47knk +.. section: Core and Builtins + +Improve error handling for the assert_has_calls and assert_has_awaits +methods of mocks. Fixed a bug where any errors encountered while binding the +expected calls to the mock's spec were silently swallowed, leading to +misleading error output. + +.. + +.. bpo: 11410 +.. date: 2019-09-24-05-32-27 +.. nonce: vS182p +.. section: Core and Builtins + +Better control over symbol visibility is provided through use of the +visibility attributes available in gcc >= 4.0, provided in a uniform way +across POSIX and Windows. The POSIX build files have been updated to compile +with -fvisibility=hidden, minimising exported symbols. + +.. + +.. bpo: 38219 +.. date: 2019-09-22-13-56-18 +.. nonce: rFl7JD +.. section: Core and Builtins + +Optimized the :class:`dict` constructor and the :meth:`~dict.update` method +for the case when the argument is a dict. + +.. + +.. bpo: 38236 +.. date: 2019-09-20-19-06-23 +.. nonce: eQ0Tmj +.. section: Core and Builtins + +Python now dumps path configuration if it fails to import the Python codecs +of the filesystem and stdio encodings. + +.. + +.. bpo: 38013 +.. date: 2019-09-12-19-50-01 +.. nonce: I7btD0 +.. section: Core and Builtins + +Allow to call ``async_generator_athrow().throw(...)`` even for non-started +async generator helper. It fixes annoying warning at the end of +:func:`asyncio.run` call. + +.. + +.. bpo: 38124 +.. date: 2019-09-12-00-14-01 +.. nonce: n6E0H7 +.. section: Core and Builtins + +Fix an off-by-one error in PyState_AddModule that could cause out-of-bounds +memory access. + +.. + +.. bpo: 38116 +.. date: 2019-09-11-14-49-42 +.. nonce: KDwmwt +.. section: Core and Builtins + +The select module is now PEP-384 compliant and no longer has static state + +.. + +.. bpo: 38113 +.. date: 2019-09-11-14-10-02 +.. nonce: yZXC3P +.. section: Core and Builtins + +ast module updated to PEP-384 and all statics removed + +.. + +.. bpo: 38076 +.. date: 2019-09-09-16-36-37 +.. nonce: C5dVBl +.. section: Core and Builtins + +The struct module is now PEP-384 compatible + +.. + +.. bpo: 38075 +.. date: 2019-09-09-15-59-50 +.. nonce: N8OZKF +.. section: Core and Builtins + +The random module is now PEP-384 compatible + +.. + +.. bpo: 38074 +.. date: 2019-09-09-15-40-57 +.. nonce: MsVbeI +.. section: Core and Builtins + +zlib module made PEP-384 compatible + +.. + +.. bpo: 38073 +.. date: 2019-09-09-15-17-58 +.. nonce: ZoKYOU +.. section: Core and Builtins + +Make pwd extension module PEP-384 compatible + +.. + +.. bpo: 38072 +.. date: 2019-09-09-15-00-42 +.. nonce: Y1xpDO +.. section: Core and Builtins + +grp module made PEP-384 compatible + +.. + +.. bpo: 38069 +.. date: 2019-09-09-14-46-05 +.. nonce: cn8XLv +.. section: Core and Builtins + +Make _posixsubprocess PEP-384 compatible + +.. + +.. bpo: 38071 +.. date: 2019-09-09-14-44-17 +.. nonce: bLwkBJ +.. section: Core and Builtins + +Make termios extension module PEP-384 compatible + +.. + +.. bpo: 38005 +.. date: 2019-09-02-20-00-31 +.. nonce: e7VsTA +.. section: Core and Builtins + +Fixed comparing and creating of InterpreterID and ChannelID. + +.. + +.. bpo: 36946 +.. date: 2019-09-02-16-17-42 +.. nonce: _lAuSR +.. section: Core and Builtins + +Fix possible signed integer overflow when handling slices. Patch by +hongweipeng. + +.. + +.. bpo: 37994 +.. date: 2019-08-31-11-13-25 +.. nonce: Rj6S4j +.. section: Core and Builtins + +Fixed silencing arbitrary errors if an attribute lookup fails in several +sites. Only AttributeError should be silenced. + +.. + +.. bpo: 8425 +.. date: 2019-08-29-01-55-38 +.. nonce: FTq4A8 +.. section: Core and Builtins + +Optimize set difference_update for the case when the other set is much +larger than the base set. (Suggested by Evgeny Kapun with code contributed +by Michele Orrù). + +.. + +.. bpo: 37966 +.. date: 2019-08-27-21-21-36 +.. nonce: 5OBLez +.. section: Core and Builtins + +The implementation of :func:`~unicodedata.is_normalized` has been greatly +sped up on strings that aren't normalized, by implementing the full +normalization-quick-check algorithm from the Unicode standard. + +.. + +.. bpo: 37947 +.. date: 2019-08-26-04-09-57 +.. nonce: mzAQtB +.. section: Core and Builtins + +Adjust correctly the recursion level in the symtable generation for named +expressions. Patch by Pablo Galindo. + +.. + +.. bpo: 37812 +.. date: 2019-08-23-22-46-25 +.. nonce: vsWZwS +.. section: Core and Builtins + +The ``CHECK_SMALL_INT`` macro used inside :file:`Object/longobject.c` has +been replaced with an explicit ``return`` at each call site. + +.. + +.. bpo: 37751 +.. date: 2019-08-20-04-36-37 +.. nonce: CSFzUd +.. section: Core and Builtins + +Fix :func:`codecs.lookup` to normalize the encoding name the same way than +:func:`encodings.normalize_encoding`, except that :func:`codecs.lookup` also +converts the name to lower case. + +.. + +.. bpo: 37830 +.. date: 2019-08-17-18-41-59 +.. nonce: fNfMbz +.. section: Core and Builtins + +Fixed compilation of :keyword:`break` and :keyword:`continue` in the +:keyword:`finally` block when the corresponding :keyword:`try` block +contains :keyword:`return` with a non-constant value. + +.. + +.. bpo: 20490 +.. date: 2019-08-15-12-48-36 +.. nonce: -hXeEn +.. section: Core and Builtins + +Improve import error message for partially initialized module on circular +``from`` imports - by Anthony Sottile. + +.. + +.. bpo: 37840 +.. date: 2019-08-13-18-05-20 +.. nonce: elLCci +.. section: Core and Builtins + +Fix handling of negative indices in :c:member:`~PySequenceMethods.sq_item` +of :class:`bytearray`. Patch by Sergey Fedoseev. + +.. + +.. bpo: 37802 +.. date: 2019-08-09-18-28-57 +.. nonce: pKxcAW +.. section: Core and Builtins + +Slightly improve performance of :c:func:`PyLong_FromUnsignedLong`, +:c:func:`PyLong_FromUnsignedLongLong` and :c:func:`PyLong_FromSize_t`. Patch +by Sergey Fedoseev. + +.. + +.. bpo: 37409 +.. date: 2019-08-06-23-39-05 +.. nonce: 1qwzn2 +.. section: Core and Builtins + +Ensure explicit relative imports from interactive sessions and scripts +(having no parent package) always raise ImportError, rather than treating +the current module as the package. Patch by Ben Lewis. + +.. + +.. bpo: 32912 +.. date: 2019-08-06-14-03-59 +.. nonce: UDwSMJ +.. section: Core and Builtins + +Reverted :issue:`32912`: emitting :exc:`SyntaxWarning` instead of +:exc:`DeprecationWarning` for invalid escape sequences in string and bytes +literals. + +.. + +.. bpo: 37757 +.. date: 2019-08-05-14-22-59 +.. nonce: lRv5HX +.. section: Core and Builtins + +:pep:`572`: As described in the PEP, assignment expressions now raise +:exc:`SyntaxError` when their interaction with comprehension scoping results +in an ambiguous target scope. + +The ``TargetScopeError`` subclass originally proposed by the PEP has been +removed in favour of just raising regular syntax errors for the disallowed +cases. + +.. + +.. bpo: 36279 +.. date: 2019-08-04-12-24-18 +.. nonce: 8Zy7jZ +.. section: Core and Builtins + +Fix potential use of uninitialized memory in :func:`os.wait3`. + +.. + +.. bpo: 36311 +.. date: 2019-08-02-15-01-33 +.. nonce: uY5vt- +.. section: Core and Builtins + +Decoding bytes objects larger than 2GiB is faster and no longer fails when a +multibyte characters spans a chunk boundary. + +.. + +.. bpo: 34880 +.. date: 2019-08-01-10-45-51 +.. nonce: u_x_CG +.. section: Core and Builtins + +The :keyword:`assert` statement now works properly if the +:exc:`AssertionError` exception is being shadowed. Patch by Zackery Spytz. + +.. + +.. bpo: 37340 +.. date: 2019-07-25-11-06-57 +.. nonce: 5ktLEg +.. section: Core and Builtins + +Removed object cache (``free_list``) for bound method objects. Temporary +bound method objects are less used than before thanks to the ``LOAD_METHOD`` +opcode and the ``_PyObject_VectorcallMethod`` C API. + +.. + +.. bpo: 37648 +.. date: 2019-07-22-11-05-05 +.. nonce: 6TY2L- +.. section: Core and Builtins + +Fixed minor inconsistency in :meth:`list.__contains__`, +:meth:`tuple.__contains__` and a few other places. The collection's item is +now always at the left and the needle is on the right of ``==``. + +.. + +.. bpo: 37444 +.. date: 2019-07-20-22-34-42 +.. nonce: UOd3Xs +.. section: Core and Builtins + +Update differing exception between :meth:`builtins.__import__` and +:meth:`importlib.__import__`. + +.. + +.. bpo: 37619 +.. date: 2019-07-18-11-50-49 +.. nonce: X6Lulo +.. section: Core and Builtins + +When adding a wrapper descriptor from one class to a different class (for +example, setting ``__add__ = str.__add__`` on an ``int`` subclass), an +exception is correctly raised when the operator is called. + +.. + +.. bpo: 37593 +.. date: 2019-07-14-23-57-27 +.. nonce: yHSTwH +.. section: Core and Builtins + +Swap the positions of the *posonlyargs* and *args* parameters in the +constructor of :class:`ast.parameters` nodes. + +.. + +.. bpo: 37543 +.. date: 2019-07-10-20-33-53 +.. nonce: EvI19D +.. section: Core and Builtins + +Optimized pymalloc for non PGO build. + +.. + +.. bpo: 37537 +.. date: 2019-07-10-09-56-47 +.. nonce: OkB0wd +.. section: Core and Builtins + +Compute allocated pymalloc blocks inside _Py_GetAllocatedBlocks(). This +slows down _Py_GetAllocatedBlocks() but gives a small speedup to +_PyObject_Malloc() and _PyObject_Free(). + +.. + +.. bpo: 37467 +.. date: 2019-07-01-12-22-44 +.. nonce: u-XyEu +.. section: Core and Builtins + +Fix :func:`sys.excepthook` and :c:func:`PyErr_Display` if a filename is a +bytes string. For example, for a SyntaxError exception where the filename +attribute is a bytes string. + +.. + +.. bpo: 37433 +.. date: 2019-06-27-15-01-14 +.. nonce: amNGqr +.. section: Core and Builtins + +Fix ``SyntaxError`` indicator printing too many spaces for multi-line +strings - by Anthony Sottile. + +.. + +.. bpo: 37417 +.. date: 2019-06-26-18-41-00 +.. nonce: VsZeHL +.. section: Core and Builtins + +:meth:`bytearray.extend` now correctly handles errors that arise during +iteration. Patch by Brandt Bucher. + +.. + +.. bpo: 37414 +.. date: 2019-06-26-17-27-26 +.. nonce: o6Lnbc +.. section: Core and Builtins + +The undocumented ``sys.callstats()`` function has been removed. Since Python +3.7, it was deprecated and always returned ``None``. It required a special +build option ``CALL_PROFILE`` which was already removed in Python 3.7. + +.. + +.. bpo: 37392 +.. date: 2019-06-25-01-45-06 +.. nonce: J3JhIx +.. section: Core and Builtins + +Remove ``sys.getcheckinterval()`` and ``sys.setcheckinterval()`` functions. +They were deprecated since Python 3.2. Use :func:`sys.getswitchinterval` and +:func:`sys.setswitchinterval` instead. Remove also ``check_interval`` field +of the ``PyInterpreterState`` structure. + +.. + +.. bpo: 37388 +.. date: 2019-06-24-21-53-52 +.. nonce: 0XTZmW +.. section: Core and Builtins + +In development mode and in debug build, *encoding* and *errors* arguments +are now checked on string encoding and decoding operations. Examples: +:func:`open`, :meth:`str.encode` and :meth:`bytes.decode`. + +By default, for best performances, the *errors* argument is only checked at +the first encoding/decoding error, and the *encoding* argument is sometimes +ignored for empty strings. + +.. + +.. bpo: 37348 +.. date: 2019-06-23-00-26-30 +.. nonce: pp8P-x +.. section: Core and Builtins + +Optimized decoding short ASCII string with UTF-8 and ascii codecs. +``b"foo".decode()`` is about 15% faster. Patch by Inada Naoki. + +.. + +.. bpo: 24214 +.. date: 2019-06-22-12-45-20 +.. nonce: hIiHeD +.. section: Core and Builtins + +Improved support of the surrogatepass error handler in the UTF-8 and UTF-16 +incremental decoders. + +.. + +.. bpo: 37330 +.. date: 2019-06-18-17-53-06 +.. nonce: wAvHmz +.. section: Core and Builtins + +:func:`open`, :func:`io.open`, :func:`codecs.open` and +:class:`fileinput.FileInput` no longer accept ``'U'`` ("universal newline") +in the file mode. This flag was deprecated since Python 3.3. + +.. + +.. bpo: 35224 +.. date: 2019-06-17-06-03-55 +.. nonce: FHWPGv +.. section: Core and Builtins + +Reverse evaluation order of key: value in dict comprehensions as proposed in +PEP 572. I.e. in ``{k: v for ...}``, ``k`` will be evaluated before ``v``. + +.. + +.. bpo: 37316 +.. date: 2019-06-17-03-53-16 +.. nonce: LytDX_ +.. section: Core and Builtins + +Fix the :c:func:`PySys_Audit` call in :class:`mmap.mmap`. + +.. + +.. bpo: 37300 +.. date: 2019-06-16-02-38-25 +.. nonce: WJkgKV +.. section: Core and Builtins + +Remove an unnecessary Py_XINCREF in classobject.c. + +.. + +.. bpo: 37269 +.. date: 2019-06-14-06-32-33 +.. nonce: SjVVAe +.. section: Core and Builtins + +Fix a bug in the peephole optimizer that was not treating correctly constant +conditions with binary operators. Patch by Pablo Galindo. + +.. + +.. bpo: 20443 +.. date: 2019-06-13-12-55-38 +.. nonce: bQWAxg +.. section: Core and Builtins + +Python now gets the absolute path of the script filename specified on the +command line (ex: "python3 script.py"): the __file__ attribute of the +__main__ module and sys.path[0] become an absolute path, rather than a +relative path. + +.. + +.. bpo: 37257 +.. date: 2019-06-13-02-27-12 +.. nonce: IMxDvT +.. section: Core and Builtins + +Python's small object allocator (``obmalloc.c``) now allows (no more than) +one empty arena to remain available for immediate reuse, without returning +it to the OS. This prevents thrashing in simple loops where an arena could +be created and destroyed anew on each iteration. + +.. + +.. bpo: 37231 +.. date: 2019-06-12-14-39-16 +.. nonce: LF41Es +.. section: Core and Builtins + +The dispatching of type slots to special methods (for example calling +``__mul__`` when doing ``x * y``) has been made faster. + +.. + +.. bpo: 36974 +.. date: 2019-06-11-12-59-38 +.. nonce: bVYmSA +.. section: Core and Builtins + +Implemented separate vectorcall functions for every calling convention of +builtin functions and methods. This improves performance for calls. + +.. + +.. bpo: 37213 +.. date: 2019-06-11-11-15-19 +.. nonce: UPii5K +.. section: Core and Builtins + +Handle correctly negative line offsets in the peephole optimizer. Patch by +Pablo Galindo. + +.. + +.. bpo: 37219 +.. date: 2019-06-10-23-18-31 +.. nonce: jPSufq +.. section: Core and Builtins + +Remove erroneous optimization for empty set differences. + +.. + +.. bpo: 15913 +.. date: 2019-06-06-20-52-38 +.. nonce: 5Sg5cv +.. section: Core and Builtins + +Implement :c:func:`PyBuffer_SizeFromFormat()` function (previously +documented but not implemented): call :func:`struct.calcsize`. Patch by +Joannah Nanjekye. + +.. + +.. bpo: 36922 +.. date: 2019-06-06-13-59-52 +.. nonce: EMZ3TF +.. section: Core and Builtins + +Slot functions optimize any callable with ``Py_TPFLAGS_METHOD_DESCRIPTOR`` +instead of only instances of ``function``. + +.. + +.. bpo: 36974 +.. date: 2019-06-06-11-00-55 +.. nonce: wdzzym +.. section: Core and Builtins + +The slot ``tp_vectorcall_offset`` is inherited unconditionally to support +``super().__call__()`` when the base class uses vectorcall. + +.. + +.. bpo: 37160 +.. date: 2019-06-05-09-24-17 +.. nonce: O3IAY3 +.. section: Core and Builtins + +:func:`threading.get_native_id` now also supports NetBSD. + +.. + +.. bpo: 37077 +.. date: 2019-05-28-11-47-44 +.. nonce: S1h0Fc +.. section: Core and Builtins + +Add :func:`threading.get_native_id` support for AIX. Patch by M. Felt + +.. + +.. bpo: 36781 +.. date: 2019-05-06-09-59-31 +.. nonce: uocWt6 +.. section: Core and Builtins + +:func:`sum` has been optimized for boolean values. + +.. + +.. bpo: 34556 +.. date: 2019-05-05-18-09-40 +.. nonce: o9kfpu +.. section: Core and Builtins + +Add ``--upgrade-deps`` to venv module. Patch by Cooper Ry Lees + +.. + +.. bpo: 20523 +.. date: 2019-02-15-20-42-36 +.. nonce: rRLrvr +.. section: Core and Builtins + +``pdb.Pdb`` supports ~/.pdbrc in Windows 7. Patch by Tim Hopper and Dan +Lidral-Porter. + +.. + +.. bpo: 35551 +.. date: 2019-01-18-16-16-27 +.. nonce: oF5pbO +.. section: Core and Builtins + +Updated encodings: - Removed the "tis260" encoding, which was an alias for +the nonexistent "tactis" codec. - Added "mac_centeuro" as an alias for the +mac_latin2 encoding. + +.. + +.. bpo: 19072 +.. date: 2018-07-23-13-09-54 +.. nonce: Gc59GS +.. section: Core and Builtins + +The :class:`classmethod` decorator can now wrap other descriptors such as +property objects. Adapted from a patch written by Graham Dumpleton. + +.. + +.. bpo: 27575 +.. date: 2018-06-14-13-55-45 +.. nonce: mMYgzv +.. section: Core and Builtins + +Improve speed of dictview intersection by directly using set intersection +logic. Patch by David Su. + +.. + +.. bpo: 30773 +.. date: 2018-06-07-01-01-20 +.. nonce: C31rVE +.. section: Core and Builtins + +Prohibit parallel running of aclose() / asend() / athrow(). Fix ag_running +to reflect the actual running status of the AG. + +.. + +.. bpo: 36589 +.. date: 2019-11-16-22-56-51 +.. nonce: 0Io76D +.. section: Library + +The :func:`curses.update_lines_cols` function now returns ``None`` instead +of ``1`` on success. + +.. + +.. bpo: 38807 +.. date: 2019-11-15-09-30-29 +.. nonce: PsmRog +.. section: Library + +Update :exc:`TypeError` messages for :meth:`os.path.join` to include +:class:`os.PathLike` objects as acceptable input types. + +.. + +.. bpo: 38724 +.. date: 2019-11-14-14-13-29 +.. nonce: T5ySfR +.. section: Library + +Add a repr for ``subprocess.Popen`` objects. Patch by Andrey Doroschenko. + +.. + +.. bpo: 38786 +.. date: 2019-11-13-16-49-03 +.. nonce: gNOwKh +.. section: Library + +pydoc now recognizes and parses HTTPS URLs. Patch by python273. + +.. + +.. bpo: 38785 +.. date: 2019-11-13-16-17-43 +.. nonce: NEOEfk +.. section: Library + +Prevent asyncio from crashing if parent ``__init__`` is not called from a +constructor of object derived from ``asyncio.Future``. + +.. + +.. bpo: 38723 +.. date: 2019-11-12-15-46-28 +.. nonce: gcdMFn +.. section: Library + +:mod:`pdb` now uses :meth:`io.open_code` to trigger auditing events. + +.. + +.. bpo: 27805 +.. date: 2019-11-11-21-43-06 +.. nonce: D3zl1_ +.. section: Library + +Allow opening pipes and other non-seekable files in append mode with +:func:`open`. + +.. + +.. bpo: 38438 +.. date: 2019-11-11-06-14-25 +.. nonce: vSVeHN +.. section: Library + +Simplify the :mod:`argparse` usage message for ``nargs="*"``. + +.. + +.. bpo: 38761 +.. date: 2019-11-10-13-40-33 +.. nonce: P1UUIZ +.. section: Library + +WeakSet is now registered as a collections.abc.MutableSet. + +.. + +.. bpo: 38716 +.. date: 2019-11-06-15-58-07 +.. nonce: R3uMLT +.. section: Library + +logging: change RotatingHandler namer and rotator to class-level attributes. +This stops __init__ from setting them to None in the case where a subclass +defines them with eponymous methods. + +.. + +.. bpo: 38713 +.. date: 2019-11-05-21-22-22 +.. nonce: bmhquU +.. section: Library + +Add :const:`os.P_PIDFD` constant, which may be passed to :func:`os.waitid` to +wait on a Linux process file descriptor. + +.. + +.. bpo: 38692 +.. date: 2019-11-05-19-15-57 +.. nonce: 2DCDA- +.. section: Library + +Add :class:`asyncio.PidfdChildWatcher`, a Linux-specific child watcher +implementation that polls process file descriptors. + +.. + +.. bpo: 38692 +.. date: 2019-11-05-07-18-24 +.. nonce: UpatA7 +.. section: Library + +Expose the Linux ``pidfd_open`` syscall as :func:`os.pidfd_open`. + +.. + +.. bpo: 38602 +.. date: 2019-10-27-22-29-45 +.. nonce: 7jvYFA +.. section: Library + +Added constants :const:`~fcntl.F_OFD_GETLK`, :const:`~fcntl.F_OFD_SETLK` and +:const:`~fcntl.F_OFD_SETLKW` to the :mod:`fcntl` module. Patch by Donghee +Na. + +.. + +.. bpo: 38334 +.. date: 2019-10-27-00-08-49 +.. nonce: pfLLmc +.. section: Library + +Fixed seeking backward on an encrypted :class:`zipfile.ZipExtFile`. + +.. + +.. bpo: 38312 +.. date: 2019-10-26-14-42-20 +.. nonce: e_FVWh +.. section: Library + +Add :func:`curses.get_escdelay`, :func:`curses.set_escdelay`, +:func:`curses.get_tabsize`, and :func:`curses.set_tabsize` functions - by +Anthony Sottile. + +.. + +.. bpo: 38586 +.. date: 2019-10-24-17-26-39 +.. nonce: cyq5nr +.. section: Library + +Now :func:`~logging.config.fileConfig` correctly sets the .name of handlers +loaded. + +.. + +.. bpo: 38565 +.. date: 2019-10-24-08-10-30 +.. nonce: SWSUst +.. section: Library + +Add new cache_parameters() method for functools.lru_cache() to better +support pickling. + +.. + +.. bpo: 34679 +.. date: 2019-10-23-16-25-12 +.. nonce: Bnw8o3 +.. section: Library + +asynci.ProactorEventLoop.close() now only calls signal.set_wakeup_fd() in +the main thread. + +.. + +.. bpo: 31202 +.. date: 2019-10-20-12-04-48 +.. nonce: NfdIus +.. section: Library + +The case the result of :func:`pathlib.WindowsPath.glob` matches now the case +of the pattern for literal parts. + +.. + +.. bpo: 36321 +.. date: 2019-10-19-21-41-20 +.. nonce: CFlxfy +.. section: Library + +Remove misspelled attribute. The 3.8 changelog noted that this would be +removed in 3.9. + +.. + +.. bpo: 38521 +.. date: 2019-10-18-13-57-31 +.. nonce: U-7aaM +.. section: Library + +Fixed erroneous equality comparison in statistics.NormalDist(). + +.. + +.. bpo: 38493 +.. date: 2019-10-16-19-56-51 +.. nonce: 86ExWB +.. section: Library + +Added :const:`~os.CLD_KILLED` and :const:`~os.CLD_STOPPED` for +:attr:`si_code`. Patch by Donghee Na. + +.. + +.. bpo: 38478 +.. date: 2019-10-15-11-37-57 +.. nonce: A87OPO +.. section: Library + +Fixed a bug in :meth:`inspect.signature.bind` that was causing it to fail +when handling a keyword argument with same name as positional-only +parameter. Patch by Pablo Galindo. + +.. + +.. bpo: 33604 +.. date: 2019-10-15-09-47-40 +.. nonce: J12cWT +.. section: Library + +Fixed `hmac.new` and `hmac.HMAC` to raise TypeError instead of ValueError +when the digestmod parameter, now required in 3.8, is omitted. Also +clarified the hmac module documentation and docstrings. + +.. + +.. bpo: 38378 +.. date: 2019-10-13-11-00-03 +.. nonce: yYNpSm +.. section: Library + +Parameters *out* and *in* of :func:`os.sendfile` was renamed to *out_fd* and +*in_fd*. + +.. + +.. bpo: 38417 +.. date: 2019-10-12-00-13-47 +.. nonce: W7x_aS +.. section: Library + +Added support for setting the umask in the child process to the subprocess +module on POSIX systems. + +.. + +.. bpo: 38449 +.. date: 2019-10-11-18-49-00 +.. nonce: 9TWMlz +.. section: Library + +Revert PR 15522, which introduces a regression in +:meth:`mimetypes.guess_type` due to improper handling of filenames as urls. + +.. + +.. bpo: 38431 +.. date: 2019-10-10-16-53-00 +.. nonce: d5wzNp +.. section: Library + +Fix ``__repr__`` method for :class:`dataclasses.InitVar` to support typing +objects, patch by Samuel Colvin. + +.. + +.. bpo: 38109 +.. date: 2019-10-10-00-25-28 +.. nonce: 9w-IGF +.. section: Library + +Add missing :const:`stat.S_IFDOOR`, :const:`stat.S_IFPORT`, +:const:`stat.S_IFWHT`, :func:`stat.S_ISDOOR`, :func:`stat.S_ISPORT`, and +:func:`stat.S_ISWHT` values to the Python implementation of :mod:`stat`. + +.. + +.. bpo: 38422 +.. date: 2019-10-09-18-16-51 +.. nonce: aiM5bq +.. section: Library + +Clarify docstrings of pathlib suffix(es) + +.. + +.. bpo: 38405 +.. date: 2019-10-08-11-18-40 +.. nonce: 0-7e7s +.. section: Library + +Nested subclasses of :class:`typing.NamedTuple` are now pickleable. + +.. + +.. bpo: 38332 +.. date: 2019-10-05-02-07-52 +.. nonce: hwrPN7 +.. section: Library + +Prevent :exc:`KeyError` thrown by :func:`_encoded_words.decode` when given +an encoded-word with invalid content-type encoding from propagating all the +way to :func:`email.message.get`. + +.. + +.. bpo: 38371 +.. date: 2019-10-04-18-39-59 +.. nonce: S6Klvm +.. section: Library + +Deprecated the ``split()`` method in :class:`_tkinter.TkappType` in favour +of the ``splitlist()`` method which has more consistent and predicable +behavior. + +.. + +.. bpo: 38341 +.. date: 2019-10-01-21-06-18 +.. nonce: uqwgU_ +.. section: Library + +Add :exc:`smtplib.SMTPNotSupportedError` to the :mod:`smtplib` exported +names. + +.. + +.. bpo: 38319 +.. date: 2019-09-30-22-06-33 +.. nonce: 5QjiDa +.. section: Library + +sendfile() used in socket and shutil modules was raising OverflowError for +files >= 2GiB on 32-bit architectures. (patch by Giampaolo Rodola) + +.. + +.. bpo: 38242 +.. date: 2019-09-30-00-15-27 +.. nonce: uPIyAc +.. section: Library + +Revert the new asyncio Streams API + +.. + +.. bpo: 13153 +.. date: 2019-09-29-22-47-37 +.. nonce: 0mO9qR +.. section: Library + +OS native encoding is now used for converting between Python strings and Tcl +objects. This allows to display, copy and paste to clipboard emoji and +other non-BMP characters. Converting strings from Tcl to Python and back +now never fails (except MemoryError). + +.. + +.. bpo: 38019 +.. date: 2019-09-29-13-50-24 +.. nonce: 6MoOE3 +.. section: Library + +Correctly handle pause/resume reading of closed asyncio unix pipe. + +.. + +.. bpo: 38163 +.. date: 2019-09-28-20-16-40 +.. nonce: x51-vK +.. section: Library + +Child mocks will now detect their type as either synchronous or +asynchronous, asynchronous child mocks will be AsyncMocks and synchronous +child mocks will be either MagicMock or Mock (depending on their parent +type). + +.. + +.. bpo: 38161 +.. date: 2019-09-27-16-31-28 +.. nonce: zehai1 +.. section: Library + +Removes _AwaitEvent from AsyncMock. + +.. + +.. bpo: 38216 +.. date: 2019-09-27-15-24-45 +.. nonce: -7yvZR +.. section: Library + +Allow the rare code that wants to send invalid http requests from the +`http.client` library a way to do so. The fixes for bpo-30458 led to +breakage for some projects that were relying on this ability to test their +own behavior in the face of bad requests. + +.. + +.. bpo: 28286 +.. date: 2019-09-26-12-16-30 +.. nonce: LdSsrN +.. section: Library + +Deprecate opening :class:`~gzip.GzipFile` for writing implicitly. Always +specify the *mode* argument for writing. + +.. + +.. bpo: 38108 +.. date: 2019-09-25-21-37-02 +.. nonce: Jr9HU6 +.. section: Library + +Any synchronous magic methods on an AsyncMock now return a MagicMock. Any +asynchronous magic methods on a MagicMock now return an AsyncMock. + +.. + +.. bpo: 38265 +.. date: 2019-09-25-05-16-19 +.. nonce: X6-gsT +.. section: Library + +Update the *length* parameter of :func:`os.pread` to accept +:c:type:`Py_ssize_t` instead of :c:expr:`int`. + +.. + +.. bpo: 38112 +.. date: 2019-09-24-10-55-01 +.. nonce: 2EinX9 +.. section: Library + +:mod:`compileall` has a higher default recursion limit and new command-line +arguments for path manipulation, symlinks handling, and multiple +optimization levels. + +.. + +.. bpo: 38248 +.. date: 2019-09-22-13-05-36 +.. nonce: Yo3N_1 +.. section: Library + +asyncio: Fix inconsistent immediate Task cancellation + +.. + +.. bpo: 38237 +.. date: 2019-09-20-14-27-17 +.. nonce: xRUZbx +.. section: Library + +The arguments for the builtin pow function are more descriptive. They can +now also be passed in as keywords. + +.. + +.. bpo: 34002 +.. date: 2019-09-19-19-58-33 +.. nonce: KBnaVX +.. section: Library + +Improve efficiency in parts of email package by changing while-pop to a for +loop, using isdisjoint instead of set intersections. + +.. + +.. bpo: 38191 +.. date: 2019-09-17-12-28-27 +.. nonce: 1TU0HV +.. section: Library + +Constructors of :class:`~typing.NamedTuple` and :class:`~typing.TypedDict` +types now accept arbitrary keyword argument names, including "cls", "self", +"typename", "_typename", "fields" and "_fields". + +.. + +.. bpo: 38155 +.. date: 2019-09-16-21-47-48 +.. nonce: d92lRc +.. section: Library + +Add ``__all__`` to :mod:`datetime`. Patch by Tahia Khan. + +.. + +.. bpo: 38185 +.. date: 2019-09-16-19-12-57 +.. nonce: zYWppY +.. section: Library + +Fixed case-insensitive string comparison in :class:`sqlite3.Row` indexing. + +.. + +.. bpo: 38136 +.. date: 2019-09-16-09-54-42 +.. nonce: MdI-Zb +.. section: Library + +Changes AsyncMock call count and await count to be two different counters. +Now await count only counts when a coroutine has been awaited, not when it +has been called, and vice-versa. Update the documentation around this. + +.. + +.. bpo: 37828 +.. date: 2019-09-15-21-31-18 +.. nonce: gLLDX7 +.. section: Library + +Fix default mock name in :meth:`unittest.mock.Mock.assert_called` +exceptions. Patch by Abraham Toriz Cruz. + +.. + +.. bpo: 38175 +.. date: 2019-09-15-10-30-33 +.. nonce: 61XlUv +.. section: Library + +Fix a memory leak in comparison of :class:`sqlite3.Row` objects. + +.. + +.. bpo: 33936 +.. date: 2019-09-14-10-34-00 +.. nonce: 8wCI_n +.. section: Library + +_hashlib no longer calls obsolete OpenSSL initialization function with +OpenSSL 1.1.0+. + +.. + +.. bpo: 34706 +.. date: 2019-09-13-14-54-33 +.. nonce: HWVpOY +.. section: Library + +Preserve subclassing in inspect.Signature.from_callable. + +.. + +.. bpo: 38153 +.. date: 2019-09-13-12-18-51 +.. nonce: nHAbuJ +.. section: Library + +Names of hashing algorithms from OpenSSL are now normalized to follow +Python's naming conventions. For example OpenSSL uses sha3-512 instead of +sha3_512 or blake2b512 instead of blake2b. + +.. + +.. bpo: 38115 +.. date: 2019-09-13-09-24-58 +.. nonce: BOO-Y1 +.. section: Library + +Fix a bug in dis.findlinestarts() where it would return invalid bytecode +offsets. Document that a code object's co_lnotab can contain invalid +bytecode offsets. + +.. + +.. bpo: 38148 +.. date: 2019-09-13-08-55-43 +.. nonce: Lnww6D +.. section: Library + +Add slots to :mod:`asyncio` transport classes, which can reduce memory +usage. + +.. + +.. bpo: 38142 +.. date: 2019-09-12-18-41-35 +.. nonce: 1I0Ch0 +.. section: Library + +The _hashlib OpenSSL wrapper extension module is now PEP-384 compliant. + +.. + +.. bpo: 9216 +.. date: 2019-09-12-14-54-45 +.. nonce: W7QMpC +.. section: Library + +hashlib constructors now support usedforsecurity flag to signal that a +hashing algorithm is not used in a security context. + +.. + +.. bpo: 36991 +.. date: 2019-09-12-14-52-38 +.. nonce: 1OcSm8 +.. section: Library + +Fixes a potential incorrect AttributeError exception escaping +ZipFile.extract() in some unsupported input error situations. + +.. + +.. bpo: 38134 +.. date: 2019-09-12-13-18-55 +.. nonce: gXJTbP +.. section: Library + +Remove obsolete copy of PBKDF2_HMAC_fast. All supported OpenSSL versions +contain a fast implementation. + +.. + +.. bpo: 38132 +.. date: 2019-09-12-12-47-35 +.. nonce: KSFx1F +.. section: Library + +The OpenSSL hashlib wrapper uses a simpler implementation. Several Macros +and pointless caches are gone. The hash name now comes from OpenSSL's EVP. +The algorithm name stays the same, except it is now always lower case. + +.. + +.. bpo: 38008 +.. date: 2019-09-12-10-47-34 +.. nonce: sH74Iy +.. section: Library + +Fix parent class check in protocols to correctly identify the module that +provides a builtin protocol, instead of assuming they all come from the +:mod:`collections.abc` module + +.. + +.. bpo: 34037 +.. date: 2019-09-11-21-38-41 +.. nonce: LIAS_3 +.. section: Library + +For :mod:`asyncio`, add a new coroutine +:meth:`loop.shutdown_default_executor`. The new coroutine provides an API to +schedule an executor shutdown that waits on the threadpool to finish +closing. Also, :func:`asyncio.run` has been updated to utilize the new +coroutine. Patch by Kyle Stanley. + +.. + +.. bpo: 37405 +.. date: 2019-09-11-20-27-41 +.. nonce: MG5xiY +.. section: Library + +Fixed regression bug for socket.getsockname() for non-CAN_ISOTP AF_CAN +address family sockets by returning a 1-tuple instead of string. + +.. + +.. bpo: 38121 +.. date: 2019-09-11-16-54-57 +.. nonce: SrSDzB +.. section: Library + +Update parameter names on functions in importlib.metadata matching the +changes in the 0.22 release of importlib_metadata. + +.. + +.. bpo: 38110 +.. date: 2019-09-11-14-49-20 +.. nonce: A19Y-q +.. section: Library + +The os.closewalk() implementation now uses the libc fdwalk() API on +platforms where it is available. + +.. + +.. bpo: 38093 +.. date: 2019-09-11-14-45-30 +.. nonce: yQ6k7y +.. section: Library + +Fixes AsyncMock so it doesn't crash when used with AsyncContextManagers or +AsyncIterators. + +.. + +.. bpo: 37488 +.. date: 2019-09-11-11-44-16 +.. nonce: S8CJUL +.. section: Library + +Add warning to :meth:`datetime.utctimetuple`, :meth:`datetime.utcnow` and +:meth:`datetime.utcfromtimestamp` . + +.. + +.. bpo: 35640 +.. date: 2019-09-10-15-52-55 +.. nonce: X0lp5f +.. section: Library + +Allow passing a :term:`path-like object` as ``directory`` argument to the +:class:`http.server.SimpleHTTPRequestHandler` class. Patch by Géry Ogam. + +.. + +.. bpo: 38086 +.. date: 2019-09-10-11-42-59 +.. nonce: w5TlG- +.. section: Library + +Update importlib.metadata with changes from `importlib_metadata 0.21 +<https://gitlab.com/python-devs/importlib_metadata/blob/0.21/importlib_metadata/docs/changelog.rst>`_. + +.. + +.. bpo: 37251 +.. date: 2019-09-10-10-59-50 +.. nonce: 8zn2o3 +.. section: Library + +Remove `__code__` check in AsyncMock that incorrectly evaluated function +specs as async objects but failed to evaluate classes with `__await__` but +no `__code__` attribute defined as async objects. + +.. + +.. bpo: 38037 +.. date: 2019-09-09-18-39-23 +.. nonce: B0UgFU +.. section: Library + +Fix reference counters in the :mod:`signal` module. + +.. + +.. bpo: 38066 +.. date: 2019-09-09-14-39-47 +.. nonce: l9mWv- +.. section: Library + +Hide internal asyncio.Stream methods: feed_eof(), feed_data(), +set_exception() and set_transport(). + +.. + +.. bpo: 38059 +.. date: 2019-09-08-11-36-50 +.. nonce: 8SA6co +.. section: Library + +inspect.py now uses sys.exit() instead of exit() + +.. + +.. bpo: 38049 +.. date: 2019-09-07-12-32-50 +.. nonce: xKP4tf +.. section: Library + +Added command-line interface for the :mod:`ast` module. + +.. + +.. bpo: 37953 +.. date: 2019-09-06-17-40-34 +.. nonce: db5FQq +.. section: Library + +In :mod:`typing`, improved the ``__hash__`` and ``__eq__`` methods for +:class:`ForwardReferences`. + +.. + +.. bpo: 38026 +.. date: 2019-09-04-20-34-14 +.. nonce: 0LLRX- +.. section: Library + +Fixed :func:`inspect.getattr_static` used ``isinstance`` while it should +avoid dynamic lookup. + +.. + +.. bpo: 35923 +.. date: 2019-09-03-01-41-35 +.. nonce: lYpKbY +.. section: Library + +Update :class:`importlib.machinery.BuiltinImporter` to use +``loader._ORIGIN`` instead of a hardcoded value. Patch by Donghee Na. + +.. + +.. bpo: 38010 +.. date: 2019-09-02-14-30-39 +.. nonce: JOnz9Z +.. section: Library + +In ``importlib.metadata`` sync with ``importlib_metadata`` 0.20, clarifying +behavior of ``files()`` and fixing issue where only one requirement was +returned for ``requires()`` on ``dist-info`` packages. + +.. + +.. bpo: 38006 +.. date: 2019-09-02-13-37-27 +.. nonce: Y7vA0Q +.. section: Library + +weakref.WeakValueDictionary defines a local remove() function used as +callback for weak references. This function was created with a closure. +Modify the implementation to avoid the closure. + +.. + +.. bpo: 37995 +.. date: 2019-08-31-13-36-09 +.. nonce: rS8HzT +.. section: Library + +Added the *indent* option to :func:`ast.dump` which allows it to produce a +multiline indented output. + +.. + +.. bpo: 34410 +.. date: 2019-08-31-01-52-59 +.. nonce: 7KbWZQ +.. section: Library + +Fixed a crash in the :func:`tee` iterator when re-enter it. RuntimeError is +now raised in this case. + +.. + +.. bpo: 37140 +.. date: 2019-08-30-11-21-10 +.. nonce: cFAX-a +.. section: Library + +Fix a ctypes regression of Python 3.8. When a ctypes.Structure is passed by +copy to a function, ctypes internals created a temporary object which had +the side effect of calling the structure finalizer (__del__) twice. The +Python semantics requires a finalizer to be called exactly once. Fix ctypes +internals to no longer call the finalizer twice. + +.. + +.. bpo: 37587 +.. date: 2019-08-29-18-48-48 +.. nonce: N7TGTC +.. section: Library + +``_json.scanstring`` is now up to 3x faster when there are many backslash +escaped characters in the JSON string. + +.. + +.. bpo: 37834 +.. date: 2019-08-29-16-41-36 +.. nonce: FThnsh +.. section: Library + +Prevent shutil.rmtree exception when built on non-Windows system without fd +system call support, like older versions of macOS. + +.. + +.. bpo: 10978 +.. date: 2019-08-29-01-19-13 +.. nonce: J6FQYY +.. section: Library + +Semaphores and BoundedSemaphores can now release more than one waiting +thread at a time. + +.. + +.. bpo: 37972 +.. date: 2019-08-28-21-40-12 +.. nonce: kP-n4L +.. section: Library + +Subscripts to the `unittest.mock.call` objects now receive the same chaining +mechanism as any other custom attributes, so that the following usage no +longer raises a `TypeError`: + +call().foo().__getitem__('bar') + +Patch by blhsing + +.. + +.. bpo: 37965 +.. date: 2019-08-28-14-04-18 +.. nonce: 7xGE-C +.. section: Library + +Fix C compiler warning caused by distutils.ccompiler.CCompiler.has_function. + +.. + +.. bpo: 37964 +.. date: 2019-08-27-21-19-28 +.. nonce: SxdnsF +.. section: Library + +Add ``F_GETPATH`` command to :mod:`fcntl`. + +.. + +.. bpo: 37960 +.. date: 2019-08-27-10-52-13 +.. nonce: CTY7Lw +.. section: Library + +``repr()`` of buffered and text streams now silences only expected +exceptions when get the value of "name" and "mode" attributes. + +.. + +.. bpo: 37961 +.. date: 2019-08-27-10-30-44 +.. nonce: 4nm0zZ +.. section: Library + +Add a ``total_nframe`` field to the traces collected by the tracemalloc +module. This field indicates the original number of frames before it was +truncated. + +.. + +.. bpo: 37951 +.. date: 2019-08-27-10-03-48 +.. nonce: MfRQgL +.. section: Library + +Most features of the subprocess module now work again in subinterpreters. +Only *preexec_fn* is restricted in subinterpreters. + +.. + +.. bpo: 36205 +.. date: 2019-08-27-03-53-26 +.. nonce: AfkGRl +.. section: Library + +Fix the rusage implementation of time.process_time() to correctly report the +sum of the system and user CPU time. + +.. + +.. bpo: 37950 +.. date: 2019-08-26-10-45-51 +.. nonce: -K1IKT +.. section: Library + +Fix :func:`ast.dump` when call with incompletely initialized node. + +.. + +.. bpo: 34679 +.. date: 2019-08-25-18-07-48 +.. nonce: HECzL7 +.. section: Library + +Restores instantiation of Windows IOCP event loops from the non-main thread. + +.. + +.. bpo: 36917 +.. date: 2019-08-25-14-56-42 +.. nonce: GBxdw2 +.. section: Library + +Add default implementation of the :meth:`ast.NodeVisitor.visit_Constant` +method which emits a deprecation warning and calls corresponding methody +``visit_Num()``, ``visit_Str()``, etc. + +.. + +.. bpo: 37798 +.. date: 2019-08-24-16-54-49 +.. nonce: 7mRQCk +.. section: Library + +Update test_statistics.py to verify that the statistics module works well +for both C and Python implementations. Patch by Donghee Na + +.. + +.. bpo: 26589 +.. date: 2019-08-23-00-55-19 +.. nonce: M1xyxG +.. section: Library + +Added a new status code to the http module: 451 +UNAVAILABLE_FOR_LEGAL_REASONS + +.. + +.. bpo: 37915 +.. date: 2019-08-22-16-13-27 +.. nonce: xyoZI5 +.. section: Library + +Fix a segmentation fault that appeared when comparing instances of +``datetime.timezone`` and ``datetime.tzinfo`` objects. Patch by Pablo +Galindo. + +.. + +.. bpo: 32554 +.. date: 2019-08-22-01-49-05 +.. nonce: 4xiXyM +.. section: Library + +Deprecate having random.seed() call hash on arbitrary types. + +.. + +.. bpo: 9938 +.. date: 2019-08-21-16-38-56 +.. nonce: t3G7N9 +.. section: Library + +Add optional keyword argument ``exit_on_error`` for :class:`ArgumentParser`. + +.. + +.. bpo: 37851 +.. date: 2019-08-21-13-43-04 +.. nonce: mIIfD_ +.. section: Library + +The :mod:`faulthandler` module no longer allocates its alternative stack at +Python startup. Now the stack is only allocated at the first faulthandler +usage. + +.. + +.. bpo: 32793 +.. date: 2019-08-20-05-17-32 +.. nonce: cgpXl6 +.. section: Library + +Fix a duplicated debug message when :meth:`smtplib.SMTP.connect` is called. + +.. + +.. bpo: 37885 +.. date: 2019-08-19-10-31-41 +.. nonce: 4Nc9sp +.. section: Library + +venv: Don't generate unset variable warning on deactivate. + +.. + +.. bpo: 37868 +.. date: 2019-08-17-22-33-54 +.. nonce: hp64fi +.. section: Library + +Fix dataclasses.is_dataclass when given an instance that never raises +AttributeError in __getattr__. That is, an object that returns something +for __dataclass_fields__ even if it's not a dataclass. + +.. + +.. bpo: 37811 +.. date: 2019-08-14-21-41-07 +.. nonce: d1xYj7 +.. section: Library + +Fix ``socket`` module's ``socket.connect(address)`` function being unable to +establish connection in case of interrupted system call. The problem was +observed on all OSes which ``poll(2)`` system call can take only +non-negative integers and -1 as a timeout value. + +.. + +.. bpo: 37863 +.. date: 2019-08-14-20-46-39 +.. nonce: CkXqgX +.. section: Library + +Optimizations for Fraction.__hash__ suggested by Tim Peters. + +.. + +.. bpo: 21131 +.. date: 2019-08-14-15-34-23 +.. nonce: 0MMQRi +.. section: Library + +Fix ``faulthandler.register(chain=True)`` stack. faulthandler now allocates +a dedicated stack of ``SIGSTKSZ*2`` bytes, instead of just ``SIGSTKSZ`` +bytes. Calling the previous signal handler in faulthandler signal handler +uses more than ``SIGSTKSZ`` bytes of stack memory on some platforms. + +.. + +.. bpo: 37798 +.. date: 2019-08-14-13-51-24 +.. nonce: AmXrik +.. section: Library + +Add C fastpath for statistics.NormalDist.inv_cdf() Patch by Donghee Na + +.. + +.. bpo: 37804 +.. date: 2019-08-12-23-07-47 +.. nonce: Ene6L- +.. section: Library + +Remove the deprecated method `threading.Thread.isAlive()`. Patch by Donghee +Na. + +.. + +.. bpo: 37819 +.. date: 2019-08-11-10-34-19 +.. nonce: LVJls- +.. section: Library + +Add Fraction.as_integer_ratio() to match the corresponding methods in bool, +int, float, and decimal. + +.. + +.. bpo: 14465 +.. date: 2019-08-10-18-50-04 +.. nonce: qZGC4g +.. section: Library + +Add an xml.etree.ElementTree.indent() function for pretty-printing XML +trees. Contributed by Stefan Behnel. + +.. + +.. bpo: 37810 +.. date: 2019-08-10-12-33-27 +.. nonce: d4zbvB +.. section: Library + +Fix :mod:`difflib` ``?`` hint in diff output when dealing with tabs. Patch +by Anthony Sottile. + +.. + +.. bpo: 37772 +.. date: 2019-08-07-23-48-09 +.. nonce: hLCvdn +.. section: Library + +In ``zipfile.Path``, when adding implicit dirs, ensure that ancestral +directories are added and that duplicates are excluded. + +.. + +.. bpo: 18578 +.. date: 2019-08-07-19-34-07 +.. nonce: xfvdb_ +.. section: Library + +Renamed and documented `test.bytecode_helper` as +`test.support.bytecode_helper`. Patch by Joannah Nanjekye. + +.. + +.. bpo: 37785 +.. date: 2019-08-07-14-49-22 +.. nonce: y7OlT8 +.. section: Library + +Fix xgettext warnings in :mod:`argparse`. + +.. + +.. bpo: 34488 +.. date: 2019-08-06-21-30-58 +.. nonce: OqxVo8 +.. section: Library + +:meth:`writelines` method of :class:`io.BytesIO` is now slightly faster when +many small lines are passed. Patch by Sergey Fedoseev. + +.. + +.. bpo: 37449 +.. date: 2019-08-04-17-22-33 +.. nonce: ycbL2z +.. section: Library + +`ensurepip` now uses `importlib.resources.read_binary()` to read data +instead of `pkgutil.get_data()`. Patch by Joannah Nanjekye. + +.. + +.. bpo: 28292 +.. date: 2019-08-04-11-47-58 +.. nonce: vkihH5 +.. section: Library + +Mark calendar.py helper functions as being private. The follows PEP 8 +guidance to maintain the style conventions in the module and it addresses a +known case of user confusion. + +.. + +.. bpo: 18049 +.. date: 2019-08-02-16-44-42 +.. nonce: OA4qBL +.. section: Library + +Add definition of THREAD_STACK_SIZE for AIX in Python/thread_pthread.h The +default thread stacksize caused crashes with the default recursion limit +Patch by M Felt + +.. + +.. bpo: 37742 +.. date: 2019-08-02-14-01-25 +.. nonce: f4Xn9S +.. section: Library + +The logging.getLogger() API now returns the root logger when passed the name +'root', whereas previously it returned a non-root logger named 'root'. This +could affect cases where user code explicitly wants a non-root logger named +'root', or instantiates a logger using logging.getLogger(__name__) in some +top-level module called 'root.py'. + +.. + +.. bpo: 37738 +.. date: 2019-08-01-17-11-16 +.. nonce: A3WWcT +.. section: Library + +Fix the implementation of curses ``addch(str, color_pair)``: pass the color +pair to ``setcchar()``, instead of always passing 0 as the color pair. + +.. + +.. bpo: 37723 +.. date: 2019-07-31-16-49-01 +.. nonce: zq6tw8 +.. section: Library + +Fix performance regression on regular expression parsing with huge character +sets. Patch by Yann Vaginay. + +.. + +.. bpo: 35943 +.. date: 2019-07-31-15-52-51 +.. nonce: -KswoB +.. section: Library + +The function :c:func:`PyImport_GetModule` now ensures any module it returns +is fully initialized. Patch by Joannah Nanjekye. + +.. + +.. bpo: 32178 +.. date: 2019-07-30-22-41-05 +.. nonce: X-IFLe +.. section: Library + +Fix IndexError in :mod:`email` package when trying to parse invalid address +fields starting with ``:``. + +.. + +.. bpo: 37268 +.. date: 2019-07-30-01-27-29 +.. nonce: QDmA44 +.. section: Library + +The :mod:`parser` module is deprecated and will be removed in future +versions of Python. + +.. + +.. bpo: 11953 +.. date: 2019-07-29-21-39-45 +.. nonce: 4Hpwf9 +.. section: Library + +Completing WSA* error codes in :mod:`socket`. + +.. + +.. bpo: 37685 +.. date: 2019-07-28-22-25-25 +.. nonce: _3bN9f +.. section: Library + +Fixed comparisons of :class:`datetime.timedelta` and +:class:`datetime.timezone`. + +.. + +.. bpo: 37697 +.. date: 2019-07-28-17-44-21 +.. nonce: 7UV5d0 +.. section: Library + +Synchronize ``importlib.metadata`` with `importlib_metadata 0.19 +<https://gitlab.com/python-devs/importlib_metadata/-/milestones/20>`_, +improving handling of EGG-INFO files and fixing a crash when entry point +names contained colons. + +.. + +.. bpo: 37695 +.. date: 2019-07-27-20-21-03 +.. nonce: QANdvg +.. section: Library + +Correct :func:`curses.unget_wch` error message. Patch by Anthony Sottile. + +.. + +.. bpo: 37689 +.. date: 2019-07-27-18-00-43 +.. nonce: glEmZi +.. section: Library + +Add :meth:`is_relative_to` in :class:`PurePath` to determine whether or not +one path is relative to another. + +.. + +.. bpo: 29553 +.. date: 2019-07-27-10-14-45 +.. nonce: TVeIDe +.. section: Library + +Fixed :meth:`argparse.ArgumentParser.format_usage` for mutually exclusive +groups. Patch by Andrew Nester. + +.. + +.. bpo: 37691 +.. date: 2019-07-26-22-30-01 +.. nonce: 1Li3rx +.. section: Library + +Let math.dist() accept coordinates as sequences (or iterables) rather than +just tuples. + +.. + +.. bpo: 37685 +.. date: 2019-07-26-00-12-29 +.. nonce: TqckMZ +.. section: Library + +Fixed ``__eq__``, ``__lt__`` etc implementations in some classes. They now +return :data:`NotImplemented` for unsupported type of the other operand. +This allows the other operand to play role (for example the equality +comparison with :data:`~unittest.mock.ANY` will return ``True``). + +.. + +.. bpo: 37354 +.. date: 2019-07-25-10-28-40 +.. nonce: RT3_3H +.. section: Library + +Make Activate.ps1 Powershell script static to allow for signing it. + +.. + +.. bpo: 37664 +.. date: 2019-07-24-18-27-44 +.. nonce: o-GYZC +.. section: Library + +Update wheels bundled with ensurepip (pip 19.2.3 and setuptools 41.2.0) + +.. + +.. bpo: 37663 +.. date: 2019-07-24-14-38-53 +.. nonce: h4-9-1 +.. section: Library + +Bring consistency to venv shell activation scripts by always using +__VENV_PROMPT__. + +.. + +.. bpo: 37642 +.. date: 2019-07-21-20-59-31 +.. nonce: L61Bvy +.. section: Library + +Allowed the pure Python implementation of :class:`datetime.timezone` to +represent sub-minute offsets close to minimum and maximum boundaries, +specifically in the ranges (23:59, 24:00) and (-23:59, 24:00). Patch by +Ngalim Siregar + +.. + +.. bpo: 36161 +.. date: 2019-07-20-01-17-43 +.. nonce: Fzf-f9 +.. section: Library + +In :mod:`posix`, use ``ttyname_r`` instead of ``ttyname`` for thread safety. + +.. + +.. bpo: 36324 +.. date: 2019-07-19-22-44-41 +.. nonce: 1VjywS +.. section: Library + +Make internal attributes for statistics.NormalDist() private. + +.. + +.. bpo: 37555 +.. date: 2019-07-19-20-13-48 +.. nonce: S5am28 +.. section: Library + +Fix `NonCallableMock._call_matcher` returning tuple instead of `_Call` +object when `self._spec_signature` exists. Patch by Elizabeth Uselton + +.. + +.. bpo: 29446 +.. date: 2019-07-19-16-06-48 +.. nonce: iXGuoi +.. section: Library + +Make `from tkinter import *` import only the expected objects. + +.. + +.. bpo: 16970 +.. date: 2019-07-19-01-46-56 +.. nonce: GEASf5 +.. section: Library + +Adding a value error when an invalid value in passed to nargs Patch by +Robert Leenders + +.. + +.. bpo: 34443 +.. date: 2019-07-17-11-10-08 +.. nonce: OFnGqz +.. section: Library + +Exceptions from :mod:`enum` now use the ``__qualname`` of the enum class in +the exception message instead of the ``__name__``. + +.. + +.. bpo: 37491 +.. date: 2019-07-17-06-54-43 +.. nonce: op0aMs +.. section: Library + +Fix ``IndexError`` when parsing email headers with unexpectedly ending +bare-quoted string value. Patch by Abhilash Raj. + +.. + +.. bpo: 37587 +.. date: 2019-07-13-16-02-48 +.. nonce: fd-1aF +.. section: Library + +Make json.loads faster for long strings. (Patch by Marco Paolini) + +.. + +.. bpo: 18378 +.. date: 2019-07-13-13-40-12 +.. nonce: NHcojp +.. section: Library + +Recognize "UTF-8" as a valid value for LC_CTYPE in locale._parse_localename. + +.. + +.. bpo: 37579 +.. date: 2019-07-13-10-59-43 +.. nonce: B1Tq9i +.. section: Library + +Return :exc:`NotImplemented` in Python implementation of ``__eq__`` for +:class:`~datetime.timedelta` and :class:`~datetime.time` when the other +object being compared is not of the same type to match C implementation. +Patch by Karthikeyan Singaravelan. + +.. + +.. bpo: 21478 +.. date: 2019-07-10-23-07-11 +.. nonce: cCw9rF +.. section: Library + +Record calls to parent when autospecced object is attached to a mock using +:func:`unittest.mock.attach_mock`. Patch by Karthikeyan Singaravelan. + +.. + +.. bpo: 37531 +.. date: 2019-07-09-19-38-26 +.. nonce: GX7s8S +.. section: Library + +"python3 -m test -jN --timeout=TIMEOUT" now kills a worker process if it +runs longer than *TIMEOUT* seconds. + +.. + +.. bpo: 37482 +.. date: 2019-07-09-11-20-21 +.. nonce: auzvev +.. section: Library + +Fix serialization of display name in originator or destination address +fields with both encoded words and special chars. + +.. + +.. bpo: 36993 +.. date: 2019-07-09-05-44-39 +.. nonce: 4javqu +.. section: Library + +Improve error reporting for corrupt zip files with bad zip64 extra data. +Patch by Daniel Hillier. + +.. + +.. bpo: 37502 +.. date: 2019-07-08-03-15-04 +.. nonce: qZGC4g +.. section: Library + +pickle.loads() no longer raises TypeError when the buffers argument is set +to None + +.. + +.. bpo: 37520 +.. date: 2019-07-07-21-09-08 +.. nonce: Gg0KD6 +.. section: Library + +Correct behavior for zipfile.Path.parent when the path object identifies a +subdirectory. + +.. + +.. bpo: 18374 +.. date: 2019-07-05-21-46-45 +.. nonce: qgE0H3 +.. section: Library + +Fix the ``.col_offset`` attribute of nested :class:`ast.BinOp` instances +which had a too large value in some situations. + +.. + +.. bpo: 37424 +.. date: 2019-07-04-13-00-20 +.. nonce: 0i1MR- +.. section: Library + +Fixes a possible hang when using a timeout on `subprocess.run()` while +capturing output. If the child process spawned its own children or +otherwise connected its stdout or stderr handles with another process, we +could hang after the timeout was reached and our child was killed when +attempting to read final output from the pipes. + +.. + +.. bpo: 37421 +.. date: 2019-07-03-12-47-52 +.. nonce: gR5hC8 +.. section: Library + +Fix :func:`multiprocessing.util.get_temp_dir` finalizer: clear also the +'tempdir' configuration of the current process, so next call to +``get_temp_dir()`` will create a new temporary directory, rather than +reusing the removed temporary directory. + +.. + +.. bpo: 37481 +.. date: 2019-07-02-13-08-30 +.. nonce: hd5k09 +.. section: Library + +The distutils ``bdist_wininst`` command is deprecated in Python 3.8, use +``bdist_wheel`` (wheel packages) instead. + +.. + +.. bpo: 37479 +.. date: 2019-07-02-12-43-57 +.. nonce: O53a5S +.. section: Library + +When `Enum.__str__` is overridden in a derived class, the override will be +used by `Enum.__format__` regardless of whether mixin classes are present. + +.. + +.. bpo: 37440 +.. date: 2019-06-28-16-40-17 +.. nonce: t3wX-N +.. section: Library + +http.client now enables TLS 1.3 post-handshake authentication for default +context or if a cert_file is passed to HTTPSConnection. + +.. + +.. bpo: 37437 +.. date: 2019-06-27-20-33-50 +.. nonce: du39_A +.. section: Library + +Update vendorized expat version to 2.2.7. + +.. + +.. bpo: 37428 +.. date: 2019-06-27-13-27-02 +.. nonce: _wcwUd +.. section: Library + +SSLContext.post_handshake_auth = True no longer sets +SSL_VERIFY_POST_HANDSHAKE verify flag for client connections. Although the +option is documented as ignored for clients, OpenSSL implicitly enables cert +chain validation when the flag is set. + +.. + +.. bpo: 37420 +.. date: 2019-06-26-22-25-05 +.. nonce: CxFJ09 +.. section: Library + +:func:`os.sched_setaffinity` now correctly handles errors that arise during +iteration over its ``mask`` argument. Patch by Brandt Bucher. + +.. + +.. bpo: 37412 +.. date: 2019-06-26-16-28-59 +.. nonce: lx0VjC +.. section: Library + +The :func:`os.getcwdb` function now uses the UTF-8 encoding on Windows, +rather than the ANSI code page: see :pep:`529` for the rationale. The +function is no longer deprecated on Windows. + +.. + +.. bpo: 37406 +.. date: 2019-06-26-03-00-06 +.. nonce: uovkpq +.. section: Library + +The sqlite3 module now raises TypeError, rather than ValueError, if +operation argument type is not str: execute(), executemany() and calling a +connection. + +.. + +.. bpo: 29412 +.. date: 2019-06-25-19-27-25 +.. nonce: n4Zqdh +.. section: Library + +Fix IndexError in parsing a header value ending unexpectedly. Patch by +Abhilash Raj. + +.. + +.. bpo: 36546 +.. date: 2019-06-25-05-07-48 +.. nonce: RUcxaK +.. section: Library + +The *dist* argument for statistics.quantiles() is now positional only. The +current name doesn't reflect that the argument can be either a dataset or a +distribution. Marking the parameter as positional avoids confusion and +makes it possible to change the name later. + +.. + +.. bpo: 37394 +.. date: 2019-06-25-02-10-00 +.. nonce: srZ1zx +.. section: Library + +Fix a bug that was causing the :mod:`queue` module to fail if the +accelerator module was not available. Patch by Pablo Galindo. + +.. + +.. bpo: 37376 +.. date: 2019-06-24-11-26-34 +.. nonce: SwSUQ4 +.. section: Library + +:mod:`pprint` now has support for :class:`types.SimpleNamespace`. Patch by +Carl Bordum Hansen. + +.. + +.. bpo: 26967 +.. date: 2019-06-23-12-46-10 +.. nonce: xEuem1 +.. section: Library + +An :class:`~argparse.ArgumentParser` with ``allow_abbrev=False`` no longer +disables grouping of short flags, such as ``-vv``, but only disables +abbreviation of long flags as documented. Patch by Zac Hatfield-Dodds. + +.. + +.. bpo: 37212 +.. date: 2019-06-22-22-00-35 +.. nonce: Zhv-tq +.. section: Library + +:func:`unittest.mock.call` now preserves the order of keyword arguments in +repr output. Patch by Karthikeyan Singaravelan. + +.. + +.. bpo: 37372 +.. date: 2019-06-22-12-30-00 +.. nonce: kIKqZ6 +.. section: Library + +Fix error unpickling datetime.time objects from Python 2 with seconds>=24. +Patch by Justin Blanchard. + +.. + +.. bpo: 37345 +.. date: 2019-06-22-08-51-44 +.. nonce: o8XABX +.. section: Library + +Add formal support for UDPLITE sockets. Support was present before, but it +is now easier to detect support with ``hasattr(socket, 'IPPROTO_UDPLITE')`` +and there are constants defined for each of the values needed: +:py:obj:`socket.IPPROTO_UDPLITE`, :py:obj:`UDPLITE_SEND_CSCOV`, and +:py:obj:`UDPLITE_RECV_CSCOV`. Patch by Gabe Appleton. + +.. + +.. bpo: 37358 +.. date: 2019-06-21-14-54-02 +.. nonce: RsASpn +.. section: Library + +Optimized ``functools.partial`` by using vectorcall. + +.. + +.. bpo: 37347 +.. date: 2019-06-20-14-23-48 +.. nonce: Gf9yYI +.. section: Library + +:meth:`sqlite3.Connection.create_aggregate`, +:meth:`sqlite3.Connection.create_function`, +:meth:`sqlite3.Connection.set_authorizer`, +:meth:`sqlite3.Connection.set_progress_handler` +:meth:`sqlite3.Connection.set_trace_callback` methods lead to segfaults if +some of these methods are called twice with an equal object but not the +same. Now callbacks are stored more carefully. Patch by Aleksandr Balezin. + +.. + +.. bpo: 37163 +.. date: 2019-06-19-10-35-53 +.. nonce: 9pPg2F +.. section: Library + +The *obj* argument of :func:`dataclasses.replace` is positional-only now. + +.. + +.. bpo: 37085 +.. date: 2019-06-18-16-29-31 +.. nonce: GeYaD6 +.. section: Library + +Add the optional Linux SocketCAN Broadcast Manager constants, used as flags +to configure the BCM behaviour, in the socket module. Patch by Karl Ding. + +.. + +.. bpo: 37328 +.. date: 2019-06-18-15-31-33 +.. nonce: 2PW1-l +.. section: Library + +``HTMLParser.unescape`` is removed. It was undocumented and deprecated +since Python 3.4. + +.. + +.. bpo: 37305 +.. date: 2019-06-18-13-59-55 +.. nonce: fGzWlP +.. section: Library + +Add .webmanifest -> application/manifest+json to list of recognized file +types and content type headers + +.. + +.. bpo: 37320 +.. date: 2019-06-17-22-10-37 +.. nonce: ffieYa +.. section: Library + +``aifc.openfp()`` alias to ``aifc.open()``, ``sunau.openfp()`` alias to +``sunau.open()``, and ``wave.openfp()`` alias to ``wave.open()`` have been +removed. They were deprecated since Python 3.7. + +.. + +.. bpo: 37315 +.. date: 2019-06-17-11-59-52 +.. nonce: o1xFC0 +.. section: Library + +Deprecated accepting floats with integral value (like ``5.0``) in +:func:`math.factorial`. + +.. + +.. bpo: 37312 +.. date: 2019-06-17-10-03-52 +.. nonce: qKvBfF +.. section: Library + +``_dummy_thread`` and ``dummy_threading`` modules have been removed. These +modules were deprecated since Python 3.7 which requires threading support. + +.. + +.. bpo: 33972 +.. date: 2019-06-15-14-39-50 +.. nonce: XxnNPw +.. section: Library + +Email with single part but content-type set to ``multipart/*`` doesn't raise +AttributeError anymore. + +.. + +.. bpo: 37280 +.. date: 2019-06-14-13-30-47 +.. nonce: Fxur0F +.. section: Library + +Use threadpool for reading from file for sendfile fallback mode. + +.. + +.. bpo: 37279 +.. date: 2019-06-14-13-25-56 +.. nonce: OHlW6l +.. section: Library + +Fix asyncio sendfile support when sendfile sends extra data in fallback +mode. + +.. + +.. bpo: 19865 +.. date: 2019-06-14-08-30-16 +.. nonce: FRGH4I +.. section: Library + +:func:`ctypes.create_unicode_buffer()` now also supports non-BMP characters +on platforms with 16-bit :c:type:`wchar_t` (for example, Windows and AIX). + +.. + +.. bpo: 37266 +.. date: 2019-06-13-11-59-52 +.. nonce: goLjef +.. section: Library + +In a subinterpreter, spawning a daemon thread now raises an exception. +Daemon threads were never supported in subinterpreters. Previously, the +subinterpreter finalization crashed with a Python fatal error if a daemon +thread was still running. + +.. + +.. bpo: 37210 +.. date: 2019-06-12-16-10-50 +.. nonce: r4yMg6 +.. section: Library + +Allow pure Python implementation of :mod:`pickle` to work even when the C +:mod:`_pickle` module is unavailable. + +.. + +.. bpo: 21872 +.. date: 2019-06-12-08-56-22 +.. nonce: V9QGGN +.. section: Library + +Fix :mod:`lzma`: module decompresses data incompletely. When decompressing a +FORMAT_ALONE format file, and it doesn't have the end marker, sometimes the +last one to dozens bytes can't be output. Patch by Ma Lin. + +.. + +.. bpo: 35922 +.. date: 2019-06-11-19-34-29 +.. nonce: rxpzWr +.. section: Library + +Fix :meth:`RobotFileParser.crawl_delay` and +:meth:`RobotFileParser.request_rate` to return ``None`` rather than raise +:exc:`AttributeError` when no relevant rule is defined in the robots.txt +file. Patch by Rémi Lapeyre. + +.. + +.. bpo: 35766 +.. date: 2019-06-11-16-41-40 +.. nonce: v1Kj-T +.. section: Library + +Change the format of feature_version to be a (major, minor) tuple. + +.. + +.. bpo: 36607 +.. date: 2019-06-11-13-52-04 +.. nonce: 5_mJkQ +.. section: Library + +Eliminate :exc:`RuntimeError` raised by :func:`asyncio.all_tasks()` if +internal tasks weak set is changed by another thread during iteration. + +.. + +.. bpo: 18748 +.. date: 2019-06-11-01-54-19 +.. nonce: ADqCkq +.. section: Library + +:class:`_pyio.IOBase` destructor now does nothing if getting the ``closed`` +attribute fails to better mimic :class:`_io.IOBase` finalizer. + +.. + +.. bpo: 36402 +.. date: 2019-06-11-00-35-02 +.. nonce: b0IJVp +.. section: Library + +Fix a race condition at Python shutdown when waiting for threads. Wait until +the Python thread state of all non-daemon threads get deleted (join all +non-daemon threads), rather than just wait until non-daemon Python threads +complete. + +.. + +.. bpo: 37206 +.. date: 2019-06-09-22-25-03 +.. nonce: 2WBg4q +.. section: Library + +Default values which cannot be represented as Python objects no longer +improperly represented as ``None`` in function signatures. + +.. + +.. bpo: 37111 +.. date: 2019-06-09-17-22-33 +.. nonce: 2I0z2k +.. section: Library + +Added ``encoding`` and ``errors`` keyword parameters to +``logging.basicConfig``. + +.. + +.. bpo: 12144 +.. date: 2019-06-08-23-26-58 +.. nonce: Z7mz-q +.. section: Library + +Ensure cookies with ``expires`` attribute are handled in +:meth:`CookieJar.make_cookies`. + +.. + +.. bpo: 34886 +.. date: 2019-06-08-16-03-19 +.. nonce: Ov-pc9 +.. section: Library + +Fix an unintended ValueError from :func:`subprocess.run` when checking for +conflicting `input` and `stdin` or `capture_output` and `stdout` or `stderr` +args when they were explicitly provided but with `None` values within a +passed in `**kwargs` dict rather than as passed directly by name. Patch +contributed by Rémi Lapeyre. + +.. + +.. bpo: 37173 +.. date: 2019-06-08-11-33-48 +.. nonce: 0e_8gS +.. section: Library + +The exception message for ``inspect.getfile()`` now correctly reports the +passed class rather than the builtins module. + +.. + +.. bpo: 37178 +.. date: 2019-06-07-17-16-09 +.. nonce: Day_oB +.. section: Library + +Give math.perm() a one argument form that means the same as +math.factorial(). + +.. + +.. bpo: 37178 +.. date: 2019-06-07-17-11-34 +.. nonce: b1StSv +.. section: Library + +For math.perm(n, k), let k default to n, giving the same result as +factorial. + +.. + +.. bpo: 37165 +.. date: 2019-06-05-11-48-19 +.. nonce: V_rwfE +.. section: Library + +Converted _collections._count_elements to use the Argument Clinic. + +.. + +.. bpo: 34767 +.. date: 2019-06-04-23-44-52 +.. nonce: BpDShN +.. section: Library + +Do not always create a :class:`collections.deque` in :class:`asyncio.Lock`. + +.. + +.. bpo: 37158 +.. date: 2019-06-04-22-25-38 +.. nonce: JKm15S +.. section: Library + +Speed-up statistics.fmean() by switching from a function to a generator. + +.. + +.. bpo: 34282 +.. date: 2019-06-04-15-39-14 +.. nonce: aAK54n +.. section: Library + +Remove ``Enum._convert`` method, deprecated in 3.8. + +.. + +.. bpo: 37150 +.. date: 2019-06-04-14-44-41 +.. nonce: TTzHxj +.. section: Library + +`argparse._ActionsContainer.add_argument` now throws error, if someone +accidentally pass FileType class object instead of instance of FileType as +`type` argument + +.. + +.. bpo: 28724 +.. date: 2019-05-30-15-51-42 +.. nonce: 34TrS8 +.. section: Library + +The socket module now has the :func:`socket.send_fds` and +:func:`socket.recv.fds` methods. Contributed by Joannah Nanjekye, Shinya +Okano and Victor Stinner. + +.. + +.. bpo: 35621 +.. date: 2019-05-28-19-03-46 +.. nonce: Abc1lf +.. section: Library + +Support running asyncio subprocesses when execution event loop in a thread +on UNIX. + +.. + +.. bpo: 36520 +.. date: 2019-05-28-02-37-00 +.. nonce: W4tday +.. section: Library + +Lengthy email headers with UTF-8 characters are now properly encoded when +they are folded. Patch by Jeffrey Kintscher. + +.. + +.. bpo: 30835 +.. date: 2019-05-27-15-29-46 +.. nonce: 3FoaWH +.. section: Library + +Fixed a bug in email parsing where a message with invalid bytes in +content-transfer-encoding of a multipart message can cause an +AttributeError. Patch by Andrew Donnellan. + +.. + +.. bpo: 31163 +.. date: 2019-05-26-16-34-53 +.. nonce: 21A802 +.. section: Library + +pathlib.Path instance's rename and replace methods now return the new Path +instance. + +.. + +.. bpo: 25068 +.. date: 2019-05-22-04-52-35 +.. nonce: vR_rC- +.. section: Library + +:class:`urllib.request.ProxyHandler` now lowercases the keys of the passed +dictionary. + +.. + +.. bpo: 26185 +.. date: 2019-05-20-14-17-29 +.. nonce: pQW4mI +.. section: Library + +Fix :func:`repr` on empty :class:`ZipInfo` object. Patch by Mickaël +Schoentgen. + +.. + +.. bpo: 21315 +.. date: 2019-05-19-10-48-46 +.. nonce: PgXVqF +.. section: Library + +Email headers containing RFC2047 encoded words are parsed despite the +missing whitespace, and a defect registered. Also missing trailing +whitespace after encoded words is now registered as a defect. + +.. + +.. bpo: 31904 +.. date: 2019-05-17-16-50-02 +.. nonce: 4a5ggm +.. section: Library + +Port test_datetime to VxWorks: skip zoneinfo tests on VxWorks + +.. + +.. bpo: 35805 +.. date: 2019-05-17-15-11-08 +.. nonce: E4YwYz +.. section: Library + +Add parser for Message-ID header and add it to default HeaderRegistry. This +should prevent folding of Message-ID using RFC 2048 encoded words. + +.. + +.. bpo: 36871 +.. date: 2019-05-12-12-58-37 +.. nonce: 6xiEHZ +.. section: Library + +Ensure method signature is used instead of constructor signature of a class +while asserting mock object against method calls. Patch by Karthikeyan +Singaravelan. + +.. + +.. bpo: 35070 +.. date: 2019-05-09-18-50-55 +.. nonce: 4vaqNL +.. section: Library + +posix.getgrouplist() now works correctly when the user belongs to +NGROUPS_MAX supplemental groups. Patch by Jeffrey Kintscher. + +.. + +.. bpo: 31783 +.. date: 2019-05-07-19-25-55 +.. nonce: lgLo69 +.. section: Library + +Fix race condition in ThreadPoolExecutor when worker threads are created +during interpreter shutdown. + +.. + +.. bpo: 36582 +.. date: 2019-05-07-17-42-36 +.. nonce: L_dxR6 +.. section: Library + +Fix ``UserString.encode()`` to correctly return ``bytes`` rather than a +``UserString`` instance. + +.. + +.. bpo: 32424 +.. date: 2019-04-28-10-34-19 +.. nonce: eqNPhM +.. section: Library + +Deprecate xml.etree.ElementTree.Element.copy() in favor of copy.copy(). + +Patch by Gordon P. Hemsley + +.. + +.. bpo: 36564 +.. date: 2019-04-08-13-00-13 +.. nonce: _n67m_ +.. section: Library + +Fix infinite loop in email header folding logic that would be triggered when +an email policy's max_line_length is not long enough to include the required +markup and any values in the message. Patch by Paul Ganssle + +.. + +.. bpo: 36543 +.. date: 2019-04-06-20-08-12 +.. nonce: RPjmUz +.. section: Library + +Removed methods Element.getchildren(), Element.getiterator() and +ElementTree.getiterator() and the xml.etree.cElementTree module. + +.. + +.. bpo: 36409 +.. date: 2019-03-23-16-42-46 +.. nonce: ZYVKao +.. section: Library + +Remove the old plistlib API deprecated in Python 3.4 + +.. + +.. bpo: 36302 +.. date: 2019-03-21-19-23-46 +.. nonce: Yc591g +.. section: Library + +distutils sorts source file lists so that Extension .so files build more +reproducibly by default + +.. + +.. bpo: 36250 +.. date: 2019-03-09-16-04-12 +.. nonce: tSK4N1 +.. section: Library + +Ignore ``ValueError`` from ``signal`` with ``interaction`` in non-main +thread. + +.. + +.. bpo: 36046 +.. date: 2019-02-19-17-32-45 +.. nonce: fX9OPj +.. section: Library + +Added ``user``, ``group`` and ``extra_groups`` parameters to the +subprocess.Popen constructor. Patch by Patrick McLean. + +.. + +.. bpo: 32627 +.. date: 2019-02-03-19-13-08 +.. nonce: b68f64 +.. section: Library + +Fix compile error when ``_uuid`` headers conflicting included. + +.. + +.. bpo: 35800 +.. date: 2019-01-25-17-12-17 +.. nonce: MCGJdQ +.. section: Library + +Deprecate ``smtpd.MailmanProxy`` ready for future removal. + +.. + +.. bpo: 35168 +.. date: 2019-01-22-09-23-20 +.. nonce: UGv2yW +.. section: Library + +:attr:`shlex.shlex.punctuation_chars` is now a read-only property. + +.. + +.. bpo: 8538 +.. date: 2019-01-09-16-18-52 +.. nonce: PfVZia +.. section: Library + +Add support for boolean actions like ``--foo`` and ``--no-foo`` to argparse. +Patch contributed by Rémi Lapeyre. + +.. + +.. bpo: 20504 +.. date: 2018-11-21-18-05-50 +.. nonce: kG0ub5 +.. section: Library + +Fixes a bug in :mod:`cgi` module when a multipart/form-data request has no +`Content-Length` header. + +.. + +.. bpo: 25988 +.. date: 2018-11-19-10-23-58 +.. nonce: 6o7gGK +.. section: Library + +The abstract base classes in :mod:`collections.abc` no longer are exposed in +the regular :mod:`collections` module. + +.. + +.. bpo: 11122 +.. date: 2018-11-12-19-08-50 +.. nonce: Gj7BQn +.. section: Library + +Distutils won't check for rpmbuild in specified paths only. + +.. + +.. bpo: 34775 +.. date: 2018-09-23-03-18-52 +.. nonce: vHeuHk +.. section: Library + +Division handling of PurePath now returns NotImplemented instead of raising +a TypeError when passed something other than an instance of str or PurePath. +Patch by Roger Aiudi. + +.. + +.. bpo: 34749 +.. date: 2018-09-21-13-23-29 +.. nonce: B0k819 +.. section: Library + +:func:`binascii.a2b_base64` is now up to 2 times faster. Patch by Sergey +Fedoseev. + +.. + +.. bpo: 34519 +.. date: 2018-08-27-15-44-50 +.. nonce: cPlH1h +.. section: Library + +Add additional aliases for HP Roman 8. Patch by Michael Osipov. + +.. + +.. bpo: 28009 +.. date: 2018-08-04-12-26-11 +.. nonce: 4JcHZb +.. section: Library + +Fix uuid.getnode() on platforms with '.' as MAC Addr delimiter as well fix +for MAC Addr format that omits a leading 0 in MAC Addr values. Currently, +AIX is the only know platform with these settings. Patch by Michael Felt. + +.. + +.. bpo: 30618 +.. date: 2018-07-14-13-48-56 +.. nonce: T5AUF6 +.. section: Library + +Add :meth:`~pathlib.Path.readlink`. Patch by Girts Folkmanis. + +.. + +.. bpo: 32498 +.. date: 2018-06-17-21-02-25 +.. nonce: La3TZz +.. section: Library + +Made :func:`urllib.parse.unquote()` accept bytes in addition to strings. +Patch by Stein Karlsen. + +.. + +.. bpo: 33348 +.. date: 2018-04-24-13-18-48 +.. nonce: XaJDei +.. section: Library + +lib2to3 now recognizes expressions after ``*`` and `**` like in ``f(*[] or +[])``. + +.. + +.. bpo: 32689 +.. date: 2018-02-13-17-58-30 +.. nonce: a-3SnH +.. section: Library + +Update :func:`shutil.move` function to allow for Path objects to be used as +source argument. Patch by Emily Morehouse and Maxwell "5.13b" McKinnon. + +.. + +.. bpo: 32820 +.. date: 2018-02-13-12-25-43 +.. nonce: 0stF0u +.. section: Library + +Added __format__ to IPv4 and IPv6 classes. Always outputs a fully zero- +padded string. Supports b/x/n modifiers (bin/hex/native format). Native +format for IPv4 is bin, native format for IPv6 is hex. Also supports '#' and +'_' modifiers. + +.. + +.. bpo: 27657 +.. date: 2017-12-26-14-32-23 +.. nonce: 6BhyVK +.. section: Library + +Fix urllib.parse.urlparse() with numeric paths. A string like "path:80" is +no longer parsed as a path but as a scheme ("path") and a path ("80"). + +.. + +.. bpo: 4963 +.. date: 2017-08-15-11-24-41 +.. nonce: LRYres +.. section: Library + +Fixed non-deterministic behavior related to mimetypes extension mapping and +module reinitialization. + +.. + +.. bpo: 21767 +.. date: 2019-11-17-11-54-57 +.. nonce: Qq3Dos +.. section: Documentation + +Explicitly mention abc support in functools.singledispatch + +.. + +.. bpo: 38816 +.. date: 2019-11-15-11-39-13 +.. nonce: vUaSVL +.. section: Documentation + +Provides more details about the interaction between :c:func:`fork` and +CPython's runtime, focusing just on the C-API. This includes cautions about +where :c:func:`fork` should and shouldn't be called. + +.. + +.. bpo: 38351 +.. date: 2019-11-15-09-22-28 +.. nonce: xwhlse +.. section: Documentation + +Modernize :mod:`email` examples from %-formatting to f-strings. + +.. + +.. bpo: 38778 +.. date: 2019-11-12-15-31-09 +.. nonce: PHhTlv +.. section: Documentation + +Document the fact that :exc:`RuntimeError` is raised if :meth:`os.fork` is +called in a subinterpreter. + +.. + +.. bpo: 38592 +.. date: 2019-10-26-13-19-07 +.. nonce: Y96BYO +.. section: Documentation + +Add Brazilian Portuguese to the language switcher at Python Documentation +website. + +.. + +.. bpo: 38294 +.. date: 2019-09-27-23-37-41 +.. nonce: go_jFf +.. section: Documentation + +Add list of no-longer-escaped chars to re.escape documentation + +.. + +.. bpo: 38053 +.. date: 2019-09-07-19-09-01 +.. nonce: lttibE +.. section: Documentation + +Modernized the plistlib documentation + +.. + +.. bpo: 26868 +.. date: 2019-09-07-15-55-46 +.. nonce: Raw0Gd +.. section: Documentation + +Fix example usage of :c:func:`PyModule_AddObject` to properly handle errors. + +.. + +.. bpo: 36797 +.. date: 2019-09-05-14-47-51 +.. nonce: KN9Ga5 +.. section: Documentation + +Fix a dead link in the distutils API Reference. + +.. + +.. bpo: 37977 +.. date: 2019-08-29-14-38-01 +.. nonce: pML-UI +.. section: Documentation + +Warn more strongly and clearly about pickle insecurity + +.. + +.. bpo: 37979 +.. date: 2019-08-29-10-40-05 +.. nonce: TAUx_E +.. section: Documentation + +Added a link to dateutil.parser.isoparse in the datetime.fromisoformat +documentation. Patch by Paul Ganssle + +.. + +.. bpo: 12707 +.. date: 2019-08-27-01-14-59 +.. nonce: Yj3_7_ +.. section: Documentation + +Deprecate info(), geturl(), getcode() methods in favor of the headers, url, +and status properties, respectively, for HTTPResponse and addinfourl. Also +deprecate the code attribute of addinfourl in favor of the status attribute. +Patch by Ashwin Ramaswami + +.. + +.. bpo: 37937 +.. date: 2019-08-24-12-59-06 +.. nonce: F7fHbt +.. section: Documentation + +Mention ``frame.f_trace`` in :func:`sys.settrace` docs. + +.. + +.. bpo: 37878 +.. date: 2019-08-16-20-01-10 +.. nonce: MvA6rZ +.. section: Documentation + +Make :c:func:`PyThreadState_DeleteCurrent` Internal. + +.. + +.. bpo: 37759 +.. date: 2019-08-04-19-20-58 +.. nonce: EHRF4i +.. section: Documentation + +Beginning edits to Whatsnew 3.8 + +.. + +.. bpo: 37726 +.. date: 2019-07-31-11-40-06 +.. nonce: h-3o9a +.. section: Documentation + +Stop recommending getopt in the tutorial for command line argument parsing +and promote argparse. + +.. + +.. bpo: 32910 +.. date: 2019-07-25-10-30-32 +.. nonce: caLLAe +.. section: Documentation + +Remove implementation-specific behaviour of how venv's Deactivate works. + +.. + +.. bpo: 37256 +.. date: 2019-07-16-14-48-12 +.. nonce: qJTrBb +.. section: Documentation + +Fix wording of arguments for :class:`Request` in :mod:`urllib.request` + +.. + +.. bpo: 37284 +.. date: 2019-07-13-12-58-20 +.. nonce: rP8WpB +.. section: Documentation + +Add a brief note to indicate that any new ``sys.implementation`` required +attributes must go through the PEP process. + +.. + +.. bpo: 30088 +.. date: 2019-07-13-12-43-01 +.. nonce: CIcBjy +.. section: Documentation + +Documented that :class:`mailbox.Maildir` constructor doesn't attempt to +verify the maildir folder layout correctness. Patch by Sviatoslav Sydorenko. + +.. + +.. bpo: 37521 +.. date: 2019-07-12-15-09-56 +.. nonce: 7tiFR- +.. section: Documentation + +Fix `importlib` examples to insert any newly created modules via +importlib.util.module_from_spec() immediately into sys.modules instead of +after calling loader.exec_module(). + +Thanks to Benjamin Mintz for finding the bug. + +.. + +.. bpo: 37456 +.. date: 2019-07-06-17-51-36 +.. nonce: lgAQHn +.. section: Documentation + +Slash ('/') is now part of syntax. + +.. + +.. bpo: 37487 +.. date: 2019-07-06-17-19-26 +.. nonce: QagfZ5 +.. section: Documentation + +Fix PyList_GetItem index description to include 0. + +.. + +.. bpo: 37149 +.. date: 2019-07-06-02-19-02 +.. nonce: NumHn3 +.. section: Documentation + +Replace the dead link to the Tkinter 8.5 reference by John Shipman, New +Mexico Tech, with a link to the archive.org copy. + +.. + +.. bpo: 37478 +.. date: 2019-07-06-00-57-27 +.. nonce: B0ioLw +.. section: Documentation + +Added possible exceptions to the description of os.chdir(). + +.. + +.. bpo: 34903 +.. date: 2019-06-17-09-36-46 +.. nonce: r_wGRc +.. section: Documentation + +Documented that in :meth:`datetime.datetime.strptime()`, the leading zero in +some two-digit formats is optional. Patch by Mike Gleen. + +.. + +.. bpo: 36260 +.. date: 2019-06-04-09-29-00 +.. nonce: WrGuc- +.. section: Documentation + +Add decompression pitfalls to zipfile module documentation. + +.. + +.. bpo: 37004 +.. date: 2019-05-22-04-30-07 +.. nonce: BRgxrt +.. section: Documentation + +In the documentation for difflib, a note was added explicitly warning that +the results of SequenceMatcher's ratio method may depend on the order of the +input strings. + +.. + +.. bpo: 36960 +.. date: 2019-05-18-16-25-44 +.. nonce: xEKHXj +.. section: Documentation + +Restructured the :mod:`datetime` docs in the interest of making them more +user-friendly and improving readability. Patch by Brad Solomon. + +.. + +.. bpo: 36487 +.. date: 2019-04-02-19-23-00 +.. nonce: Jg6-MG +.. section: Documentation + +Make C-API docs clear about what the "main" interpreter is. + +.. + +.. bpo: 23460 +.. date: 2019-02-14-07-12-48 +.. nonce: Iqiqtm +.. section: Documentation + +The documentation for decimal string formatting using the `:g` specifier has +been updated to reflect the correct exponential notation cutoff point. +Original patch contributed by Tuomas Suutari. + +.. + +.. bpo: 35803 +.. date: 2019-01-21-14-30-59 +.. nonce: yae6Lq +.. section: Documentation + +Document and test that ``tempfile`` functions may accept a :term:`path-like +object` for the ``dir`` argument. Patch by Anthony Sottile. + +.. + +.. bpo: 33944 +.. date: 2018-10-26-18-10-29 +.. nonce: V1YeOA +.. section: Documentation + +Added a note about the intended use of code in .pth files. + +.. + +.. bpo: 34293 +.. date: 2018-07-31-15-38-26 +.. nonce: yHupAL +.. section: Documentation + +Fix the Doc/Makefile regarding PAPER environment variable and PDF builds + +.. + +.. bpo: 25237 +.. date: 2018-06-02-12-55-23 +.. nonce: m8-JMu +.. section: Documentation + +Add documentation for tkinter modules + +.. + +.. bpo: 38614 +.. date: 2019-10-30-15-12-32 +.. nonce: M6UnLB +.. section: Tests + +Fix test_communicate() of test_asyncio.test_subprocess: use +``support.LONG_TIMEOUT`` (5 minutes), instead of just 1 minute. + +.. + +.. bpo: 38614 +.. date: 2019-10-28-15-56-02 +.. nonce: aDdDYE +.. section: Tests + +Add timeout constants to :mod:`test.support`: +:data:`~test.support.LOOPBACK_TIMEOUT`, +:data:`~test.support.INTERNET_TIMEOUT`, :data:`~test.support.SHORT_TIMEOUT` +and :data:`~test.support.LONG_TIMEOUT`. + +.. + +.. bpo: 38502 +.. date: 2019-10-17-00-49-38 +.. nonce: vUEic7 +.. section: Tests + +test.regrtest now uses process groups in the multiprocessing mode (-jN +command line option) if process groups are available: if :func:`os.setsid` +and :func:`os.killpg` functions are available. + +.. + +.. bpo: 35998 +.. date: 2019-10-16-01-36-15 +.. nonce: G305Bf +.. section: Tests + +Fix a race condition in test_asyncio.test_start_tls_server_1(). Previously, +there was a race condition between the test main() function which replaces +the protocol and the test ServerProto protocol which sends ANSWER once it +gets HELLO. Now, only the test main() function is responsible to send data, +ServerProto no longer sends data. + +.. + +.. bpo: 38470 +.. date: 2019-10-14-22-46-35 +.. nonce: NHtzpy +.. section: Tests + +Fix ``test_compileall.test_compile_dir_maxlevels()`` on Windows without long +path support: only create 3 subdirectories instead of between 20 and 100 +subdirectories. + +.. + +.. bpo: 37531 +.. date: 2019-10-08-16-42-05 +.. nonce: 7v-_Ca +.. section: Tests + +On timeout, regrtest no longer attempts to call ``popen.communicate()`` +again: it can hang until all child processes using stdout and stderr pipes +completes. Kill the worker process and ignores its output. Change also the +faulthandler timeout of the main process from 1 minute to 5 minutes, for +Python slowest buildbots. + +.. + +.. bpo: 38239 +.. date: 2019-09-26-15-48-36 +.. nonce: MfoVzY +.. section: Tests + +Fix test_gdb for Link Time Optimization (LTO) builds. + +.. + +.. bpo: 38275 +.. date: 2019-09-25-14-40-57 +.. nonce: -kdveI +.. section: Tests + +test_ssl now handles disabled TLS/SSL versions better. OpenSSL's crypto +policy and run-time settings are recognized and tests for disabled versions +are skipped. Tests also accept more TLS minimum_versions for platforms that +override OpenSSL's default with strict settings. + +.. + +.. bpo: 38271 +.. date: 2019-09-25-13-11-29 +.. nonce: iHXNIg +.. section: Tests + +The private keys for test_ssl were encrypted with 3DES in traditional PKCS#5 +format. 3DES and the digest algorithm of PKCS#5 are blocked by some strict +crypto policies. Use PKCS#8 format with AES256 encryption instead. + +.. + +.. bpo: 38270 +.. date: 2019-09-25-12-18-31 +.. nonce: _x-9uH +.. section: Tests + +test.support now has a helper function to check for availability of a hash +digest function. Several tests are refactored avoid MD5 and use SHA256 +instead. Other tests are marked to use MD5 and skipped when MD5 is disabled. + +.. + +.. bpo: 37123 +.. date: 2019-09-24-12-30-55 +.. nonce: IoutBn +.. section: Tests + +Multiprocessing test test_mymanager() now also expects -SIGTERM, not only +exitcode 0. BaseManager._finalize_manager() sends SIGTERM to the manager +process if it takes longer than 1 second to stop, which happens on slow +buildbots. + +.. + +.. bpo: 38212 +.. date: 2019-09-24-12-24-05 +.. nonce: IWbhWz +.. section: Tests + +Multiprocessing tests: increase test_queue_feeder_donot_stop_onexc() timeout +from 1 to 60 seconds. + +.. + +.. bpo: 38117 +.. date: 2019-09-11-17-22-32 +.. nonce: X7LgGY +.. section: Tests + +Test with OpenSSL 1.1.1d + +.. + +.. bpo: 38018 +.. date: 2019-09-03-19-33-10 +.. nonce: zTrMu7 +.. section: Tests + +Increase code coverage for multiprocessing.shared_memory. + +.. + +.. bpo: 37805 +.. date: 2019-08-25-19-51-46 +.. nonce: Kl1sti +.. section: Tests + +Add tests for json.dump(..., skipkeys=True). Patch by Donghee Na. + +.. + +.. bpo: 37531 +.. date: 2019-08-20-19-24-19 +.. nonce: wRoXfU +.. section: Tests + +Enhance regrtest multiprocess timeout: write a message when killing a worker +process, catch popen.kill() and popen.wait() exceptions, put a timeout on +the second call to popen.communicate(). + +.. + +.. bpo: 37876 +.. date: 2019-08-16-16-15-14 +.. nonce: m3k1w3 +.. section: Tests + +Add tests for ROT-13 codec. + +.. + +.. bpo: 36833 +.. date: 2019-07-18-14-52-58 +.. nonce: Zoe9ek +.. section: Tests + +Added tests for :samp:`PyDateTime_{xxx}_GET_{xxx}()` macros of the C API of the +:mod:`datetime` module. Patch by Joannah Nanjekye. + +.. + +.. bpo: 37558 +.. date: 2019-07-11-10-33-56 +.. nonce: SKHRsL +.. section: Tests + +Fix test_shared_memory_cleaned_after_process_termination name handling + +.. + +.. bpo: 37526 +.. date: 2019-07-09-12-33-18 +.. nonce: vmm5y7 +.. section: Tests + +Add :func:`test.support.catch_threading_exception`: context manager catching +:class:`threading.Thread` exception using :func:`threading.excepthook`. + +.. + +.. bpo: 37421 +.. date: 2019-07-08-10-11-36 +.. nonce: OY77go +.. section: Tests + +test_concurrent_futures now explicitly stops the ForkServer instance if it's +running. + +.. + +.. bpo: 37421 +.. date: 2019-07-05-14-47-55 +.. nonce: n8o2to +.. section: Tests + +multiprocessing tests now stop the ForkServer instance if it's running: +close the "alive" file descriptor to ask the server to stop and then remove +its UNIX address. + +.. + +.. bpo: 37421 +.. date: 2019-07-03-00-05-28 +.. nonce: ORGRSG +.. section: Tests + +test_distutils.test_build_ext() is now able to remove the temporary +directory on Windows: don't import the newly built C extension ("xx") in the +current process, but test it in a separated process. + +.. + +.. bpo: 37421 +.. date: 2019-07-02-23-29-06 +.. nonce: WEfc5A +.. section: Tests + +test_concurrent_futures now cleans up multiprocessing to remove immediately +temporary directories created by multiprocessing.util.get_temp_dir(). + +.. + +.. bpo: 37421 +.. date: 2019-07-02-23-20-35 +.. nonce: HCkKWz +.. section: Tests + +test_winconsoleio doesn't leak a temporary file anymore: use +tempfile.TemporaryFile() to remove it when the test completes. + +.. + +.. bpo: 37421 +.. date: 2019-07-01-19-57-26 +.. nonce: NFH1f0 +.. section: Tests + +multiprocessing tests now explicitly call ``_run_finalizers()`` to +immediately remove temporary directories created by tests. + +.. + +.. bpo: 37421 +.. date: 2019-07-01-19-56-17 +.. nonce: bOe350 +.. section: Tests + +urllib.request tests now call :func:`~urllib.request.urlcleanup` to remove +temporary files created by ``urlretrieve()`` tests and to clear the +``_opener`` global variable set by ``urlopen()`` and functions calling +indirectly ``urlopen()``. + +.. + +.. bpo: 37472 +.. date: 2019-07-01-17-19-47 +.. nonce: WzkEAx +.. section: Tests + +Remove ``Lib/test/outstanding_bugs.py``. + +.. + +.. bpo: 37199 +.. date: 2019-06-29-23-56-28 +.. nonce: FHDsLf +.. section: Tests + +Fix test failures when IPv6 is unavailable or disabled. + +.. + +.. bpo: 19696 +.. date: 2019-06-29-16-02-21 +.. nonce: 05ijhN +.. section: Tests + +Replace deprecated method "random.choose" with "random.choice" in +"test_pkg_import.py". + +.. + +.. bpo: 37335 +.. date: 2019-06-28-16-37-52 +.. nonce: o5S2hY +.. section: Tests + +Remove no longer necessary code from c locale coercion tests + +.. + +.. bpo: 37421 +.. date: 2019-06-27-00-37-59 +.. nonce: rVJb3x +.. section: Tests + +Fix test_shutil to no longer leak temporary files. + +.. + +.. bpo: 37411 +.. date: 2019-06-26-15-28-45 +.. nonce: 5lGNhM +.. section: Tests + +Fix test_wsgiref.testEnviron() to no longer depend on the environment +variables (don't fail if "X" variable is set). + +.. + +.. bpo: 37400 +.. date: 2019-06-25-16-02-43 +.. nonce: cx_EWv +.. section: Tests + +Fix test_os.test_chown(): use os.getgroups() rather than grp.getgrall() to +get groups. Rename also the test to test_chown_gid(). + +.. + +.. bpo: 37359 +.. date: 2019-06-24-10-47-07 +.. nonce: CkdtyO +.. section: Tests + +Add --cleanup option to python3 -m test to remove ``test_python_*`` +directories of previous failed jobs. Add "make cleantest" to run ``python3 +-m test --cleanup``. + +.. + +.. bpo: 37362 +.. date: 2019-06-21-15-47-33 +.. nonce: D3xppx +.. section: Tests + +test_gdb no longer fails if it gets an "unexpected" message on stderr: it +now ignores stderr. The purpose of test_gdb is to test that python-gdb.py +commands work as expected, not to test gdb. + +.. + +.. bpo: 35998 +.. date: 2019-06-14-17-05-49 +.. nonce: yX82oD +.. section: Tests + +Avoid TimeoutError in test_asyncio: test_start_tls_server_1() + +.. + +.. bpo: 37278 +.. date: 2019-06-14-12-21-47 +.. nonce: z0HUOr +.. section: Tests + +Fix test_asyncio ProactorLoopCtrlC: join the thread to prevent leaking a +running thread and leaking a reference. + +.. + +.. bpo: 37261 +.. date: 2019-06-13-12-19-56 +.. nonce: NuKFVo +.. section: Tests + +Fix :func:`test.support.catch_unraisable_exception`: its __exit__() method +now ignores unraisable exception raised when clearing its ``unraisable`` +attribute. + +.. + +.. bpo: 37069 +.. date: 2019-06-13-00-46-25 +.. nonce: wdktFo +.. section: Tests + +regrtest now uses :func:`sys.unraisablehook` to mark a test as "environment +altered" (ENV_CHANGED) if it emits an "unraisable exception". Moreover, +regrtest logs a warning in this case. + +Use ``python3 -m test --fail-env-changed`` to catch unraisable exceptions in +tests. + +.. + +.. bpo: 37252 +.. date: 2019-06-12-14-30-29 +.. nonce: 4o-uLs +.. section: Tests + +Fix assertions in ``test_close`` and ``test_events_mask_overflow`` devpoll +tests. + +.. + +.. bpo: 37169 +.. date: 2019-06-07-12-23-15 +.. nonce: yfXTFg +.. section: Tests + +Rewrite ``_PyObject_IsFreed()`` unit tests. + +.. + +.. bpo: 37153 +.. date: 2019-06-04-18-30-39 +.. nonce: 711INB +.. section: Tests + +``test_venv.test_multiprocessing()`` now explicitly calls +``pool.terminate()`` to wait until the pool completes. + +.. + +.. bpo: 34001 +.. date: 2019-06-03-20-47-10 +.. nonce: KvYx9z +.. section: Tests + +Make test_ssl pass with LibreSSL. LibreSSL handles minimum and maximum TLS +version differently than OpenSSL. + +.. + +.. bpo: 36919 +.. date: 2019-05-28-15-41-34 +.. nonce: -vGt_m +.. section: Tests + +Make ``test_source_encoding.test_issue2301`` implementation independent. The +test will work now for both CPython and IronPython. + +.. + +.. bpo: 30202 +.. date: 2019-04-15-19-05-35 +.. nonce: Wt7INj +.. section: Tests + +Update ``test.test_importlib.test_abc`` to test ``find_spec()``. + +.. + +.. bpo: 28009 +.. date: 2019-04-11-07-59-43 +.. nonce: s85urF +.. section: Tests + +Modify the test_uuid logic to test when a program is available AND can be +used to obtain a MACADDR as basis for an UUID. Patch by M. Felt + +.. + +.. bpo: 34596 +.. date: 2018-09-07-01-18-27 +.. nonce: r2-EGd +.. section: Tests + +Fallback to a default reason when :func:`unittest.skip` is uncalled. Patch +by Naitree Zhu. + +.. + +.. bpo: 38809 +.. date: 2019-11-15-09-25-44 +.. nonce: 9jwta6 +.. section: Build + +On Windows, build scripts will now recognize and use python.exe from an +active virtual env. + +.. + +.. bpo: 38684 +.. date: 2019-11-04-14-30-37 +.. nonce: aed593 +.. section: Build + +Fix _hashlib build when Blake2 is disabled, but OpenSSL supports it. + +.. + +.. bpo: 38468 +.. date: 2019-10-13-16-18-24 +.. nonce: buCO84 +.. section: Build + +Misc/python-config.in now uses `getvar()` for all still existing +`sysconfig.get_config_var()` calls. Patch by Joannah Nanjekye. + +.. + +.. bpo: 37415 +.. date: 2019-10-11-15-32-58 +.. nonce: D9RXrq +.. section: Build + +Fix stdatomic.h header check for ICC compiler: the ICC implementation lacks +atomic_uintptr_t type which is needed by Python. + +.. + +.. bpo: 38301 +.. date: 2019-09-28-02-37-11 +.. nonce: 123456 +.. section: Build + +In Solaris family, we must be sure to use ``-D_REENTRANT``. Patch by Jesús +Cea Avión. + +.. + +.. bpo: 36002 +.. date: 2019-09-13-14-12-36 +.. nonce: Bcl4oe +.. section: Build + +Locate ``llvm-profdata`` and ``llvm-ar`` binaries using ``AC_PATH_TOOL`` +rather than ``AC_PATH_TARGET_TOOL``. + +.. + +.. bpo: 37936 +.. date: 2019-09-10-00-54-48 +.. nonce: E7XEwu +.. section: Build + +The :file:`.gitignore` file systematically keeps "rooted", with a +non-trailing slash, all the rules that are meant to apply to files in a +specific place in the repo. Previously, when the intended file to ignore +happened to be at the root of the repo, we'd most often accidentally also +ignore files and directories with the same name anywhere in the tree. + +.. + +.. bpo: 37760 +.. date: 2019-08-24-17-39-09 +.. nonce: f3jXuH +.. section: Build + +The :file:`Tools/unicode/makeunicodedata.py` script, which is used for +converting information from the Unicode Character Database into generated +code and data used by the methods of :class:`str` and by the +:mod:`unicodedata` module, now handles each character's data as a +``dataclass`` with named attributes, rather than a length-18 list of +different fields. + +.. + +.. bpo: 37936 +.. date: 2019-08-24-00-29-40 +.. nonce: QrORqA +.. section: Build + +The :file:`.gitignore` file no longer applies to any files that are in fact +tracked in the Git repository. Patch by Greg Price. + +.. + +.. bpo: 37725 +.. date: 2019-07-30-16-26-11 +.. nonce: MkG1TT +.. section: Build + +Change "clean" makefile target to also clean the program guided optimization +(PGO) data. Previously you would have to use "make clean" and "make +profile-removal", or "make clobber". + +.. + +.. bpo: 37707 +.. date: 2019-07-29-11-36-16 +.. nonce: Sm-dGk +.. section: Build + +Mark some individual tests to skip when --pgo is used. The tests marked +increase the PGO task time significantly and likely don't help improve +optimization of the final executable. + +.. + +.. bpo: 36044 +.. date: 2019-07-11-01-28-24 +.. nonce: gIgfiJ +.. section: Build + +Reduce the number of unit tests run for the PGO generation task. This +speeds up the task by a factor of about 15x. Running the full unit test +suite is slow. This change may result in a slightly less optimized build +since not as many code branches will be executed. If you are willing to +wait for the much slower build, the old behavior can be restored using +'./configure [..] PROFILE_TASK="-m test --pgo-extended"'. We make no +guarantees as to which PGO task set produces a faster build. Users who care +should run their own relevant benchmarks as results can depend on the +environment, workload, and compiler tool chain. + +.. + +.. bpo: 37468 +.. date: 2019-07-01-14-39-40 +.. nonce: trbQ-_ +.. section: Build + +``make install`` no longer installs ``wininst-*.exe`` files used by +distutils bdist_wininst: bdist_wininst only works on Windows. + +.. + +.. bpo: 37189 +.. date: 2019-06-17-09-40-59 +.. nonce: j5ebdT +.. section: Build + +Many :samp:`PyRun_{XXX}()` functions like :c:func:`PyRun_String` were no longer +exported in ``libpython38.dll`` by mistake. Export them again to fix the ABI +compatibility. + +.. + +.. bpo: 25361 +.. date: 2019-03-19-22-07-37 +.. nonce: XO9Bfr +.. section: Build + +Enables use of SSE2 instructions in Windows 32-bit build. + +.. + +.. bpo: 36210 +.. date: 2019-03-06-18-55-10 +.. nonce: fup9H2 +.. section: Build + +Update optional extension module detection for AIX. ossaudiodev and spwd are +not applicable for AIX, and are no longer reported as missing. 3rd-party +packaging of ncurses (with ASIS support) conflicts with officially supported +AIX curses library, so configure AIX to use libcurses.a. However, skip +trying to build _curses_panel. + +patch by M Felt + +.. + +.. bpo: 38589 +.. date: 2019-10-28-10-48-16 +.. nonce: V69Q1a +.. section: Windows + +Fixes HTML Help shortcut when Windows is not installed to C drive + +.. + +.. bpo: 38453 +.. date: 2019-10-28-10-32-43 +.. nonce: NwwatW +.. section: Windows + +Ensure ntpath.realpath() correctly resolves relative paths. + +.. + +.. bpo: 38519 +.. date: 2019-10-28-05-01-29 +.. nonce: dCkY66 +.. section: Windows + +Restores the internal C headers that were missing from the nuget.org and +Microsoft Store packages. + +.. + +.. bpo: 38492 +.. date: 2019-10-16-09-49-09 +.. nonce: Te1LxC +.. section: Windows + +Remove ``pythonw.exe`` dependency on the Microsoft C++ runtime. + +.. + +.. bpo: 38344 +.. date: 2019-10-05-05-50-58 +.. nonce: scr2LO +.. section: Windows + +Fix error message in activate.bat + +.. + +.. bpo: 38359 +.. date: 2019-10-03-08-04-14 +.. nonce: wzwsl_ +.. section: Windows + +Ensures ``pyw.exe`` launcher reads correct registry key. + +.. + +.. bpo: 38355 +.. date: 2019-10-02-15-38-49 +.. nonce: n3AWX6 +.. section: Windows + +Fixes ``ntpath.realpath`` failing on ``sys.executable``. + +.. + +.. bpo: 38117 +.. date: 2019-09-16-14-07-11 +.. nonce: hJVf0C +.. section: Windows + +Update bundled OpenSSL to 1.1.1d + +.. + +.. bpo: 38092 +.. date: 2019-09-13-14-11-42 +.. nonce: x31ehI +.. section: Windows + +Reduce overhead when using multiprocessing in a Windows virtual environment. + +.. + +.. bpo: 38133 +.. date: 2019-09-12-12-05-55 +.. nonce: yFeRGS +.. section: Windows + +Allow py.exe launcher to locate installations from the Microsoft Store and +improve display of active virtual environments. + +.. + +.. bpo: 38114 +.. date: 2019-09-11-15-24-04 +.. nonce: cc0E5E +.. section: Windows + +The ``pip.ini`` is no longer included in the Nuget package. + +.. + +.. bpo: 32592 +.. date: 2019-09-11-14-51-56 +.. nonce: jvQMD9 +.. section: Windows + +Set Windows 8 as the minimum required version for API support + +.. + +.. bpo: 36634 +.. date: 2019-09-11-14-42-04 +.. nonce: 8Un8ih +.. section: Windows + +:func:`os.cpu_count` now returns active processors rather than maximum +processors. + +.. + +.. bpo: 36634 +.. date: 2019-09-11-12-34-31 +.. nonce: xLaGgb +.. section: Windows + +venv activate.bat now works when the existing variables contain double quote +characters. + +.. + +.. bpo: 38081 +.. date: 2019-09-11-10-22-01 +.. nonce: 8JhzjD +.. section: Windows + +Prevent error calling :func:`os.path.realpath` on ``'NUL'``. + +.. + +.. bpo: 38087 +.. date: 2019-09-10-14-21-40 +.. nonce: --eIib +.. section: Windows + +Fix case sensitivity in test_pathlib and test_ntpath. + +.. + +.. bpo: 38088 +.. date: 2019-09-10-14-17-25 +.. nonce: FOvWSM +.. section: Windows + +Fixes distutils not finding vcruntime140.dll with only the v142 toolset +installed. + +.. + +.. bpo: 37283 +.. date: 2019-09-09-12-22-23 +.. nonce: 8NvOkU +.. section: Windows + +Ensure command-line and unattend.xml setting override previously detected +states in Windows installer. + +.. + +.. bpo: 38030 +.. date: 2019-09-04-14-01-08 +.. nonce: _USdtk +.. section: Windows + +Fixes :func:`os.stat` failing for block devices on Windows + +.. + +.. bpo: 38020 +.. date: 2019-09-03-11-47-37 +.. nonce: xFZ2j0 +.. section: Windows + +Fixes potential crash when calling :func:`os.readlink` (or indirectly +through :func:`~os.path.realpath`) on a file that is not a supported link. + +.. + +.. bpo: 37705 +.. date: 2019-08-30-15-15-22 +.. nonce: 2o4NWW +.. section: Windows + +Improve the implementation of ``winerror_to_errno()``. + +.. + +.. bpo: 37549 +.. date: 2019-08-22-09-04-44 +.. nonce: TpKI3M +.. section: Windows + +:func:`os.dup` no longer fails for standard streams on Windows 7. + +.. + +.. bpo: 1311 +.. date: 2019-08-21-12-58-18 +.. nonce: BoW1wU +.. section: Windows + +The ``nul`` file on Windows now returns True from :func:`~os.path.exists` +and a valid result from :func:`os.stat` with ``S_IFCHR`` set. + +.. + +.. bpo: 9949 +.. date: 2019-08-14-13-40-15 +.. nonce: zW45Ks +.. section: Windows + +Enable support for following symlinks in :func:`os.realpath`. + +.. + +.. bpo: 37834 +.. date: 2019-08-12-12-00-24 +.. nonce: VB2QVj +.. section: Windows + +Treat all name surrogate reparse points on Windows in :func:`os.lstat` and +other reparse points as regular files in :func:`os.stat`. + +.. + +.. bpo: 36266 +.. date: 2019-08-08-18-05-27 +.. nonce: x4eZU3 +.. section: Windows + +Add the module name in the formatted error message when DLL load fail +happens during module import in ``_PyImport_FindSharedFuncptrWindows()``. +Patch by Srinivas Nyayapati. + +.. + +.. bpo: 25172 +.. date: 2019-08-06-18-09-18 +.. nonce: Akreij +.. section: Windows + +Trying to import the :mod:`crypt` module on Windows will result in an +:exc:`ImportError` with a message explaining that the module isn't supported +on Windows. On other platforms, if the underlying ``_crypt`` module is not +available, the ImportError will include a message explaining the problem. + +.. + +.. bpo: 37778 +.. date: 2019-08-06-13-54-12 +.. nonce: AY1XhH +.. section: Windows + +Fixes the icons used for file associations to the Microsoft Store package. + +.. + +.. bpo: 37734 +.. date: 2019-08-06-09-35-12 +.. nonce: EoJ9Nh +.. section: Windows + +Fix use of registry values to launch Python from Microsoft Store app. + +.. + +.. bpo: 37702 +.. date: 2019-07-29-16-49-31 +.. nonce: Lj2f5e +.. section: Windows + +Fix memory leak on Windows in creating an SSLContext object or running +``urllib.request.urlopen('https://...')``. + +.. + +.. bpo: 37672 +.. date: 2019-07-24-14-36-28 +.. nonce: uKEVHN +.. section: Windows + +Switch Windows Store package's pip to use bundled :file:`pip.ini` instead of +:envvar:`PIP_USER` variable. + +.. + +.. bpo: 10945 +.. date: 2019-07-01-12-38-48 +.. nonce: s0YBHG +.. section: Windows + +Officially drop support for creating bdist_wininst installers on non-Windows +systems. + +.. + +.. bpo: 37445 +.. date: 2019-06-28-18-10-29 +.. nonce: LsdYO6 +.. section: Windows + +Include the ``FORMAT_MESSAGE_IGNORE_INSERTS`` flag in ``FormatMessageW()`` +calls. + +.. + +.. bpo: 37369 +.. date: 2019-06-28-09-44-08 +.. nonce: 1iVpxq +.. section: Windows + +Fixes path for :data:`sys.executable` when running from the Microsoft Store. + +.. + +.. bpo: 37380 +.. date: 2019-06-25-04-15-22 +.. nonce: tPxjuz +.. section: Windows + +Don't collect unfinished processes with ``subprocess._active`` on Windows to +cleanup later. Patch by Ruslan Kuprieiev. + +.. + +.. bpo: 37351 +.. date: 2019-06-20-12-50-32 +.. nonce: asTnVW +.. section: Windows + +Removes libpython38.a from standard Windows distribution. + +.. + +.. bpo: 35360 +.. date: 2019-06-18-09-05-08 +.. nonce: tdqSmo +.. section: Windows + +Update Windows builds to use SQLite 3.28.0. + +.. + +.. bpo: 37267 +.. date: 2019-06-13-04-15-51 +.. nonce: Ygo5ef +.. section: Windows + +On Windows, :func:`os.dup` no longer creates an inheritable fd when handling +a character file. + +.. + +.. bpo: 36779 +.. date: 2019-06-11-15-41-34 +.. nonce: 0TMw6f +.. section: Windows + +Ensure ``time.tzname`` is correct on Windows when the active code page is +set to CP_UTF7 or CP_UTF8. + +.. + +.. bpo: 32587 +.. date: 2019-05-10-15-25-44 +.. nonce: -0g2O3 +.. section: Windows + +Make :const:`winreg.REG_MULTI_SZ` support zero-length strings. + +.. + +.. bpo: 28269 +.. date: 2019-05-05-05-23-34 +.. nonce: -MOHI7 +.. section: Windows + +Replace use of :c:func:`strcasecmp` for the system function +:c:func:`_stricmp`. Patch by Minmin Gong. + +.. + +.. bpo: 36590 +.. date: 2019-04-10-21-13-26 +.. nonce: ZTaKcu +.. section: Windows + +Add native Bluetooth RFCOMM support to socket module. + +.. + +.. bpo: 38117 +.. date: 2019-09-15-21-29-13 +.. nonce: ZLsoAZ +.. section: macOS + +Updated OpenSSL to 1.1.1d in macOS installer. + +.. + +.. bpo: 38089 +.. date: 2019-09-10-14-24-35 +.. nonce: eedgyD +.. section: macOS + +Move Azure Pipelines to latest VM versions and make macOS tests optional + +.. + +.. bpo: 18049 +.. date: 2019-07-13-15-58-18 +.. nonce: MklhQQ +.. section: macOS + +Increase the default stack size of threads from 5MB to 16MB on macOS, to +match the stack size of the main thread. This avoids crashes on deep +recursion in threads. + +.. + +.. bpo: 34602 +.. date: 2019-07-02-01-06-47 +.. nonce: 10d4wl +.. section: macOS + +Avoid test suite failures on macOS by no longer calling resource.setrlimit +to increase the process stack size limit at runtime. The runtime change is +no longer needed since the interpreter is being built with a larger default +stack size. + +.. + +.. bpo: 35360 +.. date: 2019-06-18-08-58-30 +.. nonce: -CWbfy +.. section: macOS + +Update macOS installer to use SQLite 3.28.0. + +.. + +.. bpo: 34631 +.. date: 2019-06-18-00-30-40 +.. nonce: vSifcv +.. section: macOS + +Updated OpenSSL to 1.1.1c in macOS installer. + +.. + +.. bpo: 26353 +.. date: 2019-11-09-23-55-59 +.. nonce: duYZiF +.. section: IDLE + +Stop adding newline when saving an IDLE shell window. + +.. + +.. bpo: 4630 +.. date: 2019-10-28-04-48-03 +.. nonce: upgjiV +.. section: IDLE + +Add an option to toggle IDLE's cursor blink for shell, editor, and output +windows. See Settings, General, Window Preferences, Cursor Blink. Patch by +Zackery Spytz. + +.. + +.. bpo: 38598 +.. date: 2019-10-26-18-16-24 +.. nonce: 6kH9FY +.. section: IDLE + +Do not try to compile IDLE shell or output windows + +.. + +.. bpo: 36698 +.. date: 2019-10-04-18-03-09 +.. nonce: BKcmom +.. section: IDLE + +IDLE no longer fails when write non-encodable characters to stderr. It now +escapes them with a backslash, as the regular Python interpreter. Added the +``errors`` field to the standard streams. + +.. + +.. bpo: 35379 +.. date: 2019-09-17-01-28-56 +.. nonce: yAECDr +.. section: IDLE + +When exiting IDLE, catch any AttributeError. One happens when +EditorWindow.close is called twice. Printing a traceback, when IDLE is run +from a terminal, is useless and annoying. + +.. + +.. bpo: 38183 +.. date: 2019-09-16-15-04-29 +.. nonce: eudCN1 +.. section: IDLE + +To avoid problems, test_idle ignores the user config directory. It no longer +tries to create or access .idlerc or any files within. Users must run IDLE +to discover problems with saving settings. + +.. + +.. bpo: 38077 +.. date: 2019-09-09-22-08-36 +.. nonce: Mzpfe2 +.. section: IDLE + +IDLE no longer adds 'argv' to the user namespace when initializing it. This +bug only affected 3.7.4 and 3.8.0b2 to 3.8.0b4. + +.. + +.. bpo: 38041 +.. date: 2019-09-05-23-12-13 +.. nonce: nxmGGK +.. section: IDLE + +Shell restart lines now fill the window width, always start with '=', and +avoid wrapping unnecessarily. The line will still wrap if the included file +name is long relative to the width. + +.. + +.. bpo: 35771 +.. date: 2019-09-01-10-22-55 +.. nonce: tdbmbP +.. section: IDLE + +To avoid occasional spurious test_idle failures on slower machines, increase +the ``hover_delay`` in test_tooltip. + +.. + +.. bpo: 37824 +.. date: 2019-08-26-00-41-53 +.. nonce: YY5jAI +.. section: IDLE + +Properly handle user input warnings in IDLE shell. Cease turning +SyntaxWarnings into SyntaxErrors. + +.. + +.. bpo: 37929 +.. date: 2019-08-24-22-00-33 +.. nonce: jb7523 +.. section: IDLE + +IDLE Settings dialog now closes properly when there is no shell window. + +.. + +.. bpo: 37902 +.. date: 2019-08-21-16-02-49 +.. nonce: _R_adE +.. section: IDLE + +Add mousewheel scrolling for IDLE module, path, and stack browsers. Patch by +George Zhang. + +.. + +.. bpo: 37849 +.. date: 2019-08-14-09-43-15 +.. nonce: -bcYF3 +.. section: IDLE + +Fixed completions list appearing too high or low when shown above the +current line. + +.. + +.. bpo: 36419 +.. date: 2019-08-04-17-10-01 +.. nonce: TJZqOc +.. section: IDLE + +Refactor IDLE autocomplete and improve testing. + +.. + +.. bpo: 37748 +.. date: 2019-08-04-15-27-50 +.. nonce: 0vf6pg +.. section: IDLE + +Reorder the Run menu. Put the most common choice, Run Module, at the top. + +.. + +.. bpo: 37692 +.. date: 2019-07-27-15-14-20 +.. nonce: TRHGjD +.. section: IDLE + +Improve highlight config sample with example shell interaction and better +labels for shell elements. + +.. + +.. bpo: 37628 +.. date: 2019-07-26-17-51-13 +.. nonce: kX4AUF +.. section: IDLE + +Settings dialog no longer expands with font size. + +.. + +.. bpo: 37627 +.. date: 2019-07-20-23-33-53 +.. nonce: dQhUNB +.. section: IDLE + +Initialize the Customize Run dialog with the command line arguments most +recently entered before. The user can optionally edit before submitting +them. + +.. + +.. bpo: 33610 +.. date: 2019-07-18-10-11-36 +.. nonce: xYqMLg +.. section: IDLE + +Fix code context not showing the correct context when first toggled on. + +.. + +.. bpo: 37530 +.. date: 2019-07-11-00-05-31 +.. nonce: AuyCyD +.. section: IDLE + +Optimize code context to reduce unneeded background activity. Font and +highlight changes now occur along with text changes instead of after a +random delay. + +.. + +.. bpo: 27452 +.. date: 2019-07-03-22-47-44 +.. nonce: nePPLi +.. section: IDLE + +Cleanup ``config.py`` by inlining ``RemoveFile`` and simplifying the +handling of ``file`` in ``CreateConfigHandlers``. + +.. + +.. bpo: 37325 +.. date: 2019-06-18-16-40-05 +.. nonce: GssOf1 +.. section: IDLE + +Fix tab focus traversal order for help source and custom run dialogs. + +.. + +.. bpo: 37321 +.. date: 2019-06-17-16-35-30 +.. nonce: zVTTGS +.. section: IDLE + +Both subprocess connection error messages now refer to the 'Startup failure' +section of the IDLE doc. + +.. + +.. bpo: 17535 +.. date: 2019-06-13-01-07-20 +.. nonce: K8i2St +.. section: IDLE + +Add optional line numbers for IDLE editor windows. Windows open without +line numbers unless set otherwise in the General tab of the configuration +dialog. + +.. + +.. bpo: 26806 +.. date: 2019-06-10-22-48-50 +.. nonce: Zltkum +.. section: IDLE + +To compensate for stack frames added by IDLE and avoid possible problems +with low recursion limits, add 30 to limits in the user code execution +process. Subtract 30 when reporting recursion limits to make this addition +mostly transparent. + +.. + +.. bpo: 37177 +.. date: 2019-06-07-00-17-41 +.. nonce: voU6pQ +.. section: IDLE + +Properly 'attach' search dialogs to their main window so that they behave +like other dialogs and do not get hidden behind their main window. + +.. + +.. bpo: 37039 +.. date: 2019-06-04-23-27-33 +.. nonce: FN_fBf +.. section: IDLE + +Adjust "Zoom Height" to individual screens by momentarily maximizing the +window on first use with a particular screen. Changing screen settings may +invalidate the saved height. While a window is maximized, "Zoom Height" has +no effect. + +.. + +.. bpo: 35763 +.. date: 2019-06-04-20-36-24 +.. nonce: 7XdoWz +.. section: IDLE + +Make calltip reminder about '/' meaning positional-only less obtrusive by +only adding it when there is room on the first line. + +.. + +.. bpo: 5680 +.. date: 2019-06-03-00-39-29 +.. nonce: VCQfOO +.. section: IDLE + +Add 'Run... Customized' to the Run menu to run a module with customized +settings. Any 'command line arguments' entered are added to sys.argv. One +can suppress the normal Shell main module restart. + +.. + +.. bpo: 36390 +.. date: 2019-03-21-08-35-00 +.. nonce: OdDCGk +.. section: IDLE + +Gather Format menu functions into format.py. Combine paragraph.py, +rstrip.py, and format methods from editor.py. + +.. + +.. bpo: 38118 +.. date: 2019-10-08-15-07-52 +.. nonce: pIZD6H +.. section: Tools/Demos + +Update Valgrind suppression file to ignore a false alarm in +:c:func:`PyUnicode_Decode` when using GCC builtin strcmp(). + +.. + +.. bpo: 38347 +.. date: 2019-10-02-09-48-42 +.. nonce: 2Tq5D1 +.. section: Tools/Demos + +pathfix.py: Assume all files that end on '.py' are Python scripts when +working recursively. + +.. + +.. bpo: 37803 +.. date: 2019-09-12-16-15-55 +.. nonce: chEizy +.. section: Tools/Demos + +pdb's ``--help`` and ``--version`` long options now work. + +.. + +.. bpo: 37942 +.. date: 2019-08-24-12-11-30 +.. nonce: 7H8N9a +.. section: Tools/Demos + +Improve ArgumentClinic converter for floats. + +.. + +.. bpo: 37704 +.. date: 2019-07-29-13-59-19 +.. nonce: xxGUz_ +.. section: Tools/Demos + +Remove ``Tools/scripts/h2py.py``: use cffi to access a C API in Python. + +.. + +.. bpo: 37675 +.. date: 2019-07-24-16-20-54 +.. nonce: 951Cvf +.. section: Tools/Demos + +2to3 now works when run from a zipped standard library. + +.. + +.. bpo: 37034 +.. date: 2019-05-27-16-13-08 +.. nonce: zbTgy8 +.. section: Tools/Demos + +Argument Clinic now uses the argument name on errors with keyword-only +argument instead of their position. Patch contributed by Rémi Lapeyre. + +.. + +.. bpo: 37064 +.. date: 2019-05-27-15-26-12 +.. nonce: k_SPW2 +.. section: Tools/Demos + +Add option -k to pathscript.py script: preserve shebang flags. Add option -a +to pathscript.py script: add flags. + +.. + +.. bpo: 37633 +.. date: 2019-11-04-21-10-47 +.. nonce: oOGVdo +.. section: C API + +Re-export some function compatibility wrappers for macros in ``pythonrun.h``. + +.. + +.. bpo: 38644 +.. date: 2019-11-04-17-59-46 +.. nonce: euO_RR +.. section: C API + +Provide :c:func:`Py_EnterRecursiveCall` and :c:func:`Py_LeaveRecursiveCall` +as regular functions for the limited API. Previously, there were defined as +macros, but these macros didn't work with the limited API which cannot +access ``PyThreadState.recursion_depth`` field. Remove +``_Py_CheckRecursionLimit`` from the stable ABI. + +.. + +.. bpo: 38650 +.. date: 2019-10-30-22-03-03 +.. nonce: 0pi8zt +.. section: C API + +The global variable :c:data:`PyStructSequence_UnnamedField` is now a +constant and refers to a constant string. + +.. + +.. bpo: 38540 +.. date: 2019-10-21-09-24-03 +.. nonce: 314N_T +.. section: C API + +Fixed possible leak in :c:func:`PyArg_Parse` and similar functions for +format units ``"es#"`` and ``"et#"`` when the macro +:c:macro:`PY_SSIZE_T_CLEAN` is not defined. + +.. + +.. bpo: 38395 +.. date: 2019-10-08-01-23-24 +.. nonce: MJ6Ey9 +.. section: C API + +Fix a crash in :class:`weakref.proxy` objects due to incorrect lifetime +management when calling some associated methods that may delete the last +reference to object being referenced by the proxy. Patch by Pablo Galindo. + +.. + +.. bpo: 36389 +.. date: 2019-10-07-17-15-09 +.. nonce: hFX_jD +.. section: C API + +The ``_PyObject_CheckConsistency()`` function is now also available in +release mode. For example, it can be used to debug a crash in the +``visit_decref()`` function of the GC. + +.. + +.. bpo: 38266 +.. date: 2019-10-03-12-53-53 +.. nonce: 0FIC1q +.. section: C API + +Revert the removal of PyThreadState_DeleteCurrent() with documentation. + +.. + +.. bpo: 38303 +.. date: 2019-09-30-16-53-30 +.. nonce: YoIs0M +.. section: C API + +Update audioop extension module to use the stable ABI (PEP-384). Patch by +Tyler Kieft. + +.. + +.. bpo: 38234 +.. date: 2019-09-24-17-09-48 +.. nonce: d0bhEA +.. section: C API + +:c:func:`!Py_SetPath` now sets :data:`sys.executable` to the program full +path (:c:func:`Py_GetProgramFullPath`) rather than to the program name +(:c:func:`Py_GetProgramName`). + +.. + +.. bpo: 38234 +.. date: 2019-09-20-17-22-41 +.. nonce: ZbquVK +.. section: C API + +Python ignored arguments passed to :c:func:`!Py_SetPath`, +:c:func:`!Py_SetPythonHome` and :c:func:`!Py_SetProgramName`: fix Python +initialization to use specified arguments. + +.. + +.. bpo: 38205 +.. date: 2019-09-19-18-26-29 +.. nonce: Db1OJL +.. section: C API + +The :c:func:`Py_UNREACHABLE` macro now calls :c:func:`Py_FatalError`. + +.. + +.. bpo: 38140 +.. date: 2019-09-13-01-24-47 +.. nonce: y59qaO +.. section: C API + +Make dict and weakref offsets opaque for C heap types by passing the offsets +through PyMemberDef + +.. + +.. bpo: 15088 +.. date: 2019-09-05-14-17-21 +.. nonce: plt8Em +.. section: C API + +The C function ``PyGen_NeedsFinalizing`` has been removed. It was not +documented, tested or used anywhere within CPython after the implementation +of :pep:`442`. Patch by Joannah Nanjekye. (Patch by Joannah Nanjekye) + +.. + +.. bpo: 36763 +.. date: 2019-08-23-18-45-11 +.. nonce: q3Kh8Z +.. section: C API + +Options added by ``PySys_AddXOption()`` are now handled the same way than +``PyConfig.xoptions`` and command line ``-X`` options. + +.. + +.. bpo: 37926 +.. date: 2019-08-23-11-35-55 +.. nonce: hnI5IQ +.. section: C API + +Fix a crash in ``PySys_SetArgvEx(0, NULL, 0)``. + +.. + +.. bpo: 37879 +.. date: 2019-08-17-13-50-21 +.. nonce: CZeUem +.. section: C API + +Fix subtype_dealloc to suppress the type decref when the base type is a C +heap type + +.. + +.. bpo: 37645 +.. date: 2019-07-21-21-08-47 +.. nonce: 4DcUaI +.. section: C API + +Add :c:func:`_PyObject_FunctionStr` to get a user-friendly string +representation of a function-like object. Patch by Jeroen Demeyer. + +.. + +.. bpo: 29548 +.. date: 2019-07-17-09-50-50 +.. nonce: 5wIptQ +.. section: C API + +The functions ``PyEval_CallObject``, ``PyEval_CallFunction``, +``PyEval_CallMethod`` and ``PyEval_CallObjectWithKeywords`` are deprecated. +Use :c:func:`PyObject_Call` and its variants instead. + +.. + +.. bpo: 37151 +.. date: 2019-07-16-11-02-00 +.. nonce: YKfuNA +.. section: C API + +``PyCFunction_Call`` is now a deprecated alias of :c:func:`PyObject_Call`. + +.. + +.. bpo: 37540 +.. date: 2019-07-10-12-27-28 +.. nonce: E8Z773 +.. section: C API + +The vectorcall protocol now requires that the caller passes only strings as +keyword names. + +.. + +.. bpo: 37207 +.. date: 2019-07-07-10-37-07 +.. nonce: SlVNky +.. section: C API + +The vectorcall protocol is now enabled for ``type`` objects: set +``tp_vectorcall`` to a vectorcall function to be used instead of ``tp_new`` +and ``tp_init`` when calling the class itself. + +.. + +.. bpo: 21120 +.. date: 2019-07-06-23-56-47 +.. nonce: lXHqlT +.. section: C API + +Exclude Python-ast.h, ast.h and asdl.h from the limited API. + +.. + +.. bpo: 37483 +.. date: 2019-07-02-15-42-37 +.. nonce: vftT4f +.. section: C API + +Add new function ``_PyObject_CallOneArg`` for calling an object with one +positional argument. + +.. + +.. bpo: 36763 +.. date: 2019-06-28-15-49-16 +.. nonce: zrmgki +.. section: C API + +Add :c:func:`PyConfig_SetWideStringList` function. + +.. + +.. bpo: 37337 +.. date: 2019-06-19-12-06-31 +.. nonce: gXIGyU +.. section: C API + +Add fast functions for calling methods: +:c:func:`_PyObject_VectorcallMethod`, :c:func:`_PyObject_CallMethodNoArgs` +and :c:func:`_PyObject_CallMethodOneArg`. + +.. + +.. bpo: 28805 +.. date: 2019-06-14-14-03-51 +.. nonce: qZC0N_ +.. section: C API + +The :c:macro:`METH_FASTCALL` calling convention has been documented. + +.. + +.. bpo: 37221 +.. date: 2019-06-11-02-50-38 +.. nonce: 4tClQT +.. section: C API + +The new function :c:func:`PyCode_NewWithPosOnlyArgs` allows to create code +objects like :c:func:`PyCode_New`, but with an extra *posonlyargcount* +parameter for indicating the number of positonal-only arguments. + +.. + +.. bpo: 37215 +.. date: 2019-06-10-15-32-34 +.. nonce: yzoNyU +.. section: C API + +Fix dtrace issue introduce by bpo-36842 + +.. + +.. bpo: 37194 +.. date: 2019-06-07-14-03-52 +.. nonce: uck7MD +.. section: C API + +Add a new public :c:func:`PyObject_CallNoArgs` function to the C API: call a +callable Python object without any arguments. It is the most efficient way +to call a callback without any argument. On x86-64, for example, +``PyObject_CallFunctionObjArgs(func, NULL)`` allocates 960 bytes on the +stack per call, whereas ``PyObject_CallNoArgs(func)`` only allocates 624 +bytes per call. + +.. + +.. bpo: 37170 +.. date: 2019-06-06-08-47-04 +.. nonce: hO_fpM +.. section: C API + +Fix the cast on error in :c:func:`PyLong_AsUnsignedLongLongMask()`. + +.. + +.. bpo: 35381 +.. date: 2019-01-18-17-05-26 +.. nonce: 9CbeW3 +.. section: C API + +Convert posixmodule.c statically allocated types ``DirEntryType`` and +``ScandirIteratorType`` to heap-allocated types. + +.. + +.. bpo: 34331 +.. date: 2018-08-04-00-59-44 +.. nonce: iaUkmU +.. section: C API + +Use singular/plural noun in error message when instantiating an abstract +class with non-overridden abstract method(s). diff --git a/Misc/NEWS.d/3.9.0a2.rst b/Misc/NEWS.d/3.9.0a2.rst new file mode 100644 index 00000000..a03eb10f --- /dev/null +++ b/Misc/NEWS.d/3.9.0a2.rst @@ -0,0 +1,957 @@ +.. bpo: 38945 +.. date: 2019-12-01-22-44-40 +.. nonce: ztmNXc +.. release date: 2019-12-18 +.. section: Security + +Newline characters have been escaped when performing uu encoding to prevent +them from overflowing into to content section of the encoded file. This +prevents malicious or accidental modification of data during the decoding +process. + +.. + +.. bpo: 37228 +.. date: 2019-11-21-21-36-54 +.. nonce: yBZnFG +.. section: Security + +Due to significant security concerns, the *reuse_address* parameter of +:meth:`asyncio.loop.create_datagram_endpoint` is no longer supported. This +is because of the behavior of ``SO_REUSEADDR`` in UDP. For more details, see +the documentation for ``loop.create_datagram_endpoint()``. (Contributed by +Kyle Stanley, Antoine Pitrou, and Yury Selivanov in :issue:`37228`.) + +.. + +.. bpo: 38804 +.. date: 2019-11-15-00-54-42 +.. nonce: vjbM8V +.. section: Security + +Fixes a ReDoS vulnerability in :mod:`http.cookiejar`. Patch by Ben Caller. + +.. + +.. bpo: 39028 +.. date: 2019-12-17-23-20-51 +.. nonce: SND4TB +.. section: Core and Builtins + +Slightly improve the speed of keyword argument parsing with many kwargs by +strengthening the assumption that kwargs are interned strings. + +.. + +.. bpo: 39080 +.. date: 2019-12-17-21-45-36 +.. nonce: OrxEVS +.. section: Core and Builtins + +Fix the value of *end_col_offset* for Starred Expression AST nodes when they +are among the elements in the *args* attribute of Call AST nodes. + +.. + +.. bpo: 39031 +.. date: 2019-12-12-21-05-43 +.. nonce: imlCYZ +.. section: Core and Builtins + +When parsing an "elif" node, lineno and col_offset of the node now point to +the "elif" keyword and not to its condition, making it consistent with the +"if" node. Patch by Lysandros Nikolaou. + +.. + +.. bpo: 20443 +.. date: 2019-12-09-17-05-53 +.. nonce: 8OyT5P +.. section: Core and Builtins + +In Python 3.9.0a1, sys.argv[0] was made an absolute path if a filename was +specified on the command line. Revert this change, since most users expect +sys.argv to be unmodified. + +.. + +.. bpo: 39008 +.. date: 2019-12-09-10-38-51 +.. nonce: Rrp6f1 +.. section: Core and Builtins + +:c:func:`PySys_Audit` now requires ``Py_ssize_t`` to be used for size +arguments in the format string, regardless of whether ``PY_SSIZE_T_CLEAN`` +was defined at include time. + +.. + +.. bpo: 38673 +.. date: 2019-12-01-00-17-44 +.. nonce: K_Tze- +.. section: Core and Builtins + +In REPL mode, don't switch to PS2 if the line starts with comment or +whitespace. Based on work by Batuhan Taşkaya. + +.. + +.. bpo: 38922 +.. date: 2019-11-26-12-20-34 +.. nonce: i6ja-i +.. section: Core and Builtins + +Calling ``replace`` on a code object now raises the ``code.__new__`` audit +event. + +.. + +.. bpo: 38920 +.. date: 2019-11-26-09-16-47 +.. nonce: Vx__sT +.. section: Core and Builtins + +Add audit hooks for when :func:`sys.excepthook` and +:func:`sys.unraisablehook` are invoked. + +.. + +.. bpo: 38892 +.. date: 2019-11-22-22-18-50 +.. nonce: LS586s +.. section: Core and Builtins + +Improve documentation for audit events table and functions. + +.. + +.. bpo: 38852 +.. date: 2019-11-22-09-55-21 +.. nonce: y7oPEa +.. section: Core and Builtins + +Set the thread stack size to 8 Mb for debug builds on android platforms. + +.. + +.. bpo: 38858 +.. date: 2019-11-21-09-02-49 +.. nonce: bDLH04 +.. section: Core and Builtins + +Each Python subinterpreter now has its own "small integer singletons": +numbers in [-5; 257] range. It is no longer possible to change the number of +small integers at build time by overriding ``NSMALLNEGINTS`` and +``NSMALLPOSINTS`` macros: macros should now be modified manually in +``pycore_pystate.h`` header file. + +.. + +.. bpo: 36854 +.. date: 2019-11-20-12-01-37 +.. nonce: Zga_md +.. section: Core and Builtins + +The garbage collector state becomes per interpreter +(``PyInterpreterState.gc``), rather than being global +(``_PyRuntimeState.gc``). + +.. + +.. bpo: 38835 +.. date: 2019-11-18-16-37-49 +.. nonce: -U4se1 +.. section: Core and Builtins + +The ``PyFPE_START_PROTECT()`` and ``PyFPE_END_PROTECT()`` macros are empty: +they have been doing nothing for the last year, so stop using them. + +.. + +.. bpo: 38328 +.. date: 2019-11-11-23-44-15 +.. nonce: IFrrjq +.. section: Core and Builtins + +Sped up the creation time of constant :class:`list` and :class:`set` +displays. Patch by Brandt Bucher. + +.. + +.. bpo: 38707 +.. date: 2019-11-08-00-36-10 +.. nonce: SZL036 +.. section: Core and Builtins + +``MainThread.native_id`` is now correctly reset in child processes spawned +using :class:`multiprocessing.Process`, instead of retaining the parent's +value. + +.. + +.. bpo: 38629 +.. date: 2019-10-29-17-11-15 +.. nonce: 3qinhF +.. section: Core and Builtins + +Added ``__floor__`` and ``__ceil__`` methods to float object. Patch by +Batuhan Taşkaya. + +.. + +.. bpo: 27145 +.. date: 2019-09-06-16-40-12 +.. nonce: njuCXU +.. section: Core and Builtins + +int + int and int - int operators can now return small integer singletons. +Patch by hongweipeng. + +.. + +.. bpo: 38021 +.. date: 2019-09-03-19-16-57 +.. nonce: KnUhdB +.. section: Core and Builtins + +Provide a platform tag for AIX that is sufficient for PEP425 binary +distribution identification. Patch by Michael Felt. + +.. + +.. bpo: 35409 +.. date: 2019-07-13-18-01-13 +.. nonce: ozbcsR +.. section: Core and Builtins + +Ignore GeneratorExit exceptions when throwing an exception into the aclose +coroutine of an asynchronous generator. + +.. + +.. bpo: 33387 +.. date: 2018-03-13-14-46-03 +.. nonce: v821M7 +.. section: Core and Builtins + +Removed WITH_CLEANUP_START, WITH_CLEANUP_FINISH, BEGIN_FINALLY, END_FINALLY, +CALL_FINALLY and POP_FINALLY bytecodes. Replaced with RERAISE and +WITH_EXCEPT_START bytecodes. The compiler now generates different code for +exceptional and non-exceptional branches for 'with' and 'try-except' +statements. For 'try-finally' statements the 'finally' block is replicated +for each exit from the 'try' body. + +.. + +.. bpo: 39033 +.. date: 2019-12-13-18-54-49 +.. nonce: cepuyD +.. section: Library + +Fix :exc:`NameError` in :mod:`zipimport`. Patch by Karthikeyan Singaravelan. + +.. + +.. bpo: 39022 +.. date: 2019-12-10-23-34-48 +.. nonce: QDtIxI +.. section: Library + +Update importlib.metadata to include improvements from importlib_metadata +1.3 including better serialization of EntryPoints and improved documentation +for custom finders. + +.. + +.. bpo: 39006 +.. date: 2019-12-09-14-40-09 +.. nonce: v4VsPg +.. section: Library + +Fix asyncio when the ssl module is missing: only check for ssl.SSLSocket +instance if the ssl module is available. + +.. + +.. bpo: 38708 +.. date: 2019-12-07-22-25-39 +.. nonce: rZTUfk +.. section: Library + +Fix a potential IndexError in email parser when parsing an empty msg-id. + +.. + +.. bpo: 38698 +.. date: 2019-12-07-21-49-50 +.. nonce: HxoSym +.. section: Library + +Add a new ``InvalidMessageID`` token to email parser to represent invalid +Message-ID headers. Also, add defects when there is remaining value after +parsing the header. + +.. + +.. bpo: 38994 +.. date: 2019-12-07-18-58-44 +.. nonce: IJYhz_ +.. section: Library + +Implement ``__class_getitem__`` for ``os.PathLike``, ``pathlib.Path``. + +.. + +.. bpo: 38979 +.. date: 2019-12-07-16-32-42 +.. nonce: q0sIHy +.. section: Library + +Return class from ``ContextVar.__class_getitem__`` to simplify subclassing. + +.. + +.. bpo: 38978 +.. date: 2019-12-07-13-40-52 +.. nonce: R3gHZI +.. section: Library + +Implement ``__class_getitem__`` on asyncio objects (Future, Task, Queue). +Patch by Batuhan Taskaya. + +.. + +.. bpo: 38916 +.. date: 2019-12-06-18-47-56 +.. nonce: K-raU8 +.. section: Library + +:class:`array.array`: Remove ``tostring()`` and ``fromstring()`` methods. +They were aliases to ``tobytes()`` and ``frombytes()``, deprecated since +Python 3.2. + +.. + +.. bpo: 38986 +.. date: 2019-12-06-15-11-42 +.. nonce: bg6iZt +.. section: Library + +Make repr of C accelerated TaskWakeupMethWrapper the same as of pure Python +version. + +.. + +.. bpo: 38982 +.. date: 2019-12-05-18-21-26 +.. nonce: W3u-03 +.. section: Library + +Fix asyncio ``PidfdChildWatcher``: handle ``waitpid()`` error. If +``waitpid()`` is called elsewhere, ``waitpid()`` call fails with +:exc:`ChildProcessError`: use return code 255 in this case, and log a +warning. It ensures that the pidfd file descriptor is closed if this error +occurs. + +.. + +.. bpo: 38529 +.. date: 2019-12-05-16-13-25 +.. nonce: yvQgx3 +.. section: Library + +Drop too noisy asyncio warning about deletion of a stream without explicit +``.close()`` call. + +.. + +.. bpo: 27413 +.. date: 2019-12-05-02-02-58 +.. nonce: 212Th2 +.. section: Library + +Added ability to pass through ``ensure_ascii`` options to json.dumps in the +``json.tool`` command-line interface. + +.. + +.. bpo: 38634 +.. date: 2019-12-04-15-56-28 +.. nonce: pq0ZWa +.. section: Library + +The :mod:`readline` module now detects if Python is linked to libedit at +runtime on all platforms. Previously, the check was only done on macOS. + +.. + +.. bpo: 33684 +.. date: 2019-12-04-15-28-40 +.. nonce: QeSmQP +.. section: Library + +Fix ``json.tool`` failed to read a JSON file with non-ASCII characters when +locale encoding is not UTF-8. + +.. + +.. bpo: 38698 +.. date: 2019-12-02-10-35-19 +.. nonce: WZnAPQ +.. section: Library + +Prevent UnboundLocalError to pop up in parse_message_id. + +parse_message_id() was improperly using a token defined inside an exception +handler, which was raising `UnboundLocalError` on parsing an invalid value. +Patch by Claudiu Popa. + +.. + +.. bpo: 38927 +.. date: 2019-11-27-17-47-00 +.. nonce: qT7xKY +.. section: Library + +Use ``python -m pip`` instead of ``pip`` to upgrade dependencies in venv. + +.. + +.. bpo: 26730 +.. date: 2019-11-27-16-30-02 +.. nonce: 56cdBn +.. section: Library + +Fix ``SpooledTemporaryFile.rollover()`` might corrupt the file when it is in +text mode. Patch by Serhiy Storchaka. + +.. + +.. bpo: 38881 +.. date: 2019-11-22-20-03-46 +.. nonce: 7HV1Q0 +.. section: Library + +random.choices() now raises a ValueError when all the weights are zero. + +.. + +.. bpo: 38876 +.. date: 2019-11-22-10-58-58 +.. nonce: qqy1Vp +.. section: Library + +Raise pickle.UnpicklingError when loading an item from memo for invalid +input. + +The previous code was raising a `KeyError` for both the Python and C +implementation. This was caused by the specified index of an invalid input +which did not exist in the memo structure, where the pickle stores what +objects it has seen. The malformed input would have caused either a `BINGET` +or `LONG_BINGET` load from the memo, leading to a `KeyError` as the +determined index was bogus. Patch by Claudiu Popa + +.. + +.. bpo: 38688 +.. date: 2019-11-22-10-45-03 +.. nonce: iKx23z +.. section: Library + +Calling func:`shutil.copytree` to copy a directory tree from one directory +to another subdirectory resulted in an endless loop and a RecursionError. A +fix was added to consume an iterator and create the list of the entries to +be copied, avoiding the recursion for newly created directories. Patch by +Bruno P. Kinoshita. + +.. + +.. bpo: 38863 +.. date: 2019-11-21-16-30-00 +.. nonce: RkdTjf +.. section: Library + +Improve :func:`is_cgi` function in :mod:`http.server`, which enables +processing the case that cgi directory is a child of another directory other +than root. + +.. + +.. bpo: 37838 +.. date: 2019-11-21-11-39-17 +.. nonce: lRFcEC +.. section: Library + +:meth:`typing.get_type_hints` properly handles functions decorated with +:meth:`functools.wraps`. + +.. + +.. bpo: 38870 +.. date: 2019-11-20-22-43-48 +.. nonce: rLVZEv +.. section: Library + +Expose :func:`ast.unparse` as a function of the :mod:`ast` module that can +be used to unparse an :class:`ast.AST` object and produce a string with code +that would produce an equivalent :class:`ast.AST` object when parsed. Patch +by Pablo Galindo and Batuhan Taskaya. + +.. + +.. bpo: 38859 +.. date: 2019-11-19-16-30-46 +.. nonce: AZUzL8 +.. section: Library + +AsyncMock now returns StopAsyncIteration on the exhaustion of a side_effects +iterable. Since PEP-479 its Impossible to raise a StopIteration exception +from a coroutine. + +.. + +.. bpo: 38857 +.. date: 2019-11-19-16-28-25 +.. nonce: YPUkU9 +.. section: Library + +AsyncMock fix for return values that are awaitable types. This also covers +side_effect iterable values that happened to be awaitable, and wraps +callables that return an awaitable type. Before these awaitables were being +awaited instead of being returned as is. + +.. + +.. bpo: 38834 +.. date: 2019-11-18-17-08-23 +.. nonce: abcdef +.. section: Library + +:class:`typing.TypedDict` subclasses now track which keys are optional using +the ``__required_keys__`` and ``__optional_keys__`` attributes, to enable +runtime validation by downstream projects. Patch by Zac Hatfield-Dodds. + +.. + +.. bpo: 38821 +.. date: 2019-11-16-23-26-25 +.. nonce: -albNN +.. section: Library + +Fix unhandled exceptions in :mod:`argparse` when internationalizing error +messages for arguments with ``nargs`` set to special (non-integer) values. +Patch by Federico Bond. + +.. + +.. bpo: 38820 +.. date: 2019-11-16-16-09-07 +.. nonce: ivhUSV +.. section: Library + +Make Python compatible with OpenSSL 3.0.0. :func:`ssl.SSLSocket.getpeercert` +no longer returns IPv6 addresses with a trailing new line. + +.. + +.. bpo: 38811 +.. date: 2019-11-15-18-06-04 +.. nonce: AmdQ6M +.. section: Library + +Fix an unhandled exception in :mod:`pathlib` when :meth:`os.link` is +missing. Patch by Toke Høiland-Jørgensen. + +.. + +.. bpo: 38686 +.. date: 2019-11-06-15-26-15 +.. nonce: HNFBce +.. section: Library + +Added support for multiple ``qop`` values in +:class:`urllib.request.AbstractDigestAuthHandler`. + +.. + +.. bpo: 38712 +.. date: 2019-11-05-21-10-12 +.. nonce: ezJ0TP +.. section: Library + +Add the Linux-specific :func:`signal.pidfd_send_signal` function, which +allows sending a signal to a process identified by a file descriptor rather +than a pid. + +.. + +.. bpo: 38348 +.. date: 2019-10-02-18-15-28 +.. nonce: _-5eq2 +.. section: Library + +Add ``-i`` and ``--indent`` (indentation level), and ``--no-type-comments`` +(type comments) command line options to ast parsing tool. + +.. + +.. bpo: 37523 +.. date: 2019-10-02-02-55-37 +.. nonce: GguwJ6 +.. section: Library + +Change :class:`zipfile.ZipExtFile` to raise ``ValueError`` when trying to +access the underlying file object after it has been closed. This new +behavior is consistent with how accessing closed files is handled in other +parts of Python. + +.. + +.. bpo: 38045 +.. date: 2019-09-30-12-09-41 +.. nonce: VDRtd3 +.. section: Library + +Improve the performance of :func:`enum._decompose` in :mod:`enum`. Patch by +hongweipeng. + +.. + +.. bpo: 36820 +.. date: 2019-05-06-15-34-17 +.. nonce: Eh5mIB +.. section: Library + +Break cycle generated when saving an exception in socket.py, codeop.py and +dyld.py as they keep alive not only the exception but user objects through +the ``__traceback__`` attribute. Patch by Mario Corchero. + +.. + +.. bpo: 36406 +.. date: 2019-03-24-12-12-27 +.. nonce: mCEkOl +.. section: Library + +Handle namespace packages in :mod:`doctest`. Patch by Karthikeyan +Singaravelan. + +.. + +.. bpo: 34776 +.. date: 2018-09-23-14-24-37 +.. nonce: 1SrQe3 +.. section: Library + +Fix dataclasses to support forward references in type annotations + +.. + +.. bpo: 20928 +.. date: 2018-03-30-16-18-12 +.. nonce: ieXu6I +.. section: Library + +ElementTree supports recursive XInclude processing. Patch by Stefan Behnel. + +.. + +.. bpo: 29636 +.. date: 2018-02-22-11-24-33 +.. nonce: ogGRE2 +.. section: Library + +Add whitespace options for formatting JSON with the ``json.tool`` CLI. The +following mutually exclusive options are now supported: ``--indent`` for +setting the indent level in spaces; ``--tab`` for indenting with tabs; +``--no-indent`` for suppressing newlines; and ``--compact`` for suppressing +all whitespace. The default behavior remains the same as ``--indent=4``. + +.. + +.. bpo: 38928 +.. date: 2019-11-27-17-51-27 +.. nonce: AfgvfO +.. section: Documentation + +Correct when venv's ``upgrade_dependencies()`` and ``--upgrade-deps`` are +added. + +.. + +.. bpo: 38899 +.. date: 2019-11-22-15-57-29 +.. nonce: 4aYPW2 +.. section: Documentation + +Update documentation to state that to activate virtual environments under +fish one should use `source`, not `.` as documented at +https://fishshell.com/docs/current/cmds/source.html. + +.. + +.. bpo: 22377 +.. date: 2019-10-01-10-53-46 +.. nonce: 5ni-iC +.. section: Documentation + +Improves documentation of the values that :meth:`datetime.datetime.strptime` +accepts for ``%Z``. Patch by Karl Dubost. + +.. + +.. bpo: 38546 +.. date: 2019-12-18-14-52-08 +.. nonce: 2kxNuM +.. section: Tests + +Fix test_ressources_gced_in_workers() of test_concurrent_futures: explicitly +stop the manager to prevent leaking a child process running in the +background after the test completes. + +.. + +.. bpo: 38546 +.. date: 2019-12-17-15-27-07 +.. nonce: 82JwN2 +.. section: Tests + +Multiprocessing and concurrent.futures tests now stop the resource tracker +process when tests complete. + +.. + +.. bpo: 38614 +.. date: 2019-12-10-14-26-23 +.. nonce: 89JpNh +.. section: Tests + +Replace hardcoded timeout constants in tests with new :mod:`test.support` +constants: :data:`~test.support.LOOPBACK_TIMEOUT`, +:data:`~test.support.INTERNET_TIMEOUT`, :data:`~test.support.SHORT_TIMEOUT` +and :data:`~test.support.LONG_TIMEOUT`. It becomes easier to adjust these +four timeout constants for all tests at once, rather than having to adjust +every single test file. + +.. + +.. bpo: 38547 +.. date: 2019-12-09-11-32-34 +.. nonce: Juw54e +.. section: Tests + +Fix test_pty: if the process is the session leader, closing the master file +descriptor raises a SIGHUP signal: simply ignore SIGHUP when running the +tests. + +.. + +.. bpo: 38992 +.. date: 2019-12-08-15-11-06 +.. nonce: cVoHOZ +.. section: Tests + +Fix a test for :func:`math.fsum` that was failing due to constant folding. + +.. + +.. bpo: 38991 +.. date: 2019-12-07-00-52-09 +.. nonce: JE3_o- +.. section: Tests + +:mod:`test.support`: :func:`~test.support.run_python_until_end`, +:func:`~test.support.assert_python_ok` and +:func:`~test.support.assert_python_failure` functions no longer strip +whitespaces from stderr. Remove ``test.support.strip_python_stderr()`` +function. + +.. + +.. bpo: 38965 +.. date: 2019-12-04-17-08-55 +.. nonce: yqax3m +.. section: Tests + +Fix test_faulthandler on GCC 10. Use the "volatile" keyword in +``faulthandler._stack_overflow()`` to prevent tail call optimization on any +compiler, rather than relying on compiler specific pragma. + +.. + +.. bpo: 38875 +.. date: 2019-11-21-09-11-06 +.. nonce: wSZJal +.. section: Tests + +test_capi: trashcan tests now require the test "cpu" resource. + +.. + +.. bpo: 38841 +.. date: 2019-11-20-16-08-19 +.. nonce: 5F5Lbw +.. section: Tests + +Skip asyncio test_create_datagram_endpoint_existing_sock_unix on platforms +lacking a functional bind() for named unix domain sockets. + +.. + +.. bpo: 38692 +.. date: 2019-11-20-15-42-06 +.. nonce: aqAvyF +.. section: Tests + +Skip the test_posix.test_pidfd_open() test if ``os.pidfd_open()`` fails with +a :exc:`PermissionError`. This situation can happen in a Linux sandbox using +a syscall whitelist which doesn't allow the ``pidfd_open()`` syscall yet. + +.. + +.. bpo: 38839 +.. date: 2019-11-18-22-10-55 +.. nonce: di6tXv +.. section: Tests + +Fix some unused functions in tests. Patch by Adam Johnson. + +.. + +.. bpo: 38669 +.. date: 2019-11-04-02-54-16 +.. nonce: pazXZ8 +.. section: Tests + +Raise :exc:`TypeError` when passing target as a string with +:meth:`unittest.mock.patch.object`. + +.. + +.. bpo: 37957 +.. date: 2019-10-30-00-01-43 +.. nonce: X1r78F +.. section: Tests + +test.regrtest now can receive a list of test patterns to ignore (using the +-i/--ignore argument) or a file with a list of patterns to ignore (using the +--ignore-file argument). Patch by Pablo Galindo. + +.. + +.. bpo: 37404 +.. date: 2019-12-01-21-45-24 +.. nonce: cNsA7S +.. section: Build + +:mod:`asyncio` now raises :exc:`TyperError` when calling incompatible +methods with an :class:`ssl.SSLSocket` socket. Patch by Ido Michael. + +.. + +.. bpo: 36500 +.. date: 2019-04-02-01-59-26 +.. nonce: fyG6_U +.. section: Build + +Added an optional "regen" project to the Visual Studio solution that will +regenerate all grammar, tokens, and opcodes. + +.. + +.. bpo: 39007 +.. date: 2019-12-09-10-40-34 +.. nonce: vtarxo +.. section: Windows + +Add auditing events to functions in :mod:`winreg`. + +.. + +.. bpo: 33125 +.. date: 2019-11-14-08-57-50 +.. nonce: EN5MWS +.. section: Windows + +Add support for building and releasing Windows ARM64 packages. + +.. + +.. bpo: 37931 +.. date: 2019-08-23-12-14-34 +.. nonce: goYgQj +.. section: macOS + +Fixed a crash on OSX dynamic builds that occurred when re-initializing the +posix module after a Py_Finalize if the environment had changed since the +previous `import posix`. Patch by Benoît Hudson. + +.. + +.. bpo: 38944 +.. date: 2019-11-30-12-10-36 +.. nonce: _3xjKG +.. section: IDLE + +Escape key now closes IDLE completion windows. Patch by Johnny Najera. + +.. + +.. bpo: 38943 +.. date: 2019-11-29-23-44-11 +.. nonce: 8pUKKs +.. section: IDLE + +Fix IDLE autocomplete windows not always appearing on some systems. Patch by +Johnny Najera. + +.. + +.. bpo: 38862 +.. date: 2019-11-23-21-50-57 +.. nonce: KQ9A0m +.. section: IDLE + +'Strip Trailing Whitespace' on the Format menu removes extra newlines at the +end of non-shell files. + +.. + +.. bpo: 38636 +.. date: 2019-10-30-22-11-16 +.. nonce: hUhDeB +.. section: IDLE + +Fix IDLE Format menu tab toggle and file indent width. These functions +(default shortcuts Alt-T and Alt-U) were mistakenly disabled in 3.7.5 and +3.8.0. + +.. + +.. bpo: 38896 +.. date: 2019-11-22-19-43-43 +.. nonce: 6wvNMJ +.. section: C API + +Remove ``PyUnicode_ClearFreeList()`` function: the Unicode free list has +been removed in Python 3.3. + +.. + +.. bpo: 37340 +.. date: 2019-11-20-11-08-06 +.. nonce: JBQJMS +.. section: C API + +Remove ``PyMethod_ClearFreeList()`` and ``PyCFunction_ClearFreeList()`` +functions: the free lists of bound method objects have been removed. + +.. + +.. bpo: 38835 +.. date: 2019-11-18-15-38-23 +.. nonce: II8Szd +.. section: C API + +Exclude ``PyFPE_START_PROTECT()`` and ``PyFPE_END_PROTECT()`` macros of +``pyfpe.h`` from ``Py_LIMITED_API`` (stable API). diff --git a/Misc/NEWS.d/3.9.0a3.rst b/Misc/NEWS.d/3.9.0a3.rst new file mode 100644 index 00000000..a56573dd --- /dev/null +++ b/Misc/NEWS.d/3.9.0a3.rst @@ -0,0 +1,905 @@ +.. bpo: 39427 +.. date: 2020-01-22-22-28-04 +.. nonce: LiO-Eo +.. release date: 2020-01-24 +.. section: Core and Builtins + +Document all possibilities for the ``-X`` options in the command line help +section. Patch by Pablo Galindo. + +.. + +.. bpo: 39421 +.. date: 2020-01-22-15-53-37 +.. nonce: O3nG7u +.. section: Core and Builtins + +Fix possible crashes when operating with the functions in the :mod:`heapq` +module and custom comparison operators. + +.. + +.. bpo: 39386 +.. date: 2020-01-20-21-40-57 +.. nonce: ULqD8t +.. section: Core and Builtins + +Prevent double awaiting of async iterator. + +.. + +.. bpo: 17005 +.. date: 2020-01-17-00-00-58 +.. nonce: nTSxsy +.. section: Core and Builtins + +Add :class:`functools.TopologicalSorter` to the :mod:`functools` module to +offers functionality to perform topological sorting of graphs. Patch by +Pablo Galindo, Tim Peters and Larry Hastings. + +.. + +.. bpo: 39320 +.. date: 2020-01-15-15-33-44 +.. nonce: b4hnJW +.. section: Core and Builtins + +Replace four complex bytecodes for building sequences with three simpler +ones. + +The following four bytecodes have been removed: + +* BUILD_LIST_UNPACK +* BUILD_TUPLE_UNPACK +* BUILD_SET_UNPACK +* BUILD_TUPLE_UNPACK_WITH_CALL + +The following three bytecodes have been added: + +* LIST_TO_TUPLE +* LIST_EXTEND +* SET_UPDATE + +.. + +.. bpo: 39336 +.. date: 2020-01-15-01-39-29 +.. nonce: nJ7W9I +.. section: Core and Builtins + +Import loaders which publish immutable module objects can now publish +immutable packages in addition to individual modules. + +.. + +.. bpo: 39322 +.. date: 2020-01-13-15-18-13 +.. nonce: aAs-1T +.. section: Core and Builtins + +Added a new function :func:`gc.is_finalized` to check if an object has been +finalized by the garbage collector. Patch by Pablo Galindo. + +.. + +.. bpo: 39048 +.. date: 2020-01-13-14-45-22 +.. nonce: iPsj81 +.. section: Core and Builtins + +Improve the displayed error message when incorrect types are passed to +``async with`` statements by looking up the :meth:`__aenter__` special +method before the :meth:`__aexit__` special method when entering an +asynchronous context manager. Patch by Géry Ogam. + +.. + +.. bpo: 39235 +.. date: 2020-01-09-10-01-18 +.. nonce: RYwjoc +.. section: Core and Builtins + +Fix AST end location for lone generator expression in function call, e.g. +f(i for i in a). + +.. + +.. bpo: 39209 +.. date: 2020-01-06-10-29-16 +.. nonce: QHAONe +.. section: Core and Builtins + +Correctly handle multi-line tokens in interactive mode. Patch by Pablo +Galindo. + +.. + +.. bpo: 1635741 +.. date: 2020-01-05-13-40-08 +.. nonce: QRTJVC +.. section: Core and Builtins + +Port _json extension module to multiphase initialization (:pep:`489`). + +.. + +.. bpo: 39216 +.. date: 2020-01-05-06-55-52 +.. nonce: 74jLh9 +.. section: Core and Builtins + +Fix constant folding optimization for positional only arguments - by Anthony +Sottile. + +.. + +.. bpo: 39215 +.. date: 2020-01-04-17-25-34 +.. nonce: xiqiIz +.. section: Core and Builtins + +Fix ``SystemError`` when nested function has annotation on positional-only +argument - by Anthony Sottile. + +.. + +.. bpo: 39200 +.. date: 2020-01-04-01-14-32 +.. nonce: 8Z9DYp +.. section: Core and Builtins + +Correct the error message when calling the :func:`min` or :func:`max` with +no arguments. Patch by Donghee Na. + +.. + +.. bpo: 39200 +.. date: 2020-01-03-14-50-14 +.. nonce: Ip2_iI +.. section: Core and Builtins + +Correct the error message when trying to construct :class:`range` objects +with no arguments. Patch by Pablo Galindo. + +.. + +.. bpo: 39166 +.. date: 2020-01-02-22-22-03 +.. nonce: Qt-UeD +.. section: Core and Builtins + +Fix incorrect line execution reporting in trace functions when tracing the +last iteration of asynchronous for loops. Patch by Pablo Galindo. + +.. + +.. bpo: 39114 +.. date: 2019-12-31-18-25-45 +.. nonce: WG9alt +.. section: Core and Builtins + +Fix incorrect line execution reporting in trace functions when tracing +exception handlers with name binding. Patch by Pablo Galindo. + +.. + +.. bpo: 39156 +.. date: 2019-12-30-10-53-59 +.. nonce: veT-CB +.. section: Core and Builtins + +Split the COMPARE_OP bytecode instruction into four distinct instructions. + +* COMPARE_OP for rich comparisons +* IS_OP for 'is' and 'is not' tests +* CONTAINS_OP for 'in' and 'is not' tests +* JUMP_IF_NOT_EXC_MATCH for checking exceptions in 'try-except' statements. + +This improves the clarity of the interpreter and should provide a modest +speedup. + +.. + +.. bpo: 38588 +.. date: 2019-12-29-19-13-54 +.. nonce: pgXnNS +.. section: Core and Builtins + +Fix possible crashes in dict and list when calling +:c:func:`PyObject_RichCompareBool`. + +.. + +.. bpo: 13601 +.. date: 2019-12-17-22-32-11 +.. nonce: vNP4LC +.. section: Core and Builtins + +By default, ``sys.stderr`` is line-buffered now, even if ``stderr`` is +redirected to a file. You can still make ``sys.stderr`` unbuffered by +passing the :option:`-u` command-line option or setting the +:envvar:`PYTHONUNBUFFERED` environment variable. + +(Contributed by Jendrik Seipp in bpo-13601.) + +.. + +.. bpo: 38610 +.. date: 2019-10-31-14-30-39 +.. nonce: fHdVMS +.. section: Core and Builtins + +Fix possible crashes in several list methods by holding strong references to +list elements when calling :c:func:`PyObject_RichCompareBool`. + +.. + +.. bpo: 32021 +.. date: 2019-03-11-13-30-40 +.. nonce: dpbtkP +.. section: Core and Builtins + +Include brotli .br encoding in mimetypes encodings_map + +.. + +.. bpo: 39430 +.. date: 2020-01-24-11-05-21 +.. nonce: I0UQzM +.. section: Library + +Fixed race condition in lazy imports in :mod:`tarfile`. + +.. + +.. bpo: 39413 +.. date: 2020-01-24-10-10-25 +.. nonce: 7XYDM8 +.. section: Library + +The :func:`os.unsetenv` function is now also available on Windows. + +.. + +.. bpo: 39390 +.. date: 2020-01-23-21-34-29 +.. nonce: D2tSXk +.. section: Library + +Fixed a regression with the `ignore` callback of :func:`shutil.copytree`. +The argument types are now str and List[str] again. + +.. + +.. bpo: 39395 +.. date: 2020-01-23-03-05-41 +.. nonce: 4dda42 +.. section: Library + +The :func:`os.putenv` and :func:`os.unsetenv` functions are now always +available. + +.. + +.. bpo: 39406 +.. date: 2020-01-22-21-18-58 +.. nonce: HMpe8x +.. section: Library + +If ``setenv()`` C function is available, :func:`os.putenv` is now +implemented with ``setenv()`` instead of ``putenv()``, so Python doesn't +have to handle the environment variable memory. + +.. + +.. bpo: 39396 +.. date: 2020-01-21-09-00-42 +.. nonce: 6UXQXE +.. section: Library + +Fix ``math.nextafter(-0.0, +0.0)`` on AIX 7.1. + +.. + +.. bpo: 29435 +.. date: 2020-01-20-18-48-00 +.. nonce: qqJ2Ax +.. section: Library + +Allow :func:`tarfile.is_tarfile` to be used with file and file-like objects, +like :func:`zipfile.is_zipfile`. Patch by William Woodruff. + +.. + +.. bpo: 39377 +.. date: 2020-01-20-13-00-35 +.. nonce: QSFdaU +.. section: Library + +Removed ``encoding`` option from :func:`json.loads`. It has been deprecated +since Python 3.1. + +.. + +.. bpo: 39389 +.. date: 2020-01-20-00-56-01 +.. nonce: fEirIS +.. section: Library + +Write accurate compression level metadata in :mod:`gzip` archives, rather +than always signaling maximum compression. + +.. + +.. bpo: 39366 +.. date: 2020-01-17-18-14-51 +.. nonce: Cv3NQS +.. section: Library + +The previously deprecated ``xpath()`` and ``xgtitle()`` methods of +:class:`nntplib.NNTP` have been removed. + +.. + +.. bpo: 39357 +.. date: 2020-01-16-11-24-00 +.. nonce: bCwx-h +.. section: Library + +Remove the *buffering* parameter of :class:`bz2.BZ2File`. Since Python 3.0, +it was ignored and using it was emitting :exc:`DeprecationWarning`. Pass an +open file object, to control how the file is opened. The *compresslevel* +parameter becomes keyword-only. + +.. + +.. bpo: 39353 +.. date: 2020-01-16-10-21-48 +.. nonce: ntp7Ql +.. section: Library + +Deprecate binhex4 and hexbin4 standards. Deprecate the :mod:`binhex` module +and the following :mod:`binascii` functions: :func:`~binascii.b2a_hqx`, +:func:`~binascii.a2b_hqx`, :func:`~binascii.rlecode_hqx`, +:func:`~binascii.rledecode_hqx`, :func:`~binascii.crc_hqx`. + +.. + +.. bpo: 39351 +.. date: 2020-01-16-09-27-28 +.. nonce: a-FQdv +.. section: Library + +Remove ``base64.encodestring()`` and ``base64.decodestring()``, aliases +deprecated since Python 3.1: use :func:`base64.encodebytes` and +:func:`base64.decodebytes` instead. + +.. + +.. bpo: 39350 +.. date: 2020-01-16-09-15-40 +.. nonce: ZQx0uY +.. section: Library + +Remove ``fractions.gcd()`` function, deprecated since Python 3.5 +(:issue:`22486`): use :func:`math.gcd` instead. + +.. + +.. bpo: 39329 +.. date: 2020-01-14-22-16-07 +.. nonce: 6OKGBn +.. section: Library + +:class:`~smtplib.LMTP` constructor now has an optional *timeout* parameter. +Patch by Donghee Na. + +.. + +.. bpo: 39313 +.. date: 2020-01-12-18-17-00 +.. nonce: DCTsnm +.. section: Library + +Add a new ``exec_function`` option (*--exec-function* in the CLI) to +``RefactoringTool`` for making ``exec`` a function. Patch by Batuhan +Taskaya. + +.. + +.. bpo: 39259 +.. date: 2020-01-12-17-19-40 +.. nonce: iax06r +.. section: Library + +:class:`~ftplib.FTP_TLS` and :class:`~ftplib.FTP_TLS` now raise a +:class:`ValueError` if the given timeout for their constructor is zero to +prevent the creation of a non-blocking socket. Patch by Donghee Na. + +.. + +.. bpo: 39259 +.. date: 2020-01-12-16-34-28 +.. nonce: J_yBVq +.. section: Library + +:class:`~smtplib.SMTP` and :class:`~smtplib.SMTP_SSL` now raise a +:class:`ValueError` if the given timeout for their constructor is zero to +prevent the creation of a non-blocking socket. Patch by Donghee Na. + +.. + +.. bpo: 39310 +.. date: 2020-01-12-13-34-42 +.. nonce: YMRdcj +.. section: Library + +Add :func:`math.ulp`: return the value of the least significant bit of a +float. + +.. + +.. bpo: 39297 +.. date: 2020-01-11-01-15-37 +.. nonce: y98Z6Q +.. section: Library + +Improved performance of importlib.metadata distribution discovery and +resilients to inaccessible sys.path entries (importlib_metadata v1.4.0). + +.. + +.. bpo: 39259 +.. date: 2020-01-11-00-32-45 +.. nonce: _S5VjC +.. section: Library + +:class:`~nntplib.NNTP` and :class:`~nntplib.NNTP_SSL` now raise a +:class:`ValueError` if the given timeout for their constructor is zero to +prevent the creation of a non-blocking socket. Patch by Donghee Na. + +.. + +.. bpo: 38901 +.. date: 2020-01-10-22-30-48 +.. nonce: OdVIIb +.. section: Library + +When you specify prompt='.' or equivalently python -m venv --prompt . ... +the basename of the current directory is used to set the created venv's +prompt when it's activated. + +.. + +.. bpo: 39288 +.. date: 2020-01-10-16-52-09 +.. nonce: IB-aQX +.. section: Library + +Add :func:`math.nextafter`: return the next floating-point value after *x* +towards *y*. + +.. + +.. bpo: 39259 +.. date: 2020-01-09-10-58-58 +.. nonce: RmDgCC +.. section: Library + +:class:`~poplib.POP3` and :class:`~poplib.POP3_SSL` now raise a +:class:`ValueError` if the given timeout for their constructor is zero to +prevent the creation of a non-blocking socket. Patch by Donghee Na. + +.. + +.. bpo: 39242 +.. date: 2020-01-08-23-25-27 +.. nonce: bnL65N +.. section: Library + +Updated the Gmane domain from news.gmane.org to news.gmane.io which is used +for examples of :class:`~nntplib.NNTP` news reader server and nntplib tests. + +.. + +.. bpo: 35292 +.. date: 2020-01-08-14-39-19 +.. nonce: ihRT1z +.. section: Library + +Proxy the `SimpleHTTPRequestHandler.guess_type` to `mimetypes.guess_type` so +the `mimetypes.init` is called lazily to avoid unnecessary costs when +:mod:`http.server` module is imported. + +.. + +.. bpo: 39239 +.. date: 2020-01-07-01-02-44 +.. nonce: r7vecs +.. section: Library + +The :meth:`select.epoll.unregister` method no longer ignores the +:data:`~errno.EBADF` error. + +.. + +.. bpo: 38907 +.. date: 2020-01-06-02-14-38 +.. nonce: F1RkCR +.. section: Library + +In http.server script, restore binding to IPv4 on Windows. + +.. + +.. bpo: 39152 +.. date: 2020-01-03-18-02-50 +.. nonce: JgPjCC +.. section: Library + +Fix ttk.Scale.configure([name]) to return configuration tuple for name or +all options. Giovanni Lombardo contributed part of the patch. + +.. + +.. bpo: 39198 +.. date: 2020-01-02-20-21-03 +.. nonce: nzwGyG +.. section: Library + +If an exception were to be thrown in `Logger.isEnabledFor` (say, by asyncio +timeouts or stopit) , the `logging` global lock may not be released +appropriately, resulting in deadlock. This change wraps that block of code +with `try...finally` to ensure the lock is released. + +.. + +.. bpo: 39191 +.. date: 2020-01-02-17-28-03 +.. nonce: ur_scy +.. section: Library + +Perform a check for running loop before starting a new task in +``loop.run_until_complete()`` to fail fast; it prevents the side effect of +new task spawning before exception raising. + +.. + +.. bpo: 38871 +.. date: 2020-01-01-18-44-52 +.. nonce: 3EEOLg +.. section: Library + +Correctly parenthesize filter-based statements that contain lambda +expressions in mod:`lib2to3`. Patch by Donghee Na. + +.. + +.. bpo: 39142 +.. date: 2019-12-31-19-27-23 +.. nonce: oqU5iD +.. section: Library + +A change was made to logging.config.dictConfig to avoid converting instances +of named tuples to ConvertingTuple. It's assumed that named tuples are too +specialised to be treated like ordinary tuples; if a user of named tuples +requires ConvertingTuple functionality, they will have to implement that +themselves in their named tuple class. + +.. + +.. bpo: 39158 +.. date: 2019-12-29-15-44-38 +.. nonce: cxVoOR +.. section: Library + +ast.literal_eval() now supports empty sets. + +.. + +.. bpo: 39129 +.. date: 2019-12-24-10-43-13 +.. nonce: jVx5rW +.. section: Library + +Fix import path for ``asyncio.TimeoutError`` + +.. + +.. bpo: 39057 +.. date: 2019-12-15-21-47-54 +.. nonce: FOxn-w +.. section: Library + +:func:`urllib.request.proxy_bypass_environment` now ignores leading dots and +no longer ignores a trailing newline. + +.. + +.. bpo: 39056 +.. date: 2019-12-15-21-05-16 +.. nonce: nEfUM9 +.. section: Library + +Fixed handling invalid warning category in the -W option. No longer import +the re module if it is not needed. + +.. + +.. bpo: 39055 +.. date: 2019-12-15-19-23-23 +.. nonce: FmN3un +.. section: Library + +:func:`base64.b64decode` with ``validate=True`` raises now a binascii.Error +if the input ends with a single ``\n``. + +.. + +.. bpo: 21600 +.. date: 2019-12-14-14-38-40 +.. nonce: kC4Cgh +.. section: Library + +Fix :func:`mock.patch.stopall` to stop active patches that were created with +:func:`mock.patch.dict`. + +.. + +.. bpo: 39019 +.. date: 2019-12-10-21-11-05 +.. nonce: YIlgZ7 +.. section: Library + +Implement dummy ``__class_getitem__`` for +:class:`tempfile.SpooledTemporaryFile`. + +.. + +.. bpo: 39019 +.. date: 2019-12-10-21-03-34 +.. nonce: i8RpMZ +.. section: Library + +Implement dummy ``__class_getitem__`` for ``subprocess.Popen``, +``subprocess.CompletedProcess`` + +.. + +.. bpo: 38914 +.. date: 2019-11-26-23-21-56 +.. nonce: 8l-g-T +.. section: Library + +Adjusted the wording of the warning issued by distutils' ``check`` command +when the ``author`` and ``maintainer`` fields are supplied but no +corresponding e-mail field (``author_email`` or ``maintainer_email``) is +found. The wording now reflects the fact that these fields are suggested, +but not required. Patch by Juergen Gmach. + +.. + +.. bpo: 38878 +.. date: 2019-11-22-12-08-52 +.. nonce: EJ0cFf +.. section: Library + +Fixed __subclasshook__ of :class:`os.PathLike` to return a correct result +upon inheritance. Patch by Bar Harel. + +.. + +.. bpo: 38615 +.. date: 2019-11-17-17-32-35 +.. nonce: OVyaNX +.. section: Library + +:class:`~imaplib.IMAP4` and :class:`~imaplib.IMAP4_SSL` now have an optional +*timeout* parameter for their constructors. Also, the +:meth:`~imaplib.IMAP4.open` method now has an optional *timeout* parameter +with this change. The overridden methods of :class:`~imaplib.IMAP4_SSL` and +:class:`~imaplib.IMAP4_stream` were applied to this change. Patch by +Donghee Na. + +.. + +.. bpo: 35182 +.. date: 2019-10-31-19-23-25 +.. nonce: hzeNl9 +.. section: Library + +Fixed :func:`Popen.communicate` subsequent call crash when the child process +has already closed any piped standard stream, but still continues to be +running. Patch by Andriy Maletsky. + +.. + +.. bpo: 38630 +.. date: 2019-10-29-12-21-10 +.. nonce: Dv6Xrm +.. section: Library + +On Unix, :meth:`subprocess.Popen.send_signal` now polls the process status. +Polling reduces the risk of sending a signal to the wrong process if the +process completed, the :attr:`subprocess.Popen.returncode` attribute is +still ``None``, and the pid has been reassigned (recycled) to a new +different process. + +.. + +.. bpo: 38536 +.. date: 2019-10-21-20-24-51 +.. nonce: beZ0Sk +.. section: Library + +Removes trailing space in formatted currency with `international=True` and a +locale with symbol following value. E.g. `locale.currency(12.34, +international=True)` returned `'12,34 EUR '` instead of `'12,34 EUR'`. + +.. + +.. bpo: 38473 +.. date: 2019-10-14-21-14-55 +.. nonce: uXpVld +.. section: Library + +Use signature from inner mock for autospecced methods attached with +:func:`unittest.mock.attach_mock`. Patch by Karthikeyan Singaravelan. + +.. + +.. bpo: 38361 +.. date: 2019-10-04-09-49-56 +.. nonce: LM4u4T +.. section: Library + +Fixed an issue where ``ident`` could include a leading path separator when +:func:`syslog.openlog` was called without arguments. + +.. + +.. bpo: 38293 +.. date: 2019-09-29-08-17-03 +.. nonce: wls5s3 +.. section: Library + +Add :func:`copy.copy` and :func:`copy.deepcopy` support to :func:`property` +objects. + +.. + +.. bpo: 37958 +.. date: 2019-08-27-03-57-25 +.. nonce: lRORI3 +.. section: Library + +Added the pstats.Stats.get_profile_dict() method to return the profile data +as a StatsProfile instance. + +.. + +.. bpo: 28367 +.. date: 2019-05-06-22-38-47 +.. nonce: 2AKen5 +.. section: Library + +Termios magic constants for the following baud rates: - B500000 - +B576000 - B921600 - B1000000 - B1152000 - B1500000 - B2000000 - +B2500000 - B3000000 - B3500000 - B4000000 Patch by Andrey Smirnov + +.. + +.. bpo: 39381 +.. date: 2020-01-18-15-37-56 +.. nonce: wTWe8d +.. section: Documentation + +Mention in docs that :func:`asyncio.get_event_loop` implicitly creates new +event loop only if called from the main thread. + +.. + +.. bpo: 38918 +.. date: 2019-12-15-22-04-41 +.. nonce: 8JnDTS +.. section: Documentation + +Add an entry for ``__module__`` in the "function" & "method" sections of the +:mod:`inspect` docs' :ref:`inspect-types` table. + +.. + +.. bpo: 3530 +.. date: 2019-11-17-11-53-10 +.. nonce: 8zFUMc +.. section: Documentation + +In the :mod:`ast` module documentation, fix a misleading ``NodeTransformer`` +example and add advice on when to use the ``fix_missing_locations`` +function. + +.. + +.. bpo: 39395 +.. date: 2020-01-23-03-05-13 +.. nonce: RoArIZ +.. section: Build + +On non-Windows platforms, the :c:func:`setenv` and :c:func:`unsetenv` +functions are now required to build Python. + +.. + +.. bpo: 39160 +.. date: 2019-12-30-03-54-24 +.. nonce: aBmj13 +.. section: Build + +Updated the documentation in `./configure --help` to show default values, +reference documentation where required and add additional explanation where +needed. + +.. + +.. bpo: 39144 +.. date: 2019-12-27-22-18-26 +.. nonce: dwHMlR +.. section: Build + +The ctags and etags build targets both include Modules/_ctypes and Python +standard library source files. + +.. + +.. bpo: 39050 +.. date: 2020-01-22-22-28-06 +.. nonce: zkn0FO +.. section: IDLE + +Make IDLE Settings dialog Help button work again. + +.. + +.. bpo: 34118 +.. date: 2019-12-30-16-44-07 +.. nonce: FaNW0a +.. section: IDLE + +Tag memoryview, range, and tuple as classes, the same as list, etcetera, in +the library manual built-in functions list. + +.. + +.. bpo: 32989 +.. date: 2018-03-03-12-56-26 +.. nonce: FVhmhH +.. section: IDLE + +Add tests for editor newline_and_indent_event method. Remove dead code from +pyparse find_good_parse_start method. + +.. + +.. bpo: 39372 +.. date: 2020-01-17-19-25-48 +.. nonce: hGJMY6 +.. section: C API + +Clean header files of interfaces defined but with no implementation. The +public API symbols being removed are: +``_PyBytes_InsertThousandsGroupingLocale``, +``_PyBytes_InsertThousandsGrouping``, ``_Py_InitializeFromArgs``, +``_Py_InitializeFromWideArgs``, ``_PyFloat_Repr``, ``_PyFloat_Digits``, +``_PyFloat_DigitsInit``, ``PyFrame_ExtendStack``, ``_PyAIterWrapper_Type``, +``PyNullImporter_Type``, ``PyCmpWrapper_Type``, ``PySortWrapper_Type``, +``PyNoArgsFunction``. + +.. + +.. bpo: 39164 +.. date: 2019-12-30-10-43-52 +.. nonce: WEV0uu +.. section: C API + +Add a private ``_PyErr_GetExcInfo()`` function to retrieve exception +information of the specified Python thread state. diff --git a/Misc/NEWS.d/3.9.0a4.rst b/Misc/NEWS.d/3.9.0a4.rst new file mode 100644 index 00000000..e59435b5 --- /dev/null +++ b/Misc/NEWS.d/3.9.0a4.rst @@ -0,0 +1,949 @@ +.. bpo: 39184 +.. date: 2020-02-07-23-54-18 +.. nonce: v-ue-v +.. release date: 2020-02-25 +.. section: Security + +Add audit events to functions in `fcntl`, `msvcrt`, `os`, `resource`, +`shutil`, `signal` and `syslog`. + +.. + +.. bpo: 39401 +.. date: 2020-01-28-20-54-09 +.. nonce: he7h_A +.. section: Security + +Avoid unsafe DLL load at startup on Windows 7 and earlier. + +.. + +.. bpo: 39184 +.. date: 2020-01-07-00-42-08 +.. nonce: fe7NgK +.. section: Security + +Add audit events to command execution functions in os and pty modules. + +.. + +.. bpo: 39382 +.. date: 2020-02-18-01-40-13 +.. nonce: OLSJu9 +.. section: Core and Builtins + +Fix a use-after-free in the single inheritance path of ``issubclass()``, +when the ``__bases__`` of an object has a single reference, and so does its +first item. Patch by Yonatan Goldschmidt. + +.. + +.. bpo: 39573 +.. date: 2020-02-14-10-08-53 +.. nonce: BIIX2M +.. section: Core and Builtins + +Update clinic tool to use :c:func:`Py_IS_TYPE`. Patch by Donghee Na. + +.. + +.. bpo: 39619 +.. date: 2020-02-13-07-35-00 +.. nonce: inb_master_chroot +.. section: Core and Builtins + +Enable use of :func:`os.chroot` on HP-UX systems. + +.. + +.. bpo: 39573 +.. date: 2020-02-13-01-30-22 +.. nonce: uTFj1m +.. section: Core and Builtins + +Add :c:func:`Py_IS_TYPE` static inline function to check whether the object +*o* type is *type*. + +.. + +.. bpo: 39606 +.. date: 2020-02-11-23-59-07 +.. nonce: a72Sxc +.. section: Core and Builtins + +Fix regression caused by fix for bpo-39386, that prevented calling +``aclose`` on an async generator that had already been closed or exhausted. + +.. + +.. bpo: 39579 +.. date: 2020-02-07-15-18-35 +.. nonce: itNmC0 +.. section: Core and Builtins + +Change the ending column offset of `Attribute` nodes constructed in +`ast_for_dotted_name` to point at the end of the current node and not at the +end of the last `NAME` node. + +.. + +.. bpo: 1635741 +.. date: 2020-02-07-12-57-40 +.. nonce: ySW6gq +.. section: Core and Builtins + +Port _crypt extension module to multiphase initialization (:pep:`489`). + +.. + +.. bpo: 1635741 +.. date: 2020-02-06-09-00-35 +.. nonce: oaxe1j +.. section: Core and Builtins + +Port _contextvars extension module to multiphase initialization +(:pep:`489`). + +.. + +.. bpo: 39510 +.. date: 2020-02-04-10-27-41 +.. nonce: PMIh-f +.. section: Core and Builtins + +Fix segfault in ``readinto()`` method on closed BufferedReader. + +.. + +.. bpo: 39502 +.. date: 2020-01-30-14-36-31 +.. nonce: IJu0rl +.. section: Core and Builtins + +Fix :func:`time.localtime` on 64-bit AIX to support years before 1902 and +after 2038. Patch by M Felt. + +.. + +.. bpo: 39492 +.. date: 2020-01-30-01-14-42 +.. nonce: eTuy0F +.. section: Core and Builtins + +Fix a reference cycle in the C Pickler that was preventing the garbage +collection of deleted, pickled objects. + +.. + +.. bpo: 39453 +.. date: 2020-01-25-23-51-17 +.. nonce: xCOkYk +.. section: Core and Builtins + +Fixed a possible crash in :meth:`list.__contains__` when a list is changed +during comparing items. Patch by Donghee Na. + +.. + +.. bpo: 39434 +.. date: 2020-01-24-01-07-04 +.. nonce: S5ehj9 +.. section: Core and Builtins + +:term:`floor division` of float operation now has a better performance. Also +the message of :exc:`ZeroDivisionError` for this operation is updated. Patch +by Donghee Na. + +.. + +.. bpo: 1635741 +.. date: 2020-01-19-11-06-30 +.. nonce: 0mjsfm +.. section: Core and Builtins + +Port _codecs extension module to multiphase initialization (:pep:`489`). + +.. + +.. bpo: 1635741 +.. date: 2020-01-18-11-06-28 +.. nonce: OKROOt +.. section: Core and Builtins + +Port _bz2 extension module to multiphase initialization (:pep:`489`). + +.. + +.. bpo: 1635741 +.. date: 2020-01-16-12-00-04 +.. nonce: fuqoBG +.. section: Core and Builtins + +Port _abc extension module to multiphase initialization (:pep:`489`). + +.. + +.. bpo: 39320 +.. date: 2020-01-15-15-50-22 +.. nonce: oWARyk +.. section: Core and Builtins + +Replace two complex bytecodes for building dicts with two simpler ones. The +new bytecodes ``DICT_MERGE`` and ``DICT_UPDATE`` have been added The old +bytecodes ``BUILD_MAP_UNPACK`` and ``BUILD_MAP_UNPACK_WITH_CALL`` have been +removed. + +.. + +.. bpo: 39219 +.. date: 2020-01-05-13-36-08 +.. nonce: uHtKd4 +.. section: Core and Builtins + +Syntax errors raised in the tokenizer now always set correct "text" and +"offset" attributes. + +.. + +.. bpo: 36051 +.. date: 2019-12-30-15-56-07 +.. nonce: imaVlq +.. section: Core and Builtins + +Drop the GIL during large ``bytes.join`` operations. Patch by Bruce Merry. + +.. + +.. bpo: 38960 +.. date: 2019-12-03-16-41-22 +.. nonce: kvoFM0 +.. section: Core and Builtins + +Fix DTrace build issues on FreeBSD. Patch by David Carlier. + +.. + +.. bpo: 37207 +.. date: 2019-06-09-10-54-31 +.. nonce: bLjgLR +.. section: Core and Builtins + +Speed up calls to ``range()`` by about 30%, by using the PEP 590 +``vectorcall`` calling convention. Patch by Mark Shannon. + +.. + +.. bpo: 36144 +.. date: 2019-03-02-23-03-34 +.. nonce: LRl4LS +.. section: Core and Builtins + +:class:`dict` (and :class:`collections.UserDict`) objects now support PEP +584's merge (``|``) and update (``|=``) operators. Patch by Brandt Bucher. + +.. + +.. bpo: 32856 +.. date: 2018-02-16-10-44-24 +.. nonce: UjR8SD +.. section: Core and Builtins + +Optimized the idiom for assignment a temporary variable in comprehensions. +Now ``for y in [expr]`` in comprehensions is as fast as a simple assignment +``y = expr``. + +.. + +.. bpo: 30566 +.. date: 2020-02-24-03-45-28 +.. nonce: qROxty +.. section: Library + +Fix :exc:`IndexError` when trying to decode an invalid string with punycode +codec. + +.. + +.. bpo: 39649 +.. date: 2020-02-23-21-27-10 +.. nonce: qiubSp +.. section: Library + +Remove obsolete check for `__args__` in bdb.Bdb.format_stack_entry. + +.. + +.. bpo: 39648 +.. date: 2020-02-22-12-49-04 +.. nonce: Y-9N7F +.. section: Library + +Expanded :func:`math.gcd` and :func:`math.lcm` to handle multiple arguments. + +.. + +.. bpo: 39681 +.. date: 2020-02-21-13-58-40 +.. nonce: zN8hf0 +.. section: Library + +Fix a regression where the C pickle module wouldn't allow unpickling from a +file-like object that doesn't expose a readinto() method. + +.. + +.. bpo: 35950 +.. date: 2020-02-21-02-42-41 +.. nonce: 9G3-wl +.. section: Library + +Raise :exc:`io.UnsupportedOperation` in :meth:`io.BufferedReader.truncate` +when it is called on a read-only :class:`io.BufferedReader` instance. + +.. + +.. bpo: 39479 +.. date: 2020-02-18-12-37-16 +.. nonce: j3UcCq +.. section: Library + +Add :func:`math.lcm` function: least common multiple. + +.. + +.. bpo: 39674 +.. date: 2020-02-18-12-31-24 +.. nonce: S_zqVM +.. section: Library + +Revert "Do not expose abstract collection classes in the collections module" +change (bpo-25988). Aliases to ABC like collections.Mapping are kept in +Python 3.9 to ease transition from Python 2.7, but will be removed in Python +3.10. + +.. + +.. bpo: 39104 +.. date: 2020-02-16-18-49-16 +.. nonce: cI5MJY +.. section: Library + +Fix hanging ProcessPoolExcutor on ``shutdown(wait=False)`` when a task has +failed pickling. + +.. + +.. bpo: 39627 +.. date: 2020-02-13-18-14-15 +.. nonce: Q0scyQ +.. section: Library + +Fixed TypedDict totality check for inherited keys. + +.. + +.. bpo: 39474 +.. date: 2020-02-12-12-01-26 +.. nonce: RZMEUH +.. section: Library + +Fixed starting position of AST for expressions like ``(a)(b)``, ``(a)[b]`` +and ``(a).b``. + +.. + +.. bpo: 21016 +.. date: 2020-02-12-10-04-39 +.. nonce: bFXPH7 +.. section: Library + +The :mod:`pydoc` and :mod:`trace` modules now use the :mod:`sysconfig` +module to get the path to the Python standard library, to support uncommon +installation path like ``/usr/lib64/python3.9/`` on Fedora. Patch by Jan +Matějek. + +.. + +.. bpo: 39590 +.. date: 2020-02-09-05-51-05 +.. nonce: rf98GU +.. section: Library + +Collections.deque now holds strong references during deque.__contains__ and +deque.count, fixing crashes. + +.. + +.. bpo: 39586 +.. date: 2020-02-08-13-37-00 +.. nonce: nfTPxX +.. section: Library + +The distutils ``bdist_msi`` command is deprecated in Python 3.9, use +``bdist_wheel`` (wheel packages) instead. + +.. + +.. bpo: 39595 +.. date: 2020-02-07-23-14-14 +.. nonce: DHwddE +.. section: Library + +Improved performance of zipfile.Path for files with a large number of +entries. Also improved performance and fixed minor issue as published with +`importlib_metadata 1.5 +<https://importlib-metadata.readthedocs.io/en/latest/history.html#v1-5-0>`_. + +.. + +.. bpo: 39350 +.. date: 2020-02-06-13-34-52 +.. nonce: wRwup1 +.. section: Library + +Fix regression in :class:`fractions.Fraction` if the numerator and/or the +denominator is an :class:`int` subclass. The :func:`math.gcd` function is +now used to normalize the *numerator* and *denominator*. :func:`math.gcd` +always return a :class:`int` type. Previously, the GCD type depended on +*numerator* and *denominator*. + +.. + +.. bpo: 39567 +.. date: 2020-02-06-10-23-32 +.. nonce: VpFBxt +.. section: Library + +Added audit for :func:`os.walk`, :func:`os.fwalk`, :meth:`pathlib.Path.glob` +and :meth:`pathlib.Path.rglob`. + +.. + +.. bpo: 39559 +.. date: 2020-02-05-18-29-14 +.. nonce: L8i5YB +.. section: Library + +Remove unused, undocumented argument ``getters`` from :func:`uuid.getnode` + +.. + +.. bpo: 38149 +.. date: 2020-02-05-11-24-16 +.. nonce: GWsjHE +.. section: Library + +:func:`sys.audit` is now called only once per call of :func:`glob.glob` and +:func:`glob.iglob`. + +.. + +.. bpo: 39546 +.. date: 2020-02-03-15-12-51 +.. nonce: _Kj0Pn +.. section: Library + +Fix a regression in :class:`~argparse.ArgumentParser` where +``allow_abbrev=False`` was ignored for long options that used a prefix +character other than "-". + +.. + +.. bpo: 39450 +.. date: 2020-02-02-14-46-34 +.. nonce: 48R274 +.. section: Library + +Striped whitespace from docstring before returning it from +:func:`unittest.case.shortDescription`. + +.. + +.. bpo: 12915 +.. date: 2020-02-02-10-08-25 +.. nonce: d6r50- +.. section: Library + +A new function ``resolve_name`` has been added to the ``pkgutil`` module. +This resolves a string of the form ``'a.b.c.d'`` or ``'a.b:c.d'`` to an +object. In the example, ``a.b`` is a package/module and ``c.d`` is an object +within that package/module reached via recursive attribute access. + +.. + +.. bpo: 39353 +.. date: 2020-01-30-09-07-16 +.. nonce: wTl9hc +.. section: Library + +The :func:`binascii.crc_hqx` function is no longer deprecated. + +.. + +.. bpo: 39493 +.. date: 2020-01-30-01-13-19 +.. nonce: CbFRi7 +.. section: Library + +Mark ``typing.IO.closed`` as a property + +.. + +.. bpo: 39491 +.. date: 2020-01-29-22-47-12 +.. nonce: tdl17b +.. section: Library + +Add :data:`typing.Annotated` and ``include_extras`` parameter to +:func:`typing.get_type_hints` as part of :pep:`593`. Patch by Till +Varoquaux, documentation by Till Varoquaux and Konstantin Kashin. + +.. + +.. bpo: 39485 +.. date: 2020-01-29-14-58-27 +.. nonce: Zy3ot6 +.. section: Library + +Fix a bug in :func:`unittest.mock.create_autospec` that would complain about +the wrong number of arguments for custom descriptors defined in an extension +module returning functions. + +.. + +.. bpo: 38932 +.. date: 2020-01-25-13-41-27 +.. nonce: 1pu_8I +.. section: Library + +Mock fully resets child objects on reset_mock(). Patch by Vegard Stikbakke + +.. + +.. bpo: 39082 +.. date: 2020-01-24-13-24-35 +.. nonce: qKgrq_ +.. section: Library + +Allow AsyncMock to correctly patch static/class methods + +.. + +.. bpo: 39432 +.. date: 2020-01-23-16-08-58 +.. nonce: Cee6mi +.. section: Library + +Implement PEP-489 algorithm for non-ascii "PyInit\_..." symbol names in +distutils to make it export the correct init symbol also on Windows. + +.. + +.. bpo: 18819 +.. date: 2020-01-20-10-06-19 +.. nonce: H4qsoS +.. section: Library + +Omit ``devmajor`` and ``devminor`` fields for non-device files in +:mod:`tarfile` archives, enabling bit-for-bit compatibility with GNU +``tar(1)``. + +.. + +.. bpo: 39349 +.. date: 2020-01-19-04-12-34 +.. nonce: 7CV-LC +.. section: Library + +Added a new *cancel_futures* parameter to +:meth:`concurrent.futures.Executor.shutdown` that cancels all pending +futures which have not started running, instead of waiting for them to +complete before shutting down the executor. + +.. + +.. bpo: 39274 +.. date: 2020-01-15-23-13-03 +.. nonce: lpc0-n +.. section: Library + +``bool(fraction.Fraction)`` now returns a boolean even if (numerator != 0) +does not return a boolean (ex: numpy number). + +.. + +.. bpo: 34793 +.. date: 2019-12-09-17-24-29 +.. nonce: D82Dyu +.. section: Library + +Remove support for ``with (await asyncio.lock):`` and ``with (yield from +asyncio.lock):``. The same is correct for ``asyncio.Condition`` and +``asyncio.Semaphore``. + +.. + +.. bpo: 25597 +.. date: 2019-09-12-12-11-05 +.. nonce: mPMzVx +.. section: Library + +Ensure, if ``wraps`` is supplied to :class:`unittest.mock.MagicMock`, it is +used to calculate return values for the magic methods instead of using the +default return values. Patch by Karthikeyan Singaravelan. + +.. + +.. bpo: 36350 +.. date: 2019-03-18-16-17-59 +.. nonce: udRSWE +.. section: Library + +`inspect.Signature.parameters` and `inspect.BoundArguments.arguments` are +now dicts instead of OrderedDicts. Patch contributed by Rémi Lapeyre. + +.. + +.. bpo: 35727 +.. date: 2019-01-12-20-39-34 +.. nonce: FWrbHn +.. section: Library + +Fix sys.exit() and sys.exit(None) exit code propagation when used in +multiprocessing.Process. + +.. + +.. bpo: 32173 +.. date: 2017-12-04-10-14-23 +.. nonce: e0C5dF +.. section: Library + +* Add `lazycache` function to `__all__`. +* Use `dict.clear` to clear the cache. +* Refactoring `getline` function and `checkcache` function. + +.. + +.. bpo: 17422 +.. date: 2020-02-19-11-13-47 +.. nonce: g7_9zz +.. section: Documentation + +The language reference now specifies restrictions on class namespaces. +Adapted from a patch by Ethan Furman. + +.. + +.. bpo: 39572 +.. date: 2020-02-18-18-37-07 +.. nonce: CCtzy1 +.. section: Documentation + +Updated documentation of ``total`` flag of ``TypedDict``. + +.. + +.. bpo: 39654 +.. date: 2020-02-18-07-42-20 +.. nonce: MoT1jI +.. section: Documentation + +In pyclbr doc, update 'class' to 'module' where appropriate and add +readmodule comment. Patch by Hakan Çelik. + +.. + +.. bpo: 39153 +.. date: 2020-01-27-22-24-51 +.. nonce: Pjl8jV +.. section: Documentation + +Clarify refcounting semantics for the following functions: - +PyObject_SetItem - PyMapping_SetItemString - PyDict_SetItem - +PyDict_SetItemString + +.. + +.. bpo: 39392 +.. date: 2020-01-27-18-18-42 +.. nonce: oiqcLO +.. section: Documentation + +Explain that when filling with turtle, overlap regions may be left unfilled. + +.. + +.. bpo: 39369 +.. date: 2020-01-17-13-59-21 +.. nonce: Bx5yE3 +.. section: Documentation + +Update mmap readline method description. The fact that the readline method +does update the file position should not be ignored since this might give +the impression for the programmer that it doesn't update it. + +.. + +.. bpo: 9056 +.. date: 2018-09-28-18-13-08 +.. nonce: -sFOwU +.. section: Documentation + +Include subsection in TOC for PDF version of docs. + +.. + +.. bpo: 38325 +.. date: 2020-02-11-00-38-32 +.. nonce: HgmfoE +.. section: Tests + +Skip tests on non-BMP characters of test_winconsoleio. + +.. + +.. bpo: 39502 +.. date: 2020-01-30-15-04-54 +.. nonce: chbpII +.. section: Tests + +Skip test_zipfile.test_add_file_after_2107() if :func:`time.localtime` fails +with :exc:`OverflowError`. It is the case on AIX 6.1 for example. + +.. + +.. bpo: 39489 +.. date: 2020-01-29-19-17-02 +.. nonce: HKPzv- +.. section: Build + +Remove ``COUNT_ALLOCS`` special build. + +.. + +.. bpo: 39553 +.. date: 2020-02-04-19-50-53 +.. nonce: _EnweA +.. section: Windows + +Delete unused code related to SxS manifests. + +.. + +.. bpo: 39439 +.. date: 2020-01-24-03-15-05 +.. nonce: sFxGfR +.. section: Windows + +Honor the Python path when a virtualenv is active on Windows. + +.. + +.. bpo: 39393 +.. date: 2020-01-20-23-42-53 +.. nonce: gWlJDG +.. section: Windows + +Improve the error message when attempting to load a DLL with unresolved +dependencies. + +.. + +.. bpo: 38883 +.. date: 2020-01-11-22-53-55 +.. nonce: X7FRaN +.. section: Windows + +:meth:`~pathlib.Path.home()` and :meth:`~pathlib.Path.expanduser()` on +Windows now prefer :envvar:`USERPROFILE` and no longer use :envvar:`HOME`, +which is not normally set for regular user accounts. This makes them again +behave like :func:`os.path.expanduser`, which was changed to ignore +:envvar:`HOME` in 3.8, see :issue:`36264`. + +.. + +.. bpo: 39185 +.. date: 2020-01-02-01-11-53 +.. nonce: T4herN +.. section: Windows + +The build.bat script has additional options for very-quiet output (-q) and +very-verbose output (-vv) + +.. + +.. bpo: 39663 +.. date: 2020-02-17-21-09-03 +.. nonce: wexcsH +.. section: IDLE + +Add tests for pyparse find_good_parse_start(). + +.. + +.. bpo: 39600 +.. date: 2020-02-10-17-09-48 +.. nonce: X6NsyM +.. section: IDLE + +In the font configuration window, remove duplicated font names. + +.. + +.. bpo: 30780 +.. date: 2020-01-27-16-44-29 +.. nonce: nR80qu +.. section: IDLE + +Add remaining configdialog tests for buttons and highlights and keys tabs. + +.. + +.. bpo: 39388 +.. date: 2020-01-25-02-26-45 +.. nonce: x4TQNh +.. section: IDLE + +IDLE Settings Cancel button now cancels pending changes + +.. + +.. bpo: 38792 +.. date: 2019-11-13-23-51-39 +.. nonce: xhTC5a +.. section: IDLE + +Close an IDLE shell calltip if a :exc:`KeyboardInterrupt` or shell restart +occurs. Patch by Zackery Spytz. + +.. + +.. bpo: 35081 +.. date: 2020-02-12-21-38-49 +.. nonce: 5tj1yC +.. section: C API + +Move the ``bytes_methods.h`` header file to the internal C API as +``pycore_bytes_methods.h``: it only contains private symbols (prefixed by +``_Py``), except of the ``PyDoc_STRVAR_shared()`` macro. + +.. + +.. bpo: 35081 +.. date: 2020-02-12-21-24-02 +.. nonce: at7BjN +.. section: C API + +Move the ``dtoa.h`` header file to the internal C API as ``pycore_dtoa.h``: +it only contains private functions (prefixed by ``_Py``). The :mod:`math` +and :mod:`cmath` modules must now be compiled with the ``Py_BUILD_CORE`` +macro defined. + +.. + +.. bpo: 39573 +.. date: 2020-02-07-10-41-53 +.. nonce: EG9VDI +.. section: C API + +Add :c:func:`Py_SET_SIZE` function to set the size of an object. + +.. + +.. bpo: 39500 +.. date: 2020-02-07-09-35-43 +.. nonce: xRAEgX +.. section: C API + +:c:func:`PyUnicode_IsIdentifier` does not call :c:func:`Py_FatalError` +anymore if the string is not ready. + +.. + +.. bpo: 39573 +.. date: 2020-02-07-03-39-03 +.. nonce: Oa8cL1 +.. section: C API + +Add :c:func:`Py_SET_TYPE` function to set the type of an object. + +.. + +.. bpo: 39573 +.. date: 2020-02-07-00-23-44 +.. nonce: nRD1q7 +.. section: C API + +Add a :c:func:`Py_SET_REFCNT` function to set the reference counter of an +object. + +.. + +.. bpo: 39542 +.. date: 2020-02-05-13-14-20 +.. nonce: 5mleGX +.. section: C API + +Convert :c:func:`PyType_HasFeature`, :c:func:`PyType_Check` and +:c:func:`PyType_CheckExact` macros to static inline functions. + +.. + +.. bpo: 39542 +.. date: 2020-02-05-12-40-51 +.. nonce: si-_Zq +.. section: C API + +In the limited C API, ``PyObject_INIT()`` and ``PyObject_INIT_VAR()`` are +now defined as aliases to :c:func:`PyObject_Init` and +:c:func:`PyObject_InitVar` to make their implementation opaque. It avoids to +leak implementation details in the limited C API. Exclude the following +functions from the limited C API: ``_Py_NewReference()``, +``_Py_ForgetReference()``, ``_PyTraceMalloc_NewReference()`` and +``_Py_GetRefTotal()``. + +.. + +.. bpo: 39542 +.. date: 2020-02-05-12-00-18 +.. nonce: RJCUKR +.. section: C API + +Exclude trashcan mechanism from the limited C API: it requires access to +PyTypeObject and PyThreadState structure fields, whereas these structures +are opaque in the limited C API. + +.. + +.. bpo: 39511 +.. date: 2020-01-31-16-35-21 +.. nonce: nv9yEn +.. section: C API + +The :c:func:`PyThreadState_Clear` function now calls the +:c:member:`PyThreadState.on_delete` callback. Previously, that happened in +:c:func:`PyThreadState_Delete`. + +.. + +.. bpo: 38076 +.. date: 2020-01-17-11-37-05 +.. nonce: cxfw2x +.. section: C API + +Fix to clear the interpreter state only after clearing module globals to +guarantee module state access from C Extensions during runtime destruction + +.. + +.. bpo: 39245 +.. date: 2020-01-07-13-46-40 +.. nonce: G7wog6 +.. section: C API + +The Vectorcall API (PEP 590) was made public, adding the functions +``PyObject_Vectorcall``, ``PyObject_VectorcallMethod``, +``PyVectorcall_Function``, ``PyObject_CallOneArg``, +``PyObject_CallMethodNoArgs``, ``PyObject_CallMethodOneArg``, +``PyObject_FastCallDict``, and the flag ``Py_TPFLAGS_HAVE_VECTORCALL``. diff --git a/Misc/NEWS.d/3.9.0a5.rst b/Misc/NEWS.d/3.9.0a5.rst new file mode 100644 index 00000000..6ff05788 --- /dev/null +++ b/Misc/NEWS.d/3.9.0a5.rst @@ -0,0 +1,1310 @@ +.. bpo: 38576 +.. date: 2020-03-14-14-57-44 +.. nonce: OowwQn +.. release date: 2020-03-23 +.. section: Security + +Disallow control characters in hostnames in http.client, addressing +CVE-2019-18348. Such potentially malicious header injection URLs now cause a +InvalidURL to be raised. + +.. + +.. bpo: 40010 +.. date: 2020-03-20-13-51-55 +.. nonce: QGf5s8 +.. section: Core and Builtins + +Optimize pending calls in multithreaded applications. If a thread different +than the main thread schedules a pending call (:c:func:`Py_AddPendingCall`), +the bytecode evaluation loop is no longer interrupted at each bytecode +instruction to check for pending calls which cannot be executed. Only the +main thread can execute pending calls. + +Previously, the bytecode evaluation loop was interrupted at each instruction +until the main thread executes pending calls. + +.. + +.. bpo: 1635741 +.. date: 2020-03-20-13-42-35 +.. nonce: bhIu5M +.. section: Core and Builtins + +Port _weakref extension module to multiphase initialization (:pep:`489`). + +.. + +.. bpo: 1635741 +.. date: 2020-03-19-23-34-22 +.. nonce: ayunLM +.. section: Core and Builtins + +Port _collections module to multiphase initialization (:pep:`489`). + +.. + +.. bpo: 40010 +.. date: 2020-03-19-02-26-13 +.. nonce: Y-LIR0 +.. section: Core and Builtins + +Optimize signal handling in multithreaded applications. If a thread +different than the main thread gets a signal, the bytecode evaluation loop +is no longer interrupted at each bytecode instruction to check for pending +signals which cannot be handled. Only the main thread of the main +interpreter can handle signals. + +Previously, the bytecode evaluation loop was interrupted at each instruction +until the main thread handles signals. + +.. + +.. bpo: 39984 +.. date: 2020-03-19-00-45-37 +.. nonce: u-bHIq +.. section: Core and Builtins + +If :c:func:`Py_AddPendingCall` is called in a subinterpreter, the function +is now scheduled to be called from the subinterpreter, rather than being +called from the main interpreter. Each subinterpreter now has its own list +of scheduled calls. + +.. + +.. bpo: 1635741 +.. date: 2020-03-18-19-48-53 +.. nonce: ELEihr +.. section: Core and Builtins + +Port _heapq module to multiphase initialization. + +.. + +.. bpo: 1635741 +.. date: 2020-03-18-00-17-26 +.. nonce: 7AtdhP +.. section: Core and Builtins + +Port itertools module to multiphase initialization (:pep:`489`). + +.. + +.. bpo: 37207 +.. date: 2020-03-17-22-35-29 +.. nonce: sBAV1j +.. section: Core and Builtins + +Speed up calls to ``frozenset()`` by using the :pep:`590` ``vectorcall`` +calling convention. Patch by Donghee Na. + +.. + +.. bpo: 39984 +.. date: 2020-03-17-01-55-33 +.. nonce: y5Chgb +.. section: Core and Builtins + +subinterpreters: Move ``_PyRuntimeState.ceval.tracing_possible`` to +``PyInterpreterState.ceval.tracing_possible``: each interpreter now has its +own variable. + +.. + +.. bpo: 37207 +.. date: 2020-03-15-23-16-00 +.. nonce: 6XbnQA +.. section: Core and Builtins + +Speed up calls to ``set()`` by using the :pep:`590` ``vectorcall`` calling +convention. Patch by Donghee Na. + +.. + +.. bpo: 1635741 +.. date: 2020-03-15-20-51-15 +.. nonce: iH0JND +.. section: Core and Builtins + +Port _statistics module to multiphase initialization (:pep:`489`). + +.. + +.. bpo: 39968 +.. date: 2020-03-15-13-51-10 +.. nonce: f-Xi39 +.. section: Core and Builtins + +Use inline function to replace extension modules' get_module_state macros. + +.. + +.. bpo: 39965 +.. date: 2020-03-15-03-52-01 +.. nonce: Od3ZdP +.. section: Core and Builtins + +Correctly raise ``SyntaxError`` if *await* is used inside non-async +functions and ``PyCF_ALLOW_TOP_LEVEL_AWAIT`` is set (like in the asyncio +REPL). Patch by Pablo Galindo. + +.. + +.. bpo: 39562 +.. date: 2020-03-12-22-13-50 +.. nonce: E2u273 +.. section: Core and Builtins + +Allow executing asynchronous comprehensions on the top level when the +``PyCF_ALLOW_TOP_LEVEL_AWAIT`` flag is given. Patch by Batuhan Taskaya. + +.. + +.. bpo: 37207 +.. date: 2020-03-12-02-41-12 +.. nonce: ye7OM3 +.. section: Core and Builtins + +Speed up calls to ``tuple()`` by using the :pep:`590` ``vectorcall`` calling +convention. Patch by Donghee Na. + +.. + +.. bpo: 38373 +.. date: 2020-03-11-12-28-16 +.. nonce: FE9S21 +.. section: Core and Builtins + +Changed list overallocation strategy. It no longer overallocates if the new +size is closer to overallocated size than to the old size and adds padding. + +.. + +.. bpo: 39926 +.. date: 2020-03-10-19-14-42 +.. nonce: H19bAa +.. section: Core and Builtins + +Update Unicode database to Unicode version 13.0.0. + +.. + +.. bpo: 19466 +.. date: 2020-03-08-12-11-38 +.. nonce: OdOpXP +.. section: Core and Builtins + +Clear the frames of daemon threads earlier during the Python shutdown to +call objects destructors. So "unclosed file" resource warnings are now +emitted for daemon threads in a more reliable way. + +.. + +.. bpo: 38894 +.. date: 2020-03-06-21-04-39 +.. nonce: nfcGKv +.. section: Core and Builtins + +Fix a bug that was causing incomplete results when calling +``pathlib.Path.glob`` in the presence of symlinks that point to files where +the user does not have read access. Patch by Pablo Galindo and Matt +Wozniski. + +.. + +.. bpo: 39877 +.. date: 2020-03-06-18-30-00 +.. nonce: bzd1y0 +.. section: Core and Builtins + +Fix :c:func:`PyEval_RestoreThread` random crash at exit with daemon threads. +It now accesses the ``_PyRuntime`` variable directly instead of using +``tstate->interp->runtime``, since ``tstate`` can be a dangling pointer +after :c:func:`Py_Finalize` has been called. Moreover, the daemon thread now +exits before trying to take the GIL. + +.. + +.. bpo: 39871 +.. date: 2020-03-06-06-12-37 +.. nonce: dCAj_2 +.. section: Core and Builtins + +Fix a possible :exc:`SystemError` in ``math.{atan2,copysign,remainder}()`` +when the first argument cannot be converted to a :class:`float`. Patch by +Zackery Spytz. + +.. + +.. bpo: 39776 +.. date: 2020-03-02-20-12-33 +.. nonce: fNaxi_ +.. section: Core and Builtins + +Fix race condition where threads created by PyGILState_Ensure() could get a +duplicate id. + +This affects consumers of tstate->id like the contextvar caching machinery, +which could return invalid cached objects under heavy thread load (observed +in embedded scenarios). + +.. + +.. bpo: 39778 +.. date: 2020-03-02-19-21-21 +.. nonce: _YGLEc +.. section: Core and Builtins + +Fixed a crash due to incorrect handling of weak references in +``collections.OrderedDict`` classes. Patch by Pablo Galindo. + +.. + +.. bpo: 1635741 +.. date: 2020-02-22-14-33-59 +.. nonce: BTJ0cX +.. section: Core and Builtins + +Port audioop extension module to multiphase initialization (:pep:`489`). + +.. + +.. bpo: 39702 +.. date: 2020-02-20-08-12-52 +.. nonce: 4_AmyF +.. section: Core and Builtins + +Relax :term:`decorator` grammar restrictions to allow any valid expression +(:pep:`614`). + +.. + +.. bpo: 38091 +.. date: 2020-02-14-23-10-07 +.. nonce: pwR0K7 +.. section: Core and Builtins + +Tweak import deadlock detection code to not deadlock itself. + +.. + +.. bpo: 1635741 +.. date: 2020-02-05-07-55-57 +.. nonce: H_tCC9 +.. section: Core and Builtins + +Port _locale extension module to multiphase initialization (:pep:`489`). + +.. + +.. bpo: 39087 +.. date: 2020-02-03-21-12-39 +.. nonce: YnbUpL +.. section: Core and Builtins + +Optimize :c:func:`PyUnicode_AsUTF8` and :c:func:`PyUnicode_AsUTF8AndSize` +slightly when they need to create internal UTF-8 cache. + +.. + +.. bpo: 39520 +.. date: 2020-02-02-00-12-07 +.. nonce: uicBq6 +.. section: Core and Builtins + +Fix unparsing of ext slices with no items (``foo[:,]``). Patch by Batuhan +Taskaya. + +.. + +.. bpo: 39220 +.. date: 2020-01-06-13-58-37 +.. nonce: KGFovE +.. section: Core and Builtins + +Do not optimize annotations if 'from __future__ import annotations' is used. +Patch by Pablo Galindo. + +.. + +.. bpo: 35712 +.. date: 2019-05-08-11-11-45 +.. nonce: KJthus +.. section: Core and Builtins + +Using :data:`NotImplemented` in a boolean context has been deprecated. Patch +contributed by Josh Rosenberg. + +.. + +.. bpo: 22490 +.. date: 2018-09-23-16-32-58 +.. nonce: 8e0YDf +.. section: Core and Builtins + +Don't leak environment variable ``__PYVENV_LAUNCHER__`` into the interpreter +session on macOS. + +.. + +.. bpo: 39830 +.. date: 2020-03-23-05-21-13 +.. nonce: IkqU1Y +.. section: Library + +Add :class:`zipfile.Path` to ``__all__`` in the :mod:`zipfile` module. + +.. + +.. bpo: 40000 +.. date: 2020-03-18-12-54-25 +.. nonce: FnsPZC +.. section: Library + +Improved error messages for validation of ``ast.Constant`` nodes. Patch by +Batuhan Taskaya. + +.. + +.. bpo: 39999 +.. date: 2020-03-18-11-50-25 +.. nonce: 8aOXDT +.. section: Library + +``__module__`` of the AST node classes is now set to "ast" instead of +"_ast". Added docstrings for dummy AST node classes and deprecated +attributes. + +.. + +.. bpo: 39991 +.. date: 2020-03-17-12-40-38 +.. nonce: hLPPs4 +.. section: Library + +:func:`uuid.getnode` now skips IPv6 addresses with the same string length +than a MAC address (17 characters): only use MAC addresses. + +.. + +.. bpo: 39988 +.. date: 2020-03-17-09-35-00 +.. nonce: kXGl35 +.. section: Library + +Deprecated ``ast.AugLoad`` and ``ast.AugStore`` node classes because they +are no longer used. + +.. + +.. bpo: 39656 +.. date: 2020-03-16-11-38-45 +.. nonce: MaNOgm +.. section: Library + +Ensure ``bin/python3.#`` is always present in virtual environments on POSIX +platforms - by Anthony Sottile. + +.. + +.. bpo: 39969 +.. date: 2020-03-15-17-56-48 +.. nonce: 6snm0c +.. section: Library + +Deprecated ``ast.Param`` node class because it's no longer used. Patch by +Batuhan Taskaya. + +.. + +.. bpo: 39360 +.. date: 2020-03-15-05-41-05 +.. nonce: cmcU5p +.. section: Library + +Ensure all workers exit when finalizing a :class:`multiprocessing.Pool` +implicitly via the module finalization handlers of multiprocessing. This +fixes a deadlock situation that can be experienced when the Pool is not +properly finalized via the context manager or a call to +``multiprocessing.Pool.terminate``. Patch by Batuhan Taskaya and Pablo +Galindo. + +.. + +.. bpo: 35370 +.. date: 2020-03-13-14-41-28 +.. nonce: df50Q7 +.. section: Library + +sys.settrace(), sys.setprofile() and _lsprof.Profiler.enable() now properly +report :c:func:`PySys_Audit` error if "sys.setprofile" or "sys.settrace" +audit event is denied. + +.. + +.. bpo: 39936 +.. date: 2020-03-12-21-59-47 +.. nonce: Ca9IKe +.. section: Library + +AIX: Fix _aix_support module when the subprocess is not available, when +building Python from scratch. It now uses new private _bootsubprocess +module, rather than having two implementations depending if subprocess is +available or not. So _aix_support.aix_platform() result is now the same if +subprocess is available or not. + +.. + +.. bpo: 36144 +.. date: 2020-03-12-11-55-16 +.. nonce: 9bxGH_ +.. section: Library + +:class:`collections.OrderedDict` now implements ``|`` and ``|=`` +(:pep:`584`). + +.. + +.. bpo: 39652 +.. date: 2020-03-11-23-08-25 +.. nonce: gbasrk +.. section: Library + +The column name found in ``sqlite3.Cursor.description`` is now truncated on +the first '[' only if the PARSE_COLNAMES option is set. + +.. + +.. bpo: 39915 +.. date: 2020-03-10-19-38-47 +.. nonce: CjPeiY +.. section: Library + +Ensure :attr:`unittest.mock.AsyncMock.await_args_list` has call objects in +the order of awaited arguments instead of using +:attr:`unittest.mock.Mock.call_args` which has the last value of the call. +Patch by Karthikeyan Singaravelan. + +.. + +.. bpo: 36144 +.. date: 2020-03-10-19-22-31 +.. nonce: LABm7W +.. section: Library + +Updated :data:`os.environ` and :data:`os.environb` to support :pep:`584`'s +merge (``|``) and update (``|=``) operators. + +.. + +.. bpo: 38662 +.. date: 2020-03-10-15-32-31 +.. nonce: o1DMXj +.. section: Library + +The ``ensurepip`` module now invokes ``pip`` via the ``runpy`` module. Hence +it is no longer tightly coupled with the internal API of the bundled ``pip`` +version, allowing easier updates to a newer ``pip`` version both internally +and for distributors. + +.. + +.. bpo: 38075 +.. date: 2020-03-10-12-52-06 +.. nonce: qbESAF +.. section: Library + +Fix the :meth:`random.Random.seed` method when a :class:`bool` is passed as +the seed. + +.. + +.. bpo: 39916 +.. date: 2020-03-09-18-56-27 +.. nonce: BHHyp3 +.. section: Library + +More reliable use of ``os.scandir()`` in ``Path.glob()``. It no longer emits +a ResourceWarning when interrupted. + +.. + +.. bpo: 39850 +.. date: 2020-03-09-01-45-06 +.. nonce: eaJNIE +.. section: Library + +:mod:`multiprocessing` now supports abstract socket addresses (if abstract +sockets are supported in the running platform). When creating arbitrary +addresses (like when default-constructing +:class:`multiprocessing.connection.Listener` objects) abstract sockets are +preferred to avoid the case when the temporary-file-generated address is too +large for an AF_UNIX socket address. Patch by Pablo Galindo. + +.. + +.. bpo: 36287 +.. date: 2020-03-08-09-53-55 +.. nonce: mxr5m8 +.. section: Library + +:func:`ast.dump()` no longer outputs optional fields and attributes with +default values. The default values for optional fields and attributes of AST +nodes are now set as class attributes (e.g. ``Constant.kind`` is set to +``None``). + +.. + +.. bpo: 39889 +.. date: 2020-03-07-16-44-51 +.. nonce: 3RYqeX +.. section: Library + +Fixed :func:`ast.unparse` for extended slices containing a single element +(e.g. ``a[i:j,]``). Remove redundant tuples when index with a tuple (e.g. +``a[i, j]``). + +.. + +.. bpo: 39828 +.. date: 2020-03-05-00-57-49 +.. nonce: yWq9NJ +.. section: Library + +Fix :mod:`json.tool` to catch :exc:`BrokenPipeError`. Patch by Donghee Na. + +.. + +.. bpo: 13487 +.. date: 2020-03-04-16-10-59 +.. nonce: gqe4Fb +.. section: Library + +Avoid a possible *"RuntimeError: dictionary changed size during iteration"* +from :func:`inspect.getmodule` when it tried to loop through +:data:`sys.modules`. + +.. + +.. bpo: 39674 +.. date: 2020-03-03-16-21-41 +.. nonce: HJVkD5 +.. section: Library + +Revert "bpo-37330: open() no longer accept 'U' in file mode". The "U" mode +of open() is kept in Python 3.9 to ease transition from Python 2.7, but will +be removed in Python 3.10. + +.. + +.. bpo: 28577 +.. date: 2020-03-02-23-52-38 +.. nonce: EK91ae +.. section: Library + +The hosts method on 32-bit prefix length IPv4Networks and 128-bit prefix +IPv6Networks now returns a list containing the single Address instead of an +empty list. + +.. + +.. bpo: 39826 +.. date: 2020-03-02-15-15-01 +.. nonce: DglHk7 +.. section: Library + +Add getConnection method to logging HTTPHandler to enable custom +connections. + +.. + +.. bpo: 39763 +.. date: 2020-03-02-14-43-19 +.. nonce: 5a822c +.. section: Library + +Reimplement ``distutils.spawn.spawn`` function with the +:mod:`subprocess` module. + +.. + +.. bpo: 39794 +.. date: 2020-02-29-19-17-39 +.. nonce: 7VjatS +.. section: Library + +Add --without-decimal-contextvar build option. This enables a thread-local +rather than a coroutine local context. + +.. + +.. bpo: 36144 +.. date: 2020-02-29-15-54-08 +.. nonce: 4GgTZs +.. section: Library + +:class:`collections.defaultdict` now implements ``|`` (:pep:`584`). + +.. + +.. bpo: 39517 +.. date: 2020-02-29-11-20-50 +.. nonce: voQZb8 +.. section: Library + +Fix runpy.run_path() when using pathlike objects + +.. + +.. bpo: 39775 +.. date: 2020-02-28-16-42-16 +.. nonce: IuSvVb +.. section: Library + +Change ``inspect.Signature.parameters`` back to ``collections.OrderedDict``. +This was changed to ``dict`` in Python 3.9.0a4. + +.. + +.. bpo: 39678 +.. date: 2020-02-28-12-59-30 +.. nonce: 3idfxM +.. section: Library + +Refactor queue_manager in :class:`concurrent.futures.ProcessPoolExecutor` to +make it easier to maintain. + +.. + +.. bpo: 39764 +.. date: 2020-02-27-18-21-07 +.. nonce: wqPk68 +.. section: Library + +Fix AttributeError when calling get_stack on a PyAsyncGenObject Task + +.. + +.. bpo: 39769 +.. date: 2020-02-27-00-40-21 +.. nonce: hJmxu4 +.. section: Library + +The :func:`compileall.compile_dir` function's *ddir* parameter and the +compileall command line flag `-d` no longer write the wrong pathname to the +generated pyc file for submodules beneath the root of the directory tree +being compiled. This fixes a regression introduced with Python 3.5. + +.. + +.. bpo: 36144 +.. date: 2020-02-25-09-28-06 +.. nonce: Rbvvi7 +.. section: Library + +:class:`types.MappingProxyType` objects now support the merge (``|``) +operator from :pep:`584`. + +.. + +.. bpo: 38691 +.. date: 2020-02-23-02-09-03 +.. nonce: oND8Sk +.. section: Library + +The :mod:`importlib` module now ignores the :envvar:`PYTHONCASEOK` +environment variable when the :option:`-E` or :option:`-I` command line +options are being used. + +.. + +.. bpo: 39719 +.. date: 2020-02-21-22-35-57 +.. nonce: 2jLy1C +.. section: Library + +Remove :meth:`tempfile.SpooledTemporaryFile.softspace` as files no longer +have the ``softspace`` attribute in Python 3. Patch by Shantanu. + +.. + +.. bpo: 39667 +.. date: 2020-02-17-22-38-15 +.. nonce: QuzEHH +.. section: Library + +Improve pathlib.Path compatibility on zipfile.Path and correct performance +degradation as found in zipp 3.0. + +.. + +.. bpo: 39638 +.. date: 2020-02-15-20-38-11 +.. nonce: wm_RS3 +.. section: Library + +Keep ASDL signatures in the docstrings for ``AST`` nodes. Patch by Batuhan +Taskaya + +.. + +.. bpo: 39639 +.. date: 2020-02-15-15-29-34 +.. nonce: 3mqJjm +.. section: Library + +Deprecated ``ast.Suite`` node class because it's no longer used. Patch by +Batuhan Taskaya. + +.. + +.. bpo: 39609 +.. date: 2020-02-11-19-45-31 +.. nonce: dk40Uw +.. section: Library + +Add thread_name_prefix to default asyncio executor + +.. + +.. bpo: 39548 +.. date: 2020-02-06-05-33-52 +.. nonce: DF4FFe +.. section: Library + +Fix handling of header in :class:`urllib.request.AbstractDigestAuthHandler` +when the optional ``qop`` parameter is not present. + +.. + +.. bpo: 39509 +.. date: 2020-02-01-00-03-06 +.. nonce: -YxUSf +.. section: Library + +HTTP status codes ``103 EARLY_HINTS`` and ``425 TOO_EARLY`` are added to +:class:`http.HTTPStatus`. Patch by Donghee Na. + +.. + +.. bpo: 39507 +.. date: 2020-01-31-14-24-05 +.. nonce: 3oln1a +.. section: Library + +Adding HTTP status 418 "I'm a Teapot" to HTTPStatus in http library. Patch +by Ross Rhodes. + +.. + +.. bpo: 39495 +.. date: 2020-01-30-07-02-02 +.. nonce: 8LsIRN +.. section: Library + +Remove default value from *attrs* parameter of +:meth:`xml.etree.ElementTree.TreeBuilder.start` for consistency between +Python and C implementations. + +.. + +.. bpo: 38971 +.. date: 2019-12-20-16-06-28 +.. nonce: fKRYlF +.. section: Library + +Open issue in the BPO indicated a desire to make the implementation of +codecs.open() at parity with io.open(), which implements a try/except to +assure file stream gets closed before an exception is raised. + +.. + +.. bpo: 38641 +.. date: 2019-10-30-15-31-09 +.. nonce: HrTL9k +.. section: Library + +Added starred expressions support to ``return`` and ``yield`` statements for +``lib2to3``. Patch by Vlad Emelianov. + +.. + +.. bpo: 37534 +.. date: 2019-08-20-00-02-37 +.. nonce: TvjAUi +.. section: Library + +When using minidom module to generate XML documents the ability to add +Standalone Document Declaration is added. All the changes are made to +generate a document in compliance with Extensible Markup Language (XML) 1.0 +(Fifth Edition) W3C Recommendation (available here: +https://www.w3.org/TR/xml/#sec-prolog-dtd). + +.. + +.. bpo: 34788 +.. date: 2019-07-17-08-26-14 +.. nonce: pwV1OK +.. section: Library + +Add support for scoped IPv6 addresses to :mod:`ipaddress`. Patch by +Oleksandr Pavliuk. + +.. + +.. bpo: 34822 +.. date: 2018-09-27-19-31-47 +.. nonce: EztBhL +.. section: Library + +Simplified AST for subscription. Simple indices are now represented by their +value, extended slices are represented as tuples. :mod:`ast` classes +``Index`` and ``ExtSlice`` are considered deprecated and will be removed in +future Python versions. In the meantime, ``Index(value)`` now returns a +``value`` itself, ``ExtSlice(slices)`` returns ``Tuple(slices, Load())``. + +.. + +.. bpo: 39868 +.. date: 2020-03-05-16-29-03 +.. nonce: JQoHhO +.. section: Documentation + +Updated the Language Reference for :pep:`572`. + +.. + +.. bpo: 13790 +.. date: 2020-02-28-14-39-25 +.. nonce: hvLaRI +.. section: Documentation + +Change 'string' to 'specification' in format doc. + +.. + +.. bpo: 17422 +.. date: 2020-02-27-17-35-27 +.. nonce: eS1hVh +.. section: Documentation + +The language reference no longer restricts default class namespaces to dicts +only. + +.. + +.. bpo: 39530 +.. date: 2020-02-23-13-26-40 +.. nonce: _bCvzQ +.. section: Documentation + +Fix misleading documentation about mixed-type numeric comparisons. + +.. + +.. bpo: 39718 +.. date: 2020-02-21-22-05-20 +.. nonce: xtBoSi +.. section: Documentation + +Update :mod:`token` documentation to reflect additions in Python 3.8 + +.. + +.. bpo: 39677 +.. date: 2020-02-18-14-28-31 +.. nonce: vNHqoX +.. section: Documentation + +Changed operand name of **MAKE_FUNCTION** from *argc* to *flags* for module +:mod:`dis` + +.. + +.. bpo: 40019 +.. date: 2020-03-20-00-30-36 +.. nonce: zOqHpQ +.. section: Tests + +test_gdb now skips tests if it detects that gdb failed to read debug +information because the Python binary is optimized. + +.. + +.. bpo: 27807 +.. date: 2020-03-18-16-04-33 +.. nonce: 9gKjET +.. section: Tests + +``test_site.test_startup_imports()`` is now skipped if a path of +:data:`sys.path` contains a ``.pth`` file. + +.. + +.. bpo: 26067 +.. date: 2020-03-16-20-54-55 +.. nonce: m18_VV +.. section: Tests + +Do not fail test_shutil test_chown test when uid or gid of user cannot be +resolved to a name. + +.. + +.. bpo: 39855 +.. date: 2020-03-04-23-03-01 +.. nonce: Ql5xv8 +.. section: Tests + +test_subprocess.test_user() now skips the test on an user name if the user +name doesn't exist. For example, skip the test if the user "nobody" doesn't +exist on Linux. + +.. + +.. bpo: 39761 +.. date: 2020-03-03-15-56-07 +.. nonce: k10aGe +.. section: Build + +Fix build with DTrace but without additional DFLAGS. + +.. + +.. bpo: 39763 +.. date: 2020-03-02-14-44-09 +.. nonce: GGEwhH +.. section: Build + +setup.py now uses a basic implementation of the :mod:`subprocess` module if +the :mod:`subprocess` module is not available: before required C extension +modules are built. + +.. + +.. bpo: 1294959 +.. date: 2020-02-06-18-08-25 +.. nonce: AZPg4R +.. section: Build + +Add ``--with-platlibdir`` option to the configure script: name of the +platform-specific library directory, stored in the new +:data:`sys.platlibdir` attribute. It is used to build the path of +platform-specific extension modules and the path of the standard library. It +is equal to ``"lib"`` on most platforms. On Fedora and SuSE, it is equal to +``"lib64"`` on 64-bit platforms. Patch by Jan Matějek, Matěj Cepl, +Charalampos Stratakis and Victor Stinner. + +.. + +.. bpo: 39930 +.. date: 2020-03-11-10-15-56 +.. nonce: LGHw1j +.. section: Windows + +Ensures the required :file:`vcruntime140.dll` is included in install +packages. + +.. + +.. bpo: 39847 +.. date: 2020-03-04-17-05-11 +.. nonce: C3N2m3 +.. section: Windows + +Avoid hang when computer is hibernated whilst waiting for a mutex (for +lock-related objects from :mod:`threading`) around 49-day uptime. + +.. + +.. bpo: 38597 +.. date: 2020-03-01-15-04-54 +.. nonce: MnHdYl +.. section: Windows + +``distutils`` will no longer statically link :file:`vcruntime140.dll` +when a redistributable version is unavailable. All future releases of +CPython will include a copy of this DLL to ensure distributed extensions can +continue to load. + +.. + +.. bpo: 38380 +.. date: 2020-02-28-23-51-27 +.. nonce: TpOBCj +.. section: Windows + +Update Windows builds to use SQLite 3.31.1 + +.. + +.. bpo: 39789 +.. date: 2020-02-28-22-46-09 +.. nonce: 67XRoP +.. section: Windows + +Update Windows release build machines to Visual Studio 2019 (MSVC 14.2). + +.. + +.. bpo: 34803 +.. date: 2020-02-25-18-43-34 +.. nonce: S3VcS0 +.. section: Windows + +Package for nuget.org now includes repository reference and bundled icon +image. + +.. + +.. bpo: 38380 +.. date: 2020-02-28-23-51-47 +.. nonce: u-ySyA +.. section: macOS + +Update macOS builds to use SQLite 3.31.1 + +.. + +.. bpo: 27115 +.. date: 2020-03-09-02-45-12 +.. nonce: 8hSHMo +.. section: IDLE + +For 'Go to Line', use a Query box subclass with IDLE standard behavior and +improved error checking. + +.. + +.. bpo: 39885 +.. date: 2020-03-08-14-27-36 +.. nonce: 29ERiR +.. section: IDLE + +Since clicking to get an IDLE context menu moves the cursor, any text +selection should be and now is cleared. + +.. + +.. bpo: 39852 +.. date: 2020-03-06-01-55-14 +.. nonce: QjA1qF +.. section: IDLE + +Edit "Go to line" now clears any selection, preventing accidental deletion. +It also updates Ln and Col on the status bar. + +.. + +.. bpo: 39781 +.. date: 2020-02-27-22-17-09 +.. nonce: bbYBeL +.. section: IDLE + +Selecting code context lines no longer causes a jump. + +.. + +.. bpo: 36184 +.. date: 2020-03-09-13-28-13 +.. nonce: BMPJ0D +.. section: Tools/Demos + +Port python-gdb.py to FreeBSD. python-gdb.py now checks for "take_gil" +function name to check if a frame tries to acquire the GIL, instead of +checking for "pthread_cond_timedwait" which is specific to Linux and can be +a different condition than the GIL. + +.. + +.. bpo: 38080 +.. date: 2019-09-18-13-49-56 +.. nonce: Nbl7lF +.. section: Tools/Demos + +Added support to fix ``getproxies`` in the :mod:`lib2to3.fixes.fix_urllib` +module. Patch by José Roberto Meza Cabrera. + +.. + +.. bpo: 40024 +.. date: 2020-03-20-18-41-33 +.. nonce: 9zHpve +.. section: C API + +Add :c:func:`PyModule_AddType` helper function: add a type to a module. +Patch by Donghee Na. + +.. + +.. bpo: 39946 +.. date: 2020-03-20-17-05-52 +.. nonce: 3NS-Ls +.. section: C API + +Remove ``_PyRuntime.getframe`` hook and remove ``_PyThreadState_GetFrame`` +macro which was an alias to ``_PyRuntime.getframe``. They were only exposed +by the internal C API. Remove also ``PyThreadFrameGetter`` type. + +.. + +.. bpo: 39947 +.. date: 2020-03-20-14-55-09 +.. nonce: W7uCJ3 +.. section: C API + +Add :c:func:`PyThreadState_GetFrame` function: get the current frame of a +Python thread state. + +.. + +.. bpo: 37207 +.. date: 2020-03-14-01-56-03 +.. nonce: R3jaTy +.. section: C API + +Add _PyArg_NoKwnames helper function. Patch by Donghee Na. + +.. + +.. bpo: 39947 +.. date: 2020-03-13-18-10-58 +.. nonce: gmEAaU +.. section: C API + +Add :c:func:`PyThreadState_GetInterpreter`: get the interpreter of a Python +thread state. + +.. + +.. bpo: 39947 +.. date: 2020-03-13-17-43-00 +.. nonce: 1Cu_d2 +.. section: C API + +Add :c:func:`PyInterpreterState_Get` function to the limited C API. + +.. + +.. bpo: 35370 +.. date: 2020-03-13-16-44-23 +.. nonce: sXRA-r +.. section: C API + +If :c:func:`PySys_Audit` fails in :c:func:`PyEval_SetProfile` or +:c:func:`PyEval_SetTrace`, log the error as an unraisable exception. + +.. + +.. bpo: 39947 +.. date: 2020-03-13-00-15-19 +.. nonce: w3dIru +.. section: C API + +Move the static inline function flavor of Py_EnterRecursiveCall() and +Py_LeaveRecursiveCall() to the internal C API: they access PyThreadState +attributes. The limited C API provides regular functions which hide +implementation details. + +.. + +.. bpo: 39947 +.. date: 2020-03-12-23-47-57 +.. nonce: -nCdFV +.. section: C API + +Py_TRASHCAN_BEGIN_CONDITION and Py_TRASHCAN_END macro no longer access +PyThreadState attributes, but call new private _PyTrash_begin() and +_PyTrash_end() functions which hide implementation details. + +.. + +.. bpo: 39884 +.. date: 2020-03-12-00-27-26 +.. nonce: CGOJBO +.. section: C API + +:c:func:`PyDescr_NewMethod` and :c:func:`PyCFunction_NewEx` now include the +method name in the SystemError "bad call flags" error message to ease debug. + +.. + +.. bpo: 39877 +.. date: 2020-03-10-00-18-16 +.. nonce: GOYtIm +.. section: C API + +Deprecated :c:func:`!PyEval_InitThreads` and +:c:func:`!PyEval_ThreadsInitialized`. Calling :c:func:`!PyEval_InitThreads` +now does nothing. + +.. + +.. bpo: 38249 +.. date: 2020-03-09-20-27-19 +.. nonce: IxYbQy +.. section: C API + +:c:macro:`Py_UNREACHABLE` is now implemented with +``__builtin_unreachable()`` and analogs in release mode. + +.. + +.. bpo: 38643 +.. date: 2020-03-08-22-56-22 +.. nonce: k2ixx6 +.. section: C API + +:c:func:`PyNumber_ToBase` now raises a :exc:`SystemError` instead of +crashing when called with invalid base. + +.. + +.. bpo: 39882 +.. date: 2020-03-06-23-56-04 +.. nonce: Iqhcqm +.. section: C API + +The :c:func:`Py_FatalError` function is replaced with a macro which logs +automatically the name of the current function, unless the +``Py_LIMITED_API`` macro is defined. + +.. + +.. bpo: 39824 +.. date: 2020-03-02-11-29-45 +.. nonce: 71_ZMn +.. section: C API + +Extension modules: :c:member:`~PyModuleDef.m_traverse`, +:c:member:`~PyModuleDef.m_clear` and :c:member:`~PyModuleDef.m_free` +functions of :c:type:`PyModuleDef` are no longer called if the module state +was requested but is not allocated yet. This is the case immediately after +the module is created and before the module is executed +(:c:data:`Py_mod_exec` function). More precisely, these functions are not +called if :c:member:`~PyModuleDef.m_size` is greater than 0 and the module +state (as returned by :c:func:`PyModule_GetState`) is ``NULL``. + +Extension modules without module state (``m_size <= 0``) are not affected. + +.. + +.. bpo: 38913 +.. date: 2020-02-25-20-10-34 +.. nonce: siF1lS +.. section: C API + +Fixed segfault in ``Py_BuildValue()`` called with a format containing "#" +and undefined PY_SSIZE_T_CLEAN whwn an exception is set. + +.. + +.. bpo: 38500 +.. date: 2019-11-22-14-06-28 +.. nonce: nPEdjH +.. section: C API + +Add a private API to get and set the frame evaluation function: add +:c:func:`_PyInterpreterState_GetEvalFrameFunc` and +:c:func:`_PyInterpreterState_SetEvalFrameFunc` C functions. The +:c:type:`_PyFrameEvalFunction` function type now takes a *tstate* parameter. diff --git a/Misc/NEWS.d/3.9.0a6.rst b/Misc/NEWS.d/3.9.0a6.rst new file mode 100644 index 00000000..fec792a9 --- /dev/null +++ b/Misc/NEWS.d/3.9.0a6.rst @@ -0,0 +1,1211 @@ +.. bpo: 40121 +.. date: 2020-03-30-23-16-25 +.. nonce: p2LIio +.. release date: 2020-04-27 +.. section: Security + +Fixes audit events raised on creating a new socket. + +.. + +.. bpo: 39073 +.. date: 2020-03-15-01-28-36 +.. nonce: 6Szd3i +.. section: Security + +Disallow CR or LF in email.headerregistry.Address arguments to guard against +header injection attacks. + +.. + +.. bpo: 39503 +.. date: 2020-01-30-16-15-29 +.. nonce: B299Yq +.. section: Security + +CVE-2020-8492: The :class:`~urllib.request.AbstractBasicAuthHandler` class +of the :mod:`urllib.request` module uses an inefficient regular expression +which can be exploited by an attacker to cause a denial of service. Fix the +regex to prevent the catastrophic backtracking. Vulnerability reported by +Ben Caller and Matt Schwager. + +.. + +.. bpo: 40313 +.. date: 2020-04-20-23-58-35 +.. nonce: USVRW8 +.. section: Core and Builtins + +Improve the performance of bytes.hex(). + +.. + +.. bpo: 40334 +.. date: 2020-04-20-14-06-19 +.. nonce: CTLGEp +.. section: Core and Builtins + +Switch to a new parser, based on PEG. For more details see PEP 617. To +temporarily switch back to the old parser, use ``-X oldparser`` or +``PYTHONOLDPARSER=1``. In Python 3.10 we will remove the old parser +completely, including the ``parser`` module (already deprecated) and +anything that depends on it. + +.. + +.. bpo: 40267 +.. date: 2020-04-14-18-54-50 +.. nonce: Q2N6Bw +.. section: Core and Builtins + +Fix the tokenizer to display the correct error message, when there is a +SyntaxError on the last input character and no newline follows. It used to +be `unexpected EOF while parsing`, while it should be `invalid syntax`. + +.. + +.. bpo: 39522 +.. date: 2020-04-14-18-47-00 +.. nonce: uVeIV_ +.. section: Core and Builtins + +Correctly unparse explicit ``u`` prefix for strings when postponed +evaluation for annotations activated. Patch by Batuhan Taskaya. + +.. + +.. bpo: 40246 +.. date: 2020-04-11-17-52-03 +.. nonce: vXPze5 +.. section: Core and Builtins + +Report a specialized error message, `invalid string prefix`, when the +tokenizer encounters a string with an invalid prefix. + +.. + +.. bpo: 40082 +.. date: 2020-04-08-22-33-24 +.. nonce: WI3-lu +.. section: Core and Builtins + +Fix the signal handler: it now always uses the main interpreter, rather than +trying to get the current Python thread state. + +.. + +.. bpo: 37388 +.. date: 2020-04-07-15-44-29 +.. nonce: stlxBq +.. section: Core and Builtins + +str.encode() and str.decode() no longer check the encoding and errors in +development mode or in debug mode during Python finalization. The codecs +machinery can no longer work on very late calls to str.encode() and +str.decode(). + +.. + +.. bpo: 40077 +.. date: 2020-04-04-12-43-19 +.. nonce: m15TTX +.. section: Core and Builtins + +Fix possible refleaks in :mod:`_json`, memo of PyScannerObject should be +traversed. + +.. + +.. bpo: 37207 +.. date: 2020-04-02-00-25-19 +.. nonce: ZTPmKJ +.. section: Core and Builtins + +Speed up calls to ``dict()`` by using the :pep:`590` ``vectorcall`` calling +convention. + +.. + +.. bpo: 40141 +.. date: 2020-04-01-21-50-37 +.. nonce: 8fCRVj +.. section: Core and Builtins + +Add column and line information to ``ast.keyword`` nodes. Patch by Pablo +Galindo. + +.. + +.. bpo: 1635741 +.. date: 2020-04-01-00-08-18 +.. nonce: bhGWam +.. section: Core and Builtins + +Port :mod:`resource` to multiphase initialization (:pep:`489`). + +.. + +.. bpo: 1635741 +.. date: 2020-03-31-22-15-04 +.. nonce: 8Ir1a0 +.. section: Core and Builtins + +Port :mod:`math` to multiphase initialization (:pep:`489`). + +.. + +.. bpo: 1635741 +.. date: 2020-03-31-21-12-27 +.. nonce: S2nkF3 +.. section: Core and Builtins + +Port _uuid module to multiphase initialization (:pep:`489`). + +.. + +.. bpo: 40077 +.. date: 2020-03-27-01-11-08 +.. nonce: wT002V +.. section: Core and Builtins + +Convert json module to use :c:func:`PyType_FromSpec`. + +.. + +.. bpo: 40067 +.. date: 2020-03-25-20-34-01 +.. nonce: 0bFda2 +.. section: Core and Builtins + +Improve the error message for multiple star expressions in an assignment. +Patch by Furkan Onder + +.. + +.. bpo: 1635741 +.. date: 2020-03-24-22-26-26 +.. nonce: AB38ot +.. section: Core and Builtins + +Port _functools module to multiphase initialization (PEP 489). Patch by +Paulo Henrique Silva. + +.. + +.. bpo: 1635741 +.. date: 2020-03-24-22-17-12 +.. nonce: jWaMRV +.. section: Core and Builtins + +Port operator module to multiphase initialization (PEP 489). Patch by Paulo +Henrique Silva. + +.. + +.. bpo: 20526 +.. date: 2020-03-23-18-08-34 +.. nonce: NHNZIv +.. section: Core and Builtins + +Fix :c:func:`PyThreadState_Clear()`. ``PyThreadState.frame`` is a borrowed +reference, not a strong reference: ``PyThreadState_Clear()`` must not call +``Py_CLEAR(tstate->frame)``. + +.. + +.. bpo: 1635741 +.. date: 2020-03-22-01-01-41 +.. nonce: gR7Igp +.. section: Core and Builtins + +Port time module to multiphase initialization (:pep:`489`). Patch by Paulo +Henrique Silva. + +.. + +.. bpo: 1635741 +.. date: 2020-03-20-13-42-35 +.. nonce: bhIu5M +.. section: Core and Builtins + +Port _weakref extension module to multiphase initialization (:pep:`489`). + +.. + +.. bpo: 40020 +.. date: 2020-03-19-21-53-41 +.. nonce: n-26G7 +.. section: Core and Builtins + +Fix a leak and subsequent crash in parsetok.c caused by realloc misuse on a +rare codepath. + +.. + +.. bpo: 39939 +.. date: 2020-03-11-19-17-36 +.. nonce: NwCnAM +.. section: Core and Builtins + +Added str.removeprefix and str.removesuffix methods and corresponding bytes, +bytearray, and collections.UserString methods to remove affixes from a +string if present. See :pep:`616` for a full description. Patch by Dennis +Sweeney. + +.. + +.. bpo: 39481 +.. date: 2020-01-28-17-19-18 +.. nonce: rqSeGl +.. section: Core and Builtins + +Implement PEP 585. This supports list[int], tuple[str, ...] etc. + +.. + +.. bpo: 32894 +.. date: 2019-12-01-21-36-49 +.. nonce: 5g_UQr +.. section: Core and Builtins + +Support unparsing of infinity numbers in postponed annotations. Patch by +Batuhan Taşkaya. + +.. + +.. bpo: 37207 +.. date: 2019-06-09-10-54-31 +.. nonce: bLjgLS +.. section: Core and Builtins + +Speed up calls to ``list()`` by using the :pep:`590` ``vectorcall`` calling +convention. Patch by Mark Shannon. + +.. + +.. bpo: 40398 +.. date: 2020-04-26-22-25-36 +.. nonce: OdXnR3 +.. section: Library + +:func:`typing.get_args` now always returns an empty tuple for special +generic aliases. + +.. + +.. bpo: 40396 +.. date: 2020-04-26-19-07-40 +.. nonce: Fn-is1 +.. section: Library + +Functions :func:`typing.get_origin`, :func:`typing.get_args` and +:func:`typing.get_type_hints` support now generic aliases like +``list[int]``. + +.. + +.. bpo: 38061 +.. date: 2020-04-24-01-55-00 +.. nonce: XmULB3 +.. section: Library + +Optimize the :mod:`subprocess` module on FreeBSD using ``closefrom()``. A +single ``close(fd)`` syscall is cheap, but when ``sysconf(_SC_OPEN_MAX)`` is +high, the loop calling ``close(fd)`` on each file descriptor can take +several milliseconds. + +The workaround on FreeBSD to improve performance was to load and mount the +fdescfs kernel module, but this is not enabled by default. + +Initial patch by Ed Maste (emaste), Conrad Meyer (cem), Kyle Evans (kevans) +and Kubilay Kocak (koobs): +https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=242274 + +.. + +.. bpo: 38061 +.. date: 2020-04-24-01-27-08 +.. nonce: cdlkMz +.. section: Library + +On FreeBSD, ``os.closerange(fd_low, fd_high)`` now calls +``closefrom(fd_low)`` if *fd_high* is greater than or equal to +``sysconf(_SC_OPEN_MAX)``. + +Initial patch by Ed Maste (emaste), Conrad Meyer (cem), Kyle Evans (kevans) +and Kubilay Kocak (koobs): +https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=242274 + +.. + +.. bpo: 40360 +.. date: 2020-04-22-20-55-17 +.. nonce: Er8sv- +.. section: Library + +The :mod:`lib2to3` module is pending deprecation due to :pep:`617`. + +.. + +.. bpo: 40138 +.. date: 2020-04-22-00-05-10 +.. nonce: i_oGqa +.. section: Library + +Fix the Windows implementation of :func:`os.waitpid` for exit code larger +than ``INT_MAX >> 8``. The exit status is now interpreted as an unsigned +number. + +.. + +.. bpo: 39942 +.. date: 2020-04-20-20-16-02 +.. nonce: NvGnTc +.. section: Library + +Set "__main__" as the default module name when "__name__" is missing in +:class:`typing.TypeVar`. Patch by Weipeng Hong. + +.. + +.. bpo: 40275 +.. date: 2020-04-20-19-06-55 +.. nonce: 9UcN2g +.. section: Library + +The :mod:`logging` package is now imported lazily in :mod:`unittest` only +when the :meth:`~unittest.TestCase.assertLogs` assertion is used. + +.. + +.. bpo: 40275 +.. date: 2020-04-20-18-50-25 +.. nonce: Ofk6J8 +.. section: Library + +The :mod:`asyncio` package is now imported lazily in :mod:`unittest` only +when the :class:`~unittest.IsolatedAsyncioTestCase` class is used. + +.. + +.. bpo: 40330 +.. date: 2020-04-19-17-31-29 +.. nonce: DGjoIS +.. section: Library + +In :meth:`ShareableList.__setitem__`, check the size of a new string item +after encoding it to utf-8, not before. + +.. + +.. bpo: 40148 +.. date: 2020-04-19-14-16-43 +.. nonce: pDZR6V +.. section: Library + +Added :meth:`pathlib.Path.with_stem()` to create a new Path with the stem +replaced. + +.. + +.. bpo: 40325 +.. date: 2020-04-18-19-40-00 +.. nonce: KWSvix +.. section: Library + +Deprecated support for set objects in random.sample(). + +.. + +.. bpo: 40257 +.. date: 2020-04-18-10-52-15 +.. nonce: lv4WTq +.. section: Library + +Improved help for the :mod:`typing` module. Docstrings are now shown for all +special forms and special generic aliases (like ``Union`` and ``List``). +Using ``help()`` with generic alias like ``List[int]`` will show the help +for the correspondent concrete type (``list`` in this case). + +.. + +.. bpo: 40257 +.. date: 2020-04-15-19-34-11 +.. nonce: ux8FUr +.. section: Library + +func:`inspect.getdoc` no longer returns docstring inherited from the type of +the object or from parent class if it is a class if it is not defined in the +object itself. In :mod:`pydoc` the documentation string is now shown not +only for class, function, method etc, but for any object that has its own +``__doc__`` attribute. + +.. + +.. bpo: 40287 +.. date: 2020-04-15-17-21-48 +.. nonce: -mkEJH +.. section: Library + +Fixed ``SpooledTemporaryFile.seek()`` to return the position. + +.. + +.. bpo: 40290 +.. date: 2020-04-15-16-43-48 +.. nonce: eqCMGJ +.. section: Library + +Added zscore() to statistics.NormalDist(). + +.. + +.. bpo: 40282 +.. date: 2020-04-15-10-23-52 +.. nonce: rIYJmu +.. section: Library + +Allow ``random.getrandbits(0)`` to succeed and to return 0. + +.. + +.. bpo: 40286 +.. date: 2020-04-15-00-39-25 +.. nonce: ai80FA +.. section: Library + +Add :func:`random.randbytes` function and :meth:`random.Random.randbytes` +method to generate random bytes. + +.. + +.. bpo: 40277 +.. date: 2020-04-14-21-53-18 +.. nonce: NknSaf +.. section: Library + +:func:`collections.namedtuple` now provides a human-readable repr for its +field accessors. + +.. + +.. bpo: 40270 +.. date: 2020-04-14-16-18-49 +.. nonce: XVJzeG +.. section: Library + +The included copy of sqlite3 on Windows is now compiled with the json +extension. This allows the use of functions such as ``json_object``. + +.. + +.. bpo: 29255 +.. date: 2020-04-14-11-31-07 +.. nonce: 4EcyIN +.. section: Library + +Wait in `KqueueSelector.select` when no fds are registered + +.. + +.. bpo: 40260 +.. date: 2020-04-12-21-18-56 +.. nonce: F6VWaE +.. section: Library + +Ensure :mod:`modulefinder` uses :func:`io.open_code` and respects coding +comments. + +.. + +.. bpo: 40234 +.. date: 2020-04-10-16-13-47 +.. nonce: tar4d_ +.. section: Library + +Allow again to spawn daemon threads in subinterpreters (revert change which +denied them). + +.. + +.. bpo: 39207 +.. date: 2020-04-10-01-24-58 +.. nonce: 2dE5Ox +.. section: Library + +Workers in :class:`~concurrent.futures.ProcessPoolExecutor` are now spawned +on demand, only when there are no available idle workers to reuse. This +optimizes startup overhead and reduces the amount of lost CPU time to idle +workers. Patch by Kyle Stanley. + +.. + +.. bpo: 40091 +.. date: 2020-04-07-23-26-25 +.. nonce: 5M9AW5 +.. section: Library + +Fix a hang at fork in the logging module: the new private _at_fork_reinit() +method is now used to reinitialize locks at fork in the child process. + +.. + +.. bpo: 40149 +.. date: 2020-04-07-18-06-38 +.. nonce: mMU2iu +.. section: Library + +Implement traverse and clear slots in _abc._abc_data type. + +.. + +.. bpo: 40208 +.. date: 2020-04-06-20-09-33 +.. nonce: 3rO_q7 +.. section: Library + +Remove deprecated :meth:`symtable.SymbolTable.has_exec`. + +.. + +.. bpo: 40196 +.. date: 2020-04-06-11-05-13 +.. nonce: Jqowse +.. section: Library + +Fix a bug in the :mod:`symtable` module that was causing incorrectly report +global variables as local. Patch by Pablo Galindo. + +.. + +.. bpo: 40190 +.. date: 2020-04-05-02-58-17 +.. nonce: HF3OWo +.. section: Library + +Add support for ``_SC_AIX_REALMEM`` to :func:`posix.sysconf`. + +.. + +.. bpo: 40182 +.. date: 2020-04-04-23-44-09 +.. nonce: Bf_kFN +.. section: Library + +Removed the ``_field_types`` attribute of the :class:`typing.NamedTuple` +class. + +.. + +.. bpo: 36517 +.. date: 2020-04-04-17-49-39 +.. nonce: Ilj1IJ +.. section: Library + +Multiple inheritance with :class:`typing.NamedTuple` now raises an error +instead of silently ignoring other types. + +.. + +.. bpo: 40126 +.. date: 2020-04-04-00-47-40 +.. nonce: Y-bTNP +.. section: Library + +Fixed reverting multiple patches in unittest.mock. Patcher's ``__exit__()`` +is now never called if its ``__enter__()`` is failed. Returning true from +``__exit__()`` silences now the exception. + +.. + +.. bpo: 40094 +.. date: 2020-04-02-01-13-28 +.. nonce: AeZ34K +.. section: Library + +CGIHTTPRequestHandler of http.server now logs the CGI script exit code, +rather than the CGI script exit status of os.waitpid(). For example, if the +script is killed by signal 11, it now logs: "CGI script exit code -11." + +.. + +.. bpo: 40108 +.. date: 2020-03-31-01-11-20 +.. nonce: EGDVQ_ +.. section: Library + +Improve the error message when triying to import a module using :mod:`runpy` +and incorrently use the ".py" extension at the end of the module name. Patch +by Pablo Galindo. + +.. + +.. bpo: 40094 +.. date: 2020-03-28-18-25-49 +.. nonce: v-wQIU +.. section: Library + +Add :func:`os.waitstatus_to_exitcode` function: convert a wait status to an +exit code. + +.. + +.. bpo: 40089 +.. date: 2020-03-27-17-22-34 +.. nonce: -lFsD0 +.. section: Library + +Fix threading._after_fork(): if fork was not called by a thread spawned by +threading.Thread, threading._after_fork() now creates a _MainThread instance +for _main_thread, instead of a _DummyThread instance. + +.. + +.. bpo: 40089 +.. date: 2020-03-27-16-54-29 +.. nonce: VTq_8s +.. section: Library + +Add a private ``_at_fork_reinit()`` method to :class:`_thread.Lock`, +:class:`_thread.RLock`, :class:`threading.RLock` and +:class:`threading.Condition` classes: reinitialize the lock at fork in the +child process, reset the lock to the unlocked state. Rename also the private +``_reset_internal_locks()`` method of :class:`threading.Event` to +``_at_fork_reinit()``. + +.. + +.. bpo: 25780 +.. date: 2020-03-27-08-57-46 +.. nonce: kIjVge +.. section: Library + +Expose :const:`~socket.CAN_RAW_JOIN_FILTERS` in the :mod:`socket` module. + +.. + +.. bpo: 39503 +.. date: 2020-03-25-16-02-16 +.. nonce: YmMbYn +.. section: Library + +:class:`~urllib.request.AbstractBasicAuthHandler` of :mod:`urllib.request` +now parses all WWW-Authenticate HTTP headers and accepts multiple challenges +per header: use the realm of the first Basic challenge. + +.. + +.. bpo: 39812 +.. date: 2020-03-25-00-35-48 +.. nonce: rIKnms +.. section: Library + +Removed daemon threads from :mod:`concurrent.futures` by adding an internal +`threading._register_atexit()`, which calls registered functions prior to +joining all non-daemon threads. This allows for compatibility with +subinterpreters, which don't support daemon threads. + +.. + +.. bpo: 40050 +.. date: 2020-03-24-16-17-20 +.. nonce: 6GrOlz +.. section: Library + +Fix ``importlib._bootstrap_external``: avoid creating a new ``winreg`` +builtin module if it's already available in :data:`sys.modules`, and remove +redundant imports. + +.. + +.. bpo: 40014 +.. date: 2020-03-23-17-52-00 +.. nonce: Ya70VG +.. section: Library + +Fix ``os.getgrouplist()``: if ``getgrouplist()`` function fails because the +group list is too small, retry with a larger group list. On failure, the +glibc implementation of ``getgrouplist()`` sets ``ngroups`` to the total +number of groups. For other implementations, double the group list size. + +.. + +.. bpo: 40017 +.. date: 2020-03-21-00-46-18 +.. nonce: HFpHZS +.. section: Library + +Add :const:`time.CLOCK_TAI` constant if the operating system support it. + +.. + +.. bpo: 40016 +.. date: 2020-03-19-19-40-27 +.. nonce: JWtxqJ +.. section: Library + +In re docstring, clarify the relationship between inline and argument +compile flags. + +.. + +.. bpo: 39953 +.. date: 2020-03-19-16-33-03 +.. nonce: yy5lC_ +.. section: Library + +Update internal table of OpenSSL error codes in the ``ssl`` module. + +.. + +.. bpo: 36144 +.. date: 2020-03-18-14-51-41 +.. nonce: lQm_RK +.. section: Library + +Added :pep:`584` operators to :class:`weakref.WeakValueDictionary`. + +.. + +.. bpo: 36144 +.. date: 2020-03-18-14-02-58 +.. nonce: ooyn6Z +.. section: Library + +Added :pep:`584` operators to :class:`weakref.WeakKeyDictionary`. + +.. + +.. bpo: 38891 +.. date: 2020-03-15-08-06-05 +.. nonce: 56Yokh +.. section: Library + +Fix linear runtime behaviour of the `__getitem__` and `__setitem__` methods +in :class:`multiprocessing.shared_memory.ShareableList`. This avoids +quadratic performance when iterating a `ShareableList`. Patch by Thomas +Krennwallner. + +.. + +.. bpo: 39682 +.. date: 2020-03-08-11-00-01 +.. nonce: AxXZNz +.. section: Library + +Remove undocumented support for *closing* a `pathlib.Path` object via its +context manager. The context manager magic methods remain, but they are now +a no-op, making `Path` objects immutable. + +.. + +.. bpo: 36144 +.. date: 2020-03-07-11-26-08 +.. nonce: FG9jqy +.. section: Library + +Added :pep:`584` operators (``|`` and ``|=``) to +:class:`collections.ChainMap`. + +.. + +.. bpo: 39011 +.. date: 2020-02-12-01-48-51 +.. nonce: hGve_t +.. section: Library + +Normalization of line endings in ElementTree attributes was removed, as line +endings which were replaced by entity numbers should be preserved in +original form. + +.. + +.. bpo: 38410 +.. date: 2019-10-09-08-14-25 +.. nonce: _YyoMV +.. section: Library + +Properly handle :func:`sys.audit` failures in +:func:`sys.set_asyncgen_hooks`. + +.. + +.. bpo: 36541 +.. date: 2019-06-18-19-38-27 +.. nonce: XI8mi1 +.. section: Library + +lib2to3 now recognizes named assignment expressions (the walrus operator, +``:=``) + +.. + +.. bpo: 35967 +.. date: 2019-04-14-14-11-07 +.. nonce: KUMT9E +.. section: Library + +In platform, delay the invocation of 'uname -p' until the processor +attribute is requested. + +.. + +.. bpo: 35113 +.. date: 2018-11-03-16-18-20 +.. nonce: vwvWKG +.. section: Library + +:meth:`inspect.getsource` now returns correct source code for inner class +with same name as module level class. Decorators are also returned as part +of source of the class. Patch by Karthikeyan Singaravelan. + +.. + +.. bpo: 33262 +.. date: 2018-04-17-13-23-29 +.. nonce: vHC7YQ +.. section: Library + +Deprecate passing None as an argument for :func:`shlex.split()`'s ``s`` +parameter. Patch by Zackery Spytz. + +.. + +.. bpo: 31758 +.. date: 2017-10-14-21-02-40 +.. nonce: 563ZZb +.. section: Library + +Prevent crashes when using an uninitialized ``_elementtree.XMLParser`` +object. Patch by Oren Milman. + +.. + +.. bpo: 27635 +.. date: 2020-04-01-00-27-03 +.. nonce: VwxUty +.. section: Documentation + +The pickle documentation incorrectly claimed that ``__new__`` isn't called +by default when unpickling. + +.. + +.. bpo: 39879 +.. date: 2020-03-16-18-12-02 +.. nonce: CnQ7Cv +.. section: Documentation + +Updated :ref:`datamodel` docs to include :func:`dict` insertion order +preservation. Patch by Furkan Onder and Samy Lahfa. + +.. + +.. bpo: 38387 +.. date: 2019-10-06-23-44-15 +.. nonce: fZoq0S +.. section: Documentation + +Document :c:macro:`PyDoc_STRVAR` macro in the C-API reference. + +.. + +.. bpo: 13743 +.. date: 2019-09-25-23-20-55 +.. nonce: 5ToLDy +.. section: Documentation + +Some methods within xml.dom.minidom.Element class are now better documented. + +.. + +.. bpo: 31904 +.. date: 2020-04-09-16-29-18 +.. nonce: ej348T +.. section: Tests + +Set expected default encoding in test_c_locale_coercion.py for VxWorks RTOS. + +.. + +.. bpo: 40162 +.. date: 2020-04-03-02-40-16 +.. nonce: v3pQW_ +.. section: Tests + +Update Travis CI configuration to OpenSSL 1.1.1f. + +.. + +.. bpo: 40146 +.. date: 2020-04-02-02-14-37 +.. nonce: J-Yo9G +.. section: Tests + +Update OpenSSL to 1.1.1f in Azure Pipelines. + +.. + +.. bpo: 40094 +.. date: 2020-03-31-18-57-52 +.. nonce: m3fTJe +.. section: Tests + +Add :func:`test.support.wait_process` function. + +.. + +.. bpo: 40003 +.. date: 2020-03-31-16-07-15 +.. nonce: SOruLY +.. section: Tests + +``test.bisect_cmd`` now copies Python command line options like ``-O`` or +``-W``. Moreover, emit a warning if ``test.bisect_cmd`` is used with +``-w``/``--verbose2`` option. + +.. + +.. bpo: 39380 +.. date: 2020-03-22-20-00-04 +.. nonce: ZXlRQU +.. section: Tests + +Add the encoding in :class:`ftplib.FTP` and :class:`ftplib.FTP_TLS` to the +constructor as keyword-only and change the default from ``latin-1`` to +``utf-8`` to follow :rfc:`2640`. + +.. + +.. bpo: 39793 +.. date: 2020-02-29-12-58-17 +.. nonce: Og2SUN +.. section: Tests + +Use the same domain when testing ``make_msgid``. Patch by Batuhan Taskaya. + +.. + +.. bpo: 1812 +.. date: 2019-11-25-21-46-47 +.. nonce: sAbTbY +.. section: Tests + +Fix newline handling in doctest.testfile when loading from a package whose +loader has a get_data method. Patch by Peter Donis. + +.. + +.. bpo: 38360 +.. date: 2020-04-22-02-33-54 +.. nonce: 74C68u +.. section: Build + +Support single-argument form of macOS -isysroot flag. + +.. + +.. bpo: 40158 +.. date: 2020-04-03-17-54-33 +.. nonce: MWUTs4 +.. section: Build + +Fix CPython MSBuild Properties in NuGet Package (build/native/python.props) + +.. + +.. bpo: 38527 +.. date: 2020-03-28-10-43-09 +.. nonce: fqCRgD +.. section: Build + +Fix configure check on Solaris for "float word ordering": sometimes, the +correct "grep" command was not being used. Patch by Arnon Yaari. + +.. + +.. bpo: 40164 +.. date: 2020-04-04-13-13-44 +.. nonce: SPrSn5 +.. section: Windows + +Updates Windows to OpenSSL 1.1.1f + +.. + +.. bpo: 8901 +.. date: 2020-01-24-09-15-41 +.. nonce: hVnhGO +.. section: Windows + +Ignore the Windows registry when the ``-E`` option is used. + +.. + +.. bpo: 38329 +.. date: 2020-04-22-03-39-22 +.. nonce: H0a8JV +.. section: macOS + +python.org macOS installers now update the Current version symlink of +/Library/Frameworks/Python.framework/Versions for 3.9 installs. Previously, +Current was only updated for Python 2.x installs. This should make it easier +to embed Python 3 into other macOS applications. + +.. + +.. bpo: 40164 +.. date: 2020-04-21-19-46-35 +.. nonce: 6HA6IC +.. section: macOS + +Update macOS installer builds to use OpenSSL 1.1.1g. + +.. + +.. bpo: 38439 +.. date: 2019-12-05-14-20-53 +.. nonce: j_L2PI +.. section: IDLE + +Add a 256×256 pixel IDLE icon to support more modern environments. Created +by Andrew Clover. Delete the unused macOS idle.icns icon file. + +.. + +.. bpo: 38689 +.. date: 2019-11-14-12-59-19 +.. nonce: Lgfxva +.. section: IDLE + +IDLE will no longer freeze when inspect.signature fails when fetching a +calltip. + +.. + +.. bpo: 40385 +.. date: 2020-04-24-21-08-19 +.. nonce: nWIQdq +.. section: Tools/Demos + +Removed the checkpyc.py tool. Please see compileall without force mode as a +potential alternative. + +.. + +.. bpo: 40179 +.. date: 2020-04-04-19-35-22 +.. nonce: u9FH10 +.. section: Tools/Demos + +Fixed translation of ``#elif`` in Argument Clinic. + +.. + +.. bpo: 40094 +.. date: 2020-04-02-01-22-21 +.. nonce: 1XQQF6 +.. section: Tools/Demos + +Fix ``which.py`` script exit code: it now uses +:func:`os.waitstatus_to_exitcode` to convert :func:`os.system` exit status +into an exit code. + +.. + +.. bpo: 40241 +.. date: 2020-04-13-02-56-24 +.. nonce: _FOf7E +.. section: C API + +Move the :c:type:`PyGC_Head` structure to the internal C API. + +.. + +.. bpo: 40170 +.. date: 2020-04-11-06-12-44 +.. nonce: cmM9oK +.. section: C API + +Convert :c:func:`PyObject_IS_GC` macro to a function to hide implementation +details. + +.. + +.. bpo: 40241 +.. date: 2020-04-10-19-43-04 +.. nonce: Xm3w-1 +.. section: C API + +Add the functions :c:func:`PyObject_GC_IsTracked` and +:c:func:`PyObject_GC_IsFinalized` to the public API to allow to query if +Python objects are being currently tracked or have been already finalized by +the garbage collector respectively. Patch by Pablo Galindo. + +.. + +.. bpo: 40170 +.. date: 2020-04-05-00-37-34 +.. nonce: Seuh3D +.. section: C API + +The :c:func:`PyObject_NEW` macro becomes an alias to the +:c:func:`PyObject_New` macro, and the :c:func:`PyObject_NEW_VAR` macro +becomes an alias to the :c:func:`PyObject_NewVar` macro, to hide +implementation details. They no longer access directly the +:c:member:`PyTypeObject.tp_basicsize` member. + +.. + +.. bpo: 40170 +.. date: 2020-04-05-00-21-38 +.. nonce: Tx0vy6 +.. section: C API + +:c:func:`PyType_HasFeature` now always calls :c:func:`PyType_GetFlags` to +hide implementation details. Previously, it accessed directly the +:c:member:`PyTypeObject.tp_flags` member when the limited C API was not +used. + +.. + +.. bpo: 40170 +.. date: 2020-04-05-00-10-45 +.. nonce: 6nFYbY +.. section: C API + +Convert the :c:func:`PyObject_GET_WEAKREFS_LISTPTR` macro to a function to +hide implementation details: the macro accessed directly to the +:c:member:`PyTypeObject.tp_weaklistoffset` member. + +.. + +.. bpo: 40170 +.. date: 2020-04-05-00-02-13 +.. nonce: IFsGZ- +.. section: C API + +Convert :c:func:`PyObject_CheckBuffer` macro to a function to hide +implementation details: the macro accessed directly the +:c:member:`PyTypeObject.tp_as_buffer` member. + +.. + +.. bpo: 40170 +.. date: 2020-04-04-23-51-59 +.. nonce: uXQ701 +.. section: C API + +Always declare :c:func:`PyIndex_Check` as an opaque function to hide +implementation details: remove ``PyIndex_Check()`` macro. The macro accessed +directly the :c:member:`PyTypeObject.tp_as_number` member. + +.. + +.. bpo: 39947 +.. date: 2020-03-25-19-44-55 +.. nonce: 2OxvPt +.. section: C API + +Add :c:func:`PyThreadState_GetID` function: get the unique identifier of a +Python thread state. diff --git a/Misc/NEWS.d/3.9.0b1.rst b/Misc/NEWS.d/3.9.0b1.rst new file mode 100644 index 00000000..49418640 --- /dev/null +++ b/Misc/NEWS.d/3.9.0b1.rst @@ -0,0 +1,961 @@ +.. bpo: 40501 +.. date: 2020-05-06-00-41-11 +.. nonce: _61wv_ +.. release date: 2020-05-19 +.. section: Security + +:mod:`uuid` no longer uses :mod:`ctypes` to load :file:`libuuid` or +:file:`rpcrt4.dll` at runtime. + +.. + +.. bpo: 40663 +.. date: 2020-05-17-20-38-12 +.. nonce: u2aiZf +.. section: Core and Builtins + +Correctly generate annotations where parentheses are omitted but required +(e.g: ``Type[(str, int, *other))]``. + +.. + +.. bpo: 40596 +.. date: 2020-05-11-20-53-52 +.. nonce: dwOH_X +.. section: Core and Builtins + +Fixed :meth:`str.isidentifier` for non-canonicalized strings containing +non-BMP characters on Windows. + +.. + +.. bpo: 40593 +.. date: 2020-05-11-13-50-52 +.. nonce: yuOXj3 +.. section: Core and Builtins + +Improved syntax errors for invalid characters in source code. + +.. + +.. bpo: 40585 +.. date: 2020-05-11-00-19-42 +.. nonce: yusknY +.. section: Core and Builtins + +Fixed a bug when using :func:`codeop.compile_command` that was causing +exceptions to be swallowed with the new parser. Patch by Pablo Galindo + +.. + +.. bpo: 40566 +.. date: 2020-05-09-01-39-16 +.. nonce: wlcjW_ +.. section: Core and Builtins + +Apply :pep:`573` to :mod:`abc`. + +.. + +.. bpo: 40502 +.. date: 2020-05-08-03-25-26 +.. nonce: e-VCyL +.. section: Core and Builtins + +Initialize ``n->n_col_offset``. (Patch by Joannah Nanjekye) + +.. + +.. bpo: 40527 +.. date: 2020-05-06-14-52-35 +.. nonce: gTNKuy +.. section: Core and Builtins + +Fix command line argument parsing: no longer write errors multiple times +into stderr. + +.. + +.. bpo: 1635741 +.. date: 2020-05-05-21-11-35 +.. nonce: ggwD3C +.. section: Core and Builtins + +Port :mod:`errno` to multiphase initialization (:pep:`489`). + +.. + +.. bpo: 40523 +.. date: 2020-05-05-20-36-15 +.. nonce: hKZVTB +.. section: Core and Builtins + +Add pass-throughs for :func:`hash` and :func:`reversed` to +:class:`weakref.proxy` objects. Patch by Pablo Galindo. + +.. + +.. bpo: 1635741 +.. date: 2020-05-05-03-36-27 +.. nonce: ARv1YV +.. section: Core and Builtins + +Port :mod:`syslog` to multiphase initialization (:pep:`489`). + +.. + +.. bpo: 40246 +.. date: 2020-05-03-23-28-11 +.. nonce: c1D7x8 +.. section: Core and Builtins + +Reporting a specialised error message for invalid string prefixes, which was +introduced in :issue:`40246`, is being reverted due to backwards +compatibility concerns for strings that immediately follow a reserved +keyword without whitespace between them. Constructs like `bg="#d00" if clear +else"#fca"` were failing to parse, which is not an acceptable breakage on +such short notice. + +.. + +.. bpo: 40417 +.. date: 2020-05-01-19-04-52 +.. nonce: Sti2lJ +.. section: Core and Builtins + +Fix imp module deprecation warning when PyImport_ReloadModule is called. +Patch by Robert Rouhani. + +.. + +.. bpo: 40408 +.. date: 2020-05-01-15-36-14 +.. nonce: XzQI59 +.. section: Core and Builtins + +Fixed support of nested type variables in GenericAlias (e.g. +``list[list[T]]``). + +.. + +.. bpo: 1635741 +.. date: 2020-04-30-01-44-42 +.. nonce: GKtjqr +.. section: Core and Builtins + +Port _stat module to multiphase initialization (:pep:`489`). + +.. + +.. bpo: 29587 +.. date: 2020-04-30-00-50-25 +.. nonce: oEwSq +.. section: Core and Builtins + +Enable implicit exception chaining when calling :meth:`generator.throw`. + +.. + +.. bpo: 40328 +.. date: 2020-04-19-22-23-32 +.. nonce: gWJ53f +.. section: Core and Builtins + +Add tools for generating mappings headers for CJKCodecs. + +.. + +.. bpo: 40228 +.. date: 2020-04-08-17-02-35 +.. nonce: bRaaJ- +.. section: Core and Builtins + +Setting frame.f_lineno is now robust w.r.t. changes in the +source-to-bytecode compiler + +.. + +.. bpo: 38880 +.. date: 2019-11-22-14-34-47 +.. nonce: evcCPa +.. section: Core and Builtins + +Added the ability to list interpreters associated with channel ends in the +internal subinterpreters module. + +.. + +.. bpo: 37986 +.. date: 2019-11-20-09-50-58 +.. nonce: o0lmA7 +.. section: Core and Builtins + +Improve performance of :c:func:`PyLong_FromDouble` for values that fit into +:c:expr:`long`. + +.. + +.. bpo: 40662 +.. date: 2020-05-18-12-56-45 +.. nonce: dfornR +.. section: Library + +Fixed :func:`ast.get_source_segment` for ast nodes that have incomplete +location information. Patch by Irit Katriel. + +.. + +.. bpo: 40665 +.. date: 2020-05-17-21-56-38 +.. nonce: msB7u5 +.. section: Library + +Convert :mod:`bisect` to use Argument Clinic. + +.. + +.. bpo: 40536 +.. date: 2020-05-17-14-00-12 +.. nonce: FCpoRA +.. section: Library + +Added the :func:`~zoneinfo.available_timezones` function to the +:mod:`zoneinfo` module. Patch by Paul Ganssle. + +.. + +.. bpo: 40645 +.. date: 2020-05-16-19-34-38 +.. nonce: 7ibMt- +.. section: Library + +The :class:`hmac.HMAC` exposes internal implementation details. The +attributes ``digest_cons``, ``inner``, and ``outer`` are deprecated and will +be removed in the future. + +.. + +.. bpo: 40645 +.. date: 2020-05-16-17-05-02 +.. nonce: wYSkjT +.. section: Library + +The internal module ``_hashlib`` wraps and exposes OpenSSL's HMAC API. The +new code will be used in Python 3.10 after the internal implementation +details of the pure Python HMAC module are no longer part of the public API. + +.. + +.. bpo: 40637 +.. date: 2020-05-15-21-57-10 +.. nonce: lb3Bnp +.. section: Library + +Builtin hash modules can now be disabled or selectively enabled with +``configure --with-builtin-hashlib-hashes=sha3,blake1`` or +``--without-builtin-hashlib-hashes``. + +.. + +.. bpo: 37630 +.. date: 2020-05-15-19-53-18 +.. nonce: O5kgAw +.. section: Library + +The :mod:`hashlib` module can now use SHA3 hashes and SHAKE XOF from OpenSSL +when available. + +.. + +.. bpo: 40479 +.. date: 2020-05-15-17-38-21 +.. nonce: yamSCh +.. section: Library + +The :mod:`hashlib` now compiles with OpenSSL 3.0.0-alpha2. + +.. + +.. bpo: 40257 +.. date: 2020-05-13-23-10-25 +.. nonce: aR4TGp +.. section: Library + +Revert changes to :func:`inspect.getdoc`. + +.. + +.. bpo: 40607 +.. date: 2020-05-13-15-32-13 +.. nonce: uSPFCi +.. section: Library + +When cancelling a task due to timeout, :meth:`asyncio.wait_for` will now +propagate the exception if an error happens during cancellation. Patch by +Roman Skurikhin. + +.. + +.. bpo: 40612 +.. date: 2020-05-13-10-23-29 +.. nonce: gOIreM +.. section: Library + +Fix edge cases in SyntaxError formatting. If the offset is <= 0, no caret is +printed. If the offset is > line length, the caret is printed pointing just +after the last character. + +.. + +.. bpo: 40597 +.. date: 2020-05-11-19-17-23 +.. nonce: 4SGfgm +.. section: Library + +If text content lines are longer than policy.max_line_length, always use a +content-encoding to make sure they are wrapped. + +.. + +.. bpo: 40571 +.. date: 2020-05-09-15-38-25 +.. nonce: kOXZGC +.. section: Library + +Added functools.cache() as a simpler, more discoverable way to access the +unbounded cache variant of lru_cache(maxsize=None). + +.. + +.. bpo: 40503 +.. date: 2020-05-08-15-48-39 +.. nonce: elZyxc +.. section: Library + +:pep:`615`, the :mod:`zoneinfo` module. Adds support for the IANA time zone +database. + +.. + +.. bpo: 40397 +.. date: 2020-05-07-21-22-04 +.. nonce: PVWFAn +.. section: Library + +Removed attributes ``__args__`` and ``__parameters__`` from special generic +aliases like ``typing.List`` (not subscripted). + +.. + +.. bpo: 40549 +.. date: 2020-05-07-20-11-51 +.. nonce: 6FiRSV +.. section: Library + +Convert posixmodule.c ("posix" or "nt" module) to the multiphase +initialization (PEP 489). + +.. + +.. bpo: 31033 +.. date: 2020-05-07-06-41-20 +.. nonce: waCj3n +.. section: Library + +Add a ``msg`` argument to :meth:`Future.cancel` and :meth:`Task.cancel`. + +.. + +.. bpo: 40541 +.. date: 2020-05-06-15-36-47 +.. nonce: LlYghL +.. section: Library + +Added an optional *counts* parameter to random.sample(). + +.. + +.. bpo: 40515 +.. date: 2020-05-06-13-51-19 +.. nonce: TUCvYB +.. section: Library + +The :mod:`ssl` and :mod:`hashlib` modules now actively check that OpenSSL is +build with thread support. Python 3.7.0 made thread support mandatory and no +longer works safely with a no-thread builds. + +.. + +.. bpo: 31033 +.. date: 2020-05-06-02-33-00 +.. nonce: aX12pw +.. section: Library + +When a :class:`asyncio.Task` is cancelled, the exception traceback now +chains all the way back to where the task was first interrupted. + +.. + +.. bpo: 40504 +.. date: 2020-05-05-17-12-47 +.. nonce: EX6wPn +.. section: Library + +:func:`functools.lru_cache` objects can now be the targets of weakrefs. + +.. + +.. bpo: 40559 +.. date: 2020-05-05-08-12-51 +.. nonce: 112wwa +.. section: Library + +Fix possible memory leak in the C implementation of :class:`asyncio.Task`. + +.. + +.. bpo: 40480 +.. date: 2020-05-04-21-21-43 +.. nonce: mjldWa +.. section: Library + +``fnmatch.fnmatch()`` could take exponential time in the presence of +multiple ``*`` pattern characters. This was repaired by generating more +elaborate regular expressions to avoid futile backtracking. + +.. + +.. bpo: 40495 +.. date: 2020-05-04-11-20-49 +.. nonce: TyTc2O +.. section: Library + +:mod:`compileall` is now able to use hardlinks to prevent duplicates in a +case when ``.pyc`` files for different optimization levels have the same +content. + +.. + +.. bpo: 40457 +.. date: 2020-05-02-17-17-37 +.. nonce: EXReI1 +.. section: Library + +The ssl module now support OpenSSL builds without TLS 1.0 and 1.1 methods. + +.. + +.. bpo: 40355 +.. date: 2020-05-02-14-24-48 +.. nonce: xTujaB +.. section: Library + +Improve error reporting in :func:`ast.literal_eval` in the presence of +malformed :class:`ast.Dict` nodes instead of silently ignoring any +non-conforming elements. Patch by Curtis Bucher. + +.. + +.. bpo: 40465 +.. date: 2020-05-02-12-00-28 +.. nonce: qfCjOD +.. section: Library + +Deprecated the optional *random* argument to *random.shuffle()*. + +.. + +.. bpo: 40459 +.. date: 2020-05-02-04-29-31 +.. nonce: fSAYVD +.. section: Library + +:func:`platform.win32_ver` now produces correct *ptype* strings instead of +empty strings. + +.. + +.. bpo: 39435 +.. date: 2020-05-01-23-24-25 +.. nonce: mgb6ib +.. section: Library + +The first argument of :func:`pickle.loads` is now positional-only. + +.. + +.. bpo: 39305 +.. date: 2020-05-01-00-22-58 +.. nonce: Cuwu_H +.. section: Library + +Update :mod:`nntplib` to merge :class:`nntplib.NNTP` and +:class:`nntplib._NNTPBase`. Patch by Donghee Na. + +.. + +.. bpo: 32494 +.. date: 2020-04-30-22-25-08 +.. nonce: 1xaU5l +.. section: Library + +Update :mod:`dbm.gnu` to use gdbm_count if possible when calling +:func:`len`. Patch by Donghee Na. + +.. + +.. bpo: 40453 +.. date: 2020-04-30-22-04-58 +.. nonce: ggz7sl +.. section: Library + +Add ``isolated=True`` keyword-only parameter to +``_xxsubinterpreters.create()``. An isolated subinterpreter cannot spawn +threads, spawn a child process or call ``os.fork()``. + +.. + +.. bpo: 40286 +.. date: 2020-04-29-18-02-16 +.. nonce: txbQNx +.. section: Library + +Remove ``_random.Random.randbytes()``: the C implementation of +``randbytes()``. Implement the method in Python to ease subclassing: +``randbytes()`` now directly reuses ``getrandbits()``. + +.. + +.. bpo: 40394 +.. date: 2020-04-28-18-59-48 +.. nonce: Yi5uuM +.. section: Library + +Added default arguments to +:meth:`difflib.SequenceMatcher.find_longest_match()`. + +.. + +.. bpo: 39995 +.. date: 2020-04-28-18-25-27 +.. nonce: WmA3Gk +.. section: Library + +Fix a race condition in concurrent.futures._ThreadWakeup: access to +_ThreadWakeup is now protected with the shutdown lock. + +.. + +.. bpo: 30966 +.. date: 2020-04-27-20-27-39 +.. nonce: Xmtlqu +.. section: Library + +``Process.shutdown(wait=True)`` of :mod:`concurrent.futures` now closes +explicitly the result queue. + +.. + +.. bpo: 30966 +.. date: 2020-04-27-17-19-09 +.. nonce: _5lDx- +.. section: Library + +Add a new :meth:`~multiprocessing.SimpleQueue.close` method to the +:class:`~multiprocessing.SimpleQueue` class to explicitly close the queue. + +.. + +.. bpo: 39966 +.. date: 2020-04-27-14-48-43 +.. nonce: N5yXUe +.. section: Library + +Revert bpo-25597. :class:`unittest.mock.MagicMock` with wraps' set uses +default return values for magic methods. + +.. + +.. bpo: 39791 +.. date: 2020-04-27-00-51-40 +.. nonce: wv8Dxn +.. section: Library + +Added ``files()`` function to importlib.resources with support for +subdirectories in package data, matching backport in importlib_resources +1.5. + +.. + +.. bpo: 40375 +.. date: 2020-04-25-23-14-11 +.. nonce: 5GuK2A +.. section: Library + +:meth:`imaplib.IMAP4.unselect` is added. Patch by Donghee Na. + +.. + +.. bpo: 40389 +.. date: 2020-04-25-20-00-58 +.. nonce: FPA6f0 +.. section: Library + +``repr()`` now returns ``typing.Optional[T]`` when called for +``typing.Union`` of two types, one of which is ``NoneType``. + +.. + +.. bpo: 40291 +.. date: 2020-04-14-22-31-27 +.. nonce: _O8hXn +.. section: Library + +Add support for CAN_J1939 sockets (available on Linux 5.4+) + +.. + +.. bpo: 40273 +.. date: 2020-04-14-09-54-35 +.. nonce: IN73Ks +.. section: Library + +:class:`types.MappingProxyType` is now reversible. + +.. + +.. bpo: 39075 +.. date: 2020-04-07-23-44-06 +.. nonce: hgck3j +.. section: Library + +The repr for :class:`types.SimpleNamespace` is now insertion ordered rather +than alphabetical. + +.. + +.. bpo: 40192 +.. date: 2020-04-05-04-16-14 +.. nonce: nk8uRJ +.. section: Library + +On AIX, :func:`~time.thread_time` is now implemented with +``thread_cputime()`` which has nanosecond resolution, rather than +``clock_gettime(CLOCK_THREAD_CPUTIME_ID)`` which has a resolution of 10 milliseconds. +Patch by Batuhan Taskaya. + +.. + +.. bpo: 40025 +.. date: 2020-03-21-05-26-38 +.. nonce: DTLtyq +.. section: Library + +Raise TypeError when _generate_next_value_ is defined after members. Patch +by Ethan Onstott. + +.. + +.. bpo: 39058 +.. date: 2019-12-15-19-17-10 +.. nonce: 7ci-vd +.. section: Library + +In the argparse module, the repr for Namespace() and other argument holders +now displayed in the order attributes were added. Formerly, it displayed in +alphabetical order even though argument order is preserved the user visible +parts of the module. + +.. + +.. bpo: 24416 +.. date: 2019-09-01-15-17-49 +.. nonce: G8Ww1U +.. section: Library + +The ``isocalendar()`` methods of :class:`datetime.date` and +:class:`datetime.datetime` now return a :term:`named tuple` instead of a +:class:`tuple`. + +.. + +.. bpo: 34790 +.. date: 2020-05-08-20-18-55 +.. nonce: t6kW_1 +.. section: Documentation + +Add version of removal for explicit passing of coros to `asyncio.wait()`'s +documentation + +.. + +.. bpo: 40561 +.. date: 2020-05-08-08-39-40 +.. nonce: ZMB_2i +.. section: Documentation + +Provide docstrings for webbrowser open functions. + +.. + +.. bpo: 40499 +.. date: 2020-05-04-14-20-02 +.. nonce: tjLSo8 +.. section: Documentation + +Mention that :func:`asyncio.wait` requires a non-empty set of awaitables. + +.. + +.. bpo: 39705 +.. date: 2020-03-14-18-37-06 +.. nonce: nQVqig +.. section: Documentation + +Tutorial example for sorted() in the Loop Techniques section is given a +better explanation. Also a new example is included to explain sorted()'s +basic behavior. + +.. + +.. bpo: 39435 +.. date: 2020-01-24-05-42-57 +.. nonce: EFcdFU +.. section: Documentation + +Fix an incorrect signature for :func:`pickle.loads` in the docs + +.. + +.. bpo: 40055 +.. date: 2020-05-15-01-21-44 +.. nonce: Xp4aP9 +.. section: Tests + +distutils.tests now saves/restores warnings filters to leave them unchanged. +Importing tests imports docutils which imports pkg_resources which adds a +warnings filter. + +.. + +.. bpo: 40436 +.. date: 2020-04-29-16-08-24 +.. nonce: gDMnYl +.. section: Tests + +test_gdb and test.pythoninfo now check gdb command exit code. + +.. + +.. bpo: 40653 +.. date: 2020-05-17-03-33-00 +.. nonce: WI8UGn +.. section: Build + +Move _dirnameW out of HAVE_SYMLINK to fix a potential compiling issue. + +.. + +.. bpo: 40514 +.. date: 2020-05-05-15-39-11 +.. nonce: bZZmuS +.. section: Build + +Add ``--with-experimental-isolated-subinterpreters`` build option to +``configure``: better isolate subinterpreters, experimental build mode. + +.. + +.. bpo: 40650 +.. date: 2020-05-17-00-08-13 +.. nonce: 4euMtU +.. section: Windows + +Include winsock2.h in pytime.c for timeval. + +.. + +.. bpo: 40458 +.. date: 2020-05-01-20-57-57 +.. nonce: Eb0ueI +.. section: Windows + +Increase reserved stack space to prevent overflow crash on Windows. + +.. + +.. bpo: 39148 +.. date: 2020-03-23-19-07-55 +.. nonce: W1YJEb +.. section: Windows + +Add IPv6 support to :mod:`asyncio` datagram endpoints in ProactorEventLoop. +Change the raised exception for unknown address families to ValueError as +it's not coming from Windows API. + +.. + +.. bpo: 34956 +.. date: 2020-05-18-02-43-11 +.. nonce: 35IcGF +.. section: macOS + +When building Python on macOS from source, ``_tkinter`` now links with +non-system Tcl and Tk frameworks if they are installed in +``/Library/Frameworks``, as had been the case on older releases +of macOS. If a macOS SDK is explicitly configured, by using +``--enable-universalsdk=`` or ``-isysroot``, only the SDK itself is +searched. The default behavior can still be overridden with +``--with-tcltk-includes`` and ``--with-tcltk-libs``. + +.. + +.. bpo: 35569 +.. date: 2020-04-15-00-02-47 +.. nonce: 02_1MV +.. section: macOS + +Expose RFC 3542 IPv6 socket options. + +.. + +.. bpo: 40479 +.. date: 2020-05-15-17-48-25 +.. nonce: B1gBl- +.. section: Tools/Demos + +Update multissltest helper to test with latest OpenSSL 1.0.2, 1.1.0, 1.1.1, +and 3.0.0-alpha. + +.. + +.. bpo: 40431 +.. date: 2020-04-29-01-32-17 +.. nonce: B_aEZ0 +.. section: Tools/Demos + +Fix a syntax typo in ``turtledemo`` that now raises a ``SyntaxError``. + +.. + +.. bpo: 40163 +.. date: 2020-04-03-08-32-31 +.. nonce: lX8K4B +.. section: Tools/Demos + +Fix multissltest tool. OpenSSL has changed download URL for old releases. +The multissltest tool now tries to download from current and old download +URLs. + +.. + +.. bpo: 39465 +.. date: 2020-05-14-00-36-19 +.. nonce: 3a5g-X +.. section: C API + +Remove the ``_PyUnicode_ClearStaticStrings()`` function from the C API. + +.. + +.. bpo: 38787 +.. date: 2020-05-10-16-39-08 +.. nonce: XzQ59O +.. section: C API + +Add PyCFunction_CheckExact() macro for exact type checks now that we allow +subtypes of PyCFunction, as well as PyCMethod_CheckExact() and +PyCMethod_Check() for the new PyCMethod subtype. + +.. + +.. bpo: 40545 +.. date: 2020-05-07-11-41-13 +.. nonce: 51DzF1 +.. section: C API + +Declare ``_PyErr_GetTopmostException()`` with ``PyAPI_FUNC()`` to properly +export the function in the C API. The function remains private (``_Py``) +prefix. + +.. + +.. bpo: 40412 +.. date: 2020-05-01-17-28-04 +.. nonce: dE0D8N +.. section: C API + +Nullify inittab_copy during finalization, preventing future interpreter +initializations in an embedded situation from crashing. Patch by Gregory +Szorc. + +.. + +.. bpo: 40429 +.. date: 2020-04-29-01-39-41 +.. nonce: VQfvta +.. section: C API + +The :c:func:`PyThreadState_GetFrame` function now returns a strong reference +to the frame. + +.. + +.. bpo: 40428 +.. date: 2020-04-28-23-17-27 +.. nonce: rmtpru +.. section: C API + +Remove the following functions from the C API. Call :c:func:`PyGC_Collect` +explicitly to free all free lists. + +* ``PyAsyncGen_ClearFreeLists()`` +* ``PyContext_ClearFreeList()`` +* ``PyDict_ClearFreeList()`` +* ``PyFloat_ClearFreeList()`` +* ``PyFrame_ClearFreeList()`` +* ``PyList_ClearFreeList()`` +* ``PySet_ClearFreeList()`` +* ``PyTuple_ClearFreeList()`` + +.. + +.. bpo: 40421 +.. date: 2020-04-28-19-29-36 +.. nonce: 3uIIaB +.. section: C API + +New :c:func:`PyFrame_GetBack` function: get the frame next outer frame. + +.. + +.. bpo: 40421 +.. date: 2020-04-28-15-47-58 +.. nonce: ZIzOV0 +.. section: C API + +New :c:func:`PyFrame_GetCode` function: return a borrowed reference to the +frame code. + +.. + +.. bpo: 40217 +.. date: 2020-04-27-14-00-38 +.. nonce: sgn6c8 +.. section: C API + +Ensure that instances of types created with +:c:func:`PyType_FromSpecWithBases` will visit its class object when +traversing references in the garbage collector (implemented as an extension +of the provided :c:member:`~PyTypeObject.tp_traverse`). Patch by Pablo +Galindo. + +.. + +.. bpo: 38787 +.. date: 2020-01-22-12-38-59 +.. nonce: HUH6hd +.. section: C API + +Module C state is now accessible from C-defined heap type methods +(:pep:`573`). Patch by Marcel Plch and Petr Viktorin. diff --git a/Misc/NEWS.d/next/Build/README.rst b/Misc/NEWS.d/next/Build/README.rst new file mode 100644 index 00000000..d43e989e --- /dev/null +++ b/Misc/NEWS.d/next/Build/README.rst @@ -0,0 +1,3 @@ +Put news entry `blurb`_ files for the *Build* section in this directory. + +.. _blurb: https://pypi.org/project/blurb/ diff --git a/Misc/NEWS.d/next/C API/README.rst b/Misc/NEWS.d/next/C API/README.rst new file mode 100644 index 00000000..a4eb2615 --- /dev/null +++ b/Misc/NEWS.d/next/C API/README.rst @@ -0,0 +1,3 @@ +Put news entry `blurb`_ files for the *C API* section in this directory. + +.. _blurb: https://pypi.org/project/blurb/ diff --git a/Misc/NEWS.d/next/Core and Builtins/README.rst b/Misc/NEWS.d/next/Core and Builtins/README.rst new file mode 100644 index 00000000..00831936 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/README.rst @@ -0,0 +1,3 @@ +Put news entry `blurb`_ files for the *Core and Builtins* section in this directory. + +.. _blurb: https://pypi.org/project/blurb/ diff --git a/Misc/NEWS.d/next/Documentation/README.rst b/Misc/NEWS.d/next/Documentation/README.rst new file mode 100644 index 00000000..245b7d63 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/README.rst @@ -0,0 +1,3 @@ +Put news entry `blurb`_ files for the *Documentation* section in this directory. + +.. _blurb: https://pypi.org/project/blurb/ diff --git a/Misc/NEWS.d/next/IDLE/README.rst b/Misc/NEWS.d/next/IDLE/README.rst new file mode 100644 index 00000000..834c5d48 --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/README.rst @@ -0,0 +1,3 @@ +Put news entry `blurb`_ files for the *IDLE* section in this directory. + +.. _blurb: https://pypi.org/project/blurb/ diff --git a/Misc/NEWS.d/next/Library/README.rst b/Misc/NEWS.d/next/Library/README.rst new file mode 100644 index 00000000..178ac664 --- /dev/null +++ b/Misc/NEWS.d/next/Library/README.rst @@ -0,0 +1,3 @@ +Put news entry `blurb`_ files for the *Library* section in this directory. + +.. _blurb: https://pypi.org/project/blurb/ diff --git a/Misc/NEWS.d/next/Security/README.rst b/Misc/NEWS.d/next/Security/README.rst new file mode 100644 index 00000000..9ea371df --- /dev/null +++ b/Misc/NEWS.d/next/Security/README.rst @@ -0,0 +1,3 @@ +Put news entry `blurb`_ files for the *Security* section in this directory. + +.. _blurb: https://pypi.org/project/blurb/ diff --git a/Misc/NEWS.d/next/Tests/README.rst b/Misc/NEWS.d/next/Tests/README.rst new file mode 100644 index 00000000..8ea9b4ce --- /dev/null +++ b/Misc/NEWS.d/next/Tests/README.rst @@ -0,0 +1,3 @@ +Put news entry `blurb`_ files for the *Tests* section in this directory. + +.. _blurb: https://pypi.org/project/blurb/ diff --git a/Misc/NEWS.d/next/Tools-Demos/README.rst b/Misc/NEWS.d/next/Tools-Demos/README.rst new file mode 100644 index 00000000..9f03d79b --- /dev/null +++ b/Misc/NEWS.d/next/Tools-Demos/README.rst @@ -0,0 +1,3 @@ +Put news entry `blurb`_ files for the *Tools/Demos* section in this directory. + +.. _blurb: https://pypi.org/project/blurb/ diff --git a/Misc/NEWS.d/next/Windows/README.rst b/Misc/NEWS.d/next/Windows/README.rst new file mode 100644 index 00000000..7dbc5805 --- /dev/null +++ b/Misc/NEWS.d/next/Windows/README.rst @@ -0,0 +1,3 @@ +Put news entry `blurb`_ files for the *Windows* section in this directory. + +.. _blurb: https://pypi.org/project/blurb/ diff --git a/Misc/NEWS.d/next/macOS/README.rst b/Misc/NEWS.d/next/macOS/README.rst new file mode 100644 index 00000000..56376692 --- /dev/null +++ b/Misc/NEWS.d/next/macOS/README.rst @@ -0,0 +1,3 @@ +Put news entry `blurb`_ files for the *macOS* section in this directory. + +.. _blurb: https://pypi.org/project/blurb/ diff --git a/Misc/README b/Misc/README index e4dd2005..3dab768b 100644 --- a/Misc/README +++ b/Misc/README @@ -8,7 +8,6 @@ Files found here ---------------- ACKS Acknowledgements -gdbinit Handy stuff to put in your .gdbinit file, if you use gdb HISTORY News from previous releases -- oldest last indent.pro GNU indent profile approximating my C style NEWS News for this release (for some meaning of "this") diff --git a/Misc/gdbinit b/Misc/gdbinit deleted file mode 100644 index e8f62ba6..00000000 --- a/Misc/gdbinit +++ /dev/null @@ -1,176 +0,0 @@ -# If you use the GNU debugger gdb to debug the Python C runtime, you -# might find some of the following commands useful. Copy this to your -# ~/.gdbinit file and it'll get loaded into gdb automatically when you -# start it up. Then, at the gdb prompt you can do things like: -# -# (gdb) pyo apyobjectptr -# <module 'foobar' (built-in)> -# refcounts: 1 -# address : 84a7a2c -# $1 = void -# (gdb) -# -# NOTE: If you have gdb 7 or later, it supports debugging of Python directly -# with embedded macros that you may find superior to what is in here. -# See Tools/gdb/libpython.py and http://bugs.python.org/issue8032. - -define pyo - # side effect of calling _PyObject_Dump is to dump the object's - # info - assigning just prevents gdb from printing the - # NULL return value - set $_unused_void = _PyObject_Dump($arg0) -end -document pyo - Prints a representation of the object to stderr, along with the - number of reference counts it currently has and the hex address the - object is allocated at. The argument must be a PyObject* -end - -define pyg - print _PyGC_Dump($arg0) -end -document pyg - Prints a representation of the object to stderr, along with the - number of reference counts it currently has and the hex address the - object is allocated at. The argument must be a PyGC_Head* -end - -define pylocals - set $_i = 0 - while $_i < f->f_code->co_nlocals - if f->f_localsplus + $_i != 0 - set $_names = f->f_code->co_varnames - set $_name = PyUnicode_AsUTF8(PyTuple_GetItem($_names, $_i)) - printf "%s:\n", $_name - pyo f->f_localsplus[$_i] - end - set $_i = $_i + 1 - end -end -document pylocals - Print the local variables of the current frame. -end - -# A rewrite of the Python interpreter's line number calculator in GDB's -# command language -define lineno - set $__continue = 1 - set $__co = f->f_code - set $__lasti = f->f_lasti - set $__sz = ((PyVarObject *)$__co->co_lnotab)->ob_size/2 - set $__p = (unsigned char *)((PyBytesObject *)$__co->co_lnotab)->ob_sval - set $__li = $__co->co_firstlineno - set $__ad = 0 - while ($__sz-1 >= 0 && $__continue) - set $__sz = $__sz - 1 - set $__ad = $__ad + *$__p - set $__p = $__p + 1 - if ($__ad > $__lasti) - set $__continue = 0 - else - set $__li = $__li + *$__p - set $__p = $__p + 1 - end - end - printf "%d", $__li -end - -define pyframev - pyframe - pylocals -end -document pyframev - Print the current frame - verbose -end - -define pyframe - set $__fn = PyUnicode_AsUTF8(f->f_code->co_filename) - set $__n = PyUnicode_AsUTF8(f->f_code->co_name) - printf "%s (", $__fn - lineno - printf "): %s\n", $__n -### Uncomment these lines when using from within Emacs/XEmacs so it will -### automatically track/display the current Python source line -# printf "%c%c%s:", 032, 032, $__fn -# lineno -# printf ":1\n" -end - -### Use these at your own risk. It appears that a bug in gdb causes it -### to crash in certain circumstances. - -#define up -# up-silently 1 -# printframe -#end - -#define down -# down-silently 1 -# printframe -#end - -define printframe - if $pc > PyEval_EvalFrameEx && $pc < _PyEval_EvalFrameDefault - pyframe - else - frame - end -end - -# Here's a somewhat fragile way to print the entire Python stack from gdb. -# It's fragile because the tests for the value of $pc depend on the layout -# of specific functions in the C source code. - -# Explanation of while and if tests: We want to pop up the stack until we -# land in Py_Main (this is probably an incorrect assumption in an embedded -# interpreter, but the test can be extended by an interested party). If -# Py_Main <= $pc <= Py_GetArgcArv is true, $pc is in Py_Main(), so the while -# tests succeeds as long as it's not true. In a similar fashion the if -# statement tests to see if we are in PyEval_EvalFrameEx(). - -# Note: The name of the main interpreter function and the function which -# follow it has changed over time. This version of pystack works with this -# version of Python. If you try using it with older or newer versions of -# the interpreter you may will have to change the functions you compare with -# $pc. - -define pystack - while $pc < Py_Main || $pc > Py_GetArgcArgv - if $pc > PyEval_EvalFrameEx && $pc < _PyEval_EvalFrameDefault - pyframe - end - up-silently 1 - end - select-frame 0 -end -document pystack - Print the entire Python call stack -end - -define pystackv - while $pc < Py_Main || $pc > Py_GetArgcArgv - if $pc > PyEval_EvalFrameEx && $pc < _PyEval_EvalFrameDefault - pyframev - end - up-silently 1 - end - select-frame 0 -end -document pystackv - Print the entire Python call stack - verbose mode -end - -define pu - set $uni = $arg0 - set $i = 0 - while (*$uni && $i++<100) - if (*$uni < 0x80) - print *(char*)$uni++ - else - print /x *(short*)$uni++ - end - end -end -document pu - Generally useful macro to print a Unicode string -end diff --git a/Misc/python.man b/Misc/python.man index 07a08315..9f89c94a 100644 --- a/Misc/python.man +++ b/Misc/python.man @@ -592,8 +592,8 @@ works on Mac OS X. .IP PYTHONUSERBASE Defines the user base directory, which is used to compute the path of the user .IR site-packages -directory and Distutils installation paths for -.IR "python setup\.py install \-\-user" . +directory and installation paths for +.IR "python \-m pip install \-\-user" . .IP PYTHONPROFILEIMPORTTIME If this environment variable is set to a non-empty string, Python will show how long each import takes. This is exactly equivalent to setting @@ -605,9 +605,6 @@ can be set to the callable of your debugger of choice. Setting these variables only has an effect in a debug build of Python, that is, if Python was configured with the \fB\--with-pydebug\fP build option. -.IP PYTHONTHREADDEBUG -If this environment variable is set, Python will print threading debug info. -The feature is deprecated in Python 3.10 and will be removed in Python 3.12. .IP PYTHONDUMPREFS If this environment variable is set, Python will dump objects and reference counts still alive after shutting down the interpreter. diff --git a/Misc/python.pc.in b/Misc/python.pc.in index 87e04dec..027dba38 100644 --- a/Misc/python.pc.in +++ b/Misc/python.pc.in @@ -9,5 +9,5 @@ Description: Build a C extension for Python Requires: Version: @VERSION@ Libs.private: @LIBS@ -Libs: +Libs: -L${libdir} @LIBPYTHON@ Cflags: -I${includedir}/python@VERSION@@ABIFLAGS@ diff --git a/Misc/stable_abi.toml b/Misc/stable_abi.toml index ebae4e44..48299e9b 100644 --- a/Misc/stable_abi.toml +++ b/Misc/stable_abi.toml @@ -2,7 +2,7 @@ # Please append new items at the end. # The syntax of this file is not fixed. -# It is designed to be read only by Tools/stable_abi.py, which can change +# It is designed to be read only by Tools/build/stable_abi.py, which can change # without notice. # For the history of the stable ABI prior to this file, @@ -94,7 +94,7 @@ added = '3.2' struct_abi_kind = 'full-abi' [struct.PyMemberDef] - added = '3.2' + added = '3.2' # Before 3.12, PyMemberDef required #include "structmember.h" struct_abi_kind = 'full-abi' [struct.PyGetSetDef] added = '3.2' @@ -609,6 +609,8 @@ added = '3.2' [function.PyErr_Display] added = '3.2' +[function.PyErr_DisplayException] + added = '3.12' [function.PyErr_ExceptionMatches] added = '3.2' [function.PyErr_Fetch] @@ -1531,6 +1533,7 @@ added = '3.2' [function.PyUnicode_GetSize] added = '3.2' + abi_only = true [function.PyUnicode_IsIdentifier] added = '3.2' [function.PyUnicode_Join] @@ -1569,6 +1572,7 @@ added = '3.2' [function.PyUnicode_InternImmortal] added = '3.2' + abi_only = true [function.PyUnicode_InternInPlace] added = '3.2' [data.PyUnicode_Type] @@ -1775,11 +1779,9 @@ added = '3.2' abi_only = true [function.PyMember_GetOne] - added = '3.2' - abi_only = true + added = '3.2' # Before 3.12, available in "structmember.h" [function.PyMember_SetOne] - added = '3.2' - abi_only = true + added = '3.2' # Before 3.12, available in "structmember.h" # TLS api is deprecated; superseded by TSS API @@ -2324,3 +2326,83 @@ added = '3.11' [function.PyErr_SetHandledException] added = '3.11' + +[function.PyType_FromMetaclass] + added = '3.12' +[const.Py_TPFLAGS_HAVE_VECTORCALL] + added = '3.12' +[function.PyVectorcall_NARGS] + added = '3.12' +[function.PyVectorcall_Call] + added = '3.12' +[function.PyErr_GetRaisedException] + added = '3.12' +[function.PyErr_SetRaisedException] + added = '3.12' +[function.PyException_GetArgs] + added = '3.12' +[function.PyException_SetArgs] + added = '3.12' + +[typedef.vectorcallfunc] + added = '3.12' +[function.PyObject_Vectorcall] + added = '3.12' +[function.PyObject_VectorcallMethod] + added = '3.12' +[macro.PY_VECTORCALL_ARGUMENTS_OFFSET] + added = '3.12' +[typedef.getbufferproc] + added = '3.12' +[typedef.releasebufferproc] + added = '3.12' + +[const.Py_T_BYTE] + added = '3.12' # Before 3.12, available in "structmember.h" w/o Py_ prefix +[const.Py_T_SHORT] + added = '3.12' # Before 3.12, available in "structmember.h" w/o Py_ prefix +[const.Py_T_INT] + added = '3.12' # Before 3.12, available in "structmember.h" w/o Py_ prefix +[const.Py_T_LONG] + added = '3.12' # Before 3.12, available in "structmember.h" w/o Py_ prefix +[const.Py_T_LONGLONG] + added = '3.12' # Before 3.12, available in "structmember.h" w/o Py_ prefix +[const.Py_T_UBYTE] + added = '3.12' # Before 3.12, available in "structmember.h" w/o Py_ prefix +[const.Py_T_UINT] + added = '3.12' # Before 3.12, available in "structmember.h" w/o Py_ prefix +[const.Py_T_USHORT] + added = '3.12' # Before 3.12, available in "structmember.h" w/o Py_ prefix +[const.Py_T_ULONG] + added = '3.12' # Before 3.12, available in "structmember.h" w/o Py_ prefix +[const.Py_T_ULONGLONG] + added = '3.12' # Before 3.12, available in "structmember.h" w/o Py_ prefix +[const.Py_T_PYSSIZET] + added = '3.12' # Before 3.12, available in "structmember.h" w/o Py_ prefix +[const.Py_T_FLOAT] + added = '3.12' # Before 3.12, available in "structmember.h" w/o Py_ prefix +[const.Py_T_DOUBLE] + added = '3.12' # Before 3.12, available in "structmember.h" w/o Py_ prefix +[const.Py_T_BOOL] + added = '3.12' # Before 3.12, available in "structmember.h" w/o Py_ prefix +[const.Py_T_STRING] + added = '3.12' # Before 3.12, available in "structmember.h" w/o Py_ prefix +[const.Py_T_STRING_INPLACE] + added = '3.12' # Before 3.12, available in "structmember.h" w/o Py_ prefix +[const.Py_T_CHAR] + added = '3.12' # Before 3.12, available in "structmember.h" w/o Py_ prefix +[const.Py_T_OBJECT_EX] + added = '3.12' # Before 3.12, available in "structmember.h" w/o Py_ prefix +[const.Py_READONLY] + added = '3.12' # Before 3.12, available in "structmember.h" w/o Py_ prefix +[const.Py_AUDIT_READ] + added = '3.12' # Before 3.12, available in "structmember.h" + +[function.PyObject_GetTypeData] + added = '3.12' +[function.PyType_GetTypeDataSize] + added = '3.12' +[const.Py_RELATIVE_OFFSET] + added = '3.12' +[const.Py_TPFLAGS_ITEMS_AT_END] + added = '3.12' diff --git a/Modules/Setup b/Modules/Setup index d3647ecb..a8faa1d1 100644 --- a/Modules/Setup +++ b/Modules/Setup @@ -163,11 +163,10 @@ PYTHONPATH=$(COREPYTHONPATH) # hashing builtins #_blake2 _blake2/blake2module.c _blake2/blake2b_impl.c _blake2/blake2s_impl.c -#_md5 md5module.c -#_sha1 sha1module.c -#_sha256 sha256module.c -#_sha512 sha512module.c -#_sha3 _sha3/sha3module.c +#_md5 md5module.c -I$(srcdir)/Modules/_hacl/include _hacl/Hacl_Hash_MD5.c -D_BSD_SOURCE -D_DEFAULT_SOURCE +#_sha1 sha1module.c -I$(srcdir)/Modules/_hacl/include _hacl/Hacl_Hash_SHA1.c -D_BSD_SOURCE -D_DEFAULT_SOURCE +#_sha2 sha2module.c -I$(srcdir)/Modules/_hacl/include Modules/_hacl/libHacl_Hash_SHA2.a +#_sha3 sha3module.c -I$(srcdir)/Modules/_hacl/include _hacl/Hacl_Hash_SHA3.c -D_BSD_SOURCE -D_DEFAULT_SOURCE # text encodings and unicode #_codecs_cn cjkcodecs/_codecs_cn.c @@ -275,11 +274,12 @@ PYTHONPATH=$(COREPYTHONPATH) #xx xxmodule.c #xxlimited xxlimited.c #xxlimited_35 xxlimited_35.c -xxsubtype xxsubtype.c # Required for the test suite to pass! +#xxsubtype xxsubtype.c # Testing #_xxsubinterpreters _xxsubinterpretersmodule.c +#_xxinterpchannels _xxinterpchannelsmodule.c #_xxtestfuzz _xxtestfuzz/_xxtestfuzz.c _xxtestfuzz/fuzzer.c #_testbuffer _testbuffer.c #_testinternalcapi _testinternalcapi.c @@ -291,6 +291,7 @@ xxsubtype xxsubtype.c # Required for the test suite to pass! #_testcapi _testcapimodule.c #_testimportmultiple _testimportmultiple.c #_testmultiphase _testmultiphase.c +#_testsinglephase _testsinglephase.c # --- # Uncommenting the following line tells makesetup that all following modules diff --git a/Modules/Setup.bootstrap.in b/Modules/Setup.bootstrap.in index e3e9b96b..8ef0f203 100644 --- a/Modules/Setup.bootstrap.in +++ b/Modules/Setup.bootstrap.in @@ -21,6 +21,7 @@ itertools itertoolsmodule.c _sre _sre/sre.c _thread _threadmodule.c time timemodule.c +_typing _typingmodule.c _weakref _weakref.c # commonly used core modules diff --git a/Modules/Setup.stdlib.in b/Modules/Setup.stdlib.in index 2009a4d2..3e01e250 100644 --- a/Modules/Setup.stdlib.in +++ b/Modules/Setup.stdlib.in @@ -41,8 +41,8 @@ @MODULE__QUEUE_TRUE@_queue _queuemodule.c @MODULE__RANDOM_TRUE@_random _randommodule.c @MODULE__STRUCT_TRUE@_struct _struct.c -@MODULE__TYPING_TRUE@_typing _typingmodule.c @MODULE__XXSUBINTERPRETERS_TRUE@_xxsubinterpreters _xxsubinterpretersmodule.c +@MODULE__XXINTERPCHANNELS_TRUE@_xxinterpchannels _xxinterpchannelsmodule.c @MODULE__ZONEINFO_TRUE@_zoneinfo _zoneinfo.c # needs libm @@ -68,19 +68,18 @@ # dbm/gdbm # dbm needs either libndbm, libgdbm_compat, or libdb 5.x -#@MODULE__DBM_TRUE@_dbm _dbmmodule.c +@MODULE__DBM_TRUE@_dbm _dbmmodule.c # gdbm module needs -lgdbm @MODULE__GDBM_TRUE@_gdbm _gdbmmodule.c -# needs -lreadline or -leditline, sometimes termcap, termlib, or tinfo -#@MODULE_READLINE_TRUE@readline readline.c +# needs -lreadline or -ledit, sometimes termcap, termlib, or tinfo +@MODULE_READLINE_TRUE@readline readline.c # hashing builtins, can be disabled with --without-builtin-hashlib-hashes -@MODULE__MD5_TRUE@_md5 md5module.c -@MODULE__SHA1_TRUE@_sha1 sha1module.c -@MODULE__SHA256_TRUE@_sha256 sha256module.c -@MODULE__SHA512_TRUE@_sha512 sha512module.c -@MODULE__SHA3_TRUE@_sha3 _sha3/sha3module.c +@MODULE__MD5_TRUE@_md5 md5module.c -I$(srcdir)/Modules/_hacl/include _hacl/Hacl_Hash_MD5.c -D_BSD_SOURCE -D_DEFAULT_SOURCE +@MODULE__SHA1_TRUE@_sha1 sha1module.c -I$(srcdir)/Modules/_hacl/include _hacl/Hacl_Hash_SHA1.c -D_BSD_SOURCE -D_DEFAULT_SOURCE +@MODULE__SHA2_TRUE@_sha2 sha2module.c -I$(srcdir)/Modules/_hacl/include Modules/_hacl/libHacl_Hash_SHA2.a +@MODULE__SHA3_TRUE@_sha3 sha3module.c -I$(srcdir)/Modules/_hacl/include _hacl/Hacl_Hash_SHA3.c -D_BSD_SOURCE -D_DEFAULT_SOURCE @MODULE__BLAKE2_TRUE@_blake2 _blake2/blake2module.c _blake2/blake2b_impl.c _blake2/blake2s_impl.c ############################################################################ @@ -136,12 +135,12 @@ # # needs -lffi and -ldl -#@MODULE__CTYPES_TRUE@_ctypes _ctypes/_ctypes.c _ctypes/callbacks.c _ctypes/callproc.c _ctypes/stgdict.c _ctypes/cfield.c +@MODULE__CTYPES_TRUE@_ctypes _ctypes/_ctypes.c _ctypes/callbacks.c _ctypes/callproc.c _ctypes/stgdict.c _ctypes/cfield.c @MODULE__CTYPES_MALLOC_CLOSURE@ -# needs -lncurses, -lncursesw or -lcurses, sometimes -ltermcap -#@MODULE__CURSES_TRUE@_curses _cursesmodule.c -# needs -lncurses and -lpanel -#@MODULE__CURSES_PANEL_TRUE@_curses_panel _curses_panel.c +# needs -lncurses[w], sometimes -ltermcap/tinfo +@MODULE__CURSES_TRUE@_curses _cursesmodule.c +# needs -lncurses[w] and -lpanel[w] +@MODULE__CURSES_PANEL_TRUE@_curses_panel _curses_panel.c @MODULE__SQLITE3_TRUE@_sqlite3 _sqlite/blob.c _sqlite/connection.c _sqlite/cursor.c _sqlite/microprotocols.c _sqlite/module.c _sqlite/prepare_protocol.c _sqlite/row.c _sqlite/statement.c _sqlite/util.c @@ -165,16 +164,18 @@ ############################################################################ # Test modules +@MODULE_XXSUBTYPE_TRUE@xxsubtype xxsubtype.c @MODULE__XXTESTFUZZ_TRUE@_xxtestfuzz _xxtestfuzz/_xxtestfuzz.c _xxtestfuzz/fuzzer.c @MODULE__TESTBUFFER_TRUE@_testbuffer _testbuffer.c @MODULE__TESTINTERNALCAPI_TRUE@_testinternalcapi _testinternalcapi.c -@MODULE__TESTCAPI_TRUE@_testcapi _testcapimodule.c +@MODULE__TESTCAPI_TRUE@_testcapi _testcapimodule.c _testcapi/vectorcall.c _testcapi/vectorcall_limited.c _testcapi/heaptype.c _testcapi/abstract.c _testcapi/unicode.c _testcapi/dict.c _testcapi/getargs.c _testcapi/pytime.c _testcapi/datetime.c _testcapi/docstring.c _testcapi/mem.c _testcapi/watchers.c _testcapi/long.c _testcapi/float.c _testcapi/structmember.c _testcapi/exceptions.c _testcapi/code.c _testcapi/buffer.c _testcapi/pyos.c _testcapi/immortal.c _testcapi/heaptype_relative.c _testcapi/gc.c @MODULE__TESTCLINIC_TRUE@_testclinic _testclinic.c # Some testing modules MUST be built as shared libraries. *shared* @MODULE__TESTIMPORTMULTIPLE_TRUE@_testimportmultiple _testimportmultiple.c @MODULE__TESTMULTIPHASE_TRUE@_testmultiphase _testmultiphase.c +@MODULE__TESTMULTIPHASE_TRUE@_testsinglephase _testsinglephase.c @MODULE__CTYPES_TEST_TRUE@_ctypes_test _ctypes/_ctypes_test.c # Limited API template modules; must be built as shared modules. diff --git a/Modules/_abc.c b/Modules/_abc.c index b22daa81..d3e405da 100644 --- a/Modules/_abc.c +++ b/Modules/_abc.c @@ -7,6 +7,7 @@ #include "pycore_moduleobject.h" // _PyModule_GetState() #include "pycore_object.h" // _PyType_GetSubclasses() #include "pycore_runtime.h" // _Py_ID() +#include "pycore_typeobject.h" // _PyType_GetMRO() #include "clinic/_abc.c.h" /*[clinic input] @@ -79,7 +80,7 @@ abc_data_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return NULL; } - state = PyType_GetModuleState(type); + state = _PyType_GetModuleState(type); if (state == NULL) { Py_DECREF(self); return NULL; @@ -452,7 +453,8 @@ _abc__abc_init(PyObject *module, PyObject *self) * their special status w.r.t. pattern matching. */ if (PyType_Check(self)) { PyTypeObject *cls = (PyTypeObject *)self; - PyObject *flags = PyDict_GetItemWithError(cls->tp_dict, + PyObject *dict = _PyType_GetDict(cls); + PyObject *flags = PyDict_GetItemWithError(dict, &_Py_ID(__abc_tpflags__)); if (flags == NULL) { if (PyErr_Occurred()) { @@ -471,7 +473,7 @@ _abc__abc_init(PyObject *module, PyObject *self) } ((PyTypeObject *)self)->tp_flags |= (val & COLLECTION_FLAGS); } - if (PyDict_DelItem(cls->tp_dict, &_Py_ID(__abc_tpflags__)) < 0) { + if (PyDict_DelItem(dict, &_Py_ID(__abc_tpflags__)) < 0) { return NULL; } } @@ -524,8 +526,7 @@ _abc__abc_register_impl(PyObject *module, PyObject *self, PyObject *subclass) } int result = PyObject_IsSubclass(subclass, self); if (result > 0) { - Py_INCREF(subclass); - return subclass; /* Already a subclass. */ + return Py_NewRef(subclass); /* Already a subclass. */ } if (result < 0) { return NULL; @@ -561,8 +562,7 @@ _abc__abc_register_impl(PyObject *module, PyObject *self, PyObject *subclass) set_collection_flag_recursive((PyTypeObject *)subclass, collection_flag); } } - Py_INCREF(subclass); - return subclass; + return Py_NewRef(subclass); } @@ -598,8 +598,7 @@ _abc__abc_instancecheck_impl(PyObject *module, PyObject *self, goto end; } if (incache > 0) { - result = Py_True; - Py_INCREF(result); + result = Py_NewRef(Py_True); goto end; } subtype = (PyObject *)Py_TYPE(instance); @@ -610,8 +609,7 @@ _abc__abc_instancecheck_impl(PyObject *module, PyObject *self, goto end; } if (incache > 0) { - result = Py_False; - Py_INCREF(result); + result = Py_NewRef(Py_False); goto end; } } @@ -628,8 +626,7 @@ _abc__abc_instancecheck_impl(PyObject *module, PyObject *self, switch (PyObject_IsTrue(result)) { case -1: - Py_DECREF(result); - result = NULL; + Py_SETREF(result, NULL); break; case 0: Py_DECREF(result); @@ -747,7 +744,7 @@ _abc__abc_subclasscheck_impl(PyObject *module, PyObject *self, Py_DECREF(ok); /* 4. Check if it's a direct subclass. */ - PyObject *mro = ((PyTypeObject *)subclass)->tp_mro; + PyObject *mro = _PyType_GetMRO((PyTypeObject *)subclass); assert(PyTuple_Check(mro)); for (pos = 0; pos < PyTuple_GET_SIZE(mro); pos++) { PyObject *mro_item = PyTuple_GET_ITEM(mro, pos); @@ -802,8 +799,7 @@ _abc__abc_subclasscheck_impl(PyObject *module, PyObject *self, end: Py_DECREF(impl); Py_XDECREF(subclasses); - Py_XINCREF(result); - return result; + return Py_XNewRef(result); } @@ -842,8 +838,7 @@ subclasscheck_check_registry(_abc_data *impl, PyObject *subclass, Py_ssize_t i = 0; while (_PySet_NextEntry(impl->_abc_registry, &pos, &key, &hash)) { - Py_INCREF(key); - copy[i++] = key; + copy[i++] = Py_NewRef(key); } assert(i == registry_size); @@ -949,6 +944,7 @@ _abcmodule_free(void *module) static PyModuleDef_Slot _abcmodule_slots[] = { {Py_mod_exec, _abcmodule_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index b2fef017..a465090b 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -1,11 +1,13 @@ #ifndef Py_BUILD_CORE_BUILTIN # define Py_BUILD_CORE_MODULE 1 #endif -#define NEEDS_PY_IDENTIFIER #include "Python.h" #include "pycore_pyerrors.h" // _PyErr_ClearExcState() #include "pycore_pystate.h" // _PyThreadState_GET() +#include "pycore_runtime_init.h" // _Py_ID() +#include "pycore_moduleobject.h" // _PyModule_GetState() +#include "structmember.h" // PyMemberDef #include <stddef.h> // offsetof() @@ -15,46 +17,90 @@ module _asyncio /*[clinic end generated code: output=da39a3ee5e6b4b0d input=8fd17862aa989c69]*/ -/* identifiers used from some functions */ -_Py_IDENTIFIER(__asyncio_running_event_loop__); -_Py_IDENTIFIER(_asyncio_future_blocking); -_Py_IDENTIFIER(add_done_callback); -_Py_IDENTIFIER(call_soon); -_Py_IDENTIFIER(cancel); -_Py_IDENTIFIER(get_event_loop); -_Py_IDENTIFIER(throw); +#define FI_FREELIST_MAXLEN 255 +typedef struct futureiterobject futureiterobject; /* State of the _asyncio module */ -static PyObject *asyncio_mod; -static PyObject *traceback_extract_stack; -static PyObject *asyncio_get_event_loop_policy; -static PyObject *asyncio_future_repr_func; -static PyObject *asyncio_iscoroutine_func; -static PyObject *asyncio_task_get_stack_func; -static PyObject *asyncio_task_print_stack_func; -static PyObject *asyncio_task_repr_func; -static PyObject *asyncio_InvalidStateError; -static PyObject *asyncio_CancelledError; -static PyObject *context_kwname; -static int module_initialized; +typedef struct { + PyTypeObject *FutureIterType; + PyTypeObject *TaskStepMethWrapper_Type; + PyTypeObject *FutureType; + PyTypeObject *TaskType; + + PyObject *asyncio_mod; + PyObject *context_kwname; + + /* Dictionary containing tasks that are currently active in + all running event loops. {EventLoop: Task} */ + PyObject *current_tasks; + + /* WeakSet containing all tasks scheduled to run on event loops. */ + PyObject *scheduled_tasks; + + /* Set containing all eagerly executing tasks. */ + PyObject *eager_tasks; -static PyObject *cached_running_holder; -static volatile uint64_t cached_running_holder_tsid; + /* An isinstance type cache for the 'is_coroutine()' function. */ + PyObject *iscoroutine_typecache; -/* Counter for autogenerated Task names */ -static uint64_t task_name_counter = 0; + /* Imports from asyncio.events. */ + PyObject *asyncio_get_event_loop_policy; -/* WeakSet containing all alive tasks. */ -static PyObject *all_tasks; + /* Imports from asyncio.base_futures. */ + PyObject *asyncio_future_repr_func; -/* Dictionary containing tasks that are currently active in - all running event loops. {EventLoop: Task} */ -static PyObject *current_tasks; + /* Imports from asyncio.exceptions. */ + PyObject *asyncio_CancelledError; + PyObject *asyncio_InvalidStateError; -/* An isinstance type cache for the 'is_coroutine()' function. */ -static PyObject *iscoroutine_typecache; + /* Imports from asyncio.base_tasks. */ + PyObject *asyncio_task_get_stack_func; + PyObject *asyncio_task_print_stack_func; + PyObject *asyncio_task_repr_func; + /* Imports from asyncio.coroutines. */ + PyObject *asyncio_iscoroutine_func; + + /* Imports from traceback. */ + PyObject *traceback_extract_stack; + + PyObject *cached_running_loop; // Borrowed reference + volatile uint64_t cached_running_loop_tsid; + + /* Counter for autogenerated Task names */ + uint64_t task_name_counter; + + futureiterobject *fi_freelist; + Py_ssize_t fi_freelist_len; +} asyncio_state; + +static inline asyncio_state * +get_asyncio_state(PyObject *mod) +{ + asyncio_state *state = _PyModule_GetState(mod); + assert(state != NULL); + return state; +} + +static inline asyncio_state * +get_asyncio_state_by_cls(PyTypeObject *cls) +{ + asyncio_state *state = (asyncio_state *)_PyType_GetModuleState(cls); + assert(state != NULL); + return state; +} + +static struct PyModuleDef _asynciomodule; + +static inline asyncio_state * +get_asyncio_state_by_def(PyObject *self) +{ + PyTypeObject *tp = Py_TYPE(self); + PyObject *mod = PyType_GetModuleByDef(tp, &_asynciomodule); + assert(mod != NULL); + return get_asyncio_state(mod); +} typedef enum { STATE_PENDING, @@ -101,25 +147,12 @@ typedef struct { PyObject *sw_arg; } TaskStepMethWrapper; -typedef struct { - PyObject_HEAD - PyObject *rl_loop; -#if defined(HAVE_GETPID) && !defined(MS_WINDOWS) - pid_t rl_pid; -#endif -} PyRunningLoopHolder; - -static PyTypeObject FutureType; -static PyTypeObject TaskType; -static PyTypeObject PyRunningLoopHolder_Type; +#define Future_CheckExact(state, obj) Py_IS_TYPE(obj, state->FutureType) +#define Task_CheckExact(state, obj) Py_IS_TYPE(obj, state->TaskType) - -#define Future_CheckExact(obj) Py_IS_TYPE(obj, &FutureType) -#define Task_CheckExact(obj) Py_IS_TYPE(obj, &TaskType) - -#define Future_Check(obj) PyObject_TypeCheck(obj, &FutureType) -#define Task_Check(obj) PyObject_TypeCheck(obj, &TaskType) +#define Future_Check(state, obj) PyObject_TypeCheck(obj, state->FutureType) +#define Task_Check(state, obj) PyObject_TypeCheck(obj, state->TaskType) #include "clinic/_asynciomodule.c.h" @@ -133,11 +166,12 @@ class _asyncio.Future "FutureObj *" "&Future_Type" /* Get FutureIter from Future */ static PyObject * future_new_iter(PyObject *); -static PyRunningLoopHolder * new_running_loop_holder(PyObject *); +static PyObject * +task_step_handle_result_impl(asyncio_state *state, TaskObj *task, PyObject *result); static int -_is_coroutine(PyObject *coro) +_is_coroutine(asyncio_state *state, PyObject *coro) { /* 'coro' is not a native coroutine, call asyncio.iscoroutine() to check if it's another coroutine flavour. @@ -145,7 +179,7 @@ _is_coroutine(PyObject *coro) Do this check after 'future_init()'; in case we need to raise an error, __del__ needs a properly initialized object. */ - PyObject *res = PyObject_CallOneArg(asyncio_iscoroutine_func, coro); + PyObject *res = PyObject_CallOneArg(state->asyncio_iscoroutine_func, coro); if (res == NULL) { return -1; } @@ -156,12 +190,12 @@ _is_coroutine(PyObject *coro) return is_res_true; } - if (PySet_GET_SIZE(iscoroutine_typecache) < 100) { + if (PySet_GET_SIZE(state->iscoroutine_typecache) < 100) { /* Just in case we don't want to cache more than 100 positive types. That shouldn't ever happen, unless someone stressing the system on purpose. */ - if (PySet_Add(iscoroutine_typecache, (PyObject*) Py_TYPE(coro))) { + if (PySet_Add(state->iscoroutine_typecache, (PyObject*) Py_TYPE(coro))) { return -1; } } @@ -171,7 +205,7 @@ _is_coroutine(PyObject *coro) static inline int -is_coroutine(PyObject *coro) +is_coroutine(asyncio_state *state, PyObject *coro) { if (PyCoro_CheckExact(coro)) { return 1; @@ -187,10 +221,10 @@ is_coroutine(PyObject *coro) a pure-Python function in 99.9% cases. */ int has_it = PySet_Contains( - iscoroutine_typecache, (PyObject*) Py_TYPE(coro)); + state->iscoroutine_typecache, (PyObject*) Py_TYPE(coro)); if (has_it == 0) { /* type(coro) is not in iscoroutine_typecache */ - return _is_coroutine(coro); + return _is_coroutine(state, coro); } /* either an error has occurred or @@ -201,21 +235,18 @@ is_coroutine(PyObject *coro) static PyObject * -get_future_loop(PyObject *fut) +get_future_loop(asyncio_state *state, PyObject *fut) { /* Implementation of `asyncio.futures._get_loop` */ - _Py_IDENTIFIER(get_loop); - _Py_IDENTIFIER(_loop); PyObject *getloop; - if (Future_CheckExact(fut) || Task_CheckExact(fut)) { + if (Future_CheckExact(state, fut) || Task_CheckExact(state, fut)) { PyObject *loop = ((FutureObj *)fut)->fut_loop; - Py_INCREF(loop); - return loop; + return Py_NewRef(loop); } - if (_PyObject_LookupAttrId(fut, &PyId_get_loop, &getloop) < 0) { + if (_PyObject_LookupAttr(fut, &_Py_ID(get_loop), &getloop) < 0) { return NULL; } if (getloop != NULL) { @@ -224,20 +255,22 @@ get_future_loop(PyObject *fut) return res; } - return _PyObject_GetAttrId(fut, &PyId__loop); + return PyObject_GetAttr(fut, &_Py_ID(_loop)); } static int -get_running_loop(PyObject **loop) +get_running_loop(asyncio_state *state, PyObject **loop) { PyObject *rl; PyThreadState *ts = _PyThreadState_GET(); uint64_t ts_id = PyThreadState_GetID(ts); - if (ts_id == cached_running_holder_tsid && cached_running_holder != NULL) { + if (state->cached_running_loop_tsid == ts_id && + state->cached_running_loop != NULL) + { // Fast path, check the cache. - rl = cached_running_holder; // borrowed + rl = state->cached_running_loop; } else { PyObject *ts_dict = _PyThreadState_GetDict(ts); // borrowed @@ -245,8 +278,8 @@ get_running_loop(PyObject **loop) goto not_found; } - rl = _PyDict_GetItemIdWithError( - ts_dict, &PyId___asyncio_running_event_loop__); // borrowed + rl = PyDict_GetItemWithError( + ts_dict, &_Py_ID(__asyncio_running_event_loop__)); // borrowed if (rl == NULL) { if (PyErr_Occurred()) { goto error; @@ -256,28 +289,16 @@ get_running_loop(PyObject **loop) } } - cached_running_holder = rl; // borrowed - cached_running_holder_tsid = ts_id; + state->cached_running_loop = rl; + state->cached_running_loop_tsid = ts_id; } - assert(Py_IS_TYPE(rl, &PyRunningLoopHolder_Type)); - PyObject *running_loop = ((PyRunningLoopHolder *)rl)->rl_loop; - if (running_loop == Py_None) { + if (rl == Py_None) { goto not_found; } -#if defined(HAVE_GETPID) && !defined(MS_WINDOWS) - /* On Windows there is no getpid, but there is also no os.fork(), - so there is no need for this check. - */ - if (getpid() != ((PyRunningLoopHolder *)rl)->rl_pid) { - goto not_found; - } -#endif - - Py_INCREF(running_loop); - *loop = running_loop; + *loop = Py_NewRef(rl); return 0; not_found: @@ -291,7 +312,7 @@ error: static int -set_running_loop(PyObject *loop) +set_running_loop(asyncio_state *state, PyObject *loop) { PyObject *ts_dict = NULL; @@ -305,81 +326,68 @@ set_running_loop(PyObject *loop) PyExc_RuntimeError, "thread-local storage is not available"); return -1; } - - PyRunningLoopHolder *rl = new_running_loop_holder(loop); - if (rl == NULL) { - return -1; - } - - if (_PyDict_SetItemId( - ts_dict, &PyId___asyncio_running_event_loop__, (PyObject *)rl) < 0) + if (PyDict_SetItem( + ts_dict, &_Py_ID(__asyncio_running_event_loop__), loop) < 0) { - Py_DECREF(rl); // will cleanup loop & current_pid return -1; } - Py_DECREF(rl); - cached_running_holder = (PyObject *)rl; - cached_running_holder_tsid = PyThreadState_GetID(tstate); + state->cached_running_loop = loop; // borrowed, kept alive by ts_dict + state->cached_running_loop_tsid = PyThreadState_GetID(tstate); return 0; } static PyObject * -get_event_loop(int stacklevel) +get_event_loop(asyncio_state *state) { PyObject *loop; PyObject *policy; - if (get_running_loop(&loop)) { + if (get_running_loop(state, &loop)) { return NULL; } if (loop != NULL) { return loop; } - policy = PyObject_CallNoArgs(asyncio_get_event_loop_policy); + policy = PyObject_CallNoArgs(state->asyncio_get_event_loop_policy); if (policy == NULL) { return NULL; } - loop = _PyObject_CallMethodIdNoArgs(policy, &PyId_get_event_loop); + loop = PyObject_CallMethodNoArgs(policy, &_Py_ID(get_event_loop)); Py_DECREF(policy); return loop; } static int -call_soon(PyObject *loop, PyObject *func, PyObject *arg, PyObject *ctx) +call_soon(asyncio_state *state, PyObject *loop, PyObject *func, PyObject *arg, + PyObject *ctx) { PyObject *handle; - PyObject *stack[3]; - Py_ssize_t nargs; if (ctx == NULL) { - handle = _PyObject_CallMethodIdObjArgs( - loop, &PyId_call_soon, func, arg, NULL); + PyObject *stack[] = {loop, func, arg}; + size_t nargsf = 3 | PY_VECTORCALL_ARGUMENTS_OFFSET; + handle = PyObject_VectorcallMethod(&_Py_ID(call_soon), stack, nargsf, NULL); } else { - /* Use FASTCALL to pass a keyword-only argument to call_soon */ - - PyObject *callable = _PyObject_GetAttrId(loop, &PyId_call_soon); - if (callable == NULL) { - return -1; - } - /* All refs in 'stack' are borrowed. */ - nargs = 1; - stack[0] = func; + PyObject *stack[4]; + size_t nargs = 2; + stack[0] = loop; + stack[1] = func; if (arg != NULL) { - stack[1] = arg; + stack[2] = arg; nargs++; } stack[nargs] = (PyObject *)ctx; - - handle = PyObject_Vectorcall(callable, stack, nargs, context_kwname); - Py_DECREF(callable); + size_t nargsf = nargs | PY_VECTORCALL_ARGUMENTS_OFFSET; + handle = PyObject_VectorcallMethod(&_Py_ID(call_soon), stack, nargsf, + state->context_kwname); } if (handle == NULL) { @@ -409,17 +417,18 @@ future_ensure_alive(FutureObj *fut) } -#define ENSURE_FUTURE_ALIVE(fut) \ - do { \ - assert(Future_Check(fut) || Task_Check(fut)); \ - if (future_ensure_alive((FutureObj*)fut)) { \ - return NULL; \ - } \ +#define ENSURE_FUTURE_ALIVE(state, fut) \ + do { \ + assert(Future_Check(state, fut) || Task_Check(state, fut)); \ + (void)state; \ + if (future_ensure_alive((FutureObj*)fut)) { \ + return NULL; \ + } \ } while(0); static int -future_schedule_callbacks(FutureObj *fut) +future_schedule_callbacks(asyncio_state *state, FutureObj *fut) { Py_ssize_t len; Py_ssize_t i; @@ -427,7 +436,7 @@ future_schedule_callbacks(FutureObj *fut) if (fut->fut_callback0 != NULL) { /* There's a 1st callback */ - int ret = call_soon( + int ret = call_soon(state, fut->fut_loop, fut->fut_callback0, (PyObject *)fut, fut->fut_context0); @@ -461,7 +470,7 @@ future_schedule_callbacks(FutureObj *fut) PyObject *cb = PyTuple_GET_ITEM(cb_tup, 0); PyObject *ctx = PyTuple_GET_ITEM(cb_tup, 1); - if (call_soon(fut->fut_loop, cb, (PyObject *)fut, ctx)) { + if (call_soon(state, fut->fut_loop, cb, (PyObject *)fut, ctx)) { /* If an error occurs in pure-Python implementation, all callbacks are cleared. */ Py_CLEAR(fut->fut_callbacks); @@ -479,7 +488,6 @@ future_init(FutureObj *fut, PyObject *loop) { PyObject *res; int is_true; - _Py_IDENTIFIER(get_debug); // Same to FutureObj_clear() but not clearing fut->dict Py_CLEAR(fut->fut_loop); @@ -498,7 +506,8 @@ future_init(FutureObj *fut, PyObject *loop) fut->fut_blocking = 0; if (loop == Py_None) { - loop = get_event_loop(1); + asyncio_state *state = get_asyncio_state_by_def((PyObject *)fut); + loop = get_event_loop(state); if (loop == NULL) { return -1; } @@ -508,7 +517,7 @@ future_init(FutureObj *fut, PyObject *loop) } fut->fut_loop = loop; - res = _PyObject_CallMethodIdNoArgs(fut->fut_loop, &PyId_get_debug); + res = PyObject_CallMethodNoArgs(fut->fut_loop, &_Py_ID(get_debug)); if (res == NULL) { return -1; } @@ -517,14 +526,15 @@ future_init(FutureObj *fut, PyObject *loop) if (is_true < 0) { return -1; } - if (is_true && !_Py_IsFinalizing()) { + if (is_true && !_Py_IsInterpreterFinalizing(PyInterpreterState_Get())) { /* Only try to capture the traceback if the interpreter is not being finalized. The original motivation to add a `_Py_IsFinalizing()` call was to prevent SIGSEGV when a Future is created in a __del__ method, which is called during the interpreter shutdown and the traceback module is already unloaded. */ - fut->fut_source_tb = PyObject_CallNoArgs(traceback_extract_stack); + asyncio_state *state = get_asyncio_state_by_def((PyObject *)fut); + fut->fut_source_tb = PyObject_CallNoArgs(state->traceback_extract_stack); if (fut->fut_source_tb == NULL) { return -1; } @@ -534,35 +544,34 @@ future_init(FutureObj *fut, PyObject *loop) } static PyObject * -future_set_result(FutureObj *fut, PyObject *res) +future_set_result(asyncio_state *state, FutureObj *fut, PyObject *res) { if (future_ensure_alive(fut)) { return NULL; } if (fut->fut_state != STATE_PENDING) { - PyErr_SetString(asyncio_InvalidStateError, "invalid state"); + PyErr_SetString(state->asyncio_InvalidStateError, "invalid state"); return NULL; } assert(!fut->fut_result); - Py_INCREF(res); - fut->fut_result = res; + fut->fut_result = Py_NewRef(res); fut->fut_state = STATE_FINISHED; - if (future_schedule_callbacks(fut) == -1) { + if (future_schedule_callbacks(state, fut) == -1) { return NULL; } Py_RETURN_NONE; } static PyObject * -future_set_exception(FutureObj *fut, PyObject *exc) +future_set_exception(asyncio_state *state, FutureObj *fut, PyObject *exc) { PyObject *exc_val = NULL; if (fut->fut_state != STATE_PENDING) { - PyErr_SetString(asyncio_InvalidStateError, "invalid state"); + PyErr_SetString(state->asyncio_InvalidStateError, "invalid state"); return NULL; } @@ -573,13 +582,12 @@ future_set_exception(FutureObj *fut, PyObject *exc) } if (fut->fut_state != STATE_PENDING) { Py_DECREF(exc_val); - PyErr_SetString(asyncio_InvalidStateError, "invalid state"); + PyErr_SetString(state->asyncio_InvalidStateError, "invalid state"); return NULL; } } else { - exc_val = exc; - Py_INCREF(exc_val); + exc_val = Py_NewRef(exc); } if (!PyExceptionInstance_Check(exc_val)) { Py_DECREF(exc_val); @@ -600,7 +608,7 @@ future_set_exception(FutureObj *fut, PyObject *exc) fut->fut_exception_tb = PyException_GetTraceback(exc_val); fut->fut_state = STATE_FINISHED; - if (future_schedule_callbacks(fut) == -1) { + if (future_schedule_callbacks(state, fut) == -1) { return NULL; } @@ -609,7 +617,7 @@ future_set_exception(FutureObj *fut, PyObject *exc) } static PyObject * -create_cancelled_error(FutureObj *fut) +create_cancelled_error(asyncio_state *state, FutureObj *fut) { PyObject *exc; if (fut->fut_cancelled_exc != NULL) { @@ -620,34 +628,35 @@ create_cancelled_error(FutureObj *fut) } PyObject *msg = fut->fut_cancel_msg; if (msg == NULL || msg == Py_None) { - exc = PyObject_CallNoArgs(asyncio_CancelledError); + exc = PyObject_CallNoArgs(state->asyncio_CancelledError); } else { - exc = PyObject_CallOneArg(asyncio_CancelledError, msg); + exc = PyObject_CallOneArg(state->asyncio_CancelledError, msg); } return exc; } static void -future_set_cancelled_error(FutureObj *fut) +future_set_cancelled_error(asyncio_state *state, FutureObj *fut) { - PyObject *exc = create_cancelled_error(fut); + PyObject *exc = create_cancelled_error(state, fut); if (exc == NULL) { return; } - PyErr_SetObject(asyncio_CancelledError, exc); + PyErr_SetObject(state->asyncio_CancelledError, exc); Py_DECREF(exc); } static int -future_get_result(FutureObj *fut, PyObject **result) +future_get_result(asyncio_state *state, FutureObj *fut, PyObject **result) { if (fut->fut_state == STATE_CANCELLED) { - future_set_cancelled_error(fut); + future_set_cancelled_error(state, fut); return -1; } if (fut->fut_state != STATE_FINISHED) { - PyErr_SetString(asyncio_InvalidStateError, "Result is not set."); + PyErr_SetString(state->asyncio_InvalidStateError, + "Result is not set."); return -1; } @@ -660,19 +669,18 @@ future_get_result(FutureObj *fut, PyObject **result) if (PyException_SetTraceback(fut->fut_exception, tb) < 0) { return -1; } - Py_INCREF(fut->fut_exception); - *result = fut->fut_exception; + *result = Py_NewRef(fut->fut_exception); Py_CLEAR(fut->fut_exception_tb); return 1; } - Py_INCREF(fut->fut_result); - *result = fut->fut_result; + *result = Py_NewRef(fut->fut_result); return 0; } static PyObject * -future_add_done_callback(FutureObj *fut, PyObject *arg, PyObject *ctx) +future_add_done_callback(asyncio_state *state, FutureObj *fut, PyObject *arg, + PyObject *ctx) { if (!future_is_alive(fut)) { PyErr_SetString(PyExc_RuntimeError, "uninitialized Future object"); @@ -682,7 +690,7 @@ future_add_done_callback(FutureObj *fut, PyObject *arg, PyObject *ctx) if (fut->fut_state != STATE_PENDING) { /* The future is done/cancelled, so schedule the callback right away. */ - if (call_soon(fut->fut_loop, arg, (PyObject*) fut, ctx)) { + if (call_soon(state, fut->fut_loop, arg, (PyObject*) fut, ctx)) { return NULL; } } @@ -709,10 +717,8 @@ future_add_done_callback(FutureObj *fut, PyObject *arg, PyObject *ctx) */ if (fut->fut_callbacks == NULL && fut->fut_callback0 == NULL) { - Py_INCREF(arg); - fut->fut_callback0 = arg; - Py_INCREF(ctx); - fut->fut_context0 = ctx; + fut->fut_callback0 = Py_NewRef(arg); + fut->fut_context0 = Py_NewRef(ctx); } else { PyObject *tup = PyTuple_New(2); @@ -748,7 +754,7 @@ future_add_done_callback(FutureObj *fut, PyObject *arg, PyObject *ctx) } static PyObject * -future_cancel(FutureObj *fut, PyObject *msg) +future_cancel(asyncio_state *state, FutureObj *fut, PyObject *msg) { fut->fut_log_tb = 0; @@ -760,7 +766,7 @@ future_cancel(FutureObj *fut, PyObject *msg) Py_XINCREF(msg); Py_XSETREF(fut->fut_cancel_msg, msg); - if (future_schedule_callbacks(fut) == -1) { + if (future_schedule_callbacks(state, fut) == -1) { return NULL; } @@ -815,6 +821,7 @@ FutureObj_clear(FutureObj *fut) static int FutureObj_traverse(FutureObj *fut, visitproc visit, void *arg) { + Py_VISIT(Py_TYPE(fut)); Py_VISIT(fut->fut_loop); Py_VISIT(fut->fut_callback0); Py_VISIT(fut->fut_context0); @@ -843,15 +850,16 @@ static PyObject * _asyncio_Future_result_impl(FutureObj *self) /*[clinic end generated code: output=f35f940936a4b1e5 input=49ecf9cf5ec50dc5]*/ { + asyncio_state *state = get_asyncio_state_by_def((PyObject *)self); PyObject *result; if (!future_is_alive(self)) { - PyErr_SetString(asyncio_InvalidStateError, + PyErr_SetString(state->asyncio_InvalidStateError, "Future object is not initialized."); return NULL; } - int res = future_get_result(self, &result); + int res = future_get_result(state, self, &result); if (res == -1) { return NULL; @@ -871,6 +879,9 @@ _asyncio_Future_result_impl(FutureObj *self) /*[clinic input] _asyncio.Future.exception + cls: defining_class + / + Return the exception that was set on this future. The exception (or None if no exception was set) is returned only if @@ -880,29 +891,32 @@ InvalidStateError. [clinic start generated code]*/ static PyObject * -_asyncio_Future_exception_impl(FutureObj *self) -/*[clinic end generated code: output=88b20d4f855e0710 input=733547a70c841c68]*/ +_asyncio_Future_exception_impl(FutureObj *self, PyTypeObject *cls) +/*[clinic end generated code: output=ce75576b187c905b input=3faf15c22acdb60d]*/ { if (!future_is_alive(self)) { - PyErr_SetString(asyncio_InvalidStateError, + asyncio_state *state = get_asyncio_state_by_cls(cls); + PyErr_SetString(state->asyncio_InvalidStateError, "Future object is not initialized."); return NULL; } if (self->fut_state == STATE_CANCELLED) { - future_set_cancelled_error(self); + asyncio_state *state = get_asyncio_state_by_cls(cls); + future_set_cancelled_error(state, self); return NULL; } if (self->fut_state != STATE_FINISHED) { - PyErr_SetString(asyncio_InvalidStateError, "Exception is not set."); + asyncio_state *state = get_asyncio_state_by_cls(cls); + PyErr_SetString(state->asyncio_InvalidStateError, + "Exception is not set."); return NULL; } if (self->fut_exception != NULL) { self->fut_log_tb = 0; - Py_INCREF(self->fut_exception); - return self->fut_exception; + return Py_NewRef(self->fut_exception); } Py_RETURN_NONE; @@ -911,6 +925,7 @@ _asyncio_Future_exception_impl(FutureObj *self) /*[clinic input] _asyncio.Future.set_result + cls: defining_class result: object / @@ -921,16 +936,19 @@ InvalidStateError. [clinic start generated code]*/ static PyObject * -_asyncio_Future_set_result(FutureObj *self, PyObject *result) -/*[clinic end generated code: output=1ec2e6bcccd6f2ce input=8b75172c2a7b05f1]*/ +_asyncio_Future_set_result_impl(FutureObj *self, PyTypeObject *cls, + PyObject *result) +/*[clinic end generated code: output=99afbbe78f99c32d input=d5a41c1e353acc2e]*/ { - ENSURE_FUTURE_ALIVE(self) - return future_set_result(self, result); + asyncio_state *state = get_asyncio_state_by_cls(cls); + ENSURE_FUTURE_ALIVE(state, self) + return future_set_result(state, self, result); } /*[clinic input] _asyncio.Future.set_exception + cls: defining_class exception: object / @@ -941,16 +959,19 @@ InvalidStateError. [clinic start generated code]*/ static PyObject * -_asyncio_Future_set_exception(FutureObj *self, PyObject *exception) -/*[clinic end generated code: output=f1c1b0cd321be360 input=e45b7d7aa71cc66d]*/ +_asyncio_Future_set_exception_impl(FutureObj *self, PyTypeObject *cls, + PyObject *exception) +/*[clinic end generated code: output=0a5e8b5a52f058d6 input=a245cd49d3df939b]*/ { - ENSURE_FUTURE_ALIVE(self) - return future_set_exception(self, exception); + asyncio_state *state = get_asyncio_state_by_cls(cls); + ENSURE_FUTURE_ALIVE(state, self) + return future_set_exception(state, self, exception); } /*[clinic input] _asyncio.Future.add_done_callback + cls: defining_class fn: object / * @@ -964,25 +985,27 @@ scheduled with call_soon. [clinic start generated code]*/ static PyObject * -_asyncio_Future_add_done_callback_impl(FutureObj *self, PyObject *fn, - PyObject *context) -/*[clinic end generated code: output=7ce635bbc9554c1e input=15ab0693a96e9533]*/ +_asyncio_Future_add_done_callback_impl(FutureObj *self, PyTypeObject *cls, + PyObject *fn, PyObject *context) +/*[clinic end generated code: output=922e9a4cbd601167 input=599261c521458cc2]*/ { + asyncio_state *state = get_asyncio_state_by_cls(cls); if (context == NULL) { context = PyContext_CopyCurrent(); if (context == NULL) { return NULL; } - PyObject *res = future_add_done_callback(self, fn, context); + PyObject *res = future_add_done_callback(state, self, fn, context); Py_DECREF(context); return res; } - return future_add_done_callback(self, fn, context); + return future_add_done_callback(state, self, fn, context); } /*[clinic input] _asyncio.Future.remove_done_callback + cls: defining_class fn: object / @@ -992,14 +1015,16 @@ Returns the number of callbacks removed. [clinic start generated code]*/ static PyObject * -_asyncio_Future_remove_done_callback(FutureObj *self, PyObject *fn) -/*[clinic end generated code: output=5ab1fb52b24ef31f input=0a43280a149d505b]*/ +_asyncio_Future_remove_done_callback_impl(FutureObj *self, PyTypeObject *cls, + PyObject *fn) +/*[clinic end generated code: output=2da35ccabfe41b98 input=c7518709b86fc747]*/ { PyObject *newlist; Py_ssize_t len, i, j=0; Py_ssize_t cleared_callback0 = 0; - ENSURE_FUTURE_ALIVE(self) + asyncio_state *state = get_asyncio_state_by_cls(cls); + ENSURE_FUTURE_ALIVE(state, self) if (self->fut_callback0 != NULL) { int cmp = PyObject_RichCompareBool(self->fut_callback0, fn, Py_EQ); @@ -1096,6 +1121,8 @@ fail: /*[clinic input] _asyncio.Future.cancel + cls: defining_class + / msg: object = None Cancel the future and schedule callbacks. @@ -1106,11 +1133,13 @@ return True. [clinic start generated code]*/ static PyObject * -_asyncio_Future_cancel_impl(FutureObj *self, PyObject *msg) -/*[clinic end generated code: output=3edebbc668e5aba3 input=925eb545251f2c5a]*/ +_asyncio_Future_cancel_impl(FutureObj *self, PyTypeObject *cls, + PyObject *msg) +/*[clinic end generated code: output=074956f35904b034 input=bba8f8b786941a94]*/ { - ENSURE_FUTURE_ALIVE(self) - return future_cancel(self, msg); + asyncio_state *state = get_asyncio_state_by_cls(cls); + ENSURE_FUTURE_ALIVE(state, self) + return future_cancel(state, self, msg); } /*[clinic input] @@ -1155,16 +1184,19 @@ _asyncio_Future_done_impl(FutureObj *self) /*[clinic input] _asyncio.Future.get_loop + cls: defining_class + / + Return the event loop the Future is bound to. [clinic start generated code]*/ static PyObject * -_asyncio_Future_get_loop_impl(FutureObj *self) -/*[clinic end generated code: output=119b6ea0c9816c3f input=cba48c2136c79d1f]*/ +_asyncio_Future_get_loop_impl(FutureObj *self, PyTypeObject *cls) +/*[clinic end generated code: output=f50ea6c374d9ee97 input=163c2c498b45a1f0]*/ { - ENSURE_FUTURE_ALIVE(self) - Py_INCREF(self->fut_loop); - return self->fut_loop; + asyncio_state *state = get_asyncio_state_by_cls(cls); + ENSURE_FUTURE_ALIVE(state, self) + return Py_NewRef(self->fut_loop); } static PyObject * @@ -1200,7 +1232,8 @@ FutureObj_set_blocking(FutureObj *fut, PyObject *val, void *Py_UNUSED(ignored)) static PyObject * FutureObj_get_log_traceback(FutureObj *fut, void *Py_UNUSED(ignored)) { - ENSURE_FUTURE_ALIVE(fut) + asyncio_state *state = get_asyncio_state_by_def((PyObject *)fut); + ENSURE_FUTURE_ALIVE(state, fut) if (fut->fut_log_tb) { Py_RETURN_TRUE; } @@ -1235,24 +1268,23 @@ FutureObj_get_loop(FutureObj *fut, void *Py_UNUSED(ignored)) if (!future_is_alive(fut)) { Py_RETURN_NONE; } - Py_INCREF(fut->fut_loop); - return fut->fut_loop; + return Py_NewRef(fut->fut_loop); } static PyObject * FutureObj_get_callbacks(FutureObj *fut, void *Py_UNUSED(ignored)) { + asyncio_state *state = get_asyncio_state_by_def((PyObject *)fut); Py_ssize_t i; - ENSURE_FUTURE_ALIVE(fut) + ENSURE_FUTURE_ALIVE(state, fut) if (fut->fut_callback0 == NULL) { if (fut->fut_callbacks == NULL) { Py_RETURN_NONE; } - Py_INCREF(fut->fut_callbacks); - return fut->fut_callbacks; + return Py_NewRef(fut->fut_callbacks); } Py_ssize_t len = 1; @@ -1294,23 +1326,23 @@ FutureObj_get_callbacks(FutureObj *fut, void *Py_UNUSED(ignored)) static PyObject * FutureObj_get_result(FutureObj *fut, void *Py_UNUSED(ignored)) { - ENSURE_FUTURE_ALIVE(fut) + asyncio_state *state = get_asyncio_state_by_def((PyObject *)fut); + ENSURE_FUTURE_ALIVE(state, fut) if (fut->fut_result == NULL) { Py_RETURN_NONE; } - Py_INCREF(fut->fut_result); - return fut->fut_result; + return Py_NewRef(fut->fut_result); } static PyObject * FutureObj_get_exception(FutureObj *fut, void *Py_UNUSED(ignored)) { - ENSURE_FUTURE_ALIVE(fut) + asyncio_state *state = get_asyncio_state_by_def((PyObject *)fut); + ENSURE_FUTURE_ALIVE(state, fut) if (fut->fut_exception == NULL) { Py_RETURN_NONE; } - Py_INCREF(fut->fut_exception); - return fut->fut_exception; + return Py_NewRef(fut->fut_exception); } static PyObject * @@ -1319,8 +1351,7 @@ FutureObj_get_source_traceback(FutureObj *fut, void *Py_UNUSED(ignored)) if (!future_is_alive(fut) || fut->fut_source_tb == NULL) { Py_RETURN_NONE; } - Py_INCREF(fut->fut_source_tb); - return fut->fut_source_tb; + return Py_NewRef(fut->fut_source_tb); } static PyObject * @@ -1329,8 +1360,7 @@ FutureObj_get_cancel_message(FutureObj *fut, void *Py_UNUSED(ignored)) if (fut->fut_cancel_msg == NULL) { Py_RETURN_NONE; } - Py_INCREF(fut->fut_cancel_msg); - return fut->fut_cancel_msg; + return Py_NewRef(fut->fut_cancel_msg); } static int @@ -1349,35 +1379,33 @@ FutureObj_set_cancel_message(FutureObj *fut, PyObject *msg, static PyObject * FutureObj_get_state(FutureObj *fut, void *Py_UNUSED(ignored)) { - _Py_IDENTIFIER(PENDING); - _Py_IDENTIFIER(CANCELLED); - _Py_IDENTIFIER(FINISHED); + asyncio_state *state = get_asyncio_state_by_def((PyObject *)fut); PyObject *ret = NULL; - ENSURE_FUTURE_ALIVE(fut) + ENSURE_FUTURE_ALIVE(state, fut) switch (fut->fut_state) { case STATE_PENDING: - ret = _PyUnicode_FromId(&PyId_PENDING); + ret = &_Py_ID(PENDING); break; case STATE_CANCELLED: - ret = _PyUnicode_FromId(&PyId_CANCELLED); + ret = &_Py_ID(CANCELLED); break; case STATE_FINISHED: - ret = _PyUnicode_FromId(&PyId_FINISHED); + ret = &_Py_ID(FINISHED); break; default: assert (0); } - Py_XINCREF(ret); - return ret; + return Py_XNewRef(ret); } static PyObject * FutureObj_repr(FutureObj *fut) { - ENSURE_FUTURE_ALIVE(fut) - return PyObject_CallOneArg(asyncio_future_repr_func, (PyObject *)fut); + asyncio_state *state = get_asyncio_state_by_def((PyObject *)fut); + ENSURE_FUTURE_ALIVE(state, fut) + return PyObject_CallOneArg(state->asyncio_future_repr_func, (PyObject *)fut); } /*[clinic input] @@ -1393,19 +1421,13 @@ static PyObject * _asyncio_Future__make_cancelled_error_impl(FutureObj *self) /*[clinic end generated code: output=a5df276f6c1213de input=ac6effe4ba795ecc]*/ { - return create_cancelled_error(self); + asyncio_state *state = get_asyncio_state_by_def((PyObject *)self); + return create_cancelled_error(state, self); } static void FutureObj_finalize(FutureObj *fut) { - _Py_IDENTIFIER(call_exception_handler); - _Py_IDENTIFIER(message); - _Py_IDENTIFIER(exception); - _Py_IDENTIFIER(future); - _Py_IDENTIFIER(source_traceback); - - PyObject *error_type, *error_value, *error_traceback; PyObject *context; PyObject *message = NULL; PyObject *func; @@ -1417,7 +1439,7 @@ FutureObj_finalize(FutureObj *fut) fut->fut_log_tb = 0; /* Save the current exception, if any. */ - PyErr_Fetch(&error_type, &error_value, &error_traceback); + PyObject *exc = PyErr_GetRaisedException(); context = PyDict_New(); if (context == NULL) { @@ -1430,19 +1452,19 @@ FutureObj_finalize(FutureObj *fut) goto finally; } - if (_PyDict_SetItemId(context, &PyId_message, message) < 0 || - _PyDict_SetItemId(context, &PyId_exception, fut->fut_exception) < 0 || - _PyDict_SetItemId(context, &PyId_future, (PyObject*)fut) < 0) { + if (PyDict_SetItem(context, &_Py_ID(message), message) < 0 || + PyDict_SetItem(context, &_Py_ID(exception), fut->fut_exception) < 0 || + PyDict_SetItem(context, &_Py_ID(future), (PyObject*)fut) < 0) { goto finally; } if (fut->fut_source_tb != NULL) { - if (_PyDict_SetItemId(context, &PyId_source_traceback, + if (PyDict_SetItem(context, &_Py_ID(source_traceback), fut->fut_source_tb) < 0) { goto finally; } } - func = _PyObject_GetAttrId(fut->fut_loop, &PyId_call_exception_handler); + func = PyObject_GetAttr(fut->fut_loop, &_Py_ID(call_exception_handler)); if (func != NULL) { PyObject *res = PyObject_CallOneArg(func, context); if (res == NULL) { @@ -1459,16 +1481,9 @@ finally: Py_XDECREF(message); /* Restore the saved exception. */ - PyErr_Restore(error_type, error_value, error_traceback); + PyErr_SetRaisedException(exc); } -static PyAsyncMethods FutureType_as_async = { - (unaryfunc)future_new_iter, /* am_await */ - 0, /* am_aiter */ - 0, /* am_anext */ - 0, /* am_send */ -}; - static PyMethodDef FutureType_methods[] = { _ASYNCIO_FUTURE_RESULT_METHODDEF _ASYNCIO_FUTURE_EXCEPTION_METHODDEF @@ -1485,6 +1500,12 @@ static PyMethodDef FutureType_methods[] = { {NULL, NULL} /* Sentinel */ }; +static PyMemberDef FutureType_members[] = { + {"__weaklistoffset__", T_PYSSIZET, offsetof(FutureObj, fut_weakreflist), READONLY}, + {"__dictoffset__", T_PYSSIZET, offsetof(FutureObj, dict), READONLY}, + {NULL}, +}; + #define FUTURE_COMMON_GETSETLIST \ {"_state", (getter)FutureObj_get_state, NULL, NULL}, \ {"_asyncio_future_blocking", (getter)FutureObj_get_blocking, \ @@ -1507,25 +1528,31 @@ static PyGetSetDef FutureType_getsetlist[] = { static void FutureObj_dealloc(PyObject *self); -static PyTypeObject FutureType = { - PyVarObject_HEAD_INIT(NULL, 0) - "_asyncio.Future", - sizeof(FutureObj), /* tp_basicsize */ - .tp_dealloc = FutureObj_dealloc, - .tp_as_async = &FutureType_as_async, - .tp_repr = (reprfunc)FutureObj_repr, - .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, - .tp_doc = _asyncio_Future___init____doc__, - .tp_traverse = (traverseproc)FutureObj_traverse, - .tp_clear = (inquiry)FutureObj_clear, - .tp_weaklistoffset = offsetof(FutureObj, fut_weakreflist), - .tp_iter = (getiterfunc)future_new_iter, - .tp_methods = FutureType_methods, - .tp_getset = FutureType_getsetlist, - .tp_dictoffset = offsetof(FutureObj, dict), - .tp_init = (initproc)_asyncio_Future___init__, - .tp_new = PyType_GenericNew, - .tp_finalize = (destructor)FutureObj_finalize, +static PyType_Slot Future_slots[] = { + {Py_tp_dealloc, FutureObj_dealloc}, + {Py_tp_repr, (reprfunc)FutureObj_repr}, + {Py_tp_doc, (void *)_asyncio_Future___init____doc__}, + {Py_tp_traverse, (traverseproc)FutureObj_traverse}, + {Py_tp_clear, (inquiry)FutureObj_clear}, + {Py_tp_iter, (getiterfunc)future_new_iter}, + {Py_tp_methods, FutureType_methods}, + {Py_tp_members, FutureType_members}, + {Py_tp_getset, FutureType_getsetlist}, + {Py_tp_init, (initproc)_asyncio_Future___init__}, + {Py_tp_new, PyType_GenericNew}, + {Py_tp_finalize, (destructor)FutureObj_finalize}, + + // async slots + {Py_am_await, (unaryfunc)future_new_iter}, + {0, NULL}, +}; + +static PyType_Spec Future_spec = { + .name = "_asyncio.Future", + .basicsize = sizeof(FutureObj), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = Future_slots, }; static void @@ -1533,16 +1560,12 @@ FutureObj_dealloc(PyObject *self) { FutureObj *fut = (FutureObj *)self; - if (Future_CheckExact(fut)) { - /* When fut is subclass of Future, finalizer is called from - * subtype_dealloc. - */ - if (PyObject_CallFinalizerFromDealloc(self) < 0) { - // resurrected. - return; - } + if (PyObject_CallFinalizerFromDealloc(self) < 0) { + // resurrected. + return; } + PyTypeObject *tp = Py_TYPE(fut); PyObject_GC_UnTrack(self); if (fut->fut_weakreflist != NULL) { @@ -1550,36 +1573,35 @@ FutureObj_dealloc(PyObject *self) } (void)FutureObj_clear(fut); - Py_TYPE(fut)->tp_free(fut); + tp->tp_free(fut); + Py_DECREF(tp); } /*********************** Future Iterator **************************/ -typedef struct { +typedef struct futureiterobject { PyObject_HEAD FutureObj *future; } futureiterobject; -#define FI_FREELIST_MAXLEN 255 -static futureiterobject *fi_freelist = NULL; -static Py_ssize_t fi_freelist_len = 0; - - static void FutureIter_dealloc(futureiterobject *it) { + PyTypeObject *tp = Py_TYPE(it); + asyncio_state *state = get_asyncio_state_by_def((PyObject *)it); PyObject_GC_UnTrack(it); - Py_CLEAR(it->future); + tp->tp_clear((PyObject *)it); - if (fi_freelist_len < FI_FREELIST_MAXLEN) { - fi_freelist_len++; - it->future = (FutureObj*) fi_freelist; - fi_freelist = it; + if (state->fi_freelist_len < FI_FREELIST_MAXLEN) { + state->fi_freelist_len++; + it->future = (FutureObj*) state->fi_freelist; + state->fi_freelist = it; } else { PyObject_GC_Del(it); + Py_DECREF(tp); } } @@ -1601,8 +1623,7 @@ FutureIter_am_send(futureiterobject *it, if (fut->fut_state == STATE_PENDING) { if (!fut->fut_blocking) { fut->fut_blocking = 1; - Py_INCREF(fut); - *result = (PyObject *)fut; + *result = Py_NewRef(fut); return PYGEN_NEXT; } PyErr_SetString(PyExc_RuntimeError, @@ -1656,6 +1677,14 @@ FutureIter_throw(futureiterobject *self, PyObject *const *args, Py_ssize_t nargs if (!_PyArg_CheckPositional("throw", nargs, 1, 3)) { return NULL; } + if (nargs > 1) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "the (type, exc, tb) signature of throw() is deprecated, " + "use the single-arg signature instead.", + 1) < 0) { + return NULL; + } + } type = args[0]; if (nargs == 3) { @@ -1715,16 +1744,24 @@ FutureIter_throw(futureiterobject *self, PyObject *const *args, Py_ssize_t nargs return NULL; } +static int +FutureIter_clear(futureiterobject *it) +{ + Py_CLEAR(it->future); + return 0; +} + static PyObject * FutureIter_close(futureiterobject *self, PyObject *arg) { - Py_CLEAR(self->future); + (void)FutureIter_clear(self); Py_RETURN_NONE; } static int FutureIter_traverse(futureiterobject *it, visitproc visit, void *arg) { + Py_VISIT(Py_TYPE(it)); Py_VISIT(it->future); return 0; } @@ -1736,27 +1773,26 @@ static PyMethodDef FutureIter_methods[] = { {NULL, NULL} /* Sentinel */ }; -static PyAsyncMethods FutureIterType_as_async = { - 0, /* am_await */ - 0, /* am_aiter */ - 0, /* am_anext */ - (sendfunc)FutureIter_am_send, /* am_send */ +static PyType_Slot FutureIter_slots[] = { + {Py_tp_dealloc, (destructor)FutureIter_dealloc}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_traverse, (traverseproc)FutureIter_traverse}, + {Py_tp_clear, FutureIter_clear}, + {Py_tp_iter, PyObject_SelfIter}, + {Py_tp_iternext, (iternextfunc)FutureIter_iternext}, + {Py_tp_methods, FutureIter_methods}, + + // async methods + {Py_am_send, (sendfunc)FutureIter_am_send}, + {0, NULL}, }; - -static PyTypeObject FutureIterType = { - PyVarObject_HEAD_INIT(NULL, 0) - "_asyncio.FutureIter", - .tp_basicsize = sizeof(futureiterobject), - .tp_itemsize = 0, - .tp_dealloc = (destructor)FutureIter_dealloc, - .tp_as_async = &FutureIterType_as_async, - .tp_getattro = PyObject_GenericGetAttr, - .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, - .tp_traverse = (traverseproc)FutureIter_traverse, - .tp_iter = PyObject_SelfIter, - .tp_iternext = (iternextfunc)FutureIter_iternext, - .tp_methods = FutureIter_methods, +static PyType_Spec FutureIter_spec = { + .name = "_asyncio.FutureIter", + .basicsize = sizeof(futureiterobject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = FutureIter_slots, }; static PyObject * @@ -1764,29 +1800,24 @@ future_new_iter(PyObject *fut) { futureiterobject *it; - if (!PyObject_TypeCheck(fut, &FutureType)) { - PyErr_BadInternalCall(); - return NULL; - } - - ENSURE_FUTURE_ALIVE(fut) + asyncio_state *state = get_asyncio_state_by_def((PyObject *)fut); + ENSURE_FUTURE_ALIVE(state, fut) - if (fi_freelist_len) { - fi_freelist_len--; - it = fi_freelist; - fi_freelist = (futureiterobject*) it->future; + if (state->fi_freelist_len) { + state->fi_freelist_len--; + it = state->fi_freelist; + state->fi_freelist = (futureiterobject*) it->future; it->future = NULL; _Py_NewReference((PyObject*) it); } else { - it = PyObject_GC_New(futureiterobject, &FutureIterType); + it = PyObject_GC_New(futureiterobject, state->FutureIterType); if (it == NULL) { return NULL; } } - Py_INCREF(fut); - it->future = (FutureObj*)fut; + it->future = (FutureObj*)Py_NewRef(fut); PyObject_GC_Track(it); return (PyObject*)it; } @@ -1800,9 +1831,10 @@ class _asyncio.Task "TaskObj *" "&Task_Type" [clinic start generated code]*/ /*[clinic end generated code: output=da39a3ee5e6b4b0d input=719dcef0fcc03b37]*/ -static int task_call_step_soon(TaskObj *, PyObject *); +static int task_call_step_soon(asyncio_state *state, TaskObj *, PyObject *); static PyObject * task_wakeup(TaskObj *, PyObject *); -static PyObject * task_step(TaskObj *, PyObject *); +static PyObject * task_step(asyncio_state *, TaskObj *, PyObject *); +static int task_eager_start(asyncio_state *state, TaskObj *task); /* ----- Task._step wrapper */ @@ -1817,9 +1849,11 @@ TaskStepMethWrapper_clear(TaskStepMethWrapper *o) static void TaskStepMethWrapper_dealloc(TaskStepMethWrapper *o) { + PyTypeObject *tp = Py_TYPE(o); PyObject_GC_UnTrack(o); (void)TaskStepMethWrapper_clear(o); Py_TYPE(o)->tp_free(o); + Py_DECREF(tp); } static PyObject * @@ -1834,13 +1868,15 @@ TaskStepMethWrapper_call(TaskStepMethWrapper *o, PyErr_SetString(PyExc_TypeError, "function takes no positional arguments"); return NULL; } - return task_step(o->sw_task, o->sw_arg); + asyncio_state *state = get_asyncio_state_by_def((PyObject *)o); + return task_step(state, o->sw_task, o->sw_arg); } static int TaskStepMethWrapper_traverse(TaskStepMethWrapper *o, visitproc visit, void *arg) { + Py_VISIT(Py_TYPE(o)); Py_VISIT(o->sw_task); Py_VISIT(o->sw_arg); return 0; @@ -1850,8 +1886,7 @@ static PyObject * TaskStepMethWrapper_get___self__(TaskStepMethWrapper *o, void *Py_UNUSED(ignored)) { if (o->sw_task) { - Py_INCREF(o->sw_task); - return (PyObject*)o->sw_task; + return Py_NewRef(o->sw_task); } Py_RETURN_NONE; } @@ -1861,34 +1896,36 @@ static PyGetSetDef TaskStepMethWrapper_getsetlist[] = { {NULL} /* Sentinel */ }; -static PyTypeObject TaskStepMethWrapper_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "TaskStepMethWrapper", - .tp_basicsize = sizeof(TaskStepMethWrapper), - .tp_itemsize = 0, - .tp_getset = TaskStepMethWrapper_getsetlist, - .tp_dealloc = (destructor)TaskStepMethWrapper_dealloc, - .tp_call = (ternaryfunc)TaskStepMethWrapper_call, - .tp_getattro = PyObject_GenericGetAttr, - .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, - .tp_traverse = (traverseproc)TaskStepMethWrapper_traverse, - .tp_clear = (inquiry)TaskStepMethWrapper_clear, +static PyType_Slot TaskStepMethWrapper_slots[] = { + {Py_tp_getset, TaskStepMethWrapper_getsetlist}, + {Py_tp_dealloc, (destructor)TaskStepMethWrapper_dealloc}, + {Py_tp_call, (ternaryfunc)TaskStepMethWrapper_call}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_traverse, (traverseproc)TaskStepMethWrapper_traverse}, + {Py_tp_clear, (inquiry)TaskStepMethWrapper_clear}, + {0, NULL}, +}; + +static PyType_Spec TaskStepMethWrapper_spec = { + .name = "_asyncio.TaskStepMethWrapper", + .basicsize = sizeof(TaskStepMethWrapper), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = TaskStepMethWrapper_slots, }; static PyObject * TaskStepMethWrapper_new(TaskObj *task, PyObject *arg) { + asyncio_state *state = get_asyncio_state_by_def((PyObject *)task); TaskStepMethWrapper *o; - o = PyObject_GC_New(TaskStepMethWrapper, &TaskStepMethWrapper_Type); + o = PyObject_GC_New(TaskStepMethWrapper, state->TaskStepMethWrapper_Type); if (o == NULL) { return NULL; } - Py_INCREF(task); - o->sw_task = task; - - Py_XINCREF(arg); - o->sw_arg = arg; + o->sw_task = (TaskObj*)Py_NewRef(task); + o->sw_arg = Py_XNewRef(arg); PyObject_GC_Track(o); return (PyObject*) o; @@ -1906,12 +1943,10 @@ static PyMethodDef TaskWakeupDef = { /* ----- Task introspection helpers */ static int -register_task(PyObject *task) +register_task(asyncio_state *state, PyObject *task) { - _Py_IDENTIFIER(add); - - PyObject *res = _PyObject_CallMethodIdOneArg(all_tasks, - &PyId_add, task); + PyObject *res = PyObject_CallMethodOneArg(state->scheduled_tasks, + &_Py_ID(add), task); if (res == NULL) { return -1; } @@ -1919,14 +1954,17 @@ register_task(PyObject *task) return 0; } - static int -unregister_task(PyObject *task) +register_eager_task(asyncio_state *state, PyObject *task) { - _Py_IDENTIFIER(discard); + return PySet_Add(state->eager_tasks, task); +} - PyObject *res = _PyObject_CallMethodIdOneArg(all_tasks, - &PyId_discard, task); +static int +unregister_task(asyncio_state *state, PyObject *task) +{ + PyObject *res = PyObject_CallMethodOneArg(state->scheduled_tasks, + &_Py_ID(discard), task); if (res == NULL) { return -1; } @@ -1934,9 +1972,14 @@ unregister_task(PyObject *task) return 0; } +static int +unregister_eager_task(asyncio_state *state, PyObject *task) +{ + return PySet_Discard(state->eager_tasks, task); +} static int -enter_task(PyObject *loop, PyObject *task) +enter_task(asyncio_state *state, PyObject *loop, PyObject *task) { PyObject *item; Py_hash_t hash; @@ -1944,7 +1987,7 @@ enter_task(PyObject *loop, PyObject *task) if (hash == -1) { return -1; } - item = _PyDict_GetItem_KnownHash(current_tasks, loop, hash); + item = _PyDict_GetItem_KnownHash(state->current_tasks, loop, hash); if (item != NULL) { Py_INCREF(item); PyErr_Format( @@ -1958,12 +2001,12 @@ enter_task(PyObject *loop, PyObject *task) if (PyErr_Occurred()) { return -1; } - return _PyDict_SetItem_KnownHash(current_tasks, loop, task, hash); + return _PyDict_SetItem_KnownHash(state->current_tasks, loop, task, hash); } static int -leave_task(PyObject *loop, PyObject *task) +leave_task(asyncio_state *state, PyObject *loop, PyObject *task) /*[clinic end generated code: output=0ebf6db4b858fb41 input=51296a46313d1ad8]*/ { PyObject *item; @@ -1972,7 +2015,7 @@ leave_task(PyObject *loop, PyObject *task) if (hash == -1) { return -1; } - item = _PyDict_GetItem_KnownHash(current_tasks, loop, hash); + item = _PyDict_GetItem_KnownHash(state->current_tasks, loop, hash); if (item != task) { if (item == NULL) { /* Not entered, replace with None */ @@ -1984,7 +2027,43 @@ leave_task(PyObject *loop, PyObject *task) task, item, NULL); return -1; } - return _PyDict_DelItem_KnownHash(current_tasks, loop, hash); + return _PyDict_DelItem_KnownHash(state->current_tasks, loop, hash); +} + +static PyObject * +swap_current_task(asyncio_state *state, PyObject *loop, PyObject *task) +{ + PyObject *prev_task; + Py_hash_t hash; + hash = PyObject_Hash(loop); + if (hash == -1) { + return NULL; + } + + prev_task = _PyDict_GetItem_KnownHash(state->current_tasks, loop, hash); + if (prev_task == NULL) { + if (PyErr_Occurred()) { + return NULL; + } + prev_task = Py_None; + } + Py_INCREF(prev_task); + + if (task == Py_None) { + if (_PyDict_DelItem_KnownHash(state->current_tasks, loop, hash) == -1) { + goto error; + } + } else { + if (_PyDict_SetItem_KnownHash(state->current_tasks, loop, task, hash) == -1) { + goto error; + } + } + + return prev_task; + +error: + Py_DECREF(prev_task); + return NULL; } /* ----- Task */ @@ -1997,21 +2076,23 @@ _asyncio.Task.__init__ loop: object = None name: object = None context: object = None + eager_start: bool = False A coroutine wrapped in a Future. [clinic start generated code]*/ static int _asyncio_Task___init___impl(TaskObj *self, PyObject *coro, PyObject *loop, - PyObject *name, PyObject *context) -/*[clinic end generated code: output=49ac96fe33d0e5c7 input=924522490c8ce825]*/ - + PyObject *name, PyObject *context, + int eager_start) +/*[clinic end generated code: output=7aced2d27836f1a1 input=18e3f113a51b829d]*/ { if (future_init((FutureObj*)self, loop)) { return -1; } - int is_coro = is_coroutine(coro); + asyncio_state *state = get_asyncio_state_by_def((PyObject *)self); + int is_coro = is_coroutine(state, coro); if (is_coro == -1) { return -1; } @@ -2040,7 +2121,10 @@ _asyncio_Task___init___impl(TaskObj *self, PyObject *coro, PyObject *loop, Py_XSETREF(self->task_coro, coro); if (name == Py_None) { - name = PyUnicode_FromFormat("Task-%" PRIu64, ++task_name_counter); + // optimization: defer task name formatting + // store the task counter as PyLong in the name + // for deferred formatting in get_name + name = PyLong_FromUnsignedLongLong(++state->task_name_counter); } else if (!PyUnicode_CheckExact(name)) { name = PyObject_Str(name); } else { @@ -2051,10 +2135,25 @@ _asyncio_Task___init___impl(TaskObj *self, PyObject *coro, PyObject *loop, return -1; } - if (task_call_step_soon(self, NULL)) { + if (eager_start) { + PyObject *res = PyObject_CallMethodNoArgs(loop, &_Py_ID(is_running)); + if (res == NULL) { + return -1; + } + int is_loop_running = Py_IsTrue(res); + Py_DECREF(res); + if (is_loop_running) { + if (task_eager_start(state, self)) { + return -1; + } + return 0; + } + } + + if (task_call_step_soon(state, self, NULL)) { return -1; } - return register_task((PyObject*)self); + return register_task(state, (PyObject*)self); } static int @@ -2071,11 +2170,23 @@ TaskObj_clear(TaskObj *task) static int TaskObj_traverse(TaskObj *task, visitproc visit, void *arg) { + Py_VISIT(Py_TYPE(task)); Py_VISIT(task->task_context); Py_VISIT(task->task_coro); Py_VISIT(task->task_name); Py_VISIT(task->task_fut_waiter); - (void)FutureObj_traverse((FutureObj*) task, visit, arg); + FutureObj *fut = (FutureObj *)task; + Py_VISIT(fut->fut_loop); + Py_VISIT(fut->fut_callback0); + Py_VISIT(fut->fut_context0); + Py_VISIT(fut->fut_callbacks); + Py_VISIT(fut->fut_result); + Py_VISIT(fut->fut_exception); + Py_VISIT(fut->fut_exception_tb); + Py_VISIT(fut->fut_source_tb); + Py_VISIT(fut->fut_cancel_msg); + Py_VISIT(fut->fut_cancelled_exc); + Py_VISIT(fut->dict); return 0; } @@ -2120,8 +2231,7 @@ static PyObject * TaskObj_get_coro(TaskObj *task, void *Py_UNUSED(ignored)) { if (task->task_coro) { - Py_INCREF(task->task_coro); - return task->task_coro; + return Py_NewRef(task->task_coro); } Py_RETURN_NONE; @@ -2131,8 +2241,7 @@ static PyObject * TaskObj_get_fut_waiter(TaskObj *task, void *Py_UNUSED(ignored)) { if (task->task_fut_waiter) { - Py_INCREF(task->task_fut_waiter); - return task->task_fut_waiter; + return Py_NewRef(task->task_fut_waiter); } Py_RETURN_NONE; @@ -2141,7 +2250,9 @@ TaskObj_get_fut_waiter(TaskObj *task, void *Py_UNUSED(ignored)) static PyObject * TaskObj_repr(TaskObj *task) { - return PyObject_CallOneArg(asyncio_task_repr_func, (PyObject *)task); + asyncio_state *state = get_asyncio_state_by_def((PyObject *)task); + return PyObject_CallOneArg(state->asyncio_task_repr_func, + (PyObject *)task); } @@ -2213,8 +2324,8 @@ _asyncio_Task_cancel_impl(TaskObj *self, PyObject *msg) PyObject *res; int is_true; - res = _PyObject_CallMethodIdOneArg(self->task_fut_waiter, - &PyId_cancel, msg); + res = PyObject_CallMethodOneArg(self->task_fut_waiter, + &_Py_ID(cancel), msg); if (res == NULL) { return NULL; } @@ -2278,6 +2389,8 @@ _asyncio_Task_uncancel_impl(TaskObj *self) /*[clinic input] _asyncio.Task.get_stack + cls: defining_class + / * limit: object = None @@ -2303,16 +2416,21 @@ returned for a suspended coroutine. [clinic start generated code]*/ static PyObject * -_asyncio_Task_get_stack_impl(TaskObj *self, PyObject *limit) -/*[clinic end generated code: output=c9aeeeebd1e18118 input=05b323d42b809b90]*/ +_asyncio_Task_get_stack_impl(TaskObj *self, PyTypeObject *cls, + PyObject *limit) +/*[clinic end generated code: output=6774dfc10d3857fa input=8e01c9b2618ae953]*/ { - return PyObject_CallFunctionObjArgs( - asyncio_task_get_stack_func, self, limit, NULL); + asyncio_state *state = get_asyncio_state_by_cls(cls); + PyObject *stack[] = {(PyObject *)self, limit}; + return PyObject_Vectorcall(state->asyncio_task_get_stack_func, + stack, 2, NULL); } /*[clinic input] _asyncio.Task.print_stack + cls: defining_class + / * limit: object = None file: object = None @@ -2327,12 +2445,14 @@ to sys.stderr. [clinic start generated code]*/ static PyObject * -_asyncio_Task_print_stack_impl(TaskObj *self, PyObject *limit, - PyObject *file) -/*[clinic end generated code: output=7339e10314cd3f4d input=1a0352913b7fcd92]*/ +_asyncio_Task_print_stack_impl(TaskObj *self, PyTypeObject *cls, + PyObject *limit, PyObject *file) +/*[clinic end generated code: output=b38affe9289ec826 input=150b35ba2d3a7dee]*/ { - return PyObject_CallFunctionObjArgs( - asyncio_task_print_stack_func, self, limit, file, NULL); + asyncio_state *state = get_asyncio_state_by_cls(cls); + PyObject *stack[] = {(PyObject *)self, limit, file}; + return PyObject_Vectorcall(state->asyncio_task_print_stack_func, + stack, 3, NULL); } /*[clinic input] @@ -2375,8 +2495,18 @@ static PyObject * _asyncio_Task_get_coro_impl(TaskObj *self) /*[clinic end generated code: output=bcac27c8cc6c8073 input=d2e8606c42a7b403]*/ { - Py_INCREF(self->task_coro); - return self->task_coro; + return Py_NewRef(self->task_coro); +} + +/*[clinic input] +_asyncio.Task.get_context +[clinic start generated code]*/ + +static PyObject * +_asyncio_Task_get_context_impl(TaskObj *self) +/*[clinic end generated code: output=6996f53d3dc01aef input=87c0b209b8fceeeb]*/ +{ + return Py_NewRef(self->task_context); } /*[clinic input] @@ -2388,8 +2518,14 @@ _asyncio_Task_get_name_impl(TaskObj *self) /*[clinic end generated code: output=0ecf1570c3b37a8f input=a4a6595d12f4f0f8]*/ { if (self->task_name) { - Py_INCREF(self->task_name); - return self->task_name; + if (PyLong_CheckExact(self->task_name)) { + PyObject *name = PyUnicode_FromFormat("Task-%S", self->task_name); + if (name == NULL) { + return NULL; + } + Py_SETREF(self->task_name, name); + } + return Py_NewRef(self->task_name); } Py_RETURN_NONE; @@ -2422,22 +2558,16 @@ _asyncio_Task_set_name(TaskObj *self, PyObject *value) static void TaskObj_finalize(TaskObj *task) { - _Py_IDENTIFIER(call_exception_handler); - _Py_IDENTIFIER(task); - _Py_IDENTIFIER(message); - _Py_IDENTIFIER(source_traceback); - PyObject *context; PyObject *message = NULL; PyObject *func; - PyObject *error_type, *error_value, *error_traceback; if (task->task_state != STATE_PENDING || !task->task_log_destroy_pending) { goto done; } /* Save the current exception, if any. */ - PyErr_Fetch(&error_type, &error_value, &error_traceback); + PyObject *exc = PyErr_GetRaisedException(); context = PyDict_New(); if (context == NULL) { @@ -2449,21 +2579,21 @@ TaskObj_finalize(TaskObj *task) goto finally; } - if (_PyDict_SetItemId(context, &PyId_message, message) < 0 || - _PyDict_SetItemId(context, &PyId_task, (PyObject*)task) < 0) + if (PyDict_SetItem(context, &_Py_ID(message), message) < 0 || + PyDict_SetItem(context, &_Py_ID(task), (PyObject*)task) < 0) { goto finally; } if (task->task_source_tb != NULL) { - if (_PyDict_SetItemId(context, &PyId_source_traceback, + if (PyDict_SetItem(context, &_Py_ID(source_traceback), task->task_source_tb) < 0) { goto finally; } } - func = _PyObject_GetAttrId(task->task_loop, &PyId_call_exception_handler); + func = PyObject_GetAttr(task->task_loop, &_Py_ID(call_exception_handler)); if (func != NULL) { PyObject *res = PyObject_CallOneArg(func, context); if (res == NULL) { @@ -2480,7 +2610,7 @@ finally: Py_XDECREF(message); /* Restore the saved exception. */ - PyErr_Restore(error_type, error_value, error_traceback); + PyErr_SetRaisedException(exc); done: FutureObj_finalize((FutureObj*)task); @@ -2506,10 +2636,17 @@ static PyMethodDef TaskType_methods[] = { _ASYNCIO_TASK_GET_NAME_METHODDEF _ASYNCIO_TASK_SET_NAME_METHODDEF _ASYNCIO_TASK_GET_CORO_METHODDEF + _ASYNCIO_TASK_GET_CONTEXT_METHODDEF {"__class_getitem__", Py_GenericAlias, METH_O|METH_CLASS, PyDoc_STR("See PEP 585")}, {NULL, NULL} /* Sentinel */ }; +static PyMemberDef TaskType_members[] = { + {"__weaklistoffset__", T_PYSSIZET, offsetof(TaskObj, task_weakreflist), READONLY}, + {"__dictoffset__", T_PYSSIZET, offsetof(TaskObj, dict), READONLY}, + {NULL}, +}; + static PyGetSetDef TaskType_getsetlist[] = { FUTURE_COMMON_GETSETLIST {"_log_destroy_pending", (getter)TaskObj_get_log_destroy_pending, @@ -2520,26 +2657,31 @@ static PyGetSetDef TaskType_getsetlist[] = { {NULL} /* Sentinel */ }; -static PyTypeObject TaskType = { - PyVarObject_HEAD_INIT(NULL, 0) - "_asyncio.Task", - sizeof(TaskObj), /* tp_basicsize */ - .tp_base = &FutureType, - .tp_dealloc = TaskObj_dealloc, - .tp_as_async = &FutureType_as_async, - .tp_repr = (reprfunc)TaskObj_repr, - .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, - .tp_doc = _asyncio_Task___init____doc__, - .tp_traverse = (traverseproc)TaskObj_traverse, - .tp_clear = (inquiry)TaskObj_clear, - .tp_weaklistoffset = offsetof(TaskObj, task_weakreflist), - .tp_iter = (getiterfunc)future_new_iter, - .tp_methods = TaskType_methods, - .tp_getset = TaskType_getsetlist, - .tp_dictoffset = offsetof(TaskObj, dict), - .tp_init = (initproc)_asyncio_Task___init__, - .tp_new = PyType_GenericNew, - .tp_finalize = (destructor)TaskObj_finalize, +static PyType_Slot Task_slots[] = { + {Py_tp_dealloc, TaskObj_dealloc}, + {Py_tp_repr, (reprfunc)TaskObj_repr}, + {Py_tp_doc, (void *)_asyncio_Task___init____doc__}, + {Py_tp_traverse, (traverseproc)TaskObj_traverse}, + {Py_tp_clear, (inquiry)TaskObj_clear}, + {Py_tp_iter, (getiterfunc)future_new_iter}, + {Py_tp_methods, TaskType_methods}, + {Py_tp_members, TaskType_members}, + {Py_tp_getset, TaskType_getsetlist}, + {Py_tp_init, (initproc)_asyncio_Task___init__}, + {Py_tp_new, PyType_GenericNew}, + {Py_tp_finalize, (destructor)TaskObj_finalize}, + + // async slots + {Py_am_await, (unaryfunc)future_new_iter}, + {0, NULL}, +}; + +static PyType_Spec Task_spec = { + .name = "_asyncio.Task", + .basicsize = sizeof(TaskObj), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = Task_slots, }; static void @@ -2547,16 +2689,12 @@ TaskObj_dealloc(PyObject *self) { TaskObj *task = (TaskObj *)self; - if (Task_CheckExact(self)) { - /* When fut is subclass of Task, finalizer is called from - * subtype_dealloc. - */ - if (PyObject_CallFinalizerFromDealloc(self) < 0) { - // resurrected. - return; - } + if (PyObject_CallFinalizerFromDealloc(self) < 0) { + // resurrected. + return; } + PyTypeObject *tp = Py_TYPE(task); PyObject_GC_UnTrack(self); if (task->task_weakreflist != NULL) { @@ -2564,33 +2702,31 @@ TaskObj_dealloc(PyObject *self) } (void)TaskObj_clear(task); - Py_TYPE(task)->tp_free(task); + tp->tp_free(task); + Py_DECREF(tp); } static int -task_call_step_soon(TaskObj *task, PyObject *arg) +task_call_step_soon(asyncio_state *state, TaskObj *task, PyObject *arg) { PyObject *cb = TaskStepMethWrapper_new(task, arg); if (cb == NULL) { return -1; } - int ret = call_soon(task->task_loop, cb, NULL, task->task_context); + int ret = call_soon(state, task->task_loop, cb, NULL, task->task_context); Py_DECREF(cb); return ret; } static PyObject * -task_set_error_soon(TaskObj *task, PyObject *et, const char *format, ...) +task_set_error_soon(asyncio_state *state, TaskObj *task, PyObject *et, + const char *format, ...) { PyObject* msg; va_list vargs; -#ifdef HAVE_STDARG_PROTOTYPES va_start(vargs, format); -#else - va_start(vargs); -#endif msg = PyUnicode_FromFormatV(format, vargs); va_end(vargs); @@ -2604,7 +2740,7 @@ task_set_error_soon(TaskObj *task, PyObject *et, const char *format, ...) return NULL; } - if (task_call_step_soon(task, e) == -1) { + if (task_call_step_soon(state, task, e) == -1) { Py_DECREF(e); return NULL; } @@ -2628,7 +2764,7 @@ gen_status_from_result(PyObject **result) } static PyObject * -task_step_impl(TaskObj *task, PyObject *exc) +task_step_impl(asyncio_state *state, TaskObj *task, PyObject *exc) { int res; int clear_exc = 0; @@ -2637,7 +2773,7 @@ task_step_impl(TaskObj *task, PyObject *exc) PyObject *o; if (task->task_state != STATE_PENDING) { - PyErr_Format(asyncio_InvalidStateError, + PyErr_Format(state->asyncio_InvalidStateError, "_step(): already done: %R %R", task, exc ? exc : Py_None); @@ -2649,7 +2785,7 @@ task_step_impl(TaskObj *task, PyObject *exc) if (exc) { /* Check if exc is a CancelledError */ - res = PyObject_IsInstance(exc, asyncio_CancelledError); + res = PyObject_IsInstance(exc, state->asyncio_CancelledError); if (res == -1) { /* An error occurred, abort */ goto fail; @@ -2662,7 +2798,7 @@ task_step_impl(TaskObj *task, PyObject *exc) if (!exc) { /* exc was not a CancelledError */ - exc = create_cancelled_error((FutureObj*)task); + exc = create_cancelled_error(state, (FutureObj*)task); if (!exc) { goto fail; @@ -2690,7 +2826,7 @@ task_step_impl(TaskObj *task, PyObject *exc) gen_status = PyIter_Send(coro, Py_None, &result); } else { - result = _PyObject_CallMethodIdOneArg(coro, &PyId_throw, exc); + result = PyObject_CallMethodOneArg(coro, &_Py_ID(throw), exc); gen_status = gen_status_from_result(&result); if (clear_exc) { /* We created 'exc' during this call */ @@ -2699,8 +2835,6 @@ task_step_impl(TaskObj *task, PyObject *exc) } if (gen_status == PYGEN_RETURN || gen_status == PYGEN_ERROR) { - PyObject *et, *ev, *tb; - if (result != NULL) { /* The error is StopIteration and that means that the underlying coroutine has resolved */ @@ -2709,10 +2843,11 @@ task_step_impl(TaskObj *task, PyObject *exc) if (task->task_must_cancel) { // Task is cancelled right before coro stops. task->task_must_cancel = 0; - tmp = future_cancel((FutureObj*)task, task->task_cancel_msg); + tmp = future_cancel(state, (FutureObj*)task, + task->task_cancel_msg); } else { - tmp = future_set_result((FutureObj*)task, result); + tmp = future_set_result(state, (FutureObj*)task, result); } Py_DECREF(result); @@ -2724,65 +2859,66 @@ task_step_impl(TaskObj *task, PyObject *exc) Py_RETURN_NONE; } - if (PyErr_ExceptionMatches(asyncio_CancelledError)) { + if (PyErr_ExceptionMatches(state->asyncio_CancelledError)) { /* CancelledError */ - PyErr_Fetch(&et, &ev, &tb); - assert(et); - PyErr_NormalizeException(&et, &ev, &tb); - if (tb != NULL) { - PyException_SetTraceback(ev, tb); - Py_DECREF(tb); - } - Py_XDECREF(et); + + PyObject *exc = PyErr_GetRaisedException(); + assert(exc); FutureObj *fut = (FutureObj*)task; /* transfer ownership */ - fut->fut_cancelled_exc = ev; + fut->fut_cancelled_exc = exc; - return future_cancel(fut, NULL); + return future_cancel(state, fut, NULL); } /* Some other exception; pop it and call Task.set_exception() */ - PyErr_Fetch(&et, &ev, &tb); - assert(et); - PyErr_NormalizeException(&et, &ev, &tb); - if (tb != NULL) { - PyException_SetTraceback(ev, tb); - } + PyObject *exc = PyErr_GetRaisedException(); + assert(exc); - o = future_set_exception((FutureObj*)task, ev); + o = future_set_exception(state, (FutureObj*)task, exc); if (!o) { /* An exception in Task.set_exception() */ - Py_DECREF(et); - Py_XDECREF(tb); - Py_XDECREF(ev); + Py_DECREF(exc); goto fail; } assert(o == Py_None); Py_DECREF(o); - if (PyErr_GivenExceptionMatches(et, PyExc_KeyboardInterrupt) || - PyErr_GivenExceptionMatches(et, PyExc_SystemExit)) + if (PyErr_GivenExceptionMatches(exc, PyExc_KeyboardInterrupt) || + PyErr_GivenExceptionMatches(exc, PyExc_SystemExit)) { /* We've got a KeyboardInterrupt or a SystemError; re-raise it */ - PyErr_Restore(et, ev, tb); + PyErr_SetRaisedException(exc); goto fail; } - Py_DECREF(et); - Py_XDECREF(tb); - Py_XDECREF(ev); + Py_DECREF(exc); Py_RETURN_NONE; } + PyObject *ret = task_step_handle_result_impl(state, task, result); + return ret; + +fail: + return NULL; +} + + +static PyObject * +task_step_handle_result_impl(asyncio_state *state, TaskObj *task, PyObject *result) +{ + int res; + PyObject *o; + if (result == (PyObject*)task) { /* We have a task that wants to await on itself */ goto self_await; } /* Check if `result` is FutureObj or TaskObj (and not a subclass) */ - if (Future_CheckExact(result) || Task_CheckExact(result)) { + if (Future_CheckExact(state, result) || Task_CheckExact(state, result)) { PyObject *wrapper; PyObject *tmp; FutureObj *fut = (FutureObj*)result; @@ -2803,7 +2939,7 @@ task_step_impl(TaskObj *task, PyObject *exc) if (wrapper == NULL) { goto fail; } - tmp = future_add_done_callback( + tmp = future_add_done_callback(state, (FutureObj*)result, wrapper, task->task_context); Py_DECREF(wrapper); if (tmp == NULL) { @@ -2817,7 +2953,7 @@ task_step_impl(TaskObj *task, PyObject *exc) if (task->task_must_cancel) { PyObject *r; int is_true; - r = _PyObject_CallMethodIdOneArg(result, &PyId_cancel, + r = PyObject_CallMethodOneArg(result, &_Py_ID(cancel), task->task_cancel_msg); if (r == NULL) { return NULL; @@ -2838,14 +2974,14 @@ task_step_impl(TaskObj *task, PyObject *exc) /* Check if `result` is None */ if (result == Py_None) { /* Bare yield relinquishes control for one event loop iteration. */ - if (task_call_step_soon(task, NULL)) { + if (task_call_step_soon(state, task, NULL)) { goto fail; } return result; } /* Check if `result` is a Future-compatible object */ - if (_PyObject_LookupAttrId(result, &PyId__asyncio_future_blocking, &o) < 0) { + if (_PyObject_LookupAttr(result, &_Py_ID(_asyncio_future_blocking), &o) < 0) { goto fail; } if (o != NULL && o != Py_None) { @@ -2860,7 +2996,7 @@ task_step_impl(TaskObj *task, PyObject *exc) } /* Check if `result` future is attached to a different loop */ - PyObject *oloop = get_future_loop(result); + PyObject *oloop = get_future_loop(state, result); if (oloop == NULL) { goto fail; } @@ -2875,8 +3011,8 @@ task_step_impl(TaskObj *task, PyObject *exc) } /* result._asyncio_future_blocking = False */ - if (_PyObject_SetAttrId( - result, &PyId__asyncio_future_blocking, Py_False) == -1) { + if (PyObject_SetAttr( + result, &_Py_ID(_asyncio_future_blocking), Py_False) == -1) { goto fail; } @@ -2886,8 +3022,8 @@ task_step_impl(TaskObj *task, PyObject *exc) } /* result.add_done_callback(task._wakeup) */ - PyObject *add_cb = _PyObject_GetAttrId( - result, &PyId_add_done_callback); + PyObject *add_cb = PyObject_GetAttr( + result, &_Py_ID(add_done_callback)); if (add_cb == NULL) { Py_DECREF(wrapper); goto fail; @@ -2895,7 +3031,8 @@ task_step_impl(TaskObj *task, PyObject *exc) PyObject *stack[2]; stack[0] = wrapper; stack[1] = (PyObject *)task->task_context; - tmp = PyObject_Vectorcall(add_cb, stack, 1, context_kwname); + EVAL_CALL_STAT_INC_IF_FUNCTION(EVAL_CALL_API, add_cb); + tmp = PyObject_Vectorcall(add_cb, stack, 1, state->context_kwname); Py_DECREF(add_cb); Py_DECREF(wrapper); if (tmp == NULL) { @@ -2909,7 +3046,7 @@ task_step_impl(TaskObj *task, PyObject *exc) if (task->task_must_cancel) { PyObject *r; int is_true; - r = _PyObject_CallMethodIdOneArg(result, &PyId_cancel, + r = PyObject_CallMethodOneArg(result, &_Py_ID(cancel), task->task_cancel_msg); if (r == NULL) { return NULL; @@ -2936,7 +3073,7 @@ task_step_impl(TaskObj *task, PyObject *exc) if (res) { /* `result` is a generator */ o = task_set_error_soon( - task, PyExc_RuntimeError, + state, task, PyExc_RuntimeError, "yield was used instead of yield from for " "generator in task %R with %R", task, result); Py_DECREF(result); @@ -2945,20 +3082,20 @@ task_step_impl(TaskObj *task, PyObject *exc) /* The `result` is none of the above */ o = task_set_error_soon( - task, PyExc_RuntimeError, "Task got bad yield: %R", result); + state, task, PyExc_RuntimeError, "Task got bad yield: %R", result); Py_DECREF(result); return o; self_await: o = task_set_error_soon( - task, PyExc_RuntimeError, + state, task, PyExc_RuntimeError, "Task cannot await on itself: %R", task); Py_DECREF(result); return o; yield_insteadof_yf: o = task_set_error_soon( - task, PyExc_RuntimeError, + state, task, PyExc_RuntimeError, "yield was used instead of yield from " "in task %R with %R", task, result); @@ -2967,7 +3104,7 @@ yield_insteadof_yf: different_loop: o = task_set_error_soon( - task, PyExc_RuntimeError, + state, task, PyExc_RuntimeError, "Task %R got Future %R attached to a different loop", task, result); Py_DECREF(result); @@ -2979,25 +3116,24 @@ fail: } static PyObject * -task_step(TaskObj *task, PyObject *exc) +task_step(asyncio_state *state, TaskObj *task, PyObject *exc) { PyObject *res; - if (enter_task(task->task_loop, (PyObject*)task) < 0) { + if (enter_task(state, task->task_loop, (PyObject*)task) < 0) { return NULL; } - res = task_step_impl(task, exc); + res = task_step_impl(state, task, exc); if (res == NULL) { - PyObject *et, *ev, *tb; - PyErr_Fetch(&et, &ev, &tb); - leave_task(task->task_loop, (PyObject*)task); - _PyErr_ChainExceptions(et, ev, tb); /* Normalizes (et, ev, tb) */ + PyObject *exc = PyErr_GetRaisedException(); + leave_task(state, task->task_loop, (PyObject*)task); + _PyErr_ChainExceptions1(exc); return NULL; } else { - if (leave_task(task->task_loop, (PyObject*)task) < 0) { + if (leave_task(state, task->task_loop, (PyObject*)task) < 0) { Py_DECREF(res); return NULL; } @@ -3007,16 +3143,75 @@ task_step(TaskObj *task, PyObject *exc) } } +static int +task_eager_start(asyncio_state *state, TaskObj *task) +{ + assert(task != NULL); + PyObject *prevtask = swap_current_task(state, task->task_loop, (PyObject *)task); + if (prevtask == NULL) { + return -1; + } + + if (register_eager_task(state, (PyObject *)task) == -1) { + Py_DECREF(prevtask); + return -1; + } + + if (PyContext_Enter(task->task_context) == -1) { + Py_DECREF(prevtask); + return -1; + } + + int retval = 0; + + PyObject *stepres = task_step_impl(state, task, NULL); + if (stepres == NULL) { + PyObject *exc = PyErr_GetRaisedException(); + _PyErr_ChainExceptions1(exc); + retval = -1; + } else { + Py_DECREF(stepres); + } + + PyObject *curtask = swap_current_task(state, task->task_loop, prevtask); + Py_DECREF(prevtask); + if (curtask == NULL) { + retval = -1; + } else { + assert(curtask == (PyObject *)task); + Py_DECREF(curtask); + } + + if (unregister_eager_task(state, (PyObject *)task) == -1) { + retval = -1; + } + + if (PyContext_Exit(task->task_context) == -1) { + retval = -1; + } + + if (task->task_state == STATE_PENDING) { + if (register_task(state, (PyObject *)task) == -1) { + retval = -1; + } + } else { + // This seems to really help performance on pyperformance benchmarks + Py_CLEAR(task->task_coro); + } + + return retval; +} + static PyObject * task_wakeup(TaskObj *task, PyObject *o) { - PyObject *et, *ev, *tb; PyObject *result; assert(o); - if (Future_CheckExact(o) || Task_CheckExact(o)) { + asyncio_state *state = get_asyncio_state_by_def((PyObject *)task); + if (Future_CheckExact(state, o) || Task_CheckExact(state, o)) { PyObject *fut_result = NULL; - int res = future_get_result((FutureObj*)o, &fut_result); + int res = future_get_result(state, (FutureObj*)o, &fut_result); switch(res) { case -1: @@ -3024,10 +3219,10 @@ task_wakeup(TaskObj *task, PyObject *o) break; /* exception raised */ case 0: Py_DECREF(fut_result); - return task_step(task, NULL); + return task_step(state, task, NULL); default: assert(res == 1); - result = task_step(task, fut_result); + result = task_step(state, task, fut_result); Py_DECREF(fut_result); return result; } @@ -3036,23 +3231,17 @@ task_wakeup(TaskObj *task, PyObject *o) PyObject *fut_result = PyObject_CallMethod(o, "result", NULL); if (fut_result != NULL) { Py_DECREF(fut_result); - return task_step(task, NULL); + return task_step(state, task, NULL); } /* exception raised */ } - PyErr_Fetch(&et, &ev, &tb); - assert(et); - PyErr_NormalizeException(&et, &ev, &tb); - if (tb != NULL) { - PyException_SetTraceback(ev, tb); - } + PyObject *exc = PyErr_GetRaisedException(); + assert(exc); - result = task_step(task, ev); + result = task_step(state, task, exc); - Py_DECREF(et); - Py_XDECREF(tb); - Py_XDECREF(ev); + Py_DECREF(exc); return result; } @@ -3076,7 +3265,8 @@ _asyncio__get_running_loop_impl(PyObject *module) /*[clinic end generated code: output=b4390af721411a0a input=0a21627e25a4bd43]*/ { PyObject *loop; - if (get_running_loop(&loop)) { + asyncio_state *state = get_asyncio_state(module); + if (get_running_loop(state, &loop)) { return NULL; } if (loop == NULL) { @@ -3101,7 +3291,8 @@ static PyObject * _asyncio__set_running_loop(PyObject *module, PyObject *loop) /*[clinic end generated code: output=ae56bf7a28ca189a input=4c9720233d606604]*/ { - if (set_running_loop(loop)) { + asyncio_state *state = get_asyncio_state(module); + if (set_running_loop(state, loop)) { return NULL; } Py_RETURN_NONE; @@ -3124,24 +3315,8 @@ static PyObject * _asyncio_get_event_loop_impl(PyObject *module) /*[clinic end generated code: output=2a2d8b2f824c648b input=9364bf2916c8655d]*/ { - return get_event_loop(1); -} - -// This internal method is going away in Python 3.12, left here only for -// backwards compatibility with 3.10.0 - 3.10.8 and 3.11.0. -// Similarly, this method's Python equivalent in asyncio.events is going -// away as well. -// See GH-99949 for more details. -/*[clinic input] -_asyncio._get_event_loop - stacklevel: int = 3 -[clinic start generated code]*/ - -static PyObject * -_asyncio__get_event_loop_impl(PyObject *module, int stacklevel) -/*[clinic end generated code: output=9c1d6d3c802e67c9 input=d17aebbd686f711d]*/ -{ - return get_event_loop(stacklevel-1); + asyncio_state *state = get_asyncio_state(module); + return get_event_loop(state); } /*[clinic input] @@ -3157,7 +3332,8 @@ _asyncio_get_running_loop_impl(PyObject *module) /*[clinic end generated code: output=c247b5f9e529530e input=2a3bf02ba39f173d]*/ { PyObject *loop; - if (get_running_loop(&loop)) { + asyncio_state *state = get_asyncio_state(module); + if (get_running_loop(state, &loop)) { return NULL; } if (loop == NULL) { @@ -3182,7 +3358,29 @@ static PyObject * _asyncio__register_task_impl(PyObject *module, PyObject *task) /*[clinic end generated code: output=8672dadd69a7d4e2 input=21075aaea14dfbad]*/ { - if (register_task(task) < 0) { + asyncio_state *state = get_asyncio_state(module); + if (register_task(state, task) < 0) { + return NULL; + } + Py_RETURN_NONE; +} + +/*[clinic input] +_asyncio._register_eager_task + + task: object + +Register a new task in asyncio as executed by loop. + +Returns None. +[clinic start generated code]*/ + +static PyObject * +_asyncio__register_eager_task_impl(PyObject *module, PyObject *task) +/*[clinic end generated code: output=dfe1d45367c73f1a input=237f684683398c51]*/ +{ + asyncio_state *state = get_asyncio_state(module); + if (register_eager_task(state, task) < 0) { return NULL; } Py_RETURN_NONE; @@ -3203,7 +3401,29 @@ static PyObject * _asyncio__unregister_task_impl(PyObject *module, PyObject *task) /*[clinic end generated code: output=6e5585706d568a46 input=28fb98c3975f7bdc]*/ { - if (unregister_task(task) < 0) { + asyncio_state *state = get_asyncio_state(module); + if (unregister_task(state, task) < 0) { + return NULL; + } + Py_RETURN_NONE; +} + +/*[clinic input] +_asyncio._unregister_eager_task + + task: object + +Unregister a task. + +Returns None. +[clinic start generated code]*/ + +static PyObject * +_asyncio__unregister_eager_task_impl(PyObject *module, PyObject *task) +/*[clinic end generated code: output=a426922bd07f23d1 input=9d07401ef14ee048]*/ +{ + asyncio_state *state = get_asyncio_state(module); + if (unregister_eager_task(state, task) < 0) { return NULL; } Py_RETURN_NONE; @@ -3227,7 +3447,8 @@ static PyObject * _asyncio__enter_task_impl(PyObject *module, PyObject *loop, PyObject *task) /*[clinic end generated code: output=a22611c858035b73 input=de1b06dca70d8737]*/ { - if (enter_task(loop, task) < 0) { + asyncio_state *state = get_asyncio_state(module); + if (enter_task(state, loop, task) < 0) { return NULL; } Py_RETURN_NONE; @@ -3251,131 +3472,195 @@ static PyObject * _asyncio__leave_task_impl(PyObject *module, PyObject *loop, PyObject *task) /*[clinic end generated code: output=0ebf6db4b858fb41 input=51296a46313d1ad8]*/ { - if (leave_task(loop, task) < 0) { + asyncio_state *state = get_asyncio_state(module); + if (leave_task(state, loop, task) < 0) { return NULL; } Py_RETURN_NONE; } -/*********************** PyRunningLoopHolder ********************/ +/*[clinic input] +_asyncio._swap_current_task + loop: object + task: object -static PyRunningLoopHolder * -new_running_loop_holder(PyObject *loop) -{ - PyRunningLoopHolder *rl = PyObject_New( - PyRunningLoopHolder, &PyRunningLoopHolder_Type); - if (rl == NULL) { - return NULL; - } +Temporarily swap in the supplied task and return the original one (or None). -#if defined(HAVE_GETPID) && !defined(MS_WINDOWS) - rl->rl_pid = getpid(); -#endif +This is intended for use during eager coroutine execution. - Py_INCREF(loop); - rl->rl_loop = loop; +[clinic start generated code]*/ - return rl; +static PyObject * +_asyncio__swap_current_task_impl(PyObject *module, PyObject *loop, + PyObject *task) +/*[clinic end generated code: output=9f88de958df74c7e input=c9c72208d3d38b6c]*/ +{ + return swap_current_task(get_asyncio_state(module), loop, task); } -static void -PyRunningLoopHolder_tp_dealloc(PyRunningLoopHolder *rl) +/*[clinic input] +_asyncio.current_task + + loop: object = None + +Return a currently executed task. + +[clinic start generated code]*/ + +static PyObject * +_asyncio_current_task_impl(PyObject *module, PyObject *loop) +/*[clinic end generated code: output=fe15ac331a7f981a input=58910f61a5627112]*/ { - if (cached_running_holder == (PyObject *)rl) { - cached_running_holder = NULL; - } - Py_CLEAR(rl->rl_loop); - PyObject_Free(rl); -} + PyObject *ret; + asyncio_state *state = get_asyncio_state(module); + if (loop == Py_None) { + loop = _asyncio_get_running_loop_impl(module); + if (loop == NULL) { + return NULL; + } + } else { + Py_INCREF(loop); + } -static PyTypeObject PyRunningLoopHolder_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_RunningLoopHolder", - sizeof(PyRunningLoopHolder), - .tp_getattro = PyObject_GenericGetAttr, - .tp_flags = Py_TPFLAGS_DEFAULT, - .tp_dealloc = (destructor)PyRunningLoopHolder_tp_dealloc, -}; + ret = PyDict_GetItemWithError(state->current_tasks, loop); + Py_DECREF(loop); + if (ret == NULL && PyErr_Occurred()) { + return NULL; + } + else if (ret == NULL) { + Py_RETURN_NONE; + } + Py_INCREF(ret); + return ret; +} /*********************** Module **************************/ static void -module_free_freelists(void) +module_free_freelists(asyncio_state *state) { PyObject *next; PyObject *current; - next = (PyObject*) fi_freelist; + next = (PyObject*) state->fi_freelist; while (next != NULL) { - assert(fi_freelist_len > 0); - fi_freelist_len--; + assert(state->fi_freelist_len > 0); + state->fi_freelist_len--; current = next; next = (PyObject*) ((futureiterobject*) current)->future; PyObject_GC_Del(current); } - assert(fi_freelist_len == 0); - fi_freelist = NULL; + assert(state->fi_freelist_len == 0); + state->fi_freelist = NULL; } +static int +module_traverse(PyObject *mod, visitproc visit, void *arg) +{ + asyncio_state *state = get_asyncio_state(mod); + + Py_VISIT(state->FutureIterType); + Py_VISIT(state->TaskStepMethWrapper_Type); + Py_VISIT(state->FutureType); + Py_VISIT(state->TaskType); + + Py_VISIT(state->asyncio_mod); + Py_VISIT(state->traceback_extract_stack); + Py_VISIT(state->asyncio_future_repr_func); + Py_VISIT(state->asyncio_get_event_loop_policy); + Py_VISIT(state->asyncio_iscoroutine_func); + Py_VISIT(state->asyncio_task_get_stack_func); + Py_VISIT(state->asyncio_task_print_stack_func); + Py_VISIT(state->asyncio_task_repr_func); + Py_VISIT(state->asyncio_InvalidStateError); + Py_VISIT(state->asyncio_CancelledError); + + Py_VISIT(state->scheduled_tasks); + Py_VISIT(state->eager_tasks); + Py_VISIT(state->current_tasks); + Py_VISIT(state->iscoroutine_typecache); + + Py_VISIT(state->context_kwname); + + // Visit freelist. + PyObject *next = (PyObject*) state->fi_freelist; + while (next != NULL) { + PyObject *current = next; + Py_VISIT(current); + next = (PyObject*) ((futureiterobject*) current)->future; + } + return 0; +} -static void -module_free(void *m) +static int +module_clear(PyObject *mod) { - Py_CLEAR(asyncio_mod); - Py_CLEAR(traceback_extract_stack); - Py_CLEAR(asyncio_future_repr_func); - Py_CLEAR(asyncio_get_event_loop_policy); - Py_CLEAR(asyncio_iscoroutine_func); - Py_CLEAR(asyncio_task_get_stack_func); - Py_CLEAR(asyncio_task_print_stack_func); - Py_CLEAR(asyncio_task_repr_func); - Py_CLEAR(asyncio_InvalidStateError); - Py_CLEAR(asyncio_CancelledError); + asyncio_state *state = get_asyncio_state(mod); + + Py_CLEAR(state->FutureIterType); + Py_CLEAR(state->TaskStepMethWrapper_Type); + Py_CLEAR(state->FutureType); + Py_CLEAR(state->TaskType); + + Py_CLEAR(state->asyncio_mod); + Py_CLEAR(state->traceback_extract_stack); + Py_CLEAR(state->asyncio_future_repr_func); + Py_CLEAR(state->asyncio_get_event_loop_policy); + Py_CLEAR(state->asyncio_iscoroutine_func); + Py_CLEAR(state->asyncio_task_get_stack_func); + Py_CLEAR(state->asyncio_task_print_stack_func); + Py_CLEAR(state->asyncio_task_repr_func); + Py_CLEAR(state->asyncio_InvalidStateError); + Py_CLEAR(state->asyncio_CancelledError); - Py_CLEAR(all_tasks); - Py_CLEAR(current_tasks); - Py_CLEAR(iscoroutine_typecache); + Py_CLEAR(state->scheduled_tasks); + Py_CLEAR(state->eager_tasks); + Py_CLEAR(state->current_tasks); + Py_CLEAR(state->iscoroutine_typecache); - Py_CLEAR(context_kwname); + Py_CLEAR(state->context_kwname); - module_free_freelists(); + module_free_freelists(state); + + return 0; +} - module_initialized = 0; +static void +module_free(void *mod) +{ + (void)module_clear((PyObject *)mod); } static int -module_init(void) +module_init(asyncio_state *state) { PyObject *module = NULL; - if (module_initialized) { - return 0; - } - asyncio_mod = PyImport_ImportModule("asyncio"); - if (asyncio_mod == NULL) { + state->asyncio_mod = PyImport_ImportModule("asyncio"); + if (state->asyncio_mod == NULL) { goto fail; } - current_tasks = PyDict_New(); - if (current_tasks == NULL) { + state->current_tasks = PyDict_New(); + if (state->current_tasks == NULL) { goto fail; } - iscoroutine_typecache = PySet_New(NULL); - if (iscoroutine_typecache == NULL) { + state->iscoroutine_typecache = PySet_New(NULL); + if (state->iscoroutine_typecache == NULL) { goto fail; } - context_kwname = Py_BuildValue("(s)", "context"); - if (context_kwname == NULL) { + state->context_kwname = Py_BuildValue("(s)", "context"); + if (state->context_kwname == NULL) { goto fail; } @@ -3393,42 +3678,45 @@ module_init(void) } WITH_MOD("asyncio.events") - GET_MOD_ATTR(asyncio_get_event_loop_policy, "get_event_loop_policy") + GET_MOD_ATTR(state->asyncio_get_event_loop_policy, "get_event_loop_policy") WITH_MOD("asyncio.base_futures") - GET_MOD_ATTR(asyncio_future_repr_func, "_future_repr") + GET_MOD_ATTR(state->asyncio_future_repr_func, "_future_repr") WITH_MOD("asyncio.exceptions") - GET_MOD_ATTR(asyncio_InvalidStateError, "InvalidStateError") - GET_MOD_ATTR(asyncio_CancelledError, "CancelledError") + GET_MOD_ATTR(state->asyncio_InvalidStateError, "InvalidStateError") + GET_MOD_ATTR(state->asyncio_CancelledError, "CancelledError") WITH_MOD("asyncio.base_tasks") - GET_MOD_ATTR(asyncio_task_repr_func, "_task_repr") - GET_MOD_ATTR(asyncio_task_get_stack_func, "_task_get_stack") - GET_MOD_ATTR(asyncio_task_print_stack_func, "_task_print_stack") + GET_MOD_ATTR(state->asyncio_task_repr_func, "_task_repr") + GET_MOD_ATTR(state->asyncio_task_get_stack_func, "_task_get_stack") + GET_MOD_ATTR(state->asyncio_task_print_stack_func, "_task_print_stack") WITH_MOD("asyncio.coroutines") - GET_MOD_ATTR(asyncio_iscoroutine_func, "iscoroutine") + GET_MOD_ATTR(state->asyncio_iscoroutine_func, "iscoroutine") WITH_MOD("traceback") - GET_MOD_ATTR(traceback_extract_stack, "extract_stack") + GET_MOD_ATTR(state->traceback_extract_stack, "extract_stack") PyObject *weak_set; WITH_MOD("weakref") GET_MOD_ATTR(weak_set, "WeakSet"); - all_tasks = PyObject_CallNoArgs(weak_set); + state->scheduled_tasks = PyObject_CallNoArgs(weak_set); Py_CLEAR(weak_set); - if (all_tasks == NULL) { + if (state->scheduled_tasks == NULL) { + goto fail; + } + + state->eager_tasks = PySet_New(NULL); + if (state->eager_tasks == NULL) { goto fail; } - module_initialized = 1; Py_DECREF(module); return 0; fail: Py_CLEAR(module); - module_free(NULL); return -1; #undef WITH_MOD @@ -3438,76 +3726,90 @@ fail: PyDoc_STRVAR(module_doc, "Accelerator module for asyncio"); static PyMethodDef asyncio_methods[] = { + _ASYNCIO_CURRENT_TASK_METHODDEF _ASYNCIO_GET_EVENT_LOOP_METHODDEF - _ASYNCIO__GET_EVENT_LOOP_METHODDEF _ASYNCIO_GET_RUNNING_LOOP_METHODDEF _ASYNCIO__GET_RUNNING_LOOP_METHODDEF _ASYNCIO__SET_RUNNING_LOOP_METHODDEF _ASYNCIO__REGISTER_TASK_METHODDEF + _ASYNCIO__REGISTER_EAGER_TASK_METHODDEF _ASYNCIO__UNREGISTER_TASK_METHODDEF + _ASYNCIO__UNREGISTER_EAGER_TASK_METHODDEF _ASYNCIO__ENTER_TASK_METHODDEF _ASYNCIO__LEAVE_TASK_METHODDEF + _ASYNCIO__SWAP_CURRENT_TASK_METHODDEF {NULL, NULL} }; -static struct PyModuleDef _asynciomodule = { - PyModuleDef_HEAD_INIT, /* m_base */ - "_asyncio", /* m_name */ - module_doc, /* m_doc */ - -1, /* m_size */ - asyncio_methods, /* m_methods */ - NULL, /* m_slots */ - NULL, /* m_traverse */ - NULL, /* m_clear */ - (freefunc)module_free /* m_free */ -}; +static int +module_exec(PyObject *mod) +{ + asyncio_state *state = get_asyncio_state(mod); +#define CREATE_TYPE(m, tp, spec, base) \ + do { \ + tp = (PyTypeObject *)PyType_FromMetaclass(NULL, m, spec, \ + (PyObject *)base); \ + if (tp == NULL) { \ + return -1; \ + } \ + } while (0) -PyMODINIT_FUNC -PyInit__asyncio(void) -{ - if (module_init() < 0) { - return NULL; - } - if (PyType_Ready(&FutureIterType) < 0) { - return NULL; + CREATE_TYPE(mod, state->TaskStepMethWrapper_Type, &TaskStepMethWrapper_spec, NULL); + CREATE_TYPE(mod, state->FutureIterType, &FutureIter_spec, NULL); + CREATE_TYPE(mod, state->FutureType, &Future_spec, NULL); + CREATE_TYPE(mod, state->TaskType, &Task_spec, state->FutureType); + +#undef CREATE_TYPE + + if (PyModule_AddType(mod, state->FutureType) < 0) { + return -1; } - if (PyType_Ready(&TaskStepMethWrapper_Type) < 0) { - return NULL; + + if (PyModule_AddType(mod, state->TaskType) < 0) { + return -1; } - if (PyType_Ready(&PyRunningLoopHolder_Type) < 0) { - return NULL; + // Must be done after types are added to avoid a circular dependency + if (module_init(state) < 0) { + return -1; } - PyObject *m = PyModule_Create(&_asynciomodule); - if (m == NULL) { - return NULL; + if (PyModule_AddObjectRef(mod, "_scheduled_tasks", state->scheduled_tasks) < 0) { + return -1; } - /* FutureType and TaskType are made ready by PyModule_AddType() calls below. */ - if (PyModule_AddType(m, &FutureType) < 0) { - Py_DECREF(m); - return NULL; + if (PyModule_AddObjectRef(mod, "_eager_tasks", state->eager_tasks) < 0) { + return -1; } - if (PyModule_AddType(m, &TaskType) < 0) { - Py_DECREF(m); - return NULL; + if (PyModule_AddObjectRef(mod, "_current_tasks", state->current_tasks) < 0) { + return -1; } - Py_INCREF(all_tasks); - if (PyModule_AddObject(m, "_all_tasks", all_tasks) < 0) { - Py_DECREF(all_tasks); - Py_DECREF(m); - return NULL; - } - Py_INCREF(current_tasks); - if (PyModule_AddObject(m, "_current_tasks", current_tasks) < 0) { - Py_DECREF(current_tasks); - Py_DECREF(m); - return NULL; - } + return 0; +} + +static struct PyModuleDef_Slot module_slots[] = { + {Py_mod_exec, module_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, + {0, NULL}, +}; + +static struct PyModuleDef _asynciomodule = { + .m_base = PyModuleDef_HEAD_INIT, + .m_name = "_asyncio", + .m_doc = module_doc, + .m_size = sizeof(asyncio_state), + .m_methods = asyncio_methods, + .m_slots = module_slots, + .m_traverse = module_traverse, + .m_clear = module_clear, + .m_free = (freefunc)module_free, +}; - return m; +PyMODINIT_FUNC +PyInit__asyncio(void) +{ + return PyModuleDef_Init(&_asynciomodule); } diff --git a/Modules/_bisectmodule.c b/Modules/_bisectmodule.c index 0caa92b2..0773bbd1 100644 --- a/Modules/_bisectmodule.c +++ b/Modules/_bisectmodule.c @@ -25,6 +25,26 @@ get_bisect_state(PyObject *module) return (bisect_state *)state; } +static ssizeargfunc +get_sq_item(PyObject *s) +{ + // The parts of PySequence_GetItem that we only need to do once + PyTypeObject *tp = Py_TYPE(s); + PySequenceMethods *m = tp->tp_as_sequence; + if (m && m->sq_item) { + return m->sq_item; + } + const char *msg; + if (tp->tp_as_mapping && tp->tp_as_mapping->mp_subscript) { + msg = "%.200s is not a sequence"; + } + else { + msg = "'%.200s' object does not support indexing"; + } + PyErr_Format(PyExc_TypeError, msg, tp->tp_name); + return NULL; +} + static inline Py_ssize_t internal_bisect_right(PyObject *list, PyObject *item, Py_ssize_t lo, Py_ssize_t hi, PyObject* key) @@ -42,32 +62,86 @@ internal_bisect_right(PyObject *list, PyObject *item, Py_ssize_t lo, Py_ssize_t if (hi < 0) return -1; } + ssizeargfunc sq_item = get_sq_item(list); + if (sq_item == NULL) { + return -1; + } + if (Py_EnterRecursiveCall("in _bisect.bisect_right")) { + return -1; + } + PyTypeObject *tp = Py_TYPE(item); + richcmpfunc compare = tp->tp_richcompare; while (lo < hi) { /* The (size_t)cast ensures that the addition and subsequent division are performed as unsigned operations, avoiding difficulties from signed overflow. (See issue 13496.) */ mid = ((size_t)lo + hi) / 2; - litem = PySequence_GetItem(list, mid); - if (litem == NULL) - return -1; + assert(mid >= 0); + // PySequence_GetItem, but we already checked the types. + litem = sq_item(list, mid); + assert((PyErr_Occurred() == NULL) ^ (litem == NULL)); + if (litem == NULL) { + goto error; + } if (key != Py_None) { PyObject *newitem = PyObject_CallOneArg(key, litem); if (newitem == NULL) { - Py_DECREF(litem); - return -1; + goto error; } Py_SETREF(litem, newitem); } - res = PyObject_RichCompareBool(item, litem, Py_LT); + /* if item < key(list[mid]): + * hi = mid + * else: + * lo = mid + 1 + */ + if (compare != NULL && Py_IS_TYPE(litem, tp)) { + // A fast path for comparing objects of the same type + PyObject *res_obj = compare(item, litem, Py_LT); + if (res_obj == Py_True) { + Py_DECREF(res_obj); + Py_DECREF(litem); + hi = mid; + continue; + } + if (res_obj == Py_False) { + Py_DECREF(res_obj); + Py_DECREF(litem); + lo = mid + 1; + continue; + } + if (res_obj == NULL) { + goto error; + } + if (res_obj == Py_NotImplemented) { + Py_DECREF(res_obj); + compare = NULL; + res = PyObject_RichCompareBool(item, litem, Py_LT); + } + else { + res = PyObject_IsTrue(res_obj); + Py_DECREF(res_obj); + } + } + else { + // A default path for comparing arbitrary objects + res = PyObject_RichCompareBool(item, litem, Py_LT); + } + if (res < 0) { + goto error; + } Py_DECREF(litem); - if (res < 0) - return -1; if (res) hi = mid; else lo = mid + 1; } + Py_LeaveRecursiveCall(); return lo; +error: + Py_LeaveRecursiveCall(); + Py_XDECREF(litem); + return -1; } /*[clinic input] @@ -88,12 +162,14 @@ insert just after the rightmost x already there. Optional args lo (default 0) and hi (default len(a)) bound the slice of a to be searched. + +A custom key function can be supplied to customize the sort order. [clinic start generated code]*/ static Py_ssize_t _bisect_bisect_right_impl(PyObject *module, PyObject *a, PyObject *x, Py_ssize_t lo, Py_ssize_t hi, PyObject *key) -/*[clinic end generated code: output=3a4bc09cc7c8a73d input=40fcc5afa06ae593]*/ +/*[clinic end generated code: output=3a4bc09cc7c8a73d input=43071869772dd53a]*/ { return internal_bisect_right(a, x, lo, hi, key); } @@ -114,12 +190,14 @@ If x is already in a, insert it to the right of the rightmost x. Optional args lo (default 0) and hi (default len(a)) bound the slice of a to be searched. + +A custom key function can be supplied to customize the sort order. [clinic start generated code]*/ static PyObject * _bisect_insort_right_impl(PyObject *module, PyObject *a, PyObject *x, Py_ssize_t lo, Py_ssize_t hi, PyObject *key) -/*[clinic end generated code: output=ac3bf26d07aedda2 input=44e1708e26b7b802]*/ +/*[clinic end generated code: output=ac3bf26d07aedda2 input=f60777d2b6ddb239]*/ { PyObject *result, *key_x; Py_ssize_t index; @@ -168,32 +246,86 @@ internal_bisect_left(PyObject *list, PyObject *item, Py_ssize_t lo, Py_ssize_t h if (hi < 0) return -1; } + ssizeargfunc sq_item = get_sq_item(list); + if (sq_item == NULL) { + return -1; + } + if (Py_EnterRecursiveCall("in _bisect.bisect_left")) { + return -1; + } + PyTypeObject *tp = Py_TYPE(item); + richcmpfunc compare = tp->tp_richcompare; while (lo < hi) { /* The (size_t)cast ensures that the addition and subsequent division are performed as unsigned operations, avoiding difficulties from signed overflow. (See issue 13496.) */ mid = ((size_t)lo + hi) / 2; - litem = PySequence_GetItem(list, mid); - if (litem == NULL) - return -1; + assert(mid >= 0); + // PySequence_GetItem, but we already checked the types. + litem = sq_item(list, mid); + assert((PyErr_Occurred() == NULL) ^ (litem == NULL)); + if (litem == NULL) { + goto error; + } if (key != Py_None) { PyObject *newitem = PyObject_CallOneArg(key, litem); if (newitem == NULL) { - Py_DECREF(litem); - return -1; + goto error; } Py_SETREF(litem, newitem); } - res = PyObject_RichCompareBool(litem, item, Py_LT); + /* if key(list[mid]) < item: + * lo = mid + 1 + * else: + * hi = mid + */ + if (compare != NULL && Py_IS_TYPE(litem, tp)) { + // A fast path for comparing objects of the same type + PyObject *res_obj = compare(litem, item, Py_LT); + if (res_obj == Py_True) { + Py_DECREF(res_obj); + Py_DECREF(litem); + lo = mid + 1; + continue; + } + if (res_obj == Py_False) { + Py_DECREF(res_obj); + Py_DECREF(litem); + hi = mid; + continue; + } + if (res_obj == NULL) { + goto error; + } + if (res_obj == Py_NotImplemented) { + Py_DECREF(res_obj); + compare = NULL; + res = PyObject_RichCompareBool(litem, item, Py_LT); + } + else { + res = PyObject_IsTrue(res_obj); + Py_DECREF(res_obj); + } + } + else { + // A default path for comparing arbitrary objects + res = PyObject_RichCompareBool(litem, item, Py_LT); + } + if (res < 0) { + goto error; + } Py_DECREF(litem); - if (res < 0) - return -1; if (res) lo = mid + 1; else hi = mid; } + Py_LeaveRecursiveCall(); return lo; +error: + Py_LeaveRecursiveCall(); + Py_XDECREF(litem); + return -1; } @@ -215,12 +347,14 @@ insert just before the leftmost x already there. Optional args lo (default 0) and hi (default len(a)) bound the slice of a to be searched. + +A custom key function can be supplied to customize the sort order. [clinic start generated code]*/ static Py_ssize_t _bisect_bisect_left_impl(PyObject *module, PyObject *a, PyObject *x, Py_ssize_t lo, Py_ssize_t hi, PyObject *key) -/*[clinic end generated code: output=70749d6e5cae9284 input=90dd35b50ceb05e3]*/ +/*[clinic end generated code: output=70749d6e5cae9284 input=f29c4fe7f9b797c7]*/ { return internal_bisect_left(a, x, lo, hi, key); } @@ -242,12 +376,14 @@ If x is already in a, insert it to the left of the leftmost x. Optional args lo (default 0) and hi (default len(a)) bound the slice of a to be searched. + +A custom key function can be supplied to customize the sort order. [clinic start generated code]*/ static PyObject * _bisect_insort_left_impl(PyObject *module, PyObject *a, PyObject *x, Py_ssize_t lo, Py_ssize_t hi, PyObject *key) -/*[clinic end generated code: output=b1d33e5e7ffff11e input=3ab65d8784f585b1]*/ +/*[clinic end generated code: output=b1d33e5e7ffff11e input=0a700a82edbd472c]*/ { PyObject *result, *key_x; Py_ssize_t index; @@ -321,6 +457,7 @@ bisect_modexec(PyObject *m) static PyModuleDef_Slot bisect_slots[] = { {Py_mod_exec, bisect_modexec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; diff --git a/Modules/_blake2/blake2module.c b/Modules/_blake2/blake2module.c index 44d783b4..0d1d88c6 100644 --- a/Modules/_blake2/blake2module.c +++ b/Modules/_blake2/blake2module.c @@ -127,6 +127,7 @@ blake2_exec(PyObject *m) static PyModuleDef_Slot _blake2_slots[] = { {Py_mod_exec, blake2_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; @@ -146,4 +147,4 @@ PyMODINIT_FUNC PyInit__blake2(void) { return PyModuleDef_Init(&blake2_module); -} \ No newline at end of file +} diff --git a/Modules/_blake2/blake2module.h b/Modules/_blake2/blake2module.h index aa8f2811..c8144ec9 100644 --- a/Modules/_blake2/blake2module.h +++ b/Modules/_blake2/blake2module.h @@ -38,6 +38,6 @@ #endif // HAVE_LIBB2 // for secure_zero_memory(), store32(), store48(), and store64() -#include "impl/blake2-impl.h" +#include "impl/blake2-impl.h" #endif // Py_BLAKE2MODULE_H diff --git a/Modules/_blake2/clinic/blake2b_impl.c.h b/Modules/_blake2/clinic/blake2b_impl.c.h index 4e74e088..99b0f098 100644 --- a/Modules/_blake2/clinic/blake2b_impl.c.h +++ b/Modules/_blake2/clinic/blake2b_impl.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(py_blake2b_new__doc__, "blake2b(data=b\'\', /, *, digest_size=_blake2.blake2b.MAX_DIGEST_SIZE,\n" " key=b\'\', salt=b\'\', person=b\'\', fanout=1, depth=1, leaf_size=0,\n" @@ -22,8 +28,31 @@ static PyObject * py_blake2b_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 12 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(digest_size), &_Py_ID(key), &_Py_ID(salt), &_Py_ID(person), &_Py_ID(fanout), &_Py_ID(depth), &_Py_ID(leaf_size), &_Py_ID(node_offset), &_Py_ID(node_depth), &_Py_ID(inner_size), &_Py_ID(last_node), &_Py_ID(usedforsecurity), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "digest_size", "key", "salt", "person", "fanout", "depth", "leaf_size", "node_offset", "node_depth", "inner_size", "last_node", "usedforsecurity", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "blake2b", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "blake2b", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[13]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -247,4 +276,4 @@ _blake2_blake2b_hexdigest(BLAKE2bObject *self, PyObject *Py_UNUSED(ignored)) { return _blake2_blake2b_hexdigest_impl(self); } -/*[clinic end generated code: output=10eb47aba77f192d input=a9049054013a1b77]*/ +/*[clinic end generated code: output=996b4fe396824797 input=a9049054013a1b77]*/ diff --git a/Modules/_blake2/clinic/blake2s_impl.c.h b/Modules/_blake2/clinic/blake2s_impl.c.h index 0f0d9835..9b821fbc 100644 --- a/Modules/_blake2/clinic/blake2s_impl.c.h +++ b/Modules/_blake2/clinic/blake2s_impl.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(py_blake2s_new__doc__, "blake2s(data=b\'\', /, *, digest_size=_blake2.blake2s.MAX_DIGEST_SIZE,\n" " key=b\'\', salt=b\'\', person=b\'\', fanout=1, depth=1, leaf_size=0,\n" @@ -22,8 +28,31 @@ static PyObject * py_blake2s_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 12 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(digest_size), &_Py_ID(key), &_Py_ID(salt), &_Py_ID(person), &_Py_ID(fanout), &_Py_ID(depth), &_Py_ID(leaf_size), &_Py_ID(node_offset), &_Py_ID(node_depth), &_Py_ID(inner_size), &_Py_ID(last_node), &_Py_ID(usedforsecurity), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "digest_size", "key", "salt", "person", "fanout", "depth", "leaf_size", "node_offset", "node_depth", "inner_size", "last_node", "usedforsecurity", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "blake2s", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "blake2s", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[13]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -247,4 +276,4 @@ _blake2_blake2s_hexdigest(BLAKE2sObject *self, PyObject *Py_UNUSED(ignored)) { return _blake2_blake2s_hexdigest_impl(self); } -/*[clinic end generated code: output=f7ee8092ed67e9c7 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=bd0fb7639e450618 input=a9049054013a1b77]*/ diff --git a/Modules/_blake2/impl/blake2-config.h b/Modules/_blake2/impl/blake2-config.h index f5dd6faa..c09cb4bc 100644 --- a/Modules/_blake2/impl/blake2-config.h +++ b/Modules/_blake2/impl/blake2-config.h @@ -53,7 +53,7 @@ #endif #endif -#ifdef HAVE_SSE41 +#ifdef HAVE_SSE4_1 #ifndef HAVE_SSSE3 #define HAVE_SSSE3 #endif diff --git a/Modules/_blake2/impl/blake2b-round.h b/Modules/_blake2/impl/blake2b-round.h index cebc2255..5b452c4d 100644 --- a/Modules/_blake2/impl/blake2b-round.h +++ b/Modules/_blake2/impl/blake2b-round.h @@ -62,7 +62,7 @@ \ row2l = _mm_roti_epi64(row2l, -24); \ row2h = _mm_roti_epi64(row2h, -24); \ - + #define G2(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1) \ row1l = _mm_add_epi64(_mm_add_epi64(row1l, b0), row2l); \ row1h = _mm_add_epi64(_mm_add_epi64(row1h, b1), row2h); \ @@ -81,7 +81,7 @@ \ row2l = _mm_roti_epi64(row2l, -63); \ row2h = _mm_roti_epi64(row2h, -63); \ - + #if defined(HAVE_SSSE3) #define DIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h) \ t0 = _mm_alignr_epi8(row2h, row2l, 8); \ diff --git a/Modules/_blake2/impl/blake2s-load-xop.h b/Modules/_blake2/impl/blake2s-load-xop.h index ac591a77..14d9e7f7 100644 --- a/Modules/_blake2/impl/blake2s-load-xop.h +++ b/Modules/_blake2/impl/blake2s-load-xop.h @@ -166,7 +166,7 @@ buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(1),TOB(7)) ); #define LOAD_MSG_8_3(buf) \ t0 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(6),TOB(1),TOB(0),TOB(0)) ); \ buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(5),TOB(4)) ); \ - + #define LOAD_MSG_8_4(buf) \ buf = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(5),TOB(4),TOB(7),TOB(2)) ); diff --git a/Modules/_blake2/impl/blake2s-round.h b/Modules/_blake2/impl/blake2s-round.h index 1e2f2b7f..3af4be35 100644 --- a/Modules/_blake2/impl/blake2s-round.h +++ b/Modules/_blake2/impl/blake2s-round.h @@ -86,6 +86,6 @@ LOAD_MSG_ ##r ##_4(buf4); \ G2(row1,row2,row3,row4,buf4); \ UNDIAGONALIZE(row1,row2,row3,row4); \ - + #endif diff --git a/Modules/_bz2module.c b/Modules/_bz2module.c index 798e9efc..97bd44b4 100644 --- a/Modules/_bz2module.c +++ b/Modules/_bz2module.c @@ -15,6 +15,29 @@ #error "The maximum block size accepted by libbzip2 is UINT32_MAX." #endif +typedef struct { + PyTypeObject *bz2_compressor_type; + PyTypeObject *bz2_decompressor_type; +} _bz2_state; + +static inline _bz2_state * +get_module_state(PyObject *module) +{ + void *state = PyModule_GetState(module); + assert(state != NULL); + return (_bz2_state *)state; +} + +static struct PyModuleDef _bz2module; + +static inline _bz2_state * +find_module_state_by_def(PyTypeObject *type) +{ + PyObject *module = PyType_GetModuleByDef(type, &_bz2module); + assert(module != NULL); + return get_module_state(module); +} + /* On success, return value >= 0 On failure, return -1 */ static inline Py_ssize_t @@ -81,19 +104,6 @@ OutputBuffer_OnError(_BlocksOutputBuffer *buffer) #define RELEASE_LOCK(obj) PyThread_release_lock((obj)->lock) -typedef struct { - PyTypeObject *bz2_compressor_type; - PyTypeObject *bz2_decompressor_type; -} _bz2_state; - -static inline _bz2_state* -get_bz2_state(PyObject *module) -{ - void *state = PyModule_GetState(module); - assert(state != NULL); - return (_bz2_state *)state; -} - typedef struct { PyObject_HEAD bz_stream bzs; @@ -227,12 +237,14 @@ error: /*[clinic input] module _bz2 -class _bz2.BZ2Compressor "BZ2Compressor *" "&BZ2Compressor_Type" -class _bz2.BZ2Decompressor "BZ2Decompressor *" "&BZ2Decompressor_Type" +class _bz2.BZ2Compressor "BZ2Compressor *" "clinic_state()->bz2_compressor_type" +class _bz2.BZ2Decompressor "BZ2Decompressor *" "clinic_state()->bz2_decompressor_type" [clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=dc7d7992a79f9cb7]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=92348121632b94c4]*/ +#define clinic_state() (find_module_state_by_def(type)) #include "clinic/_bz2module.c.h" +#undef clinic_state /*[clinic input] _bz2.BZ2Compressor.compress @@ -308,24 +320,43 @@ BZ2_Free(void* ctx, void *ptr) PyMem_RawFree(ptr); } +/*[clinic input] +@classmethod +_bz2.BZ2Compressor.__new__ -/* Argument Clinic is not used since the Argument Clinic always want to - check the type which would be wrong here */ -static int -_bz2_BZ2Compressor___init___impl(BZ2Compressor *self, int compresslevel) + compresslevel: int = 9 + Compression level, as a number between 1 and 9. + / + +Create a compressor object for compressing data incrementally. + +For one-shot compression, use the compress() function instead. +[clinic start generated code]*/ + +static PyObject * +_bz2_BZ2Compressor_impl(PyTypeObject *type, int compresslevel) +/*[clinic end generated code: output=83346c96beaacad7 input=d4500d2a52c8b263]*/ { int bzerror; + BZ2Compressor *self; if (!(1 <= compresslevel && compresslevel <= 9)) { PyErr_SetString(PyExc_ValueError, "compresslevel must be between 1 and 9"); - return -1; + return NULL; + } + + assert(type != NULL && type->tp_alloc != NULL); + self = (BZ2Compressor *)type->tp_alloc(type, 0); + if (self == NULL) { + return NULL; } self->lock = PyThread_allocate_lock(); if (self->lock == NULL) { + Py_DECREF(self); PyErr_SetString(PyExc_MemoryError, "Unable to allocate lock"); - return -1; + return NULL; } self->bzs.opaque = NULL; @@ -335,49 +366,11 @@ _bz2_BZ2Compressor___init___impl(BZ2Compressor *self, int compresslevel) if (catch_bz2_error(bzerror)) goto error; - return 0; + return (PyObject *)self; error: - PyThread_free_lock(self->lock); - self->lock = NULL; - return -1; -} - -PyDoc_STRVAR(_bz2_BZ2Compressor___init____doc__, -"BZ2Compressor(compresslevel=9, /)\n" -"--\n" -"\n" -"Create a compressor object for compressing data incrementally.\n" -"\n" -" compresslevel\n" -" Compression level, as a number between 1 and 9.\n" -"\n" -"For one-shot compression, use the compress() function instead."); - -static int -_bz2_BZ2Compressor___init__(PyObject *self, PyObject *args, PyObject *kwargs) -{ - int return_value = -1; - int compresslevel = 9; - - if (!_PyArg_NoKeywords("BZ2Compressor", kwargs)) { - goto exit; - } - if (!_PyArg_CheckPositional("BZ2Compressor", PyTuple_GET_SIZE(args), 0, 1)) { - goto exit; - } - if (PyTuple_GET_SIZE(args) < 1) { - goto skip_optional; - } - compresslevel = _PyLong_AsInt(PyTuple_GET_ITEM(args, 0)); - if (compresslevel == -1 && PyErr_Occurred()) { - goto exit; - } -skip_optional: - return_value = _bz2_BZ2Compressor___init___impl((BZ2Compressor *)self, compresslevel); - -exit: - return return_value; + Py_DECREF(self); + return NULL; } static void @@ -408,9 +401,8 @@ static PyMethodDef BZ2Compressor_methods[] = { static PyType_Slot bz2_compressor_type_slots[] = { {Py_tp_dealloc, BZ2Compressor_dealloc}, {Py_tp_methods, BZ2Compressor_methods}, - {Py_tp_init, _bz2_BZ2Compressor___init__}, - {Py_tp_new, PyType_GenericNew}, - {Py_tp_doc, (char *)_bz2_BZ2Compressor___init____doc__}, + {Py_tp_new, _bz2_BZ2Compressor}, + {Py_tp_doc, (char *)_bz2_BZ2Compressor__doc__}, {Py_tp_traverse, BZ2Compressor_traverse}, {0, 0} }; @@ -637,28 +629,40 @@ _bz2_BZ2Decompressor_decompress_impl(BZ2Decompressor *self, Py_buffer *data, return result; } -/* Argument Clinic is not used since the Argument Clinic always want to - check the type which would be wrong here */ -static int -_bz2_BZ2Decompressor___init___impl(BZ2Decompressor *self) +/*[clinic input] +@classmethod +_bz2.BZ2Decompressor.__new__ + +Create a decompressor object for decompressing data incrementally. + +For one-shot decompression, use the decompress() function instead. +[clinic start generated code]*/ + +static PyObject * +_bz2_BZ2Decompressor_impl(PyTypeObject *type) +/*[clinic end generated code: output=5150d51ccaab220e input=b87413ce51853528]*/ { + BZ2Decompressor *self; int bzerror; - PyThread_type_lock lock = PyThread_allocate_lock(); - if (lock == NULL) { - PyErr_SetString(PyExc_MemoryError, "Unable to allocate lock"); - return -1; + assert(type != NULL && type->tp_alloc != NULL); + self = (BZ2Decompressor *)type->tp_alloc(type, 0); + if (self == NULL) { + return NULL; } - if (self->lock != NULL) { - PyThread_free_lock(self->lock); + + self->lock = PyThread_allocate_lock(); + if (self->lock == NULL) { + Py_DECREF(self); + PyErr_SetString(PyExc_MemoryError, "Unable to allocate lock"); + return NULL; } - self->lock = lock; self->needs_input = 1; self->bzs_avail_in_real = 0; self->input_buffer = NULL; self->input_buffer_size = 0; - Py_XSETREF(self->unused_data, PyBytes_FromStringAndSize(NULL, 0)); + self->unused_data = PyBytes_FromStringAndSize(NULL, 0); if (self->unused_data == NULL) goto error; @@ -666,40 +670,13 @@ _bz2_BZ2Decompressor___init___impl(BZ2Decompressor *self) if (catch_bz2_error(bzerror)) goto error; - return 0; + return (PyObject *)self; error: - Py_CLEAR(self->unused_data); - PyThread_free_lock(self->lock); - self->lock = NULL; - return -1; -} - -static int -_bz2_BZ2Decompressor___init__(PyObject *self, PyObject *args, PyObject *kwargs) -{ - int return_value = -1; - - if (!_PyArg_NoPositional("BZ2Decompressor", args)) { - goto exit; - } - if (!_PyArg_NoKeywords("BZ2Decompressor", kwargs)) { - goto exit; - } - return_value = _bz2_BZ2Decompressor___init___impl((BZ2Decompressor *)self); - -exit: - return return_value; + Py_DECREF(self); + return NULL; } -PyDoc_STRVAR(_bz2_BZ2Decompressor___init____doc__, -"BZ2Decompressor()\n" -"--\n" -"\n" -"Create a decompressor object for decompressing data incrementally.\n" -"\n" -"For one-shot decompression, use the decompress() function instead."); - static void BZ2Decompressor_dealloc(BZ2Decompressor *self) { @@ -751,10 +728,9 @@ static PyMemberDef BZ2Decompressor_members[] = { static PyType_Slot bz2_decompressor_type_slots[] = { {Py_tp_dealloc, BZ2Decompressor_dealloc}, {Py_tp_methods, BZ2Decompressor_methods}, - {Py_tp_init, _bz2_BZ2Decompressor___init__}, - {Py_tp_doc, (char *)_bz2_BZ2Decompressor___init____doc__}, + {Py_tp_doc, (char *)_bz2_BZ2Decompressor__doc__}, {Py_tp_members, BZ2Decompressor_members}, - {Py_tp_new, PyType_GenericNew}, + {Py_tp_new, _bz2_BZ2Decompressor}, {Py_tp_traverse, BZ2Decompressor_traverse}, {0, 0} }; @@ -775,13 +751,12 @@ static PyType_Spec bz2_decompressor_type_spec = { static int _bz2_exec(PyObject *module) { - _bz2_state *state = get_bz2_state(module); + _bz2_state *state = get_module_state(module); state->bz2_compressor_type = (PyTypeObject *)PyType_FromModuleAndSpec(module, &bz2_compressor_type_spec, NULL); if (state->bz2_compressor_type == NULL) { return -1; } - if (PyModule_AddType(module, state->bz2_compressor_type) < 0) { return -1; } @@ -791,7 +766,6 @@ _bz2_exec(PyObject *module) if (state->bz2_decompressor_type == NULL) { return -1; } - if (PyModule_AddType(module, state->bz2_decompressor_type) < 0) { return -1; } @@ -802,7 +776,7 @@ _bz2_exec(PyObject *module) static int _bz2_traverse(PyObject *module, visitproc visit, void *arg) { - _bz2_state *state = get_bz2_state(module); + _bz2_state *state = get_module_state(module); Py_VISIT(state->bz2_compressor_type); Py_VISIT(state->bz2_decompressor_type); return 0; @@ -811,7 +785,7 @@ _bz2_traverse(PyObject *module, visitproc visit, void *arg) static int _bz2_clear(PyObject *module) { - _bz2_state *state = get_bz2_state(module); + _bz2_state *state = get_module_state(module); Py_CLEAR(state->bz2_compressor_type); Py_CLEAR(state->bz2_decompressor_type); return 0; @@ -820,22 +794,23 @@ _bz2_clear(PyObject *module) static void _bz2_free(void *module) { - _bz2_clear((PyObject *)module); + (void)_bz2_clear((PyObject *)module); } static struct PyModuleDef_Slot _bz2_slots[] = { {Py_mod_exec, _bz2_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; static struct PyModuleDef _bz2module = { - PyModuleDef_HEAD_INIT, + .m_base = PyModuleDef_HEAD_INIT, .m_name = "_bz2", .m_size = sizeof(_bz2_state), - .m_slots = _bz2_slots, .m_traverse = _bz2_traverse, .m_clear = _bz2_clear, .m_free = _bz2_free, + .m_slots = _bz2_slots, }; PyMODINIT_FUNC diff --git a/Modules/_codecsmodule.c b/Modules/_codecsmodule.c index 50afc097..777c753b 100644 --- a/Modules/_codecsmodule.c +++ b/Modules/_codecsmodule.c @@ -42,6 +42,7 @@ module _codecs [clinic start generated code]*/ /*[clinic end generated code: output=da39a3ee5e6b4b0d input=e1390e3da3cb9deb]*/ +#include "pycore_runtime.h" #include "clinic/_codecsmodule.c.h" /* --- Registry ----------------------------------------------------------- */ @@ -255,14 +256,14 @@ _codecs_escape_encode_impl(PyObject *module, PyObject *data, _codecs.utf_7_decode data: Py_buffer errors: str(accept={str, NoneType}) = None - final: bool(accept={int}) = False + final: bool = False / [clinic start generated code]*/ static PyObject * _codecs_utf_7_decode_impl(PyObject *module, Py_buffer *data, const char *errors, int final) -/*[clinic end generated code: output=0cd3a944a32a4089 input=22c395d357815d26]*/ +/*[clinic end generated code: output=0cd3a944a32a4089 input=dbf8c8998102dc7d]*/ { Py_ssize_t consumed = data->len; PyObject *decoded = PyUnicode_DecodeUTF7Stateful(data->buf, data->len, @@ -275,14 +276,14 @@ _codecs_utf_7_decode_impl(PyObject *module, Py_buffer *data, _codecs.utf_8_decode data: Py_buffer errors: str(accept={str, NoneType}) = None - final: bool(accept={int}) = False + final: bool = False / [clinic start generated code]*/ static PyObject * _codecs_utf_8_decode_impl(PyObject *module, Py_buffer *data, const char *errors, int final) -/*[clinic end generated code: output=10f74dec8d9bb8bf input=f611b3867352ba59]*/ +/*[clinic end generated code: output=10f74dec8d9bb8bf input=ca06bc8a9c970e25]*/ { Py_ssize_t consumed = data->len; PyObject *decoded = PyUnicode_DecodeUTF8Stateful(data->buf, data->len, @@ -295,14 +296,14 @@ _codecs_utf_8_decode_impl(PyObject *module, Py_buffer *data, _codecs.utf_16_decode data: Py_buffer errors: str(accept={str, NoneType}) = None - final: bool(accept={int}) = False + final: bool = False / [clinic start generated code]*/ static PyObject * _codecs_utf_16_decode_impl(PyObject *module, Py_buffer *data, const char *errors, int final) -/*[clinic end generated code: output=783b442abcbcc2d0 input=191d360bd7309180]*/ +/*[clinic end generated code: output=783b442abcbcc2d0 input=5b0f52071ba6cadc]*/ { int byteorder = 0; /* This is overwritten unless final is true. */ @@ -317,14 +318,14 @@ _codecs_utf_16_decode_impl(PyObject *module, Py_buffer *data, _codecs.utf_16_le_decode data: Py_buffer errors: str(accept={str, NoneType}) = None - final: bool(accept={int}) = False + final: bool = False / [clinic start generated code]*/ static PyObject * _codecs_utf_16_le_decode_impl(PyObject *module, Py_buffer *data, const char *errors, int final) -/*[clinic end generated code: output=899b9e6364379dcd input=c6904fdc27fb4724]*/ +/*[clinic end generated code: output=899b9e6364379dcd input=115bd8c7b783d0bf]*/ { int byteorder = -1; /* This is overwritten unless final is true. */ @@ -339,14 +340,14 @@ _codecs_utf_16_le_decode_impl(PyObject *module, Py_buffer *data, _codecs.utf_16_be_decode data: Py_buffer errors: str(accept={str, NoneType}) = None - final: bool(accept={int}) = False + final: bool = False / [clinic start generated code]*/ static PyObject * _codecs_utf_16_be_decode_impl(PyObject *module, Py_buffer *data, const char *errors, int final) -/*[clinic end generated code: output=49f6465ea07669c8 input=e49012400974649b]*/ +/*[clinic end generated code: output=49f6465ea07669c8 input=63131422b01f9cb4]*/ { int byteorder = 1; /* This is overwritten unless final is true. */ @@ -369,14 +370,14 @@ _codecs.utf_16_ex_decode data: Py_buffer errors: str(accept={str, NoneType}) = None byteorder: int = 0 - final: bool(accept={int}) = False + final: bool = False / [clinic start generated code]*/ static PyObject * _codecs_utf_16_ex_decode_impl(PyObject *module, Py_buffer *data, const char *errors, int byteorder, int final) -/*[clinic end generated code: output=0f385f251ecc1988 input=5a9c19f2e6b6cf0e]*/ +/*[clinic end generated code: output=0f385f251ecc1988 input=f368a51cf384bf4c]*/ { /* This is overwritten unless final is true. */ Py_ssize_t consumed = data->len; @@ -393,14 +394,14 @@ _codecs_utf_16_ex_decode_impl(PyObject *module, Py_buffer *data, _codecs.utf_32_decode data: Py_buffer errors: str(accept={str, NoneType}) = None - final: bool(accept={int}) = False + final: bool = False / [clinic start generated code]*/ static PyObject * _codecs_utf_32_decode_impl(PyObject *module, Py_buffer *data, const char *errors, int final) -/*[clinic end generated code: output=2fc961807f7b145f input=fd7193965627eb58]*/ +/*[clinic end generated code: output=2fc961807f7b145f input=fcdf3658c5e9b5f3]*/ { int byteorder = 0; /* This is overwritten unless final is true. */ @@ -415,14 +416,14 @@ _codecs_utf_32_decode_impl(PyObject *module, Py_buffer *data, _codecs.utf_32_le_decode data: Py_buffer errors: str(accept={str, NoneType}) = None - final: bool(accept={int}) = False + final: bool = False / [clinic start generated code]*/ static PyObject * _codecs_utf_32_le_decode_impl(PyObject *module, Py_buffer *data, const char *errors, int final) -/*[clinic end generated code: output=ec8f46b67a94f3e6 input=9078ec70acfe7613]*/ +/*[clinic end generated code: output=ec8f46b67a94f3e6 input=12220556e885f817]*/ { int byteorder = -1; /* This is overwritten unless final is true. */ @@ -437,14 +438,14 @@ _codecs_utf_32_le_decode_impl(PyObject *module, Py_buffer *data, _codecs.utf_32_be_decode data: Py_buffer errors: str(accept={str, NoneType}) = None - final: bool(accept={int}) = False + final: bool = False / [clinic start generated code]*/ static PyObject * _codecs_utf_32_be_decode_impl(PyObject *module, Py_buffer *data, const char *errors, int final) -/*[clinic end generated code: output=ff82bae862c92c4e input=f1ae1bbbb86648ff]*/ +/*[clinic end generated code: output=ff82bae862c92c4e input=2bc669b4781598db]*/ { int byteorder = 1; /* This is overwritten unless final is true. */ @@ -467,14 +468,14 @@ _codecs.utf_32_ex_decode data: Py_buffer errors: str(accept={str, NoneType}) = None byteorder: int = 0 - final: bool(accept={int}) = False + final: bool = False / [clinic start generated code]*/ static PyObject * _codecs_utf_32_ex_decode_impl(PyObject *module, Py_buffer *data, const char *errors, int byteorder, int final) -/*[clinic end generated code: output=6bfb177dceaf4848 input=e46a73bc859d0bd0]*/ +/*[clinic end generated code: output=6bfb177dceaf4848 input=4a2323d0013620df]*/ { Py_ssize_t consumed = data->len; PyObject *decoded = PyUnicode_DecodeUTF32Stateful(data->buf, data->len, @@ -489,14 +490,14 @@ _codecs_utf_32_ex_decode_impl(PyObject *module, Py_buffer *data, _codecs.unicode_escape_decode data: Py_buffer(accept={str, buffer}) errors: str(accept={str, NoneType}) = None - final: bool(accept={int}) = True + final: bool = True / [clinic start generated code]*/ static PyObject * _codecs_unicode_escape_decode_impl(PyObject *module, Py_buffer *data, const char *errors, int final) -/*[clinic end generated code: output=b284f97b12c635ee input=6154f039a9f7c639]*/ +/*[clinic end generated code: output=b284f97b12c635ee input=15019f081ffe272b]*/ { Py_ssize_t consumed = data->len; PyObject *decoded = _PyUnicode_DecodeUnicodeEscapeStateful(data->buf, data->len, @@ -509,14 +510,14 @@ _codecs_unicode_escape_decode_impl(PyObject *module, Py_buffer *data, _codecs.raw_unicode_escape_decode data: Py_buffer(accept={str, buffer}) errors: str(accept={str, NoneType}) = None - final: bool(accept={int}) = True + final: bool = True / [clinic start generated code]*/ static PyObject * _codecs_raw_unicode_escape_decode_impl(PyObject *module, Py_buffer *data, const char *errors, int final) -/*[clinic end generated code: output=11dbd96301e2879e input=2d166191beb3235a]*/ +/*[clinic end generated code: output=11dbd96301e2879e input=b93f823aa8c343ad]*/ { Py_ssize_t consumed = data->len; PyObject *decoded = _PyUnicode_DecodeRawUnicodeEscapeStateful(data->buf, data->len, @@ -585,14 +586,14 @@ _codecs_charmap_decode_impl(PyObject *module, Py_buffer *data, _codecs.mbcs_decode data: Py_buffer errors: str(accept={str, NoneType}) = None - final: bool(accept={int}) = False + final: bool = False / [clinic start generated code]*/ static PyObject * _codecs_mbcs_decode_impl(PyObject *module, Py_buffer *data, const char *errors, int final) -/*[clinic end generated code: output=39b65b8598938c4b input=1c1d50f08fa53789]*/ +/*[clinic end generated code: output=39b65b8598938c4b input=f144ad1ed6d8f5a6]*/ { Py_ssize_t consumed = data->len; PyObject *decoded = PyUnicode_DecodeMBCSStateful(data->buf, data->len, @@ -604,14 +605,14 @@ _codecs_mbcs_decode_impl(PyObject *module, Py_buffer *data, _codecs.oem_decode data: Py_buffer errors: str(accept={str, NoneType}) = None - final: bool(accept={int}) = False + final: bool = False / [clinic start generated code]*/ static PyObject * _codecs_oem_decode_impl(PyObject *module, Py_buffer *data, const char *errors, int final) -/*[clinic end generated code: output=da1617612f3fcad8 input=81b67cba811022e5]*/ +/*[clinic end generated code: output=da1617612f3fcad8 input=629bf87376d211b4]*/ { Py_ssize_t consumed = data->len; PyObject *decoded = PyUnicode_DecodeCodePageStateful(CP_OEMCP, @@ -624,14 +625,14 @@ _codecs.code_page_decode codepage: int data: Py_buffer errors: str(accept={str, NoneType}) = None - final: bool(accept={int}) = False + final: bool = False / [clinic start generated code]*/ static PyObject * _codecs_code_page_decode_impl(PyObject *module, int codepage, Py_buffer *data, const char *errors, int final) -/*[clinic end generated code: output=53008ea967da3fff input=c5f58d036cb63575]*/ +/*[clinic end generated code: output=53008ea967da3fff input=6a32589b0658c277]*/ { Py_ssize_t consumed = data->len; PyObject *decoded = PyUnicode_DecodeCodePageStateful(codepage, @@ -1048,6 +1049,7 @@ static PyMethodDef _codecs_functions[] = { }; static PyModuleDef_Slot _codecs_slots[] = { + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; diff --git a/Modules/_collectionsmodule.c b/Modules/_collectionsmodule.c index 741cfbe9..9a81531b 100644 --- a/Modules/_collectionsmodule.c +++ b/Modules/_collectionsmodule.c @@ -1,17 +1,56 @@ #include "Python.h" #include "pycore_call.h" // _PyObject_CallNoArgs() #include "pycore_long.h" // _PyLong_GetZero() +#include "pycore_moduleobject.h" // _PyModule_GetState() +#include "pycore_typeobject.h" // _PyType_GetModuleState() #include "structmember.h" // PyMemberDef #include <stddef.h> +typedef struct { + PyTypeObject *deque_type; + PyTypeObject *defdict_type; + PyTypeObject *dequeiter_type; + PyTypeObject *dequereviter_type; + PyTypeObject *tuplegetter_type; +} collections_state; + +static inline collections_state * +get_module_state(PyObject *mod) +{ + void *state = _PyModule_GetState(mod); + assert(state != NULL); + return (collections_state *)state; +} + +static inline collections_state * +get_module_state_by_cls(PyTypeObject *cls) +{ + void *state = _PyType_GetModuleState(cls); + assert(state != NULL); + return (collections_state *)state; +} + +static struct PyModuleDef _collectionsmodule; + +static inline collections_state * +find_module_state_by_def(PyTypeObject *type) +{ + PyObject *mod = PyType_GetModuleByDef(type, &_collectionsmodule); + assert(mod != NULL); + return get_module_state(mod); +} + /*[clinic input] module _collections -class _tuplegetter "_tuplegetterobject *" "&tuplegetter_type" +class _tuplegetter "_tuplegetterobject *" "clinic_state()->tuplegetter_type" [clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=a8ece4ccad7e30ac]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=7356042a89862e0e]*/ -static PyTypeObject tuplegetter_type; +/* We can safely assume type to be the defining class, + * since tuplegetter is not a base type */ +#define clinic_state() (get_module_state_by_cls(type)) #include "clinic/_collectionsmodule.c.h" +#undef clinic_state /* collections module implementation of a deque() datatype Written and maintained by Raymond D. Hettinger <python@rcn.com> @@ -94,8 +133,6 @@ typedef struct { PyObject *weakreflist; } dequeobject; -static PyTypeObject deque_type; - /* For debug builds, add error checking to track the endpoints * in the chain of links. The goal is to make sure that link * assignments only take place at endpoints so that links already @@ -299,8 +336,7 @@ deque_append_internal(dequeobject *deque, PyObject *item, Py_ssize_t maxlen) static PyObject * deque_append(dequeobject *deque, PyObject *item) { - Py_INCREF(item); - if (deque_append_internal(deque, item, deque->maxlen) < 0) + if (deque_append_internal(deque, Py_NewRef(item), deque->maxlen) < 0) return NULL; Py_RETURN_NONE; } @@ -336,8 +372,7 @@ deque_appendleft_internal(dequeobject *deque, PyObject *item, Py_ssize_t maxlen) static PyObject * deque_appendleft(dequeobject *deque, PyObject *item) { - Py_INCREF(item); - if (deque_appendleft_internal(deque, item, deque->maxlen) < 0) + if (deque_appendleft_internal(deque, Py_NewRef(item), deque->maxlen) < 0) return NULL; Py_RETURN_NONE; } @@ -486,11 +521,13 @@ deque_copy(PyObject *deque, PyObject *Py_UNUSED(ignored)) { PyObject *result; dequeobject *old_deque = (dequeobject *)deque; - if (Py_IS_TYPE(deque, &deque_type)) { + collections_state *state = find_module_state_by_def(Py_TYPE(deque)); + if (Py_IS_TYPE(deque, state->deque_type)) { dequeobject *new_deque; PyObject *rv; - new_deque = (dequeobject *)deque_new(&deque_type, (PyObject *)NULL, (PyObject *)NULL); + new_deque = (dequeobject *)deque_new(state->deque_type, + (PyObject *)NULL, (PyObject *)NULL); if (new_deque == NULL) return NULL; new_deque->maxlen = old_deque->maxlen; @@ -513,7 +550,7 @@ deque_copy(PyObject *deque, PyObject *Py_UNUSED(ignored)) else result = PyObject_CallFunction((PyObject *)(Py_TYPE(deque)), "Oi", deque, old_deque->maxlen, NULL); - if (result != NULL && !PyObject_TypeCheck(result, &deque_type)) { + if (result != NULL && !PyObject_TypeCheck(result, state->deque_type)) { PyErr_Format(PyExc_TypeError, "%.200s() must return a deque, not %.200s", Py_TYPE(deque)->tp_name, Py_TYPE(result)->tp_name); @@ -531,7 +568,8 @@ deque_concat(dequeobject *deque, PyObject *other) PyObject *new_deque, *result; int rv; - rv = PyObject_IsInstance(other, (PyObject *)&deque_type); + collections_state *state = find_module_state_by_def(Py_TYPE(deque)); + rv = PyObject_IsInstance(other, (PyObject *)state->deque_type); if (rv <= 0) { if (rv == 0) { PyErr_Format(PyExc_TypeError, @@ -655,14 +693,12 @@ deque_inplace_repeat(dequeobject *deque, Py_ssize_t n) size = Py_SIZE(deque); if (size == 0 || n == 1) { - Py_INCREF(deque); - return (PyObject *)deque; + return Py_NewRef(deque); } if (n <= 0) { deque_clear(deque); - Py_INCREF(deque); - return (PyObject *)deque; + return Py_NewRef(deque); } if (size == 1) { @@ -693,13 +729,11 @@ deque_inplace_repeat(dequeobject *deque, Py_ssize_t n) i += m; while (m--) { deque->rightindex++; - Py_INCREF(item); - deque->rightblock->data[deque->rightindex] = item; + deque->rightblock->data[deque->rightindex] = Py_NewRef(item); } } Py_SET_SIZE(deque, Py_SIZE(deque) + i); - Py_INCREF(deque); - return (PyObject *)deque; + return Py_NewRef(deque); } if ((size_t)size > PY_SSIZE_T_MAX / (size_t)n) { @@ -972,8 +1006,7 @@ deque_count(dequeobject *deque, PyObject *v) while (--n >= 0) { CHECK_NOT_END(b); - item = b->data[index]; - Py_INCREF(item); + item = Py_NewRef(b->data[index]); cmp = PyObject_RichCompareBool(item, v, Py_EQ); Py_DECREF(item); if (cmp < 0) @@ -997,7 +1030,7 @@ deque_count(dequeobject *deque, PyObject *v) } PyDoc_STRVAR(count_doc, -"D.count(value) -> integer -- return number of occurrences of value"); +"D.count(value) -- return number of occurrences of value"); static int deque_contains(dequeobject *deque, PyObject *v) @@ -1011,8 +1044,7 @@ deque_contains(dequeobject *deque, PyObject *v) while (--n >= 0) { CHECK_NOT_END(b); - item = b->data[index]; - Py_INCREF(item); + item = Py_NewRef(b->data[index]); cmp = PyObject_RichCompareBool(item, v, Py_EQ); Py_DECREF(item); if (cmp) { @@ -1106,7 +1138,7 @@ deque_index(dequeobject *deque, PyObject *const *args, Py_ssize_t nargs) } PyDoc_STRVAR(index_doc, -"D.index(value, [start, [stop]]) -> integer -- return first index of value.\n" +"D.index(value, [start, [stop]]) -- return first index of value.\n" "Raises ValueError if the value is not present."); /* insert(), remove(), and delitem() are implemented in terms of @@ -1201,8 +1233,7 @@ deque_item(dequeobject *deque, Py_ssize_t i) } } item = b->data[i]; - Py_INCREF(item); - return item; + return Py_NewRef(item); } static int @@ -1231,8 +1262,7 @@ deque_remove(dequeobject *deque, PyObject *value) int cmp, rv; for (i = 0 ; i < n; i++) { - item = b->data[index]; - Py_INCREF(item); + item = Py_NewRef(b->data[index]); cmp = PyObject_RichCompareBool(item, value, Py_EQ); Py_DECREF(item); if (cmp < 0) { @@ -1266,7 +1296,6 @@ deque_remove(dequeobject *deque, PyObject *value) static int deque_ass_item(dequeobject *deque, Py_ssize_t i, PyObject *v) { - PyObject *old_value; block *b; Py_ssize_t n, len=Py_SIZE(deque), halflen=(len+1)>>1, index=i; @@ -1292,16 +1321,14 @@ deque_ass_item(dequeobject *deque, Py_ssize_t i, PyObject *v) while (--n >= 0) b = b->leftlink; } - Py_INCREF(v); - old_value = b->data[i]; - b->data[i] = v; - Py_DECREF(old_value); + Py_SETREF(b->data[i], Py_NewRef(v)); return 0; } static void deque_dealloc(dequeobject *deque) { + PyTypeObject *tp = Py_TYPE(deque); Py_ssize_t i; PyObject_GC_UnTrack(deque); @@ -1317,12 +1344,15 @@ deque_dealloc(dequeobject *deque) for (i=0 ; i < deque->numfreeblocks ; i++) { PyMem_Free(deque->freeblocks[i]); } - Py_TYPE(deque)->tp_free(deque); + tp->tp_free(deque); + Py_DECREF(tp); } static int deque_traverse(dequeobject *deque, visitproc visit, void *arg) { + Py_VISIT(Py_TYPE(deque)); + block *b; PyObject *item; Py_ssize_t index; @@ -1407,8 +1437,9 @@ deque_richcompare(PyObject *v, PyObject *w, int op) Py_ssize_t vs, ws; int b, cmp=-1; - if (!PyObject_TypeCheck(v, &deque_type) || - !PyObject_TypeCheck(w, &deque_type)) { + collections_state *state = find_module_state_by_def(Py_TYPE(v)); + if (!PyObject_TypeCheck(v, state->deque_type) || + !PyObject_TypeCheck(w, state->deque_type)) { Py_RETURN_NOTIMPLEMENTED; } @@ -1522,15 +1553,13 @@ deque_init(dequeobject *deque, PyObject *args, PyObject *kwdargs) static PyObject * deque_sizeof(dequeobject *deque, void *unused) { - Py_ssize_t res; - Py_ssize_t blocks; - - res = _PyObject_SIZE(Py_TYPE(deque)); + size_t res = _PyObject_SIZE(Py_TYPE(deque)); + size_t blocks; blocks = (size_t)(deque->leftindex + Py_SIZE(deque) + BLOCKLEN - 1) / BLOCKLEN; - assert(deque->leftindex + Py_SIZE(deque) - 1 == - (blocks - 1) * BLOCKLEN + deque->rightindex); + assert(((size_t)deque->leftindex + (size_t)Py_SIZE(deque) - 1) == + ((blocks - 1) * BLOCKLEN + (size_t)deque->rightindex)); res += blocks * sizeof(block); - return PyLong_FromSsize_t(res); + return PyLong_FromSize_t(res); } PyDoc_STRVAR(sizeof_doc, @@ -1553,19 +1582,6 @@ static PyGetSetDef deque_getset[] = { {0} }; -static PySequenceMethods deque_as_sequence = { - (lenfunc)deque_len, /* sq_length */ - (binaryfunc)deque_concat, /* sq_concat */ - (ssizeargfunc)deque_repeat, /* sq_repeat */ - (ssizeargfunc)deque_item, /* sq_item */ - 0, /* sq_slice */ - (ssizeobjargproc)deque_ass_item, /* sq_ass_item */ - 0, /* sq_ass_slice */ - (objobjproc)deque_contains, /* sq_contains */ - (binaryfunc)deque_inplace_concat, /* sq_inplace_concat */ - (ssizeargfunc)deque_inplace_repeat, /* sq_inplace_repeat */ -}; - static PyObject *deque_iter(dequeobject *deque); static PyObject *deque_reviter(dequeobject *deque, PyObject *Py_UNUSED(ignored)); PyDoc_STRVAR(reversed_doc, @@ -1613,54 +1629,53 @@ static PyMethodDef deque_methods[] = { {NULL, NULL} /* sentinel */ }; +static PyMemberDef deque_members[] = { + {"__weaklistoffset__", T_PYSSIZET, offsetof(dequeobject, weakreflist), READONLY}, + {NULL}, +}; + PyDoc_STRVAR(deque_doc, "deque([iterable[, maxlen]]) --> deque object\n\ \n\ A list-like sequence optimized for data accesses near its endpoints."); -static PyTypeObject deque_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "collections.deque", /* tp_name */ - sizeof(dequeobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)deque_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - deque_repr, /* tp_repr */ - 0, /* tp_as_number */ - &deque_as_sequence, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - PyObject_HashNotImplemented, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | - Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_SEQUENCE, - /* tp_flags */ - deque_doc, /* tp_doc */ - (traverseproc)deque_traverse, /* tp_traverse */ - (inquiry)deque_clear, /* tp_clear */ - (richcmpfunc)deque_richcompare, /* tp_richcompare */ - offsetof(dequeobject, weakreflist), /* tp_weaklistoffset*/ - (getiterfunc)deque_iter, /* tp_iter */ - 0, /* tp_iternext */ - deque_methods, /* tp_methods */ - 0, /* tp_members */ - deque_getset, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc)deque_init, /* tp_init */ - PyType_GenericAlloc, /* tp_alloc */ - deque_new, /* tp_new */ - PyObject_GC_Del, /* tp_free */ +static PyType_Slot deque_slots[] = { + {Py_tp_dealloc, deque_dealloc}, + {Py_tp_repr, deque_repr}, + {Py_tp_hash, PyObject_HashNotImplemented}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_doc, (void *)deque_doc}, + {Py_tp_traverse, deque_traverse}, + {Py_tp_clear, deque_clear}, + {Py_tp_richcompare, deque_richcompare}, + {Py_tp_iter, deque_iter}, + {Py_tp_getset, deque_getset}, + {Py_tp_init, deque_init}, + {Py_tp_alloc, PyType_GenericAlloc}, + {Py_tp_new, deque_new}, + {Py_tp_free, PyObject_GC_Del}, + {Py_tp_methods, deque_methods}, + {Py_tp_members, deque_members}, + + // Sequence protocol + {Py_sq_length, deque_len}, + {Py_sq_concat, deque_concat}, + {Py_sq_repeat, deque_repeat}, + {Py_sq_item, deque_item}, + {Py_sq_ass_item, deque_ass_item}, + {Py_sq_contains, deque_contains}, + {Py_sq_inplace_concat, deque_inplace_concat}, + {Py_sq_inplace_repeat, deque_inplace_repeat}, + {0, NULL}, +}; + +static PyType_Spec deque_spec = { + .name = "collections.deque", + .basicsize = sizeof(dequeobject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_SEQUENCE | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = deque_slots, }; /*********************** Deque Iterator **************************/ @@ -1674,20 +1689,18 @@ typedef struct { Py_ssize_t counter; /* number of items remaining for iteration */ } dequeiterobject; -static PyTypeObject dequeiter_type; - static PyObject * deque_iter(dequeobject *deque) { dequeiterobject *it; - it = PyObject_GC_New(dequeiterobject, &dequeiter_type); + collections_state *state = find_module_state_by_def(Py_TYPE(deque)); + it = PyObject_GC_New(dequeiterobject, state->dequeiter_type); if (it == NULL) return NULL; it->b = deque->leftblock; it->index = deque->leftindex; - Py_INCREF(deque); - it->deque = deque; + it->deque = (dequeobject*)Py_NewRef(deque); it->state = deque->state; it->counter = Py_SIZE(deque); PyObject_GC_Track(it); @@ -1697,17 +1710,27 @@ deque_iter(dequeobject *deque) static int dequeiter_traverse(dequeiterobject *dio, visitproc visit, void *arg) { + Py_VISIT(Py_TYPE(dio)); Py_VISIT(dio->deque); return 0; } +static int +dequeiter_clear(dequeiterobject *dio) +{ + Py_CLEAR(dio->deque); + return 0; +} + static void dequeiter_dealloc(dequeiterobject *dio) { /* bpo-31095: UnTrack is needed before calling any callbacks */ + PyTypeObject *tp = Py_TYPE(dio); PyObject_GC_UnTrack(dio); - Py_XDECREF(dio->deque); + (void)dequeiter_clear(dio); PyObject_GC_Del(dio); + Py_DECREF(tp); } static PyObject * @@ -1734,8 +1757,7 @@ dequeiter_next(dequeiterobject *it) it->b = it->b->rightlink; it->index = 0; } - Py_INCREF(item); - return item; + return Py_NewRef(item); } static PyObject * @@ -1744,9 +1766,10 @@ dequeiter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) Py_ssize_t i, index=0; PyObject *deque; dequeiterobject *it; - if (!PyArg_ParseTuple(args, "O!|n", &deque_type, &deque, &index)) + collections_state *state = get_module_state_by_cls(type); + if (!PyArg_ParseTuple(args, "O!|n", state->deque_type, &deque, &index)) return NULL; - assert(type == &dequeiter_type); + assert(type == state->dequeiter_type); it = (dequeiterobject*)deque_iter((dequeobject *)deque); if (!it) @@ -1787,65 +1810,40 @@ static PyMethodDef dequeiter_methods[] = { {NULL, NULL} /* sentinel */ }; -static PyTypeObject dequeiter_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_collections._deque_iterator", /* tp_name */ - sizeof(dequeiterobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)dequeiter_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ - 0, /* tp_doc */ - (traverseproc)dequeiter_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)dequeiter_next, /* tp_iternext */ - dequeiter_methods, /* 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 */ - 0, /* tp_init */ - 0, /* tp_alloc */ - dequeiter_new, /* tp_new */ - 0, +static PyType_Slot dequeiter_slots[] = { + {Py_tp_dealloc, dequeiter_dealloc}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_traverse, dequeiter_traverse}, + {Py_tp_clear, dequeiter_clear}, + {Py_tp_iter, PyObject_SelfIter}, + {Py_tp_iternext, dequeiter_next}, + {Py_tp_methods, dequeiter_methods}, + {Py_tp_new, dequeiter_new}, + {0, NULL}, }; -/*********************** Deque Reverse Iterator **************************/ +static PyType_Spec dequeiter_spec = { + .name = "collections._deque_iterator", + .basicsize = sizeof(dequeiterobject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = dequeiter_slots, +}; -static PyTypeObject dequereviter_type; +/*********************** Deque Reverse Iterator **************************/ static PyObject * deque_reviter(dequeobject *deque, PyObject *Py_UNUSED(ignored)) { dequeiterobject *it; + collections_state *state = find_module_state_by_def(Py_TYPE(deque)); - it = PyObject_GC_New(dequeiterobject, &dequereviter_type); + it = PyObject_GC_New(dequeiterobject, state->dequereviter_type); if (it == NULL) return NULL; it->b = deque->rightblock; it->index = deque->rightindex; - Py_INCREF(deque); - it->deque = deque; + it->deque = (dequeobject*)Py_NewRef(deque); it->state = deque->state; it->counter = Py_SIZE(deque); PyObject_GC_Track(it); @@ -1876,8 +1874,7 @@ dequereviter_next(dequeiterobject *it) it->b = it->b->leftlink; it->index = BLOCKLEN - 1; } - Py_INCREF(item); - return item; + return Py_NewRef(item); } static PyObject * @@ -1886,9 +1883,10 @@ dequereviter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) Py_ssize_t i, index=0; PyObject *deque; dequeiterobject *it; - if (!PyArg_ParseTuple(args, "O!|n", &deque_type, &deque, &index)) + collections_state *state = get_module_state_by_cls(type); + if (!PyArg_ParseTuple(args, "O!|n", state->deque_type, &deque, &index)) return NULL; - assert(type == &dequereviter_type); + assert(type == state->dequereviter_type); it = (dequeiterobject*)deque_reviter((dequeobject *)deque, NULL); if (!it) @@ -1909,47 +1907,24 @@ dequereviter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return (PyObject*)it; } -static PyTypeObject dequereviter_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_collections._deque_reverse_iterator", /* tp_name */ - sizeof(dequeiterobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)dequeiter_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ - 0, /* tp_doc */ - (traverseproc)dequeiter_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)dequereviter_next, /* tp_iternext */ - dequeiter_methods, /* 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 */ - 0, /* tp_init */ - 0, /* tp_alloc */ - dequereviter_new, /* tp_new */ - 0, +static PyType_Slot dequereviter_slots[] = { + {Py_tp_dealloc, dequeiter_dealloc}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_traverse, dequeiter_traverse}, + {Py_tp_clear, dequeiter_clear}, + {Py_tp_iter, PyObject_SelfIter}, + {Py_tp_iternext, dequereviter_next}, + {Py_tp_methods, dequeiter_methods}, + {Py_tp_new, dequereviter_new}, + {0, NULL}, +}; + +static PyType_Spec dequereviter_spec = { + .name = "collections._deque_reverse_iterator", + .basicsize = sizeof(dequeiterobject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = dequereviter_slots, }; /* defaultdict type *********************************************************/ @@ -1959,8 +1934,6 @@ typedef struct { PyObject *default_factory; } defdictobject; -static PyTypeObject defdict_type; /* Forward */ - PyDoc_STRVAR(defdict_missing_doc, "__missing__(key) # Called by __getitem__ for missing key; pseudo-code:\n\ if self.default_factory is None: raise KeyError((key,))\n\ @@ -2091,9 +2064,11 @@ static void defdict_dealloc(defdictobject *dd) { /* bpo-31095: UnTrack is needed before calling any callbacks */ + PyTypeObject *tp = Py_TYPE(dd); PyObject_GC_UnTrack(dd); Py_CLEAR(dd->default_factory); PyDict_Type.tp_dealloc((PyObject *)dd); + Py_DECREF(tp); } static PyObject * @@ -2137,11 +2112,24 @@ static PyObject* defdict_or(PyObject* left, PyObject* right) { PyObject *self, *other; - if (PyObject_TypeCheck(left, &defdict_type)) { + + // Find module state + PyTypeObject *tp = Py_TYPE(left); + PyObject *mod = PyType_GetModuleByDef(tp, &_collectionsmodule); + if (mod == NULL) { + PyErr_Clear(); + tp = Py_TYPE(right); + mod = PyType_GetModuleByDef(tp, &_collectionsmodule); + } + assert(mod != NULL); + collections_state *state = get_module_state(mod); + + if (PyObject_TypeCheck(left, state->defdict_type)) { self = left; other = right; } else { + assert(PyObject_TypeCheck(right, state->defdict_type)); self = right; other = left; } @@ -2161,13 +2149,10 @@ defdict_or(PyObject* left, PyObject* right) return new; } -static PyNumberMethods defdict_as_number = { - .nb_or = defdict_or, -}; - static int defdict_traverse(PyObject *self, visitproc visit, void *arg) { + Py_VISIT(Py_TYPE(self)); Py_VISIT(((defdictobject *)self)->default_factory); return PyDict_Type.tp_traverse(self, visit, arg); } @@ -2203,8 +2188,7 @@ defdict_init(PyObject *self, PyObject *args, PyObject *kwds) } if (newargs == NULL) return -1; - Py_XINCREF(newdefault); - dd->default_factory = newdefault; + dd->default_factory = Py_XNewRef(newdefault); result = PyDict_Type.tp_init(self, newargs, kwds); Py_DECREF(newargs); Py_XDECREF(olddefault); @@ -2224,48 +2208,28 @@ passed to the dict constructor, including keyword arguments.\n\ /* See comment in xxsubtype.c */ #define DEFERRED_ADDRESS(ADDR) 0 -static PyTypeObject defdict_type = { - PyVarObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type), 0) - "collections.defaultdict", /* tp_name */ - sizeof(defdictobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)defdict_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - (reprfunc)defdict_repr, /* tp_repr */ - &defdict_as_number, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, - /* tp_flags */ - defdict_doc, /* tp_doc */ - defdict_traverse, /* tp_traverse */ - (inquiry)defdict_tp_clear, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset*/ - 0, /* tp_iter */ - 0, /* tp_iternext */ - defdict_methods, /* tp_methods */ - defdict_members, /* tp_members */ - 0, /* tp_getset */ - DEFERRED_ADDRESS(&PyDict_Type), /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - defdict_init, /* tp_init */ - PyType_GenericAlloc, /* tp_alloc */ - 0, /* tp_new */ - PyObject_GC_Del, /* tp_free */ +static PyType_Slot defdict_slots[] = { + {Py_tp_dealloc, defdict_dealloc}, + {Py_tp_repr, defdict_repr}, + {Py_nb_or, defdict_or}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_doc, (void *)defdict_doc}, + {Py_tp_traverse, defdict_traverse}, + {Py_tp_clear, defdict_tp_clear}, + {Py_tp_methods, defdict_methods}, + {Py_tp_members, defdict_members}, + {Py_tp_init, defdict_init}, + {Py_tp_alloc, PyType_GenericAlloc}, + {Py_tp_free, PyObject_GC_Del}, + {0, NULL}, +}; + +static PyType_Spec defdict_spec = { + .name = "collections.defaultdict", + .basicsize = sizeof(defdictobject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = defdict_slots, }; /* helper function for Counter *********************************************/ @@ -2414,8 +2378,7 @@ tuplegetter_new_impl(PyTypeObject *type, Py_ssize_t index, PyObject *doc) return NULL; } self->index = index; - Py_INCREF(doc); - self->doc = doc; + self->doc = Py_NewRef(doc); return (PyObject *)self; } @@ -2426,13 +2389,11 @@ tuplegetter_descr_get(PyObject *self, PyObject *obj, PyObject *type) PyObject *result; if (obj == NULL) { - Py_INCREF(self); - return self; + return Py_NewRef(self); } if (!PyTuple_Check(obj)) { if (obj == Py_None) { - Py_INCREF(self); - return self; + return Py_NewRef(self); } PyErr_Format(PyExc_TypeError, "descriptor for index '%zd' for tuple subclasses " @@ -2448,8 +2409,7 @@ tuplegetter_descr_get(PyObject *self, PyObject *obj, PyObject *type) } result = PyTuple_GET_ITEM(obj, index); - Py_INCREF(result); - return result; + return Py_NewRef(result); } static int @@ -2467,6 +2427,7 @@ static int tuplegetter_traverse(PyObject *self, visitproc visit, void *arg) { _tuplegetterobject *tuplegetter = (_tuplegetterobject *)self; + Py_VISIT(Py_TYPE(tuplegetter)); Py_VISIT(tuplegetter->doc); return 0; } @@ -2482,9 +2443,11 @@ tuplegetter_clear(PyObject *self) static void tuplegetter_dealloc(_tuplegetterobject *self) { + PyTypeObject *tp = Py_TYPE(self); PyObject_GC_UnTrack(self); tuplegetter_clear((PyObject*)self); - Py_TYPE(self)->tp_free((PyObject*)self); + tp->tp_free((PyObject*)self); + Py_DECREF(tp); } static PyObject* @@ -2512,52 +2475,60 @@ static PyMethodDef tuplegetter_methods[] = { {NULL}, }; -static PyTypeObject tuplegetter_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_collections._tuplegetter", /* tp_name */ - sizeof(_tuplegetterobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)tuplegetter_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - (reprfunc)tuplegetter_repr, /* 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_HAVE_GC, /* tp_flags */ - 0, /* tp_doc */ - (traverseproc)tuplegetter_traverse, /* tp_traverse */ - (inquiry)tuplegetter_clear, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - tuplegetter_methods, /* tp_methods */ - tuplegetter_members, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - tuplegetter_descr_get, /* tp_descr_get */ - tuplegetter_descr_set, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - tuplegetter_new, /* tp_new */ - 0, +static PyType_Slot tuplegetter_slots[] = { + {Py_tp_dealloc, tuplegetter_dealloc}, + {Py_tp_repr, tuplegetter_repr}, + {Py_tp_traverse, tuplegetter_traverse}, + {Py_tp_clear, tuplegetter_clear}, + {Py_tp_methods, tuplegetter_methods}, + {Py_tp_members, tuplegetter_members}, + {Py_tp_descr_get, tuplegetter_descr_get}, + {Py_tp_descr_set, tuplegetter_descr_set}, + {Py_tp_new, tuplegetter_new}, + {0, NULL}, +}; + +static PyType_Spec tuplegetter_spec = { + .name = "collections._tuplegetter", + .basicsize = sizeof(_tuplegetterobject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = tuplegetter_slots, }; /* module level code ********************************************************/ +static int +collections_traverse(PyObject *mod, visitproc visit, void *arg) +{ + collections_state *state = get_module_state(mod); + Py_VISIT(state->deque_type); + Py_VISIT(state->defdict_type); + Py_VISIT(state->dequeiter_type); + Py_VISIT(state->dequereviter_type); + Py_VISIT(state->tuplegetter_type); + return 0; +} + +static int +collections_clear(PyObject *mod) +{ + collections_state *state = get_module_state(mod); + Py_CLEAR(state->deque_type); + Py_CLEAR(state->defdict_type); + Py_CLEAR(state->dequeiter_type); + Py_CLEAR(state->dequereviter_type); + Py_CLEAR(state->tuplegetter_type); + return 0; +} + +static void +collections_free(void *module) +{ + collections_clear((PyObject *)module); +} + PyDoc_STRVAR(collections_doc, "High performance data structures.\n\ - deque: ordered collection accessible from endpoints only\n\ @@ -2569,43 +2540,51 @@ static struct PyMethodDef collections_methods[] = { {NULL, NULL} /* sentinel */ }; +#define ADD_TYPE(MOD, SPEC, TYPE, BASE) do { \ + TYPE = (PyTypeObject *)PyType_FromMetaclass(NULL, MOD, SPEC, \ + (PyObject *)BASE); \ + if (TYPE == NULL) { \ + return -1; \ + } \ + if (PyModule_AddType(MOD, TYPE) < 0) { \ + return -1; \ + } \ +} while (0) + static int collections_exec(PyObject *module) { - PyTypeObject *typelist[] = { - &deque_type, - &defdict_type, - &PyODict_Type, - &dequeiter_type, - &dequereviter_type, - &tuplegetter_type - }; - - defdict_type.tp_base = &PyDict_Type; - - for (size_t i = 0; i < Py_ARRAY_LENGTH(typelist); i++) { - if (PyModule_AddType(module, typelist[i]) < 0) { - return -1; - } + collections_state *state = get_module_state(module); + ADD_TYPE(module, &deque_spec, state->deque_type, NULL); + ADD_TYPE(module, &defdict_spec, state->defdict_type, &PyDict_Type); + ADD_TYPE(module, &dequeiter_spec, state->dequeiter_type, NULL); + ADD_TYPE(module, &dequereviter_spec, state->dequereviter_type, NULL); + ADD_TYPE(module, &tuplegetter_spec, state->tuplegetter_type, NULL); + + if (PyModule_AddType(module, &PyODict_Type) < 0) { + return -1; } return 0; } +#undef ADD_TYPE + static struct PyModuleDef_Slot collections_slots[] = { {Py_mod_exec, collections_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; static struct PyModuleDef _collectionsmodule = { - PyModuleDef_HEAD_INIT, - "_collections", - collections_doc, - 0, - collections_methods, - collections_slots, - NULL, - NULL, - NULL + .m_base = PyModuleDef_HEAD_INIT, + .m_name = "_collections", + .m_doc = collections_doc, + .m_size = sizeof(collections_state), + .m_methods = collections_methods, + .m_slots = collections_slots, + .m_traverse = collections_traverse, + .m_clear = collections_clear, + .m_free = collections_free, }; PyMODINIT_FUNC diff --git a/Modules/_contextvarsmodule.c b/Modules/_contextvarsmodule.c index d13b5962..f621c1de 100644 --- a/Modules/_contextvarsmodule.c +++ b/Modules/_contextvarsmodule.c @@ -44,6 +44,7 @@ _contextvars_exec(PyObject *m) static struct PyModuleDef_Slot _contextvars_slots[] = { {Py_mod_exec, _contextvars_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; diff --git a/Modules/_cryptmodule.c b/Modules/_cryptmodule.c index 72a4f446..75035084 100644 --- a/Modules/_cryptmodule.c +++ b/Modules/_cryptmodule.c @@ -58,6 +58,7 @@ static PyMethodDef crypt_methods[] = { }; static PyModuleDef_Slot _crypt_slots[] = { + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; diff --git a/Modules/_csv.c b/Modules/_csv.c index 7519da68..9ab2ad26 100644 --- a/Modules/_csv.c +++ b/Modules/_csv.c @@ -82,7 +82,8 @@ typedef enum { } ParserState; typedef enum { - QUOTE_MINIMAL, QUOTE_ALL, QUOTE_NONNUMERIC, QUOTE_NONE + QUOTE_MINIMAL, QUOTE_ALL, QUOTE_NONNUMERIC, QUOTE_NONE, + QUOTE_STRINGS, QUOTE_NOTNULL } QuoteStyle; typedef struct { @@ -95,6 +96,8 @@ static const StyleDesc quote_styles[] = { { QUOTE_ALL, "QUOTE_ALL" }, { QUOTE_NONNUMERIC, "QUOTE_NONNUMERIC" }, { QUOTE_NONE, "QUOTE_NONE" }, + { QUOTE_STRINGS, "QUOTE_STRINGS" }, + { QUOTE_NOTNULL, "QUOTE_NOTNULL" }, { 0 } }; @@ -176,8 +179,7 @@ get_char_or_None(Py_UCS4 c) static PyObject * Dialect_get_lineterminator(DialectObj *self, void *Py_UNUSED(ignored)) { - Py_XINCREF(self->lineterminator); - return self->lineterminator; + return Py_XNewRef(self->lineterminator); } static PyObject * @@ -316,8 +318,7 @@ _set_str(const char *name, PyObject **target, PyObject *src, const char *dflt) else { if (PyUnicode_READY(src) == -1) return -1; - Py_INCREF(src); - Py_XSETREF(*target, src); + Py_XSETREF(*target, Py_NewRef(src)); } } return 0; @@ -514,8 +515,7 @@ dialect_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) goto err; } - ret = (PyObject *)self; - Py_INCREF(self); + ret = Py_NewRef(self); err: Py_CLEAR(self); Py_CLEAR(dialect); @@ -868,7 +868,7 @@ Reader_iternext(ReaderObj *self) PyObject *fields = NULL; Py_UCS4 c; Py_ssize_t pos, linelen; - unsigned int kind; + int kind; const void *data; PyObject *lineobj; @@ -1000,7 +1000,7 @@ PyType_Spec Reader_Type_spec = { .name = "_csv.reader", .basicsize = sizeof(ReaderObj), .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_IMMUTABLETYPE), + Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_DISALLOW_INSTANTIATION), .slots = Reader_Type_slots }; @@ -1066,7 +1066,7 @@ join_reset(WriterObj *self) * record length. */ static Py_ssize_t -join_append_data(WriterObj *self, unsigned int field_kind, const void *field_data, +join_append_data(WriterObj *self, int field_kind, const void *field_data, Py_ssize_t field_len, int *quoted, int copy_phase) { @@ -1179,7 +1179,7 @@ join_check_rec_size(WriterObj *self, Py_ssize_t rec_len) static int join_append(WriterObj *self, PyObject *field, int quoted) { - unsigned int field_kind = -1; + int field_kind = -1; const void *field_data = NULL; Py_ssize_t field_len = 0; Py_ssize_t rec_len; @@ -1211,7 +1211,7 @@ static int join_append_lineterminator(WriterObj *self) { Py_ssize_t terminator_len, i; - unsigned int term_kind; + int term_kind; const void *term_data; terminator_len = PyUnicode_GET_LENGTH(self->dialect->lineterminator); @@ -1267,6 +1267,12 @@ csv_writerow(WriterObj *self, PyObject *seq) case QUOTE_ALL: quoted = 1; break; + case QUOTE_STRINGS: + quoted = PyUnicode_Check(field); + break; + case QUOTE_NOTNULL: + quoted = field != Py_None; + break; default: quoted = 0; break; @@ -1425,7 +1431,7 @@ PyType_Spec Writer_Type_spec = { .name = "_csv.writer", .basicsize = sizeof(WriterObj), .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_IMMUTABLETYPE), + Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_DISALLOW_INSTANTIATION), .slots = Writer_Type_slots, }; @@ -1662,6 +1668,11 @@ PyDoc_STRVAR(csv_module_doc, " csv.QUOTE_NONNUMERIC means that quotes are always placed around\n" " fields which do not parse as integers or floating point\n" " numbers.\n" +" csv.QUOTE_STRINGS means that quotes are always placed around\n" +" fields which are strings. Note that the Python value None\n" +" is not a string.\n" +" csv.QUOTE_NOTNULL means that quotes are only placed around fields\n" +" that are not the Python value None.\n" " csv.QUOTE_NONE means that quotes are never placed around fields.\n" " * escapechar - specifies a one-character string used to escape\n" " the delimiter when quoting is set to QUOTE_NONE.\n" @@ -1787,6 +1798,7 @@ csv_exec(PyObject *module) { static PyModuleDef_Slot csv_slots[] = { {Py_mod_exec, csv_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index fc73264f..534ef8c1 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -101,8 +101,6 @@ bytes(cdata) #ifndef Py_BUILD_CORE_BUILTIN # define Py_BUILD_CORE_MODULE 1 #endif -#define NEEDS_PY_IDENTIFIER - #define PY_SSIZE_T_CLEAN #include "Python.h" @@ -122,12 +120,14 @@ bytes(cdata) #define IS_INTRESOURCE(x) (((size_t)(x) >> 16) == 0) #endif #else -#include "ctypes_dlfcn.h" +#include <dlfcn.h> #endif #include "ctypes.h" #include "pycore_long.h" // _PyLong_GetZero() +ctypes_state global_state; + PyObject *PyExc_ArgError = NULL; /* This dict maps ctypes types to POINTER types */ @@ -139,10 +139,6 @@ static PyTypeObject Simple_Type; strong reference to _ctypes._unpickle() function */ static PyObject *_unpickle; -#ifdef MS_WIN32 -PyObject *ComError; // Borrowed reference to: &PyComError_Type -#endif - /****************************************************************/ @@ -152,13 +148,32 @@ typedef struct { PyObject *dict; } DictRemoverObject; +static int +_DictRemover_traverse(DictRemoverObject *self, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(self)); + Py_VISIT(self->key); + Py_VISIT(self->dict); + return 0; +} + +static int +_DictRemover_clear(DictRemoverObject *self) +{ + Py_CLEAR(self->key); + Py_CLEAR(self->dict); + return 0; +} + static void _DictRemover_dealloc(PyObject *myself) { + PyTypeObject *tp = Py_TYPE(myself); DictRemoverObject *self = (DictRemoverObject *)myself; - Py_XDECREF(self->key); - Py_XDECREF(self->dict); - Py_TYPE(self)->tp_free(myself); + PyObject_GC_UnTrack(myself); + (void)_DictRemover_clear(self); + tp->tp_free(myself); + Py_DECREF(tp); } static PyObject * @@ -175,47 +190,23 @@ _DictRemover_call(PyObject *myself, PyObject *args, PyObject *kw) Py_RETURN_NONE; } -static PyTypeObject DictRemover_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_ctypes.DictRemover", /* tp_name */ - sizeof(DictRemoverObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - _DictRemover_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - _DictRemover_call, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ -/* XXX should participate in GC? */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ - PyDoc_STR("deletes a key from a dictionary"), /* 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 */ - 0, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ - 0, /* tp_free */ +PyDoc_STRVAR(dictremover_doc, "deletes a key from a dictionary"); + +static PyType_Slot dictremover_slots[] = { + {Py_tp_dealloc, _DictRemover_dealloc}, + {Py_tp_traverse, _DictRemover_traverse}, + {Py_tp_clear, _DictRemover_clear}, + {Py_tp_call, _DictRemover_call}, + {Py_tp_doc, (void *)dictremover_doc}, + {0, NULL}, +}; + +static PyType_Spec dictremover_spec = { + .name = "_ctypes.DictRemover", + .basicsize = sizeof(DictRemoverObject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = dictremover_slots, }; int @@ -226,17 +217,16 @@ PyDict_SetItemProxy(PyObject *dict, PyObject *key, PyObject *item) PyObject *proxy; int result; - obj = _PyObject_CallNoArgs((PyObject *)&DictRemover_Type); + ctypes_state *st = GLOBAL_STATE(); + obj = _PyObject_CallNoArgs((PyObject *)st->DictRemover_Type); if (obj == NULL) return -1; remover = (DictRemoverObject *)obj; assert(remover->key == NULL); assert(remover->dict == NULL); - Py_INCREF(key); - remover->key = key; - Py_INCREF(dict); - remover->dict = dict; + remover->key = Py_NewRef(key); + remover->dict = Py_NewRef(dict); proxy = PyWeakref_NewProxy(item, obj); Py_DECREF(obj); @@ -396,9 +386,9 @@ _ctypes_alloc_format_string_with_shape(int ndim, const Py_ssize_t *shape, strcat(new_prefix, "("); for (k = 0; k < ndim; ++k) { if (k < ndim-1) { - sprintf(buf, "%"PY_FORMAT_SIZE_T"d,", shape[k]); + sprintf(buf, "%zd,", shape[k]); } else { - sprintf(buf, "%"PY_FORMAT_SIZE_T"d)", shape[k]); + sprintf(buf, "%zd)", shape[k]); } strcat(new_prefix, buf); } @@ -419,23 +409,45 @@ typedef struct { PyObject *keep; // If set, a reference to the original CDataObject. } StructParamObject; +static int +StructParam_traverse(StructParamObject *self, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(self)); + return 0; +} + +static int +StructParam_clear(StructParamObject *self) +{ + Py_CLEAR(self->keep); + return 0; +} static void StructParam_dealloc(PyObject *myself) { StructParamObject *self = (StructParamObject *)myself; - Py_XDECREF(self->keep); + PyTypeObject *tp = Py_TYPE(self); + PyObject_GC_UnTrack(myself); + (void)StructParam_clear(self); PyMem_Free(self->ptr); - Py_TYPE(self)->tp_free(myself); + tp->tp_free(myself); + Py_DECREF(tp); } +static PyType_Slot structparam_slots[] = { + {Py_tp_traverse, StructParam_traverse}, + {Py_tp_clear, StructParam_clear}, + {Py_tp_dealloc, StructParam_dealloc}, + {0, NULL}, +}; -static PyTypeObject StructParam_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - .tp_name = "_ctypes.StructParam_Type", - .tp_basicsize = sizeof(StructParamObject), - .tp_dealloc = StructParam_dealloc, - .tp_flags = Py_TPFLAGS_DEFAULT, +static PyType_Spec structparam_spec = { + .name = "_ctypes.StructParam_Type", + .basicsize = sizeof(StructParamObject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE | + Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_DISALLOW_INSTANTIATION), + .slots = structparam_slots, }; @@ -464,7 +476,9 @@ StructUnionType_paramfunc(CDataObject *self) /* Create a Python object which calls PyMem_Free(ptr) in its deallocator. The object will be destroyed at _ctypes_callproc() cleanup. */ - obj = (&StructParam_Type)->tp_alloc(&StructParam_Type, 0); + ctypes_state *st = GLOBAL_STATE(); + PyTypeObject *tp = st->StructParam_Type; + obj = tp->tp_alloc(tp, 0); if (obj == NULL) { PyMem_Free(ptr); return NULL; @@ -475,8 +489,7 @@ StructUnionType_paramfunc(CDataObject *self) struct_param->keep = Py_NewRef(self); } else { ptr = self->b_ptr; - obj = (PyObject *)self; - Py_INCREF(obj); + obj = Py_NewRef(self); } parg = PyCArgObject_new(); @@ -501,8 +514,6 @@ StructUnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds, int isSt PyTypeObject *result; PyObject *fields; StgDictObject *dict; - _Py_IDENTIFIER(_abstract_); - _Py_IDENTIFIER(_fields_); /* create the new instance (which is a class, since we are a metatype!) */ @@ -511,7 +522,7 @@ StructUnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds, int isSt return NULL; /* keep this for bw compatibility */ - int r = _PyDict_ContainsId(result->tp_dict, &PyId__abstract_); + int r = PyDict_Contains(result->tp_dict, &_Py_ID(_abstract_)); if (r > 0) return (PyObject *)result; if (r < 0) { @@ -543,9 +554,9 @@ StructUnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds, int isSt dict->paramfunc = StructUnionType_paramfunc; - fields = _PyDict_GetItemIdWithError((PyObject *)dict, &PyId__fields_); + fields = PyDict_GetItemWithError((PyObject *)dict, &_Py_ID(_fields_)); if (fields) { - if (_PyObject_SetAttrId((PyObject *)result, &PyId__fields_, fields) < 0) { + if (PyObject_SetAttr((PyObject *)result, &_Py_ID(_fields_), fields) < 0) { Py_DECREF(result); return NULL; } @@ -778,7 +789,7 @@ CDataType_in_dll(PyObject *type, PyObject *args) return NULL; } #else - address = (void *)ctypes_dlsym(handle, name); + address = (void *)dlsym(handle, name); if (!address) { #ifdef __CYGWIN__ /* dlerror() isn't very helpful on cygwin */ @@ -786,7 +797,7 @@ CDataType_in_dll(PyObject *type, PyObject *args) "symbol '%s' not found", name); #else - PyErr_SetString(PyExc_ValueError, ctypes_dlerror()); + PyErr_SetString(PyExc_ValueError, dlerror()); #endif return NULL; } @@ -800,16 +811,15 @@ PyDoc_STRVAR(from_param_doc, static PyObject * CDataType_from_param(PyObject *type, PyObject *value) { - _Py_IDENTIFIER(_as_parameter_); PyObject *as_parameter; int res = PyObject_IsInstance(value, type); if (res == -1) return NULL; if (res) { - Py_INCREF(value); - return value; + return Py_NewRef(value); } - if (PyCArg_CheckExact(value)) { + ctypes_state *st = GLOBAL_STATE(); + if (PyCArg_CheckExact(st, value)) { PyCArgObject *p = (PyCArgObject *)value; PyObject *ob = p->obj; const char *ob_name; @@ -823,8 +833,7 @@ CDataType_from_param(PyObject *type, PyObject *value) if (res == -1) return NULL; if (res) { - Py_INCREF(value); - return value; + return Py_NewRef(value); } } ob_name = (ob) ? Py_TYPE(ob)->tp_name : "???"; @@ -834,7 +843,7 @@ CDataType_from_param(PyObject *type, PyObject *value) return NULL; } - if (_PyObject_LookupAttrId(value, &PyId__as_parameter_, &as_parameter) < 0) { + if (_PyObject_LookupAttr(value, &_Py_ID(_as_parameter_), &as_parameter) < 0) { return NULL; } if (as_parameter) { @@ -1058,8 +1067,7 @@ PyCPointerType_paramfunc(CDataObject *self) parg->tag = 'P'; parg->pffi_type = &ffi_type_pointer; - Py_INCREF(self); - parg->obj = (PyObject *)self; + parg->obj = Py_NewRef(self); parg->value.p = *(void **)self->b_ptr; return parg; } @@ -1071,7 +1079,7 @@ PyCPointerType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) StgDictObject *stgdict; PyObject *proto; PyObject *typedict; - _Py_IDENTIFIER(_type_); + typedict = PyTuple_GetItem(args, 2); if (!typedict) @@ -1091,7 +1099,7 @@ PyCPointerType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) stgdict->paramfunc = PyCPointerType_paramfunc; stgdict->flags |= TYPEFLAG_ISPOINTER; - proto = _PyDict_GetItemIdWithError(typedict, &PyId__type_); /* Borrowed ref */ + proto = PyDict_GetItemWithError(typedict, &_Py_ID(_type_)); /* Borrowed ref */ if (proto) { StgDictObject *itemdict; const char *current_format; @@ -1149,7 +1157,7 @@ static PyObject * PyCPointerType_set_type(PyTypeObject *self, PyObject *type) { StgDictObject *dict; - _Py_IDENTIFIER(_type_); + dict = PyType_stgdict((PyObject *)self); if (!dict) { @@ -1161,7 +1169,7 @@ PyCPointerType_set_type(PyTypeObject *self, PyObject *type) if (-1 == PyCPointerType_SetProto(dict, type)) return NULL; - if (-1 == _PyDict_SetItemId((PyObject *)dict, &PyId__type_, type)) + if (-1 == PyDict_SetItem((PyObject *)dict, &_Py_ID(_type_), type)) return NULL; Py_RETURN_NONE; @@ -1176,8 +1184,7 @@ PyCPointerType_from_param(PyObject *type, PyObject *value) if (value == Py_None) { /* ConvParam will convert to a NULL pointer later */ - Py_INCREF(value); - return value; + return Py_NewRef(value); } typedict = PyType_stgdict(type); @@ -1211,8 +1218,7 @@ PyCPointerType_from_param(PyObject *type, PyObject *value) return NULL; } if (ret) { - Py_INCREF(value); - return value; + return Py_NewRef(value); } } return CDataType_from_param(type, value); @@ -1456,16 +1462,13 @@ PyCArrayType_paramfunc(CDataObject *self) p->tag = 'P'; p->pffi_type = &ffi_type_pointer; p->value.p = (char *)self->b_ptr; - Py_INCREF(self); - p->obj = (PyObject *)self; + p->obj = Py_NewRef(self); return p; } static PyObject * PyCArrayType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { - _Py_IDENTIFIER(_length_); - _Py_IDENTIFIER(_type_); PyTypeObject *result; StgDictObject *stgdict; StgDictObject *itemdict; @@ -1484,7 +1487,7 @@ PyCArrayType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) stgdict = NULL; type_attr = NULL; - if (_PyObject_LookupAttrId((PyObject *)result, &PyId__length_, &length_attr) < 0) { + if (_PyObject_LookupAttr((PyObject *)result, &_Py_ID(_length_), &length_attr) < 0) { goto error; } if (!length_attr) { @@ -1517,7 +1520,7 @@ PyCArrayType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) goto error; } - if (_PyObject_LookupAttrId((PyObject *)result, &PyId__type_, &type_attr) < 0) { + if (_PyObject_LookupAttr((PyObject *)result, &_Py_ID(_type_), &type_attr) < 0) { goto error; } if (!type_attr) { @@ -1662,7 +1665,6 @@ static const char SIMPLE_TYPE_CHARS[] = "cbBhHiIlLdfuzZqQPXOv?g"; static PyObject * c_wchar_p_from_param(PyObject *type, PyObject *value) { - _Py_IDENTIFIER(_as_parameter_); PyObject *as_parameter; int res; if (value == Py_None) { @@ -1688,8 +1690,7 @@ c_wchar_p_from_param(PyObject *type, PyObject *value) if (res == -1) return NULL; if (res) { - Py_INCREF(value); - return value; + return Py_NewRef(value); } if (ArrayObject_Check(value) || PointerObject_Check(value)) { /* c_wchar array instance or pointer(c_wchar(...)) */ @@ -1698,21 +1699,20 @@ c_wchar_p_from_param(PyObject *type, PyObject *value) assert(dt); /* Cannot be NULL for pointer or array objects */ dict = dt && dt->proto ? PyType_stgdict(dt->proto) : NULL; if (dict && (dict->setfunc == _ctypes_get_fielddesc("u")->setfunc)) { - Py_INCREF(value); - return value; + return Py_NewRef(value); } } - if (PyCArg_CheckExact(value)) { + ctypes_state *st = GLOBAL_STATE(); + if (PyCArg_CheckExact(st, value)) { /* byref(c_char(...)) */ PyCArgObject *a = (PyCArgObject *)value; StgDictObject *dict = PyObject_stgdict(a->obj); if (dict && (dict->setfunc == _ctypes_get_fielddesc("u")->setfunc)) { - Py_INCREF(value); - return value; + return Py_NewRef(value); } } - if (_PyObject_LookupAttrId(value, &PyId__as_parameter_, &as_parameter) < 0) { + if (_PyObject_LookupAttr(value, &_Py_ID(_as_parameter_), &as_parameter) < 0) { return NULL; } if (as_parameter) { @@ -1729,7 +1729,6 @@ c_wchar_p_from_param(PyObject *type, PyObject *value) static PyObject * c_char_p_from_param(PyObject *type, PyObject *value) { - _Py_IDENTIFIER(_as_parameter_); PyObject *as_parameter; int res; if (value == Py_None) { @@ -1755,8 +1754,7 @@ c_char_p_from_param(PyObject *type, PyObject *value) if (res == -1) return NULL; if (res) { - Py_INCREF(value); - return value; + return Py_NewRef(value); } if (ArrayObject_Check(value) || PointerObject_Check(value)) { /* c_char array instance or pointer(c_char(...)) */ @@ -1765,21 +1763,20 @@ c_char_p_from_param(PyObject *type, PyObject *value) assert(dt); /* Cannot be NULL for pointer or array objects */ dict = dt && dt->proto ? PyType_stgdict(dt->proto) : NULL; if (dict && (dict->setfunc == _ctypes_get_fielddesc("c")->setfunc)) { - Py_INCREF(value); - return value; + return Py_NewRef(value); } } - if (PyCArg_CheckExact(value)) { + ctypes_state *st = GLOBAL_STATE(); + if (PyCArg_CheckExact(st, value)) { /* byref(c_char(...)) */ PyCArgObject *a = (PyCArgObject *)value; StgDictObject *dict = PyObject_stgdict(a->obj); if (dict && (dict->setfunc == _ctypes_get_fielddesc("c")->setfunc)) { - Py_INCREF(value); - return value; + return Py_NewRef(value); } } - if (_PyObject_LookupAttrId(value, &PyId__as_parameter_, &as_parameter) < 0) { + if (_PyObject_LookupAttr(value, &_Py_ID(_as_parameter_), &as_parameter) < 0) { return NULL; } if (as_parameter) { @@ -1796,7 +1793,6 @@ c_char_p_from_param(PyObject *type, PyObject *value) static PyObject * c_void_p_from_param(PyObject *type, PyObject *value) { - _Py_IDENTIFIER(_as_parameter_); StgDictObject *stgd; PyObject *as_parameter; int res; @@ -1864,22 +1860,20 @@ c_void_p_from_param(PyObject *type, PyObject *value) return NULL; if (res) { /* c_void_p instances */ - Py_INCREF(value); - return value; + return Py_NewRef(value); } /* ctypes array or pointer instance */ if (ArrayObject_Check(value) || PointerObject_Check(value)) { /* Any array or pointer is accepted */ - Py_INCREF(value); - return value; + return Py_NewRef(value); } /* byref(...) */ - if (PyCArg_CheckExact(value)) { + ctypes_state *st = GLOBAL_STATE(); + if (PyCArg_CheckExact(st, value)) { /* byref(c_xxx()) */ PyCArgObject *a = (PyCArgObject *)value; if (a->tag == 'P') { - Py_INCREF(value); - return value; + return Py_NewRef(value); } } /* function pointer */ @@ -1910,15 +1904,14 @@ c_void_p_from_param(PyObject *type, PyObject *value) return NULL; parg->pffi_type = &ffi_type_pointer; parg->tag = 'Z'; - Py_INCREF(value); - parg->obj = value; + parg->obj = Py_NewRef(value); /* Remember: b_ptr points to where the pointer is stored! */ parg->value.p = *(void **)(((CDataObject *)value)->b_ptr); return (PyObject *)parg; } } - if (_PyObject_LookupAttrId(value, &PyId__as_parameter_, &as_parameter) < 0) { + if (_PyObject_LookupAttr(value, &_Py_ID(_as_parameter_), &as_parameter) < 0) { return NULL; } if (as_parameter) { @@ -1996,8 +1989,7 @@ static PyObject *CreateSwappedType(PyTypeObject *type, PyObject *args, PyObject stgdict->setfunc = fmt->setfunc_swapped; stgdict->getfunc = fmt->getfunc_swapped; - Py_INCREF(proto); - stgdict->proto = proto; + stgdict->proto = Py_NewRef(proto); /* replace the class dict by our updated spam dict */ if (-1 == PyDict_Update((PyObject *)stgdict, result->tp_dict)) { @@ -2032,8 +2024,7 @@ PyCSimpleType_paramfunc(CDataObject *self) parg->tag = fmt[0]; parg->pffi_type = fd->pffi_type; - Py_INCREF(self); - parg->obj = (PyObject *)self; + parg->obj = Py_NewRef(self); memcpy(&parg->value, self->b_ptr, self->b_size); return parg; } @@ -2041,7 +2032,6 @@ PyCSimpleType_paramfunc(CDataObject *self) static PyObject * PyCSimpleType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { - _Py_IDENTIFIER(_type_); PyTypeObject *result; StgDictObject *stgdict; PyObject *proto; @@ -2056,7 +2046,7 @@ PyCSimpleType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) if (result == NULL) return NULL; - if (_PyObject_LookupAttrId((PyObject *)result, &PyId__type_, &proto) < 0) { + if (_PyObject_LookupAttr((PyObject *)result, &_Py_ID(_type_), &proto) < 0) { return NULL; } if (!proto) { @@ -2226,7 +2216,6 @@ PyCSimpleType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) static PyObject * PyCSimpleType_from_param(PyObject *type, PyObject *value) { - _Py_IDENTIFIER(_as_parameter_); StgDictObject *dict; const char *fmt; PyCArgObject *parg; @@ -2240,8 +2229,7 @@ PyCSimpleType_from_param(PyObject *type, PyObject *value) if (res == -1) return NULL; if (res) { - Py_INCREF(value); - return value; + return Py_NewRef(value); } dict = PyType_stgdict(type); @@ -2267,24 +2255,31 @@ PyCSimpleType_from_param(PyObject *type, PyObject *value) parg->obj = fd->setfunc(&parg->value, value, 0); if (parg->obj) return (PyObject *)parg; - PyErr_Clear(); + PyObject *exc = PyErr_GetRaisedException(); Py_DECREF(parg); - if (_PyObject_LookupAttrId(value, &PyId__as_parameter_, &as_parameter) < 0) { + if (_PyObject_LookupAttr(value, &_Py_ID(_as_parameter_), &as_parameter) < 0) { + Py_XDECREF(exc); return NULL; } if (as_parameter) { if (_Py_EnterRecursiveCall("while processing _as_parameter_")) { Py_DECREF(as_parameter); + Py_XDECREF(exc); return NULL; } value = PyCSimpleType_from_param(type, as_parameter); _Py_LeaveRecursiveCall(); Py_DECREF(as_parameter); + Py_XDECREF(exc); return value; } - PyErr_SetString(PyExc_TypeError, - "wrong type"); + if (exc) { + PyErr_SetRaisedException(exc); + } + else { + PyErr_SetString(PyExc_TypeError, "wrong type"); + } return NULL; } @@ -2347,7 +2342,6 @@ PyTypeObject PyCSimpleType_Type = { static PyObject * converters_from_argtypes(PyObject *ob) { - _Py_IDENTIFIER(from_param); PyObject *converters; Py_ssize_t i; @@ -2427,7 +2421,7 @@ converters_from_argtypes(PyObject *ob) } */ - if (_PyObject_LookupAttrId(tp, &PyId_from_param, &cnv) <= 0) { + if (_PyObject_LookupAttr(tp, &_Py_ID(from_param), &cnv) <= 0) { Py_DECREF(converters); Py_DECREF(ob); if (!PyErr_Occurred()) { @@ -2448,10 +2442,6 @@ make_funcptrtype_dict(StgDictObject *stgdict) { PyObject *ob; PyObject *converters = NULL; - _Py_IDENTIFIER(_flags_); - _Py_IDENTIFIER(_argtypes_); - _Py_IDENTIFIER(_restype_); - _Py_IDENTIFIER(_check_retval_); stgdict->align = _ctypes_get_fielddesc("P")->pffi_type->alignment; stgdict->length = 1; @@ -2460,7 +2450,7 @@ make_funcptrtype_dict(StgDictObject *stgdict) stgdict->getfunc = NULL; stgdict->ffi_type_pointer = ffi_type_pointer; - ob = _PyDict_GetItemIdWithError((PyObject *)stgdict, &PyId__flags_); + ob = PyDict_GetItemWithError((PyObject *)stgdict, &_Py_ID(_flags_)); if (!ob || !PyLong_Check(ob)) { if (!PyErr_Occurred()) { PyErr_SetString(PyExc_TypeError, @@ -2471,29 +2461,27 @@ make_funcptrtype_dict(StgDictObject *stgdict) stgdict->flags = PyLong_AsUnsignedLongMask(ob) | TYPEFLAG_ISPOINTER; /* _argtypes_ is optional... */ - ob = _PyDict_GetItemIdWithError((PyObject *)stgdict, &PyId__argtypes_); + ob = PyDict_GetItemWithError((PyObject *)stgdict, &_Py_ID(_argtypes_)); if (ob) { converters = converters_from_argtypes(ob); if (!converters) return -1; - Py_INCREF(ob); - stgdict->argtypes = ob; + stgdict->argtypes = Py_NewRef(ob); stgdict->converters = converters; } else if (PyErr_Occurred()) { return -1; } - ob = _PyDict_GetItemIdWithError((PyObject *)stgdict, &PyId__restype_); + ob = PyDict_GetItemWithError((PyObject *)stgdict, &_Py_ID(_restype_)); if (ob) { if (ob != Py_None && !PyType_stgdict(ob) && !PyCallable_Check(ob)) { PyErr_SetString(PyExc_TypeError, "_restype_ must be a type, a callable, or None"); return -1; } - Py_INCREF(ob); - stgdict->restype = ob; - if (_PyObject_LookupAttrId(ob, &PyId__check_retval_, + stgdict->restype = Py_NewRef(ob); + if (_PyObject_LookupAttr(ob, &_Py_ID(_check_retval_), &stgdict->checker) < 0) { return -1; @@ -2510,8 +2498,7 @@ make_funcptrtype_dict(StgDictObject *stgdict) "_errcheck_ must be callable"); return -1; } - Py_INCREF(ob); - stgdict->errcheck = ob; + stgdict->errcheck = Py_NewRef(ob); } else if (PyErr_Occurred()) { return -1; @@ -2531,8 +2518,7 @@ PyCFuncPtrType_paramfunc(CDataObject *self) parg->tag = 'P'; parg->pffi_type = &ffi_type_pointer; - Py_INCREF(self); - parg->obj = (PyObject *)self; + parg->obj = Py_NewRef(self); parg->value.p = *(void **)self->b_ptr; return parg; } @@ -2644,8 +2630,7 @@ PyCData_GetContainer(CDataObject *self) if (self->b_objects == NULL) return NULL; } else { - Py_INCREF(Py_None); - self->b_objects = Py_None; + self->b_objects = Py_NewRef(Py_None); } } return self; @@ -2809,8 +2794,7 @@ PyCData_NewGetBuffer(PyObject *myself, Py_buffer *view, int flags) if (view == NULL) return 0; view->buf = self->b_ptr; - view->obj = myself; - Py_INCREF(myself); + view->obj = Py_NewRef(myself); view->len = self->b_size; view->readonly = 0; /* use default format character if not set */ @@ -2897,8 +2881,7 @@ PyCData_setstate(PyObject *myself, PyObject *args) static PyObject * PyCData_from_outparam(PyObject *self, PyObject *args) { - Py_INCREF(self); - return self; + return Py_NewRef(self); } static PyMethodDef PyCData_methods[] = { @@ -3003,8 +2986,7 @@ PyCData_FromBaseObj(PyObject *type, PyObject *base, Py_ssize_t index, char *adr) assert(CDataObject_Check(base)); cmem->b_ptr = adr; cmem->b_needsfree = 0; - Py_INCREF(base); - cmem->b_base = (CDataObject *)base; + cmem->b_base = (CDataObject *)Py_NewRef(base); cmem->b_index = index; } else { /* copy contents of adr */ if (-1 == PyCData_MallocBuffer(cmem, dict)) { @@ -3141,8 +3123,7 @@ _PyCData_set(CDataObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value, if (value == NULL) return NULL; - Py_INCREF(value); - return value; + return Py_NewRef(value); } if (PyCPointerTypeObject_Check(type) @@ -3265,8 +3246,7 @@ static PyObject * PyCFuncPtr_get_errcheck(PyCFuncPtrObject *self, void *Py_UNUSED(ignored)) { if (self->errcheck) { - Py_INCREF(self->errcheck); - return self->errcheck; + return Py_NewRef(self->errcheck); } Py_RETURN_NONE; } @@ -3274,7 +3254,6 @@ PyCFuncPtr_get_errcheck(PyCFuncPtrObject *self, void *Py_UNUSED(ignored)) static int PyCFuncPtr_set_restype(PyCFuncPtrObject *self, PyObject *ob, void *Py_UNUSED(ignored)) { - _Py_IDENTIFIER(_check_retval_); PyObject *checker, *oldchecker; if (ob == NULL) { oldchecker = self->checker; @@ -3288,7 +3267,7 @@ PyCFuncPtr_set_restype(PyCFuncPtrObject *self, PyObject *ob, void *Py_UNUSED(ign "restype must be a type, a callable, or None"); return -1; } - if (_PyObject_LookupAttrId(ob, &PyId__check_retval_, &checker) < 0) { + if (_PyObject_LookupAttr(ob, &_Py_ID(_check_retval_), &checker) < 0) { return -1; } oldchecker = self->checker; @@ -3304,14 +3283,12 @@ PyCFuncPtr_get_restype(PyCFuncPtrObject *self, void *Py_UNUSED(ignored)) { StgDictObject *dict; if (self->restype) { - Py_INCREF(self->restype); - return self->restype; + return Py_NewRef(self->restype); } dict = PyObject_stgdict((PyObject *)self); assert(dict); /* Cannot be NULL for PyCFuncPtrObject instances */ if (dict->restype) { - Py_INCREF(dict->restype); - return dict->restype; + return Py_NewRef(dict->restype); } else { Py_RETURN_NONE; } @@ -3341,14 +3318,12 @@ PyCFuncPtr_get_argtypes(PyCFuncPtrObject *self, void *Py_UNUSED(ignored)) { StgDictObject *dict; if (self->argtypes) { - Py_INCREF(self->argtypes); - return self->argtypes; + return Py_NewRef(self->argtypes); } dict = PyObject_stgdict((PyObject *)self); assert(dict); /* Cannot be NULL for PyCFuncPtrObject instances */ if (dict->argtypes) { - Py_INCREF(dict->argtypes); - return dict->argtypes; + return Py_NewRef(dict->argtypes); } else { Py_RETURN_NONE; } @@ -3617,7 +3592,7 @@ PyCFuncPtr_FromDll(PyTypeObject *type, PyObject *args, PyObject *kwds) return NULL; } #else - address = (PPROC)ctypes_dlsym(handle, name); + address = (PPROC)dlsym(handle, name); if (!address) { #ifdef __CYGWIN__ /* dlerror() isn't very helpful on cygwin */ @@ -3625,7 +3600,7 @@ PyCFuncPtr_FromDll(PyTypeObject *type, PyObject *args, PyObject *kwds) "function '%s' not found", name); #else - PyErr_SetString(PyExc_AttributeError, ctypes_dlerror()); + PyErr_SetString(PyExc_AttributeError, dlerror()); #endif Py_DECREF(ftuple); return NULL; @@ -3642,8 +3617,7 @@ PyCFuncPtr_FromDll(PyTypeObject *type, PyObject *args, PyObject *kwds) return NULL; } - Py_XINCREF(paramflags); - self->paramflags = paramflags; + self->paramflags = Py_XNewRef(paramflags); *(void **)self->b_ptr = address; Py_INCREF(dll); @@ -3653,8 +3627,7 @@ PyCFuncPtr_FromDll(PyTypeObject *type, PyObject *args, PyObject *kwds) return NULL; } - Py_INCREF(self); - self->callable = (PyObject *)self; + self->callable = Py_NewRef(self); return (PyObject *)self; } @@ -3679,8 +3652,7 @@ PyCFuncPtr_FromVtblIndex(PyTypeObject *type, PyObject *args, PyObject *kwds) self = (PyCFuncPtrObject *)GenericPyCData_new(type, args, kwds); self->index = index + 0x1000; - Py_XINCREF(paramflags); - self->paramflags = paramflags; + self->paramflags = Py_XNewRef(paramflags); if (iid_len == sizeof(GUID)) self->iid = iid; return (PyObject *)self; @@ -3778,8 +3750,7 @@ PyCFuncPtr_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return NULL; } - Py_INCREF(callable); - self->callable = callable; + self->callable = Py_NewRef(callable); self->thunk = thunk; *(void **)self->b_ptr = (void *)thunk->pcl_exec; @@ -3827,23 +3798,20 @@ _get_arg(int *pindex, PyObject *name, PyObject *defval, PyObject *inargs, PyObje if (*pindex < PyTuple_GET_SIZE(inargs)) { v = PyTuple_GET_ITEM(inargs, *pindex); ++*pindex; - Py_INCREF(v); - return v; + return Py_NewRef(v); } if (kwds && name) { v = PyDict_GetItemWithError(kwds, name); if (v) { ++*pindex; - Py_INCREF(v); - return v; + return Py_NewRef(v); } else if (PyErr_Occurred()) { return NULL; } } if (defval) { - Py_INCREF(defval); - return defval; + return Py_NewRef(defval); } /* we can't currently emit a better error message */ if (name) @@ -3898,8 +3866,7 @@ _build_callargs(PyCFuncPtrObject *self, PyObject *argtypes, if (self->index) return PyTuple_GetSlice(inargs, 1, PyTuple_GET_SIZE(inargs)); #endif - Py_INCREF(inargs); - return inargs; + return Py_NewRef(inargs); } len = PyTuple_GET_SIZE(argtypes); @@ -4082,10 +4049,9 @@ _build_result(PyObject *result, PyObject *callargs, PyTuple_SET_ITEM(tup, index, v); index++; } else if (bit & outmask) { - _Py_IDENTIFIER(__ctypes_from_outparam__); v = PyTuple_GET_ITEM(callargs, i); - v = _PyObject_CallMethodIdNoArgs(v, &PyId___ctypes_from_outparam__); + v = PyObject_CallMethodNoArgs(v, &_Py_ID(__ctypes_from_outparam__)); if (v == NULL || numretvals == 1) { Py_DECREF(callargs); return v; @@ -4368,7 +4334,6 @@ _init_pos_args(PyObject *self, PyTypeObject *type, StgDictObject *dict; PyObject *fields; Py_ssize_t i; - _Py_IDENTIFIER(_fields_); if (PyType_stgdict((PyObject *)type->tp_base)) { index = _init_pos_args(self, type->tp_base, @@ -4379,7 +4344,7 @@ _init_pos_args(PyObject *self, PyTypeObject *type, } dict = PyType_stgdict((PyObject *)type); - fields = _PyDict_GetItemIdWithError((PyObject *)dict, &PyId__fields_); + fields = PyDict_GetItemWithError((PyObject *)dict, &_Py_ID(_fields_)); if (fields == NULL) { if (PyErr_Occurred()) { return -1; @@ -4988,8 +4953,7 @@ static PyObject * Simple_from_outparm(PyObject *self, PyObject *args) { if (_ctypes_simple_instance((PyObject *)Py_TYPE(self))) { - Py_INCREF(self); - return self; + return Py_NewRef(self); } /* call stgdict->getfunc */ return Simple_get_value((CDataObject *)self, NULL); @@ -5512,46 +5476,46 @@ comerror_init(PyObject *self, PyObject *args, PyObject *kwds) return 0; } -static PyTypeObject PyComError_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_ctypes.COMError", /* tp_name */ - sizeof(PyBaseExceptionObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - 0, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 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 */ - PyDoc_STR(comerror_doc), /* 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)comerror_init, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ +static int +comerror_clear(PyObject *self) +{ + return ((PyTypeObject *)PyExc_BaseException)->tp_clear(self); +} + +static int +comerror_traverse(PyObject *self, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(self)); + return ((PyTypeObject *)PyExc_BaseException)->tp_traverse(self, visit, arg); +} + +static void +comerror_dealloc(PyObject *self) +{ + PyTypeObject *tp = Py_TYPE(self); + PyObject_GC_UnTrack(self); + (void)comerror_clear(self); + tp->tp_free(self); + Py_DECREF(tp); +} + +static PyType_Slot comerror_slots[] = { + {Py_tp_doc, (void *)PyDoc_STR(comerror_doc)}, + {Py_tp_init, comerror_init}, + {Py_tp_traverse, comerror_traverse}, + {Py_tp_dealloc, comerror_dealloc}, + {Py_tp_clear, comerror_clear}, + {0, NULL}, }; + +static PyType_Spec comerror_spec = { + .name = "_ctypes.COMError", + .basicsize = sizeof(PyBaseExceptionObject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE), + .slots = comerror_slots, +}; + #endif // MS_WIN32 static PyObject * @@ -5623,8 +5587,7 @@ cast(void *ptr, PyObject *src, PyObject *ctype) if (obj->b_objects == NULL) goto failed; } - Py_XINCREF(obj->b_objects); - result->b_objects = obj->b_objects; + result->b_objects = Py_XNewRef(obj->b_objects); if (result->b_objects && PyDict_CheckExact(result->b_objects)) { PyObject *index; int rc; @@ -5694,12 +5657,23 @@ _ctypes_add_types(PyObject *mod) } \ } while (0) +#define CREATE_TYPE(MOD, TP, SPEC, BASE) do { \ + PyObject *type = PyType_FromMetaclass(NULL, MOD, SPEC, \ + (PyObject *)BASE); \ + if (type == NULL) { \ + return -1; \ + } \ + TP = (PyTypeObject *)type; \ +} while (0) + + ctypes_state *st = GLOBAL_STATE(); + /* Note: ob_type is the metatype (the 'type'), defaults to PyType_Type, tp_base is the base type, defaults to 'object' aka PyBaseObject_Type. */ - TYPE_READY(&PyCArg_Type); - TYPE_READY(&PyCThunk_Type); + CREATE_TYPE(mod, st->PyCArg_Type, &carg_spec, NULL); + CREATE_TYPE(mod, st->PyCThunk_Type, &cthunk_spec, NULL); TYPE_READY(&PyCData_Type); /* StgDict is derived from PyDict_Type */ TYPE_READY_BASE(&PyCStgDict_Type, &PyDict_Type); @@ -5732,25 +5706,24 @@ _ctypes_add_types(PyObject *mod) * Simple classes */ - /* PyCField_Type is derived from PyBaseObject_Type */ - TYPE_READY(&PyCField_Type); + CREATE_TYPE(mod, st->PyCField_Type, &cfield_spec, NULL); /************************************************* * * Other stuff */ - DictRemover_Type.tp_new = PyType_GenericNew; - TYPE_READY(&DictRemover_Type); - TYPE_READY(&StructParam_Type); + CREATE_TYPE(mod, st->DictRemover_Type, &dictremover_spec, NULL); + CREATE_TYPE(mod, st->StructParam_Type, &structparam_spec, NULL); #ifdef MS_WIN32 - TYPE_READY_BASE(&PyComError_Type, (PyTypeObject*)PyExc_Exception); + CREATE_TYPE(mod, st->PyComError_Type, &comerror_spec, PyExc_Exception); #endif #undef TYPE_READY #undef TYPE_READY_BASE #undef MOD_ADD_TYPE +#undef CREATE_TYPE return 0; } @@ -5774,7 +5747,8 @@ _ctypes_add_objects(PyObject *mod) MOD_ADD("_pointer_type_cache", Py_NewRef(_ctypes_ptrtype_cache)); #ifdef MS_WIN32 - MOD_ADD("COMError", Py_NewRef(ComError)); + ctypes_state *st = GLOBAL_STATE(); + MOD_ADD("COMError", Py_NewRef(st->PyComError_Type)); MOD_ADD("FUNCFLAG_HRESULT", PyLong_FromLong(FUNCFLAG_HRESULT)); MOD_ADD("FUNCFLAG_STDCALL", PyLong_FromLong(FUNCFLAG_STDCALL)); #endif @@ -5804,6 +5778,7 @@ _ctypes_add_objects(PyObject *mod) MOD_ADD("RTLD_GLOBAL", PyLong_FromLong(RTLD_GLOBAL)); MOD_ADD("CTYPES_MAX_ARGCOUNT", PyLong_FromLong(CTYPES_MAX_ARGCOUNT)); MOD_ADD("ArgumentError", Py_NewRef(PyExc_ArgError)); + MOD_ADD("SIZEOF_TIME_T", PyLong_FromSsize_t(SIZEOF_TIME_T)); return 0; #undef MOD_ADD } @@ -5830,9 +5805,6 @@ _ctypes_mod_exec(PyObject *mod) if (_ctypes_add_types(mod) < 0) { return -1; } -#ifdef MS_WIN32 - ComError = (PyObject*)&PyComError_Type; -#endif if (_ctypes_add_objects(mod) < 0) { return -1; diff --git a/Modules/_ctypes/_ctypes_test.c b/Modules/_ctypes/_ctypes_test.c index 8a6a1167..ddfb2c8a 100644 --- a/Modules/_ctypes/_ctypes_test.c +++ b/Modules/_ctypes/_ctypes_test.c @@ -1034,6 +1034,19 @@ EXPORT (HRESULT) KeepObject(IUnknown *punk) #endif +#ifdef MS_WIN32 + +// i38748: c stub for testing stack corruption +// When executing a Python callback with a long and a long long + +typedef long(__stdcall *_test_i38748_funcType)(long, long long); + +EXPORT(long) _test_i38748_runCallback(_test_i38748_funcType callback, int a, int b) { + return callback(a, b); +} + +#endif + EXPORT(int) _testfunc_pylist_append(PyObject *list, PyObject *item) { @@ -1041,6 +1054,7 @@ _testfunc_pylist_append(PyObject *list, PyObject *item) } static struct PyModuleDef_Slot _ctypes_test_slots[] = { + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; diff --git a/Modules/_ctypes/callbacks.c b/Modules/_ctypes/callbacks.c index b46067bf..d71297f9 100644 --- a/Modules/_ctypes/callbacks.c +++ b/Modules/_ctypes/callbacks.c @@ -1,7 +1,6 @@ #ifndef Py_BUILD_CORE_BUILTIN # define Py_BUILD_CORE_MODULE 1 #endif -#define NEEDS_PY_IDENTIFIER #include "Python.h" // windows.h must be included before pycore internal headers @@ -9,7 +8,9 @@ # include <windows.h> #endif -#include "pycore_call.h" // _PyObject_CallNoArgs() +#include "pycore_call.h" // _PyObject_CallNoArgs() +#include "pycore_runtime.h" // _PyRuntime +#include "pycore_global_objects.h" // _Py_ID() #include <stdbool.h> @@ -27,23 +28,11 @@ /**************************************************************/ -static void -CThunkObject_dealloc(PyObject *myself) -{ - CThunkObject *self = (CThunkObject *)myself; - PyObject_GC_UnTrack(self); - Py_XDECREF(self->converters); - Py_XDECREF(self->callable); - Py_XDECREF(self->restype); - if (self->pcl_write) - Py_ffi_closure_free(self->pcl_write); - PyObject_GC_Del(self); -} - static int CThunkObject_traverse(PyObject *myself, visitproc visit, void *arg) { CThunkObject *self = (CThunkObject *)myself; + Py_VISIT(Py_TYPE(self)); Py_VISIT(self->converters); Py_VISIT(self->callable); Py_VISIT(self->restype); @@ -60,36 +49,35 @@ CThunkObject_clear(PyObject *myself) return 0; } -PyTypeObject PyCThunk_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_ctypes.CThunkObject", - sizeof(CThunkObject), /* tp_basicsize */ - sizeof(ffi_type), /* tp_itemsize */ - CThunkObject_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 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_HAVE_GC, /* tp_flags */ - PyDoc_STR("CThunkObject"), /* tp_doc */ - CThunkObject_traverse, /* tp_traverse */ - CThunkObject_clear, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - 0, /* tp_members */ +static void +CThunkObject_dealloc(PyObject *myself) +{ + CThunkObject *self = (CThunkObject *)myself; + PyTypeObject *tp = Py_TYPE(myself); + PyObject_GC_UnTrack(self); + (void)CThunkObject_clear(myself); + if (self->pcl_write) { + Py_ffi_closure_free(self->pcl_write); + } + PyObject_GC_Del(self); + Py_DECREF(tp); +} + +static PyType_Slot cthunk_slots[] = { + {Py_tp_doc, (void *)PyDoc_STR("CThunkObject")}, + {Py_tp_dealloc, CThunkObject_dealloc}, + {Py_tp_traverse, CThunkObject_traverse}, + {Py_tp_clear, CThunkObject_clear}, + {0, NULL}, +}; + +PyType_Spec cthunk_spec = { + .name = "_ctypes.CThunkObject", + .basicsize = sizeof(CThunkObject), + .itemsize = sizeof(ffi_type), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_DISALLOW_INSTANTIATION), + .slots = cthunk_slots, }; /**************************************************************/ @@ -125,9 +113,7 @@ static void TryAddRef(StgDictObject *dict, CDataObject *obj) { IUnknown *punk; - _Py_IDENTIFIER(_needs_com_addref_); - - int r = _PyDict_ContainsId((PyObject *)dict, &PyId__needs_com_addref_); + int r = PyDict_Contains((PyObject *)dict, &_Py_ID(_needs_com_addref_)); if (r <= 0) { if (r < 0) { PrintError("getting _needs_com_addref_"); @@ -321,7 +307,8 @@ static CThunkObject* CThunkObject_new(Py_ssize_t nargs) CThunkObject *p; Py_ssize_t i; - p = PyObject_GC_NewVar(CThunkObject, &PyCThunk_Type, nargs); + ctypes_state *st = GLOBAL_STATE(); + p = PyObject_GC_NewVar(CThunkObject, st->PyCThunk_Type, nargs); if (p == NULL) { return NULL; } @@ -358,7 +345,10 @@ CThunkObject *_ctypes_alloc_callback(PyObject *callable, if (p == NULL) return NULL; - assert(CThunk_CheckExact((PyObject *)p)); +#ifdef Py_DEBUG + ctypes_state *st = GLOBAL_STATE(); + assert(CThunk_CheckExact(st, (PyObject *)p)); +#endif p->pcl_write = Py_ffi_closure_alloc(sizeof(ffi_closure), &p->pcl_exec); if (p->pcl_write == NULL) { @@ -374,8 +364,7 @@ CThunkObject *_ctypes_alloc_callback(PyObject *callable, } p->atypes[i] = NULL; - Py_INCREF(restype); - p->restype = restype; + p->restype = Py_NewRef(restype); if (restype == Py_None) { p->setfunc = NULL; p->ffi_restype = &ffi_type_void; @@ -427,7 +416,7 @@ CThunkObject *_ctypes_alloc_callback(PyObject *callable, PyErr_Format(PyExc_NotImplementedError, "ffi_prep_closure_loc() is missing"); goto error; #else -#if defined(__clang__) || defined(MACOSX) +#if defined(__clang__) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" #endif @@ -437,7 +426,7 @@ CThunkObject *_ctypes_alloc_callback(PyObject *callable, #endif result = ffi_prep_closure(p->pcl_write, &p->cif, closure_fcn, p); -#if defined(__clang__) || defined(MACOSX) +#if defined(__clang__) #pragma clang diagnostic pop #endif #if defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5))) @@ -452,10 +441,8 @@ CThunkObject *_ctypes_alloc_callback(PyObject *callable, goto error; } - Py_INCREF(converters); - p->converters = converters; - Py_INCREF(callable); - p->callable = callable; + p->converters = Py_NewRef(converters); + p->callable = Py_NewRef(callable); return p; error: @@ -476,35 +463,38 @@ static void LoadPython(void) long Call_GetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) { - PyObject *mod, *func, *result; + PyObject *func, *result; long retval; static PyObject *context; if (context == NULL) context = PyUnicode_InternFromString("_ctypes.DllGetClassObject"); - mod = PyImport_ImportModule("ctypes"); - if (!mod) { - PyErr_WriteUnraisable(context ? context : Py_None); - /* There has been a warning before about this already */ - return E_FAIL; - } - - func = PyObject_GetAttrString(mod, "DllGetClassObject"); - Py_DECREF(mod); + func = _PyImport_GetModuleAttrString("ctypes", "DllGetClassObject"); if (!func) { PyErr_WriteUnraisable(context ? context : Py_None); + /* There has been a warning before about this already */ return E_FAIL; } { PyObject *py_rclsid = PyLong_FromVoidPtr((void *)rclsid); + if (py_rclsid == NULL) { + Py_DECREF(func); + PyErr_WriteUnraisable(context ? context : Py_None); + return E_FAIL; + } PyObject *py_riid = PyLong_FromVoidPtr((void *)riid); + if (py_riid == NULL) { + Py_DECREF(func); + Py_DECREF(py_rclsid); + PyErr_WriteUnraisable(context ? context : Py_None); + return E_FAIL; + } PyObject *py_ppv = PyLong_FromVoidPtr(ppv); - if (!py_rclsid || !py_riid || !py_ppv) { - Py_XDECREF(py_rclsid); - Py_XDECREF(py_riid); - Py_XDECREF(py_ppv); + if (py_ppv == NULL) { + Py_DECREF(py_rclsid); + Py_DECREF(py_riid); Py_DECREF(func); PyErr_WriteUnraisable(context ? context : Py_None); return E_FAIL; diff --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c index f42ff08f..d2fe525d 100644 --- a/Modules/_ctypes/callproc.c +++ b/Modules/_ctypes/callproc.c @@ -54,7 +54,9 @@ */ -#define NEEDS_PY_IDENTIFIER +#ifndef Py_BUILD_CORE_BUILTIN +# define Py_BUILD_CORE_MODULE 1 +#endif #include "Python.h" #include "structmember.h" // PyMemberDef @@ -65,7 +67,7 @@ #include <windows.h> #include <tchar.h> #else -#include "ctypes_dlfcn.h" +#include <dlfcn.h> #endif #ifdef __APPLE__ @@ -94,6 +96,9 @@ #define DONT_USE_SEH #endif +#include "pycore_runtime.h" // _PyRuntime +#include "pycore_global_objects.h" // _Py_ID() + #define CTYPES_CAPSULE_NAME_PYMEM "_ctypes pymem" @@ -281,7 +286,7 @@ static WCHAR *FormatError(DWORD code) #ifndef DONT_USE_SEH static void SetException(DWORD code, EXCEPTION_RECORD *pr) { - if (PySys_Audit("ctypes.seh_exception", "I", code) < 0) { + if (PySys_Audit("ctypes.set_exception", "I", code) < 0) { /* An exception was set by the audit hook */ return; } @@ -464,21 +469,41 @@ PyCArgObject * PyCArgObject_new(void) { PyCArgObject *p; - p = PyObject_New(PyCArgObject, &PyCArg_Type); + ctypes_state *st = GLOBAL_STATE(); + p = PyObject_GC_New(PyCArgObject, st->PyCArg_Type); if (p == NULL) return NULL; p->pffi_type = NULL; p->tag = '\0'; p->obj = NULL; memset(&p->value, 0, sizeof(p->value)); + PyObject_GC_Track(p); return p; } +static int +PyCArg_traverse(PyCArgObject *self, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(self)); + Py_VISIT(self->obj); + return 0; +} + +static int +PyCArg_clear(PyCArgObject *self) +{ + Py_CLEAR(self->obj); + return 0; +} + static void PyCArg_dealloc(PyCArgObject *self) { - Py_XDECREF(self->obj); - PyObject_Free(self); + PyTypeObject *tp = Py_TYPE(self); + PyObject_GC_UnTrack(self); + (void)PyCArg_clear(self); + tp->tp_free((PyObject *)self); + Py_DECREF(tp); } static int @@ -562,36 +587,21 @@ static PyMemberDef PyCArgType_members[] = { { NULL }, }; -PyTypeObject PyCArg_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "CArgObject", - sizeof(PyCArgObject), - 0, - (destructor)PyCArg_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - (reprfunc)PyCArg_repr, /* 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, /* tp_flags */ - 0, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - PyCArgType_members, /* tp_members */ +static PyType_Slot carg_slots[] = { + {Py_tp_dealloc, PyCArg_dealloc}, + {Py_tp_traverse, PyCArg_traverse}, + {Py_tp_clear, PyCArg_clear}, + {Py_tp_repr, PyCArg_repr}, + {Py_tp_members, PyCArgType_members}, + {0, NULL}, +}; + +PyType_Spec carg_spec = { + .name = "_ctypes.CArgObject", + .basicsize = sizeof(PyCArgObject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_DISALLOW_INSTANTIATION), + .slots = carg_slots, }; /****************************************************************/ @@ -664,11 +674,11 @@ static int ConvParam(PyObject *obj, Py_ssize_t index, struct argument *pa) return 0; } - if (PyCArg_CheckExact(obj)) { + ctypes_state *st = GLOBAL_STATE(); + if (PyCArg_CheckExact(st, obj)) { PyCArgObject *carg = (PyCArgObject *)obj; pa->ffi_type = carg->pffi_type; - Py_INCREF(obj); - pa->keep = obj; + pa->keep = Py_NewRef(obj); memcpy(&pa->value, &carg->value, sizeof(pa->value)); return 0; } @@ -698,8 +708,7 @@ static int ConvParam(PyObject *obj, Py_ssize_t index, struct argument *pa) if (PyBytes_Check(obj)) { pa->ffi_type = &ffi_type_pointer; pa->value.p = PyBytes_AsString(obj); - Py_INCREF(obj); - pa->keep = obj; + pa->keep = Py_NewRef(obj); return 0; } @@ -717,9 +726,8 @@ static int ConvParam(PyObject *obj, Py_ssize_t index, struct argument *pa) } { - _Py_IDENTIFIER(_as_parameter_); PyObject *arg; - if (_PyObject_LookupAttrId(obj, &PyId__as_parameter_, &arg) < 0) { + if (_PyObject_LookupAttr(obj, &_Py_ID(_as_parameter_), &arg) < 0) { return -1; } /* Which types should we exactly allow here? @@ -1011,41 +1019,43 @@ static PyObject *GetResult(PyObject *restype, void *result, PyObject *checker) void _ctypes_extend_error(PyObject *exc_class, const char *fmt, ...) { va_list vargs; - PyObject *tp, *v, *tb, *s, *cls_str, *msg_str; va_start(vargs, fmt); - s = PyUnicode_FromFormatV(fmt, vargs); + PyObject *s = PyUnicode_FromFormatV(fmt, vargs); va_end(vargs); - if (!s) + if (s == NULL) { return; + } - PyErr_Fetch(&tp, &v, &tb); - PyErr_NormalizeException(&tp, &v, &tb); - if (PyType_Check(tp)) - cls_str = PyType_GetName((PyTypeObject *)tp); - else - cls_str = PyObject_Str(tp); + assert(PyErr_Occurred()); + PyObject *exc = PyErr_GetRaisedException(); + assert(exc != NULL); + PyObject *cls_str = PyType_GetName(Py_TYPE(exc)); if (cls_str) { PyUnicode_AppendAndDel(&s, cls_str); PyUnicode_AppendAndDel(&s, PyUnicode_FromString(": ")); - if (s == NULL) + if (s == NULL) { goto error; - } else + } + } + else { PyErr_Clear(); - msg_str = PyObject_Str(v); - if (msg_str) + } + + PyObject *msg_str = PyObject_Str(exc); + if (msg_str) { PyUnicode_AppendAndDel(&s, msg_str); + } else { PyErr_Clear(); PyUnicode_AppendAndDel(&s, PyUnicode_FromString("???")); } - if (s == NULL) + if (s == NULL) { goto error; + } PyErr_SetObject(exc_class, s); error: - Py_XDECREF(tp); - Py_XDECREF(v); - Py_XDECREF(tb); + Py_XDECREF(exc); Py_XDECREF(s); } @@ -1105,7 +1115,8 @@ GetComError(HRESULT errcode, GUID *riid, IUnknown *pIunk) descr, source, helpfile, helpcontext, progid); if (obj) { - PyErr_SetObject(ComError, obj); + ctypes_state *st = GLOBAL_STATE(); + PyErr_SetObject((PyObject *)st->PyComError_Type, obj); Py_DECREF(obj); } LocalFree(text); @@ -1535,10 +1546,10 @@ static PyObject *py_dl_open(PyObject *self, PyObject *args) if (PySys_Audit("ctypes.dlopen", "O", name) < 0) { return NULL; } - handle = ctypes_dlopen(name_str, mode); + handle = dlopen(name_str, mode); Py_XDECREF(name2); if (!handle) { - const char *errmsg = ctypes_dlerror(); + const char *errmsg = dlerror(); if (!errmsg) errmsg = "dlopen() error"; PyErr_SetString(PyExc_OSError, @@ -1556,7 +1567,7 @@ static PyObject *py_dl_close(PyObject *self, PyObject *args) return NULL; if (dlclose(handle)) { PyErr_SetString(PyExc_OSError, - ctypes_dlerror()); + dlerror()); return NULL; } Py_RETURN_NONE; @@ -1574,10 +1585,10 @@ static PyObject *py_dl_sym(PyObject *self, PyObject *args) if (PySys_Audit("ctypes.dlsym/handle", "O", args) < 0) { return NULL; } - ptr = ctypes_dlsym((void*)handle, name); + ptr = dlsym((void*)handle, name); if (!ptr) { PyErr_SetString(PyExc_OSError, - ctypes_dlerror()); + dlerror()); return NULL; } return PyLong_FromVoidPtr(ptr); @@ -1739,8 +1750,7 @@ byref(PyObject *self, PyObject *args) parg->tag = 'P'; parg->pffi_type = &ffi_type_pointer; - Py_INCREF(obj); - parg->obj = obj; + parg->obj = Py_NewRef(obj); parg->value.p = (char *)((CDataObject *)obj)->b_ptr + offset; return (PyObject *)parg; } @@ -1780,8 +1790,7 @@ My_PyObj_FromPtr(PyObject *self, PyObject *args) if (PySys_Audit("ctypes.PyObj_FromPtr", "(O)", ob) < 0) { return NULL; } - Py_INCREF(ob); - return ob; + return Py_NewRef(ob); } static PyObject * @@ -1815,7 +1824,7 @@ resize(PyObject *self, PyObject *args) dict = PyObject_stgdict((PyObject *)obj); if (dict == NULL) { PyErr_SetString(PyExc_TypeError, - "excepted ctypes instance"); + "expected ctypes instance"); return NULL; } if (size < dict->size) { @@ -1858,16 +1867,14 @@ static PyObject * unpickle(PyObject *self, PyObject *args) { PyObject *typ, *state, *meth, *obj, *result; - _Py_IDENTIFIER(__new__); - _Py_IDENTIFIER(__setstate__); if (!PyArg_ParseTuple(args, "OO!", &typ, &PyTuple_Type, &state)) return NULL; - obj = _PyObject_CallMethodIdOneArg(typ, &PyId___new__, typ); + obj = PyObject_CallMethodOneArg(typ, &_Py_ID(__new__), typ); if (obj == NULL) return NULL; - meth = _PyObject_GetAttrId(obj, &PyId___setstate__); + meth = PyObject_GetAttr(obj, &_Py_ID(__setstate__)); if (meth == NULL) { goto error; } @@ -1892,29 +1899,20 @@ POINTER(PyObject *self, PyObject *cls) PyObject *result; PyTypeObject *typ; PyObject *key; - char *buf; result = PyDict_GetItemWithError(_ctypes_ptrtype_cache, cls); if (result) { - Py_INCREF(result); - return result; + return Py_NewRef(result); } else if (PyErr_Occurred()) { return NULL; } if (PyUnicode_CheckExact(cls)) { - const char *name = PyUnicode_AsUTF8(cls); - if (name == NULL) - return NULL; - buf = PyMem_Malloc(strlen(name) + 3 + 1); - if (buf == NULL) - return PyErr_NoMemory(); - sprintf(buf, "LP_%s", name); + PyObject *name = PyUnicode_FromFormat("LP_%U", cls); result = PyObject_CallFunction((PyObject *)Py_TYPE(&PyCPointer_Type), - "s(O){}", - buf, + "N(O){}", + name, &PyCPointer_Type); - PyMem_Free(buf); if (result == NULL) return result; key = PyLong_FromVoidPtr(result); @@ -1924,20 +1922,15 @@ POINTER(PyObject *self, PyObject *cls) } } else if (PyType_Check(cls)) { typ = (PyTypeObject *)cls; - buf = PyMem_Malloc(strlen(typ->tp_name) + 3 + 1); - if (buf == NULL) - return PyErr_NoMemory(); - sprintf(buf, "LP_%s", typ->tp_name); + PyObject *name = PyUnicode_FromFormat("LP_%s", typ->tp_name); result = PyObject_CallFunction((PyObject *)Py_TYPE(&PyCPointer_Type), - "s(O){sO}", - buf, + "N(O){sO}", + name, &PyCPointer_Type, "_type_", cls); - PyMem_Free(buf); if (result == NULL) return result; - Py_INCREF(cls); - key = cls; + key = Py_NewRef(cls); } else { PyErr_SetString(PyExc_TypeError, "must be a ctypes type"); return NULL; diff --git a/Modules/_ctypes/cfield.c b/Modules/_ctypes/cfield.c index 9bdf1db8..128506a9 100644 --- a/Modules/_ctypes/cfield.c +++ b/Modules/_ctypes/cfield.c @@ -61,7 +61,9 @@ PyCField_FromDesc(PyObject *desc, Py_ssize_t index, #define CONT_BITFIELD 2 #define EXPAND_BITFIELD 3 - self = (CFieldObject *)PyCField_Type.tp_alloc((PyTypeObject *)&PyCField_Type, 0); + ctypes_state *st = GLOBAL_STATE(); + PyTypeObject *tp = st->PyCField_Type; + self = (CFieldObject *)tp->tp_alloc(tp, 0); if (self == NULL) return NULL; dict = PyType_stgdict(desc); @@ -137,8 +139,7 @@ PyCField_FromDesc(PyObject *desc, Py_ssize_t index, self->getfunc = getfunc; self->index = index; - Py_INCREF(proto); - self->proto = proto; + self->proto = Py_NewRef(proto); switch (fieldtype) { case NEW_BITFIELD: @@ -224,8 +225,7 @@ PyCField_get(CFieldObject *self, PyObject *inst, PyTypeObject *type) { CDataObject *src; if (inst == NULL) { - Py_INCREF(self); - return (PyObject *)self; + return Py_NewRef(self); } if (!CDataObject_Check(inst)) { PyErr_SetString(PyExc_TypeError, @@ -258,6 +258,7 @@ static PyGetSetDef PyCField_getset[] = { static int PyCField_traverse(CFieldObject *self, visitproc visit, void *arg) { + Py_VISIT(Py_TYPE(self)); Py_VISIT(self->proto); return 0; } @@ -272,9 +273,11 @@ PyCField_clear(CFieldObject *self) static void PyCField_dealloc(PyObject *self) { + PyTypeObject *tp = Py_TYPE(self); PyObject_GC_UnTrack(self); - PyCField_clear((CFieldObject *)self); + (void)PyCField_clear((CFieldObject *)self); Py_TYPE(self)->tp_free((PyObject *)self); + Py_DECREF(tp); } static PyObject * @@ -298,46 +301,24 @@ PyCField_repr(CFieldObject *self) return result; } -PyTypeObject PyCField_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_ctypes.CField", /* tp_name */ - sizeof(CFieldObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - PyCField_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - (reprfunc)PyCField_repr, /* 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_HAVE_GC, /* tp_flags */ - PyDoc_STR("Structure/Union member"), /* tp_doc */ - (traverseproc)PyCField_traverse, /* tp_traverse */ - (inquiry)PyCField_clear, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - 0, /* tp_members */ - PyCField_getset, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - (descrgetfunc)PyCField_get, /* tp_descr_get */ - (descrsetfunc)PyCField_set, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ - 0, /* tp_free */ +static PyType_Slot cfield_slots[] = { + {Py_tp_dealloc, PyCField_dealloc}, + {Py_tp_repr, PyCField_repr}, + {Py_tp_doc, (void *)PyDoc_STR("Structure/Union member")}, + {Py_tp_traverse, PyCField_traverse}, + {Py_tp_clear, PyCField_clear}, + {Py_tp_getset, PyCField_getset}, + {Py_tp_descr_get, PyCField_get}, + {Py_tp_descr_set, PyCField_set}, + {0, NULL}, +}; + +PyType_Spec cfield_spec = { + .name = "_ctypes.CField", + .basicsize = sizeof(CFieldObject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_DISALLOW_INSTANTIATION), + .slots = cfield_slots, }; @@ -1090,8 +1071,7 @@ O_get(void *ptr, Py_ssize_t size) "PyObject is NULL"); return NULL; } - Py_INCREF(ob); - return ob; + return Py_NewRef(ob); } static PyObject * @@ -1099,8 +1079,7 @@ O_set(void *ptr, PyObject *value, Py_ssize_t size) { /* Hm, does the memory block need it's own refcount or not? */ *(PyObject **)ptr = value; - Py_INCREF(value); - return value; + return Py_NewRef(value); } @@ -1226,8 +1205,7 @@ U_set(void *ptr, PyObject *value, Py_ssize_t length) return NULL; } - Py_INCREF(value); - return value; + return Py_NewRef(value); } @@ -1285,13 +1263,11 @@ z_set(void *ptr, PyObject *value, Py_ssize_t size) { if (value == Py_None) { *(char **)ptr = NULL; - Py_INCREF(value); - return value; + return Py_NewRef(value); } if (PyBytes_Check(value)) { *(const char **)ptr = PyBytes_AsString(value); - Py_INCREF(value); - return value; + return Py_NewRef(value); } else if (PyLong_Check(value)) { #if SIZEOF_VOID_P == SIZEOF_LONG_LONG *(char **)ptr = (char *)PyLong_AsUnsignedLongLongMask(value); @@ -1327,8 +1303,7 @@ Z_set(void *ptr, PyObject *value, Py_ssize_t size) if (value == Py_None) { *(wchar_t **)ptr = NULL; - Py_INCREF(value); - return value; + return Py_NewRef(value); } if (PyLong_Check(value)) { #if SIZEOF_VOID_P == SIZEOF_LONG_LONG diff --git a/Modules/_ctypes/ctypes.h b/Modules/_ctypes/ctypes.h index a7029b6e..8891a0a7 100644 --- a/Modules/_ctypes/ctypes.h +++ b/Modules/_ctypes/ctypes.h @@ -32,6 +32,25 @@ #endif #endif +typedef struct { + PyTypeObject *DictRemover_Type; + PyTypeObject *PyCArg_Type; + PyTypeObject *PyCField_Type; + PyTypeObject *PyCThunk_Type; +#ifdef MS_WIN32 + PyTypeObject *PyComError_Type; +#endif + PyTypeObject *StructParam_Type; +} ctypes_state; + +extern ctypes_state global_state; + +#define GLOBAL_STATE() (&global_state) + +extern PyType_Spec carg_spec; +extern PyType_Spec cfield_spec; +extern PyType_Spec cthunk_spec; + typedef struct tagPyCArgObject PyCArgObject; typedef struct tagCDataObject CDataObject; typedef PyObject *(* GETFUNC)(void *, Py_ssize_t size); @@ -88,8 +107,7 @@ typedef struct { ffi_type *ffi_restype; ffi_type *atypes[1]; } CThunkObject; -extern PyTypeObject PyCThunk_Type; -#define CThunk_CheckExact(v) Py_IS_TYPE(v, &PyCThunk_Type) +#define CThunk_CheckExact(st, v) Py_IS_TYPE(v, st->PyCThunk_Type) typedef struct { /* First part identical to tagCDataObject */ @@ -141,7 +159,6 @@ extern PyTypeObject PyCSimpleType_Type; #define PyCSimpleTypeObject_CheckExact(v) Py_IS_TYPE(v, &PyCSimpleType_Type) #define PyCSimpleTypeObject_Check(v) PyObject_TypeCheck(v, &PyCSimpleType_Type) -extern PyTypeObject PyCField_Type; extern struct fielddesc *_ctypes_get_fielddesc(const char *fmt); @@ -334,8 +351,7 @@ struct tagPyCArgObject { Py_ssize_t size; /* for the 'V' tag */ }; -extern PyTypeObject PyCArg_Type; -#define PyCArg_CheckExact(v) Py_IS_TYPE(v, &PyCArg_Type) +#define PyCArg_CheckExact(st, v) Py_IS_TYPE(v, st->PyCArg_Type) extern PyCArgObject *PyCArgObject_new(void); extern PyObject * @@ -379,10 +395,6 @@ extern int _ctypes_simple_instance(PyObject *obj); extern PyObject *_ctypes_ptrtype_cache; PyObject *_ctypes_get_errobj(int **pspace); -#ifdef MS_WIN32 -extern PyObject *ComError; -#endif - #ifdef USING_MALLOC_CLOSURE_DOT_C void Py_ffi_closure_free(void *p); void *Py_ffi_closure_alloc(size_t size, void** codeloc); diff --git a/Modules/_ctypes/ctypes_dlfcn.h b/Modules/_ctypes/ctypes_dlfcn.h deleted file mode 100644 index 54cdde9a..00000000 --- a/Modules/_ctypes/ctypes_dlfcn.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef _CTYPES_DLFCN_H_ -#define _CTYPES_DLFCN_H_ - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -#ifndef MS_WIN32 - -#include <dlfcn.h> - -#ifndef CTYPES_DARWIN_DLFCN - -#define ctypes_dlsym dlsym -#define ctypes_dlerror dlerror -#define ctypes_dlopen dlopen -#define ctypes_dlclose dlclose -#define ctypes_dladdr dladdr - -#endif /* !CTYPES_DARWIN_DLFCN */ - -#endif /* !MS_WIN32 */ - -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif /* _CTYPES_DLFCN_H_ */ diff --git a/Modules/_ctypes/darwin/LICENSE b/Modules/_ctypes/darwin/LICENSE deleted file mode 100644 index 786fb502..00000000 --- a/Modules/_ctypes/darwin/LICENSE +++ /dev/null @@ -1,31 +0,0 @@ -Copyright (c) 2002 Jorge Acereda <jacereda@users.sourceforge.net> & - Peter O'Gorman <ogorman@users.sourceforge.net> - -Portions may be copyright others, see the AUTHORS file included with this -distribution. - -Maintained by Peter O'Gorman <ogorman@users.sourceforge.net> - -Bug Reports and other queries should go to <ogorman@users.sourceforge.net> - - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - diff --git a/Modules/_ctypes/darwin/README b/Modules/_ctypes/darwin/README deleted file mode 100644 index 4d63f3df..00000000 --- a/Modules/_ctypes/darwin/README +++ /dev/null @@ -1,95 +0,0 @@ -dlcompat for Darwin -========================= - -This is dlcompat, a small library that emulates the dlopen() -interface on top of Darwin's dyld API. - -dlcompat allows loading a ".dylib" library (as long as the RTLD_LOCAL -flag isn't passed to dlopen()). It can be configured to yield a warning -when trying to close it (dynamic libraries cannot currently be unloaded). - -It automatically searches for modules in several directories when no -absolute path is specified and the module is not found in the current -directory. - -The paths searched are those specified in the environment variables -LD_LIBRARY_PATH and DYLD_LIBRARY_PATH plus /lib, /usr/local/lib and -/usr/lib or the path specified in the environment variable -DYLD_FALLBACK_LIBRARY_PATH. - -In the default install the behavior of dlsym is to automatically prepend -an underscore to passed in symbol names, this allows easier porting of -applications which were written specifically for ELF based lifeforms. - -Installation --------------- -Type: - ./configure - make - sudo make install - -This will compile the source file, generate both a static and shared -library called libdl and install it into /usr/local/lib. The header -file dlfcn.h will be installed in /usr/local/include. - -If you want to place the files somewhere else, run - - make clean - ./configure --prefix=<prefix> - make - sudo make install - -where <prefix> is the hierarchy you want to install into, e.g. /usr -for /usr/lib and /usr/include (_NOT_ recommended!). - -To enable debugging output (useful for me), run - - make clean - ./configure --enable-debug - make - sudo make install - -If you want old dlcompat style behavior of not prepending the underscore -on calls to dlsym then type: - - make clean - ./configure --enable-fink - make - sudo make install - -Usage -------- -Software that uses GNU autoconf will likely check for a library called -libdl, that's why I named it that way. For software that doesn't find -the library on its own, you must add a '-ldl' to the appropriate -Makefile (or environment) variable, usually LIBS. - -If you installed dlcompat into a directory other than /usr/local/lib, -you must tell the compiler where to find it. Add '-L<prefix>/lib' to -LDFLAGS (or CFLAGS) and '-I<prefix>/include' to CPPFLAGS (or CFLAGS). - -Notes ------ -If you are writing new software and plan to have Mac OX X compatibility you -should look at the dyld api's in /usr/include/mach-o/dyld.h, rather than -using dlcompat, using the native api's is the supported method of loading -dynamically on Mac OS X, if you want an small example, look at dlfcn_simple.c, -which should help get you started. - -Also note that the functions in dlcompat are not thread safe, and while it is not -POSIX spec compliant, it is about as close to compliance as it is going to get though. - -You can always get the latest version from opendarwin cvs: - - cvs -d :pserver:anonymous@anoncvs.opendarwin.org:/cvs/od login - cvs -z3 -d :pserver:anonymous@anoncvs.opendarwin.org:/cvs/od \ - co -d dlcompat proj/dlcompat - - -It is hoped that this library will be useful, and as bug free as possible, if you find -any bugs please let us know about them so they can be fixed. - -Please send bug reports to Peter O'Gorman <ogorman@users.sourceforge.net> - -Thanks. - diff --git a/Modules/_ctypes/darwin/README.ctypes b/Modules/_ctypes/darwin/README.ctypes deleted file mode 100644 index 8520b01f..00000000 --- a/Modules/_ctypes/darwin/README.ctypes +++ /dev/null @@ -1,11 +0,0 @@ -The files in this directory are taken from -http://www.opendarwin.org/cgi-bin/cvsweb.cgi/~checkout~/proj/dlcompat/ - -The LICENSE in this directory applies to these files. - -Thomas Heller, Jan 2003 - -These files have been modified so they fall back to the system -dlfcn calls if available in libSystem. - -Bob Ippolito, Feb 2006 diff --git a/Modules/_ctypes/darwin/dlfcn.h b/Modules/_ctypes/darwin/dlfcn.h deleted file mode 100644 index a2afc3ee..00000000 --- a/Modules/_ctypes/darwin/dlfcn.h +++ /dev/null @@ -1,84 +0,0 @@ -/* -Copyright (c) 2002 Jorge Acereda <jacereda@users.sourceforge.net> & - Peter O'Gorman <ogorman@users.sourceforge.net> - -Portions may be copyright others, see the AUTHORS file included with this -distribution. - -Maintained by Peter O'Gorman <ogorman@users.sourceforge.net> - -Bug Reports and other queries should go to <ogorman@users.sourceforge.net> - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ -#ifndef _DLFCN_H_ -#define _DLFCN_H_ - -#include <AvailabilityMacros.h> - -#ifdef __cplusplus -extern "C" { -#endif - - -/* - * Structure filled in by dladdr(). - */ - -typedef struct dl_info { - const char *dli_fname; /* Pathname of shared object */ - void *dli_fbase; /* Base address of shared object */ - const char *dli_sname; /* Name of nearest symbol */ - void *dli_saddr; /* Address of nearest symbol */ -} Dl_info; - - -#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_2 -#warning CTYPES_DARWIN_DLFCN -#define CTYPES_DARWIN_DLFCN -extern void * (*ctypes_dlopen)(const char *path, int mode); -extern void * (*ctypes_dlsym)(void * handle, const char *symbol); -extern const char * (*ctypes_dlerror)(void); -extern int (*ctypes_dlclose)(void * handle); -extern int (*ctypes_dladdr)(const void *, Dl_info *); -#else -extern void * dlopen(const char *path, int mode); -extern void * dlsym(void * handle, const char *symbol); -extern const char * dlerror(void); -extern int dlclose(void * handle); -extern int dladdr(const void *, Dl_info *); -#endif - -#define RTLD_LAZY 0x1 -#define RTLD_NOW 0x2 -#define RTLD_LOCAL 0x4 -#define RTLD_GLOBAL 0x8 -#define RTLD_NOLOAD 0x10 -#define RTLD_NODELETE 0x80 - -/* These are from the Mac OS X 10.4 headers */ -#define RTLD_NEXT ((void *) -1) /* Search subsequent objects. */ -#define RTLD_DEFAULT ((void *) -2) /* Use default search algorithm. */ - -#ifdef __cplusplus -} -#endif - -#endif /* _DLFCN_H_ */ diff --git a/Modules/_ctypes/darwin/dlfcn_simple.c b/Modules/_ctypes/darwin/dlfcn_simple.c deleted file mode 100644 index 2b293bb8..00000000 --- a/Modules/_ctypes/darwin/dlfcn_simple.c +++ /dev/null @@ -1,272 +0,0 @@ -/* -Copyright (c) 2002 Peter O'Gorman <ogorman@users.sourceforge.net> - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - - -/* Just to prove that it isn't that hard to add Mac calls to your code :) - This works with pretty much everything, including kde3 xemacs and the gimp, - I'd guess that it'd work in at least 95% of cases, use this as your starting - point, rather than the mess that is dlfcn.c, assuming that your code does not - require ref counting or symbol lookups in dependent libraries -*/ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <stdarg.h> -#include <limits.h> -#include <mach-o/dyld.h> -#include <AvailabilityMacros.h> -#include "dlfcn.h" - -#ifdef CTYPES_DARWIN_DLFCN - -#define ERR_STR_LEN 256 - -#ifndef MAC_OS_X_VERSION_10_3 -#define MAC_OS_X_VERSION_10_3 1030 -#endif - -#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3 -#define DARWIN_HAS_DLOPEN -extern void * dlopen(const char *path, int mode) __attribute__((weak_import)); -extern void * dlsym(void * handle, const char *symbol) __attribute__((weak_import)); -extern const char * dlerror(void) __attribute__((weak_import)); -extern int dlclose(void * handle) __attribute__((weak_import)); -extern int dladdr(const void *, Dl_info *) __attribute__((weak_import)); -#endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3 */ - -#ifndef DARWIN_HAS_DLOPEN -#define dlopen darwin_dlopen -#define dlsym darwin_dlsym -#define dlerror darwin_dlerror -#define dlclose darwin_dlclose -#define dladdr darwin_dladdr -#endif - -void * (*ctypes_dlopen)(const char *path, int mode); -void * (*ctypes_dlsym)(void * handle, const char *symbol); -const char * (*ctypes_dlerror)(void); -int (*ctypes_dlclose)(void * handle); -int (*ctypes_dladdr)(const void *, Dl_info *); - -#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_3 -/* Mac OS X 10.3+ has dlopen, so strip all this dead code to avoid warnings */ - -static void *dlsymIntern(void *handle, const char *symbol); - -static const char *error(int setget, const char *str, ...); - -/* Set and get the error string for use by dlerror */ -static const char *error(int setget, const char *str, ...) -{ - static char errstr[ERR_STR_LEN]; - static int err_filled = 0; - const char *retval; - va_list arg; - if (setget == 0) - { - va_start(arg, str); - strncpy(errstr, "dlcompat: ", ERR_STR_LEN); - vsnprintf(errstr + 10, ERR_STR_LEN - 10, str, arg); - va_end(arg); - err_filled = 1; - retval = NULL; - } - else - { - if (!err_filled) - retval = NULL; - else - retval = errstr; - err_filled = 0; - } - return retval; -} - -/* darwin_dlopen */ -static void *darwin_dlopen(const char *path, int mode) -{ - void *module = 0; - NSObjectFileImage ofi = 0; - NSObjectFileImageReturnCode ofirc; - - /* If we got no path, the app wants the global namespace, use -1 as the marker - in this case */ - if (!path) - return (void *)-1; - - /* Create the object file image, works for things linked with the -bundle arg to ld */ - ofirc = NSCreateObjectFileImageFromFile(path, &ofi); - switch (ofirc) - { - case NSObjectFileImageSuccess: - /* It was okay, so use NSLinkModule to link in the image */ - module = NSLinkModule(ofi, path, - NSLINKMODULE_OPTION_RETURN_ON_ERROR - | (mode & RTLD_GLOBAL) ? 0 : NSLINKMODULE_OPTION_PRIVATE - | (mode & RTLD_LAZY) ? 0 : NSLINKMODULE_OPTION_BINDNOW); - NSDestroyObjectFileImage(ofi); - break; - case NSObjectFileImageInappropriateFile: - /* It may have been a dynamic library rather than a bundle, try to load it */ - module = (void *)NSAddImage(path, NSADDIMAGE_OPTION_RETURN_ON_ERROR); - break; - default: - /* God knows what we got */ - error(0, "Can not open \"%s\"", path); - return 0; - } - if (!module) - error(0, "Can not open \"%s\"", path); - return module; - -} - -/* dlsymIntern is used by dlsym to find the symbol */ -static void *dlsymIntern(void *handle, const char *symbol) -{ - NSSymbol nssym = 0; - /* If the handle is -1, if is the app global context */ - if (handle == (void *)-1) - { - /* Global context, use NSLookupAndBindSymbol */ - if (NSIsSymbolNameDefined(symbol)) - { - nssym = NSLookupAndBindSymbol(symbol); - } - - } - /* Now see if the handle is a struch mach_header* or not, use NSLookupSymbol in image - for libraries, and NSLookupSymbolInModule for bundles */ - else - { - /* Check for both possible magic numbers depending on x86/ppc byte order */ - if ((((struct mach_header *)handle)->magic == MH_MAGIC) || - (((struct mach_header *)handle)->magic == MH_CIGAM)) - { - if (NSIsSymbolNameDefinedInImage((struct mach_header *)handle, symbol)) - { - nssym = NSLookupSymbolInImage((struct mach_header *)handle, - symbol, - NSLOOKUPSYMBOLINIMAGE_OPTION_BIND - | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR); - } - - } - else - { - nssym = NSLookupSymbolInModule(handle, symbol); - } - } - if (!nssym) - { - error(0, "Symbol \"%s\" Not found", symbol); - return NULL; - } - return NSAddressOfSymbol(nssym); -} - -static const char *darwin_dlerror(void) -{ - return error(1, (char *)NULL); -} - -static int darwin_dlclose(void *handle) -{ - if ((((struct mach_header *)handle)->magic == MH_MAGIC) || - (((struct mach_header *)handle)->magic == MH_CIGAM)) - { - error(0, "Can't remove dynamic libraries on darwin"); - return 0; - } - if (!NSUnLinkModule(handle, 0)) - { - error(0, "unable to unlink module %s", NSNameOfModule(handle)); - return 1; - } - return 0; -} - - -/* dlsym, prepend the underscore and call dlsymIntern */ -static void *darwin_dlsym(void *handle, const char *symbol) -{ - static char undersym[257]; /* Saves calls to malloc(3) */ - int sym_len = strlen(symbol); - void *value = NULL; - char *malloc_sym = NULL; - - if (sym_len < 256) - { - snprintf(undersym, 256, "_%s", symbol); - value = dlsymIntern(handle, undersym); - } - else - { - malloc_sym = malloc(sym_len + 2); - if (malloc_sym) - { - sprintf(malloc_sym, "_%s", symbol); - value = dlsymIntern(handle, malloc_sym); - free(malloc_sym); - } - else - { - error(0, "Unable to allocate memory"); - } - } - return value; -} - -static int darwin_dladdr(const void *handle, Dl_info *info) { - return 0; -} -#endif /* MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_3 */ - -#if __GNUC__ < 4 -#pragma CALL_ON_LOAD ctypes_dlfcn_init -#else -static void __attribute__ ((constructor)) ctypes_dlfcn_init(void); -static -#endif -void ctypes_dlfcn_init(void) { - if (dlopen != NULL) { - ctypes_dlsym = dlsym; - ctypes_dlopen = dlopen; - ctypes_dlerror = dlerror; - ctypes_dlclose = dlclose; - ctypes_dladdr = dladdr; - } else { -#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_3 - ctypes_dlsym = darwin_dlsym; - ctypes_dlopen = darwin_dlopen; - ctypes_dlerror = darwin_dlerror; - ctypes_dlclose = darwin_dlclose; - ctypes_dladdr = darwin_dladdr; -#endif /* MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_3 */ - } -} - -#endif /* CTYPES_DARWIN_DLFCN */ diff --git a/Modules/_ctypes/libffi_osx/LICENSE b/Modules/_ctypes/libffi_osx/LICENSE deleted file mode 100644 index f5917951..00000000 --- a/Modules/_ctypes/libffi_osx/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -libffi - Copyright (c) 1996-2003 Red Hat, Inc. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -``Software''), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. diff --git a/Modules/_ctypes/libffi_osx/README b/Modules/_ctypes/libffi_osx/README deleted file mode 100644 index 54f00e3e..00000000 --- a/Modules/_ctypes/libffi_osx/README +++ /dev/null @@ -1,500 +0,0 @@ -This directory contains the libffi package, which is not part of GCC but -shipped with GCC as convenience. - -Status -====== - -libffi-2.00 has not been released yet! This is a development snapshot! - -libffi-1.20 was released on October 5, 1998. Check the libffi web -page for updates: <URL:http://sources.redhat.com/libffi/>. - - -What is libffi? -=============== - -Compilers for high level languages generate code that follow certain -conventions. These conventions are necessary, in part, for separate -compilation to work. One such convention is the "calling -convention". The "calling convention" is essentially a set of -assumptions made by the compiler about where function arguments will -be found on entry to a function. A "calling convention" also specifies -where the return value for a function is found. - -Some programs may not know at the time of compilation what arguments -are to be passed to a function. For instance, an interpreter may be -told at run-time about the number and types of arguments used to call -a given function. Libffi can be used in such programs to provide a -bridge from the interpreter program to compiled code. - -The libffi library provides a portable, high level programming -interface to various calling conventions. This allows a programmer to -call any function specified by a call interface description at run -time. - -Ffi stands for Foreign Function Interface. A foreign function -interface is the popular name for the interface that allows code -written in one language to call code written in another language. The -libffi library really only provides the lowest, machine dependent -layer of a fully featured foreign function interface. A layer must -exist above libffi that handles type conversions for values passed -between the two languages. - - -Supported Platforms and Prerequisites -===================================== - -Libffi has been ported to: - - SunOS 4.1.3 & Solaris 2.x (SPARC-V8, SPARC-V9) - - Irix 5.3 & 6.2 (System V/o32 & n32) - - Intel x86 - Linux (System V ABI) - - Alpha - Linux and OSF/1 - - m68k - Linux (System V ABI) - - PowerPC - Linux (System V ABI, Darwin, AIX) - - ARM - Linux (System V ABI) - -Libffi has been tested with the egcs 1.0.2 gcc compiler. Chances are -that other versions will work. Libffi has also been built and tested -with the SGI compiler tools. - -On PowerPC, the tests failed (see the note below). - -You must use GNU make to build libffi. SGI's make will not work. -Sun's probably won't either. - -If you port libffi to another platform, please let me know! I assume -that some will be easy (x86 NetBSD), and others will be more difficult -(HP). - - -Installing libffi -================= - -[Note: before actually performing any of these installation steps, - you may wish to read the "Platform Specific Notes" below.] - -First you must configure the distribution for your particular -system. Go to the directory you wish to build libffi in and run the -"configure" program found in the root directory of the libffi source -distribution. - -You may want to tell configure where to install the libffi library and -header files. To do that, use the --prefix configure switch. Libffi -will install under /usr/local by default. - -If you want to enable extra run-time debugging checks use the the ---enable-debug configure switch. This is useful when your program dies -mysteriously while using libffi. - -Another useful configure switch is --enable-purify-safety. Using this -will add some extra code which will suppress certain warnings when you -are using Purify with libffi. Only use this switch when using -Purify, as it will slow down the library. - -Configure has many other options. Use "configure --help" to see them all. - -Once configure has finished, type "make". Note that you must be using -GNU make. SGI's make will not work. Sun's probably won't either. -You can ftp GNU make from prep.ai.mit.edu:/pub/gnu. - -To ensure that libffi is working as advertised, type "make test". - -To install the library and header files, type "make install". - - -Using libffi -============ - - The Basics - ---------- - -Libffi assumes that you have a pointer to the function you wish to -call and that you know the number and types of arguments to pass it, -as well as the return type of the function. - -The first thing you must do is create an ffi_cif object that matches -the signature of the function you wish to call. The cif in ffi_cif -stands for Call InterFace. To prepare a call interface object, use the -following function: - -ffi_status ffi_prep_cif(ffi_cif *cif, ffi_abi abi, - unsigned int nargs, - ffi_type *rtype, ffi_type **atypes); - - CIF is a pointer to the call interface object you wish - to initialize. - - ABI is an enum that specifies the calling convention - to use for the call. FFI_DEFAULT_ABI defaults - to the system's native calling convention. Other - ABI's may be used with care. They are system - specific. - - NARGS is the number of arguments this function accepts. - libffi does not yet support vararg functions. - - RTYPE is a pointer to an ffi_type structure that represents - the return type of the function. Ffi_type objects - describe the types of values. libffi provides - ffi_type objects for many of the native C types: - signed int, unsigned int, signed char, unsigned char, - etc. There is also a pointer ffi_type object and - a void ffi_type. Use &ffi_type_void for functions that - don't return values. - - ATYPES is a vector of ffi_type pointers. ARGS must be NARGS long. - If NARGS is 0, this is ignored. - - -ffi_prep_cif will return a status code that you are responsible -for checking. It will be one of the following: - - FFI_OK - All is good. - - FFI_BAD_TYPEDEF - One of the ffi_type objects that ffi_prep_cif - came across is bad. - - -Before making the call, the VALUES vector should be initialized -with pointers to the appropriate argument values. - -To call the function using the initialized ffi_cif, use the -ffi_call function: - -void ffi_call(ffi_cif *cif, void *fn, void *rvalue, void **avalues); - - CIF is a pointer to the ffi_cif initialized specifically - for this function. - - FN is a pointer to the function you want to call. - - RVALUE is a pointer to a chunk of memory that is to hold the - result of the function call. Currently, it must be - at least one word in size (except for the n32 version - under Irix 6.x, which must be a pointer to an 8 byte - aligned value (a long long). It must also be at least - word aligned (depending on the return type, and the - system's alignment requirements). If RTYPE is - &ffi_type_void, this is ignored. If RVALUE is NULL, - the return value is discarded. - - AVALUES is a vector of void* that point to the memory locations - holding the argument values for a call. - If NARGS is 0, this is ignored. - - -If you are expecting a return value from FN it will have been stored -at RVALUE. - - - - An Example - ---------- - -Here is a trivial example that calls puts() a few times. - - #include <stdio.h> - #include <ffi.h> - - int main() - { - ffi_cif cif; - ffi_type *args[1]; - void *values[1]; - char *s; - int rc; - - /* Initialize the argument info vectors */ - args[0] = &ffi_type_uint; - values[0] = &s; - - /* Initialize the cif */ - if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, - &ffi_type_uint, args) == FFI_OK) - { - s = "Hello World!"; - ffi_call(&cif, puts, &rc, values); - /* rc now holds the result of the call to puts */ - - /* values holds a pointer to the function's arg, so to - call puts() again all we need to do is change the - value of s */ - s = "This is cool!"; - ffi_call(&cif, puts, &rc, values); - } - - return 0; - } - - - - Aggregate Types - --------------- - -Although libffi has no special support for unions or bit-fields, it is -perfectly happy passing structures back and forth. You must first -describe the structure to libffi by creating a new ffi_type object -for it. Here is the definition of ffi_type: - - typedef struct _ffi_type - { - unsigned size; - short alignment; - short type; - struct _ffi_type **elements; - } ffi_type; - -All structures must have type set to FFI_TYPE_STRUCT. You may set -size and alignment to 0. These will be calculated and reset to the -appropriate values by ffi_prep_cif(). - -elements is a NULL terminated array of pointers to ffi_type objects -that describe the type of the structure elements. These may, in turn, -be structure elements. - -The following example initializes a ffi_type object representing the -tm struct from Linux's time.h: - - struct tm { - int tm_sec; - int tm_min; - int tm_hour; - int tm_mday; - int tm_mon; - int tm_year; - int tm_wday; - int tm_yday; - int tm_isdst; - /* Those are for future use. */ - long int __tm_gmtoff__; - __const char *__tm_zone__; - }; - - { - ffi_type tm_type; - ffi_type *tm_type_elements[12]; - int i; - - tm_type.size = tm_type.alignment = 0; - tm_type.elements = &tm_type_elements; - - for (i = 0; i < 9; i++) - tm_type_elements[i] = &ffi_type_sint; - - tm_type_elements[9] = &ffi_type_slong; - tm_type_elements[10] = &ffi_type_pointer; - tm_type_elements[11] = NULL; - - /* tm_type can now be used to represent tm argument types and - return types for ffi_prep_cif() */ - } - - - -Platform Specific Notes -======================= - - Intel x86 - --------- - -There are no known problems with the x86 port. - - Sun SPARC - SunOS 4.1.3 & Solaris 2.x - ------------------------------------- - -You must use GNU Make to build libffi on Sun platforms. - - MIPS - Irix 5.3 & 6.x - --------------------- - -Irix 6.2 and better supports three different calling conventions: o32, -n32 and n64. Currently, libffi only supports both o32 and n32 under -Irix 6.x, but only o32 under Irix 5.3. Libffi will automatically be -configured for whichever calling convention it was built for. - -By default, the configure script will try to build libffi with the GNU -development tools. To build libffi with the SGI development tools, set -the environment variable CC to either "cc -32" or "cc -n32" before -running configure under Irix 6.x (depending on whether you want an o32 -or n32 library), or just "cc" for Irix 5.3. - -With the n32 calling convention, when returning structures smaller -than 16 bytes, be sure to provide an RVALUE that is 8 byte aligned. -Here's one way of forcing this: - - double struct_storage[2]; - my_small_struct *s = (my_small_struct *) struct_storage; - /* Use s for RVALUE */ - -If you don't do this you are liable to get spurious bus errors. - -"long long" values are not supported yet. - -You must use GNU Make to build libffi on SGI platforms. - - ARM - System V ABI - ------------------ - -The ARM port was performed on a NetWinder running ARM Linux ELF -(2.0.31) and gcc 2.8.1. - - - - PowerPC System V ABI - -------------------- - -There are two `System V ABI's which libffi implements for PowerPC. -They differ only in how small structures are returned from functions. - -In the FFI_SYSV version, structures that are 8 bytes or smaller are -returned in registers. This is what GCC does when it is configured -for solaris, and is what the System V ABI I have (dated September -1995) says. - -In the FFI_GCC_SYSV version, all structures are returned the same way: -by passing a pointer as the first argument to the function. This is -what GCC does when it is configured for linux or a generic sysv -target. - -EGCS 1.0.1 (and probably other versions of EGCS/GCC) also has a -inconsistency with the SysV ABI: When a procedure is called with many -floating-point arguments, some of them get put on the stack. They are -all supposed to be stored in double-precision format, even if they are -only single-precision, but EGCS stores single-precision arguments as -single-precision anyway. This causes one test to fail (the `many -arguments' test). - - -What's With The Cryptic Comments? -================================= - -You might notice a number of cryptic comments in the code, delimited -by /*@ and @*/. These are annotations read by the program LCLint, a -tool for statically checking C programs. You can read all about it at -<http://larch-www.lcs.mit.edu:8001/larch/lclint/index.html>. - - -History -======= - -1.20 Oct-5-98 - Raffaele Sena produces ARM port. - -1.19 Oct-5-98 - Fixed x86 long double and long long return support. - m68k bug fixes from Andreas Schwab. - Patch for DU assembler compatibility for the Alpha from Richard - Henderson. - -1.18 Apr-17-98 - Bug fixes and MIPS configuration changes. - -1.17 Feb-24-98 - Bug fixes and m68k port from Andreas Schwab. PowerPC port from - Geoffrey Keating. Various bug x86, Sparc and MIPS bug fixes. - -1.16 Feb-11-98 - Richard Henderson produces Alpha port. - -1.15 Dec-4-97 - Fixed an n32 ABI bug. New libtool, auto* support. - -1.14 May-13-97 - libtool is now used to generate shared and static libraries. - Fixed a minor portability problem reported by Russ McManus - <mcmanr@eq.gs.com>. - -1.13 Dec-2-96 - Added --enable-purify-safety to keep Purify from complaining - about certain low level code. - Sparc fix for calling functions with < 6 args. - Linux x86 a.out fix. - -1.12 Nov-22-96 - Added missing ffi_type_void, needed for supporting void return - types. Fixed test case for non MIPS machines. Cygnus Support - is now Cygnus Solutions. - -1.11 Oct-30-96 - Added notes about GNU make. - -1.10 Oct-29-96 - Added configuration fix for non GNU compilers. - -1.09 Oct-29-96 - Added --enable-debug configure switch. Clean-ups based on LCLint - feedback. ffi_mips.h is always installed. Many configuration - fixes. Fixed ffitest.c for sparc builds. - -1.08 Oct-15-96 - Fixed n32 problem. Many clean-ups. - -1.07 Oct-14-96 - Gordon Irlam rewrites v8.S again. Bug fixes. - -1.06 Oct-14-96 - Gordon Irlam improved the sparc port. - -1.05 Oct-14-96 - Interface changes based on feedback. - -1.04 Oct-11-96 - Sparc port complete (modulo struct passing bug). - -1.03 Oct-10-96 - Passing struct args, and returning struct values works for - all architectures/calling conventions. Expanded tests. - -1.02 Oct-9-96 - Added SGI n32 support. Fixed bugs in both o32 and Linux support. - Added "make test". - -1.01 Oct-8-96 - Fixed float passing bug in mips version. Restructured some - of the code. Builds cleanly with SGI tools. - -1.00 Oct-7-96 - First release. No public announcement. - - -Authors & Credits -================= - -libffi was written by Anthony Green <green@cygnus.com>. - -Portions of libffi were derived from Gianni Mariani's free gencall -library for Silicon Graphics machines. - -The closure mechanism was designed and implemented by Kresten Krab -Thorup. - -The Sparc port was derived from code contributed by the fine folks at -Visible Decisions Inc <http://www.vdi.com>. Further enhancements were -made by Gordon Irlam at Cygnus Solutions <http://www.cygnus.com>. - -The Alpha port was written by Richard Henderson at Cygnus Solutions. - -Andreas Schwab ported libffi to m68k Linux and provided a number of -bug fixes. - -Geoffrey Keating ported libffi to the PowerPC. - -Raffaele Sena ported libffi to the ARM. - -Jesper Skov and Andrew Haley both did more than their fair share of -stepping through the code and tracking down bugs. - -Thanks also to Tom Tromey for bug fixes and configuration help. - -Thanks to Jim Blandy, who provided some useful feedback on the libffi -interface. - -If you have a problem, or have found a bug, please send a note to -green@cygnus.com. diff --git a/Modules/_ctypes/libffi_osx/README.pyobjc b/Modules/_ctypes/libffi_osx/README.pyobjc deleted file mode 100644 index 405d85fe..00000000 --- a/Modules/_ctypes/libffi_osx/README.pyobjc +++ /dev/null @@ -1,5 +0,0 @@ -This directory contains a slightly modified version of libffi, extracted from -the GCC source-tree. - -The only modifications are those that are necessary to compile libffi using -the Apple provided compiler and outside of the GCC source tree. diff --git a/Modules/_ctypes/libffi_osx/ffi.c b/Modules/_ctypes/libffi_osx/ffi.c deleted file mode 100644 index 1776b795..00000000 --- a/Modules/_ctypes/libffi_osx/ffi.c +++ /dev/null @@ -1,227 +0,0 @@ -/* ----------------------------------------------------------------------- - prep_cif.c - Copyright (c) 1996, 1998 Red Hat, Inc. - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ - -#include <ffi.h> -#include <ffi_common.h> - -#include <stdbool.h> -#include <stdlib.h> - -/* Round up to FFI_SIZEOF_ARG. */ -#define STACK_ARG_SIZE(x) ALIGN(x, FFI_SIZEOF_ARG) - -/* Perform machine independent initialization of aggregate type - specifications. */ - -static ffi_status -initialize_aggregate( -/*@out@*/ ffi_type* arg) -{ -/*@-usedef@*/ - ffi_type** ptr; - - if (arg == NULL || arg->elements == NULL || - arg->size != 0 || arg->alignment != 0) - return FFI_BAD_TYPEDEF; - - ptr = &(arg->elements[0]); - - while ((*ptr) != NULL) - { - if (((*ptr)->size == 0) && (initialize_aggregate(*ptr) != FFI_OK)) - return FFI_BAD_TYPEDEF; - - /* Perform a sanity check on the argument type */ - FFI_ASSERT_VALID_TYPE(*ptr); - -#ifdef POWERPC_DARWIN - int curalign = (*ptr)->alignment; - - if (ptr != &(arg->elements[0])) - { - if (curalign > 4 && curalign != 16) - curalign = 4; - } - - arg->size = ALIGN(arg->size, curalign); - arg->size += (*ptr)->size; - arg->alignment = (arg->alignment > curalign) ? - arg->alignment : curalign; -#else - arg->size = ALIGN(arg->size, (*ptr)->alignment); - arg->size += (*ptr)->size; - arg->alignment = (arg->alignment > (*ptr)->alignment) ? - arg->alignment : (*ptr)->alignment; -#endif - - ptr++; - } - - /* Structure size includes tail padding. This is important for - structures that fit in one register on ABIs like the PowerPC64 - Linux ABI that right justify small structs in a register. - It's also needed for nested structure layout, for example - struct A { long a; char b; }; struct B { struct A x; char y; }; - should find y at an offset of 2*sizeof(long) and result in a - total size of 3*sizeof(long). */ - arg->size = ALIGN(arg->size, arg->alignment); - - if (arg->size == 0) - return FFI_BAD_TYPEDEF; - - return FFI_OK; - -/*@=usedef@*/ -} - -#ifndef __CRIS__ -/* The CRIS ABI specifies structure elements to have byte - alignment only, so it completely overrides this functions, - which assumes "natural" alignment and padding. */ - -/* Perform machine independent ffi_cif preparation, then call - machine dependent routine. */ - -#if defined(X86_DARWIN) && !defined __x86_64__ - -static inline bool -struct_on_stack( - int size) -{ - if (size > 8) - return true; - - /* This is not what the ABI says, but is what is really implemented */ - switch (size) - { - case 1: - case 2: - case 4: - case 8: - return false; - - default: - return true; - } -} - -#endif // defined(X86_DARWIN) && !defined __x86_64__ - -// Arguments' ffi_type->alignment must be nonzero. -ffi_status -ffi_prep_cif( -/*@out@*/ /*@partial@*/ ffi_cif* cif, - ffi_abi abi, - unsigned int nargs, -/*@dependent@*/ /*@out@*/ /*@partial@*/ ffi_type* rtype, -/*@dependent@*/ ffi_type** atypes) -{ - unsigned int bytes = 0; - unsigned int i; - ffi_type** ptr; - - if (cif == NULL) - return FFI_BAD_TYPEDEF; - - if (abi <= FFI_FIRST_ABI || abi > FFI_DEFAULT_ABI) - return FFI_BAD_ABI; - - cif->abi = abi; - cif->arg_types = atypes; - cif->nargs = nargs; - cif->rtype = rtype; - cif->flags = 0; - - /* Initialize the return type if necessary */ - /*@-usedef@*/ - if ((cif->rtype->size == 0) && (initialize_aggregate(cif->rtype) != FFI_OK)) - return FFI_BAD_TYPEDEF; - /*@=usedef@*/ - - /* Perform a sanity check on the return type */ - FFI_ASSERT_VALID_TYPE(cif->rtype); - - /* x86-64 and s390 stack space allocation is handled in prep_machdep. */ -#if !defined M68K && !defined __x86_64__ && !defined S390 && !defined PA - /* Make space for the return structure pointer */ - if (cif->rtype->type == FFI_TYPE_STRUCT -#ifdef SPARC - && (cif->abi != FFI_V9 || cif->rtype->size > 32) -#endif -#ifdef X86_DARWIN - && (struct_on_stack(cif->rtype->size)) -#endif - ) - bytes = STACK_ARG_SIZE(sizeof(void*)); -#endif - - for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++) - { - /* Initialize any uninitialized aggregate type definitions */ - if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK)) - return FFI_BAD_TYPEDEF; - - if ((*ptr)->alignment == 0) - return FFI_BAD_TYPEDEF; - - /* Perform a sanity check on the argument type, do this - check after the initialization. */ - FFI_ASSERT_VALID_TYPE(*ptr); - -#if defined(X86_DARWIN) - { - int align = (*ptr)->alignment; - - if (align > 4) - align = 4; - - if ((align - 1) & bytes) - bytes = ALIGN(bytes, align); - - bytes += STACK_ARG_SIZE((*ptr)->size); - } -#elif !defined __x86_64__ && !defined S390 && !defined PA -#ifdef SPARC - if (((*ptr)->type == FFI_TYPE_STRUCT - && ((*ptr)->size > 16 || cif->abi != FFI_V9)) - || ((*ptr)->type == FFI_TYPE_LONGDOUBLE - && cif->abi != FFI_V9)) - bytes += sizeof(void*); - else -#endif - { - /* Add any padding if necessary */ - if (((*ptr)->alignment - 1) & bytes) - bytes = ALIGN(bytes, (*ptr)->alignment); - - bytes += STACK_ARG_SIZE((*ptr)->size); - } -#endif - } - - cif->bytes = bytes; - - /* Perform machine dependent cif processing */ - return ffi_prep_cif_machdep(cif); -} -#endif /* not __CRIS__ */ diff --git a/Modules/_ctypes/libffi_osx/include/ffi.h b/Modules/_ctypes/libffi_osx/include/ffi.h deleted file mode 100644 index c104a5c8..00000000 --- a/Modules/_ctypes/libffi_osx/include/ffi.h +++ /dev/null @@ -1,355 +0,0 @@ -/* -----------------------------------------------------------------*-C-*- - libffi PyOBJC - Copyright (c) 1996-2003 Red Hat, Inc. - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - - ----------------------------------------------------------------------- */ - -/* ------------------------------------------------------------------- - The basic API is described in the README file. - - The raw API is designed to bypass some of the argument packing - and unpacking on architectures for which it can be avoided. - - The closure API allows interpreted functions to be packaged up - inside a C function pointer, so that they can be called as C functions, - with no understanding on the client side that they are interpreted. - It can also be used in other cases in which it is necessary to package - up a user specified parameter and a function pointer as a single - function pointer. - - The closure API must be implemented in order to get its functionality, - e.g. for use by gij. Routines are provided to emulate the raw API - if the underlying platform doesn't allow faster implementation. - - More details on the raw and closure API can be found in: - - http://gcc.gnu.org/ml/java/1999-q3/msg00138.html - - and - - http://gcc.gnu.org/ml/java/1999-q3/msg00174.html - -------------------------------------------------------------------- */ - -#ifndef LIBFFI_H -#define LIBFFI_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* Specify which architecture libffi is configured for. */ -#ifdef MACOSX -# if defined(__i386__) || defined(__x86_64__) -# define X86_DARWIN -# elif defined(__ppc__) || defined(__ppc64__) -# define POWERPC_DARWIN -# else -# error "Unsupported MacOS X CPU type" -# endif -#else -#error "Unsupported OS type" -#endif - -/* ---- System configuration information --------------------------------- */ - -#include "ffitarget.h" -#include "fficonfig.h" - -#ifndef LIBFFI_ASM - -#include <stddef.h> -#include <limits.h> - -/* LONG_LONG_MAX is not always defined (not if STRICT_ANSI, for example). - But we can find it either under the correct ANSI name, or under GNU - C's internal name. */ -#ifdef LONG_LONG_MAX -# define FFI_LONG_LONG_MAX LONG_LONG_MAX -#else -# ifdef LLONG_MAX -# define FFI_LONG_LONG_MAX LLONG_MAX -# else -# ifdef __GNUC__ -# define FFI_LONG_LONG_MAX __LONG_LONG_MAX__ -# endif -# endif -#endif - -#if SCHAR_MAX == 127 -# define ffi_type_uchar ffi_type_uint8 -# define ffi_type_schar ffi_type_sint8 -#else -#error "char size not supported" -#endif - -#if SHRT_MAX == 32767 -# define ffi_type_ushort ffi_type_uint16 -# define ffi_type_sshort ffi_type_sint16 -#elif SHRT_MAX == 2147483647 -# define ffi_type_ushort ffi_type_uint32 -# define ffi_type_sshort ffi_type_sint32 -#else -#error "short size not supported" -#endif - -#if INT_MAX == 32767 -# define ffi_type_uint ffi_type_uint16 -# define ffi_type_sint ffi_type_sint16 -#elif INT_MAX == 2147483647 -# define ffi_type_uint ffi_type_uint32 -# define ffi_type_sint ffi_type_sint32 -#elif INT_MAX == 9223372036854775807 -# define ffi_type_uint ffi_type_uint64 -# define ffi_type_sint ffi_type_sint64 -#else -#error "int size not supported" -#endif - -#define ffi_type_ulong ffi_type_uint64 -#define ffi_type_slong ffi_type_sint64 - -#if LONG_MAX == 2147483647 -# if FFI_LONG_LONG_MAX != 9223372036854775807 -# error "no 64-bit data type supported" -# endif -#elif LONG_MAX != 9223372036854775807 -#error "long size not supported" -#endif - -/* The closure code assumes that this works on pointers, i.e. a size_t - can hold a pointer. */ - -typedef struct _ffi_type { - size_t size; - unsigned short alignment; - unsigned short type; -/*@null@*/ struct _ffi_type** elements; -} ffi_type; - -/* These are defined in types.c */ -extern ffi_type ffi_type_void; -extern ffi_type ffi_type_uint8; -extern ffi_type ffi_type_sint8; -extern ffi_type ffi_type_uint16; -extern ffi_type ffi_type_sint16; -extern ffi_type ffi_type_uint32; -extern ffi_type ffi_type_sint32; -extern ffi_type ffi_type_uint64; -extern ffi_type ffi_type_sint64; -extern ffi_type ffi_type_float; -extern ffi_type ffi_type_double; -extern ffi_type ffi_type_longdouble; -extern ffi_type ffi_type_pointer; - -typedef enum ffi_status { - FFI_OK = 0, - FFI_BAD_TYPEDEF, - FFI_BAD_ABI -} ffi_status; - -typedef unsigned FFI_TYPE; - -typedef struct ffi_cif { - ffi_abi abi; - unsigned nargs; -/*@dependent@*/ ffi_type** arg_types; -/*@dependent@*/ ffi_type* rtype; - unsigned bytes; - unsigned flags; -#ifdef FFI_EXTRA_CIF_FIELDS - FFI_EXTRA_CIF_FIELDS; -#endif -} ffi_cif; - -/* ---- Definitions for the raw API -------------------------------------- */ - -#ifndef FFI_SIZEOF_ARG -# if LONG_MAX == 2147483647 -# define FFI_SIZEOF_ARG 4 -# elif LONG_MAX == 9223372036854775807 -# define FFI_SIZEOF_ARG 8 -# endif -#endif - -typedef union { - ffi_sarg sint; - ffi_arg uint; - float flt; - char data[FFI_SIZEOF_ARG]; - void* ptr; -} ffi_raw; - -void -ffi_raw_call( -/*@dependent@*/ ffi_cif* cif, - void (*fn)(void), -/*@out@*/ void* rvalue, -/*@dependent@*/ ffi_raw* avalue); - -void -ffi_ptrarray_to_raw( - ffi_cif* cif, - void** args, - ffi_raw* raw); - -void -ffi_raw_to_ptrarray( - ffi_cif* cif, - ffi_raw* raw, - void** args); - -size_t -ffi_raw_size( - ffi_cif* cif); - -/* This is analogous to the raw API, except it uses Java parameter - packing, even on 64-bit machines. I.e. on 64-bit machines - longs and doubles are followed by an empty 64-bit word. */ -void -ffi_java_raw_call( -/*@dependent@*/ ffi_cif* cif, - void (*fn)(void), -/*@out@*/ void* rvalue, -/*@dependent@*/ ffi_raw* avalue); - -void -ffi_java_ptrarray_to_raw( - ffi_cif* cif, - void** args, - ffi_raw* raw); - -void -ffi_java_raw_to_ptrarray( - ffi_cif* cif, - ffi_raw* raw, - void** args); - -size_t -ffi_java_raw_size( - ffi_cif* cif); - -/* ---- Definitions for closures ----------------------------------------- */ - -#if FFI_CLOSURES - -typedef struct ffi_closure { - char tramp[FFI_TRAMPOLINE_SIZE]; - ffi_cif* cif; - void (*fun)(ffi_cif*,void*,void**,void*); - void* user_data; -} ffi_closure; - -ffi_status -ffi_prep_closure( - ffi_closure* closure, - ffi_cif* cif, - void (*fun)(ffi_cif*,void*,void**,void*), - void* user_data); - -void ffi_closure_free(void *); -void *ffi_closure_alloc (size_t size, void **code); - -typedef struct ffi_raw_closure { - char tramp[FFI_TRAMPOLINE_SIZE]; - ffi_cif* cif; - -#if !FFI_NATIVE_RAW_API - /* if this is enabled, then a raw closure has the same layout - as a regular closure. We use this to install an intermediate - handler to do the transaltion, void** -> ffi_raw*. */ - void (*translate_args)(ffi_cif*,void*,void**,void*); - void* this_closure; -#endif - - void (*fun)(ffi_cif*,void*,ffi_raw*,void*); - void* user_data; -} ffi_raw_closure; - -ffi_status -ffi_prep_raw_closure( - ffi_raw_closure* closure, - ffi_cif* cif, - void (*fun)(ffi_cif*,void*,ffi_raw*,void*), - void* user_data); - -ffi_status -ffi_prep_java_raw_closure( - ffi_raw_closure* closure, - ffi_cif* cif, - void (*fun)(ffi_cif*,void*,ffi_raw*,void*), - void* user_data); - -#endif // FFI_CLOSURES - -/* ---- Public interface definition -------------------------------------- */ - -ffi_status -ffi_prep_cif( -/*@out@*/ /*@partial@*/ ffi_cif* cif, - ffi_abi abi, - unsigned int nargs, -/*@dependent@*/ /*@out@*/ /*@partial@*/ ffi_type* rtype, -/*@dependent@*/ ffi_type** atypes); - -void -ffi_call( -/*@dependent@*/ ffi_cif* cif, - void (*fn)(void), -/*@out@*/ void* rvalue, -/*@dependent@*/ void** avalue); - -/* Useful for eliminating compiler warnings */ -#define FFI_FN(f) ((void (*)(void))f) - -#endif // #ifndef LIBFFI_ASM -/* ---- Definitions shared with assembly code ---------------------------- */ - -/* If these change, update src/mips/ffitarget.h. */ -#define FFI_TYPE_VOID 0 -#define FFI_TYPE_INT 1 -#define FFI_TYPE_FLOAT 2 -#define FFI_TYPE_DOUBLE 3 - -#ifdef HAVE_LONG_DOUBLE -# define FFI_TYPE_LONGDOUBLE 4 -#else -# define FFI_TYPE_LONGDOUBLE FFI_TYPE_DOUBLE -#endif - -#define FFI_TYPE_UINT8 5 -#define FFI_TYPE_SINT8 6 -#define FFI_TYPE_UINT16 7 -#define FFI_TYPE_SINT16 8 -#define FFI_TYPE_UINT32 9 -#define FFI_TYPE_SINT32 10 -#define FFI_TYPE_UINT64 11 -#define FFI_TYPE_SINT64 12 -#define FFI_TYPE_STRUCT 13 -#define FFI_TYPE_POINTER 14 - -/* This should always refer to the last type code (for sanity checks) */ -#define FFI_TYPE_LAST FFI_TYPE_POINTER - -#ifdef __cplusplus -} -#endif - -#endif // #ifndef LIBFFI_H diff --git a/Modules/_ctypes/libffi_osx/include/ffi_common.h b/Modules/_ctypes/libffi_osx/include/ffi_common.h deleted file mode 100644 index 685a3580..00000000 --- a/Modules/_ctypes/libffi_osx/include/ffi_common.h +++ /dev/null @@ -1,102 +0,0 @@ -/* ----------------------------------------------------------------------- - ffi_common.h - Copyright (c) 1996 Red Hat, Inc. - - Common internal definitions and macros. Only necessary for building - libffi. - ----------------------------------------------------------------------- */ - -#ifndef FFI_COMMON_H -#define FFI_COMMON_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include "fficonfig.h" - -/* Do not move this. Some versions of AIX are very picky about where - this is positioned. */ -#ifdef __GNUC__ -# define alloca __builtin_alloca -#else -# if HAVE_ALLOCA_H -# include <alloca.h> -# else -# ifdef _AIX -# pragma alloca -# else -# ifndef alloca /* predefined by HP cc +Olibcalls */ -char* alloca(); -# endif -# endif -# endif -#endif - -/* Check for the existence of memcpy. */ -#if STDC_HEADERS -# include <string.h> -#else -# ifndef HAVE_MEMCPY -# define memcpy(d, s, n) bcopy((s), (d), (n)) -# endif -#endif - -/*#if defined(FFI_DEBUG) -#include <stdio.h> -#endif*/ - -#ifdef FFI_DEBUG -#include <stdio.h> - -/*@exits@*/ void -ffi_assert( -/*@temp@*/ char* expr, -/*@temp@*/ char* file, - int line); -void -ffi_stop_here(void); -void -ffi_type_test( -/*@temp@*/ /*@out@*/ ffi_type* a, -/*@temp@*/ char* file, - int line); - -# define FFI_ASSERT(x) ((x) ? (void)0 : ffi_assert(#x, __FILE__,__LINE__)) -# define FFI_ASSERT_AT(x, f, l) ((x) ? 0 : ffi_assert(#x, (f), (l))) -# define FFI_ASSERT_VALID_TYPE(x) ffi_type_test(x, __FILE__, __LINE__) -#else -# define FFI_ASSERT(x) -# define FFI_ASSERT_AT(x, f, l) -# define FFI_ASSERT_VALID_TYPE(x) -#endif // #ifdef FFI_DEBUG - -#define ALIGN(v, a) (((size_t)(v) + (a) - 1) & ~((a) - 1)) - -/* Perform machine dependent cif processing */ -ffi_status -ffi_prep_cif_machdep( - ffi_cif* cif); - -/* Extended cif, used in callback from assembly routine */ -typedef struct extended_cif { -/*@dependent@*/ ffi_cif* cif; -/*@dependent@*/ void* rvalue; -/*@dependent@*/ void** avalue; -} extended_cif; - -/* Terse sized type definitions. */ -typedef unsigned int UINT8 __attribute__((__mode__(__QI__))); -typedef signed int SINT8 __attribute__((__mode__(__QI__))); -typedef unsigned int UINT16 __attribute__((__mode__(__HI__))); -typedef signed int SINT16 __attribute__((__mode__(__HI__))); -typedef unsigned int UINT32 __attribute__((__mode__(__SI__))); -typedef signed int SINT32 __attribute__((__mode__(__SI__))); -typedef unsigned int UINT64 __attribute__((__mode__(__DI__))); -typedef signed int SINT64 __attribute__((__mode__(__DI__))); -typedef float FLOAT32; - -#ifdef __cplusplus -} -#endif - -#endif // #ifndef FFI_COMMON_H \ No newline at end of file diff --git a/Modules/_ctypes/libffi_osx/include/fficonfig.h b/Modules/_ctypes/libffi_osx/include/fficonfig.h deleted file mode 100644 index 21724907..00000000 --- a/Modules/_ctypes/libffi_osx/include/fficonfig.h +++ /dev/null @@ -1,150 +0,0 @@ -/* Manually created fficonfig.h for Darwin on PowerPC or Intel - - This file is manually generated to do away with the need for autoconf and - therefore make it easier to cross-compile and build fat binaries. - - NOTE: This file was added by PyObjC. -*/ - -#ifndef MACOSX -#error "This file is only supported on Mac OS X" -#endif - -#if defined(__i386__) -# define BYTEORDER 1234 -# undef HOST_WORDS_BIG_ENDIAN -# undef WORDS_BIGENDIAN -# define SIZEOF_DOUBLE 8 -# define HAVE_LONG_DOUBLE 1 -# define SIZEOF_LONG_DOUBLE 16 - -#elif defined(__x86_64__) -# define BYTEORDER 1234 -# undef HOST_WORDS_BIG_ENDIAN -# undef WORDS_BIGENDIAN -# define SIZEOF_DOUBLE 8 -# define HAVE_LONG_DOUBLE 1 -# define SIZEOF_LONG_DOUBLE 16 - -#elif defined(__ppc__) -# define BYTEORDER 4321 -# define HOST_WORDS_BIG_ENDIAN 1 -# define WORDS_BIGENDIAN 1 -# define SIZEOF_DOUBLE 8 -# if __GNUC__ >= 4 -# define HAVE_LONG_DOUBLE 1 -# define SIZEOF_LONG_DOUBLE 16 -# else -# undef HAVE_LONG_DOUBLE -# define SIZEOF_LONG_DOUBLE 8 -# endif - -#elif defined(__ppc64__) -# define BYTEORDER 4321 -# define HOST_WORDS_BIG_ENDIAN 1 -# define WORDS_BIGENDIAN 1 -# define SIZEOF_DOUBLE 8 -# define HAVE_LONG_DOUBLE 1 -# define SIZEOF_LONG_DOUBLE 16 - -#else -#error "Unknown CPU type" -#endif - -/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP - systems. This function is required for `alloca.c' support on those systems. */ -#undef CRAY_STACKSEG_END - -/* Define to 1 if using `alloca.c'. */ -/* #undef C_ALLOCA */ - -/* Define to the flags needed for the .section .eh_frame directive. */ -#define EH_FRAME_FLAGS "aw" - -/* Define this if you want extra debugging. */ -/* #undef FFI_DEBUG */ - -/* Define this is you do not want support for the raw API. */ -#define FFI_NO_RAW_API 1 - -/* Define this if you do not want support for aggregate types. */ -/* #undef FFI_NO_STRUCTS */ - -/* Define to 1 if you have `alloca', as a function or macro. */ -#define HAVE_ALLOCA 1 - -/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix). */ -#define HAVE_ALLOCA_H 1 - -/* Define if your assembler supports .register. */ -/* #undef HAVE_AS_REGISTER_PSEUDO_OP */ - -/* Define if your assembler and linker support unaligned PC relative relocs. */ -/* #undef HAVE_AS_SPARC_UA_PCREL */ - -/* Define to 1 if you have the `memcpy' function. */ -#define HAVE_MEMCPY 1 - -/* Define if mmap with MAP_ANON(YMOUS) works. */ -#define HAVE_MMAP_ANON 1 - -/* Define if mmap of /dev/zero works. */ -/* #undef HAVE_MMAP_DEV_ZERO */ - -/* Define if read-only mmap of a plain file works. */ -#define HAVE_MMAP_FILE 1 - -/* Define if .eh_frame sections should be read-only. */ -/* #undef HAVE_RO_EH_FRAME */ - -/* Define to 1 if your C compiler doesn't accept -c and -o together. */ -/* #undef NO_MINUS_C_MINUS_O */ - -/* Name of package */ -#define PACKAGE "libffi" - -/* Define to the address where bug reports for this package should be sent. */ -#define PACKAGE_BUGREPORT "http://gcc.gnu.org/bugs.html" - -/* Define to the full name of this package. */ -#define PACKAGE_NAME "libffi" - -/* Define to the full name and version of this package. */ -#define PACKAGE_STRING "libffi 2.1" - -/* Define to the one symbol short name of this package. */ -#define PACKAGE_TARNAME "libffi" - -/* Define to the version of this package. */ -#define PACKAGE_VERSION "2.1" - -/* If using the C implementation of alloca, define if you know the - direction of stack growth for your system; otherwise it will be - automatically deduced at run-time. - STACK_DIRECTION > 0 => grows toward higher addresses - STACK_DIRECTION < 0 => grows toward lower addresses - STACK_DIRECTION = 0 => direction of growth unknown */ -/* #undef STACK_DIRECTION */ - -/* Define to 1 if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* Define this if you are using Purify and want to suppress spurious messages. */ -/* #undef USING_PURIFY */ - -/* Version number of package */ -#define VERSION "2.1-pyobjc" - -#ifdef HAVE_HIDDEN_VISIBILITY_ATTRIBUTE -# ifdef LIBFFI_ASM -# define FFI_HIDDEN(name) .hidden name -# else -# define FFI_HIDDEN __attribute__((visibility ("hidden"))) -# endif -#else -# ifdef LIBFFI_ASM -# define FFI_HIDDEN(name) -# else -# define FFI_HIDDEN -# endif -#endif \ No newline at end of file diff --git a/Modules/_ctypes/libffi_osx/include/ffitarget.h b/Modules/_ctypes/libffi_osx/include/ffitarget.h deleted file mode 100644 index faaa30de..00000000 --- a/Modules/_ctypes/libffi_osx/include/ffitarget.h +++ /dev/null @@ -1,13 +0,0 @@ -/* Dispatch to the right ffitarget file. This file is PyObjC specific; in a - normal build, the build environment copies the file to the right location or - sets up the right include flags. We want to do neither because that would - make building fat binaries harder. -*/ - -#if defined(__i386__) || defined(__x86_64__) -#include "x86-ffitarget.h" -#elif defined(__ppc__) || defined(__ppc64__) -#include "ppc-ffitarget.h" -#else -#error "Unsupported CPU type" -#endif \ No newline at end of file diff --git a/Modules/_ctypes/libffi_osx/include/ppc-ffitarget.h b/Modules/_ctypes/libffi_osx/include/ppc-ffitarget.h deleted file mode 100644 index 23184219..00000000 --- a/Modules/_ctypes/libffi_osx/include/ppc-ffitarget.h +++ /dev/null @@ -1,104 +0,0 @@ -/* -----------------------------------------------------------------*-C-*- - ppc-ffitarget.h - Copyright (c) 1996-2003 Red Hat, Inc. - Target configuration macros for PowerPC. - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ - -#ifndef LIBFFI_TARGET_H -#define LIBFFI_TARGET_H - -/* ---- System specific configurations ----------------------------------- */ - -#if (defined(POWERPC) && defined(__powerpc64__)) || \ - (defined(POWERPC_DARWIN) && defined(__ppc64__)) -#define POWERPC64 -#endif - -#ifndef LIBFFI_ASM - -typedef unsigned long ffi_arg; -typedef signed long ffi_sarg; - -typedef enum ffi_abi { - FFI_FIRST_ABI = 0, - -#ifdef POWERPC - FFI_SYSV, - FFI_GCC_SYSV, - FFI_LINUX64, -# ifdef POWERPC64 - FFI_DEFAULT_ABI = FFI_LINUX64, -# else - FFI_DEFAULT_ABI = FFI_GCC_SYSV, -# endif -#endif - -#ifdef POWERPC_AIX - FFI_AIX, - FFI_DARWIN, - FFI_DEFAULT_ABI = FFI_AIX, -#endif - -#ifdef POWERPC_DARWIN - FFI_AIX, - FFI_DARWIN, - FFI_DEFAULT_ABI = FFI_DARWIN, -#endif - -#ifdef POWERPC_FREEBSD - FFI_SYSV, - FFI_GCC_SYSV, - FFI_LINUX64, - FFI_DEFAULT_ABI = FFI_SYSV, -#endif - - FFI_LAST_ABI = FFI_DEFAULT_ABI + 1 -} ffi_abi; - -#endif // #ifndef LIBFFI_ASM - -/* ---- Definitions for closures ----------------------------------------- */ - -#define FFI_CLOSURES 1 -#define FFI_NATIVE_RAW_API 0 - -/* Needed for FFI_SYSV small structure returns. */ -#define FFI_SYSV_TYPE_SMALL_STRUCT (FFI_TYPE_LAST) - -#if defined(POWERPC64) /*|| defined(POWERPC_AIX)*/ -# define FFI_TRAMPOLINE_SIZE 48 -#elif defined(POWERPC_AIX) -# define FFI_TRAMPOLINE_SIZE 24 -#else -# define FFI_TRAMPOLINE_SIZE 40 -#endif - -#ifndef LIBFFI_ASM -# if defined(POWERPC_DARWIN) || defined(POWERPC_AIX) -typedef struct ffi_aix_trampoline_struct { - void* code_pointer; /* Pointer to ffi_closure_ASM */ - void* toc; /* TOC */ - void* static_chain; /* Pointer to closure */ -} ffi_aix_trampoline_struct; -# endif -#endif // #ifndef LIBFFI_ASM - -#endif // #ifndef LIBFFI_TARGET_H \ No newline at end of file diff --git a/Modules/_ctypes/libffi_osx/include/x86-ffitarget.h b/Modules/_ctypes/libffi_osx/include/x86-ffitarget.h deleted file mode 100644 index 55c2b6c5..00000000 --- a/Modules/_ctypes/libffi_osx/include/x86-ffitarget.h +++ /dev/null @@ -1,88 +0,0 @@ -/* -----------------------------------------------------------------*-C-*- - x86-ffitarget.h - Copyright (c) 1996-2003 Red Hat, Inc. - Target configuration macros for x86 and x86-64. - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - - ----------------------------------------------------------------------- */ - -#ifndef LIBFFI_TARGET_H -#define LIBFFI_TARGET_H - -/* ---- System specific configurations ----------------------------------- */ - -#if defined(X86_64) && defined(__i386__) -# undef X86_64 -# define X86 -#endif - -#if defined(__x86_64__) -# ifndef X86_64 -# define X86_64 -# endif -#endif - -/* ---- Generic type definitions ----------------------------------------- */ - -#ifndef LIBFFI_ASM - -typedef unsigned long ffi_arg; -typedef signed long ffi_sarg; - -typedef enum ffi_abi { - FFI_FIRST_ABI = 0, - - /* ---- Intel x86 Win32 ---------- */ -#ifdef X86_WIN32 - FFI_SYSV, - FFI_STDCALL, - /* TODO: Add fastcall support for the sake of completeness */ - FFI_DEFAULT_ABI = FFI_SYSV, -#endif - - /* ---- Intel x86 and AMD x86-64 - */ -#if !defined(X86_WIN32) && (defined(__i386__) || defined(__x86_64__)) - FFI_SYSV, - FFI_UNIX64, /* Unix variants all use the same ABI for x86-64 */ -# ifdef __i386__ - FFI_DEFAULT_ABI = FFI_SYSV, -# else - FFI_DEFAULT_ABI = FFI_UNIX64, -# endif -#endif - - FFI_LAST_ABI = FFI_DEFAULT_ABI + 1 -} ffi_abi; - -#endif // #ifndef LIBFFI_ASM - -/* ---- Definitions for closures ----------------------------------------- */ - -#define FFI_CLOSURES 1 - -#if defined(X86_64) || (defined(__x86_64__) && defined(X86_DARWIN)) -# define FFI_TRAMPOLINE_SIZE 24 -# define FFI_NATIVE_RAW_API 0 -#else -# define FFI_TRAMPOLINE_SIZE 10 -# define FFI_NATIVE_RAW_API 1 /* x86 has native raw api support */ -#endif - -#endif // #ifndef LIBFFI_TARGET_H \ No newline at end of file diff --git a/Modules/_ctypes/libffi_osx/powerpc/ppc-darwin.S b/Modules/_ctypes/libffi_osx/powerpc/ppc-darwin.S deleted file mode 100644 index f143dbd2..00000000 --- a/Modules/_ctypes/libffi_osx/powerpc/ppc-darwin.S +++ /dev/null @@ -1,365 +0,0 @@ -#if defined(__ppc__) || defined(__ppc64__) - -/* ----------------------------------------------------------------------- - ppc-darwin.S - Copyright (c) 2000 John Hornkvist - Copyright (c) 2004 Free Software Foundation, Inc. - - PowerPC Assembly glue. - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ - -#define LIBFFI_ASM - -#include <fficonfig.h> -#include <ffi.h> -#include <ppc-darwin.h> -#include <architecture/ppc/mode_independent_asm.h> - -.text - .align 2 -.globl _ffi_prep_args - -.text - .align 2 -.globl _ffi_call_DARWIN - -.text - .align 2 -_ffi_call_DARWIN: -LFB0: - mr r12,r8 /* We only need r12 until the call, - so it doesn't have to be saved. */ - -LFB1: - /* Save the old stack pointer as AP. */ - mr r8,r1 - -LCFI0: -#if defined(__ppc64__) - /* Allocate the stack space we need. - r4 (size of input data) - 48 bytes (linkage area) - 40 bytes (saved registers) - 8 bytes (extra FPR) - r4 + 96 bytes total - */ - - addi r4,r4,-96 // Add our overhead. - li r0,-32 // Align to 32 bytes. - and r4,r4,r0 -#endif - stgux r1,r1,r4 // Grow the stack. - mflr r9 - - /* Save registers we use. */ -#if defined(__ppc64__) - std r27,-40(r8) -#endif - stg r28,MODE_CHOICE(-16,-32)(r8) - stg r29,MODE_CHOICE(-12,-24)(r8) - stg r30,MODE_CHOICE(-8,-16)(r8) - stg r31,MODE_CHOICE(-4,-8)(r8) - stg r9,SF_RETURN(r8) /* return address */ -#if !defined(POWERPC_DARWIN) /* TOC unused in OS X */ - stg r2,MODE_CHOICE(20,40)(r1) -#endif - -LCFI1: -#if defined(__ppc64__) - mr r27,r3 // our extended_cif -#endif - /* Save arguments over call. */ - mr r31,r5 /* flags, */ - mr r30,r6 /* rvalue, */ - mr r29,r7 /* function address, */ - mr r28,r8 /* our AP. */ - -LCFI2: - /* Call ffi_prep_args. */ - mr r4,r1 - li r9,0 - mtctr r12 /* r12 holds address of _ffi_prep_args. */ - bctrl -#if !defined(POWERPC_DARWIN) /* TOC unused in OS X */ - lg r2,MODE_CHOICE(20,40)(r1) -#endif - - /* Now do the call. - Set up cr1 with bits 4-7 of the flags. */ - mtcrf 0x40,r31 - - /* Load all those argument registers. - We have set up a nice stack frame, just load it into registers. */ - lg r3,SF_ARG1(r1) - lg r4,SF_ARG2(r1) - lg r5,SF_ARG3(r1) - lg r6,SF_ARG4(r1) - nop - lg r7,SF_ARG5(r1) - lg r8,SF_ARG6(r1) - lg r9,SF_ARG7(r1) - lg r10,SF_ARG8(r1) - - /* Load all the FP registers. */ - bf 6,L2 /* No floats to load. */ -#if defined(__ppc64__) - lfd f1,MODE_CHOICE(-16,-40)-(14*8)(r28) - lfd f2,MODE_CHOICE(-16,-40)-(13*8)(r28) - lfd f3,MODE_CHOICE(-16,-40)-(12*8)(r28) - lfd f4,MODE_CHOICE(-16,-40)-(11*8)(r28) - nop - lfd f5,MODE_CHOICE(-16,-40)-(10*8)(r28) - lfd f6,MODE_CHOICE(-16,-40)-(9*8)(r28) - lfd f7,MODE_CHOICE(-16,-40)-(8*8)(r28) - lfd f8,MODE_CHOICE(-16,-40)-(7*8)(r28) - nop - lfd f9,MODE_CHOICE(-16,-40)-(6*8)(r28) - lfd f10,MODE_CHOICE(-16,-40)-(5*8)(r28) - lfd f11,MODE_CHOICE(-16,-40)-(4*8)(r28) - lfd f12,MODE_CHOICE(-16,-40)-(3*8)(r28) - nop - lfd f13,MODE_CHOICE(-16,-40)-(2*8)(r28) - lfd f14,MODE_CHOICE(-16,-40)-(1*8)(r28) -#elif defined(__ppc__) - lfd f1,MODE_CHOICE(-16,-40)-(13*8)(r28) - lfd f2,MODE_CHOICE(-16,-40)-(12*8)(r28) - lfd f3,MODE_CHOICE(-16,-40)-(11*8)(r28) - lfd f4,MODE_CHOICE(-16,-40)-(10*8)(r28) - nop - lfd f5,MODE_CHOICE(-16,-40)-(9*8)(r28) - lfd f6,MODE_CHOICE(-16,-40)-(8*8)(r28) - lfd f7,MODE_CHOICE(-16,-40)-(7*8)(r28) - lfd f8,MODE_CHOICE(-16,-40)-(6*8)(r28) - nop - lfd f9,MODE_CHOICE(-16,-40)-(5*8)(r28) - lfd f10,MODE_CHOICE(-16,-40)-(4*8)(r28) - lfd f11,MODE_CHOICE(-16,-40)-(3*8)(r28) - lfd f12,MODE_CHOICE(-16,-40)-(2*8)(r28) - nop - lfd f13,MODE_CHOICE(-16,-40)-(1*8)(r28) -#else -#error undefined architecture -#endif - -L2: - mr r12,r29 // Put the target address in r12 as specified. - mtctr r12 // Get the address to call into CTR. - nop - nop - bctrl // Make the call. - - // Deal with the return value. -#if defined(__ppc64__) - mtcrf 0x3,r31 // flags in cr6 and cr7 - bt 27,L(st_return_value) -#elif defined(__ppc__) - mtcrf 0x1,r31 // flags in cr7 -#else -#error undefined architecture -#endif - - bt 30,L(done_return_value) - bt 29,L(fp_return_value) - stg r3,0(r30) -#if defined(__ppc__) - bf 28,L(done_return_value) // Store the second long if necessary. - stg r4,4(r30) -#endif - // Fall through - -L(done_return_value): - lg r1,0(r1) // Restore stack pointer. - // Restore the registers we used. - lg r9,SF_RETURN(r1) // return address - lg r31,MODE_CHOICE(-4,-8)(r1) - mtlr r9 - lg r30,MODE_CHOICE(-8,-16)(r1) - lg r29,MODE_CHOICE(-12,-24)(r1) - lg r28,MODE_CHOICE(-16,-32)(r1) -#if defined(__ppc64__) - ld r27,-40(r1) -#endif - blr - -#if defined(__ppc64__) -L(st_return_value): - // Grow the stack enough to fit the registers. Leave room for 8 args - // to trample the 1st 8 slots in param area. - stgu r1,-SF_ROUND(280)(r1) // 64 + 104 + 48 + 64 - - // Store GPRs - std r3,SF_ARG9(r1) - std r4,SF_ARG10(r1) - std r5,SF_ARG11(r1) - std r6,SF_ARG12(r1) - nop - std r7,SF_ARG13(r1) - std r8,SF_ARG14(r1) - std r9,SF_ARG15(r1) - std r10,SF_ARG16(r1) - - // Store FPRs - nop - bf 26,L(call_struct_to_ram_form) - stfd f1,SF_ARG17(r1) - stfd f2,SF_ARG18(r1) - stfd f3,SF_ARG19(r1) - stfd f4,SF_ARG20(r1) - nop - stfd f5,SF_ARG21(r1) - stfd f6,SF_ARG22(r1) - stfd f7,SF_ARG23(r1) - stfd f8,SF_ARG24(r1) - nop - stfd f9,SF_ARG25(r1) - stfd f10,SF_ARG26(r1) - stfd f11,SF_ARG27(r1) - stfd f12,SF_ARG28(r1) - nop - stfd f13,SF_ARG29(r1) - -L(call_struct_to_ram_form): - ld r3,0(r27) // extended_cif->cif* - ld r3,16(r3) // ffi_cif->rtype* - addi r4,r1,SF_ARG9 // stored GPRs - addi r6,r1,SF_ARG17 // stored FPRs - li r5,0 // GPR size ptr (NULL) - li r7,0 // FPR size ptr (NULL) - li r8,0 // FPR count ptr (NULL) - li r10,0 // struct offset (NULL) - mr r9,r30 // return area - bl Lffi64_struct_to_ram_form$stub - lg r1,0(r1) // Restore stack pointer. - b L(done_return_value) -#endif - -L(fp_return_value): - /* Do we have long double to store? */ - bf 31,L(fd_return_value) - stfd f1,0(r30) - stfd f2,8(r30) - b L(done_return_value) - -L(fd_return_value): - /* Do we have double to store? */ - bf 28,L(float_return_value) - stfd f1,0(r30) - b L(done_return_value) - -L(float_return_value): - /* We only have a float to store. */ - stfs f1,0(r30) - b L(done_return_value) - -LFE1: -/* END(_ffi_call_DARWIN) */ - -/* Provide a null definition of _ffi_call_AIX. */ -.text - .align 2 -.globl _ffi_call_AIX -.text - .align 2 -_ffi_call_AIX: - blr -/* END(_ffi_call_AIX) */ - -.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms -EH_frame1: - .set L$set$0,LECIE1-LSCIE1 - .long L$set$0 ; Length of Common Information Entry -LSCIE1: - .long 0x0 ; CIE Identifier Tag - .byte 0x1 ; CIE Version - .ascii "zR\0" ; CIE Augmentation - .byte 0x1 ; uleb128 0x1; CIE Code Alignment Factor - .byte 0x7c ; sleb128 -4; CIE Data Alignment Factor - .byte 0x41 ; CIE RA Column - .byte 0x1 ; uleb128 0x1; Augmentation size - .byte 0x10 ; FDE Encoding (pcrel) - .byte 0xc ; DW_CFA_def_cfa - .byte 0x1 ; uleb128 0x1 - .byte 0x0 ; uleb128 0x0 - .align LOG2_GPR_BYTES -LECIE1: -.globl _ffi_call_DARWIN.eh -_ffi_call_DARWIN.eh: -LSFDE1: - .set L$set$1,LEFDE1-LASFDE1 - .long L$set$1 ; FDE Length - -LASFDE1: - .long LASFDE1-EH_frame1 ; FDE CIE offset - .g_long LFB0-. ; FDE initial location - .set L$set$3,LFE1-LFB0 - .g_long L$set$3 ; FDE address range - .byte 0x0 ; uleb128 0x0; Augmentation size - .byte 0x4 ; DW_CFA_advance_loc4 - .set L$set$4,LCFI0-LFB1 - .long L$set$4 - .byte 0xd ; DW_CFA_def_cfa_register - .byte 0x08 ; uleb128 0x08 - .byte 0x4 ; DW_CFA_advance_loc4 - .set L$set$5,LCFI1-LCFI0 - .long L$set$5 - .byte 0x11 ; DW_CFA_offset_extended_sf - .byte 0x41 ; uleb128 0x41 - .byte 0x7e ; sleb128 -2 - .byte 0x9f ; DW_CFA_offset, column 0x1f - .byte 0x1 ; uleb128 0x1 - .byte 0x9e ; DW_CFA_offset, column 0x1e - .byte 0x2 ; uleb128 0x2 - .byte 0x9d ; DW_CFA_offset, column 0x1d - .byte 0x3 ; uleb128 0x3 - .byte 0x9c ; DW_CFA_offset, column 0x1c - .byte 0x4 ; uleb128 0x4 - .byte 0x4 ; DW_CFA_advance_loc4 - .set L$set$6,LCFI2-LCFI1 - .long L$set$6 - .byte 0xd ; DW_CFA_def_cfa_register - .byte 0x1c ; uleb128 0x1c - .align LOG2_GPR_BYTES -LEFDE1: - -#if defined(__ppc64__) -.section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32 - .align LOG2_GPR_BYTES - -Lffi64_struct_to_ram_form$stub: - .indirect_symbol _ffi64_struct_to_ram_form - mflr r0 - bcl 20,31,LO$ffi64_struct_to_ram_form - -LO$ffi64_struct_to_ram_form: - mflr r11 - addis r11,r11,ha16(L_ffi64_struct_to_ram_form$lazy_ptr - LO$ffi64_struct_to_ram_form) - mtlr r0 - lgu r12,lo16(L_ffi64_struct_to_ram_form$lazy_ptr - LO$ffi64_struct_to_ram_form)(r11) - mtctr r12 - bctr - -.lazy_symbol_pointer -L_ffi64_struct_to_ram_form$lazy_ptr: - .indirect_symbol _ffi64_struct_to_ram_form - .g_long dyld_stub_binding_helper - -#endif // __ppc64__ -#endif // __ppc__ || __ppc64__ diff --git a/Modules/_ctypes/libffi_osx/powerpc/ppc-darwin.h b/Modules/_ctypes/libffi_osx/powerpc/ppc-darwin.h deleted file mode 100644 index cf4bd50f..00000000 --- a/Modules/_ctypes/libffi_osx/powerpc/ppc-darwin.h +++ /dev/null @@ -1,85 +0,0 @@ -/* ----------------------------------------------------------------------- - ppc-darwin.h - Copyright (c) 2002, 2003, 2004, Free Software Foundation, - Inc. - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ - -#define L(x) x - -#define SF_ARG9 MODE_CHOICE(56,112) -#define SF_ARG10 MODE_CHOICE(60,120) -#define SF_ARG11 MODE_CHOICE(64,128) -#define SF_ARG12 MODE_CHOICE(68,136) -#define SF_ARG13 MODE_CHOICE(72,144) -#define SF_ARG14 MODE_CHOICE(76,152) -#define SF_ARG15 MODE_CHOICE(80,160) -#define SF_ARG16 MODE_CHOICE(84,168) -#define SF_ARG17 MODE_CHOICE(88,176) -#define SF_ARG18 MODE_CHOICE(92,184) -#define SF_ARG19 MODE_CHOICE(96,192) -#define SF_ARG20 MODE_CHOICE(100,200) -#define SF_ARG21 MODE_CHOICE(104,208) -#define SF_ARG22 MODE_CHOICE(108,216) -#define SF_ARG23 MODE_CHOICE(112,224) -#define SF_ARG24 MODE_CHOICE(116,232) -#define SF_ARG25 MODE_CHOICE(120,240) -#define SF_ARG26 MODE_CHOICE(124,248) -#define SF_ARG27 MODE_CHOICE(128,256) -#define SF_ARG28 MODE_CHOICE(132,264) -#define SF_ARG29 MODE_CHOICE(136,272) - -#define ASM_NEEDS_REGISTERS 4 -#define NUM_GPR_ARG_REGISTERS 8 -#define NUM_FPR_ARG_REGISTERS 13 - -#define FFI_TYPE_1_BYTE(x) ((x) == FFI_TYPE_UINT8 || (x) == FFI_TYPE_SINT8) -#define FFI_TYPE_2_BYTE(x) ((x) == FFI_TYPE_UINT16 || (x) == FFI_TYPE_SINT16) -#define FFI_TYPE_4_BYTE(x) \ - ((x) == FFI_TYPE_UINT32 || (x) == FFI_TYPE_SINT32 ||\ - (x) == FFI_TYPE_INT || (x) == FFI_TYPE_FLOAT) - -#if !defined(LIBFFI_ASM) - -enum { - FLAG_RETURNS_NOTHING = 1 << (31 - 30), // cr7 - FLAG_RETURNS_FP = 1 << (31 - 29), - FLAG_RETURNS_64BITS = 1 << (31 - 28), - FLAG_RETURNS_128BITS = 1 << (31 - 31), - - FLAG_RETURNS_STRUCT = 1 << (31 - 27), // cr6 - FLAG_STRUCT_CONTAINS_FP = 1 << (31 - 26), - - FLAG_ARG_NEEDS_COPY = 1 << (31 - 7), - FLAG_FP_ARGUMENTS = 1 << (31 - 6), // cr1.eq; specified by ABI - FLAG_4_GPR_ARGUMENTS = 1 << (31 - 5), - FLAG_RETVAL_REFERENCE = 1 << (31 - 4) -}; - -#if defined(__ppc64__) -void ffi64_struct_to_ram_form(const ffi_type*, const char*, unsigned int*, - const char*, unsigned int*, unsigned int*, char*, unsigned int*); -void ffi64_struct_to_reg_form(const ffi_type*, const char*, unsigned int*, - unsigned int*, char*, unsigned int*, char*, unsigned int*); -bool ffi64_stret_needs_ptr(const ffi_type* inType, - unsigned short*, unsigned short*); -#endif - -#endif // !defined(LIBFFI_ASM) \ No newline at end of file diff --git a/Modules/_ctypes/libffi_osx/powerpc/ppc-darwin_closure.S b/Modules/_ctypes/libffi_osx/powerpc/ppc-darwin_closure.S deleted file mode 100644 index c3d30c25..00000000 --- a/Modules/_ctypes/libffi_osx/powerpc/ppc-darwin_closure.S +++ /dev/null @@ -1,308 +0,0 @@ -#if defined(__ppc__) - -/* ----------------------------------------------------------------------- - ppc-darwin_closure.S - Copyright (c) 2002, 2003, 2004, Free Software Foundation, - Inc. based on ppc_closure.S - - PowerPC Assembly glue. - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ - -#define LIBFFI_ASM - -#include <ffi.h> -#include <ppc-ffitarget.h> // for FFI_TRAMPOLINE_SIZE -#include <ppc-darwin.h> -#include <architecture/ppc/mode_independent_asm.h> - - .file "ppc-darwin_closure.S" -.text - .align LOG2_GPR_BYTES - .globl _ffi_closure_ASM - -.text - .align LOG2_GPR_BYTES - -_ffi_closure_ASM: -LFB1: - mflr r0 // Save return address - stg r0,SF_RETURN(r1) - -LCFI0: - /* 24/48 bytes (Linkage Area) - 32/64 bytes (outgoing parameter area, always reserved) - 104 bytes (13*8 from FPR) - 16/32 bytes (result) - 176/232 total bytes */ - - /* skip over caller save area and keep stack aligned to 16/32. */ - stgu r1,-SF_ROUND(176)(r1) - -LCFI1: - /* We want to build up an area for the parameters passed - in registers. (both floating point and integer) */ - - /* 176/256 bytes (callee stack frame aligned to 16/32) - 24/48 bytes (caller linkage area) - 200/304 (start of caller parameter area aligned to 4/8) - */ - - /* Save GPRs 3 - 10 (aligned to 4/8) - in the parents outgoing area. */ - stg r3,200(r1) - stg r4,204(r1) - stg r5,208(r1) - stg r6,212(r1) - stg r7,216(r1) - stg r8,220(r1) - stg r9,224(r1) - stg r10,228(r1) - - /* Save FPRs 1 - 13. (aligned to 8) */ - stfd f1,56(r1) - stfd f2,64(r1) - stfd f3,72(r1) - stfd f4,80(r1) - stfd f5,88(r1) - stfd f6,96(r1) - stfd f7,104(r1) - stfd f8,112(r1) - stfd f9,120(r1) - stfd f10,128(r1) - stfd f11,136(r1) - stfd f12,144(r1) - stfd f13,152(r1) - - // Set up registers for the routine that actually does the work. - mr r3,r11 // context pointer from the trampoline - addi r4,r1,160 // result storage - addi r5,r1,200 // saved GPRs - addi r6,r1,56 // saved FPRs - bl Lffi_closure_helper_DARWIN$stub - - /* Now r3 contains the return type. Use it to look up in a table - so we know how to deal with each type. */ - addi r5,r1,160 // Copy result storage pointer. - bl Lget_ret_type0_addr // Get pointer to Lret_type0 into LR. - mflr r4 // Move to r4. - slwi r3,r3,4 // Multiply return type by 16. - add r3,r3,r4 // Add contents of table to table address. - mtctr r3 - bctr - -LFE1: -/* Each of the ret_typeX code fragments has to be exactly 16 bytes long - (4 instructions). For cache effectiveness we align to a 16 byte boundary - first. */ - .align 4 - nop - nop - nop - -Lget_ret_type0_addr: - blrl - -/* case FFI_TYPE_VOID */ -Lret_type0: - b Lfinish - nop - nop - nop - -/* case FFI_TYPE_INT */ -Lret_type1: - lwz r3,0(r5) - b Lfinish - nop - nop - -/* case FFI_TYPE_FLOAT */ -Lret_type2: - lfs f1,0(r5) - b Lfinish - nop - nop - -/* case FFI_TYPE_DOUBLE */ -Lret_type3: - lfd f1,0(r5) - b Lfinish - nop - nop - -/* case FFI_TYPE_LONGDOUBLE */ -Lret_type4: - lfd f1,0(r5) - lfd f2,8(r5) - b Lfinish - nop - -/* case FFI_TYPE_UINT8 */ -Lret_type5: - lbz r3,3(r5) - b Lfinish - nop - nop - -/* case FFI_TYPE_SINT8 */ -Lret_type6: - lbz r3,3(r5) - extsb r3,r3 - b Lfinish - nop - -/* case FFI_TYPE_UINT16 */ -Lret_type7: - lhz r3,2(r5) - b Lfinish - nop - nop - -/* case FFI_TYPE_SINT16 */ -Lret_type8: - lha r3,2(r5) - b Lfinish - nop - nop - -/* case FFI_TYPE_UINT32 */ -Lret_type9: // same as Lret_type1 - lwz r3,0(r5) - b Lfinish - nop - nop - -/* case FFI_TYPE_SINT32 */ -Lret_type10: // same as Lret_type1 - lwz r3,0(r5) - b Lfinish - nop - nop - -/* case FFI_TYPE_UINT64 */ -Lret_type11: - lwz r3,0(r5) - lwz r4,4(r5) - b Lfinish - nop - -/* case FFI_TYPE_SINT64 */ -Lret_type12: // same as Lret_type11 - lwz r3,0(r5) - lwz r4,4(r5) - b Lfinish - nop - -/* case FFI_TYPE_STRUCT */ -Lret_type13: - b Lfinish - nop - nop - nop - -/* End 16-byte aligned cases */ -/* case FFI_TYPE_POINTER */ -// This case assumes that FFI_TYPE_POINTER == FFI_TYPE_LAST. If more types -// are added in future, the following code will need to be updated and -// padded to 16 bytes. -Lret_type14: - lg r3,0(r5) - // fall through - -/* case done */ -Lfinish: - addi r1,r1,SF_ROUND(176) // Restore stack pointer. - lg r0,SF_RETURN(r1) // Restore return address. - mtlr r0 // Restore link register. - blr - -/* END(ffi_closure_ASM) */ - -.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support -EH_frame1: - .set L$set$0,LECIE1-LSCIE1 - .long L$set$0 ; Length of Common Information Entry -LSCIE1: - .long 0x0 ; CIE Identifier Tag - .byte 0x1 ; CIE Version - .ascii "zR\0" ; CIE Augmentation - .byte 0x1 ; uleb128 0x1; CIE Code Alignment Factor - .byte 0x7c ; sleb128 -4; CIE Data Alignment Factor - .byte 0x41 ; CIE RA Column - .byte 0x1 ; uleb128 0x1; Augmentation size - .byte 0x10 ; FDE Encoding (pcrel) - .byte 0xc ; DW_CFA_def_cfa - .byte 0x1 ; uleb128 0x1 - .byte 0x0 ; uleb128 0x0 - .align LOG2_GPR_BYTES -LECIE1: -.globl _ffi_closure_ASM.eh -_ffi_closure_ASM.eh: -LSFDE1: - .set L$set$1,LEFDE1-LASFDE1 - .long L$set$1 ; FDE Length - -LASFDE1: - .long LASFDE1-EH_frame1 ; FDE CIE offset - .g_long LFB1-. ; FDE initial location - .set L$set$3,LFE1-LFB1 - .g_long L$set$3 ; FDE address range - .byte 0x0 ; uleb128 0x0; Augmentation size - .byte 0x4 ; DW_CFA_advance_loc4 - .set L$set$3,LCFI1-LCFI0 - .long L$set$3 - .byte 0xe ; DW_CFA_def_cfa_offset - .byte 176,1 ; uleb128 176 - .byte 0x4 ; DW_CFA_advance_loc4 - .set L$set$4,LCFI0-LFB1 - .long L$set$4 - .byte 0x11 ; DW_CFA_offset_extended_sf - .byte 0x41 ; uleb128 0x41 - .byte 0x7e ; sleb128 -2 - .align LOG2_GPR_BYTES - -LEFDE1: -.data - .align LOG2_GPR_BYTES -LDFCM0: -.section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32 - .align LOG2_GPR_BYTES - -Lffi_closure_helper_DARWIN$stub: - .indirect_symbol _ffi_closure_helper_DARWIN - mflr r0 - bcl 20,31,LO$ffi_closure_helper_DARWIN - -LO$ffi_closure_helper_DARWIN: - mflr r11 - addis r11,r11,ha16(L_ffi_closure_helper_DARWIN$lazy_ptr - LO$ffi_closure_helper_DARWIN) - mtlr r0 - lgu r12,lo16(L_ffi_closure_helper_DARWIN$lazy_ptr - LO$ffi_closure_helper_DARWIN)(r11) - mtctr r12 - bctr - -.lazy_symbol_pointer -L_ffi_closure_helper_DARWIN$lazy_ptr: - .indirect_symbol _ffi_closure_helper_DARWIN - .g_long dyld_stub_binding_helper - - -#endif // __ppc__ diff --git a/Modules/_ctypes/libffi_osx/powerpc/ppc-ffi_darwin.c b/Modules/_ctypes/libffi_osx/powerpc/ppc-ffi_darwin.c deleted file mode 100644 index 8953d5fd..00000000 --- a/Modules/_ctypes/libffi_osx/powerpc/ppc-ffi_darwin.c +++ /dev/null @@ -1,1776 +0,0 @@ -#if defined(__ppc__) || defined(__ppc64__) - -/* ----------------------------------------------------------------------- - ffi.c - Copyright (c) 1998 Geoffrey Keating - - PowerPC Foreign Function Interface - - Darwin ABI support (c) 2001 John Hornkvist - AIX ABI support (c) 2002 Free Software Foundation, Inc. - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ - -#include <ffi.h> -#include <ffi_common.h> - -#include <stdbool.h> -#include <stdio.h> -#include <stdlib.h> -#include <ppc-darwin.h> -#include <architecture/ppc/mode_independent_asm.h> - -#if 0 -#if defined(POWERPC_DARWIN) -#include <libkern/OSCacheControl.h> // for sys_icache_invalidate() -#endif - -#else - -#pragma weak sys_icache_invalidate -extern void sys_icache_invalidate(void *start, size_t len); - -#endif - - -extern void ffi_closure_ASM(void); - -// The layout of a function descriptor. A C function pointer really -// points to one of these. -typedef struct aix_fd_struct { - void* code_pointer; - void* toc; -} aix_fd; - -/* ffi_prep_args is called by the assembly routine once stack space - has been allocated for the function's arguments. - - The stack layout we want looks like this: - - | Return address from ffi_call_DARWIN | higher addresses - |--------------------------------------------| - | Previous backchain pointer 4/8 | stack pointer here - |--------------------------------------------|-\ <<< on entry to - | Saved r28-r31 (4/8)*4 | | ffi_call_DARWIN - |--------------------------------------------| | - | Parameters (at least 8*(4/8)=32/64) | | (176) +112 - +288 - |--------------------------------------------| | - | Space for GPR2 4/8 | | - |--------------------------------------------| | stack | - | Reserved (4/8)*2 | | grows | - |--------------------------------------------| | down V - | Space for callee's LR 4/8 | | - |--------------------------------------------| | lower addresses - | Saved CR 4/8 | | - |--------------------------------------------| | stack pointer here - | Current backchain pointer 4/8 | | during - |--------------------------------------------|-/ <<< ffi_call_DARWIN - - Note: ppc64 CR is saved in the low word of a long on the stack. -*/ - -/*@-exportheader@*/ -void -ffi_prep_args( - extended_cif* inEcif, - unsigned *const stack) -/*@=exportheader@*/ -{ - /* Copy the ecif to a local var so we can trample the arg. - BC note: test this with GP later for possible problems... */ - volatile extended_cif* ecif = inEcif; - - const unsigned bytes = ecif->cif->bytes; - const unsigned flags = ecif->cif->flags; - - /* Cast the stack arg from int* to long*. sizeof(long) == 4 in 32-bit mode - and 8 in 64-bit mode. */ - unsigned long *const longStack = (unsigned long *const)stack; - - /* 'stacktop' points at the previous backchain pointer. */ -#if defined(__ppc64__) - // In ppc-darwin.s, an extra 96 bytes is reserved for the linkage area, - // saved registers, and an extra FPR. - unsigned long *const stacktop = - (unsigned long *)(unsigned long)((char*)longStack + bytes + 96); -#elif defined(__ppc__) - unsigned long *const stacktop = longStack + (bytes / sizeof(long)); -#else -#error undefined architecture -#endif - - /* 'fpr_base' points at the space for fpr1, and grows upwards as - we use FPR registers. */ - double* fpr_base = (double*)(stacktop - ASM_NEEDS_REGISTERS) - - NUM_FPR_ARG_REGISTERS; - -#if defined(__ppc64__) - // 64-bit saves an extra register, and uses an extra FPR. Knock fpr_base - // down a couple pegs. - fpr_base -= 2; -#endif - - unsigned int fparg_count = 0; - - /* 'next_arg' grows up as we put parameters in it. */ - unsigned long* next_arg = longStack + 6; /* 6 reserved positions. */ - - int i; - double double_tmp; - void** p_argv = ecif->avalue; - unsigned long gprvalue; - ffi_type** ptr = ecif->cif->arg_types; - - /* Check that everything starts aligned properly. */ - FFI_ASSERT(stack == SF_ROUND(stack)); - FFI_ASSERT(stacktop == SF_ROUND(stacktop)); - FFI_ASSERT(bytes == SF_ROUND(bytes)); - - /* Deal with return values that are actually pass-by-reference. - Rule: - Return values are referenced by r3, so r4 is the first parameter. */ - - if (flags & FLAG_RETVAL_REFERENCE) - *next_arg++ = (unsigned long)(char*)ecif->rvalue; - - /* Now for the arguments. */ - for (i = ecif->cif->nargs; i > 0; i--, ptr++, p_argv++) - { - switch ((*ptr)->type) - { - /* If a floating-point parameter appears before all of the general- - purpose registers are filled, the corresponding GPRs that match - the size of the floating-point parameter are shadowed for the - benefit of vararg and pre-ANSI functions. */ - case FFI_TYPE_FLOAT: - double_tmp = *(float*)*p_argv; - - if (fparg_count < NUM_FPR_ARG_REGISTERS) - *fpr_base++ = double_tmp; - - *(double*)next_arg = double_tmp; - - next_arg++; - fparg_count++; - FFI_ASSERT(flags & FLAG_FP_ARGUMENTS); - - break; - - case FFI_TYPE_DOUBLE: - double_tmp = *(double*)*p_argv; - - if (fparg_count < NUM_FPR_ARG_REGISTERS) - *fpr_base++ = double_tmp; - - *(double*)next_arg = double_tmp; - - next_arg += MODE_CHOICE(2,1); - fparg_count++; - FFI_ASSERT(flags & FLAG_FP_ARGUMENTS); - - break; - -#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE - case FFI_TYPE_LONGDOUBLE: -#if defined(__ppc64__) - if (fparg_count < NUM_FPR_ARG_REGISTERS) - *(long double*)fpr_base = *(long double*)*p_argv; -#elif defined(__ppc__) - if (fparg_count < NUM_FPR_ARG_REGISTERS - 1) - *(long double*)fpr_base = *(long double*)*p_argv; - else if (fparg_count == NUM_FPR_ARG_REGISTERS - 1) - *(double*)fpr_base = *(double*)*p_argv; -#else -#error undefined architecture -#endif - - *(long double*)next_arg = *(long double*)*p_argv; - fparg_count += 2; - fpr_base += 2; - next_arg += MODE_CHOICE(4,2); - FFI_ASSERT(flags & FLAG_FP_ARGUMENTS); - - break; -#endif // FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE - - case FFI_TYPE_UINT64: - case FFI_TYPE_SINT64: -#if defined(__ppc64__) - gprvalue = *(long long*)*p_argv; - goto putgpr; -#elif defined(__ppc__) - *(long long*)next_arg = *(long long*)*p_argv; - next_arg += 2; - break; -#else -#error undefined architecture -#endif - - case FFI_TYPE_POINTER: - gprvalue = *(unsigned long*)*p_argv; - goto putgpr; - - case FFI_TYPE_UINT8: - gprvalue = *(unsigned char*)*p_argv; - goto putgpr; - - case FFI_TYPE_SINT8: - gprvalue = *(signed char*)*p_argv; - goto putgpr; - - case FFI_TYPE_UINT16: - gprvalue = *(unsigned short*)*p_argv; - goto putgpr; - - case FFI_TYPE_SINT16: - gprvalue = *(signed short*)*p_argv; - goto putgpr; - - case FFI_TYPE_STRUCT: - { -#if defined(__ppc64__) - unsigned int gprSize = 0; - unsigned int fprSize = 0; - - ffi64_struct_to_reg_form(*ptr, (char*)*p_argv, NULL, &fparg_count, - (char*)next_arg, &gprSize, (char*)fpr_base, &fprSize); - next_arg += gprSize / sizeof(long); - fpr_base += fprSize / sizeof(double); - -#elif defined(__ppc__) - char* dest_cpy = (char*)next_arg; - - /* Structures that match the basic modes (QI 1 byte, HI 2 bytes, - SI 4 bytes) are aligned as if they were those modes. - Structures with 3 byte in size are padded upwards. */ - unsigned size_al = (*ptr)->size; - - /* If the first member of the struct is a double, then align - the struct to double-word. */ - if ((*ptr)->elements[0]->type == FFI_TYPE_DOUBLE) - size_al = ALIGN((*ptr)->size, 8); - - if (ecif->cif->abi == FFI_DARWIN) - { - if (size_al < 3) - dest_cpy += 4 - size_al; - } - - memcpy((char*)dest_cpy, (char*)*p_argv, size_al); - next_arg += (size_al + 3) / 4; -#else -#error undefined architecture -#endif - break; - } - - case FFI_TYPE_INT: - case FFI_TYPE_UINT32: - case FFI_TYPE_SINT32: - gprvalue = *(unsigned*)*p_argv; - -putgpr: - *next_arg++ = gprvalue; - break; - - default: - break; - } - } - - /* Check that we didn't overrun the stack... */ - //FFI_ASSERT(gpr_base <= stacktop - ASM_NEEDS_REGISTERS); - //FFI_ASSERT((unsigned *)fpr_base - // <= stacktop - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS); - //FFI_ASSERT(flags & FLAG_4_GPR_ARGUMENTS || intarg_count <= 4); -} - -#if defined(__ppc64__) - -bool -ffi64_struct_contains_fp( - const ffi_type* inType) -{ - bool containsFP = false; - unsigned int i; - - for (i = 0; inType->elements[i] != NULL && !containsFP; i++) - { - if (inType->elements[i]->type == FFI_TYPE_FLOAT || - inType->elements[i]->type == FFI_TYPE_DOUBLE || - inType->elements[i]->type == FFI_TYPE_LONGDOUBLE) - containsFP = true; - else if (inType->elements[i]->type == FFI_TYPE_STRUCT) - containsFP = ffi64_struct_contains_fp(inType->elements[i]); - } - - return containsFP; -} - -#endif // defined(__ppc64__) - -/* Perform machine dependent cif processing. */ -ffi_status -ffi_prep_cif_machdep( - ffi_cif* cif) -{ - /* All this is for the DARWIN ABI. */ - int i; - ffi_type** ptr; - int intarg_count = 0; - int fparg_count = 0; - unsigned int flags = 0; - unsigned int size_al = 0; - - /* All the machine-independent calculation of cif->bytes will be wrong. - Redo the calculation for DARWIN. */ - - /* Space for the frame pointer, callee's LR, CR, etc, and for - the asm's temp regs. */ - unsigned int bytes = (6 + ASM_NEEDS_REGISTERS) * sizeof(long); - - /* Return value handling. The rules are as follows: - - 32-bit (or less) integer values are returned in gpr3; - - Structures of size <= 4 bytes also returned in gpr3; - - 64-bit integer values and structures between 5 and 8 bytes are - returned in gpr3 and gpr4; - - Single/double FP values are returned in fpr1; - - Long double FP (if not equivalent to double) values are returned in - fpr1 and fpr2; - - Larger structures values are allocated space and a pointer is passed - as the first argument. */ - switch (cif->rtype->type) - { -#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE - case FFI_TYPE_LONGDOUBLE: - flags |= FLAG_RETURNS_128BITS; - flags |= FLAG_RETURNS_FP; - break; -#endif // FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE - - case FFI_TYPE_DOUBLE: - flags |= FLAG_RETURNS_64BITS; - /* Fall through. */ - case FFI_TYPE_FLOAT: - flags |= FLAG_RETURNS_FP; - break; - -#if defined(__ppc64__) - case FFI_TYPE_POINTER: -#endif - case FFI_TYPE_UINT64: - case FFI_TYPE_SINT64: - flags |= FLAG_RETURNS_64BITS; - break; - - case FFI_TYPE_STRUCT: - { -#if defined(__ppc64__) - - if (ffi64_stret_needs_ptr(cif->rtype, NULL, NULL)) - { - flags |= FLAG_RETVAL_REFERENCE; - flags |= FLAG_RETURNS_NOTHING; - intarg_count++; - } - else - { - flags |= FLAG_RETURNS_STRUCT; - - if (ffi64_struct_contains_fp(cif->rtype)) - flags |= FLAG_STRUCT_CONTAINS_FP; - } - -#elif defined(__ppc__) - - flags |= FLAG_RETVAL_REFERENCE; - flags |= FLAG_RETURNS_NOTHING; - intarg_count++; - -#else -#error undefined architecture -#endif - break; - } - - case FFI_TYPE_VOID: - flags |= FLAG_RETURNS_NOTHING; - break; - - default: - /* Returns 32-bit integer, or similar. Nothing to do here. */ - break; - } - - /* The first NUM_GPR_ARG_REGISTERS words of integer arguments, and the - first NUM_FPR_ARG_REGISTERS fp arguments, go in registers; the rest - goes on the stack. Structures are passed as a pointer to a copy of - the structure. Stuff on the stack needs to keep proper alignment. */ - for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++) - { - switch ((*ptr)->type) - { - case FFI_TYPE_FLOAT: - case FFI_TYPE_DOUBLE: - fparg_count++; - /* If this FP arg is going on the stack, it must be - 8-byte-aligned. */ - if (fparg_count > NUM_FPR_ARG_REGISTERS - && intarg_count % 2 != 0) - intarg_count++; - break; - -#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE - case FFI_TYPE_LONGDOUBLE: - fparg_count += 2; - /* If this FP arg is going on the stack, it must be - 8-byte-aligned. */ - - if ( -#if defined(__ppc64__) - fparg_count > NUM_FPR_ARG_REGISTERS + 1 -#elif defined(__ppc__) - fparg_count > NUM_FPR_ARG_REGISTERS -#else -#error undefined architecture -#endif - && intarg_count % 2 != 0) - intarg_count++; - - intarg_count += 2; - break; -#endif // FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE - - case FFI_TYPE_UINT64: - case FFI_TYPE_SINT64: - /* 'long long' arguments are passed as two words, but - either both words must fit in registers or both go - on the stack. If they go on the stack, they must - be 8-byte-aligned. */ - if (intarg_count == NUM_GPR_ARG_REGISTERS - 1 - || (intarg_count >= NUM_GPR_ARG_REGISTERS - && intarg_count % 2 != 0)) - intarg_count++; - - intarg_count += MODE_CHOICE(2,1); - - break; - - case FFI_TYPE_STRUCT: - size_al = (*ptr)->size; - /* If the first member of the struct is a double, then align - the struct to double-word. */ - if ((*ptr)->elements[0]->type == FFI_TYPE_DOUBLE) - size_al = ALIGN((*ptr)->size, 8); - -#if defined(__ppc64__) - // Look for FP struct members. - unsigned int j; - - for (j = 0; (*ptr)->elements[j] != NULL; j++) - { - if ((*ptr)->elements[j]->type == FFI_TYPE_FLOAT || - (*ptr)->elements[j]->type == FFI_TYPE_DOUBLE) - { - fparg_count++; - - if (fparg_count > NUM_FPR_ARG_REGISTERS) - intarg_count++; - } - else if ((*ptr)->elements[j]->type == FFI_TYPE_LONGDOUBLE) - { - fparg_count += 2; - - if (fparg_count > NUM_FPR_ARG_REGISTERS + 1) - intarg_count += 2; - } - else - intarg_count++; - } -#elif defined(__ppc__) - intarg_count += (size_al + 3) / 4; -#else -#error undefined architecture -#endif - - break; - - default: - /* Everything else is passed as a 4/8-byte word in a GPR, either - the object itself or a pointer to it. */ - intarg_count++; - break; - } - } - - /* Space for the FPR registers, if needed. */ - if (fparg_count != 0) - { - flags |= FLAG_FP_ARGUMENTS; -#if defined(__ppc64__) - bytes += (NUM_FPR_ARG_REGISTERS + 1) * sizeof(double); -#elif defined(__ppc__) - bytes += NUM_FPR_ARG_REGISTERS * sizeof(double); -#else -#error undefined architecture -#endif - } - - /* Stack space. */ -#if defined(__ppc64__) - if ((intarg_count + fparg_count) > NUM_GPR_ARG_REGISTERS) - bytes += (intarg_count + fparg_count) * sizeof(long); -#elif defined(__ppc__) - if ((intarg_count + 2 * fparg_count) > NUM_GPR_ARG_REGISTERS) - bytes += (intarg_count + 2 * fparg_count) * sizeof(long); -#else -#error undefined architecture -#endif - else - bytes += NUM_GPR_ARG_REGISTERS * sizeof(long); - - /* The stack space allocated needs to be a multiple of 16/32 bytes. */ - bytes = SF_ROUND(bytes); - - cif->flags = flags; - cif->bytes = bytes; - - return FFI_OK; -} - -/*@-declundef@*/ -/*@-exportheader@*/ -extern void -ffi_call_AIX( -/*@out@*/ extended_cif*, - unsigned, - unsigned, -/*@out@*/ unsigned*, - void (*fn)(void), - void (*fn2)(extended_cif*, unsigned *const)); - -extern void -ffi_call_DARWIN( -/*@out@*/ extended_cif*, - unsigned long, - unsigned, -/*@out@*/ unsigned*, - void (*fn)(void), - void (*fn2)(extended_cif*, unsigned *const)); -/*@=declundef@*/ -/*@=exportheader@*/ - -void -ffi_call( -/*@dependent@*/ ffi_cif* cif, - void (*fn)(void), -/*@out@*/ void* rvalue, -/*@dependent@*/ void** avalue) -{ - extended_cif ecif; - - ecif.cif = cif; - ecif.avalue = avalue; - - /* If the return value is a struct and we don't have a return - value address then we need to make one. */ - if ((rvalue == NULL) && - (cif->rtype->type == FFI_TYPE_STRUCT)) - { - /*@-sysunrecog@*/ - ecif.rvalue = alloca(cif->rtype->size); - /*@=sysunrecog@*/ - } - else - ecif.rvalue = rvalue; - - switch (cif->abi) - { - case FFI_AIX: - /*@-usedef@*/ - ffi_call_AIX(&ecif, -cif->bytes, - cif->flags, ecif.rvalue, fn, ffi_prep_args); - /*@=usedef@*/ - break; - - case FFI_DARWIN: - /*@-usedef@*/ - ffi_call_DARWIN(&ecif, -(long)cif->bytes, - cif->flags, ecif.rvalue, fn, ffi_prep_args); - /*@=usedef@*/ - break; - - default: - FFI_ASSERT(0); - break; - } -} - -/* here I'd like to add the stack frame layout we use in darwin_closure.S - and aix_clsoure.S - - SP previous -> +---------------------------------------+ <--- child frame - | back chain to caller 4 | - +---------------------------------------+ 4 - | saved CR 4 | - +---------------------------------------+ 8 - | saved LR 4 | - +---------------------------------------+ 12 - | reserved for compilers 4 | - +---------------------------------------+ 16 - | reserved for binders 4 | - +---------------------------------------+ 20 - | saved TOC pointer 4 | - +---------------------------------------+ 24 - | always reserved 8*4=32 (previous GPRs)| - | according to the linkage convention | - | from AIX | - +---------------------------------------+ 56 - | our FPR area 13*8=104 | - | f1 | - | . | - | f13 | - +---------------------------------------+ 160 - | result area 8 | - +---------------------------------------+ 168 - | alignement to the next multiple of 16 | -SP current --> +---------------------------------------+ 176 <- parent frame - | back chain to caller 4 | - +---------------------------------------+ 180 - | saved CR 4 | - +---------------------------------------+ 184 - | saved LR 4 | - +---------------------------------------+ 188 - | reserved for compilers 4 | - +---------------------------------------+ 192 - | reserved for binders 4 | - +---------------------------------------+ 196 - | saved TOC pointer 4 | - +---------------------------------------+ 200 - | always reserved 8*4=32 we store our | - | GPRs here | - | r3 | - | . | - | r10 | - +---------------------------------------+ 232 - | overflow part | - +---------------------------------------+ xxx - | ???? | - +---------------------------------------+ xxx -*/ - -#if !defined(POWERPC_DARWIN) - -#define MIN_LINE_SIZE 32 - -static void -flush_icache( - char* addr) -{ -#ifndef _AIX - __asm__ volatile ( - "dcbf 0,%0\n" - "sync\n" - "icbi 0,%0\n" - "sync\n" - "isync" - : : "r" (addr) : "memory"); -#endif -} - -static void -flush_range( - char* addr, - int size) -{ - int i; - - for (i = 0; i < size; i += MIN_LINE_SIZE) - flush_icache(addr + i); - - flush_icache(addr + size - 1); -} - -#endif // !defined(POWERPC_DARWIN) - -ffi_status -ffi_prep_closure( - ffi_closure* closure, - ffi_cif* cif, - void (*fun)(ffi_cif*, void*, void**, void*), - void* user_data) -{ - switch (cif->abi) - { - case FFI_DARWIN: - { - FFI_ASSERT (cif->abi == FFI_DARWIN); - - unsigned int* tramp = (unsigned int*)&closure->tramp[0]; - -#if defined(__ppc64__) - tramp[0] = 0x7c0802a6; // mflr r0 - tramp[1] = 0x429f0005; // bcl 20,31,+0x8 - tramp[2] = 0x7d6802a6; // mflr r11 - tramp[3] = 0x7c0803a6; // mtlr r0 - tramp[4] = 0xe98b0018; // ld r12,24(r11) - tramp[5] = 0x7d8903a6; // mtctr r12 - tramp[6] = 0xe96b0020; // ld r11,32(r11) - tramp[7] = 0x4e800420; // bctr - *(unsigned long*)&tramp[8] = (unsigned long)ffi_closure_ASM; - *(unsigned long*)&tramp[10] = (unsigned long)closure; -#elif defined(__ppc__) - tramp[0] = 0x7c0802a6; // mflr r0 - tramp[1] = 0x429f0005; // bcl 20,31,+0x8 - tramp[2] = 0x7d6802a6; // mflr r11 - tramp[3] = 0x7c0803a6; // mtlr r0 - tramp[4] = 0x818b0018; // lwz r12,24(r11) - tramp[5] = 0x7d8903a6; // mtctr r12 - tramp[6] = 0x816b001c; // lwz r11,28(r11) - tramp[7] = 0x4e800420; // bctr - tramp[8] = (unsigned long)ffi_closure_ASM; - tramp[9] = (unsigned long)closure; -#else -#error undefined architecture -#endif - - closure->cif = cif; - closure->fun = fun; - closure->user_data = user_data; - - // Flush the icache. Only necessary on Darwin. -#if defined(POWERPC_DARWIN) - sys_icache_invalidate(closure->tramp, FFI_TRAMPOLINE_SIZE); -#else - flush_range(closure->tramp, FFI_TRAMPOLINE_SIZE); -#endif - - break; - } - - case FFI_AIX: - { - FFI_ASSERT (cif->abi == FFI_AIX); - - ffi_aix_trampoline_struct* tramp_aix = - (ffi_aix_trampoline_struct*)(closure->tramp); - aix_fd* fd = (aix_fd*)(void*)ffi_closure_ASM; - - tramp_aix->code_pointer = fd->code_pointer; - tramp_aix->toc = fd->toc; - tramp_aix->static_chain = closure; - closure->cif = cif; - closure->fun = fun; - closure->user_data = user_data; - break; - } - - default: - return FFI_BAD_ABI; - } - - return FFI_OK; -} - -#if defined(__ppc__) - typedef double ldbits[2]; - - typedef union - { - ldbits lb; - long double ld; - } ldu; -#endif - -typedef union -{ - float f; - double d; -} ffi_dblfl; - -/* The trampoline invokes ffi_closure_ASM, and on entry, r11 holds the - address of the closure. After storing the registers that could possibly - contain parameters to be passed into the stack frame and setting up space - for a return value, ffi_closure_ASM invokes the following helper function - to do most of the work. */ -int -ffi_closure_helper_DARWIN( - ffi_closure* closure, - void* rvalue, - unsigned long* pgr, - ffi_dblfl* pfr) -{ - /* rvalue is the pointer to space for return value in closure assembly - pgr is the pointer to where r3-r10 are stored in ffi_closure_ASM - pfr is the pointer to where f1-f13 are stored in ffi_closure_ASM. */ - -#if defined(__ppc__) - ldu temp_ld; -#endif - - double temp; - unsigned int i; - unsigned int nf = 0; /* number of FPRs already used. */ - unsigned int ng = 0; /* number of GPRs already used. */ - ffi_cif* cif = closure->cif; - long avn = cif->nargs; - void** avalue = alloca(cif->nargs * sizeof(void*)); - ffi_type** arg_types = cif->arg_types; - - /* Copy the caller's structure return value address so that the closure - returns the data directly to the caller. */ -#if defined(__ppc64__) - if (cif->rtype->type == FFI_TYPE_STRUCT && - ffi64_stret_needs_ptr(cif->rtype, NULL, NULL)) -#elif defined(__ppc__) - if (cif->rtype->type == FFI_TYPE_STRUCT) -#else -#error undefined architecture -#endif - { - rvalue = (void*)*pgr; - pgr++; - ng++; - } - - /* Grab the addresses of the arguments from the stack frame. */ - for (i = 0; i < avn; i++) - { - switch (arg_types[i]->type) - { - case FFI_TYPE_SINT8: - case FFI_TYPE_UINT8: - avalue[i] = (char*)pgr + MODE_CHOICE(3,7); - ng++; - pgr++; - break; - - case FFI_TYPE_SINT16: - case FFI_TYPE_UINT16: - avalue[i] = (char*)pgr + MODE_CHOICE(2,6); - ng++; - pgr++; - break; - -#if defined(__ppc__) - case FFI_TYPE_POINTER: -#endif - case FFI_TYPE_SINT32: - case FFI_TYPE_UINT32: - avalue[i] = (char*)pgr + MODE_CHOICE(0,4); - ng++; - pgr++; - - break; - - case FFI_TYPE_STRUCT: - if (cif->abi == FFI_DARWIN) - { -#if defined(__ppc64__) - unsigned int gprSize = 0; - unsigned int fprSize = 0; - unsigned int savedFPRSize = fprSize; - - avalue[i] = alloca(arg_types[i]->size); - ffi64_struct_to_ram_form(arg_types[i], (const char*)pgr, - &gprSize, (const char*)pfr, &fprSize, &nf, avalue[i], NULL); - - ng += gprSize / sizeof(long); - pgr += gprSize / sizeof(long); - pfr += (fprSize - savedFPRSize) / sizeof(double); - -#elif defined(__ppc__) - /* Structures that match the basic modes (QI 1 byte, HI 2 bytes, - SI 4 bytes) are aligned as if they were those modes. */ - unsigned int size_al = size_al = arg_types[i]->size; - - /* If the first member of the struct is a double, then align - the struct to double-word. */ - if (arg_types[i]->elements[0]->type == FFI_TYPE_DOUBLE) - size_al = ALIGN(arg_types[i]->size, 8); - - if (size_al < 3) - avalue[i] = (void*)pgr + MODE_CHOICE(4,8) - size_al; - else - avalue[i] = (void*)pgr; - - ng += (size_al + 3) / sizeof(long); - pgr += (size_al + 3) / sizeof(long); -#else -#error undefined architecture -#endif - } - - break; - -#if defined(__ppc64__) - case FFI_TYPE_POINTER: -#endif - case FFI_TYPE_SINT64: - case FFI_TYPE_UINT64: - /* Long long ints are passed in 1 or 2 GPRs. */ - avalue[i] = pgr; - ng += MODE_CHOICE(2,1); - pgr += MODE_CHOICE(2,1); - - break; - - case FFI_TYPE_FLOAT: - /* A float value consumes a GPR. - There are 13 64-bit floating point registers. */ - if (nf < NUM_FPR_ARG_REGISTERS) - { - temp = pfr->d; - pfr->f = (float)temp; - avalue[i] = pfr; - pfr++; - } - else - avalue[i] = pgr; - - nf++; - ng++; - pgr++; - break; - - case FFI_TYPE_DOUBLE: - /* A double value consumes one or two GPRs. - There are 13 64bit floating point registers. */ - if (nf < NUM_FPR_ARG_REGISTERS) - { - avalue[i] = pfr; - pfr++; - } - else - avalue[i] = pgr; - - nf++; - ng += MODE_CHOICE(2,1); - pgr += MODE_CHOICE(2,1); - - break; - -#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE - - case FFI_TYPE_LONGDOUBLE: -#if defined(__ppc64__) - if (nf < NUM_FPR_ARG_REGISTERS) - { - avalue[i] = pfr; - pfr += 2; - } -#elif defined(__ppc__) - /* A long double value consumes 2/4 GPRs and 2 FPRs. - There are 13 64bit floating point registers. */ - if (nf < NUM_FPR_ARG_REGISTERS - 1) - { - avalue[i] = pfr; - pfr += 2; - } - /* Here we have the situation where one part of the long double - is stored in fpr13 and the other part is already on the stack. - We use a union to pass the long double to avalue[i]. */ - else if (nf == NUM_FPR_ARG_REGISTERS - 1) - { - memcpy (&temp_ld.lb[0], pfr, sizeof(temp_ld.lb[0])); - memcpy (&temp_ld.lb[1], pgr + 2, sizeof(temp_ld.lb[1])); - avalue[i] = &temp_ld.ld; - } -#else -#error undefined architecture -#endif - else - avalue[i] = pgr; - - nf += 2; - ng += MODE_CHOICE(4,2); - pgr += MODE_CHOICE(4,2); - - break; - -#endif /* FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE */ - - default: - FFI_ASSERT(0); - break; - } - } - - (closure->fun)(cif, rvalue, avalue, closure->user_data); - - /* Tell ffi_closure_ASM to perform return type promotions. */ - return cif->rtype->type; -} - -#if defined(__ppc64__) - -/* ffi64_struct_to_ram_form - - Rebuild a struct's natural layout from buffers of concatenated registers. - Return the number of registers used. - inGPRs[0-7] == r3, inFPRs[0-7] == f1 ... -*/ -void -ffi64_struct_to_ram_form( - const ffi_type* inType, - const char* inGPRs, - unsigned int* ioGPRMarker, - const char* inFPRs, - unsigned int* ioFPRMarker, - unsigned int* ioFPRsUsed, - char* outStruct, // caller-allocated - unsigned int* ioStructMarker) -{ - unsigned int srcGMarker = 0; - unsigned int srcFMarker = 0; - unsigned int savedFMarker = 0; - unsigned int fprsUsed = 0; - unsigned int savedFPRsUsed = 0; - unsigned int destMarker = 0; - - static unsigned int recurseCount = 0; - - if (ioGPRMarker) - srcGMarker = *ioGPRMarker; - - if (ioFPRMarker) - { - srcFMarker = *ioFPRMarker; - savedFMarker = srcFMarker; - } - - if (ioFPRsUsed) - { - fprsUsed = *ioFPRsUsed; - savedFPRsUsed = fprsUsed; - } - - if (ioStructMarker) - destMarker = *ioStructMarker; - - size_t i; - - switch (inType->size) - { - case 1: case 2: case 4: - srcGMarker += 8 - inType->size; - break; - - default: - break; - } - - for (i = 0; inType->elements[i] != NULL; i++) - { - switch (inType->elements[i]->type) - { - case FFI_TYPE_FLOAT: - srcFMarker = ALIGN(srcFMarker, 4); - srcGMarker = ALIGN(srcGMarker, 4); - destMarker = ALIGN(destMarker, 4); - - if (fprsUsed < NUM_FPR_ARG_REGISTERS) - { - *(float*)&outStruct[destMarker] = - (float)*(double*)&inFPRs[srcFMarker]; - srcFMarker += 8; - fprsUsed++; - } - else - *(float*)&outStruct[destMarker] = - (float)*(double*)&inGPRs[srcGMarker]; - - srcGMarker += 4; - destMarker += 4; - - // Skip to next GPR if next element won't fit and we're - // not already at a register boundary. - if (inType->elements[i + 1] != NULL && (destMarker % 8)) - { - if (!FFI_TYPE_1_BYTE(inType->elements[i + 1]->type) && - (!FFI_TYPE_2_BYTE(inType->elements[i + 1]->type) || - (ALIGN(srcGMarker, 8) - srcGMarker) < 2) && - (!FFI_TYPE_4_BYTE(inType->elements[i + 1]->type) || - (ALIGN(srcGMarker, 8) - srcGMarker) < 4)) - srcGMarker = ALIGN(srcGMarker, 8); - } - - break; - - case FFI_TYPE_DOUBLE: - srcFMarker = ALIGN(srcFMarker, 8); - destMarker = ALIGN(destMarker, 8); - - if (fprsUsed < NUM_FPR_ARG_REGISTERS) - { - *(double*)&outStruct[destMarker] = - *(double*)&inFPRs[srcFMarker]; - srcFMarker += 8; - fprsUsed++; - } - else - *(double*)&outStruct[destMarker] = - *(double*)&inGPRs[srcGMarker]; - - destMarker += 8; - - // Skip next GPR - srcGMarker += 8; - srcGMarker = ALIGN(srcGMarker, 8); - - break; - - case FFI_TYPE_LONGDOUBLE: - destMarker = ALIGN(destMarker, 16); - - if (fprsUsed < NUM_FPR_ARG_REGISTERS) - { - srcFMarker = ALIGN(srcFMarker, 8); - srcGMarker = ALIGN(srcGMarker, 8); - *(long double*)&outStruct[destMarker] = - *(long double*)&inFPRs[srcFMarker]; - srcFMarker += 16; - fprsUsed += 2; - } - else - { - srcFMarker = ALIGN(srcFMarker, 16); - srcGMarker = ALIGN(srcGMarker, 16); - *(long double*)&outStruct[destMarker] = - *(long double*)&inGPRs[srcGMarker]; - } - - destMarker += 16; - - // Skip next 2 GPRs - srcGMarker += 16; - srcGMarker = ALIGN(srcGMarker, 8); - - break; - - case FFI_TYPE_UINT8: - case FFI_TYPE_SINT8: - { - if (inType->alignment == 1) // chars only - { - if (inType->size == 1) - outStruct[destMarker++] = inGPRs[srcGMarker++]; - else if (inType->size == 2) - { - outStruct[destMarker++] = inGPRs[srcGMarker++]; - outStruct[destMarker++] = inGPRs[srcGMarker++]; - i++; - } - else - { - memcpy(&outStruct[destMarker], - &inGPRs[srcGMarker], inType->size); - srcGMarker += inType->size; - destMarker += inType->size; - i += inType->size - 1; - } - } - else // chars and other stuff - { - outStruct[destMarker++] = inGPRs[srcGMarker++]; - - // Skip to next GPR if next element won't fit and we're - // not already at a register boundary. - if (inType->elements[i + 1] != NULL && (srcGMarker % 8)) - { - if (!FFI_TYPE_1_BYTE(inType->elements[i + 1]->type) && - (!FFI_TYPE_2_BYTE(inType->elements[i + 1]->type) || - (ALIGN(srcGMarker, 8) - srcGMarker) < 2) && - (!FFI_TYPE_4_BYTE(inType->elements[i + 1]->type) || - (ALIGN(srcGMarker, 8) - srcGMarker) < 4)) - srcGMarker = ALIGN(srcGMarker, inType->alignment); // was 8 - } - } - - break; - } - - case FFI_TYPE_UINT16: - case FFI_TYPE_SINT16: - srcGMarker = ALIGN(srcGMarker, 2); - destMarker = ALIGN(destMarker, 2); - - *(short*)&outStruct[destMarker] = - *(short*)&inGPRs[srcGMarker]; - srcGMarker += 2; - destMarker += 2; - - break; - - case FFI_TYPE_INT: - case FFI_TYPE_UINT32: - case FFI_TYPE_SINT32: - srcGMarker = ALIGN(srcGMarker, 4); - destMarker = ALIGN(destMarker, 4); - - *(int*)&outStruct[destMarker] = - *(int*)&inGPRs[srcGMarker]; - srcGMarker += 4; - destMarker += 4; - - break; - - case FFI_TYPE_POINTER: - case FFI_TYPE_UINT64: - case FFI_TYPE_SINT64: - srcGMarker = ALIGN(srcGMarker, 8); - destMarker = ALIGN(destMarker, 8); - - *(long long*)&outStruct[destMarker] = - *(long long*)&inGPRs[srcGMarker]; - srcGMarker += 8; - destMarker += 8; - - break; - - case FFI_TYPE_STRUCT: - recurseCount++; - ffi64_struct_to_ram_form(inType->elements[i], inGPRs, - &srcGMarker, inFPRs, &srcFMarker, &fprsUsed, - outStruct, &destMarker); - recurseCount--; - break; - - default: - FFI_ASSERT(0); // unknown element type - break; - } - } - - srcGMarker = ALIGN(srcGMarker, inType->alignment); - - // Take care of the special case for 16-byte structs, but not for - // nested structs. - if (recurseCount == 0 && srcGMarker == 16) - { - *(long double*)&outStruct[0] = *(long double*)&inGPRs[0]; - srcFMarker = savedFMarker; - fprsUsed = savedFPRsUsed; - } - - if (ioGPRMarker) - *ioGPRMarker = ALIGN(srcGMarker, 8); - - if (ioFPRMarker) - *ioFPRMarker = srcFMarker; - - if (ioFPRsUsed) - *ioFPRsUsed = fprsUsed; - - if (ioStructMarker) - *ioStructMarker = ALIGN(destMarker, 8); -} - -/* ffi64_struct_to_reg_form - - Copy a struct's elements into buffers that can be sliced into registers. - Return the sizes of the output buffers in bytes. Pass NULL buffer pointers - to calculate size only. - outGPRs[0-7] == r3, outFPRs[0-7] == f1 ... -*/ -void -ffi64_struct_to_reg_form( - const ffi_type* inType, - const char* inStruct, - unsigned int* ioStructMarker, - unsigned int* ioFPRsUsed, - char* outGPRs, // caller-allocated - unsigned int* ioGPRSize, - char* outFPRs, // caller-allocated - unsigned int* ioFPRSize) -{ - size_t i; - unsigned int srcMarker = 0; - unsigned int destGMarker = 0; - unsigned int destFMarker = 0; - unsigned int savedFMarker = 0; - unsigned int fprsUsed = 0; - unsigned int savedFPRsUsed = 0; - - static unsigned int recurseCount = 0; - - if (ioStructMarker) - srcMarker = *ioStructMarker; - - if (ioFPRsUsed) - { - fprsUsed = *ioFPRsUsed; - savedFPRsUsed = fprsUsed; - } - - if (ioGPRSize) - destGMarker = *ioGPRSize; - - if (ioFPRSize) - { - destFMarker = *ioFPRSize; - savedFMarker = destFMarker; - } - - switch (inType->size) - { - case 1: case 2: case 4: - destGMarker += 8 - inType->size; - break; - - default: - break; - } - - for (i = 0; inType->elements[i] != NULL; i++) - { - switch (inType->elements[i]->type) - { - // Shadow floating-point types in GPRs for vararg and pre-ANSI - // functions. - case FFI_TYPE_FLOAT: - // Nudge markers to next 4/8-byte boundary - srcMarker = ALIGN(srcMarker, 4); - destGMarker = ALIGN(destGMarker, 4); - destFMarker = ALIGN(destFMarker, 8); - - if (fprsUsed < NUM_FPR_ARG_REGISTERS) - { - if (outFPRs != NULL && inStruct != NULL) - *(double*)&outFPRs[destFMarker] = - (double)*(float*)&inStruct[srcMarker]; - - destFMarker += 8; - fprsUsed++; - } - - if (outGPRs != NULL && inStruct != NULL) - *(double*)&outGPRs[destGMarker] = - (double)*(float*)&inStruct[srcMarker]; - - srcMarker += 4; - destGMarker += 4; - - // Skip to next GPR if next element won't fit and we're - // not already at a register boundary. - if (inType->elements[i + 1] != NULL && (srcMarker % 8)) - { - if (!FFI_TYPE_1_BYTE(inType->elements[i + 1]->type) && - (!FFI_TYPE_2_BYTE(inType->elements[i + 1]->type) || - (ALIGN(destGMarker, 8) - destGMarker) < 2) && - (!FFI_TYPE_4_BYTE(inType->elements[i + 1]->type) || - (ALIGN(destGMarker, 8) - destGMarker) < 4)) - destGMarker = ALIGN(destGMarker, 8); - } - - break; - - case FFI_TYPE_DOUBLE: - srcMarker = ALIGN(srcMarker, 8); - destFMarker = ALIGN(destFMarker, 8); - - if (fprsUsed < NUM_FPR_ARG_REGISTERS) - { - if (outFPRs != NULL && inStruct != NULL) - *(double*)&outFPRs[destFMarker] = - *(double*)&inStruct[srcMarker]; - - destFMarker += 8; - fprsUsed++; - } - - if (outGPRs != NULL && inStruct != NULL) - *(double*)&outGPRs[destGMarker] = - *(double*)&inStruct[srcMarker]; - - srcMarker += 8; - - // Skip next GPR - destGMarker += 8; - destGMarker = ALIGN(destGMarker, 8); - - break; - - case FFI_TYPE_LONGDOUBLE: - srcMarker = ALIGN(srcMarker, 16); - - if (fprsUsed < NUM_FPR_ARG_REGISTERS) - { - destFMarker = ALIGN(destFMarker, 8); - destGMarker = ALIGN(destGMarker, 8); - - if (outFPRs != NULL && inStruct != NULL) - *(long double*)&outFPRs[destFMarker] = - *(long double*)&inStruct[srcMarker]; - - if (outGPRs != NULL && inStruct != NULL) - *(long double*)&outGPRs[destGMarker] = - *(long double*)&inStruct[srcMarker]; - - destFMarker += 16; - fprsUsed += 2; - } - else - { - destGMarker = ALIGN(destGMarker, 16); - - if (outGPRs != NULL && inStruct != NULL) - *(long double*)&outGPRs[destGMarker] = - *(long double*)&inStruct[srcMarker]; - } - - srcMarker += 16; - destGMarker += 16; // Skip next 2 GPRs - destGMarker = ALIGN(destGMarker, 8); // was 16 - - break; - - case FFI_TYPE_UINT8: - case FFI_TYPE_SINT8: - if (inType->alignment == 1) // bytes only - { - if (inType->size == 1) - { - if (outGPRs != NULL && inStruct != NULL) - outGPRs[destGMarker] = inStruct[srcMarker]; - - srcMarker++; - destGMarker++; - } - else if (inType->size == 2) - { - if (outGPRs != NULL && inStruct != NULL) - { - outGPRs[destGMarker] = inStruct[srcMarker]; - outGPRs[destGMarker + 1] = inStruct[srcMarker + 1]; - } - - srcMarker += 2; - destGMarker += 2; - - i++; - } - else - { - if (outGPRs != NULL && inStruct != NULL) - { - // Avoid memcpy for small chunks. - if (inType->size <= sizeof(long)) - *(long*)&outGPRs[destGMarker] = - *(long*)&inStruct[srcMarker]; - else - memcpy(&outGPRs[destGMarker], - &inStruct[srcMarker], inType->size); - } - - srcMarker += inType->size; - destGMarker += inType->size; - i += inType->size - 1; - } - } - else // bytes and other stuff - { - if (outGPRs != NULL && inStruct != NULL) - outGPRs[destGMarker] = inStruct[srcMarker]; - - srcMarker++; - destGMarker++; - - // Skip to next GPR if next element won't fit and we're - // not already at a register boundary. - if (inType->elements[i + 1] != NULL && (destGMarker % 8)) - { - if (!FFI_TYPE_1_BYTE(inType->elements[i + 1]->type) && - (!FFI_TYPE_2_BYTE(inType->elements[i + 1]->type) || - (ALIGN(destGMarker, 8) - destGMarker) < 2) && - (!FFI_TYPE_4_BYTE(inType->elements[i + 1]->type) || - (ALIGN(destGMarker, 8) - destGMarker) < 4)) - destGMarker = ALIGN(destGMarker, inType->alignment); // was 8 - } - } - - break; - - case FFI_TYPE_UINT16: - case FFI_TYPE_SINT16: - srcMarker = ALIGN(srcMarker, 2); - destGMarker = ALIGN(destGMarker, 2); - - if (outGPRs != NULL && inStruct != NULL) - *(short*)&outGPRs[destGMarker] = - *(short*)&inStruct[srcMarker]; - - srcMarker += 2; - destGMarker += 2; - - if (inType->elements[i + 1] == NULL) - destGMarker = ALIGN(destGMarker, inType->alignment); - - break; - - case FFI_TYPE_INT: - case FFI_TYPE_UINT32: - case FFI_TYPE_SINT32: - srcMarker = ALIGN(srcMarker, 4); - destGMarker = ALIGN(destGMarker, 4); - - if (outGPRs != NULL && inStruct != NULL) - *(int*)&outGPRs[destGMarker] = - *(int*)&inStruct[srcMarker]; - - srcMarker += 4; - destGMarker += 4; - - break; - - case FFI_TYPE_POINTER: - case FFI_TYPE_UINT64: - case FFI_TYPE_SINT64: - srcMarker = ALIGN(srcMarker, 8); - destGMarker = ALIGN(destGMarker, 8); - - if (outGPRs != NULL && inStruct != NULL) - *(long long*)&outGPRs[destGMarker] = - *(long long*)&inStruct[srcMarker]; - - srcMarker += 8; - destGMarker += 8; - - if (inType->elements[i + 1] == NULL) - destGMarker = ALIGN(destGMarker, inType->alignment); - - break; - - case FFI_TYPE_STRUCT: - recurseCount++; - ffi64_struct_to_reg_form(inType->elements[i], - inStruct, &srcMarker, &fprsUsed, outGPRs, - &destGMarker, outFPRs, &destFMarker); - recurseCount--; - break; - - default: - FFI_ASSERT(0); - break; - } - } - - destGMarker = ALIGN(destGMarker, inType->alignment); - - // Take care of the special case for 16-byte structs, but not for - // nested structs. - if (recurseCount == 0 && destGMarker == 16) - { - if (outGPRs != NULL && inStruct != NULL) - *(long double*)&outGPRs[0] = *(long double*)&inStruct[0]; - - destFMarker = savedFMarker; - fprsUsed = savedFPRsUsed; - } - - if (ioStructMarker) - *ioStructMarker = ALIGN(srcMarker, 8); - - if (ioFPRsUsed) - *ioFPRsUsed = fprsUsed; - - if (ioGPRSize) - *ioGPRSize = ALIGN(destGMarker, 8); - - if (ioFPRSize) - *ioFPRSize = ALIGN(destFMarker, 8); -} - -/* ffi64_stret_needs_ptr - - Determine whether a returned struct needs a pointer in r3 or can fit - in registers. -*/ - -bool -ffi64_stret_needs_ptr( - const ffi_type* inType, - unsigned short* ioGPRCount, - unsigned short* ioFPRCount) -{ - // Obvious case first- struct is larger than combined FPR size. - if (inType->size > 14 * 8) - return true; - - // Now the struct can physically fit in registers, determine if it - // also fits logically. - bool needsPtr = false; - unsigned short gprsUsed = 0; - unsigned short fprsUsed = 0; - size_t i; - - if (ioGPRCount) - gprsUsed = *ioGPRCount; - - if (ioFPRCount) - fprsUsed = *ioFPRCount; - - for (i = 0; inType->elements[i] != NULL && !needsPtr; i++) - { - switch (inType->elements[i]->type) - { - case FFI_TYPE_FLOAT: - case FFI_TYPE_DOUBLE: - gprsUsed++; - fprsUsed++; - - if (fprsUsed > 13) - needsPtr = true; - - break; - - case FFI_TYPE_LONGDOUBLE: - gprsUsed += 2; - fprsUsed += 2; - - if (fprsUsed > 14) - needsPtr = true; - - break; - - case FFI_TYPE_UINT8: - case FFI_TYPE_SINT8: - { - gprsUsed++; - - if (gprsUsed > 8) - { - needsPtr = true; - break; - } - - if (inType->elements[i + 1] == NULL) // last byte in the struct - break; - - // Count possible contiguous bytes ahead, up to 8. - unsigned short j; - - for (j = 1; j < 8; j++) - { - if (inType->elements[i + j] == NULL || - !FFI_TYPE_1_BYTE(inType->elements[i + j]->type)) - break; - } - - i += j - 1; // allow for i++ before the test condition - - break; - } - - case FFI_TYPE_UINT16: - case FFI_TYPE_SINT16: - case FFI_TYPE_INT: - case FFI_TYPE_UINT32: - case FFI_TYPE_SINT32: - case FFI_TYPE_POINTER: - case FFI_TYPE_UINT64: - case FFI_TYPE_SINT64: - gprsUsed++; - - if (gprsUsed > 8) - needsPtr = true; - - break; - - case FFI_TYPE_STRUCT: - needsPtr = ffi64_stret_needs_ptr( - inType->elements[i], &gprsUsed, &fprsUsed); - - break; - - default: - FFI_ASSERT(0); - break; - } - } - - if (ioGPRCount) - *ioGPRCount = gprsUsed; - - if (ioFPRCount) - *ioFPRCount = fprsUsed; - - return needsPtr; -} - -/* ffi64_data_size - - Calculate the size in bytes of an ffi type. -*/ - -unsigned int -ffi64_data_size( - const ffi_type* inType) -{ - unsigned int size = 0; - - switch (inType->type) - { - case FFI_TYPE_UINT8: - case FFI_TYPE_SINT8: - size = 1; - break; - - case FFI_TYPE_UINT16: - case FFI_TYPE_SINT16: - size = 2; - break; - - case FFI_TYPE_INT: - case FFI_TYPE_UINT32: - case FFI_TYPE_SINT32: - case FFI_TYPE_FLOAT: - size = 4; - break; - - case FFI_TYPE_POINTER: - case FFI_TYPE_UINT64: - case FFI_TYPE_SINT64: - case FFI_TYPE_DOUBLE: - size = 8; - break; - - case FFI_TYPE_LONGDOUBLE: - size = 16; - break; - - case FFI_TYPE_STRUCT: - ffi64_struct_to_reg_form( - inType, NULL, NULL, NULL, NULL, &size, NULL, NULL); - break; - - case FFI_TYPE_VOID: - break; - - default: - FFI_ASSERT(0); - break; - } - - return size; -} - -#endif /* defined(__ppc64__) */ -#endif /* __ppc__ || __ppc64__ */ diff --git a/Modules/_ctypes/libffi_osx/powerpc/ppc64-darwin_closure.S b/Modules/_ctypes/libffi_osx/powerpc/ppc64-darwin_closure.S deleted file mode 100644 index 7162fa1d..00000000 --- a/Modules/_ctypes/libffi_osx/powerpc/ppc64-darwin_closure.S +++ /dev/null @@ -1,418 +0,0 @@ -#if defined(__ppc64__) - -/* ----------------------------------------------------------------------- - ppc64-darwin_closure.S - Copyright (c) 2002, 2003, 2004, Free Software Foundation, - Inc. based on ppc_closure.S - - PowerPC Assembly glue. - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ - -#define LIBFFI_ASM - -#include <ffi.h> -#include <ppc-ffitarget.h> // for FFI_TRAMPOLINE_SIZE -#include <ppc-darwin.h> -#include <architecture/ppc/mode_independent_asm.h> - - .file "ppc64-darwin_closure.S" -.text - .align LOG2_GPR_BYTES - .globl _ffi_closure_ASM - -.text - .align LOG2_GPR_BYTES - -_ffi_closure_ASM: -LFB1: - mflr r0 - stg r0,SF_RETURN(r1) // save return address - - // Save GPRs 3 - 10 (aligned to 8) in the parents outgoing area. - stg r3,SF_ARG1(r1) - stg r4,SF_ARG2(r1) - stg r5,SF_ARG3(r1) - stg r6,SF_ARG4(r1) - stg r7,SF_ARG5(r1) - stg r8,SF_ARG6(r1) - stg r9,SF_ARG7(r1) - stg r10,SF_ARG8(r1) - -LCFI0: -/* 48 bytes (Linkage Area) - 64 bytes (outgoing parameter area, always reserved) - 112 bytes (14*8 for incoming FPR) - ? bytes (result) - 112 bytes (14*8 for outgoing FPR) - 16 bytes (2 saved registers) - 352 + ? total bytes -*/ - - std r31,-8(r1) // Save registers we use. - std r30,-16(r1) - mr r30,r1 // Save the old SP. - mr r31,r11 // Save the ffi_closure around ffi64_data_size. - - // Calculate the space we need. - stdu r1,-SF_MINSIZE(r1) - ld r3,FFI_TRAMPOLINE_SIZE(r31) // ffi_closure->cif* - ld r3,16(r3) // ffi_cif->rtype* - bl Lffi64_data_size$stub - ld r1,0(r1) - - addi r3,r3,352 // Add our overhead. - neg r3,r3 - li r0,-32 // Align to 32 bytes. - and r3,r3,r0 - stdux r1,r1,r3 // Grow the stack. - - mr r11,r31 // Copy the ffi_closure back. - -LCFI1: - // We want to build up an area for the parameters passed - // in registers. (both floating point and integer) - -/* 320 bytes (callee stack frame aligned to 32) - 48 bytes (caller linkage area) - 368 (start of caller parameter area aligned to 8) -*/ - - // Save FPRs 1 - 14. (aligned to 8) - stfd f1,112(r1) - stfd f2,120(r1) - stfd f3,128(r1) - stfd f4,136(r1) - stfd f5,144(r1) - stfd f6,152(r1) - stfd f7,160(r1) - stfd f8,168(r1) - stfd f9,176(r1) - stfd f10,184(r1) - stfd f11,192(r1) - stfd f12,200(r1) - stfd f13,208(r1) - stfd f14,216(r1) - - // Set up registers for the routine that actually does the work. - mr r3,r11 // context pointer from the trampoline - addi r4,r1,224 // result storage - addi r5,r30,SF_ARG1 // saved GPRs - addi r6,r1,112 // saved FPRs - bl Lffi_closure_helper_DARWIN$stub - - // Look the proper starting point in table - // by using return type as an offset. - addi r5,r1,224 // Get pointer to results area. - bl Lget_ret_type0_addr // Get pointer to Lret_type0 into LR. - mflr r4 // Move to r4. - slwi r3,r3,4 // Now multiply return type by 16. - add r3,r3,r4 // Add contents of table to table address. - mtctr r3 - bctr - -LFE1: - // Each of the ret_typeX code fragments has to be exactly 16 bytes long - // (4 instructions). For cache effectiveness we align to a 16 byte - // boundary first. - .align 4 - nop - nop - nop - -Lget_ret_type0_addr: - blrl - -// case FFI_TYPE_VOID -Lret_type0: - b Lfinish - nop - nop - nop - -// case FFI_TYPE_INT -Lret_type1: - lwz r3,4(r5) - b Lfinish - nop - nop - -// case FFI_TYPE_FLOAT -Lret_type2: - lfs f1,0(r5) - b Lfinish - nop - nop - -// case FFI_TYPE_DOUBLE -Lret_type3: - lfd f1,0(r5) - b Lfinish - nop - nop - -// case FFI_TYPE_LONGDOUBLE -Lret_type4: - lfd f1,0(r5) - lfd f2,8(r5) - b Lfinish - nop - -// case FFI_TYPE_UINT8 -Lret_type5: - lbz r3,7(r5) - b Lfinish - nop - nop - -// case FFI_TYPE_SINT8 -Lret_type6: - lbz r3,7(r5) - extsb r3,r3 - b Lfinish - nop - -// case FFI_TYPE_UINT16 -Lret_type7: - lhz r3,6(r5) - b Lfinish - nop - nop - -// case FFI_TYPE_SINT16 -Lret_type8: - lha r3,6(r5) - b Lfinish - nop - nop - -// case FFI_TYPE_UINT32 -Lret_type9: // same as Lret_type1 - lwz r3,4(r5) - b Lfinish - nop - nop - -// case FFI_TYPE_SINT32 -Lret_type10: // same as Lret_type1 - lwz r3,4(r5) - b Lfinish - nop - nop - -// case FFI_TYPE_UINT64 -Lret_type11: - ld r3,0(r5) - b Lfinish - nop - nop - -// case FFI_TYPE_SINT64 -Lret_type12: // same as Lret_type11 - ld r3,0(r5) - b Lfinish - nop - nop - -// case FFI_TYPE_STRUCT -Lret_type13: - b Lret_struct - nop - nop - nop - -// ** End 16-byte aligned cases ** -// case FFI_TYPE_POINTER -// This case assumes that FFI_TYPE_POINTER == FFI_TYPE_LAST. If more types -// are added in future, the following code will need to be updated and -// padded to 16 bytes. -Lret_type14: - lg r3,0(r5) - b Lfinish - -// copy struct into registers -Lret_struct: - ld r31,FFI_TRAMPOLINE_SIZE(r31) // ffi_closure->cif* - ld r3,16(r31) // ffi_cif->rtype* - ld r31,24(r31) // ffi_cif->flags - mr r4,r5 // copy struct* to 2nd arg - addi r7,r1,SF_ARG9 // GPR return area - addi r9,r30,-16-(14*8) // FPR return area - li r5,0 // struct offset ptr (NULL) - li r6,0 // FPR used count ptr (NULL) - li r8,0 // GPR return area size ptr (NULL) - li r10,0 // FPR return area size ptr (NULL) - bl Lffi64_struct_to_reg_form$stub - - // Load GPRs - ld r3,SF_ARG9(r1) - ld r4,SF_ARG10(r1) - ld r5,SF_ARG11(r1) - ld r6,SF_ARG12(r1) - nop - ld r7,SF_ARG13(r1) - ld r8,SF_ARG14(r1) - ld r9,SF_ARG15(r1) - ld r10,SF_ARG16(r1) - nop - - // Load FPRs - mtcrf 0x2,r31 - bf 26,Lfinish - lfd f1,-16-(14*8)(r30) - lfd f2,-16-(13*8)(r30) - lfd f3,-16-(12*8)(r30) - lfd f4,-16-(11*8)(r30) - nop - lfd f5,-16-(10*8)(r30) - lfd f6,-16-(9*8)(r30) - lfd f7,-16-(8*8)(r30) - lfd f8,-16-(7*8)(r30) - nop - lfd f9,-16-(6*8)(r30) - lfd f10,-16-(5*8)(r30) - lfd f11,-16-(4*8)(r30) - lfd f12,-16-(3*8)(r30) - nop - lfd f13,-16-(2*8)(r30) - lfd f14,-16-(1*8)(r30) - // Fall through - -// case done -Lfinish: - lg r1,0(r1) // Restore stack pointer. - ld r31,-8(r1) // Restore registers we used. - ld r30,-16(r1) - lg r0,SF_RETURN(r1) // Get return address. - mtlr r0 // Reset link register. - blr - -// END(ffi_closure_ASM) - -.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support -EH_frame1: - .set L$set$0,LECIE1-LSCIE1 - .long L$set$0 ; Length of Common Information Entry -LSCIE1: - .long 0x0 ; CIE Identifier Tag - .byte 0x1 ; CIE Version - .ascii "zR\0" ; CIE Augmentation - .byte 0x1 ; uleb128 0x1; CIE Code Alignment Factor - .byte 0x7c ; sleb128 -4; CIE Data Alignment Factor - .byte 0x41 ; CIE RA Column - .byte 0x1 ; uleb128 0x1; Augmentation size - .byte 0x10 ; FDE Encoding (pcrel) - .byte 0xc ; DW_CFA_def_cfa - .byte 0x1 ; uleb128 0x1 - .byte 0x0 ; uleb128 0x0 - .align LOG2_GPR_BYTES -LECIE1: -.globl _ffi_closure_ASM.eh -_ffi_closure_ASM.eh: -LSFDE1: - .set L$set$1,LEFDE1-LASFDE1 - .long L$set$1 ; FDE Length - -LASFDE1: - .long LASFDE1-EH_frame1 ; FDE CIE offset - .g_long LFB1-. ; FDE initial location - .set L$set$3,LFE1-LFB1 - .g_long L$set$3 ; FDE address range - .byte 0x0 ; uleb128 0x0; Augmentation size - .byte 0x4 ; DW_CFA_advance_loc4 - .set L$set$3,LCFI1-LCFI0 - .long L$set$3 - .byte 0xe ; DW_CFA_def_cfa_offset - .byte 176,1 ; uleb128 176 - .byte 0x4 ; DW_CFA_advance_loc4 - .set L$set$4,LCFI0-LFB1 - .long L$set$4 - .byte 0x11 ; DW_CFA_offset_extended_sf - .byte 0x41 ; uleb128 0x41 - .byte 0x7e ; sleb128 -2 - .align LOG2_GPR_BYTES - -LEFDE1: -.data - .align LOG2_GPR_BYTES -LDFCM0: -.section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32 - .align LOG2_GPR_BYTES - -Lffi_closure_helper_DARWIN$stub: - .indirect_symbol _ffi_closure_helper_DARWIN - mflr r0 - bcl 20,31,LO$ffi_closure_helper_DARWIN - -LO$ffi_closure_helper_DARWIN: - mflr r11 - addis r11,r11,ha16(L_ffi_closure_helper_DARWIN$lazy_ptr - LO$ffi_closure_helper_DARWIN) - mtlr r0 - lgu r12,lo16(L_ffi_closure_helper_DARWIN$lazy_ptr - LO$ffi_closure_helper_DARWIN)(r11) - mtctr r12 - bctr - -.lazy_symbol_pointer -L_ffi_closure_helper_DARWIN$lazy_ptr: - .indirect_symbol _ffi_closure_helper_DARWIN - .g_long dyld_stub_binding_helper - -.section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32 - .align LOG2_GPR_BYTES - -Lffi64_struct_to_reg_form$stub: - .indirect_symbol _ffi64_struct_to_reg_form - mflr r0 - bcl 20,31,LO$ffi64_struct_to_reg_form - -LO$ffi64_struct_to_reg_form: - mflr r11 - addis r11,r11,ha16(L_ffi64_struct_to_reg_form$lazy_ptr - LO$ffi64_struct_to_reg_form) - mtlr r0 - lgu r12,lo16(L_ffi64_struct_to_reg_form$lazy_ptr - LO$ffi64_struct_to_reg_form)(r11) - mtctr r12 - bctr - -.section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32 - .align LOG2_GPR_BYTES - -Lffi64_data_size$stub: - .indirect_symbol _ffi64_data_size - mflr r0 - bcl 20,31,LO$ffi64_data_size - -LO$ffi64_data_size: - mflr r11 - addis r11,r11,ha16(L_ffi64_data_size$lazy_ptr - LO$ffi64_data_size) - mtlr r0 - lgu r12,lo16(L_ffi64_data_size$lazy_ptr - LO$ffi64_data_size)(r11) - mtctr r12 - bctr - -.lazy_symbol_pointer -L_ffi64_struct_to_reg_form$lazy_ptr: - .indirect_symbol _ffi64_struct_to_reg_form - .g_long dyld_stub_binding_helper - -L_ffi64_data_size$lazy_ptr: - .indirect_symbol _ffi64_data_size - .g_long dyld_stub_binding_helper - -#endif // __ppc64__ diff --git a/Modules/_ctypes/libffi_osx/types.c b/Modules/_ctypes/libffi_osx/types.c deleted file mode 100644 index 44806aee..00000000 --- a/Modules/_ctypes/libffi_osx/types.c +++ /dev/null @@ -1,115 +0,0 @@ -/* ----------------------------------------------------------------------- - types.c - Copyright (c) 1996, 1998 Red Hat, Inc. - - Predefined ffi_types needed by libffi. - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ - -#include <ffi.h> -#include <ffi_common.h> - -/* Type definitions */ -#define FFI_INTEGRAL_TYPEDEF(n, s, a, t) \ - ffi_type ffi_type_##n = { s, a, t, NULL } -#define FFI_AGGREGATE_TYPEDEF(n, e) \ - ffi_type ffi_type_##n = { 0, 0, FFI_TYPE_STRUCT, e } - -FFI_INTEGRAL_TYPEDEF(uint8, 1, 1, FFI_TYPE_UINT8); -FFI_INTEGRAL_TYPEDEF(sint8, 1, 1, FFI_TYPE_SINT8); -FFI_INTEGRAL_TYPEDEF(uint16, 2, 2, FFI_TYPE_UINT16); -FFI_INTEGRAL_TYPEDEF(sint16, 2, 2, FFI_TYPE_SINT16); -FFI_INTEGRAL_TYPEDEF(uint32, 4, 4, FFI_TYPE_UINT32); -FFI_INTEGRAL_TYPEDEF(sint32, 4, 4, FFI_TYPE_SINT32); -FFI_INTEGRAL_TYPEDEF(float, 4, 4, FFI_TYPE_FLOAT); - -/* Size and alignment are fake here. They must not be 0. */ -FFI_INTEGRAL_TYPEDEF(void, 1, 1, FFI_TYPE_VOID); - -#if defined ALPHA || defined SPARC64 || defined X86_64 || \ - defined S390X || defined IA64 || defined POWERPC64 -FFI_INTEGRAL_TYPEDEF(pointer, 8, 8, FFI_TYPE_POINTER); -#else -FFI_INTEGRAL_TYPEDEF(pointer, 4, 4, FFI_TYPE_POINTER); -#endif - -#if defined X86 || defined ARM || defined M68K || defined(X86_DARWIN) - -# ifdef X86_64 - FFI_INTEGRAL_TYPEDEF(uint64, 8, 8, FFI_TYPE_UINT64); - FFI_INTEGRAL_TYPEDEF(sint64, 8, 8, FFI_TYPE_SINT64); -# else - FFI_INTEGRAL_TYPEDEF(uint64, 8, 4, FFI_TYPE_UINT64); - FFI_INTEGRAL_TYPEDEF(sint64, 8, 4, FFI_TYPE_SINT64); -# endif - -#elif defined(POWERPC_DARWIN) -FFI_INTEGRAL_TYPEDEF(uint64, 8, 8, FFI_TYPE_UINT64); -FFI_INTEGRAL_TYPEDEF(sint64, 8, 8, FFI_TYPE_SINT64); -#elif defined SH -FFI_INTEGRAL_TYPEDEF(uint64, 8, 4, FFI_TYPE_UINT64); -FFI_INTEGRAL_TYPEDEF(sint64, 8, 4, FFI_TYPE_SINT64); -#else -FFI_INTEGRAL_TYPEDEF(uint64, 8, 8, FFI_TYPE_UINT64); -FFI_INTEGRAL_TYPEDEF(sint64, 8, 8, FFI_TYPE_SINT64); -#endif - -#if defined X86 || defined X86_WIN32 || defined M68K || defined(X86_DARWIN) - -# if defined X86_WIN32 || defined X86_64 - FFI_INTEGRAL_TYPEDEF(double, 8, 8, FFI_TYPE_DOUBLE); -# else - FFI_INTEGRAL_TYPEDEF(double, 8, 4, FFI_TYPE_DOUBLE); -# endif - -# ifdef X86_DARWIN - FFI_INTEGRAL_TYPEDEF(longdouble, 16, 16, FFI_TYPE_LONGDOUBLE); -# else - FFI_INTEGRAL_TYPEDEF(longdouble, 12, 4, FFI_TYPE_LONGDOUBLE); -# endif - -#elif defined ARM || defined SH || defined POWERPC_AIX -FFI_INTEGRAL_TYPEDEF(double, 8, 4, FFI_TYPE_DOUBLE); -FFI_INTEGRAL_TYPEDEF(longdouble, 8, 4, FFI_TYPE_LONGDOUBLE); -#elif defined POWERPC_DARWIN -FFI_INTEGRAL_TYPEDEF(double, 8, 8, FFI_TYPE_DOUBLE); - -# if __GNUC__ >= 4 - FFI_INTEGRAL_TYPEDEF(longdouble, 16, 16, FFI_TYPE_LONGDOUBLE); -# else - FFI_INTEGRAL_TYPEDEF(longdouble, 8, 8, FFI_TYPE_LONGDOUBLE); -# endif - -#elif defined SPARC -FFI_INTEGRAL_TYPEDEF(double, 8, 8, FFI_TYPE_DOUBLE); - -# ifdef SPARC64 - FFI_INTEGRAL_TYPEDEF(longdouble, 16, 16, FFI_TYPE_LONGDOUBLE); -# else - FFI_INTEGRAL_TYPEDEF(longdouble, 16, 8, FFI_TYPE_LONGDOUBLE); -# endif - -#elif defined X86_64 || defined POWERPC64 -FFI_INTEGRAL_TYPEDEF(double, 8, 8, FFI_TYPE_DOUBLE); -FFI_INTEGRAL_TYPEDEF(longdouble, 16, 16, FFI_TYPE_LONGDOUBLE); -#else -FFI_INTEGRAL_TYPEDEF(double, 8, 8, FFI_TYPE_DOUBLE); -FFI_INTEGRAL_TYPEDEF(longdouble, 8, 8, FFI_TYPE_LONGDOUBLE); -#endif \ No newline at end of file diff --git a/Modules/_ctypes/libffi_osx/x86/darwin64.S b/Modules/_ctypes/libffi_osx/x86/darwin64.S deleted file mode 100644 index 1286d33f..00000000 --- a/Modules/_ctypes/libffi_osx/x86/darwin64.S +++ /dev/null @@ -1,417 +0,0 @@ -/* ----------------------------------------------------------------------- - darwin64.S - Copyright (c) 2006 Free Software Foundation, Inc. - derived from unix64.S - - x86-64 Foreign Function Interface for Darwin. - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ - -#ifdef __x86_64__ -#define LIBFFI_ASM -#include <fficonfig.h> -#include <ffi.h> - - .file "darwin64.S" -.text - -/* ffi_call_unix64 (void *args, unsigned long bytes, unsigned flags, - void *raddr, void (*fnaddr)()); - - Bit o trickiness here -- ARGS+BYTES is the base of the stack frame - for this function. This has been allocated by ffi_call. We also - deallocate some of the stack that has been alloca'd. */ - - .align 3 - .globl _ffi_call_unix64 - -_ffi_call_unix64: -LUW0: - movq (%rsp), %r10 /* Load return address. */ - movq %rdi, %r12 /* Save a copy of the register area. */ - leaq (%rdi, %rsi), %rax /* Find local stack base. */ - movq %rdx, (%rax) /* Save flags. */ - movq %rcx, 8(%rax) /* Save raddr. */ - movq %rbp, 16(%rax) /* Save old frame pointer. */ - movq %r10, 24(%rax) /* Relocate return address. */ - movq %rax, %rbp /* Finalize local stack frame. */ -LUW1: - /* movq %rdi, %r10 // Save a copy of the register area. */ - movq %r12, %r10 - movq %r8, %r11 /* Save a copy of the target fn. */ - movl %r9d, %eax /* Set number of SSE registers. */ - - /* Load up all argument registers. */ - movq (%r10), %rdi - movq 8(%r10), %rsi - movq 16(%r10), %rdx - movq 24(%r10), %rcx - movq 32(%r10), %r8 - movq 40(%r10), %r9 - testl %eax, %eax - jnz Lload_sse -Lret_from_load_sse: - - /* Deallocate the reg arg area. */ - leaq 176(%r10), %rsp - - /* Call the user function. */ - call *%r11 - - /* Deallocate stack arg area; local stack frame in redzone. */ - leaq 24(%rbp), %rsp - - movq 0(%rbp), %rcx /* Reload flags. */ - movq 8(%rbp), %rdi /* Reload raddr. */ - movq 16(%rbp), %rbp /* Reload old frame pointer. */ -LUW2: - - /* The first byte of the flags contains the FFI_TYPE. */ - movzbl %cl, %r10d - leaq Lstore_table(%rip), %r11 - movslq (%r11, %r10, 4), %r10 - addq %r11, %r10 - jmp *%r10 - -Lstore_table: - .long Lst_void-Lstore_table /* FFI_TYPE_VOID */ - .long Lst_sint32-Lstore_table /* FFI_TYPE_INT */ - .long Lst_float-Lstore_table /* FFI_TYPE_FLOAT */ - .long Lst_double-Lstore_table /* FFI_TYPE_DOUBLE */ - .long Lst_ldouble-Lstore_table /* FFI_TYPE_LONGDOUBLE */ - .long Lst_uint8-Lstore_table /* FFI_TYPE_UINT8 */ - .long Lst_sint8-Lstore_table /* FFI_TYPE_SINT8 */ - .long Lst_uint16-Lstore_table /* FFI_TYPE_UINT16 */ - .long Lst_sint16-Lstore_table /* FFI_TYPE_SINT16 */ - .long Lst_uint32-Lstore_table /* FFI_TYPE_UINT32 */ - .long Lst_sint32-Lstore_table /* FFI_TYPE_SINT32 */ - .long Lst_int64-Lstore_table /* FFI_TYPE_UINT64 */ - .long Lst_int64-Lstore_table /* FFI_TYPE_SINT64 */ - .long Lst_struct-Lstore_table /* FFI_TYPE_STRUCT */ - .long Lst_int64-Lstore_table /* FFI_TYPE_POINTER */ - - .text - .align 3 -Lst_void: - ret - .align 3 -Lst_uint8: - movzbq %al, %rax - movq %rax, (%rdi) - ret - .align 3 -Lst_sint8: - movsbq %al, %rax - movq %rax, (%rdi) - ret - .align 3 -Lst_uint16: - movzwq %ax, %rax - movq %rax, (%rdi) - .align 3 -Lst_sint16: - movswq %ax, %rax - movq %rax, (%rdi) - ret - .align 3 -Lst_uint32: - movl %eax, %eax - movq %rax, (%rdi) - .align 3 -Lst_sint32: - cltq - movq %rax, (%rdi) - ret - .align 3 -Lst_int64: - movq %rax, (%rdi) - ret - .align 3 -Lst_float: - movss %xmm0, (%rdi) - ret - .align 3 -Lst_double: - movsd %xmm0, (%rdi) - ret -Lst_ldouble: - fstpt (%rdi) - ret - .align 3 -Lst_struct: - leaq -20(%rsp), %rsi /* Scratch area in redzone. */ - - /* We have to locate the values now, and since we don't want to - write too much data into the user's return value, we spill the - value to a 16 byte scratch area first. Bits 8, 9, and 10 - control where the values are located. Only one of the three - bits will be set; see ffi_prep_cif_machdep for the pattern. */ - movd %xmm0, %r10 - movd %xmm1, %r11 - testl $0x100, %ecx - cmovnz %rax, %rdx - cmovnz %r10, %rax - testl $0x200, %ecx - cmovnz %r10, %rdx - testl $0x400, %ecx - cmovnz %r10, %rax - cmovnz %r11, %rdx - movq %rax, (%rsi) - movq %rdx, 8(%rsi) - - /* Bits 12-31 contain the true size of the structure. Copy from - the scratch area to the true destination. */ - shrl $12, %ecx - rep movsb - ret - - /* Many times we can avoid loading any SSE registers at all. - It's not worth an indirect jump to load the exact set of - SSE registers needed; zero or all is a good compromise. */ - .align 3 -LUW3: -Lload_sse: - movdqa 48(%r10), %xmm0 - movdqa 64(%r10), %xmm1 - movdqa 80(%r10), %xmm2 - movdqa 96(%r10), %xmm3 - movdqa 112(%r10), %xmm4 - movdqa 128(%r10), %xmm5 - movdqa 144(%r10), %xmm6 - movdqa 160(%r10), %xmm7 - jmp Lret_from_load_sse - -LUW4: - .align 3 - .globl _ffi_closure_unix64 - -_ffi_closure_unix64: -LUW5: - /* The carry flag is set by the trampoline iff SSE registers - are used. Don't clobber it before the branch instruction. */ - leaq -200(%rsp), %rsp -LUW6: - movq %rdi, (%rsp) - movq %rsi, 8(%rsp) - movq %rdx, 16(%rsp) - movq %rcx, 24(%rsp) - movq %r8, 32(%rsp) - movq %r9, 40(%rsp) - jc Lsave_sse -Lret_from_save_sse: - - movq %r10, %rdi - leaq 176(%rsp), %rsi - movq %rsp, %rdx - leaq 208(%rsp), %rcx - call _ffi_closure_unix64_inner - - /* Deallocate stack frame early; return value is now in redzone. */ - addq $200, %rsp -LUW7: - - /* The first byte of the return value contains the FFI_TYPE. */ - movzbl %al, %r10d - leaq Lload_table(%rip), %r11 - movslq (%r11, %r10, 4), %r10 - addq %r11, %r10 - jmp *%r10 - -Lload_table: - .long Lld_void-Lload_table /* FFI_TYPE_VOID */ - .long Lld_int32-Lload_table /* FFI_TYPE_INT */ - .long Lld_float-Lload_table /* FFI_TYPE_FLOAT */ - .long Lld_double-Lload_table /* FFI_TYPE_DOUBLE */ - .long Lld_ldouble-Lload_table /* FFI_TYPE_LONGDOUBLE */ - .long Lld_int8-Lload_table /* FFI_TYPE_UINT8 */ - .long Lld_int8-Lload_table /* FFI_TYPE_SINT8 */ - .long Lld_int16-Lload_table /* FFI_TYPE_UINT16 */ - .long Lld_int16-Lload_table /* FFI_TYPE_SINT16 */ - .long Lld_int32-Lload_table /* FFI_TYPE_UINT32 */ - .long Lld_int32-Lload_table /* FFI_TYPE_SINT32 */ - .long Lld_int64-Lload_table /* FFI_TYPE_UINT64 */ - .long Lld_int64-Lload_table /* FFI_TYPE_SINT64 */ - .long Lld_struct-Lload_table /* FFI_TYPE_STRUCT */ - .long Lld_int64-Lload_table /* FFI_TYPE_POINTER */ - - .text - .align 3 -Lld_void: - ret - .align 3 -Lld_int8: - movzbl -24(%rsp), %eax - ret - .align 3 -Lld_int16: - movzwl -24(%rsp), %eax - ret - .align 3 -Lld_int32: - movl -24(%rsp), %eax - ret - .align 3 -Lld_int64: - movq -24(%rsp), %rax - ret - .align 3 -Lld_float: - movss -24(%rsp), %xmm0 - ret - .align 3 -Lld_double: - movsd -24(%rsp), %xmm0 - ret - .align 3 -Lld_ldouble: - fldt -24(%rsp) - ret - .align 3 -Lld_struct: - /* There are four possibilities here, %rax/%rdx, %xmm0/%rax, - %rax/%xmm0, %xmm0/%xmm1. We collapse two by always loading - both rdx and xmm1 with the second word. For the remaining, - bit 8 set means xmm0 gets the second word, and bit 9 means - that rax gets the second word. */ - movq -24(%rsp), %rcx - movq -16(%rsp), %rdx - movq -16(%rsp), %xmm1 - testl $0x100, %eax - cmovnz %rdx, %rcx - movd %rcx, %xmm0 - testl $0x200, %eax - movq -24(%rsp), %rax - cmovnz %rdx, %rax - ret - - /* See the comment above Lload_sse; the same logic applies here. */ - .align 3 -LUW8: -Lsave_sse: - movdqa %xmm0, 48(%rsp) - movdqa %xmm1, 64(%rsp) - movdqa %xmm2, 80(%rsp) - movdqa %xmm3, 96(%rsp) - movdqa %xmm4, 112(%rsp) - movdqa %xmm5, 128(%rsp) - movdqa %xmm6, 144(%rsp) - movdqa %xmm7, 160(%rsp) - jmp Lret_from_save_sse - -LUW9: -.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support -EH_frame1: - .set L$set$0,LECIE1-LSCIE1 /* CIE Length */ - .long L$set$0 -LSCIE1: - .long 0x0 /* CIE Identifier Tag */ - .byte 0x1 /* CIE Version */ - .ascii "zR\0" /* CIE Augmentation */ - .byte 0x1 /* uleb128 0x1; CIE Code Alignment Factor */ - .byte 0x78 /* sleb128 -8; CIE Data Alignment Factor */ - .byte 0x10 /* CIE RA Column */ - .byte 0x1 /* uleb128 0x1; Augmentation size */ - .byte 0x10 /* FDE Encoding (pcrel sdata4) */ - .byte 0xc /* DW_CFA_def_cfa, %rsp offset 8 */ - .byte 0x7 /* uleb128 0x7 */ - .byte 0x8 /* uleb128 0x8 */ - .byte 0x90 /* DW_CFA_offset, column 0x10 */ - .byte 0x1 - .align 3 -LECIE1: - .globl _ffi_call_unix64.eh -_ffi_call_unix64.eh: -LSFDE1: - .set L$set$1,LEFDE1-LASFDE1 /* FDE Length */ - .long L$set$1 -LASFDE1: - .long LASFDE1-EH_frame1 /* FDE CIE offset */ - .quad LUW0-. /* FDE initial location */ - .set L$set$2,LUW4-LUW0 /* FDE address range */ - .quad L$set$2 - .byte 0x0 /* Augmentation size */ - .byte 0x4 /* DW_CFA_advance_loc4 */ - .set L$set$3,LUW1-LUW0 - .long L$set$3 - - /* New stack frame based off rbp. This is an itty bit of unwind - trickery in that the CFA *has* changed. There is no easy way - to describe it correctly on entry to the function. Fortunately, - it doesn't matter too much since at all points we can correctly - unwind back to ffi_call. Note that the location to which we - moved the return address is (the new) CFA-8, so from the - perspective of the unwind info, it hasn't moved. */ - .byte 0xc /* DW_CFA_def_cfa, %rbp offset 32 */ - .byte 0x6 - .byte 0x20 - .byte 0x80+6 /* DW_CFA_offset, %rbp offset 2*-8 */ - .byte 0x2 - .byte 0xa /* DW_CFA_remember_state */ - - .byte 0x4 /* DW_CFA_advance_loc4 */ - .set L$set$4,LUW2-LUW1 - .long L$set$4 - .byte 0xc /* DW_CFA_def_cfa, %rsp offset 8 */ - .byte 0x7 - .byte 0x8 - .byte 0xc0+6 /* DW_CFA_restore, %rbp */ - - .byte 0x4 /* DW_CFA_advance_loc4 */ - .set L$set$5,LUW3-LUW2 - .long L$set$5 - .byte 0xb /* DW_CFA_restore_state */ - - .align 3 -LEFDE1: - .globl _ffi_closure_unix64.eh -_ffi_closure_unix64.eh: -LSFDE3: - .set L$set$6,LEFDE3-LASFDE3 /* FDE Length */ - .long L$set$6 -LASFDE3: - .long LASFDE3-EH_frame1 /* FDE CIE offset */ - .quad LUW5-. /* FDE initial location */ - .set L$set$7,LUW9-LUW5 /* FDE address range */ - .quad L$set$7 - .byte 0x0 /* Augmentation size */ - - .byte 0x4 /* DW_CFA_advance_loc4 */ - .set L$set$8,LUW6-LUW5 - .long L$set$8 - .byte 0xe /* DW_CFA_def_cfa_offset */ - .byte 208,1 /* uleb128 208 */ - .byte 0xa /* DW_CFA_remember_state */ - - .byte 0x4 /* DW_CFA_advance_loc4 */ - .set L$set$9,LUW7-LUW6 - .long L$set$9 - .byte 0xe /* DW_CFA_def_cfa_offset */ - .byte 0x8 - - .byte 0x4 /* DW_CFA_advance_loc4 */ - .set L$set$10,LUW8-LUW7 - .long L$set$10 - .byte 0xb /* DW_CFA_restore_state */ - - .align 3 -LEFDE3: - .subsections_via_symbols - -#endif /* __x86_64__ */ diff --git a/Modules/_ctypes/libffi_osx/x86/x86-darwin.S b/Modules/_ctypes/libffi_osx/x86/x86-darwin.S deleted file mode 100644 index 925a8413..00000000 --- a/Modules/_ctypes/libffi_osx/x86/x86-darwin.S +++ /dev/null @@ -1,422 +0,0 @@ -#ifdef __i386__ -/* ----------------------------------------------------------------------- - darwin.S - Copyright (c) 1996, 1998, 2001, 2002, 2003 Red Hat, Inc. - - X86 Foreign Function Interface - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ - -/* - * This file is based on sysv.S and then hacked up by Ronald who hasn't done - * assembly programming in 8 years. - */ - -#ifndef __x86_64__ - -#define LIBFFI_ASM -#include <fficonfig.h> -#include <ffi.h> - -#ifdef PyObjC_STRICT_DEBUGGING - /* XXX: Debugging of stack alignment, to be removed */ -#define ASSERT_STACK_ALIGNED movdqa -16(%esp), %xmm0 -#else -#define ASSERT_STACK_ALIGNED -#endif - -.text - -.globl _ffi_prep_args - - .align 4 -.globl _ffi_call_SYSV - -_ffi_call_SYSV: -LFB1: - pushl %ebp -LCFI0: - movl %esp,%ebp -LCFI1: - subl $8,%esp - /* Make room for all of the new args. */ - movl 16(%ebp),%ecx - subl %ecx,%esp - - movl %esp,%eax - - /* Place all of the ffi_prep_args in position */ - subl $8,%esp - pushl 12(%ebp) - pushl %eax - call *8(%ebp) - - /* Return stack to previous state and call the function */ - addl $16,%esp - - call *28(%ebp) - - /* Remove the space we pushed for the args */ - movl 16(%ebp),%ecx - addl %ecx,%esp - - /* Load %ecx with the return type code */ - movl 20(%ebp),%ecx - - /* If the return value pointer is NULL, assume no return value. */ - cmpl $0,24(%ebp) - jne Lretint - - /* Even if there is no space for the return value, we are - obliged to handle floating-point values. */ - cmpl $FFI_TYPE_FLOAT,%ecx - jne Lnoretval - fstp %st(0) - - jmp Lepilogue - -Lretint: - cmpl $FFI_TYPE_INT,%ecx - jne Lretfloat - /* Load %ecx with the pointer to storage for the return value */ - movl 24(%ebp),%ecx - movl %eax,0(%ecx) - jmp Lepilogue - -Lretfloat: - cmpl $FFI_TYPE_FLOAT,%ecx - jne Lretdouble - /* Load %ecx with the pointer to storage for the return value */ - movl 24(%ebp),%ecx - fstps (%ecx) - jmp Lepilogue - -Lretdouble: - cmpl $FFI_TYPE_DOUBLE,%ecx - jne Lretlongdouble - /* Load %ecx with the pointer to storage for the return value */ - movl 24(%ebp),%ecx - fstpl (%ecx) - jmp Lepilogue - -Lretlongdouble: - cmpl $FFI_TYPE_LONGDOUBLE,%ecx - jne Lretint64 - /* Load %ecx with the pointer to storage for the return value */ - movl 24(%ebp),%ecx - fstpt (%ecx) - jmp Lepilogue - -Lretint64: - cmpl $FFI_TYPE_SINT64,%ecx - jne Lretstruct1b - /* Load %ecx with the pointer to storage for the return value */ - movl 24(%ebp),%ecx - movl %eax,0(%ecx) - movl %edx,4(%ecx) - jmp Lepilogue - -Lretstruct1b: - cmpl $FFI_TYPE_SINT8,%ecx - jne Lretstruct2b - /* Load %ecx with the pointer to storage for the return value */ - movl 24(%ebp),%ecx - movb %al,0(%ecx) - jmp Lepilogue - -Lretstruct2b: - cmpl $FFI_TYPE_SINT16,%ecx - jne Lretstruct - /* Load %ecx with the pointer to storage for the return value */ - movl 24(%ebp),%ecx - movw %ax,0(%ecx) - jmp Lepilogue - -Lretstruct: - cmpl $FFI_TYPE_STRUCT,%ecx - jne Lnoretval - /* Nothing to do! */ - addl $4,%esp - popl %ebp - ret - -Lnoretval: -Lepilogue: - addl $8,%esp - movl %ebp,%esp - popl %ebp - ret -LFE1: -.ffi_call_SYSV_end: - - .align 4 -FFI_HIDDEN (ffi_closure_SYSV) -.globl _ffi_closure_SYSV - -_ffi_closure_SYSV: -LFB2: - pushl %ebp -LCFI2: - movl %esp, %ebp -LCFI3: - subl $56, %esp - leal -40(%ebp), %edx - movl %edx, -12(%ebp) /* resp */ - leal 8(%ebp), %edx - movl %edx, 4(%esp) /* args = __builtin_dwarf_cfa () */ - leal -12(%ebp), %edx - movl %edx, (%esp) /* &resp */ - movl %ebx, 8(%esp) -LCFI7: - call L_ffi_closure_SYSV_inner$stub - movl 8(%esp), %ebx - movl -12(%ebp), %ecx - cmpl $FFI_TYPE_INT, %eax - je Lcls_retint - cmpl $FFI_TYPE_FLOAT, %eax - je Lcls_retfloat - cmpl $FFI_TYPE_DOUBLE, %eax - je Lcls_retdouble - cmpl $FFI_TYPE_LONGDOUBLE, %eax - je Lcls_retldouble - cmpl $FFI_TYPE_SINT64, %eax - je Lcls_retllong - cmpl $FFI_TYPE_UINT8, %eax - je Lcls_retstruct1 - cmpl $FFI_TYPE_SINT8, %eax - je Lcls_retstruct1 - cmpl $FFI_TYPE_UINT16, %eax - je Lcls_retstruct2 - cmpl $FFI_TYPE_SINT16, %eax - je Lcls_retstruct2 - cmpl $FFI_TYPE_STRUCT, %eax - je Lcls_retstruct -Lcls_epilogue: - movl %ebp, %esp - popl %ebp - ret -Lcls_retint: - movl (%ecx), %eax - jmp Lcls_epilogue -Lcls_retfloat: - flds (%ecx) - jmp Lcls_epilogue -Lcls_retdouble: - fldl (%ecx) - jmp Lcls_epilogue -Lcls_retldouble: - fldt (%ecx) - jmp Lcls_epilogue -Lcls_retllong: - movl (%ecx), %eax - movl 4(%ecx), %edx - jmp Lcls_epilogue -Lcls_retstruct1: - movsbl (%ecx), %eax - jmp Lcls_epilogue -Lcls_retstruct2: - movswl (%ecx), %eax - jmp Lcls_epilogue -Lcls_retstruct: - lea -8(%ebp),%esp - movl %ebp, %esp - popl %ebp - ret $4 -LFE2: - -#if !FFI_NO_RAW_API - -#define RAW_CLOSURE_CIF_OFFSET ((FFI_TRAMPOLINE_SIZE + 3) & ~3) -#define RAW_CLOSURE_FUN_OFFSET (RAW_CLOSURE_CIF_OFFSET + 4) -#define RAW_CLOSURE_USER_DATA_OFFSET (RAW_CLOSURE_FUN_OFFSET + 4) -#define CIF_FLAGS_OFFSET 20 - - .align 4 -FFI_HIDDEN (ffi_closure_raw_SYSV) -.globl _ffi_closure_raw_SYSV - -_ffi_closure_raw_SYSV: -LFB3: - pushl %ebp -LCFI4: - movl %esp, %ebp -LCFI5: - pushl %esi -LCFI6: - subl $36, %esp - movl RAW_CLOSURE_CIF_OFFSET(%eax), %esi /* closure->cif */ - movl RAW_CLOSURE_USER_DATA_OFFSET(%eax), %edx /* closure->user_data */ - movl %edx, 12(%esp) /* user_data */ - leal 8(%ebp), %edx /* __builtin_dwarf_cfa () */ - movl %edx, 8(%esp) /* raw_args */ - leal -24(%ebp), %edx - movl %edx, 4(%esp) /* &res */ - movl %esi, (%esp) /* cif */ - call *RAW_CLOSURE_FUN_OFFSET(%eax) /* closure->fun */ - movl CIF_FLAGS_OFFSET(%esi), %eax /* rtype */ - cmpl $FFI_TYPE_INT, %eax - je Lrcls_retint - cmpl $FFI_TYPE_FLOAT, %eax - je Lrcls_retfloat - cmpl $FFI_TYPE_DOUBLE, %eax - je Lrcls_retdouble - cmpl $FFI_TYPE_LONGDOUBLE, %eax - je Lrcls_retldouble - cmpl $FFI_TYPE_SINT64, %eax - je Lrcls_retllong -Lrcls_epilogue: - addl $36, %esp - popl %esi - popl %ebp - ret -Lrcls_retint: - movl -24(%ebp), %eax - jmp Lrcls_epilogue -Lrcls_retfloat: - flds -24(%ebp) - jmp Lrcls_epilogue -Lrcls_retdouble: - fldl -24(%ebp) - jmp Lrcls_epilogue -Lrcls_retldouble: - fldt -24(%ebp) - jmp Lrcls_epilogue -Lrcls_retllong: - movl -24(%ebp), %eax - movl -20(%ebp), %edx - jmp Lrcls_epilogue -LFE3: -#endif - -.section __IMPORT,__jump_table,symbol_stubs,self_modifying_code+pure_instructions,5 -L_ffi_closure_SYSV_inner$stub: - .indirect_symbol _ffi_closure_SYSV_inner - hlt ; hlt ; hlt ; hlt ; hlt - - -.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support -EH_frame1: - .set L$set$0,LECIE1-LSCIE1 - .long L$set$0 -LSCIE1: - .long 0x0 - .byte 0x1 - .ascii "zR\0" - .byte 0x1 - .byte 0x7c - .byte 0x8 - .byte 0x1 - .byte 0x10 - .byte 0xc - .byte 0x5 - .byte 0x4 - .byte 0x88 - .byte 0x1 - .align 2 -LECIE1: -.globl _ffi_call_SYSV.eh -_ffi_call_SYSV.eh: -LSFDE1: - .set L$set$1,LEFDE1-LASFDE1 - .long L$set$1 -LASFDE1: - .long LASFDE1-EH_frame1 - .long LFB1-. - .set L$set$2,LFE1-LFB1 - .long L$set$2 - .byte 0x0 - .byte 0x4 - .set L$set$3,LCFI0-LFB1 - .long L$set$3 - .byte 0xe - .byte 0x8 - .byte 0x84 - .byte 0x2 - .byte 0x4 - .set L$set$4,LCFI1-LCFI0 - .long L$set$4 - .byte 0xd - .byte 0x4 - .align 2 -LEFDE1: -.globl _ffi_closure_SYSV.eh -_ffi_closure_SYSV.eh: -LSFDE2: - .set L$set$5,LEFDE2-LASFDE2 - .long L$set$5 -LASFDE2: - .long LASFDE2-EH_frame1 - .long LFB2-. - .set L$set$6,LFE2-LFB2 - .long L$set$6 - .byte 0x0 - .byte 0x4 - .set L$set$7,LCFI2-LFB2 - .long L$set$7 - .byte 0xe - .byte 0x8 - .byte 0x84 - .byte 0x2 - .byte 0x4 - .set L$set$8,LCFI3-LCFI2 - .long L$set$8 - .byte 0xd - .byte 0x4 - .align 2 -LEFDE2: - -#if !FFI_NO_RAW_API - -.globl _ffi_closure_raw_SYSV.eh -_ffi_closure_raw_SYSV.eh: -LSFDE3: - .set L$set$10,LEFDE3-LASFDE3 - .long L$set$10 -LASFDE3: - .long LASFDE3-EH_frame1 - .long LFB3-. - .set L$set$11,LFE3-LFB3 - .long L$set$11 - .byte 0x0 - .byte 0x4 - .set L$set$12,LCFI4-LFB3 - .long L$set$12 - .byte 0xe - .byte 0x8 - .byte 0x84 - .byte 0x2 - .byte 0x4 - .set L$set$13,LCFI5-LCFI4 - .long L$set$13 - .byte 0xd - .byte 0x4 - .byte 0x4 - .set L$set$14,LCFI6-LCFI5 - .long L$set$14 - .byte 0x85 - .byte 0x3 - .align 2 -LEFDE3: - -#endif - -#endif /* ifndef __x86_64__ */ - -#endif /* defined __i386__ */ diff --git a/Modules/_ctypes/libffi_osx/x86/x86-ffi64.c b/Modules/_ctypes/libffi_osx/x86/x86-ffi64.c deleted file mode 100644 index 8e7d0164..00000000 --- a/Modules/_ctypes/libffi_osx/x86/x86-ffi64.c +++ /dev/null @@ -1,737 +0,0 @@ -#ifdef __x86_64__ - -/* ----------------------------------------------------------------------- - x86-ffi64.c - Copyright (c) 2002 Bo Thorsen <bo@suse.de> - - x86-64 Foreign Function Interface - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ - -#include <ffi.h> -#include <ffi_common.h> - -#include <stdlib.h> -#include <stdarg.h> - -#define MAX_GPR_REGS 6 -#define MAX_SSE_REGS 8 - -typedef struct RegisterArgs { - /* Registers for argument passing. */ - UINT64 gpr[MAX_GPR_REGS]; - __int128_t sse[MAX_SSE_REGS]; -} RegisterArgs; - -extern void -ffi_call_unix64( - void* args, - unsigned long bytes, - unsigned flags, - void* raddr, - void (*fnaddr)(void), - unsigned ssecount); - -/* All reference to register classes here is identical to the code in - gcc/config/i386/i386.c. Do *not* change one without the other. */ - -/* Register class used for passing given 64bit part of the argument. - These represent classes as documented by the PS ABI, with the exception - of SSESF, SSEDF classes, that are basically SSE class, just gcc will - use SF or DFmode move instead of DImode to avoid reformating penalties. - - Similarly we play games with INTEGERSI_CLASS to use cheaper SImode moves - whenever possible (upper half does contain padding). */ -enum x86_64_reg_class -{ - X86_64_NO_CLASS, - X86_64_INTEGER_CLASS, - X86_64_INTEGERSI_CLASS, - X86_64_SSE_CLASS, - X86_64_SSESF_CLASS, - X86_64_SSEDF_CLASS, - X86_64_SSEUP_CLASS, - X86_64_X87_CLASS, - X86_64_X87UP_CLASS, - X86_64_COMPLEX_X87_CLASS, - X86_64_MEMORY_CLASS -}; - -#define MAX_CLASSES 4 -#define SSE_CLASS_P(X) ((X) >= X86_64_SSE_CLASS && X <= X86_64_SSEUP_CLASS) - -/* x86-64 register passing implementation. See x86-64 ABI for details. Goal - of this code is to classify each 8bytes of incoming argument by the register - class and assign registers accordingly. */ - -/* Return the union class of CLASS1 and CLASS2. - See the x86-64 PS ABI for details. */ -static enum x86_64_reg_class -merge_classes( - enum x86_64_reg_class class1, - enum x86_64_reg_class class2) -{ - /* Rule #1: If both classes are equal, this is the resulting class. */ - if (class1 == class2) - return class1; - - /* Rule #2: If one of the classes is NO_CLASS, the resulting class is - the other class. */ - if (class1 == X86_64_NO_CLASS) - return class2; - - if (class2 == X86_64_NO_CLASS) - return class1; - - /* Rule #3: If one of the classes is MEMORY, the result is MEMORY. */ - if (class1 == X86_64_MEMORY_CLASS || class2 == X86_64_MEMORY_CLASS) - return X86_64_MEMORY_CLASS; - - /* Rule #4: If one of the classes is INTEGER, the result is INTEGER. */ - if ((class1 == X86_64_INTEGERSI_CLASS && class2 == X86_64_SSESF_CLASS) - || (class2 == X86_64_INTEGERSI_CLASS && class1 == X86_64_SSESF_CLASS)) - return X86_64_INTEGERSI_CLASS; - - if (class1 == X86_64_INTEGER_CLASS || class1 == X86_64_INTEGERSI_CLASS - || class2 == X86_64_INTEGER_CLASS || class2 == X86_64_INTEGERSI_CLASS) - return X86_64_INTEGER_CLASS; - - /* Rule #5: If one of the classes is X87, X87UP, or COMPLEX_X87 class, - MEMORY is used. */ - if (class1 == X86_64_X87_CLASS - || class1 == X86_64_X87UP_CLASS - || class1 == X86_64_COMPLEX_X87_CLASS - || class2 == X86_64_X87_CLASS - || class2 == X86_64_X87UP_CLASS - || class2 == X86_64_COMPLEX_X87_CLASS) - return X86_64_MEMORY_CLASS; - - /* Rule #6: Otherwise class SSE is used. */ - return X86_64_SSE_CLASS; -} - -/* Classify the argument of type TYPE and mode MODE. - CLASSES will be filled by the register class used to pass each word - of the operand. The number of words is returned. In case the parameter - should be passed in memory, 0 is returned. As a special case for zero - sized containers, classes[0] will be NO_CLASS and 1 is returned. - - See the x86-64 PS ABI for details. */ - -static int -classify_argument( - ffi_type* type, - enum x86_64_reg_class classes[], - size_t byte_offset) -{ - switch (type->type) - { - case FFI_TYPE_UINT8: - case FFI_TYPE_SINT8: - case FFI_TYPE_UINT16: - case FFI_TYPE_SINT16: - case FFI_TYPE_UINT32: - case FFI_TYPE_SINT32: - case FFI_TYPE_UINT64: - case FFI_TYPE_SINT64: - case FFI_TYPE_POINTER: -#if 0 - if (byte_offset + type->size <= 4) - classes[0] = X86_64_INTEGERSI_CLASS; - else - classes[0] = X86_64_INTEGER_CLASS; - - return 1; -#else - { - int size = byte_offset + type->size; - - if (size <= 4) - { - classes[0] = X86_64_INTEGERSI_CLASS; - return 1; - } - else if (size <= 8) - { - classes[0] = X86_64_INTEGER_CLASS; - return 1; - } - else if (size <= 12) - { - classes[0] = X86_64_INTEGER_CLASS; - classes[1] = X86_64_INTEGERSI_CLASS; - return 2; - } - else if (size <= 16) - { - classes[0] = classes[1] = X86_64_INTEGERSI_CLASS; - return 2; - } - else - FFI_ASSERT (0); - } -#endif - - case FFI_TYPE_FLOAT: - if (byte_offset == 0) - classes[0] = X86_64_SSESF_CLASS; - else - classes[0] = X86_64_SSE_CLASS; - - return 1; - - case FFI_TYPE_DOUBLE: - classes[0] = X86_64_SSEDF_CLASS; - return 1; - - case FFI_TYPE_LONGDOUBLE: - classes[0] = X86_64_X87_CLASS; - classes[1] = X86_64_X87UP_CLASS; - return 2; - - case FFI_TYPE_STRUCT: - { - ffi_type** ptr; - int i; - enum x86_64_reg_class subclasses[MAX_CLASSES]; - const int UNITS_PER_WORD = 8; - int words = - (type->size + UNITS_PER_WORD - 1) / UNITS_PER_WORD; - - /* If the struct is larger than 16 bytes, pass it on the stack. */ - if (type->size > 16) - return 0; - - for (i = 0; i < words; i++) - classes[i] = X86_64_NO_CLASS; - - /* Merge the fields of structure. */ - for (ptr = type->elements; *ptr != NULL; ptr++) - { - int num, pos; - - byte_offset = ALIGN(byte_offset, (*ptr)->alignment); - - num = classify_argument(*ptr, subclasses, byte_offset % 8); - - if (num == 0) - return 0; - - pos = byte_offset / 8; - - for (i = 0; i < num; i++) - { - classes[i + pos] = - merge_classes(subclasses[i], classes[i + pos]); - } - - byte_offset += (*ptr)->size; - } - - if (words > 2) - { - /* When size > 16 bytes, if the first one isn't - X86_64_SSE_CLASS or any other ones aren't - X86_64_SSEUP_CLASS, everything should be passed in - memory. */ - if (classes[0] != X86_64_SSE_CLASS) - return 0; - - for (i = 1; i < words; i++) - if (classes[i] != X86_64_SSEUP_CLASS) - return 0; - } - - - /* Final merger cleanup. */ - for (i = 0; i < words; i++) - { - /* If one class is MEMORY, everything should be passed in - memory. */ - if (classes[i] == X86_64_MEMORY_CLASS) - return 0; - - /* The X86_64_SSEUP_CLASS should be always preceded by - X86_64_SSE_CLASS. */ - if (classes[i] == X86_64_SSEUP_CLASS - && classes[i - 1] != X86_64_SSE_CLASS - && classes[i - 1] != X86_64_SSEUP_CLASS) - { - FFI_ASSERT(i != 0); - classes[i] = X86_64_SSE_CLASS; - } - - /* X86_64_X87UP_CLASS should be preceded by X86_64_X87_CLASS. */ - if (classes[i] == X86_64_X87UP_CLASS - && classes[i - 1] != X86_64_X87_CLASS) - { - FFI_ASSERT(i != 0); - classes[i] = X86_64_SSE_CLASS; - } - } - - return words; - } - - default: - FFI_ASSERT(0); - } - - return 0; /* Never reached. */ -} - -/* Examine the argument and return set number of register required in each - class. Return zero if parameter should be passed in memory, otherwise - the number of registers. */ -static int -examine_argument( - ffi_type* type, - enum x86_64_reg_class classes[MAX_CLASSES], - _Bool in_return, - int* pngpr, - int* pnsse) -{ - int n = classify_argument(type, classes, 0); - int ngpr = 0; - int nsse = 0; - int i; - - if (n == 0) - return 0; - - for (i = 0; i < n; ++i) - { - switch (classes[i]) - { - case X86_64_INTEGER_CLASS: - case X86_64_INTEGERSI_CLASS: - ngpr++; - break; - - case X86_64_SSE_CLASS: - case X86_64_SSESF_CLASS: - case X86_64_SSEDF_CLASS: - nsse++; - break; - - case X86_64_NO_CLASS: - case X86_64_SSEUP_CLASS: - break; - - case X86_64_X87_CLASS: - case X86_64_X87UP_CLASS: - case X86_64_COMPLEX_X87_CLASS: - return in_return != 0; - - default: - abort(); - } - } - - *pngpr = ngpr; - *pnsse = nsse; - - return n; -} - -/* Perform machine dependent cif processing. */ -ffi_status -ffi_prep_cif_machdep( - ffi_cif* cif) -{ - int gprcount = 0; - int ssecount = 0; - int flags = cif->rtype->type; - int i, avn, n, ngpr, nsse; - enum x86_64_reg_class classes[MAX_CLASSES]; - size_t bytes; - - if (flags != FFI_TYPE_VOID) - { - n = examine_argument (cif->rtype, classes, 1, &ngpr, &nsse); - - if (n == 0) - { - /* The return value is passed in memory. A pointer to that - memory is the first argument. Allocate a register for it. */ - gprcount++; - - /* We don't have to do anything in asm for the return. */ - flags = FFI_TYPE_VOID; - } - else if (flags == FFI_TYPE_STRUCT) - { - /* Mark which registers the result appears in. */ - _Bool sse0 = SSE_CLASS_P(classes[0]); - _Bool sse1 = n == 2 && SSE_CLASS_P(classes[1]); - - if (sse0 && !sse1) - flags |= 1 << 8; - else if (!sse0 && sse1) - flags |= 1 << 9; - else if (sse0 && sse1) - flags |= 1 << 10; - - /* Mark the true size of the structure. */ - flags |= cif->rtype->size << 12; - } - } - - /* Go over all arguments and determine the way they should be passed. - If it's in a register and there is space for it, let that be so. If - not, add it's size to the stack byte count. */ - for (bytes = 0, i = 0, avn = cif->nargs; i < avn; i++) - { - if (examine_argument(cif->arg_types[i], classes, 0, &ngpr, &nsse) == 0 - || gprcount + ngpr > MAX_GPR_REGS - || ssecount + nsse > MAX_SSE_REGS) - { - long align = cif->arg_types[i]->alignment; - - if (align < 8) - align = 8; - - bytes = ALIGN(bytes, align); - bytes += cif->arg_types[i]->size; - } - else - { - gprcount += ngpr; - ssecount += nsse; - } - } - - if (ssecount) - flags |= 1 << 11; - - cif->flags = flags; - cif->bytes = bytes; - cif->bytes = ALIGN(bytes,8); - - return FFI_OK; -} - -void -ffi_call( - ffi_cif* cif, - void (*fn)(void), - void* rvalue, - void** avalue) -{ - enum x86_64_reg_class classes[MAX_CLASSES]; - char* stack; - char* argp; - ffi_type** arg_types; - int gprcount, ssecount, ngpr, nsse, i, avn; - _Bool ret_in_memory; - RegisterArgs* reg_args; - - /* Can't call 32-bit mode from 64-bit mode. */ - FFI_ASSERT(cif->abi == FFI_UNIX64); - - /* If the return value is a struct and we don't have a return value - address then we need to make one. Note the setting of flags to - VOID above in ffi_prep_cif_machdep. */ - ret_in_memory = (cif->rtype->type == FFI_TYPE_STRUCT - && (cif->flags & 0xff) == FFI_TYPE_VOID); - - if (rvalue == NULL && ret_in_memory) - rvalue = alloca (cif->rtype->size); - - /* Allocate the space for the arguments, plus 4 words of temp space. */ - stack = alloca(sizeof(RegisterArgs) + cif->bytes + 4 * 8); - reg_args = (RegisterArgs*)stack; - argp = stack + sizeof(RegisterArgs); - - gprcount = ssecount = 0; - - /* If the return value is passed in memory, add the pointer as the - first integer argument. */ - if (ret_in_memory) - reg_args->gpr[gprcount++] = (long) rvalue; - - avn = cif->nargs; - arg_types = cif->arg_types; - - for (i = 0; i < avn; ++i) - { - size_t size = arg_types[i]->size; - int n; - - n = examine_argument (arg_types[i], classes, 0, &ngpr, &nsse); - - if (n == 0 - || gprcount + ngpr > MAX_GPR_REGS - || ssecount + nsse > MAX_SSE_REGS) - { - long align = arg_types[i]->alignment; - - /* Stack arguments are *always* at least 8 byte aligned. */ - if (align < 8) - align = 8; - - /* Pass this argument in memory. */ - argp = (void *) ALIGN (argp, align); - memcpy (argp, avalue[i], size); - argp += size; - } - else - { /* The argument is passed entirely in registers. */ - char *a = (char *) avalue[i]; - int j; - - for (j = 0; j < n; j++, a += 8, size -= 8) - { - switch (classes[j]) - { - case X86_64_INTEGER_CLASS: - case X86_64_INTEGERSI_CLASS: - reg_args->gpr[gprcount] = 0; - switch (arg_types[i]->type) { - case FFI_TYPE_SINT8: - { - int8_t shortval = *(int8_t*)a; - int64_t actval = (int64_t)shortval; - reg_args->gpr[gprcount] = actval; - /*memcpy (®_args->gpr[gprcount], &actval, 8);*/ - break; - } - - case FFI_TYPE_SINT16: - { - int16_t shortval = *(int16_t*)a; - int64_t actval = (int64_t)shortval; - memcpy (®_args->gpr[gprcount], &actval, 8); - break; - } - - case FFI_TYPE_SINT32: - { - int32_t shortval = *(int32_t*)a; - int64_t actval = (int64_t)shortval; - memcpy (®_args->gpr[gprcount], &actval, 8); - break; - } - - case FFI_TYPE_UINT8: - { - u_int8_t shortval = *(u_int8_t*)a; - u_int64_t actval = (u_int64_t)shortval; - /*memcpy (®_args->gpr[gprcount], &actval, 8);*/ - reg_args->gpr[gprcount] = actval; - break; - } - - case FFI_TYPE_UINT16: - { - u_int16_t shortval = *(u_int16_t*)a; - u_int64_t actval = (u_int64_t)shortval; - memcpy (®_args->gpr[gprcount], &actval, 8); - break; - } - - case FFI_TYPE_UINT32: - { - u_int32_t shortval = *(u_int32_t*)a; - u_int64_t actval = (u_int64_t)shortval; - memcpy (®_args->gpr[gprcount], &actval, 8); - break; - } - - default: - //memcpy (®_args->gpr[gprcount], a, size < 8 ? size : 8); - reg_args->gpr[gprcount] = *(int64_t*)a; - } - gprcount++; - break; - - case X86_64_SSE_CLASS: - case X86_64_SSEDF_CLASS: - reg_args->sse[ssecount++] = *(UINT64 *) a; - break; - - case X86_64_SSESF_CLASS: - reg_args->sse[ssecount++] = *(UINT32 *) a; - break; - - default: - abort(); - } - } - } - } - - ffi_call_unix64 (stack, cif->bytes + sizeof(RegisterArgs), - cif->flags, rvalue, fn, ssecount); -} - -extern void ffi_closure_unix64(void); - -ffi_status -ffi_prep_closure( - ffi_closure* closure, - ffi_cif* cif, - void (*fun)(ffi_cif*, void*, void**, void*), - void* user_data) -{ - volatile unsigned short* tramp; - - if (cif->abi != FFI_UNIX64) - return FFI_BAD_ABI; - - tramp = (volatile unsigned short*)&closure->tramp[0]; - - tramp[0] = 0xbb49; /* mov <code>, %r11 */ - *(void* volatile*)&tramp[1] = ffi_closure_unix64; - tramp[5] = 0xba49; /* mov <data>, %r10 */ - *(void* volatile*)&tramp[6] = closure; - - /* Set the carry bit if the function uses any sse registers. - This is clc or stc, together with the first byte of the jmp. */ - tramp[10] = cif->flags & (1 << 11) ? 0x49f9 : 0x49f8; - tramp[11] = 0xe3ff; /* jmp *%r11 */ - - closure->cif = cif; - closure->fun = fun; - closure->user_data = user_data; - - return FFI_OK; -} - -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wmissing-prototypes" -int -ffi_closure_unix64_inner( - ffi_closure* closure, - void* rvalue, - RegisterArgs* reg_args, - char* argp) -#pragma clang diagnostic pop -{ - ffi_cif* cif = closure->cif; - void** avalue = alloca(cif->nargs * sizeof(void *)); - ffi_type** arg_types; - long i, avn; - int gprcount = 0; - int ssecount = 0; - int ngpr, nsse; - int ret; - - ret = cif->rtype->type; - - if (ret != FFI_TYPE_VOID) - { - enum x86_64_reg_class classes[MAX_CLASSES]; - int n = examine_argument (cif->rtype, classes, 1, &ngpr, &nsse); - - if (n == 0) - { - /* The return value goes in memory. Arrange for the closure - return value to go directly back to the original caller. */ - rvalue = (void *) reg_args->gpr[gprcount++]; - - /* We don't have to do anything in asm for the return. */ - ret = FFI_TYPE_VOID; - } - else if (ret == FFI_TYPE_STRUCT && n == 2) - { - /* Mark which register the second word of the structure goes in. */ - _Bool sse0 = SSE_CLASS_P (classes[0]); - _Bool sse1 = SSE_CLASS_P (classes[1]); - - if (!sse0 && sse1) - ret |= 1 << 8; - else if (sse0 && !sse1) - ret |= 1 << 9; - } - } - - avn = cif->nargs; - arg_types = cif->arg_types; - - for (i = 0; i < avn; ++i) - { - enum x86_64_reg_class classes[MAX_CLASSES]; - int n; - - n = examine_argument (arg_types[i], classes, 0, &ngpr, &nsse); - - if (n == 0 - || gprcount + ngpr > MAX_GPR_REGS - || ssecount + nsse > MAX_SSE_REGS) - { - long align = arg_types[i]->alignment; - - /* Stack arguments are *always* at least 8 byte aligned. */ - if (align < 8) - align = 8; - - /* Pass this argument in memory. */ - argp = (void *) ALIGN (argp, align); - avalue[i] = argp; - argp += arg_types[i]->size; - } - -#if !defined(X86_DARWIN) - /* If the argument is in a single register, or two consecutive - registers, then we can use that address directly. */ - else if (n == 1 || (n == 2 && - SSE_CLASS_P (classes[0]) == SSE_CLASS_P (classes[1]))) - { - // The argument is in a single register. - if (SSE_CLASS_P (classes[0])) - { - avalue[i] = ®_args->sse[ssecount]; - ssecount += n; - } - else - { - avalue[i] = ®_args->gpr[gprcount]; - gprcount += n; - } - } -#endif - - /* Otherwise, allocate space to make them consecutive. */ - else - { - char *a = alloca (16); - int j; - - avalue[i] = a; - - for (j = 0; j < n; j++, a += 8) - { - if (SSE_CLASS_P (classes[j])) - memcpy (a, ®_args->sse[ssecount++], 8); - else - memcpy (a, ®_args->gpr[gprcount++], 8); - } - } - } - - /* Invoke the closure. */ - closure->fun (cif, rvalue, avalue, closure->user_data); - - /* Tell assembly how to perform return type promotions. */ - return ret; -} - -#endif /* __x86_64__ */ diff --git a/Modules/_ctypes/libffi_osx/x86/x86-ffi_darwin.c b/Modules/_ctypes/libffi_osx/x86/x86-ffi_darwin.c deleted file mode 100644 index 706ea0f5..00000000 --- a/Modules/_ctypes/libffi_osx/x86/x86-ffi_darwin.c +++ /dev/null @@ -1,438 +0,0 @@ -#ifdef __i386__ -/* ----------------------------------------------------------------------- - ffi.c - Copyright (c) 1996, 1998, 1999, 2001 Red Hat, Inc. - Copyright (c) 2002 Ranjit Mathew - Copyright (c) 2002 Bo Thorsen - Copyright (c) 2002 Roger Sayle - - x86 Foreign Function Interface - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ - -#include <ffi.h> -#include <ffi_common.h> - -#include <stdlib.h> - -/* ffi_prep_args is called by the assembly routine once stack space - has been allocated for the function's arguments */ - -void ffi_prep_args(char *stack, extended_cif *ecif); - -void ffi_prep_args(char *stack, extended_cif *ecif) -{ - register unsigned int i; - register void **p_argv; - register char *argp; - register ffi_type **p_arg; - - argp = stack; - - if (ecif->cif->flags == FFI_TYPE_STRUCT) - { - *(void **) argp = ecif->rvalue; - argp += 4; - } - - p_argv = ecif->avalue; - - for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; - i != 0; - i--, p_arg++) - { - size_t z; - - /* Align if necessary */ - if ((sizeof(int) - 1) & (unsigned) argp) - argp = (char *) ALIGN(argp, sizeof(int)); - - z = (*p_arg)->size; - if (z < sizeof(int)) - { - z = sizeof(int); - switch ((*p_arg)->type) - { - case FFI_TYPE_SINT8: - *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv); - break; - - case FFI_TYPE_UINT8: - *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv); - break; - - case FFI_TYPE_SINT16: - *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv); - break; - - case FFI_TYPE_UINT16: - *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv); - break; - - case FFI_TYPE_SINT32: - *(signed int *) argp = (signed int)*(SINT32 *)(* p_argv); - break; - - case FFI_TYPE_UINT32: - *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv); - break; - - case FFI_TYPE_STRUCT: - *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv); - break; - - default: - FFI_ASSERT(0); - } - } - else - { - memcpy(argp, *p_argv, z); - } - p_argv++; - argp += z; - } - - return; -} - -/* Perform machine dependent cif processing */ -ffi_status ffi_prep_cif_machdep(ffi_cif *cif) -{ - /* Set the return type flag */ - switch (cif->rtype->type) - { - case FFI_TYPE_VOID: -#ifdef X86 - case FFI_TYPE_STRUCT: - case FFI_TYPE_UINT8: - case FFI_TYPE_UINT16: - case FFI_TYPE_SINT8: - case FFI_TYPE_SINT16: -#endif - - case FFI_TYPE_SINT64: - case FFI_TYPE_FLOAT: - case FFI_TYPE_DOUBLE: - case FFI_TYPE_LONGDOUBLE: - cif->flags = (unsigned) cif->rtype->type; - break; - - case FFI_TYPE_UINT64: - cif->flags = FFI_TYPE_SINT64; - break; - -#ifndef X86 - case FFI_TYPE_STRUCT: - if (cif->rtype->size == 1) - { - cif->flags = FFI_TYPE_SINT8; /* same as char size */ - } - else if (cif->rtype->size == 2) - { - cif->flags = FFI_TYPE_SINT16; /* same as short size */ - } - else if (cif->rtype->size == 4) - { - cif->flags = FFI_TYPE_INT; /* same as int type */ - } - else if (cif->rtype->size == 8) - { - cif->flags = FFI_TYPE_SINT64; /* same as int64 type */ - } - else - { - cif->flags = FFI_TYPE_STRUCT; - } - break; -#endif - - default: - cif->flags = FFI_TYPE_INT; - break; - } - -#ifdef X86_DARWIN - cif->bytes = (cif->bytes + 15) & ~0xF; -#endif - - return FFI_OK; -} - -extern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *, - unsigned, unsigned, unsigned *, void (*fn)()); - -#ifdef X86_WIN32 -extern void ffi_call_STDCALL(void (*)(char *, extended_cif *), extended_cif *, - unsigned, unsigned, unsigned *, void (*fn)()); - -#endif /* X86_WIN32 */ - -void ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue) -{ - extended_cif ecif; - - ecif.cif = cif; - ecif.avalue = avalue; - - /* If the return value is a struct and we don't have a return */ - /* value address then we need to make one */ - - if ((rvalue == NULL) && - (cif->flags == FFI_TYPE_STRUCT)) - { - ecif.rvalue = alloca(cif->rtype->size); - } - else - ecif.rvalue = rvalue; - - - switch (cif->abi) - { - case FFI_SYSV: - ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue, - fn); - break; -#ifdef X86_WIN32 - case FFI_STDCALL: - ffi_call_STDCALL(ffi_prep_args, &ecif, cif->bytes, cif->flags, - ecif.rvalue, fn); - break; -#endif /* X86_WIN32 */ - default: - FFI_ASSERT(0); - break; - } -} - - -/** private members **/ - -static void ffi_prep_incoming_args_SYSV (char *stack, void **ret, - void** args, ffi_cif* cif); -void FFI_HIDDEN ffi_closure_SYSV (ffi_closure *) -__attribute__ ((regparm(1))); -unsigned int FFI_HIDDEN ffi_closure_SYSV_inner (ffi_closure *, void **, void *) -__attribute__ ((regparm(1))); -void FFI_HIDDEN ffi_closure_raw_SYSV (ffi_raw_closure *) -__attribute__ ((regparm(1))); - -/* This function is jumped to by the trampoline */ - -unsigned int FFI_HIDDEN -ffi_closure_SYSV_inner (closure, respp, args) -ffi_closure *closure; -void **respp; -void *args; -{ - // our various things... - ffi_cif *cif; - void **arg_area; - - cif = closure->cif; - arg_area = (void**) alloca (cif->nargs * sizeof (void*)); - - /* this call will initialize ARG_AREA, such that each - * element in that array points to the corresponding - * value on the stack; and if the function returns - * a structure, it will re-set RESP to point to the - * structure return address. */ - - ffi_prep_incoming_args_SYSV(args, respp, arg_area, cif); - - (closure->fun) (cif, *respp, arg_area, closure->user_data); - - return cif->flags; -} - -static void -ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, void **avalue, - ffi_cif *cif) -{ - register unsigned int i; - register void **p_argv; - register char *argp; - register ffi_type **p_arg; - - argp = stack; - - if ( cif->flags == FFI_TYPE_STRUCT ) { - *rvalue = *(void **) argp; - argp += 4; - } - - p_argv = avalue; - - for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++) - { - size_t z; - - /* Align if necessary */ - if ((sizeof(int) - 1) & (unsigned) argp) { - argp = (char *) ALIGN(argp, sizeof(int)); - } - - z = (*p_arg)->size; - - /* because we're little endian, this is what it turns into. */ - - *p_argv = (void*) argp; - - p_argv++; - argp += z; - } - - return; -} - -/* How to make a trampoline. Derived from gcc/config/i386/i386.c. */ - -#define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX) \ -({ unsigned char *__tramp = (unsigned char*)(TRAMP); \ -unsigned int __fun = (unsigned int)(FUN); \ -unsigned int __ctx = (unsigned int)(CTX); \ -unsigned int __dis = __fun - (__ctx + FFI_TRAMPOLINE_SIZE); \ -*(unsigned char*) &__tramp[0] = 0xb8; \ -*(unsigned int*) &__tramp[1] = __ctx; /* movl __ctx, %eax */ \ -*(unsigned char *) &__tramp[5] = 0xe9; \ -*(unsigned int*) &__tramp[6] = __dis; /* jmp __fun */ \ -}) - - -/* the cif must already be prep'ed */ -ffi_status -ffi_prep_closure (ffi_closure* closure, - ffi_cif* cif, - void (*fun)(ffi_cif*,void*,void**,void*), - void *user_data) -{ - if (cif->abi != FFI_SYSV) - return FFI_BAD_ABI; - - FFI_INIT_TRAMPOLINE (&closure->tramp[0], \ - &ffi_closure_SYSV, \ - (void*)closure); - - closure->cif = cif; - closure->user_data = user_data; - closure->fun = fun; - - return FFI_OK; -} - -/* ------- Native raw API support -------------------------------- */ - -#if !FFI_NO_RAW_API - -ffi_status -ffi_prep_raw_closure_loc (ffi_raw_closure* closure, - ffi_cif* cif, - void (*fun)(ffi_cif*,void*,ffi_raw*,void*), - void *user_data, - void *codeloc) -{ - int i; - - FFI_ASSERT (cif->abi == FFI_SYSV); - - // we currently don't support certain kinds of arguments for raw - // closures. This should be implemented by a separate assembly language - // routine, since it would require argument processing, something we - // don't do now for performance. - - for (i = cif->nargs-1; i >= 0; i--) - { - FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_STRUCT); - FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_LONGDOUBLE); - } - - - FFI_INIT_TRAMPOLINE (&closure->tramp[0], &ffi_closure_raw_SYSV, - codeloc); - - closure->cif = cif; - closure->user_data = user_data; - closure->fun = fun; - - return FFI_OK; -} - -static void -ffi_prep_args_raw(char *stack, extended_cif *ecif) -{ - memcpy (stack, ecif->avalue, ecif->cif->bytes); -} - -/* we borrow this routine from libffi (it must be changed, though, to - * actually call the function passed in the first argument. as of - * libffi-1.20, this is not the case.) - */ - -extern void -ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *, unsigned, - unsigned, unsigned *, void (*fn)()); - -#ifdef X86_WIN32 -extern void -ffi_call_STDCALL(void (*)(char *, extended_cif *), extended_cif *, unsigned, - unsigned, unsigned *, void (*fn)()); -#endif /* X86_WIN32 */ - -void -ffi_raw_call(ffi_cif *cif, void (*fn)(), void *rvalue, ffi_raw *fake_avalue) -{ - extended_cif ecif; - void **avalue = (void **)fake_avalue; - - ecif.cif = cif; - ecif.avalue = avalue; - - /* If the return value is a struct and we don't have a return */ - /* value address then we need to make one */ - - if ((rvalue == NULL) && - (cif->rtype->type == FFI_TYPE_STRUCT)) - { - ecif.rvalue = alloca(cif->rtype->size); - } - else - ecif.rvalue = rvalue; - - - switch (cif->abi) - { - case FFI_SYSV: - ffi_call_SYSV(ffi_prep_args_raw, &ecif, cif->bytes, cif->flags, - ecif.rvalue, fn); - break; -#ifdef X86_WIN32 - case FFI_STDCALL: - ffi_call_STDCALL(ffi_prep_args_raw, &ecif, cif->bytes, cif->flags, - ecif.rvalue, fn); - break; -#endif /* X86_WIN32 */ - default: - FFI_ASSERT(0); - break; - } -} - -#endif -#endif // __i386__ diff --git a/Modules/_ctypes/malloc_closure.c b/Modules/_ctypes/malloc_closure.c index 108660c9..3a859322 100644 --- a/Modules/_ctypes/malloc_closure.c +++ b/Modules/_ctypes/malloc_closure.c @@ -1,3 +1,6 @@ +#ifndef Py_BUILD_CORE_BUILTIN +# define Py_BUILD_CORE_MODULE 1 +#endif #include <Python.h> #include <ffi.h> #ifdef MS_WIN32 diff --git a/Modules/_ctypes/stgdict.c b/Modules/_ctypes/stgdict.c index b7134ce2..b1b2bac1 100644 --- a/Modules/_ctypes/stgdict.c +++ b/Modules/_ctypes/stgdict.c @@ -1,7 +1,6 @@ #ifndef Py_BUILD_CORE_BUILTIN # define Py_BUILD_CORE_MODULE 1 #endif -#define NEEDS_PY_IDENTIFIER #include "Python.h" // windows.h must be included before pycore internal headers @@ -226,6 +225,8 @@ MakeFields(PyObject *type, CFieldObject *descr, if (fieldlist == NULL) return -1; + ctypes_state *st = GLOBAL_STATE(); + PyTypeObject *cfield_tp = st->PyCField_Type; for (i = 0; i < PySequence_Fast_GET_SIZE(fieldlist); ++i) { PyObject *pair = PySequence_Fast_GET_ITEM(fieldlist, i); /* borrowed */ PyObject *fname, *ftype, *bits; @@ -241,7 +242,7 @@ MakeFields(PyObject *type, CFieldObject *descr, Py_DECREF(fieldlist); return -1; } - if (!Py_IS_TYPE(fdescr, &PyCField_Type)) { + if (!Py_IS_TYPE(fdescr, cfield_tp)) { PyErr_SetString(PyExc_TypeError, "unexpected type"); Py_DECREF(fdescr); Py_DECREF(fieldlist); @@ -258,18 +259,17 @@ MakeFields(PyObject *type, CFieldObject *descr, } continue; } - new_descr = (CFieldObject *)PyCField_Type.tp_alloc((PyTypeObject *)&PyCField_Type, 0); + new_descr = (CFieldObject *)cfield_tp->tp_alloc(cfield_tp, 0); if (new_descr == NULL) { Py_DECREF(fdescr); Py_DECREF(fieldlist); return -1; } - assert(Py_IS_TYPE(new_descr, &PyCField_Type)); + assert(Py_IS_TYPE(new_descr, cfield_tp)); new_descr->size = fdescr->size; new_descr->offset = fdescr->offset + offset; new_descr->index = fdescr->index + index; - new_descr->proto = fdescr->proto; - Py_XINCREF(new_descr->proto); + new_descr->proto = Py_XNewRef(fdescr->proto); new_descr->getfunc = fdescr->getfunc; new_descr->setfunc = fdescr->setfunc; @@ -291,12 +291,11 @@ MakeFields(PyObject *type, CFieldObject *descr, static int MakeAnonFields(PyObject *type) { - _Py_IDENTIFIER(_anonymous_); PyObject *anon; PyObject *anon_names; Py_ssize_t i; - if (_PyObject_LookupAttrId(type, &PyId__anonymous_, &anon) < 0) { + if (_PyObject_LookupAttr(type, &_Py_ID(_anonymous_), &anon) < 0) { return -1; } if (anon == NULL) { @@ -307,6 +306,8 @@ MakeAnonFields(PyObject *type) if (anon_names == NULL) return -1; + ctypes_state *st = GLOBAL_STATE(); + PyTypeObject *cfield_tp = st->PyCField_Type; for (i = 0; i < PySequence_Fast_GET_SIZE(anon_names); ++i) { PyObject *fname = PySequence_Fast_GET_ITEM(anon_names, i); /* borrowed */ CFieldObject *descr = (CFieldObject *)PyObject_GetAttr(type, fname); @@ -314,7 +315,7 @@ MakeAnonFields(PyObject *type) Py_DECREF(anon_names); return -1; } - if (!Py_IS_TYPE(descr, &PyCField_Type)) { + if (!Py_IS_TYPE(descr, cfield_tp)) { PyErr_Format(PyExc_AttributeError, "'%U' is specified in _anonymous_ but not in " "_fields_", @@ -340,6 +341,29 @@ MakeAnonFields(PyObject *type) return 0; } +/* + Allocate a memory block for a pep3118 format string, copy prefix (if + non-null) into it and append `{padding}x` to the end. + Returns NULL on failure, with the error indicator set. +*/ +char * +_ctypes_alloc_format_padding(const char *prefix, Py_ssize_t padding) +{ + /* int64 decimal characters + x + null */ + char buf[19 + 1 + 1]; + + assert(padding > 0); + + if (padding == 1) { + /* Use x instead of 1x, for brevity */ + return _ctypes_alloc_format_string(prefix, "x"); + } + + int ret = PyOS_snprintf(buf, sizeof(buf), "%zdx", padding); (void)ret; + assert(0 <= ret && ret < (Py_ssize_t)sizeof(buf)); + return _ctypes_alloc_format_string(prefix, buf); +} + /* Retrieve the (optional) _pack_ attribute from a type, the _fields_ attribute, and create an StgDictObject. Used for Structure and Union subclasses. @@ -347,33 +371,21 @@ MakeAnonFields(PyObject *type) int PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct) { - _Py_IDENTIFIER(_swappedbytes_); - _Py_IDENTIFIER(_use_broken_old_ctypes_structure_semantics_); - _Py_IDENTIFIER(_pack_); StgDictObject *stgdict, *basedict; Py_ssize_t len, offset, size, align, i; - Py_ssize_t union_size, total_align; + Py_ssize_t union_size, total_align, aligned_size; Py_ssize_t field_size = 0; int bitofs; PyObject *tmp; - int isPacked; int pack; Py_ssize_t ffi_ofs; int big_endian; int arrays_seen = 0; - /* HACK Alert: I cannot be bothered to fix ctypes.com, so there has to - be a way to use the old, broken semantics: _fields_ are not extended - but replaced in subclasses. - - XXX Remove this in ctypes 1.0! - */ - int use_broken_old_ctypes_semantics; - if (fields == NULL) return 0; - if (_PyObject_LookupAttrId(type, &PyId__swappedbytes_, &tmp) < 0) { + if (_PyObject_LookupAttr(type, &_Py_ID(_swappedbytes_), &tmp) < 0) { return -1; } if (tmp) { @@ -384,24 +396,10 @@ PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct big_endian = PY_BIG_ENDIAN; } - if (_PyObject_LookupAttrId(type, - &PyId__use_broken_old_ctypes_structure_semantics_, &tmp) < 0) - { + if (_PyObject_LookupAttr(type, &_Py_ID(_pack_), &tmp) < 0) { return -1; } if (tmp) { - Py_DECREF(tmp); - use_broken_old_ctypes_semantics = 1; - } - else { - use_broken_old_ctypes_semantics = 0; - } - - if (_PyObject_LookupAttrId(type, &PyId__pack_, &tmp) < 0) { - return -1; - } - if (tmp) { - isPacked = 1; pack = _PyLong_AsInt(tmp); Py_DECREF(tmp); if (pack < 0) { @@ -416,7 +414,7 @@ PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct } } else { - isPacked = 0; + /* Setting `_pack_ = 0` amounts to using the default alignment */ pack = 0; } @@ -460,7 +458,7 @@ PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct if (!isStruct) { stgdict->flags |= TYPEFLAG_HASUNION; } - if (basedict && !use_broken_old_ctypes_semantics) { + if (basedict) { size = offset = basedict->size; align = basedict->align; union_size = 0; @@ -497,12 +495,10 @@ PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct } assert(stgdict->format == NULL); - if (isStruct && !isPacked) { + if (isStruct) { stgdict->format = _ctypes_alloc_format_string(NULL, "T{"); } else { - /* PEP3118 doesn't support union, or packed structures (well, - only standard packing, but we don't support the pep for - that). Use 'B' for bytes. */ + /* PEP3118 doesn't support union. Use 'B' for bytes. */ stgdict->format = _ctypes_alloc_format_string(NULL, "B"); } if (stgdict->format == NULL) @@ -570,12 +566,14 @@ PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct } else bitsize = 0; - if (isStruct && !isPacked) { + if (isStruct) { const char *fieldfmt = dict->format ? dict->format : "B"; const char *fieldname = PyUnicode_AsUTF8(name); char *ptr; Py_ssize_t len; char *buf; + Py_ssize_t last_size = size; + Py_ssize_t padding; if (fieldname == NULL) { @@ -583,11 +581,38 @@ PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct return -1; } + /* construct the field now, as `prop->offset` is `offset` with + corrected alignment */ + prop = PyCField_FromDesc(desc, i, + &field_size, bitsize, &bitofs, + &size, &offset, &align, + pack, big_endian); + if (prop == NULL) { + Py_DECREF(pair); + return -1; + } + + /* number of bytes between the end of the last field and the start + of this one */ + padding = ((CFieldObject *)prop)->offset - last_size; + + if (padding > 0) { + ptr = stgdict->format; + stgdict->format = _ctypes_alloc_format_padding(ptr, padding); + PyMem_Free(ptr); + if (stgdict->format == NULL) { + Py_DECREF(pair); + Py_DECREF(prop); + return -1; + } + } + len = strlen(fieldname) + strlen(fieldfmt); buf = PyMem_Malloc(len + 2 + 1); if (buf == NULL) { Py_DECREF(pair); + Py_DECREF(prop); PyErr_NoMemory(); return -1; } @@ -605,15 +630,9 @@ PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct if (stgdict->format == NULL) { Py_DECREF(pair); + Py_DECREF(prop); return -1; } - } - - if (isStruct) { - prop = PyCField_FromDesc(desc, i, - &field_size, bitsize, &bitofs, - &size, &offset, &align, - pack, big_endian); } else /* union */ { size = 0; offset = 0; @@ -622,14 +641,14 @@ PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct &field_size, bitsize, &bitofs, &size, &offset, &align, pack, big_endian); + if (prop == NULL) { + Py_DECREF(pair); + return -1; + } union_size = max(size, union_size); } total_align = max(align, total_align); - if (!prop) { - Py_DECREF(pair); - return -1; - } if (-1 == PyObject_SetAttr(type, name, prop)) { Py_DECREF(prop); Py_DECREF(pair); @@ -639,26 +658,41 @@ PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct Py_DECREF(prop); } - if (isStruct && !isPacked) { - char *ptr = stgdict->format; + if (!isStruct) { + size = union_size; + } + + /* Adjust the size according to the alignment requirements */ + aligned_size = ((size + total_align - 1) / total_align) * total_align; + + if (isStruct) { + char *ptr; + Py_ssize_t padding; + + /* Pad up to the full size of the struct */ + padding = aligned_size - size; + if (padding > 0) { + ptr = stgdict->format; + stgdict->format = _ctypes_alloc_format_padding(ptr, padding); + PyMem_Free(ptr); + if (stgdict->format == NULL) { + return -1; + } + } + + ptr = stgdict->format; stgdict->format = _ctypes_alloc_format_string(stgdict->format, "}"); PyMem_Free(ptr); if (stgdict->format == NULL) return -1; } - if (!isStruct) - size = union_size; - - /* Adjust the size according to the alignment requirements */ - size = ((size + total_align - 1) / total_align) * total_align; - stgdict->ffi_type_pointer.alignment = Py_SAFE_DOWNCAST(total_align, Py_ssize_t, unsigned short); - stgdict->ffi_type_pointer.size = size; + stgdict->ffi_type_pointer.size = aligned_size; - stgdict->size = size; + stgdict->size = aligned_size; stgdict->align = total_align; stgdict->length = len; /* ADD ffi_ofs? */ diff --git a/Modules/_curses_panel.c b/Modules/_curses_panel.c index 0b328f96..292b57c0 100644 --- a/Modules/_curses_panel.c +++ b/Modules/_curses_panel.c @@ -261,8 +261,7 @@ PyCursesPanel_New(_curses_panel_state *state, PANEL *pan, Py_DECREF(po); return NULL; } - po->wo = wo; - Py_INCREF(wo); + po->wo = (PyCursesWindowObject*)Py_NewRef(wo); return (PyObject *)po; } @@ -313,8 +312,7 @@ _curses_panel_panel_above_impl(PyCursesPanelObject *self) "panel_above: can't find Panel Object"); return NULL; } - Py_INCREF(po); - return (PyObject *)po; + return Py_NewRef(po); } /* panel_below(NULL) returns the top panel in the stack. To get @@ -344,8 +342,7 @@ _curses_panel_panel_below_impl(PyCursesPanelObject *self) "panel_below: can't find Panel Object"); return NULL; } - Py_INCREF(po); - return (PyObject *)po; + return Py_NewRef(po); } /*[clinic input] @@ -394,8 +391,7 @@ static PyObject * _curses_panel_panel_window_impl(PyCursesPanelObject *self) /*[clinic end generated code: output=5f05940d4106b4cb input=6067353d2c307901]*/ { - Py_INCREF(self->wo); - return (PyObject *)self->wo; + return Py_NewRef(self->wo); } /*[clinic input] @@ -428,8 +424,7 @@ _curses_panel_panel_replace_impl(PyCursesPanelObject *self, PyErr_SetString(state->PyCursesError, "replace_panel() returned ERR"); return NULL; } - Py_INCREF(win); - Py_SETREF(po->wo, win); + Py_SETREF(po->wo, (PyCursesWindowObject*)Py_NewRef(win)); Py_RETURN_NONE; } @@ -486,8 +481,7 @@ _curses_panel_panel_userptr_impl(PyCursesPanelObject *self, return NULL; } - Py_INCREF(obj); - return obj; + return Py_NewRef(obj); } @@ -555,8 +549,7 @@ _curses_panel_bottom_panel_impl(PyObject *module) "panel_above: can't find Panel Object"); return NULL; } - Py_INCREF(po); - return (PyObject *)po; + return Py_NewRef(po); } /*[clinic input] @@ -614,8 +607,7 @@ _curses_panel_top_panel_impl(PyObject *module) "panel_below: can't find Panel Object"); return NULL; } - Py_INCREF(po); - return (PyObject *)po; + return Py_NewRef(po); } /*[clinic input] @@ -670,9 +662,7 @@ _curses_panel_exec(PyObject *mod) state->PyCursesError = PyErr_NewException( "_curses_panel.error", NULL, NULL); - Py_INCREF(state->PyCursesError); - if (PyModule_AddObject(mod, "error", state->PyCursesError) < 0) { - Py_DECREF(state->PyCursesError); + if (PyModule_AddObjectRef(mod, "error", state->PyCursesError) < 0) { return -1; } @@ -699,6 +689,9 @@ _curses_panel_exec(PyObject *mod) static PyModuleDef_Slot _curses_slots[] = { {Py_mod_exec, _curses_panel_exec}, + // XXX gh-103092: fix isolation. + {Py_mod_multiple_interpreters, Py_MOD_MULTIPLE_INTERPRETERS_NOT_SUPPORTED}, + //{Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; diff --git a/Modules/_cursesmodule.c b/Modules/_cursesmodule.c index c10b2b30..743b9e37 100644 --- a/Modules/_cursesmodule.c +++ b/Modules/_cursesmodule.c @@ -103,7 +103,6 @@ static const char PyCursesVersion[] = "2.2"; #ifndef Py_BUILD_CORE_BUILTIN # define Py_BUILD_CORE_MODULE 1 #endif -#define NEEDS_PY_IDENTIFIER #define PY_SSIZE_T_CLEAN @@ -390,8 +389,7 @@ PyCurses_ConvertToString(PyCursesWindowObject *win, PyObject *obj, #endif } else if (PyBytes_Check(obj)) { - Py_INCREF(obj); - *bytes = obj; + *bytes = Py_NewRef(obj); /* check for embedded null bytes */ if (PyBytes_AsStringAndSize(*bytes, &str, NULL) < 0) { Py_DECREF(obj); @@ -2177,12 +2175,11 @@ _curses_window_putwin(PyCursesWindowObject *self, PyObject *file) while (1) { char buf[BUFSIZ]; Py_ssize_t n = fread(buf, 1, BUFSIZ, fp); - _Py_IDENTIFIER(write); if (n <= 0) break; Py_DECREF(res); - res = _PyObject_CallMethodId(file, &PyId_write, "y#", buf, n); + res = PyObject_CallMethod(file, "write", "y#", buf, n); if (res == NULL) break; } @@ -2374,7 +2371,7 @@ _curses.window.touchline start: int count: int [ - changed: bool(accept={int}) = True + changed: bool = True ] / @@ -2387,7 +2384,7 @@ as having been changed (changed=True) or unchanged (changed=False). static PyObject * _curses_window_touchline_impl(PyCursesWindowObject *self, int start, int count, int group_right_1, int changed) -/*[clinic end generated code: output=65d05b3f7438c61d input=918ad1cbdadf93ea]*/ +/*[clinic end generated code: output=65d05b3f7438c61d input=a98aa4f79b6be845]*/ { if (!group_right_1) { return PyCursesCheckERR(touchline(self->win, start, count), "touchline"); @@ -2709,7 +2706,7 @@ NoArgTrueFalseFunctionBody(can_change_color) /*[clinic input] _curses.cbreak - flag: bool(accept={int}) = True + flag: bool = True If false, the effect is the same as calling nocbreak(). / @@ -2724,7 +2721,7 @@ Calling first raw() then cbreak() leaves the terminal in cbreak mode. static PyObject * _curses_cbreak_impl(PyObject *module, int flag) -/*[clinic end generated code: output=9f9dee9664769751 input=150be619eb1f1458]*/ +/*[clinic end generated code: output=9f9dee9664769751 input=c7d0bddda93016c1]*/ NoArgOrFlagNoReturnFunctionBody(cbreak, flag) /*[clinic input] @@ -2873,7 +2870,7 @@ NoArgNoReturnFunctionBody(doupdate) /*[clinic input] _curses.echo - flag: bool(accept={int}) = True + flag: bool = True If false, the effect is the same as calling noecho(). / @@ -2884,7 +2881,7 @@ In echo mode, each character input is echoed to the screen as it is entered. static PyObject * _curses_echo_impl(PyObject *module, int flag) -/*[clinic end generated code: output=03acb2ddfa6c8729 input=2e9e891d637eac5d]*/ +/*[clinic end generated code: output=03acb2ddfa6c8729 input=86cd4d5bb1d569c0]*/ NoArgOrFlagNoReturnFunctionBody(echo, flag) /*[clinic input] @@ -3051,7 +3048,6 @@ _curses_getwin(PyObject *module, PyObject *file) PyObject *data; size_t datalen; WINDOW *win; - _Py_IDENTIFIER(read); PyObject *res = NULL; PyCursesInitialised; @@ -3063,7 +3059,7 @@ _curses_getwin(PyObject *module, PyObject *file) if (_Py_set_inheritable(fileno(fp), 0, NULL) < 0) goto error; - data = _PyObject_CallMethodIdNoArgs(file, &PyId_read); + data = PyObject_CallMethod(file, "read", NULL); if (data == NULL) goto error; if (!PyBytes_Check(data)) { @@ -3075,8 +3071,8 @@ _curses_getwin(PyObject *module, PyObject *file) } datalen = PyBytes_GET_SIZE(data); if (fwrite(PyBytes_AS_STRING(data), 1, datalen, fp) != datalen) { - Py_DECREF(data); PyErr_SetFromErrno(PyExc_OSError); + Py_DECREF(data); goto error; } Py_DECREF(data); @@ -3500,14 +3496,14 @@ _curses_set_tabsize_impl(PyObject *module, int size) /*[clinic input] _curses.intrflush - flag: bool(accept={int}) + flag: bool / [clinic start generated code]*/ static PyObject * _curses_intrflush_impl(PyObject *module, int flag) -/*[clinic end generated code: output=c1986df35e999a0f input=fcba57bb28dfd795]*/ +/*[clinic end generated code: output=c1986df35e999a0f input=c65fe2ef973fe40a]*/ { PyCursesInitialised; @@ -3609,7 +3605,7 @@ NoArgReturnStringFunctionBody(longname) /*[clinic input] _curses.meta - yes: bool(accept={int}) + yes: bool / Enable/disable meta keys. @@ -3620,7 +3616,7 @@ allow only 7-bit characters. static PyObject * _curses_meta_impl(PyObject *module, int yes) -/*[clinic end generated code: output=22f5abda46a605d8 input=af9892e3a74f35db]*/ +/*[clinic end generated code: output=22f5abda46a605d8 input=cfe7da79f51d0e30]*/ { PyCursesInitialised; @@ -3770,7 +3766,7 @@ _curses_newwin_impl(PyObject *module, int nlines, int ncols, /*[clinic input] _curses.nl - flag: bool(accept={int}) = True + flag: bool = True If false, the effect is the same as calling nonl(). / @@ -3782,7 +3778,7 @@ newline into return and line-feed on output. Newline mode is initially on. static PyObject * _curses_nl_impl(PyObject *module, int flag) -/*[clinic end generated code: output=b39cc0ffc9015003 input=cf36a63f7b86e28a]*/ +/*[clinic end generated code: output=b39cc0ffc9015003 input=18e3e9c6e8cfcf6f]*/ NoArgOrFlagNoReturnFunctionBody(nl, flag) /*[clinic input] @@ -3929,7 +3925,7 @@ _curses_putp_impl(PyObject *module, const char *string) /*[clinic input] _curses.qiflush - flag: bool(accept={int}) = True + flag: bool = True If false, the effect is the same as calling noqiflush(). / @@ -3941,7 +3937,7 @@ will be flushed when the INTR, QUIT and SUSP characters are read. static PyObject * _curses_qiflush_impl(PyObject *module, int flag) -/*[clinic end generated code: output=9167e862f760ea30 input=e9e4a389946a0dbc]*/ +/*[clinic end generated code: output=9167e862f760ea30 input=6ec8b3e2b717ec40]*/ { PyCursesInitialised; @@ -3962,8 +3958,6 @@ update_lines_cols(void) { PyObject *o; PyObject *m = PyImport_ImportModule("curses"); - _Py_IDENTIFIER(LINES); - _Py_IDENTIFIER(COLS); if (!m) return 0; @@ -3973,13 +3967,12 @@ update_lines_cols(void) Py_DECREF(m); return 0; } - if (_PyObject_SetAttrId(m, &PyId_LINES, o)) { + if (PyObject_SetAttrString(m, "LINES", o)) { Py_DECREF(m); Py_DECREF(o); return 0; } - /* PyId_LINES.object will be initialized here. */ - if (PyDict_SetItem(ModDict, _PyUnicode_FromId(&PyId_LINES), o)) { + if (PyDict_SetItemString(ModDict, "LINES", o)) { Py_DECREF(m); Py_DECREF(o); return 0; @@ -3990,12 +3983,12 @@ update_lines_cols(void) Py_DECREF(m); return 0; } - if (_PyObject_SetAttrId(m, &PyId_COLS, o)) { + if (PyObject_SetAttrString(m, "COLS", o)) { Py_DECREF(m); Py_DECREF(o); return 0; } - if (PyDict_SetItem(ModDict, _PyUnicode_FromId(&PyId_COLS), o)) { + if (PyDict_SetItemString(ModDict, "COLS", o)) { Py_DECREF(m); Py_DECREF(o); return 0; @@ -4025,7 +4018,7 @@ _curses_update_lines_cols_impl(PyObject *module) /*[clinic input] _curses.raw - flag: bool(accept={int}) = True + flag: bool = True If false, the effect is the same as calling noraw(). / @@ -4038,7 +4031,7 @@ curses input functions one by one. static PyObject * _curses_raw_impl(PyObject *module, int flag) -/*[clinic end generated code: output=a750e4b342be015b input=e36d8db27832b848]*/ +/*[clinic end generated code: output=a750e4b342be015b input=4b447701389fb4df]*/ NoArgOrFlagNoReturnFunctionBody(raw, flag) /*[clinic input] @@ -4510,7 +4503,7 @@ _curses_unget_wch(PyObject *module, PyObject *ch) /*[clinic input] _curses.use_env - flag: bool(accept={int}) + flag: bool / Use environment variables LINES and COLUMNS. @@ -4527,7 +4520,7 @@ not set). static PyObject * _curses_use_env_impl(PyObject *module, int flag) -/*[clinic end generated code: output=b2c445e435c0b164 input=1778eb1e9151ea37]*/ +/*[clinic end generated code: output=b2c445e435c0b164 input=06ac30948f2d78e4]*/ { use_env(flag); Py_RETURN_NONE; diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c index 274d7df8..d8183c63 100644 --- a/Modules/_datetimemodule.c +++ b/Modules/_datetimemodule.c @@ -10,7 +10,6 @@ #ifndef Py_BUILD_CORE_BUILTIN # define Py_BUILD_CORE_MODULE 1 #endif -#define NEEDS_PY_IDENTIFIER #include "Python.h" #include "pycore_long.h" // _PyLong_GetOne() @@ -141,10 +140,6 @@ static PyTypeObject PyDateTime_TimeZoneType; static int check_tzinfo_subclass(PyObject *p); -_Py_IDENTIFIER(as_integer_ratio); -_Py_IDENTIFIER(fromutc); -_Py_IDENTIFIER(isoformat); -_Py_IDENTIFIER(strftime); /* --------------------------------------------------------------------------- * Math utilities. @@ -194,8 +189,7 @@ divide_nearest(PyObject *m, PyObject *n) temp = _PyLong_DivmodNear(m, n); if (temp == NULL) return NULL; - result = PyTuple_GET_ITEM(temp, 0); - Py_INCREF(result); + result = Py_NewRef(PyTuple_GET_ITEM(temp, 0)); Py_DECREF(temp); return result; @@ -1010,8 +1004,7 @@ new_datetime_ex2(int year, int month, int day, int hour, int minute, DATE_SET_SECOND(self, second); DATE_SET_MICROSECOND(self, usecond); if (aware) { - Py_INCREF(tzinfo); - self->tzinfo = tzinfo; + self->tzinfo = Py_NewRef(tzinfo); } DATE_SET_FOLD(self, fold); } @@ -1088,8 +1081,7 @@ new_time_ex2(int hour, int minute, int second, int usecond, TIME_SET_SECOND(self, second); TIME_SET_MICROSECOND(self, usecond); if (aware) { - Py_INCREF(tzinfo); - self->tzinfo = tzinfo; + self->tzinfo = Py_NewRef(tzinfo); } TIME_SET_FOLD(self, fold); } @@ -1170,10 +1162,8 @@ create_timezone(PyObject *offset, PyObject *name) if (self == NULL) { return NULL; } - Py_INCREF(offset); - self->offset = offset; - Py_XINCREF(name); - self->name = name; + self->offset = Py_NewRef(offset); + self->name = Py_XNewRef(name); return (PyObject *)self; } @@ -1187,8 +1177,7 @@ new_timezone(PyObject *offset, PyObject *name) assert(name == NULL || PyUnicode_Check(name)); if (name == NULL && delta_bool((PyDateTime_Delta *)offset) == 0) { - Py_INCREF(PyDateTime_TimeZone_UTC); - return PyDateTime_TimeZone_UTC; + return Py_NewRef(PyDateTime_TimeZone_UTC); } if ((GET_TD_DAYS(offset) == -1 && GET_TD_SECONDS(offset) == 0 && @@ -1323,8 +1312,6 @@ static PyObject * call_tzname(PyObject *tzinfo, PyObject *tzinfoarg) { PyObject *result; - _Py_IDENTIFIER(tzname); - assert(tzinfo != NULL); assert(check_tzinfo_subclass(tzinfo) >= 0); assert(tzinfoarg != NULL); @@ -1332,7 +1319,7 @@ call_tzname(PyObject *tzinfo, PyObject *tzinfoarg) if (tzinfo == Py_None) Py_RETURN_NONE; - result = _PyObject_CallMethodIdOneArg(tzinfo, &PyId_tzname, tzinfoarg); + result = PyObject_CallMethodOneArg(tzinfo, &_Py_ID(tzname), tzinfoarg); if (result == NULL || result == Py_None) return result; @@ -1341,8 +1328,7 @@ call_tzname(PyObject *tzinfo, PyObject *tzinfoarg) PyErr_Format(PyExc_TypeError, "tzinfo.tzname() must " "return None or a string, not '%s'", Py_TYPE(result)->tp_name); - Py_DECREF(result); - result = NULL; + Py_SETREF(result, NULL); } return result; @@ -1404,8 +1390,7 @@ tzinfo_from_isoformat_results(int rv, int tzoffset, int tz_useconds) if (rv == 1) { // Create a timezone from offset in seconds (0 returns UTC) if (tzoffset == 0) { - Py_INCREF(PyDateTime_TimeZone_UTC); - return PyDateTime_TimeZone_UTC; + return Py_NewRef(PyDateTime_TimeZone_UTC); } PyObject *delta = new_delta(0, tzoffset, tz_useconds, 1); @@ -1416,8 +1401,7 @@ tzinfo_from_isoformat_results(int rv, int tzoffset, int tz_useconds) Py_DECREF(delta); } else { - tzinfo = Py_None; - Py_INCREF(Py_None); + tzinfo = Py_NewRef(Py_None); } return tzinfo; @@ -1506,13 +1490,33 @@ format_utcoffset(char *buf, size_t buflen, const char *sep, return 0; } +static PyObject * +make_somezreplacement(PyObject *object, char *sep, PyObject *tzinfoarg) +{ + char buf[100]; + PyObject *tzinfo = get_tzinfo_member(object); + + if (tzinfo == Py_None || tzinfo == NULL) { + return PyBytes_FromStringAndSize(NULL, 0); + } + + assert(tzinfoarg != NULL); + if (format_utcoffset(buf, + sizeof(buf), + sep, + tzinfo, + tzinfoarg) < 0) + return NULL; + + return PyBytes_FromStringAndSize(buf, strlen(buf)); +} + static PyObject * make_Zreplacement(PyObject *object, PyObject *tzinfoarg) { PyObject *temp; PyObject *tzinfo = get_tzinfo_member(object); PyObject *Zreplacement = PyUnicode_FromStringAndSize(NULL, 0); - _Py_IDENTIFIER(replace); if (Zreplacement == NULL) return NULL; @@ -1534,7 +1538,7 @@ make_Zreplacement(PyObject *object, PyObject *tzinfoarg) * strftime doesn't treat them as format codes. */ Py_DECREF(Zreplacement); - Zreplacement = _PyObject_CallMethodId(temp, &PyId_replace, "ss", "%", "%%"); + Zreplacement = PyObject_CallMethod(temp, "replace", "ss", "%", "%%"); Py_DECREF(temp); if (Zreplacement == NULL) return NULL; @@ -1566,7 +1570,7 @@ make_freplacement(PyObject *object) /* I sure don't want to reproduce the strftime code from the time module, * so this imports the module and calls it. All the hair is due to - * giving special meanings to the %z, %Z and %f format codes via a + * giving special meanings to the %z, %:z, %Z and %f format codes via a * preprocessing step on the format string. * tzinfoarg is the argument to pass to the object's tzinfo method, if * needed. @@ -1578,6 +1582,7 @@ wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple, PyObject *result = NULL; /* guilty until proved innocent */ PyObject *zreplacement = NULL; /* py string, replacement for %z */ + PyObject *colonzreplacement = NULL; /* py string, replacement for %:z */ PyObject *Zreplacement = NULL; /* py string, replacement for %Z */ PyObject *freplacement = NULL; /* py string, replacement for %f */ @@ -1632,32 +1637,29 @@ wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple, } /* A % has been seen and ch is the character after it. */ else if (ch == 'z') { + /* %z -> +HHMM */ if (zreplacement == NULL) { - /* format utcoffset */ - char buf[100]; - PyObject *tzinfo = get_tzinfo_member(object); - zreplacement = PyBytes_FromStringAndSize("", 0); - if (zreplacement == NULL) goto Done; - if (tzinfo != Py_None && tzinfo != NULL) { - assert(tzinfoarg != NULL); - if (format_utcoffset(buf, - sizeof(buf), - "", - tzinfo, - tzinfoarg) < 0) - goto Done; - Py_DECREF(zreplacement); - zreplacement = - PyBytes_FromStringAndSize(buf, - strlen(buf)); - if (zreplacement == NULL) - goto Done; - } + zreplacement = make_somezreplacement(object, "", tzinfoarg); + if (zreplacement == NULL) + goto Done; } assert(zreplacement != NULL); + assert(PyBytes_Check(zreplacement)); ptoappend = PyBytes_AS_STRING(zreplacement); ntoappend = PyBytes_GET_SIZE(zreplacement); } + else if (ch == ':' && *pin == 'z' && pin++) { + /* %:z -> +HH:MM */ + if (colonzreplacement == NULL) { + colonzreplacement = make_somezreplacement(object, ":", tzinfoarg); + if (colonzreplacement == NULL) + goto Done; + } + assert(colonzreplacement != NULL); + assert(PyBytes_Check(colonzreplacement)); + ptoappend = PyBytes_AS_STRING(colonzreplacement); + ntoappend = PyBytes_GET_SIZE(colonzreplacement); + } else if (ch == 'Z') { /* format tzname */ if (Zreplacement == NULL) { @@ -1686,7 +1688,7 @@ wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple, ntoappend = PyBytes_GET_SIZE(freplacement); } else { - /* percent followed by neither z nor Z */ + /* percent followed by something else */ ptoappend = pin - 2; ntoappend = 2; } @@ -1718,21 +1720,22 @@ wrap_strftime(PyObject *object, PyObject *format, PyObject *timetuple, goto Done; { PyObject *format; - PyObject *time = PyImport_ImportModule("time"); + PyObject *strftime = _PyImport_GetModuleAttrString("time", "strftime"); - if (time == NULL) + if (strftime == NULL) goto Done; format = PyUnicode_FromString(PyBytes_AS_STRING(newfmt)); if (format != NULL) { - result = _PyObject_CallMethodIdObjArgs(time, &PyId_strftime, + result = PyObject_CallFunctionObjArgs(strftime, format, timetuple, NULL); Py_DECREF(format); } - Py_DECREF(time); + Py_DECREF(strftime); } Done: Py_XDECREF(freplacement); Py_XDECREF(zreplacement); + Py_XDECREF(colonzreplacement); Py_XDECREF(Zreplacement); Py_XDECREF(newfmt); return result; @@ -1748,12 +1751,10 @@ static PyObject * time_time(void) { PyObject *result = NULL; - PyObject *time = PyImport_ImportModule("time"); + PyObject *time = _PyImport_GetModuleAttrString("time", "time"); if (time != NULL) { - _Py_IDENTIFIER(time); - - result = _PyObject_CallMethodIdNoArgs(time, &PyId_time); + result = PyObject_CallNoArgs(time); Py_DECREF(time); } return result; @@ -1765,31 +1766,21 @@ time_time(void) static PyObject * build_struct_time(int y, int m, int d, int hh, int mm, int ss, int dstflag) { - PyObject *time; + PyObject *struct_time; PyObject *result; - _Py_IDENTIFIER(struct_time); - PyObject *args; - - time = PyImport_ImportModule("time"); - if (time == NULL) { + struct_time = _PyImport_GetModuleAttrString("time", "struct_time"); + if (struct_time == NULL) { return NULL; } - args = Py_BuildValue("iiiiiiiii", + result = PyObject_CallFunction(struct_time, "((iiiiiiiii))", y, m, d, hh, mm, ss, weekday(y, m, d), days_before_month(y, m) + d, dstflag); - if (args == NULL) { - Py_DECREF(time); - return NULL; - } - - result = _PyObject_CallMethodIdOneArg(time, &PyId_struct_time, args); - Py_DECREF(time); - Py_DECREF(args); + Py_DECREF(struct_time); return result; } @@ -1857,8 +1848,7 @@ delta_to_microseconds(PyDateTime_Delta *self) x2 = PyNumber_Multiply(x1, seconds_per_day); /* days in seconds */ if (x2 == NULL) goto Done; - Py_DECREF(x1); - x1 = NULL; + Py_SETREF(x1, NULL); /* x2 has days in seconds */ x1 = PyLong_FromLong(GET_TD_SECONDS(self)); /* seconds */ @@ -1875,8 +1865,7 @@ delta_to_microseconds(PyDateTime_Delta *self) x1 = PyNumber_Multiply(x3, us_per_second); /* us */ if (x1 == NULL) goto Done; - Py_DECREF(x3); - x3 = NULL; + Py_SETREF(x3, NULL); /* x1 has days+seconds in us */ x2 = PyLong_FromLong(GET_TD_MICROSECONDS(self)); @@ -1943,8 +1932,7 @@ microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type) goto BadDivmod; } - num = PyTuple_GET_ITEM(tuple, 0); /* leftover seconds */ - Py_INCREF(num); + num = Py_NewRef(PyTuple_GET_ITEM(tuple, 0)); /* leftover seconds */ Py_DECREF(tuple); tuple = checked_divmod(num, seconds_per_day); @@ -1962,8 +1950,7 @@ microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type) goto BadDivmod; } - num = PyTuple_GET_ITEM(tuple, 0); /* leftover days */ - Py_INCREF(num); + num = Py_NewRef(PyTuple_GET_ITEM(tuple, 0)); /* leftover days */ d = _PyLong_AsInt(num); if (d == -1 && PyErr_Occurred()) { goto Done; @@ -2011,7 +1998,7 @@ get_float_as_integer_ratio(PyObject *floatobj) PyObject *ratio; assert(floatobj && PyFloat_Check(floatobj)); - ratio = _PyObject_CallMethodIdNoArgs(floatobj, &PyId_as_integer_ratio); + ratio = PyObject_CallMethodNoArgs(floatobj, &_Py_ID(as_integer_ratio)); if (ratio == NULL) { return NULL; } @@ -2048,8 +2035,7 @@ multiply_truedivide_timedelta_float(PyDateTime_Delta *delta, PyObject *floatobj, goto error; } temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, op)); - Py_DECREF(pyus_in); - pyus_in = NULL; + Py_SETREF(pyus_in, NULL); if (temp == NULL) goto error; pyus_out = divide_nearest(temp, PyTuple_GET_ITEM(ratio, !op)); @@ -2974,8 +2960,6 @@ date_today(PyObject *cls, PyObject *dummy) { PyObject *time; PyObject *result; - _Py_IDENTIFIER(fromtimestamp); - time = time_time(); if (time == NULL) return NULL; @@ -2986,7 +2970,7 @@ date_today(PyObject *cls, PyObject *dummy) * time.time() delivers; if someone were gonzo about optimization, * date.today() could get away with plain C time(). */ - result = _PyObject_CallMethodIdOneArg(cls, &PyId_fromtimestamp, time); + result = PyObject_CallMethodOneArg(cls, &_Py_ID(fromtimestamp), time); Py_DECREF(time); return result; } @@ -3237,7 +3221,7 @@ date_isoformat(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored)) static PyObject * date_str(PyDateTime_Date *self) { - return _PyObject_CallMethodIdNoArgs((PyObject *)self, &PyId_isoformat); + return PyObject_CallMethodNoArgs((PyObject *)self, &_Py_ID(isoformat)); } @@ -3256,14 +3240,13 @@ date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw) PyObject *result; PyObject *tuple; PyObject *format; - _Py_IDENTIFIER(timetuple); static char *keywords[] = {"format", NULL}; if (! PyArg_ParseTupleAndKeywords(args, kw, "U:strftime", keywords, &format)) return NULL; - tuple = _PyObject_CallMethodIdNoArgs((PyObject *)self, &PyId_timetuple); + tuple = PyObject_CallMethodNoArgs((PyObject *)self, &_Py_ID(timetuple)); if (tuple == NULL) return NULL; result = wrap_strftime((PyObject *)self, format, tuple, @@ -3284,7 +3267,7 @@ date_format(PyDateTime_Date *self, PyObject *args) if (PyUnicode_GetLength(format) == 0) return PyObject_Str((PyObject *)self); - return _PyObject_CallMethodIdOneArg((PyObject *)self, &PyId_strftime, + return PyObject_CallMethodOneArg((PyObject *)self, &_Py_ID(strftime), format); } @@ -3349,8 +3332,7 @@ iso_calendar_date_year(PyDateTime_IsoCalendarDate *self, void *unused) if (year == NULL) { return NULL; } - Py_INCREF(year); - return year; + return Py_NewRef(year); } static PyObject * @@ -3360,8 +3342,7 @@ iso_calendar_date_week(PyDateTime_IsoCalendarDate *self, void *unused) if (week == NULL) { return NULL; } - Py_INCREF(week); - return week; + return Py_NewRef(week); } static PyObject * @@ -3371,8 +3352,7 @@ iso_calendar_date_weekday(PyDateTime_IsoCalendarDate *self, void *unused) if (weekday == NULL) { return NULL; } - Py_INCREF(weekday); - return weekday; + return Py_NewRef(weekday); } static PyGetSetDef iso_calendar_date_getset[] = { @@ -3813,9 +3793,8 @@ tzinfo_reduce(PyObject *self, PyObject *Py_UNUSED(ignored)) { PyObject *args, *state; PyObject *getinitargs; - _Py_IDENTIFIER(__getinitargs__); - if (_PyObject_LookupAttrId(self, &PyId___getinitargs__, &getinitargs) < 0) { + if (_PyObject_LookupAttr(self, &_Py_ID(__getinitargs__), &getinitargs) < 0) { return NULL; } if (getinitargs != NULL) { @@ -3984,8 +3963,7 @@ timezone_str(PyDateTime_TimeZone *self) char sign; if (self->name != NULL) { - Py_INCREF(self->name); - return self->name; + return Py_NewRef(self->name); } if ((PyObject *)self == PyDateTime_TimeZone_UTC || (GET_TD_DAYS(self->offset) == 0 && @@ -4001,8 +3979,7 @@ timezone_str(PyDateTime_TimeZone *self) } else { sign = '+'; - offset = self->offset; - Py_INCREF(offset); + offset = Py_NewRef(self->offset); } /* Offset is not negative here. */ microseconds = GET_TD_MICROSECONDS(offset); @@ -4037,8 +4014,7 @@ timezone_utcoffset(PyDateTime_TimeZone *self, PyObject *dt) if (_timezone_check_argument(dt, "utcoffset") == -1) return NULL; - Py_INCREF(self->offset); - return self->offset; + return Py_NewRef(self->offset); } static PyObject * @@ -4175,8 +4151,7 @@ static PyObject * time_tzinfo(PyDateTime_Time *self, void *unused) { PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None; - Py_INCREF(result); - return result; + return Py_NewRef(result); } static PyObject * @@ -4221,8 +4196,7 @@ time_from_pickle(PyTypeObject *type, PyObject *state, PyObject *tzinfo) me->hashcode = -1; me->hastzinfo = aware; if (aware) { - Py_INCREF(tzinfo); - me->tzinfo = tzinfo; + me->tzinfo = Py_NewRef(tzinfo); } if (pdata[0] & (1 << 7)) { me->data[0] -= 128; @@ -4360,7 +4334,7 @@ time_repr(PyDateTime_Time *self) static PyObject * time_str(PyDateTime_Time *self) { - return _PyObject_CallMethodIdNoArgs((PyObject *)self, &PyId_isoformat); + return PyObject_CallMethodNoArgs((PyObject *)self, &_Py_ID(isoformat)); } static PyObject * @@ -4518,12 +4492,10 @@ time_richcompare(PyObject *self, PyObject *other, int op) result = diff_to_bool(diff, op); } else if (op == Py_EQ) { - result = Py_False; - Py_INCREF(result); + result = Py_NewRef(Py_False); } else if (op == Py_NE) { - result = Py_True; - Py_INCREF(result); + result = Py_NewRef(Py_True); } else { PyErr_SetString(PyExc_TypeError, @@ -4552,8 +4524,7 @@ time_hash(PyDateTime_Time *self) return -1; } else { - self0 = (PyObject *)self; - Py_INCREF(self0); + self0 = Py_NewRef(self); } offset = time_utcoffset(self0, NULL); Py_DECREF(self0); @@ -4850,8 +4821,7 @@ static PyObject * datetime_tzinfo(PyDateTime_DateTime *self, void *unused) { PyObject *result = HASTZINFO(self) ? self->tzinfo : Py_None; - Py_INCREF(result); - return result; + return Py_NewRef(result); } static PyObject * @@ -4898,8 +4868,7 @@ datetime_from_pickle(PyTypeObject *type, PyObject *state, PyObject *tzinfo) me->hashcode = -1; me->hastzinfo = aware; if (aware) { - Py_INCREF(tzinfo); - me->tzinfo = tzinfo; + me->tzinfo = Py_NewRef(tzinfo); } if (pdata[2] & (1 << 7)) { me->data[2] -= 128; @@ -5162,7 +5131,9 @@ datetime_datetime_now_impl(PyTypeObject *type, PyObject *tz) tz); if (self != NULL && tz != Py_None) { /* Convert UTC to tzinfo's zone. */ - self = _PyObject_CallMethodId(tz, &PyId_fromutc, "N", self); + PyObject *res = PyObject_CallMethodOneArg(tz, &_Py_ID(fromutc), self); + Py_DECREF(self); + return res; } return self; } @@ -5173,6 +5144,13 @@ datetime_datetime_now_impl(PyTypeObject *type, PyObject *tz) static PyObject * datetime_utcnow(PyObject *cls, PyObject *dummy) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "datetime.datetime.utcnow() is deprecated and scheduled for removal in a " + "future version. Use timezone-aware objects to represent datetimes " + "in UTC: datetime.datetime.now(datetime.UTC).", 1)) + { + return NULL; + } return datetime_best_possible(cls, _PyTime_gmtime, Py_None); } @@ -5198,7 +5176,9 @@ datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw) tzinfo); if (self != NULL && tzinfo != Py_None) { /* Convert UTC to tzinfo's zone. */ - self = _PyObject_CallMethodId(tzinfo, &PyId_fromutc, "N", self); + PyObject *res = PyObject_CallMethodOneArg(tzinfo, &_Py_ID(fromutc), self); + Py_DECREF(self); + return res; } return self; } @@ -5207,6 +5187,13 @@ datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw) static PyObject * datetime_utcfromtimestamp(PyObject *cls, PyObject *args) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "datetime.datetime.utcfromtimestamp() is deprecated and scheduled for removal " + "in a future version. Use timezone-aware objects to represent " + "datetimes in UTC: datetime.datetime.fromtimestamp(timestamp, datetime.UTC).", 1)) + { + return NULL; + } PyObject *timestamp; PyObject *result = NULL; @@ -5222,7 +5209,6 @@ datetime_strptime(PyObject *cls, PyObject *args) { static PyObject *module = NULL; PyObject *string, *format; - _Py_IDENTIFIER(_strptime_datetime); if (!PyArg_ParseTuple(args, "UU:strptime", &string, &format)) return NULL; @@ -5232,7 +5218,7 @@ datetime_strptime(PyObject *cls, PyObject *args) if (module == NULL) return NULL; } - return _PyObject_CallMethodIdObjArgs(module, &PyId__strptime_datetime, + return PyObject_CallMethodObjArgs(module, &_Py_ID(_strptime_datetime), cls, string, format, NULL); } @@ -5284,7 +5270,7 @@ _sanitize_isoformat_str(PyObject *dtstr) // // The result of this, if not NULL, returns a new reference const void* const unicode_data = PyUnicode_DATA(dtstr); - const unsigned int kind = PyUnicode_KIND(dtstr); + const int kind = PyUnicode_KIND(dtstr); // Depending on the format of the string, the separator can only ever be // in positions 7, 8 or 10. We'll check each of these for a surrogate and @@ -5308,8 +5294,7 @@ _sanitize_isoformat_str(PyObject *dtstr) } if (surrogate_separator == 0) { - Py_INCREF(dtstr); - return dtstr; + return Py_NewRef(dtstr); } PyObject *str_out = _PyUnicode_Copy(dtstr); @@ -5623,9 +5608,8 @@ datetime_subtract(PyObject *left, PyObject *right) int delta_d, delta_s, delta_us; if (GET_DT_TZINFO(left) == GET_DT_TZINFO(right)) { - offset2 = offset1 = Py_None; - Py_INCREF(offset1); - Py_INCREF(offset2); + offset1 = Py_NewRef(Py_None); + offset2 = Py_NewRef(Py_None); } else { offset1 = datetime_utcoffset(left, NULL); @@ -5739,7 +5723,14 @@ datetime_repr(PyDateTime_DateTime *self) static PyObject * datetime_str(PyDateTime_DateTime *self) { - return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, "s", " "); + PyObject *space = PyUnicode_FromString(" "); + if (space == NULL) { + return NULL; + } + PyObject *res = PyObject_CallMethodOneArg((PyObject *)self, + &_Py_ID(isoformat), space); + Py_DECREF(space); + return res; } static PyObject * @@ -5963,12 +5954,10 @@ datetime_richcompare(PyObject *self, PyObject *other, int op) result = diff_to_bool(diff, op); } else if (op == Py_EQ) { - result = Py_False; - Py_INCREF(result); + result = Py_NewRef(Py_False); } else if (op == Py_NE) { - result = Py_True; - Py_INCREF(result); + result = Py_NewRef(Py_True); } else { PyErr_SetString(PyExc_TypeError, @@ -6000,8 +5989,7 @@ datetime_hash(PyDateTime_DateTime *self) return -1; } else { - self0 = (PyObject *)self; - Py_INCREF(self0); + self0 = Py_NewRef(self); } offset = datetime_utcoffset(self0, NULL); Py_DECREF(self0); @@ -6179,17 +6167,31 @@ local_to_seconds(int year, int month, int day, static PyObject * local_timezone_from_local(PyDateTime_DateTime *local_dt) { - long long seconds; + long long seconds, seconds2; time_t timestamp; + int fold = DATE_GET_FOLD(local_dt); seconds = local_to_seconds(GET_YEAR(local_dt), GET_MONTH(local_dt), GET_DAY(local_dt), DATE_GET_HOUR(local_dt), DATE_GET_MINUTE(local_dt), DATE_GET_SECOND(local_dt), - DATE_GET_FOLD(local_dt)); + fold); if (seconds == -1) return NULL; + seconds2 = local_to_seconds(GET_YEAR(local_dt), + GET_MONTH(local_dt), + GET_DAY(local_dt), + DATE_GET_HOUR(local_dt), + DATE_GET_MINUTE(local_dt), + DATE_GET_SECOND(local_dt), + !fold); + if (seconds2 == -1) + return NULL; + /* Detect gap */ + if (seconds2 != seconds && (seconds2 > seconds) == fold) + seconds = seconds2; + /* XXX: add bounds check */ timestamp = seconds - epoch; return local_timezone_from_timestamp(timestamp); @@ -6218,15 +6220,13 @@ datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw) if (self_tzinfo == NULL) return NULL; } else { - self_tzinfo = self->tzinfo; - Py_INCREF(self_tzinfo); + self_tzinfo = Py_NewRef(self->tzinfo); } /* Conversion to self's own time zone is a NOP. */ if (self_tzinfo == tzinfo) { Py_DECREF(self_tzinfo); - Py_INCREF(self); - return self; + return (PyDateTime_DateTime*)Py_NewRef(self); } /* Convert self to UTC. */ @@ -6271,14 +6271,10 @@ datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw) } else { /* Result is already aware - just replace tzinfo. */ - temp = result->tzinfo; - result->tzinfo = PyDateTime_TimeZone_UTC; - Py_INCREF(result->tzinfo); - Py_DECREF(temp); + Py_SETREF(result->tzinfo, Py_NewRef(PyDateTime_TimeZone_UTC)); } /* Attach new tzinfo and let fromutc() do the rest. */ - temp = result->tzinfo; if (tzinfo == Py_None) { tzinfo = local_timezone(result); if (tzinfo == NULL) { @@ -6288,12 +6284,11 @@ datetime_astimezone(PyDateTime_DateTime *self, PyObject *args, PyObject *kw) } else Py_INCREF(tzinfo); - result->tzinfo = tzinfo; - Py_DECREF(temp); + Py_SETREF(result->tzinfo, tzinfo); temp = (PyObject *)result; result = (PyDateTime_DateTime *) - _PyObject_CallMethodIdOneArg(tzinfo, &PyId_fromutc, temp); + PyObject_CallMethodOneArg(tzinfo, &_Py_ID(fromutc), temp); Py_DECREF(temp); return result; @@ -6443,8 +6438,7 @@ datetime_utctimetuple(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored)) tzinfo = GET_DT_TZINFO(self); if (tzinfo == Py_None) { - utcself = self; - Py_INCREF(utcself); + utcself = (PyDateTime_DateTime*)Py_NewRef(self); } else { PyObject *offset; @@ -6453,8 +6447,7 @@ datetime_utctimetuple(PyDateTime_DateTime *self, PyObject *Py_UNUSED(ignored)) return NULL; if (offset == Py_None) { Py_DECREF(offset); - utcself = self; - Py_INCREF(utcself); + utcself = (PyDateTime_DateTime*)Py_NewRef(self); } else { utcself = (PyDateTime_DateTime *)add_datetime_timedelta(self, @@ -6878,24 +6871,49 @@ _datetime_exec(PyObject *module) assert(DI100Y == days_before_year(100+1)); us_per_ms = PyLong_FromLong(1000); + if (us_per_ms == NULL) { + goto error; + } us_per_second = PyLong_FromLong(1000000); + if (us_per_second == NULL) { + goto error; + } us_per_minute = PyLong_FromLong(60000000); + if (us_per_minute == NULL) { + goto error; + } seconds_per_day = PyLong_FromLong(24 * 3600); - if (us_per_ms == NULL || us_per_second == NULL || - us_per_minute == NULL || seconds_per_day == NULL) { - return -1; + if (seconds_per_day == NULL) { + goto error; } /* The rest are too big for 32-bit ints, but even * us_per_week fits in 40 bits, so doubles should be exact. */ us_per_hour = PyLong_FromDouble(3600000000.0); + if (us_per_hour == NULL) { + goto error; + } us_per_day = PyLong_FromDouble(86400000000.0); + if (us_per_day == NULL) { + goto error; + } us_per_week = PyLong_FromDouble(604800000000.0); - if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL) { - return -1; + if (us_per_week == NULL) { + goto error; } + return 0; + +error: + Py_XDECREF(us_per_ms); + Py_XDECREF(us_per_second); + Py_XDECREF(us_per_minute); + Py_XDECREF(us_per_hour); + Py_XDECREF(us_per_day); + Py_XDECREF(us_per_week); + Py_XDECREF(seconds_per_day); + return -1; } static struct PyModuleDef datetimemodule = { diff --git a/Modules/_dbmmodule.c b/Modules/_dbmmodule.c index 5913b034..9908174c 100644 --- a/Modules/_dbmmodule.c +++ b/Modules/_dbmmodule.c @@ -130,6 +130,37 @@ dbm_length(dbmobject *dp) return dp->di_size; } +static int +dbm_bool(dbmobject *dp) +{ + _dbm_state *state = PyType_GetModuleState(Py_TYPE(dp)); + assert(state != NULL); + + if (dp->di_dbm == NULL) { + PyErr_SetString(state->dbm_error, "DBM object has already been closed"); + return -1; + } + + if (dp->di_size > 0) { + /* Known non-zero size. */ + return 1; + } + if (dp->di_size == 0) { + /* Known zero size. */ + return 0; + } + + /* Unknown size. Ensure DBM object has an entry. */ + datum key = dbm_firstkey(dp->di_dbm); + if (key.dptr == NULL) { + /* Empty. Cache this fact. */ + dp->di_size = 0; + return 0; + } + /* Non-empty. Don't cache the length since we don't know. */ + return 1; +} + static PyObject * dbm_subscript(dbmobject *dp, PyObject *key) { @@ -327,8 +358,7 @@ _dbm_dbm_get_impl(dbmobject *self, PyTypeObject *cls, const char *key, return PyBytes_FromStringAndSize(val.dptr, val.dsize); } - Py_INCREF(default_value); - return default_value; + return Py_NewRef(default_value); } /*[clinic input] @@ -388,8 +418,7 @@ _dbm_dbm_setdefault_impl(dbmobject *self, PyTypeObject *cls, const char *key, static PyObject * dbm__enter__(PyObject *self, PyObject *args) { - Py_INCREF(self); - return self; + return Py_NewRef(self); } static PyObject * @@ -416,6 +445,7 @@ static PyType_Slot dbmtype_spec_slots[] = { {Py_mp_length, dbm_length}, {Py_mp_subscript, dbm_subscript}, {Py_mp_ass_subscript, dbm_ass_sub}, + {Py_nb_bool, dbm_bool}, {0, 0} }; @@ -553,6 +583,7 @@ _dbm_module_free(void *module) static PyModuleDef_Slot _dbmmodule_slots[] = { {Py_mod_exec, _dbm_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; diff --git a/Modules/_decimal/_decimal.c b/Modules/_decimal/_decimal.c index 65885965..70b13982 100644 --- a/Modules/_decimal/_decimal.c +++ b/Modules/_decimal/_decimal.c @@ -30,6 +30,7 @@ #endif #include <Python.h> +#include "pycore_long.h" // _PyLong_IsZero() #include "pycore_pystate.h" // _PyThreadState_GET() #include "complexobject.h" #include "mpdecimal.h" @@ -116,15 +117,13 @@ static PyTypeObject PyDecContextManager_Type; Py_LOCAL_INLINE(PyObject *) incr_true(void) { - Py_INCREF(Py_True); - return Py_True; + return Py_NewRef(Py_True); } Py_LOCAL_INLINE(PyObject *) incr_false(void) { - Py_INCREF(Py_False); - return Py_False; + return Py_NewRef(Py_False); } @@ -247,14 +246,12 @@ value_error_int(const char *mesg) return -1; } -#ifdef CONFIG_32 static PyObject * value_error_ptr(const char *mesg) { PyErr_SetString(PyExc_ValueError, mesg); return NULL; } -#endif static int type_error_int(const char *mesg) @@ -541,6 +538,8 @@ getround(PyObject *v) initialized to new SignalDicts. Once a SignalDict is tied to a context, it cannot be deleted. */ +static const char *INVALID_SIGNALDICT_ERROR_MSG = "invalid signal dict"; + static int signaldict_init(PyObject *self, PyObject *args UNUSED, PyObject *kwds UNUSED) { @@ -549,8 +548,11 @@ signaldict_init(PyObject *self, PyObject *args UNUSED, PyObject *kwds UNUSED) } static Py_ssize_t -signaldict_len(PyObject *self UNUSED) +signaldict_len(PyObject *self) { + if (SdFlagAddr(self) == NULL) { + return value_error_int(INVALID_SIGNALDICT_ERROR_MSG); + } return SIGNAL_MAP_LEN; } @@ -558,6 +560,9 @@ static PyObject *SignalTuple; static PyObject * signaldict_iter(PyObject *self UNUSED) { + if (SdFlagAddr(self) == NULL) { + return value_error_ptr(INVALID_SIGNALDICT_ERROR_MSG); + } return PyTuple_Type.tp_iter(SignalTuple); } @@ -565,6 +570,9 @@ static PyObject * signaldict_getitem(PyObject *self, PyObject *key) { uint32_t flag; + if (SdFlagAddr(self) == NULL) { + return value_error_ptr(INVALID_SIGNALDICT_ERROR_MSG); + } flag = exception_as_flag(key); if (flag & DEC_ERRORS) { @@ -580,6 +588,10 @@ signaldict_setitem(PyObject *self, PyObject *key, PyObject *value) uint32_t flag; int x; + if (SdFlagAddr(self) == NULL) { + return value_error_int(INVALID_SIGNALDICT_ERROR_MSG); + } + if (value == NULL) { return value_error_int("signal keys cannot be deleted"); } @@ -612,6 +624,10 @@ signaldict_repr(PyObject *self) const char *b[SIGNAL_MAP_LEN]; /* bool */ int i; + if (SdFlagAddr(self) == NULL) { + return value_error_ptr(INVALID_SIGNALDICT_ERROR_MSG); + } + assert(SIGNAL_MAP_LEN == 9); for (cm=signal_map, i=0; cm->name != NULL; cm++, i++) { @@ -633,6 +649,9 @@ signaldict_richcompare(PyObject *v, PyObject *w, int op) PyObject *res = Py_NotImplemented; assert(PyDecSignalDict_Check(v)); + if ((SdFlagAddr(v) == NULL) || (SdFlagAddr(w) == NULL)) { + return value_error_ptr(INVALID_SIGNALDICT_ERROR_MSG); + } if (op == Py_EQ || op == Py_NE) { if (PyDecSignalDict_Check(w)) { @@ -655,13 +674,15 @@ signaldict_richcompare(PyObject *v, PyObject *w, int op) } } - Py_INCREF(res); - return res; + return Py_NewRef(res); } static PyObject * signaldict_copy(PyObject *self, PyObject *args UNUSED) { + if (SdFlagAddr(self) == NULL) { + return value_error_ptr(INVALID_SIGNALDICT_ERROR_MSG); + } return flags_as_dict(SdFlags(self)); } @@ -754,8 +775,7 @@ context_getround(PyObject *self, void *closure UNUSED) { int i = mpd_getround(CTX(self)); - Py_INCREF(round_map[i]); - return round_map[i]; + return Py_NewRef(round_map[i]); } static PyObject * @@ -1122,13 +1142,11 @@ context_getattr(PyObject *self, PyObject *name) if (PyUnicode_Check(name)) { if (PyUnicode_CompareWithASCIIString(name, "traps") == 0) { retval = ((PyDecContextObject *)self)->traps; - Py_INCREF(retval); - return retval; + return Py_NewRef(retval); } if (PyUnicode_CompareWithASCIIString(name, "flags") == 0) { retval = ((PyDecContextObject *)self)->flags; - Py_INCREF(retval); - return retval; + return Py_NewRef(retval); } } @@ -1602,8 +1620,7 @@ PyDec_GetCurrentContext(PyObject *self UNUSED, PyObject *args UNUSED) return NULL; } - Py_INCREF(context); - return context; + return Py_NewRef(context); } /* Set the thread local context to a new context, decrement old reference */ @@ -1778,8 +1795,7 @@ ctxmanager_new(PyTypeObject *type UNUSED, PyObject *args, PyObject *kwds) Py_DECREF(self); return NULL; } - self->global = global; - Py_INCREF(self->global); + self->global = Py_NewRef(global); int ret = context_setattrs( self->local, prec, rounding, @@ -1814,8 +1830,7 @@ ctxmanager_set_local(PyDecContextManagerObject *self, PyObject *args UNUSED) } Py_DECREF(ret); - Py_INCREF(self->local); - return self->local; + return Py_NewRef(self->local); } static PyObject * @@ -1918,7 +1933,7 @@ dec_dealloc(PyObject *dec) /******************************************************************************/ Py_LOCAL_INLINE(int) -is_space(enum PyUnicode_Kind kind, const void *data, Py_ssize_t pos) +is_space(int kind, const void *data, Py_ssize_t pos) { Py_UCS4 ch = PyUnicode_READ(kind, data, pos); return Py_UNICODE_ISSPACE(ch); @@ -1933,9 +1948,9 @@ is_space(enum PyUnicode_Kind kind, const void *data, Py_ssize_t pos) Return NULL if malloc fails and an empty string if invalid characters are found. */ static char * -numeric_as_ascii(const PyObject *u, int strip_ws, int ignore_underscores) +numeric_as_ascii(PyObject *u, int strip_ws, int ignore_underscores) { - enum PyUnicode_Kind kind; + int kind; const void *data; Py_UCS4 ch; char *res, *cp; @@ -2047,7 +2062,7 @@ PyDecType_FromCStringExact(PyTypeObject *type, const char *s, /* Return a new PyDecObject or a subtype from a PyUnicodeObject. */ static PyObject * -PyDecType_FromUnicode(PyTypeObject *type, const PyObject *u, +PyDecType_FromUnicode(PyTypeObject *type, PyObject *u, PyObject *context) { PyObject *dec; @@ -2067,7 +2082,7 @@ PyDecType_FromUnicode(PyTypeObject *type, const PyObject *u, * conversion. If the conversion is not exact, fail with InvalidOperation. * Allow leading and trailing whitespace in the input operand. */ static PyObject * -PyDecType_FromUnicodeExactWS(PyTypeObject *type, const PyObject *u, +PyDecType_FromUnicodeExactWS(PyTypeObject *type, PyObject *u, PyObject *context) { PyObject *dec; @@ -2150,46 +2165,36 @@ PyDecType_FromSsizeExact(PyTypeObject *type, mpd_ssize_t v, PyObject *context) /* Convert from a PyLongObject. The context is not modified; flags set during conversion are accumulated in the status parameter. */ static PyObject * -dec_from_long(PyTypeObject *type, const PyObject *v, +dec_from_long(PyTypeObject *type, PyObject *v, const mpd_context_t *ctx, uint32_t *status) { PyObject *dec; PyLongObject *l = (PyLongObject *)v; - Py_ssize_t ob_size; - size_t len; - uint8_t sign; dec = PyDecType_New(type); if (dec == NULL) { return NULL; } - ob_size = Py_SIZE(l); - if (ob_size == 0) { + if (_PyLong_IsZero(l)) { _dec_settriple(dec, MPD_POS, 0, 0); return dec; } - if (ob_size < 0) { - len = -ob_size; - sign = MPD_NEG; - } - else { - len = ob_size; - sign = MPD_POS; - } + uint8_t sign = _PyLong_IsNegative(l) ? MPD_NEG : MPD_POS; - if (len == 1) { - _dec_settriple(dec, sign, *l->ob_digit, 0); + if (_PyLong_IsCompact(l)) { + _dec_settriple(dec, sign, l->long_value.ob_digit[0], 0); mpd_qfinalize(MPD(dec), ctx, status); return dec; } + size_t len = _PyLong_DigitCount(l); #if PYLONG_BITS_IN_DIGIT == 30 - mpd_qimport_u32(MPD(dec), l->ob_digit, len, sign, PyLong_BASE, + mpd_qimport_u32(MPD(dec), l->long_value.ob_digit, len, sign, PyLong_BASE, ctx, status); #elif PYLONG_BITS_IN_DIGIT == 15 - mpd_qimport_u16(MPD(dec), l->ob_digit, len, sign, PyLong_BASE, + mpd_qimport_u16(MPD(dec), l->long_value.ob_digit, len, sign, PyLong_BASE, ctx, status); #else #error "PYLONG_BITS_IN_DIGIT should be 15 or 30" @@ -2201,7 +2206,7 @@ dec_from_long(PyTypeObject *type, const PyObject *v, /* Return a new PyDecObject from a PyLongObject. Use the context for conversion. */ static PyObject * -PyDecType_FromLong(PyTypeObject *type, const PyObject *v, PyObject *context) +PyDecType_FromLong(PyTypeObject *type, PyObject *v, PyObject *context) { PyObject *dec; uint32_t status = 0; @@ -2227,7 +2232,7 @@ PyDecType_FromLong(PyTypeObject *type, const PyObject *v, PyObject *context) /* Return a new PyDecObject from a PyLongObject. Use a maximum context for conversion. If the conversion is not exact, set InvalidOperation. */ static PyObject * -PyDecType_FromLongExact(PyTypeObject *type, const PyObject *v, +PyDecType_FromLongExact(PyTypeObject *type, PyObject *v, PyObject *context) { PyObject *dec; @@ -2418,8 +2423,7 @@ PyDecType_FromDecimalExact(PyTypeObject *type, PyObject *v, PyObject *context) uint32_t status = 0; if (type == &PyDec_Type && PyDec_CheckExact(v)) { - Py_INCREF(v); - return v; + return Py_NewRef(v); } dec = PyDecType_New(type); @@ -2440,8 +2444,7 @@ static PyObject * sequence_as_tuple(PyObject *v, PyObject *ex, const char *mesg) { if (PyTuple_Check(v)) { - Py_INCREF(v); - return v; + return Py_NewRef(v); } if (PyList_Check(v)) { return PyList_AsTuple(v); @@ -2863,8 +2866,7 @@ convert_op(int type_err, PyObject **conv, PyObject *v, PyObject *context) { if (PyDec_Check(v)) { - *conv = v; - Py_INCREF(v); + *conv = Py_NewRef(v); return 1; } if (PyLong_Check(v)) { @@ -2881,8 +2883,7 @@ convert_op(int type_err, PyObject **conv, PyObject *v, PyObject *context) Py_TYPE(v)->tp_name); } else { - Py_INCREF(Py_NotImplemented); - *conv = Py_NotImplemented; + *conv = Py_NewRef(Py_NotImplemented); } return 0; } @@ -3041,8 +3042,7 @@ convert_op_cmp(PyObject **vcmp, PyObject **wcmp, PyObject *v, PyObject *w, *vcmp = v; if (PyDec_Check(w)) { - Py_INCREF(w); - *wcmp = w; + *wcmp = Py_NewRef(w); } else if (PyLong_Check(w)) { *wcmp = PyDec_FromLongExact(w, context); @@ -3074,8 +3074,7 @@ convert_op_cmp(PyObject **vcmp, PyObject **wcmp, PyObject *v, PyObject *w, } } else { - Py_INCREF(Py_NotImplemented); - *wcmp = Py_NotImplemented; + *wcmp = Py_NewRef(Py_NotImplemented); } } else { @@ -3093,8 +3092,7 @@ convert_op_cmp(PyObject **vcmp, PyObject **wcmp, PyObject *v, PyObject *w, } } else { - Py_INCREF(Py_NotImplemented); - *wcmp = Py_NotImplemented; + *wcmp = Py_NewRef(Py_NotImplemented); } } @@ -3498,7 +3496,6 @@ dec_as_long(PyObject *dec, PyObject *context, int round) PyLongObject *pylong; digit *ob_digit; size_t n; - Py_ssize_t i; mpd_t *x; mpd_context_t workctx; uint32_t status = 0; @@ -3552,26 +3549,9 @@ dec_as_long(PyObject *dec, PyObject *context, int round) } assert(n > 0); - pylong = _PyLong_New(n); - if (pylong == NULL) { - mpd_free(ob_digit); - mpd_del(x); - return NULL; - } - - memcpy(pylong->ob_digit, ob_digit, n * sizeof(digit)); + assert(!mpd_iszero(x)); + pylong = _PyLong_FromDigits(mpd_isnegative(x), n, ob_digit); mpd_free(ob_digit); - - i = n; - while ((i > 0) && (pylong->ob_digit[i-1] == 0)) { - i--; - } - - Py_SET_SIZE(pylong, i); - if (mpd_isnegative(x) && !mpd_iszero(x)) { - Py_SET_SIZE(pylong, -i); - } - mpd_del(x); return (PyObject *) pylong; } @@ -3658,9 +3638,13 @@ dec_as_integer_ratio(PyObject *self, PyObject *args UNUSED) goto error; } Py_SETREF(numerator, _py_long_floor_divide(numerator, tmp)); + if (numerator == NULL) { + Py_DECREF(tmp); + goto error; + } Py_SETREF(denominator, _py_long_floor_divide(denominator, tmp)); Py_DECREF(tmp); - if (numerator == NULL || denominator == NULL) { + if (denominator == NULL) { goto error; } } @@ -4329,15 +4313,13 @@ dec_mpd_adjexp(PyObject *self, PyObject *dummy UNUSED) static PyObject * dec_canonical(PyObject *self, PyObject *dummy UNUSED) { - Py_INCREF(self); - return self; + return Py_NewRef(self); } static PyObject * dec_conjugate(PyObject *self, PyObject *dummy UNUSED) { - Py_INCREF(self); - return self; + return Py_NewRef(self); } static PyObject * @@ -4654,8 +4636,7 @@ dec_complex(PyObject *self, PyObject *dummy UNUSED) static PyObject * dec_copy(PyObject *self, PyObject *dummy UNUSED) { - Py_INCREF(self); - return self; + return Py_NewRef(self); } /* __floor__ */ @@ -4815,13 +4796,11 @@ dec_reduce(PyObject *self, PyObject *dummy UNUSED) static PyObject * dec_sizeof(PyObject *v, PyObject *dummy UNUSED) { - Py_ssize_t res; - - res = _PyObject_SIZE(Py_TYPE(v)); + size_t res = _PyObject_SIZE(Py_TYPE(v)); if (mpd_isdynamic_data(MPD(v))) { - res += MPD(v)->alloc * sizeof(mpd_uint_t); + res += (size_t)MPD(v)->alloc * sizeof(mpd_uint_t); } - return PyLong_FromSsize_t(res); + return PyLong_FromSize_t(res); } /* __trunc__ */ @@ -4838,8 +4817,7 @@ dec_trunc(PyObject *self, PyObject *dummy UNUSED) static PyObject * dec_real(PyObject *self, void *closure UNUSED) { - Py_INCREF(self); - return self; + return Py_NewRef(self); } static PyObject * @@ -5384,8 +5362,7 @@ ctx_canonical(PyObject *context UNUSED, PyObject *v) return NULL; } - Py_INCREF(v); - return v; + return Py_NewRef(v); } static PyObject * @@ -5916,23 +5893,16 @@ PyInit__decimal(void) /* Create the module */ ASSIGN_PTR(m, PyModule_Create(&_decimal_module)); - /* Add types to the module */ - Py_INCREF(&PyDec_Type); - CHECK_INT(PyModule_AddObject(m, "Decimal", (PyObject *)&PyDec_Type)); - Py_INCREF(&PyDecContext_Type); - CHECK_INT(PyModule_AddObject(m, "Context", - (PyObject *)&PyDecContext_Type)); - Py_INCREF(DecimalTuple); - CHECK_INT(PyModule_AddObject(m, "DecimalTuple", (PyObject *)DecimalTuple)); - + CHECK_INT(PyModule_AddObjectRef(m, "Decimal", (PyObject *)&PyDec_Type)); + CHECK_INT(PyModule_AddObjectRef(m, "Context", (PyObject *)&PyDecContext_Type)); + CHECK_INT(PyModule_AddObjectRef(m, "DecimalTuple", (PyObject *)DecimalTuple)); /* Create top level exception */ ASSIGN_PTR(DecimalException, PyErr_NewException( "decimal.DecimalException", PyExc_ArithmeticError, NULL)); - Py_INCREF(DecimalException); - CHECK_INT(PyModule_AddObject(m, "DecimalException", DecimalException)); + CHECK_INT(PyModule_AddObjectRef(m, "DecimalException", DecimalException)); /* Create signal tuple */ ASSIGN_PTR(SignalTuple, PyTuple_New(SIGNAL_MAP_LEN)); @@ -5972,12 +5942,10 @@ PyInit__decimal(void) Py_DECREF(base); /* add to module */ - Py_INCREF(cm->ex); - CHECK_INT(PyModule_AddObject(m, cm->name, cm->ex)); + CHECK_INT(PyModule_AddObjectRef(m, cm->name, cm->ex)); /* add to signal tuple */ - Py_INCREF(cm->ex); - PyTuple_SET_ITEM(SignalTuple, i, cm->ex); + PyTuple_SET_ITEM(SignalTuple, i, Py_NewRef(cm->ex)); } /* @@ -6003,45 +5971,38 @@ PyInit__decimal(void) ASSIGN_PTR(cm->ex, PyErr_NewException(cm->fqname, base, NULL)); Py_DECREF(base); - Py_INCREF(cm->ex); - CHECK_INT(PyModule_AddObject(m, cm->name, cm->ex)); + CHECK_INT(PyModule_AddObjectRef(m, cm->name, cm->ex)); } /* Init default context template first */ ASSIGN_PTR(default_context_template, PyObject_CallObject((PyObject *)&PyDecContext_Type, NULL)); - Py_INCREF(default_context_template); - CHECK_INT(PyModule_AddObject(m, "DefaultContext", - default_context_template)); + CHECK_INT(PyModule_AddObjectRef(m, "DefaultContext", + default_context_template)); #ifndef WITH_DECIMAL_CONTEXTVAR ASSIGN_PTR(tls_context_key, PyUnicode_FromString("___DECIMAL_CTX__")); - Py_INCREF(Py_False); - CHECK_INT(PyModule_AddObject(m, "HAVE_CONTEXTVAR", Py_False)); + CHECK_INT(PyModule_AddObjectRef(m, "HAVE_CONTEXTVAR", Py_False)); #else ASSIGN_PTR(current_context_var, PyContextVar_New("decimal_context", NULL)); - Py_INCREF(Py_True); - CHECK_INT(PyModule_AddObject(m, "HAVE_CONTEXTVAR", Py_True)); + CHECK_INT(PyModule_AddObjectRef(m, "HAVE_CONTEXTVAR", Py_True)); #endif - Py_INCREF(Py_True); - CHECK_INT(PyModule_AddObject(m, "HAVE_THREADS", Py_True)); + CHECK_INT(PyModule_AddObjectRef(m, "HAVE_THREADS", Py_True)); /* Init basic context template */ ASSIGN_PTR(basic_context_template, PyObject_CallObject((PyObject *)&PyDecContext_Type, NULL)); init_basic_context(basic_context_template); - Py_INCREF(basic_context_template); - CHECK_INT(PyModule_AddObject(m, "BasicContext", - basic_context_template)); + CHECK_INT(PyModule_AddObjectRef(m, "BasicContext", + basic_context_template)); /* Init extended context template */ ASSIGN_PTR(extended_context_template, PyObject_CallObject((PyObject *)&PyDecContext_Type, NULL)); init_extended_context(extended_context_template); - Py_INCREF(extended_context_template); - CHECK_INT(PyModule_AddObject(m, "ExtendedContext", - extended_context_template)); + CHECK_INT(PyModule_AddObjectRef(m, "ExtendedContext", + extended_context_template)); /* Init mpd_ssize_t constants */ @@ -6060,8 +6021,7 @@ PyInit__decimal(void) /* Init string constants */ for (i = 0; i < _PY_DEC_ROUND_GUARD; i++) { ASSIGN_PTR(round_map[i], PyUnicode_InternFromString(mpd_round_string[i])); - Py_INCREF(round_map[i]); - CHECK_INT(PyModule_AddObject(m, mpd_round_string[i], round_map[i])); + CHECK_INT(PyModule_AddObjectRef(m, mpd_round_string[i], round_map[i])); } /* Add specification version number */ diff --git a/Modules/_decimal/libmpdec/mpdecimal.c b/Modules/_decimal/libmpdec/mpdecimal.c index f1626df4..959934bd 100644 --- a/Modules/_decimal/libmpdec/mpdecimal.c +++ b/Modules/_decimal/libmpdec/mpdecimal.c @@ -76,6 +76,12 @@ #endif #endif +/* ClangCL claims to support 128-bit int, but doesn't */ +#if defined(__SIZEOF_INT128__) && defined(__clang__) && defined(_MSC_VER) +#undef __SIZEOF_INT128__ +#endif + + #define MPD_NEWTONDIV_CUTOFF 1024L diff --git a/Modules/_decimal/tests/formathelper.py b/Modules/_decimal/tests/formathelper.py index c3daacfb..f4a6a1ce 100644 --- a/Modules/_decimal/tests/formathelper.py +++ b/Modules/_decimal/tests/formathelper.py @@ -32,7 +32,7 @@ import os, sys, locale, random import platform, subprocess from test.support.import_helper import import_fresh_module -from distutils.spawn import find_executable +from shutil import which C = import_fresh_module('decimal', fresh=['_decimal']) P = import_fresh_module('decimal', blocked=['_decimal']) @@ -139,7 +139,7 @@ else: with open("/var/lib/locales/supported.d/local") as f: locale_list = [loc.split()[0] for loc in f.readlines() \ if not loc.startswith('#')] - elif find_executable('locale'): + elif which('locale'): locale_list = subprocess.Popen(["locale", "-a"], stdout=subprocess.PIPE).communicate()[0] try: diff --git a/Modules/_decimal/tests/runall.bat b/Modules/_decimal/tests/runall.bat index f278ef33..a9d6c6f1 100755 --- a/Modules/_decimal/tests/runall.bat +++ b/Modules/_decimal/tests/runall.bat @@ -1,129 +1,129 @@ -@ECHO OFF - -rem Test all machine configurations, pydebug, refleaks, release build. - -cd ..\..\..\ - - -echo. -echo # ====================================================================== -echo # Building Python (Debug^|x64) -echo # ====================================================================== -echo. - -call .\Tools\buildbot\clean.bat -call .\Tools\buildbot\build.bat -c Debug -p x64 - -echo. -echo # ====================================================================== -echo # platform=Debug^|x64 -echo # ====================================================================== -echo. - -echo # ==================== refleak tests ======================= -echo. -call python.bat -m test -uall -R 3:3 test_decimal -echo. -echo. - -echo # ==================== regular tests ======================= -echo. -call python.bat -m test -uall test_decimal -echo. -echo. - -echo # ==================== deccheck ======================= -echo. -call python.bat .\Modules\_decimal\tests\deccheck.py -echo. -echo. - - -echo. -echo # ====================================================================== -echo # Building Python (Release^|x64) -echo # ====================================================================== -echo. - -call .\Tools\buildbot\clean.bat -call .\Tools\buildbot\build.bat -c Release -p x64 - -echo. -echo # ====================================================================== -echo # platform=Release^|x64 -echo # ====================================================================== -echo. - -echo # ==================== regular tests ======================= -echo. -call python.bat -m test -uall test_decimal -echo. -echo. - -echo # ==================== deccheck ======================= -echo. -call python.bat .\Modules\_decimal\tests\deccheck.py -echo. -echo. - - -echo. -echo # ====================================================================== -echo # Building Python (Debug^|Win32) -echo # ====================================================================== -echo. - -call .\Tools\buildbot\clean.bat -call Tools\buildbot\build.bat -c Debug -p Win32 - -echo. -echo # ====================================================================== -echo # platform=Debug^|Win32 -echo # ====================================================================== -echo. - -echo # ==================== refleak tests ======================= -echo. -call python.bat -m test -uall -R 3:3 test_decimal -echo. -echo. - -echo # ==================== regular tests ======================= -echo. -call python.bat -m test -uall test_decimal -echo. -echo. - -echo # ==================== deccheck ======================= -echo. -call python.bat .\Modules\_decimal\tests\deccheck.py -echo. -echo. - - -echo. -echo # ====================================================================== -echo # Building Python (Release^|Win32) -echo # ====================================================================== -echo. - -call .\Tools\buildbot\clean.bat -call .\Tools\buildbot\build.bat -c Release -p Win32 - -echo. -echo # ====================================================================== -echo # platform=Release^|Win32 -echo # ====================================================================== -echo. - -echo # ==================== regular tests ======================= -echo. -call python.bat -m test -uall test_decimal -echo. -echo. - -echo # ==================== deccheck ======================= -echo. -call python.bat .\Modules\_decimal\tests\deccheck.py -echo. -echo. +@ECHO OFF + +rem Test all machine configurations, pydebug, refleaks, release build. + +cd ..\..\..\ + + +echo. +echo # ====================================================================== +echo # Building Python (Debug^|x64) +echo # ====================================================================== +echo. + +call .\Tools\buildbot\clean.bat +call .\Tools\buildbot\build.bat -c Debug -p x64 + +echo. +echo # ====================================================================== +echo # platform=Debug^|x64 +echo # ====================================================================== +echo. + +echo # ==================== refleak tests ======================= +echo. +call python.bat -m test -uall -R 3:3 test_decimal +echo. +echo. + +echo # ==================== regular tests ======================= +echo. +call python.bat -m test -uall test_decimal +echo. +echo. + +echo # ==================== deccheck ======================= +echo. +call python.bat .\Modules\_decimal\tests\deccheck.py +echo. +echo. + + +echo. +echo # ====================================================================== +echo # Building Python (Release^|x64) +echo # ====================================================================== +echo. + +call .\Tools\buildbot\clean.bat +call .\Tools\buildbot\build.bat -c Release -p x64 + +echo. +echo # ====================================================================== +echo # platform=Release^|x64 +echo # ====================================================================== +echo. + +echo # ==================== regular tests ======================= +echo. +call python.bat -m test -uall test_decimal +echo. +echo. + +echo # ==================== deccheck ======================= +echo. +call python.bat .\Modules\_decimal\tests\deccheck.py +echo. +echo. + + +echo. +echo # ====================================================================== +echo # Building Python (Debug^|Win32) +echo # ====================================================================== +echo. + +call .\Tools\buildbot\clean.bat +call Tools\buildbot\build.bat -c Debug -p Win32 + +echo. +echo # ====================================================================== +echo # platform=Debug^|Win32 +echo # ====================================================================== +echo. + +echo # ==================== refleak tests ======================= +echo. +call python.bat -m test -uall -R 3:3 test_decimal +echo. +echo. + +echo # ==================== regular tests ======================= +echo. +call python.bat -m test -uall test_decimal +echo. +echo. + +echo # ==================== deccheck ======================= +echo. +call python.bat .\Modules\_decimal\tests\deccheck.py +echo. +echo. + + +echo. +echo # ====================================================================== +echo # Building Python (Release^|Win32) +echo # ====================================================================== +echo. + +call .\Tools\buildbot\clean.bat +call .\Tools\buildbot\build.bat -c Release -p Win32 + +echo. +echo # ====================================================================== +echo # platform=Release^|Win32 +echo # ====================================================================== +echo. + +echo # ==================== regular tests ======================= +echo. +call python.bat -m test -uall test_decimal +echo. +echo. + +echo # ==================== deccheck ======================= +echo. +call python.bat .\Modules\_decimal\tests\deccheck.py +echo. +echo. diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c index 89f877f6..6244fcc2 100644 --- a/Modules/_elementtree.c +++ b/Modules/_elementtree.c @@ -12,10 +12,11 @@ */ #define PY_SSIZE_T_CLEAN -#define NEEDS_PY_IDENTIFIER #include "Python.h" #include "structmember.h" // PyMemberDef +#include "expat.h" +#include "pyexpat.h" /* -------------------------------------------------------------------- */ /* configuration */ @@ -70,13 +71,6 @@ static void _clear_joined_ptr(PyObject **p) } } -/* Types defined by this extension */ -static PyTypeObject Element_Type; -static PyTypeObject ElementIter_Type; -static PyTypeObject TreeBuilder_Type; -static PyTypeObject XMLParser_Type; - - /* Per-module state; PEP 3121 */ typedef struct { PyObject *parseerror_obj; @@ -84,6 +78,22 @@ typedef struct { PyObject *elementpath_obj; PyObject *comment_factory; PyObject *pi_factory; + /* Interned strings */ + PyObject *str_text; + PyObject *str_tail; + PyObject *str_append; + PyObject *str_find; + PyObject *str_findtext; + PyObject *str_findall; + PyObject *str_iterfind; + PyObject *str_doctype; + /* Types defined by this extension */ + PyTypeObject *Element_Type; + PyTypeObject *ElementIter_Type; + PyTypeObject *TreeBuilder_Type; + PyTypeObject *XMLParser_Type; + + struct PyExpat_CAPI *expat_capi; } elementtreestate; static struct PyModuleDef elementtreemodule; @@ -99,11 +109,21 @@ get_elementtree_state(PyObject *module) return (elementtreestate *)state; } -/* Find the module instance imported in the currently running sub-interpreter - * and get its state. - */ -#define ET_STATE_GLOBAL \ - ((elementtreestate *) PyModule_GetState(PyState_FindModule(&elementtreemodule))) +static inline elementtreestate * +get_elementtree_state_by_cls(PyTypeObject *cls) +{ + void *state = PyType_GetModuleState(cls); + assert(state != NULL); + return (elementtreestate *)state; +} + +static inline elementtreestate * +get_elementtree_state_by_type(PyTypeObject *tp) +{ + PyObject *mod = PyType_GetModuleByDef(tp, &elementtreemodule); + assert(mod != NULL); + return get_elementtree_state(mod); +} static int elementtree_clear(PyObject *m) @@ -114,6 +134,24 @@ elementtree_clear(PyObject *m) Py_CLEAR(st->elementpath_obj); Py_CLEAR(st->comment_factory); Py_CLEAR(st->pi_factory); + + // Interned strings + Py_CLEAR(st->str_append); + Py_CLEAR(st->str_find); + Py_CLEAR(st->str_findall); + Py_CLEAR(st->str_findtext); + Py_CLEAR(st->str_iterfind); + Py_CLEAR(st->str_tail); + Py_CLEAR(st->str_text); + Py_CLEAR(st->str_doctype); + + // Heap types + Py_CLEAR(st->Element_Type); + Py_CLEAR(st->ElementIter_Type); + Py_CLEAR(st->TreeBuilder_Type); + Py_CLEAR(st->XMLParser_Type); + + st->expat_capi = NULL; return 0; } @@ -126,6 +164,12 @@ elementtree_traverse(PyObject *m, visitproc visit, void *arg) Py_VISIT(st->elementpath_obj); Py_VISIT(st->comment_factory); Py_VISIT(st->pi_factory); + + // Heap types + Py_VISIT(st->Element_Type); + Py_VISIT(st->ElementIter_Type); + Py_VISIT(st->TreeBuilder_Type); + Py_VISIT(st->XMLParser_Type); return 0; } @@ -205,8 +249,8 @@ typedef struct { } ElementObject; -#define Element_CheckExact(op) Py_IS_TYPE(op, &Element_Type) -#define Element_Check(op) PyObject_TypeCheck(op, &Element_Type) +#define Element_CheckExact(st, op) Py_IS_TYPE(op, (st)->Element_Type) +#define Element_Check(st, op) PyObject_TypeCheck(op, (st)->Element_Type) /* -------------------------------------------------------------------- */ @@ -221,8 +265,7 @@ create_extra(ElementObject* self, PyObject* attrib) return -1; } - Py_XINCREF(attrib); - self->extra->attrib = attrib; + self->extra->attrib = Py_XNewRef(attrib); self->extra->length = 0; self->extra->allocated = STATIC_CHILDREN; @@ -270,24 +313,17 @@ clear_extra(ElementObject* self) * tag and attributes. */ LOCAL(PyObject*) -create_new_element(PyObject* tag, PyObject* attrib) +create_new_element(elementtreestate *st, PyObject *tag, PyObject *attrib) { ElementObject* self; - self = PyObject_GC_New(ElementObject, &Element_Type); + self = PyObject_GC_New(ElementObject, st->Element_Type); if (self == NULL) return NULL; self->extra = NULL; - - Py_INCREF(tag); - self->tag = tag; - - Py_INCREF(Py_None); - self->text = Py_None; - - Py_INCREF(Py_None); - self->tail = Py_None; - + self->tag = Py_NewRef(tag); + self->text = Py_NewRef(Py_None); + self->tail = Py_NewRef(Py_None); self->weakreflist = NULL; PyObject_GC_Track(self); @@ -307,15 +343,9 @@ element_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { ElementObject *e = (ElementObject *)type->tp_alloc(type, 0); if (e != NULL) { - Py_INCREF(Py_None); - e->tag = Py_None; - - Py_INCREF(Py_None); - e->text = Py_None; - - Py_INCREF(Py_None); - e->tail = Py_None; - + e->tag = Py_NewRef(Py_None); + e->text = Py_NewRef(Py_None); + e->tail = Py_NewRef(Py_None); e->extra = NULL; e->weakreflist = NULL; } @@ -351,8 +381,7 @@ get_attrib_from_keywords(PyObject *kwds) } attrib = PyDict_Copy(attrib); if (attrib && PyDict_DelItem(kwds, attrib_str) < 0) { - Py_DECREF(attrib); - attrib = NULL; + Py_SETREF(attrib, NULL); } } else if (!PyErr_Occurred()) { @@ -370,11 +399,11 @@ get_attrib_from_keywords(PyObject *kwds) /*[clinic input] module _elementtree -class _elementtree.Element "ElementObject *" "&Element_Type" -class _elementtree.TreeBuilder "TreeBuilderObject *" "&TreeBuilder_Type" -class _elementtree.XMLParser "XMLParserObject *" "&XMLParser_Type" +class _elementtree.Element "ElementObject *" "clinic_state()->Element_Type" +class _elementtree.TreeBuilder "TreeBuilderObject *" "clinic_state()->TreeBuilder_Type" +class _elementtree.XMLParser "XMLParserObject *" "clinic_state()->XMLParser_Type" [clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=159aa50a54061c22]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=6c83ea832d2b0ef1]*/ static int element_init(PyObject *self, PyObject *args, PyObject *kwds) @@ -417,14 +446,10 @@ element_init(PyObject *self, PyObject *args, PyObject *kwds) Py_XDECREF(attrib); /* Replace the objects already pointed to by tag, text and tail. */ - Py_INCREF(tag); - Py_XSETREF(self_elem->tag, tag); + Py_XSETREF(self_elem->tag, Py_NewRef(tag)); - Py_INCREF(Py_None); - _set_joined_ptr(&self_elem->text, Py_None); - - Py_INCREF(Py_None); - _set_joined_ptr(&self_elem->tail, Py_None); + _set_joined_ptr(&self_elem->text, Py_NewRef(Py_None)); + _set_joined_ptr(&self_elem->tail, Py_NewRef(Py_None)); return 0; } @@ -494,11 +519,11 @@ raise_type_error(PyObject *element) } LOCAL(int) -element_add_subelement(ElementObject* self, PyObject* element) +element_add_subelement(elementtreestate *st, ElementObject *self, + PyObject *element) { /* add a child element to a parent */ - - if (!Element_Check(element)) { + if (!Element_Check(st, element)) { raise_type_error(element); return -1; } @@ -506,8 +531,7 @@ element_add_subelement(ElementObject* self, PyObject* element) if (element_resize(self, 1) < 0) return -1; - Py_INCREF(element); - self->extra->children[self->extra->length] = element; + self->extra->children[self->extra->length] = Py_NewRef(element); self->extra->length++; @@ -544,8 +568,7 @@ element_get_text(ElementObject* self) if (!tmp) return NULL; self->text = tmp; - Py_DECREF(res); - res = tmp; + Py_SETREF(res, tmp); } } @@ -566,8 +589,7 @@ element_get_tail(ElementObject* self) if (!tmp) return NULL; self->tail = tmp; - Py_DECREF(res); - res = tmp; + Py_SETREF(res, tmp); } } @@ -579,11 +601,12 @@ subelement(PyObject *self, PyObject *args, PyObject *kwds) { PyObject* elem; + elementtreestate *st = get_elementtree_state(self); ElementObject* parent; PyObject* tag; PyObject* attrib = NULL; if (!PyArg_ParseTuple(args, "O!O|O!:SubElement", - &Element_Type, &parent, &tag, + st->Element_Type, &parent, &tag, &PyDict_Type, &attrib)) { return NULL; } @@ -606,12 +629,12 @@ subelement(PyObject *self, PyObject *args, PyObject *kwds) /* no attrib arg, no kwds, so no attribute */ } - elem = create_new_element(tag, attrib); + elem = create_new_element(st, tag, attrib); Py_XDECREF(attrib); if (elem == NULL) return NULL; - if (element_add_subelement(parent, elem) < 0) { + if (element_add_subelement(st, parent, elem) < 0) { Py_DECREF(elem); return NULL; } @@ -622,6 +645,7 @@ subelement(PyObject *self, PyObject *args, PyObject *kwds) static int element_gc_traverse(ElementObject *self, visitproc visit, void *arg) { + Py_VISIT(Py_TYPE(self)); Py_VISIT(self->tag); Py_VISIT(JOIN_OBJ(self->text)); Py_VISIT(JOIN_OBJ(self->tail)); @@ -653,6 +677,8 @@ element_gc_clear(ElementObject *self) static void element_dealloc(ElementObject* self) { + PyTypeObject *tp = Py_TYPE(self); + /* bpo-31095: UnTrack is needed before calling any callbacks */ PyObject_GC_UnTrack(self); Py_TRASHCAN_BEGIN(self, element_dealloc) @@ -664,7 +690,8 @@ element_dealloc(ElementObject* self) */ element_gc_clear(self); - Py_TYPE(self)->tp_free((PyObject *)self); + tp->tp_free((PyObject *)self); + Py_DECREF(tp); Py_TRASHCAN_END } @@ -673,16 +700,19 @@ element_dealloc(ElementObject* self) /*[clinic input] _elementtree.Element.append - subelement: object(subclass_of='&Element_Type') + cls: defining_class + subelement: object(subclass_of='clinic_state()->Element_Type') / [clinic start generated code]*/ static PyObject * -_elementtree_Element_append_impl(ElementObject *self, PyObject *subelement) -/*[clinic end generated code: output=54a884b7cf2295f4 input=3ed648beb5bfa22a]*/ +_elementtree_Element_append_impl(ElementObject *self, PyTypeObject *cls, + PyObject *subelement) +/*[clinic end generated code: output=d00923711ea317fc input=8baf92679f9717b8]*/ { - if (element_add_subelement(self, subelement) < 0) + elementtreestate *st = get_elementtree_state_by_cls(cls); + if (element_add_subelement(st, self, subelement) < 0) return NULL; Py_RETURN_NONE; @@ -699,11 +729,8 @@ _elementtree_Element_clear_impl(ElementObject *self) { clear_extra(self); - Py_INCREF(Py_None); - _set_joined_ptr(&self->text, Py_None); - - Py_INCREF(Py_None); - _set_joined_ptr(&self->tail, Py_None); + _set_joined_ptr(&self->text, Py_NewRef(Py_None)); + _set_joined_ptr(&self->tail, Py_NewRef(Py_None)); Py_RETURN_NONE; } @@ -711,17 +738,21 @@ _elementtree_Element_clear_impl(ElementObject *self) /*[clinic input] _elementtree.Element.__copy__ + cls: defining_class + / + [clinic start generated code]*/ static PyObject * -_elementtree_Element___copy___impl(ElementObject *self) -/*[clinic end generated code: output=2c701ebff7247781 input=ad87aaebe95675bf]*/ +_elementtree_Element___copy___impl(ElementObject *self, PyTypeObject *cls) +/*[clinic end generated code: output=da22894421ff2b36 input=91edb92d9f441213]*/ { Py_ssize_t i; ElementObject* element; + elementtreestate *st = get_elementtree_state_by_cls(cls); element = (ElementObject*) create_new_element( - self->tag, self->extra ? self->extra->attrib : NULL); + st, self->tag, self->extra ? self->extra->attrib : NULL); if (!element) return NULL; @@ -739,8 +770,7 @@ _elementtree_Element___copy___impl(ElementObject *self) } for (i = 0; i < self->extra->length; i++) { - Py_INCREF(self->extra->children[i]); - element->extra->children[i] = self->extra->children[i]; + element->extra->children[i] = Py_NewRef(self->extra->children[i]); } assert(!element->extra->length); @@ -751,7 +781,7 @@ _elementtree_Element___copy___impl(ElementObject *self) } /* Helper for a deep copy. */ -LOCAL(PyObject *) deepcopy(PyObject *, PyObject *); +LOCAL(PyObject *) deepcopy(elementtreestate *, PyObject *, PyObject *); /*[clinic input] _elementtree.Element.__deepcopy__ @@ -773,12 +803,14 @@ _elementtree_Element___deepcopy___impl(ElementObject *self, PyObject *memo) PyObject* tail; PyObject* id; - tag = deepcopy(self->tag, memo); + PyTypeObject *tp = Py_TYPE(self); + elementtreestate *st = get_elementtree_state_by_type(tp); + tag = deepcopy(st, self->tag, memo); if (!tag) return NULL; if (self->extra && self->extra->attrib) { - attrib = deepcopy(self->extra->attrib, memo); + attrib = deepcopy(st, self->extra->attrib, memo); if (!attrib) { Py_DECREF(tag); return NULL; @@ -787,7 +819,7 @@ _elementtree_Element___deepcopy___impl(ElementObject *self, PyObject *memo) attrib = NULL; } - element = (ElementObject*) create_new_element(tag, attrib); + element = (ElementObject*) create_new_element(st, tag, attrib); Py_DECREF(tag); Py_XDECREF(attrib); @@ -795,12 +827,12 @@ _elementtree_Element___deepcopy___impl(ElementObject *self, PyObject *memo) if (!element) return NULL; - text = deepcopy(JOIN_OBJ(self->text), memo); + text = deepcopy(st, JOIN_OBJ(self->text), memo); if (!text) goto error; _set_joined_ptr(&element->text, JOIN_SET(text, JOIN_GET(self->text))); - tail = deepcopy(JOIN_OBJ(self->tail), memo); + tail = deepcopy(st, JOIN_OBJ(self->tail), memo); if (!tail) goto error; _set_joined_ptr(&element->tail, JOIN_SET(tail, JOIN_GET(self->tail))); @@ -811,8 +843,8 @@ _elementtree_Element___deepcopy___impl(ElementObject *self, PyObject *memo) goto error; for (i = 0; i < self->extra->length; i++) { - PyObject* child = deepcopy(self->extra->children[i], memo); - if (!child || !Element_Check(child)) { + PyObject* child = deepcopy(st, self->extra->children[i], memo); + if (!child || !Element_Check(st, child)) { if (child) { raise_type_error(child); Py_DECREF(child); @@ -847,16 +879,14 @@ _elementtree_Element___deepcopy___impl(ElementObject *self, PyObject *memo) } LOCAL(PyObject *) -deepcopy(PyObject *object, PyObject *memo) +deepcopy(elementtreestate *st, PyObject *object, PyObject *memo) { /* do a deep copy of the given object */ - elementtreestate *st; PyObject *stack[2]; /* Fast paths */ if (object == Py_None || PyUnicode_CheckExact(object)) { - Py_INCREF(object); - return object; + return Py_NewRef(object); } if (Py_REFCNT(object) == 1) { @@ -874,14 +904,13 @@ deepcopy(PyObject *object, PyObject *memo) return PyDict_Copy(object); /* Fall through to general case */ } - else if (Element_CheckExact(object)) { + else if (Element_CheckExact(st, object)) { return _elementtree_Element___deepcopy___impl( (ElementObject *)object, memo); } } /* General case */ - st = ET_STATE_GLOBAL; if (!st->deepcopy_obj) { PyErr_SetString(PyExc_RuntimeError, "deepcopy helper not found"); @@ -895,19 +924,20 @@ deepcopy(PyObject *object, PyObject *memo) /*[clinic input] -_elementtree.Element.__sizeof__ -> Py_ssize_t +_elementtree.Element.__sizeof__ -> size_t [clinic start generated code]*/ -static Py_ssize_t +static size_t _elementtree_Element___sizeof___impl(ElementObject *self) -/*[clinic end generated code: output=bf73867721008000 input=70f4b323d55a17c1]*/ +/*[clinic end generated code: output=baae4e7ae9fe04ec input=54e298c501f3e0d0]*/ { - Py_ssize_t result = _PyObject_SIZE(Py_TYPE(self)); + size_t result = _PyObject_SIZE(Py_TYPE(self)); if (self->extra) { result += sizeof(ElementObjectExtra); - if (self->extra->children != self->extra->_children) - result += sizeof(PyObject*) * self->extra->allocated; + if (self->extra->children != self->extra->_children) { + result += (size_t)self->extra->allocated * sizeof(PyObject*); + } } return result; } @@ -942,14 +972,12 @@ _elementtree_Element___getstate___impl(ElementObject *self) if (!children) return NULL; for (i = 0; i < PyList_GET_SIZE(children); i++) { - PyObject *child = self->extra->children[i]; - Py_INCREF(child); + PyObject *child = Py_NewRef(self->extra->children[i]); PyList_SET_ITEM(children, i, child); } if (self->extra && self->extra->attrib) { - attrib = self->extra->attrib; - Py_INCREF(attrib); + attrib = Py_NewRef(self->extra->attrib); } else { attrib = PyDict_New(); @@ -968,7 +996,8 @@ _elementtree_Element___getstate___impl(ElementObject *self) } static PyObject * -element_setstate_from_attributes(ElementObject *self, +element_setstate_from_attributes(elementtreestate *st, + ElementObject *self, PyObject *tag, PyObject *attrib, PyObject *text, @@ -983,8 +1012,7 @@ element_setstate_from_attributes(ElementObject *self, return NULL; } - Py_INCREF(tag); - Py_XSETREF(self->tag, tag); + Py_XSETREF(self->tag, Py_NewRef(tag)); text = text ? JOIN_SET(text, PyList_CheckExact(text)) : Py_None; Py_INCREF(JOIN_OBJ(text)); @@ -1029,14 +1057,13 @@ element_setstate_from_attributes(ElementObject *self, /* Copy children */ for (i = 0; i < nchildren; i++) { PyObject *child = PyList_GET_ITEM(children, i); - if (!Element_Check(child)) { + if (!Element_Check(st, child)) { raise_type_error(child); self->extra->length = i; dealloc_extra(oldextra); return NULL; } - Py_INCREF(child); - self->extra->children[i] = child; + self->extra->children[i] = Py_NewRef(child); } assert(!self->extra->length); @@ -1049,8 +1076,7 @@ element_setstate_from_attributes(ElementObject *self, } /* Stash attrib. */ - Py_XINCREF(attrib); - Py_XSETREF(self->extra->attrib, attrib); + Py_XSETREF(self->extra->attrib, Py_XNewRef(attrib)); dealloc_extra(oldextra); Py_RETURN_NONE; @@ -1061,7 +1087,8 @@ element_setstate_from_attributes(ElementObject *self, */ static PyObject * -element_setstate_from_Python(ElementObject *self, PyObject *state) +element_setstate_from_Python(elementtreestate *st, ElementObject *self, + PyObject *state) { static char *kwlist[] = {PICKLED_TAG, PICKLED_ATTRIB, PICKLED_TEXT, PICKLED_TAIL, PICKLED_CHILDREN, 0}; @@ -1076,7 +1103,7 @@ element_setstate_from_Python(ElementObject *self, PyObject *state) if (PyArg_ParseTupleAndKeywords(args, state, "|$OOOOO", kwlist, &tag, &attrib, &text, &tail, &children)) - retval = element_setstate_from_attributes(self, tag, attrib, text, + retval = element_setstate_from_attributes(st, self, tag, attrib, text, tail, children); else retval = NULL; @@ -1088,14 +1115,16 @@ element_setstate_from_Python(ElementObject *self, PyObject *state) /*[clinic input] _elementtree.Element.__setstate__ + cls: defining_class state: object / [clinic start generated code]*/ static PyObject * -_elementtree_Element___setstate__(ElementObject *self, PyObject *state) -/*[clinic end generated code: output=ea28bf3491b1f75e input=aaf80abea7c1e3b9]*/ +_elementtree_Element___setstate___impl(ElementObject *self, + PyTypeObject *cls, PyObject *state) +/*[clinic end generated code: output=598bfb5730f71509 input=13830488d35d51f7]*/ { if (!PyDict_CheckExact(state)) { PyErr_Format(PyExc_TypeError, @@ -1103,8 +1132,10 @@ _elementtree_Element___setstate__(ElementObject *self, PyObject *state) state); return NULL; } - else - return element_setstate_from_Python(self, state); + else { + elementtreestate *st = get_elementtree_state_by_cls(cls); + return element_setstate_from_Python(st, self, state); + } } LOCAL(int) @@ -1121,7 +1152,7 @@ checkpath(PyObject* tag) if (PyUnicode_Check(tag)) { const Py_ssize_t len = PyUnicode_GET_LENGTH(tag); const void *data = PyUnicode_DATA(tag); - unsigned int kind = PyUnicode_KIND(tag); + int kind = PyUnicode_KIND(tag); if (len >= 3 && PyUnicode_READ(kind, data, 0) == '{' && ( PyUnicode_READ(kind, data, 1) == '}' || ( PyUnicode_READ(kind, data, 1) == '*' && @@ -1165,14 +1196,16 @@ checkpath(PyObject* tag) /*[clinic input] _elementtree.Element.extend + cls: defining_class elements: object / [clinic start generated code]*/ static PyObject * -_elementtree_Element_extend(ElementObject *self, PyObject *elements) -/*[clinic end generated code: output=f6e67fc2ff529191 input=807bc4f31c69f7c0]*/ +_elementtree_Element_extend_impl(ElementObject *self, PyTypeObject *cls, + PyObject *elements) +/*[clinic end generated code: output=3e86d37fac542216 input=6479b1b5379d09ae]*/ { PyObject* seq; Py_ssize_t i; @@ -1186,10 +1219,10 @@ _elementtree_Element_extend(ElementObject *self, PyObject *elements) return NULL; } + elementtreestate *st = get_elementtree_state_by_cls(cls); for (i = 0; i < PySequence_Fast_GET_SIZE(seq); i++) { - PyObject* element = PySequence_Fast_GET_ITEM(seq, i); - Py_INCREF(element); - if (element_add_subelement(self, element) < 0) { + PyObject* element = Py_NewRef(PySequence_Fast_GET_ITEM(seq, i)); + if (element_add_subelement(st, self, element) < 0) { Py_DECREF(seq); Py_DECREF(element); return NULL; @@ -1205,23 +1238,24 @@ _elementtree_Element_extend(ElementObject *self, PyObject *elements) /*[clinic input] _elementtree.Element.find + cls: defining_class + / path: object namespaces: object = None [clinic start generated code]*/ static PyObject * -_elementtree_Element_find_impl(ElementObject *self, PyObject *path, - PyObject *namespaces) -/*[clinic end generated code: output=41b43f0f0becafae input=359b6985f6489d2e]*/ +_elementtree_Element_find_impl(ElementObject *self, PyTypeObject *cls, + PyObject *path, PyObject *namespaces) +/*[clinic end generated code: output=18f77d393c9fef1b input=94df8a83f956acc6]*/ { Py_ssize_t i; - elementtreestate *st = ET_STATE_GLOBAL; + elementtreestate *st = get_elementtree_state_by_cls(cls); if (checkpath(path) || namespaces != Py_None) { - _Py_IDENTIFIER(find); - return _PyObject_CallMethodIdObjArgs( - st->elementpath_obj, &PyId_find, self, path, namespaces, NULL + return PyObject_CallMethodObjArgs( + st->elementpath_obj, st->str_find, self, path, namespaces, NULL ); } @@ -1231,7 +1265,7 @@ _elementtree_Element_find_impl(ElementObject *self, PyObject *path, for (i = 0; i < self->extra->length; i++) { PyObject* item = self->extra->children[i]; int rc; - assert(Element_Check(item)); + assert(Element_Check(st, item)); Py_INCREF(item); rc = PyObject_RichCompareBool(((ElementObject*)item)->tag, path, Py_EQ); if (rc > 0) @@ -1247,6 +1281,8 @@ _elementtree_Element_find_impl(ElementObject *self, PyObject *path, /*[clinic input] _elementtree.Element.findtext + cls: defining_class + / path: object default: object = None namespaces: object = None @@ -1254,30 +1290,28 @@ _elementtree.Element.findtext [clinic start generated code]*/ static PyObject * -_elementtree_Element_findtext_impl(ElementObject *self, PyObject *path, - PyObject *default_value, +_elementtree_Element_findtext_impl(ElementObject *self, PyTypeObject *cls, + PyObject *path, PyObject *default_value, PyObject *namespaces) -/*[clinic end generated code: output=83b3ba4535d308d2 input=b53a85aa5aa2a916]*/ +/*[clinic end generated code: output=6af7a2d96aac32cb input=32f252099f62a3d2]*/ { Py_ssize_t i; - _Py_IDENTIFIER(findtext); - elementtreestate *st = ET_STATE_GLOBAL; + elementtreestate *st = get_elementtree_state_by_cls(cls); if (checkpath(path) || namespaces != Py_None) - return _PyObject_CallMethodIdObjArgs( - st->elementpath_obj, &PyId_findtext, + return PyObject_CallMethodObjArgs( + st->elementpath_obj, st->str_findtext, self, path, default_value, namespaces, NULL ); if (!self->extra) { - Py_INCREF(default_value); - return default_value; + return Py_NewRef(default_value); } for (i = 0; i < self->extra->length; i++) { PyObject *item = self->extra->children[i]; int rc; - assert(Element_Check(item)); + assert(Element_Check(st, item)); Py_INCREF(item); rc = PyObject_RichCompareBool(((ElementObject*)item)->tag, path, Py_EQ); if (rc > 0) { @@ -1295,31 +1329,31 @@ _elementtree_Element_findtext_impl(ElementObject *self, PyObject *path, return NULL; } - Py_INCREF(default_value); - return default_value; + return Py_NewRef(default_value); } /*[clinic input] _elementtree.Element.findall + cls: defining_class + / path: object namespaces: object = None [clinic start generated code]*/ static PyObject * -_elementtree_Element_findall_impl(ElementObject *self, PyObject *path, - PyObject *namespaces) -/*[clinic end generated code: output=1a0bd9f5541b711d input=4d9e6505a638550c]*/ +_elementtree_Element_findall_impl(ElementObject *self, PyTypeObject *cls, + PyObject *path, PyObject *namespaces) +/*[clinic end generated code: output=65e39a1208f3b59e input=7aa0db45673fc9a5]*/ { Py_ssize_t i; PyObject* out; - elementtreestate *st = ET_STATE_GLOBAL; + elementtreestate *st = get_elementtree_state_by_cls(cls); if (checkpath(path) || namespaces != Py_None) { - _Py_IDENTIFIER(findall); - return _PyObject_CallMethodIdObjArgs( - st->elementpath_obj, &PyId_findall, self, path, namespaces, NULL + return PyObject_CallMethodObjArgs( + st->elementpath_obj, st->str_findall, self, path, namespaces, NULL ); } @@ -1333,7 +1367,7 @@ _elementtree_Element_findall_impl(ElementObject *self, PyObject *path, for (i = 0; i < self->extra->length; i++) { PyObject* item = self->extra->children[i]; int rc; - assert(Element_Check(item)); + assert(Element_Check(st, item)); Py_INCREF(item); rc = PyObject_RichCompareBool(((ElementObject*)item)->tag, path, Py_EQ); if (rc != 0 && (rc < 0 || PyList_Append(out, item) < 0)) { @@ -1350,22 +1384,23 @@ _elementtree_Element_findall_impl(ElementObject *self, PyObject *path, /*[clinic input] _elementtree.Element.iterfind + cls: defining_class + / path: object namespaces: object = None [clinic start generated code]*/ static PyObject * -_elementtree_Element_iterfind_impl(ElementObject *self, PyObject *path, - PyObject *namespaces) -/*[clinic end generated code: output=ecdd56d63b19d40f input=abb974e350fb65c7]*/ +_elementtree_Element_iterfind_impl(ElementObject *self, PyTypeObject *cls, + PyObject *path, PyObject *namespaces) +/*[clinic end generated code: output=be5c3f697a14e676 input=88766875a5c9a88b]*/ { PyObject* tag = path; - _Py_IDENTIFIER(iterfind); - elementtreestate *st = ET_STATE_GLOBAL; + elementtreestate *st = get_elementtree_state_by_cls(cls); - return _PyObject_CallMethodIdObjArgs( - st->elementpath_obj, &PyId_iterfind, self, tag, namespaces, NULL); + return PyObject_CallMethodObjArgs( + st->elementpath_obj, st->str_iterfind, self, tag, namespaces, NULL); } /*[clinic input] @@ -1382,34 +1417,35 @@ _elementtree_Element_get_impl(ElementObject *self, PyObject *key, /*[clinic end generated code: output=523c614142595d75 input=ee153bbf8cdb246e]*/ { if (self->extra && self->extra->attrib) { - PyObject *attrib = self->extra->attrib; - Py_INCREF(attrib); - PyObject *value = PyDict_GetItemWithError(attrib, key); - Py_XINCREF(value); + PyObject *attrib = Py_NewRef(self->extra->attrib); + PyObject *value = Py_XNewRef(PyDict_GetItemWithError(attrib, key)); Py_DECREF(attrib); if (value != NULL || PyErr_Occurred()) { return value; } } - Py_INCREF(default_value); - return default_value; + return Py_NewRef(default_value); } static PyObject * -create_elementiter(ElementObject *self, PyObject *tag, int gettext); +create_elementiter(elementtreestate *st, ElementObject *self, PyObject *tag, + int gettext); /*[clinic input] _elementtree.Element.iter + cls: defining_class + / tag: object = None [clinic start generated code]*/ static PyObject * -_elementtree_Element_iter_impl(ElementObject *self, PyObject *tag) -/*[clinic end generated code: output=3f49f9a862941cc5 input=774d5b12e573aedd]*/ +_elementtree_Element_iter_impl(ElementObject *self, PyTypeObject *cls, + PyObject *tag) +/*[clinic end generated code: output=bff29dc5d4566c68 input=f6944c48d3f84c58]*/ { if (PyUnicode_Check(tag)) { if (PyUnicode_READY(tag) < 0) @@ -1422,20 +1458,25 @@ _elementtree_Element_iter_impl(ElementObject *self, PyObject *tag) tag = Py_None; } - return create_elementiter(self, tag, 0); + elementtreestate *st = get_elementtree_state_by_cls(cls); + return create_elementiter(st, self, tag, 0); } /*[clinic input] _elementtree.Element.itertext + cls: defining_class + / + [clinic start generated code]*/ static PyObject * -_elementtree_Element_itertext_impl(ElementObject *self) -/*[clinic end generated code: output=5fa34b2fbcb65df6 input=af8f0e42cb239c89]*/ +_elementtree_Element_itertext_impl(ElementObject *self, PyTypeObject *cls) +/*[clinic end generated code: output=fdeb2a3bca0ae063 input=a1ef1f0fc872a586]*/ { - return create_elementiter(self, Py_None, 1); + elementtreestate *st = get_elementtree_state_by_cls(cls); + return create_elementiter(st, self, Py_None, 1); } @@ -1452,15 +1493,31 @@ element_getitem(PyObject* self_, Py_ssize_t index) return NULL; } - Py_INCREF(self->extra->children[index]); - return self->extra->children[index]; + return Py_NewRef(self->extra->children[index]); +} + +static int +element_bool(PyObject* self_) +{ + ElementObject* self = (ElementObject*) self_; + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Testing an element's truth value will raise an exception " + "in future versions. Use specific 'len(elem)' or " + "'elem is not None' test instead.", + 1) < 0) { + return -1; + }; + if (self->extra ? self->extra->length : 0) { + return 1; + } + return 0; } /*[clinic input] _elementtree.Element.insert index: Py_ssize_t - subelement: object(subclass_of='&Element_Type') + subelement: object(subclass_of='clinic_state()->Element_Type') / [clinic start generated code]*/ @@ -1468,7 +1525,7 @@ _elementtree.Element.insert static PyObject * _elementtree_Element_insert_impl(ElementObject *self, Py_ssize_t index, PyObject *subelement) -/*[clinic end generated code: output=990adfef4d424c0b input=cd6fbfcdab52d7a8]*/ +/*[clinic end generated code: output=990adfef4d424c0b input=9530f4905aa401ca]*/ { Py_ssize_t i; @@ -1491,8 +1548,7 @@ _elementtree_Element_insert_impl(ElementObject *self, Py_ssize_t index, for (i = self->extra->length; i > index; i--) self->extra->children[i] = self->extra->children[i-1]; - Py_INCREF(subelement); - self->extra->children[index] = subelement; + self->extra->children[index] = Py_NewRef(subelement); self->extra->length++; @@ -1541,6 +1597,7 @@ element_length(ElementObject* self) /*[clinic input] _elementtree.Element.makeelement + cls: defining_class tag: object attrib: object(subclass_of='&PyDict_Type') / @@ -1548,9 +1605,9 @@ _elementtree.Element.makeelement [clinic start generated code]*/ static PyObject * -_elementtree_Element_makeelement_impl(ElementObject *self, PyObject *tag, - PyObject *attrib) -/*[clinic end generated code: output=4109832d5bb789ef input=2279d974529c3861]*/ +_elementtree_Element_makeelement_impl(ElementObject *self, PyTypeObject *cls, + PyObject *tag, PyObject *attrib) +/*[clinic end generated code: output=d50bb17a47077d47 input=589829dab92f26e8]*/ { PyObject* elem; @@ -1558,7 +1615,8 @@ _elementtree_Element_makeelement_impl(ElementObject *self, PyObject *tag, if (!attrib) return NULL; - elem = create_new_element(tag, attrib); + elementtreestate *st = get_elementtree_state_by_cls(cls); + elem = create_new_element(st, tag, attrib); Py_DECREF(attrib); @@ -1568,14 +1626,14 @@ _elementtree_Element_makeelement_impl(ElementObject *self, PyObject *tag, /*[clinic input] _elementtree.Element.remove - subelement: object(subclass_of='&Element_Type') + subelement: object(subclass_of='clinic_state()->Element_Type') / [clinic start generated code]*/ static PyObject * _elementtree_Element_remove_impl(ElementObject *self, PyObject *subelement) -/*[clinic end generated code: output=38fe6c07d6d87d1f input=d52fc28ededc0bd8]*/ +/*[clinic end generated code: output=38fe6c07d6d87d1f input=6133e1d05597d5ee]*/ { Py_ssize_t i; int rc; @@ -1689,12 +1747,13 @@ element_setitem(PyObject* self_, Py_ssize_t index, PyObject* item) old = self->extra->children[index]; if (item) { - if (!Element_Check(item)) { + PyTypeObject *tp = Py_TYPE(self); + elementtreestate *st = get_elementtree_state_by_type(tp); + if (!Element_Check(st, item)) { raise_type_error(item); return -1; } - Py_INCREF(item); - self->extra->children[index] = item; + self->extra->children[index] = Py_NewRef(item); } else { self->extra->length--; for (i = index; i < self->extra->length; i++) @@ -1744,8 +1803,7 @@ element_subscr(PyObject* self_, PyObject* item) for (cur = start, i = 0; i < slicelen; cur += step, i++) { - PyObject* item = self->extra->children[cur]; - Py_INCREF(item); + PyObject* item = Py_NewRef(self->extra->children[cur]); PyList_SET_ITEM(list, i, item); } @@ -1888,9 +1946,11 @@ element_ass_subscr(PyObject* self_, PyObject* item, PyObject* value) } } + PyTypeObject *tp = Py_TYPE(self); + elementtreestate *st = get_elementtree_state_by_type(tp); for (i = 0; i < newlen; i++) { PyObject *element = PySequence_Fast_GET_ITEM(seq, i); - if (!Element_Check(element)) { + if (!Element_Check(st, element)) { raise_type_error(element); Py_DECREF(seq); return -1; @@ -1925,8 +1985,7 @@ element_ass_subscr(PyObject* self_, PyObject* item, PyObject* value) for (cur = start, i = 0; i < newlen; cur += step, i++) { PyObject* element = PySequence_Fast_GET_ITEM(seq, i); - Py_INCREF(element); - self->extra->children[cur] = element; + self->extra->children[cur] = Py_NewRef(element); } self->extra->length += newlen - slicelen; @@ -1949,24 +2008,21 @@ static PyObject* element_tag_getter(ElementObject *self, void *closure) { PyObject *res = self->tag; - Py_INCREF(res); - return res; + return Py_NewRef(res); } static PyObject* element_text_getter(ElementObject *self, void *closure) { PyObject *res = element_get_text(self); - Py_XINCREF(res); - return res; + return Py_XNewRef(res); } static PyObject* element_tail_getter(ElementObject *self, void *closure) { PyObject *res = element_get_tail(self); - Py_XINCREF(res); - return res; + return Py_XNewRef(res); } static PyObject* @@ -1978,8 +2034,7 @@ element_attrib_getter(ElementObject *self, void *closure) return NULL; } res = element_get_attrib(self); - Py_XINCREF(res); - return res; + return Py_XNewRef(res); } /* macro for setter validation */ @@ -1995,8 +2050,7 @@ static int element_tag_setter(ElementObject *self, PyObject *value, void *closure) { _VALIDATE_ATTR_VALUE(value); - Py_INCREF(value); - Py_SETREF(self->tag, value); + Py_SETREF(self->tag, Py_NewRef(value)); return 0; } @@ -2004,8 +2058,7 @@ static int element_text_setter(ElementObject *self, PyObject *value, void *closure) { _VALIDATE_ATTR_VALUE(value); - Py_INCREF(value); - _set_joined_ptr(&self->text, value); + _set_joined_ptr(&self->text, Py_NewRef(value)); return 0; } @@ -2013,8 +2066,7 @@ static int element_tail_setter(ElementObject *self, PyObject *value, void *closure) { _VALIDATE_ATTR_VALUE(value); - Py_INCREF(value); - _set_joined_ptr(&self->tail, value); + _set_joined_ptr(&self->tail, Py_NewRef(value)); return 0; } @@ -2032,21 +2084,10 @@ element_attrib_setter(ElementObject *self, PyObject *value, void *closure) if (create_extra(self, NULL) < 0) return -1; } - Py_INCREF(value); - Py_XSETREF(self->extra->attrib, value); + Py_XSETREF(self->extra->attrib, Py_NewRef(value)); return 0; } -static PySequenceMethods element_as_sequence = { - (lenfunc) element_length, - 0, /* sq_concat */ - 0, /* sq_repeat */ - element_getitem, - 0, - element_setitem, - 0, -}; - /******************************* Element iterator ****************************/ /* ElementIterObject represents the iteration state over an XML element in @@ -2076,6 +2117,7 @@ typedef struct { static void elementiter_dealloc(ElementIterObject *it) { + PyTypeObject *tp = Py_TYPE(it); Py_ssize_t i = it->parent_stack_used; it->parent_stack_used = 0; /* bpo-31095: UnTrack is needed before calling any callbacks */ @@ -2087,7 +2129,8 @@ elementiter_dealloc(ElementIterObject *it) Py_XDECREF(it->sought_tag); Py_XDECREF(it->root_element); - PyObject_GC_Del(it); + tp->tp_free(it); + Py_DECREF(tp); } static int @@ -2099,6 +2142,7 @@ elementiter_traverse(ElementIterObject *it, visitproc visit, void *arg) Py_VISIT(it->root_element); Py_VISIT(it->sought_tag); + Py_VISIT(Py_TYPE(it)); return 0; } @@ -2119,8 +2163,7 @@ parent_stack_push_new(ElementIterObject *it, ElementObject *parent) it->parent_stack_size = new_size; } item = it->parent_stack + it->parent_stack_used++; - Py_INCREF(parent); - item->parent = parent; + item->parent = (ElementObject*)Py_NewRef(parent); item->child_index = 0; return 0; } @@ -2180,10 +2223,13 @@ elementiter_next(ElementIterObject *it) continue; } - assert(Element_Check(extra->children[child_index])); - elem = (ElementObject *)extra->children[child_index]; +#ifndef NDEBUG + PyTypeObject *tp = Py_TYPE(it); + elementtreestate *st = get_elementtree_state_by_type(tp); + assert(Element_Check(st, extra->children[child_index])); +#endif + elem = (ElementObject *)Py_NewRef(extra->children[child_index]); item->child_index++; - Py_INCREF(elem); } if (parent_stack_push_new(it, elem) < 0) { @@ -2231,67 +2277,39 @@ gettext: return NULL; } +static PyType_Slot elementiter_slots[] = { + {Py_tp_dealloc, elementiter_dealloc}, + {Py_tp_traverse, elementiter_traverse}, + {Py_tp_iter, PyObject_SelfIter}, + {Py_tp_iternext, elementiter_next}, + {0, NULL}, +}; -static PyTypeObject ElementIter_Type = { - PyVarObject_HEAD_INIT(NULL, 0) +static PyType_Spec elementiter_spec = { /* Using the module's name since the pure-Python implementation does not have such a type. */ - "_elementtree._element_iterator", /* tp_name */ - sizeof(ElementIterObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)elementiter_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 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_HAVE_GC, /* tp_flags */ - 0, /* tp_doc */ - (traverseproc)elementiter_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)elementiter_next, /* 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 */ - 0, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ + .name = "_elementtree._element_iterator", + .basicsize = sizeof(ElementIterObject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_DISALLOW_INSTANTIATION), + .slots = elementiter_slots, }; #define INIT_PARENT_STACK_SIZE 8 static PyObject * -create_elementiter(ElementObject *self, PyObject *tag, int gettext) +create_elementiter(elementtreestate *st, ElementObject *self, PyObject *tag, + int gettext) { ElementIterObject *it; - it = PyObject_GC_New(ElementIterObject, &ElementIter_Type); + it = PyObject_GC_New(ElementIterObject, st->ElementIter_Type); if (!it) return NULL; - Py_INCREF(tag); - it->sought_tag = tag; + it->sought_tag = Py_NewRef(tag); it->gettext = gettext; - Py_INCREF(self); - it->root_element = self; + it->root_element = (ElementObject*)Py_NewRef(self); it->parent_stack = PyMem_New(ParentLocator, INIT_PARENT_STACK_SIZE); if (it->parent_stack == NULL) { @@ -2340,9 +2358,10 @@ typedef struct { char insert_comments; char insert_pis; + elementtreestate *state; } TreeBuilderObject; -#define TreeBuilder_CheckExact(op) Py_IS_TYPE((op), &TreeBuilder_Type) +#define TreeBuilder_CheckExact(st, op) Py_IS_TYPE((op), (st)->TreeBuilder_Type) /* -------------------------------------------------------------------- */ /* constructor and destructor */ @@ -2353,12 +2372,8 @@ treebuilder_new(PyTypeObject *type, PyObject *args, PyObject *kwds) TreeBuilderObject *t = (TreeBuilderObject *)type->tp_alloc(type, 0); if (t != NULL) { t->root = NULL; - - Py_INCREF(Py_None); - t->this = Py_None; - Py_INCREF(Py_None); - t->last = Py_None; - + t->this = Py_NewRef(Py_None); + t->last = Py_NewRef(Py_None); t->data = NULL; t->element_factory = NULL; t->comment_factory = NULL; @@ -2377,6 +2392,7 @@ treebuilder_new(PyTypeObject *type, PyObject *args, PyObject *kwds) t->start_ns_event_obj = t->end_ns_event_obj = NULL; t->comment_event_obj = t->pi_event_obj = NULL; t->insert_comments = t->insert_pis = 0; + t->state = get_elementtree_state_by_type(type); } return (PyObject *)t; } @@ -2402,19 +2418,17 @@ _elementtree_TreeBuilder___init___impl(TreeBuilderObject *self, /*[clinic end generated code: output=8571d4dcadfdf952 input=ae98a94df20b5cc3]*/ { if (element_factory != Py_None) { - Py_INCREF(element_factory); - Py_XSETREF(self->element_factory, element_factory); + Py_XSETREF(self->element_factory, Py_NewRef(element_factory)); } else { Py_CLEAR(self->element_factory); } if (comment_factory == Py_None) { - elementtreestate *st = ET_STATE_GLOBAL; + elementtreestate *st = self->state; comment_factory = st->comment_factory; } if (comment_factory) { - Py_INCREF(comment_factory); - Py_XSETREF(self->comment_factory, comment_factory); + Py_XSETREF(self->comment_factory, Py_NewRef(comment_factory)); self->insert_comments = insert_comments; } else { Py_CLEAR(self->comment_factory); @@ -2422,12 +2436,11 @@ _elementtree_TreeBuilder___init___impl(TreeBuilderObject *self, } if (pi_factory == Py_None) { - elementtreestate *st = ET_STATE_GLOBAL; + elementtreestate *st = self->state; pi_factory = st->pi_factory; } if (pi_factory) { - Py_INCREF(pi_factory); - Py_XSETREF(self->pi_factory, pi_factory); + Py_XSETREF(self->pi_factory, Py_NewRef(pi_factory)); self->insert_pis = insert_pis; } else { Py_CLEAR(self->pi_factory); @@ -2440,6 +2453,7 @@ _elementtree_TreeBuilder___init___impl(TreeBuilderObject *self, static int treebuilder_gc_traverse(TreeBuilderObject *self, visitproc visit, void *arg) { + Py_VISIT(Py_TYPE(self)); Py_VISIT(self->pi_event_obj); Py_VISIT(self->comment_event_obj); Py_VISIT(self->end_ns_event_obj); @@ -2484,9 +2498,11 @@ treebuilder_gc_clear(TreeBuilderObject *self) static void treebuilder_dealloc(TreeBuilderObject *self) { + PyTypeObject *tp = Py_TYPE(self); PyObject_GC_UnTrack(self); treebuilder_gc_clear(self); - Py_TYPE(self)->tp_free((PyObject *)self); + tp->tp_free(self); + Py_DECREF(tp); } /* -------------------------------------------------------------------- */ @@ -2509,7 +2525,7 @@ _elementtree__set_factories_impl(PyObject *module, PyObject *comment_factory, PyObject *pi_factory) /*[clinic end generated code: output=813b408adee26535 input=99d17627aea7fb3b]*/ { - elementtreestate *st = ET_STATE_GLOBAL; + elementtreestate *st = get_elementtree_state(module); PyObject *old; if (!PyCallable_Check(comment_factory) && comment_factory != Py_None) { @@ -2530,25 +2546,24 @@ _elementtree__set_factories_impl(PyObject *module, PyObject *comment_factory, if (comment_factory == Py_None) { Py_CLEAR(st->comment_factory); } else { - Py_INCREF(comment_factory); - Py_XSETREF(st->comment_factory, comment_factory); + Py_XSETREF(st->comment_factory, Py_NewRef(comment_factory)); } if (pi_factory == Py_None) { Py_CLEAR(st->pi_factory); } else { - Py_INCREF(pi_factory); - Py_XSETREF(st->pi_factory, pi_factory); + Py_XSETREF(st->pi_factory, Py_NewRef(pi_factory)); } return old; } static int -treebuilder_extend_element_text_or_tail(PyObject *element, PyObject **data, - PyObject **dest, _Py_Identifier *name) +treebuilder_extend_element_text_or_tail(elementtreestate *st, PyObject *element, + PyObject **data, PyObject **dest, + PyObject *name) { /* Fast paths for the "almost always" cases. */ - if (Element_CheckExact(element)) { + if (Element_CheckExact(st, element)) { PyObject *dest_obj = JOIN_OBJ(*dest); if (dest_obj == Py_None) { *dest = JOIN_SET(*data, PyList_CheckExact(*data)); @@ -2569,7 +2584,7 @@ treebuilder_extend_element_text_or_tail(PyObject *element, PyObject **data, { int r; PyObject* joined; - PyObject* previous = _PyObject_GetAttrId(element, name); + PyObject* previous = PyObject_GetAttr(element, name); if (!previous) return -1; joined = list_join(*data); @@ -2588,7 +2603,7 @@ treebuilder_extend_element_text_or_tail(PyObject *element, PyObject **data, Py_DECREF(previous); } - r = _PyObject_SetAttrId(element, name, joined); + r = PyObject_SetAttr(element, name, joined); Py_DECREF(joined); if (r < 0) return -1; @@ -2603,34 +2618,32 @@ treebuilder_flush_data(TreeBuilderObject* self) if (!self->data) { return 0; } - + elementtreestate *st = self->state; if (!self->last_for_tail) { PyObject *element = self->last; - _Py_IDENTIFIER(text); return treebuilder_extend_element_text_or_tail( - element, &self->data, - &((ElementObject *) element)->text, &PyId_text); + st, element, &self->data, + &((ElementObject *) element)->text, st->str_text); } else { PyObject *element = self->last_for_tail; - _Py_IDENTIFIER(tail); return treebuilder_extend_element_text_or_tail( - element, &self->data, - &((ElementObject *) element)->tail, &PyId_tail); + st, element, &self->data, + &((ElementObject *) element)->tail, st->str_tail); } } static int -treebuilder_add_subelement(PyObject *element, PyObject *child) +treebuilder_add_subelement(elementtreestate *st, PyObject *element, + PyObject *child) { - _Py_IDENTIFIER(append); - if (Element_CheckExact(element)) { + if (Element_CheckExact(st, element)) { ElementObject *elem = (ElementObject *) element; - return element_add_subelement(elem, child); + return element_add_subelement(st, elem, child); } else { PyObject *res; - res = _PyObject_CallMethodIdOneArg(element, &PyId_append, child); + res = PyObject_CallMethodOneArg(element, st->str_append, child); if (res == NULL) return -1; Py_DECREF(res); @@ -2665,15 +2678,16 @@ treebuilder_handle_start(TreeBuilderObject* self, PyObject* tag, { PyObject* node; PyObject* this; - elementtreestate *st = ET_STATE_GLOBAL; + elementtreestate *st = self->state; if (treebuilder_flush_data(self) < 0) { return NULL; } if (!self->element_factory) { - node = create_new_element(tag, attrib); - } else if (attrib == NULL) { + node = create_new_element(st, tag, attrib); + } + else if (attrib == NULL) { attrib = PyDict_New(); if (!attrib) return NULL; @@ -2693,8 +2707,9 @@ treebuilder_handle_start(TreeBuilderObject* self, PyObject* tag, Py_CLEAR(self->last_for_tail); if (this != Py_None) { - if (treebuilder_add_subelement(this, node) < 0) + if (treebuilder_add_subelement(st, this, node) < 0) { goto error; + } } else { if (self->root) { PyErr_SetString( @@ -2703,8 +2718,7 @@ treebuilder_handle_start(TreeBuilderObject* self, PyObject* tag, ); goto error; } - Py_INCREF(node); - self->root = node; + self->root = Py_NewRef(node); } if (self->index < PyList_GET_SIZE(self->stack)) { @@ -2717,10 +2731,8 @@ treebuilder_handle_start(TreeBuilderObject* self, PyObject* tag, } self->index++; - Py_INCREF(node); - Py_SETREF(self->this, node); - Py_INCREF(node); - Py_SETREF(self->last, node); + Py_SETREF(self->this, Py_NewRef(node)); + Py_SETREF(self->last, Py_NewRef(node)); if (treebuilder_append_event(self, self->start_event_obj, node) < 0) goto error; @@ -2741,7 +2753,7 @@ treebuilder_handle_data(TreeBuilderObject* self, PyObject* data) Py_RETURN_NONE; } /* store the first item as is */ - Py_INCREF(data); self->data = data; + self->data = Py_NewRef(data); } else { /* more than one item; use a list to collect items */ if (PyBytes_CheckExact(self->data) && Py_REFCNT(self->data) == 1 && @@ -2760,9 +2772,9 @@ treebuilder_handle_data(TreeBuilderObject* self, PyObject* data) PyObject* list = PyList_New(2); if (!list) return NULL; - PyList_SET_ITEM(list, 0, self->data); - Py_INCREF(data); PyList_SET_ITEM(list, 1, data); - self->data = list; + PyList_SET_ITEM(list, 0, Py_NewRef(self->data)); + PyList_SET_ITEM(list, 1, Py_NewRef(data)); + Py_SETREF(self->data, list); } } @@ -2787,19 +2799,16 @@ treebuilder_handle_end(TreeBuilderObject* self, PyObject* tag) } item = self->last; - self->last = self->this; - Py_INCREF(self->last); + self->last = Py_NewRef(self->this); Py_XSETREF(self->last_for_tail, self->last); self->index--; - self->this = PyList_GET_ITEM(self->stack, self->index); - Py_INCREF(self->this); + self->this = Py_NewRef(PyList_GET_ITEM(self->stack, self->index)); Py_DECREF(item); if (treebuilder_append_event(self, self->end_event_obj, self->last) < 0) return NULL; - Py_INCREF(self->last); - return (PyObject*) self->last; + return Py_NewRef(self->last); } LOCAL(PyObject*) @@ -2819,14 +2828,13 @@ treebuilder_handle_comment(TreeBuilderObject* self, PyObject* text) this = self->this; if (self->insert_comments && this != Py_None) { - if (treebuilder_add_subelement(this, comment) < 0) + if (treebuilder_add_subelement(self->state, this, comment) < 0) { goto error; - Py_INCREF(comment); - Py_XSETREF(self->last_for_tail, comment); + } + Py_XSETREF(self->last_for_tail, Py_NewRef(comment)); } } else { - Py_INCREF(text); - comment = text; + comment = Py_NewRef(text); } if (self->events_append && self->comment_event_obj) { @@ -2860,10 +2868,10 @@ treebuilder_handle_pi(TreeBuilderObject* self, PyObject* target, PyObject* text) this = self->this; if (self->insert_pis && this != Py_None) { - if (treebuilder_add_subelement(this, pi) < 0) + if (treebuilder_add_subelement(self->state, this, pi) < 0) { goto error; - Py_INCREF(pi); - Py_XSETREF(self->last_for_tail, pi); + } + Py_XSETREF(self->last_for_tail, Py_NewRef(pi)); } } else { pi = PyTuple_Pack(2, target, text); @@ -2994,8 +3002,7 @@ treebuilder_done(TreeBuilderObject* self) else res = Py_None; - Py_INCREF(res); - return res; + return Py_NewRef(res); } /*[clinic input] @@ -3030,14 +3037,7 @@ _elementtree_TreeBuilder_start_impl(TreeBuilderObject *self, PyObject *tag, /* ==================================================================== */ /* the expat interface */ -#include "expat.h" -#include "pyexpat.h" - -/* The PyExpat_CAPI structure is an immutable dispatch table, so it can be - * cached globally without being in per-module state. - */ -static struct PyExpat_CAPI *expat_capi; -#define EXPAT(func) (expat_capi->func) +#define EXPAT(st, func) ((st)->expat_capi->func) static XML_Memory_Handling_Suite ExpatMemoryHandler = { PyObject_Malloc, PyObject_Realloc, PyObject_Free}; @@ -3064,6 +3064,7 @@ typedef struct { PyObject *handle_close; + elementtreestate *state; } XMLParserObject; /* helpers */ @@ -3083,12 +3084,9 @@ makeuniversal(XMLParserObject* self, const char* string) if (!key) return NULL; - value = PyDict_GetItemWithError(self->names, key); + value = Py_XNewRef(PyDict_GetItemWithError(self->names, key)); - if (value) { - Py_INCREF(value); - } - else if (!PyErr_Occurred()) { + if (value == NULL && !PyErr_Occurred()) { /* new name. convert to universal name, and decode as necessary */ @@ -3113,8 +3111,7 @@ makeuniversal(XMLParserObject* self, const char* string) size++; } else { /* plain name; use key as tag */ - Py_INCREF(key); - tag = key; + tag = Py_NewRef(key); } /* decode universal name */ @@ -3143,14 +3140,13 @@ makeuniversal(XMLParserObject* self, const char* string) * message string is the default for the given error_code. */ static void -expat_set_error(enum XML_Error error_code, Py_ssize_t line, Py_ssize_t column, - const char *message) +expat_set_error(elementtreestate *st, enum XML_Error error_code, + Py_ssize_t line, Py_ssize_t column, const char *message) { PyObject *errmsg, *error, *position, *code; - elementtreestate *st = ET_STATE_GLOBAL; errmsg = PyUnicode_FromFormat("%s: line %zd, column %zd", - message ? message : EXPAT(ErrorString)(error_code), + message ? message : EXPAT(st, ErrorString)(error_code), line, column); if (errmsg == NULL) return; @@ -3212,8 +3208,9 @@ expat_default_handler(XMLParserObject* self, const XML_Char* data_in, value = PyDict_GetItemWithError(self->entity, key); + elementtreestate *st = self->state; if (value) { - if (TreeBuilder_CheckExact(self->target)) + if (TreeBuilder_CheckExact(st, self->target)) res = treebuilder_handle_data( (TreeBuilderObject*) self->target, value ); @@ -3227,9 +3224,10 @@ expat_default_handler(XMLParserObject* self, const XML_Char* data_in, char message[128] = "undefined entity "; strncat(message, data_in, data_len < 100?data_len:100); expat_set_error( + st, XML_ERROR_UNDEFINED_ENTITY, - EXPAT(GetErrorLineNumber)(self->parser), - EXPAT(GetErrorColumnNumber)(self->parser), + EXPAT(st, GetErrorLineNumber)(self->parser), + EXPAT(st, GetErrorColumnNumber)(self->parser), message ); } @@ -3263,10 +3261,14 @@ expat_start_handler(XMLParserObject* self, const XML_Char* tag_in, } while (attrib_in[0] && attrib_in[1]) { PyObject* key = makeuniversal(self, attrib_in[0]); + if (key == NULL) { + Py_DECREF(attrib); + Py_DECREF(tag); + return; + } PyObject* value = PyUnicode_DecodeUTF8(attrib_in[1], strlen(attrib_in[1]), "strict"); - if (!key || !value) { - Py_XDECREF(value); - Py_XDECREF(key); + if (value == NULL) { + Py_DECREF(key); Py_DECREF(attrib); Py_DECREF(tag); return; @@ -3285,7 +3287,8 @@ expat_start_handler(XMLParserObject* self, const XML_Char* tag_in, attrib = NULL; } - if (TreeBuilder_CheckExact(self->target)) { + elementtreestate *st = self->state; + if (TreeBuilder_CheckExact(st, self->target)) { /* shortcut */ res = treebuilder_handle_start((TreeBuilderObject*) self->target, tag, attrib); @@ -3323,7 +3326,8 @@ expat_data_handler(XMLParserObject* self, const XML_Char* data_in, if (!data) return; /* parser will look for errors */ - if (TreeBuilder_CheckExact(self->target)) + elementtreestate *st = self->state; + if (TreeBuilder_CheckExact(st, self->target)) /* shortcut */ res = treebuilder_handle_data((TreeBuilderObject*) self->target, data); else if (self->handle_data) @@ -3345,7 +3349,8 @@ expat_end_handler(XMLParserObject* self, const XML_Char* tag_in) if (PyErr_Occurred()) return; - if (TreeBuilder_CheckExact(self->target)) + elementtreestate *st = self->state; + if (TreeBuilder_CheckExact(st, self->target)) /* shortcut */ /* the standard tree builder doesn't look at the end tag */ res = treebuilder_handle_end( @@ -3379,7 +3384,8 @@ expat_start_ns_handler(XMLParserObject* self, const XML_Char* prefix_in, if (!prefix_in) prefix_in = ""; - if (TreeBuilder_CheckExact(self->target)) { + elementtreestate *st = self->state; + if (TreeBuilder_CheckExact(st, self->target)) { /* shortcut - TreeBuilder does not actually implement .start_ns() */ TreeBuilderObject *target = (TreeBuilderObject*) self->target; @@ -3429,7 +3435,8 @@ expat_end_ns_handler(XMLParserObject* self, const XML_Char* prefix_in) if (!prefix_in) prefix_in = ""; - if (TreeBuilder_CheckExact(self->target)) { + elementtreestate *st = self->state; + if (TreeBuilder_CheckExact(st, self->target)) { /* shortcut - TreeBuilder does not actually implement .end_ns() */ TreeBuilderObject *target = (TreeBuilderObject*) self->target; @@ -3457,7 +3464,8 @@ expat_comment_handler(XMLParserObject* self, const XML_Char* comment_in) if (PyErr_Occurred()) return; - if (TreeBuilder_CheckExact(self->target)) { + elementtreestate *st = self->state; + if (TreeBuilder_CheckExact(st, self->target)) { /* shortcut */ TreeBuilderObject *target = (TreeBuilderObject*) self->target; @@ -3486,7 +3494,6 @@ expat_start_doctype_handler(XMLParserObject *self, const XML_Char *pubid, int has_internal_subset) { - _Py_IDENTIFIER(doctype); PyObject *doctype_name_obj, *sysid_obj, *pubid_obj; PyObject *res; @@ -3504,8 +3511,7 @@ expat_start_doctype_handler(XMLParserObject *self, return; } } else { - Py_INCREF(Py_None); - sysid_obj = Py_None; + sysid_obj = Py_NewRef(Py_None); } if (pubid) { @@ -3516,10 +3522,10 @@ expat_start_doctype_handler(XMLParserObject *self, return; } } else { - Py_INCREF(Py_None); - pubid_obj = Py_None; + pubid_obj = Py_NewRef(Py_None); } + elementtreestate *st = self->state; /* If the target has a handler for doctype, call it. */ if (self->handle_doctype) { res = PyObject_CallFunctionObjArgs(self->handle_doctype, @@ -3527,7 +3533,7 @@ expat_start_doctype_handler(XMLParserObject *self, sysid_obj, NULL); Py_XDECREF(res); } - else if (_PyObject_LookupAttrId((PyObject *)self, &PyId_doctype, &res) > 0) { + else if (_PyObject_LookupAttr((PyObject *)self, st->str_doctype, &res) > 0) { (void)PyErr_WarnEx(PyExc_RuntimeWarning, "The doctype() method of XMLParser is ignored. " "Define doctype() method on the TreeBuilder target.", @@ -3552,7 +3558,8 @@ expat_pi_handler(XMLParserObject* self, const XML_Char* target_in, if (PyErr_Occurred()) return; - if (TreeBuilder_CheckExact(self->target)) { + elementtreestate *st = self->state; + if (TreeBuilder_CheckExact(st, self->target)) { /* shortcut */ TreeBuilderObject *target = (TreeBuilderObject*) self->target; @@ -3604,6 +3611,7 @@ xmlparser_new(PyTypeObject *type, PyObject *args, PyObject *kwds) self->handle_start = self->handle_data = self->handle_end = NULL; self->handle_comment = self->handle_pi = self->handle_close = NULL; self->handle_doctype = NULL; + self->state = get_elementtree_state_by_type(type); } return (PyObject *)self; } @@ -3643,8 +3651,8 @@ _elementtree_XMLParser___init___impl(XMLParserObject *self, PyObject *target, Py_CLEAR(self->entity); return -1; } - - self->parser = EXPAT(ParserCreate_MM)(encoding, &ExpatMemoryHandler, "}"); + elementtreestate *st = self->state; + self->parser = EXPAT(st, ParserCreate_MM)(encoding, &ExpatMemoryHandler, "}"); if (!self->parser) { Py_CLEAR(self->entity); Py_CLEAR(self->names); @@ -3652,15 +3660,15 @@ _elementtree_XMLParser___init___impl(XMLParserObject *self, PyObject *target, return -1; } /* expat < 2.1.0 has no XML_SetHashSalt() */ - if (EXPAT(SetHashSalt) != NULL) { - EXPAT(SetHashSalt)(self->parser, + if (EXPAT(st, SetHashSalt) != NULL) { + EXPAT(st, SetHashSalt)(self->parser, (unsigned long)_Py_HashSecret.expat.hashsalt); } if (target != Py_None) { Py_INCREF(target); } else { - target = treebuilder_new(&TreeBuilder_Type, NULL, NULL); + target = treebuilder_new(st->TreeBuilder_Type, NULL, NULL); if (!target) { Py_CLEAR(self->entity); Py_CLEAR(self->names); @@ -3707,43 +3715,43 @@ _elementtree_XMLParser___init___impl(XMLParserObject *self, PyObject *target, } /* configure parser */ - EXPAT(SetUserData)(self->parser, self); + EXPAT(st, SetUserData)(self->parser, self); if (self->handle_start_ns || self->handle_end_ns) - EXPAT(SetNamespaceDeclHandler)( + EXPAT(st, SetNamespaceDeclHandler)( self->parser, (XML_StartNamespaceDeclHandler) expat_start_ns_handler, (XML_EndNamespaceDeclHandler) expat_end_ns_handler ); - EXPAT(SetElementHandler)( + EXPAT(st, SetElementHandler)( self->parser, (XML_StartElementHandler) expat_start_handler, (XML_EndElementHandler) expat_end_handler ); - EXPAT(SetDefaultHandlerExpand)( + EXPAT(st, SetDefaultHandlerExpand)( self->parser, (XML_DefaultHandler) expat_default_handler ); - EXPAT(SetCharacterDataHandler)( + EXPAT(st, SetCharacterDataHandler)( self->parser, (XML_CharacterDataHandler) expat_data_handler ); if (self->handle_comment) - EXPAT(SetCommentHandler)( + EXPAT(st, SetCommentHandler)( self->parser, (XML_CommentHandler) expat_comment_handler ); if (self->handle_pi) - EXPAT(SetProcessingInstructionHandler)( + EXPAT(st, SetProcessingInstructionHandler)( self->parser, (XML_ProcessingInstructionHandler) expat_pi_handler ); - EXPAT(SetStartDoctypeDeclHandler)( + EXPAT(st, SetStartDoctypeDeclHandler)( self->parser, (XML_StartDoctypeDeclHandler) expat_start_doctype_handler ); - EXPAT(SetUnknownEncodingHandler)( + EXPAT(st, SetUnknownEncodingHandler)( self->parser, - EXPAT(DefaultUnknownEncodingHandler), NULL + EXPAT(st, DefaultUnknownEncodingHandler), NULL ); return 0; @@ -3752,6 +3760,7 @@ _elementtree_XMLParser___init___impl(XMLParserObject *self, PyObject *target, static int xmlparser_gc_traverse(XMLParserObject *self, visitproc visit, void *arg) { + Py_VISIT(Py_TYPE(self)); Py_VISIT(self->handle_close); Py_VISIT(self->handle_pi); Py_VISIT(self->handle_comment); @@ -3772,10 +3781,11 @@ xmlparser_gc_traverse(XMLParserObject *self, visitproc visit, void *arg) static int xmlparser_gc_clear(XMLParserObject *self) { + elementtreestate *st = self->state; if (self->parser != NULL) { XML_Parser parser = self->parser; self->parser = NULL; - EXPAT(ParserFree)(parser); + EXPAT(st, ParserFree)(parser); } Py_CLEAR(self->handle_close); @@ -3798,9 +3808,11 @@ xmlparser_gc_clear(XMLParserObject *self) static void xmlparser_dealloc(XMLParserObject* self) { + PyTypeObject *tp = Py_TYPE(self); PyObject_GC_UnTrack(self); xmlparser_gc_clear(self); - Py_TYPE(self)->tp_free((PyObject *)self); + tp->tp_free(self); + Py_DECREF(tp); } Py_LOCAL_INLINE(int) @@ -3815,21 +3827,23 @@ _check_xmlparser(XMLParserObject* self) } LOCAL(PyObject*) -expat_parse(XMLParserObject* self, const char* data, int data_len, int final) +expat_parse(elementtreestate *st, XMLParserObject *self, const char *data, + int data_len, int final) { int ok; assert(!PyErr_Occurred()); - ok = EXPAT(Parse)(self->parser, data, data_len, final); + ok = EXPAT(st, Parse)(self->parser, data, data_len, final); if (PyErr_Occurred()) return NULL; if (!ok) { expat_set_error( - EXPAT(GetErrorCode)(self->parser), - EXPAT(GetErrorLineNumber)(self->parser), - EXPAT(GetErrorColumnNumber)(self->parser), + st, + EXPAT(st, GetErrorCode)(self->parser), + EXPAT(st, GetErrorLineNumber)(self->parser), + EXPAT(st, GetErrorColumnNumber)(self->parser), NULL ); return NULL; @@ -3854,11 +3868,12 @@ _elementtree_XMLParser_close_impl(XMLParserObject *self) if (!_check_xmlparser(self)) { return NULL; } - res = expat_parse(self, "", 0, 1); + elementtreestate *st = self->state; + res = expat_parse(st, self, "", 0, 1); if (!res) return NULL; - if (TreeBuilder_CheckExact(self->target)) { + if (TreeBuilder_CheckExact(st, self->target)) { Py_DECREF(res); return treebuilder_done((TreeBuilderObject*) self->target); } @@ -3888,6 +3903,7 @@ _elementtree_XMLParser_feed(XMLParserObject *self, PyObject *data) if (!_check_xmlparser(self)) { return NULL; } + elementtreestate *st = self->state; if (PyUnicode_Check(data)) { Py_ssize_t data_len; const char *data_ptr = PyUnicode_AsUTF8AndSize(data, &data_len); @@ -3898,8 +3914,9 @@ _elementtree_XMLParser_feed(XMLParserObject *self, PyObject *data) return NULL; } /* Explicitly set UTF-8 encoding. Return code ignored. */ - (void)EXPAT(SetEncoding)(self->parser, "utf-8"); - return expat_parse(self, data_ptr, (int)data_len, 0); + (void)EXPAT(st, SetEncoding)(self->parser, "utf-8"); + + return expat_parse(st, self, data_ptr, (int)data_len, 0); } else { Py_buffer view; @@ -3911,7 +3928,7 @@ _elementtree_XMLParser_feed(XMLParserObject *self, PyObject *data) PyErr_SetString(PyExc_OverflowError, "size does not fit in an int"); return NULL; } - res = expat_parse(self, view.buf, (int)view.len, 0); + res = expat_parse(st, self, view.buf, (int)view.len, 0); PyBuffer_Release(&view); return res; } @@ -3943,6 +3960,7 @@ _elementtree_XMLParser__parse_whole(XMLParserObject *self, PyObject *file) return NULL; /* read from open file object */ + elementtreestate *st = self->state; for (;;) { buffer = PyObject_CallFunction(reader, "i", 64*1024); @@ -3980,8 +3998,8 @@ _elementtree_XMLParser__parse_whole(XMLParserObject *self, PyObject *file) return NULL; } res = expat_parse( - self, PyBytes_AS_STRING(buffer), (int)PyBytes_GET_SIZE(buffer), 0 - ); + st, self, PyBytes_AS_STRING(buffer), (int)PyBytes_GET_SIZE(buffer), + 0); Py_DECREF(buffer); @@ -3995,9 +4013,9 @@ _elementtree_XMLParser__parse_whole(XMLParserObject *self, PyObject *file) Py_DECREF(reader); - res = expat_parse(self, "", 0, 1); + res = expat_parse(st, self, "", 0, 1); - if (res && TreeBuilder_CheckExact(self->target)) { + if (res && TreeBuilder_CheckExact(st, self->target)) { Py_DECREF(res); return treebuilder_done((TreeBuilderObject*) self->target); } @@ -4028,7 +4046,8 @@ _elementtree_XMLParser__setevents_impl(XMLParserObject *self, if (!_check_xmlparser(self)) { return NULL; } - if (!TreeBuilder_CheckExact(self->target)) { + elementtreestate *st = self->state; + if (!TreeBuilder_CheckExact(st, self->target)) { PyErr_SetString( PyExc_TypeError, "event handling only supported for ElementTree.TreeBuilder " @@ -4077,39 +4096,37 @@ _elementtree_XMLParser__setevents_impl(XMLParserObject *self, return NULL; } - Py_INCREF(event_name_obj); if (strcmp(event_name, "start") == 0) { - Py_XSETREF(target->start_event_obj, event_name_obj); + Py_XSETREF(target->start_event_obj, Py_NewRef(event_name_obj)); } else if (strcmp(event_name, "end") == 0) { - Py_XSETREF(target->end_event_obj, event_name_obj); + Py_XSETREF(target->end_event_obj, Py_NewRef(event_name_obj)); } else if (strcmp(event_name, "start-ns") == 0) { - Py_XSETREF(target->start_ns_event_obj, event_name_obj); - EXPAT(SetNamespaceDeclHandler)( + Py_XSETREF(target->start_ns_event_obj, Py_NewRef(event_name_obj)); + EXPAT(st, SetNamespaceDeclHandler)( self->parser, (XML_StartNamespaceDeclHandler) expat_start_ns_handler, (XML_EndNamespaceDeclHandler) expat_end_ns_handler ); } else if (strcmp(event_name, "end-ns") == 0) { - Py_XSETREF(target->end_ns_event_obj, event_name_obj); - EXPAT(SetNamespaceDeclHandler)( + Py_XSETREF(target->end_ns_event_obj, Py_NewRef(event_name_obj)); + EXPAT(st, SetNamespaceDeclHandler)( self->parser, (XML_StartNamespaceDeclHandler) expat_start_ns_handler, (XML_EndNamespaceDeclHandler) expat_end_ns_handler ); } else if (strcmp(event_name, "comment") == 0) { - Py_XSETREF(target->comment_event_obj, event_name_obj); - EXPAT(SetCommentHandler)( + Py_XSETREF(target->comment_event_obj, Py_NewRef(event_name_obj)); + EXPAT(st, SetCommentHandler)( self->parser, (XML_CommentHandler) expat_comment_handler ); } else if (strcmp(event_name, "pi") == 0) { - Py_XSETREF(target->pi_event_obj, event_name_obj); - EXPAT(SetProcessingInstructionHandler)( + Py_XSETREF(target->pi_event_obj, Py_NewRef(event_name_obj)); + EXPAT(st, SetProcessingInstructionHandler)( self->parser, (XML_ProcessingInstructionHandler) expat_pi_handler ); } else { - Py_DECREF(event_name_obj); Py_DECREF(events_seq); PyErr_Format(PyExc_ValueError, "unknown event '%s'", event_name); return NULL; @@ -4139,7 +4156,9 @@ static PyGetSetDef xmlparser_getsetlist[] = { {NULL}, }; +#define clinic_state() (get_elementtree_state_by_type(Py_TYPE(self))) #include "clinic/_elementtree.c.h" +#undef clinic_state static PyMethodDef element_methods[] = { @@ -4175,10 +4194,9 @@ static PyMethodDef element_methods[] = { {NULL, NULL} }; -static PyMappingMethods element_as_mapping = { - (lenfunc) element_length, - (binaryfunc) element_subscr, - (objobjargproc) element_ass_subscr, +static struct PyMemberDef element_members[] = { + {"__weaklistoffset__", T_PYSSIZET, offsetof(ElementObject, weakreflist), READONLY}, + {NULL}, }; static PyGetSetDef element_getsetlist[] = { @@ -4201,46 +4219,34 @@ static PyGetSetDef element_getsetlist[] = { {NULL}, }; -static PyTypeObject Element_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "xml.etree.ElementTree.Element", sizeof(ElementObject), 0, - /* methods */ - (destructor)element_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - (reprfunc)element_repr, /* tp_repr */ - 0, /* tp_as_number */ - &element_as_sequence, /* tp_as_sequence */ - &element_as_mapping, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, - /* tp_flags */ - 0, /* tp_doc */ - (traverseproc)element_gc_traverse, /* tp_traverse */ - (inquiry)element_gc_clear, /* tp_clear */ - 0, /* tp_richcompare */ - offsetof(ElementObject, weakreflist), /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - element_methods, /* tp_methods */ - 0, /* tp_members */ - element_getsetlist, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc)element_init, /* tp_init */ - PyType_GenericAlloc, /* tp_alloc */ - element_new, /* tp_new */ - 0, /* tp_free */ +static PyType_Slot element_slots[] = { + {Py_tp_dealloc, element_dealloc}, + {Py_tp_repr, element_repr}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_traverse, element_gc_traverse}, + {Py_tp_clear, element_gc_clear}, + {Py_tp_methods, element_methods}, + {Py_tp_members, element_members}, + {Py_tp_getset, element_getsetlist}, + {Py_tp_init, element_init}, + {Py_tp_alloc, PyType_GenericAlloc}, + {Py_tp_new, element_new}, + {Py_sq_length, element_length}, + {Py_sq_item, element_getitem}, + {Py_sq_ass_item, element_setitem}, + {Py_nb_bool, element_bool}, + {Py_mp_length, element_length}, + {Py_mp_subscript, element_subscr}, + {Py_mp_ass_subscript, element_ass_subscr}, + {0, NULL}, +}; + +static PyType_Spec element_spec = { + .name = "xml.etree.ElementTree.Element", + .basicsize = sizeof(ElementObject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = element_slots, }; static PyMethodDef treebuilder_methods[] = { @@ -4253,46 +4259,22 @@ static PyMethodDef treebuilder_methods[] = { {NULL, NULL} }; -static PyTypeObject TreeBuilder_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "xml.etree.ElementTree.TreeBuilder", sizeof(TreeBuilderObject), 0, - /* methods */ - (destructor)treebuilder_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 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 | Py_TPFLAGS_HAVE_GC, - /* tp_flags */ - 0, /* tp_doc */ - (traverseproc)treebuilder_gc_traverse, /* tp_traverse */ - (inquiry)treebuilder_gc_clear, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - treebuilder_methods, /* 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 */ - _elementtree_TreeBuilder___init__, /* tp_init */ - PyType_GenericAlloc, /* tp_alloc */ - treebuilder_new, /* tp_new */ - 0, /* tp_free */ +static PyType_Slot treebuilder_slots[] = { + {Py_tp_dealloc, treebuilder_dealloc}, + {Py_tp_traverse, treebuilder_gc_traverse}, + {Py_tp_clear, treebuilder_gc_clear}, + {Py_tp_methods, treebuilder_methods}, + {Py_tp_init, _elementtree_TreeBuilder___init__}, + {Py_tp_alloc, PyType_GenericAlloc}, + {Py_tp_new, treebuilder_new}, + {0, NULL}, +}; + +static PyType_Spec treebuilder_spec = { + .name = "xml.etree.ElementTree.TreeBuilder", + .basicsize = sizeof(TreeBuilderObject), + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE, + .slots = treebuilder_slots, }; static PyMethodDef xmlparser_methods[] = { @@ -4303,46 +4285,25 @@ static PyMethodDef xmlparser_methods[] = { {NULL, NULL} }; -static PyTypeObject XMLParser_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "xml.etree.ElementTree.XMLParser", sizeof(XMLParserObject), 0, - /* methods */ - (destructor)xmlparser_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 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 | Py_TPFLAGS_HAVE_GC, - /* tp_flags */ - 0, /* tp_doc */ - (traverseproc)xmlparser_gc_traverse, /* tp_traverse */ - (inquiry)xmlparser_gc_clear, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - xmlparser_methods, /* tp_methods */ - xmlparser_members, /* tp_members */ - xmlparser_getsetlist, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - _elementtree_XMLParser___init__, /* tp_init */ - PyType_GenericAlloc, /* tp_alloc */ - xmlparser_new, /* tp_new */ - 0, /* tp_free */ +static PyType_Slot xmlparser_slots[] = { + {Py_tp_dealloc, xmlparser_dealloc}, + {Py_tp_traverse, xmlparser_gc_traverse}, + {Py_tp_clear, xmlparser_gc_clear}, + {Py_tp_methods, xmlparser_methods}, + {Py_tp_members, xmlparser_members}, + {Py_tp_getset, xmlparser_getsetlist}, + {Py_tp_init, _elementtree_XMLParser___init__}, + {Py_tp_alloc, PyType_GenericAlloc}, + {Py_tp_new, xmlparser_new}, + {0, NULL}, +}; + +static PyType_Spec xmlparser_spec = { + .name = "xml.etree.ElementTree.XMLParser", + .basicsize = sizeof(XMLParserObject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = xmlparser_slots, }; /* ==================================================================== */ @@ -4354,96 +4315,132 @@ static PyMethodDef _functions[] = { {NULL, NULL} }; +#define CREATE_TYPE(module, type, spec) \ +do { \ + if (type != NULL) { \ + break; \ + } \ + type = (PyTypeObject *)PyType_FromModuleAndSpec(module, spec, NULL); \ + if (type == NULL) { \ + goto error; \ + } \ +} while (0) -static struct PyModuleDef elementtreemodule = { - PyModuleDef_HEAD_INIT, - "_elementtree", - NULL, - sizeof(elementtreestate), - _functions, - NULL, - elementtree_traverse, - elementtree_clear, - elementtree_free -}; - -PyMODINIT_FUNC -PyInit__elementtree(void) +static int +module_exec(PyObject *m) { - PyObject *m, *temp; - elementtreestate *st; - - m = PyState_FindModule(&elementtreemodule); - if (m) { - Py_INCREF(m); - return m; - } + elementtreestate *st = get_elementtree_state(m); /* Initialize object types */ - if (PyType_Ready(&ElementIter_Type) < 0) - return NULL; - if (PyType_Ready(&TreeBuilder_Type) < 0) - return NULL; - if (PyType_Ready(&Element_Type) < 0) - return NULL; - if (PyType_Ready(&XMLParser_Type) < 0) - return NULL; - - m = PyModule_Create(&elementtreemodule); - if (!m) - return NULL; - st = get_elementtree_state(m); - - if (!(temp = PyImport_ImportModule("copy"))) - return NULL; - st->deepcopy_obj = PyObject_GetAttrString(temp, "deepcopy"); - Py_XDECREF(temp); + CREATE_TYPE(m, st->ElementIter_Type, &elementiter_spec); + CREATE_TYPE(m, st->TreeBuilder_Type, &treebuilder_spec); + CREATE_TYPE(m, st->Element_Type, &element_spec); + CREATE_TYPE(m, st->XMLParser_Type, &xmlparser_spec); + st->deepcopy_obj = _PyImport_GetModuleAttrString("copy", "deepcopy"); if (st->deepcopy_obj == NULL) { - return NULL; + goto error; } assert(!PyErr_Occurred()); if (!(st->elementpath_obj = PyImport_ImportModule("xml.etree.ElementPath"))) - return NULL; + goto error; /* link against pyexpat */ - expat_capi = PyCapsule_Import(PyExpat_CAPSULE_NAME, 0); - if (expat_capi) { + st->expat_capi = PyCapsule_Import(PyExpat_CAPSULE_NAME, 0); + if (st->expat_capi) { /* check that it's usable */ - if (strcmp(expat_capi->magic, PyExpat_CAPI_MAGIC) != 0 || - (size_t)expat_capi->size < sizeof(struct PyExpat_CAPI) || - expat_capi->MAJOR_VERSION != XML_MAJOR_VERSION || - expat_capi->MINOR_VERSION != XML_MINOR_VERSION || - expat_capi->MICRO_VERSION != XML_MICRO_VERSION) { + if (strcmp(st->expat_capi->magic, PyExpat_CAPI_MAGIC) != 0 || + (size_t)st->expat_capi->size < sizeof(struct PyExpat_CAPI) || + st->expat_capi->MAJOR_VERSION != XML_MAJOR_VERSION || + st->expat_capi->MINOR_VERSION != XML_MINOR_VERSION || + st->expat_capi->MICRO_VERSION != XML_MICRO_VERSION) { PyErr_SetString(PyExc_ImportError, "pyexpat version is incompatible"); - return NULL; + goto error; } } else { - return NULL; + goto error; } + st->str_append = PyUnicode_InternFromString("append"); + if (st->str_append == NULL) { + goto error; + } + st->str_find = PyUnicode_InternFromString("find"); + if (st->str_find == NULL) { + goto error; + } + st->str_findall = PyUnicode_InternFromString("findall"); + if (st->str_findall == NULL) { + goto error; + } + st->str_findtext = PyUnicode_InternFromString("findtext"); + if (st->str_findtext == NULL) { + goto error; + } + st->str_iterfind = PyUnicode_InternFromString("iterfind"); + if (st->str_iterfind == NULL) { + goto error; + } + st->str_tail = PyUnicode_InternFromString("tail"); + if (st->str_tail == NULL) { + goto error; + } + st->str_text = PyUnicode_InternFromString("text"); + if (st->str_text == NULL) { + goto error; + } + st->str_doctype = PyUnicode_InternFromString("doctype"); + if (st->str_doctype == NULL) { + goto error; + } st->parseerror_obj = PyErr_NewException( "xml.etree.ElementTree.ParseError", PyExc_SyntaxError, NULL ); - Py_INCREF(st->parseerror_obj); - if (PyModule_AddObject(m, "ParseError", st->parseerror_obj) < 0) { - Py_DECREF(st->parseerror_obj); - return NULL; + if (PyModule_AddObjectRef(m, "ParseError", st->parseerror_obj) < 0) { + goto error; } PyTypeObject *types[] = { - &Element_Type, - &TreeBuilder_Type, - &XMLParser_Type + st->Element_Type, + st->TreeBuilder_Type, + st->XMLParser_Type }; for (size_t i = 0; i < Py_ARRAY_LENGTH(types); i++) { if (PyModule_AddType(m, types[i]) < 0) { - return NULL; + goto error; } } - return m; + return 0; + +error: + return -1; +} + +static struct PyModuleDef_Slot elementtree_slots[] = { + {Py_mod_exec, module_exec}, + // XXX gh-103092: fix isolation. + {Py_mod_multiple_interpreters, Py_MOD_MULTIPLE_INTERPRETERS_NOT_SUPPORTED}, + //{Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, + {0, NULL}, +}; + +static struct PyModuleDef elementtreemodule = { + .m_base = PyModuleDef_HEAD_INIT, + .m_name = "_elementtree", + .m_size = sizeof(elementtreestate), + .m_methods = _functions, + .m_slots = elementtree_slots, + .m_traverse = elementtree_traverse, + .m_clear = elementtree_clear, + .m_free = elementtree_free, +}; + +PyMODINIT_FUNC +PyInit__elementtree(void) +{ + return PyModuleDef_Init(&elementtreemodule); } diff --git a/Modules/_functoolsmodule.c b/Modules/_functoolsmodule.c index 3abb7fd7..a8001d71 100644 --- a/Modules/_functoolsmodule.c +++ b/Modules/_functoolsmodule.c @@ -1,5 +1,6 @@ #include "Python.h" #include "pycore_call.h" // _PyObject_CallNoArgs() +#include "pycore_dict.h" // _PyDict_Pop_KnownHash() #include "pycore_long.h" // _PyLong_GetZero() #include "pycore_moduleobject.h" // _PyModule_GetState() #include "pycore_object.h" // _PyObject_GC_TRACK @@ -7,6 +8,13 @@ #include "pycore_tuple.h" // _PyTuple_ITEMS() #include "structmember.h" // PyMemberDef +#include "clinic/_functoolsmodule.c.h" +/*[clinic input] +module _functools +class _functools._lru_cache_wrapper "PyObject *" "&lru_cache_type_spec" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=bece4053896b09c0]*/ + /* _functools module written and maintained by Hye-Shik Chang <perky@FreeBSD.org> with adaptations by Raymond Hettinger <python@rcn.com> @@ -58,6 +66,7 @@ get_functools_state_by_type(PyTypeObject *type) return get_functools_state(module); } +// Not converted to argument clinic, because of `*args, **kwargs` arguments. static PyObject * partial_new(PyTypeObject *type, PyObject *args, PyObject *kw) { @@ -97,8 +106,7 @@ partial_new(PyTypeObject *type, PyObject *args, PyObject *kw) if (pto == NULL) return NULL; - pto->fn = func; - Py_INCREF(func); + pto->fn = Py_NewRef(func); nargs = PyTuple_GetSlice(args, 1, PY_SSIZE_T_MAX); if (nargs == NULL) { @@ -123,8 +131,7 @@ partial_new(PyTypeObject *type, PyObject *args, PyObject *kw) pto->kw = PyDict_New(); } else if (Py_REFCNT(kw) == 1) { - Py_INCREF(kw); - pto->kw = kw; + pto->kw = Py_NewRef(kw); } else { pto->kw = PyDict_Copy(kw); @@ -282,6 +289,7 @@ partial_setvectorcall(partialobject *pto) } +// Not converted to argument clinic, because of `*args, **kwargs` arguments. static PyObject * partial_call(partialobject *pto, PyObject *args, PyObject *kwargs) { @@ -293,8 +301,7 @@ partial_call(partialobject *pto, PyObject *args, PyObject *kwargs) PyObject *kwargs2; if (PyDict_GET_SIZE(pto->kw) == 0) { /* kwargs can be NULL */ - kwargs2 = kwargs; - Py_XINCREF(kwargs2); + kwargs2 = Py_XNewRef(kwargs); } else { /* bpo-27840, bpo-29318: dictionary of keyword parameters must be @@ -454,8 +461,7 @@ partial_setstate(partialobject *pto, PyObject *state) else Py_INCREF(dict); - Py_INCREF(fn); - Py_SETREF(pto->fn, fn); + Py_SETREF(pto->fn, Py_NewRef(fn)); Py_SETREF(pto->args, fnargs); Py_SETREF(pto->kw, kw); Py_XSETREF(pto->dict, dict); @@ -579,10 +585,8 @@ keyobject_call(keyobject *ko, PyObject *args, PyObject *kwds) if (result == NULL) { return NULL; } - Py_INCREF(ko->cmp); - result->cmp = ko->cmp; - Py_INCREF(object); - result->object = object; + result->cmp = Py_NewRef(ko->cmp); + result->object = Py_NewRef(object); PyObject_GC_Track(result); return (PyObject *)result; } @@ -625,33 +629,36 @@ keyobject_richcompare(PyObject *ko, PyObject *other, int op) return answer; } +/*[clinic input] +_functools.cmp_to_key + + mycmp: object + Function that compares two objects. + +Convert a cmp= function into a key= function. +[clinic start generated code]*/ + static PyObject * -functools_cmp_to_key(PyObject *self, PyObject *args, PyObject *kwds) +_functools_cmp_to_key_impl(PyObject *module, PyObject *mycmp) +/*[clinic end generated code: output=71eaad0f4fc81f33 input=d1b76f231c0dfeb3]*/ { - PyObject *cmp; - static char *kwargs[] = {"mycmp", NULL}; keyobject *object; _functools_state *state; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:cmp_to_key", kwargs, &cmp)) - return NULL; - - state = get_functools_state(self); + state = get_functools_state(module); object = PyObject_GC_New(keyobject, state->keyobject_type); if (!object) return NULL; - Py_INCREF(cmp); - object->cmp = cmp; + object->cmp = Py_NewRef(mycmp); object->object = NULL; PyObject_GC_Track(object); return (PyObject *)object; } -PyDoc_STRVAR(functools_cmp_to_key_doc, -"Convert a cmp= function into a key= function."); - /* reduce (used to be a builtin) ********************************************/ +// Not converted to argument clinic, because of `args` in-place modification. +// AC will affect performance. static PyObject * functools_reduce(PyObject *self, PyObject *args) { @@ -824,12 +831,10 @@ lru_cache_make_key(PyObject *kwd_mark, PyObject *args, if (PyUnicode_CheckExact(key) || PyLong_CheckExact(key)) { /* For common scalar keys, save space by dropping the enclosing args tuple */ - Py_INCREF(key); - return key; + return Py_NewRef(key); } } - Py_INCREF(args); - return args; + return Py_NewRef(args); } key_size = PyTuple_GET_SIZE(args); @@ -845,31 +850,25 @@ lru_cache_make_key(PyObject *kwd_mark, PyObject *args, key_pos = 0; for (pos = 0; pos < PyTuple_GET_SIZE(args); ++pos) { PyObject *item = PyTuple_GET_ITEM(args, pos); - Py_INCREF(item); - PyTuple_SET_ITEM(key, key_pos++, item); + PyTuple_SET_ITEM(key, key_pos++, Py_NewRef(item)); } if (kwds_size) { - Py_INCREF(kwd_mark); - PyTuple_SET_ITEM(key, key_pos++, kwd_mark); + PyTuple_SET_ITEM(key, key_pos++, Py_NewRef(kwd_mark)); for (pos = 0; PyDict_Next(kwds, &pos, &keyword, &value);) { - Py_INCREF(keyword); - PyTuple_SET_ITEM(key, key_pos++, keyword); - Py_INCREF(value); - PyTuple_SET_ITEM(key, key_pos++, value); + PyTuple_SET_ITEM(key, key_pos++, Py_NewRef(keyword)); + PyTuple_SET_ITEM(key, key_pos++, Py_NewRef(value)); } assert(key_pos == PyTuple_GET_SIZE(args) + kwds_size * 2 + 1); } if (typed) { for (pos = 0; pos < PyTuple_GET_SIZE(args); ++pos) { PyObject *item = (PyObject *)Py_TYPE(PyTuple_GET_ITEM(args, pos)); - Py_INCREF(item); - PyTuple_SET_ITEM(key, key_pos++, item); + PyTuple_SET_ITEM(key, key_pos++, Py_NewRef(item)); } if (kwds_size) { for (pos = 0; PyDict_Next(kwds, &pos, &keyword, &value);) { PyObject *item = (PyObject *)Py_TYPE(value); - Py_INCREF(item); - PyTuple_SET_ITEM(key, key_pos++, item); + PyTuple_SET_ITEM(key, key_pos++, Py_NewRef(item)); } } } @@ -1071,8 +1070,7 @@ bounded_lru_cache_wrapper(lru_cache_object *self, PyObject *args, PyObject *kwds return NULL; } lru_cache_append_link(self, link); - Py_INCREF(result); /* for return */ - return result; + return Py_NewRef(result); } /* Since the cache is full, we need to evict an old key and add a new key. Rather than free the old link and allocate a new @@ -1217,16 +1215,12 @@ lru_cache_new(PyTypeObject *type, PyObject *args, PyObject *kw) obj->wrapper = wrapper; obj->typed = typed; obj->cache = cachedict; - Py_INCREF(func); - obj->func = func; + obj->func = Py_NewRef(func); obj->misses = obj->hits = 0; obj->maxsize = maxsize; - Py_INCREF(state->kwd_mark); - obj->kwd_mark = state->kwd_mark; - Py_INCREF(state->lru_list_elem_type); - obj->lru_list_elem_type = state->lru_list_elem_type; - Py_INCREF(cache_info_type); - obj->cache_info_type = cache_info_type; + obj->kwd_mark = Py_NewRef(state->kwd_mark); + obj->lru_list_elem_type = (PyTypeObject*)Py_NewRef(state->lru_list_elem_type); + obj->cache_info_type = Py_NewRef(cache_info_type); obj->dict = NULL; obj->weakreflist = NULL; return (PyObject *)obj; @@ -1249,8 +1243,7 @@ lru_cache_clear_list(lru_list_elem *link) { while (link != NULL) { lru_list_elem *next = link->next; - Py_DECREF(link); - link = next; + Py_SETREF(link, next); } } @@ -1293,31 +1286,46 @@ static PyObject * lru_cache_descr_get(PyObject *self, PyObject *obj, PyObject *type) { if (obj == Py_None || obj == NULL) { - Py_INCREF(self); - return self; + return Py_NewRef(self); } return PyMethod_New(self, obj); } +/*[clinic input] +_functools._lru_cache_wrapper.cache_info + +Report cache statistics +[clinic start generated code]*/ + static PyObject * -lru_cache_cache_info(lru_cache_object *self, PyObject *unused) +_functools__lru_cache_wrapper_cache_info_impl(PyObject *self) +/*[clinic end generated code: output=cc796a0b06dbd717 input=f05e5b6ebfe38645]*/ { - if (self->maxsize == -1) { - return PyObject_CallFunction(self->cache_info_type, "nnOn", - self->hits, self->misses, Py_None, - PyDict_GET_SIZE(self->cache)); - } - return PyObject_CallFunction(self->cache_info_type, "nnnn", - self->hits, self->misses, self->maxsize, - PyDict_GET_SIZE(self->cache)); + lru_cache_object *_self = (lru_cache_object *) self; + if (_self->maxsize == -1) { + return PyObject_CallFunction(_self->cache_info_type, "nnOn", + _self->hits, _self->misses, Py_None, + PyDict_GET_SIZE(_self->cache)); + } + return PyObject_CallFunction(_self->cache_info_type, "nnnn", + _self->hits, _self->misses, _self->maxsize, + PyDict_GET_SIZE(_self->cache)); } +/*[clinic input] +_functools._lru_cache_wrapper.cache_clear + +Clear the cache and cache statistics +[clinic start generated code]*/ + static PyObject * -lru_cache_cache_clear(lru_cache_object *self, PyObject *unused) +_functools__lru_cache_wrapper_cache_clear_impl(PyObject *self) +/*[clinic end generated code: output=58423b35efc3e381 input=6ca59dba09b12584]*/ { - lru_list_elem *list = lru_cache_unlink_list(self); - self->hits = self->misses = 0; - PyDict_Clear(self->cache); + lru_cache_object *_self = (lru_cache_object *) self; + lru_list_elem *list = lru_cache_unlink_list(_self); + _self->hits = _self->misses = 0; + PyDict_Clear(_self->cache); lru_cache_clear_list(list); Py_RETURN_NONE; } @@ -1331,15 +1339,13 @@ lru_cache_reduce(PyObject *self, PyObject *unused) static PyObject * lru_cache_copy(PyObject *self, PyObject *unused) { - Py_INCREF(self); - return self; + return Py_NewRef(self); } static PyObject * lru_cache_deepcopy(PyObject *self, PyObject *unused) { - Py_INCREF(self); - return self; + return Py_NewRef(self); } static int @@ -1381,8 +1387,8 @@ cache_info_type: namedtuple class with the fields:\n\ ); static PyMethodDef lru_cache_methods[] = { - {"cache_info", (PyCFunction)lru_cache_cache_info, METH_NOARGS}, - {"cache_clear", (PyCFunction)lru_cache_cache_clear, METH_NOARGS}, + _FUNCTOOLS__LRU_CACHE_WRAPPER_CACHE_INFO_METHODDEF + _FUNCTOOLS__LRU_CACHE_WRAPPER_CACHE_CLEAR_METHODDEF {"__reduce__", (PyCFunction)lru_cache_reduce, METH_NOARGS}, {"__copy__", (PyCFunction)lru_cache_copy, METH_VARARGS}, {"__deepcopy__", (PyCFunction)lru_cache_deepcopy, METH_VARARGS}, @@ -1432,8 +1438,7 @@ PyDoc_STRVAR(_functools_doc, static PyMethodDef _functools_methods[] = { {"reduce", functools_reduce, METH_VARARGS, functools_reduce_doc}, - {"cmp_to_key", _PyCFunction_CAST(functools_cmp_to_key), - METH_VARARGS | METH_KEYWORDS, functools_cmp_to_key_doc}, + _FUNCTOOLS_CMP_TO_KEY_METHODDEF {NULL, NULL} /* sentinel */ }; @@ -1515,6 +1520,7 @@ _functools_free(void *module) static struct PyModuleDef_Slot _functools_slots[] = { {Py_mod_exec, _functools_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; diff --git a/Modules/_gdbmmodule.c b/Modules/_gdbmmodule.c index e6440fa9..4dbb5741 100644 --- a/Modules/_gdbmmodule.c +++ b/Modules/_gdbmmodule.c @@ -162,6 +162,35 @@ gdbm_length(gdbmobject *dp) return dp->di_size; } +static int +gdbm_bool(gdbmobject *dp) +{ + _gdbm_state *state = PyType_GetModuleState(Py_TYPE(dp)); + if (dp->di_dbm == NULL) { + PyErr_SetString(state->gdbm_error, "GDBM object has already been closed"); + return -1; + } + if (dp->di_size > 0) { + /* Known non-zero size. */ + return 1; + } + if (dp->di_size == 0) { + /* Known zero size. */ + return 0; + } + /* Unknown size. Ensure DBM object has an entry. */ + datum key = gdbm_firstkey(dp->di_dbm); + if (key.dptr == NULL) { + /* Empty. Cache this fact. */ + dp->di_size = 0; + return 0; + } + + /* Non-empty. Don't cache the length since we don't know. */ + free(key.dptr); + return 1; +} + // Wrapper function for PyArg_Parse(o, "s#", &d.dptr, &d.size). // This function is needed to support PY_SSIZE_T_CLEAN. // Return 1 on success, same to PyArg_Parse(). @@ -227,8 +256,7 @@ _gdbm_gdbm_get_impl(gdbmobject *self, PyObject *key, PyObject *default_value) res = gdbm_subscript(self, key); if (res == NULL && PyErr_ExceptionMatches(PyExc_KeyError)) { PyErr_Clear(); - Py_INCREF(default_value); - return default_value; + return Py_NewRef(default_value); } return res; } @@ -537,8 +565,7 @@ _gdbm_gdbm_sync_impl(gdbmobject *self, PyTypeObject *cls) static PyObject * gdbm__enter__(PyObject *self, PyObject *args) { - Py_INCREF(self); - return self; + return Py_NewRef(self); } static PyObject * @@ -569,6 +596,7 @@ static PyType_Slot gdbmtype_spec_slots[] = { {Py_mp_length, gdbm_length}, {Py_mp_subscript, gdbm_subscript}, {Py_mp_ass_subscript, gdbm_ass_sub}, + {Py_nb_bool, gdbm_bool}, {Py_tp_doc, (char*)gdbm_object__doc__}, {0, 0} }; @@ -647,7 +675,6 @@ dbmopen_impl(PyObject *module, PyObject *filename, const char *flags, return NULL; } for (flags++; *flags != '\0'; flags++) { - char buf[40]; switch (*flags) { #ifdef GDBM_FAST case 'f': @@ -665,9 +692,8 @@ dbmopen_impl(PyObject *module, PyObject *filename, const char *flags, break; #endif default: - PyOS_snprintf(buf, sizeof(buf), "Flag '%c' is not supported.", - *flags); - PyErr_SetString(state->gdbm_error, buf); + PyErr_Format(state->gdbm_error, + "Flag '%c' is not supported.", (unsigned char)*flags); return NULL; } } @@ -767,6 +793,7 @@ _gdbm_module_free(void *module) static PyModuleDef_Slot _gdbm_module_slots[] = { {Py_mod_exec, _gdbm_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; diff --git a/Modules/_hacl/Hacl_Hash_MD5.c b/Modules/_hacl/Hacl_Hash_MD5.c new file mode 100644 index 00000000..222ac824 --- /dev/null +++ b/Modules/_hacl/Hacl_Hash_MD5.c @@ -0,0 +1,1472 @@ +/* MIT License + * + * Copyright (c) 2016-2022 INRIA, CMU and Microsoft Corporation + * Copyright (c) 2022-2023 HACL* Contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + + +#include "internal/Hacl_Hash_MD5.h" + +static uint32_t +_h0[4U] = + { (uint32_t)0x67452301U, (uint32_t)0xefcdab89U, (uint32_t)0x98badcfeU, (uint32_t)0x10325476U }; + +static uint32_t +_t[64U] = + { + (uint32_t)0xd76aa478U, (uint32_t)0xe8c7b756U, (uint32_t)0x242070dbU, (uint32_t)0xc1bdceeeU, + (uint32_t)0xf57c0fafU, (uint32_t)0x4787c62aU, (uint32_t)0xa8304613U, (uint32_t)0xfd469501U, + (uint32_t)0x698098d8U, (uint32_t)0x8b44f7afU, (uint32_t)0xffff5bb1U, (uint32_t)0x895cd7beU, + (uint32_t)0x6b901122U, (uint32_t)0xfd987193U, (uint32_t)0xa679438eU, (uint32_t)0x49b40821U, + (uint32_t)0xf61e2562U, (uint32_t)0xc040b340U, (uint32_t)0x265e5a51U, (uint32_t)0xe9b6c7aaU, + (uint32_t)0xd62f105dU, (uint32_t)0x02441453U, (uint32_t)0xd8a1e681U, (uint32_t)0xe7d3fbc8U, + (uint32_t)0x21e1cde6U, (uint32_t)0xc33707d6U, (uint32_t)0xf4d50d87U, (uint32_t)0x455a14edU, + (uint32_t)0xa9e3e905U, (uint32_t)0xfcefa3f8U, (uint32_t)0x676f02d9U, (uint32_t)0x8d2a4c8aU, + (uint32_t)0xfffa3942U, (uint32_t)0x8771f681U, (uint32_t)0x6d9d6122U, (uint32_t)0xfde5380cU, + (uint32_t)0xa4beea44U, (uint32_t)0x4bdecfa9U, (uint32_t)0xf6bb4b60U, (uint32_t)0xbebfbc70U, + (uint32_t)0x289b7ec6U, (uint32_t)0xeaa127faU, (uint32_t)0xd4ef3085U, (uint32_t)0x4881d05U, + (uint32_t)0xd9d4d039U, (uint32_t)0xe6db99e5U, (uint32_t)0x1fa27cf8U, (uint32_t)0xc4ac5665U, + (uint32_t)0xf4292244U, (uint32_t)0x432aff97U, (uint32_t)0xab9423a7U, (uint32_t)0xfc93a039U, + (uint32_t)0x655b59c3U, (uint32_t)0x8f0ccc92U, (uint32_t)0xffeff47dU, (uint32_t)0x85845dd1U, + (uint32_t)0x6fa87e4fU, (uint32_t)0xfe2ce6e0U, (uint32_t)0xa3014314U, (uint32_t)0x4e0811a1U, + (uint32_t)0xf7537e82U, (uint32_t)0xbd3af235U, (uint32_t)0x2ad7d2bbU, (uint32_t)0xeb86d391U + }; + +void Hacl_Hash_Core_MD5_legacy_init(uint32_t *s) +{ + KRML_MAYBE_FOR4(i, (uint32_t)0U, (uint32_t)4U, (uint32_t)1U, s[i] = _h0[i];); +} + +static void legacy_update(uint32_t *abcd, uint8_t *x) +{ + uint32_t aa = abcd[0U]; + uint32_t bb = abcd[1U]; + uint32_t cc = abcd[2U]; + uint32_t dd = abcd[3U]; + uint32_t va = abcd[0U]; + uint32_t vb0 = abcd[1U]; + uint32_t vc0 = abcd[2U]; + uint32_t vd0 = abcd[3U]; + uint8_t *b0 = x; + uint32_t u = load32_le(b0); + uint32_t xk = u; + uint32_t ti0 = _t[0U]; + uint32_t + v = + vb0 + + + ((va + ((vb0 & vc0) | (~vb0 & vd0)) + xk + ti0) + << (uint32_t)7U + | (va + ((vb0 & vc0) | (~vb0 & vd0)) + xk + ti0) >> (uint32_t)25U); + abcd[0U] = v; + uint32_t va0 = abcd[3U]; + uint32_t vb1 = abcd[0U]; + uint32_t vc1 = abcd[1U]; + uint32_t vd1 = abcd[2U]; + uint8_t *b1 = x + (uint32_t)4U; + uint32_t u0 = load32_le(b1); + uint32_t xk0 = u0; + uint32_t ti1 = _t[1U]; + uint32_t + v0 = + vb1 + + + ((va0 + ((vb1 & vc1) | (~vb1 & vd1)) + xk0 + ti1) + << (uint32_t)12U + | (va0 + ((vb1 & vc1) | (~vb1 & vd1)) + xk0 + ti1) >> (uint32_t)20U); + abcd[3U] = v0; + uint32_t va1 = abcd[2U]; + uint32_t vb2 = abcd[3U]; + uint32_t vc2 = abcd[0U]; + uint32_t vd2 = abcd[1U]; + uint8_t *b2 = x + (uint32_t)8U; + uint32_t u1 = load32_le(b2); + uint32_t xk1 = u1; + uint32_t ti2 = _t[2U]; + uint32_t + v1 = + vb2 + + + ((va1 + ((vb2 & vc2) | (~vb2 & vd2)) + xk1 + ti2) + << (uint32_t)17U + | (va1 + ((vb2 & vc2) | (~vb2 & vd2)) + xk1 + ti2) >> (uint32_t)15U); + abcd[2U] = v1; + uint32_t va2 = abcd[1U]; + uint32_t vb3 = abcd[2U]; + uint32_t vc3 = abcd[3U]; + uint32_t vd3 = abcd[0U]; + uint8_t *b3 = x + (uint32_t)12U; + uint32_t u2 = load32_le(b3); + uint32_t xk2 = u2; + uint32_t ti3 = _t[3U]; + uint32_t + v2 = + vb3 + + + ((va2 + ((vb3 & vc3) | (~vb3 & vd3)) + xk2 + ti3) + << (uint32_t)22U + | (va2 + ((vb3 & vc3) | (~vb3 & vd3)) + xk2 + ti3) >> (uint32_t)10U); + abcd[1U] = v2; + uint32_t va3 = abcd[0U]; + uint32_t vb4 = abcd[1U]; + uint32_t vc4 = abcd[2U]; + uint32_t vd4 = abcd[3U]; + uint8_t *b4 = x + (uint32_t)16U; + uint32_t u3 = load32_le(b4); + uint32_t xk3 = u3; + uint32_t ti4 = _t[4U]; + uint32_t + v3 = + vb4 + + + ((va3 + ((vb4 & vc4) | (~vb4 & vd4)) + xk3 + ti4) + << (uint32_t)7U + | (va3 + ((vb4 & vc4) | (~vb4 & vd4)) + xk3 + ti4) >> (uint32_t)25U); + abcd[0U] = v3; + uint32_t va4 = abcd[3U]; + uint32_t vb5 = abcd[0U]; + uint32_t vc5 = abcd[1U]; + uint32_t vd5 = abcd[2U]; + uint8_t *b5 = x + (uint32_t)20U; + uint32_t u4 = load32_le(b5); + uint32_t xk4 = u4; + uint32_t ti5 = _t[5U]; + uint32_t + v4 = + vb5 + + + ((va4 + ((vb5 & vc5) | (~vb5 & vd5)) + xk4 + ti5) + << (uint32_t)12U + | (va4 + ((vb5 & vc5) | (~vb5 & vd5)) + xk4 + ti5) >> (uint32_t)20U); + abcd[3U] = v4; + uint32_t va5 = abcd[2U]; + uint32_t vb6 = abcd[3U]; + uint32_t vc6 = abcd[0U]; + uint32_t vd6 = abcd[1U]; + uint8_t *b6 = x + (uint32_t)24U; + uint32_t u5 = load32_le(b6); + uint32_t xk5 = u5; + uint32_t ti6 = _t[6U]; + uint32_t + v5 = + vb6 + + + ((va5 + ((vb6 & vc6) | (~vb6 & vd6)) + xk5 + ti6) + << (uint32_t)17U + | (va5 + ((vb6 & vc6) | (~vb6 & vd6)) + xk5 + ti6) >> (uint32_t)15U); + abcd[2U] = v5; + uint32_t va6 = abcd[1U]; + uint32_t vb7 = abcd[2U]; + uint32_t vc7 = abcd[3U]; + uint32_t vd7 = abcd[0U]; + uint8_t *b7 = x + (uint32_t)28U; + uint32_t u6 = load32_le(b7); + uint32_t xk6 = u6; + uint32_t ti7 = _t[7U]; + uint32_t + v6 = + vb7 + + + ((va6 + ((vb7 & vc7) | (~vb7 & vd7)) + xk6 + ti7) + << (uint32_t)22U + | (va6 + ((vb7 & vc7) | (~vb7 & vd7)) + xk6 + ti7) >> (uint32_t)10U); + abcd[1U] = v6; + uint32_t va7 = abcd[0U]; + uint32_t vb8 = abcd[1U]; + uint32_t vc8 = abcd[2U]; + uint32_t vd8 = abcd[3U]; + uint8_t *b8 = x + (uint32_t)32U; + uint32_t u7 = load32_le(b8); + uint32_t xk7 = u7; + uint32_t ti8 = _t[8U]; + uint32_t + v7 = + vb8 + + + ((va7 + ((vb8 & vc8) | (~vb8 & vd8)) + xk7 + ti8) + << (uint32_t)7U + | (va7 + ((vb8 & vc8) | (~vb8 & vd8)) + xk7 + ti8) >> (uint32_t)25U); + abcd[0U] = v7; + uint32_t va8 = abcd[3U]; + uint32_t vb9 = abcd[0U]; + uint32_t vc9 = abcd[1U]; + uint32_t vd9 = abcd[2U]; + uint8_t *b9 = x + (uint32_t)36U; + uint32_t u8 = load32_le(b9); + uint32_t xk8 = u8; + uint32_t ti9 = _t[9U]; + uint32_t + v8 = + vb9 + + + ((va8 + ((vb9 & vc9) | (~vb9 & vd9)) + xk8 + ti9) + << (uint32_t)12U + | (va8 + ((vb9 & vc9) | (~vb9 & vd9)) + xk8 + ti9) >> (uint32_t)20U); + abcd[3U] = v8; + uint32_t va9 = abcd[2U]; + uint32_t vb10 = abcd[3U]; + uint32_t vc10 = abcd[0U]; + uint32_t vd10 = abcd[1U]; + uint8_t *b10 = x + (uint32_t)40U; + uint32_t u9 = load32_le(b10); + uint32_t xk9 = u9; + uint32_t ti10 = _t[10U]; + uint32_t + v9 = + vb10 + + + ((va9 + ((vb10 & vc10) | (~vb10 & vd10)) + xk9 + ti10) + << (uint32_t)17U + | (va9 + ((vb10 & vc10) | (~vb10 & vd10)) + xk9 + ti10) >> (uint32_t)15U); + abcd[2U] = v9; + uint32_t va10 = abcd[1U]; + uint32_t vb11 = abcd[2U]; + uint32_t vc11 = abcd[3U]; + uint32_t vd11 = abcd[0U]; + uint8_t *b11 = x + (uint32_t)44U; + uint32_t u10 = load32_le(b11); + uint32_t xk10 = u10; + uint32_t ti11 = _t[11U]; + uint32_t + v10 = + vb11 + + + ((va10 + ((vb11 & vc11) | (~vb11 & vd11)) + xk10 + ti11) + << (uint32_t)22U + | (va10 + ((vb11 & vc11) | (~vb11 & vd11)) + xk10 + ti11) >> (uint32_t)10U); + abcd[1U] = v10; + uint32_t va11 = abcd[0U]; + uint32_t vb12 = abcd[1U]; + uint32_t vc12 = abcd[2U]; + uint32_t vd12 = abcd[3U]; + uint8_t *b12 = x + (uint32_t)48U; + uint32_t u11 = load32_le(b12); + uint32_t xk11 = u11; + uint32_t ti12 = _t[12U]; + uint32_t + v11 = + vb12 + + + ((va11 + ((vb12 & vc12) | (~vb12 & vd12)) + xk11 + ti12) + << (uint32_t)7U + | (va11 + ((vb12 & vc12) | (~vb12 & vd12)) + xk11 + ti12) >> (uint32_t)25U); + abcd[0U] = v11; + uint32_t va12 = abcd[3U]; + uint32_t vb13 = abcd[0U]; + uint32_t vc13 = abcd[1U]; + uint32_t vd13 = abcd[2U]; + uint8_t *b13 = x + (uint32_t)52U; + uint32_t u12 = load32_le(b13); + uint32_t xk12 = u12; + uint32_t ti13 = _t[13U]; + uint32_t + v12 = + vb13 + + + ((va12 + ((vb13 & vc13) | (~vb13 & vd13)) + xk12 + ti13) + << (uint32_t)12U + | (va12 + ((vb13 & vc13) | (~vb13 & vd13)) + xk12 + ti13) >> (uint32_t)20U); + abcd[3U] = v12; + uint32_t va13 = abcd[2U]; + uint32_t vb14 = abcd[3U]; + uint32_t vc14 = abcd[0U]; + uint32_t vd14 = abcd[1U]; + uint8_t *b14 = x + (uint32_t)56U; + uint32_t u13 = load32_le(b14); + uint32_t xk13 = u13; + uint32_t ti14 = _t[14U]; + uint32_t + v13 = + vb14 + + + ((va13 + ((vb14 & vc14) | (~vb14 & vd14)) + xk13 + ti14) + << (uint32_t)17U + | (va13 + ((vb14 & vc14) | (~vb14 & vd14)) + xk13 + ti14) >> (uint32_t)15U); + abcd[2U] = v13; + uint32_t va14 = abcd[1U]; + uint32_t vb15 = abcd[2U]; + uint32_t vc15 = abcd[3U]; + uint32_t vd15 = abcd[0U]; + uint8_t *b15 = x + (uint32_t)60U; + uint32_t u14 = load32_le(b15); + uint32_t xk14 = u14; + uint32_t ti15 = _t[15U]; + uint32_t + v14 = + vb15 + + + ((va14 + ((vb15 & vc15) | (~vb15 & vd15)) + xk14 + ti15) + << (uint32_t)22U + | (va14 + ((vb15 & vc15) | (~vb15 & vd15)) + xk14 + ti15) >> (uint32_t)10U); + abcd[1U] = v14; + uint32_t va15 = abcd[0U]; + uint32_t vb16 = abcd[1U]; + uint32_t vc16 = abcd[2U]; + uint32_t vd16 = abcd[3U]; + uint8_t *b16 = x + (uint32_t)4U; + uint32_t u15 = load32_le(b16); + uint32_t xk15 = u15; + uint32_t ti16 = _t[16U]; + uint32_t + v15 = + vb16 + + + ((va15 + ((vb16 & vd16) | (vc16 & ~vd16)) + xk15 + ti16) + << (uint32_t)5U + | (va15 + ((vb16 & vd16) | (vc16 & ~vd16)) + xk15 + ti16) >> (uint32_t)27U); + abcd[0U] = v15; + uint32_t va16 = abcd[3U]; + uint32_t vb17 = abcd[0U]; + uint32_t vc17 = abcd[1U]; + uint32_t vd17 = abcd[2U]; + uint8_t *b17 = x + (uint32_t)24U; + uint32_t u16 = load32_le(b17); + uint32_t xk16 = u16; + uint32_t ti17 = _t[17U]; + uint32_t + v16 = + vb17 + + + ((va16 + ((vb17 & vd17) | (vc17 & ~vd17)) + xk16 + ti17) + << (uint32_t)9U + | (va16 + ((vb17 & vd17) | (vc17 & ~vd17)) + xk16 + ti17) >> (uint32_t)23U); + abcd[3U] = v16; + uint32_t va17 = abcd[2U]; + uint32_t vb18 = abcd[3U]; + uint32_t vc18 = abcd[0U]; + uint32_t vd18 = abcd[1U]; + uint8_t *b18 = x + (uint32_t)44U; + uint32_t u17 = load32_le(b18); + uint32_t xk17 = u17; + uint32_t ti18 = _t[18U]; + uint32_t + v17 = + vb18 + + + ((va17 + ((vb18 & vd18) | (vc18 & ~vd18)) + xk17 + ti18) + << (uint32_t)14U + | (va17 + ((vb18 & vd18) | (vc18 & ~vd18)) + xk17 + ti18) >> (uint32_t)18U); + abcd[2U] = v17; + uint32_t va18 = abcd[1U]; + uint32_t vb19 = abcd[2U]; + uint32_t vc19 = abcd[3U]; + uint32_t vd19 = abcd[0U]; + uint8_t *b19 = x; + uint32_t u18 = load32_le(b19); + uint32_t xk18 = u18; + uint32_t ti19 = _t[19U]; + uint32_t + v18 = + vb19 + + + ((va18 + ((vb19 & vd19) | (vc19 & ~vd19)) + xk18 + ti19) + << (uint32_t)20U + | (va18 + ((vb19 & vd19) | (vc19 & ~vd19)) + xk18 + ti19) >> (uint32_t)12U); + abcd[1U] = v18; + uint32_t va19 = abcd[0U]; + uint32_t vb20 = abcd[1U]; + uint32_t vc20 = abcd[2U]; + uint32_t vd20 = abcd[3U]; + uint8_t *b20 = x + (uint32_t)20U; + uint32_t u19 = load32_le(b20); + uint32_t xk19 = u19; + uint32_t ti20 = _t[20U]; + uint32_t + v19 = + vb20 + + + ((va19 + ((vb20 & vd20) | (vc20 & ~vd20)) + xk19 + ti20) + << (uint32_t)5U + | (va19 + ((vb20 & vd20) | (vc20 & ~vd20)) + xk19 + ti20) >> (uint32_t)27U); + abcd[0U] = v19; + uint32_t va20 = abcd[3U]; + uint32_t vb21 = abcd[0U]; + uint32_t vc21 = abcd[1U]; + uint32_t vd21 = abcd[2U]; + uint8_t *b21 = x + (uint32_t)40U; + uint32_t u20 = load32_le(b21); + uint32_t xk20 = u20; + uint32_t ti21 = _t[21U]; + uint32_t + v20 = + vb21 + + + ((va20 + ((vb21 & vd21) | (vc21 & ~vd21)) + xk20 + ti21) + << (uint32_t)9U + | (va20 + ((vb21 & vd21) | (vc21 & ~vd21)) + xk20 + ti21) >> (uint32_t)23U); + abcd[3U] = v20; + uint32_t va21 = abcd[2U]; + uint32_t vb22 = abcd[3U]; + uint32_t vc22 = abcd[0U]; + uint32_t vd22 = abcd[1U]; + uint8_t *b22 = x + (uint32_t)60U; + uint32_t u21 = load32_le(b22); + uint32_t xk21 = u21; + uint32_t ti22 = _t[22U]; + uint32_t + v21 = + vb22 + + + ((va21 + ((vb22 & vd22) | (vc22 & ~vd22)) + xk21 + ti22) + << (uint32_t)14U + | (va21 + ((vb22 & vd22) | (vc22 & ~vd22)) + xk21 + ti22) >> (uint32_t)18U); + abcd[2U] = v21; + uint32_t va22 = abcd[1U]; + uint32_t vb23 = abcd[2U]; + uint32_t vc23 = abcd[3U]; + uint32_t vd23 = abcd[0U]; + uint8_t *b23 = x + (uint32_t)16U; + uint32_t u22 = load32_le(b23); + uint32_t xk22 = u22; + uint32_t ti23 = _t[23U]; + uint32_t + v22 = + vb23 + + + ((va22 + ((vb23 & vd23) | (vc23 & ~vd23)) + xk22 + ti23) + << (uint32_t)20U + | (va22 + ((vb23 & vd23) | (vc23 & ~vd23)) + xk22 + ti23) >> (uint32_t)12U); + abcd[1U] = v22; + uint32_t va23 = abcd[0U]; + uint32_t vb24 = abcd[1U]; + uint32_t vc24 = abcd[2U]; + uint32_t vd24 = abcd[3U]; + uint8_t *b24 = x + (uint32_t)36U; + uint32_t u23 = load32_le(b24); + uint32_t xk23 = u23; + uint32_t ti24 = _t[24U]; + uint32_t + v23 = + vb24 + + + ((va23 + ((vb24 & vd24) | (vc24 & ~vd24)) + xk23 + ti24) + << (uint32_t)5U + | (va23 + ((vb24 & vd24) | (vc24 & ~vd24)) + xk23 + ti24) >> (uint32_t)27U); + abcd[0U] = v23; + uint32_t va24 = abcd[3U]; + uint32_t vb25 = abcd[0U]; + uint32_t vc25 = abcd[1U]; + uint32_t vd25 = abcd[2U]; + uint8_t *b25 = x + (uint32_t)56U; + uint32_t u24 = load32_le(b25); + uint32_t xk24 = u24; + uint32_t ti25 = _t[25U]; + uint32_t + v24 = + vb25 + + + ((va24 + ((vb25 & vd25) | (vc25 & ~vd25)) + xk24 + ti25) + << (uint32_t)9U + | (va24 + ((vb25 & vd25) | (vc25 & ~vd25)) + xk24 + ti25) >> (uint32_t)23U); + abcd[3U] = v24; + uint32_t va25 = abcd[2U]; + uint32_t vb26 = abcd[3U]; + uint32_t vc26 = abcd[0U]; + uint32_t vd26 = abcd[1U]; + uint8_t *b26 = x + (uint32_t)12U; + uint32_t u25 = load32_le(b26); + uint32_t xk25 = u25; + uint32_t ti26 = _t[26U]; + uint32_t + v25 = + vb26 + + + ((va25 + ((vb26 & vd26) | (vc26 & ~vd26)) + xk25 + ti26) + << (uint32_t)14U + | (va25 + ((vb26 & vd26) | (vc26 & ~vd26)) + xk25 + ti26) >> (uint32_t)18U); + abcd[2U] = v25; + uint32_t va26 = abcd[1U]; + uint32_t vb27 = abcd[2U]; + uint32_t vc27 = abcd[3U]; + uint32_t vd27 = abcd[0U]; + uint8_t *b27 = x + (uint32_t)32U; + uint32_t u26 = load32_le(b27); + uint32_t xk26 = u26; + uint32_t ti27 = _t[27U]; + uint32_t + v26 = + vb27 + + + ((va26 + ((vb27 & vd27) | (vc27 & ~vd27)) + xk26 + ti27) + << (uint32_t)20U + | (va26 + ((vb27 & vd27) | (vc27 & ~vd27)) + xk26 + ti27) >> (uint32_t)12U); + abcd[1U] = v26; + uint32_t va27 = abcd[0U]; + uint32_t vb28 = abcd[1U]; + uint32_t vc28 = abcd[2U]; + uint32_t vd28 = abcd[3U]; + uint8_t *b28 = x + (uint32_t)52U; + uint32_t u27 = load32_le(b28); + uint32_t xk27 = u27; + uint32_t ti28 = _t[28U]; + uint32_t + v27 = + vb28 + + + ((va27 + ((vb28 & vd28) | (vc28 & ~vd28)) + xk27 + ti28) + << (uint32_t)5U + | (va27 + ((vb28 & vd28) | (vc28 & ~vd28)) + xk27 + ti28) >> (uint32_t)27U); + abcd[0U] = v27; + uint32_t va28 = abcd[3U]; + uint32_t vb29 = abcd[0U]; + uint32_t vc29 = abcd[1U]; + uint32_t vd29 = abcd[2U]; + uint8_t *b29 = x + (uint32_t)8U; + uint32_t u28 = load32_le(b29); + uint32_t xk28 = u28; + uint32_t ti29 = _t[29U]; + uint32_t + v28 = + vb29 + + + ((va28 + ((vb29 & vd29) | (vc29 & ~vd29)) + xk28 + ti29) + << (uint32_t)9U + | (va28 + ((vb29 & vd29) | (vc29 & ~vd29)) + xk28 + ti29) >> (uint32_t)23U); + abcd[3U] = v28; + uint32_t va29 = abcd[2U]; + uint32_t vb30 = abcd[3U]; + uint32_t vc30 = abcd[0U]; + uint32_t vd30 = abcd[1U]; + uint8_t *b30 = x + (uint32_t)28U; + uint32_t u29 = load32_le(b30); + uint32_t xk29 = u29; + uint32_t ti30 = _t[30U]; + uint32_t + v29 = + vb30 + + + ((va29 + ((vb30 & vd30) | (vc30 & ~vd30)) + xk29 + ti30) + << (uint32_t)14U + | (va29 + ((vb30 & vd30) | (vc30 & ~vd30)) + xk29 + ti30) >> (uint32_t)18U); + abcd[2U] = v29; + uint32_t va30 = abcd[1U]; + uint32_t vb31 = abcd[2U]; + uint32_t vc31 = abcd[3U]; + uint32_t vd31 = abcd[0U]; + uint8_t *b31 = x + (uint32_t)48U; + uint32_t u30 = load32_le(b31); + uint32_t xk30 = u30; + uint32_t ti31 = _t[31U]; + uint32_t + v30 = + vb31 + + + ((va30 + ((vb31 & vd31) | (vc31 & ~vd31)) + xk30 + ti31) + << (uint32_t)20U + | (va30 + ((vb31 & vd31) | (vc31 & ~vd31)) + xk30 + ti31) >> (uint32_t)12U); + abcd[1U] = v30; + uint32_t va31 = abcd[0U]; + uint32_t vb32 = abcd[1U]; + uint32_t vc32 = abcd[2U]; + uint32_t vd32 = abcd[3U]; + uint8_t *b32 = x + (uint32_t)20U; + uint32_t u31 = load32_le(b32); + uint32_t xk31 = u31; + uint32_t ti32 = _t[32U]; + uint32_t + v31 = + vb32 + + + ((va31 + (vb32 ^ (vc32 ^ vd32)) + xk31 + ti32) + << (uint32_t)4U + | (va31 + (vb32 ^ (vc32 ^ vd32)) + xk31 + ti32) >> (uint32_t)28U); + abcd[0U] = v31; + uint32_t va32 = abcd[3U]; + uint32_t vb33 = abcd[0U]; + uint32_t vc33 = abcd[1U]; + uint32_t vd33 = abcd[2U]; + uint8_t *b33 = x + (uint32_t)32U; + uint32_t u32 = load32_le(b33); + uint32_t xk32 = u32; + uint32_t ti33 = _t[33U]; + uint32_t + v32 = + vb33 + + + ((va32 + (vb33 ^ (vc33 ^ vd33)) + xk32 + ti33) + << (uint32_t)11U + | (va32 + (vb33 ^ (vc33 ^ vd33)) + xk32 + ti33) >> (uint32_t)21U); + abcd[3U] = v32; + uint32_t va33 = abcd[2U]; + uint32_t vb34 = abcd[3U]; + uint32_t vc34 = abcd[0U]; + uint32_t vd34 = abcd[1U]; + uint8_t *b34 = x + (uint32_t)44U; + uint32_t u33 = load32_le(b34); + uint32_t xk33 = u33; + uint32_t ti34 = _t[34U]; + uint32_t + v33 = + vb34 + + + ((va33 + (vb34 ^ (vc34 ^ vd34)) + xk33 + ti34) + << (uint32_t)16U + | (va33 + (vb34 ^ (vc34 ^ vd34)) + xk33 + ti34) >> (uint32_t)16U); + abcd[2U] = v33; + uint32_t va34 = abcd[1U]; + uint32_t vb35 = abcd[2U]; + uint32_t vc35 = abcd[3U]; + uint32_t vd35 = abcd[0U]; + uint8_t *b35 = x + (uint32_t)56U; + uint32_t u34 = load32_le(b35); + uint32_t xk34 = u34; + uint32_t ti35 = _t[35U]; + uint32_t + v34 = + vb35 + + + ((va34 + (vb35 ^ (vc35 ^ vd35)) + xk34 + ti35) + << (uint32_t)23U + | (va34 + (vb35 ^ (vc35 ^ vd35)) + xk34 + ti35) >> (uint32_t)9U); + abcd[1U] = v34; + uint32_t va35 = abcd[0U]; + uint32_t vb36 = abcd[1U]; + uint32_t vc36 = abcd[2U]; + uint32_t vd36 = abcd[3U]; + uint8_t *b36 = x + (uint32_t)4U; + uint32_t u35 = load32_le(b36); + uint32_t xk35 = u35; + uint32_t ti36 = _t[36U]; + uint32_t + v35 = + vb36 + + + ((va35 + (vb36 ^ (vc36 ^ vd36)) + xk35 + ti36) + << (uint32_t)4U + | (va35 + (vb36 ^ (vc36 ^ vd36)) + xk35 + ti36) >> (uint32_t)28U); + abcd[0U] = v35; + uint32_t va36 = abcd[3U]; + uint32_t vb37 = abcd[0U]; + uint32_t vc37 = abcd[1U]; + uint32_t vd37 = abcd[2U]; + uint8_t *b37 = x + (uint32_t)16U; + uint32_t u36 = load32_le(b37); + uint32_t xk36 = u36; + uint32_t ti37 = _t[37U]; + uint32_t + v36 = + vb37 + + + ((va36 + (vb37 ^ (vc37 ^ vd37)) + xk36 + ti37) + << (uint32_t)11U + | (va36 + (vb37 ^ (vc37 ^ vd37)) + xk36 + ti37) >> (uint32_t)21U); + abcd[3U] = v36; + uint32_t va37 = abcd[2U]; + uint32_t vb38 = abcd[3U]; + uint32_t vc38 = abcd[0U]; + uint32_t vd38 = abcd[1U]; + uint8_t *b38 = x + (uint32_t)28U; + uint32_t u37 = load32_le(b38); + uint32_t xk37 = u37; + uint32_t ti38 = _t[38U]; + uint32_t + v37 = + vb38 + + + ((va37 + (vb38 ^ (vc38 ^ vd38)) + xk37 + ti38) + << (uint32_t)16U + | (va37 + (vb38 ^ (vc38 ^ vd38)) + xk37 + ti38) >> (uint32_t)16U); + abcd[2U] = v37; + uint32_t va38 = abcd[1U]; + uint32_t vb39 = abcd[2U]; + uint32_t vc39 = abcd[3U]; + uint32_t vd39 = abcd[0U]; + uint8_t *b39 = x + (uint32_t)40U; + uint32_t u38 = load32_le(b39); + uint32_t xk38 = u38; + uint32_t ti39 = _t[39U]; + uint32_t + v38 = + vb39 + + + ((va38 + (vb39 ^ (vc39 ^ vd39)) + xk38 + ti39) + << (uint32_t)23U + | (va38 + (vb39 ^ (vc39 ^ vd39)) + xk38 + ti39) >> (uint32_t)9U); + abcd[1U] = v38; + uint32_t va39 = abcd[0U]; + uint32_t vb40 = abcd[1U]; + uint32_t vc40 = abcd[2U]; + uint32_t vd40 = abcd[3U]; + uint8_t *b40 = x + (uint32_t)52U; + uint32_t u39 = load32_le(b40); + uint32_t xk39 = u39; + uint32_t ti40 = _t[40U]; + uint32_t + v39 = + vb40 + + + ((va39 + (vb40 ^ (vc40 ^ vd40)) + xk39 + ti40) + << (uint32_t)4U + | (va39 + (vb40 ^ (vc40 ^ vd40)) + xk39 + ti40) >> (uint32_t)28U); + abcd[0U] = v39; + uint32_t va40 = abcd[3U]; + uint32_t vb41 = abcd[0U]; + uint32_t vc41 = abcd[1U]; + uint32_t vd41 = abcd[2U]; + uint8_t *b41 = x; + uint32_t u40 = load32_le(b41); + uint32_t xk40 = u40; + uint32_t ti41 = _t[41U]; + uint32_t + v40 = + vb41 + + + ((va40 + (vb41 ^ (vc41 ^ vd41)) + xk40 + ti41) + << (uint32_t)11U + | (va40 + (vb41 ^ (vc41 ^ vd41)) + xk40 + ti41) >> (uint32_t)21U); + abcd[3U] = v40; + uint32_t va41 = abcd[2U]; + uint32_t vb42 = abcd[3U]; + uint32_t vc42 = abcd[0U]; + uint32_t vd42 = abcd[1U]; + uint8_t *b42 = x + (uint32_t)12U; + uint32_t u41 = load32_le(b42); + uint32_t xk41 = u41; + uint32_t ti42 = _t[42U]; + uint32_t + v41 = + vb42 + + + ((va41 + (vb42 ^ (vc42 ^ vd42)) + xk41 + ti42) + << (uint32_t)16U + | (va41 + (vb42 ^ (vc42 ^ vd42)) + xk41 + ti42) >> (uint32_t)16U); + abcd[2U] = v41; + uint32_t va42 = abcd[1U]; + uint32_t vb43 = abcd[2U]; + uint32_t vc43 = abcd[3U]; + uint32_t vd43 = abcd[0U]; + uint8_t *b43 = x + (uint32_t)24U; + uint32_t u42 = load32_le(b43); + uint32_t xk42 = u42; + uint32_t ti43 = _t[43U]; + uint32_t + v42 = + vb43 + + + ((va42 + (vb43 ^ (vc43 ^ vd43)) + xk42 + ti43) + << (uint32_t)23U + | (va42 + (vb43 ^ (vc43 ^ vd43)) + xk42 + ti43) >> (uint32_t)9U); + abcd[1U] = v42; + uint32_t va43 = abcd[0U]; + uint32_t vb44 = abcd[1U]; + uint32_t vc44 = abcd[2U]; + uint32_t vd44 = abcd[3U]; + uint8_t *b44 = x + (uint32_t)36U; + uint32_t u43 = load32_le(b44); + uint32_t xk43 = u43; + uint32_t ti44 = _t[44U]; + uint32_t + v43 = + vb44 + + + ((va43 + (vb44 ^ (vc44 ^ vd44)) + xk43 + ti44) + << (uint32_t)4U + | (va43 + (vb44 ^ (vc44 ^ vd44)) + xk43 + ti44) >> (uint32_t)28U); + abcd[0U] = v43; + uint32_t va44 = abcd[3U]; + uint32_t vb45 = abcd[0U]; + uint32_t vc45 = abcd[1U]; + uint32_t vd45 = abcd[2U]; + uint8_t *b45 = x + (uint32_t)48U; + uint32_t u44 = load32_le(b45); + uint32_t xk44 = u44; + uint32_t ti45 = _t[45U]; + uint32_t + v44 = + vb45 + + + ((va44 + (vb45 ^ (vc45 ^ vd45)) + xk44 + ti45) + << (uint32_t)11U + | (va44 + (vb45 ^ (vc45 ^ vd45)) + xk44 + ti45) >> (uint32_t)21U); + abcd[3U] = v44; + uint32_t va45 = abcd[2U]; + uint32_t vb46 = abcd[3U]; + uint32_t vc46 = abcd[0U]; + uint32_t vd46 = abcd[1U]; + uint8_t *b46 = x + (uint32_t)60U; + uint32_t u45 = load32_le(b46); + uint32_t xk45 = u45; + uint32_t ti46 = _t[46U]; + uint32_t + v45 = + vb46 + + + ((va45 + (vb46 ^ (vc46 ^ vd46)) + xk45 + ti46) + << (uint32_t)16U + | (va45 + (vb46 ^ (vc46 ^ vd46)) + xk45 + ti46) >> (uint32_t)16U); + abcd[2U] = v45; + uint32_t va46 = abcd[1U]; + uint32_t vb47 = abcd[2U]; + uint32_t vc47 = abcd[3U]; + uint32_t vd47 = abcd[0U]; + uint8_t *b47 = x + (uint32_t)8U; + uint32_t u46 = load32_le(b47); + uint32_t xk46 = u46; + uint32_t ti47 = _t[47U]; + uint32_t + v46 = + vb47 + + + ((va46 + (vb47 ^ (vc47 ^ vd47)) + xk46 + ti47) + << (uint32_t)23U + | (va46 + (vb47 ^ (vc47 ^ vd47)) + xk46 + ti47) >> (uint32_t)9U); + abcd[1U] = v46; + uint32_t va47 = abcd[0U]; + uint32_t vb48 = abcd[1U]; + uint32_t vc48 = abcd[2U]; + uint32_t vd48 = abcd[3U]; + uint8_t *b48 = x; + uint32_t u47 = load32_le(b48); + uint32_t xk47 = u47; + uint32_t ti48 = _t[48U]; + uint32_t + v47 = + vb48 + + + ((va47 + (vc48 ^ (vb48 | ~vd48)) + xk47 + ti48) + << (uint32_t)6U + | (va47 + (vc48 ^ (vb48 | ~vd48)) + xk47 + ti48) >> (uint32_t)26U); + abcd[0U] = v47; + uint32_t va48 = abcd[3U]; + uint32_t vb49 = abcd[0U]; + uint32_t vc49 = abcd[1U]; + uint32_t vd49 = abcd[2U]; + uint8_t *b49 = x + (uint32_t)28U; + uint32_t u48 = load32_le(b49); + uint32_t xk48 = u48; + uint32_t ti49 = _t[49U]; + uint32_t + v48 = + vb49 + + + ((va48 + (vc49 ^ (vb49 | ~vd49)) + xk48 + ti49) + << (uint32_t)10U + | (va48 + (vc49 ^ (vb49 | ~vd49)) + xk48 + ti49) >> (uint32_t)22U); + abcd[3U] = v48; + uint32_t va49 = abcd[2U]; + uint32_t vb50 = abcd[3U]; + uint32_t vc50 = abcd[0U]; + uint32_t vd50 = abcd[1U]; + uint8_t *b50 = x + (uint32_t)56U; + uint32_t u49 = load32_le(b50); + uint32_t xk49 = u49; + uint32_t ti50 = _t[50U]; + uint32_t + v49 = + vb50 + + + ((va49 + (vc50 ^ (vb50 | ~vd50)) + xk49 + ti50) + << (uint32_t)15U + | (va49 + (vc50 ^ (vb50 | ~vd50)) + xk49 + ti50) >> (uint32_t)17U); + abcd[2U] = v49; + uint32_t va50 = abcd[1U]; + uint32_t vb51 = abcd[2U]; + uint32_t vc51 = abcd[3U]; + uint32_t vd51 = abcd[0U]; + uint8_t *b51 = x + (uint32_t)20U; + uint32_t u50 = load32_le(b51); + uint32_t xk50 = u50; + uint32_t ti51 = _t[51U]; + uint32_t + v50 = + vb51 + + + ((va50 + (vc51 ^ (vb51 | ~vd51)) + xk50 + ti51) + << (uint32_t)21U + | (va50 + (vc51 ^ (vb51 | ~vd51)) + xk50 + ti51) >> (uint32_t)11U); + abcd[1U] = v50; + uint32_t va51 = abcd[0U]; + uint32_t vb52 = abcd[1U]; + uint32_t vc52 = abcd[2U]; + uint32_t vd52 = abcd[3U]; + uint8_t *b52 = x + (uint32_t)48U; + uint32_t u51 = load32_le(b52); + uint32_t xk51 = u51; + uint32_t ti52 = _t[52U]; + uint32_t + v51 = + vb52 + + + ((va51 + (vc52 ^ (vb52 | ~vd52)) + xk51 + ti52) + << (uint32_t)6U + | (va51 + (vc52 ^ (vb52 | ~vd52)) + xk51 + ti52) >> (uint32_t)26U); + abcd[0U] = v51; + uint32_t va52 = abcd[3U]; + uint32_t vb53 = abcd[0U]; + uint32_t vc53 = abcd[1U]; + uint32_t vd53 = abcd[2U]; + uint8_t *b53 = x + (uint32_t)12U; + uint32_t u52 = load32_le(b53); + uint32_t xk52 = u52; + uint32_t ti53 = _t[53U]; + uint32_t + v52 = + vb53 + + + ((va52 + (vc53 ^ (vb53 | ~vd53)) + xk52 + ti53) + << (uint32_t)10U + | (va52 + (vc53 ^ (vb53 | ~vd53)) + xk52 + ti53) >> (uint32_t)22U); + abcd[3U] = v52; + uint32_t va53 = abcd[2U]; + uint32_t vb54 = abcd[3U]; + uint32_t vc54 = abcd[0U]; + uint32_t vd54 = abcd[1U]; + uint8_t *b54 = x + (uint32_t)40U; + uint32_t u53 = load32_le(b54); + uint32_t xk53 = u53; + uint32_t ti54 = _t[54U]; + uint32_t + v53 = + vb54 + + + ((va53 + (vc54 ^ (vb54 | ~vd54)) + xk53 + ti54) + << (uint32_t)15U + | (va53 + (vc54 ^ (vb54 | ~vd54)) + xk53 + ti54) >> (uint32_t)17U); + abcd[2U] = v53; + uint32_t va54 = abcd[1U]; + uint32_t vb55 = abcd[2U]; + uint32_t vc55 = abcd[3U]; + uint32_t vd55 = abcd[0U]; + uint8_t *b55 = x + (uint32_t)4U; + uint32_t u54 = load32_le(b55); + uint32_t xk54 = u54; + uint32_t ti55 = _t[55U]; + uint32_t + v54 = + vb55 + + + ((va54 + (vc55 ^ (vb55 | ~vd55)) + xk54 + ti55) + << (uint32_t)21U + | (va54 + (vc55 ^ (vb55 | ~vd55)) + xk54 + ti55) >> (uint32_t)11U); + abcd[1U] = v54; + uint32_t va55 = abcd[0U]; + uint32_t vb56 = abcd[1U]; + uint32_t vc56 = abcd[2U]; + uint32_t vd56 = abcd[3U]; + uint8_t *b56 = x + (uint32_t)32U; + uint32_t u55 = load32_le(b56); + uint32_t xk55 = u55; + uint32_t ti56 = _t[56U]; + uint32_t + v55 = + vb56 + + + ((va55 + (vc56 ^ (vb56 | ~vd56)) + xk55 + ti56) + << (uint32_t)6U + | (va55 + (vc56 ^ (vb56 | ~vd56)) + xk55 + ti56) >> (uint32_t)26U); + abcd[0U] = v55; + uint32_t va56 = abcd[3U]; + uint32_t vb57 = abcd[0U]; + uint32_t vc57 = abcd[1U]; + uint32_t vd57 = abcd[2U]; + uint8_t *b57 = x + (uint32_t)60U; + uint32_t u56 = load32_le(b57); + uint32_t xk56 = u56; + uint32_t ti57 = _t[57U]; + uint32_t + v56 = + vb57 + + + ((va56 + (vc57 ^ (vb57 | ~vd57)) + xk56 + ti57) + << (uint32_t)10U + | (va56 + (vc57 ^ (vb57 | ~vd57)) + xk56 + ti57) >> (uint32_t)22U); + abcd[3U] = v56; + uint32_t va57 = abcd[2U]; + uint32_t vb58 = abcd[3U]; + uint32_t vc58 = abcd[0U]; + uint32_t vd58 = abcd[1U]; + uint8_t *b58 = x + (uint32_t)24U; + uint32_t u57 = load32_le(b58); + uint32_t xk57 = u57; + uint32_t ti58 = _t[58U]; + uint32_t + v57 = + vb58 + + + ((va57 + (vc58 ^ (vb58 | ~vd58)) + xk57 + ti58) + << (uint32_t)15U + | (va57 + (vc58 ^ (vb58 | ~vd58)) + xk57 + ti58) >> (uint32_t)17U); + abcd[2U] = v57; + uint32_t va58 = abcd[1U]; + uint32_t vb59 = abcd[2U]; + uint32_t vc59 = abcd[3U]; + uint32_t vd59 = abcd[0U]; + uint8_t *b59 = x + (uint32_t)52U; + uint32_t u58 = load32_le(b59); + uint32_t xk58 = u58; + uint32_t ti59 = _t[59U]; + uint32_t + v58 = + vb59 + + + ((va58 + (vc59 ^ (vb59 | ~vd59)) + xk58 + ti59) + << (uint32_t)21U + | (va58 + (vc59 ^ (vb59 | ~vd59)) + xk58 + ti59) >> (uint32_t)11U); + abcd[1U] = v58; + uint32_t va59 = abcd[0U]; + uint32_t vb60 = abcd[1U]; + uint32_t vc60 = abcd[2U]; + uint32_t vd60 = abcd[3U]; + uint8_t *b60 = x + (uint32_t)16U; + uint32_t u59 = load32_le(b60); + uint32_t xk59 = u59; + uint32_t ti60 = _t[60U]; + uint32_t + v59 = + vb60 + + + ((va59 + (vc60 ^ (vb60 | ~vd60)) + xk59 + ti60) + << (uint32_t)6U + | (va59 + (vc60 ^ (vb60 | ~vd60)) + xk59 + ti60) >> (uint32_t)26U); + abcd[0U] = v59; + uint32_t va60 = abcd[3U]; + uint32_t vb61 = abcd[0U]; + uint32_t vc61 = abcd[1U]; + uint32_t vd61 = abcd[2U]; + uint8_t *b61 = x + (uint32_t)44U; + uint32_t u60 = load32_le(b61); + uint32_t xk60 = u60; + uint32_t ti61 = _t[61U]; + uint32_t + v60 = + vb61 + + + ((va60 + (vc61 ^ (vb61 | ~vd61)) + xk60 + ti61) + << (uint32_t)10U + | (va60 + (vc61 ^ (vb61 | ~vd61)) + xk60 + ti61) >> (uint32_t)22U); + abcd[3U] = v60; + uint32_t va61 = abcd[2U]; + uint32_t vb62 = abcd[3U]; + uint32_t vc62 = abcd[0U]; + uint32_t vd62 = abcd[1U]; + uint8_t *b62 = x + (uint32_t)8U; + uint32_t u61 = load32_le(b62); + uint32_t xk61 = u61; + uint32_t ti62 = _t[62U]; + uint32_t + v61 = + vb62 + + + ((va61 + (vc62 ^ (vb62 | ~vd62)) + xk61 + ti62) + << (uint32_t)15U + | (va61 + (vc62 ^ (vb62 | ~vd62)) + xk61 + ti62) >> (uint32_t)17U); + abcd[2U] = v61; + uint32_t va62 = abcd[1U]; + uint32_t vb = abcd[2U]; + uint32_t vc = abcd[3U]; + uint32_t vd = abcd[0U]; + uint8_t *b63 = x + (uint32_t)36U; + uint32_t u62 = load32_le(b63); + uint32_t xk62 = u62; + uint32_t ti = _t[63U]; + uint32_t + v62 = + vb + + + ((va62 + (vc ^ (vb | ~vd)) + xk62 + ti) + << (uint32_t)21U + | (va62 + (vc ^ (vb | ~vd)) + xk62 + ti) >> (uint32_t)11U); + abcd[1U] = v62; + uint32_t a = abcd[0U]; + uint32_t b = abcd[1U]; + uint32_t c = abcd[2U]; + uint32_t d = abcd[3U]; + abcd[0U] = a + aa; + abcd[1U] = b + bb; + abcd[2U] = c + cc; + abcd[3U] = d + dd; +} + +static void legacy_pad(uint64_t len, uint8_t *dst) +{ + uint8_t *dst1 = dst; + dst1[0U] = (uint8_t)0x80U; + uint8_t *dst2 = dst + (uint32_t)1U; + for + (uint32_t + i = (uint32_t)0U; + i + < ((uint32_t)128U - ((uint32_t)9U + (uint32_t)(len % (uint64_t)(uint32_t)64U))) % (uint32_t)64U; + i++) + { + dst2[i] = (uint8_t)0U; + } + uint8_t + *dst3 = + dst + + + (uint32_t)1U + + + ((uint32_t)128U - ((uint32_t)9U + (uint32_t)(len % (uint64_t)(uint32_t)64U))) + % (uint32_t)64U; + store64_le(dst3, len << (uint32_t)3U); +} + +void Hacl_Hash_Core_MD5_legacy_finish(uint32_t *s, uint8_t *dst) +{ + KRML_MAYBE_FOR4(i, + (uint32_t)0U, + (uint32_t)4U, + (uint32_t)1U, + store32_le(dst + i * (uint32_t)4U, s[i]);); +} + +void Hacl_Hash_MD5_legacy_update_multi(uint32_t *s, uint8_t *blocks, uint32_t n_blocks) +{ + for (uint32_t i = (uint32_t)0U; i < n_blocks; i++) + { + uint32_t sz = (uint32_t)64U; + uint8_t *block = blocks + sz * i; + legacy_update(s, block); + } +} + +void +Hacl_Hash_MD5_legacy_update_last( + uint32_t *s, + uint64_t prev_len, + uint8_t *input, + uint32_t input_len +) +{ + uint32_t blocks_n = input_len / (uint32_t)64U; + uint32_t blocks_len = blocks_n * (uint32_t)64U; + uint8_t *blocks = input; + uint32_t rest_len = input_len - blocks_len; + uint8_t *rest = input + blocks_len; + Hacl_Hash_MD5_legacy_update_multi(s, blocks, blocks_n); + uint64_t total_input_len = prev_len + (uint64_t)input_len; + uint32_t + pad_len = + (uint32_t)1U + + + ((uint32_t)128U - ((uint32_t)9U + (uint32_t)(total_input_len % (uint64_t)(uint32_t)64U))) + % (uint32_t)64U + + (uint32_t)8U; + uint32_t tmp_len = rest_len + pad_len; + uint8_t tmp_twoblocks[128U] = { 0U }; + uint8_t *tmp = tmp_twoblocks; + uint8_t *tmp_rest = tmp; + uint8_t *tmp_pad = tmp + rest_len; + memcpy(tmp_rest, rest, rest_len * sizeof (uint8_t)); + legacy_pad(total_input_len, tmp_pad); + Hacl_Hash_MD5_legacy_update_multi(s, tmp, tmp_len / (uint32_t)64U); +} + +void Hacl_Hash_MD5_legacy_hash(uint8_t *input, uint32_t input_len, uint8_t *dst) +{ + uint32_t + s[4U] = + { (uint32_t)0x67452301U, (uint32_t)0xefcdab89U, (uint32_t)0x98badcfeU, (uint32_t)0x10325476U }; + uint32_t blocks_n0 = input_len / (uint32_t)64U; + uint32_t blocks_n1; + if (input_len % (uint32_t)64U == (uint32_t)0U && blocks_n0 > (uint32_t)0U) + { + blocks_n1 = blocks_n0 - (uint32_t)1U; + } + else + { + blocks_n1 = blocks_n0; + } + uint32_t blocks_len0 = blocks_n1 * (uint32_t)64U; + uint8_t *blocks0 = input; + uint32_t rest_len0 = input_len - blocks_len0; + uint8_t *rest0 = input + blocks_len0; + uint32_t blocks_n = blocks_n1; + uint32_t blocks_len = blocks_len0; + uint8_t *blocks = blocks0; + uint32_t rest_len = rest_len0; + uint8_t *rest = rest0; + Hacl_Hash_MD5_legacy_update_multi(s, blocks, blocks_n); + Hacl_Hash_MD5_legacy_update_last(s, (uint64_t)blocks_len, rest, rest_len); + Hacl_Hash_Core_MD5_legacy_finish(s, dst); +} + +Hacl_Streaming_MD_state_32 *Hacl_Streaming_MD5_legacy_create_in(void) +{ + uint8_t *buf = (uint8_t *)KRML_HOST_CALLOC((uint32_t)64U, sizeof (uint8_t)); + uint32_t *block_state = (uint32_t *)KRML_HOST_CALLOC((uint32_t)4U, sizeof (uint32_t)); + Hacl_Streaming_MD_state_32 + s = { .block_state = block_state, .buf = buf, .total_len = (uint64_t)(uint32_t)0U }; + Hacl_Streaming_MD_state_32 + *p = (Hacl_Streaming_MD_state_32 *)KRML_HOST_MALLOC(sizeof (Hacl_Streaming_MD_state_32)); + p[0U] = s; + Hacl_Hash_Core_MD5_legacy_init(block_state); + return p; +} + +void Hacl_Streaming_MD5_legacy_init(Hacl_Streaming_MD_state_32 *s) +{ + Hacl_Streaming_MD_state_32 scrut = *s; + uint8_t *buf = scrut.buf; + uint32_t *block_state = scrut.block_state; + Hacl_Hash_Core_MD5_legacy_init(block_state); + Hacl_Streaming_MD_state_32 + tmp = { .block_state = block_state, .buf = buf, .total_len = (uint64_t)(uint32_t)0U }; + s[0U] = tmp; +} + +/** +0 = success, 1 = max length exceeded +*/ +Hacl_Streaming_Types_error_code +Hacl_Streaming_MD5_legacy_update(Hacl_Streaming_MD_state_32 *p, uint8_t *data, uint32_t len) +{ + Hacl_Streaming_MD_state_32 s = *p; + uint64_t total_len = s.total_len; + if ((uint64_t)len > (uint64_t)2305843009213693951U - total_len) + { + return Hacl_Streaming_Types_MaximumLengthExceeded; + } + uint32_t sz; + if (total_len % (uint64_t)(uint32_t)64U == (uint64_t)0U && total_len > (uint64_t)0U) + { + sz = (uint32_t)64U; + } + else + { + sz = (uint32_t)(total_len % (uint64_t)(uint32_t)64U); + } + if (len <= (uint32_t)64U - sz) + { + Hacl_Streaming_MD_state_32 s1 = *p; + uint32_t *block_state1 = s1.block_state; + uint8_t *buf = s1.buf; + uint64_t total_len1 = s1.total_len; + uint32_t sz1; + if (total_len1 % (uint64_t)(uint32_t)64U == (uint64_t)0U && total_len1 > (uint64_t)0U) + { + sz1 = (uint32_t)64U; + } + else + { + sz1 = (uint32_t)(total_len1 % (uint64_t)(uint32_t)64U); + } + uint8_t *buf2 = buf + sz1; + memcpy(buf2, data, len * sizeof (uint8_t)); + uint64_t total_len2 = total_len1 + (uint64_t)len; + *p + = + ( + (Hacl_Streaming_MD_state_32){ + .block_state = block_state1, + .buf = buf, + .total_len = total_len2 + } + ); + } + else if (sz == (uint32_t)0U) + { + Hacl_Streaming_MD_state_32 s1 = *p; + uint32_t *block_state1 = s1.block_state; + uint8_t *buf = s1.buf; + uint64_t total_len1 = s1.total_len; + uint32_t sz1; + if (total_len1 % (uint64_t)(uint32_t)64U == (uint64_t)0U && total_len1 > (uint64_t)0U) + { + sz1 = (uint32_t)64U; + } + else + { + sz1 = (uint32_t)(total_len1 % (uint64_t)(uint32_t)64U); + } + if (!(sz1 == (uint32_t)0U)) + { + Hacl_Hash_MD5_legacy_update_multi(block_state1, buf, (uint32_t)1U); + } + uint32_t ite; + if ((uint64_t)len % (uint64_t)(uint32_t)64U == (uint64_t)0U && (uint64_t)len > (uint64_t)0U) + { + ite = (uint32_t)64U; + } + else + { + ite = (uint32_t)((uint64_t)len % (uint64_t)(uint32_t)64U); + } + uint32_t n_blocks = (len - ite) / (uint32_t)64U; + uint32_t data1_len = n_blocks * (uint32_t)64U; + uint32_t data2_len = len - data1_len; + uint8_t *data1 = data; + uint8_t *data2 = data + data1_len; + Hacl_Hash_MD5_legacy_update_multi(block_state1, data1, data1_len / (uint32_t)64U); + uint8_t *dst = buf; + memcpy(dst, data2, data2_len * sizeof (uint8_t)); + *p + = + ( + (Hacl_Streaming_MD_state_32){ + .block_state = block_state1, + .buf = buf, + .total_len = total_len1 + (uint64_t)len + } + ); + } + else + { + uint32_t diff = (uint32_t)64U - sz; + uint8_t *data1 = data; + uint8_t *data2 = data + diff; + Hacl_Streaming_MD_state_32 s1 = *p; + uint32_t *block_state10 = s1.block_state; + uint8_t *buf0 = s1.buf; + uint64_t total_len10 = s1.total_len; + uint32_t sz10; + if (total_len10 % (uint64_t)(uint32_t)64U == (uint64_t)0U && total_len10 > (uint64_t)0U) + { + sz10 = (uint32_t)64U; + } + else + { + sz10 = (uint32_t)(total_len10 % (uint64_t)(uint32_t)64U); + } + uint8_t *buf2 = buf0 + sz10; + memcpy(buf2, data1, diff * sizeof (uint8_t)); + uint64_t total_len2 = total_len10 + (uint64_t)diff; + *p + = + ( + (Hacl_Streaming_MD_state_32){ + .block_state = block_state10, + .buf = buf0, + .total_len = total_len2 + } + ); + Hacl_Streaming_MD_state_32 s10 = *p; + uint32_t *block_state1 = s10.block_state; + uint8_t *buf = s10.buf; + uint64_t total_len1 = s10.total_len; + uint32_t sz1; + if (total_len1 % (uint64_t)(uint32_t)64U == (uint64_t)0U && total_len1 > (uint64_t)0U) + { + sz1 = (uint32_t)64U; + } + else + { + sz1 = (uint32_t)(total_len1 % (uint64_t)(uint32_t)64U); + } + if (!(sz1 == (uint32_t)0U)) + { + Hacl_Hash_MD5_legacy_update_multi(block_state1, buf, (uint32_t)1U); + } + uint32_t ite; + if + ( + (uint64_t)(len - diff) + % (uint64_t)(uint32_t)64U + == (uint64_t)0U + && (uint64_t)(len - diff) > (uint64_t)0U + ) + { + ite = (uint32_t)64U; + } + else + { + ite = (uint32_t)((uint64_t)(len - diff) % (uint64_t)(uint32_t)64U); + } + uint32_t n_blocks = (len - diff - ite) / (uint32_t)64U; + uint32_t data1_len = n_blocks * (uint32_t)64U; + uint32_t data2_len = len - diff - data1_len; + uint8_t *data11 = data2; + uint8_t *data21 = data2 + data1_len; + Hacl_Hash_MD5_legacy_update_multi(block_state1, data11, data1_len / (uint32_t)64U); + uint8_t *dst = buf; + memcpy(dst, data21, data2_len * sizeof (uint8_t)); + *p + = + ( + (Hacl_Streaming_MD_state_32){ + .block_state = block_state1, + .buf = buf, + .total_len = total_len1 + (uint64_t)(len - diff) + } + ); + } + return Hacl_Streaming_Types_Success; +} + +void Hacl_Streaming_MD5_legacy_finish(Hacl_Streaming_MD_state_32 *p, uint8_t *dst) +{ + Hacl_Streaming_MD_state_32 scrut = *p; + uint32_t *block_state = scrut.block_state; + uint8_t *buf_ = scrut.buf; + uint64_t total_len = scrut.total_len; + uint32_t r; + if (total_len % (uint64_t)(uint32_t)64U == (uint64_t)0U && total_len > (uint64_t)0U) + { + r = (uint32_t)64U; + } + else + { + r = (uint32_t)(total_len % (uint64_t)(uint32_t)64U); + } + uint8_t *buf_1 = buf_; + uint32_t tmp_block_state[4U] = { 0U }; + memcpy(tmp_block_state, block_state, (uint32_t)4U * sizeof (uint32_t)); + uint32_t ite; + if (r % (uint32_t)64U == (uint32_t)0U && r > (uint32_t)0U) + { + ite = (uint32_t)64U; + } + else + { + ite = r % (uint32_t)64U; + } + uint8_t *buf_last = buf_1 + r - ite; + uint8_t *buf_multi = buf_1; + Hacl_Hash_MD5_legacy_update_multi(tmp_block_state, buf_multi, (uint32_t)0U); + uint64_t prev_len_last = total_len - (uint64_t)r; + Hacl_Hash_MD5_legacy_update_last(tmp_block_state, prev_len_last, buf_last, r); + Hacl_Hash_Core_MD5_legacy_finish(tmp_block_state, dst); +} + +void Hacl_Streaming_MD5_legacy_free(Hacl_Streaming_MD_state_32 *s) +{ + Hacl_Streaming_MD_state_32 scrut = *s; + uint8_t *buf = scrut.buf; + uint32_t *block_state = scrut.block_state; + KRML_HOST_FREE(block_state); + KRML_HOST_FREE(buf); + KRML_HOST_FREE(s); +} + +Hacl_Streaming_MD_state_32 *Hacl_Streaming_MD5_legacy_copy(Hacl_Streaming_MD_state_32 *s0) +{ + Hacl_Streaming_MD_state_32 scrut = *s0; + uint32_t *block_state0 = scrut.block_state; + uint8_t *buf0 = scrut.buf; + uint64_t total_len0 = scrut.total_len; + uint8_t *buf = (uint8_t *)KRML_HOST_CALLOC((uint32_t)64U, sizeof (uint8_t)); + memcpy(buf, buf0, (uint32_t)64U * sizeof (uint8_t)); + uint32_t *block_state = (uint32_t *)KRML_HOST_CALLOC((uint32_t)4U, sizeof (uint32_t)); + memcpy(block_state, block_state0, (uint32_t)4U * sizeof (uint32_t)); + Hacl_Streaming_MD_state_32 + s = { .block_state = block_state, .buf = buf, .total_len = total_len0 }; + Hacl_Streaming_MD_state_32 + *p = (Hacl_Streaming_MD_state_32 *)KRML_HOST_MALLOC(sizeof (Hacl_Streaming_MD_state_32)); + p[0U] = s; + return p; +} + +void Hacl_Streaming_MD5_legacy_hash(uint8_t *input, uint32_t input_len, uint8_t *dst) +{ + Hacl_Hash_MD5_legacy_hash(input, input_len, dst); +} + diff --git a/Modules/_hacl/Hacl_Hash_MD5.h b/Modules/_hacl/Hacl_Hash_MD5.h new file mode 100644 index 00000000..13c19fd4 --- /dev/null +++ b/Modules/_hacl/Hacl_Hash_MD5.h @@ -0,0 +1,65 @@ +/* MIT License + * + * Copyright (c) 2016-2022 INRIA, CMU and Microsoft Corporation + * Copyright (c) 2022-2023 HACL* Contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + + +#ifndef __Hacl_Hash_MD5_H +#define __Hacl_Hash_MD5_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include <string.h> +#include "krml/types.h" +#include "krml/lowstar_endianness.h" +#include "krml/internal/target.h" + +#include "Hacl_Streaming_Types.h" + +typedef Hacl_Streaming_MD_state_32 Hacl_Streaming_MD5_state; + +Hacl_Streaming_MD_state_32 *Hacl_Streaming_MD5_legacy_create_in(void); + +void Hacl_Streaming_MD5_legacy_init(Hacl_Streaming_MD_state_32 *s); + +/** +0 = success, 1 = max length exceeded +*/ +Hacl_Streaming_Types_error_code +Hacl_Streaming_MD5_legacy_update(Hacl_Streaming_MD_state_32 *p, uint8_t *data, uint32_t len); + +void Hacl_Streaming_MD5_legacy_finish(Hacl_Streaming_MD_state_32 *p, uint8_t *dst); + +void Hacl_Streaming_MD5_legacy_free(Hacl_Streaming_MD_state_32 *s); + +Hacl_Streaming_MD_state_32 *Hacl_Streaming_MD5_legacy_copy(Hacl_Streaming_MD_state_32 *s0); + +void Hacl_Streaming_MD5_legacy_hash(uint8_t *input, uint32_t input_len, uint8_t *dst); + +#if defined(__cplusplus) +} +#endif + +#define __Hacl_Hash_MD5_H_DEFINED +#endif diff --git a/Modules/_hacl/Hacl_Hash_SHA1.c b/Modules/_hacl/Hacl_Hash_SHA1.c new file mode 100644 index 00000000..5ecb3c0b --- /dev/null +++ b/Modules/_hacl/Hacl_Hash_SHA1.c @@ -0,0 +1,508 @@ +/* MIT License + * + * Copyright (c) 2016-2022 INRIA, CMU and Microsoft Corporation + * Copyright (c) 2022-2023 HACL* Contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + + +#include "internal/Hacl_Hash_SHA1.h" + +static uint32_t +_h0[5U] = + { + (uint32_t)0x67452301U, (uint32_t)0xefcdab89U, (uint32_t)0x98badcfeU, (uint32_t)0x10325476U, + (uint32_t)0xc3d2e1f0U + }; + +void Hacl_Hash_Core_SHA1_legacy_init(uint32_t *s) +{ + KRML_MAYBE_FOR5(i, (uint32_t)0U, (uint32_t)5U, (uint32_t)1U, s[i] = _h0[i];); +} + +static void legacy_update(uint32_t *h, uint8_t *l) +{ + uint32_t ha = h[0U]; + uint32_t hb = h[1U]; + uint32_t hc = h[2U]; + uint32_t hd = h[3U]; + uint32_t he = h[4U]; + uint32_t _w[80U] = { 0U }; + for (uint32_t i = (uint32_t)0U; i < (uint32_t)80U; i++) + { + uint32_t v; + if (i < (uint32_t)16U) + { + uint8_t *b = l + i * (uint32_t)4U; + uint32_t u = load32_be(b); + v = u; + } + else + { + uint32_t wmit3 = _w[i - (uint32_t)3U]; + uint32_t wmit8 = _w[i - (uint32_t)8U]; + uint32_t wmit14 = _w[i - (uint32_t)14U]; + uint32_t wmit16 = _w[i - (uint32_t)16U]; + v = + (wmit3 ^ (wmit8 ^ (wmit14 ^ wmit16))) + << (uint32_t)1U + | (wmit3 ^ (wmit8 ^ (wmit14 ^ wmit16))) >> (uint32_t)31U; + } + _w[i] = v; + } + for (uint32_t i = (uint32_t)0U; i < (uint32_t)80U; i++) + { + uint32_t _a = h[0U]; + uint32_t _b = h[1U]; + uint32_t _c = h[2U]; + uint32_t _d = h[3U]; + uint32_t _e = h[4U]; + uint32_t wmit = _w[i]; + uint32_t ite0; + if (i < (uint32_t)20U) + { + ite0 = (_b & _c) ^ (~_b & _d); + } + else if ((uint32_t)39U < i && i < (uint32_t)60U) + { + ite0 = (_b & _c) ^ ((_b & _d) ^ (_c & _d)); + } + else + { + ite0 = _b ^ (_c ^ _d); + } + uint32_t ite; + if (i < (uint32_t)20U) + { + ite = (uint32_t)0x5a827999U; + } + else if (i < (uint32_t)40U) + { + ite = (uint32_t)0x6ed9eba1U; + } + else if (i < (uint32_t)60U) + { + ite = (uint32_t)0x8f1bbcdcU; + } + else + { + ite = (uint32_t)0xca62c1d6U; + } + uint32_t _T = (_a << (uint32_t)5U | _a >> (uint32_t)27U) + ite0 + _e + ite + wmit; + h[0U] = _T; + h[1U] = _a; + h[2U] = _b << (uint32_t)30U | _b >> (uint32_t)2U; + h[3U] = _c; + h[4U] = _d; + } + for (uint32_t i = (uint32_t)0U; i < (uint32_t)80U; i++) + { + _w[i] = (uint32_t)0U; + } + uint32_t sta = h[0U]; + uint32_t stb = h[1U]; + uint32_t stc = h[2U]; + uint32_t std = h[3U]; + uint32_t ste = h[4U]; + h[0U] = sta + ha; + h[1U] = stb + hb; + h[2U] = stc + hc; + h[3U] = std + hd; + h[4U] = ste + he; +} + +static void legacy_pad(uint64_t len, uint8_t *dst) +{ + uint8_t *dst1 = dst; + dst1[0U] = (uint8_t)0x80U; + uint8_t *dst2 = dst + (uint32_t)1U; + for + (uint32_t + i = (uint32_t)0U; + i + < ((uint32_t)128U - ((uint32_t)9U + (uint32_t)(len % (uint64_t)(uint32_t)64U))) % (uint32_t)64U; + i++) + { + dst2[i] = (uint8_t)0U; + } + uint8_t + *dst3 = + dst + + + (uint32_t)1U + + + ((uint32_t)128U - ((uint32_t)9U + (uint32_t)(len % (uint64_t)(uint32_t)64U))) + % (uint32_t)64U; + store64_be(dst3, len << (uint32_t)3U); +} + +void Hacl_Hash_Core_SHA1_legacy_finish(uint32_t *s, uint8_t *dst) +{ + KRML_MAYBE_FOR5(i, + (uint32_t)0U, + (uint32_t)5U, + (uint32_t)1U, + store32_be(dst + i * (uint32_t)4U, s[i]);); +} + +void Hacl_Hash_SHA1_legacy_update_multi(uint32_t *s, uint8_t *blocks, uint32_t n_blocks) +{ + for (uint32_t i = (uint32_t)0U; i < n_blocks; i++) + { + uint32_t sz = (uint32_t)64U; + uint8_t *block = blocks + sz * i; + legacy_update(s, block); + } +} + +void +Hacl_Hash_SHA1_legacy_update_last( + uint32_t *s, + uint64_t prev_len, + uint8_t *input, + uint32_t input_len +) +{ + uint32_t blocks_n = input_len / (uint32_t)64U; + uint32_t blocks_len = blocks_n * (uint32_t)64U; + uint8_t *blocks = input; + uint32_t rest_len = input_len - blocks_len; + uint8_t *rest = input + blocks_len; + Hacl_Hash_SHA1_legacy_update_multi(s, blocks, blocks_n); + uint64_t total_input_len = prev_len + (uint64_t)input_len; + uint32_t + pad_len = + (uint32_t)1U + + + ((uint32_t)128U - ((uint32_t)9U + (uint32_t)(total_input_len % (uint64_t)(uint32_t)64U))) + % (uint32_t)64U + + (uint32_t)8U; + uint32_t tmp_len = rest_len + pad_len; + uint8_t tmp_twoblocks[128U] = { 0U }; + uint8_t *tmp = tmp_twoblocks; + uint8_t *tmp_rest = tmp; + uint8_t *tmp_pad = tmp + rest_len; + memcpy(tmp_rest, rest, rest_len * sizeof (uint8_t)); + legacy_pad(total_input_len, tmp_pad); + Hacl_Hash_SHA1_legacy_update_multi(s, tmp, tmp_len / (uint32_t)64U); +} + +void Hacl_Hash_SHA1_legacy_hash(uint8_t *input, uint32_t input_len, uint8_t *dst) +{ + uint32_t + s[5U] = + { + (uint32_t)0x67452301U, (uint32_t)0xefcdab89U, (uint32_t)0x98badcfeU, (uint32_t)0x10325476U, + (uint32_t)0xc3d2e1f0U + }; + uint32_t blocks_n0 = input_len / (uint32_t)64U; + uint32_t blocks_n1; + if (input_len % (uint32_t)64U == (uint32_t)0U && blocks_n0 > (uint32_t)0U) + { + blocks_n1 = blocks_n0 - (uint32_t)1U; + } + else + { + blocks_n1 = blocks_n0; + } + uint32_t blocks_len0 = blocks_n1 * (uint32_t)64U; + uint8_t *blocks0 = input; + uint32_t rest_len0 = input_len - blocks_len0; + uint8_t *rest0 = input + blocks_len0; + uint32_t blocks_n = blocks_n1; + uint32_t blocks_len = blocks_len0; + uint8_t *blocks = blocks0; + uint32_t rest_len = rest_len0; + uint8_t *rest = rest0; + Hacl_Hash_SHA1_legacy_update_multi(s, blocks, blocks_n); + Hacl_Hash_SHA1_legacy_update_last(s, (uint64_t)blocks_len, rest, rest_len); + Hacl_Hash_Core_SHA1_legacy_finish(s, dst); +} + +Hacl_Streaming_MD_state_32 *Hacl_Streaming_SHA1_legacy_create_in(void) +{ + uint8_t *buf = (uint8_t *)KRML_HOST_CALLOC((uint32_t)64U, sizeof (uint8_t)); + uint32_t *block_state = (uint32_t *)KRML_HOST_CALLOC((uint32_t)5U, sizeof (uint32_t)); + Hacl_Streaming_MD_state_32 + s = { .block_state = block_state, .buf = buf, .total_len = (uint64_t)(uint32_t)0U }; + Hacl_Streaming_MD_state_32 + *p = (Hacl_Streaming_MD_state_32 *)KRML_HOST_MALLOC(sizeof (Hacl_Streaming_MD_state_32)); + p[0U] = s; + Hacl_Hash_Core_SHA1_legacy_init(block_state); + return p; +} + +void Hacl_Streaming_SHA1_legacy_init(Hacl_Streaming_MD_state_32 *s) +{ + Hacl_Streaming_MD_state_32 scrut = *s; + uint8_t *buf = scrut.buf; + uint32_t *block_state = scrut.block_state; + Hacl_Hash_Core_SHA1_legacy_init(block_state); + Hacl_Streaming_MD_state_32 + tmp = { .block_state = block_state, .buf = buf, .total_len = (uint64_t)(uint32_t)0U }; + s[0U] = tmp; +} + +/** +0 = success, 1 = max length exceeded +*/ +Hacl_Streaming_Types_error_code +Hacl_Streaming_SHA1_legacy_update(Hacl_Streaming_MD_state_32 *p, uint8_t *data, uint32_t len) +{ + Hacl_Streaming_MD_state_32 s = *p; + uint64_t total_len = s.total_len; + if ((uint64_t)len > (uint64_t)2305843009213693951U - total_len) + { + return Hacl_Streaming_Types_MaximumLengthExceeded; + } + uint32_t sz; + if (total_len % (uint64_t)(uint32_t)64U == (uint64_t)0U && total_len > (uint64_t)0U) + { + sz = (uint32_t)64U; + } + else + { + sz = (uint32_t)(total_len % (uint64_t)(uint32_t)64U); + } + if (len <= (uint32_t)64U - sz) + { + Hacl_Streaming_MD_state_32 s1 = *p; + uint32_t *block_state1 = s1.block_state; + uint8_t *buf = s1.buf; + uint64_t total_len1 = s1.total_len; + uint32_t sz1; + if (total_len1 % (uint64_t)(uint32_t)64U == (uint64_t)0U && total_len1 > (uint64_t)0U) + { + sz1 = (uint32_t)64U; + } + else + { + sz1 = (uint32_t)(total_len1 % (uint64_t)(uint32_t)64U); + } + uint8_t *buf2 = buf + sz1; + memcpy(buf2, data, len * sizeof (uint8_t)); + uint64_t total_len2 = total_len1 + (uint64_t)len; + *p + = + ( + (Hacl_Streaming_MD_state_32){ + .block_state = block_state1, + .buf = buf, + .total_len = total_len2 + } + ); + } + else if (sz == (uint32_t)0U) + { + Hacl_Streaming_MD_state_32 s1 = *p; + uint32_t *block_state1 = s1.block_state; + uint8_t *buf = s1.buf; + uint64_t total_len1 = s1.total_len; + uint32_t sz1; + if (total_len1 % (uint64_t)(uint32_t)64U == (uint64_t)0U && total_len1 > (uint64_t)0U) + { + sz1 = (uint32_t)64U; + } + else + { + sz1 = (uint32_t)(total_len1 % (uint64_t)(uint32_t)64U); + } + if (!(sz1 == (uint32_t)0U)) + { + Hacl_Hash_SHA1_legacy_update_multi(block_state1, buf, (uint32_t)1U); + } + uint32_t ite; + if ((uint64_t)len % (uint64_t)(uint32_t)64U == (uint64_t)0U && (uint64_t)len > (uint64_t)0U) + { + ite = (uint32_t)64U; + } + else + { + ite = (uint32_t)((uint64_t)len % (uint64_t)(uint32_t)64U); + } + uint32_t n_blocks = (len - ite) / (uint32_t)64U; + uint32_t data1_len = n_blocks * (uint32_t)64U; + uint32_t data2_len = len - data1_len; + uint8_t *data1 = data; + uint8_t *data2 = data + data1_len; + Hacl_Hash_SHA1_legacy_update_multi(block_state1, data1, data1_len / (uint32_t)64U); + uint8_t *dst = buf; + memcpy(dst, data2, data2_len * sizeof (uint8_t)); + *p + = + ( + (Hacl_Streaming_MD_state_32){ + .block_state = block_state1, + .buf = buf, + .total_len = total_len1 + (uint64_t)len + } + ); + } + else + { + uint32_t diff = (uint32_t)64U - sz; + uint8_t *data1 = data; + uint8_t *data2 = data + diff; + Hacl_Streaming_MD_state_32 s1 = *p; + uint32_t *block_state10 = s1.block_state; + uint8_t *buf0 = s1.buf; + uint64_t total_len10 = s1.total_len; + uint32_t sz10; + if (total_len10 % (uint64_t)(uint32_t)64U == (uint64_t)0U && total_len10 > (uint64_t)0U) + { + sz10 = (uint32_t)64U; + } + else + { + sz10 = (uint32_t)(total_len10 % (uint64_t)(uint32_t)64U); + } + uint8_t *buf2 = buf0 + sz10; + memcpy(buf2, data1, diff * sizeof (uint8_t)); + uint64_t total_len2 = total_len10 + (uint64_t)diff; + *p + = + ( + (Hacl_Streaming_MD_state_32){ + .block_state = block_state10, + .buf = buf0, + .total_len = total_len2 + } + ); + Hacl_Streaming_MD_state_32 s10 = *p; + uint32_t *block_state1 = s10.block_state; + uint8_t *buf = s10.buf; + uint64_t total_len1 = s10.total_len; + uint32_t sz1; + if (total_len1 % (uint64_t)(uint32_t)64U == (uint64_t)0U && total_len1 > (uint64_t)0U) + { + sz1 = (uint32_t)64U; + } + else + { + sz1 = (uint32_t)(total_len1 % (uint64_t)(uint32_t)64U); + } + if (!(sz1 == (uint32_t)0U)) + { + Hacl_Hash_SHA1_legacy_update_multi(block_state1, buf, (uint32_t)1U); + } + uint32_t ite; + if + ( + (uint64_t)(len - diff) + % (uint64_t)(uint32_t)64U + == (uint64_t)0U + && (uint64_t)(len - diff) > (uint64_t)0U + ) + { + ite = (uint32_t)64U; + } + else + { + ite = (uint32_t)((uint64_t)(len - diff) % (uint64_t)(uint32_t)64U); + } + uint32_t n_blocks = (len - diff - ite) / (uint32_t)64U; + uint32_t data1_len = n_blocks * (uint32_t)64U; + uint32_t data2_len = len - diff - data1_len; + uint8_t *data11 = data2; + uint8_t *data21 = data2 + data1_len; + Hacl_Hash_SHA1_legacy_update_multi(block_state1, data11, data1_len / (uint32_t)64U); + uint8_t *dst = buf; + memcpy(dst, data21, data2_len * sizeof (uint8_t)); + *p + = + ( + (Hacl_Streaming_MD_state_32){ + .block_state = block_state1, + .buf = buf, + .total_len = total_len1 + (uint64_t)(len - diff) + } + ); + } + return Hacl_Streaming_Types_Success; +} + +void Hacl_Streaming_SHA1_legacy_finish(Hacl_Streaming_MD_state_32 *p, uint8_t *dst) +{ + Hacl_Streaming_MD_state_32 scrut = *p; + uint32_t *block_state = scrut.block_state; + uint8_t *buf_ = scrut.buf; + uint64_t total_len = scrut.total_len; + uint32_t r; + if (total_len % (uint64_t)(uint32_t)64U == (uint64_t)0U && total_len > (uint64_t)0U) + { + r = (uint32_t)64U; + } + else + { + r = (uint32_t)(total_len % (uint64_t)(uint32_t)64U); + } + uint8_t *buf_1 = buf_; + uint32_t tmp_block_state[5U] = { 0U }; + memcpy(tmp_block_state, block_state, (uint32_t)5U * sizeof (uint32_t)); + uint32_t ite; + if (r % (uint32_t)64U == (uint32_t)0U && r > (uint32_t)0U) + { + ite = (uint32_t)64U; + } + else + { + ite = r % (uint32_t)64U; + } + uint8_t *buf_last = buf_1 + r - ite; + uint8_t *buf_multi = buf_1; + Hacl_Hash_SHA1_legacy_update_multi(tmp_block_state, buf_multi, (uint32_t)0U); + uint64_t prev_len_last = total_len - (uint64_t)r; + Hacl_Hash_SHA1_legacy_update_last(tmp_block_state, prev_len_last, buf_last, r); + Hacl_Hash_Core_SHA1_legacy_finish(tmp_block_state, dst); +} + +void Hacl_Streaming_SHA1_legacy_free(Hacl_Streaming_MD_state_32 *s) +{ + Hacl_Streaming_MD_state_32 scrut = *s; + uint8_t *buf = scrut.buf; + uint32_t *block_state = scrut.block_state; + KRML_HOST_FREE(block_state); + KRML_HOST_FREE(buf); + KRML_HOST_FREE(s); +} + +Hacl_Streaming_MD_state_32 *Hacl_Streaming_SHA1_legacy_copy(Hacl_Streaming_MD_state_32 *s0) +{ + Hacl_Streaming_MD_state_32 scrut = *s0; + uint32_t *block_state0 = scrut.block_state; + uint8_t *buf0 = scrut.buf; + uint64_t total_len0 = scrut.total_len; + uint8_t *buf = (uint8_t *)KRML_HOST_CALLOC((uint32_t)64U, sizeof (uint8_t)); + memcpy(buf, buf0, (uint32_t)64U * sizeof (uint8_t)); + uint32_t *block_state = (uint32_t *)KRML_HOST_CALLOC((uint32_t)5U, sizeof (uint32_t)); + memcpy(block_state, block_state0, (uint32_t)5U * sizeof (uint32_t)); + Hacl_Streaming_MD_state_32 + s = { .block_state = block_state, .buf = buf, .total_len = total_len0 }; + Hacl_Streaming_MD_state_32 + *p = (Hacl_Streaming_MD_state_32 *)KRML_HOST_MALLOC(sizeof (Hacl_Streaming_MD_state_32)); + p[0U] = s; + return p; +} + +void Hacl_Streaming_SHA1_legacy_hash(uint8_t *input, uint32_t input_len, uint8_t *dst) +{ + Hacl_Hash_SHA1_legacy_hash(input, input_len, dst); +} + diff --git a/Modules/_hacl/Hacl_Hash_SHA1.h b/Modules/_hacl/Hacl_Hash_SHA1.h new file mode 100644 index 00000000..dc50aa6f --- /dev/null +++ b/Modules/_hacl/Hacl_Hash_SHA1.h @@ -0,0 +1,65 @@ +/* MIT License + * + * Copyright (c) 2016-2022 INRIA, CMU and Microsoft Corporation + * Copyright (c) 2022-2023 HACL* Contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + + +#ifndef __Hacl_Hash_SHA1_H +#define __Hacl_Hash_SHA1_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include <string.h> +#include "krml/types.h" +#include "krml/lowstar_endianness.h" +#include "krml/internal/target.h" + +#include "Hacl_Streaming_Types.h" + +typedef Hacl_Streaming_MD_state_32 Hacl_Streaming_SHA1_state; + +Hacl_Streaming_MD_state_32 *Hacl_Streaming_SHA1_legacy_create_in(void); + +void Hacl_Streaming_SHA1_legacy_init(Hacl_Streaming_MD_state_32 *s); + +/** +0 = success, 1 = max length exceeded +*/ +Hacl_Streaming_Types_error_code +Hacl_Streaming_SHA1_legacy_update(Hacl_Streaming_MD_state_32 *p, uint8_t *data, uint32_t len); + +void Hacl_Streaming_SHA1_legacy_finish(Hacl_Streaming_MD_state_32 *p, uint8_t *dst); + +void Hacl_Streaming_SHA1_legacy_free(Hacl_Streaming_MD_state_32 *s); + +Hacl_Streaming_MD_state_32 *Hacl_Streaming_SHA1_legacy_copy(Hacl_Streaming_MD_state_32 *s0); + +void Hacl_Streaming_SHA1_legacy_hash(uint8_t *input, uint32_t input_len, uint8_t *dst); + +#if defined(__cplusplus) +} +#endif + +#define __Hacl_Hash_SHA1_H_DEFINED +#endif diff --git a/Modules/_hacl/Hacl_Hash_SHA2.c b/Modules/_hacl/Hacl_Hash_SHA2.c new file mode 100644 index 00000000..08e3f7ed --- /dev/null +++ b/Modules/_hacl/Hacl_Hash_SHA2.c @@ -0,0 +1,1345 @@ +/* MIT License + * + * Copyright (c) 2016-2022 INRIA, CMU and Microsoft Corporation + * Copyright (c) 2022-2023 HACL* Contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + + +#include "internal/Hacl_Hash_SHA2.h" + + + +void Hacl_SHA2_Scalar32_sha256_init(uint32_t *hash) +{ + KRML_MAYBE_FOR8(i, + (uint32_t)0U, + (uint32_t)8U, + (uint32_t)1U, + uint32_t *os = hash; + uint32_t x = Hacl_Impl_SHA2_Generic_h256[i]; + os[i] = x;); +} + +static inline void sha256_update(uint8_t *b, uint32_t *hash) +{ + uint32_t hash_old[8U] = { 0U }; + uint32_t ws[16U] = { 0U }; + memcpy(hash_old, hash, (uint32_t)8U * sizeof (uint32_t)); + uint8_t *b10 = b; + uint32_t u = load32_be(b10); + ws[0U] = u; + uint32_t u0 = load32_be(b10 + (uint32_t)4U); + ws[1U] = u0; + uint32_t u1 = load32_be(b10 + (uint32_t)8U); + ws[2U] = u1; + uint32_t u2 = load32_be(b10 + (uint32_t)12U); + ws[3U] = u2; + uint32_t u3 = load32_be(b10 + (uint32_t)16U); + ws[4U] = u3; + uint32_t u4 = load32_be(b10 + (uint32_t)20U); + ws[5U] = u4; + uint32_t u5 = load32_be(b10 + (uint32_t)24U); + ws[6U] = u5; + uint32_t u6 = load32_be(b10 + (uint32_t)28U); + ws[7U] = u6; + uint32_t u7 = load32_be(b10 + (uint32_t)32U); + ws[8U] = u7; + uint32_t u8 = load32_be(b10 + (uint32_t)36U); + ws[9U] = u8; + uint32_t u9 = load32_be(b10 + (uint32_t)40U); + ws[10U] = u9; + uint32_t u10 = load32_be(b10 + (uint32_t)44U); + ws[11U] = u10; + uint32_t u11 = load32_be(b10 + (uint32_t)48U); + ws[12U] = u11; + uint32_t u12 = load32_be(b10 + (uint32_t)52U); + ws[13U] = u12; + uint32_t u13 = load32_be(b10 + (uint32_t)56U); + ws[14U] = u13; + uint32_t u14 = load32_be(b10 + (uint32_t)60U); + ws[15U] = u14; + KRML_MAYBE_FOR4(i0, + (uint32_t)0U, + (uint32_t)4U, + (uint32_t)1U, + KRML_MAYBE_FOR16(i, + (uint32_t)0U, + (uint32_t)16U, + (uint32_t)1U, + uint32_t k_t = Hacl_Impl_SHA2_Generic_k224_256[(uint32_t)16U * i0 + i]; + uint32_t ws_t = ws[i]; + uint32_t a0 = hash[0U]; + uint32_t b0 = hash[1U]; + uint32_t c0 = hash[2U]; + uint32_t d0 = hash[3U]; + uint32_t e0 = hash[4U]; + uint32_t f0 = hash[5U]; + uint32_t g0 = hash[6U]; + uint32_t h02 = hash[7U]; + uint32_t k_e_t = k_t; + uint32_t + t1 = + h02 + + + ((e0 << (uint32_t)26U | e0 >> (uint32_t)6U) + ^ + ((e0 << (uint32_t)21U | e0 >> (uint32_t)11U) + ^ (e0 << (uint32_t)7U | e0 >> (uint32_t)25U))) + + ((e0 & f0) ^ (~e0 & g0)) + + k_e_t + + ws_t; + uint32_t + t2 = + ((a0 << (uint32_t)30U | a0 >> (uint32_t)2U) + ^ + ((a0 << (uint32_t)19U | a0 >> (uint32_t)13U) + ^ (a0 << (uint32_t)10U | a0 >> (uint32_t)22U))) + + ((a0 & b0) ^ ((a0 & c0) ^ (b0 & c0))); + uint32_t a1 = t1 + t2; + uint32_t b1 = a0; + uint32_t c1 = b0; + uint32_t d1 = c0; + uint32_t e1 = d0 + t1; + uint32_t f1 = e0; + uint32_t g1 = f0; + uint32_t h12 = g0; + hash[0U] = a1; + hash[1U] = b1; + hash[2U] = c1; + hash[3U] = d1; + hash[4U] = e1; + hash[5U] = f1; + hash[6U] = g1; + hash[7U] = h12;); + if (i0 < (uint32_t)3U) + { + KRML_MAYBE_FOR16(i, + (uint32_t)0U, + (uint32_t)16U, + (uint32_t)1U, + uint32_t t16 = ws[i]; + uint32_t t15 = ws[(i + (uint32_t)1U) % (uint32_t)16U]; + uint32_t t7 = ws[(i + (uint32_t)9U) % (uint32_t)16U]; + uint32_t t2 = ws[(i + (uint32_t)14U) % (uint32_t)16U]; + uint32_t + s1 = + (t2 << (uint32_t)15U | t2 >> (uint32_t)17U) + ^ ((t2 << (uint32_t)13U | t2 >> (uint32_t)19U) ^ t2 >> (uint32_t)10U); + uint32_t + s0 = + (t15 << (uint32_t)25U | t15 >> (uint32_t)7U) + ^ ((t15 << (uint32_t)14U | t15 >> (uint32_t)18U) ^ t15 >> (uint32_t)3U); + ws[i] = s1 + t7 + s0 + t16;); + }); + KRML_MAYBE_FOR8(i, + (uint32_t)0U, + (uint32_t)8U, + (uint32_t)1U, + uint32_t *os = hash; + uint32_t x = hash[i] + hash_old[i]; + os[i] = x;); +} + +void Hacl_SHA2_Scalar32_sha256_update_nblocks(uint32_t len, uint8_t *b, uint32_t *st) +{ + uint32_t blocks = len / (uint32_t)64U; + for (uint32_t i = (uint32_t)0U; i < blocks; i++) + { + uint8_t *b0 = b; + uint8_t *mb = b0 + i * (uint32_t)64U; + sha256_update(mb, st); + } +} + +void +Hacl_SHA2_Scalar32_sha256_update_last( + uint64_t totlen, + uint32_t len, + uint8_t *b, + uint32_t *hash +) +{ + uint32_t blocks; + if (len + (uint32_t)8U + (uint32_t)1U <= (uint32_t)64U) + { + blocks = (uint32_t)1U; + } + else + { + blocks = (uint32_t)2U; + } + uint32_t fin = blocks * (uint32_t)64U; + uint8_t last[128U] = { 0U }; + uint8_t totlen_buf[8U] = { 0U }; + uint64_t total_len_bits = totlen << (uint32_t)3U; + store64_be(totlen_buf, total_len_bits); + uint8_t *b0 = b; + memcpy(last, b0, len * sizeof (uint8_t)); + last[len] = (uint8_t)0x80U; + memcpy(last + fin - (uint32_t)8U, totlen_buf, (uint32_t)8U * sizeof (uint8_t)); + uint8_t *last00 = last; + uint8_t *last10 = last + (uint32_t)64U; + uint8_t *l0 = last00; + uint8_t *l1 = last10; + uint8_t *lb0 = l0; + uint8_t *lb1 = l1; + uint8_t *last0 = lb0; + uint8_t *last1 = lb1; + sha256_update(last0, hash); + if (blocks > (uint32_t)1U) + { + sha256_update(last1, hash); + return; + } +} + +void Hacl_SHA2_Scalar32_sha256_finish(uint32_t *st, uint8_t *h) +{ + uint8_t hbuf[32U] = { 0U }; + KRML_MAYBE_FOR8(i, + (uint32_t)0U, + (uint32_t)8U, + (uint32_t)1U, + store32_be(hbuf + i * (uint32_t)4U, st[i]);); + memcpy(h, hbuf, (uint32_t)32U * sizeof (uint8_t)); +} + +void Hacl_SHA2_Scalar32_sha224_init(uint32_t *hash) +{ + KRML_MAYBE_FOR8(i, + (uint32_t)0U, + (uint32_t)8U, + (uint32_t)1U, + uint32_t *os = hash; + uint32_t x = Hacl_Impl_SHA2_Generic_h224[i]; + os[i] = x;); +} + +static inline void sha224_update_nblocks(uint32_t len, uint8_t *b, uint32_t *st) +{ + Hacl_SHA2_Scalar32_sha256_update_nblocks(len, b, st); +} + +void +Hacl_SHA2_Scalar32_sha224_update_last(uint64_t totlen, uint32_t len, uint8_t *b, uint32_t *st) +{ + Hacl_SHA2_Scalar32_sha256_update_last(totlen, len, b, st); +} + +void Hacl_SHA2_Scalar32_sha224_finish(uint32_t *st, uint8_t *h) +{ + uint8_t hbuf[32U] = { 0U }; + KRML_MAYBE_FOR8(i, + (uint32_t)0U, + (uint32_t)8U, + (uint32_t)1U, + store32_be(hbuf + i * (uint32_t)4U, st[i]);); + memcpy(h, hbuf, (uint32_t)28U * sizeof (uint8_t)); +} + +void Hacl_SHA2_Scalar32_sha512_init(uint64_t *hash) +{ + KRML_MAYBE_FOR8(i, + (uint32_t)0U, + (uint32_t)8U, + (uint32_t)1U, + uint64_t *os = hash; + uint64_t x = Hacl_Impl_SHA2_Generic_h512[i]; + os[i] = x;); +} + +static inline void sha512_update(uint8_t *b, uint64_t *hash) +{ + uint64_t hash_old[8U] = { 0U }; + uint64_t ws[16U] = { 0U }; + memcpy(hash_old, hash, (uint32_t)8U * sizeof (uint64_t)); + uint8_t *b10 = b; + uint64_t u = load64_be(b10); + ws[0U] = u; + uint64_t u0 = load64_be(b10 + (uint32_t)8U); + ws[1U] = u0; + uint64_t u1 = load64_be(b10 + (uint32_t)16U); + ws[2U] = u1; + uint64_t u2 = load64_be(b10 + (uint32_t)24U); + ws[3U] = u2; + uint64_t u3 = load64_be(b10 + (uint32_t)32U); + ws[4U] = u3; + uint64_t u4 = load64_be(b10 + (uint32_t)40U); + ws[5U] = u4; + uint64_t u5 = load64_be(b10 + (uint32_t)48U); + ws[6U] = u5; + uint64_t u6 = load64_be(b10 + (uint32_t)56U); + ws[7U] = u6; + uint64_t u7 = load64_be(b10 + (uint32_t)64U); + ws[8U] = u7; + uint64_t u8 = load64_be(b10 + (uint32_t)72U); + ws[9U] = u8; + uint64_t u9 = load64_be(b10 + (uint32_t)80U); + ws[10U] = u9; + uint64_t u10 = load64_be(b10 + (uint32_t)88U); + ws[11U] = u10; + uint64_t u11 = load64_be(b10 + (uint32_t)96U); + ws[12U] = u11; + uint64_t u12 = load64_be(b10 + (uint32_t)104U); + ws[13U] = u12; + uint64_t u13 = load64_be(b10 + (uint32_t)112U); + ws[14U] = u13; + uint64_t u14 = load64_be(b10 + (uint32_t)120U); + ws[15U] = u14; + KRML_MAYBE_FOR5(i0, + (uint32_t)0U, + (uint32_t)5U, + (uint32_t)1U, + KRML_MAYBE_FOR16(i, + (uint32_t)0U, + (uint32_t)16U, + (uint32_t)1U, + uint64_t k_t = Hacl_Impl_SHA2_Generic_k384_512[(uint32_t)16U * i0 + i]; + uint64_t ws_t = ws[i]; + uint64_t a0 = hash[0U]; + uint64_t b0 = hash[1U]; + uint64_t c0 = hash[2U]; + uint64_t d0 = hash[3U]; + uint64_t e0 = hash[4U]; + uint64_t f0 = hash[5U]; + uint64_t g0 = hash[6U]; + uint64_t h02 = hash[7U]; + uint64_t k_e_t = k_t; + uint64_t + t1 = + h02 + + + ((e0 << (uint32_t)50U | e0 >> (uint32_t)14U) + ^ + ((e0 << (uint32_t)46U | e0 >> (uint32_t)18U) + ^ (e0 << (uint32_t)23U | e0 >> (uint32_t)41U))) + + ((e0 & f0) ^ (~e0 & g0)) + + k_e_t + + ws_t; + uint64_t + t2 = + ((a0 << (uint32_t)36U | a0 >> (uint32_t)28U) + ^ + ((a0 << (uint32_t)30U | a0 >> (uint32_t)34U) + ^ (a0 << (uint32_t)25U | a0 >> (uint32_t)39U))) + + ((a0 & b0) ^ ((a0 & c0) ^ (b0 & c0))); + uint64_t a1 = t1 + t2; + uint64_t b1 = a0; + uint64_t c1 = b0; + uint64_t d1 = c0; + uint64_t e1 = d0 + t1; + uint64_t f1 = e0; + uint64_t g1 = f0; + uint64_t h12 = g0; + hash[0U] = a1; + hash[1U] = b1; + hash[2U] = c1; + hash[3U] = d1; + hash[4U] = e1; + hash[5U] = f1; + hash[6U] = g1; + hash[7U] = h12;); + if (i0 < (uint32_t)4U) + { + KRML_MAYBE_FOR16(i, + (uint32_t)0U, + (uint32_t)16U, + (uint32_t)1U, + uint64_t t16 = ws[i]; + uint64_t t15 = ws[(i + (uint32_t)1U) % (uint32_t)16U]; + uint64_t t7 = ws[(i + (uint32_t)9U) % (uint32_t)16U]; + uint64_t t2 = ws[(i + (uint32_t)14U) % (uint32_t)16U]; + uint64_t + s1 = + (t2 << (uint32_t)45U | t2 >> (uint32_t)19U) + ^ ((t2 << (uint32_t)3U | t2 >> (uint32_t)61U) ^ t2 >> (uint32_t)6U); + uint64_t + s0 = + (t15 << (uint32_t)63U | t15 >> (uint32_t)1U) + ^ ((t15 << (uint32_t)56U | t15 >> (uint32_t)8U) ^ t15 >> (uint32_t)7U); + ws[i] = s1 + t7 + s0 + t16;); + }); + KRML_MAYBE_FOR8(i, + (uint32_t)0U, + (uint32_t)8U, + (uint32_t)1U, + uint64_t *os = hash; + uint64_t x = hash[i] + hash_old[i]; + os[i] = x;); +} + +void Hacl_SHA2_Scalar32_sha512_update_nblocks(uint32_t len, uint8_t *b, uint64_t *st) +{ + uint32_t blocks = len / (uint32_t)128U; + for (uint32_t i = (uint32_t)0U; i < blocks; i++) + { + uint8_t *b0 = b; + uint8_t *mb = b0 + i * (uint32_t)128U; + sha512_update(mb, st); + } +} + +void +Hacl_SHA2_Scalar32_sha512_update_last( + FStar_UInt128_uint128 totlen, + uint32_t len, + uint8_t *b, + uint64_t *hash +) +{ + uint32_t blocks; + if (len + (uint32_t)16U + (uint32_t)1U <= (uint32_t)128U) + { + blocks = (uint32_t)1U; + } + else + { + blocks = (uint32_t)2U; + } + uint32_t fin = blocks * (uint32_t)128U; + uint8_t last[256U] = { 0U }; + uint8_t totlen_buf[16U] = { 0U }; + FStar_UInt128_uint128 total_len_bits = FStar_UInt128_shift_left(totlen, (uint32_t)3U); + store128_be(totlen_buf, total_len_bits); + uint8_t *b0 = b; + memcpy(last, b0, len * sizeof (uint8_t)); + last[len] = (uint8_t)0x80U; + memcpy(last + fin - (uint32_t)16U, totlen_buf, (uint32_t)16U * sizeof (uint8_t)); + uint8_t *last00 = last; + uint8_t *last10 = last + (uint32_t)128U; + uint8_t *l0 = last00; + uint8_t *l1 = last10; + uint8_t *lb0 = l0; + uint8_t *lb1 = l1; + uint8_t *last0 = lb0; + uint8_t *last1 = lb1; + sha512_update(last0, hash); + if (blocks > (uint32_t)1U) + { + sha512_update(last1, hash); + return; + } +} + +void Hacl_SHA2_Scalar32_sha512_finish(uint64_t *st, uint8_t *h) +{ + uint8_t hbuf[64U] = { 0U }; + KRML_MAYBE_FOR8(i, + (uint32_t)0U, + (uint32_t)8U, + (uint32_t)1U, + store64_be(hbuf + i * (uint32_t)8U, st[i]);); + memcpy(h, hbuf, (uint32_t)64U * sizeof (uint8_t)); +} + +void Hacl_SHA2_Scalar32_sha384_init(uint64_t *hash) +{ + KRML_MAYBE_FOR8(i, + (uint32_t)0U, + (uint32_t)8U, + (uint32_t)1U, + uint64_t *os = hash; + uint64_t x = Hacl_Impl_SHA2_Generic_h384[i]; + os[i] = x;); +} + +void Hacl_SHA2_Scalar32_sha384_update_nblocks(uint32_t len, uint8_t *b, uint64_t *st) +{ + Hacl_SHA2_Scalar32_sha512_update_nblocks(len, b, st); +} + +void +Hacl_SHA2_Scalar32_sha384_update_last( + FStar_UInt128_uint128 totlen, + uint32_t len, + uint8_t *b, + uint64_t *st +) +{ + Hacl_SHA2_Scalar32_sha512_update_last(totlen, len, b, st); +} + +void Hacl_SHA2_Scalar32_sha384_finish(uint64_t *st, uint8_t *h) +{ + uint8_t hbuf[64U] = { 0U }; + KRML_MAYBE_FOR8(i, + (uint32_t)0U, + (uint32_t)8U, + (uint32_t)1U, + store64_be(hbuf + i * (uint32_t)8U, st[i]);); + memcpy(h, hbuf, (uint32_t)48U * sizeof (uint8_t)); +} + +/** +Allocate initial state for the SHA2_256 hash. The state is to be freed by +calling `free_256`. +*/ +Hacl_Streaming_MD_state_32 *Hacl_Streaming_SHA2_create_in_256(void) +{ + uint8_t *buf = (uint8_t *)KRML_HOST_CALLOC((uint32_t)64U, sizeof (uint8_t)); + uint32_t *block_state = (uint32_t *)KRML_HOST_CALLOC((uint32_t)8U, sizeof (uint32_t)); + Hacl_Streaming_MD_state_32 + s = { .block_state = block_state, .buf = buf, .total_len = (uint64_t)(uint32_t)0U }; + Hacl_Streaming_MD_state_32 + *p = (Hacl_Streaming_MD_state_32 *)KRML_HOST_MALLOC(sizeof (Hacl_Streaming_MD_state_32)); + p[0U] = s; + Hacl_SHA2_Scalar32_sha256_init(block_state); + return p; +} + +/** +Copies the state passed as argument into a newly allocated state (deep copy). +The state is to be freed by calling `free_256`. Cloning the state this way is +useful, for instance, if your control-flow diverges and you need to feed +more (different) data into the hash in each branch. +*/ +Hacl_Streaming_MD_state_32 *Hacl_Streaming_SHA2_copy_256(Hacl_Streaming_MD_state_32 *s0) +{ + Hacl_Streaming_MD_state_32 scrut = *s0; + uint32_t *block_state0 = scrut.block_state; + uint8_t *buf0 = scrut.buf; + uint64_t total_len0 = scrut.total_len; + uint8_t *buf = (uint8_t *)KRML_HOST_CALLOC((uint32_t)64U, sizeof (uint8_t)); + memcpy(buf, buf0, (uint32_t)64U * sizeof (uint8_t)); + uint32_t *block_state = (uint32_t *)KRML_HOST_CALLOC((uint32_t)8U, sizeof (uint32_t)); + memcpy(block_state, block_state0, (uint32_t)8U * sizeof (uint32_t)); + Hacl_Streaming_MD_state_32 + s = { .block_state = block_state, .buf = buf, .total_len = total_len0 }; + Hacl_Streaming_MD_state_32 + *p = (Hacl_Streaming_MD_state_32 *)KRML_HOST_MALLOC(sizeof (Hacl_Streaming_MD_state_32)); + p[0U] = s; + return p; +} + +/** +Reset an existing state to the initial hash state with empty data. +*/ +void Hacl_Streaming_SHA2_init_256(Hacl_Streaming_MD_state_32 *s) +{ + Hacl_Streaming_MD_state_32 scrut = *s; + uint8_t *buf = scrut.buf; + uint32_t *block_state = scrut.block_state; + Hacl_SHA2_Scalar32_sha256_init(block_state); + Hacl_Streaming_MD_state_32 + tmp = { .block_state = block_state, .buf = buf, .total_len = (uint64_t)(uint32_t)0U }; + s[0U] = tmp; +} + +static inline Hacl_Streaming_Types_error_code +update_224_256(Hacl_Streaming_MD_state_32 *p, uint8_t *data, uint32_t len) +{ + Hacl_Streaming_MD_state_32 s = *p; + uint64_t total_len = s.total_len; + if ((uint64_t)len > (uint64_t)2305843009213693951U - total_len) + { + return Hacl_Streaming_Types_MaximumLengthExceeded; + } + uint32_t sz; + if (total_len % (uint64_t)(uint32_t)64U == (uint64_t)0U && total_len > (uint64_t)0U) + { + sz = (uint32_t)64U; + } + else + { + sz = (uint32_t)(total_len % (uint64_t)(uint32_t)64U); + } + if (len <= (uint32_t)64U - sz) + { + Hacl_Streaming_MD_state_32 s1 = *p; + uint32_t *block_state1 = s1.block_state; + uint8_t *buf = s1.buf; + uint64_t total_len1 = s1.total_len; + uint32_t sz1; + if (total_len1 % (uint64_t)(uint32_t)64U == (uint64_t)0U && total_len1 > (uint64_t)0U) + { + sz1 = (uint32_t)64U; + } + else + { + sz1 = (uint32_t)(total_len1 % (uint64_t)(uint32_t)64U); + } + uint8_t *buf2 = buf + sz1; + memcpy(buf2, data, len * sizeof (uint8_t)); + uint64_t total_len2 = total_len1 + (uint64_t)len; + *p + = + ( + (Hacl_Streaming_MD_state_32){ + .block_state = block_state1, + .buf = buf, + .total_len = total_len2 + } + ); + } + else if (sz == (uint32_t)0U) + { + Hacl_Streaming_MD_state_32 s1 = *p; + uint32_t *block_state1 = s1.block_state; + uint8_t *buf = s1.buf; + uint64_t total_len1 = s1.total_len; + uint32_t sz1; + if (total_len1 % (uint64_t)(uint32_t)64U == (uint64_t)0U && total_len1 > (uint64_t)0U) + { + sz1 = (uint32_t)64U; + } + else + { + sz1 = (uint32_t)(total_len1 % (uint64_t)(uint32_t)64U); + } + if (!(sz1 == (uint32_t)0U)) + { + Hacl_SHA2_Scalar32_sha256_update_nblocks((uint32_t)64U, buf, block_state1); + } + uint32_t ite; + if ((uint64_t)len % (uint64_t)(uint32_t)64U == (uint64_t)0U && (uint64_t)len > (uint64_t)0U) + { + ite = (uint32_t)64U; + } + else + { + ite = (uint32_t)((uint64_t)len % (uint64_t)(uint32_t)64U); + } + uint32_t n_blocks = (len - ite) / (uint32_t)64U; + uint32_t data1_len = n_blocks * (uint32_t)64U; + uint32_t data2_len = len - data1_len; + uint8_t *data1 = data; + uint8_t *data2 = data + data1_len; + Hacl_SHA2_Scalar32_sha256_update_nblocks(data1_len / (uint32_t)64U * (uint32_t)64U, + data1, + block_state1); + uint8_t *dst = buf; + memcpy(dst, data2, data2_len * sizeof (uint8_t)); + *p + = + ( + (Hacl_Streaming_MD_state_32){ + .block_state = block_state1, + .buf = buf, + .total_len = total_len1 + (uint64_t)len + } + ); + } + else + { + uint32_t diff = (uint32_t)64U - sz; + uint8_t *data1 = data; + uint8_t *data2 = data + diff; + Hacl_Streaming_MD_state_32 s1 = *p; + uint32_t *block_state10 = s1.block_state; + uint8_t *buf0 = s1.buf; + uint64_t total_len10 = s1.total_len; + uint32_t sz10; + if (total_len10 % (uint64_t)(uint32_t)64U == (uint64_t)0U && total_len10 > (uint64_t)0U) + { + sz10 = (uint32_t)64U; + } + else + { + sz10 = (uint32_t)(total_len10 % (uint64_t)(uint32_t)64U); + } + uint8_t *buf2 = buf0 + sz10; + memcpy(buf2, data1, diff * sizeof (uint8_t)); + uint64_t total_len2 = total_len10 + (uint64_t)diff; + *p + = + ( + (Hacl_Streaming_MD_state_32){ + .block_state = block_state10, + .buf = buf0, + .total_len = total_len2 + } + ); + Hacl_Streaming_MD_state_32 s10 = *p; + uint32_t *block_state1 = s10.block_state; + uint8_t *buf = s10.buf; + uint64_t total_len1 = s10.total_len; + uint32_t sz1; + if (total_len1 % (uint64_t)(uint32_t)64U == (uint64_t)0U && total_len1 > (uint64_t)0U) + { + sz1 = (uint32_t)64U; + } + else + { + sz1 = (uint32_t)(total_len1 % (uint64_t)(uint32_t)64U); + } + if (!(sz1 == (uint32_t)0U)) + { + Hacl_SHA2_Scalar32_sha256_update_nblocks((uint32_t)64U, buf, block_state1); + } + uint32_t ite; + if + ( + (uint64_t)(len - diff) + % (uint64_t)(uint32_t)64U + == (uint64_t)0U + && (uint64_t)(len - diff) > (uint64_t)0U + ) + { + ite = (uint32_t)64U; + } + else + { + ite = (uint32_t)((uint64_t)(len - diff) % (uint64_t)(uint32_t)64U); + } + uint32_t n_blocks = (len - diff - ite) / (uint32_t)64U; + uint32_t data1_len = n_blocks * (uint32_t)64U; + uint32_t data2_len = len - diff - data1_len; + uint8_t *data11 = data2; + uint8_t *data21 = data2 + data1_len; + Hacl_SHA2_Scalar32_sha256_update_nblocks(data1_len / (uint32_t)64U * (uint32_t)64U, + data11, + block_state1); + uint8_t *dst = buf; + memcpy(dst, data21, data2_len * sizeof (uint8_t)); + *p + = + ( + (Hacl_Streaming_MD_state_32){ + .block_state = block_state1, + .buf = buf, + .total_len = total_len1 + (uint64_t)(len - diff) + } + ); + } + return Hacl_Streaming_Types_Success; +} + +/** +Feed an arbitrary amount of data into the hash. This function returns 0 for +success, or 1 if the combined length of all of the data passed to `update_256` +(since the last call to `init_256`) exceeds 2^61-1 bytes. + +This function is identical to the update function for SHA2_224. +*/ +Hacl_Streaming_Types_error_code +Hacl_Streaming_SHA2_update_256( + Hacl_Streaming_MD_state_32 *p, + uint8_t *input, + uint32_t input_len +) +{ + return update_224_256(p, input, input_len); +} + +/** +Write the resulting hash into `dst`, an array of 32 bytes. The state remains +valid after a call to `finish_256`, meaning the user may feed more data into +the hash via `update_256`. (The finish_256 function operates on an internal copy of +the state and therefore does not invalidate the client-held state `p`.) +*/ +void Hacl_Streaming_SHA2_finish_256(Hacl_Streaming_MD_state_32 *p, uint8_t *dst) +{ + Hacl_Streaming_MD_state_32 scrut = *p; + uint32_t *block_state = scrut.block_state; + uint8_t *buf_ = scrut.buf; + uint64_t total_len = scrut.total_len; + uint32_t r; + if (total_len % (uint64_t)(uint32_t)64U == (uint64_t)0U && total_len > (uint64_t)0U) + { + r = (uint32_t)64U; + } + else + { + r = (uint32_t)(total_len % (uint64_t)(uint32_t)64U); + } + uint8_t *buf_1 = buf_; + uint32_t tmp_block_state[8U] = { 0U }; + memcpy(tmp_block_state, block_state, (uint32_t)8U * sizeof (uint32_t)); + uint32_t ite; + if (r % (uint32_t)64U == (uint32_t)0U && r > (uint32_t)0U) + { + ite = (uint32_t)64U; + } + else + { + ite = r % (uint32_t)64U; + } + uint8_t *buf_last = buf_1 + r - ite; + uint8_t *buf_multi = buf_1; + Hacl_SHA2_Scalar32_sha256_update_nblocks((uint32_t)0U, buf_multi, tmp_block_state); + uint64_t prev_len_last = total_len - (uint64_t)r; + Hacl_SHA2_Scalar32_sha256_update_last(prev_len_last + (uint64_t)r, + r, + buf_last, + tmp_block_state); + Hacl_SHA2_Scalar32_sha256_finish(tmp_block_state, dst); +} + +/** +Free a state allocated with `create_in_256`. + +This function is identical to the free function for SHA2_224. +*/ +void Hacl_Streaming_SHA2_free_256(Hacl_Streaming_MD_state_32 *s) +{ + Hacl_Streaming_MD_state_32 scrut = *s; + uint8_t *buf = scrut.buf; + uint32_t *block_state = scrut.block_state; + KRML_HOST_FREE(block_state); + KRML_HOST_FREE(buf); + KRML_HOST_FREE(s); +} + +/** +Hash `input`, of len `input_len`, into `dst`, an array of 32 bytes. +*/ +void Hacl_Streaming_SHA2_hash_256(uint8_t *input, uint32_t input_len, uint8_t *dst) +{ + uint8_t *ib = input; + uint8_t *rb = dst; + uint32_t st[8U] = { 0U }; + Hacl_SHA2_Scalar32_sha256_init(st); + uint32_t rem = input_len % (uint32_t)64U; + uint64_t len_ = (uint64_t)input_len; + Hacl_SHA2_Scalar32_sha256_update_nblocks(input_len, ib, st); + uint32_t rem1 = input_len % (uint32_t)64U; + uint8_t *b0 = ib; + uint8_t *lb = b0 + input_len - rem1; + Hacl_SHA2_Scalar32_sha256_update_last(len_, rem, lb, st); + Hacl_SHA2_Scalar32_sha256_finish(st, rb); +} + +Hacl_Streaming_MD_state_32 *Hacl_Streaming_SHA2_create_in_224(void) +{ + uint8_t *buf = (uint8_t *)KRML_HOST_CALLOC((uint32_t)64U, sizeof (uint8_t)); + uint32_t *block_state = (uint32_t *)KRML_HOST_CALLOC((uint32_t)8U, sizeof (uint32_t)); + Hacl_Streaming_MD_state_32 + s = { .block_state = block_state, .buf = buf, .total_len = (uint64_t)(uint32_t)0U }; + Hacl_Streaming_MD_state_32 + *p = (Hacl_Streaming_MD_state_32 *)KRML_HOST_MALLOC(sizeof (Hacl_Streaming_MD_state_32)); + p[0U] = s; + Hacl_SHA2_Scalar32_sha224_init(block_state); + return p; +} + +void Hacl_Streaming_SHA2_init_224(Hacl_Streaming_MD_state_32 *s) +{ + Hacl_Streaming_MD_state_32 scrut = *s; + uint8_t *buf = scrut.buf; + uint32_t *block_state = scrut.block_state; + Hacl_SHA2_Scalar32_sha224_init(block_state); + Hacl_Streaming_MD_state_32 + tmp = { .block_state = block_state, .buf = buf, .total_len = (uint64_t)(uint32_t)0U }; + s[0U] = tmp; +} + +Hacl_Streaming_Types_error_code +Hacl_Streaming_SHA2_update_224( + Hacl_Streaming_MD_state_32 *p, + uint8_t *input, + uint32_t input_len +) +{ + return update_224_256(p, input, input_len); +} + +/** +Write the resulting hash into `dst`, an array of 28 bytes. The state remains +valid after a call to `finish_224`, meaning the user may feed more data into +the hash via `update_224`. +*/ +void Hacl_Streaming_SHA2_finish_224(Hacl_Streaming_MD_state_32 *p, uint8_t *dst) +{ + Hacl_Streaming_MD_state_32 scrut = *p; + uint32_t *block_state = scrut.block_state; + uint8_t *buf_ = scrut.buf; + uint64_t total_len = scrut.total_len; + uint32_t r; + if (total_len % (uint64_t)(uint32_t)64U == (uint64_t)0U && total_len > (uint64_t)0U) + { + r = (uint32_t)64U; + } + else + { + r = (uint32_t)(total_len % (uint64_t)(uint32_t)64U); + } + uint8_t *buf_1 = buf_; + uint32_t tmp_block_state[8U] = { 0U }; + memcpy(tmp_block_state, block_state, (uint32_t)8U * sizeof (uint32_t)); + uint32_t ite; + if (r % (uint32_t)64U == (uint32_t)0U && r > (uint32_t)0U) + { + ite = (uint32_t)64U; + } + else + { + ite = r % (uint32_t)64U; + } + uint8_t *buf_last = buf_1 + r - ite; + uint8_t *buf_multi = buf_1; + sha224_update_nblocks((uint32_t)0U, buf_multi, tmp_block_state); + uint64_t prev_len_last = total_len - (uint64_t)r; + Hacl_SHA2_Scalar32_sha224_update_last(prev_len_last + (uint64_t)r, + r, + buf_last, + tmp_block_state); + Hacl_SHA2_Scalar32_sha224_finish(tmp_block_state, dst); +} + +void Hacl_Streaming_SHA2_free_224(Hacl_Streaming_MD_state_32 *p) +{ + Hacl_Streaming_SHA2_free_256(p); +} + +/** +Hash `input`, of len `input_len`, into `dst`, an array of 28 bytes. +*/ +void Hacl_Streaming_SHA2_hash_224(uint8_t *input, uint32_t input_len, uint8_t *dst) +{ + uint8_t *ib = input; + uint8_t *rb = dst; + uint32_t st[8U] = { 0U }; + Hacl_SHA2_Scalar32_sha224_init(st); + uint32_t rem = input_len % (uint32_t)64U; + uint64_t len_ = (uint64_t)input_len; + sha224_update_nblocks(input_len, ib, st); + uint32_t rem1 = input_len % (uint32_t)64U; + uint8_t *b0 = ib; + uint8_t *lb = b0 + input_len - rem1; + Hacl_SHA2_Scalar32_sha224_update_last(len_, rem, lb, st); + Hacl_SHA2_Scalar32_sha224_finish(st, rb); +} + +Hacl_Streaming_MD_state_64 *Hacl_Streaming_SHA2_create_in_512(void) +{ + uint8_t *buf = (uint8_t *)KRML_HOST_CALLOC((uint32_t)128U, sizeof (uint8_t)); + uint64_t *block_state = (uint64_t *)KRML_HOST_CALLOC((uint32_t)8U, sizeof (uint64_t)); + Hacl_Streaming_MD_state_64 + s = { .block_state = block_state, .buf = buf, .total_len = (uint64_t)(uint32_t)0U }; + Hacl_Streaming_MD_state_64 + *p = (Hacl_Streaming_MD_state_64 *)KRML_HOST_MALLOC(sizeof (Hacl_Streaming_MD_state_64)); + p[0U] = s; + Hacl_SHA2_Scalar32_sha512_init(block_state); + return p; +} + +/** +Copies the state passed as argument into a newly allocated state (deep copy). +The state is to be freed by calling `free_512`. Cloning the state this way is +useful, for instance, if your control-flow diverges and you need to feed +more (different) data into the hash in each branch. +*/ +Hacl_Streaming_MD_state_64 *Hacl_Streaming_SHA2_copy_512(Hacl_Streaming_MD_state_64 *s0) +{ + Hacl_Streaming_MD_state_64 scrut = *s0; + uint64_t *block_state0 = scrut.block_state; + uint8_t *buf0 = scrut.buf; + uint64_t total_len0 = scrut.total_len; + uint8_t *buf = (uint8_t *)KRML_HOST_CALLOC((uint32_t)128U, sizeof (uint8_t)); + memcpy(buf, buf0, (uint32_t)128U * sizeof (uint8_t)); + uint64_t *block_state = (uint64_t *)KRML_HOST_CALLOC((uint32_t)8U, sizeof (uint64_t)); + memcpy(block_state, block_state0, (uint32_t)8U * sizeof (uint64_t)); + Hacl_Streaming_MD_state_64 + s = { .block_state = block_state, .buf = buf, .total_len = total_len0 }; + Hacl_Streaming_MD_state_64 + *p = (Hacl_Streaming_MD_state_64 *)KRML_HOST_MALLOC(sizeof (Hacl_Streaming_MD_state_64)); + p[0U] = s; + return p; +} + +void Hacl_Streaming_SHA2_init_512(Hacl_Streaming_MD_state_64 *s) +{ + Hacl_Streaming_MD_state_64 scrut = *s; + uint8_t *buf = scrut.buf; + uint64_t *block_state = scrut.block_state; + Hacl_SHA2_Scalar32_sha512_init(block_state); + Hacl_Streaming_MD_state_64 + tmp = { .block_state = block_state, .buf = buf, .total_len = (uint64_t)(uint32_t)0U }; + s[0U] = tmp; +} + +static inline Hacl_Streaming_Types_error_code +update_384_512(Hacl_Streaming_MD_state_64 *p, uint8_t *data, uint32_t len) +{ + Hacl_Streaming_MD_state_64 s = *p; + uint64_t total_len = s.total_len; + if ((uint64_t)len > (uint64_t)18446744073709551615U - total_len) + { + return Hacl_Streaming_Types_MaximumLengthExceeded; + } + uint32_t sz; + if (total_len % (uint64_t)(uint32_t)128U == (uint64_t)0U && total_len > (uint64_t)0U) + { + sz = (uint32_t)128U; + } + else + { + sz = (uint32_t)(total_len % (uint64_t)(uint32_t)128U); + } + if (len <= (uint32_t)128U - sz) + { + Hacl_Streaming_MD_state_64 s1 = *p; + uint64_t *block_state1 = s1.block_state; + uint8_t *buf = s1.buf; + uint64_t total_len1 = s1.total_len; + uint32_t sz1; + if (total_len1 % (uint64_t)(uint32_t)128U == (uint64_t)0U && total_len1 > (uint64_t)0U) + { + sz1 = (uint32_t)128U; + } + else + { + sz1 = (uint32_t)(total_len1 % (uint64_t)(uint32_t)128U); + } + uint8_t *buf2 = buf + sz1; + memcpy(buf2, data, len * sizeof (uint8_t)); + uint64_t total_len2 = total_len1 + (uint64_t)len; + *p + = + ( + (Hacl_Streaming_MD_state_64){ + .block_state = block_state1, + .buf = buf, + .total_len = total_len2 + } + ); + } + else if (sz == (uint32_t)0U) + { + Hacl_Streaming_MD_state_64 s1 = *p; + uint64_t *block_state1 = s1.block_state; + uint8_t *buf = s1.buf; + uint64_t total_len1 = s1.total_len; + uint32_t sz1; + if (total_len1 % (uint64_t)(uint32_t)128U == (uint64_t)0U && total_len1 > (uint64_t)0U) + { + sz1 = (uint32_t)128U; + } + else + { + sz1 = (uint32_t)(total_len1 % (uint64_t)(uint32_t)128U); + } + if (!(sz1 == (uint32_t)0U)) + { + Hacl_SHA2_Scalar32_sha512_update_nblocks((uint32_t)128U, buf, block_state1); + } + uint32_t ite; + if ((uint64_t)len % (uint64_t)(uint32_t)128U == (uint64_t)0U && (uint64_t)len > (uint64_t)0U) + { + ite = (uint32_t)128U; + } + else + { + ite = (uint32_t)((uint64_t)len % (uint64_t)(uint32_t)128U); + } + uint32_t n_blocks = (len - ite) / (uint32_t)128U; + uint32_t data1_len = n_blocks * (uint32_t)128U; + uint32_t data2_len = len - data1_len; + uint8_t *data1 = data; + uint8_t *data2 = data + data1_len; + Hacl_SHA2_Scalar32_sha512_update_nblocks(data1_len / (uint32_t)128U * (uint32_t)128U, + data1, + block_state1); + uint8_t *dst = buf; + memcpy(dst, data2, data2_len * sizeof (uint8_t)); + *p + = + ( + (Hacl_Streaming_MD_state_64){ + .block_state = block_state1, + .buf = buf, + .total_len = total_len1 + (uint64_t)len + } + ); + } + else + { + uint32_t diff = (uint32_t)128U - sz; + uint8_t *data1 = data; + uint8_t *data2 = data + diff; + Hacl_Streaming_MD_state_64 s1 = *p; + uint64_t *block_state10 = s1.block_state; + uint8_t *buf0 = s1.buf; + uint64_t total_len10 = s1.total_len; + uint32_t sz10; + if (total_len10 % (uint64_t)(uint32_t)128U == (uint64_t)0U && total_len10 > (uint64_t)0U) + { + sz10 = (uint32_t)128U; + } + else + { + sz10 = (uint32_t)(total_len10 % (uint64_t)(uint32_t)128U); + } + uint8_t *buf2 = buf0 + sz10; + memcpy(buf2, data1, diff * sizeof (uint8_t)); + uint64_t total_len2 = total_len10 + (uint64_t)diff; + *p + = + ( + (Hacl_Streaming_MD_state_64){ + .block_state = block_state10, + .buf = buf0, + .total_len = total_len2 + } + ); + Hacl_Streaming_MD_state_64 s10 = *p; + uint64_t *block_state1 = s10.block_state; + uint8_t *buf = s10.buf; + uint64_t total_len1 = s10.total_len; + uint32_t sz1; + if (total_len1 % (uint64_t)(uint32_t)128U == (uint64_t)0U && total_len1 > (uint64_t)0U) + { + sz1 = (uint32_t)128U; + } + else + { + sz1 = (uint32_t)(total_len1 % (uint64_t)(uint32_t)128U); + } + if (!(sz1 == (uint32_t)0U)) + { + Hacl_SHA2_Scalar32_sha512_update_nblocks((uint32_t)128U, buf, block_state1); + } + uint32_t ite; + if + ( + (uint64_t)(len - diff) + % (uint64_t)(uint32_t)128U + == (uint64_t)0U + && (uint64_t)(len - diff) > (uint64_t)0U + ) + { + ite = (uint32_t)128U; + } + else + { + ite = (uint32_t)((uint64_t)(len - diff) % (uint64_t)(uint32_t)128U); + } + uint32_t n_blocks = (len - diff - ite) / (uint32_t)128U; + uint32_t data1_len = n_blocks * (uint32_t)128U; + uint32_t data2_len = len - diff - data1_len; + uint8_t *data11 = data2; + uint8_t *data21 = data2 + data1_len; + Hacl_SHA2_Scalar32_sha512_update_nblocks(data1_len / (uint32_t)128U * (uint32_t)128U, + data11, + block_state1); + uint8_t *dst = buf; + memcpy(dst, data21, data2_len * sizeof (uint8_t)); + *p + = + ( + (Hacl_Streaming_MD_state_64){ + .block_state = block_state1, + .buf = buf, + .total_len = total_len1 + (uint64_t)(len - diff) + } + ); + } + return Hacl_Streaming_Types_Success; +} + +/** +Feed an arbitrary amount of data into the hash. This function returns 0 for +success, or 1 if the combined length of all of the data passed to `update_512` +(since the last call to `init_512`) exceeds 2^125-1 bytes. + +This function is identical to the update function for SHA2_384. +*/ +Hacl_Streaming_Types_error_code +Hacl_Streaming_SHA2_update_512( + Hacl_Streaming_MD_state_64 *p, + uint8_t *input, + uint32_t input_len +) +{ + return update_384_512(p, input, input_len); +} + +/** +Write the resulting hash into `dst`, an array of 64 bytes. The state remains +valid after a call to `finish_512`, meaning the user may feed more data into +the hash via `update_512`. (The finish_512 function operates on an internal copy of +the state and therefore does not invalidate the client-held state `p`.) +*/ +void Hacl_Streaming_SHA2_finish_512(Hacl_Streaming_MD_state_64 *p, uint8_t *dst) +{ + Hacl_Streaming_MD_state_64 scrut = *p; + uint64_t *block_state = scrut.block_state; + uint8_t *buf_ = scrut.buf; + uint64_t total_len = scrut.total_len; + uint32_t r; + if (total_len % (uint64_t)(uint32_t)128U == (uint64_t)0U && total_len > (uint64_t)0U) + { + r = (uint32_t)128U; + } + else + { + r = (uint32_t)(total_len % (uint64_t)(uint32_t)128U); + } + uint8_t *buf_1 = buf_; + uint64_t tmp_block_state[8U] = { 0U }; + memcpy(tmp_block_state, block_state, (uint32_t)8U * sizeof (uint64_t)); + uint32_t ite; + if (r % (uint32_t)128U == (uint32_t)0U && r > (uint32_t)0U) + { + ite = (uint32_t)128U; + } + else + { + ite = r % (uint32_t)128U; + } + uint8_t *buf_last = buf_1 + r - ite; + uint8_t *buf_multi = buf_1; + Hacl_SHA2_Scalar32_sha512_update_nblocks((uint32_t)0U, buf_multi, tmp_block_state); + uint64_t prev_len_last = total_len - (uint64_t)r; + Hacl_SHA2_Scalar32_sha512_update_last(FStar_UInt128_add(FStar_UInt128_uint64_to_uint128(prev_len_last), + FStar_UInt128_uint64_to_uint128((uint64_t)r)), + r, + buf_last, + tmp_block_state); + Hacl_SHA2_Scalar32_sha512_finish(tmp_block_state, dst); +} + +/** +Free a state allocated with `create_in_512`. + +This function is identical to the free function for SHA2_384. +*/ +void Hacl_Streaming_SHA2_free_512(Hacl_Streaming_MD_state_64 *s) +{ + Hacl_Streaming_MD_state_64 scrut = *s; + uint8_t *buf = scrut.buf; + uint64_t *block_state = scrut.block_state; + KRML_HOST_FREE(block_state); + KRML_HOST_FREE(buf); + KRML_HOST_FREE(s); +} + +/** +Hash `input`, of len `input_len`, into `dst`, an array of 64 bytes. +*/ +void Hacl_Streaming_SHA2_hash_512(uint8_t *input, uint32_t input_len, uint8_t *dst) +{ + uint8_t *ib = input; + uint8_t *rb = dst; + uint64_t st[8U] = { 0U }; + Hacl_SHA2_Scalar32_sha512_init(st); + uint32_t rem = input_len % (uint32_t)128U; + FStar_UInt128_uint128 len_ = FStar_UInt128_uint64_to_uint128((uint64_t)input_len); + Hacl_SHA2_Scalar32_sha512_update_nblocks(input_len, ib, st); + uint32_t rem1 = input_len % (uint32_t)128U; + uint8_t *b0 = ib; + uint8_t *lb = b0 + input_len - rem1; + Hacl_SHA2_Scalar32_sha512_update_last(len_, rem, lb, st); + Hacl_SHA2_Scalar32_sha512_finish(st, rb); +} + +Hacl_Streaming_MD_state_64 *Hacl_Streaming_SHA2_create_in_384(void) +{ + uint8_t *buf = (uint8_t *)KRML_HOST_CALLOC((uint32_t)128U, sizeof (uint8_t)); + uint64_t *block_state = (uint64_t *)KRML_HOST_CALLOC((uint32_t)8U, sizeof (uint64_t)); + Hacl_Streaming_MD_state_64 + s = { .block_state = block_state, .buf = buf, .total_len = (uint64_t)(uint32_t)0U }; + Hacl_Streaming_MD_state_64 + *p = (Hacl_Streaming_MD_state_64 *)KRML_HOST_MALLOC(sizeof (Hacl_Streaming_MD_state_64)); + p[0U] = s; + Hacl_SHA2_Scalar32_sha384_init(block_state); + return p; +} + +void Hacl_Streaming_SHA2_init_384(Hacl_Streaming_MD_state_64 *s) +{ + Hacl_Streaming_MD_state_64 scrut = *s; + uint8_t *buf = scrut.buf; + uint64_t *block_state = scrut.block_state; + Hacl_SHA2_Scalar32_sha384_init(block_state); + Hacl_Streaming_MD_state_64 + tmp = { .block_state = block_state, .buf = buf, .total_len = (uint64_t)(uint32_t)0U }; + s[0U] = tmp; +} + +Hacl_Streaming_Types_error_code +Hacl_Streaming_SHA2_update_384( + Hacl_Streaming_MD_state_64 *p, + uint8_t *input, + uint32_t input_len +) +{ + return update_384_512(p, input, input_len); +} + +/** +Write the resulting hash into `dst`, an array of 48 bytes. The state remains +valid after a call to `finish_384`, meaning the user may feed more data into +the hash via `update_384`. +*/ +void Hacl_Streaming_SHA2_finish_384(Hacl_Streaming_MD_state_64 *p, uint8_t *dst) +{ + Hacl_Streaming_MD_state_64 scrut = *p; + uint64_t *block_state = scrut.block_state; + uint8_t *buf_ = scrut.buf; + uint64_t total_len = scrut.total_len; + uint32_t r; + if (total_len % (uint64_t)(uint32_t)128U == (uint64_t)0U && total_len > (uint64_t)0U) + { + r = (uint32_t)128U; + } + else + { + r = (uint32_t)(total_len % (uint64_t)(uint32_t)128U); + } + uint8_t *buf_1 = buf_; + uint64_t tmp_block_state[8U] = { 0U }; + memcpy(tmp_block_state, block_state, (uint32_t)8U * sizeof (uint64_t)); + uint32_t ite; + if (r % (uint32_t)128U == (uint32_t)0U && r > (uint32_t)0U) + { + ite = (uint32_t)128U; + } + else + { + ite = r % (uint32_t)128U; + } + uint8_t *buf_last = buf_1 + r - ite; + uint8_t *buf_multi = buf_1; + Hacl_SHA2_Scalar32_sha384_update_nblocks((uint32_t)0U, buf_multi, tmp_block_state); + uint64_t prev_len_last = total_len - (uint64_t)r; + Hacl_SHA2_Scalar32_sha384_update_last(FStar_UInt128_add(FStar_UInt128_uint64_to_uint128(prev_len_last), + FStar_UInt128_uint64_to_uint128((uint64_t)r)), + r, + buf_last, + tmp_block_state); + Hacl_SHA2_Scalar32_sha384_finish(tmp_block_state, dst); +} + +void Hacl_Streaming_SHA2_free_384(Hacl_Streaming_MD_state_64 *p) +{ + Hacl_Streaming_SHA2_free_512(p); +} + +/** +Hash `input`, of len `input_len`, into `dst`, an array of 48 bytes. +*/ +void Hacl_Streaming_SHA2_hash_384(uint8_t *input, uint32_t input_len, uint8_t *dst) +{ + uint8_t *ib = input; + uint8_t *rb = dst; + uint64_t st[8U] = { 0U }; + Hacl_SHA2_Scalar32_sha384_init(st); + uint32_t rem = input_len % (uint32_t)128U; + FStar_UInt128_uint128 len_ = FStar_UInt128_uint64_to_uint128((uint64_t)input_len); + Hacl_SHA2_Scalar32_sha384_update_nblocks(input_len, ib, st); + uint32_t rem1 = input_len % (uint32_t)128U; + uint8_t *b0 = ib; + uint8_t *lb = b0 + input_len - rem1; + Hacl_SHA2_Scalar32_sha384_update_last(len_, rem, lb, st); + Hacl_SHA2_Scalar32_sha384_finish(st, rb); +} + diff --git a/Modules/_hacl/Hacl_Hash_SHA2.h b/Modules/_hacl/Hacl_Hash_SHA2.h new file mode 100644 index 00000000..a0e73109 --- /dev/null +++ b/Modules/_hacl/Hacl_Hash_SHA2.h @@ -0,0 +1,204 @@ +/* MIT License + * + * Copyright (c) 2016-2022 INRIA, CMU and Microsoft Corporation + * Copyright (c) 2022-2023 HACL* Contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + + +#ifndef __Hacl_Hash_SHA2_H +#define __Hacl_Hash_SHA2_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include <string.h> +#include "python_hacl_namespaces.h" +#include "krml/types.h" +#include "krml/lowstar_endianness.h" +#include "krml/internal/target.h" + +#include "Hacl_Streaming_Types.h" + + +typedef Hacl_Streaming_MD_state_32 Hacl_Streaming_SHA2_state_sha2_224; + +typedef Hacl_Streaming_MD_state_32 Hacl_Streaming_SHA2_state_sha2_256; + +typedef Hacl_Streaming_MD_state_64 Hacl_Streaming_SHA2_state_sha2_384; + +typedef Hacl_Streaming_MD_state_64 Hacl_Streaming_SHA2_state_sha2_512; + +/** +Allocate initial state for the SHA2_256 hash. The state is to be freed by +calling `free_256`. +*/ +Hacl_Streaming_MD_state_32 *Hacl_Streaming_SHA2_create_in_256(void); + +/** +Copies the state passed as argument into a newly allocated state (deep copy). +The state is to be freed by calling `free_256`. Cloning the state this way is +useful, for instance, if your control-flow diverges and you need to feed +more (different) data into the hash in each branch. +*/ +Hacl_Streaming_MD_state_32 *Hacl_Streaming_SHA2_copy_256(Hacl_Streaming_MD_state_32 *s0); + +/** +Reset an existing state to the initial hash state with empty data. +*/ +void Hacl_Streaming_SHA2_init_256(Hacl_Streaming_MD_state_32 *s); + +/** +Feed an arbitrary amount of data into the hash. This function returns 0 for +success, or 1 if the combined length of all of the data passed to `update_256` +(since the last call to `init_256`) exceeds 2^61-1 bytes. + +This function is identical to the update function for SHA2_224. +*/ +Hacl_Streaming_Types_error_code +Hacl_Streaming_SHA2_update_256( + Hacl_Streaming_MD_state_32 *p, + uint8_t *input, + uint32_t input_len +); + +/** +Write the resulting hash into `dst`, an array of 32 bytes. The state remains +valid after a call to `finish_256`, meaning the user may feed more data into +the hash via `update_256`. (The finish_256 function operates on an internal copy of +the state and therefore does not invalidate the client-held state `p`.) +*/ +void Hacl_Streaming_SHA2_finish_256(Hacl_Streaming_MD_state_32 *p, uint8_t *dst); + +/** +Free a state allocated with `create_in_256`. + +This function is identical to the free function for SHA2_224. +*/ +void Hacl_Streaming_SHA2_free_256(Hacl_Streaming_MD_state_32 *s); + +/** +Hash `input`, of len `input_len`, into `dst`, an array of 32 bytes. +*/ +void Hacl_Streaming_SHA2_hash_256(uint8_t *input, uint32_t input_len, uint8_t *dst); + +Hacl_Streaming_MD_state_32 *Hacl_Streaming_SHA2_create_in_224(void); + +void Hacl_Streaming_SHA2_init_224(Hacl_Streaming_MD_state_32 *s); + +Hacl_Streaming_Types_error_code +Hacl_Streaming_SHA2_update_224( + Hacl_Streaming_MD_state_32 *p, + uint8_t *input, + uint32_t input_len +); + +/** +Write the resulting hash into `dst`, an array of 28 bytes. The state remains +valid after a call to `finish_224`, meaning the user may feed more data into +the hash via `update_224`. +*/ +void Hacl_Streaming_SHA2_finish_224(Hacl_Streaming_MD_state_32 *p, uint8_t *dst); + +void Hacl_Streaming_SHA2_free_224(Hacl_Streaming_MD_state_32 *p); + +/** +Hash `input`, of len `input_len`, into `dst`, an array of 28 bytes. +*/ +void Hacl_Streaming_SHA2_hash_224(uint8_t *input, uint32_t input_len, uint8_t *dst); + +Hacl_Streaming_MD_state_64 *Hacl_Streaming_SHA2_create_in_512(void); + +/** +Copies the state passed as argument into a newly allocated state (deep copy). +The state is to be freed by calling `free_512`. Cloning the state this way is +useful, for instance, if your control-flow diverges and you need to feed +more (different) data into the hash in each branch. +*/ +Hacl_Streaming_MD_state_64 *Hacl_Streaming_SHA2_copy_512(Hacl_Streaming_MD_state_64 *s0); + +void Hacl_Streaming_SHA2_init_512(Hacl_Streaming_MD_state_64 *s); + +/** +Feed an arbitrary amount of data into the hash. This function returns 0 for +success, or 1 if the combined length of all of the data passed to `update_512` +(since the last call to `init_512`) exceeds 2^125-1 bytes. + +This function is identical to the update function for SHA2_384. +*/ +Hacl_Streaming_Types_error_code +Hacl_Streaming_SHA2_update_512( + Hacl_Streaming_MD_state_64 *p, + uint8_t *input, + uint32_t input_len +); + +/** +Write the resulting hash into `dst`, an array of 64 bytes. The state remains +valid after a call to `finish_512`, meaning the user may feed more data into +the hash via `update_512`. (The finish_512 function operates on an internal copy of +the state and therefore does not invalidate the client-held state `p`.) +*/ +void Hacl_Streaming_SHA2_finish_512(Hacl_Streaming_MD_state_64 *p, uint8_t *dst); + +/** +Free a state allocated with `create_in_512`. + +This function is identical to the free function for SHA2_384. +*/ +void Hacl_Streaming_SHA2_free_512(Hacl_Streaming_MD_state_64 *s); + +/** +Hash `input`, of len `input_len`, into `dst`, an array of 64 bytes. +*/ +void Hacl_Streaming_SHA2_hash_512(uint8_t *input, uint32_t input_len, uint8_t *dst); + +Hacl_Streaming_MD_state_64 *Hacl_Streaming_SHA2_create_in_384(void); + +void Hacl_Streaming_SHA2_init_384(Hacl_Streaming_MD_state_64 *s); + +Hacl_Streaming_Types_error_code +Hacl_Streaming_SHA2_update_384( + Hacl_Streaming_MD_state_64 *p, + uint8_t *input, + uint32_t input_len +); + +/** +Write the resulting hash into `dst`, an array of 48 bytes. The state remains +valid after a call to `finish_384`, meaning the user may feed more data into +the hash via `update_384`. +*/ +void Hacl_Streaming_SHA2_finish_384(Hacl_Streaming_MD_state_64 *p, uint8_t *dst); + +void Hacl_Streaming_SHA2_free_384(Hacl_Streaming_MD_state_64 *p); + +/** +Hash `input`, of len `input_len`, into `dst`, an array of 48 bytes. +*/ +void Hacl_Streaming_SHA2_hash_384(uint8_t *input, uint32_t input_len, uint8_t *dst); + +#if defined(__cplusplus) +} +#endif + +#define __Hacl_Hash_SHA2_H_DEFINED +#endif diff --git a/Modules/_hacl/Hacl_Hash_SHA3.c b/Modules/_hacl/Hacl_Hash_SHA3.c new file mode 100644 index 00000000..b3febdfe --- /dev/null +++ b/Modules/_hacl/Hacl_Hash_SHA3.c @@ -0,0 +1,824 @@ +/* MIT License + * + * Copyright (c) 2016-2022 INRIA, CMU and Microsoft Corporation + * Copyright (c) 2022-2023 HACL* Contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + + +#include "internal/Hacl_Hash_SHA3.h" + +static uint32_t block_len(Spec_Hash_Definitions_hash_alg a) +{ + switch (a) + { + case Spec_Hash_Definitions_SHA3_224: + { + return (uint32_t)144U; + } + case Spec_Hash_Definitions_SHA3_256: + { + return (uint32_t)136U; + } + case Spec_Hash_Definitions_SHA3_384: + { + return (uint32_t)104U; + } + case Spec_Hash_Definitions_SHA3_512: + { + return (uint32_t)72U; + } + case Spec_Hash_Definitions_Shake128: + { + return (uint32_t)168U; + } + case Spec_Hash_Definitions_Shake256: + { + return (uint32_t)136U; + } + default: + { + KRML_HOST_EPRINTF("KaRaMeL incomplete match at %s:%d\n", __FILE__, __LINE__); + KRML_HOST_EXIT(253U); + } + } +} + +static uint32_t hash_len(Spec_Hash_Definitions_hash_alg a) +{ + switch (a) + { + case Spec_Hash_Definitions_SHA3_224: + { + return (uint32_t)28U; + } + case Spec_Hash_Definitions_SHA3_256: + { + return (uint32_t)32U; + } + case Spec_Hash_Definitions_SHA3_384: + { + return (uint32_t)48U; + } + case Spec_Hash_Definitions_SHA3_512: + { + return (uint32_t)64U; + } + default: + { + KRML_HOST_EPRINTF("KaRaMeL incomplete match at %s:%d\n", __FILE__, __LINE__); + KRML_HOST_EXIT(253U); + } + } +} + +void +Hacl_Hash_SHA3_update_multi_sha3( + Spec_Hash_Definitions_hash_alg a, + uint64_t *s, + uint8_t *blocks, + uint32_t n_blocks +) +{ + for (uint32_t i = (uint32_t)0U; i < n_blocks; i++) + { + uint8_t *block = blocks + i * block_len(a); + Hacl_Impl_SHA3_absorb_inner(block_len(a), block, s); + } +} + +void +Hacl_Hash_SHA3_update_last_sha3( + Spec_Hash_Definitions_hash_alg a, + uint64_t *s, + uint8_t *input, + uint32_t input_len +) +{ + uint8_t suffix; + if (a == Spec_Hash_Definitions_Shake128 || a == Spec_Hash_Definitions_Shake256) + { + suffix = (uint8_t)0x1fU; + } + else + { + suffix = (uint8_t)0x06U; + } + uint32_t len = block_len(a); + if (input_len == len) + { + Hacl_Impl_SHA3_absorb_inner(len, input, s); + uint8_t *uu____0 = input + input_len; + uint8_t lastBlock_[200U] = { 0U }; + uint8_t *lastBlock = lastBlock_; + memcpy(lastBlock, uu____0, (uint32_t)0U * sizeof (uint8_t)); + lastBlock[0U] = suffix; + Hacl_Impl_SHA3_loadState(len, lastBlock, s); + if (!((suffix & (uint8_t)0x80U) == (uint8_t)0U) && (uint32_t)0U == len - (uint32_t)1U) + { + Hacl_Impl_SHA3_state_permute(s); + } + uint8_t nextBlock_[200U] = { 0U }; + uint8_t *nextBlock = nextBlock_; + nextBlock[len - (uint32_t)1U] = (uint8_t)0x80U; + Hacl_Impl_SHA3_loadState(len, nextBlock, s); + Hacl_Impl_SHA3_state_permute(s); + return; + } + uint8_t lastBlock_[200U] = { 0U }; + uint8_t *lastBlock = lastBlock_; + memcpy(lastBlock, input, input_len * sizeof (uint8_t)); + lastBlock[input_len] = suffix; + Hacl_Impl_SHA3_loadState(len, lastBlock, s); + if (!((suffix & (uint8_t)0x80U) == (uint8_t)0U) && input_len == len - (uint32_t)1U) + { + Hacl_Impl_SHA3_state_permute(s); + } + uint8_t nextBlock_[200U] = { 0U }; + uint8_t *nextBlock = nextBlock_; + nextBlock[len - (uint32_t)1U] = (uint8_t)0x80U; + Hacl_Impl_SHA3_loadState(len, nextBlock, s); + Hacl_Impl_SHA3_state_permute(s); +} + +typedef struct hash_buf2_s +{ + Hacl_Streaming_Keccak_hash_buf fst; + Hacl_Streaming_Keccak_hash_buf snd; +} +hash_buf2; + +Spec_Hash_Definitions_hash_alg Hacl_Streaming_Keccak_get_alg(Hacl_Streaming_Keccak_state *s) +{ + Hacl_Streaming_Keccak_state scrut = *s; + Hacl_Streaming_Keccak_hash_buf block_state = scrut.block_state; + return block_state.fst; +} + +Hacl_Streaming_Keccak_state *Hacl_Streaming_Keccak_malloc(Spec_Hash_Definitions_hash_alg a) +{ + KRML_CHECK_SIZE(sizeof (uint8_t), block_len(a)); + uint8_t *buf0 = (uint8_t *)KRML_HOST_CALLOC(block_len(a), sizeof (uint8_t)); + uint64_t *buf = (uint64_t *)KRML_HOST_CALLOC((uint32_t)25U, sizeof (uint64_t)); + Hacl_Streaming_Keccak_hash_buf block_state = { .fst = a, .snd = buf }; + Hacl_Streaming_Keccak_state + s = { .block_state = block_state, .buf = buf0, .total_len = (uint64_t)(uint32_t)0U }; + Hacl_Streaming_Keccak_state + *p = (Hacl_Streaming_Keccak_state *)KRML_HOST_MALLOC(sizeof (Hacl_Streaming_Keccak_state)); + p[0U] = s; + uint64_t *s1 = block_state.snd; + memset(s1, 0U, (uint32_t)25U * sizeof (uint64_t)); + return p; +} + +void Hacl_Streaming_Keccak_free(Hacl_Streaming_Keccak_state *s) +{ + Hacl_Streaming_Keccak_state scrut = *s; + uint8_t *buf = scrut.buf; + Hacl_Streaming_Keccak_hash_buf block_state = scrut.block_state; + uint64_t *s1 = block_state.snd; + KRML_HOST_FREE(s1); + KRML_HOST_FREE(buf); + KRML_HOST_FREE(s); +} + +Hacl_Streaming_Keccak_state *Hacl_Streaming_Keccak_copy(Hacl_Streaming_Keccak_state *s0) +{ + Hacl_Streaming_Keccak_state scrut0 = *s0; + Hacl_Streaming_Keccak_hash_buf block_state0 = scrut0.block_state; + uint8_t *buf0 = scrut0.buf; + uint64_t total_len0 = scrut0.total_len; + Spec_Hash_Definitions_hash_alg i = block_state0.fst; + KRML_CHECK_SIZE(sizeof (uint8_t), block_len(i)); + uint8_t *buf1 = (uint8_t *)KRML_HOST_CALLOC(block_len(i), sizeof (uint8_t)); + memcpy(buf1, buf0, block_len(i) * sizeof (uint8_t)); + uint64_t *buf = (uint64_t *)KRML_HOST_CALLOC((uint32_t)25U, sizeof (uint64_t)); + Hacl_Streaming_Keccak_hash_buf block_state = { .fst = i, .snd = buf }; + hash_buf2 scrut = { .fst = block_state0, .snd = block_state }; + uint64_t *s_dst = scrut.snd.snd; + uint64_t *s_src = scrut.fst.snd; + memcpy(s_dst, s_src, (uint32_t)25U * sizeof (uint64_t)); + Hacl_Streaming_Keccak_state + s = { .block_state = block_state, .buf = buf1, .total_len = total_len0 }; + Hacl_Streaming_Keccak_state + *p = (Hacl_Streaming_Keccak_state *)KRML_HOST_MALLOC(sizeof (Hacl_Streaming_Keccak_state)); + p[0U] = s; + return p; +} + +void Hacl_Streaming_Keccak_reset(Hacl_Streaming_Keccak_state *s) +{ + Hacl_Streaming_Keccak_state scrut = *s; + uint8_t *buf = scrut.buf; + Hacl_Streaming_Keccak_hash_buf block_state = scrut.block_state; + uint64_t *s1 = block_state.snd; + memset(s1, 0U, (uint32_t)25U * sizeof (uint64_t)); + Hacl_Streaming_Keccak_state + tmp = { .block_state = block_state, .buf = buf, .total_len = (uint64_t)(uint32_t)0U }; + s[0U] = tmp; +} + +Hacl_Streaming_Types_error_code +Hacl_Streaming_Keccak_update(Hacl_Streaming_Keccak_state *p, uint8_t *data, uint32_t len) +{ + Hacl_Streaming_Keccak_state s = *p; + Hacl_Streaming_Keccak_hash_buf block_state = s.block_state; + uint64_t total_len = s.total_len; + Spec_Hash_Definitions_hash_alg i = block_state.fst; + if ((uint64_t)len > (uint64_t)0xFFFFFFFFFFFFFFFFU - total_len) + { + return Hacl_Streaming_Types_MaximumLengthExceeded; + } + uint32_t sz; + if (total_len % (uint64_t)block_len(i) == (uint64_t)0U && total_len > (uint64_t)0U) + { + sz = block_len(i); + } + else + { + sz = (uint32_t)(total_len % (uint64_t)block_len(i)); + } + if (len <= block_len(i) - sz) + { + Hacl_Streaming_Keccak_state s1 = *p; + Hacl_Streaming_Keccak_hash_buf block_state1 = s1.block_state; + uint8_t *buf = s1.buf; + uint64_t total_len1 = s1.total_len; + uint32_t sz1; + if (total_len1 % (uint64_t)block_len(i) == (uint64_t)0U && total_len1 > (uint64_t)0U) + { + sz1 = block_len(i); + } + else + { + sz1 = (uint32_t)(total_len1 % (uint64_t)block_len(i)); + } + uint8_t *buf2 = buf + sz1; + memcpy(buf2, data, len * sizeof (uint8_t)); + uint64_t total_len2 = total_len1 + (uint64_t)len; + *p + = + ( + (Hacl_Streaming_Keccak_state){ + .block_state = block_state1, + .buf = buf, + .total_len = total_len2 + } + ); + } + else if (sz == (uint32_t)0U) + { + Hacl_Streaming_Keccak_state s1 = *p; + Hacl_Streaming_Keccak_hash_buf block_state1 = s1.block_state; + uint8_t *buf = s1.buf; + uint64_t total_len1 = s1.total_len; + uint32_t sz1; + if (total_len1 % (uint64_t)block_len(i) == (uint64_t)0U && total_len1 > (uint64_t)0U) + { + sz1 = block_len(i); + } + else + { + sz1 = (uint32_t)(total_len1 % (uint64_t)block_len(i)); + } + if (!(sz1 == (uint32_t)0U)) + { + Spec_Hash_Definitions_hash_alg a1 = block_state1.fst; + uint64_t *s2 = block_state1.snd; + Hacl_Hash_SHA3_update_multi_sha3(a1, s2, buf, block_len(i) / block_len(a1)); + } + uint32_t ite; + if ((uint64_t)len % (uint64_t)block_len(i) == (uint64_t)0U && (uint64_t)len > (uint64_t)0U) + { + ite = block_len(i); + } + else + { + ite = (uint32_t)((uint64_t)len % (uint64_t)block_len(i)); + } + uint32_t n_blocks = (len - ite) / block_len(i); + uint32_t data1_len = n_blocks * block_len(i); + uint32_t data2_len = len - data1_len; + uint8_t *data1 = data; + uint8_t *data2 = data + data1_len; + Spec_Hash_Definitions_hash_alg a1 = block_state1.fst; + uint64_t *s2 = block_state1.snd; + Hacl_Hash_SHA3_update_multi_sha3(a1, s2, data1, data1_len / block_len(a1)); + uint8_t *dst = buf; + memcpy(dst, data2, data2_len * sizeof (uint8_t)); + *p + = + ( + (Hacl_Streaming_Keccak_state){ + .block_state = block_state1, + .buf = buf, + .total_len = total_len1 + (uint64_t)len + } + ); + } + else + { + uint32_t diff = block_len(i) - sz; + uint8_t *data1 = data; + uint8_t *data2 = data + diff; + Hacl_Streaming_Keccak_state s1 = *p; + Hacl_Streaming_Keccak_hash_buf block_state10 = s1.block_state; + uint8_t *buf0 = s1.buf; + uint64_t total_len10 = s1.total_len; + uint32_t sz10; + if (total_len10 % (uint64_t)block_len(i) == (uint64_t)0U && total_len10 > (uint64_t)0U) + { + sz10 = block_len(i); + } + else + { + sz10 = (uint32_t)(total_len10 % (uint64_t)block_len(i)); + } + uint8_t *buf2 = buf0 + sz10; + memcpy(buf2, data1, diff * sizeof (uint8_t)); + uint64_t total_len2 = total_len10 + (uint64_t)diff; + *p + = + ( + (Hacl_Streaming_Keccak_state){ + .block_state = block_state10, + .buf = buf0, + .total_len = total_len2 + } + ); + Hacl_Streaming_Keccak_state s10 = *p; + Hacl_Streaming_Keccak_hash_buf block_state1 = s10.block_state; + uint8_t *buf = s10.buf; + uint64_t total_len1 = s10.total_len; + uint32_t sz1; + if (total_len1 % (uint64_t)block_len(i) == (uint64_t)0U && total_len1 > (uint64_t)0U) + { + sz1 = block_len(i); + } + else + { + sz1 = (uint32_t)(total_len1 % (uint64_t)block_len(i)); + } + if (!(sz1 == (uint32_t)0U)) + { + Spec_Hash_Definitions_hash_alg a1 = block_state1.fst; + uint64_t *s2 = block_state1.snd; + Hacl_Hash_SHA3_update_multi_sha3(a1, s2, buf, block_len(i) / block_len(a1)); + } + uint32_t ite; + if + ( + (uint64_t)(len - diff) + % (uint64_t)block_len(i) + == (uint64_t)0U + && (uint64_t)(len - diff) > (uint64_t)0U + ) + { + ite = block_len(i); + } + else + { + ite = (uint32_t)((uint64_t)(len - diff) % (uint64_t)block_len(i)); + } + uint32_t n_blocks = (len - diff - ite) / block_len(i); + uint32_t data1_len = n_blocks * block_len(i); + uint32_t data2_len = len - diff - data1_len; + uint8_t *data11 = data2; + uint8_t *data21 = data2 + data1_len; + Spec_Hash_Definitions_hash_alg a1 = block_state1.fst; + uint64_t *s2 = block_state1.snd; + Hacl_Hash_SHA3_update_multi_sha3(a1, s2, data11, data1_len / block_len(a1)); + uint8_t *dst = buf; + memcpy(dst, data21, data2_len * sizeof (uint8_t)); + *p + = + ( + (Hacl_Streaming_Keccak_state){ + .block_state = block_state1, + .buf = buf, + .total_len = total_len1 + (uint64_t)(len - diff) + } + ); + } + return Hacl_Streaming_Types_Success; +} + +static void +finish_( + Spec_Hash_Definitions_hash_alg a, + Hacl_Streaming_Keccak_state *p, + uint8_t *dst, + uint32_t l +) +{ + Hacl_Streaming_Keccak_state scrut0 = *p; + Hacl_Streaming_Keccak_hash_buf block_state = scrut0.block_state; + uint8_t *buf_ = scrut0.buf; + uint64_t total_len = scrut0.total_len; + uint32_t r; + if (total_len % (uint64_t)block_len(a) == (uint64_t)0U && total_len > (uint64_t)0U) + { + r = block_len(a); + } + else + { + r = (uint32_t)(total_len % (uint64_t)block_len(a)); + } + uint8_t *buf_1 = buf_; + uint64_t buf[25U] = { 0U }; + Hacl_Streaming_Keccak_hash_buf tmp_block_state = { .fst = a, .snd = buf }; + hash_buf2 scrut = { .fst = block_state, .snd = tmp_block_state }; + uint64_t *s_dst = scrut.snd.snd; + uint64_t *s_src = scrut.fst.snd; + memcpy(s_dst, s_src, (uint32_t)25U * sizeof (uint64_t)); + uint32_t ite0; + if (r % block_len(a) == (uint32_t)0U && r > (uint32_t)0U) + { + ite0 = block_len(a); + } + else + { + ite0 = r % block_len(a); + } + uint8_t *buf_last = buf_1 + r - ite0; + uint8_t *buf_multi = buf_1; + Spec_Hash_Definitions_hash_alg a1 = tmp_block_state.fst; + uint64_t *s0 = tmp_block_state.snd; + Hacl_Hash_SHA3_update_multi_sha3(a1, s0, buf_multi, (uint32_t)0U / block_len(a1)); + Spec_Hash_Definitions_hash_alg a10 = tmp_block_state.fst; + uint64_t *s1 = tmp_block_state.snd; + Hacl_Hash_SHA3_update_last_sha3(a10, s1, buf_last, r); + Spec_Hash_Definitions_hash_alg a11 = tmp_block_state.fst; + uint64_t *s = tmp_block_state.snd; + if (a11 == Spec_Hash_Definitions_Shake128 || a11 == Spec_Hash_Definitions_Shake256) + { + uint32_t ite; + if (a11 == Spec_Hash_Definitions_Shake128 || a11 == Spec_Hash_Definitions_Shake256) + { + ite = l; + } + else + { + ite = hash_len(a11); + } + Hacl_Impl_SHA3_squeeze(s, block_len(a11), ite, dst); + return; + } + Hacl_Impl_SHA3_squeeze(s, block_len(a11), hash_len(a11), dst); +} + +Hacl_Streaming_Types_error_code +Hacl_Streaming_Keccak_finish(Hacl_Streaming_Keccak_state *s, uint8_t *dst) +{ + Spec_Hash_Definitions_hash_alg a1 = Hacl_Streaming_Keccak_get_alg(s); + if (a1 == Spec_Hash_Definitions_Shake128 || a1 == Spec_Hash_Definitions_Shake256) + { + return Hacl_Streaming_Types_InvalidAlgorithm; + } + finish_(a1, s, dst, hash_len(a1)); + return Hacl_Streaming_Types_Success; +} + +Hacl_Streaming_Types_error_code +Hacl_Streaming_Keccak_squeeze(Hacl_Streaming_Keccak_state *s, uint8_t *dst, uint32_t l) +{ + Spec_Hash_Definitions_hash_alg a1 = Hacl_Streaming_Keccak_get_alg(s); + if (!(a1 == Spec_Hash_Definitions_Shake128 || a1 == Spec_Hash_Definitions_Shake256)) + { + return Hacl_Streaming_Types_InvalidAlgorithm; + } + if (l == (uint32_t)0U) + { + return Hacl_Streaming_Types_InvalidLength; + } + finish_(a1, s, dst, l); + return Hacl_Streaming_Types_Success; +} + +uint32_t Hacl_Streaming_Keccak_block_len(Hacl_Streaming_Keccak_state *s) +{ + Spec_Hash_Definitions_hash_alg a1 = Hacl_Streaming_Keccak_get_alg(s); + return block_len(a1); +} + +uint32_t Hacl_Streaming_Keccak_hash_len(Hacl_Streaming_Keccak_state *s) +{ + Spec_Hash_Definitions_hash_alg a1 = Hacl_Streaming_Keccak_get_alg(s); + return hash_len(a1); +} + +bool Hacl_Streaming_Keccak_is_shake(Hacl_Streaming_Keccak_state *s) +{ + Spec_Hash_Definitions_hash_alg uu____0 = Hacl_Streaming_Keccak_get_alg(s); + return uu____0 == Spec_Hash_Definitions_Shake128 || uu____0 == Spec_Hash_Definitions_Shake256; +} + +void +Hacl_SHA3_shake128_hacl( + uint32_t inputByteLen, + uint8_t *input, + uint32_t outputByteLen, + uint8_t *output +) +{ + Hacl_Impl_SHA3_keccak((uint32_t)1344U, + (uint32_t)256U, + inputByteLen, + input, + (uint8_t)0x1FU, + outputByteLen, + output); +} + +void +Hacl_SHA3_shake256_hacl( + uint32_t inputByteLen, + uint8_t *input, + uint32_t outputByteLen, + uint8_t *output +) +{ + Hacl_Impl_SHA3_keccak((uint32_t)1088U, + (uint32_t)512U, + inputByteLen, + input, + (uint8_t)0x1FU, + outputByteLen, + output); +} + +void Hacl_SHA3_sha3_224(uint32_t inputByteLen, uint8_t *input, uint8_t *output) +{ + Hacl_Impl_SHA3_keccak((uint32_t)1152U, + (uint32_t)448U, + inputByteLen, + input, + (uint8_t)0x06U, + (uint32_t)28U, + output); +} + +void Hacl_SHA3_sha3_256(uint32_t inputByteLen, uint8_t *input, uint8_t *output) +{ + Hacl_Impl_SHA3_keccak((uint32_t)1088U, + (uint32_t)512U, + inputByteLen, + input, + (uint8_t)0x06U, + (uint32_t)32U, + output); +} + +void Hacl_SHA3_sha3_384(uint32_t inputByteLen, uint8_t *input, uint8_t *output) +{ + Hacl_Impl_SHA3_keccak((uint32_t)832U, + (uint32_t)768U, + inputByteLen, + input, + (uint8_t)0x06U, + (uint32_t)48U, + output); +} + +void Hacl_SHA3_sha3_512(uint32_t inputByteLen, uint8_t *input, uint8_t *output) +{ + Hacl_Impl_SHA3_keccak((uint32_t)576U, + (uint32_t)1024U, + inputByteLen, + input, + (uint8_t)0x06U, + (uint32_t)64U, + output); +} + +static const +uint32_t +keccak_rotc[24U] = + { + (uint32_t)1U, (uint32_t)3U, (uint32_t)6U, (uint32_t)10U, (uint32_t)15U, (uint32_t)21U, + (uint32_t)28U, (uint32_t)36U, (uint32_t)45U, (uint32_t)55U, (uint32_t)2U, (uint32_t)14U, + (uint32_t)27U, (uint32_t)41U, (uint32_t)56U, (uint32_t)8U, (uint32_t)25U, (uint32_t)43U, + (uint32_t)62U, (uint32_t)18U, (uint32_t)39U, (uint32_t)61U, (uint32_t)20U, (uint32_t)44U + }; + +static const +uint32_t +keccak_piln[24U] = + { + (uint32_t)10U, (uint32_t)7U, (uint32_t)11U, (uint32_t)17U, (uint32_t)18U, (uint32_t)3U, + (uint32_t)5U, (uint32_t)16U, (uint32_t)8U, (uint32_t)21U, (uint32_t)24U, (uint32_t)4U, + (uint32_t)15U, (uint32_t)23U, (uint32_t)19U, (uint32_t)13U, (uint32_t)12U, (uint32_t)2U, + (uint32_t)20U, (uint32_t)14U, (uint32_t)22U, (uint32_t)9U, (uint32_t)6U, (uint32_t)1U + }; + +static const +uint64_t +keccak_rndc[24U] = + { + (uint64_t)0x0000000000000001U, (uint64_t)0x0000000000008082U, (uint64_t)0x800000000000808aU, + (uint64_t)0x8000000080008000U, (uint64_t)0x000000000000808bU, (uint64_t)0x0000000080000001U, + (uint64_t)0x8000000080008081U, (uint64_t)0x8000000000008009U, (uint64_t)0x000000000000008aU, + (uint64_t)0x0000000000000088U, (uint64_t)0x0000000080008009U, (uint64_t)0x000000008000000aU, + (uint64_t)0x000000008000808bU, (uint64_t)0x800000000000008bU, (uint64_t)0x8000000000008089U, + (uint64_t)0x8000000000008003U, (uint64_t)0x8000000000008002U, (uint64_t)0x8000000000000080U, + (uint64_t)0x000000000000800aU, (uint64_t)0x800000008000000aU, (uint64_t)0x8000000080008081U, + (uint64_t)0x8000000000008080U, (uint64_t)0x0000000080000001U, (uint64_t)0x8000000080008008U + }; + +void Hacl_Impl_SHA3_state_permute(uint64_t *s) +{ + for (uint32_t i0 = (uint32_t)0U; i0 < (uint32_t)24U; i0++) + { + uint64_t _C[5U] = { 0U }; + KRML_MAYBE_FOR5(i, + (uint32_t)0U, + (uint32_t)5U, + (uint32_t)1U, + _C[i] = + s[i + + (uint32_t)0U] + ^ + (s[i + + (uint32_t)5U] + ^ (s[i + (uint32_t)10U] ^ (s[i + (uint32_t)15U] ^ s[i + (uint32_t)20U])));); + KRML_MAYBE_FOR5(i1, + (uint32_t)0U, + (uint32_t)5U, + (uint32_t)1U, + uint64_t uu____0 = _C[(i1 + (uint32_t)1U) % (uint32_t)5U]; + uint64_t + _D = + _C[(i1 + (uint32_t)4U) + % (uint32_t)5U] + ^ (uu____0 << (uint32_t)1U | uu____0 >> (uint32_t)63U); + KRML_MAYBE_FOR5(i, + (uint32_t)0U, + (uint32_t)5U, + (uint32_t)1U, + s[i1 + (uint32_t)5U * i] = s[i1 + (uint32_t)5U * i] ^ _D;);); + uint64_t x = s[1U]; + uint64_t current = x; + for (uint32_t i = (uint32_t)0U; i < (uint32_t)24U; i++) + { + uint32_t _Y = keccak_piln[i]; + uint32_t r = keccak_rotc[i]; + uint64_t temp = s[_Y]; + uint64_t uu____1 = current; + s[_Y] = uu____1 << r | uu____1 >> ((uint32_t)64U - r); + current = temp; + } + KRML_MAYBE_FOR5(i, + (uint32_t)0U, + (uint32_t)5U, + (uint32_t)1U, + uint64_t + v0 = + s[(uint32_t)0U + + (uint32_t)5U * i] + ^ (~s[(uint32_t)1U + (uint32_t)5U * i] & s[(uint32_t)2U + (uint32_t)5U * i]); + uint64_t + v1 = + s[(uint32_t)1U + + (uint32_t)5U * i] + ^ (~s[(uint32_t)2U + (uint32_t)5U * i] & s[(uint32_t)3U + (uint32_t)5U * i]); + uint64_t + v2 = + s[(uint32_t)2U + + (uint32_t)5U * i] + ^ (~s[(uint32_t)3U + (uint32_t)5U * i] & s[(uint32_t)4U + (uint32_t)5U * i]); + uint64_t + v3 = + s[(uint32_t)3U + + (uint32_t)5U * i] + ^ (~s[(uint32_t)4U + (uint32_t)5U * i] & s[(uint32_t)0U + (uint32_t)5U * i]); + uint64_t + v4 = + s[(uint32_t)4U + + (uint32_t)5U * i] + ^ (~s[(uint32_t)0U + (uint32_t)5U * i] & s[(uint32_t)1U + (uint32_t)5U * i]); + s[(uint32_t)0U + (uint32_t)5U * i] = v0; + s[(uint32_t)1U + (uint32_t)5U * i] = v1; + s[(uint32_t)2U + (uint32_t)5U * i] = v2; + s[(uint32_t)3U + (uint32_t)5U * i] = v3; + s[(uint32_t)4U + (uint32_t)5U * i] = v4;); + uint64_t c = keccak_rndc[i0]; + s[0U] = s[0U] ^ c; + } +} + +void Hacl_Impl_SHA3_loadState(uint32_t rateInBytes, uint8_t *input, uint64_t *s) +{ + uint8_t block[200U] = { 0U }; + memcpy(block, input, rateInBytes * sizeof (uint8_t)); + for (uint32_t i = (uint32_t)0U; i < (uint32_t)25U; i++) + { + uint64_t u = load64_le(block + i * (uint32_t)8U); + uint64_t x = u; + s[i] = s[i] ^ x; + } +} + +static void storeState(uint32_t rateInBytes, uint64_t *s, uint8_t *res) +{ + uint8_t block[200U] = { 0U }; + for (uint32_t i = (uint32_t)0U; i < (uint32_t)25U; i++) + { + uint64_t sj = s[i]; + store64_le(block + i * (uint32_t)8U, sj); + } + memcpy(res, block, rateInBytes * sizeof (uint8_t)); +} + +void Hacl_Impl_SHA3_absorb_inner(uint32_t rateInBytes, uint8_t *block, uint64_t *s) +{ + Hacl_Impl_SHA3_loadState(rateInBytes, block, s); + Hacl_Impl_SHA3_state_permute(s); +} + +static void +absorb( + uint64_t *s, + uint32_t rateInBytes, + uint32_t inputByteLen, + uint8_t *input, + uint8_t delimitedSuffix +) +{ + uint32_t n_blocks = inputByteLen / rateInBytes; + uint32_t rem = inputByteLen % rateInBytes; + for (uint32_t i = (uint32_t)0U; i < n_blocks; i++) + { + uint8_t *block = input + i * rateInBytes; + Hacl_Impl_SHA3_absorb_inner(rateInBytes, block, s); + } + uint8_t *last = input + n_blocks * rateInBytes; + uint8_t lastBlock_[200U] = { 0U }; + uint8_t *lastBlock = lastBlock_; + memcpy(lastBlock, last, rem * sizeof (uint8_t)); + lastBlock[rem] = delimitedSuffix; + Hacl_Impl_SHA3_loadState(rateInBytes, lastBlock, s); + if (!((delimitedSuffix & (uint8_t)0x80U) == (uint8_t)0U) && rem == rateInBytes - (uint32_t)1U) + { + Hacl_Impl_SHA3_state_permute(s); + } + uint8_t nextBlock_[200U] = { 0U }; + uint8_t *nextBlock = nextBlock_; + nextBlock[rateInBytes - (uint32_t)1U] = (uint8_t)0x80U; + Hacl_Impl_SHA3_loadState(rateInBytes, nextBlock, s); + Hacl_Impl_SHA3_state_permute(s); +} + +void +Hacl_Impl_SHA3_squeeze( + uint64_t *s, + uint32_t rateInBytes, + uint32_t outputByteLen, + uint8_t *output +) +{ + uint32_t outBlocks = outputByteLen / rateInBytes; + uint32_t remOut = outputByteLen % rateInBytes; + uint8_t *last = output + outputByteLen - remOut; + uint8_t *blocks = output; + for (uint32_t i = (uint32_t)0U; i < outBlocks; i++) + { + storeState(rateInBytes, s, blocks + i * rateInBytes); + Hacl_Impl_SHA3_state_permute(s); + } + storeState(remOut, s, last); +} + +void +Hacl_Impl_SHA3_keccak( + uint32_t rate, + uint32_t capacity, + uint32_t inputByteLen, + uint8_t *input, + uint8_t delimitedSuffix, + uint32_t outputByteLen, + uint8_t *output +) +{ + uint32_t rateInBytes = rate / (uint32_t)8U; + uint64_t s[25U] = { 0U }; + absorb(s, rateInBytes, inputByteLen, input, delimitedSuffix); + Hacl_Impl_SHA3_squeeze(s, rateInBytes, outputByteLen, output); +} + diff --git a/Modules/_hacl/Hacl_Hash_SHA3.h b/Modules/_hacl/Hacl_Hash_SHA3.h new file mode 100644 index 00000000..681b6af4 --- /dev/null +++ b/Modules/_hacl/Hacl_Hash_SHA3.h @@ -0,0 +1,130 @@ +/* MIT License + * + * Copyright (c) 2016-2022 INRIA, CMU and Microsoft Corporation + * Copyright (c) 2022-2023 HACL* Contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + + +#ifndef __Hacl_Hash_SHA3_H +#define __Hacl_Hash_SHA3_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include <string.h> +#include "krml/types.h" +#include "krml/lowstar_endianness.h" +#include "krml/internal/target.h" + +#include "Hacl_Streaming_Types.h" + +typedef struct Hacl_Streaming_Keccak_hash_buf_s +{ + Spec_Hash_Definitions_hash_alg fst; + uint64_t *snd; +} +Hacl_Streaming_Keccak_hash_buf; + +typedef struct Hacl_Streaming_Keccak_state_s +{ + Hacl_Streaming_Keccak_hash_buf block_state; + uint8_t *buf; + uint64_t total_len; +} +Hacl_Streaming_Keccak_state; + +Spec_Hash_Definitions_hash_alg Hacl_Streaming_Keccak_get_alg(Hacl_Streaming_Keccak_state *s); + +Hacl_Streaming_Keccak_state *Hacl_Streaming_Keccak_malloc(Spec_Hash_Definitions_hash_alg a); + +void Hacl_Streaming_Keccak_free(Hacl_Streaming_Keccak_state *s); + +Hacl_Streaming_Keccak_state *Hacl_Streaming_Keccak_copy(Hacl_Streaming_Keccak_state *s0); + +void Hacl_Streaming_Keccak_reset(Hacl_Streaming_Keccak_state *s); + +Hacl_Streaming_Types_error_code +Hacl_Streaming_Keccak_update(Hacl_Streaming_Keccak_state *p, uint8_t *data, uint32_t len); + +Hacl_Streaming_Types_error_code +Hacl_Streaming_Keccak_finish(Hacl_Streaming_Keccak_state *s, uint8_t *dst); + +Hacl_Streaming_Types_error_code +Hacl_Streaming_Keccak_squeeze(Hacl_Streaming_Keccak_state *s, uint8_t *dst, uint32_t l); + +uint32_t Hacl_Streaming_Keccak_block_len(Hacl_Streaming_Keccak_state *s); + +uint32_t Hacl_Streaming_Keccak_hash_len(Hacl_Streaming_Keccak_state *s); + +bool Hacl_Streaming_Keccak_is_shake(Hacl_Streaming_Keccak_state *s); + +void +Hacl_SHA3_shake128_hacl( + uint32_t inputByteLen, + uint8_t *input, + uint32_t outputByteLen, + uint8_t *output +); + +void +Hacl_SHA3_shake256_hacl( + uint32_t inputByteLen, + uint8_t *input, + uint32_t outputByteLen, + uint8_t *output +); + +void Hacl_SHA3_sha3_224(uint32_t inputByteLen, uint8_t *input, uint8_t *output); + +void Hacl_SHA3_sha3_256(uint32_t inputByteLen, uint8_t *input, uint8_t *output); + +void Hacl_SHA3_sha3_384(uint32_t inputByteLen, uint8_t *input, uint8_t *output); + +void Hacl_SHA3_sha3_512(uint32_t inputByteLen, uint8_t *input, uint8_t *output); + +void Hacl_Impl_SHA3_absorb_inner(uint32_t rateInBytes, uint8_t *block, uint64_t *s); + +void +Hacl_Impl_SHA3_squeeze( + uint64_t *s, + uint32_t rateInBytes, + uint32_t outputByteLen, + uint8_t *output +); + +void +Hacl_Impl_SHA3_keccak( + uint32_t rate, + uint32_t capacity, + uint32_t inputByteLen, + uint8_t *input, + uint8_t delimitedSuffix, + uint32_t outputByteLen, + uint8_t *output +); + +#if defined(__cplusplus) +} +#endif + +#define __Hacl_Hash_SHA3_H_DEFINED +#endif diff --git a/Modules/_hacl/Hacl_Streaming_Types.h b/Modules/_hacl/Hacl_Streaming_Types.h new file mode 100644 index 00000000..15ef16ba --- /dev/null +++ b/Modules/_hacl/Hacl_Streaming_Types.h @@ -0,0 +1,83 @@ +/* MIT License + * + * Copyright (c) 2016-2022 INRIA, CMU and Microsoft Corporation + * Copyright (c) 2022-2023 HACL* Contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + + +#ifndef __Hacl_Streaming_Types_H +#define __Hacl_Streaming_Types_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include <string.h> +#include "krml/types.h" +#include "krml/lowstar_endianness.h" +#include "krml/internal/target.h" + +#define Spec_Hash_Definitions_SHA2_224 0 +#define Spec_Hash_Definitions_SHA2_256 1 +#define Spec_Hash_Definitions_SHA2_384 2 +#define Spec_Hash_Definitions_SHA2_512 3 +#define Spec_Hash_Definitions_SHA1 4 +#define Spec_Hash_Definitions_MD5 5 +#define Spec_Hash_Definitions_Blake2S 6 +#define Spec_Hash_Definitions_Blake2B 7 +#define Spec_Hash_Definitions_SHA3_256 8 +#define Spec_Hash_Definitions_SHA3_224 9 +#define Spec_Hash_Definitions_SHA3_384 10 +#define Spec_Hash_Definitions_SHA3_512 11 +#define Spec_Hash_Definitions_Shake128 12 +#define Spec_Hash_Definitions_Shake256 13 + +typedef uint8_t Spec_Hash_Definitions_hash_alg; + +#define Hacl_Streaming_Types_Success 0 +#define Hacl_Streaming_Types_InvalidAlgorithm 1 +#define Hacl_Streaming_Types_InvalidLength 2 +#define Hacl_Streaming_Types_MaximumLengthExceeded 3 + +typedef uint8_t Hacl_Streaming_Types_error_code; + +typedef struct Hacl_Streaming_MD_state_32_s +{ + uint32_t *block_state; + uint8_t *buf; + uint64_t total_len; +} +Hacl_Streaming_MD_state_32; + +typedef struct Hacl_Streaming_MD_state_64_s +{ + uint64_t *block_state; + uint8_t *buf; + uint64_t total_len; +} +Hacl_Streaming_MD_state_64; + +#if defined(__cplusplus) +} +#endif + +#define __Hacl_Streaming_Types_H_DEFINED +#endif diff --git a/Modules/_hacl/README.md b/Modules/_hacl/README.md new file mode 100644 index 00000000..e6a156a5 --- /dev/null +++ b/Modules/_hacl/README.md @@ -0,0 +1,29 @@ +# Algorithm implementations used by the `hashlib` module. + +This code comes from the +[HACL\*](https://github.com/hacl-star/hacl-star/) project. + +HACL\* is a cryptographic library that has been formally verified for memory +safety, functional correctness, and secret independence. + +## Updating HACL* + +Use the `refresh.sh` script in this directory to pull in a new upstream code +version. The upstream git hash used for the most recent code pull is recorded +in the script. Modify the script as needed to bring in more if changes are +needed based on upstream code refactoring. + +Never manually edit HACL\* files. Always add transformation shell code to the +`refresh.sh` script to perform any necessary edits. If there are serious code +changes needed, work with the upstream repository. + +## Local files + +1. `./include/python_hacl_namespaces.h` +1. `./README.md` +1. `./refresh.sh` + +## ACKS + +* Jonathan Protzenko aka [@msprotz on Github](https://github.com/msprotz) +contributed our HACL\* based builtin code. diff --git a/Modules/_hacl/include/krml/FStar_UInt128_Verified.h b/Modules/_hacl/include/krml/FStar_UInt128_Verified.h new file mode 100644 index 00000000..3d36d440 --- /dev/null +++ b/Modules/_hacl/include/krml/FStar_UInt128_Verified.h @@ -0,0 +1,346 @@ +/* + Copyright (c) INRIA and Microsoft Corporation. All rights reserved. + Licensed under the Apache 2.0 License. +*/ + + +#ifndef __FStar_UInt128_Verified_H +#define __FStar_UInt128_Verified_H + +#include "FStar_UInt_8_16_32_64.h" +#include <inttypes.h> +#include <stdbool.h> +#include "krml/types.h" +#include "krml/internal/target.h" + +static inline uint64_t FStar_UInt128_constant_time_carry(uint64_t a, uint64_t b) +{ + return (a ^ ((a ^ b) | ((a - b) ^ b))) >> (uint32_t)63U; +} + +static inline uint64_t FStar_UInt128_carry(uint64_t a, uint64_t b) +{ + return FStar_UInt128_constant_time_carry(a, b); +} + +static inline FStar_UInt128_uint128 +FStar_UInt128_add(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b) +{ + FStar_UInt128_uint128 lit; + lit.low = a.low + b.low; + lit.high = a.high + b.high + FStar_UInt128_carry(a.low + b.low, b.low); + return lit; +} + +static inline FStar_UInt128_uint128 +FStar_UInt128_add_underspec(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b) +{ + FStar_UInt128_uint128 lit; + lit.low = a.low + b.low; + lit.high = a.high + b.high + FStar_UInt128_carry(a.low + b.low, b.low); + return lit; +} + +static inline FStar_UInt128_uint128 +FStar_UInt128_add_mod(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b) +{ + FStar_UInt128_uint128 lit; + lit.low = a.low + b.low; + lit.high = a.high + b.high + FStar_UInt128_carry(a.low + b.low, b.low); + return lit; +} + +static inline FStar_UInt128_uint128 +FStar_UInt128_sub(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b) +{ + FStar_UInt128_uint128 lit; + lit.low = a.low - b.low; + lit.high = a.high - b.high - FStar_UInt128_carry(a.low, a.low - b.low); + return lit; +} + +static inline FStar_UInt128_uint128 +FStar_UInt128_sub_underspec(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b) +{ + FStar_UInt128_uint128 lit; + lit.low = a.low - b.low; + lit.high = a.high - b.high - FStar_UInt128_carry(a.low, a.low - b.low); + return lit; +} + +static inline FStar_UInt128_uint128 +FStar_UInt128_sub_mod_impl(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b) +{ + FStar_UInt128_uint128 lit; + lit.low = a.low - b.low; + lit.high = a.high - b.high - FStar_UInt128_carry(a.low, a.low - b.low); + return lit; +} + +static inline FStar_UInt128_uint128 +FStar_UInt128_sub_mod(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b) +{ + return FStar_UInt128_sub_mod_impl(a, b); +} + +static inline FStar_UInt128_uint128 +FStar_UInt128_logand(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b) +{ + FStar_UInt128_uint128 lit; + lit.low = a.low & b.low; + lit.high = a.high & b.high; + return lit; +} + +static inline FStar_UInt128_uint128 +FStar_UInt128_logxor(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b) +{ + FStar_UInt128_uint128 lit; + lit.low = a.low ^ b.low; + lit.high = a.high ^ b.high; + return lit; +} + +static inline FStar_UInt128_uint128 +FStar_UInt128_logor(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b) +{ + FStar_UInt128_uint128 lit; + lit.low = a.low | b.low; + lit.high = a.high | b.high; + return lit; +} + +static inline FStar_UInt128_uint128 FStar_UInt128_lognot(FStar_UInt128_uint128 a) +{ + FStar_UInt128_uint128 lit; + lit.low = ~a.low; + lit.high = ~a.high; + return lit; +} + +static uint32_t FStar_UInt128_u32_64 = (uint32_t)64U; + +static inline uint64_t FStar_UInt128_add_u64_shift_left(uint64_t hi, uint64_t lo, uint32_t s) +{ + return (hi << s) + (lo >> (FStar_UInt128_u32_64 - s)); +} + +static inline uint64_t +FStar_UInt128_add_u64_shift_left_respec(uint64_t hi, uint64_t lo, uint32_t s) +{ + return FStar_UInt128_add_u64_shift_left(hi, lo, s); +} + +static inline FStar_UInt128_uint128 +FStar_UInt128_shift_left_small(FStar_UInt128_uint128 a, uint32_t s) +{ + if (s == (uint32_t)0U) + { + return a; + } + else + { + FStar_UInt128_uint128 lit; + lit.low = a.low << s; + lit.high = FStar_UInt128_add_u64_shift_left_respec(a.high, a.low, s); + return lit; + } +} + +static inline FStar_UInt128_uint128 +FStar_UInt128_shift_left_large(FStar_UInt128_uint128 a, uint32_t s) +{ + FStar_UInt128_uint128 lit; + lit.low = (uint64_t)0U; + lit.high = a.low << (s - FStar_UInt128_u32_64); + return lit; +} + +static inline FStar_UInt128_uint128 +FStar_UInt128_shift_left(FStar_UInt128_uint128 a, uint32_t s) +{ + if (s < FStar_UInt128_u32_64) + { + return FStar_UInt128_shift_left_small(a, s); + } + else + { + return FStar_UInt128_shift_left_large(a, s); + } +} + +static inline uint64_t FStar_UInt128_add_u64_shift_right(uint64_t hi, uint64_t lo, uint32_t s) +{ + return (lo >> s) + (hi << (FStar_UInt128_u32_64 - s)); +} + +static inline uint64_t +FStar_UInt128_add_u64_shift_right_respec(uint64_t hi, uint64_t lo, uint32_t s) +{ + return FStar_UInt128_add_u64_shift_right(hi, lo, s); +} + +static inline FStar_UInt128_uint128 +FStar_UInt128_shift_right_small(FStar_UInt128_uint128 a, uint32_t s) +{ + if (s == (uint32_t)0U) + { + return a; + } + else + { + FStar_UInt128_uint128 lit; + lit.low = FStar_UInt128_add_u64_shift_right_respec(a.high, a.low, s); + lit.high = a.high >> s; + return lit; + } +} + +static inline FStar_UInt128_uint128 +FStar_UInt128_shift_right_large(FStar_UInt128_uint128 a, uint32_t s) +{ + FStar_UInt128_uint128 lit; + lit.low = a.high >> (s - FStar_UInt128_u32_64); + lit.high = (uint64_t)0U; + return lit; +} + +static inline FStar_UInt128_uint128 +FStar_UInt128_shift_right(FStar_UInt128_uint128 a, uint32_t s) +{ + if (s < FStar_UInt128_u32_64) + { + return FStar_UInt128_shift_right_small(a, s); + } + else + { + return FStar_UInt128_shift_right_large(a, s); + } +} + +static inline bool FStar_UInt128_eq(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b) +{ + return a.low == b.low && a.high == b.high; +} + +static inline bool FStar_UInt128_gt(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b) +{ + return a.high > b.high || (a.high == b.high && a.low > b.low); +} + +static inline bool FStar_UInt128_lt(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b) +{ + return a.high < b.high || (a.high == b.high && a.low < b.low); +} + +static inline bool FStar_UInt128_gte(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b) +{ + return a.high > b.high || (a.high == b.high && a.low >= b.low); +} + +static inline bool FStar_UInt128_lte(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b) +{ + return a.high < b.high || (a.high == b.high && a.low <= b.low); +} + +static inline FStar_UInt128_uint128 +FStar_UInt128_eq_mask(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b) +{ + FStar_UInt128_uint128 lit; + lit.low = FStar_UInt64_eq_mask(a.low, b.low) & FStar_UInt64_eq_mask(a.high, b.high); + lit.high = FStar_UInt64_eq_mask(a.low, b.low) & FStar_UInt64_eq_mask(a.high, b.high); + return lit; +} + +static inline FStar_UInt128_uint128 +FStar_UInt128_gte_mask(FStar_UInt128_uint128 a, FStar_UInt128_uint128 b) +{ + FStar_UInt128_uint128 lit; + lit.low = + (FStar_UInt64_gte_mask(a.high, b.high) & ~FStar_UInt64_eq_mask(a.high, b.high)) + | (FStar_UInt64_eq_mask(a.high, b.high) & FStar_UInt64_gte_mask(a.low, b.low)); + lit.high = + (FStar_UInt64_gte_mask(a.high, b.high) & ~FStar_UInt64_eq_mask(a.high, b.high)) + | (FStar_UInt64_eq_mask(a.high, b.high) & FStar_UInt64_gte_mask(a.low, b.low)); + return lit; +} + +static inline FStar_UInt128_uint128 FStar_UInt128_uint64_to_uint128(uint64_t a) +{ + FStar_UInt128_uint128 lit; + lit.low = a; + lit.high = (uint64_t)0U; + return lit; +} + +static inline uint64_t FStar_UInt128_uint128_to_uint64(FStar_UInt128_uint128 a) +{ + return a.low; +} + +static inline uint64_t FStar_UInt128_u64_mod_32(uint64_t a) +{ + return a & (uint64_t)0xffffffffU; +} + +static uint32_t FStar_UInt128_u32_32 = (uint32_t)32U; + +static inline uint64_t FStar_UInt128_u32_combine(uint64_t hi, uint64_t lo) +{ + return lo + (hi << FStar_UInt128_u32_32); +} + +static inline FStar_UInt128_uint128 FStar_UInt128_mul32(uint64_t x, uint32_t y) +{ + FStar_UInt128_uint128 lit; + lit.low = + FStar_UInt128_u32_combine((x >> FStar_UInt128_u32_32) + * (uint64_t)y + + (FStar_UInt128_u64_mod_32(x) * (uint64_t)y >> FStar_UInt128_u32_32), + FStar_UInt128_u64_mod_32(FStar_UInt128_u64_mod_32(x) * (uint64_t)y)); + lit.high = + ((x >> FStar_UInt128_u32_32) + * (uint64_t)y + + (FStar_UInt128_u64_mod_32(x) * (uint64_t)y >> FStar_UInt128_u32_32)) + >> FStar_UInt128_u32_32; + return lit; +} + +static inline uint64_t FStar_UInt128_u32_combine_(uint64_t hi, uint64_t lo) +{ + return lo + (hi << FStar_UInt128_u32_32); +} + +static inline FStar_UInt128_uint128 FStar_UInt128_mul_wide(uint64_t x, uint64_t y) +{ + FStar_UInt128_uint128 lit; + lit.low = + FStar_UInt128_u32_combine_(FStar_UInt128_u64_mod_32(x) + * (y >> FStar_UInt128_u32_32) + + + FStar_UInt128_u64_mod_32((x >> FStar_UInt128_u32_32) + * FStar_UInt128_u64_mod_32(y) + + (FStar_UInt128_u64_mod_32(x) * FStar_UInt128_u64_mod_32(y) >> FStar_UInt128_u32_32)), + FStar_UInt128_u64_mod_32(FStar_UInt128_u64_mod_32(x) * FStar_UInt128_u64_mod_32(y))); + lit.high = + (x >> FStar_UInt128_u32_32) + * (y >> FStar_UInt128_u32_32) + + + (((x >> FStar_UInt128_u32_32) + * FStar_UInt128_u64_mod_32(y) + + (FStar_UInt128_u64_mod_32(x) * FStar_UInt128_u64_mod_32(y) >> FStar_UInt128_u32_32)) + >> FStar_UInt128_u32_32) + + + ((FStar_UInt128_u64_mod_32(x) + * (y >> FStar_UInt128_u32_32) + + + FStar_UInt128_u64_mod_32((x >> FStar_UInt128_u32_32) + * FStar_UInt128_u64_mod_32(y) + + (FStar_UInt128_u64_mod_32(x) * FStar_UInt128_u64_mod_32(y) >> FStar_UInt128_u32_32))) + >> FStar_UInt128_u32_32); + return lit; +} + + +#define __FStar_UInt128_Verified_H_DEFINED +#endif diff --git a/Modules/_hacl/include/krml/FStar_UInt_8_16_32_64.h b/Modules/_hacl/include/krml/FStar_UInt_8_16_32_64.h new file mode 100644 index 00000000..a56c7d61 --- /dev/null +++ b/Modules/_hacl/include/krml/FStar_UInt_8_16_32_64.h @@ -0,0 +1,107 @@ +/* + Copyright (c) INRIA and Microsoft Corporation. All rights reserved. + Licensed under the Apache 2.0 License. +*/ + + +#ifndef __FStar_UInt_8_16_32_64_H +#define __FStar_UInt_8_16_32_64_H + +#include <inttypes.h> +#include <stdbool.h> + +#include "krml/lowstar_endianness.h" +#include "krml/types.h" +#include "krml/internal/target.h" + +static inline uint64_t FStar_UInt64_eq_mask(uint64_t a, uint64_t b) +{ + uint64_t x = a ^ b; + uint64_t minus_x = ~x + (uint64_t)1U; + uint64_t x_or_minus_x = x | minus_x; + uint64_t xnx = x_or_minus_x >> (uint32_t)63U; + return xnx - (uint64_t)1U; +} + +static inline uint64_t FStar_UInt64_gte_mask(uint64_t a, uint64_t b) +{ + uint64_t x = a; + uint64_t y = b; + uint64_t x_xor_y = x ^ y; + uint64_t x_sub_y = x - y; + uint64_t x_sub_y_xor_y = x_sub_y ^ y; + uint64_t q = x_xor_y | x_sub_y_xor_y; + uint64_t x_xor_q = x ^ q; + uint64_t x_xor_q_ = x_xor_q >> (uint32_t)63U; + return x_xor_q_ - (uint64_t)1U; +} + +static inline uint32_t FStar_UInt32_eq_mask(uint32_t a, uint32_t b) +{ + uint32_t x = a ^ b; + uint32_t minus_x = ~x + (uint32_t)1U; + uint32_t x_or_minus_x = x | minus_x; + uint32_t xnx = x_or_minus_x >> (uint32_t)31U; + return xnx - (uint32_t)1U; +} + +static inline uint32_t FStar_UInt32_gte_mask(uint32_t a, uint32_t b) +{ + uint32_t x = a; + uint32_t y = b; + uint32_t x_xor_y = x ^ y; + uint32_t x_sub_y = x - y; + uint32_t x_sub_y_xor_y = x_sub_y ^ y; + uint32_t q = x_xor_y | x_sub_y_xor_y; + uint32_t x_xor_q = x ^ q; + uint32_t x_xor_q_ = x_xor_q >> (uint32_t)31U; + return x_xor_q_ - (uint32_t)1U; +} + +static inline uint16_t FStar_UInt16_eq_mask(uint16_t a, uint16_t b) +{ + uint16_t x = a ^ b; + uint16_t minus_x = ~x + (uint16_t)1U; + uint16_t x_or_minus_x = x | minus_x; + uint16_t xnx = x_or_minus_x >> (uint32_t)15U; + return xnx - (uint16_t)1U; +} + +static inline uint16_t FStar_UInt16_gte_mask(uint16_t a, uint16_t b) +{ + uint16_t x = a; + uint16_t y = b; + uint16_t x_xor_y = x ^ y; + uint16_t x_sub_y = x - y; + uint16_t x_sub_y_xor_y = x_sub_y ^ y; + uint16_t q = x_xor_y | x_sub_y_xor_y; + uint16_t x_xor_q = x ^ q; + uint16_t x_xor_q_ = x_xor_q >> (uint32_t)15U; + return x_xor_q_ - (uint16_t)1U; +} + +static inline uint8_t FStar_UInt8_eq_mask(uint8_t a, uint8_t b) +{ + uint8_t x = a ^ b; + uint8_t minus_x = ~x + (uint8_t)1U; + uint8_t x_or_minus_x = x | minus_x; + uint8_t xnx = x_or_minus_x >> (uint32_t)7U; + return xnx - (uint8_t)1U; +} + +static inline uint8_t FStar_UInt8_gte_mask(uint8_t a, uint8_t b) +{ + uint8_t x = a; + uint8_t y = b; + uint8_t x_xor_y = x ^ y; + uint8_t x_sub_y = x - y; + uint8_t x_sub_y_xor_y = x_sub_y ^ y; + uint8_t q = x_xor_y | x_sub_y_xor_y; + uint8_t x_xor_q = x ^ q; + uint8_t x_xor_q_ = x_xor_q >> (uint32_t)7U; + return x_xor_q_ - (uint8_t)1U; +} + + +#define __FStar_UInt_8_16_32_64_H_DEFINED +#endif diff --git a/Modules/_hacl/include/krml/fstar_uint128_struct_endianness.h b/Modules/_hacl/include/krml/fstar_uint128_struct_endianness.h new file mode 100644 index 00000000..e2b6d628 --- /dev/null +++ b/Modules/_hacl/include/krml/fstar_uint128_struct_endianness.h @@ -0,0 +1,68 @@ +/* Copyright (c) INRIA and Microsoft Corporation. All rights reserved. + Licensed under the Apache 2.0 License. */ + +#ifndef FSTAR_UINT128_STRUCT_ENDIANNESS_H +#define FSTAR_UINT128_STRUCT_ENDIANNESS_H + +/* Hand-written implementation of endianness-related uint128 functions + * for the extracted uint128 implementation */ + +/* Access 64-bit fields within the int128. */ +#define HIGH64_OF(x) ((x)->high) +#define LOW64_OF(x) ((x)->low) + +/* A series of definitions written using pointers. */ + +inline static void load128_le_(uint8_t *b, uint128_t *r) { + LOW64_OF(r) = load64_le(b); + HIGH64_OF(r) = load64_le(b + 8); +} + +inline static void store128_le_(uint8_t *b, uint128_t *n) { + store64_le(b, LOW64_OF(n)); + store64_le(b + 8, HIGH64_OF(n)); +} + +inline static void load128_be_(uint8_t *b, uint128_t *r) { + HIGH64_OF(r) = load64_be(b); + LOW64_OF(r) = load64_be(b + 8); +} + +inline static void store128_be_(uint8_t *b, uint128_t *n) { + store64_be(b, HIGH64_OF(n)); + store64_be(b + 8, LOW64_OF(n)); +} + +#ifndef KRML_NOSTRUCT_PASSING + +inline static uint128_t load128_le(uint8_t *b) { + uint128_t r; + load128_le_(b, &r); + return r; +} + +inline static void store128_le(uint8_t *b, uint128_t n) { + store128_le_(b, &n); +} + +inline static uint128_t load128_be(uint8_t *b) { + uint128_t r; + load128_be_(b, &r); + return r; +} + +inline static void store128_be(uint8_t *b, uint128_t n) { + store128_be_(b, &n); +} + +#else /* !defined(KRML_STRUCT_PASSING) */ + +# define print128 print128_ +# define load128_le load128_le_ +# define store128_le store128_le_ +# define load128_be load128_be_ +# define store128_be store128_be_ + +#endif /* KRML_STRUCT_PASSING */ + +#endif diff --git a/Modules/_hacl/include/krml/internal/target.h b/Modules/_hacl/include/krml/internal/target.h new file mode 100644 index 00000000..5a2f94eb --- /dev/null +++ b/Modules/_hacl/include/krml/internal/target.h @@ -0,0 +1,266 @@ +/* Copyright (c) INRIA and Microsoft Corporation. All rights reserved. + Licensed under the Apache 2.0 License. */ + +#ifndef __KRML_TARGET_H +#define __KRML_TARGET_H + +#include <stdlib.h> +#include <stddef.h> +#include <stdio.h> +#include <stdbool.h> +#include <inttypes.h> +#include <limits.h> +#include <assert.h> + +/* Since KaRaMeL emits the inline keyword unconditionally, we follow the + * guidelines at https://gcc.gnu.org/onlinedocs/gcc/Inline.html and make this + * __inline__ to ensure the code compiles with -std=c90 and earlier. */ +#ifdef __GNUC__ +# define inline __inline__ +#endif + +/******************************************************************************/ +/* Macros that KaRaMeL will generate. */ +/******************************************************************************/ + +/* For "bare" targets that do not have a C stdlib, the user might want to use + * [-add-early-include '"mydefinitions.h"'] and override these. */ +#ifndef KRML_HOST_PRINTF +# define KRML_HOST_PRINTF printf +#endif + +#if ( \ + (defined __STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \ + (!(defined KRML_HOST_EPRINTF))) +# define KRML_HOST_EPRINTF(...) fprintf(stderr, __VA_ARGS__) +#elif !(defined KRML_HOST_EPRINTF) && defined(_MSC_VER) +# define KRML_HOST_EPRINTF(...) fprintf(stderr, __VA_ARGS__) +#endif + +#ifndef KRML_HOST_EXIT +# define KRML_HOST_EXIT exit +#endif + +#ifndef KRML_HOST_MALLOC +# define KRML_HOST_MALLOC malloc +#endif + +#ifndef KRML_HOST_CALLOC +# define KRML_HOST_CALLOC calloc +#endif + +#ifndef KRML_HOST_FREE +# define KRML_HOST_FREE free +#endif + +#ifndef KRML_HOST_IGNORE +# define KRML_HOST_IGNORE(x) (void)(x) +#endif + +/* In FStar.Buffer.fst, the size of arrays is uint32_t, but it's a number of + * *elements*. Do an ugly, run-time check (some of which KaRaMeL can eliminate). + */ +#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 4)) +# define _KRML_CHECK_SIZE_PRAGMA \ + _Pragma("GCC diagnostic ignored \"-Wtype-limits\"") +#else +# define _KRML_CHECK_SIZE_PRAGMA +#endif + +#define KRML_CHECK_SIZE(size_elt, sz) \ + do { \ + _KRML_CHECK_SIZE_PRAGMA \ + if (((size_t)(sz)) > ((size_t)(SIZE_MAX / (size_elt)))) { \ + KRML_HOST_PRINTF( \ + "Maximum allocatable size exceeded, aborting before overflow at " \ + "%s:%d\n", \ + __FILE__, __LINE__); \ + KRML_HOST_EXIT(253); \ + } \ + } while (0) + +/* Macros for prettier unrolling of loops */ +#define KRML_LOOP1(i, n, x) { \ + x \ + i += n; \ +} + +#define KRML_LOOP2(i, n, x) \ + KRML_LOOP1(i, n, x) \ + KRML_LOOP1(i, n, x) + +#define KRML_LOOP3(i, n, x) \ + KRML_LOOP2(i, n, x) \ + KRML_LOOP1(i, n, x) + +#define KRML_LOOP4(i, n, x) \ + KRML_LOOP2(i, n, x) \ + KRML_LOOP2(i, n, x) + +#define KRML_LOOP5(i, n, x) \ + KRML_LOOP4(i, n, x) \ + KRML_LOOP1(i, n, x) + +#define KRML_LOOP6(i, n, x) \ + KRML_LOOP4(i, n, x) \ + KRML_LOOP2(i, n, x) + +#define KRML_LOOP7(i, n, x) \ + KRML_LOOP4(i, n, x) \ + KRML_LOOP3(i, n, x) + +#define KRML_LOOP8(i, n, x) \ + KRML_LOOP4(i, n, x) \ + KRML_LOOP4(i, n, x) + +#define KRML_LOOP9(i, n, x) \ + KRML_LOOP8(i, n, x) \ + KRML_LOOP1(i, n, x) + +#define KRML_LOOP10(i, n, x) \ + KRML_LOOP8(i, n, x) \ + KRML_LOOP2(i, n, x) + +#define KRML_LOOP11(i, n, x) \ + KRML_LOOP8(i, n, x) \ + KRML_LOOP3(i, n, x) + +#define KRML_LOOP12(i, n, x) \ + KRML_LOOP8(i, n, x) \ + KRML_LOOP4(i, n, x) + +#define KRML_LOOP13(i, n, x) \ + KRML_LOOP8(i, n, x) \ + KRML_LOOP5(i, n, x) + +#define KRML_LOOP14(i, n, x) \ + KRML_LOOP8(i, n, x) \ + KRML_LOOP6(i, n, x) + +#define KRML_LOOP15(i, n, x) \ + KRML_LOOP8(i, n, x) \ + KRML_LOOP7(i, n, x) + +#define KRML_LOOP16(i, n, x) \ + KRML_LOOP8(i, n, x) \ + KRML_LOOP8(i, n, x) + +#define KRML_UNROLL_FOR(i, z, n, k, x) do { \ + uint32_t i = z; \ + KRML_LOOP##n(i, k, x) \ +} while (0) + +#define KRML_ACTUAL_FOR(i, z, n, k, x) \ + do { \ + for (uint32_t i = z; i < n; i += k) { \ + x \ + } \ + } while (0) + +#ifndef KRML_UNROLL_MAX +#define KRML_UNROLL_MAX 16 +#endif + +/* 1 is the number of loop iterations, i.e. (n - z)/k as evaluated by krml */ +#if 0 <= KRML_UNROLL_MAX +#define KRML_MAYBE_FOR0(i, z, n, k, x) +#else +#define KRML_MAYBE_FOR0(i, z, n, k, x) KRML_ACTUAL_FOR(i, z, n, k, x) +#endif + +#if 1 <= KRML_UNROLL_MAX +#define KRML_MAYBE_FOR1(i, z, n, k, x) KRML_UNROLL_FOR(i, z, 1, k, x) +#else +#define KRML_MAYBE_FOR1(i, z, n, k, x) KRML_ACTUAL_FOR(i, z, n, k, x) +#endif + +#if 2 <= KRML_UNROLL_MAX +#define KRML_MAYBE_FOR2(i, z, n, k, x) KRML_UNROLL_FOR(i, z, 2, k, x) +#else +#define KRML_MAYBE_FOR2(i, z, n, k, x) KRML_ACTUAL_FOR(i, z, n, k, x) +#endif + +#if 3 <= KRML_UNROLL_MAX +#define KRML_MAYBE_FOR3(i, z, n, k, x) KRML_UNROLL_FOR(i, z, 3, k, x) +#else +#define KRML_MAYBE_FOR3(i, z, n, k, x) KRML_ACTUAL_FOR(i, z, n, k, x) +#endif + +#if 4 <= KRML_UNROLL_MAX +#define KRML_MAYBE_FOR4(i, z, n, k, x) KRML_UNROLL_FOR(i, z, 4, k, x) +#else +#define KRML_MAYBE_FOR4(i, z, n, k, x) KRML_ACTUAL_FOR(i, z, n, k, x) +#endif + +#if 5 <= KRML_UNROLL_MAX +#define KRML_MAYBE_FOR5(i, z, n, k, x) KRML_UNROLL_FOR(i, z, 5, k, x) +#else +#define KRML_MAYBE_FOR5(i, z, n, k, x) KRML_ACTUAL_FOR(i, z, n, k, x) +#endif + +#if 6 <= KRML_UNROLL_MAX +#define KRML_MAYBE_FOR6(i, z, n, k, x) KRML_UNROLL_FOR(i, z, 6, k, x) +#else +#define KRML_MAYBE_FOR6(i, z, n, k, x) KRML_ACTUAL_FOR(i, z, n, k, x) +#endif + +#if 7 <= KRML_UNROLL_MAX +#define KRML_MAYBE_FOR7(i, z, n, k, x) KRML_UNROLL_FOR(i, z, 7, k, x) +#else +#define KRML_MAYBE_FOR7(i, z, n, k, x) KRML_ACTUAL_FOR(i, z, n, k, x) +#endif + +#if 8 <= KRML_UNROLL_MAX +#define KRML_MAYBE_FOR8(i, z, n, k, x) KRML_UNROLL_FOR(i, z, 8, k, x) +#else +#define KRML_MAYBE_FOR8(i, z, n, k, x) KRML_ACTUAL_FOR(i, z, n, k, x) +#endif + +#if 9 <= KRML_UNROLL_MAX +#define KRML_MAYBE_FOR9(i, z, n, k, x) KRML_UNROLL_FOR(i, z, 9, k, x) +#else +#define KRML_MAYBE_FOR9(i, z, n, k, x) KRML_ACTUAL_FOR(i, z, n, k, x) +#endif + +#if 10 <= KRML_UNROLL_MAX +#define KRML_MAYBE_FOR10(i, z, n, k, x) KRML_UNROLL_FOR(i, z, 10, k, x) +#else +#define KRML_MAYBE_FOR10(i, z, n, k, x) KRML_ACTUAL_FOR(i, z, n, k, x) +#endif + +#if 11 <= KRML_UNROLL_MAX +#define KRML_MAYBE_FOR11(i, z, n, k, x) KRML_UNROLL_FOR(i, z, 11, k, x) +#else +#define KRML_MAYBE_FOR11(i, z, n, k, x) KRML_ACTUAL_FOR(i, z, n, k, x) +#endif + +#if 12 <= KRML_UNROLL_MAX +#define KRML_MAYBE_FOR12(i, z, n, k, x) KRML_UNROLL_FOR(i, z, 12, k, x) +#else +#define KRML_MAYBE_FOR12(i, z, n, k, x) KRML_ACTUAL_FOR(i, z, n, k, x) +#endif + +#if 13 <= KRML_UNROLL_MAX +#define KRML_MAYBE_FOR13(i, z, n, k, x) KRML_UNROLL_FOR(i, z, 13, k, x) +#else +#define KRML_MAYBE_FOR13(i, z, n, k, x) KRML_ACTUAL_FOR(i, z, n, k, x) +#endif + +#if 14 <= KRML_UNROLL_MAX +#define KRML_MAYBE_FOR14(i, z, n, k, x) KRML_UNROLL_FOR(i, z, 14, k, x) +#else +#define KRML_MAYBE_FOR14(i, z, n, k, x) KRML_ACTUAL_FOR(i, z, n, k, x) +#endif + +#if 15 <= KRML_UNROLL_MAX +#define KRML_MAYBE_FOR15(i, z, n, k, x) KRML_UNROLL_FOR(i, z, 15, k, x) +#else +#define KRML_MAYBE_FOR15(i, z, n, k, x) KRML_ACTUAL_FOR(i, z, n, k, x) +#endif + +#if 16 <= KRML_UNROLL_MAX +#define KRML_MAYBE_FOR16(i, z, n, k, x) KRML_UNROLL_FOR(i, z, 16, k, x) +#else +#define KRML_MAYBE_FOR16(i, z, n, k, x) KRML_ACTUAL_FOR(i, z, n, k, x) +#endif +#endif diff --git a/Modules/_hacl/include/krml/lowstar_endianness.h b/Modules/_hacl/include/krml/lowstar_endianness.h new file mode 100644 index 00000000..1aa2ccd6 --- /dev/null +++ b/Modules/_hacl/include/krml/lowstar_endianness.h @@ -0,0 +1,231 @@ +/* Copyright (c) INRIA and Microsoft Corporation. All rights reserved. + Licensed under the Apache 2.0 License. */ + +#ifndef __LOWSTAR_ENDIANNESS_H +#define __LOWSTAR_ENDIANNESS_H + +#include <string.h> +#include <inttypes.h> + +/******************************************************************************/ +/* Implementing C.fst (part 2: endian-ness macros) */ +/******************************************************************************/ + +/* ... for Linux */ +#if defined(__linux__) || defined(__CYGWIN__) || defined (__USE_SYSTEM_ENDIAN_H__) || defined(__GLIBC__) +# include <endian.h> + +/* ... for OSX */ +#elif defined(__APPLE__) +# include <libkern/OSByteOrder.h> +# define htole64(x) OSSwapHostToLittleInt64(x) +# define le64toh(x) OSSwapLittleToHostInt64(x) +# define htobe64(x) OSSwapHostToBigInt64(x) +# define be64toh(x) OSSwapBigToHostInt64(x) + +# define htole16(x) OSSwapHostToLittleInt16(x) +# define le16toh(x) OSSwapLittleToHostInt16(x) +# define htobe16(x) OSSwapHostToBigInt16(x) +# define be16toh(x) OSSwapBigToHostInt16(x) + +# define htole32(x) OSSwapHostToLittleInt32(x) +# define le32toh(x) OSSwapLittleToHostInt32(x) +# define htobe32(x) OSSwapHostToBigInt32(x) +# define be32toh(x) OSSwapBigToHostInt32(x) + +/* ... for Solaris */ +#elif defined(__sun__) +# include <sys/byteorder.h> +# define htole64(x) LE_64(x) +# define le64toh(x) LE_64(x) +# define htobe64(x) BE_64(x) +# define be64toh(x) BE_64(x) + +# define htole16(x) LE_16(x) +# define le16toh(x) LE_16(x) +# define htobe16(x) BE_16(x) +# define be16toh(x) BE_16(x) + +# define htole32(x) LE_32(x) +# define le32toh(x) LE_32(x) +# define htobe32(x) BE_32(x) +# define be32toh(x) BE_32(x) + +/* ... for the BSDs */ +#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) +# include <sys/endian.h> +#elif defined(__OpenBSD__) +# include <endian.h> + +/* ... for Windows (MSVC)... not targeting XBOX 360! */ +#elif defined(_MSC_VER) + +# include <stdlib.h> +# define htobe16(x) _byteswap_ushort(x) +# define htole16(x) (x) +# define be16toh(x) _byteswap_ushort(x) +# define le16toh(x) (x) + +# define htobe32(x) _byteswap_ulong(x) +# define htole32(x) (x) +# define be32toh(x) _byteswap_ulong(x) +# define le32toh(x) (x) + +# define htobe64(x) _byteswap_uint64(x) +# define htole64(x) (x) +# define be64toh(x) _byteswap_uint64(x) +# define le64toh(x) (x) + +/* ... for Windows (GCC-like, e.g. mingw or clang) */ +#elif (defined(_WIN32) || defined(_WIN64) || defined(__EMSCRIPTEN__)) && \ + (defined(__GNUC__) || defined(__clang__)) + +# define htobe16(x) __builtin_bswap16(x) +# define htole16(x) (x) +# define be16toh(x) __builtin_bswap16(x) +# define le16toh(x) (x) + +# define htobe32(x) __builtin_bswap32(x) +# define htole32(x) (x) +# define be32toh(x) __builtin_bswap32(x) +# define le32toh(x) (x) + +# define htobe64(x) __builtin_bswap64(x) +# define htole64(x) (x) +# define be64toh(x) __builtin_bswap64(x) +# define le64toh(x) (x) + +/* ... generic big-endian fallback code */ +/* ... AIX doesn't have __BYTE_ORDER__ (with XLC compiler) & is always big-endian */ +#elif (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) || defined(_AIX) + +/* byte swapping code inspired by: + * https://github.com/rweather/arduinolibs/blob/master/libraries/Crypto/utility/EndianUtil.h + * */ + +# define htobe32(x) (x) +# define be32toh(x) (x) +# define htole32(x) \ + (__extension__({ \ + uint32_t _temp = (x); \ + ((_temp >> 24) & 0x000000FF) | ((_temp >> 8) & 0x0000FF00) | \ + ((_temp << 8) & 0x00FF0000) | ((_temp << 24) & 0xFF000000); \ + })) +# define le32toh(x) (htole32((x))) + +# define htobe64(x) (x) +# define be64toh(x) (x) +# define htole64(x) \ + (__extension__({ \ + uint64_t __temp = (x); \ + uint32_t __low = htobe32((uint32_t)__temp); \ + uint32_t __high = htobe32((uint32_t)(__temp >> 32)); \ + (((uint64_t)__low) << 32) | __high; \ + })) +# define le64toh(x) (htole64((x))) + +/* ... generic little-endian fallback code */ +#elif defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + +# define htole32(x) (x) +# define le32toh(x) (x) +# define htobe32(x) \ + (__extension__({ \ + uint32_t _temp = (x); \ + ((_temp >> 24) & 0x000000FF) | ((_temp >> 8) & 0x0000FF00) | \ + ((_temp << 8) & 0x00FF0000) | ((_temp << 24) & 0xFF000000); \ + })) +# define be32toh(x) (htobe32((x))) + +# define htole64(x) (x) +# define le64toh(x) (x) +# define htobe64(x) \ + (__extension__({ \ + uint64_t __temp = (x); \ + uint32_t __low = htobe32((uint32_t)__temp); \ + uint32_t __high = htobe32((uint32_t)(__temp >> 32)); \ + (((uint64_t)__low) << 32) | __high; \ + })) +# define be64toh(x) (htobe64((x))) + +/* ... couldn't determine endian-ness of the target platform */ +#else +# error "Please define __BYTE_ORDER__!" + +#endif /* defined(__linux__) || ... */ + +/* Loads and stores. These avoid undefined behavior due to unaligned memory + * accesses, via memcpy. */ + +inline static uint16_t load16(uint8_t *b) { + uint16_t x; + memcpy(&x, b, 2); + return x; +} + +inline static uint32_t load32(uint8_t *b) { + uint32_t x; + memcpy(&x, b, 4); + return x; +} + +inline static uint64_t load64(uint8_t *b) { + uint64_t x; + memcpy(&x, b, 8); + return x; +} + +inline static void store16(uint8_t *b, uint16_t i) { + memcpy(b, &i, 2); +} + +inline static void store32(uint8_t *b, uint32_t i) { + memcpy(b, &i, 4); +} + +inline static void store64(uint8_t *b, uint64_t i) { + memcpy(b, &i, 8); +} + +/* Legacy accessors so that this header can serve as an implementation of + * C.Endianness */ +#define load16_le(b) (le16toh(load16(b))) +#define store16_le(b, i) (store16(b, htole16(i))) +#define load16_be(b) (be16toh(load16(b))) +#define store16_be(b, i) (store16(b, htobe16(i))) + +#define load32_le(b) (le32toh(load32(b))) +#define store32_le(b, i) (store32(b, htole32(i))) +#define load32_be(b) (be32toh(load32(b))) +#define store32_be(b, i) (store32(b, htobe32(i))) + +#define load64_le(b) (le64toh(load64(b))) +#define store64_le(b, i) (store64(b, htole64(i))) +#define load64_be(b) (be64toh(load64(b))) +#define store64_be(b, i) (store64(b, htobe64(i))) + +/* Co-existence of LowStar.Endianness and FStar.Endianness generates name + * conflicts, because of course both insist on having no prefixes. Until a + * prefix is added, or until we truly retire FStar.Endianness, solve this issue + * in an elegant way. */ +#define load16_le0 load16_le +#define store16_le0 store16_le +#define load16_be0 load16_be +#define store16_be0 store16_be + +#define load32_le0 load32_le +#define store32_le0 store32_le +#define load32_be0 load32_be +#define store32_be0 store32_be + +#define load64_le0 load64_le +#define store64_le0 store64_le +#define load64_be0 load64_be +#define store64_be0 store64_be + +#define load128_le0 load128_le +#define store128_le0 store128_le +#define load128_be0 load128_be +#define store128_be0 store128_be + +#endif diff --git a/Modules/_hacl/include/krml/types.h b/Modules/_hacl/include/krml/types.h new file mode 100644 index 00000000..509f5555 --- /dev/null +++ b/Modules/_hacl/include/krml/types.h @@ -0,0 +1,14 @@ +#pragma once + +#include <inttypes.h> + +typedef struct FStar_UInt128_uint128_s { + uint64_t low; + uint64_t high; +} FStar_UInt128_uint128, uint128_t; + +#define KRML_VERIFIED_UINT128 + +#include "krml/lowstar_endianness.h" +#include "krml/fstar_uint128_struct_endianness.h" +#include "krml/FStar_UInt128_Verified.h" diff --git a/Modules/_hacl/internal/Hacl_Hash_MD5.h b/Modules/_hacl/internal/Hacl_Hash_MD5.h new file mode 100644 index 00000000..87ad4cf2 --- /dev/null +++ b/Modules/_hacl/internal/Hacl_Hash_MD5.h @@ -0,0 +1,61 @@ +/* MIT License + * + * Copyright (c) 2016-2022 INRIA, CMU and Microsoft Corporation + * Copyright (c) 2022-2023 HACL* Contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + + +#ifndef __internal_Hacl_Hash_MD5_H +#define __internal_Hacl_Hash_MD5_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include <string.h> +#include "krml/types.h" +#include "krml/lowstar_endianness.h" +#include "krml/internal/target.h" + +#include "../Hacl_Hash_MD5.h" + +void Hacl_Hash_Core_MD5_legacy_init(uint32_t *s); + +void Hacl_Hash_Core_MD5_legacy_finish(uint32_t *s, uint8_t *dst); + +void Hacl_Hash_MD5_legacy_update_multi(uint32_t *s, uint8_t *blocks, uint32_t n_blocks); + +void +Hacl_Hash_MD5_legacy_update_last( + uint32_t *s, + uint64_t prev_len, + uint8_t *input, + uint32_t input_len +); + +void Hacl_Hash_MD5_legacy_hash(uint8_t *input, uint32_t input_len, uint8_t *dst); + +#if defined(__cplusplus) +} +#endif + +#define __internal_Hacl_Hash_MD5_H_DEFINED +#endif diff --git a/Modules/_hacl/internal/Hacl_Hash_SHA1.h b/Modules/_hacl/internal/Hacl_Hash_SHA1.h new file mode 100644 index 00000000..d2d9df44 --- /dev/null +++ b/Modules/_hacl/internal/Hacl_Hash_SHA1.h @@ -0,0 +1,61 @@ +/* MIT License + * + * Copyright (c) 2016-2022 INRIA, CMU and Microsoft Corporation + * Copyright (c) 2022-2023 HACL* Contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + + +#ifndef __internal_Hacl_Hash_SHA1_H +#define __internal_Hacl_Hash_SHA1_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include <string.h> +#include "krml/types.h" +#include "krml/lowstar_endianness.h" +#include "krml/internal/target.h" + +#include "../Hacl_Hash_SHA1.h" + +void Hacl_Hash_Core_SHA1_legacy_init(uint32_t *s); + +void Hacl_Hash_Core_SHA1_legacy_finish(uint32_t *s, uint8_t *dst); + +void Hacl_Hash_SHA1_legacy_update_multi(uint32_t *s, uint8_t *blocks, uint32_t n_blocks); + +void +Hacl_Hash_SHA1_legacy_update_last( + uint32_t *s, + uint64_t prev_len, + uint8_t *input, + uint32_t input_len +); + +void Hacl_Hash_SHA1_legacy_hash(uint8_t *input, uint32_t input_len, uint8_t *dst); + +#if defined(__cplusplus) +} +#endif + +#define __internal_Hacl_Hash_SHA1_H_DEFINED +#endif diff --git a/Modules/_hacl/internal/Hacl_Hash_SHA2.h b/Modules/_hacl/internal/Hacl_Hash_SHA2.h new file mode 100644 index 00000000..851f7dc6 --- /dev/null +++ b/Modules/_hacl/internal/Hacl_Hash_SHA2.h @@ -0,0 +1,184 @@ +/* MIT License + * + * Copyright (c) 2016-2022 INRIA, CMU and Microsoft Corporation + * Copyright (c) 2022-2023 HACL* Contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + + +#ifndef __internal_Hacl_Hash_SHA2_H +#define __internal_Hacl_Hash_SHA2_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include <string.h> +#include "krml/types.h" +#include "krml/lowstar_endianness.h" +#include "krml/internal/target.h" + + +#include "../Hacl_Hash_SHA2.h" + +static const +uint32_t +Hacl_Impl_SHA2_Generic_h224[8U] = + { + (uint32_t)0xc1059ed8U, (uint32_t)0x367cd507U, (uint32_t)0x3070dd17U, (uint32_t)0xf70e5939U, + (uint32_t)0xffc00b31U, (uint32_t)0x68581511U, (uint32_t)0x64f98fa7U, (uint32_t)0xbefa4fa4U + }; + +static const +uint32_t +Hacl_Impl_SHA2_Generic_h256[8U] = + { + (uint32_t)0x6a09e667U, (uint32_t)0xbb67ae85U, (uint32_t)0x3c6ef372U, (uint32_t)0xa54ff53aU, + (uint32_t)0x510e527fU, (uint32_t)0x9b05688cU, (uint32_t)0x1f83d9abU, (uint32_t)0x5be0cd19U + }; + +static const +uint64_t +Hacl_Impl_SHA2_Generic_h384[8U] = + { + (uint64_t)0xcbbb9d5dc1059ed8U, (uint64_t)0x629a292a367cd507U, (uint64_t)0x9159015a3070dd17U, + (uint64_t)0x152fecd8f70e5939U, (uint64_t)0x67332667ffc00b31U, (uint64_t)0x8eb44a8768581511U, + (uint64_t)0xdb0c2e0d64f98fa7U, (uint64_t)0x47b5481dbefa4fa4U + }; + +static const +uint64_t +Hacl_Impl_SHA2_Generic_h512[8U] = + { + (uint64_t)0x6a09e667f3bcc908U, (uint64_t)0xbb67ae8584caa73bU, (uint64_t)0x3c6ef372fe94f82bU, + (uint64_t)0xa54ff53a5f1d36f1U, (uint64_t)0x510e527fade682d1U, (uint64_t)0x9b05688c2b3e6c1fU, + (uint64_t)0x1f83d9abfb41bd6bU, (uint64_t)0x5be0cd19137e2179U + }; + +static const +uint32_t +Hacl_Impl_SHA2_Generic_k224_256[64U] = + { + (uint32_t)0x428a2f98U, (uint32_t)0x71374491U, (uint32_t)0xb5c0fbcfU, (uint32_t)0xe9b5dba5U, + (uint32_t)0x3956c25bU, (uint32_t)0x59f111f1U, (uint32_t)0x923f82a4U, (uint32_t)0xab1c5ed5U, + (uint32_t)0xd807aa98U, (uint32_t)0x12835b01U, (uint32_t)0x243185beU, (uint32_t)0x550c7dc3U, + (uint32_t)0x72be5d74U, (uint32_t)0x80deb1feU, (uint32_t)0x9bdc06a7U, (uint32_t)0xc19bf174U, + (uint32_t)0xe49b69c1U, (uint32_t)0xefbe4786U, (uint32_t)0x0fc19dc6U, (uint32_t)0x240ca1ccU, + (uint32_t)0x2de92c6fU, (uint32_t)0x4a7484aaU, (uint32_t)0x5cb0a9dcU, (uint32_t)0x76f988daU, + (uint32_t)0x983e5152U, (uint32_t)0xa831c66dU, (uint32_t)0xb00327c8U, (uint32_t)0xbf597fc7U, + (uint32_t)0xc6e00bf3U, (uint32_t)0xd5a79147U, (uint32_t)0x06ca6351U, (uint32_t)0x14292967U, + (uint32_t)0x27b70a85U, (uint32_t)0x2e1b2138U, (uint32_t)0x4d2c6dfcU, (uint32_t)0x53380d13U, + (uint32_t)0x650a7354U, (uint32_t)0x766a0abbU, (uint32_t)0x81c2c92eU, (uint32_t)0x92722c85U, + (uint32_t)0xa2bfe8a1U, (uint32_t)0xa81a664bU, (uint32_t)0xc24b8b70U, (uint32_t)0xc76c51a3U, + (uint32_t)0xd192e819U, (uint32_t)0xd6990624U, (uint32_t)0xf40e3585U, (uint32_t)0x106aa070U, + (uint32_t)0x19a4c116U, (uint32_t)0x1e376c08U, (uint32_t)0x2748774cU, (uint32_t)0x34b0bcb5U, + (uint32_t)0x391c0cb3U, (uint32_t)0x4ed8aa4aU, (uint32_t)0x5b9cca4fU, (uint32_t)0x682e6ff3U, + (uint32_t)0x748f82eeU, (uint32_t)0x78a5636fU, (uint32_t)0x84c87814U, (uint32_t)0x8cc70208U, + (uint32_t)0x90befffaU, (uint32_t)0xa4506cebU, (uint32_t)0xbef9a3f7U, (uint32_t)0xc67178f2U + }; + +static const +uint64_t +Hacl_Impl_SHA2_Generic_k384_512[80U] = + { + (uint64_t)0x428a2f98d728ae22U, (uint64_t)0x7137449123ef65cdU, (uint64_t)0xb5c0fbcfec4d3b2fU, + (uint64_t)0xe9b5dba58189dbbcU, (uint64_t)0x3956c25bf348b538U, (uint64_t)0x59f111f1b605d019U, + (uint64_t)0x923f82a4af194f9bU, (uint64_t)0xab1c5ed5da6d8118U, (uint64_t)0xd807aa98a3030242U, + (uint64_t)0x12835b0145706fbeU, (uint64_t)0x243185be4ee4b28cU, (uint64_t)0x550c7dc3d5ffb4e2U, + (uint64_t)0x72be5d74f27b896fU, (uint64_t)0x80deb1fe3b1696b1U, (uint64_t)0x9bdc06a725c71235U, + (uint64_t)0xc19bf174cf692694U, (uint64_t)0xe49b69c19ef14ad2U, (uint64_t)0xefbe4786384f25e3U, + (uint64_t)0x0fc19dc68b8cd5b5U, (uint64_t)0x240ca1cc77ac9c65U, (uint64_t)0x2de92c6f592b0275U, + (uint64_t)0x4a7484aa6ea6e483U, (uint64_t)0x5cb0a9dcbd41fbd4U, (uint64_t)0x76f988da831153b5U, + (uint64_t)0x983e5152ee66dfabU, (uint64_t)0xa831c66d2db43210U, (uint64_t)0xb00327c898fb213fU, + (uint64_t)0xbf597fc7beef0ee4U, (uint64_t)0xc6e00bf33da88fc2U, (uint64_t)0xd5a79147930aa725U, + (uint64_t)0x06ca6351e003826fU, (uint64_t)0x142929670a0e6e70U, (uint64_t)0x27b70a8546d22ffcU, + (uint64_t)0x2e1b21385c26c926U, (uint64_t)0x4d2c6dfc5ac42aedU, (uint64_t)0x53380d139d95b3dfU, + (uint64_t)0x650a73548baf63deU, (uint64_t)0x766a0abb3c77b2a8U, (uint64_t)0x81c2c92e47edaee6U, + (uint64_t)0x92722c851482353bU, (uint64_t)0xa2bfe8a14cf10364U, (uint64_t)0xa81a664bbc423001U, + (uint64_t)0xc24b8b70d0f89791U, (uint64_t)0xc76c51a30654be30U, (uint64_t)0xd192e819d6ef5218U, + (uint64_t)0xd69906245565a910U, (uint64_t)0xf40e35855771202aU, (uint64_t)0x106aa07032bbd1b8U, + (uint64_t)0x19a4c116b8d2d0c8U, (uint64_t)0x1e376c085141ab53U, (uint64_t)0x2748774cdf8eeb99U, + (uint64_t)0x34b0bcb5e19b48a8U, (uint64_t)0x391c0cb3c5c95a63U, (uint64_t)0x4ed8aa4ae3418acbU, + (uint64_t)0x5b9cca4f7763e373U, (uint64_t)0x682e6ff3d6b2b8a3U, (uint64_t)0x748f82ee5defb2fcU, + (uint64_t)0x78a5636f43172f60U, (uint64_t)0x84c87814a1f0ab72U, (uint64_t)0x8cc702081a6439ecU, + (uint64_t)0x90befffa23631e28U, (uint64_t)0xa4506cebde82bde9U, (uint64_t)0xbef9a3f7b2c67915U, + (uint64_t)0xc67178f2e372532bU, (uint64_t)0xca273eceea26619cU, (uint64_t)0xd186b8c721c0c207U, + (uint64_t)0xeada7dd6cde0eb1eU, (uint64_t)0xf57d4f7fee6ed178U, (uint64_t)0x06f067aa72176fbaU, + (uint64_t)0x0a637dc5a2c898a6U, (uint64_t)0x113f9804bef90daeU, (uint64_t)0x1b710b35131c471bU, + (uint64_t)0x28db77f523047d84U, (uint64_t)0x32caab7b40c72493U, (uint64_t)0x3c9ebe0a15c9bebcU, + (uint64_t)0x431d67c49c100d4cU, (uint64_t)0x4cc5d4becb3e42b6U, (uint64_t)0x597f299cfc657e2aU, + (uint64_t)0x5fcb6fab3ad6faecU, (uint64_t)0x6c44198c4a475817U + }; + +void Hacl_SHA2_Scalar32_sha256_init(uint32_t *hash); + +void Hacl_SHA2_Scalar32_sha256_update_nblocks(uint32_t len, uint8_t *b, uint32_t *st); + +void +Hacl_SHA2_Scalar32_sha256_update_last( + uint64_t totlen, + uint32_t len, + uint8_t *b, + uint32_t *hash +); + +void Hacl_SHA2_Scalar32_sha256_finish(uint32_t *st, uint8_t *h); + +void Hacl_SHA2_Scalar32_sha224_init(uint32_t *hash); + +void +Hacl_SHA2_Scalar32_sha224_update_last(uint64_t totlen, uint32_t len, uint8_t *b, uint32_t *st); + +void Hacl_SHA2_Scalar32_sha224_finish(uint32_t *st, uint8_t *h); + +void Hacl_SHA2_Scalar32_sha512_init(uint64_t *hash); + +void Hacl_SHA2_Scalar32_sha512_update_nblocks(uint32_t len, uint8_t *b, uint64_t *st); + +void +Hacl_SHA2_Scalar32_sha512_update_last( + FStar_UInt128_uint128 totlen, + uint32_t len, + uint8_t *b, + uint64_t *hash +); + +void Hacl_SHA2_Scalar32_sha512_finish(uint64_t *st, uint8_t *h); + +void Hacl_SHA2_Scalar32_sha384_init(uint64_t *hash); + +void Hacl_SHA2_Scalar32_sha384_update_nblocks(uint32_t len, uint8_t *b, uint64_t *st); + +void +Hacl_SHA2_Scalar32_sha384_update_last( + FStar_UInt128_uint128 totlen, + uint32_t len, + uint8_t *b, + uint64_t *st +); + +void Hacl_SHA2_Scalar32_sha384_finish(uint64_t *st, uint8_t *h); + +#if defined(__cplusplus) +} +#endif + +#define __internal_Hacl_Hash_SHA2_H_DEFINED +#endif diff --git a/Modules/_hacl/internal/Hacl_Hash_SHA3.h b/Modules/_hacl/internal/Hacl_Hash_SHA3.h new file mode 100644 index 00000000..1c9808b8 --- /dev/null +++ b/Modules/_hacl/internal/Hacl_Hash_SHA3.h @@ -0,0 +1,65 @@ +/* MIT License + * + * Copyright (c) 2016-2022 INRIA, CMU and Microsoft Corporation + * Copyright (c) 2022-2023 HACL* Contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + + +#ifndef __internal_Hacl_Hash_SHA3_H +#define __internal_Hacl_Hash_SHA3_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include <string.h> +#include "krml/types.h" +#include "krml/lowstar_endianness.h" +#include "krml/internal/target.h" + +#include "../Hacl_Hash_SHA3.h" + +void +Hacl_Hash_SHA3_update_multi_sha3( + Spec_Hash_Definitions_hash_alg a, + uint64_t *s, + uint8_t *blocks, + uint32_t n_blocks +); + +void +Hacl_Hash_SHA3_update_last_sha3( + Spec_Hash_Definitions_hash_alg a, + uint64_t *s, + uint8_t *input, + uint32_t input_len +); + +void Hacl_Impl_SHA3_state_permute(uint64_t *s); + +void Hacl_Impl_SHA3_loadState(uint32_t rateInBytes, uint8_t *input, uint64_t *s); + +#if defined(__cplusplus) +} +#endif + +#define __internal_Hacl_Hash_SHA3_H_DEFINED +#endif diff --git a/Modules/_hacl/python_hacl_namespaces.h b/Modules/_hacl/python_hacl_namespaces.h new file mode 100644 index 00000000..0df23628 --- /dev/null +++ b/Modules/_hacl/python_hacl_namespaces.h @@ -0,0 +1,86 @@ +#ifndef _PYTHON_HACL_NAMESPACES_H +#define _PYTHON_HACL_NAMESPACES_H + +/* + * C's excuse for namespaces: Use globally unique names to avoid linkage + * conflicts with builds linking or dynamically loading other code potentially + * using HACL* libraries. + */ + +#define Hacl_Streaming_SHA2_state_sha2_224_s python_hashlib_Hacl_Streaming_SHA2_state_sha2_224_s +#define Hacl_Streaming_SHA2_state_sha2_224 python_hashlib_Hacl_Streaming_SHA2_state_sha2_224 +#define Hacl_Streaming_SHA2_state_sha2_256 python_hashlib_Hacl_Streaming_SHA2_state_sha2_256 +#define Hacl_Streaming_SHA2_state_sha2_384_s python_hashlib_Hacl_Streaming_SHA2_state_sha2_384_s +#define Hacl_Streaming_SHA2_state_sha2_384 python_hashlib_Hacl_Streaming_SHA2_state_sha2_384 +#define Hacl_Streaming_SHA2_state_sha2_512 python_hashlib_Hacl_Streaming_SHA2_state_sha2_512 +#define Hacl_Streaming_SHA2_create_in_256 python_hashlib_Hacl_Streaming_SHA2_create_in_256 +#define Hacl_Streaming_SHA2_create_in_224 python_hashlib_Hacl_Streaming_SHA2_create_in_224 +#define Hacl_Streaming_SHA2_create_in_512 python_hashlib_Hacl_Streaming_SHA2_create_in_512 +#define Hacl_Streaming_SHA2_create_in_384 python_hashlib_Hacl_Streaming_SHA2_create_in_384 +#define Hacl_Streaming_SHA2_copy_256 python_hashlib_Hacl_Streaming_SHA2_copy_256 +#define Hacl_Streaming_SHA2_copy_224 python_hashlib_Hacl_Streaming_SHA2_copy_224 +#define Hacl_Streaming_SHA2_copy_512 python_hashlib_Hacl_Streaming_SHA2_copy_512 +#define Hacl_Streaming_SHA2_copy_384 python_hashlib_Hacl_Streaming_SHA2_copy_384 +#define Hacl_Streaming_SHA2_init_256 python_hashlib_Hacl_Streaming_SHA2_init_256 +#define Hacl_Streaming_SHA2_init_224 python_hashlib_Hacl_Streaming_SHA2_init_224 +#define Hacl_Streaming_SHA2_init_512 python_hashlib_Hacl_Streaming_SHA2_init_512 +#define Hacl_Streaming_SHA2_init_384 python_hashlib_Hacl_Streaming_SHA2_init_384 +#define Hacl_SHA2_Scalar32_sha512_init python_hashlib_Hacl_SHA2_Scalar32_sha512_init +#define Hacl_Streaming_SHA2_update_256 python_hashlib_Hacl_Streaming_SHA2_update_256 +#define Hacl_Streaming_SHA2_update_224 python_hashlib_Hacl_Streaming_SHA2_update_224 +#define Hacl_Streaming_SHA2_update_512 python_hashlib_Hacl_Streaming_SHA2_update_512 +#define Hacl_Streaming_SHA2_update_384 python_hashlib_Hacl_Streaming_SHA2_update_384 +#define Hacl_Streaming_SHA2_finish_256 python_hashlib_Hacl_Streaming_SHA2_finish_256 +#define Hacl_Streaming_SHA2_finish_224 python_hashlib_Hacl_Streaming_SHA2_finish_224 +#define Hacl_Streaming_SHA2_finish_512 python_hashlib_Hacl_Streaming_SHA2_finish_512 +#define Hacl_Streaming_SHA2_finish_384 python_hashlib_Hacl_Streaming_SHA2_finish_384 +#define Hacl_Streaming_SHA2_free_256 python_hashlib_Hacl_Streaming_SHA2_free_256 +#define Hacl_Streaming_SHA2_free_224 python_hashlib_Hacl_Streaming_SHA2_free_224 +#define Hacl_Streaming_SHA2_free_512 python_hashlib_Hacl_Streaming_SHA2_free_512 +#define Hacl_Streaming_SHA2_free_384 python_hashlib_Hacl_Streaming_SHA2_free_384 +#define Hacl_Streaming_SHA2_sha256 python_hashlib_Hacl_Streaming_SHA2_sha256 +#define Hacl_Streaming_SHA2_sha224 python_hashlib_Hacl_Streaming_SHA2_sha224 +#define Hacl_Streaming_SHA2_sha512 python_hashlib_Hacl_Streaming_SHA2_sha512 +#define Hacl_Streaming_SHA2_sha384 python_hashlib_Hacl_Streaming_SHA2_sha384 + +#define Hacl_Streaming_MD5_legacy_create_in python_hashlib_Hacl_Streaming_MD5_legacy_create_in +#define Hacl_Streaming_MD5_legacy_init python_hashlib_Hacl_Streaming_MD5_legacy_init +#define Hacl_Streaming_MD5_legacy_update python_hashlib_Hacl_Streaming_MD5_legacy_update +#define Hacl_Streaming_MD5_legacy_finish python_hashlib_Hacl_Streaming_MD5_legacy_finish +#define Hacl_Streaming_MD5_legacy_free python_hashlib_Hacl_Streaming_MD5_legacy_free +#define Hacl_Streaming_MD5_legacy_copy python_hashlib_Hacl_Streaming_MD5_legacy_copy +#define Hacl_Streaming_MD5_legacy_hash python_hashlib_Hacl_Streaming_MD5_legacy_hash + +#define Hacl_Streaming_SHA1_legacy_create_in python_hashlib_Hacl_Streaming_SHA1_legacy_create_in +#define Hacl_Streaming_SHA1_legacy_init python_hashlib_Hacl_Streaming_SHA1_legacy_init +#define Hacl_Streaming_SHA1_legacy_update python_hashlib_Hacl_Streaming_SHA1_legacy_update +#define Hacl_Streaming_SHA1_legacy_finish python_hashlib_Hacl_Streaming_SHA1_legacy_finish +#define Hacl_Streaming_SHA1_legacy_free python_hashlib_Hacl_Streaming_SHA1_legacy_free +#define Hacl_Streaming_SHA1_legacy_copy python_hashlib_Hacl_Streaming_SHA1_legacy_copy +#define Hacl_Streaming_SHA1_legacy_hash python_hashlib_Hacl_Streaming_SHA1_legacy_hash + +#define Hacl_Hash_SHA3_update_last_sha3 python_hashlib_Hacl_Hash_SHA3_update_last_sha3 +#define Hacl_Hash_SHA3_update_multi_sha3 python_hashlib_Hacl_Hash_SHA3_update_multi_sha3 +#define Hacl_Impl_SHA3_absorb_inner python_hashlib_Hacl_Impl_SHA3_absorb_inner +#define Hacl_Impl_SHA3_keccak python_hashlib_Hacl_Impl_SHA3_keccak +#define Hacl_Impl_SHA3_loadState python_hashlib_Hacl_Impl_SHA3_loadState +#define Hacl_Impl_SHA3_squeeze python_hashlib_Hacl_Impl_SHA3_squeeze +#define Hacl_Impl_SHA3_state_permute python_hashlib_Hacl_Impl_SHA3_state_permute +#define Hacl_SHA3_sha3_224 python_hashlib_Hacl_SHA3_sha3_224 +#define Hacl_SHA3_sha3_256 python_hashlib_Hacl_SHA3_sha3_256 +#define Hacl_SHA3_sha3_384 python_hashlib_Hacl_SHA3_sha3_384 +#define Hacl_SHA3_sha3_512 python_hashlib_Hacl_SHA3_sha3_512 +#define Hacl_SHA3_shake128_hacl python_hashlib_Hacl_SHA3_shake128_hacl +#define Hacl_SHA3_shake256_hacl python_hashlib_Hacl_SHA3_shake256_hacl +#define Hacl_Streaming_Keccak_block_len python_hashlib_Hacl_Streaming_Keccak_block_len +#define Hacl_Streaming_Keccak_copy python_hashlib_Hacl_Streaming_Keccak_copy +#define Hacl_Streaming_Keccak_finish python_hashlib_Hacl_Streaming_Keccak_finish +#define Hacl_Streaming_Keccak_free python_hashlib_Hacl_Streaming_Keccak_free +#define Hacl_Streaming_Keccak_get_alg python_hashlib_Hacl_Streaming_Keccak_get_alg +#define Hacl_Streaming_Keccak_hash_len python_hashlib_Hacl_Streaming_Keccak_hash_len +#define Hacl_Streaming_Keccak_is_shake python_hashlib_Hacl_Streaming_Keccak_is_shake +#define Hacl_Streaming_Keccak_malloc python_hashlib_Hacl_Streaming_Keccak_malloc +#define Hacl_Streaming_Keccak_reset python_hashlib_Hacl_Streaming_Keccak_reset +#define Hacl_Streaming_Keccak_update python_hashlib_Hacl_Streaming_Keccak_update + +#endif // _PYTHON_HACL_NAMESPACES_H diff --git a/Modules/_hacl/refresh.sh b/Modules/_hacl/refresh.sh new file mode 100755 index 00000000..c1b3e37f --- /dev/null +++ b/Modules/_hacl/refresh.sh @@ -0,0 +1,139 @@ +#!/usr/bin/env bash +# +# Use this script to update the HACL generated hash algorithm implementation +# code from a local checkout of the upstream hacl-star repository. +# + +set -e +set -o pipefail + +if [[ "${BASH_VERSINFO[0]}" -lt 4 ]]; then + echo "A bash version >= 4 required. Got: $BASH_VERSION" >&2 + exit 1 +fi + +if [[ $1 == "" ]]; then + echo "Usage: $0 path-to-hacl-directory" + echo "" + echo " path-to-hacl-directory should be a local git checkout of a" + echo " https://github.com/hacl-star/hacl-star/ repo." + exit 1 +fi + +# Update this when updating to a new version after verifying that the changes +# the update brings in are good. +expected_hacl_star_rev=521af282fdf6d60227335120f18ae9309a4b8e8c + +hacl_dir="$(realpath "$1")" +cd "$(dirname "$0")" +actual_rev=$(cd "$hacl_dir" && git rev-parse HEAD) + +if [[ "$actual_rev" != "$expected_hacl_star_rev" ]]; then + echo "WARNING: HACL* in '$hacl_dir' is at revision:" >&2 + echo " $actual_rev" >&2 + echo "but expected revision:" >&2 + echo " $expected_hacl_star_rev" >&2 + echo "Edit the expected rev if the changes pulled in are what you want." +fi + +# Step 1: copy files + +declare -a dist_files +dist_files=( + Hacl_Hash_SHA2.h + Hacl_Streaming_Types.h + Hacl_Hash_SHA1.h + internal/Hacl_Hash_SHA1.h + Hacl_Hash_MD5.h + Hacl_Hash_SHA3.h + internal/Hacl_Hash_MD5.h + internal/Hacl_Hash_SHA3.h + Hacl_Hash_SHA2.c + internal/Hacl_Hash_SHA2.h + Hacl_Hash_SHA1.c + Hacl_Hash_MD5.c + Hacl_Hash_SHA3.c +) + +declare -a include_files +include_files=( + include/krml/lowstar_endianness.h + include/krml/internal/target.h +) + +declare -a lib_files +lib_files=( + krmllib/dist/minimal/FStar_UInt_8_16_32_64.h + krmllib/dist/minimal/fstar_uint128_struct_endianness.h + krmllib/dist/minimal/FStar_UInt128_Verified.h +) + +# C files for the algorithms themselves: current directory +(cd "$hacl_dir/dist/gcc-compatible" && tar cf - "${dist_files[@]}") | tar xf - + +# Support header files (e.g. endianness macros): stays in include/ +(cd "$hacl_dir/dist/karamel" && tar cf - "${include_files[@]}") | tar xf - + +# Special treatment: we don't bother with an extra directory and move krmllib +# files to the same include directory +for f in "${lib_files[@]}"; do + cp "$hacl_dir/dist/karamel/$f" include/krml/ +done + +# Step 2: some in-place modifications to keep things simple and minimal + +# This is basic, but refreshes of the vendored HACL code are infrequent, so +# let's not over-engineer this. +if [[ $(uname) == "Darwin" ]]; then + # You're already running with homebrew or macports to satisfy the + # bash>=4 requirement, so requiring GNU sed is entirely reasonable. + sed=gsed +else + sed=sed +fi + +readarray -t all_files < <(find . -name '*.h' -or -name '*.c') + +# types.h originally contains a complex series of if-defs and auxiliary type +# definitions; here, we just need a proper uint128 type in scope +# is a simple wrapper that defines the uint128 type +cat > include/krml/types.h <<EOF +#pragma once + +#include <inttypes.h> + +typedef struct FStar_UInt128_uint128_s { + uint64_t low; + uint64_t high; +} FStar_UInt128_uint128, uint128_t; + +#define KRML_VERIFIED_UINT128 + +#include "krml/lowstar_endianness.h" +#include "krml/fstar_uint128_struct_endianness.h" +#include "krml/FStar_UInt128_Verified.h" +EOF +# Adjust the include path to reflect the local directory structure +$sed -i 's!#include.*types.h"!#include "krml/types.h"!g' "${all_files[@]}" +$sed -i 's!#include.*compat.h"!!g' "${all_files[@]}" + +# FStar_UInt_8_16_32_64 contains definitions useful in the general case, but not +# for us; trim! +$sed -i -z 's!\(extern\|typedef\)[^;]*;\n\n!!g' include/krml/FStar_UInt_8_16_32_64.h + +# This contains static inline prototypes that are defined in +# FStar_UInt_8_16_32_64; they are by default repeated for safety of separate +# compilation, but this is not necessary. +$sed -i 's!#include.*Hacl_Krmllib.h"!!g' "${all_files[@]}" + +# Use globally unique names for the Hacl_ C APIs to avoid linkage conflicts. +$sed -i -z 's!#include <string.h>\n!#include <string.h>\n#include "python_hacl_namespaces.h"\n!' Hacl_Hash_SHA2.h + +# Finally, we remove a bunch of ifdefs from target.h that are, again, useful in +# the general case, but not exercised by the subset of HACL* that we vendor. +$sed -z -i 's!#ifndef KRML_\(PRE_ALIGN\|POST_ALIGN\|ALIGNED_MALLOC\|ALIGNED_FREE\|HOST_TIME\)\n\(\n\|# [^\n]*\n\|[^#][^\n]*\n\)*#endif\n\n!!g' include/krml/internal/target.h +$sed -z -i 's!\n\n\([^#][^\n]*\n\)*#define KRML_\(EABORT\|EXIT\)[^\n]*\(\n [^\n]*\)*!!g' include/krml/internal/target.h +$sed -z -i 's!\n\n\([^#][^\n]*\n\)*#if [^\n]*\n\( [^\n]*\n\)*#define KRML_\(EABORT\|EXIT\|CHECK_SIZE\)[^\n]*\(\n [^\n]*\)*!!g' include/krml/internal/target.h +$sed -z -i 's!\n\n\([^#][^\n]*\n\)*#if [^\n]*\n\( [^\n]*\n\)*# define _\?KRML_\(DEPRECATED\|HOST_SNPRINTF\)[^\n]*\n\([^#][^\n]*\n\|#el[^\n]*\n\|# [^\n]*\n\)*#endif!!g' include/krml/internal/target.h + +echo "Updated; verify all is okay using git diff and git status." diff --git a/Modules/_hashopenssl.c b/Modules/_hashopenssl.c index 3c40f09f..af6d1b23 100644 --- a/Modules/_hashopenssl.c +++ b/Modules/_hashopenssl.c @@ -32,12 +32,11 @@ /* EVP is the preferred interface to hashing in OpenSSL */ #include <openssl/evp.h> #include <openssl/hmac.h> -#include <openssl/crypto.h> +#include <openssl/crypto.h> // FIPS_mode() /* We use the object interface to discover what hashes OpenSSL supports. */ #include <openssl/objects.h> #include <openssl/err.h> -#include <openssl/crypto.h> // FIPS_mode() #ifndef OPENSSL_THREADS # error "OPENSSL_THREADS is not defined, Python requires thread-safe OpenSSL" @@ -228,12 +227,16 @@ get_hashlib_state(PyObject *module) typedef struct { PyObject_HEAD EVP_MD_CTX *ctx; /* OpenSSL message digest context */ + // Prevents undefined behavior via multiple threads entering the C API. + // The lock will be NULL before threaded access has been enabled. PyThread_type_lock lock; /* OpenSSL context lock */ } EVPobject; typedef struct { PyObject_HEAD HMAC_CTX *ctx; /* OpenSSL hmac context */ + // Prevents undefined behavior via multiple threads entering the C API. + // The lock will be NULL before threaded access has been enabled. PyThread_type_lock lock; /* HMAC context lock */ } HMACobject; @@ -255,11 +258,7 @@ _setException(PyObject *exc, const char* altmsg, ...) const char *lib, *func, *reason; va_list vargs; -#ifdef HAVE_STDARG_PROTOTYPES va_start(vargs, altmsg); -#else - va_start(vargs); -#endif if (!errcode) { if (altmsg == NULL) { PyErr_SetString(exc, "no reason supplied"); @@ -360,7 +359,7 @@ py_digest_by_name(PyObject *module, const char *name, enum Py_hash_type py_ht) } } if (digest == NULL) { - _setException(PyExc_ValueError, "unsupported hash type %s", name); + _setException(state->unsupported_digestmod_error, "unsupported hash type %s", name); return NULL; } return digest; @@ -384,14 +383,15 @@ py_digest_by_digestmod(PyObject *module, PyObject *digestmod, enum Py_hash_type } else { _hashlibstate *state = get_hashlib_state(module); // borrowed ref - name_obj = PyDict_GetItem(state->constructs, digestmod); + name_obj = PyDict_GetItemWithError(state->constructs, digestmod); } if (name_obj == NULL) { - _hashlibstate *state = get_hashlib_state(module); - PyErr_Clear(); - PyErr_Format( - state->unsupported_digestmod_error, - "Unsupported digestmod %R", digestmod); + if (!PyErr_Occurred()) { + _hashlibstate *state = get_hashlib_state(module); + PyErr_Format( + state->unsupported_digestmod_error, + "Unsupported digestmod %R", digestmod); + } return NULL; } @@ -901,6 +901,8 @@ py_evp_fromname(PyObject *module, const char *digestname, PyObject *data_obj, if (view.buf && view.len) { if (view.len >= HASHLIB_GIL_MINSIZE) { + /* We do not initialize self->lock here as this is the constructor + * where it is not yet possible to have concurrent access. */ Py_BEGIN_ALLOW_THREADS result = EVP_hash(self, view.buf, view.len); Py_END_ALLOW_THREADS @@ -2265,6 +2267,7 @@ static PyModuleDef_Slot hashlib_slots[] = { {Py_mod_exec, hashlib_md_meth_names}, {Py_mod_exec, hashlib_init_constructors}, {Py_mod_exec, hashlib_exception}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; diff --git a/Modules/_heapqmodule.c b/Modules/_heapqmodule.c index 3dbaaa0a..00285ae0 100644 --- a/Modules/_heapqmodule.c +++ b/Modules/_heapqmodule.c @@ -197,8 +197,7 @@ heapreplace_internal(PyObject *heap, PyObject *item, int siftup_func(PyListObjec } returnitem = PyList_GET_ITEM(heap, 0); - Py_INCREF(item); - PyList_SET_ITEM(heap, 0, item); + PyList_SET_ITEM(heap, 0, Py_NewRef(item)); if (siftup_func((PyListObject *)heap, 0)) { Py_DECREF(returnitem); return NULL; @@ -253,8 +252,7 @@ _heapq_heappushpop_impl(PyObject *module, PyObject *heap, PyObject *item) int cmp; if (PyList_GET_SIZE(heap) == 0) { - Py_INCREF(item); - return item; + return Py_NewRef(item); } PyObject* top = PyList_GET_ITEM(heap, 0); @@ -264,8 +262,7 @@ _heapq_heappushpop_impl(PyObject *module, PyObject *heap, PyObject *item) if (cmp < 0) return NULL; if (cmp == 0) { - Py_INCREF(item); - return item; + return Py_NewRef(item); } if (PyList_GET_SIZE(heap) == 0) { @@ -274,8 +271,7 @@ _heapq_heappushpop_impl(PyObject *module, PyObject *heap, PyObject *item) } returnitem = PyList_GET_ITEM(heap, 0); - Py_INCREF(item); - PyList_SET_ITEM(heap, 0, item); + PyList_SET_ITEM(heap, 0, Py_NewRef(item)); if (siftup((PyListObject *)heap, 0)) { Py_DECREF(returnitem); return NULL; @@ -410,8 +406,7 @@ siftdown_max(PyListObject *heap, Py_ssize_t startpos, Py_ssize_t pos) newitem = arr[pos]; while (pos > startpos) { parentpos = (pos - 1) >> 1; - parent = arr[parentpos]; - Py_INCREF(parent); + parent = Py_NewRef(arr[parentpos]); Py_INCREF(newitem); cmp = PyObject_RichCompareBool(parent, newitem, Py_LT); Py_DECREF(parent); @@ -687,6 +682,7 @@ heapq_exec(PyObject *m) static struct PyModuleDef_Slot heapq_slots[] = { {Py_mod_exec, heapq_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; diff --git a/Modules/_io/_iomodule.c b/Modules/_io/_iomodule.c index a7b2e984..7b06c1be 100644 --- a/Modules/_io/_iomodule.c +++ b/Modules/_io/_iomodule.c @@ -11,6 +11,7 @@ #include "Python.h" #include "_iomodule.h" #include "pycore_pystate.h" // _PyInterpreterState_GET() +#include "pycore_initconfig.h" // _PyStatus_OK() #ifdef HAVE_SYS_TYPES_H #include <sys/types.h> @@ -59,7 +60,7 @@ PyDoc_STRVAR(module_doc, " I/O classes. open() uses the file's blksize (as obtained by os.stat) if\n" " possible.\n" ); - + /* * The main open() function @@ -74,7 +75,7 @@ _io.open encoding: str(accept={str, NoneType}) = None errors: str(accept={str, NoneType}) = None newline: str(accept={str, NoneType}) = None - closefd: bool(accept={int}) = True + closefd: bool = True opener: object = None Open file and return a stream. Raise OSError upon failure. @@ -196,7 +197,7 @@ static PyObject * _io_open_impl(PyObject *module, PyObject *file, const char *mode, int buffering, const char *encoding, const char *errors, const char *newline, int closefd, PyObject *opener) -/*[clinic end generated code: output=aefafc4ce2b46dc0 input=5bb37f174cb2fb11]*/ +/*[clinic end generated code: output=aefafc4ce2b46dc0 input=cd034e7cdfbf4e78]*/ { unsigned i; @@ -204,16 +205,14 @@ _io_open_impl(PyObject *module, PyObject *file, const char *mode, int text = 0, binary = 0; char rawmode[6], *m; - int line_buffering, is_number; - long isatty = 0; + int line_buffering, is_number, isatty = 0; PyObject *raw, *modeobj = NULL, *buffer, *wrapper, *result = NULL, *path_or_fd = NULL; is_number = PyNumber_Check(file); if (is_number) { - path_or_fd = file; - Py_INCREF(path_or_fd); + path_or_fd = Py_NewRef(file); } else { path_or_fd = PyOS_FSPath(file); if (path_or_fd == NULL) { @@ -316,12 +315,13 @@ _io_open_impl(PyObject *module, PyObject *file, const char *mode, } /* Create the Raw file stream */ + _PyIO_State *state = get_io_state(module); { - PyObject *RawIO_class = (PyObject *)&PyFileIO_Type; -#ifdef MS_WINDOWS + PyObject *RawIO_class = (PyObject *)state->PyFileIO_Type; +#ifdef HAVE_WINDOWS_CONSOLE_IO const PyConfig *config = _Py_GetConfig(); if (!config->legacy_windows_stdio && _PyIO_get_console_type(path_or_fd) != '\0') { - RawIO_class = (PyObject *)&PyWindowsConsoleIO_Type; + RawIO_class = (PyObject *)state->PyWindowsConsoleIO_Type; encoding = "utf-8"; } #endif @@ -335,8 +335,7 @@ _io_open_impl(PyObject *module, PyObject *file, const char *mode, goto error; result = raw; - Py_DECREF(path_or_fd); - path_or_fd = NULL; + Py_SETREF(path_or_fd, NULL); modeobj = PyUnicode_FromString(mode); if (modeobj == NULL) @@ -347,9 +346,9 @@ _io_open_impl(PyObject *module, PyObject *file, const char *mode, PyObject *res = PyObject_CallMethodNoArgs(raw, &_Py_ID(isatty)); if (res == NULL) goto error; - isatty = PyLong_AsLong(res); + isatty = PyObject_IsTrue(res); Py_DECREF(res); - if (isatty == -1 && PyErr_Occurred()) + if (isatty < 0) goto error; } @@ -392,12 +391,15 @@ _io_open_impl(PyObject *module, PyObject *file, const char *mode, { PyObject *Buffered_class; - if (updating) - Buffered_class = (PyObject *)&PyBufferedRandom_Type; - else if (creating || writing || appending) - Buffered_class = (PyObject *)&PyBufferedWriter_Type; - else if (reading) - Buffered_class = (PyObject *)&PyBufferedReader_Type; + if (updating) { + Buffered_class = (PyObject *)state->PyBufferedRandom_Type; + } + else if (creating || writing || appending) { + Buffered_class = (PyObject *)state->PyBufferedWriter_Type; + } + else if (reading) { + Buffered_class = (PyObject *)state->PyBufferedReader_Type; + } else { PyErr_Format(PyExc_ValueError, "unknown mode: '%s'", mode); @@ -419,7 +421,7 @@ _io_open_impl(PyObject *module, PyObject *file, const char *mode, } /* wraps into a TextIOWrapper */ - wrapper = PyObject_CallFunction((PyObject *)&PyTextIOWrapper_Type, + wrapper = PyObject_CallFunction((PyObject *)state->PyTextIOWrapper_Type, "OsssO", buffer, encoding, errors, newline, @@ -436,10 +438,9 @@ _io_open_impl(PyObject *module, PyObject *file, const char *mode, error: if (result != NULL) { - PyObject *exc, *val, *tb, *close_result; - PyErr_Fetch(&exc, &val, &tb); - close_result = PyObject_CallMethodNoArgs(result, &_Py_ID(close)); - _PyErr_ChainExceptions(exc, val, tb); + PyObject *exc = PyErr_GetRaisedException(); + PyObject *close_result = PyObject_CallMethodNoArgs(result, &_Py_ID(close)); + _PyErr_ChainExceptions1(exc); Py_XDECREF(close_result); Py_DECREF(result); } @@ -489,8 +490,7 @@ _io_text_encoding_impl(PyObject *module, PyObject *encoding, int stacklevel) encoding = &_Py_ID(locale); } } - Py_INCREF(encoding); - return encoding; + return Py_NewRef(encoding); } @@ -512,7 +512,7 @@ _io_open_code_impl(PyObject *module, PyObject *path) { return PyFile_OpenCodeObject(path); } - + /* * Private helpers for the io module. */ @@ -561,35 +561,28 @@ PyNumber_AsOff_t(PyObject *item, PyObject *err) return result; } -static inline _PyIO_State* -get_io_state(PyObject *module) -{ - void *state = PyModule_GetState(module); - assert(state != NULL); - return (_PyIO_State *)state; -} - -_PyIO_State * -_PyIO_get_module_state(void) -{ - PyObject *mod = PyState_FindModule(&_PyIO_Module); - _PyIO_State *state; - if (mod == NULL || (state = get_io_state(mod)) == NULL) { - PyErr_SetString(PyExc_RuntimeError, - "could not find io module state " - "(interpreter shutdown?)"); - return NULL; - } - return state; -} - static int iomodule_traverse(PyObject *mod, visitproc visit, void *arg) { _PyIO_State *state = get_io_state(mod); - if (!state->initialized) - return 0; - Py_VISIT(state->locale_module); Py_VISIT(state->unsupported_operation); + + Py_VISIT(state->PyIOBase_Type); + Py_VISIT(state->PyIncrementalNewlineDecoder_Type); + Py_VISIT(state->PyRawIOBase_Type); + Py_VISIT(state->PyBufferedIOBase_Type); + Py_VISIT(state->PyBufferedRWPair_Type); + Py_VISIT(state->PyBufferedRandom_Type); + Py_VISIT(state->PyBufferedReader_Type); + Py_VISIT(state->PyBufferedWriter_Type); + Py_VISIT(state->PyBytesIOBuffer_Type); + Py_VISIT(state->PyBytesIO_Type); + Py_VISIT(state->PyFileIO_Type); + Py_VISIT(state->PyStringIO_Type); + Py_VISIT(state->PyTextIOBase_Type); + Py_VISIT(state->PyTextIOWrapper_Type); +#ifdef HAVE_WINDOWS_CONSOLE_IO + Py_VISIT(state->PyWindowsConsoleIO_Type); +#endif return 0; } @@ -597,17 +590,32 @@ iomodule_traverse(PyObject *mod, visitproc visit, void *arg) { static int iomodule_clear(PyObject *mod) { _PyIO_State *state = get_io_state(mod); - if (!state->initialized) - return 0; - if (state->locale_module != NULL) - Py_CLEAR(state->locale_module); Py_CLEAR(state->unsupported_operation); + + Py_CLEAR(state->PyIOBase_Type); + Py_CLEAR(state->PyIncrementalNewlineDecoder_Type); + Py_CLEAR(state->PyRawIOBase_Type); + Py_CLEAR(state->PyBufferedIOBase_Type); + Py_CLEAR(state->PyBufferedRWPair_Type); + Py_CLEAR(state->PyBufferedRandom_Type); + Py_CLEAR(state->PyBufferedReader_Type); + Py_CLEAR(state->PyBufferedWriter_Type); + Py_CLEAR(state->PyBytesIOBuffer_Type); + Py_CLEAR(state->PyBytesIO_Type); + Py_CLEAR(state->PyFileIO_Type); + Py_CLEAR(state->PyStringIO_Type); + Py_CLEAR(state->PyTextIOBase_Type); + Py_CLEAR(state->PyTextIOWrapper_Type); +#ifdef HAVE_WINDOWS_CONSOLE_IO + Py_CLEAR(state->PyWindowsConsoleIO_Type); +#endif return 0; } static void -iomodule_free(PyObject *mod) { - iomodule_clear(mod); +iomodule_free(void *mod) +{ + (void)iomodule_clear((PyObject *)mod); } @@ -615,7 +623,9 @@ iomodule_free(PyObject *mod) { * Module definition */ +#define clinic_state() (get_io_state(module)) #include "clinic/_iomodule.c.h" +#undef clinic_state static PyMethodDef module_methods[] = { _IO_OPEN_METHODDEF @@ -624,125 +634,106 @@ static PyMethodDef module_methods[] = { {NULL, NULL} }; -struct PyModuleDef _PyIO_Module = { - PyModuleDef_HEAD_INIT, - "io", - module_doc, - sizeof(_PyIO_State), - module_methods, - NULL, - iomodule_traverse, - iomodule_clear, - (freefunc)iomodule_free, -}; - - -static PyTypeObject* static_types[] = { - // Base classes - &PyIOBase_Type, - &PyIncrementalNewlineDecoder_Type, - - // PyIOBase_Type subclasses - &PyBufferedIOBase_Type, - &PyRawIOBase_Type, - &PyTextIOBase_Type, - - // PyBufferedIOBase_Type(PyIOBase_Type) subclasses - &PyBytesIO_Type, - &PyBufferedReader_Type, - &PyBufferedWriter_Type, - &PyBufferedRWPair_Type, - &PyBufferedRandom_Type, - - // PyRawIOBase_Type(PyIOBase_Type) subclasses - &PyFileIO_Type, - &_PyBytesIOBuffer_Type, -#ifdef MS_WINDOWS - &PyWindowsConsoleIO_Type, -#endif - - // PyTextIOBase_Type(PyIOBase_Type) subclasses - &PyStringIO_Type, - &PyTextIOWrapper_Type, -}; - - -void -_PyIO_Fini(void) -{ - for (Py_ssize_t i=Py_ARRAY_LENGTH(static_types) - 1; i >= 0; i--) { - PyTypeObject *exc = static_types[i]; - _PyStaticType_Dealloc(exc); - } -} - +#define ADD_TYPE(module, type, spec, base) \ +do { \ + type = (PyTypeObject *)PyType_FromModuleAndSpec(module, spec, \ + (PyObject *)base); \ + if (type == NULL) { \ + return -1; \ + } \ + if (PyModule_AddType(module, type) < 0) { \ + return -1; \ + } \ +} while (0) -PyMODINIT_FUNC -PyInit__io(void) +static int +iomodule_exec(PyObject *m) { - PyObject *m = PyModule_Create(&_PyIO_Module); - _PyIO_State *state = NULL; - if (m == NULL) - return NULL; - state = get_io_state(m); - state->initialized = 0; + _PyIO_State *state = get_io_state(m); /* DEFAULT_BUFFER_SIZE */ if (PyModule_AddIntMacro(m, DEFAULT_BUFFER_SIZE) < 0) - goto fail; + return -1; /* UnsupportedOperation inherits from ValueError and OSError */ state->unsupported_operation = PyObject_CallFunction( (PyObject *)&PyType_Type, "s(OO){}", "UnsupportedOperation", PyExc_OSError, PyExc_ValueError); if (state->unsupported_operation == NULL) - goto fail; - Py_INCREF(state->unsupported_operation); - if (PyModule_AddObject(m, "UnsupportedOperation", - state->unsupported_operation) < 0) - goto fail; + return -1; + if (PyModule_AddObjectRef(m, "UnsupportedOperation", + state->unsupported_operation) < 0) + { + return -1; + } /* BlockingIOError, for compatibility */ if (PyModule_AddObjectRef(m, "BlockingIOError", (PyObject *) PyExc_BlockingIOError) < 0) { - goto fail; + return -1; } - // Set type base classes - PyFileIO_Type.tp_base = &PyRawIOBase_Type; - PyBytesIO_Type.tp_base = &PyBufferedIOBase_Type; - PyStringIO_Type.tp_base = &PyTextIOBase_Type; -#ifdef MS_WINDOWS - PyWindowsConsoleIO_Type.tp_base = &PyRawIOBase_Type; + // Base classes + ADD_TYPE(m, state->PyIncrementalNewlineDecoder_Type, &nldecoder_spec, NULL); + ADD_TYPE(m, state->PyBytesIOBuffer_Type, &bytesiobuf_spec, NULL); + ADD_TYPE(m, state->PyIOBase_Type, &iobase_spec, NULL); + + // PyIOBase_Type subclasses + ADD_TYPE(m, state->PyTextIOBase_Type, &textiobase_spec, + state->PyIOBase_Type); + ADD_TYPE(m, state->PyBufferedIOBase_Type, &bufferediobase_spec, + state->PyIOBase_Type); + ADD_TYPE(m, state->PyRawIOBase_Type, &rawiobase_spec, + state->PyIOBase_Type); + + // PyBufferedIOBase_Type(PyIOBase_Type) subclasses + ADD_TYPE(m, state->PyBytesIO_Type, &bytesio_spec, state->PyBufferedIOBase_Type); + ADD_TYPE(m, state->PyBufferedWriter_Type, &bufferedwriter_spec, + state->PyBufferedIOBase_Type); + ADD_TYPE(m, state->PyBufferedReader_Type, &bufferedreader_spec, + state->PyBufferedIOBase_Type); + ADD_TYPE(m, state->PyBufferedRWPair_Type, &bufferedrwpair_spec, + state->PyBufferedIOBase_Type); + ADD_TYPE(m, state->PyBufferedRandom_Type, &bufferedrandom_spec, + state->PyBufferedIOBase_Type); + + // PyRawIOBase_Type(PyIOBase_Type) subclasses + ADD_TYPE(m, state->PyFileIO_Type, &fileio_spec, state->PyRawIOBase_Type); + +#ifdef HAVE_WINDOWS_CONSOLE_IO + ADD_TYPE(m, state->PyWindowsConsoleIO_Type, &winconsoleio_spec, + state->PyRawIOBase_Type); #endif - PyBufferedReader_Type.tp_base = &PyBufferedIOBase_Type; - PyBufferedWriter_Type.tp_base = &PyBufferedIOBase_Type; - PyBufferedRWPair_Type.tp_base = &PyBufferedIOBase_Type; - PyBufferedRandom_Type.tp_base = &PyBufferedIOBase_Type; - PyTextIOWrapper_Type.tp_base = &PyTextIOBase_Type; - - // Add types - for (size_t i=0; i < Py_ARRAY_LENGTH(static_types); i++) { - PyTypeObject *type = static_types[i]; - // Private type not exposed in the _io module - if (type == &_PyBytesIOBuffer_Type) { - if (PyType_Ready(type) < 0) { - goto fail; - } - } - else { - if (PyModule_AddType(m, type) < 0) { - goto fail; - } - } - } - state->initialized = 1; + // PyTextIOBase_Type(PyIOBase_Type) subclasses + ADD_TYPE(m, state->PyStringIO_Type, &stringio_spec, state->PyTextIOBase_Type); + ADD_TYPE(m, state->PyTextIOWrapper_Type, &textiowrapper_spec, + state->PyTextIOBase_Type); - return m; +#undef ADD_TYPE + return 0; +} - fail: - Py_XDECREF(state->unsupported_operation); - Py_DECREF(m); - return NULL; +static struct PyModuleDef_Slot iomodule_slots[] = { + {Py_mod_exec, iomodule_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, + {0, NULL}, +}; + +struct PyModuleDef _PyIO_Module = { + .m_base = PyModuleDef_HEAD_INIT, + .m_name = "io", + .m_doc = module_doc, + .m_size = sizeof(_PyIO_State), + .m_methods = module_methods, + .m_traverse = iomodule_traverse, + .m_clear = iomodule_clear, + .m_free = iomodule_free, + .m_slots = iomodule_slots, +}; + +PyMODINIT_FUNC +PyInit__io(void) +{ + return PyModuleDef_Init(&_PyIO_Module); } diff --git a/Modules/_io/_iomodule.h b/Modules/_io/_iomodule.h index c260080f..afd638a1 100644 --- a/Modules/_io/_iomodule.h +++ b/Modules/_io/_iomodule.h @@ -4,38 +4,41 @@ #include "exports.h" -/* ABCs */ -extern PyTypeObject PyIOBase_Type; -extern PyTypeObject PyRawIOBase_Type; -extern PyTypeObject PyBufferedIOBase_Type; -extern PyTypeObject PyTextIOBase_Type; - -/* Concrete classes */ -extern PyTypeObject PyFileIO_Type; -extern PyTypeObject PyBytesIO_Type; -extern PyTypeObject PyStringIO_Type; -extern PyTypeObject PyBufferedReader_Type; -extern PyTypeObject PyBufferedWriter_Type; -extern PyTypeObject PyBufferedRWPair_Type; -extern PyTypeObject PyBufferedRandom_Type; -extern PyTypeObject PyTextIOWrapper_Type; -extern PyTypeObject PyIncrementalNewlineDecoder_Type; - -#ifndef Py_LIMITED_API -#ifdef MS_WINDOWS -extern PyTypeObject PyWindowsConsoleIO_Type; -PyAPI_DATA(PyObject *) _PyWindowsConsoleIO_Type; -#define PyWindowsConsoleIO_Check(op) (PyObject_TypeCheck((op), (PyTypeObject*)_PyWindowsConsoleIO_Type)) -#endif /* MS_WINDOWS */ -#endif /* Py_LIMITED_API */ +#include "pycore_moduleobject.h" // _PyModule_GetState() +#include "pycore_typeobject.h" // _PyType_GetModuleState() +#include "structmember.h" + +/* Type specs */ +extern PyType_Spec bufferediobase_spec; +extern PyType_Spec bufferedrandom_spec; +extern PyType_Spec bufferedreader_spec; +extern PyType_Spec bufferedrwpair_spec; +extern PyType_Spec bufferedwriter_spec; +extern PyType_Spec bytesio_spec; +extern PyType_Spec bytesiobuf_spec; +extern PyType_Spec fileio_spec; +extern PyType_Spec iobase_spec; +extern PyType_Spec nldecoder_spec; +extern PyType_Spec rawiobase_spec; +extern PyType_Spec stringio_spec; +extern PyType_Spec textiobase_spec; +extern PyType_Spec textiowrapper_spec; + +#ifdef HAVE_WINDOWS_CONSOLE_IO +extern PyType_Spec winconsoleio_spec; +#endif /* These functions are used as METH_NOARGS methods, are normally called * with args=NULL, and return a new reference. * BUT when args=Py_True is passed, they return a borrowed reference. */ -extern PyObject* _PyIOBase_check_readable(PyObject *self, PyObject *args); -extern PyObject* _PyIOBase_check_writable(PyObject *self, PyObject *args); -extern PyObject* _PyIOBase_check_seekable(PyObject *self, PyObject *args); +typedef struct _io_state _PyIO_State; // Forward decl. +extern PyObject* _PyIOBase_check_readable(_PyIO_State *state, + PyObject *self, PyObject *args); +extern PyObject* _PyIOBase_check_writable(_PyIO_State *state, + PyObject *self, PyObject *args); +extern PyObject* _PyIOBase_check_seekable(_PyIO_State *state, + PyObject *self, PyObject *args); extern PyObject* _PyIOBase_check_closed(PyObject *self, PyObject *args); /* Helper for finalization. @@ -139,20 +142,56 @@ extern Py_off_t PyNumber_AsOff_t(PyObject *item, PyObject *err); extern PyModuleDef _PyIO_Module; -typedef struct { +struct _io_state { int initialized; - PyObject *locale_module; - PyObject *unsupported_operation; -} _PyIO_State; - -#define IO_MOD_STATE(mod) ((_PyIO_State *)PyModule_GetState(mod)) -#define IO_STATE() _PyIO_get_module_state() -extern _PyIO_State *_PyIO_get_module_state(void); - -#ifdef MS_WINDOWS + /* Types */ + PyTypeObject *PyIOBase_Type; + PyTypeObject *PyIncrementalNewlineDecoder_Type; + PyTypeObject *PyRawIOBase_Type; + PyTypeObject *PyBufferedIOBase_Type; + PyTypeObject *PyBufferedRWPair_Type; + PyTypeObject *PyBufferedRandom_Type; + PyTypeObject *PyBufferedReader_Type; + PyTypeObject *PyBufferedWriter_Type; + PyTypeObject *PyBytesIOBuffer_Type; + PyTypeObject *PyBytesIO_Type; + PyTypeObject *PyFileIO_Type; + PyTypeObject *PyStringIO_Type; + PyTypeObject *PyTextIOBase_Type; + PyTypeObject *PyTextIOWrapper_Type; +#ifdef HAVE_WINDOWS_CONSOLE_IO + PyTypeObject *PyWindowsConsoleIO_Type; +#endif +}; + +static inline _PyIO_State * +get_io_state(PyObject *module) +{ + void *state = _PyModule_GetState(module); + assert(state != NULL); + return (_PyIO_State *)state; +} + +static inline _PyIO_State * +get_io_state_by_cls(PyTypeObject *cls) +{ + void *state = _PyType_GetModuleState(cls); + assert(state != NULL); + return (_PyIO_State *)state; +} + +static inline _PyIO_State * +find_io_state_by_def(PyTypeObject *type) +{ + PyObject *mod = PyType_GetModuleByDef(type, &_PyIO_Module); + assert(mod != NULL); + return get_io_state(mod); +} + +extern PyObject *_PyIOBase_cannot_pickle(PyObject *self, PyObject *args); + +#ifdef HAVE_WINDOWS_CONSOLE_IO extern char _PyIO_get_console_type(PyObject *); #endif - -extern Py_EXPORTED_SYMBOL PyTypeObject _PyBytesIOBuffer_Type; diff --git a/Modules/_io/bufferedio.c b/Modules/_io/bufferedio.c index 4a4a1992..f30d54a5 100644 --- a/Modules/_io/bufferedio.c +++ b/Modules/_io/bufferedio.c @@ -16,14 +16,14 @@ /*[clinic input] module _io -class _io._BufferedIOBase "PyObject *" "&PyBufferedIOBase_Type" -class _io._Buffered "buffered *" "&PyBufferedIOBase_Type" -class _io.BufferedReader "buffered *" "&PyBufferedReader_Type" -class _io.BufferedWriter "buffered *" "&PyBufferedWriter_Type" -class _io.BufferedRWPair "rwpair *" "&PyBufferedRWPair_Type" -class _io.BufferedRandom "buffered *" "&PyBufferedRandom_Type" +class _io._BufferedIOBase "PyObject *" "clinic_state()->PyBufferedIOBase_Type" +class _io._Buffered "buffered *" "clinic_state()->PyBufferedIOBase_Type" +class _io.BufferedReader "buffered *" "clinic_state()->PyBufferedReader_Type" +class _io.BufferedWriter "buffered *" "clinic_state()->PyBufferedWriter_Type" +class _io.BufferedRWPair "rwpair *" "clinic_state()->PyBufferedRWPair_Type" +class _io.BufferedRandom "buffered *" "clinic_state()->PyBufferedRandom_Type" [clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=59460b9c5639984d]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3b3ef9cbbbad4590]*/ /* * BufferedIOBase class, inherits from IOBase. @@ -106,17 +106,18 @@ _io__BufferedIOBase_readinto1_impl(PyObject *self, Py_buffer *buffer) } static PyObject * -bufferediobase_unsupported(const char *message) +bufferediobase_unsupported(_PyIO_State *state, const char *message) { - _PyIO_State *state = IO_STATE(); - if (state != NULL) - PyErr_SetString(state->unsupported_operation, message); + PyErr_SetString(state->unsupported_operation, message); return NULL; } /*[clinic input] _io._BufferedIOBase.detach + cls: defining_class + / + Disconnect this buffer from its underlying raw stream and return it. After the raw stream has been detached, the buffer is in an unusable @@ -124,62 +125,92 @@ state. [clinic start generated code]*/ static PyObject * -_io__BufferedIOBase_detach_impl(PyObject *self) -/*[clinic end generated code: output=754977c8d10ed88c input=822427fb58fe4169]*/ +_io__BufferedIOBase_detach_impl(PyObject *self, PyTypeObject *cls) +/*[clinic end generated code: output=b87b135d67cd4448 input=0b61a7b4357c1ea7]*/ { - return bufferediobase_unsupported("detach"); + _PyIO_State *state = get_io_state_by_cls(cls); + return bufferediobase_unsupported(state, "detach"); } -PyDoc_STRVAR(bufferediobase_read_doc, - "Read and return up to n bytes.\n" - "\n" - "If the argument is omitted, None, or negative, reads and\n" - "returns all data until EOF.\n" - "\n" - "If the argument is positive, and the underlying raw stream is\n" - "not 'interactive', multiple raw reads may be issued to satisfy\n" - "the byte count (unless EOF is reached first). But for\n" - "interactive raw streams (as well as sockets and pipes), at most\n" - "one raw read will be issued, and a short result does not imply\n" - "that EOF is imminent.\n" - "\n" - "Returns an empty bytes object on EOF.\n" - "\n" - "Returns None if the underlying raw stream was open in non-blocking\n" - "mode and no data is available at the moment.\n"); +/*[clinic input] +_io._BufferedIOBase.read + + cls: defining_class + size: int(unused=True) = -1 + / + +Read and return up to n bytes. + +If the size argument is omitted, None, or negative, read and +return all data until EOF. + +If the size argument is positive, and the underlying raw stream is +not 'interactive', multiple raw reads may be issued to satisfy +the byte count (unless EOF is reached first). +However, for interactive raw streams (as well as sockets and pipes), +at most one raw read will be issued, and a short result does not +imply that EOF is imminent. + +Return an empty bytes object on EOF. + +Return None if the underlying raw stream was open in non-blocking +mode and no data is available at the moment. +[clinic start generated code]*/ static PyObject * -bufferediobase_read(PyObject *self, PyObject *args) +_io__BufferedIOBase_read_impl(PyObject *self, PyTypeObject *cls, + int Py_UNUSED(size)) +/*[clinic end generated code: output=aceb2765587b0a29 input=824f6f910465e61a]*/ { - return bufferediobase_unsupported("read"); + _PyIO_State *state = get_io_state_by_cls(cls); + return bufferediobase_unsupported(state, "read"); } -PyDoc_STRVAR(bufferediobase_read1_doc, - "Read and return up to n bytes, with at most one read() call\n" - "to the underlying raw stream. A short result does not imply\n" - "that EOF is imminent.\n" - "\n" - "Returns an empty bytes object on EOF.\n"); +/*[clinic input] +_io._BufferedIOBase.read1 + + cls: defining_class + size: int(unused=True) = -1 + / + +Read and return up to size bytes, with at most one read() call to the underlying raw stream. + +Return an empty bytes object on EOF. +A short result does not imply that EOF is imminent. +[clinic start generated code]*/ static PyObject * -bufferediobase_read1(PyObject *self, PyObject *args) +_io__BufferedIOBase_read1_impl(PyObject *self, PyTypeObject *cls, + int Py_UNUSED(size)) +/*[clinic end generated code: output=2e7fc62972487eaa input=af76380e020fd9e6]*/ { - return bufferediobase_unsupported("read1"); + _PyIO_State *state = get_io_state_by_cls(cls); + return bufferediobase_unsupported(state, "read1"); } -PyDoc_STRVAR(bufferediobase_write_doc, - "Write the given buffer to the IO stream.\n" - "\n" - "Returns the number of bytes written, which is always the length of b\n" - "in bytes.\n" - "\n" - "Raises BlockingIOError if the buffer is full and the\n" - "underlying raw stream cannot accept more data at the moment.\n"); +/*[clinic input] +_io._BufferedIOBase.write + + cls: defining_class + b: object(unused=True) + / + +Write buffer b to the IO stream. + +Return the number of bytes written, which is always +the length of b in bytes. + +Raise BlockingIOError if the buffer is full and the +underlying raw stream cannot accept more data at the moment. +[clinic start generated code]*/ static PyObject * -bufferediobase_write(PyObject *self, PyObject *args) +_io__BufferedIOBase_write_impl(PyObject *self, PyTypeObject *cls, + PyObject *Py_UNUSED(b)) +/*[clinic end generated code: output=712c635246bf2306 input=9793f5c8f71029ad]*/ { - return bufferediobase_unsupported("write"); + _PyIO_State *state = get_io_state_by_cls(cls); + return bufferediobase_unsupported(state, "write"); } @@ -262,7 +293,8 @@ _enter_buffered_busy(buffered *self) "reentrant call inside %R", self); return 0; } - relax_locking = _Py_IsFinalizing(); + PyInterpreterState *interp = PyInterpreterState_Get(); + relax_locking = _Py_IsInterpreterFinalizing(interp); Py_BEGIN_ALLOW_THREADS if (!relax_locking) st = PyThread_acquire_lock(self->lock, 1); @@ -363,9 +395,19 @@ _enter_buffered_busy(buffered *self) (self->buffer_size * (size / self->buffer_size))) +static int +buffered_clear(buffered *self) +{ + self->ok = 0; + Py_CLEAR(self->raw); + Py_CLEAR(self->dict); + return 0; +} + static void buffered_dealloc(buffered *self) { + PyTypeObject *tp = Py_TYPE(self); self->finalizing = 1; if (_PyIOBase_finalize((PyObject *) self) < 0) return; @@ -373,7 +415,6 @@ buffered_dealloc(buffered *self) self->ok = 0; if (self->weakreflist != NULL) PyObject_ClearWeakRefs((PyObject *)self); - Py_CLEAR(self->raw); if (self->buffer) { PyMem_Free(self->buffer); self->buffer = NULL; @@ -382,43 +423,49 @@ buffered_dealloc(buffered *self) PyThread_free_lock(self->lock); self->lock = NULL; } - Py_CLEAR(self->dict); - Py_TYPE(self)->tp_free((PyObject *)self); + (void)buffered_clear(self); + tp->tp_free((PyObject *)self); + Py_DECREF(tp); } +/*[clinic input] +_io._Buffered.__sizeof__ +[clinic start generated code]*/ + static PyObject * -buffered_sizeof(buffered *self, PyObject *Py_UNUSED(ignored)) +_io__Buffered___sizeof___impl(buffered *self) +/*[clinic end generated code: output=0231ef7f5053134e input=753c782d808d34df]*/ { - Py_ssize_t res; - - res = _PyObject_SIZE(Py_TYPE(self)); - if (self->buffer) - res += self->buffer_size; - return PyLong_FromSsize_t(res); + size_t res = _PyObject_SIZE(Py_TYPE(self)); + if (self->buffer) { + res += (size_t)self->buffer_size; + } + return PyLong_FromSize_t(res); } static int buffered_traverse(buffered *self, visitproc visit, void *arg) { + Py_VISIT(Py_TYPE(self)); Py_VISIT(self->raw); Py_VISIT(self->dict); return 0; } -static int -buffered_clear(buffered *self) -{ - self->ok = 0; - Py_CLEAR(self->raw); - Py_CLEAR(self->dict); - return 0; -} - /* Because this can call arbitrary code, it shouldn't be called when the refcount is 0 (that is, not directly from tp_dealloc unless the refcount has been temporarily re-incremented). */ +/*[clinic input] +_io._Buffered._dealloc_warn + + source: object + / + +[clinic start generated code]*/ + static PyObject * -buffered_dealloc_warn(buffered *self, PyObject *source) +_io__Buffered__dealloc_warn(buffered *self, PyObject *source) +/*[clinic end generated code: output=690dcc3df8967162 input=8f845f2a4786391c]*/ { if (self->ok && self->raw) { PyObject *r; @@ -438,9 +485,13 @@ buffered_dealloc_warn(buffered *self, PyObject *source) */ /* Flush and close */ +/*[clinic input] +_io._Buffered.flush as _io__Buffered_simple_flush +[clinic start generated code]*/ static PyObject * -buffered_simple_flush(buffered *self, PyObject *args) +_io__Buffered_simple_flush_impl(buffered *self) +/*[clinic end generated code: output=29ebb3820db1bdfd input=f33ef045e7250767]*/ { CHECK_INITIALIZED(self) return PyObject_CallMethodNoArgs(self->raw, &_Py_ID(flush)); @@ -467,27 +518,32 @@ buffered_closed_get(buffered *self, void *context) return PyObject_GetAttr(self->raw, &_Py_ID(closed)); } +/*[clinic input] +_io._Buffered.close +[clinic start generated code]*/ + static PyObject * -buffered_close(buffered *self, PyObject *args) +_io__Buffered_close_impl(buffered *self) +/*[clinic end generated code: output=7280b7b42033be0c input=d20b83d1ddd7d805]*/ { - PyObject *res = NULL, *exc = NULL, *val, *tb; + PyObject *res = NULL; int r; CHECK_INITIALIZED(self) - if (!ENTER_BUFFERED(self)) + if (!ENTER_BUFFERED(self)) { return NULL; + } r = buffered_closed(self); if (r < 0) goto end; if (r > 0) { - res = Py_None; - Py_INCREF(res); + res = Py_NewRef(Py_None); goto end; } if (self->finalizing) { - PyObject *r = buffered_dealloc_warn(self, (PyObject *) self); + PyObject *r = _io__Buffered__dealloc_warn(self, (PyObject *) self); if (r) Py_DECREF(r); else @@ -496,12 +552,16 @@ buffered_close(buffered *self, PyObject *args) /* flush() will most probably re-take the lock, so drop it first */ LEAVE_BUFFERED(self) res = PyObject_CallMethodNoArgs((PyObject *)self, &_Py_ID(flush)); - if (!ENTER_BUFFERED(self)) + if (!ENTER_BUFFERED(self)) { return NULL; - if (res == NULL) - PyErr_Fetch(&exc, &val, &tb); - else + } + PyObject *exc = NULL; + if (res == NULL) { + exc = PyErr_GetRaisedException(); + } + else { Py_DECREF(res); + } res = PyObject_CallMethodNoArgs(self->raw, &_Py_ID(close)); @@ -511,7 +571,7 @@ buffered_close(buffered *self, PyObject *args) } if (exc != NULL) { - _PyErr_ChainExceptions(exc, val, tb); + _PyErr_ChainExceptions1(exc); Py_CLEAR(res); } @@ -523,10 +583,13 @@ end: return res; } -/* detach */ +/*[clinic input] +_io._Buffered.detach +[clinic start generated code]*/ static PyObject * -buffered_detach(buffered *self, PyObject *Py_UNUSED(ignored)) +_io__Buffered_detach_impl(buffered *self) +/*[clinic end generated code: output=dd0fc057b8b779f7 input=482762a345cc9f44]*/ { PyObject *raw, *res; CHECK_INITIALIZED(self) @@ -543,22 +606,37 @@ buffered_detach(buffered *self, PyObject *Py_UNUSED(ignored)) /* Inquiries */ +/*[clinic input] +_io._Buffered.seekable +[clinic start generated code]*/ + static PyObject * -buffered_seekable(buffered *self, PyObject *Py_UNUSED(ignored)) +_io__Buffered_seekable_impl(buffered *self) +/*[clinic end generated code: output=90172abb5ceb6e8f input=7d35764f5fb5262b]*/ { CHECK_INITIALIZED(self) return PyObject_CallMethodNoArgs(self->raw, &_Py_ID(seekable)); } +/*[clinic input] +_io._Buffered.readable +[clinic start generated code]*/ + static PyObject * -buffered_readable(buffered *self, PyObject *Py_UNUSED(ignored)) +_io__Buffered_readable_impl(buffered *self) +/*[clinic end generated code: output=92afa07661ecb698 input=640619addb513b8b]*/ { CHECK_INITIALIZED(self) return PyObject_CallMethodNoArgs(self->raw, &_Py_ID(readable)); } +/*[clinic input] +_io._Buffered.writable +[clinic start generated code]*/ + static PyObject * -buffered_writable(buffered *self, PyObject *Py_UNUSED(ignored)) +_io__Buffered_writable_impl(buffered *self) +/*[clinic end generated code: output=4e3eee8d6f9d8552 input=b35ea396b2201554]*/ { CHECK_INITIALIZED(self) return PyObject_CallMethodNoArgs(self->raw, &_Py_ID(writable)); @@ -580,15 +658,25 @@ buffered_mode_get(buffered *self, void *context) /* Lower-level APIs */ +/*[clinic input] +_io._Buffered.fileno +[clinic start generated code]*/ + static PyObject * -buffered_fileno(buffered *self, PyObject *Py_UNUSED(ignored)) +_io__Buffered_fileno_impl(buffered *self) +/*[clinic end generated code: output=b717648d58a95ee3 input=768ea30b3f6314a7]*/ { CHECK_INITIALIZED(self) return PyObject_CallMethodNoArgs(self->raw, &_Py_ID(fileno)); } +/*[clinic input] +_io._Buffered.isatty +[clinic start generated code]*/ + static PyObject * -buffered_isatty(buffered *self, PyObject *Py_UNUSED(ignored)) +_io__Buffered_isatty_impl(buffered *self) +/*[clinic end generated code: output=c20e55caae67baea input=9ea007b11559bee4]*/ { CHECK_INITIALIZED(self) return PyObject_CallMethodNoArgs(self->raw, &_Py_ID(isatty)); @@ -636,17 +724,14 @@ _set_BlockingIOError(const char *msg, Py_ssize_t written) static Py_ssize_t * _buffered_check_blocking_error(void) { - PyObject *t, *v, *tb; - PyOSErrorObject *err; - - PyErr_Fetch(&t, &v, &tb); - if (v == NULL || !PyErr_GivenExceptionMatches(v, PyExc_BlockingIOError)) { - PyErr_Restore(t, v, tb); + PyObject *exc = PyErr_GetRaisedException(); + if (exc == NULL || !PyErr_GivenExceptionMatches(exc, PyExc_BlockingIOError)) { + PyErr_SetRaisedException(exc); return NULL; } - err = (PyOSErrorObject *) v; + PyOSErrorObject *err = (PyOSErrorObject *)exc; /* TODO: sanity check (err->written >= 0) */ - PyErr_Restore(t, v, tb); + PyErr_SetRaisedException(exc); return &err->written; } @@ -748,29 +833,25 @@ _buffered_init(buffered *self) int _PyIO_trap_eintr(void) { - static PyObject *eintr_int = NULL; - PyObject *typ, *val, *tb; - PyOSErrorObject *env_err; - - if (eintr_int == NULL) { - eintr_int = PyLong_FromLong(EINTR); - assert(eintr_int != NULL); - } - if (!PyErr_ExceptionMatches(PyExc_OSError)) + if (!PyErr_ExceptionMatches(PyExc_OSError)) { return 0; - PyErr_Fetch(&typ, &val, &tb); - PyErr_NormalizeException(&typ, &val, &tb); - env_err = (PyOSErrorObject *) val; + } + PyObject *exc = PyErr_GetRaisedException(); + PyOSErrorObject *env_err = (PyOSErrorObject *)exc; assert(env_err != NULL); - if (env_err->myerrno != NULL && - PyObject_RichCompareBool(env_err->myerrno, eintr_int, Py_EQ) > 0) { - Py_DECREF(typ); - Py_DECREF(val); - Py_XDECREF(tb); - return 1; + if (env_err->myerrno != NULL) { + assert(EINTR > 0 && EINTR < INT_MAX); + assert(PyLong_CheckExact(env_err->myerrno)); + int overflow; + int myerrno = PyLong_AsLongAndOverflow(env_err->myerrno, &overflow); + PyErr_Clear(); + if (myerrno == EINTR) { + Py_DECREF(exc); + return 1; + } } /* This silences any error set by PyObject_RichCompareBool() */ - PyErr_Restore(typ, val, tb); + PyErr_SetRaisedException(exc); return 0; } @@ -800,8 +881,13 @@ buffered_flush_and_rewind_unlocked(buffered *self) Py_RETURN_NONE; } +/*[clinic input] +_io._Buffered.flush +[clinic start generated code]*/ + static PyObject * -buffered_flush(buffered *self, PyObject *args) +_io__Buffered_flush_impl(buffered *self) +/*[clinic end generated code: output=da2674ef1ce71f3a input=fda63444697c6bf4]*/ { PyObject *res; @@ -1007,8 +1093,7 @@ _buffered_readinto_generic(buffered *self, Py_buffer *buffer, char readinto1) break; if (n < 0) { if (n == -2) { - Py_INCREF(Py_None); - res = Py_None; + res = Py_NewRef(Py_None); } goto end; } @@ -1176,8 +1261,13 @@ _io__Buffered_readline_impl(buffered *self, Py_ssize_t size) } +/*[clinic input] +_io._Buffered.tell +[clinic start generated code]*/ + static PyObject * -buffered_tell(buffered *self, PyObject *Py_UNUSED(ignored)) +_io__Buffered_tell_impl(buffered *self) +/*[clinic end generated code: output=386972ae84716c1e input=ad61e04a6b349573]*/ { Py_off_t pos; @@ -1224,8 +1314,10 @@ _io__Buffered_seek_impl(buffered *self, PyObject *targetobj, int whence) CHECK_CLOSED(self, "seek of closed file") - if (_PyIOBase_check_seekable(self->raw, Py_True) == NULL) + _PyIO_State *state = find_io_state_by_def(Py_TYPE(self)); + if (_PyIOBase_check_seekable(state, self->raw, Py_True) == NULL) { return NULL; + } target = PyNumber_AsOff_t(targetobj, PyExc_ValueError); if (target == -1 && PyErr_Occurred()) @@ -1287,20 +1379,22 @@ end: /*[clinic input] _io._Buffered.truncate + cls: defining_class pos: object = None / [clinic start generated code]*/ static PyObject * -_io__Buffered_truncate_impl(buffered *self, PyObject *pos) -/*[clinic end generated code: output=667ca03c60c270de input=8a1be34d57cca2d3]*/ +_io__Buffered_truncate_impl(buffered *self, PyTypeObject *cls, PyObject *pos) +/*[clinic end generated code: output=fe3882fbffe79f1a input=f5b737d97d76303f]*/ { PyObject *res = NULL; CHECK_INITIALIZED(self) CHECK_CLOSED(self, "truncate of closed file") if (!self->writable) { - return bufferediobase_unsupported("truncate"); + _PyIO_State *state = get_io_state_by_cls(cls); + return bufferediobase_unsupported(state, "truncate"); } if (!ENTER_BUFFERED(self)) return NULL; @@ -1331,9 +1425,11 @@ buffered_iternext(buffered *self) CHECK_INITIALIZED(self); + _PyIO_State *state = find_io_state_by_def(Py_TYPE(self)); tp = Py_TYPE(self); - if (tp == &PyBufferedReader_Type || - tp == &PyBufferedRandom_Type) { + if (Py_IS_TYPE(tp, state->PyBufferedReader_Type) || + Py_IS_TYPE(tp, state->PyBufferedRandom_Type)) + { /* Skip method call overhead for speed */ line = _buffered_readline(self, -1); } @@ -1419,11 +1515,12 @@ _io_BufferedReader___init___impl(buffered *self, PyObject *raw, self->ok = 0; self->detached = 0; - if (_PyIOBase_check_readable(raw, Py_True) == NULL) + _PyIO_State *state = find_io_state_by_def(Py_TYPE(self)); + if (_PyIOBase_check_readable(state, raw, Py_True) == NULL) { return -1; + } - Py_INCREF(raw); - Py_XSETREF(self->raw, raw); + Py_XSETREF(self->raw, Py_NewRef(raw)); self->buffer_size = buffer_size; self->readable = 1; self->writable = 0; @@ -1432,8 +1529,10 @@ _io_BufferedReader___init___impl(buffered *self, PyObject *raw, return -1; _bufferedreader_reset_buf(self); - self->fast_closed_checks = (Py_IS_TYPE(self, &PyBufferedReader_Type) && - Py_IS_TYPE(raw, &PyFileIO_Type)); + self->fast_closed_checks = ( + Py_IS_TYPE(self, state->PyBufferedReader_Type) && + Py_IS_TYPE(raw, state->PyFileIO_Type) + ); self->ok = 1; return 0; @@ -1740,7 +1839,6 @@ _bufferedreader_peek_unlocked(buffered *self) self->pos = 0; return PyBytes_FromStringAndSize(self->buffer, r); } - /* @@ -1773,8 +1871,10 @@ _io_BufferedWriter___init___impl(buffered *self, PyObject *raw, self->ok = 0; self->detached = 0; - if (_PyIOBase_check_writable(raw, Py_True) == NULL) + _PyIO_State *state = find_io_state_by_def(Py_TYPE(self)); + if (_PyIOBase_check_writable(state, raw, Py_True) == NULL) { return -1; + } Py_INCREF(raw); Py_XSETREF(self->raw, raw); @@ -1787,8 +1887,10 @@ _io_BufferedWriter___init___impl(buffered *self, PyObject *raw, _bufferedwriter_reset_buf(self); self->pos = 0; - self->fast_closed_checks = (Py_IS_TYPE(self, &PyBufferedWriter_Type) && - Py_IS_TYPE(raw, &PyFileIO_Type)); + self->fast_closed_checks = ( + Py_IS_TYPE(self, state->PyBufferedWriter_Type) && + Py_IS_TYPE(raw, state->PyFileIO_Type) + ); self->ok = 1; return 0; @@ -2047,7 +2149,6 @@ error: LEAVE_BUFFERED(self) return res; } - /* @@ -2089,18 +2190,23 @@ _io_BufferedRWPair___init___impl(rwpair *self, PyObject *reader, PyObject *writer, Py_ssize_t buffer_size) /*[clinic end generated code: output=327e73d1aee8f984 input=620d42d71f33a031]*/ { - if (_PyIOBase_check_readable(reader, Py_True) == NULL) + _PyIO_State *state = find_io_state_by_def(Py_TYPE(self)); + if (_PyIOBase_check_readable(state, reader, Py_True) == NULL) { return -1; - if (_PyIOBase_check_writable(writer, Py_True) == NULL) + } + if (_PyIOBase_check_writable(state, writer, Py_True) == NULL) { return -1; + } self->reader = (buffered *) PyObject_CallFunction( - (PyObject *) &PyBufferedReader_Type, "On", reader, buffer_size); + (PyObject *)state->PyBufferedReader_Type, + "On", reader, buffer_size); if (self->reader == NULL) return -1; self->writer = (buffered *) PyObject_CallFunction( - (PyObject *) &PyBufferedWriter_Type, "On", writer, buffer_size); + (PyObject *)state->PyBufferedWriter_Type, + "On", writer, buffer_size); if (self->writer == NULL) { Py_CLEAR(self->reader); return -1; @@ -2112,7 +2218,10 @@ _io_BufferedRWPair___init___impl(rwpair *self, PyObject *reader, static int bufferedrwpair_traverse(rwpair *self, visitproc visit, void *arg) { + Py_VISIT(Py_TYPE(self)); Py_VISIT(self->dict); + Py_VISIT(self->reader); + Py_VISIT(self->writer); return 0; } @@ -2128,13 +2237,13 @@ bufferedrwpair_clear(rwpair *self) static void bufferedrwpair_dealloc(rwpair *self) { + PyTypeObject *tp = Py_TYPE(self); _PyObject_GC_UNTRACK(self); if (self->weakreflist != NULL) PyObject_ClearWeakRefs((PyObject *)self); - Py_CLEAR(self->reader); - Py_CLEAR(self->writer); - Py_CLEAR(self->dict); - Py_TYPE(self)->tp_free((PyObject *) self); + (void)bufferedrwpair_clear(self); + tp->tp_free((PyObject *) self); + Py_DECREF(tp); } static PyObject * @@ -2215,15 +2324,17 @@ bufferedrwpair_writable(rwpair *self, PyObject *Py_UNUSED(ignored)) static PyObject * bufferedrwpair_close(rwpair *self, PyObject *Py_UNUSED(ignored)) { - PyObject *exc = NULL, *val, *tb; + PyObject *exc = NULL; PyObject *ret = _forward_call(self->writer, &_Py_ID(close), NULL); - if (ret == NULL) - PyErr_Fetch(&exc, &val, &tb); - else + if (ret == NULL) { + exc = PyErr_GetRaisedException(); + } + else { Py_DECREF(ret); + } ret = _forward_call(self->reader, &_Py_ID(close), NULL); if (exc != NULL) { - _PyErr_ChainExceptions(exc, val, tb); + _PyErr_ChainExceptions1(exc); Py_CLEAR(ret); } return ret; @@ -2253,7 +2364,6 @@ bufferedrwpair_closed_get(rwpair *self, void *context) } return PyObject_GetAttr((PyObject *) self->writer, &_Py_ID(closed)); } - /* @@ -2280,12 +2390,16 @@ _io_BufferedRandom___init___impl(buffered *self, PyObject *raw, self->ok = 0; self->detached = 0; - if (_PyIOBase_check_seekable(raw, Py_True) == NULL) + _PyIO_State *state = find_io_state_by_def(Py_TYPE(self)); + if (_PyIOBase_check_seekable(state, raw, Py_True) == NULL) { return -1; - if (_PyIOBase_check_readable(raw, Py_True) == NULL) + } + if (_PyIOBase_check_readable(state, raw, Py_True) == NULL) { return -1; - if (_PyIOBase_check_writable(raw, Py_True) == NULL) + } + if (_PyIOBase_check_writable(state, raw, Py_True) == NULL) { return -1; + } Py_INCREF(raw); Py_XSETREF(self->raw, raw); @@ -2299,88 +2413,51 @@ _io_BufferedRandom___init___impl(buffered *self, PyObject *raw, _bufferedwriter_reset_buf(self); self->pos = 0; - self->fast_closed_checks = (Py_IS_TYPE(self, &PyBufferedRandom_Type) && - Py_IS_TYPE(raw, &PyFileIO_Type)); + self->fast_closed_checks = (Py_IS_TYPE(self, state->PyBufferedRandom_Type) && + Py_IS_TYPE(raw, state->PyFileIO_Type)); self->ok = 1; return 0; } +#define clinic_state() (find_io_state_by_def(Py_TYPE(self))) #include "clinic/bufferedio.c.h" - +#undef clinic_state static PyMethodDef bufferediobase_methods[] = { _IO__BUFFEREDIOBASE_DETACH_METHODDEF - {"read", bufferediobase_read, METH_VARARGS, bufferediobase_read_doc}, - {"read1", bufferediobase_read1, METH_VARARGS, bufferediobase_read1_doc}, + _IO__BUFFEREDIOBASE_READ_METHODDEF + _IO__BUFFEREDIOBASE_READ1_METHODDEF _IO__BUFFEREDIOBASE_READINTO_METHODDEF _IO__BUFFEREDIOBASE_READINTO1_METHODDEF - {"write", bufferediobase_write, METH_VARARGS, bufferediobase_write_doc}, + _IO__BUFFEREDIOBASE_WRITE_METHODDEF {NULL, NULL} }; -PyTypeObject PyBufferedIOBase_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_io._BufferedIOBase", /*tp_name*/ - 0, /*tp_basicsize*/ - 0, /*tp_itemsize*/ - 0, /*tp_dealloc*/ - 0, /*tp_vectorcall_offset*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_as_async*/ - 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*/ - bufferediobase_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - bufferediobase_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - &PyIOBase_Type, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ - 0, /* tp_free */ - 0, /* tp_is_gc */ - 0, /* tp_bases */ - 0, /* tp_mro */ - 0, /* tp_cache */ - 0, /* tp_subclasses */ - 0, /* tp_weaklist */ - 0, /* tp_del */ - 0, /* tp_version_tag */ - 0, /* tp_finalize */ +static PyType_Slot bufferediobase_slots[] = { + {Py_tp_doc, (void *)bufferediobase_doc}, + {Py_tp_methods, bufferediobase_methods}, + {0, NULL}, }; +/* Do not set Py_TPFLAGS_HAVE_GC so that tp_traverse and tp_clear are inherited */ +PyType_Spec bufferediobase_spec = { + .name = "_io._BufferedIOBase", + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = bufferediobase_slots, +}; static PyMethodDef bufferedreader_methods[] = { /* BufferedIOMixin methods */ - {"detach", (PyCFunction)buffered_detach, METH_NOARGS}, - {"flush", (PyCFunction)buffered_simple_flush, METH_NOARGS}, - {"close", (PyCFunction)buffered_close, METH_NOARGS}, - {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS}, - {"readable", (PyCFunction)buffered_readable, METH_NOARGS}, - {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS}, - {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS}, - {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O}, + _IO__BUFFERED_DETACH_METHODDEF + _IO__BUFFERED_SIMPLE_FLUSH_METHODDEF + _IO__BUFFERED_CLOSE_METHODDEF + _IO__BUFFERED_SEEKABLE_METHODDEF + _IO__BUFFERED_READABLE_METHODDEF + _IO__BUFFERED_FILENO_METHODDEF + _IO__BUFFERED_ISATTY_METHODDEF + _IO__BUFFERED__DEALLOC_WARN_METHODDEF _IO__BUFFERED_READ_METHODDEF _IO__BUFFERED_PEEK_METHODDEF @@ -2389,15 +2466,20 @@ static PyMethodDef bufferedreader_methods[] = { _IO__BUFFERED_READINTO1_METHODDEF _IO__BUFFERED_READLINE_METHODDEF _IO__BUFFERED_SEEK_METHODDEF - {"tell", (PyCFunction)buffered_tell, METH_NOARGS}, + _IO__BUFFERED_TELL_METHODDEF _IO__BUFFERED_TRUNCATE_METHODDEF - {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS}, + _IO__BUFFERED___SIZEOF___METHODDEF + + {"__reduce__", _PyIOBase_cannot_pickle, METH_VARARGS}, + {"__reduce_ex__", _PyIOBase_cannot_pickle, METH_VARARGS}, {NULL, NULL} }; static PyMemberDef bufferedreader_members[] = { {"raw", T_OBJECT, offsetof(buffered, raw), READONLY}, {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0}, + {"__weaklistoffset__", T_PYSSIZET, offsetof(buffered, weakreflist), READONLY}, + {"__dictoffset__", T_PYSSIZET, offsetof(buffered, dict), READONLY}, {NULL} }; @@ -2409,81 +2491,55 @@ static PyGetSetDef bufferedreader_getset[] = { }; -PyTypeObject PyBufferedReader_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_io.BufferedReader", /*tp_name*/ - sizeof(buffered), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - (destructor)buffered_dealloc, /*tp_dealloc*/ - 0, /*tp_vectorcall_offset*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_as_async*/ - (reprfunc)buffered_repr, /*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 - | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ - _io_BufferedReader___init____doc__, /* tp_doc */ - (traverseproc)buffered_traverse, /* tp_traverse */ - (inquiry)buffered_clear, /* tp_clear */ - 0, /* tp_richcompare */ - offsetof(buffered, weakreflist), /*tp_weaklistoffset*/ - 0, /* tp_iter */ - (iternextfunc)buffered_iternext, /* tp_iternext */ - bufferedreader_methods, /* tp_methods */ - bufferedreader_members, /* tp_members */ - bufferedreader_getset, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - offsetof(buffered, dict), /* tp_dictoffset */ - _io_BufferedReader___init__, /* tp_init */ - 0, /* tp_alloc */ - PyType_GenericNew, /* tp_new */ - 0, /* tp_free */ - 0, /* tp_is_gc */ - 0, /* tp_bases */ - 0, /* tp_mro */ - 0, /* tp_cache */ - 0, /* tp_subclasses */ - 0, /* tp_weaklist */ - 0, /* tp_del */ - 0, /* tp_version_tag */ - 0, /* tp_finalize */ +static PyType_Slot bufferedreader_slots[] = { + {Py_tp_dealloc, buffered_dealloc}, + {Py_tp_repr, buffered_repr}, + {Py_tp_doc, (void *)_io_BufferedReader___init____doc__}, + {Py_tp_traverse, buffered_traverse}, + {Py_tp_clear, buffered_clear}, + {Py_tp_iternext, buffered_iternext}, + {Py_tp_methods, bufferedreader_methods}, + {Py_tp_members, bufferedreader_members}, + {Py_tp_getset, bufferedreader_getset}, + {Py_tp_init, _io_BufferedReader___init__}, + {0, NULL}, }; +PyType_Spec bufferedreader_spec = { + .name = "_io.BufferedReader", + .basicsize = sizeof(buffered), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = bufferedreader_slots, +}; static PyMethodDef bufferedwriter_methods[] = { /* BufferedIOMixin methods */ - {"close", (PyCFunction)buffered_close, METH_NOARGS}, - {"detach", (PyCFunction)buffered_detach, METH_NOARGS}, - {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS}, - {"writable", (PyCFunction)buffered_writable, METH_NOARGS}, - {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS}, - {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS}, - {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O}, + _IO__BUFFERED_CLOSE_METHODDEF + _IO__BUFFERED_DETACH_METHODDEF + _IO__BUFFERED_SEEKABLE_METHODDEF + _IO__BUFFERED_WRITABLE_METHODDEF + _IO__BUFFERED_FILENO_METHODDEF + _IO__BUFFERED_ISATTY_METHODDEF + _IO__BUFFERED__DEALLOC_WARN_METHODDEF _IO_BUFFEREDWRITER_WRITE_METHODDEF _IO__BUFFERED_TRUNCATE_METHODDEF - {"flush", (PyCFunction)buffered_flush, METH_NOARGS}, + _IO__BUFFERED_FLUSH_METHODDEF _IO__BUFFERED_SEEK_METHODDEF - {"tell", (PyCFunction)buffered_tell, METH_NOARGS}, - {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS}, + _IO__BUFFERED_TELL_METHODDEF + _IO__BUFFERED___SIZEOF___METHODDEF + + {"__reduce__", _PyIOBase_cannot_pickle, METH_VARARGS}, + {"__reduce_ex__", _PyIOBase_cannot_pickle, METH_VARARGS}, {NULL, NULL} }; static PyMemberDef bufferedwriter_members[] = { {"raw", T_OBJECT, offsetof(buffered, raw), READONLY}, {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0}, + {"__weaklistoffset__", T_PYSSIZET, offsetof(buffered, weakreflist), READONLY}, + {"__dictoffset__", T_PYSSIZET, offsetof(buffered, dict), READONLY}, {NULL} }; @@ -2495,58 +2551,26 @@ static PyGetSetDef bufferedwriter_getset[] = { }; -PyTypeObject PyBufferedWriter_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_io.BufferedWriter", /*tp_name*/ - sizeof(buffered), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - (destructor)buffered_dealloc, /*tp_dealloc*/ - 0, /*tp_vectorcall_offset*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_as_async*/ - (reprfunc)buffered_repr, /*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 - | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ - _io_BufferedWriter___init____doc__, /* tp_doc */ - (traverseproc)buffered_traverse, /* tp_traverse */ - (inquiry)buffered_clear, /* tp_clear */ - 0, /* tp_richcompare */ - offsetof(buffered, weakreflist), /*tp_weaklistoffset*/ - 0, /* tp_iter */ - 0, /* tp_iternext */ - bufferedwriter_methods, /* tp_methods */ - bufferedwriter_members, /* tp_members */ - bufferedwriter_getset, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - offsetof(buffered, dict), /* tp_dictoffset */ - _io_BufferedWriter___init__, /* tp_init */ - 0, /* tp_alloc */ - PyType_GenericNew, /* tp_new */ - 0, /* tp_free */ - 0, /* tp_is_gc */ - 0, /* tp_bases */ - 0, /* tp_mro */ - 0, /* tp_cache */ - 0, /* tp_subclasses */ - 0, /* tp_weaklist */ - 0, /* tp_del */ - 0, /* tp_version_tag */ - 0, /* tp_finalize */ +static PyType_Slot bufferedwriter_slots[] = { + {Py_tp_dealloc, buffered_dealloc}, + {Py_tp_repr, buffered_repr}, + {Py_tp_doc, (void *)_io_BufferedWriter___init____doc__}, + {Py_tp_traverse, buffered_traverse}, + {Py_tp_clear, buffered_clear}, + {Py_tp_methods, bufferedwriter_methods}, + {Py_tp_members, bufferedwriter_members}, + {Py_tp_getset, bufferedwriter_getset}, + {Py_tp_init, _io_BufferedWriter___init__}, + {0, NULL}, }; +PyType_Spec bufferedwriter_spec = { + .name = "_io.BufferedWriter", + .basicsize = sizeof(buffered), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = bufferedwriter_slots, +}; static PyMethodDef bufferedrwpair_methods[] = { {"read", (PyCFunction)bufferedrwpair_read, METH_VARARGS}, @@ -2567,79 +2591,53 @@ static PyMethodDef bufferedrwpair_methods[] = { {NULL, NULL} }; +static PyMemberDef bufferedrwpair_members[] = { + {"__weaklistoffset__", T_PYSSIZET, offsetof(rwpair, weakreflist), READONLY}, + {"__dictoffset__", T_PYSSIZET, offsetof(rwpair, dict), READONLY}, + {NULL} +}; + static PyGetSetDef bufferedrwpair_getset[] = { {"closed", (getter)bufferedrwpair_closed_get, NULL, NULL}, {NULL} }; -PyTypeObject PyBufferedRWPair_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_io.BufferedRWPair", /*tp_name*/ - sizeof(rwpair), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - (destructor)bufferedrwpair_dealloc, /*tp_dealloc*/ - 0, /*tp_vectorcall_offset*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_as_async*/ - 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 - | Py_TPFLAGS_HAVE_GC, /* tp_flags */ - _io_BufferedRWPair___init____doc__, /* tp_doc */ - (traverseproc)bufferedrwpair_traverse, /* tp_traverse */ - (inquiry)bufferedrwpair_clear, /* tp_clear */ - 0, /* tp_richcompare */ - offsetof(rwpair, weakreflist), /*tp_weaklistoffset*/ - 0, /* tp_iter */ - 0, /* tp_iternext */ - bufferedrwpair_methods, /* tp_methods */ - 0, /* tp_members */ - bufferedrwpair_getset, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - offsetof(rwpair, dict), /* tp_dictoffset */ - _io_BufferedRWPair___init__, /* tp_init */ - 0, /* tp_alloc */ - PyType_GenericNew, /* tp_new */ - 0, /* tp_free */ - 0, /* tp_is_gc */ - 0, /* tp_bases */ - 0, /* tp_mro */ - 0, /* tp_cache */ - 0, /* tp_subclasses */ - 0, /* tp_weaklist */ - 0, /* tp_del */ - 0, /* tp_version_tag */ - 0, /* tp_finalize */ +static PyType_Slot bufferedrwpair_slots[] = { + {Py_tp_dealloc, bufferedrwpair_dealloc}, + {Py_tp_doc, (void *)_io_BufferedRWPair___init____doc__}, + {Py_tp_traverse, bufferedrwpair_traverse}, + {Py_tp_clear, bufferedrwpair_clear}, + {Py_tp_methods, bufferedrwpair_methods}, + {Py_tp_members, bufferedrwpair_members}, + {Py_tp_getset, bufferedrwpair_getset}, + {Py_tp_init, _io_BufferedRWPair___init__}, + {0, NULL}, +}; + +PyType_Spec bufferedrwpair_spec = { + .name = "_io.BufferedRWPair", + .basicsize = sizeof(rwpair), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = bufferedrwpair_slots, }; static PyMethodDef bufferedrandom_methods[] = { /* BufferedIOMixin methods */ - {"close", (PyCFunction)buffered_close, METH_NOARGS}, - {"detach", (PyCFunction)buffered_detach, METH_NOARGS}, - {"seekable", (PyCFunction)buffered_seekable, METH_NOARGS}, - {"readable", (PyCFunction)buffered_readable, METH_NOARGS}, - {"writable", (PyCFunction)buffered_writable, METH_NOARGS}, - {"fileno", (PyCFunction)buffered_fileno, METH_NOARGS}, - {"isatty", (PyCFunction)buffered_isatty, METH_NOARGS}, - {"_dealloc_warn", (PyCFunction)buffered_dealloc_warn, METH_O}, + _IO__BUFFERED_CLOSE_METHODDEF + _IO__BUFFERED_DETACH_METHODDEF + _IO__BUFFERED_SEEKABLE_METHODDEF + _IO__BUFFERED_READABLE_METHODDEF + _IO__BUFFERED_WRITABLE_METHODDEF + _IO__BUFFERED_FILENO_METHODDEF + _IO__BUFFERED_ISATTY_METHODDEF + _IO__BUFFERED__DEALLOC_WARN_METHODDEF - {"flush", (PyCFunction)buffered_flush, METH_NOARGS}, + _IO__BUFFERED_FLUSH_METHODDEF _IO__BUFFERED_SEEK_METHODDEF - {"tell", (PyCFunction)buffered_tell, METH_NOARGS}, + _IO__BUFFERED_TELL_METHODDEF _IO__BUFFERED_TRUNCATE_METHODDEF _IO__BUFFERED_READ_METHODDEF _IO__BUFFERED_READ1_METHODDEF @@ -2648,13 +2646,18 @@ static PyMethodDef bufferedrandom_methods[] = { _IO__BUFFERED_READLINE_METHODDEF _IO__BUFFERED_PEEK_METHODDEF _IO_BUFFEREDWRITER_WRITE_METHODDEF - {"__sizeof__", (PyCFunction)buffered_sizeof, METH_NOARGS}, + _IO__BUFFERED___SIZEOF___METHODDEF + + {"__reduce__", _PyIOBase_cannot_pickle, METH_VARARGS}, + {"__reduce_ex__", _PyIOBase_cannot_pickle, METH_VARARGS}, {NULL, NULL} }; static PyMemberDef bufferedrandom_members[] = { {"raw", T_OBJECT, offsetof(buffered, raw), READONLY}, {"_finalizing", T_BOOL, offsetof(buffered, finalizing), 0}, + {"__weaklistoffset__", T_PYSSIZET, offsetof(buffered, weakreflist), READONLY}, + {"__dictoffset__", T_PYSSIZET, offsetof(buffered, dict), READONLY}, {NULL} }; @@ -2666,54 +2669,24 @@ static PyGetSetDef bufferedrandom_getset[] = { }; -PyTypeObject PyBufferedRandom_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_io.BufferedRandom", /*tp_name*/ - sizeof(buffered), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - (destructor)buffered_dealloc, /*tp_dealloc*/ - 0, /*tp_vectorcall_offset*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_as_async*/ - (reprfunc)buffered_repr, /*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 - | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ - _io_BufferedRandom___init____doc__, /* tp_doc */ - (traverseproc)buffered_traverse, /* tp_traverse */ - (inquiry)buffered_clear, /* tp_clear */ - 0, /* tp_richcompare */ - offsetof(buffered, weakreflist), /*tp_weaklistoffset*/ - 0, /* tp_iter */ - (iternextfunc)buffered_iternext, /* tp_iternext */ - bufferedrandom_methods, /* tp_methods */ - bufferedrandom_members, /* tp_members */ - bufferedrandom_getset, /* tp_getset */ - 0, /* tp_base */ - 0, /*tp_dict*/ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - offsetof(buffered, dict), /*tp_dictoffset*/ - _io_BufferedRandom___init__, /* tp_init */ - 0, /* tp_alloc */ - PyType_GenericNew, /* tp_new */ - 0, /* tp_free */ - 0, /* tp_is_gc */ - 0, /* tp_bases */ - 0, /* tp_mro */ - 0, /* tp_cache */ - 0, /* tp_subclasses */ - 0, /* tp_weaklist */ - 0, /* tp_del */ - 0, /* tp_version_tag */ - 0, /* tp_finalize */ +static PyType_Slot bufferedrandom_slots[] = { + {Py_tp_dealloc, buffered_dealloc}, + {Py_tp_repr, buffered_repr}, + {Py_tp_doc, (void *)_io_BufferedRandom___init____doc__}, + {Py_tp_traverse, buffered_traverse}, + {Py_tp_clear, buffered_clear}, + {Py_tp_iternext, buffered_iternext}, + {Py_tp_methods, bufferedrandom_methods}, + {Py_tp_members, bufferedrandom_members}, + {Py_tp_getset, bufferedrandom_getset}, + {Py_tp_init, _io_BufferedRandom___init__}, + {0, NULL}, +}; + +PyType_Spec bufferedrandom_spec = { + .name = "_io.BufferedRandom", + .basicsize = sizeof(buffered), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = bufferedrandom_slots, }; diff --git a/Modules/_io/bytesio.c b/Modules/_io/bytesio.c index 930ef7e2..80773058 100644 --- a/Modules/_io/bytesio.c +++ b/Modules/_io/bytesio.c @@ -5,9 +5,9 @@ /*[clinic input] module _io -class _io.BytesIO "bytesio *" "&PyBytesIO_Type" +class _io.BytesIO "bytesio *" "clinic_state()->PyBytesIO_Type" [clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=7f50ec034f5c0b26]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=48ede2f330f847c3]*/ typedef struct { PyObject_HEAD @@ -308,14 +308,18 @@ _io_BytesIO_flush_impl(bytesio *self) /*[clinic input] _io.BytesIO.getbuffer + cls: defining_class + / + Get a read-write view over the contents of the BytesIO object. [clinic start generated code]*/ static PyObject * -_io_BytesIO_getbuffer_impl(bytesio *self) -/*[clinic end generated code: output=72cd7c6e13aa09ed input=8f738ef615865176]*/ +_io_BytesIO_getbuffer_impl(bytesio *self, PyTypeObject *cls) +/*[clinic end generated code: output=045091d7ce87fe4e input=0668fbb48f95dffa]*/ { - PyTypeObject *type = &_PyBytesIOBuffer_Type; + _PyIO_State *state = get_io_state_by_cls(cls); + PyTypeObject *type = state->PyBytesIOBuffer_Type; bytesiobuf *buf; PyObject *view; @@ -324,8 +328,7 @@ _io_BytesIO_getbuffer_impl(bytesio *self) buf = (bytesiobuf *) type->tp_alloc(type, 0); if (buf == NULL) return NULL; - Py_INCREF(self); - buf->source = self; + buf->source = (bytesio*)Py_NewRef(self); view = PyMemoryView_FromObject((PyObject *) buf); Py_DECREF(buf); return view; @@ -356,8 +359,7 @@ _io_BytesIO_getvalue_impl(bytesio *self) return NULL; } } - Py_INCREF(self->buf); - return self->buf; + return Py_NewRef(self->buf); } /*[clinic input] @@ -401,8 +403,7 @@ read_bytes(bytesio *self, Py_ssize_t size) self->pos == 0 && size == PyBytes_GET_SIZE(self->buf) && self->exports == 0) { self->pos += size; - Py_INCREF(self->buf); - return self->buf; + return Py_NewRef(self->buf); } output = PyBytes_AS_STRING(self->buf) + self->pos; @@ -791,8 +792,7 @@ bytesio_getstate(bytesio *self, PyObject *Py_UNUSED(ignored)) if (initvalue == NULL) return NULL; if (self->dict == NULL) { - Py_INCREF(Py_None); - dict = Py_None; + dict = Py_NewRef(Py_None); } else { dict = PyDict_Copy(self->dict); @@ -875,8 +875,7 @@ bytesio_setstate(bytesio *self, PyObject *state) return NULL; } else { - Py_INCREF(dict); - self->dict = dict; + self->dict = Py_NewRef(dict); } } @@ -886,6 +885,7 @@ bytesio_setstate(bytesio *self, PyObject *state) static void bytesio_dealloc(bytesio *self) { + PyTypeObject *tp = Py_TYPE(self); _PyObject_GC_UNTRACK(self); if (self->exports > 0) { PyErr_SetString(PyExc_SystemError, @@ -896,7 +896,8 @@ bytesio_dealloc(bytesio *self) Py_CLEAR(self->dict); if (self->weakreflist != NULL) PyObject_ClearWeakRefs((PyObject *) self); - Py_TYPE(self)->tp_free(self); + tp->tp_free(self); + Py_DECREF(tp); } static PyObject * @@ -943,8 +944,7 @@ _io_BytesIO___init___impl(bytesio *self, PyObject *initvalue) } if (initvalue && initvalue != Py_None) { if (PyBytes_CheckExact(initvalue)) { - Py_INCREF(initvalue); - Py_XSETREF(self->buf, initvalue); + Py_XSETREF(self->buf, Py_NewRef(initvalue)); self->string_size = PyBytes_GET_SIZE(initvalue); } else { @@ -963,23 +963,23 @@ _io_BytesIO___init___impl(bytesio *self, PyObject *initvalue) static PyObject * bytesio_sizeof(bytesio *self, void *unused) { - Py_ssize_t res; - - res = _PyObject_SIZE(Py_TYPE(self)); + size_t res = _PyObject_SIZE(Py_TYPE(self)); if (self->buf && !SHARED_BUF(self)) { - Py_ssize_t s = _PySys_GetSizeOf(self->buf); - if (s == -1) { + size_t s = _PySys_GetSizeOf(self->buf); + if (s == (size_t)-1) { return NULL; } res += s; } - return PyLong_FromSsize_t(res); + return PyLong_FromSize_t(res); } static int bytesio_traverse(bytesio *self, visitproc visit, void *arg) { + Py_VISIT(Py_TYPE(self)); Py_VISIT(self->dict); + Py_VISIT(self->buf); return 0; } @@ -987,11 +987,14 @@ static int bytesio_clear(bytesio *self) { Py_CLEAR(self->dict); + Py_CLEAR(self->buf); return 0; } +#define clinic_state() (find_io_state_by_def(Py_TYPE(self))) #include "clinic/bytesio.c.h" +#undef clinic_state static PyGetSetDef bytesio_getsetlist[] = { {"closed", (getter)bytesio_get_closed, NULL, @@ -1024,48 +1027,34 @@ static struct PyMethodDef bytesio_methods[] = { {NULL, NULL} /* sentinel */ }; -PyTypeObject PyBytesIO_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_io.BytesIO", /*tp_name*/ - sizeof(bytesio), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - (destructor)bytesio_dealloc, /*tp_dealloc*/ - 0, /*tp_vectorcall_offset*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_as_async*/ - 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 | - Py_TPFLAGS_HAVE_GC, /*tp_flags*/ - _io_BytesIO___init____doc__, /*tp_doc*/ - (traverseproc)bytesio_traverse, /*tp_traverse*/ - (inquiry)bytesio_clear, /*tp_clear*/ - 0, /*tp_richcompare*/ - offsetof(bytesio, weakreflist), /*tp_weaklistoffset*/ - PyObject_SelfIter, /*tp_iter*/ - (iternextfunc)bytesio_iternext, /*tp_iternext*/ - bytesio_methods, /*tp_methods*/ - 0, /*tp_members*/ - bytesio_getsetlist, /*tp_getset*/ - 0, /*tp_base*/ - 0, /*tp_dict*/ - 0, /*tp_descr_get*/ - 0, /*tp_descr_set*/ - offsetof(bytesio, dict), /*tp_dictoffset*/ - _io_BytesIO___init__, /*tp_init*/ - 0, /*tp_alloc*/ - bytesio_new, /*tp_new*/ +static PyMemberDef bytesio_members[] = { + {"__weaklistoffset__", T_PYSSIZET, offsetof(bytesio, weakreflist), READONLY}, + {"__dictoffset__", T_PYSSIZET, offsetof(bytesio, dict), READONLY}, + {NULL} }; +static PyType_Slot bytesio_slots[] = { + {Py_tp_dealloc, bytesio_dealloc}, + {Py_tp_doc, (void *)_io_BytesIO___init____doc__}, + {Py_tp_traverse, bytesio_traverse}, + {Py_tp_clear, bytesio_clear}, + {Py_tp_iter, PyObject_SelfIter}, + {Py_tp_iternext, bytesio_iternext}, + {Py_tp_methods, bytesio_methods}, + {Py_tp_members, bytesio_members}, + {Py_tp_getset, bytesio_getsetlist}, + {Py_tp_init, _io_BytesIO___init__}, + {Py_tp_new, bytesio_new}, + {0, NULL}, +}; + +PyType_Spec bytesio_spec = { + .name = "_io.BytesIO", + .basicsize = sizeof(bytesio), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = bytesio_slots, +}; /* * Implementation of the small intermediate object used by getbuffer(). @@ -1103,9 +1092,17 @@ bytesiobuf_releasebuffer(bytesiobuf *obj, Py_buffer *view) b->exports--; } +static int +bytesiobuf_clear(bytesiobuf *self) +{ + Py_CLEAR(self->source); + return 0; +} + static int bytesiobuf_traverse(bytesiobuf *self, visitproc visit, void *arg) { + Py_VISIT(Py_TYPE(self)); Py_VISIT(self->source); return 0; } @@ -1113,54 +1110,29 @@ bytesiobuf_traverse(bytesiobuf *self, visitproc visit, void *arg) static void bytesiobuf_dealloc(bytesiobuf *self) { + PyTypeObject *tp = Py_TYPE(self); /* bpo-31095: UnTrack is needed before calling any callbacks */ PyObject_GC_UnTrack(self); - Py_CLEAR(self->source); - Py_TYPE(self)->tp_free(self); + (void)bytesiobuf_clear(self); + tp->tp_free(self); + Py_DECREF(tp); } -static PyBufferProcs bytesiobuf_as_buffer = { - (getbufferproc) bytesiobuf_getbuffer, - (releasebufferproc) bytesiobuf_releasebuffer, +static PyType_Slot bytesiobuf_slots[] = { + {Py_tp_dealloc, bytesiobuf_dealloc}, + {Py_tp_traverse, bytesiobuf_traverse}, + {Py_tp_clear, bytesiobuf_clear}, + + // Buffer protocol + {Py_bf_getbuffer, bytesiobuf_getbuffer}, + {Py_bf_releasebuffer, bytesiobuf_releasebuffer}, + {0, NULL}, }; -Py_EXPORTED_SYMBOL PyTypeObject _PyBytesIOBuffer_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_io._BytesIOBuffer", /*tp_name*/ - sizeof(bytesiobuf), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - (destructor)bytesiobuf_dealloc, /*tp_dealloc*/ - 0, /*tp_vectorcall_offset*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_as_async*/ - 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*/ - &bytesiobuf_as_buffer, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ - 0, /*tp_doc*/ - (traverseproc)bytesiobuf_traverse, /*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*/ - 0, /*tp_init*/ - 0, /*tp_alloc*/ - 0, /*tp_new*/ +PyType_Spec bytesiobuf_spec = { + .name = "_io._BytesIOBuffer", + .basicsize = sizeof(bytesiobuf), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_DISALLOW_INSTANTIATION), + .slots = bytesiobuf_slots, }; diff --git a/Modules/_io/clinic/_iomodule.c.h b/Modules/_io/clinic/_iomodule.c.h index 0249dd18..4d76e333 100644 --- a/Modules/_io/clinic/_iomodule.c.h +++ b/Modules/_io/clinic/_iomodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_io_open__doc__, "open($module, /, file, mode=\'r\', buffering=-1, encoding=None,\n" " errors=None, newline=None, closefd=True, opener=None)\n" @@ -133,8 +139,31 @@ static PyObject * _io_open(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 8 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(file), &_Py_ID(mode), &_Py_ID(buffering), &_Py_ID(encoding), &_Py_ID(errors), &_Py_ID(newline), &_Py_ID(closefd), &_Py_ID(opener), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"file", "mode", "buffering", "encoding", "errors", "newline", "closefd", "opener", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "open", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "open", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[8]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *file; @@ -251,8 +280,8 @@ _io_open(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw } } if (args[6]) { - closefd = _PyLong_AsInt(args[6]); - if (closefd == -1 && PyErr_Occurred()) { + closefd = PyObject_IsTrue(args[6]); + if (closefd < 0) { goto exit; } if (!--noptargs) { @@ -333,8 +362,31 @@ static PyObject * _io_open_code(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "open_code", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "open_code", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *path; @@ -355,4 +407,4 @@ _io_open_code(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec exit: return return_value; } -/*[clinic end generated code: output=c4d7e4ef878985f8 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=f387eba3f4c0254a input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/bufferedio.c.h b/Modules/_io/clinic/bufferedio.c.h index 37004512..4f40fdad 100644 --- a/Modules/_io/clinic/bufferedio.c.h +++ b/Modules/_io/clinic/bufferedio.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_io__BufferedIOBase_readinto__doc__, "readinto($self, buffer, /)\n" "--\n" @@ -86,15 +92,367 @@ PyDoc_STRVAR(_io__BufferedIOBase_detach__doc__, "state."); #define _IO__BUFFEREDIOBASE_DETACH_METHODDEF \ - {"detach", (PyCFunction)_io__BufferedIOBase_detach, METH_NOARGS, _io__BufferedIOBase_detach__doc__}, + {"detach", _PyCFunction_CAST(_io__BufferedIOBase_detach), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _io__BufferedIOBase_detach__doc__}, + +static PyObject * +_io__BufferedIOBase_detach_impl(PyObject *self, PyTypeObject *cls); + +static PyObject * +_io__BufferedIOBase_detach(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + if (nargs) { + PyErr_SetString(PyExc_TypeError, "detach() takes no arguments"); + return NULL; + } + return _io__BufferedIOBase_detach_impl(self, cls); +} + +PyDoc_STRVAR(_io__BufferedIOBase_read__doc__, +"read($self, size=-1, /)\n" +"--\n" +"\n" +"Read and return up to n bytes.\n" +"\n" +"If the size argument is omitted, None, or negative, read and\n" +"return all data until EOF.\n" +"\n" +"If the size argument is positive, and the underlying raw stream is\n" +"not \'interactive\', multiple raw reads may be issued to satisfy\n" +"the byte count (unless EOF is reached first).\n" +"However, for interactive raw streams (as well as sockets and pipes),\n" +"at most one raw read will be issued, and a short result does not\n" +"imply that EOF is imminent.\n" +"\n" +"Return an empty bytes object on EOF.\n" +"\n" +"Return None if the underlying raw stream was open in non-blocking\n" +"mode and no data is available at the moment."); + +#define _IO__BUFFEREDIOBASE_READ_METHODDEF \ + {"read", _PyCFunction_CAST(_io__BufferedIOBase_read), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _io__BufferedIOBase_read__doc__}, + +static PyObject * +_io__BufferedIOBase_read_impl(PyObject *self, PyTypeObject *cls, + int Py_UNUSED(size)); + +static PyObject * +_io__BufferedIOBase_read(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + + static const char * const _keywords[] = {"", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "read", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + int size = -1; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (nargs < 1) { + goto skip_optional_posonly; + } + size = _PyLong_AsInt(args[0]); + if (size == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional_posonly: + return_value = _io__BufferedIOBase_read_impl(self, cls, size); + +exit: + return return_value; +} + +PyDoc_STRVAR(_io__BufferedIOBase_read1__doc__, +"read1($self, size=-1, /)\n" +"--\n" +"\n" +"Read and return up to size bytes, with at most one read() call to the underlying raw stream.\n" +"\n" +"Return an empty bytes object on EOF.\n" +"A short result does not imply that EOF is imminent."); + +#define _IO__BUFFEREDIOBASE_READ1_METHODDEF \ + {"read1", _PyCFunction_CAST(_io__BufferedIOBase_read1), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _io__BufferedIOBase_read1__doc__}, + +static PyObject * +_io__BufferedIOBase_read1_impl(PyObject *self, PyTypeObject *cls, + int Py_UNUSED(size)); + +static PyObject * +_io__BufferedIOBase_read1(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + + static const char * const _keywords[] = {"", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "read1", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + int size = -1; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (nargs < 1) { + goto skip_optional_posonly; + } + size = _PyLong_AsInt(args[0]); + if (size == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional_posonly: + return_value = _io__BufferedIOBase_read1_impl(self, cls, size); + +exit: + return return_value; +} + +PyDoc_STRVAR(_io__BufferedIOBase_write__doc__, +"write($self, b, /)\n" +"--\n" +"\n" +"Write buffer b to the IO stream.\n" +"\n" +"Return the number of bytes written, which is always\n" +"the length of b in bytes.\n" +"\n" +"Raise BlockingIOError if the buffer is full and the\n" +"underlying raw stream cannot accept more data at the moment."); + +#define _IO__BUFFEREDIOBASE_WRITE_METHODDEF \ + {"write", _PyCFunction_CAST(_io__BufferedIOBase_write), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _io__BufferedIOBase_write__doc__}, + +static PyObject * +_io__BufferedIOBase_write_impl(PyObject *self, PyTypeObject *cls, + PyObject *Py_UNUSED(b)); + +static PyObject * +_io__BufferedIOBase_write(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + + static const char * const _keywords[] = {"", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "write", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject *b; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + b = args[0]; + return_value = _io__BufferedIOBase_write_impl(self, cls, b); + +exit: + return return_value; +} + +PyDoc_STRVAR(_io__Buffered___sizeof____doc__, +"__sizeof__($self, /)\n" +"--\n" +"\n"); + +#define _IO__BUFFERED___SIZEOF___METHODDEF \ + {"__sizeof__", (PyCFunction)_io__Buffered___sizeof__, METH_NOARGS, _io__Buffered___sizeof____doc__}, + +static PyObject * +_io__Buffered___sizeof___impl(buffered *self); + +static PyObject * +_io__Buffered___sizeof__(buffered *self, PyObject *Py_UNUSED(ignored)) +{ + return _io__Buffered___sizeof___impl(self); +} + +PyDoc_STRVAR(_io__Buffered__dealloc_warn__doc__, +"_dealloc_warn($self, source, /)\n" +"--\n" +"\n"); + +#define _IO__BUFFERED__DEALLOC_WARN_METHODDEF \ + {"_dealloc_warn", (PyCFunction)_io__Buffered__dealloc_warn, METH_O, _io__Buffered__dealloc_warn__doc__}, + +PyDoc_STRVAR(_io__Buffered_simple_flush__doc__, +"flush($self, /)\n" +"--\n" +"\n"); + +#define _IO__BUFFERED_SIMPLE_FLUSH_METHODDEF \ + {"flush", (PyCFunction)_io__Buffered_simple_flush, METH_NOARGS, _io__Buffered_simple_flush__doc__}, + +static PyObject * +_io__Buffered_simple_flush_impl(buffered *self); static PyObject * -_io__BufferedIOBase_detach_impl(PyObject *self); +_io__Buffered_simple_flush(buffered *self, PyObject *Py_UNUSED(ignored)) +{ + return _io__Buffered_simple_flush_impl(self); +} + +PyDoc_STRVAR(_io__Buffered_close__doc__, +"close($self, /)\n" +"--\n" +"\n"); + +#define _IO__BUFFERED_CLOSE_METHODDEF \ + {"close", (PyCFunction)_io__Buffered_close, METH_NOARGS, _io__Buffered_close__doc__}, + +static PyObject * +_io__Buffered_close_impl(buffered *self); + +static PyObject * +_io__Buffered_close(buffered *self, PyObject *Py_UNUSED(ignored)) +{ + return _io__Buffered_close_impl(self); +} + +PyDoc_STRVAR(_io__Buffered_detach__doc__, +"detach($self, /)\n" +"--\n" +"\n"); + +#define _IO__BUFFERED_DETACH_METHODDEF \ + {"detach", (PyCFunction)_io__Buffered_detach, METH_NOARGS, _io__Buffered_detach__doc__}, + +static PyObject * +_io__Buffered_detach_impl(buffered *self); + +static PyObject * +_io__Buffered_detach(buffered *self, PyObject *Py_UNUSED(ignored)) +{ + return _io__Buffered_detach_impl(self); +} + +PyDoc_STRVAR(_io__Buffered_seekable__doc__, +"seekable($self, /)\n" +"--\n" +"\n"); + +#define _IO__BUFFERED_SEEKABLE_METHODDEF \ + {"seekable", (PyCFunction)_io__Buffered_seekable, METH_NOARGS, _io__Buffered_seekable__doc__}, + +static PyObject * +_io__Buffered_seekable_impl(buffered *self); + +static PyObject * +_io__Buffered_seekable(buffered *self, PyObject *Py_UNUSED(ignored)) +{ + return _io__Buffered_seekable_impl(self); +} + +PyDoc_STRVAR(_io__Buffered_readable__doc__, +"readable($self, /)\n" +"--\n" +"\n"); + +#define _IO__BUFFERED_READABLE_METHODDEF \ + {"readable", (PyCFunction)_io__Buffered_readable, METH_NOARGS, _io__Buffered_readable__doc__}, + +static PyObject * +_io__Buffered_readable_impl(buffered *self); + +static PyObject * +_io__Buffered_readable(buffered *self, PyObject *Py_UNUSED(ignored)) +{ + return _io__Buffered_readable_impl(self); +} + +PyDoc_STRVAR(_io__Buffered_writable__doc__, +"writable($self, /)\n" +"--\n" +"\n"); + +#define _IO__BUFFERED_WRITABLE_METHODDEF \ + {"writable", (PyCFunction)_io__Buffered_writable, METH_NOARGS, _io__Buffered_writable__doc__}, static PyObject * -_io__BufferedIOBase_detach(PyObject *self, PyObject *Py_UNUSED(ignored)) +_io__Buffered_writable_impl(buffered *self); + +static PyObject * +_io__Buffered_writable(buffered *self, PyObject *Py_UNUSED(ignored)) +{ + return _io__Buffered_writable_impl(self); +} + +PyDoc_STRVAR(_io__Buffered_fileno__doc__, +"fileno($self, /)\n" +"--\n" +"\n"); + +#define _IO__BUFFERED_FILENO_METHODDEF \ + {"fileno", (PyCFunction)_io__Buffered_fileno, METH_NOARGS, _io__Buffered_fileno__doc__}, + +static PyObject * +_io__Buffered_fileno_impl(buffered *self); + +static PyObject * +_io__Buffered_fileno(buffered *self, PyObject *Py_UNUSED(ignored)) { - return _io__BufferedIOBase_detach_impl(self); + return _io__Buffered_fileno_impl(self); +} + +PyDoc_STRVAR(_io__Buffered_isatty__doc__, +"isatty($self, /)\n" +"--\n" +"\n"); + +#define _IO__BUFFERED_ISATTY_METHODDEF \ + {"isatty", (PyCFunction)_io__Buffered_isatty, METH_NOARGS, _io__Buffered_isatty__doc__}, + +static PyObject * +_io__Buffered_isatty_impl(buffered *self); + +static PyObject * +_io__Buffered_isatty(buffered *self, PyObject *Py_UNUSED(ignored)) +{ + return _io__Buffered_isatty_impl(self); +} + +PyDoc_STRVAR(_io__Buffered_flush__doc__, +"flush($self, /)\n" +"--\n" +"\n"); + +#define _IO__BUFFERED_FLUSH_METHODDEF \ + {"flush", (PyCFunction)_io__Buffered_flush, METH_NOARGS, _io__Buffered_flush__doc__}, + +static PyObject * +_io__Buffered_flush_impl(buffered *self); + +static PyObject * +_io__Buffered_flush(buffered *self, PyObject *Py_UNUSED(ignored)) +{ + return _io__Buffered_flush_impl(self); } PyDoc_STRVAR(_io__Buffered_peek__doc__, @@ -321,6 +679,23 @@ exit: return return_value; } +PyDoc_STRVAR(_io__Buffered_tell__doc__, +"tell($self, /)\n" +"--\n" +"\n"); + +#define _IO__BUFFERED_TELL_METHODDEF \ + {"tell", (PyCFunction)_io__Buffered_tell, METH_NOARGS, _io__Buffered_tell__doc__}, + +static PyObject * +_io__Buffered_tell_impl(buffered *self); + +static PyObject * +_io__Buffered_tell(buffered *self, PyObject *Py_UNUSED(ignored)) +{ + return _io__Buffered_tell_impl(self); +} + PyDoc_STRVAR(_io__Buffered_seek__doc__, "seek($self, target, whence=0, /)\n" "--\n" @@ -363,26 +738,41 @@ PyDoc_STRVAR(_io__Buffered_truncate__doc__, "\n"); #define _IO__BUFFERED_TRUNCATE_METHODDEF \ - {"truncate", _PyCFunction_CAST(_io__Buffered_truncate), METH_FASTCALL, _io__Buffered_truncate__doc__}, + {"truncate", _PyCFunction_CAST(_io__Buffered_truncate), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _io__Buffered_truncate__doc__}, static PyObject * -_io__Buffered_truncate_impl(buffered *self, PyObject *pos); +_io__Buffered_truncate_impl(buffered *self, PyTypeObject *cls, PyObject *pos); static PyObject * -_io__Buffered_truncate(buffered *self, PyObject *const *args, Py_ssize_t nargs) +_io__Buffered_truncate(buffered *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + + static const char * const _keywords[] = {"", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "truncate", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; PyObject *pos = Py_None; - if (!_PyArg_CheckPositional("truncate", nargs, 0, 1)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { goto exit; } if (nargs < 1) { - goto skip_optional; + goto skip_optional_posonly; } pos = args[0]; -skip_optional: - return_value = _io__Buffered_truncate_impl(self, pos); +skip_optional_posonly: + return_value = _io__Buffered_truncate_impl(self, cls, pos); exit: return return_value; @@ -402,8 +792,31 @@ static int _io_BufferedReader___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(raw), &_Py_ID(buffer_size), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"raw", "buffer_size", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "BufferedReader", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "BufferedReader", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -456,8 +869,31 @@ static int _io_BufferedWriter___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(raw), &_Py_ID(buffer_size), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"raw", "buffer_size", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "BufferedWriter", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "BufferedWriter", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -549,12 +985,13 @@ static int _io_BufferedRWPair___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; + PyTypeObject *base_tp = clinic_state()->PyBufferedRWPair_Type; PyObject *reader; PyObject *writer; Py_ssize_t buffer_size = DEFAULT_BUFFER_SIZE; - if ((Py_IS_TYPE(self, &PyBufferedRWPair_Type) || - Py_TYPE(self)->tp_new == PyBufferedRWPair_Type.tp_new) && + if ((Py_IS_TYPE(self, base_tp) || + Py_TYPE(self)->tp_new == base_tp->tp_new) && !_PyArg_NoKeywords("BufferedRWPair", kwargs)) { goto exit; } @@ -603,8 +1040,31 @@ static int _io_BufferedRandom___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(raw), &_Py_ID(buffer_size), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"raw", "buffer_size", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "BufferedRandom", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "BufferedRandom", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -638,4 +1098,4 @@ skip_optional_pos: exit: return return_value; } -/*[clinic end generated code: output=820461c6b0e29e48 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=b7ddf84a5bc2bf34 input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/bytesio.c.h b/Modules/_io/clinic/bytesio.c.h index 049d3473..9550c872 100644 --- a/Modules/_io/clinic/bytesio.c.h +++ b/Modules/_io/clinic/bytesio.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_io_BytesIO_readable__doc__, "readable($self, /)\n" "--\n" @@ -81,15 +87,19 @@ PyDoc_STRVAR(_io_BytesIO_getbuffer__doc__, "Get a read-write view over the contents of the BytesIO object."); #define _IO_BYTESIO_GETBUFFER_METHODDEF \ - {"getbuffer", (PyCFunction)_io_BytesIO_getbuffer, METH_NOARGS, _io_BytesIO_getbuffer__doc__}, + {"getbuffer", _PyCFunction_CAST(_io_BytesIO_getbuffer), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _io_BytesIO_getbuffer__doc__}, static PyObject * -_io_BytesIO_getbuffer_impl(bytesio *self); +_io_BytesIO_getbuffer_impl(bytesio *self, PyTypeObject *cls); static PyObject * -_io_BytesIO_getbuffer(bytesio *self, PyObject *Py_UNUSED(ignored)) +_io_BytesIO_getbuffer(bytesio *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - return _io_BytesIO_getbuffer_impl(self); + if (nargs) { + PyErr_SetString(PyExc_TypeError, "getbuffer() takes no arguments"); + return NULL; + } + return _io_BytesIO_getbuffer_impl(self, cls); } PyDoc_STRVAR(_io_BytesIO_getvalue__doc__, @@ -483,8 +493,31 @@ static int _io_BytesIO___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(initial_bytes), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"initial_bytes", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "BytesIO", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "BytesIO", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -505,4 +538,4 @@ skip_optional_pos: exit: return return_value; } -/*[clinic end generated code: output=93d9700a6cf395b8 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=098584d485420b65 input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/fileio.c.h b/Modules/_io/clinic/fileio.c.h index bb0b36c8..33a37a38 100644 --- a/Modules/_io/clinic/fileio.c.h +++ b/Modules/_io/clinic/fileio.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_io_FileIO_close__doc__, "close($self, /)\n" "--\n" @@ -12,15 +18,19 @@ PyDoc_STRVAR(_io_FileIO_close__doc__, "called more than once without error."); #define _IO_FILEIO_CLOSE_METHODDEF \ - {"close", (PyCFunction)_io_FileIO_close, METH_NOARGS, _io_FileIO_close__doc__}, + {"close", _PyCFunction_CAST(_io_FileIO_close), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _io_FileIO_close__doc__}, static PyObject * -_io_FileIO_close_impl(fileio *self); +_io_FileIO_close_impl(fileio *self, PyTypeObject *cls); static PyObject * -_io_FileIO_close(fileio *self, PyObject *Py_UNUSED(ignored)) +_io_FileIO_close(fileio *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - return _io_FileIO_close_impl(self); + if (nargs) { + PyErr_SetString(PyExc_TypeError, "close() takes no arguments"); + return NULL; + } + return _io_FileIO_close_impl(self, cls); } PyDoc_STRVAR(_io_FileIO___init____doc__, @@ -49,8 +59,31 @@ static int _io_FileIO___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(file), &_Py_ID(mode), &_Py_ID(closefd), &_Py_ID(opener), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"file", "mode", "closefd", "opener", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "FileIO", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "FileIO", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -87,8 +120,8 @@ _io_FileIO___init__(PyObject *self, PyObject *args, PyObject *kwargs) } } if (fastargs[2]) { - closefd = _PyLong_AsInt(fastargs[2]); - if (closefd == -1 && PyErr_Occurred()) { + closefd = PyObject_IsTrue(fastargs[2]); + if (closefd < 0) { goto exit; } if (!--noptargs) { @@ -182,27 +215,45 @@ PyDoc_STRVAR(_io_FileIO_readinto__doc__, "Same as RawIOBase.readinto()."); #define _IO_FILEIO_READINTO_METHODDEF \ - {"readinto", (PyCFunction)_io_FileIO_readinto, METH_O, _io_FileIO_readinto__doc__}, + {"readinto", _PyCFunction_CAST(_io_FileIO_readinto), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _io_FileIO_readinto__doc__}, static PyObject * -_io_FileIO_readinto_impl(fileio *self, Py_buffer *buffer); +_io_FileIO_readinto_impl(fileio *self, PyTypeObject *cls, Py_buffer *buffer); static PyObject * -_io_FileIO_readinto(fileio *self, PyObject *arg) +_io_FileIO_readinto(fileio *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + + static const char * const _keywords[] = {"", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "readinto", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; Py_buffer buffer = {NULL, NULL}; - if (PyObject_GetBuffer(arg, &buffer, PyBUF_WRITABLE) < 0) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &buffer, PyBUF_WRITABLE) < 0) { PyErr_Clear(); - _PyArg_BadArgument("readinto", "argument", "read-write bytes-like object", arg); + _PyArg_BadArgument("readinto", "argument 1", "read-write bytes-like object", args[0]); goto exit; } if (!PyBuffer_IsContiguous(&buffer, 'C')) { - _PyArg_BadArgument("readinto", "argument", "contiguous buffer", arg); + _PyArg_BadArgument("readinto", "argument 1", "contiguous buffer", args[0]); goto exit; } - return_value = _io_FileIO_readinto_impl(self, &buffer); + return_value = _io_FileIO_readinto_impl(self, cls, &buffer); exit: /* Cleanup for buffer */ @@ -245,28 +296,43 @@ PyDoc_STRVAR(_io_FileIO_read__doc__, "Return an empty bytes object at EOF."); #define _IO_FILEIO_READ_METHODDEF \ - {"read", _PyCFunction_CAST(_io_FileIO_read), METH_FASTCALL, _io_FileIO_read__doc__}, + {"read", _PyCFunction_CAST(_io_FileIO_read), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _io_FileIO_read__doc__}, static PyObject * -_io_FileIO_read_impl(fileio *self, Py_ssize_t size); +_io_FileIO_read_impl(fileio *self, PyTypeObject *cls, Py_ssize_t size); static PyObject * -_io_FileIO_read(fileio *self, PyObject *const *args, Py_ssize_t nargs) +_io_FileIO_read(fileio *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + + static const char * const _keywords[] = {"", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "read", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; Py_ssize_t size = -1; - if (!_PyArg_CheckPositional("read", nargs, 0, 1)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { goto exit; } if (nargs < 1) { - goto skip_optional; + goto skip_optional_posonly; } if (!_Py_convert_optional_to_ssize_t(args[0], &size)) { goto exit; } -skip_optional: - return_value = _io_FileIO_read_impl(self, size); +skip_optional_posonly: + return_value = _io_FileIO_read_impl(self, cls, size); exit: return return_value; @@ -283,25 +349,43 @@ PyDoc_STRVAR(_io_FileIO_write__doc__, "returns None if the write would block."); #define _IO_FILEIO_WRITE_METHODDEF \ - {"write", (PyCFunction)_io_FileIO_write, METH_O, _io_FileIO_write__doc__}, + {"write", _PyCFunction_CAST(_io_FileIO_write), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _io_FileIO_write__doc__}, static PyObject * -_io_FileIO_write_impl(fileio *self, Py_buffer *b); +_io_FileIO_write_impl(fileio *self, PyTypeObject *cls, Py_buffer *b); static PyObject * -_io_FileIO_write(fileio *self, PyObject *arg) +_io_FileIO_write(fileio *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + + static const char * const _keywords[] = {"", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "write", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; Py_buffer b = {NULL, NULL}; - if (PyObject_GetBuffer(arg, &b, PyBUF_SIMPLE) != 0) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &b, PyBUF_SIMPLE) != 0) { goto exit; } if (!PyBuffer_IsContiguous(&b, 'C')) { - _PyArg_BadArgument("write", "argument", "contiguous buffer", arg); + _PyArg_BadArgument("write", "argument 1", "contiguous buffer", args[0]); goto exit; } - return_value = _io_FileIO_write_impl(self, &b); + return_value = _io_FileIO_write_impl(self, cls, &b); exit: /* Cleanup for b */ @@ -389,26 +473,41 @@ PyDoc_STRVAR(_io_FileIO_truncate__doc__, "The current file position is changed to the value of size."); #define _IO_FILEIO_TRUNCATE_METHODDEF \ - {"truncate", _PyCFunction_CAST(_io_FileIO_truncate), METH_FASTCALL, _io_FileIO_truncate__doc__}, + {"truncate", _PyCFunction_CAST(_io_FileIO_truncate), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _io_FileIO_truncate__doc__}, static PyObject * -_io_FileIO_truncate_impl(fileio *self, PyObject *posobj); +_io_FileIO_truncate_impl(fileio *self, PyTypeObject *cls, PyObject *posobj); static PyObject * -_io_FileIO_truncate(fileio *self, PyObject *const *args, Py_ssize_t nargs) +_io_FileIO_truncate(fileio *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + + static const char * const _keywords[] = {"", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "truncate", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; PyObject *posobj = Py_None; - if (!_PyArg_CheckPositional("truncate", nargs, 0, 1)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { goto exit; } if (nargs < 1) { - goto skip_optional; + goto skip_optional_posonly; } posobj = args[0]; -skip_optional: - return_value = _io_FileIO_truncate_impl(self, posobj); +skip_optional_posonly: + return_value = _io_FileIO_truncate_impl(self, cls, posobj); exit: return return_value; @@ -437,4 +536,4 @@ _io_FileIO_isatty(fileio *self, PyObject *Py_UNUSED(ignored)) #ifndef _IO_FILEIO_TRUNCATE_METHODDEF #define _IO_FILEIO_TRUNCATE_METHODDEF #endif /* !defined(_IO_FILEIO_TRUNCATE_METHODDEF) */ -/*[clinic end generated code: output=fdcf0f9277d44415 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=bef47b31b644996a input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/iobase.c.h b/Modules/_io/clinic/iobase.c.h index ed3fdc9b..e29a4f18 100644 --- a/Modules/_io/clinic/iobase.c.h +++ b/Modules/_io/clinic/iobase.c.h @@ -2,6 +2,82 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + +PyDoc_STRVAR(_io__IOBase_seek__doc__, +"seek($self, offset, whence=os.SEEK_SET, /)\n" +"--\n" +"\n" +"Change the stream position to the given byte offset.\n" +"\n" +" offset\n" +" The stream position, relative to \'whence\'.\n" +" whence\n" +" The relative position to seek from.\n" +"\n" +"The offset is interpreted relative to the position indicated by whence.\n" +"Values for whence are:\n" +"\n" +"* os.SEEK_SET or 0 -- start of stream (the default); offset should be zero or positive\n" +"* os.SEEK_CUR or 1 -- current stream position; offset may be negative\n" +"* os.SEEK_END or 2 -- end of stream; offset is usually negative\n" +"\n" +"Return the new absolute position."); + +#define _IO__IOBASE_SEEK_METHODDEF \ + {"seek", _PyCFunction_CAST(_io__IOBase_seek), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _io__IOBase_seek__doc__}, + +static PyObject * +_io__IOBase_seek_impl(PyObject *self, PyTypeObject *cls, + int Py_UNUSED(offset), int Py_UNUSED(whence)); + +static PyObject * +_io__IOBase_seek(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + + static const char * const _keywords[] = {"", "", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "seek", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + int offset; + int whence = 0; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); + if (!args) { + goto exit; + } + offset = _PyLong_AsInt(args[0]); + if (offset == -1 && PyErr_Occurred()) { + goto exit; + } + if (nargs < 2) { + goto skip_optional_posonly; + } + whence = _PyLong_AsInt(args[1]); + if (whence == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional_posonly: + return_value = _io__IOBase_seek_impl(self, cls, offset, whence); + +exit: + return return_value; +} + PyDoc_STRVAR(_io__IOBase_tell__doc__, "tell($self, /)\n" "--\n" @@ -20,6 +96,57 @@ _io__IOBase_tell(PyObject *self, PyObject *Py_UNUSED(ignored)) return _io__IOBase_tell_impl(self); } +PyDoc_STRVAR(_io__IOBase_truncate__doc__, +"truncate($self, size=None, /)\n" +"--\n" +"\n" +"Truncate file to size bytes.\n" +"\n" +"File pointer is left unchanged. Size defaults to the current IO position\n" +"as reported by tell(). Return the new size."); + +#define _IO__IOBASE_TRUNCATE_METHODDEF \ + {"truncate", _PyCFunction_CAST(_io__IOBase_truncate), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _io__IOBase_truncate__doc__}, + +static PyObject * +_io__IOBase_truncate_impl(PyObject *self, PyTypeObject *cls, + PyObject *Py_UNUSED(size)); + +static PyObject * +_io__IOBase_truncate(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + + static const char * const _keywords[] = {"", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "truncate", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject *size = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (nargs < 1) { + goto skip_optional_posonly; + } + size = args[0]; +skip_optional_posonly: + return_value = _io__IOBase_truncate_impl(self, cls, size); + +exit: + return return_value; +} + PyDoc_STRVAR(_io__IOBase_flush__doc__, "flush($self, /)\n" "--\n" @@ -125,20 +252,24 @@ PyDoc_STRVAR(_io__IOBase_fileno__doc__, "fileno($self, /)\n" "--\n" "\n" -"Returns underlying file descriptor if one exists.\n" +"Return underlying file descriptor if one exists.\n" "\n" -"OSError is raised if the IO object does not use a file descriptor."); +"Raise OSError if the IO object does not use a file descriptor."); #define _IO__IOBASE_FILENO_METHODDEF \ - {"fileno", (PyCFunction)_io__IOBase_fileno, METH_NOARGS, _io__IOBase_fileno__doc__}, + {"fileno", _PyCFunction_CAST(_io__IOBase_fileno), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _io__IOBase_fileno__doc__}, static PyObject * -_io__IOBase_fileno_impl(PyObject *self); +_io__IOBase_fileno_impl(PyObject *self, PyTypeObject *cls); static PyObject * -_io__IOBase_fileno(PyObject *self, PyObject *Py_UNUSED(ignored)) +_io__IOBase_fileno(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - return _io__IOBase_fileno_impl(self); + if (nargs) { + PyErr_SetString(PyExc_TypeError, "fileno() takes no arguments"); + return NULL; + } + return _io__IOBase_fileno_impl(self, cls); } PyDoc_STRVAR(_io__IOBase_isatty__doc__, @@ -310,4 +441,4 @@ _io__RawIOBase_readall(PyObject *self, PyObject *Py_UNUSED(ignored)) { return _io__RawIOBase_readall_impl(self); } -/*[clinic end generated code: output=0362e134da2d8641 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=7c2df7a330be8b5b input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/stringio.c.h b/Modules/_io/clinic/stringio.c.h index 6758ee05..d495dd10 100644 --- a/Modules/_io/clinic/stringio.c.h +++ b/Modules/_io/clinic/stringio.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_io_StringIO_getvalue__doc__, "getvalue($self, /)\n" "--\n" @@ -255,8 +261,31 @@ static int _io_StringIO___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(initial_value), &_Py_ID(newline), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"initial_value", "newline", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "StringIO", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "StringIO", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -338,4 +367,4 @@ _io_StringIO_seekable(stringio *self, PyObject *Py_UNUSED(ignored)) { return _io_StringIO_seekable_impl(self); } -/*[clinic end generated code: output=3207dc548c305ad8 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=533f20ae9b773126 input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/textio.c.h b/Modules/_io/clinic/textio.c.h index 907785b2..4a3c1330 100644 --- a/Modules/_io/clinic/textio.c.h +++ b/Modules/_io/clinic/textio.c.h @@ -2,6 +2,203 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + +PyDoc_STRVAR(_io__TextIOBase_detach__doc__, +"detach($self, /)\n" +"--\n" +"\n" +"Separate the underlying buffer from the TextIOBase and return it.\n" +"\n" +"After the underlying buffer has been detached, the TextIO is in an unusable state."); + +#define _IO__TEXTIOBASE_DETACH_METHODDEF \ + {"detach", _PyCFunction_CAST(_io__TextIOBase_detach), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _io__TextIOBase_detach__doc__}, + +static PyObject * +_io__TextIOBase_detach_impl(PyObject *self, PyTypeObject *cls); + +static PyObject * +_io__TextIOBase_detach(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + if (nargs) { + PyErr_SetString(PyExc_TypeError, "detach() takes no arguments"); + return NULL; + } + return _io__TextIOBase_detach_impl(self, cls); +} + +PyDoc_STRVAR(_io__TextIOBase_read__doc__, +"read($self, size=-1, /)\n" +"--\n" +"\n" +"Read at most size characters from stream.\n" +"\n" +"Read from underlying buffer until we have size characters or we hit EOF.\n" +"If size is negative or omitted, read until EOF."); + +#define _IO__TEXTIOBASE_READ_METHODDEF \ + {"read", _PyCFunction_CAST(_io__TextIOBase_read), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _io__TextIOBase_read__doc__}, + +static PyObject * +_io__TextIOBase_read_impl(PyObject *self, PyTypeObject *cls, + int Py_UNUSED(size)); + +static PyObject * +_io__TextIOBase_read(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + + static const char * const _keywords[] = {"", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "read", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + int size = -1; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (nargs < 1) { + goto skip_optional_posonly; + } + size = _PyLong_AsInt(args[0]); + if (size == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional_posonly: + return_value = _io__TextIOBase_read_impl(self, cls, size); + +exit: + return return_value; +} + +PyDoc_STRVAR(_io__TextIOBase_readline__doc__, +"readline($self, size=-1, /)\n" +"--\n" +"\n" +"Read until newline or EOF.\n" +"\n" +"Return an empty string if EOF is hit immediately.\n" +"If size is specified, at most size characters will be read."); + +#define _IO__TEXTIOBASE_READLINE_METHODDEF \ + {"readline", _PyCFunction_CAST(_io__TextIOBase_readline), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _io__TextIOBase_readline__doc__}, + +static PyObject * +_io__TextIOBase_readline_impl(PyObject *self, PyTypeObject *cls, + int Py_UNUSED(size)); + +static PyObject * +_io__TextIOBase_readline(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + + static const char * const _keywords[] = {"", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "readline", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + int size = -1; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (nargs < 1) { + goto skip_optional_posonly; + } + size = _PyLong_AsInt(args[0]); + if (size == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional_posonly: + return_value = _io__TextIOBase_readline_impl(self, cls, size); + +exit: + return return_value; +} + +PyDoc_STRVAR(_io__TextIOBase_write__doc__, +"write($self, s, /)\n" +"--\n" +"\n" +"Write string s to stream.\n" +"\n" +"Return the number of characters written\n" +"(which is always equal to the length of the string)."); + +#define _IO__TEXTIOBASE_WRITE_METHODDEF \ + {"write", _PyCFunction_CAST(_io__TextIOBase_write), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _io__TextIOBase_write__doc__}, + +static PyObject * +_io__TextIOBase_write_impl(PyObject *self, PyTypeObject *cls, + const char *Py_UNUSED(s)); + +static PyObject * +_io__TextIOBase_write(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + + static const char * const _keywords[] = {"", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "write", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + const char *s; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("write", "argument 1", "str", args[0]); + goto exit; + } + Py_ssize_t s_length; + s = PyUnicode_AsUTF8AndSize(args[0], &s_length); + if (s == NULL) { + goto exit; + } + if (strlen(s) != (size_t)s_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + return_value = _io__TextIOBase_write_impl(self, cls, s); + +exit: + return return_value; +} + PyDoc_STRVAR(_io_IncrementalNewlineDecoder___init____doc__, "IncrementalNewlineDecoder(decoder, translate, errors=\'strict\')\n" "--\n" @@ -24,8 +221,31 @@ static int _io_IncrementalNewlineDecoder___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(decoder), &_Py_ID(translate), &_Py_ID(errors), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"decoder", "translate", "errors", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "IncrementalNewlineDecoder", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "IncrementalNewlineDecoder", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -39,8 +259,8 @@ _io_IncrementalNewlineDecoder___init__(PyObject *self, PyObject *args, PyObject goto exit; } decoder = fastargs[0]; - translate = _PyLong_AsInt(fastargs[1]); - if (translate == -1 && PyErr_Occurred()) { + translate = PyObject_IsTrue(fastargs[1]); + if (translate < 0) { goto exit; } if (!noptargs) { @@ -70,8 +290,31 @@ static PyObject * _io_IncrementalNewlineDecoder_decode(nldecoder_object *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(input), &_Py_ID(final), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"input", "final", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "decode", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "decode", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *input; @@ -85,8 +328,8 @@ _io_IncrementalNewlineDecoder_decode(nldecoder_object *self, PyObject *const *ar if (!noptargs) { goto skip_optional_pos; } - final = _PyLong_AsInt(args[1]); - if (final == -1 && PyErr_Occurred()) { + final = PyObject_IsTrue(args[1]); + if (final < 0) { goto exit; } skip_optional_pos: @@ -182,8 +425,31 @@ static int _io_TextIOWrapper___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 6 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(buffer), &_Py_ID(encoding), &_Py_ID(errors), &_Py_ID(newline), &_Py_ID(line_buffering), &_Py_ID(write_through), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"buffer", "encoding", "errors", "newline", "line_buffering", "write_through", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "TextIOWrapper", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "TextIOWrapper", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[6]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -256,16 +522,16 @@ _io_TextIOWrapper___init__(PyObject *self, PyObject *args, PyObject *kwargs) } } if (fastargs[4]) { - line_buffering = _PyLong_AsInt(fastargs[4]); - if (line_buffering == -1 && PyErr_Occurred()) { + line_buffering = PyObject_IsTrue(fastargs[4]); + if (line_buffering < 0) { goto exit; } if (!--noptargs) { goto skip_optional_pos; } } - write_through = _PyLong_AsInt(fastargs[5]); - if (write_through == -1 && PyErr_Occurred()) { + write_through = PyObject_IsTrue(fastargs[5]); + if (write_through < 0) { goto exit; } skip_optional_pos: @@ -297,8 +563,31 @@ static PyObject * _io_TextIOWrapper_reconfigure(textio *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 5 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(encoding), &_Py_ID(errors), &_Py_ID(newline), &_Py_ID(line_buffering), &_Py_ID(write_through), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"encoding", "errors", "newline", "line_buffering", "write_through", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "reconfigure", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "reconfigure", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *encoding = Py_None; @@ -470,9 +759,27 @@ exit: } PyDoc_STRVAR(_io_TextIOWrapper_seek__doc__, -"seek($self, cookie, whence=0, /)\n" +"seek($self, cookie, whence=os.SEEK_SET, /)\n" "--\n" -"\n"); +"\n" +"Set the stream position, and return the new stream position.\n" +"\n" +" cookie\n" +" Zero or an opaque number returned by tell().\n" +" whence\n" +" The relative position to seek from.\n" +"\n" +"Four operations are supported, given by the following argument\n" +"combinations:\n" +"\n" +"- seek(0, SEEK_SET): Rewind to the start of the stream.\n" +"- seek(cookie, SEEK_SET): Restore a previous position;\n" +" \'cookie\' must be a number returned by tell().\n" +"- seek(0, SEEK_END): Fast-forward to the end of the stream.\n" +"- seek(0, SEEK_CUR): Leave the current stream position unchanged.\n" +"\n" +"Any other argument combinations are invalid,\n" +"and may raise exceptions."); #define _IO_TEXTIOWRAPPER_SEEK_METHODDEF \ {"seek", _PyCFunction_CAST(_io_TextIOWrapper_seek), METH_FASTCALL, _io_TextIOWrapper_seek__doc__}, @@ -508,7 +815,11 @@ exit: PyDoc_STRVAR(_io_TextIOWrapper_tell__doc__, "tell($self, /)\n" "--\n" -"\n"); +"\n" +"Return the stream position as an opaque number.\n" +"\n" +"The return value of tell() can be given as input to seek(), to restore a\n" +"previous stream position."); #define _IO_TEXTIOWRAPPER_TELL_METHODDEF \ {"tell", (PyCFunction)_io_TextIOWrapper_tell, METH_NOARGS, _io_TextIOWrapper_tell__doc__}, @@ -671,4 +982,4 @@ _io_TextIOWrapper_close(textio *self, PyObject *Py_UNUSED(ignored)) { return _io_TextIOWrapper_close_impl(self); } -/*[clinic end generated code: output=bb78b568b24759d6 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=a3614e1c64747ff5 input=a9049054013a1b77]*/ diff --git a/Modules/_io/clinic/winconsoleio.c.h b/Modules/_io/clinic/winconsoleio.c.h index 75102a3d..cd3348dc 100644 --- a/Modules/_io/clinic/winconsoleio.c.h +++ b/Modules/_io/clinic/winconsoleio.c.h @@ -2,7 +2,13 @@ preserve [clinic start generated code]*/ -#if defined(MS_WINDOWS) +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + +#if defined(HAVE_WINDOWS_CONSOLE_IO) PyDoc_STRVAR(_io__WindowsConsoleIO_close__doc__, "close($self, /)\n" @@ -14,20 +20,24 @@ PyDoc_STRVAR(_io__WindowsConsoleIO_close__doc__, "close() may be called more than once without error."); #define _IO__WINDOWSCONSOLEIO_CLOSE_METHODDEF \ - {"close", (PyCFunction)_io__WindowsConsoleIO_close, METH_NOARGS, _io__WindowsConsoleIO_close__doc__}, + {"close", _PyCFunction_CAST(_io__WindowsConsoleIO_close), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _io__WindowsConsoleIO_close__doc__}, static PyObject * -_io__WindowsConsoleIO_close_impl(winconsoleio *self); +_io__WindowsConsoleIO_close_impl(winconsoleio *self, PyTypeObject *cls); static PyObject * -_io__WindowsConsoleIO_close(winconsoleio *self, PyObject *Py_UNUSED(ignored)) +_io__WindowsConsoleIO_close(winconsoleio *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - return _io__WindowsConsoleIO_close_impl(self); + if (nargs) { + PyErr_SetString(PyExc_TypeError, "close() takes no arguments"); + return NULL; + } + return _io__WindowsConsoleIO_close_impl(self, cls); } -#endif /* defined(MS_WINDOWS) */ +#endif /* defined(HAVE_WINDOWS_CONSOLE_IO) */ -#if defined(MS_WINDOWS) +#if defined(HAVE_WINDOWS_CONSOLE_IO) PyDoc_STRVAR(_io__WindowsConsoleIO___init____doc__, "_WindowsConsoleIO(file, mode=\'r\', closefd=True, opener=None)\n" @@ -48,8 +58,31 @@ static int _io__WindowsConsoleIO___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(file), &_Py_ID(mode), &_Py_ID(closefd), &_Py_ID(opener), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"file", "mode", "closefd", "opener", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "_WindowsConsoleIO", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "_WindowsConsoleIO", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -86,8 +119,8 @@ _io__WindowsConsoleIO___init__(PyObject *self, PyObject *args, PyObject *kwargs) } } if (fastargs[2]) { - closefd = _PyLong_AsInt(fastargs[2]); - if (closefd == -1 && PyErr_Occurred()) { + closefd = PyObject_IsTrue(fastargs[2]); + if (closefd < 0) { goto exit; } if (!--noptargs) { @@ -102,9 +135,9 @@ exit: return return_value; } -#endif /* defined(MS_WINDOWS) */ +#endif /* defined(HAVE_WINDOWS_CONSOLE_IO) */ -#if defined(MS_WINDOWS) +#if defined(HAVE_WINDOWS_CONSOLE_IO) PyDoc_STRVAR(_io__WindowsConsoleIO_fileno__doc__, "fileno($self, /)\n" @@ -124,9 +157,9 @@ _io__WindowsConsoleIO_fileno(winconsoleio *self, PyObject *Py_UNUSED(ignored)) return _io__WindowsConsoleIO_fileno_impl(self); } -#endif /* defined(MS_WINDOWS) */ +#endif /* defined(HAVE_WINDOWS_CONSOLE_IO) */ -#if defined(MS_WINDOWS) +#if defined(HAVE_WINDOWS_CONSOLE_IO) PyDoc_STRVAR(_io__WindowsConsoleIO_readable__doc__, "readable($self, /)\n" @@ -146,9 +179,9 @@ _io__WindowsConsoleIO_readable(winconsoleio *self, PyObject *Py_UNUSED(ignored)) return _io__WindowsConsoleIO_readable_impl(self); } -#endif /* defined(MS_WINDOWS) */ +#endif /* defined(HAVE_WINDOWS_CONSOLE_IO) */ -#if defined(MS_WINDOWS) +#if defined(HAVE_WINDOWS_CONSOLE_IO) PyDoc_STRVAR(_io__WindowsConsoleIO_writable__doc__, "writable($self, /)\n" @@ -168,9 +201,9 @@ _io__WindowsConsoleIO_writable(winconsoleio *self, PyObject *Py_UNUSED(ignored)) return _io__WindowsConsoleIO_writable_impl(self); } -#endif /* defined(MS_WINDOWS) */ +#endif /* defined(HAVE_WINDOWS_CONSOLE_IO) */ -#if defined(MS_WINDOWS) +#if defined(HAVE_WINDOWS_CONSOLE_IO) PyDoc_STRVAR(_io__WindowsConsoleIO_readinto__doc__, "readinto($self, buffer, /)\n" @@ -179,27 +212,46 @@ PyDoc_STRVAR(_io__WindowsConsoleIO_readinto__doc__, "Same as RawIOBase.readinto()."); #define _IO__WINDOWSCONSOLEIO_READINTO_METHODDEF \ - {"readinto", (PyCFunction)_io__WindowsConsoleIO_readinto, METH_O, _io__WindowsConsoleIO_readinto__doc__}, + {"readinto", _PyCFunction_CAST(_io__WindowsConsoleIO_readinto), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _io__WindowsConsoleIO_readinto__doc__}, static PyObject * -_io__WindowsConsoleIO_readinto_impl(winconsoleio *self, Py_buffer *buffer); +_io__WindowsConsoleIO_readinto_impl(winconsoleio *self, PyTypeObject *cls, + Py_buffer *buffer); static PyObject * -_io__WindowsConsoleIO_readinto(winconsoleio *self, PyObject *arg) +_io__WindowsConsoleIO_readinto(winconsoleio *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + + static const char * const _keywords[] = {"", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "readinto", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; Py_buffer buffer = {NULL, NULL}; - if (PyObject_GetBuffer(arg, &buffer, PyBUF_WRITABLE) < 0) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &buffer, PyBUF_WRITABLE) < 0) { PyErr_Clear(); - _PyArg_BadArgument("readinto", "argument", "read-write bytes-like object", arg); + _PyArg_BadArgument("readinto", "argument 1", "read-write bytes-like object", args[0]); goto exit; } if (!PyBuffer_IsContiguous(&buffer, 'C')) { - _PyArg_BadArgument("readinto", "argument", "contiguous buffer", arg); + _PyArg_BadArgument("readinto", "argument 1", "contiguous buffer", args[0]); goto exit; } - return_value = _io__WindowsConsoleIO_readinto_impl(self, &buffer); + return_value = _io__WindowsConsoleIO_readinto_impl(self, cls, &buffer); exit: /* Cleanup for buffer */ @@ -210,9 +262,9 @@ exit: return return_value; } -#endif /* defined(MS_WINDOWS) */ +#endif /* defined(HAVE_WINDOWS_CONSOLE_IO) */ -#if defined(MS_WINDOWS) +#if defined(HAVE_WINDOWS_CONSOLE_IO) PyDoc_STRVAR(_io__WindowsConsoleIO_readall__doc__, "readall($self, /)\n" @@ -234,9 +286,9 @@ _io__WindowsConsoleIO_readall(winconsoleio *self, PyObject *Py_UNUSED(ignored)) return _io__WindowsConsoleIO_readall_impl(self); } -#endif /* defined(MS_WINDOWS) */ +#endif /* defined(HAVE_WINDOWS_CONSOLE_IO) */ -#if defined(MS_WINDOWS) +#if defined(HAVE_WINDOWS_CONSOLE_IO) PyDoc_STRVAR(_io__WindowsConsoleIO_read__doc__, "read($self, size=-1, /)\n" @@ -249,36 +301,52 @@ PyDoc_STRVAR(_io__WindowsConsoleIO_read__doc__, "Return an empty bytes object at EOF."); #define _IO__WINDOWSCONSOLEIO_READ_METHODDEF \ - {"read", _PyCFunction_CAST(_io__WindowsConsoleIO_read), METH_FASTCALL, _io__WindowsConsoleIO_read__doc__}, + {"read", _PyCFunction_CAST(_io__WindowsConsoleIO_read), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _io__WindowsConsoleIO_read__doc__}, static PyObject * -_io__WindowsConsoleIO_read_impl(winconsoleio *self, Py_ssize_t size); +_io__WindowsConsoleIO_read_impl(winconsoleio *self, PyTypeObject *cls, + Py_ssize_t size); static PyObject * -_io__WindowsConsoleIO_read(winconsoleio *self, PyObject *const *args, Py_ssize_t nargs) +_io__WindowsConsoleIO_read(winconsoleio *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + + static const char * const _keywords[] = {"", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "read", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; Py_ssize_t size = -1; - if (!_PyArg_CheckPositional("read", nargs, 0, 1)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { goto exit; } if (nargs < 1) { - goto skip_optional; + goto skip_optional_posonly; } if (!_Py_convert_optional_to_ssize_t(args[0], &size)) { goto exit; } -skip_optional: - return_value = _io__WindowsConsoleIO_read_impl(self, size); +skip_optional_posonly: + return_value = _io__WindowsConsoleIO_read_impl(self, cls, size); exit: return return_value; } -#endif /* defined(MS_WINDOWS) */ +#endif /* defined(HAVE_WINDOWS_CONSOLE_IO) */ -#if defined(MS_WINDOWS) +#if defined(HAVE_WINDOWS_CONSOLE_IO) PyDoc_STRVAR(_io__WindowsConsoleIO_write__doc__, "write($self, b, /)\n" @@ -290,25 +358,44 @@ PyDoc_STRVAR(_io__WindowsConsoleIO_write__doc__, "The number of bytes actually written is returned."); #define _IO__WINDOWSCONSOLEIO_WRITE_METHODDEF \ - {"write", (PyCFunction)_io__WindowsConsoleIO_write, METH_O, _io__WindowsConsoleIO_write__doc__}, + {"write", _PyCFunction_CAST(_io__WindowsConsoleIO_write), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _io__WindowsConsoleIO_write__doc__}, static PyObject * -_io__WindowsConsoleIO_write_impl(winconsoleio *self, Py_buffer *b); +_io__WindowsConsoleIO_write_impl(winconsoleio *self, PyTypeObject *cls, + Py_buffer *b); static PyObject * -_io__WindowsConsoleIO_write(winconsoleio *self, PyObject *arg) +_io__WindowsConsoleIO_write(winconsoleio *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + + static const char * const _keywords[] = {"", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "write", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; Py_buffer b = {NULL, NULL}; - if (PyObject_GetBuffer(arg, &b, PyBUF_SIMPLE) != 0) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &b, PyBUF_SIMPLE) != 0) { goto exit; } if (!PyBuffer_IsContiguous(&b, 'C')) { - _PyArg_BadArgument("write", "argument", "contiguous buffer", arg); + _PyArg_BadArgument("write", "argument 1", "contiguous buffer", args[0]); goto exit; } - return_value = _io__WindowsConsoleIO_write_impl(self, &b); + return_value = _io__WindowsConsoleIO_write_impl(self, cls, &b); exit: /* Cleanup for b */ @@ -319,9 +406,9 @@ exit: return return_value; } -#endif /* defined(MS_WINDOWS) */ +#endif /* defined(HAVE_WINDOWS_CONSOLE_IO) */ -#if defined(MS_WINDOWS) +#if defined(HAVE_WINDOWS_CONSOLE_IO) PyDoc_STRVAR(_io__WindowsConsoleIO_isatty__doc__, "isatty($self, /)\n" @@ -341,7 +428,7 @@ _io__WindowsConsoleIO_isatty(winconsoleio *self, PyObject *Py_UNUSED(ignored)) return _io__WindowsConsoleIO_isatty_impl(self); } -#endif /* defined(MS_WINDOWS) */ +#endif /* defined(HAVE_WINDOWS_CONSOLE_IO) */ #ifndef _IO__WINDOWSCONSOLEIO_CLOSE_METHODDEF #define _IO__WINDOWSCONSOLEIO_CLOSE_METHODDEF @@ -378,4 +465,4 @@ _io__WindowsConsoleIO_isatty(winconsoleio *self, PyObject *Py_UNUSED(ignored)) #ifndef _IO__WINDOWSCONSOLEIO_ISATTY_METHODDEF #define _IO__WINDOWSCONSOLEIO_ISATTY_METHODDEF #endif /* !defined(_IO__WINDOWSCONSOLEIO_ISATTY_METHODDEF) */ -/*[clinic end generated code: output=2d8648fab31ec60e input=a9049054013a1b77]*/ +/*[clinic end generated code: output=235393758365c229 input=a9049054013a1b77]*/ diff --git a/Modules/_io/fileio.c b/Modules/_io/fileio.c index 4496609a..c8be9982 100644 --- a/Modules/_io/fileio.c +++ b/Modules/_io/fileio.c @@ -37,7 +37,9 @@ #ifdef MS_WINDOWS /* can simulate truncate with Win32 API functions; see file_truncate */ #define HAVE_FTRUNCATE +#ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN +#endif #include <windows.h> #endif @@ -51,9 +53,9 @@ /*[clinic input] module _io -class _io.FileIO "fileio *" "&PyFileIO_Type" +class _io.FileIO "fileio *" "clinic_state()->PyFileIO_Type" [clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=1c77708b41fda70c]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=ac25ec278f4d6703]*/ typedef struct { PyObject_HEAD @@ -70,9 +72,7 @@ typedef struct { PyObject *dict; } fileio; -PyTypeObject PyFileIO_Type; - -#define PyFileIO_Check(op) (PyObject_TypeCheck((op), &PyFileIO_Type)) +#define PyFileIO_Check(state, op) (PyObject_TypeCheck((op), state->PyFileIO_Type)) /* Forward declarations */ static PyObject* portable_lseek(fileio *self, PyObject *posobj, int whence, bool suppress_pipe_error); @@ -90,14 +90,13 @@ static PyObject * fileio_dealloc_warn(fileio *self, PyObject *source) { if (self->fd >= 0 && self->closefd) { - PyObject *exc, *val, *tb; - PyErr_Fetch(&exc, &val, &tb); + PyObject *exc = PyErr_GetRaisedException(); if (PyErr_ResourceWarning(source, 1, "unclosed file %R", source)) { /* Spurious errors can appear at shutdown */ if (PyErr_ExceptionMatches(PyExc_Warning)) PyErr_WriteUnraisable((PyObject *) self); } - PyErr_Restore(exc, val, tb); + PyErr_SetRaisedException(exc); } Py_RETURN_NONE; } @@ -131,6 +130,9 @@ internal_close(fileio *self) /*[clinic input] _io.FileIO.close + cls: defining_class + / + Close the file. A closed file cannot be used for further I/O operations. close() may be @@ -138,32 +140,39 @@ called more than once without error. [clinic start generated code]*/ static PyObject * -_io_FileIO_close_impl(fileio *self) -/*[clinic end generated code: output=7737a319ef3bad0b input=f35231760d54a522]*/ +_io_FileIO_close_impl(fileio *self, PyTypeObject *cls) +/*[clinic end generated code: output=c30cbe9d1f23ca58 input=70da49e63db7c64d]*/ { PyObject *res; - PyObject *exc, *val, *tb; int rc; - res = PyObject_CallMethodOneArg((PyObject*)&PyRawIOBase_Type, + _PyIO_State *state = get_io_state_by_cls(cls); + res = PyObject_CallMethodOneArg((PyObject*)state->PyRawIOBase_Type, &_Py_ID(close), (PyObject *)self); if (!self->closefd) { self->fd = -1; return res; } - if (res == NULL) - PyErr_Fetch(&exc, &val, &tb); + + PyObject *exc; + if (res == NULL) { + exc = PyErr_GetRaisedException(); + } if (self->finalizing) { PyObject *r = fileio_dealloc_warn(self, (PyObject *) self); - if (r) + if (r) { Py_DECREF(r); - else + } + else { PyErr_Clear(); + } } rc = internal_close(self); - if (res == NULL) - _PyErr_ChainExceptions(exc, val, tb); - if (rc < 0) + if (res == NULL) { + _PyErr_ChainExceptions1(exc); + } + if (rc < 0) { Py_CLEAR(res); + } return res; } @@ -198,7 +207,7 @@ extern int _Py_open_cloexec_works; _io.FileIO.__init__ file as nameobj: object mode: str = "r" - closefd: bool(accept={int}) = True + closefd: bool = True opener: object = None Open a file. @@ -219,7 +228,7 @@ results in functionality similar to passing None). static int _io_FileIO___init___impl(fileio *self, PyObject *nameobj, const char *mode, int closefd, PyObject *opener) -/*[clinic end generated code: output=23413f68e6484bbd input=1596c9157a042a39]*/ +/*[clinic end generated code: output=23413f68e6484bbd input=588aac967e0ba74b]*/ { #ifdef MS_WINDOWS Py_UNICODE *widename = NULL; @@ -242,7 +251,10 @@ _io_FileIO___init___impl(fileio *self, PyObject *nameobj, const char *mode, int fstat_result; int async_err = 0; - assert(PyFileIO_Check(self)); +#ifdef Py_DEBUG + _PyIO_State *state = find_io_state_by_def(Py_TYPE(self)); + assert(PyFileIO_Check(state, self)); +#endif if (self->fd >= 0) { if (self->closefd) { /* Have to close the existing file first. */ @@ -268,14 +280,7 @@ _io_FileIO___init___impl(fileio *self, PyObject *nameobj, const char *mode, if (!PyUnicode_FSDecoder(nameobj, &stringobj)) { return -1; } -#if USE_UNICODE_WCHAR_CACHE -_Py_COMP_DIAG_PUSH -_Py_COMP_DIAG_IGNORE_DEPR_DECLS - widename = PyUnicode_AsUnicode(stringobj); -_Py_COMP_DIAG_POP -#else /* USE_UNICODE_WCHAR_CACHE */ widename = PyUnicode_AsWideCharString(stringobj, NULL); -#endif /* USE_UNICODE_WCHAR_CACHE */ if (widename == NULL) return -1; #else @@ -389,6 +394,11 @@ _Py_COMP_DIAG_POP if (async_err) goto error; + + if (self->fd < 0) { + PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, nameobj); + goto error; + } } else { PyObject *fdobj; @@ -420,12 +430,7 @@ _Py_COMP_DIAG_POP goto error; } } - fd_is_own = 1; - if (self->fd < 0) { - PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, nameobj); - goto error; - } #ifndef MS_WINDOWS if (_Py_set_inheritable(self->fd, 0, atomic_flag_works) < 0) @@ -493,17 +498,14 @@ _Py_COMP_DIAG_POP if (!fd_is_own) self->fd = -1; if (self->fd >= 0) { - PyObject *exc, *val, *tb; - PyErr_Fetch(&exc, &val, &tb); + PyObject *exc = PyErr_GetRaisedException(); internal_close(self); - _PyErr_ChainExceptions(exc, val, tb); + _PyErr_ChainExceptions1(exc); } done: #ifdef MS_WINDOWS -#if !USE_UNICODE_WCHAR_CACHE PyMem_Free(widename); -#endif /* USE_UNICODE_WCHAR_CACHE */ #endif Py_CLEAR(stringobj); return ret; @@ -512,6 +514,7 @@ _Py_COMP_DIAG_POP static int fileio_traverse(fileio *self, visitproc visit, void *arg) { + Py_VISIT(Py_TYPE(self)); Py_VISIT(self->dict); return 0; } @@ -526,14 +529,16 @@ fileio_clear(fileio *self) static void fileio_dealloc(fileio *self) { + PyTypeObject *tp = Py_TYPE(self); self->finalizing = 1; if (_PyIOBase_finalize((PyObject *) self) < 0) return; _PyObject_GC_UNTRACK(self); if (self->weakreflist != NULL) PyObject_ClearWeakRefs((PyObject *) self); - Py_CLEAR(self->dict); - Py_TYPE(self)->tp_free((PyObject *)self); + (void)fileio_clear(self); + tp->tp_free((PyObject *)self); + Py_DECREF(tp); } static PyObject * @@ -544,13 +549,10 @@ err_closed(void) } static PyObject * -err_mode(const char *action) +err_mode(_PyIO_State *state, const char *action) { - _PyIO_State *state = IO_STATE(); - if (state != NULL) - PyErr_Format(state->unsupported_operation, - "File not open for %s", action); - return NULL; + return PyErr_Format(state->unsupported_operation, + "File not open for %s", action); } /*[clinic input] @@ -626,6 +628,7 @@ _io_FileIO_seekable_impl(fileio *self) /*[clinic input] _io.FileIO.readinto + cls: defining_class buffer: Py_buffer(accept={rwbuffer}) / @@ -633,16 +636,18 @@ Same as RawIOBase.readinto(). [clinic start generated code]*/ static PyObject * -_io_FileIO_readinto_impl(fileio *self, Py_buffer *buffer) -/*[clinic end generated code: output=b01a5a22c8415cb4 input=4721d7b68b154eaf]*/ +_io_FileIO_readinto_impl(fileio *self, PyTypeObject *cls, Py_buffer *buffer) +/*[clinic end generated code: output=97f0f3d69534db34 input=fd20323e18ce1ec8]*/ { Py_ssize_t n; int err; if (self->fd < 0) return err_closed(); - if (!self->readable) - return err_mode("reading"); + if (!self->readable) { + _PyIO_State *state = get_io_state_by_cls(cls); + return err_mode(state, "reading"); + } n = _Py_read(self->fd, buffer->buf, buffer->len); /* copy errno because PyBuffer_Release() can indirectly modify it */ @@ -779,6 +784,7 @@ _io_FileIO_readall_impl(fileio *self) /*[clinic input] _io.FileIO.read + cls: defining_class size: Py_ssize_t(accept={int, NoneType}) = -1 / @@ -790,8 +796,8 @@ Return an empty bytes object at EOF. [clinic start generated code]*/ static PyObject * -_io_FileIO_read_impl(fileio *self, Py_ssize_t size) -/*[clinic end generated code: output=42528d39dd0ca641 input=bec9a2c704ddcbc9]*/ +_io_FileIO_read_impl(fileio *self, PyTypeObject *cls, Py_ssize_t size) +/*[clinic end generated code: output=bbd749c7c224143e input=f613d2057e4a1918]*/ { char *ptr; Py_ssize_t n; @@ -799,8 +805,10 @@ _io_FileIO_read_impl(fileio *self, Py_ssize_t size) if (self->fd < 0) return err_closed(); - if (!self->readable) - return err_mode("reading"); + if (!self->readable) { + _PyIO_State *state = get_io_state_by_cls(cls); + return err_mode(state, "reading"); + } if (size < 0) return _io_FileIO_readall_impl(self); @@ -838,6 +846,7 @@ _io_FileIO_read_impl(fileio *self, Py_ssize_t size) /*[clinic input] _io.FileIO.write + cls: defining_class b: Py_buffer / @@ -849,16 +858,18 @@ returns None if the write would block. [clinic start generated code]*/ static PyObject * -_io_FileIO_write_impl(fileio *self, Py_buffer *b) -/*[clinic end generated code: output=b4059db3d363a2f7 input=6e7908b36f0ce74f]*/ +_io_FileIO_write_impl(fileio *self, PyTypeObject *cls, Py_buffer *b) +/*[clinic end generated code: output=927e25be80f3b77b input=2776314f043088f5]*/ { Py_ssize_t n; int err; if (self->fd < 0) return err_closed(); - if (!self->writable) - return err_mode("writing"); + if (!self->writable) { + _PyIO_State *state = get_io_state_by_cls(cls); + return err_mode(state, "writing"); + } n = _Py_write(self->fd, b->buf, b->len); /* copy errno because PyBuffer_Release() can indirectly modify it */ @@ -989,6 +1000,7 @@ _io_FileIO_tell_impl(fileio *self) #ifdef HAVE_FTRUNCATE /*[clinic input] _io.FileIO.truncate + cls: defining_class size as posobj: object = None / @@ -999,8 +1011,8 @@ The current file position is changed to the value of size. [clinic start generated code]*/ static PyObject * -_io_FileIO_truncate_impl(fileio *self, PyObject *posobj) -/*[clinic end generated code: output=e49ca7a916c176fa input=b0ac133939823875]*/ +_io_FileIO_truncate_impl(fileio *self, PyTypeObject *cls, PyObject *posobj) +/*[clinic end generated code: output=d936732a49e8d5a2 input=c367fb45d6bb2c18]*/ { Py_off_t pos; int ret; @@ -1009,8 +1021,10 @@ _io_FileIO_truncate_impl(fileio *self, PyObject *posobj) fd = self->fd; if (fd < 0) return err_closed(); - if (!self->writable) - return err_mode("writing"); + if (!self->writable) { + _PyIO_State *state = get_io_state_by_cls(cls); + return err_mode(state, "writing"); + } if (posobj == Py_None) { /* Get the current position. */ @@ -1044,8 +1058,8 @@ _io_FileIO_truncate_impl(fileio *self, PyObject *posobj) Py_END_ALLOW_THREADS if (ret != 0) { - Py_DECREF(posobj); PyErr_SetFromErrno(PyExc_OSError); + Py_DECREF(posobj); return NULL; } @@ -1152,6 +1166,8 @@ static PyMethodDef fileio_methods[] = { _IO_FILEIO_FILENO_METHODDEF _IO_FILEIO_ISATTY_METHODDEF {"_dealloc_warn", (PyCFunction)fileio_dealloc_warn, METH_O, NULL}, + {"__reduce__", _PyIOBase_cannot_pickle, METH_VARARGS}, + {"__reduce_ex__", _PyIOBase_cannot_pickle, METH_VARARGS}, {NULL, NULL} /* sentinel */ }; @@ -1186,57 +1202,29 @@ static PyGetSetDef fileio_getsetlist[] = { static PyMemberDef fileio_members[] = { {"_blksize", T_UINT, offsetof(fileio, blksize), 0}, {"_finalizing", T_BOOL, offsetof(fileio, finalizing), 0}, + {"__weaklistoffset__", T_PYSSIZET, offsetof(fileio, weakreflist), READONLY}, + {"__dictoffset__", T_PYSSIZET, offsetof(fileio, dict), READONLY}, {NULL} }; -PyTypeObject PyFileIO_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_io.FileIO", - sizeof(fileio), - 0, - (destructor)fileio_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - (reprfunc)fileio_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE - | Py_TPFLAGS_HAVE_GC, /* tp_flags */ - _io_FileIO___init____doc__, /* tp_doc */ - (traverseproc)fileio_traverse, /* tp_traverse */ - (inquiry)fileio_clear, /* tp_clear */ - 0, /* tp_richcompare */ - offsetof(fileio, weakreflist), /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - fileio_methods, /* tp_methods */ - fileio_members, /* tp_members */ - fileio_getsetlist, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - offsetof(fileio, dict), /* tp_dictoffset */ - _io_FileIO___init__, /* tp_init */ - PyType_GenericAlloc, /* tp_alloc */ - fileio_new, /* tp_new */ - PyObject_GC_Del, /* tp_free */ - 0, /* tp_is_gc */ - 0, /* tp_bases */ - 0, /* tp_mro */ - 0, /* tp_cache */ - 0, /* tp_subclasses */ - 0, /* tp_weaklist */ - 0, /* tp_del */ - 0, /* tp_version_tag */ - 0, /* tp_finalize */ +static PyType_Slot fileio_slots[] = { + {Py_tp_dealloc, fileio_dealloc}, + {Py_tp_repr, fileio_repr}, + {Py_tp_doc, (void *)_io_FileIO___init____doc__}, + {Py_tp_traverse, fileio_traverse}, + {Py_tp_clear, fileio_clear}, + {Py_tp_methods, fileio_methods}, + {Py_tp_members, fileio_members}, + {Py_tp_getset, fileio_getsetlist}, + {Py_tp_init, _io_FileIO___init__}, + {Py_tp_new, fileio_new}, + {0, NULL}, +}; + +PyType_Spec fileio_spec = { + .name = "_io.FileIO", + .basicsize = sizeof(fileio), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = fileio_slots, }; diff --git a/Modules/_io/iobase.c b/Modules/_io/iobase.c index 6ae43a8b..bc2c9afa 100644 --- a/Modules/_io/iobase.c +++ b/Modules/_io/iobase.c @@ -17,10 +17,10 @@ /*[clinic input] module _io -class _io._IOBase "PyObject *" "&PyIOBase_Type" -class _io._RawIOBase "PyObject *" "&PyRawIOBase_Type" +class _io._IOBase "PyObject *" "clinic_state()->PyIOBase_Type" +class _io._RawIOBase "PyObject *" "clinic_state()->PyRawIOBase_Type" [clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=d29a4d076c2b211c]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=9006b7802ab8ea85]*/ /* * IOBase class, an abstract class @@ -71,33 +71,42 @@ PyDoc_STRVAR(iobase_doc, /* Internal methods */ static PyObject * -iobase_unsupported(const char *message) +iobase_unsupported(_PyIO_State *state, const char *message) { - _PyIO_State *state = IO_STATE(); - if (state != NULL) - PyErr_SetString(state->unsupported_operation, message); + PyErr_SetString(state->unsupported_operation, message); return NULL; } /* Positioning */ -PyDoc_STRVAR(iobase_seek_doc, - "Change stream position.\n" - "\n" - "Change the stream position to the given byte offset. The offset is\n" - "interpreted relative to the position indicated by whence. Values\n" - "for whence are:\n" - "\n" - "* 0 -- start of stream (the default); offset should be zero or positive\n" - "* 1 -- current stream position; offset may be negative\n" - "* 2 -- end of stream; offset is usually negative\n" - "\n" - "Return the new absolute position."); +/*[clinic input] +_io._IOBase.seek + cls: defining_class + offset: int(unused=True) + The stream position, relative to 'whence'. + whence: int(unused=True, c_default='0') = os.SEEK_SET + The relative position to seek from. + / + +Change the stream position to the given byte offset. + +The offset is interpreted relative to the position indicated by whence. +Values for whence are: + +* os.SEEK_SET or 0 -- start of stream (the default); offset should be zero or positive +* os.SEEK_CUR or 1 -- current stream position; offset may be negative +* os.SEEK_END or 2 -- end of stream; offset is usually negative + +Return the new absolute position. +[clinic start generated code]*/ static PyObject * -iobase_seek(PyObject *self, PyObject *args) +_io__IOBase_seek_impl(PyObject *self, PyTypeObject *cls, + int Py_UNUSED(offset), int Py_UNUSED(whence)) +/*[clinic end generated code: output=8bd74ea6538ded53 input=74211232b363363e]*/ { - return iobase_unsupported("seek"); + _PyIO_State *state = get_io_state_by_cls(cls); + return iobase_unsupported(state, "seek"); } /*[clinic input] @@ -113,16 +122,25 @@ _io__IOBase_tell_impl(PyObject *self) return _PyObject_CallMethod(self, &_Py_ID(seek), "ii", 0, 1); } -PyDoc_STRVAR(iobase_truncate_doc, - "Truncate file to size bytes.\n" - "\n" - "File pointer is left unchanged. Size defaults to the current IO\n" - "position as reported by tell(). Returns the new size."); +/*[clinic input] +_io._IOBase.truncate + cls: defining_class + size: object(unused=True) = None + / + +Truncate file to size bytes. + +File pointer is left unchanged. Size defaults to the current IO position +as reported by tell(). Return the new size. +[clinic start generated code]*/ static PyObject * -iobase_truncate(PyObject *self, PyObject *args) +_io__IOBase_truncate_impl(PyObject *self, PyTypeObject *cls, + PyObject *Py_UNUSED(size)) +/*[clinic end generated code: output=2013179bff1fe8ef input=660ac20936612c27]*/ { - return iobase_unsupported("truncate"); + _PyIO_State *state = get_io_state_by_cls(cls); + return iobase_unsupported(state, "truncate"); } static int @@ -204,6 +222,35 @@ _PyIOBase_check_closed(PyObject *self, PyObject *args) Py_RETURN_NONE; } +static PyObject * +iobase_check_seekable(PyObject *self, PyObject *args) +{ + _PyIO_State *state = find_io_state_by_def(Py_TYPE(self)); + return _PyIOBase_check_seekable(state, self, args); +} + +static PyObject * +iobase_check_readable(PyObject *self, PyObject *args) +{ + _PyIO_State *state = find_io_state_by_def(Py_TYPE(self)); + return _PyIOBase_check_readable(state, self, args); +} + +static PyObject * +iobase_check_writable(PyObject *self, PyObject *args) +{ + _PyIO_State *state = find_io_state_by_def(Py_TYPE(self)); + return _PyIOBase_check_writable(state, self, args); +} + +PyObject * +_PyIOBase_cannot_pickle(PyObject *self, PyObject *args) +{ + PyErr_Format(PyExc_TypeError, + "cannot pickle '%.100s' instances", _PyType_Name(Py_TYPE(self))); + return NULL; +} + /* XXX: IOBase thinks it has to maintain its own internal state in `__IOBase_closed` and call flush() by itself, but it is redundant with whatever behaviour a non-trivial derived class will implement. */ @@ -220,7 +267,6 @@ static PyObject * _io__IOBase_close_impl(PyObject *self) /*[clinic end generated code: output=63c6a6f57d783d6d input=f4494d5c31dbc6b7]*/ { - PyObject *res, *exc, *val, *tb; int rc, closed = iobase_is_closed(self); if (closed < 0) { @@ -230,11 +276,11 @@ _io__IOBase_close_impl(PyObject *self) Py_RETURN_NONE; } - res = PyObject_CallMethodNoArgs(self, &_Py_ID(flush)); + PyObject *res = PyObject_CallMethodNoArgs(self, &_Py_ID(flush)); - PyErr_Fetch(&exc, &val, &tb); + PyObject *exc = PyErr_GetRaisedException(); rc = PyObject_SetAttr(self, &_Py_ID(__IOBase_closed), Py_True); - _PyErr_ChainExceptions(exc, val, tb); + _PyErr_ChainExceptions1(exc); if (rc < 0) { Py_CLEAR(res); } @@ -252,11 +298,10 @@ static void iobase_finalize(PyObject *self) { PyObject *res; - PyObject *error_type, *error_value, *error_traceback; int closed; /* Save the current exception, if any. */ - PyErr_Fetch(&error_type, &error_value, &error_traceback); + PyObject *exc = PyErr_GetRaisedException(); /* If `closed` doesn't exist or can't be evaluated as bool, then the object is probably in an unusable state, so ignore. */ @@ -297,7 +342,7 @@ iobase_finalize(PyObject *self) } /* Restore the saved exception. */ - PyErr_Restore(error_type, error_value, error_traceback); + PyErr_SetRaisedException(exc); } int @@ -319,6 +364,7 @@ _PyIOBase_finalize(PyObject *self) static int iobase_traverse(iobase *self, visitproc visit, void *arg) { + Py_VISIT(Py_TYPE(self)); Py_VISIT(self->dict); return 0; } @@ -348,11 +394,13 @@ iobase_dealloc(iobase *self) } return; } + PyTypeObject *tp = Py_TYPE(self); _PyObject_GC_UNTRACK(self); if (self->weakreflist != NULL) PyObject_ClearWeakRefs((PyObject *) self); Py_CLEAR(self->dict); - Py_TYPE(self)->tp_free((PyObject *) self); + tp->tp_free((PyObject *)self); + Py_DECREF(tp); } /* Inquiry methods */ @@ -374,14 +422,14 @@ _io__IOBase_seekable_impl(PyObject *self) } PyObject * -_PyIOBase_check_seekable(PyObject *self, PyObject *args) +_PyIOBase_check_seekable(_PyIO_State *state, PyObject *self, PyObject *args) { PyObject *res = PyObject_CallMethodNoArgs(self, &_Py_ID(seekable)); if (res == NULL) return NULL; if (res != Py_True) { Py_CLEAR(res); - iobase_unsupported("File or stream is not seekable."); + iobase_unsupported(state, "File or stream is not seekable."); return NULL; } if (args == Py_True) { @@ -407,14 +455,14 @@ _io__IOBase_readable_impl(PyObject *self) /* May be called with any object */ PyObject * -_PyIOBase_check_readable(PyObject *self, PyObject *args) +_PyIOBase_check_readable(_PyIO_State *state, PyObject *self, PyObject *args) { PyObject *res = PyObject_CallMethodNoArgs(self, &_Py_ID(readable)); if (res == NULL) return NULL; if (res != Py_True) { Py_CLEAR(res); - iobase_unsupported("File or stream is not readable."); + iobase_unsupported(state, "File or stream is not readable."); return NULL; } if (args == Py_True) { @@ -440,14 +488,14 @@ _io__IOBase_writable_impl(PyObject *self) /* May be called with any object */ PyObject * -_PyIOBase_check_writable(PyObject *self, PyObject *args) +_PyIOBase_check_writable(_PyIO_State *state, PyObject *self, PyObject *args) { PyObject *res = PyObject_CallMethodNoArgs(self, &_Py_ID(writable)); if (res == NULL) return NULL; if (res != Py_True) { Py_CLEAR(res); - iobase_unsupported("File or stream is not writable."); + iobase_unsupported(state, "File or stream is not writable."); return NULL; } if (args == Py_True) { @@ -464,8 +512,7 @@ iobase_enter(PyObject *self, PyObject *args) if (iobase_check_closed(self)) return NULL; - Py_INCREF(self); - return self; + return Py_NewRef(self); } static PyObject * @@ -480,17 +527,20 @@ iobase_exit(PyObject *self, PyObject *args) /*[clinic input] _io._IOBase.fileno + cls: defining_class + / -Returns underlying file descriptor if one exists. +Return underlying file descriptor if one exists. -OSError is raised if the IO object does not use a file descriptor. +Raise OSError if the IO object does not use a file descriptor. [clinic start generated code]*/ static PyObject * -_io__IOBase_fileno_impl(PyObject *self) -/*[clinic end generated code: output=7cc0973f0f5f3b73 input=4e37028947dc1cc8]*/ +_io__IOBase_fileno_impl(PyObject *self, PyTypeObject *cls) +/*[clinic end generated code: output=7caaa32a6f4ada3d input=1927c8bea5c85099]*/ { - return iobase_unsupported("fileno"); + _PyIO_State *state = get_io_state_by_cls(cls); + return iobase_unsupported(state, "fileno"); } /*[clinic input] @@ -642,8 +692,7 @@ iobase_iter(PyObject *self) if (iobase_check_closed(self)) return NULL; - Py_INCREF(self); - return self; + return Py_NewRef(self); } static PyObject * @@ -788,12 +837,14 @@ _io__IOBase_writelines(PyObject *self, PyObject *lines) Py_RETURN_NONE; } +#define clinic_state() (find_io_state_by_def(Py_TYPE(self))) #include "clinic/iobase.c.h" +#undef clinic_state static PyMethodDef iobase_methods[] = { - {"seek", iobase_seek, METH_VARARGS, iobase_seek_doc}, + _IO__IOBASE_SEEK_METHODDEF _IO__IOBASE_TELL_METHODDEF - {"truncate", iobase_truncate, METH_VARARGS, iobase_truncate_doc}, + _IO__IOBASE_TRUNCATE_METHODDEF _IO__IOBASE_FLUSH_METHODDEF _IO__IOBASE_CLOSE_METHODDEF @@ -802,9 +853,9 @@ static PyMethodDef iobase_methods[] = { _IO__IOBASE_WRITABLE_METHODDEF {"_checkClosed", _PyIOBase_check_closed, METH_NOARGS}, - {"_checkSeekable", _PyIOBase_check_seekable, METH_NOARGS}, - {"_checkReadable", _PyIOBase_check_readable, METH_NOARGS}, - {"_checkWritable", _PyIOBase_check_writable, METH_NOARGS}, + {"_checkSeekable", iobase_check_seekable, METH_NOARGS}, + {"_checkReadable", iobase_check_readable, METH_NOARGS}, + {"_checkWritable", iobase_check_writable, METH_NOARGS}, _IO__IOBASE_FILENO_METHODDEF _IO__IOBASE_ISATTY_METHODDEF @@ -825,59 +876,34 @@ static PyGetSetDef iobase_getset[] = { {NULL} }; +static struct PyMemberDef iobase_members[] = { + {"__weaklistoffset__", T_PYSSIZET, offsetof(iobase, weakreflist), READONLY}, + {"__dictoffset__", T_PYSSIZET, offsetof(iobase, dict), READONLY}, + {NULL}, +}; -PyTypeObject PyIOBase_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_io._IOBase", /*tp_name*/ - sizeof(iobase), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - (destructor)iobase_dealloc, /*tp_dealloc*/ - 0, /*tp_vectorcall_offset*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_as_async*/ - 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 - | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ - iobase_doc, /* tp_doc */ - (traverseproc)iobase_traverse, /* tp_traverse */ - (inquiry)iobase_clear, /* tp_clear */ - 0, /* tp_richcompare */ - offsetof(iobase, weakreflist), /* tp_weaklistoffset */ - iobase_iter, /* tp_iter */ - iobase_iternext, /* tp_iternext */ - iobase_methods, /* tp_methods */ - 0, /* tp_members */ - iobase_getset, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - offsetof(iobase, dict), /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - PyType_GenericNew, /* tp_new */ - 0, /* tp_free */ - 0, /* tp_is_gc */ - 0, /* tp_bases */ - 0, /* tp_mro */ - 0, /* tp_cache */ - 0, /* tp_subclasses */ - 0, /* tp_weaklist */ - 0, /* tp_del */ - 0, /* tp_version_tag */ - iobase_finalize, /* tp_finalize */ + +static PyType_Slot iobase_slots[] = { + {Py_tp_dealloc, iobase_dealloc}, + {Py_tp_doc, (void *)iobase_doc}, + {Py_tp_traverse, iobase_traverse}, + {Py_tp_clear, iobase_clear}, + {Py_tp_iter, iobase_iter}, + {Py_tp_iternext, iobase_iternext}, + {Py_tp_methods, iobase_methods}, + {Py_tp_members, iobase_members}, + {Py_tp_getset, iobase_getset}, + {Py_tp_finalize, iobase_finalize}, + {0, NULL}, }; +PyType_Spec iobase_spec = { + .name = "_io._IOBase", + .basicsize = sizeof(iobase), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = iobase_slots, +}; /* * RawIOBase class, Inherits from IOBase. @@ -1020,53 +1046,16 @@ static PyMethodDef rawiobase_methods[] = { {NULL, NULL} }; -PyTypeObject PyRawIOBase_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_io._RawIOBase", /*tp_name*/ - 0, /*tp_basicsize*/ - 0, /*tp_itemsize*/ - 0, /*tp_dealloc*/ - 0, /*tp_vectorcall_offset*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_as_async*/ - 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*/ - rawiobase_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - rawiobase_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - &PyIOBase_Type, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ - 0, /* tp_free */ - 0, /* tp_is_gc */ - 0, /* tp_bases */ - 0, /* tp_mro */ - 0, /* tp_cache */ - 0, /* tp_subclasses */ - 0, /* tp_weaklist */ - 0, /* tp_del */ - 0, /* tp_version_tag */ - 0, /* tp_finalize */ +static PyType_Slot rawiobase_slots[] = { + {Py_tp_doc, (void *)rawiobase_doc}, + {Py_tp_methods, rawiobase_methods}, + {0, NULL}, +}; + +/* Do not set Py_TPFLAGS_HAVE_GC so that tp_traverse and tp_clear are inherited */ +PyType_Spec rawiobase_spec = { + .name = "_io._RawIOBase", + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = rawiobase_slots, }; diff --git a/Modules/_io/stringio.c b/Modules/_io/stringio.c index 3fe02d35..3eb25704 100644 --- a/Modules/_io/stringio.c +++ b/Modules/_io/stringio.c @@ -1,7 +1,6 @@ #define PY_SSIZE_T_CLEAN #include "Python.h" #include <stddef.h> // offsetof() -#include "pycore_accu.h" #include "pycore_object.h" #include "_iomodule.h" @@ -14,9 +13,9 @@ /*[clinic input] module _io -class _io.StringIO "stringio *" "&PyStringIO_Type" +class _io.StringIO "stringio *" "clinic_state()->PyStringIO_Type" [clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=c17bc0f42165cd7d]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=2693eada0658d470]*/ typedef struct { PyObject_HEAD @@ -27,12 +26,12 @@ typedef struct { /* The stringio object can be in two states: accumulating or realized. In accumulating state, the internal buffer contains nothing and - the contents are given by the embedded _PyAccu structure. + the contents are given by the embedded _PyUnicodeWriter structure. In realized state, the internal buffer is meaningful and the - _PyAccu is destroyed. + _PyUnicodeWriter is destroyed. */ int state; - _PyAccu accu; + _PyUnicodeWriter writer; char ok; /* initialized? */ char closed; @@ -44,6 +43,7 @@ typedef struct { PyObject *dict; PyObject *weakreflist; + _PyIO_State *module_state; } stringio; static int _io_StringIO___init__(PyObject *self, PyObject *args, PyObject *kwargs); @@ -126,12 +126,14 @@ resize_buffer(stringio *self, size_t size) static PyObject * make_intermediate(stringio *self) { - PyObject *intermediate = _PyAccu_Finish(&self->accu); + PyObject *intermediate = _PyUnicodeWriter_Finish(&self->writer); self->state = STATE_REALIZED; if (intermediate == NULL) return NULL; - if (_PyAccu_Init(&self->accu) || - _PyAccu_Accumulate(&self->accu, intermediate)) { + + _PyUnicodeWriter_Init(&self->writer); + self->writer.overallocate = 1; + if (_PyUnicodeWriter_WriteStr(&self->writer, intermediate)) { Py_DECREF(intermediate); return NULL; } @@ -150,7 +152,7 @@ realize(stringio *self) assert(self->state == STATE_ACCUMULATING); self->state = STATE_REALIZED; - intermediate = _PyAccu_Finish(&self->accu); + intermediate = _PyUnicodeWriter_Finish(&self->writer); if (intermediate == NULL) return -1; @@ -187,14 +189,12 @@ write_str(stringio *self, PyObject *obj) self->decoder, obj, 1 /* always final */); } else { - decoded = obj; - Py_INCREF(decoded); + decoded = Py_NewRef(obj); } if (self->writenl) { PyObject *translated = PyUnicode_Replace( decoded, &_Py_STR(newline), self->writenl, -1); - Py_DECREF(decoded); - decoded = translated; + Py_SETREF(decoded, translated); } if (decoded == NULL) return -1; @@ -218,7 +218,7 @@ write_str(stringio *self, PyObject *obj) if (self->state == STATE_ACCUMULATING) { if (self->string_size == self->pos) { - if (_PyAccu_Accumulate(&self->accu, decoded)) + if (_PyUnicodeWriter_WriteStr(&self->writer, decoded)) goto fail; goto success; } @@ -402,7 +402,7 @@ stringio_iternext(stringio *self) CHECK_CLOSED(self); ENSURE_REALIZED(self); - if (Py_IS_TYPE(self, &PyStringIO_Type)) { + if (Py_IS_TYPE(self, self->module_state->PyStringIO_Type)) { /* Skip method call overhead for speed */ line = _stringio_readline(self, -1); } @@ -572,7 +572,7 @@ _io_StringIO_close_impl(stringio *self) /* Free up some memory */ if (resize_buffer(self, 0) < 0) return NULL; - _PyAccu_Destroy(&self->accu); + _PyUnicodeWriter_Dealloc(&self->writer); Py_CLEAR(self->readnl); Py_CLEAR(self->writenl); Py_CLEAR(self->decoder); @@ -582,6 +582,10 @@ _io_StringIO_close_impl(stringio *self) static int stringio_traverse(stringio *self, visitproc visit, void *arg) { + Py_VISIT(Py_TYPE(self)); + Py_VISIT(self->readnl); + Py_VISIT(self->writenl); + Py_VISIT(self->decoder); Py_VISIT(self->dict); return 0; } @@ -589,6 +593,9 @@ stringio_traverse(stringio *self, visitproc visit, void *arg) static int stringio_clear(stringio *self) { + Py_CLEAR(self->readnl); + Py_CLEAR(self->writenl); + Py_CLEAR(self->decoder); Py_CLEAR(self->dict); return 0; } @@ -596,20 +603,20 @@ stringio_clear(stringio *self) static void stringio_dealloc(stringio *self) { + PyTypeObject *tp = Py_TYPE(self); _PyObject_GC_UNTRACK(self); self->ok = 0; if (self->buf) { PyMem_Free(self->buf); self->buf = NULL; } - _PyAccu_Destroy(&self->accu); - Py_CLEAR(self->readnl); - Py_CLEAR(self->writenl); - Py_CLEAR(self->decoder); - Py_CLEAR(self->dict); - if (self->weakreflist != NULL) + _PyUnicodeWriter_Dealloc(&self->writer); + (void)stringio_clear(self); + if (self->weakreflist != NULL) { PyObject_ClearWeakRefs((PyObject *) self); - Py_TYPE(self)->tp_free(self); + } + tp->tp_free(self); + Py_DECREF(tp); } static PyObject * @@ -687,7 +694,7 @@ _io_StringIO___init___impl(stringio *self, PyObject *value, self->ok = 0; - _PyAccu_Destroy(&self->accu); + _PyUnicodeWriter_Dealloc(&self->writer); Py_CLEAR(self->readnl); Py_CLEAR(self->writenl); Py_CLEAR(self->decoder); @@ -709,13 +716,13 @@ _io_StringIO___init___impl(stringio *self, PyObject *value, is pointless for StringIO) */ if (newline != NULL && newline[0] == '\r') { - self->writenl = self->readnl; - Py_INCREF(self->writenl); + self->writenl = Py_NewRef(self->readnl); } + _PyIO_State *module_state = find_io_state_by_def(Py_TYPE(self)); if (self->readuniversal) { self->decoder = PyObject_CallFunctionObjArgs( - (PyObject *)&PyIncrementalNewlineDecoder_Type, + (PyObject *)module_state->PyIncrementalNewlineDecoder_Type, Py_None, self->readtranslate ? Py_True : Py_False, NULL); if (self->decoder == NULL) return -1; @@ -742,12 +749,12 @@ _io_StringIO___init___impl(stringio *self, PyObject *value, /* Empty stringio object, we can start by accumulating */ if (resize_buffer(self, 0) < 0) return -1; - if (_PyAccu_Init(&self->accu)) - return -1; + _PyUnicodeWriter_Init(&self->writer); + self->writer.overallocate = 1; self->state = STATE_ACCUMULATING; } self->pos = 0; - + self->module_state = module_state; self->closed = 0; self->ok = 1; return 0; @@ -822,8 +829,7 @@ stringio_getstate(stringio *self, PyObject *Py_UNUSED(ignored)) if (initvalue == NULL) return NULL; if (self->dict == NULL) { - Py_INCREF(Py_None); - dict = Py_None; + dict = Py_NewRef(Py_None); } else { dict = PyDict_Copy(self->dict); @@ -933,8 +939,7 @@ stringio_setstate(stringio *self, PyObject *state) return NULL; } else { - Py_INCREF(dict); - self->dict = dict; + self->dict = Py_NewRef(dict); } } @@ -967,7 +972,9 @@ stringio_newlines(stringio *self, void *context) return PyObject_GetAttr(self->decoder, &_Py_ID(newlines)); } +#define clinic_state() (find_io_state_by_def(Py_TYPE(self))) #include "clinic/stringio.c.h" +#undef clinic_state static struct PyMethodDef stringio_methods[] = { _IO_STRINGIO_CLOSE_METHODDEF @@ -1001,44 +1008,30 @@ static PyGetSetDef stringio_getset[] = { {NULL} }; -PyTypeObject PyStringIO_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_io.StringIO", /*tp_name*/ - sizeof(stringio), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - (destructor)stringio_dealloc, /*tp_dealloc*/ - 0, /*tp_vectorcall_offset*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_as_async*/ - 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 - | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ - _io_StringIO___init____doc__, /*tp_doc*/ - (traverseproc)stringio_traverse, /*tp_traverse*/ - (inquiry)stringio_clear, /*tp_clear*/ - 0, /*tp_richcompare*/ - offsetof(stringio, weakreflist), /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - (iternextfunc)stringio_iternext, /*tp_iternext*/ - stringio_methods, /*tp_methods*/ - 0, /*tp_members*/ - stringio_getset, /*tp_getset*/ - 0, /*tp_base*/ - 0, /*tp_dict*/ - 0, /*tp_descr_get*/ - 0, /*tp_descr_set*/ - offsetof(stringio, dict), /*tp_dictoffset*/ - _io_StringIO___init__, /*tp_init*/ - 0, /*tp_alloc*/ - stringio_new, /*tp_new*/ +static struct PyMemberDef stringio_members[] = { + {"__weaklistoffset__", T_PYSSIZET, offsetof(stringio, weakreflist), READONLY}, + {"__dictoffset__", T_PYSSIZET, offsetof(stringio, dict), READONLY}, + {NULL}, +}; + +static PyType_Slot stringio_slots[] = { + {Py_tp_dealloc, stringio_dealloc}, + {Py_tp_doc, (void *)_io_StringIO___init____doc__}, + {Py_tp_traverse, stringio_traverse}, + {Py_tp_clear, stringio_clear}, + {Py_tp_iternext, stringio_iternext}, + {Py_tp_methods, stringio_methods}, + {Py_tp_members, stringio_members}, + {Py_tp_getset, stringio_getset}, + {Py_tp_init, _io_StringIO___init__}, + {Py_tp_new, stringio_new}, + {0, NULL}, +}; + +PyType_Spec stringio_spec = { + .name = "_io.StringIO", + .basicsize = sizeof(stringio), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = stringio_slots, }; diff --git a/Modules/_io/textio.c b/Modules/_io/textio.c index 6cb5a686..e8bf6beb 100644 --- a/Modules/_io/textio.c +++ b/Modules/_io/textio.c @@ -18,10 +18,18 @@ /*[clinic input] module _io -class _io.IncrementalNewlineDecoder "nldecoder_object *" "&PyIncrementalNewlineDecoder_Type" -class _io.TextIOWrapper "textio *" "&TextIOWrapper_Type" +class _io.IncrementalNewlineDecoder "nldecoder_object *" "clinic_state()->PyIncrementalNewlineDecoder_Type" +class _io.TextIOWrapper "textio *" "clinic_state()->TextIOWrapper_Type" +class _io._TextIOBase "PyObject *" "&PyTextIOBase_Type" [clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=ed072384f8aada2c]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=8b7f24fa13bfdd7f]*/ + +typedef struct nldecoder_object nldecoder_object; +typedef struct textio textio; + +#define clinic_state() (find_io_state_by_def(Py_TYPE(self))) +#include "clinic/textio.c.h" +#undef clinic_state /* TextIOBase */ @@ -34,62 +42,91 @@ PyDoc_STRVAR(textiobase_doc, ); static PyObject * -_unsupported(const char *message) +_unsupported(_PyIO_State *state, const char *message) { - _PyIO_State *state = IO_STATE(); - if (state != NULL) - PyErr_SetString(state->unsupported_operation, message); + PyErr_SetString(state->unsupported_operation, message); return NULL; } -PyDoc_STRVAR(textiobase_detach_doc, - "Separate the underlying buffer from the TextIOBase and return it.\n" - "\n" - "After the underlying buffer has been detached, the TextIO is in an\n" - "unusable state.\n" - ); +/*[clinic input] +_io._TextIOBase.detach + cls: defining_class + / + +Separate the underlying buffer from the TextIOBase and return it. + +After the underlying buffer has been detached, the TextIO is in an unusable state. +[clinic start generated code]*/ static PyObject * -textiobase_detach(PyObject *self, PyObject *Py_UNUSED(ignored)) +_io__TextIOBase_detach_impl(PyObject *self, PyTypeObject *cls) +/*[clinic end generated code: output=50915f40c609eaa4 input=987ca3640d0a3776]*/ { - return _unsupported("detach"); + _PyIO_State *state = get_io_state_by_cls(cls); + return _unsupported(state, "detach"); } -PyDoc_STRVAR(textiobase_read_doc, - "Read at most n characters from stream.\n" - "\n" - "Read from underlying buffer until we have n characters or we hit EOF.\n" - "If n is negative or omitted, read until EOF.\n" - ); +/*[clinic input] +_io._TextIOBase.read + cls: defining_class + size: int(unused=True) = -1 + / + +Read at most size characters from stream. + +Read from underlying buffer until we have size characters or we hit EOF. +If size is negative or omitted, read until EOF. +[clinic start generated code]*/ static PyObject * -textiobase_read(PyObject *self, PyObject *args) +_io__TextIOBase_read_impl(PyObject *self, PyTypeObject *cls, + int Py_UNUSED(size)) +/*[clinic end generated code: output=51a5178a309ce647 input=f5e37720f9fc563f]*/ { - return _unsupported("read"); + _PyIO_State *state = get_io_state_by_cls(cls); + return _unsupported(state, "read"); } -PyDoc_STRVAR(textiobase_readline_doc, - "Read until newline or EOF.\n" - "\n" - "Returns an empty string if EOF is hit immediately.\n" - ); +/*[clinic input] +_io._TextIOBase.readline + cls: defining_class + size: int(unused=True) = -1 + / + +Read until newline or EOF. + +Return an empty string if EOF is hit immediately. +If size is specified, at most size characters will be read. +[clinic start generated code]*/ static PyObject * -textiobase_readline(PyObject *self, PyObject *args) +_io__TextIOBase_readline_impl(PyObject *self, PyTypeObject *cls, + int Py_UNUSED(size)) +/*[clinic end generated code: output=3f47d7966d6d074e input=42eafec94107fa27]*/ { - return _unsupported("readline"); + _PyIO_State *state = get_io_state_by_cls(cls); + return _unsupported(state, "readline"); } -PyDoc_STRVAR(textiobase_write_doc, - "Write string to stream.\n" - "Returns the number of characters written (which is always equal to\n" - "the length of the string).\n" - ); +/*[clinic input] +_io._TextIOBase.write + cls: defining_class + s: str(unused=True) + / + +Write string s to stream. + +Return the number of characters written +(which is always equal to the length of the string). +[clinic start generated code]*/ static PyObject * -textiobase_write(PyObject *self, PyObject *args) +_io__TextIOBase_write_impl(PyObject *self, PyTypeObject *cls, + const char *Py_UNUSED(s)) +/*[clinic end generated code: output=18b28231460275de input=e9cabaa5f6732b07]*/ { - return _unsupported("write"); + _PyIO_State *state = get_io_state_by_cls(cls); + return _unsupported(state, "write"); } PyDoc_STRVAR(textiobase_encoding_doc, @@ -132,10 +169,10 @@ textiobase_errors_get(PyObject *self, void *context) static PyMethodDef textiobase_methods[] = { - {"detach", textiobase_detach, METH_NOARGS, textiobase_detach_doc}, - {"read", textiobase_read, METH_VARARGS, textiobase_read_doc}, - {"readline", textiobase_readline, METH_VARARGS, textiobase_readline_doc}, - {"write", textiobase_write, METH_VARARGS, textiobase_write_doc}, + _IO__TEXTIOBASE_DETACH_METHODDEF + _IO__TEXTIOBASE_READ_METHODDEF + _IO__TEXTIOBASE_READLINE_METHODDEF + _IO__TEXTIOBASE_WRITE_METHODDEF {NULL, NULL} }; @@ -146,73 +183,36 @@ static PyGetSetDef textiobase_getset[] = { {NULL} }; -PyTypeObject PyTextIOBase_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_io._TextIOBase", /*tp_name*/ - 0, /*tp_basicsize*/ - 0, /*tp_itemsize*/ - 0, /*tp_dealloc*/ - 0, /*tp_vectorcall_offset*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_as_async*/ - 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*/ - textiobase_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - textiobase_methods, /* tp_methods */ - 0, /* tp_members */ - textiobase_getset, /* tp_getset */ - &PyIOBase_Type, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ - 0, /* tp_free */ - 0, /* tp_is_gc */ - 0, /* tp_bases */ - 0, /* tp_mro */ - 0, /* tp_cache */ - 0, /* tp_subclasses */ - 0, /* tp_weaklist */ - 0, /* tp_del */ - 0, /* tp_version_tag */ - 0, /* tp_finalize */ +static PyType_Slot textiobase_slots[] = { + {Py_tp_doc, (void *)textiobase_doc}, + {Py_tp_methods, textiobase_methods}, + {Py_tp_getset, textiobase_getset}, + {0, NULL}, }; +/* Do not set Py_TPFLAGS_HAVE_GC so that tp_traverse and tp_clear are inherited */ +PyType_Spec textiobase_spec = { + .name = "_io._TextIOBase", + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = textiobase_slots, +}; /* IncrementalNewlineDecoder */ -typedef struct { +struct nldecoder_object { PyObject_HEAD PyObject *decoder; PyObject *errors; unsigned int pendingcr: 1; unsigned int translate: 1; unsigned int seennl: 3; -} nldecoder_object; +}; /*[clinic input] _io.IncrementalNewlineDecoder.__init__ decoder: object - translate: int + translate: bool errors: object(c_default="NULL") = "strict" Codec used when reading a file in universal newlines mode. @@ -229,7 +229,7 @@ static int _io_IncrementalNewlineDecoder___init___impl(nldecoder_object *self, PyObject *decoder, int translate, PyObject *errors) -/*[clinic end generated code: output=fbd04d443e764ec2 input=89db6b19c6b126bf]*/ +/*[clinic end generated code: output=fbd04d443e764ec2 input=ed547aa257616b0e]*/ { if (errors == NULL) { @@ -248,12 +248,32 @@ _io_IncrementalNewlineDecoder___init___impl(nldecoder_object *self, return 0; } -static void -incrementalnewlinedecoder_dealloc(nldecoder_object *self) +static int +incrementalnewlinedecoder_traverse(nldecoder_object *self, visitproc visit, + void *arg) +{ + Py_VISIT(Py_TYPE(self)); + Py_VISIT(self->decoder); + Py_VISIT(self->errors); + return 0; +} + +static int +incrementalnewlinedecoder_clear(nldecoder_object *self) { Py_CLEAR(self->decoder); Py_CLEAR(self->errors); - Py_TYPE(self)->tp_free((PyObject *)self); + return 0; +} + +static void +incrementalnewlinedecoder_dealloc(nldecoder_object *self) +{ + PyTypeObject *tp = Py_TYPE(self); + _PyObject_GC_UNTRACK(self); + (void)incrementalnewlinedecoder_clear(self); + tp->tp_free((PyObject *)self); + Py_DECREF(tp); } static int @@ -303,8 +323,7 @@ _PyIncrementalNewlineDecoder_decode(PyObject *myself, &_Py_ID(decode), input, final ? Py_True : Py_False, NULL); } else { - output = input; - Py_INCREF(output); + output = Py_NewRef(input); } if (check_decoded(output) < 0) @@ -325,8 +344,7 @@ _PyIncrementalNewlineDecoder_decode(PyObject *myself, out = PyUnicode_DATA(modified); PyUnicode_WRITE(kind, out, 0, '\r'); memcpy(out + kind, PyUnicode_DATA(output), kind * output_len); - Py_DECREF(output); - output = modified; /* output remains ready */ + Py_SETREF(output, modified); /* output remains ready */ self->pendingcr = 0; output_len++; } @@ -341,8 +359,7 @@ _PyIncrementalNewlineDecoder_decode(PyObject *myself, PyObject *modified = PyUnicode_Substring(output, 0, output_len -1); if (modified == NULL) goto error; - Py_DECREF(output); - output = modified; + Py_SETREF(output, modified); self->pendingcr = 1; } } @@ -487,13 +504,13 @@ _PyIncrementalNewlineDecoder_decode(PyObject *myself, /*[clinic input] _io.IncrementalNewlineDecoder.decode input: object - final: bool(accept={int}) = False + final: bool = False [clinic start generated code]*/ static PyObject * _io_IncrementalNewlineDecoder_decode_impl(nldecoder_object *self, PyObject *input, int final) -/*[clinic end generated code: output=0d486755bb37a66e input=a4ea97f26372d866]*/ +/*[clinic end generated code: output=0d486755bb37a66e input=90e223c70322c5cd]*/ { return _PyIncrementalNewlineDecoder_decode((PyObject *) self, input, final); } @@ -628,7 +645,7 @@ incrementalnewlinedecoder_newlines_get(nldecoder_object *self, void *context) typedef PyObject * (*encodefunc_t)(PyObject *, PyObject *); -typedef struct +struct textio { PyObject_HEAD int ok; /* initialized? */ @@ -685,7 +702,9 @@ typedef struct PyObject *weakreflist; PyObject *dict; -} textio; + + _PyIO_State *state; +}; static void textiowrapper_set_decoded_chars(textio *self, PyObject *chars); @@ -873,24 +892,25 @@ _textiowrapper_set_decoder(textio *self, PyObject *codec_info, return -1; if (self->readuniversal) { + _PyIO_State *state = self->state; PyObject *incrementalDecoder = PyObject_CallFunctionObjArgs( - (PyObject *)&PyIncrementalNewlineDecoder_Type, + (PyObject *)state->PyIncrementalNewlineDecoder_Type, self->decoder, self->readtranslate ? Py_True : Py_False, NULL); if (incrementalDecoder == NULL) return -1; - Py_CLEAR(self->decoder); - self->decoder = incrementalDecoder; + Py_XSETREF(self->decoder, incrementalDecoder); } return 0; } static PyObject* -_textiowrapper_decode(PyObject *decoder, PyObject *bytes, int eof) +_textiowrapper_decode(_PyIO_State *state, PyObject *decoder, PyObject *bytes, + int eof) { PyObject *chars; - if (Py_IS_TYPE(decoder, &PyIncrementalNewlineDecoder_Type)) + if (Py_IS_TYPE(decoder, state->PyIncrementalNewlineDecoder_Type)) chars = _PyIncrementalNewlineDecoder_decode(decoder, bytes, eof); else chars = PyObject_CallMethodObjArgs(decoder, &_Py_ID(decode), bytes, @@ -1027,8 +1047,8 @@ _io.TextIOWrapper.__init__ encoding: str(accept={str, NoneType}) = None errors: object = None newline: str(accept={str, NoneType}) = None - line_buffering: bool(accept={int}) = False - write_through: bool(accept={int}) = False + line_buffering: bool = False + write_through: bool = False Character and line based layer over a BufferedIOBase object, buffer. @@ -1065,7 +1085,7 @@ _io_TextIOWrapper___init___impl(textio *self, PyObject *buffer, const char *encoding, PyObject *errors, const char *newline, int line_buffering, int write_through) -/*[clinic end generated code: output=72267c0c01032ed2 input=72590963698f289b]*/ +/*[clinic end generated code: output=72267c0c01032ed2 input=e6cfaaaf6059d4f5]*/ { PyObject *raw, *codec_info = NULL; PyObject *res; @@ -1158,8 +1178,7 @@ _io_TextIOWrapper___init___impl(textio *self, PyObject *buffer, * of the partially constructed object (like self->encoding) */ - Py_INCREF(errors); - self->errors = errors; + self->errors = Py_NewRef(errors); self->chunk_size = 8192; self->line_buffering = line_buffering; self->write_through = write_through; @@ -1167,10 +1186,11 @@ _io_TextIOWrapper___init___impl(textio *self, PyObject *buffer, goto error; } - self->buffer = buffer; - Py_INCREF(buffer); + self->buffer = Py_NewRef(buffer); /* Build the decoder object */ + _PyIO_State *state = find_io_state_by_def(Py_TYPE(self)); + self->state = state; if (_textiowrapper_set_decoder(self, codec_info, PyUnicode_AsUTF8(errors)) != 0) goto error; @@ -1181,15 +1201,15 @@ _io_TextIOWrapper___init___impl(textio *self, PyObject *buffer, /* Finished sorting out the codec details */ Py_CLEAR(codec_info); - if (Py_IS_TYPE(buffer, &PyBufferedReader_Type) || - Py_IS_TYPE(buffer, &PyBufferedWriter_Type) || - Py_IS_TYPE(buffer, &PyBufferedRandom_Type)) + if (Py_IS_TYPE(buffer, state->PyBufferedReader_Type) || + Py_IS_TYPE(buffer, state->PyBufferedWriter_Type) || + Py_IS_TYPE(buffer, state->PyBufferedRandom_Type)) { if (_PyObject_LookupAttr(buffer, &_Py_ID(raw), &raw) < 0) goto error; /* Cache the raw FileIO object to speed up 'closed' checks */ if (raw != NULL) { - if (Py_IS_TYPE(raw, &PyFileIO_Type)) + if (Py_IS_TYPE(raw, state->PyFileIO_Type)) self->raw = raw; else Py_DECREF(raw); @@ -1294,9 +1314,8 @@ textiowrapper_change_encoding(textio *self, PyObject *encoding, } Py_DECREF(codec_info); - Py_INCREF(errors); Py_SETREF(self->encoding, encoding); - Py_SETREF(self->errors, errors); + Py_SETREF(self->errors, Py_NewRef(errors)); return _textiowrapper_fix_encoder_state(self); } @@ -1330,7 +1349,8 @@ _io_TextIOWrapper_reconfigure_impl(textio *self, PyObject *encoding, /* Check if something is in the read buffer */ if (self->decoded_chars != NULL) { if (encoding != Py_None || errors != Py_None || newline_obj != NULL) { - _unsupported("It is not possible to set the encoding or newline " + _unsupported(self->state, + "It is not possible to set the encoding or newline " "of stream after the first read"); return NULL; } @@ -1394,6 +1414,7 @@ textiowrapper_clear(textio *self) static void textiowrapper_dealloc(textio *self) { + PyTypeObject *tp = Py_TYPE(self); self->finalizing = 1; if (_PyIOBase_finalize((PyObject *) self) < 0) return; @@ -1401,13 +1422,15 @@ textiowrapper_dealloc(textio *self) _PyObject_GC_UNTRACK(self); if (self->weakreflist != NULL) PyObject_ClearWeakRefs((PyObject *)self); - textiowrapper_clear(self); - Py_TYPE(self)->tp_free((PyObject *)self); + (void)textiowrapper_clear(self); + tp->tp_free((PyObject *)self); + Py_DECREF(tp); } static int textiowrapper_traverse(textio *self, visitproc visit, void *arg) { + Py_VISIT(Py_TYPE(self)); Py_VISIT(self->buffer); Py_VISIT(self->encoding); Py_VISIT(self->encoder); @@ -1431,7 +1454,7 @@ textiowrapper_closed_get(textio *self, void *context); do { \ int r; \ PyObject *_res; \ - if (Py_IS_TYPE(self, &PyTextIOWrapper_Type)) { \ + if (Py_IS_TYPE(self, self->state->PyTextIOWrapper_Type)) { \ if (self->raw != NULL) \ r = _PyFileIO_closed(self->raw); \ else { \ @@ -1512,8 +1535,7 @@ _textiowrapper_writeflush(textio *self) PyObject *b; if (PyBytes_Check(pending)) { - b = pending; - Py_INCREF(b); + b = Py_NewRef(pending); } else if (PyUnicode_Check(pending)) { assert(PyUnicode_IS_ASCII(pending)); @@ -1595,8 +1617,9 @@ _io_TextIOWrapper_write_impl(textio *self, PyObject *text) CHECK_ATTACHED(self); CHECK_CLOSED(self); - if (self->encoder == NULL) - return _unsupported("not writable"); + if (self->encoder == NULL) { + return _unsupported(self->state, "not writable"); + } Py_INCREF(text); @@ -1628,8 +1651,7 @@ _io_TextIOWrapper_write_impl(textio *self, PyObject *text) // See bpo-43260 PyUnicode_GET_LENGTH(text) <= self->chunk_size && is_asciicompat_encoding(self->encodefunc)) { - b = text; - Py_INCREF(b); + b = Py_NewRef(text); } else { b = (*self->encodefunc)((PyObject *) self, text); @@ -1751,8 +1773,7 @@ textiowrapper_get_decoded_chars(textio *self, Py_ssize_t n) return NULL; } else { - chars = self->decoded_chars; - Py_INCREF(chars); + chars = Py_NewRef(self->decoded_chars); } self->decoded_chars_used += n; @@ -1779,7 +1800,7 @@ textiowrapper_read_chunk(textio *self, Py_ssize_t size_hint) */ if (self->decoder == NULL) { - _unsupported("not readable"); + _unsupported(self->state, "not readable"); return -1; } @@ -1846,7 +1867,8 @@ textiowrapper_read_chunk(textio *self, Py_ssize_t size_hint) nbytes = input_chunk_buf.len; eof = (nbytes == 0); - decoded_chars = _textiowrapper_decode(self->decoder, input_chunk, eof); + decoded_chars = _textiowrapper_decode(self->state, self->decoder, + input_chunk, eof); PyBuffer_Release(&input_chunk_buf); if (decoded_chars == NULL) goto fail; @@ -1903,8 +1925,9 @@ _io_TextIOWrapper_read_impl(textio *self, Py_ssize_t n) CHECK_ATTACHED(self); CHECK_CLOSED(self); - if (self->decoder == NULL) - return _unsupported("not readable"); + if (self->decoder == NULL) { + return _unsupported(self->state, "not readable"); + } if (_textiowrapper_writeflush(self) < 0) return NULL; @@ -1916,7 +1939,8 @@ _io_TextIOWrapper_read_impl(textio *self, Py_ssize_t n) if (bytes == NULL) goto fail; - if (Py_IS_TYPE(self->decoder, &PyIncrementalNewlineDecoder_Type)) + _PyIO_State *state = self->state; + if (Py_IS_TYPE(self->decoder, state->PyIncrementalNewlineDecoder_Type)) decoded = _PyIncrementalNewlineDecoder_decode(self->decoder, bytes, 1); else @@ -2149,10 +2173,9 @@ _textiowrapper_readline(textio *self, Py_ssize_t limit) } if (remaining == NULL) { - line = self->decoded_chars; + line = Py_NewRef(self->decoded_chars); start = self->decoded_chars_used; offset_to_buffer = 0; - Py_INCREF(line); } else { assert(self->decoded_chars_used == 0); @@ -2415,13 +2438,29 @@ _textiowrapper_encoder_setstate(textio *self, cookie_type *cookie) /*[clinic input] _io.TextIOWrapper.seek cookie as cookieObj: object - whence: int = 0 + Zero or an opaque number returned by tell(). + whence: int(c_default='0') = os.SEEK_SET + The relative position to seek from. / + +Set the stream position, and return the new stream position. + +Four operations are supported, given by the following argument +combinations: + +- seek(0, SEEK_SET): Rewind to the start of the stream. +- seek(cookie, SEEK_SET): Restore a previous position; + 'cookie' must be a number returned by tell(). +- seek(0, SEEK_END): Fast-forward to the end of the stream. +- seek(0, SEEK_CUR): Leave the current stream position unchanged. + +Any other argument combinations are invalid, +and may raise exceptions. [clinic start generated code]*/ static PyObject * _io_TextIOWrapper_seek_impl(textio *self, PyObject *cookieObj, int whence) -/*[clinic end generated code: output=0a15679764e2d04d input=0458abeb3d7842be]*/ +/*[clinic end generated code: output=0a15679764e2d04d input=0f68adcb02cf2823]*/ { PyObject *posobj; cookie_type cookie; @@ -2435,7 +2474,7 @@ _io_TextIOWrapper_seek_impl(textio *self, PyObject *cookieObj, int whence) Py_INCREF(cookieObj); if (!self->seekable) { - _unsupported("underlying stream is not seekable"); + _unsupported(self->state, "underlying stream is not seekable"); goto fail; } @@ -2449,7 +2488,7 @@ _io_TextIOWrapper_seek_impl(textio *self, PyObject *cookieObj, int whence) goto fail; if (cmp == 0) { - _unsupported("can't do nonzero cur-relative seeks"); + _unsupported(self->state, "can't do nonzero cur-relative seeks"); goto fail; } @@ -2469,7 +2508,7 @@ _io_TextIOWrapper_seek_impl(textio *self, PyObject *cookieObj, int whence) goto fail; if (cmp == 0) { - _unsupported("can't do nonzero end-relative seeks"); + _unsupported(self->state, "can't do nonzero end-relative seeks"); goto fail; } @@ -2611,11 +2650,16 @@ _io_TextIOWrapper_seek_impl(textio *self, PyObject *cookieObj, int whence) /*[clinic input] _io.TextIOWrapper.tell + +Return the stream position as an opaque number. + +The return value of tell() can be given as input to seek(), to restore a +previous stream position. [clinic start generated code]*/ static PyObject * _io_TextIOWrapper_tell_impl(textio *self) -/*[clinic end generated code: output=4f168c08bf34ad5f input=9a2caf88c24f9ddf]*/ +/*[clinic end generated code: output=4f168c08bf34ad5f input=0852d627d76fb520]*/ { PyObject *res; PyObject *posobj = NULL; @@ -2632,7 +2676,7 @@ _io_TextIOWrapper_tell_impl(textio *self) CHECK_CLOSED(self); if (!self->seekable) { - _unsupported("underlying stream is not seekable"); + _unsupported(self->state, "underlying stream is not seekable"); goto fail; } if (!self->telling) { @@ -2831,11 +2875,10 @@ finally: fail: if (saved_state) { - PyObject *type, *value, *traceback; - PyErr_Fetch(&type, &value, &traceback); + PyObject *exc = PyErr_GetRaisedException(); res = PyObject_CallMethodOneArg( self->decoder, &_Py_ID(setstate), saved_state); - _PyErr_ChainExceptions(type, value, traceback); + _PyErr_ChainExceptions1(exc); Py_DECREF(saved_state); Py_XDECREF(res); } @@ -3032,24 +3075,28 @@ _io_TextIOWrapper_close_impl(textio *self) Py_RETURN_NONE; /* stream already closed */ } else { - PyObject *exc = NULL, *val, *tb; + PyObject *exc = NULL; if (self->finalizing) { res = PyObject_CallMethodOneArg(self->buffer, &_Py_ID(_dealloc_warn), (PyObject *)self); - if (res) + if (res) { Py_DECREF(res); - else + } + else { PyErr_Clear(); + } } res = PyObject_CallMethodNoArgs((PyObject *)self, &_Py_ID(flush)); - if (res == NULL) - PyErr_Fetch(&exc, &val, &tb); - else + if (res == NULL) { + exc = PyErr_GetRaisedException(); + } + else { Py_DECREF(res); + } res = PyObject_CallMethodNoArgs(self->buffer, &_Py_ID(close)); if (exc != NULL) { - _PyErr_ChainExceptions(exc, val, tb); + _PyErr_ChainExceptions1(exc); Py_CLEAR(res); } return res; @@ -3064,7 +3111,7 @@ textiowrapper_iternext(textio *self) CHECK_ATTACHED(self); self->telling = 0; - if (Py_IS_TYPE(self, &PyTextIOWrapper_Type)) { + if (Py_IS_TYPE(self, self->state->PyTextIOWrapper_Type)) { /* Skip method call overhead for speed */ line = _textiowrapper_readline(self, -1); } @@ -3125,8 +3172,7 @@ static PyObject * textiowrapper_errors_get(textio *self, void *context) { CHECK_INITIALIZED(self); - Py_INCREF(self->errors); - return self->errors; + return Py_NewRef(self->errors); } static PyObject * @@ -3157,8 +3203,6 @@ textiowrapper_chunk_size_set(textio *self, PyObject *arg, void *context) return 0; } -#include "clinic/textio.c.h" - static PyMethodDef incrementalnewlinedecoder_methods[] = { _IO_INCREMENTALNEWLINEDECODER_DECODE_METHODDEF _IO_INCREMENTALNEWLINEDECODER_GETSTATE_METHODDEF @@ -3172,45 +3216,23 @@ static PyGetSetDef incrementalnewlinedecoder_getset[] = { {NULL} }; -PyTypeObject PyIncrementalNewlineDecoder_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_io.IncrementalNewlineDecoder", /*tp_name*/ - sizeof(nldecoder_object), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - (destructor)incrementalnewlinedecoder_dealloc, /*tp_dealloc*/ - 0, /*tp_vectorcall_offset*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_as_async*/ - 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*/ - _io_IncrementalNewlineDecoder___init____doc__, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /*tp_weaklistoffset*/ - 0, /* tp_iter */ - 0, /* tp_iternext */ - incrementalnewlinedecoder_methods, /* tp_methods */ - 0, /* tp_members */ - incrementalnewlinedecoder_getset, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - _io_IncrementalNewlineDecoder___init__, /* tp_init */ - 0, /* tp_alloc */ - PyType_GenericNew, /* tp_new */ +static PyType_Slot nldecoder_slots[] = { + {Py_tp_dealloc, incrementalnewlinedecoder_dealloc}, + {Py_tp_doc, (void *)_io_IncrementalNewlineDecoder___init____doc__}, + {Py_tp_methods, incrementalnewlinedecoder_methods}, + {Py_tp_getset, incrementalnewlinedecoder_getset}, + {Py_tp_traverse, incrementalnewlinedecoder_traverse}, + {Py_tp_clear, incrementalnewlinedecoder_clear}, + {Py_tp_init, _io_IncrementalNewlineDecoder___init__}, + {0, NULL}, +}; + +PyType_Spec nldecoder_spec = { + .name = "_io.IncrementalNewlineDecoder", + .basicsize = sizeof(nldecoder_object), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = nldecoder_slots, }; @@ -3232,6 +3254,9 @@ static PyMethodDef textiowrapper_methods[] = { _IO_TEXTIOWRAPPER_SEEK_METHODDEF _IO_TEXTIOWRAPPER_TELL_METHODDEF _IO_TEXTIOWRAPPER_TRUNCATE_METHODDEF + + {"__reduce__", _PyIOBase_cannot_pickle, METH_VARARGS}, + {"__reduce_ex__", _PyIOBase_cannot_pickle, METH_VARARGS}, {NULL, NULL} }; @@ -3241,6 +3266,8 @@ static PyMemberDef textiowrapper_members[] = { {"line_buffering", T_BOOL, offsetof(textio, line_buffering), READONLY}, {"write_through", T_BOOL, offsetof(textio, write_through), READONLY}, {"_finalizing", T_BOOL, offsetof(textio, finalizing), 0}, + {"__weaklistoffset__", T_PYSSIZET, offsetof(textio, weakreflist), READONLY}, + {"__dictoffset__", T_PYSSIZET, offsetof(textio, dict), READONLY}, {NULL} }; @@ -3256,54 +3283,24 @@ static PyGetSetDef textiowrapper_getset[] = { {NULL} }; -PyTypeObject PyTextIOWrapper_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_io.TextIOWrapper", /*tp_name*/ - sizeof(textio), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - (destructor)textiowrapper_dealloc, /*tp_dealloc*/ - 0, /*tp_vectorcall_offset*/ - 0, /*tp_getattr*/ - 0, /*tps_etattr*/ - 0, /*tp_as_async*/ - (reprfunc)textiowrapper_repr,/*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 - | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ - _io_TextIOWrapper___init____doc__, /* tp_doc */ - (traverseproc)textiowrapper_traverse, /* tp_traverse */ - (inquiry)textiowrapper_clear, /* tp_clear */ - 0, /* tp_richcompare */ - offsetof(textio, weakreflist), /*tp_weaklistoffset*/ - 0, /* tp_iter */ - (iternextfunc)textiowrapper_iternext, /* tp_iternext */ - textiowrapper_methods, /* tp_methods */ - textiowrapper_members, /* tp_members */ - textiowrapper_getset, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - offsetof(textio, dict), /*tp_dictoffset*/ - _io_TextIOWrapper___init__, /* tp_init */ - 0, /* tp_alloc */ - PyType_GenericNew, /* tp_new */ - 0, /* tp_free */ - 0, /* tp_is_gc */ - 0, /* tp_bases */ - 0, /* tp_mro */ - 0, /* tp_cache */ - 0, /* tp_subclasses */ - 0, /* tp_weaklist */ - 0, /* tp_del */ - 0, /* tp_version_tag */ - 0, /* tp_finalize */ +PyType_Slot textiowrapper_slots[] = { + {Py_tp_dealloc, textiowrapper_dealloc}, + {Py_tp_repr, textiowrapper_repr}, + {Py_tp_doc, (void *)_io_TextIOWrapper___init____doc__}, + {Py_tp_traverse, textiowrapper_traverse}, + {Py_tp_clear, textiowrapper_clear}, + {Py_tp_iternext, textiowrapper_iternext}, + {Py_tp_methods, textiowrapper_methods}, + {Py_tp_members, textiowrapper_members}, + {Py_tp_getset, textiowrapper_getset}, + {Py_tp_init, _io_TextIOWrapper___init__}, + {0, NULL}, +}; + +PyType_Spec textiowrapper_spec = { + .name = "_io.TextIOWrapper", + .basicsize = sizeof(textio), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = textiowrapper_slots, }; diff --git a/Modules/_io/winconsoleio.c b/Modules/_io/winconsoleio.c index c8f3481e..7c6f2263 100644 --- a/Modules/_io/winconsoleio.c +++ b/Modules/_io/winconsoleio.c @@ -11,7 +11,7 @@ #include "pycore_fileutils.h" // _Py_BEGIN_SUPPRESS_IPH #include "pycore_object.h" // _PyObject_GC_UNTRACK() -#ifdef MS_WINDOWS +#ifdef HAVE_WINDOWS_CONSOLE_IO #include "structmember.h" // PyMemberDef #ifdef HAVE_SYS_TYPES_H @@ -22,7 +22,9 @@ #endif #include <stddef.h> /* For offsetof */ +#ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN +#endif #include <windows.h> #include <fcntl.h> @@ -135,9 +137,9 @@ char _PyIO_get_console_type(PyObject *path_or_fd) { /*[clinic input] module _io -class _io._WindowsConsoleIO "winconsoleio *" "&PyWindowsConsoleIO_Type" +class _io._WindowsConsoleIO "winconsoleio *" "clinic_state()->PyWindowsConsoleIO_Type" [clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=e897fdc1fba4e131]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=05526e723011ab36]*/ typedef struct { PyObject_HEAD @@ -154,8 +156,6 @@ typedef struct { wchar_t wbuf; } winconsoleio; -PyTypeObject PyWindowsConsoleIO_Type; - int _PyWindowsConsoleIO_closed(PyObject *self) { @@ -180,6 +180,8 @@ internal_close(winconsoleio *self) /*[clinic input] _io._WindowsConsoleIO.close + cls: defining_class + / Close the console object. @@ -188,25 +190,30 @@ close() may be called more than once without error. [clinic start generated code]*/ static PyObject * -_io__WindowsConsoleIO_close_impl(winconsoleio *self) -/*[clinic end generated code: output=27ef95b66c29057b input=68c4e5754f8136c2]*/ +_io__WindowsConsoleIO_close_impl(winconsoleio *self, PyTypeObject *cls) +/*[clinic end generated code: output=e50c1808c063e1e2 input=161001bd2a649a4b]*/ { PyObject *res; - PyObject *exc, *val, *tb; + PyObject *exc; int rc; - res = PyObject_CallMethodOneArg((PyObject*)&PyRawIOBase_Type, + + _PyIO_State *state = get_io_state_by_cls(cls); + res = PyObject_CallMethodOneArg((PyObject*)state->PyRawIOBase_Type, &_Py_ID(close), (PyObject*)self); if (!self->closefd) { self->fd = -1; return res; } - if (res == NULL) - PyErr_Fetch(&exc, &val, &tb); + if (res == NULL) { + exc = PyErr_GetRaisedException(); + } rc = internal_close(self); - if (res == NULL) - _PyErr_ChainExceptions(exc, val, tb); - if (rc < 0) + if (res == NULL) { + _PyErr_ChainExceptions1(exc); + } + if (rc < 0) { Py_CLEAR(res); + } return res; } @@ -235,7 +242,7 @@ winconsoleio_new(PyTypeObject *type, PyObject *args, PyObject *kwds) _io._WindowsConsoleIO.__init__ file as nameobj: object mode: str = "r" - closefd: bool(accept={int}) = True + closefd: bool = True opener: object = None Open a console buffer by file descriptor. @@ -249,7 +256,7 @@ static int _io__WindowsConsoleIO___init___impl(winconsoleio *self, PyObject *nameobj, const char *mode, int closefd, PyObject *opener) -/*[clinic end generated code: output=3fd9cbcdd8d95429 input=06ae4b863c63244b]*/ +/*[clinic end generated code: output=3fd9cbcdd8d95429 input=7a3eed6bbe998fd9]*/ { const char *s; wchar_t *name = NULL; @@ -260,7 +267,10 @@ _io__WindowsConsoleIO___init___impl(winconsoleio *self, PyObject *nameobj, int fd_is_own = 0; HANDLE handle = NULL; - assert(PyWindowsConsoleIO_Check(self)); +#ifndef NDEBUG + _PyIO_State *state = find_io_state_by_def(Py_TYPE(self)); + assert(PyObject_TypeCheck(self, state->PyWindowsConsoleIO_Type)); +#endif if (self->fd >= 0) { if (self->closefd) { /* Have to close the existing file first. */ @@ -368,8 +378,8 @@ _io__WindowsConsoleIO___init___impl(winconsoleio *self, PyObject *nameobj, else self->fd = _Py_open_osfhandle_noraise(handle, _O_RDONLY | _O_BINARY); if (self->fd < 0) { - CloseHandle(handle); PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, nameobj); + CloseHandle(handle); goto error; } } @@ -412,6 +422,7 @@ done: static int winconsoleio_traverse(winconsoleio *self, visitproc visit, void *arg) { + Py_VISIT(Py_TYPE(self)); Py_VISIT(self->dict); return 0; } @@ -426,6 +437,7 @@ winconsoleio_clear(winconsoleio *self) static void winconsoleio_dealloc(winconsoleio *self) { + PyTypeObject *tp = Py_TYPE(self); self->finalizing = 1; if (_PyIOBase_finalize((PyObject *) self) < 0) return; @@ -433,7 +445,8 @@ winconsoleio_dealloc(winconsoleio *self) if (self->weakreflist != NULL) PyObject_ClearWeakRefs((PyObject *) self); Py_CLEAR(self->dict); - Py_TYPE(self)->tp_free((PyObject *)self); + tp->tp_free((PyObject *)self); + Py_DECREF(tp); } static PyObject * @@ -444,13 +457,10 @@ err_closed(void) } static PyObject * -err_mode(const char *action) +err_mode(_PyIO_State *state, const char *action) { - _PyIO_State *state = IO_STATE(); - if (state != NULL) - PyErr_Format(state->unsupported_operation, - "Console buffer does not support %s", action); - return NULL; + return PyErr_Format(state->unsupported_operation, + "Console buffer does not support %s", action); } /*[clinic input] @@ -627,14 +637,14 @@ error: static Py_ssize_t -readinto(winconsoleio *self, char *buf, Py_ssize_t len) +readinto(_PyIO_State *state, winconsoleio *self, char *buf, Py_ssize_t len) { if (self->fd == -1) { err_closed(); return -1; } if (!self->readable) { - err_mode("reading"); + err_mode(state, "reading"); return -1; } if (len == 0) @@ -724,6 +734,7 @@ readinto(winconsoleio *self, char *buf, Py_ssize_t len) /*[clinic input] _io._WindowsConsoleIO.readinto + cls: defining_class buffer: Py_buffer(accept={rwbuffer}) / @@ -731,10 +742,12 @@ Same as RawIOBase.readinto(). [clinic start generated code]*/ static PyObject * -_io__WindowsConsoleIO_readinto_impl(winconsoleio *self, Py_buffer *buffer) -/*[clinic end generated code: output=66d1bdfa3f20af39 input=4ed68da48a6baffe]*/ +_io__WindowsConsoleIO_readinto_impl(winconsoleio *self, PyTypeObject *cls, + Py_buffer *buffer) +/*[clinic end generated code: output=96717c74f6204b79 input=4b0627c3b1645f78]*/ { - Py_ssize_t len = readinto(self, buffer->buf, buffer->len); + _PyIO_State *state = get_io_state_by_cls(cls); + Py_ssize_t len = readinto(state, self, buffer->buf, buffer->len); if (len < 0) return NULL; @@ -888,6 +901,7 @@ _io__WindowsConsoleIO_readall_impl(winconsoleio *self) /*[clinic input] _io._WindowsConsoleIO.read + cls: defining_class size: Py_ssize_t(accept={int, NoneType}) = -1 / @@ -899,16 +913,19 @@ Return an empty bytes object at EOF. [clinic start generated code]*/ static PyObject * -_io__WindowsConsoleIO_read_impl(winconsoleio *self, Py_ssize_t size) -/*[clinic end generated code: output=57df68af9f4b22d0 input=8bc73bc15d0fa072]*/ +_io__WindowsConsoleIO_read_impl(winconsoleio *self, PyTypeObject *cls, + Py_ssize_t size) +/*[clinic end generated code: output=7e569a586537c0ae input=a14570a5da273365]*/ { PyObject *bytes; Py_ssize_t bytes_size; if (self->fd == -1) return err_closed(); - if (!self->readable) - return err_mode("reading"); + if (!self->readable) { + _PyIO_State *state = get_io_state_by_cls(cls); + return err_mode(state, "reading"); + } if (size < 0) return _io__WindowsConsoleIO_readall_impl(self); @@ -921,7 +938,9 @@ _io__WindowsConsoleIO_read_impl(winconsoleio *self, Py_ssize_t size) if (bytes == NULL) return NULL; - bytes_size = readinto(self, PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes)); + _PyIO_State *state = get_io_state_by_cls(cls); + bytes_size = readinto(state, self, PyBytes_AS_STRING(bytes), + PyBytes_GET_SIZE(bytes)); if (bytes_size < 0) { Py_CLEAR(bytes); return NULL; @@ -939,6 +958,7 @@ _io__WindowsConsoleIO_read_impl(winconsoleio *self, Py_ssize_t size) /*[clinic input] _io._WindowsConsoleIO.write + cls: defining_class b: Py_buffer / @@ -949,8 +969,9 @@ The number of bytes actually written is returned. [clinic start generated code]*/ static PyObject * -_io__WindowsConsoleIO_write_impl(winconsoleio *self, Py_buffer *b) -/*[clinic end generated code: output=775bdb16fbf9137b input=be35fb624f97c941]*/ +_io__WindowsConsoleIO_write_impl(winconsoleio *self, PyTypeObject *cls, + Py_buffer *b) +/*[clinic end generated code: output=e8019f480243cb29 input=10ac37c19339dfbe]*/ { BOOL res = TRUE; wchar_t *wbuf; @@ -959,8 +980,10 @@ _io__WindowsConsoleIO_write_impl(winconsoleio *self, Py_buffer *b) if (self->fd == -1) return err_closed(); - if (!self->writable) - return err_mode("writing"); + if (!self->writable) { + _PyIO_State *state = get_io_state_by_cls(cls); + return err_mode(state, "writing"); + } handle = _Py_get_osfhandle(self->fd); if (handle == INVALID_HANDLE_VALUE) @@ -1073,7 +1096,9 @@ _io__WindowsConsoleIO_isatty_impl(winconsoleio *self) Py_RETURN_TRUE; } +#define clinic_state() (find_io_state_by_def(Py_TYPE(self))) #include "clinic/winconsoleio.c.h" +#undef clinic_state static PyMethodDef winconsoleio_methods[] = { _IO__WINDOWSCONSOLEIO_READ_METHODDEF @@ -1119,61 +1144,32 @@ static PyGetSetDef winconsoleio_getsetlist[] = { static PyMemberDef winconsoleio_members[] = { {"_blksize", T_UINT, offsetof(winconsoleio, blksize), 0}, {"_finalizing", T_BOOL, offsetof(winconsoleio, finalizing), 0}, + {"__weaklistoffset__", T_PYSSIZET, offsetof(winconsoleio, weakreflist), READONLY}, + {"__dictoffset__", T_PYSSIZET, offsetof(winconsoleio, dict), READONLY}, {NULL} }; -PyTypeObject PyWindowsConsoleIO_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_io._WindowsConsoleIO", - sizeof(winconsoleio), - 0, - (destructor)winconsoleio_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - (reprfunc)winconsoleio_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE - | Py_TPFLAGS_HAVE_GC, /* tp_flags */ - _io__WindowsConsoleIO___init____doc__, /* tp_doc */ - (traverseproc)winconsoleio_traverse, /* tp_traverse */ - (inquiry)winconsoleio_clear, /* tp_clear */ - 0, /* tp_richcompare */ - offsetof(winconsoleio, weakreflist), /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - winconsoleio_methods, /* tp_methods */ - winconsoleio_members, /* tp_members */ - winconsoleio_getsetlist, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - offsetof(winconsoleio, dict), /* tp_dictoffset */ - _io__WindowsConsoleIO___init__, /* tp_init */ - PyType_GenericAlloc, /* tp_alloc */ - winconsoleio_new, /* tp_new */ - PyObject_GC_Del, /* tp_free */ - 0, /* tp_is_gc */ - 0, /* tp_bases */ - 0, /* tp_mro */ - 0, /* tp_cache */ - 0, /* tp_subclasses */ - 0, /* tp_weaklist */ - 0, /* tp_del */ - 0, /* tp_version_tag */ - 0, /* tp_finalize */ +static PyType_Slot winconsoleio_slots[] = { + {Py_tp_dealloc, winconsoleio_dealloc}, + {Py_tp_repr, winconsoleio_repr}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_doc, (void *)_io__WindowsConsoleIO___init____doc__}, + {Py_tp_traverse, winconsoleio_traverse}, + {Py_tp_clear, winconsoleio_clear}, + {Py_tp_methods, winconsoleio_methods}, + {Py_tp_members, winconsoleio_members}, + {Py_tp_getset, winconsoleio_getsetlist}, + {Py_tp_init, _io__WindowsConsoleIO___init__}, + {Py_tp_new, winconsoleio_new}, + {0, NULL}, }; -PyObject * _PyWindowsConsoleIO_Type = (PyObject*)&PyWindowsConsoleIO_Type; +PyType_Spec winconsoleio_spec = { + .name = "_io._WindowsConsoleIO", + .basicsize = sizeof(winconsoleio), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = winconsoleio_slots, +}; -#endif /* MS_WINDOWS */ +#endif /* HAVE_WINDOWS_CONSOLE_IO */ diff --git a/Modules/_json.c b/Modules/_json.c index 9464b9f4..c90de05b 100644 --- a/Modules/_json.c +++ b/Modules/_json.c @@ -7,25 +7,13 @@ #ifndef Py_BUILD_CORE_BUILTIN # define Py_BUILD_CORE_MODULE 1 #endif -#define NEEDS_PY_IDENTIFIER #include "Python.h" -#include "pycore_ceval.h" // _Py_EnterRecursiveCall() -#include "structmember.h" // PyMemberDef -#include "pycore_accu.h" - -typedef struct { - PyObject *PyScannerType; - PyObject *PyEncoderType; -} _jsonmodulestate; - -static inline _jsonmodulestate* -get_json_state(PyObject *module) -{ - void *state = PyModule_GetState(module); - assert(state != NULL); - return (_jsonmodulestate *)state; -} +#include "pycore_ceval.h" // _Py_EnterRecursiveCall() +#include "pycore_runtime.h" // _PyRuntime +#include "structmember.h" // PyMemberDef +#include "pycore_global_objects.h" // _Py_ID() +#include <stdbool.h> // bool typedef struct _PyScannerObject { @@ -98,11 +86,11 @@ encoder_dealloc(PyObject *self); static int encoder_clear(PyEncoderObject *self); static int -encoder_listencode_list(PyEncoderObject *s, _PyAccu *acc, PyObject *seq, Py_ssize_t indent_level); +encoder_listencode_list(PyEncoderObject *s, _PyUnicodeWriter *writer, PyObject *seq, Py_ssize_t indent_level); static int -encoder_listencode_obj(PyEncoderObject *s, _PyAccu *acc, PyObject *obj, Py_ssize_t indent_level); +encoder_listencode_obj(PyEncoderObject *s, _PyUnicodeWriter *writer, PyObject *obj, Py_ssize_t indent_level); static int -encoder_listencode_dict(PyEncoderObject *s, _PyAccu *acc, PyObject *dct, Py_ssize_t indent_level); +encoder_listencode_dict(PyEncoderObject *s, _PyUnicodeWriter *writer, PyObject *dct, Py_ssize_t indent_level); static PyObject * _encoded_const(PyObject *obj); static void @@ -318,15 +306,9 @@ static void raise_errmsg(const char *msg, PyObject *s, Py_ssize_t end) { /* Use JSONDecodeError exception to raise a nice looking ValueError subclass */ - _Py_static_string(PyId_decoder, "json.decoder"); - PyObject *decoder = _PyImport_GetModuleId(&PyId_decoder); - if (decoder == NULL) { - return; - } - - _Py_IDENTIFIER(JSONDecodeError); - PyObject *JSONDecodeError = _PyObject_GetAttrId(decoder, &PyId_JSONDecodeError); - Py_DECREF(decoder); + _Py_DECLARE_STR(json_decoder, "json.decoder"); + PyObject *JSONDecodeError = + _PyImport_GetModuleAttr(&_Py_STR(json_decoder), &_Py_ID(JSONDecodeError)); if (JSONDecodeError == NULL) { return; } @@ -574,7 +556,7 @@ py_scanstring(PyObject* Py_UNUSED(self), PyObject *args) Py_ssize_t end; Py_ssize_t next_end = -1; int strict = 1; - if (!PyArg_ParseTuple(args, "On|i:scanstring", &pystr, &end, &strict)) { + if (!PyArg_ParseTuple(args, "On|p:scanstring", &pystr, &end, &strict)) { return NULL; } if (PyUnicode_Check(pystr)) { @@ -727,9 +709,7 @@ _parse_object_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ss if (memokey == NULL) { goto bail; } - Py_INCREF(memokey); - Py_DECREF(key); - key = memokey; + Py_SETREF(key, Py_NewRef(memokey)); idx = next_idx; /* skip whitespace between key and : delimiter, read :, skip whitespace */ @@ -1261,16 +1241,17 @@ encoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds) if (s == NULL) return NULL; - s->markers = markers; - s->defaultfn = defaultfn; - s->encoder = encoder; - s->indent = indent; - s->key_separator = key_separator; - s->item_separator = item_separator; + s->markers = Py_NewRef(markers); + s->defaultfn = Py_NewRef(defaultfn); + s->encoder = Py_NewRef(encoder); + s->indent = Py_NewRef(indent); + s->key_separator = Py_NewRef(key_separator); + s->item_separator = Py_NewRef(item_separator); s->sort_keys = sort_keys; s->skipkeys = skipkeys; s->allow_nan = allow_nan; s->fast_encode = NULL; + if (PyCFunction_Check(s->encoder)) { PyCFunction f = PyCFunction_GetFunction(s->encoder); if (f == (PyCFunction)py_encode_basestring_ascii || @@ -1279,12 +1260,6 @@ encoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds) } } - Py_INCREF(s->markers); - Py_INCREF(s->defaultfn); - Py_INCREF(s->encoder); - Py_INCREF(s->indent); - Py_INCREF(s->key_separator); - Py_INCREF(s->item_separator); return (PyObject *)s; } @@ -1293,19 +1268,29 @@ encoder_call(PyEncoderObject *self, PyObject *args, PyObject *kwds) { /* Python callable interface to encode_listencode_obj */ static char *kwlist[] = {"obj", "_current_indent_level", NULL}; - PyObject *obj; + PyObject *obj, *result; Py_ssize_t indent_level; - _PyAccu acc; + _PyUnicodeWriter writer; + if (!PyArg_ParseTupleAndKeywords(args, kwds, "On:_iterencode", kwlist, &obj, &indent_level)) return NULL; - if (_PyAccu_Init(&acc)) + + _PyUnicodeWriter_Init(&writer); + writer.overallocate = 1; + + if (encoder_listencode_obj(self, &writer, obj, indent_level)) { + _PyUnicodeWriter_Dealloc(&writer); return NULL; - if (encoder_listencode_obj(self, &acc, obj, indent_level)) { - _PyAccu_Destroy(&acc); + } + + result = PyTuple_New(1); + if (result == NULL || + PyTuple_SetItem(result, 0, _PyUnicodeWriter_Finish(&writer)) < 0) { + Py_XDECREF(result); return NULL; } - return _PyAccu_FinishAsList(&acc); + return result; } static PyObject * @@ -1313,28 +1298,13 @@ _encoded_const(PyObject *obj) { /* Return the JSON string representation of None, True, False */ if (obj == Py_None) { - _Py_static_string(PyId_null, "null"); - PyObject *s_null = _PyUnicode_FromId(&PyId_null); - if (s_null == NULL) { - return NULL; - } - return Py_NewRef(s_null); + return Py_NewRef(&_Py_ID(null)); } else if (obj == Py_True) { - _Py_static_string(PyId_true, "true"); - PyObject *s_true = _PyUnicode_FromId(&PyId_true); - if (s_true == NULL) { - return NULL; - } - return Py_NewRef(s_true); + return Py_NewRef(&_Py_ID(true)); } else if (obj == Py_False) { - _Py_static_string(PyId_false, "false"); - PyObject *s_false = _PyUnicode_FromId(&PyId_false); - if (s_false == NULL) { - return NULL; - } - return Py_NewRef(s_false); + return Py_NewRef(&_Py_ID(false)); } else { PyErr_SetString(PyExc_ValueError, "not a const"); @@ -1349,9 +1319,10 @@ encoder_encode_float(PyEncoderObject *s, PyObject *obj) double i = PyFloat_AS_DOUBLE(obj); if (!Py_IS_FINITE(i)) { if (!s->allow_nan) { - PyErr_SetString( + PyErr_Format( PyExc_ValueError, - "Out of range float values are not JSON compliant" + "Out of range float values are not JSON compliant: %R", + obj ); return NULL; } @@ -1389,58 +1360,60 @@ encoder_encode_string(PyEncoderObject *s, PyObject *obj) } static int -_steal_accumulate(_PyAccu *acc, PyObject *stolen) +_steal_accumulate(_PyUnicodeWriter *writer, PyObject *stolen) { /* Append stolen and then decrement its reference count */ - int rval = _PyAccu_Accumulate(acc, stolen); + int rval = _PyUnicodeWriter_WriteStr(writer, stolen); Py_DECREF(stolen); return rval; } static int -encoder_listencode_obj(PyEncoderObject *s, _PyAccu *acc, +encoder_listencode_obj(PyEncoderObject *s, _PyUnicodeWriter *writer, PyObject *obj, Py_ssize_t indent_level) { /* Encode Python object obj to a JSON term */ PyObject *newobj; int rv; - if (obj == Py_None || obj == Py_True || obj == Py_False) { - PyObject *cstr = _encoded_const(obj); - if (cstr == NULL) - return -1; - return _steal_accumulate(acc, cstr); + if (obj == Py_None) { + return _PyUnicodeWriter_WriteASCIIString(writer, "null", 4); + } + else if (obj == Py_True) { + return _PyUnicodeWriter_WriteASCIIString(writer, "true", 4); + } + else if (obj == Py_False) { + return _PyUnicodeWriter_WriteASCIIString(writer, "false", 5); } - else if (PyUnicode_Check(obj)) - { + else if (PyUnicode_Check(obj)) { PyObject *encoded = encoder_encode_string(s, obj); if (encoded == NULL) return -1; - return _steal_accumulate(acc, encoded); + return _steal_accumulate(writer, encoded); } else if (PyLong_Check(obj)) { PyObject *encoded = PyLong_Type.tp_repr(obj); if (encoded == NULL) return -1; - return _steal_accumulate(acc, encoded); + return _steal_accumulate(writer, encoded); } else if (PyFloat_Check(obj)) { PyObject *encoded = encoder_encode_float(s, obj); if (encoded == NULL) return -1; - return _steal_accumulate(acc, encoded); + return _steal_accumulate(writer, encoded); } else if (PyList_Check(obj) || PyTuple_Check(obj)) { if (_Py_EnterRecursiveCall(" while encoding a JSON object")) return -1; - rv = encoder_listencode_list(s, acc, obj, indent_level); + rv = encoder_listencode_list(s, writer, obj, indent_level); _Py_LeaveRecursiveCall(); return rv; } else if (PyDict_Check(obj)) { if (_Py_EnterRecursiveCall(" while encoding a JSON object")) return -1; - rv = encoder_listencode_dict(s, acc, obj, indent_level); + rv = encoder_listencode_dict(s, writer, obj, indent_level); _Py_LeaveRecursiveCall(); return rv; } @@ -1474,7 +1447,7 @@ encoder_listencode_obj(PyEncoderObject *s, _PyAccu *acc, Py_XDECREF(ident); return -1; } - rv = encoder_listencode_obj(s, acc, newobj, indent_level); + rv = encoder_listencode_obj(s, writer, newobj, indent_level); _Py_LeaveRecursiveCall(); Py_DECREF(newobj); @@ -1494,28 +1467,80 @@ encoder_listencode_obj(PyEncoderObject *s, _PyAccu *acc, } static int -encoder_listencode_dict(PyEncoderObject *s, _PyAccu *acc, +encoder_encode_key_value(PyEncoderObject *s, _PyUnicodeWriter *writer, bool *first, + PyObject *key, PyObject *value, Py_ssize_t indent_level) +{ + PyObject *keystr = NULL; + PyObject *encoded; + + if (PyUnicode_Check(key)) { + keystr = Py_NewRef(key); + } + else if (PyFloat_Check(key)) { + keystr = encoder_encode_float(s, key); + } + else if (key == Py_True || key == Py_False || key == Py_None) { + /* This must come before the PyLong_Check because + True and False are also 1 and 0.*/ + keystr = _encoded_const(key); + } + else if (PyLong_Check(key)) { + keystr = PyLong_Type.tp_repr(key); + } + else if (s->skipkeys) { + return 0; + } + else { + PyErr_Format(PyExc_TypeError, + "keys must be str, int, float, bool or None, " + "not %.100s", Py_TYPE(key)->tp_name); + return -1; + } + + if (keystr == NULL) { + return -1; + } + + if (*first) { + *first = false; + } + else { + if (_PyUnicodeWriter_WriteStr(writer, s->item_separator) < 0) { + Py_DECREF(keystr); + return -1; + } + } + + encoded = encoder_encode_string(s, keystr); + Py_DECREF(keystr); + if (encoded == NULL) { + return -1; + } + + if (_steal_accumulate(writer, encoded) < 0) { + return -1; + } + if (_PyUnicodeWriter_WriteStr(writer, s->key_separator) < 0) { + return -1; + } + if (encoder_listencode_obj(s, writer, value, indent_level) < 0) { + return -1; + } + return 0; +} + +static int +encoder_listencode_dict(PyEncoderObject *s, _PyUnicodeWriter *writer, PyObject *dct, Py_ssize_t indent_level) { /* Encode Python dict dct a JSON term */ - _Py_static_string(PyId_open_dict, "{"); - _Py_static_string(PyId_close_dict, "}"); - _Py_static_string(PyId_empty_dict, "{}"); - PyObject *open_dict = _PyUnicode_FromId(&PyId_open_dict); // borrowed ref - PyObject *close_dict = _PyUnicode_FromId(&PyId_close_dict); // borrowed ref - PyObject *empty_dict = _PyUnicode_FromId(&PyId_empty_dict); // borrowed ref - PyObject *kstr = NULL; PyObject *ident = NULL; - PyObject *it = NULL; - PyObject *items; - PyObject *item = NULL; - Py_ssize_t idx; + PyObject *items = NULL; + PyObject *key, *value; + bool first = true; - if (open_dict == NULL || close_dict == NULL || empty_dict == NULL) { - return -1; - } if (PyDict_GET_SIZE(dct) == 0) /* Fast path */ - return _PyAccu_Accumulate(acc, empty_dict); + return _PyUnicodeWriter_WriteASCIIString(writer, "{}", 2); if (s->markers != Py_None) { int has_key; @@ -1533,7 +1558,7 @@ encoder_listencode_dict(PyEncoderObject *s, _PyAccu *acc, } } - if (_PyAccu_Accumulate(acc, open_dict)) + if (_PyUnicodeWriter_WriteChar(writer, '{')) goto bail; if (s->indent != Py_None) { @@ -1546,84 +1571,33 @@ encoder_listencode_dict(PyEncoderObject *s, _PyAccu *acc, */ } - items = PyMapping_Items(dct); - if (items == NULL) - goto bail; - if (s->sort_keys && PyList_Sort(items) < 0) { - Py_DECREF(items); - goto bail; - } - it = PyObject_GetIter(items); - Py_DECREF(items); - if (it == NULL) - goto bail; - idx = 0; - while ((item = PyIter_Next(it)) != NULL) { - PyObject *encoded, *key, *value; - if (!PyTuple_Check(item) || PyTuple_GET_SIZE(item) != 2) { - PyErr_SetString(PyExc_ValueError, "items must return 2-tuples"); + if (s->sort_keys || !PyDict_CheckExact(dct)) { + items = PyMapping_Items(dct); + if (items == NULL || (s->sort_keys && PyList_Sort(items) < 0)) goto bail; - } - key = PyTuple_GET_ITEM(item, 0); - if (PyUnicode_Check(key)) { - Py_INCREF(key); - kstr = key; - } - else if (PyFloat_Check(key)) { - kstr = encoder_encode_float(s, key); - if (kstr == NULL) - goto bail; - } - else if (key == Py_True || key == Py_False || key == Py_None) { - /* This must come before the PyLong_Check because - True and False are also 1 and 0.*/ - kstr = _encoded_const(key); - if (kstr == NULL) - goto bail; - } - else if (PyLong_Check(key)) { - kstr = PyLong_Type.tp_repr(key); - if (kstr == NULL) { + + for (Py_ssize_t i = 0; i < PyList_GET_SIZE(items); i++) { + PyObject *item = PyList_GET_ITEM(items, i); + + if (!PyTuple_Check(item) || PyTuple_GET_SIZE(item) != 2) { + PyErr_SetString(PyExc_ValueError, "items must return 2-tuples"); goto bail; } - } - else if (s->skipkeys) { - Py_DECREF(item); - continue; - } - else { - PyErr_Format(PyExc_TypeError, - "keys must be str, int, float, bool or None, " - "not %.100s", Py_TYPE(key)->tp_name); - goto bail; - } - if (idx) { - if (_PyAccu_Accumulate(acc, s->item_separator)) + key = PyTuple_GET_ITEM(item, 0); + value = PyTuple_GET_ITEM(item, 1); + if (encoder_encode_key_value(s, writer, &first, key, value, indent_level) < 0) goto bail; } + Py_CLEAR(items); - encoded = encoder_encode_string(s, kstr); - Py_CLEAR(kstr); - if (encoded == NULL) - goto bail; - if (_PyAccu_Accumulate(acc, encoded)) { - Py_DECREF(encoded); - goto bail; + } else { + Py_ssize_t pos = 0; + while (PyDict_Next(dct, &pos, &key, &value)) { + if (encoder_encode_key_value(s, writer, &first, key, value, indent_level) < 0) + goto bail; } - Py_DECREF(encoded); - if (_PyAccu_Accumulate(acc, s->key_separator)) - goto bail; - - value = PyTuple_GET_ITEM(item, 1); - if (encoder_listencode_obj(s, acc, value, indent_level)) - goto bail; - idx += 1; - Py_DECREF(item); } - if (PyErr_Occurred()) - goto bail; - Py_CLEAR(it); if (ident != NULL) { if (PyDict_DelItem(s->markers, ident)) @@ -1636,44 +1610,31 @@ encoder_listencode_dict(PyEncoderObject *s, _PyAccu *acc, yield '\n' + (' ' * (_indent * _current_indent_level)) }*/ - if (_PyAccu_Accumulate(acc, close_dict)) + if (_PyUnicodeWriter_WriteChar(writer, '}')) goto bail; return 0; bail: - Py_XDECREF(it); - Py_XDECREF(item); - Py_XDECREF(kstr); + Py_XDECREF(items); Py_XDECREF(ident); return -1; } - static int -encoder_listencode_list(PyEncoderObject *s, _PyAccu *acc, +encoder_listencode_list(PyEncoderObject *s, _PyUnicodeWriter *writer, PyObject *seq, Py_ssize_t indent_level) { - /* Encode Python list seq to a JSON term */ - _Py_static_string(PyId_open_array, "["); - _Py_static_string(PyId_close_array, "]"); - _Py_static_string(PyId_empty_array, "[]"); - PyObject *open_array = _PyUnicode_FromId(&PyId_open_array); // borrowed ref - PyObject *close_array = _PyUnicode_FromId(&PyId_close_array); // borrowed ref - PyObject *empty_array = _PyUnicode_FromId(&PyId_empty_array); // borrowed ref PyObject *ident = NULL; PyObject *s_fast = NULL; Py_ssize_t i; - if (open_array == NULL || close_array == NULL || empty_array == NULL) { - return -1; - } ident = NULL; s_fast = PySequence_Fast(seq, "_iterencode_list needs a sequence"); if (s_fast == NULL) return -1; if (PySequence_Fast_GET_SIZE(s_fast) == 0) { Py_DECREF(s_fast); - return _PyAccu_Accumulate(acc, empty_array); + return _PyUnicodeWriter_WriteASCIIString(writer, "[]", 2); } if (s->markers != Py_None) { @@ -1692,7 +1653,7 @@ encoder_listencode_list(PyEncoderObject *s, _PyAccu *acc, } } - if (_PyAccu_Accumulate(acc, open_array)) + if (_PyUnicodeWriter_WriteChar(writer, '[')) goto bail; if (s->indent != Py_None) { /* TODO: DOES NOT RUN */ @@ -1706,10 +1667,10 @@ encoder_listencode_list(PyEncoderObject *s, _PyAccu *acc, for (i = 0; i < PySequence_Fast_GET_SIZE(s_fast); i++) { PyObject *obj = PySequence_Fast_GET_ITEM(s_fast, i); if (i) { - if (_PyAccu_Accumulate(acc, s->item_separator)) + if (_PyUnicodeWriter_WriteStr(writer, s->item_separator)) goto bail; } - if (encoder_listencode_obj(s, acc, obj, indent_level)) + if (encoder_listencode_obj(s, writer, obj, indent_level)) goto bail; } if (ident != NULL) { @@ -1724,7 +1685,7 @@ encoder_listencode_list(PyEncoderObject *s, _PyAccu *acc, yield '\n' + (' ' * (_indent * _current_indent_level)) }*/ - if (_PyAccu_Accumulate(acc, close_array)) + if (_PyUnicodeWriter_WriteChar(writer, ']')) goto bail; Py_DECREF(s_fast); return 0; @@ -1815,70 +1776,41 @@ PyDoc_STRVAR(module_doc, static int _json_exec(PyObject *module) { - _jsonmodulestate *state = get_json_state(module); - - state->PyScannerType = PyType_FromSpec(&PyScannerType_spec); - if (state->PyScannerType == NULL) { + PyObject *PyScannerType = PyType_FromSpec(&PyScannerType_spec); + if (PyScannerType == NULL) { return -1; } - Py_INCREF(state->PyScannerType); - if (PyModule_AddObject(module, "make_scanner", state->PyScannerType) < 0) { - Py_DECREF(state->PyScannerType); + int rc = PyModule_AddObjectRef(module, "make_scanner", PyScannerType); + Py_DECREF(PyScannerType); + if (rc < 0) { return -1; } - state->PyEncoderType = PyType_FromSpec(&PyEncoderType_spec); - if (state->PyEncoderType == NULL) { + PyObject *PyEncoderType = PyType_FromSpec(&PyEncoderType_spec); + if (PyEncoderType == NULL) { return -1; } - Py_INCREF(state->PyEncoderType); - if (PyModule_AddObject(module, "make_encoder", state->PyEncoderType) < 0) { - Py_DECREF(state->PyEncoderType); + rc = PyModule_AddObjectRef(module, "make_encoder", PyEncoderType); + Py_DECREF(PyEncoderType); + if (rc < 0) { return -1; } return 0; } -static int -_jsonmodule_traverse(PyObject *module, visitproc visit, void *arg) -{ - _jsonmodulestate *state = get_json_state(module); - Py_VISIT(state->PyScannerType); - Py_VISIT(state->PyEncoderType); - return 0; -} - -static int -_jsonmodule_clear(PyObject *module) -{ - _jsonmodulestate *state = get_json_state(module); - Py_CLEAR(state->PyScannerType); - Py_CLEAR(state->PyEncoderType); - return 0; -} - -static void -_jsonmodule_free(void *module) -{ - _jsonmodule_clear((PyObject *)module); -} - static PyModuleDef_Slot _json_slots[] = { {Py_mod_exec, _json_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; static struct PyModuleDef jsonmodule = { - PyModuleDef_HEAD_INIT, - "_json", - module_doc, - sizeof(_jsonmodulestate), - speedups_methods, - _json_slots, - _jsonmodule_traverse, - _jsonmodule_clear, - _jsonmodule_free, + .m_base = PyModuleDef_HEAD_INIT, + .m_name = "_json", + .m_doc = module_doc, + .m_methods = speedups_methods, + .m_slots = _json_slots, }; PyMODINIT_FUNC diff --git a/Modules/_localemodule.c b/Modules/_localemodule.c index 23c38e14..cbd036fd 100644 --- a/Modules/_localemodule.c +++ b/Modules/_localemodule.c @@ -35,7 +35,9 @@ This software comes with no warranty. Use at your own risk. #endif #if defined(MS_WINDOWS) +#ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN +#endif #include <windows.h> #endif @@ -457,12 +459,12 @@ _locale__getdefaultlocale_impl(PyObject *module) PyOS_snprintf(encoding, sizeof(encoding), "cp%u", GetACP()); - if (GetLocaleInfo(LOCALE_USER_DEFAULT, + if (GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_SISO639LANGNAME, locale, sizeof(locale))) { Py_ssize_t i = strlen(locale); locale[i++] = '_'; - if (GetLocaleInfo(LOCALE_USER_DEFAULT, + if (GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_SISO3166CTRYNAME, locale+i, (int)(sizeof(locale)-i))) return Py_BuildValue("ss", locale, encoding); @@ -474,7 +476,7 @@ _locale__getdefaultlocale_impl(PyObject *module) locale[0] = '0'; locale[1] = 'x'; - if (GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IDEFAULTLANGUAGE, + if (GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_IDEFAULTLANGUAGE, locale+2, sizeof(locale)-2)) { return Py_BuildValue("ss", locale, encoding); } @@ -735,8 +737,8 @@ _locale_bindtextdomain_impl(PyObject *module, const char *domain, } current_dirname = bindtextdomain(domain, dirname); if (current_dirname == NULL) { - Py_XDECREF(dirname_bytes); PyErr_SetFromErrno(PyExc_OSError); + Py_XDECREF(dirname_bytes); return NULL; } result = PyUnicode_DecodeLocale(current_dirname, NULL); @@ -872,6 +874,7 @@ _locale_exec(PyObject *module) static struct PyModuleDef_Slot _locale_slots[] = { {Py_mod_exec, _locale_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; diff --git a/Modules/_lsprof.c b/Modules/_lsprof.c index a0e262bd..257de438 100644 --- a/Modules/_lsprof.c +++ b/Modules/_lsprof.c @@ -49,6 +49,8 @@ typedef struct { int flags; PyObject *externalTimer; double externalTimerUnit; + int tool_id; + PyObject* missing; } ProfilerObject; #define POF_ENABLED 0x001 @@ -128,8 +130,7 @@ normalizeUserObj(PyObject *obj) { PyCFunctionObject *fn; if (!PyCFunction_Check(obj)) { - Py_INCREF(obj); - return obj; + return Py_NewRef(obj); } /* Replace built-in function objects with a descriptive string because of built-in methods -- keeping a reference to @@ -142,8 +143,7 @@ normalizeUserObj(PyObject *obj) PyObject *modname = NULL; if (mod != NULL) { if (PyUnicode_Check(mod)) { - modname = mod; - Py_INCREF(modname); + modname = Py_NewRef(mod); } else if (PyModule_Check(mod)) { modname = PyModule_GetNameObject(mod); @@ -350,8 +350,7 @@ ptrace_enter_call(PyObject *self, void *key, PyObject *userObj) * exception, and some of the code under here assumes that * PyErr_* is its own to mess around with, so we have to * save and restore any current exception. */ - PyObject *last_type, *last_value, *last_tb; - PyErr_Fetch(&last_type, &last_value, &last_tb); + PyObject *exc = PyErr_GetRaisedException(); profEntry = getEntry(pObj, key); if (profEntry == NULL) { @@ -376,7 +375,7 @@ ptrace_enter_call(PyObject *self, void *key, PyObject *userObj) initContext(pObj, pContext, profEntry); restorePyerr: - PyErr_Restore(last_type, last_value, last_tb); + PyErr_SetRaisedException(exc); } static void @@ -402,64 +401,6 @@ ptrace_leave_call(PyObject *self, void *key) pObj->freelistProfilerContext = pContext; } -static int -profiler_callback(PyObject *self, PyFrameObject *frame, int what, - PyObject *arg) -{ - switch (what) { - - /* the 'frame' of a called function is about to start its execution */ - case PyTrace_CALL: - { - PyCodeObject *code = PyFrame_GetCode(frame); - ptrace_enter_call(self, (void *)code, (PyObject *)code); - Py_DECREF(code); - break; - } - - /* the 'frame' of a called function is about to finish - (either normally or with an exception) */ - case PyTrace_RETURN: - { - PyCodeObject *code = PyFrame_GetCode(frame); - ptrace_leave_call(self, (void *)code); - Py_DECREF(code); - break; - } - - /* case PyTrace_EXCEPTION: - If the exception results in the function exiting, a - PyTrace_RETURN event will be generated, so we don't need to - handle it. */ - - /* the Python function 'frame' is issuing a call to the built-in - function 'arg' */ - case PyTrace_C_CALL: - if ((((ProfilerObject *)self)->flags & POF_BUILTINS) - && PyCFunction_Check(arg)) { - ptrace_enter_call(self, - ((PyCFunctionObject *)arg)->m_ml, - arg); - } - break; - - /* the call to the built-in function 'arg' is returning into its - caller 'frame' */ - case PyTrace_C_RETURN: /* ...normally */ - case PyTrace_C_EXCEPTION: /* ...with an exception set */ - if ((((ProfilerObject *)self)->flags & POF_BUILTINS) - && PyCFunction_Check(arg)) { - ptrace_leave_call(self, - ((PyCFunctionObject *)arg)->m_ml); - } - break; - - default: - break; - } - return 0; -} - static int pending_exception(ProfilerObject *pObj) { @@ -555,8 +496,7 @@ static int statsForEntry(rotating_node_t *node, void *arg) } } else { - Py_INCREF(Py_None); - collect->sublist = Py_None; + collect->sublist = Py_NewRef(Py_None); } info = PyObject_CallFunction((PyObject*) collect->state->stats_entry_type, @@ -610,7 +550,7 @@ _lsprof_Profiler_getstats_impl(ProfilerObject *self, PyTypeObject *cls) /*[clinic end generated code: output=1806ef720019ee03 input=445e193ef4522902]*/ { statscollector_t collect; - collect.state = PyType_GetModuleState(cls); + collect.state = _PyType_GetModuleState(cls); if (pending_exception(self)) { return NULL; } @@ -654,6 +594,100 @@ setBuiltins(ProfilerObject *pObj, int nvalue) return 0; } +PyObject* pystart_callback(ProfilerObject* self, PyObject *const *args, Py_ssize_t size) +{ + PyObject* code = args[0]; + ptrace_enter_call((PyObject*)self, (void *)code, (PyObject *)code); + + Py_RETURN_NONE; +} + +PyObject* pyreturn_callback(ProfilerObject* self, PyObject *const *args, Py_ssize_t size) +{ + PyObject* code = args[0]; + ptrace_leave_call((PyObject*)self, (void *)code); + + Py_RETURN_NONE; +} + +PyObject* get_cfunc_from_callable(PyObject* callable, PyObject* self_arg, PyObject* missing) +{ + // return a new reference + if (PyCFunction_Check(callable)) { + Py_INCREF(callable); + return (PyObject*)((PyCFunctionObject *)callable); + } + if (Py_TYPE(callable) == &PyMethodDescr_Type) { + /* For backwards compatibility need to + * convert to builtin method */ + + /* If no arg, skip */ + if (self_arg == missing) { + return NULL; + } + PyObject *meth = Py_TYPE(callable)->tp_descr_get( + callable, self_arg, (PyObject*)Py_TYPE(self_arg)); + if (meth == NULL) { + return NULL; + } + if (PyCFunction_Check(meth)) { + return (PyObject*)((PyCFunctionObject *)meth); + } + } + return NULL; +} + +PyObject* ccall_callback(ProfilerObject* self, PyObject *const *args, Py_ssize_t size) +{ + if (self->flags & POF_BUILTINS) { + PyObject* callable = args[2]; + PyObject* self_arg = args[3]; + + PyObject* cfunc = get_cfunc_from_callable(callable, self_arg, self->missing); + + if (cfunc) { + ptrace_enter_call((PyObject*)self, + ((PyCFunctionObject *)cfunc)->m_ml, + cfunc); + Py_DECREF(cfunc); + } + } + Py_RETURN_NONE; +} + +PyObject* creturn_callback(ProfilerObject* self, PyObject *const *args, Py_ssize_t size) +{ + if (self->flags & POF_BUILTINS) { + PyObject* callable = args[2]; + PyObject* self_arg = args[3]; + + PyObject* cfunc = get_cfunc_from_callable(callable, self_arg, self->missing); + + if (cfunc) { + ptrace_leave_call((PyObject*)self, + ((PyCFunctionObject *)cfunc)->m_ml); + Py_DECREF(cfunc); + } + } + Py_RETURN_NONE; +} + +static const struct { + int event; + const char* callback_method; +} callback_table[] = { + {PY_MONITORING_EVENT_PY_START, "_pystart_callback"}, + {PY_MONITORING_EVENT_PY_RESUME, "_pystart_callback"}, + {PY_MONITORING_EVENT_PY_THROW, "_pystart_callback"}, + {PY_MONITORING_EVENT_PY_RETURN, "_pyreturn_callback"}, + {PY_MONITORING_EVENT_PY_YIELD, "_pyreturn_callback"}, + {PY_MONITORING_EVENT_PY_UNWIND, "_pyreturn_callback"}, + {PY_MONITORING_EVENT_CALL, "_ccall_callback"}, + {PY_MONITORING_EVENT_C_RETURN, "_creturn_callback"}, + {PY_MONITORING_EVENT_C_RAISE, "_creturn_callback"}, + {0, NULL} +}; + PyDoc_STRVAR(enable_doc, "\ enable(subcalls=True, builtins=True)\n\ \n\ @@ -670,18 +704,46 @@ profiler_enable(ProfilerObject *self, PyObject *args, PyObject *kwds) int subcalls = -1; int builtins = -1; static char *kwlist[] = {"subcalls", "builtins", 0}; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|ii:enable", + int all_events = 0; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|pp:enable", kwlist, &subcalls, &builtins)) return NULL; if (setSubcalls(self, subcalls) < 0 || setBuiltins(self, builtins) < 0) { return NULL; } - PyThreadState *tstate = _PyThreadState_GET(); - if (_PyEval_SetProfile(tstate, profiler_callback, (PyObject*)self) < 0) { + PyObject* monitoring = _PyImport_GetModuleAttrString("sys", "monitoring"); + if (!monitoring) { + return NULL; + } + + if (PyObject_CallMethod(monitoring, "use_tool_id", "is", self->tool_id, "cProfile") == NULL) { + PyErr_Format(PyExc_ValueError, "Another profiling tool is already active"); + Py_DECREF(monitoring); + return NULL; + } + + for (int i = 0; callback_table[i].callback_method; i++) { + PyObject* callback = PyObject_GetAttrString((PyObject*)self, callback_table[i].callback_method); + if (!callback) { + Py_DECREF(monitoring); + return NULL; + } + Py_XDECREF(PyObject_CallMethod(monitoring, "register_callback", "iiO", self->tool_id, + (1 << callback_table[i].event), + callback)); + Py_DECREF(callback); + all_events |= (1 << callback_table[i].event); + } + + if (!PyObject_CallMethod(monitoring, "set_events", "ii", self->tool_id, all_events)) { + Py_DECREF(monitoring); return NULL; } + Py_DECREF(monitoring); + self->flags |= POF_ENABLED; Py_RETURN_NONE; } @@ -711,13 +773,44 @@ Stop collecting profiling information.\n\ static PyObject* profiler_disable(ProfilerObject *self, PyObject* noarg) { - PyThreadState *tstate = _PyThreadState_GET(); - if (_PyEval_SetProfile(tstate, NULL, NULL) < 0) { - return NULL; + if (self->flags & POF_ENABLED) { + PyObject* result = NULL; + PyObject* monitoring = _PyImport_GetModuleAttrString("sys", "monitoring"); + + if (!monitoring) { + return NULL; + } + + for (int i = 0; callback_table[i].callback_method; i++) { + result = PyObject_CallMethod(monitoring, "register_callback", "iiO", self->tool_id, + (1 << callback_table[i].event), Py_None); + if (!result) { + Py_DECREF(monitoring); + return NULL; + } + Py_DECREF(result); + } + + result = PyObject_CallMethod(monitoring, "set_events", "ii", self->tool_id, 0); + if (!result) { + Py_DECREF(monitoring); + return NULL; + } + Py_DECREF(result); + + result = PyObject_CallMethod(monitoring, "free_tool_id", "i", self->tool_id); + if (!result) { + Py_DECREF(monitoring); + return NULL; + } + Py_DECREF(result); + + Py_DECREF(monitoring); + + self->flags &= ~POF_ENABLED; + flush_unmatched(self); } - self->flags &= ~POF_ENABLED; - flush_unmatched(self); if (pending_exception(self)) { return NULL; } @@ -773,7 +866,7 @@ profiler_init(ProfilerObject *pObj, PyObject *args, PyObject *kw) static char *kwlist[] = {"timer", "timeunit", "subcalls", "builtins", 0}; - if (!PyArg_ParseTupleAndKeywords(args, kw, "|Odii:Profiler", kwlist, + if (!PyArg_ParseTupleAndKeywords(args, kw, "|Odpp:Profiler", kwlist, &timer, &timeunit, &subcalls, &builtins)) return -1; @@ -781,19 +874,38 @@ profiler_init(ProfilerObject *pObj, PyObject *args, PyObject *kw) if (setSubcalls(pObj, subcalls) < 0 || setBuiltins(pObj, builtins) < 0) return -1; pObj->externalTimerUnit = timeunit; - Py_XINCREF(timer); - Py_XSETREF(pObj->externalTimer, timer); + Py_XSETREF(pObj->externalTimer, Py_XNewRef(timer)); + pObj->tool_id = PY_MONITORING_PROFILER_ID; + + PyObject* monitoring = _PyImport_GetModuleAttrString("sys", "monitoring"); + if (!monitoring) { + return -1; + } + pObj->missing = PyObject_GetAttrString(monitoring, "MISSING"); + if (!pObj->missing) { + Py_DECREF(monitoring); + return -1; + } + Py_DECREF(monitoring); return 0; } static PyMethodDef profiler_methods[] = { _LSPROF_PROFILER_GETSTATS_METHODDEF - {"enable", _PyCFunction_CAST(profiler_enable), + {"enable", _PyCFunction_CAST(profiler_enable), METH_VARARGS | METH_KEYWORDS, enable_doc}, - {"disable", (PyCFunction)profiler_disable, + {"disable", (PyCFunction)profiler_disable, METH_NOARGS, disable_doc}, - {"clear", (PyCFunction)profiler_clear, + {"clear", (PyCFunction)profiler_clear, METH_NOARGS, clear_doc}, + {"_pystart_callback", _PyCFunction_CAST(pystart_callback), + METH_FASTCALL, NULL}, + {"_pyreturn_callback", _PyCFunction_CAST(pyreturn_callback), + METH_FASTCALL, NULL}, + {"_ccall_callback", _PyCFunction_CAST(ccall_callback), + METH_FASTCALL, NULL}, + {"_creturn_callback", _PyCFunction_CAST(creturn_callback), + METH_FASTCALL, NULL}, {NULL, NULL} }; @@ -890,6 +1002,9 @@ _lsprof_exec(PyObject *module) static PyModuleDef_Slot _lsprofslots[] = { {Py_mod_exec, _lsprof_exec}, + // XXX gh-103092: fix isolation. + {Py_mod_multiple_interpreters, Py_MOD_MULTIPLE_INTERPRETERS_NOT_SUPPORTED}, + //{Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; diff --git a/Modules/_lzmamodule.c b/Modules/_lzmamodule.c index b572d8cd..e34fbad2 100644 --- a/Modules/_lzmamodule.c +++ b/Modules/_lzmamodule.c @@ -734,7 +734,8 @@ Compressor_init_raw(_lzma_state *state, lzma_stream *lzs, PyObject *filterspecs) } /*[-clinic input] -_lzma.LZMACompressor.__init__ +@classmethod +_lzma.LZMACompressor.__new__ format: int(c_default="FORMAT_XZ") = FORMAT_XZ The container format to use for the output. This can @@ -765,8 +766,8 @@ the raw compressor does not support preset compression levels. For one-shot compression, use the compress() function instead. [-clinic start generated code]*/ -static int -Compressor_init(Compressor *self, PyObject *args, PyObject *kwargs) +static PyObject * +Compressor_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { static char *arg_names[] = {"format", "check", "preset", "filters", NULL}; int format = FORMAT_XZ; @@ -774,31 +775,37 @@ Compressor_init(Compressor *self, PyObject *args, PyObject *kwargs) uint32_t preset = LZMA_PRESET_DEFAULT; PyObject *preset_obj = Py_None; PyObject *filterspecs = Py_None; - _lzma_state *state = PyType_GetModuleState(Py_TYPE(self)); + Compressor *self; + + _lzma_state *state = PyType_GetModuleState(type); assert(state != NULL); if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|iiOO:LZMACompressor", arg_names, &format, &check, &preset_obj, &filterspecs)) { - return -1; + return NULL; } if (format != FORMAT_XZ && check != -1 && check != LZMA_CHECK_NONE) { PyErr_SetString(PyExc_ValueError, "Integrity checks are only supported by FORMAT_XZ"); - return -1; + return NULL; } if (preset_obj != Py_None && filterspecs != Py_None) { PyErr_SetString(PyExc_ValueError, "Cannot specify both preset and filter chain"); - return -1; + return NULL; } - if (preset_obj != Py_None) { - if (!uint32_converter(preset_obj, &preset)) { - return -1; - } + if (preset_obj != Py_None && !uint32_converter(preset_obj, &preset)) { + return NULL; + } + + assert(type != NULL && type->tp_alloc != NULL); + self = (Compressor *)type->tp_alloc(type, 0); + if (self == NULL) { + return NULL; } self->alloc.opaque = NULL; @@ -808,8 +815,9 @@ Compressor_init(Compressor *self, PyObject *args, PyObject *kwargs) self->lock = PyThread_allocate_lock(); if (self->lock == NULL) { + Py_DECREF(self); PyErr_SetString(PyExc_MemoryError, "Unable to allocate lock"); - return -1; + return NULL; } self->flushed = 0; @@ -819,31 +827,33 @@ Compressor_init(Compressor *self, PyObject *args, PyObject *kwargs) check = LZMA_CHECK_CRC64; } if (Compressor_init_xz(state, &self->lzs, check, preset, filterspecs) != 0) { - break; + goto error; } - return 0; + break; case FORMAT_ALONE: if (Compressor_init_alone(state, &self->lzs, preset, filterspecs) != 0) { - break; + goto error; } - return 0; + break; case FORMAT_RAW: if (Compressor_init_raw(state, &self->lzs, filterspecs) != 0) { - break; + goto error; } - return 0; + break; default: PyErr_Format(PyExc_ValueError, "Invalid container format: %d", format); - break; + goto error; } - PyThread_free_lock(self->lock); - self->lock = NULL; - return -1; + return (PyObject *)self; + +error: + Py_DECREF(self); + return NULL; } static void @@ -902,8 +912,7 @@ PyDoc_STRVAR(Compressor_doc, static PyType_Slot lzma_compressor_type_slots[] = { {Py_tp_dealloc, Compressor_dealloc}, {Py_tp_methods, Compressor_methods}, - {Py_tp_init, Compressor_init}, - {Py_tp_new, PyType_GenericNew}, + {Py_tp_new, Compressor_new}, {Py_tp_doc, (char *)Compressor_doc}, {Py_tp_traverse, Compressor_traverse}, {0, 0} @@ -1165,7 +1174,8 @@ Decompressor_init_raw(_lzma_state *state, lzma_stream *lzs, PyObject *filterspec } /*[clinic input] -_lzma.LZMADecompressor.__init__ +@classmethod +_lzma.LZMADecompressor.__new__ format: int(c_default="FORMAT_AUTO") = FORMAT_AUTO Specifies the container format of the input stream. If this is @@ -1189,54 +1199,57 @@ Create a decompressor object for decompressing data incrementally. For one-shot decompression, use the decompress() function instead. [clinic start generated code]*/ -static int -_lzma_LZMADecompressor___init___impl(Decompressor *self, int format, - PyObject *memlimit, PyObject *filters) -/*[clinic end generated code: output=3e1821f8aa36564c input=81fe684a6c2f8a27]*/ +static PyObject * +_lzma_LZMADecompressor_impl(PyTypeObject *type, int format, + PyObject *memlimit, PyObject *filters) +/*[clinic end generated code: output=2d46d5e70f10bc7f input=ca40cd1cb1202b0d]*/ { + Decompressor *self; const uint32_t decoder_flags = LZMA_TELL_ANY_CHECK | LZMA_TELL_NO_CHECK; uint64_t memlimit_ = UINT64_MAX; lzma_ret lzret; - _lzma_state *state = PyType_GetModuleState(Py_TYPE(self)); + _lzma_state *state = PyType_GetModuleState(type); assert(state != NULL); if (memlimit != Py_None) { if (format == FORMAT_RAW) { PyErr_SetString(PyExc_ValueError, "Cannot specify memory limit with FORMAT_RAW"); - return -1; + return NULL; } memlimit_ = PyLong_AsUnsignedLongLong(memlimit); if (PyErr_Occurred()) { - return -1; + return NULL; } } if (format == FORMAT_RAW && filters == Py_None) { PyErr_SetString(PyExc_ValueError, "Must specify filters for FORMAT_RAW"); - return -1; + return NULL; } else if (format != FORMAT_RAW && filters != Py_None) { PyErr_SetString(PyExc_ValueError, "Cannot specify filters except with FORMAT_RAW"); - return -1; + return NULL; } + assert(type != NULL && type->tp_alloc != NULL); + self = (Decompressor *)type->tp_alloc(type, 0); + if (self == NULL) { + return NULL; + } self->alloc.opaque = NULL; self->alloc.alloc = PyLzma_Malloc; self->alloc.free = PyLzma_Free; self->lzs.allocator = &self->alloc; self->lzs.next_in = NULL; - PyThread_type_lock lock = PyThread_allocate_lock(); - if (lock == NULL) { + self->lock = PyThread_allocate_lock(); + if (self->lock == NULL) { + Py_DECREF(self); PyErr_SetString(PyExc_MemoryError, "Unable to allocate lock"); - return -1; - } - if (self->lock != NULL) { - PyThread_free_lock(self->lock); + return NULL; } - self->lock = lock; self->check = LZMA_CHECK_UNKNOWN; self->needs_input = 1; @@ -1251,43 +1264,43 @@ _lzma_LZMADecompressor___init___impl(Decompressor *self, int format, case FORMAT_AUTO: lzret = lzma_auto_decoder(&self->lzs, memlimit_, decoder_flags); if (catch_lzma_error(state, lzret)) { - break; + goto error; } - return 0; + break; case FORMAT_XZ: lzret = lzma_stream_decoder(&self->lzs, memlimit_, decoder_flags); if (catch_lzma_error(state, lzret)) { - break; + goto error; } - return 0; + break; case FORMAT_ALONE: self->check = LZMA_CHECK_NONE; lzret = lzma_alone_decoder(&self->lzs, memlimit_); if (catch_lzma_error(state, lzret)) { - break; + goto error; } - return 0; + break; case FORMAT_RAW: self->check = LZMA_CHECK_NONE; if (Decompressor_init_raw(state, &self->lzs, filters) == -1) { - break; + goto error; } - return 0; + break; default: PyErr_Format(PyExc_ValueError, "Invalid container format: %d", format); - break; + goto error; } + return (PyObject *)self; + error: - Py_CLEAR(self->unused_data); - PyThread_free_lock(self->lock); - self->lock = NULL; - return -1; + Py_DECREF(self); + return NULL; } static void @@ -1345,9 +1358,8 @@ static PyMemberDef Decompressor_members[] = { static PyType_Slot lzma_decompressor_type_slots[] = { {Py_tp_dealloc, Decompressor_dealloc}, {Py_tp_methods, Decompressor_methods}, - {Py_tp_init, _lzma_LZMADecompressor___init__}, - {Py_tp_new, PyType_GenericNew}, - {Py_tp_doc, (char *)_lzma_LZMADecompressor___init____doc__}, + {Py_tp_new, _lzma_LZMADecompressor}, + {Py_tp_doc, (char *)_lzma_LZMADecompressor__doc__}, {Py_tp_traverse, Decompressor_traverse}, {Py_tp_members, Decompressor_members}, {0, 0} @@ -1599,6 +1611,7 @@ static PyMethodDef lzma_methods[] = { static PyModuleDef_Slot lzma_slots[] = { {Py_mod_exec, lzma_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; diff --git a/Modules/_math.h b/Modules/_math.h index 4a6bc223..2285b647 100644 --- a/Modules/_math.h +++ b/Modules/_math.h @@ -7,8 +7,9 @@ static double _Py_log1p(double x) { - /* Some platforms supply a log1p function but don't respect the sign of - zero: log1p(-0.0) gives 0.0 instead of the correct result of -0.0. + /* Some platforms (e.g. MacOS X 10.8, see gh-59682) supply a log1p function + but don't respect the sign of zero: log1p(-0.0) gives 0.0 instead of + the correct result of -0.0. To save fiddling with configure tests and platform checks, we handle the special case of zero input directly on all platforms. diff --git a/Modules/_multiprocessing/clinic/multiprocessing.c.h b/Modules/_multiprocessing/clinic/multiprocessing.c.h index e9953215..885cd5c2 100644 --- a/Modules/_multiprocessing/clinic/multiprocessing.c.h +++ b/Modules/_multiprocessing/clinic/multiprocessing.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + #if defined(MS_WINDOWS) PyDoc_STRVAR(_multiprocessing_closesocket__doc__, @@ -21,7 +27,8 @@ _multiprocessing_closesocket(PyObject *module, PyObject *arg) PyObject *return_value = NULL; HANDLE handle; - if (!PyArg_Parse(arg, ""F_HANDLE":closesocket", &handle)) { + handle = PyLong_AsVoidPtr(arg); + if (!handle && PyErr_Occurred()) { goto exit; } return_value = _multiprocessing_closesocket_impl(module, handle); @@ -52,8 +59,15 @@ _multiprocessing_recv(PyObject *module, PyObject *const *args, Py_ssize_t nargs) HANDLE handle; int size; - if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"i:recv", - &handle, &size)) { + if (!_PyArg_CheckPositional("recv", nargs, 2, 2)) { + goto exit; + } + handle = PyLong_AsVoidPtr(args[0]); + if (!handle && PyErr_Occurred()) { + goto exit; + } + size = _PyLong_AsInt(args[1]); + if (size == -1 && PyErr_Occurred()) { goto exit; } return_value = _multiprocessing_recv_impl(module, handle, size); @@ -84,8 +98,18 @@ _multiprocessing_send(PyObject *module, PyObject *const *args, Py_ssize_t nargs) HANDLE handle; Py_buffer buf = {NULL, NULL}; - if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"y*:send", - &handle, &buf)) { + if (!_PyArg_CheckPositional("send", nargs, 2, 2)) { + goto exit; + } + handle = PyLong_AsVoidPtr(args[0]); + if (!handle && PyErr_Occurred()) { + goto exit; + } + if (PyObject_GetBuffer(args[1], &buf, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&buf, 'C')) { + _PyArg_BadArgument("send", "argument 2", "contiguous buffer", args[1]); goto exit; } return_value = _multiprocessing_send_impl(module, handle, &buf); @@ -148,4 +172,4 @@ exit: #ifndef _MULTIPROCESSING_SEND_METHODDEF #define _MULTIPROCESSING_SEND_METHODDEF #endif /* !defined(_MULTIPROCESSING_SEND_METHODDEF) */ -/*[clinic end generated code: output=d3bbf69de578db7b input=a9049054013a1b77]*/ +/*[clinic end generated code: output=4a6afc67c1f5ec85 input=a9049054013a1b77]*/ diff --git a/Modules/_multiprocessing/clinic/posixshmem.c.h b/Modules/_multiprocessing/clinic/posixshmem.c.h index be21f836..df2aa29c 100644 --- a/Modules/_multiprocessing/clinic/posixshmem.c.h +++ b/Modules/_multiprocessing/clinic/posixshmem.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + #if defined(HAVE_SHM_OPEN) PyDoc_STRVAR(_posixshmem_shm_open__doc__, @@ -21,8 +27,31 @@ static PyObject * _posixshmem_shm_open(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(flags), &_Py_ID(mode), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", "flags", "mode", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "shm_open", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "shm_open", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; PyObject *path; @@ -88,8 +117,31 @@ static PyObject * _posixshmem_shm_unlink(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "shm_unlink", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "shm_unlink", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *path; @@ -120,4 +172,4 @@ exit: #ifndef _POSIXSHMEM_SHM_UNLINK_METHODDEF #define _POSIXSHMEM_SHM_UNLINK_METHODDEF #endif /* !defined(_POSIXSHMEM_SHM_UNLINK_METHODDEF) */ -/*[clinic end generated code: output=a6db931a47d36e1b input=a9049054013a1b77]*/ +/*[clinic end generated code: output=3f6fee283d5fd0e9 input=a9049054013a1b77]*/ diff --git a/Modules/_multiprocessing/clinic/semaphore.c.h b/Modules/_multiprocessing/clinic/semaphore.c.h index adb47476..35347169 100644 --- a/Modules/_multiprocessing/clinic/semaphore.c.h +++ b/Modules/_multiprocessing/clinic/semaphore.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + #if defined(HAVE_MP_SEMAPHORE) && defined(MS_WINDOWS) PyDoc_STRVAR(_multiprocessing_SemLock_acquire__doc__, @@ -21,8 +27,31 @@ static PyObject * _multiprocessing_SemLock_acquire(SemLockObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(block), &_Py_ID(timeout), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"block", "timeout", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "acquire", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "acquire", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int blocking = 1; @@ -36,8 +65,8 @@ _multiprocessing_SemLock_acquire(SemLockObject *self, PyObject *const *args, Py_ goto skip_optional_pos; } if (args[0]) { - blocking = _PyLong_AsInt(args[0]); - if (blocking == -1 && PyErr_Occurred()) { + blocking = PyObject_IsTrue(args[0]); + if (blocking < 0) { goto exit; } if (!--noptargs) { @@ -95,8 +124,31 @@ static PyObject * _multiprocessing_SemLock_acquire(SemLockObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(block), &_Py_ID(timeout), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"block", "timeout", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "acquire", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "acquire", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int blocking = 1; @@ -110,8 +162,8 @@ _multiprocessing_SemLock_acquire(SemLockObject *self, PyObject *const *args, Py_ goto skip_optional_pos; } if (args[0]) { - blocking = _PyLong_AsInt(args[0]); - if (blocking == -1 && PyErr_Occurred()) { + blocking = PyObject_IsTrue(args[0]); + if (blocking < 0) { goto exit; } if (!--noptargs) { @@ -160,8 +212,31 @@ static PyObject * _multiprocessing_SemLock(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 5 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(kind), &_Py_ID(value), &_Py_ID(maxvalue), &_Py_ID(name), &_Py_ID(unlink), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"kind", "value", "maxvalue", "name", "unlink", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "SemLock", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "SemLock", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -200,8 +275,8 @@ _multiprocessing_SemLock(PyTypeObject *type, PyObject *args, PyObject *kwargs) PyErr_SetString(PyExc_ValueError, "embedded null character"); goto exit; } - unlink = _PyLong_AsInt(fastargs[4]); - if (unlink == -1 && PyErr_Occurred()) { + unlink = PyObject_IsTrue(fastargs[4]); + if (unlink < 0) { goto exit; } return_value = _multiprocessing_SemLock_impl(type, kind, value, maxvalue, name, unlink); @@ -467,4 +542,4 @@ exit: #ifndef _MULTIPROCESSING_SEMLOCK___EXIT___METHODDEF #define _MULTIPROCESSING_SEMLOCK___EXIT___METHODDEF #endif /* !defined(_MULTIPROCESSING_SEMLOCK___EXIT___METHODDEF) */ -/*[clinic end generated code: output=64ba32544811c9e6 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=dae57a702cc01512 input=a9049054013a1b77]*/ diff --git a/Modules/_multiprocessing/multiprocessing.c b/Modules/_multiprocessing/multiprocessing.c index 0809c245..8f9daa5c 100644 --- a/Modules/_multiprocessing/multiprocessing.c +++ b/Modules/_multiprocessing/multiprocessing.c @@ -14,8 +14,16 @@ class HANDLE_converter(CConverter): type = "HANDLE" format_unit = '"F_HANDLE"' + def parse_arg(self, argname, displayname): + return """ + {paramname} = PyLong_AsVoidPtr({argname}); + if (!{paramname} && PyErr_Occurred()) {{{{ + goto exit; + }}}} + """.format(argname=argname, paramname=self.parser_name) + [python start generated code]*/ -/*[python end generated code: output=da39a3ee5e6b4b0d input=9fad6080b79ace91]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=3e537d244034affb]*/ /*[clinic input] module _multiprocessing @@ -188,33 +196,39 @@ multiprocessing_exec(PyObject *module) { #ifdef HAVE_MP_SEMAPHORE - /* Add _PyMp_SemLock type to module */ - if (PyModule_AddType(module, &_PyMp_SemLockType) < 0) { + PyTypeObject *semlock_type = (PyTypeObject *)PyType_FromModuleAndSpec( + module, &_PyMp_SemLockType_spec, NULL); + + if (semlock_type == NULL) { + return -1; + } + int rc = PyModule_AddType(module, semlock_type); + Py_DECREF(semlock_type); + if (rc < 0) { return -1; } - { - PyObject *py_sem_value_max; - /* Some systems define SEM_VALUE_MAX as an unsigned value that - * causes it to be negative when used as an int (NetBSD). - * - * Issue #28152: Use (0) instead of 0 to fix a warning on dead code - * when using clang -Wunreachable-code. */ - if ((int)(SEM_VALUE_MAX) < (0)) - py_sem_value_max = PyLong_FromLong(INT_MAX); - else - py_sem_value_max = PyLong_FromLong(SEM_VALUE_MAX); - - if (py_sem_value_max == NULL) { - return -1; - } - if (PyDict_SetItemString(_PyMp_SemLockType.tp_dict, "SEM_VALUE_MAX", - py_sem_value_max) < 0) { - Py_DECREF(py_sem_value_max); - return -1; - } + PyObject *py_sem_value_max; + /* Some systems define SEM_VALUE_MAX as an unsigned value that + * causes it to be negative when used as an int (NetBSD). + * + * Issue #28152: Use (0) instead of 0 to fix a warning on dead code + * when using clang -Wunreachable-code. */ + if ((int)(SEM_VALUE_MAX) < (0)) { + py_sem_value_max = PyLong_FromLong(INT_MAX); + } + else { + py_sem_value_max = PyLong_FromLong(SEM_VALUE_MAX); + } + if (py_sem_value_max == NULL) { + return -1; + } + if (PyDict_SetItemString(semlock_type->tp_dict, "SEM_VALUE_MAX", + py_sem_value_max) < 0) { Py_DECREF(py_sem_value_max); + return -1; } + Py_DECREF(py_sem_value_max); #endif @@ -262,12 +276,14 @@ multiprocessing_exec(PyObject *module) static PyModuleDef_Slot multiprocessing_slots[] = { {Py_mod_exec, multiprocessing_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; static struct PyModuleDef multiprocessing_module = { PyModuleDef_HEAD_INIT, .m_name = "_multiprocessing", + .m_size = 0, .m_methods = module_methods, .m_slots = multiprocessing_slots, }; diff --git a/Modules/_multiprocessing/multiprocessing.h b/Modules/_multiprocessing/multiprocessing.h index 3a8314b1..dfc2a8e0 100644 --- a/Modules/_multiprocessing/multiprocessing.h +++ b/Modules/_multiprocessing/multiprocessing.h @@ -12,7 +12,9 @@ */ #ifdef MS_WINDOWS -# define WIN32_LEAN_AND_MEAN +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +# endif # include <windows.h> # include <winsock2.h> # include <process.h> /* getpid() */ @@ -89,7 +91,7 @@ PyObject *_PyMp_SetError(PyObject *Type, int num); * Externs - not all will really exist on all platforms */ -extern PyTypeObject _PyMp_SemLockType; +extern PyType_Spec _PyMp_SemLockType_spec; extern PyObject *_PyMp_sem_unlink(const char *name); #endif /* MULTIPROCESSING_H */ diff --git a/Modules/_multiprocessing/posixshmem.c b/Modules/_multiprocessing/posixshmem.c index d64ded41..88c93fe3 100644 --- a/Modules/_multiprocessing/posixshmem.c +++ b/Modules/_multiprocessing/posixshmem.c @@ -110,12 +110,19 @@ static PyMethodDef module_methods[ ] = { }; +static PyModuleDef_Slot module_slots[] = { + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, + {0, NULL} +}; + + static struct PyModuleDef _posixshmemmodule = { PyModuleDef_HEAD_INIT, .m_name = "_posixshmem", .m_doc = "POSIX shared memory module", .m_size = 0, .m_methods = module_methods, + .m_slots = module_slots, }; /* Module init function */ diff --git a/Modules/_multiprocessing/semaphore.c b/Modules/_multiprocessing/semaphore.c index f5fd3257..c7df82df 100644 --- a/Modules/_multiprocessing/semaphore.c +++ b/Modules/_multiprocessing/semaphore.c @@ -79,7 +79,7 @@ _GetSemaphoreValue(HANDLE handle, long *value) /*[clinic input] _multiprocessing.SemLock.acquire - block as blocking: bool(accept={int}) = True + block as blocking: bool = True timeout as timeout_obj: object = None Acquire the semaphore/lock. @@ -88,7 +88,7 @@ Acquire the semaphore/lock. static PyObject * _multiprocessing_SemLock_acquire_impl(SemLockObject *self, int blocking, PyObject *timeout_obj) -/*[clinic end generated code: output=f9998f0b6b0b0872 input=86f05662cf753eb4]*/ +/*[clinic end generated code: output=f9998f0b6b0b0872 input=e5b45f5cbb775166]*/ { double timeout; DWORD res, full_msecs, nhandles; @@ -295,7 +295,7 @@ sem_timedwait_save(sem_t *sem, struct timespec *deadline, PyThreadState *_save) /*[clinic input] _multiprocessing.SemLock.acquire - block as blocking: bool(accept={int}) = True + block as blocking: bool = True timeout as timeout_obj: object = None Acquire the semaphore/lock. @@ -304,7 +304,7 @@ Acquire the semaphore/lock. static PyObject * _multiprocessing_SemLock_acquire_impl(SemLockObject *self, int blocking, PyObject *timeout_obj) -/*[clinic end generated code: output=f9998f0b6b0b0872 input=86f05662cf753eb4]*/ +/*[clinic end generated code: output=f9998f0b6b0b0872 input=e5b45f5cbb775166]*/ { int res, err = 0; struct timespec deadline = {0}; @@ -474,14 +474,14 @@ _multiprocessing.SemLock.__new__ value: int maxvalue: int name: str - unlink: bool(accept={int}) + unlink: bool [clinic start generated code]*/ static PyObject * _multiprocessing_SemLock_impl(PyTypeObject *type, int kind, int value, int maxvalue, const char *name, int unlink) -/*[clinic end generated code: output=30727e38f5f7577a input=b378c3ee27d3a0fa]*/ +/*[clinic end generated code: output=30727e38f5f7577a input=fdaeb69814471c5b]*/ { SEM_HANDLE handle = SEM_FAILED; PyObject *result; @@ -516,12 +516,12 @@ _multiprocessing_SemLock_impl(PyTypeObject *type, int kind, int value, return result; failure: - if (handle != SEM_FAILED) - SEM_CLOSE(handle); - PyMem_Free(name_copy); if (!PyErr_Occurred()) { _PyMp_SetError(NULL, MP_STANDARD_ERROR); } + if (handle != SEM_FAILED) + SEM_CLOSE(handle); + PyMem_Free(name_copy); return NULL; } @@ -556,8 +556,9 @@ _multiprocessing_SemLock__rebuild_impl(PyTypeObject *type, SEM_HANDLE handle, if (name != NULL) { handle = sem_open(name, 0); if (handle == SEM_FAILED) { + PyErr_SetFromErrno(PyExc_OSError); PyMem_Free(name_copy); - return PyErr_SetFromErrno(PyExc_OSError); + return NULL; } } #endif @@ -568,10 +569,13 @@ _multiprocessing_SemLock__rebuild_impl(PyTypeObject *type, SEM_HANDLE handle, static void semlock_dealloc(SemLockObject* self) { + PyTypeObject *tp = Py_TYPE(self); + PyObject_GC_UnTrack(self); if (self->handle != SEM_FAILED) SEM_CLOSE(self->handle); PyMem_Free(self->name); - Py_TYPE(self)->tp_free((PyObject*)self); + tp->tp_free(self); + Py_DECREF(tp); } /*[clinic input] @@ -701,6 +705,13 @@ _multiprocessing_SemLock___exit___impl(SemLockObject *self, return _multiprocessing_SemLock_release_impl(self); } +static int +semlock_traverse(SemLockObject *s, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(s)); + return 0; +} + /* * Semaphore methods */ @@ -739,45 +750,26 @@ static PyMemberDef semlock_members[] = { * Semaphore type */ -PyTypeObject _PyMp_SemLockType = { - PyVarObject_HEAD_INIT(NULL, 0) - /* tp_name */ "_multiprocessing.SemLock", - /* tp_basicsize */ sizeof(SemLockObject), - /* tp_itemsize */ 0, - /* tp_dealloc */ (destructor)semlock_dealloc, - /* tp_vectorcall_offset */ 0, - /* tp_getattr */ 0, - /* tp_setattr */ 0, - /* tp_as_async */ 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 */ 0, - /* tp_flags */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, - /* tp_doc */ "Semaphore/Mutex type", - /* tp_traverse */ 0, - /* tp_clear */ 0, - /* tp_richcompare */ 0, - /* tp_weaklistoffset */ 0, - /* tp_iter */ 0, - /* tp_iternext */ 0, - /* tp_methods */ semlock_methods, - /* tp_members */ semlock_members, - /* tp_getset */ 0, - /* tp_base */ 0, - /* tp_dict */ 0, - /* tp_descr_get */ 0, - /* tp_descr_set */ 0, - /* tp_dictoffset */ 0, - /* tp_init */ 0, - /* tp_alloc */ 0, - /* tp_new */ _multiprocessing_SemLock, +static PyType_Slot _PyMp_SemLockType_slots[] = { + {Py_tp_dealloc, semlock_dealloc}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_setattro, PyObject_GenericSetAttr}, + {Py_tp_methods, semlock_methods}, + {Py_tp_members, semlock_members}, + {Py_tp_alloc, PyType_GenericAlloc}, + {Py_tp_new, _multiprocessing_SemLock}, + {Py_tp_traverse, semlock_traverse}, + {Py_tp_free, PyObject_GC_Del}, + {Py_tp_doc, (void *)PyDoc_STR("Semaphore/Mutex type")}, + {0, 0}, +}; + +PyType_Spec _PyMp_SemLockType_spec = { + .name = "_multiprocessing.SemLock", + .basicsize = sizeof(SemLockObject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE), + .slots = _PyMp_SemLockType_slots, }; /* diff --git a/Modules/_opcode.c b/Modules/_opcode.c index 4812716c..b70d426f 100644 --- a/Modules/_opcode.c +++ b/Modules/_opcode.c @@ -60,12 +60,7 @@ _opcode_stack_effect_impl(PyObject *module, int opcode, PyObject *oparg, "stack_effect: jump must be False, True or None"); return -1; } - if (IS_ARTIFICIAL(opcode)) { - effect = PY_INVALID_STACK_EFFECT; - } - else { - effect = PyCompile_OpcodeStackEffectWithJump(opcode, oparg_int, jump_int); - } + effect = PyCompile_OpcodeStackEffectWithJump(opcode, oparg_int, jump_int); if (effect == PY_INVALID_STACK_EFFECT) { PyErr_SetString(PyExc_ValueError, "invalid opcode or oparg"); @@ -99,12 +94,18 @@ opcode_functions[] = { {NULL, NULL, 0, NULL} }; +static PyModuleDef_Slot module_slots[] = { + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, + {0, NULL} +}; + static struct PyModuleDef opcodemodule = { PyModuleDef_HEAD_INIT, .m_name = "_opcode", .m_doc = "Opcode support module.", .m_size = 0, - .m_methods = opcode_functions + .m_methods = opcode_functions, + .m_slots = module_slots, }; PyMODINIT_FUNC diff --git a/Modules/_operator.c b/Modules/_operator.c index 6a252057..68ccc905 100644 --- a/Modules/_operator.c +++ b/Modules/_operator.c @@ -722,8 +722,7 @@ _operator_is_not_impl(PyObject *module, PyObject *a, PyObject *b) { PyObject *result; result = (a != b) ? Py_True : Py_False; - Py_INCREF(result); - return result; + return Py_NewRef(result); } /* compare_digest **********************************************************/ @@ -731,9 +730,9 @@ _operator_is_not_impl(PyObject *module, PyObject *a, PyObject *b) /* * timing safe compare * - * Returns 1 of the strings are equal. + * Returns 1 if the strings are equal. * In case of len(a) != len(b) the function tries to keep the timing - * dependent on the length of b. CPU cache locally may still alter timing + * dependent on the length of b. CPU cache locality may still alter timing * a bit. */ static int @@ -1003,15 +1002,14 @@ itemgetter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) } else { item = args; } - _operator_state *state = PyType_GetModuleState(type); + _operator_state *state = _PyType_GetModuleState(type); /* create itemgetterobject structure */ ig = PyObject_GC_New(itemgetterobject, (PyTypeObject *) state->itemgetter_type); if (ig == NULL) { return NULL; } - Py_INCREF(item); - ig->item = item; + ig->item = Py_NewRef(item); ig->nitems = nitems; ig->index = -1; if (PyLong_CheckExact(item)) { @@ -1095,8 +1093,7 @@ itemgetter_call_impl(itemgetterobject *ig, PyObject *obj) && ig->index < PyTuple_GET_SIZE(obj)) { result = PyTuple_GET_ITEM(obj, ig->index); - Py_INCREF(result); - return result; + return Py_NewRef(result); } return PyObject_GetItem(obj, ig->item); } @@ -1162,8 +1159,7 @@ static PyMemberDef itemgetter_members[] = { }; PyDoc_STRVAR(itemgetter_doc, -"itemgetter(item, ...) --> itemgetter object\n\ -\n\ +"itemgetter(item, /, *items)\n--\n\n\ Return a callable object that fetches the given item(s) from its operand.\n\ After f = itemgetter(2), the call f(r) returns r[2].\n\ After g = itemgetter(2, 5, 3), the call g(r) returns (r[2], r[5], r[3])"); @@ -1230,9 +1226,6 @@ attrgetter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) /* prepare attr while checking args */ for (idx = 0; idx < nattrs; ++idx) { PyObject *item = PyTuple_GET_ITEM(args, idx); - Py_ssize_t item_len; - const void *data; - unsigned int kind; int dot_count; if (!PyUnicode_Check(item)) { @@ -1245,9 +1238,9 @@ attrgetter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) Py_DECREF(attr); return NULL; } - item_len = PyUnicode_GET_LENGTH(item); - kind = PyUnicode_KIND(item); - data = PyUnicode_DATA(item); + Py_ssize_t item_len = PyUnicode_GET_LENGTH(item); + int kind = PyUnicode_KIND(item); + const void *data = PyUnicode_DATA(item); /* check whether the string is dotted */ dot_count = 0; @@ -1305,7 +1298,7 @@ attrgetter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) } } - _operator_state *state = PyType_GetModuleState(type); + _operator_state *state = _PyType_GetModuleState(type); /* create attrgetterobject structure */ ag = PyObject_GC_New(attrgetterobject, (PyTypeObject *)state->attrgetter_type); if (ag == NULL) { @@ -1444,8 +1437,7 @@ dotjoinattr(PyObject *attr, PyObject **attrsep) } return PyUnicode_Join(*attrsep, attr); } else { - Py_INCREF(attr); - return attr; + return Py_NewRef(attr); } } @@ -1526,8 +1518,7 @@ static PyMemberDef attrgetter_members[] = { }; PyDoc_STRVAR(attrgetter_doc, -"attrgetter(attr, ...) --> attrgetter object\n\ -\n\ +"attrgetter(attr, /, *attrs)\n--\n\n\ Return a callable object that fetches the given attribute(s) from its operand.\n\ After f = attrgetter('name'), the call f(r) returns r.name.\n\ After g = attrgetter('name', 'date'), the call g(r) returns (r.name, r.date).\n\ @@ -1587,7 +1578,7 @@ methodcaller_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return NULL; } - _operator_state *state = PyType_GetModuleState(type); + _operator_state *state = _PyType_GetModuleState(type); /* create methodcallerobject structure */ mc = PyObject_GC_New(methodcallerobject, (PyTypeObject *)state->methodcaller_type); if (mc == NULL) { @@ -1599,8 +1590,7 @@ methodcaller_new(PyTypeObject *type, PyObject *args, PyObject *kwds) PyUnicode_InternInPlace(&name); mc->name = name; - Py_XINCREF(kwds); - mc->kwds = kwds; + mc->kwds = Py_XNewRef(kwds); mc->args = PyTuple_GetSlice(args, 1, PyTuple_GET_SIZE(args)); if (mc->args == NULL) { @@ -1745,26 +1735,19 @@ methodcaller_reduce(methodcallerobject *mc, PyObject *Py_UNUSED(ignored)) newargs = PyTuple_New(1 + callargcount); if (newargs == NULL) return NULL; - Py_INCREF(mc->name); - PyTuple_SET_ITEM(newargs, 0, mc->name); + PyTuple_SET_ITEM(newargs, 0, Py_NewRef(mc->name)); for (i = 0; i < callargcount; ++i) { PyObject *arg = PyTuple_GET_ITEM(mc->args, i); - Py_INCREF(arg); - PyTuple_SET_ITEM(newargs, i + 1, arg); + PyTuple_SET_ITEM(newargs, i + 1, Py_NewRef(arg)); } return Py_BuildValue("ON", Py_TYPE(mc), newargs); } else { - PyObject *functools; PyObject *partial; PyObject *constructor; PyObject *newargs[2]; - functools = PyImport_ImportModule("functools"); - if (!functools) - return NULL; - partial = PyObject_GetAttr(functools, &_Py_ID(partial)); - Py_DECREF(functools); + partial = _PyImport_GetModuleAttrString("functools", "partial"); if (!partial) return NULL; @@ -1783,8 +1766,7 @@ static PyMethodDef methodcaller_methods[] = { {NULL} }; PyDoc_STRVAR(methodcaller_doc, -"methodcaller(name, ...) --> methodcaller object\n\ -\n\ +"methodcaller(name, /, *args, **kwargs)\n--\n\n\ Return a callable object that calls the given method on its operand.\n\ After f = methodcaller('name'), the call f(r) returns r.name().\n\ After g = methodcaller('name', 'date', foo=1), the call g(r) returns\n\ @@ -1846,6 +1828,7 @@ operator_exec(PyObject *module) static struct PyModuleDef_Slot operator_slots[] = { {Py_mod_exec, operator_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; diff --git a/Modules/_pickle.c b/Modules/_pickle.c index 721079c9..d2f6d710 100644 --- a/Modules/_pickle.c +++ b/Modules/_pickle.c @@ -22,12 +22,12 @@ PyDoc_STRVAR(pickle_module_doc, /*[clinic input] module _pickle -class _pickle.Pickler "PicklerObject *" "&Pickler_Type" -class _pickle.PicklerMemoProxy "PicklerMemoProxyObject *" "&PicklerMemoProxyType" -class _pickle.Unpickler "UnpicklerObject *" "&Unpickler_Type" -class _pickle.UnpicklerMemoProxy "UnpicklerMemoProxyObject *" "&UnpicklerMemoProxyType" +class _pickle.Pickler "PicklerObject *" "" +class _pickle.PicklerMemoProxy "PicklerMemoProxyObject *" "" +class _pickle.Unpickler "UnpicklerObject *" "" +class _pickle.UnpicklerMemoProxy "UnpicklerMemoProxyObject *" "" [clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=4b3e113468a58e6c]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=b6d7191ab6466cda]*/ /* Bump HIGHEST_PROTOCOL when new opcodes are added to the pickle protocol. Bump DEFAULT_PROTOCOL only when the oldest still supported version of Python @@ -42,6 +42,12 @@ enum { #define FLOAT FLOAT_ #define INT INT_ #define LONG LONG_ + +/* This can already be defined on Windows to set the character set + the Windows header files treat as default */ +#ifdef UNICODE +#undef UNICODE +#endif #endif /* Pickle opcodes. These must be kept updated with pickle.py. @@ -186,24 +192,41 @@ typedef struct { /* functools.partial, used for implementing __newobj_ex__ with protocols 2 and 3 */ PyObject *partial; + + /* Types */ + PyTypeObject *Pickler_Type; + PyTypeObject *Unpickler_Type; + PyTypeObject *Pdata_Type; + PyTypeObject *PicklerMemoProxyType; + PyTypeObject *UnpicklerMemoProxyType; } PickleState; /* Forward declaration of the _pickle module definition. */ static struct PyModuleDef _picklemodule; /* Given a module object, get its per-module state. */ -static PickleState * +static inline PickleState * _Pickle_GetState(PyObject *module) { - return (PickleState *)_PyModule_GetState(module); + void *state = _PyModule_GetState(module); + assert(state != NULL); + return (PickleState *)state; } -/* Find the module instance imported in the currently running sub-interpreter - and get its state. */ -static PickleState * -_Pickle_GetGlobalState(void) +static inline PickleState * +_Pickle_GetStateByClass(PyTypeObject *cls) { - return _Pickle_GetState(PyState_FindModule(&_picklemodule)); + void *state = _PyType_GetModuleState(cls); + assert(state != NULL); + return (PickleState *)state; +} + +static inline PickleState * +_Pickle_FindStateByType(PyTypeObject *tp) +{ + PyObject *module = PyType_GetModuleByDef(tp, &_picklemodule); + assert(module != NULL); + return _Pickle_GetState(module); } /* Clear the given pickle module state. */ @@ -224,6 +247,11 @@ _Pickle_ClearState(PickleState *st) Py_CLEAR(st->codecs_encode); Py_CLEAR(st->getattr); Py_CLEAR(st->partial); + Py_CLEAR(st->Pickler_Type); + Py_CLEAR(st->Unpickler_Type); + Py_CLEAR(st->Pdata_Type); + Py_CLEAR(st->PicklerMemoProxyType); + Py_CLEAR(st->UnpicklerMemoProxyType); } /* Initialize the given pickle module state. */ @@ -232,8 +260,6 @@ _Pickle_InitState(PickleState *st) { PyObject *copyreg = NULL; PyObject *compat_pickle = NULL; - PyObject *codecs = NULL; - PyObject *functools = NULL; st->getattr = _PyEval_GetBuiltin(&_Py_ID(getattr)); if (st->getattr == NULL) @@ -329,10 +355,7 @@ _Pickle_InitState(PickleState *st) } Py_CLEAR(compat_pickle); - codecs = PyImport_ImportModule("codecs"); - if (codecs == NULL) - goto error; - st->codecs_encode = PyObject_GetAttrString(codecs, "encode"); + st->codecs_encode = _PyImport_GetModuleAttrString("codecs", "encode"); if (st->codecs_encode == NULL) { goto error; } @@ -342,23 +365,16 @@ _Pickle_InitState(PickleState *st) Py_TYPE(st->codecs_encode)->tp_name); goto error; } - Py_CLEAR(codecs); - functools = PyImport_ImportModule("functools"); - if (!functools) - goto error; - st->partial = PyObject_GetAttrString(functools, "partial"); + st->partial = _PyImport_GetModuleAttrString("functools", "partial"); if (!st->partial) goto error; - Py_CLEAR(functools); return 0; error: Py_CLEAR(copyreg); Py_CLEAR(compat_pickle); - Py_CLEAR(codecs); - Py_CLEAR(functools); _Pickle_ClearState(st); return -1; } @@ -398,10 +414,9 @@ init_method_ref(PyObject *self, PyObject *name, 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); + func2 = PyMethod_GET_FUNCTION(func); + Py_XSETREF(*method_func, Py_NewRef(func2)); Py_DECREF(func); return 0; } @@ -420,8 +435,7 @@ reconstruct_method(PyObject *func, PyObject *self) return PyMethod_New(func, self); } else { - Py_INCREF(func); - return func; + return Py_NewRef(func); } } @@ -447,39 +461,58 @@ typedef struct { Py_ssize_t allocated; /* number of slots in data allocated */ } Pdata; +static int +Pdata_traverse(Pdata *self, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(self)); + return 0; +} + static void Pdata_dealloc(Pdata *self) { + PyTypeObject *tp = Py_TYPE(self); + PyObject_GC_UnTrack(self); Py_ssize_t i = Py_SIZE(self); while (--i >= 0) { Py_DECREF(self->data[i]); } PyMem_Free(self->data); - PyObject_Free(self); + tp->tp_free((PyObject *)self); + Py_DECREF(tp); } -static PyTypeObject Pdata_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_pickle.Pdata", /*tp_name*/ - sizeof(Pdata), /*tp_basicsize*/ - sizeof(PyObject *), /*tp_itemsize*/ - (destructor)Pdata_dealloc, /*tp_dealloc*/ +static PyType_Slot pdata_slots[] = { + {Py_tp_dealloc, Pdata_dealloc}, + {Py_tp_traverse, Pdata_traverse}, + {0, NULL}, +}; + +static PyType_Spec pdata_spec = { + .name = "_pickle.Pdata", + .basicsize = sizeof(Pdata), + .itemsize = sizeof(PyObject *), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = pdata_slots, }; static PyObject * -Pdata_New(void) +Pdata_New(PickleState *state) { Pdata *self; - if (!(self = PyObject_New(Pdata, &Pdata_Type))) + if (!(self = PyObject_GC_New(Pdata, state->Pdata_Type))) return NULL; Py_SET_SIZE(self, 0); self->mark_set = 0; self->fence = 0; self->allocated = 8; self->data = PyMem_Malloc(self->allocated * sizeof(PyObject *)); - if (self->data) + if (self->data) { + PyObject_GC_Track(self); return (PyObject *)self; + } Py_DECREF(self); return PyErr_NoMemory(); } @@ -530,9 +563,8 @@ Pdata_grow(Pdata *self) } static int -Pdata_stack_underflow(Pdata *self) +Pdata_stack_underflow(PickleState *st, Pdata *self) { - PickleState *st = _Pickle_GetGlobalState(); PyErr_SetString(st->UnpicklingError, self->mark_set ? "unexpected MARK found" : @@ -545,16 +577,16 @@ Pdata_stack_underflow(Pdata *self) * is raised and V is set to NULL. */ static PyObject * -Pdata_pop(Pdata *self) +Pdata_pop(PickleState *state, Pdata *self) { if (Py_SIZE(self) <= self->fence) { - Pdata_stack_underflow(self); + Pdata_stack_underflow(state, self); return NULL; } Py_SET_SIZE(self, Py_SIZE(self) - 1); return self->data[Py_SIZE(self)]; } -#define PDATA_POP(D, V) do { (V) = Pdata_pop((D)); } while (0) +#define PDATA_POP(S, D, V) do { (V) = Pdata_pop(S, (D)); } while (0) static int Pdata_push(Pdata *self, PyObject *obj) @@ -577,13 +609,13 @@ Pdata_push(Pdata *self, PyObject *obj) if (Pdata_push((D), (O)) < 0) return (ER); } while(0) static PyObject * -Pdata_poptuple(Pdata *self, Py_ssize_t start) +Pdata_poptuple(PickleState *state, Pdata *self, Py_ssize_t start) { PyObject *tuple; Py_ssize_t len, i, j; if (start < self->fence) { - Pdata_stack_underflow(self); + Pdata_stack_underflow(state, self); return NULL; } len = Py_SIZE(self) - start; @@ -718,10 +750,8 @@ typedef struct { } UnpicklerMemoProxyObject; /* Forward declarations */ -static int save(PicklerObject *, PyObject *, int); -static int save_reduce(PicklerObject *, PyObject *, PyObject *); -static PyTypeObject Pickler_Type; -static PyTypeObject Unpickler_Type; +static int save(PickleState *state, PicklerObject *, PyObject *, int); +static int save_reduce(PickleState *, PicklerObject *, PyObject *, PyObject *); #include "clinic/_pickle.c.h" @@ -919,8 +949,7 @@ PyMemoTable_Set(PyMemoTable *self, PyObject *key, Py_ssize_t value) entry->me_value = value; return 0; } - Py_INCREF(key); - entry->me_key = key; + entry->me_key = Py_NewRef(key); entry->me_value = value; self->mt_used++; @@ -1114,41 +1143,51 @@ _Pickler_Write(PicklerObject *self, const char *s, Py_ssize_t data_len) } static PicklerObject * -_Pickler_New(void) +_Pickler_New(PickleState *st) { - PicklerObject *self; - - self = PyObject_GC_New(PicklerObject, &Pickler_Type); - if (self == NULL) + PyMemoTable *memo = PyMemoTable_New(); + if (memo == NULL) { return NULL; + } + + const Py_ssize_t max_output_len = WRITE_BUF_SIZE; + PyObject *output_buffer = PyBytes_FromStringAndSize(NULL, max_output_len); + if (output_buffer == NULL) { + goto error; + } + + PicklerObject *self = PyObject_GC_New(PicklerObject, st->Pickler_Type); + if (self == NULL) { + goto error; + } + self->memo = memo; self->pers_func = NULL; + self->pers_func_self = NULL; self->dispatch_table = NULL; - self->buffer_callback = NULL; + self->reducer_override = NULL; self->write = NULL; + self->output_buffer = output_buffer; + self->output_len = 0; + self->max_output_len = max_output_len; self->proto = 0; self->bin = 0; self->framing = 0; self->frame_start = -1; + self->buf_size = 0; self->fast = 0; self->fast_nesting = 0; self->fix_imports = 0; self->fast_memo = NULL; - self->max_output_len = WRITE_BUF_SIZE; - self->output_len = 0; - self->reducer_override = NULL; - - self->memo = PyMemoTable_New(); - self->output_buffer = PyBytes_FromStringAndSize(NULL, - self->max_output_len); - - if (self->memo == NULL || self->output_buffer == NULL) { - Py_DECREF(self); - return NULL; - } + self->buffer_callback = NULL; PyObject_GC_Track(self); return self; + +error: + PyMem_Free(memo); + Py_XDECREF(output_buffer); + return NULL; } static int @@ -1208,8 +1247,7 @@ _Pickler_SetBufferCallback(PicklerObject *self, PyObject *buffer_callback) return -1; } - Py_XINCREF(buffer_callback); - self->buffer_callback = buffer_callback; + self->buffer_callback = Py_XNewRef(buffer_callback); return 0; } @@ -1230,9 +1268,8 @@ _Unpickler_SetStringInput(UnpicklerObject *self, PyObject *input) } static int -bad_readline(void) +bad_readline(PickleState *st) { - PickleState *st = _Pickle_GetGlobalState(); PyErr_SetString(st->UnpicklingError, "pickle data was truncated"); return -1; } @@ -1327,13 +1364,12 @@ _Unpickler_ReadFromFile(UnpicklerObject *self, Py_ssize_t n) /* Don't call it directly: use _Unpickler_Read() */ static Py_ssize_t -_Unpickler_ReadImpl(UnpicklerObject *self, char **s, Py_ssize_t n) +_Unpickler_ReadImpl(UnpicklerObject *self, PickleState *st, char **s, Py_ssize_t n) { Py_ssize_t num_read; *s = NULL; if (self->next_read_idx > PY_SSIZE_T_MAX - n) { - PickleState *st = _Pickle_GetGlobalState(); PyErr_SetString(st->UnpicklingError, "read would overflow (invalid bytecode)"); return -1; @@ -1343,14 +1379,14 @@ _Unpickler_ReadImpl(UnpicklerObject *self, char **s, Py_ssize_t n) assert(self->next_read_idx + n > self->input_len); if (!self->read) - return bad_readline(); + return bad_readline(st); /* Extend the buffer to satisfy desired size */ num_read = _Unpickler_ReadFromFile(self, n); if (num_read < 0) return -1; if (num_read < n) - return bad_readline(); + return bad_readline(st); *s = self->input_buffer; self->next_read_idx = n; return n; @@ -1365,7 +1401,8 @@ _Unpickler_ReadImpl(UnpicklerObject *self, char **s, Py_ssize_t n) * _Unpickler_Read() is recommended in most cases. */ static Py_ssize_t -_Unpickler_ReadInto(UnpicklerObject *self, char *buf, Py_ssize_t n) +_Unpickler_ReadInto(PickleState *state, UnpicklerObject *self, char *buf, + Py_ssize_t n) { assert(n != READ_WHOLE_LINE); @@ -1386,7 +1423,7 @@ _Unpickler_ReadInto(UnpicklerObject *self, char *buf, Py_ssize_t n) /* Read from file */ if (!self->read) { /* We're unpickling memory, this means the input is truncated */ - return bad_readline(); + return bad_readline(state); } if (_Unpickler_SkipConsumed(self) < 0) { return -1; @@ -1413,7 +1450,7 @@ _Unpickler_ReadInto(UnpicklerObject *self, char *buf, Py_ssize_t n) Py_ssize_t read_size = PyBytes_GET_SIZE(data); if (read_size < n) { Py_DECREF(data); - return bad_readline(); + return bad_readline(state); } memcpy(buf, PyBytes_AS_STRING(data), n); Py_DECREF(data); @@ -1440,7 +1477,7 @@ _Unpickler_ReadInto(UnpicklerObject *self, char *buf, Py_ssize_t n) return -1; } if (read_size < n) { - return bad_readline(); + return bad_readline(state); } return n; } @@ -1458,12 +1495,12 @@ _Unpickler_ReadInto(UnpicklerObject *self, char *buf, Py_ssize_t n) Returns -1 (with an exception set) on failure. On success, return the number of chars read. */ -#define _Unpickler_Read(self, s, n) \ +#define _Unpickler_Read(self, state, s, n) \ (((n) <= (self)->input_len - (self)->next_read_idx) \ ? (*(s) = (self)->input_buffer + (self)->next_read_idx, \ (self)->next_read_idx += (n), \ (n)) \ - : _Unpickler_ReadImpl(self, (s), (n))) + : _Unpickler_ReadImpl(self, state, (s), (n))) static Py_ssize_t _Unpickler_CopyLine(UnpicklerObject *self, char *line, Py_ssize_t len, @@ -1487,7 +1524,7 @@ _Unpickler_CopyLine(UnpicklerObject *self, char *line, Py_ssize_t len, Returns the number of chars read, or -1 on failure. */ static Py_ssize_t -_Unpickler_Readline(UnpicklerObject *self, char **result) +_Unpickler_Readline(PickleState *state, UnpicklerObject *self, char **result) { Py_ssize_t i, num_read; @@ -1500,13 +1537,13 @@ _Unpickler_Readline(UnpicklerObject *self, char **result) } } if (!self->read) - return bad_readline(); + return bad_readline(state); num_read = _Unpickler_ReadFromFile(self, READ_WHOLE_LINE); if (num_read < 0) return -1; if (num_read == 0 || self->input_buffer[num_read - 1] != '\n') - return bad_readline(); + return bad_readline(state); self->next_read_idx = num_read; return _Unpickler_CopyLine(self, self->input_buffer, num_read, result); } @@ -1555,9 +1592,8 @@ _Unpickler_MemoPut(UnpicklerObject *self, size_t idx, PyObject *value) return -1; assert(idx < self->memo_size); } - Py_INCREF(value); old_item = self->memo[idx]; - self->memo[idx] = value; + self->memo[idx] = Py_NewRef(value); if (old_item != NULL) { Py_DECREF(old_item); } @@ -1597,15 +1633,33 @@ _Unpickler_MemoCleanup(UnpicklerObject *self) } static UnpicklerObject * -_Unpickler_New(void) +_Unpickler_New(PyObject *module) { - UnpicklerObject *self; - - self = PyObject_GC_New(UnpicklerObject, &Unpickler_Type); - if (self == NULL) + const int MEMO_SIZE = 32; + PyObject **memo = _Unpickler_NewMemo(MEMO_SIZE); + if (memo == NULL) { return NULL; + } + PickleState *st = _Pickle_GetState(module); + PyObject *stack = Pdata_New(st); + if (stack == NULL) { + goto error; + } + + UnpicklerObject *self = PyObject_GC_New(UnpicklerObject, + st->Unpickler_Type); + if (self == NULL) { + goto error; + } + + self->stack = (Pdata *)stack; + self->memo = memo; + self->memo_size = MEMO_SIZE; + self->memo_len = 0; self->pers_func = NULL; + self->pers_func_self = NULL; + memset(&self->buffer, 0, sizeof(Py_buffer)); self->input_buffer = NULL; self->input_line = NULL; self->input_len = 0; @@ -1623,19 +1677,14 @@ _Unpickler_New(void) self->marks_size = 0; self->proto = 0; self->fix_imports = 0; - memset(&self->buffer, 0, sizeof(Py_buffer)); - self->memo_size = 32; - self->memo_len = 0; - self->memo = _Unpickler_NewMemo(self->memo_size); - self->stack = (Pdata *)Pdata_New(); - - if (self->memo == NULL || self->stack == NULL) { - Py_DECREF(self); - return NULL; - } PyObject_GC_Track(self); return self; + +error: + PyMem_Free(memo); + Py_XDECREF(stack); + return NULL; } /* Returns -1 (with an exception set) on failure, 0 on success. This may @@ -1645,25 +1694,30 @@ _Unpickler_SetInputStream(UnpicklerObject *self, PyObject *file) { /* Optional file methods */ if (_PyObject_LookupAttr(file, &_Py_ID(peek), &self->peek) < 0) { - return -1; + goto error; } if (_PyObject_LookupAttr(file, &_Py_ID(readinto), &self->readinto) < 0) { - return -1; + goto error; + } + if (_PyObject_LookupAttr(file, &_Py_ID(read), &self->read) < 0) { + goto error; + } + if (_PyObject_LookupAttr(file, &_Py_ID(readline), &self->readline) < 0) { + goto error; } - (void)_PyObject_LookupAttr(file, &_Py_ID(read), &self->read); - (void)_PyObject_LookupAttr(file, &_Py_ID(readline), &self->readline); if (!self->readline || !self->read) { - if (!PyErr_Occurred()) { - PyErr_SetString(PyExc_TypeError, - "file must have 'read' and 'readline' attributes"); - } - Py_CLEAR(self->read); - Py_CLEAR(self->readinto); - Py_CLEAR(self->readline); - Py_CLEAR(self->peek); - return -1; + PyErr_SetString(PyExc_TypeError, + "file must have 'read' and 'readline' attributes"); + goto error; } return 0; + +error: + Py_CLEAR(self->read); + Py_CLEAR(self->readinto); + Py_CLEAR(self->readline); + Py_CLEAR(self->peek); + return -1; } /* Returns -1 (with an exception set) on failure, 0 on success. This may @@ -1706,7 +1760,7 @@ _Unpickler_SetBuffers(UnpicklerObject *self, PyObject *buffers) /* Generate a GET opcode for an object stored in the memo. */ static int -memo_get(PicklerObject *self, PyObject *key) +memo_get(PickleState *st, PicklerObject *self, PyObject *key) { Py_ssize_t *value; char pdata[30]; @@ -1739,7 +1793,6 @@ memo_get(PicklerObject *self, PyObject *key) len = 5; } else { /* unlikely */ - PickleState *st = _Pickle_GetGlobalState(); PyErr_SetString(st->PicklingError, "memo id too large for LONG_BINGET"); return -1; @@ -1755,7 +1808,7 @@ memo_get(PicklerObject *self, PyObject *key) /* Store an object in the memo, assign it a new unique ID based on the number of objects currently stored in the memo and generate a PUT opcode. */ static int -memo_put(PicklerObject *self, PyObject *obj) +memo_put(PickleState *st, PicklerObject *self, PyObject *obj) { char pdata[30]; Py_ssize_t len; @@ -1796,7 +1849,6 @@ memo_put(PicklerObject *self, PyObject *obj) len = 5; } else { /* unlikely */ - PickleState *st = _Pickle_GetGlobalState(); PyErr_SetString(st->PicklingError, "memo id too large for LONG_BINPUT"); return -1; @@ -1846,8 +1898,7 @@ get_deep_attribute(PyObject *obj, PyObject *names, PyObject **pparent) n = PyList_GET_SIZE(names); for (i = 0; i < n; i++) { PyObject *name = PyList_GET_ITEM(names, i); - Py_XDECREF(parent); - parent = obj; + Py_XSETREF(parent, obj); (void)_PyObject_LookupAttr(parent, name, &obj); if (obj == NULL) { Py_DECREF(parent); @@ -1940,8 +1991,7 @@ whichmodule(PyObject *global, PyObject *dotted_path) i = 0; while (PyDict_Next(modules, &i, &module_name, &module)) { if (_checkmodule(module_name, module, global, dotted_path) == 0) { - Py_INCREF(module_name); - return module_name; + return Py_NewRef(module_name); } if (PyErr_Occurred()) { return NULL; @@ -1977,8 +2027,7 @@ whichmodule(PyObject *global, PyObject *dotted_path) /* If no module is found, use __main__. */ module_name = &_Py_ID(__main__); - Py_INCREF(module_name); - return module_name; + return Py_NewRef(module_name); } /* fast_save_enter() and fast_save_leave() are guards against recursive @@ -2352,8 +2401,8 @@ _Pickler_write_bytes(PicklerObject *self, } static int -_save_bytes_data(PicklerObject *self, PyObject *obj, const char *data, - Py_ssize_t size) +_save_bytes_data(PickleState *st, PicklerObject *self, PyObject *obj, + const char *data, Py_ssize_t size) { assert(self->proto >= 3); @@ -2392,7 +2441,7 @@ _save_bytes_data(PicklerObject *self, PyObject *obj, const char *data, return -1; } - if (memo_put(self, obj) < 0) { + if (memo_put(st, self, obj) < 0) { return -1; } @@ -2400,7 +2449,7 @@ _save_bytes_data(PicklerObject *self, PyObject *obj, const char *data, } static int -save_bytes(PicklerObject *self, PyObject *obj) +save_bytes(PickleState *st, PicklerObject *self, PyObject *obj) { if (self->proto < 3) { /* Older pickle protocols do not have an opcode for pickling bytes @@ -2421,7 +2470,6 @@ save_bytes(PicklerObject *self, PyObject *obj) reduce_value = Py_BuildValue("(O())", (PyObject*)&PyBytes_Type); } else { - PickleState *st = _Pickle_GetGlobalState(); PyObject *unicode_str = PyUnicode_DecodeLatin1(PyBytes_AS_STRING(obj), PyBytes_GET_SIZE(obj), @@ -2439,19 +2487,19 @@ save_bytes(PicklerObject *self, PyObject *obj) return -1; /* save_reduce() will memoize the object automatically. */ - status = save_reduce(self, reduce_value, obj); + status = save_reduce(st, self, reduce_value, obj); Py_DECREF(reduce_value); return status; } else { - return _save_bytes_data(self, obj, PyBytes_AS_STRING(obj), + return _save_bytes_data(st, self, obj, PyBytes_AS_STRING(obj), PyBytes_GET_SIZE(obj)); } } static int -_save_bytearray_data(PicklerObject *self, PyObject *obj, const char *data, - Py_ssize_t size) +_save_bytearray_data(PickleState *state, PicklerObject *self, PyObject *obj, + const char *data, Py_ssize_t size) { assert(self->proto >= 5); @@ -2469,7 +2517,7 @@ _save_bytearray_data(PicklerObject *self, PyObject *obj, const char *data, return -1; } - if (memo_put(self, obj) < 0) { + if (memo_put(state, self, obj) < 0) { return -1; } @@ -2477,7 +2525,7 @@ _save_bytearray_data(PicklerObject *self, PyObject *obj, const char *data, } static int -save_bytearray(PicklerObject *self, PyObject *obj) +save_bytearray(PickleState *state, PicklerObject *self, PyObject *obj) { if (self->proto < 5) { /* Older pickle protocols do not have an opcode for pickling @@ -2502,21 +2550,21 @@ save_bytearray(PicklerObject *self, PyObject *obj) return -1; /* save_reduce() will memoize the object automatically. */ - status = save_reduce(self, reduce_value, obj); + status = save_reduce(state, self, reduce_value, obj); Py_DECREF(reduce_value); return status; } else { - return _save_bytearray_data(self, obj, PyByteArray_AS_STRING(obj), + return _save_bytearray_data(state, self, obj, + PyByteArray_AS_STRING(obj), PyByteArray_GET_SIZE(obj)); } } static int -save_picklebuffer(PicklerObject *self, PyObject *obj) +save_picklebuffer(PickleState *st, PicklerObject *self, PyObject *obj) { if (self->proto < 5) { - PickleState *st = _Pickle_GetGlobalState(); PyErr_SetString(st->PicklingError, "PickleBuffer can only pickled with protocol >= 5"); return -1; @@ -2526,7 +2574,6 @@ save_picklebuffer(PicklerObject *self, PyObject *obj) return -1; } if (view->suboffsets != NULL || !PyBuffer_IsContiguous(view, 'A')) { - PickleState *st = _Pickle_GetGlobalState(); PyErr_SetString(st->PicklingError, "PickleBuffer can not be pickled when " "pointing to a non-contiguous buffer"); @@ -2547,11 +2594,11 @@ save_picklebuffer(PicklerObject *self, PyObject *obj) if (in_band) { /* Write data in-band */ if (view->readonly) { - return _save_bytes_data(self, obj, (const char*) view->buf, + return _save_bytes_data(st, self, obj, (const char *)view->buf, view->len); } else { - return _save_bytearray_data(self, obj, (const char*) view->buf, + return _save_bytearray_data(st, self, obj, (const char *)view->buf, view->len); } } @@ -2579,7 +2626,7 @@ raw_unicode_escape(PyObject *obj) char *p; Py_ssize_t i, size; const void *data; - unsigned int kind; + int kind; _PyBytesWriter writer; if (PyUnicode_READY(obj)) @@ -2706,7 +2753,7 @@ write_unicode_binary(PicklerObject *self, PyObject *obj) } static int -save_unicode(PicklerObject *self, PyObject *obj) +save_unicode(PickleState *state, PicklerObject *self, PyObject *obj) { if (self->bin) { if (write_unicode_binary(self, obj) < 0) @@ -2736,7 +2783,7 @@ save_unicode(PicklerObject *self, PyObject *obj) if (_Pickler_Write(self, "\n", 1) < 0) return -1; } - if (memo_put(self, obj) < 0) + if (memo_put(state, self, obj) < 0) return -1; return 0; @@ -2744,7 +2791,8 @@ save_unicode(PicklerObject *self, PyObject *obj) /* A helper for save_tuple. Push the len elements in tuple t on the stack. */ static int -store_tuple_elements(PicklerObject *self, PyObject *t, Py_ssize_t len) +store_tuple_elements(PickleState *state, PicklerObject *self, PyObject *t, + Py_ssize_t len) { Py_ssize_t i; @@ -2755,7 +2803,7 @@ store_tuple_elements(PicklerObject *self, PyObject *t, Py_ssize_t len) if (element == NULL) return -1; - if (save(self, element, 0) < 0) + if (save(state, self, element, 0) < 0) return -1; } @@ -2769,7 +2817,7 @@ store_tuple_elements(PicklerObject *self, PyObject *t, Py_ssize_t len) * magic so that it works in all cases. IOW, this is a long routine. */ static int -save_tuple(PicklerObject *self, PyObject *obj) +save_tuple(PickleState *state, PicklerObject *self, PyObject *obj) { Py_ssize_t len, i; @@ -2806,7 +2854,7 @@ save_tuple(PicklerObject *self, PyObject *obj) */ if (len <= 3 && self->proto >= 2) { /* Use TUPLE{1,2,3} opcodes. */ - if (store_tuple_elements(self, obj, len) < 0) + if (store_tuple_elements(state, self, obj, len) < 0) return -1; if (PyMemoTable_Get(self->memo, obj)) { @@ -2815,7 +2863,7 @@ save_tuple(PicklerObject *self, PyObject *obj) if (_Pickler_Write(self, &pop_op, 1) < 0) return -1; /* fetch from memo */ - if (memo_get(self, obj) < 0) + if (memo_get(state, self, obj) < 0) return -1; return 0; @@ -2833,7 +2881,7 @@ save_tuple(PicklerObject *self, PyObject *obj) if (_Pickler_Write(self, &mark_op, 1) < 0) return -1; - if (store_tuple_elements(self, obj, len) < 0) + if (store_tuple_elements(state, self, obj, len) < 0) return -1; if (PyMemoTable_Get(self->memo, obj)) { @@ -2851,7 +2899,7 @@ save_tuple(PicklerObject *self, PyObject *obj) return -1; } /* fetch from memo */ - if (memo_get(self, obj) < 0) + if (memo_get(state, self, obj) < 0) return -1; return 0; @@ -2862,7 +2910,7 @@ save_tuple(PicklerObject *self, PyObject *obj) } memoize: - if (memo_put(self, obj) < 0) + if (memo_put(state, self, obj) < 0) return -1; return 0; @@ -2875,7 +2923,7 @@ save_tuple(PicklerObject *self, PyObject *obj) * Returns 0 on success, <0 on error. */ static int -batch_list(PicklerObject *self, PyObject *iter) +batch_list(PickleState *state, PicklerObject *self, PyObject *iter) { PyObject *obj = NULL; PyObject *firstitem = NULL; @@ -2901,7 +2949,7 @@ batch_list(PicklerObject *self, PyObject *iter) return -1; break; } - i = save(self, obj, 0); + i = save(state, self, obj, 0); Py_DECREF(obj); if (i < 0) return -1; @@ -2930,7 +2978,7 @@ batch_list(PicklerObject *self, PyObject *iter) goto error; /* Only one item to write */ - if (save(self, firstitem, 0) < 0) + if (save(state, self, firstitem, 0) < 0) goto error; if (_Pickler_Write(self, &append_op, 1) < 0) goto error; @@ -2944,14 +2992,14 @@ batch_list(PicklerObject *self, PyObject *iter) if (_Pickler_Write(self, &mark_op, 1) < 0) goto error; - if (save(self, firstitem, 0) < 0) + if (save(state, self, firstitem, 0) < 0) goto error; Py_CLEAR(firstitem); n = 1; /* Fetch and save up to BATCHSIZE items */ while (obj) { - if (save(self, obj, 0) < 0) + if (save(state, self, obj, 0) < 0) goto error; Py_CLEAR(obj); n += 1; @@ -2991,7 +3039,7 @@ batch_list(PicklerObject *self, PyObject *iter) * Note that this only works for protocols > 0. */ static int -batch_list_exact(PicklerObject *self, PyObject *obj) +batch_list_exact(PickleState *state, PicklerObject *self, PyObject *obj) { PyObject *item = NULL; Py_ssize_t this_batch, total; @@ -3007,7 +3055,7 @@ batch_list_exact(PicklerObject *self, PyObject *obj) if (PyList_GET_SIZE(obj) == 1) { item = PyList_GET_ITEM(obj, 0); Py_INCREF(item); - int err = save(self, item, 0); + int err = save(state, self, item, 0); Py_DECREF(item); if (err < 0) return -1; @@ -3025,7 +3073,7 @@ batch_list_exact(PicklerObject *self, PyObject *obj) while (total < PyList_GET_SIZE(obj)) { item = PyList_GET_ITEM(obj, total); Py_INCREF(item); - int err = save(self, item, 0); + int err = save(state, self, item, 0); Py_DECREF(item); if (err < 0) return -1; @@ -3042,7 +3090,7 @@ batch_list_exact(PicklerObject *self, PyObject *obj) } static int -save_list(PicklerObject *self, PyObject *obj) +save_list(PickleState *state, PicklerObject *self, PyObject *obj) { char header[3]; Py_ssize_t len; @@ -3069,7 +3117,7 @@ save_list(PicklerObject *self, PyObject *obj) if ((len = PyList_Size(obj)) < 0) goto error; - if (memo_put(self, obj) < 0) + if (memo_put(state, self, obj) < 0) goto error; if (len != 0) { @@ -3077,7 +3125,7 @@ save_list(PicklerObject *self, PyObject *obj) if (PyList_CheckExact(obj) && self->proto > 0) { if (_Py_EnterRecursiveCall(" while pickling an object")) goto error; - status = batch_list_exact(self, obj); + status = batch_list_exact(state, self, obj); _Py_LeaveRecursiveCall(); } else { PyObject *iter = PyObject_GetIter(obj); @@ -3088,7 +3136,7 @@ save_list(PicklerObject *self, PyObject *obj) Py_DECREF(iter); goto error; } - status = batch_list(self, iter); + status = batch_list(state, self, iter); _Py_LeaveRecursiveCall(); Py_DECREF(iter); } @@ -3116,7 +3164,7 @@ save_list(PicklerObject *self, PyObject *obj) * ugly to bear. */ static int -batch_dict(PicklerObject *self, PyObject *iter) +batch_dict(PickleState *state, PicklerObject *self, PyObject *iter) { PyObject *obj = NULL; PyObject *firstitem = NULL; @@ -3142,9 +3190,9 @@ batch_dict(PicklerObject *self, PyObject *iter) "iterator must return 2-tuples"); return -1; } - i = save(self, PyTuple_GET_ITEM(obj, 0), 0); + i = save(state, self, PyTuple_GET_ITEM(obj, 0), 0); if (i >= 0) - i = save(self, PyTuple_GET_ITEM(obj, 1), 0); + i = save(state, self, PyTuple_GET_ITEM(obj, 1), 0); Py_DECREF(obj); if (i < 0) return -1; @@ -3178,9 +3226,9 @@ batch_dict(PicklerObject *self, PyObject *iter) goto error; /* Only one item to write */ - if (save(self, PyTuple_GET_ITEM(firstitem, 0), 0) < 0) + if (save(state, self, PyTuple_GET_ITEM(firstitem, 0), 0) < 0) goto error; - if (save(self, PyTuple_GET_ITEM(firstitem, 1), 0) < 0) + if (save(state, self, PyTuple_GET_ITEM(firstitem, 1), 0) < 0) goto error; if (_Pickler_Write(self, &setitem_op, 1) < 0) goto error; @@ -3194,9 +3242,9 @@ batch_dict(PicklerObject *self, PyObject *iter) if (_Pickler_Write(self, &mark_op, 1) < 0) goto error; - if (save(self, PyTuple_GET_ITEM(firstitem, 0), 0) < 0) + if (save(state, self, PyTuple_GET_ITEM(firstitem, 0), 0) < 0) goto error; - if (save(self, PyTuple_GET_ITEM(firstitem, 1), 0) < 0) + if (save(state, self, PyTuple_GET_ITEM(firstitem, 1), 0) < 0) goto error; Py_CLEAR(firstitem); n = 1; @@ -3208,8 +3256,8 @@ batch_dict(PicklerObject *self, PyObject *iter) "iterator must return 2-tuples"); goto error; } - if (save(self, PyTuple_GET_ITEM(obj, 0), 0) < 0 || - save(self, PyTuple_GET_ITEM(obj, 1), 0) < 0) + if (save(state, self, PyTuple_GET_ITEM(obj, 0), 0) < 0 || + save(state, self, PyTuple_GET_ITEM(obj, 1), 0) < 0) goto error; Py_CLEAR(obj); n += 1; @@ -3247,7 +3295,7 @@ batch_dict(PicklerObject *self, PyObject *iter) * Note that this currently doesn't work for protocol 0. */ static int -batch_dict_exact(PicklerObject *self, PyObject *obj) +batch_dict_exact(PickleState *state, PicklerObject *self, PyObject *obj) { PyObject *key = NULL, *value = NULL; int i; @@ -3267,10 +3315,10 @@ batch_dict_exact(PicklerObject *self, PyObject *obj) PyDict_Next(obj, &ppos, &key, &value); Py_INCREF(key); Py_INCREF(value); - if (save(self, key, 0) < 0) { + if (save(state, self, key, 0) < 0) { goto error; } - if (save(self, value, 0) < 0) { + if (save(state, self, value, 0) < 0) { goto error; } Py_CLEAR(key); @@ -3288,10 +3336,10 @@ batch_dict_exact(PicklerObject *self, PyObject *obj) while (PyDict_Next(obj, &ppos, &key, &value)) { Py_INCREF(key); Py_INCREF(value); - if (save(self, key, 0) < 0) { + if (save(state, self, key, 0) < 0) { goto error; } - if (save(self, value, 0) < 0) { + if (save(state, self, value, 0) < 0) { goto error; } Py_CLEAR(key); @@ -3317,7 +3365,7 @@ error: } static int -save_dict(PicklerObject *self, PyObject *obj) +save_dict(PickleState *state, PicklerObject *self, PyObject *obj) { PyObject *items, *iter; char header[3]; @@ -3342,7 +3390,7 @@ save_dict(PicklerObject *self, PyObject *obj) if (_Pickler_Write(self, header, len) < 0) goto error; - if (memo_put(self, obj) < 0) + if (memo_put(state, self, obj) < 0) goto error; if (PyDict_GET_SIZE(obj)) { @@ -3352,7 +3400,7 @@ save_dict(PicklerObject *self, PyObject *obj) not a dict subclass. */ if (_Py_EnterRecursiveCall(" while pickling an object")) goto error; - status = batch_dict_exact(self, obj); + status = batch_dict_exact(state, self, obj); _Py_LeaveRecursiveCall(); } else { items = PyObject_CallMethodNoArgs(obj, &_Py_ID(items)); @@ -3366,7 +3414,7 @@ save_dict(PicklerObject *self, PyObject *obj) Py_DECREF(iter); goto error; } - status = batch_dict(self, iter); + status = batch_dict(state, self, iter); _Py_LeaveRecursiveCall(); Py_DECREF(iter); } @@ -3384,7 +3432,7 @@ save_dict(PicklerObject *self, PyObject *obj) } static int -save_set(PicklerObject *self, PyObject *obj) +save_set(PickleState *state, PicklerObject *self, PyObject *obj) { PyObject *item; int i; @@ -3410,7 +3458,7 @@ save_set(PicklerObject *self, PyObject *obj) return -1; } /* save_reduce() will memoize the object automatically. */ - status = save_reduce(self, reduce_value, obj); + status = save_reduce(state, self, reduce_value, obj); Py_DECREF(reduce_value); return status; } @@ -3418,7 +3466,7 @@ save_set(PicklerObject *self, PyObject *obj) if (_Pickler_Write(self, &empty_set_op, 1) < 0) return -1; - if (memo_put(self, obj) < 0) + if (memo_put(state, self, obj) < 0) return -1; set_size = PySet_GET_SIZE(obj); @@ -3432,7 +3480,7 @@ save_set(PicklerObject *self, PyObject *obj) return -1; while (_PySet_NextEntry(obj, &ppos, &item, &hash)) { Py_INCREF(item); - int err = save(self, item, 0); + int err = save(state, self, item, 0); Py_CLEAR(item); if (err < 0) return -1; @@ -3453,7 +3501,7 @@ save_set(PicklerObject *self, PyObject *obj) } static int -save_frozenset(PicklerObject *self, PyObject *obj) +save_frozenset(PickleState *state, PicklerObject *self, PyObject *obj) { PyObject *iter; @@ -3479,7 +3527,7 @@ save_frozenset(PicklerObject *self, PyObject *obj) return -1; } /* save_reduce() will memoize the object automatically. */ - status = save_reduce(self, reduce_value, obj); + status = save_reduce(state, self, reduce_value, obj); Py_DECREF(reduce_value); return status; } @@ -3502,7 +3550,7 @@ save_frozenset(PicklerObject *self, PyObject *obj) } break; } - if (save(self, item, 0) < 0) { + if (save(state, self, item, 0) < 0) { Py_DECREF(item); Py_DECREF(iter); return -1; @@ -3519,25 +3567,24 @@ save_frozenset(PicklerObject *self, PyObject *obj) if (_Pickler_Write(self, &pop_mark_op, 1) < 0) return -1; - if (memo_get(self, obj) < 0) + if (memo_get(state, self, obj) < 0) return -1; return 0; } if (_Pickler_Write(self, &frozenset_op, 1) < 0) return -1; - if (memo_put(self, obj) < 0) + if (memo_put(state, self, obj) < 0) return -1; return 0; } static int -fix_imports(PyObject **module_name, PyObject **global_name) +fix_imports(PickleState *st, PyObject **module_name, PyObject **global_name) { PyObject *key; PyObject *item; - PickleState *st = _Pickle_GetGlobalState(); key = PyTuple_Pack(2, *module_name, *global_name); if (key == NULL) @@ -3569,10 +3616,8 @@ fix_imports(PyObject **module_name, PyObject **global_name) Py_CLEAR(*module_name); Py_CLEAR(*global_name); - Py_INCREF(fixed_module_name); - Py_INCREF(fixed_global_name); - *module_name = fixed_module_name; - *global_name = fixed_global_name; + *module_name = Py_NewRef(fixed_module_name); + *global_name = Py_NewRef(fixed_global_name); return 0; } else if (PyErr_Occurred()) { @@ -3588,8 +3633,7 @@ fix_imports(PyObject **module_name, PyObject **global_name) Py_TYPE(item)->tp_name); return -1; } - Py_INCREF(item); - Py_XSETREF(*module_name, item); + Py_XSETREF(*module_name, Py_NewRef(item)); } else if (PyErr_Occurred()) { return -1; @@ -3599,7 +3643,8 @@ fix_imports(PyObject **module_name, PyObject **global_name) } static int -save_global(PicklerObject *self, PyObject *obj, PyObject *name) +save_global(PickleState *st, PicklerObject *self, PyObject *obj, + PyObject *name) { PyObject *global_name = NULL; PyObject *module_name = NULL; @@ -3608,14 +3653,12 @@ save_global(PicklerObject *self, PyObject *obj, PyObject *name) PyObject *dotted_path = NULL; PyObject *lastname = NULL; PyObject *cls; - PickleState *st = _Pickle_GetGlobalState(); int status = 0; const char global_op = GLOBAL; if (name) { - Py_INCREF(name); - global_name = name; + global_name = Py_NewRef(name); } else { if (_PyObject_LookupAttr(obj, &_Py_ID(__qualname__), &global_name) < 0) @@ -3649,8 +3692,8 @@ save_global(PicklerObject *self, PyObject *obj, PyObject *name) obj, module_name); goto error; } - lastname = PyList_GET_ITEM(dotted_path, PyList_GET_SIZE(dotted_path)-1); - Py_INCREF(lastname); + lastname = Py_NewRef(PyList_GET_ITEM(dotted_path, + PyList_GET_SIZE(dotted_path) - 1)); cls = get_deep_attribute(module, dotted_path, &parent); Py_CLEAR(dotted_path); if (cls == NULL) { @@ -3740,28 +3783,25 @@ save_global(PicklerObject *self, PyObject *obj, PyObject *name) else { gen_global: if (parent == module) { - Py_INCREF(lastname); - Py_DECREF(global_name); - global_name = lastname; + Py_SETREF(global_name, Py_NewRef(lastname)); } if (self->proto >= 4) { const char stack_global_op = STACK_GLOBAL; - if (save(self, module_name, 0) < 0) + if (save(st, self, module_name, 0) < 0) goto error; - if (save(self, global_name, 0) < 0) + if (save(st, self, global_name, 0) < 0) goto error; if (_Pickler_Write(self, &stack_global_op, 1) < 0) goto error; } else if (parent != module) { - PickleState *st = _Pickle_GetGlobalState(); PyObject *reduce_value = Py_BuildValue("(O(OO))", st->getattr, parent, lastname); if (reduce_value == NULL) goto error; - status = save_reduce(self, reduce_value, NULL); + status = save_reduce(st, self, reduce_value, NULL); Py_DECREF(reduce_value); if (status < 0) goto error; @@ -3779,7 +3819,7 @@ save_global(PicklerObject *self, PyObject *obj, PyObject *name) /* For protocol < 3 and if the user didn't request against doing so, we convert module names to the old 2.x module names. */ if (self->proto < 3 && self->fix_imports) { - if (fix_imports(&module_name, &global_name) < 0) { + if (fix_imports(st, &module_name, &global_name) < 0) { goto error; } } @@ -3833,7 +3873,7 @@ save_global(PicklerObject *self, PyObject *obj, PyObject *name) goto error; } /* Memoize the object. */ - if (memo_put(self, obj) < 0) + if (memo_put(st, self, obj) < 0) goto error; } @@ -3852,7 +3892,8 @@ save_global(PicklerObject *self, PyObject *obj, PyObject *name) } static int -save_singleton_type(PicklerObject *self, PyObject *obj, PyObject *singleton) +save_singleton_type(PickleState *state, PicklerObject *self, PyObject *obj, + PyObject *singleton) { PyObject *reduce_value; int status; @@ -3861,28 +3902,28 @@ save_singleton_type(PicklerObject *self, PyObject *obj, PyObject *singleton) if (reduce_value == NULL) { return -1; } - status = save_reduce(self, reduce_value, obj); + status = save_reduce(state, self, reduce_value, obj); Py_DECREF(reduce_value); return status; } static int -save_type(PicklerObject *self, PyObject *obj) +save_type(PickleState *state, PicklerObject *self, PyObject *obj) { if (obj == (PyObject *)&_PyNone_Type) { - return save_singleton_type(self, obj, Py_None); + return save_singleton_type(state, self, obj, Py_None); } else if (obj == (PyObject *)&PyEllipsis_Type) { - return save_singleton_type(self, obj, Py_Ellipsis); + return save_singleton_type(state, self, obj, Py_Ellipsis); } else if (obj == (PyObject *)&_PyNotImplemented_Type) { - return save_singleton_type(self, obj, Py_NotImplemented); + return save_singleton_type(state, self, obj, Py_NotImplemented); } - return save_global(self, obj, NULL); + return save_global(state, self, obj, NULL); } static int -save_pers(PicklerObject *self, PyObject *obj) +save_pers(PickleState *state, PicklerObject *self, PyObject *obj) { PyObject *pid = NULL; int status = 0; @@ -3896,7 +3937,7 @@ save_pers(PicklerObject *self, PyObject *obj) if (pid != Py_None) { if (self->bin) { - if (save(self, pid, 1) < 0 || + if (save(state, self, pid, 1) < 0 || _Pickler_Write(self, &binpersid_op, 1) < 0) goto error; } @@ -3910,7 +3951,7 @@ save_pers(PicklerObject *self, PyObject *obj) /* XXX: Should it check whether the pid contains embedded newlines? */ if (!PyUnicode_IS_ASCII(pid_str)) { - PyErr_SetString(_Pickle_GetGlobalState()->PicklingError, + PyErr_SetString(state->PicklingError, "persistent IDs in protocol 0 must be " "ASCII strings"); Py_DECREF(pid_str); @@ -3944,8 +3985,7 @@ get_class(PyObject *obj) PyObject *cls; if (_PyObject_LookupAttr(obj, &_Py_ID(__class__), &cls) == 0) { - cls = (PyObject *) Py_TYPE(obj); - Py_INCREF(cls); + cls = Py_NewRef(Py_TYPE(obj)); } return cls; } @@ -3954,7 +3994,8 @@ get_class(PyObject *obj) * appropriate __reduce__ method for obj. */ static int -save_reduce(PicklerObject *self, PyObject *args, PyObject *obj) +save_reduce(PickleState *st, PicklerObject *self, PyObject *args, + PyObject *obj) { PyObject *callable; PyObject *argtup; @@ -3962,7 +4003,6 @@ save_reduce(PicklerObject *self, PyObject *args, PyObject *obj) PyObject *listitems = Py_None; PyObject *dictitems = Py_None; PyObject *state_setter = Py_None; - PickleState *st = _Pickle_GetGlobalState(); Py_ssize_t size; int use_newobj = 0, use_newobj_ex = 0; @@ -4074,9 +4114,9 @@ save_reduce(PicklerObject *self, PyObject *args, PyObject *obj) } if (self->proto >= 4) { - if (save(self, cls, 0) < 0 || - save(self, args, 0) < 0 || - save(self, kwargs, 0) < 0 || + if (save(st, self, cls, 0) < 0 || + save(st, self, args, 0) < 0 || + save(st, self, kwargs, 0) < 0 || _Pickler_Write(self, &newobj_ex_op, 1) < 0) { return -1; } @@ -4096,12 +4136,10 @@ save_reduce(PicklerObject *self, PyObject *args, PyObject *obj) return -1; } PyTuple_SET_ITEM(newargs, 0, cls_new); - Py_INCREF(cls); - PyTuple_SET_ITEM(newargs, 1, cls); + PyTuple_SET_ITEM(newargs, 1, Py_NewRef(cls)); for (i = 0; i < PyTuple_GET_SIZE(args); i++) { PyObject *item = PyTuple_GET_ITEM(args, i); - Py_INCREF(item); - PyTuple_SET_ITEM(newargs, i + 2, item); + PyTuple_SET_ITEM(newargs, i + 2, Py_NewRef(item)); } callable = PyObject_Call(st->partial, newargs, kwargs); @@ -4115,8 +4153,8 @@ save_reduce(PicklerObject *self, PyObject *args, PyObject *obj) return -1; } - if (save(self, callable, 0) < 0 || - save(self, newargs, 0) < 0 || + if (save(st, self, callable, 0) < 0 || + save(st, self, newargs, 0) < 0 || _Pickler_Write(self, &reduce_op, 1) < 0) { Py_DECREF(newargs); Py_DECREF(callable); @@ -4186,14 +4224,15 @@ save_reduce(PicklerObject *self, PyObject *args, PyObject *obj) function. */ /* Save the class and its __new__ arguments. */ - if (save(self, cls, 0) < 0) + if (save(st, self, cls, 0) < 0) { return -1; + } newargtup = PyTuple_GetSlice(argtup, 1, PyTuple_GET_SIZE(argtup)); if (newargtup == NULL) return -1; - p = save(self, newargtup, 0); + p = save(st, self, newargtup, 0); Py_DECREF(newargtup); if (p < 0) return -1; @@ -4203,8 +4242,8 @@ save_reduce(PicklerObject *self, PyObject *args, PyObject *obj) return -1; } else { /* Not using NEWOBJ. */ - if (save(self, callable, 0) < 0 || - save(self, argtup, 0) < 0 || + if (save(st, self, callable, 0) < 0 || + save(st, self, argtup, 0) < 0 || _Pickler_Write(self, &reduce_op, 1) < 0) return -1; } @@ -4222,24 +4261,24 @@ save_reduce(PicklerObject *self, PyObject *args, PyObject *obj) if (_Pickler_Write(self, &pop_op, 1) < 0) return -1; - if (memo_get(self, obj) < 0) + if (memo_get(st, self, obj) < 0) return -1; return 0; } - else if (memo_put(self, obj) < 0) + else if (memo_put(st, self, obj) < 0) return -1; } - if (listitems && batch_list(self, listitems) < 0) + if (listitems && batch_list(st, self, listitems) < 0) return -1; - if (dictitems && batch_dict(self, dictitems) < 0) + if (dictitems && batch_dict(st, self, dictitems) < 0) return -1; if (state) { if (state_setter == NULL) { - if (save(self, state, 0) < 0 || + if (save(st, self, state, 0) < 0 || _Pickler_Write(self, &build_op, 1) < 0) return -1; } @@ -4256,8 +4295,8 @@ save_reduce(PicklerObject *self, PyObject *args, PyObject *obj) const char tupletwo_op = TUPLE2; const char pop_op = POP; - if (save(self, state_setter, 0) < 0 || - save(self, obj, 0) < 0 || save(self, state, 0) < 0 || + if (save(st, self, state_setter, 0) < 0 || + save(st, self, obj, 0) < 0 || save(st, self, state, 0) < 0 || _Pickler_Write(self, &tupletwo_op, 1) < 0 || _Pickler_Write(self, &reduce_op, 1) < 0 || _Pickler_Write(self, &pop_op, 1) < 0) @@ -4268,7 +4307,7 @@ save_reduce(PicklerObject *self, PyObject *args, PyObject *obj) } static int -save(PicklerObject *self, PyObject *obj, int pers_save) +save(PickleState *st, PicklerObject *self, PyObject *obj, int pers_save) { PyTypeObject *type; PyObject *reduce_func = NULL; @@ -4286,7 +4325,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)) != 0) + if ((status = save_pers(st, self, obj)) != 0) return status; } @@ -4316,14 +4355,14 @@ save(PicklerObject *self, PyObject *obj, int pers_save) a GET (or BINGET) opcode, instead of pickling the object once again. */ if (PyMemoTable_Get(self->memo, obj)) { - return memo_get(self, obj); + return memo_get(st, self, obj); } if (type == &PyBytes_Type) { - return save_bytes(self, obj); + return save_bytes(st, self, obj); } else if (type == &PyUnicode_Type) { - return save_unicode(self, obj); + return save_unicode(st, self, obj); } /* We're only calling _Py_EnterRecursiveCall here so that atomic @@ -4333,31 +4372,31 @@ save(PicklerObject *self, PyObject *obj, int pers_save) } if (type == &PyDict_Type) { - status = save_dict(self, obj); + status = save_dict(st, self, obj); goto done; } else if (type == &PySet_Type) { - status = save_set(self, obj); + status = save_set(st, self, obj); goto done; } else if (type == &PyFrozenSet_Type) { - status = save_frozenset(self, obj); + status = save_frozenset(st, self, obj); goto done; } else if (type == &PyList_Type) { - status = save_list(self, obj); + status = save_list(st, self, obj); goto done; } else if (type == &PyTuple_Type) { - status = save_tuple(self, obj); + status = save_tuple(st, self, obj); goto done; } else if (type == &PyByteArray_Type) { - status = save_bytearray(self, obj); + status = save_bytearray(st, self, obj); goto done; } else if (type == &PyPickleBuffer_Type) { - status = save_picklebuffer(self, obj); + status = save_picklebuffer(st, self, obj); goto done; } @@ -4373,16 +4412,15 @@ save(PicklerObject *self, PyObject *obj, int pers_save) if (reduce_value != Py_NotImplemented) { goto reduce; } - Py_DECREF(reduce_value); - reduce_value = NULL; + Py_SETREF(reduce_value, NULL); } if (type == &PyType_Type) { - status = save_type(self, obj); + status = save_type(st, self, obj); goto done; } else if (type == &PyFunction_Type) { - status = save_global(self, obj, NULL); + status = save_global(st, self, obj, NULL); goto done; } @@ -4393,7 +4431,6 @@ save(PicklerObject *self, PyObject *obj, int pers_save) * __reduce_ex__ method, or the object's __reduce__ method. */ if (self->dispatch_table == NULL) { - PickleState *st = _Pickle_GetGlobalState(); reduce_func = PyDict_GetItemWithError(st->dispatch_table, (PyObject *)type); if (reduce_func == NULL) { @@ -4417,11 +4454,10 @@ save(PicklerObject *self, PyObject *obj, int pers_save) } } if (reduce_func != NULL) { - Py_INCREF(obj); - reduce_value = _Pickle_FastCall(reduce_func, obj); + reduce_value = _Pickle_FastCall(reduce_func, Py_NewRef(obj)); } else if (PyType_IsSubtype(type, &PyType_Type)) { - status = save_global(self, obj, NULL); + status = save_global(st, self, obj, NULL); goto done; } else { @@ -4453,7 +4489,6 @@ save(PicklerObject *self, PyObject *obj, int pers_save) reduce_value = PyObject_CallNoArgs(reduce_func); } else { - PickleState *st = _Pickle_GetGlobalState(); PyErr_Format(st->PicklingError, "can't pickle '%.200s' object: %R", type->tp_name, obj); @@ -4467,18 +4502,17 @@ save(PicklerObject *self, PyObject *obj, int pers_save) reduce: if (PyUnicode_Check(reduce_value)) { - status = save_global(self, obj, reduce_value); + status = save_global(st, self, obj, reduce_value); goto done; } if (!PyTuple_Check(reduce_value)) { - PickleState *st = _Pickle_GetGlobalState(); PyErr_SetString(st->PicklingError, "__reduce__ must return a string or tuple"); goto error; } - status = save_reduce(self, reduce_value, obj); + status = save_reduce(st, self, reduce_value, obj); if (0) { error: @@ -4494,7 +4528,7 @@ save(PicklerObject *self, PyObject *obj, int pers_save) } static int -dump(PicklerObject *self, PyObject *obj) +dump(PickleState *state, PicklerObject *self, PyObject *obj) { const char stop_op = STOP; int status = -1; @@ -4524,7 +4558,7 @@ dump(PicklerObject *self, PyObject *obj) self->framing = 1; } - if (save(self, obj, 0) < 0 || + if (save(state, self, obj, 0) < 0 || _Pickler_Write(self, &stop_op, 1) < 0 || _Pickler_CommitFrame(self) < 0) goto error; @@ -4571,6 +4605,7 @@ _pickle_Pickler_clear_memo_impl(PicklerObject *self) _pickle.Pickler.dump + cls: defining_class obj: object / @@ -4578,14 +4613,15 @@ Write a pickled representation of the given object to the open file. [clinic start generated code]*/ static PyObject * -_pickle_Pickler_dump(PicklerObject *self, PyObject *obj) -/*[clinic end generated code: output=87ecad1261e02ac7 input=552eb1c0f52260d9]*/ +_pickle_Pickler_dump_impl(PicklerObject *self, PyTypeObject *cls, + PyObject *obj) +/*[clinic end generated code: output=952cf7f68b1445bb input=f949d84151983594]*/ { + PickleState *st = _Pickle_GetStateByClass(cls); /* Check whether the Pickler was initialized correctly (issue3664). Developers often forget to call __init__() in their subclasses, which would trigger a segfault without this check. */ if (self->write == NULL) { - PickleState *st = _Pickle_GetGlobalState(); PyErr_Format(st->PicklingError, "Pickler.__init__() was not called by %s.__init__()", Py_TYPE(self)->tp_name); @@ -4595,7 +4631,7 @@ _pickle_Pickler_dump(PicklerObject *self, PyObject *obj) if (_Pickler_ClearBuffer(self) < 0) return NULL; - if (dump(self, obj) < 0) + if (dump(st, self, obj) < 0) return NULL; if (_Pickler_FlushToFile(self) < 0) @@ -4606,26 +4642,25 @@ _pickle_Pickler_dump(PicklerObject *self, PyObject *obj) /*[clinic input] -_pickle.Pickler.__sizeof__ -> Py_ssize_t +_pickle.Pickler.__sizeof__ -> size_t Returns size in memory, in bytes. [clinic start generated code]*/ -static Py_ssize_t +static size_t _pickle_Pickler___sizeof___impl(PicklerObject *self) -/*[clinic end generated code: output=106edb3123f332e1 input=8cbbec9bd5540d42]*/ +/*[clinic end generated code: output=23ad75658d3b59ff input=d8127c8e7012ebd7]*/ { - Py_ssize_t res, s; - - res = _PyObject_SIZE(Py_TYPE(self)); + size_t res = _PyObject_SIZE(Py_TYPE(self)); if (self->memo != NULL) { res += sizeof(PyMemoTable); res += self->memo->mt_allocated * sizeof(PyMemoEntry); } if (self->output_buffer != NULL) { - s = _PySys_GetSizeOf(self->output_buffer); - if (s == -1) + size_t s = _PySys_GetSizeOf(self->output_buffer); + if (s == (size_t)-1) { return -1; + } res += s; } return res; @@ -4638,36 +4673,6 @@ static struct PyMethodDef Pickler_methods[] = { {NULL, NULL} /* sentinel */ }; -static void -Pickler_dealloc(PicklerObject *self) -{ - PyObject_GC_UnTrack(self); - - Py_XDECREF(self->output_buffer); - Py_XDECREF(self->write); - Py_XDECREF(self->pers_func); - Py_XDECREF(self->dispatch_table); - Py_XDECREF(self->fast_memo); - Py_XDECREF(self->reducer_override); - Py_XDECREF(self->buffer_callback); - - PyMemoTable_Del(self->memo); - - Py_TYPE(self)->tp_free((PyObject *)self); -} - -static int -Pickler_traverse(PicklerObject *self, visitproc visit, void *arg) -{ - Py_VISIT(self->write); - Py_VISIT(self->pers_func); - Py_VISIT(self->dispatch_table); - Py_VISIT(self->fast_memo); - Py_VISIT(self->reducer_override); - Py_VISIT(self->buffer_callback); - return 0; -} - static int Pickler_clear(PicklerObject *self) { @@ -4687,6 +4692,29 @@ Pickler_clear(PicklerObject *self) return 0; } +static void +Pickler_dealloc(PicklerObject *self) +{ + PyTypeObject *tp = Py_TYPE(self); + PyObject_GC_UnTrack(self); + (void)Pickler_clear(self); + tp->tp_free((PyObject *)self); + Py_DECREF(tp); +} + +static int +Pickler_traverse(PicklerObject *self, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(self)); + Py_VISIT(self->write); + Py_VISIT(self->pers_func); + Py_VISIT(self->dispatch_table); + Py_VISIT(self->fast_memo); + Py_VISIT(self->reducer_override); + Py_VISIT(self->buffer_callback); + return 0; +} + /*[clinic input] @@ -4833,11 +4861,12 @@ _pickle_PicklerMemoProxy_copy_impl(PicklerMemoProxyObject *self) PyObject *key, *value; key = PyLong_FromVoidPtr(entry.me_key); + if (key == NULL) { + goto error; + } value = Py_BuildValue("nO", entry.me_value, entry.me_key); - - if (key == NULL || value == NULL) { - Py_XDECREF(key); - Py_XDECREF(value); + if (value == NULL) { + Py_DECREF(key); goto error; } status = PyDict_SetItem(new_memo, key, value); @@ -4881,8 +4910,7 @@ _pickle_PicklerMemoProxy___reduce___impl(PicklerMemoProxyObject *self) return NULL; } PyTuple_SET_ITEM(dict_args, 0, contents); - Py_INCREF((PyObject *)&PyDict_Type); - PyTuple_SET_ITEM(reduce_value, 0, (PyObject *)&PyDict_Type); + PyTuple_SET_ITEM(reduce_value, 0, Py_NewRef(&PyDict_Type)); PyTuple_SET_ITEM(reduce_value, 1, dict_args); return reduce_value; } @@ -4897,15 +4925,18 @@ static PyMethodDef picklerproxy_methods[] = { static void PicklerMemoProxy_dealloc(PicklerMemoProxyObject *self) { + PyTypeObject *tp = Py_TYPE(self); PyObject_GC_UnTrack(self); - Py_XDECREF(self->pickler); - PyObject_GC_Del((PyObject *)self); + Py_CLEAR(self->pickler); + tp->tp_free((PyObject *)self); + Py_DECREF(tp); } static int PicklerMemoProxy_traverse(PicklerMemoProxyObject *self, visitproc visit, void *arg) { + Py_VISIT(Py_TYPE(self)); Py_VISIT(self->pickler); return 0; } @@ -4917,47 +4948,32 @@ PicklerMemoProxy_clear(PicklerMemoProxyObject *self) return 0; } -static PyTypeObject PicklerMemoProxyType = { - PyVarObject_HEAD_INIT(NULL, 0) - "_pickle.PicklerMemoProxy", /*tp_name*/ - sizeof(PicklerMemoProxyObject), /*tp_basicsize*/ - 0, - (destructor)PicklerMemoProxy_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - PyObject_HashNotImplemented, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - PyObject_GenericSetAttr, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, - 0, /* tp_doc */ - (traverseproc)PicklerMemoProxy_traverse, /* tp_traverse */ - (inquiry)PicklerMemoProxy_clear, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - picklerproxy_methods, /* tp_methods */ +static PyType_Slot memoproxy_slots[] = { + {Py_tp_dealloc, PicklerMemoProxy_dealloc}, + {Py_tp_traverse, PicklerMemoProxy_traverse}, + {Py_tp_clear, PicklerMemoProxy_clear}, + {Py_tp_methods, picklerproxy_methods}, + {Py_tp_hash, PyObject_HashNotImplemented}, + {0, NULL}, +}; + +static PyType_Spec memoproxy_spec = { + .name = "_pickle.PicklerMemoProxy", + .basicsize = sizeof(PicklerMemoProxyObject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = memoproxy_slots, }; static PyObject * PicklerMemoProxy_New(PicklerObject *pickler) { PicklerMemoProxyObject *self; - - self = PyObject_GC_New(PicklerMemoProxyObject, &PicklerMemoProxyType); + PickleState *st = _Pickle_FindStateByType(Py_TYPE(pickler)); + self = PyObject_GC_New(PicklerMemoProxyObject, st->PicklerMemoProxyType); if (self == NULL) return NULL; - Py_INCREF(pickler); - self->pickler = pickler; + self->pickler = (PicklerObject*)Py_NewRef(pickler); PyObject_GC_Track(self); return (PyObject *)self; } @@ -4981,7 +4997,8 @@ Pickler_set_memo(PicklerObject *self, PyObject *obj, void *Py_UNUSED(ignored)) return -1; } - if (Py_IS_TYPE(obj, &PicklerMemoProxyType)) { + PickleState *st = _Pickle_FindStateByType(Py_TYPE(self)); + if (Py_IS_TYPE(obj, st->PicklerMemoProxyType)) { PicklerObject *pickler = ((PicklerMemoProxyObject *)obj)->pickler; @@ -5057,8 +5074,7 @@ Pickler_set_persid(PicklerObject *self, PyObject *value, void *Py_UNUSED(ignored } self->pers_func_self = NULL; - Py_INCREF(value); - Py_XSETREF(self->pers_func, value); + Py_XSETREF(self->pers_func, Py_NewRef(value)); return 0; } @@ -5078,47 +5094,27 @@ static PyGetSetDef Pickler_getsets[] = { {NULL} }; -static PyTypeObject Pickler_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_pickle.Pickler" , /*tp_name*/ - sizeof(PicklerObject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - (destructor)Pickler_dealloc, /*tp_dealloc*/ - 0, /*tp_vectorcall_offset*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_as_async*/ - 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 | Py_TPFLAGS_HAVE_GC, - _pickle_Pickler___init____doc__, /*tp_doc*/ - (traverseproc)Pickler_traverse, /*tp_traverse*/ - (inquiry)Pickler_clear, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - Pickler_methods, /*tp_methods*/ - Pickler_members, /*tp_members*/ - Pickler_getsets, /*tp_getset*/ - 0, /*tp_base*/ - 0, /*tp_dict*/ - 0, /*tp_descr_get*/ - 0, /*tp_descr_set*/ - 0, /*tp_dictoffset*/ - _pickle_Pickler___init__, /*tp_init*/ - PyType_GenericAlloc, /*tp_alloc*/ - PyType_GenericNew, /*tp_new*/ - PyObject_GC_Del, /*tp_free*/ - 0, /*tp_is_gc*/ +static PyType_Slot pickler_type_slots[] = { + {Py_tp_dealloc, Pickler_dealloc}, + {Py_tp_methods, Pickler_methods}, + {Py_tp_members, Pickler_members}, + {Py_tp_getset, Pickler_getsets}, + {Py_tp_clear, Pickler_clear}, + {Py_tp_doc, (char*)_pickle_Pickler___init____doc__}, + {Py_tp_traverse, Pickler_traverse}, + {Py_tp_init, _pickle_Pickler___init__}, + {Py_tp_new, PyType_GenericNew}, + {Py_tp_alloc, PyType_GenericAlloc}, + {Py_tp_free, PyObject_GC_Del}, + {0, NULL}, +}; + +static PyType_Spec pickler_type_spec = { + .name = "_pickle.Pickler", + .basicsize = sizeof(PicklerObject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = pickler_type_slots, }; /* Temporary helper for calling self.find_class(). @@ -5136,17 +5132,14 @@ find_class(UnpicklerObject *self, PyObject *module_name, PyObject *global_name) } static Py_ssize_t -marker(UnpicklerObject *self) +marker(PickleState *st, UnpicklerObject *self) { - Py_ssize_t mark; - if (self->num_marks < 1) { - PickleState *st = _Pickle_GetGlobalState(); PyErr_SetString(st->UnpicklingError, "could not find MARK"); return -1; } - mark = self->marks[--self->num_marks]; + Py_ssize_t mark = self->marks[--self->num_marks]; self->stack->mark_set = self->num_marks != 0; self->stack->fence = self->num_marks ? self->marks[self->num_marks - 1] : 0; @@ -5154,24 +5147,24 @@ marker(UnpicklerObject *self) } static int -load_none(UnpicklerObject *self) +load_none(PickleState *state, UnpicklerObject *self) { PDATA_APPEND(self->stack, Py_None, -1); return 0; } static int -load_int(UnpicklerObject *self) +load_int(PickleState *state, UnpicklerObject *self) { PyObject *value; char *endptr, *s; Py_ssize_t len; long x; - if ((len = _Unpickler_Readline(self, &s)) < 0) + if ((len = _Unpickler_Readline(state, self, &s)) < 0) return -1; if (len < 2) - return bad_readline(); + return bad_readline(state); errno = 0; /* XXX: Should the base argument of strtol() be explicitly set to 10? @@ -5206,7 +5199,7 @@ load_int(UnpicklerObject *self) } static int -load_bool(UnpicklerObject *self, PyObject *boolean) +load_bool(PickleState *state, UnpicklerObject *self, PyObject *boolean) { assert(boolean == Py_True || boolean == Py_False); PDATA_APPEND(self->stack, boolean, -1); @@ -5286,49 +5279,46 @@ load_binintx(UnpicklerObject *self, char *s, int size) } static int -load_binint(UnpicklerObject *self) +load_binint(PickleState *state, UnpicklerObject *self) { char *s; - - if (_Unpickler_Read(self, &s, 4) < 0) + if (_Unpickler_Read(self, state, &s, 4) < 0) return -1; return load_binintx(self, s, 4); } static int -load_binint1(UnpicklerObject *self) +load_binint1(PickleState *state, UnpicklerObject *self) { char *s; - - if (_Unpickler_Read(self, &s, 1) < 0) + if (_Unpickler_Read(self, state, &s, 1) < 0) return -1; return load_binintx(self, s, 1); } static int -load_binint2(UnpicklerObject *self) +load_binint2(PickleState *state, UnpicklerObject *self) { char *s; - - if (_Unpickler_Read(self, &s, 2) < 0) + if (_Unpickler_Read(self, state, &s, 2) < 0) return -1; return load_binintx(self, s, 2); } static int -load_long(UnpicklerObject *self) +load_long(PickleState *state, UnpicklerObject *self) { PyObject *value; char *s = NULL; Py_ssize_t len; - if ((len = _Unpickler_Readline(self, &s)) < 0) + if ((len = _Unpickler_Readline(state, self, &s)) < 0) return -1; if (len < 2) - return bad_readline(); + return bad_readline(state); /* s[len-2] will usually be 'L' (and s[len-1] is '\n'); we need to remove the 'L' before calling PyLong_FromString. In order to maintain @@ -5349,19 +5339,18 @@ load_long(UnpicklerObject *self) * data following. */ static int -load_counted_long(UnpicklerObject *self, int size) +load_counted_long(PickleState *st, UnpicklerObject *self, int size) { PyObject *value; char *nbytes; char *pdata; assert(size == 1 || size == 4); - if (_Unpickler_Read(self, &nbytes, size) < 0) + if (_Unpickler_Read(self, st, &nbytes, size) < 0) return -1; size = calc_binint(nbytes, size); if (size < 0) { - PickleState *st = _Pickle_GetGlobalState(); /* Corrupt or hostile pickle -- we never write one like this */ PyErr_SetString(st->UnpicklingError, "LONG pickle has negative byte count"); @@ -5372,7 +5361,7 @@ load_counted_long(UnpicklerObject *self, int size) value = PyLong_FromLong(0L); else { /* Read the raw little-endian bytes and convert. */ - if (_Unpickler_Read(self, &pdata, size) < 0) + if (_Unpickler_Read(self, st, &pdata, size) < 0) return -1; value = _PyLong_FromByteArray((unsigned char *)pdata, (size_t)size, 1 /* little endian */ , 1 /* signed */ ); @@ -5384,17 +5373,17 @@ load_counted_long(UnpicklerObject *self, int size) } static int -load_float(UnpicklerObject *self) +load_float(PickleState *state, UnpicklerObject *self) { PyObject *value; char *endptr, *s; Py_ssize_t len; double d; - if ((len = _Unpickler_Readline(self, &s)) < 0) + if ((len = _Unpickler_Readline(state, self, &s)) < 0) return -1; if (len < 2) - return bad_readline(); + return bad_readline(state); errno = 0; d = PyOS_string_to_double(s, &endptr, PyExc_OverflowError); @@ -5413,13 +5402,13 @@ load_float(UnpicklerObject *self) } static int -load_binfloat(UnpicklerObject *self) +load_binfloat(PickleState *state, UnpicklerObject *self) { PyObject *value; double x; char *s; - if (_Unpickler_Read(self, &s, 8) < 0) + if (_Unpickler_Read(self, state, &s, 8) < 0) return -1; x = PyFloat_Unpack8(s, 0); @@ -5434,14 +5423,14 @@ load_binfloat(UnpicklerObject *self) } static int -load_string(UnpicklerObject *self) +load_string(PickleState *st, UnpicklerObject *self) { PyObject *bytes; PyObject *obj; Py_ssize_t len; char *s, *p; - if ((len = _Unpickler_Readline(self, &s)) < 0) + if ((len = _Unpickler_Readline(st, self, &s)) < 0) return -1; /* Strip the newline */ len--; @@ -5451,7 +5440,6 @@ load_string(UnpicklerObject *self) len -= 2; } else { - PickleState *st = _Pickle_GetGlobalState(); PyErr_SetString(st->UnpicklingError, "the STRING opcode argument must be quoted"); return -1; @@ -5482,25 +5470,24 @@ load_string(UnpicklerObject *self) } static int -load_counted_binstring(UnpicklerObject *self, int nbytes) +load_counted_binstring(PickleState *st, UnpicklerObject *self, int nbytes) { PyObject *obj; Py_ssize_t size; char *s; - if (_Unpickler_Read(self, &s, nbytes) < 0) + if (_Unpickler_Read(self, st, &s, nbytes) < 0) return -1; size = calc_binsize(s, nbytes); if (size < 0) { - PickleState *st = _Pickle_GetGlobalState(); PyErr_Format(st->UnpicklingError, "BINSTRING exceeds system's maximum size of %zd bytes", PY_SSIZE_T_MAX); return -1; } - if (_Unpickler_Read(self, &s, size) < 0) + if (_Unpickler_Read(self, st, &s, size) < 0) return -1; /* Convert Python 2.x strings to bytes if the *encoding* given to the @@ -5520,13 +5507,13 @@ load_counted_binstring(UnpicklerObject *self, int nbytes) } static int -load_counted_binbytes(UnpicklerObject *self, int nbytes) +load_counted_binbytes(PickleState *state, UnpicklerObject *self, int nbytes) { PyObject *bytes; Py_ssize_t size; char *s; - if (_Unpickler_Read(self, &s, nbytes) < 0) + if (_Unpickler_Read(self, state, &s, nbytes) < 0) return -1; size = calc_binsize(s, nbytes); @@ -5540,7 +5527,7 @@ load_counted_binbytes(UnpicklerObject *self, int nbytes) bytes = PyBytes_FromStringAndSize(NULL, size); if (bytes == NULL) return -1; - if (_Unpickler_ReadInto(self, PyBytes_AS_STRING(bytes), size) < 0) { + if (_Unpickler_ReadInto(state, self, PyBytes_AS_STRING(bytes), size) < 0) { Py_DECREF(bytes); return -1; } @@ -5550,13 +5537,13 @@ load_counted_binbytes(UnpicklerObject *self, int nbytes) } static int -load_counted_bytearray(UnpicklerObject *self) +load_counted_bytearray(PickleState *state, UnpicklerObject *self) { PyObject *bytearray; Py_ssize_t size; char *s; - if (_Unpickler_Read(self, &s, 8) < 0) { + if (_Unpickler_Read(self, state, &s, 8) < 0) { return -1; } @@ -5572,7 +5559,8 @@ load_counted_bytearray(UnpicklerObject *self) if (bytearray == NULL) { return -1; } - if (_Unpickler_ReadInto(self, PyByteArray_AS_STRING(bytearray), size) < 0) { + char *str = PyByteArray_AS_STRING(bytearray); + if (_Unpickler_ReadInto(state, self, str, size) < 0) { Py_DECREF(bytearray); return -1; } @@ -5582,10 +5570,9 @@ load_counted_bytearray(UnpicklerObject *self) } static int -load_next_buffer(UnpicklerObject *self) +load_next_buffer(PickleState *st, UnpicklerObject *self) { if (self->buffers == NULL) { - PickleState *st = _Pickle_GetGlobalState(); PyErr_SetString(st->UnpicklingError, "pickle stream refers to out-of-band data " "but no *buffers* argument was given"); @@ -5594,7 +5581,6 @@ load_next_buffer(UnpicklerObject *self) PyObject *buf = PyIter_Next(self->buffers); if (buf == NULL) { if (!PyErr_Occurred()) { - PickleState *st = _Pickle_GetGlobalState(); PyErr_SetString(st->UnpicklingError, "not enough out-of-band buffers"); } @@ -5606,11 +5592,11 @@ load_next_buffer(UnpicklerObject *self) } static int -load_readonly_buffer(UnpicklerObject *self) +load_readonly_buffer(PickleState *state, UnpicklerObject *self) { Py_ssize_t len = Py_SIZE(self->stack); if (len <= self->stack->fence) { - return Pdata_stack_underflow(self->stack); + return Pdata_stack_underflow(state, self->stack); } PyObject *obj = self->stack->data[len - 1]; @@ -5632,16 +5618,16 @@ load_readonly_buffer(UnpicklerObject *self) } static int -load_unicode(UnpicklerObject *self) +load_unicode(PickleState *state, UnpicklerObject *self) { PyObject *str; Py_ssize_t len; char *s = NULL; - if ((len = _Unpickler_Readline(self, &s)) < 0) + if ((len = _Unpickler_Readline(state, self, &s)) < 0) return -1; if (len < 1) - return bad_readline(); + return bad_readline(state); str = PyUnicode_DecodeRawUnicodeEscape(s, len - 1, NULL); if (str == NULL) @@ -5652,13 +5638,13 @@ load_unicode(UnpicklerObject *self) } static int -load_counted_binunicode(UnpicklerObject *self, int nbytes) +load_counted_binunicode(PickleState *state, UnpicklerObject *self, int nbytes) { PyObject *str; Py_ssize_t size; char *s; - if (_Unpickler_Read(self, &s, nbytes) < 0) + if (_Unpickler_Read(self, state, &s, nbytes) < 0) return -1; size = calc_binsize(s, nbytes); @@ -5669,7 +5655,7 @@ load_counted_binunicode(UnpicklerObject *self, int nbytes) return -1; } - if (_Unpickler_Read(self, &s, size) < 0) + if (_Unpickler_Read(self, state, &s, size) < 0) return -1; str = PyUnicode_DecodeUTF8(s, size, "surrogatepass"); @@ -5681,14 +5667,14 @@ load_counted_binunicode(UnpicklerObject *self, int nbytes) } static int -load_counted_tuple(UnpicklerObject *self, Py_ssize_t len) +load_counted_tuple(PickleState *state, UnpicklerObject *self, Py_ssize_t len) { PyObject *tuple; if (Py_SIZE(self->stack) < len) - return Pdata_stack_underflow(self->stack); + return Pdata_stack_underflow(state, self->stack); - tuple = Pdata_poptuple(self->stack, Py_SIZE(self->stack) - len); + tuple = Pdata_poptuple(state, self->stack, Py_SIZE(self->stack) - len); if (tuple == NULL) return -1; PDATA_PUSH(self->stack, tuple, -1); @@ -5696,18 +5682,18 @@ load_counted_tuple(UnpicklerObject *self, Py_ssize_t len) } static int -load_tuple(UnpicklerObject *self) +load_tuple(PickleState *state, UnpicklerObject *self) { Py_ssize_t i; - if ((i = marker(self)) < 0) + if ((i = marker(state, self)) < 0) return -1; - return load_counted_tuple(self, Py_SIZE(self->stack) - i); + return load_counted_tuple(state, self, Py_SIZE(self->stack) - i); } static int -load_empty_list(UnpicklerObject *self) +load_empty_list(PickleState *state, UnpicklerObject *self) { PyObject *list; @@ -5718,7 +5704,7 @@ load_empty_list(UnpicklerObject *self) } static int -load_empty_dict(UnpicklerObject *self) +load_empty_dict(PickleState *state, UnpicklerObject *self) { PyObject *dict; @@ -5729,7 +5715,7 @@ load_empty_dict(UnpicklerObject *self) } static int -load_empty_set(UnpicklerObject *self) +load_empty_set(PickleState *state, UnpicklerObject *self) { PyObject *set; @@ -5740,12 +5726,12 @@ load_empty_set(UnpicklerObject *self) } static int -load_list(UnpicklerObject *self) +load_list(PickleState *state, UnpicklerObject *self) { PyObject *list; Py_ssize_t i; - if ((i = marker(self)) < 0) + if ((i = marker(state, self)) < 0) return -1; list = Pdata_poplist(self->stack, i); @@ -5756,12 +5742,12 @@ load_list(UnpicklerObject *self) } static int -load_dict(UnpicklerObject *self) +load_dict(PickleState *st, UnpicklerObject *self) { PyObject *dict, *key, *value; Py_ssize_t i, j, k; - if ((i = marker(self)) < 0) + if ((i = marker(st, self)) < 0) return -1; j = Py_SIZE(self->stack); @@ -5769,7 +5755,6 @@ load_dict(UnpicklerObject *self) return -1; if ((j - i) % 2 != 0) { - PickleState *st = _Pickle_GetGlobalState(); PyErr_SetString(st->UnpicklingError, "odd number of items for DICT"); Py_DECREF(dict); return -1; @@ -5789,16 +5774,16 @@ load_dict(UnpicklerObject *self) } static int -load_frozenset(UnpicklerObject *self) +load_frozenset(PickleState *state, UnpicklerObject *self) { PyObject *items; PyObject *frozenset; Py_ssize_t i; - if ((i = marker(self)) < 0) + if ((i = marker(state, self)) < 0) return -1; - items = Pdata_poptuple(self->stack, i); + items = Pdata_poptuple(state, self->stack, i); if (items == NULL) return -1; @@ -5832,22 +5817,22 @@ instantiate(PyObject *cls, PyObject *args) } static int -load_obj(UnpicklerObject *self) +load_obj(PickleState *state, UnpicklerObject *self) { PyObject *cls, *args, *obj = NULL; Py_ssize_t i; - if ((i = marker(self)) < 0) + if ((i = marker(state, self)) < 0) return -1; if (Py_SIZE(self->stack) - i < 1) - return Pdata_stack_underflow(self->stack); + return Pdata_stack_underflow(state, self->stack); - args = Pdata_poptuple(self->stack, i + 1); + args = Pdata_poptuple(state, self->stack, i + 1); if (args == NULL) return -1; - PDATA_POP(self->stack, cls); + PDATA_POP(state, self->stack, cls); if (cls) { obj = instantiate(cls, args); Py_DECREF(cls); @@ -5861,7 +5846,7 @@ load_obj(UnpicklerObject *self) } static int -load_inst(UnpicklerObject *self) +load_inst(PickleState *state, UnpicklerObject *self) { PyObject *cls = NULL; PyObject *args = NULL; @@ -5872,12 +5857,12 @@ load_inst(UnpicklerObject *self) Py_ssize_t i; char *s; - if ((i = marker(self)) < 0) + if ((i = marker(state, self)) < 0) return -1; - if ((len = _Unpickler_Readline(self, &s)) < 0) + if ((len = _Unpickler_Readline(state, self, &s)) < 0) return -1; if (len < 2) - return bad_readline(); + return bad_readline(state); /* Here it is safe to use PyUnicode_DecodeASCII(), even though non-ASCII identifiers are permitted in Python 3.0, since the INST opcode is only @@ -5886,10 +5871,10 @@ load_inst(UnpicklerObject *self) if (module_name == NULL) return -1; - if ((len = _Unpickler_Readline(self, &s)) >= 0) { + if ((len = _Unpickler_Readline(state, self, &s)) >= 0) { if (len < 2) { Py_DECREF(module_name); - return bad_readline(); + return bad_readline(state); } class_name = PyUnicode_DecodeASCII(s, len - 1, "strict"); if (class_name != NULL) { @@ -5902,7 +5887,7 @@ load_inst(UnpicklerObject *self) if (cls == NULL) return -1; - if ((args = Pdata_poptuple(self->stack, i)) != NULL) { + if ((args = Pdata_poptuple(state, self->stack, i)) != NULL) { obj = instantiate(cls, args); Py_DECREF(args); } @@ -5916,16 +5901,16 @@ load_inst(UnpicklerObject *self) } static void -newobj_unpickling_error(const char * msg, int use_kwargs, PyObject *arg) +newobj_unpickling_error(PickleState *st, const char *msg, int use_kwargs, + PyObject *arg) { - PickleState *st = _Pickle_GetGlobalState(); PyErr_Format(st->UnpicklingError, msg, use_kwargs ? "NEWOBJ_EX" : "NEWOBJ", Py_TYPE(arg)->tp_name); } static int -load_newobj(UnpicklerObject *self, int use_kwargs) +load_newobj(PickleState *state, UnpicklerObject *self, int use_kwargs) { PyObject *cls, *args, *kwargs = NULL; PyObject *obj; @@ -5934,17 +5919,17 @@ load_newobj(UnpicklerObject *self, int use_kwargs) * cls.__new__(cls, *args, **kwargs). */ if (use_kwargs) { - PDATA_POP(self->stack, kwargs); + PDATA_POP(state, self->stack, kwargs); if (kwargs == NULL) { return -1; } } - PDATA_POP(self->stack, args); + PDATA_POP(state, self->stack, args); if (args == NULL) { Py_XDECREF(kwargs); return -1; } - PDATA_POP(self->stack, cls); + PDATA_POP(state, self->stack, cls); if (cls == NULL) { Py_XDECREF(kwargs); Py_DECREF(args); @@ -5952,22 +5937,26 @@ load_newobj(UnpicklerObject *self, int use_kwargs) } if (!PyType_Check(cls)) { - newobj_unpickling_error("%s class argument must be a type, not %.200s", + newobj_unpickling_error(state, + "%s class argument must be a type, not %.200s", use_kwargs, cls); goto error; } if (((PyTypeObject *)cls)->tp_new == NULL) { - newobj_unpickling_error("%s class argument '%.200s' doesn't have __new__", + newobj_unpickling_error(state, + "%s class argument '%.200s' doesn't have __new__", use_kwargs, cls); goto error; } if (!PyTuple_Check(args)) { - newobj_unpickling_error("%s args argument must be a tuple, not %.200s", + newobj_unpickling_error(state, + "%s args argument must be a tuple, not %.200s", use_kwargs, args); goto error; } if (use_kwargs && !PyDict_Check(kwargs)) { - newobj_unpickling_error("%s kwargs argument must be a dict, not %.200s", + newobj_unpickling_error(state, + "%s kwargs argument must be a dict, not %.200s", use_kwargs, kwargs); goto error; } @@ -5990,7 +5979,7 @@ error: } static int -load_global(UnpicklerObject *self) +load_global(PickleState *state, UnpicklerObject *self) { PyObject *global = NULL; PyObject *module_name; @@ -5998,18 +5987,18 @@ load_global(UnpicklerObject *self) Py_ssize_t len; char *s; - if ((len = _Unpickler_Readline(self, &s)) < 0) + if ((len = _Unpickler_Readline(state, self, &s)) < 0) return -1; if (len < 2) - return bad_readline(); + return bad_readline(state); module_name = PyUnicode_DecodeUTF8(s, len - 1, "strict"); if (!module_name) return -1; - if ((len = _Unpickler_Readline(self, &s)) >= 0) { + if ((len = _Unpickler_Readline(state, self, &s)) >= 0) { if (len < 2) { Py_DECREF(module_name); - return bad_readline(); + return bad_readline(state); } global_name = PyUnicode_DecodeUTF8(s, len - 1, "strict"); if (global_name) { @@ -6026,20 +6015,27 @@ load_global(UnpicklerObject *self) } static int -load_stack_global(UnpicklerObject *self) +load_stack_global(PickleState *st, UnpicklerObject *self) { PyObject *global; PyObject *module_name; PyObject *global_name; - PDATA_POP(self->stack, global_name); - PDATA_POP(self->stack, module_name); - if (module_name == NULL || !PyUnicode_CheckExact(module_name) || - global_name == NULL || !PyUnicode_CheckExact(global_name)) { - PickleState *st = _Pickle_GetGlobalState(); + PDATA_POP(st, self->stack, global_name); + if (global_name == NULL) { + return -1; + } + PDATA_POP(st, self->stack, module_name); + if (module_name == NULL) { + Py_DECREF(global_name); + return -1; + } + if (!PyUnicode_CheckExact(module_name) || + !PyUnicode_CheckExact(global_name)) + { PyErr_SetString(st->UnpicklingError, "STACK_GLOBAL requires str"); - Py_XDECREF(global_name); - Py_XDECREF(module_name); + Py_DECREF(global_name); + Py_DECREF(module_name); return -1; } global = find_class(self, module_name, global_name); @@ -6052,22 +6048,22 @@ load_stack_global(UnpicklerObject *self) } static int -load_persid(UnpicklerObject *self) +load_persid(PickleState *st, UnpicklerObject *self) { PyObject *pid, *obj; Py_ssize_t len; char *s; if (self->pers_func) { - if ((len = _Unpickler_Readline(self, &s)) < 0) + if ((len = _Unpickler_Readline(st, self, &s)) < 0) return -1; if (len < 1) - return bad_readline(); + return bad_readline(st); pid = PyUnicode_DecodeASCII(s, len - 1, "strict"); if (pid == NULL) { if (PyErr_ExceptionMatches(PyExc_UnicodeDecodeError)) { - PyErr_SetString(_Pickle_GetGlobalState()->UnpicklingError, + PyErr_SetString(st->UnpicklingError, "persistent IDs in protocol 0 must be " "ASCII strings"); } @@ -6083,21 +6079,20 @@ load_persid(UnpicklerObject *self) return 0; } else { - PickleState *st = _Pickle_GetGlobalState(); PyErr_SetString(st->UnpicklingError, - "A load persistent id instruction was encountered,\n" + "A load persistent id instruction was encountered, " "but no persistent_load function was specified."); return -1; } } static int -load_binpersid(UnpicklerObject *self) +load_binpersid(PickleState *st, UnpicklerObject *self) { PyObject *pid, *obj; if (self->pers_func) { - PDATA_POP(self->stack, pid); + PDATA_POP(st, self->stack, pid); if (pid == NULL) return -1; @@ -6110,16 +6105,15 @@ load_binpersid(UnpicklerObject *self) return 0; } else { - PickleState *st = _Pickle_GetGlobalState(); PyErr_SetString(st->UnpicklingError, - "A load persistent id instruction was encountered,\n" + "A load persistent id instruction was encountered, " "but no persistent_load function was specified."); return -1; } } static int -load_pop(UnpicklerObject *self) +load_pop(PickleState *state, UnpicklerObject *self) { Py_ssize_t len = Py_SIZE(self->stack); @@ -6136,7 +6130,7 @@ load_pop(UnpicklerObject *self) self->stack->fence = self->num_marks ? self->marks[self->num_marks - 1] : 0; } else if (len <= self->stack->fence) - return Pdata_stack_underflow(self->stack); + return Pdata_stack_underflow(state, self->stack); else { len--; Py_DECREF(self->stack->data[len]); @@ -6146,11 +6140,10 @@ load_pop(UnpicklerObject *self) } static int -load_pop_mark(UnpicklerObject *self) +load_pop_mark(PickleState *state, UnpicklerObject *self) { Py_ssize_t i; - - if ((i = marker(self)) < 0) + if ((i = marker(state, self)) < 0) return -1; Pdata_clear(self->stack, i); @@ -6159,30 +6152,30 @@ load_pop_mark(UnpicklerObject *self) } static int -load_dup(UnpicklerObject *self) +load_dup(PickleState *state, UnpicklerObject *self) { PyObject *last; Py_ssize_t len = Py_SIZE(self->stack); if (len <= self->stack->fence) - return Pdata_stack_underflow(self->stack); + return Pdata_stack_underflow(state, self->stack); last = self->stack->data[len - 1]; PDATA_APPEND(self->stack, last, -1); return 0; } static int -load_get(UnpicklerObject *self) +load_get(PickleState *st, UnpicklerObject *self) { PyObject *key, *value; Py_ssize_t idx; Py_ssize_t len; char *s; - if ((len = _Unpickler_Readline(self, &s)) < 0) + if ((len = _Unpickler_Readline(st, self, &s)) < 0) return -1; if (len < 2) - return bad_readline(); + return bad_readline(st); key = PyLong_FromString(s, NULL, 10); if (key == NULL) @@ -6196,7 +6189,6 @@ load_get(UnpicklerObject *self) value = _Unpickler_MemoGet(self, idx); if (value == NULL) { if (!PyErr_Occurred()) { - PickleState *st = _Pickle_GetGlobalState(); PyErr_Format(st->UnpicklingError, "Memo value not found at index %ld", idx); } Py_DECREF(key); @@ -6209,13 +6201,13 @@ load_get(UnpicklerObject *self) } static int -load_binget(UnpicklerObject *self) +load_binget(PickleState *st, UnpicklerObject *self) { PyObject *value; Py_ssize_t idx; char *s; - if (_Unpickler_Read(self, &s, 1) < 0) + if (_Unpickler_Read(self, st, &s, 1) < 0) return -1; idx = Py_CHARMASK(s[0]); @@ -6224,7 +6216,6 @@ load_binget(UnpicklerObject *self) if (value == NULL) { PyObject *key = PyLong_FromSsize_t(idx); if (key != NULL) { - PickleState *st = _Pickle_GetGlobalState(); PyErr_Format(st->UnpicklingError, "Memo value not found at index %ld", idx); Py_DECREF(key); } @@ -6236,13 +6227,13 @@ load_binget(UnpicklerObject *self) } static int -load_long_binget(UnpicklerObject *self) +load_long_binget(PickleState *st, UnpicklerObject *self) { PyObject *value; Py_ssize_t idx; char *s; - if (_Unpickler_Read(self, &s, 4) < 0) + if (_Unpickler_Read(self, st, &s, 4) < 0) return -1; idx = calc_binsize(s, 4); @@ -6251,7 +6242,6 @@ load_long_binget(UnpicklerObject *self) if (value == NULL) { PyObject *key = PyLong_FromSsize_t(idx); if (key != NULL) { - PickleState *st = _Pickle_GetGlobalState(); PyErr_Format(st->UnpicklingError, "Memo value not found at index %ld", idx); Py_DECREF(key); } @@ -6266,7 +6256,7 @@ load_long_binget(UnpicklerObject *self) * the number of bytes following the opcode, holding the index (code) value. */ static int -load_extension(UnpicklerObject *self, int nbytes) +load_extension(PickleState *st, UnpicklerObject *self, int nbytes) { char *codebytes; /* the nbytes bytes after the opcode */ long code; /* calc_binint returns long */ @@ -6274,10 +6264,9 @@ load_extension(UnpicklerObject *self, int nbytes) PyObject *obj; /* the object to push */ PyObject *pair; /* (module_name, class_name) */ PyObject *module_name, *class_name; - PickleState *st = _Pickle_GetGlobalState(); assert(nbytes == 1 || nbytes == 2 || nbytes == 4); - if (_Unpickler_Read(self, &codebytes, nbytes) < 0) + if (_Unpickler_Read(self, st, &codebytes, nbytes) < 0) return -1; code = calc_binint(codebytes, nbytes); if (code <= 0) { /* note that 0 is forbidden */ @@ -6353,19 +6342,19 @@ error: } static int -load_put(UnpicklerObject *self) +load_put(PickleState *state, UnpicklerObject *self) { PyObject *key, *value; Py_ssize_t idx; Py_ssize_t len; char *s = NULL; - if ((len = _Unpickler_Readline(self, &s)) < 0) + if ((len = _Unpickler_Readline(state, self, &s)) < 0) return -1; if (len < 2) - return bad_readline(); + return bad_readline(state); if (Py_SIZE(self->stack) <= self->stack->fence) - return Pdata_stack_underflow(self->stack); + return Pdata_stack_underflow(state, self->stack); value = self->stack->data[Py_SIZE(self->stack) - 1]; key = PyLong_FromString(s, NULL, 10); @@ -6384,17 +6373,17 @@ load_put(UnpicklerObject *self) } static int -load_binput(UnpicklerObject *self) +load_binput(PickleState *state, UnpicklerObject *self) { PyObject *value; Py_ssize_t idx; char *s; - if (_Unpickler_Read(self, &s, 1) < 0) + if (_Unpickler_Read(self, state, &s, 1) < 0) return -1; if (Py_SIZE(self->stack) <= self->stack->fence) - return Pdata_stack_underflow(self->stack); + return Pdata_stack_underflow(state, self->stack); value = self->stack->data[Py_SIZE(self->stack) - 1]; idx = Py_CHARMASK(s[0]); @@ -6403,17 +6392,17 @@ load_binput(UnpicklerObject *self) } static int -load_long_binput(UnpicklerObject *self) +load_long_binput(PickleState *state, UnpicklerObject *self) { PyObject *value; Py_ssize_t idx; char *s; - if (_Unpickler_Read(self, &s, 4) < 0) + if (_Unpickler_Read(self, state, &s, 4) < 0) return -1; if (Py_SIZE(self->stack) <= self->stack->fence) - return Pdata_stack_underflow(self->stack); + return Pdata_stack_underflow(state, self->stack); value = self->stack->data[Py_SIZE(self->stack) - 1]; idx = calc_binsize(s, 4); @@ -6427,19 +6416,19 @@ load_long_binput(UnpicklerObject *self) } static int -load_memoize(UnpicklerObject *self) +load_memoize(PickleState *state, UnpicklerObject *self) { PyObject *value; if (Py_SIZE(self->stack) <= self->stack->fence) - return Pdata_stack_underflow(self->stack); + return Pdata_stack_underflow(state, self->stack); value = self->stack->data[Py_SIZE(self->stack) - 1]; return _Unpickler_MemoPut(self, self->memo_len, value); } static int -do_append(UnpicklerObject *self, Py_ssize_t x) +do_append(PickleState *state, UnpicklerObject *self, Py_ssize_t x) { PyObject *value; PyObject *slice; @@ -6449,7 +6438,7 @@ do_append(UnpicklerObject *self, Py_ssize_t x) len = Py_SIZE(self->stack); if (x > len || x <= self->stack->fence) - return Pdata_stack_underflow(self->stack); + return Pdata_stack_underflow(state, self->stack); if (len == x) /* nothing to do */ return 0; @@ -6514,24 +6503,24 @@ do_append(UnpicklerObject *self, Py_ssize_t x) } static int -load_append(UnpicklerObject *self) +load_append(PickleState *state, UnpicklerObject *self) { if (Py_SIZE(self->stack) - 1 <= self->stack->fence) - return Pdata_stack_underflow(self->stack); - return do_append(self, Py_SIZE(self->stack) - 1); + return Pdata_stack_underflow(state, self->stack); + return do_append(state, self, Py_SIZE(self->stack) - 1); } static int -load_appends(UnpicklerObject *self) +load_appends(PickleState *state, UnpicklerObject *self) { - Py_ssize_t i = marker(self); + Py_ssize_t i = marker(state, self); if (i < 0) return -1; - return do_append(self, i); + return do_append(state, self, i); } static int -do_setitems(UnpicklerObject *self, Py_ssize_t x) +do_setitems(PickleState *st, UnpicklerObject *self, Py_ssize_t x) { PyObject *value, *key; PyObject *dict; @@ -6540,11 +6529,10 @@ do_setitems(UnpicklerObject *self, Py_ssize_t x) len = Py_SIZE(self->stack); if (x > len || x <= self->stack->fence) - return Pdata_stack_underflow(self->stack); + return Pdata_stack_underflow(st, self->stack); if (len == x) /* nothing to do */ return 0; if ((len - x) % 2 != 0) { - PickleState *st = _Pickle_GetGlobalState(); /* Corrupt or hostile pickle -- we never write one like this. */ PyErr_SetString(st->UnpicklingError, "odd number of items for SETITEMS"); @@ -6569,32 +6557,32 @@ do_setitems(UnpicklerObject *self, Py_ssize_t x) } static int -load_setitem(UnpicklerObject *self) +load_setitem(PickleState *state, UnpicklerObject *self) { - return do_setitems(self, Py_SIZE(self->stack) - 2); + return do_setitems(state, self, Py_SIZE(self->stack) - 2); } static int -load_setitems(UnpicklerObject *self) +load_setitems(PickleState *state, UnpicklerObject *self) { - Py_ssize_t i = marker(self); + Py_ssize_t i = marker(state, self); if (i < 0) return -1; - return do_setitems(self, i); + return do_setitems(state, self, i); } static int -load_additems(UnpicklerObject *self) +load_additems(PickleState *state, UnpicklerObject *self) { PyObject *set; Py_ssize_t mark, len, i; - mark = marker(self); + mark = marker(state, self); if (mark < 0) return -1; len = Py_SIZE(self->stack); if (mark > len || mark <= self->stack->fence) - return Pdata_stack_underflow(self->stack); + return Pdata_stack_underflow(state, self->stack); if (len == mark) /* nothing to do */ return 0; @@ -6604,7 +6592,7 @@ load_additems(UnpicklerObject *self) PyObject *items; int status; - items = Pdata_poptuple(self->stack, mark); + items = Pdata_poptuple(state, self->stack, mark); if (items == NULL) return -1; @@ -6638,9 +6626,9 @@ load_additems(UnpicklerObject *self) } static int -load_build(UnpicklerObject *self) +load_build(PickleState *st, UnpicklerObject *self) { - PyObject *state, *inst, *slotstate; + PyObject *inst, *slotstate; PyObject *setstate; int status = 0; @@ -6648,9 +6636,10 @@ load_build(UnpicklerObject *self) * the stack top, possibly mutated via instance.__setstate__(state). */ if (Py_SIZE(self->stack) - 2 < self->stack->fence) - return Pdata_stack_underflow(self->stack); + return Pdata_stack_underflow(st, self->stack); - PDATA_POP(self->stack, state); + PyObject *state; + PDATA_POP(st, self->stack, state); if (state == NULL) return -1; @@ -6694,7 +6683,6 @@ load_build(UnpicklerObject *self) Py_ssize_t i; if (!PyDict_Check(state)) { - PickleState *st = _Pickle_GetGlobalState(); PyErr_SetString(st->UnpicklingError, "state is not a dictionary"); goto error; } @@ -6724,7 +6712,6 @@ load_build(UnpicklerObject *self) Py_ssize_t i; if (!PyDict_Check(slotstate)) { - PickleState *st = _Pickle_GetGlobalState(); PyErr_SetString(st->UnpicklingError, "slot state is not a dictionary"); goto error; @@ -6747,7 +6734,7 @@ load_build(UnpicklerObject *self) } static int -load_mark(UnpicklerObject *self) +load_mark(PickleState *state, UnpicklerObject *self) { /* Note that we split the (pickle.py) stack into two stacks, an @@ -6774,16 +6761,16 @@ load_mark(UnpicklerObject *self) } static int -load_reduce(UnpicklerObject *self) +load_reduce(PickleState *state, UnpicklerObject *self) { PyObject *callable = NULL; PyObject *argtup = NULL; PyObject *obj = NULL; - PDATA_POP(self->stack, argtup); + PDATA_POP(state, self->stack, argtup); if (argtup == NULL) return -1; - PDATA_POP(self->stack, callable); + PDATA_POP(state, self->stack, callable); if (callable) { obj = PyObject_CallObject(callable, argtup); Py_DECREF(callable); @@ -6801,12 +6788,12 @@ load_reduce(UnpicklerObject *self) * is the first opcode for protocols >= 2. */ static int -load_proto(UnpicklerObject *self) +load_proto(PickleState *state, UnpicklerObject *self) { char *s; int i; - if (_Unpickler_Read(self, &s, 1) < 0) + if (_Unpickler_Read(self, state, &s, 1) < 0) return -1; i = (unsigned char)s[0]; @@ -6820,12 +6807,12 @@ load_proto(UnpicklerObject *self) } static int -load_frame(UnpicklerObject *self) +load_frame(PickleState *state, UnpicklerObject *self) { char *s; Py_ssize_t frame_len; - if (_Unpickler_Read(self, &s, 8) < 0) + if (_Unpickler_Read(self, state, &s, 8) < 0) return -1; frame_len = calc_binsize(s, 8); @@ -6836,7 +6823,7 @@ load_frame(UnpicklerObject *self) return -1; } - if (_Unpickler_Read(self, &s, frame_len) < 0) + if (_Unpickler_Read(self, state, &s, frame_len) < 0) return -1; /* Rewind to start of frame */ @@ -6845,7 +6832,7 @@ load_frame(UnpicklerObject *self) } static PyObject * -load(UnpicklerObject *self) +load(PickleState *st, UnpicklerObject *self) { PyObject *value = NULL; char *s = NULL; @@ -6859,14 +6846,13 @@ load(UnpicklerObject *self) /* Convenient macros for the dispatch while-switch loop just below. */ #define OP(opcode, load_func) \ - case opcode: if (load_func(self) < 0) break; continue; + case opcode: if (load_func(st, self) < 0) break; continue; #define OP_ARG(opcode, load_func, arg) \ - case opcode: if (load_func(self, (arg)) < 0) break; continue; + case opcode: if (load_func(st, self, (arg)) < 0) break; continue; while (1) { - if (_Unpickler_Read(self, &s, 1) < 0) { - PickleState *st = _Pickle_GetGlobalState(); + if (_Unpickler_Read(self, st, &s, 1) < 0) { if (PyErr_ExceptionMatches(st->UnpicklingError)) { PyErr_Format(PyExc_EOFError, "Ran out of input"); } @@ -6947,7 +6933,6 @@ load(UnpicklerObject *self) default: { - PickleState *st = _Pickle_GetGlobalState(); unsigned char c = (unsigned char) *s; if (0x20 <= c && c <= 0x7e && c != '\'' && c != '\\') { PyErr_Format(st->UnpicklingError, @@ -6971,7 +6956,7 @@ load(UnpicklerObject *self) if (_Unpickler_SkipConsumed(self) < 0) return NULL; - PDATA_POP(self->stack, value); + PDATA_POP(st, self->stack, value); return value; } @@ -6979,6 +6964,8 @@ load(UnpicklerObject *self) _pickle.Unpickler.load + cls: defining_class + Load a pickle. Read a pickled object representation from the open file object given @@ -6987,24 +6974,25 @@ specified therein. [clinic start generated code]*/ static PyObject * -_pickle_Unpickler_load_impl(UnpicklerObject *self) -/*[clinic end generated code: output=fdcc488aad675b14 input=acbb91a42fa9b7b9]*/ +_pickle_Unpickler_load_impl(UnpicklerObject *self, PyTypeObject *cls) +/*[clinic end generated code: output=cc88168f608e3007 input=f5d2f87e61d5f07f]*/ { UnpicklerObject *unpickler = (UnpicklerObject*)self; + PickleState *st = _Pickle_GetStateByClass(cls); + /* Check whether the Unpickler was initialized correctly. This prevents segfaulting if a subclass overridden __init__ with a function that does not call Unpickler.__init__(). Here, we simply ensure that self->read is not NULL. */ if (unpickler->read == NULL) { - PickleState *st = _Pickle_GetGlobalState(); PyErr_Format(st->UnpicklingError, "Unpickler.__init__() was not called by %s.__init__()", Py_TYPE(unpickler)->tp_name); return NULL; } - return load(unpickler); + return load(st, unpickler); } /* The name of find_class() is misleading. In newer pickle protocols, this @@ -7015,6 +7003,7 @@ _pickle_Unpickler_load_impl(UnpicklerObject *self) _pickle.Unpickler.find_class + cls: defining_class module_name: object global_name: object / @@ -7030,10 +7019,10 @@ needed. Both arguments passed are str objects. [clinic start generated code]*/ static PyObject * -_pickle_Unpickler_find_class_impl(UnpicklerObject *self, +_pickle_Unpickler_find_class_impl(UnpicklerObject *self, PyTypeObject *cls, PyObject *module_name, PyObject *global_name) -/*[clinic end generated code: output=becc08d7f9ed41e3 input=e2e6a865de093ef4]*/ +/*[clinic end generated code: output=99577948abb0be81 input=9577745719219fc7]*/ { PyObject *global; PyObject *module; @@ -7049,7 +7038,7 @@ _pickle_Unpickler_find_class_impl(UnpicklerObject *self, if (self->proto < 3 && self->fix_imports) { PyObject *key; PyObject *item; - PickleState *st = _Pickle_GetGlobalState(); + PickleState *st = _Pickle_GetStateByClass(cls); /* Check if the global (i.e., a function or a class) was renamed or moved to another module. */ @@ -7113,22 +7102,20 @@ _pickle_Unpickler_find_class_impl(UnpicklerObject *self, /*[clinic input] -_pickle.Unpickler.__sizeof__ -> Py_ssize_t +_pickle.Unpickler.__sizeof__ -> size_t Returns size in memory, in bytes. [clinic start generated code]*/ -static Py_ssize_t +static size_t _pickle_Unpickler___sizeof___impl(UnpicklerObject *self) -/*[clinic end generated code: output=119d9d03ad4c7651 input=13333471fdeedf5e]*/ +/*[clinic end generated code: output=4648d84c228196df input=27180b2b6b524012]*/ { - Py_ssize_t res; - - res = _PyObject_SIZE(Py_TYPE(self)); + size_t res = _PyObject_SIZE(Py_TYPE(self)); if (self->memo != NULL) res += self->memo_size * sizeof(PyObject *); if (self->marks != NULL) - res += self->marks_size * sizeof(Py_ssize_t); + res += (size_t)self->marks_size * sizeof(Py_ssize_t); if (self->input_line != NULL) res += strlen(self->input_line) + 1; if (self->encoding != NULL) @@ -7145,44 +7132,6 @@ static struct PyMethodDef Unpickler_methods[] = { {NULL, NULL} /* sentinel */ }; -static void -Unpickler_dealloc(UnpicklerObject *self) -{ - PyObject_GC_UnTrack((PyObject *)self); - Py_XDECREF(self->readline); - Py_XDECREF(self->readinto); - Py_XDECREF(self->read); - Py_XDECREF(self->peek); - Py_XDECREF(self->stack); - Py_XDECREF(self->pers_func); - Py_XDECREF(self->buffers); - if (self->buffer.buf != NULL) { - PyBuffer_Release(&self->buffer); - self->buffer.buf = NULL; - } - - _Unpickler_MemoCleanup(self); - PyMem_Free(self->marks); - PyMem_Free(self->input_line); - PyMem_Free(self->encoding); - PyMem_Free(self->errors); - - Py_TYPE(self)->tp_free((PyObject *)self); -} - -static int -Unpickler_traverse(UnpicklerObject *self, visitproc visit, void *arg) -{ - Py_VISIT(self->readline); - Py_VISIT(self->readinto); - Py_VISIT(self->read); - Py_VISIT(self->peek); - Py_VISIT(self->stack); - Py_VISIT(self->pers_func); - Py_VISIT(self->buffers); - return 0; -} - static int Unpickler_clear(UnpicklerObject *self) { @@ -7211,6 +7160,30 @@ Unpickler_clear(UnpicklerObject *self) return 0; } +static void +Unpickler_dealloc(UnpicklerObject *self) +{ + PyTypeObject *tp = Py_TYPE(self); + PyObject_GC_UnTrack((PyObject *)self); + (void)Unpickler_clear(self); + tp->tp_free((PyObject *)self); + Py_DECREF(tp); +} + +static int +Unpickler_traverse(UnpicklerObject *self, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(self)); + Py_VISIT(self->readline); + Py_VISIT(self->readinto); + Py_VISIT(self->read); + Py_VISIT(self->peek); + Py_VISIT(self->stack); + Py_VISIT(self->pers_func); + Py_VISIT(self->buffers); + return 0; +} + /*[clinic input] _pickle.Unpickler.__init__ @@ -7271,7 +7244,9 @@ _pickle_Unpickler___init___impl(UnpicklerObject *self, PyObject *file, return -1; } - self->stack = (Pdata *)Pdata_New(); + PyTypeObject *tp = Py_TYPE(self); + PickleState *state = _Pickle_FindStateByType(tp); + self->stack = (Pdata *)Pdata_New(state); if (self->stack == NULL) return -1; @@ -7382,8 +7357,7 @@ _pickle_UnpicklerMemoProxy___reduce___impl(UnpicklerMemoProxyObject *self) return NULL; } PyTuple_SET_ITEM(constructor_args, 0, contents); - Py_INCREF((PyObject *)&PyDict_Type); - PyTuple_SET_ITEM(reduce_value, 0, (PyObject *)&PyDict_Type); + PyTuple_SET_ITEM(reduce_value, 0, Py_NewRef(&PyDict_Type)); PyTuple_SET_ITEM(reduce_value, 1, constructor_args); return reduce_value; } @@ -7398,15 +7372,18 @@ static PyMethodDef unpicklerproxy_methods[] = { static void UnpicklerMemoProxy_dealloc(UnpicklerMemoProxyObject *self) { + PyTypeObject *tp = Py_TYPE(self); PyObject_GC_UnTrack(self); - Py_XDECREF(self->unpickler); - PyObject_GC_Del((PyObject *)self); + Py_CLEAR(self->unpickler); + tp->tp_free((PyObject *)self); + Py_DECREF(tp); } static int UnpicklerMemoProxy_traverse(UnpicklerMemoProxyObject *self, visitproc visit, void *arg) { + Py_VISIT(Py_TYPE(self)); Py_VISIT(self->unpickler); return 0; } @@ -7418,48 +7395,33 @@ UnpicklerMemoProxy_clear(UnpicklerMemoProxyObject *self) return 0; } -static PyTypeObject UnpicklerMemoProxyType = { - PyVarObject_HEAD_INIT(NULL, 0) - "_pickle.UnpicklerMemoProxy", /*tp_name*/ - sizeof(UnpicklerMemoProxyObject), /*tp_basicsize*/ - 0, - (destructor)UnpicklerMemoProxy_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - PyObject_HashNotImplemented, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - PyObject_GenericSetAttr, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, - 0, /* tp_doc */ - (traverseproc)UnpicklerMemoProxy_traverse, /* tp_traverse */ - (inquiry)UnpicklerMemoProxy_clear, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - unpicklerproxy_methods, /* tp_methods */ +static PyType_Slot unpickler_memoproxy_slots[] = { + {Py_tp_dealloc, UnpicklerMemoProxy_dealloc}, + {Py_tp_traverse, UnpicklerMemoProxy_traverse}, + {Py_tp_clear, UnpicklerMemoProxy_clear}, + {Py_tp_methods, unpicklerproxy_methods}, + {Py_tp_hash, PyObject_HashNotImplemented}, + {0, NULL}, +}; + +static PyType_Spec unpickler_memoproxy_spec = { + .name = "_pickle.UnpicklerMemoProxy", + .basicsize = sizeof(UnpicklerMemoProxyObject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = unpickler_memoproxy_slots, }; static PyObject * UnpicklerMemoProxy_New(UnpicklerObject *unpickler) { + PickleState *state = _Pickle_FindStateByType(Py_TYPE(unpickler)); UnpicklerMemoProxyObject *self; - self = PyObject_GC_New(UnpicklerMemoProxyObject, - &UnpicklerMemoProxyType); + state->UnpicklerMemoProxyType); if (self == NULL) return NULL; - Py_INCREF(unpickler); - self->unpickler = unpickler; + self->unpickler = (UnpicklerObject*)Py_NewRef(unpickler); PyObject_GC_Track(self); return (PyObject *)self; } @@ -7485,7 +7447,8 @@ Unpickler_set_memo(UnpicklerObject *self, PyObject *obj, void *Py_UNUSED(ignored return -1; } - if (Py_IS_TYPE(obj, &UnpicklerMemoProxyType)) { + PickleState *state = _Pickle_FindStateByType(Py_TYPE(self)); + if (Py_IS_TYPE(obj, state->UnpicklerMemoProxyType)) { UnpicklerObject *unpickler = ((UnpicklerMemoProxyObject *)obj)->unpickler; @@ -7495,8 +7458,7 @@ Unpickler_set_memo(UnpicklerObject *self, PyObject *obj, void *Py_UNUSED(ignored return -1; for (size_t i = 0; i < new_memo_size; i++) { - Py_XINCREF(unpickler->memo[i]); - new_memo[i] = unpickler->memo[i]; + new_memo[i] = Py_XNewRef(unpickler->memo[i]); } } else if (PyDict_Check(obj)) { @@ -7576,8 +7538,7 @@ Unpickler_set_persload(UnpicklerObject *self, PyObject *value, void *Py_UNUSED(i } self->pers_func_self = NULL; - Py_INCREF(value); - Py_XSETREF(self->pers_func, value); + Py_XSETREF(self->pers_func, Py_NewRef(value)); return 0; } @@ -7589,47 +7550,26 @@ static PyGetSetDef Unpickler_getsets[] = { {NULL} }; -static PyTypeObject Unpickler_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_pickle.Unpickler", /*tp_name*/ - sizeof(UnpicklerObject), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - (destructor)Unpickler_dealloc, /*tp_dealloc*/ - 0, /*tp_vectorcall_offset*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_as_async*/ - 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 | Py_TPFLAGS_HAVE_GC, - _pickle_Unpickler___init____doc__, /*tp_doc*/ - (traverseproc)Unpickler_traverse, /*tp_traverse*/ - (inquiry)Unpickler_clear, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - Unpickler_methods, /*tp_methods*/ - 0, /*tp_members*/ - Unpickler_getsets, /*tp_getset*/ - 0, /*tp_base*/ - 0, /*tp_dict*/ - 0, /*tp_descr_get*/ - 0, /*tp_descr_set*/ - 0, /*tp_dictoffset*/ - _pickle_Unpickler___init__, /*tp_init*/ - PyType_GenericAlloc, /*tp_alloc*/ - PyType_GenericNew, /*tp_new*/ - PyObject_GC_Del, /*tp_free*/ - 0, /*tp_is_gc*/ +static PyType_Slot unpickler_type_slots[] = { + {Py_tp_dealloc, Unpickler_dealloc}, + {Py_tp_doc, (char *)_pickle_Unpickler___init____doc__}, + {Py_tp_traverse, Unpickler_traverse}, + {Py_tp_clear, Unpickler_clear}, + {Py_tp_methods, Unpickler_methods}, + {Py_tp_getset, Unpickler_getsets}, + {Py_tp_init, _pickle_Unpickler___init__}, + {Py_tp_alloc, PyType_GenericAlloc}, + {Py_tp_new, PyType_GenericNew}, + {Py_tp_free, PyObject_GC_Del}, + {0, NULL}, +}; + +static PyType_Spec unpickler_type_spec = { + .name = "_pickle.Unpickler", + .basicsize = sizeof(UnpicklerObject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = unpickler_type_slots, }; /*[clinic input] @@ -7678,7 +7618,8 @@ _pickle_dump_impl(PyObject *module, PyObject *obj, PyObject *file, PyObject *buffer_callback) /*[clinic end generated code: output=706186dba996490c input=5ed6653da99cd97c]*/ { - PicklerObject *pickler = _Pickler_New(); + PickleState *state = _Pickle_GetState(module); + PicklerObject *pickler = _Pickler_New(state); if (pickler == NULL) return NULL; @@ -7692,7 +7633,7 @@ _pickle_dump_impl(PyObject *module, PyObject *obj, PyObject *file, if (_Pickler_SetBufferCallback(pickler, buffer_callback) < 0) goto error; - if (dump(pickler, obj) < 0) + if (dump(state, pickler, obj) < 0) goto error; if (_Pickler_FlushToFile(pickler) < 0) @@ -7743,7 +7684,8 @@ _pickle_dumps_impl(PyObject *module, PyObject *obj, PyObject *protocol, /*[clinic end generated code: output=fbab0093a5580fdf input=e543272436c6f987]*/ { PyObject *result; - PicklerObject *pickler = _Pickler_New(); + PickleState *state = _Pickle_GetState(module); + PicklerObject *pickler = _Pickler_New(state); if (pickler == NULL) return NULL; @@ -7754,7 +7696,7 @@ _pickle_dumps_impl(PyObject *module, PyObject *obj, PyObject *protocol, if (_Pickler_SetBufferCallback(pickler, buffer_callback) < 0) goto error; - if (dump(pickler, obj) < 0) + if (dump(state, pickler, obj) < 0) goto error; result = _Pickler_GetString(pickler); @@ -7809,7 +7751,7 @@ _pickle_load_impl(PyObject *module, PyObject *file, int fix_imports, /*[clinic end generated code: output=250452d141c23e76 input=46c7c31c92f4f371]*/ { PyObject *result; - UnpicklerObject *unpickler = _Unpickler_New(); + UnpicklerObject *unpickler = _Unpickler_New(module); if (unpickler == NULL) return NULL; @@ -7825,7 +7767,8 @@ _pickle_load_impl(PyObject *module, PyObject *file, int fix_imports, unpickler->fix_imports = fix_imports; - result = load(unpickler); + PickleState *state = _Pickle_GetState(module); + result = load(state, unpickler); Py_DECREF(unpickler); return result; @@ -7869,7 +7812,7 @@ _pickle_loads_impl(PyObject *module, PyObject *data, int fix_imports, /*[clinic end generated code: output=82ac1e6b588e6d02 input=b3615540d0535087]*/ { PyObject *result; - UnpicklerObject *unpickler = _Unpickler_New(); + UnpicklerObject *unpickler = _Unpickler_New(module); if (unpickler == NULL) return NULL; @@ -7885,7 +7828,8 @@ _pickle_loads_impl(PyObject *module, PyObject *data, int fix_imports, unpickler->fix_imports = fix_imports; - result = load(unpickler); + PickleState *state = _Pickle_GetState(module); + result = load(state, unpickler); Py_DECREF(unpickler); return result; @@ -7933,82 +7877,95 @@ pickle_traverse(PyObject *m, visitproc visit, void *arg) Py_VISIT(st->codecs_encode); Py_VISIT(st->getattr); Py_VISIT(st->partial); + Py_VISIT(st->Pickler_Type); + Py_VISIT(st->Unpickler_Type); + Py_VISIT(st->Pdata_Type); + Py_VISIT(st->PicklerMemoProxyType); + Py_VISIT(st->UnpicklerMemoProxyType); return 0; } -static struct PyModuleDef _picklemodule = { - PyModuleDef_HEAD_INIT, - "_pickle", /* m_name */ - pickle_module_doc, /* m_doc */ - sizeof(PickleState), /* m_size */ - pickle_methods, /* m_methods */ - NULL, /* m_reload */ - pickle_traverse, /* m_traverse */ - pickle_clear, /* m_clear */ - (freefunc)pickle_free /* m_free */ -}; - -PyMODINIT_FUNC -PyInit__pickle(void) +static int +_pickle_exec(PyObject *m) { - PyObject *m; - PickleState *st; + PickleState *st = _Pickle_GetState(m); - m = PyState_FindModule(&_picklemodule); - if (m) { - Py_INCREF(m); - return m; - } +#define CREATE_TYPE(mod, type, spec) \ + do { \ + type = (PyTypeObject *)PyType_FromMetaclass(NULL, mod, spec, NULL); \ + if (type == NULL) { \ + return -1; \ + } \ + } while (0) - if (PyType_Ready(&Pdata_Type) < 0) - return NULL; - if (PyType_Ready(&PicklerMemoProxyType) < 0) - return NULL; - if (PyType_Ready(&UnpicklerMemoProxyType) < 0) - return NULL; + CREATE_TYPE(m, st->Pdata_Type, &pdata_spec); + CREATE_TYPE(m, st->PicklerMemoProxyType, &memoproxy_spec); + CREATE_TYPE(m, st->UnpicklerMemoProxyType, &unpickler_memoproxy_spec); + CREATE_TYPE(m, st->Pickler_Type, &pickler_type_spec); + CREATE_TYPE(m, st->Unpickler_Type, &unpickler_type_spec); - /* Create the module and add the functions. */ - m = PyModule_Create(&_picklemodule); - if (m == NULL) - return NULL; +#undef CREATE_TYPE /* Add types */ - if (PyModule_AddType(m, &Pickler_Type) < 0) { - return NULL; + if (PyModule_AddType(m, &PyPickleBuffer_Type) < 0) { + return -1; } - if (PyModule_AddType(m, &Unpickler_Type) < 0) { - return NULL; + if (PyModule_AddType(m, st->Pickler_Type) < 0) { + return -1; } - if (PyModule_AddType(m, &PyPickleBuffer_Type) < 0) { - return NULL; + if (PyModule_AddType(m, st->Unpickler_Type) < 0) { + return -1; } - st = _Pickle_GetState(m); - /* Initialize the exceptions. */ st->PickleError = PyErr_NewException("_pickle.PickleError", NULL, NULL); if (st->PickleError == NULL) - return NULL; + return -1; st->PicklingError = \ PyErr_NewException("_pickle.PicklingError", st->PickleError, NULL); if (st->PicklingError == NULL) - return NULL; + return -1; st->UnpicklingError = \ PyErr_NewException("_pickle.UnpicklingError", st->PickleError, NULL); if (st->UnpicklingError == NULL) - return NULL; + return -1; if (PyModule_AddObjectRef(m, "PickleError", st->PickleError) < 0) { - return NULL; + return -1; } if (PyModule_AddObjectRef(m, "PicklingError", st->PicklingError) < 0) { - return NULL; + return -1; } if (PyModule_AddObjectRef(m, "UnpicklingError", st->UnpicklingError) < 0) { - return NULL; + return -1; } + if (_Pickle_InitState(st) < 0) - return NULL; + return -1; + + return 0; +} + +static PyModuleDef_Slot pickle_slots[] = { + {Py_mod_exec, _pickle_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, + {0, NULL}, +}; + +static struct PyModuleDef _picklemodule = { + PyModuleDef_HEAD_INIT, + .m_name = "_pickle", + .m_doc = pickle_module_doc, + .m_size = sizeof(PickleState), + .m_methods = pickle_methods, + .m_slots = pickle_slots, + .m_traverse = pickle_traverse, + .m_clear = pickle_clear, + .m_free = (freefunc)pickle_free, +}; - return m; +PyMODINIT_FUNC +PyInit__pickle(void) +{ + return PyModuleDef_Init(&_picklemodule); } diff --git a/Modules/_posixsubprocess.c b/Modules/_posixsubprocess.c index 9132f13e..2d88f5e9 100644 --- a/Modules/_posixsubprocess.c +++ b/Modules/_posixsubprocess.c @@ -5,6 +5,7 @@ #include "Python.h" #include "pycore_fileutils.h" +#include "pycore_pystate.h" #if defined(HAVE_PIPE2) && !defined(_GNU_SOURCE) # define _GNU_SOURCE #endif @@ -75,6 +76,28 @@ static struct PyModuleDef _posixsubprocessmodule; +/*[clinic input] +module _posixsubprocess +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=c62211df27cf7334]*/ + +/*[python input] +class pid_t_converter(CConverter): + type = 'pid_t' + format_unit = '" _Py_PARSE_PID "' + + def parse_arg(self, argname, displayname): + return """ + {paramname} = PyLong_AsPid({argname}); + if ({paramname} == -1 && PyErr_Occurred()) {{{{ + goto exit; + }}}} + """.format(argname=argname, paramname=self.parser_name) +[python start generated code]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=5af1c116d56cbb5a]*/ + +#include "clinic/_posixsubprocess.c.h" + /* Convert ASCII to a positive int, no libc call. no overflow. -1 on error. */ static int _pos_int_from_ascii(const char *name) @@ -138,16 +161,17 @@ _sanity_check_python_fd_sequence(PyObject *fd_sequence) /* Is fd found in the sorted Python Sequence? */ static int -_is_fd_in_sorted_fd_sequence(int fd, PyObject *fd_sequence) +_is_fd_in_sorted_fd_sequence(int fd, int *fd_sequence, + Py_ssize_t fd_sequence_len) { /* Binary search. */ Py_ssize_t search_min = 0; - Py_ssize_t search_max = PyTuple_GET_SIZE(fd_sequence) - 1; + Py_ssize_t search_max = fd_sequence_len - 1; if (search_max < 0) return 0; do { long middle = (search_min + search_max) / 2; - long middle_fd = PyLong_AsLong(PyTuple_GET_ITEM(fd_sequence, middle)); + long middle_fd = fd_sequence[middle]; if (fd == middle_fd) return 1; if (fd > middle_fd) @@ -158,8 +182,18 @@ _is_fd_in_sorted_fd_sequence(int fd, PyObject *fd_sequence) return 0; } +/* + * Do all the Python C API calls in the parent process to turn the pass_fds + * "py_fds_to_keep" tuple into a C array. The caller owns allocation and + * freeing of the array. + * + * On error an unknown number of array elements may have been filled in. + * A Python exception has been set when an error is returned. + * + * Returns: -1 on error, 0 on success. + */ static int -make_inheritable(PyObject *py_fds_to_keep, int errpipe_write) +convert_fds_to_keep_to_c(PyObject *py_fds_to_keep, int *c_fds_to_keep) { Py_ssize_t i, len; @@ -167,15 +201,37 @@ make_inheritable(PyObject *py_fds_to_keep, int errpipe_write) for (i = 0; i < len; ++i) { PyObject* fdobj = PyTuple_GET_ITEM(py_fds_to_keep, i); long fd = PyLong_AsLong(fdobj); - assert(!PyErr_Occurred()); - assert(0 <= fd && fd <= INT_MAX); + if (fd == -1 && PyErr_Occurred()) { + return -1; + } + if (fd < 0 || fd > INT_MAX) { + PyErr_SetString(PyExc_ValueError, + "fd out of range in fds_to_keep."); + return -1; + } + c_fds_to_keep[i] = (int)fd; + } + return 0; +} + + +/* This function must be async-signal-safe as it is called from child_exec() + * after fork() or vfork(). + */ +static int +make_inheritable(int *c_fds_to_keep, Py_ssize_t len, int errpipe_write) +{ + Py_ssize_t i; + + for (i = 0; i < len; ++i) { + int fd = c_fds_to_keep[i]; if (fd == errpipe_write) { - /* errpipe_write is part of py_fds_to_keep. It must be closed at + /* errpipe_write is part of fds_to_keep. It must be closed at exec(), but kept open in the child process until exec() is called. */ continue; } - if (_Py_set_inheritable_async_safe((int)fd, 1, NULL) < 0) + if (_Py_set_inheritable_async_safe(fd, 1, NULL) < 0) return -1; } return 0; @@ -211,7 +267,7 @@ safe_get_max_fd(void) /* Close all file descriptors in the given range except for those in - * py_fds_to_keep by invoking closer on each subrange. + * fds_to_keep by invoking closer on each subrange. * * If end_fd == -1, it's guessed via safe_get_max_fd(), but it isn't * possible to know for sure what the max fd to go up to is for @@ -221,19 +277,18 @@ safe_get_max_fd(void) static int _close_range_except(int start_fd, int end_fd, - PyObject *py_fds_to_keep, + int *fds_to_keep, + Py_ssize_t fds_to_keep_len, int (*closer)(int, int)) { if (end_fd == -1) { end_fd = Py_MIN(safe_get_max_fd(), INT_MAX); } - Py_ssize_t num_fds_to_keep = PyTuple_GET_SIZE(py_fds_to_keep); Py_ssize_t keep_seq_idx; - /* As py_fds_to_keep is sorted we can loop through the list closing + /* As fds_to_keep is sorted we can loop through the list closing * fds in between any in the keep list falling within our range. */ - for (keep_seq_idx = 0; keep_seq_idx < num_fds_to_keep; ++keep_seq_idx) { - PyObject* py_keep_fd = PyTuple_GET_ITEM(py_fds_to_keep, keep_seq_idx); - int keep_fd = PyLong_AsLong(py_keep_fd); + for (keep_seq_idx = 0; keep_seq_idx < fds_to_keep_len; ++keep_seq_idx) { + int keep_fd = fds_to_keep[keep_seq_idx]; if (keep_fd < start_fd) continue; if (closer(start_fd, keep_fd - 1) != 0) @@ -273,7 +328,7 @@ _brute_force_closer(int first, int last) } /* Close all open file descriptors in the range from start_fd and higher - * Do not close any in the sorted py_fds_to_keep list. + * Do not close any in the sorted fds_to_keep list. * * This version is async signal safe as it does not make any unsafe C library * calls, malloc calls or handle any locks. It is _unfortunate_ to be forced @@ -288,14 +343,16 @@ _brute_force_closer(int first, int last) * it with some cpp #define magic to work on other OSes as well if you want. */ static void -_close_open_fds_safe(int start_fd, PyObject* py_fds_to_keep) +_close_open_fds_safe(int start_fd, int *fds_to_keep, Py_ssize_t fds_to_keep_len) { int fd_dir_fd; fd_dir_fd = _Py_open_noraise(FD_DIR, O_RDONLY); if (fd_dir_fd == -1) { /* No way to get a list of open fds. */ - _close_range_except(start_fd, -1, py_fds_to_keep, _brute_force_closer); + _close_range_except(start_fd, -1, + fds_to_keep, fds_to_keep_len, + _brute_force_closer); return; } else { char buffer[sizeof(struct linux_dirent64)]; @@ -314,7 +371,8 @@ _close_open_fds_safe(int start_fd, PyObject* py_fds_to_keep) if ((fd = _pos_int_from_ascii(entry->d_name)) < 0) continue; /* Not a number. */ if (fd != fd_dir_fd && fd >= start_fd && - !_is_fd_in_sorted_fd_sequence(fd, py_fds_to_keep)) { + !_is_fd_in_sorted_fd_sequence(fd, fds_to_keep, + fds_to_keep_len)) { close(fd); } } @@ -335,7 +393,7 @@ _unsafe_closer(int first, int last) } /* Close all open file descriptors from start_fd and higher. - * Do not close any in the sorted py_fds_to_keep tuple. + * Do not close any in the sorted fds_to_keep tuple. * * This function violates the strict use of async signal safe functions. :( * It calls opendir(), readdir() and closedir(). Of these, the one most @@ -348,11 +406,13 @@ _unsafe_closer(int first, int last) * http://womble.decadent.org.uk/readdir_r-advisory.html */ static void -_close_open_fds_maybe_unsafe(int start_fd, PyObject* py_fds_to_keep) +_close_open_fds_maybe_unsafe(int start_fd, int *fds_to_keep, + Py_ssize_t fds_to_keep_len) { DIR *proc_fd_dir; #ifndef HAVE_DIRFD - while (_is_fd_in_sorted_fd_sequence(start_fd, py_fds_to_keep)) { + while (_is_fd_in_sorted_fd_sequence(start_fd, fds_to_keep, + fds_to_keep_len)) { ++start_fd; } /* Close our lowest fd before we call opendir so that it is likely to @@ -371,7 +431,8 @@ _close_open_fds_maybe_unsafe(int start_fd, PyObject* py_fds_to_keep) proc_fd_dir = opendir(FD_DIR); if (!proc_fd_dir) { /* No way to get a list of open fds. */ - _close_range_except(start_fd, -1, py_fds_to_keep, _unsafe_closer); + _close_range_except(start_fd, -1, fds_to_keep, fds_to_keep_len, + _unsafe_closer); } else { struct dirent *dir_entry; #ifdef HAVE_DIRFD @@ -385,14 +446,16 @@ _close_open_fds_maybe_unsafe(int start_fd, PyObject* py_fds_to_keep) if ((fd = _pos_int_from_ascii(dir_entry->d_name)) < 0) continue; /* Not a number. */ if (fd != fd_used_by_opendir && fd >= start_fd && - !_is_fd_in_sorted_fd_sequence(fd, py_fds_to_keep)) { + !_is_fd_in_sorted_fd_sequence(fd, fds_to_keep, + fds_to_keep_len)) { close(fd); } errno = 0; } if (errno) { /* readdir error, revert behavior. Highly Unlikely. */ - _close_range_except(start_fd, -1, py_fds_to_keep, _unsafe_closer); + _close_range_except(start_fd, -1, fds_to_keep, fds_to_keep_len, + _unsafe_closer); } closedir(proc_fd_dir); } @@ -420,16 +483,16 @@ _close_range_closer(int first, int last) #endif static void -_close_open_fds(int start_fd, PyObject* py_fds_to_keep) +_close_open_fds(int start_fd, int *fds_to_keep, Py_ssize_t fds_to_keep_len) { #ifdef HAVE_ASYNC_SAFE_CLOSE_RANGE if (_close_range_except( - start_fd, INT_MAX, py_fds_to_keep, + start_fd, INT_MAX, fds_to_keep, fds_to_keep_len, _close_range_closer) == 0) { return; } #endif - _close_open_fds_fallback(start_fd, py_fds_to_keep); + _close_open_fds_fallback(start_fd, fds_to_keep, fds_to_keep_len); } #ifdef VFORK_USABLE @@ -497,7 +560,7 @@ reset_signal_handlers(const sigset_t *child_sigmask) * required by POSIX but not supported natively on Linux. Another reason to * avoid this family of functions is that sharing an address space between * processes running with different privileges is inherently insecure. - * See bpo-35823 for further discussion and references. + * See https://bugs.python.org/issue35823 for discussion and references. * * In some C libraries, setrlimit() has the same thread list/signalling * behavior since resource limits were per-thread attributes before @@ -518,11 +581,11 @@ child_exec(char *const exec_array[], int errpipe_read, int errpipe_write, int close_fds, int restore_signals, int call_setsid, pid_t pgid_to_set, - int call_setgid, gid_t gid, - int call_setgroups, size_t groups_size, const gid_t *groups, - int call_setuid, uid_t uid, int child_umask, + gid_t gid, + Py_ssize_t extra_group_size, const gid_t *extra_groups, + uid_t uid, int child_umask, const void *child_sigmask, - PyObject *py_fds_to_keep, + int *fds_to_keep, Py_ssize_t fds_to_keep_len, PyObject *preexec_fn, PyObject *preexec_fn_args_tuple) { @@ -532,7 +595,7 @@ child_exec(char *const exec_array[], /* Buffer large enough to hold a hex integer. We can't malloc. */ char hex_errno[sizeof(saved_errno)*2+1]; - if (make_inheritable(py_fds_to_keep, errpipe_write) < 0) + if (make_inheritable(fds_to_keep, fds_to_keep_len, errpipe_write) < 0) goto error; /* Close parent's pipe ends. */ @@ -612,22 +675,24 @@ child_exec(char *const exec_array[], #endif #ifdef HAVE_SETPGID - if (pgid_to_set >= 0) + static_assert(_Py_IS_TYPE_SIGNED(pid_t), "pid_t is unsigned"); + if (pgid_to_set >= 0) { POSIX_CALL(setpgid(0, pgid_to_set)); + } #endif #ifdef HAVE_SETGROUPS - if (call_setgroups) - POSIX_CALL(setgroups(groups_size, groups)); + if (extra_group_size > 0) + POSIX_CALL(setgroups(extra_group_size, extra_groups)); #endif /* HAVE_SETGROUPS */ #ifdef HAVE_SETREGID - if (call_setgid) + if (gid != (gid_t)-1) POSIX_CALL(setregid(gid, gid)); #endif /* HAVE_SETREGID */ #ifdef HAVE_SETREUID - if (call_setuid) + if (uid != (uid_t)-1) POSIX_CALL(setreuid(uid, uid)); #endif /* HAVE_SETREUID */ @@ -652,7 +717,7 @@ child_exec(char *const exec_array[], /* close FDs after executing preexec_fn, which might open FDs */ if (close_fds) { /* TODO HP-UX could use pstat_getproc() if anyone cares about it. */ - _close_open_fds(3, py_fds_to_keep); + _close_open_fds(3, fds_to_keep, fds_to_keep_len); } /* This loop matches the Lib/os.py _execvpe()'s PATH search when */ @@ -722,11 +787,11 @@ do_fork_exec(char *const exec_array[], int errpipe_read, int errpipe_write, int close_fds, int restore_signals, int call_setsid, pid_t pgid_to_set, - int call_setgid, gid_t gid, - int call_setgroups, size_t groups_size, const gid_t *groups, - int call_setuid, uid_t uid, int child_umask, + gid_t gid, + Py_ssize_t extra_group_size, const gid_t *extra_groups, + uid_t uid, int child_umask, const void *child_sigmask, - PyObject *py_fds_to_keep, + int *fds_to_keep, Py_ssize_t fds_to_keep_len, PyObject *preexec_fn, PyObject *preexec_fn_args_tuple) { @@ -734,15 +799,31 @@ do_fork_exec(char *const exec_array[], pid_t pid; #ifdef VFORK_USABLE + PyThreadState *vfork_tstate_save; if (child_sigmask) { /* These are checked by our caller; verify them in debug builds. */ - assert(!call_setuid); - assert(!call_setgid); - assert(!call_setgroups); + assert(uid == (uid_t)-1); + assert(gid == (gid_t)-1); + assert(extra_group_size < 0); assert(preexec_fn == Py_None); + /* Drop the GIL so that other threads can continue execution while this + * thread in the parent remains blocked per vfork-semantics on the + * child's exec syscall outcome. Exec does filesystem access which + * can take an arbitrarily long time. This addresses GH-104372. + * + * The vfork'ed child still runs in our address space. Per POSIX it + * must be limited to nothing but exec, but the Linux implementation + * is a little more usable. See the child_exec() comment - The child + * MUST NOT re-acquire the GIL. + */ + vfork_tstate_save = PyEval_SaveThread(); pid = vfork(); - if (pid == -1) { + if (pid != 0) { + // Not in the child process, reacquire the GIL. + PyEval_RestoreThread(vfork_tstate_save); + } + if (pid == (pid_t)-1) { /* If vfork() fails, fall back to using fork(). When it isn't * allowed in a process by the kernel, vfork can return -1 * with errno EINVAL. https://bugs.python.org/issue47151. */ @@ -755,6 +836,7 @@ do_fork_exec(char *const exec_array[], } if (pid != 0) { + // Parent process. return pid; } @@ -775,56 +857,99 @@ do_fork_exec(char *const exec_array[], p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, errpipe_read, errpipe_write, close_fds, restore_signals, call_setsid, pgid_to_set, - call_setgid, gid, call_setgroups, groups_size, groups, - call_setuid, uid, child_umask, child_sigmask, - py_fds_to_keep, preexec_fn, preexec_fn_args_tuple); + gid, extra_group_size, extra_groups, + uid, child_umask, child_sigmask, + fds_to_keep, fds_to_keep_len, + preexec_fn, preexec_fn_args_tuple); _exit(255); return 0; /* Dead code to avoid a potential compiler warning. */ } +/*[clinic input] +_posixsubprocess.fork_exec as subprocess_fork_exec + args as process_args: object + executable_list: object + close_fds: bool + pass_fds as py_fds_to_keep: object(subclass_of='&PyTuple_Type') + cwd as cwd_obj: object + env as env_list: object + p2cread: int + p2cwrite: int + c2pread: int + c2pwrite: int + errread: int + errwrite: int + errpipe_read: int + errpipe_write: int + restore_signals: bool + call_setsid: bool + pgid_to_set: pid_t + gid as gid_object: object + extra_groups as extra_groups_packed: object + uid as uid_object: object + child_umask: int + preexec_fn: object + allow_vfork: bool + / + +Spawn a fresh new child process. + +Fork a child process, close parent file descriptors as appropriate in the +child and duplicate the few that are needed before calling exec() in the +child process. + +If close_fds is True, close file descriptors 3 and higher, except those listed +in the sorted tuple pass_fds. + +The preexec_fn, if supplied, will be called immediately before closing file +descriptors and exec. + +WARNING: preexec_fn is NOT SAFE if your application uses threads. + It may trigger infrequent, difficult to debug deadlocks. + +If an error occurs in the child process before the exec, it is +serialized and written to the errpipe_write fd per subprocess.py. + +Returns: the child process's PID. + +Raises: Only on an error in the parent process. +[clinic start generated code]*/ static PyObject * -subprocess_fork_exec(PyObject *module, PyObject *args) +subprocess_fork_exec_impl(PyObject *module, PyObject *process_args, + PyObject *executable_list, int close_fds, + PyObject *py_fds_to_keep, PyObject *cwd_obj, + PyObject *env_list, int p2cread, int p2cwrite, + int c2pread, int c2pwrite, int errread, + int errwrite, int errpipe_read, int errpipe_write, + int restore_signals, int call_setsid, + pid_t pgid_to_set, PyObject *gid_object, + PyObject *extra_groups_packed, + PyObject *uid_object, int child_umask, + PyObject *preexec_fn, int allow_vfork) +/*[clinic end generated code: output=7ee4f6ee5cf22b5b input=51757287ef266ffa]*/ { - PyObject *gc_module = NULL; - PyObject *executable_list, *py_fds_to_keep; - PyObject *env_list, *preexec_fn; - PyObject *process_args, *converted_args = NULL, *fast_args = NULL; + PyObject *converted_args = NULL, *fast_args = NULL; PyObject *preexec_fn_args_tuple = NULL; - PyObject *groups_list; - PyObject *uid_object, *gid_object; - int p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite; - int errpipe_read, errpipe_write, close_fds, restore_signals; - int call_setsid; - pid_t pgid_to_set = -1; - int call_setgid = 0, call_setgroups = 0, call_setuid = 0; - uid_t uid; - gid_t gid, *groups = NULL; - int child_umask; - PyObject *cwd_obj, *cwd_obj2 = NULL; - const char *cwd; + gid_t *extra_groups = NULL; + PyObject *cwd_obj2 = NULL; + const char *cwd = NULL; pid_t pid = -1; int need_to_reenable_gc = 0; - char *const *exec_array, *const *argv = NULL, *const *envp = NULL; - Py_ssize_t arg_num, num_groups = 0; + char *const *argv = NULL, *const *envp = NULL; + Py_ssize_t extra_group_size = 0; int need_after_fork = 0; int saved_errno = 0; - int allow_vfork; - - if (!PyArg_ParseTuple( - args, "OOpO!OOiiiiiiiiii" _Py_PARSE_PID "OOOiOp:fork_exec", - &process_args, &executable_list, - &close_fds, &PyTuple_Type, &py_fds_to_keep, - &cwd_obj, &env_list, - &p2cread, &p2cwrite, &c2pread, &c2pwrite, - &errread, &errwrite, &errpipe_read, &errpipe_write, - &restore_signals, &call_setsid, &pgid_to_set, - &gid_object, &groups_list, &uid_object, &child_umask, - &preexec_fn, &allow_vfork)) - return NULL; + int *c_fds_to_keep = NULL; + Py_ssize_t fds_to_keep_len = PyTuple_GET_SIZE(py_fds_to_keep); - if ((preexec_fn != Py_None) && - (PyInterpreterState_Get() != PyInterpreterState_Main())) { + PyInterpreterState *interp = PyInterpreterState_Get(); + if ((preexec_fn != Py_None) && interp->finalizing) { + PyErr_SetString(PyExc_RuntimeError, + "preexec_fn not supported at interpreter shutdown"); + return NULL; + } + if ((preexec_fn != Py_None) && (interp != PyInterpreterState_Main())) { PyErr_SetString(PyExc_RuntimeError, "preexec_fn not supported within subinterpreters"); return NULL; @@ -839,20 +964,12 @@ subprocess_fork_exec(PyObject *module, PyObject *args) return NULL; } - PyInterpreterState *interp = PyInterpreterState_Get(); - const PyConfig *config = _PyInterpreterState_GetConfig(interp); - if (config->_isolated_interpreter) { - PyErr_SetString(PyExc_RuntimeError, - "subprocess not supported for isolated subinterpreters"); - return NULL; - } - /* We need to call gc.disable() when we'll be calling preexec_fn */ if (preexec_fn != Py_None) { need_to_reenable_gc = PyGC_Disable(); } - exec_array = _PySequence_BytesToCharpArray(executable_list); + char *const *exec_array = _PySequence_BytesToCharpArray(executable_list); if (!exec_array) goto cleanup; @@ -870,7 +987,7 @@ subprocess_fork_exec(PyObject *module, PyObject *args) converted_args = PyTuple_New(num_args); if (converted_args == NULL) goto cleanup; - for (arg_num = 0; arg_num < num_args; ++arg_num) { + for (Py_ssize_t arg_num = 0; arg_num < num_args; ++arg_num) { PyObject *borrowed_arg, *converted_arg; if (PySequence_Fast_GET_SIZE(fast_args) != num_args) { PyErr_SetString(PyExc_RuntimeError, "args changed during iteration"); @@ -899,57 +1016,56 @@ subprocess_fork_exec(PyObject *module, PyObject *args) if (PyUnicode_FSConverter(cwd_obj, &cwd_obj2) == 0) goto cleanup; cwd = PyBytes_AsString(cwd_obj2); - } else { - cwd = NULL; } - if (groups_list != Py_None) { + if (extra_groups_packed != Py_None) { #ifdef HAVE_SETGROUPS - Py_ssize_t i; - gid_t gid; - - if (!PyList_Check(groups_list)) { + if (!PyList_Check(extra_groups_packed)) { PyErr_SetString(PyExc_TypeError, "setgroups argument must be a list"); goto cleanup; } - num_groups = PySequence_Size(groups_list); + extra_group_size = PySequence_Size(extra_groups_packed); - if (num_groups < 0) + if (extra_group_size < 0) goto cleanup; - if (num_groups > MAX_GROUPS) { - PyErr_SetString(PyExc_ValueError, "too many groups"); + if (extra_group_size > MAX_GROUPS) { + PyErr_SetString(PyExc_ValueError, "too many extra_groups"); goto cleanup; } - if ((groups = PyMem_RawMalloc(num_groups * sizeof(gid_t))) == NULL) { - PyErr_SetString(PyExc_MemoryError, - "failed to allocate memory for group list"); - goto cleanup; + /* Deliberately keep extra_groups == NULL for extra_group_size == 0 */ + if (extra_group_size > 0) { + extra_groups = PyMem_RawMalloc(extra_group_size * sizeof(gid_t)); + if (extra_groups == NULL) { + PyErr_SetString(PyExc_MemoryError, + "failed to allocate memory for group list"); + goto cleanup; + } } - for (i = 0; i < num_groups; i++) { + for (Py_ssize_t i = 0; i < extra_group_size; i++) { PyObject *elem; - elem = PySequence_GetItem(groups_list, i); + elem = PySequence_GetItem(extra_groups_packed, i); if (!elem) goto cleanup; if (!PyLong_Check(elem)) { PyErr_SetString(PyExc_TypeError, - "groups must be integers"); + "extra_groups must be integers"); Py_DECREF(elem); goto cleanup; } else { + gid_t gid; if (!_Py_Gid_Converter(elem, &gid)) { Py_DECREF(elem); PyErr_SetString(PyExc_ValueError, "invalid group id"); goto cleanup; } - groups[i] = gid; + extra_groups[i] = gid; } Py_DECREF(elem); } - call_setgroups = 1; #else /* HAVE_SETGROUPS */ PyErr_BadInternalCall(); @@ -957,32 +1073,39 @@ subprocess_fork_exec(PyObject *module, PyObject *args) #endif /* HAVE_SETGROUPS */ } + gid_t gid = (gid_t)-1; if (gid_object != Py_None) { #ifdef HAVE_SETREGID if (!_Py_Gid_Converter(gid_object, &gid)) goto cleanup; - call_setgid = 1; - #else /* HAVE_SETREGID */ PyErr_BadInternalCall(); goto cleanup; #endif /* HAVE_SETREUID */ } + uid_t uid = (uid_t)-1; if (uid_object != Py_None) { #ifdef HAVE_SETREUID if (!_Py_Uid_Converter(uid_object, &uid)) goto cleanup; - call_setuid = 1; - #else /* HAVE_SETREUID */ PyErr_BadInternalCall(); goto cleanup; #endif /* HAVE_SETREUID */ } + c_fds_to_keep = PyMem_Malloc(fds_to_keep_len * sizeof(int)); + if (c_fds_to_keep == NULL) { + PyErr_SetString(PyExc_MemoryError, "failed to malloc c_fds_to_keep"); + goto cleanup; + } + if (convert_fds_to_keep_to_c(py_fds_to_keep, c_fds_to_keep) < 0) { + goto cleanup; + } + /* This must be the last thing done before fork() because we do not * want to call PyOS_BeforeFork() if there is any chance of another * error leading to the cleanup: code without calling fork(). */ @@ -1000,7 +1123,7 @@ subprocess_fork_exec(PyObject *module, PyObject *args) /* Use vfork() only if it's safe. See the comment above child_exec(). */ sigset_t old_sigs; if (preexec_fn == Py_None && allow_vfork && - !call_setuid && !call_setgid && !call_setgroups) { + uid == (uid_t)-1 && gid == (gid_t)-1 && extra_group_size < 0) { /* Block all signals to ensure that no signal handlers are run in the * child process while it shares memory with us. Note that signals * used internally by C libraries won't be blocked by @@ -1023,12 +1146,13 @@ subprocess_fork_exec(PyObject *module, PyObject *args) p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, errpipe_read, errpipe_write, close_fds, restore_signals, call_setsid, pgid_to_set, - call_setgid, gid, call_setgroups, num_groups, groups, - call_setuid, uid, child_umask, old_sigmask, - py_fds_to_keep, preexec_fn, preexec_fn_args_tuple); + gid, extra_group_size, extra_groups, + uid, child_umask, old_sigmask, + c_fds_to_keep, fds_to_keep_len, + preexec_fn, preexec_fn_args_tuple); /* Parent (original) process */ - if (pid == -1) { + if (pid == (pid_t)-1) { /* Capture errno for the exception. */ saved_errno = errno; } @@ -1055,6 +1179,10 @@ subprocess_fork_exec(PyObject *module, PyObject *args) PyOS_AfterFork_Parent(); cleanup: + if (c_fds_to_keep != NULL) { + PyMem_Free(c_fds_to_keep); + } + if (saved_errno != 0) { errno = saved_errno; /* We can't call this above as PyOS_AfterFork_Parent() calls back @@ -1063,7 +1191,7 @@ cleanup: } Py_XDECREF(preexec_fn_args_tuple); - PyMem_RawFree(groups); + PyMem_RawFree(extra_groups); Py_XDECREF(cwd_obj2); if (envp) _Py_FreeCharPArray(envp); @@ -1077,51 +1205,22 @@ cleanup: if (need_to_reenable_gc) { PyGC_Enable(); } - Py_XDECREF(gc_module); return pid == -1 ? NULL : PyLong_FromPid(pid); } - -PyDoc_STRVAR(subprocess_fork_exec_doc, -"fork_exec(args, executable_list, close_fds, pass_fds, cwd, env,\n\ - p2cread, p2cwrite, c2pread, c2pwrite,\n\ - errread, errwrite, errpipe_read, errpipe_write,\n\ - restore_signals, call_setsid, pgid_to_set,\n\ - gid, groups_list, uid,\n\ - preexec_fn)\n\ -\n\ -Forks a child process, closes parent file descriptors as appropriate in the\n\ -child and dups the few that are needed before calling exec() in the child\n\ -process.\n\ -\n\ -If close_fds is true, close file descriptors 3 and higher, except those listed\n\ -in the sorted tuple pass_fds.\n\ -\n\ -The preexec_fn, if supplied, will be called immediately before closing file\n\ -descriptors and exec.\n\ -WARNING: preexec_fn is NOT SAFE if your application uses threads.\n\ - It may trigger infrequent, difficult to debug deadlocks.\n\ -\n\ -If an error occurs in the child process before the exec, it is\n\ -serialized and written to the errpipe_write fd per subprocess.py.\n\ -\n\ -Returns: the child process's PID.\n\ -\n\ -Raises: Only on an error in the parent process.\n\ -"); - /* module level code ********************************************************/ PyDoc_STRVAR(module_doc, "A POSIX helper for the subprocess module."); static PyMethodDef module_methods[] = { - {"fork_exec", subprocess_fork_exec, METH_VARARGS, subprocess_fork_exec_doc}, + SUBPROCESS_FORK_EXEC_METHODDEF {NULL, NULL} /* sentinel */ }; static PyModuleDef_Slot _posixsubprocess_slots[] = { + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; diff --git a/Modules/_queuemodule.c b/Modules/_queuemodule.c index af19dd6c..db5be842 100644 --- a/Modules/_queuemodule.c +++ b/Modules/_queuemodule.c @@ -210,6 +210,7 @@ _queue_SimpleQueue_get_impl(simplequeueobject *self, PyTypeObject *cls, PyObject *item; PyLockStatus r; PY_TIMEOUT_T microseconds; + PyThreadState *tstate = PyThreadState_Get(); if (block == 0) { /* Non-blocking */ @@ -253,7 +254,7 @@ _queue_SimpleQueue_get_impl(simplequeueobject *self, PyTypeObject *cls, Py_END_ALLOW_THREADS } - if (r == PY_LOCK_INTR && Py_MakePendingCalls() < 0) { + if (r == PY_LOCK_INTR && _PyEval_MakePendingCalls(tstate) < 0) { return NULL; } if (r == PY_LOCK_FAILURE) { @@ -431,6 +432,7 @@ queuemodule_exec(PyObject *module) static PyModuleDef_Slot queuemodule_slots[] = { {Py_mod_exec, queuemodule_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; diff --git a/Modules/_randommodule.c b/Modules/_randommodule.c index d96c0371..fda5ef26 100644 --- a/Modules/_randommodule.c +++ b/Modules/_randommodule.c @@ -72,10 +72,15 @@ #include "Python.h" #include "pycore_moduleobject.h" // _PyModule_GetState() +#include "pycore_runtime.h" #ifdef HAVE_PROCESS_H # include <process.h> // getpid() #endif +#ifdef MS_WINDOWS +# include <windows.h> +#endif + /* Period parameters -- These are all magic. Don't change. */ #define N 624 #define M 397 @@ -258,7 +263,9 @@ random_seed_time_pid(RandomObject *self) key[0] = (uint32_t)(now & 0xffffffffU); key[1] = (uint32_t)(now >> 32); -#ifdef HAVE_GETPID +#if defined(MS_WINDOWS) && !defined(MS_WINDOWS_DESKTOP) && !defined(MS_WINDOWS_SYSTEM) + key[2] = (uint32_t)GetCurrentProcessId(); +#elif defined(HAVE_GETPID) key[2] = (uint32_t)getpid(); #else key[2] = 0; @@ -617,6 +624,7 @@ _random_exec(PyObject *module) static PyModuleDef_Slot _random_slots[] = { {Py_mod_exec, _random_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; diff --git a/Modules/_scproxy.c b/Modules/_scproxy.c index 4c1f1aa3..0df0324d 100644 --- a/Modules/_scproxy.c +++ b/Modules/_scproxy.c @@ -84,7 +84,7 @@ get_proxy_settings(PyObject* Py_UNUSED(mod), PyObject *Py_UNUSED(ignored)) if (v == NULL) goto error; r = PyDict_SetItemString(result, "exclude_simple", v); - Py_DECREF(v); v = NULL; + Py_SETREF(v, NULL); if (r == -1) goto error; anArray = CFDictionaryGetValue(proxyDict, @@ -206,6 +206,11 @@ get_proxies(PyObject* Py_UNUSED(mod), PyObject *Py_UNUSED(ignored)) kSCPropNetProxiesGopherProxy, kSCPropNetProxiesGopherPort); if (r == -1) goto error; + r = set_proxy(result, "socks", proxyDict, + kSCPropNetProxiesSOCKSEnable, + kSCPropNetProxiesSOCKSProxy, + kSCPropNetProxiesSOCKSPort); + if (r == -1) goto error; CFRelease(proxyDict); return result; @@ -232,6 +237,7 @@ static PyMethodDef mod_methods[] = { }; static PyModuleDef_Slot _scproxy_slots[] = { + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; diff --git a/Modules/_sha3/LICENSE b/Modules/_sha3/LICENSE deleted file mode 100644 index d2d484d8..00000000 --- a/Modules/_sha3/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2015 Markku-Juhani O. Saarinen - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - diff --git a/Modules/_sha3/README.txt b/Modules/_sha3/README.txt deleted file mode 100644 index b35919b0..00000000 --- a/Modules/_sha3/README.txt +++ /dev/null @@ -1,8 +0,0 @@ -tiny_sha3 -========= - -https://github.com/mjosaarinen/tiny_sha3 -commit dcbb3192047c2a721f5f851db591871d428036a9 - -- All functions have been converted to static functions. -- sha3() function is commented out. diff --git a/Modules/_sha3/sha3.c b/Modules/_sha3/sha3.c deleted file mode 100644 index e2d3fd7b..00000000 --- a/Modules/_sha3/sha3.c +++ /dev/null @@ -1,193 +0,0 @@ -// sha3.c -// 19-Nov-11 Markku-Juhani O. Saarinen <mjos@iki.fi> - -// Revised 07-Aug-15 to match with official release of FIPS PUB 202 "SHA3" -// Revised 03-Sep-15 for portability + OpenSSL - style API - -#include "sha3.h" - -// update the state with given number of rounds - -static void sha3_keccakf(uint64_t st[25]) -{ - // constants - const uint64_t keccakf_rndc[24] = { - 0x0000000000000001, 0x0000000000008082, 0x800000000000808a, - 0x8000000080008000, 0x000000000000808b, 0x0000000080000001, - 0x8000000080008081, 0x8000000000008009, 0x000000000000008a, - 0x0000000000000088, 0x0000000080008009, 0x000000008000000a, - 0x000000008000808b, 0x800000000000008b, 0x8000000000008089, - 0x8000000000008003, 0x8000000000008002, 0x8000000000000080, - 0x000000000000800a, 0x800000008000000a, 0x8000000080008081, - 0x8000000000008080, 0x0000000080000001, 0x8000000080008008 - }; - const int keccakf_rotc[24] = { - 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14, - 27, 41, 56, 8, 25, 43, 62, 18, 39, 61, 20, 44 - }; - const int keccakf_piln[24] = { - 10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4, - 15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1 - }; - - // variables - int i, j, r; - uint64_t t, bc[5]; - -#if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__ - uint8_t *v; - - // endianess conversion. this is redundant on little-endian targets - for (i = 0; i < 25; i++) { - v = (uint8_t *) &st[i]; - st[i] = ((uint64_t) v[0]) | (((uint64_t) v[1]) << 8) | - (((uint64_t) v[2]) << 16) | (((uint64_t) v[3]) << 24) | - (((uint64_t) v[4]) << 32) | (((uint64_t) v[5]) << 40) | - (((uint64_t) v[6]) << 48) | (((uint64_t) v[7]) << 56); - } -#endif - - // actual iteration - for (r = 0; r < KECCAKF_ROUNDS; r++) { - - // Theta - for (i = 0; i < 5; i++) - bc[i] = st[i] ^ st[i + 5] ^ st[i + 10] ^ st[i + 15] ^ st[i + 20]; - - for (i = 0; i < 5; i++) { - t = bc[(i + 4) % 5] ^ ROTL64(bc[(i + 1) % 5], 1); - for (j = 0; j < 25; j += 5) - st[j + i] ^= t; - } - - // Rho Pi - t = st[1]; - for (i = 0; i < 24; i++) { - j = keccakf_piln[i]; - bc[0] = st[j]; - st[j] = ROTL64(t, keccakf_rotc[i]); - t = bc[0]; - } - - // Chi - for (j = 0; j < 25; j += 5) { - for (i = 0; i < 5; i++) - bc[i] = st[j + i]; - for (i = 0; i < 5; i++) - st[j + i] ^= (~bc[(i + 1) % 5]) & bc[(i + 2) % 5]; - } - - // Iota - st[0] ^= keccakf_rndc[r]; - } - -#if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__ - // endianess conversion. this is redundant on little-endian targets - for (i = 0; i < 25; i++) { - v = (uint8_t *) &st[i]; - t = st[i]; - v[0] = t & 0xFF; - v[1] = (t >> 8) & 0xFF; - v[2] = (t >> 16) & 0xFF; - v[3] = (t >> 24) & 0xFF; - v[4] = (t >> 32) & 0xFF; - v[5] = (t >> 40) & 0xFF; - v[6] = (t >> 48) & 0xFF; - v[7] = (t >> 56) & 0xFF; - } -#endif -} - -// Initialize the context for SHA3 - -static int sha3_init(sha3_ctx_t *c, int mdlen) -{ - int i; - - for (i = 0; i < 25; i++) - c->st.q[i] = 0; - c->mdlen = mdlen; - c->rsiz = 200 - 2 * mdlen; - c->pt = 0; - - return 1; -} - -// update state with more data - -static int sha3_update(sha3_ctx_t *c, const void *data, size_t len) -{ - size_t i; - int j; - - j = c->pt; - for (i = 0; i < len; i++) { - c->st.b[j++] ^= ((const uint8_t *) data)[i]; - if (j >= c->rsiz) { - sha3_keccakf(c->st.q); - j = 0; - } - } - c->pt = j; - - return 1; -} - -// finalize and output a hash - -static int sha3_final(void *md, sha3_ctx_t *c) -{ - int i; - - c->st.b[c->pt] ^= 0x06; - c->st.b[c->rsiz - 1] ^= 0x80; - sha3_keccakf(c->st.q); - - for (i = 0; i < c->mdlen; i++) { - ((uint8_t *) md)[i] = c->st.b[i]; - } - - return 1; -} - -#if 0 -// compute a SHA-3 hash (md) of given byte length from "in" - -void *sha3(const void *in, size_t inlen, void *md, int mdlen) -{ - sha3_ctx_t sha3; - - sha3_init(&sha3, mdlen); - sha3_update(&sha3, in, inlen); - sha3_final(md, &sha3); - - return md; -} -#endif - -// SHAKE128 and SHAKE256 extensible-output functionality - -static void shake_xof(sha3_ctx_t *c) -{ - c->st.b[c->pt] ^= 0x1F; - c->st.b[c->rsiz - 1] ^= 0x80; - sha3_keccakf(c->st.q); - c->pt = 0; -} - -static void shake_out(sha3_ctx_t *c, void *out, size_t len) -{ - size_t i; - int j; - - j = c->pt; - for (i = 0; i < len; i++) { - if (j >= c->rsiz) { - sha3_keccakf(c->st.q); - j = 0; - } - ((uint8_t *) out)[i] = c->st.b[j++]; - } - c->pt = j; -} - diff --git a/Modules/_sha3/sha3.h b/Modules/_sha3/sha3.h deleted file mode 100644 index f973d673..00000000 --- a/Modules/_sha3/sha3.h +++ /dev/null @@ -1,49 +0,0 @@ -// sha3.h -// 19-Nov-11 Markku-Juhani O. Saarinen <mjos@iki.fi> - -#ifndef SHA3_H -#define SHA3_H - -#include <stddef.h> -#include <stdint.h> - -#ifndef KECCAKF_ROUNDS -#define KECCAKF_ROUNDS 24 -#endif - -#ifndef ROTL64 -#define ROTL64(x, y) (((x) << (y)) | ((x) >> (64 - (y)))) -#endif - -// state context -typedef struct { - union { // state: - uint8_t b[200]; // 8-bit bytes - uint64_t q[25]; // 64-bit words - } st; - int pt, rsiz, mdlen; // these don't overflow -} sha3_ctx_t; - -// Compression function. -static void sha3_keccakf(uint64_t st[25]); - -// OpenSSL - like interfece -static int sha3_init(sha3_ctx_t *c, int mdlen); // mdlen = hash output in bytes -static int sha3_update(sha3_ctx_t *c, const void *data, size_t len); -static int sha3_final(void *md, sha3_ctx_t *c); // digest goes to md - -// compute a sha3 hash (md) of given byte length from "in" -#if 0 -static void *sha3(const void *in, size_t inlen, void *md, int mdlen); -#endif - -// SHAKE128 and SHAKE256 extensible-output functions -#define shake128_init(c) sha3_init(c, 16) -#define shake256_init(c) sha3_init(c, 32) -#define shake_update sha3_update - -static void shake_xof(sha3_ctx_t *c); -static void shake_out(sha3_ctx_t *c, void *out, size_t len); - -#endif - diff --git a/Modules/_sqlite/clinic/blob.c.h b/Modules/_sqlite/clinic/blob.c.h index b467c99e..f3d8a35b 100644 --- a/Modules/_sqlite/clinic/blob.c.h +++ b/Modules/_sqlite/clinic/blob.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(blob_close__doc__, "close($self, /)\n" "--\n" @@ -213,4 +219,4 @@ blob_exit(pysqlite_Blob *self, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=382cbf0977bb158a input=a9049054013a1b77]*/ +/*[clinic end generated code: output=ad6a402f70e85977 input=a9049054013a1b77]*/ diff --git a/Modules/_sqlite/clinic/connection.c.h b/Modules/_sqlite/clinic/connection.c.h index 62d31b78..417abcc4 100644 --- a/Modules/_sqlite/clinic/connection.c.h +++ b/Modules/_sqlite/clinic/connection.c.h @@ -2,20 +2,50 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + static int pysqlite_connection_init_impl(pysqlite_Connection *self, PyObject *database, double timeout, int detect_types, const char *isolation_level, int check_same_thread, PyObject *factory, - int cache_size, int uri); + int cache_size, int uri, + enum autocommit_mode autocommit); static int pysqlite_connection_init(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; - static const char * const _keywords[] = {"database", "timeout", "detect_types", "isolation_level", "check_same_thread", "factory", "cached_statements", "uri", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "Connection", 0}; - PyObject *argsbuf[8]; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 9 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(database), &_Py_ID(timeout), &_Py_ID(detect_types), &_Py_ID(isolation_level), &_Py_ID(check_same_thread), &_Py_ID(factory), &_Py_ID(cached_statements), &_Py_ID(uri), &_Py_ID(autocommit), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"database", "timeout", "detect_types", "isolation_level", "check_same_thread", "factory", "cached_statements", "uri", "autocommit", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "Connection", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[9]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); Py_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 1; @@ -27,6 +57,7 @@ pysqlite_connection_init(PyObject *self, PyObject *args, PyObject *kwargs) PyObject *factory = (PyObject*)clinic_state()->ConnectionType; int cache_size = 128; int uri = 0; + enum autocommit_mode autocommit = LEGACY_TRANSACTION_CONTROL; fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 8, 0, argsbuf); if (!fastargs) { @@ -69,8 +100,8 @@ pysqlite_connection_init(PyObject *self, PyObject *args, PyObject *kwargs) } } if (fastargs[4]) { - check_same_thread = _PyLong_AsInt(fastargs[4]); - if (check_same_thread == -1 && PyErr_Occurred()) { + check_same_thread = PyObject_IsTrue(fastargs[4]); + if (check_same_thread < 0) { goto exit; } if (!--noptargs) { @@ -92,12 +123,24 @@ pysqlite_connection_init(PyObject *self, PyObject *args, PyObject *kwargs) goto skip_optional_pos; } } - uri = PyObject_IsTrue(fastargs[7]); - if (uri < 0) { - goto exit; + if (fastargs[7]) { + uri = PyObject_IsTrue(fastargs[7]); + if (uri < 0) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } } skip_optional_pos: - return_value = pysqlite_connection_init_impl((pysqlite_Connection *)self, database, timeout, detect_types, isolation_level, check_same_thread, factory, cache_size, uri); + if (!noptargs) { + goto skip_optional_kwonly; + } + if (!autocommit_converter(fastargs[8], &autocommit)) { + goto exit; + } +skip_optional_kwonly: + return_value = pysqlite_connection_init_impl((pysqlite_Connection *)self, database, timeout, detect_types, isolation_level, check_same_thread, factory, cache_size, uri, autocommit); exit: return return_value; @@ -119,8 +162,31 @@ static PyObject * pysqlite_connection_cursor(pysqlite_Connection *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(factory), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"factory", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "cursor", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "cursor", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *factory = NULL; @@ -162,19 +228,42 @@ PyDoc_STRVAR(blobopen__doc__, static PyObject * blobopen_impl(pysqlite_Connection *self, const char *table, const char *col, - int row, int readonly, const char *name); + sqlite3_int64 row, int readonly, const char *name); static PyObject * blobopen(pysqlite_Connection *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(readonly), &_Py_ID(name), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "", "", "readonly", "name", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "blobopen", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "blobopen", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3; const char *table; const char *col; - int row; + sqlite3_int64 row; int readonly = 0; const char *name = "main"; @@ -208,16 +297,15 @@ blobopen(pysqlite_Connection *self, PyObject *const *args, Py_ssize_t nargs, PyO PyErr_SetString(PyExc_ValueError, "embedded null character"); goto exit; } - row = _PyLong_AsInt(args[2]); - if (row == -1 && PyErr_Occurred()) { + if (!sqlite3_int64_converter(args[2], &row)) { goto exit; } if (!noptargs) { goto skip_optional_kwonly; } if (args[3]) { - readonly = _PyLong_AsInt(args[3]); - if (readonly == -1 && PyErr_Occurred()) { + readonly = PyObject_IsTrue(args[3]); + if (readonly < 0) { goto exit; } if (!--noptargs) { @@ -323,8 +411,31 @@ static PyObject * pysqlite_connection_create_function(pysqlite_Connection *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(name), &_Py_ID(narg), &_Py_ID(func), &_Py_ID(deterministic), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"name", "narg", "func", "deterministic", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "create_function", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "create_function", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3; const char *name; @@ -397,8 +508,19 @@ static PyObject * create_window_function(pysqlite_Connection *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + static const char * const _keywords[] = {"", "", "", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "create_window_function", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "create_window_function", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; const char *name; int num_params; @@ -453,8 +575,31 @@ static PyObject * pysqlite_connection_create_aggregate(pysqlite_Connection *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(name), &_Py_ID(n_arg), &_Py_ID(aggregate_class), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"name", "n_arg", "aggregate_class", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "create_aggregate", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "create_aggregate", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; const char *name; int n_arg; @@ -506,8 +651,31 @@ static PyObject * pysqlite_connection_set_authorizer(pysqlite_Connection *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(authorizer_callback), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"authorizer_callback", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "set_authorizer", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "set_authorizer", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *callable; @@ -540,8 +708,31 @@ static PyObject * pysqlite_connection_set_progress_handler(pysqlite_Connection *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(progress_handler), &_Py_ID(n), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"progress_handler", "n", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "set_progress_handler", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "set_progress_handler", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject *callable; int n; @@ -579,8 +770,31 @@ static PyObject * pysqlite_connection_set_trace_callback(pysqlite_Connection *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(trace_callback), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"trace_callback", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "set_trace_callback", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "set_trace_callback", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *callable; @@ -616,8 +830,8 @@ pysqlite_connection_enable_load_extension(pysqlite_Connection *self, PyObject *a PyObject *return_value = NULL; int onoff; - onoff = _PyLong_AsInt(arg); - if (onoff == -1 && PyErr_Occurred()) { + onoff = PyObject_IsTrue(arg); + if (onoff < 0) { goto exit; } return_value = pysqlite_connection_enable_load_extension_impl(self, onoff); @@ -631,30 +845,63 @@ exit: #if defined(PY_SQLITE_ENABLE_LOAD_EXTENSION) PyDoc_STRVAR(pysqlite_connection_load_extension__doc__, -"load_extension($self, name, /)\n" +"load_extension($self, name, /, *, entrypoint=None)\n" "--\n" "\n" "Load SQLite extension module."); #define PYSQLITE_CONNECTION_LOAD_EXTENSION_METHODDEF \ - {"load_extension", (PyCFunction)pysqlite_connection_load_extension, METH_O, pysqlite_connection_load_extension__doc__}, + {"load_extension", _PyCFunction_CAST(pysqlite_connection_load_extension), METH_FASTCALL|METH_KEYWORDS, pysqlite_connection_load_extension__doc__}, static PyObject * pysqlite_connection_load_extension_impl(pysqlite_Connection *self, - const char *extension_name); + const char *extension_name, + const char *entrypoint); static PyObject * -pysqlite_connection_load_extension(pysqlite_Connection *self, PyObject *arg) +pysqlite_connection_load_extension(pysqlite_Connection *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(entrypoint), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"", "entrypoint", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "load_extension", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; const char *extension_name; + const char *entrypoint = NULL; - if (!PyUnicode_Check(arg)) { - _PyArg_BadArgument("load_extension", "argument", "str", arg); + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("load_extension", "argument 1", "str", args[0]); goto exit; } Py_ssize_t extension_name_length; - extension_name = PyUnicode_AsUTF8AndSize(arg, &extension_name_length); + extension_name = PyUnicode_AsUTF8AndSize(args[0], &extension_name_length); if (extension_name == NULL) { goto exit; } @@ -662,7 +909,29 @@ pysqlite_connection_load_extension(pysqlite_Connection *self, PyObject *arg) PyErr_SetString(PyExc_ValueError, "embedded null character"); goto exit; } - return_value = pysqlite_connection_load_extension_impl(self, extension_name); + if (!noptargs) { + goto skip_optional_kwonly; + } + if (args[1] == Py_None) { + entrypoint = NULL; + } + else if (PyUnicode_Check(args[1])) { + Py_ssize_t entrypoint_length; + entrypoint = PyUnicode_AsUTF8AndSize(args[1], &entrypoint_length); + if (entrypoint == NULL) { + goto exit; + } + if (strlen(entrypoint) != (size_t)entrypoint_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + } + else { + _PyArg_BadArgument("load_extension", "argument 'entrypoint'", "str or None", args[1]); + goto exit; + } +skip_optional_kwonly: + return_value = pysqlite_connection_load_extension_impl(self, extension_name, entrypoint); exit: return return_value; @@ -815,8 +1084,31 @@ static PyObject * pysqlite_connection_backup(pysqlite_Connection *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 5 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(target), &_Py_ID(pages), &_Py_ID(progress), &_Py_ID(name), &_Py_ID(sleep), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"target", "pages", "progress", "name", "sleep", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "backup", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "backup", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; pysqlite_Connection *target; @@ -906,8 +1198,19 @@ static PyObject * pysqlite_connection_create_collation(pysqlite_Connection *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + static const char * const _keywords[] = {"", "", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "create_collation", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "create_collation", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; const char *name; PyObject *callable; @@ -962,8 +1265,31 @@ static PyObject * serialize(pysqlite_Connection *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(name), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"name", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "serialize", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "serialize", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; const char *name = "main"; @@ -1028,8 +1354,31 @@ static PyObject * deserialize(pysqlite_Connection *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(name), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "name", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "deserialize", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "deserialize", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; Py_buffer data = {NULL, NULL}; @@ -1218,6 +1567,85 @@ exit: return return_value; } +PyDoc_STRVAR(setconfig__doc__, +"setconfig($self, op, enable=True, /)\n" +"--\n" +"\n" +"Set a boolean connection configuration option.\n" +"\n" +" op\n" +" The configuration verb; one of the sqlite3.SQLITE_DBCONFIG codes."); + +#define SETCONFIG_METHODDEF \ + {"setconfig", _PyCFunction_CAST(setconfig), METH_FASTCALL, setconfig__doc__}, + +static PyObject * +setconfig_impl(pysqlite_Connection *self, int op, int enable); + +static PyObject * +setconfig(pysqlite_Connection *self, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int op; + int enable = 1; + + if (!_PyArg_CheckPositional("setconfig", nargs, 1, 2)) { + goto exit; + } + op = _PyLong_AsInt(args[0]); + if (op == -1 && PyErr_Occurred()) { + goto exit; + } + if (nargs < 2) { + goto skip_optional; + } + enable = PyObject_IsTrue(args[1]); + if (enable < 0) { + goto exit; + } +skip_optional: + return_value = setconfig_impl(self, op, enable); + +exit: + return return_value; +} + +PyDoc_STRVAR(getconfig__doc__, +"getconfig($self, op, /)\n" +"--\n" +"\n" +"Query a boolean connection configuration option.\n" +"\n" +" op\n" +" The configuration verb; one of the sqlite3.SQLITE_DBCONFIG codes."); + +#define GETCONFIG_METHODDEF \ + {"getconfig", (PyCFunction)getconfig, METH_O, getconfig__doc__}, + +static int +getconfig_impl(pysqlite_Connection *self, int op); + +static PyObject * +getconfig(pysqlite_Connection *self, PyObject *arg) +{ + PyObject *return_value = NULL; + int op; + int _return_value; + + op = _PyLong_AsInt(arg); + if (op == -1 && PyErr_Occurred()) { + goto exit; + } + _return_value = getconfig_impl(self, op); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyBool_FromLong((long)_return_value); + +exit: + return return_value; +} + #ifndef CREATE_WINDOW_FUNCTION_METHODDEF #define CREATE_WINDOW_FUNCTION_METHODDEF #endif /* !defined(CREATE_WINDOW_FUNCTION_METHODDEF) */ @@ -1237,4 +1665,4 @@ exit: #ifndef DESERIALIZE_METHODDEF #define DESERIALIZE_METHODDEF #endif /* !defined(DESERIALIZE_METHODDEF) */ -/*[clinic end generated code: output=8818c1c3ec9425aa input=a9049054013a1b77]*/ +/*[clinic end generated code: output=834a99827555bf1a input=a9049054013a1b77]*/ diff --git a/Modules/_sqlite/clinic/cursor.c.h b/Modules/_sqlite/clinic/cursor.c.h index b29c3330..43e912d1 100644 --- a/Modules/_sqlite/clinic/cursor.c.h +++ b/Modules/_sqlite/clinic/cursor.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + static int pysqlite_cursor_init_impl(pysqlite_Cursor *self, pysqlite_Connection *connection); @@ -10,10 +16,11 @@ static int pysqlite_cursor_init(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; + PyTypeObject *base_tp = clinic_state()->CursorType; pysqlite_Connection *connection; - if ((Py_IS_TYPE(self, clinic_state()->CursorType) || - Py_TYPE(self)->tp_new == clinic_state()->CursorType->tp_new) && + if ((Py_IS_TYPE(self, base_tp) || + Py_TYPE(self)->tp_new == base_tp->tp_new) && !_PyArg_NoKeywords("Cursor", kwargs)) { goto exit; } @@ -186,8 +193,31 @@ static PyObject * pysqlite_cursor_fetchmany(pysqlite_Cursor *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(size), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"size", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "fetchmany", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "fetchmany", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int maxrows = self->arraysize; @@ -289,4 +319,4 @@ pysqlite_cursor_close(pysqlite_Cursor *self, PyObject *Py_UNUSED(ignored)) { return pysqlite_cursor_close_impl(self); } -/*[clinic end generated code: output=2b9c6a3ca8a8caff input=a9049054013a1b77]*/ +/*[clinic end generated code: output=1f82e3c9791bb9a5 input=a9049054013a1b77]*/ diff --git a/Modules/_sqlite/clinic/module.c.h b/Modules/_sqlite/clinic/module.c.h index f5278078..12f60835 100644 --- a/Modules/_sqlite/clinic/module.c.h +++ b/Modules/_sqlite/clinic/module.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(pysqlite_complete_statement__doc__, "complete_statement($module, /, statement)\n" "--\n" @@ -18,8 +24,31 @@ static PyObject * pysqlite_complete_statement(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(statement), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"statement", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "complete_statement", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "complete_statement", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; const char *statement; @@ -46,46 +75,6 @@ exit: return return_value; } -PyDoc_STRVAR(pysqlite_enable_shared_cache__doc__, -"enable_shared_cache($module, /, do_enable)\n" -"--\n" -"\n" -"Enable or disable shared cache mode for the calling thread.\n" -"\n" -"This method is deprecated and will be removed in Python 3.12.\n" -"Shared cache is strongly discouraged by the SQLite 3 documentation.\n" -"If shared cache must be used, open the database in URI mode using\n" -"the cache=shared query parameter."); - -#define PYSQLITE_ENABLE_SHARED_CACHE_METHODDEF \ - {"enable_shared_cache", _PyCFunction_CAST(pysqlite_enable_shared_cache), METH_FASTCALL|METH_KEYWORDS, pysqlite_enable_shared_cache__doc__}, - -static PyObject * -pysqlite_enable_shared_cache_impl(PyObject *module, int do_enable); - -static PyObject * -pysqlite_enable_shared_cache(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"do_enable", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "enable_shared_cache", 0}; - PyObject *argsbuf[1]; - int do_enable; - - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); - if (!args) { - goto exit; - } - do_enable = _PyLong_AsInt(args[0]); - if (do_enable == -1 && PyErr_Occurred()) { - goto exit; - } - return_value = pysqlite_enable_shared_cache_impl(module, do_enable); - -exit: - return return_value; -} - PyDoc_STRVAR(pysqlite_register_adapter__doc__, "register_adapter($module, type, adapter, /)\n" "--\n" @@ -222,4 +211,4 @@ skip_optional: exit: return return_value; } -/*[clinic end generated code: output=ecaf4e0a239c2685 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=39d38c6cfc455042 input=a9049054013a1b77]*/ diff --git a/Modules/_sqlite/clinic/row.c.h b/Modules/_sqlite/clinic/row.c.h index c936ef75..89a48fd5 100644 --- a/Modules/_sqlite/clinic/row.c.h +++ b/Modules/_sqlite/clinic/row.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + static PyObject * pysqlite_row_new_impl(PyTypeObject *type, pysqlite_Cursor *cursor, PyObject *data); @@ -10,11 +16,11 @@ static PyObject * pysqlite_row_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + PyTypeObject *base_tp = clinic_state()->RowType; pysqlite_Cursor *cursor; PyObject *data; - if ((type == clinic_state()->RowType || - type->tp_init == clinic_state()->RowType->tp_init) && + if ((type == base_tp || type->tp_init == base_tp->tp_init) && !_PyArg_NoKeywords("Row", kwargs)) { goto exit; } @@ -54,4 +60,4 @@ pysqlite_row_keys(pysqlite_Row *self, PyObject *Py_UNUSED(ignored)) { return pysqlite_row_keys_impl(self); } -/*[clinic end generated code: output=9d54919dbb4ba5f1 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=157b31ac3f6af1ba input=a9049054013a1b77]*/ diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index 20982558..12e5c135 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -30,6 +30,8 @@ #include "prepare_protocol.h" #include "util.h" +#include <stdbool.h> + #if SQLITE_VERSION_NUMBER >= 3014000 #define HAVE_TRACE_V2 #endif @@ -92,6 +94,44 @@ isolation_level_converter(PyObject *str_or_none, const char **result) return 1; } +static int +autocommit_converter(PyObject *val, enum autocommit_mode *result) +{ + if (Py_IsTrue(val)) { + *result = AUTOCOMMIT_ENABLED; + return 1; + } + if (Py_IsFalse(val)) { + *result = AUTOCOMMIT_DISABLED; + return 1; + } + if (PyLong_Check(val) && + PyLong_AsLong(val) == LEGACY_TRANSACTION_CONTROL) + { + *result = AUTOCOMMIT_LEGACY; + return 1; + } + + PyErr_SetString(PyExc_ValueError, + "autocommit must be True, False, or " + "sqlite3.LEGACY_TRANSACTION_CONTROL"); + return 0; +} + +static int +sqlite3_int64_converter(PyObject *obj, sqlite3_int64 *result) +{ + if (!PyLong_Check(obj)) { + PyErr_SetString(PyExc_TypeError, "expected 'int'"); + return 0; + } + *result = _pysqlite_long_as_int64(obj); + if (PyErr_Occurred()) { + return 0; + } + return 1; +} + #define clinic_state() (pysqlite_get_state_by_type(Py_TYPE(self))) #include "clinic/connection.c.h" #undef clinic_state @@ -106,7 +146,7 @@ static void _pysqlite_drop_unused_cursor_references(pysqlite_Connection* self); static void free_callback_context(callback_context *ctx); static void set_callback_context(callback_context **ctx_pp, callback_context *ctx); -static void connection_close(pysqlite_Connection *self); +static int connection_close(pysqlite_Connection *self); PyObject *_pysqlite_query_execute(pysqlite_Cursor *, int, PyObject *, PyObject *); static PyObject * @@ -132,13 +172,42 @@ new_statement_cache(pysqlite_Connection *self, pysqlite_state *state, return res; } +static inline int +connection_exec_stmt(pysqlite_Connection *self, const char *sql) +{ + int rc; + Py_BEGIN_ALLOW_THREADS + int len = (int)strlen(sql) + 1; + sqlite3_stmt *stmt; + rc = sqlite3_prepare_v2(self->db, sql, len, &stmt, NULL); + if (rc == SQLITE_OK) { + (void)sqlite3_step(stmt); + rc = sqlite3_finalize(stmt); + } + Py_END_ALLOW_THREADS + + if (rc != SQLITE_OK) { + (void)_pysqlite_seterror(self->state, self->db); + return -1; + } + return 0; +} + /*[python input] class IsolationLevel_converter(CConverter): type = "const char *" converter = "isolation_level_converter" +class Autocommit_converter(CConverter): + type = "enum autocommit_mode" + converter = "autocommit_converter" + +class sqlite3_int64_converter(CConverter): + type = "sqlite3_int64" + converter = "sqlite3_int64_converter" + [python start generated code]*/ -/*[python end generated code: output=da39a3ee5e6b4b0d input=cbcfe85b253061c2]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=dff8760fb1eba6a1]*/ // NB: This needs to be in sync with the sqlite3.connect docstring /*[clinic input] @@ -148,10 +217,12 @@ _sqlite3.Connection.__init__ as pysqlite_connection_init timeout: double = 5.0 detect_types: int = 0 isolation_level: IsolationLevel = "" - check_same_thread: bool(accept={int}) = True + check_same_thread: bool = True factory: object(c_default='(PyObject*)clinic_state()->ConnectionType') = ConnectionType cached_statements as cache_size: int = 128 uri: bool = False + * + autocommit: Autocommit(c_default='LEGACY_TRANSACTION_CONTROL') = sqlite3.LEGACY_TRANSACTION_CONTROL [clinic start generated code]*/ static int @@ -159,8 +230,9 @@ pysqlite_connection_init_impl(pysqlite_Connection *self, PyObject *database, double timeout, int detect_types, const char *isolation_level, int check_same_thread, PyObject *factory, - int cache_size, int uri) -/*[clinic end generated code: output=839eb2fee4293bda input=b8ce63dc6f70a383]*/ + int cache_size, int uri, + enum autocommit_mode autocommit) +/*[clinic end generated code: output=cba057313ea7712f input=9b0ab6c12f674fa3]*/ { if (PySys_Audit("sqlite3.connect", "O", database) < 0) { return -1; @@ -172,10 +244,13 @@ pysqlite_connection_init_impl(pysqlite_Connection *self, PyObject *database, } if (self->initialized) { + self->initialized = 0; + PyTypeObject *tp = Py_TYPE(self); tp->tp_clear((PyObject *)self); - connection_close(self); - self->initialized = 0; + if (connection_close(self) < 0) { + return -1; + } } // Create and configure SQLite database object. @@ -227,6 +302,7 @@ pysqlite_connection_init_impl(pysqlite_Connection *self, PyObject *database, self->state = state; self->detect_types = detect_types; self->isolation_level = isolation_level; + self->autocommit = autocommit; self->check_same_thread = check_same_thread; self->thread_ident = PyThread_get_thread_ident(); self->statement_cache = statement_cache; @@ -256,6 +332,12 @@ pysqlite_connection_init_impl(pysqlite_Connection *self, PyObject *database, } self->initialized = 1; + + if (autocommit == AUTOCOMMIT_DISABLED) { + if (connection_exec_stmt(self, "BEGIN") < 0) { + return -1; + } + } return 0; error: @@ -322,31 +404,90 @@ free_callback_contexts(pysqlite_Connection *self) } static void -connection_close(pysqlite_Connection *self) +remove_callbacks(sqlite3 *db) { - if (self->db) { - free_callback_contexts(self); + assert(db != NULL); + /* None of these APIs can fail, as long as they are given a valid + * database pointer. */ + int rc; +#ifdef HAVE_TRACE_V2 + rc = sqlite3_trace_v2(db, SQLITE_TRACE_STMT, 0, 0); + assert(rc == SQLITE_OK), (void)rc; +#else + sqlite3_trace(db, 0, (void*)0); +#endif - sqlite3 *db = self->db; - self->db = NULL; + sqlite3_progress_handler(db, 0, 0, (void *)0); - Py_BEGIN_ALLOW_THREADS - int rc = sqlite3_close_v2(db); - assert(rc == SQLITE_OK), (void)rc; - Py_END_ALLOW_THREADS + rc = sqlite3_set_authorizer(db, NULL, NULL); + assert(rc == SQLITE_OK), (void)rc; +} + +static int +connection_close(pysqlite_Connection *self) +{ + if (self->db == NULL) { + return 0; + } + + int rc = 0; + if (self->autocommit == AUTOCOMMIT_DISABLED && + !sqlite3_get_autocommit(self->db)) + { + if (connection_exec_stmt(self, "ROLLBACK") < 0) { + rc = -1; + } } + + sqlite3 *db = self->db; + self->db = NULL; + + Py_BEGIN_ALLOW_THREADS + /* The v2 close call always returns SQLITE_OK if given a valid database + * pointer (which we do), so we can safely ignore the return value */ + (void)sqlite3_close_v2(db); + Py_END_ALLOW_THREADS + + free_callback_contexts(self); + return rc; } static void -connection_dealloc(pysqlite_Connection *self) +connection_finalize(PyObject *self) { - PyTypeObject *tp = Py_TYPE(self); - PyObject_GC_UnTrack(self); - tp->tp_clear((PyObject *)self); + pysqlite_Connection *con = (pysqlite_Connection *)self; + PyObject *exc = PyErr_GetRaisedException(); + + /* If close is implicitly called as a result of interpreter + * tear-down, we must not call back into Python. */ + PyInterpreterState *interp = PyInterpreterState_Get(); + int teardown = _Py_IsInterpreterFinalizing(interp); + if (teardown && con->db) { + remove_callbacks(con->db); + } /* Clean up if user has not called .close() explicitly. */ - connection_close(self); + if (connection_close(con) < 0) { + if (teardown) { + PyErr_Clear(); + } + else { + PyErr_WriteUnraisable((PyObject *)self); + } + } + + PyErr_SetRaisedException(exc); +} +static void +connection_dealloc(PyObject *self) +{ + if (PyObject_CallFinalizerFromDealloc(self) < 0) { + return; + } + PyTypeObject *tp = Py_TYPE(self); + PyObject_GC_UnTrack(self); + tp->tp_clear(self); tp->tp_free(self); Py_DECREF(tp); } @@ -401,11 +542,11 @@ _sqlite3.Connection.blobopen as blobopen Table name. column as col: str Column name. - row: int + row: sqlite3_int64 Row index. / * - readonly: bool(accept={int}) = False + readonly: bool = False Open the BLOB without write permissions. name: str = "main" Database name. @@ -415,8 +556,8 @@ Open and return a BLOB object. static PyObject * blobopen_impl(pysqlite_Connection *self, const char *table, const char *col, - int row, int readonly, const char *name) -/*[clinic end generated code: output=0c8e2e58516d0b5c input=1e7052516acfc94d]*/ + sqlite3_int64 row, int readonly, const char *name) +/*[clinic end generated code: output=6a02d43efb885d1c input=23576bd1108d8774]*/ { if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { return NULL; @@ -494,7 +635,9 @@ pysqlite_connection_close_impl(pysqlite_Connection *self) pysqlite_close_all_blobs(self); Py_CLEAR(self->statement_cache); - connection_close(self); + if (connection_close(self) < 0) { + return NULL; + } Py_RETURN_NONE; } @@ -538,24 +681,21 @@ pysqlite_connection_commit_impl(pysqlite_Connection *self) return NULL; } - if (!sqlite3_get_autocommit(self->db)) { - int rc; - - Py_BEGIN_ALLOW_THREADS - sqlite3_stmt *statement; - rc = sqlite3_prepare_v2(self->db, "COMMIT", 7, &statement, NULL); - if (rc == SQLITE_OK) { - (void)sqlite3_step(statement); - rc = sqlite3_finalize(statement); + if (self->autocommit == AUTOCOMMIT_LEGACY) { + if (!sqlite3_get_autocommit(self->db)) { + if (connection_exec_stmt(self, "COMMIT") < 0) { + return NULL; + } } - Py_END_ALLOW_THREADS - - if (rc != SQLITE_OK) { - (void)_pysqlite_seterror(self->state, self->db); + } + else if (self->autocommit == AUTOCOMMIT_DISABLED) { + if (connection_exec_stmt(self, "COMMIT") < 0) { + return NULL; + } + if (connection_exec_stmt(self, "BEGIN") < 0) { return NULL; } } - Py_RETURN_NONE; } @@ -575,25 +715,21 @@ pysqlite_connection_rollback_impl(pysqlite_Connection *self) return NULL; } - if (!sqlite3_get_autocommit(self->db)) { - int rc; - - Py_BEGIN_ALLOW_THREADS - sqlite3_stmt *statement; - rc = sqlite3_prepare_v2(self->db, "ROLLBACK", 9, &statement, NULL); - if (rc == SQLITE_OK) { - (void)sqlite3_step(statement); - rc = sqlite3_finalize(statement); + if (self->autocommit == AUTOCOMMIT_LEGACY) { + if (!sqlite3_get_autocommit(self->db)) { + if (connection_exec_stmt(self, "ROLLBACK") < 0) { + return NULL; + } } - Py_END_ALLOW_THREADS - - if (rc != SQLITE_OK) { - (void)_pysqlite_seterror(self->state, self->db); + } + else if (self->autocommit == AUTOCOMMIT_DISABLED) { + if (connection_exec_stmt(self, "ROLLBACK") < 0) { + return NULL; + } + if (connection_exec_stmt(self, "BEGIN") < 0) { return NULL; } - } - Py_RETURN_NONE; } @@ -835,7 +971,6 @@ final_callback(sqlite3_context *context) PyObject* function_result; PyObject** aggregate_instance; int ok; - PyObject *exception, *value, *tb; aggregate_instance = (PyObject**)sqlite3_aggregate_context(context, 0); if (aggregate_instance == NULL) { @@ -850,7 +985,7 @@ final_callback(sqlite3_context *context) } // Keep the exception (if any) of the last call to step, value, or inverse - PyErr_Fetch(&exception, &value, &tb); + PyObject *exc = PyErr_GetRaisedException(); callback_context *ctx = (callback_context *)sqlite3_user_data(context); assert(ctx != NULL); @@ -865,7 +1000,7 @@ final_callback(sqlite3_context *context) } if (!ok) { int attr_err = PyErr_ExceptionMatches(PyExc_AttributeError); - _PyErr_ChainExceptions(exception, value, tb); + _PyErr_ChainExceptions1(exc); /* Note: contrary to the step, value, and inverse callbacks, SQLite * does _not_, as of SQLite 3.38.0, propagate errors to sqlite3_step() @@ -876,7 +1011,7 @@ final_callback(sqlite3_context *context) : "user-defined aggregate's 'finalize' method raised error"); } else { - PyErr_Restore(exception, value, tb); + PyErr_SetRaisedException(exc); } error: @@ -1491,7 +1626,7 @@ pysqlite_connection_set_trace_callback_impl(pysqlite_Connection *self, /*[clinic input] _sqlite3.Connection.enable_load_extension as pysqlite_connection_enable_load_extension - enable as onoff: bool(accept={int}) + enable as onoff: bool / Enable dynamic loading of SQLite extension modules. @@ -1500,7 +1635,7 @@ Enable dynamic loading of SQLite extension modules. static PyObject * pysqlite_connection_enable_load_extension_impl(pysqlite_Connection *self, int onoff) -/*[clinic end generated code: output=9cac37190d388baf input=5f00e93f7a9d3540]*/ +/*[clinic end generated code: output=9cac37190d388baf input=2a1e87931486380f]*/ { int rc; @@ -1529,14 +1664,17 @@ _sqlite3.Connection.load_extension as pysqlite_connection_load_extension name as extension_name: str / + * + entrypoint: str(accept={str, NoneType}) = None Load SQLite extension module. [clinic start generated code]*/ static PyObject * pysqlite_connection_load_extension_impl(pysqlite_Connection *self, - const char *extension_name) -/*[clinic end generated code: output=47eb1d7312bc97a7 input=edd507389d89d621]*/ + const char *extension_name, + const char *entrypoint) +/*[clinic end generated code: output=7e61a7add9de0286 input=c36b14ea702e04f5]*/ { int rc; char* errmsg; @@ -1549,7 +1687,7 @@ pysqlite_connection_load_extension_impl(pysqlite_Connection *self, return NULL; } - rc = sqlite3_load_extension(self->db, extension_name, 0, &errmsg); + rc = sqlite3_load_extension(self->db, extension_name, entrypoint, &errmsg); if (rc != 0) { PyErr_SetString(self->OperationalError, errmsg); return NULL; @@ -1589,9 +1727,8 @@ static PyObject* pysqlite_connection_get_total_changes(pysqlite_Connection* self { if (!pysqlite_check_connection(self)) { return NULL; - } else { - return Py_BuildValue("i", sqlite3_total_changes(self->db)); } + return PyLong_FromLong(sqlite3_total_changes(self->db)); } static PyObject* pysqlite_connection_get_in_transaction(pysqlite_Connection* self, void* unused) @@ -1774,10 +1911,12 @@ collation_callback(void *context, int text1_length, const void *text1_data, } string1 = PyUnicode_FromStringAndSize((const char*)text1_data, text1_length); + if (string1 == NULL) { + goto finally; + } string2 = PyUnicode_FromStringAndSize((const char*)text2_data, text2_length); - - if (!string1 || !string2) { - goto finally; /* failed to allocate strings */ + if (string2 == NULL) { + goto finally; } callback_context *ctx = (callback_context *)context; @@ -1848,43 +1987,21 @@ static PyObject * pysqlite_connection_iterdump_impl(pysqlite_Connection *self) /*[clinic end generated code: output=586997aaf9808768 input=1911ca756066da89]*/ { - PyObject* retval = NULL; - PyObject* module = NULL; - PyObject* module_dict; - PyObject* pyfn_iterdump; - if (!pysqlite_check_connection(self)) { - goto finally; - } - - module = PyImport_ImportModule(MODULE_NAME ".dump"); - if (!module) { - goto finally; - } - - module_dict = PyModule_GetDict(module); - if (!module_dict) { - goto finally; + return NULL; } - PyObject *meth = PyUnicode_InternFromString("_iterdump"); - if (meth == NULL) { - goto finally; - } - pyfn_iterdump = PyDict_GetItemWithError(module_dict, meth); - Py_DECREF(meth); - if (!pyfn_iterdump) { + PyObject *iterdump = _PyImport_GetModuleAttrString(MODULE_NAME ".dump", "_iterdump"); + if (!iterdump) { if (!PyErr_Occurred()) { PyErr_SetString(self->OperationalError, "Failed to obtain _iterdump() reference"); } - goto finally; + return NULL; } - retval = PyObject_CallOneArg(pyfn_iterdump, (PyObject *)self); - -finally: - Py_XDECREF(module); + PyObject *retval = PyObject_CallOneArg(iterdump, (PyObject *)self); + Py_DECREF(iterdump); return retval; } @@ -2224,15 +2341,14 @@ pysqlite_connection_exit_impl(pysqlite_Connection *self, PyObject *exc_type, if (commit) { /* Commit failed; try to rollback in order to unlock the database. * If rollback also fails, chain the exceptions. */ - PyObject *exc, *val, *tb; - PyErr_Fetch(&exc, &val, &tb); + PyObject *exc = PyErr_GetRaisedException(); result = pysqlite_connection_rollback_impl(self); if (result == NULL) { - _PyErr_ChainExceptions(exc, val, tb); + _PyErr_ChainExceptions1(exc); } else { Py_DECREF(result); - PyErr_Restore(exc, val, tb); + PyErr_SetRaisedException(exc); } } return NULL; @@ -2292,6 +2408,161 @@ getlimit_impl(pysqlite_Connection *self, int category) return setlimit_impl(self, category, -1); } +static inline bool +is_int_config(const int op) +{ + switch (op) { + case SQLITE_DBCONFIG_ENABLE_FKEY: + case SQLITE_DBCONFIG_ENABLE_TRIGGER: +#if SQLITE_VERSION_NUMBER >= 3012002 + case SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER: +#endif +#if SQLITE_VERSION_NUMBER >= 3013000 + case SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION: +#endif +#if SQLITE_VERSION_NUMBER >= 3016000 + case SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE: +#endif +#if SQLITE_VERSION_NUMBER >= 3020000 + case SQLITE_DBCONFIG_ENABLE_QPSG: +#endif +#if SQLITE_VERSION_NUMBER >= 3022000 + case SQLITE_DBCONFIG_TRIGGER_EQP: +#endif +#if SQLITE_VERSION_NUMBER >= 3024000 + case SQLITE_DBCONFIG_RESET_DATABASE: +#endif +#if SQLITE_VERSION_NUMBER >= 3026000 + case SQLITE_DBCONFIG_DEFENSIVE: +#endif +#if SQLITE_VERSION_NUMBER >= 3028000 + case SQLITE_DBCONFIG_WRITABLE_SCHEMA: +#endif +#if SQLITE_VERSION_NUMBER >= 3029000 + case SQLITE_DBCONFIG_DQS_DDL: + case SQLITE_DBCONFIG_DQS_DML: + case SQLITE_DBCONFIG_LEGACY_ALTER_TABLE: +#endif +#if SQLITE_VERSION_NUMBER >= 3030000 + case SQLITE_DBCONFIG_ENABLE_VIEW: +#endif +#if SQLITE_VERSION_NUMBER >= 3031000 + case SQLITE_DBCONFIG_LEGACY_FILE_FORMAT: + case SQLITE_DBCONFIG_TRUSTED_SCHEMA: +#endif + return true; + default: + return false; + } +} + +/*[clinic input] +_sqlite3.Connection.setconfig as setconfig + + op: int + The configuration verb; one of the sqlite3.SQLITE_DBCONFIG codes. + enable: bool = True + / + +Set a boolean connection configuration option. +[clinic start generated code]*/ + +static PyObject * +setconfig_impl(pysqlite_Connection *self, int op, int enable) +/*[clinic end generated code: output=c60b13e618aff873 input=a10f1539c2d7da6b]*/ +{ + if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { + return NULL; + } + if (!is_int_config(op)) { + return PyErr_Format(PyExc_ValueError, "unknown config 'op': %d", op); + } + + int actual; + int rc = sqlite3_db_config(self->db, op, enable, &actual); + if (rc != SQLITE_OK) { + (void)_pysqlite_seterror(self->state, self->db); + return NULL; + } + if (enable != actual) { + PyErr_SetString(self->state->OperationalError, "Unable to set config"); + return NULL; + } + Py_RETURN_NONE; +} + +/*[clinic input] +_sqlite3.Connection.getconfig as getconfig -> bool + + op: int + The configuration verb; one of the sqlite3.SQLITE_DBCONFIG codes. + / + +Query a boolean connection configuration option. +[clinic start generated code]*/ + +static int +getconfig_impl(pysqlite_Connection *self, int op) +/*[clinic end generated code: output=25ac05044c7b78a3 input=b0526d7e432e3f2f]*/ +{ + if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { + return -1; + } + if (!is_int_config(op)) { + PyErr_Format(PyExc_ValueError, "unknown config 'op': %d", op); + return -1; + } + + int current; + int rc = sqlite3_db_config(self->db, op, -1, ¤t); + if (rc != SQLITE_OK) { + (void)_pysqlite_seterror(self->state, self->db); + return -1; + } + return current; +} + +static PyObject * +get_autocommit(pysqlite_Connection *self, void *Py_UNUSED(ctx)) +{ + if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { + return NULL; + } + if (self->autocommit == AUTOCOMMIT_ENABLED) { + Py_RETURN_TRUE; + } + if (self->autocommit == AUTOCOMMIT_DISABLED) { + Py_RETURN_FALSE; + } + return PyLong_FromLong(LEGACY_TRANSACTION_CONTROL); +} + +static int +set_autocommit(pysqlite_Connection *self, PyObject *val, void *Py_UNUSED(ctx)) +{ + if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { + return -1; + } + if (!autocommit_converter(val, &self->autocommit)) { + return -1; + } + if (self->autocommit == AUTOCOMMIT_ENABLED) { + if (!sqlite3_get_autocommit(self->db)) { + if (connection_exec_stmt(self, "COMMIT") < 0) { + return -1; + } + } + } + else if (self->autocommit == AUTOCOMMIT_DISABLED) { + if (sqlite3_get_autocommit(self->db)) { + if (connection_exec_stmt(self, "BEGIN") < 0) { + return -1; + } + } + } + return 0; +} + static const char connection_doc[] = PyDoc_STR("SQLite database connection object."); @@ -2300,6 +2571,7 @@ static PyGetSetDef connection_getset[] = { {"isolation_level", (getter)pysqlite_connection_get_isolation_level, (setter)pysqlite_connection_set_isolation_level}, {"total_changes", (getter)pysqlite_connection_get_total_changes, (setter)0}, {"in_transaction", (getter)pysqlite_connection_get_in_transaction, (setter)0}, + {"autocommit", (getter)get_autocommit, (setter)set_autocommit}, {NULL} }; @@ -2330,6 +2602,8 @@ static PyMethodDef connection_methods[] = { DESERIALIZE_METHODDEF CREATE_WINDOW_FUNCTION_METHODDEF BLOBOPEN_METHODDEF + SETCONFIG_METHODDEF + GETCONFIG_METHODDEF {NULL, NULL} }; @@ -2351,6 +2625,7 @@ static struct PyMemberDef connection_members[] = }; static PyType_Slot connection_slots[] = { + {Py_tp_finalize, connection_finalize}, {Py_tp_dealloc, connection_dealloc}, {Py_tp_doc, (void *)connection_doc}, {Py_tp_methods, connection_methods}, diff --git a/Modules/_sqlite/connection.h b/Modules/_sqlite/connection.h index 629fe3d3..1df92065 100644 --- a/Modules/_sqlite/connection.h +++ b/Modules/_sqlite/connection.h @@ -39,6 +39,12 @@ typedef struct _callback_context pysqlite_state *state; } callback_context; +enum autocommit_mode { + AUTOCOMMIT_LEGACY = LEGACY_TRANSACTION_CONTROL, + AUTOCOMMIT_ENABLED = 1, + AUTOCOMMIT_DISABLED = 0, +}; + typedef struct { PyObject_HEAD @@ -51,6 +57,7 @@ typedef struct /* NULL for autocommit, otherwise a string with the isolation level */ const char *isolation_level; + enum autocommit_mode autocommit; /* 1 if a check should be performed for each API call if the connection is * used from the same thread it was created in */ diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index 3f5cfef0..caeedbdd 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -130,14 +130,10 @@ stmt_reset(pysqlite_Statement *self) { int rc = SQLITE_OK; - if (self->in_use && self->st) { + if (self->st != NULL) { Py_BEGIN_ALLOW_THREADS rc = sqlite3_reset(self->st); Py_END_ALLOW_THREADS - - if (rc == SQLITE_OK) { - self->in_use = 0; - } } return rc; @@ -666,6 +662,19 @@ bind_parameters(pysqlite_state *state, pysqlite_Statement *self, return; } for (i = 0; i < num_params; i++) { + const char *name = sqlite3_bind_parameter_name(self->st, i+1); + if (name != NULL) { + int ret = PyErr_WarnFormat(PyExc_DeprecationWarning, 1, + "Binding %d ('%s') is a named parameter, but you " + "supplied a sequence which requires nameless (qmark) " + "placeholders. Starting with Python 3.14 an " + "sqlite3.ProgrammingError will be raised.", + i+1, name); + if (ret < 0) { + return; + } + } + if (PyTuple_CheckExact(parameters)) { PyObject *item = PyTuple_GET_ITEM(parameters, i); current_param = Py_NewRef(item); @@ -696,11 +705,10 @@ bind_parameters(pysqlite_state *state, pysqlite_Statement *self, Py_DECREF(adapted); if (rc != SQLITE_OK) { - PyObject *exc, *val, *tb; - PyErr_Fetch(&exc, &val, &tb); + PyObject *exc = PyErr_GetRaisedException(); sqlite3 *db = sqlite3_db_handle(self->st); _pysqlite_seterror(state, db); - _PyErr_ChainExceptions(exc, val, tb); + _PyErr_ChainExceptions1(exc); return; } } @@ -756,11 +764,10 @@ bind_parameters(pysqlite_state *state, pysqlite_Statement *self, Py_DECREF(adapted); if (rc != SQLITE_OK) { - PyObject *exc, *val, *tb; - PyErr_Fetch(&exc, &val, &tb); + PyObject *exc = PyErr_GetRaisedException(); sqlite3 *db = sqlite3_db_handle(self->st); _pysqlite_seterror(state, db); - _PyErr_ChainExceptions(exc, val, tb); + _PyErr_ChainExceptions1(exc); return; } } @@ -770,12 +777,6 @@ bind_parameters(pysqlite_state *state, pysqlite_Statement *self, } } -static inline void -stmt_mark_dirty(pysqlite_Statement *self) -{ - self->in_use = 1; -} - PyObject * _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation, PyObject* second_argument) { @@ -830,16 +831,12 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation } } - if (self->statement != NULL) { - /* There is an active statement */ - stmt_reset(self->statement); - } - /* reset description */ Py_INCREF(Py_None); Py_SETREF(self->description, Py_None); if (self->statement) { + // Reset pending statements on this cursor. (void)stmt_reset(self->statement); } @@ -856,7 +853,7 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation goto error; } - if (self->statement->in_use) { + if (sqlite3_stmt_busy(self->statement->st)) { Py_SETREF(self->statement, pysqlite_statement_create(self->connection, operation)); if (self->statement == NULL) { @@ -864,13 +861,13 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation } } - stmt_reset(self->statement); - stmt_mark_dirty(self->statement); + (void)stmt_reset(self->statement); self->rowcount = self->statement->is_dml ? 0L : -1L; /* We start a transaction implicitly before a DML statement. SELECT is the only exception. See #9924. */ - if (self->connection->isolation_level + if (self->connection->autocommit == AUTOCOMMIT_LEGACY + && self->connection->isolation_level && self->statement->is_dml && sqlite3_get_autocommit(self->connection->db)) { @@ -879,14 +876,13 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation } } + assert(!sqlite3_stmt_busy(self->statement->st)); while (1) { parameters = PyIter_Next(parameters_iter); if (!parameters) { break; } - stmt_mark_dirty(self->statement); - bind_parameters(state, self->statement, parameters); if (PyErr_Occurred()) { goto error; @@ -902,7 +898,6 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation PyErr_Clear(); } } - (void)stmt_reset(self->statement); _pysqlite_seterror(state, self->connection->db); goto error; } @@ -944,16 +939,8 @@ _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* operation } } - if (rc == SQLITE_DONE && !multiple) { + if (rc == SQLITE_DONE) { if (self->statement->is_dml) { - self->rowcount = (long)sqlite3_changes(self->connection->db); - } - stmt_reset(self->statement); - Py_CLEAR(self->statement); - } - - if (multiple) { - if (self->statement->is_dml && rc == SQLITE_DONE) { self->rowcount += (long)sqlite3_changes(self->connection->db); } stmt_reset(self->statement); @@ -980,11 +967,17 @@ error: self->locked = 0; if (PyErr_Occurred()) { + if (self->statement) { + (void)stmt_reset(self->statement); + Py_CLEAR(self->statement); + } self->rowcount = -1L; return NULL; - } else { - return Py_NewRef((PyObject *)self); } + if (self->statement && !sqlite3_stmt_busy(self->statement->st)) { + Py_CLEAR(self->statement); + } + return Py_NewRef((PyObject *)self); } /*[clinic input] @@ -1052,7 +1045,9 @@ pysqlite_cursor_executescript_impl(pysqlite_Cursor *self, // Commit if needed sqlite3 *db = self->connection->db; - if (!sqlite3_get_autocommit(db)) { + if (self->connection->autocommit == AUTOCOMMIT_LEGACY + && !sqlite3_get_autocommit(db)) + { int rc = SQLITE_OK; Py_BEGIN_ALLOW_THREADS @@ -1111,11 +1106,7 @@ pysqlite_cursor_iternext(pysqlite_Cursor *self) sqlite3_stmt *stmt = self->statement->st; assert(stmt != NULL); - if (sqlite3_data_count(stmt) == 0) { - (void)stmt_reset(self->statement); - Py_CLEAR(self->statement); - return NULL; - } + assert(sqlite3_data_count(stmt) != 0); self->locked = 1; // GH-80254: Prevent recursive use of cursors. PyObject *row = _pysqlite_fetch_one_row(self); @@ -1143,8 +1134,7 @@ pysqlite_cursor_iternext(pysqlite_Cursor *self) PyObject *factory = self->row_factory; PyObject *args[] = { (PyObject *)self, row, }; PyObject *new_row = PyObject_Vectorcall(factory, args, 2, NULL); - Py_DECREF(row); - row = new_row; + Py_SETREF(row, new_row); } return row; } diff --git a/Modules/_sqlite/microprotocols.c b/Modules/_sqlite/microprotocols.c index a79f0067..148220d0 100644 --- a/Modules/_sqlite/microprotocols.c +++ b/Modules/_sqlite/microprotocols.c @@ -57,7 +57,7 @@ pysqlite_microprotocols_add(pysqlite_state *state, PyTypeObject *type, assert(type != NULL); assert(proto != NULL); - key = Py_BuildValue("(OO)", (PyObject*)type, proto); + key = PyTuple_Pack(2, (PyObject *)type, proto); if (!key) { return -1; } @@ -81,7 +81,7 @@ pysqlite_microprotocols_adapt(pysqlite_state *state, PyObject *obj, way to get a quotable object to be its instance */ /* look for an adapter in the registry */ - key = Py_BuildValue("(OO)", (PyObject*)Py_TYPE(obj), proto); + key = PyTuple_Pack(2, (PyObject *)Py_TYPE(obj), proto); if (!key) { return NULL; } diff --git a/Modules/_sqlite/module.c b/Modules/_sqlite/module.c index e633a63a..27bd42f4 100644 --- a/Modules/_sqlite/module.c +++ b/Modules/_sqlite/module.c @@ -46,7 +46,8 @@ module _sqlite3 PyDoc_STRVAR(module_connect_doc, "connect($module, /, database, timeout=5.0, detect_types=0,\n" " isolation_level='', check_same_thread=True,\n" -" factory=ConnectionType, cached_statements=128, uri=False)\n" +" factory=ConnectionType, cached_statements=128, uri=False, *,\n" +" autocommit=sqlite3.LEGACY_TRANSACTION_CONTROL)\n" "--\n" "\n" "Opens a connection to the SQLite database file database.\n" @@ -101,36 +102,6 @@ pysqlite_complete_statement_impl(PyObject *module, const char *statement) } } -/*[clinic input] -_sqlite3.enable_shared_cache as pysqlite_enable_shared_cache - - do_enable: int - -Enable or disable shared cache mode for the calling thread. - -This method is deprecated and will be removed in Python 3.12. -Shared cache is strongly discouraged by the SQLite 3 documentation. -If shared cache must be used, open the database in URI mode using -the cache=shared query parameter. -[clinic start generated code]*/ - -static PyObject * -pysqlite_enable_shared_cache_impl(PyObject *module, int do_enable) -/*[clinic end generated code: output=259c74eedee1516b input=26e40d5971d3487d]*/ -{ - int rc; - - rc = sqlite3_enable_shared_cache(do_enable); - - if (rc != SQLITE_OK) { - pysqlite_state *state = pysqlite_get_state(module); - PyErr_SetString(state->OperationalError, "Changing the shared_cache flag failed"); - return NULL; - } else { - Py_RETURN_NONE; - } -} - /*[clinic input] _sqlite3.register_adapter as pysqlite_register_adapter @@ -254,14 +225,8 @@ static int converters_init(PyObject* module) static int load_functools_lru_cache(PyObject *module) { - PyObject *functools = PyImport_ImportModule("functools"); - if (functools == NULL) { - return -1; - } - pysqlite_state *state = pysqlite_get_state(module); - state->lru_cache = PyObject_GetAttrString(functools, "lru_cache"); - Py_DECREF(functools); + state->lru_cache = _PyImport_GetModuleAttrString("functools", "lru_cache"); if (state->lru_cache == NULL) { return -1; } @@ -273,7 +238,6 @@ static PyMethodDef module_methods[] = { PYSQLITE_COMPLETE_STATEMENT_METHODDEF PYSQLITE_CONNECT_METHODDEF PYSQLITE_ENABLE_CALLBACK_TRACE_METHODDEF - PYSQLITE_ENABLE_SHARED_CACHE_METHODDEF PYSQLITE_REGISTER_ADAPTER_METHODDEF PYSQLITE_REGISTER_CONVERTER_METHODDEF {NULL, NULL} @@ -535,6 +499,49 @@ add_integer_constants(PyObject *module) { #if SQLITE_VERSION_NUMBER >= 3008007 ADD_INT(SQLITE_LIMIT_WORKER_THREADS); #endif + + /* + * Database connection configuration options. + * See https://www.sqlite.org/c3ref/c_dbconfig_defensive.html + */ + ADD_INT(SQLITE_DBCONFIG_ENABLE_FKEY); + ADD_INT(SQLITE_DBCONFIG_ENABLE_TRIGGER); +#if SQLITE_VERSION_NUMBER >= 3012002 + ADD_INT(SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER); +#endif +#if SQLITE_VERSION_NUMBER >= 3013000 + ADD_INT(SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION); +#endif +#if SQLITE_VERSION_NUMBER >= 3016000 + ADD_INT(SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE); +#endif +#if SQLITE_VERSION_NUMBER >= 3020000 + ADD_INT(SQLITE_DBCONFIG_ENABLE_QPSG); +#endif +#if SQLITE_VERSION_NUMBER >= 3022000 + ADD_INT(SQLITE_DBCONFIG_TRIGGER_EQP); +#endif +#if SQLITE_VERSION_NUMBER >= 3024000 + ADD_INT(SQLITE_DBCONFIG_RESET_DATABASE); +#endif +#if SQLITE_VERSION_NUMBER >= 3026000 + ADD_INT(SQLITE_DBCONFIG_DEFENSIVE); +#endif +#if SQLITE_VERSION_NUMBER >= 3028000 + ADD_INT(SQLITE_DBCONFIG_WRITABLE_SCHEMA); +#endif +#if SQLITE_VERSION_NUMBER >= 3029000 + ADD_INT(SQLITE_DBCONFIG_DQS_DDL); + ADD_INT(SQLITE_DBCONFIG_DQS_DML); + ADD_INT(SQLITE_DBCONFIG_LEGACY_ALTER_TABLE); +#endif +#if SQLITE_VERSION_NUMBER >= 3030000 + ADD_INT(SQLITE_DBCONFIG_ENABLE_VIEW); +#endif +#if SQLITE_VERSION_NUMBER >= 3031000 + ADD_INT(SQLITE_DBCONFIG_LEGACY_FILE_FORMAT); + ADD_INT(SQLITE_DBCONFIG_TRUSTED_SCHEMA); +#endif #undef ADD_INT return 0; } @@ -735,7 +742,7 @@ module_exec(PyObject *module) goto error; } - if (PyModule_AddStringConstant(module, "version", PYSQLITE_VERSION) < 0) { + if (PyModule_AddStringConstant(module, "_deprecated_version", PYSQLITE_VERSION) < 0) { goto error; } @@ -743,6 +750,10 @@ module_exec(PyObject *module) goto error; } + if (PyModule_AddIntMacro(module, LEGACY_TRANSACTION_CONTROL) < 0) { + goto error; + } + int threadsafety = get_threadsafety(state); if (threadsafety < 0) { goto error; @@ -774,6 +785,7 @@ error: static struct PyModuleDef_Slot module_slots[] = { {Py_mod_exec, module_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL}, }; diff --git a/Modules/_sqlite/module.h b/Modules/_sqlite/module.h index 7deba22f..daa22091 100644 --- a/Modules/_sqlite/module.h +++ b/Modules/_sqlite/module.h @@ -26,6 +26,8 @@ #define PY_SSIZE_T_CLEAN #include "Python.h" +#define LEGACY_TRANSACTION_CONTROL -1 + #define PYSQLITE_VERSION "2.6.0" #define MODULE_NAME "sqlite3" diff --git a/Modules/_sqlite/statement.c b/Modules/_sqlite/statement.c index aee46074..229bfc3b 100644 --- a/Modules/_sqlite/statement.c +++ b/Modules/_sqlite/statement.c @@ -88,7 +88,6 @@ pysqlite_statement_create(pysqlite_Connection *connection, PyObject *sql) } self->st = stmt; - self->in_use = 0; self->is_dml = is_dml; PyObject_GC_Track(self); diff --git a/Modules/_sqlite/statement.h b/Modules/_sqlite/statement.h index 5e612274..11a6464b 100644 --- a/Modules/_sqlite/statement.h +++ b/Modules/_sqlite/statement.h @@ -33,7 +33,6 @@ typedef struct { PyObject_HEAD sqlite3_stmt* st; - int in_use; int is_dml; } pysqlite_Statement; diff --git a/Modules/_sre/clinic/sre.c.h b/Modules/_sre/clinic/sre.c.h index 048a494f..da641081 100644 --- a/Modules/_sre/clinic/sre.c.h +++ b/Modules/_sre/clinic/sre.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_sre_getcodesize__doc__, "getcodesize($module, /)\n" "--\n" @@ -175,8 +181,31 @@ static PyObject * _sre_SRE_Pattern_match(PatternObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(pos), &_Py_ID(endpos), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"string", "pos", "endpos", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "match", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "match", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *string; @@ -245,8 +274,31 @@ static PyObject * _sre_SRE_Pattern_fullmatch(PatternObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(pos), &_Py_ID(endpos), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"string", "pos", "endpos", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "fullmatch", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "fullmatch", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *string; @@ -317,8 +369,31 @@ static PyObject * _sre_SRE_Pattern_search(PatternObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(pos), &_Py_ID(endpos), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"string", "pos", "endpos", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "search", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "search", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *string; @@ -386,8 +461,31 @@ static PyObject * _sre_SRE_Pattern_findall(PatternObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(pos), &_Py_ID(endpos), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"string", "pos", "endpos", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "findall", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "findall", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *string; @@ -458,8 +556,31 @@ static PyObject * _sre_SRE_Pattern_finditer(PatternObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(pos), &_Py_ID(endpos), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"string", "pos", "endpos", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "finditer", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "finditer", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *string; @@ -527,8 +648,31 @@ static PyObject * _sre_SRE_Pattern_scanner(PatternObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(pos), &_Py_ID(endpos), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"string", "pos", "endpos", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "scanner", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "scanner", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *string; @@ -596,8 +740,31 @@ static PyObject * _sre_SRE_Pattern_split(PatternObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(maxsplit), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"string", "maxsplit", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "split", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "split", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *string; @@ -647,8 +814,31 @@ static PyObject * _sre_SRE_Pattern_sub(PatternObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(repl), &_Py_ID(string), &_Py_ID(count), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"repl", "string", "count", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "sub", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "sub", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; PyObject *repl; @@ -701,8 +891,31 @@ static PyObject * _sre_SRE_Pattern_subn(PatternObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(repl), &_Py_ID(string), &_Py_ID(count), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"repl", "string", "count", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "subn", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "subn", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; PyObject *repl; @@ -780,8 +993,31 @@ static PyObject * _sre_compile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 6 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(pattern), &_Py_ID(flags), &_Py_ID(code), &_Py_ID(groups), &_Py_ID(groupindex), &_Py_ID(indexgroup), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"pattern", "flags", "code", "groups", "groupindex", "indexgroup", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "compile", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "compile", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[6]; PyObject *pattern; int flags; @@ -832,6 +1068,45 @@ exit: return return_value; } +PyDoc_STRVAR(_sre_template__doc__, +"template($module, pattern, template, /)\n" +"--\n" +"\n" +"\n" +"\n" +" template\n" +" A list containing interleaved literal strings (str or bytes) and group\n" +" indices (int), as returned by re._parser.parse_template():\n" +" [literal1, group1, ..., literalN, groupN]"); + +#define _SRE_TEMPLATE_METHODDEF \ + {"template", _PyCFunction_CAST(_sre_template), METH_FASTCALL, _sre_template__doc__}, + +static PyObject * +_sre_template_impl(PyObject *module, PyObject *pattern, PyObject *template); + +static PyObject * +_sre_template(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *pattern; + PyObject *template; + + if (!_PyArg_CheckPositional("template", nargs, 2, 2)) { + goto exit; + } + pattern = args[0]; + if (!PyList_Check(args[1])) { + _PyArg_BadArgument("template", "argument 2", "list", args[1]); + goto exit; + } + template = args[1]; + return_value = _sre_template_impl(module, pattern, template); + +exit: + return return_value; +} + PyDoc_STRVAR(_sre_SRE_Match_expand__doc__, "expand($self, /, template)\n" "--\n" @@ -848,8 +1123,31 @@ static PyObject * _sre_SRE_Match_expand(MatchObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(template), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"template", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "expand", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "expand", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *template; @@ -883,8 +1181,31 @@ static PyObject * _sre_SRE_Match_groups(MatchObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(default), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"default", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "groups", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "groups", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *default_value = Py_None; @@ -923,8 +1244,31 @@ static PyObject * _sre_SRE_Match_groupdict(MatchObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(default), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"default", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "groupdict", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "groupdict", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *default_value = Py_None; @@ -1116,4 +1460,4 @@ _sre_SRE_Scanner_search(ScannerObject *self, PyTypeObject *cls, PyObject *const } return _sre_SRE_Scanner_search_impl(self, cls); } -/*[clinic end generated code: output=fd2f45c941620e6e input=a9049054013a1b77]*/ +/*[clinic end generated code: output=e3ba72156dd71572 input=a9049054013a1b77]*/ diff --git a/Modules/_sre/sre.c b/Modules/_sre/sre.c index 448e761c..2f1c7324 100644 --- a/Modules/_sre/sre.c +++ b/Modules/_sre/sre.c @@ -51,13 +51,6 @@ static const char copyright[] = #include <ctype.h> -/* name of this module, minus the leading underscore */ -#if !defined(SRE_MODULE) -#define SRE_MODULE "sre" -#endif - -#define SRE_PY_MODULE "re" - /* defining this one enables tracing */ #undef VERBOSE @@ -254,6 +247,8 @@ typedef struct { PyTypeObject *Pattern_Type; PyTypeObject *Match_Type; PyTypeObject *Scanner_Type; + PyTypeObject *Template_Type; + PyObject *compile_template; // reference to re._compile_template } _sremodulestate; static _sremodulestate * @@ -464,8 +459,7 @@ state_init(SRE_STATE* state, PatternObject* pattern, PyObject* string, state->start = (void*) ((char*) ptr + start * state->charsize); state->end = (void*) ((char*) ptr + end * state->charsize); - Py_INCREF(string); - state->string = string; + state->string = Py_NewRef(string); state->pos = start; state->endpos = end; @@ -504,8 +498,7 @@ getslice(int isbytes, const void *ptr, if (isbytes) { if (PyBytes_CheckExact(string) && start == 0 && end == PyBytes_GET_SIZE(string)) { - Py_INCREF(string); - return string; + return Py_NewRef(string); } return PyBytes_FromStringAndSize( (const char *)ptr + start, end - start); @@ -757,33 +750,6 @@ _sre_SRE_Pattern_search_impl(PatternObject *self, PyTypeObject *cls, return match; } -static PyObject* -call(const char* module, const char* function, PyObject* args) -{ - PyObject* name; - PyObject* mod; - PyObject* func; - PyObject* result; - - if (!args) - return NULL; - name = PyUnicode_FromString(module); - if (!name) - return NULL; - mod = PyImport_Import(name); - Py_DECREF(name); - if (!mod) - return NULL; - func = PyObject_GetAttrString(mod, function); - Py_DECREF(mod); - if (!func) - return NULL; - result = PyObject_CallObject(func, args); - Py_DECREF(func); - Py_DECREF(args); - return result; -} - /*[clinic input] _sre.SRE_Pattern.findall @@ -1046,6 +1012,57 @@ error: } +static PyObject * +compile_template(_sremodulestate *module_state, + PatternObject *pattern, PyObject *template) +{ + /* delegate to Python code */ + PyObject *func = module_state->compile_template; + if (func == NULL) { + func = _PyImport_GetModuleAttrString("re", "_compile_template"); + if (func == NULL) { + return NULL; + } + Py_XSETREF(module_state->compile_template, func); + } + + PyObject *args[] = {(PyObject *)pattern, template}; + PyObject *result = PyObject_Vectorcall(func, args, 2, NULL); + + if (result == NULL && PyErr_ExceptionMatches(PyExc_TypeError)) { + /* If the replacement string is unhashable (e.g. bytearray), + * convert it to the basic type (str or bytes) and repeat. */ + if (PyUnicode_Check(template) && !PyUnicode_CheckExact(template)) { + PyErr_Clear(); + template = _PyUnicode_Copy(template); + } + else if (PyObject_CheckBuffer(template) && !PyBytes_CheckExact(template)) { + PyErr_Clear(); + template = PyBytes_FromObject(template); + } + else { + return NULL; + } + if (template == NULL) { + return NULL; + } + args[1] = template; + result = PyObject_Vectorcall(func, args, 2, NULL); + Py_DECREF(template); + } + + if (result != NULL && Py_TYPE(result) != module_state->Template_Type) { + PyErr_Format(PyExc_RuntimeError, + "the result of compiling a replacement string is %.200s", + Py_TYPE(result)->tp_name); + Py_DECREF(result); + return NULL; + } + return result; +} + +static PyObject *expand_template(TemplateObject *, MatchObject *); /* Forward */ + static PyObject* pattern_subx(_sremodulestate* module_state, PatternObject* self, @@ -1065,14 +1082,13 @@ pattern_subx(_sremodulestate* module_state, Py_ssize_t n; Py_ssize_t i, b, e; int isbytes, charsize; - int filter_is_callable; + enum {LITERAL, TEMPLATE, CALLABLE} filter_type; Py_buffer view; if (PyCallable_Check(ptemplate)) { /* sub/subn takes either a function or a template */ - filter = ptemplate; - Py_INCREF(filter); - filter_is_callable = 1; + filter = Py_NewRef(ptemplate); + filter_type = CALLABLE; } else { /* if not callable, check if it's a literal string */ int literal; @@ -1090,18 +1106,23 @@ pattern_subx(_sremodulestate* module_state, if (view.buf) PyBuffer_Release(&view); if (literal) { - filter = ptemplate; - Py_INCREF(filter); - filter_is_callable = 0; + filter = Py_NewRef(ptemplate); + filter_type = LITERAL; } else { /* not a literal; hand it over to the template compiler */ - filter = call( - SRE_PY_MODULE, "_subx", - PyTuple_Pack(2, self, ptemplate) - ); + filter = compile_template(module_state, self, ptemplate); if (!filter) return NULL; - filter_is_callable = PyCallable_Check(filter); + + assert(Py_TYPE(filter) == module_state->Template_Type); + if (Py_SIZE(filter) == 0) { + Py_SETREF(filter, + Py_NewRef(((TemplateObject *)filter)->literal)); + filter_type = LITERAL; + } + else { + filter_type = TEMPLATE; + } } } @@ -1152,19 +1173,25 @@ pattern_subx(_sremodulestate* module_state, } - if (filter_is_callable) { + if (filter_type != LITERAL) { /* pass match object through filter */ match = pattern_new_match(module_state, self, &state, 1); if (!match) goto error; - item = PyObject_CallOneArg(filter, match); + if (filter_type == TEMPLATE) { + item = expand_template((TemplateObject *)filter, + (MatchObject *)match); + } + else { + assert(filter_type == CALLABLE); + item = PyObject_CallOneArg(filter, match); + } Py_DECREF(match); if (!item) goto error; } else { /* filter is literal string */ - item = filter; - Py_INCREF(item); + item = Py_NewRef(filter); } /* add to list */ @@ -1285,8 +1312,7 @@ static PyObject * _sre_SRE_Pattern___copy___impl(PatternObject *self) /*[clinic end generated code: output=85dedc2db1bd8694 input=a730a59d863bc9f5]*/ { - Py_INCREF(self); - return (PyObject *)self; + return Py_NewRef(self); } /*[clinic input] @@ -1301,8 +1327,7 @@ static PyObject * _sre_SRE_Pattern___deepcopy__(PatternObject *self, PyObject *memo) /*[clinic end generated code: output=2ad25679c1f1204a input=a465b1602f997bed]*/ { - Py_INCREF(self); - return (PyObject *)self; + return Py_NewRef(self); } static PyObject * @@ -1468,19 +1493,16 @@ _sre_compile_impl(PyObject *module, PyObject *pattern, int flags, PyBuffer_Release(&view); } - Py_INCREF(pattern); - self->pattern = pattern; + self->pattern = Py_NewRef(pattern); self->flags = flags; self->groups = groups; if (PyDict_GET_SIZE(groupindex) > 0) { - Py_INCREF(groupindex); - self->groupindex = groupindex; + self->groupindex = Py_NewRef(groupindex); if (PyTuple_GET_SIZE(indexgroup) > 0) { - Py_INCREF(indexgroup); - self->indexgroup = indexgroup; + self->indexgroup = Py_NewRef(indexgroup); } } @@ -1492,6 +1514,69 @@ _sre_compile_impl(PyObject *module, PyObject *pattern, int flags, return (PyObject*) self; } +/*[clinic input] +_sre.template + + pattern: object + template: object(subclass_of="&PyList_Type") + A list containing interleaved literal strings (str or bytes) and group + indices (int), as returned by re._parser.parse_template(): + [literal1, group1, ..., literalN, groupN] + / + +[clinic start generated code]*/ + +static PyObject * +_sre_template_impl(PyObject *module, PyObject *pattern, PyObject *template) +/*[clinic end generated code: output=d51290e596ebca86 input=af55380b27f02942]*/ +{ + /* template is a list containing interleaved literal strings (str or bytes) + * and group indices (int), as returned by _parser.parse_template: + * [literal1, group1, literal2, ..., literalN]. + */ + _sremodulestate *module_state = get_sre_module_state(module); + TemplateObject *self = NULL; + Py_ssize_t n = PyList_GET_SIZE(template); + if ((n & 1) == 0 || n < 1) { + goto bad_template; + } + n /= 2; + self = PyObject_GC_NewVar(TemplateObject, module_state->Template_Type, n); + if (!self) + return NULL; + self->chunks = 1 + 2*n; + self->literal = Py_NewRef(PyList_GET_ITEM(template, 0)); + for (Py_ssize_t i = 0; i < n; i++) { + Py_ssize_t index = PyLong_AsSsize_t(PyList_GET_ITEM(template, 2*i+1)); + if (index == -1 && PyErr_Occurred()) { + Py_SET_SIZE(self, i); + Py_DECREF(self); + return NULL; + } + if (index < 0) { + Py_SET_SIZE(self, i); + goto bad_template; + } + self->items[i].index = index; + + PyObject *literal = PyList_GET_ITEM(template, 2*i+2); + // Skip empty literals. + if ((PyUnicode_Check(literal) && !PyUnicode_GET_LENGTH(literal)) || + (PyBytes_Check(literal) && !PyBytes_GET_SIZE(literal))) + { + literal = NULL; + self->chunks--; + } + self->items[i].literal = Py_XNewRef(literal); + } + return (PyObject*) self; + +bad_template: + PyErr_SetString(PyExc_TypeError, "invalid template"); + Py_XDECREF(self); + return NULL; +} + /* -------------------------------------------------------------------- */ /* Code validation */ @@ -2033,8 +2118,7 @@ match_getslice_by_index(MatchObject* self, Py_ssize_t index, PyObject* def) if (self->string == Py_None || self->mark[index] < 0) { /* return default value if the string or group is undefined */ - Py_INCREF(def); - return def; + return Py_NewRef(def); } ptr = getstring(self->string, &length, &isbytes, &charsize, &view); @@ -2108,11 +2192,14 @@ static PyObject * _sre_SRE_Match_expand_impl(MatchObject *self, PyObject *template) /*[clinic end generated code: output=931b58ccc323c3a1 input=4bfdb22c2f8b146a]*/ { - /* delegate to Python code */ - return call( - SRE_PY_MODULE, "_expand", - PyTuple_Pack(3, self->pattern, self, template) - ); + _sremodulestate *module_state = get_sre_module_state_by_class(Py_TYPE(self)); + PyObject *filter = compile_template(module_state, self->pattern, template); + if (filter == NULL) { + return NULL; + } + PyObject *result = expand_template((TemplateObject *)filter, self); + Py_DECREF(filter); + return result; } static PyObject* @@ -2350,8 +2437,7 @@ match_regs(MatchObject* self) PyTuple_SET_ITEM(regs, index, item); } - Py_INCREF(regs); - self->regs = regs; + self->regs = Py_NewRef(regs); return regs; } @@ -2365,8 +2451,7 @@ static PyObject * _sre_SRE_Match___copy___impl(MatchObject *self) /*[clinic end generated code: output=a779c5fc8b5b4eb4 input=3bb4d30b6baddb5b]*/ { - Py_INCREF(self); - return (PyObject *)self; + return Py_NewRef(self); } /*[clinic input] @@ -2381,8 +2466,7 @@ static PyObject * _sre_SRE_Match___deepcopy__(MatchObject *self, PyObject *memo) /*[clinic end generated code: output=ba7cb46d655e4ee2 input=779d12a31c2c325e]*/ { - Py_INCREF(self); - return (PyObject *)self; + return Py_NewRef(self); } PyDoc_STRVAR(match_doc, @@ -2411,8 +2495,7 @@ match_lastgroup_get(MatchObject *self, void *Py_UNUSED(ignored)) { PyObject *result = PyTuple_GET_ITEM(self->pattern->indexgroup, self->lastindex); - Py_INCREF(result); - return result; + return Py_NewRef(result); } Py_RETURN_NONE; } @@ -2421,8 +2504,7 @@ static PyObject * match_regs_get(MatchObject *self, void *Py_UNUSED(ignored)) { if (self->regs) { - Py_INCREF(self->regs); - return self->regs; + return Py_NewRef(self->regs); } else return match_regs(self); } @@ -2466,11 +2548,9 @@ pattern_new_match(_sremodulestate* module_state, if (!match) return NULL; - Py_INCREF(pattern); - match->pattern = pattern; + match->pattern = (PatternObject*)Py_NewRef(pattern); - Py_INCREF(state->string); - match->string = state->string; + match->string = Py_NewRef(state->string); match->regs = NULL; match->groups = pattern->groups+1; @@ -2690,13 +2770,114 @@ pattern_scanner(_sremodulestate *module_state, return NULL; } - Py_INCREF(self); - scanner->pattern = (PyObject*) self; + scanner->pattern = Py_NewRef(self); PyObject_GC_Track(scanner); return (PyObject*) scanner; } +/* -------------------------------------------------------------------- */ +/* template methods */ + +static int +template_traverse(TemplateObject *self, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(self)); + Py_VISIT(self->literal); + for (Py_ssize_t i = 0, n = Py_SIZE(self); i < n; i++) { + Py_VISIT(self->items[i].literal); + } + return 0; +} + +static int +template_clear(TemplateObject *self) +{ + Py_CLEAR(self->literal); + for (Py_ssize_t i = 0, n = Py_SIZE(self); i < n; i++) { + Py_CLEAR(self->items[i].literal); + } + return 0; +} + +static void +template_dealloc(TemplateObject *self) +{ + PyTypeObject *tp = Py_TYPE(self); + + PyObject_GC_UnTrack(self); + (void)template_clear(self); + tp->tp_free(self); + Py_DECREF(tp); +} + +static PyObject * +expand_template(TemplateObject *self, MatchObject *match) +{ + if (Py_SIZE(self) == 0) { + return Py_NewRef(self->literal); + } + + PyObject *result = NULL; + Py_ssize_t count = 0; // the number of non-empty chunks + /* For small number of strings use a buffer allocated on the stack, + * otherwise use a list object. */ + PyObject *buffer[10]; + PyObject **out = buffer; + PyObject *list = NULL; + if (self->chunks > (int)Py_ARRAY_LENGTH(buffer) || + !PyUnicode_Check(self->literal)) + { + list = PyList_New(self->chunks); + if (!list) { + return NULL; + } + out = &PyList_GET_ITEM(list, 0); + } + + out[count++] = Py_NewRef(self->literal); + for (Py_ssize_t i = 0; i < Py_SIZE(self); i++) { + Py_ssize_t index = self->items[i].index; + if (index >= match->groups) { + PyErr_SetString(PyExc_IndexError, "no such group"); + goto cleanup; + } + PyObject *item = match_getslice_by_index(match, index, Py_None); + if (item == NULL) { + goto cleanup; + } + if (item != Py_None) { + out[count++] = Py_NewRef(item); + } + Py_DECREF(item); + + PyObject *literal = self->items[i].literal; + if (literal != NULL) { + out[count++] = Py_NewRef(literal); + } + } + + if (PyUnicode_Check(self->literal)) { + result = _PyUnicode_JoinArray(&_Py_STR(empty), out, count); + } + else { + Py_SET_SIZE(list, count); + result = _PyBytes_Join((PyObject *)&_Py_SINGLETON(bytes_empty), list); + } + +cleanup: + if (list) { + Py_DECREF(list); + } + else { + for (Py_ssize_t i = 0; i < count; i++) { + Py_DECREF(out[i]); + } + } + return result; +} + + static Py_hash_t pattern_hash(PatternObject *self) { @@ -2919,15 +3100,32 @@ static PyType_Slot scanner_slots[] = { }; static PyType_Spec scanner_spec = { - .name = "_" SRE_MODULE ".SRE_Scanner", + .name = "_sre.SRE_Scanner", .basicsize = sizeof(ScannerObject), .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_HAVE_GC), .slots = scanner_slots, }; +static PyType_Slot template_slots[] = { + {Py_tp_dealloc, template_dealloc}, + {Py_tp_traverse, template_traverse}, + {Py_tp_clear, template_clear}, + {0, NULL}, +}; + +static PyType_Spec template_spec = { + .name = "_sre.SRE_Template", + .basicsize = sizeof(TemplateObject), + .itemsize = sizeof(((TemplateObject *)0)->items[0]), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE | + Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_HAVE_GC), + .slots = template_slots, +}; + static PyMethodDef _functions[] = { _SRE_COMPILE_METHODDEF + _SRE_TEMPLATE_METHODDEF _SRE_GETCODESIZE_METHODDEF _SRE_ASCII_ISCASED_METHODDEF _SRE_UNICODE_ISCASED_METHODDEF @@ -2944,6 +3142,8 @@ sre_traverse(PyObject *module, visitproc visit, void *arg) Py_VISIT(state->Pattern_Type); Py_VISIT(state->Match_Type); Py_VISIT(state->Scanner_Type); + Py_VISIT(state->Template_Type); + Py_VISIT(state->compile_template); return 0; } @@ -2956,6 +3156,8 @@ sre_clear(PyObject *module) Py_CLEAR(state->Pattern_Type); Py_CLEAR(state->Match_Type); Py_CLEAR(state->Scanner_Type); + Py_CLEAR(state->Template_Type); + Py_CLEAR(state->compile_template); return 0; } @@ -2996,6 +3198,7 @@ sre_exec(PyObject *m) CREATE_TYPE(m, state->Pattern_Type, &pattern_spec); CREATE_TYPE(m, state->Match_Type, &match_spec); CREATE_TYPE(m, state->Scanner_Type, &scanner_spec); + CREATE_TYPE(m, state->Template_Type, &template_spec); if (PyModule_AddIntConstant(m, "MAGIC", SRE_MAGIC) < 0) { goto error; @@ -3020,12 +3223,13 @@ error: static PyModuleDef_Slot sre_slots[] = { {Py_mod_exec, sre_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL}, }; static struct PyModuleDef sremodule = { .m_base = PyModuleDef_HEAD_INIT, - .m_name = "_" SRE_MODULE, + .m_name = "_sre", .m_size = sizeof(_sremodulestate), .m_methods = _functions, .m_slots = sre_slots, diff --git a/Modules/_sre/sre.h b/Modules/_sre/sre.h index 52ae3e11..d967d9ea 100644 --- a/Modules/_sre/sre.h +++ b/Modules/_sre/sre.h @@ -52,6 +52,17 @@ typedef struct { Py_ssize_t mark[1]; } MatchObject; +typedef struct { + PyObject_VAR_HEAD + Py_ssize_t chunks; /* the number of group references and non-NULL literals + * self->chunks <= 2*Py_SIZE(self) + 1 */ + PyObject *literal; + struct { + Py_ssize_t index; + PyObject *literal; /* NULL if empty */ + } items[0]; +} TemplateObject; + typedef struct SRE_REPEAT_T { Py_ssize_t count; const SRE_CODE* pattern; /* points to REPEAT operator arguments */ diff --git a/Modules/_sre/sre_constants.h b/Modules/_sre/sre_constants.h index c6335147..b5692292 100644 --- a/Modules/_sre/sre_constants.h +++ b/Modules/_sre/sre_constants.h @@ -3,7 +3,7 @@ * * regular expression matching engine * - * Auto-generated by Tools/scripts/generate_sre_constants.py from + * Auto-generated by Tools/build/generate_sre_constants.py from * Lib/re/_constants.py. * * Copyright (c) 1997-2001 by Secret Labs AB. All rights reserved. @@ -11,7 +11,7 @@ * See the sre.c file for information on usage and redistribution. */ -#define SRE_MAGIC 20220615 +#define SRE_MAGIC 20221023 #define SRE_OP_FAILURE 0 #define SRE_OP_SUCCESS 1 #define SRE_OP_ANY 2 diff --git a/Modules/_sre/sre_lib.h b/Modules/_sre/sre_lib.h index fb4c18b6..e8314982 100644 --- a/Modules/_sre/sre_lib.h +++ b/Modules/_sre/sre_lib.h @@ -1334,6 +1334,10 @@ dispatch: MARK_POP(ctx->lastmark); LASTMARK_RESTORE(); + /* Restore the global Input Stream pointer + since it can change after jumps. */ + state->ptr = ptr; + /* We have sufficient matches, so exit loop. */ break; } diff --git a/Modules/_sre/sre_targets.h b/Modules/_sre/sre_targets.h index 25b6edd4..62761a00 100644 --- a/Modules/_sre/sre_targets.h +++ b/Modules/_sre/sre_targets.h @@ -3,7 +3,7 @@ * * regular expression matching engine * - * Auto-generated by Tools/scripts/generate_sre_constants.py from + * Auto-generated by Tools/build/generate_sre_constants.py from * Lib/re/_constants.py. * * Copyright (c) 1997-2001 by Secret Labs AB. All rights reserved. diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 60712021..b602eb04 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -28,6 +28,10 @@ /* Include symbols from _socket module */ #include "socketmodule.h" +#ifdef MS_WINDOWS +# include <wincrypt.h> +#endif + #include "_ssl.h" /* Redefined below for Windows debug builds after important #includes */ @@ -112,7 +116,9 @@ static void _PySSLFixErrno(void) { #endif /* Include generated data (error codes) */ -#if (OPENSSL_VERSION_NUMBER >= 0x30000000L) +#if (OPENSSL_VERSION_NUMBER >= 0x30100000L) +#include "_ssl_data_31.h" +#elif (OPENSSL_VERSION_NUMBER >= 0x30000000L) #include "_ssl_data_300.h" #elif (OPENSSL_VERSION_NUMBER >= 0x10101000L) && !defined(LIBRESSL_VERSION_NUMBER) #include "_ssl_data_111.h" @@ -138,9 +144,6 @@ extern const SSL_METHOD *TLSv1_2_method(void); #define INVALID_SOCKET (-1) #endif -/* OpenSSL 1.1 does not have SSL 2.0 */ -#define OPENSSL_NO_SSL2 - /* Default cipher suites */ #ifndef PY_SSL_DEFAULT_CIPHERS #define PY_SSL_DEFAULT_CIPHERS 1 @@ -317,9 +320,7 @@ typedef struct { * store exception information on the socket. The handshake, read, write, * and shutdown methods check for chained exceptions. */ - PyObject *exc_type; - PyObject *exc_value; - PyObject *exc_tb; + PyObject *exc; } PySSLSocket; typedef struct { @@ -418,8 +419,7 @@ static PyObject * SSLError_str(PyOSErrorObject *self) { if (self->strerror != NULL && PyUnicode_Check(self->strerror)) { - Py_INCREF(self->strerror); - return self->strerror; + return Py_NewRef(self->strerror); } else return PyObject_Str(self->args); @@ -503,8 +503,7 @@ fill_and_set_sslerror(_sslmodulestate *state, if (verify_str != NULL) { verify_obj = PyUnicode_FromString(verify_str); } else { - verify_obj = Py_None; - Py_INCREF(verify_obj); + verify_obj = Py_NewRef(Py_None); } break; } @@ -565,13 +564,11 @@ fail: static int PySSL_ChainExceptions(PySSLSocket *sslsock) { - if (sslsock->exc_type == NULL) + if (sslsock->exc == NULL) return 0; - _PyErr_ChainExceptions(sslsock->exc_type, sslsock->exc_value, sslsock->exc_tb); - sslsock->exc_type = NULL; - sslsock->exc_value = NULL; - sslsock->exc_tb = NULL; + _PyErr_ChainExceptions1(sslsock->exc); + sslsock->exc = NULL; return -1; } @@ -650,6 +647,10 @@ PySSL_SetError(PySSLSocket *sslsock, int ret, const char *filename, int lineno) errstr = "Some I/O error occurred"; } } else { + if (ERR_GET_LIB(e) == ERR_LIB_SSL && + ERR_GET_REASON(e) == SSL_R_CERTIFICATE_VERIFY_FAILED) { + type = state->PySSLCertVerificationErrorObject; + } p = PY_SSL_ERROR_SYSCALL; } break; @@ -665,6 +666,16 @@ PySSL_SetError(PySSLSocket *sslsock, int ret, const char *filename, int lineno) ERR_GET_REASON(e) == SSL_R_CERTIFICATE_VERIFY_FAILED) { type = state->PySSLCertVerificationErrorObject; } +#if defined(SSL_R_UNEXPECTED_EOF_WHILE_READING) + /* OpenSSL 3.0 changed transport EOF from SSL_ERROR_SYSCALL with + * zero return value to SSL_ERROR_SSL with a special error code. */ + if (ERR_GET_LIB(e) == ERR_LIB_SSL && + ERR_GET_REASON(e) == SSL_R_UNEXPECTED_EOF_WHILE_READING) { + p = PY_SSL_ERROR_EOF; + type = state->PySSLEOFErrorObject; + errstr = "EOF occurred in violation of protocol"; + } +#endif break; } default: @@ -803,15 +814,12 @@ newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock, self->ssl = NULL; self->Socket = NULL; - self->ctx = sslctx; - Py_INCREF(sslctx); + self->ctx = (PySSLContext*)Py_NewRef(sslctx); self->shutdown_seen_zero = 0; self->owner = NULL; self->server_hostname = NULL; self->err = err; - self->exc_type = NULL; - self->exc_value = NULL; - self->exc_tb = NULL; + self->exc = NULL; /* Make sure the SSL error state is initialized */ ERR_clear_error(); @@ -1029,8 +1037,7 @@ _asn1obj2py(_sslmodulestate *state, const ASN1_OBJECT *name, int no_name) } } if (!buflen && no_name) { - Py_INCREF(Py_None); - name_obj = Py_None; + name_obj = Py_NewRef(Py_None); } else { name_obj = PyUnicode_FromStringAndSize(namebuf, buflen); @@ -1329,10 +1336,8 @@ _get_peer_alt_names (_sslmodulestate *state, X509 *certificate) { p[0], p[1], p[2], p[3] ); } else if (name->d.ip->length == 16) { - /* PyUnicode_FromFormat() does not support %X */ unsigned char *p = name->d.ip->data; - len = sprintf( - buf, + v = PyUnicode_FromFormat( "%X:%X:%X:%X:%X:%X:%X:%X", p[0] << 8 | p[1], p[2] << 8 | p[3], @@ -1343,7 +1348,6 @@ _get_peer_alt_names (_sslmodulestate *state, X509 *certificate) { p[12] << 8 | p[13], p[14] << 8 | p[15] ); - v = PyUnicode_FromStringAndSize(buf, len); } else { v = PyUnicode_FromString("<invalid>"); } @@ -1879,8 +1883,7 @@ _ssl__SSLSocket_get_unverified_chain_impl(PySSLSocket *self) X509 *peer = SSL_get_peer_certificate(self->ssl); if (peer == NULL) { - peerobj = Py_None; - Py_INCREF(peerobj); + peerobj = Py_NewRef(Py_None); } else { /* consume X509 reference on success */ peerobj = _PySSL_CertificateFromX509(self->ctx->state, peer, 0); @@ -1910,8 +1913,7 @@ cipher_to_tuple(const SSL_CIPHER *cipher) cipher_name = SSL_CIPHER_get_name(cipher); if (cipher_name == NULL) { - Py_INCREF(Py_None); - PyTuple_SET_ITEM(retval, 0, Py_None); + PyTuple_SET_ITEM(retval, 0, Py_NewRef(Py_None)); } else { v = PyUnicode_FromString(cipher_name); if (v == NULL) @@ -1921,8 +1923,7 @@ cipher_to_tuple(const SSL_CIPHER *cipher) cipher_protocol = SSL_CIPHER_get_version(cipher); if (cipher_protocol == NULL) { - Py_INCREF(Py_None); - PyTuple_SET_ITEM(retval, 1, Py_None); + PyTuple_SET_ITEM(retval, 1, Py_NewRef(Py_None)); } else { v = PyUnicode_FromString(cipher_protocol); if (v == NULL) @@ -2000,24 +2001,44 @@ static PyObject * _ssl__SSLSocket_shared_ciphers_impl(PySSLSocket *self) /*[clinic end generated code: output=3d174ead2e42c4fd input=0bfe149da8fe6306]*/ { - STACK_OF(SSL_CIPHER) *ciphers; - int i; + STACK_OF(SSL_CIPHER) *server_ciphers; + STACK_OF(SSL_CIPHER) *client_ciphers; + int i, len; PyObject *res; + const SSL_CIPHER* cipher; + + /* Rather than use SSL_get_shared_ciphers, we use an equivalent algorithm because: - ciphers = SSL_get_ciphers(self->ssl); - if (!ciphers) + 1) It returns a colon separated list of strings, in an undefined + order, that we would have to post process back into tuples. + 2) It will return a truncated string with no indication that it has + done so, if the buffer is too small. + */ + + server_ciphers = SSL_get_ciphers(self->ssl); + if (!server_ciphers) + Py_RETURN_NONE; + client_ciphers = SSL_get_client_ciphers(self->ssl); + if (!client_ciphers) Py_RETURN_NONE; - res = PyList_New(sk_SSL_CIPHER_num(ciphers)); + + res = PyList_New(sk_SSL_CIPHER_num(server_ciphers)); if (!res) return NULL; - for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) { - PyObject *tup = cipher_to_tuple(sk_SSL_CIPHER_value(ciphers, i)); + len = 0; + for (i = 0; i < sk_SSL_CIPHER_num(server_ciphers); i++) { + cipher = sk_SSL_CIPHER_value(server_ciphers, i); + if (sk_SSL_CIPHER_find(client_ciphers, cipher) < 0) + continue; + + PyObject *tup = cipher_to_tuple(cipher); if (!tup) { Py_DECREF(res); return NULL; } - PyList_SET_ITEM(res, i, tup); + PyList_SET_ITEM(res, len++, tup); } + Py_SET_SIZE(res, len); return res; } @@ -2106,16 +2127,14 @@ _ssl__SSLSocket_compression_impl(PySSLSocket *self) } static PySSLContext *PySSL_get_context(PySSLSocket *self, void *closure) { - Py_INCREF(self->ctx); - return self->ctx; + return (PySSLContext*)Py_NewRef(self->ctx); } static int PySSL_set_context(PySSLSocket *self, PyObject *value, void *closure) { if (PyObject_TypeCheck(value, self->ctx->state->PySSLContext_Type)) { - Py_INCREF(value); - Py_SETREF(self->ctx, (PySSLContext *)value); + Py_SETREF(self->ctx, (PySSLContext *)Py_NewRef(value)); SSL_set_SSL_CTX(self->ssl, self->ctx->ctx); /* Set SSL* internal msg_callback to state of new context's state */ SSL_set_msg_callback( @@ -2153,8 +2172,7 @@ PySSL_get_server_hostname(PySSLSocket *self, void *c) { if (self->server_hostname == NULL) Py_RETURN_NONE; - Py_INCREF(self->server_hostname); - return self->server_hostname; + return Py_NewRef(self->server_hostname); } PyDoc_STRVAR(PySSL_get_server_hostname_doc, @@ -2169,8 +2187,7 @@ PySSL_get_owner(PySSLSocket *self, void *c) Py_RETURN_NONE; owner = PyWeakref_GetObject(self->owner); - Py_INCREF(owner); - return owner; + return Py_NewRef(owner); } static int @@ -2189,9 +2206,7 @@ Passed as \"self\" in servername callback."); static int PySSL_traverse(PySSLSocket *self, visitproc visit, void *arg) { - Py_VISIT(self->exc_type); - Py_VISIT(self->exc_value); - Py_VISIT(self->exc_tb); + Py_VISIT(self->exc); Py_VISIT(Py_TYPE(self)); return 0; } @@ -2199,9 +2214,7 @@ PySSL_traverse(PySSLSocket *self, visitproc visit, void *arg) static int PySSL_clear(PySSLSocket *self) { - Py_CLEAR(self->exc_type); - Py_CLEAR(self->exc_value); - Py_CLEAR(self->exc_tb); + Py_CLEAR(self->exc); return 0; } @@ -2546,7 +2559,7 @@ _ssl__SSLSocket_read_impl(PySSLSocket *self, Py_ssize_t len, PySSL_SetError(self, retval, __FILE__, __LINE__); goto error; } - if (self->exc_type != NULL) + if (self->exc != NULL) goto error; done: @@ -2672,7 +2685,7 @@ _ssl__SSLSocket_shutdown_impl(PySSLSocket *self) PySSL_SetError(self, ret, __FILE__, __LINE__); return NULL; } - if (self->exc_type != NULL) + if (self->exc != NULL) goto error; if (sock) /* It's already INCREF'ed */ @@ -2770,7 +2783,7 @@ _ssl_session_dup(SSL_SESSION *session) { /* get length */ slen = i2d_SSL_SESSION(session, NULL); if (slen == 0 || slen > 0xFF00) { - PyErr_SetString(PyExc_ValueError, "i2d() failed."); + PyErr_SetString(PyExc_ValueError, "i2d() failed"); goto error; } if ((senc = PyMem_Malloc(slen)) == NULL) { @@ -2779,12 +2792,13 @@ _ssl_session_dup(SSL_SESSION *session) { } p = senc; if (!i2d_SSL_SESSION(session, &p)) { - PyErr_SetString(PyExc_ValueError, "i2d() failed."); + PyErr_SetString(PyExc_ValueError, "i2d() failed"); goto error; } const_p = senc; newsession = d2i_SSL_SESSION(NULL, &const_p, slen); - if (session == NULL) { + if (newsession == NULL) { + PyErr_SetString(PyExc_ValueError, "d2i() failed"); goto error; } PyMem_Free(senc); @@ -2823,8 +2837,7 @@ PySSL_get_session(PySSLSocket *self, void *closure) { } assert(self->ctx); - pysess->ctx = self->ctx; - Py_INCREF(pysess->ctx); + pysess->ctx = (PySSLContext*)Py_NewRef(self->ctx); pysess->session = session; PyObject_GC_Track(pysess); return (PyObject *)pysess; @@ -2988,7 +3001,7 @@ _ssl__SSLContext_impl(PyTypeObject *type, int proto_version) /*[clinic end generated code: output=2cf0d7a0741b6bd1 input=8d58a805b95fc534]*/ { PySSLContext *self; - long options; + uint64_t options; const SSL_METHOD *method = NULL; SSL_CTX *ctx = NULL; X509_VERIFY_PARAM *params; @@ -3113,10 +3126,6 @@ _ssl__SSLContext_impl(PyTypeObject *type, int proto_version) #endif #ifdef SSL_OP_SINGLE_ECDH_USE options |= SSL_OP_SINGLE_ECDH_USE; -#endif -#ifdef SSL_OP_IGNORE_UNEXPECTED_EOF - /* Make OpenSSL 3.0.0 behave like 1.1.1 */ - options |= SSL_OP_IGNORE_UNEXPECTED_EOF; #endif SSL_CTX_set_options(self->ctx, options); @@ -3590,20 +3599,32 @@ PyDoc_STRVAR(PySSLContext_security_level_doc, "The current security level"); static PyObject * get_options(PySSLContext *self, void *c) { - return PyLong_FromLong(SSL_CTX_get_options(self->ctx)); + uint64_t options = SSL_CTX_get_options(self->ctx); + Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(options)); + return PyLong_FromUnsignedLongLong(options); } static int set_options(PySSLContext *self, PyObject *arg, void *c) { - long new_opts, opts, set, clear; - long opt_no = ( + PyObject *new_opts_obj; + unsigned long long new_opts_arg; + uint64_t new_opts, opts, clear, set; + uint64_t opt_no = ( SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2 | SSL_OP_NO_TLSv1_3 ); - if (!PyArg_Parse(arg, "l", &new_opts)) + if (!PyArg_Parse(arg, "O!", &PyLong_Type, &new_opts_obj)) { + return -1; + } + new_opts_arg = PyLong_AsUnsignedLongLong(new_opts_obj); + if (new_opts_arg == (unsigned long long)-1 && PyErr_Occurred()) { return -1; + } + Py_BUILD_ASSERT(sizeof(new_opts) >= sizeof(new_opts_arg)); + new_opts = (uint64_t)new_opts_arg; + opts = SSL_CTX_get_options(self->ctx); clear = opts & ~new_opts; set = ~opts & new_opts; @@ -3617,8 +3638,9 @@ set_options(PySSLContext *self, PyObject *arg, void *c) if (clear) { SSL_CTX_clear_options(self->ctx, clear); } - if (set) + if (set) { SSL_CTX_set_options(self->ctx, set); + } return 0; } @@ -3867,8 +3889,8 @@ _ssl__SSLContext_load_cert_chain_impl(PySSLContext *self, PyObject *certfile, /* the password callback has already set the error information */ } else if (errno != 0) { - ERR_clear_error(); PyErr_SetFromErrno(PyExc_OSError); + ERR_clear_error(); } else { _setSSLError(get_state_ctx(self), NULL, 0, __FILE__, __LINE__); @@ -3888,8 +3910,8 @@ _ssl__SSLContext_load_cert_chain_impl(PySSLContext *self, PyObject *certfile, /* the password callback has already set the error information */ } else if (errno != 0) { - ERR_clear_error(); PyErr_SetFromErrno(PyExc_OSError); + ERR_clear_error(); } else { _setSSLError(get_state_ctx(self), NULL, 0, __FILE__, __LINE__); @@ -3925,7 +3947,7 @@ _add_ca_certs(PySSLContext *self, const void *data, Py_ssize_t len, { BIO *biobuf = NULL; X509_STORE *store; - int retval = -1, err, loaded = 0; + int retval = -1, err, loaded = 0, was_bio_eof = 0; assert(filetype == SSL_FILETYPE_ASN1 || filetype == SSL_FILETYPE_PEM); @@ -3953,6 +3975,10 @@ _add_ca_certs(PySSLContext *self, const void *data, Py_ssize_t len, int r; if (filetype == SSL_FILETYPE_ASN1) { + if (BIO_eof(biobuf)) { + was_bio_eof = 1; + break; + } cert = d2i_X509_bio(biobuf, NULL); } else { cert = PEM_read_bio_X509(biobuf, NULL, @@ -3988,9 +4014,7 @@ _add_ca_certs(PySSLContext *self, const void *data, Py_ssize_t len, } _setSSLError(get_state_ctx(self), msg, 0, __FILE__, __LINE__); retval = -1; - } else if ((filetype == SSL_FILETYPE_ASN1) && - (ERR_GET_LIB(err) == ERR_LIB_ASN1) && - (ERR_GET_REASON(err) == ASN1_R_HEADER_TOO_LONG)) { + } else if ((filetype == SSL_FILETYPE_ASN1) && was_bio_eof) { /* EOF ASN1 file, not an error */ ERR_clear_error(); retval = 0; @@ -4116,8 +4140,8 @@ _ssl__SSLContext_load_verify_locations_impl(PySSLContext *self, PySSL_END_ALLOW_THREADS if (r != 1) { if (errno != 0) { - ERR_clear_error(); PyErr_SetFromErrno(PyExc_OSError); + ERR_clear_error(); } else { _setSSLError(get_state_ctx(self), NULL, 0, __FILE__, __LINE__); @@ -4164,8 +4188,8 @@ _ssl__SSLContext_load_dh_params(PySSLContext *self, PyObject *filepath) PySSL_END_ALLOW_THREADS if (dh == NULL) { if (errno != 0) { - ERR_clear_error(); PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, filepath); + ERR_clear_error(); } else { _setSSLError(get_state_ctx(self), NULL, 0, __FILE__, __LINE__); @@ -4183,7 +4207,7 @@ _ssl__SSLContext_load_dh_params(PySSLContext *self, PyObject *filepath) /*[clinic input] _ssl._SSLContext._wrap_socket sock: object(subclass_of="get_state_ctx(self)->Sock_Type") - server_side: int + server_side: bool server_hostname as hostname_obj: object = None * owner: object = None @@ -4195,7 +4219,7 @@ static PyObject * _ssl__SSLContext__wrap_socket_impl(PySSLContext *self, PyObject *sock, int server_side, PyObject *hostname_obj, PyObject *owner, PyObject *session) -/*[clinic end generated code: output=f103f238633940b4 input=f5916eadbc6eae81]*/ +/*[clinic end generated code: output=f103f238633940b4 input=700ca8fedff53994]*/ { char *hostname = NULL; PyObject *res; @@ -4220,7 +4244,7 @@ _ssl__SSLContext__wrap_socket_impl(PySSLContext *self, PyObject *sock, _ssl._SSLContext._wrap_bio incoming: object(subclass_of="get_state_ctx(self)->PySSLMemoryBIO_Type", type="PySSLMemoryBIO *") outgoing: object(subclass_of="get_state_ctx(self)->PySSLMemoryBIO_Type", type="PySSLMemoryBIO *") - server_side: int + server_side: bool server_hostname as hostname_obj: object = None * owner: object = None @@ -4233,7 +4257,7 @@ _ssl__SSLContext__wrap_bio_impl(PySSLContext *self, PySSLMemoryBIO *incoming, PySSLMemoryBIO *outgoing, int server_side, PyObject *hostname_obj, PyObject *owner, PyObject *session) -/*[clinic end generated code: output=5c5d6d9b41f99332 input=331edeec9c738382]*/ +/*[clinic end generated code: output=5c5d6d9b41f99332 input=a9205d097fd45a82]*/ { char *hostname = NULL; PyObject *res; @@ -4329,8 +4353,6 @@ _ssl__SSLContext_set_ecdh_curve(PySSLContext *self, PyObject *name) { PyObject *name_bytes; int nid; - EC_KEY *key; - if (!PyUnicode_FSConverter(name, &name_bytes)) return NULL; assert(PyBytes_Check(name_bytes)); @@ -4341,13 +4363,20 @@ _ssl__SSLContext_set_ecdh_curve(PySSLContext *self, PyObject *name) "unknown elliptic curve name %R", name); return NULL; } - key = EC_KEY_new_by_curve_name(nid); +#if OPENSSL_VERSION_MAJOR < 3 + EC_KEY *key = EC_KEY_new_by_curve_name(nid); if (key == NULL) { _setSSLError(get_state_ctx(self), NULL, 0, __FILE__, __LINE__); return NULL; } SSL_CTX_set_tmp_ecdh(self->ctx, key); EC_KEY_free(key); +#else + if (!SSL_CTX_set1_groups(self->ctx, &nid, 1)) { + _setSSLError(get_state_ctx(self), NULL, 0, __FILE__, __LINE__); + return NULL; + } +#endif Py_RETURN_NONE; } @@ -4462,8 +4491,7 @@ get_sni_callback(PySSLContext *self, void *c) if (cb == NULL) { Py_RETURN_NONE; } - Py_INCREF(cb); - return cb; + return Py_NewRef(cb); } static int @@ -4485,8 +4513,7 @@ set_sni_callback(PySSLContext *self, PyObject *arg, void *c) "not a callable object"); return -1; } - Py_INCREF(arg); - self->set_sni_cb = arg; + self->set_sni_cb = Py_NewRef(arg); SSL_CTX_set_tlsext_servername_callback(self->ctx, _servername_callback); SSL_CTX_set_tlsext_servername_arg(self->ctx, self); } @@ -5162,24 +5189,6 @@ _ssl_RAND_bytes_impl(PyObject *module, int n) return PySSL_RAND(module, n, 0); } -/*[clinic input] -_ssl.RAND_pseudo_bytes - n: int - / - -Generate n pseudo-random bytes. - -Return a pair (bytes, is_cryptographic). is_cryptographic is True -if the bytes generated are cryptographically strong. -[clinic start generated code]*/ - -static PyObject * -_ssl_RAND_pseudo_bytes_impl(PyObject *module, int n) -/*[clinic end generated code: output=b1509e937000e52d input=58312bd53f9bbdd0]*/ -{ - PY_SSL_DEPRECATED("ssl.RAND_pseudo_bytes() is deprecated", 1, NULL); - return PySSL_RAND(module, n, 1); -} /*[clinic input] _ssl.RAND_status @@ -5217,7 +5226,7 @@ _ssl_get_default_verify_paths_impl(PyObject *module) #define CONVERT(info, target) { \ const char *tmp = (info); \ target = NULL; \ - if (!tmp) { Py_INCREF(Py_None); target = Py_None; } \ + if (!tmp) { target = Py_NewRef(Py_None); } \ else if ((target = PyUnicode_DecodeFSDefault(tmp)) == NULL) { \ target = PyBytes_FromString(tmp); } \ if (!target) goto error; \ @@ -5332,11 +5341,9 @@ certEncodingType(DWORD encodingType) } switch(encodingType) { case X509_ASN_ENCODING: - Py_INCREF(x509_asn); - return x509_asn; + return Py_NewRef(x509_asn); case PKCS_7_ASN_ENCODING: - Py_INCREF(pkcs_7_asn); - return pkcs_7_asn; + return Py_NewRef(pkcs_7_asn); default: return PyLong_FromLong(encodingType); } @@ -5638,7 +5645,6 @@ static PyMethodDef PySSL_methods[] = { _SSL__TEST_DECODE_CERT_METHODDEF _SSL_RAND_ADD_METHODDEF _SSL_RAND_BYTES_METHODDEF - _SSL_RAND_PSEUDO_BYTES_METHODDEF _SSL_RAND_STATUS_METHODDEF _SSL_GET_DEFAULT_VERIFY_PATHS_METHODDEF _SSL_ENUM_CERTIFICATES_METHODDEF @@ -5739,15 +5745,28 @@ sslmodule_init_socketapi(PyObject *module) if ((sockmod == NULL) || (sockmod->Sock_Type == NULL)) { return -1; } - state->Sock_Type = sockmod->Sock_Type; - Py_INCREF(state->Sock_Type); + state->Sock_Type = (PyTypeObject*)Py_NewRef(sockmod->Sock_Type); return 0; } + static int -sslmodule_init_constants(PyObject *m) +sslmodule_add_option(PyObject *m, const char *name, uint64_t value) { + Py_BUILD_ASSERT(sizeof(unsigned long long) >= sizeof(value)); + PyObject *obj = PyLong_FromUnsignedLongLong(value); + if (obj == NULL) { + return -1; + } + int res = PyModule_AddObjectRef(m, name, obj); + Py_DECREF(obj); + return res; +} + +static int +sslmodule_init_constants(PyObject *m) +{ PyModule_AddStringConstant(m, "_DEFAULT_CIPHERS", PY_SSL_DEFAULT_CIPHER_STRING); @@ -5848,10 +5867,6 @@ sslmodule_init_constants(PyObject *m) #undef ADD_AD_CONSTANT /* protocol versions */ -#ifndef OPENSSL_NO_SSL2 - PyModule_AddIntConstant(m, "PROTOCOL_SSLv2", - PY_SSL_VERSION_SSL2); -#endif #ifndef OPENSSL_NO_SSL3 PyModule_AddIntConstant(m, "PROTOCOL_SSLv3", PY_SSL_VERSION_SSL3); @@ -5871,42 +5886,48 @@ sslmodule_init_constants(PyObject *m) PyModule_AddIntConstant(m, "PROTOCOL_TLSv1_2", PY_SSL_VERSION_TLS1_2); +#define ADD_OPTION(NAME, VALUE) if (sslmodule_add_option(m, NAME, (VALUE)) < 0) return -1 + /* protocol options */ - PyModule_AddIntConstant(m, "OP_ALL", - SSL_OP_ALL & ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS); - PyModule_AddIntConstant(m, "OP_NO_SSLv2", SSL_OP_NO_SSLv2); - PyModule_AddIntConstant(m, "OP_NO_SSLv3", SSL_OP_NO_SSLv3); - PyModule_AddIntConstant(m, "OP_NO_TLSv1", SSL_OP_NO_TLSv1); - PyModule_AddIntConstant(m, "OP_NO_TLSv1_1", SSL_OP_NO_TLSv1_1); - PyModule_AddIntConstant(m, "OP_NO_TLSv1_2", SSL_OP_NO_TLSv1_2); + ADD_OPTION("OP_ALL", SSL_OP_ALL & ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS); + ADD_OPTION("OP_NO_SSLv2", SSL_OP_NO_SSLv2); + ADD_OPTION("OP_NO_SSLv3", SSL_OP_NO_SSLv3); + ADD_OPTION("OP_NO_TLSv1", SSL_OP_NO_TLSv1); + ADD_OPTION("OP_NO_TLSv1_1", SSL_OP_NO_TLSv1_1); + ADD_OPTION("OP_NO_TLSv1_2", SSL_OP_NO_TLSv1_2); #ifdef SSL_OP_NO_TLSv1_3 - PyModule_AddIntConstant(m, "OP_NO_TLSv1_3", SSL_OP_NO_TLSv1_3); + ADD_OPTION("OP_NO_TLSv1_3", SSL_OP_NO_TLSv1_3); #else - PyModule_AddIntConstant(m, "OP_NO_TLSv1_3", 0); + ADD_OPTION("OP_NO_TLSv1_3", 0); #endif - PyModule_AddIntConstant(m, "OP_CIPHER_SERVER_PREFERENCE", + ADD_OPTION("OP_CIPHER_SERVER_PREFERENCE", SSL_OP_CIPHER_SERVER_PREFERENCE); - PyModule_AddIntConstant(m, "OP_SINGLE_DH_USE", SSL_OP_SINGLE_DH_USE); - PyModule_AddIntConstant(m, "OP_NO_TICKET", SSL_OP_NO_TICKET); + ADD_OPTION("OP_SINGLE_DH_USE", SSL_OP_SINGLE_DH_USE); + ADD_OPTION("OP_NO_TICKET", SSL_OP_NO_TICKET); + ADD_OPTION("OP_LEGACY_SERVER_CONNECT", + SSL_OP_LEGACY_SERVER_CONNECT); #ifdef SSL_OP_SINGLE_ECDH_USE - PyModule_AddIntConstant(m, "OP_SINGLE_ECDH_USE", SSL_OP_SINGLE_ECDH_USE); + ADD_OPTION("OP_SINGLE_ECDH_USE", SSL_OP_SINGLE_ECDH_USE); #endif #ifdef SSL_OP_NO_COMPRESSION - PyModule_AddIntConstant(m, "OP_NO_COMPRESSION", + ADD_OPTION("OP_NO_COMPRESSION", SSL_OP_NO_COMPRESSION); #endif #ifdef SSL_OP_ENABLE_MIDDLEBOX_COMPAT - PyModule_AddIntConstant(m, "OP_ENABLE_MIDDLEBOX_COMPAT", + ADD_OPTION("OP_ENABLE_MIDDLEBOX_COMPAT", SSL_OP_ENABLE_MIDDLEBOX_COMPAT); #endif #ifdef SSL_OP_NO_RENEGOTIATION - PyModule_AddIntConstant(m, "OP_NO_RENEGOTIATION", + ADD_OPTION("OP_NO_RENEGOTIATION", SSL_OP_NO_RENEGOTIATION); #endif #ifdef SSL_OP_IGNORE_UNEXPECTED_EOF - PyModule_AddIntConstant(m, "OP_IGNORE_UNEXPECTED_EOF", + ADD_OPTION("OP_IGNORE_UNEXPECTED_EOF", SSL_OP_IGNORE_UNEXPECTED_EOF); #endif +#ifdef SSL_OP_ENABLE_KTLS + ADD_OPTION("OP_ENABLE_KTLS", SSL_OP_ENABLE_KTLS); +#endif #ifdef X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT PyModule_AddIntConstant(m, "HOSTFLAG_ALWAYS_CHECK_SUBJECT", @@ -5951,8 +5972,7 @@ sslmodule_init_constants(PyObject *m) #define addbool(m, key, value) \ do { \ PyObject *bool_obj = (value) ? Py_True : Py_False; \ - Py_INCREF(bool_obj); \ - PyModule_AddObject((m), (key), bool_obj); \ + PyModule_AddObject((m), (key), Py_NewRef(bool_obj)); \ } while (0) addbool(m, "HAS_SNI", 1); @@ -5961,11 +5981,7 @@ sslmodule_init_constants(PyObject *m) addbool(m, "HAS_NPN", 0); addbool(m, "HAS_ALPN", 1); -#if defined(SSL2_VERSION) && !defined(OPENSSL_NO_SSL2) - addbool(m, "HAS_SSLv2", 1); -#else addbool(m, "HAS_SSLv2", 0); -#endif #if defined(SSL3_VERSION) && !defined(OPENSSL_NO_SSL3) addbool(m, "HAS_SSLv3", 1); @@ -6012,26 +6028,27 @@ sslmodule_init_errorcodes(PyObject *module) state->err_codes_to_names = PyDict_New(); if (state->err_codes_to_names == NULL) return -1; - state->err_names_to_codes = PyDict_New(); - if (state->err_names_to_codes == NULL) - return -1; state->lib_codes_to_names = PyDict_New(); if (state->lib_codes_to_names == NULL) return -1; errcode = error_codes; while (errcode->mnemonic != NULL) { - PyObject *mnemo, *key; - mnemo = PyUnicode_FromString(errcode->mnemonic); - key = Py_BuildValue("ii", errcode->library, errcode->reason); - if (mnemo == NULL || key == NULL) + PyObject *mnemo = PyUnicode_FromString(errcode->mnemonic); + if (mnemo == NULL) { return -1; - if (PyDict_SetItem(state->err_codes_to_names, key, mnemo)) - return -1; - if (PyDict_SetItem(state->err_names_to_codes, mnemo, key)) + } + PyObject *key = Py_BuildValue("ii", errcode->library, errcode->reason); + if (key == NULL) { + Py_DECREF(mnemo); return -1; + } + int rc = PyDict_SetItem(state->err_codes_to_names, key, mnemo); Py_DECREF(key); Py_DECREF(mnemo); + if (rc < 0) { + return -1; + } errcode++; } @@ -6049,13 +6066,6 @@ sslmodule_init_errorcodes(PyObject *module) libcode++; } - if (PyModule_AddObjectRef(module, "err_codes_to_names", state->err_codes_to_names)) - return -1; - if (PyModule_AddObjectRef(module, "err_names_to_codes", state->err_names_to_codes)) - return -1; - if (PyModule_AddObjectRef(module, "lib_codes_to_names", state->lib_codes_to_names)) - return -1; - return 0; } @@ -6089,22 +6099,22 @@ sslmodule_init_versioninfo(PyObject *m) */ libver = OpenSSL_version_num(); r = PyLong_FromUnsignedLong(libver); - if (r == NULL || PyModule_AddObject(m, "OPENSSL_VERSION_NUMBER", r)) + if (_PyModule_Add(m, "OPENSSL_VERSION_NUMBER", r) < 0) return -1; parse_openssl_version(libver, &major, &minor, &fix, &patch, &status); r = Py_BuildValue("IIIII", major, minor, fix, patch, status); - if (r == NULL || PyModule_AddObject(m, "OPENSSL_VERSION_INFO", r)) + if (_PyModule_Add(m, "OPENSSL_VERSION_INFO", r) < 0) return -1; r = PyUnicode_FromString(OpenSSL_version(OPENSSL_VERSION)); - if (r == NULL || PyModule_AddObject(m, "OPENSSL_VERSION", r)) + if (_PyModule_Add(m, "OPENSSL_VERSION", r) < 0) return -1; libver = OPENSSL_VERSION_NUMBER; parse_openssl_version(libver, &major, &minor, &fix, &patch, &status); r = Py_BuildValue("IIIII", major, minor, fix, patch, status); - if (r == NULL || PyModule_AddObject(m, "_OPENSSL_API_VERSION", r)) + if (_PyModule_Add(m, "_OPENSSL_API_VERSION", r) < 0) return -1; return 0; @@ -6181,6 +6191,18 @@ sslmodule_init_strings(PyObject *module) return 0; } +static int +sslmodule_init_lock(PyObject *module) +{ + _sslmodulestate *state = get_ssl_state(module); + state->keylog_lock = PyThread_allocate_lock(); + if (state->keylog_lock == NULL) { + PyErr_NoMemory(); + return -1; + } + return 0; +} + static PyModuleDef_Slot sslmodule_slots[] = { {Py_mod_exec, sslmodule_init_types}, {Py_mod_exec, sslmodule_init_exceptions}, @@ -6189,6 +6211,8 @@ static PyModuleDef_Slot sslmodule_slots[] = { {Py_mod_exec, sslmodule_init_constants}, {Py_mod_exec, sslmodule_init_versioninfo}, {Py_mod_exec, sslmodule_init_strings}, + {Py_mod_exec, sslmodule_init_lock}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; @@ -6210,7 +6234,6 @@ sslmodule_traverse(PyObject *m, visitproc visit, void *arg) Py_VISIT(state->PySSLSyscallErrorObject); Py_VISIT(state->PySSLEOFErrorObject); Py_VISIT(state->err_codes_to_names); - Py_VISIT(state->err_names_to_codes); Py_VISIT(state->lib_codes_to_names); Py_VISIT(state->Sock_Type); @@ -6235,7 +6258,6 @@ sslmodule_clear(PyObject *m) Py_CLEAR(state->PySSLSyscallErrorObject); Py_CLEAR(state->PySSLEOFErrorObject); Py_CLEAR(state->err_codes_to_names); - Py_CLEAR(state->err_names_to_codes); Py_CLEAR(state->lib_codes_to_names); Py_CLEAR(state->Sock_Type); Py_CLEAR(state->str_library); @@ -6249,6 +6271,8 @@ static void sslmodule_free(void *m) { sslmodule_clear((PyObject *)m); + _sslmodulestate *state = get_ssl_state(m); + PyThread_free_lock(state->keylog_lock); } static struct PyModuleDef _sslmodule_def = { diff --git a/Modules/_ssl.h b/Modules/_ssl.h index d68ccdec..22d93ddc 100644 --- a/Modules/_ssl.h +++ b/Modules/_ssl.h @@ -25,7 +25,6 @@ typedef struct { PyObject *PySSLEOFErrorObject; /* Error mappings */ PyObject *err_codes_to_names; - PyObject *err_names_to_codes; PyObject *lib_codes_to_names; /* socket type from module CAPI */ PyTypeObject *Sock_Type; @@ -34,6 +33,8 @@ typedef struct { PyObject *str_reason; PyObject *str_verify_code; PyObject *str_verify_message; + /* keylog lock */ + PyThread_type_lock keylog_lock; } _sslmodulestate; static struct PyModuleDef _sslmodule_def; diff --git a/Modules/_ssl/clinic/cert.c.h b/Modules/_ssl/clinic/cert.c.h index 53cedabc..a052ab20 100644 --- a/Modules/_ssl/clinic/cert.c.h +++ b/Modules/_ssl/clinic/cert.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_ssl_Certificate_public_bytes__doc__, "public_bytes($self, /, format=Encoding.PEM)\n" "--\n" @@ -17,8 +23,31 @@ static PyObject * _ssl_Certificate_public_bytes(PySSLCertificate *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(format), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"format", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "public_bytes", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "public_bytes", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int format = PY_SSL_ENCODING_PEM; @@ -57,4 +86,4 @@ _ssl_Certificate_get_info(PySSLCertificate *self, PyObject *Py_UNUSED(ignored)) { return _ssl_Certificate_get_info_impl(self); } -/*[clinic end generated code: output=18885c4d167d5244 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=82efada014f9b7fe input=a9049054013a1b77]*/ diff --git a/Modules/_ssl/debughelpers.c b/Modules/_ssl/debughelpers.c index 03c125eb..a81f0aad 100644 --- a/Modules/_ssl/debughelpers.c +++ b/Modules/_ssl/debughelpers.c @@ -74,7 +74,7 @@ _PySSL_msg_callback(int write_p, int version, int content_type, buf, len ); if (res == NULL) { - PyErr_Fetch(&ssl_obj->exc_type, &ssl_obj->exc_value, &ssl_obj->exc_tb); + ssl_obj->exc = PyErr_GetRaisedException(); } else { Py_DECREF(res); } @@ -87,8 +87,7 @@ _PySSL_msg_callback(int write_p, int version, int content_type, static PyObject * _PySSLContext_get_msg_callback(PySSLContext *self, void *c) { if (self->msg_cb != NULL) { - Py_INCREF(self->msg_cb); - return self->msg_cb; + return Py_NewRef(self->msg_cb); } else { Py_RETURN_NONE; } @@ -107,8 +106,7 @@ _PySSLContext_set_msg_callback(PySSLContext *self, PyObject *arg, void *c) { "not a callable object"); return -1; } - Py_INCREF(arg); - self->msg_cb = arg; + self->msg_cb = Py_NewRef(arg); SSL_CTX_set_msg_callback(self->ctx, _PySSL_msg_callback); } return 0; @@ -120,31 +118,22 @@ _PySSL_keylog_callback(const SSL *ssl, const char *line) PyGILState_STATE threadstate; PySSLSocket *ssl_obj = NULL; /* ssl._SSLSocket, borrowed ref */ int res, e; - static PyThread_type_lock *lock = NULL; threadstate = PyGILState_Ensure(); ssl_obj = (PySSLSocket *)SSL_get_app_data(ssl); assert(Py_IS_TYPE(ssl_obj, get_state_sock(ssl_obj)->PySSLSocket_Type)); + PyThread_type_lock lock = get_state_sock(ssl_obj)->keylog_lock; + assert(lock != NULL); if (ssl_obj->ctx->keylog_bio == NULL) { return; } - - /* Allocate a static lock to synchronize writes to keylog file. + /* * The lock is neither released on exit nor on fork(). The lock is * also shared between all SSLContexts although contexts may write to * their own files. IMHO that's good enough for a non-performance * critical debug helper. */ - if (lock == NULL) { - lock = PyThread_allocate_lock(); - if (lock == NULL) { - PyErr_SetString(PyExc_MemoryError, "Unable to allocate lock"); - PyErr_Fetch(&ssl_obj->exc_type, &ssl_obj->exc_value, - &ssl_obj->exc_tb); - return; - } - } PySSL_BEGIN_ALLOW_THREADS PyThread_acquire_lock(lock, 1); @@ -158,7 +147,7 @@ _PySSL_keylog_callback(const SSL *ssl, const char *line) errno = e; PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, ssl_obj->ctx->keylog_filename); - PyErr_Fetch(&ssl_obj->exc_type, &ssl_obj->exc_value, &ssl_obj->exc_tb); + ssl_obj->exc = PyErr_GetRaisedException(); } PyGILState_Release(threadstate); } @@ -166,8 +155,7 @@ _PySSL_keylog_callback(const SSL *ssl, const char *line) static PyObject * _PySSLContext_get_keylog_filename(PySSLContext *self, void *c) { if (self->keylog_filename != NULL) { - Py_INCREF(self->keylog_filename); - return self->keylog_filename; + return Py_NewRef(self->keylog_filename); } else { Py_RETURN_NONE; } @@ -203,8 +191,7 @@ _PySSLContext_set_keylog_filename(PySSLContext *self, PyObject *arg, void *c) { "Can't malloc memory for keylog file"); return -1; } - Py_INCREF(arg); - self->keylog_filename = arg; + self->keylog_filename = Py_NewRef(arg); /* Write a header for seekable, empty files (this excludes pipes). */ PySSL_BEGIN_ALLOW_THREADS diff --git a/Modules/_ssl_data_111.h b/Modules/_ssl_data_111.h index 85a2f7ec..093c786e 100644 --- a/Modules/_ssl_data_111.h +++ b/Modules/_ssl_data_111.h @@ -1,4 +1,4 @@ -/* File generated by Tools/ssl/make_ssl_data.py *//* Generated on 2021-04-09T09:36:21.493286 */ +/* File generated by Tools/ssl/make_ssl_data.py *//* Generated on 2023-06-01T02:58:04.081473 */ static struct py_ssl_library_code library_codes[] = { #ifdef ERR_LIB_ASN1 {"ASN1", ERR_LIB_ASN1}, @@ -1375,6 +1375,11 @@ static struct py_ssl_error_code error_codes[] = { #else {"UNSUPPORTED_COMPRESSION_ALGORITHM", 46, 151}, #endif + #ifdef CMS_R_UNSUPPORTED_CONTENT_ENCRYPTION_ALGORITHM + {"UNSUPPORTED_CONTENT_ENCRYPTION_ALGORITHM", ERR_LIB_CMS, CMS_R_UNSUPPORTED_CONTENT_ENCRYPTION_ALGORITHM}, + #else + {"UNSUPPORTED_CONTENT_ENCRYPTION_ALGORITHM", 46, 194}, + #endif #ifdef CMS_R_UNSUPPORTED_CONTENT_TYPE {"UNSUPPORTED_CONTENT_TYPE", ERR_LIB_CMS, CMS_R_UNSUPPORTED_CONTENT_TYPE}, #else @@ -4860,6 +4865,11 @@ static struct py_ssl_error_code error_codes[] = { #else {"MISSING_PARAMETERS", 20, 290}, #endif + #ifdef SSL_R_MISSING_PSK_KEX_MODES_EXTENSION + {"MISSING_PSK_KEX_MODES_EXTENSION", ERR_LIB_SSL, SSL_R_MISSING_PSK_KEX_MODES_EXTENSION}, + #else + {"MISSING_PSK_KEX_MODES_EXTENSION", 20, 310}, + #endif #ifdef SSL_R_MISSING_RSA_CERTIFICATE {"MISSING_RSA_CERTIFICATE", ERR_LIB_SSL, SSL_R_MISSING_RSA_CERTIFICATE}, #else @@ -5065,6 +5075,11 @@ static struct py_ssl_error_code error_codes[] = { #else {"NULL_SSL_METHOD_PASSED", 20, 196}, #endif + #ifdef SSL_R_OCSP_CALLBACK_FAILURE + {"OCSP_CALLBACK_FAILURE", ERR_LIB_SSL, SSL_R_OCSP_CALLBACK_FAILURE}, + #else + {"OCSP_CALLBACK_FAILURE", 20, 294}, + #endif #ifdef SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED {"OLD_SESSION_CIPHER_NOT_RETURNED", ERR_LIB_SSL, SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED}, #else diff --git a/Modules/_ssl_data_300.h b/Modules/_ssl_data_300.h index 6be8b24e..dc66731f 100644 --- a/Modules/_ssl_data_300.h +++ b/Modules/_ssl_data_300.h @@ -1,4 +1,4 @@ -/* File generated by Tools/ssl/make_ssl_data.py *//* Generated on 2021-04-09T09:44:43.288448 */ +/* File generated by Tools/ssl/make_ssl_data.py *//* Generated on 2023-06-01T03:03:52.163218 */ static struct py_ssl_library_code library_codes[] = { #ifdef ERR_LIB_ASN1 {"ASN1", ERR_LIB_ASN1}, @@ -1035,6 +1035,11 @@ static struct py_ssl_error_code error_codes[] = { #else {"NO_INVERSE", 3, 108}, #endif + #ifdef BN_R_NO_PRIME_CANDIDATE + {"NO_PRIME_CANDIDATE", ERR_LIB_BN, BN_R_NO_PRIME_CANDIDATE}, + #else + {"NO_PRIME_CANDIDATE", 3, 121}, + #endif #ifdef BN_R_NO_SOLUTION {"NO_SOLUTION", ERR_LIB_BN, BN_R_NO_SOLUTION}, #else @@ -1255,6 +1260,11 @@ static struct py_ssl_error_code error_codes[] = { #else {"INVALID_OPTION", 58, 174}, #endif + #ifdef CMP_R_MISSING_CERTID + {"MISSING_CERTID", ERR_LIB_CMP, CMP_R_MISSING_CERTID}, + #else + {"MISSING_CERTID", 58, 165}, + #endif #ifdef CMP_R_MISSING_KEY_INPUT_FOR_CREATING_PROTECTION {"MISSING_KEY_INPUT_FOR_CREATING_PROTECTION", ERR_LIB_CMP, CMP_R_MISSING_KEY_INPUT_FOR_CREATING_PROTECTION}, #else @@ -1280,21 +1290,41 @@ static struct py_ssl_error_code error_codes[] = { #else {"MISSING_PRIVATE_KEY", 58, 131}, #endif + #ifdef CMP_R_MISSING_PRIVATE_KEY_FOR_POPO + {"MISSING_PRIVATE_KEY_FOR_POPO", ERR_LIB_CMP, CMP_R_MISSING_PRIVATE_KEY_FOR_POPO}, + #else + {"MISSING_PRIVATE_KEY_FOR_POPO", 58, 190}, + #endif #ifdef CMP_R_MISSING_PROTECTION {"MISSING_PROTECTION", ERR_LIB_CMP, CMP_R_MISSING_PROTECTION}, #else {"MISSING_PROTECTION", 58, 143}, #endif + #ifdef CMP_R_MISSING_PUBLIC_KEY + {"MISSING_PUBLIC_KEY", ERR_LIB_CMP, CMP_R_MISSING_PUBLIC_KEY}, + #else + {"MISSING_PUBLIC_KEY", 58, 183}, + #endif #ifdef CMP_R_MISSING_REFERENCE_CERT {"MISSING_REFERENCE_CERT", ERR_LIB_CMP, CMP_R_MISSING_REFERENCE_CERT}, #else {"MISSING_REFERENCE_CERT", 58, 168}, #endif + #ifdef CMP_R_MISSING_SECRET + {"MISSING_SECRET", ERR_LIB_CMP, CMP_R_MISSING_SECRET}, + #else + {"MISSING_SECRET", 58, 178}, + #endif #ifdef CMP_R_MISSING_SENDER_IDENTIFICATION {"MISSING_SENDER_IDENTIFICATION", ERR_LIB_CMP, CMP_R_MISSING_SENDER_IDENTIFICATION}, #else {"MISSING_SENDER_IDENTIFICATION", 58, 111}, #endif + #ifdef CMP_R_MISSING_TRUST_ANCHOR + {"MISSING_TRUST_ANCHOR", ERR_LIB_CMP, CMP_R_MISSING_TRUST_ANCHOR}, + #else + {"MISSING_TRUST_ANCHOR", 58, 179}, + #endif #ifdef CMP_R_MISSING_TRUST_STORE {"MISSING_TRUST_STORE", ERR_LIB_CMP, CMP_R_MISSING_TRUST_STORE}, #else @@ -1455,6 +1485,11 @@ static struct py_ssl_error_code error_codes[] = { #else {"WRONG_ALGORITHM_OID", 58, 138}, #endif + #ifdef CMP_R_WRONG_CERTID + {"WRONG_CERTID", ERR_LIB_CMP, CMP_R_WRONG_CERTID}, + #else + {"WRONG_CERTID", 58, 189}, + #endif #ifdef CMP_R_WRONG_CERTID_IN_RP {"WRONG_CERTID_IN_RP", ERR_LIB_CMP, CMP_R_WRONG_CERTID_IN_RP}, #else @@ -1885,6 +1920,11 @@ static struct py_ssl_error_code error_codes[] = { #else {"UNSUPPORTED_COMPRESSION_ALGORITHM", 46, 151}, #endif + #ifdef CMS_R_UNSUPPORTED_CONTENT_ENCRYPTION_ALGORITHM + {"UNSUPPORTED_CONTENT_ENCRYPTION_ALGORITHM", ERR_LIB_CMS, CMS_R_UNSUPPORTED_CONTENT_ENCRYPTION_ALGORITHM}, + #else + {"UNSUPPORTED_CONTENT_ENCRYPTION_ALGORITHM", 46, 194}, + #endif #ifdef CMS_R_UNSUPPORTED_CONTENT_TYPE {"UNSUPPORTED_CONTENT_TYPE", ERR_LIB_CMS, CMS_R_UNSUPPORTED_CONTENT_TYPE}, #else @@ -2045,6 +2085,11 @@ static struct py_ssl_error_code error_codes[] = { #else {"RECURSIVE_DIRECTORY_INCLUDE", 14, 111}, #endif + #ifdef CONF_R_RELATIVE_PATH + {"RELATIVE_PATH", ERR_LIB_CONF, CONF_R_RELATIVE_PATH}, + #else + {"RELATIVE_PATH", 14, 125}, + #endif #ifdef CONF_R_SSL_COMMAND_SECTION_EMPTY {"SSL_COMMAND_SECTION_EMPTY", ERR_LIB_CONF, CONF_R_SSL_COMMAND_SECTION_EMPTY}, #else @@ -2235,6 +2280,11 @@ static struct py_ssl_error_code error_codes[] = { #else {"INSUFFICIENT_SECURE_DATA_SPACE", 15, 108}, #endif + #ifdef CRYPTO_R_INVALID_NEGATIVE_VALUE + {"INVALID_NEGATIVE_VALUE", ERR_LIB_CRYPTO, CRYPTO_R_INVALID_NEGATIVE_VALUE}, + #else + {"INVALID_NEGATIVE_VALUE", 15, 122}, + #endif #ifdef CRYPTO_R_INVALID_NULL_ARGUMENT {"INVALID_NULL_ARGUMENT", ERR_LIB_CRYPTO, CRYPTO_R_INVALID_NULL_ARGUMENT}, #else @@ -2605,6 +2655,11 @@ static struct py_ssl_error_code error_codes[] = { #else {"SEED_LEN_SMALL", 10, 110}, #endif + #ifdef DSA_R_TOO_MANY_RETRIES + {"TOO_MANY_RETRIES", ERR_LIB_DSA, DSA_R_TOO_MANY_RETRIES}, + #else + {"TOO_MANY_RETRIES", 10, 116}, + #endif #ifdef DSO_R_CTRL_FAILED {"CTRL_FAILED", ERR_LIB_DSO, DSO_R_CTRL_FAILED}, #else @@ -2745,6 +2800,11 @@ static struct py_ssl_error_code error_codes[] = { #else {"EC_GROUP_NEW_BY_NAME_FAILURE", 16, 119}, #endif + #ifdef EC_R_EXPLICIT_PARAMS_NOT_SUPPORTED + {"EXPLICIT_PARAMS_NOT_SUPPORTED", ERR_LIB_EC, EC_R_EXPLICIT_PARAMS_NOT_SUPPORTED}, + #else + {"EXPLICIT_PARAMS_NOT_SUPPORTED", 16, 127}, + #endif #ifdef EC_R_FAILED_MAKING_PUBLIC_KEY {"FAILED_MAKING_PUBLIC_KEY", ERR_LIB_EC, EC_R_FAILED_MAKING_PUBLIC_KEY}, #else @@ -2850,6 +2910,11 @@ static struct py_ssl_error_code error_codes[] = { #else {"INVALID_KEY", 16, 116}, #endif + #ifdef EC_R_INVALID_LENGTH + {"INVALID_LENGTH", ERR_LIB_EC, EC_R_INVALID_LENGTH}, + #else + {"INVALID_LENGTH", 16, 117}, + #endif #ifdef EC_R_INVALID_NAMED_GROUP_CONVERSION {"INVALID_NAMED_GROUP_CONVERSION", ERR_LIB_EC, EC_R_INVALID_NAMED_GROUP_CONVERSION}, #else @@ -3010,6 +3075,11 @@ static struct py_ssl_error_code error_codes[] = { #else {"SLOT_FULL", 16, 108}, #endif + #ifdef EC_R_TOO_MANY_RETRIES + {"TOO_MANY_RETRIES", ERR_LIB_EC, EC_R_TOO_MANY_RETRIES}, + #else + {"TOO_MANY_RETRIES", 16, 176}, + #endif #ifdef EC_R_UNDEFINED_GENERATOR {"UNDEFINED_GENERATOR", ERR_LIB_EC, EC_R_UNDEFINED_GENERATOR}, #else @@ -3690,6 +3760,11 @@ static struct py_ssl_error_code error_codes[] = { #else {"PUBLIC_KEY_NOT_RSA", 6, 106}, #endif + #ifdef EVP_R_SETTING_XOF_FAILED + {"SETTING_XOF_FAILED", ERR_LIB_EVP, EVP_R_SETTING_XOF_FAILED}, + #else + {"SETTING_XOF_FAILED", 6, 227}, + #endif #ifdef EVP_R_SET_DEFAULT_PROPERTY_FAILURE {"SET_DEFAULT_PROPERTY_FAILURE", ERR_LIB_EVP, EVP_R_SET_DEFAULT_PROPERTY_FAILURE}, #else @@ -3865,6 +3940,11 @@ static struct py_ssl_error_code error_codes[] = { #else {"FAILED_READING_DATA", 61, 128}, #endif + #ifdef HTTP_R_HEADER_PARSE_ERROR + {"HEADER_PARSE_ERROR", ERR_LIB_HTTP, HTTP_R_HEADER_PARSE_ERROR}, + #else + {"HEADER_PARSE_ERROR", 61, 126}, + #endif #ifdef HTTP_R_INCONSISTENT_CONTENT_LENGTH {"INCONSISTENT_CONTENT_LENGTH", ERR_LIB_HTTP, HTTP_R_INCONSISTENT_CONTENT_LENGTH}, #else @@ -3935,6 +4015,16 @@ static struct py_ssl_error_code error_codes[] = { #else {"RESPONSE_PARSE_ERROR", 61, 104}, #endif + #ifdef HTTP_R_RETRY_TIMEOUT + {"RETRY_TIMEOUT", ERR_LIB_HTTP, HTTP_R_RETRY_TIMEOUT}, + #else + {"RETRY_TIMEOUT", 61, 129}, + #endif + #ifdef HTTP_R_SERVER_CANCELED_CONNECTION + {"SERVER_CANCELED_CONNECTION", ERR_LIB_HTTP, HTTP_R_SERVER_CANCELED_CONNECTION}, + #else + {"SERVER_CANCELED_CONNECTION", 61, 127}, + #endif #ifdef HTTP_R_SOCK_NOT_SUPPORTED {"SOCK_NOT_SUPPORTED", ERR_LIB_HTTP, HTTP_R_SOCK_NOT_SUPPORTED}, #else @@ -4100,6 +4190,16 @@ static struct py_ssl_error_code error_codes[] = { #else {"UNSUPPORTED_REQUESTORNAME_TYPE", 39, 129}, #endif + #ifdef OSSL_DECODER_R_COULD_NOT_DECODE_OBJECT + {"COULD_NOT_DECODE_OBJECT", ERR_LIB_OSSL_DECODER, OSSL_DECODER_R_COULD_NOT_DECODE_OBJECT}, + #else + {"COULD_NOT_DECODE_OBJECT", 60, 101}, + #endif + #ifdef OSSL_DECODER_R_DECODER_NOT_FOUND + {"DECODER_NOT_FOUND", ERR_LIB_OSSL_DECODER, OSSL_DECODER_R_DECODER_NOT_FOUND}, + #else + {"DECODER_NOT_FOUND", 60, 102}, + #endif #ifdef OSSL_DECODER_R_MISSING_GET_PARAMS {"MISSING_GET_PARAMS", ERR_LIB_OSSL_DECODER, OSSL_DECODER_R_MISSING_GET_PARAMS}, #else @@ -4190,6 +4290,11 @@ static struct py_ssl_error_code error_codes[] = { #else {"NOT_PARAMETERS", 44, 104}, #endif + #ifdef OSSL_STORE_R_NO_LOADERS_FOUND + {"NO_LOADERS_FOUND", ERR_LIB_OSSL_STORE, OSSL_STORE_R_NO_LOADERS_FOUND}, + #else + {"NO_LOADERS_FOUND", 44, 123}, + #endif #ifdef OSSL_STORE_R_PASSPHRASE_CALLBACK_ERROR {"PASSPHRASE_CALLBACK_ERROR", ERR_LIB_OSSL_STORE, OSSL_STORE_R_PASSPHRASE_CALLBACK_ERROR}, #else @@ -4935,6 +5040,11 @@ static struct py_ssl_error_code error_codes[] = { #else {"INVALID_DIGEST_SIZE", 57, 218}, #endif + #ifdef PROV_R_INVALID_INPUT_LENGTH + {"INVALID_INPUT_LENGTH", ERR_LIB_PROV, PROV_R_INVALID_INPUT_LENGTH}, + #else + {"INVALID_INPUT_LENGTH", 57, 230}, + #endif #ifdef PROV_R_INVALID_ITERATION_COUNT {"INVALID_ITERATION_COUNT", ERR_LIB_PROV, PROV_R_INVALID_ITERATION_COUNT}, #else @@ -4970,6 +5080,11 @@ static struct py_ssl_error_code error_codes[] = { #else {"INVALID_MODE", 57, 125}, #endif + #ifdef PROV_R_INVALID_OUTPUT_LENGTH + {"INVALID_OUTPUT_LENGTH", ERR_LIB_PROV, PROV_R_INVALID_OUTPUT_LENGTH}, + #else + {"INVALID_OUTPUT_LENGTH", 57, 217}, + #endif #ifdef PROV_R_INVALID_PADDING_MODE {"INVALID_PADDING_MODE", ERR_LIB_PROV, PROV_R_INVALID_PADDING_MODE}, #else @@ -5035,6 +5150,16 @@ static struct py_ssl_error_code error_codes[] = { #else {"KEY_SIZE_TOO_SMALL", 57, 171}, #endif + #ifdef PROV_R_LENGTH_TOO_LARGE + {"LENGTH_TOO_LARGE", ERR_LIB_PROV, PROV_R_LENGTH_TOO_LARGE}, + #else + {"LENGTH_TOO_LARGE", 57, 202}, + #endif + #ifdef PROV_R_MISMATCHING_DOMAIN_PARAMETERS + {"MISMATCHING_DOMAIN_PARAMETERS", ERR_LIB_PROV, PROV_R_MISMATCHING_DOMAIN_PARAMETERS}, + #else + {"MISMATCHING_DOMAIN_PARAMETERS", 57, 203}, + #endif #ifdef PROV_R_MISSING_CEK_ALG {"MISSING_CEK_ALG", ERR_LIB_PROV, PROV_R_MISSING_CEK_ALG}, #else @@ -5695,6 +5820,11 @@ static struct py_ssl_error_code error_codes[] = { #else {"INVALID_LABEL", 4, 160}, #endif + #ifdef RSA_R_INVALID_LENGTH + {"INVALID_LENGTH", ERR_LIB_RSA, RSA_R_INVALID_LENGTH}, + #else + {"INVALID_LENGTH", 4, 181}, + #endif #ifdef RSA_R_INVALID_MESSAGE_LENGTH {"INVALID_MESSAGE_LENGTH", ERR_LIB_RSA, RSA_R_INVALID_MESSAGE_LENGTH}, #else @@ -5880,6 +6010,11 @@ static struct py_ssl_error_code error_codes[] = { #else {"Q_NOT_PRIME", 4, 129}, #endif + #ifdef RSA_R_RANDOMNESS_SOURCE_STRENGTH_INSUFFICIENT + {"RANDOMNESS_SOURCE_STRENGTH_INSUFFICIENT", ERR_LIB_RSA, RSA_R_RANDOMNESS_SOURCE_STRENGTH_INSUFFICIENT}, + #else + {"RANDOMNESS_SOURCE_STRENGTH_INSUFFICIENT", 4, 180}, + #endif #ifdef RSA_R_RSA_OPERATIONS_NOT_SUPPORTED {"RSA_OPERATIONS_NOT_SUPPORTED", ERR_LIB_RSA, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED}, #else @@ -6680,6 +6815,11 @@ static struct py_ssl_error_code error_codes[] = { #else {"INVALID_TICKET_KEYS_LENGTH", 20, 325}, #endif + #ifdef SSL_R_LEGACY_SIGALG_DISALLOWED_OR_UNSUPPORTED + {"LEGACY_SIGALG_DISALLOWED_OR_UNSUPPORTED", ERR_LIB_SSL, SSL_R_LEGACY_SIGALG_DISALLOWED_OR_UNSUPPORTED}, + #else + {"LEGACY_SIGALG_DISALLOWED_OR_UNSUPPORTED", 20, 333}, + #endif #ifdef SSL_R_LENGTH_MISMATCH {"LENGTH_MISMATCH", ERR_LIB_SSL, SSL_R_LENGTH_MISMATCH}, #else @@ -6725,6 +6865,11 @@ static struct py_ssl_error_code error_codes[] = { #else {"MISSING_PARAMETERS", 20, 290}, #endif + #ifdef SSL_R_MISSING_PSK_KEX_MODES_EXTENSION + {"MISSING_PSK_KEX_MODES_EXTENSION", ERR_LIB_SSL, SSL_R_MISSING_PSK_KEX_MODES_EXTENSION}, + #else + {"MISSING_PSK_KEX_MODES_EXTENSION", 20, 310}, + #endif #ifdef SSL_R_MISSING_RSA_CERTIFICATE {"MISSING_RSA_CERTIFICATE", ERR_LIB_SSL, SSL_R_MISSING_RSA_CERTIFICATE}, #else @@ -6940,6 +7085,11 @@ static struct py_ssl_error_code error_codes[] = { #else {"NULL_SSL_METHOD_PASSED", 20, 196}, #endif + #ifdef SSL_R_OCSP_CALLBACK_FAILURE + {"OCSP_CALLBACK_FAILURE", ERR_LIB_SSL, SSL_R_OCSP_CALLBACK_FAILURE}, + #else + {"OCSP_CALLBACK_FAILURE", 20, 305}, + #endif #ifdef SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED {"OLD_SESSION_CIPHER_NOT_RETURNED", ERR_LIB_SSL, SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED}, #else diff --git a/Modules/_ssl_data_31.h b/Modules/_ssl_data_31.h new file mode 100644 index 00000000..c589c501 --- /dev/null +++ b/Modules/_ssl_data_31.h @@ -0,0 +1,8605 @@ +/* File generated by Tools/ssl/make_ssl_data.py *//* Generated on 2023-06-01T03:04:00.275280 */ +static struct py_ssl_library_code library_codes[] = { +#ifdef ERR_LIB_ASN1 + {"ASN1", ERR_LIB_ASN1}, +#endif +#ifdef ERR_LIB_ASYNC + {"ASYNC", ERR_LIB_ASYNC}, +#endif +#ifdef ERR_LIB_BIO + {"BIO", ERR_LIB_BIO}, +#endif +#ifdef ERR_LIB_BN + {"BN", ERR_LIB_BN}, +#endif +#ifdef ERR_LIB_BUF + {"BUF", ERR_LIB_BUF}, +#endif +#ifdef ERR_LIB_CMP + {"CMP", ERR_LIB_CMP}, +#endif +#ifdef ERR_LIB_CMS + {"CMS", ERR_LIB_CMS}, +#endif +#ifdef ERR_LIB_COMP + {"COMP", ERR_LIB_COMP}, +#endif +#ifdef ERR_LIB_CONF + {"CONF", ERR_LIB_CONF}, +#endif +#ifdef ERR_LIB_CRMF + {"CRMF", ERR_LIB_CRMF}, +#endif +#ifdef ERR_LIB_CRYPTO + {"CRYPTO", ERR_LIB_CRYPTO}, +#endif +#ifdef ERR_LIB_CT + {"CT", ERR_LIB_CT}, +#endif +#ifdef ERR_LIB_DH + {"DH", ERR_LIB_DH}, +#endif +#ifdef ERR_LIB_DSA + {"DSA", ERR_LIB_DSA}, +#endif +#ifdef ERR_LIB_DSO + {"DSO", ERR_LIB_DSO}, +#endif +#ifdef ERR_LIB_EC + {"EC", ERR_LIB_EC}, +#endif +#ifdef ERR_LIB_ECDH + {"ECDH", ERR_LIB_ECDH}, +#endif +#ifdef ERR_LIB_ECDSA + {"ECDSA", ERR_LIB_ECDSA}, +#endif +#ifdef ERR_LIB_ENGINE + {"ENGINE", ERR_LIB_ENGINE}, +#endif +#ifdef ERR_LIB_ESS + {"ESS", ERR_LIB_ESS}, +#endif +#ifdef ERR_LIB_EVP + {"EVP", ERR_LIB_EVP}, +#endif +#ifdef ERR_LIB_FIPS + {"FIPS", ERR_LIB_FIPS}, +#endif +#ifdef ERR_LIB_HMAC + {"HMAC", ERR_LIB_HMAC}, +#endif +#ifdef ERR_LIB_HTTP + {"HTTP", ERR_LIB_HTTP}, +#endif +#ifdef ERR_LIB_JPAKE + {"JPAKE", ERR_LIB_JPAKE}, +#endif +#ifdef ERR_LIB_KDF + {"KDF", ERR_LIB_KDF}, +#endif +#ifdef ERR_LIB_MASK + {"MASK", ERR_LIB_MASK}, +#endif +#ifdef ERR_LIB_METH + {"METH", ERR_LIB_METH}, +#endif +#ifdef ERR_LIB_NONE + {"NONE", ERR_LIB_NONE}, +#endif +#ifdef ERR_LIB_OBJ + {"OBJ", ERR_LIB_OBJ}, +#endif +#ifdef ERR_LIB_OCSP + {"OCSP", ERR_LIB_OCSP}, +#endif +#ifdef ERR_LIB_OFFSET + {"OFFSET", ERR_LIB_OFFSET}, +#endif +#ifdef ERR_LIB_OSSL_DECODER + {"OSSL_DECODER", ERR_LIB_OSSL_DECODER}, +#endif +#ifdef ERR_LIB_OSSL_ENCODER + {"OSSL_ENCODER", ERR_LIB_OSSL_ENCODER}, +#endif +#ifdef ERR_LIB_OSSL_STORE + {"OSSL_STORE", ERR_LIB_OSSL_STORE}, +#endif +#ifdef ERR_LIB_PEM + {"PEM", ERR_LIB_PEM}, +#endif +#ifdef ERR_LIB_PKCS12 + {"PKCS12", ERR_LIB_PKCS12}, +#endif +#ifdef ERR_LIB_PKCS7 + {"PKCS7", ERR_LIB_PKCS7}, +#endif +#ifdef ERR_LIB_PROP + {"PROP", ERR_LIB_PROP}, +#endif +#ifdef ERR_LIB_PROV + {"PROV", ERR_LIB_PROV}, +#endif +#ifdef ERR_LIB_PROXY + {"PROXY", ERR_LIB_PROXY}, +#endif +#ifdef ERR_LIB_RAND + {"RAND", ERR_LIB_RAND}, +#endif +#ifdef ERR_LIB_RSA + {"RSA", ERR_LIB_RSA}, +#endif +#ifdef ERR_LIB_RSAREF + {"RSAREF", ERR_LIB_RSAREF}, +#endif +#ifdef ERR_LIB_SM2 + {"SM2", ERR_LIB_SM2}, +#endif +#ifdef ERR_LIB_SSL + {"SSL", ERR_LIB_SSL}, +#endif +#ifdef ERR_LIB_SSL2 + {"SSL2", ERR_LIB_SSL2}, +#endif +#ifdef ERR_LIB_SSL23 + {"SSL23", ERR_LIB_SSL23}, +#endif +#ifdef ERR_LIB_SSL3 + {"SSL3", ERR_LIB_SSL3}, +#endif +#ifdef ERR_LIB_SYS + {"SYS", ERR_LIB_SYS}, +#endif +#ifdef ERR_LIB_TS + {"TS", ERR_LIB_TS}, +#endif +#ifdef ERR_LIB_UI + {"UI", ERR_LIB_UI}, +#endif +#ifdef ERR_LIB_USER + {"USER", ERR_LIB_USER}, +#endif +#ifdef ERR_LIB_X509 + {"X509", ERR_LIB_X509}, +#endif +#ifdef ERR_LIB_X509V3 + {"X509V3", ERR_LIB_X509V3}, +#endif + { NULL } +}; + + +static struct py_ssl_error_code error_codes[] = { + #ifdef ASN1_R_ADDING_OBJECT + {"ADDING_OBJECT", ERR_LIB_ASN1, ASN1_R_ADDING_OBJECT}, + #else + {"ADDING_OBJECT", 13, 171}, + #endif + #ifdef ASN1_R_ASN1_PARSE_ERROR + {"ASN1_PARSE_ERROR", ERR_LIB_ASN1, ASN1_R_ASN1_PARSE_ERROR}, + #else + {"ASN1_PARSE_ERROR", 13, 203}, + #endif + #ifdef ASN1_R_ASN1_SIG_PARSE_ERROR + {"ASN1_SIG_PARSE_ERROR", ERR_LIB_ASN1, ASN1_R_ASN1_SIG_PARSE_ERROR}, + #else + {"ASN1_SIG_PARSE_ERROR", 13, 204}, + #endif + #ifdef ASN1_R_AUX_ERROR + {"AUX_ERROR", ERR_LIB_ASN1, ASN1_R_AUX_ERROR}, + #else + {"AUX_ERROR", 13, 100}, + #endif + #ifdef ASN1_R_BAD_OBJECT_HEADER + {"BAD_OBJECT_HEADER", ERR_LIB_ASN1, ASN1_R_BAD_OBJECT_HEADER}, + #else + {"BAD_OBJECT_HEADER", 13, 102}, + #endif + #ifdef ASN1_R_BAD_TEMPLATE + {"BAD_TEMPLATE", ERR_LIB_ASN1, ASN1_R_BAD_TEMPLATE}, + #else + {"BAD_TEMPLATE", 13, 230}, + #endif + #ifdef ASN1_R_BMPSTRING_IS_WRONG_LENGTH + {"BMPSTRING_IS_WRONG_LENGTH", ERR_LIB_ASN1, ASN1_R_BMPSTRING_IS_WRONG_LENGTH}, + #else + {"BMPSTRING_IS_WRONG_LENGTH", 13, 214}, + #endif + #ifdef ASN1_R_BN_LIB + {"BN_LIB", ERR_LIB_ASN1, ASN1_R_BN_LIB}, + #else + {"BN_LIB", 13, 105}, + #endif + #ifdef ASN1_R_BOOLEAN_IS_WRONG_LENGTH + {"BOOLEAN_IS_WRONG_LENGTH", ERR_LIB_ASN1, ASN1_R_BOOLEAN_IS_WRONG_LENGTH}, + #else + {"BOOLEAN_IS_WRONG_LENGTH", 13, 106}, + #endif + #ifdef ASN1_R_BUFFER_TOO_SMALL + {"BUFFER_TOO_SMALL", ERR_LIB_ASN1, ASN1_R_BUFFER_TOO_SMALL}, + #else + {"BUFFER_TOO_SMALL", 13, 107}, + #endif + #ifdef ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER + {"CIPHER_HAS_NO_OBJECT_IDENTIFIER", ERR_LIB_ASN1, ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER}, + #else + {"CIPHER_HAS_NO_OBJECT_IDENTIFIER", 13, 108}, + #endif + #ifdef ASN1_R_CONTEXT_NOT_INITIALISED + {"CONTEXT_NOT_INITIALISED", ERR_LIB_ASN1, ASN1_R_CONTEXT_NOT_INITIALISED}, + #else + {"CONTEXT_NOT_INITIALISED", 13, 217}, + #endif + #ifdef ASN1_R_DATA_IS_WRONG + {"DATA_IS_WRONG", ERR_LIB_ASN1, ASN1_R_DATA_IS_WRONG}, + #else + {"DATA_IS_WRONG", 13, 109}, + #endif + #ifdef ASN1_R_DECODE_ERROR + {"DECODE_ERROR", ERR_LIB_ASN1, ASN1_R_DECODE_ERROR}, + #else + {"DECODE_ERROR", 13, 110}, + #endif + #ifdef ASN1_R_DEPTH_EXCEEDED + {"DEPTH_EXCEEDED", ERR_LIB_ASN1, ASN1_R_DEPTH_EXCEEDED}, + #else + {"DEPTH_EXCEEDED", 13, 174}, + #endif + #ifdef ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED + {"DIGEST_AND_KEY_TYPE_NOT_SUPPORTED", ERR_LIB_ASN1, ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED}, + #else + {"DIGEST_AND_KEY_TYPE_NOT_SUPPORTED", 13, 198}, + #endif + #ifdef ASN1_R_ENCODE_ERROR + {"ENCODE_ERROR", ERR_LIB_ASN1, ASN1_R_ENCODE_ERROR}, + #else + {"ENCODE_ERROR", 13, 112}, + #endif + #ifdef ASN1_R_ERROR_GETTING_TIME + {"ERROR_GETTING_TIME", ERR_LIB_ASN1, ASN1_R_ERROR_GETTING_TIME}, + #else + {"ERROR_GETTING_TIME", 13, 173}, + #endif + #ifdef ASN1_R_ERROR_LOADING_SECTION + {"ERROR_LOADING_SECTION", ERR_LIB_ASN1, ASN1_R_ERROR_LOADING_SECTION}, + #else + {"ERROR_LOADING_SECTION", 13, 172}, + #endif + #ifdef ASN1_R_ERROR_SETTING_CIPHER_PARAMS + {"ERROR_SETTING_CIPHER_PARAMS", ERR_LIB_ASN1, ASN1_R_ERROR_SETTING_CIPHER_PARAMS}, + #else + {"ERROR_SETTING_CIPHER_PARAMS", 13, 114}, + #endif + #ifdef ASN1_R_EXPECTING_AN_INTEGER + {"EXPECTING_AN_INTEGER", ERR_LIB_ASN1, ASN1_R_EXPECTING_AN_INTEGER}, + #else + {"EXPECTING_AN_INTEGER", 13, 115}, + #endif + #ifdef ASN1_R_EXPECTING_AN_OBJECT + {"EXPECTING_AN_OBJECT", ERR_LIB_ASN1, ASN1_R_EXPECTING_AN_OBJECT}, + #else + {"EXPECTING_AN_OBJECT", 13, 116}, + #endif + #ifdef ASN1_R_EXPLICIT_LENGTH_MISMATCH + {"EXPLICIT_LENGTH_MISMATCH", ERR_LIB_ASN1, ASN1_R_EXPLICIT_LENGTH_MISMATCH}, + #else + {"EXPLICIT_LENGTH_MISMATCH", 13, 119}, + #endif + #ifdef ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED + {"EXPLICIT_TAG_NOT_CONSTRUCTED", ERR_LIB_ASN1, ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED}, + #else + {"EXPLICIT_TAG_NOT_CONSTRUCTED", 13, 120}, + #endif + #ifdef ASN1_R_FIELD_MISSING + {"FIELD_MISSING", ERR_LIB_ASN1, ASN1_R_FIELD_MISSING}, + #else + {"FIELD_MISSING", 13, 121}, + #endif + #ifdef ASN1_R_FIRST_NUM_TOO_LARGE + {"FIRST_NUM_TOO_LARGE", ERR_LIB_ASN1, ASN1_R_FIRST_NUM_TOO_LARGE}, + #else + {"FIRST_NUM_TOO_LARGE", 13, 122}, + #endif + #ifdef ASN1_R_HEADER_TOO_LONG + {"HEADER_TOO_LONG", ERR_LIB_ASN1, ASN1_R_HEADER_TOO_LONG}, + #else + {"HEADER_TOO_LONG", 13, 123}, + #endif + #ifdef ASN1_R_ILLEGAL_BITSTRING_FORMAT + {"ILLEGAL_BITSTRING_FORMAT", ERR_LIB_ASN1, ASN1_R_ILLEGAL_BITSTRING_FORMAT}, + #else + {"ILLEGAL_BITSTRING_FORMAT", 13, 175}, + #endif + #ifdef ASN1_R_ILLEGAL_BOOLEAN + {"ILLEGAL_BOOLEAN", ERR_LIB_ASN1, ASN1_R_ILLEGAL_BOOLEAN}, + #else + {"ILLEGAL_BOOLEAN", 13, 176}, + #endif + #ifdef ASN1_R_ILLEGAL_CHARACTERS + {"ILLEGAL_CHARACTERS", ERR_LIB_ASN1, ASN1_R_ILLEGAL_CHARACTERS}, + #else + {"ILLEGAL_CHARACTERS", 13, 124}, + #endif + #ifdef ASN1_R_ILLEGAL_FORMAT + {"ILLEGAL_FORMAT", ERR_LIB_ASN1, ASN1_R_ILLEGAL_FORMAT}, + #else + {"ILLEGAL_FORMAT", 13, 177}, + #endif + #ifdef ASN1_R_ILLEGAL_HEX + {"ILLEGAL_HEX", ERR_LIB_ASN1, ASN1_R_ILLEGAL_HEX}, + #else + {"ILLEGAL_HEX", 13, 178}, + #endif + #ifdef ASN1_R_ILLEGAL_IMPLICIT_TAG + {"ILLEGAL_IMPLICIT_TAG", ERR_LIB_ASN1, ASN1_R_ILLEGAL_IMPLICIT_TAG}, + #else + {"ILLEGAL_IMPLICIT_TAG", 13, 179}, + #endif + #ifdef ASN1_R_ILLEGAL_INTEGER + {"ILLEGAL_INTEGER", ERR_LIB_ASN1, ASN1_R_ILLEGAL_INTEGER}, + #else + {"ILLEGAL_INTEGER", 13, 180}, + #endif + #ifdef ASN1_R_ILLEGAL_NEGATIVE_VALUE + {"ILLEGAL_NEGATIVE_VALUE", ERR_LIB_ASN1, ASN1_R_ILLEGAL_NEGATIVE_VALUE}, + #else + {"ILLEGAL_NEGATIVE_VALUE", 13, 226}, + #endif + #ifdef ASN1_R_ILLEGAL_NESTED_TAGGING + {"ILLEGAL_NESTED_TAGGING", ERR_LIB_ASN1, ASN1_R_ILLEGAL_NESTED_TAGGING}, + #else + {"ILLEGAL_NESTED_TAGGING", 13, 181}, + #endif + #ifdef ASN1_R_ILLEGAL_NULL + {"ILLEGAL_NULL", ERR_LIB_ASN1, ASN1_R_ILLEGAL_NULL}, + #else + {"ILLEGAL_NULL", 13, 125}, + #endif + #ifdef ASN1_R_ILLEGAL_NULL_VALUE + {"ILLEGAL_NULL_VALUE", ERR_LIB_ASN1, ASN1_R_ILLEGAL_NULL_VALUE}, + #else + {"ILLEGAL_NULL_VALUE", 13, 182}, + #endif + #ifdef ASN1_R_ILLEGAL_OBJECT + {"ILLEGAL_OBJECT", ERR_LIB_ASN1, ASN1_R_ILLEGAL_OBJECT}, + #else + {"ILLEGAL_OBJECT", 13, 183}, + #endif + #ifdef ASN1_R_ILLEGAL_OPTIONAL_ANY + {"ILLEGAL_OPTIONAL_ANY", ERR_LIB_ASN1, ASN1_R_ILLEGAL_OPTIONAL_ANY}, + #else + {"ILLEGAL_OPTIONAL_ANY", 13, 126}, + #endif + #ifdef ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE + {"ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE", ERR_LIB_ASN1, ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE}, + #else + {"ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE", 13, 170}, + #endif + #ifdef ASN1_R_ILLEGAL_PADDING + {"ILLEGAL_PADDING", ERR_LIB_ASN1, ASN1_R_ILLEGAL_PADDING}, + #else + {"ILLEGAL_PADDING", 13, 221}, + #endif + #ifdef ASN1_R_ILLEGAL_TAGGED_ANY + {"ILLEGAL_TAGGED_ANY", ERR_LIB_ASN1, ASN1_R_ILLEGAL_TAGGED_ANY}, + #else + {"ILLEGAL_TAGGED_ANY", 13, 127}, + #endif + #ifdef ASN1_R_ILLEGAL_TIME_VALUE + {"ILLEGAL_TIME_VALUE", ERR_LIB_ASN1, ASN1_R_ILLEGAL_TIME_VALUE}, + #else + {"ILLEGAL_TIME_VALUE", 13, 184}, + #endif + #ifdef ASN1_R_ILLEGAL_ZERO_CONTENT + {"ILLEGAL_ZERO_CONTENT", ERR_LIB_ASN1, ASN1_R_ILLEGAL_ZERO_CONTENT}, + #else + {"ILLEGAL_ZERO_CONTENT", 13, 222}, + #endif + #ifdef ASN1_R_INTEGER_NOT_ASCII_FORMAT + {"INTEGER_NOT_ASCII_FORMAT", ERR_LIB_ASN1, ASN1_R_INTEGER_NOT_ASCII_FORMAT}, + #else + {"INTEGER_NOT_ASCII_FORMAT", 13, 185}, + #endif + #ifdef ASN1_R_INTEGER_TOO_LARGE_FOR_LONG + {"INTEGER_TOO_LARGE_FOR_LONG", ERR_LIB_ASN1, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG}, + #else + {"INTEGER_TOO_LARGE_FOR_LONG", 13, 128}, + #endif + #ifdef ASN1_R_INVALID_BIT_STRING_BITS_LEFT + {"INVALID_BIT_STRING_BITS_LEFT", ERR_LIB_ASN1, ASN1_R_INVALID_BIT_STRING_BITS_LEFT}, + #else + {"INVALID_BIT_STRING_BITS_LEFT", 13, 220}, + #endif + #ifdef ASN1_R_INVALID_BMPSTRING_LENGTH + {"INVALID_BMPSTRING_LENGTH", ERR_LIB_ASN1, ASN1_R_INVALID_BMPSTRING_LENGTH}, + #else + {"INVALID_BMPSTRING_LENGTH", 13, 129}, + #endif + #ifdef ASN1_R_INVALID_DIGIT + {"INVALID_DIGIT", ERR_LIB_ASN1, ASN1_R_INVALID_DIGIT}, + #else + {"INVALID_DIGIT", 13, 130}, + #endif + #ifdef ASN1_R_INVALID_MIME_TYPE + {"INVALID_MIME_TYPE", ERR_LIB_ASN1, ASN1_R_INVALID_MIME_TYPE}, + #else + {"INVALID_MIME_TYPE", 13, 205}, + #endif + #ifdef ASN1_R_INVALID_MODIFIER + {"INVALID_MODIFIER", ERR_LIB_ASN1, ASN1_R_INVALID_MODIFIER}, + #else + {"INVALID_MODIFIER", 13, 186}, + #endif + #ifdef ASN1_R_INVALID_NUMBER + {"INVALID_NUMBER", ERR_LIB_ASN1, ASN1_R_INVALID_NUMBER}, + #else + {"INVALID_NUMBER", 13, 187}, + #endif + #ifdef ASN1_R_INVALID_OBJECT_ENCODING + {"INVALID_OBJECT_ENCODING", ERR_LIB_ASN1, ASN1_R_INVALID_OBJECT_ENCODING}, + #else + {"INVALID_OBJECT_ENCODING", 13, 216}, + #endif + #ifdef ASN1_R_INVALID_SCRYPT_PARAMETERS + {"INVALID_SCRYPT_PARAMETERS", ERR_LIB_ASN1, ASN1_R_INVALID_SCRYPT_PARAMETERS}, + #else + {"INVALID_SCRYPT_PARAMETERS", 13, 227}, + #endif + #ifdef ASN1_R_INVALID_SEPARATOR + {"INVALID_SEPARATOR", ERR_LIB_ASN1, ASN1_R_INVALID_SEPARATOR}, + #else + {"INVALID_SEPARATOR", 13, 131}, + #endif + #ifdef ASN1_R_INVALID_STRING_TABLE_VALUE + {"INVALID_STRING_TABLE_VALUE", ERR_LIB_ASN1, ASN1_R_INVALID_STRING_TABLE_VALUE}, + #else + {"INVALID_STRING_TABLE_VALUE", 13, 218}, + #endif + #ifdef ASN1_R_INVALID_UNIVERSALSTRING_LENGTH + {"INVALID_UNIVERSALSTRING_LENGTH", ERR_LIB_ASN1, ASN1_R_INVALID_UNIVERSALSTRING_LENGTH}, + #else + {"INVALID_UNIVERSALSTRING_LENGTH", 13, 133}, + #endif + #ifdef ASN1_R_INVALID_UTF8STRING + {"INVALID_UTF8STRING", ERR_LIB_ASN1, ASN1_R_INVALID_UTF8STRING}, + #else + {"INVALID_UTF8STRING", 13, 134}, + #endif + #ifdef ASN1_R_INVALID_VALUE + {"INVALID_VALUE", ERR_LIB_ASN1, ASN1_R_INVALID_VALUE}, + #else + {"INVALID_VALUE", 13, 219}, + #endif + #ifdef ASN1_R_LENGTH_TOO_LONG + {"LENGTH_TOO_LONG", ERR_LIB_ASN1, ASN1_R_LENGTH_TOO_LONG}, + #else + {"LENGTH_TOO_LONG", 13, 231}, + #endif + #ifdef ASN1_R_LIST_ERROR + {"LIST_ERROR", ERR_LIB_ASN1, ASN1_R_LIST_ERROR}, + #else + {"LIST_ERROR", 13, 188}, + #endif + #ifdef ASN1_R_MIME_NO_CONTENT_TYPE + {"MIME_NO_CONTENT_TYPE", ERR_LIB_ASN1, ASN1_R_MIME_NO_CONTENT_TYPE}, + #else + {"MIME_NO_CONTENT_TYPE", 13, 206}, + #endif + #ifdef ASN1_R_MIME_PARSE_ERROR + {"MIME_PARSE_ERROR", ERR_LIB_ASN1, ASN1_R_MIME_PARSE_ERROR}, + #else + {"MIME_PARSE_ERROR", 13, 207}, + #endif + #ifdef ASN1_R_MIME_SIG_PARSE_ERROR + {"MIME_SIG_PARSE_ERROR", ERR_LIB_ASN1, ASN1_R_MIME_SIG_PARSE_ERROR}, + #else + {"MIME_SIG_PARSE_ERROR", 13, 208}, + #endif + #ifdef ASN1_R_MISSING_EOC + {"MISSING_EOC", ERR_LIB_ASN1, ASN1_R_MISSING_EOC}, + #else + {"MISSING_EOC", 13, 137}, + #endif + #ifdef ASN1_R_MISSING_SECOND_NUMBER + {"MISSING_SECOND_NUMBER", ERR_LIB_ASN1, ASN1_R_MISSING_SECOND_NUMBER}, + #else + {"MISSING_SECOND_NUMBER", 13, 138}, + #endif + #ifdef ASN1_R_MISSING_VALUE + {"MISSING_VALUE", ERR_LIB_ASN1, ASN1_R_MISSING_VALUE}, + #else + {"MISSING_VALUE", 13, 189}, + #endif + #ifdef ASN1_R_MSTRING_NOT_UNIVERSAL + {"MSTRING_NOT_UNIVERSAL", ERR_LIB_ASN1, ASN1_R_MSTRING_NOT_UNIVERSAL}, + #else + {"MSTRING_NOT_UNIVERSAL", 13, 139}, + #endif + #ifdef ASN1_R_MSTRING_WRONG_TAG + {"MSTRING_WRONG_TAG", ERR_LIB_ASN1, ASN1_R_MSTRING_WRONG_TAG}, + #else + {"MSTRING_WRONG_TAG", 13, 140}, + #endif + #ifdef ASN1_R_NESTED_ASN1_STRING + {"NESTED_ASN1_STRING", ERR_LIB_ASN1, ASN1_R_NESTED_ASN1_STRING}, + #else + {"NESTED_ASN1_STRING", 13, 197}, + #endif + #ifdef ASN1_R_NESTED_TOO_DEEP + {"NESTED_TOO_DEEP", ERR_LIB_ASN1, ASN1_R_NESTED_TOO_DEEP}, + #else + {"NESTED_TOO_DEEP", 13, 201}, + #endif + #ifdef ASN1_R_NON_HEX_CHARACTERS + {"NON_HEX_CHARACTERS", ERR_LIB_ASN1, ASN1_R_NON_HEX_CHARACTERS}, + #else + {"NON_HEX_CHARACTERS", 13, 141}, + #endif + #ifdef ASN1_R_NOT_ASCII_FORMAT + {"NOT_ASCII_FORMAT", ERR_LIB_ASN1, ASN1_R_NOT_ASCII_FORMAT}, + #else + {"NOT_ASCII_FORMAT", 13, 190}, + #endif + #ifdef ASN1_R_NOT_ENOUGH_DATA + {"NOT_ENOUGH_DATA", ERR_LIB_ASN1, ASN1_R_NOT_ENOUGH_DATA}, + #else + {"NOT_ENOUGH_DATA", 13, 142}, + #endif + #ifdef ASN1_R_NO_CONTENT_TYPE + {"NO_CONTENT_TYPE", ERR_LIB_ASN1, ASN1_R_NO_CONTENT_TYPE}, + #else + {"NO_CONTENT_TYPE", 13, 209}, + #endif + #ifdef ASN1_R_NO_MATCHING_CHOICE_TYPE + {"NO_MATCHING_CHOICE_TYPE", ERR_LIB_ASN1, ASN1_R_NO_MATCHING_CHOICE_TYPE}, + #else + {"NO_MATCHING_CHOICE_TYPE", 13, 143}, + #endif + #ifdef ASN1_R_NO_MULTIPART_BODY_FAILURE + {"NO_MULTIPART_BODY_FAILURE", ERR_LIB_ASN1, ASN1_R_NO_MULTIPART_BODY_FAILURE}, + #else + {"NO_MULTIPART_BODY_FAILURE", 13, 210}, + #endif + #ifdef ASN1_R_NO_MULTIPART_BOUNDARY + {"NO_MULTIPART_BOUNDARY", ERR_LIB_ASN1, ASN1_R_NO_MULTIPART_BOUNDARY}, + #else + {"NO_MULTIPART_BOUNDARY", 13, 211}, + #endif + #ifdef ASN1_R_NO_SIG_CONTENT_TYPE + {"NO_SIG_CONTENT_TYPE", ERR_LIB_ASN1, ASN1_R_NO_SIG_CONTENT_TYPE}, + #else + {"NO_SIG_CONTENT_TYPE", 13, 212}, + #endif + #ifdef ASN1_R_NULL_IS_WRONG_LENGTH + {"NULL_IS_WRONG_LENGTH", ERR_LIB_ASN1, ASN1_R_NULL_IS_WRONG_LENGTH}, + #else + {"NULL_IS_WRONG_LENGTH", 13, 144}, + #endif + #ifdef ASN1_R_OBJECT_NOT_ASCII_FORMAT + {"OBJECT_NOT_ASCII_FORMAT", ERR_LIB_ASN1, ASN1_R_OBJECT_NOT_ASCII_FORMAT}, + #else + {"OBJECT_NOT_ASCII_FORMAT", 13, 191}, + #endif + #ifdef ASN1_R_ODD_NUMBER_OF_CHARS + {"ODD_NUMBER_OF_CHARS", ERR_LIB_ASN1, ASN1_R_ODD_NUMBER_OF_CHARS}, + #else + {"ODD_NUMBER_OF_CHARS", 13, 145}, + #endif + #ifdef ASN1_R_SECOND_NUMBER_TOO_LARGE + {"SECOND_NUMBER_TOO_LARGE", ERR_LIB_ASN1, ASN1_R_SECOND_NUMBER_TOO_LARGE}, + #else + {"SECOND_NUMBER_TOO_LARGE", 13, 147}, + #endif + #ifdef ASN1_R_SEQUENCE_LENGTH_MISMATCH + {"SEQUENCE_LENGTH_MISMATCH", ERR_LIB_ASN1, ASN1_R_SEQUENCE_LENGTH_MISMATCH}, + #else + {"SEQUENCE_LENGTH_MISMATCH", 13, 148}, + #endif + #ifdef ASN1_R_SEQUENCE_NOT_CONSTRUCTED + {"SEQUENCE_NOT_CONSTRUCTED", ERR_LIB_ASN1, ASN1_R_SEQUENCE_NOT_CONSTRUCTED}, + #else + {"SEQUENCE_NOT_CONSTRUCTED", 13, 149}, + #endif + #ifdef ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG + {"SEQUENCE_OR_SET_NEEDS_CONFIG", ERR_LIB_ASN1, ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG}, + #else + {"SEQUENCE_OR_SET_NEEDS_CONFIG", 13, 192}, + #endif + #ifdef ASN1_R_SHORT_LINE + {"SHORT_LINE", ERR_LIB_ASN1, ASN1_R_SHORT_LINE}, + #else + {"SHORT_LINE", 13, 150}, + #endif + #ifdef ASN1_R_SIG_INVALID_MIME_TYPE + {"SIG_INVALID_MIME_TYPE", ERR_LIB_ASN1, ASN1_R_SIG_INVALID_MIME_TYPE}, + #else + {"SIG_INVALID_MIME_TYPE", 13, 213}, + #endif + #ifdef ASN1_R_STREAMING_NOT_SUPPORTED + {"STREAMING_NOT_SUPPORTED", ERR_LIB_ASN1, ASN1_R_STREAMING_NOT_SUPPORTED}, + #else + {"STREAMING_NOT_SUPPORTED", 13, 202}, + #endif + #ifdef ASN1_R_STRING_TOO_LONG + {"STRING_TOO_LONG", ERR_LIB_ASN1, ASN1_R_STRING_TOO_LONG}, + #else + {"STRING_TOO_LONG", 13, 151}, + #endif + #ifdef ASN1_R_STRING_TOO_SHORT + {"STRING_TOO_SHORT", ERR_LIB_ASN1, ASN1_R_STRING_TOO_SHORT}, + #else + {"STRING_TOO_SHORT", 13, 152}, + #endif + #ifdef ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD + {"THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD", ERR_LIB_ASN1, ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD}, + #else + {"THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD", 13, 154}, + #endif + #ifdef ASN1_R_TIME_NOT_ASCII_FORMAT + {"TIME_NOT_ASCII_FORMAT", ERR_LIB_ASN1, ASN1_R_TIME_NOT_ASCII_FORMAT}, + #else + {"TIME_NOT_ASCII_FORMAT", 13, 193}, + #endif + #ifdef ASN1_R_TOO_LARGE + {"TOO_LARGE", ERR_LIB_ASN1, ASN1_R_TOO_LARGE}, + #else + {"TOO_LARGE", 13, 223}, + #endif + #ifdef ASN1_R_TOO_LONG + {"TOO_LONG", ERR_LIB_ASN1, ASN1_R_TOO_LONG}, + #else + {"TOO_LONG", 13, 155}, + #endif + #ifdef ASN1_R_TOO_SMALL + {"TOO_SMALL", ERR_LIB_ASN1, ASN1_R_TOO_SMALL}, + #else + {"TOO_SMALL", 13, 224}, + #endif + #ifdef ASN1_R_TYPE_NOT_CONSTRUCTED + {"TYPE_NOT_CONSTRUCTED", ERR_LIB_ASN1, ASN1_R_TYPE_NOT_CONSTRUCTED}, + #else + {"TYPE_NOT_CONSTRUCTED", 13, 156}, + #endif + #ifdef ASN1_R_TYPE_NOT_PRIMITIVE + {"TYPE_NOT_PRIMITIVE", ERR_LIB_ASN1, ASN1_R_TYPE_NOT_PRIMITIVE}, + #else + {"TYPE_NOT_PRIMITIVE", 13, 195}, + #endif + #ifdef ASN1_R_UNEXPECTED_EOC + {"UNEXPECTED_EOC", ERR_LIB_ASN1, ASN1_R_UNEXPECTED_EOC}, + #else + {"UNEXPECTED_EOC", 13, 159}, + #endif + #ifdef ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH + {"UNIVERSALSTRING_IS_WRONG_LENGTH", ERR_LIB_ASN1, ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH}, + #else + {"UNIVERSALSTRING_IS_WRONG_LENGTH", 13, 215}, + #endif + #ifdef ASN1_R_UNKNOWN_DIGEST + {"UNKNOWN_DIGEST", ERR_LIB_ASN1, ASN1_R_UNKNOWN_DIGEST}, + #else + {"UNKNOWN_DIGEST", 13, 229}, + #endif + #ifdef ASN1_R_UNKNOWN_FORMAT + {"UNKNOWN_FORMAT", ERR_LIB_ASN1, ASN1_R_UNKNOWN_FORMAT}, + #else + {"UNKNOWN_FORMAT", 13, 160}, + #endif + #ifdef ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM + {"UNKNOWN_MESSAGE_DIGEST_ALGORITHM", ERR_LIB_ASN1, ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM}, + #else + {"UNKNOWN_MESSAGE_DIGEST_ALGORITHM", 13, 161}, + #endif + #ifdef ASN1_R_UNKNOWN_OBJECT_TYPE + {"UNKNOWN_OBJECT_TYPE", ERR_LIB_ASN1, ASN1_R_UNKNOWN_OBJECT_TYPE}, + #else + {"UNKNOWN_OBJECT_TYPE", 13, 162}, + #endif + #ifdef ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE + {"UNKNOWN_PUBLIC_KEY_TYPE", ERR_LIB_ASN1, ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE}, + #else + {"UNKNOWN_PUBLIC_KEY_TYPE", 13, 163}, + #endif + #ifdef ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM + {"UNKNOWN_SIGNATURE_ALGORITHM", ERR_LIB_ASN1, ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM}, + #else + {"UNKNOWN_SIGNATURE_ALGORITHM", 13, 199}, + #endif + #ifdef ASN1_R_UNKNOWN_TAG + {"UNKNOWN_TAG", ERR_LIB_ASN1, ASN1_R_UNKNOWN_TAG}, + #else + {"UNKNOWN_TAG", 13, 194}, + #endif + #ifdef ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE + {"UNSUPPORTED_ANY_DEFINED_BY_TYPE", ERR_LIB_ASN1, ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE}, + #else + {"UNSUPPORTED_ANY_DEFINED_BY_TYPE", 13, 164}, + #endif + #ifdef ASN1_R_UNSUPPORTED_CIPHER + {"UNSUPPORTED_CIPHER", ERR_LIB_ASN1, ASN1_R_UNSUPPORTED_CIPHER}, + #else + {"UNSUPPORTED_CIPHER", 13, 228}, + #endif + #ifdef ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE + {"UNSUPPORTED_PUBLIC_KEY_TYPE", ERR_LIB_ASN1, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE}, + #else + {"UNSUPPORTED_PUBLIC_KEY_TYPE", 13, 167}, + #endif + #ifdef ASN1_R_UNSUPPORTED_TYPE + {"UNSUPPORTED_TYPE", ERR_LIB_ASN1, ASN1_R_UNSUPPORTED_TYPE}, + #else + {"UNSUPPORTED_TYPE", 13, 196}, + #endif + #ifdef ASN1_R_WRONG_INTEGER_TYPE + {"WRONG_INTEGER_TYPE", ERR_LIB_ASN1, ASN1_R_WRONG_INTEGER_TYPE}, + #else + {"WRONG_INTEGER_TYPE", 13, 225}, + #endif + #ifdef ASN1_R_WRONG_PUBLIC_KEY_TYPE + {"WRONG_PUBLIC_KEY_TYPE", ERR_LIB_ASN1, ASN1_R_WRONG_PUBLIC_KEY_TYPE}, + #else + {"WRONG_PUBLIC_KEY_TYPE", 13, 200}, + #endif + #ifdef ASN1_R_WRONG_TAG + {"WRONG_TAG", ERR_LIB_ASN1, ASN1_R_WRONG_TAG}, + #else + {"WRONG_TAG", 13, 168}, + #endif + #ifdef ASYNC_R_FAILED_TO_SET_POOL + {"FAILED_TO_SET_POOL", ERR_LIB_ASYNC, ASYNC_R_FAILED_TO_SET_POOL}, + #else + {"FAILED_TO_SET_POOL", 51, 101}, + #endif + #ifdef ASYNC_R_FAILED_TO_SWAP_CONTEXT + {"FAILED_TO_SWAP_CONTEXT", ERR_LIB_ASYNC, ASYNC_R_FAILED_TO_SWAP_CONTEXT}, + #else + {"FAILED_TO_SWAP_CONTEXT", 51, 102}, + #endif + #ifdef ASYNC_R_INIT_FAILED + {"INIT_FAILED", ERR_LIB_ASYNC, ASYNC_R_INIT_FAILED}, + #else + {"INIT_FAILED", 51, 105}, + #endif + #ifdef ASYNC_R_INVALID_POOL_SIZE + {"INVALID_POOL_SIZE", ERR_LIB_ASYNC, ASYNC_R_INVALID_POOL_SIZE}, + #else + {"INVALID_POOL_SIZE", 51, 103}, + #endif + #ifdef BIO_R_ACCEPT_ERROR + {"ACCEPT_ERROR", ERR_LIB_BIO, BIO_R_ACCEPT_ERROR}, + #else + {"ACCEPT_ERROR", 32, 100}, + #endif + #ifdef BIO_R_ADDRINFO_ADDR_IS_NOT_AF_INET + {"ADDRINFO_ADDR_IS_NOT_AF_INET", ERR_LIB_BIO, BIO_R_ADDRINFO_ADDR_IS_NOT_AF_INET}, + #else + {"ADDRINFO_ADDR_IS_NOT_AF_INET", 32, 141}, + #endif + #ifdef BIO_R_AMBIGUOUS_HOST_OR_SERVICE + {"AMBIGUOUS_HOST_OR_SERVICE", ERR_LIB_BIO, BIO_R_AMBIGUOUS_HOST_OR_SERVICE}, + #else + {"AMBIGUOUS_HOST_OR_SERVICE", 32, 129}, + #endif + #ifdef BIO_R_BAD_FOPEN_MODE + {"BAD_FOPEN_MODE", ERR_LIB_BIO, BIO_R_BAD_FOPEN_MODE}, + #else + {"BAD_FOPEN_MODE", 32, 101}, + #endif + #ifdef BIO_R_BROKEN_PIPE + {"BROKEN_PIPE", ERR_LIB_BIO, BIO_R_BROKEN_PIPE}, + #else + {"BROKEN_PIPE", 32, 124}, + #endif + #ifdef BIO_R_CONNECT_ERROR + {"CONNECT_ERROR", ERR_LIB_BIO, BIO_R_CONNECT_ERROR}, + #else + {"CONNECT_ERROR", 32, 103}, + #endif + #ifdef BIO_R_CONNECT_TIMEOUT + {"CONNECT_TIMEOUT", ERR_LIB_BIO, BIO_R_CONNECT_TIMEOUT}, + #else + {"CONNECT_TIMEOUT", 32, 147}, + #endif + #ifdef BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET + {"GETHOSTBYNAME_ADDR_IS_NOT_AF_INET", ERR_LIB_BIO, BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET}, + #else + {"GETHOSTBYNAME_ADDR_IS_NOT_AF_INET", 32, 107}, + #endif + #ifdef BIO_R_GETSOCKNAME_ERROR + {"GETSOCKNAME_ERROR", ERR_LIB_BIO, BIO_R_GETSOCKNAME_ERROR}, + #else + {"GETSOCKNAME_ERROR", 32, 132}, + #endif + #ifdef BIO_R_GETSOCKNAME_TRUNCATED_ADDRESS + {"GETSOCKNAME_TRUNCATED_ADDRESS", ERR_LIB_BIO, BIO_R_GETSOCKNAME_TRUNCATED_ADDRESS}, + #else + {"GETSOCKNAME_TRUNCATED_ADDRESS", 32, 133}, + #endif + #ifdef BIO_R_GETTING_SOCKTYPE + {"GETTING_SOCKTYPE", ERR_LIB_BIO, BIO_R_GETTING_SOCKTYPE}, + #else + {"GETTING_SOCKTYPE", 32, 134}, + #endif + #ifdef BIO_R_INVALID_ARGUMENT + {"INVALID_ARGUMENT", ERR_LIB_BIO, BIO_R_INVALID_ARGUMENT}, + #else + {"INVALID_ARGUMENT", 32, 125}, + #endif + #ifdef BIO_R_INVALID_SOCKET + {"INVALID_SOCKET", ERR_LIB_BIO, BIO_R_INVALID_SOCKET}, + #else + {"INVALID_SOCKET", 32, 135}, + #endif + #ifdef BIO_R_IN_USE + {"IN_USE", ERR_LIB_BIO, BIO_R_IN_USE}, + #else + {"IN_USE", 32, 123}, + #endif + #ifdef BIO_R_LENGTH_TOO_LONG + {"LENGTH_TOO_LONG", ERR_LIB_BIO, BIO_R_LENGTH_TOO_LONG}, + #else + {"LENGTH_TOO_LONG", 32, 102}, + #endif + #ifdef BIO_R_LISTEN_V6_ONLY + {"LISTEN_V6_ONLY", ERR_LIB_BIO, BIO_R_LISTEN_V6_ONLY}, + #else + {"LISTEN_V6_ONLY", 32, 136}, + #endif + #ifdef BIO_R_LOOKUP_RETURNED_NOTHING + {"LOOKUP_RETURNED_NOTHING", ERR_LIB_BIO, BIO_R_LOOKUP_RETURNED_NOTHING}, + #else + {"LOOKUP_RETURNED_NOTHING", 32, 142}, + #endif + #ifdef BIO_R_MALFORMED_HOST_OR_SERVICE + {"MALFORMED_HOST_OR_SERVICE", ERR_LIB_BIO, BIO_R_MALFORMED_HOST_OR_SERVICE}, + #else + {"MALFORMED_HOST_OR_SERVICE", 32, 130}, + #endif + #ifdef BIO_R_NBIO_CONNECT_ERROR + {"NBIO_CONNECT_ERROR", ERR_LIB_BIO, BIO_R_NBIO_CONNECT_ERROR}, + #else + {"NBIO_CONNECT_ERROR", 32, 110}, + #endif + #ifdef BIO_R_NO_ACCEPT_ADDR_OR_SERVICE_SPECIFIED + {"NO_ACCEPT_ADDR_OR_SERVICE_SPECIFIED", ERR_LIB_BIO, BIO_R_NO_ACCEPT_ADDR_OR_SERVICE_SPECIFIED}, + #else + {"NO_ACCEPT_ADDR_OR_SERVICE_SPECIFIED", 32, 143}, + #endif + #ifdef BIO_R_NO_HOSTNAME_OR_SERVICE_SPECIFIED + {"NO_HOSTNAME_OR_SERVICE_SPECIFIED", ERR_LIB_BIO, BIO_R_NO_HOSTNAME_OR_SERVICE_SPECIFIED}, + #else + {"NO_HOSTNAME_OR_SERVICE_SPECIFIED", 32, 144}, + #endif + #ifdef BIO_R_NO_PORT_DEFINED + {"NO_PORT_DEFINED", ERR_LIB_BIO, BIO_R_NO_PORT_DEFINED}, + #else + {"NO_PORT_DEFINED", 32, 113}, + #endif + #ifdef BIO_R_NO_SUCH_FILE + {"NO_SUCH_FILE", ERR_LIB_BIO, BIO_R_NO_SUCH_FILE}, + #else + {"NO_SUCH_FILE", 32, 128}, + #endif + #ifdef BIO_R_TRANSFER_ERROR + {"TRANSFER_ERROR", ERR_LIB_BIO, BIO_R_TRANSFER_ERROR}, + #else + {"TRANSFER_ERROR", 32, 104}, + #endif + #ifdef BIO_R_TRANSFER_TIMEOUT + {"TRANSFER_TIMEOUT", ERR_LIB_BIO, BIO_R_TRANSFER_TIMEOUT}, + #else + {"TRANSFER_TIMEOUT", 32, 105}, + #endif + #ifdef BIO_R_UNABLE_TO_BIND_SOCKET + {"UNABLE_TO_BIND_SOCKET", ERR_LIB_BIO, BIO_R_UNABLE_TO_BIND_SOCKET}, + #else + {"UNABLE_TO_BIND_SOCKET", 32, 117}, + #endif + #ifdef BIO_R_UNABLE_TO_CREATE_SOCKET + {"UNABLE_TO_CREATE_SOCKET", ERR_LIB_BIO, BIO_R_UNABLE_TO_CREATE_SOCKET}, + #else + {"UNABLE_TO_CREATE_SOCKET", 32, 118}, + #endif + #ifdef BIO_R_UNABLE_TO_KEEPALIVE + {"UNABLE_TO_KEEPALIVE", ERR_LIB_BIO, BIO_R_UNABLE_TO_KEEPALIVE}, + #else + {"UNABLE_TO_KEEPALIVE", 32, 137}, + #endif + #ifdef BIO_R_UNABLE_TO_LISTEN_SOCKET + {"UNABLE_TO_LISTEN_SOCKET", ERR_LIB_BIO, BIO_R_UNABLE_TO_LISTEN_SOCKET}, + #else + {"UNABLE_TO_LISTEN_SOCKET", 32, 119}, + #endif + #ifdef BIO_R_UNABLE_TO_NODELAY + {"UNABLE_TO_NODELAY", ERR_LIB_BIO, BIO_R_UNABLE_TO_NODELAY}, + #else + {"UNABLE_TO_NODELAY", 32, 138}, + #endif + #ifdef BIO_R_UNABLE_TO_REUSEADDR + {"UNABLE_TO_REUSEADDR", ERR_LIB_BIO, BIO_R_UNABLE_TO_REUSEADDR}, + #else + {"UNABLE_TO_REUSEADDR", 32, 139}, + #endif + #ifdef BIO_R_UNAVAILABLE_IP_FAMILY + {"UNAVAILABLE_IP_FAMILY", ERR_LIB_BIO, BIO_R_UNAVAILABLE_IP_FAMILY}, + #else + {"UNAVAILABLE_IP_FAMILY", 32, 145}, + #endif + #ifdef BIO_R_UNINITIALIZED + {"UNINITIALIZED", ERR_LIB_BIO, BIO_R_UNINITIALIZED}, + #else + {"UNINITIALIZED", 32, 120}, + #endif + #ifdef BIO_R_UNKNOWN_INFO_TYPE + {"UNKNOWN_INFO_TYPE", ERR_LIB_BIO, BIO_R_UNKNOWN_INFO_TYPE}, + #else + {"UNKNOWN_INFO_TYPE", 32, 140}, + #endif + #ifdef BIO_R_UNSUPPORTED_IP_FAMILY + {"UNSUPPORTED_IP_FAMILY", ERR_LIB_BIO, BIO_R_UNSUPPORTED_IP_FAMILY}, + #else + {"UNSUPPORTED_IP_FAMILY", 32, 146}, + #endif + #ifdef BIO_R_UNSUPPORTED_METHOD + {"UNSUPPORTED_METHOD", ERR_LIB_BIO, BIO_R_UNSUPPORTED_METHOD}, + #else + {"UNSUPPORTED_METHOD", 32, 121}, + #endif + #ifdef BIO_R_UNSUPPORTED_PROTOCOL_FAMILY + {"UNSUPPORTED_PROTOCOL_FAMILY", ERR_LIB_BIO, BIO_R_UNSUPPORTED_PROTOCOL_FAMILY}, + #else + {"UNSUPPORTED_PROTOCOL_FAMILY", 32, 131}, + #endif + #ifdef BIO_R_WRITE_TO_READ_ONLY_BIO + {"WRITE_TO_READ_ONLY_BIO", ERR_LIB_BIO, BIO_R_WRITE_TO_READ_ONLY_BIO}, + #else + {"WRITE_TO_READ_ONLY_BIO", 32, 126}, + #endif + #ifdef BIO_R_WSASTARTUP + {"WSASTARTUP", ERR_LIB_BIO, BIO_R_WSASTARTUP}, + #else + {"WSASTARTUP", 32, 122}, + #endif + #ifdef BN_R_ARG2_LT_ARG3 + {"ARG2_LT_ARG3", ERR_LIB_BN, BN_R_ARG2_LT_ARG3}, + #else + {"ARG2_LT_ARG3", 3, 100}, + #endif + #ifdef BN_R_BAD_RECIPROCAL + {"BAD_RECIPROCAL", ERR_LIB_BN, BN_R_BAD_RECIPROCAL}, + #else + {"BAD_RECIPROCAL", 3, 101}, + #endif + #ifdef BN_R_BIGNUM_TOO_LONG + {"BIGNUM_TOO_LONG", ERR_LIB_BN, BN_R_BIGNUM_TOO_LONG}, + #else + {"BIGNUM_TOO_LONG", 3, 114}, + #endif + #ifdef BN_R_BITS_TOO_SMALL + {"BITS_TOO_SMALL", ERR_LIB_BN, BN_R_BITS_TOO_SMALL}, + #else + {"BITS_TOO_SMALL", 3, 118}, + #endif + #ifdef BN_R_CALLED_WITH_EVEN_MODULUS + {"CALLED_WITH_EVEN_MODULUS", ERR_LIB_BN, BN_R_CALLED_WITH_EVEN_MODULUS}, + #else + {"CALLED_WITH_EVEN_MODULUS", 3, 102}, + #endif + #ifdef BN_R_DIV_BY_ZERO + {"DIV_BY_ZERO", ERR_LIB_BN, BN_R_DIV_BY_ZERO}, + #else + {"DIV_BY_ZERO", 3, 103}, + #endif + #ifdef BN_R_ENCODING_ERROR + {"ENCODING_ERROR", ERR_LIB_BN, BN_R_ENCODING_ERROR}, + #else + {"ENCODING_ERROR", 3, 104}, + #endif + #ifdef BN_R_EXPAND_ON_STATIC_BIGNUM_DATA + {"EXPAND_ON_STATIC_BIGNUM_DATA", ERR_LIB_BN, BN_R_EXPAND_ON_STATIC_BIGNUM_DATA}, + #else + {"EXPAND_ON_STATIC_BIGNUM_DATA", 3, 105}, + #endif + #ifdef BN_R_INPUT_NOT_REDUCED + {"INPUT_NOT_REDUCED", ERR_LIB_BN, BN_R_INPUT_NOT_REDUCED}, + #else + {"INPUT_NOT_REDUCED", 3, 110}, + #endif + #ifdef BN_R_INVALID_LENGTH + {"INVALID_LENGTH", ERR_LIB_BN, BN_R_INVALID_LENGTH}, + #else + {"INVALID_LENGTH", 3, 106}, + #endif + #ifdef BN_R_INVALID_RANGE + {"INVALID_RANGE", ERR_LIB_BN, BN_R_INVALID_RANGE}, + #else + {"INVALID_RANGE", 3, 115}, + #endif + #ifdef BN_R_INVALID_SHIFT + {"INVALID_SHIFT", ERR_LIB_BN, BN_R_INVALID_SHIFT}, + #else + {"INVALID_SHIFT", 3, 119}, + #endif + #ifdef BN_R_NOT_A_SQUARE + {"NOT_A_SQUARE", ERR_LIB_BN, BN_R_NOT_A_SQUARE}, + #else + {"NOT_A_SQUARE", 3, 111}, + #endif + #ifdef BN_R_NOT_INITIALIZED + {"NOT_INITIALIZED", ERR_LIB_BN, BN_R_NOT_INITIALIZED}, + #else + {"NOT_INITIALIZED", 3, 107}, + #endif + #ifdef BN_R_NO_INVERSE + {"NO_INVERSE", ERR_LIB_BN, BN_R_NO_INVERSE}, + #else + {"NO_INVERSE", 3, 108}, + #endif + #ifdef BN_R_NO_PRIME_CANDIDATE + {"NO_PRIME_CANDIDATE", ERR_LIB_BN, BN_R_NO_PRIME_CANDIDATE}, + #else + {"NO_PRIME_CANDIDATE", 3, 121}, + #endif + #ifdef BN_R_NO_SOLUTION + {"NO_SOLUTION", ERR_LIB_BN, BN_R_NO_SOLUTION}, + #else + {"NO_SOLUTION", 3, 116}, + #endif + #ifdef BN_R_NO_SUITABLE_DIGEST + {"NO_SUITABLE_DIGEST", ERR_LIB_BN, BN_R_NO_SUITABLE_DIGEST}, + #else + {"NO_SUITABLE_DIGEST", 3, 120}, + #endif + #ifdef BN_R_PRIVATE_KEY_TOO_LARGE + {"PRIVATE_KEY_TOO_LARGE", ERR_LIB_BN, BN_R_PRIVATE_KEY_TOO_LARGE}, + #else + {"PRIVATE_KEY_TOO_LARGE", 3, 117}, + #endif + #ifdef BN_R_P_IS_NOT_PRIME + {"P_IS_NOT_PRIME", ERR_LIB_BN, BN_R_P_IS_NOT_PRIME}, + #else + {"P_IS_NOT_PRIME", 3, 112}, + #endif + #ifdef BN_R_TOO_MANY_ITERATIONS + {"TOO_MANY_ITERATIONS", ERR_LIB_BN, BN_R_TOO_MANY_ITERATIONS}, + #else + {"TOO_MANY_ITERATIONS", 3, 113}, + #endif + #ifdef BN_R_TOO_MANY_TEMPORARY_VARIABLES + {"TOO_MANY_TEMPORARY_VARIABLES", ERR_LIB_BN, BN_R_TOO_MANY_TEMPORARY_VARIABLES}, + #else + {"TOO_MANY_TEMPORARY_VARIABLES", 3, 109}, + #endif + #ifdef CMP_R_ALGORITHM_NOT_SUPPORTED + {"ALGORITHM_NOT_SUPPORTED", ERR_LIB_CMP, CMP_R_ALGORITHM_NOT_SUPPORTED}, + #else + {"ALGORITHM_NOT_SUPPORTED", 58, 139}, + #endif + #ifdef CMP_R_BAD_CHECKAFTER_IN_POLLREP + {"BAD_CHECKAFTER_IN_POLLREP", ERR_LIB_CMP, CMP_R_BAD_CHECKAFTER_IN_POLLREP}, + #else + {"BAD_CHECKAFTER_IN_POLLREP", 58, 167}, + #endif + #ifdef CMP_R_BAD_REQUEST_ID + {"BAD_REQUEST_ID", ERR_LIB_CMP, CMP_R_BAD_REQUEST_ID}, + #else + {"BAD_REQUEST_ID", 58, 108}, + #endif + #ifdef CMP_R_CERTHASH_UNMATCHED + {"CERTHASH_UNMATCHED", ERR_LIB_CMP, CMP_R_CERTHASH_UNMATCHED}, + #else + {"CERTHASH_UNMATCHED", 58, 156}, + #endif + #ifdef CMP_R_CERTID_NOT_FOUND + {"CERTID_NOT_FOUND", ERR_LIB_CMP, CMP_R_CERTID_NOT_FOUND}, + #else + {"CERTID_NOT_FOUND", 58, 109}, + #endif + #ifdef CMP_R_CERTIFICATE_NOT_ACCEPTED + {"CERTIFICATE_NOT_ACCEPTED", ERR_LIB_CMP, CMP_R_CERTIFICATE_NOT_ACCEPTED}, + #else + {"CERTIFICATE_NOT_ACCEPTED", 58, 169}, + #endif + #ifdef CMP_R_CERTIFICATE_NOT_FOUND + {"CERTIFICATE_NOT_FOUND", ERR_LIB_CMP, CMP_R_CERTIFICATE_NOT_FOUND}, + #else + {"CERTIFICATE_NOT_FOUND", 58, 112}, + #endif + #ifdef CMP_R_CERTREQMSG_NOT_FOUND + {"CERTREQMSG_NOT_FOUND", ERR_LIB_CMP, CMP_R_CERTREQMSG_NOT_FOUND}, + #else + {"CERTREQMSG_NOT_FOUND", 58, 157}, + #endif + #ifdef CMP_R_CERTRESPONSE_NOT_FOUND + {"CERTRESPONSE_NOT_FOUND", ERR_LIB_CMP, CMP_R_CERTRESPONSE_NOT_FOUND}, + #else + {"CERTRESPONSE_NOT_FOUND", 58, 113}, + #endif + #ifdef CMP_R_CERT_AND_KEY_DO_NOT_MATCH + {"CERT_AND_KEY_DO_NOT_MATCH", ERR_LIB_CMP, CMP_R_CERT_AND_KEY_DO_NOT_MATCH}, + #else + {"CERT_AND_KEY_DO_NOT_MATCH", 58, 114}, + #endif + #ifdef CMP_R_CHECKAFTER_OUT_OF_RANGE + {"CHECKAFTER_OUT_OF_RANGE", ERR_LIB_CMP, CMP_R_CHECKAFTER_OUT_OF_RANGE}, + #else + {"CHECKAFTER_OUT_OF_RANGE", 58, 181}, + #endif + #ifdef CMP_R_ENCOUNTERED_KEYUPDATEWARNING + {"ENCOUNTERED_KEYUPDATEWARNING", ERR_LIB_CMP, CMP_R_ENCOUNTERED_KEYUPDATEWARNING}, + #else + {"ENCOUNTERED_KEYUPDATEWARNING", 58, 176}, + #endif + #ifdef CMP_R_ENCOUNTERED_WAITING + {"ENCOUNTERED_WAITING", ERR_LIB_CMP, CMP_R_ENCOUNTERED_WAITING}, + #else + {"ENCOUNTERED_WAITING", 58, 162}, + #endif + #ifdef CMP_R_ERROR_CALCULATING_PROTECTION + {"ERROR_CALCULATING_PROTECTION", ERR_LIB_CMP, CMP_R_ERROR_CALCULATING_PROTECTION}, + #else + {"ERROR_CALCULATING_PROTECTION", 58, 115}, + #endif + #ifdef CMP_R_ERROR_CREATING_CERTCONF + {"ERROR_CREATING_CERTCONF", ERR_LIB_CMP, CMP_R_ERROR_CREATING_CERTCONF}, + #else + {"ERROR_CREATING_CERTCONF", 58, 116}, + #endif + #ifdef CMP_R_ERROR_CREATING_CERTREP + {"ERROR_CREATING_CERTREP", ERR_LIB_CMP, CMP_R_ERROR_CREATING_CERTREP}, + #else + {"ERROR_CREATING_CERTREP", 58, 117}, + #endif + #ifdef CMP_R_ERROR_CREATING_CERTREQ + {"ERROR_CREATING_CERTREQ", ERR_LIB_CMP, CMP_R_ERROR_CREATING_CERTREQ}, + #else + {"ERROR_CREATING_CERTREQ", 58, 163}, + #endif + #ifdef CMP_R_ERROR_CREATING_ERROR + {"ERROR_CREATING_ERROR", ERR_LIB_CMP, CMP_R_ERROR_CREATING_ERROR}, + #else + {"ERROR_CREATING_ERROR", 58, 118}, + #endif + #ifdef CMP_R_ERROR_CREATING_GENM + {"ERROR_CREATING_GENM", ERR_LIB_CMP, CMP_R_ERROR_CREATING_GENM}, + #else + {"ERROR_CREATING_GENM", 58, 119}, + #endif + #ifdef CMP_R_ERROR_CREATING_GENP + {"ERROR_CREATING_GENP", ERR_LIB_CMP, CMP_R_ERROR_CREATING_GENP}, + #else + {"ERROR_CREATING_GENP", 58, 120}, + #endif + #ifdef CMP_R_ERROR_CREATING_PKICONF + {"ERROR_CREATING_PKICONF", ERR_LIB_CMP, CMP_R_ERROR_CREATING_PKICONF}, + #else + {"ERROR_CREATING_PKICONF", 58, 122}, + #endif + #ifdef CMP_R_ERROR_CREATING_POLLREP + {"ERROR_CREATING_POLLREP", ERR_LIB_CMP, CMP_R_ERROR_CREATING_POLLREP}, + #else + {"ERROR_CREATING_POLLREP", 58, 123}, + #endif + #ifdef CMP_R_ERROR_CREATING_POLLREQ + {"ERROR_CREATING_POLLREQ", ERR_LIB_CMP, CMP_R_ERROR_CREATING_POLLREQ}, + #else + {"ERROR_CREATING_POLLREQ", 58, 124}, + #endif + #ifdef CMP_R_ERROR_CREATING_RP + {"ERROR_CREATING_RP", ERR_LIB_CMP, CMP_R_ERROR_CREATING_RP}, + #else + {"ERROR_CREATING_RP", 58, 125}, + #endif + #ifdef CMP_R_ERROR_CREATING_RR + {"ERROR_CREATING_RR", ERR_LIB_CMP, CMP_R_ERROR_CREATING_RR}, + #else + {"ERROR_CREATING_RR", 58, 126}, + #endif + #ifdef CMP_R_ERROR_PARSING_PKISTATUS + {"ERROR_PARSING_PKISTATUS", ERR_LIB_CMP, CMP_R_ERROR_PARSING_PKISTATUS}, + #else + {"ERROR_PARSING_PKISTATUS", 58, 107}, + #endif + #ifdef CMP_R_ERROR_PROCESSING_MESSAGE + {"ERROR_PROCESSING_MESSAGE", ERR_LIB_CMP, CMP_R_ERROR_PROCESSING_MESSAGE}, + #else + {"ERROR_PROCESSING_MESSAGE", 58, 158}, + #endif + #ifdef CMP_R_ERROR_PROTECTING_MESSAGE + {"ERROR_PROTECTING_MESSAGE", ERR_LIB_CMP, CMP_R_ERROR_PROTECTING_MESSAGE}, + #else + {"ERROR_PROTECTING_MESSAGE", 58, 127}, + #endif + #ifdef CMP_R_ERROR_SETTING_CERTHASH + {"ERROR_SETTING_CERTHASH", ERR_LIB_CMP, CMP_R_ERROR_SETTING_CERTHASH}, + #else + {"ERROR_SETTING_CERTHASH", 58, 128}, + #endif + #ifdef CMP_R_ERROR_UNEXPECTED_CERTCONF + {"ERROR_UNEXPECTED_CERTCONF", ERR_LIB_CMP, CMP_R_ERROR_UNEXPECTED_CERTCONF}, + #else + {"ERROR_UNEXPECTED_CERTCONF", 58, 160}, + #endif + #ifdef CMP_R_ERROR_VALIDATING_PROTECTION + {"ERROR_VALIDATING_PROTECTION", ERR_LIB_CMP, CMP_R_ERROR_VALIDATING_PROTECTION}, + #else + {"ERROR_VALIDATING_PROTECTION", 58, 140}, + #endif + #ifdef CMP_R_ERROR_VALIDATING_SIGNATURE + {"ERROR_VALIDATING_SIGNATURE", ERR_LIB_CMP, CMP_R_ERROR_VALIDATING_SIGNATURE}, + #else + {"ERROR_VALIDATING_SIGNATURE", 58, 171}, + #endif + #ifdef CMP_R_FAILED_BUILDING_OWN_CHAIN + {"FAILED_BUILDING_OWN_CHAIN", ERR_LIB_CMP, CMP_R_FAILED_BUILDING_OWN_CHAIN}, + #else + {"FAILED_BUILDING_OWN_CHAIN", 58, 164}, + #endif + #ifdef CMP_R_FAILED_EXTRACTING_PUBKEY + {"FAILED_EXTRACTING_PUBKEY", ERR_LIB_CMP, CMP_R_FAILED_EXTRACTING_PUBKEY}, + #else + {"FAILED_EXTRACTING_PUBKEY", 58, 141}, + #endif + #ifdef CMP_R_FAILURE_OBTAINING_RANDOM + {"FAILURE_OBTAINING_RANDOM", ERR_LIB_CMP, CMP_R_FAILURE_OBTAINING_RANDOM}, + #else + {"FAILURE_OBTAINING_RANDOM", 58, 110}, + #endif + #ifdef CMP_R_FAIL_INFO_OUT_OF_RANGE + {"FAIL_INFO_OUT_OF_RANGE", ERR_LIB_CMP, CMP_R_FAIL_INFO_OUT_OF_RANGE}, + #else + {"FAIL_INFO_OUT_OF_RANGE", 58, 129}, + #endif + #ifdef CMP_R_INVALID_ARGS + {"INVALID_ARGS", ERR_LIB_CMP, CMP_R_INVALID_ARGS}, + #else + {"INVALID_ARGS", 58, 100}, + #endif + #ifdef CMP_R_INVALID_OPTION + {"INVALID_OPTION", ERR_LIB_CMP, CMP_R_INVALID_OPTION}, + #else + {"INVALID_OPTION", 58, 174}, + #endif + #ifdef CMP_R_MISSING_CERTID + {"MISSING_CERTID", ERR_LIB_CMP, CMP_R_MISSING_CERTID}, + #else + {"MISSING_CERTID", 58, 165}, + #endif + #ifdef CMP_R_MISSING_KEY_INPUT_FOR_CREATING_PROTECTION + {"MISSING_KEY_INPUT_FOR_CREATING_PROTECTION", ERR_LIB_CMP, CMP_R_MISSING_KEY_INPUT_FOR_CREATING_PROTECTION}, + #else + {"MISSING_KEY_INPUT_FOR_CREATING_PROTECTION", 58, 130}, + #endif + #ifdef CMP_R_MISSING_KEY_USAGE_DIGITALSIGNATURE + {"MISSING_KEY_USAGE_DIGITALSIGNATURE", ERR_LIB_CMP, CMP_R_MISSING_KEY_USAGE_DIGITALSIGNATURE}, + #else + {"MISSING_KEY_USAGE_DIGITALSIGNATURE", 58, 142}, + #endif + #ifdef CMP_R_MISSING_P10CSR + {"MISSING_P10CSR", ERR_LIB_CMP, CMP_R_MISSING_P10CSR}, + #else + {"MISSING_P10CSR", 58, 121}, + #endif + #ifdef CMP_R_MISSING_PBM_SECRET + {"MISSING_PBM_SECRET", ERR_LIB_CMP, CMP_R_MISSING_PBM_SECRET}, + #else + {"MISSING_PBM_SECRET", 58, 166}, + #endif + #ifdef CMP_R_MISSING_PRIVATE_KEY + {"MISSING_PRIVATE_KEY", ERR_LIB_CMP, CMP_R_MISSING_PRIVATE_KEY}, + #else + {"MISSING_PRIVATE_KEY", 58, 131}, + #endif + #ifdef CMP_R_MISSING_PRIVATE_KEY_FOR_POPO + {"MISSING_PRIVATE_KEY_FOR_POPO", ERR_LIB_CMP, CMP_R_MISSING_PRIVATE_KEY_FOR_POPO}, + #else + {"MISSING_PRIVATE_KEY_FOR_POPO", 58, 190}, + #endif + #ifdef CMP_R_MISSING_PROTECTION + {"MISSING_PROTECTION", ERR_LIB_CMP, CMP_R_MISSING_PROTECTION}, + #else + {"MISSING_PROTECTION", 58, 143}, + #endif + #ifdef CMP_R_MISSING_PUBLIC_KEY + {"MISSING_PUBLIC_KEY", ERR_LIB_CMP, CMP_R_MISSING_PUBLIC_KEY}, + #else + {"MISSING_PUBLIC_KEY", 58, 183}, + #endif + #ifdef CMP_R_MISSING_REFERENCE_CERT + {"MISSING_REFERENCE_CERT", ERR_LIB_CMP, CMP_R_MISSING_REFERENCE_CERT}, + #else + {"MISSING_REFERENCE_CERT", 58, 168}, + #endif + #ifdef CMP_R_MISSING_SECRET + {"MISSING_SECRET", ERR_LIB_CMP, CMP_R_MISSING_SECRET}, + #else + {"MISSING_SECRET", 58, 178}, + #endif + #ifdef CMP_R_MISSING_SENDER_IDENTIFICATION + {"MISSING_SENDER_IDENTIFICATION", ERR_LIB_CMP, CMP_R_MISSING_SENDER_IDENTIFICATION}, + #else + {"MISSING_SENDER_IDENTIFICATION", 58, 111}, + #endif + #ifdef CMP_R_MISSING_TRUST_ANCHOR + {"MISSING_TRUST_ANCHOR", ERR_LIB_CMP, CMP_R_MISSING_TRUST_ANCHOR}, + #else + {"MISSING_TRUST_ANCHOR", 58, 179}, + #endif + #ifdef CMP_R_MISSING_TRUST_STORE + {"MISSING_TRUST_STORE", ERR_LIB_CMP, CMP_R_MISSING_TRUST_STORE}, + #else + {"MISSING_TRUST_STORE", 58, 144}, + #endif + #ifdef CMP_R_MULTIPLE_REQUESTS_NOT_SUPPORTED + {"MULTIPLE_REQUESTS_NOT_SUPPORTED", ERR_LIB_CMP, CMP_R_MULTIPLE_REQUESTS_NOT_SUPPORTED}, + #else + {"MULTIPLE_REQUESTS_NOT_SUPPORTED", 58, 161}, + #endif + #ifdef CMP_R_MULTIPLE_RESPONSES_NOT_SUPPORTED + {"MULTIPLE_RESPONSES_NOT_SUPPORTED", ERR_LIB_CMP, CMP_R_MULTIPLE_RESPONSES_NOT_SUPPORTED}, + #else + {"MULTIPLE_RESPONSES_NOT_SUPPORTED", 58, 170}, + #endif + #ifdef CMP_R_MULTIPLE_SAN_SOURCES + {"MULTIPLE_SAN_SOURCES", ERR_LIB_CMP, CMP_R_MULTIPLE_SAN_SOURCES}, + #else + {"MULTIPLE_SAN_SOURCES", 58, 102}, + #endif + #ifdef CMP_R_NO_STDIO + {"NO_STDIO", ERR_LIB_CMP, CMP_R_NO_STDIO}, + #else + {"NO_STDIO", 58, 194}, + #endif + #ifdef CMP_R_NO_SUITABLE_SENDER_CERT + {"NO_SUITABLE_SENDER_CERT", ERR_LIB_CMP, CMP_R_NO_SUITABLE_SENDER_CERT}, + #else + {"NO_SUITABLE_SENDER_CERT", 58, 145}, + #endif + #ifdef CMP_R_NULL_ARGUMENT + {"NULL_ARGUMENT", ERR_LIB_CMP, CMP_R_NULL_ARGUMENT}, + #else + {"NULL_ARGUMENT", 58, 103}, + #endif + #ifdef CMP_R_PKIBODY_ERROR + {"PKIBODY_ERROR", ERR_LIB_CMP, CMP_R_PKIBODY_ERROR}, + #else + {"PKIBODY_ERROR", 58, 146}, + #endif + #ifdef CMP_R_PKISTATUSINFO_NOT_FOUND + {"PKISTATUSINFO_NOT_FOUND", ERR_LIB_CMP, CMP_R_PKISTATUSINFO_NOT_FOUND}, + #else + {"PKISTATUSINFO_NOT_FOUND", 58, 132}, + #endif + #ifdef CMP_R_POLLING_FAILED + {"POLLING_FAILED", ERR_LIB_CMP, CMP_R_POLLING_FAILED}, + #else + {"POLLING_FAILED", 58, 172}, + #endif + #ifdef CMP_R_POTENTIALLY_INVALID_CERTIFICATE + {"POTENTIALLY_INVALID_CERTIFICATE", ERR_LIB_CMP, CMP_R_POTENTIALLY_INVALID_CERTIFICATE}, + #else + {"POTENTIALLY_INVALID_CERTIFICATE", 58, 147}, + #endif + #ifdef CMP_R_RECEIVED_ERROR + {"RECEIVED_ERROR", ERR_LIB_CMP, CMP_R_RECEIVED_ERROR}, + #else + {"RECEIVED_ERROR", 58, 180}, + #endif + #ifdef CMP_R_RECIPNONCE_UNMATCHED + {"RECIPNONCE_UNMATCHED", ERR_LIB_CMP, CMP_R_RECIPNONCE_UNMATCHED}, + #else + {"RECIPNONCE_UNMATCHED", 58, 148}, + #endif + #ifdef CMP_R_REQUEST_NOT_ACCEPTED + {"REQUEST_NOT_ACCEPTED", ERR_LIB_CMP, CMP_R_REQUEST_NOT_ACCEPTED}, + #else + {"REQUEST_NOT_ACCEPTED", 58, 149}, + #endif + #ifdef CMP_R_REQUEST_REJECTED_BY_SERVER + {"REQUEST_REJECTED_BY_SERVER", ERR_LIB_CMP, CMP_R_REQUEST_REJECTED_BY_SERVER}, + #else + {"REQUEST_REJECTED_BY_SERVER", 58, 182}, + #endif + #ifdef CMP_R_SENDER_GENERALNAME_TYPE_NOT_SUPPORTED + {"SENDER_GENERALNAME_TYPE_NOT_SUPPORTED", ERR_LIB_CMP, CMP_R_SENDER_GENERALNAME_TYPE_NOT_SUPPORTED}, + #else + {"SENDER_GENERALNAME_TYPE_NOT_SUPPORTED", 58, 150}, + #endif + #ifdef CMP_R_SRVCERT_DOES_NOT_VALIDATE_MSG + {"SRVCERT_DOES_NOT_VALIDATE_MSG", ERR_LIB_CMP, CMP_R_SRVCERT_DOES_NOT_VALIDATE_MSG}, + #else + {"SRVCERT_DOES_NOT_VALIDATE_MSG", 58, 151}, + #endif + #ifdef CMP_R_TOTAL_TIMEOUT + {"TOTAL_TIMEOUT", ERR_LIB_CMP, CMP_R_TOTAL_TIMEOUT}, + #else + {"TOTAL_TIMEOUT", 58, 184}, + #endif + #ifdef CMP_R_TRANSACTIONID_UNMATCHED + {"TRANSACTIONID_UNMATCHED", ERR_LIB_CMP, CMP_R_TRANSACTIONID_UNMATCHED}, + #else + {"TRANSACTIONID_UNMATCHED", 58, 152}, + #endif + #ifdef CMP_R_TRANSFER_ERROR + {"TRANSFER_ERROR", ERR_LIB_CMP, CMP_R_TRANSFER_ERROR}, + #else + {"TRANSFER_ERROR", 58, 159}, + #endif + #ifdef CMP_R_UNEXPECTED_PKIBODY + {"UNEXPECTED_PKIBODY", ERR_LIB_CMP, CMP_R_UNEXPECTED_PKIBODY}, + #else + {"UNEXPECTED_PKIBODY", 58, 133}, + #endif + #ifdef CMP_R_UNEXPECTED_PKISTATUS + {"UNEXPECTED_PKISTATUS", ERR_LIB_CMP, CMP_R_UNEXPECTED_PKISTATUS}, + #else + {"UNEXPECTED_PKISTATUS", 58, 185}, + #endif + #ifdef CMP_R_UNEXPECTED_PVNO + {"UNEXPECTED_PVNO", ERR_LIB_CMP, CMP_R_UNEXPECTED_PVNO}, + #else + {"UNEXPECTED_PVNO", 58, 153}, + #endif + #ifdef CMP_R_UNKNOWN_ALGORITHM_ID + {"UNKNOWN_ALGORITHM_ID", ERR_LIB_CMP, CMP_R_UNKNOWN_ALGORITHM_ID}, + #else + {"UNKNOWN_ALGORITHM_ID", 58, 134}, + #endif + #ifdef CMP_R_UNKNOWN_CERT_TYPE + {"UNKNOWN_CERT_TYPE", ERR_LIB_CMP, CMP_R_UNKNOWN_CERT_TYPE}, + #else + {"UNKNOWN_CERT_TYPE", 58, 135}, + #endif + #ifdef CMP_R_UNKNOWN_PKISTATUS + {"UNKNOWN_PKISTATUS", ERR_LIB_CMP, CMP_R_UNKNOWN_PKISTATUS}, + #else + {"UNKNOWN_PKISTATUS", 58, 186}, + #endif + #ifdef CMP_R_UNSUPPORTED_ALGORITHM + {"UNSUPPORTED_ALGORITHM", ERR_LIB_CMP, CMP_R_UNSUPPORTED_ALGORITHM}, + #else + {"UNSUPPORTED_ALGORITHM", 58, 136}, + #endif + #ifdef CMP_R_UNSUPPORTED_KEY_TYPE + {"UNSUPPORTED_KEY_TYPE", ERR_LIB_CMP, CMP_R_UNSUPPORTED_KEY_TYPE}, + #else + {"UNSUPPORTED_KEY_TYPE", 58, 137}, + #endif + #ifdef CMP_R_UNSUPPORTED_PROTECTION_ALG_DHBASEDMAC + {"UNSUPPORTED_PROTECTION_ALG_DHBASEDMAC", ERR_LIB_CMP, CMP_R_UNSUPPORTED_PROTECTION_ALG_DHBASEDMAC}, + #else + {"UNSUPPORTED_PROTECTION_ALG_DHBASEDMAC", 58, 154}, + #endif + #ifdef CMP_R_VALUE_TOO_LARGE + {"VALUE_TOO_LARGE", ERR_LIB_CMP, CMP_R_VALUE_TOO_LARGE}, + #else + {"VALUE_TOO_LARGE", 58, 175}, + #endif + #ifdef CMP_R_VALUE_TOO_SMALL + {"VALUE_TOO_SMALL", ERR_LIB_CMP, CMP_R_VALUE_TOO_SMALL}, + #else + {"VALUE_TOO_SMALL", 58, 177}, + #endif + #ifdef CMP_R_WRONG_ALGORITHM_OID + {"WRONG_ALGORITHM_OID", ERR_LIB_CMP, CMP_R_WRONG_ALGORITHM_OID}, + #else + {"WRONG_ALGORITHM_OID", 58, 138}, + #endif + #ifdef CMP_R_WRONG_CERTID + {"WRONG_CERTID", ERR_LIB_CMP, CMP_R_WRONG_CERTID}, + #else + {"WRONG_CERTID", 58, 189}, + #endif + #ifdef CMP_R_WRONG_CERTID_IN_RP + {"WRONG_CERTID_IN_RP", ERR_LIB_CMP, CMP_R_WRONG_CERTID_IN_RP}, + #else + {"WRONG_CERTID_IN_RP", 58, 187}, + #endif + #ifdef CMP_R_WRONG_PBM_VALUE + {"WRONG_PBM_VALUE", ERR_LIB_CMP, CMP_R_WRONG_PBM_VALUE}, + #else + {"WRONG_PBM_VALUE", 58, 155}, + #endif + #ifdef CMP_R_WRONG_RP_COMPONENT_COUNT + {"WRONG_RP_COMPONENT_COUNT", ERR_LIB_CMP, CMP_R_WRONG_RP_COMPONENT_COUNT}, + #else + {"WRONG_RP_COMPONENT_COUNT", 58, 188}, + #endif + #ifdef CMP_R_WRONG_SERIAL_IN_RP + {"WRONG_SERIAL_IN_RP", ERR_LIB_CMP, CMP_R_WRONG_SERIAL_IN_RP}, + #else + {"WRONG_SERIAL_IN_RP", 58, 173}, + #endif + #ifdef CMS_R_ADD_SIGNER_ERROR + {"ADD_SIGNER_ERROR", ERR_LIB_CMS, CMS_R_ADD_SIGNER_ERROR}, + #else + {"ADD_SIGNER_ERROR", 46, 99}, + #endif + #ifdef CMS_R_ATTRIBUTE_ERROR + {"ATTRIBUTE_ERROR", ERR_LIB_CMS, CMS_R_ATTRIBUTE_ERROR}, + #else + {"ATTRIBUTE_ERROR", 46, 161}, + #endif + #ifdef CMS_R_CERTIFICATE_ALREADY_PRESENT + {"CERTIFICATE_ALREADY_PRESENT", ERR_LIB_CMS, CMS_R_CERTIFICATE_ALREADY_PRESENT}, + #else + {"CERTIFICATE_ALREADY_PRESENT", 46, 175}, + #endif + #ifdef CMS_R_CERTIFICATE_HAS_NO_KEYID + {"CERTIFICATE_HAS_NO_KEYID", ERR_LIB_CMS, CMS_R_CERTIFICATE_HAS_NO_KEYID}, + #else + {"CERTIFICATE_HAS_NO_KEYID", 46, 160}, + #endif + #ifdef CMS_R_CERTIFICATE_VERIFY_ERROR + {"CERTIFICATE_VERIFY_ERROR", ERR_LIB_CMS, CMS_R_CERTIFICATE_VERIFY_ERROR}, + #else + {"CERTIFICATE_VERIFY_ERROR", 46, 100}, + #endif + #ifdef CMS_R_CIPHER_AEAD_SET_TAG_ERROR + {"CIPHER_AEAD_SET_TAG_ERROR", ERR_LIB_CMS, CMS_R_CIPHER_AEAD_SET_TAG_ERROR}, + #else + {"CIPHER_AEAD_SET_TAG_ERROR", 46, 184}, + #endif + #ifdef CMS_R_CIPHER_GET_TAG + {"CIPHER_GET_TAG", ERR_LIB_CMS, CMS_R_CIPHER_GET_TAG}, + #else + {"CIPHER_GET_TAG", 46, 185}, + #endif + #ifdef CMS_R_CIPHER_INITIALISATION_ERROR + {"CIPHER_INITIALISATION_ERROR", ERR_LIB_CMS, CMS_R_CIPHER_INITIALISATION_ERROR}, + #else + {"CIPHER_INITIALISATION_ERROR", 46, 101}, + #endif + #ifdef CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR + {"CIPHER_PARAMETER_INITIALISATION_ERROR", ERR_LIB_CMS, CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR}, + #else + {"CIPHER_PARAMETER_INITIALISATION_ERROR", 46, 102}, + #endif + #ifdef CMS_R_CMS_DATAFINAL_ERROR + {"CMS_DATAFINAL_ERROR", ERR_LIB_CMS, CMS_R_CMS_DATAFINAL_ERROR}, + #else + {"CMS_DATAFINAL_ERROR", 46, 103}, + #endif + #ifdef CMS_R_CMS_LIB + {"CMS_LIB", ERR_LIB_CMS, CMS_R_CMS_LIB}, + #else + {"CMS_LIB", 46, 104}, + #endif + #ifdef CMS_R_CONTENTIDENTIFIER_MISMATCH + {"CONTENTIDENTIFIER_MISMATCH", ERR_LIB_CMS, CMS_R_CONTENTIDENTIFIER_MISMATCH}, + #else + {"CONTENTIDENTIFIER_MISMATCH", 46, 170}, + #endif + #ifdef CMS_R_CONTENT_NOT_FOUND + {"CONTENT_NOT_FOUND", ERR_LIB_CMS, CMS_R_CONTENT_NOT_FOUND}, + #else + {"CONTENT_NOT_FOUND", 46, 105}, + #endif + #ifdef CMS_R_CONTENT_TYPE_MISMATCH + {"CONTENT_TYPE_MISMATCH", ERR_LIB_CMS, CMS_R_CONTENT_TYPE_MISMATCH}, + #else + {"CONTENT_TYPE_MISMATCH", 46, 171}, + #endif + #ifdef CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA + {"CONTENT_TYPE_NOT_COMPRESSED_DATA", ERR_LIB_CMS, CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA}, + #else + {"CONTENT_TYPE_NOT_COMPRESSED_DATA", 46, 106}, + #endif + #ifdef CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA + {"CONTENT_TYPE_NOT_ENVELOPED_DATA", ERR_LIB_CMS, CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA}, + #else + {"CONTENT_TYPE_NOT_ENVELOPED_DATA", 46, 107}, + #endif + #ifdef CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA + {"CONTENT_TYPE_NOT_SIGNED_DATA", ERR_LIB_CMS, CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA}, + #else + {"CONTENT_TYPE_NOT_SIGNED_DATA", 46, 108}, + #endif + #ifdef CMS_R_CONTENT_VERIFY_ERROR + {"CONTENT_VERIFY_ERROR", ERR_LIB_CMS, CMS_R_CONTENT_VERIFY_ERROR}, + #else + {"CONTENT_VERIFY_ERROR", 46, 109}, + #endif + #ifdef CMS_R_CTRL_ERROR + {"CTRL_ERROR", ERR_LIB_CMS, CMS_R_CTRL_ERROR}, + #else + {"CTRL_ERROR", 46, 110}, + #endif + #ifdef CMS_R_CTRL_FAILURE + {"CTRL_FAILURE", ERR_LIB_CMS, CMS_R_CTRL_FAILURE}, + #else + {"CTRL_FAILURE", 46, 111}, + #endif + #ifdef CMS_R_DECODE_ERROR + {"DECODE_ERROR", ERR_LIB_CMS, CMS_R_DECODE_ERROR}, + #else + {"DECODE_ERROR", 46, 187}, + #endif + #ifdef CMS_R_DECRYPT_ERROR + {"DECRYPT_ERROR", ERR_LIB_CMS, CMS_R_DECRYPT_ERROR}, + #else + {"DECRYPT_ERROR", 46, 112}, + #endif + #ifdef CMS_R_ERROR_GETTING_PUBLIC_KEY + {"ERROR_GETTING_PUBLIC_KEY", ERR_LIB_CMS, CMS_R_ERROR_GETTING_PUBLIC_KEY}, + #else + {"ERROR_GETTING_PUBLIC_KEY", 46, 113}, + #endif + #ifdef CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE + {"ERROR_READING_MESSAGEDIGEST_ATTRIBUTE", ERR_LIB_CMS, CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE}, + #else + {"ERROR_READING_MESSAGEDIGEST_ATTRIBUTE", 46, 114}, + #endif + #ifdef CMS_R_ERROR_SETTING_KEY + {"ERROR_SETTING_KEY", ERR_LIB_CMS, CMS_R_ERROR_SETTING_KEY}, + #else + {"ERROR_SETTING_KEY", 46, 115}, + #endif + #ifdef CMS_R_ERROR_SETTING_RECIPIENTINFO + {"ERROR_SETTING_RECIPIENTINFO", ERR_LIB_CMS, CMS_R_ERROR_SETTING_RECIPIENTINFO}, + #else + {"ERROR_SETTING_RECIPIENTINFO", 46, 116}, + #endif + #ifdef CMS_R_ESS_SIGNING_CERTID_MISMATCH_ERROR + {"ESS_SIGNING_CERTID_MISMATCH_ERROR", ERR_LIB_CMS, CMS_R_ESS_SIGNING_CERTID_MISMATCH_ERROR}, + #else + {"ESS_SIGNING_CERTID_MISMATCH_ERROR", 46, 183}, + #endif + #ifdef CMS_R_INVALID_ENCRYPTED_KEY_LENGTH + {"INVALID_ENCRYPTED_KEY_LENGTH", ERR_LIB_CMS, CMS_R_INVALID_ENCRYPTED_KEY_LENGTH}, + #else + {"INVALID_ENCRYPTED_KEY_LENGTH", 46, 117}, + #endif + #ifdef CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER + {"INVALID_KEY_ENCRYPTION_PARAMETER", ERR_LIB_CMS, CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER}, + #else + {"INVALID_KEY_ENCRYPTION_PARAMETER", 46, 176}, + #endif + #ifdef CMS_R_INVALID_KEY_LENGTH + {"INVALID_KEY_LENGTH", ERR_LIB_CMS, CMS_R_INVALID_KEY_LENGTH}, + #else + {"INVALID_KEY_LENGTH", 46, 118}, + #endif + #ifdef CMS_R_INVALID_LABEL + {"INVALID_LABEL", ERR_LIB_CMS, CMS_R_INVALID_LABEL}, + #else + {"INVALID_LABEL", 46, 190}, + #endif + #ifdef CMS_R_INVALID_OAEP_PARAMETERS + {"INVALID_OAEP_PARAMETERS", ERR_LIB_CMS, CMS_R_INVALID_OAEP_PARAMETERS}, + #else + {"INVALID_OAEP_PARAMETERS", 46, 191}, + #endif + #ifdef CMS_R_KDF_PARAMETER_ERROR + {"KDF_PARAMETER_ERROR", ERR_LIB_CMS, CMS_R_KDF_PARAMETER_ERROR}, + #else + {"KDF_PARAMETER_ERROR", 46, 186}, + #endif + #ifdef CMS_R_MD_BIO_INIT_ERROR + {"MD_BIO_INIT_ERROR", ERR_LIB_CMS, CMS_R_MD_BIO_INIT_ERROR}, + #else + {"MD_BIO_INIT_ERROR", 46, 119}, + #endif + #ifdef CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH + {"MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH", ERR_LIB_CMS, CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH}, + #else + {"MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH", 46, 120}, + #endif + #ifdef CMS_R_MESSAGEDIGEST_WRONG_LENGTH + {"MESSAGEDIGEST_WRONG_LENGTH", ERR_LIB_CMS, CMS_R_MESSAGEDIGEST_WRONG_LENGTH}, + #else + {"MESSAGEDIGEST_WRONG_LENGTH", 46, 121}, + #endif + #ifdef CMS_R_MSGSIGDIGEST_ERROR + {"MSGSIGDIGEST_ERROR", ERR_LIB_CMS, CMS_R_MSGSIGDIGEST_ERROR}, + #else + {"MSGSIGDIGEST_ERROR", 46, 172}, + #endif + #ifdef CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE + {"MSGSIGDIGEST_VERIFICATION_FAILURE", ERR_LIB_CMS, CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE}, + #else + {"MSGSIGDIGEST_VERIFICATION_FAILURE", 46, 162}, + #endif + #ifdef CMS_R_MSGSIGDIGEST_WRONG_LENGTH + {"MSGSIGDIGEST_WRONG_LENGTH", ERR_LIB_CMS, CMS_R_MSGSIGDIGEST_WRONG_LENGTH}, + #else + {"MSGSIGDIGEST_WRONG_LENGTH", 46, 163}, + #endif + #ifdef CMS_R_NEED_ONE_SIGNER + {"NEED_ONE_SIGNER", ERR_LIB_CMS, CMS_R_NEED_ONE_SIGNER}, + #else + {"NEED_ONE_SIGNER", 46, 164}, + #endif + #ifdef CMS_R_NOT_A_SIGNED_RECEIPT + {"NOT_A_SIGNED_RECEIPT", ERR_LIB_CMS, CMS_R_NOT_A_SIGNED_RECEIPT}, + #else + {"NOT_A_SIGNED_RECEIPT", 46, 165}, + #endif + #ifdef CMS_R_NOT_ENCRYPTED_DATA + {"NOT_ENCRYPTED_DATA", ERR_LIB_CMS, CMS_R_NOT_ENCRYPTED_DATA}, + #else + {"NOT_ENCRYPTED_DATA", 46, 122}, + #endif + #ifdef CMS_R_NOT_KEK + {"NOT_KEK", ERR_LIB_CMS, CMS_R_NOT_KEK}, + #else + {"NOT_KEK", 46, 123}, + #endif + #ifdef CMS_R_NOT_KEY_AGREEMENT + {"NOT_KEY_AGREEMENT", ERR_LIB_CMS, CMS_R_NOT_KEY_AGREEMENT}, + #else + {"NOT_KEY_AGREEMENT", 46, 181}, + #endif + #ifdef CMS_R_NOT_KEY_TRANSPORT + {"NOT_KEY_TRANSPORT", ERR_LIB_CMS, CMS_R_NOT_KEY_TRANSPORT}, + #else + {"NOT_KEY_TRANSPORT", 46, 124}, + #endif + #ifdef CMS_R_NOT_PWRI + {"NOT_PWRI", ERR_LIB_CMS, CMS_R_NOT_PWRI}, + #else + {"NOT_PWRI", 46, 177}, + #endif + #ifdef CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE + {"NOT_SUPPORTED_FOR_THIS_KEY_TYPE", ERR_LIB_CMS, CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE}, + #else + {"NOT_SUPPORTED_FOR_THIS_KEY_TYPE", 46, 125}, + #endif + #ifdef CMS_R_NO_CIPHER + {"NO_CIPHER", ERR_LIB_CMS, CMS_R_NO_CIPHER}, + #else + {"NO_CIPHER", 46, 126}, + #endif + #ifdef CMS_R_NO_CONTENT + {"NO_CONTENT", ERR_LIB_CMS, CMS_R_NO_CONTENT}, + #else + {"NO_CONTENT", 46, 127}, + #endif + #ifdef CMS_R_NO_CONTENT_TYPE + {"NO_CONTENT_TYPE", ERR_LIB_CMS, CMS_R_NO_CONTENT_TYPE}, + #else + {"NO_CONTENT_TYPE", 46, 173}, + #endif + #ifdef CMS_R_NO_DEFAULT_DIGEST + {"NO_DEFAULT_DIGEST", ERR_LIB_CMS, CMS_R_NO_DEFAULT_DIGEST}, + #else + {"NO_DEFAULT_DIGEST", 46, 128}, + #endif + #ifdef CMS_R_NO_DIGEST_SET + {"NO_DIGEST_SET", ERR_LIB_CMS, CMS_R_NO_DIGEST_SET}, + #else + {"NO_DIGEST_SET", 46, 129}, + #endif + #ifdef CMS_R_NO_KEY + {"NO_KEY", ERR_LIB_CMS, CMS_R_NO_KEY}, + #else + {"NO_KEY", 46, 130}, + #endif + #ifdef CMS_R_NO_KEY_OR_CERT + {"NO_KEY_OR_CERT", ERR_LIB_CMS, CMS_R_NO_KEY_OR_CERT}, + #else + {"NO_KEY_OR_CERT", 46, 174}, + #endif + #ifdef CMS_R_NO_MATCHING_DIGEST + {"NO_MATCHING_DIGEST", ERR_LIB_CMS, CMS_R_NO_MATCHING_DIGEST}, + #else + {"NO_MATCHING_DIGEST", 46, 131}, + #endif + #ifdef CMS_R_NO_MATCHING_RECIPIENT + {"NO_MATCHING_RECIPIENT", ERR_LIB_CMS, CMS_R_NO_MATCHING_RECIPIENT}, + #else + {"NO_MATCHING_RECIPIENT", 46, 132}, + #endif + #ifdef CMS_R_NO_MATCHING_SIGNATURE + {"NO_MATCHING_SIGNATURE", ERR_LIB_CMS, CMS_R_NO_MATCHING_SIGNATURE}, + #else + {"NO_MATCHING_SIGNATURE", 46, 166}, + #endif + #ifdef CMS_R_NO_MSGSIGDIGEST + {"NO_MSGSIGDIGEST", ERR_LIB_CMS, CMS_R_NO_MSGSIGDIGEST}, + #else + {"NO_MSGSIGDIGEST", 46, 167}, + #endif + #ifdef CMS_R_NO_PASSWORD + {"NO_PASSWORD", ERR_LIB_CMS, CMS_R_NO_PASSWORD}, + #else + {"NO_PASSWORD", 46, 178}, + #endif + #ifdef CMS_R_NO_PRIVATE_KEY + {"NO_PRIVATE_KEY", ERR_LIB_CMS, CMS_R_NO_PRIVATE_KEY}, + #else + {"NO_PRIVATE_KEY", 46, 133}, + #endif + #ifdef CMS_R_NO_PUBLIC_KEY + {"NO_PUBLIC_KEY", ERR_LIB_CMS, CMS_R_NO_PUBLIC_KEY}, + #else + {"NO_PUBLIC_KEY", 46, 134}, + #endif + #ifdef CMS_R_NO_RECEIPT_REQUEST + {"NO_RECEIPT_REQUEST", ERR_LIB_CMS, CMS_R_NO_RECEIPT_REQUEST}, + #else + {"NO_RECEIPT_REQUEST", 46, 168}, + #endif + #ifdef CMS_R_NO_SIGNERS + {"NO_SIGNERS", ERR_LIB_CMS, CMS_R_NO_SIGNERS}, + #else + {"NO_SIGNERS", 46, 135}, + #endif + #ifdef CMS_R_PEER_KEY_ERROR + {"PEER_KEY_ERROR", ERR_LIB_CMS, CMS_R_PEER_KEY_ERROR}, + #else + {"PEER_KEY_ERROR", 46, 188}, + #endif + #ifdef CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE + {"PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE", ERR_LIB_CMS, CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE}, + #else + {"PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE", 46, 136}, + #endif + #ifdef CMS_R_RECEIPT_DECODE_ERROR + {"RECEIPT_DECODE_ERROR", ERR_LIB_CMS, CMS_R_RECEIPT_DECODE_ERROR}, + #else + {"RECEIPT_DECODE_ERROR", 46, 169}, + #endif + #ifdef CMS_R_RECIPIENT_ERROR + {"RECIPIENT_ERROR", ERR_LIB_CMS, CMS_R_RECIPIENT_ERROR}, + #else + {"RECIPIENT_ERROR", 46, 137}, + #endif + #ifdef CMS_R_SHARED_INFO_ERROR + {"SHARED_INFO_ERROR", ERR_LIB_CMS, CMS_R_SHARED_INFO_ERROR}, + #else + {"SHARED_INFO_ERROR", 46, 189}, + #endif + #ifdef CMS_R_SIGNER_CERTIFICATE_NOT_FOUND + {"SIGNER_CERTIFICATE_NOT_FOUND", ERR_LIB_CMS, CMS_R_SIGNER_CERTIFICATE_NOT_FOUND}, + #else + {"SIGNER_CERTIFICATE_NOT_FOUND", 46, 138}, + #endif + #ifdef CMS_R_SIGNFINAL_ERROR + {"SIGNFINAL_ERROR", ERR_LIB_CMS, CMS_R_SIGNFINAL_ERROR}, + #else + {"SIGNFINAL_ERROR", 46, 139}, + #endif + #ifdef CMS_R_SMIME_TEXT_ERROR + {"SMIME_TEXT_ERROR", ERR_LIB_CMS, CMS_R_SMIME_TEXT_ERROR}, + #else + {"SMIME_TEXT_ERROR", 46, 140}, + #endif + #ifdef CMS_R_STORE_INIT_ERROR + {"STORE_INIT_ERROR", ERR_LIB_CMS, CMS_R_STORE_INIT_ERROR}, + #else + {"STORE_INIT_ERROR", 46, 141}, + #endif + #ifdef CMS_R_TYPE_NOT_COMPRESSED_DATA + {"TYPE_NOT_COMPRESSED_DATA", ERR_LIB_CMS, CMS_R_TYPE_NOT_COMPRESSED_DATA}, + #else + {"TYPE_NOT_COMPRESSED_DATA", 46, 142}, + #endif + #ifdef CMS_R_TYPE_NOT_DATA + {"TYPE_NOT_DATA", ERR_LIB_CMS, CMS_R_TYPE_NOT_DATA}, + #else + {"TYPE_NOT_DATA", 46, 143}, + #endif + #ifdef CMS_R_TYPE_NOT_DIGESTED_DATA + {"TYPE_NOT_DIGESTED_DATA", ERR_LIB_CMS, CMS_R_TYPE_NOT_DIGESTED_DATA}, + #else + {"TYPE_NOT_DIGESTED_DATA", 46, 144}, + #endif + #ifdef CMS_R_TYPE_NOT_ENCRYPTED_DATA + {"TYPE_NOT_ENCRYPTED_DATA", ERR_LIB_CMS, CMS_R_TYPE_NOT_ENCRYPTED_DATA}, + #else + {"TYPE_NOT_ENCRYPTED_DATA", 46, 145}, + #endif + #ifdef CMS_R_TYPE_NOT_ENVELOPED_DATA + {"TYPE_NOT_ENVELOPED_DATA", ERR_LIB_CMS, CMS_R_TYPE_NOT_ENVELOPED_DATA}, + #else + {"TYPE_NOT_ENVELOPED_DATA", 46, 146}, + #endif + #ifdef CMS_R_UNABLE_TO_FINALIZE_CONTEXT + {"UNABLE_TO_FINALIZE_CONTEXT", ERR_LIB_CMS, CMS_R_UNABLE_TO_FINALIZE_CONTEXT}, + #else + {"UNABLE_TO_FINALIZE_CONTEXT", 46, 147}, + #endif + #ifdef CMS_R_UNKNOWN_CIPHER + {"UNKNOWN_CIPHER", ERR_LIB_CMS, CMS_R_UNKNOWN_CIPHER}, + #else + {"UNKNOWN_CIPHER", 46, 148}, + #endif + #ifdef CMS_R_UNKNOWN_DIGEST_ALGORITHM + {"UNKNOWN_DIGEST_ALGORITHM", ERR_LIB_CMS, CMS_R_UNKNOWN_DIGEST_ALGORITHM}, + #else + {"UNKNOWN_DIGEST_ALGORITHM", 46, 149}, + #endif + #ifdef CMS_R_UNKNOWN_ID + {"UNKNOWN_ID", ERR_LIB_CMS, CMS_R_UNKNOWN_ID}, + #else + {"UNKNOWN_ID", 46, 150}, + #endif + #ifdef CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM + {"UNSUPPORTED_COMPRESSION_ALGORITHM", ERR_LIB_CMS, CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM}, + #else + {"UNSUPPORTED_COMPRESSION_ALGORITHM", 46, 151}, + #endif + #ifdef CMS_R_UNSUPPORTED_CONTENT_ENCRYPTION_ALGORITHM + {"UNSUPPORTED_CONTENT_ENCRYPTION_ALGORITHM", ERR_LIB_CMS, CMS_R_UNSUPPORTED_CONTENT_ENCRYPTION_ALGORITHM}, + #else + {"UNSUPPORTED_CONTENT_ENCRYPTION_ALGORITHM", 46, 194}, + #endif + #ifdef CMS_R_UNSUPPORTED_CONTENT_TYPE + {"UNSUPPORTED_CONTENT_TYPE", ERR_LIB_CMS, CMS_R_UNSUPPORTED_CONTENT_TYPE}, + #else + {"UNSUPPORTED_CONTENT_TYPE", 46, 152}, + #endif + #ifdef CMS_R_UNSUPPORTED_ENCRYPTION_TYPE + {"UNSUPPORTED_ENCRYPTION_TYPE", ERR_LIB_CMS, CMS_R_UNSUPPORTED_ENCRYPTION_TYPE}, + #else + {"UNSUPPORTED_ENCRYPTION_TYPE", 46, 192}, + #endif + #ifdef CMS_R_UNSUPPORTED_KEK_ALGORITHM + {"UNSUPPORTED_KEK_ALGORITHM", ERR_LIB_CMS, CMS_R_UNSUPPORTED_KEK_ALGORITHM}, + #else + {"UNSUPPORTED_KEK_ALGORITHM", 46, 153}, + #endif + #ifdef CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM + {"UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM", ERR_LIB_CMS, CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM}, + #else + {"UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM", 46, 179}, + #endif + #ifdef CMS_R_UNSUPPORTED_LABEL_SOURCE + {"UNSUPPORTED_LABEL_SOURCE", ERR_LIB_CMS, CMS_R_UNSUPPORTED_LABEL_SOURCE}, + #else + {"UNSUPPORTED_LABEL_SOURCE", 46, 193}, + #endif + #ifdef CMS_R_UNSUPPORTED_RECIPIENTINFO_TYPE + {"UNSUPPORTED_RECIPIENTINFO_TYPE", ERR_LIB_CMS, CMS_R_UNSUPPORTED_RECIPIENTINFO_TYPE}, + #else + {"UNSUPPORTED_RECIPIENTINFO_TYPE", 46, 155}, + #endif + #ifdef CMS_R_UNSUPPORTED_RECIPIENT_TYPE + {"UNSUPPORTED_RECIPIENT_TYPE", ERR_LIB_CMS, CMS_R_UNSUPPORTED_RECIPIENT_TYPE}, + #else + {"UNSUPPORTED_RECIPIENT_TYPE", 46, 154}, + #endif + #ifdef CMS_R_UNSUPPORTED_TYPE + {"UNSUPPORTED_TYPE", ERR_LIB_CMS, CMS_R_UNSUPPORTED_TYPE}, + #else + {"UNSUPPORTED_TYPE", 46, 156}, + #endif + #ifdef CMS_R_UNWRAP_ERROR + {"UNWRAP_ERROR", ERR_LIB_CMS, CMS_R_UNWRAP_ERROR}, + #else + {"UNWRAP_ERROR", 46, 157}, + #endif + #ifdef CMS_R_UNWRAP_FAILURE + {"UNWRAP_FAILURE", ERR_LIB_CMS, CMS_R_UNWRAP_FAILURE}, + #else + {"UNWRAP_FAILURE", 46, 180}, + #endif + #ifdef CMS_R_VERIFICATION_FAILURE + {"VERIFICATION_FAILURE", ERR_LIB_CMS, CMS_R_VERIFICATION_FAILURE}, + #else + {"VERIFICATION_FAILURE", 46, 158}, + #endif + #ifdef CMS_R_WRAP_ERROR + {"WRAP_ERROR", ERR_LIB_CMS, CMS_R_WRAP_ERROR}, + #else + {"WRAP_ERROR", 46, 159}, + #endif + #ifdef COMP_R_ZLIB_DEFLATE_ERROR + {"ZLIB_DEFLATE_ERROR", ERR_LIB_COMP, COMP_R_ZLIB_DEFLATE_ERROR}, + #else + {"ZLIB_DEFLATE_ERROR", 41, 99}, + #endif + #ifdef COMP_R_ZLIB_INFLATE_ERROR + {"ZLIB_INFLATE_ERROR", ERR_LIB_COMP, COMP_R_ZLIB_INFLATE_ERROR}, + #else + {"ZLIB_INFLATE_ERROR", 41, 100}, + #endif + #ifdef COMP_R_ZLIB_NOT_SUPPORTED + {"ZLIB_NOT_SUPPORTED", ERR_LIB_COMP, COMP_R_ZLIB_NOT_SUPPORTED}, + #else + {"ZLIB_NOT_SUPPORTED", 41, 101}, + #endif + #ifdef CONF_R_ERROR_LOADING_DSO + {"ERROR_LOADING_DSO", ERR_LIB_CONF, CONF_R_ERROR_LOADING_DSO}, + #else + {"ERROR_LOADING_DSO", 14, 110}, + #endif + #ifdef CONF_R_INVALID_PRAGMA + {"INVALID_PRAGMA", ERR_LIB_CONF, CONF_R_INVALID_PRAGMA}, + #else + {"INVALID_PRAGMA", 14, 122}, + #endif + #ifdef CONF_R_LIST_CANNOT_BE_NULL + {"LIST_CANNOT_BE_NULL", ERR_LIB_CONF, CONF_R_LIST_CANNOT_BE_NULL}, + #else + {"LIST_CANNOT_BE_NULL", 14, 115}, + #endif + #ifdef CONF_R_MANDATORY_BRACES_IN_VARIABLE_EXPANSION + {"MANDATORY_BRACES_IN_VARIABLE_EXPANSION", ERR_LIB_CONF, CONF_R_MANDATORY_BRACES_IN_VARIABLE_EXPANSION}, + #else + {"MANDATORY_BRACES_IN_VARIABLE_EXPANSION", 14, 123}, + #endif + #ifdef CONF_R_MISSING_CLOSE_SQUARE_BRACKET + {"MISSING_CLOSE_SQUARE_BRACKET", ERR_LIB_CONF, CONF_R_MISSING_CLOSE_SQUARE_BRACKET}, + #else + {"MISSING_CLOSE_SQUARE_BRACKET", 14, 100}, + #endif + #ifdef CONF_R_MISSING_EQUAL_SIGN + {"MISSING_EQUAL_SIGN", ERR_LIB_CONF, CONF_R_MISSING_EQUAL_SIGN}, + #else + {"MISSING_EQUAL_SIGN", 14, 101}, + #endif + #ifdef CONF_R_MISSING_INIT_FUNCTION + {"MISSING_INIT_FUNCTION", ERR_LIB_CONF, CONF_R_MISSING_INIT_FUNCTION}, + #else + {"MISSING_INIT_FUNCTION", 14, 112}, + #endif + #ifdef CONF_R_MODULE_INITIALIZATION_ERROR + {"MODULE_INITIALIZATION_ERROR", ERR_LIB_CONF, CONF_R_MODULE_INITIALIZATION_ERROR}, + #else + {"MODULE_INITIALIZATION_ERROR", 14, 109}, + #endif + #ifdef CONF_R_NO_CLOSE_BRACE + {"NO_CLOSE_BRACE", ERR_LIB_CONF, CONF_R_NO_CLOSE_BRACE}, + #else + {"NO_CLOSE_BRACE", 14, 102}, + #endif + #ifdef CONF_R_NO_CONF + {"NO_CONF", ERR_LIB_CONF, CONF_R_NO_CONF}, + #else + {"NO_CONF", 14, 105}, + #endif + #ifdef CONF_R_NO_CONF_OR_ENVIRONMENT_VARIABLE + {"NO_CONF_OR_ENVIRONMENT_VARIABLE", ERR_LIB_CONF, CONF_R_NO_CONF_OR_ENVIRONMENT_VARIABLE}, + #else + {"NO_CONF_OR_ENVIRONMENT_VARIABLE", 14, 106}, + #endif + #ifdef CONF_R_NO_SECTION + {"NO_SECTION", ERR_LIB_CONF, CONF_R_NO_SECTION}, + #else + {"NO_SECTION", 14, 107}, + #endif + #ifdef CONF_R_NO_SUCH_FILE + {"NO_SUCH_FILE", ERR_LIB_CONF, CONF_R_NO_SUCH_FILE}, + #else + {"NO_SUCH_FILE", 14, 114}, + #endif + #ifdef CONF_R_NO_VALUE + {"NO_VALUE", ERR_LIB_CONF, CONF_R_NO_VALUE}, + #else + {"NO_VALUE", 14, 108}, + #endif + #ifdef CONF_R_NUMBER_TOO_LARGE + {"NUMBER_TOO_LARGE", ERR_LIB_CONF, CONF_R_NUMBER_TOO_LARGE}, + #else + {"NUMBER_TOO_LARGE", 14, 121}, + #endif + #ifdef CONF_R_OPENSSL_CONF_REFERENCES_MISSING_SECTION + {"OPENSSL_CONF_REFERENCES_MISSING_SECTION", ERR_LIB_CONF, CONF_R_OPENSSL_CONF_REFERENCES_MISSING_SECTION}, + #else + {"OPENSSL_CONF_REFERENCES_MISSING_SECTION", 14, 124}, + #endif + #ifdef CONF_R_RECURSIVE_DIRECTORY_INCLUDE + {"RECURSIVE_DIRECTORY_INCLUDE", ERR_LIB_CONF, CONF_R_RECURSIVE_DIRECTORY_INCLUDE}, + #else + {"RECURSIVE_DIRECTORY_INCLUDE", 14, 111}, + #endif + #ifdef CONF_R_RELATIVE_PATH + {"RELATIVE_PATH", ERR_LIB_CONF, CONF_R_RELATIVE_PATH}, + #else + {"RELATIVE_PATH", 14, 125}, + #endif + #ifdef CONF_R_SSL_COMMAND_SECTION_EMPTY + {"SSL_COMMAND_SECTION_EMPTY", ERR_LIB_CONF, CONF_R_SSL_COMMAND_SECTION_EMPTY}, + #else + {"SSL_COMMAND_SECTION_EMPTY", 14, 117}, + #endif + #ifdef CONF_R_SSL_COMMAND_SECTION_NOT_FOUND + {"SSL_COMMAND_SECTION_NOT_FOUND", ERR_LIB_CONF, CONF_R_SSL_COMMAND_SECTION_NOT_FOUND}, + #else + {"SSL_COMMAND_SECTION_NOT_FOUND", 14, 118}, + #endif + #ifdef CONF_R_SSL_SECTION_EMPTY + {"SSL_SECTION_EMPTY", ERR_LIB_CONF, CONF_R_SSL_SECTION_EMPTY}, + #else + {"SSL_SECTION_EMPTY", 14, 119}, + #endif + #ifdef CONF_R_SSL_SECTION_NOT_FOUND + {"SSL_SECTION_NOT_FOUND", ERR_LIB_CONF, CONF_R_SSL_SECTION_NOT_FOUND}, + #else + {"SSL_SECTION_NOT_FOUND", 14, 120}, + #endif + #ifdef CONF_R_UNABLE_TO_CREATE_NEW_SECTION + {"UNABLE_TO_CREATE_NEW_SECTION", ERR_LIB_CONF, CONF_R_UNABLE_TO_CREATE_NEW_SECTION}, + #else + {"UNABLE_TO_CREATE_NEW_SECTION", 14, 103}, + #endif + #ifdef CONF_R_UNKNOWN_MODULE_NAME + {"UNKNOWN_MODULE_NAME", ERR_LIB_CONF, CONF_R_UNKNOWN_MODULE_NAME}, + #else + {"UNKNOWN_MODULE_NAME", 14, 113}, + #endif + #ifdef CONF_R_VARIABLE_EXPANSION_TOO_LONG + {"VARIABLE_EXPANSION_TOO_LONG", ERR_LIB_CONF, CONF_R_VARIABLE_EXPANSION_TOO_LONG}, + #else + {"VARIABLE_EXPANSION_TOO_LONG", 14, 116}, + #endif + #ifdef CONF_R_VARIABLE_HAS_NO_VALUE + {"VARIABLE_HAS_NO_VALUE", ERR_LIB_CONF, CONF_R_VARIABLE_HAS_NO_VALUE}, + #else + {"VARIABLE_HAS_NO_VALUE", 14, 104}, + #endif + #ifdef CRMF_R_BAD_PBM_ITERATIONCOUNT + {"BAD_PBM_ITERATIONCOUNT", ERR_LIB_CRMF, CRMF_R_BAD_PBM_ITERATIONCOUNT}, + #else + {"BAD_PBM_ITERATIONCOUNT", 56, 100}, + #endif + #ifdef CRMF_R_CRMFERROR + {"CRMFERROR", ERR_LIB_CRMF, CRMF_R_CRMFERROR}, + #else + {"CRMFERROR", 56, 102}, + #endif + #ifdef CRMF_R_ERROR + {"ERROR", ERR_LIB_CRMF, CRMF_R_ERROR}, + #else + {"ERROR", 56, 103}, + #endif + #ifdef CRMF_R_ERROR_DECODING_CERTIFICATE + {"ERROR_DECODING_CERTIFICATE", ERR_LIB_CRMF, CRMF_R_ERROR_DECODING_CERTIFICATE}, + #else + {"ERROR_DECODING_CERTIFICATE", 56, 104}, + #endif + #ifdef CRMF_R_ERROR_DECRYPTING_CERTIFICATE + {"ERROR_DECRYPTING_CERTIFICATE", ERR_LIB_CRMF, CRMF_R_ERROR_DECRYPTING_CERTIFICATE}, + #else + {"ERROR_DECRYPTING_CERTIFICATE", 56, 105}, + #endif + #ifdef CRMF_R_ERROR_DECRYPTING_SYMMETRIC_KEY + {"ERROR_DECRYPTING_SYMMETRIC_KEY", ERR_LIB_CRMF, CRMF_R_ERROR_DECRYPTING_SYMMETRIC_KEY}, + #else + {"ERROR_DECRYPTING_SYMMETRIC_KEY", 56, 106}, + #endif + #ifdef CRMF_R_FAILURE_OBTAINING_RANDOM + {"FAILURE_OBTAINING_RANDOM", ERR_LIB_CRMF, CRMF_R_FAILURE_OBTAINING_RANDOM}, + #else + {"FAILURE_OBTAINING_RANDOM", 56, 107}, + #endif + #ifdef CRMF_R_ITERATIONCOUNT_BELOW_100 + {"ITERATIONCOUNT_BELOW_100", ERR_LIB_CRMF, CRMF_R_ITERATIONCOUNT_BELOW_100}, + #else + {"ITERATIONCOUNT_BELOW_100", 56, 108}, + #endif + #ifdef CRMF_R_MALFORMED_IV + {"MALFORMED_IV", ERR_LIB_CRMF, CRMF_R_MALFORMED_IV}, + #else + {"MALFORMED_IV", 56, 101}, + #endif + #ifdef CRMF_R_NULL_ARGUMENT + {"NULL_ARGUMENT", ERR_LIB_CRMF, CRMF_R_NULL_ARGUMENT}, + #else + {"NULL_ARGUMENT", 56, 109}, + #endif + #ifdef CRMF_R_POPOSKINPUT_NOT_SUPPORTED + {"POPOSKINPUT_NOT_SUPPORTED", ERR_LIB_CRMF, CRMF_R_POPOSKINPUT_NOT_SUPPORTED}, + #else + {"POPOSKINPUT_NOT_SUPPORTED", 56, 113}, + #endif + #ifdef CRMF_R_POPO_INCONSISTENT_PUBLIC_KEY + {"POPO_INCONSISTENT_PUBLIC_KEY", ERR_LIB_CRMF, CRMF_R_POPO_INCONSISTENT_PUBLIC_KEY}, + #else + {"POPO_INCONSISTENT_PUBLIC_KEY", 56, 117}, + #endif + #ifdef CRMF_R_POPO_MISSING + {"POPO_MISSING", ERR_LIB_CRMF, CRMF_R_POPO_MISSING}, + #else + {"POPO_MISSING", 56, 121}, + #endif + #ifdef CRMF_R_POPO_MISSING_PUBLIC_KEY + {"POPO_MISSING_PUBLIC_KEY", ERR_LIB_CRMF, CRMF_R_POPO_MISSING_PUBLIC_KEY}, + #else + {"POPO_MISSING_PUBLIC_KEY", 56, 118}, + #endif + #ifdef CRMF_R_POPO_MISSING_SUBJECT + {"POPO_MISSING_SUBJECT", ERR_LIB_CRMF, CRMF_R_POPO_MISSING_SUBJECT}, + #else + {"POPO_MISSING_SUBJECT", 56, 119}, + #endif + #ifdef CRMF_R_POPO_RAVERIFIED_NOT_ACCEPTED + {"POPO_RAVERIFIED_NOT_ACCEPTED", ERR_LIB_CRMF, CRMF_R_POPO_RAVERIFIED_NOT_ACCEPTED}, + #else + {"POPO_RAVERIFIED_NOT_ACCEPTED", 56, 120}, + #endif + #ifdef CRMF_R_SETTING_MAC_ALGOR_FAILURE + {"SETTING_MAC_ALGOR_FAILURE", ERR_LIB_CRMF, CRMF_R_SETTING_MAC_ALGOR_FAILURE}, + #else + {"SETTING_MAC_ALGOR_FAILURE", 56, 110}, + #endif + #ifdef CRMF_R_SETTING_OWF_ALGOR_FAILURE + {"SETTING_OWF_ALGOR_FAILURE", ERR_LIB_CRMF, CRMF_R_SETTING_OWF_ALGOR_FAILURE}, + #else + {"SETTING_OWF_ALGOR_FAILURE", 56, 111}, + #endif + #ifdef CRMF_R_UNSUPPORTED_ALGORITHM + {"UNSUPPORTED_ALGORITHM", ERR_LIB_CRMF, CRMF_R_UNSUPPORTED_ALGORITHM}, + #else + {"UNSUPPORTED_ALGORITHM", 56, 112}, + #endif + #ifdef CRMF_R_UNSUPPORTED_CIPHER + {"UNSUPPORTED_CIPHER", ERR_LIB_CRMF, CRMF_R_UNSUPPORTED_CIPHER}, + #else + {"UNSUPPORTED_CIPHER", 56, 114}, + #endif + #ifdef CRMF_R_UNSUPPORTED_METHOD_FOR_CREATING_POPO + {"UNSUPPORTED_METHOD_FOR_CREATING_POPO", ERR_LIB_CRMF, CRMF_R_UNSUPPORTED_METHOD_FOR_CREATING_POPO}, + #else + {"UNSUPPORTED_METHOD_FOR_CREATING_POPO", 56, 115}, + #endif + #ifdef CRMF_R_UNSUPPORTED_POPO_METHOD + {"UNSUPPORTED_POPO_METHOD", ERR_LIB_CRMF, CRMF_R_UNSUPPORTED_POPO_METHOD}, + #else + {"UNSUPPORTED_POPO_METHOD", 56, 116}, + #endif + #ifdef CRYPTO_R_BAD_ALGORITHM_NAME + {"BAD_ALGORITHM_NAME", ERR_LIB_CRYPTO, CRYPTO_R_BAD_ALGORITHM_NAME}, + #else + {"BAD_ALGORITHM_NAME", 15, 117}, + #endif + #ifdef CRYPTO_R_CONFLICTING_NAMES + {"CONFLICTING_NAMES", ERR_LIB_CRYPTO, CRYPTO_R_CONFLICTING_NAMES}, + #else + {"CONFLICTING_NAMES", 15, 118}, + #endif + #ifdef CRYPTO_R_HEX_STRING_TOO_SHORT + {"HEX_STRING_TOO_SHORT", ERR_LIB_CRYPTO, CRYPTO_R_HEX_STRING_TOO_SHORT}, + #else + {"HEX_STRING_TOO_SHORT", 15, 121}, + #endif + #ifdef CRYPTO_R_ILLEGAL_HEX_DIGIT + {"ILLEGAL_HEX_DIGIT", ERR_LIB_CRYPTO, CRYPTO_R_ILLEGAL_HEX_DIGIT}, + #else + {"ILLEGAL_HEX_DIGIT", 15, 102}, + #endif + #ifdef CRYPTO_R_INSUFFICIENT_DATA_SPACE + {"INSUFFICIENT_DATA_SPACE", ERR_LIB_CRYPTO, CRYPTO_R_INSUFFICIENT_DATA_SPACE}, + #else + {"INSUFFICIENT_DATA_SPACE", 15, 106}, + #endif + #ifdef CRYPTO_R_INSUFFICIENT_PARAM_SIZE + {"INSUFFICIENT_PARAM_SIZE", ERR_LIB_CRYPTO, CRYPTO_R_INSUFFICIENT_PARAM_SIZE}, + #else + {"INSUFFICIENT_PARAM_SIZE", 15, 107}, + #endif + #ifdef CRYPTO_R_INSUFFICIENT_SECURE_DATA_SPACE + {"INSUFFICIENT_SECURE_DATA_SPACE", ERR_LIB_CRYPTO, CRYPTO_R_INSUFFICIENT_SECURE_DATA_SPACE}, + #else + {"INSUFFICIENT_SECURE_DATA_SPACE", 15, 108}, + #endif + #ifdef CRYPTO_R_INTEGER_OVERFLOW + {"INTEGER_OVERFLOW", ERR_LIB_CRYPTO, CRYPTO_R_INTEGER_OVERFLOW}, + #else + {"INTEGER_OVERFLOW", 15, 127}, + #endif + #ifdef CRYPTO_R_INVALID_NEGATIVE_VALUE + {"INVALID_NEGATIVE_VALUE", ERR_LIB_CRYPTO, CRYPTO_R_INVALID_NEGATIVE_VALUE}, + #else + {"INVALID_NEGATIVE_VALUE", 15, 122}, + #endif + #ifdef CRYPTO_R_INVALID_NULL_ARGUMENT + {"INVALID_NULL_ARGUMENT", ERR_LIB_CRYPTO, CRYPTO_R_INVALID_NULL_ARGUMENT}, + #else + {"INVALID_NULL_ARGUMENT", 15, 109}, + #endif + #ifdef CRYPTO_R_INVALID_OSSL_PARAM_TYPE + {"INVALID_OSSL_PARAM_TYPE", ERR_LIB_CRYPTO, CRYPTO_R_INVALID_OSSL_PARAM_TYPE}, + #else + {"INVALID_OSSL_PARAM_TYPE", 15, 110}, + #endif + #ifdef CRYPTO_R_NO_PARAMS_TO_MERGE + {"NO_PARAMS_TO_MERGE", ERR_LIB_CRYPTO, CRYPTO_R_NO_PARAMS_TO_MERGE}, + #else + {"NO_PARAMS_TO_MERGE", 15, 131}, + #endif + #ifdef CRYPTO_R_NO_SPACE_FOR_TERMINATING_NULL + {"NO_SPACE_FOR_TERMINATING_NULL", ERR_LIB_CRYPTO, CRYPTO_R_NO_SPACE_FOR_TERMINATING_NULL}, + #else + {"NO_SPACE_FOR_TERMINATING_NULL", 15, 128}, + #endif + #ifdef CRYPTO_R_ODD_NUMBER_OF_DIGITS + {"ODD_NUMBER_OF_DIGITS", ERR_LIB_CRYPTO, CRYPTO_R_ODD_NUMBER_OF_DIGITS}, + #else + {"ODD_NUMBER_OF_DIGITS", 15, 103}, + #endif + #ifdef CRYPTO_R_PARAM_CANNOT_BE_REPRESENTED_EXACTLY + {"PARAM_CANNOT_BE_REPRESENTED_EXACTLY", ERR_LIB_CRYPTO, CRYPTO_R_PARAM_CANNOT_BE_REPRESENTED_EXACTLY}, + #else + {"PARAM_CANNOT_BE_REPRESENTED_EXACTLY", 15, 123}, + #endif + #ifdef CRYPTO_R_PARAM_NOT_INTEGER_TYPE + {"PARAM_NOT_INTEGER_TYPE", ERR_LIB_CRYPTO, CRYPTO_R_PARAM_NOT_INTEGER_TYPE}, + #else + {"PARAM_NOT_INTEGER_TYPE", 15, 124}, + #endif + #ifdef CRYPTO_R_PARAM_OF_INCOMPATIBLE_TYPE + {"PARAM_OF_INCOMPATIBLE_TYPE", ERR_LIB_CRYPTO, CRYPTO_R_PARAM_OF_INCOMPATIBLE_TYPE}, + #else + {"PARAM_OF_INCOMPATIBLE_TYPE", 15, 129}, + #endif + #ifdef CRYPTO_R_PARAM_UNSIGNED_INTEGER_NEGATIVE_VALUE_UNSUPPORTED + {"PARAM_UNSIGNED_INTEGER_NEGATIVE_VALUE_UNSUPPORTED", ERR_LIB_CRYPTO, CRYPTO_R_PARAM_UNSIGNED_INTEGER_NEGATIVE_VALUE_UNSUPPORTED}, + #else + {"PARAM_UNSIGNED_INTEGER_NEGATIVE_VALUE_UNSUPPORTED", 15, 125}, + #endif + #ifdef CRYPTO_R_PARAM_UNSUPPORTED_FLOATING_POINT_FORMAT + {"PARAM_UNSUPPORTED_FLOATING_POINT_FORMAT", ERR_LIB_CRYPTO, CRYPTO_R_PARAM_UNSUPPORTED_FLOATING_POINT_FORMAT}, + #else + {"PARAM_UNSUPPORTED_FLOATING_POINT_FORMAT", 15, 130}, + #endif + #ifdef CRYPTO_R_PARAM_VALUE_TOO_LARGE_FOR_DESTINATION + {"PARAM_VALUE_TOO_LARGE_FOR_DESTINATION", ERR_LIB_CRYPTO, CRYPTO_R_PARAM_VALUE_TOO_LARGE_FOR_DESTINATION}, + #else + {"PARAM_VALUE_TOO_LARGE_FOR_DESTINATION", 15, 126}, + #endif + #ifdef CRYPTO_R_PROVIDER_ALREADY_EXISTS + {"PROVIDER_ALREADY_EXISTS", ERR_LIB_CRYPTO, CRYPTO_R_PROVIDER_ALREADY_EXISTS}, + #else + {"PROVIDER_ALREADY_EXISTS", 15, 104}, + #endif + #ifdef CRYPTO_R_PROVIDER_SECTION_ERROR + {"PROVIDER_SECTION_ERROR", ERR_LIB_CRYPTO, CRYPTO_R_PROVIDER_SECTION_ERROR}, + #else + {"PROVIDER_SECTION_ERROR", 15, 105}, + #endif + #ifdef CRYPTO_R_RANDOM_SECTION_ERROR + {"RANDOM_SECTION_ERROR", ERR_LIB_CRYPTO, CRYPTO_R_RANDOM_SECTION_ERROR}, + #else + {"RANDOM_SECTION_ERROR", 15, 119}, + #endif + #ifdef CRYPTO_R_SECURE_MALLOC_FAILURE + {"SECURE_MALLOC_FAILURE", ERR_LIB_CRYPTO, CRYPTO_R_SECURE_MALLOC_FAILURE}, + #else + {"SECURE_MALLOC_FAILURE", 15, 111}, + #endif + #ifdef CRYPTO_R_STRING_TOO_LONG + {"STRING_TOO_LONG", ERR_LIB_CRYPTO, CRYPTO_R_STRING_TOO_LONG}, + #else + {"STRING_TOO_LONG", 15, 112}, + #endif + #ifdef CRYPTO_R_TOO_MANY_BYTES + {"TOO_MANY_BYTES", ERR_LIB_CRYPTO, CRYPTO_R_TOO_MANY_BYTES}, + #else + {"TOO_MANY_BYTES", 15, 113}, + #endif + #ifdef CRYPTO_R_TOO_MANY_RECORDS + {"TOO_MANY_RECORDS", ERR_LIB_CRYPTO, CRYPTO_R_TOO_MANY_RECORDS}, + #else + {"TOO_MANY_RECORDS", 15, 114}, + #endif + #ifdef CRYPTO_R_TOO_SMALL_BUFFER + {"TOO_SMALL_BUFFER", ERR_LIB_CRYPTO, CRYPTO_R_TOO_SMALL_BUFFER}, + #else + {"TOO_SMALL_BUFFER", 15, 116}, + #endif + #ifdef CRYPTO_R_UNKNOWN_NAME_IN_RANDOM_SECTION + {"UNKNOWN_NAME_IN_RANDOM_SECTION", ERR_LIB_CRYPTO, CRYPTO_R_UNKNOWN_NAME_IN_RANDOM_SECTION}, + #else + {"UNKNOWN_NAME_IN_RANDOM_SECTION", 15, 120}, + #endif + #ifdef CRYPTO_R_ZERO_LENGTH_NUMBER + {"ZERO_LENGTH_NUMBER", ERR_LIB_CRYPTO, CRYPTO_R_ZERO_LENGTH_NUMBER}, + #else + {"ZERO_LENGTH_NUMBER", 15, 115}, + #endif + #ifdef CT_R_BASE64_DECODE_ERROR + {"BASE64_DECODE_ERROR", ERR_LIB_CT, CT_R_BASE64_DECODE_ERROR}, + #else + {"BASE64_DECODE_ERROR", 50, 108}, + #endif + #ifdef CT_R_INVALID_LOG_ID_LENGTH + {"INVALID_LOG_ID_LENGTH", ERR_LIB_CT, CT_R_INVALID_LOG_ID_LENGTH}, + #else + {"INVALID_LOG_ID_LENGTH", 50, 100}, + #endif + #ifdef CT_R_LOG_CONF_INVALID + {"LOG_CONF_INVALID", ERR_LIB_CT, CT_R_LOG_CONF_INVALID}, + #else + {"LOG_CONF_INVALID", 50, 109}, + #endif + #ifdef CT_R_LOG_CONF_INVALID_KEY + {"LOG_CONF_INVALID_KEY", ERR_LIB_CT, CT_R_LOG_CONF_INVALID_KEY}, + #else + {"LOG_CONF_INVALID_KEY", 50, 110}, + #endif + #ifdef CT_R_LOG_CONF_MISSING_DESCRIPTION + {"LOG_CONF_MISSING_DESCRIPTION", ERR_LIB_CT, CT_R_LOG_CONF_MISSING_DESCRIPTION}, + #else + {"LOG_CONF_MISSING_DESCRIPTION", 50, 111}, + #endif + #ifdef CT_R_LOG_CONF_MISSING_KEY + {"LOG_CONF_MISSING_KEY", ERR_LIB_CT, CT_R_LOG_CONF_MISSING_KEY}, + #else + {"LOG_CONF_MISSING_KEY", 50, 112}, + #endif + #ifdef CT_R_LOG_KEY_INVALID + {"LOG_KEY_INVALID", ERR_LIB_CT, CT_R_LOG_KEY_INVALID}, + #else + {"LOG_KEY_INVALID", 50, 113}, + #endif + #ifdef CT_R_SCT_FUTURE_TIMESTAMP + {"SCT_FUTURE_TIMESTAMP", ERR_LIB_CT, CT_R_SCT_FUTURE_TIMESTAMP}, + #else + {"SCT_FUTURE_TIMESTAMP", 50, 116}, + #endif + #ifdef CT_R_SCT_INVALID + {"SCT_INVALID", ERR_LIB_CT, CT_R_SCT_INVALID}, + #else + {"SCT_INVALID", 50, 104}, + #endif + #ifdef CT_R_SCT_INVALID_SIGNATURE + {"SCT_INVALID_SIGNATURE", ERR_LIB_CT, CT_R_SCT_INVALID_SIGNATURE}, + #else + {"SCT_INVALID_SIGNATURE", 50, 107}, + #endif + #ifdef CT_R_SCT_LIST_INVALID + {"SCT_LIST_INVALID", ERR_LIB_CT, CT_R_SCT_LIST_INVALID}, + #else + {"SCT_LIST_INVALID", 50, 105}, + #endif + #ifdef CT_R_SCT_LOG_ID_MISMATCH + {"SCT_LOG_ID_MISMATCH", ERR_LIB_CT, CT_R_SCT_LOG_ID_MISMATCH}, + #else + {"SCT_LOG_ID_MISMATCH", 50, 114}, + #endif + #ifdef CT_R_SCT_NOT_SET + {"SCT_NOT_SET", ERR_LIB_CT, CT_R_SCT_NOT_SET}, + #else + {"SCT_NOT_SET", 50, 106}, + #endif + #ifdef CT_R_SCT_UNSUPPORTED_VERSION + {"SCT_UNSUPPORTED_VERSION", ERR_LIB_CT, CT_R_SCT_UNSUPPORTED_VERSION}, + #else + {"SCT_UNSUPPORTED_VERSION", 50, 115}, + #endif + #ifdef CT_R_UNRECOGNIZED_SIGNATURE_NID + {"UNRECOGNIZED_SIGNATURE_NID", ERR_LIB_CT, CT_R_UNRECOGNIZED_SIGNATURE_NID}, + #else + {"UNRECOGNIZED_SIGNATURE_NID", 50, 101}, + #endif + #ifdef CT_R_UNSUPPORTED_ENTRY_TYPE + {"UNSUPPORTED_ENTRY_TYPE", ERR_LIB_CT, CT_R_UNSUPPORTED_ENTRY_TYPE}, + #else + {"UNSUPPORTED_ENTRY_TYPE", 50, 102}, + #endif + #ifdef CT_R_UNSUPPORTED_VERSION + {"UNSUPPORTED_VERSION", ERR_LIB_CT, CT_R_UNSUPPORTED_VERSION}, + #else + {"UNSUPPORTED_VERSION", 50, 103}, + #endif + #ifdef DH_R_BAD_FFC_PARAMETERS + {"BAD_FFC_PARAMETERS", ERR_LIB_DH, DH_R_BAD_FFC_PARAMETERS}, + #else + {"BAD_FFC_PARAMETERS", 5, 127}, + #endif + #ifdef DH_R_BAD_GENERATOR + {"BAD_GENERATOR", ERR_LIB_DH, DH_R_BAD_GENERATOR}, + #else + {"BAD_GENERATOR", 5, 101}, + #endif + #ifdef DH_R_BN_DECODE_ERROR + {"BN_DECODE_ERROR", ERR_LIB_DH, DH_R_BN_DECODE_ERROR}, + #else + {"BN_DECODE_ERROR", 5, 109}, + #endif + #ifdef DH_R_BN_ERROR + {"BN_ERROR", ERR_LIB_DH, DH_R_BN_ERROR}, + #else + {"BN_ERROR", 5, 106}, + #endif + #ifdef DH_R_CHECK_INVALID_J_VALUE + {"CHECK_INVALID_J_VALUE", ERR_LIB_DH, DH_R_CHECK_INVALID_J_VALUE}, + #else + {"CHECK_INVALID_J_VALUE", 5, 115}, + #endif + #ifdef DH_R_CHECK_INVALID_Q_VALUE + {"CHECK_INVALID_Q_VALUE", ERR_LIB_DH, DH_R_CHECK_INVALID_Q_VALUE}, + #else + {"CHECK_INVALID_Q_VALUE", 5, 116}, + #endif + #ifdef DH_R_CHECK_PUBKEY_INVALID + {"CHECK_PUBKEY_INVALID", ERR_LIB_DH, DH_R_CHECK_PUBKEY_INVALID}, + #else + {"CHECK_PUBKEY_INVALID", 5, 122}, + #endif + #ifdef DH_R_CHECK_PUBKEY_TOO_LARGE + {"CHECK_PUBKEY_TOO_LARGE", ERR_LIB_DH, DH_R_CHECK_PUBKEY_TOO_LARGE}, + #else + {"CHECK_PUBKEY_TOO_LARGE", 5, 123}, + #endif + #ifdef DH_R_CHECK_PUBKEY_TOO_SMALL + {"CHECK_PUBKEY_TOO_SMALL", ERR_LIB_DH, DH_R_CHECK_PUBKEY_TOO_SMALL}, + #else + {"CHECK_PUBKEY_TOO_SMALL", 5, 124}, + #endif + #ifdef DH_R_CHECK_P_NOT_PRIME + {"CHECK_P_NOT_PRIME", ERR_LIB_DH, DH_R_CHECK_P_NOT_PRIME}, + #else + {"CHECK_P_NOT_PRIME", 5, 117}, + #endif + #ifdef DH_R_CHECK_P_NOT_SAFE_PRIME + {"CHECK_P_NOT_SAFE_PRIME", ERR_LIB_DH, DH_R_CHECK_P_NOT_SAFE_PRIME}, + #else + {"CHECK_P_NOT_SAFE_PRIME", 5, 118}, + #endif + #ifdef DH_R_CHECK_Q_NOT_PRIME + {"CHECK_Q_NOT_PRIME", ERR_LIB_DH, DH_R_CHECK_Q_NOT_PRIME}, + #else + {"CHECK_Q_NOT_PRIME", 5, 119}, + #endif + #ifdef DH_R_DECODE_ERROR + {"DECODE_ERROR", ERR_LIB_DH, DH_R_DECODE_ERROR}, + #else + {"DECODE_ERROR", 5, 104}, + #endif + #ifdef DH_R_INVALID_PARAMETER_NAME + {"INVALID_PARAMETER_NAME", ERR_LIB_DH, DH_R_INVALID_PARAMETER_NAME}, + #else + {"INVALID_PARAMETER_NAME", 5, 110}, + #endif + #ifdef DH_R_INVALID_PARAMETER_NID + {"INVALID_PARAMETER_NID", ERR_LIB_DH, DH_R_INVALID_PARAMETER_NID}, + #else + {"INVALID_PARAMETER_NID", 5, 114}, + #endif + #ifdef DH_R_INVALID_PUBKEY + {"INVALID_PUBKEY", ERR_LIB_DH, DH_R_INVALID_PUBKEY}, + #else + {"INVALID_PUBKEY", 5, 102}, + #endif + #ifdef DH_R_INVALID_SECRET + {"INVALID_SECRET", ERR_LIB_DH, DH_R_INVALID_SECRET}, + #else + {"INVALID_SECRET", 5, 128}, + #endif + #ifdef DH_R_KDF_PARAMETER_ERROR + {"KDF_PARAMETER_ERROR", ERR_LIB_DH, DH_R_KDF_PARAMETER_ERROR}, + #else + {"KDF_PARAMETER_ERROR", 5, 112}, + #endif + #ifdef DH_R_KEYS_NOT_SET + {"KEYS_NOT_SET", ERR_LIB_DH, DH_R_KEYS_NOT_SET}, + #else + {"KEYS_NOT_SET", 5, 108}, + #endif + #ifdef DH_R_MISSING_PUBKEY + {"MISSING_PUBKEY", ERR_LIB_DH, DH_R_MISSING_PUBKEY}, + #else + {"MISSING_PUBKEY", 5, 125}, + #endif + #ifdef DH_R_MODULUS_TOO_LARGE + {"MODULUS_TOO_LARGE", ERR_LIB_DH, DH_R_MODULUS_TOO_LARGE}, + #else + {"MODULUS_TOO_LARGE", 5, 103}, + #endif + #ifdef DH_R_MODULUS_TOO_SMALL + {"MODULUS_TOO_SMALL", ERR_LIB_DH, DH_R_MODULUS_TOO_SMALL}, + #else + {"MODULUS_TOO_SMALL", 5, 126}, + #endif + #ifdef DH_R_NOT_SUITABLE_GENERATOR + {"NOT_SUITABLE_GENERATOR", ERR_LIB_DH, DH_R_NOT_SUITABLE_GENERATOR}, + #else + {"NOT_SUITABLE_GENERATOR", 5, 120}, + #endif + #ifdef DH_R_NO_PARAMETERS_SET + {"NO_PARAMETERS_SET", ERR_LIB_DH, DH_R_NO_PARAMETERS_SET}, + #else + {"NO_PARAMETERS_SET", 5, 107}, + #endif + #ifdef DH_R_NO_PRIVATE_VALUE + {"NO_PRIVATE_VALUE", ERR_LIB_DH, DH_R_NO_PRIVATE_VALUE}, + #else + {"NO_PRIVATE_VALUE", 5, 100}, + #endif + #ifdef DH_R_PARAMETER_ENCODING_ERROR + {"PARAMETER_ENCODING_ERROR", ERR_LIB_DH, DH_R_PARAMETER_ENCODING_ERROR}, + #else + {"PARAMETER_ENCODING_ERROR", 5, 105}, + #endif + #ifdef DH_R_PEER_KEY_ERROR + {"PEER_KEY_ERROR", ERR_LIB_DH, DH_R_PEER_KEY_ERROR}, + #else + {"PEER_KEY_ERROR", 5, 111}, + #endif + #ifdef DH_R_SHARED_INFO_ERROR + {"SHARED_INFO_ERROR", ERR_LIB_DH, DH_R_SHARED_INFO_ERROR}, + #else + {"SHARED_INFO_ERROR", 5, 113}, + #endif + #ifdef DH_R_UNABLE_TO_CHECK_GENERATOR + {"UNABLE_TO_CHECK_GENERATOR", ERR_LIB_DH, DH_R_UNABLE_TO_CHECK_GENERATOR}, + #else + {"UNABLE_TO_CHECK_GENERATOR", 5, 121}, + #endif + #ifdef DSA_R_BAD_FFC_PARAMETERS + {"BAD_FFC_PARAMETERS", ERR_LIB_DSA, DSA_R_BAD_FFC_PARAMETERS}, + #else + {"BAD_FFC_PARAMETERS", 10, 114}, + #endif + #ifdef DSA_R_BAD_Q_VALUE + {"BAD_Q_VALUE", ERR_LIB_DSA, DSA_R_BAD_Q_VALUE}, + #else + {"BAD_Q_VALUE", 10, 102}, + #endif + #ifdef DSA_R_BN_DECODE_ERROR + {"BN_DECODE_ERROR", ERR_LIB_DSA, DSA_R_BN_DECODE_ERROR}, + #else + {"BN_DECODE_ERROR", 10, 108}, + #endif + #ifdef DSA_R_BN_ERROR + {"BN_ERROR", ERR_LIB_DSA, DSA_R_BN_ERROR}, + #else + {"BN_ERROR", 10, 109}, + #endif + #ifdef DSA_R_DECODE_ERROR + {"DECODE_ERROR", ERR_LIB_DSA, DSA_R_DECODE_ERROR}, + #else + {"DECODE_ERROR", 10, 104}, + #endif + #ifdef DSA_R_INVALID_DIGEST_TYPE + {"INVALID_DIGEST_TYPE", ERR_LIB_DSA, DSA_R_INVALID_DIGEST_TYPE}, + #else + {"INVALID_DIGEST_TYPE", 10, 106}, + #endif + #ifdef DSA_R_INVALID_PARAMETERS + {"INVALID_PARAMETERS", ERR_LIB_DSA, DSA_R_INVALID_PARAMETERS}, + #else + {"INVALID_PARAMETERS", 10, 112}, + #endif + #ifdef DSA_R_MISSING_PARAMETERS + {"MISSING_PARAMETERS", ERR_LIB_DSA, DSA_R_MISSING_PARAMETERS}, + #else + {"MISSING_PARAMETERS", 10, 101}, + #endif + #ifdef DSA_R_MISSING_PRIVATE_KEY + {"MISSING_PRIVATE_KEY", ERR_LIB_DSA, DSA_R_MISSING_PRIVATE_KEY}, + #else + {"MISSING_PRIVATE_KEY", 10, 111}, + #endif + #ifdef DSA_R_MODULUS_TOO_LARGE + {"MODULUS_TOO_LARGE", ERR_LIB_DSA, DSA_R_MODULUS_TOO_LARGE}, + #else + {"MODULUS_TOO_LARGE", 10, 103}, + #endif + #ifdef DSA_R_NO_PARAMETERS_SET + {"NO_PARAMETERS_SET", ERR_LIB_DSA, DSA_R_NO_PARAMETERS_SET}, + #else + {"NO_PARAMETERS_SET", 10, 107}, + #endif + #ifdef DSA_R_PARAMETER_ENCODING_ERROR + {"PARAMETER_ENCODING_ERROR", ERR_LIB_DSA, DSA_R_PARAMETER_ENCODING_ERROR}, + #else + {"PARAMETER_ENCODING_ERROR", 10, 105}, + #endif + #ifdef DSA_R_P_NOT_PRIME + {"P_NOT_PRIME", ERR_LIB_DSA, DSA_R_P_NOT_PRIME}, + #else + {"P_NOT_PRIME", 10, 115}, + #endif + #ifdef DSA_R_Q_NOT_PRIME + {"Q_NOT_PRIME", ERR_LIB_DSA, DSA_R_Q_NOT_PRIME}, + #else + {"Q_NOT_PRIME", 10, 113}, + #endif + #ifdef DSA_R_SEED_LEN_SMALL + {"SEED_LEN_SMALL", ERR_LIB_DSA, DSA_R_SEED_LEN_SMALL}, + #else + {"SEED_LEN_SMALL", 10, 110}, + #endif + #ifdef DSA_R_TOO_MANY_RETRIES + {"TOO_MANY_RETRIES", ERR_LIB_DSA, DSA_R_TOO_MANY_RETRIES}, + #else + {"TOO_MANY_RETRIES", 10, 116}, + #endif + #ifdef DSO_R_CTRL_FAILED + {"CTRL_FAILED", ERR_LIB_DSO, DSO_R_CTRL_FAILED}, + #else + {"CTRL_FAILED", 37, 100}, + #endif + #ifdef DSO_R_DSO_ALREADY_LOADED + {"DSO_ALREADY_LOADED", ERR_LIB_DSO, DSO_R_DSO_ALREADY_LOADED}, + #else + {"DSO_ALREADY_LOADED", 37, 110}, + #endif + #ifdef DSO_R_EMPTY_FILE_STRUCTURE + {"EMPTY_FILE_STRUCTURE", ERR_LIB_DSO, DSO_R_EMPTY_FILE_STRUCTURE}, + #else + {"EMPTY_FILE_STRUCTURE", 37, 113}, + #endif + #ifdef DSO_R_FAILURE + {"FAILURE", ERR_LIB_DSO, DSO_R_FAILURE}, + #else + {"FAILURE", 37, 114}, + #endif + #ifdef DSO_R_FILENAME_TOO_BIG + {"FILENAME_TOO_BIG", ERR_LIB_DSO, DSO_R_FILENAME_TOO_BIG}, + #else + {"FILENAME_TOO_BIG", 37, 101}, + #endif + #ifdef DSO_R_FINISH_FAILED + {"FINISH_FAILED", ERR_LIB_DSO, DSO_R_FINISH_FAILED}, + #else + {"FINISH_FAILED", 37, 102}, + #endif + #ifdef DSO_R_INCORRECT_FILE_SYNTAX + {"INCORRECT_FILE_SYNTAX", ERR_LIB_DSO, DSO_R_INCORRECT_FILE_SYNTAX}, + #else + {"INCORRECT_FILE_SYNTAX", 37, 115}, + #endif + #ifdef DSO_R_LOAD_FAILED + {"LOAD_FAILED", ERR_LIB_DSO, DSO_R_LOAD_FAILED}, + #else + {"LOAD_FAILED", 37, 103}, + #endif + #ifdef DSO_R_NAME_TRANSLATION_FAILED + {"NAME_TRANSLATION_FAILED", ERR_LIB_DSO, DSO_R_NAME_TRANSLATION_FAILED}, + #else + {"NAME_TRANSLATION_FAILED", 37, 109}, + #endif + #ifdef DSO_R_NO_FILENAME + {"NO_FILENAME", ERR_LIB_DSO, DSO_R_NO_FILENAME}, + #else + {"NO_FILENAME", 37, 111}, + #endif + #ifdef DSO_R_NULL_HANDLE + {"NULL_HANDLE", ERR_LIB_DSO, DSO_R_NULL_HANDLE}, + #else + {"NULL_HANDLE", 37, 104}, + #endif + #ifdef DSO_R_SET_FILENAME_FAILED + {"SET_FILENAME_FAILED", ERR_LIB_DSO, DSO_R_SET_FILENAME_FAILED}, + #else + {"SET_FILENAME_FAILED", 37, 112}, + #endif + #ifdef DSO_R_STACK_ERROR + {"STACK_ERROR", ERR_LIB_DSO, DSO_R_STACK_ERROR}, + #else + {"STACK_ERROR", 37, 105}, + #endif + #ifdef DSO_R_SYM_FAILURE + {"SYM_FAILURE", ERR_LIB_DSO, DSO_R_SYM_FAILURE}, + #else + {"SYM_FAILURE", 37, 106}, + #endif + #ifdef DSO_R_UNLOAD_FAILED + {"UNLOAD_FAILED", ERR_LIB_DSO, DSO_R_UNLOAD_FAILED}, + #else + {"UNLOAD_FAILED", 37, 107}, + #endif + #ifdef DSO_R_UNSUPPORTED + {"UNSUPPORTED", ERR_LIB_DSO, DSO_R_UNSUPPORTED}, + #else + {"UNSUPPORTED", 37, 108}, + #endif + #ifdef EC_R_ASN1_ERROR + {"ASN1_ERROR", ERR_LIB_EC, EC_R_ASN1_ERROR}, + #else + {"ASN1_ERROR", 16, 115}, + #endif + #ifdef EC_R_BAD_SIGNATURE + {"BAD_SIGNATURE", ERR_LIB_EC, EC_R_BAD_SIGNATURE}, + #else + {"BAD_SIGNATURE", 16, 156}, + #endif + #ifdef EC_R_BIGNUM_OUT_OF_RANGE + {"BIGNUM_OUT_OF_RANGE", ERR_LIB_EC, EC_R_BIGNUM_OUT_OF_RANGE}, + #else + {"BIGNUM_OUT_OF_RANGE", 16, 144}, + #endif + #ifdef EC_R_BUFFER_TOO_SMALL + {"BUFFER_TOO_SMALL", ERR_LIB_EC, EC_R_BUFFER_TOO_SMALL}, + #else + {"BUFFER_TOO_SMALL", 16, 100}, + #endif + #ifdef EC_R_CANNOT_INVERT + {"CANNOT_INVERT", ERR_LIB_EC, EC_R_CANNOT_INVERT}, + #else + {"CANNOT_INVERT", 16, 165}, + #endif + #ifdef EC_R_COORDINATES_OUT_OF_RANGE + {"COORDINATES_OUT_OF_RANGE", ERR_LIB_EC, EC_R_COORDINATES_OUT_OF_RANGE}, + #else + {"COORDINATES_OUT_OF_RANGE", 16, 146}, + #endif + #ifdef EC_R_CURVE_DOES_NOT_SUPPORT_ECDH + {"CURVE_DOES_NOT_SUPPORT_ECDH", ERR_LIB_EC, EC_R_CURVE_DOES_NOT_SUPPORT_ECDH}, + #else + {"CURVE_DOES_NOT_SUPPORT_ECDH", 16, 160}, + #endif + #ifdef EC_R_CURVE_DOES_NOT_SUPPORT_ECDSA + {"CURVE_DOES_NOT_SUPPORT_ECDSA", ERR_LIB_EC, EC_R_CURVE_DOES_NOT_SUPPORT_ECDSA}, + #else + {"CURVE_DOES_NOT_SUPPORT_ECDSA", 16, 170}, + #endif + #ifdef EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING + {"CURVE_DOES_NOT_SUPPORT_SIGNING", ERR_LIB_EC, EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING}, + #else + {"CURVE_DOES_NOT_SUPPORT_SIGNING", 16, 159}, + #endif + #ifdef EC_R_DECODE_ERROR + {"DECODE_ERROR", ERR_LIB_EC, EC_R_DECODE_ERROR}, + #else + {"DECODE_ERROR", 16, 142}, + #endif + #ifdef EC_R_DISCRIMINANT_IS_ZERO + {"DISCRIMINANT_IS_ZERO", ERR_LIB_EC, EC_R_DISCRIMINANT_IS_ZERO}, + #else + {"DISCRIMINANT_IS_ZERO", 16, 118}, + #endif + #ifdef EC_R_EC_GROUP_NEW_BY_NAME_FAILURE + {"EC_GROUP_NEW_BY_NAME_FAILURE", ERR_LIB_EC, EC_R_EC_GROUP_NEW_BY_NAME_FAILURE}, + #else + {"EC_GROUP_NEW_BY_NAME_FAILURE", 16, 119}, + #endif + #ifdef EC_R_EXPLICIT_PARAMS_NOT_SUPPORTED + {"EXPLICIT_PARAMS_NOT_SUPPORTED", ERR_LIB_EC, EC_R_EXPLICIT_PARAMS_NOT_SUPPORTED}, + #else + {"EXPLICIT_PARAMS_NOT_SUPPORTED", 16, 127}, + #endif + #ifdef EC_R_FAILED_MAKING_PUBLIC_KEY + {"FAILED_MAKING_PUBLIC_KEY", ERR_LIB_EC, EC_R_FAILED_MAKING_PUBLIC_KEY}, + #else + {"FAILED_MAKING_PUBLIC_KEY", 16, 166}, + #endif + #ifdef EC_R_FIELD_TOO_LARGE + {"FIELD_TOO_LARGE", ERR_LIB_EC, EC_R_FIELD_TOO_LARGE}, + #else + {"FIELD_TOO_LARGE", 16, 143}, + #endif + #ifdef EC_R_GF2M_NOT_SUPPORTED + {"GF2M_NOT_SUPPORTED", ERR_LIB_EC, EC_R_GF2M_NOT_SUPPORTED}, + #else + {"GF2M_NOT_SUPPORTED", 16, 147}, + #endif + #ifdef EC_R_GROUP2PKPARAMETERS_FAILURE + {"GROUP2PKPARAMETERS_FAILURE", ERR_LIB_EC, EC_R_GROUP2PKPARAMETERS_FAILURE}, + #else + {"GROUP2PKPARAMETERS_FAILURE", 16, 120}, + #endif + #ifdef EC_R_I2D_ECPKPARAMETERS_FAILURE + {"I2D_ECPKPARAMETERS_FAILURE", ERR_LIB_EC, EC_R_I2D_ECPKPARAMETERS_FAILURE}, + #else + {"I2D_ECPKPARAMETERS_FAILURE", 16, 121}, + #endif + #ifdef EC_R_INCOMPATIBLE_OBJECTS + {"INCOMPATIBLE_OBJECTS", ERR_LIB_EC, EC_R_INCOMPATIBLE_OBJECTS}, + #else + {"INCOMPATIBLE_OBJECTS", 16, 101}, + #endif + #ifdef EC_R_INVALID_A + {"INVALID_A", ERR_LIB_EC, EC_R_INVALID_A}, + #else + {"INVALID_A", 16, 168}, + #endif + #ifdef EC_R_INVALID_ARGUMENT + {"INVALID_ARGUMENT", ERR_LIB_EC, EC_R_INVALID_ARGUMENT}, + #else + {"INVALID_ARGUMENT", 16, 112}, + #endif + #ifdef EC_R_INVALID_B + {"INVALID_B", ERR_LIB_EC, EC_R_INVALID_B}, + #else + {"INVALID_B", 16, 169}, + #endif + #ifdef EC_R_INVALID_COFACTOR + {"INVALID_COFACTOR", ERR_LIB_EC, EC_R_INVALID_COFACTOR}, + #else + {"INVALID_COFACTOR", 16, 171}, + #endif + #ifdef EC_R_INVALID_COMPRESSED_POINT + {"INVALID_COMPRESSED_POINT", ERR_LIB_EC, EC_R_INVALID_COMPRESSED_POINT}, + #else + {"INVALID_COMPRESSED_POINT", 16, 110}, + #endif + #ifdef EC_R_INVALID_COMPRESSION_BIT + {"INVALID_COMPRESSION_BIT", ERR_LIB_EC, EC_R_INVALID_COMPRESSION_BIT}, + #else + {"INVALID_COMPRESSION_BIT", 16, 109}, + #endif + #ifdef EC_R_INVALID_CURVE + {"INVALID_CURVE", ERR_LIB_EC, EC_R_INVALID_CURVE}, + #else + {"INVALID_CURVE", 16, 141}, + #endif + #ifdef EC_R_INVALID_DIGEST + {"INVALID_DIGEST", ERR_LIB_EC, EC_R_INVALID_DIGEST}, + #else + {"INVALID_DIGEST", 16, 151}, + #endif + #ifdef EC_R_INVALID_DIGEST_TYPE + {"INVALID_DIGEST_TYPE", ERR_LIB_EC, EC_R_INVALID_DIGEST_TYPE}, + #else + {"INVALID_DIGEST_TYPE", 16, 138}, + #endif + #ifdef EC_R_INVALID_ENCODING + {"INVALID_ENCODING", ERR_LIB_EC, EC_R_INVALID_ENCODING}, + #else + {"INVALID_ENCODING", 16, 102}, + #endif + #ifdef EC_R_INVALID_FIELD + {"INVALID_FIELD", ERR_LIB_EC, EC_R_INVALID_FIELD}, + #else + {"INVALID_FIELD", 16, 103}, + #endif + #ifdef EC_R_INVALID_FORM + {"INVALID_FORM", ERR_LIB_EC, EC_R_INVALID_FORM}, + #else + {"INVALID_FORM", 16, 104}, + #endif + #ifdef EC_R_INVALID_GENERATOR + {"INVALID_GENERATOR", ERR_LIB_EC, EC_R_INVALID_GENERATOR}, + #else + {"INVALID_GENERATOR", 16, 173}, + #endif + #ifdef EC_R_INVALID_GROUP_ORDER + {"INVALID_GROUP_ORDER", ERR_LIB_EC, EC_R_INVALID_GROUP_ORDER}, + #else + {"INVALID_GROUP_ORDER", 16, 122}, + #endif + #ifdef EC_R_INVALID_KEY + {"INVALID_KEY", ERR_LIB_EC, EC_R_INVALID_KEY}, + #else + {"INVALID_KEY", 16, 116}, + #endif + #ifdef EC_R_INVALID_LENGTH + {"INVALID_LENGTH", ERR_LIB_EC, EC_R_INVALID_LENGTH}, + #else + {"INVALID_LENGTH", 16, 117}, + #endif + #ifdef EC_R_INVALID_NAMED_GROUP_CONVERSION + {"INVALID_NAMED_GROUP_CONVERSION", ERR_LIB_EC, EC_R_INVALID_NAMED_GROUP_CONVERSION}, + #else + {"INVALID_NAMED_GROUP_CONVERSION", 16, 174}, + #endif + #ifdef EC_R_INVALID_OUTPUT_LENGTH + {"INVALID_OUTPUT_LENGTH", ERR_LIB_EC, EC_R_INVALID_OUTPUT_LENGTH}, + #else + {"INVALID_OUTPUT_LENGTH", 16, 161}, + #endif + #ifdef EC_R_INVALID_P + {"INVALID_P", ERR_LIB_EC, EC_R_INVALID_P}, + #else + {"INVALID_P", 16, 172}, + #endif + #ifdef EC_R_INVALID_PEER_KEY + {"INVALID_PEER_KEY", ERR_LIB_EC, EC_R_INVALID_PEER_KEY}, + #else + {"INVALID_PEER_KEY", 16, 133}, + #endif + #ifdef EC_R_INVALID_PENTANOMIAL_BASIS + {"INVALID_PENTANOMIAL_BASIS", ERR_LIB_EC, EC_R_INVALID_PENTANOMIAL_BASIS}, + #else + {"INVALID_PENTANOMIAL_BASIS", 16, 132}, + #endif + #ifdef EC_R_INVALID_PRIVATE_KEY + {"INVALID_PRIVATE_KEY", ERR_LIB_EC, EC_R_INVALID_PRIVATE_KEY}, + #else + {"INVALID_PRIVATE_KEY", 16, 123}, + #endif + #ifdef EC_R_INVALID_SEED + {"INVALID_SEED", ERR_LIB_EC, EC_R_INVALID_SEED}, + #else + {"INVALID_SEED", 16, 175}, + #endif + #ifdef EC_R_INVALID_TRINOMIAL_BASIS + {"INVALID_TRINOMIAL_BASIS", ERR_LIB_EC, EC_R_INVALID_TRINOMIAL_BASIS}, + #else + {"INVALID_TRINOMIAL_BASIS", 16, 137}, + #endif + #ifdef EC_R_KDF_PARAMETER_ERROR + {"KDF_PARAMETER_ERROR", ERR_LIB_EC, EC_R_KDF_PARAMETER_ERROR}, + #else + {"KDF_PARAMETER_ERROR", 16, 148}, + #endif + #ifdef EC_R_KEYS_NOT_SET + {"KEYS_NOT_SET", ERR_LIB_EC, EC_R_KEYS_NOT_SET}, + #else + {"KEYS_NOT_SET", 16, 140}, + #endif + #ifdef EC_R_LADDER_POST_FAILURE + {"LADDER_POST_FAILURE", ERR_LIB_EC, EC_R_LADDER_POST_FAILURE}, + #else + {"LADDER_POST_FAILURE", 16, 136}, + #endif + #ifdef EC_R_LADDER_PRE_FAILURE + {"LADDER_PRE_FAILURE", ERR_LIB_EC, EC_R_LADDER_PRE_FAILURE}, + #else + {"LADDER_PRE_FAILURE", 16, 153}, + #endif + #ifdef EC_R_LADDER_STEP_FAILURE + {"LADDER_STEP_FAILURE", ERR_LIB_EC, EC_R_LADDER_STEP_FAILURE}, + #else + {"LADDER_STEP_FAILURE", 16, 162}, + #endif + #ifdef EC_R_MISSING_OID + {"MISSING_OID", ERR_LIB_EC, EC_R_MISSING_OID}, + #else + {"MISSING_OID", 16, 167}, + #endif + #ifdef EC_R_MISSING_PARAMETERS + {"MISSING_PARAMETERS", ERR_LIB_EC, EC_R_MISSING_PARAMETERS}, + #else + {"MISSING_PARAMETERS", 16, 124}, + #endif + #ifdef EC_R_MISSING_PRIVATE_KEY + {"MISSING_PRIVATE_KEY", ERR_LIB_EC, EC_R_MISSING_PRIVATE_KEY}, + #else + {"MISSING_PRIVATE_KEY", 16, 125}, + #endif + #ifdef EC_R_NEED_NEW_SETUP_VALUES + {"NEED_NEW_SETUP_VALUES", ERR_LIB_EC, EC_R_NEED_NEW_SETUP_VALUES}, + #else + {"NEED_NEW_SETUP_VALUES", 16, 157}, + #endif + #ifdef EC_R_NOT_A_NIST_PRIME + {"NOT_A_NIST_PRIME", ERR_LIB_EC, EC_R_NOT_A_NIST_PRIME}, + #else + {"NOT_A_NIST_PRIME", 16, 135}, + #endif + #ifdef EC_R_NOT_IMPLEMENTED + {"NOT_IMPLEMENTED", ERR_LIB_EC, EC_R_NOT_IMPLEMENTED}, + #else + {"NOT_IMPLEMENTED", 16, 126}, + #endif + #ifdef EC_R_NOT_INITIALIZED + {"NOT_INITIALIZED", ERR_LIB_EC, EC_R_NOT_INITIALIZED}, + #else + {"NOT_INITIALIZED", 16, 111}, + #endif + #ifdef EC_R_NO_PARAMETERS_SET + {"NO_PARAMETERS_SET", ERR_LIB_EC, EC_R_NO_PARAMETERS_SET}, + #else + {"NO_PARAMETERS_SET", 16, 139}, + #endif + #ifdef EC_R_NO_PRIVATE_VALUE + {"NO_PRIVATE_VALUE", ERR_LIB_EC, EC_R_NO_PRIVATE_VALUE}, + #else + {"NO_PRIVATE_VALUE", 16, 154}, + #endif + #ifdef EC_R_OPERATION_NOT_SUPPORTED + {"OPERATION_NOT_SUPPORTED", ERR_LIB_EC, EC_R_OPERATION_NOT_SUPPORTED}, + #else + {"OPERATION_NOT_SUPPORTED", 16, 152}, + #endif + #ifdef EC_R_PASSED_NULL_PARAMETER + {"PASSED_NULL_PARAMETER", ERR_LIB_EC, EC_R_PASSED_NULL_PARAMETER}, + #else + {"PASSED_NULL_PARAMETER", 16, 134}, + #endif + #ifdef EC_R_PEER_KEY_ERROR + {"PEER_KEY_ERROR", ERR_LIB_EC, EC_R_PEER_KEY_ERROR}, + #else + {"PEER_KEY_ERROR", 16, 149}, + #endif + #ifdef EC_R_POINT_ARITHMETIC_FAILURE + {"POINT_ARITHMETIC_FAILURE", ERR_LIB_EC, EC_R_POINT_ARITHMETIC_FAILURE}, + #else + {"POINT_ARITHMETIC_FAILURE", 16, 155}, + #endif + #ifdef EC_R_POINT_AT_INFINITY + {"POINT_AT_INFINITY", ERR_LIB_EC, EC_R_POINT_AT_INFINITY}, + #else + {"POINT_AT_INFINITY", 16, 106}, + #endif + #ifdef EC_R_POINT_COORDINATES_BLIND_FAILURE + {"POINT_COORDINATES_BLIND_FAILURE", ERR_LIB_EC, EC_R_POINT_COORDINATES_BLIND_FAILURE}, + #else + {"POINT_COORDINATES_BLIND_FAILURE", 16, 163}, + #endif + #ifdef EC_R_POINT_IS_NOT_ON_CURVE + {"POINT_IS_NOT_ON_CURVE", ERR_LIB_EC, EC_R_POINT_IS_NOT_ON_CURVE}, + #else + {"POINT_IS_NOT_ON_CURVE", 16, 107}, + #endif + #ifdef EC_R_RANDOM_NUMBER_GENERATION_FAILED + {"RANDOM_NUMBER_GENERATION_FAILED", ERR_LIB_EC, EC_R_RANDOM_NUMBER_GENERATION_FAILED}, + #else + {"RANDOM_NUMBER_GENERATION_FAILED", 16, 158}, + #endif + #ifdef EC_R_SHARED_INFO_ERROR + {"SHARED_INFO_ERROR", ERR_LIB_EC, EC_R_SHARED_INFO_ERROR}, + #else + {"SHARED_INFO_ERROR", 16, 150}, + #endif + #ifdef EC_R_SLOT_FULL + {"SLOT_FULL", ERR_LIB_EC, EC_R_SLOT_FULL}, + #else + {"SLOT_FULL", 16, 108}, + #endif + #ifdef EC_R_TOO_MANY_RETRIES + {"TOO_MANY_RETRIES", ERR_LIB_EC, EC_R_TOO_MANY_RETRIES}, + #else + {"TOO_MANY_RETRIES", 16, 176}, + #endif + #ifdef EC_R_UNDEFINED_GENERATOR + {"UNDEFINED_GENERATOR", ERR_LIB_EC, EC_R_UNDEFINED_GENERATOR}, + #else + {"UNDEFINED_GENERATOR", 16, 113}, + #endif + #ifdef EC_R_UNDEFINED_ORDER + {"UNDEFINED_ORDER", ERR_LIB_EC, EC_R_UNDEFINED_ORDER}, + #else + {"UNDEFINED_ORDER", 16, 128}, + #endif + #ifdef EC_R_UNKNOWN_COFACTOR + {"UNKNOWN_COFACTOR", ERR_LIB_EC, EC_R_UNKNOWN_COFACTOR}, + #else + {"UNKNOWN_COFACTOR", 16, 164}, + #endif + #ifdef EC_R_UNKNOWN_GROUP + {"UNKNOWN_GROUP", ERR_LIB_EC, EC_R_UNKNOWN_GROUP}, + #else + {"UNKNOWN_GROUP", 16, 129}, + #endif + #ifdef EC_R_UNKNOWN_ORDER + {"UNKNOWN_ORDER", ERR_LIB_EC, EC_R_UNKNOWN_ORDER}, + #else + {"UNKNOWN_ORDER", 16, 114}, + #endif + #ifdef EC_R_UNSUPPORTED_FIELD + {"UNSUPPORTED_FIELD", ERR_LIB_EC, EC_R_UNSUPPORTED_FIELD}, + #else + {"UNSUPPORTED_FIELD", 16, 131}, + #endif + #ifdef EC_R_WRONG_CURVE_PARAMETERS + {"WRONG_CURVE_PARAMETERS", ERR_LIB_EC, EC_R_WRONG_CURVE_PARAMETERS}, + #else + {"WRONG_CURVE_PARAMETERS", 16, 145}, + #endif + #ifdef EC_R_WRONG_ORDER + {"WRONG_ORDER", ERR_LIB_EC, EC_R_WRONG_ORDER}, + #else + {"WRONG_ORDER", 16, 130}, + #endif + #ifdef ENGINE_R_ALREADY_LOADED + {"ALREADY_LOADED", ERR_LIB_ENGINE, ENGINE_R_ALREADY_LOADED}, + #else + {"ALREADY_LOADED", 38, 100}, + #endif + #ifdef ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER + {"ARGUMENT_IS_NOT_A_NUMBER", ERR_LIB_ENGINE, ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER}, + #else + {"ARGUMENT_IS_NOT_A_NUMBER", 38, 133}, + #endif + #ifdef ENGINE_R_CMD_NOT_EXECUTABLE + {"CMD_NOT_EXECUTABLE", ERR_LIB_ENGINE, ENGINE_R_CMD_NOT_EXECUTABLE}, + #else + {"CMD_NOT_EXECUTABLE", 38, 134}, + #endif + #ifdef ENGINE_R_COMMAND_TAKES_INPUT + {"COMMAND_TAKES_INPUT", ERR_LIB_ENGINE, ENGINE_R_COMMAND_TAKES_INPUT}, + #else + {"COMMAND_TAKES_INPUT", 38, 135}, + #endif + #ifdef ENGINE_R_COMMAND_TAKES_NO_INPUT + {"COMMAND_TAKES_NO_INPUT", ERR_LIB_ENGINE, ENGINE_R_COMMAND_TAKES_NO_INPUT}, + #else + {"COMMAND_TAKES_NO_INPUT", 38, 136}, + #endif + #ifdef ENGINE_R_CONFLICTING_ENGINE_ID + {"CONFLICTING_ENGINE_ID", ERR_LIB_ENGINE, ENGINE_R_CONFLICTING_ENGINE_ID}, + #else + {"CONFLICTING_ENGINE_ID", 38, 103}, + #endif + #ifdef ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED + {"CTRL_COMMAND_NOT_IMPLEMENTED", ERR_LIB_ENGINE, ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED}, + #else + {"CTRL_COMMAND_NOT_IMPLEMENTED", 38, 119}, + #endif + #ifdef ENGINE_R_DSO_FAILURE + {"DSO_FAILURE", ERR_LIB_ENGINE, ENGINE_R_DSO_FAILURE}, + #else + {"DSO_FAILURE", 38, 104}, + #endif + #ifdef ENGINE_R_DSO_NOT_FOUND + {"DSO_NOT_FOUND", ERR_LIB_ENGINE, ENGINE_R_DSO_NOT_FOUND}, + #else + {"DSO_NOT_FOUND", 38, 132}, + #endif + #ifdef ENGINE_R_ENGINES_SECTION_ERROR + {"ENGINES_SECTION_ERROR", ERR_LIB_ENGINE, ENGINE_R_ENGINES_SECTION_ERROR}, + #else + {"ENGINES_SECTION_ERROR", 38, 148}, + #endif + #ifdef ENGINE_R_ENGINE_CONFIGURATION_ERROR + {"ENGINE_CONFIGURATION_ERROR", ERR_LIB_ENGINE, ENGINE_R_ENGINE_CONFIGURATION_ERROR}, + #else + {"ENGINE_CONFIGURATION_ERROR", 38, 102}, + #endif + #ifdef ENGINE_R_ENGINE_IS_NOT_IN_LIST + {"ENGINE_IS_NOT_IN_LIST", ERR_LIB_ENGINE, ENGINE_R_ENGINE_IS_NOT_IN_LIST}, + #else + {"ENGINE_IS_NOT_IN_LIST", 38, 105}, + #endif + #ifdef ENGINE_R_ENGINE_SECTION_ERROR + {"ENGINE_SECTION_ERROR", ERR_LIB_ENGINE, ENGINE_R_ENGINE_SECTION_ERROR}, + #else + {"ENGINE_SECTION_ERROR", 38, 149}, + #endif + #ifdef ENGINE_R_FAILED_LOADING_PRIVATE_KEY + {"FAILED_LOADING_PRIVATE_KEY", ERR_LIB_ENGINE, ENGINE_R_FAILED_LOADING_PRIVATE_KEY}, + #else + {"FAILED_LOADING_PRIVATE_KEY", 38, 128}, + #endif + #ifdef ENGINE_R_FAILED_LOADING_PUBLIC_KEY + {"FAILED_LOADING_PUBLIC_KEY", ERR_LIB_ENGINE, ENGINE_R_FAILED_LOADING_PUBLIC_KEY}, + #else + {"FAILED_LOADING_PUBLIC_KEY", 38, 129}, + #endif + #ifdef ENGINE_R_FINISH_FAILED + {"FINISH_FAILED", ERR_LIB_ENGINE, ENGINE_R_FINISH_FAILED}, + #else + {"FINISH_FAILED", 38, 106}, + #endif + #ifdef ENGINE_R_ID_OR_NAME_MISSING + {"ID_OR_NAME_MISSING", ERR_LIB_ENGINE, ENGINE_R_ID_OR_NAME_MISSING}, + #else + {"ID_OR_NAME_MISSING", 38, 108}, + #endif + #ifdef ENGINE_R_INIT_FAILED + {"INIT_FAILED", ERR_LIB_ENGINE, ENGINE_R_INIT_FAILED}, + #else + {"INIT_FAILED", 38, 109}, + #endif + #ifdef ENGINE_R_INTERNAL_LIST_ERROR + {"INTERNAL_LIST_ERROR", ERR_LIB_ENGINE, ENGINE_R_INTERNAL_LIST_ERROR}, + #else + {"INTERNAL_LIST_ERROR", 38, 110}, + #endif + #ifdef ENGINE_R_INVALID_ARGUMENT + {"INVALID_ARGUMENT", ERR_LIB_ENGINE, ENGINE_R_INVALID_ARGUMENT}, + #else + {"INVALID_ARGUMENT", 38, 143}, + #endif + #ifdef ENGINE_R_INVALID_CMD_NAME + {"INVALID_CMD_NAME", ERR_LIB_ENGINE, ENGINE_R_INVALID_CMD_NAME}, + #else + {"INVALID_CMD_NAME", 38, 137}, + #endif + #ifdef ENGINE_R_INVALID_CMD_NUMBER + {"INVALID_CMD_NUMBER", ERR_LIB_ENGINE, ENGINE_R_INVALID_CMD_NUMBER}, + #else + {"INVALID_CMD_NUMBER", 38, 138}, + #endif + #ifdef ENGINE_R_INVALID_INIT_VALUE + {"INVALID_INIT_VALUE", ERR_LIB_ENGINE, ENGINE_R_INVALID_INIT_VALUE}, + #else + {"INVALID_INIT_VALUE", 38, 151}, + #endif + #ifdef ENGINE_R_INVALID_STRING + {"INVALID_STRING", ERR_LIB_ENGINE, ENGINE_R_INVALID_STRING}, + #else + {"INVALID_STRING", 38, 150}, + #endif + #ifdef ENGINE_R_NOT_INITIALISED + {"NOT_INITIALISED", ERR_LIB_ENGINE, ENGINE_R_NOT_INITIALISED}, + #else + {"NOT_INITIALISED", 38, 117}, + #endif + #ifdef ENGINE_R_NOT_LOADED + {"NOT_LOADED", ERR_LIB_ENGINE, ENGINE_R_NOT_LOADED}, + #else + {"NOT_LOADED", 38, 112}, + #endif + #ifdef ENGINE_R_NO_CONTROL_FUNCTION + {"NO_CONTROL_FUNCTION", ERR_LIB_ENGINE, ENGINE_R_NO_CONTROL_FUNCTION}, + #else + {"NO_CONTROL_FUNCTION", 38, 120}, + #endif + #ifdef ENGINE_R_NO_INDEX + {"NO_INDEX", ERR_LIB_ENGINE, ENGINE_R_NO_INDEX}, + #else + {"NO_INDEX", 38, 144}, + #endif + #ifdef ENGINE_R_NO_LOAD_FUNCTION + {"NO_LOAD_FUNCTION", ERR_LIB_ENGINE, ENGINE_R_NO_LOAD_FUNCTION}, + #else + {"NO_LOAD_FUNCTION", 38, 125}, + #endif + #ifdef ENGINE_R_NO_REFERENCE + {"NO_REFERENCE", ERR_LIB_ENGINE, ENGINE_R_NO_REFERENCE}, + #else + {"NO_REFERENCE", 38, 130}, + #endif + #ifdef ENGINE_R_NO_SUCH_ENGINE + {"NO_SUCH_ENGINE", ERR_LIB_ENGINE, ENGINE_R_NO_SUCH_ENGINE}, + #else + {"NO_SUCH_ENGINE", 38, 116}, + #endif + #ifdef ENGINE_R_UNIMPLEMENTED_CIPHER + {"UNIMPLEMENTED_CIPHER", ERR_LIB_ENGINE, ENGINE_R_UNIMPLEMENTED_CIPHER}, + #else + {"UNIMPLEMENTED_CIPHER", 38, 146}, + #endif + #ifdef ENGINE_R_UNIMPLEMENTED_DIGEST + {"UNIMPLEMENTED_DIGEST", ERR_LIB_ENGINE, ENGINE_R_UNIMPLEMENTED_DIGEST}, + #else + {"UNIMPLEMENTED_DIGEST", 38, 147}, + #endif + #ifdef ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD + {"UNIMPLEMENTED_PUBLIC_KEY_METHOD", ERR_LIB_ENGINE, ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD}, + #else + {"UNIMPLEMENTED_PUBLIC_KEY_METHOD", 38, 101}, + #endif + #ifdef ENGINE_R_VERSION_INCOMPATIBILITY + {"VERSION_INCOMPATIBILITY", ERR_LIB_ENGINE, ENGINE_R_VERSION_INCOMPATIBILITY}, + #else + {"VERSION_INCOMPATIBILITY", 38, 145}, + #endif + #ifdef ESS_R_EMPTY_ESS_CERT_ID_LIST + {"EMPTY_ESS_CERT_ID_LIST", ERR_LIB_ESS, ESS_R_EMPTY_ESS_CERT_ID_LIST}, + #else + {"EMPTY_ESS_CERT_ID_LIST", 54, 107}, + #endif + #ifdef ESS_R_ESS_CERT_DIGEST_ERROR + {"ESS_CERT_DIGEST_ERROR", ERR_LIB_ESS, ESS_R_ESS_CERT_DIGEST_ERROR}, + #else + {"ESS_CERT_DIGEST_ERROR", 54, 103}, + #endif + #ifdef ESS_R_ESS_CERT_ID_NOT_FOUND + {"ESS_CERT_ID_NOT_FOUND", ERR_LIB_ESS, ESS_R_ESS_CERT_ID_NOT_FOUND}, + #else + {"ESS_CERT_ID_NOT_FOUND", 54, 104}, + #endif + #ifdef ESS_R_ESS_CERT_ID_WRONG_ORDER + {"ESS_CERT_ID_WRONG_ORDER", ERR_LIB_ESS, ESS_R_ESS_CERT_ID_WRONG_ORDER}, + #else + {"ESS_CERT_ID_WRONG_ORDER", 54, 105}, + #endif + #ifdef ESS_R_ESS_DIGEST_ALG_UNKNOWN + {"ESS_DIGEST_ALG_UNKNOWN", ERR_LIB_ESS, ESS_R_ESS_DIGEST_ALG_UNKNOWN}, + #else + {"ESS_DIGEST_ALG_UNKNOWN", 54, 106}, + #endif + #ifdef ESS_R_ESS_SIGNING_CERTIFICATE_ERROR + {"ESS_SIGNING_CERTIFICATE_ERROR", ERR_LIB_ESS, ESS_R_ESS_SIGNING_CERTIFICATE_ERROR}, + #else + {"ESS_SIGNING_CERTIFICATE_ERROR", 54, 102}, + #endif + #ifdef ESS_R_ESS_SIGNING_CERT_ADD_ERROR + {"ESS_SIGNING_CERT_ADD_ERROR", ERR_LIB_ESS, ESS_R_ESS_SIGNING_CERT_ADD_ERROR}, + #else + {"ESS_SIGNING_CERT_ADD_ERROR", 54, 100}, + #endif + #ifdef ESS_R_ESS_SIGNING_CERT_V2_ADD_ERROR + {"ESS_SIGNING_CERT_V2_ADD_ERROR", ERR_LIB_ESS, ESS_R_ESS_SIGNING_CERT_V2_ADD_ERROR}, + #else + {"ESS_SIGNING_CERT_V2_ADD_ERROR", 54, 101}, + #endif + #ifdef ESS_R_MISSING_SIGNING_CERTIFICATE_ATTRIBUTE + {"MISSING_SIGNING_CERTIFICATE_ATTRIBUTE", ERR_LIB_ESS, ESS_R_MISSING_SIGNING_CERTIFICATE_ATTRIBUTE}, + #else + {"MISSING_SIGNING_CERTIFICATE_ATTRIBUTE", 54, 108}, + #endif + #ifdef EVP_R_AES_KEY_SETUP_FAILED + {"AES_KEY_SETUP_FAILED", ERR_LIB_EVP, EVP_R_AES_KEY_SETUP_FAILED}, + #else + {"AES_KEY_SETUP_FAILED", 6, 143}, + #endif + #ifdef EVP_R_ARIA_KEY_SETUP_FAILED + {"ARIA_KEY_SETUP_FAILED", ERR_LIB_EVP, EVP_R_ARIA_KEY_SETUP_FAILED}, + #else + {"ARIA_KEY_SETUP_FAILED", 6, 176}, + #endif + #ifdef EVP_R_BAD_ALGORITHM_NAME + {"BAD_ALGORITHM_NAME", ERR_LIB_EVP, EVP_R_BAD_ALGORITHM_NAME}, + #else + {"BAD_ALGORITHM_NAME", 6, 200}, + #endif + #ifdef EVP_R_BAD_DECRYPT + {"BAD_DECRYPT", ERR_LIB_EVP, EVP_R_BAD_DECRYPT}, + #else + {"BAD_DECRYPT", 6, 100}, + #endif + #ifdef EVP_R_BAD_KEY_LENGTH + {"BAD_KEY_LENGTH", ERR_LIB_EVP, EVP_R_BAD_KEY_LENGTH}, + #else + {"BAD_KEY_LENGTH", 6, 195}, + #endif + #ifdef EVP_R_BUFFER_TOO_SMALL + {"BUFFER_TOO_SMALL", ERR_LIB_EVP, EVP_R_BUFFER_TOO_SMALL}, + #else + {"BUFFER_TOO_SMALL", 6, 155}, + #endif + #ifdef EVP_R_CACHE_CONSTANTS_FAILED + {"CACHE_CONSTANTS_FAILED", ERR_LIB_EVP, EVP_R_CACHE_CONSTANTS_FAILED}, + #else + {"CACHE_CONSTANTS_FAILED", 6, 225}, + #endif + #ifdef EVP_R_CAMELLIA_KEY_SETUP_FAILED + {"CAMELLIA_KEY_SETUP_FAILED", ERR_LIB_EVP, EVP_R_CAMELLIA_KEY_SETUP_FAILED}, + #else + {"CAMELLIA_KEY_SETUP_FAILED", 6, 157}, + #endif + #ifdef EVP_R_CANNOT_GET_PARAMETERS + {"CANNOT_GET_PARAMETERS", ERR_LIB_EVP, EVP_R_CANNOT_GET_PARAMETERS}, + #else + {"CANNOT_GET_PARAMETERS", 6, 197}, + #endif + #ifdef EVP_R_CANNOT_SET_PARAMETERS + {"CANNOT_SET_PARAMETERS", ERR_LIB_EVP, EVP_R_CANNOT_SET_PARAMETERS}, + #else + {"CANNOT_SET_PARAMETERS", 6, 198}, + #endif + #ifdef EVP_R_CIPHER_NOT_GCM_MODE + {"CIPHER_NOT_GCM_MODE", ERR_LIB_EVP, EVP_R_CIPHER_NOT_GCM_MODE}, + #else + {"CIPHER_NOT_GCM_MODE", 6, 184}, + #endif + #ifdef EVP_R_CIPHER_PARAMETER_ERROR + {"CIPHER_PARAMETER_ERROR", ERR_LIB_EVP, EVP_R_CIPHER_PARAMETER_ERROR}, + #else + {"CIPHER_PARAMETER_ERROR", 6, 122}, + #endif + #ifdef EVP_R_COMMAND_NOT_SUPPORTED + {"COMMAND_NOT_SUPPORTED", ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED}, + #else + {"COMMAND_NOT_SUPPORTED", 6, 147}, + #endif + #ifdef EVP_R_CONFLICTING_ALGORITHM_NAME + {"CONFLICTING_ALGORITHM_NAME", ERR_LIB_EVP, EVP_R_CONFLICTING_ALGORITHM_NAME}, + #else + {"CONFLICTING_ALGORITHM_NAME", 6, 201}, + #endif + #ifdef EVP_R_COPY_ERROR + {"COPY_ERROR", ERR_LIB_EVP, EVP_R_COPY_ERROR}, + #else + {"COPY_ERROR", 6, 173}, + #endif + #ifdef EVP_R_CTRL_NOT_IMPLEMENTED + {"CTRL_NOT_IMPLEMENTED", ERR_LIB_EVP, EVP_R_CTRL_NOT_IMPLEMENTED}, + #else + {"CTRL_NOT_IMPLEMENTED", 6, 132}, + #endif + #ifdef EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED + {"CTRL_OPERATION_NOT_IMPLEMENTED", ERR_LIB_EVP, EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED}, + #else + {"CTRL_OPERATION_NOT_IMPLEMENTED", 6, 133}, + #endif + #ifdef EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH + {"DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH", ERR_LIB_EVP, EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH}, + #else + {"DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH", 6, 138}, + #endif + #ifdef EVP_R_DECODE_ERROR + {"DECODE_ERROR", ERR_LIB_EVP, EVP_R_DECODE_ERROR}, + #else + {"DECODE_ERROR", 6, 114}, + #endif + #ifdef EVP_R_DEFAULT_QUERY_PARSE_ERROR + {"DEFAULT_QUERY_PARSE_ERROR", ERR_LIB_EVP, EVP_R_DEFAULT_QUERY_PARSE_ERROR}, + #else + {"DEFAULT_QUERY_PARSE_ERROR", 6, 210}, + #endif + #ifdef EVP_R_DIFFERENT_KEY_TYPES + {"DIFFERENT_KEY_TYPES", ERR_LIB_EVP, EVP_R_DIFFERENT_KEY_TYPES}, + #else + {"DIFFERENT_KEY_TYPES", 6, 101}, + #endif + #ifdef EVP_R_DIFFERENT_PARAMETERS + {"DIFFERENT_PARAMETERS", ERR_LIB_EVP, EVP_R_DIFFERENT_PARAMETERS}, + #else + {"DIFFERENT_PARAMETERS", 6, 153}, + #endif + #ifdef EVP_R_ERROR_LOADING_SECTION + {"ERROR_LOADING_SECTION", ERR_LIB_EVP, EVP_R_ERROR_LOADING_SECTION}, + #else + {"ERROR_LOADING_SECTION", 6, 165}, + #endif + #ifdef EVP_R_EXPECTING_AN_HMAC_KEY + {"EXPECTING_AN_HMAC_KEY", ERR_LIB_EVP, EVP_R_EXPECTING_AN_HMAC_KEY}, + #else + {"EXPECTING_AN_HMAC_KEY", 6, 174}, + #endif + #ifdef EVP_R_EXPECTING_AN_RSA_KEY + {"EXPECTING_AN_RSA_KEY", ERR_LIB_EVP, EVP_R_EXPECTING_AN_RSA_KEY}, + #else + {"EXPECTING_AN_RSA_KEY", 6, 127}, + #endif + #ifdef EVP_R_EXPECTING_A_DH_KEY + {"EXPECTING_A_DH_KEY", ERR_LIB_EVP, EVP_R_EXPECTING_A_DH_KEY}, + #else + {"EXPECTING_A_DH_KEY", 6, 128}, + #endif + #ifdef EVP_R_EXPECTING_A_DSA_KEY + {"EXPECTING_A_DSA_KEY", ERR_LIB_EVP, EVP_R_EXPECTING_A_DSA_KEY}, + #else + {"EXPECTING_A_DSA_KEY", 6, 129}, + #endif + #ifdef EVP_R_EXPECTING_A_ECX_KEY + {"EXPECTING_A_ECX_KEY", ERR_LIB_EVP, EVP_R_EXPECTING_A_ECX_KEY}, + #else + {"EXPECTING_A_ECX_KEY", 6, 219}, + #endif + #ifdef EVP_R_EXPECTING_A_EC_KEY + {"EXPECTING_A_EC_KEY", ERR_LIB_EVP, EVP_R_EXPECTING_A_EC_KEY}, + #else + {"EXPECTING_A_EC_KEY", 6, 142}, + #endif + #ifdef EVP_R_EXPECTING_A_POLY1305_KEY + {"EXPECTING_A_POLY1305_KEY", ERR_LIB_EVP, EVP_R_EXPECTING_A_POLY1305_KEY}, + #else + {"EXPECTING_A_POLY1305_KEY", 6, 164}, + #endif + #ifdef EVP_R_EXPECTING_A_SIPHASH_KEY + {"EXPECTING_A_SIPHASH_KEY", ERR_LIB_EVP, EVP_R_EXPECTING_A_SIPHASH_KEY}, + #else + {"EXPECTING_A_SIPHASH_KEY", 6, 175}, + #endif + #ifdef EVP_R_FINAL_ERROR + {"FINAL_ERROR", ERR_LIB_EVP, EVP_R_FINAL_ERROR}, + #else + {"FINAL_ERROR", 6, 188}, + #endif + #ifdef EVP_R_GENERATE_ERROR + {"GENERATE_ERROR", ERR_LIB_EVP, EVP_R_GENERATE_ERROR}, + #else + {"GENERATE_ERROR", 6, 214}, + #endif + #ifdef EVP_R_GET_RAW_KEY_FAILED + {"GET_RAW_KEY_FAILED", ERR_LIB_EVP, EVP_R_GET_RAW_KEY_FAILED}, + #else + {"GET_RAW_KEY_FAILED", 6, 182}, + #endif + #ifdef EVP_R_ILLEGAL_SCRYPT_PARAMETERS + {"ILLEGAL_SCRYPT_PARAMETERS", ERR_LIB_EVP, EVP_R_ILLEGAL_SCRYPT_PARAMETERS}, + #else + {"ILLEGAL_SCRYPT_PARAMETERS", 6, 171}, + #endif + #ifdef EVP_R_INACCESSIBLE_DOMAIN_PARAMETERS + {"INACCESSIBLE_DOMAIN_PARAMETERS", ERR_LIB_EVP, EVP_R_INACCESSIBLE_DOMAIN_PARAMETERS}, + #else + {"INACCESSIBLE_DOMAIN_PARAMETERS", 6, 204}, + #endif + #ifdef EVP_R_INACCESSIBLE_KEY + {"INACCESSIBLE_KEY", ERR_LIB_EVP, EVP_R_INACCESSIBLE_KEY}, + #else + {"INACCESSIBLE_KEY", 6, 203}, + #endif + #ifdef EVP_R_INITIALIZATION_ERROR + {"INITIALIZATION_ERROR", ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR}, + #else + {"INITIALIZATION_ERROR", 6, 134}, + #endif + #ifdef EVP_R_INPUT_NOT_INITIALIZED + {"INPUT_NOT_INITIALIZED", ERR_LIB_EVP, EVP_R_INPUT_NOT_INITIALIZED}, + #else + {"INPUT_NOT_INITIALIZED", 6, 111}, + #endif + #ifdef EVP_R_INVALID_CUSTOM_LENGTH + {"INVALID_CUSTOM_LENGTH", ERR_LIB_EVP, EVP_R_INVALID_CUSTOM_LENGTH}, + #else + {"INVALID_CUSTOM_LENGTH", 6, 185}, + #endif + #ifdef EVP_R_INVALID_DIGEST + {"INVALID_DIGEST", ERR_LIB_EVP, EVP_R_INVALID_DIGEST}, + #else + {"INVALID_DIGEST", 6, 152}, + #endif + #ifdef EVP_R_INVALID_IV_LENGTH + {"INVALID_IV_LENGTH", ERR_LIB_EVP, EVP_R_INVALID_IV_LENGTH}, + #else + {"INVALID_IV_LENGTH", 6, 194}, + #endif + #ifdef EVP_R_INVALID_KEY + {"INVALID_KEY", ERR_LIB_EVP, EVP_R_INVALID_KEY}, + #else + {"INVALID_KEY", 6, 163}, + #endif + #ifdef EVP_R_INVALID_KEY_LENGTH + {"INVALID_KEY_LENGTH", ERR_LIB_EVP, EVP_R_INVALID_KEY_LENGTH}, + #else + {"INVALID_KEY_LENGTH", 6, 130}, + #endif + #ifdef EVP_R_INVALID_LENGTH + {"INVALID_LENGTH", ERR_LIB_EVP, EVP_R_INVALID_LENGTH}, + #else + {"INVALID_LENGTH", 6, 221}, + #endif + #ifdef EVP_R_INVALID_NULL_ALGORITHM + {"INVALID_NULL_ALGORITHM", ERR_LIB_EVP, EVP_R_INVALID_NULL_ALGORITHM}, + #else + {"INVALID_NULL_ALGORITHM", 6, 218}, + #endif + #ifdef EVP_R_INVALID_OPERATION + {"INVALID_OPERATION", ERR_LIB_EVP, EVP_R_INVALID_OPERATION}, + #else + {"INVALID_OPERATION", 6, 148}, + #endif + #ifdef EVP_R_INVALID_PROVIDER_FUNCTIONS + {"INVALID_PROVIDER_FUNCTIONS", ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS}, + #else + {"INVALID_PROVIDER_FUNCTIONS", 6, 193}, + #endif + #ifdef EVP_R_INVALID_SALT_LENGTH + {"INVALID_SALT_LENGTH", ERR_LIB_EVP, EVP_R_INVALID_SALT_LENGTH}, + #else + {"INVALID_SALT_LENGTH", 6, 186}, + #endif + #ifdef EVP_R_INVALID_SECRET_LENGTH + {"INVALID_SECRET_LENGTH", ERR_LIB_EVP, EVP_R_INVALID_SECRET_LENGTH}, + #else + {"INVALID_SECRET_LENGTH", 6, 223}, + #endif + #ifdef EVP_R_INVALID_SEED_LENGTH + {"INVALID_SEED_LENGTH", ERR_LIB_EVP, EVP_R_INVALID_SEED_LENGTH}, + #else + {"INVALID_SEED_LENGTH", 6, 220}, + #endif + #ifdef EVP_R_INVALID_VALUE + {"INVALID_VALUE", ERR_LIB_EVP, EVP_R_INVALID_VALUE}, + #else + {"INVALID_VALUE", 6, 222}, + #endif + #ifdef EVP_R_KEYMGMT_EXPORT_FAILURE + {"KEYMGMT_EXPORT_FAILURE", ERR_LIB_EVP, EVP_R_KEYMGMT_EXPORT_FAILURE}, + #else + {"KEYMGMT_EXPORT_FAILURE", 6, 205}, + #endif + #ifdef EVP_R_KEY_SETUP_FAILED + {"KEY_SETUP_FAILED", ERR_LIB_EVP, EVP_R_KEY_SETUP_FAILED}, + #else + {"KEY_SETUP_FAILED", 6, 180}, + #endif + #ifdef EVP_R_LOCKING_NOT_SUPPORTED + {"LOCKING_NOT_SUPPORTED", ERR_LIB_EVP, EVP_R_LOCKING_NOT_SUPPORTED}, + #else + {"LOCKING_NOT_SUPPORTED", 6, 213}, + #endif + #ifdef EVP_R_MEMORY_LIMIT_EXCEEDED + {"MEMORY_LIMIT_EXCEEDED", ERR_LIB_EVP, EVP_R_MEMORY_LIMIT_EXCEEDED}, + #else + {"MEMORY_LIMIT_EXCEEDED", 6, 172}, + #endif + #ifdef EVP_R_MESSAGE_DIGEST_IS_NULL + {"MESSAGE_DIGEST_IS_NULL", ERR_LIB_EVP, EVP_R_MESSAGE_DIGEST_IS_NULL}, + #else + {"MESSAGE_DIGEST_IS_NULL", 6, 159}, + #endif + #ifdef EVP_R_METHOD_NOT_SUPPORTED + {"METHOD_NOT_SUPPORTED", ERR_LIB_EVP, EVP_R_METHOD_NOT_SUPPORTED}, + #else + {"METHOD_NOT_SUPPORTED", 6, 144}, + #endif + #ifdef EVP_R_MISSING_PARAMETERS + {"MISSING_PARAMETERS", ERR_LIB_EVP, EVP_R_MISSING_PARAMETERS}, + #else + {"MISSING_PARAMETERS", 6, 103}, + #endif + #ifdef EVP_R_NOT_ABLE_TO_COPY_CTX + {"NOT_ABLE_TO_COPY_CTX", ERR_LIB_EVP, EVP_R_NOT_ABLE_TO_COPY_CTX}, + #else + {"NOT_ABLE_TO_COPY_CTX", 6, 190}, + #endif + #ifdef EVP_R_NOT_XOF_OR_INVALID_LENGTH + {"NOT_XOF_OR_INVALID_LENGTH", ERR_LIB_EVP, EVP_R_NOT_XOF_OR_INVALID_LENGTH}, + #else + {"NOT_XOF_OR_INVALID_LENGTH", 6, 178}, + #endif + #ifdef EVP_R_NO_CIPHER_SET + {"NO_CIPHER_SET", ERR_LIB_EVP, EVP_R_NO_CIPHER_SET}, + #else + {"NO_CIPHER_SET", 6, 131}, + #endif + #ifdef EVP_R_NO_DEFAULT_DIGEST + {"NO_DEFAULT_DIGEST", ERR_LIB_EVP, EVP_R_NO_DEFAULT_DIGEST}, + #else + {"NO_DEFAULT_DIGEST", 6, 158}, + #endif + #ifdef EVP_R_NO_DIGEST_SET + {"NO_DIGEST_SET", ERR_LIB_EVP, EVP_R_NO_DIGEST_SET}, + #else + {"NO_DIGEST_SET", 6, 139}, + #endif + #ifdef EVP_R_NO_IMPORT_FUNCTION + {"NO_IMPORT_FUNCTION", ERR_LIB_EVP, EVP_R_NO_IMPORT_FUNCTION}, + #else + {"NO_IMPORT_FUNCTION", 6, 206}, + #endif + #ifdef EVP_R_NO_KEYMGMT_AVAILABLE + {"NO_KEYMGMT_AVAILABLE", ERR_LIB_EVP, EVP_R_NO_KEYMGMT_AVAILABLE}, + #else + {"NO_KEYMGMT_AVAILABLE", 6, 199}, + #endif + #ifdef EVP_R_NO_KEYMGMT_PRESENT + {"NO_KEYMGMT_PRESENT", ERR_LIB_EVP, EVP_R_NO_KEYMGMT_PRESENT}, + #else + {"NO_KEYMGMT_PRESENT", 6, 196}, + #endif + #ifdef EVP_R_NO_KEY_SET + {"NO_KEY_SET", ERR_LIB_EVP, EVP_R_NO_KEY_SET}, + #else + {"NO_KEY_SET", 6, 154}, + #endif + #ifdef EVP_R_NO_OPERATION_SET + {"NO_OPERATION_SET", ERR_LIB_EVP, EVP_R_NO_OPERATION_SET}, + #else + {"NO_OPERATION_SET", 6, 149}, + #endif + #ifdef EVP_R_NULL_MAC_PKEY_CTX + {"NULL_MAC_PKEY_CTX", ERR_LIB_EVP, EVP_R_NULL_MAC_PKEY_CTX}, + #else + {"NULL_MAC_PKEY_CTX", 6, 208}, + #endif + #ifdef EVP_R_ONLY_ONESHOT_SUPPORTED + {"ONLY_ONESHOT_SUPPORTED", ERR_LIB_EVP, EVP_R_ONLY_ONESHOT_SUPPORTED}, + #else + {"ONLY_ONESHOT_SUPPORTED", 6, 177}, + #endif + #ifdef EVP_R_OPERATION_NOT_INITIALIZED + {"OPERATION_NOT_INITIALIZED", ERR_LIB_EVP, EVP_R_OPERATION_NOT_INITIALIZED}, + #else + {"OPERATION_NOT_INITIALIZED", 6, 151}, + #endif + #ifdef EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE + {"OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE", ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE}, + #else + {"OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE", 6, 150}, + #endif + #ifdef EVP_R_OUTPUT_WOULD_OVERFLOW + {"OUTPUT_WOULD_OVERFLOW", ERR_LIB_EVP, EVP_R_OUTPUT_WOULD_OVERFLOW}, + #else + {"OUTPUT_WOULD_OVERFLOW", 6, 202}, + #endif + #ifdef EVP_R_PARAMETER_TOO_LARGE + {"PARAMETER_TOO_LARGE", ERR_LIB_EVP, EVP_R_PARAMETER_TOO_LARGE}, + #else + {"PARAMETER_TOO_LARGE", 6, 187}, + #endif + #ifdef EVP_R_PARTIALLY_OVERLAPPING + {"PARTIALLY_OVERLAPPING", ERR_LIB_EVP, EVP_R_PARTIALLY_OVERLAPPING}, + #else + {"PARTIALLY_OVERLAPPING", 6, 162}, + #endif + #ifdef EVP_R_PBKDF2_ERROR + {"PBKDF2_ERROR", ERR_LIB_EVP, EVP_R_PBKDF2_ERROR}, + #else + {"PBKDF2_ERROR", 6, 181}, + #endif + #ifdef EVP_R_PKEY_APPLICATION_ASN1_METHOD_ALREADY_REGISTERED + {"PKEY_APPLICATION_ASN1_METHOD_ALREADY_REGISTERED", ERR_LIB_EVP, EVP_R_PKEY_APPLICATION_ASN1_METHOD_ALREADY_REGISTERED}, + #else + {"PKEY_APPLICATION_ASN1_METHOD_ALREADY_REGISTERED", 6, 179}, + #endif + #ifdef EVP_R_PRIVATE_KEY_DECODE_ERROR + {"PRIVATE_KEY_DECODE_ERROR", ERR_LIB_EVP, EVP_R_PRIVATE_KEY_DECODE_ERROR}, + #else + {"PRIVATE_KEY_DECODE_ERROR", 6, 145}, + #endif + #ifdef EVP_R_PRIVATE_KEY_ENCODE_ERROR + {"PRIVATE_KEY_ENCODE_ERROR", ERR_LIB_EVP, EVP_R_PRIVATE_KEY_ENCODE_ERROR}, + #else + {"PRIVATE_KEY_ENCODE_ERROR", 6, 146}, + #endif + #ifdef EVP_R_PUBLIC_KEY_NOT_RSA + {"PUBLIC_KEY_NOT_RSA", ERR_LIB_EVP, EVP_R_PUBLIC_KEY_NOT_RSA}, + #else + {"PUBLIC_KEY_NOT_RSA", 6, 106}, + #endif + #ifdef EVP_R_SETTING_XOF_FAILED + {"SETTING_XOF_FAILED", ERR_LIB_EVP, EVP_R_SETTING_XOF_FAILED}, + #else + {"SETTING_XOF_FAILED", 6, 227}, + #endif + #ifdef EVP_R_SET_DEFAULT_PROPERTY_FAILURE + {"SET_DEFAULT_PROPERTY_FAILURE", ERR_LIB_EVP, EVP_R_SET_DEFAULT_PROPERTY_FAILURE}, + #else + {"SET_DEFAULT_PROPERTY_FAILURE", 6, 209}, + #endif + #ifdef EVP_R_TOO_MANY_RECORDS + {"TOO_MANY_RECORDS", ERR_LIB_EVP, EVP_R_TOO_MANY_RECORDS}, + #else + {"TOO_MANY_RECORDS", 6, 183}, + #endif + #ifdef EVP_R_UNABLE_TO_ENABLE_LOCKING + {"UNABLE_TO_ENABLE_LOCKING", ERR_LIB_EVP, EVP_R_UNABLE_TO_ENABLE_LOCKING}, + #else + {"UNABLE_TO_ENABLE_LOCKING", 6, 212}, + #endif + #ifdef EVP_R_UNABLE_TO_GET_MAXIMUM_REQUEST_SIZE + {"UNABLE_TO_GET_MAXIMUM_REQUEST_SIZE", ERR_LIB_EVP, EVP_R_UNABLE_TO_GET_MAXIMUM_REQUEST_SIZE}, + #else + {"UNABLE_TO_GET_MAXIMUM_REQUEST_SIZE", 6, 215}, + #endif + #ifdef EVP_R_UNABLE_TO_GET_RANDOM_STRENGTH + {"UNABLE_TO_GET_RANDOM_STRENGTH", ERR_LIB_EVP, EVP_R_UNABLE_TO_GET_RANDOM_STRENGTH}, + #else + {"UNABLE_TO_GET_RANDOM_STRENGTH", 6, 216}, + #endif + #ifdef EVP_R_UNABLE_TO_LOCK_CONTEXT + {"UNABLE_TO_LOCK_CONTEXT", ERR_LIB_EVP, EVP_R_UNABLE_TO_LOCK_CONTEXT}, + #else + {"UNABLE_TO_LOCK_CONTEXT", 6, 211}, + #endif + #ifdef EVP_R_UNABLE_TO_SET_CALLBACKS + {"UNABLE_TO_SET_CALLBACKS", ERR_LIB_EVP, EVP_R_UNABLE_TO_SET_CALLBACKS}, + #else + {"UNABLE_TO_SET_CALLBACKS", 6, 217}, + #endif + #ifdef EVP_R_UNKNOWN_CIPHER + {"UNKNOWN_CIPHER", ERR_LIB_EVP, EVP_R_UNKNOWN_CIPHER}, + #else + {"UNKNOWN_CIPHER", 6, 160}, + #endif + #ifdef EVP_R_UNKNOWN_DIGEST + {"UNKNOWN_DIGEST", ERR_LIB_EVP, EVP_R_UNKNOWN_DIGEST}, + #else + {"UNKNOWN_DIGEST", 6, 161}, + #endif + #ifdef EVP_R_UNKNOWN_KEY_TYPE + {"UNKNOWN_KEY_TYPE", ERR_LIB_EVP, EVP_R_UNKNOWN_KEY_TYPE}, + #else + {"UNKNOWN_KEY_TYPE", 6, 207}, + #endif + #ifdef EVP_R_UNKNOWN_OPTION + {"UNKNOWN_OPTION", ERR_LIB_EVP, EVP_R_UNKNOWN_OPTION}, + #else + {"UNKNOWN_OPTION", 6, 169}, + #endif + #ifdef EVP_R_UNKNOWN_PBE_ALGORITHM + {"UNKNOWN_PBE_ALGORITHM", ERR_LIB_EVP, EVP_R_UNKNOWN_PBE_ALGORITHM}, + #else + {"UNKNOWN_PBE_ALGORITHM", 6, 121}, + #endif + #ifdef EVP_R_UNSUPPORTED_ALGORITHM + {"UNSUPPORTED_ALGORITHM", ERR_LIB_EVP, EVP_R_UNSUPPORTED_ALGORITHM}, + #else + {"UNSUPPORTED_ALGORITHM", 6, 156}, + #endif + #ifdef EVP_R_UNSUPPORTED_CIPHER + {"UNSUPPORTED_CIPHER", ERR_LIB_EVP, EVP_R_UNSUPPORTED_CIPHER}, + #else + {"UNSUPPORTED_CIPHER", 6, 107}, + #endif + #ifdef EVP_R_UNSUPPORTED_KEYLENGTH + {"UNSUPPORTED_KEYLENGTH", ERR_LIB_EVP, EVP_R_UNSUPPORTED_KEYLENGTH}, + #else + {"UNSUPPORTED_KEYLENGTH", 6, 123}, + #endif + #ifdef EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION + {"UNSUPPORTED_KEY_DERIVATION_FUNCTION", ERR_LIB_EVP, EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION}, + #else + {"UNSUPPORTED_KEY_DERIVATION_FUNCTION", 6, 124}, + #endif + #ifdef EVP_R_UNSUPPORTED_KEY_SIZE + {"UNSUPPORTED_KEY_SIZE", ERR_LIB_EVP, EVP_R_UNSUPPORTED_KEY_SIZE}, + #else + {"UNSUPPORTED_KEY_SIZE", 6, 108}, + #endif + #ifdef EVP_R_UNSUPPORTED_KEY_TYPE + {"UNSUPPORTED_KEY_TYPE", ERR_LIB_EVP, EVP_R_UNSUPPORTED_KEY_TYPE}, + #else + {"UNSUPPORTED_KEY_TYPE", 6, 224}, + #endif + #ifdef EVP_R_UNSUPPORTED_NUMBER_OF_ROUNDS + {"UNSUPPORTED_NUMBER_OF_ROUNDS", ERR_LIB_EVP, EVP_R_UNSUPPORTED_NUMBER_OF_ROUNDS}, + #else + {"UNSUPPORTED_NUMBER_OF_ROUNDS", 6, 135}, + #endif + #ifdef EVP_R_UNSUPPORTED_PRF + {"UNSUPPORTED_PRF", ERR_LIB_EVP, EVP_R_UNSUPPORTED_PRF}, + #else + {"UNSUPPORTED_PRF", 6, 125}, + #endif + #ifdef EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM + {"UNSUPPORTED_PRIVATE_KEY_ALGORITHM", ERR_LIB_EVP, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM}, + #else + {"UNSUPPORTED_PRIVATE_KEY_ALGORITHM", 6, 118}, + #endif + #ifdef EVP_R_UNSUPPORTED_SALT_TYPE + {"UNSUPPORTED_SALT_TYPE", ERR_LIB_EVP, EVP_R_UNSUPPORTED_SALT_TYPE}, + #else + {"UNSUPPORTED_SALT_TYPE", 6, 126}, + #endif + #ifdef EVP_R_UPDATE_ERROR + {"UPDATE_ERROR", ERR_LIB_EVP, EVP_R_UPDATE_ERROR}, + #else + {"UPDATE_ERROR", 6, 189}, + #endif + #ifdef EVP_R_WRAP_MODE_NOT_ALLOWED + {"WRAP_MODE_NOT_ALLOWED", ERR_LIB_EVP, EVP_R_WRAP_MODE_NOT_ALLOWED}, + #else + {"WRAP_MODE_NOT_ALLOWED", 6, 170}, + #endif + #ifdef EVP_R_WRONG_FINAL_BLOCK_LENGTH + {"WRONG_FINAL_BLOCK_LENGTH", ERR_LIB_EVP, EVP_R_WRONG_FINAL_BLOCK_LENGTH}, + #else + {"WRONG_FINAL_BLOCK_LENGTH", 6, 109}, + #endif + #ifdef EVP_R_XTS_DATA_UNIT_IS_TOO_LARGE + {"XTS_DATA_UNIT_IS_TOO_LARGE", ERR_LIB_EVP, EVP_R_XTS_DATA_UNIT_IS_TOO_LARGE}, + #else + {"XTS_DATA_UNIT_IS_TOO_LARGE", 6, 191}, + #endif + #ifdef EVP_R_XTS_DUPLICATED_KEYS + {"XTS_DUPLICATED_KEYS", ERR_LIB_EVP, EVP_R_XTS_DUPLICATED_KEYS}, + #else + {"XTS_DUPLICATED_KEYS", 6, 192}, + #endif + #ifdef HTTP_R_ASN1_LEN_EXCEEDS_MAX_RESP_LEN + {"ASN1_LEN_EXCEEDS_MAX_RESP_LEN", ERR_LIB_HTTP, HTTP_R_ASN1_LEN_EXCEEDS_MAX_RESP_LEN}, + #else + {"ASN1_LEN_EXCEEDS_MAX_RESP_LEN", 61, 108}, + #endif + #ifdef HTTP_R_CONNECT_FAILURE + {"CONNECT_FAILURE", ERR_LIB_HTTP, HTTP_R_CONNECT_FAILURE}, + #else + {"CONNECT_FAILURE", 61, 100}, + #endif + #ifdef HTTP_R_ERROR_PARSING_ASN1_LENGTH + {"ERROR_PARSING_ASN1_LENGTH", ERR_LIB_HTTP, HTTP_R_ERROR_PARSING_ASN1_LENGTH}, + #else + {"ERROR_PARSING_ASN1_LENGTH", 61, 109}, + #endif + #ifdef HTTP_R_ERROR_PARSING_CONTENT_LENGTH + {"ERROR_PARSING_CONTENT_LENGTH", ERR_LIB_HTTP, HTTP_R_ERROR_PARSING_CONTENT_LENGTH}, + #else + {"ERROR_PARSING_CONTENT_LENGTH", 61, 119}, + #endif + #ifdef HTTP_R_ERROR_PARSING_URL + {"ERROR_PARSING_URL", ERR_LIB_HTTP, HTTP_R_ERROR_PARSING_URL}, + #else + {"ERROR_PARSING_URL", 61, 101}, + #endif + #ifdef HTTP_R_ERROR_RECEIVING + {"ERROR_RECEIVING", ERR_LIB_HTTP, HTTP_R_ERROR_RECEIVING}, + #else + {"ERROR_RECEIVING", 61, 103}, + #endif + #ifdef HTTP_R_ERROR_SENDING + {"ERROR_SENDING", ERR_LIB_HTTP, HTTP_R_ERROR_SENDING}, + #else + {"ERROR_SENDING", 61, 102}, + #endif + #ifdef HTTP_R_FAILED_READING_DATA + {"FAILED_READING_DATA", ERR_LIB_HTTP, HTTP_R_FAILED_READING_DATA}, + #else + {"FAILED_READING_DATA", 61, 128}, + #endif + #ifdef HTTP_R_HEADER_PARSE_ERROR + {"HEADER_PARSE_ERROR", ERR_LIB_HTTP, HTTP_R_HEADER_PARSE_ERROR}, + #else + {"HEADER_PARSE_ERROR", 61, 126}, + #endif + #ifdef HTTP_R_INCONSISTENT_CONTENT_LENGTH + {"INCONSISTENT_CONTENT_LENGTH", ERR_LIB_HTTP, HTTP_R_INCONSISTENT_CONTENT_LENGTH}, + #else + {"INCONSISTENT_CONTENT_LENGTH", 61, 120}, + #endif + #ifdef HTTP_R_INVALID_PORT_NUMBER + {"INVALID_PORT_NUMBER", ERR_LIB_HTTP, HTTP_R_INVALID_PORT_NUMBER}, + #else + {"INVALID_PORT_NUMBER", 61, 123}, + #endif + #ifdef HTTP_R_INVALID_URL_PATH + {"INVALID_URL_PATH", ERR_LIB_HTTP, HTTP_R_INVALID_URL_PATH}, + #else + {"INVALID_URL_PATH", 61, 125}, + #endif + #ifdef HTTP_R_INVALID_URL_SCHEME + {"INVALID_URL_SCHEME", ERR_LIB_HTTP, HTTP_R_INVALID_URL_SCHEME}, + #else + {"INVALID_URL_SCHEME", 61, 124}, + #endif + #ifdef HTTP_R_MAX_RESP_LEN_EXCEEDED + {"MAX_RESP_LEN_EXCEEDED", ERR_LIB_HTTP, HTTP_R_MAX_RESP_LEN_EXCEEDED}, + #else + {"MAX_RESP_LEN_EXCEEDED", 61, 117}, + #endif + #ifdef HTTP_R_MISSING_ASN1_ENCODING + {"MISSING_ASN1_ENCODING", ERR_LIB_HTTP, HTTP_R_MISSING_ASN1_ENCODING}, + #else + {"MISSING_ASN1_ENCODING", 61, 110}, + #endif + #ifdef HTTP_R_MISSING_CONTENT_TYPE + {"MISSING_CONTENT_TYPE", ERR_LIB_HTTP, HTTP_R_MISSING_CONTENT_TYPE}, + #else + {"MISSING_CONTENT_TYPE", 61, 121}, + #endif + #ifdef HTTP_R_MISSING_REDIRECT_LOCATION + {"MISSING_REDIRECT_LOCATION", ERR_LIB_HTTP, HTTP_R_MISSING_REDIRECT_LOCATION}, + #else + {"MISSING_REDIRECT_LOCATION", 61, 111}, + #endif + #ifdef HTTP_R_RECEIVED_ERROR + {"RECEIVED_ERROR", ERR_LIB_HTTP, HTTP_R_RECEIVED_ERROR}, + #else + {"RECEIVED_ERROR", 61, 105}, + #endif + #ifdef HTTP_R_RECEIVED_WRONG_HTTP_VERSION + {"RECEIVED_WRONG_HTTP_VERSION", ERR_LIB_HTTP, HTTP_R_RECEIVED_WRONG_HTTP_VERSION}, + #else + {"RECEIVED_WRONG_HTTP_VERSION", 61, 106}, + #endif + #ifdef HTTP_R_REDIRECTION_FROM_HTTPS_TO_HTTP + {"REDIRECTION_FROM_HTTPS_TO_HTTP", ERR_LIB_HTTP, HTTP_R_REDIRECTION_FROM_HTTPS_TO_HTTP}, + #else + {"REDIRECTION_FROM_HTTPS_TO_HTTP", 61, 112}, + #endif + #ifdef HTTP_R_REDIRECTION_NOT_ENABLED + {"REDIRECTION_NOT_ENABLED", ERR_LIB_HTTP, HTTP_R_REDIRECTION_NOT_ENABLED}, + #else + {"REDIRECTION_NOT_ENABLED", 61, 116}, + #endif + #ifdef HTTP_R_RESPONSE_LINE_TOO_LONG + {"RESPONSE_LINE_TOO_LONG", ERR_LIB_HTTP, HTTP_R_RESPONSE_LINE_TOO_LONG}, + #else + {"RESPONSE_LINE_TOO_LONG", 61, 113}, + #endif + #ifdef HTTP_R_RESPONSE_PARSE_ERROR + {"RESPONSE_PARSE_ERROR", ERR_LIB_HTTP, HTTP_R_RESPONSE_PARSE_ERROR}, + #else + {"RESPONSE_PARSE_ERROR", 61, 104}, + #endif + #ifdef HTTP_R_RETRY_TIMEOUT + {"RETRY_TIMEOUT", ERR_LIB_HTTP, HTTP_R_RETRY_TIMEOUT}, + #else + {"RETRY_TIMEOUT", 61, 129}, + #endif + #ifdef HTTP_R_SERVER_CANCELED_CONNECTION + {"SERVER_CANCELED_CONNECTION", ERR_LIB_HTTP, HTTP_R_SERVER_CANCELED_CONNECTION}, + #else + {"SERVER_CANCELED_CONNECTION", 61, 127}, + #endif + #ifdef HTTP_R_SOCK_NOT_SUPPORTED + {"SOCK_NOT_SUPPORTED", ERR_LIB_HTTP, HTTP_R_SOCK_NOT_SUPPORTED}, + #else + {"SOCK_NOT_SUPPORTED", 61, 122}, + #endif + #ifdef HTTP_R_STATUS_CODE_UNSUPPORTED + {"STATUS_CODE_UNSUPPORTED", ERR_LIB_HTTP, HTTP_R_STATUS_CODE_UNSUPPORTED}, + #else + {"STATUS_CODE_UNSUPPORTED", 61, 114}, + #endif + #ifdef HTTP_R_TLS_NOT_ENABLED + {"TLS_NOT_ENABLED", ERR_LIB_HTTP, HTTP_R_TLS_NOT_ENABLED}, + #else + {"TLS_NOT_ENABLED", 61, 107}, + #endif + #ifdef HTTP_R_TOO_MANY_REDIRECTIONS + {"TOO_MANY_REDIRECTIONS", ERR_LIB_HTTP, HTTP_R_TOO_MANY_REDIRECTIONS}, + #else + {"TOO_MANY_REDIRECTIONS", 61, 115}, + #endif + #ifdef HTTP_R_UNEXPECTED_CONTENT_TYPE + {"UNEXPECTED_CONTENT_TYPE", ERR_LIB_HTTP, HTTP_R_UNEXPECTED_CONTENT_TYPE}, + #else + {"UNEXPECTED_CONTENT_TYPE", 61, 118}, + #endif + #ifdef OBJ_R_OID_EXISTS + {"OID_EXISTS", ERR_LIB_OBJ, OBJ_R_OID_EXISTS}, + #else + {"OID_EXISTS", 8, 102}, + #endif + #ifdef OBJ_R_UNKNOWN_NID + {"UNKNOWN_NID", ERR_LIB_OBJ, OBJ_R_UNKNOWN_NID}, + #else + {"UNKNOWN_NID", 8, 101}, + #endif + #ifdef OBJ_R_UNKNOWN_OBJECT_NAME + {"UNKNOWN_OBJECT_NAME", ERR_LIB_OBJ, OBJ_R_UNKNOWN_OBJECT_NAME}, + #else + {"UNKNOWN_OBJECT_NAME", 8, 103}, + #endif + #ifdef OCSP_R_CERTIFICATE_VERIFY_ERROR + {"CERTIFICATE_VERIFY_ERROR", ERR_LIB_OCSP, OCSP_R_CERTIFICATE_VERIFY_ERROR}, + #else + {"CERTIFICATE_VERIFY_ERROR", 39, 101}, + #endif + #ifdef OCSP_R_DIGEST_ERR + {"DIGEST_ERR", ERR_LIB_OCSP, OCSP_R_DIGEST_ERR}, + #else + {"DIGEST_ERR", 39, 102}, + #endif + #ifdef OCSP_R_DIGEST_NAME_ERR + {"DIGEST_NAME_ERR", ERR_LIB_OCSP, OCSP_R_DIGEST_NAME_ERR}, + #else + {"DIGEST_NAME_ERR", 39, 106}, + #endif + #ifdef OCSP_R_DIGEST_SIZE_ERR + {"DIGEST_SIZE_ERR", ERR_LIB_OCSP, OCSP_R_DIGEST_SIZE_ERR}, + #else + {"DIGEST_SIZE_ERR", 39, 107}, + #endif + #ifdef OCSP_R_ERROR_IN_NEXTUPDATE_FIELD + {"ERROR_IN_NEXTUPDATE_FIELD", ERR_LIB_OCSP, OCSP_R_ERROR_IN_NEXTUPDATE_FIELD}, + #else + {"ERROR_IN_NEXTUPDATE_FIELD", 39, 122}, + #endif + #ifdef OCSP_R_ERROR_IN_THISUPDATE_FIELD + {"ERROR_IN_THISUPDATE_FIELD", ERR_LIB_OCSP, OCSP_R_ERROR_IN_THISUPDATE_FIELD}, + #else + {"ERROR_IN_THISUPDATE_FIELD", 39, 123}, + #endif + #ifdef OCSP_R_MISSING_OCSPSIGNING_USAGE + {"MISSING_OCSPSIGNING_USAGE", ERR_LIB_OCSP, OCSP_R_MISSING_OCSPSIGNING_USAGE}, + #else + {"MISSING_OCSPSIGNING_USAGE", 39, 103}, + #endif + #ifdef OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE + {"NEXTUPDATE_BEFORE_THISUPDATE", ERR_LIB_OCSP, OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE}, + #else + {"NEXTUPDATE_BEFORE_THISUPDATE", 39, 124}, + #endif + #ifdef OCSP_R_NOT_BASIC_RESPONSE + {"NOT_BASIC_RESPONSE", ERR_LIB_OCSP, OCSP_R_NOT_BASIC_RESPONSE}, + #else + {"NOT_BASIC_RESPONSE", 39, 104}, + #endif + #ifdef OCSP_R_NO_CERTIFICATES_IN_CHAIN + {"NO_CERTIFICATES_IN_CHAIN", ERR_LIB_OCSP, OCSP_R_NO_CERTIFICATES_IN_CHAIN}, + #else + {"NO_CERTIFICATES_IN_CHAIN", 39, 105}, + #endif + #ifdef OCSP_R_NO_RESPONSE_DATA + {"NO_RESPONSE_DATA", ERR_LIB_OCSP, OCSP_R_NO_RESPONSE_DATA}, + #else + {"NO_RESPONSE_DATA", 39, 108}, + #endif + #ifdef OCSP_R_NO_REVOKED_TIME + {"NO_REVOKED_TIME", ERR_LIB_OCSP, OCSP_R_NO_REVOKED_TIME}, + #else + {"NO_REVOKED_TIME", 39, 109}, + #endif + #ifdef OCSP_R_NO_SIGNER_KEY + {"NO_SIGNER_KEY", ERR_LIB_OCSP, OCSP_R_NO_SIGNER_KEY}, + #else + {"NO_SIGNER_KEY", 39, 130}, + #endif + #ifdef OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE + {"PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE", ERR_LIB_OCSP, OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE}, + #else + {"PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE", 39, 110}, + #endif + #ifdef OCSP_R_REQUEST_NOT_SIGNED + {"REQUEST_NOT_SIGNED", ERR_LIB_OCSP, OCSP_R_REQUEST_NOT_SIGNED}, + #else + {"REQUEST_NOT_SIGNED", 39, 128}, + #endif + #ifdef OCSP_R_RESPONSE_CONTAINS_NO_REVOCATION_DATA + {"RESPONSE_CONTAINS_NO_REVOCATION_DATA", ERR_LIB_OCSP, OCSP_R_RESPONSE_CONTAINS_NO_REVOCATION_DATA}, + #else + {"RESPONSE_CONTAINS_NO_REVOCATION_DATA", 39, 111}, + #endif + #ifdef OCSP_R_ROOT_CA_NOT_TRUSTED + {"ROOT_CA_NOT_TRUSTED", ERR_LIB_OCSP, OCSP_R_ROOT_CA_NOT_TRUSTED}, + #else + {"ROOT_CA_NOT_TRUSTED", 39, 112}, + #endif + #ifdef OCSP_R_SIGNATURE_FAILURE + {"SIGNATURE_FAILURE", ERR_LIB_OCSP, OCSP_R_SIGNATURE_FAILURE}, + #else + {"SIGNATURE_FAILURE", 39, 117}, + #endif + #ifdef OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND + {"SIGNER_CERTIFICATE_NOT_FOUND", ERR_LIB_OCSP, OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND}, + #else + {"SIGNER_CERTIFICATE_NOT_FOUND", 39, 118}, + #endif + #ifdef OCSP_R_STATUS_EXPIRED + {"STATUS_EXPIRED", ERR_LIB_OCSP, OCSP_R_STATUS_EXPIRED}, + #else + {"STATUS_EXPIRED", 39, 125}, + #endif + #ifdef OCSP_R_STATUS_NOT_YET_VALID + {"STATUS_NOT_YET_VALID", ERR_LIB_OCSP, OCSP_R_STATUS_NOT_YET_VALID}, + #else + {"STATUS_NOT_YET_VALID", 39, 126}, + #endif + #ifdef OCSP_R_STATUS_TOO_OLD + {"STATUS_TOO_OLD", ERR_LIB_OCSP, OCSP_R_STATUS_TOO_OLD}, + #else + {"STATUS_TOO_OLD", 39, 127}, + #endif + #ifdef OCSP_R_UNKNOWN_MESSAGE_DIGEST + {"UNKNOWN_MESSAGE_DIGEST", ERR_LIB_OCSP, OCSP_R_UNKNOWN_MESSAGE_DIGEST}, + #else + {"UNKNOWN_MESSAGE_DIGEST", 39, 119}, + #endif + #ifdef OCSP_R_UNKNOWN_NID + {"UNKNOWN_NID", ERR_LIB_OCSP, OCSP_R_UNKNOWN_NID}, + #else + {"UNKNOWN_NID", 39, 120}, + #endif + #ifdef OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE + {"UNSUPPORTED_REQUESTORNAME_TYPE", ERR_LIB_OCSP, OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE}, + #else + {"UNSUPPORTED_REQUESTORNAME_TYPE", 39, 129}, + #endif + #ifdef OSSL_DECODER_R_COULD_NOT_DECODE_OBJECT + {"COULD_NOT_DECODE_OBJECT", ERR_LIB_OSSL_DECODER, OSSL_DECODER_R_COULD_NOT_DECODE_OBJECT}, + #else + {"COULD_NOT_DECODE_OBJECT", 60, 101}, + #endif + #ifdef OSSL_DECODER_R_DECODER_NOT_FOUND + {"DECODER_NOT_FOUND", ERR_LIB_OSSL_DECODER, OSSL_DECODER_R_DECODER_NOT_FOUND}, + #else + {"DECODER_NOT_FOUND", 60, 102}, + #endif + #ifdef OSSL_DECODER_R_MISSING_GET_PARAMS + {"MISSING_GET_PARAMS", ERR_LIB_OSSL_DECODER, OSSL_DECODER_R_MISSING_GET_PARAMS}, + #else + {"MISSING_GET_PARAMS", 60, 100}, + #endif + #ifdef OSSL_ENCODER_R_ENCODER_NOT_FOUND + {"ENCODER_NOT_FOUND", ERR_LIB_OSSL_ENCODER, OSSL_ENCODER_R_ENCODER_NOT_FOUND}, + #else + {"ENCODER_NOT_FOUND", 59, 101}, + #endif + #ifdef OSSL_ENCODER_R_INCORRECT_PROPERTY_QUERY + {"INCORRECT_PROPERTY_QUERY", ERR_LIB_OSSL_ENCODER, OSSL_ENCODER_R_INCORRECT_PROPERTY_QUERY}, + #else + {"INCORRECT_PROPERTY_QUERY", 59, 100}, + #endif + #ifdef OSSL_ENCODER_R_MISSING_GET_PARAMS + {"MISSING_GET_PARAMS", ERR_LIB_OSSL_ENCODER, OSSL_ENCODER_R_MISSING_GET_PARAMS}, + #else + {"MISSING_GET_PARAMS", 59, 102}, + #endif + #ifdef OSSL_STORE_R_AMBIGUOUS_CONTENT_TYPE + {"AMBIGUOUS_CONTENT_TYPE", ERR_LIB_OSSL_STORE, OSSL_STORE_R_AMBIGUOUS_CONTENT_TYPE}, + #else + {"AMBIGUOUS_CONTENT_TYPE", 44, 107}, + #endif + #ifdef OSSL_STORE_R_BAD_PASSWORD_READ + {"BAD_PASSWORD_READ", ERR_LIB_OSSL_STORE, OSSL_STORE_R_BAD_PASSWORD_READ}, + #else + {"BAD_PASSWORD_READ", 44, 115}, + #endif + #ifdef OSSL_STORE_R_ERROR_VERIFYING_PKCS12_MAC + {"ERROR_VERIFYING_PKCS12_MAC", ERR_LIB_OSSL_STORE, OSSL_STORE_R_ERROR_VERIFYING_PKCS12_MAC}, + #else + {"ERROR_VERIFYING_PKCS12_MAC", 44, 113}, + #endif + #ifdef OSSL_STORE_R_FINGERPRINT_SIZE_DOES_NOT_MATCH_DIGEST + {"FINGERPRINT_SIZE_DOES_NOT_MATCH_DIGEST", ERR_LIB_OSSL_STORE, OSSL_STORE_R_FINGERPRINT_SIZE_DOES_NOT_MATCH_DIGEST}, + #else + {"FINGERPRINT_SIZE_DOES_NOT_MATCH_DIGEST", 44, 121}, + #endif + #ifdef OSSL_STORE_R_INVALID_SCHEME + {"INVALID_SCHEME", ERR_LIB_OSSL_STORE, OSSL_STORE_R_INVALID_SCHEME}, + #else + {"INVALID_SCHEME", 44, 106}, + #endif + #ifdef OSSL_STORE_R_IS_NOT_A + {"IS_NOT_A", ERR_LIB_OSSL_STORE, OSSL_STORE_R_IS_NOT_A}, + #else + {"IS_NOT_A", 44, 112}, + #endif + #ifdef OSSL_STORE_R_LOADER_INCOMPLETE + {"LOADER_INCOMPLETE", ERR_LIB_OSSL_STORE, OSSL_STORE_R_LOADER_INCOMPLETE}, + #else + {"LOADER_INCOMPLETE", 44, 116}, + #endif + #ifdef OSSL_STORE_R_LOADING_STARTED + {"LOADING_STARTED", ERR_LIB_OSSL_STORE, OSSL_STORE_R_LOADING_STARTED}, + #else + {"LOADING_STARTED", 44, 117}, + #endif + #ifdef OSSL_STORE_R_NOT_A_CERTIFICATE + {"NOT_A_CERTIFICATE", ERR_LIB_OSSL_STORE, OSSL_STORE_R_NOT_A_CERTIFICATE}, + #else + {"NOT_A_CERTIFICATE", 44, 100}, + #endif + #ifdef OSSL_STORE_R_NOT_A_CRL + {"NOT_A_CRL", ERR_LIB_OSSL_STORE, OSSL_STORE_R_NOT_A_CRL}, + #else + {"NOT_A_CRL", 44, 101}, + #endif + #ifdef OSSL_STORE_R_NOT_A_NAME + {"NOT_A_NAME", ERR_LIB_OSSL_STORE, OSSL_STORE_R_NOT_A_NAME}, + #else + {"NOT_A_NAME", 44, 103}, + #endif + #ifdef OSSL_STORE_R_NOT_A_PRIVATE_KEY + {"NOT_A_PRIVATE_KEY", ERR_LIB_OSSL_STORE, OSSL_STORE_R_NOT_A_PRIVATE_KEY}, + #else + {"NOT_A_PRIVATE_KEY", 44, 102}, + #endif + #ifdef OSSL_STORE_R_NOT_A_PUBLIC_KEY + {"NOT_A_PUBLIC_KEY", ERR_LIB_OSSL_STORE, OSSL_STORE_R_NOT_A_PUBLIC_KEY}, + #else + {"NOT_A_PUBLIC_KEY", 44, 122}, + #endif + #ifdef OSSL_STORE_R_NOT_PARAMETERS + {"NOT_PARAMETERS", ERR_LIB_OSSL_STORE, OSSL_STORE_R_NOT_PARAMETERS}, + #else + {"NOT_PARAMETERS", 44, 104}, + #endif + #ifdef OSSL_STORE_R_NO_LOADERS_FOUND + {"NO_LOADERS_FOUND", ERR_LIB_OSSL_STORE, OSSL_STORE_R_NO_LOADERS_FOUND}, + #else + {"NO_LOADERS_FOUND", 44, 123}, + #endif + #ifdef OSSL_STORE_R_PASSPHRASE_CALLBACK_ERROR + {"PASSPHRASE_CALLBACK_ERROR", ERR_LIB_OSSL_STORE, OSSL_STORE_R_PASSPHRASE_CALLBACK_ERROR}, + #else + {"PASSPHRASE_CALLBACK_ERROR", 44, 114}, + #endif + #ifdef OSSL_STORE_R_PATH_MUST_BE_ABSOLUTE + {"PATH_MUST_BE_ABSOLUTE", ERR_LIB_OSSL_STORE, OSSL_STORE_R_PATH_MUST_BE_ABSOLUTE}, + #else + {"PATH_MUST_BE_ABSOLUTE", 44, 108}, + #endif + #ifdef OSSL_STORE_R_SEARCH_ONLY_SUPPORTED_FOR_DIRECTORIES + {"SEARCH_ONLY_SUPPORTED_FOR_DIRECTORIES", ERR_LIB_OSSL_STORE, OSSL_STORE_R_SEARCH_ONLY_SUPPORTED_FOR_DIRECTORIES}, + #else + {"SEARCH_ONLY_SUPPORTED_FOR_DIRECTORIES", 44, 119}, + #endif + #ifdef OSSL_STORE_R_UI_PROCESS_INTERRUPTED_OR_CANCELLED + {"UI_PROCESS_INTERRUPTED_OR_CANCELLED", ERR_LIB_OSSL_STORE, OSSL_STORE_R_UI_PROCESS_INTERRUPTED_OR_CANCELLED}, + #else + {"UI_PROCESS_INTERRUPTED_OR_CANCELLED", 44, 109}, + #endif + #ifdef OSSL_STORE_R_UNREGISTERED_SCHEME + {"UNREGISTERED_SCHEME", ERR_LIB_OSSL_STORE, OSSL_STORE_R_UNREGISTERED_SCHEME}, + #else + {"UNREGISTERED_SCHEME", 44, 105}, + #endif + #ifdef OSSL_STORE_R_UNSUPPORTED_CONTENT_TYPE + {"UNSUPPORTED_CONTENT_TYPE", ERR_LIB_OSSL_STORE, OSSL_STORE_R_UNSUPPORTED_CONTENT_TYPE}, + #else + {"UNSUPPORTED_CONTENT_TYPE", 44, 110}, + #endif + #ifdef OSSL_STORE_R_UNSUPPORTED_OPERATION + {"UNSUPPORTED_OPERATION", ERR_LIB_OSSL_STORE, OSSL_STORE_R_UNSUPPORTED_OPERATION}, + #else + {"UNSUPPORTED_OPERATION", 44, 118}, + #endif + #ifdef OSSL_STORE_R_UNSUPPORTED_SEARCH_TYPE + {"UNSUPPORTED_SEARCH_TYPE", ERR_LIB_OSSL_STORE, OSSL_STORE_R_UNSUPPORTED_SEARCH_TYPE}, + #else + {"UNSUPPORTED_SEARCH_TYPE", 44, 120}, + #endif + #ifdef OSSL_STORE_R_URI_AUTHORITY_UNSUPPORTED + {"URI_AUTHORITY_UNSUPPORTED", ERR_LIB_OSSL_STORE, OSSL_STORE_R_URI_AUTHORITY_UNSUPPORTED}, + #else + {"URI_AUTHORITY_UNSUPPORTED", 44, 111}, + #endif + #ifdef PEM_R_BAD_BASE64_DECODE + {"BAD_BASE64_DECODE", ERR_LIB_PEM, PEM_R_BAD_BASE64_DECODE}, + #else + {"BAD_BASE64_DECODE", 9, 100}, + #endif + #ifdef PEM_R_BAD_DECRYPT + {"BAD_DECRYPT", ERR_LIB_PEM, PEM_R_BAD_DECRYPT}, + #else + {"BAD_DECRYPT", 9, 101}, + #endif + #ifdef PEM_R_BAD_END_LINE + {"BAD_END_LINE", ERR_LIB_PEM, PEM_R_BAD_END_LINE}, + #else + {"BAD_END_LINE", 9, 102}, + #endif + #ifdef PEM_R_BAD_IV_CHARS + {"BAD_IV_CHARS", ERR_LIB_PEM, PEM_R_BAD_IV_CHARS}, + #else + {"BAD_IV_CHARS", 9, 103}, + #endif + #ifdef PEM_R_BAD_MAGIC_NUMBER + {"BAD_MAGIC_NUMBER", ERR_LIB_PEM, PEM_R_BAD_MAGIC_NUMBER}, + #else + {"BAD_MAGIC_NUMBER", 9, 116}, + #endif + #ifdef PEM_R_BAD_PASSWORD_READ + {"BAD_PASSWORD_READ", ERR_LIB_PEM, PEM_R_BAD_PASSWORD_READ}, + #else + {"BAD_PASSWORD_READ", 9, 104}, + #endif + #ifdef PEM_R_BAD_VERSION_NUMBER + {"BAD_VERSION_NUMBER", ERR_LIB_PEM, PEM_R_BAD_VERSION_NUMBER}, + #else + {"BAD_VERSION_NUMBER", 9, 117}, + #endif + #ifdef PEM_R_BIO_WRITE_FAILURE + {"BIO_WRITE_FAILURE", ERR_LIB_PEM, PEM_R_BIO_WRITE_FAILURE}, + #else + {"BIO_WRITE_FAILURE", 9, 118}, + #endif + #ifdef PEM_R_CIPHER_IS_NULL + {"CIPHER_IS_NULL", ERR_LIB_PEM, PEM_R_CIPHER_IS_NULL}, + #else + {"CIPHER_IS_NULL", 9, 127}, + #endif + #ifdef PEM_R_ERROR_CONVERTING_PRIVATE_KEY + {"ERROR_CONVERTING_PRIVATE_KEY", ERR_LIB_PEM, PEM_R_ERROR_CONVERTING_PRIVATE_KEY}, + #else + {"ERROR_CONVERTING_PRIVATE_KEY", 9, 115}, + #endif + #ifdef PEM_R_EXPECTING_DSS_KEY_BLOB + {"EXPECTING_DSS_KEY_BLOB", ERR_LIB_PEM, PEM_R_EXPECTING_DSS_KEY_BLOB}, + #else + {"EXPECTING_DSS_KEY_BLOB", 9, 131}, + #endif + #ifdef PEM_R_EXPECTING_PRIVATE_KEY_BLOB + {"EXPECTING_PRIVATE_KEY_BLOB", ERR_LIB_PEM, PEM_R_EXPECTING_PRIVATE_KEY_BLOB}, + #else + {"EXPECTING_PRIVATE_KEY_BLOB", 9, 119}, + #endif + #ifdef PEM_R_EXPECTING_PUBLIC_KEY_BLOB + {"EXPECTING_PUBLIC_KEY_BLOB", ERR_LIB_PEM, PEM_R_EXPECTING_PUBLIC_KEY_BLOB}, + #else + {"EXPECTING_PUBLIC_KEY_BLOB", 9, 120}, + #endif + #ifdef PEM_R_EXPECTING_RSA_KEY_BLOB + {"EXPECTING_RSA_KEY_BLOB", ERR_LIB_PEM, PEM_R_EXPECTING_RSA_KEY_BLOB}, + #else + {"EXPECTING_RSA_KEY_BLOB", 9, 132}, + #endif + #ifdef PEM_R_HEADER_TOO_LONG + {"HEADER_TOO_LONG", ERR_LIB_PEM, PEM_R_HEADER_TOO_LONG}, + #else + {"HEADER_TOO_LONG", 9, 128}, + #endif + #ifdef PEM_R_INCONSISTENT_HEADER + {"INCONSISTENT_HEADER", ERR_LIB_PEM, PEM_R_INCONSISTENT_HEADER}, + #else + {"INCONSISTENT_HEADER", 9, 121}, + #endif + #ifdef PEM_R_KEYBLOB_HEADER_PARSE_ERROR + {"KEYBLOB_HEADER_PARSE_ERROR", ERR_LIB_PEM, PEM_R_KEYBLOB_HEADER_PARSE_ERROR}, + #else + {"KEYBLOB_HEADER_PARSE_ERROR", 9, 122}, + #endif + #ifdef PEM_R_KEYBLOB_TOO_SHORT + {"KEYBLOB_TOO_SHORT", ERR_LIB_PEM, PEM_R_KEYBLOB_TOO_SHORT}, + #else + {"KEYBLOB_TOO_SHORT", 9, 123}, + #endif + #ifdef PEM_R_MISSING_DEK_IV + {"MISSING_DEK_IV", ERR_LIB_PEM, PEM_R_MISSING_DEK_IV}, + #else + {"MISSING_DEK_IV", 9, 129}, + #endif + #ifdef PEM_R_NOT_DEK_INFO + {"NOT_DEK_INFO", ERR_LIB_PEM, PEM_R_NOT_DEK_INFO}, + #else + {"NOT_DEK_INFO", 9, 105}, + #endif + #ifdef PEM_R_NOT_ENCRYPTED + {"NOT_ENCRYPTED", ERR_LIB_PEM, PEM_R_NOT_ENCRYPTED}, + #else + {"NOT_ENCRYPTED", 9, 106}, + #endif + #ifdef PEM_R_NOT_PROC_TYPE + {"NOT_PROC_TYPE", ERR_LIB_PEM, PEM_R_NOT_PROC_TYPE}, + #else + {"NOT_PROC_TYPE", 9, 107}, + #endif + #ifdef PEM_R_NO_START_LINE + {"NO_START_LINE", ERR_LIB_PEM, PEM_R_NO_START_LINE}, + #else + {"NO_START_LINE", 9, 108}, + #endif + #ifdef PEM_R_PROBLEMS_GETTING_PASSWORD + {"PROBLEMS_GETTING_PASSWORD", ERR_LIB_PEM, PEM_R_PROBLEMS_GETTING_PASSWORD}, + #else + {"PROBLEMS_GETTING_PASSWORD", 9, 109}, + #endif + #ifdef PEM_R_PVK_DATA_TOO_SHORT + {"PVK_DATA_TOO_SHORT", ERR_LIB_PEM, PEM_R_PVK_DATA_TOO_SHORT}, + #else + {"PVK_DATA_TOO_SHORT", 9, 124}, + #endif + #ifdef PEM_R_PVK_TOO_SHORT + {"PVK_TOO_SHORT", ERR_LIB_PEM, PEM_R_PVK_TOO_SHORT}, + #else + {"PVK_TOO_SHORT", 9, 125}, + #endif + #ifdef PEM_R_READ_KEY + {"READ_KEY", ERR_LIB_PEM, PEM_R_READ_KEY}, + #else + {"READ_KEY", 9, 111}, + #endif + #ifdef PEM_R_SHORT_HEADER + {"SHORT_HEADER", ERR_LIB_PEM, PEM_R_SHORT_HEADER}, + #else + {"SHORT_HEADER", 9, 112}, + #endif + #ifdef PEM_R_UNEXPECTED_DEK_IV + {"UNEXPECTED_DEK_IV", ERR_LIB_PEM, PEM_R_UNEXPECTED_DEK_IV}, + #else + {"UNEXPECTED_DEK_IV", 9, 130}, + #endif + #ifdef PEM_R_UNSUPPORTED_CIPHER + {"UNSUPPORTED_CIPHER", ERR_LIB_PEM, PEM_R_UNSUPPORTED_CIPHER}, + #else + {"UNSUPPORTED_CIPHER", 9, 113}, + #endif + #ifdef PEM_R_UNSUPPORTED_ENCRYPTION + {"UNSUPPORTED_ENCRYPTION", ERR_LIB_PEM, PEM_R_UNSUPPORTED_ENCRYPTION}, + #else + {"UNSUPPORTED_ENCRYPTION", 9, 114}, + #endif + #ifdef PEM_R_UNSUPPORTED_KEY_COMPONENTS + {"UNSUPPORTED_KEY_COMPONENTS", ERR_LIB_PEM, PEM_R_UNSUPPORTED_KEY_COMPONENTS}, + #else + {"UNSUPPORTED_KEY_COMPONENTS", 9, 126}, + #endif + #ifdef PEM_R_UNSUPPORTED_PUBLIC_KEY_TYPE + {"UNSUPPORTED_PUBLIC_KEY_TYPE", ERR_LIB_PEM, PEM_R_UNSUPPORTED_PUBLIC_KEY_TYPE}, + #else + {"UNSUPPORTED_PUBLIC_KEY_TYPE", 9, 110}, + #endif + #ifdef PKCS12_R_CANT_PACK_STRUCTURE + {"CANT_PACK_STRUCTURE", ERR_LIB_PKCS12, PKCS12_R_CANT_PACK_STRUCTURE}, + #else + {"CANT_PACK_STRUCTURE", 35, 100}, + #endif + #ifdef PKCS12_R_CONTENT_TYPE_NOT_DATA + {"CONTENT_TYPE_NOT_DATA", ERR_LIB_PKCS12, PKCS12_R_CONTENT_TYPE_NOT_DATA}, + #else + {"CONTENT_TYPE_NOT_DATA", 35, 121}, + #endif + #ifdef PKCS12_R_DECODE_ERROR + {"DECODE_ERROR", ERR_LIB_PKCS12, PKCS12_R_DECODE_ERROR}, + #else + {"DECODE_ERROR", 35, 101}, + #endif + #ifdef PKCS12_R_ENCODE_ERROR + {"ENCODE_ERROR", ERR_LIB_PKCS12, PKCS12_R_ENCODE_ERROR}, + #else + {"ENCODE_ERROR", 35, 102}, + #endif + #ifdef PKCS12_R_ENCRYPT_ERROR + {"ENCRYPT_ERROR", ERR_LIB_PKCS12, PKCS12_R_ENCRYPT_ERROR}, + #else + {"ENCRYPT_ERROR", 35, 103}, + #endif + #ifdef PKCS12_R_ERROR_SETTING_ENCRYPTED_DATA_TYPE + {"ERROR_SETTING_ENCRYPTED_DATA_TYPE", ERR_LIB_PKCS12, PKCS12_R_ERROR_SETTING_ENCRYPTED_DATA_TYPE}, + #else + {"ERROR_SETTING_ENCRYPTED_DATA_TYPE", 35, 120}, + #endif + #ifdef PKCS12_R_INVALID_NULL_ARGUMENT + {"INVALID_NULL_ARGUMENT", ERR_LIB_PKCS12, PKCS12_R_INVALID_NULL_ARGUMENT}, + #else + {"INVALID_NULL_ARGUMENT", 35, 104}, + #endif + #ifdef PKCS12_R_INVALID_NULL_PKCS12_POINTER + {"INVALID_NULL_PKCS12_POINTER", ERR_LIB_PKCS12, PKCS12_R_INVALID_NULL_PKCS12_POINTER}, + #else + {"INVALID_NULL_PKCS12_POINTER", 35, 105}, + #endif + #ifdef PKCS12_R_INVALID_TYPE + {"INVALID_TYPE", ERR_LIB_PKCS12, PKCS12_R_INVALID_TYPE}, + #else + {"INVALID_TYPE", 35, 112}, + #endif + #ifdef PKCS12_R_IV_GEN_ERROR + {"IV_GEN_ERROR", ERR_LIB_PKCS12, PKCS12_R_IV_GEN_ERROR}, + #else + {"IV_GEN_ERROR", 35, 106}, + #endif + #ifdef PKCS12_R_KEY_GEN_ERROR + {"KEY_GEN_ERROR", ERR_LIB_PKCS12, PKCS12_R_KEY_GEN_ERROR}, + #else + {"KEY_GEN_ERROR", 35, 107}, + #endif + #ifdef PKCS12_R_MAC_ABSENT + {"MAC_ABSENT", ERR_LIB_PKCS12, PKCS12_R_MAC_ABSENT}, + #else + {"MAC_ABSENT", 35, 108}, + #endif + #ifdef PKCS12_R_MAC_GENERATION_ERROR + {"MAC_GENERATION_ERROR", ERR_LIB_PKCS12, PKCS12_R_MAC_GENERATION_ERROR}, + #else + {"MAC_GENERATION_ERROR", 35, 109}, + #endif + #ifdef PKCS12_R_MAC_SETUP_ERROR + {"MAC_SETUP_ERROR", ERR_LIB_PKCS12, PKCS12_R_MAC_SETUP_ERROR}, + #else + {"MAC_SETUP_ERROR", 35, 110}, + #endif + #ifdef PKCS12_R_MAC_STRING_SET_ERROR + {"MAC_STRING_SET_ERROR", ERR_LIB_PKCS12, PKCS12_R_MAC_STRING_SET_ERROR}, + #else + {"MAC_STRING_SET_ERROR", 35, 111}, + #endif + #ifdef PKCS12_R_MAC_VERIFY_FAILURE + {"MAC_VERIFY_FAILURE", ERR_LIB_PKCS12, PKCS12_R_MAC_VERIFY_FAILURE}, + #else + {"MAC_VERIFY_FAILURE", 35, 113}, + #endif + #ifdef PKCS12_R_PARSE_ERROR + {"PARSE_ERROR", ERR_LIB_PKCS12, PKCS12_R_PARSE_ERROR}, + #else + {"PARSE_ERROR", 35, 114}, + #endif + #ifdef PKCS12_R_PKCS12_CIPHERFINAL_ERROR + {"PKCS12_CIPHERFINAL_ERROR", ERR_LIB_PKCS12, PKCS12_R_PKCS12_CIPHERFINAL_ERROR}, + #else + {"PKCS12_CIPHERFINAL_ERROR", 35, 116}, + #endif + #ifdef PKCS12_R_UNKNOWN_DIGEST_ALGORITHM + {"UNKNOWN_DIGEST_ALGORITHM", ERR_LIB_PKCS12, PKCS12_R_UNKNOWN_DIGEST_ALGORITHM}, + #else + {"UNKNOWN_DIGEST_ALGORITHM", 35, 118}, + #endif + #ifdef PKCS12_R_UNSUPPORTED_PKCS12_MODE + {"UNSUPPORTED_PKCS12_MODE", ERR_LIB_PKCS12, PKCS12_R_UNSUPPORTED_PKCS12_MODE}, + #else + {"UNSUPPORTED_PKCS12_MODE", 35, 119}, + #endif + #ifdef PKCS7_R_CERTIFICATE_VERIFY_ERROR + {"CERTIFICATE_VERIFY_ERROR", ERR_LIB_PKCS7, PKCS7_R_CERTIFICATE_VERIFY_ERROR}, + #else + {"CERTIFICATE_VERIFY_ERROR", 33, 117}, + #endif + #ifdef PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER + {"CIPHER_HAS_NO_OBJECT_IDENTIFIER", ERR_LIB_PKCS7, PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER}, + #else + {"CIPHER_HAS_NO_OBJECT_IDENTIFIER", 33, 144}, + #endif + #ifdef PKCS7_R_CIPHER_NOT_INITIALIZED + {"CIPHER_NOT_INITIALIZED", ERR_LIB_PKCS7, PKCS7_R_CIPHER_NOT_INITIALIZED}, + #else + {"CIPHER_NOT_INITIALIZED", 33, 116}, + #endif + #ifdef PKCS7_R_CONTENT_AND_DATA_PRESENT + {"CONTENT_AND_DATA_PRESENT", ERR_LIB_PKCS7, PKCS7_R_CONTENT_AND_DATA_PRESENT}, + #else + {"CONTENT_AND_DATA_PRESENT", 33, 118}, + #endif + #ifdef PKCS7_R_CTRL_ERROR + {"CTRL_ERROR", ERR_LIB_PKCS7, PKCS7_R_CTRL_ERROR}, + #else + {"CTRL_ERROR", 33, 152}, + #endif + #ifdef PKCS7_R_DECRYPT_ERROR + {"DECRYPT_ERROR", ERR_LIB_PKCS7, PKCS7_R_DECRYPT_ERROR}, + #else + {"DECRYPT_ERROR", 33, 119}, + #endif + #ifdef PKCS7_R_DIGEST_FAILURE + {"DIGEST_FAILURE", ERR_LIB_PKCS7, PKCS7_R_DIGEST_FAILURE}, + #else + {"DIGEST_FAILURE", 33, 101}, + #endif + #ifdef PKCS7_R_ENCRYPTION_CTRL_FAILURE + {"ENCRYPTION_CTRL_FAILURE", ERR_LIB_PKCS7, PKCS7_R_ENCRYPTION_CTRL_FAILURE}, + #else + {"ENCRYPTION_CTRL_FAILURE", 33, 149}, + #endif + #ifdef PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE + {"ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE", ERR_LIB_PKCS7, PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE}, + #else + {"ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE", 33, 150}, + #endif + #ifdef PKCS7_R_ERROR_ADDING_RECIPIENT + {"ERROR_ADDING_RECIPIENT", ERR_LIB_PKCS7, PKCS7_R_ERROR_ADDING_RECIPIENT}, + #else + {"ERROR_ADDING_RECIPIENT", 33, 120}, + #endif + #ifdef PKCS7_R_ERROR_SETTING_CIPHER + {"ERROR_SETTING_CIPHER", ERR_LIB_PKCS7, PKCS7_R_ERROR_SETTING_CIPHER}, + #else + {"ERROR_SETTING_CIPHER", 33, 121}, + #endif + #ifdef PKCS7_R_INVALID_NULL_POINTER + {"INVALID_NULL_POINTER", ERR_LIB_PKCS7, PKCS7_R_INVALID_NULL_POINTER}, + #else + {"INVALID_NULL_POINTER", 33, 143}, + #endif + #ifdef PKCS7_R_INVALID_SIGNED_DATA_TYPE + {"INVALID_SIGNED_DATA_TYPE", ERR_LIB_PKCS7, PKCS7_R_INVALID_SIGNED_DATA_TYPE}, + #else + {"INVALID_SIGNED_DATA_TYPE", 33, 155}, + #endif + #ifdef PKCS7_R_NO_CONTENT + {"NO_CONTENT", ERR_LIB_PKCS7, PKCS7_R_NO_CONTENT}, + #else + {"NO_CONTENT", 33, 122}, + #endif + #ifdef PKCS7_R_NO_DEFAULT_DIGEST + {"NO_DEFAULT_DIGEST", ERR_LIB_PKCS7, PKCS7_R_NO_DEFAULT_DIGEST}, + #else + {"NO_DEFAULT_DIGEST", 33, 151}, + #endif + #ifdef PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND + {"NO_MATCHING_DIGEST_TYPE_FOUND", ERR_LIB_PKCS7, PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND}, + #else + {"NO_MATCHING_DIGEST_TYPE_FOUND", 33, 154}, + #endif + #ifdef PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE + {"NO_RECIPIENT_MATCHES_CERTIFICATE", ERR_LIB_PKCS7, PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE}, + #else + {"NO_RECIPIENT_MATCHES_CERTIFICATE", 33, 115}, + #endif + #ifdef PKCS7_R_NO_SIGNATURES_ON_DATA + {"NO_SIGNATURES_ON_DATA", ERR_LIB_PKCS7, PKCS7_R_NO_SIGNATURES_ON_DATA}, + #else + {"NO_SIGNATURES_ON_DATA", 33, 123}, + #endif + #ifdef PKCS7_R_NO_SIGNERS + {"NO_SIGNERS", ERR_LIB_PKCS7, PKCS7_R_NO_SIGNERS}, + #else + {"NO_SIGNERS", 33, 142}, + #endif + #ifdef PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE + {"OPERATION_NOT_SUPPORTED_ON_THIS_TYPE", ERR_LIB_PKCS7, PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE}, + #else + {"OPERATION_NOT_SUPPORTED_ON_THIS_TYPE", 33, 104}, + #endif + #ifdef PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR + {"PKCS7_ADD_SIGNATURE_ERROR", ERR_LIB_PKCS7, PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR}, + #else + {"PKCS7_ADD_SIGNATURE_ERROR", 33, 124}, + #endif + #ifdef PKCS7_R_PKCS7_ADD_SIGNER_ERROR + {"PKCS7_ADD_SIGNER_ERROR", ERR_LIB_PKCS7, PKCS7_R_PKCS7_ADD_SIGNER_ERROR}, + #else + {"PKCS7_ADD_SIGNER_ERROR", 33, 153}, + #endif + #ifdef PKCS7_R_PKCS7_DATASIGN + {"PKCS7_DATASIGN", ERR_LIB_PKCS7, PKCS7_R_PKCS7_DATASIGN}, + #else + {"PKCS7_DATASIGN", 33, 145}, + #endif + #ifdef PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE + {"PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE", ERR_LIB_PKCS7, PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE}, + #else + {"PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE", 33, 127}, + #endif + #ifdef PKCS7_R_SIGNATURE_FAILURE + {"SIGNATURE_FAILURE", ERR_LIB_PKCS7, PKCS7_R_SIGNATURE_FAILURE}, + #else + {"SIGNATURE_FAILURE", 33, 105}, + #endif + #ifdef PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND + {"SIGNER_CERTIFICATE_NOT_FOUND", ERR_LIB_PKCS7, PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND}, + #else + {"SIGNER_CERTIFICATE_NOT_FOUND", 33, 128}, + #endif + #ifdef PKCS7_R_SIGNING_CTRL_FAILURE + {"SIGNING_CTRL_FAILURE", ERR_LIB_PKCS7, PKCS7_R_SIGNING_CTRL_FAILURE}, + #else + {"SIGNING_CTRL_FAILURE", 33, 147}, + #endif + #ifdef PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE + {"SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE", ERR_LIB_PKCS7, PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE}, + #else + {"SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE", 33, 148}, + #endif + #ifdef PKCS7_R_SMIME_TEXT_ERROR + {"SMIME_TEXT_ERROR", ERR_LIB_PKCS7, PKCS7_R_SMIME_TEXT_ERROR}, + #else + {"SMIME_TEXT_ERROR", 33, 129}, + #endif + #ifdef PKCS7_R_UNABLE_TO_FIND_CERTIFICATE + {"UNABLE_TO_FIND_CERTIFICATE", ERR_LIB_PKCS7, PKCS7_R_UNABLE_TO_FIND_CERTIFICATE}, + #else + {"UNABLE_TO_FIND_CERTIFICATE", 33, 106}, + #endif + #ifdef PKCS7_R_UNABLE_TO_FIND_MEM_BIO + {"UNABLE_TO_FIND_MEM_BIO", ERR_LIB_PKCS7, PKCS7_R_UNABLE_TO_FIND_MEM_BIO}, + #else + {"UNABLE_TO_FIND_MEM_BIO", 33, 107}, + #endif + #ifdef PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST + {"UNABLE_TO_FIND_MESSAGE_DIGEST", ERR_LIB_PKCS7, PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST}, + #else + {"UNABLE_TO_FIND_MESSAGE_DIGEST", 33, 108}, + #endif + #ifdef PKCS7_R_UNKNOWN_DIGEST_TYPE + {"UNKNOWN_DIGEST_TYPE", ERR_LIB_PKCS7, PKCS7_R_UNKNOWN_DIGEST_TYPE}, + #else + {"UNKNOWN_DIGEST_TYPE", 33, 109}, + #endif + #ifdef PKCS7_R_UNKNOWN_OPERATION + {"UNKNOWN_OPERATION", ERR_LIB_PKCS7, PKCS7_R_UNKNOWN_OPERATION}, + #else + {"UNKNOWN_OPERATION", 33, 110}, + #endif + #ifdef PKCS7_R_UNSUPPORTED_CIPHER_TYPE + {"UNSUPPORTED_CIPHER_TYPE", ERR_LIB_PKCS7, PKCS7_R_UNSUPPORTED_CIPHER_TYPE}, + #else + {"UNSUPPORTED_CIPHER_TYPE", 33, 111}, + #endif + #ifdef PKCS7_R_UNSUPPORTED_CONTENT_TYPE + {"UNSUPPORTED_CONTENT_TYPE", ERR_LIB_PKCS7, PKCS7_R_UNSUPPORTED_CONTENT_TYPE}, + #else + {"UNSUPPORTED_CONTENT_TYPE", 33, 112}, + #endif + #ifdef PKCS7_R_WRONG_CONTENT_TYPE + {"WRONG_CONTENT_TYPE", ERR_LIB_PKCS7, PKCS7_R_WRONG_CONTENT_TYPE}, + #else + {"WRONG_CONTENT_TYPE", 33, 113}, + #endif + #ifdef PKCS7_R_WRONG_PKCS7_TYPE + {"WRONG_PKCS7_TYPE", ERR_LIB_PKCS7, PKCS7_R_WRONG_PKCS7_TYPE}, + #else + {"WRONG_PKCS7_TYPE", 33, 114}, + #endif + #ifdef PROP_R_NAME_TOO_LONG + {"NAME_TOO_LONG", ERR_LIB_PROP, PROP_R_NAME_TOO_LONG}, + #else + {"NAME_TOO_LONG", 55, 100}, + #endif + #ifdef PROP_R_NOT_AN_ASCII_CHARACTER + {"NOT_AN_ASCII_CHARACTER", ERR_LIB_PROP, PROP_R_NOT_AN_ASCII_CHARACTER}, + #else + {"NOT_AN_ASCII_CHARACTER", 55, 101}, + #endif + #ifdef PROP_R_NOT_AN_HEXADECIMAL_DIGIT + {"NOT_AN_HEXADECIMAL_DIGIT", ERR_LIB_PROP, PROP_R_NOT_AN_HEXADECIMAL_DIGIT}, + #else + {"NOT_AN_HEXADECIMAL_DIGIT", 55, 102}, + #endif + #ifdef PROP_R_NOT_AN_IDENTIFIER + {"NOT_AN_IDENTIFIER", ERR_LIB_PROP, PROP_R_NOT_AN_IDENTIFIER}, + #else + {"NOT_AN_IDENTIFIER", 55, 103}, + #endif + #ifdef PROP_R_NOT_AN_OCTAL_DIGIT + {"NOT_AN_OCTAL_DIGIT", ERR_LIB_PROP, PROP_R_NOT_AN_OCTAL_DIGIT}, + #else + {"NOT_AN_OCTAL_DIGIT", 55, 104}, + #endif + #ifdef PROP_R_NOT_A_DECIMAL_DIGIT + {"NOT_A_DECIMAL_DIGIT", ERR_LIB_PROP, PROP_R_NOT_A_DECIMAL_DIGIT}, + #else + {"NOT_A_DECIMAL_DIGIT", 55, 105}, + #endif + #ifdef PROP_R_NO_MATCHING_STRING_DELIMITER + {"NO_MATCHING_STRING_DELIMITER", ERR_LIB_PROP, PROP_R_NO_MATCHING_STRING_DELIMITER}, + #else + {"NO_MATCHING_STRING_DELIMITER", 55, 106}, + #endif + #ifdef PROP_R_NO_VALUE + {"NO_VALUE", ERR_LIB_PROP, PROP_R_NO_VALUE}, + #else + {"NO_VALUE", 55, 107}, + #endif + #ifdef PROP_R_PARSE_FAILED + {"PARSE_FAILED", ERR_LIB_PROP, PROP_R_PARSE_FAILED}, + #else + {"PARSE_FAILED", 55, 108}, + #endif + #ifdef PROP_R_STRING_TOO_LONG + {"STRING_TOO_LONG", ERR_LIB_PROP, PROP_R_STRING_TOO_LONG}, + #else + {"STRING_TOO_LONG", 55, 109}, + #endif + #ifdef PROP_R_TRAILING_CHARACTERS + {"TRAILING_CHARACTERS", ERR_LIB_PROP, PROP_R_TRAILING_CHARACTERS}, + #else + {"TRAILING_CHARACTERS", 55, 110}, + #endif + #ifdef PROV_R_ADDITIONAL_INPUT_TOO_LONG + {"ADDITIONAL_INPUT_TOO_LONG", ERR_LIB_PROV, PROV_R_ADDITIONAL_INPUT_TOO_LONG}, + #else + {"ADDITIONAL_INPUT_TOO_LONG", 57, 184}, + #endif + #ifdef PROV_R_ALGORITHM_MISMATCH + {"ALGORITHM_MISMATCH", ERR_LIB_PROV, PROV_R_ALGORITHM_MISMATCH}, + #else + {"ALGORITHM_MISMATCH", 57, 173}, + #endif + #ifdef PROV_R_ALREADY_INSTANTIATED + {"ALREADY_INSTANTIATED", ERR_LIB_PROV, PROV_R_ALREADY_INSTANTIATED}, + #else + {"ALREADY_INSTANTIATED", 57, 185}, + #endif + #ifdef PROV_R_BAD_DECRYPT + {"BAD_DECRYPT", ERR_LIB_PROV, PROV_R_BAD_DECRYPT}, + #else + {"BAD_DECRYPT", 57, 100}, + #endif + #ifdef PROV_R_BAD_ENCODING + {"BAD_ENCODING", ERR_LIB_PROV, PROV_R_BAD_ENCODING}, + #else + {"BAD_ENCODING", 57, 141}, + #endif + #ifdef PROV_R_BAD_LENGTH + {"BAD_LENGTH", ERR_LIB_PROV, PROV_R_BAD_LENGTH}, + #else + {"BAD_LENGTH", 57, 142}, + #endif + #ifdef PROV_R_BAD_TLS_CLIENT_VERSION + {"BAD_TLS_CLIENT_VERSION", ERR_LIB_PROV, PROV_R_BAD_TLS_CLIENT_VERSION}, + #else + {"BAD_TLS_CLIENT_VERSION", 57, 161}, + #endif + #ifdef PROV_R_BN_ERROR + {"BN_ERROR", ERR_LIB_PROV, PROV_R_BN_ERROR}, + #else + {"BN_ERROR", 57, 160}, + #endif + #ifdef PROV_R_CIPHER_OPERATION_FAILED + {"CIPHER_OPERATION_FAILED", ERR_LIB_PROV, PROV_R_CIPHER_OPERATION_FAILED}, + #else + {"CIPHER_OPERATION_FAILED", 57, 102}, + #endif + #ifdef PROV_R_DERIVATION_FUNCTION_INIT_FAILED + {"DERIVATION_FUNCTION_INIT_FAILED", ERR_LIB_PROV, PROV_R_DERIVATION_FUNCTION_INIT_FAILED}, + #else + {"DERIVATION_FUNCTION_INIT_FAILED", 57, 205}, + #endif + #ifdef PROV_R_DIGEST_NOT_ALLOWED + {"DIGEST_NOT_ALLOWED", ERR_LIB_PROV, PROV_R_DIGEST_NOT_ALLOWED}, + #else + {"DIGEST_NOT_ALLOWED", 57, 174}, + #endif + #ifdef PROV_R_EMS_NOT_ENABLED + {"EMS_NOT_ENABLED", ERR_LIB_PROV, PROV_R_EMS_NOT_ENABLED}, + #else + {"EMS_NOT_ENABLED", 57, 233}, + #endif + #ifdef PROV_R_ENTROPY_SOURCE_STRENGTH_TOO_WEAK + {"ENTROPY_SOURCE_STRENGTH_TOO_WEAK", ERR_LIB_PROV, PROV_R_ENTROPY_SOURCE_STRENGTH_TOO_WEAK}, + #else + {"ENTROPY_SOURCE_STRENGTH_TOO_WEAK", 57, 186}, + #endif + #ifdef PROV_R_ERROR_INSTANTIATING_DRBG + {"ERROR_INSTANTIATING_DRBG", ERR_LIB_PROV, PROV_R_ERROR_INSTANTIATING_DRBG}, + #else + {"ERROR_INSTANTIATING_DRBG", 57, 188}, + #endif + #ifdef PROV_R_ERROR_RETRIEVING_ENTROPY + {"ERROR_RETRIEVING_ENTROPY", ERR_LIB_PROV, PROV_R_ERROR_RETRIEVING_ENTROPY}, + #else + {"ERROR_RETRIEVING_ENTROPY", 57, 189}, + #endif + #ifdef PROV_R_ERROR_RETRIEVING_NONCE + {"ERROR_RETRIEVING_NONCE", ERR_LIB_PROV, PROV_R_ERROR_RETRIEVING_NONCE}, + #else + {"ERROR_RETRIEVING_NONCE", 57, 190}, + #endif + #ifdef PROV_R_FAILED_DURING_DERIVATION + {"FAILED_DURING_DERIVATION", ERR_LIB_PROV, PROV_R_FAILED_DURING_DERIVATION}, + #else + {"FAILED_DURING_DERIVATION", 57, 164}, + #endif + #ifdef PROV_R_FAILED_TO_CREATE_LOCK + {"FAILED_TO_CREATE_LOCK", ERR_LIB_PROV, PROV_R_FAILED_TO_CREATE_LOCK}, + #else + {"FAILED_TO_CREATE_LOCK", 57, 180}, + #endif + #ifdef PROV_R_FAILED_TO_DECRYPT + {"FAILED_TO_DECRYPT", ERR_LIB_PROV, PROV_R_FAILED_TO_DECRYPT}, + #else + {"FAILED_TO_DECRYPT", 57, 162}, + #endif + #ifdef PROV_R_FAILED_TO_GENERATE_KEY + {"FAILED_TO_GENERATE_KEY", ERR_LIB_PROV, PROV_R_FAILED_TO_GENERATE_KEY}, + #else + {"FAILED_TO_GENERATE_KEY", 57, 121}, + #endif + #ifdef PROV_R_FAILED_TO_GET_PARAMETER + {"FAILED_TO_GET_PARAMETER", ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER}, + #else + {"FAILED_TO_GET_PARAMETER", 57, 103}, + #endif + #ifdef PROV_R_FAILED_TO_SET_PARAMETER + {"FAILED_TO_SET_PARAMETER", ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER}, + #else + {"FAILED_TO_SET_PARAMETER", 57, 104}, + #endif + #ifdef PROV_R_FAILED_TO_SIGN + {"FAILED_TO_SIGN", ERR_LIB_PROV, PROV_R_FAILED_TO_SIGN}, + #else + {"FAILED_TO_SIGN", 57, 175}, + #endif + #ifdef PROV_R_FIPS_MODULE_CONDITIONAL_ERROR + {"FIPS_MODULE_CONDITIONAL_ERROR", ERR_LIB_PROV, PROV_R_FIPS_MODULE_CONDITIONAL_ERROR}, + #else + {"FIPS_MODULE_CONDITIONAL_ERROR", 57, 227}, + #endif + #ifdef PROV_R_FIPS_MODULE_ENTERING_ERROR_STATE + {"FIPS_MODULE_ENTERING_ERROR_STATE", ERR_LIB_PROV, PROV_R_FIPS_MODULE_ENTERING_ERROR_STATE}, + #else + {"FIPS_MODULE_ENTERING_ERROR_STATE", 57, 224}, + #endif + #ifdef PROV_R_FIPS_MODULE_IN_ERROR_STATE + {"FIPS_MODULE_IN_ERROR_STATE", ERR_LIB_PROV, PROV_R_FIPS_MODULE_IN_ERROR_STATE}, + #else + {"FIPS_MODULE_IN_ERROR_STATE", 57, 225}, + #endif + #ifdef PROV_R_GENERATE_ERROR + {"GENERATE_ERROR", ERR_LIB_PROV, PROV_R_GENERATE_ERROR}, + #else + {"GENERATE_ERROR", 57, 191}, + #endif + #ifdef PROV_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE + {"ILLEGAL_OR_UNSUPPORTED_PADDING_MODE", ERR_LIB_PROV, PROV_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE}, + #else + {"ILLEGAL_OR_UNSUPPORTED_PADDING_MODE", 57, 165}, + #endif + #ifdef PROV_R_INDICATOR_INTEGRITY_FAILURE + {"INDICATOR_INTEGRITY_FAILURE", ERR_LIB_PROV, PROV_R_INDICATOR_INTEGRITY_FAILURE}, + #else + {"INDICATOR_INTEGRITY_FAILURE", 57, 210}, + #endif + #ifdef PROV_R_INSUFFICIENT_DRBG_STRENGTH + {"INSUFFICIENT_DRBG_STRENGTH", ERR_LIB_PROV, PROV_R_INSUFFICIENT_DRBG_STRENGTH}, + #else + {"INSUFFICIENT_DRBG_STRENGTH", 57, 181}, + #endif + #ifdef PROV_R_INVALID_AAD + {"INVALID_AAD", ERR_LIB_PROV, PROV_R_INVALID_AAD}, + #else + {"INVALID_AAD", 57, 108}, + #endif + #ifdef PROV_R_INVALID_CONFIG_DATA + {"INVALID_CONFIG_DATA", ERR_LIB_PROV, PROV_R_INVALID_CONFIG_DATA}, + #else + {"INVALID_CONFIG_DATA", 57, 211}, + #endif + #ifdef PROV_R_INVALID_CONSTANT_LENGTH + {"INVALID_CONSTANT_LENGTH", ERR_LIB_PROV, PROV_R_INVALID_CONSTANT_LENGTH}, + #else + {"INVALID_CONSTANT_LENGTH", 57, 157}, + #endif + #ifdef PROV_R_INVALID_CURVE + {"INVALID_CURVE", ERR_LIB_PROV, PROV_R_INVALID_CURVE}, + #else + {"INVALID_CURVE", 57, 176}, + #endif + #ifdef PROV_R_INVALID_CUSTOM_LENGTH + {"INVALID_CUSTOM_LENGTH", ERR_LIB_PROV, PROV_R_INVALID_CUSTOM_LENGTH}, + #else + {"INVALID_CUSTOM_LENGTH", 57, 111}, + #endif + #ifdef PROV_R_INVALID_DATA + {"INVALID_DATA", ERR_LIB_PROV, PROV_R_INVALID_DATA}, + #else + {"INVALID_DATA", 57, 115}, + #endif + #ifdef PROV_R_INVALID_DIGEST + {"INVALID_DIGEST", ERR_LIB_PROV, PROV_R_INVALID_DIGEST}, + #else + {"INVALID_DIGEST", 57, 122}, + #endif + #ifdef PROV_R_INVALID_DIGEST_LENGTH + {"INVALID_DIGEST_LENGTH", ERR_LIB_PROV, PROV_R_INVALID_DIGEST_LENGTH}, + #else + {"INVALID_DIGEST_LENGTH", 57, 166}, + #endif + #ifdef PROV_R_INVALID_DIGEST_SIZE + {"INVALID_DIGEST_SIZE", ERR_LIB_PROV, PROV_R_INVALID_DIGEST_SIZE}, + #else + {"INVALID_DIGEST_SIZE", 57, 218}, + #endif + #ifdef PROV_R_INVALID_INPUT_LENGTH + {"INVALID_INPUT_LENGTH", ERR_LIB_PROV, PROV_R_INVALID_INPUT_LENGTH}, + #else + {"INVALID_INPUT_LENGTH", 57, 230}, + #endif + #ifdef PROV_R_INVALID_ITERATION_COUNT + {"INVALID_ITERATION_COUNT", ERR_LIB_PROV, PROV_R_INVALID_ITERATION_COUNT}, + #else + {"INVALID_ITERATION_COUNT", 57, 123}, + #endif + #ifdef PROV_R_INVALID_IV_LENGTH + {"INVALID_IV_LENGTH", ERR_LIB_PROV, PROV_R_INVALID_IV_LENGTH}, + #else + {"INVALID_IV_LENGTH", 57, 109}, + #endif + #ifdef PROV_R_INVALID_KEY + {"INVALID_KEY", ERR_LIB_PROV, PROV_R_INVALID_KEY}, + #else + {"INVALID_KEY", 57, 158}, + #endif + #ifdef PROV_R_INVALID_KEY_LENGTH + {"INVALID_KEY_LENGTH", ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH}, + #else + {"INVALID_KEY_LENGTH", 57, 105}, + #endif + #ifdef PROV_R_INVALID_MAC + {"INVALID_MAC", ERR_LIB_PROV, PROV_R_INVALID_MAC}, + #else + {"INVALID_MAC", 57, 151}, + #endif + #ifdef PROV_R_INVALID_MGF1_MD + {"INVALID_MGF1_MD", ERR_LIB_PROV, PROV_R_INVALID_MGF1_MD}, + #else + {"INVALID_MGF1_MD", 57, 167}, + #endif + #ifdef PROV_R_INVALID_MODE + {"INVALID_MODE", ERR_LIB_PROV, PROV_R_INVALID_MODE}, + #else + {"INVALID_MODE", 57, 125}, + #endif + #ifdef PROV_R_INVALID_OUTPUT_LENGTH + {"INVALID_OUTPUT_LENGTH", ERR_LIB_PROV, PROV_R_INVALID_OUTPUT_LENGTH}, + #else + {"INVALID_OUTPUT_LENGTH", 57, 217}, + #endif + #ifdef PROV_R_INVALID_PADDING_MODE + {"INVALID_PADDING_MODE", ERR_LIB_PROV, PROV_R_INVALID_PADDING_MODE}, + #else + {"INVALID_PADDING_MODE", 57, 168}, + #endif + #ifdef PROV_R_INVALID_PUBINFO + {"INVALID_PUBINFO", ERR_LIB_PROV, PROV_R_INVALID_PUBINFO}, + #else + {"INVALID_PUBINFO", 57, 198}, + #endif + #ifdef PROV_R_INVALID_SALT_LENGTH + {"INVALID_SALT_LENGTH", ERR_LIB_PROV, PROV_R_INVALID_SALT_LENGTH}, + #else + {"INVALID_SALT_LENGTH", 57, 112}, + #endif + #ifdef PROV_R_INVALID_SEED_LENGTH + {"INVALID_SEED_LENGTH", ERR_LIB_PROV, PROV_R_INVALID_SEED_LENGTH}, + #else + {"INVALID_SEED_LENGTH", 57, 154}, + #endif + #ifdef PROV_R_INVALID_SIGNATURE_SIZE + {"INVALID_SIGNATURE_SIZE", ERR_LIB_PROV, PROV_R_INVALID_SIGNATURE_SIZE}, + #else + {"INVALID_SIGNATURE_SIZE", 57, 179}, + #endif + #ifdef PROV_R_INVALID_STATE + {"INVALID_STATE", ERR_LIB_PROV, PROV_R_INVALID_STATE}, + #else + {"INVALID_STATE", 57, 212}, + #endif + #ifdef PROV_R_INVALID_TAG + {"INVALID_TAG", ERR_LIB_PROV, PROV_R_INVALID_TAG}, + #else + {"INVALID_TAG", 57, 110}, + #endif + #ifdef PROV_R_INVALID_TAG_LENGTH + {"INVALID_TAG_LENGTH", ERR_LIB_PROV, PROV_R_INVALID_TAG_LENGTH}, + #else + {"INVALID_TAG_LENGTH", 57, 118}, + #endif + #ifdef PROV_R_INVALID_UKM_LENGTH + {"INVALID_UKM_LENGTH", ERR_LIB_PROV, PROV_R_INVALID_UKM_LENGTH}, + #else + {"INVALID_UKM_LENGTH", 57, 200}, + #endif + #ifdef PROV_R_INVALID_X931_DIGEST + {"INVALID_X931_DIGEST", ERR_LIB_PROV, PROV_R_INVALID_X931_DIGEST}, + #else + {"INVALID_X931_DIGEST", 57, 170}, + #endif + #ifdef PROV_R_IN_ERROR_STATE + {"IN_ERROR_STATE", ERR_LIB_PROV, PROV_R_IN_ERROR_STATE}, + #else + {"IN_ERROR_STATE", 57, 192}, + #endif + #ifdef PROV_R_KEY_SETUP_FAILED + {"KEY_SETUP_FAILED", ERR_LIB_PROV, PROV_R_KEY_SETUP_FAILED}, + #else + {"KEY_SETUP_FAILED", 57, 101}, + #endif + #ifdef PROV_R_KEY_SIZE_TOO_SMALL + {"KEY_SIZE_TOO_SMALL", ERR_LIB_PROV, PROV_R_KEY_SIZE_TOO_SMALL}, + #else + {"KEY_SIZE_TOO_SMALL", 57, 171}, + #endif + #ifdef PROV_R_LENGTH_TOO_LARGE + {"LENGTH_TOO_LARGE", ERR_LIB_PROV, PROV_R_LENGTH_TOO_LARGE}, + #else + {"LENGTH_TOO_LARGE", 57, 202}, + #endif + #ifdef PROV_R_MISMATCHING_DOMAIN_PARAMETERS + {"MISMATCHING_DOMAIN_PARAMETERS", ERR_LIB_PROV, PROV_R_MISMATCHING_DOMAIN_PARAMETERS}, + #else + {"MISMATCHING_DOMAIN_PARAMETERS", 57, 203}, + #endif + #ifdef PROV_R_MISSING_CEK_ALG + {"MISSING_CEK_ALG", ERR_LIB_PROV, PROV_R_MISSING_CEK_ALG}, + #else + {"MISSING_CEK_ALG", 57, 144}, + #endif + #ifdef PROV_R_MISSING_CIPHER + {"MISSING_CIPHER", ERR_LIB_PROV, PROV_R_MISSING_CIPHER}, + #else + {"MISSING_CIPHER", 57, 155}, + #endif + #ifdef PROV_R_MISSING_CONFIG_DATA + {"MISSING_CONFIG_DATA", ERR_LIB_PROV, PROV_R_MISSING_CONFIG_DATA}, + #else + {"MISSING_CONFIG_DATA", 57, 213}, + #endif + #ifdef PROV_R_MISSING_CONSTANT + {"MISSING_CONSTANT", ERR_LIB_PROV, PROV_R_MISSING_CONSTANT}, + #else + {"MISSING_CONSTANT", 57, 156}, + #endif + #ifdef PROV_R_MISSING_KEY + {"MISSING_KEY", ERR_LIB_PROV, PROV_R_MISSING_KEY}, + #else + {"MISSING_KEY", 57, 128}, + #endif + #ifdef PROV_R_MISSING_MAC + {"MISSING_MAC", ERR_LIB_PROV, PROV_R_MISSING_MAC}, + #else + {"MISSING_MAC", 57, 150}, + #endif + #ifdef PROV_R_MISSING_MESSAGE_DIGEST + {"MISSING_MESSAGE_DIGEST", ERR_LIB_PROV, PROV_R_MISSING_MESSAGE_DIGEST}, + #else + {"MISSING_MESSAGE_DIGEST", 57, 129}, + #endif + #ifdef PROV_R_MISSING_OID + {"MISSING_OID", ERR_LIB_PROV, PROV_R_MISSING_OID}, + #else + {"MISSING_OID", 57, 209}, + #endif + #ifdef PROV_R_MISSING_PASS + {"MISSING_PASS", ERR_LIB_PROV, PROV_R_MISSING_PASS}, + #else + {"MISSING_PASS", 57, 130}, + #endif + #ifdef PROV_R_MISSING_SALT + {"MISSING_SALT", ERR_LIB_PROV, PROV_R_MISSING_SALT}, + #else + {"MISSING_SALT", 57, 131}, + #endif + #ifdef PROV_R_MISSING_SECRET + {"MISSING_SECRET", ERR_LIB_PROV, PROV_R_MISSING_SECRET}, + #else + {"MISSING_SECRET", 57, 132}, + #endif + #ifdef PROV_R_MISSING_SEED + {"MISSING_SEED", ERR_LIB_PROV, PROV_R_MISSING_SEED}, + #else + {"MISSING_SEED", 57, 140}, + #endif + #ifdef PROV_R_MISSING_SESSION_ID + {"MISSING_SESSION_ID", ERR_LIB_PROV, PROV_R_MISSING_SESSION_ID}, + #else + {"MISSING_SESSION_ID", 57, 133}, + #endif + #ifdef PROV_R_MISSING_TYPE + {"MISSING_TYPE", ERR_LIB_PROV, PROV_R_MISSING_TYPE}, + #else + {"MISSING_TYPE", 57, 134}, + #endif + #ifdef PROV_R_MISSING_XCGHASH + {"MISSING_XCGHASH", ERR_LIB_PROV, PROV_R_MISSING_XCGHASH}, + #else + {"MISSING_XCGHASH", 57, 135}, + #endif + #ifdef PROV_R_MODULE_INTEGRITY_FAILURE + {"MODULE_INTEGRITY_FAILURE", ERR_LIB_PROV, PROV_R_MODULE_INTEGRITY_FAILURE}, + #else + {"MODULE_INTEGRITY_FAILURE", 57, 214}, + #endif + #ifdef PROV_R_NOT_A_PRIVATE_KEY + {"NOT_A_PRIVATE_KEY", ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY}, + #else + {"NOT_A_PRIVATE_KEY", 57, 221}, + #endif + #ifdef PROV_R_NOT_A_PUBLIC_KEY + {"NOT_A_PUBLIC_KEY", ERR_LIB_PROV, PROV_R_NOT_A_PUBLIC_KEY}, + #else + {"NOT_A_PUBLIC_KEY", 57, 220}, + #endif + #ifdef PROV_R_NOT_INSTANTIATED + {"NOT_INSTANTIATED", ERR_LIB_PROV, PROV_R_NOT_INSTANTIATED}, + #else + {"NOT_INSTANTIATED", 57, 193}, + #endif + #ifdef PROV_R_NOT_PARAMETERS + {"NOT_PARAMETERS", ERR_LIB_PROV, PROV_R_NOT_PARAMETERS}, + #else + {"NOT_PARAMETERS", 57, 226}, + #endif + #ifdef PROV_R_NOT_SUPPORTED + {"NOT_SUPPORTED", ERR_LIB_PROV, PROV_R_NOT_SUPPORTED}, + #else + {"NOT_SUPPORTED", 57, 136}, + #endif + #ifdef PROV_R_NOT_XOF_OR_INVALID_LENGTH + {"NOT_XOF_OR_INVALID_LENGTH", ERR_LIB_PROV, PROV_R_NOT_XOF_OR_INVALID_LENGTH}, + #else + {"NOT_XOF_OR_INVALID_LENGTH", 57, 113}, + #endif + #ifdef PROV_R_NO_KEY_SET + {"NO_KEY_SET", ERR_LIB_PROV, PROV_R_NO_KEY_SET}, + #else + {"NO_KEY_SET", 57, 114}, + #endif + #ifdef PROV_R_NO_PARAMETERS_SET + {"NO_PARAMETERS_SET", ERR_LIB_PROV, PROV_R_NO_PARAMETERS_SET}, + #else + {"NO_PARAMETERS_SET", 57, 177}, + #endif + #ifdef PROV_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE + {"OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE", ERR_LIB_PROV, PROV_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE}, + #else + {"OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE", 57, 178}, + #endif + #ifdef PROV_R_OUTPUT_BUFFER_TOO_SMALL + {"OUTPUT_BUFFER_TOO_SMALL", ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL}, + #else + {"OUTPUT_BUFFER_TOO_SMALL", 57, 106}, + #endif + #ifdef PROV_R_PARENT_CANNOT_GENERATE_RANDOM_NUMBERS + {"PARENT_CANNOT_GENERATE_RANDOM_NUMBERS", ERR_LIB_PROV, PROV_R_PARENT_CANNOT_GENERATE_RANDOM_NUMBERS}, + #else + {"PARENT_CANNOT_GENERATE_RANDOM_NUMBERS", 57, 228}, + #endif + #ifdef PROV_R_PARENT_CANNOT_SUPPLY_ENTROPY_SEED + {"PARENT_CANNOT_SUPPLY_ENTROPY_SEED", ERR_LIB_PROV, PROV_R_PARENT_CANNOT_SUPPLY_ENTROPY_SEED}, + #else + {"PARENT_CANNOT_SUPPLY_ENTROPY_SEED", 57, 187}, + #endif + #ifdef PROV_R_PARENT_LOCKING_NOT_ENABLED + {"PARENT_LOCKING_NOT_ENABLED", ERR_LIB_PROV, PROV_R_PARENT_LOCKING_NOT_ENABLED}, + #else + {"PARENT_LOCKING_NOT_ENABLED", 57, 182}, + #endif + #ifdef PROV_R_PARENT_STRENGTH_TOO_WEAK + {"PARENT_STRENGTH_TOO_WEAK", ERR_LIB_PROV, PROV_R_PARENT_STRENGTH_TOO_WEAK}, + #else + {"PARENT_STRENGTH_TOO_WEAK", 57, 194}, + #endif + #ifdef PROV_R_PATH_MUST_BE_ABSOLUTE + {"PATH_MUST_BE_ABSOLUTE", ERR_LIB_PROV, PROV_R_PATH_MUST_BE_ABSOLUTE}, + #else + {"PATH_MUST_BE_ABSOLUTE", 57, 219}, + #endif + #ifdef PROV_R_PERSONALISATION_STRING_TOO_LONG + {"PERSONALISATION_STRING_TOO_LONG", ERR_LIB_PROV, PROV_R_PERSONALISATION_STRING_TOO_LONG}, + #else + {"PERSONALISATION_STRING_TOO_LONG", 57, 195}, + #endif + #ifdef PROV_R_PSS_SALTLEN_TOO_SMALL + {"PSS_SALTLEN_TOO_SMALL", ERR_LIB_PROV, PROV_R_PSS_SALTLEN_TOO_SMALL}, + #else + {"PSS_SALTLEN_TOO_SMALL", 57, 172}, + #endif + #ifdef PROV_R_REQUEST_TOO_LARGE_FOR_DRBG + {"REQUEST_TOO_LARGE_FOR_DRBG", ERR_LIB_PROV, PROV_R_REQUEST_TOO_LARGE_FOR_DRBG}, + #else + {"REQUEST_TOO_LARGE_FOR_DRBG", 57, 196}, + #endif + #ifdef PROV_R_REQUIRE_CTR_MODE_CIPHER + {"REQUIRE_CTR_MODE_CIPHER", ERR_LIB_PROV, PROV_R_REQUIRE_CTR_MODE_CIPHER}, + #else + {"REQUIRE_CTR_MODE_CIPHER", 57, 206}, + #endif + #ifdef PROV_R_RESEED_ERROR + {"RESEED_ERROR", ERR_LIB_PROV, PROV_R_RESEED_ERROR}, + #else + {"RESEED_ERROR", 57, 197}, + #endif + #ifdef PROV_R_SEARCH_ONLY_SUPPORTED_FOR_DIRECTORIES + {"SEARCH_ONLY_SUPPORTED_FOR_DIRECTORIES", ERR_LIB_PROV, PROV_R_SEARCH_ONLY_SUPPORTED_FOR_DIRECTORIES}, + #else + {"SEARCH_ONLY_SUPPORTED_FOR_DIRECTORIES", 57, 222}, + #endif + #ifdef PROV_R_SEED_SOURCES_MUST_NOT_HAVE_A_PARENT + {"SEED_SOURCES_MUST_NOT_HAVE_A_PARENT", ERR_LIB_PROV, PROV_R_SEED_SOURCES_MUST_NOT_HAVE_A_PARENT}, + #else + {"SEED_SOURCES_MUST_NOT_HAVE_A_PARENT", 57, 229}, + #endif + #ifdef PROV_R_SELF_TEST_KAT_FAILURE + {"SELF_TEST_KAT_FAILURE", ERR_LIB_PROV, PROV_R_SELF_TEST_KAT_FAILURE}, + #else + {"SELF_TEST_KAT_FAILURE", 57, 215}, + #endif + #ifdef PROV_R_SELF_TEST_POST_FAILURE + {"SELF_TEST_POST_FAILURE", ERR_LIB_PROV, PROV_R_SELF_TEST_POST_FAILURE}, + #else + {"SELF_TEST_POST_FAILURE", 57, 216}, + #endif + #ifdef PROV_R_TAG_NOT_NEEDED + {"TAG_NOT_NEEDED", ERR_LIB_PROV, PROV_R_TAG_NOT_NEEDED}, + #else + {"TAG_NOT_NEEDED", 57, 120}, + #endif + #ifdef PROV_R_TAG_NOT_SET + {"TAG_NOT_SET", ERR_LIB_PROV, PROV_R_TAG_NOT_SET}, + #else + {"TAG_NOT_SET", 57, 119}, + #endif + #ifdef PROV_R_TOO_MANY_RECORDS + {"TOO_MANY_RECORDS", ERR_LIB_PROV, PROV_R_TOO_MANY_RECORDS}, + #else + {"TOO_MANY_RECORDS", 57, 126}, + #endif + #ifdef PROV_R_UNABLE_TO_FIND_CIPHERS + {"UNABLE_TO_FIND_CIPHERS", ERR_LIB_PROV, PROV_R_UNABLE_TO_FIND_CIPHERS}, + #else + {"UNABLE_TO_FIND_CIPHERS", 57, 207}, + #endif + #ifdef PROV_R_UNABLE_TO_GET_PARENT_STRENGTH + {"UNABLE_TO_GET_PARENT_STRENGTH", ERR_LIB_PROV, PROV_R_UNABLE_TO_GET_PARENT_STRENGTH}, + #else + {"UNABLE_TO_GET_PARENT_STRENGTH", 57, 199}, + #endif + #ifdef PROV_R_UNABLE_TO_GET_PASSPHRASE + {"UNABLE_TO_GET_PASSPHRASE", ERR_LIB_PROV, PROV_R_UNABLE_TO_GET_PASSPHRASE}, + #else + {"UNABLE_TO_GET_PASSPHRASE", 57, 159}, + #endif + #ifdef PROV_R_UNABLE_TO_INITIALISE_CIPHERS + {"UNABLE_TO_INITIALISE_CIPHERS", ERR_LIB_PROV, PROV_R_UNABLE_TO_INITIALISE_CIPHERS}, + #else + {"UNABLE_TO_INITIALISE_CIPHERS", 57, 208}, + #endif + #ifdef PROV_R_UNABLE_TO_LOAD_SHA256 + {"UNABLE_TO_LOAD_SHA256", ERR_LIB_PROV, PROV_R_UNABLE_TO_LOAD_SHA256}, + #else + {"UNABLE_TO_LOAD_SHA256", 57, 147}, + #endif + #ifdef PROV_R_UNABLE_TO_LOCK_PARENT + {"UNABLE_TO_LOCK_PARENT", ERR_LIB_PROV, PROV_R_UNABLE_TO_LOCK_PARENT}, + #else + {"UNABLE_TO_LOCK_PARENT", 57, 201}, + #endif + #ifdef PROV_R_UNABLE_TO_RESEED + {"UNABLE_TO_RESEED", ERR_LIB_PROV, PROV_R_UNABLE_TO_RESEED}, + #else + {"UNABLE_TO_RESEED", 57, 204}, + #endif + #ifdef PROV_R_UNSUPPORTED_CEK_ALG + {"UNSUPPORTED_CEK_ALG", ERR_LIB_PROV, PROV_R_UNSUPPORTED_CEK_ALG}, + #else + {"UNSUPPORTED_CEK_ALG", 57, 145}, + #endif + #ifdef PROV_R_UNSUPPORTED_KEY_SIZE + {"UNSUPPORTED_KEY_SIZE", ERR_LIB_PROV, PROV_R_UNSUPPORTED_KEY_SIZE}, + #else + {"UNSUPPORTED_KEY_SIZE", 57, 153}, + #endif + #ifdef PROV_R_UNSUPPORTED_MAC_TYPE + {"UNSUPPORTED_MAC_TYPE", ERR_LIB_PROV, PROV_R_UNSUPPORTED_MAC_TYPE}, + #else + {"UNSUPPORTED_MAC_TYPE", 57, 137}, + #endif + #ifdef PROV_R_UNSUPPORTED_NUMBER_OF_ROUNDS + {"UNSUPPORTED_NUMBER_OF_ROUNDS", ERR_LIB_PROV, PROV_R_UNSUPPORTED_NUMBER_OF_ROUNDS}, + #else + {"UNSUPPORTED_NUMBER_OF_ROUNDS", 57, 152}, + #endif + #ifdef PROV_R_URI_AUTHORITY_UNSUPPORTED + {"URI_AUTHORITY_UNSUPPORTED", ERR_LIB_PROV, PROV_R_URI_AUTHORITY_UNSUPPORTED}, + #else + {"URI_AUTHORITY_UNSUPPORTED", 57, 223}, + #endif + #ifdef PROV_R_VALUE_ERROR + {"VALUE_ERROR", ERR_LIB_PROV, PROV_R_VALUE_ERROR}, + #else + {"VALUE_ERROR", 57, 138}, + #endif + #ifdef PROV_R_WRONG_FINAL_BLOCK_LENGTH + {"WRONG_FINAL_BLOCK_LENGTH", ERR_LIB_PROV, PROV_R_WRONG_FINAL_BLOCK_LENGTH}, + #else + {"WRONG_FINAL_BLOCK_LENGTH", 57, 107}, + #endif + #ifdef PROV_R_WRONG_OUTPUT_BUFFER_SIZE + {"WRONG_OUTPUT_BUFFER_SIZE", ERR_LIB_PROV, PROV_R_WRONG_OUTPUT_BUFFER_SIZE}, + #else + {"WRONG_OUTPUT_BUFFER_SIZE", 57, 139}, + #endif + #ifdef PROV_R_XOF_DIGESTS_NOT_ALLOWED + {"XOF_DIGESTS_NOT_ALLOWED", ERR_LIB_PROV, PROV_R_XOF_DIGESTS_NOT_ALLOWED}, + #else + {"XOF_DIGESTS_NOT_ALLOWED", 57, 183}, + #endif + #ifdef PROV_R_XTS_DATA_UNIT_IS_TOO_LARGE + {"XTS_DATA_UNIT_IS_TOO_LARGE", ERR_LIB_PROV, PROV_R_XTS_DATA_UNIT_IS_TOO_LARGE}, + #else + {"XTS_DATA_UNIT_IS_TOO_LARGE", 57, 148}, + #endif + #ifdef PROV_R_XTS_DUPLICATED_KEYS + {"XTS_DUPLICATED_KEYS", ERR_LIB_PROV, PROV_R_XTS_DUPLICATED_KEYS}, + #else + {"XTS_DUPLICATED_KEYS", 57, 149}, + #endif + #ifdef RAND_R_ADDITIONAL_INPUT_TOO_LONG + {"ADDITIONAL_INPUT_TOO_LONG", ERR_LIB_RAND, RAND_R_ADDITIONAL_INPUT_TOO_LONG}, + #else + {"ADDITIONAL_INPUT_TOO_LONG", 36, 102}, + #endif + #ifdef RAND_R_ALREADY_INSTANTIATED + {"ALREADY_INSTANTIATED", ERR_LIB_RAND, RAND_R_ALREADY_INSTANTIATED}, + #else + {"ALREADY_INSTANTIATED", 36, 103}, + #endif + #ifdef RAND_R_ARGUMENT_OUT_OF_RANGE + {"ARGUMENT_OUT_OF_RANGE", ERR_LIB_RAND, RAND_R_ARGUMENT_OUT_OF_RANGE}, + #else + {"ARGUMENT_OUT_OF_RANGE", 36, 105}, + #endif + #ifdef RAND_R_CANNOT_OPEN_FILE + {"CANNOT_OPEN_FILE", ERR_LIB_RAND, RAND_R_CANNOT_OPEN_FILE}, + #else + {"CANNOT_OPEN_FILE", 36, 121}, + #endif + #ifdef RAND_R_DRBG_ALREADY_INITIALIZED + {"DRBG_ALREADY_INITIALIZED", ERR_LIB_RAND, RAND_R_DRBG_ALREADY_INITIALIZED}, + #else + {"DRBG_ALREADY_INITIALIZED", 36, 129}, + #endif + #ifdef RAND_R_DRBG_NOT_INITIALISED + {"DRBG_NOT_INITIALISED", ERR_LIB_RAND, RAND_R_DRBG_NOT_INITIALISED}, + #else + {"DRBG_NOT_INITIALISED", 36, 104}, + #endif + #ifdef RAND_R_ENTROPY_INPUT_TOO_LONG + {"ENTROPY_INPUT_TOO_LONG", ERR_LIB_RAND, RAND_R_ENTROPY_INPUT_TOO_LONG}, + #else + {"ENTROPY_INPUT_TOO_LONG", 36, 106}, + #endif + #ifdef RAND_R_ENTROPY_OUT_OF_RANGE + {"ENTROPY_OUT_OF_RANGE", ERR_LIB_RAND, RAND_R_ENTROPY_OUT_OF_RANGE}, + #else + {"ENTROPY_OUT_OF_RANGE", 36, 124}, + #endif + #ifdef RAND_R_ERROR_ENTROPY_POOL_WAS_IGNORED + {"ERROR_ENTROPY_POOL_WAS_IGNORED", ERR_LIB_RAND, RAND_R_ERROR_ENTROPY_POOL_WAS_IGNORED}, + #else + {"ERROR_ENTROPY_POOL_WAS_IGNORED", 36, 127}, + #endif + #ifdef RAND_R_ERROR_INITIALISING_DRBG + {"ERROR_INITIALISING_DRBG", ERR_LIB_RAND, RAND_R_ERROR_INITIALISING_DRBG}, + #else + {"ERROR_INITIALISING_DRBG", 36, 107}, + #endif + #ifdef RAND_R_ERROR_INSTANTIATING_DRBG + {"ERROR_INSTANTIATING_DRBG", ERR_LIB_RAND, RAND_R_ERROR_INSTANTIATING_DRBG}, + #else + {"ERROR_INSTANTIATING_DRBG", 36, 108}, + #endif + #ifdef RAND_R_ERROR_RETRIEVING_ADDITIONAL_INPUT + {"ERROR_RETRIEVING_ADDITIONAL_INPUT", ERR_LIB_RAND, RAND_R_ERROR_RETRIEVING_ADDITIONAL_INPUT}, + #else + {"ERROR_RETRIEVING_ADDITIONAL_INPUT", 36, 109}, + #endif + #ifdef RAND_R_ERROR_RETRIEVING_ENTROPY + {"ERROR_RETRIEVING_ENTROPY", ERR_LIB_RAND, RAND_R_ERROR_RETRIEVING_ENTROPY}, + #else + {"ERROR_RETRIEVING_ENTROPY", 36, 110}, + #endif + #ifdef RAND_R_ERROR_RETRIEVING_NONCE + {"ERROR_RETRIEVING_NONCE", ERR_LIB_RAND, RAND_R_ERROR_RETRIEVING_NONCE}, + #else + {"ERROR_RETRIEVING_NONCE", 36, 111}, + #endif + #ifdef RAND_R_FAILED_TO_CREATE_LOCK + {"FAILED_TO_CREATE_LOCK", ERR_LIB_RAND, RAND_R_FAILED_TO_CREATE_LOCK}, + #else + {"FAILED_TO_CREATE_LOCK", 36, 126}, + #endif + #ifdef RAND_R_FUNC_NOT_IMPLEMENTED + {"FUNC_NOT_IMPLEMENTED", ERR_LIB_RAND, RAND_R_FUNC_NOT_IMPLEMENTED}, + #else + {"FUNC_NOT_IMPLEMENTED", 36, 101}, + #endif + #ifdef RAND_R_FWRITE_ERROR + {"FWRITE_ERROR", ERR_LIB_RAND, RAND_R_FWRITE_ERROR}, + #else + {"FWRITE_ERROR", 36, 123}, + #endif + #ifdef RAND_R_GENERATE_ERROR + {"GENERATE_ERROR", ERR_LIB_RAND, RAND_R_GENERATE_ERROR}, + #else + {"GENERATE_ERROR", 36, 112}, + #endif + #ifdef RAND_R_INSUFFICIENT_DRBG_STRENGTH + {"INSUFFICIENT_DRBG_STRENGTH", ERR_LIB_RAND, RAND_R_INSUFFICIENT_DRBG_STRENGTH}, + #else + {"INSUFFICIENT_DRBG_STRENGTH", 36, 139}, + #endif + #ifdef RAND_R_INTERNAL_ERROR + {"INTERNAL_ERROR", ERR_LIB_RAND, RAND_R_INTERNAL_ERROR}, + #else + {"INTERNAL_ERROR", 36, 113}, + #endif + #ifdef RAND_R_IN_ERROR_STATE + {"IN_ERROR_STATE", ERR_LIB_RAND, RAND_R_IN_ERROR_STATE}, + #else + {"IN_ERROR_STATE", 36, 114}, + #endif + #ifdef RAND_R_NOT_A_REGULAR_FILE + {"NOT_A_REGULAR_FILE", ERR_LIB_RAND, RAND_R_NOT_A_REGULAR_FILE}, + #else + {"NOT_A_REGULAR_FILE", 36, 122}, + #endif + #ifdef RAND_R_NOT_INSTANTIATED + {"NOT_INSTANTIATED", ERR_LIB_RAND, RAND_R_NOT_INSTANTIATED}, + #else + {"NOT_INSTANTIATED", 36, 115}, + #endif + #ifdef RAND_R_NO_DRBG_IMPLEMENTATION_SELECTED + {"NO_DRBG_IMPLEMENTATION_SELECTED", ERR_LIB_RAND, RAND_R_NO_DRBG_IMPLEMENTATION_SELECTED}, + #else + {"NO_DRBG_IMPLEMENTATION_SELECTED", 36, 128}, + #endif + #ifdef RAND_R_PARENT_LOCKING_NOT_ENABLED + {"PARENT_LOCKING_NOT_ENABLED", ERR_LIB_RAND, RAND_R_PARENT_LOCKING_NOT_ENABLED}, + #else + {"PARENT_LOCKING_NOT_ENABLED", 36, 130}, + #endif + #ifdef RAND_R_PARENT_STRENGTH_TOO_WEAK + {"PARENT_STRENGTH_TOO_WEAK", ERR_LIB_RAND, RAND_R_PARENT_STRENGTH_TOO_WEAK}, + #else + {"PARENT_STRENGTH_TOO_WEAK", 36, 131}, + #endif + #ifdef RAND_R_PERSONALISATION_STRING_TOO_LONG + {"PERSONALISATION_STRING_TOO_LONG", ERR_LIB_RAND, RAND_R_PERSONALISATION_STRING_TOO_LONG}, + #else + {"PERSONALISATION_STRING_TOO_LONG", 36, 116}, + #endif + #ifdef RAND_R_PREDICTION_RESISTANCE_NOT_SUPPORTED + {"PREDICTION_RESISTANCE_NOT_SUPPORTED", ERR_LIB_RAND, RAND_R_PREDICTION_RESISTANCE_NOT_SUPPORTED}, + #else + {"PREDICTION_RESISTANCE_NOT_SUPPORTED", 36, 133}, + #endif + #ifdef RAND_R_PRNG_NOT_SEEDED + {"PRNG_NOT_SEEDED", ERR_LIB_RAND, RAND_R_PRNG_NOT_SEEDED}, + #else + {"PRNG_NOT_SEEDED", 36, 100}, + #endif + #ifdef RAND_R_RANDOM_POOL_OVERFLOW + {"RANDOM_POOL_OVERFLOW", ERR_LIB_RAND, RAND_R_RANDOM_POOL_OVERFLOW}, + #else + {"RANDOM_POOL_OVERFLOW", 36, 125}, + #endif + #ifdef RAND_R_RANDOM_POOL_UNDERFLOW + {"RANDOM_POOL_UNDERFLOW", ERR_LIB_RAND, RAND_R_RANDOM_POOL_UNDERFLOW}, + #else + {"RANDOM_POOL_UNDERFLOW", 36, 134}, + #endif + #ifdef RAND_R_REQUEST_TOO_LARGE_FOR_DRBG + {"REQUEST_TOO_LARGE_FOR_DRBG", ERR_LIB_RAND, RAND_R_REQUEST_TOO_LARGE_FOR_DRBG}, + #else + {"REQUEST_TOO_LARGE_FOR_DRBG", 36, 117}, + #endif + #ifdef RAND_R_RESEED_ERROR + {"RESEED_ERROR", ERR_LIB_RAND, RAND_R_RESEED_ERROR}, + #else + {"RESEED_ERROR", 36, 118}, + #endif + #ifdef RAND_R_SELFTEST_FAILURE + {"SELFTEST_FAILURE", ERR_LIB_RAND, RAND_R_SELFTEST_FAILURE}, + #else + {"SELFTEST_FAILURE", 36, 119}, + #endif + #ifdef RAND_R_TOO_LITTLE_NONCE_REQUESTED + {"TOO_LITTLE_NONCE_REQUESTED", ERR_LIB_RAND, RAND_R_TOO_LITTLE_NONCE_REQUESTED}, + #else + {"TOO_LITTLE_NONCE_REQUESTED", 36, 135}, + #endif + #ifdef RAND_R_TOO_MUCH_NONCE_REQUESTED + {"TOO_MUCH_NONCE_REQUESTED", ERR_LIB_RAND, RAND_R_TOO_MUCH_NONCE_REQUESTED}, + #else + {"TOO_MUCH_NONCE_REQUESTED", 36, 136}, + #endif + #ifdef RAND_R_UNABLE_TO_CREATE_DRBG + {"UNABLE_TO_CREATE_DRBG", ERR_LIB_RAND, RAND_R_UNABLE_TO_CREATE_DRBG}, + #else + {"UNABLE_TO_CREATE_DRBG", 36, 143}, + #endif + #ifdef RAND_R_UNABLE_TO_FETCH_DRBG + {"UNABLE_TO_FETCH_DRBG", ERR_LIB_RAND, RAND_R_UNABLE_TO_FETCH_DRBG}, + #else + {"UNABLE_TO_FETCH_DRBG", 36, 144}, + #endif + #ifdef RAND_R_UNABLE_TO_GET_PARENT_RESEED_PROP_COUNTER + {"UNABLE_TO_GET_PARENT_RESEED_PROP_COUNTER", ERR_LIB_RAND, RAND_R_UNABLE_TO_GET_PARENT_RESEED_PROP_COUNTER}, + #else + {"UNABLE_TO_GET_PARENT_RESEED_PROP_COUNTER", 36, 141}, + #endif + #ifdef RAND_R_UNABLE_TO_GET_PARENT_STRENGTH + {"UNABLE_TO_GET_PARENT_STRENGTH", ERR_LIB_RAND, RAND_R_UNABLE_TO_GET_PARENT_STRENGTH}, + #else + {"UNABLE_TO_GET_PARENT_STRENGTH", 36, 138}, + #endif + #ifdef RAND_R_UNABLE_TO_LOCK_PARENT + {"UNABLE_TO_LOCK_PARENT", ERR_LIB_RAND, RAND_R_UNABLE_TO_LOCK_PARENT}, + #else + {"UNABLE_TO_LOCK_PARENT", 36, 140}, + #endif + #ifdef RAND_R_UNSUPPORTED_DRBG_FLAGS + {"UNSUPPORTED_DRBG_FLAGS", ERR_LIB_RAND, RAND_R_UNSUPPORTED_DRBG_FLAGS}, + #else + {"UNSUPPORTED_DRBG_FLAGS", 36, 132}, + #endif + #ifdef RAND_R_UNSUPPORTED_DRBG_TYPE + {"UNSUPPORTED_DRBG_TYPE", ERR_LIB_RAND, RAND_R_UNSUPPORTED_DRBG_TYPE}, + #else + {"UNSUPPORTED_DRBG_TYPE", 36, 120}, + #endif + #ifdef RSA_R_ALGORITHM_MISMATCH + {"ALGORITHM_MISMATCH", ERR_LIB_RSA, RSA_R_ALGORITHM_MISMATCH}, + #else + {"ALGORITHM_MISMATCH", 4, 100}, + #endif + #ifdef RSA_R_BAD_E_VALUE + {"BAD_E_VALUE", ERR_LIB_RSA, RSA_R_BAD_E_VALUE}, + #else + {"BAD_E_VALUE", 4, 101}, + #endif + #ifdef RSA_R_BAD_FIXED_HEADER_DECRYPT + {"BAD_FIXED_HEADER_DECRYPT", ERR_LIB_RSA, RSA_R_BAD_FIXED_HEADER_DECRYPT}, + #else + {"BAD_FIXED_HEADER_DECRYPT", 4, 102}, + #endif + #ifdef RSA_R_BAD_PAD_BYTE_COUNT + {"BAD_PAD_BYTE_COUNT", ERR_LIB_RSA, RSA_R_BAD_PAD_BYTE_COUNT}, + #else + {"BAD_PAD_BYTE_COUNT", 4, 103}, + #endif + #ifdef RSA_R_BAD_SIGNATURE + {"BAD_SIGNATURE", ERR_LIB_RSA, RSA_R_BAD_SIGNATURE}, + #else + {"BAD_SIGNATURE", 4, 104}, + #endif + #ifdef RSA_R_BLOCK_TYPE_IS_NOT_01 + {"BLOCK_TYPE_IS_NOT_01", ERR_LIB_RSA, RSA_R_BLOCK_TYPE_IS_NOT_01}, + #else + {"BLOCK_TYPE_IS_NOT_01", 4, 106}, + #endif + #ifdef RSA_R_BLOCK_TYPE_IS_NOT_02 + {"BLOCK_TYPE_IS_NOT_02", ERR_LIB_RSA, RSA_R_BLOCK_TYPE_IS_NOT_02}, + #else + {"BLOCK_TYPE_IS_NOT_02", 4, 107}, + #endif + #ifdef RSA_R_DATA_GREATER_THAN_MOD_LEN + {"DATA_GREATER_THAN_MOD_LEN", ERR_LIB_RSA, RSA_R_DATA_GREATER_THAN_MOD_LEN}, + #else + {"DATA_GREATER_THAN_MOD_LEN", 4, 108}, + #endif + #ifdef RSA_R_DATA_TOO_LARGE + {"DATA_TOO_LARGE", ERR_LIB_RSA, RSA_R_DATA_TOO_LARGE}, + #else + {"DATA_TOO_LARGE", 4, 109}, + #endif + #ifdef RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE + {"DATA_TOO_LARGE_FOR_KEY_SIZE", ERR_LIB_RSA, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE}, + #else + {"DATA_TOO_LARGE_FOR_KEY_SIZE", 4, 110}, + #endif + #ifdef RSA_R_DATA_TOO_LARGE_FOR_MODULUS + {"DATA_TOO_LARGE_FOR_MODULUS", ERR_LIB_RSA, RSA_R_DATA_TOO_LARGE_FOR_MODULUS}, + #else + {"DATA_TOO_LARGE_FOR_MODULUS", 4, 132}, + #endif + #ifdef RSA_R_DATA_TOO_SMALL + {"DATA_TOO_SMALL", ERR_LIB_RSA, RSA_R_DATA_TOO_SMALL}, + #else + {"DATA_TOO_SMALL", 4, 111}, + #endif + #ifdef RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE + {"DATA_TOO_SMALL_FOR_KEY_SIZE", ERR_LIB_RSA, RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE}, + #else + {"DATA_TOO_SMALL_FOR_KEY_SIZE", 4, 122}, + #endif + #ifdef RSA_R_DIGEST_DOES_NOT_MATCH + {"DIGEST_DOES_NOT_MATCH", ERR_LIB_RSA, RSA_R_DIGEST_DOES_NOT_MATCH}, + #else + {"DIGEST_DOES_NOT_MATCH", 4, 158}, + #endif + #ifdef RSA_R_DIGEST_NOT_ALLOWED + {"DIGEST_NOT_ALLOWED", ERR_LIB_RSA, RSA_R_DIGEST_NOT_ALLOWED}, + #else + {"DIGEST_NOT_ALLOWED", 4, 145}, + #endif + #ifdef RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY + {"DIGEST_TOO_BIG_FOR_RSA_KEY", ERR_LIB_RSA, RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY}, + #else + {"DIGEST_TOO_BIG_FOR_RSA_KEY", 4, 112}, + #endif + #ifdef RSA_R_DMP1_NOT_CONGRUENT_TO_D + {"DMP1_NOT_CONGRUENT_TO_D", ERR_LIB_RSA, RSA_R_DMP1_NOT_CONGRUENT_TO_D}, + #else + {"DMP1_NOT_CONGRUENT_TO_D", 4, 124}, + #endif + #ifdef RSA_R_DMQ1_NOT_CONGRUENT_TO_D + {"DMQ1_NOT_CONGRUENT_TO_D", ERR_LIB_RSA, RSA_R_DMQ1_NOT_CONGRUENT_TO_D}, + #else + {"DMQ1_NOT_CONGRUENT_TO_D", 4, 125}, + #endif + #ifdef RSA_R_D_E_NOT_CONGRUENT_TO_1 + {"D_E_NOT_CONGRUENT_TO_1", ERR_LIB_RSA, RSA_R_D_E_NOT_CONGRUENT_TO_1}, + #else + {"D_E_NOT_CONGRUENT_TO_1", 4, 123}, + #endif + #ifdef RSA_R_FIRST_OCTET_INVALID + {"FIRST_OCTET_INVALID", ERR_LIB_RSA, RSA_R_FIRST_OCTET_INVALID}, + #else + {"FIRST_OCTET_INVALID", 4, 133}, + #endif + #ifdef RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE + {"ILLEGAL_OR_UNSUPPORTED_PADDING_MODE", ERR_LIB_RSA, RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE}, + #else + {"ILLEGAL_OR_UNSUPPORTED_PADDING_MODE", 4, 144}, + #endif + #ifdef RSA_R_INVALID_DIGEST + {"INVALID_DIGEST", ERR_LIB_RSA, RSA_R_INVALID_DIGEST}, + #else + {"INVALID_DIGEST", 4, 157}, + #endif + #ifdef RSA_R_INVALID_DIGEST_LENGTH + {"INVALID_DIGEST_LENGTH", ERR_LIB_RSA, RSA_R_INVALID_DIGEST_LENGTH}, + #else + {"INVALID_DIGEST_LENGTH", 4, 143}, + #endif + #ifdef RSA_R_INVALID_HEADER + {"INVALID_HEADER", ERR_LIB_RSA, RSA_R_INVALID_HEADER}, + #else + {"INVALID_HEADER", 4, 137}, + #endif + #ifdef RSA_R_INVALID_KEYPAIR + {"INVALID_KEYPAIR", ERR_LIB_RSA, RSA_R_INVALID_KEYPAIR}, + #else + {"INVALID_KEYPAIR", 4, 171}, + #endif + #ifdef RSA_R_INVALID_KEY_LENGTH + {"INVALID_KEY_LENGTH", ERR_LIB_RSA, RSA_R_INVALID_KEY_LENGTH}, + #else + {"INVALID_KEY_LENGTH", 4, 173}, + #endif + #ifdef RSA_R_INVALID_LABEL + {"INVALID_LABEL", ERR_LIB_RSA, RSA_R_INVALID_LABEL}, + #else + {"INVALID_LABEL", 4, 160}, + #endif + #ifdef RSA_R_INVALID_LENGTH + {"INVALID_LENGTH", ERR_LIB_RSA, RSA_R_INVALID_LENGTH}, + #else + {"INVALID_LENGTH", 4, 181}, + #endif + #ifdef RSA_R_INVALID_MESSAGE_LENGTH + {"INVALID_MESSAGE_LENGTH", ERR_LIB_RSA, RSA_R_INVALID_MESSAGE_LENGTH}, + #else + {"INVALID_MESSAGE_LENGTH", 4, 131}, + #endif + #ifdef RSA_R_INVALID_MGF1_MD + {"INVALID_MGF1_MD", ERR_LIB_RSA, RSA_R_INVALID_MGF1_MD}, + #else + {"INVALID_MGF1_MD", 4, 156}, + #endif + #ifdef RSA_R_INVALID_MODULUS + {"INVALID_MODULUS", ERR_LIB_RSA, RSA_R_INVALID_MODULUS}, + #else + {"INVALID_MODULUS", 4, 174}, + #endif + #ifdef RSA_R_INVALID_MULTI_PRIME_KEY + {"INVALID_MULTI_PRIME_KEY", ERR_LIB_RSA, RSA_R_INVALID_MULTI_PRIME_KEY}, + #else + {"INVALID_MULTI_PRIME_KEY", 4, 167}, + #endif + #ifdef RSA_R_INVALID_OAEP_PARAMETERS + {"INVALID_OAEP_PARAMETERS", ERR_LIB_RSA, RSA_R_INVALID_OAEP_PARAMETERS}, + #else + {"INVALID_OAEP_PARAMETERS", 4, 161}, + #endif + #ifdef RSA_R_INVALID_PADDING + {"INVALID_PADDING", ERR_LIB_RSA, RSA_R_INVALID_PADDING}, + #else + {"INVALID_PADDING", 4, 138}, + #endif + #ifdef RSA_R_INVALID_PADDING_MODE + {"INVALID_PADDING_MODE", ERR_LIB_RSA, RSA_R_INVALID_PADDING_MODE}, + #else + {"INVALID_PADDING_MODE", 4, 141}, + #endif + #ifdef RSA_R_INVALID_PSS_PARAMETERS + {"INVALID_PSS_PARAMETERS", ERR_LIB_RSA, RSA_R_INVALID_PSS_PARAMETERS}, + #else + {"INVALID_PSS_PARAMETERS", 4, 149}, + #endif + #ifdef RSA_R_INVALID_PSS_SALTLEN + {"INVALID_PSS_SALTLEN", ERR_LIB_RSA, RSA_R_INVALID_PSS_SALTLEN}, + #else + {"INVALID_PSS_SALTLEN", 4, 146}, + #endif + #ifdef RSA_R_INVALID_REQUEST + {"INVALID_REQUEST", ERR_LIB_RSA, RSA_R_INVALID_REQUEST}, + #else + {"INVALID_REQUEST", 4, 175}, + #endif + #ifdef RSA_R_INVALID_SALT_LENGTH + {"INVALID_SALT_LENGTH", ERR_LIB_RSA, RSA_R_INVALID_SALT_LENGTH}, + #else + {"INVALID_SALT_LENGTH", 4, 150}, + #endif + #ifdef RSA_R_INVALID_STRENGTH + {"INVALID_STRENGTH", ERR_LIB_RSA, RSA_R_INVALID_STRENGTH}, + #else + {"INVALID_STRENGTH", 4, 176}, + #endif + #ifdef RSA_R_INVALID_TRAILER + {"INVALID_TRAILER", ERR_LIB_RSA, RSA_R_INVALID_TRAILER}, + #else + {"INVALID_TRAILER", 4, 139}, + #endif + #ifdef RSA_R_INVALID_X931_DIGEST + {"INVALID_X931_DIGEST", ERR_LIB_RSA, RSA_R_INVALID_X931_DIGEST}, + #else + {"INVALID_X931_DIGEST", 4, 142}, + #endif + #ifdef RSA_R_IQMP_NOT_INVERSE_OF_Q + {"IQMP_NOT_INVERSE_OF_Q", ERR_LIB_RSA, RSA_R_IQMP_NOT_INVERSE_OF_Q}, + #else + {"IQMP_NOT_INVERSE_OF_Q", 4, 126}, + #endif + #ifdef RSA_R_KEY_PRIME_NUM_INVALID + {"KEY_PRIME_NUM_INVALID", ERR_LIB_RSA, RSA_R_KEY_PRIME_NUM_INVALID}, + #else + {"KEY_PRIME_NUM_INVALID", 4, 165}, + #endif + #ifdef RSA_R_KEY_SIZE_TOO_SMALL + {"KEY_SIZE_TOO_SMALL", ERR_LIB_RSA, RSA_R_KEY_SIZE_TOO_SMALL}, + #else + {"KEY_SIZE_TOO_SMALL", 4, 120}, + #endif + #ifdef RSA_R_LAST_OCTET_INVALID + {"LAST_OCTET_INVALID", ERR_LIB_RSA, RSA_R_LAST_OCTET_INVALID}, + #else + {"LAST_OCTET_INVALID", 4, 134}, + #endif + #ifdef RSA_R_MGF1_DIGEST_NOT_ALLOWED + {"MGF1_DIGEST_NOT_ALLOWED", ERR_LIB_RSA, RSA_R_MGF1_DIGEST_NOT_ALLOWED}, + #else + {"MGF1_DIGEST_NOT_ALLOWED", 4, 152}, + #endif + #ifdef RSA_R_MISSING_PRIVATE_KEY + {"MISSING_PRIVATE_KEY", ERR_LIB_RSA, RSA_R_MISSING_PRIVATE_KEY}, + #else + {"MISSING_PRIVATE_KEY", 4, 179}, + #endif + #ifdef RSA_R_MODULUS_TOO_LARGE + {"MODULUS_TOO_LARGE", ERR_LIB_RSA, RSA_R_MODULUS_TOO_LARGE}, + #else + {"MODULUS_TOO_LARGE", 4, 105}, + #endif + #ifdef RSA_R_MP_COEFFICIENT_NOT_INVERSE_OF_R + {"MP_COEFFICIENT_NOT_INVERSE_OF_R", ERR_LIB_RSA, RSA_R_MP_COEFFICIENT_NOT_INVERSE_OF_R}, + #else + {"MP_COEFFICIENT_NOT_INVERSE_OF_R", 4, 168}, + #endif + #ifdef RSA_R_MP_EXPONENT_NOT_CONGRUENT_TO_D + {"MP_EXPONENT_NOT_CONGRUENT_TO_D", ERR_LIB_RSA, RSA_R_MP_EXPONENT_NOT_CONGRUENT_TO_D}, + #else + {"MP_EXPONENT_NOT_CONGRUENT_TO_D", 4, 169}, + #endif + #ifdef RSA_R_MP_R_NOT_PRIME + {"MP_R_NOT_PRIME", ERR_LIB_RSA, RSA_R_MP_R_NOT_PRIME}, + #else + {"MP_R_NOT_PRIME", 4, 170}, + #endif + #ifdef RSA_R_NO_PUBLIC_EXPONENT + {"NO_PUBLIC_EXPONENT", ERR_LIB_RSA, RSA_R_NO_PUBLIC_EXPONENT}, + #else + {"NO_PUBLIC_EXPONENT", 4, 140}, + #endif + #ifdef RSA_R_NULL_BEFORE_BLOCK_MISSING + {"NULL_BEFORE_BLOCK_MISSING", ERR_LIB_RSA, RSA_R_NULL_BEFORE_BLOCK_MISSING}, + #else + {"NULL_BEFORE_BLOCK_MISSING", 4, 113}, + #endif + #ifdef RSA_R_N_DOES_NOT_EQUAL_PRODUCT_OF_PRIMES + {"N_DOES_NOT_EQUAL_PRODUCT_OF_PRIMES", ERR_LIB_RSA, RSA_R_N_DOES_NOT_EQUAL_PRODUCT_OF_PRIMES}, + #else + {"N_DOES_NOT_EQUAL_PRODUCT_OF_PRIMES", 4, 172}, + #endif + #ifdef RSA_R_N_DOES_NOT_EQUAL_P_Q + {"N_DOES_NOT_EQUAL_P_Q", ERR_LIB_RSA, RSA_R_N_DOES_NOT_EQUAL_P_Q}, + #else + {"N_DOES_NOT_EQUAL_P_Q", 4, 127}, + #endif + #ifdef RSA_R_OAEP_DECODING_ERROR + {"OAEP_DECODING_ERROR", ERR_LIB_RSA, RSA_R_OAEP_DECODING_ERROR}, + #else + {"OAEP_DECODING_ERROR", 4, 121}, + #endif + #ifdef RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE + {"OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE", ERR_LIB_RSA, RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE}, + #else + {"OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE", 4, 148}, + #endif + #ifdef RSA_R_PADDING_CHECK_FAILED + {"PADDING_CHECK_FAILED", ERR_LIB_RSA, RSA_R_PADDING_CHECK_FAILED}, + #else + {"PADDING_CHECK_FAILED", 4, 114}, + #endif + #ifdef RSA_R_PAIRWISE_TEST_FAILURE + {"PAIRWISE_TEST_FAILURE", ERR_LIB_RSA, RSA_R_PAIRWISE_TEST_FAILURE}, + #else + {"PAIRWISE_TEST_FAILURE", 4, 177}, + #endif + #ifdef RSA_R_PKCS_DECODING_ERROR + {"PKCS_DECODING_ERROR", ERR_LIB_RSA, RSA_R_PKCS_DECODING_ERROR}, + #else + {"PKCS_DECODING_ERROR", 4, 159}, + #endif + #ifdef RSA_R_PSS_SALTLEN_TOO_SMALL + {"PSS_SALTLEN_TOO_SMALL", ERR_LIB_RSA, RSA_R_PSS_SALTLEN_TOO_SMALL}, + #else + {"PSS_SALTLEN_TOO_SMALL", 4, 164}, + #endif + #ifdef RSA_R_PUB_EXPONENT_OUT_OF_RANGE + {"PUB_EXPONENT_OUT_OF_RANGE", ERR_LIB_RSA, RSA_R_PUB_EXPONENT_OUT_OF_RANGE}, + #else + {"PUB_EXPONENT_OUT_OF_RANGE", 4, 178}, + #endif + #ifdef RSA_R_P_NOT_PRIME + {"P_NOT_PRIME", ERR_LIB_RSA, RSA_R_P_NOT_PRIME}, + #else + {"P_NOT_PRIME", 4, 128}, + #endif + #ifdef RSA_R_Q_NOT_PRIME + {"Q_NOT_PRIME", ERR_LIB_RSA, RSA_R_Q_NOT_PRIME}, + #else + {"Q_NOT_PRIME", 4, 129}, + #endif + #ifdef RSA_R_RANDOMNESS_SOURCE_STRENGTH_INSUFFICIENT + {"RANDOMNESS_SOURCE_STRENGTH_INSUFFICIENT", ERR_LIB_RSA, RSA_R_RANDOMNESS_SOURCE_STRENGTH_INSUFFICIENT}, + #else + {"RANDOMNESS_SOURCE_STRENGTH_INSUFFICIENT", 4, 180}, + #endif + #ifdef RSA_R_RSA_OPERATIONS_NOT_SUPPORTED + {"RSA_OPERATIONS_NOT_SUPPORTED", ERR_LIB_RSA, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED}, + #else + {"RSA_OPERATIONS_NOT_SUPPORTED", 4, 130}, + #endif + #ifdef RSA_R_SLEN_CHECK_FAILED + {"SLEN_CHECK_FAILED", ERR_LIB_RSA, RSA_R_SLEN_CHECK_FAILED}, + #else + {"SLEN_CHECK_FAILED", 4, 136}, + #endif + #ifdef RSA_R_SLEN_RECOVERY_FAILED + {"SLEN_RECOVERY_FAILED", ERR_LIB_RSA, RSA_R_SLEN_RECOVERY_FAILED}, + #else + {"SLEN_RECOVERY_FAILED", 4, 135}, + #endif + #ifdef RSA_R_SSLV3_ROLLBACK_ATTACK + {"SSLV3_ROLLBACK_ATTACK", ERR_LIB_RSA, RSA_R_SSLV3_ROLLBACK_ATTACK}, + #else + {"SSLV3_ROLLBACK_ATTACK", 4, 115}, + #endif + #ifdef RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD + {"THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD", ERR_LIB_RSA, RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD}, + #else + {"THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD", 4, 116}, + #endif + #ifdef RSA_R_UNKNOWN_ALGORITHM_TYPE + {"UNKNOWN_ALGORITHM_TYPE", ERR_LIB_RSA, RSA_R_UNKNOWN_ALGORITHM_TYPE}, + #else + {"UNKNOWN_ALGORITHM_TYPE", 4, 117}, + #endif + #ifdef RSA_R_UNKNOWN_DIGEST + {"UNKNOWN_DIGEST", ERR_LIB_RSA, RSA_R_UNKNOWN_DIGEST}, + #else + {"UNKNOWN_DIGEST", 4, 166}, + #endif + #ifdef RSA_R_UNKNOWN_MASK_DIGEST + {"UNKNOWN_MASK_DIGEST", ERR_LIB_RSA, RSA_R_UNKNOWN_MASK_DIGEST}, + #else + {"UNKNOWN_MASK_DIGEST", 4, 151}, + #endif + #ifdef RSA_R_UNKNOWN_PADDING_TYPE + {"UNKNOWN_PADDING_TYPE", ERR_LIB_RSA, RSA_R_UNKNOWN_PADDING_TYPE}, + #else + {"UNKNOWN_PADDING_TYPE", 4, 118}, + #endif + #ifdef RSA_R_UNSUPPORTED_ENCRYPTION_TYPE + {"UNSUPPORTED_ENCRYPTION_TYPE", ERR_LIB_RSA, RSA_R_UNSUPPORTED_ENCRYPTION_TYPE}, + #else + {"UNSUPPORTED_ENCRYPTION_TYPE", 4, 162}, + #endif + #ifdef RSA_R_UNSUPPORTED_LABEL_SOURCE + {"UNSUPPORTED_LABEL_SOURCE", ERR_LIB_RSA, RSA_R_UNSUPPORTED_LABEL_SOURCE}, + #else + {"UNSUPPORTED_LABEL_SOURCE", 4, 163}, + #endif + #ifdef RSA_R_UNSUPPORTED_MASK_ALGORITHM + {"UNSUPPORTED_MASK_ALGORITHM", ERR_LIB_RSA, RSA_R_UNSUPPORTED_MASK_ALGORITHM}, + #else + {"UNSUPPORTED_MASK_ALGORITHM", 4, 153}, + #endif + #ifdef RSA_R_UNSUPPORTED_MASK_PARAMETER + {"UNSUPPORTED_MASK_PARAMETER", ERR_LIB_RSA, RSA_R_UNSUPPORTED_MASK_PARAMETER}, + #else + {"UNSUPPORTED_MASK_PARAMETER", 4, 154}, + #endif + #ifdef RSA_R_UNSUPPORTED_SIGNATURE_TYPE + {"UNSUPPORTED_SIGNATURE_TYPE", ERR_LIB_RSA, RSA_R_UNSUPPORTED_SIGNATURE_TYPE}, + #else + {"UNSUPPORTED_SIGNATURE_TYPE", 4, 155}, + #endif + #ifdef RSA_R_VALUE_MISSING + {"VALUE_MISSING", ERR_LIB_RSA, RSA_R_VALUE_MISSING}, + #else + {"VALUE_MISSING", 4, 147}, + #endif + #ifdef RSA_R_WRONG_SIGNATURE_LENGTH + {"WRONG_SIGNATURE_LENGTH", ERR_LIB_RSA, RSA_R_WRONG_SIGNATURE_LENGTH}, + #else + {"WRONG_SIGNATURE_LENGTH", 4, 119}, + #endif + #ifdef SM2_R_ASN1_ERROR + {"ASN1_ERROR", ERR_LIB_SM2, SM2_R_ASN1_ERROR}, + #else + {"ASN1_ERROR", 53, 100}, + #endif + #ifdef SM2_R_BAD_SIGNATURE + {"BAD_SIGNATURE", ERR_LIB_SM2, SM2_R_BAD_SIGNATURE}, + #else + {"BAD_SIGNATURE", 53, 101}, + #endif + #ifdef SM2_R_BUFFER_TOO_SMALL + {"BUFFER_TOO_SMALL", ERR_LIB_SM2, SM2_R_BUFFER_TOO_SMALL}, + #else + {"BUFFER_TOO_SMALL", 53, 107}, + #endif + #ifdef SM2_R_DIST_ID_TOO_LARGE + {"DIST_ID_TOO_LARGE", ERR_LIB_SM2, SM2_R_DIST_ID_TOO_LARGE}, + #else + {"DIST_ID_TOO_LARGE", 53, 110}, + #endif + #ifdef SM2_R_ID_NOT_SET + {"ID_NOT_SET", ERR_LIB_SM2, SM2_R_ID_NOT_SET}, + #else + {"ID_NOT_SET", 53, 112}, + #endif + #ifdef SM2_R_ID_TOO_LARGE + {"ID_TOO_LARGE", ERR_LIB_SM2, SM2_R_ID_TOO_LARGE}, + #else + {"ID_TOO_LARGE", 53, 111}, + #endif + #ifdef SM2_R_INVALID_CURVE + {"INVALID_CURVE", ERR_LIB_SM2, SM2_R_INVALID_CURVE}, + #else + {"INVALID_CURVE", 53, 108}, + #endif + #ifdef SM2_R_INVALID_DIGEST + {"INVALID_DIGEST", ERR_LIB_SM2, SM2_R_INVALID_DIGEST}, + #else + {"INVALID_DIGEST", 53, 102}, + #endif + #ifdef SM2_R_INVALID_DIGEST_TYPE + {"INVALID_DIGEST_TYPE", ERR_LIB_SM2, SM2_R_INVALID_DIGEST_TYPE}, + #else + {"INVALID_DIGEST_TYPE", 53, 103}, + #endif + #ifdef SM2_R_INVALID_ENCODING + {"INVALID_ENCODING", ERR_LIB_SM2, SM2_R_INVALID_ENCODING}, + #else + {"INVALID_ENCODING", 53, 104}, + #endif + #ifdef SM2_R_INVALID_FIELD + {"INVALID_FIELD", ERR_LIB_SM2, SM2_R_INVALID_FIELD}, + #else + {"INVALID_FIELD", 53, 105}, + #endif + #ifdef SM2_R_INVALID_PRIVATE_KEY + {"INVALID_PRIVATE_KEY", ERR_LIB_SM2, SM2_R_INVALID_PRIVATE_KEY}, + #else + {"INVALID_PRIVATE_KEY", 53, 113}, + #endif + #ifdef SM2_R_NO_PARAMETERS_SET + {"NO_PARAMETERS_SET", ERR_LIB_SM2, SM2_R_NO_PARAMETERS_SET}, + #else + {"NO_PARAMETERS_SET", 53, 109}, + #endif + #ifdef SM2_R_USER_ID_TOO_LARGE + {"USER_ID_TOO_LARGE", ERR_LIB_SM2, SM2_R_USER_ID_TOO_LARGE}, + #else + {"USER_ID_TOO_LARGE", 53, 106}, + #endif + #ifdef SSL_R_APPLICATION_DATA_AFTER_CLOSE_NOTIFY + {"APPLICATION_DATA_AFTER_CLOSE_NOTIFY", ERR_LIB_SSL, SSL_R_APPLICATION_DATA_AFTER_CLOSE_NOTIFY}, + #else + {"APPLICATION_DATA_AFTER_CLOSE_NOTIFY", 20, 291}, + #endif + #ifdef SSL_R_APP_DATA_IN_HANDSHAKE + {"APP_DATA_IN_HANDSHAKE", ERR_LIB_SSL, SSL_R_APP_DATA_IN_HANDSHAKE}, + #else + {"APP_DATA_IN_HANDSHAKE", 20, 100}, + #endif + #ifdef SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT + {"ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT", ERR_LIB_SSL, SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT}, + #else + {"ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT", 20, 272}, + #endif + #ifdef SSL_R_AT_LEAST_TLS_1_2_NEEDED_IN_SUITEB_MODE + {"AT_LEAST_TLS_1_2_NEEDED_IN_SUITEB_MODE", ERR_LIB_SSL, SSL_R_AT_LEAST_TLS_1_2_NEEDED_IN_SUITEB_MODE}, + #else + {"AT_LEAST_TLS_1_2_NEEDED_IN_SUITEB_MODE", 20, 158}, + #endif + #ifdef SSL_R_BAD_CHANGE_CIPHER_SPEC + {"BAD_CHANGE_CIPHER_SPEC", ERR_LIB_SSL, SSL_R_BAD_CHANGE_CIPHER_SPEC}, + #else + {"BAD_CHANGE_CIPHER_SPEC", 20, 103}, + #endif + #ifdef SSL_R_BAD_CIPHER + {"BAD_CIPHER", ERR_LIB_SSL, SSL_R_BAD_CIPHER}, + #else + {"BAD_CIPHER", 20, 186}, + #endif + #ifdef SSL_R_BAD_DATA + {"BAD_DATA", ERR_LIB_SSL, SSL_R_BAD_DATA}, + #else + {"BAD_DATA", 20, 390}, + #endif + #ifdef SSL_R_BAD_DATA_RETURNED_BY_CALLBACK + {"BAD_DATA_RETURNED_BY_CALLBACK", ERR_LIB_SSL, SSL_R_BAD_DATA_RETURNED_BY_CALLBACK}, + #else + {"BAD_DATA_RETURNED_BY_CALLBACK", 20, 106}, + #endif + #ifdef SSL_R_BAD_DECOMPRESSION + {"BAD_DECOMPRESSION", ERR_LIB_SSL, SSL_R_BAD_DECOMPRESSION}, + #else + {"BAD_DECOMPRESSION", 20, 107}, + #endif + #ifdef SSL_R_BAD_DH_VALUE + {"BAD_DH_VALUE", ERR_LIB_SSL, SSL_R_BAD_DH_VALUE}, + #else + {"BAD_DH_VALUE", 20, 102}, + #endif + #ifdef SSL_R_BAD_DIGEST_LENGTH + {"BAD_DIGEST_LENGTH", ERR_LIB_SSL, SSL_R_BAD_DIGEST_LENGTH}, + #else + {"BAD_DIGEST_LENGTH", 20, 111}, + #endif + #ifdef SSL_R_BAD_EARLY_DATA + {"BAD_EARLY_DATA", ERR_LIB_SSL, SSL_R_BAD_EARLY_DATA}, + #else + {"BAD_EARLY_DATA", 20, 233}, + #endif + #ifdef SSL_R_BAD_ECC_CERT + {"BAD_ECC_CERT", ERR_LIB_SSL, SSL_R_BAD_ECC_CERT}, + #else + {"BAD_ECC_CERT", 20, 304}, + #endif + #ifdef SSL_R_BAD_ECPOINT + {"BAD_ECPOINT", ERR_LIB_SSL, SSL_R_BAD_ECPOINT}, + #else + {"BAD_ECPOINT", 20, 306}, + #endif + #ifdef SSL_R_BAD_EXTENSION + {"BAD_EXTENSION", ERR_LIB_SSL, SSL_R_BAD_EXTENSION}, + #else + {"BAD_EXTENSION", 20, 110}, + #endif + #ifdef SSL_R_BAD_HANDSHAKE_LENGTH + {"BAD_HANDSHAKE_LENGTH", ERR_LIB_SSL, SSL_R_BAD_HANDSHAKE_LENGTH}, + #else + {"BAD_HANDSHAKE_LENGTH", 20, 332}, + #endif + #ifdef SSL_R_BAD_HANDSHAKE_STATE + {"BAD_HANDSHAKE_STATE", ERR_LIB_SSL, SSL_R_BAD_HANDSHAKE_STATE}, + #else + {"BAD_HANDSHAKE_STATE", 20, 236}, + #endif + #ifdef SSL_R_BAD_HELLO_REQUEST + {"BAD_HELLO_REQUEST", ERR_LIB_SSL, SSL_R_BAD_HELLO_REQUEST}, + #else + {"BAD_HELLO_REQUEST", 20, 105}, + #endif + #ifdef SSL_R_BAD_HRR_VERSION + {"BAD_HRR_VERSION", ERR_LIB_SSL, SSL_R_BAD_HRR_VERSION}, + #else + {"BAD_HRR_VERSION", 20, 263}, + #endif + #ifdef SSL_R_BAD_KEY_SHARE + {"BAD_KEY_SHARE", ERR_LIB_SSL, SSL_R_BAD_KEY_SHARE}, + #else + {"BAD_KEY_SHARE", 20, 108}, + #endif + #ifdef SSL_R_BAD_KEY_UPDATE + {"BAD_KEY_UPDATE", ERR_LIB_SSL, SSL_R_BAD_KEY_UPDATE}, + #else + {"BAD_KEY_UPDATE", 20, 122}, + #endif + #ifdef SSL_R_BAD_LEGACY_VERSION + {"BAD_LEGACY_VERSION", ERR_LIB_SSL, SSL_R_BAD_LEGACY_VERSION}, + #else + {"BAD_LEGACY_VERSION", 20, 292}, + #endif + #ifdef SSL_R_BAD_LENGTH + {"BAD_LENGTH", ERR_LIB_SSL, SSL_R_BAD_LENGTH}, + #else + {"BAD_LENGTH", 20, 271}, + #endif + #ifdef SSL_R_BAD_PACKET + {"BAD_PACKET", ERR_LIB_SSL, SSL_R_BAD_PACKET}, + #else + {"BAD_PACKET", 20, 240}, + #endif + #ifdef SSL_R_BAD_PACKET_LENGTH + {"BAD_PACKET_LENGTH", ERR_LIB_SSL, SSL_R_BAD_PACKET_LENGTH}, + #else + {"BAD_PACKET_LENGTH", 20, 115}, + #endif + #ifdef SSL_R_BAD_PROTOCOL_VERSION_NUMBER + {"BAD_PROTOCOL_VERSION_NUMBER", ERR_LIB_SSL, SSL_R_BAD_PROTOCOL_VERSION_NUMBER}, + #else + {"BAD_PROTOCOL_VERSION_NUMBER", 20, 116}, + #endif + #ifdef SSL_R_BAD_PSK + {"BAD_PSK", ERR_LIB_SSL, SSL_R_BAD_PSK}, + #else + {"BAD_PSK", 20, 219}, + #endif + #ifdef SSL_R_BAD_PSK_IDENTITY + {"BAD_PSK_IDENTITY", ERR_LIB_SSL, SSL_R_BAD_PSK_IDENTITY}, + #else + {"BAD_PSK_IDENTITY", 20, 114}, + #endif + #ifdef SSL_R_BAD_RECORD_TYPE + {"BAD_RECORD_TYPE", ERR_LIB_SSL, SSL_R_BAD_RECORD_TYPE}, + #else + {"BAD_RECORD_TYPE", 20, 443}, + #endif + #ifdef SSL_R_BAD_RSA_ENCRYPT + {"BAD_RSA_ENCRYPT", ERR_LIB_SSL, SSL_R_BAD_RSA_ENCRYPT}, + #else + {"BAD_RSA_ENCRYPT", 20, 119}, + #endif + #ifdef SSL_R_BAD_SIGNATURE + {"BAD_SIGNATURE", ERR_LIB_SSL, SSL_R_BAD_SIGNATURE}, + #else + {"BAD_SIGNATURE", 20, 123}, + #endif + #ifdef SSL_R_BAD_SRP_A_LENGTH + {"BAD_SRP_A_LENGTH", ERR_LIB_SSL, SSL_R_BAD_SRP_A_LENGTH}, + #else + {"BAD_SRP_A_LENGTH", 20, 347}, + #endif + #ifdef SSL_R_BAD_SRP_PARAMETERS + {"BAD_SRP_PARAMETERS", ERR_LIB_SSL, SSL_R_BAD_SRP_PARAMETERS}, + #else + {"BAD_SRP_PARAMETERS", 20, 371}, + #endif + #ifdef SSL_R_BAD_SRTP_MKI_VALUE + {"BAD_SRTP_MKI_VALUE", ERR_LIB_SSL, SSL_R_BAD_SRTP_MKI_VALUE}, + #else + {"BAD_SRTP_MKI_VALUE", 20, 352}, + #endif + #ifdef SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST + {"BAD_SRTP_PROTECTION_PROFILE_LIST", ERR_LIB_SSL, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST}, + #else + {"BAD_SRTP_PROTECTION_PROFILE_LIST", 20, 353}, + #endif + #ifdef SSL_R_BAD_SSL_FILETYPE + {"BAD_SSL_FILETYPE", ERR_LIB_SSL, SSL_R_BAD_SSL_FILETYPE}, + #else + {"BAD_SSL_FILETYPE", 20, 124}, + #endif + #ifdef SSL_R_BAD_VALUE + {"BAD_VALUE", ERR_LIB_SSL, SSL_R_BAD_VALUE}, + #else + {"BAD_VALUE", 20, 384}, + #endif + #ifdef SSL_R_BAD_WRITE_RETRY + {"BAD_WRITE_RETRY", ERR_LIB_SSL, SSL_R_BAD_WRITE_RETRY}, + #else + {"BAD_WRITE_RETRY", 20, 127}, + #endif + #ifdef SSL_R_BINDER_DOES_NOT_VERIFY + {"BINDER_DOES_NOT_VERIFY", ERR_LIB_SSL, SSL_R_BINDER_DOES_NOT_VERIFY}, + #else + {"BINDER_DOES_NOT_VERIFY", 20, 253}, + #endif + #ifdef SSL_R_BIO_NOT_SET + {"BIO_NOT_SET", ERR_LIB_SSL, SSL_R_BIO_NOT_SET}, + #else + {"BIO_NOT_SET", 20, 128}, + #endif + #ifdef SSL_R_BLOCK_CIPHER_PAD_IS_WRONG + {"BLOCK_CIPHER_PAD_IS_WRONG", ERR_LIB_SSL, SSL_R_BLOCK_CIPHER_PAD_IS_WRONG}, + #else + {"BLOCK_CIPHER_PAD_IS_WRONG", 20, 129}, + #endif + #ifdef SSL_R_BN_LIB + {"BN_LIB", ERR_LIB_SSL, SSL_R_BN_LIB}, + #else + {"BN_LIB", 20, 130}, + #endif + #ifdef SSL_R_CALLBACK_FAILED + {"CALLBACK_FAILED", ERR_LIB_SSL, SSL_R_CALLBACK_FAILED}, + #else + {"CALLBACK_FAILED", 20, 234}, + #endif + #ifdef SSL_R_CANNOT_CHANGE_CIPHER + {"CANNOT_CHANGE_CIPHER", ERR_LIB_SSL, SSL_R_CANNOT_CHANGE_CIPHER}, + #else + {"CANNOT_CHANGE_CIPHER", 20, 109}, + #endif + #ifdef SSL_R_CANNOT_GET_GROUP_NAME + {"CANNOT_GET_GROUP_NAME", ERR_LIB_SSL, SSL_R_CANNOT_GET_GROUP_NAME}, + #else + {"CANNOT_GET_GROUP_NAME", 20, 299}, + #endif + #ifdef SSL_R_CA_DN_LENGTH_MISMATCH + {"CA_DN_LENGTH_MISMATCH", ERR_LIB_SSL, SSL_R_CA_DN_LENGTH_MISMATCH}, + #else + {"CA_DN_LENGTH_MISMATCH", 20, 131}, + #endif + #ifdef SSL_R_CA_KEY_TOO_SMALL + {"CA_KEY_TOO_SMALL", ERR_LIB_SSL, SSL_R_CA_KEY_TOO_SMALL}, + #else + {"CA_KEY_TOO_SMALL", 20, 397}, + #endif + #ifdef SSL_R_CA_MD_TOO_WEAK + {"CA_MD_TOO_WEAK", ERR_LIB_SSL, SSL_R_CA_MD_TOO_WEAK}, + #else + {"CA_MD_TOO_WEAK", 20, 398}, + #endif + #ifdef SSL_R_CCS_RECEIVED_EARLY + {"CCS_RECEIVED_EARLY", ERR_LIB_SSL, SSL_R_CCS_RECEIVED_EARLY}, + #else + {"CCS_RECEIVED_EARLY", 20, 133}, + #endif + #ifdef SSL_R_CERTIFICATE_VERIFY_FAILED + {"CERTIFICATE_VERIFY_FAILED", ERR_LIB_SSL, SSL_R_CERTIFICATE_VERIFY_FAILED}, + #else + {"CERTIFICATE_VERIFY_FAILED", 20, 134}, + #endif + #ifdef SSL_R_CERT_CB_ERROR + {"CERT_CB_ERROR", ERR_LIB_SSL, SSL_R_CERT_CB_ERROR}, + #else + {"CERT_CB_ERROR", 20, 377}, + #endif + #ifdef SSL_R_CERT_LENGTH_MISMATCH + {"CERT_LENGTH_MISMATCH", ERR_LIB_SSL, SSL_R_CERT_LENGTH_MISMATCH}, + #else + {"CERT_LENGTH_MISMATCH", 20, 135}, + #endif + #ifdef SSL_R_CIPHERSUITE_DIGEST_HAS_CHANGED + {"CIPHERSUITE_DIGEST_HAS_CHANGED", ERR_LIB_SSL, SSL_R_CIPHERSUITE_DIGEST_HAS_CHANGED}, + #else + {"CIPHERSUITE_DIGEST_HAS_CHANGED", 20, 218}, + #endif + #ifdef SSL_R_CIPHER_CODE_WRONG_LENGTH + {"CIPHER_CODE_WRONG_LENGTH", ERR_LIB_SSL, SSL_R_CIPHER_CODE_WRONG_LENGTH}, + #else + {"CIPHER_CODE_WRONG_LENGTH", 20, 137}, + #endif + #ifdef SSL_R_CLIENTHELLO_TLSEXT + {"CLIENTHELLO_TLSEXT", ERR_LIB_SSL, SSL_R_CLIENTHELLO_TLSEXT}, + #else + {"CLIENTHELLO_TLSEXT", 20, 226}, + #endif + #ifdef SSL_R_COMPRESSED_LENGTH_TOO_LONG + {"COMPRESSED_LENGTH_TOO_LONG", ERR_LIB_SSL, SSL_R_COMPRESSED_LENGTH_TOO_LONG}, + #else + {"COMPRESSED_LENGTH_TOO_LONG", 20, 140}, + #endif + #ifdef SSL_R_COMPRESSION_DISABLED + {"COMPRESSION_DISABLED", ERR_LIB_SSL, SSL_R_COMPRESSION_DISABLED}, + #else + {"COMPRESSION_DISABLED", 20, 343}, + #endif + #ifdef SSL_R_COMPRESSION_FAILURE + {"COMPRESSION_FAILURE", ERR_LIB_SSL, SSL_R_COMPRESSION_FAILURE}, + #else + {"COMPRESSION_FAILURE", 20, 141}, + #endif + #ifdef SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE + {"COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE", ERR_LIB_SSL, SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE}, + #else + {"COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE", 20, 307}, + #endif + #ifdef SSL_R_COMPRESSION_LIBRARY_ERROR + {"COMPRESSION_LIBRARY_ERROR", ERR_LIB_SSL, SSL_R_COMPRESSION_LIBRARY_ERROR}, + #else + {"COMPRESSION_LIBRARY_ERROR", 20, 142}, + #endif + #ifdef SSL_R_CONNECTION_TYPE_NOT_SET + {"CONNECTION_TYPE_NOT_SET", ERR_LIB_SSL, SSL_R_CONNECTION_TYPE_NOT_SET}, + #else + {"CONNECTION_TYPE_NOT_SET", 20, 144}, + #endif + #ifdef SSL_R_CONTEXT_NOT_DANE_ENABLED + {"CONTEXT_NOT_DANE_ENABLED", ERR_LIB_SSL, SSL_R_CONTEXT_NOT_DANE_ENABLED}, + #else + {"CONTEXT_NOT_DANE_ENABLED", 20, 167}, + #endif + #ifdef SSL_R_COOKIE_GEN_CALLBACK_FAILURE + {"COOKIE_GEN_CALLBACK_FAILURE", ERR_LIB_SSL, SSL_R_COOKIE_GEN_CALLBACK_FAILURE}, + #else + {"COOKIE_GEN_CALLBACK_FAILURE", 20, 400}, + #endif + #ifdef SSL_R_COOKIE_MISMATCH + {"COOKIE_MISMATCH", ERR_LIB_SSL, SSL_R_COOKIE_MISMATCH}, + #else + {"COOKIE_MISMATCH", 20, 308}, + #endif + #ifdef SSL_R_COPY_PARAMETERS_FAILED + {"COPY_PARAMETERS_FAILED", ERR_LIB_SSL, SSL_R_COPY_PARAMETERS_FAILED}, + #else + {"COPY_PARAMETERS_FAILED", 20, 296}, + #endif + #ifdef SSL_R_CUSTOM_EXT_HANDLER_ALREADY_INSTALLED + {"CUSTOM_EXT_HANDLER_ALREADY_INSTALLED", ERR_LIB_SSL, SSL_R_CUSTOM_EXT_HANDLER_ALREADY_INSTALLED}, + #else + {"CUSTOM_EXT_HANDLER_ALREADY_INSTALLED", 20, 206}, + #endif + #ifdef SSL_R_DANE_ALREADY_ENABLED + {"DANE_ALREADY_ENABLED", ERR_LIB_SSL, SSL_R_DANE_ALREADY_ENABLED}, + #else + {"DANE_ALREADY_ENABLED", 20, 172}, + #endif + #ifdef SSL_R_DANE_CANNOT_OVERRIDE_MTYPE_FULL + {"DANE_CANNOT_OVERRIDE_MTYPE_FULL", ERR_LIB_SSL, SSL_R_DANE_CANNOT_OVERRIDE_MTYPE_FULL}, + #else + {"DANE_CANNOT_OVERRIDE_MTYPE_FULL", 20, 173}, + #endif + #ifdef SSL_R_DANE_NOT_ENABLED + {"DANE_NOT_ENABLED", ERR_LIB_SSL, SSL_R_DANE_NOT_ENABLED}, + #else + {"DANE_NOT_ENABLED", 20, 175}, + #endif + #ifdef SSL_R_DANE_TLSA_BAD_CERTIFICATE + {"DANE_TLSA_BAD_CERTIFICATE", ERR_LIB_SSL, SSL_R_DANE_TLSA_BAD_CERTIFICATE}, + #else + {"DANE_TLSA_BAD_CERTIFICATE", 20, 180}, + #endif + #ifdef SSL_R_DANE_TLSA_BAD_CERTIFICATE_USAGE + {"DANE_TLSA_BAD_CERTIFICATE_USAGE", ERR_LIB_SSL, SSL_R_DANE_TLSA_BAD_CERTIFICATE_USAGE}, + #else + {"DANE_TLSA_BAD_CERTIFICATE_USAGE", 20, 184}, + #endif + #ifdef SSL_R_DANE_TLSA_BAD_DATA_LENGTH + {"DANE_TLSA_BAD_DATA_LENGTH", ERR_LIB_SSL, SSL_R_DANE_TLSA_BAD_DATA_LENGTH}, + #else + {"DANE_TLSA_BAD_DATA_LENGTH", 20, 189}, + #endif + #ifdef SSL_R_DANE_TLSA_BAD_DIGEST_LENGTH + {"DANE_TLSA_BAD_DIGEST_LENGTH", ERR_LIB_SSL, SSL_R_DANE_TLSA_BAD_DIGEST_LENGTH}, + #else + {"DANE_TLSA_BAD_DIGEST_LENGTH", 20, 192}, + #endif + #ifdef SSL_R_DANE_TLSA_BAD_MATCHING_TYPE + {"DANE_TLSA_BAD_MATCHING_TYPE", ERR_LIB_SSL, SSL_R_DANE_TLSA_BAD_MATCHING_TYPE}, + #else + {"DANE_TLSA_BAD_MATCHING_TYPE", 20, 200}, + #endif + #ifdef SSL_R_DANE_TLSA_BAD_PUBLIC_KEY + {"DANE_TLSA_BAD_PUBLIC_KEY", ERR_LIB_SSL, SSL_R_DANE_TLSA_BAD_PUBLIC_KEY}, + #else + {"DANE_TLSA_BAD_PUBLIC_KEY", 20, 201}, + #endif + #ifdef SSL_R_DANE_TLSA_BAD_SELECTOR + {"DANE_TLSA_BAD_SELECTOR", ERR_LIB_SSL, SSL_R_DANE_TLSA_BAD_SELECTOR}, + #else + {"DANE_TLSA_BAD_SELECTOR", 20, 202}, + #endif + #ifdef SSL_R_DANE_TLSA_NULL_DATA + {"DANE_TLSA_NULL_DATA", ERR_LIB_SSL, SSL_R_DANE_TLSA_NULL_DATA}, + #else + {"DANE_TLSA_NULL_DATA", 20, 203}, + #endif + #ifdef SSL_R_DATA_BETWEEN_CCS_AND_FINISHED + {"DATA_BETWEEN_CCS_AND_FINISHED", ERR_LIB_SSL, SSL_R_DATA_BETWEEN_CCS_AND_FINISHED}, + #else + {"DATA_BETWEEN_CCS_AND_FINISHED", 20, 145}, + #endif + #ifdef SSL_R_DATA_LENGTH_TOO_LONG + {"DATA_LENGTH_TOO_LONG", ERR_LIB_SSL, SSL_R_DATA_LENGTH_TOO_LONG}, + #else + {"DATA_LENGTH_TOO_LONG", 20, 146}, + #endif + #ifdef SSL_R_DECRYPTION_FAILED + {"DECRYPTION_FAILED", ERR_LIB_SSL, SSL_R_DECRYPTION_FAILED}, + #else + {"DECRYPTION_FAILED", 20, 147}, + #endif + #ifdef SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC + {"DECRYPTION_FAILED_OR_BAD_RECORD_MAC", ERR_LIB_SSL, SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC}, + #else + {"DECRYPTION_FAILED_OR_BAD_RECORD_MAC", 20, 281}, + #endif + #ifdef SSL_R_DH_KEY_TOO_SMALL + {"DH_KEY_TOO_SMALL", ERR_LIB_SSL, SSL_R_DH_KEY_TOO_SMALL}, + #else + {"DH_KEY_TOO_SMALL", 20, 394}, + #endif + #ifdef SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG + {"DH_PUBLIC_VALUE_LENGTH_IS_WRONG", ERR_LIB_SSL, SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG}, + #else + {"DH_PUBLIC_VALUE_LENGTH_IS_WRONG", 20, 148}, + #endif + #ifdef SSL_R_DIGEST_CHECK_FAILED + {"DIGEST_CHECK_FAILED", ERR_LIB_SSL, SSL_R_DIGEST_CHECK_FAILED}, + #else + {"DIGEST_CHECK_FAILED", 20, 149}, + #endif + #ifdef SSL_R_DTLS_MESSAGE_TOO_BIG + {"DTLS_MESSAGE_TOO_BIG", ERR_LIB_SSL, SSL_R_DTLS_MESSAGE_TOO_BIG}, + #else + {"DTLS_MESSAGE_TOO_BIG", 20, 334}, + #endif + #ifdef SSL_R_DUPLICATE_COMPRESSION_ID + {"DUPLICATE_COMPRESSION_ID", ERR_LIB_SSL, SSL_R_DUPLICATE_COMPRESSION_ID}, + #else + {"DUPLICATE_COMPRESSION_ID", 20, 309}, + #endif + #ifdef SSL_R_ECC_CERT_NOT_FOR_SIGNING + {"ECC_CERT_NOT_FOR_SIGNING", ERR_LIB_SSL, SSL_R_ECC_CERT_NOT_FOR_SIGNING}, + #else + {"ECC_CERT_NOT_FOR_SIGNING", 20, 318}, + #endif + #ifdef SSL_R_ECDH_REQUIRED_FOR_SUITEB_MODE + {"ECDH_REQUIRED_FOR_SUITEB_MODE", ERR_LIB_SSL, SSL_R_ECDH_REQUIRED_FOR_SUITEB_MODE}, + #else + {"ECDH_REQUIRED_FOR_SUITEB_MODE", 20, 374}, + #endif + #ifdef SSL_R_EE_KEY_TOO_SMALL + {"EE_KEY_TOO_SMALL", ERR_LIB_SSL, SSL_R_EE_KEY_TOO_SMALL}, + #else + {"EE_KEY_TOO_SMALL", 20, 399}, + #endif + #ifdef SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST + {"EMPTY_SRTP_PROTECTION_PROFILE_LIST", ERR_LIB_SSL, SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST}, + #else + {"EMPTY_SRTP_PROTECTION_PROFILE_LIST", 20, 354}, + #endif + #ifdef SSL_R_ENCRYPTED_LENGTH_TOO_LONG + {"ENCRYPTED_LENGTH_TOO_LONG", ERR_LIB_SSL, SSL_R_ENCRYPTED_LENGTH_TOO_LONG}, + #else + {"ENCRYPTED_LENGTH_TOO_LONG", 20, 150}, + #endif + #ifdef SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST + {"ERROR_IN_RECEIVED_CIPHER_LIST", ERR_LIB_SSL, SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST}, + #else + {"ERROR_IN_RECEIVED_CIPHER_LIST", 20, 151}, + #endif + #ifdef SSL_R_ERROR_SETTING_TLSA_BASE_DOMAIN + {"ERROR_SETTING_TLSA_BASE_DOMAIN", ERR_LIB_SSL, SSL_R_ERROR_SETTING_TLSA_BASE_DOMAIN}, + #else + {"ERROR_SETTING_TLSA_BASE_DOMAIN", 20, 204}, + #endif + #ifdef SSL_R_EXCEEDS_MAX_FRAGMENT_SIZE + {"EXCEEDS_MAX_FRAGMENT_SIZE", ERR_LIB_SSL, SSL_R_EXCEEDS_MAX_FRAGMENT_SIZE}, + #else + {"EXCEEDS_MAX_FRAGMENT_SIZE", 20, 194}, + #endif + #ifdef SSL_R_EXCESSIVE_MESSAGE_SIZE + {"EXCESSIVE_MESSAGE_SIZE", ERR_LIB_SSL, SSL_R_EXCESSIVE_MESSAGE_SIZE}, + #else + {"EXCESSIVE_MESSAGE_SIZE", 20, 152}, + #endif + #ifdef SSL_R_EXTENSION_NOT_RECEIVED + {"EXTENSION_NOT_RECEIVED", ERR_LIB_SSL, SSL_R_EXTENSION_NOT_RECEIVED}, + #else + {"EXTENSION_NOT_RECEIVED", 20, 279}, + #endif + #ifdef SSL_R_EXTRA_DATA_IN_MESSAGE + {"EXTRA_DATA_IN_MESSAGE", ERR_LIB_SSL, SSL_R_EXTRA_DATA_IN_MESSAGE}, + #else + {"EXTRA_DATA_IN_MESSAGE", 20, 153}, + #endif + #ifdef SSL_R_EXT_LENGTH_MISMATCH + {"EXT_LENGTH_MISMATCH", ERR_LIB_SSL, SSL_R_EXT_LENGTH_MISMATCH}, + #else + {"EXT_LENGTH_MISMATCH", 20, 163}, + #endif + #ifdef SSL_R_FAILED_TO_INIT_ASYNC + {"FAILED_TO_INIT_ASYNC", ERR_LIB_SSL, SSL_R_FAILED_TO_INIT_ASYNC}, + #else + {"FAILED_TO_INIT_ASYNC", 20, 405}, + #endif + #ifdef SSL_R_FRAGMENTED_CLIENT_HELLO + {"FRAGMENTED_CLIENT_HELLO", ERR_LIB_SSL, SSL_R_FRAGMENTED_CLIENT_HELLO}, + #else + {"FRAGMENTED_CLIENT_HELLO", 20, 401}, + #endif + #ifdef SSL_R_GOT_A_FIN_BEFORE_A_CCS + {"GOT_A_FIN_BEFORE_A_CCS", ERR_LIB_SSL, SSL_R_GOT_A_FIN_BEFORE_A_CCS}, + #else + {"GOT_A_FIN_BEFORE_A_CCS", 20, 154}, + #endif + #ifdef SSL_R_HTTPS_PROXY_REQUEST + {"HTTPS_PROXY_REQUEST", ERR_LIB_SSL, SSL_R_HTTPS_PROXY_REQUEST}, + #else + {"HTTPS_PROXY_REQUEST", 20, 155}, + #endif + #ifdef SSL_R_HTTP_REQUEST + {"HTTP_REQUEST", ERR_LIB_SSL, SSL_R_HTTP_REQUEST}, + #else + {"HTTP_REQUEST", 20, 156}, + #endif + #ifdef SSL_R_ILLEGAL_POINT_COMPRESSION + {"ILLEGAL_POINT_COMPRESSION", ERR_LIB_SSL, SSL_R_ILLEGAL_POINT_COMPRESSION}, + #else + {"ILLEGAL_POINT_COMPRESSION", 20, 162}, + #endif + #ifdef SSL_R_ILLEGAL_SUITEB_DIGEST + {"ILLEGAL_SUITEB_DIGEST", ERR_LIB_SSL, SSL_R_ILLEGAL_SUITEB_DIGEST}, + #else + {"ILLEGAL_SUITEB_DIGEST", 20, 380}, + #endif + #ifdef SSL_R_INAPPROPRIATE_FALLBACK + {"INAPPROPRIATE_FALLBACK", ERR_LIB_SSL, SSL_R_INAPPROPRIATE_FALLBACK}, + #else + {"INAPPROPRIATE_FALLBACK", 20, 373}, + #endif + #ifdef SSL_R_INCONSISTENT_COMPRESSION + {"INCONSISTENT_COMPRESSION", ERR_LIB_SSL, SSL_R_INCONSISTENT_COMPRESSION}, + #else + {"INCONSISTENT_COMPRESSION", 20, 340}, + #endif + #ifdef SSL_R_INCONSISTENT_EARLY_DATA_ALPN + {"INCONSISTENT_EARLY_DATA_ALPN", ERR_LIB_SSL, SSL_R_INCONSISTENT_EARLY_DATA_ALPN}, + #else + {"INCONSISTENT_EARLY_DATA_ALPN", 20, 222}, + #endif + #ifdef SSL_R_INCONSISTENT_EARLY_DATA_SNI + {"INCONSISTENT_EARLY_DATA_SNI", ERR_LIB_SSL, SSL_R_INCONSISTENT_EARLY_DATA_SNI}, + #else + {"INCONSISTENT_EARLY_DATA_SNI", 20, 231}, + #endif + #ifdef SSL_R_INCONSISTENT_EXTMS + {"INCONSISTENT_EXTMS", ERR_LIB_SSL, SSL_R_INCONSISTENT_EXTMS}, + #else + {"INCONSISTENT_EXTMS", 20, 104}, + #endif + #ifdef SSL_R_INSUFFICIENT_SECURITY + {"INSUFFICIENT_SECURITY", ERR_LIB_SSL, SSL_R_INSUFFICIENT_SECURITY}, + #else + {"INSUFFICIENT_SECURITY", 20, 241}, + #endif + #ifdef SSL_R_INVALID_ALERT + {"INVALID_ALERT", ERR_LIB_SSL, SSL_R_INVALID_ALERT}, + #else + {"INVALID_ALERT", 20, 205}, + #endif + #ifdef SSL_R_INVALID_CCS_MESSAGE + {"INVALID_CCS_MESSAGE", ERR_LIB_SSL, SSL_R_INVALID_CCS_MESSAGE}, + #else + {"INVALID_CCS_MESSAGE", 20, 260}, + #endif + #ifdef SSL_R_INVALID_CERTIFICATE_OR_ALG + {"INVALID_CERTIFICATE_OR_ALG", ERR_LIB_SSL, SSL_R_INVALID_CERTIFICATE_OR_ALG}, + #else + {"INVALID_CERTIFICATE_OR_ALG", 20, 238}, + #endif + #ifdef SSL_R_INVALID_COMMAND + {"INVALID_COMMAND", ERR_LIB_SSL, SSL_R_INVALID_COMMAND}, + #else + {"INVALID_COMMAND", 20, 280}, + #endif + #ifdef SSL_R_INVALID_COMPRESSION_ALGORITHM + {"INVALID_COMPRESSION_ALGORITHM", ERR_LIB_SSL, SSL_R_INVALID_COMPRESSION_ALGORITHM}, + #else + {"INVALID_COMPRESSION_ALGORITHM", 20, 341}, + #endif + #ifdef SSL_R_INVALID_CONFIG + {"INVALID_CONFIG", ERR_LIB_SSL, SSL_R_INVALID_CONFIG}, + #else + {"INVALID_CONFIG", 20, 283}, + #endif + #ifdef SSL_R_INVALID_CONFIGURATION_NAME + {"INVALID_CONFIGURATION_NAME", ERR_LIB_SSL, SSL_R_INVALID_CONFIGURATION_NAME}, + #else + {"INVALID_CONFIGURATION_NAME", 20, 113}, + #endif + #ifdef SSL_R_INVALID_CONTEXT + {"INVALID_CONTEXT", ERR_LIB_SSL, SSL_R_INVALID_CONTEXT}, + #else + {"INVALID_CONTEXT", 20, 282}, + #endif + #ifdef SSL_R_INVALID_CT_VALIDATION_TYPE + {"INVALID_CT_VALIDATION_TYPE", ERR_LIB_SSL, SSL_R_INVALID_CT_VALIDATION_TYPE}, + #else + {"INVALID_CT_VALIDATION_TYPE", 20, 212}, + #endif + #ifdef SSL_R_INVALID_KEY_UPDATE_TYPE + {"INVALID_KEY_UPDATE_TYPE", ERR_LIB_SSL, SSL_R_INVALID_KEY_UPDATE_TYPE}, + #else + {"INVALID_KEY_UPDATE_TYPE", 20, 120}, + #endif + #ifdef SSL_R_INVALID_MAX_EARLY_DATA + {"INVALID_MAX_EARLY_DATA", ERR_LIB_SSL, SSL_R_INVALID_MAX_EARLY_DATA}, + #else + {"INVALID_MAX_EARLY_DATA", 20, 174}, + #endif + #ifdef SSL_R_INVALID_NULL_CMD_NAME + {"INVALID_NULL_CMD_NAME", ERR_LIB_SSL, SSL_R_INVALID_NULL_CMD_NAME}, + #else + {"INVALID_NULL_CMD_NAME", 20, 385}, + #endif + #ifdef SSL_R_INVALID_SEQUENCE_NUMBER + {"INVALID_SEQUENCE_NUMBER", ERR_LIB_SSL, SSL_R_INVALID_SEQUENCE_NUMBER}, + #else + {"INVALID_SEQUENCE_NUMBER", 20, 402}, + #endif + #ifdef SSL_R_INVALID_SERVERINFO_DATA + {"INVALID_SERVERINFO_DATA", ERR_LIB_SSL, SSL_R_INVALID_SERVERINFO_DATA}, + #else + {"INVALID_SERVERINFO_DATA", 20, 388}, + #endif + #ifdef SSL_R_INVALID_SESSION_ID + {"INVALID_SESSION_ID", ERR_LIB_SSL, SSL_R_INVALID_SESSION_ID}, + #else + {"INVALID_SESSION_ID", 20, 999}, + #endif + #ifdef SSL_R_INVALID_SRP_USERNAME + {"INVALID_SRP_USERNAME", ERR_LIB_SSL, SSL_R_INVALID_SRP_USERNAME}, + #else + {"INVALID_SRP_USERNAME", 20, 357}, + #endif + #ifdef SSL_R_INVALID_STATUS_RESPONSE + {"INVALID_STATUS_RESPONSE", ERR_LIB_SSL, SSL_R_INVALID_STATUS_RESPONSE}, + #else + {"INVALID_STATUS_RESPONSE", 20, 328}, + #endif + #ifdef SSL_R_INVALID_TICKET_KEYS_LENGTH + {"INVALID_TICKET_KEYS_LENGTH", ERR_LIB_SSL, SSL_R_INVALID_TICKET_KEYS_LENGTH}, + #else + {"INVALID_TICKET_KEYS_LENGTH", 20, 325}, + #endif + #ifdef SSL_R_LEGACY_SIGALG_DISALLOWED_OR_UNSUPPORTED + {"LEGACY_SIGALG_DISALLOWED_OR_UNSUPPORTED", ERR_LIB_SSL, SSL_R_LEGACY_SIGALG_DISALLOWED_OR_UNSUPPORTED}, + #else + {"LEGACY_SIGALG_DISALLOWED_OR_UNSUPPORTED", 20, 333}, + #endif + #ifdef SSL_R_LENGTH_MISMATCH + {"LENGTH_MISMATCH", ERR_LIB_SSL, SSL_R_LENGTH_MISMATCH}, + #else + {"LENGTH_MISMATCH", 20, 159}, + #endif + #ifdef SSL_R_LENGTH_TOO_LONG + {"LENGTH_TOO_LONG", ERR_LIB_SSL, SSL_R_LENGTH_TOO_LONG}, + #else + {"LENGTH_TOO_LONG", 20, 404}, + #endif + #ifdef SSL_R_LENGTH_TOO_SHORT + {"LENGTH_TOO_SHORT", ERR_LIB_SSL, SSL_R_LENGTH_TOO_SHORT}, + #else + {"LENGTH_TOO_SHORT", 20, 160}, + #endif + #ifdef SSL_R_LIBRARY_BUG + {"LIBRARY_BUG", ERR_LIB_SSL, SSL_R_LIBRARY_BUG}, + #else + {"LIBRARY_BUG", 20, 274}, + #endif + #ifdef SSL_R_LIBRARY_HAS_NO_CIPHERS + {"LIBRARY_HAS_NO_CIPHERS", ERR_LIB_SSL, SSL_R_LIBRARY_HAS_NO_CIPHERS}, + #else + {"LIBRARY_HAS_NO_CIPHERS", 20, 161}, + #endif + #ifdef SSL_R_MISSING_DSA_SIGNING_CERT + {"MISSING_DSA_SIGNING_CERT", ERR_LIB_SSL, SSL_R_MISSING_DSA_SIGNING_CERT}, + #else + {"MISSING_DSA_SIGNING_CERT", 20, 165}, + #endif + #ifdef SSL_R_MISSING_ECDSA_SIGNING_CERT + {"MISSING_ECDSA_SIGNING_CERT", ERR_LIB_SSL, SSL_R_MISSING_ECDSA_SIGNING_CERT}, + #else + {"MISSING_ECDSA_SIGNING_CERT", 20, 381}, + #endif + #ifdef SSL_R_MISSING_FATAL + {"MISSING_FATAL", ERR_LIB_SSL, SSL_R_MISSING_FATAL}, + #else + {"MISSING_FATAL", 20, 256}, + #endif + #ifdef SSL_R_MISSING_PARAMETERS + {"MISSING_PARAMETERS", ERR_LIB_SSL, SSL_R_MISSING_PARAMETERS}, + #else + {"MISSING_PARAMETERS", 20, 290}, + #endif + #ifdef SSL_R_MISSING_PSK_KEX_MODES_EXTENSION + {"MISSING_PSK_KEX_MODES_EXTENSION", ERR_LIB_SSL, SSL_R_MISSING_PSK_KEX_MODES_EXTENSION}, + #else + {"MISSING_PSK_KEX_MODES_EXTENSION", 20, 310}, + #endif + #ifdef SSL_R_MISSING_RSA_CERTIFICATE + {"MISSING_RSA_CERTIFICATE", ERR_LIB_SSL, SSL_R_MISSING_RSA_CERTIFICATE}, + #else + {"MISSING_RSA_CERTIFICATE", 20, 168}, + #endif + #ifdef SSL_R_MISSING_RSA_ENCRYPTING_CERT + {"MISSING_RSA_ENCRYPTING_CERT", ERR_LIB_SSL, SSL_R_MISSING_RSA_ENCRYPTING_CERT}, + #else + {"MISSING_RSA_ENCRYPTING_CERT", 20, 169}, + #endif + #ifdef SSL_R_MISSING_RSA_SIGNING_CERT + {"MISSING_RSA_SIGNING_CERT", ERR_LIB_SSL, SSL_R_MISSING_RSA_SIGNING_CERT}, + #else + {"MISSING_RSA_SIGNING_CERT", 20, 170}, + #endif + #ifdef SSL_R_MISSING_SIGALGS_EXTENSION + {"MISSING_SIGALGS_EXTENSION", ERR_LIB_SSL, SSL_R_MISSING_SIGALGS_EXTENSION}, + #else + {"MISSING_SIGALGS_EXTENSION", 20, 112}, + #endif + #ifdef SSL_R_MISSING_SIGNING_CERT + {"MISSING_SIGNING_CERT", ERR_LIB_SSL, SSL_R_MISSING_SIGNING_CERT}, + #else + {"MISSING_SIGNING_CERT", 20, 221}, + #endif + #ifdef SSL_R_MISSING_SRP_PARAM + {"MISSING_SRP_PARAM", ERR_LIB_SSL, SSL_R_MISSING_SRP_PARAM}, + #else + {"MISSING_SRP_PARAM", 20, 358}, + #endif + #ifdef SSL_R_MISSING_SUPPORTED_GROUPS_EXTENSION + {"MISSING_SUPPORTED_GROUPS_EXTENSION", ERR_LIB_SSL, SSL_R_MISSING_SUPPORTED_GROUPS_EXTENSION}, + #else + {"MISSING_SUPPORTED_GROUPS_EXTENSION", 20, 209}, + #endif + #ifdef SSL_R_MISSING_TMP_DH_KEY + {"MISSING_TMP_DH_KEY", ERR_LIB_SSL, SSL_R_MISSING_TMP_DH_KEY}, + #else + {"MISSING_TMP_DH_KEY", 20, 171}, + #endif + #ifdef SSL_R_MISSING_TMP_ECDH_KEY + {"MISSING_TMP_ECDH_KEY", ERR_LIB_SSL, SSL_R_MISSING_TMP_ECDH_KEY}, + #else + {"MISSING_TMP_ECDH_KEY", 20, 311}, + #endif + #ifdef SSL_R_MIXED_HANDSHAKE_AND_NON_HANDSHAKE_DATA + {"MIXED_HANDSHAKE_AND_NON_HANDSHAKE_DATA", ERR_LIB_SSL, SSL_R_MIXED_HANDSHAKE_AND_NON_HANDSHAKE_DATA}, + #else + {"MIXED_HANDSHAKE_AND_NON_HANDSHAKE_DATA", 20, 293}, + #endif + #ifdef SSL_R_NOT_ON_RECORD_BOUNDARY + {"NOT_ON_RECORD_BOUNDARY", ERR_LIB_SSL, SSL_R_NOT_ON_RECORD_BOUNDARY}, + #else + {"NOT_ON_RECORD_BOUNDARY", 20, 182}, + #endif + #ifdef SSL_R_NOT_REPLACING_CERTIFICATE + {"NOT_REPLACING_CERTIFICATE", ERR_LIB_SSL, SSL_R_NOT_REPLACING_CERTIFICATE}, + #else + {"NOT_REPLACING_CERTIFICATE", 20, 289}, + #endif + #ifdef SSL_R_NOT_SERVER + {"NOT_SERVER", ERR_LIB_SSL, SSL_R_NOT_SERVER}, + #else + {"NOT_SERVER", 20, 284}, + #endif + #ifdef SSL_R_NO_APPLICATION_PROTOCOL + {"NO_APPLICATION_PROTOCOL", ERR_LIB_SSL, SSL_R_NO_APPLICATION_PROTOCOL}, + #else + {"NO_APPLICATION_PROTOCOL", 20, 235}, + #endif + #ifdef SSL_R_NO_CERTIFICATES_RETURNED + {"NO_CERTIFICATES_RETURNED", ERR_LIB_SSL, SSL_R_NO_CERTIFICATES_RETURNED}, + #else + {"NO_CERTIFICATES_RETURNED", 20, 176}, + #endif + #ifdef SSL_R_NO_CERTIFICATE_ASSIGNED + {"NO_CERTIFICATE_ASSIGNED", ERR_LIB_SSL, SSL_R_NO_CERTIFICATE_ASSIGNED}, + #else + {"NO_CERTIFICATE_ASSIGNED", 20, 177}, + #endif + #ifdef SSL_R_NO_CERTIFICATE_SET + {"NO_CERTIFICATE_SET", ERR_LIB_SSL, SSL_R_NO_CERTIFICATE_SET}, + #else + {"NO_CERTIFICATE_SET", 20, 179}, + #endif + #ifdef SSL_R_NO_CHANGE_FOLLOWING_HRR + {"NO_CHANGE_FOLLOWING_HRR", ERR_LIB_SSL, SSL_R_NO_CHANGE_FOLLOWING_HRR}, + #else + {"NO_CHANGE_FOLLOWING_HRR", 20, 214}, + #endif + #ifdef SSL_R_NO_CIPHERS_AVAILABLE + {"NO_CIPHERS_AVAILABLE", ERR_LIB_SSL, SSL_R_NO_CIPHERS_AVAILABLE}, + #else + {"NO_CIPHERS_AVAILABLE", 20, 181}, + #endif + #ifdef SSL_R_NO_CIPHERS_SPECIFIED + {"NO_CIPHERS_SPECIFIED", ERR_LIB_SSL, SSL_R_NO_CIPHERS_SPECIFIED}, + #else + {"NO_CIPHERS_SPECIFIED", 20, 183}, + #endif + #ifdef SSL_R_NO_CIPHER_MATCH + {"NO_CIPHER_MATCH", ERR_LIB_SSL, SSL_R_NO_CIPHER_MATCH}, + #else + {"NO_CIPHER_MATCH", 20, 185}, + #endif + #ifdef SSL_R_NO_CLIENT_CERT_METHOD + {"NO_CLIENT_CERT_METHOD", ERR_LIB_SSL, SSL_R_NO_CLIENT_CERT_METHOD}, + #else + {"NO_CLIENT_CERT_METHOD", 20, 331}, + #endif + #ifdef SSL_R_NO_COMPRESSION_SPECIFIED + {"NO_COMPRESSION_SPECIFIED", ERR_LIB_SSL, SSL_R_NO_COMPRESSION_SPECIFIED}, + #else + {"NO_COMPRESSION_SPECIFIED", 20, 187}, + #endif + #ifdef SSL_R_NO_COOKIE_CALLBACK_SET + {"NO_COOKIE_CALLBACK_SET", ERR_LIB_SSL, SSL_R_NO_COOKIE_CALLBACK_SET}, + #else + {"NO_COOKIE_CALLBACK_SET", 20, 287}, + #endif + #ifdef SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER + {"NO_GOST_CERTIFICATE_SENT_BY_PEER", ERR_LIB_SSL, SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER}, + #else + {"NO_GOST_CERTIFICATE_SENT_BY_PEER", 20, 330}, + #endif + #ifdef SSL_R_NO_METHOD_SPECIFIED + {"NO_METHOD_SPECIFIED", ERR_LIB_SSL, SSL_R_NO_METHOD_SPECIFIED}, + #else + {"NO_METHOD_SPECIFIED", 20, 188}, + #endif + #ifdef SSL_R_NO_PEM_EXTENSIONS + {"NO_PEM_EXTENSIONS", ERR_LIB_SSL, SSL_R_NO_PEM_EXTENSIONS}, + #else + {"NO_PEM_EXTENSIONS", 20, 389}, + #endif + #ifdef SSL_R_NO_PRIVATE_KEY_ASSIGNED + {"NO_PRIVATE_KEY_ASSIGNED", ERR_LIB_SSL, SSL_R_NO_PRIVATE_KEY_ASSIGNED}, + #else + {"NO_PRIVATE_KEY_ASSIGNED", 20, 190}, + #endif + #ifdef SSL_R_NO_PROTOCOLS_AVAILABLE + {"NO_PROTOCOLS_AVAILABLE", ERR_LIB_SSL, SSL_R_NO_PROTOCOLS_AVAILABLE}, + #else + {"NO_PROTOCOLS_AVAILABLE", 20, 191}, + #endif + #ifdef SSL_R_NO_RENEGOTIATION + {"NO_RENEGOTIATION", ERR_LIB_SSL, SSL_R_NO_RENEGOTIATION}, + #else + {"NO_RENEGOTIATION", 20, 339}, + #endif + #ifdef SSL_R_NO_REQUIRED_DIGEST + {"NO_REQUIRED_DIGEST", ERR_LIB_SSL, SSL_R_NO_REQUIRED_DIGEST}, + #else + {"NO_REQUIRED_DIGEST", 20, 324}, + #endif + #ifdef SSL_R_NO_SHARED_CIPHER + {"NO_SHARED_CIPHER", ERR_LIB_SSL, SSL_R_NO_SHARED_CIPHER}, + #else + {"NO_SHARED_CIPHER", 20, 193}, + #endif + #ifdef SSL_R_NO_SHARED_GROUPS + {"NO_SHARED_GROUPS", ERR_LIB_SSL, SSL_R_NO_SHARED_GROUPS}, + #else + {"NO_SHARED_GROUPS", 20, 410}, + #endif + #ifdef SSL_R_NO_SHARED_SIGNATURE_ALGORITHMS + {"NO_SHARED_SIGNATURE_ALGORITHMS", ERR_LIB_SSL, SSL_R_NO_SHARED_SIGNATURE_ALGORITHMS}, + #else + {"NO_SHARED_SIGNATURE_ALGORITHMS", 20, 376}, + #endif + #ifdef SSL_R_NO_SRTP_PROFILES + {"NO_SRTP_PROFILES", ERR_LIB_SSL, SSL_R_NO_SRTP_PROFILES}, + #else + {"NO_SRTP_PROFILES", 20, 359}, + #endif + #ifdef SSL_R_NO_SUITABLE_DIGEST_ALGORITHM + {"NO_SUITABLE_DIGEST_ALGORITHM", ERR_LIB_SSL, SSL_R_NO_SUITABLE_DIGEST_ALGORITHM}, + #else + {"NO_SUITABLE_DIGEST_ALGORITHM", 20, 297}, + #endif + #ifdef SSL_R_NO_SUITABLE_GROUPS + {"NO_SUITABLE_GROUPS", ERR_LIB_SSL, SSL_R_NO_SUITABLE_GROUPS}, + #else + {"NO_SUITABLE_GROUPS", 20, 295}, + #endif + #ifdef SSL_R_NO_SUITABLE_KEY_SHARE + {"NO_SUITABLE_KEY_SHARE", ERR_LIB_SSL, SSL_R_NO_SUITABLE_KEY_SHARE}, + #else + {"NO_SUITABLE_KEY_SHARE", 20, 101}, + #endif + #ifdef SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM + {"NO_SUITABLE_SIGNATURE_ALGORITHM", ERR_LIB_SSL, SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM}, + #else + {"NO_SUITABLE_SIGNATURE_ALGORITHM", 20, 118}, + #endif + #ifdef SSL_R_NO_VALID_SCTS + {"NO_VALID_SCTS", ERR_LIB_SSL, SSL_R_NO_VALID_SCTS}, + #else + {"NO_VALID_SCTS", 20, 216}, + #endif + #ifdef SSL_R_NO_VERIFY_COOKIE_CALLBACK + {"NO_VERIFY_COOKIE_CALLBACK", ERR_LIB_SSL, SSL_R_NO_VERIFY_COOKIE_CALLBACK}, + #else + {"NO_VERIFY_COOKIE_CALLBACK", 20, 403}, + #endif + #ifdef SSL_R_NULL_SSL_CTX + {"NULL_SSL_CTX", ERR_LIB_SSL, SSL_R_NULL_SSL_CTX}, + #else + {"NULL_SSL_CTX", 20, 195}, + #endif + #ifdef SSL_R_NULL_SSL_METHOD_PASSED + {"NULL_SSL_METHOD_PASSED", ERR_LIB_SSL, SSL_R_NULL_SSL_METHOD_PASSED}, + #else + {"NULL_SSL_METHOD_PASSED", 20, 196}, + #endif + #ifdef SSL_R_OCSP_CALLBACK_FAILURE + {"OCSP_CALLBACK_FAILURE", ERR_LIB_SSL, SSL_R_OCSP_CALLBACK_FAILURE}, + #else + {"OCSP_CALLBACK_FAILURE", 20, 305}, + #endif + #ifdef SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED + {"OLD_SESSION_CIPHER_NOT_RETURNED", ERR_LIB_SSL, SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED}, + #else + {"OLD_SESSION_CIPHER_NOT_RETURNED", 20, 197}, + #endif + #ifdef SSL_R_OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED + {"OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED", ERR_LIB_SSL, SSL_R_OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED}, + #else + {"OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED", 20, 344}, + #endif + #ifdef SSL_R_OVERFLOW_ERROR + {"OVERFLOW_ERROR", ERR_LIB_SSL, SSL_R_OVERFLOW_ERROR}, + #else + {"OVERFLOW_ERROR", 20, 237}, + #endif + #ifdef SSL_R_PACKET_LENGTH_TOO_LONG + {"PACKET_LENGTH_TOO_LONG", ERR_LIB_SSL, SSL_R_PACKET_LENGTH_TOO_LONG}, + #else + {"PACKET_LENGTH_TOO_LONG", 20, 198}, + #endif + #ifdef SSL_R_PARSE_TLSEXT + {"PARSE_TLSEXT", ERR_LIB_SSL, SSL_R_PARSE_TLSEXT}, + #else + {"PARSE_TLSEXT", 20, 227}, + #endif + #ifdef SSL_R_PATH_TOO_LONG + {"PATH_TOO_LONG", ERR_LIB_SSL, SSL_R_PATH_TOO_LONG}, + #else + {"PATH_TOO_LONG", 20, 270}, + #endif + #ifdef SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE + {"PEER_DID_NOT_RETURN_A_CERTIFICATE", ERR_LIB_SSL, SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE}, + #else + {"PEER_DID_NOT_RETURN_A_CERTIFICATE", 20, 199}, + #endif + #ifdef SSL_R_PEM_NAME_BAD_PREFIX + {"PEM_NAME_BAD_PREFIX", ERR_LIB_SSL, SSL_R_PEM_NAME_BAD_PREFIX}, + #else + {"PEM_NAME_BAD_PREFIX", 20, 391}, + #endif + #ifdef SSL_R_PEM_NAME_TOO_SHORT + {"PEM_NAME_TOO_SHORT", ERR_LIB_SSL, SSL_R_PEM_NAME_TOO_SHORT}, + #else + {"PEM_NAME_TOO_SHORT", 20, 392}, + #endif + #ifdef SSL_R_PIPELINE_FAILURE + {"PIPELINE_FAILURE", ERR_LIB_SSL, SSL_R_PIPELINE_FAILURE}, + #else + {"PIPELINE_FAILURE", 20, 406}, + #endif + #ifdef SSL_R_POST_HANDSHAKE_AUTH_ENCODING_ERR + {"POST_HANDSHAKE_AUTH_ENCODING_ERR", ERR_LIB_SSL, SSL_R_POST_HANDSHAKE_AUTH_ENCODING_ERR}, + #else + {"POST_HANDSHAKE_AUTH_ENCODING_ERR", 20, 278}, + #endif + #ifdef SSL_R_PRIVATE_KEY_MISMATCH + {"PRIVATE_KEY_MISMATCH", ERR_LIB_SSL, SSL_R_PRIVATE_KEY_MISMATCH}, + #else + {"PRIVATE_KEY_MISMATCH", 20, 288}, + #endif + #ifdef SSL_R_PROTOCOL_IS_SHUTDOWN + {"PROTOCOL_IS_SHUTDOWN", ERR_LIB_SSL, SSL_R_PROTOCOL_IS_SHUTDOWN}, + #else + {"PROTOCOL_IS_SHUTDOWN", 20, 207}, + #endif + #ifdef SSL_R_PSK_IDENTITY_NOT_FOUND + {"PSK_IDENTITY_NOT_FOUND", ERR_LIB_SSL, SSL_R_PSK_IDENTITY_NOT_FOUND}, + #else + {"PSK_IDENTITY_NOT_FOUND", 20, 223}, + #endif + #ifdef SSL_R_PSK_NO_CLIENT_CB + {"PSK_NO_CLIENT_CB", ERR_LIB_SSL, SSL_R_PSK_NO_CLIENT_CB}, + #else + {"PSK_NO_CLIENT_CB", 20, 224}, + #endif + #ifdef SSL_R_PSK_NO_SERVER_CB + {"PSK_NO_SERVER_CB", ERR_LIB_SSL, SSL_R_PSK_NO_SERVER_CB}, + #else + {"PSK_NO_SERVER_CB", 20, 225}, + #endif + #ifdef SSL_R_READ_BIO_NOT_SET + {"READ_BIO_NOT_SET", ERR_LIB_SSL, SSL_R_READ_BIO_NOT_SET}, + #else + {"READ_BIO_NOT_SET", 20, 211}, + #endif + #ifdef SSL_R_READ_TIMEOUT_EXPIRED + {"READ_TIMEOUT_EXPIRED", ERR_LIB_SSL, SSL_R_READ_TIMEOUT_EXPIRED}, + #else + {"READ_TIMEOUT_EXPIRED", 20, 312}, + #endif + #ifdef SSL_R_RECORD_LENGTH_MISMATCH + {"RECORD_LENGTH_MISMATCH", ERR_LIB_SSL, SSL_R_RECORD_LENGTH_MISMATCH}, + #else + {"RECORD_LENGTH_MISMATCH", 20, 213}, + #endif + #ifdef SSL_R_RECORD_TOO_SMALL + {"RECORD_TOO_SMALL", ERR_LIB_SSL, SSL_R_RECORD_TOO_SMALL}, + #else + {"RECORD_TOO_SMALL", 20, 298}, + #endif + #ifdef SSL_R_RENEGOTIATE_EXT_TOO_LONG + {"RENEGOTIATE_EXT_TOO_LONG", ERR_LIB_SSL, SSL_R_RENEGOTIATE_EXT_TOO_LONG}, + #else + {"RENEGOTIATE_EXT_TOO_LONG", 20, 335}, + #endif + #ifdef SSL_R_RENEGOTIATION_ENCODING_ERR + {"RENEGOTIATION_ENCODING_ERR", ERR_LIB_SSL, SSL_R_RENEGOTIATION_ENCODING_ERR}, + #else + {"RENEGOTIATION_ENCODING_ERR", 20, 336}, + #endif + #ifdef SSL_R_RENEGOTIATION_MISMATCH + {"RENEGOTIATION_MISMATCH", ERR_LIB_SSL, SSL_R_RENEGOTIATION_MISMATCH}, + #else + {"RENEGOTIATION_MISMATCH", 20, 337}, + #endif + #ifdef SSL_R_REQUEST_PENDING + {"REQUEST_PENDING", ERR_LIB_SSL, SSL_R_REQUEST_PENDING}, + #else + {"REQUEST_PENDING", 20, 285}, + #endif + #ifdef SSL_R_REQUEST_SENT + {"REQUEST_SENT", ERR_LIB_SSL, SSL_R_REQUEST_SENT}, + #else + {"REQUEST_SENT", 20, 286}, + #endif + #ifdef SSL_R_REQUIRED_CIPHER_MISSING + {"REQUIRED_CIPHER_MISSING", ERR_LIB_SSL, SSL_R_REQUIRED_CIPHER_MISSING}, + #else + {"REQUIRED_CIPHER_MISSING", 20, 215}, + #endif + #ifdef SSL_R_REQUIRED_COMPRESSION_ALGORITHM_MISSING + {"REQUIRED_COMPRESSION_ALGORITHM_MISSING", ERR_LIB_SSL, SSL_R_REQUIRED_COMPRESSION_ALGORITHM_MISSING}, + #else + {"REQUIRED_COMPRESSION_ALGORITHM_MISSING", 20, 342}, + #endif + #ifdef SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING + {"SCSV_RECEIVED_WHEN_RENEGOTIATING", ERR_LIB_SSL, SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING}, + #else + {"SCSV_RECEIVED_WHEN_RENEGOTIATING", 20, 345}, + #endif + #ifdef SSL_R_SCT_VERIFICATION_FAILED + {"SCT_VERIFICATION_FAILED", ERR_LIB_SSL, SSL_R_SCT_VERIFICATION_FAILED}, + #else + {"SCT_VERIFICATION_FAILED", 20, 208}, + #endif + #ifdef SSL_R_SERVERHELLO_TLSEXT + {"SERVERHELLO_TLSEXT", ERR_LIB_SSL, SSL_R_SERVERHELLO_TLSEXT}, + #else + {"SERVERHELLO_TLSEXT", 20, 275}, + #endif + #ifdef SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED + {"SESSION_ID_CONTEXT_UNINITIALIZED", ERR_LIB_SSL, SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED}, + #else + {"SESSION_ID_CONTEXT_UNINITIALIZED", 20, 277}, + #endif + #ifdef SSL_R_SHUTDOWN_WHILE_IN_INIT + {"SHUTDOWN_WHILE_IN_INIT", ERR_LIB_SSL, SSL_R_SHUTDOWN_WHILE_IN_INIT}, + #else + {"SHUTDOWN_WHILE_IN_INIT", 20, 407}, + #endif + #ifdef SSL_R_SIGNATURE_ALGORITHMS_ERROR + {"SIGNATURE_ALGORITHMS_ERROR", ERR_LIB_SSL, SSL_R_SIGNATURE_ALGORITHMS_ERROR}, + #else + {"SIGNATURE_ALGORITHMS_ERROR", 20, 360}, + #endif + #ifdef SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE + {"SIGNATURE_FOR_NON_SIGNING_CERTIFICATE", ERR_LIB_SSL, SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE}, + #else + {"SIGNATURE_FOR_NON_SIGNING_CERTIFICATE", 20, 220}, + #endif + #ifdef SSL_R_SRP_A_CALC + {"SRP_A_CALC", ERR_LIB_SSL, SSL_R_SRP_A_CALC}, + #else + {"SRP_A_CALC", 20, 361}, + #endif + #ifdef SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES + {"SRTP_COULD_NOT_ALLOCATE_PROFILES", ERR_LIB_SSL, SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES}, + #else + {"SRTP_COULD_NOT_ALLOCATE_PROFILES", 20, 362}, + #endif + #ifdef SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG + {"SRTP_PROTECTION_PROFILE_LIST_TOO_LONG", ERR_LIB_SSL, SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG}, + #else + {"SRTP_PROTECTION_PROFILE_LIST_TOO_LONG", 20, 363}, + #endif + #ifdef SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE + {"SRTP_UNKNOWN_PROTECTION_PROFILE", ERR_LIB_SSL, SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE}, + #else + {"SRTP_UNKNOWN_PROTECTION_PROFILE", 20, 364}, + #endif + #ifdef SSL_R_SSL3_EXT_INVALID_MAX_FRAGMENT_LENGTH + {"SSL3_EXT_INVALID_MAX_FRAGMENT_LENGTH", ERR_LIB_SSL, SSL_R_SSL3_EXT_INVALID_MAX_FRAGMENT_LENGTH}, + #else + {"SSL3_EXT_INVALID_MAX_FRAGMENT_LENGTH", 20, 232}, + #endif + #ifdef SSL_R_SSL3_EXT_INVALID_SERVERNAME + {"SSL3_EXT_INVALID_SERVERNAME", ERR_LIB_SSL, SSL_R_SSL3_EXT_INVALID_SERVERNAME}, + #else + {"SSL3_EXT_INVALID_SERVERNAME", 20, 319}, + #endif + #ifdef SSL_R_SSL3_EXT_INVALID_SERVERNAME_TYPE + {"SSL3_EXT_INVALID_SERVERNAME_TYPE", ERR_LIB_SSL, SSL_R_SSL3_EXT_INVALID_SERVERNAME_TYPE}, + #else + {"SSL3_EXT_INVALID_SERVERNAME_TYPE", 20, 320}, + #endif + #ifdef SSL_R_SSL3_SESSION_ID_TOO_LONG + {"SSL3_SESSION_ID_TOO_LONG", ERR_LIB_SSL, SSL_R_SSL3_SESSION_ID_TOO_LONG}, + #else + {"SSL3_SESSION_ID_TOO_LONG", 20, 300}, + #endif + #ifdef SSL_R_SSLV3_ALERT_BAD_CERTIFICATE + {"SSLV3_ALERT_BAD_CERTIFICATE", ERR_LIB_SSL, SSL_R_SSLV3_ALERT_BAD_CERTIFICATE}, + #else + {"SSLV3_ALERT_BAD_CERTIFICATE", 20, 1042}, + #endif + #ifdef SSL_R_SSLV3_ALERT_BAD_RECORD_MAC + {"SSLV3_ALERT_BAD_RECORD_MAC", ERR_LIB_SSL, SSL_R_SSLV3_ALERT_BAD_RECORD_MAC}, + #else + {"SSLV3_ALERT_BAD_RECORD_MAC", 20, 1020}, + #endif + #ifdef SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED + {"SSLV3_ALERT_CERTIFICATE_EXPIRED", ERR_LIB_SSL, SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED}, + #else + {"SSLV3_ALERT_CERTIFICATE_EXPIRED", 20, 1045}, + #endif + #ifdef SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED + {"SSLV3_ALERT_CERTIFICATE_REVOKED", ERR_LIB_SSL, SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED}, + #else + {"SSLV3_ALERT_CERTIFICATE_REVOKED", 20, 1044}, + #endif + #ifdef SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN + {"SSLV3_ALERT_CERTIFICATE_UNKNOWN", ERR_LIB_SSL, SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN}, + #else + {"SSLV3_ALERT_CERTIFICATE_UNKNOWN", 20, 1046}, + #endif + #ifdef SSL_R_SSLV3_ALERT_DECOMPRESSION_FAILURE + {"SSLV3_ALERT_DECOMPRESSION_FAILURE", ERR_LIB_SSL, SSL_R_SSLV3_ALERT_DECOMPRESSION_FAILURE}, + #else + {"SSLV3_ALERT_DECOMPRESSION_FAILURE", 20, 1030}, + #endif + #ifdef SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE + {"SSLV3_ALERT_HANDSHAKE_FAILURE", ERR_LIB_SSL, SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE}, + #else + {"SSLV3_ALERT_HANDSHAKE_FAILURE", 20, 1040}, + #endif + #ifdef SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER + {"SSLV3_ALERT_ILLEGAL_PARAMETER", ERR_LIB_SSL, SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER}, + #else + {"SSLV3_ALERT_ILLEGAL_PARAMETER", 20, 1047}, + #endif + #ifdef SSL_R_SSLV3_ALERT_NO_CERTIFICATE + {"SSLV3_ALERT_NO_CERTIFICATE", ERR_LIB_SSL, SSL_R_SSLV3_ALERT_NO_CERTIFICATE}, + #else + {"SSLV3_ALERT_NO_CERTIFICATE", 20, 1041}, + #endif + #ifdef SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE + {"SSLV3_ALERT_UNEXPECTED_MESSAGE", ERR_LIB_SSL, SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE}, + #else + {"SSLV3_ALERT_UNEXPECTED_MESSAGE", 20, 1010}, + #endif + #ifdef SSL_R_SSLV3_ALERT_UNSUPPORTED_CERTIFICATE + {"SSLV3_ALERT_UNSUPPORTED_CERTIFICATE", ERR_LIB_SSL, SSL_R_SSLV3_ALERT_UNSUPPORTED_CERTIFICATE}, + #else + {"SSLV3_ALERT_UNSUPPORTED_CERTIFICATE", 20, 1043}, + #endif + #ifdef SSL_R_SSL_COMMAND_SECTION_EMPTY + {"SSL_COMMAND_SECTION_EMPTY", ERR_LIB_SSL, SSL_R_SSL_COMMAND_SECTION_EMPTY}, + #else + {"SSL_COMMAND_SECTION_EMPTY", 20, 117}, + #endif + #ifdef SSL_R_SSL_COMMAND_SECTION_NOT_FOUND + {"SSL_COMMAND_SECTION_NOT_FOUND", ERR_LIB_SSL, SSL_R_SSL_COMMAND_SECTION_NOT_FOUND}, + #else + {"SSL_COMMAND_SECTION_NOT_FOUND", 20, 125}, + #endif + #ifdef SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION + {"SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION", ERR_LIB_SSL, SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION}, + #else + {"SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION", 20, 228}, + #endif + #ifdef SSL_R_SSL_HANDSHAKE_FAILURE + {"SSL_HANDSHAKE_FAILURE", ERR_LIB_SSL, SSL_R_SSL_HANDSHAKE_FAILURE}, + #else + {"SSL_HANDSHAKE_FAILURE", 20, 229}, + #endif + #ifdef SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS + {"SSL_LIBRARY_HAS_NO_CIPHERS", ERR_LIB_SSL, SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS}, + #else + {"SSL_LIBRARY_HAS_NO_CIPHERS", 20, 230}, + #endif + #ifdef SSL_R_SSL_NEGATIVE_LENGTH + {"SSL_NEGATIVE_LENGTH", ERR_LIB_SSL, SSL_R_SSL_NEGATIVE_LENGTH}, + #else + {"SSL_NEGATIVE_LENGTH", 20, 372}, + #endif + #ifdef SSL_R_SSL_SECTION_EMPTY + {"SSL_SECTION_EMPTY", ERR_LIB_SSL, SSL_R_SSL_SECTION_EMPTY}, + #else + {"SSL_SECTION_EMPTY", 20, 126}, + #endif + #ifdef SSL_R_SSL_SECTION_NOT_FOUND + {"SSL_SECTION_NOT_FOUND", ERR_LIB_SSL, SSL_R_SSL_SECTION_NOT_FOUND}, + #else + {"SSL_SECTION_NOT_FOUND", 20, 136}, + #endif + #ifdef SSL_R_SSL_SESSION_ID_CALLBACK_FAILED + {"SSL_SESSION_ID_CALLBACK_FAILED", ERR_LIB_SSL, SSL_R_SSL_SESSION_ID_CALLBACK_FAILED}, + #else + {"SSL_SESSION_ID_CALLBACK_FAILED", 20, 301}, + #endif + #ifdef SSL_R_SSL_SESSION_ID_CONFLICT + {"SSL_SESSION_ID_CONFLICT", ERR_LIB_SSL, SSL_R_SSL_SESSION_ID_CONFLICT}, + #else + {"SSL_SESSION_ID_CONFLICT", 20, 302}, + #endif + #ifdef SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG + {"SSL_SESSION_ID_CONTEXT_TOO_LONG", ERR_LIB_SSL, SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG}, + #else + {"SSL_SESSION_ID_CONTEXT_TOO_LONG", 20, 273}, + #endif + #ifdef SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH + {"SSL_SESSION_ID_HAS_BAD_LENGTH", ERR_LIB_SSL, SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH}, + #else + {"SSL_SESSION_ID_HAS_BAD_LENGTH", 20, 303}, + #endif + #ifdef SSL_R_SSL_SESSION_ID_TOO_LONG + {"SSL_SESSION_ID_TOO_LONG", ERR_LIB_SSL, SSL_R_SSL_SESSION_ID_TOO_LONG}, + #else + {"SSL_SESSION_ID_TOO_LONG", 20, 408}, + #endif + #ifdef SSL_R_SSL_SESSION_VERSION_MISMATCH + {"SSL_SESSION_VERSION_MISMATCH", ERR_LIB_SSL, SSL_R_SSL_SESSION_VERSION_MISMATCH}, + #else + {"SSL_SESSION_VERSION_MISMATCH", 20, 210}, + #endif + #ifdef SSL_R_STILL_IN_INIT + {"STILL_IN_INIT", ERR_LIB_SSL, SSL_R_STILL_IN_INIT}, + #else + {"STILL_IN_INIT", 20, 121}, + #endif + #ifdef SSL_R_TLSV13_ALERT_CERTIFICATE_REQUIRED + {"TLSV13_ALERT_CERTIFICATE_REQUIRED", ERR_LIB_SSL, SSL_R_TLSV13_ALERT_CERTIFICATE_REQUIRED}, + #else + {"TLSV13_ALERT_CERTIFICATE_REQUIRED", 20, 1116}, + #endif + #ifdef SSL_R_TLSV13_ALERT_MISSING_EXTENSION + {"TLSV13_ALERT_MISSING_EXTENSION", ERR_LIB_SSL, SSL_R_TLSV13_ALERT_MISSING_EXTENSION}, + #else + {"TLSV13_ALERT_MISSING_EXTENSION", 20, 1109}, + #endif + #ifdef SSL_R_TLSV1_ALERT_ACCESS_DENIED + {"TLSV1_ALERT_ACCESS_DENIED", ERR_LIB_SSL, SSL_R_TLSV1_ALERT_ACCESS_DENIED}, + #else + {"TLSV1_ALERT_ACCESS_DENIED", 20, 1049}, + #endif + #ifdef SSL_R_TLSV1_ALERT_DECODE_ERROR + {"TLSV1_ALERT_DECODE_ERROR", ERR_LIB_SSL, SSL_R_TLSV1_ALERT_DECODE_ERROR}, + #else + {"TLSV1_ALERT_DECODE_ERROR", 20, 1050}, + #endif + #ifdef SSL_R_TLSV1_ALERT_DECRYPTION_FAILED + {"TLSV1_ALERT_DECRYPTION_FAILED", ERR_LIB_SSL, SSL_R_TLSV1_ALERT_DECRYPTION_FAILED}, + #else + {"TLSV1_ALERT_DECRYPTION_FAILED", 20, 1021}, + #endif + #ifdef SSL_R_TLSV1_ALERT_DECRYPT_ERROR + {"TLSV1_ALERT_DECRYPT_ERROR", ERR_LIB_SSL, SSL_R_TLSV1_ALERT_DECRYPT_ERROR}, + #else + {"TLSV1_ALERT_DECRYPT_ERROR", 20, 1051}, + #endif + #ifdef SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION + {"TLSV1_ALERT_EXPORT_RESTRICTION", ERR_LIB_SSL, SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION}, + #else + {"TLSV1_ALERT_EXPORT_RESTRICTION", 20, 1060}, + #endif + #ifdef SSL_R_TLSV1_ALERT_INAPPROPRIATE_FALLBACK + {"TLSV1_ALERT_INAPPROPRIATE_FALLBACK", ERR_LIB_SSL, SSL_R_TLSV1_ALERT_INAPPROPRIATE_FALLBACK}, + #else + {"TLSV1_ALERT_INAPPROPRIATE_FALLBACK", 20, 1086}, + #endif + #ifdef SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY + {"TLSV1_ALERT_INSUFFICIENT_SECURITY", ERR_LIB_SSL, SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY}, + #else + {"TLSV1_ALERT_INSUFFICIENT_SECURITY", 20, 1071}, + #endif + #ifdef SSL_R_TLSV1_ALERT_INTERNAL_ERROR + {"TLSV1_ALERT_INTERNAL_ERROR", ERR_LIB_SSL, SSL_R_TLSV1_ALERT_INTERNAL_ERROR}, + #else + {"TLSV1_ALERT_INTERNAL_ERROR", 20, 1080}, + #endif + #ifdef SSL_R_TLSV1_ALERT_NO_RENEGOTIATION + {"TLSV1_ALERT_NO_RENEGOTIATION", ERR_LIB_SSL, SSL_R_TLSV1_ALERT_NO_RENEGOTIATION}, + #else + {"TLSV1_ALERT_NO_RENEGOTIATION", 20, 1100}, + #endif + #ifdef SSL_R_TLSV1_ALERT_PROTOCOL_VERSION + {"TLSV1_ALERT_PROTOCOL_VERSION", ERR_LIB_SSL, SSL_R_TLSV1_ALERT_PROTOCOL_VERSION}, + #else + {"TLSV1_ALERT_PROTOCOL_VERSION", 20, 1070}, + #endif + #ifdef SSL_R_TLSV1_ALERT_RECORD_OVERFLOW + {"TLSV1_ALERT_RECORD_OVERFLOW", ERR_LIB_SSL, SSL_R_TLSV1_ALERT_RECORD_OVERFLOW}, + #else + {"TLSV1_ALERT_RECORD_OVERFLOW", 20, 1022}, + #endif + #ifdef SSL_R_TLSV1_ALERT_UNKNOWN_CA + {"TLSV1_ALERT_UNKNOWN_CA", ERR_LIB_SSL, SSL_R_TLSV1_ALERT_UNKNOWN_CA}, + #else + {"TLSV1_ALERT_UNKNOWN_CA", 20, 1048}, + #endif + #ifdef SSL_R_TLSV1_ALERT_USER_CANCELLED + {"TLSV1_ALERT_USER_CANCELLED", ERR_LIB_SSL, SSL_R_TLSV1_ALERT_USER_CANCELLED}, + #else + {"TLSV1_ALERT_USER_CANCELLED", 20, 1090}, + #endif + #ifdef SSL_R_TLSV1_BAD_CERTIFICATE_HASH_VALUE + {"TLSV1_BAD_CERTIFICATE_HASH_VALUE", ERR_LIB_SSL, SSL_R_TLSV1_BAD_CERTIFICATE_HASH_VALUE}, + #else + {"TLSV1_BAD_CERTIFICATE_HASH_VALUE", 20, 1114}, + #endif + #ifdef SSL_R_TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE + {"TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE", ERR_LIB_SSL, SSL_R_TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE}, + #else + {"TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE", 20, 1113}, + #endif + #ifdef SSL_R_TLSV1_CERTIFICATE_UNOBTAINABLE + {"TLSV1_CERTIFICATE_UNOBTAINABLE", ERR_LIB_SSL, SSL_R_TLSV1_CERTIFICATE_UNOBTAINABLE}, + #else + {"TLSV1_CERTIFICATE_UNOBTAINABLE", 20, 1111}, + #endif + #ifdef SSL_R_TLSV1_UNRECOGNIZED_NAME + {"TLSV1_UNRECOGNIZED_NAME", ERR_LIB_SSL, SSL_R_TLSV1_UNRECOGNIZED_NAME}, + #else + {"TLSV1_UNRECOGNIZED_NAME", 20, 1112}, + #endif + #ifdef SSL_R_TLSV1_UNSUPPORTED_EXTENSION + {"TLSV1_UNSUPPORTED_EXTENSION", ERR_LIB_SSL, SSL_R_TLSV1_UNSUPPORTED_EXTENSION}, + #else + {"TLSV1_UNSUPPORTED_EXTENSION", 20, 1110}, + #endif + #ifdef SSL_R_TLS_ILLEGAL_EXPORTER_LABEL + {"TLS_ILLEGAL_EXPORTER_LABEL", ERR_LIB_SSL, SSL_R_TLS_ILLEGAL_EXPORTER_LABEL}, + #else + {"TLS_ILLEGAL_EXPORTER_LABEL", 20, 367}, + #endif + #ifdef SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST + {"TLS_INVALID_ECPOINTFORMAT_LIST", ERR_LIB_SSL, SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST}, + #else + {"TLS_INVALID_ECPOINTFORMAT_LIST", 20, 157}, + #endif + #ifdef SSL_R_TOO_MANY_KEY_UPDATES + {"TOO_MANY_KEY_UPDATES", ERR_LIB_SSL, SSL_R_TOO_MANY_KEY_UPDATES}, + #else + {"TOO_MANY_KEY_UPDATES", 20, 132}, + #endif + #ifdef SSL_R_TOO_MANY_WARN_ALERTS + {"TOO_MANY_WARN_ALERTS", ERR_LIB_SSL, SSL_R_TOO_MANY_WARN_ALERTS}, + #else + {"TOO_MANY_WARN_ALERTS", 20, 409}, + #endif + #ifdef SSL_R_TOO_MUCH_EARLY_DATA + {"TOO_MUCH_EARLY_DATA", ERR_LIB_SSL, SSL_R_TOO_MUCH_EARLY_DATA}, + #else + {"TOO_MUCH_EARLY_DATA", 20, 164}, + #endif + #ifdef SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS + {"UNABLE_TO_FIND_ECDH_PARAMETERS", ERR_LIB_SSL, SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS}, + #else + {"UNABLE_TO_FIND_ECDH_PARAMETERS", 20, 314}, + #endif + #ifdef SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS + {"UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS", ERR_LIB_SSL, SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS}, + #else + {"UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS", 20, 239}, + #endif + #ifdef SSL_R_UNABLE_TO_LOAD_SSL3_MD5_ROUTINES + {"UNABLE_TO_LOAD_SSL3_MD5_ROUTINES", ERR_LIB_SSL, SSL_R_UNABLE_TO_LOAD_SSL3_MD5_ROUTINES}, + #else + {"UNABLE_TO_LOAD_SSL3_MD5_ROUTINES", 20, 242}, + #endif + #ifdef SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES + {"UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES", ERR_LIB_SSL, SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES}, + #else + {"UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES", 20, 243}, + #endif + #ifdef SSL_R_UNEXPECTED_CCS_MESSAGE + {"UNEXPECTED_CCS_MESSAGE", ERR_LIB_SSL, SSL_R_UNEXPECTED_CCS_MESSAGE}, + #else + {"UNEXPECTED_CCS_MESSAGE", 20, 262}, + #endif + #ifdef SSL_R_UNEXPECTED_END_OF_EARLY_DATA + {"UNEXPECTED_END_OF_EARLY_DATA", ERR_LIB_SSL, SSL_R_UNEXPECTED_END_OF_EARLY_DATA}, + #else + {"UNEXPECTED_END_OF_EARLY_DATA", 20, 178}, + #endif + #ifdef SSL_R_UNEXPECTED_EOF_WHILE_READING + {"UNEXPECTED_EOF_WHILE_READING", ERR_LIB_SSL, SSL_R_UNEXPECTED_EOF_WHILE_READING}, + #else + {"UNEXPECTED_EOF_WHILE_READING", 20, 294}, + #endif + #ifdef SSL_R_UNEXPECTED_MESSAGE + {"UNEXPECTED_MESSAGE", ERR_LIB_SSL, SSL_R_UNEXPECTED_MESSAGE}, + #else + {"UNEXPECTED_MESSAGE", 20, 244}, + #endif + #ifdef SSL_R_UNEXPECTED_RECORD + {"UNEXPECTED_RECORD", ERR_LIB_SSL, SSL_R_UNEXPECTED_RECORD}, + #else + {"UNEXPECTED_RECORD", 20, 245}, + #endif + #ifdef SSL_R_UNINITIALIZED + {"UNINITIALIZED", ERR_LIB_SSL, SSL_R_UNINITIALIZED}, + #else + {"UNINITIALIZED", 20, 276}, + #endif + #ifdef SSL_R_UNKNOWN_ALERT_TYPE + {"UNKNOWN_ALERT_TYPE", ERR_LIB_SSL, SSL_R_UNKNOWN_ALERT_TYPE}, + #else + {"UNKNOWN_ALERT_TYPE", 20, 246}, + #endif + #ifdef SSL_R_UNKNOWN_CERTIFICATE_TYPE + {"UNKNOWN_CERTIFICATE_TYPE", ERR_LIB_SSL, SSL_R_UNKNOWN_CERTIFICATE_TYPE}, + #else + {"UNKNOWN_CERTIFICATE_TYPE", 20, 247}, + #endif + #ifdef SSL_R_UNKNOWN_CIPHER_RETURNED + {"UNKNOWN_CIPHER_RETURNED", ERR_LIB_SSL, SSL_R_UNKNOWN_CIPHER_RETURNED}, + #else + {"UNKNOWN_CIPHER_RETURNED", 20, 248}, + #endif + #ifdef SSL_R_UNKNOWN_CIPHER_TYPE + {"UNKNOWN_CIPHER_TYPE", ERR_LIB_SSL, SSL_R_UNKNOWN_CIPHER_TYPE}, + #else + {"UNKNOWN_CIPHER_TYPE", 20, 249}, + #endif + #ifdef SSL_R_UNKNOWN_CMD_NAME + {"UNKNOWN_CMD_NAME", ERR_LIB_SSL, SSL_R_UNKNOWN_CMD_NAME}, + #else + {"UNKNOWN_CMD_NAME", 20, 386}, + #endif + #ifdef SSL_R_UNKNOWN_COMMAND + {"UNKNOWN_COMMAND", ERR_LIB_SSL, SSL_R_UNKNOWN_COMMAND}, + #else + {"UNKNOWN_COMMAND", 20, 139}, + #endif + #ifdef SSL_R_UNKNOWN_DIGEST + {"UNKNOWN_DIGEST", ERR_LIB_SSL, SSL_R_UNKNOWN_DIGEST}, + #else + {"UNKNOWN_DIGEST", 20, 368}, + #endif + #ifdef SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE + {"UNKNOWN_KEY_EXCHANGE_TYPE", ERR_LIB_SSL, SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE}, + #else + {"UNKNOWN_KEY_EXCHANGE_TYPE", 20, 250}, + #endif + #ifdef SSL_R_UNKNOWN_PKEY_TYPE + {"UNKNOWN_PKEY_TYPE", ERR_LIB_SSL, SSL_R_UNKNOWN_PKEY_TYPE}, + #else + {"UNKNOWN_PKEY_TYPE", 20, 251}, + #endif + #ifdef SSL_R_UNKNOWN_PROTOCOL + {"UNKNOWN_PROTOCOL", ERR_LIB_SSL, SSL_R_UNKNOWN_PROTOCOL}, + #else + {"UNKNOWN_PROTOCOL", 20, 252}, + #endif + #ifdef SSL_R_UNKNOWN_SSL_VERSION + {"UNKNOWN_SSL_VERSION", ERR_LIB_SSL, SSL_R_UNKNOWN_SSL_VERSION}, + #else + {"UNKNOWN_SSL_VERSION", 20, 254}, + #endif + #ifdef SSL_R_UNKNOWN_STATE + {"UNKNOWN_STATE", ERR_LIB_SSL, SSL_R_UNKNOWN_STATE}, + #else + {"UNKNOWN_STATE", 20, 255}, + #endif + #ifdef SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED + {"UNSAFE_LEGACY_RENEGOTIATION_DISABLED", ERR_LIB_SSL, SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED}, + #else + {"UNSAFE_LEGACY_RENEGOTIATION_DISABLED", 20, 338}, + #endif + #ifdef SSL_R_UNSOLICITED_EXTENSION + {"UNSOLICITED_EXTENSION", ERR_LIB_SSL, SSL_R_UNSOLICITED_EXTENSION}, + #else + {"UNSOLICITED_EXTENSION", 20, 217}, + #endif + #ifdef SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM + {"UNSUPPORTED_COMPRESSION_ALGORITHM", ERR_LIB_SSL, SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM}, + #else + {"UNSUPPORTED_COMPRESSION_ALGORITHM", 20, 257}, + #endif + #ifdef SSL_R_UNSUPPORTED_ELLIPTIC_CURVE + {"UNSUPPORTED_ELLIPTIC_CURVE", ERR_LIB_SSL, SSL_R_UNSUPPORTED_ELLIPTIC_CURVE}, + #else + {"UNSUPPORTED_ELLIPTIC_CURVE", 20, 315}, + #endif + #ifdef SSL_R_UNSUPPORTED_PROTOCOL + {"UNSUPPORTED_PROTOCOL", ERR_LIB_SSL, SSL_R_UNSUPPORTED_PROTOCOL}, + #else + {"UNSUPPORTED_PROTOCOL", 20, 258}, + #endif + #ifdef SSL_R_UNSUPPORTED_SSL_VERSION + {"UNSUPPORTED_SSL_VERSION", ERR_LIB_SSL, SSL_R_UNSUPPORTED_SSL_VERSION}, + #else + {"UNSUPPORTED_SSL_VERSION", 20, 259}, + #endif + #ifdef SSL_R_UNSUPPORTED_STATUS_TYPE + {"UNSUPPORTED_STATUS_TYPE", ERR_LIB_SSL, SSL_R_UNSUPPORTED_STATUS_TYPE}, + #else + {"UNSUPPORTED_STATUS_TYPE", 20, 329}, + #endif + #ifdef SSL_R_USE_SRTP_NOT_NEGOTIATED + {"USE_SRTP_NOT_NEGOTIATED", ERR_LIB_SSL, SSL_R_USE_SRTP_NOT_NEGOTIATED}, + #else + {"USE_SRTP_NOT_NEGOTIATED", 20, 369}, + #endif + #ifdef SSL_R_VERSION_TOO_HIGH + {"VERSION_TOO_HIGH", ERR_LIB_SSL, SSL_R_VERSION_TOO_HIGH}, + #else + {"VERSION_TOO_HIGH", 20, 166}, + #endif + #ifdef SSL_R_VERSION_TOO_LOW + {"VERSION_TOO_LOW", ERR_LIB_SSL, SSL_R_VERSION_TOO_LOW}, + #else + {"VERSION_TOO_LOW", 20, 396}, + #endif + #ifdef SSL_R_WRONG_CERTIFICATE_TYPE + {"WRONG_CERTIFICATE_TYPE", ERR_LIB_SSL, SSL_R_WRONG_CERTIFICATE_TYPE}, + #else + {"WRONG_CERTIFICATE_TYPE", 20, 383}, + #endif + #ifdef SSL_R_WRONG_CIPHER_RETURNED + {"WRONG_CIPHER_RETURNED", ERR_LIB_SSL, SSL_R_WRONG_CIPHER_RETURNED}, + #else + {"WRONG_CIPHER_RETURNED", 20, 261}, + #endif + #ifdef SSL_R_WRONG_CURVE + {"WRONG_CURVE", ERR_LIB_SSL, SSL_R_WRONG_CURVE}, + #else + {"WRONG_CURVE", 20, 378}, + #endif + #ifdef SSL_R_WRONG_SIGNATURE_LENGTH + {"WRONG_SIGNATURE_LENGTH", ERR_LIB_SSL, SSL_R_WRONG_SIGNATURE_LENGTH}, + #else + {"WRONG_SIGNATURE_LENGTH", 20, 264}, + #endif + #ifdef SSL_R_WRONG_SIGNATURE_SIZE + {"WRONG_SIGNATURE_SIZE", ERR_LIB_SSL, SSL_R_WRONG_SIGNATURE_SIZE}, + #else + {"WRONG_SIGNATURE_SIZE", 20, 265}, + #endif + #ifdef SSL_R_WRONG_SIGNATURE_TYPE + {"WRONG_SIGNATURE_TYPE", ERR_LIB_SSL, SSL_R_WRONG_SIGNATURE_TYPE}, + #else + {"WRONG_SIGNATURE_TYPE", 20, 370}, + #endif + #ifdef SSL_R_WRONG_SSL_VERSION + {"WRONG_SSL_VERSION", ERR_LIB_SSL, SSL_R_WRONG_SSL_VERSION}, + #else + {"WRONG_SSL_VERSION", 20, 266}, + #endif + #ifdef SSL_R_WRONG_VERSION_NUMBER + {"WRONG_VERSION_NUMBER", ERR_LIB_SSL, SSL_R_WRONG_VERSION_NUMBER}, + #else + {"WRONG_VERSION_NUMBER", 20, 267}, + #endif + #ifdef SSL_R_X509_LIB + {"X509_LIB", ERR_LIB_SSL, SSL_R_X509_LIB}, + #else + {"X509_LIB", 20, 268}, + #endif + #ifdef SSL_R_X509_VERIFICATION_SETUP_PROBLEMS + {"X509_VERIFICATION_SETUP_PROBLEMS", ERR_LIB_SSL, SSL_R_X509_VERIFICATION_SETUP_PROBLEMS}, + #else + {"X509_VERIFICATION_SETUP_PROBLEMS", 20, 269}, + #endif + #ifdef TS_R_BAD_PKCS7_TYPE + {"BAD_PKCS7_TYPE", ERR_LIB_TS, TS_R_BAD_PKCS7_TYPE}, + #else + {"BAD_PKCS7_TYPE", 47, 132}, + #endif + #ifdef TS_R_BAD_TYPE + {"BAD_TYPE", ERR_LIB_TS, TS_R_BAD_TYPE}, + #else + {"BAD_TYPE", 47, 133}, + #endif + #ifdef TS_R_CANNOT_LOAD_CERT + {"CANNOT_LOAD_CERT", ERR_LIB_TS, TS_R_CANNOT_LOAD_CERT}, + #else + {"CANNOT_LOAD_CERT", 47, 137}, + #endif + #ifdef TS_R_CANNOT_LOAD_KEY + {"CANNOT_LOAD_KEY", ERR_LIB_TS, TS_R_CANNOT_LOAD_KEY}, + #else + {"CANNOT_LOAD_KEY", 47, 138}, + #endif + #ifdef TS_R_CERTIFICATE_VERIFY_ERROR + {"CERTIFICATE_VERIFY_ERROR", ERR_LIB_TS, TS_R_CERTIFICATE_VERIFY_ERROR}, + #else + {"CERTIFICATE_VERIFY_ERROR", 47, 100}, + #endif + #ifdef TS_R_COULD_NOT_SET_ENGINE + {"COULD_NOT_SET_ENGINE", ERR_LIB_TS, TS_R_COULD_NOT_SET_ENGINE}, + #else + {"COULD_NOT_SET_ENGINE", 47, 127}, + #endif + #ifdef TS_R_COULD_NOT_SET_TIME + {"COULD_NOT_SET_TIME", ERR_LIB_TS, TS_R_COULD_NOT_SET_TIME}, + #else + {"COULD_NOT_SET_TIME", 47, 115}, + #endif + #ifdef TS_R_DETACHED_CONTENT + {"DETACHED_CONTENT", ERR_LIB_TS, TS_R_DETACHED_CONTENT}, + #else + {"DETACHED_CONTENT", 47, 134}, + #endif + #ifdef TS_R_ESS_ADD_SIGNING_CERT_ERROR + {"ESS_ADD_SIGNING_CERT_ERROR", ERR_LIB_TS, TS_R_ESS_ADD_SIGNING_CERT_ERROR}, + #else + {"ESS_ADD_SIGNING_CERT_ERROR", 47, 116}, + #endif + #ifdef TS_R_ESS_ADD_SIGNING_CERT_V2_ERROR + {"ESS_ADD_SIGNING_CERT_V2_ERROR", ERR_LIB_TS, TS_R_ESS_ADD_SIGNING_CERT_V2_ERROR}, + #else + {"ESS_ADD_SIGNING_CERT_V2_ERROR", 47, 139}, + #endif + #ifdef TS_R_ESS_SIGNING_CERTIFICATE_ERROR + {"ESS_SIGNING_CERTIFICATE_ERROR", ERR_LIB_TS, TS_R_ESS_SIGNING_CERTIFICATE_ERROR}, + #else + {"ESS_SIGNING_CERTIFICATE_ERROR", 47, 101}, + #endif + #ifdef TS_R_INVALID_NULL_POINTER + {"INVALID_NULL_POINTER", ERR_LIB_TS, TS_R_INVALID_NULL_POINTER}, + #else + {"INVALID_NULL_POINTER", 47, 102}, + #endif + #ifdef TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE + {"INVALID_SIGNER_CERTIFICATE_PURPOSE", ERR_LIB_TS, TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE}, + #else + {"INVALID_SIGNER_CERTIFICATE_PURPOSE", 47, 117}, + #endif + #ifdef TS_R_MESSAGE_IMPRINT_MISMATCH + {"MESSAGE_IMPRINT_MISMATCH", ERR_LIB_TS, TS_R_MESSAGE_IMPRINT_MISMATCH}, + #else + {"MESSAGE_IMPRINT_MISMATCH", 47, 103}, + #endif + #ifdef TS_R_NONCE_MISMATCH + {"NONCE_MISMATCH", ERR_LIB_TS, TS_R_NONCE_MISMATCH}, + #else + {"NONCE_MISMATCH", 47, 104}, + #endif + #ifdef TS_R_NONCE_NOT_RETURNED + {"NONCE_NOT_RETURNED", ERR_LIB_TS, TS_R_NONCE_NOT_RETURNED}, + #else + {"NONCE_NOT_RETURNED", 47, 105}, + #endif + #ifdef TS_R_NO_CONTENT + {"NO_CONTENT", ERR_LIB_TS, TS_R_NO_CONTENT}, + #else + {"NO_CONTENT", 47, 106}, + #endif + #ifdef TS_R_NO_TIME_STAMP_TOKEN + {"NO_TIME_STAMP_TOKEN", ERR_LIB_TS, TS_R_NO_TIME_STAMP_TOKEN}, + #else + {"NO_TIME_STAMP_TOKEN", 47, 107}, + #endif + #ifdef TS_R_PKCS7_ADD_SIGNATURE_ERROR + {"PKCS7_ADD_SIGNATURE_ERROR", ERR_LIB_TS, TS_R_PKCS7_ADD_SIGNATURE_ERROR}, + #else + {"PKCS7_ADD_SIGNATURE_ERROR", 47, 118}, + #endif + #ifdef TS_R_PKCS7_ADD_SIGNED_ATTR_ERROR + {"PKCS7_ADD_SIGNED_ATTR_ERROR", ERR_LIB_TS, TS_R_PKCS7_ADD_SIGNED_ATTR_ERROR}, + #else + {"PKCS7_ADD_SIGNED_ATTR_ERROR", 47, 119}, + #endif + #ifdef TS_R_PKCS7_TO_TS_TST_INFO_FAILED + {"PKCS7_TO_TS_TST_INFO_FAILED", ERR_LIB_TS, TS_R_PKCS7_TO_TS_TST_INFO_FAILED}, + #else + {"PKCS7_TO_TS_TST_INFO_FAILED", 47, 129}, + #endif + #ifdef TS_R_POLICY_MISMATCH + {"POLICY_MISMATCH", ERR_LIB_TS, TS_R_POLICY_MISMATCH}, + #else + {"POLICY_MISMATCH", 47, 108}, + #endif + #ifdef TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE + {"PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE", ERR_LIB_TS, TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE}, + #else + {"PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE", 47, 120}, + #endif + #ifdef TS_R_RESPONSE_SETUP_ERROR + {"RESPONSE_SETUP_ERROR", ERR_LIB_TS, TS_R_RESPONSE_SETUP_ERROR}, + #else + {"RESPONSE_SETUP_ERROR", 47, 121}, + #endif + #ifdef TS_R_SIGNATURE_FAILURE + {"SIGNATURE_FAILURE", ERR_LIB_TS, TS_R_SIGNATURE_FAILURE}, + #else + {"SIGNATURE_FAILURE", 47, 109}, + #endif + #ifdef TS_R_THERE_MUST_BE_ONE_SIGNER + {"THERE_MUST_BE_ONE_SIGNER", ERR_LIB_TS, TS_R_THERE_MUST_BE_ONE_SIGNER}, + #else + {"THERE_MUST_BE_ONE_SIGNER", 47, 110}, + #endif + #ifdef TS_R_TIME_SYSCALL_ERROR + {"TIME_SYSCALL_ERROR", ERR_LIB_TS, TS_R_TIME_SYSCALL_ERROR}, + #else + {"TIME_SYSCALL_ERROR", 47, 122}, + #endif + #ifdef TS_R_TOKEN_NOT_PRESENT + {"TOKEN_NOT_PRESENT", ERR_LIB_TS, TS_R_TOKEN_NOT_PRESENT}, + #else + {"TOKEN_NOT_PRESENT", 47, 130}, + #endif + #ifdef TS_R_TOKEN_PRESENT + {"TOKEN_PRESENT", ERR_LIB_TS, TS_R_TOKEN_PRESENT}, + #else + {"TOKEN_PRESENT", 47, 131}, + #endif + #ifdef TS_R_TSA_NAME_MISMATCH + {"TSA_NAME_MISMATCH", ERR_LIB_TS, TS_R_TSA_NAME_MISMATCH}, + #else + {"TSA_NAME_MISMATCH", 47, 111}, + #endif + #ifdef TS_R_TSA_UNTRUSTED + {"TSA_UNTRUSTED", ERR_LIB_TS, TS_R_TSA_UNTRUSTED}, + #else + {"TSA_UNTRUSTED", 47, 112}, + #endif + #ifdef TS_R_TST_INFO_SETUP_ERROR + {"TST_INFO_SETUP_ERROR", ERR_LIB_TS, TS_R_TST_INFO_SETUP_ERROR}, + #else + {"TST_INFO_SETUP_ERROR", 47, 123}, + #endif + #ifdef TS_R_TS_DATASIGN + {"TS_DATASIGN", ERR_LIB_TS, TS_R_TS_DATASIGN}, + #else + {"TS_DATASIGN", 47, 124}, + #endif + #ifdef TS_R_UNACCEPTABLE_POLICY + {"UNACCEPTABLE_POLICY", ERR_LIB_TS, TS_R_UNACCEPTABLE_POLICY}, + #else + {"UNACCEPTABLE_POLICY", 47, 125}, + #endif + #ifdef TS_R_UNSUPPORTED_MD_ALGORITHM + {"UNSUPPORTED_MD_ALGORITHM", ERR_LIB_TS, TS_R_UNSUPPORTED_MD_ALGORITHM}, + #else + {"UNSUPPORTED_MD_ALGORITHM", 47, 126}, + #endif + #ifdef TS_R_UNSUPPORTED_VERSION + {"UNSUPPORTED_VERSION", ERR_LIB_TS, TS_R_UNSUPPORTED_VERSION}, + #else + {"UNSUPPORTED_VERSION", 47, 113}, + #endif + #ifdef TS_R_VAR_BAD_VALUE + {"VAR_BAD_VALUE", ERR_LIB_TS, TS_R_VAR_BAD_VALUE}, + #else + {"VAR_BAD_VALUE", 47, 135}, + #endif + #ifdef TS_R_VAR_LOOKUP_FAILURE + {"VAR_LOOKUP_FAILURE", ERR_LIB_TS, TS_R_VAR_LOOKUP_FAILURE}, + #else + {"VAR_LOOKUP_FAILURE", 47, 136}, + #endif + #ifdef TS_R_WRONG_CONTENT_TYPE + {"WRONG_CONTENT_TYPE", ERR_LIB_TS, TS_R_WRONG_CONTENT_TYPE}, + #else + {"WRONG_CONTENT_TYPE", 47, 114}, + #endif + #ifdef UI_R_COMMON_OK_AND_CANCEL_CHARACTERS + {"COMMON_OK_AND_CANCEL_CHARACTERS", ERR_LIB_UI, UI_R_COMMON_OK_AND_CANCEL_CHARACTERS}, + #else + {"COMMON_OK_AND_CANCEL_CHARACTERS", 40, 104}, + #endif + #ifdef UI_R_INDEX_TOO_LARGE + {"INDEX_TOO_LARGE", ERR_LIB_UI, UI_R_INDEX_TOO_LARGE}, + #else + {"INDEX_TOO_LARGE", 40, 102}, + #endif + #ifdef UI_R_INDEX_TOO_SMALL + {"INDEX_TOO_SMALL", ERR_LIB_UI, UI_R_INDEX_TOO_SMALL}, + #else + {"INDEX_TOO_SMALL", 40, 103}, + #endif + #ifdef UI_R_NO_RESULT_BUFFER + {"NO_RESULT_BUFFER", ERR_LIB_UI, UI_R_NO_RESULT_BUFFER}, + #else + {"NO_RESULT_BUFFER", 40, 105}, + #endif + #ifdef UI_R_PROCESSING_ERROR + {"PROCESSING_ERROR", ERR_LIB_UI, UI_R_PROCESSING_ERROR}, + #else + {"PROCESSING_ERROR", 40, 107}, + #endif + #ifdef UI_R_RESULT_TOO_LARGE + {"RESULT_TOO_LARGE", ERR_LIB_UI, UI_R_RESULT_TOO_LARGE}, + #else + {"RESULT_TOO_LARGE", 40, 100}, + #endif + #ifdef UI_R_RESULT_TOO_SMALL + {"RESULT_TOO_SMALL", ERR_LIB_UI, UI_R_RESULT_TOO_SMALL}, + #else + {"RESULT_TOO_SMALL", 40, 101}, + #endif + #ifdef UI_R_SYSASSIGN_ERROR + {"SYSASSIGN_ERROR", ERR_LIB_UI, UI_R_SYSASSIGN_ERROR}, + #else + {"SYSASSIGN_ERROR", 40, 109}, + #endif + #ifdef UI_R_SYSDASSGN_ERROR + {"SYSDASSGN_ERROR", ERR_LIB_UI, UI_R_SYSDASSGN_ERROR}, + #else + {"SYSDASSGN_ERROR", 40, 110}, + #endif + #ifdef UI_R_SYSQIOW_ERROR + {"SYSQIOW_ERROR", ERR_LIB_UI, UI_R_SYSQIOW_ERROR}, + #else + {"SYSQIOW_ERROR", 40, 111}, + #endif + #ifdef UI_R_UNKNOWN_CONTROL_COMMAND + {"UNKNOWN_CONTROL_COMMAND", ERR_LIB_UI, UI_R_UNKNOWN_CONTROL_COMMAND}, + #else + {"UNKNOWN_CONTROL_COMMAND", 40, 106}, + #endif + #ifdef UI_R_UNKNOWN_TTYGET_ERRNO_VALUE + {"UNKNOWN_TTYGET_ERRNO_VALUE", ERR_LIB_UI, UI_R_UNKNOWN_TTYGET_ERRNO_VALUE}, + #else + {"UNKNOWN_TTYGET_ERRNO_VALUE", 40, 108}, + #endif + #ifdef UI_R_USER_DATA_DUPLICATION_UNSUPPORTED + {"USER_DATA_DUPLICATION_UNSUPPORTED", ERR_LIB_UI, UI_R_USER_DATA_DUPLICATION_UNSUPPORTED}, + #else + {"USER_DATA_DUPLICATION_UNSUPPORTED", 40, 112}, + #endif + #ifdef X509V3_R_BAD_IP_ADDRESS + {"BAD_IP_ADDRESS", ERR_LIB_X509V3, X509V3_R_BAD_IP_ADDRESS}, + #else + {"BAD_IP_ADDRESS", 34, 118}, + #endif + #ifdef X509V3_R_BAD_OBJECT + {"BAD_OBJECT", ERR_LIB_X509V3, X509V3_R_BAD_OBJECT}, + #else + {"BAD_OBJECT", 34, 119}, + #endif + #ifdef X509V3_R_BN_DEC2BN_ERROR + {"BN_DEC2BN_ERROR", ERR_LIB_X509V3, X509V3_R_BN_DEC2BN_ERROR}, + #else + {"BN_DEC2BN_ERROR", 34, 100}, + #endif + #ifdef X509V3_R_BN_TO_ASN1_INTEGER_ERROR + {"BN_TO_ASN1_INTEGER_ERROR", ERR_LIB_X509V3, X509V3_R_BN_TO_ASN1_INTEGER_ERROR}, + #else + {"BN_TO_ASN1_INTEGER_ERROR", 34, 101}, + #endif + #ifdef X509V3_R_DIRNAME_ERROR + {"DIRNAME_ERROR", ERR_LIB_X509V3, X509V3_R_DIRNAME_ERROR}, + #else + {"DIRNAME_ERROR", 34, 149}, + #endif + #ifdef X509V3_R_DISTPOINT_ALREADY_SET + {"DISTPOINT_ALREADY_SET", ERR_LIB_X509V3, X509V3_R_DISTPOINT_ALREADY_SET}, + #else + {"DISTPOINT_ALREADY_SET", 34, 160}, + #endif + #ifdef X509V3_R_DUPLICATE_ZONE_ID + {"DUPLICATE_ZONE_ID", ERR_LIB_X509V3, X509V3_R_DUPLICATE_ZONE_ID}, + #else + {"DUPLICATE_ZONE_ID", 34, 133}, + #endif + #ifdef X509V3_R_EMPTY_KEY_USAGE + {"EMPTY_KEY_USAGE", ERR_LIB_X509V3, X509V3_R_EMPTY_KEY_USAGE}, + #else + {"EMPTY_KEY_USAGE", 34, 169}, + #endif + #ifdef X509V3_R_ERROR_CONVERTING_ZONE + {"ERROR_CONVERTING_ZONE", ERR_LIB_X509V3, X509V3_R_ERROR_CONVERTING_ZONE}, + #else + {"ERROR_CONVERTING_ZONE", 34, 131}, + #endif + #ifdef X509V3_R_ERROR_CREATING_EXTENSION + {"ERROR_CREATING_EXTENSION", ERR_LIB_X509V3, X509V3_R_ERROR_CREATING_EXTENSION}, + #else + {"ERROR_CREATING_EXTENSION", 34, 144}, + #endif + #ifdef X509V3_R_ERROR_IN_EXTENSION + {"ERROR_IN_EXTENSION", ERR_LIB_X509V3, X509V3_R_ERROR_IN_EXTENSION}, + #else + {"ERROR_IN_EXTENSION", 34, 128}, + #endif + #ifdef X509V3_R_EXPECTED_A_SECTION_NAME + {"EXPECTED_A_SECTION_NAME", ERR_LIB_X509V3, X509V3_R_EXPECTED_A_SECTION_NAME}, + #else + {"EXPECTED_A_SECTION_NAME", 34, 137}, + #endif + #ifdef X509V3_R_EXTENSION_EXISTS + {"EXTENSION_EXISTS", ERR_LIB_X509V3, X509V3_R_EXTENSION_EXISTS}, + #else + {"EXTENSION_EXISTS", 34, 145}, + #endif + #ifdef X509V3_R_EXTENSION_NAME_ERROR + {"EXTENSION_NAME_ERROR", ERR_LIB_X509V3, X509V3_R_EXTENSION_NAME_ERROR}, + #else + {"EXTENSION_NAME_ERROR", 34, 115}, + #endif + #ifdef X509V3_R_EXTENSION_NOT_FOUND + {"EXTENSION_NOT_FOUND", ERR_LIB_X509V3, X509V3_R_EXTENSION_NOT_FOUND}, + #else + {"EXTENSION_NOT_FOUND", 34, 102}, + #endif + #ifdef X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED + {"EXTENSION_SETTING_NOT_SUPPORTED", ERR_LIB_X509V3, X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED}, + #else + {"EXTENSION_SETTING_NOT_SUPPORTED", 34, 103}, + #endif + #ifdef X509V3_R_EXTENSION_VALUE_ERROR + {"EXTENSION_VALUE_ERROR", ERR_LIB_X509V3, X509V3_R_EXTENSION_VALUE_ERROR}, + #else + {"EXTENSION_VALUE_ERROR", 34, 116}, + #endif + #ifdef X509V3_R_ILLEGAL_EMPTY_EXTENSION + {"ILLEGAL_EMPTY_EXTENSION", ERR_LIB_X509V3, X509V3_R_ILLEGAL_EMPTY_EXTENSION}, + #else + {"ILLEGAL_EMPTY_EXTENSION", 34, 151}, + #endif + #ifdef X509V3_R_INCORRECT_POLICY_SYNTAX_TAG + {"INCORRECT_POLICY_SYNTAX_TAG", ERR_LIB_X509V3, X509V3_R_INCORRECT_POLICY_SYNTAX_TAG}, + #else + {"INCORRECT_POLICY_SYNTAX_TAG", 34, 152}, + #endif + #ifdef X509V3_R_INVALID_ASNUMBER + {"INVALID_ASNUMBER", ERR_LIB_X509V3, X509V3_R_INVALID_ASNUMBER}, + #else + {"INVALID_ASNUMBER", 34, 162}, + #endif + #ifdef X509V3_R_INVALID_ASRANGE + {"INVALID_ASRANGE", ERR_LIB_X509V3, X509V3_R_INVALID_ASRANGE}, + #else + {"INVALID_ASRANGE", 34, 163}, + #endif + #ifdef X509V3_R_INVALID_BOOLEAN_STRING + {"INVALID_BOOLEAN_STRING", ERR_LIB_X509V3, X509V3_R_INVALID_BOOLEAN_STRING}, + #else + {"INVALID_BOOLEAN_STRING", 34, 104}, + #endif + #ifdef X509V3_R_INVALID_CERTIFICATE + {"INVALID_CERTIFICATE", ERR_LIB_X509V3, X509V3_R_INVALID_CERTIFICATE}, + #else + {"INVALID_CERTIFICATE", 34, 158}, + #endif + #ifdef X509V3_R_INVALID_EMPTY_NAME + {"INVALID_EMPTY_NAME", ERR_LIB_X509V3, X509V3_R_INVALID_EMPTY_NAME}, + #else + {"INVALID_EMPTY_NAME", 34, 108}, + #endif + #ifdef X509V3_R_INVALID_EXTENSION_STRING + {"INVALID_EXTENSION_STRING", ERR_LIB_X509V3, X509V3_R_INVALID_EXTENSION_STRING}, + #else + {"INVALID_EXTENSION_STRING", 34, 105}, + #endif + #ifdef X509V3_R_INVALID_INHERITANCE + {"INVALID_INHERITANCE", ERR_LIB_X509V3, X509V3_R_INVALID_INHERITANCE}, + #else + {"INVALID_INHERITANCE", 34, 165}, + #endif + #ifdef X509V3_R_INVALID_IPADDRESS + {"INVALID_IPADDRESS", ERR_LIB_X509V3, X509V3_R_INVALID_IPADDRESS}, + #else + {"INVALID_IPADDRESS", 34, 166}, + #endif + #ifdef X509V3_R_INVALID_MULTIPLE_RDNS + {"INVALID_MULTIPLE_RDNS", ERR_LIB_X509V3, X509V3_R_INVALID_MULTIPLE_RDNS}, + #else + {"INVALID_MULTIPLE_RDNS", 34, 161}, + #endif + #ifdef X509V3_R_INVALID_NAME + {"INVALID_NAME", ERR_LIB_X509V3, X509V3_R_INVALID_NAME}, + #else + {"INVALID_NAME", 34, 106}, + #endif + #ifdef X509V3_R_INVALID_NULL_ARGUMENT + {"INVALID_NULL_ARGUMENT", ERR_LIB_X509V3, X509V3_R_INVALID_NULL_ARGUMENT}, + #else + {"INVALID_NULL_ARGUMENT", 34, 107}, + #endif + #ifdef X509V3_R_INVALID_NULL_VALUE + {"INVALID_NULL_VALUE", ERR_LIB_X509V3, X509V3_R_INVALID_NULL_VALUE}, + #else + {"INVALID_NULL_VALUE", 34, 109}, + #endif + #ifdef X509V3_R_INVALID_NUMBER + {"INVALID_NUMBER", ERR_LIB_X509V3, X509V3_R_INVALID_NUMBER}, + #else + {"INVALID_NUMBER", 34, 140}, + #endif + #ifdef X509V3_R_INVALID_NUMBERS + {"INVALID_NUMBERS", ERR_LIB_X509V3, X509V3_R_INVALID_NUMBERS}, + #else + {"INVALID_NUMBERS", 34, 141}, + #endif + #ifdef X509V3_R_INVALID_OBJECT_IDENTIFIER + {"INVALID_OBJECT_IDENTIFIER", ERR_LIB_X509V3, X509V3_R_INVALID_OBJECT_IDENTIFIER}, + #else + {"INVALID_OBJECT_IDENTIFIER", 34, 110}, + #endif + #ifdef X509V3_R_INVALID_OPTION + {"INVALID_OPTION", ERR_LIB_X509V3, X509V3_R_INVALID_OPTION}, + #else + {"INVALID_OPTION", 34, 138}, + #endif + #ifdef X509V3_R_INVALID_POLICY_IDENTIFIER + {"INVALID_POLICY_IDENTIFIER", ERR_LIB_X509V3, X509V3_R_INVALID_POLICY_IDENTIFIER}, + #else + {"INVALID_POLICY_IDENTIFIER", 34, 134}, + #endif + #ifdef X509V3_R_INVALID_PROXY_POLICY_SETTING + {"INVALID_PROXY_POLICY_SETTING", ERR_LIB_X509V3, X509V3_R_INVALID_PROXY_POLICY_SETTING}, + #else + {"INVALID_PROXY_POLICY_SETTING", 34, 153}, + #endif + #ifdef X509V3_R_INVALID_PURPOSE + {"INVALID_PURPOSE", ERR_LIB_X509V3, X509V3_R_INVALID_PURPOSE}, + #else + {"INVALID_PURPOSE", 34, 146}, + #endif + #ifdef X509V3_R_INVALID_SAFI + {"INVALID_SAFI", ERR_LIB_X509V3, X509V3_R_INVALID_SAFI}, + #else + {"INVALID_SAFI", 34, 164}, + #endif + #ifdef X509V3_R_INVALID_SECTION + {"INVALID_SECTION", ERR_LIB_X509V3, X509V3_R_INVALID_SECTION}, + #else + {"INVALID_SECTION", 34, 135}, + #endif + #ifdef X509V3_R_INVALID_SYNTAX + {"INVALID_SYNTAX", ERR_LIB_X509V3, X509V3_R_INVALID_SYNTAX}, + #else + {"INVALID_SYNTAX", 34, 143}, + #endif + #ifdef X509V3_R_ISSUER_DECODE_ERROR + {"ISSUER_DECODE_ERROR", ERR_LIB_X509V3, X509V3_R_ISSUER_DECODE_ERROR}, + #else + {"ISSUER_DECODE_ERROR", 34, 126}, + #endif + #ifdef X509V3_R_MISSING_VALUE + {"MISSING_VALUE", ERR_LIB_X509V3, X509V3_R_MISSING_VALUE}, + #else + {"MISSING_VALUE", 34, 124}, + #endif + #ifdef X509V3_R_NEED_ORGANIZATION_AND_NUMBERS + {"NEED_ORGANIZATION_AND_NUMBERS", ERR_LIB_X509V3, X509V3_R_NEED_ORGANIZATION_AND_NUMBERS}, + #else + {"NEED_ORGANIZATION_AND_NUMBERS", 34, 142}, + #endif + #ifdef X509V3_R_NEGATIVE_PATHLEN + {"NEGATIVE_PATHLEN", ERR_LIB_X509V3, X509V3_R_NEGATIVE_PATHLEN}, + #else + {"NEGATIVE_PATHLEN", 34, 168}, + #endif + #ifdef X509V3_R_NO_CONFIG_DATABASE + {"NO_CONFIG_DATABASE", ERR_LIB_X509V3, X509V3_R_NO_CONFIG_DATABASE}, + #else + {"NO_CONFIG_DATABASE", 34, 136}, + #endif + #ifdef X509V3_R_NO_ISSUER_CERTIFICATE + {"NO_ISSUER_CERTIFICATE", ERR_LIB_X509V3, X509V3_R_NO_ISSUER_CERTIFICATE}, + #else + {"NO_ISSUER_CERTIFICATE", 34, 121}, + #endif + #ifdef X509V3_R_NO_ISSUER_DETAILS + {"NO_ISSUER_DETAILS", ERR_LIB_X509V3, X509V3_R_NO_ISSUER_DETAILS}, + #else + {"NO_ISSUER_DETAILS", 34, 127}, + #endif + #ifdef X509V3_R_NO_POLICY_IDENTIFIER + {"NO_POLICY_IDENTIFIER", ERR_LIB_X509V3, X509V3_R_NO_POLICY_IDENTIFIER}, + #else + {"NO_POLICY_IDENTIFIER", 34, 139}, + #endif + #ifdef X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED + {"NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED", ERR_LIB_X509V3, X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED}, + #else + {"NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED", 34, 154}, + #endif + #ifdef X509V3_R_NO_PUBLIC_KEY + {"NO_PUBLIC_KEY", ERR_LIB_X509V3, X509V3_R_NO_PUBLIC_KEY}, + #else + {"NO_PUBLIC_KEY", 34, 114}, + #endif + #ifdef X509V3_R_NO_SUBJECT_DETAILS + {"NO_SUBJECT_DETAILS", ERR_LIB_X509V3, X509V3_R_NO_SUBJECT_DETAILS}, + #else + {"NO_SUBJECT_DETAILS", 34, 125}, + #endif + #ifdef X509V3_R_OPERATION_NOT_DEFINED + {"OPERATION_NOT_DEFINED", ERR_LIB_X509V3, X509V3_R_OPERATION_NOT_DEFINED}, + #else + {"OPERATION_NOT_DEFINED", 34, 148}, + #endif + #ifdef X509V3_R_OTHERNAME_ERROR + {"OTHERNAME_ERROR", ERR_LIB_X509V3, X509V3_R_OTHERNAME_ERROR}, + #else + {"OTHERNAME_ERROR", 34, 147}, + #endif + #ifdef X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED + {"POLICY_LANGUAGE_ALREADY_DEFINED", ERR_LIB_X509V3, X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED}, + #else + {"POLICY_LANGUAGE_ALREADY_DEFINED", 34, 155}, + #endif + #ifdef X509V3_R_POLICY_PATH_LENGTH + {"POLICY_PATH_LENGTH", ERR_LIB_X509V3, X509V3_R_POLICY_PATH_LENGTH}, + #else + {"POLICY_PATH_LENGTH", 34, 156}, + #endif + #ifdef X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED + {"POLICY_PATH_LENGTH_ALREADY_DEFINED", ERR_LIB_X509V3, X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED}, + #else + {"POLICY_PATH_LENGTH_ALREADY_DEFINED", 34, 157}, + #endif + #ifdef X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY + {"POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY", ERR_LIB_X509V3, X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY}, + #else + {"POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY", 34, 159}, + #endif + #ifdef X509V3_R_SECTION_NOT_FOUND + {"SECTION_NOT_FOUND", ERR_LIB_X509V3, X509V3_R_SECTION_NOT_FOUND}, + #else + {"SECTION_NOT_FOUND", 34, 150}, + #endif + #ifdef X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS + {"UNABLE_TO_GET_ISSUER_DETAILS", ERR_LIB_X509V3, X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS}, + #else + {"UNABLE_TO_GET_ISSUER_DETAILS", 34, 122}, + #endif + #ifdef X509V3_R_UNABLE_TO_GET_ISSUER_KEYID + {"UNABLE_TO_GET_ISSUER_KEYID", ERR_LIB_X509V3, X509V3_R_UNABLE_TO_GET_ISSUER_KEYID}, + #else + {"UNABLE_TO_GET_ISSUER_KEYID", 34, 123}, + #endif + #ifdef X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT + {"UNKNOWN_BIT_STRING_ARGUMENT", ERR_LIB_X509V3, X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT}, + #else + {"UNKNOWN_BIT_STRING_ARGUMENT", 34, 111}, + #endif + #ifdef X509V3_R_UNKNOWN_EXTENSION + {"UNKNOWN_EXTENSION", ERR_LIB_X509V3, X509V3_R_UNKNOWN_EXTENSION}, + #else + {"UNKNOWN_EXTENSION", 34, 129}, + #endif + #ifdef X509V3_R_UNKNOWN_EXTENSION_NAME + {"UNKNOWN_EXTENSION_NAME", ERR_LIB_X509V3, X509V3_R_UNKNOWN_EXTENSION_NAME}, + #else + {"UNKNOWN_EXTENSION_NAME", 34, 130}, + #endif + #ifdef X509V3_R_UNKNOWN_OPTION + {"UNKNOWN_OPTION", ERR_LIB_X509V3, X509V3_R_UNKNOWN_OPTION}, + #else + {"UNKNOWN_OPTION", 34, 120}, + #endif + #ifdef X509V3_R_UNSUPPORTED_OPTION + {"UNSUPPORTED_OPTION", ERR_LIB_X509V3, X509V3_R_UNSUPPORTED_OPTION}, + #else + {"UNSUPPORTED_OPTION", 34, 117}, + #endif + #ifdef X509V3_R_UNSUPPORTED_TYPE + {"UNSUPPORTED_TYPE", ERR_LIB_X509V3, X509V3_R_UNSUPPORTED_TYPE}, + #else + {"UNSUPPORTED_TYPE", 34, 167}, + #endif + #ifdef X509V3_R_USER_TOO_LONG + {"USER_TOO_LONG", ERR_LIB_X509V3, X509V3_R_USER_TOO_LONG}, + #else + {"USER_TOO_LONG", 34, 132}, + #endif + #ifdef X509_R_AKID_MISMATCH + {"AKID_MISMATCH", ERR_LIB_X509, X509_R_AKID_MISMATCH}, + #else + {"AKID_MISMATCH", 11, 110}, + #endif + #ifdef X509_R_BAD_SELECTOR + {"BAD_SELECTOR", ERR_LIB_X509, X509_R_BAD_SELECTOR}, + #else + {"BAD_SELECTOR", 11, 133}, + #endif + #ifdef X509_R_BAD_X509_FILETYPE + {"BAD_X509_FILETYPE", ERR_LIB_X509, X509_R_BAD_X509_FILETYPE}, + #else + {"BAD_X509_FILETYPE", 11, 100}, + #endif + #ifdef X509_R_BASE64_DECODE_ERROR + {"BASE64_DECODE_ERROR", ERR_LIB_X509, X509_R_BASE64_DECODE_ERROR}, + #else + {"BASE64_DECODE_ERROR", 11, 118}, + #endif + #ifdef X509_R_CANT_CHECK_DH_KEY + {"CANT_CHECK_DH_KEY", ERR_LIB_X509, X509_R_CANT_CHECK_DH_KEY}, + #else + {"CANT_CHECK_DH_KEY", 11, 114}, + #endif + #ifdef X509_R_CERTIFICATE_VERIFICATION_FAILED + {"CERTIFICATE_VERIFICATION_FAILED", ERR_LIB_X509, X509_R_CERTIFICATE_VERIFICATION_FAILED}, + #else + {"CERTIFICATE_VERIFICATION_FAILED", 11, 139}, + #endif + #ifdef X509_R_CERT_ALREADY_IN_HASH_TABLE + {"CERT_ALREADY_IN_HASH_TABLE", ERR_LIB_X509, X509_R_CERT_ALREADY_IN_HASH_TABLE}, + #else + {"CERT_ALREADY_IN_HASH_TABLE", 11, 101}, + #endif + #ifdef X509_R_CRL_ALREADY_DELTA + {"CRL_ALREADY_DELTA", ERR_LIB_X509, X509_R_CRL_ALREADY_DELTA}, + #else + {"CRL_ALREADY_DELTA", 11, 127}, + #endif + #ifdef X509_R_CRL_VERIFY_FAILURE + {"CRL_VERIFY_FAILURE", ERR_LIB_X509, X509_R_CRL_VERIFY_FAILURE}, + #else + {"CRL_VERIFY_FAILURE", 11, 131}, + #endif + #ifdef X509_R_ERROR_GETTING_MD_BY_NID + {"ERROR_GETTING_MD_BY_NID", ERR_LIB_X509, X509_R_ERROR_GETTING_MD_BY_NID}, + #else + {"ERROR_GETTING_MD_BY_NID", 11, 141}, + #endif + #ifdef X509_R_ERROR_USING_SIGINF_SET + {"ERROR_USING_SIGINF_SET", ERR_LIB_X509, X509_R_ERROR_USING_SIGINF_SET}, + #else + {"ERROR_USING_SIGINF_SET", 11, 142}, + #endif + #ifdef X509_R_IDP_MISMATCH + {"IDP_MISMATCH", ERR_LIB_X509, X509_R_IDP_MISMATCH}, + #else + {"IDP_MISMATCH", 11, 128}, + #endif + #ifdef X509_R_INVALID_ATTRIBUTES + {"INVALID_ATTRIBUTES", ERR_LIB_X509, X509_R_INVALID_ATTRIBUTES}, + #else + {"INVALID_ATTRIBUTES", 11, 138}, + #endif + #ifdef X509_R_INVALID_DIRECTORY + {"INVALID_DIRECTORY", ERR_LIB_X509, X509_R_INVALID_DIRECTORY}, + #else + {"INVALID_DIRECTORY", 11, 113}, + #endif + #ifdef X509_R_INVALID_DISTPOINT + {"INVALID_DISTPOINT", ERR_LIB_X509, X509_R_INVALID_DISTPOINT}, + #else + {"INVALID_DISTPOINT", 11, 143}, + #endif + #ifdef X509_R_INVALID_FIELD_NAME + {"INVALID_FIELD_NAME", ERR_LIB_X509, X509_R_INVALID_FIELD_NAME}, + #else + {"INVALID_FIELD_NAME", 11, 119}, + #endif + #ifdef X509_R_INVALID_TRUST + {"INVALID_TRUST", ERR_LIB_X509, X509_R_INVALID_TRUST}, + #else + {"INVALID_TRUST", 11, 123}, + #endif + #ifdef X509_R_ISSUER_MISMATCH + {"ISSUER_MISMATCH", ERR_LIB_X509, X509_R_ISSUER_MISMATCH}, + #else + {"ISSUER_MISMATCH", 11, 129}, + #endif + #ifdef X509_R_KEY_TYPE_MISMATCH + {"KEY_TYPE_MISMATCH", ERR_LIB_X509, X509_R_KEY_TYPE_MISMATCH}, + #else + {"KEY_TYPE_MISMATCH", 11, 115}, + #endif + #ifdef X509_R_KEY_VALUES_MISMATCH + {"KEY_VALUES_MISMATCH", ERR_LIB_X509, X509_R_KEY_VALUES_MISMATCH}, + #else + {"KEY_VALUES_MISMATCH", 11, 116}, + #endif + #ifdef X509_R_LOADING_CERT_DIR + {"LOADING_CERT_DIR", ERR_LIB_X509, X509_R_LOADING_CERT_DIR}, + #else + {"LOADING_CERT_DIR", 11, 103}, + #endif + #ifdef X509_R_LOADING_DEFAULTS + {"LOADING_DEFAULTS", ERR_LIB_X509, X509_R_LOADING_DEFAULTS}, + #else + {"LOADING_DEFAULTS", 11, 104}, + #endif + #ifdef X509_R_METHOD_NOT_SUPPORTED + {"METHOD_NOT_SUPPORTED", ERR_LIB_X509, X509_R_METHOD_NOT_SUPPORTED}, + #else + {"METHOD_NOT_SUPPORTED", 11, 124}, + #endif + #ifdef X509_R_NAME_TOO_LONG + {"NAME_TOO_LONG", ERR_LIB_X509, X509_R_NAME_TOO_LONG}, + #else + {"NAME_TOO_LONG", 11, 134}, + #endif + #ifdef X509_R_NEWER_CRL_NOT_NEWER + {"NEWER_CRL_NOT_NEWER", ERR_LIB_X509, X509_R_NEWER_CRL_NOT_NEWER}, + #else + {"NEWER_CRL_NOT_NEWER", 11, 132}, + #endif + #ifdef X509_R_NO_CERTIFICATE_FOUND + {"NO_CERTIFICATE_FOUND", ERR_LIB_X509, X509_R_NO_CERTIFICATE_FOUND}, + #else + {"NO_CERTIFICATE_FOUND", 11, 135}, + #endif + #ifdef X509_R_NO_CERTIFICATE_OR_CRL_FOUND + {"NO_CERTIFICATE_OR_CRL_FOUND", ERR_LIB_X509, X509_R_NO_CERTIFICATE_OR_CRL_FOUND}, + #else + {"NO_CERTIFICATE_OR_CRL_FOUND", 11, 136}, + #endif + #ifdef X509_R_NO_CERT_SET_FOR_US_TO_VERIFY + {"NO_CERT_SET_FOR_US_TO_VERIFY", ERR_LIB_X509, X509_R_NO_CERT_SET_FOR_US_TO_VERIFY}, + #else + {"NO_CERT_SET_FOR_US_TO_VERIFY", 11, 105}, + #endif + #ifdef X509_R_NO_CRL_FOUND + {"NO_CRL_FOUND", ERR_LIB_X509, X509_R_NO_CRL_FOUND}, + #else + {"NO_CRL_FOUND", 11, 137}, + #endif + #ifdef X509_R_NO_CRL_NUMBER + {"NO_CRL_NUMBER", ERR_LIB_X509, X509_R_NO_CRL_NUMBER}, + #else + {"NO_CRL_NUMBER", 11, 130}, + #endif + #ifdef X509_R_PUBLIC_KEY_DECODE_ERROR + {"PUBLIC_KEY_DECODE_ERROR", ERR_LIB_X509, X509_R_PUBLIC_KEY_DECODE_ERROR}, + #else + {"PUBLIC_KEY_DECODE_ERROR", 11, 125}, + #endif + #ifdef X509_R_PUBLIC_KEY_ENCODE_ERROR + {"PUBLIC_KEY_ENCODE_ERROR", ERR_LIB_X509, X509_R_PUBLIC_KEY_ENCODE_ERROR}, + #else + {"PUBLIC_KEY_ENCODE_ERROR", 11, 126}, + #endif + #ifdef X509_R_SHOULD_RETRY + {"SHOULD_RETRY", ERR_LIB_X509, X509_R_SHOULD_RETRY}, + #else + {"SHOULD_RETRY", 11, 106}, + #endif + #ifdef X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN + {"UNABLE_TO_FIND_PARAMETERS_IN_CHAIN", ERR_LIB_X509, X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN}, + #else + {"UNABLE_TO_FIND_PARAMETERS_IN_CHAIN", 11, 107}, + #endif + #ifdef X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY + {"UNABLE_TO_GET_CERTS_PUBLIC_KEY", ERR_LIB_X509, X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY}, + #else + {"UNABLE_TO_GET_CERTS_PUBLIC_KEY", 11, 108}, + #endif + #ifdef X509_R_UNKNOWN_KEY_TYPE + {"UNKNOWN_KEY_TYPE", ERR_LIB_X509, X509_R_UNKNOWN_KEY_TYPE}, + #else + {"UNKNOWN_KEY_TYPE", 11, 117}, + #endif + #ifdef X509_R_UNKNOWN_NID + {"UNKNOWN_NID", ERR_LIB_X509, X509_R_UNKNOWN_NID}, + #else + {"UNKNOWN_NID", 11, 109}, + #endif + #ifdef X509_R_UNKNOWN_PURPOSE_ID + {"UNKNOWN_PURPOSE_ID", ERR_LIB_X509, X509_R_UNKNOWN_PURPOSE_ID}, + #else + {"UNKNOWN_PURPOSE_ID", 11, 121}, + #endif + #ifdef X509_R_UNKNOWN_SIGID_ALGS + {"UNKNOWN_SIGID_ALGS", ERR_LIB_X509, X509_R_UNKNOWN_SIGID_ALGS}, + #else + {"UNKNOWN_SIGID_ALGS", 11, 144}, + #endif + #ifdef X509_R_UNKNOWN_TRUST_ID + {"UNKNOWN_TRUST_ID", ERR_LIB_X509, X509_R_UNKNOWN_TRUST_ID}, + #else + {"UNKNOWN_TRUST_ID", 11, 120}, + #endif + #ifdef X509_R_UNSUPPORTED_ALGORITHM + {"UNSUPPORTED_ALGORITHM", ERR_LIB_X509, X509_R_UNSUPPORTED_ALGORITHM}, + #else + {"UNSUPPORTED_ALGORITHM", 11, 111}, + #endif + #ifdef X509_R_WRONG_LOOKUP_TYPE + {"WRONG_LOOKUP_TYPE", ERR_LIB_X509, X509_R_WRONG_LOOKUP_TYPE}, + #else + {"WRONG_LOOKUP_TYPE", 11, 112}, + #endif + #ifdef X509_R_WRONG_TYPE + {"WRONG_TYPE", ERR_LIB_X509, X509_R_WRONG_TYPE}, + #else + {"WRONG_TYPE", 11, 122}, + #endif + { NULL } +}; + diff --git a/Modules/_stat.c b/Modules/_stat.c index 546e6a5f..4ec2bd25 100644 --- a/Modules/_stat.c +++ b/Modules/_stat.c @@ -592,17 +592,17 @@ stat_exec(PyObject *module) ADD_INT_MACRO(module, FILE_ATTRIBUTE_TEMPORARY); ADD_INT_MACRO(module, FILE_ATTRIBUTE_VIRTUAL); - if (PyModule_AddObject(module, "IO_REPARSE_TAG_SYMLINK", - PyLong_FromUnsignedLong(IO_REPARSE_TAG_SYMLINK)) < 0) { - return -1; + if (_PyModule_Add(module, "IO_REPARSE_TAG_SYMLINK", + PyLong_FromUnsignedLong(IO_REPARSE_TAG_SYMLINK)) < 0) { + return -1; } - if (PyModule_AddObject(module, "IO_REPARSE_TAG_MOUNT_POINT", - PyLong_FromUnsignedLong(IO_REPARSE_TAG_MOUNT_POINT)) < 0) { - return -1; + if (_PyModule_Add(module, "IO_REPARSE_TAG_MOUNT_POINT", + PyLong_FromUnsignedLong(IO_REPARSE_TAG_MOUNT_POINT)) < 0) { + return -1; } - if (PyModule_AddObject(module, "IO_REPARSE_TAG_APPEXECLINK", - PyLong_FromUnsignedLong(IO_REPARSE_TAG_APPEXECLINK)) < 0) { - return -1; + if (_PyModule_Add(module, "IO_REPARSE_TAG_APPEXECLINK", + PyLong_FromUnsignedLong(IO_REPARSE_TAG_APPEXECLINK)) < 0) { + return -1; } #endif @@ -612,6 +612,7 @@ stat_exec(PyObject *module) static PyModuleDef_Slot stat_slots[] = { {Py_mod_exec, stat_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; diff --git a/Modules/_statisticsmodule.c b/Modules/_statisticsmodule.c index 78c0676a..1d5465fb 100644 --- a/Modules/_statisticsmodule.c +++ b/Modules/_statisticsmodule.c @@ -31,7 +31,7 @@ _statistics__normal_dist_inv_cdf_impl(PyObject *module, double p, double mu, /*[clinic end generated code: output=02fd19ddaab36602 input=24715a74be15296a]*/ { double q, num, den, r, x; - if (p <= 0.0 || p >= 1.0 || sigma <= 0.0) { + if (p <= 0.0 || p >= 1.0) { goto error; } @@ -129,6 +129,7 @@ PyDoc_STRVAR(statistics_doc, "Accelerators for the statistics module.\n"); static struct PyModuleDef_Slot _statisticsmodule_slots[] = { + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; diff --git a/Modules/_struct.c b/Modules/_struct.c index 9d66568a..4f9478bd 100644 --- a/Modules/_struct.c +++ b/Modules/_struct.c @@ -167,9 +167,6 @@ get_long(_structmodulestate *state, PyObject *v, long *p) x = PyLong_AsLong(v); Py_DECREF(v); if (x == (long)-1 && PyErr_Occurred()) { - if (PyErr_ExceptionMatches(PyExc_OverflowError)) - PyErr_SetString(state->StructError, - "argument out of range"); return -1; } *p = x; @@ -191,9 +188,6 @@ get_ulong(_structmodulestate *state, PyObject *v, unsigned long *p) x = PyLong_AsUnsignedLong(v); Py_DECREF(v); if (x == (unsigned long)-1 && PyErr_Occurred()) { - if (PyErr_ExceptionMatches(PyExc_OverflowError)) - PyErr_SetString(state->StructError, - "argument out of range"); return -1; } *p = x; @@ -214,9 +208,6 @@ get_longlong(_structmodulestate *state, PyObject *v, long long *p) x = PyLong_AsLongLong(v); Py_DECREF(v); if (x == (long long)-1 && PyErr_Occurred()) { - if (PyErr_ExceptionMatches(PyExc_OverflowError)) - PyErr_SetString(state->StructError, - "argument out of range"); return -1; } *p = x; @@ -237,9 +228,6 @@ get_ulonglong(_structmodulestate *state, PyObject *v, unsigned long long *p) x = PyLong_AsUnsignedLongLong(v); Py_DECREF(v); if (x == (unsigned long long)-1 && PyErr_Occurred()) { - if (PyErr_ExceptionMatches(PyExc_OverflowError)) - PyErr_SetString(state->StructError, - "argument out of range"); return -1; } *p = x; @@ -260,9 +248,6 @@ get_ssize_t(_structmodulestate *state, PyObject *v, Py_ssize_t *p) x = PyLong_AsSsize_t(v); Py_DECREF(v); if (x == (Py_ssize_t)-1 && PyErr_Occurred()) { - if (PyErr_ExceptionMatches(PyExc_OverflowError)) - PyErr_SetString(state->StructError, - "argument out of range"); return -1; } *p = x; @@ -283,9 +268,6 @@ get_size_t(_structmodulestate *state, PyObject *v, size_t *p) x = PyLong_AsSize_t(v); Py_DECREF(v); if (x == (size_t)-1 && PyErr_Occurred()) { - if (PyErr_ExceptionMatches(PyExc_OverflowError)) - PyErr_SetString(state->StructError, - "argument out of range"); return -1; } *p = x; @@ -293,7 +275,7 @@ get_size_t(_structmodulestate *state, PyObject *v, size_t *p) } -#define RANGE_ERROR(state, x, f, flag, mask) return _range_error(state, f, flag) +#define RANGE_ERROR(state, f, flag) return _range_error(state, f, flag) /* Floating point helpers */ @@ -545,12 +527,14 @@ static int np_byte(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) { long x; - if (get_long(state, v, &x) < 0) + if (get_long(state, v, &x) < 0) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) { + RANGE_ERROR(state, f, 0); + } return -1; + } if (x < -128 || x > 127) { - PyErr_SetString(state->StructError, - "byte format requires -128 <= number <= 127"); - return -1; + RANGE_ERROR(state, f, 0); } *p = (char)x; return 0; @@ -560,12 +544,14 @@ static int np_ubyte(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) { long x; - if (get_long(state, v, &x) < 0) + if (get_long(state, v, &x) < 0) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) { + RANGE_ERROR(state, f, 1); + } return -1; + } if (x < 0 || x > 255) { - PyErr_SetString(state->StructError, - "ubyte format requires 0 <= number <= 255"); - return -1; + RANGE_ERROR(state, f, 1); } *(unsigned char *)p = (unsigned char)x; return 0; @@ -588,13 +574,14 @@ np_short(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) { long x; short y; - if (get_long(state, v, &x) < 0) + if (get_long(state, v, &x) < 0) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) { + RANGE_ERROR(state, f, 0); + } return -1; + } if (x < SHRT_MIN || x > SHRT_MAX) { - PyErr_Format(state->StructError, - "short format requires %d <= number <= %d", - (int)SHRT_MIN, (int)SHRT_MAX); - return -1; + RANGE_ERROR(state, f, 0); } y = (short)x; memcpy(p, (char *)&y, sizeof y); @@ -606,13 +593,14 @@ np_ushort(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) { long x; unsigned short y; - if (get_long(state, v, &x) < 0) + if (get_long(state, v, &x) < 0) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) { + RANGE_ERROR(state, f, 1); + } return -1; + } if (x < 0 || x > USHRT_MAX) { - PyErr_Format(state->StructError, - "ushort format requires 0 <= number <= %u", - (unsigned int)USHRT_MAX); - return -1; + RANGE_ERROR(state, f, 1); } y = (unsigned short)x; memcpy(p, (char *)&y, sizeof y); @@ -624,11 +612,15 @@ np_int(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) { long x; int y; - if (get_long(state, v, &x) < 0) + if (get_long(state, v, &x) < 0) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) { + RANGE_ERROR(state, f, 0); + } return -1; + } #if (SIZEOF_LONG > SIZEOF_INT) if ((x < ((long)INT_MIN)) || (x > ((long)INT_MAX))) - RANGE_ERROR(state, x, f, 0, -1); + RANGE_ERROR(state, f, 0); #endif y = (int)x; memcpy(p, (char *)&y, sizeof y); @@ -640,12 +632,16 @@ np_uint(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) { unsigned long x; unsigned int y; - if (get_ulong(state, v, &x) < 0) + if (get_ulong(state, v, &x) < 0) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) { + RANGE_ERROR(state, f, 1); + } return -1; + } y = (unsigned int)x; #if (SIZEOF_LONG > SIZEOF_INT) if (x > ((unsigned long)UINT_MAX)) - RANGE_ERROR(state, y, f, 1, -1); + RANGE_ERROR(state, f, 1); #endif memcpy(p, (char *)&y, sizeof y); return 0; @@ -655,8 +651,12 @@ static int np_long(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) { long x; - if (get_long(state, v, &x) < 0) + if (get_long(state, v, &x) < 0) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) { + RANGE_ERROR(state, f, 0); + } return -1; + } memcpy(p, (char *)&x, sizeof x); return 0; } @@ -665,8 +665,12 @@ static int np_ulong(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) { unsigned long x; - if (get_ulong(state, v, &x) < 0) + if (get_ulong(state, v, &x) < 0) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) { + RANGE_ERROR(state, f, 1); + } return -1; + } memcpy(p, (char *)&x, sizeof x); return 0; } @@ -675,8 +679,12 @@ static int np_ssize_t(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) { Py_ssize_t x; - if (get_ssize_t(state, v, &x) < 0) + if (get_ssize_t(state, v, &x) < 0) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) { + RANGE_ERROR(state, f, 0); + } return -1; + } memcpy(p, (char *)&x, sizeof x); return 0; } @@ -685,8 +693,12 @@ static int np_size_t(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) { size_t x; - if (get_size_t(state, v, &x) < 0) + if (get_size_t(state, v, &x) < 0) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) { + RANGE_ERROR(state, f, 1); + } return -1; + } memcpy(p, (char *)&x, sizeof x); return 0; } @@ -695,8 +707,16 @@ static int np_longlong(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) { long long x; - if (get_longlong(state, v, &x) < 0) + if (get_longlong(state, v, &x) < 0) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) { + PyErr_Format(state->StructError, + "'%c' format requires %lld <= number <= %lld", + f->format, + LLONG_MIN, + LLONG_MAX); + } return -1; + } memcpy(p, (char *)&x, sizeof x); return 0; } @@ -705,8 +725,15 @@ static int np_ulonglong(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) { unsigned long long x; - if (get_ulonglong(state, v, &x) < 0) + if (get_ulonglong(state, v, &x) < 0) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) { + PyErr_Format(state->StructError, + "'%c' format requires 0 <= number <= %llu", + f->format, + ULLONG_MAX); + } return -1; + } memcpy(p, (char *)&x, sizeof x); return 0; } @@ -805,19 +832,38 @@ static const formatdef native_table[] = { /* Big-endian routines. *****************************************************/ +static PyObject * +bu_short(_structmodulestate *state, const char *p, const formatdef *f) +{ + unsigned long x = 0; + + /* This function is only ever used in the case f->size == 2. */ + assert(f->size == 2); + Py_ssize_t i = 2; + const unsigned char *bytes = (const unsigned char *)p; + do { + x = (x<<8) | *bytes++; + } while (--i > 0); + /* Extend sign, avoiding implementation-defined or undefined behaviour. */ + x = (x ^ 0x8000U) - 0x8000U; + return PyLong_FromLong(x & 0x8000U ? -1 - (long)(~x) : (long)x); +} + static PyObject * bu_int(_structmodulestate *state, const char *p, const formatdef *f) { - long x = 0; - Py_ssize_t i = f->size; + unsigned long x = 0; + + /* This function is only ever used in the case f->size == 4. */ + assert(f->size == 4); + Py_ssize_t i = 4; const unsigned char *bytes = (const unsigned char *)p; do { x = (x<<8) | *bytes++; } while (--i > 0); - /* Extend the sign bit. */ - if (SIZEOF_LONG > f->size) - x |= -(x & (1L << ((8 * f->size) - 1))); - return PyLong_FromLong(x); + /* Extend sign, avoiding implementation-defined or undefined behaviour. */ + x = (x ^ 0x80000000U) - 0x80000000U; + return PyLong_FromLong(x & 0x80000000U ? -1 - (long)(~x) : (long)x); } static PyObject * @@ -835,16 +881,19 @@ bu_uint(_structmodulestate *state, const char *p, const formatdef *f) static PyObject * bu_longlong(_structmodulestate *state, const char *p, const formatdef *f) { - long long x = 0; - Py_ssize_t i = f->size; + unsigned long long x = 0; + + /* This function is only ever used in the case f->size == 8. */ + assert(f->size == 8); + Py_ssize_t i = 8; const unsigned char *bytes = (const unsigned char *)p; do { x = (x<<8) | *bytes++; } while (--i > 0); - /* Extend the sign bit. */ - if (SIZEOF_LONG_LONG > f->size) - x |= -(x & ((long long)1 << ((8 * f->size) - 1))); - return PyLong_FromLongLong(x); + /* Extend sign, avoiding implementation-defined or undefined behaviour. */ + x = (x ^ 0x8000000000000000U) - 0x8000000000000000U; + return PyLong_FromLongLong( + x & 0x8000000000000000U ? -1 - (long long)(~x) : (long long)x); } static PyObject * @@ -889,15 +938,19 @@ bp_int(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) long x; Py_ssize_t i; unsigned char *q = (unsigned char *)p; - if (get_long(state, v, &x) < 0) + if (get_long(state, v, &x) < 0) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) { + RANGE_ERROR(state, f, 0); + } return -1; + } i = f->size; if (i != SIZEOF_LONG) { if ((i == 2) && (x < -32768 || x > 32767)) - RANGE_ERROR(state, x, f, 0, 0xffffL); + RANGE_ERROR(state, f, 0); #if (SIZEOF_LONG != 4) else if ((i == 4) && (x < -2147483648L || x > 2147483647L)) - RANGE_ERROR(state, x, f, 0, 0xffffffffL); + RANGE_ERROR(state, f, 0); #endif } do { @@ -913,14 +966,18 @@ bp_uint(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) unsigned long x; Py_ssize_t i; unsigned char *q = (unsigned char *)p; - if (get_ulong(state, v, &x) < 0) + if (get_ulong(state, v, &x) < 0) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) { + RANGE_ERROR(state, f, 1); + } return -1; + } i = f->size; if (i != SIZEOF_LONG) { unsigned long maxint = 1; maxint <<= (unsigned long)(i * 8); if (x >= maxint) - RANGE_ERROR(state, x, f, 1, maxint - 1); + RANGE_ERROR(state, f, 1); } do { q[--i] = (unsigned char)(x & 0xffUL); @@ -942,6 +999,14 @@ bp_longlong(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) 0, /* little_endian */ 1 /* signed */); Py_DECREF(v); + if (res == -1 && PyErr_Occurred()) { + PyErr_Format(state->StructError, + "'%c' format requires %lld <= number <= %lld", + f->format, + LLONG_MIN, + LLONG_MAX); + return -1; + } return res; } @@ -958,6 +1023,13 @@ bp_ulonglong(_structmodulestate *state, char *p, PyObject *v, const formatdef *f 0, /* little_endian */ 0 /* signed */); Py_DECREF(v); + if (res == -1 && PyErr_Occurred()) { + PyErr_Format(state->StructError, + "'%c' format requires 0 <= number <= %llu", + f->format, + ULLONG_MAX); + return -1; + } return res; } @@ -1009,7 +1081,7 @@ static formatdef bigendian_table[] = { {'c', 1, 0, nu_char, np_char}, {'s', 1, 0, NULL}, {'p', 1, 0, NULL}, - {'h', 2, 0, bu_int, bp_int}, + {'h', 2, 0, bu_short, bp_int}, {'H', 2, 0, bu_uint, bp_uint}, {'i', 4, 0, bu_int, bp_int}, {'I', 4, 0, bu_uint, bp_uint}, @@ -1026,19 +1098,38 @@ static formatdef bigendian_table[] = { /* Little-endian routines. *****************************************************/ +static PyObject * +lu_short(_structmodulestate *state, const char *p, const formatdef *f) +{ + unsigned long x = 0; + + /* This function is only ever used in the case f->size == 2. */ + assert(f->size == 2); + Py_ssize_t i = 2; + const unsigned char *bytes = (const unsigned char *)p; + do { + x = (x<<8) | bytes[--i]; + } while (i > 0); + /* Extend sign, avoiding implementation-defined or undefined behaviour. */ + x = (x ^ 0x8000U) - 0x8000U; + return PyLong_FromLong(x & 0x8000U ? -1 - (long)(~x) : (long)x); +} + static PyObject * lu_int(_structmodulestate *state, const char *p, const formatdef *f) { - long x = 0; - Py_ssize_t i = f->size; + unsigned long x = 0; + + /* This function is only ever used in the case f->size == 4. */ + assert(f->size == 4); + Py_ssize_t i = 4; const unsigned char *bytes = (const unsigned char *)p; do { x = (x<<8) | bytes[--i]; } while (i > 0); - /* Extend the sign bit. */ - if (SIZEOF_LONG > f->size) - x |= -(x & (1L << ((8 * f->size) - 1))); - return PyLong_FromLong(x); + /* Extend sign, avoiding implementation-defined or undefined behaviour. */ + x = (x ^ 0x80000000U) - 0x80000000U; + return PyLong_FromLong(x & 0x80000000U ? -1 - (long)(~x) : (long)x); } static PyObject * @@ -1056,16 +1147,19 @@ lu_uint(_structmodulestate *state, const char *p, const formatdef *f) static PyObject * lu_longlong(_structmodulestate *state, const char *p, const formatdef *f) { - long long x = 0; - Py_ssize_t i = f->size; + unsigned long long x = 0; + + /* This function is only ever used in the case f->size == 8. */ + assert(f->size == 8); + Py_ssize_t i = 8; const unsigned char *bytes = (const unsigned char *)p; do { x = (x<<8) | bytes[--i]; } while (i > 0); - /* Extend the sign bit. */ - if (SIZEOF_LONG_LONG > f->size) - x |= -(x & ((long long)1 << ((8 * f->size) - 1))); - return PyLong_FromLongLong(x); + /* Extend sign, avoiding implementation-defined or undefined behaviour. */ + x = (x ^ 0x8000000000000000U) - 0x8000000000000000U; + return PyLong_FromLongLong( + x & 0x8000000000000000U ? -1 - (long long)(~x) : (long long)x); } static PyObject * @@ -1104,15 +1198,19 @@ lp_int(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) long x; Py_ssize_t i; unsigned char *q = (unsigned char *)p; - if (get_long(state, v, &x) < 0) + if (get_long(state, v, &x) < 0) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) { + RANGE_ERROR(state, f, 0); + } return -1; + } i = f->size; if (i != SIZEOF_LONG) { if ((i == 2) && (x < -32768 || x > 32767)) - RANGE_ERROR(state, x, f, 0, 0xffffL); + RANGE_ERROR(state, f, 0); #if (SIZEOF_LONG != 4) else if ((i == 4) && (x < -2147483648L || x > 2147483647L)) - RANGE_ERROR(state, x, f, 0, 0xffffffffL); + RANGE_ERROR(state, f, 0); #endif } do { @@ -1128,14 +1226,18 @@ lp_uint(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) unsigned long x; Py_ssize_t i; unsigned char *q = (unsigned char *)p; - if (get_ulong(state, v, &x) < 0) + if (get_ulong(state, v, &x) < 0) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) { + RANGE_ERROR(state, f, 1); + } return -1; + } i = f->size; if (i != SIZEOF_LONG) { unsigned long maxint = 1; maxint <<= (unsigned long)(i * 8); if (x >= maxint) - RANGE_ERROR(state, x, f, 1, maxint - 1); + RANGE_ERROR(state, f, 1); } do { *q++ = (unsigned char)(x & 0xffUL); @@ -1157,6 +1259,14 @@ lp_longlong(_structmodulestate *state, char *p, PyObject *v, const formatdef *f) 1, /* little_endian */ 1 /* signed */); Py_DECREF(v); + if (res == -1 && PyErr_Occurred()) { + PyErr_Format(state->StructError, + "'%c' format requires %lld <= number <= %lld", + f->format, + LLONG_MIN, + LLONG_MAX); + return -1; + } return res; } @@ -1173,6 +1283,13 @@ lp_ulonglong(_structmodulestate *state, char *p, PyObject *v, const formatdef *f 1, /* little_endian */ 0 /* signed */); Py_DECREF(v); + if (res == -1 && PyErr_Occurred()) { + PyErr_Format(state->StructError, + "'%c' format requires 0 <= number <= %llu", + f->format, + ULLONG_MAX); + return -1; + } return res; } @@ -1213,7 +1330,7 @@ static formatdef lilendian_table[] = { {'c', 1, 0, nu_char, np_char}, {'s', 1, 0, NULL}, {'p', 1, 0, NULL}, - {'h', 2, 0, lu_int, lp_int}, + {'h', 2, 0, lu_short, lp_int}, {'H', 2, 0, lu_uint, lp_uint}, {'i', 4, 0, lu_int, lp_int}, {'I', 4, 0, lu_uint, lp_uint}, @@ -1433,28 +1550,9 @@ prepare_s(PyStructObject *self) return -1; } -static PyObject * -s_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - PyObject *self; - - assert(type != NULL); - allocfunc alloc_func = PyType_GetSlot(type, Py_tp_alloc); - assert(alloc_func != NULL); - - self = alloc_func(type, 0); - if (self != NULL) { - PyStructObject *s = (PyStructObject*)self; - s->s_format = Py_NewRef(Py_None); - s->s_codes = NULL; - s->s_size = -1; - s->s_len = -1; - } - return self; -} - /*[clinic input] -Struct.__init__ +@classmethod +Struct.__new__ format: object @@ -1466,16 +1564,24 @@ the format string. See help(struct) for more on format strings. [clinic start generated code]*/ -static int -Struct___init___impl(PyStructObject *self, PyObject *format) -/*[clinic end generated code: output=b8e80862444e92d0 input=192a4575a3dde802]*/ +static PyObject * +Struct_impl(PyTypeObject *type, PyObject *format) +/*[clinic end generated code: output=49468b044e334308 input=8b91868eb1df0e28]*/ { - int ret = 0; + allocfunc alloc = PyType_GetSlot(type, Py_tp_alloc); + assert(alloc != NULL); + PyStructObject *self = (PyStructObject *)alloc(type, 0); + + if (self == NULL) { + return NULL; + } if (PyUnicode_Check(format)) { format = PyUnicode_AsASCIIString(format); - if (format == NULL) - return -1; + if (format == NULL) { + Py_DECREF(self); + return NULL; + } } else { Py_INCREF(format); @@ -1483,19 +1589,24 @@ Struct___init___impl(PyStructObject *self, PyObject *format) if (!PyBytes_Check(format)) { Py_DECREF(format); + Py_DECREF(self); PyErr_Format(PyExc_TypeError, "Struct() argument 1 must be a str or bytes object, " "not %.200s", _PyType_Name(Py_TYPE(format))); - return -1; + return NULL; } - Py_SETREF(self->s_format, format); + self->s_format = format; - ret = prepare_s(self); - return ret; + if (prepare_s(self) < 0) { + Py_DECREF(self); + return NULL; + } + return (PyObject *)self; } + static int s_clear(PyStructObject *s) { @@ -1721,11 +1832,6 @@ unpackiter_iternext(unpackiterobject *self) return result; } -PyObject *unpackiter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { - PyErr_Format(PyExc_TypeError, "Cannot create '%.200s objects", _PyType_Name(type)); - return NULL; -} - static PyType_Slot unpackiter_type_slots[] = { {Py_tp_dealloc, unpackiter_dealloc}, {Py_tp_getattro, PyObject_GenericGetAttr}, @@ -1733,7 +1839,6 @@ static PyType_Slot unpackiter_type_slots[] = { {Py_tp_iter, PyObject_SelfIter}, {Py_tp_iternext, unpackiter_iternext}, {Py_tp_methods, unpackiter_methods}, - {Py_tp_new, unpackiter_new}, {0, 0}, }; @@ -1742,7 +1847,7 @@ static PyType_Spec unpackiter_type_spec = { sizeof(unpackiterobject), 0, (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_IMMUTABLETYPE), + Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_DISALLOW_INSTANTIATION), unpackiter_type_slots }; @@ -1791,8 +1896,7 @@ Struct_iter_unpack(PyStructObject *self, PyObject *buffer) Py_DECREF(iter); return NULL; } - Py_INCREF(self); - iter->so = self; + iter->so = (PyStructObject*)Py_NewRef(self); iter->index = 0; return (PyObject *)iter; } @@ -2053,13 +2157,11 @@ PyDoc_STRVAR(s_sizeof__doc__, static PyObject * s_sizeof(PyStructObject *self, void *unused) { - Py_ssize_t size; - formatcode *code; - - size = _PyObject_SIZE(Py_TYPE(self)) + sizeof(formatcode); - for (code = self->s_codes; code->fmtdef != NULL; code++) + size_t size = _PyObject_SIZE(Py_TYPE(self)) + sizeof(formatcode); + for (formatcode *code = self->s_codes; code->fmtdef != NULL; code++) { size += sizeof(formatcode); - return PyLong_FromSsize_t(size); + } + return PyLong_FromSize_t(size); } /* List of functions */ @@ -2100,9 +2202,8 @@ static PyType_Slot PyStructType_slots[] = { {Py_tp_methods, s_methods}, {Py_tp_members, s_members}, {Py_tp_getset, s_getsetlist}, - {Py_tp_init, Struct___init__}, + {Py_tp_new, Struct}, {Py_tp_alloc, PyType_GenericAlloc}, - {Py_tp_new, s_new}, {Py_tp_free, PyObject_GC_Del}, {0, 0}, }; @@ -2128,8 +2229,7 @@ cache_struct_converter(PyObject *module, PyObject *fmt, PyStructObject **ptr) _structmodulestate *state = get_struct_state(module); if (fmt == NULL) { - Py_DECREF(*ptr); - *ptr = NULL; + Py_SETREF(*ptr, NULL); return 1; } @@ -2141,8 +2241,7 @@ cache_struct_converter(PyObject *module, PyObject *fmt, PyStructObject **ptr) s_object = PyDict_GetItemWithError(state->cache, fmt); if (s_object != NULL) { - Py_INCREF(s_object); - *ptr = (PyStructObject *)s_object; + *ptr = (PyStructObject *)Py_NewRef(s_object); return Py_CLEANUP_SUPPORTED; } else if (PyErr_Occurred()) { @@ -2467,6 +2566,7 @@ _structmodule_exec(PyObject *m) static PyModuleDef_Slot _structmodule_slots[] = { {Py_mod_exec, _structmodule_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; diff --git a/Modules/_testbuffer.c b/Modules/_testbuffer.c index eea9d217..63ed4dc6 100644 --- a/Modules/_testbuffer.c +++ b/Modules/_testbuffer.c @@ -1524,8 +1524,7 @@ ndarray_getbuf(NDArrayObject *self, Py_buffer *view, int flags) return -1; } - view->obj = (PyObject *)self; - Py_INCREF(view->obj); + view->obj = Py_NewRef(self); self->head->exports++; return 0; @@ -1788,8 +1787,7 @@ ndarray_subscript(NDArrayObject *self, PyObject *key) return unpack_single(base->buf, base->format, base->itemsize); } else if (key == Py_Ellipsis) { - Py_INCREF(self); - return (PyObject *)self; + return Py_NewRef(self); } else { PyErr_SetString(PyExc_TypeError, "invalid indexing of scalar"); @@ -2021,8 +2019,7 @@ ndarray_get_obj(NDArrayObject *self, void *closure) if (base->obj == NULL) { Py_RETURN_NONE; } - Py_INCREF(base->obj); - return base->obj; + return Py_NewRef(base->obj); } static PyObject * @@ -2559,8 +2556,7 @@ result: PyBuffer_Release(&v2); ret = equal ? Py_True : Py_False; - Py_INCREF(ret); - return ret; + return Py_NewRef(ret); } static PyObject * @@ -2597,8 +2593,7 @@ is_contiguous(PyObject *self, PyObject *args) PyBuffer_Release(&view); } - Py_INCREF(ret); - return ret; + return Py_NewRef(ret); } static Py_hash_t @@ -2748,8 +2743,7 @@ staticarray_getbuf(StaticArrayObject *self, Py_buffer *view, int flags) view->obj = NULL; /* Don't use this in new code. */ } else { - view->obj = (PyObject *)self; - Py_INCREF(view->obj); + view->obj = Py_NewRef(self); } return 0; diff --git a/Modules/_testcapi/README.txt b/Modules/_testcapi/README.txt new file mode 100644 index 00000000..8a65e7ab --- /dev/null +++ b/Modules/_testcapi/README.txt @@ -0,0 +1,10 @@ +Tests in this directory are compiled into the _testcapi extension. +The main file for the extension is Modules/_testcapimodule.c, which +calls `_PyTestCapi_Init_*` from these functions. + +General guideline when writing test code for C API. +* Use Argument Clinic to minimise the amount of boilerplate code. +* Add a newline between the argument spec and the docstring. +* If a test description is needed, make sure the added docstring clearly and succinctly describes purpose of the function. +* DRY, use the clone feature of Argument Clinic. +* Try to avoid adding new interned strings; reuse existing parameter names if possible. Use the `as` feature of Argument Clinic to override the C variable name, if needed. diff --git a/Modules/_testcapi/abstract.c b/Modules/_testcapi/abstract.c new file mode 100644 index 00000000..38236aaf --- /dev/null +++ b/Modules/_testcapi/abstract.c @@ -0,0 +1,518 @@ +#include <stddef.h> // ptrdiff_t + +#define PY_SSIZE_T_CLEAN +#include "parts.h" +#include "util.h" + + +static PyObject * +object_getattr(PyObject *self, PyObject *args) +{ + PyObject *obj, *attr_name; + if (!PyArg_ParseTuple(args, "OO", &obj, &attr_name)) { + return NULL; + } + NULLABLE(obj); + NULLABLE(attr_name); + return PyObject_GetAttr(obj, attr_name); +} + +static PyObject * +object_getattrstring(PyObject *self, PyObject *args) +{ + PyObject *obj; + const char *attr_name; + Py_ssize_t size; + if (!PyArg_ParseTuple(args, "Oz#", &obj, &attr_name, &size)) { + return NULL; + } + NULLABLE(obj); + return PyObject_GetAttrString(obj, attr_name); +} + +static PyObject * +object_hasattr(PyObject *self, PyObject *args) +{ + PyObject *obj, *attr_name; + if (!PyArg_ParseTuple(args, "OO", &obj, &attr_name)) { + return NULL; + } + NULLABLE(obj); + NULLABLE(attr_name); + return PyLong_FromLong(PyObject_HasAttr(obj, attr_name)); +} + +static PyObject * +object_hasattrstring(PyObject *self, PyObject *args) +{ + PyObject *obj; + const char *attr_name; + Py_ssize_t size; + if (!PyArg_ParseTuple(args, "Oz#", &obj, &attr_name, &size)) { + return NULL; + } + NULLABLE(obj); + return PyLong_FromLong(PyObject_HasAttrString(obj, attr_name)); +} + +static PyObject * +object_setattr(PyObject *self, PyObject *args) +{ + PyObject *obj, *attr_name, *value; + if (!PyArg_ParseTuple(args, "OOO", &obj, &attr_name, &value)) { + return NULL; + } + NULLABLE(obj); + NULLABLE(attr_name); + NULLABLE(value); + RETURN_INT(PyObject_SetAttr(obj, attr_name, value)); +} + +static PyObject * +object_setattrstring(PyObject *self, PyObject *args) +{ + PyObject *obj, *value; + const char *attr_name; + Py_ssize_t size; + if (!PyArg_ParseTuple(args, "Oz#O", &obj, &attr_name, &size, &value)) { + return NULL; + } + NULLABLE(obj); + NULLABLE(value); + RETURN_INT(PyObject_SetAttrString(obj, attr_name, value)); +} + +static PyObject * +object_delattr(PyObject *self, PyObject *args) +{ + PyObject *obj, *attr_name; +if (!PyArg_ParseTuple(args, "OO", &obj, &attr_name)) { + return NULL; + } + NULLABLE(obj); + NULLABLE(attr_name); + RETURN_INT(PyObject_DelAttr(obj, attr_name)); +} + +static PyObject * +object_delattrstring(PyObject *self, PyObject *args) +{ + PyObject *obj; + const char *attr_name; + Py_ssize_t size; + if (!PyArg_ParseTuple(args, "Oz#", &obj, &attr_name, &size)) { + return NULL; + } + NULLABLE(obj); + RETURN_INT(PyObject_DelAttrString(obj, attr_name)); +} + + +static PyObject * +mapping_check(PyObject *self, PyObject *obj) +{ + NULLABLE(obj); + return PyLong_FromLong(PyMapping_Check(obj)); +} + +static PyObject * +mapping_size(PyObject *self, PyObject *obj) +{ + NULLABLE(obj); + RETURN_SIZE(PyMapping_Size(obj)); +} + +static PyObject * +mapping_length(PyObject *self, PyObject *obj) +{ + NULLABLE(obj); + RETURN_SIZE(PyMapping_Length(obj)); +} + +static PyObject * +object_getitem(PyObject *self, PyObject *args) +{ + PyObject *mapping, *key; + if (!PyArg_ParseTuple(args, "OO", &mapping, &key)) { + return NULL; + } + NULLABLE(mapping); + NULLABLE(key); + return PyObject_GetItem(mapping, key); +} + +static PyObject * +mapping_getitemstring(PyObject *self, PyObject *args) +{ + PyObject *mapping; + const char *key; + Py_ssize_t size; + if (!PyArg_ParseTuple(args, "Oz#", &mapping, &key, &size)) { + return NULL; + } + NULLABLE(mapping); + return PyMapping_GetItemString(mapping, key); +} + +static PyObject * +mapping_haskey(PyObject *self, PyObject *args) +{ + PyObject *mapping, *key; + if (!PyArg_ParseTuple(args, "OO", &mapping, &key)) { + return NULL; + } + NULLABLE(mapping); + NULLABLE(key); + return PyLong_FromLong(PyMapping_HasKey(mapping, key)); +} + +static PyObject * +mapping_haskeystring(PyObject *self, PyObject *args) +{ + PyObject *mapping; + const char *key; + Py_ssize_t size; + if (!PyArg_ParseTuple(args, "Oz#", &mapping, &key, &size)) { + return NULL; + } + NULLABLE(mapping); + return PyLong_FromLong(PyMapping_HasKeyString(mapping, key)); +} + +static PyObject * +object_setitem(PyObject *self, PyObject *args) +{ + PyObject *mapping, *key, *value; + if (!PyArg_ParseTuple(args, "OOO", &mapping, &key, &value)) { + return NULL; + } + NULLABLE(mapping); + NULLABLE(key); + NULLABLE(value); + RETURN_INT(PyObject_SetItem(mapping, key, value)); +} + +static PyObject * +mapping_setitemstring(PyObject *self, PyObject *args) +{ + PyObject *mapping, *value; + const char *key; + Py_ssize_t size; + if (!PyArg_ParseTuple(args, "Oz#O", &mapping, &key, &size, &value)) { + return NULL; + } + NULLABLE(mapping); + NULLABLE(value); + RETURN_INT(PyMapping_SetItemString(mapping, key, value)); +} + +static PyObject * +object_delitem(PyObject *self, PyObject *args) +{ + PyObject *mapping, *key; + if (!PyArg_ParseTuple(args, "OO", &mapping, &key)) { + return NULL; + } + NULLABLE(mapping); + NULLABLE(key); + RETURN_INT(PyObject_DelItem(mapping, key)); +} + +static PyObject * +mapping_delitem(PyObject *self, PyObject *args) +{ + PyObject *mapping, *key; + if (!PyArg_ParseTuple(args, "OO", &mapping, &key)) { + return NULL; + } + NULLABLE(mapping); + NULLABLE(key); + RETURN_INT(PyMapping_DelItem(mapping, key)); +} + +static PyObject * +mapping_delitemstring(PyObject *self, PyObject *args) +{ + PyObject *mapping; + const char *key; + Py_ssize_t size; + if (!PyArg_ParseTuple(args, "Oz#", &mapping, &key, &size)) { + return NULL; + } + NULLABLE(mapping); + RETURN_INT(PyMapping_DelItemString(mapping, key)); +} + +static PyObject * +mapping_keys(PyObject *self, PyObject *obj) +{ + NULLABLE(obj); + return PyMapping_Keys(obj); +} + +static PyObject * +mapping_values(PyObject *self, PyObject *obj) +{ + NULLABLE(obj); + return PyMapping_Values(obj); +} + +static PyObject * +mapping_items(PyObject *self, PyObject *obj) +{ + NULLABLE(obj); + return PyMapping_Items(obj); +} + + +static PyObject * +sequence_check(PyObject* self, PyObject *obj) +{ + NULLABLE(obj); + return PyLong_FromLong(PySequence_Check(obj)); +} + +static PyObject * +sequence_size(PyObject* self, PyObject *obj) +{ + NULLABLE(obj); + RETURN_SIZE(PySequence_Size(obj)); +} + +static PyObject * +sequence_length(PyObject* self, PyObject *obj) +{ + NULLABLE(obj); + RETURN_SIZE(PySequence_Length(obj)); +} + +static PyObject * +sequence_concat(PyObject *self, PyObject *args) +{ + PyObject *seq1, *seq2; + if (!PyArg_ParseTuple(args, "OO", &seq1, &seq2)) { + return NULL; + } + NULLABLE(seq1); + NULLABLE(seq2); + + return PySequence_Concat(seq1, seq2); +} + +static PyObject * +sequence_repeat(PyObject *self, PyObject *args) +{ + PyObject *seq; + Py_ssize_t count; + if (!PyArg_ParseTuple(args, "On", &seq, &count)) { + return NULL; + } + NULLABLE(seq); + + return PySequence_Repeat(seq, count); +} + +static PyObject * +sequence_inplaceconcat(PyObject *self, PyObject *args) +{ + PyObject *seq1, *seq2; + if (!PyArg_ParseTuple(args, "OO", &seq1, &seq2)) { + return NULL; + } + NULLABLE(seq1); + NULLABLE(seq2); + + return PySequence_InPlaceConcat(seq1, seq2); +} + +static PyObject * +sequence_inplacerepeat(PyObject *self, PyObject *args) +{ + PyObject *seq; + Py_ssize_t count; + if (!PyArg_ParseTuple(args, "On", &seq, &count)) { + return NULL; + } + NULLABLE(seq); + + return PySequence_InPlaceRepeat(seq, count); +} + +static PyObject * +sequence_getitem(PyObject *self, PyObject *args) +{ + PyObject *seq; + Py_ssize_t i; + if (!PyArg_ParseTuple(args, "On", &seq, &i)) { + return NULL; + } + NULLABLE(seq); + + return PySequence_GetItem(seq, i); +} + +static PyObject * +sequence_setitem(PyObject *self, PyObject *args) +{ + Py_ssize_t i; + PyObject *seq, *val; + if (!PyArg_ParseTuple(args, "OnO", &seq, &i, &val)) { + return NULL; + } + NULLABLE(seq); + NULLABLE(val); + + RETURN_INT(PySequence_SetItem(seq, i, val)); +} + + +static PyObject * +sequence_delitem(PyObject *self, PyObject *args) +{ + Py_ssize_t i; + PyObject *seq; + if (!PyArg_ParseTuple(args, "On", &seq, &i)) { + return NULL; + } + NULLABLE(seq); + + RETURN_INT(PySequence_DelItem(seq, i)); +} + +static PyObject * +sequence_setslice(PyObject* self, PyObject *args) +{ + PyObject *sequence, *obj; + Py_ssize_t i1, i2; + if (!PyArg_ParseTuple(args, "OnnO", &sequence, &i1, &i2, &obj)) { + return NULL; + } + NULLABLE(sequence); + NULLABLE(obj); + + RETURN_INT(PySequence_SetSlice(sequence, i1, i2, obj)); +} + +static PyObject * +sequence_delslice(PyObject *self, PyObject *args) +{ + PyObject *sequence; + Py_ssize_t i1, i2; + if (!PyArg_ParseTuple(args, "Onn", &sequence, &i1, &i2)) { + return NULL; + } + NULLABLE(sequence); + + RETURN_INT(PySequence_DelSlice(sequence, i1, i2)); +} + +static PyObject * +sequence_count(PyObject *self, PyObject *args) +{ + PyObject *seq, *value; + if (!PyArg_ParseTuple(args, "OO", &seq, &value)) { + return NULL; + } + NULLABLE(seq); + NULLABLE(value); + + RETURN_SIZE(PySequence_Count(seq, value)); +} + +static PyObject * +sequence_contains(PyObject *self, PyObject *args) +{ + PyObject *seq, *value; + if (!PyArg_ParseTuple(args, "OO", &seq, &value)) { + return NULL; + } + NULLABLE(seq); + NULLABLE(value); + + RETURN_INT(PySequence_Contains(seq, value)); +} + +static PyObject * +sequence_index(PyObject *self, PyObject *args) +{ + PyObject *seq, *value; + if (!PyArg_ParseTuple(args, "OO", &seq, &value)) { + return NULL; + } + NULLABLE(seq); + NULLABLE(value); + + RETURN_SIZE(PySequence_Index(seq, value)); +} + +static PyObject * +sequence_list(PyObject *self, PyObject *obj) +{ + NULLABLE(obj); + return PySequence_List(obj); +} + +static PyObject * +sequence_tuple(PyObject *self, PyObject *obj) +{ + NULLABLE(obj); + return PySequence_Tuple(obj); +} + + +static PyMethodDef test_methods[] = { + {"object_getattr", object_getattr, METH_VARARGS}, + {"object_getattrstring", object_getattrstring, METH_VARARGS}, + {"object_hasattr", object_hasattr, METH_VARARGS}, + {"object_hasattrstring", object_hasattrstring, METH_VARARGS}, + {"object_setattr", object_setattr, METH_VARARGS}, + {"object_setattrstring", object_setattrstring, METH_VARARGS}, + {"object_delattr", object_delattr, METH_VARARGS}, + {"object_delattrstring", object_delattrstring, METH_VARARGS}, + + {"mapping_check", mapping_check, METH_O}, + {"mapping_size", mapping_size, METH_O}, + {"mapping_length", mapping_length, METH_O}, + {"object_getitem", object_getitem, METH_VARARGS}, + {"mapping_getitemstring", mapping_getitemstring, METH_VARARGS}, + {"mapping_haskey", mapping_haskey, METH_VARARGS}, + {"mapping_haskeystring", mapping_haskeystring, METH_VARARGS}, + {"object_setitem", object_setitem, METH_VARARGS}, + {"mapping_setitemstring", mapping_setitemstring, METH_VARARGS}, + {"object_delitem", object_delitem, METH_VARARGS}, + {"mapping_delitem", mapping_delitem, METH_VARARGS}, + {"mapping_delitemstring", mapping_delitemstring, METH_VARARGS}, + {"mapping_keys", mapping_keys, METH_O}, + {"mapping_values", mapping_values, METH_O}, + {"mapping_items", mapping_items, METH_O}, + + {"sequence_check", sequence_check, METH_O}, + {"sequence_size", sequence_size, METH_O}, + {"sequence_length", sequence_length, METH_O}, + {"sequence_concat", sequence_concat, METH_VARARGS}, + {"sequence_repeat", sequence_repeat, METH_VARARGS}, + {"sequence_inplaceconcat", sequence_inplaceconcat, METH_VARARGS}, + {"sequence_inplacerepeat", sequence_inplacerepeat, METH_VARARGS}, + {"sequence_getitem", sequence_getitem, METH_VARARGS}, + {"sequence_setitem", sequence_setitem, METH_VARARGS}, + {"sequence_delitem", sequence_delitem, METH_VARARGS}, + {"sequence_setslice", sequence_setslice, METH_VARARGS}, + {"sequence_delslice", sequence_delslice, METH_VARARGS}, + {"sequence_count", sequence_count, METH_VARARGS}, + {"sequence_contains", sequence_contains, METH_VARARGS}, + {"sequence_index", sequence_index, METH_VARARGS}, + {"sequence_list", sequence_list, METH_O}, + {"sequence_tuple", sequence_tuple, METH_O}, + + {NULL}, +}; + +int +_PyTestCapi_Init_Abstract(PyObject *m) +{ + if (PyModule_AddFunctions(m, test_methods) < 0) { + return -1; + } + + return 0; +} diff --git a/Modules/_testcapi/buffer.c b/Modules/_testcapi/buffer.c new file mode 100644 index 00000000..aff9a477 --- /dev/null +++ b/Modules/_testcapi/buffer.c @@ -0,0 +1,102 @@ +/* Test PEP 688 - Buffers */ + +#include "parts.h" + +#include "structmember.h" // PyMemberDef +#include <stddef.h> // offsetof + +typedef struct { + PyObject_HEAD + PyObject *obj; + Py_ssize_t references; +} testBufObject; + +static PyObject * +testbuf_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyObject *obj = PyBytes_FromString("test"); + if (obj == NULL) { + return NULL; + } + testBufObject *self = (testBufObject *)type->tp_alloc(type, 0); + if (self == NULL) { + Py_DECREF(obj); + return NULL; + } + self->obj = obj; + self->references = 0; + return (PyObject *)self; +} + +static int +testbuf_traverse(testBufObject *self, visitproc visit, void *arg) +{ + Py_VISIT(self->obj); + return 0; +} + +static int +testbuf_clear(testBufObject *self) +{ + Py_CLEAR(self->obj); + return 0; +} + +static void +testbuf_dealloc(testBufObject *self) +{ + PyObject_GC_UnTrack(self); + Py_XDECREF(self->obj); + Py_TYPE(self)->tp_free((PyObject *) self); +} + +static int +testbuf_getbuf(testBufObject *self, Py_buffer *view, int flags) +{ + int buf = PyObject_GetBuffer(self->obj, view, flags); + Py_SETREF(view->obj, Py_NewRef(self)); + self->references++; + return buf; +} + +static void +testbuf_releasebuf(testBufObject *self, Py_buffer *view) +{ + self->references--; + assert(self->references >= 0); +} + +static PyBufferProcs testbuf_as_buffer = { + .bf_getbuffer = (getbufferproc) testbuf_getbuf, + .bf_releasebuffer = (releasebufferproc) testbuf_releasebuf, +}; + +static struct PyMemberDef testbuf_members[] = { + {"references", T_PYSSIZET, offsetof(testBufObject, references), READONLY}, + {NULL}, +}; + +static PyTypeObject testBufType = { + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name = "testBufType", + .tp_basicsize = sizeof(testBufObject), + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, + .tp_new = testbuf_new, + .tp_dealloc = (destructor) testbuf_dealloc, + .tp_traverse = (traverseproc) testbuf_traverse, + .tp_clear = (inquiry) testbuf_clear, + .tp_as_buffer = &testbuf_as_buffer, + .tp_members = testbuf_members +}; + +int +_PyTestCapi_Init_Buffer(PyObject *m) { + if (PyType_Ready(&testBufType) < 0) { + return -1; + } + if (PyModule_AddObjectRef(m, "testBuf", (PyObject *)&testBufType)) { + return -1; + } + + return 0; +} diff --git a/Modules/_testcapi/clinic/exceptions.c.h b/Modules/_testcapi/clinic/exceptions.c.h new file mode 100644 index 00000000..16954a5e --- /dev/null +++ b/Modules/_testcapi/clinic/exceptions.c.h @@ -0,0 +1,491 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + +PyDoc_STRVAR(_testcapi_err_set_raised__doc__, +"err_set_raised($module, exception, /)\n" +"--\n" +"\n"); + +#define _TESTCAPI_ERR_SET_RAISED_METHODDEF \ + {"err_set_raised", (PyCFunction)_testcapi_err_set_raised, METH_O, _testcapi_err_set_raised__doc__}, + +PyDoc_STRVAR(_testcapi_exception_print__doc__, +"exception_print($module, exception, legacy=False, /)\n" +"--\n" +"\n" +"To test the format of exceptions as printed out."); + +#define _TESTCAPI_EXCEPTION_PRINT_METHODDEF \ + {"exception_print", _PyCFunction_CAST(_testcapi_exception_print), METH_FASTCALL, _testcapi_exception_print__doc__}, + +static PyObject * +_testcapi_exception_print_impl(PyObject *module, PyObject *exc, int legacy); + +static PyObject * +_testcapi_exception_print(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *exc; + int legacy = 0; + + if (!_PyArg_CheckPositional("exception_print", nargs, 1, 2)) { + goto exit; + } + exc = args[0]; + if (nargs < 2) { + goto skip_optional; + } + legacy = PyObject_IsTrue(args[1]); + if (legacy < 0) { + goto exit; + } +skip_optional: + return_value = _testcapi_exception_print_impl(module, exc, legacy); + +exit: + return return_value; +} + +PyDoc_STRVAR(_testcapi_make_exception_with_doc__doc__, +"make_exception_with_doc($module, /, name, doc=<unrepresentable>,\n" +" base=<unrepresentable>, dict=<unrepresentable>)\n" +"--\n" +"\n" +"Test PyErr_NewExceptionWithDoc (also exercise PyErr_NewException). Run via Lib/test/test_exceptions.py"); + +#define _TESTCAPI_MAKE_EXCEPTION_WITH_DOC_METHODDEF \ + {"make_exception_with_doc", _PyCFunction_CAST(_testcapi_make_exception_with_doc), METH_FASTCALL|METH_KEYWORDS, _testcapi_make_exception_with_doc__doc__}, + +static PyObject * +_testcapi_make_exception_with_doc_impl(PyObject *module, const char *name, + const char *doc, PyObject *base, + PyObject *dict); + +static PyObject * +_testcapi_make_exception_with_doc(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(name), &_Py_ID(doc), &_Py_ID(base), &_Py_ID(dict), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"name", "doc", "base", "dict", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "make_exception_with_doc", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[4]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + const char *name; + const char *doc = NULL; + PyObject *base = NULL; + PyObject *dict = NULL; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 4, 0, argsbuf); + if (!args) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("make_exception_with_doc", "argument 'name'", "str", args[0]); + goto exit; + } + Py_ssize_t name_length; + name = PyUnicode_AsUTF8AndSize(args[0], &name_length); + if (name == NULL) { + goto exit; + } + if (strlen(name) != (size_t)name_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[1]) { + if (!PyUnicode_Check(args[1])) { + _PyArg_BadArgument("make_exception_with_doc", "argument 'doc'", "str", args[1]); + goto exit; + } + Py_ssize_t doc_length; + doc = PyUnicode_AsUTF8AndSize(args[1], &doc_length); + if (doc == NULL) { + goto exit; + } + if (strlen(doc) != (size_t)doc_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (args[2]) { + base = args[2]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + dict = args[3]; +skip_optional_pos: + return_value = _testcapi_make_exception_with_doc_impl(module, name, doc, base, dict); + +exit: + return return_value; +} + +PyDoc_STRVAR(_testcapi_exc_set_object__doc__, +"exc_set_object($module, exception, obj, /)\n" +"--\n" +"\n"); + +#define _TESTCAPI_EXC_SET_OBJECT_METHODDEF \ + {"exc_set_object", _PyCFunction_CAST(_testcapi_exc_set_object), METH_FASTCALL, _testcapi_exc_set_object__doc__}, + +static PyObject * +_testcapi_exc_set_object_impl(PyObject *module, PyObject *exc, PyObject *obj); + +static PyObject * +_testcapi_exc_set_object(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *exc; + PyObject *obj; + + if (!_PyArg_CheckPositional("exc_set_object", nargs, 2, 2)) { + goto exit; + } + exc = args[0]; + obj = args[1]; + return_value = _testcapi_exc_set_object_impl(module, exc, obj); + +exit: + return return_value; +} + +PyDoc_STRVAR(_testcapi_exc_set_object_fetch__doc__, +"exc_set_object_fetch($module, exception, obj, /)\n" +"--\n" +"\n"); + +#define _TESTCAPI_EXC_SET_OBJECT_FETCH_METHODDEF \ + {"exc_set_object_fetch", _PyCFunction_CAST(_testcapi_exc_set_object_fetch), METH_FASTCALL, _testcapi_exc_set_object_fetch__doc__}, + +static PyObject * +_testcapi_exc_set_object_fetch_impl(PyObject *module, PyObject *exc, + PyObject *obj); + +static PyObject * +_testcapi_exc_set_object_fetch(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *exc; + PyObject *obj; + + if (!_PyArg_CheckPositional("exc_set_object_fetch", nargs, 2, 2)) { + goto exit; + } + exc = args[0]; + obj = args[1]; + return_value = _testcapi_exc_set_object_fetch_impl(module, exc, obj); + +exit: + return return_value; +} + +PyDoc_STRVAR(_testcapi_err_setstring__doc__, +"err_setstring($module, exc, value, /)\n" +"--\n" +"\n"); + +#define _TESTCAPI_ERR_SETSTRING_METHODDEF \ + {"err_setstring", _PyCFunction_CAST(_testcapi_err_setstring), METH_FASTCALL, _testcapi_err_setstring__doc__}, + +static PyObject * +_testcapi_err_setstring_impl(PyObject *module, PyObject *exc, + const char *value, Py_ssize_t value_length); + +static PyObject * +_testcapi_err_setstring(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *exc; + const char *value; + Py_ssize_t value_length; + + if (!_PyArg_ParseStack(args, nargs, "Oz#:err_setstring", + &exc, &value, &value_length)) { + goto exit; + } + return_value = _testcapi_err_setstring_impl(module, exc, value, value_length); + +exit: + return return_value; +} + +PyDoc_STRVAR(_testcapi_err_setfromerrnowithfilename__doc__, +"err_setfromerrnowithfilename($module, error, exc, value, /)\n" +"--\n" +"\n"); + +#define _TESTCAPI_ERR_SETFROMERRNOWITHFILENAME_METHODDEF \ + {"err_setfromerrnowithfilename", _PyCFunction_CAST(_testcapi_err_setfromerrnowithfilename), METH_FASTCALL, _testcapi_err_setfromerrnowithfilename__doc__}, + +static PyObject * +_testcapi_err_setfromerrnowithfilename_impl(PyObject *module, int error, + PyObject *exc, const char *value, + Py_ssize_t value_length); + +static PyObject * +_testcapi_err_setfromerrnowithfilename(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int error; + PyObject *exc; + const char *value; + Py_ssize_t value_length; + + if (!_PyArg_ParseStack(args, nargs, "iOz#:err_setfromerrnowithfilename", + &error, &exc, &value, &value_length)) { + goto exit; + } + return_value = _testcapi_err_setfromerrnowithfilename_impl(module, error, exc, value, value_length); + +exit: + return return_value; +} + +PyDoc_STRVAR(_testcapi_raise_exception__doc__, +"raise_exception($module, exception, num_args, /)\n" +"--\n" +"\n"); + +#define _TESTCAPI_RAISE_EXCEPTION_METHODDEF \ + {"raise_exception", _PyCFunction_CAST(_testcapi_raise_exception), METH_FASTCALL, _testcapi_raise_exception__doc__}, + +static PyObject * +_testcapi_raise_exception_impl(PyObject *module, PyObject *exc, int num_args); + +static PyObject * +_testcapi_raise_exception(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *exc; + int num_args; + + if (!_PyArg_CheckPositional("raise_exception", nargs, 2, 2)) { + goto exit; + } + exc = args[0]; + num_args = _PyLong_AsInt(args[1]); + if (num_args == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = _testcapi_raise_exception_impl(module, exc, num_args); + +exit: + return return_value; +} + +PyDoc_STRVAR(_testcapi_raise_memoryerror__doc__, +"raise_memoryerror($module, /)\n" +"--\n" +"\n"); + +#define _TESTCAPI_RAISE_MEMORYERROR_METHODDEF \ + {"raise_memoryerror", (PyCFunction)_testcapi_raise_memoryerror, METH_NOARGS, _testcapi_raise_memoryerror__doc__}, + +static PyObject * +_testcapi_raise_memoryerror_impl(PyObject *module); + +static PyObject * +_testcapi_raise_memoryerror(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return _testcapi_raise_memoryerror_impl(module); +} + +PyDoc_STRVAR(_testcapi_fatal_error__doc__, +"fatal_error($module, message, release_gil=False, /)\n" +"--\n" +"\n"); + +#define _TESTCAPI_FATAL_ERROR_METHODDEF \ + {"fatal_error", _PyCFunction_CAST(_testcapi_fatal_error), METH_FASTCALL, _testcapi_fatal_error__doc__}, + +static PyObject * +_testcapi_fatal_error_impl(PyObject *module, const char *message, + int release_gil); + +static PyObject * +_testcapi_fatal_error(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + const char *message; + int release_gil = 0; + + if (!_PyArg_ParseStack(args, nargs, "y|p:fatal_error", + &message, &release_gil)) { + goto exit; + } + return_value = _testcapi_fatal_error_impl(module, message, release_gil); + +exit: + return return_value; +} + +PyDoc_STRVAR(_testcapi_set_exc_info__doc__, +"set_exc_info($module, new_type, new_value, new_tb, /)\n" +"--\n" +"\n"); + +#define _TESTCAPI_SET_EXC_INFO_METHODDEF \ + {"set_exc_info", _PyCFunction_CAST(_testcapi_set_exc_info), METH_FASTCALL, _testcapi_set_exc_info__doc__}, + +static PyObject * +_testcapi_set_exc_info_impl(PyObject *module, PyObject *new_type, + PyObject *new_value, PyObject *new_tb); + +static PyObject * +_testcapi_set_exc_info(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *new_type; + PyObject *new_value; + PyObject *new_tb; + + if (!_PyArg_CheckPositional("set_exc_info", nargs, 3, 3)) { + goto exit; + } + new_type = args[0]; + new_value = args[1]; + new_tb = args[2]; + return_value = _testcapi_set_exc_info_impl(module, new_type, new_value, new_tb); + +exit: + return return_value; +} + +PyDoc_STRVAR(_testcapi_set_exception__doc__, +"set_exception($module, new_exc, /)\n" +"--\n" +"\n"); + +#define _TESTCAPI_SET_EXCEPTION_METHODDEF \ + {"set_exception", (PyCFunction)_testcapi_set_exception, METH_O, _testcapi_set_exception__doc__}, + +PyDoc_STRVAR(_testcapi_write_unraisable_exc__doc__, +"write_unraisable_exc($module, exception, err_msg, obj, /)\n" +"--\n" +"\n"); + +#define _TESTCAPI_WRITE_UNRAISABLE_EXC_METHODDEF \ + {"write_unraisable_exc", _PyCFunction_CAST(_testcapi_write_unraisable_exc), METH_FASTCALL, _testcapi_write_unraisable_exc__doc__}, + +static PyObject * +_testcapi_write_unraisable_exc_impl(PyObject *module, PyObject *exc, + PyObject *err_msg, PyObject *obj); + +static PyObject * +_testcapi_write_unraisable_exc(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *exc; + PyObject *err_msg; + PyObject *obj; + + if (!_PyArg_CheckPositional("write_unraisable_exc", nargs, 3, 3)) { + goto exit; + } + exc = args[0]; + err_msg = args[1]; + obj = args[2]; + return_value = _testcapi_write_unraisable_exc_impl(module, exc, err_msg, obj); + +exit: + return return_value; +} + +PyDoc_STRVAR(_testcapi_traceback_print__doc__, +"traceback_print($module, traceback, file, /)\n" +"--\n" +"\n" +"To test the format of tracebacks as printed out."); + +#define _TESTCAPI_TRACEBACK_PRINT_METHODDEF \ + {"traceback_print", _PyCFunction_CAST(_testcapi_traceback_print), METH_FASTCALL, _testcapi_traceback_print__doc__}, + +static PyObject * +_testcapi_traceback_print_impl(PyObject *module, PyObject *traceback, + PyObject *file); + +static PyObject * +_testcapi_traceback_print(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *traceback; + PyObject *file; + + if (!_PyArg_CheckPositional("traceback_print", nargs, 2, 2)) { + goto exit; + } + traceback = args[0]; + file = args[1]; + return_value = _testcapi_traceback_print_impl(module, traceback, file); + +exit: + return return_value; +} + +PyDoc_STRVAR(_testcapi_unstable_exc_prep_reraise_star__doc__, +"unstable_exc_prep_reraise_star($module, orig, excs, /)\n" +"--\n" +"\n" +"To test PyUnstable_Exc_PrepReraiseStar."); + +#define _TESTCAPI_UNSTABLE_EXC_PREP_RERAISE_STAR_METHODDEF \ + {"unstable_exc_prep_reraise_star", _PyCFunction_CAST(_testcapi_unstable_exc_prep_reraise_star), METH_FASTCALL, _testcapi_unstable_exc_prep_reraise_star__doc__}, + +static PyObject * +_testcapi_unstable_exc_prep_reraise_star_impl(PyObject *module, + PyObject *orig, PyObject *excs); + +static PyObject * +_testcapi_unstable_exc_prep_reraise_star(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *orig; + PyObject *excs; + + if (!_PyArg_CheckPositional("unstable_exc_prep_reraise_star", nargs, 2, 2)) { + goto exit; + } + orig = args[0]; + excs = args[1]; + return_value = _testcapi_unstable_exc_prep_reraise_star_impl(module, orig, excs); + +exit: + return return_value; +} +/*[clinic end generated code: output=d574342d716e98b5 input=a9049054013a1b77]*/ diff --git a/Modules/_testcapi/clinic/float.c.h b/Modules/_testcapi/clinic/float.c.h new file mode 100644 index 00000000..c1dff2a9 --- /dev/null +++ b/Modules/_testcapi/clinic/float.c.h @@ -0,0 +1,88 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + +PyDoc_STRVAR(_testcapi_float_pack__doc__, +"float_pack($module, size, d, le, /)\n" +"--\n" +"\n" +"Test PyFloat_Pack2(), PyFloat_Pack4() and PyFloat_Pack8()"); + +#define _TESTCAPI_FLOAT_PACK_METHODDEF \ + {"float_pack", _PyCFunction_CAST(_testcapi_float_pack), METH_FASTCALL, _testcapi_float_pack__doc__}, + +static PyObject * +_testcapi_float_pack_impl(PyObject *module, int size, double d, int le); + +static PyObject * +_testcapi_float_pack(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int size; + double d; + int le; + + if (!_PyArg_CheckPositional("float_pack", nargs, 3, 3)) { + goto exit; + } + size = _PyLong_AsInt(args[0]); + if (size == -1 && PyErr_Occurred()) { + goto exit; + } + if (PyFloat_CheckExact(args[1])) { + d = PyFloat_AS_DOUBLE(args[1]); + } + else + { + d = PyFloat_AsDouble(args[1]); + if (d == -1.0 && PyErr_Occurred()) { + goto exit; + } + } + le = _PyLong_AsInt(args[2]); + if (le == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = _testcapi_float_pack_impl(module, size, d, le); + +exit: + return return_value; +} + +PyDoc_STRVAR(_testcapi_float_unpack__doc__, +"float_unpack($module, data, le, /)\n" +"--\n" +"\n" +"Test PyFloat_Unpack2(), PyFloat_Unpack4() and PyFloat_Unpack8()"); + +#define _TESTCAPI_FLOAT_UNPACK_METHODDEF \ + {"float_unpack", _PyCFunction_CAST(_testcapi_float_unpack), METH_FASTCALL, _testcapi_float_unpack__doc__}, + +static PyObject * +_testcapi_float_unpack_impl(PyObject *module, const char *data, + Py_ssize_t data_length, int le); + +static PyObject * +_testcapi_float_unpack(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + const char *data; + Py_ssize_t data_length; + int le; + + if (!_PyArg_ParseStack(args, nargs, "y#i:float_unpack", + &data, &data_length, &le)) { + goto exit; + } + return_value = _testcapi_float_unpack_impl(module, data, data_length, le); + +exit: + return return_value; +} +/*[clinic end generated code: output=083e5df26cd5fbeb input=a9049054013a1b77]*/ diff --git a/Modules/_testcapi/clinic/vectorcall.c.h b/Modules/_testcapi/clinic/vectorcall.c.h new file mode 100644 index 00000000..765afeda --- /dev/null +++ b/Modules/_testcapi/clinic/vectorcall.c.h @@ -0,0 +1,113 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + +PyDoc_STRVAR(_testcapi_VectorCallClass_set_vectorcall__doc__, +"set_vectorcall($self, type, /)\n" +"--\n" +"\n" +"Set self\'s vectorcall function for `type` to one that returns \"vectorcall\""); + +#define _TESTCAPI_VECTORCALLCLASS_SET_VECTORCALL_METHODDEF \ + {"set_vectorcall", (PyCFunction)_testcapi_VectorCallClass_set_vectorcall, METH_O, _testcapi_VectorCallClass_set_vectorcall__doc__}, + +static PyObject * +_testcapi_VectorCallClass_set_vectorcall_impl(PyObject *self, + PyTypeObject *type); + +static PyObject * +_testcapi_VectorCallClass_set_vectorcall(PyObject *self, PyObject *arg) +{ + PyObject *return_value = NULL; + PyTypeObject *type; + + if (!PyObject_TypeCheck(arg, &PyType_Type)) { + _PyArg_BadArgument("set_vectorcall", "argument", (&PyType_Type)->tp_name, arg); + goto exit; + } + type = (PyTypeObject *)arg; + return_value = _testcapi_VectorCallClass_set_vectorcall_impl(self, type); + +exit: + return return_value; +} + +PyDoc_STRVAR(_testcapi_make_vectorcall_class__doc__, +"make_vectorcall_class($module, base=<unrepresentable>, /)\n" +"--\n" +"\n" +"Create a class whose instances return \"tpcall\" when called.\n" +"\n" +"When the \"set_vectorcall\" method is called on an instance, a vectorcall\n" +"function that returns \"vectorcall\" will be installed."); + +#define _TESTCAPI_MAKE_VECTORCALL_CLASS_METHODDEF \ + {"make_vectorcall_class", _PyCFunction_CAST(_testcapi_make_vectorcall_class), METH_FASTCALL, _testcapi_make_vectorcall_class__doc__}, + +static PyObject * +_testcapi_make_vectorcall_class_impl(PyObject *module, PyTypeObject *base); + +static PyObject * +_testcapi_make_vectorcall_class(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyTypeObject *base = NULL; + + if (!_PyArg_CheckPositional("make_vectorcall_class", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + if (!PyObject_TypeCheck(args[0], &PyType_Type)) { + _PyArg_BadArgument("make_vectorcall_class", "argument 1", (&PyType_Type)->tp_name, args[0]); + goto exit; + } + base = (PyTypeObject *)args[0]; +skip_optional: + return_value = _testcapi_make_vectorcall_class_impl(module, base); + +exit: + return return_value; +} + +PyDoc_STRVAR(_testcapi_has_vectorcall_flag__doc__, +"has_vectorcall_flag($module, type, /)\n" +"--\n" +"\n" +"Return true iff Py_TPFLAGS_HAVE_VECTORCALL is set on the class."); + +#define _TESTCAPI_HAS_VECTORCALL_FLAG_METHODDEF \ + {"has_vectorcall_flag", (PyCFunction)_testcapi_has_vectorcall_flag, METH_O, _testcapi_has_vectorcall_flag__doc__}, + +static int +_testcapi_has_vectorcall_flag_impl(PyObject *module, PyTypeObject *type); + +static PyObject * +_testcapi_has_vectorcall_flag(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + PyTypeObject *type; + int _return_value; + + if (!PyObject_TypeCheck(arg, &PyType_Type)) { + _PyArg_BadArgument("has_vectorcall_flag", "argument", (&PyType_Type)->tp_name, arg); + goto exit; + } + type = (PyTypeObject *)arg; + _return_value = _testcapi_has_vectorcall_flag_impl(module, type); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyBool_FromLong((long)_return_value); + +exit: + return return_value; +} +/*[clinic end generated code: output=609569aa9942584f input=a9049054013a1b77]*/ diff --git a/Modules/_testcapi/clinic/watchers.c.h b/Modules/_testcapi/clinic/watchers.c.h new file mode 100644 index 00000000..975244bd --- /dev/null +++ b/Modules/_testcapi/clinic/watchers.c.h @@ -0,0 +1,198 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + +PyDoc_STRVAR(_testcapi_watch_dict__doc__, +"watch_dict($module, watcher_id, dict, /)\n" +"--\n" +"\n"); + +#define _TESTCAPI_WATCH_DICT_METHODDEF \ + {"watch_dict", _PyCFunction_CAST(_testcapi_watch_dict), METH_FASTCALL, _testcapi_watch_dict__doc__}, + +static PyObject * +_testcapi_watch_dict_impl(PyObject *module, int watcher_id, PyObject *dict); + +static PyObject * +_testcapi_watch_dict(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int watcher_id; + PyObject *dict; + + if (!_PyArg_CheckPositional("watch_dict", nargs, 2, 2)) { + goto exit; + } + watcher_id = _PyLong_AsInt(args[0]); + if (watcher_id == -1 && PyErr_Occurred()) { + goto exit; + } + dict = args[1]; + return_value = _testcapi_watch_dict_impl(module, watcher_id, dict); + +exit: + return return_value; +} + +PyDoc_STRVAR(_testcapi_unwatch_dict__doc__, +"unwatch_dict($module, watcher_id, dict, /)\n" +"--\n" +"\n"); + +#define _TESTCAPI_UNWATCH_DICT_METHODDEF \ + {"unwatch_dict", _PyCFunction_CAST(_testcapi_unwatch_dict), METH_FASTCALL, _testcapi_unwatch_dict__doc__}, + +static PyObject * +_testcapi_unwatch_dict_impl(PyObject *module, int watcher_id, PyObject *dict); + +static PyObject * +_testcapi_unwatch_dict(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int watcher_id; + PyObject *dict; + + if (!_PyArg_CheckPositional("unwatch_dict", nargs, 2, 2)) { + goto exit; + } + watcher_id = _PyLong_AsInt(args[0]); + if (watcher_id == -1 && PyErr_Occurred()) { + goto exit; + } + dict = args[1]; + return_value = _testcapi_unwatch_dict_impl(module, watcher_id, dict); + +exit: + return return_value; +} + +PyDoc_STRVAR(_testcapi_watch_type__doc__, +"watch_type($module, watcher_id, type, /)\n" +"--\n" +"\n"); + +#define _TESTCAPI_WATCH_TYPE_METHODDEF \ + {"watch_type", _PyCFunction_CAST(_testcapi_watch_type), METH_FASTCALL, _testcapi_watch_type__doc__}, + +static PyObject * +_testcapi_watch_type_impl(PyObject *module, int watcher_id, PyObject *type); + +static PyObject * +_testcapi_watch_type(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int watcher_id; + PyObject *type; + + if (!_PyArg_CheckPositional("watch_type", nargs, 2, 2)) { + goto exit; + } + watcher_id = _PyLong_AsInt(args[0]); + if (watcher_id == -1 && PyErr_Occurred()) { + goto exit; + } + type = args[1]; + return_value = _testcapi_watch_type_impl(module, watcher_id, type); + +exit: + return return_value; +} + +PyDoc_STRVAR(_testcapi_unwatch_type__doc__, +"unwatch_type($module, watcher_id, type, /)\n" +"--\n" +"\n"); + +#define _TESTCAPI_UNWATCH_TYPE_METHODDEF \ + {"unwatch_type", _PyCFunction_CAST(_testcapi_unwatch_type), METH_FASTCALL, _testcapi_unwatch_type__doc__}, + +static PyObject * +_testcapi_unwatch_type_impl(PyObject *module, int watcher_id, PyObject *type); + +static PyObject * +_testcapi_unwatch_type(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int watcher_id; + PyObject *type; + + if (!_PyArg_CheckPositional("unwatch_type", nargs, 2, 2)) { + goto exit; + } + watcher_id = _PyLong_AsInt(args[0]); + if (watcher_id == -1 && PyErr_Occurred()) { + goto exit; + } + type = args[1]; + return_value = _testcapi_unwatch_type_impl(module, watcher_id, type); + +exit: + return return_value; +} + +PyDoc_STRVAR(_testcapi_set_func_defaults_via_capi__doc__, +"set_func_defaults_via_capi($module, func, defaults, /)\n" +"--\n" +"\n"); + +#define _TESTCAPI_SET_FUNC_DEFAULTS_VIA_CAPI_METHODDEF \ + {"set_func_defaults_via_capi", _PyCFunction_CAST(_testcapi_set_func_defaults_via_capi), METH_FASTCALL, _testcapi_set_func_defaults_via_capi__doc__}, + +static PyObject * +_testcapi_set_func_defaults_via_capi_impl(PyObject *module, PyObject *func, + PyObject *defaults); + +static PyObject * +_testcapi_set_func_defaults_via_capi(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *func; + PyObject *defaults; + + if (!_PyArg_CheckPositional("set_func_defaults_via_capi", nargs, 2, 2)) { + goto exit; + } + func = args[0]; + defaults = args[1]; + return_value = _testcapi_set_func_defaults_via_capi_impl(module, func, defaults); + +exit: + return return_value; +} + +PyDoc_STRVAR(_testcapi_set_func_kwdefaults_via_capi__doc__, +"set_func_kwdefaults_via_capi($module, func, defaults, /)\n" +"--\n" +"\n"); + +#define _TESTCAPI_SET_FUNC_KWDEFAULTS_VIA_CAPI_METHODDEF \ + {"set_func_kwdefaults_via_capi", _PyCFunction_CAST(_testcapi_set_func_kwdefaults_via_capi), METH_FASTCALL, _testcapi_set_func_kwdefaults_via_capi__doc__}, + +static PyObject * +_testcapi_set_func_kwdefaults_via_capi_impl(PyObject *module, PyObject *func, + PyObject *defaults); + +static PyObject * +_testcapi_set_func_kwdefaults_via_capi(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *func; + PyObject *defaults; + + if (!_PyArg_CheckPositional("set_func_kwdefaults_via_capi", nargs, 2, 2)) { + goto exit; + } + func = args[0]; + defaults = args[1]; + return_value = _testcapi_set_func_kwdefaults_via_capi_impl(module, func, defaults); + +exit: + return return_value; +} +/*[clinic end generated code: output=12c375089125d165 input=a9049054013a1b77]*/ diff --git a/Modules/_testcapi/code.c b/Modules/_testcapi/code.c new file mode 100644 index 00000000..8287268b --- /dev/null +++ b/Modules/_testcapi/code.c @@ -0,0 +1,121 @@ +#include "parts.h" +#include "util.h" + +static Py_ssize_t +get_code_extra_index(PyInterpreterState* interp) { + Py_ssize_t result = -1; + + static const char *key = "_testcapi.frame_evaluation.code_index"; + + PyObject *interp_dict = PyInterpreterState_GetDict(interp); // borrowed + assert(interp_dict); // real users would handle missing dict... somehow + + PyObject *index_obj = _PyDict_GetItemStringWithError(interp_dict, key); // borrowed + Py_ssize_t index = 0; + if (!index_obj) { + if (PyErr_Occurred()) { + goto finally; + } + index = PyUnstable_Eval_RequestCodeExtraIndex(NULL); + if (index < 0 || PyErr_Occurred()) { + goto finally; + } + index_obj = PyLong_FromSsize_t(index); // strong ref + if (!index_obj) { + goto finally; + } + int res = PyDict_SetItemString(interp_dict, key, index_obj); + Py_DECREF(index_obj); + if (res < 0) { + goto finally; + } + } + else { + index = PyLong_AsSsize_t(index_obj); + if (index == -1 && PyErr_Occurred()) { + goto finally; + } + } + + result = index; +finally: + return result; +} + +static PyObject * +test_code_extra(PyObject* self, PyObject *Py_UNUSED(callable)) +{ + PyObject *result = NULL; + PyObject *test_module = NULL; + PyObject *test_func = NULL; + + // Get or initialize interpreter-specific code object storage index + PyInterpreterState *interp = PyInterpreterState_Get(); + if (!interp) { + return NULL; + } + Py_ssize_t code_extra_index = get_code_extra_index(interp); + if (PyErr_Occurred()) { + goto finally; + } + + // Get a function to test with + // This can be any Python function. Use `test.test_misc.testfunction`. + test_module = PyImport_ImportModule("test.test_capi.test_misc"); + if (!test_module) { + goto finally; + } + test_func = PyObject_GetAttrString(test_module, "testfunction"); + if (!test_func) { + goto finally; + } + PyObject *test_func_code = PyFunction_GetCode(test_func); // borrowed + if (!test_func_code) { + goto finally; + } + + // Check the value is initially NULL + void *extra = UNINITIALIZED_PTR; + int res = PyUnstable_Code_GetExtra(test_func_code, code_extra_index, &extra); + if (res < 0) { + goto finally; + } + assert (extra == NULL); + + // Set another code extra value + res = PyUnstable_Code_SetExtra(test_func_code, code_extra_index, (void*)(uintptr_t)77); + if (res < 0) { + goto finally; + } + // Assert it was set correctly + extra = UNINITIALIZED_PTR; + res = PyUnstable_Code_GetExtra(test_func_code, code_extra_index, &extra); + if (res < 0) { + goto finally; + } + assert ((uintptr_t)extra == 77); + // Revert to initial code extra value. + res = PyUnstable_Code_SetExtra(test_func_code, code_extra_index, NULL); + if (res < 0) { + goto finally; + } + result = Py_NewRef(Py_None); +finally: + Py_XDECREF(test_module); + Py_XDECREF(test_func); + return result; +} + +static PyMethodDef TestMethods[] = { + {"test_code_extra", test_code_extra, METH_NOARGS}, + {NULL}, +}; + +int +_PyTestCapi_Init_Code(PyObject *m) { + if (PyModule_AddFunctions(m, TestMethods) < 0) { + return -1; + } + + return 0; +} diff --git a/Modules/_testcapi/datetime.c b/Modules/_testcapi/datetime.c new file mode 100644 index 00000000..88f99291 --- /dev/null +++ b/Modules/_testcapi/datetime.c @@ -0,0 +1,451 @@ +#include "parts.h" + +#include "datetime.h" // PyDateTimeAPI + + +static int test_run_counter = 0; + +static PyObject * +test_datetime_capi(PyObject *self, PyObject *args) +{ + if (PyDateTimeAPI) { + if (test_run_counter) { + /* Probably regrtest.py -R */ + Py_RETURN_NONE; + } + else { + PyErr_SetString(PyExc_AssertionError, + "PyDateTime_CAPI somehow initialized"); + return NULL; + } + } + test_run_counter++; + PyDateTime_IMPORT; + + if (PyDateTimeAPI) { + Py_RETURN_NONE; + } + return NULL; +} + +/* Functions exposing the C API type checking for testing */ +#define MAKE_DATETIME_CHECK_FUNC(check_method, exact_method) \ +do { \ + PyObject *obj; \ + int exact = 0; \ + if (!PyArg_ParseTuple(args, "O|p", &obj, &exact)) { \ + return NULL; \ + } \ + int rv = exact?exact_method(obj):check_method(obj); \ + if (rv) { \ + Py_RETURN_TRUE; \ + } \ + Py_RETURN_FALSE; \ +} while (0) \ + +static PyObject * +datetime_check_date(PyObject *self, PyObject *args) +{ + MAKE_DATETIME_CHECK_FUNC(PyDate_Check, PyDate_CheckExact); +} + +static PyObject * +datetime_check_time(PyObject *self, PyObject *args) +{ + MAKE_DATETIME_CHECK_FUNC(PyTime_Check, PyTime_CheckExact); +} + +static PyObject * +datetime_check_datetime(PyObject *self, PyObject *args) +{ + MAKE_DATETIME_CHECK_FUNC(PyDateTime_Check, PyDateTime_CheckExact); +} + +static PyObject * +datetime_check_delta(PyObject *self, PyObject *args) +{ + MAKE_DATETIME_CHECK_FUNC(PyDelta_Check, PyDelta_CheckExact); +} + +static PyObject * +datetime_check_tzinfo(PyObject *self, PyObject *args) +{ + MAKE_DATETIME_CHECK_FUNC(PyTZInfo_Check, PyTZInfo_CheckExact); +} +#undef MAKE_DATETIME_CHECK_FUNC + + +/* Makes three variations on timezone representing UTC-5: + 1. timezone with offset and name from PyDateTimeAPI + 2. timezone with offset and name from PyTimeZone_FromOffsetAndName + 3. timezone with offset (no name) from PyTimeZone_FromOffset +*/ +static PyObject * +make_timezones_capi(PyObject *self, PyObject *args) +{ + PyObject *offset = PyDelta_FromDSU(0, -18000, 0); + PyObject *name = PyUnicode_FromString("EST"); + + PyObject *est_zone_capi = PyDateTimeAPI->TimeZone_FromTimeZone(offset, name); + PyObject *est_zone_macro = PyTimeZone_FromOffsetAndName(offset, name); + PyObject *est_zone_macro_noname = PyTimeZone_FromOffset(offset); + + Py_DecRef(offset); + Py_DecRef(name); + + PyObject *rv = PyTuple_New(3); + if (rv == NULL) { + return NULL; + } + + PyTuple_SET_ITEM(rv, 0, est_zone_capi); + PyTuple_SET_ITEM(rv, 1, est_zone_macro); + PyTuple_SET_ITEM(rv, 2, est_zone_macro_noname); + + return rv; +} + +static PyObject * +get_timezones_offset_zero(PyObject *self, PyObject *args) +{ + PyObject *offset = PyDelta_FromDSU(0, 0, 0); + PyObject *name = PyUnicode_FromString(""); + + // These two should return the UTC singleton + PyObject *utc_singleton_0 = PyTimeZone_FromOffset(offset); + PyObject *utc_singleton_1 = PyTimeZone_FromOffsetAndName(offset, NULL); + + // This one will return +00:00 zone, but not the UTC singleton + PyObject *non_utc_zone = PyTimeZone_FromOffsetAndName(offset, name); + + Py_DecRef(offset); + Py_DecRef(name); + + PyObject *rv = PyTuple_New(3); + PyTuple_SET_ITEM(rv, 0, utc_singleton_0); + PyTuple_SET_ITEM(rv, 1, utc_singleton_1); + PyTuple_SET_ITEM(rv, 2, non_utc_zone); + + return rv; +} + +static PyObject * +get_timezone_utc_capi(PyObject *self, PyObject *args) +{ + int macro = 0; + if (!PyArg_ParseTuple(args, "|p", ¯o)) { + return NULL; + } + if (macro) { + return Py_NewRef(PyDateTime_TimeZone_UTC); + } + return Py_NewRef(PyDateTimeAPI->TimeZone_UTC); +} + +static PyObject * +get_date_fromdate(PyObject *self, PyObject *args) +{ + PyObject *rv = NULL; + int macro; + int year, month, day; + + if (!PyArg_ParseTuple(args, "piii", ¯o, &year, &month, &day)) { + return NULL; + } + + if (macro) { + rv = PyDate_FromDate(year, month, day); + } + else { + rv = PyDateTimeAPI->Date_FromDate( + year, month, day, + PyDateTimeAPI->DateType); + } + return rv; +} + +static PyObject * +get_datetime_fromdateandtime(PyObject *self, PyObject *args) +{ + PyObject *rv = NULL; + int macro; + int year, month, day; + int hour, minute, second, microsecond; + + if (!PyArg_ParseTuple(args, "piiiiiii", + ¯o, + &year, &month, &day, + &hour, &minute, &second, µsecond)) { + return NULL; + } + + if (macro) { + rv = PyDateTime_FromDateAndTime( + year, month, day, + hour, minute, second, microsecond); + } + else { + rv = PyDateTimeAPI->DateTime_FromDateAndTime( + year, month, day, + hour, minute, second, microsecond, + Py_None, + PyDateTimeAPI->DateTimeType); + } + return rv; +} + +static PyObject * +get_datetime_fromdateandtimeandfold(PyObject *self, PyObject *args) +{ + PyObject *rv = NULL; + int macro; + int year, month, day; + int hour, minute, second, microsecond, fold; + + if (!PyArg_ParseTuple(args, "piiiiiiii", + ¯o, + &year, &month, &day, + &hour, &minute, &second, µsecond, + &fold)) { + return NULL; + } + + if (macro) { + rv = PyDateTime_FromDateAndTimeAndFold( + year, month, day, + hour, minute, second, microsecond, + fold); + } + else { + rv = PyDateTimeAPI->DateTime_FromDateAndTimeAndFold( + year, month, day, + hour, minute, second, microsecond, + Py_None, + fold, + PyDateTimeAPI->DateTimeType); + } + return rv; +} + +static PyObject * +get_time_fromtime(PyObject *self, PyObject *args) +{ + PyObject *rv = NULL; + int macro; + int hour, minute, second, microsecond; + + if (!PyArg_ParseTuple(args, "piiii", + ¯o, + &hour, &minute, &second, µsecond)) + { + return NULL; + } + + if (macro) { + rv = PyTime_FromTime(hour, minute, second, microsecond); + } + else { + rv = PyDateTimeAPI->Time_FromTime( + hour, minute, second, microsecond, + Py_None, + PyDateTimeAPI->TimeType); + } + return rv; +} + +static PyObject * +get_time_fromtimeandfold(PyObject *self, PyObject *args) +{ + PyObject *rv = NULL; + int macro; + int hour, minute, second, microsecond, fold; + + if (!PyArg_ParseTuple(args, "piiiii", + ¯o, + &hour, &minute, &second, µsecond, + &fold)) { + return NULL; + } + + if (macro) { + rv = PyTime_FromTimeAndFold(hour, minute, second, microsecond, fold); + } + else { + rv = PyDateTimeAPI->Time_FromTimeAndFold( + hour, minute, second, microsecond, + Py_None, + fold, + PyDateTimeAPI->TimeType); + } + return rv; +} + +static PyObject * +get_delta_fromdsu(PyObject *self, PyObject *args) +{ + PyObject *rv = NULL; + int macro; + int days, seconds, microseconds; + + if (!PyArg_ParseTuple(args, "piii", + ¯o, + &days, &seconds, µseconds)) { + return NULL; + } + + if (macro) { + rv = PyDelta_FromDSU(days, seconds, microseconds); + } + else { + rv = PyDateTimeAPI->Delta_FromDelta( + days, seconds, microseconds, 1, + PyDateTimeAPI->DeltaType); + } + + return rv; +} + +static PyObject * +get_date_fromtimestamp(PyObject *self, PyObject *args) +{ + PyObject *tsargs = NULL, *ts = NULL, *rv = NULL; + int macro = 0; + + if (!PyArg_ParseTuple(args, "O|p", &ts, ¯o)) { + return NULL; + } + + // Construct the argument tuple + if ((tsargs = PyTuple_Pack(1, ts)) == NULL) { + return NULL; + } + + // Pass along to the API function + if (macro) { + rv = PyDate_FromTimestamp(tsargs); + } + else { + rv = PyDateTimeAPI->Date_FromTimestamp( + (PyObject *)PyDateTimeAPI->DateType, tsargs + ); + } + + Py_DECREF(tsargs); + return rv; +} + +static PyObject * +get_datetime_fromtimestamp(PyObject *self, PyObject *args) +{ + int macro = 0; + int usetz = 0; + PyObject *tsargs = NULL, *ts = NULL, *tzinfo = Py_None, *rv = NULL; + if (!PyArg_ParseTuple(args, "OO|pp", &ts, &tzinfo, &usetz, ¯o)) { + return NULL; + } + + // Construct the argument tuple + if (usetz) { + tsargs = PyTuple_Pack(2, ts, tzinfo); + } + else { + tsargs = PyTuple_Pack(1, ts); + } + + if (tsargs == NULL) { + return NULL; + } + + // Pass along to the API function + if (macro) { + rv = PyDateTime_FromTimestamp(tsargs); + } + else { + rv = PyDateTimeAPI->DateTime_FromTimestamp( + (PyObject *)PyDateTimeAPI->DateTimeType, tsargs, NULL + ); + } + + Py_DECREF(tsargs); + return rv; +} + +static PyObject * +test_PyDateTime_GET(PyObject *self, PyObject *obj) +{ + int year, month, day; + + year = PyDateTime_GET_YEAR(obj); + month = PyDateTime_GET_MONTH(obj); + day = PyDateTime_GET_DAY(obj); + + return Py_BuildValue("(iii)", year, month, day); +} + +static PyObject * +test_PyDateTime_DATE_GET(PyObject *self, PyObject *obj) +{ + int hour = PyDateTime_DATE_GET_HOUR(obj); + int minute = PyDateTime_DATE_GET_MINUTE(obj); + int second = PyDateTime_DATE_GET_SECOND(obj); + int microsecond = PyDateTime_DATE_GET_MICROSECOND(obj); + PyObject *tzinfo = PyDateTime_DATE_GET_TZINFO(obj); + + return Py_BuildValue("(iiiiO)", hour, minute, second, microsecond, tzinfo); +} + +static PyObject * +test_PyDateTime_TIME_GET(PyObject *self, PyObject *obj) +{ + int hour = PyDateTime_TIME_GET_HOUR(obj); + int minute = PyDateTime_TIME_GET_MINUTE(obj); + int second = PyDateTime_TIME_GET_SECOND(obj); + int microsecond = PyDateTime_TIME_GET_MICROSECOND(obj); + PyObject *tzinfo = PyDateTime_TIME_GET_TZINFO(obj); + + return Py_BuildValue("(iiiiO)", hour, minute, second, microsecond, tzinfo); +} + +static PyObject * +test_PyDateTime_DELTA_GET(PyObject *self, PyObject *obj) +{ + int days = PyDateTime_DELTA_GET_DAYS(obj); + int seconds = PyDateTime_DELTA_GET_SECONDS(obj); + int microseconds = PyDateTime_DELTA_GET_MICROSECONDS(obj); + + return Py_BuildValue("(iii)", days, seconds, microseconds); +} + +static PyMethodDef test_methods[] = { + {"PyDateTime_DATE_GET", test_PyDateTime_DATE_GET, METH_O}, + {"PyDateTime_DELTA_GET", test_PyDateTime_DELTA_GET, METH_O}, + {"PyDateTime_GET", test_PyDateTime_GET, METH_O}, + {"PyDateTime_TIME_GET", test_PyDateTime_TIME_GET, METH_O}, + {"datetime_check_date", datetime_check_date, METH_VARARGS}, + {"datetime_check_datetime", datetime_check_datetime, METH_VARARGS}, + {"datetime_check_delta", datetime_check_delta, METH_VARARGS}, + {"datetime_check_time", datetime_check_time, METH_VARARGS}, + {"datetime_check_tzinfo", datetime_check_tzinfo, METH_VARARGS}, + {"get_date_fromdate", get_date_fromdate, METH_VARARGS}, + {"get_date_fromtimestamp", get_date_fromtimestamp, METH_VARARGS}, + {"get_datetime_fromdateandtime", get_datetime_fromdateandtime, METH_VARARGS}, + {"get_datetime_fromdateandtimeandfold", get_datetime_fromdateandtimeandfold, METH_VARARGS}, + {"get_datetime_fromtimestamp", get_datetime_fromtimestamp, METH_VARARGS}, + {"get_delta_fromdsu", get_delta_fromdsu, METH_VARARGS}, + {"get_time_fromtime", get_time_fromtime, METH_VARARGS}, + {"get_time_fromtimeandfold", get_time_fromtimeandfold, METH_VARARGS}, + {"get_timezone_utc_capi", get_timezone_utc_capi, METH_VARARGS}, + {"get_timezones_offset_zero", get_timezones_offset_zero, METH_NOARGS}, + {"make_timezones_capi", make_timezones_capi, METH_NOARGS}, + {"test_datetime_capi", test_datetime_capi, METH_NOARGS}, + {NULL}, +}; + +int +_PyTestCapi_Init_DateTime(PyObject *mod) +{ + if (PyModule_AddFunctions(mod, test_methods) < 0) { + return -1; + } + return 0; +} diff --git a/Modules/_testcapi/dict.c b/Modules/_testcapi/dict.c new file mode 100644 index 00000000..374464c4 --- /dev/null +++ b/Modules/_testcapi/dict.c @@ -0,0 +1,308 @@ +#include <stddef.h> // ptrdiff_t + +#define PY_SSIZE_T_CLEAN +#include "parts.h" +#include "util.h" + + +static PyObject * +dict_check(PyObject *self, PyObject *obj) +{ + NULLABLE(obj); + return PyLong_FromLong(PyDict_Check(obj)); +} + +static PyObject * +dict_checkexact(PyObject *self, PyObject *obj) +{ + NULLABLE(obj); + return PyLong_FromLong(PyDict_CheckExact(obj)); +} + +static PyObject * +dict_new(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return PyDict_New(); +} + +static PyObject * +dictproxy_new(PyObject *self, PyObject *obj) +{ + NULLABLE(obj); + return PyDictProxy_New(obj); +} + +static PyObject * +dict_clear(PyObject *self, PyObject *obj) +{ + PyDict_Clear(obj); + Py_RETURN_NONE; +} + +static PyObject * +dict_copy(PyObject *self, PyObject *obj) +{ + NULLABLE(obj); + return PyDict_Copy(obj); +} + +static PyObject * +dict_contains(PyObject *self, PyObject *args) +{ + PyObject *obj, *key; + if (!PyArg_ParseTuple(args, "OO", &obj, &key)) { + return NULL; + } + NULLABLE(obj); + NULLABLE(key); + RETURN_INT(PyDict_Contains(obj, key)); +} + +static PyObject * +dict_size(PyObject *self, PyObject *obj) +{ + NULLABLE(obj); + RETURN_SIZE(PyDict_Size(obj)); +} + +static PyObject * +dict_getitem(PyObject *self, PyObject *args) +{ + PyObject *mapping, *key; + if (!PyArg_ParseTuple(args, "OO", &mapping, &key)) { + return NULL; + } + NULLABLE(mapping); + NULLABLE(key); + PyObject *value = PyDict_GetItem(mapping, key); + if (value == NULL) { + if (PyErr_Occurred()) { + return NULL; + } + return Py_NewRef(PyExc_KeyError); + } + return Py_NewRef(value); +} + +static PyObject * +dict_getitemstring(PyObject *self, PyObject *args) +{ + PyObject *mapping; + const char *key; + Py_ssize_t size; + if (!PyArg_ParseTuple(args, "Oz#", &mapping, &key, &size)) { + return NULL; + } + NULLABLE(mapping); + PyObject *value = PyDict_GetItemString(mapping, key); + if (value == NULL) { + if (PyErr_Occurred()) { + return NULL; + } + return Py_NewRef(PyExc_KeyError); + } + return Py_NewRef(value); +} + +static PyObject * +dict_getitemwitherror(PyObject *self, PyObject *args) +{ + PyObject *mapping, *key; + if (!PyArg_ParseTuple(args, "OO", &mapping, &key)) { + return NULL; + } + NULLABLE(mapping); + NULLABLE(key); + PyObject *value = PyDict_GetItemWithError(mapping, key); + if (value == NULL) { + if (PyErr_Occurred()) { + return NULL; + } + return Py_NewRef(PyExc_KeyError); + } + return Py_NewRef(value); +} + +static PyObject * +dict_setitem(PyObject *self, PyObject *args) +{ + PyObject *mapping, *key, *value; + if (!PyArg_ParseTuple(args, "OOO", &mapping, &key, &value)) { + return NULL; + } + NULLABLE(mapping); + NULLABLE(key); + NULLABLE(value); + RETURN_INT(PyDict_SetItem(mapping, key, value)); +} + +static PyObject * +dict_setitemstring(PyObject *self, PyObject *args) +{ + PyObject *mapping, *value; + const char *key; + Py_ssize_t size; + if (!PyArg_ParseTuple(args, "Oz#O", &mapping, &key, &size, &value)) { + return NULL; + } + NULLABLE(mapping); + NULLABLE(value); + RETURN_INT(PyDict_SetItemString(mapping, key, value)); +} + +static PyObject * +dict_setdefault(PyObject *self, PyObject *args) +{ + PyObject *mapping, *key, *defaultobj; + if (!PyArg_ParseTuple(args, "OOO", &mapping, &key, &defaultobj)) { + return NULL; + } + NULLABLE(mapping); + NULLABLE(key); + NULLABLE(defaultobj); + return PyDict_SetDefault(mapping, key, defaultobj); +} + +static PyObject * +dict_delitem(PyObject *self, PyObject *args) +{ + PyObject *mapping, *key; + if (!PyArg_ParseTuple(args, "OO", &mapping, &key)) { + return NULL; + } + NULLABLE(mapping); + NULLABLE(key); + RETURN_INT(PyDict_DelItem(mapping, key)); +} + +static PyObject * +dict_delitemstring(PyObject *self, PyObject *args) +{ + PyObject *mapping; + const char *key; + Py_ssize_t size; + if (!PyArg_ParseTuple(args, "Oz#", &mapping, &key, &size)) { + return NULL; + } + NULLABLE(mapping); + RETURN_INT(PyDict_DelItemString(mapping, key)); +} + +static PyObject * +dict_keys(PyObject *self, PyObject *obj) +{ + NULLABLE(obj); + return PyDict_Keys(obj); +} + +static PyObject * +dict_values(PyObject *self, PyObject *obj) +{ + NULLABLE(obj); + return PyDict_Values(obj); +} + +static PyObject * +dict_items(PyObject *self, PyObject *obj) +{ + NULLABLE(obj); + return PyDict_Items(obj); +} + +static PyObject * +dict_next(PyObject *self, PyObject *args) +{ + PyObject *mapping, *key = UNINITIALIZED_PTR, *value = UNINITIALIZED_PTR; + Py_ssize_t pos; + if (!PyArg_ParseTuple(args, "On", &mapping, &pos)) { + return NULL; + } + NULLABLE(mapping); + int rc = PyDict_Next(mapping, &pos, &key, &value); + if (rc != 0) { + return Py_BuildValue("inOO", rc, pos, key, value); + } + assert(key == UNINITIALIZED_PTR); + assert(value == UNINITIALIZED_PTR); + if (PyErr_Occurred()) { + return NULL; + } + Py_RETURN_NONE; +} + +static PyObject * +dict_merge(PyObject *self, PyObject *args) +{ + PyObject *mapping, *mapping2; + int override; + if (!PyArg_ParseTuple(args, "OOi", &mapping, &mapping2, &override)) { + return NULL; + } + NULLABLE(mapping); + NULLABLE(mapping2); + RETURN_INT(PyDict_Merge(mapping, mapping2, override)); +} + +static PyObject * +dict_update(PyObject *self, PyObject *args) +{ + PyObject *mapping, *mapping2; + if (!PyArg_ParseTuple(args, "OO", &mapping, &mapping2)) { + return NULL; + } + NULLABLE(mapping); + NULLABLE(mapping2); + RETURN_INT(PyDict_Update(mapping, mapping2)); +} + +static PyObject * +dict_mergefromseq2(PyObject *self, PyObject *args) +{ + PyObject *mapping, *seq; + int override; + if (!PyArg_ParseTuple(args, "OOi", &mapping, &seq, &override)) { + return NULL; + } + NULLABLE(mapping); + NULLABLE(seq); + RETURN_INT(PyDict_MergeFromSeq2(mapping, seq, override)); +} + + +static PyMethodDef test_methods[] = { + {"dict_check", dict_check, METH_O}, + {"dict_checkexact", dict_checkexact, METH_O}, + {"dict_new", dict_new, METH_NOARGS}, + {"dictproxy_new", dictproxy_new, METH_O}, + {"dict_clear", dict_clear, METH_O}, + {"dict_copy", dict_copy, METH_O}, + {"dict_size", dict_size, METH_O}, + {"dict_getitem", dict_getitem, METH_VARARGS}, + {"dict_getitemwitherror", dict_getitemwitherror, METH_VARARGS}, + {"dict_getitemstring", dict_getitemstring, METH_VARARGS}, + {"dict_contains", dict_contains, METH_VARARGS}, + {"dict_setitem", dict_setitem, METH_VARARGS}, + {"dict_setitemstring", dict_setitemstring, METH_VARARGS}, + {"dict_delitem", dict_delitem, METH_VARARGS}, + {"dict_delitemstring", dict_delitemstring, METH_VARARGS}, + {"dict_setdefault", dict_setdefault, METH_VARARGS}, + {"dict_keys", dict_keys, METH_O}, + {"dict_values", dict_values, METH_O}, + {"dict_items", dict_items, METH_O}, + {"dict_next", dict_next, METH_VARARGS}, + {"dict_merge", dict_merge, METH_VARARGS}, + {"dict_update", dict_update, METH_VARARGS}, + {"dict_mergefromseq2", dict_mergefromseq2, METH_VARARGS}, + + {NULL}, +}; + +int +_PyTestCapi_Init_Dict(PyObject *m) +{ + if (PyModule_AddFunctions(m, test_methods) < 0) { + return -1; + } + + return 0; +} diff --git a/Modules/_testcapi/docstring.c b/Modules/_testcapi/docstring.c new file mode 100644 index 00000000..a997c54a --- /dev/null +++ b/Modules/_testcapi/docstring.c @@ -0,0 +1,107 @@ +#include "parts.h" + + +PyDoc_STRVAR(docstring_empty, +"" +); + +PyDoc_STRVAR(docstring_no_signature, +"This docstring has no signature." +); + +PyDoc_STRVAR(docstring_with_invalid_signature, +"docstring_with_invalid_signature($module, /, boo)\n" +"\n" +"This docstring has an invalid signature." +); + +PyDoc_STRVAR(docstring_with_invalid_signature2, +"docstring_with_invalid_signature2($module, /, boo)\n" +"\n" +"--\n" +"\n" +"This docstring also has an invalid signature." +); + +PyDoc_STRVAR(docstring_with_signature, +"docstring_with_signature($module, /, sig)\n" +"--\n" +"\n" +"This docstring has a valid signature." +); + +PyDoc_STRVAR(docstring_with_signature_but_no_doc, +"docstring_with_signature_but_no_doc($module, /, sig)\n" +"--\n" +"\n" +); + +PyDoc_STRVAR(docstring_with_signature_and_extra_newlines, +"docstring_with_signature_and_extra_newlines($module, /, parameter)\n" +"--\n" +"\n" +"\n" +"This docstring has a valid signature and some extra newlines." +); + +PyDoc_STRVAR(docstring_with_signature_with_defaults, +"docstring_with_signature_with_defaults(module, s='avocado',\n" +" b=b'bytes', d=3.14, i=35, n=None, t=True, f=False,\n" +" local=the_number_three, sys=sys.maxsize,\n" +" exp=sys.maxsize - 1)\n" +"--\n" +"\n" +"\n" +"\n" +"This docstring has a valid signature with parameters,\n" +"and the parameters take defaults of varying types." +); + +/* This is here to provide a docstring for test_descr. */ +static PyObject * +test_with_docstring(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + Py_RETURN_NONE; +} + +static PyMethodDef test_methods[] = { + {"docstring_empty", + (PyCFunction)test_with_docstring, METH_NOARGS, + docstring_empty}, + {"docstring_no_signature", + (PyCFunction)test_with_docstring, METH_NOARGS, + docstring_no_signature}, + {"docstring_with_invalid_signature", + (PyCFunction)test_with_docstring, METH_NOARGS, + docstring_with_invalid_signature}, + {"docstring_with_invalid_signature2", + (PyCFunction)test_with_docstring, METH_NOARGS, + docstring_with_invalid_signature2}, + {"docstring_with_signature", + (PyCFunction)test_with_docstring, METH_NOARGS, + docstring_with_signature}, + {"docstring_with_signature_and_extra_newlines", + (PyCFunction)test_with_docstring, METH_NOARGS, + docstring_with_signature_and_extra_newlines}, + {"docstring_with_signature_but_no_doc", + (PyCFunction)test_with_docstring, METH_NOARGS, + docstring_with_signature_but_no_doc}, + {"docstring_with_signature_with_defaults", + (PyCFunction)test_with_docstring, METH_NOARGS, + docstring_with_signature_with_defaults}, + {"no_docstring", + (PyCFunction)test_with_docstring, METH_NOARGS}, + {"test_with_docstring", + test_with_docstring, METH_NOARGS, + PyDoc_STR("This is a pretty normal docstring.")}, + {NULL}, +}; + +int +_PyTestCapi_Init_Docstring(PyObject *mod) +{ + if (PyModule_AddFunctions(mod, test_methods) < 0) { + return -1; + } + return 0; +} diff --git a/Modules/_testcapi/exceptions.c b/Modules/_testcapi/exceptions.c new file mode 100644 index 00000000..c511c6d0 --- /dev/null +++ b/Modules/_testcapi/exceptions.c @@ -0,0 +1,414 @@ +#define PY_SSIZE_T_CLEAN +#include "parts.h" +#include "util.h" +#include "clinic/exceptions.c.h" + + +/*[clinic input] +module _testcapi +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=6361033e795369fc]*/ + +/*[clinic input] +_testcapi.err_set_raised + exception as exc: object + / +[clinic start generated code]*/ + +static PyObject * +_testcapi_err_set_raised(PyObject *module, PyObject *exc) +/*[clinic end generated code: output=0a0c7743961fcae5 input=c5f7331864a94df9]*/ +{ + Py_INCREF(exc); + PyErr_SetRaisedException(exc); + assert(PyErr_Occurred()); + return NULL; +} + +static PyObject * +err_restore(PyObject *self, PyObject *args) { + PyObject *type = NULL, *value = NULL, *traceback = NULL; + switch(PyTuple_Size(args)) { + case 3: + traceback = PyTuple_GetItem(args, 2); + Py_INCREF(traceback); + /* fall through */ + case 2: + value = PyTuple_GetItem(args, 1); + Py_INCREF(value); + /* fall through */ + case 1: + type = PyTuple_GetItem(args, 0); + Py_INCREF(type); + break; + default: + PyErr_SetString(PyExc_TypeError, + "wrong number of arguments"); + return NULL; + } + PyErr_Restore(type, value, traceback); + assert(PyErr_Occurred()); + return NULL; +} + +/*[clinic input] +_testcapi.exception_print + exception as exc: object + legacy: bool = False + / + +To test the format of exceptions as printed out. +[clinic start generated code]*/ + +static PyObject * +_testcapi_exception_print_impl(PyObject *module, PyObject *exc, int legacy) +/*[clinic end generated code: output=3f04fe0c18412ae0 input=c76f42cb94136dbf]*/ +{ + if (legacy) { + PyObject *tb = NULL; + if (PyExceptionInstance_Check(exc)) { + tb = PyException_GetTraceback(exc); + } + PyErr_Display((PyObject *) Py_TYPE(exc), exc, tb); + Py_XDECREF(tb); + } + else { + PyErr_DisplayException(exc); + } + Py_RETURN_NONE; +} + +/*[clinic input] +_testcapi.make_exception_with_doc + name: str + doc: str = NULL + base: object = NULL + dict: object = NULL + +Test PyErr_NewExceptionWithDoc (also exercise PyErr_NewException). Run via Lib/test/test_exceptions.py +[clinic start generated code]*/ + +static PyObject * +_testcapi_make_exception_with_doc_impl(PyObject *module, const char *name, + const char *doc, PyObject *base, + PyObject *dict) +/*[clinic end generated code: output=439f0d963c1ce2c4 input=23a73013f8a8795a]*/ +{ + return PyErr_NewExceptionWithDoc(name, doc, base, dict); +} + +/*[clinic input] +_testcapi.exc_set_object + exception as exc: object + obj: object + / +[clinic start generated code]*/ + +static PyObject * +_testcapi_exc_set_object_impl(PyObject *module, PyObject *exc, PyObject *obj) +/*[clinic end generated code: output=34c8c7c83e5c8463 input=fc530aafb1b0a360]*/ +{ + PyErr_SetObject(exc, obj); + return NULL; +} + +/*[clinic input] +_testcapi.exc_set_object_fetch = _testcapi.exc_set_object +[clinic start generated code]*/ + +static PyObject * +_testcapi_exc_set_object_fetch_impl(PyObject *module, PyObject *exc, + PyObject *obj) +/*[clinic end generated code: output=7a5ff5f6d3cf687f input=77ec686f1f95fa38]*/ +{ + PyObject *type = UNINITIALIZED_PTR; + PyObject *value = UNINITIALIZED_PTR; + PyObject *tb = UNINITIALIZED_PTR; + + PyErr_SetObject(exc, obj); + PyErr_Fetch(&type, &value, &tb); + assert(type != UNINITIALIZED_PTR); + assert(value != UNINITIALIZED_PTR); + assert(tb != UNINITIALIZED_PTR); + Py_XDECREF(type); + Py_XDECREF(tb); + return value; +} + +/*[clinic input] +_testcapi.err_setstring + exc: object + value: str(zeroes=True, accept={robuffer, str, NoneType}) + / +[clinic start generated code]*/ + +static PyObject * +_testcapi_err_setstring_impl(PyObject *module, PyObject *exc, + const char *value, Py_ssize_t value_length) +/*[clinic end generated code: output=fba8705e5703dd3f input=e8a95fad66d9004b]*/ +{ + NULLABLE(exc); + PyErr_SetString(exc, value); + return NULL; +} + +/*[clinic input] +_testcapi.err_setfromerrnowithfilename + error: int + exc: object + value: str(zeroes=True, accept={robuffer, str, NoneType}) + / +[clinic start generated code]*/ + +static PyObject * +_testcapi_err_setfromerrnowithfilename_impl(PyObject *module, int error, + PyObject *exc, const char *value, + Py_ssize_t value_length) +/*[clinic end generated code: output=d02df5749a01850e input=ff7c384234bf097f]*/ +{ + NULLABLE(exc); + errno = error; + PyErr_SetFromErrnoWithFilename(exc, value); + return NULL; +} + +/*[clinic input] +_testcapi.raise_exception + exception as exc: object + num_args: int + / +[clinic start generated code]*/ + +static PyObject * +_testcapi_raise_exception_impl(PyObject *module, PyObject *exc, int num_args) +/*[clinic end generated code: output=eb0a9c5d69e0542d input=83d6262c3829d088]*/ +{ + PyObject *exc_args = PyTuple_New(num_args); + if (exc_args == NULL) { + return NULL; + } + for (int i = 0; i < num_args; ++i) { + PyObject *v = PyLong_FromLong(i); + if (v == NULL) { + Py_DECREF(exc_args); + return NULL; + } + PyTuple_SET_ITEM(exc_args, i, v); + } + PyErr_SetObject(exc, exc_args); + Py_DECREF(exc_args); + return NULL; +} + +/*[clinic input] +_testcapi.raise_memoryerror +[clinic start generated code]*/ + +static PyObject * +_testcapi_raise_memoryerror_impl(PyObject *module) +/*[clinic end generated code: output=dd057803fb0131e6 input=6ca521bd07fb73cb]*/ +{ + return PyErr_NoMemory(); +} + +/*[clinic input] +_testcapi.fatal_error + message: str(accept={robuffer}) + release_gil: bool = False + / +[clinic start generated code]*/ + +static PyObject * +_testcapi_fatal_error_impl(PyObject *module, const char *message, + int release_gil) +/*[clinic end generated code: output=9c3237116e6a03e8 input=1be357a2ccb04c8c]*/ +{ + if (release_gil) { + Py_BEGIN_ALLOW_THREADS + Py_FatalError(message); + Py_END_ALLOW_THREADS + } + else { + Py_FatalError(message); + } + // Py_FatalError() does not return, but exits the process. + Py_RETURN_NONE; +} + +/*[clinic input] +_testcapi.set_exc_info + new_type: object + new_value: object + new_tb: object + / +[clinic start generated code]*/ + +static PyObject * +_testcapi_set_exc_info_impl(PyObject *module, PyObject *new_type, + PyObject *new_value, PyObject *new_tb) +/*[clinic end generated code: output=b55fa35dec31300e input=ea9f19e0f55fe5b3]*/ +{ + PyObject *type = UNINITIALIZED_PTR, *value = UNINITIALIZED_PTR, *tb = UNINITIALIZED_PTR; + PyErr_GetExcInfo(&type, &value, &tb); + + Py_INCREF(new_type); + Py_INCREF(new_value); + Py_INCREF(new_tb); + PyErr_SetExcInfo(new_type, new_value, new_tb); + + PyObject *orig_exc = PyTuple_Pack(3, + type ? type : Py_None, + value ? value : Py_None, + tb ? tb : Py_None); + Py_XDECREF(type); + Py_XDECREF(value); + Py_XDECREF(tb); + return orig_exc; +} + +/*[clinic input] +_testcapi.set_exception + new_exc: object + / +[clinic start generated code]*/ + +static PyObject * +_testcapi_set_exception(PyObject *module, PyObject *new_exc) +/*[clinic end generated code: output=8b969b35d029e96d input=c89d4ca966c69738]*/ +{ + PyObject *exc = PyErr_GetHandledException(); + assert(PyExceptionInstance_Check(exc) || exc == NULL); + PyErr_SetHandledException(new_exc); + return exc; +} + +/*[clinic input] +_testcapi.write_unraisable_exc + exception as exc: object + err_msg: object + obj: object + / +[clinic start generated code]*/ + +static PyObject * +_testcapi_write_unraisable_exc_impl(PyObject *module, PyObject *exc, + PyObject *err_msg, PyObject *obj) +/*[clinic end generated code: output=39827c5e0a8c2092 input=582498da5b2ee6cf]*/ +{ + + const char *err_msg_utf8; + if (err_msg != Py_None) { + err_msg_utf8 = PyUnicode_AsUTF8(err_msg); + if (err_msg_utf8 == NULL) { + return NULL; + } + } + else { + err_msg_utf8 = NULL; + } + + PyErr_SetObject((PyObject *)Py_TYPE(exc), exc); + _PyErr_WriteUnraisableMsg(err_msg_utf8, obj); + Py_RETURN_NONE; +} + +/*[clinic input] +_testcapi.traceback_print + traceback: object + file: object + / +To test the format of tracebacks as printed out. +[clinic start generated code]*/ + +static PyObject * +_testcapi_traceback_print_impl(PyObject *module, PyObject *traceback, + PyObject *file) +/*[clinic end generated code: output=17074ecf9d95cf30 input=9423f2857b008ca8]*/ +{ + if (PyTraceBack_Print(traceback, file) < 0) { + return NULL; + } + Py_RETURN_NONE; +} + +/*[clinic input] +_testcapi.unstable_exc_prep_reraise_star + orig: object + excs: object + / +To test PyUnstable_Exc_PrepReraiseStar. +[clinic start generated code]*/ + +static PyObject * +_testcapi_unstable_exc_prep_reraise_star_impl(PyObject *module, + PyObject *orig, PyObject *excs) +/*[clinic end generated code: output=850cf008e0563c77 input=27fbcda2203eb301]*/ +{ + return PyUnstable_Exc_PrepReraiseStar(orig, excs); +} + + +/* + * Define the PyRecurdingInfinitelyError_Type + */ + +static PyTypeObject PyRecursingInfinitelyError_Type; + +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 PyTypeObject PyRecursingInfinitelyError_Type = { + .tp_name = "RecursingInfinitelyError", + .tp_basicsize = sizeof(PyBaseExceptionObject), + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + .tp_doc = PyDoc_STR("Instantiating this exception starts infinite recursion."), + .tp_init = (initproc)recurse_infinitely_error_init, +}; + +static PyMethodDef test_methods[] = { + {"err_restore", err_restore, METH_VARARGS}, + _TESTCAPI_ERR_SET_RAISED_METHODDEF + _TESTCAPI_EXCEPTION_PRINT_METHODDEF + _TESTCAPI_FATAL_ERROR_METHODDEF + _TESTCAPI_MAKE_EXCEPTION_WITH_DOC_METHODDEF + _TESTCAPI_EXC_SET_OBJECT_METHODDEF + _TESTCAPI_EXC_SET_OBJECT_FETCH_METHODDEF + _TESTCAPI_ERR_SETSTRING_METHODDEF + _TESTCAPI_ERR_SETFROMERRNOWITHFILENAME_METHODDEF + _TESTCAPI_RAISE_EXCEPTION_METHODDEF + _TESTCAPI_RAISE_MEMORYERROR_METHODDEF + _TESTCAPI_SET_EXC_INFO_METHODDEF + _TESTCAPI_SET_EXCEPTION_METHODDEF + _TESTCAPI_TRACEBACK_PRINT_METHODDEF + _TESTCAPI_WRITE_UNRAISABLE_EXC_METHODDEF + _TESTCAPI_UNSTABLE_EXC_PREP_RERAISE_STAR_METHODDEF + {NULL}, +}; + +int +_PyTestCapi_Init_Exceptions(PyObject *mod) +{ + PyRecursingInfinitelyError_Type.tp_base = (PyTypeObject *)PyExc_Exception; + if (PyType_Ready(&PyRecursingInfinitelyError_Type) < 0) { + return -1; + } + if (PyModule_AddObjectRef(mod, "RecursingInfinitelyError", + (PyObject *)&PyRecursingInfinitelyError_Type) < 0) + { + return -1; + } + + if (PyModule_AddFunctions(mod, test_methods) < 0) { + return -1; + } + + return 0; +} diff --git a/Modules/_testcapi/float.c b/Modules/_testcapi/float.c new file mode 100644 index 00000000..33cbda83 --- /dev/null +++ b/Modules/_testcapi/float.c @@ -0,0 +1,114 @@ +#define PY_SSIZE_T_CLEAN + +#include "parts.h" +#include "clinic/float.c.h" + + +/*[clinic input] +module _testcapi +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=6361033e795369fc]*/ + +/*[clinic input] +_testcapi.float_pack + + size: int + d: double + le: int + / + +Test PyFloat_Pack2(), PyFloat_Pack4() and PyFloat_Pack8() +[clinic start generated code]*/ + +static PyObject * +_testcapi_float_pack_impl(PyObject *module, int size, double d, int le) +/*[clinic end generated code: output=7899bd98f8b6cb04 input=52c9115121999c98]*/ +{ + switch (size) + { + case 2: + { + char data[2]; + if (PyFloat_Pack2(d, data, le) < 0) { + return NULL; + } + return PyBytes_FromStringAndSize(data, Py_ARRAY_LENGTH(data)); + } + case 4: + { + char data[4]; + if (PyFloat_Pack4(d, data, le) < 0) { + return NULL; + } + return PyBytes_FromStringAndSize(data, Py_ARRAY_LENGTH(data)); + } + case 8: + { + char data[8]; + if (PyFloat_Pack8(d, data, le) < 0) { + return NULL; + } + return PyBytes_FromStringAndSize(data, Py_ARRAY_LENGTH(data)); + } + default: break; + } + + PyErr_SetString(PyExc_ValueError, "size must 2, 4 or 8"); + return NULL; +} + + +/*[clinic input] +_testcapi.float_unpack + + data: str(accept={robuffer}, zeroes=True) + le: int + / + +Test PyFloat_Unpack2(), PyFloat_Unpack4() and PyFloat_Unpack8() +[clinic start generated code]*/ + +static PyObject * +_testcapi_float_unpack_impl(PyObject *module, const char *data, + Py_ssize_t data_length, int le) +/*[clinic end generated code: output=617059f889ddbfe4 input=c095e4bb75a696cd]*/ +{ + assert(!PyErr_Occurred()); + double d; + switch (data_length) + { + case 2: + d = PyFloat_Unpack2(data, le); + break; + case 4: + d = PyFloat_Unpack4(data, le); + break; + case 8: + d = PyFloat_Unpack8(data, le); + break; + default: + PyErr_SetString(PyExc_ValueError, "data length must 2, 4 or 8 bytes"); + return NULL; + } + + if (d == -1.0 && PyErr_Occurred()) { + return NULL; + } + return PyFloat_FromDouble(d); +} + +static PyMethodDef test_methods[] = { + _TESTCAPI_FLOAT_PACK_METHODDEF + _TESTCAPI_FLOAT_UNPACK_METHODDEF + {NULL}, +}; + +int +_PyTestCapi_Init_Float(PyObject *mod) +{ + if (PyModule_AddFunctions(mod, test_methods) < 0) { + return -1; + } + + return 0; +} diff --git a/Modules/_testcapi/gc.c b/Modules/_testcapi/gc.c new file mode 100644 index 00000000..829200ad --- /dev/null +++ b/Modules/_testcapi/gc.c @@ -0,0 +1,344 @@ +#include "parts.h" + +static PyObject* +test_gc_control(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + int orig_enabled = PyGC_IsEnabled(); + const char* msg = "ok"; + int old_state; + + old_state = PyGC_Enable(); + msg = "Enable(1)"; + if (old_state != orig_enabled) { + goto failed; + } + msg = "IsEnabled(1)"; + if (!PyGC_IsEnabled()) { + goto failed; + } + + old_state = PyGC_Disable(); + msg = "disable(2)"; + if (!old_state) { + goto failed; + } + msg = "IsEnabled(2)"; + if (PyGC_IsEnabled()) { + goto failed; + } + + old_state = PyGC_Enable(); + msg = "enable(3)"; + if (old_state) { + goto failed; + } + msg = "IsEnabled(3)"; + if (!PyGC_IsEnabled()) { + goto failed; + } + + if (!orig_enabled) { + old_state = PyGC_Disable(); + msg = "disable(4)"; + if (old_state) { + goto failed; + } + msg = "IsEnabled(4)"; + if (PyGC_IsEnabled()) { + goto failed; + } + } + + Py_RETURN_NONE; + +failed: + /* Try to clean up if we can. */ + if (orig_enabled) { + PyGC_Enable(); + } else { + PyGC_Disable(); + } + PyErr_Format(PyExc_ValueError, "GC control failed in %s", msg); + return NULL; +} + +static PyObject * +without_gc(PyObject *Py_UNUSED(self), PyObject *obj) +{ + PyTypeObject *tp = (PyTypeObject*)obj; + if (!PyType_Check(obj) || !PyType_HasFeature(tp, Py_TPFLAGS_HEAPTYPE)) { + return PyErr_Format(PyExc_TypeError, "heap type expected, got %R", obj); + } + if (PyType_IS_GC(tp)) { + // Don't try this at home, kids: + tp->tp_flags -= Py_TPFLAGS_HAVE_GC; + tp->tp_free = PyObject_Del; + tp->tp_traverse = NULL; + tp->tp_clear = NULL; + } + assert(!PyType_IS_GC(tp)); + return Py_NewRef(obj); +} + +static void +slot_tp_del(PyObject *self) +{ + PyObject *del, *res; + + /* Temporarily resurrect the object. */ + assert(Py_REFCNT(self) == 0); + Py_SET_REFCNT(self, 1); + + /* Save the current exception, if any. */ + PyObject *exc = PyErr_GetRaisedException(); + + PyObject *tp_del = PyUnicode_InternFromString("__tp_del__"); + if (tp_del == NULL) { + PyErr_WriteUnraisable(NULL); + PyErr_SetRaisedException(exc); + return; + } + /* Execute __del__ method, if any. */ + del = _PyType_Lookup(Py_TYPE(self), tp_del); + Py_DECREF(tp_del); + if (del != NULL) { + res = PyObject_CallOneArg(del, self); + if (res == NULL) + PyErr_WriteUnraisable(del); + else + Py_DECREF(res); + } + + /* Restore the saved exception. */ + PyErr_SetRaisedException(exc); + + /* Undo the temporary resurrection; can't use DECREF here, it would + * cause a recursive call. + */ + assert(Py_REFCNT(self) > 0); + Py_SET_REFCNT(self, Py_REFCNT(self) - 1); + if (Py_REFCNT(self) == 0) { + /* this is the normal path out */ + return; + } + + /* __del__ resurrected it! Make it look like the original Py_DECREF + * never happened. + */ + { + Py_ssize_t refcnt = Py_REFCNT(self); + _Py_NewReferenceNoTotal(self); + Py_SET_REFCNT(self, refcnt); + } + assert(!PyType_IS_GC(Py_TYPE(self)) || PyObject_GC_IsTracked(self)); +} + +static PyObject * +with_tp_del(PyObject *self, PyObject *args) +{ + PyObject *obj; + PyTypeObject *tp; + + if (!PyArg_ParseTuple(args, "O:with_tp_del", &obj)) + return NULL; + tp = (PyTypeObject *) obj; + if (!PyType_Check(obj) || !PyType_HasFeature(tp, Py_TPFLAGS_HEAPTYPE)) { + PyErr_Format(PyExc_TypeError, + "heap type expected, got %R", obj); + return NULL; + } + tp->tp_del = slot_tp_del; + return Py_NewRef(obj); +} + + +struct gc_visit_state_basic { + PyObject *target; + int found; +}; + +static int +gc_visit_callback_basic(PyObject *obj, void *arg) +{ + struct gc_visit_state_basic *state = (struct gc_visit_state_basic *)arg; + if (obj == state->target) { + state->found = 1; + return 0; + } + return 1; +} + +static PyObject * +test_gc_visit_objects_basic(PyObject *Py_UNUSED(self), + PyObject *Py_UNUSED(ignored)) +{ + PyObject *obj; + struct gc_visit_state_basic state; + + obj = PyList_New(0); + if (obj == NULL) { + return NULL; + } + state.target = obj; + state.found = 0; + + PyUnstable_GC_VisitObjects(gc_visit_callback_basic, &state); + Py_DECREF(obj); + if (!state.found) { + PyErr_SetString( + PyExc_AssertionError, + "test_gc_visit_objects_basic: Didn't find live list"); + return NULL; + } + Py_RETURN_NONE; +} + +static int +gc_visit_callback_exit_early(PyObject *obj, void *arg) + { + int *visited_i = (int *)arg; + (*visited_i)++; + if (*visited_i == 2) { + return 0; + } + return 1; +} + +static PyObject * +test_gc_visit_objects_exit_early(PyObject *Py_UNUSED(self), + PyObject *Py_UNUSED(ignored)) +{ + int visited_i = 0; + PyUnstable_GC_VisitObjects(gc_visit_callback_exit_early, &visited_i); + if (visited_i != 2) { + PyErr_SetString( + PyExc_AssertionError, + "test_gc_visit_objects_exit_early: did not exit when expected"); + } + Py_RETURN_NONE; +} + +typedef struct { + PyObject_HEAD +} ObjExtraData; + +static PyObject * +obj_extra_data_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + size_t extra_size = sizeof(PyObject *); + PyObject *obj = PyUnstable_Object_GC_NewWithExtraData(type, extra_size); + if (obj == NULL) { + return PyErr_NoMemory(); + } + PyObject_GC_Track(obj); + return obj; +} + +static PyObject ** +obj_extra_data_get_extra_storage(PyObject *self) +{ + return (PyObject **)((char *)self + Py_TYPE(self)->tp_basicsize); +} + +static PyObject * +obj_extra_data_get(PyObject *self, void *Py_UNUSED(ignored)) +{ + PyObject **extra_storage = obj_extra_data_get_extra_storage(self); + PyObject *value = *extra_storage; + if (!value) { + Py_RETURN_NONE; + } + return Py_NewRef(value); +} + +static int +obj_extra_data_set(PyObject *self, PyObject *newval, void *Py_UNUSED(ignored)) +{ + PyObject **extra_storage = obj_extra_data_get_extra_storage(self); + Py_CLEAR(*extra_storage); + if (newval) { + *extra_storage = Py_NewRef(newval); + } + return 0; +} + +static PyGetSetDef obj_extra_data_getset[] = { + {"extra", (getter)obj_extra_data_get, (setter)obj_extra_data_set, NULL}, + {NULL} +}; + +static int +obj_extra_data_traverse(PyObject *self, visitproc visit, void *arg) +{ + PyObject **extra_storage = obj_extra_data_get_extra_storage(self); + PyObject *value = *extra_storage; + Py_VISIT(value); + return 0; +} + +static int +obj_extra_data_clear(PyObject *self) +{ + PyObject **extra_storage = obj_extra_data_get_extra_storage(self); + Py_CLEAR(*extra_storage); + return 0; +} + +static void +obj_extra_data_dealloc(PyObject *self) +{ + PyTypeObject *tp = Py_TYPE(self); + PyObject_GC_UnTrack(self); + obj_extra_data_clear(self); + tp->tp_free(self); + Py_DECREF(tp); +} + +static PyType_Slot ObjExtraData_Slots[] = { + {Py_tp_getset, obj_extra_data_getset}, + {Py_tp_dealloc, obj_extra_data_dealloc}, + {Py_tp_traverse, obj_extra_data_traverse}, + {Py_tp_clear, obj_extra_data_clear}, + {Py_tp_new, obj_extra_data_new}, + {Py_tp_free, PyObject_GC_Del}, + {0, NULL}, +}; + +static PyType_Spec ObjExtraData_TypeSpec = { + .name = "_testcapi.ObjExtraData", + .basicsize = sizeof(ObjExtraData), + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, + .slots = ObjExtraData_Slots, +}; + +static PyMethodDef test_methods[] = { + {"test_gc_control", test_gc_control, METH_NOARGS}, + {"test_gc_visit_objects_basic", test_gc_visit_objects_basic, METH_NOARGS, NULL}, + {"test_gc_visit_objects_exit_early", test_gc_visit_objects_exit_early, METH_NOARGS, NULL}, + {"without_gc", without_gc, METH_O, NULL}, + {"with_tp_del", with_tp_del, METH_VARARGS, NULL}, + {NULL} +}; + +int _PyTestCapi_Init_GC(PyObject *mod) +{ + if (PyModule_AddFunctions(mod, test_methods) < 0) { + return -1; + } + if (PyModule_AddFunctions(mod, test_methods) < 0) { + return -1; + } + + PyObject *ObjExtraData_Type = PyType_FromModuleAndSpec( + mod, &ObjExtraData_TypeSpec, NULL); + if (ObjExtraData_Type == 0) { + return -1; + } + int ret = PyModule_AddType(mod, (PyTypeObject*)ObjExtraData_Type); + Py_DECREF(ObjExtraData_Type); + if (ret < 0) { + return ret; + } + + return 0; +} diff --git a/Modules/_testcapi/getargs.c b/Modules/_testcapi/getargs.c new file mode 100644 index 00000000..aa201319 --- /dev/null +++ b/Modules/_testcapi/getargs.c @@ -0,0 +1,939 @@ +/* + * Tests for Python/getargs.c and Python/modsupport.c; + * APIs that parse and build arguments. + */ + +#define PY_SSIZE_T_CLEAN + +#include "parts.h" + +static PyObject * +parse_tuple_and_keywords(PyObject *self, PyObject *args) +{ + PyObject *sub_args; + PyObject *sub_kwargs; + const char *sub_format; + PyObject *sub_keywords; + + double buffers[8][4]; /* double ensures alignment where necessary */ + PyObject *converted[8]; + char *keywords[8 + 1]; /* space for NULL at end */ + + PyObject *return_value = NULL; + + if (!PyArg_ParseTuple(args, "OOsO:parse_tuple_and_keywords", + &sub_args, &sub_kwargs, &sub_format, &sub_keywords)) + { + return NULL; + } + + if (!(PyList_CheckExact(sub_keywords) || + PyTuple_CheckExact(sub_keywords))) + { + PyErr_SetString(PyExc_ValueError, + "parse_tuple_and_keywords: " + "sub_keywords must be either list or tuple"); + return NULL; + } + + memset(buffers, 0, sizeof(buffers)); + memset(converted, 0, sizeof(converted)); + memset(keywords, 0, sizeof(keywords)); + + Py_ssize_t size = PySequence_Fast_GET_SIZE(sub_keywords); + if (size > 8) { + PyErr_SetString(PyExc_ValueError, + "parse_tuple_and_keywords: too many keywords in sub_keywords"); + goto exit; + } + + for (Py_ssize_t i = 0; i < size; i++) { + PyObject *o = PySequence_Fast_GET_ITEM(sub_keywords, i); + if (!PyUnicode_FSConverter(o, (void *)(converted + i))) { + PyErr_Format(PyExc_ValueError, + "parse_tuple_and_keywords: " + "could not convert keywords[%zd] to narrow string", i); + goto exit; + } + keywords[i] = PyBytes_AS_STRING(converted[i]); + } + + int result = PyArg_ParseTupleAndKeywords(sub_args, sub_kwargs, + sub_format, keywords, + buffers + 0, buffers + 1, buffers + 2, buffers + 3, + buffers + 4, buffers + 5, buffers + 6, buffers + 7); + + if (result) { + return_value = Py_NewRef(Py_None); + } + +exit: + size = sizeof(converted) / sizeof(converted[0]); + for (Py_ssize_t i = 0; i < size; i++) { + Py_XDECREF(converted[i]); + } + return return_value; +} + +static PyObject * +get_args(PyObject *self, PyObject *args) +{ + if (args == NULL) { + args = Py_None; + } + return Py_NewRef(args); +} + +static PyObject * +get_kwargs(PyObject *self, PyObject *args, PyObject *kwargs) +{ + if (kwargs == NULL) { + kwargs = Py_None; + } + return Py_NewRef(kwargs); +} + +static PyObject * +getargs_w_star(PyObject *self, PyObject *args) +{ + Py_buffer buffer; + + if (!PyArg_ParseTuple(args, "w*:getargs_w_star", &buffer)) { + return NULL; + } + + if (2 <= buffer.len) { + char *str = buffer.buf; + str[0] = '['; + str[buffer.len-1] = ']'; + } + + PyObject *result = PyBytes_FromStringAndSize(buffer.buf, buffer.len); + PyBuffer_Release(&buffer); + return result; +} + +static PyObject * +test_empty_argparse(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + /* Test that formats can begin with '|'. See issue #4720. */ + PyObject *dict = NULL; + static char *kwlist[] = {NULL}; + PyObject *tuple = PyTuple_New(0); + if (!tuple) { + return NULL; + } + int result; + if (!(result = PyArg_ParseTuple(tuple, "|:test_empty_argparse"))) { + goto done; + } + dict = PyDict_New(); + if (!dict) { + goto done; + } + result = PyArg_ParseTupleAndKeywords(tuple, dict, "|:test_empty_argparse", + kwlist); + done: + Py_DECREF(tuple); + Py_XDECREF(dict); + if (!result) { + return NULL; + } + Py_RETURN_NONE; +} + +/* Test tuple argument processing */ +static PyObject * +getargs_tuple(PyObject *self, PyObject *args) +{ + int a, b, c; + if (!PyArg_ParseTuple(args, "i(ii)", &a, &b, &c)) { + return NULL; + } + return Py_BuildValue("iii", a, b, c); +} + +/* test PyArg_ParseTupleAndKeywords */ +static PyObject * +getargs_keywords(PyObject *self, PyObject *args, PyObject *kwargs) +{ + static char *keywords[] = {"arg1","arg2","arg3","arg4","arg5", NULL}; + static const char fmt[] = "(ii)i|(i(ii))(iii)i"; + int int_args[10] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, fmt, keywords, + &int_args[0], &int_args[1], &int_args[2], &int_args[3], &int_args[4], + &int_args[5], &int_args[6], &int_args[7], &int_args[8], &int_args[9])) + { + return NULL; + } + return Py_BuildValue("iiiiiiiiii", + int_args[0], int_args[1], int_args[2], int_args[3], int_args[4], + int_args[5], int_args[6], int_args[7], int_args[8], int_args[9]); +} + +/* test PyArg_ParseTupleAndKeywords keyword-only arguments */ +static PyObject * +getargs_keyword_only(PyObject *self, PyObject *args, PyObject *kwargs) +{ + static char *keywords[] = {"required", "optional", "keyword_only", NULL}; + int required = -1; + int optional = -1; + int keyword_only = -1; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|i$i", keywords, + &required, &optional, &keyword_only)) + { + return NULL; + } + return Py_BuildValue("iii", required, optional, keyword_only); +} + +/* test PyArg_ParseTupleAndKeywords positional-only arguments */ +static PyObject * +getargs_positional_only_and_keywords(PyObject *self, PyObject *args, + PyObject *kwargs) +{ + static char *keywords[] = {"", "", "keyword", NULL}; + int required = -1; + int optional = -1; + int keyword = -1; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|ii", keywords, + &required, &optional, &keyword)) + { + return NULL; + } + return Py_BuildValue("iii", required, optional, keyword); +} + +/* Functions to call PyArg_ParseTuple with integer format codes, + and return the result. +*/ +static PyObject * +getargs_b(PyObject *self, PyObject *args) +{ + unsigned char value; + if (!PyArg_ParseTuple(args, "b", &value)) { + return NULL; + } + return PyLong_FromUnsignedLong((unsigned long)value); +} + +static PyObject * +getargs_B(PyObject *self, PyObject *args) +{ + unsigned char value; + if (!PyArg_ParseTuple(args, "B", &value)) { + return NULL; + } + return PyLong_FromUnsignedLong((unsigned long)value); +} + +static PyObject * +getargs_h(PyObject *self, PyObject *args) +{ + short value; + if (!PyArg_ParseTuple(args, "h", &value)) { + return NULL; + } + return PyLong_FromLong((long)value); +} + +static PyObject * +getargs_H(PyObject *self, PyObject *args) +{ + unsigned short value; + if (!PyArg_ParseTuple(args, "H", &value)) { + return NULL; + } + return PyLong_FromUnsignedLong((unsigned long)value); +} + +static PyObject * +getargs_I(PyObject *self, PyObject *args) +{ + unsigned int value; + if (!PyArg_ParseTuple(args, "I", &value)) { + return NULL; + } + return PyLong_FromUnsignedLong((unsigned long)value); +} + +static PyObject * +getargs_k(PyObject *self, PyObject *args) +{ + unsigned long value; + if (!PyArg_ParseTuple(args, "k", &value)) { + return NULL; + } + return PyLong_FromUnsignedLong(value); +} + +static PyObject * +getargs_i(PyObject *self, PyObject *args) +{ + int value; + if (!PyArg_ParseTuple(args, "i", &value)) { + return NULL; + } + return PyLong_FromLong((long)value); +} + +static PyObject * +getargs_l(PyObject *self, PyObject *args) +{ + long value; + if (!PyArg_ParseTuple(args, "l", &value)) { + return NULL; + } + return PyLong_FromLong(value); +} + +static PyObject * +getargs_n(PyObject *self, PyObject *args) +{ + Py_ssize_t value; + if (!PyArg_ParseTuple(args, "n", &value)) { + return NULL; + } + return PyLong_FromSsize_t(value); +} + +static PyObject * +getargs_p(PyObject *self, PyObject *args) +{ + int value; + if (!PyArg_ParseTuple(args, "p", &value)) { + return NULL; + } + return PyLong_FromLong(value); +} + +static PyObject * +getargs_L(PyObject *self, PyObject *args) +{ + long long value; + if (!PyArg_ParseTuple(args, "L", &value)) { + return NULL; + } + return PyLong_FromLongLong(value); +} + +static PyObject * +getargs_K(PyObject *self, PyObject *args) +{ + unsigned long long value; + if (!PyArg_ParseTuple(args, "K", &value)) { + return NULL; + } + return PyLong_FromUnsignedLongLong(value); +} + +/* This function not only tests the 'k' getargs code, but also the + PyLong_AsUnsignedLongMask() function. */ +static PyObject * +test_k_code(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject *tuple, *num; + unsigned long value; + + tuple = PyTuple_New(1); + if (tuple == NULL) { + return NULL; + } + + /* a number larger than ULONG_MAX even on 64-bit platforms */ + num = PyLong_FromString("FFFFFFFFFFFFFFFFFFFFFFFF", NULL, 16); + if (num == NULL) { + return NULL; + } + + value = PyLong_AsUnsignedLongMask(num); + if (value != ULONG_MAX) { + PyErr_SetString(PyExc_AssertionError, + "test_k_code: " + "PyLong_AsUnsignedLongMask() returned wrong value for long 0xFFF...FFF"); + return NULL; + } + + PyTuple_SET_ITEM(tuple, 0, num); + + value = 0; + if (!PyArg_ParseTuple(tuple, "k:test_k_code", &value)) { + return NULL; + } + if (value != ULONG_MAX) { + PyErr_SetString(PyExc_AssertionError, + "test_k_code: k code returned wrong value for long 0xFFF...FFF"); + return NULL; + } + + Py_DECREF(num); + num = PyLong_FromString("-FFFFFFFF000000000000000042", NULL, 16); + if (num == NULL) { + return NULL; + } + + value = PyLong_AsUnsignedLongMask(num); + if (value != (unsigned long)-0x42) { + PyErr_SetString(PyExc_AssertionError, + "test_k_code: " + "PyLong_AsUnsignedLongMask() returned wrong value for long -0xFFF..000042"); + return NULL; + } + + PyTuple_SET_ITEM(tuple, 0, num); + + value = 0; + if (!PyArg_ParseTuple(tuple, "k:test_k_code", &value)) { + return NULL; + } + if (value != (unsigned long)-0x42) { + PyErr_SetString(PyExc_AssertionError, + "test_k_code: k code returned wrong value for long -0xFFF..000042"); + return NULL; + } + + Py_DECREF(tuple); + Py_RETURN_NONE; +} + +static PyObject * +getargs_f(PyObject *self, PyObject *args) +{ + float f; + if (!PyArg_ParseTuple(args, "f", &f)) { + return NULL; + } + return PyFloat_FromDouble(f); +} + +static PyObject * +getargs_d(PyObject *self, PyObject *args) +{ + double d; + if (!PyArg_ParseTuple(args, "d", &d)) { + return NULL; + } + return PyFloat_FromDouble(d); +} + +static PyObject * +getargs_D(PyObject *self, PyObject *args) +{ + Py_complex cval; + if (!PyArg_ParseTuple(args, "D", &cval)) { + return NULL; + } + return PyComplex_FromCComplex(cval); +} + +static PyObject * +getargs_S(PyObject *self, PyObject *args) +{ + PyObject *obj; + if (!PyArg_ParseTuple(args, "S", &obj)) { + return NULL; + } + return Py_NewRef(obj); +} + +static PyObject * +getargs_Y(PyObject *self, PyObject *args) +{ + PyObject *obj; + if (!PyArg_ParseTuple(args, "Y", &obj)) { + return NULL; + } + return Py_NewRef(obj); +} + +static PyObject * +getargs_U(PyObject *self, PyObject *args) +{ + PyObject *obj; + if (!PyArg_ParseTuple(args, "U", &obj)) { + return NULL; + } + return Py_NewRef(obj); +} + +static PyObject * +getargs_c(PyObject *self, PyObject *args) +{ + char c; + if (!PyArg_ParseTuple(args, "c", &c)) { + return NULL; + } + return PyLong_FromLong((unsigned char)c); +} + +static PyObject * +getargs_C(PyObject *self, PyObject *args) +{ + int c; + if (!PyArg_ParseTuple(args, "C", &c)) { + return NULL; + } + return PyLong_FromLong(c); +} + +static PyObject * +getargs_s(PyObject *self, PyObject *args) +{ + char *str; + if (!PyArg_ParseTuple(args, "s", &str)) { + return NULL; + } + return PyBytes_FromString(str); +} + +static PyObject * +getargs_s_star(PyObject *self, PyObject *args) +{ + Py_buffer buffer; + PyObject *bytes; + if (!PyArg_ParseTuple(args, "s*", &buffer)) { + return NULL; + } + bytes = PyBytes_FromStringAndSize(buffer.buf, buffer.len); + PyBuffer_Release(&buffer); + return bytes; +} + +static PyObject * +getargs_s_hash(PyObject *self, PyObject *args) +{ + char *str; + Py_ssize_t size; + if (!PyArg_ParseTuple(args, "s#", &str, &size)) { + return NULL; + } + return PyBytes_FromStringAndSize(str, size); +} + +static PyObject * +getargs_z(PyObject *self, PyObject *args) +{ + char *str; + if (!PyArg_ParseTuple(args, "z", &str)) { + return NULL; + } + if (str != NULL) { + return PyBytes_FromString(str); + } + Py_RETURN_NONE; +} + +static PyObject * +getargs_z_star(PyObject *self, PyObject *args) +{ + Py_buffer buffer; + PyObject *bytes; + if (!PyArg_ParseTuple(args, "z*", &buffer)) { + return NULL; + } + if (buffer.buf != NULL) { + bytes = PyBytes_FromStringAndSize(buffer.buf, buffer.len); + } + else { + bytes = Py_NewRef(Py_None); + } + PyBuffer_Release(&buffer); + return bytes; +} + +static PyObject * +getargs_z_hash(PyObject *self, PyObject *args) +{ + char *str; + Py_ssize_t size; + if (!PyArg_ParseTuple(args, "z#", &str, &size)) { + return NULL; + } + if (str != NULL) { + return PyBytes_FromStringAndSize(str, size); + } + Py_RETURN_NONE; +} + +static PyObject * +getargs_y(PyObject *self, PyObject *args) +{ + char *str; + if (!PyArg_ParseTuple(args, "y", &str)) { + return NULL; + } + return PyBytes_FromString(str); +} + +static PyObject * +getargs_y_star(PyObject *self, PyObject *args) +{ + Py_buffer buffer; + if (!PyArg_ParseTuple(args, "y*", &buffer)) { + return NULL; + } + PyObject *bytes = PyBytes_FromStringAndSize(buffer.buf, buffer.len); + PyBuffer_Release(&buffer); + return bytes; +} + +static PyObject * +getargs_y_hash(PyObject *self, PyObject *args) +{ + char *str; + Py_ssize_t size; + if (!PyArg_ParseTuple(args, "y#", &str, &size)) { + return NULL; + } + return PyBytes_FromStringAndSize(str, size); +} + +static PyObject * +getargs_u(PyObject *self, PyObject *args) +{ + Py_UNICODE *str; + if (!PyArg_ParseTuple(args, "u", &str)) { + return NULL; + } + return PyUnicode_FromWideChar(str, -1); +} + +static PyObject * +getargs_u_hash(PyObject *self, PyObject *args) +{ + Py_UNICODE *str; + Py_ssize_t size; + if (!PyArg_ParseTuple(args, "u#", &str, &size)) { + return NULL; + } + return PyUnicode_FromWideChar(str, size); +} + +static PyObject * +getargs_Z(PyObject *self, PyObject *args) +{ + Py_UNICODE *str; + if (!PyArg_ParseTuple(args, "Z", &str)) { + return NULL; + } + if (str != NULL) { + return PyUnicode_FromWideChar(str, -1); + } + Py_RETURN_NONE; +} + +static PyObject * +getargs_Z_hash(PyObject *self, PyObject *args) +{ + Py_UNICODE *str; + Py_ssize_t size; + if (!PyArg_ParseTuple(args, "Z#", &str, &size)) { + return NULL; + } + if (str != NULL) { + return PyUnicode_FromWideChar(str, size); + } + Py_RETURN_NONE; +} + +static PyObject * +getargs_es(PyObject *self, PyObject *args) +{ + PyObject *arg; + const char *encoding = NULL; + char *str; + + if (!PyArg_ParseTuple(args, "O|s", &arg, &encoding)) { + return NULL; + } + if (!PyArg_Parse(arg, "es", encoding, &str)) { + return NULL; + } + PyObject *result = PyBytes_FromString(str); + PyMem_Free(str); + return result; +} + +static PyObject * +getargs_et(PyObject *self, PyObject *args) +{ + PyObject *arg; + const char *encoding = NULL; + char *str; + + if (!PyArg_ParseTuple(args, "O|s", &arg, &encoding)) { + return NULL; + } + if (!PyArg_Parse(arg, "et", encoding, &str)) { + return NULL; + } + PyObject *result = PyBytes_FromString(str); + PyMem_Free(str); + return result; +} + +static PyObject * +getargs_es_hash(PyObject *self, PyObject *args) +{ + PyObject *arg; + const char *encoding = NULL; + PyByteArrayObject *buffer = NULL; + char *str = NULL; + Py_ssize_t size; + + if (!PyArg_ParseTuple(args, "O|sY", &arg, &encoding, &buffer)) { + return NULL; + } + if (buffer != NULL) { + str = PyByteArray_AS_STRING(buffer); + size = PyByteArray_GET_SIZE(buffer); + } + if (!PyArg_Parse(arg, "es#", encoding, &str, &size)) { + return NULL; + } + PyObject *result = PyBytes_FromStringAndSize(str, size); + if (buffer == NULL) { + PyMem_Free(str); + } + return result; +} + +static PyObject * +getargs_et_hash(PyObject *self, PyObject *args) +{ + PyObject *arg; + const char *encoding = NULL; + PyByteArrayObject *buffer = NULL; + char *str = NULL; + Py_ssize_t size; + + if (!PyArg_ParseTuple(args, "O|sY", &arg, &encoding, &buffer)) { + return NULL; + } + if (buffer != NULL) { + str = PyByteArray_AS_STRING(buffer); + size = PyByteArray_GET_SIZE(buffer); + } + if (!PyArg_Parse(arg, "et#", encoding, &str, &size)) { + return NULL; + } + PyObject *result = PyBytes_FromStringAndSize(str, size); + if (buffer == NULL) { + PyMem_Free(str); + } + return result; +} + +/* Test the L code for PyArg_ParseTuple. This should deliver a long long + for both long and int arguments. The test may leak a little memory if + it fails. +*/ +static PyObject * +test_L_code(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject *tuple, *num; + long long value; + + tuple = PyTuple_New(1); + if (tuple == NULL) { + return NULL; + } + + num = PyLong_FromLong(42); + if (num == NULL) { + return NULL; + } + + PyTuple_SET_ITEM(tuple, 0, num); + + value = -1; + if (!PyArg_ParseTuple(tuple, "L:test_L_code", &value)) { + return NULL; + } + if (value != 42) { + PyErr_SetString(PyExc_AssertionError, + "test_L_code: L code returned wrong value for long 42"); + return NULL; + } + + Py_DECREF(num); + num = PyLong_FromLong(42); + if (num == NULL) { + return NULL; + } + + PyTuple_SET_ITEM(tuple, 0, num); + + value = -1; + if (!PyArg_ParseTuple(tuple, "L:test_L_code", &value)) { + return NULL; + } + if (value != 42) { + PyErr_SetString(PyExc_AssertionError, + "test_L_code: L code returned wrong value for int 42"); + return NULL; + } + + Py_DECREF(tuple); + Py_RETURN_NONE; +} + +/* Test the s and z codes for PyArg_ParseTuple. +*/ +static PyObject * +test_s_code(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + /* Unicode strings should be accepted */ + PyObject *tuple = PyTuple_New(1); + if (tuple == NULL) { + return NULL; + } + + PyObject *obj = PyUnicode_Decode("t\xeate", strlen("t\xeate"), + "latin-1", NULL); + if (obj == NULL) { + return NULL; + } + + PyTuple_SET_ITEM(tuple, 0, obj); + + /* These two blocks used to raise a TypeError: + * "argument must be string without null bytes, not str" + */ + char *value; + if (!PyArg_ParseTuple(tuple, "s:test_s_code1", &value)) { + return NULL; + } + + if (!PyArg_ParseTuple(tuple, "z:test_s_code2", &value)) { + return NULL; + } + + Py_DECREF(tuple); + Py_RETURN_NONE; +} + +#undef PyArg_ParseTupleAndKeywords +PyAPI_FUNC(int) PyArg_ParseTupleAndKeywords(PyObject *, PyObject *, + const char *, char **, ...); + +static PyObject * +getargs_s_hash_int(PyObject *self, PyObject *args, PyObject *kwargs) +{ + static char *keywords[] = {"", "", "x", NULL}; + Py_buffer buf = {NULL}; + const char *s; + int len; + int i = 0; + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "w*|s#i", keywords, + &buf, &s, &len, &i)) + { + return NULL; + } + PyBuffer_Release(&buf); + Py_RETURN_NONE; +} + +static PyObject * +getargs_s_hash_int2(PyObject *self, PyObject *args, PyObject *kwargs) +{ + static char *keywords[] = {"", "", "x", NULL}; + Py_buffer buf = {NULL}; + const char *s; + int len; + int i = 0; + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "w*|(s#)i", keywords, + &buf, &s, &len, &i)) + { + return NULL; + } + PyBuffer_Release(&buf); + Py_RETURN_NONE; +} + +static PyObject * +gh_99240_clear_args(PyObject *self, PyObject *args) +{ + char *a = NULL; + char *b = NULL; + + if (!PyArg_ParseTuple(args, "eses", "idna", &a, "idna", &b)) { + if (a || b) { + PyErr_Clear(); + PyErr_SetString(PyExc_AssertionError, "Arguments are not cleared."); + } + return NULL; + } + PyMem_Free(a); + PyMem_Free(b); + Py_RETURN_NONE; +} + +static PyMethodDef test_methods[] = { + {"get_args", get_args, METH_VARARGS}, + {"get_kwargs", _PyCFunction_CAST(get_kwargs), METH_VARARGS|METH_KEYWORDS}, + {"getargs_B", getargs_B, METH_VARARGS}, + {"getargs_C", getargs_C, METH_VARARGS}, + {"getargs_D", getargs_D, METH_VARARGS}, + {"getargs_H", getargs_H, METH_VARARGS}, + {"getargs_I", getargs_I, METH_VARARGS}, + {"getargs_K", getargs_K, METH_VARARGS}, + {"getargs_L", getargs_L, METH_VARARGS}, + {"getargs_S", getargs_S, METH_VARARGS}, + {"getargs_U", getargs_U, METH_VARARGS}, + {"getargs_Y", getargs_Y, METH_VARARGS}, + {"getargs_Z", getargs_Z, METH_VARARGS}, + {"getargs_Z_hash", getargs_Z_hash, METH_VARARGS}, + {"getargs_b", getargs_b, METH_VARARGS}, + {"getargs_c", getargs_c, METH_VARARGS}, + {"getargs_d", getargs_d, METH_VARARGS}, + {"getargs_es", getargs_es, METH_VARARGS}, + {"getargs_es_hash", getargs_es_hash, METH_VARARGS}, + {"getargs_et", getargs_et, METH_VARARGS}, + {"getargs_et_hash", getargs_et_hash, METH_VARARGS}, + {"getargs_f", getargs_f, METH_VARARGS}, + {"getargs_h", getargs_h, METH_VARARGS}, + {"getargs_i", getargs_i, METH_VARARGS}, + {"getargs_k", getargs_k, METH_VARARGS}, + {"getargs_keyword_only", _PyCFunction_CAST(getargs_keyword_only), METH_VARARGS|METH_KEYWORDS}, + {"getargs_keywords", _PyCFunction_CAST(getargs_keywords), METH_VARARGS|METH_KEYWORDS}, + {"getargs_l", getargs_l, METH_VARARGS}, + {"getargs_n", getargs_n, METH_VARARGS}, + {"getargs_p", getargs_p, METH_VARARGS}, + {"getargs_positional_only_and_keywords", _PyCFunction_CAST(getargs_positional_only_and_keywords), METH_VARARGS|METH_KEYWORDS}, + {"getargs_s", getargs_s, METH_VARARGS}, + {"getargs_s_hash", getargs_s_hash, METH_VARARGS}, + {"getargs_s_hash_int", _PyCFunction_CAST(getargs_s_hash_int), METH_VARARGS|METH_KEYWORDS}, + {"getargs_s_hash_int2", _PyCFunction_CAST(getargs_s_hash_int2), METH_VARARGS|METH_KEYWORDS}, + {"getargs_s_star", getargs_s_star, METH_VARARGS}, + {"getargs_tuple", getargs_tuple, METH_VARARGS}, + {"getargs_u", getargs_u, METH_VARARGS}, + {"getargs_u_hash", getargs_u_hash, METH_VARARGS}, + {"getargs_w_star", getargs_w_star, METH_VARARGS}, + {"getargs_y", getargs_y, METH_VARARGS}, + {"getargs_y_hash", getargs_y_hash, METH_VARARGS}, + {"getargs_y_star", getargs_y_star, METH_VARARGS}, + {"getargs_z", getargs_z, METH_VARARGS}, + {"getargs_z_hash", getargs_z_hash, METH_VARARGS}, + {"getargs_z_star", getargs_z_star, METH_VARARGS}, + {"parse_tuple_and_keywords", parse_tuple_and_keywords, METH_VARARGS}, + {"test_L_code", test_L_code, METH_NOARGS}, + {"test_empty_argparse", test_empty_argparse, METH_NOARGS}, + {"test_k_code", test_k_code, METH_NOARGS}, + {"test_s_code", test_s_code, METH_NOARGS}, + {"gh_99240_clear_args", gh_99240_clear_args, METH_VARARGS}, + {NULL}, +}; + +int +_PyTestCapi_Init_GetArgs(PyObject *mod) +{ + if (PyModule_AddFunctions(mod, test_methods) < 0) { + return -1; + } + + return 0; +} diff --git a/Modules/_testcapi/heaptype.c b/Modules/_testcapi/heaptype.c new file mode 100644 index 00000000..c124871e --- /dev/null +++ b/Modules/_testcapi/heaptype.c @@ -0,0 +1,1259 @@ +#include "parts.h" +#include "structmember.h" // PyMemberDef + +static struct PyModuleDef *_testcapimodule = NULL; // set at initialization + +/* Tests for heap types (PyType_From*) */ + +static PyObject *pytype_fromspec_meta(PyObject* self, PyObject *meta) +{ + if (!PyType_Check(meta)) { + PyErr_SetString( + PyExc_TypeError, + "pytype_fromspec_meta: must be invoked with a type argument!"); + return NULL; + } + + PyType_Slot HeapCTypeViaMetaclass_slots[] = { + {0}, + }; + + PyType_Spec HeapCTypeViaMetaclass_spec = { + "_testcapi.HeapCTypeViaMetaclass", + sizeof(PyObject), + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + HeapCTypeViaMetaclass_slots + }; + + return PyType_FromMetaclass( + (PyTypeObject *) meta, NULL, &HeapCTypeViaMetaclass_spec, NULL); +} + + +static PyType_Slot empty_type_slots[] = { + {0, 0}, +}; + +static PyType_Spec MinimalMetaclass_spec = { + .name = "_testcapi.MinimalMetaclass", + .basicsize = sizeof(PyHeapTypeObject), + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + .slots = empty_type_slots, +}; + +static PyType_Spec MinimalType_spec = { + .name = "_testcapi.MinimalSpecType", + .basicsize = 0, // Updated later + .flags = Py_TPFLAGS_DEFAULT, + .slots = empty_type_slots, +}; + + +static PyObject * +test_from_spec_metatype_inheritance(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject *metaclass = NULL; + PyObject *class = NULL; + PyObject *new = NULL; + PyObject *subclasses = NULL; + PyObject *result = NULL; + int r; + + metaclass = PyType_FromSpecWithBases(&MinimalMetaclass_spec, (PyObject*)&PyType_Type); + if (metaclass == NULL) { + goto finally; + } + class = PyObject_CallFunction(metaclass, "s(){}", "TestClass"); + if (class == NULL) { + goto finally; + } + + MinimalType_spec.basicsize = (int)(((PyTypeObject*)class)->tp_basicsize); + new = PyType_FromSpecWithBases(&MinimalType_spec, class); + if (new == NULL) { + goto finally; + } + if (Py_TYPE(new) != (PyTypeObject*)metaclass) { + PyErr_SetString(PyExc_AssertionError, + "Metaclass not set properly!"); + goto finally; + } + + /* Assert that __subclasses__ is updated */ + subclasses = PyObject_CallMethod(class, "__subclasses__", ""); + if (!subclasses) { + goto finally; + } + r = PySequence_Contains(subclasses, new); + if (r < 0) { + goto finally; + } + if (r == 0) { + PyErr_SetString(PyExc_AssertionError, + "subclasses not set properly!"); + goto finally; + } + + result = Py_NewRef(Py_None); + +finally: + Py_XDECREF(metaclass); + Py_XDECREF(class); + Py_XDECREF(new); + Py_XDECREF(subclasses); + return result; +} + + +static PyObject * +test_from_spec_invalid_metatype_inheritance(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject *metaclass_a = NULL; + PyObject *metaclass_b = NULL; + PyObject *class_a = NULL; + PyObject *class_b = NULL; + PyObject *bases = NULL; + PyObject *new = NULL; + PyObject *meta_error_string = NULL; + PyObject *exc = NULL; + PyObject *result = NULL; + PyObject *message = NULL; + PyObject *args = NULL; + + metaclass_a = PyType_FromSpecWithBases(&MinimalMetaclass_spec, (PyObject*)&PyType_Type); + if (metaclass_a == NULL) { + goto finally; + } + metaclass_b = PyType_FromSpecWithBases(&MinimalMetaclass_spec, (PyObject*)&PyType_Type); + if (metaclass_b == NULL) { + goto finally; + } + class_a = PyObject_CallFunction(metaclass_a, "s(){}", "TestClassA"); + if (class_a == NULL) { + goto finally; + } + + class_b = PyObject_CallFunction(metaclass_b, "s(){}", "TestClassB"); + if (class_b == NULL) { + goto finally; + } + + bases = PyTuple_Pack(2, class_a, class_b); + if (bases == NULL) { + goto finally; + } + + /* + * The following should raise a TypeError due to a MetaClass conflict. + */ + new = PyType_FromSpecWithBases(&MinimalType_spec, bases); + if (new != NULL) { + PyErr_SetString(PyExc_AssertionError, + "MetaType conflict not recognized by PyType_FromSpecWithBases"); + goto finally; + } + + // Assert that the correct exception was raised + if (PyErr_ExceptionMatches(PyExc_TypeError)) { + exc = PyErr_GetRaisedException(); + args = PyException_GetArgs(exc); + if (!PyTuple_Check(args) || PyTuple_Size(args) != 1) { + PyErr_SetString(PyExc_AssertionError, + "TypeError args are not a one-tuple"); + goto finally; + } + message = Py_NewRef(PyTuple_GET_ITEM(args, 0)); + meta_error_string = PyUnicode_FromString("metaclass conflict:"); + if (meta_error_string == NULL) { + goto finally; + } + int res = PyUnicode_Contains(message, meta_error_string); + if (res < 0) { + goto finally; + } + if (res == 0) { + PyErr_SetString(PyExc_AssertionError, + "TypeError did not include expected message."); + goto finally; + } + result = Py_NewRef(Py_None); + } +finally: + Py_XDECREF(metaclass_a); + Py_XDECREF(metaclass_b); + Py_XDECREF(bases); + Py_XDECREF(new); + Py_XDECREF(meta_error_string); + Py_XDECREF(exc); + Py_XDECREF(message); + Py_XDECREF(class_a); + Py_XDECREF(class_b); + Py_XDECREF(args); + return result; +} + + +static PyObject * +simple_str(PyObject *self) { + return PyUnicode_FromString("<test>"); +} + + +static PyObject * +test_type_from_ephemeral_spec(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + // Test that a heap type can be created from a spec that's later deleted + // (along with all its contents). + // All necessary data must be copied and held by the class + PyType_Spec *spec = NULL; + char *name = NULL; + char *doc = NULL; + PyType_Slot *slots = NULL; + PyObject *class = NULL; + PyObject *instance = NULL; + PyObject *obj = NULL; + PyObject *result = NULL; + + /* create a spec (and all its contents) on the heap */ + + const char NAME[] = "testcapi._Test"; + const char DOC[] = "a test class"; + + spec = PyMem_New(PyType_Spec, 1); + if (spec == NULL) { + PyErr_NoMemory(); + goto finally; + } + name = PyMem_New(char, sizeof(NAME)); + if (name == NULL) { + PyErr_NoMemory(); + goto finally; + } + memcpy(name, NAME, sizeof(NAME)); + + doc = PyMem_New(char, sizeof(DOC)); + if (doc == NULL) { + PyErr_NoMemory(); + goto finally; + } + memcpy(doc, DOC, sizeof(DOC)); + + spec->name = name; + spec->basicsize = sizeof(PyObject); + spec->itemsize = 0; + spec->flags = Py_TPFLAGS_DEFAULT; + slots = PyMem_New(PyType_Slot, 3); + if (slots == NULL) { + PyErr_NoMemory(); + goto finally; + } + slots[0].slot = Py_tp_str; + slots[0].pfunc = simple_str; + slots[1].slot = Py_tp_doc; + slots[1].pfunc = doc; + slots[2].slot = 0; + slots[2].pfunc = NULL; + spec->slots = slots; + + /* create the class */ + + class = PyType_FromSpec(spec); + if (class == NULL) { + goto finally; + } + + /* deallocate the spec (and all contents) */ + + // (Explicitly overwrite memory before freeing, + // so bugs show themselves even without the debug allocator's help.) + memset(spec, 0xdd, sizeof(PyType_Spec)); + PyMem_Del(spec); + spec = NULL; + memset(name, 0xdd, sizeof(NAME)); + PyMem_Del(name); + name = NULL; + memset(doc, 0xdd, sizeof(DOC)); + PyMem_Del(doc); + doc = NULL; + memset(slots, 0xdd, 3 * sizeof(PyType_Slot)); + PyMem_Del(slots); + slots = NULL; + + /* check that everything works */ + + PyTypeObject *class_tp = (PyTypeObject *)class; + PyHeapTypeObject *class_ht = (PyHeapTypeObject *)class; + assert(strcmp(class_tp->tp_name, "testcapi._Test") == 0); + assert(strcmp(PyUnicode_AsUTF8(class_ht->ht_name), "_Test") == 0); + assert(strcmp(PyUnicode_AsUTF8(class_ht->ht_qualname), "_Test") == 0); + assert(strcmp(class_tp->tp_doc, "a test class") == 0); + + // call and check __str__ + instance = PyObject_CallNoArgs(class); + if (instance == NULL) { + goto finally; + } + obj = PyObject_Str(instance); + if (obj == NULL) { + goto finally; + } + assert(strcmp(PyUnicode_AsUTF8(obj), "<test>") == 0); + Py_CLEAR(obj); + + result = Py_NewRef(Py_None); + finally: + PyMem_Del(spec); + PyMem_Del(name); + PyMem_Del(doc); + PyMem_Del(slots); + Py_XDECREF(class); + Py_XDECREF(instance); + Py_XDECREF(obj); + return result; +} + +PyType_Slot repeated_doc_slots[] = { + {Py_tp_doc, "A class used for tests·"}, + {Py_tp_doc, "A class used for tests"}, + {0, 0}, +}; + +PyType_Spec repeated_doc_slots_spec = { + .name = "RepeatedDocSlotClass", + .basicsize = sizeof(PyObject), + .slots = repeated_doc_slots, +}; + +typedef struct { + PyObject_HEAD + int data; +} HeapCTypeWithDataObject; + + +static struct PyMemberDef members_to_repeat[] = { + {"T_INT", T_INT, offsetof(HeapCTypeWithDataObject, data), 0, NULL}, + {NULL} +}; + +PyType_Slot repeated_members_slots[] = { + {Py_tp_members, members_to_repeat}, + {Py_tp_members, members_to_repeat}, + {0, 0}, +}; + +PyType_Spec repeated_members_slots_spec = { + .name = "RepeatedMembersSlotClass", + .basicsize = sizeof(HeapCTypeWithDataObject), + .slots = repeated_members_slots, +}; + +static PyObject * +create_type_from_repeated_slots(PyObject *self, PyObject *variant_obj) +{ + PyObject *class = NULL; + int variant = PyLong_AsLong(variant_obj); + if (PyErr_Occurred()) { + return NULL; + } + switch (variant) { + case 0: + class = PyType_FromSpec(&repeated_doc_slots_spec); + break; + case 1: + class = PyType_FromSpec(&repeated_members_slots_spec); + break; + default: + PyErr_SetString(PyExc_ValueError, "bad test variant"); + break; + } + return class; +} + + +static PyObject * +make_immutable_type_with_base(PyObject *self, PyObject *base) +{ + assert(PyType_Check(base)); + PyType_Spec ImmutableSubclass_spec = { + .name = "ImmutableSubclass", + .basicsize = (int)((PyTypeObject*)base)->tp_basicsize, + .slots = empty_type_slots, + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE, + }; + return PyType_FromSpecWithBases(&ImmutableSubclass_spec, base); +} + +static PyObject * +make_type_with_base(PyObject *self, PyObject *base) +{ + assert(PyType_Check(base)); + PyType_Spec ImmutableSubclass_spec = { + .name = "_testcapi.Subclass", + .basicsize = (int)((PyTypeObject*)base)->tp_basicsize, + .slots = empty_type_slots, + .flags = Py_TPFLAGS_DEFAULT, + }; + return PyType_FromSpecWithBases(&ImmutableSubclass_spec, base); +} + + +static PyObject * +pyobject_getitemdata(PyObject *self, PyObject *o) +{ + void *pointer = PyObject_GetItemData(o); + if (pointer == NULL) { + return NULL; + } + return PyLong_FromVoidPtr(pointer); +} + + +static PyMethodDef TestMethods[] = { + {"pytype_fromspec_meta", pytype_fromspec_meta, METH_O}, + {"test_type_from_ephemeral_spec", test_type_from_ephemeral_spec, METH_NOARGS}, + {"create_type_from_repeated_slots", + create_type_from_repeated_slots, METH_O}, + {"test_from_spec_metatype_inheritance", test_from_spec_metatype_inheritance, + METH_NOARGS}, + {"test_from_spec_invalid_metatype_inheritance", + test_from_spec_invalid_metatype_inheritance, + METH_NOARGS}, + {"make_immutable_type_with_base", make_immutable_type_with_base, METH_O}, + {"make_type_with_base", make_type_with_base, METH_O}, + {"pyobject_getitemdata", pyobject_getitemdata, METH_O}, + {NULL}, +}; + + +PyDoc_STRVAR(heapdocctype__doc__, +"HeapDocCType(arg1, arg2)\n" +"--\n" +"\n" +"somedoc"); + +typedef struct { + PyObject_HEAD +} HeapDocCTypeObject; + +static PyType_Slot HeapDocCType_slots[] = { + {Py_tp_doc, (char*)heapdocctype__doc__}, + {0}, +}; + +static PyType_Spec HeapDocCType_spec = { + "_testcapi.HeapDocCType", + sizeof(HeapDocCTypeObject), + 0, + Py_TPFLAGS_DEFAULT, + HeapDocCType_slots +}; + +typedef struct { + PyObject_HEAD +} NullTpDocTypeObject; + +static PyType_Slot NullTpDocType_slots[] = { + {Py_tp_doc, NULL}, + {0, 0}, +}; + +static PyType_Spec NullTpDocType_spec = { + "_testcapi.NullTpDocType", + sizeof(NullTpDocTypeObject), + 0, + Py_TPFLAGS_DEFAULT, + NullTpDocType_slots +}; + + +PyDoc_STRVAR(heapgctype__doc__, +"A heap type with GC, and with overridden dealloc.\n\n" +"The 'value' attribute is set to 10 in __init__."); + +typedef struct { + PyObject_HEAD + int value; +} HeapCTypeObject; + +static struct PyMemberDef heapctype_members[] = { + {"value", T_INT, offsetof(HeapCTypeObject, value)}, + {NULL} /* Sentinel */ +}; + +static int +heapctype_init(PyObject *self, PyObject *args, PyObject *kwargs) +{ + ((HeapCTypeObject *)self)->value = 10; + return 0; +} + +static int +heapgcctype_traverse(HeapCTypeObject *self, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(self)); + return 0; +} + +static void +heapgcctype_dealloc(HeapCTypeObject *self) +{ + PyTypeObject *tp = Py_TYPE(self); + PyObject_GC_UnTrack(self); + PyObject_GC_Del(self); + Py_DECREF(tp); +} + +static PyType_Slot HeapGcCType_slots[] = { + {Py_tp_init, heapctype_init}, + {Py_tp_members, heapctype_members}, + {Py_tp_dealloc, heapgcctype_dealloc}, + {Py_tp_traverse, heapgcctype_traverse}, + {Py_tp_doc, (char*)heapgctype__doc__}, + {0, 0}, +}; + +static PyType_Spec HeapGcCType_spec = { + "_testcapi.HeapGcCType", + sizeof(HeapCTypeObject), + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, + HeapGcCType_slots +}; + +PyDoc_STRVAR(heapctype__doc__, +"A heap type without GC, but with overridden dealloc.\n\n" +"The 'value' attribute is set to 10 in __init__."); + +static void +heapctype_dealloc(HeapCTypeObject *self) +{ + PyTypeObject *tp = Py_TYPE(self); + PyObject_Free(self); + Py_DECREF(tp); +} + +static PyType_Slot HeapCType_slots[] = { + {Py_tp_init, heapctype_init}, + {Py_tp_members, heapctype_members}, + {Py_tp_dealloc, heapctype_dealloc}, + {Py_tp_doc, (char*)heapctype__doc__}, + {0, 0}, +}; + +static PyType_Spec HeapCType_spec = { + "_testcapi.HeapCType", + sizeof(HeapCTypeObject), + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + HeapCType_slots +}; + +PyDoc_STRVAR(heapctypesubclass__doc__, +"Subclass of HeapCType, without GC.\n\n" +"__init__ sets the 'value' attribute to 10 and 'value2' to 20."); + +typedef struct { + HeapCTypeObject base; + int value2; +} HeapCTypeSubclassObject; + +static int +heapctypesubclass_init(PyObject *self, PyObject *args, PyObject *kwargs) +{ + /* Call __init__ of the superclass */ + if (heapctype_init(self, args, kwargs) < 0) { + return -1; + } + /* Initialize additional element */ + ((HeapCTypeSubclassObject *)self)->value2 = 20; + return 0; +} + +static struct PyMemberDef heapctypesubclass_members[] = { + {"value2", T_INT, offsetof(HeapCTypeSubclassObject, value2)}, + {NULL} /* Sentinel */ +}; + +static PyType_Slot HeapCTypeSubclass_slots[] = { + {Py_tp_init, heapctypesubclass_init}, + {Py_tp_members, heapctypesubclass_members}, + {Py_tp_doc, (char*)heapctypesubclass__doc__}, + {0, 0}, +}; + +static PyType_Spec HeapCTypeSubclass_spec = { + "_testcapi.HeapCTypeSubclass", + sizeof(HeapCTypeSubclassObject), + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + HeapCTypeSubclass_slots +}; + +PyDoc_STRVAR(heapctypewithbuffer__doc__, +"Heap type with buffer support.\n\n" +"The buffer is set to [b'1', b'2', b'3', b'4']"); + +typedef struct { + HeapCTypeObject base; + char buffer[4]; +} HeapCTypeWithBufferObject; + +static int +heapctypewithbuffer_getbuffer(HeapCTypeWithBufferObject *self, Py_buffer *view, int flags) +{ + self->buffer[0] = '1'; + self->buffer[1] = '2'; + self->buffer[2] = '3'; + self->buffer[3] = '4'; + return PyBuffer_FillInfo( + view, (PyObject*)self, (void *)self->buffer, 4, 1, flags); +} + +static void +heapctypewithbuffer_releasebuffer(HeapCTypeWithBufferObject *self, Py_buffer *view) +{ + assert(view->obj == (void*) self); +} + +static PyType_Slot HeapCTypeWithBuffer_slots[] = { + {Py_bf_getbuffer, heapctypewithbuffer_getbuffer}, + {Py_bf_releasebuffer, heapctypewithbuffer_releasebuffer}, + {Py_tp_doc, (char*)heapctypewithbuffer__doc__}, + {0, 0}, +}; + +static PyType_Spec HeapCTypeWithBuffer_spec = { + "_testcapi.HeapCTypeWithBuffer", + sizeof(HeapCTypeWithBufferObject), + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + HeapCTypeWithBuffer_slots +}; + +PyDoc_STRVAR(heapctypesubclasswithfinalizer__doc__, +"Subclass of HeapCType with a finalizer that reassigns __class__.\n\n" +"__class__ is set to plain HeapCTypeSubclass during finalization.\n" +"__init__ sets the 'value' attribute to 10 and 'value2' to 20."); + +static int +heapctypesubclasswithfinalizer_init(PyObject *self, PyObject *args, PyObject *kwargs) +{ + PyTypeObject *base = (PyTypeObject *)PyType_GetSlot(Py_TYPE(self), Py_tp_base); + initproc base_init = PyType_GetSlot(base, Py_tp_init); + base_init(self, args, kwargs); + return 0; +} + +static void +heapctypesubclasswithfinalizer_finalize(PyObject *self) +{ + PyObject *oldtype = NULL, *newtype = NULL, *refcnt = NULL; + + /* Save the current exception, if any. */ + PyObject *exc = PyErr_GetRaisedException(); + + if (_testcapimodule == NULL) { + goto cleanup_finalize; + } + PyObject *m = PyState_FindModule(_testcapimodule); + if (m == NULL) { + goto cleanup_finalize; + } + oldtype = PyObject_GetAttrString(m, "HeapCTypeSubclassWithFinalizer"); + if (oldtype == NULL) { + goto cleanup_finalize; + } + newtype = PyObject_GetAttrString(m, "HeapCTypeSubclass"); + if (newtype == NULL) { + goto cleanup_finalize; + } + + if (PyObject_SetAttrString(self, "__class__", newtype) < 0) { + goto cleanup_finalize; + } + refcnt = PyLong_FromSsize_t(Py_REFCNT(oldtype)); + if (refcnt == NULL) { + goto cleanup_finalize; + } + if (PyObject_SetAttrString(oldtype, "refcnt_in_del", refcnt) < 0) { + goto cleanup_finalize; + } + Py_DECREF(refcnt); + refcnt = PyLong_FromSsize_t(Py_REFCNT(newtype)); + if (refcnt == NULL) { + goto cleanup_finalize; + } + if (PyObject_SetAttrString(newtype, "refcnt_in_del", refcnt) < 0) { + goto cleanup_finalize; + } + +cleanup_finalize: + Py_XDECREF(oldtype); + Py_XDECREF(newtype); + Py_XDECREF(refcnt); + + /* Restore the saved exception. */ + PyErr_SetRaisedException(exc); +} + +static PyType_Slot HeapCTypeSubclassWithFinalizer_slots[] = { + {Py_tp_init, heapctypesubclasswithfinalizer_init}, + {Py_tp_members, heapctypesubclass_members}, + {Py_tp_finalize, heapctypesubclasswithfinalizer_finalize}, + {Py_tp_doc, (char*)heapctypesubclasswithfinalizer__doc__}, + {0, 0}, +}; + +static PyType_Spec HeapCTypeSubclassWithFinalizer_spec = { + "_testcapi.HeapCTypeSubclassWithFinalizer", + sizeof(HeapCTypeSubclassObject), + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_FINALIZE, + HeapCTypeSubclassWithFinalizer_slots +}; + +static PyType_Slot HeapCTypeMetaclass_slots[] = { + {0}, +}; + +static PyType_Spec HeapCTypeMetaclass_spec = { + "_testcapi.HeapCTypeMetaclass", + sizeof(PyHeapTypeObject), + sizeof(PyMemberDef), + Py_TPFLAGS_DEFAULT, + HeapCTypeMetaclass_slots +}; + +static PyObject * +heap_ctype_metaclass_custom_tp_new(PyTypeObject *tp, PyObject *args, PyObject *kwargs) +{ + return PyType_Type.tp_new(tp, args, kwargs); +} + +static PyType_Slot HeapCTypeMetaclassCustomNew_slots[] = { + { Py_tp_new, heap_ctype_metaclass_custom_tp_new }, + {0}, +}; + +static PyType_Spec HeapCTypeMetaclassCustomNew_spec = { + "_testcapi.HeapCTypeMetaclassCustomNew", + sizeof(PyHeapTypeObject), + sizeof(PyMemberDef), + Py_TPFLAGS_DEFAULT, + HeapCTypeMetaclassCustomNew_slots +}; + +static PyType_Spec HeapCTypeMetaclassNullNew_spec = { + .name = "_testcapi.HeapCTypeMetaclassNullNew", + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION, + .slots = empty_type_slots +}; + + +typedef struct { + PyObject_HEAD + PyObject *dict; +} HeapCTypeWithDictObject; + +static void +heapctypewithdict_dealloc(HeapCTypeWithDictObject* self) +{ + + PyTypeObject *tp = Py_TYPE(self); + Py_XDECREF(self->dict); + PyObject_Free(self); + Py_DECREF(tp); +} + +static PyGetSetDef heapctypewithdict_getsetlist[] = { + {"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict}, + {NULL} /* Sentinel */ +}; + +static struct PyMemberDef heapctypewithdict_members[] = { + {"dictobj", T_OBJECT, offsetof(HeapCTypeWithDictObject, dict)}, + {"__dictoffset__", T_PYSSIZET, offsetof(HeapCTypeWithDictObject, dict), READONLY}, + {NULL} /* Sentinel */ +}; + +static PyType_Slot HeapCTypeWithDict_slots[] = { + {Py_tp_members, heapctypewithdict_members}, + {Py_tp_getset, heapctypewithdict_getsetlist}, + {Py_tp_dealloc, heapctypewithdict_dealloc}, + {0, 0}, +}; + +static PyType_Spec HeapCTypeWithDict_spec = { + "_testcapi.HeapCTypeWithDict", + sizeof(HeapCTypeWithDictObject), + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + HeapCTypeWithDict_slots +}; + +static PyType_Spec HeapCTypeWithDict2_spec = { + "_testcapi.HeapCTypeWithDict2", + sizeof(HeapCTypeWithDictObject), + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + HeapCTypeWithDict_slots +}; + +static int +heapmanaged_traverse(HeapCTypeObject *self, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(self)); + return _PyObject_VisitManagedDict((PyObject *)self, visit, arg); +} + +static int +heapmanaged_clear(HeapCTypeObject *self) +{ + _PyObject_ClearManagedDict((PyObject *)self); + return 0; +} + +static void +heapmanaged_dealloc(HeapCTypeObject *self) +{ + PyTypeObject *tp = Py_TYPE(self); + _PyObject_ClearManagedDict((PyObject *)self); + PyObject_GC_UnTrack(self); + PyObject_GC_Del(self); + Py_DECREF(tp); +} + +static PyType_Slot HeapCTypeWithManagedDict_slots[] = { + {Py_tp_traverse, heapmanaged_traverse}, + {Py_tp_getset, heapctypewithdict_getsetlist}, + {Py_tp_clear, heapmanaged_clear}, + {Py_tp_dealloc, heapmanaged_dealloc}, + {0, 0}, +}; + +static PyType_Spec HeapCTypeWithManagedDict_spec = { + "_testcapi.HeapCTypeWithManagedDict", + sizeof(PyObject), + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_MANAGED_DICT, + HeapCTypeWithManagedDict_slots +}; + +static void +heapctypewithmanagedweakref_dealloc(PyObject* self) +{ + + PyTypeObject *tp = Py_TYPE(self); + PyObject_ClearWeakRefs(self); + PyObject_GC_UnTrack(self); + PyObject_GC_Del(self); + Py_DECREF(tp); +} + +static PyType_Slot HeapCTypeWithManagedWeakref_slots[] = { + {Py_tp_traverse, heapgcctype_traverse}, + {Py_tp_getset, heapctypewithdict_getsetlist}, + {Py_tp_dealloc, heapctypewithmanagedweakref_dealloc}, + {0, 0}, +}; + +static PyType_Spec HeapCTypeWithManagedWeakref_spec = { + "_testcapi.HeapCTypeWithManagedWeakref", + sizeof(PyObject), + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_MANAGED_WEAKREF, + HeapCTypeWithManagedWeakref_slots +}; + +static struct PyMemberDef heapctypewithnegativedict_members[] = { + {"dictobj", T_OBJECT, offsetof(HeapCTypeWithDictObject, dict)}, + {"__dictoffset__", T_PYSSIZET, -(Py_ssize_t)sizeof(void*), READONLY}, + {NULL} /* Sentinel */ +}; + +static PyType_Slot HeapCTypeWithNegativeDict_slots[] = { + {Py_tp_members, heapctypewithnegativedict_members}, + {Py_tp_getset, heapctypewithdict_getsetlist}, + {Py_tp_dealloc, heapctypewithdict_dealloc}, + {0, 0}, +}; + +static PyType_Spec HeapCTypeWithNegativeDict_spec = { + "_testcapi.HeapCTypeWithNegativeDict", + sizeof(HeapCTypeWithDictObject), + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + HeapCTypeWithNegativeDict_slots +}; + +typedef struct { + PyObject_HEAD + PyObject *weakreflist; +} HeapCTypeWithWeakrefObject; + +static struct PyMemberDef heapctypewithweakref_members[] = { + {"weakreflist", T_OBJECT, offsetof(HeapCTypeWithWeakrefObject, weakreflist)}, + {"__weaklistoffset__", T_PYSSIZET, + offsetof(HeapCTypeWithWeakrefObject, weakreflist), READONLY}, + {NULL} /* Sentinel */ +}; + +static void +heapctypewithweakref_dealloc(HeapCTypeWithWeakrefObject* self) +{ + + PyTypeObject *tp = Py_TYPE(self); + if (self->weakreflist != NULL) + PyObject_ClearWeakRefs((PyObject *) self); + Py_XDECREF(self->weakreflist); + PyObject_Free(self); + Py_DECREF(tp); +} + +static PyType_Slot HeapCTypeWithWeakref_slots[] = { + {Py_tp_members, heapctypewithweakref_members}, + {Py_tp_dealloc, heapctypewithweakref_dealloc}, + {0, 0}, +}; + +static PyType_Spec HeapCTypeWithWeakref_spec = { + "_testcapi.HeapCTypeWithWeakref", + sizeof(HeapCTypeWithWeakrefObject), + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + HeapCTypeWithWeakref_slots +}; + +static PyType_Spec HeapCTypeWithWeakref2_spec = { + "_testcapi.HeapCTypeWithWeakref2", + sizeof(HeapCTypeWithWeakrefObject), + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + HeapCTypeWithWeakref_slots +}; + +PyDoc_STRVAR(heapctypesetattr__doc__, +"A heap type without GC, but with overridden __setattr__.\n\n" +"The 'value' attribute is set to 10 in __init__ and updated via attribute setting."); + +typedef struct { + PyObject_HEAD + long value; +} HeapCTypeSetattrObject; + +static struct PyMemberDef heapctypesetattr_members[] = { + {"pvalue", T_LONG, offsetof(HeapCTypeSetattrObject, value)}, + {NULL} /* Sentinel */ +}; + +static int +heapctypesetattr_init(PyObject *self, PyObject *args, PyObject *kwargs) +{ + ((HeapCTypeSetattrObject *)self)->value = 10; + return 0; +} + +static void +heapctypesetattr_dealloc(HeapCTypeSetattrObject *self) +{ + PyTypeObject *tp = Py_TYPE(self); + PyObject_Free(self); + Py_DECREF(tp); +} + +static int +heapctypesetattr_setattro(HeapCTypeSetattrObject *self, PyObject *attr, PyObject *value) +{ + PyObject *svalue = PyUnicode_FromString("value"); + if (svalue == NULL) + return -1; + int eq = PyObject_RichCompareBool(svalue, attr, Py_EQ); + Py_DECREF(svalue); + if (eq < 0) + return -1; + if (!eq) { + return PyObject_GenericSetAttr((PyObject*) self, attr, value); + } + if (value == NULL) { + self->value = 0; + return 0; + } + PyObject *ivalue = PyNumber_Long(value); + if (ivalue == NULL) + return -1; + long v = PyLong_AsLong(ivalue); + Py_DECREF(ivalue); + if (v == -1 && PyErr_Occurred()) + return -1; + self->value = v; + return 0; +} + +static PyType_Slot HeapCTypeSetattr_slots[] = { + {Py_tp_init, heapctypesetattr_init}, + {Py_tp_members, heapctypesetattr_members}, + {Py_tp_setattro, heapctypesetattr_setattro}, + {Py_tp_dealloc, heapctypesetattr_dealloc}, + {Py_tp_doc, (char*)heapctypesetattr__doc__}, + {0, 0}, +}; + +static PyType_Spec HeapCTypeSetattr_spec = { + "_testcapi.HeapCTypeSetattr", + sizeof(HeapCTypeSetattrObject), + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + HeapCTypeSetattr_slots +}; + +PyDoc_STRVAR(HeapCCollection_doc, +"Tuple-like heap type that uses PyObject_GetItemData for items."); + +static PyObject* +HeapCCollection_new(PyTypeObject *subtype, PyObject *args, PyObject *kwds) +{ + PyObject *self = NULL; + PyObject *result = NULL; + + Py_ssize_t size = PyTuple_GET_SIZE(args); + self = subtype->tp_alloc(subtype, size); + if (!self) { + goto finally; + } + PyObject **data = PyObject_GetItemData(self); + if (!data) { + goto finally; + } + + for (Py_ssize_t i = 0; i < size; i++) { + data[i] = Py_NewRef(PyTuple_GET_ITEM(args, i)); + } + + result = self; + self = NULL; + finally: + Py_XDECREF(self); + return result; +} + +static Py_ssize_t +HeapCCollection_length(PyVarObject *self) +{ + return Py_SIZE(self); +} + +static PyObject* +HeapCCollection_item(PyObject *self, Py_ssize_t i) +{ + if (i < 0 || i >= Py_SIZE(self)) { + return PyErr_Format(PyExc_IndexError, "index %zd out of range", i); + } + PyObject **data = PyObject_GetItemData(self); + if (!data) { + return NULL; + } + return Py_NewRef(data[i]); +} + +static int +HeapCCollection_traverse(PyObject *self, visitproc visit, void *arg) +{ + PyObject **data = PyObject_GetItemData(self); + if (!data) { + return -1; + } + for (Py_ssize_t i = 0; i < Py_SIZE(self); i++) { + Py_VISIT(data[i]); + } + return 0; +} + +static int +HeapCCollection_clear(PyObject *self) +{ + PyObject **data = PyObject_GetItemData(self); + if (!data) { + return -1; + } + Py_ssize_t size = Py_SIZE(self); + Py_SET_SIZE(self, 0); + for (Py_ssize_t i = 0; i < size; i++) { + Py_CLEAR(data[i]); + } + return 0; +} + +static void +HeapCCollection_dealloc(PyObject *self) +{ + PyTypeObject *tp = Py_TYPE(self); + HeapCCollection_clear(self); + PyObject_GC_UnTrack(self); + tp->tp_free(self); + Py_DECREF(tp); +} + +static PyType_Slot HeapCCollection_slots[] = { + {Py_tp_new, HeapCCollection_new}, + {Py_sq_length, HeapCCollection_length}, + {Py_sq_item, HeapCCollection_item}, + {Py_tp_traverse, HeapCCollection_traverse}, + {Py_tp_clear, HeapCCollection_clear}, + {Py_tp_dealloc, HeapCCollection_dealloc}, + {Py_tp_doc, (void *)HeapCCollection_doc}, + {0, 0}, +}; + +static PyType_Spec HeapCCollection_spec = { + .name = "_testcapi.HeapCCollection", + .basicsize = sizeof(PyVarObject), + .itemsize = sizeof(PyObject*), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_ITEMS_AT_END), + .slots = HeapCCollection_slots, +}; + +int +_PyTestCapi_Init_Heaptype(PyObject *m) { + _testcapimodule = PyModule_GetDef(m); + + if (PyModule_AddFunctions(m, TestMethods) < 0) { + return -1; + } + + PyObject *HeapDocCType = PyType_FromSpec(&HeapDocCType_spec); + if (HeapDocCType == NULL) { + return -1; + } + PyModule_AddObject(m, "HeapDocCType", HeapDocCType); + + /* bpo-41832: Add a new type to test PyType_FromSpec() + now can accept a NULL tp_doc slot. */ + PyObject *NullTpDocType = PyType_FromSpec(&NullTpDocType_spec); + if (NullTpDocType == NULL) { + return -1; + } + PyModule_AddObject(m, "NullTpDocType", NullTpDocType); + + PyObject *HeapGcCType = PyType_FromSpec(&HeapGcCType_spec); + if (HeapGcCType == NULL) { + return -1; + } + PyModule_AddObject(m, "HeapGcCType", HeapGcCType); + + PyObject *HeapCType = PyType_FromSpec(&HeapCType_spec); + if (HeapCType == NULL) { + return -1; + } + PyObject *subclass_bases = PyTuple_Pack(1, HeapCType); + if (subclass_bases == NULL) { + return -1; + } + PyObject *HeapCTypeSubclass = PyType_FromSpecWithBases(&HeapCTypeSubclass_spec, subclass_bases); + if (HeapCTypeSubclass == NULL) { + return -1; + } + Py_DECREF(subclass_bases); + PyModule_AddObject(m, "HeapCTypeSubclass", HeapCTypeSubclass); + + PyObject *HeapCTypeWithDict = PyType_FromSpec(&HeapCTypeWithDict_spec); + if (HeapCTypeWithDict == NULL) { + return -1; + } + PyModule_AddObject(m, "HeapCTypeWithDict", HeapCTypeWithDict); + + PyObject *HeapCTypeWithDict2 = PyType_FromSpec(&HeapCTypeWithDict2_spec); + if (HeapCTypeWithDict2 == NULL) { + return -1; + } + PyModule_AddObject(m, "HeapCTypeWithDict2", HeapCTypeWithDict2); + + PyObject *HeapCTypeWithNegativeDict = PyType_FromSpec(&HeapCTypeWithNegativeDict_spec); + if (HeapCTypeWithNegativeDict == NULL) { + return -1; + } + PyModule_AddObject(m, "HeapCTypeWithNegativeDict", HeapCTypeWithNegativeDict); + + PyObject *HeapCTypeWithManagedDict = PyType_FromSpec(&HeapCTypeWithManagedDict_spec); + if (HeapCTypeWithManagedDict == NULL) { + return -1; + } + PyModule_AddObject(m, "HeapCTypeWithManagedDict", HeapCTypeWithManagedDict); + + PyObject *HeapCTypeWithManagedWeakref = PyType_FromSpec(&HeapCTypeWithManagedWeakref_spec); + if (HeapCTypeWithManagedWeakref == NULL) { + return -1; + } + PyModule_AddObject(m, "HeapCTypeWithManagedWeakref", HeapCTypeWithManagedWeakref); + + PyObject *HeapCTypeWithWeakref = PyType_FromSpec(&HeapCTypeWithWeakref_spec); + if (HeapCTypeWithWeakref == NULL) { + return -1; + } + PyModule_AddObject(m, "HeapCTypeWithWeakref", HeapCTypeWithWeakref); + + PyObject *HeapCTypeWithWeakref2 = PyType_FromSpec(&HeapCTypeWithWeakref2_spec); + if (HeapCTypeWithWeakref2 == NULL) { + return -1; + } + PyModule_AddObject(m, "HeapCTypeWithWeakref2", HeapCTypeWithWeakref2); + + PyObject *HeapCTypeWithBuffer = PyType_FromSpec(&HeapCTypeWithBuffer_spec); + if (HeapCTypeWithBuffer == NULL) { + return -1; + } + PyModule_AddObject(m, "HeapCTypeWithBuffer", HeapCTypeWithBuffer); + + PyObject *HeapCTypeSetattr = PyType_FromSpec(&HeapCTypeSetattr_spec); + if (HeapCTypeSetattr == NULL) { + return -1; + } + PyModule_AddObject(m, "HeapCTypeSetattr", HeapCTypeSetattr); + + PyObject *subclass_with_finalizer_bases = PyTuple_Pack(1, HeapCTypeSubclass); + if (subclass_with_finalizer_bases == NULL) { + return -1; + } + PyObject *HeapCTypeSubclassWithFinalizer = PyType_FromSpecWithBases( + &HeapCTypeSubclassWithFinalizer_spec, subclass_with_finalizer_bases); + if (HeapCTypeSubclassWithFinalizer == NULL) { + return -1; + } + Py_DECREF(subclass_with_finalizer_bases); + PyModule_AddObject(m, "HeapCTypeSubclassWithFinalizer", HeapCTypeSubclassWithFinalizer); + + PyObject *HeapCTypeMetaclass = PyType_FromMetaclass( + &PyType_Type, m, &HeapCTypeMetaclass_spec, (PyObject *) &PyType_Type); + if (HeapCTypeMetaclass == NULL) { + return -1; + } + PyModule_AddObject(m, "HeapCTypeMetaclass", HeapCTypeMetaclass); + + PyObject *HeapCTypeMetaclassCustomNew = PyType_FromMetaclass( + &PyType_Type, m, &HeapCTypeMetaclassCustomNew_spec, (PyObject *) &PyType_Type); + if (HeapCTypeMetaclassCustomNew == NULL) { + return -1; + } + PyModule_AddObject(m, "HeapCTypeMetaclassCustomNew", HeapCTypeMetaclassCustomNew); + + PyObject *HeapCTypeMetaclassNullNew = PyType_FromMetaclass( + &PyType_Type, m, &HeapCTypeMetaclassNullNew_spec, (PyObject *) &PyType_Type); + if (HeapCTypeMetaclassNullNew == NULL) { + return -1; + } + PyModule_AddObject(m, "HeapCTypeMetaclassNullNew", HeapCTypeMetaclassNullNew); + + PyObject *HeapCCollection = PyType_FromMetaclass( + NULL, m, &HeapCCollection_spec, NULL); + if (HeapCCollection == NULL) { + return -1; + } + int rc = PyModule_AddType(m, (PyTypeObject *)HeapCCollection); + Py_DECREF(HeapCCollection); + if (rc < 0) { + return -1; + } + + return 0; +} diff --git a/Modules/_testcapi/heaptype_relative.c b/Modules/_testcapi/heaptype_relative.c new file mode 100644 index 00000000..c247ca33 --- /dev/null +++ b/Modules/_testcapi/heaptype_relative.c @@ -0,0 +1,343 @@ +#define Py_LIMITED_API 0x030c0000 // 3.12 +#include "parts.h" +#include <stddef.h> // max_align_t +#include <string.h> // memset + +#ifdef LIMITED_API_AVAILABLE + +static PyType_Slot empty_slots[] = { + {0, NULL}, +}; + +static PyObject * +make_sized_heaptypes(PyObject *module, PyObject *args) +{ + PyObject *base = NULL; + PyObject *sub = NULL; + PyObject *instance = NULL; + PyObject *result = NULL; + + int extra_base_size, basicsize; + + int r = PyArg_ParseTuple(args, "ii", &extra_base_size, &basicsize); + if (!r) { + goto finally; + } + + PyType_Spec base_spec = { + .name = "_testcapi.Base", + .basicsize = sizeof(PyObject) + extra_base_size, + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + .slots = empty_slots, + }; + PyType_Spec sub_spec = { + .name = "_testcapi.Sub", + .basicsize = basicsize, + .flags = Py_TPFLAGS_DEFAULT, + .slots = empty_slots, + }; + + base = PyType_FromMetaclass(NULL, module, &base_spec, NULL); + if (!base) { + goto finally; + } + sub = PyType_FromMetaclass(NULL, module, &sub_spec, base); + if (!sub) { + goto finally; + } + instance = PyObject_CallNoArgs(sub); + if (!instance) { + goto finally; + } + char *data_ptr = PyObject_GetTypeData(instance, (PyTypeObject *)sub); + if (!data_ptr) { + goto finally; + } + Py_ssize_t data_size = PyType_GetTypeDataSize((PyTypeObject *)sub); + if (data_size < 0) { + goto finally; + } + + result = Py_BuildValue("OOOKnn", base, sub, instance, + (unsigned long long)data_ptr, + (Py_ssize_t)(data_ptr - (char*)instance), + data_size); + finally: + Py_XDECREF(base); + Py_XDECREF(sub); + Py_XDECREF(instance); + return result; +} + +static PyObject * +var_heaptype_set_data_to_3s( + PyObject *self, PyTypeObject *defining_class, + PyObject **args, Py_ssize_t nargs, PyObject *kwnames) +{ + void *data_ptr = PyObject_GetTypeData(self, defining_class); + if (!data_ptr) { + return NULL; + } + Py_ssize_t data_size = PyType_GetTypeDataSize(defining_class); + if (data_size < 0) { + return NULL; + } + memset(data_ptr, 3, data_size); + Py_RETURN_NONE; +} + +static PyObject * +var_heaptype_get_data(PyObject *self, PyTypeObject *defining_class, + PyObject **args, Py_ssize_t nargs, PyObject *kwnames) +{ + void *data_ptr = PyObject_GetTypeData(self, defining_class); + if (!data_ptr) { + return NULL; + } + Py_ssize_t data_size = PyType_GetTypeDataSize(defining_class); + if (data_size < 0) { + return NULL; + } + return PyBytes_FromStringAndSize(data_ptr, data_size); +} + +static PyMethodDef var_heaptype_methods[] = { + {"set_data_to_3s", _PyCFunction_CAST(var_heaptype_set_data_to_3s), + METH_METHOD | METH_FASTCALL | METH_KEYWORDS}, + {"get_data", _PyCFunction_CAST(var_heaptype_get_data), + METH_METHOD | METH_FASTCALL | METH_KEYWORDS}, + {NULL}, +}; + +static PyObject * +subclass_var_heaptype(PyObject *module, PyObject *args) +{ + PyObject *result = NULL; + + PyObject *base; // borrowed from args + int basicsize, itemsize; + long pfunc; + + int r = PyArg_ParseTuple(args, "Oiil", &base, &basicsize, &itemsize, &pfunc); + if (!r) { + goto finally; + } + + PyType_Slot slots[] = { + {Py_tp_methods, var_heaptype_methods}, + {0, NULL}, + }; + + PyType_Spec sub_spec = { + .name = "_testcapi.Sub", + .basicsize = basicsize, + .itemsize = itemsize, + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_ITEMS_AT_END, + .slots = slots, + }; + + result = PyType_FromMetaclass(NULL, module, &sub_spec, base); + finally: + return result; +} + +static PyObject * +subclass_heaptype(PyObject *module, PyObject *args) +{ + PyObject *result = NULL; + + PyObject *base; // borrowed from args + int basicsize, itemsize; + + int r = PyArg_ParseTuple(args, "Oii", &base, &basicsize, &itemsize); + if (!r) { + goto finally; + } + + PyType_Slot slots[] = { + {Py_tp_methods, var_heaptype_methods}, + {0, NULL}, + }; + + PyType_Spec sub_spec = { + .name = "_testcapi.Sub", + .basicsize = basicsize, + .itemsize = itemsize, + .flags = Py_TPFLAGS_DEFAULT, + .slots = slots, + }; + + result = PyType_FromMetaclass(NULL, module, &sub_spec, base); + finally: + return result; +} + +static PyMemberDef * +heaptype_with_member_extract_and_check_memb(PyObject *self) +{ + PyMemberDef *def = PyType_GetSlot(Py_TYPE(self), Py_tp_members); + if (!def) { + if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_ValueError, "tp_members is NULL"); + } + return NULL; + } + if (!def[0].name) { + PyErr_SetString(PyExc_ValueError, "tp_members[0] is NULL"); + return NULL; + } + if (def[1].name) { + PyErr_SetString(PyExc_ValueError, "tp_members[1] is not NULL"); + return NULL; + } + if (strcmp(def[0].name, "memb")) { + PyErr_SetString(PyExc_ValueError, "tp_members[0] is not for `memb`"); + return NULL; + } + if (def[0].flags) { + PyErr_SetString(PyExc_ValueError, "tp_members[0] has flags set"); + return NULL; + } + return def; +} + +static PyObject * +heaptype_with_member_get_memb(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyMemberDef *def = heaptype_with_member_extract_and_check_memb(self); + return PyMember_GetOne((const char *)self, def); +} + +static PyObject * +heaptype_with_member_set_memb(PyObject *self, PyObject *value) +{ + PyMemberDef *def = heaptype_with_member_extract_and_check_memb(self); + int r = PyMember_SetOne((char *)self, def, value); + if (r < 0) { + return NULL; + } + Py_RETURN_NONE; +} + +static PyObject * +get_memb_offset(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyMemberDef *def = heaptype_with_member_extract_and_check_memb(self); + return PyLong_FromSsize_t(def->offset); +} + +static PyObject * +heaptype_with_member_get_memb_relative(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyMemberDef def = {"memb", Py_T_BYTE, sizeof(PyObject), Py_RELATIVE_OFFSET}; + return PyMember_GetOne((const char *)self, &def); +} + +static PyObject * +heaptype_with_member_set_memb_relative(PyObject *self, PyObject *value) +{ + PyMemberDef def = {"memb", Py_T_BYTE, sizeof(PyObject), Py_RELATIVE_OFFSET}; + int r = PyMember_SetOne((char *)self, &def, value); + if (r < 0) { + return NULL; + } + Py_RETURN_NONE; +} + +static PyMethodDef heaptype_with_member_methods[] = { + {"get_memb", heaptype_with_member_get_memb, METH_NOARGS}, + {"set_memb", heaptype_with_member_set_memb, METH_O}, + {"get_memb_offset", get_memb_offset, METH_NOARGS}, + {"get_memb_relative", heaptype_with_member_get_memb_relative, METH_NOARGS}, + {"set_memb_relative", heaptype_with_member_set_memb_relative, METH_O}, + {NULL}, +}; + +static PyObject * +make_heaptype_with_member(PyObject *module, PyObject *args) +{ + PyObject *base = NULL; + PyObject *result = NULL; + + int extra_base_size, basicsize, offset, add_flag; + + int r = PyArg_ParseTuple(args, "iiip", &extra_base_size, &basicsize, &offset, &add_flag); + if (!r) { + goto finally; + } + + PyType_Spec base_spec = { + .name = "_testcapi.Base", + .basicsize = sizeof(PyObject) + extra_base_size, + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + .slots = empty_slots, + }; + base = PyType_FromMetaclass(NULL, module, &base_spec, NULL); + if (!base) { + goto finally; + } + + PyMemberDef members[] = { + {"memb", Py_T_BYTE, offset, add_flag ? Py_RELATIVE_OFFSET : 0}, + {0}, + }; + PyType_Slot slots[] = { + {Py_tp_members, members}, + {Py_tp_methods, heaptype_with_member_methods}, + {0, NULL}, + }; + + PyType_Spec sub_spec = { + .name = "_testcapi.Sub", + .basicsize = basicsize, + .flags = Py_TPFLAGS_DEFAULT, + .slots = slots, + }; + + result = PyType_FromMetaclass(NULL, module, &sub_spec, base); + finally: + Py_XDECREF(base); + return result; +} + + +static PyObject * +test_alignof_max_align_t(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + // We define ALIGNOF_MAX_ALIGN_T even if the compiler doesn't support + // max_align_t. Double-check that it's correct. + assert(ALIGNOF_MAX_ALIGN_T > 0); + assert(ALIGNOF_MAX_ALIGN_T >= _Alignof(long long)); + assert(ALIGNOF_MAX_ALIGN_T >= _Alignof(long double)); + assert(ALIGNOF_MAX_ALIGN_T >= _Alignof(void*)); + assert(ALIGNOF_MAX_ALIGN_T >= _Alignof(void (*)(void))); + + // Ensure it's a power of two + assert((ALIGNOF_MAX_ALIGN_T & (ALIGNOF_MAX_ALIGN_T - 1)) == 0); + + Py_RETURN_NONE; +} + +static PyMethodDef TestMethods[] = { + {"make_sized_heaptypes", make_sized_heaptypes, METH_VARARGS}, + {"subclass_var_heaptype", subclass_var_heaptype, METH_VARARGS}, + {"subclass_heaptype", subclass_heaptype, METH_VARARGS}, + {"make_heaptype_with_member", make_heaptype_with_member, METH_VARARGS}, + {"test_alignof_max_align_t", test_alignof_max_align_t, METH_NOARGS}, + {NULL}, +}; + +int +_PyTestCapi_Init_HeaptypeRelative(PyObject *m) { + if (PyModule_AddFunctions(m, TestMethods) < 0) { + return -1; + } + + if (PyModule_AddIntMacro(m, ALIGNOF_MAX_ALIGN_T) < 0) { + return -1; + } + + return 0; +} + +#endif // LIMITED_API_AVAILABLE diff --git a/Modules/_testcapi/immortal.c b/Modules/_testcapi/immortal.c new file mode 100644 index 00000000..9f813898 --- /dev/null +++ b/Modules/_testcapi/immortal.c @@ -0,0 +1,47 @@ +#include "parts.h" + +int verify_immortality(PyObject *object) +{ + assert(_Py_IsImmortal(object)); + Py_ssize_t old_count = Py_REFCNT(object); + for (int j = 0; j < 10000; j++) { + Py_DECREF(object); + } + Py_ssize_t current_count = Py_REFCNT(object); + return old_count == current_count; +} + +static PyObject * +test_immortal_builtins(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject *objects[] = {Py_True, Py_False, Py_None, Py_Ellipsis}; + Py_ssize_t n = Py_ARRAY_LENGTH(objects); + for (Py_ssize_t i = 0; i < n; i++) { + assert(verify_immortality(objects[i])); + } + Py_RETURN_NONE; +} + +static PyObject * +test_immortal_small_ints(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + for (int i = -5; i <= 256; i++) { + assert(verify_immortality(PyLong_FromLong(i))); + } + Py_RETURN_NONE; +} + +static PyMethodDef test_methods[] = { + {"test_immortal_builtins", test_immortal_builtins, METH_NOARGS}, + {"test_immortal_small_ints", test_immortal_small_ints, METH_NOARGS}, + {NULL}, +}; + +int +_PyTestCapi_Init_Immortal(PyObject *mod) +{ + if (PyModule_AddFunctions(mod, test_methods) < 0) { + return -1; + } + return 0; +} diff --git a/Modules/_testcapi/long.c b/Modules/_testcapi/long.c new file mode 100644 index 00000000..61dd9659 --- /dev/null +++ b/Modules/_testcapi/long.c @@ -0,0 +1,570 @@ +#include "parts.h" + + +static PyObject * +raiseTestError(const char* test_name, const char* msg) +{ + PyErr_Format(PyExc_AssertionError, "%s: %s", test_name, msg); + return NULL; +} + +/* Tests of PyLong_{As, From}{Unsigned,}Long(), and + PyLong_{As, From}{Unsigned,}LongLong(). + + Note that the meat of the test is contained in testcapi_long.h. + This is revolting, but delicate code duplication is worse: "almost + exactly the same" code is needed to test long long, but the ubiquitous + dependence on type names makes it impossible to use a parameterized + function. A giant macro would be even worse than this. A C++ template + would be perfect. + + The "report an error" functions are deliberately not part of the #include + file: if the test fails, you can set a breakpoint in the appropriate + error function directly, and crawl back from there in the debugger. +*/ + +#define UNBIND(X) Py_DECREF(X); (X) = NULL + +static PyObject * +raise_test_long_error(const char* msg) +{ + return raiseTestError("test_long_api", msg); +} + +#define TESTNAME test_long_api_inner +#define TYPENAME long +#define F_S_TO_PY PyLong_FromLong +#define F_PY_TO_S PyLong_AsLong +#define F_U_TO_PY PyLong_FromUnsignedLong +#define F_PY_TO_U PyLong_AsUnsignedLong + +#include "testcapi_long.h" + +static PyObject * +test_long_api(PyObject* self, PyObject *Py_UNUSED(ignored)) +{ + return TESTNAME(raise_test_long_error); +} + +#undef TESTNAME +#undef TYPENAME +#undef F_S_TO_PY +#undef F_PY_TO_S +#undef F_U_TO_PY +#undef F_PY_TO_U + +static PyObject * +raise_test_longlong_error(const char* msg) +{ + return raiseTestError("test_longlong_api", msg); +} + +#define TESTNAME test_longlong_api_inner +#define TYPENAME long long +#define F_S_TO_PY PyLong_FromLongLong +#define F_PY_TO_S PyLong_AsLongLong +#define F_U_TO_PY PyLong_FromUnsignedLongLong +#define F_PY_TO_U PyLong_AsUnsignedLongLong + +#include "testcapi_long.h" + +static PyObject * +test_longlong_api(PyObject* self, PyObject *args) +{ + return TESTNAME(raise_test_longlong_error); +} + +#undef TESTNAME +#undef TYPENAME +#undef F_S_TO_PY +#undef F_PY_TO_S +#undef F_U_TO_PY +#undef F_PY_TO_U + +/* Test the PyLong_AsLongAndOverflow API. General conversion to PY_LONG + is tested by test_long_api_inner. This test will concentrate on proper + handling of overflow. +*/ + +static PyObject * +test_long_and_overflow(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject *num, *one, *temp; + long value; + int overflow; + + /* Test that overflow is set properly for a large value. */ + /* num is a number larger than LONG_MAX even on 64-bit platforms */ + num = PyLong_FromString("FFFFFFFFFFFFFFFFFFFFFFFF", NULL, 16); + if (num == NULL) + return NULL; + overflow = 1234; + value = PyLong_AsLongAndOverflow(num, &overflow); + Py_DECREF(num); + if (value == -1 && PyErr_Occurred()) + return NULL; + if (value != -1) + return raiseTestError("test_long_and_overflow", + "return value was not set to -1"); + if (overflow != 1) + return raiseTestError("test_long_and_overflow", + "overflow was not set to 1"); + + /* Same again, with num = LONG_MAX + 1 */ + num = PyLong_FromLong(LONG_MAX); + if (num == NULL) + return NULL; + one = PyLong_FromLong(1L); + if (one == NULL) { + Py_DECREF(num); + return NULL; + } + temp = PyNumber_Add(num, one); + Py_DECREF(one); + Py_SETREF(num, temp); + if (num == NULL) + return NULL; + overflow = 0; + value = PyLong_AsLongAndOverflow(num, &overflow); + Py_DECREF(num); + if (value == -1 && PyErr_Occurred()) + return NULL; + if (value != -1) + return raiseTestError("test_long_and_overflow", + "return value was not set to -1"); + if (overflow != 1) + return raiseTestError("test_long_and_overflow", + "overflow was not set to 1"); + + /* Test that overflow is set properly for a large negative value. */ + /* num is a number smaller than LONG_MIN even on 64-bit platforms */ + num = PyLong_FromString("-FFFFFFFFFFFFFFFFFFFFFFFF", NULL, 16); + if (num == NULL) + return NULL; + overflow = 1234; + value = PyLong_AsLongAndOverflow(num, &overflow); + Py_DECREF(num); + if (value == -1 && PyErr_Occurred()) + return NULL; + if (value != -1) + return raiseTestError("test_long_and_overflow", + "return value was not set to -1"); + if (overflow != -1) + return raiseTestError("test_long_and_overflow", + "overflow was not set to -1"); + + /* Same again, with num = LONG_MIN - 1 */ + num = PyLong_FromLong(LONG_MIN); + if (num == NULL) + return NULL; + one = PyLong_FromLong(1L); + if (one == NULL) { + Py_DECREF(num); + return NULL; + } + temp = PyNumber_Subtract(num, one); + Py_DECREF(one); + Py_SETREF(num, temp); + if (num == NULL) + return NULL; + overflow = 0; + value = PyLong_AsLongAndOverflow(num, &overflow); + Py_DECREF(num); + if (value == -1 && PyErr_Occurred()) + return NULL; + if (value != -1) + return raiseTestError("test_long_and_overflow", + "return value was not set to -1"); + if (overflow != -1) + return raiseTestError("test_long_and_overflow", + "overflow was not set to -1"); + + /* Test that overflow is cleared properly for small values. */ + num = PyLong_FromString("FF", NULL, 16); + if (num == NULL) + return NULL; + overflow = 1234; + value = PyLong_AsLongAndOverflow(num, &overflow); + Py_DECREF(num); + if (value == -1 && PyErr_Occurred()) + return NULL; + if (value != 0xFF) + return raiseTestError("test_long_and_overflow", + "expected return value 0xFF"); + if (overflow != 0) + return raiseTestError("test_long_and_overflow", + "overflow was not cleared"); + + num = PyLong_FromString("-FF", NULL, 16); + if (num == NULL) + return NULL; + overflow = 0; + value = PyLong_AsLongAndOverflow(num, &overflow); + Py_DECREF(num); + if (value == -1 && PyErr_Occurred()) + return NULL; + if (value != -0xFF) + return raiseTestError("test_long_and_overflow", + "expected return value 0xFF"); + if (overflow != 0) + return raiseTestError("test_long_and_overflow", + "overflow was set incorrectly"); + + num = PyLong_FromLong(LONG_MAX); + if (num == NULL) + return NULL; + overflow = 1234; + value = PyLong_AsLongAndOverflow(num, &overflow); + Py_DECREF(num); + if (value == -1 && PyErr_Occurred()) + return NULL; + if (value != LONG_MAX) + return raiseTestError("test_long_and_overflow", + "expected return value LONG_MAX"); + if (overflow != 0) + return raiseTestError("test_long_and_overflow", + "overflow was not cleared"); + + num = PyLong_FromLong(LONG_MIN); + if (num == NULL) + return NULL; + overflow = 0; + value = PyLong_AsLongAndOverflow(num, &overflow); + Py_DECREF(num); + if (value == -1 && PyErr_Occurred()) + return NULL; + if (value != LONG_MIN) + return raiseTestError("test_long_and_overflow", + "expected return value LONG_MIN"); + if (overflow != 0) + return raiseTestError("test_long_and_overflow", + "overflow was not cleared"); + + Py_RETURN_NONE; +} + +/* Test the PyLong_AsLongLongAndOverflow API. General conversion to + long long is tested by test_long_api_inner. This test will + concentrate on proper handling of overflow. +*/ + +static PyObject * +test_long_long_and_overflow(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject *num, *one, *temp; + long long value; + int overflow; + + /* Test that overflow is set properly for a large value. */ + /* num is a number larger than LLONG_MAX on a typical machine. */ + num = PyLong_FromString("FFFFFFFFFFFFFFFFFFFFFFFF", NULL, 16); + if (num == NULL) + return NULL; + overflow = 1234; + value = PyLong_AsLongLongAndOverflow(num, &overflow); + Py_DECREF(num); + if (value == -1 && PyErr_Occurred()) + return NULL; + if (value != -1) + return raiseTestError("test_long_long_and_overflow", + "return value was not set to -1"); + if (overflow != 1) + return raiseTestError("test_long_long_and_overflow", + "overflow was not set to 1"); + + /* Same again, with num = LLONG_MAX + 1 */ + num = PyLong_FromLongLong(LLONG_MAX); + if (num == NULL) + return NULL; + one = PyLong_FromLong(1L); + if (one == NULL) { + Py_DECREF(num); + return NULL; + } + temp = PyNumber_Add(num, one); + Py_DECREF(one); + Py_SETREF(num, temp); + if (num == NULL) + return NULL; + overflow = 0; + value = PyLong_AsLongLongAndOverflow(num, &overflow); + Py_DECREF(num); + if (value == -1 && PyErr_Occurred()) + return NULL; + if (value != -1) + return raiseTestError("test_long_long_and_overflow", + "return value was not set to -1"); + if (overflow != 1) + return raiseTestError("test_long_long_and_overflow", + "overflow was not set to 1"); + + /* Test that overflow is set properly for a large negative value. */ + /* num is a number smaller than LLONG_MIN on a typical platform */ + num = PyLong_FromString("-FFFFFFFFFFFFFFFFFFFFFFFF", NULL, 16); + if (num == NULL) + return NULL; + overflow = 1234; + value = PyLong_AsLongLongAndOverflow(num, &overflow); + Py_DECREF(num); + if (value == -1 && PyErr_Occurred()) + return NULL; + if (value != -1) + return raiseTestError("test_long_long_and_overflow", + "return value was not set to -1"); + if (overflow != -1) + return raiseTestError("test_long_long_and_overflow", + "overflow was not set to -1"); + + /* Same again, with num = LLONG_MIN - 1 */ + num = PyLong_FromLongLong(LLONG_MIN); + if (num == NULL) + return NULL; + one = PyLong_FromLong(1L); + if (one == NULL) { + Py_DECREF(num); + return NULL; + } + temp = PyNumber_Subtract(num, one); + Py_DECREF(one); + Py_SETREF(num, temp); + if (num == NULL) + return NULL; + overflow = 0; + value = PyLong_AsLongLongAndOverflow(num, &overflow); + Py_DECREF(num); + if (value == -1 && PyErr_Occurred()) + return NULL; + if (value != -1) + return raiseTestError("test_long_long_and_overflow", + "return value was not set to -1"); + if (overflow != -1) + return raiseTestError("test_long_long_and_overflow", + "overflow was not set to -1"); + + /* Test that overflow is cleared properly for small values. */ + num = PyLong_FromString("FF", NULL, 16); + if (num == NULL) + return NULL; + overflow = 1234; + value = PyLong_AsLongLongAndOverflow(num, &overflow); + Py_DECREF(num); + if (value == -1 && PyErr_Occurred()) + return NULL; + if (value != 0xFF) + return raiseTestError("test_long_long_and_overflow", + "expected return value 0xFF"); + if (overflow != 0) + return raiseTestError("test_long_long_and_overflow", + "overflow was not cleared"); + + num = PyLong_FromString("-FF", NULL, 16); + if (num == NULL) + return NULL; + overflow = 0; + value = PyLong_AsLongLongAndOverflow(num, &overflow); + Py_DECREF(num); + if (value == -1 && PyErr_Occurred()) + return NULL; + if (value != -0xFF) + return raiseTestError("test_long_long_and_overflow", + "expected return value 0xFF"); + if (overflow != 0) + return raiseTestError("test_long_long_and_overflow", + "overflow was set incorrectly"); + + num = PyLong_FromLongLong(LLONG_MAX); + if (num == NULL) + return NULL; + overflow = 1234; + value = PyLong_AsLongLongAndOverflow(num, &overflow); + Py_DECREF(num); + if (value == -1 && PyErr_Occurred()) + return NULL; + if (value != LLONG_MAX) + return raiseTestError("test_long_long_and_overflow", + "expected return value LLONG_MAX"); + if (overflow != 0) + return raiseTestError("test_long_long_and_overflow", + "overflow was not cleared"); + + num = PyLong_FromLongLong(LLONG_MIN); + if (num == NULL) + return NULL; + overflow = 0; + value = PyLong_AsLongLongAndOverflow(num, &overflow); + Py_DECREF(num); + if (value == -1 && PyErr_Occurred()) + return NULL; + if (value != LLONG_MIN) + return raiseTestError("test_long_long_and_overflow", + "expected return value LLONG_MIN"); + if (overflow != 0) + return raiseTestError("test_long_long_and_overflow", + "overflow was not cleared"); + + Py_RETURN_NONE; +} + +/* Test the PyLong_As{Size,Ssize}_t API. At present this just tests that + non-integer arguments are handled correctly. It should be extended to + test overflow handling. + */ + +static PyObject * +test_long_as_size_t(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + size_t out_u; + Py_ssize_t out_s; + + Py_INCREF(Py_None); + + out_u = PyLong_AsSize_t(Py_None); + if (out_u != (size_t)-1 || !PyErr_Occurred()) + return raiseTestError("test_long_as_size_t", + "PyLong_AsSize_t(None) didn't complain"); + if (!PyErr_ExceptionMatches(PyExc_TypeError)) + return raiseTestError("test_long_as_size_t", + "PyLong_AsSize_t(None) raised " + "something other than TypeError"); + PyErr_Clear(); + + out_s = PyLong_AsSsize_t(Py_None); + if (out_s != (Py_ssize_t)-1 || !PyErr_Occurred()) + return raiseTestError("test_long_as_size_t", + "PyLong_AsSsize_t(None) didn't complain"); + if (!PyErr_ExceptionMatches(PyExc_TypeError)) + return raiseTestError("test_long_as_size_t", + "PyLong_AsSsize_t(None) raised " + "something other than TypeError"); + PyErr_Clear(); + + /* Py_INCREF(Py_None) omitted - we already have a reference to it. */ + return Py_None; +} + +static PyObject * +test_long_as_unsigned_long_long_mask(PyObject *self, + PyObject *Py_UNUSED(ignored)) +{ + unsigned long long res = PyLong_AsUnsignedLongLongMask(NULL); + + if (res != (unsigned long long)-1 || !PyErr_Occurred()) { + return raiseTestError("test_long_as_unsigned_long_long_mask", + "PyLong_AsUnsignedLongLongMask(NULL) didn't " + "complain"); + } + if (!PyErr_ExceptionMatches(PyExc_SystemError)) { + return raiseTestError("test_long_as_unsigned_long_long_mask", + "PyLong_AsUnsignedLongLongMask(NULL) raised " + "something other than SystemError"); + } + PyErr_Clear(); + Py_RETURN_NONE; +} + +/* Test the PyLong_AsDouble API. At present this just tests that + non-integer arguments are handled correctly. + */ + +static PyObject * +test_long_as_double(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + double out; + + Py_INCREF(Py_None); + + out = PyLong_AsDouble(Py_None); + if (out != -1.0 || !PyErr_Occurred()) + return raiseTestError("test_long_as_double", + "PyLong_AsDouble(None) didn't complain"); + if (!PyErr_ExceptionMatches(PyExc_TypeError)) + return raiseTestError("test_long_as_double", + "PyLong_AsDouble(None) raised " + "something other than TypeError"); + PyErr_Clear(); + + /* Py_INCREF(Py_None) omitted - we already have a reference to it. */ + return Py_None; +} + +/* Simple test of _PyLong_NumBits and _PyLong_Sign. */ +static PyObject * +test_long_numbits(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + struct triple { + long input; + size_t nbits; + int sign; + } testcases[] = {{0, 0, 0}, + {1L, 1, 1}, + {-1L, 1, -1}, + {2L, 2, 1}, + {-2L, 2, -1}, + {3L, 2, 1}, + {-3L, 2, -1}, + {4L, 3, 1}, + {-4L, 3, -1}, + {0x7fffL, 15, 1}, /* one Python int digit */ + {-0x7fffL, 15, -1}, + {0xffffL, 16, 1}, + {-0xffffL, 16, -1}, + {0xfffffffL, 28, 1}, + {-0xfffffffL, 28, -1}}; + size_t i; + + for (i = 0; i < Py_ARRAY_LENGTH(testcases); ++i) { + size_t nbits; + int sign; + PyObject *plong; + + plong = PyLong_FromLong(testcases[i].input); + if (plong == NULL) + return NULL; + nbits = _PyLong_NumBits(plong); + sign = _PyLong_Sign(plong); + + Py_DECREF(plong); + if (nbits != testcases[i].nbits) + return raiseTestError("test_long_numbits", + "wrong result for _PyLong_NumBits"); + if (sign != testcases[i].sign) + return raiseTestError("test_long_numbits", + "wrong result for _PyLong_Sign"); + } + Py_RETURN_NONE; +} + +static PyObject * +check_long_compact_api(PyObject *self, PyObject *arg) +{ + assert(PyLong_Check(arg)); + int is_compact = PyUnstable_Long_IsCompact((PyLongObject*)arg); + Py_ssize_t value = -1; + if (is_compact) { + value = PyUnstable_Long_CompactValue((PyLongObject*)arg); + } + return Py_BuildValue("in", is_compact, value); +} + +static PyMethodDef test_methods[] = { + {"test_long_and_overflow", test_long_and_overflow, METH_NOARGS}, + {"test_long_api", test_long_api, METH_NOARGS}, + {"test_long_as_double", test_long_as_double, METH_NOARGS}, + {"test_long_as_size_t", test_long_as_size_t, METH_NOARGS}, + {"test_long_as_unsigned_long_long_mask", test_long_as_unsigned_long_long_mask, METH_NOARGS}, + {"test_long_long_and_overflow",test_long_long_and_overflow, METH_NOARGS}, + {"test_long_numbits", test_long_numbits, METH_NOARGS}, + {"test_longlong_api", test_longlong_api, METH_NOARGS}, + {"call_long_compact_api", check_long_compact_api, METH_O}, + {NULL}, +}; + +int +_PyTestCapi_Init_Long(PyObject *mod) +{ + if (PyModule_AddFunctions(mod, test_methods) < 0) { + return -1; + } + + return 0; +} diff --git a/Modules/_testcapi/mem.c b/Modules/_testcapi/mem.c new file mode 100644 index 00000000..af32e966 --- /dev/null +++ b/Modules/_testcapi/mem.c @@ -0,0 +1,724 @@ +#include "parts.h" + +#include <stddef.h> + + +typedef struct { + PyMemAllocatorEx alloc; + + size_t malloc_size; + size_t calloc_nelem; + size_t calloc_elsize; + void *realloc_ptr; + size_t realloc_new_size; + void *free_ptr; + void *ctx; +} alloc_hook_t; + +static void * +hook_malloc(void *ctx, size_t size) +{ + alloc_hook_t *hook = (alloc_hook_t *)ctx; + hook->ctx = ctx; + hook->malloc_size = size; + return hook->alloc.malloc(hook->alloc.ctx, size); +} + +static void * +hook_calloc(void *ctx, size_t nelem, size_t elsize) +{ + alloc_hook_t *hook = (alloc_hook_t *)ctx; + hook->ctx = ctx; + hook->calloc_nelem = nelem; + hook->calloc_elsize = elsize; + return hook->alloc.calloc(hook->alloc.ctx, nelem, elsize); +} + +static void * +hook_realloc(void *ctx, void *ptr, size_t new_size) +{ + alloc_hook_t *hook = (alloc_hook_t *)ctx; + hook->ctx = ctx; + hook->realloc_ptr = ptr; + hook->realloc_new_size = new_size; + return hook->alloc.realloc(hook->alloc.ctx, ptr, new_size); +} + +static void +hook_free(void *ctx, void *ptr) +{ + alloc_hook_t *hook = (alloc_hook_t *)ctx; + hook->ctx = ctx; + hook->free_ptr = ptr; + hook->alloc.free(hook->alloc.ctx, ptr); +} + +/* 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) +{ + if (FmHook.installed) { + return; + } + FmHook.installed = 1; + + PyMemAllocatorEx alloc; + 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, PyObject *Py_UNUSED(ignored)) +{ + fm_remove_hooks(); + Py_RETURN_NONE; +} + +static PyObject * +test_setallocators(PyMemAllocatorDomain domain) +{ + PyObject *res = NULL; + const char *error_msg; + alloc_hook_t hook; + + memset(&hook, 0, sizeof(hook)); + + PyMemAllocatorEx alloc; + alloc.ctx = &hook; + alloc.malloc = &hook_malloc; + alloc.calloc = &hook_calloc; + alloc.realloc = &hook_realloc; + alloc.free = &hook_free; + PyMem_GetAllocator(domain, &hook.alloc); + PyMem_SetAllocator(domain, &alloc); + + /* malloc, realloc, free */ + size_t size = 42; + hook.ctx = NULL; + void *ptr; + switch(domain) { + case PYMEM_DOMAIN_RAW: + ptr = PyMem_RawMalloc(size); + break; + case PYMEM_DOMAIN_MEM: + ptr = PyMem_Malloc(size); + break; + case PYMEM_DOMAIN_OBJ: + ptr = PyObject_Malloc(size); + break; + default: + ptr = NULL; + break; + } + +#define CHECK_CTX(FUNC) \ + if (hook.ctx != &hook) { \ + error_msg = FUNC " wrong context"; \ + goto fail; \ + } \ + hook.ctx = NULL; /* reset for next check */ + + if (ptr == NULL) { + error_msg = "malloc failed"; + goto fail; + } + CHECK_CTX("malloc"); + if (hook.malloc_size != size) { + error_msg = "malloc invalid size"; + goto fail; + } + + size_t size2 = 200; + void *ptr2; + switch(domain) { + case PYMEM_DOMAIN_RAW: + ptr2 = PyMem_RawRealloc(ptr, size2); + break; + case PYMEM_DOMAIN_MEM: + ptr2 = PyMem_Realloc(ptr, size2); + break; + case PYMEM_DOMAIN_OBJ: + ptr2 = PyObject_Realloc(ptr, size2); + break; + default: + ptr2 = NULL; + break; + } + + if (ptr2 == NULL) { + error_msg = "realloc failed"; + goto fail; + } + CHECK_CTX("realloc"); + if (hook.realloc_ptr != ptr || hook.realloc_new_size != size2) { + error_msg = "realloc invalid parameters"; + goto fail; + } + + switch(domain) { + case PYMEM_DOMAIN_RAW: + PyMem_RawFree(ptr2); + break; + case PYMEM_DOMAIN_MEM: + PyMem_Free(ptr2); + break; + case PYMEM_DOMAIN_OBJ: + PyObject_Free(ptr2); + break; + } + + CHECK_CTX("free"); + if (hook.free_ptr != ptr2) { + error_msg = "free invalid pointer"; + goto fail; + } + + /* calloc, free */ + size_t nelem = 2; + size_t elsize = 5; + switch(domain) { + case PYMEM_DOMAIN_RAW: + ptr = PyMem_RawCalloc(nelem, elsize); + break; + case PYMEM_DOMAIN_MEM: + ptr = PyMem_Calloc(nelem, elsize); + break; + case PYMEM_DOMAIN_OBJ: + ptr = PyObject_Calloc(nelem, elsize); + break; + default: + ptr = NULL; + break; + } + + if (ptr == NULL) { + error_msg = "calloc failed"; + goto fail; + } + CHECK_CTX("calloc"); + if (hook.calloc_nelem != nelem || hook.calloc_elsize != elsize) { + error_msg = "calloc invalid nelem or elsize"; + goto fail; + } + + hook.free_ptr = NULL; + switch(domain) { + case PYMEM_DOMAIN_RAW: + PyMem_RawFree(ptr); + break; + case PYMEM_DOMAIN_MEM: + PyMem_Free(ptr); + break; + case PYMEM_DOMAIN_OBJ: + PyObject_Free(ptr); + break; + } + + CHECK_CTX("calloc free"); + if (hook.free_ptr != ptr) { + error_msg = "calloc free invalid pointer"; + goto fail; + } + + res = Py_NewRef(Py_None); + goto finally; + +fail: + PyErr_SetString(PyExc_RuntimeError, error_msg); + +finally: + PyMem_SetAllocator(domain, &hook.alloc); + return res; + +#undef CHECK_CTX +} + +static PyObject * +test_pyobject_setallocators(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return test_setallocators(PYMEM_DOMAIN_OBJ); +} + +static PyObject * +test_pyobject_new(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject *obj; + PyTypeObject *type = &PyBaseObject_Type; + PyTypeObject *var_type = &PyBytes_Type; + + // PyObject_New() + obj = PyObject_New(PyObject, type); + if (obj == NULL) { + goto alloc_failed; + } + Py_DECREF(obj); + + // PyObject_NEW() + obj = PyObject_NEW(PyObject, type); + if (obj == NULL) { + goto alloc_failed; + } + Py_DECREF(obj); + + // PyObject_NewVar() + obj = PyObject_NewVar(PyObject, var_type, 3); + if (obj == NULL) { + goto alloc_failed; + } + Py_DECREF(obj); + + // PyObject_NEW_VAR() + obj = PyObject_NEW_VAR(PyObject, var_type, 3); + if (obj == NULL) { + goto alloc_failed; + } + Py_DECREF(obj); + + Py_RETURN_NONE; + +alloc_failed: + PyErr_NoMemory(); + return NULL; +} + +static PyObject * +test_pymem_alloc0(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + void *ptr; + + ptr = PyMem_RawMalloc(0); + if (ptr == NULL) { + PyErr_SetString(PyExc_RuntimeError, + "PyMem_RawMalloc(0) returns NULL"); + return NULL; + } + PyMem_RawFree(ptr); + + ptr = PyMem_RawCalloc(0, 0); + if (ptr == NULL) { + PyErr_SetString(PyExc_RuntimeError, + "PyMem_RawCalloc(0, 0) returns NULL"); + return NULL; + } + PyMem_RawFree(ptr); + + ptr = PyMem_Malloc(0); + if (ptr == NULL) { + PyErr_SetString(PyExc_RuntimeError, + "PyMem_Malloc(0) returns NULL"); + return NULL; + } + PyMem_Free(ptr); + + ptr = PyMem_Calloc(0, 0); + if (ptr == NULL) { + PyErr_SetString(PyExc_RuntimeError, + "PyMem_Calloc(0, 0) returns NULL"); + return NULL; + } + PyMem_Free(ptr); + + ptr = PyObject_Malloc(0); + if (ptr == NULL) { + PyErr_SetString(PyExc_RuntimeError, + "PyObject_Malloc(0) returns NULL"); + return NULL; + } + PyObject_Free(ptr); + + ptr = PyObject_Calloc(0, 0); + if (ptr == NULL) { + PyErr_SetString(PyExc_RuntimeError, + "PyObject_Calloc(0, 0) returns NULL"); + return NULL; + } + PyObject_Free(ptr); + + Py_RETURN_NONE; +} + +static PyObject * +test_pymem_getallocatorsname(PyObject *self, PyObject *args) +{ + const char *name = _PyMem_GetCurrentAllocatorName(); + if (name == NULL) { + PyErr_SetString(PyExc_RuntimeError, "cannot get allocators name"); + return NULL; + } + return PyUnicode_FromString(name); +} + +static PyObject * +test_pymem_setrawallocators(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return test_setallocators(PYMEM_DOMAIN_RAW); +} + +static PyObject * +test_pymem_setallocators(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return test_setallocators(PYMEM_DOMAIN_MEM); +} + +static PyObject * +pyobject_malloc_without_gil(PyObject *self, PyObject *args) +{ + char *buffer; + + /* Deliberate bug to test debug hooks on Python memory allocators: + call PyObject_Malloc() without holding the GIL */ + Py_BEGIN_ALLOW_THREADS + buffer = PyObject_Malloc(10); + Py_END_ALLOW_THREADS + + PyObject_Free(buffer); + + Py_RETURN_NONE; +} + +static PyObject * +pymem_buffer_overflow(PyObject *self, PyObject *args) +{ + char *buffer; + + /* Deliberate buffer overflow to check that PyMem_Free() detects + the overflow when debug hooks are installed. */ + buffer = PyMem_Malloc(16); + if (buffer == NULL) { + PyErr_NoMemory(); + return NULL; + } + buffer[16] = 'x'; + PyMem_Free(buffer); + + Py_RETURN_NONE; +} + +static PyObject * +pymem_api_misuse(PyObject *self, PyObject *args) +{ + char *buffer; + + /* Deliberate misusage of Python allocators: + allococate with PyMem but release with PyMem_Raw. */ + buffer = PyMem_Malloc(16); + PyMem_RawFree(buffer); + + Py_RETURN_NONE; +} + +static PyObject * +pymem_malloc_without_gil(PyObject *self, PyObject *args) +{ + char *buffer; + + /* Deliberate bug to test debug hooks on Python memory allocators: + call PyMem_Malloc() without holding the GIL */ + Py_BEGIN_ALLOW_THREADS + buffer = PyMem_Malloc(10); + Py_END_ALLOW_THREADS + + PyMem_Free(buffer); + + Py_RETURN_NONE; +} + +static PyObject * +test_pyobject_is_freed(const char *test_name, PyObject *op) +{ + if (!_PyObject_IsFreed(op)) { + PyErr_SetString(PyExc_AssertionError, + "object is not seen as freed"); + return NULL; + } + Py_RETURN_NONE; +} + +static PyObject * +check_pyobject_null_is_freed(PyObject *self, PyObject *Py_UNUSED(args)) +{ + PyObject *op = NULL; + return test_pyobject_is_freed("check_pyobject_null_is_freed", op); +} + + +static PyObject * +check_pyobject_uninitialized_is_freed(PyObject *self, + PyObject *Py_UNUSED(args)) +{ + PyObject *op = (PyObject *)PyObject_Malloc(sizeof(PyObject)); + if (op == NULL) { + return NULL; + } + /* Initialize reference count to avoid early crash in ceval or GC */ + Py_SET_REFCNT(op, 1); + /* object fields like ob_type are uninitialized! */ + return test_pyobject_is_freed("check_pyobject_uninitialized_is_freed", op); +} + + +static PyObject * +check_pyobject_forbidden_bytes_is_freed(PyObject *self, + PyObject *Py_UNUSED(args)) +{ + /* Allocate an incomplete PyObject structure: truncate 'ob_type' field */ + PyObject *op = (PyObject *)PyObject_Malloc(offsetof(PyObject, ob_type)); + if (op == NULL) { + return NULL; + } + /* Initialize reference count to avoid early crash in ceval or GC */ + Py_SET_REFCNT(op, 1); + /* ob_type field is after the memory block: part of "forbidden bytes" + when using debug hooks on memory allocators! */ + return test_pyobject_is_freed("check_pyobject_forbidden_bytes_is_freed", op); +} + + +static PyObject * +check_pyobject_freed_is_freed(PyObject *self, PyObject *Py_UNUSED(args)) +{ + /* This test would fail if run with the address sanitizer */ +#ifdef _Py_ADDRESS_SANITIZER + Py_RETURN_NONE; +#else + PyObject *op = PyObject_CallNoArgs((PyObject *)&PyBaseObject_Type); + if (op == NULL) { + return NULL; + } + Py_TYPE(op)->tp_dealloc(op); + /* Reset reference count to avoid early crash in ceval or GC */ + Py_SET_REFCNT(op, 1); + /* object memory is freed! */ + return test_pyobject_is_freed("check_pyobject_freed_is_freed", op); +#endif +} + +// Tracemalloc tests +static PyObject * +tracemalloc_track(PyObject *self, PyObject *args) +{ + unsigned int domain; + PyObject *ptr_obj; + Py_ssize_t size; + int release_gil = 0; + + if (!PyArg_ParseTuple(args, "IOn|i", + &domain, &ptr_obj, &size, &release_gil)) + { + return NULL; + } + void *ptr = PyLong_AsVoidPtr(ptr_obj); + if (PyErr_Occurred()) { + return NULL; + } + + int res; + if (release_gil) { + Py_BEGIN_ALLOW_THREADS + res = PyTraceMalloc_Track(domain, (uintptr_t)ptr, size); + Py_END_ALLOW_THREADS + } + else { + res = PyTraceMalloc_Track(domain, (uintptr_t)ptr, size); + } + if (res < 0) { + PyErr_SetString(PyExc_RuntimeError, "PyTraceMalloc_Track error"); + return NULL; + } + + Py_RETURN_NONE; +} + +static PyObject * +tracemalloc_untrack(PyObject *self, PyObject *args) +{ + unsigned int domain; + PyObject *ptr_obj; + + if (!PyArg_ParseTuple(args, "IO", &domain, &ptr_obj)) { + return NULL; + } + void *ptr = PyLong_AsVoidPtr(ptr_obj); + if (PyErr_Occurred()) { + return NULL; + } + + int res = PyTraceMalloc_Untrack(domain, (uintptr_t)ptr); + if (res < 0) { + PyErr_SetString(PyExc_RuntimeError, "PyTraceMalloc_Untrack error"); + return NULL; + } + + Py_RETURN_NONE; +} + +static PyObject * +tracemalloc_get_traceback(PyObject *self, PyObject *args) +{ + unsigned int domain; + PyObject *ptr_obj; + + if (!PyArg_ParseTuple(args, "IO", &domain, &ptr_obj)) { + return NULL; + } + void *ptr = PyLong_AsVoidPtr(ptr_obj); + if (PyErr_Occurred()) { + return NULL; + } + + return _PyTraceMalloc_GetTraceback(domain, (uintptr_t)ptr); +} + +static PyMethodDef test_methods[] = { + {"check_pyobject_forbidden_bytes_is_freed", + check_pyobject_forbidden_bytes_is_freed, METH_NOARGS}, + {"check_pyobject_freed_is_freed", check_pyobject_freed_is_freed, METH_NOARGS}, + {"check_pyobject_null_is_freed", check_pyobject_null_is_freed, METH_NOARGS}, + {"check_pyobject_uninitialized_is_freed", + check_pyobject_uninitialized_is_freed, METH_NOARGS}, + {"pymem_api_misuse", pymem_api_misuse, METH_NOARGS}, + {"pymem_buffer_overflow", pymem_buffer_overflow, METH_NOARGS}, + {"pymem_getallocatorsname", test_pymem_getallocatorsname, METH_NOARGS}, + {"pymem_malloc_without_gil", pymem_malloc_without_gil, METH_NOARGS}, + {"pyobject_malloc_without_gil", pyobject_malloc_without_gil, METH_NOARGS}, + {"remove_mem_hooks", remove_mem_hooks, METH_NOARGS, + PyDoc_STR("Remove memory hooks.")}, + {"set_nomemory", (PyCFunction)set_nomemory, METH_VARARGS, + PyDoc_STR("set_nomemory(start:int, stop:int = 0)")}, + {"test_pymem_alloc0", test_pymem_alloc0, METH_NOARGS}, + {"test_pymem_setallocators", test_pymem_setallocators, METH_NOARGS}, + {"test_pymem_setrawallocators", test_pymem_setrawallocators, METH_NOARGS}, + {"test_pyobject_new", test_pyobject_new, METH_NOARGS}, + {"test_pyobject_setallocators", test_pyobject_setallocators, METH_NOARGS}, + + // Tracemalloc tests + {"tracemalloc_track", tracemalloc_track, METH_VARARGS}, + {"tracemalloc_untrack", tracemalloc_untrack, METH_VARARGS}, + {"tracemalloc_get_traceback", tracemalloc_get_traceback, METH_VARARGS}, + {NULL}, +}; + +int +_PyTestCapi_Init_Mem(PyObject *mod) +{ + if (PyModule_AddFunctions(mod, test_methods) < 0) { + return -1; + } + + PyObject *v; +#ifdef WITH_PYMALLOC + v = Py_NewRef(Py_True); +#else + v = Py_NewRef(Py_False); +#endif + int rc = PyModule_AddObjectRef(mod, "WITH_PYMALLOC", v); + Py_DECREF(v); + if (rc < 0) { + return -1; + } + + return 0; +} diff --git a/Modules/_testcapi/parts.h b/Modules/_testcapi/parts.h new file mode 100644 index 00000000..f37be9b6 --- /dev/null +++ b/Modules/_testcapi/parts.h @@ -0,0 +1,54 @@ +#ifndef Py_TESTCAPI_PARTS_H +#define Py_TESTCAPI_PARTS_H + +#include "pyconfig.h" // for Py_TRACE_REFS + +// Figure out if Limited API is available for this build. If it isn't we won't +// build tests for it. +// Currently, only Py_TRACE_REFS disables Limited API. +#ifdef Py_TRACE_REFS +#undef LIMITED_API_AVAILABLE +#else +#define LIMITED_API_AVAILABLE 1 +#endif + +// Always enable assertions +#undef NDEBUG + +#if !defined(LIMITED_API_AVAILABLE) && defined(Py_LIMITED_API) +// Limited API being unavailable means that with Py_LIMITED_API defined +// we can't even include Python.h. +// Do nothing; the .c file that defined Py_LIMITED_API should also do nothing. + +#else + +#include "Python.h" + +int _PyTestCapi_Init_Vectorcall(PyObject *module); +int _PyTestCapi_Init_Heaptype(PyObject *module); +int _PyTestCapi_Init_Abstract(PyObject *module); +int _PyTestCapi_Init_Unicode(PyObject *module); +int _PyTestCapi_Init_GetArgs(PyObject *module); +int _PyTestCapi_Init_PyTime(PyObject *module); +int _PyTestCapi_Init_DateTime(PyObject *module); +int _PyTestCapi_Init_Docstring(PyObject *module); +int _PyTestCapi_Init_Mem(PyObject *module); +int _PyTestCapi_Init_Watchers(PyObject *module); +int _PyTestCapi_Init_Long(PyObject *module); +int _PyTestCapi_Init_Float(PyObject *module); +int _PyTestCapi_Init_Dict(PyObject *module); +int _PyTestCapi_Init_Structmember(PyObject *module); +int _PyTestCapi_Init_Exceptions(PyObject *module); +int _PyTestCapi_Init_Code(PyObject *module); +int _PyTestCapi_Init_Buffer(PyObject *module); +int _PyTestCapi_Init_PyOS(PyObject *module); +int _PyTestCapi_Init_Immortal(PyObject *module); +int _PyTestCapi_Init_GC(PyObject *mod); + +#ifdef LIMITED_API_AVAILABLE +int _PyTestCapi_Init_VectorcallLimited(PyObject *module); +int _PyTestCapi_Init_HeaptypeRelative(PyObject *module); +#endif // LIMITED_API_AVAILABLE + +#endif +#endif // Py_TESTCAPI_PARTS_H diff --git a/Modules/_testcapi/pyos.c b/Modules/_testcapi/pyos.c new file mode 100644 index 00000000..63140e91 --- /dev/null +++ b/Modules/_testcapi/pyos.c @@ -0,0 +1,60 @@ +#include "parts.h" + + +static PyObject * +test_PyOS_mystrnicmp(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + assert(PyOS_mystrnicmp("", "", 0) == 0); + assert(PyOS_mystrnicmp("", "", 1) == 0); + + assert(PyOS_mystrnicmp("insert", "ins", 3) == 0); + assert(PyOS_mystrnicmp("ins", "insert", 3) == 0); + assert(PyOS_mystrnicmp("insect", "insert", 3) == 0); + + assert(PyOS_mystrnicmp("insert", "insert", 6) == 0); + assert(PyOS_mystrnicmp("Insert", "insert", 6) == 0); + assert(PyOS_mystrnicmp("INSERT", "insert", 6) == 0); + assert(PyOS_mystrnicmp("insert", "insert", 10) == 0); + + assert(PyOS_mystrnicmp("invert", "insert", 6) == ('v' - 's')); + assert(PyOS_mystrnicmp("insert", "invert", 6) == ('s' - 'v')); + assert(PyOS_mystrnicmp("insert", "ins\0rt", 6) == 'e'); + + // GH-21845 + assert(PyOS_mystrnicmp("insert\0a", "insert\0b", 8) == 0); + + Py_RETURN_NONE; +} + +static PyObject * +test_PyOS_mystricmp(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + assert(PyOS_mystricmp("", "") == 0); + assert(PyOS_mystricmp("insert", "insert") == 0); + assert(PyOS_mystricmp("Insert", "insert") == 0); + assert(PyOS_mystricmp("INSERT", "insert") == 0); + assert(PyOS_mystricmp("insert", "ins") == 'e'); + assert(PyOS_mystricmp("ins", "insert") == -'e'); + + // GH-21845 + assert(PyOS_mystricmp("insert", "ins\0rt") == 'e'); + assert(PyOS_mystricmp("invert", "insert") == ('v' - 's')); + + Py_RETURN_NONE; +} + +static PyMethodDef test_methods[] = { + {"test_PyOS_mystrnicmp", test_PyOS_mystrnicmp, METH_NOARGS, NULL}, + {"test_PyOS_mystricmp", test_PyOS_mystricmp, METH_NOARGS, NULL}, + {NULL}, +}; + +int +_PyTestCapi_Init_PyOS(PyObject *mod) +{ + if (PyModule_AddFunctions(mod, test_methods) < 0) { + return -1; + } + + return 0; +} diff --git a/Modules/_testcapi/pytime.c b/Modules/_testcapi/pytime.c new file mode 100644 index 00000000..7422bafc --- /dev/null +++ b/Modules/_testcapi/pytime.c @@ -0,0 +1,274 @@ +#include "parts.h" + +#ifdef MS_WINDOWS +# include <winsock2.h> // struct timeval +#endif + +static PyObject * +test_pytime_fromseconds(PyObject *self, PyObject *args) +{ + int seconds; + if (!PyArg_ParseTuple(args, "i", &seconds)) { + return NULL; + } + _PyTime_t ts = _PyTime_FromSeconds(seconds); + return _PyTime_AsNanosecondsObject(ts); +} + +static int +check_time_rounding(int round) +{ + if (round != _PyTime_ROUND_FLOOR + && round != _PyTime_ROUND_CEILING + && round != _PyTime_ROUND_HALF_EVEN + && round != _PyTime_ROUND_UP) + { + PyErr_SetString(PyExc_ValueError, "invalid rounding"); + return -1; + } + return 0; +} + +static PyObject * +test_pytime_fromsecondsobject(PyObject *self, PyObject *args) +{ + PyObject *obj; + int round; + if (!PyArg_ParseTuple(args, "Oi", &obj, &round)) { + return NULL; + } + if (check_time_rounding(round) < 0) { + return NULL; + } + _PyTime_t ts; + if (_PyTime_FromSecondsObject(&ts, obj, round) == -1) { + return NULL; + } + return _PyTime_AsNanosecondsObject(ts); +} + +static PyObject * +test_pytime_assecondsdouble(PyObject *self, PyObject *args) +{ + PyObject *obj; + if (!PyArg_ParseTuple(args, "O", &obj)) { + return NULL; + } + _PyTime_t ts; + if (_PyTime_FromNanosecondsObject(&ts, obj) < 0) { + return NULL; + } + double d = _PyTime_AsSecondsDouble(ts); + return PyFloat_FromDouble(d); +} + +static PyObject * +test_PyTime_AsTimeval(PyObject *self, PyObject *args) +{ + PyObject *obj; + int round; + if (!PyArg_ParseTuple(args, "Oi", &obj, &round)) { + return NULL; + } + if (check_time_rounding(round) < 0) { + return NULL; + } + _PyTime_t t; + if (_PyTime_FromNanosecondsObject(&t, obj) < 0) { + return NULL; + } + struct timeval tv; + if (_PyTime_AsTimeval(t, &tv, round) < 0) { + return NULL; + } + + PyObject *seconds = PyLong_FromLongLong(tv.tv_sec); + if (seconds == NULL) { + return NULL; + } + return Py_BuildValue("Nl", seconds, (long)tv.tv_usec); +} + +static PyObject * +test_PyTime_AsTimeval_clamp(PyObject *self, PyObject *args) +{ + PyObject *obj; + int round; + if (!PyArg_ParseTuple(args, "Oi", &obj, &round)) { + return NULL; + } + if (check_time_rounding(round) < 0) { + return NULL; + } + _PyTime_t t; + if (_PyTime_FromNanosecondsObject(&t, obj) < 0) { + return NULL; + } + struct timeval tv; + _PyTime_AsTimeval_clamp(t, &tv, round); + + PyObject *seconds = PyLong_FromLongLong(tv.tv_sec); + if (seconds == NULL) { + return NULL; + } + return Py_BuildValue("Nl", seconds, (long)tv.tv_usec); +} + +#ifdef HAVE_CLOCK_GETTIME +static PyObject * +test_PyTime_AsTimespec(PyObject *self, PyObject *args) +{ + PyObject *obj; + if (!PyArg_ParseTuple(args, "O", &obj)) { + return NULL; + } + _PyTime_t t; + if (_PyTime_FromNanosecondsObject(&t, obj) < 0) { + return NULL; + } + struct timespec ts; + if (_PyTime_AsTimespec(t, &ts) == -1) { + return NULL; + } + return Py_BuildValue("Nl", _PyLong_FromTime_t(ts.tv_sec), ts.tv_nsec); +} + +static PyObject * +test_PyTime_AsTimespec_clamp(PyObject *self, PyObject *args) +{ + PyObject *obj; + if (!PyArg_ParseTuple(args, "O", &obj)) { + return NULL; + } + _PyTime_t t; + if (_PyTime_FromNanosecondsObject(&t, obj) < 0) { + return NULL; + } + struct timespec ts; + _PyTime_AsTimespec_clamp(t, &ts); + return Py_BuildValue("Nl", _PyLong_FromTime_t(ts.tv_sec), ts.tv_nsec); +} +#endif + +static PyObject * +test_PyTime_AsMilliseconds(PyObject *self, PyObject *args) +{ + PyObject *obj; + int round; + if (!PyArg_ParseTuple(args, "Oi", &obj, &round)) { + return NULL; + } + _PyTime_t t; + if (_PyTime_FromNanosecondsObject(&t, obj) < 0) { + return NULL; + } + if (check_time_rounding(round) < 0) { + return NULL; + } + _PyTime_t ms = _PyTime_AsMilliseconds(t, round); + _PyTime_t ns = _PyTime_FromNanoseconds(ms); + return _PyTime_AsNanosecondsObject(ns); +} + +static PyObject * +test_PyTime_AsMicroseconds(PyObject *self, PyObject *args) +{ + PyObject *obj; + int round; + if (!PyArg_ParseTuple(args, "Oi", &obj, &round)) { + return NULL; + } + _PyTime_t t; + if (_PyTime_FromNanosecondsObject(&t, obj) < 0) { + return NULL; + } + if (check_time_rounding(round) < 0) { + return NULL; + } + _PyTime_t us = _PyTime_AsMicroseconds(t, round); + _PyTime_t ns = _PyTime_FromNanoseconds(us); + return _PyTime_AsNanosecondsObject(ns); +} + +static PyObject * +test_pytime_object_to_time_t(PyObject *self, PyObject *args) +{ + PyObject *obj; + time_t sec; + int round; + if (!PyArg_ParseTuple(args, "Oi:pytime_object_to_time_t", &obj, &round)) { + return NULL; + } + if (check_time_rounding(round) < 0) { + return NULL; + } + if (_PyTime_ObjectToTime_t(obj, &sec, round) == -1) { + return NULL; + } + return _PyLong_FromTime_t(sec); +} + +static PyObject * +test_pytime_object_to_timeval(PyObject *self, PyObject *args) +{ + PyObject *obj; + time_t sec; + long usec; + int round; + if (!PyArg_ParseTuple(args, "Oi:pytime_object_to_timeval", &obj, &round)) { + return NULL; + } + if (check_time_rounding(round) < 0) { + return NULL; + } + if (_PyTime_ObjectToTimeval(obj, &sec, &usec, round) == -1) { + return NULL; + } + return Py_BuildValue("Nl", _PyLong_FromTime_t(sec), usec); +} + +static PyObject * +test_pytime_object_to_timespec(PyObject *self, PyObject *args) +{ + PyObject *obj; + time_t sec; + long nsec; + int round; + if (!PyArg_ParseTuple(args, "Oi:pytime_object_to_timespec", &obj, &round)) { + return NULL; + } + if (check_time_rounding(round) < 0) { + return NULL; + } + if (_PyTime_ObjectToTimespec(obj, &sec, &nsec, round) == -1) { + return NULL; + } + return Py_BuildValue("Nl", _PyLong_FromTime_t(sec), nsec); +} + +static PyMethodDef test_methods[] = { + {"PyTime_AsMicroseconds", test_PyTime_AsMicroseconds, METH_VARARGS}, + {"PyTime_AsMilliseconds", test_PyTime_AsMilliseconds, METH_VARARGS}, + {"PyTime_AsSecondsDouble", test_pytime_assecondsdouble, METH_VARARGS}, +#ifdef HAVE_CLOCK_GETTIME + {"PyTime_AsTimespec", test_PyTime_AsTimespec, METH_VARARGS}, + {"PyTime_AsTimespec_clamp", test_PyTime_AsTimespec_clamp, METH_VARARGS}, +#endif + {"PyTime_AsTimeval", test_PyTime_AsTimeval, METH_VARARGS}, + {"PyTime_AsTimeval_clamp", test_PyTime_AsTimeval_clamp, METH_VARARGS}, + {"PyTime_FromSeconds", test_pytime_fromseconds, METH_VARARGS}, + {"PyTime_FromSecondsObject", test_pytime_fromsecondsobject, METH_VARARGS}, + {"pytime_object_to_time_t", test_pytime_object_to_time_t, METH_VARARGS}, + {"pytime_object_to_timespec", test_pytime_object_to_timespec, METH_VARARGS}, + {"pytime_object_to_timeval", test_pytime_object_to_timeval, METH_VARARGS}, + {NULL}, +}; + +int +_PyTestCapi_Init_PyTime(PyObject *mod) +{ + if (PyModule_AddFunctions(mod, test_methods) < 0) { + return -1; + } + return 0; +} diff --git a/Modules/_testcapi/structmember.c b/Modules/_testcapi/structmember.c new file mode 100644 index 00000000..641b003e --- /dev/null +++ b/Modules/_testcapi/structmember.c @@ -0,0 +1,217 @@ +#define PY_SSIZE_T_CLEAN +#include "parts.h" +#include <stddef.h> // for offsetof() + + +// This defines two classes that contain all the simple member types, one +// using "new" Py_-prefixed API, and the other using "old" <structmember.h>. +// They should behave identically in Python. + +typedef struct { + char bool_member; + char byte_member; + unsigned char ubyte_member; + short short_member; + unsigned short ushort_member; + int int_member; + unsigned int uint_member; + long long_member; + unsigned long ulong_member; + Py_ssize_t pyssizet_member; + float float_member; + double double_member; + char inplace_member[6]; + long long longlong_member; + unsigned long long ulonglong_member; +} all_structmembers; + +typedef struct { + PyObject_HEAD + all_structmembers structmembers; +} test_structmembers; + + +static struct PyMemberDef test_members_newapi[] = { + {"T_BOOL", Py_T_BOOL, offsetof(test_structmembers, structmembers.bool_member), 0, NULL}, + {"T_BYTE", Py_T_BYTE, offsetof(test_structmembers, structmembers.byte_member), 0, NULL}, + {"T_UBYTE", Py_T_UBYTE, offsetof(test_structmembers, structmembers.ubyte_member), 0, NULL}, + {"T_SHORT", Py_T_SHORT, offsetof(test_structmembers, structmembers.short_member), 0, NULL}, + {"T_USHORT", Py_T_USHORT, offsetof(test_structmembers, structmembers.ushort_member), 0, NULL}, + {"T_INT", Py_T_INT, offsetof(test_structmembers, structmembers.int_member), 0, NULL}, + {"T_UINT", Py_T_UINT, offsetof(test_structmembers, structmembers.uint_member), 0, NULL}, + {"T_LONG", Py_T_LONG, offsetof(test_structmembers, structmembers.long_member), 0, NULL}, + {"T_ULONG", Py_T_ULONG, offsetof(test_structmembers, structmembers.ulong_member), 0, NULL}, + {"T_PYSSIZET", Py_T_PYSSIZET, offsetof(test_structmembers, structmembers.pyssizet_member), 0, NULL}, + {"T_FLOAT", Py_T_FLOAT, offsetof(test_structmembers, structmembers.float_member), 0, NULL}, + {"T_DOUBLE", Py_T_DOUBLE, offsetof(test_structmembers, structmembers.double_member), 0, NULL}, + {"T_STRING_INPLACE", Py_T_STRING_INPLACE, offsetof(test_structmembers, structmembers.inplace_member), 0, NULL}, + {"T_LONGLONG", Py_T_LONGLONG, offsetof(test_structmembers, structmembers.longlong_member), 0, NULL}, + {"T_ULONGLONG", Py_T_ULONGLONG, offsetof(test_structmembers, structmembers.ulonglong_member), 0, NULL}, + {NULL} +}; + +static PyObject * +test_structmembers_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + static char *keywords[] = { + "T_BOOL", "T_BYTE", "T_UBYTE", "T_SHORT", "T_USHORT", + "T_INT", "T_UINT", "T_LONG", "T_ULONG", "T_PYSSIZET", + "T_FLOAT", "T_DOUBLE", "T_STRING_INPLACE", + "T_LONGLONG", "T_ULONGLONG", + NULL}; + static const char fmt[] = "|bbBhHiIlknfds#LK"; + test_structmembers *ob; + const char *s = NULL; + Py_ssize_t string_len = 0; + ob = PyObject_New(test_structmembers, type); + if (ob == NULL) { + return NULL; + } + memset(&ob->structmembers, 0, sizeof(all_structmembers)); + if (!PyArg_ParseTupleAndKeywords(args, kwargs, fmt, keywords, + &ob->structmembers.bool_member, + &ob->structmembers.byte_member, + &ob->structmembers.ubyte_member, + &ob->structmembers.short_member, + &ob->structmembers.ushort_member, + &ob->structmembers.int_member, + &ob->structmembers.uint_member, + &ob->structmembers.long_member, + &ob->structmembers.ulong_member, + &ob->structmembers.pyssizet_member, + &ob->structmembers.float_member, + &ob->structmembers.double_member, + &s, &string_len, + &ob->structmembers.longlong_member, + &ob->structmembers.ulonglong_member)) + { + Py_DECREF(ob); + return NULL; + } + if (s != NULL) { + if (string_len > 5) { + Py_DECREF(ob); + PyErr_SetString(PyExc_ValueError, "string too long"); + return NULL; + } + strcpy(ob->structmembers.inplace_member, s); + } + else { + strcpy(ob->structmembers.inplace_member, ""); + } + return (PyObject *)ob; +} + +static PyType_Slot test_structmembers_slots[] = { + {Py_tp_new, test_structmembers_new}, + {Py_tp_members, test_members_newapi}, + {0}, +}; + +static PyType_Spec test_structmembers_spec = { + .name = "_testcapi._test_structmembersType_NewAPI", + .flags = Py_TPFLAGS_DEFAULT, + .basicsize = sizeof(test_structmembers), + .slots = test_structmembers_slots, +}; + +#include <structmember.h> + +static struct PyMemberDef test_members[] = { + {"T_BOOL", T_BOOL, offsetof(test_structmembers, structmembers.bool_member), 0, NULL}, + {"T_BYTE", T_BYTE, offsetof(test_structmembers, structmembers.byte_member), 0, NULL}, + {"T_UBYTE", T_UBYTE, offsetof(test_structmembers, structmembers.ubyte_member), 0, NULL}, + {"T_SHORT", T_SHORT, offsetof(test_structmembers, structmembers.short_member), 0, NULL}, + {"T_USHORT", T_USHORT, offsetof(test_structmembers, structmembers.ushort_member), 0, NULL}, + {"T_INT", T_INT, offsetof(test_structmembers, structmembers.int_member), 0, NULL}, + {"T_UINT", T_UINT, offsetof(test_structmembers, structmembers.uint_member), 0, NULL}, + {"T_LONG", T_LONG, offsetof(test_structmembers, structmembers.long_member), 0, NULL}, + {"T_ULONG", T_ULONG, offsetof(test_structmembers, structmembers.ulong_member), 0, NULL}, + {"T_PYSSIZET", T_PYSSIZET, offsetof(test_structmembers, structmembers.pyssizet_member), 0, NULL}, + {"T_FLOAT", T_FLOAT, offsetof(test_structmembers, structmembers.float_member), 0, NULL}, + {"T_DOUBLE", T_DOUBLE, offsetof(test_structmembers, structmembers.double_member), 0, NULL}, + {"T_STRING_INPLACE", T_STRING_INPLACE, offsetof(test_structmembers, structmembers.inplace_member), 0, NULL}, + {"T_LONGLONG", T_LONGLONG, offsetof(test_structmembers, structmembers.longlong_member), 0, NULL}, + {"T_ULONGLONG", T_ULONGLONG, offsetof(test_structmembers, structmembers.ulonglong_member), 0, NULL}, + {NULL} +}; + + +static void +test_structmembers_free(PyObject *ob) +{ + PyObject_Free(ob); +} + +/* Designated initializers would work too, but this does test the *old* API */ +static PyTypeObject test_structmembersType_OldAPI= { + PyVarObject_HEAD_INIT(NULL, 0) + "test_structmembersType_OldAPI", + sizeof(test_structmembers), /* tp_basicsize */ + 0, /* tp_itemsize */ + test_structmembers_free, /* destructor tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + PyObject_GenericSetAttr, /* tp_setattro */ + 0, /* tp_as_buffer */ + 0, /* tp_flags */ + "Type containing all structmember types", + 0, /* traverseproc tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + test_members, /* tp_members */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + test_structmembers_new, /* tp_new */ +}; + + +int +_PyTestCapi_Init_Structmember(PyObject *m) +{ + int res; + res = PyType_Ready(&test_structmembersType_OldAPI); + if (res < 0) { + return -1; + } + res = PyModule_AddObjectRef( + m, + "_test_structmembersType_OldAPI", + (PyObject *)&test_structmembersType_OldAPI); + if (res < 0) { + return -1; + } + + PyObject *test_structmembersType_NewAPI = PyType_FromModuleAndSpec( + m, &test_structmembers_spec, NULL); + if (!test_structmembersType_NewAPI) { + return -1; + } + res = PyModule_AddType(m, (PyTypeObject*)test_structmembersType_NewAPI); + Py_DECREF(test_structmembersType_NewAPI); + if (res < 0) { + return -1; + } + + return 0; +} diff --git a/Modules/testcapi_long.h b/Modules/_testcapi/testcapi_long.h similarity index 99% rename from Modules/testcapi_long.h rename to Modules/_testcapi/testcapi_long.h index 6bddad7b..14325814 100644 --- a/Modules/testcapi_long.h +++ b/Modules/_testcapi/testcapi_long.h @@ -202,6 +202,5 @@ TESTNAME(PyObject *error(const char*)) Py_DECREF(Py_None); } - Py_INCREF(Py_None); - return Py_None; + return Py_NewRef(Py_None); } diff --git a/Modules/_testcapi/unicode.c b/Modules/_testcapi/unicode.c new file mode 100644 index 00000000..3f2964e4 --- /dev/null +++ b/Modules/_testcapi/unicode.c @@ -0,0 +1,2074 @@ +#include <stddef.h> // ptrdiff_t + +#define PY_SSIZE_T_CLEAN +#include "parts.h" +#include "util.h" + +static struct PyModuleDef *_testcapimodule = NULL; // set at initialization + +static PyObject * +codec_incrementalencoder(PyObject *self, PyObject *args) +{ + const char *encoding, *errors = NULL; + if (!PyArg_ParseTuple(args, "s|s:test_incrementalencoder", + &encoding, &errors)) + return NULL; + return PyCodec_IncrementalEncoder(encoding, errors); +} + +static PyObject * +codec_incrementaldecoder(PyObject *self, PyObject *args) +{ + const char *encoding, *errors = NULL; + if (!PyArg_ParseTuple(args, "s|s:test_incrementaldecoder", + &encoding, &errors)) + return NULL; + return PyCodec_IncrementalDecoder(encoding, errors); +} + +static PyObject * +test_unicode_compare_with_ascii(PyObject *self, PyObject *Py_UNUSED(ignored)) { + PyObject *py_s = PyUnicode_FromStringAndSize("str\0", 4); + int result; + if (py_s == NULL) + return NULL; + result = PyUnicode_CompareWithASCIIString(py_s, "str"); + Py_DECREF(py_s); + if (!result) { + PyErr_SetString(PyExc_AssertionError, "Python string ending in NULL " + "should not compare equal to c string."); + return NULL; + } + Py_RETURN_NONE; +} + +static PyObject * +test_widechar(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ +#if defined(SIZEOF_WCHAR_T) && (SIZEOF_WCHAR_T == 4) + const wchar_t wtext[2] = {(wchar_t)0x10ABCDu}; + size_t wtextlen = 1; + const wchar_t invalid[1] = {(wchar_t)0x110000u}; +#else + const wchar_t wtext[3] = {(wchar_t)0xDBEAu, (wchar_t)0xDFCDu}; + size_t wtextlen = 2; +#endif + PyObject *wide, *utf8; + + wide = PyUnicode_FromWideChar(wtext, wtextlen); + if (wide == NULL) + return NULL; + + utf8 = PyUnicode_FromString("\xf4\x8a\xaf\x8d"); + if (utf8 == NULL) { + Py_DECREF(wide); + return NULL; + } + + if (PyUnicode_GET_LENGTH(wide) != PyUnicode_GET_LENGTH(utf8)) { + Py_DECREF(wide); + Py_DECREF(utf8); + PyErr_SetString(PyExc_AssertionError, + "test_widechar: " + "wide string and utf8 string " + "have different length"); + return NULL; + } + if (PyUnicode_Compare(wide, utf8)) { + Py_DECREF(wide); + Py_DECREF(utf8); + if (PyErr_Occurred()) + return NULL; + PyErr_SetString(PyExc_AssertionError, + "test_widechar: " + "wide string and utf8 string " + "are different"); + return NULL; + } + + Py_DECREF(wide); + Py_DECREF(utf8); + +#if defined(SIZEOF_WCHAR_T) && (SIZEOF_WCHAR_T == 4) + wide = PyUnicode_FromWideChar(invalid, 1); + if (wide == NULL) + PyErr_Clear(); + else { + PyErr_SetString(PyExc_AssertionError, + "test_widechar: " + "PyUnicode_FromWideChar(L\"\\U00110000\", 1) didn't fail"); + return NULL; + } +#endif + Py_RETURN_NONE; +} + + +static PyObject * +unicode_copy(PyObject *unicode) +{ + PyObject *copy; + + if (!unicode) { + return NULL; + } + if (!PyUnicode_Check(unicode)) { + Py_INCREF(unicode); + return unicode; + } + + copy = PyUnicode_New(PyUnicode_GET_LENGTH(unicode), + PyUnicode_MAX_CHAR_VALUE(unicode)); + if (!copy) { + return NULL; + } + if (PyUnicode_CopyCharacters(copy, 0, unicode, + 0, PyUnicode_GET_LENGTH(unicode)) < 0) + { + Py_DECREF(copy); + return NULL; + } + return copy; +} + +/* Test PyUnicode_New() */ +static PyObject * +unicode_new(PyObject *self, PyObject *args) +{ + Py_ssize_t size; + unsigned int maxchar; + PyObject *result; + + if (!PyArg_ParseTuple(args, "nI", &size, &maxchar)) { + return NULL; + } + + result = PyUnicode_New(size, (Py_UCS4)maxchar); + if (!result) { + return NULL; + } + if (size > 0 && maxchar <= 0x10ffff && + PyUnicode_Fill(result, 0, size, (Py_UCS4)maxchar) < 0) + { + Py_DECREF(result); + return NULL; + } + return result; +} + +/* Test PyUnicode_Fill() */ +static PyObject * +unicode_fill(PyObject *self, PyObject *args) +{ + PyObject *to, *to_copy; + Py_ssize_t start, length, filled; + unsigned int fill_char; + + if (!PyArg_ParseTuple(args, "OnnI", &to, &start, &length, &fill_char)) { + return NULL; + } + + NULLABLE(to); + if (!(to_copy = unicode_copy(to)) && to) { + return NULL; + } + + filled = PyUnicode_Fill(to_copy, start, length, (Py_UCS4)fill_char); + if (filled == -1 && PyErr_Occurred()) { + Py_DECREF(to_copy); + return NULL; + } + return Py_BuildValue("(Nn)", to_copy, filled); +} + +/* Test PyUnicode_WriteChar() */ +static PyObject * +unicode_writechar(PyObject *self, PyObject *args) +{ + PyObject *to, *to_copy; + Py_ssize_t index; + unsigned int character; + int result; + + if (!PyArg_ParseTuple(args, "OnI", &to, &index, &character)) { + return NULL; + } + + NULLABLE(to); + if (!(to_copy = unicode_copy(to)) && to) { + return NULL; + } + + result = PyUnicode_WriteChar(to_copy, index, (Py_UCS4)character); + if (result == -1 && PyErr_Occurred()) { + Py_DECREF(to_copy); + return NULL; + } + return Py_BuildValue("(Ni)", to_copy, result); +} + +/* Test PyUnicode_Resize() */ +static PyObject * +unicode_resize(PyObject *self, PyObject *args) +{ + PyObject *obj, *copy; + Py_ssize_t length; + int result; + + if (!PyArg_ParseTuple(args, "On", &obj, &length)) { + return NULL; + } + + NULLABLE(obj); + if (!(copy = unicode_copy(obj)) && obj) { + return NULL; + } + result = PyUnicode_Resize(©, length); + if (result == -1 && PyErr_Occurred()) { + Py_XDECREF(copy); + return NULL; + } + if (obj && PyUnicode_Check(obj) && length > PyUnicode_GET_LENGTH(obj)) { + if (PyUnicode_Fill(copy, PyUnicode_GET_LENGTH(obj), length, 0U) < 0) { + Py_DECREF(copy); + return NULL; + } + } + return Py_BuildValue("(Ni)", copy, result); +} + +/* Test PyUnicode_Append() */ +static PyObject * +unicode_append(PyObject *self, PyObject *args) +{ + PyObject *left, *right, *left_copy; + + if (!PyArg_ParseTuple(args, "OO", &left, &right)) + return NULL; + + NULLABLE(left); + NULLABLE(right); + if (!(left_copy = unicode_copy(left)) && left) { + return NULL; + } + PyUnicode_Append(&left_copy, right); + return left_copy; +} + +/* Test PyUnicode_AppendAndDel() */ +static PyObject * +unicode_appendanddel(PyObject *self, PyObject *args) +{ + PyObject *left, *right, *left_copy; + + if (!PyArg_ParseTuple(args, "OO", &left, &right)) + return NULL; + + NULLABLE(left); + NULLABLE(right); + if (!(left_copy = unicode_copy(left)) && left) { + return NULL; + } + Py_XINCREF(right); + PyUnicode_AppendAndDel(&left_copy, right); + return left_copy; +} + +/* Test PyUnicode_FromStringAndSize() */ +static PyObject * +unicode_fromstringandsize(PyObject *self, PyObject *args) +{ + const char *s; + Py_ssize_t bsize; + Py_ssize_t size = -100; + + if (!PyArg_ParseTuple(args, "z#|n", &s, &bsize, &size)) { + return NULL; + } + + if (size == -100) { + size = bsize; + } + return PyUnicode_FromStringAndSize(s, size); +} + +/* Test PyUnicode_FromString() */ +static PyObject * +unicode_fromstring(PyObject *self, PyObject *arg) +{ + const char *s; + Py_ssize_t size; + + if (!PyArg_Parse(arg, "z#", &s, &size)) { + return NULL; + } + return PyUnicode_FromString(s); +} + +/* Test PyUnicode_FromKindAndData() */ +static PyObject * +unicode_fromkindanddata(PyObject *self, PyObject *args) +{ + int kind; + void *buffer; + Py_ssize_t bsize; + Py_ssize_t size = -100; + + if (!PyArg_ParseTuple(args, "iz#|n", &kind, &buffer, &bsize, &size)) { + return NULL; + } + + if (size == -100) { + size = bsize; + } + if (kind && size % kind) { + PyErr_SetString(PyExc_AssertionError, + "invalid size in unicode_fromkindanddata()"); + return NULL; + } + return PyUnicode_FromKindAndData(kind, buffer, kind ? size / kind : 0); +} + +/* Test PyUnicode_Substring() */ +static PyObject * +unicode_substring(PyObject *self, PyObject *args) +{ + PyObject *str; + Py_ssize_t start, end; + + if (!PyArg_ParseTuple(args, "Onn", &str, &start, &end)) { + return NULL; + } + + NULLABLE(str); + return PyUnicode_Substring(str, start, end); +} + +/* Test PyUnicode_GetLength() */ +static PyObject * +unicode_getlength(PyObject *self, PyObject *arg) +{ + NULLABLE(arg); + RETURN_SIZE(PyUnicode_GetLength(arg)); +} + +/* Test PyUnicode_ReadChar() */ +static PyObject * +unicode_readchar(PyObject *self, PyObject *args) +{ + PyObject *unicode; + Py_ssize_t index; + Py_UCS4 result; + + if (!PyArg_ParseTuple(args, "On", &unicode, &index)) { + return NULL; + } + + NULLABLE(unicode); + result = PyUnicode_ReadChar(unicode, index); + if (result == (Py_UCS4)-1) + return NULL; + return PyLong_FromUnsignedLong(result); +} + +/* Test PyUnicode_FromEncodedObject() */ +static PyObject * +unicode_fromencodedobject(PyObject *self, PyObject *args) +{ + PyObject *obj; + const char *encoding; + const char *errors = NULL; + + if (!PyArg_ParseTuple(args, "Oz|z", &obj, &encoding, &errors)) { + return NULL; + } + + NULLABLE(obj); + return PyUnicode_FromEncodedObject(obj, encoding, errors); +} + +/* Test PyUnicode_FromObject() */ +static PyObject * +unicode_fromobject(PyObject *self, PyObject *arg) +{ + NULLABLE(arg); + return PyUnicode_FromObject(arg); +} + +/* Test PyUnicode_InternInPlace() */ +static PyObject * +unicode_interninplace(PyObject *self, PyObject *arg) +{ + NULLABLE(arg); + Py_XINCREF(arg); + PyUnicode_InternInPlace(&arg); + return arg; +} + +/* Test PyUnicode_InternFromString() */ +static PyObject * +unicode_internfromstring(PyObject *self, PyObject *arg) +{ + const char *s; + Py_ssize_t size; + + if (!PyArg_Parse(arg, "z#", &s, &size)) { + return NULL; + } + return PyUnicode_InternFromString(s); +} + +/* Test PyUnicode_FromWideChar() */ +static PyObject * +unicode_fromwidechar(PyObject *self, PyObject *args) +{ + const char *s; + Py_ssize_t bsize; + Py_ssize_t size = -100; + + if (!PyArg_ParseTuple(args, "z#|n", &s, &bsize, &size)) { + return NULL; + } + if (size == -100) { + if (bsize % SIZEOF_WCHAR_T) { + PyErr_SetString(PyExc_AssertionError, + "invalid size in unicode_fromwidechar()"); + return NULL; + } + size = bsize / SIZEOF_WCHAR_T; + } + return PyUnicode_FromWideChar((const wchar_t *)s, size); +} + +/* Test PyUnicode_AsWideChar() */ +static PyObject * +unicode_aswidechar(PyObject *self, PyObject *args) +{ + PyObject *unicode, *result; + Py_ssize_t buflen, size; + wchar_t *buffer; + + if (!PyArg_ParseTuple(args, "On", &unicode, &buflen)) + return NULL; + NULLABLE(unicode); + buffer = PyMem_New(wchar_t, buflen); + if (buffer == NULL) + return PyErr_NoMemory(); + + size = PyUnicode_AsWideChar(unicode, buffer, buflen); + if (size == -1) { + PyMem_Free(buffer); + return NULL; + } + + if (size < buflen) + buflen = size + 1; + else + buflen = size; + result = PyUnicode_FromWideChar(buffer, buflen); + PyMem_Free(buffer); + if (result == NULL) + return NULL; + + return Py_BuildValue("(Nn)", result, size); +} + +/* Test PyUnicode_AsWideCharString() with NULL as buffer */ +static PyObject * +unicode_aswidechar_null(PyObject *self, PyObject *args) +{ + PyObject *unicode; + Py_ssize_t buflen; + + if (!PyArg_ParseTuple(args, "On", &unicode, &buflen)) + return NULL; + NULLABLE(unicode); + RETURN_SIZE(PyUnicode_AsWideChar(unicode, NULL, buflen)); +} + +/* Test PyUnicode_AsWideCharString() */ +static PyObject * +unicode_aswidecharstring(PyObject *self, PyObject *args) +{ + PyObject *unicode, *result; + Py_ssize_t size = UNINITIALIZED_SIZE; + wchar_t *buffer; + + if (!PyArg_ParseTuple(args, "O", &unicode)) + return NULL; + + NULLABLE(unicode); + buffer = PyUnicode_AsWideCharString(unicode, &size); + if (buffer == NULL) { + assert(size == UNINITIALIZED_SIZE); + return NULL; + } + + result = PyUnicode_FromWideChar(buffer, size + 1); + PyMem_Free(buffer); + if (result == NULL) + return NULL; + return Py_BuildValue("(Nn)", result, size); +} + +/* Test PyUnicode_AsWideCharString() with NULL as the size address */ +static PyObject * +unicode_aswidecharstring_null(PyObject *self, PyObject *args) +{ + PyObject *unicode, *result; + wchar_t *buffer; + + if (!PyArg_ParseTuple(args, "O", &unicode)) + return NULL; + + NULLABLE(unicode); + buffer = PyUnicode_AsWideCharString(unicode, NULL); + if (buffer == NULL) + return NULL; + + result = PyUnicode_FromWideChar(buffer, -1); + PyMem_Free(buffer); + if (result == NULL) + return NULL; + return result; +} + +/* Test PyUnicode_AsUCS4() */ +static PyObject * +unicode_asucs4(PyObject *self, PyObject *args) +{ + PyObject *unicode, *result; + Py_UCS4 *buffer; + int copy_null; + Py_ssize_t str_len, buf_len; + + if (!PyArg_ParseTuple(args, "Onp:unicode_asucs4", &unicode, &str_len, ©_null)) { + return NULL; + } + + NULLABLE(unicode); + buf_len = str_len + 1; + buffer = PyMem_NEW(Py_UCS4, buf_len); + if (buffer == NULL) { + return PyErr_NoMemory(); + } + memset(buffer, 0, sizeof(Py_UCS4)*buf_len); + buffer[str_len] = 0xffffU; + + if (!PyUnicode_AsUCS4(unicode, buffer, buf_len, copy_null)) { + PyMem_Free(buffer); + return NULL; + } + + result = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, buffer, buf_len); + PyMem_Free(buffer); + return result; +} + +/* Test PyUnicode_AsUCS4Copy() */ +static PyObject * +unicode_asucs4copy(PyObject *self, PyObject *args) +{ + PyObject *unicode; + Py_UCS4 *buffer; + PyObject *result; + + if (!PyArg_ParseTuple(args, "O", &unicode)) { + return NULL; + } + + NULLABLE(unicode); + buffer = PyUnicode_AsUCS4Copy(unicode); + if (buffer == NULL) { + return NULL; + } + result = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, + buffer, + PyUnicode_GET_LENGTH(unicode) + 1); + PyMem_FREE(buffer); + return result; +} + +/* Test PyUnicode_FromOrdinal() */ +static PyObject * +unicode_fromordinal(PyObject *self, PyObject *args) +{ + int ordinal; + + if (!PyArg_ParseTuple(args, "i", &ordinal)) + return NULL; + + return PyUnicode_FromOrdinal(ordinal); +} + +/* Test PyUnicode_AsUTF8() */ +static PyObject * +unicode_asutf8(PyObject *self, PyObject *args) +{ + PyObject *unicode; + Py_ssize_t buflen; + const char *s; + + if (!PyArg_ParseTuple(args, "On", &unicode, &buflen)) + return NULL; + + NULLABLE(unicode); + s = PyUnicode_AsUTF8(unicode); + if (s == NULL) + return NULL; + + return PyBytes_FromStringAndSize(s, buflen); +} + +/* Test PyUnicode_AsUTF8AndSize() */ +static PyObject * +unicode_asutf8andsize(PyObject *self, PyObject *args) +{ + PyObject *unicode; + Py_ssize_t buflen; + const char *s; + Py_ssize_t size = UNINITIALIZED_SIZE; + + if (!PyArg_ParseTuple(args, "On", &unicode, &buflen)) + return NULL; + + NULLABLE(unicode); + s = PyUnicode_AsUTF8AndSize(unicode, &size); + if (s == NULL) { + assert(size == UNINITIALIZED_SIZE); + return NULL; + } + + return Py_BuildValue("(y#n)", s, buflen, size); +} + +/* Test PyUnicode_AsUTF8AndSize() with NULL as the size address */ +static PyObject * +unicode_asutf8andsize_null(PyObject *self, PyObject *args) +{ + PyObject *unicode; + Py_ssize_t buflen; + const char *s; + + if (!PyArg_ParseTuple(args, "On", &unicode, &buflen)) + return NULL; + + NULLABLE(unicode); + s = PyUnicode_AsUTF8AndSize(unicode, NULL); + if (s == NULL) + return NULL; + + return PyBytes_FromStringAndSize(s, buflen); +} + +/* Test PyUnicode_GetDefaultEncoding() */ +static PyObject * +unicode_getdefaultencoding(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + const char *s = PyUnicode_GetDefaultEncoding(); + if (s == NULL) + return NULL; + + return PyBytes_FromString(s); +} + +/* Test _PyUnicode_TransformDecimalAndSpaceToASCII() */ +static PyObject * +unicode_transformdecimalandspacetoascii(PyObject *self, PyObject *arg) +{ + NULLABLE(arg); + return _PyUnicode_TransformDecimalAndSpaceToASCII(arg); +} + +/* Test PyUnicode_Decode() */ +static PyObject * +unicode_decode(PyObject *self, PyObject *args) +{ + const char *s; + Py_ssize_t size; + const char *encoding; + const char *errors = NULL; + + if (!PyArg_ParseTuple(args, "y#z|z", &s, &size, &encoding, &errors)) + return NULL; + + return PyUnicode_Decode(s, size, encoding, errors); +} + +/* Test PyUnicode_AsEncodedString() */ +static PyObject * +unicode_asencodedstring(PyObject *self, PyObject *args) +{ + PyObject *unicode; + const char *encoding; + const char *errors = NULL; + + if (!PyArg_ParseTuple(args, "Oz|z", &unicode, &encoding, &errors)) + return NULL; + + NULLABLE(unicode); + return PyUnicode_AsEncodedString(unicode, encoding, errors); +} + +/* Test PyUnicode_BuildEncodingMap() */ +static PyObject * +unicode_buildencodingmap(PyObject *self, PyObject *arg) +{ + NULLABLE(arg); + return PyUnicode_BuildEncodingMap(arg); +} + +/* Test PyUnicode_DecodeUTF7() */ +static PyObject * +unicode_decodeutf7(PyObject *self, PyObject *args) +{ + const char *data; + Py_ssize_t size; + const char *errors = NULL; + + if (!PyArg_ParseTuple(args, "y#|z", &data, &size, &errors)) + return NULL; + + return PyUnicode_DecodeUTF7(data, size, errors); +} + +/* Test PyUnicode_DecodeUTF7Stateful() */ +static PyObject * +unicode_decodeutf7stateful(PyObject *self, PyObject *args) +{ + const char *data; + Py_ssize_t size; + const char *errors = NULL; + Py_ssize_t consumed = UNINITIALIZED_SIZE; + PyObject *result; + + if (!PyArg_ParseTuple(args, "y#|z", &data, &size, &errors)) + return NULL; + + result = PyUnicode_DecodeUTF7Stateful(data, size, errors, &consumed); + if (!result) { + assert(consumed == UNINITIALIZED_SIZE); + return NULL; + } + return Py_BuildValue("(Nn)", result, consumed); +} + +/* Test PyUnicode_DecodeUTF8() */ +static PyObject * +unicode_decodeutf8(PyObject *self, PyObject *args) +{ + const char *data; + Py_ssize_t size; + const char *errors = NULL; + + if (!PyArg_ParseTuple(args, "y#|z", &data, &size, &errors)) + return NULL; + + return PyUnicode_DecodeUTF8(data, size, errors); +} + +/* Test PyUnicode_DecodeUTF8Stateful() */ +static PyObject * +unicode_decodeutf8stateful(PyObject *self, PyObject *args) +{ + const char *data; + Py_ssize_t size; + const char *errors = NULL; + Py_ssize_t consumed = UNINITIALIZED_SIZE; + PyObject *result; + + if (!PyArg_ParseTuple(args, "y#|z", &data, &size, &errors)) + return NULL; + + result = PyUnicode_DecodeUTF8Stateful(data, size, errors, &consumed); + if (!result) { + assert(consumed == UNINITIALIZED_SIZE); + return NULL; + } + return Py_BuildValue("(Nn)", result, consumed); +} + +/* Test PyUnicode_AsUTF8String() */ +static PyObject * +unicode_asutf8string(PyObject *self, PyObject *arg) +{ + NULLABLE(arg); + return PyUnicode_AsUTF8String(arg); +} + +/* Test PyUnicode_DecodeUTF32() */ +static PyObject * +unicode_decodeutf32(PyObject *self, PyObject *args) +{ + const char *data; + Py_ssize_t size; + const char *errors = NULL; + int byteorder = UNINITIALIZED_INT; + PyObject *result; + + if (!PyArg_ParseTuple(args, "iy#|z", &byteorder, &data, &size, &errors)) + return NULL; + + result = PyUnicode_DecodeUTF32(data, size, errors, &byteorder); + if (!result) { + return NULL; + } + return Py_BuildValue("(iN)", byteorder, result); +} + +/* Test PyUnicode_DecodeUTF32Stateful() */ +static PyObject * +unicode_decodeutf32stateful(PyObject *self, PyObject *args) +{ + const char *data; + Py_ssize_t size; + const char *errors = NULL; + int byteorder = UNINITIALIZED_INT; + Py_ssize_t consumed = UNINITIALIZED_SIZE; + PyObject *result; + + if (!PyArg_ParseTuple(args, "iy#|z", &byteorder, &data, &size, &errors)) + return NULL; + + result = PyUnicode_DecodeUTF32Stateful(data, size, errors, &byteorder, &consumed); + if (!result) { + assert(consumed == UNINITIALIZED_SIZE); + return NULL; + } + return Py_BuildValue("(iNn)", byteorder, result, consumed); +} + +/* Test PyUnicode_AsUTF32String() */ +static PyObject * +unicode_asutf32string(PyObject *self, PyObject *arg) +{ + NULLABLE(arg); + return PyUnicode_AsUTF32String(arg); +} + +/* Test PyUnicode_DecodeUTF16() */ +static PyObject * +unicode_decodeutf16(PyObject *self, PyObject *args) +{ + const char *data; + Py_ssize_t size; + const char *errors = NULL; + int byteorder = UNINITIALIZED_INT; + PyObject *result; + + if (!PyArg_ParseTuple(args, "iy#|z", &byteorder, &data, &size, &errors)) + return NULL; + + result = PyUnicode_DecodeUTF16(data, size, errors, &byteorder); + if (!result) { + return NULL; + } + return Py_BuildValue("(iN)", byteorder, result); +} + +/* Test PyUnicode_DecodeUTF16Stateful() */ +static PyObject * +unicode_decodeutf16stateful(PyObject *self, PyObject *args) +{ + const char *data; + Py_ssize_t size; + const char *errors = NULL; + int byteorder = UNINITIALIZED_INT; + Py_ssize_t consumed = UNINITIALIZED_SIZE; + PyObject *result; + + if (!PyArg_ParseTuple(args, "iy#|z", &byteorder, &data, &size, &errors)) + return NULL; + + result = PyUnicode_DecodeUTF16Stateful(data, size, errors, &byteorder, &consumed); + if (!result) { + assert(consumed == UNINITIALIZED_SIZE); + return NULL; + } + return Py_BuildValue("(iNn)", byteorder, result, consumed); +} + +/* Test PyUnicode_AsUTF16String() */ +static PyObject * +unicode_asutf16string(PyObject *self, PyObject *arg) +{ + NULLABLE(arg); + return PyUnicode_AsUTF16String(arg); +} + +/* Test PyUnicode_DecodeUnicodeEscape() */ +static PyObject * +unicode_decodeunicodeescape(PyObject *self, PyObject *args) +{ + const char *data; + Py_ssize_t size; + const char *errors = NULL; + + if (!PyArg_ParseTuple(args, "y#|z", &data, &size, &errors)) + return NULL; + + return PyUnicode_DecodeUnicodeEscape(data, size, errors); +} + +/* Test PyUnicode_AsUnicodeEscapeString() */ +static PyObject * +unicode_asunicodeescapestring(PyObject *self, PyObject *arg) +{ + NULLABLE(arg); + return PyUnicode_AsUnicodeEscapeString(arg); +} + +static PyObject * +unicode_decoderawunicodeescape(PyObject *self, PyObject *args) +{ + const char *data; + Py_ssize_t size; + const char *errors = NULL; + + if (!PyArg_ParseTuple(args, "y#|z", &data, &size, &errors)) + return NULL; + + return PyUnicode_DecodeRawUnicodeEscape(data, size, errors); +} + +/* Test PyUnicode_AsRawUnicodeEscapeString() */ +static PyObject * +unicode_asrawunicodeescapestring(PyObject *self, PyObject *arg) +{ + NULLABLE(arg); + return PyUnicode_AsRawUnicodeEscapeString(arg); +} + +static PyObject * +unicode_decodelatin1(PyObject *self, PyObject *args) +{ + const char *data; + Py_ssize_t size; + const char *errors = NULL; + + if (!PyArg_ParseTuple(args, "y#|z", &data, &size, &errors)) + return NULL; + + return PyUnicode_DecodeLatin1(data, size, errors); +} + +/* Test PyUnicode_AsLatin1String() */ +static PyObject * +unicode_aslatin1string(PyObject *self, PyObject *arg) +{ + NULLABLE(arg); + return PyUnicode_AsLatin1String(arg); +} + +/* Test PyUnicode_DecodeASCII() */ +static PyObject * +unicode_decodeascii(PyObject *self, PyObject *args) +{ + const char *data; + Py_ssize_t size; + const char *errors = NULL; + + if (!PyArg_ParseTuple(args, "y#|z", &data, &size, &errors)) + return NULL; + + return PyUnicode_DecodeASCII(data, size, errors); +} + +/* Test PyUnicode_AsASCIIString() */ +static PyObject * +unicode_asasciistring(PyObject *self, PyObject *arg) +{ + NULLABLE(arg); + return PyUnicode_AsASCIIString(arg); +} + +/* Test PyUnicode_DecodeCharmap() */ +static PyObject * +unicode_decodecharmap(PyObject *self, PyObject *args) +{ + const char *data; + Py_ssize_t size; + PyObject *mapping; + const char *errors = NULL; + + if (!PyArg_ParseTuple(args, "y#O|z", &data, &size, &mapping, &errors)) + return NULL; + + NULLABLE(mapping); + return PyUnicode_DecodeCharmap(data, size, mapping, errors); +} + +/* Test PyUnicode_AsCharmapString() */ +static PyObject * +unicode_ascharmapstring(PyObject *self, PyObject *args) +{ + PyObject *unicode; + PyObject *mapping; + + if (!PyArg_ParseTuple(args, "OO", &unicode, &mapping)) + return NULL; + + NULLABLE(unicode); + NULLABLE(mapping); + return PyUnicode_AsCharmapString(unicode, mapping); +} + +#ifdef MS_WINDOWS + +/* Test PyUnicode_DecodeMBCS() */ +static PyObject * +unicode_decodembcs(PyObject *self, PyObject *args) +{ + const char *data; + Py_ssize_t size; + const char *errors = NULL; + + if (!PyArg_ParseTuple(args, "y#|z", &data, &size, &errors)) + return NULL; + + return PyUnicode_DecodeMBCS(data, size, errors); +} + +/* Test PyUnicode_DecodeMBCSStateful() */ +static PyObject * +unicode_decodembcsstateful(PyObject *self, PyObject *args) +{ + const char *data; + Py_ssize_t size; + const char *errors = NULL; + Py_ssize_t consumed = UNINITIALIZED_SIZE; + PyObject *result; + + if (!PyArg_ParseTuple(args, "y#|z", &data, &size, &errors)) + return NULL; + + result = PyUnicode_DecodeMBCSStateful(data, size, errors, &consumed); + if (!result) { + assert(consumed == UNINITIALIZED_SIZE); + return NULL; + } + return Py_BuildValue("(Nn)", result, consumed); +} + +/* Test PyUnicode_DecodeCodePageStateful() */ +static PyObject * +unicode_decodecodepagestateful(PyObject *self, PyObject *args) +{ + int code_page; + const char *data; + Py_ssize_t size; + const char *errors = NULL; + Py_ssize_t consumed = UNINITIALIZED_SIZE; + PyObject *result; + + if (!PyArg_ParseTuple(args, "iy#|z", &code_page, &data, &size, &errors)) + return NULL; + + result = PyUnicode_DecodeCodePageStateful(code_page, data, size, errors, &consumed); + if (!result) { + assert(consumed == UNINITIALIZED_SIZE); + return NULL; + } + return Py_BuildValue("(Nn)", result, consumed); +} + +/* Test PyUnicode_AsMBCSString() */ +static PyObject * +unicode_asmbcsstring(PyObject *self, PyObject *arg) +{ + NULLABLE(arg); + return PyUnicode_AsMBCSString(arg); +} + +/* Test PyUnicode_EncodeCodePage() */ +static PyObject * +unicode_encodecodepage(PyObject *self, PyObject *args) +{ + int code_page; + PyObject *unicode; + const char *errors; + + if (!PyArg_ParseTuple(args, "iO|z", &code_page, &unicode, &errors)) + return NULL; + + NULLABLE(unicode); + return PyUnicode_EncodeCodePage(code_page, unicode, errors); +} + +#endif /* MS_WINDOWS */ + +/* Test PyUnicode_DecodeLocaleAndSize() */ +static PyObject * +unicode_decodelocaleandsize(PyObject *self, PyObject *args) +{ + const char *data; + Py_ssize_t size; + const char *errors; + + if (!PyArg_ParseTuple(args, "y#|z", &data, &size, &errors)) + return NULL; + + return PyUnicode_DecodeLocaleAndSize(data, size, errors); +} + +/* Test PyUnicode_DecodeLocale() */ +static PyObject * +unicode_decodelocale(PyObject *self, PyObject *args) +{ + const char *data; + Py_ssize_t size; + const char *errors; + + if (!PyArg_ParseTuple(args, "y#|z", &data, &size, &errors)) + return NULL; + + return PyUnicode_DecodeLocale(data, errors); +} + +/* Test PyUnicode_EncodeLocale() */ +static PyObject * +unicode_encodelocale(PyObject *self, PyObject *args) +{ + PyObject *unicode; + const char *errors; + + if (!PyArg_ParseTuple(args, "O|z", &unicode, &errors)) + return NULL; + + NULLABLE(unicode); + return PyUnicode_EncodeLocale(unicode, errors); +} + +/* Test PyUnicode_DecodeFSDefault() */ +static PyObject * +unicode_decodefsdefault(PyObject *self, PyObject *args) +{ + const char *data; + Py_ssize_t size; + + if (!PyArg_ParseTuple(args, "y#", &data, &size)) + return NULL; + + return PyUnicode_DecodeFSDefault(data); +} + +/* Test PyUnicode_DecodeFSDefaultAndSize() */ +static PyObject * +unicode_decodefsdefaultandsize(PyObject *self, PyObject *args) +{ + const char *data; + Py_ssize_t size; + + if (!PyArg_ParseTuple(args, "y#|n", &data, &size, &size)) + return NULL; + + return PyUnicode_DecodeFSDefaultAndSize(data, size); +} + +/* Test PyUnicode_EncodeFSDefault() */ +static PyObject * +unicode_encodefsdefault(PyObject *self, PyObject *arg) +{ + NULLABLE(arg); + return PyUnicode_EncodeFSDefault(arg); +} + +/* Test PyUnicode_Concat() */ +static PyObject * +unicode_concat(PyObject *self, PyObject *args) +{ + PyObject *left; + PyObject *right; + + if (!PyArg_ParseTuple(args, "OO", &left, &right)) + return NULL; + + NULLABLE(left); + NULLABLE(right); + return PyUnicode_Concat(left, right); +} + +/* Test PyUnicode_Split() */ +static PyObject * +unicode_split(PyObject *self, PyObject *args) +{ + PyObject *s; + PyObject *sep; + Py_ssize_t maxsplit = -1; + + if (!PyArg_ParseTuple(args, "OO|n", &s, &sep, &maxsplit)) + return NULL; + + NULLABLE(s); + NULLABLE(sep); + return PyUnicode_Split(s, sep, maxsplit); +} + +/* Test PyUnicode_RSplit() */ +static PyObject * +unicode_rsplit(PyObject *self, PyObject *args) +{ + PyObject *s; + PyObject *sep; + Py_ssize_t maxsplit = -1; + + if (!PyArg_ParseTuple(args, "OO|n", &s, &sep, &maxsplit)) + return NULL; + + NULLABLE(s); + NULLABLE(sep); + return PyUnicode_RSplit(s, sep, maxsplit); +} + +/* Test PyUnicode_Splitlines() */ +static PyObject * +unicode_splitlines(PyObject *self, PyObject *args) +{ + PyObject *s; + int keepends = 0; + + if (!PyArg_ParseTuple(args, "O|i", &s, &keepends)) + return NULL; + + NULLABLE(s); + return PyUnicode_Splitlines(s, keepends); +} + +/* Test PyUnicode_Partition() */ +static PyObject * +unicode_partition(PyObject *self, PyObject *args) +{ + PyObject *s; + PyObject *sep; + + if (!PyArg_ParseTuple(args, "OO", &s, &sep)) + return NULL; + + NULLABLE(s); + NULLABLE(sep); + return PyUnicode_Partition(s, sep); +} + +/* Test PyUnicode_RPartition() */ +static PyObject * +unicode_rpartition(PyObject *self, PyObject *args) +{ + PyObject *s; + PyObject *sep; + + if (!PyArg_ParseTuple(args, "OO", &s, &sep)) + return NULL; + + NULLABLE(s); + NULLABLE(sep); + return PyUnicode_RPartition(s, sep); +} + +/* Test PyUnicode_Translate() */ +static PyObject * +unicode_translate(PyObject *self, PyObject *args) +{ + PyObject *obj; + PyObject *table; + const char *errors = NULL; + + if (!PyArg_ParseTuple(args, "OO|z", &obj, &table, &errors)) + return NULL; + + NULLABLE(obj); + NULLABLE(table); + return PyUnicode_Translate(obj, table, errors); +} + +/* Test PyUnicode_Join() */ +static PyObject * +unicode_join(PyObject *self, PyObject *args) +{ + PyObject *sep; + PyObject *seq; + + if (!PyArg_ParseTuple(args, "OO", &sep, &seq)) + return NULL; + + NULLABLE(sep); + NULLABLE(seq); + return PyUnicode_Join(sep, seq); +} + +/* Test PyUnicode_Count() */ +static PyObject * +unicode_count(PyObject *self, PyObject *args) +{ + PyObject *str; + PyObject *substr; + Py_ssize_t start; + Py_ssize_t end; + + if (!PyArg_ParseTuple(args, "OOnn", &str, &substr, &start, &end)) + return NULL; + + NULLABLE(str); + NULLABLE(substr); + RETURN_SIZE(PyUnicode_Count(str, substr, start, end)); +} + +/* Test PyUnicode_Find() */ +static PyObject * +unicode_find(PyObject *self, PyObject *args) +{ + PyObject *str; + PyObject *substr; + Py_ssize_t start; + Py_ssize_t end; + int direction; + Py_ssize_t result; + + if (!PyArg_ParseTuple(args, "OOnni", &str, &substr, &start, &end, &direction)) + return NULL; + + NULLABLE(str); + NULLABLE(substr); + result = PyUnicode_Find(str, substr, start, end, direction); + if (result == -2) { + assert(PyErr_Occurred()); + return NULL; + } + assert(!PyErr_Occurred()); + return PyLong_FromSsize_t(result); +} + +/* Test PyUnicode_Tailmatch() */ +static PyObject * +unicode_tailmatch(PyObject *self, PyObject *args) +{ + PyObject *str; + PyObject *substr; + Py_ssize_t start; + Py_ssize_t end; + int direction; + + if (!PyArg_ParseTuple(args, "OOnni", &str, &substr, &start, &end, &direction)) + return NULL; + + NULLABLE(str); + NULLABLE(substr); + RETURN_SIZE(PyUnicode_Tailmatch(str, substr, start, end, direction)); +} + +/* Test PyUnicode_FindChar() */ +static PyObject * +unicode_findchar(PyObject *self, PyObject *args) +{ + PyObject *str; + int direction; + unsigned int ch; + Py_ssize_t result; + Py_ssize_t start, end; + + if (!PyArg_ParseTuple(args, "OInni:unicode_findchar", &str, &ch, + &start, &end, &direction)) { + return NULL; + } + NULLABLE(str); + result = PyUnicode_FindChar(str, (Py_UCS4)ch, start, end, direction); + if (result == -2) { + assert(PyErr_Occurred()); + return NULL; + } + assert(!PyErr_Occurred()); + return PyLong_FromSsize_t(result); +} + +/* Test PyUnicode_Replace() */ +static PyObject * +unicode_replace(PyObject *self, PyObject *args) +{ + PyObject *str; + PyObject *substr; + PyObject *replstr; + Py_ssize_t maxcount = -1; + + if (!PyArg_ParseTuple(args, "OOO|n", &str, &substr, &replstr, &maxcount)) + return NULL; + + NULLABLE(str); + NULLABLE(substr); + NULLABLE(replstr); + return PyUnicode_Replace(str, substr, replstr, maxcount); +} + +/* Test PyUnicode_Compare() */ +static PyObject * +unicode_compare(PyObject *self, PyObject *args) +{ + PyObject *left; + PyObject *right; + int result; + + if (!PyArg_ParseTuple(args, "OO", &left, &right)) + return NULL; + + NULLABLE(left); + NULLABLE(right); + result = PyUnicode_Compare(left, right); + if (result == -1 && PyErr_Occurred()) { + return NULL; + } + assert(!PyErr_Occurred()); + return PyLong_FromLong(result); +} + +/* Test PyUnicode_CompareWithASCIIString() */ +static PyObject * +unicode_comparewithasciistring(PyObject *self, PyObject *args) +{ + PyObject *left; + const char *right = NULL; + Py_ssize_t right_len; + int result; + + if (!PyArg_ParseTuple(args, "O|y#", &left, &right, &right_len)) + return NULL; + + NULLABLE(left); + result = PyUnicode_CompareWithASCIIString(left, right); + if (result == -1 && PyErr_Occurred()) { + return NULL; + } + return PyLong_FromLong(result); +} + +/* Test PyUnicode_RichCompare() */ +static PyObject * +unicode_richcompare(PyObject *self, PyObject *args) +{ + PyObject *left; + PyObject *right; + int op; + + if (!PyArg_ParseTuple(args, "OOi", &left, &right, &op)) + return NULL; + + NULLABLE(left); + NULLABLE(right); + return PyUnicode_RichCompare(left, right, op); +} + +/* Test PyUnicode_Format() */ +static PyObject * +unicode_format(PyObject *self, PyObject *args) +{ + PyObject *format; + PyObject *fargs; + + if (!PyArg_ParseTuple(args, "OO", &format, &fargs)) + return NULL; + + NULLABLE(format); + NULLABLE(fargs); + return PyUnicode_Format(format, fargs); +} + +/* Test PyUnicode_Contains() */ +static PyObject * +unicode_contains(PyObject *self, PyObject *args) +{ + PyObject *container; + PyObject *element; + + if (!PyArg_ParseTuple(args, "OO", &container, &element)) + return NULL; + + NULLABLE(container); + NULLABLE(element); + RETURN_INT(PyUnicode_Contains(container, element)); +} + +/* Test PyUnicode_IsIdentifier() */ +static PyObject * +unicode_isidentifier(PyObject *self, PyObject *arg) +{ + NULLABLE(arg); + RETURN_INT(PyUnicode_IsIdentifier(arg)); +} + +/* Test PyUnicode_CopyCharacters() */ +static PyObject * +unicode_copycharacters(PyObject *self, PyObject *args) +{ + PyObject *from, *to, *to_copy; + Py_ssize_t from_start, to_start, how_many, copied; + + if (!PyArg_ParseTuple(args, "UnOnn", &to, &to_start, + &from, &from_start, &how_many)) { + return NULL; + } + + NULLABLE(from); + if (!(to_copy = PyUnicode_New(PyUnicode_GET_LENGTH(to), + PyUnicode_MAX_CHAR_VALUE(to)))) { + return NULL; + } + if (PyUnicode_Fill(to_copy, 0, PyUnicode_GET_LENGTH(to_copy), 0U) < 0) { + Py_DECREF(to_copy); + return NULL; + } + + copied = PyUnicode_CopyCharacters(to_copy, to_start, from, + from_start, how_many); + if (copied == -1 && PyErr_Occurred()) { + Py_DECREF(to_copy); + return NULL; + } + + return Py_BuildValue("(Nn)", to_copy, copied); +} + +static int +check_raised_systemerror(PyObject *result, char* msg) +{ + if (result) { + // no exception + PyErr_Format(PyExc_AssertionError, + "SystemError not raised: %s", + msg); + return 0; + } + if (PyErr_ExceptionMatches(PyExc_SystemError)) { + // expected exception + PyErr_Clear(); + return 1; + } + // unexpected exception + return 0; +} + +static PyObject * +test_string_from_format(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject *result; + PyObject *unicode = PyUnicode_FromString("None"); + +#define CHECK_FORMAT_2(FORMAT, EXPECTED, ARG1, ARG2) \ + result = PyUnicode_FromFormat(FORMAT, ARG1, ARG2); \ + if (EXPECTED == NULL) { \ + if (!check_raised_systemerror(result, FORMAT)) { \ + goto Fail; \ + } \ + } \ + else if (result == NULL) \ + return NULL; \ + else if (!_PyUnicode_EqualToASCIIString(result, EXPECTED)) { \ + PyErr_Format(PyExc_AssertionError, \ + "test_string_from_format: failed at \"%s\" " \ + "expected \"%s\" got \"%s\"", \ + FORMAT, EXPECTED, PyUnicode_AsUTF8(result)); \ + goto Fail; \ + } \ + Py_XDECREF(result) + +#define CHECK_FORMAT_1(FORMAT, EXPECTED, ARG) \ + CHECK_FORMAT_2(FORMAT, EXPECTED, ARG, 0) + +#define CHECK_FORMAT_0(FORMAT, EXPECTED) \ + CHECK_FORMAT_2(FORMAT, EXPECTED, 0, 0) + + // Unrecognized + CHECK_FORMAT_2("%u %? %u", NULL, 1, 2); + + // "%%" (options are rejected) + CHECK_FORMAT_0( "%%", "%"); + CHECK_FORMAT_0( "%0%", NULL); + CHECK_FORMAT_0("%00%", NULL); + CHECK_FORMAT_0( "%2%", NULL); + CHECK_FORMAT_0("%02%", NULL); + CHECK_FORMAT_0("%.0%", NULL); + CHECK_FORMAT_0("%.2%", NULL); + + // "%c" + CHECK_FORMAT_1( "%c", "c", 'c'); + CHECK_FORMAT_1( "%0c", "c", 'c'); + CHECK_FORMAT_1("%00c", "c", 'c'); + CHECK_FORMAT_1( "%2c", NULL, 'c'); + CHECK_FORMAT_1("%02c", NULL, 'c'); + CHECK_FORMAT_1("%.0c", NULL, 'c'); + CHECK_FORMAT_1("%.2c", NULL, 'c'); + + // Integers + CHECK_FORMAT_1("%d", "123", (int)123); + CHECK_FORMAT_1("%i", "123", (int)123); + CHECK_FORMAT_1("%u", "123", (unsigned int)123); + CHECK_FORMAT_1("%x", "7b", (unsigned int)123); + CHECK_FORMAT_1("%X", "7B", (unsigned int)123); + CHECK_FORMAT_1("%o", "173", (unsigned int)123); + CHECK_FORMAT_1("%ld", "123", (long)123); + CHECK_FORMAT_1("%li", "123", (long)123); + CHECK_FORMAT_1("%lu", "123", (unsigned long)123); + CHECK_FORMAT_1("%lx", "7b", (unsigned long)123); + CHECK_FORMAT_1("%lX", "7B", (unsigned long)123); + CHECK_FORMAT_1("%lo", "173", (unsigned long)123); + CHECK_FORMAT_1("%lld", "123", (long long)123); + CHECK_FORMAT_1("%lli", "123", (long long)123); + CHECK_FORMAT_1("%llu", "123", (unsigned long long)123); + CHECK_FORMAT_1("%llx", "7b", (unsigned long long)123); + CHECK_FORMAT_1("%llX", "7B", (unsigned long long)123); + CHECK_FORMAT_1("%llo", "173", (unsigned long long)123); + CHECK_FORMAT_1("%zd", "123", (Py_ssize_t)123); + CHECK_FORMAT_1("%zi", "123", (Py_ssize_t)123); + CHECK_FORMAT_1("%zu", "123", (size_t)123); + CHECK_FORMAT_1("%zx", "7b", (size_t)123); + CHECK_FORMAT_1("%zX", "7B", (size_t)123); + CHECK_FORMAT_1("%zo", "173", (size_t)123); + CHECK_FORMAT_1("%td", "123", (ptrdiff_t)123); + CHECK_FORMAT_1("%ti", "123", (ptrdiff_t)123); + CHECK_FORMAT_1("%tu", "123", (ptrdiff_t)123); + CHECK_FORMAT_1("%tx", "7b", (ptrdiff_t)123); + CHECK_FORMAT_1("%tX", "7B", (ptrdiff_t)123); + CHECK_FORMAT_1("%to", "173", (ptrdiff_t)123); + CHECK_FORMAT_1("%jd", "123", (intmax_t)123); + CHECK_FORMAT_1("%ji", "123", (intmax_t)123); + CHECK_FORMAT_1("%ju", "123", (uintmax_t)123); + CHECK_FORMAT_1("%jx", "7b", (uintmax_t)123); + CHECK_FORMAT_1("%jX", "7B", (uintmax_t)123); + CHECK_FORMAT_1("%jo", "173", (uintmax_t)123); + + CHECK_FORMAT_1("%d", "-123", (int)-123); + CHECK_FORMAT_1("%i", "-123", (int)-123); + CHECK_FORMAT_1("%ld", "-123", (long)-123); + CHECK_FORMAT_1("%li", "-123", (long)-123); + CHECK_FORMAT_1("%lld", "-123", (long long)-123); + CHECK_FORMAT_1("%lli", "-123", (long long)-123); + CHECK_FORMAT_1("%zd", "-123", (Py_ssize_t)-123); + CHECK_FORMAT_1("%zi", "-123", (Py_ssize_t)-123); + CHECK_FORMAT_1("%td", "-123", (ptrdiff_t)-123); + CHECK_FORMAT_1("%ti", "-123", (ptrdiff_t)-123); + CHECK_FORMAT_1("%jd", "-123", (intmax_t)-123); + CHECK_FORMAT_1("%ji", "-123", (intmax_t)-123); + + // Integers: width < length + CHECK_FORMAT_1("%1d", "123", (int)123); + CHECK_FORMAT_1("%1i", "123", (int)123); + CHECK_FORMAT_1("%1u", "123", (unsigned int)123); + CHECK_FORMAT_1("%1ld", "123", (long)123); + CHECK_FORMAT_1("%1li", "123", (long)123); + CHECK_FORMAT_1("%1lu", "123", (unsigned long)123); + CHECK_FORMAT_1("%1lld", "123", (long long)123); + CHECK_FORMAT_1("%1lli", "123", (long long)123); + CHECK_FORMAT_1("%1llu", "123", (unsigned long long)123); + CHECK_FORMAT_1("%1zd", "123", (Py_ssize_t)123); + CHECK_FORMAT_1("%1zi", "123", (Py_ssize_t)123); + CHECK_FORMAT_1("%1zu", "123", (size_t)123); + CHECK_FORMAT_1("%1x", "7b", (int)123); + + CHECK_FORMAT_1("%1d", "-123", (int)-123); + CHECK_FORMAT_1("%1i", "-123", (int)-123); + CHECK_FORMAT_1("%1ld", "-123", (long)-123); + CHECK_FORMAT_1("%1li", "-123", (long)-123); + CHECK_FORMAT_1("%1lld", "-123", (long long)-123); + CHECK_FORMAT_1("%1lli", "-123", (long long)-123); + CHECK_FORMAT_1("%1zd", "-123", (Py_ssize_t)-123); + CHECK_FORMAT_1("%1zi", "-123", (Py_ssize_t)-123); + + // Integers: width > length + CHECK_FORMAT_1("%5d", " 123", (int)123); + CHECK_FORMAT_1("%5i", " 123", (int)123); + CHECK_FORMAT_1("%5u", " 123", (unsigned int)123); + CHECK_FORMAT_1("%5ld", " 123", (long)123); + CHECK_FORMAT_1("%5li", " 123", (long)123); + CHECK_FORMAT_1("%5lu", " 123", (unsigned long)123); + CHECK_FORMAT_1("%5lld", " 123", (long long)123); + CHECK_FORMAT_1("%5lli", " 123", (long long)123); + CHECK_FORMAT_1("%5llu", " 123", (unsigned long long)123); + CHECK_FORMAT_1("%5zd", " 123", (Py_ssize_t)123); + CHECK_FORMAT_1("%5zi", " 123", (Py_ssize_t)123); + CHECK_FORMAT_1("%5zu", " 123", (size_t)123); + CHECK_FORMAT_1("%5x", " 7b", (int)123); + + CHECK_FORMAT_1("%5d", " -123", (int)-123); + CHECK_FORMAT_1("%5i", " -123", (int)-123); + CHECK_FORMAT_1("%5ld", " -123", (long)-123); + CHECK_FORMAT_1("%5li", " -123", (long)-123); + CHECK_FORMAT_1("%5lld", " -123", (long long)-123); + CHECK_FORMAT_1("%5lli", " -123", (long long)-123); + CHECK_FORMAT_1("%5zd", " -123", (Py_ssize_t)-123); + CHECK_FORMAT_1("%5zi", " -123", (Py_ssize_t)-123); + + // Integers: width > length, 0-flag + CHECK_FORMAT_1("%05d", "00123", (int)123); + CHECK_FORMAT_1("%05i", "00123", (int)123); + CHECK_FORMAT_1("%05u", "00123", (unsigned int)123); + CHECK_FORMAT_1("%05ld", "00123", (long)123); + CHECK_FORMAT_1("%05li", "00123", (long)123); + CHECK_FORMAT_1("%05lu", "00123", (unsigned long)123); + CHECK_FORMAT_1("%05lld", "00123", (long long)123); + CHECK_FORMAT_1("%05lli", "00123", (long long)123); + CHECK_FORMAT_1("%05llu", "00123", (unsigned long long)123); + CHECK_FORMAT_1("%05zd", "00123", (Py_ssize_t)123); + CHECK_FORMAT_1("%05zi", "00123", (Py_ssize_t)123); + CHECK_FORMAT_1("%05zu", "00123", (size_t)123); + CHECK_FORMAT_1("%05x", "0007b", (int)123); + + CHECK_FORMAT_1("%05d", "-0123", (int)-123); + CHECK_FORMAT_1("%05i", "-0123", (int)-123); + CHECK_FORMAT_1("%05ld", "-0123", (long)-123); + CHECK_FORMAT_1("%05li", "-0123", (long)-123); + CHECK_FORMAT_1("%05lld", "-0123", (long long)-123); + CHECK_FORMAT_1("%05lli", "-0123", (long long)-123); + CHECK_FORMAT_1("%05zd", "-0123", (Py_ssize_t)-123); + CHECK_FORMAT_1("%05zi", "-0123", (Py_ssize_t)-123); + + // Integers: precision < length + CHECK_FORMAT_1("%.1d", "123", (int)123); + CHECK_FORMAT_1("%.1i", "123", (int)123); + CHECK_FORMAT_1("%.1u", "123", (unsigned int)123); + CHECK_FORMAT_1("%.1ld", "123", (long)123); + CHECK_FORMAT_1("%.1li", "123", (long)123); + CHECK_FORMAT_1("%.1lu", "123", (unsigned long)123); + CHECK_FORMAT_1("%.1lld", "123", (long long)123); + CHECK_FORMAT_1("%.1lli", "123", (long long)123); + CHECK_FORMAT_1("%.1llu", "123", (unsigned long long)123); + CHECK_FORMAT_1("%.1zd", "123", (Py_ssize_t)123); + CHECK_FORMAT_1("%.1zi", "123", (Py_ssize_t)123); + CHECK_FORMAT_1("%.1zu", "123", (size_t)123); + CHECK_FORMAT_1("%.1x", "7b", (int)123); + + CHECK_FORMAT_1("%.1d", "-123", (int)-123); + CHECK_FORMAT_1("%.1i", "-123", (int)-123); + CHECK_FORMAT_1("%.1ld", "-123", (long)-123); + CHECK_FORMAT_1("%.1li", "-123", (long)-123); + CHECK_FORMAT_1("%.1lld", "-123", (long long)-123); + CHECK_FORMAT_1("%.1lli", "-123", (long long)-123); + CHECK_FORMAT_1("%.1zd", "-123", (Py_ssize_t)-123); + CHECK_FORMAT_1("%.1zi", "-123", (Py_ssize_t)-123); + + // Integers: precision > length + CHECK_FORMAT_1("%.5d", "00123", (int)123); + CHECK_FORMAT_1("%.5i", "00123", (int)123); + CHECK_FORMAT_1("%.5u", "00123", (unsigned int)123); + CHECK_FORMAT_1("%.5ld", "00123", (long)123); + CHECK_FORMAT_1("%.5li", "00123", (long)123); + CHECK_FORMAT_1("%.5lu", "00123", (unsigned long)123); + CHECK_FORMAT_1("%.5lld", "00123", (long long)123); + CHECK_FORMAT_1("%.5lli", "00123", (long long)123); + CHECK_FORMAT_1("%.5llu", "00123", (unsigned long long)123); + CHECK_FORMAT_1("%.5zd", "00123", (Py_ssize_t)123); + CHECK_FORMAT_1("%.5zi", "00123", (Py_ssize_t)123); + CHECK_FORMAT_1("%.5zu", "00123", (size_t)123); + CHECK_FORMAT_1("%.5x", "0007b", (int)123); + + CHECK_FORMAT_1("%.5d", "-00123", (int)-123); + CHECK_FORMAT_1("%.5i", "-00123", (int)-123); + CHECK_FORMAT_1("%.5ld", "-00123", (long)-123); + CHECK_FORMAT_1("%.5li", "-00123", (long)-123); + CHECK_FORMAT_1("%.5lld", "-00123", (long long)-123); + CHECK_FORMAT_1("%.5lli", "-00123", (long long)-123); + CHECK_FORMAT_1("%.5zd", "-00123", (Py_ssize_t)-123); + CHECK_FORMAT_1("%.5zi", "-00123", (Py_ssize_t)-123); + + // Integers: width > precision > length + CHECK_FORMAT_1("%7.5d", " 00123", (int)123); + CHECK_FORMAT_1("%7.5i", " 00123", (int)123); + CHECK_FORMAT_1("%7.5u", " 00123", (unsigned int)123); + CHECK_FORMAT_1("%7.5ld", " 00123", (long)123); + CHECK_FORMAT_1("%7.5li", " 00123", (long)123); + CHECK_FORMAT_1("%7.5lu", " 00123", (unsigned long)123); + CHECK_FORMAT_1("%7.5lld", " 00123", (long long)123); + CHECK_FORMAT_1("%7.5lli", " 00123", (long long)123); + CHECK_FORMAT_1("%7.5llu", " 00123", (unsigned long long)123); + CHECK_FORMAT_1("%7.5zd", " 00123", (Py_ssize_t)123); + CHECK_FORMAT_1("%7.5zi", " 00123", (Py_ssize_t)123); + CHECK_FORMAT_1("%7.5zu", " 00123", (size_t)123); + CHECK_FORMAT_1("%7.5x", " 0007b", (int)123); + + CHECK_FORMAT_1("%7.5d", " -00123", (int)-123); + CHECK_FORMAT_1("%7.5i", " -00123", (int)-123); + CHECK_FORMAT_1("%7.5ld", " -00123", (long)-123); + CHECK_FORMAT_1("%7.5li", " -00123", (long)-123); + CHECK_FORMAT_1("%7.5lld", " -00123", (long long)-123); + CHECK_FORMAT_1("%7.5lli", " -00123", (long long)-123); + CHECK_FORMAT_1("%7.5zd", " -00123", (Py_ssize_t)-123); + CHECK_FORMAT_1("%7.5zi", " -00123", (Py_ssize_t)-123); + + // Integers: width > precision > length, 0-flag + CHECK_FORMAT_1("%07.5d", "0000123", (int)123); + CHECK_FORMAT_1("%07.5i", "0000123", (int)123); + CHECK_FORMAT_1("%07.5u", "0000123", (unsigned int)123); + CHECK_FORMAT_1("%07.5ld", "0000123", (long)123); + CHECK_FORMAT_1("%07.5li", "0000123", (long)123); + CHECK_FORMAT_1("%07.5lu", "0000123", (unsigned long)123); + CHECK_FORMAT_1("%07.5lld", "0000123", (long long)123); + CHECK_FORMAT_1("%07.5lli", "0000123", (long long)123); + CHECK_FORMAT_1("%07.5llu", "0000123", (unsigned long long)123); + CHECK_FORMAT_1("%07.5zd", "0000123", (Py_ssize_t)123); + CHECK_FORMAT_1("%07.5zi", "0000123", (Py_ssize_t)123); + CHECK_FORMAT_1("%07.5zu", "0000123", (size_t)123); + CHECK_FORMAT_1("%07.5x", "000007b", (int)123); + + CHECK_FORMAT_1("%07.5d", "-000123", (int)-123); + CHECK_FORMAT_1("%07.5i", "-000123", (int)-123); + CHECK_FORMAT_1("%07.5ld", "-000123", (long)-123); + CHECK_FORMAT_1("%07.5li", "-000123", (long)-123); + CHECK_FORMAT_1("%07.5lld", "-000123", (long long)-123); + CHECK_FORMAT_1("%07.5lli", "-000123", (long long)-123); + CHECK_FORMAT_1("%07.5zd", "-000123", (Py_ssize_t)-123); + CHECK_FORMAT_1("%07.5zi", "-000123", (Py_ssize_t)-123); + + // Integers: precision > width > length + CHECK_FORMAT_1("%5.7d", "0000123", (int)123); + CHECK_FORMAT_1("%5.7i", "0000123", (int)123); + CHECK_FORMAT_1("%5.7u", "0000123", (unsigned int)123); + CHECK_FORMAT_1("%5.7ld", "0000123", (long)123); + CHECK_FORMAT_1("%5.7li", "0000123", (long)123); + CHECK_FORMAT_1("%5.7lu", "0000123", (unsigned long)123); + CHECK_FORMAT_1("%5.7lld", "0000123", (long long)123); + CHECK_FORMAT_1("%5.7lli", "0000123", (long long)123); + CHECK_FORMAT_1("%5.7llu", "0000123", (unsigned long long)123); + CHECK_FORMAT_1("%5.7zd", "0000123", (Py_ssize_t)123); + CHECK_FORMAT_1("%5.7zi", "0000123", (Py_ssize_t)123); + CHECK_FORMAT_1("%5.7zu", "0000123", (size_t)123); + CHECK_FORMAT_1("%5.7x", "000007b", (int)123); + + CHECK_FORMAT_1("%5.7d", "-0000123", (int)-123); + CHECK_FORMAT_1("%5.7i", "-0000123", (int)-123); + CHECK_FORMAT_1("%5.7ld", "-0000123", (long)-123); + CHECK_FORMAT_1("%5.7li", "-0000123", (long)-123); + CHECK_FORMAT_1("%5.7lld", "-0000123", (long long)-123); + CHECK_FORMAT_1("%5.7lli", "-0000123", (long long)-123); + CHECK_FORMAT_1("%5.7zd", "-0000123", (Py_ssize_t)-123); + CHECK_FORMAT_1("%5.7zi", "-0000123", (Py_ssize_t)-123); + + // Integers: precision > width > length, 0-flag + CHECK_FORMAT_1("%05.7d", "0000123", (int)123); + CHECK_FORMAT_1("%05.7i", "0000123", (int)123); + CHECK_FORMAT_1("%05.7u", "0000123", (unsigned int)123); + CHECK_FORMAT_1("%05.7ld", "0000123", (long)123); + CHECK_FORMAT_1("%05.7li", "0000123", (long)123); + CHECK_FORMAT_1("%05.7lu", "0000123", (unsigned long)123); + CHECK_FORMAT_1("%05.7lld", "0000123", (long long)123); + CHECK_FORMAT_1("%05.7lli", "0000123", (long long)123); + CHECK_FORMAT_1("%05.7llu", "0000123", (unsigned long long)123); + CHECK_FORMAT_1("%05.7zd", "0000123", (Py_ssize_t)123); + CHECK_FORMAT_1("%05.7zi", "0000123", (Py_ssize_t)123); + CHECK_FORMAT_1("%05.7zu", "0000123", (size_t)123); + CHECK_FORMAT_1("%05.7x", "000007b", (int)123); + + CHECK_FORMAT_1("%05.7d", "-0000123", (int)-123); + CHECK_FORMAT_1("%05.7i", "-0000123", (int)-123); + CHECK_FORMAT_1("%05.7ld", "-0000123", (long)-123); + CHECK_FORMAT_1("%05.7li", "-0000123", (long)-123); + CHECK_FORMAT_1("%05.7lld", "-0000123", (long long)-123); + CHECK_FORMAT_1("%05.7lli", "-0000123", (long long)-123); + CHECK_FORMAT_1("%05.7zd", "-0000123", (Py_ssize_t)-123); + CHECK_FORMAT_1("%05.7zi", "-0000123", (Py_ssize_t)-123); + + // Integers: precision = 0, arg = 0 (empty string in C) + CHECK_FORMAT_1("%.0d", "0", (int)0); + CHECK_FORMAT_1("%.0i", "0", (int)0); + CHECK_FORMAT_1("%.0u", "0", (unsigned int)0); + CHECK_FORMAT_1("%.0ld", "0", (long)0); + CHECK_FORMAT_1("%.0li", "0", (long)0); + CHECK_FORMAT_1("%.0lu", "0", (unsigned long)0); + CHECK_FORMAT_1("%.0lld", "0", (long long)0); + CHECK_FORMAT_1("%.0lli", "0", (long long)0); + CHECK_FORMAT_1("%.0llu", "0", (unsigned long long)0); + CHECK_FORMAT_1("%.0zd", "0", (Py_ssize_t)0); + CHECK_FORMAT_1("%.0zi", "0", (Py_ssize_t)0); + CHECK_FORMAT_1("%.0zu", "0", (size_t)0); + CHECK_FORMAT_1("%.0x", "0", (int)0); + + // Strings + CHECK_FORMAT_1("%s", "None", "None"); + CHECK_FORMAT_1("%ls", "None", L"None"); + CHECK_FORMAT_1("%U", "None", unicode); + CHECK_FORMAT_1("%A", "None", Py_None); + CHECK_FORMAT_1("%S", "None", Py_None); + CHECK_FORMAT_1("%R", "None", Py_None); + CHECK_FORMAT_2("%V", "None", unicode, "ignored"); + CHECK_FORMAT_2("%V", "None", NULL, "None"); + CHECK_FORMAT_2("%lV", "None", NULL, L"None"); + + // Strings: width < length + CHECK_FORMAT_1("%1s", "None", "None"); + CHECK_FORMAT_1("%1ls", "None", L"None"); + CHECK_FORMAT_1("%1U", "None", unicode); + CHECK_FORMAT_1("%1A", "None", Py_None); + CHECK_FORMAT_1("%1S", "None", Py_None); + CHECK_FORMAT_1("%1R", "None", Py_None); + CHECK_FORMAT_2("%1V", "None", unicode, "ignored"); + CHECK_FORMAT_2("%1V", "None", NULL, "None"); + CHECK_FORMAT_2("%1lV", "None", NULL, L"None"); + + // Strings: width > length + CHECK_FORMAT_1("%5s", " None", "None"); + CHECK_FORMAT_1("%5ls", " None", L"None"); + CHECK_FORMAT_1("%5U", " None", unicode); + CHECK_FORMAT_1("%5A", " None", Py_None); + CHECK_FORMAT_1("%5S", " None", Py_None); + CHECK_FORMAT_1("%5R", " None", Py_None); + CHECK_FORMAT_2("%5V", " None", unicode, "ignored"); + CHECK_FORMAT_2("%5V", " None", NULL, "None"); + CHECK_FORMAT_2("%5lV", " None", NULL, L"None"); + + // Strings: precision < length + CHECK_FORMAT_1("%.1s", "N", "None"); + CHECK_FORMAT_1("%.1ls", "N", L"None"); + CHECK_FORMAT_1("%.1U", "N", unicode); + CHECK_FORMAT_1("%.1A", "N", Py_None); + CHECK_FORMAT_1("%.1S", "N", Py_None); + CHECK_FORMAT_1("%.1R", "N", Py_None); + CHECK_FORMAT_2("%.1V", "N", unicode, "ignored"); + CHECK_FORMAT_2("%.1V", "N", NULL, "None"); + CHECK_FORMAT_2("%.1lV", "N", NULL, L"None"); + + // Strings: precision > length + CHECK_FORMAT_1("%.5s", "None", "None"); + CHECK_FORMAT_1("%.5ls", "None", L"None"); + CHECK_FORMAT_1("%.5U", "None", unicode); + CHECK_FORMAT_1("%.5A", "None", Py_None); + CHECK_FORMAT_1("%.5S", "None", Py_None); + CHECK_FORMAT_1("%.5R", "None", Py_None); + CHECK_FORMAT_2("%.5V", "None", unicode, "ignored"); + CHECK_FORMAT_2("%.5V", "None", NULL, "None"); + CHECK_FORMAT_2("%.5lV", "None", NULL, L"None"); + + // Strings: precision < length, width > length + CHECK_FORMAT_1("%5.1s", " N", "None"); + CHECK_FORMAT_1("%5.1ls"," N", L"None"); + CHECK_FORMAT_1("%5.1U", " N", unicode); + CHECK_FORMAT_1("%5.1A", " N", Py_None); + CHECK_FORMAT_1("%5.1S", " N", Py_None); + CHECK_FORMAT_1("%5.1R", " N", Py_None); + CHECK_FORMAT_2("%5.1V", " N", unicode, "ignored"); + CHECK_FORMAT_2("%5.1V", " N", NULL, "None"); + CHECK_FORMAT_2("%5.1lV"," N", NULL, L"None"); + + // Strings: width < length, precision > length + CHECK_FORMAT_1("%1.5s", "None", "None"); + CHECK_FORMAT_1("%1.5ls", "None", L"None"); + CHECK_FORMAT_1("%1.5U", "None", unicode); + CHECK_FORMAT_1("%1.5A", "None", Py_None); + CHECK_FORMAT_1("%1.5S", "None", Py_None); + CHECK_FORMAT_1("%1.5R", "None", Py_None); + CHECK_FORMAT_2("%1.5V", "None", unicode, "ignored"); + CHECK_FORMAT_2("%1.5V", "None", NULL, "None"); + CHECK_FORMAT_2("%1.5lV", "None", NULL, L"None"); + + Py_XDECREF(unicode); + Py_RETURN_NONE; + + Fail: + Py_XDECREF(result); + Py_XDECREF(unicode); + return NULL; + +#undef CHECK_FORMAT_2 +#undef CHECK_FORMAT_1 +#undef CHECK_FORMAT_0 +} + +static PyMethodDef TestMethods[] = { + {"codec_incrementalencoder", codec_incrementalencoder, METH_VARARGS}, + {"codec_incrementaldecoder", codec_incrementaldecoder, METH_VARARGS}, + {"test_unicode_compare_with_ascii", + test_unicode_compare_with_ascii, METH_NOARGS}, + {"test_string_from_format", test_string_from_format, METH_NOARGS}, + {"test_widechar", test_widechar, METH_NOARGS}, + {"unicode_new", unicode_new, METH_VARARGS}, + {"unicode_fill", unicode_fill, METH_VARARGS}, + {"unicode_writechar", unicode_writechar, METH_VARARGS}, + {"unicode_resize", unicode_resize, METH_VARARGS}, + {"unicode_append", unicode_append, METH_VARARGS}, + {"unicode_appendanddel", unicode_appendanddel, METH_VARARGS}, + {"unicode_fromstringandsize",unicode_fromstringandsize, METH_VARARGS}, + {"unicode_fromstring", unicode_fromstring, METH_O}, + {"unicode_fromkindanddata", unicode_fromkindanddata, METH_VARARGS}, + {"unicode_substring", unicode_substring, METH_VARARGS}, + {"unicode_getlength", unicode_getlength, METH_O}, + {"unicode_readchar", unicode_readchar, METH_VARARGS}, + {"unicode_fromencodedobject",unicode_fromencodedobject, METH_VARARGS}, + {"unicode_fromobject", unicode_fromobject, METH_O}, + {"unicode_interninplace", unicode_interninplace, METH_O}, + {"unicode_internfromstring", unicode_internfromstring, METH_O}, + {"unicode_fromwidechar", unicode_fromwidechar, METH_VARARGS}, + {"unicode_aswidechar", unicode_aswidechar, METH_VARARGS}, + {"unicode_aswidechar_null", unicode_aswidechar_null, METH_VARARGS}, + {"unicode_aswidecharstring", unicode_aswidecharstring, METH_VARARGS}, + {"unicode_aswidecharstring_null",unicode_aswidecharstring_null,METH_VARARGS}, + {"unicode_asucs4", unicode_asucs4, METH_VARARGS}, + {"unicode_asucs4copy", unicode_asucs4copy, METH_VARARGS}, + {"unicode_fromordinal", unicode_fromordinal, METH_VARARGS}, + {"unicode_asutf8", unicode_asutf8, METH_VARARGS}, + {"unicode_asutf8andsize", unicode_asutf8andsize, METH_VARARGS}, + {"unicode_asutf8andsize_null",unicode_asutf8andsize_null, METH_VARARGS}, + {"unicode_getdefaultencoding",unicode_getdefaultencoding, METH_NOARGS}, + {"unicode_decode", unicode_decode, METH_VARARGS}, + {"unicode_asencodedstring", unicode_asencodedstring, METH_VARARGS}, + {"unicode_buildencodingmap", unicode_buildencodingmap, METH_O}, + {"unicode_decodeutf7", unicode_decodeutf7, METH_VARARGS}, + {"unicode_decodeutf7stateful",unicode_decodeutf7stateful, METH_VARARGS}, + {"unicode_decodeutf8", unicode_decodeutf8, METH_VARARGS}, + {"unicode_decodeutf8stateful",unicode_decodeutf8stateful, METH_VARARGS}, + {"unicode_asutf8string", unicode_asutf8string, METH_O}, + {"unicode_decodeutf16", unicode_decodeutf16, METH_VARARGS}, + {"unicode_decodeutf16stateful",unicode_decodeutf16stateful, METH_VARARGS}, + {"unicode_asutf16string", unicode_asutf16string, METH_O}, + {"unicode_decodeutf32", unicode_decodeutf32, METH_VARARGS}, + {"unicode_decodeutf32stateful",unicode_decodeutf32stateful, METH_VARARGS}, + {"unicode_asutf32string", unicode_asutf32string, METH_O}, + {"unicode_decodeunicodeescape",unicode_decodeunicodeescape, METH_VARARGS}, + {"unicode_asunicodeescapestring",unicode_asunicodeescapestring,METH_O}, + {"unicode_decoderawunicodeescape",unicode_decoderawunicodeescape,METH_VARARGS}, + {"unicode_asrawunicodeescapestring",unicode_asrawunicodeescapestring,METH_O}, + {"unicode_decodelatin1", unicode_decodelatin1, METH_VARARGS}, + {"unicode_aslatin1string", unicode_aslatin1string, METH_O}, + {"unicode_decodeascii", unicode_decodeascii, METH_VARARGS}, + {"unicode_asasciistring", unicode_asasciistring, METH_O}, + {"unicode_decodecharmap", unicode_decodecharmap, METH_VARARGS}, + {"unicode_ascharmapstring", unicode_ascharmapstring, METH_VARARGS}, +#ifdef MS_WINDOWS + {"unicode_decodembcs", unicode_decodembcs, METH_VARARGS}, + {"unicode_decodembcsstateful",unicode_decodembcsstateful, METH_VARARGS}, + {"unicode_decodecodepagestateful",unicode_decodecodepagestateful,METH_VARARGS}, + {"unicode_asmbcsstring", unicode_asmbcsstring, METH_O}, + {"unicode_encodecodepage", unicode_encodecodepage, METH_VARARGS}, +#endif /* MS_WINDOWS */ + {"unicode_decodelocaleandsize",unicode_decodelocaleandsize, METH_VARARGS}, + {"unicode_decodelocale", unicode_decodelocale, METH_VARARGS}, + {"unicode_encodelocale", unicode_encodelocale, METH_VARARGS}, + {"unicode_decodefsdefault", unicode_decodefsdefault, METH_VARARGS}, + {"unicode_decodefsdefaultandsize",unicode_decodefsdefaultandsize,METH_VARARGS}, + {"unicode_encodefsdefault", unicode_encodefsdefault, METH_O}, + {"unicode_transformdecimalandspacetoascii", unicode_transformdecimalandspacetoascii, METH_O}, + {"unicode_concat", unicode_concat, METH_VARARGS}, + {"unicode_splitlines", unicode_splitlines, METH_VARARGS}, + {"unicode_split", unicode_split, METH_VARARGS}, + {"unicode_rsplit", unicode_rsplit, METH_VARARGS}, + {"unicode_partition", unicode_partition, METH_VARARGS}, + {"unicode_rpartition", unicode_rpartition, METH_VARARGS}, + {"unicode_translate", unicode_translate, METH_VARARGS}, + {"unicode_join", unicode_join, METH_VARARGS}, + {"unicode_count", unicode_count, METH_VARARGS}, + {"unicode_tailmatch", unicode_tailmatch, METH_VARARGS}, + {"unicode_find", unicode_find, METH_VARARGS}, + {"unicode_findchar", unicode_findchar, METH_VARARGS}, + {"unicode_replace", unicode_replace, METH_VARARGS}, + {"unicode_compare", unicode_compare, METH_VARARGS}, + {"unicode_comparewithasciistring",unicode_comparewithasciistring,METH_VARARGS}, + {"unicode_richcompare", unicode_richcompare, METH_VARARGS}, + {"unicode_format", unicode_format, METH_VARARGS}, + {"unicode_contains", unicode_contains, METH_VARARGS}, + {"unicode_isidentifier", unicode_isidentifier, METH_O}, + {"unicode_copycharacters", unicode_copycharacters, METH_VARARGS}, + {NULL}, +}; + +int +_PyTestCapi_Init_Unicode(PyObject *m) { + _testcapimodule = PyModule_GetDef(m); + + if (PyModule_AddFunctions(m, TestMethods) < 0) { + return -1; + } + + return 0; +} diff --git a/Modules/_testcapi/util.h b/Modules/_testcapi/util.h new file mode 100644 index 00000000..4cf7e226 --- /dev/null +++ b/Modules/_testcapi/util.h @@ -0,0 +1,32 @@ +#define NULLABLE(x) do { \ + if (x == Py_None) { \ + x = NULL; \ + } \ + } while (0); + +#define RETURN_INT(value) do { \ + int _ret = (value); \ + if (_ret == -1) { \ + assert(PyErr_Occurred()); \ + return NULL; \ + } \ + assert(!PyErr_Occurred()); \ + return PyLong_FromLong(_ret); \ + } while (0) + +#define RETURN_SIZE(value) do { \ + Py_ssize_t _ret = (value); \ + if (_ret == -1) { \ + assert(PyErr_Occurred()); \ + return NULL; \ + } \ + assert(!PyErr_Occurred()); \ + return PyLong_FromSsize_t(_ret); \ + } while (0) + +/* Marker to check that pointer value was set. */ +#define UNINITIALIZED_PTR ((void *)"uninitialized") +/* Marker to check that Py_ssize_t value was set. */ +#define UNINITIALIZED_SIZE ((Py_ssize_t)236892191) +/* Marker to check that integer value was set. */ +#define UNINITIALIZED_INT (63256717) diff --git a/Modules/_testcapi/vectorcall.c b/Modules/_testcapi/vectorcall.c new file mode 100644 index 00000000..dcbc973c --- /dev/null +++ b/Modules/_testcapi/vectorcall.c @@ -0,0 +1,406 @@ +#include "parts.h" +#include "clinic/vectorcall.c.h" + +#include "structmember.h" // PyMemberDef +#include <stddef.h> // offsetof + + +/* Test PEP 590 - Vectorcall */ + +static int +fastcall_args(PyObject *args, PyObject ***stack, Py_ssize_t *nargs) +{ + if (args == Py_None) { + *stack = NULL; + *nargs = 0; + } + else if (PyTuple_Check(args)) { + *stack = ((PyTupleObject *)args)->ob_item; + *nargs = PyTuple_GET_SIZE(args); + } + else { + PyErr_SetString(PyExc_TypeError, "args must be None or a tuple"); + return -1; + } + return 0; +} + + +static PyObject * +test_pyobject_fastcall(PyObject *self, PyObject *args) +{ + PyObject *func, *func_args; + PyObject **stack; + Py_ssize_t nargs; + + if (!PyArg_ParseTuple(args, "OO", &func, &func_args)) { + return NULL; + } + + if (fastcall_args(func_args, &stack, &nargs) < 0) { + return NULL; + } + return _PyObject_FastCall(func, stack, nargs); +} + +static PyObject * +test_pyobject_fastcalldict(PyObject *self, PyObject *args) +{ + PyObject *func, *func_args, *kwargs; + PyObject **stack; + Py_ssize_t nargs; + + if (!PyArg_ParseTuple(args, "OOO", &func, &func_args, &kwargs)) { + return NULL; + } + + if (fastcall_args(func_args, &stack, &nargs) < 0) { + return NULL; + } + + if (kwargs == Py_None) { + kwargs = NULL; + } + else if (!PyDict_Check(kwargs)) { + PyErr_SetString(PyExc_TypeError, "kwnames must be None or a dict"); + return NULL; + } + + return PyObject_VectorcallDict(func, stack, nargs, kwargs); +} + +static PyObject * +test_pyobject_vectorcall(PyObject *self, PyObject *args) +{ + PyObject *func, *func_args, *kwnames = NULL; + PyObject **stack; + Py_ssize_t nargs, nkw; + + if (!PyArg_ParseTuple(args, "OOO", &func, &func_args, &kwnames)) { + return NULL; + } + + if (fastcall_args(func_args, &stack, &nargs) < 0) { + return NULL; + } + + if (kwnames == Py_None) { + kwnames = NULL; + } + else if (PyTuple_Check(kwnames)) { + nkw = PyTuple_GET_SIZE(kwnames); + if (nargs < nkw) { + PyErr_SetString(PyExc_ValueError, "kwnames longer than args"); + return NULL; + } + nargs -= nkw; + } + else { + PyErr_SetString(PyExc_TypeError, "kwnames must be None or a tuple"); + return NULL; + } + return PyObject_Vectorcall(func, stack, nargs, kwnames); +} + +static PyObject * +override_vectorcall(PyObject *callable, PyObject *const *args, size_t nargsf, + PyObject *kwnames) +{ + return PyUnicode_FromString("overridden"); +} + +static PyObject * +function_setvectorcall(PyObject *self, PyObject *func) +{ + if (!PyFunction_Check(func)) { + PyErr_SetString(PyExc_TypeError, "'func' must be a function"); + return NULL; + } + PyFunction_SetVectorcall((PyFunctionObject *)func, (vectorcallfunc)override_vectorcall); + Py_RETURN_NONE; +} + +static PyObject * +test_pyvectorcall_call(PyObject *self, PyObject *args) +{ + PyObject *func; + PyObject *argstuple; + PyObject *kwargs = NULL; + + if (!PyArg_ParseTuple(args, "OO|O", &func, &argstuple, &kwargs)) { + return NULL; + } + + if (!PyTuple_Check(argstuple)) { + PyErr_SetString(PyExc_TypeError, "args must be a tuple"); + return NULL; + } + if (kwargs != NULL && !PyDict_Check(kwargs)) { + PyErr_SetString(PyExc_TypeError, "kwargs must be a dict"); + return NULL; + } + + return PyVectorcall_Call(func, argstuple, kwargs); +} + +PyObject * +VectorCallClass_tpcall(PyObject *self, PyObject *args, PyObject *kwargs) { + return PyUnicode_FromString("tp_call"); +} + +PyObject * +VectorCallClass_vectorcall(PyObject *callable, + PyObject *const *args, + size_t nargsf, + PyObject *kwnames) { + return PyUnicode_FromString("vectorcall"); +} + +/*[clinic input] +module _testcapi +class _testcapi.VectorCallClass "PyObject *" "&PyType_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=8423a8e919f2f0df]*/ + +/*[clinic input] +_testcapi.VectorCallClass.set_vectorcall + + type: object(subclass_of="&PyType_Type", type="PyTypeObject *") + / + +Set self's vectorcall function for `type` to one that returns "vectorcall" +[clinic start generated code]*/ + +static PyObject * +_testcapi_VectorCallClass_set_vectorcall_impl(PyObject *self, + PyTypeObject *type) +/*[clinic end generated code: output=b37f0466f15da903 input=840de66182c7d71a]*/ +{ + if (!PyObject_TypeCheck(self, type)) { + return PyErr_Format( + PyExc_TypeError, + "expected %s instance", + PyType_GetName(type)); + } + if (!type->tp_vectorcall_offset) { + return PyErr_Format( + PyExc_TypeError, + "type %s has no vectorcall offset", + PyType_GetName(type)); + } + *(vectorcallfunc*)((char*)self + type->tp_vectorcall_offset) = ( + VectorCallClass_vectorcall); + Py_RETURN_NONE; +} + +PyMethodDef VectorCallClass_methods[] = { + _TESTCAPI_VECTORCALLCLASS_SET_VECTORCALL_METHODDEF + {NULL, NULL} +}; + +PyMemberDef VectorCallClass_members[] = { + {"__vectorcalloffset__", T_PYSSIZET, 0/* set later */, READONLY}, + {NULL} +}; + +PyType_Slot VectorCallClass_slots[] = { + {Py_tp_call, VectorCallClass_tpcall}, + {Py_tp_members, VectorCallClass_members}, + {Py_tp_methods, VectorCallClass_methods}, + {0}, +}; + +/*[clinic input] +_testcapi.make_vectorcall_class + + base: object(subclass_of="&PyType_Type", type="PyTypeObject *") = NULL + / + +Create a class whose instances return "tpcall" when called. + +When the "set_vectorcall" method is called on an instance, a vectorcall +function that returns "vectorcall" will be installed. +[clinic start generated code]*/ + +static PyObject * +_testcapi_make_vectorcall_class_impl(PyObject *module, PyTypeObject *base) +/*[clinic end generated code: output=16dcfc3062ddf968 input=f72e01ccf52de2b4]*/ +{ + if (!base) { + base = (PyTypeObject *)&PyBaseObject_Type; + } + VectorCallClass_members[0].offset = base->tp_basicsize; + PyType_Spec spec = { + .name = "_testcapi.VectorcallClass", + .basicsize = (int)(base->tp_basicsize + sizeof(vectorcallfunc)), + .flags = Py_TPFLAGS_DEFAULT + | Py_TPFLAGS_HAVE_VECTORCALL + | Py_TPFLAGS_BASETYPE, + .slots = VectorCallClass_slots, + }; + + return PyType_FromSpecWithBases(&spec, (PyObject *)base); +} + +/*[clinic input] +_testcapi.has_vectorcall_flag -> bool + + type: object(subclass_of="&PyType_Type", type="PyTypeObject *") + / + +Return true iff Py_TPFLAGS_HAVE_VECTORCALL is set on the class. +[clinic start generated code]*/ + +static int +_testcapi_has_vectorcall_flag_impl(PyObject *module, PyTypeObject *type) +/*[clinic end generated code: output=3ae8d1374388c671 input=8eee492ac548749e]*/ +{ + return PyType_HasFeature(type, Py_TPFLAGS_HAVE_VECTORCALL); +} + +static PyMethodDef TestMethods[] = { + {"pyobject_fastcall", test_pyobject_fastcall, METH_VARARGS}, + {"pyobject_fastcalldict", test_pyobject_fastcalldict, METH_VARARGS}, + {"pyobject_vectorcall", test_pyobject_vectorcall, METH_VARARGS}, + {"function_setvectorcall", function_setvectorcall, METH_O}, + {"pyvectorcall_call", test_pyvectorcall_call, METH_VARARGS}, + _TESTCAPI_MAKE_VECTORCALL_CLASS_METHODDEF + _TESTCAPI_HAS_VECTORCALL_FLAG_METHODDEF + {NULL}, +}; + + +typedef struct { + PyObject_HEAD + vectorcallfunc vectorcall; +} MethodDescriptorObject; + +static PyObject * +MethodDescriptor_vectorcall(PyObject *callable, PyObject *const *args, + size_t nargsf, PyObject *kwnames) +{ + /* True if using the vectorcall function in MethodDescriptorObject + * but False for MethodDescriptor2Object */ + MethodDescriptorObject *md = (MethodDescriptorObject *)callable; + return PyBool_FromLong(md->vectorcall != NULL); +} + +static PyObject * +MethodDescriptor_new(PyTypeObject* type, PyObject* args, PyObject *kw) +{ + MethodDescriptorObject *op = (MethodDescriptorObject *)type->tp_alloc(type, 0); + op->vectorcall = MethodDescriptor_vectorcall; + return (PyObject *)op; +} + +static PyObject * +func_descr_get(PyObject *func, PyObject *obj, PyObject *type) +{ + if (obj == Py_None || obj == NULL) { + return Py_NewRef(func); + } + return PyMethod_New(func, obj); +} + +static PyObject * +nop_descr_get(PyObject *func, PyObject *obj, PyObject *type) +{ + return Py_NewRef(func); +} + +static PyObject * +call_return_args(PyObject *self, PyObject *args, PyObject *kwargs) +{ + return Py_NewRef(args); +} + +static PyTypeObject MethodDescriptorBase_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "MethodDescriptorBase", + sizeof(MethodDescriptorObject), + .tp_new = MethodDescriptor_new, + .tp_call = PyVectorcall_Call, + .tp_vectorcall_offset = offsetof(MethodDescriptorObject, vectorcall), + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_METHOD_DESCRIPTOR | Py_TPFLAGS_HAVE_VECTORCALL, + .tp_descr_get = func_descr_get, +}; + +static PyTypeObject MethodDescriptorDerived_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "MethodDescriptorDerived", + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, +}; + +static PyTypeObject MethodDescriptorNopGet_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "MethodDescriptorNopGet", + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + .tp_call = call_return_args, + .tp_descr_get = nop_descr_get, +}; + +typedef struct { + MethodDescriptorObject base; + vectorcallfunc vectorcall; +} MethodDescriptor2Object; + +static PyObject * +MethodDescriptor2_new(PyTypeObject* type, PyObject* args, PyObject *kw) +{ + MethodDescriptor2Object *op = PyObject_New(MethodDescriptor2Object, type); + op->base.vectorcall = NULL; + op->vectorcall = MethodDescriptor_vectorcall; + return (PyObject *)op; +} + +static PyTypeObject MethodDescriptor2_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "MethodDescriptor2", + sizeof(MethodDescriptor2Object), + .tp_new = MethodDescriptor2_new, + .tp_call = PyVectorcall_Call, + .tp_vectorcall_offset = offsetof(MethodDescriptor2Object, vectorcall), + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_VECTORCALL, +}; + + +int +_PyTestCapi_Init_Vectorcall(PyObject *m) { + if (PyModule_AddFunctions(m, TestMethods) < 0) { + return -1; + } + + if (PyType_Ready(&MethodDescriptorBase_Type) < 0) { + return -1; + } + if (PyModule_AddType(m, &MethodDescriptorBase_Type) < 0) { + return -1; + } + + MethodDescriptorDerived_Type.tp_base = &MethodDescriptorBase_Type; + if (PyType_Ready(&MethodDescriptorDerived_Type) < 0) { + return -1; + } + if (PyModule_AddType(m, &MethodDescriptorDerived_Type) < 0) { + return -1; + } + + MethodDescriptorNopGet_Type.tp_base = &MethodDescriptorBase_Type; + if (PyType_Ready(&MethodDescriptorNopGet_Type) < 0) { + return -1; + } + if (PyModule_AddType(m, &MethodDescriptorNopGet_Type) < 0) { + return -1; + } + + MethodDescriptor2_Type.tp_base = &MethodDescriptorBase_Type; + if (PyType_Ready(&MethodDescriptor2_Type) < 0) { + return -1; + } + if (PyModule_AddType(m, &MethodDescriptor2_Type) < 0) { + return -1; + } + + return 0; +} diff --git a/Modules/_testcapi/vectorcall_limited.c b/Modules/_testcapi/vectorcall_limited.c new file mode 100644 index 00000000..a69f1d3f --- /dev/null +++ b/Modules/_testcapi/vectorcall_limited.c @@ -0,0 +1,179 @@ +#define Py_LIMITED_API 0x030c0000 // 3.12 +#include "parts.h" + +#ifdef LIMITED_API_AVAILABLE + +#include "structmember.h" // PyMemberDef + +/* Test Vectorcall in the limited API */ + +static PyObject * +LimitedVectorCallClass_tpcall(PyObject *self, PyObject *args, PyObject *kwargs) { + return PyUnicode_FromString("tp_call called"); +} + +static PyObject * +LimitedVectorCallClass_vectorcall(PyObject *callable, + PyObject *const *args, + size_t nargsf, + PyObject *kwnames) { + return PyUnicode_FromString("vectorcall called"); +} + +static PyObject * +LimitedVectorCallClass_new(PyTypeObject *tp, PyTypeObject *a, PyTypeObject *kw) +{ + PyObject *self = ((allocfunc)PyType_GetSlot(tp, Py_tp_alloc))(tp, 0); + if (!self) { + return NULL; + } + *(vectorcallfunc*)((char*)self + sizeof(PyObject)) = ( + LimitedVectorCallClass_vectorcall); + return self; +} + +static PyObject * +call_vectorcall(PyObject* self, PyObject *callable) +{ + PyObject *args[3] = { NULL, NULL, NULL }; + PyObject *kwname = NULL, *kwnames = NULL, *result = NULL; + + args[1] = PyUnicode_FromString("foo"); + if (!args[1]) { + goto leave; + } + + args[2] = PyUnicode_FromString("bar"); + if (!args[2]) { + goto leave; + } + + kwname = PyUnicode_InternFromString("baz"); + if (!kwname) { + goto leave; + } + + kwnames = PyTuple_New(1); + if (!kwnames) { + goto leave; + } + + if (PyTuple_SetItem(kwnames, 0, kwname)) { + goto leave; + } + + result = PyObject_Vectorcall( + callable, + args + 1, + 1 | PY_VECTORCALL_ARGUMENTS_OFFSET, + kwnames + ); + +leave: + Py_XDECREF(args[1]); + Py_XDECREF(args[2]); + Py_XDECREF(kwnames); + + return result; +} + +static PyObject * +call_vectorcall_method(PyObject* self, PyObject *callable) +{ + PyObject *args[3] = { NULL, NULL, NULL }; + PyObject *name = NULL, *kwname = NULL, + *kwnames = NULL, *result = NULL; + + name = PyUnicode_FromString("f"); + if (!name) { + goto leave; + } + + args[0] = callable; + args[1] = PyUnicode_FromString("foo"); + if (!args[1]) { + goto leave; + } + + args[2] = PyUnicode_FromString("bar"); + if (!args[2]) { + goto leave; + } + + kwname = PyUnicode_InternFromString("baz"); + if (!kwname) { + goto leave; + } + + kwnames = PyTuple_New(1); + if (!kwnames) { + goto leave; + } + + if (PyTuple_SetItem(kwnames, 0, kwname)) { + goto leave; + } + + + result = PyObject_VectorcallMethod( + name, + args, + 2 | PY_VECTORCALL_ARGUMENTS_OFFSET, + kwnames + ); + +leave: + Py_XDECREF(name); + Py_XDECREF(args[1]); + Py_XDECREF(args[2]); + Py_XDECREF(kwnames); + + return result; +} + +static PyMemberDef LimitedVectorCallClass_members[] = { + {"__vectorcalloffset__", T_PYSSIZET, sizeof(PyObject), READONLY}, + {NULL} +}; + +static PyType_Slot LimitedVectorallClass_slots[] = { + {Py_tp_new, LimitedVectorCallClass_new}, + {Py_tp_call, LimitedVectorCallClass_tpcall}, + {Py_tp_members, LimitedVectorCallClass_members}, + {0}, +}; + +static PyType_Spec LimitedVectorCallClass_spec = { + .name = "_testcapi.LimitedVectorCallClass", + .basicsize = (int)(sizeof(PyObject) + sizeof(vectorcallfunc)), + .flags = Py_TPFLAGS_DEFAULT + | Py_TPFLAGS_HAVE_VECTORCALL + | Py_TPFLAGS_BASETYPE, + .slots = LimitedVectorallClass_slots, +}; + +static PyMethodDef TestMethods[] = { + {"call_vectorcall", call_vectorcall, METH_O}, + {"call_vectorcall_method", call_vectorcall_method, METH_O}, + {NULL}, +}; + +int +_PyTestCapi_Init_VectorcallLimited(PyObject *m) { + if (PyModule_AddFunctions(m, TestMethods) < 0) { + return -1; + } + + PyObject *LimitedVectorCallClass = PyType_FromModuleAndSpec( + m, &LimitedVectorCallClass_spec, NULL); + if (!LimitedVectorCallClass) { + return -1; + } + if (PyModule_AddType(m, (PyTypeObject *)LimitedVectorCallClass) < 0) { + return -1; + } + + return 0; +} + +#endif // LIMITED_API_AVAILABLE diff --git a/Modules/_testcapi/watchers.c b/Modules/_testcapi/watchers.c new file mode 100644 index 00000000..fd695df7 --- /dev/null +++ b/Modules/_testcapi/watchers.c @@ -0,0 +1,715 @@ +#include "parts.h" + +#include "clinic/watchers.c.h" + +#define Py_BUILD_CORE +#include "pycore_function.h" // FUNC_MAX_WATCHERS +#include "pycore_code.h" // CODE_MAX_WATCHERS + +/*[clinic input] +module _testcapi +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=6361033e795369fc]*/ + +// Test dict watching +static PyObject *g_dict_watch_events; +static int g_dict_watchers_installed; + +static int +dict_watch_callback(PyDict_WatchEvent event, + PyObject *dict, + PyObject *key, + PyObject *new_value) +{ + PyObject *msg; + switch (event) { + case PyDict_EVENT_CLEARED: + msg = PyUnicode_FromString("clear"); + break; + case PyDict_EVENT_DEALLOCATED: + msg = PyUnicode_FromString("dealloc"); + break; + case PyDict_EVENT_CLONED: + msg = PyUnicode_FromString("clone"); + break; + case PyDict_EVENT_ADDED: + msg = PyUnicode_FromFormat("new:%S:%S", key, new_value); + break; + case PyDict_EVENT_MODIFIED: + msg = PyUnicode_FromFormat("mod:%S:%S", key, new_value); + break; + case PyDict_EVENT_DELETED: + msg = PyUnicode_FromFormat("del:%S", key); + break; + default: + msg = PyUnicode_FromString("unknown"); + } + if (msg == NULL) { + return -1; + } + assert(PyList_Check(g_dict_watch_events)); + if (PyList_Append(g_dict_watch_events, msg) < 0) { + Py_DECREF(msg); + return -1; + } + Py_DECREF(msg); + return 0; +} + +static int +dict_watch_callback_second(PyDict_WatchEvent event, + PyObject *dict, + PyObject *key, + PyObject *new_value) +{ + PyObject *msg = PyUnicode_FromString("second"); + if (msg == NULL) { + return -1; + } + int rc = PyList_Append(g_dict_watch_events, msg); + Py_DECREF(msg); + if (rc < 0) { + return -1; + } + return 0; +} + +static int +dict_watch_callback_error(PyDict_WatchEvent event, + PyObject *dict, + PyObject *key, + PyObject *new_value) +{ + PyErr_SetString(PyExc_RuntimeError, "boom!"); + return -1; +} + +static PyObject * +add_dict_watcher(PyObject *self, PyObject *kind) +{ + int watcher_id; + assert(PyLong_Check(kind)); + long kind_l = PyLong_AsLong(kind); + if (kind_l == 2) { + watcher_id = PyDict_AddWatcher(dict_watch_callback_second); + } + else if (kind_l == 1) { + watcher_id = PyDict_AddWatcher(dict_watch_callback_error); + } + else { + watcher_id = PyDict_AddWatcher(dict_watch_callback); + } + if (watcher_id < 0) { + return NULL; + } + if (!g_dict_watchers_installed) { + assert(!g_dict_watch_events); + if (!(g_dict_watch_events = PyList_New(0))) { + return NULL; + } + } + g_dict_watchers_installed++; + return PyLong_FromLong(watcher_id); +} + +static PyObject * +clear_dict_watcher(PyObject *self, PyObject *watcher_id) +{ + if (PyDict_ClearWatcher(PyLong_AsLong(watcher_id))) { + return NULL; + } + g_dict_watchers_installed--; + if (!g_dict_watchers_installed) { + assert(g_dict_watch_events); + Py_CLEAR(g_dict_watch_events); + } + Py_RETURN_NONE; +} + +/*[clinic input] +_testcapi.watch_dict + watcher_id: int + dict: object + / +[clinic start generated code]*/ + +static PyObject * +_testcapi_watch_dict_impl(PyObject *module, int watcher_id, PyObject *dict) +/*[clinic end generated code: output=1426e0273cebe2d8 input=269b006d60c358bd]*/ +{ + if (PyDict_Watch(watcher_id, dict)) { + return NULL; + } + Py_RETURN_NONE; +} + +/*[clinic input] +_testcapi.unwatch_dict = _testcapi.watch_dict +[clinic start generated code]*/ + +static PyObject * +_testcapi_unwatch_dict_impl(PyObject *module, int watcher_id, PyObject *dict) +/*[clinic end generated code: output=512b1a71ae33c351 input=cae7dc1b6f7713b8]*/ +{ + if (PyDict_Unwatch(watcher_id, dict)) { + return NULL; + } + Py_RETURN_NONE; +} + +static PyObject * +get_dict_watcher_events(PyObject *self, PyObject *Py_UNUSED(args)) +{ + if (!g_dict_watch_events) { + PyErr_SetString(PyExc_RuntimeError, "no watchers active"); + return NULL; + } + return Py_NewRef(g_dict_watch_events); +} + +// Test type watchers +static PyObject *g_type_modified_events; +static int g_type_watchers_installed; + +static int +type_modified_callback(PyTypeObject *type) +{ + assert(PyList_Check(g_type_modified_events)); + if(PyList_Append(g_type_modified_events, (PyObject *)type) < 0) { + return -1; + } + return 0; +} + +static int +type_modified_callback_wrap(PyTypeObject *type) +{ + assert(PyList_Check(g_type_modified_events)); + PyObject *list = PyList_New(0); + if (list == NULL) { + return -1; + } + if (PyList_Append(list, (PyObject *)type) < 0) { + Py_DECREF(list); + return -1; + } + if (PyList_Append(g_type_modified_events, list) < 0) { + Py_DECREF(list); + return -1; + } + Py_DECREF(list); + return 0; +} + +static int +type_modified_callback_error(PyTypeObject *type) +{ + PyErr_SetString(PyExc_RuntimeError, "boom!"); + return -1; +} + +static PyObject * +add_type_watcher(PyObject *self, PyObject *kind) +{ + int watcher_id; + assert(PyLong_Check(kind)); + long kind_l = PyLong_AsLong(kind); + if (kind_l == 2) { + watcher_id = PyType_AddWatcher(type_modified_callback_wrap); + } + else if (kind_l == 1) { + watcher_id = PyType_AddWatcher(type_modified_callback_error); + } + else { + watcher_id = PyType_AddWatcher(type_modified_callback); + } + if (watcher_id < 0) { + return NULL; + } + if (!g_type_watchers_installed) { + assert(!g_type_modified_events); + if (!(g_type_modified_events = PyList_New(0))) { + return NULL; + } + } + g_type_watchers_installed++; + return PyLong_FromLong(watcher_id); +} + +static PyObject * +clear_type_watcher(PyObject *self, PyObject *watcher_id) +{ + if (PyType_ClearWatcher(PyLong_AsLong(watcher_id))) { + return NULL; + } + g_type_watchers_installed--; + if (!g_type_watchers_installed) { + assert(g_type_modified_events); + Py_CLEAR(g_type_modified_events); + } + Py_RETURN_NONE; +} + +static PyObject * +get_type_modified_events(PyObject *self, PyObject *Py_UNUSED(args)) +{ + if (!g_type_modified_events) { + PyErr_SetString(PyExc_RuntimeError, "no watchers active"); + return NULL; + } + return Py_NewRef(g_type_modified_events); +} + +/*[clinic input] +_testcapi.watch_type + watcher_id: int + type: object + / +[clinic start generated code]*/ + +static PyObject * +_testcapi_watch_type_impl(PyObject *module, int watcher_id, PyObject *type) +/*[clinic end generated code: output=fdf4777126724fc4 input=5a808bf12be7e3ed]*/ +{ + if (PyType_Watch(watcher_id, type)) { + return NULL; + } + Py_RETURN_NONE; +} + +/*[clinic input] +_testcapi.unwatch_type = _testcapi.watch_type +[clinic start generated code]*/ + +static PyObject * +_testcapi_unwatch_type_impl(PyObject *module, int watcher_id, PyObject *type) +/*[clinic end generated code: output=0389672d4ad5f68b input=6701911fb45edc9e]*/ +{ + if (PyType_Unwatch(watcher_id, type)) { + return NULL; + } + Py_RETURN_NONE; +} + + +// Test code object watching + +#define NUM_CODE_WATCHERS 2 +static int code_watcher_ids[NUM_CODE_WATCHERS] = {-1, -1}; +static int num_code_object_created_events[NUM_CODE_WATCHERS] = {0, 0}; +static int num_code_object_destroyed_events[NUM_CODE_WATCHERS] = {0, 0}; + +static int +handle_code_object_event(int which_watcher, PyCodeEvent event, PyCodeObject *co) { + if (event == PY_CODE_EVENT_CREATE) { + num_code_object_created_events[which_watcher]++; + } + else if (event == PY_CODE_EVENT_DESTROY) { + num_code_object_destroyed_events[which_watcher]++; + } + else { + return -1; + } + return 0; +} + +static int +first_code_object_callback(PyCodeEvent event, PyCodeObject *co) +{ + return handle_code_object_event(0, event, co); +} + +static int +second_code_object_callback(PyCodeEvent event, PyCodeObject *co) +{ + return handle_code_object_event(1, event, co); +} + +static int +noop_code_event_handler(PyCodeEvent event, PyCodeObject *co) +{ + return 0; +} + +static int +error_code_event_handler(PyCodeEvent event, PyCodeObject *co) +{ + PyErr_SetString(PyExc_RuntimeError, "boom!"); + return -1; +} + +static PyObject * +add_code_watcher(PyObject *self, PyObject *which_watcher) +{ + int watcher_id; + assert(PyLong_Check(which_watcher)); + long which_l = PyLong_AsLong(which_watcher); + if (which_l == 0) { + watcher_id = PyCode_AddWatcher(first_code_object_callback); + code_watcher_ids[0] = watcher_id; + num_code_object_created_events[0] = 0; + num_code_object_destroyed_events[0] = 0; + } + else if (which_l == 1) { + watcher_id = PyCode_AddWatcher(second_code_object_callback); + code_watcher_ids[1] = watcher_id; + num_code_object_created_events[1] = 0; + num_code_object_destroyed_events[1] = 0; + } + else if (which_l == 2) { + watcher_id = PyCode_AddWatcher(error_code_event_handler); + } + else { + PyErr_Format(PyExc_ValueError, "invalid watcher %d", which_l); + return NULL; + } + if (watcher_id < 0) { + return NULL; + } + return PyLong_FromLong(watcher_id); +} + +static PyObject * +clear_code_watcher(PyObject *self, PyObject *watcher_id) +{ + assert(PyLong_Check(watcher_id)); + long watcher_id_l = PyLong_AsLong(watcher_id); + if (PyCode_ClearWatcher(watcher_id_l) < 0) { + return NULL; + } + // reset static events counters + if (watcher_id_l >= 0) { + for (int i = 0; i < NUM_CODE_WATCHERS; i++) { + if (watcher_id_l == code_watcher_ids[i]) { + code_watcher_ids[i] = -1; + num_code_object_created_events[i] = 0; + num_code_object_destroyed_events[i] = 0; + } + } + } + Py_RETURN_NONE; +} + +static PyObject * +get_code_watcher_num_created_events(PyObject *self, PyObject *watcher_id) +{ + assert(PyLong_Check(watcher_id)); + long watcher_id_l = PyLong_AsLong(watcher_id); + assert(watcher_id_l >= 0 && watcher_id_l < NUM_CODE_WATCHERS); + return PyLong_FromLong(num_code_object_created_events[watcher_id_l]); +} + +static PyObject * +get_code_watcher_num_destroyed_events(PyObject *self, PyObject *watcher_id) +{ + assert(PyLong_Check(watcher_id)); + long watcher_id_l = PyLong_AsLong(watcher_id); + assert(watcher_id_l >= 0 && watcher_id_l < NUM_CODE_WATCHERS); + return PyLong_FromLong(num_code_object_destroyed_events[watcher_id_l]); +} + +static PyObject * +allocate_too_many_code_watchers(PyObject *self, PyObject *args) +{ + int watcher_ids[CODE_MAX_WATCHERS + 1]; + int num_watchers = 0; + for (unsigned long i = 0; i < sizeof(watcher_ids) / sizeof(int); i++) { + int watcher_id = PyCode_AddWatcher(noop_code_event_handler); + if (watcher_id == -1) { + break; + } + watcher_ids[i] = watcher_id; + num_watchers++; + } + PyObject *exc = PyErr_GetRaisedException(); + for (int i = 0; i < num_watchers; i++) { + if (PyCode_ClearWatcher(watcher_ids[i]) < 0) { + PyErr_WriteUnraisable(Py_None); + break; + } + } + if (exc) { + PyErr_SetRaisedException(exc); + return NULL; + } + else if (PyErr_Occurred()) { + return NULL; + } + Py_RETURN_NONE; +} + +// Test function watchers + +#define NUM_TEST_FUNC_WATCHERS 2 +static PyObject *pyfunc_watchers[NUM_TEST_FUNC_WATCHERS]; +static int func_watcher_ids[NUM_TEST_FUNC_WATCHERS] = {-1, -1}; + +static PyObject * +get_id(PyObject *obj) +{ + PyObject *builtins = PyEval_GetBuiltins(); // borrowed ref. + if (builtins == NULL) { + return NULL; + } + PyObject *id_str = PyUnicode_FromString("id"); + if (id_str == NULL) { + return NULL; + } + PyObject *id_func = PyObject_GetItem(builtins, id_str); + Py_DECREF(id_str); + if (id_func == NULL) { + return NULL; + } + PyObject *stack[] = {obj}; + PyObject *id = PyObject_Vectorcall(id_func, stack, 1, NULL); + Py_DECREF(id_func); + return id; +} + +static int +call_pyfunc_watcher(PyObject *watcher, PyFunction_WatchEvent event, + PyFunctionObject *func, PyObject *new_value) +{ + PyObject *event_obj = PyLong_FromLong(event); + if (event_obj == NULL) { + return -1; + } + if (new_value == NULL) { + new_value = Py_None; + } + Py_INCREF(new_value); + PyObject *func_or_id = NULL; + if (event == PyFunction_EVENT_DESTROY) { + /* Don't expose a function that's about to be destroyed to managed code */ + func_or_id = get_id((PyObject *) func); + if (func_or_id == NULL) { + Py_DECREF(event_obj); + Py_DECREF(new_value); + return -1; + } + } + else { + Py_INCREF(func); + func_or_id = (PyObject *) func; + } + PyObject *stack[] = {event_obj, func_or_id, new_value}; + PyObject *res = PyObject_Vectorcall(watcher, stack, 3, NULL); + int st = (res == NULL) ? -1 : 0; + Py_XDECREF(res); + Py_DECREF(new_value); + Py_DECREF(event_obj); + Py_DECREF(func_or_id); + return st; +} + +static int +first_func_watcher_callback(PyFunction_WatchEvent event, PyFunctionObject *func, + PyObject *new_value) +{ + return call_pyfunc_watcher(pyfunc_watchers[0], event, func, new_value); +} + +static int +second_func_watcher_callback(PyFunction_WatchEvent event, + PyFunctionObject *func, PyObject *new_value) +{ + return call_pyfunc_watcher(pyfunc_watchers[1], event, func, new_value); +} + +static PyFunction_WatchCallback func_watcher_callbacks[NUM_TEST_FUNC_WATCHERS] = { + first_func_watcher_callback, + second_func_watcher_callback +}; + +static int +add_func_event(PyObject *module, const char *name, PyFunction_WatchEvent event) +{ + PyObject *value = PyLong_FromLong(event); + if (value == NULL) { + return -1; + } + int ok = PyModule_AddObjectRef(module, name, value); + Py_DECREF(value); + return ok; +} + +static PyObject * +add_func_watcher(PyObject *self, PyObject *func) +{ + if (!PyFunction_Check(func)) { + PyErr_SetString(PyExc_TypeError, "'func' must be a function"); + return NULL; + } + int idx = -1; + for (int i = 0; i < NUM_TEST_FUNC_WATCHERS; i++) { + if (func_watcher_ids[i] == -1) { + idx = i; + break; + } + } + if (idx == -1) { + PyErr_SetString(PyExc_RuntimeError, "no free test watchers"); + return NULL; + } + func_watcher_ids[idx] = PyFunction_AddWatcher(func_watcher_callbacks[idx]); + if (func_watcher_ids[idx] < 0) { + return NULL; + } + pyfunc_watchers[idx] = Py_NewRef(func); + PyObject *result = PyLong_FromLong(func_watcher_ids[idx]); + if (result == NULL) { + return NULL; + } + return result; +} + +static PyObject * +clear_func_watcher(PyObject *self, PyObject *watcher_id_obj) +{ + long watcher_id = PyLong_AsLong(watcher_id_obj); + if ((watcher_id < INT_MIN) || (watcher_id > INT_MAX)) { + PyErr_SetString(PyExc_ValueError, "invalid watcher ID"); + return NULL; + } + int wid = (int) watcher_id; + if (PyFunction_ClearWatcher(wid) < 0) { + return NULL; + } + int idx = -1; + for (int i = 0; i < NUM_TEST_FUNC_WATCHERS; i++) { + if (func_watcher_ids[i] == wid) { + idx = i; + break; + } + } + assert(idx != -1); + Py_CLEAR(pyfunc_watchers[idx]); + func_watcher_ids[idx] = -1; + Py_RETURN_NONE; +} + +static int +noop_func_event_handler(PyFunction_WatchEvent event, PyFunctionObject *func, + PyObject *new_value) +{ + return 0; +} + +static PyObject * +allocate_too_many_func_watchers(PyObject *self, PyObject *args) +{ + int watcher_ids[FUNC_MAX_WATCHERS + 1]; + int num_watchers = 0; + for (unsigned long i = 0; i < sizeof(watcher_ids) / sizeof(int); i++) { + int watcher_id = PyFunction_AddWatcher(noop_func_event_handler); + if (watcher_id == -1) { + break; + } + watcher_ids[i] = watcher_id; + num_watchers++; + } + PyObject *exc = PyErr_GetRaisedException(); + for (int i = 0; i < num_watchers; i++) { + if (PyFunction_ClearWatcher(watcher_ids[i]) < 0) { + PyErr_WriteUnraisable(Py_None); + break; + } + } + if (exc) { + PyErr_SetRaisedException(exc); + return NULL; + } + else if (PyErr_Occurred()) { + return NULL; + } + Py_RETURN_NONE; +} + +/*[clinic input] +_testcapi.set_func_defaults_via_capi + func: object + defaults: object + / +[clinic start generated code]*/ + +static PyObject * +_testcapi_set_func_defaults_via_capi_impl(PyObject *module, PyObject *func, + PyObject *defaults) +/*[clinic end generated code: output=caf0cb39db31ac24 input=e04a8508ca9d42fc]*/ +{ + if (PyFunction_SetDefaults(func, defaults) < 0) { + return NULL; + } + Py_RETURN_NONE; +} + +/*[clinic input] +_testcapi.set_func_kwdefaults_via_capi = _testcapi.set_func_defaults_via_capi +[clinic start generated code]*/ + +static PyObject * +_testcapi_set_func_kwdefaults_via_capi_impl(PyObject *module, PyObject *func, + PyObject *defaults) +/*[clinic end generated code: output=9ed3b08177025070 input=f3cd1ca3c18de8ce]*/ +{ + if (PyFunction_SetKwDefaults(func, defaults) < 0) { + return NULL; + } + Py_RETURN_NONE; +} + +static PyMethodDef test_methods[] = { + // Dict watchers. + {"add_dict_watcher", add_dict_watcher, METH_O, NULL}, + {"clear_dict_watcher", clear_dict_watcher, METH_O, NULL}, + _TESTCAPI_WATCH_DICT_METHODDEF + _TESTCAPI_UNWATCH_DICT_METHODDEF + {"get_dict_watcher_events", + (PyCFunction) get_dict_watcher_events, METH_NOARGS, NULL}, + + // Type watchers. + {"add_type_watcher", add_type_watcher, METH_O, NULL}, + {"clear_type_watcher", clear_type_watcher, METH_O, NULL}, + _TESTCAPI_WATCH_TYPE_METHODDEF + _TESTCAPI_UNWATCH_TYPE_METHODDEF + {"get_type_modified_events", + (PyCFunction) get_type_modified_events, METH_NOARGS, NULL}, + + // Code object watchers. + {"add_code_watcher", add_code_watcher, METH_O, NULL}, + {"clear_code_watcher", clear_code_watcher, METH_O, NULL}, + {"get_code_watcher_num_created_events", + get_code_watcher_num_created_events, METH_O, NULL}, + {"get_code_watcher_num_destroyed_events", + get_code_watcher_num_destroyed_events, METH_O, NULL}, + {"allocate_too_many_code_watchers", + (PyCFunction) allocate_too_many_code_watchers, METH_NOARGS, NULL}, + + // Function watchers. + {"add_func_watcher", add_func_watcher, METH_O, NULL}, + {"clear_func_watcher", clear_func_watcher, METH_O, NULL}, + _TESTCAPI_SET_FUNC_DEFAULTS_VIA_CAPI_METHODDEF + _TESTCAPI_SET_FUNC_KWDEFAULTS_VIA_CAPI_METHODDEF + {"allocate_too_many_func_watchers", allocate_too_many_func_watchers, + METH_NOARGS, NULL}, + {NULL}, +}; + +int +_PyTestCapi_Init_Watchers(PyObject *mod) +{ + if (PyModule_AddFunctions(mod, test_methods) < 0) { + return -1; + } + + /* Expose each event as an attribute on the module */ +#define ADD_EVENT(event) \ + if (add_func_event(mod, "PYFUNC_EVENT_" #event, \ + PyFunction_EVENT_##event)) { \ + return -1; \ + } + PY_FOREACH_FUNC_EVENT(ADD_EVENT); +#undef ADD_EVENT + + return 0; +} diff --git a/Modules/_testcapi_feature_macros.inc b/Modules/_testcapi_feature_macros.inc index b1763b57..a076e714 100644 --- a/Modules/_testcapi_feature_macros.inc +++ b/Modules/_testcapi_feature_macros.inc @@ -1,4 +1,4 @@ -// Generated by Tools/scripts/stable_abi.py +// Generated by Tools/build/stable_abi.py // Add an entry in dict `result` for each Stable ABI feature macro. diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index daf2df4f..c73b297a 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -13,7 +13,6 @@ #undef Py_BUILD_CORE_MODULE #undef Py_BUILD_CORE_BUILTIN -#define NEEDS_PY_IDENTIFIER /* Always enable assertions */ #undef NDEBUG @@ -21,15 +20,13 @@ #define PY_SSIZE_T_CLEAN #include "Python.h" -#include "datetime.h" // PyDateTimeAPI #include "frameobject.h" // PyFrame_New #include "marshal.h" // PyMarshal_WriteLongToFile -#include "structmember.h" // PyMemberDef +#include "structmember.h" // for offsetof(), T_OBJECT #include <float.h> // FLT_MAX #include <signal.h> - -#ifdef MS_WINDOWS -# include <winsock2.h> // struct timeval +#ifndef MS_WINDOWS +#include <unistd.h> #endif #ifdef HAVE_SYS_WAIT_H @@ -44,9 +41,14 @@ # error "The public headers should not include <stdbool.h>, see bpo-46748" #endif +// Several parts of this module are broken out into files in _testcapi/. +// Include definitions from there. +#include "_testcapi/parts.h" +#include "_testcapi/util.h" + + // Forward declarations static struct PyModuleDef _testcapimodule; -static PyType_Spec HeapTypeNameType_Spec; static PyObject *TestError; /* set to exception object in init */ @@ -154,68 +156,6 @@ test_sizeof_c_types(PyObject *self, PyObject *Py_UNUSED(ignored)) #endif } -static PyObject* -test_gc_control(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - int orig_enabled = PyGC_IsEnabled(); - const char* msg = "ok"; - int old_state; - - old_state = PyGC_Enable(); - msg = "Enable(1)"; - if (old_state != orig_enabled) { - goto failed; - } - msg = "IsEnabled(1)"; - if (!PyGC_IsEnabled()) { - goto failed; - } - - old_state = PyGC_Disable(); - msg = "disable(2)"; - if (!old_state) { - goto failed; - } - msg = "IsEnabled(2)"; - if (PyGC_IsEnabled()) { - goto failed; - } - - old_state = PyGC_Enable(); - msg = "enable(3)"; - if (old_state) { - goto failed; - } - msg = "IsEnabled(3)"; - if (!PyGC_IsEnabled()) { - goto failed; - } - - if (!orig_enabled) { - old_state = PyGC_Disable(); - msg = "disable(4)"; - if (old_state) { - goto failed; - } - msg = "IsEnabled(4)"; - if (PyGC_IsEnabled()) { - goto failed; - } - } - - Py_RETURN_NONE; - -failed: - /* Try to clean up if we can. */ - if (orig_enabled) { - PyGC_Enable(); - } else { - PyGC_Disable(); - } - PyErr_Format(TestError, "GC control failed in %s", msg); - return NULL; -} - static PyObject* test_list_api(PyObject *self, PyObject *Py_UNUSED(ignored)) { @@ -281,10 +221,13 @@ test_dict_inner(int count) Py_DECREF(v); } + k = v = UNINITIALIZED_PTR; while (PyDict_Next(dict, &pos, &k, &v)) { PyObject *o; iterations++; + assert(k != UNINITIALIZED_PTR); + assert(v != UNINITIALIZED_PTR); i = PyLong_AS_LONG(v) + 1; o = PyLong_FromLong(i); if (o == NULL) @@ -294,7 +237,10 @@ test_dict_inner(int count) return -1; } Py_DECREF(o); + k = v = UNINITIALIZED_PTR; } + assert(k == UNINITIALIZED_PTR); + assert(v == UNINITIALIZED_PTR); Py_DECREF(dict); @@ -308,6 +254,8 @@ test_dict_inner(int count) } } + + static PyObject* test_dict_iteration(PyObject* self, PyObject *Py_UNUSED(ignored)) { @@ -339,8 +287,7 @@ dict_getitem_knownhash(PyObject *self, PyObject *args) return NULL; } - Py_XINCREF(result); - return result; + return Py_XNewRef(result); } /* Issue #4701: Check that PyObject_Hash implicitly calls @@ -463,537 +410,6 @@ test_lazy_hash_inheritance(PyObject* self, PyObject *Py_UNUSED(ignored)) Py_RETURN_NONE; } - -/* Tests of PyLong_{As, From}{Unsigned,}Long(), and - PyLong_{As, From}{Unsigned,}LongLong(). - - Note that the meat of the test is contained in testcapi_long.h. - This is revolting, but delicate code duplication is worse: "almost - exactly the same" code is needed to test long long, but the ubiquitous - dependence on type names makes it impossible to use a parameterized - function. A giant macro would be even worse than this. A C++ template - would be perfect. - - The "report an error" functions are deliberately not part of the #include - file: if the test fails, you can set a breakpoint in the appropriate - error function directly, and crawl back from there in the debugger. -*/ - -#define UNBIND(X) Py_DECREF(X); (X) = NULL - -static PyObject * -raise_test_long_error(const char* msg) -{ - return raiseTestError("test_long_api", msg); -} - -#define TESTNAME test_long_api_inner -#define TYPENAME long -#define F_S_TO_PY PyLong_FromLong -#define F_PY_TO_S PyLong_AsLong -#define F_U_TO_PY PyLong_FromUnsignedLong -#define F_PY_TO_U PyLong_AsUnsignedLong - -#include "testcapi_long.h" - -static PyObject * -test_long_api(PyObject* self, PyObject *Py_UNUSED(ignored)) -{ - return TESTNAME(raise_test_long_error); -} - -#undef TESTNAME -#undef TYPENAME -#undef F_S_TO_PY -#undef F_PY_TO_S -#undef F_U_TO_PY -#undef F_PY_TO_U - -static PyObject * -raise_test_longlong_error(const char* msg) -{ - return raiseTestError("test_longlong_api", msg); -} - -#define TESTNAME test_longlong_api_inner -#define TYPENAME long long -#define F_S_TO_PY PyLong_FromLongLong -#define F_PY_TO_S PyLong_AsLongLong -#define F_U_TO_PY PyLong_FromUnsignedLongLong -#define F_PY_TO_U PyLong_AsUnsignedLongLong - -#include "testcapi_long.h" - -static PyObject * -test_longlong_api(PyObject* self, PyObject *args) -{ - return TESTNAME(raise_test_longlong_error); -} - -#undef TESTNAME -#undef TYPENAME -#undef F_S_TO_PY -#undef F_PY_TO_S -#undef F_U_TO_PY -#undef F_PY_TO_U - -/* Test the PyLong_AsLongAndOverflow API. General conversion to PY_LONG - is tested by test_long_api_inner. This test will concentrate on proper - handling of overflow. -*/ - -static PyObject * -test_long_and_overflow(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - PyObject *num, *one, *temp; - long value; - int overflow; - - /* Test that overflow is set properly for a large value. */ - /* num is a number larger than LONG_MAX even on 64-bit platforms */ - num = PyLong_FromString("FFFFFFFFFFFFFFFFFFFFFFFF", NULL, 16); - if (num == NULL) - return NULL; - overflow = 1234; - value = PyLong_AsLongAndOverflow(num, &overflow); - Py_DECREF(num); - if (value == -1 && PyErr_Occurred()) - return NULL; - if (value != -1) - return raiseTestError("test_long_and_overflow", - "return value was not set to -1"); - if (overflow != 1) - return raiseTestError("test_long_and_overflow", - "overflow was not set to 1"); - - /* Same again, with num = LONG_MAX + 1 */ - num = PyLong_FromLong(LONG_MAX); - if (num == NULL) - return NULL; - one = PyLong_FromLong(1L); - if (one == NULL) { - Py_DECREF(num); - return NULL; - } - temp = PyNumber_Add(num, one); - Py_DECREF(one); - Py_DECREF(num); - num = temp; - if (num == NULL) - return NULL; - overflow = 0; - value = PyLong_AsLongAndOverflow(num, &overflow); - Py_DECREF(num); - if (value == -1 && PyErr_Occurred()) - return NULL; - if (value != -1) - return raiseTestError("test_long_and_overflow", - "return value was not set to -1"); - if (overflow != 1) - return raiseTestError("test_long_and_overflow", - "overflow was not set to 1"); - - /* Test that overflow is set properly for a large negative value. */ - /* num is a number smaller than LONG_MIN even on 64-bit platforms */ - num = PyLong_FromString("-FFFFFFFFFFFFFFFFFFFFFFFF", NULL, 16); - if (num == NULL) - return NULL; - overflow = 1234; - value = PyLong_AsLongAndOverflow(num, &overflow); - Py_DECREF(num); - if (value == -1 && PyErr_Occurred()) - return NULL; - if (value != -1) - return raiseTestError("test_long_and_overflow", - "return value was not set to -1"); - if (overflow != -1) - return raiseTestError("test_long_and_overflow", - "overflow was not set to -1"); - - /* Same again, with num = LONG_MIN - 1 */ - num = PyLong_FromLong(LONG_MIN); - if (num == NULL) - return NULL; - one = PyLong_FromLong(1L); - if (one == NULL) { - Py_DECREF(num); - return NULL; - } - temp = PyNumber_Subtract(num, one); - Py_DECREF(one); - Py_DECREF(num); - num = temp; - if (num == NULL) - return NULL; - overflow = 0; - value = PyLong_AsLongAndOverflow(num, &overflow); - Py_DECREF(num); - if (value == -1 && PyErr_Occurred()) - return NULL; - if (value != -1) - return raiseTestError("test_long_and_overflow", - "return value was not set to -1"); - if (overflow != -1) - return raiseTestError("test_long_and_overflow", - "overflow was not set to -1"); - - /* Test that overflow is cleared properly for small values. */ - num = PyLong_FromString("FF", NULL, 16); - if (num == NULL) - return NULL; - overflow = 1234; - value = PyLong_AsLongAndOverflow(num, &overflow); - Py_DECREF(num); - if (value == -1 && PyErr_Occurred()) - return NULL; - if (value != 0xFF) - return raiseTestError("test_long_and_overflow", - "expected return value 0xFF"); - if (overflow != 0) - return raiseTestError("test_long_and_overflow", - "overflow was not cleared"); - - num = PyLong_FromString("-FF", NULL, 16); - if (num == NULL) - return NULL; - overflow = 0; - value = PyLong_AsLongAndOverflow(num, &overflow); - Py_DECREF(num); - if (value == -1 && PyErr_Occurred()) - return NULL; - if (value != -0xFF) - return raiseTestError("test_long_and_overflow", - "expected return value 0xFF"); - if (overflow != 0) - return raiseTestError("test_long_and_overflow", - "overflow was set incorrectly"); - - num = PyLong_FromLong(LONG_MAX); - if (num == NULL) - return NULL; - overflow = 1234; - value = PyLong_AsLongAndOverflow(num, &overflow); - Py_DECREF(num); - if (value == -1 && PyErr_Occurred()) - return NULL; - if (value != LONG_MAX) - return raiseTestError("test_long_and_overflow", - "expected return value LONG_MAX"); - if (overflow != 0) - return raiseTestError("test_long_and_overflow", - "overflow was not cleared"); - - num = PyLong_FromLong(LONG_MIN); - if (num == NULL) - return NULL; - overflow = 0; - value = PyLong_AsLongAndOverflow(num, &overflow); - Py_DECREF(num); - if (value == -1 && PyErr_Occurred()) - return NULL; - if (value != LONG_MIN) - return raiseTestError("test_long_and_overflow", - "expected return value LONG_MIN"); - if (overflow != 0) - return raiseTestError("test_long_and_overflow", - "overflow was not cleared"); - - Py_RETURN_NONE; -} - -/* Test the PyLong_AsLongLongAndOverflow API. General conversion to - long long is tested by test_long_api_inner. This test will - concentrate on proper handling of overflow. -*/ - -static PyObject * -test_long_long_and_overflow(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - PyObject *num, *one, *temp; - long long value; - int overflow; - - /* Test that overflow is set properly for a large value. */ - /* num is a number larger than LLONG_MAX on a typical machine. */ - num = PyLong_FromString("FFFFFFFFFFFFFFFFFFFFFFFF", NULL, 16); - if (num == NULL) - return NULL; - overflow = 1234; - value = PyLong_AsLongLongAndOverflow(num, &overflow); - Py_DECREF(num); - if (value == -1 && PyErr_Occurred()) - return NULL; - if (value != -1) - return raiseTestError("test_long_long_and_overflow", - "return value was not set to -1"); - if (overflow != 1) - return raiseTestError("test_long_long_and_overflow", - "overflow was not set to 1"); - - /* Same again, with num = LLONG_MAX + 1 */ - num = PyLong_FromLongLong(LLONG_MAX); - if (num == NULL) - return NULL; - one = PyLong_FromLong(1L); - if (one == NULL) { - Py_DECREF(num); - return NULL; - } - temp = PyNumber_Add(num, one); - Py_DECREF(one); - Py_DECREF(num); - num = temp; - if (num == NULL) - return NULL; - overflow = 0; - value = PyLong_AsLongLongAndOverflow(num, &overflow); - Py_DECREF(num); - if (value == -1 && PyErr_Occurred()) - return NULL; - if (value != -1) - return raiseTestError("test_long_long_and_overflow", - "return value was not set to -1"); - if (overflow != 1) - return raiseTestError("test_long_long_and_overflow", - "overflow was not set to 1"); - - /* Test that overflow is set properly for a large negative value. */ - /* num is a number smaller than LLONG_MIN on a typical platform */ - num = PyLong_FromString("-FFFFFFFFFFFFFFFFFFFFFFFF", NULL, 16); - if (num == NULL) - return NULL; - overflow = 1234; - value = PyLong_AsLongLongAndOverflow(num, &overflow); - Py_DECREF(num); - if (value == -1 && PyErr_Occurred()) - return NULL; - if (value != -1) - return raiseTestError("test_long_long_and_overflow", - "return value was not set to -1"); - if (overflow != -1) - return raiseTestError("test_long_long_and_overflow", - "overflow was not set to -1"); - - /* Same again, with num = LLONG_MIN - 1 */ - num = PyLong_FromLongLong(LLONG_MIN); - if (num == NULL) - return NULL; - one = PyLong_FromLong(1L); - if (one == NULL) { - Py_DECREF(num); - return NULL; - } - temp = PyNumber_Subtract(num, one); - Py_DECREF(one); - Py_DECREF(num); - num = temp; - if (num == NULL) - return NULL; - overflow = 0; - value = PyLong_AsLongLongAndOverflow(num, &overflow); - Py_DECREF(num); - if (value == -1 && PyErr_Occurred()) - return NULL; - if (value != -1) - return raiseTestError("test_long_long_and_overflow", - "return value was not set to -1"); - if (overflow != -1) - return raiseTestError("test_long_long_and_overflow", - "overflow was not set to -1"); - - /* Test that overflow is cleared properly for small values. */ - num = PyLong_FromString("FF", NULL, 16); - if (num == NULL) - return NULL; - overflow = 1234; - value = PyLong_AsLongLongAndOverflow(num, &overflow); - Py_DECREF(num); - if (value == -1 && PyErr_Occurred()) - return NULL; - if (value != 0xFF) - return raiseTestError("test_long_long_and_overflow", - "expected return value 0xFF"); - if (overflow != 0) - return raiseTestError("test_long_long_and_overflow", - "overflow was not cleared"); - - num = PyLong_FromString("-FF", NULL, 16); - if (num == NULL) - return NULL; - overflow = 0; - value = PyLong_AsLongLongAndOverflow(num, &overflow); - Py_DECREF(num); - if (value == -1 && PyErr_Occurred()) - return NULL; - if (value != -0xFF) - return raiseTestError("test_long_long_and_overflow", - "expected return value 0xFF"); - if (overflow != 0) - return raiseTestError("test_long_long_and_overflow", - "overflow was set incorrectly"); - - num = PyLong_FromLongLong(LLONG_MAX); - if (num == NULL) - return NULL; - overflow = 1234; - value = PyLong_AsLongLongAndOverflow(num, &overflow); - Py_DECREF(num); - if (value == -1 && PyErr_Occurred()) - return NULL; - if (value != LLONG_MAX) - return raiseTestError("test_long_long_and_overflow", - "expected return value LLONG_MAX"); - if (overflow != 0) - return raiseTestError("test_long_long_and_overflow", - "overflow was not cleared"); - - num = PyLong_FromLongLong(LLONG_MIN); - if (num == NULL) - return NULL; - overflow = 0; - value = PyLong_AsLongLongAndOverflow(num, &overflow); - Py_DECREF(num); - if (value == -1 && PyErr_Occurred()) - return NULL; - if (value != LLONG_MIN) - return raiseTestError("test_long_long_and_overflow", - "expected return value LLONG_MIN"); - if (overflow != 0) - return raiseTestError("test_long_long_and_overflow", - "overflow was not cleared"); - - Py_RETURN_NONE; -} - -/* Test the PyLong_As{Size,Ssize}_t API. At present this just tests that - non-integer arguments are handled correctly. It should be extended to - test overflow handling. - */ - -static PyObject * -test_long_as_size_t(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - size_t out_u; - Py_ssize_t out_s; - - Py_INCREF(Py_None); - - out_u = PyLong_AsSize_t(Py_None); - if (out_u != (size_t)-1 || !PyErr_Occurred()) - return raiseTestError("test_long_as_size_t", - "PyLong_AsSize_t(None) didn't complain"); - if (!PyErr_ExceptionMatches(PyExc_TypeError)) - return raiseTestError("test_long_as_size_t", - "PyLong_AsSize_t(None) raised " - "something other than TypeError"); - PyErr_Clear(); - - out_s = PyLong_AsSsize_t(Py_None); - if (out_s != (Py_ssize_t)-1 || !PyErr_Occurred()) - return raiseTestError("test_long_as_size_t", - "PyLong_AsSsize_t(None) didn't complain"); - if (!PyErr_ExceptionMatches(PyExc_TypeError)) - return raiseTestError("test_long_as_size_t", - "PyLong_AsSsize_t(None) raised " - "something other than TypeError"); - PyErr_Clear(); - - /* Py_INCREF(Py_None) omitted - we already have a reference to it. */ - return Py_None; -} - -static PyObject * -test_long_as_unsigned_long_long_mask(PyObject *self, - PyObject *Py_UNUSED(ignored)) -{ - unsigned long long res = PyLong_AsUnsignedLongLongMask(NULL); - - if (res != (unsigned long long)-1 || !PyErr_Occurred()) { - return raiseTestError("test_long_as_unsigned_long_long_mask", - "PyLong_AsUnsignedLongLongMask(NULL) didn't " - "complain"); - } - if (!PyErr_ExceptionMatches(PyExc_SystemError)) { - return raiseTestError("test_long_as_unsigned_long_long_mask", - "PyLong_AsUnsignedLongLongMask(NULL) raised " - "something other than SystemError"); - } - PyErr_Clear(); - Py_RETURN_NONE; -} - -/* Test the PyLong_AsDouble API. At present this just tests that - non-integer arguments are handled correctly. - */ - -static PyObject * -test_long_as_double(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - double out; - - Py_INCREF(Py_None); - - out = PyLong_AsDouble(Py_None); - if (out != -1.0 || !PyErr_Occurred()) - return raiseTestError("test_long_as_double", - "PyLong_AsDouble(None) didn't complain"); - if (!PyErr_ExceptionMatches(PyExc_TypeError)) - return raiseTestError("test_long_as_double", - "PyLong_AsDouble(None) raised " - "something other than TypeError"); - PyErr_Clear(); - - /* Py_INCREF(Py_None) omitted - we already have a reference to it. */ - return Py_None; -} - -/* Test the L code for PyArg_ParseTuple. This should deliver a long long - for both long and int arguments. The test may leak a little memory if - it fails. -*/ -static PyObject * -test_L_code(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - PyObject *tuple, *num; - long long value; - - tuple = PyTuple_New(1); - if (tuple == NULL) - return NULL; - - num = PyLong_FromLong(42); - if (num == NULL) - return NULL; - - PyTuple_SET_ITEM(tuple, 0, num); - - value = -1; - if (!PyArg_ParseTuple(tuple, "L:test_L_code", &value)) { - return NULL; - } - if (value != 42) - return raiseTestError("test_L_code", - "L code returned wrong value for long 42"); - - Py_DECREF(num); - num = PyLong_FromLong(42); - if (num == NULL) - return NULL; - - PyTuple_SET_ITEM(tuple, 0, num); - - value = -1; - if (!PyArg_ParseTuple(tuple, "L:test_L_code", &value)) { - return NULL; - } - if (value != 42) - return raiseTestError("test_L_code", - "L code returned wrong value for int 42"); - - Py_DECREF(tuple); - Py_RETURN_NONE; -} - static PyObject * return_none(void *unused) { @@ -1144,6 +560,17 @@ test_get_statictype_slots(PyObject *self, PyObject *Py_UNUSED(ignored)) } +static PyType_Slot HeapTypeNameType_slots[] = { + {0}, +}; + +static PyType_Spec HeapTypeNameType_Spec = { + .name = "_testcapi.HeapTypeNameType", + .basicsize = sizeof(PyObject), + .flags = Py_TPFLAGS_DEFAULT, + .slots = HeapTypeNameType_slots, +}; + static PyObject * test_get_type_name(PyObject *self, PyObject *Py_UNUSED(ignored)) { @@ -1182,126 +609,6 @@ test_get_type_name(PyObject *self, PyObject *Py_UNUSED(ignored)) } -static PyObject * -simple_str(PyObject *self) { - return PyUnicode_FromString("<test>"); -} - - -static PyObject * -test_type_from_ephemeral_spec(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - // Test that a heap type can be created from a spec that's later deleted - // (along with all its contents). - // All necessary data must be copied and held by the class - PyType_Spec *spec = NULL; - char *name = NULL; - char *doc = NULL; - PyType_Slot *slots = NULL; - PyObject *class = NULL; - PyObject *instance = NULL; - PyObject *obj = NULL; - PyObject *result = NULL; - - /* create a spec (and all its contents) on the heap */ - - const char NAME[] = "testcapi._Test"; - const char DOC[] = "a test class"; - - spec = PyMem_New(PyType_Spec, 1); - if (spec == NULL) { - PyErr_NoMemory(); - goto finally; - } - name = PyMem_New(char, sizeof(NAME)); - if (name == NULL) { - PyErr_NoMemory(); - goto finally; - } - memcpy(name, NAME, sizeof(NAME)); - - doc = PyMem_New(char, sizeof(DOC)); - if (doc == NULL) { - PyErr_NoMemory(); - goto finally; - } - memcpy(doc, DOC, sizeof(DOC)); - - spec->name = name; - spec->basicsize = sizeof(PyObject); - spec->itemsize = 0; - spec->flags = Py_TPFLAGS_DEFAULT; - slots = PyMem_New(PyType_Slot, 3); - if (slots == NULL) { - PyErr_NoMemory(); - goto finally; - } - slots[0].slot = Py_tp_str; - slots[0].pfunc = simple_str; - slots[1].slot = Py_tp_doc; - slots[1].pfunc = doc; - slots[2].slot = 0; - slots[2].pfunc = NULL; - spec->slots = slots; - - /* create the class */ - - class = PyType_FromSpec(spec); - if (class == NULL) { - goto finally; - } - - /* deallocate the spec (and all contents) */ - - // (Explicitly ovewrite memory before freeing, - // so bugs show themselves even without the debug allocator's help.) - memset(spec, 0xdd, sizeof(PyType_Spec)); - PyMem_Del(spec); - spec = NULL; - memset(name, 0xdd, sizeof(NAME)); - PyMem_Del(name); - name = NULL; - memset(doc, 0xdd, sizeof(DOC)); - PyMem_Del(doc); - doc = NULL; - memset(slots, 0xdd, 3 * sizeof(PyType_Slot)); - PyMem_Del(slots); - slots = NULL; - - /* check that everything works */ - - PyTypeObject *class_tp = (PyTypeObject *)class; - PyHeapTypeObject *class_ht = (PyHeapTypeObject *)class; - assert(strcmp(class_tp->tp_name, "testcapi._Test") == 0); - assert(strcmp(PyUnicode_AsUTF8(class_ht->ht_name), "_Test") == 0); - assert(strcmp(PyUnicode_AsUTF8(class_ht->ht_qualname), "_Test") == 0); - assert(strcmp(class_tp->tp_doc, "a test class") == 0); - - // call and check __str__ - instance = PyObject_CallNoArgs(class); - if (instance == NULL) { - goto finally; - } - obj = PyObject_Str(instance); - if (obj == NULL) { - goto finally; - } - assert(strcmp(PyUnicode_AsUTF8(obj), "<test>") == 0); - Py_CLEAR(obj); - - result = Py_NewRef(Py_None); - finally: - PyMem_Del(spec); - PyMem_Del(name); - PyMem_Del(doc); - PyMem_Del(slots); - Py_XDECREF(class); - Py_XDECREF(instance); - Py_XDECREF(obj); - return result; -} - - static PyObject * test_get_type_qualname(PyObject *self, PyObject *Py_UNUSED(ignored)) { @@ -1341,6496 +648,3090 @@ test_get_type_qualname(PyObject *self, PyObject *Py_UNUSED(ignored)) Py_RETURN_NONE; } - static PyObject * -get_args(PyObject *self, PyObject *args) +test_get_type_dict(PyObject *self, PyObject *Py_UNUSED(ignored)) { - if (args == NULL) { - args = Py_None; - } - Py_INCREF(args); - return args; -} + /* Test for PyType_GetDict */ -static PyObject * -get_kwargs(PyObject *self, PyObject *args, PyObject *kwargs) -{ - if (kwargs == NULL) { - kwargs = Py_None; - } - Py_INCREF(kwargs); - return kwargs; + // Assert ints have a `to_bytes` method + PyObject *long_dict = PyType_GetDict(&PyLong_Type); + assert(long_dict); + assert(PyDict_GetItemString(long_dict, "to_bytes")); // borrowed ref + Py_DECREF(long_dict); + + // Make a new type, add an attribute to it and assert it's there + PyObject *HeapTypeNameType = PyType_FromSpec(&HeapTypeNameType_Spec); + assert(HeapTypeNameType); + assert(PyObject_SetAttrString( + HeapTypeNameType, "new_attr", Py_NewRef(Py_None)) >= 0); + PyObject *type_dict = PyType_GetDict((PyTypeObject*)HeapTypeNameType); + assert(type_dict); + assert(PyDict_GetItemString(type_dict, "new_attr")); // borrowed ref + Py_DECREF(HeapTypeNameType); + Py_DECREF(type_dict); + Py_RETURN_NONE; } -/* Test tuple argument processing */ static PyObject * -getargs_tuple(PyObject *self, PyObject *args) +pyobject_repr_from_null(PyObject *self, PyObject *Py_UNUSED(ignored)) { - int a, b, c; - if (!PyArg_ParseTuple(args, "i(ii)", &a, &b, &c)) - return NULL; - return Py_BuildValue("iii", a, b, c); + return PyObject_Repr(NULL); } -/* test PyArg_ParseTupleAndKeywords */ static PyObject * -getargs_keywords(PyObject *self, PyObject *args, PyObject *kwargs) +pyobject_str_from_null(PyObject *self, PyObject *Py_UNUSED(ignored)) { - static char *keywords[] = {"arg1","arg2","arg3","arg4","arg5", NULL}; - static const char fmt[] = "(ii)i|(i(ii))(iii)i"; - int int_args[10]={-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, fmt, keywords, - &int_args[0], &int_args[1], &int_args[2], &int_args[3], &int_args[4], - &int_args[5], &int_args[6], &int_args[7], &int_args[8], &int_args[9])) - return NULL; - return Py_BuildValue("iiiiiiiiii", - int_args[0], int_args[1], int_args[2], int_args[3], int_args[4], - int_args[5], int_args[6], int_args[7], int_args[8], int_args[9]); + return PyObject_Str(NULL); } -/* test PyArg_ParseTupleAndKeywords keyword-only arguments */ static PyObject * -getargs_keyword_only(PyObject *self, PyObject *args, PyObject *kwargs) +pyobject_bytes_from_null(PyObject *self, PyObject *Py_UNUSED(ignored)) { - static char *keywords[] = {"required", "optional", "keyword_only", NULL}; - int required = -1; - int optional = -1; - int keyword_only = -1; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|i$i", keywords, - &required, &optional, &keyword_only)) - return NULL; - return Py_BuildValue("iii", required, optional, keyword_only); + return PyObject_Bytes(NULL); } -/* test PyArg_ParseTupleAndKeywords positional-only arguments */ static PyObject * -getargs_positional_only_and_keywords(PyObject *self, PyObject *args, PyObject *kwargs) +set_errno(PyObject *self, PyObject *args) { - static char *keywords[] = {"", "", "keyword", NULL}; - int required = -1; - int optional = -1; - int keyword = -1; + int new_errno; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|ii", keywords, - &required, &optional, &keyword)) + if (!PyArg_ParseTuple(args, "i:set_errno", &new_errno)) return NULL; - return Py_BuildValue("iii", required, optional, keyword); -} -/* Functions to call PyArg_ParseTuple with integer format codes, - and return the result. -*/ -static PyObject * -getargs_b(PyObject *self, PyObject *args) -{ - unsigned char value; - if (!PyArg_ParseTuple(args, "b", &value)) - return NULL; - return PyLong_FromUnsignedLong((unsigned long)value); + errno = new_errno; + Py_RETURN_NONE; } -static PyObject * -getargs_B(PyObject *self, PyObject *args) -{ - unsigned char value; - if (!PyArg_ParseTuple(args, "B", &value)) - return NULL; - return PyLong_FromUnsignedLong((unsigned long)value); -} +/* test_thread_state spawns a thread of its own, and that thread releases + * `thread_done` when it's finished. The driver code has to know when the + * thread finishes, because the thread uses a PyObject (the callable) that + * may go away when the driver finishes. The former lack of this explicit + * synchronization caused rare segfaults, so rare that they were seen only + * on a Mac buildbot (although they were possible on any box). + */ +static PyThread_type_lock thread_done = NULL; -static PyObject * -getargs_h(PyObject *self, PyObject *args) +static int +_make_call(void *callable) { - short value; - if (!PyArg_ParseTuple(args, "h", &value)) - return NULL; - return PyLong_FromLong((long)value); + PyObject *rc; + int success; + PyGILState_STATE s = PyGILState_Ensure(); + rc = PyObject_CallNoArgs((PyObject *)callable); + success = (rc != NULL); + Py_XDECREF(rc); + PyGILState_Release(s); + return success; } -static PyObject * -getargs_H(PyObject *self, PyObject *args) +/* Same thing, but releases `thread_done` when it returns. This variant + * should be called only from threads spawned by test_thread_state(). + */ +static void +_make_call_from_thread(void *callable) { - unsigned short value; - if (!PyArg_ParseTuple(args, "H", &value)) - return NULL; - return PyLong_FromUnsignedLong((unsigned long)value); + _make_call(callable); + PyThread_release_lock(thread_done); } static PyObject * -getargs_I(PyObject *self, PyObject *args) +test_thread_state(PyObject *self, PyObject *args) { - unsigned int value; - if (!PyArg_ParseTuple(args, "I", &value)) - return NULL; - return PyLong_FromUnsignedLong((unsigned long)value); -} + PyObject *fn; + int success = 1; -static PyObject * -getargs_k(PyObject *self, PyObject *args) -{ - unsigned long value; - if (!PyArg_ParseTuple(args, "k", &value)) + if (!PyArg_ParseTuple(args, "O:test_thread_state", &fn)) return NULL; - return PyLong_FromUnsignedLong(value); -} -static PyObject * -getargs_i(PyObject *self, PyObject *args) -{ - int value; - if (!PyArg_ParseTuple(args, "i", &value)) - return NULL; - return PyLong_FromLong((long)value); -} - -static PyObject * -getargs_l(PyObject *self, PyObject *args) -{ - long value; - if (!PyArg_ParseTuple(args, "l", &value)) - return NULL; - return PyLong_FromLong(value); -} - -static PyObject * -getargs_n(PyObject *self, PyObject *args) -{ - Py_ssize_t value; - if (!PyArg_ParseTuple(args, "n", &value)) - return NULL; - return PyLong_FromSsize_t(value); -} - -static PyObject * -getargs_p(PyObject *self, PyObject *args) -{ - int value; - if (!PyArg_ParseTuple(args, "p", &value)) - return NULL; - return PyLong_FromLong(value); -} - -static PyObject * -getargs_L(PyObject *self, PyObject *args) -{ - long long value; - if (!PyArg_ParseTuple(args, "L", &value)) - return NULL; - return PyLong_FromLongLong(value); -} - -static PyObject * -getargs_K(PyObject *self, PyObject *args) -{ - unsigned long long value; - if (!PyArg_ParseTuple(args, "K", &value)) - return NULL; - return PyLong_FromUnsignedLongLong(value); -} - -/* This function not only tests the 'k' getargs code, but also the - PyLong_AsUnsignedLongMask() function. */ -static PyObject * -test_k_code(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - PyObject *tuple, *num; - unsigned long value; - - tuple = PyTuple_New(1); - if (tuple == NULL) - return NULL; - - /* a number larger than ULONG_MAX even on 64-bit platforms */ - num = PyLong_FromString("FFFFFFFFFFFFFFFFFFFFFFFF", NULL, 16); - if (num == NULL) - return NULL; - - value = PyLong_AsUnsignedLongMask(num); - if (value != ULONG_MAX) - return raiseTestError("test_k_code", - "PyLong_AsUnsignedLongMask() returned wrong value for long 0xFFF...FFF"); - - PyTuple_SET_ITEM(tuple, 0, num); - - value = 0; - if (!PyArg_ParseTuple(tuple, "k:test_k_code", &value)) { + if (!PyCallable_Check(fn)) { + PyErr_Format(PyExc_TypeError, "'%s' object is not callable", + Py_TYPE(fn)->tp_name); return NULL; } - if (value != ULONG_MAX) - return raiseTestError("test_k_code", - "k code returned wrong value for long 0xFFF...FFF"); - Py_DECREF(num); - num = PyLong_FromString("-FFFFFFFF000000000000000042", NULL, 16); - if (num == NULL) - return NULL; + thread_done = PyThread_allocate_lock(); + if (thread_done == NULL) + return PyErr_NoMemory(); + PyThread_acquire_lock(thread_done, 1); - value = PyLong_AsUnsignedLongMask(num); - if (value != (unsigned long)-0x42) - return raiseTestError("test_k_code", - "PyLong_AsUnsignedLongMask() returned wrong " - "value for long -0xFFF..000042"); + /* Start a new thread with our callback. */ + PyThread_start_new_thread(_make_call_from_thread, fn); + /* Make the callback with the thread lock held by this thread */ + success &= _make_call(fn); + /* Do it all again, but this time with the thread-lock released */ + Py_BEGIN_ALLOW_THREADS + success &= _make_call(fn); + PyThread_acquire_lock(thread_done, 1); /* wait for thread to finish */ + Py_END_ALLOW_THREADS - PyTuple_SET_ITEM(tuple, 0, num); + /* And once more with and without a thread + XXX - should use a lock and work out exactly what we are trying + to test <wink> + */ + Py_BEGIN_ALLOW_THREADS + PyThread_start_new_thread(_make_call_from_thread, fn); + success &= _make_call(fn); + PyThread_acquire_lock(thread_done, 1); /* wait for thread to finish */ + Py_END_ALLOW_THREADS - value = 0; - if (!PyArg_ParseTuple(tuple, "k:test_k_code", &value)) { - return NULL; - } - if (value != (unsigned long)-0x42) - return raiseTestError("test_k_code", - "k code returned wrong value for long -0xFFF..000042"); + /* Release lock we acquired above. This is required on HP-UX. */ + PyThread_release_lock(thread_done); - Py_DECREF(tuple); + PyThread_free_lock(thread_done); + if (!success) + return NULL; Py_RETURN_NONE; } -static PyObject * -getargs_f(PyObject *self, PyObject *args) -{ - float f; - if (!PyArg_ParseTuple(args, "f", &f)) - return NULL; - return PyFloat_FromDouble(f); -} +#ifndef MS_WINDOWS +static PyThread_type_lock wait_done = NULL; -static PyObject * -getargs_d(PyObject *self, PyObject *args) -{ - double d; - if (!PyArg_ParseTuple(args, "d", &d)) - return NULL; - return PyFloat_FromDouble(d); +static void wait_for_lock(void *unused) { + PyThread_acquire_lock(wait_done, 1); + PyThread_release_lock(wait_done); + PyThread_free_lock(wait_done); + wait_done = NULL; } -static PyObject * -getargs_D(PyObject *self, PyObject *args) -{ - Py_complex cval; - if (!PyArg_ParseTuple(args, "D", &cval)) - return NULL; - return PyComplex_FromCComplex(cval); -} +// These can be used to test things that care about the existence of another +// thread that the threading module doesn't know about. static PyObject * -getargs_S(PyObject *self, PyObject *args) +spawn_pthread_waiter(PyObject *self, PyObject *Py_UNUSED(ignored)) { - PyObject *obj; - if (!PyArg_ParseTuple(args, "S", &obj)) + if (wait_done) { + PyErr_SetString(PyExc_RuntimeError, "thread already running"); return NULL; - Py_INCREF(obj); - return obj; + } + wait_done = PyThread_allocate_lock(); + if (wait_done == NULL) + return PyErr_NoMemory(); + PyThread_acquire_lock(wait_done, 1); + PyThread_start_new_thread(wait_for_lock, NULL); + Py_RETURN_NONE; } static PyObject * -getargs_Y(PyObject *self, PyObject *args) +end_spawned_pthread(PyObject *self, PyObject *Py_UNUSED(ignored)) { - PyObject *obj; - if (!PyArg_ParseTuple(args, "Y", &obj)) + if (!wait_done) { + PyErr_SetString(PyExc_RuntimeError, "call _spawn_pthread_waiter 1st"); return NULL; - Py_INCREF(obj); - return obj; + } + PyThread_release_lock(wait_done); + Py_RETURN_NONE; } +#endif // not MS_WINDOWS -static PyObject * -getargs_U(PyObject *self, PyObject *args) +/* test Py_AddPendingCalls using threads */ +static int _pending_callback(void *arg) { - PyObject *obj; - if (!PyArg_ParseTuple(args, "U", &obj)) - return NULL; - Py_INCREF(obj); - return obj; + /* we assume the argument is callable object to which we own a reference */ + PyObject *callable = (PyObject *)arg; + PyObject *r = PyObject_CallNoArgs(callable); + Py_DECREF(callable); + Py_XDECREF(r); + return r != NULL ? 0 : -1; } +/* The following requests n callbacks to _pending_callback. It can be + * run from any python thread. + */ static PyObject * -getargs_c(PyObject *self, PyObject *args) +pending_threadfunc(PyObject *self, PyObject *arg) { - char c; - if (!PyArg_ParseTuple(args, "c", &c)) + PyObject *callable; + int r; + if (PyArg_ParseTuple(arg, "O", &callable) == 0) return NULL; - return PyLong_FromLong((unsigned char)c); -} -static PyObject * -getargs_C(PyObject *self, PyObject *args) -{ - int c; - if (!PyArg_ParseTuple(args, "C", &c)) - return NULL; - return PyLong_FromLong(c); -} + /* create the reference for the callbackwhile we hold the lock */ + Py_INCREF(callable); -static PyObject * -getargs_s(PyObject *self, PyObject *args) -{ - char *str; - if (!PyArg_ParseTuple(args, "s", &str)) - return NULL; - return PyBytes_FromString(str); -} + Py_BEGIN_ALLOW_THREADS + r = Py_AddPendingCall(&_pending_callback, callable); + Py_END_ALLOW_THREADS -static PyObject * -getargs_s_star(PyObject *self, PyObject *args) -{ - Py_buffer buffer; - PyObject *bytes; - if (!PyArg_ParseTuple(args, "s*", &buffer)) - return NULL; - bytes = PyBytes_FromStringAndSize(buffer.buf, buffer.len); - PyBuffer_Release(&buffer); - return bytes; + if (r<0) { + Py_DECREF(callable); /* unsuccessful add, destroy the extra reference */ + Py_RETURN_FALSE; + } + Py_RETURN_TRUE; } +/* Test PyOS_string_to_double. */ static PyObject * -getargs_s_hash(PyObject *self, PyObject *args) -{ - char *str; - Py_ssize_t size; - if (!PyArg_ParseTuple(args, "s#", &str, &size)) - return NULL; - return PyBytes_FromStringAndSize(str, size); -} +test_string_to_double(PyObject *self, PyObject *Py_UNUSED(ignored)) { + double result; + const char *msg; -static PyObject * -getargs_z(PyObject *self, PyObject *args) -{ - char *str; - if (!PyArg_ParseTuple(args, "z", &str)) - return NULL; - if (str != NULL) - return PyBytes_FromString(str); - else - Py_RETURN_NONE; -} +#define CHECK_STRING(STR, expected) \ + result = PyOS_string_to_double(STR, NULL, NULL); \ + if (result == -1.0 && PyErr_Occurred()) \ + return NULL; \ + if (result != (double)expected) { \ + msg = "conversion of " STR " to float failed"; \ + goto fail; \ + } -static PyObject * -getargs_z_star(PyObject *self, PyObject *args) -{ - Py_buffer buffer; - PyObject *bytes; - if (!PyArg_ParseTuple(args, "z*", &buffer)) - return NULL; - if (buffer.buf != NULL) - bytes = PyBytes_FromStringAndSize(buffer.buf, buffer.len); - else { - Py_INCREF(Py_None); - bytes = Py_None; +#define CHECK_INVALID(STR) \ + result = PyOS_string_to_double(STR, NULL, NULL); \ + if (result == -1.0 && PyErr_Occurred()) { \ + if (PyErr_ExceptionMatches(PyExc_ValueError)) \ + PyErr_Clear(); \ + else \ + return NULL; \ + } \ + else { \ + msg = "conversion of " STR " didn't raise ValueError"; \ + goto fail; \ } - PyBuffer_Release(&buffer); - return bytes; -} -static PyObject * -getargs_z_hash(PyObject *self, PyObject *args) -{ - char *str; - Py_ssize_t size; - if (!PyArg_ParseTuple(args, "z#", &str, &size)) - return NULL; - if (str != NULL) - return PyBytes_FromStringAndSize(str, size); - else - Py_RETURN_NONE; -} + CHECK_STRING("0.1", 0.1); + CHECK_STRING("1.234", 1.234); + CHECK_STRING("-1.35", -1.35); + CHECK_STRING(".1e01", 1.0); + CHECK_STRING("2.e-2", 0.02); -static PyObject * -getargs_y(PyObject *self, PyObject *args) -{ - char *str; - if (!PyArg_ParseTuple(args, "y", &str)) - return NULL; - return PyBytes_FromString(str); -} + CHECK_INVALID(" 0.1"); + CHECK_INVALID("\t\n-3"); + CHECK_INVALID(".123 "); + CHECK_INVALID("3\n"); + CHECK_INVALID("123abc"); -static PyObject * -getargs_y_star(PyObject *self, PyObject *args) -{ - Py_buffer buffer; - PyObject *bytes; - if (!PyArg_ParseTuple(args, "y*", &buffer)) - return NULL; - bytes = PyBytes_FromStringAndSize(buffer.buf, buffer.len); - PyBuffer_Release(&buffer); - return bytes; + Py_RETURN_NONE; + fail: + return raiseTestError("test_string_to_double", msg); +#undef CHECK_STRING +#undef CHECK_INVALID } -static PyObject * -getargs_y_hash(PyObject *self, PyObject *args) -{ - char *str; - Py_ssize_t size; - if (!PyArg_ParseTuple(args, "y#", &str, &size)) - return NULL; - return PyBytes_FromStringAndSize(str, size); -} -static PyObject * -getargs_u(PyObject *self, PyObject *args) -{ - Py_UNICODE *str; - if (!PyArg_ParseTuple(args, "u", &str)) - return NULL; - return PyUnicode_FromWideChar(str, -1); -} +/* Coverage testing of capsule objects. */ -static PyObject * -getargs_u_hash(PyObject *self, PyObject *args) -{ - Py_UNICODE *str; - Py_ssize_t size; - if (!PyArg_ParseTuple(args, "u#", &str, &size)) - return NULL; - return PyUnicode_FromWideChar(str, size); -} +static const char *capsule_name = "capsule name"; +static char *capsule_pointer = "capsule pointer"; +static char *capsule_context = "capsule context"; +static const char *capsule_error = NULL; +static int +capsule_destructor_call_count = 0; -static PyObject * -getargs_Z(PyObject *self, PyObject *args) -{ - Py_UNICODE *str; - if (!PyArg_ParseTuple(args, "Z", &str)) - return NULL; - if (str != NULL) { - return PyUnicode_FromWideChar(str, -1); - } else - Py_RETURN_NONE; +static void +capsule_destructor(PyObject *o) { + capsule_destructor_call_count++; + if (PyCapsule_GetContext(o) != capsule_context) { + capsule_error = "context did not match in destructor!"; + } else if (PyCapsule_GetDestructor(o) != capsule_destructor) { + capsule_error = "destructor did not match in destructor! (woah!)"; + } else if (PyCapsule_GetName(o) != capsule_name) { + capsule_error = "name did not match in destructor!"; + } else if (PyCapsule_GetPointer(o, capsule_name) != capsule_pointer) { + capsule_error = "pointer did not match in destructor!"; + } } -static PyObject * -getargs_Z_hash(PyObject *self, PyObject *args) -{ - Py_UNICODE *str; - Py_ssize_t size; - if (!PyArg_ParseTuple(args, "Z#", &str, &size)) - return NULL; - if (str != NULL) - return PyUnicode_FromWideChar(str, size); - else - Py_RETURN_NONE; -} +typedef struct { + char *name; + char *module; + char *attribute; +} known_capsule; static PyObject * -getargs_es(PyObject *self, PyObject *args) +test_capsule(PyObject *self, PyObject *Py_UNUSED(ignored)) { - PyObject *arg, *result; - const char *encoding = NULL; - char *str; + PyObject *object; + const char *error = NULL; + void *pointer; + void *pointer2; + known_capsule known_capsules[] = { + #define KNOWN_CAPSULE(module, name) { module "." name, module, name } + KNOWN_CAPSULE("_socket", "CAPI"), + KNOWN_CAPSULE("_curses", "_C_API"), + KNOWN_CAPSULE("datetime", "datetime_CAPI"), + { NULL, NULL }, + }; + known_capsule *known = &known_capsules[0]; - if (!PyArg_ParseTuple(args, "O|s", &arg, &encoding)) - return NULL; - if (!PyArg_Parse(arg, "es", encoding, &str)) - return NULL; - result = PyBytes_FromString(str); - PyMem_Free(str); - return result; -} - -static PyObject * -getargs_et(PyObject *self, PyObject *args) -{ - PyObject *arg, *result; - const char *encoding = NULL; - char *str; +#define FAIL(x) { error = (x); goto exit; } - if (!PyArg_ParseTuple(args, "O|s", &arg, &encoding)) - return NULL; - if (!PyArg_Parse(arg, "et", encoding, &str)) - return NULL; - result = PyBytes_FromString(str); - PyMem_Free(str); - return result; -} +#define CHECK_DESTRUCTOR \ + if (capsule_error) { \ + FAIL(capsule_error); \ + } \ + else if (!capsule_destructor_call_count) { \ + FAIL("destructor not called!"); \ + } \ + capsule_destructor_call_count = 0; \ -static PyObject * -getargs_es_hash(PyObject *self, PyObject *args) -{ - PyObject *arg, *result; - const char *encoding = NULL; - PyByteArrayObject *buffer = NULL; - char *str = NULL; - Py_ssize_t size; + object = PyCapsule_New(capsule_pointer, capsule_name, capsule_destructor); + PyCapsule_SetContext(object, capsule_context); + capsule_destructor(object); + CHECK_DESTRUCTOR; + Py_DECREF(object); + CHECK_DESTRUCTOR; - if (!PyArg_ParseTuple(args, "O|sY", &arg, &encoding, &buffer)) - return NULL; - if (buffer != NULL) { - str = PyByteArray_AS_STRING(buffer); - size = PyByteArray_GET_SIZE(buffer); + object = PyCapsule_New(known, "ignored", NULL); + PyCapsule_SetPointer(object, capsule_pointer); + PyCapsule_SetName(object, capsule_name); + PyCapsule_SetDestructor(object, capsule_destructor); + PyCapsule_SetContext(object, capsule_context); + capsule_destructor(object); + CHECK_DESTRUCTOR; + /* intentionally access using the wrong name */ + pointer2 = PyCapsule_GetPointer(object, "the wrong name"); + if (!PyErr_Occurred()) { + FAIL("PyCapsule_GetPointer should have failed but did not!"); } - if (!PyArg_Parse(arg, "es#", encoding, &str, &size)) - return NULL; - result = PyBytes_FromStringAndSize(str, size); - if (buffer == NULL) - PyMem_Free(str); - return result; -} - -static PyObject * -getargs_et_hash(PyObject *self, PyObject *args) -{ - PyObject *arg, *result; - const char *encoding = NULL; - PyByteArrayObject *buffer = NULL; - char *str = NULL; - Py_ssize_t size; - - if (!PyArg_ParseTuple(args, "O|sY", &arg, &encoding, &buffer)) - return NULL; - if (buffer != NULL) { - str = PyByteArray_AS_STRING(buffer); - size = PyByteArray_GET_SIZE(buffer); + PyErr_Clear(); + if (pointer2) { + if (pointer2 == capsule_pointer) { + FAIL("PyCapsule_GetPointer should not have" + " returned the internal pointer!"); + } else { + FAIL("PyCapsule_GetPointer should have " + "returned NULL pointer but did not!"); + } + } + PyCapsule_SetDestructor(object, NULL); + Py_DECREF(object); + if (capsule_destructor_call_count) { + FAIL("destructor called when it should not have been!"); } - if (!PyArg_Parse(arg, "et#", encoding, &str, &size)) - return NULL; - result = PyBytes_FromStringAndSize(str, size); - if (buffer == NULL) - PyMem_Free(str); - return result; -} - -/* Test the s and z codes for PyArg_ParseTuple. -*/ -static PyObject * -test_s_code(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - /* Unicode strings should be accepted */ - PyObject *tuple, *obj; - char *value; - - tuple = PyTuple_New(1); - if (tuple == NULL) - return NULL; - - obj = PyUnicode_Decode("t\xeate", strlen("t\xeate"), - "latin-1", NULL); - if (obj == NULL) - return NULL; - PyTuple_SET_ITEM(tuple, 0, obj); + for (known = &known_capsules[0]; known->module != NULL; known++) { + /* yeah, ordinarily I wouldn't do this either, + but it's fine for this test harness. + */ + static char buffer[256]; +#undef FAIL +#define FAIL(x) \ + { \ + sprintf(buffer, "%s module: \"%s\" attribute: \"%s\"", \ + x, known->module, known->attribute); \ + error = buffer; \ + goto exit; \ + } \ - /* These two blocks used to raise a TypeError: - * "argument must be string without null bytes, not str" - */ - if (!PyArg_ParseTuple(tuple, "s:test_s_code1", &value)) { - return NULL; + PyObject *module = PyImport_ImportModule(known->module); + if (module) { + pointer = PyCapsule_Import(known->name, 0); + if (!pointer) { + Py_DECREF(module); + FAIL("PyCapsule_GetPointer returned NULL unexpectedly!"); + } + object = PyObject_GetAttrString(module, known->attribute); + if (!object) { + Py_DECREF(module); + return NULL; + } + pointer2 = PyCapsule_GetPointer(object, + "weebles wobble but they don't fall down"); + if (!PyErr_Occurred()) { + Py_DECREF(object); + Py_DECREF(module); + FAIL("PyCapsule_GetPointer should have failed but did not!"); + } + PyErr_Clear(); + if (pointer2) { + Py_DECREF(module); + Py_DECREF(object); + if (pointer2 == pointer) { + FAIL("PyCapsule_GetPointer should not have" + " returned its internal pointer!"); + } else { + FAIL("PyCapsule_GetPointer should have" + " returned NULL pointer but did not!"); + } + } + Py_DECREF(object); + Py_DECREF(module); + } + else + PyErr_Clear(); } - if (!PyArg_ParseTuple(tuple, "z:test_s_code2", &value)) { - return NULL; + exit: + if (error) { + return raiseTestError("test_capsule", error); } - - Py_DECREF(tuple); Py_RETURN_NONE; +#undef FAIL } -static PyObject * -parse_tuple_and_keywords(PyObject *self, PyObject *args) +#ifdef HAVE_GETTIMEOFDAY +/* Profiling of integer performance */ +static void print_delta(int test, struct timeval *s, struct timeval *e) { - PyObject *sub_args; - PyObject *sub_kwargs; - const char *sub_format; - PyObject *sub_keywords; - - Py_ssize_t i, size; - char *keywords[8 + 1]; /* space for NULL at end */ - PyObject *o; - PyObject *converted[8]; + e->tv_sec -= s->tv_sec; + e->tv_usec -= s->tv_usec; + if (e->tv_usec < 0) { + e->tv_sec -=1; + e->tv_usec += 1000000; + } + printf("Test %d: %d.%06ds\n", test, (int)e->tv_sec, (int)e->tv_usec); +} - int result; - PyObject *return_value = NULL; +static PyObject * +profile_int(PyObject *self, PyObject* args) +{ + int i, k; + struct timeval start, stop; + PyObject *single, **multiple, *op1, *result; - double buffers[8][4]; /* double ensures alignment where necessary */ + /* Test 1: Allocate and immediately deallocate + many small integers */ + gettimeofday(&start, NULL); + for(k=0; k < 20000; k++) + for(i=0; i < 1000; i++) { + single = PyLong_FromLong(i); + Py_DECREF(single); + } + gettimeofday(&stop, NULL); + print_delta(1, &start, &stop); - if (!PyArg_ParseTuple(args, "OOsO:parse_tuple_and_keywords", - &sub_args, &sub_kwargs, - &sub_format, &sub_keywords)) - return NULL; + /* Test 2: Allocate and immediately deallocate + many large integers */ + gettimeofday(&start, NULL); + for(k=0; k < 20000; k++) + for(i=0; i < 1000; i++) { + single = PyLong_FromLong(i+1000000); + Py_DECREF(single); + } + gettimeofday(&stop, NULL); + print_delta(2, &start, &stop); - if (!(PyList_CheckExact(sub_keywords) || PyTuple_CheckExact(sub_keywords))) { - PyErr_SetString(PyExc_ValueError, - "parse_tuple_and_keywords: sub_keywords must be either list or tuple"); - return NULL; + /* Test 3: Allocate a few integers, then release + them all simultaneously. */ + multiple = malloc(sizeof(PyObject*) * 1000); + if (multiple == NULL) + return PyErr_NoMemory(); + gettimeofday(&start, NULL); + for(k=0; k < 20000; k++) { + for(i=0; i < 1000; i++) { + multiple[i] = PyLong_FromLong(i+1000000); + } + for(i=0; i < 1000; i++) { + Py_DECREF(multiple[i]); + } } + gettimeofday(&stop, NULL); + print_delta(3, &start, &stop); + free(multiple); - memset(buffers, 0, sizeof(buffers)); - memset(converted, 0, sizeof(converted)); - memset(keywords, 0, sizeof(keywords)); - - size = PySequence_Fast_GET_SIZE(sub_keywords); - if (size > 8) { - PyErr_SetString(PyExc_ValueError, - "parse_tuple_and_keywords: too many keywords in sub_keywords"); - goto exit; + /* Test 4: Allocate many integers, then release + them all simultaneously. */ + multiple = malloc(sizeof(PyObject*) * 1000000); + if (multiple == NULL) + return PyErr_NoMemory(); + gettimeofday(&start, NULL); + for(k=0; k < 20; k++) { + for(i=0; i < 1000000; i++) { + multiple[i] = PyLong_FromLong(i+1000000); + } + for(i=0; i < 1000000; i++) { + Py_DECREF(multiple[i]); + } } + gettimeofday(&stop, NULL); + print_delta(4, &start, &stop); + free(multiple); - for (i = 0; i < size; i++) { - o = PySequence_Fast_GET_ITEM(sub_keywords, i); - if (!PyUnicode_FSConverter(o, (void *)(converted + i))) { - PyErr_Format(PyExc_ValueError, - "parse_tuple_and_keywords: could not convert keywords[%zd] to narrow string", i); - goto exit; + /* Test 5: Allocate many integers < 32000 */ + multiple = malloc(sizeof(PyObject*) * 1000000); + if (multiple == NULL) + return PyErr_NoMemory(); + gettimeofday(&start, NULL); + for(k=0; k < 10; k++) { + for(i=0; i < 1000000; i++) { + multiple[i] = PyLong_FromLong(i+1000); + } + for(i=0; i < 1000000; i++) { + Py_DECREF(multiple[i]); } - keywords[i] = PyBytes_AS_STRING(converted[i]); } + gettimeofday(&stop, NULL); + print_delta(5, &start, &stop); + free(multiple); - result = PyArg_ParseTupleAndKeywords(sub_args, sub_kwargs, - sub_format, keywords, - buffers + 0, buffers + 1, buffers + 2, buffers + 3, - buffers + 4, buffers + 5, buffers + 6, buffers + 7); - - if (result) { - return_value = Py_None; - Py_INCREF(Py_None); + /* Test 6: Perform small int addition */ + op1 = PyLong_FromLong(1); + gettimeofday(&start, NULL); + for(i=0; i < 10000000; i++) { + result = PyNumber_Add(op1, op1); + Py_DECREF(result); } + gettimeofday(&stop, NULL); + Py_DECREF(op1); + print_delta(6, &start, &stop); -exit: - size = sizeof(converted) / sizeof(converted[0]); - for (i = 0; i < size; i++) { - Py_XDECREF(converted[i]); + /* Test 7: Perform medium int addition */ + op1 = PyLong_FromLong(1000); + if (op1 == NULL) + return NULL; + gettimeofday(&start, NULL); + for(i=0; i < 10000000; i++) { + result = PyNumber_Add(op1, op1); + Py_XDECREF(result); } - return return_value; -} - -static volatile int x; + gettimeofday(&stop, NULL); + Py_DECREF(op1); + print_delta(7, &start, &stop); -#if USE_UNICODE_WCHAR_CACHE -/* Ignore use of deprecated APIs */ -_Py_COMP_DIAG_PUSH -_Py_COMP_DIAG_IGNORE_DEPR_DECLS + Py_RETURN_NONE; +} +#endif -/* Test the u and u# codes for PyArg_ParseTuple. May leak memory in case - of an error. -*/ -static PyObject * -test_u_code(PyObject *self, PyObject *Py_UNUSED(ignored)) +/* Issue 6012 */ +static PyObject *str1, *str2; +static int +failing_converter(PyObject *obj, void *arg) { - PyObject *tuple, *obj; - Py_UNICODE *value; - Py_ssize_t len; - - /* issue4122: Undefined reference to _Py_ascii_whitespace on Windows */ - /* Just use the macro and check that it compiles */ - x = Py_UNICODE_ISSPACE(25); - - tuple = PyTuple_New(1); - if (tuple == NULL) - return NULL; - - obj = PyUnicode_Decode("test", strlen("test"), - "ascii", NULL); - if (obj == NULL) - return NULL; - - PyTuple_SET_ITEM(tuple, 0, obj); - - value = 0; - if (!PyArg_ParseTuple(tuple, "u:test_u_code", &value)) { - return NULL; - } - if (value != PyUnicode_AS_UNICODE(obj)) - return raiseTestError("test_u_code", - "u code returned wrong value for u'test'"); - value = 0; - if (!PyArg_ParseTuple(tuple, "u#:test_u_code", &value, &len)) { - return NULL; + /* Clone str1, then let the conversion fail. */ + assert(str1); + str2 = Py_NewRef(str1); + return 0; +} +static PyObject* +argparsing(PyObject *o, PyObject *args) +{ + PyObject *res; + str1 = str2 = NULL; + if (!PyArg_ParseTuple(args, "O&O&", + PyUnicode_FSConverter, &str1, + failing_converter, &str2)) { + if (!str2) + /* argument converter not called? */ + return NULL; + /* Should be 1 */ + res = PyLong_FromSsize_t(Py_REFCNT(str2)); + Py_DECREF(str2); + PyErr_Clear(); + return res; } - if (value != PyUnicode_AS_UNICODE(obj) || - len != PyUnicode_GET_SIZE(obj)) - return raiseTestError("test_u_code", - "u# code returned wrong values for u'test'"); - - Py_DECREF(tuple); Py_RETURN_NONE; } -/* Test Z and Z# codes for PyArg_ParseTuple */ +/* To test that the result of PyCode_NewEmpty has the right members. */ static PyObject * -test_Z_code(PyObject *self, PyObject *Py_UNUSED(ignored)) +code_newempty(PyObject *self, PyObject *args) { - PyObject *tuple, *obj; - const Py_UNICODE *value1, *value2; - Py_ssize_t len1, len2; + const char *filename; + const char *funcname; + int firstlineno; - tuple = PyTuple_New(2); - if (tuple == NULL) + if (!PyArg_ParseTuple(args, "ssi:code_newempty", + &filename, &funcname, &firstlineno)) return NULL; - obj = PyUnicode_FromString("test"); - PyTuple_SET_ITEM(tuple, 0, obj); - Py_INCREF(Py_None); - PyTuple_SET_ITEM(tuple, 1, Py_None); - - /* swap values on purpose */ - value1 = NULL; - value2 = PyUnicode_AS_UNICODE(obj); + return (PyObject *)PyCode_NewEmpty(filename, funcname, firstlineno); +} - /* Test Z for both values */ - if (!PyArg_ParseTuple(tuple, "ZZ:test_Z_code", &value1, &value2)) { +static PyObject * +make_memoryview_from_NULL_pointer(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + Py_buffer info; + if (PyBuffer_FillInfo(&info, NULL, NULL, 1, 1, PyBUF_FULL_RO) < 0) return NULL; + return PyMemoryView_FromBuffer(&info); +} + +static PyObject * +test_from_contiguous(PyObject* self, PyObject *Py_UNUSED(ignored)) +{ + int data[9] = {-1,-1,-1,-1,-1,-1,-1,-1,-1}; + int init[5] = {0, 1, 2, 3, 4}; + Py_ssize_t itemsize = sizeof(int); + Py_ssize_t shape = 5; + Py_ssize_t strides = 2 * itemsize; + Py_buffer view = { + data, + NULL, + 5 * itemsize, + itemsize, + 1, + 1, + NULL, + &shape, + &strides, + NULL, + NULL + }; + int *ptr; + int i; + + PyBuffer_FromContiguous(&view, init, view.len, 'C'); + ptr = view.buf; + for (i = 0; i < 5; i++) { + if (ptr[2*i] != i) { + PyErr_SetString(TestError, + "test_from_contiguous: incorrect result"); + return NULL; + } } - if (value1 != PyUnicode_AS_UNICODE(obj)) - return raiseTestError("test_Z_code", - "Z code returned wrong value for 'test'"); - if (value2 != NULL) - return raiseTestError("test_Z_code", - "Z code returned wrong value for None"); - value1 = NULL; - value2 = PyUnicode_AS_UNICODE(obj); - len1 = -1; - len2 = -1; + view.buf = &data[8]; + view.strides[0] = -2 * itemsize; - /* Test Z# for both values */ - if (!PyArg_ParseTuple(tuple, "Z#Z#:test_Z_code", &value1, &len1, - &value2, &len2)) - { - return NULL; + PyBuffer_FromContiguous(&view, init, view.len, 'C'); + ptr = view.buf; + for (i = 0; i < 5; i++) { + if (*(ptr-2*i) != i) { + PyErr_SetString(TestError, + "test_from_contiguous: incorrect result"); + return NULL; + } } - if (value1 != PyUnicode_AS_UNICODE(obj) || - len1 != PyUnicode_GET_SIZE(obj)) - return raiseTestError("test_Z_code", - "Z# code returned wrong values for 'test'"); - if (value2 != NULL || - len2 != 0) - return raiseTestError("test_Z_code", - "Z# code returned wrong values for None'"); - Py_DECREF(tuple); Py_RETURN_NONE; } -_Py_COMP_DIAG_POP -#endif /* USE_UNICODE_WCHAR_CACHE */ + +#if (defined(__linux__) || defined(__FreeBSD__)) && defined(__GNUC__) static PyObject * -test_widechar(PyObject *self, PyObject *Py_UNUSED(ignored)) +test_pep3118_obsolete_write_locks(PyObject* self, PyObject *Py_UNUSED(ignored)) { -#if defined(SIZEOF_WCHAR_T) && (SIZEOF_WCHAR_T == 4) - const wchar_t wtext[2] = {(wchar_t)0x10ABCDu}; - size_t wtextlen = 1; - const wchar_t invalid[1] = {(wchar_t)0x110000u}; -#else - const wchar_t wtext[3] = {(wchar_t)0xDBEAu, (wchar_t)0xDFCDu}; - size_t wtextlen = 2; -#endif - PyObject *wide, *utf8; + PyObject *b; + char *dummy[1]; + int ret, match; - wide = PyUnicode_FromWideChar(wtext, wtextlen); - if (wide == NULL) - return NULL; + /* PyBuffer_FillInfo() */ + ret = PyBuffer_FillInfo(NULL, NULL, dummy, 1, 0, PyBUF_SIMPLE); + match = PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_BufferError); + PyErr_Clear(); + if (ret != -1 || match == 0) + goto error; - utf8 = PyUnicode_FromString("\xf4\x8a\xaf\x8d"); - if (utf8 == NULL) { - Py_DECREF(wide); + /* bytesiobuf_getbuffer() */ + PyTypeObject *type = (PyTypeObject *)_PyImport_GetModuleAttrString( + "_io", "_BytesIOBuffer"); + if (type == NULL) { return NULL; } - - if (PyUnicode_GET_LENGTH(wide) != PyUnicode_GET_LENGTH(utf8)) { - Py_DECREF(wide); - Py_DECREF(utf8); - return raiseTestError("test_widechar", - "wide string and utf8 string " - "have different length"); - } - if (PyUnicode_Compare(wide, utf8)) { - Py_DECREF(wide); - Py_DECREF(utf8); - if (PyErr_Occurred()) - return NULL; - return raiseTestError("test_widechar", - "wide string and utf8 string " - "are different"); + b = type->tp_alloc(type, 0); + Py_DECREF(type); + if (b == NULL) { + return NULL; } - Py_DECREF(wide); - Py_DECREF(utf8); + ret = PyObject_GetBuffer(b, NULL, PyBUF_SIMPLE); + Py_DECREF(b); + match = PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_BufferError); + PyErr_Clear(); + if (ret != -1 || match == 0) + goto error; -#if defined(SIZEOF_WCHAR_T) && (SIZEOF_WCHAR_T == 4) - wide = PyUnicode_FromWideChar(invalid, 1); - if (wide == NULL) - PyErr_Clear(); - else - return raiseTestError("test_widechar", - "PyUnicode_FromWideChar(L\"\\U00110000\", 1) didn't fail"); - -#if USE_UNICODE_WCHAR_CACHE -/* Ignore use of deprecated APIs */ -_Py_COMP_DIAG_PUSH -_Py_COMP_DIAG_IGNORE_DEPR_DECLS - wide = PyUnicode_FromUnicode(invalid, 1); - if (wide == NULL) - PyErr_Clear(); - else - return raiseTestError("test_widechar", - "PyUnicode_FromUnicode(L\"\\U00110000\", 1) didn't fail"); + Py_RETURN_NONE; - wide = PyUnicode_FromUnicode(NULL, 1); - if (wide == NULL) - return NULL; - PyUnicode_AS_UNICODE(wide)[0] = invalid[0]; - if (_PyUnicode_Ready(wide) < 0) { - Py_DECREF(wide); - PyErr_Clear(); - } - else { - Py_DECREF(wide); - return raiseTestError("test_widechar", - "PyUnicode_Ready() didn't fail"); - } -_Py_COMP_DIAG_POP -#endif /* USE_UNICODE_WCHAR_CACHE */ +error: + PyErr_SetString(TestError, + "test_pep3118_obsolete_write_locks: failure"); + return NULL; +} #endif +/* This tests functions that historically supported write locks. It is + wrong to call getbuffer() with view==NULL and a compliant getbufferproc + is entitled to segfault in that case. */ +static PyObject * +getbuffer_with_null_view(PyObject* self, PyObject *obj) +{ + if (PyObject_GetBuffer(obj, NULL, PyBUF_SIMPLE) < 0) + return NULL; + Py_RETURN_NONE; } +/* PyBuffer_SizeFromFormat() */ static PyObject * -unicode_aswidechar(PyObject *self, PyObject *args) +test_PyBuffer_SizeFromFormat(PyObject *self, PyObject *args) { - PyObject *unicode, *result; - Py_ssize_t buflen, size; - wchar_t *buffer; - - if (!PyArg_ParseTuple(args, "Un", &unicode, &buflen)) - return NULL; - buffer = PyMem_New(wchar_t, buflen); - if (buffer == NULL) - return PyErr_NoMemory(); + const char *format; - size = PyUnicode_AsWideChar(unicode, buffer, buflen); - if (size == -1) { - PyMem_Free(buffer); + if (!PyArg_ParseTuple(args, "s:test_PyBuffer_SizeFromFormat", + &format)) { return NULL; } - if (size < buflen) - buflen = size + 1; - else - buflen = size; - result = PyUnicode_FromWideChar(buffer, buflen); - PyMem_Free(buffer); - if (result == NULL) - return NULL; - - return Py_BuildValue("(Nn)", result, size); + RETURN_SIZE(PyBuffer_SizeFromFormat(format)); } +/* Test that the fatal error from not having a current thread doesn't + cause an infinite loop. Run via Lib/test/test_capi.py */ static PyObject * -unicode_aswidecharstring(PyObject *self, PyObject *args) +crash_no_current_thread(PyObject *self, PyObject *Py_UNUSED(ignored)) { - PyObject *unicode, *result; - Py_ssize_t size; - wchar_t *buffer; - - if (!PyArg_ParseTuple(args, "U", &unicode)) - return NULL; - - buffer = PyUnicode_AsWideCharString(unicode, &size); - if (buffer == NULL) - return NULL; - - result = PyUnicode_FromWideChar(buffer, size + 1); - PyMem_Free(buffer); - if (result == NULL) - return NULL; - return Py_BuildValue("(Nn)", result, size); + Py_BEGIN_ALLOW_THREADS + /* Using PyThreadState_Get() directly allows the test to pass in + !pydebug mode. However, the test only actually tests anything + in pydebug mode, since that's where the infinite loop was in + the first place. */ + PyThreadState_Get(); + Py_END_ALLOW_THREADS + return NULL; } +/* Test that the GILState thread and the "current" thread match. */ static PyObject * -unicode_asucs4(PyObject *self, PyObject *args) +test_current_tstate_matches(PyObject *self, PyObject *Py_UNUSED(ignored)) { - PyObject *unicode, *result; - Py_UCS4 *buffer; - int copy_null; - Py_ssize_t str_len, buf_len; + PyThreadState *orig_tstate = PyThreadState_Get(); - if (!PyArg_ParseTuple(args, "Unp:unicode_asucs4", &unicode, &str_len, ©_null)) { + if (orig_tstate != PyGILState_GetThisThreadState()) { + PyErr_SetString(PyExc_RuntimeError, + "current thread state doesn't match GILState"); return NULL; } - buf_len = str_len + 1; - buffer = PyMem_NEW(Py_UCS4, buf_len); - if (buffer == NULL) { - return PyErr_NoMemory(); + const char *err = NULL; + PyThreadState_Swap(NULL); + PyThreadState *substate = Py_NewInterpreter(); + + if (substate != PyThreadState_Get()) { + err = "subinterpreter thread state not current"; + goto finally; } - memset(buffer, 0, sizeof(Py_UCS4)*buf_len); - buffer[str_len] = 0xffffU; + if (substate != PyGILState_GetThisThreadState()) { + err = "subinterpreter thread state doesn't match GILState"; + goto finally; + } + +finally: + Py_EndInterpreter(substate); + PyThreadState_Swap(orig_tstate); - if (!PyUnicode_AsUCS4(unicode, buffer, buf_len, copy_null)) { - PyMem_Free(buffer); + if (err != NULL) { + PyErr_SetString(PyExc_RuntimeError, err); return NULL; } - - result = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, buffer, buf_len); - PyMem_Free(buffer); - return result; + Py_RETURN_NONE; } +/* To run some code in a sub-interpreter. */ static PyObject * -unicode_asutf8(PyObject *self, PyObject *args) +run_in_subinterp(PyObject *self, PyObject *args) { - PyObject *unicode; - const char *buffer; + const char *code; + int r; + PyThreadState *substate, *mainstate; + /* only initialise 'cflags.cf_flags' to test backwards compatibility */ + PyCompilerFlags cflags = {0}; - if (!PyArg_ParseTuple(args, "U", &unicode)) { + if (!PyArg_ParseTuple(args, "s:run_in_subinterp", + &code)) return NULL; - } - buffer = PyUnicode_AsUTF8(unicode); - if (buffer == NULL) { + mainstate = PyThreadState_Get(); + + PyThreadState_Swap(NULL); + + substate = Py_NewInterpreter(); + if (substate == NULL) { + /* Since no new thread state was created, there is no exception to + propagate; raise a fresh one after swapping in the old thread + state. */ + PyThreadState_Swap(mainstate); + PyErr_SetString(PyExc_RuntimeError, "sub-interpreter creation failed"); return NULL; } + r = PyRun_SimpleStringFlags(code, &cflags); + Py_EndInterpreter(substate); + + PyThreadState_Swap(mainstate); - return PyBytes_FromString(buffer); + return PyLong_FromLong(r); } +/* To run some code in a sub-interpreter. */ static PyObject * -unicode_asutf8andsize(PyObject *self, PyObject *args) +run_in_subinterp_with_config(PyObject *self, PyObject *args, PyObject *kwargs) { - PyObject *unicode, *result; - const char *buffer; - Py_ssize_t utf8_len; + const char *code; + int use_main_obmalloc = -1; + int allow_fork = -1; + int allow_exec = -1; + int allow_threads = -1; + int allow_daemon_threads = -1; + int check_multi_interp_extensions = -1; + int gil = -1; + int r; + PyThreadState *substate, *mainstate; + /* only initialise 'cflags.cf_flags' to test backwards compatibility */ + PyCompilerFlags cflags = {0}; - if(!PyArg_ParseTuple(args, "U", &unicode)) { + static char *kwlist[] = {"code", + "use_main_obmalloc", + "allow_fork", + "allow_exec", + "allow_threads", + "allow_daemon_threads", + "check_multi_interp_extensions", + "gil", + NULL}; + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "s$ppppppi:run_in_subinterp_with_config", kwlist, + &code, &use_main_obmalloc, + &allow_fork, &allow_exec, + &allow_threads, &allow_daemon_threads, + &check_multi_interp_extensions, + &gil)) { return NULL; } - - buffer = PyUnicode_AsUTF8AndSize(unicode, &utf8_len); - if (buffer == NULL) { + if (use_main_obmalloc < 0) { + PyErr_SetString(PyExc_ValueError, "missing use_main_obmalloc"); return NULL; } - - result = PyBytes_FromString(buffer); - if (result == NULL) { + if (allow_fork < 0) { + PyErr_SetString(PyExc_ValueError, "missing allow_fork"); return NULL; } - - return Py_BuildValue("(Nn)", result, utf8_len); -} - -static PyObject * -unicode_findchar(PyObject *self, PyObject *args) -{ - PyObject *str; - int direction; - unsigned int ch; - Py_ssize_t result; - Py_ssize_t start, end; - - if (!PyArg_ParseTuple(args, "UInni:unicode_findchar", &str, &ch, - &start, &end, &direction)) { + if (allow_exec < 0) { + PyErr_SetString(PyExc_ValueError, "missing allow_exec"); return NULL; } - - result = PyUnicode_FindChar(str, (Py_UCS4)ch, start, end, direction); - if (result == -2) - return NULL; - else - return PyLong_FromSsize_t(result); -} - -static PyObject * -unicode_copycharacters(PyObject *self, PyObject *args) -{ - PyObject *from, *to, *to_copy; - Py_ssize_t from_start, to_start, how_many, copied; - - if (!PyArg_ParseTuple(args, "UnOnn:unicode_copycharacters", &to, &to_start, - &from, &from_start, &how_many)) { + if (allow_threads < 0) { + PyErr_SetString(PyExc_ValueError, "missing allow_threads"); return NULL; } - - if (!(to_copy = PyUnicode_New(PyUnicode_GET_LENGTH(to), - PyUnicode_MAX_CHAR_VALUE(to)))) { + if (gil < 0) { + PyErr_SetString(PyExc_ValueError, "missing gil"); return NULL; } - if (PyUnicode_Fill(to_copy, 0, PyUnicode_GET_LENGTH(to_copy), 0U) < 0) { - Py_DECREF(to_copy); + if (allow_daemon_threads < 0) { + PyErr_SetString(PyExc_ValueError, "missing allow_daemon_threads"); return NULL; } - - if ((copied = PyUnicode_CopyCharacters(to_copy, to_start, from, - from_start, how_many)) < 0) { - Py_DECREF(to_copy); + if (check_multi_interp_extensions < 0) { + PyErr_SetString(PyExc_ValueError, "missing check_multi_interp_extensions"); return NULL; } - return Py_BuildValue("(Nn)", to_copy, copied); -} - -#if USE_UNICODE_WCHAR_CACHE -/* Ignore use of deprecated APIs */ -_Py_COMP_DIAG_PUSH -_Py_COMP_DIAG_IGNORE_DEPR_DECLS + mainstate = PyThreadState_Get(); -static PyObject * -unicode_legacy_string(PyObject *self, PyObject *args) -{ - Py_UNICODE *data; - Py_ssize_t len; - PyObject *u; + PyThreadState_Swap(NULL); - if (!PyArg_ParseTuple(args, "u#", &data, &len)) + const PyInterpreterConfig config = { + .use_main_obmalloc = use_main_obmalloc, + .allow_fork = allow_fork, + .allow_exec = allow_exec, + .allow_threads = allow_threads, + .allow_daemon_threads = allow_daemon_threads, + .check_multi_interp_extensions = check_multi_interp_extensions, + .gil = gil, + }; + PyStatus status = Py_NewInterpreterFromConfig(&substate, &config); + if (PyStatus_Exception(status)) { + /* Since no new thread state was created, there is no exception to + propagate; raise a fresh one after swapping in the old thread + state. */ + PyThreadState_Swap(mainstate); + _PyErr_SetFromPyStatus(status); + PyObject *exc = PyErr_GetRaisedException(); + PyErr_SetString(PyExc_RuntimeError, "sub-interpreter creation failed"); + _PyErr_ChainExceptions1(exc); return NULL; + } + assert(substate != NULL); + r = PyRun_SimpleStringFlags(code, &cflags); + Py_EndInterpreter(substate); - u = PyUnicode_FromUnicode(NULL, len); - if (u == NULL) - return NULL; + PyThreadState_Swap(mainstate); - memcpy(PyUnicode_AS_UNICODE(u), data, len * sizeof(Py_UNICODE)); + return PyLong_FromLong(r); +} - if (len > 0) { /* The empty string is always ready. */ - assert(!PyUnicode_IS_READY(u)); +static void +_xid_capsule_destructor(PyObject *capsule) +{ + _PyCrossInterpreterData *data = \ + (_PyCrossInterpreterData *)PyCapsule_GetPointer(capsule, NULL); + if (data != NULL) { + assert(_PyCrossInterpreterData_Release(data) == 0); + PyMem_Free(data); } - - return u; } -_Py_COMP_DIAG_POP -#endif /* USE_UNICODE_WCHAR_CACHE */ static PyObject * -getargs_w_star(PyObject *self, PyObject *args) +get_crossinterp_data(PyObject *self, PyObject *args) { - Py_buffer buffer; - PyObject *result; - char *str; - - if (!PyArg_ParseTuple(args, "w*:getargs_w_star", &buffer)) + PyObject *obj = NULL; + if (!PyArg_ParseTuple(args, "O:get_crossinterp_data", &obj)) { return NULL; - - if (2 <= buffer.len) { - str = buffer.buf; - str[0] = '['; - str[buffer.len-1] = ']'; } - result = PyBytes_FromStringAndSize(buffer.buf, buffer.len); - PyBuffer_Release(&buffer); - return result; -} - - -static PyObject * -test_empty_argparse(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - /* Test that formats can begin with '|'. See issue #4720. */ - PyObject *tuple, *dict = NULL; - static char *kwlist[] = {NULL}; - int result; - tuple = PyTuple_New(0); - if (!tuple) + _PyCrossInterpreterData *data = PyMem_NEW(_PyCrossInterpreterData, 1); + if (data == NULL) { + PyErr_NoMemory(); return NULL; - if (!(result = PyArg_ParseTuple(tuple, "|:test_empty_argparse"))) { - goto done; } - dict = PyDict_New(); - if (!dict) - goto done; - result = PyArg_ParseTupleAndKeywords(tuple, dict, "|:test_empty_argparse", kwlist); - done: - Py_DECREF(tuple); - Py_XDECREF(dict); - if (!result) { + if (_PyObject_GetCrossInterpreterData(obj, data) != 0) { + PyMem_Free(data); return NULL; } - else { - Py_RETURN_NONE; + PyObject *capsule = PyCapsule_New(data, NULL, _xid_capsule_destructor); + if (capsule == NULL) { + assert(_PyCrossInterpreterData_Release(data) == 0); + PyMem_Free(data); } + return capsule; } static PyObject * -codec_incrementalencoder(PyObject *self, PyObject *args) +restore_crossinterp_data(PyObject *self, PyObject *args) { - const char *encoding, *errors = NULL; - if (!PyArg_ParseTuple(args, "s|s:test_incrementalencoder", - &encoding, &errors)) + PyObject *capsule = NULL; + if (!PyArg_ParseTuple(args, "O:restore_crossinterp_data", &capsule)) { return NULL; - return PyCodec_IncrementalEncoder(encoding, errors); -} + } -static PyObject * -codec_incrementaldecoder(PyObject *self, PyObject *args) -{ - const char *encoding, *errors = NULL; - if (!PyArg_ParseTuple(args, "s|s:test_incrementaldecoder", - &encoding, &errors)) + _PyCrossInterpreterData *data = \ + (_PyCrossInterpreterData *)PyCapsule_GetPointer(capsule, NULL); + if (data == NULL) { return NULL; - return PyCodec_IncrementalDecoder(encoding, errors); -} - - -/* Simple test of _PyLong_NumBits and _PyLong_Sign. */ -static PyObject * -test_long_numbits(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - struct triple { - long input; - size_t nbits; - int sign; - } testcases[] = {{0, 0, 0}, - {1L, 1, 1}, - {-1L, 1, -1}, - {2L, 2, 1}, - {-2L, 2, -1}, - {3L, 2, 1}, - {-3L, 2, -1}, - {4L, 3, 1}, - {-4L, 3, -1}, - {0x7fffL, 15, 1}, /* one Python int digit */ - {-0x7fffL, 15, -1}, - {0xffffL, 16, 1}, - {-0xffffL, 16, -1}, - {0xfffffffL, 28, 1}, - {-0xfffffffL, 28, -1}}; - size_t i; - - for (i = 0; i < Py_ARRAY_LENGTH(testcases); ++i) { - size_t nbits; - int sign; - PyObject *plong; - - plong = PyLong_FromLong(testcases[i].input); - if (plong == NULL) - return NULL; - nbits = _PyLong_NumBits(plong); - sign = _PyLong_Sign(plong); - - Py_DECREF(plong); - if (nbits != testcases[i].nbits) - return raiseTestError("test_long_numbits", - "wrong result for _PyLong_NumBits"); - if (sign != testcases[i].sign) - return raiseTestError("test_long_numbits", - "wrong result for _PyLong_Sign"); } - Py_RETURN_NONE; + return _PyCrossInterpreterData_NewObject(data); } -static PyObject * -pyobject_repr_from_null(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - return PyObject_Repr(NULL); -} +static PyMethodDef ml; static PyObject * -pyobject_str_from_null(PyObject *self, PyObject *Py_UNUSED(ignored)) +create_cfunction(PyObject *self, PyObject *args) { - return PyObject_Str(NULL); + return PyCFunction_NewEx(&ml, self, NULL); } +static PyMethodDef ml = { + "create_cfunction", + create_cfunction, + METH_NOARGS, + NULL +}; + static PyObject * -pyobject_bytes_from_null(PyObject *self, PyObject *Py_UNUSED(ignored)) +_test_incref(PyObject *ob) { - return PyObject_Bytes(NULL); + return Py_NewRef(ob); } static PyObject * -raise_exception(PyObject *self, PyObject *args) +test_xincref_doesnt_leak(PyObject *ob, PyObject *Py_UNUSED(ignored)) { - PyObject *exc; - PyObject *exc_args, *v; - int num_args, i; - - if (!PyArg_ParseTuple(args, "Oi:raise_exception", - &exc, &num_args)) - return NULL; - - exc_args = PyTuple_New(num_args); - if (exc_args == NULL) - return NULL; - for (i = 0; i < num_args; ++i) { - v = PyLong_FromLong(i); - if (v == NULL) { - Py_DECREF(exc_args); - return NULL; - } - PyTuple_SET_ITEM(exc_args, i, v); - } - PyErr_SetObject(exc, exc_args); - Py_DECREF(exc_args); - return NULL; + PyObject *obj = PyLong_FromLong(0); + Py_XINCREF(_test_incref(obj)); + Py_DECREF(obj); + Py_DECREF(obj); + Py_DECREF(obj); + Py_RETURN_NONE; } static PyObject * -set_errno(PyObject *self, PyObject *args) +test_incref_doesnt_leak(PyObject *ob, PyObject *Py_UNUSED(ignored)) { - int new_errno; - - if (!PyArg_ParseTuple(args, "i:set_errno", &new_errno)) - return NULL; - - errno = new_errno; + PyObject *obj = PyLong_FromLong(0); + Py_INCREF(_test_incref(obj)); + Py_DECREF(obj); + Py_DECREF(obj); + Py_DECREF(obj); Py_RETURN_NONE; } static PyObject * -test_set_exception(PyObject *self, PyObject *new_exc) +test_xdecref_doesnt_leak(PyObject *ob, PyObject *Py_UNUSED(ignored)) { - PyObject *exc = PyErr_GetHandledException(); - assert(PyExceptionInstance_Check(exc) || exc == NULL); - - PyErr_SetHandledException(new_exc); - return exc; + Py_XDECREF(PyLong_FromLong(0)); + Py_RETURN_NONE; } static PyObject * -test_set_exc_info(PyObject *self, PyObject *args) +test_decref_doesnt_leak(PyObject *ob, PyObject *Py_UNUSED(ignored)) { - PyObject *orig_exc; - PyObject *new_type, *new_value, *new_tb; - PyObject *type, *value, *tb; - if (!PyArg_ParseTuple(args, "OOO:test_set_exc_info", - &new_type, &new_value, &new_tb)) - return NULL; - - PyErr_GetExcInfo(&type, &value, &tb); - - Py_INCREF(new_type); - Py_INCREF(new_value); - Py_INCREF(new_tb); - PyErr_SetExcInfo(new_type, new_value, new_tb); - - orig_exc = PyTuple_Pack(3, type ? type : Py_None, value ? value : Py_None, tb ? tb : Py_None); - Py_XDECREF(type); - Py_XDECREF(value); - Py_XDECREF(tb); - return orig_exc; + Py_DECREF(PyLong_FromLong(0)); + Py_RETURN_NONE; } -static int test_run_counter = 0; - static PyObject * -test_datetime_capi(PyObject *self, PyObject *args) { - if (PyDateTimeAPI) { - if (test_run_counter) { - /* Probably regrtest.py -R */ - Py_RETURN_NONE; - } - else { - PyErr_SetString(PyExc_AssertionError, - "PyDateTime_CAPI somehow initialized"); - return NULL; - } - } - test_run_counter++; - PyDateTime_IMPORT; +test_structseq_newtype_doesnt_leak(PyObject *Py_UNUSED(self), + PyObject *Py_UNUSED(args)) +{ + PyStructSequence_Desc descr; + PyStructSequence_Field descr_fields[3]; - if (PyDateTimeAPI) - Py_RETURN_NONE; - else - return NULL; -} + descr_fields[0] = (PyStructSequence_Field){"foo", "foo value"}; + descr_fields[1] = (PyStructSequence_Field){NULL, "some hidden value"}; + descr_fields[2] = (PyStructSequence_Field){0, NULL}; -/* Functions exposing the C API type checking for testing */ -#define MAKE_DATETIME_CHECK_FUNC(check_method, exact_method) \ - PyObject *obj; \ - int exact = 0; \ - if (!PyArg_ParseTuple(args, "O|p", &obj, &exact)) { \ - return NULL; \ - } \ - int rv = exact?exact_method(obj):check_method(obj); \ - if (rv) { \ - Py_RETURN_TRUE; \ - } else { \ - Py_RETURN_FALSE; \ - } + descr.name = "_testcapi.test_descr"; + descr.doc = "This is used to test for memory leaks in NewType"; + descr.fields = descr_fields; + descr.n_in_sequence = 1; -static PyObject * -datetime_check_date(PyObject *self, PyObject *args) { - MAKE_DATETIME_CHECK_FUNC(PyDate_Check, PyDate_CheckExact) -} + PyTypeObject* structseq_type = PyStructSequence_NewType(&descr); + assert(structseq_type != NULL); + assert(PyType_Check(structseq_type)); + assert(PyType_FastSubclass(structseq_type, Py_TPFLAGS_TUPLE_SUBCLASS)); + Py_DECREF(structseq_type); -static PyObject * -datetime_check_time(PyObject *self, PyObject *args) { - MAKE_DATETIME_CHECK_FUNC(PyTime_Check, PyTime_CheckExact) + Py_RETURN_NONE; } static PyObject * -datetime_check_datetime(PyObject *self, PyObject *args) { - MAKE_DATETIME_CHECK_FUNC(PyDateTime_Check, PyDateTime_CheckExact) -} +test_structseq_newtype_null_descr_doc(PyObject *Py_UNUSED(self), + PyObject *Py_UNUSED(args)) +{ + PyStructSequence_Field descr_fields[1] = { + (PyStructSequence_Field){NULL, NULL} + }; + // Test specifically for NULL .doc field. + PyStructSequence_Desc descr = {"_testcapi.test_descr", NULL, &descr_fields[0], 0}; -static PyObject * -datetime_check_delta(PyObject *self, PyObject *args) { - MAKE_DATETIME_CHECK_FUNC(PyDelta_Check, PyDelta_CheckExact) -} + PyTypeObject* structseq_type = PyStructSequence_NewType(&descr); + assert(structseq_type != NULL); + assert(PyType_Check(structseq_type)); + assert(PyType_FastSubclass(structseq_type, Py_TPFLAGS_TUPLE_SUBCLASS)); + Py_DECREF(structseq_type); -static PyObject * -datetime_check_tzinfo(PyObject *self, PyObject *args) { - MAKE_DATETIME_CHECK_FUNC(PyTZInfo_Check, PyTZInfo_CheckExact) + Py_RETURN_NONE; } - -/* Makes three variations on timezone representing UTC-5: - 1. timezone with offset and name from PyDateTimeAPI - 2. timezone with offset and name from PyTimeZone_FromOffsetAndName - 3. timezone with offset (no name) from PyTimeZone_FromOffset -*/ static PyObject * -make_timezones_capi(PyObject *self, PyObject *args) { - PyObject *offset = PyDelta_FromDSU(0, -18000, 0); - PyObject *name = PyUnicode_FromString("EST"); - - PyObject *est_zone_capi = PyDateTimeAPI->TimeZone_FromTimeZone(offset, name); - PyObject *est_zone_macro = PyTimeZone_FromOffsetAndName(offset, name); - PyObject *est_zone_macro_noname = PyTimeZone_FromOffset(offset); - - Py_DecRef(offset); - Py_DecRef(name); - - PyObject *rv = PyTuple_New(3); - - PyTuple_SET_ITEM(rv, 0, est_zone_capi); - PyTuple_SET_ITEM(rv, 1, est_zone_macro); - PyTuple_SET_ITEM(rv, 2, est_zone_macro_noname); - - return rv; +test_incref_decref_API(PyObject *ob, PyObject *Py_UNUSED(ignored)) +{ + PyObject *obj = PyLong_FromLong(0); + Py_IncRef(obj); + Py_DecRef(obj); + Py_DecRef(obj); + Py_RETURN_NONE; } -static PyObject * -get_timezones_offset_zero(PyObject *self, PyObject *args) { - PyObject *offset = PyDelta_FromDSU(0, 0, 0); - PyObject *name = PyUnicode_FromString(""); - - // These two should return the UTC singleton - PyObject *utc_singleton_0 = PyTimeZone_FromOffset(offset); - PyObject *utc_singleton_1 = PyTimeZone_FromOffsetAndName(offset, NULL); +typedef struct { + PyThread_type_lock start_event; + PyThread_type_lock exit_event; + PyObject *callback; +} test_c_thread_t; - // This one will return +00:00 zone, but not the UTC singleton - PyObject *non_utc_zone = PyTimeZone_FromOffsetAndName(offset, name); +static void +temporary_c_thread(void *data) +{ + test_c_thread_t *test_c_thread = data; + PyGILState_STATE state; + PyObject *res; - Py_DecRef(offset); - Py_DecRef(name); + PyThread_release_lock(test_c_thread->start_event); - PyObject *rv = PyTuple_New(3); - PyTuple_SET_ITEM(rv, 0, utc_singleton_0); - PyTuple_SET_ITEM(rv, 1, utc_singleton_1); - PyTuple_SET_ITEM(rv, 2, non_utc_zone); + /* Allocate a Python thread state for this thread */ + state = PyGILState_Ensure(); - return rv; -} + res = PyObject_CallNoArgs(test_c_thread->callback); + Py_CLEAR(test_c_thread->callback); -static PyObject * -get_timezone_utc_capi(PyObject* self, PyObject *args) { - int macro = 0; - if (!PyArg_ParseTuple(args, "|p", ¯o)) { - return NULL; + if (res == NULL) { + PyErr_Print(); } - if (macro) { - Py_INCREF(PyDateTime_TimeZone_UTC); - return PyDateTime_TimeZone_UTC; - } else { - Py_INCREF(PyDateTimeAPI->TimeZone_UTC); - return PyDateTimeAPI->TimeZone_UTC; + else { + Py_DECREF(res); } -} - -static PyObject * -get_date_fromdate(PyObject *self, PyObject *args) -{ - PyObject *rv = NULL; - int macro; - int year, month, day; - if (!PyArg_ParseTuple(args, "piii", ¯o, &year, &month, &day)) { - return NULL; - } + /* Destroy the Python thread state for this thread */ + PyGILState_Release(state); - if (macro) { - rv = PyDate_FromDate(year, month, day); - } - else { - rv = PyDateTimeAPI->Date_FromDate( - year, month, day, - PyDateTimeAPI->DateType); - } - return rv; + PyThread_release_lock(test_c_thread->exit_event); } +static test_c_thread_t test_c_thread; static PyObject * -get_datetime_fromdateandtime(PyObject *self, PyObject *args) +call_in_temporary_c_thread(PyObject *self, PyObject *args) { - PyObject *rv = NULL; - int macro; - int year, month, day; - int hour, minute, second, microsecond; - - if (!PyArg_ParseTuple(args, "piiiiiii", - ¯o, - &year, &month, &day, - &hour, &minute, &second, µsecond)) { + PyObject *res = NULL; + PyObject *callback = NULL; + long thread; + int wait = 1; + if (!PyArg_ParseTuple(args, "O|i", &callback, &wait)) + { return NULL; } - if (macro) { - rv = PyDateTime_FromDateAndTime( - year, month, day, - hour, minute, second, microsecond); - } - else { - rv = PyDateTimeAPI->DateTime_FromDateAndTime( - year, month, day, - hour, minute, second, microsecond, - Py_None, - PyDateTimeAPI->DateTimeType); + test_c_thread.start_event = PyThread_allocate_lock(); + test_c_thread.exit_event = PyThread_allocate_lock(); + test_c_thread.callback = NULL; + if (!test_c_thread.start_event || !test_c_thread.exit_event) { + PyErr_SetString(PyExc_RuntimeError, "could not allocate lock"); + goto exit; } - return rv; -} -static PyObject * -get_datetime_fromdateandtimeandfold(PyObject *self, PyObject *args) -{ - PyObject *rv = NULL; - int macro; - int year, month, day; - int hour, minute, second, microsecond, fold; + test_c_thread.callback = Py_NewRef(callback); - if (!PyArg_ParseTuple(args, "piiiiiiii", - ¯o, - &year, &month, &day, - &hour, &minute, &second, µsecond, - &fold)) { - return NULL; - } + PyThread_acquire_lock(test_c_thread.start_event, 1); + PyThread_acquire_lock(test_c_thread.exit_event, 1); - if (macro) { - rv = PyDateTime_FromDateAndTimeAndFold( - year, month, day, - hour, minute, second, microsecond, - fold); - } - else { - rv = PyDateTimeAPI->DateTime_FromDateAndTimeAndFold( - year, month, day, - hour, minute, second, microsecond, - Py_None, - fold, - PyDateTimeAPI->DateTimeType); + thread = PyThread_start_new_thread(temporary_c_thread, &test_c_thread); + if (thread == -1) { + PyErr_SetString(PyExc_RuntimeError, "unable to start the thread"); + PyThread_release_lock(test_c_thread.start_event); + PyThread_release_lock(test_c_thread.exit_event); + goto exit; } - return rv; -} -static PyObject * -get_time_fromtime(PyObject *self, PyObject *args) -{ - PyObject *rv = NULL; - int macro; - int hour, minute, second, microsecond; - - if (!PyArg_ParseTuple(args, "piiii", - ¯o, - &hour, &minute, &second, µsecond)) { - return NULL; - } + PyThread_acquire_lock(test_c_thread.start_event, 1); + PyThread_release_lock(test_c_thread.start_event); - if (macro) { - rv = PyTime_FromTime(hour, minute, second, microsecond); - } - else { - rv = PyDateTimeAPI->Time_FromTime( - hour, minute, second, microsecond, - Py_None, - PyDateTimeAPI->TimeType); + if (!wait) { + Py_RETURN_NONE; } - return rv; -} -static PyObject * -get_time_fromtimeandfold(PyObject *self, PyObject *args) -{ - PyObject *rv = NULL; - int macro; - int hour, minute, second, microsecond, fold; + Py_BEGIN_ALLOW_THREADS + PyThread_acquire_lock(test_c_thread.exit_event, 1); + PyThread_release_lock(test_c_thread.exit_event); + Py_END_ALLOW_THREADS - if (!PyArg_ParseTuple(args, "piiiii", - ¯o, - &hour, &minute, &second, µsecond, - &fold)) { - return NULL; - } + res = Py_NewRef(Py_None); - if (macro) { - rv = PyTime_FromTimeAndFold(hour, minute, second, microsecond, fold); +exit: + Py_CLEAR(test_c_thread.callback); + if (test_c_thread.start_event) { + PyThread_free_lock(test_c_thread.start_event); + test_c_thread.start_event = NULL; } - else { - rv = PyDateTimeAPI->Time_FromTimeAndFold( - hour, minute, second, microsecond, - Py_None, - fold, - PyDateTimeAPI->TimeType); + if (test_c_thread.exit_event) { + PyThread_free_lock(test_c_thread.exit_event); + test_c_thread.exit_event = NULL; } - return rv; + return res; } static PyObject * -get_delta_fromdsu(PyObject *self, PyObject *args) +join_temporary_c_thread(PyObject *self, PyObject *Py_UNUSED(ignored)) { - PyObject *rv = NULL; - int macro; - int days, seconds, microseconds; - - if (!PyArg_ParseTuple(args, "piii", - ¯o, - &days, &seconds, µseconds)) { - return NULL; - } - - if (macro) { - rv = PyDelta_FromDSU(days, seconds, microseconds); - } - else { - rv = PyDateTimeAPI->Delta_FromDelta( - days, seconds, microseconds, 1, - PyDateTimeAPI->DeltaType); - } - - return rv; + Py_BEGIN_ALLOW_THREADS + PyThread_acquire_lock(test_c_thread.exit_event, 1); + PyThread_release_lock(test_c_thread.exit_event); + Py_END_ALLOW_THREADS + Py_CLEAR(test_c_thread.callback); + PyThread_free_lock(test_c_thread.start_event); + test_c_thread.start_event = NULL; + PyThread_free_lock(test_c_thread.exit_event); + test_c_thread.exit_event = NULL; + Py_RETURN_NONE; } -static PyObject * -get_date_fromtimestamp(PyObject* self, PyObject *args) +/* marshal */ + +static PyObject* +pymarshal_write_long_to_file(PyObject* self, PyObject *args) { - PyObject *tsargs = NULL, *ts = NULL, *rv = NULL; - int macro = 0; + long value; + PyObject *filename; + int version; + FILE *fp; - if (!PyArg_ParseTuple(args, "O|p", &ts, ¯o)) { + if (!PyArg_ParseTuple(args, "lOi:pymarshal_write_long_to_file", + &value, &filename, &version)) return NULL; - } - // Construct the argument tuple - if ((tsargs = PyTuple_Pack(1, ts)) == NULL) { + fp = _Py_fopen_obj(filename, "wb"); + if (fp == NULL) { + PyErr_SetFromErrno(PyExc_OSError); return NULL; } - // Pass along to the API function - if (macro) { - rv = PyDate_FromTimestamp(tsargs); - } - else { - rv = PyDateTimeAPI->Date_FromTimestamp( - (PyObject *)PyDateTimeAPI->DateType, tsargs - ); - } + PyMarshal_WriteLongToFile(value, fp, version); + assert(!PyErr_Occurred()); - Py_DECREF(tsargs); - return rv; + fclose(fp); + Py_RETURN_NONE; } -static PyObject * -get_datetime_fromtimestamp(PyObject* self, PyObject *args) +static PyObject* +pymarshal_write_object_to_file(PyObject* self, PyObject *args) { - int macro = 0; - int usetz = 0; - PyObject *tsargs = NULL, *ts = NULL, *tzinfo = Py_None, *rv = NULL; - if (!PyArg_ParseTuple(args, "OO|pp", &ts, &tzinfo, &usetz, ¯o)) { - return NULL; - } + PyObject *obj; + PyObject *filename; + int version; + FILE *fp; - // Construct the argument tuple - if (usetz) { - tsargs = PyTuple_Pack(2, ts, tzinfo); - } - else { - tsargs = PyTuple_Pack(1, ts); - } + if (!PyArg_ParseTuple(args, "OOi:pymarshal_write_object_to_file", + &obj, &filename, &version)) + return NULL; - if (tsargs == NULL) { + fp = _Py_fopen_obj(filename, "wb"); + if (fp == NULL) { + PyErr_SetFromErrno(PyExc_OSError); return NULL; } - // Pass along to the API function - if (macro) { - rv = PyDateTime_FromTimestamp(tsargs); - } - else { - rv = PyDateTimeAPI->DateTime_FromTimestamp( - (PyObject *)PyDateTimeAPI->DateTimeType, tsargs, NULL - ); - } + PyMarshal_WriteObjectToFile(obj, fp, version); + assert(!PyErr_Occurred()); - Py_DECREF(tsargs); - return rv; + fclose(fp); + Py_RETURN_NONE; } -static PyObject * -test_PyDateTime_GET(PyObject *self, PyObject *obj) +static PyObject* +pymarshal_read_short_from_file(PyObject* self, PyObject *args) { - int year, month, day; + int value; + long pos; + PyObject *filename; + FILE *fp; + + if (!PyArg_ParseTuple(args, "O:pymarshal_read_short_from_file", &filename)) + return NULL; + + fp = _Py_fopen_obj(filename, "rb"); + if (fp == NULL) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } - year = PyDateTime_GET_YEAR(obj); - month = PyDateTime_GET_MONTH(obj); - day = PyDateTime_GET_DAY(obj); + value = PyMarshal_ReadShortFromFile(fp); + pos = ftell(fp); - return Py_BuildValue("(iii)", year, month, day); + fclose(fp); + if (PyErr_Occurred()) + return NULL; + return Py_BuildValue("il", value, pos); } -static PyObject * -test_PyDateTime_DATE_GET(PyObject *self, PyObject *obj) +static PyObject* +pymarshal_read_long_from_file(PyObject* self, PyObject *args) { - int hour, minute, second, microsecond; + long value, pos; + PyObject *filename; + FILE *fp; + + if (!PyArg_ParseTuple(args, "O:pymarshal_read_long_from_file", &filename)) + return NULL; + + fp = _Py_fopen_obj(filename, "rb"); + if (fp == NULL) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } - hour = PyDateTime_DATE_GET_HOUR(obj); - minute = PyDateTime_DATE_GET_MINUTE(obj); - second = PyDateTime_DATE_GET_SECOND(obj); - microsecond = PyDateTime_DATE_GET_MICROSECOND(obj); - PyObject *tzinfo = PyDateTime_DATE_GET_TZINFO(obj); + value = PyMarshal_ReadLongFromFile(fp); + pos = ftell(fp); - return Py_BuildValue("(iiiiO)", hour, minute, second, microsecond, tzinfo); + fclose(fp); + if (PyErr_Occurred()) + return NULL; + return Py_BuildValue("ll", value, pos); } -static PyObject * -test_PyDateTime_TIME_GET(PyObject *self, PyObject *obj) +static PyObject* +pymarshal_read_last_object_from_file(PyObject* self, PyObject *args) { - int hour, minute, second, microsecond; + PyObject *filename; + if (!PyArg_ParseTuple(args, "O:pymarshal_read_last_object_from_file", &filename)) + return NULL; + + FILE *fp = _Py_fopen_obj(filename, "rb"); + if (fp == NULL) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } - hour = PyDateTime_TIME_GET_HOUR(obj); - minute = PyDateTime_TIME_GET_MINUTE(obj); - second = PyDateTime_TIME_GET_SECOND(obj); - microsecond = PyDateTime_TIME_GET_MICROSECOND(obj); - PyObject *tzinfo = PyDateTime_TIME_GET_TZINFO(obj); + PyObject *obj = PyMarshal_ReadLastObjectFromFile(fp); + long pos = ftell(fp); - return Py_BuildValue("(iiiiO)", hour, minute, second, microsecond, tzinfo); + fclose(fp); + if (obj == NULL) { + return NULL; + } + return Py_BuildValue("Nl", obj, pos); } -static PyObject * -test_PyDateTime_DELTA_GET(PyObject *self, PyObject *obj) +static PyObject* +pymarshal_read_object_from_file(PyObject* self, PyObject *args) { - int days, seconds, microseconds; + PyObject *filename; + if (!PyArg_ParseTuple(args, "O:pymarshal_read_object_from_file", &filename)) + return NULL; + + FILE *fp = _Py_fopen_obj(filename, "rb"); + if (fp == NULL) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } - days = PyDateTime_DELTA_GET_DAYS(obj); - seconds = PyDateTime_DELTA_GET_SECONDS(obj); - microseconds = PyDateTime_DELTA_GET_MICROSECONDS(obj); + PyObject *obj = PyMarshal_ReadObjectFromFile(fp); + long pos = ftell(fp); - return Py_BuildValue("(iii)", days, seconds, microseconds); + fclose(fp); + if (obj == NULL) { + return NULL; + } + return Py_BuildValue("Nl", obj, pos); } -/* test_thread_state spawns a thread of its own, and that thread releases - * `thread_done` when it's finished. The driver code has to know when the - * thread finishes, because the thread uses a PyObject (the callable) that - * may go away when the driver finishes. The former lack of this explicit - * synchronization caused rare segfaults, so rare that they were seen only - * on a Mac buildbot (although they were possible on any box). - */ -static PyThread_type_lock thread_done = NULL; - -static int -_make_call(void *callable) +static PyObject* +return_null_without_error(PyObject *self, PyObject *args) { - PyObject *rc; - int success; - PyGILState_STATE s = PyGILState_Ensure(); - rc = PyObject_CallNoArgs((PyObject *)callable); - success = (rc != NULL); - Py_XDECREF(rc); - PyGILState_Release(s); - return success; + /* invalid call: return NULL without setting an error, + * _Py_CheckFunctionResult() must detect such bug at runtime. */ + PyErr_Clear(); + return NULL; } -/* Same thing, but releases `thread_done` when it returns. This variant - * should be called only from threads spawned by test_thread_state(). - */ -static void -_make_call_from_thread(void *callable) +static PyObject* +return_result_with_error(PyObject *self, PyObject *args) { - _make_call(callable); - PyThread_release_lock(thread_done); + /* invalid call: return a result with an error set, + * _Py_CheckFunctionResult() must detect such bug at runtime. */ + PyErr_SetNone(PyExc_ValueError); + Py_RETURN_NONE; } static PyObject * -test_thread_state(PyObject *self, PyObject *args) +getitem_with_error(PyObject *self, PyObject *args) { - PyObject *fn; - int success = 1; - - if (!PyArg_ParseTuple(args, "O:test_thread_state", &fn)) - return NULL; - - if (!PyCallable_Check(fn)) { - PyErr_Format(PyExc_TypeError, "'%s' object is not callable", - Py_TYPE(fn)->tp_name); + PyObject *map, *key; + if (!PyArg_ParseTuple(args, "OO", &map, &key)) { return NULL; } - thread_done = PyThread_allocate_lock(); - if (thread_done == NULL) - return PyErr_NoMemory(); - PyThread_acquire_lock(thread_done, 1); + PyErr_SetString(PyExc_ValueError, "bug"); + return PyObject_GetItem(map, key); +} - /* Start a new thread with our callback. */ - PyThread_start_new_thread(_make_call_from_thread, fn); - /* Make the callback with the thread lock held by this thread */ - success &= _make_call(fn); - /* Do it all again, but this time with the thread-lock released */ - Py_BEGIN_ALLOW_THREADS - success &= _make_call(fn); - PyThread_acquire_lock(thread_done, 1); /* wait for thread to finish */ - Py_END_ALLOW_THREADS +static PyObject * +dict_get_version(PyObject *self, PyObject *args) +{ + PyDictObject *dict; + uint64_t version; - /* And once more with and without a thread - XXX - should use a lock and work out exactly what we are trying - to test <wink> - */ - Py_BEGIN_ALLOW_THREADS - PyThread_start_new_thread(_make_call_from_thread, fn); - success &= _make_call(fn); - PyThread_acquire_lock(thread_done, 1); /* wait for thread to finish */ - Py_END_ALLOW_THREADS + if (!PyArg_ParseTuple(args, "O!", &PyDict_Type, &dict)) + return NULL; - /* Release lock we acquired above. This is required on HP-UX. */ - PyThread_release_lock(thread_done); + _Py_COMP_DIAG_PUSH + _Py_COMP_DIAG_IGNORE_DEPR_DECLS + version = dict->ma_version_tag; + _Py_COMP_DIAG_POP - PyThread_free_lock(thread_done); - if (!success) - return NULL; - Py_RETURN_NONE; + static_assert(sizeof(unsigned long long) >= sizeof(version), + "version is larger than unsigned long long"); + return PyLong_FromUnsignedLongLong((unsigned long long)version); } -/* test Py_AddPendingCalls using threads */ -static int _pending_callback(void *arg) -{ - /* we assume the argument is callable object to which we own a reference */ - PyObject *callable = (PyObject *)arg; - PyObject *r = PyObject_CallNoArgs(callable); - Py_DECREF(callable); - Py_XDECREF(r); - return r != NULL ? 0 : -1; -} -/* The following requests n callbacks to _pending_callback. It can be - * run from any python thread. - */ static PyObject * -pending_threadfunc(PyObject *self, PyObject *arg) +raise_SIGINT_then_send_None(PyObject *self, PyObject *args) { - PyObject *callable; - int r; - if (PyArg_ParseTuple(arg, "O", &callable) == 0) + PyGenObject *gen; + + if (!PyArg_ParseTuple(args, "O!", &PyGen_Type, &gen)) return NULL; - /* create the reference for the callbackwhile we hold the lock */ - Py_INCREF(callable); + /* This is used in a test to check what happens if a signal arrives just + as we're in the process of entering a yield from chain (see + bpo-30039). - Py_BEGIN_ALLOW_THREADS - r = Py_AddPendingCall(&_pending_callback, callable); - Py_END_ALLOW_THREADS + Needs to be done in C, because: + - we don't have a Python wrapper for raise() + - we need to make sure that the Python-level signal handler doesn't run + *before* we enter the generator frame, which is impossible in Python + because we check for signals before every bytecode operation. + */ + raise(SIGINT); + return PyObject_CallMethod((PyObject *)gen, "send", "O", Py_None); +} - if (r<0) { - Py_DECREF(callable); /* unsuccessful add, destroy the extra reference */ - Py_RETURN_FALSE; + +static PyObject* +stack_pointer(PyObject *self, PyObject *args) +{ + int v = 5; + return PyLong_FromVoidPtr(&v); +} + + +#ifdef W_STOPCODE +static PyObject* +py_w_stopcode(PyObject *self, PyObject *args) +{ + int sig, status; + if (!PyArg_ParseTuple(args, "i", &sig)) { + return NULL; } - Py_RETURN_TRUE; + status = W_STOPCODE(sig); + return PyLong_FromLong(status); } +#endif + -/* Some tests of PyUnicode_FromFormat(). This needs more tests. */ static PyObject * -test_string_from_format(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - PyObject *result; - char *msg; - -#define CHECK_1_FORMAT(FORMAT, TYPE) \ - result = PyUnicode_FromFormat(FORMAT, (TYPE)1); \ - if (result == NULL) \ - return NULL; \ - if (!_PyUnicode_EqualToASCIIString(result, "1")) { \ - msg = FORMAT " failed at 1"; \ - goto Fail; \ - } \ - Py_DECREF(result) - - CHECK_1_FORMAT("%d", int); - CHECK_1_FORMAT("%ld", long); - /* The z width modifier was added in Python 2.5. */ - CHECK_1_FORMAT("%zd", Py_ssize_t); - - /* The u type code was added in Python 2.5. */ - CHECK_1_FORMAT("%u", unsigned int); - CHECK_1_FORMAT("%lu", unsigned long); - CHECK_1_FORMAT("%zu", size_t); - - /* "%lld" and "%llu" support added in Python 2.7. */ - CHECK_1_FORMAT("%llu", unsigned long long); - CHECK_1_FORMAT("%lld", long long); +test_pythread_tss_key_state(PyObject *self, PyObject *args) +{ + Py_tss_t tss_key = Py_tss_NEEDS_INIT; + if (PyThread_tss_is_created(&tss_key)) { + return raiseTestError("test_pythread_tss_key_state", + "TSS key not in an uninitialized state at " + "creation time"); + } + if (PyThread_tss_create(&tss_key) != 0) { + PyErr_SetString(PyExc_RuntimeError, "PyThread_tss_create failed"); + return NULL; + } + if (!PyThread_tss_is_created(&tss_key)) { + return raiseTestError("test_pythread_tss_key_state", + "PyThread_tss_create succeeded, " + "but with TSS key in an uninitialized state"); + } + if (PyThread_tss_create(&tss_key) != 0) { + return raiseTestError("test_pythread_tss_key_state", + "PyThread_tss_create unsuccessful with " + "an already initialized key"); + } +#define CHECK_TSS_API(expr) \ + (void)(expr); \ + if (!PyThread_tss_is_created(&tss_key)) { \ + return raiseTestError("test_pythread_tss_key_state", \ + "TSS key initialization state was not " \ + "preserved after calling " #expr); } + CHECK_TSS_API(PyThread_tss_set(&tss_key, NULL)); + CHECK_TSS_API(PyThread_tss_get(&tss_key)); +#undef CHECK_TSS_API + PyThread_tss_delete(&tss_key); + if (PyThread_tss_is_created(&tss_key)) { + return raiseTestError("test_pythread_tss_key_state", + "PyThread_tss_delete called, but did not " + "set the key state to uninitialized"); + } + Py_tss_t *ptr_key = PyThread_tss_alloc(); + if (ptr_key == NULL) { + PyErr_SetString(PyExc_RuntimeError, "PyThread_tss_alloc failed"); + return NULL; + } + if (PyThread_tss_is_created(ptr_key)) { + return raiseTestError("test_pythread_tss_key_state", + "TSS key not in an uninitialized state at " + "allocation time"); + } + PyThread_tss_free(ptr_key); + ptr_key = NULL; Py_RETURN_NONE; +} - Fail: - Py_XDECREF(result); - return raiseTestError("test_string_from_format", msg); -#undef CHECK_1_FORMAT +static PyObject* +new_hamt(PyObject *self, PyObject *args) +{ + return _PyContext_NewHamtForTests(); } -static PyObject * -test_unicode_compare_with_ascii(PyObject *self, PyObject *Py_UNUSED(ignored)) { - PyObject *py_s = PyUnicode_FromStringAndSize("str\0", 4); - int result; - if (py_s == NULL) +/* def bad_get(self, obj, cls): + cls() + return repr(self) +*/ +static PyObject* +bad_get(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *self, *obj, *cls; + if (!_PyArg_UnpackStack(args, nargs, "bad_get", 3, 3, &self, &obj, &cls)) { return NULL; - result = PyUnicode_CompareWithASCIIString(py_s, "str"); - Py_DECREF(py_s); - if (!result) { - PyErr_SetString(TestError, "Python string ending in NULL " - "should not compare equal to c string."); + } + + PyObject *res = PyObject_CallNoArgs(cls); + if (res == NULL) { return NULL; } - Py_RETURN_NONE; + Py_DECREF(res); + + return PyObject_Repr(self); } -/* This is here to provide a docstring for test_descr. */ + +#ifdef Py_REF_DEBUG static PyObject * -test_with_docstring(PyObject *self, PyObject *Py_UNUSED(ignored)) +negative_refcount(PyObject *self, PyObject *Py_UNUSED(args)) { + PyObject *obj = PyUnicode_FromString("negative_refcount"); + if (obj == NULL) { + return NULL; + } + assert(Py_REFCNT(obj) == 1); + + Py_SET_REFCNT(obj, 0); + /* Py_DECREF() must call _Py_NegativeRefcount() and abort Python */ + Py_DECREF(obj); + Py_RETURN_NONE; } -/* Test PyOS_string_to_double. */ static PyObject * -test_string_to_double(PyObject *self, PyObject *Py_UNUSED(ignored)) { - double result; - const char *msg; - -#define CHECK_STRING(STR, expected) \ - result = PyOS_string_to_double(STR, NULL, NULL); \ - if (result == -1.0 && PyErr_Occurred()) \ - return NULL; \ - if (result != (double)expected) { \ - msg = "conversion of " STR " to float failed"; \ - goto fail; \ - } - -#define CHECK_INVALID(STR) \ - result = PyOS_string_to_double(STR, NULL, NULL); \ - if (result == -1.0 && PyErr_Occurred()) { \ - if (PyErr_ExceptionMatches(PyExc_ValueError)) \ - PyErr_Clear(); \ - else \ - return NULL; \ - } \ - else { \ - msg = "conversion of " STR " didn't raise ValueError"; \ - goto fail; \ +decref_freed_object(PyObject *self, PyObject *Py_UNUSED(args)) +{ + PyObject *obj = PyUnicode_FromString("decref_freed_object"); + if (obj == NULL) { + return NULL; } + assert(Py_REFCNT(obj) == 1); - CHECK_STRING("0.1", 0.1); - CHECK_STRING("1.234", 1.234); - CHECK_STRING("-1.35", -1.35); - CHECK_STRING(".1e01", 1.0); - CHECK_STRING("2.e-2", 0.02); + // Deallocate the memory + Py_DECREF(obj); + // obj is a now a dangling pointer - CHECK_INVALID(" 0.1"); - CHECK_INVALID("\t\n-3"); - CHECK_INVALID(".123 "); - CHECK_INVALID("3\n"); - CHECK_INVALID("123abc"); + // gh-109496: If Python is built in debug mode, Py_DECREF() must call + // _Py_NegativeRefcount() and abort Python. + Py_DECREF(obj); Py_RETURN_NONE; - fail: - return raiseTestError("test_string_to_double", msg); -#undef CHECK_STRING -#undef CHECK_INVALID } +#endif -/* Coverage testing of capsule objects. */ +/* Functions for testing C calling conventions (METH_*) are named meth_*, + * e.g. "meth_varargs" for METH_VARARGS. + * + * They all return a tuple of their C-level arguments, with None instead + * of NULL and Python tuples instead of C arrays. + */ -static const char *capsule_name = "capsule name"; -static char *capsule_pointer = "capsule pointer"; -static char *capsule_context = "capsule context"; -static const char *capsule_error = NULL; -static int -capsule_destructor_call_count = 0; -static void -capsule_destructor(PyObject *o) { - capsule_destructor_call_count++; - if (PyCapsule_GetContext(o) != capsule_context) { - capsule_error = "context did not match in destructor!"; - } else if (PyCapsule_GetDestructor(o) != capsule_destructor) { - capsule_error = "destructor did not match in destructor! (woah!)"; - } else if (PyCapsule_GetName(o) != capsule_name) { - capsule_error = "name did not match in destructor!"; - } else if (PyCapsule_GetPointer(o, capsule_name) != capsule_pointer) { - capsule_error = "pointer did not match in destructor!"; +static PyObject* +_null_to_none(PyObject* obj) +{ + if (obj == NULL) { + Py_RETURN_NONE; } + return Py_NewRef(obj); } -typedef struct { - char *name; - char *module; - char *attribute; -} known_capsule; - -static PyObject * -test_capsule(PyObject *self, PyObject *Py_UNUSED(ignored)) +static PyObject* +meth_varargs(PyObject* self, PyObject* args) { - PyObject *object; - const char *error = NULL; - void *pointer; - void *pointer2; - known_capsule known_capsules[] = { - #define KNOWN_CAPSULE(module, name) { module "." name, module, name } - KNOWN_CAPSULE("_socket", "CAPI"), - KNOWN_CAPSULE("_curses", "_C_API"), - KNOWN_CAPSULE("datetime", "datetime_CAPI"), - { NULL, NULL }, - }; - known_capsule *known = &known_capsules[0]; + return Py_BuildValue("NO", _null_to_none(self), args); +} -#define FAIL(x) { error = (x); goto exit; } +static PyObject* +meth_varargs_keywords(PyObject* self, PyObject* args, PyObject* kwargs) +{ + return Py_BuildValue("NON", _null_to_none(self), args, _null_to_none(kwargs)); +} -#define CHECK_DESTRUCTOR \ - if (capsule_error) { \ - FAIL(capsule_error); \ - } \ - else if (!capsule_destructor_call_count) { \ - FAIL("destructor not called!"); \ - } \ - capsule_destructor_call_count = 0; \ +static PyObject* +meth_o(PyObject* self, PyObject* obj) +{ + return Py_BuildValue("NO", _null_to_none(self), obj); +} - object = PyCapsule_New(capsule_pointer, capsule_name, capsule_destructor); - PyCapsule_SetContext(object, capsule_context); - capsule_destructor(object); - CHECK_DESTRUCTOR; - Py_DECREF(object); - CHECK_DESTRUCTOR; +static PyObject* +meth_noargs(PyObject* self, PyObject* ignored) +{ + return _null_to_none(self); +} - object = PyCapsule_New(known, "ignored", NULL); - PyCapsule_SetPointer(object, capsule_pointer); - PyCapsule_SetName(object, capsule_name); - PyCapsule_SetDestructor(object, capsule_destructor); - PyCapsule_SetContext(object, capsule_context); - capsule_destructor(object); - CHECK_DESTRUCTOR; - /* intentionally access using the wrong name */ - pointer2 = PyCapsule_GetPointer(object, "the wrong name"); - if (!PyErr_Occurred()) { - FAIL("PyCapsule_GetPointer should have failed but did not!"); - } - PyErr_Clear(); - if (pointer2) { - if (pointer2 == capsule_pointer) { - FAIL("PyCapsule_GetPointer should not have" - " returned the internal pointer!"); - } else { - FAIL("PyCapsule_GetPointer should have " - "returned NULL pointer but did not!"); - } +static PyObject* +_fastcall_to_tuple(PyObject* const* args, Py_ssize_t nargs) +{ + PyObject *tuple = PyTuple_New(nargs); + if (tuple == NULL) { + return NULL; } - PyCapsule_SetDestructor(object, NULL); - Py_DECREF(object); - if (capsule_destructor_call_count) { - FAIL("destructor called when it should not have been!"); + for (Py_ssize_t i=0; i < nargs; i++) { + Py_INCREF(args[i]); + PyTuple_SET_ITEM(tuple, i, args[i]); } + return tuple; +} - for (known = &known_capsules[0]; known->module != NULL; known++) { - /* yeah, ordinarily I wouldn't do this either, - but it's fine for this test harness. - */ - static char buffer[256]; -#undef FAIL -#define FAIL(x) \ - { \ - sprintf(buffer, "%s module: \"%s\" attribute: \"%s\"", \ - x, known->module, known->attribute); \ - error = buffer; \ - goto exit; \ - } \ - - PyObject *module = PyImport_ImportModule(known->module); - if (module) { - pointer = PyCapsule_Import(known->name, 0); - if (!pointer) { - Py_DECREF(module); - FAIL("PyCapsule_GetPointer returned NULL unexpectedly!"); - } - object = PyObject_GetAttrString(module, known->attribute); - if (!object) { - Py_DECREF(module); - return NULL; - } - pointer2 = PyCapsule_GetPointer(object, - "weebles wobble but they don't fall down"); - if (!PyErr_Occurred()) { - Py_DECREF(object); - Py_DECREF(module); - FAIL("PyCapsule_GetPointer should have failed but did not!"); - } - PyErr_Clear(); - if (pointer2) { - Py_DECREF(module); - Py_DECREF(object); - if (pointer2 == pointer) { - FAIL("PyCapsule_GetPointer should not have" - " returned its internal pointer!"); - } else { - FAIL("PyCapsule_GetPointer should have" - " returned NULL pointer but did not!"); - } - } - Py_DECREF(object); - Py_DECREF(module); - } - else - PyErr_Clear(); - } +static PyObject* +meth_fastcall(PyObject* self, PyObject* const* args, Py_ssize_t nargs) +{ + return Py_BuildValue( + "NN", _null_to_none(self), _fastcall_to_tuple(args, nargs) + ); +} - exit: - if (error) { - return raiseTestError("test_capsule", error); +static PyObject* +meth_fastcall_keywords(PyObject* self, PyObject* const* args, + Py_ssize_t nargs, PyObject* kwargs) +{ + PyObject *pyargs = _fastcall_to_tuple(args, nargs); + if (pyargs == NULL) { + return NULL; } - Py_RETURN_NONE; -#undef FAIL + assert(args != NULL || nargs == 0); + PyObject* const* args_offset = args == NULL ? NULL : args + nargs; + PyObject *pykwargs = PyObject_Vectorcall((PyObject*)&PyDict_Type, + args_offset, 0, kwargs); + return Py_BuildValue("NNN", _null_to_none(self), pyargs, pykwargs); } -#ifdef HAVE_GETTIMEOFDAY -/* Profiling of integer performance */ -static void print_delta(int test, struct timeval *s, struct timeval *e) +static PyObject* +pynumber_tobase(PyObject *module, PyObject *args) { - e->tv_sec -= s->tv_sec; - e->tv_usec -= s->tv_usec; - if (e->tv_usec < 0) { - e->tv_sec -=1; - e->tv_usec += 1000000; + PyObject *obj; + int base; + if (!PyArg_ParseTuple(args, "Oi:pynumber_tobase", + &obj, &base)) { + return NULL; } - printf("Test %d: %d.%06ds\n", test, (int)e->tv_sec, (int)e->tv_usec); + return PyNumber_ToBase(obj, base); } -static PyObject * -profile_int(PyObject *self, PyObject* args) +static PyObject* +test_set_type_size(PyObject *self, PyObject *Py_UNUSED(ignored)) { - int i, k; - struct timeval start, stop; - PyObject *single, **multiple, *op1, *result; - - /* Test 1: Allocate and immediately deallocate - many small integers */ - gettimeofday(&start, NULL); - for(k=0; k < 20000; k++) - for(i=0; i < 1000; i++) { - single = PyLong_FromLong(i); - Py_DECREF(single); - } - gettimeofday(&stop, NULL); - print_delta(1, &start, &stop); + PyObject *obj = PyList_New(0); + if (obj == NULL) { + return NULL; + } - /* Test 2: Allocate and immediately deallocate - many large integers */ - gettimeofday(&start, NULL); - for(k=0; k < 20000; k++) - for(i=0; i < 1000; i++) { - single = PyLong_FromLong(i+1000000); - Py_DECREF(single); - } - gettimeofday(&stop, NULL); - print_delta(2, &start, &stop); + // Ensure that following tests don't modify the object, + // to ensure that Py_DECREF() will not crash. + assert(Py_TYPE(obj) == &PyList_Type); + assert(Py_SIZE(obj) == 0); - /* Test 3: Allocate a few integers, then release - them all simultaneously. */ - multiple = malloc(sizeof(PyObject*) * 1000); - if (multiple == NULL) - return PyErr_NoMemory(); - gettimeofday(&start, NULL); - for(k=0; k < 20000; k++) { - for(i=0; i < 1000; i++) { - multiple[i] = PyLong_FromLong(i+1000000); - } - for(i=0; i < 1000; i++) { - Py_DECREF(multiple[i]); - } - } - gettimeofday(&stop, NULL); - print_delta(3, &start, &stop); - free(multiple); + // bpo-39573: Test Py_SET_TYPE() and Py_SET_SIZE() functions. + Py_SET_TYPE(obj, &PyList_Type); + Py_SET_SIZE(obj, 0); - /* Test 4: Allocate many integers, then release - them all simultaneously. */ - multiple = malloc(sizeof(PyObject*) * 1000000); - if (multiple == NULL) - return PyErr_NoMemory(); - gettimeofday(&start, NULL); - for(k=0; k < 20; k++) { - for(i=0; i < 1000000; i++) { - multiple[i] = PyLong_FromLong(i+1000000); - } - for(i=0; i < 1000000; i++) { - Py_DECREF(multiple[i]); - } - } - gettimeofday(&stop, NULL); - print_delta(4, &start, &stop); - free(multiple); + Py_DECREF(obj); + Py_RETURN_NONE; +} - /* Test 5: Allocate many integers < 32000 */ - multiple = malloc(sizeof(PyObject*) * 1000000); - if (multiple == NULL) - return PyErr_NoMemory(); - gettimeofday(&start, NULL); - for(k=0; k < 10; k++) { - for(i=0; i < 1000000; i++) { - multiple[i] = PyLong_FromLong(i+1000); - } - for(i=0; i < 1000000; i++) { - Py_DECREF(multiple[i]); - } - } - gettimeofday(&stop, NULL); - print_delta(5, &start, &stop); - free(multiple); - /* Test 6: Perform small int addition */ - op1 = PyLong_FromLong(1); - gettimeofday(&start, NULL); - for(i=0; i < 10000000; i++) { - result = PyNumber_Add(op1, op1); - Py_DECREF(result); +// Test Py_CLEAR() macro +static PyObject* +test_py_clear(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + // simple case with a variable + PyObject *obj = PyList_New(0); + if (obj == NULL) { + return NULL; } - gettimeofday(&stop, NULL); - Py_DECREF(op1); - print_delta(6, &start, &stop); + Py_CLEAR(obj); + assert(obj == NULL); - /* Test 7: Perform medium int addition */ - op1 = PyLong_FromLong(1000); - if (op1 == NULL) + // gh-98724: complex case, Py_CLEAR() argument has a side effect + PyObject* array[1]; + array[0] = PyList_New(0); + if (array[0] == NULL) { return NULL; - gettimeofday(&start, NULL); - for(i=0; i < 10000000; i++) { - result = PyNumber_Add(op1, op1); - Py_XDECREF(result); } - gettimeofday(&stop, NULL); - Py_DECREF(op1); - print_delta(7, &start, &stop); + + PyObject **p = array; + Py_CLEAR(*p++); + assert(array[0] == NULL); + assert(p == array + 1); Py_RETURN_NONE; } -#endif -/* To test the format of tracebacks as printed out. */ -static PyObject * -traceback_print(PyObject *self, PyObject *args) + +// Test Py_SETREF() and Py_XSETREF() macros, similar to test_py_clear() +static PyObject* +test_py_setref(PyObject *self, PyObject *Py_UNUSED(ignored)) { - PyObject *file; - PyObject *traceback; - int result; + // Py_SETREF() simple case with a variable + PyObject *obj = PyList_New(0); + if (obj == NULL) { + return NULL; + } + Py_SETREF(obj, NULL); + assert(obj == NULL); - if (!PyArg_ParseTuple(args, "OO:traceback_print", - &traceback, &file)) + // Py_XSETREF() simple case with a variable + PyObject *obj2 = PyList_New(0); + if (obj2 == NULL) { return NULL; + } + Py_XSETREF(obj2, NULL); + assert(obj2 == NULL); + // test Py_XSETREF() when the argument is NULL + Py_XSETREF(obj2, NULL); + assert(obj2 == NULL); - result = PyTraceBack_Print(traceback, file); - if (result < 0) + // gh-98724: complex case, Py_SETREF() argument has a side effect + PyObject* array[1]; + array[0] = PyList_New(0); + if (array[0] == NULL) { return NULL; - Py_RETURN_NONE; -} + } -/* To test the format of exceptions as printed out. */ -static PyObject * -exception_print(PyObject *self, PyObject *args) -{ - PyObject *value; - PyObject *tb = NULL; + PyObject **p = array; + Py_SETREF(*p++, NULL); + assert(array[0] == NULL); + assert(p == array + 1); - if (!PyArg_ParseTuple(args, "O:exception_print", - &value)) { + // gh-98724: complex case, Py_XSETREF() argument has a side effect + PyObject* array2[1]; + array2[0] = PyList_New(0); + if (array2[0] == NULL) { return NULL; } - if (PyExceptionInstance_Check(value)) { - tb = PyException_GetTraceback(value); - } + PyObject **p2 = array2; + Py_XSETREF(*p2++, NULL); + assert(array2[0] == NULL); + assert(p2 == array2 + 1); - PyErr_Display((PyObject *) Py_TYPE(value), value, tb); - Py_XDECREF(tb); + // test Py_XSETREF() when the argument is NULL + p2 = array2; + Py_XSETREF(*p2++, NULL); + assert(array2[0] == NULL); + assert(p2 == array2 + 1); Py_RETURN_NONE; } +#define TEST_REFCOUNT() \ + do { \ + PyObject *obj = PyList_New(0); \ + if (obj == NULL) { \ + return NULL; \ + } \ + assert(Py_REFCNT(obj) == 1); \ + \ + /* test Py_NewRef() */ \ + PyObject *ref = Py_NewRef(obj); \ + assert(ref == obj); \ + assert(Py_REFCNT(obj) == 2); \ + Py_DECREF(ref); \ + \ + /* test Py_XNewRef() */ \ + PyObject *xref = Py_XNewRef(obj); \ + assert(xref == obj); \ + assert(Py_REFCNT(obj) == 2); \ + Py_DECREF(xref); \ + \ + assert(Py_XNewRef(NULL) == NULL); \ + \ + Py_DECREF(obj); \ + Py_RETURN_NONE; \ + } while (0) \ -/* reliably raise a MemoryError */ -static PyObject * -raise_memoryerror(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - PyErr_NoMemory(); - return NULL; -} - -/* Issue 6012 */ -static PyObject *str1, *str2; -static int -failing_converter(PyObject *obj, void *arg) -{ - /* Clone str1, then let the conversion fail. */ - assert(str1); - str2 = str1; - Py_INCREF(str2); - return 0; -} +// Test Py_NewRef() and Py_XNewRef() macros static PyObject* -argparsing(PyObject *o, PyObject *args) +test_refcount_macros(PyObject *self, PyObject *Py_UNUSED(ignored)) { - PyObject *res; - str1 = str2 = NULL; - if (!PyArg_ParseTuple(args, "O&O&", - PyUnicode_FSConverter, &str1, - failing_converter, &str2)) { - if (!str2) - /* argument converter not called? */ - return NULL; - /* Should be 1 */ - res = PyLong_FromSsize_t(Py_REFCNT(str2)); - Py_DECREF(str2); - PyErr_Clear(); - return res; - } - Py_RETURN_NONE; + TEST_REFCOUNT(); } -/* To test that the result of PyCode_NewEmpty has the right members. */ -static PyObject * -code_newempty(PyObject *self, PyObject *args) -{ - const char *filename; - const char *funcname; - int firstlineno; - - if (!PyArg_ParseTuple(args, "ssi:code_newempty", - &filename, &funcname, &firstlineno)) - return NULL; - - return (PyObject *)PyCode_NewEmpty(filename, funcname, firstlineno); -} +#undef Py_NewRef +#undef Py_XNewRef -/* Test PyErr_NewExceptionWithDoc (also exercise PyErr_NewException). - Run via Lib/test/test_exceptions.py */ -static PyObject * -make_exception_with_doc(PyObject *self, PyObject *args, PyObject *kwargs) +// Test Py_NewRef() and Py_XNewRef() functions, after undefining macros. +static PyObject* +test_refcount_funcs(PyObject *self, PyObject *Py_UNUSED(ignored)) { - const char *name; - const char *doc = NULL; - PyObject *base = NULL; - PyObject *dict = NULL; + TEST_REFCOUNT(); +} - static char *kwlist[] = {"name", "doc", "base", "dict", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, - "s|sOO:make_exception_with_doc", kwlist, - &name, &doc, &base, &dict)) - return NULL; +// Test Py_Is() function +#define TEST_PY_IS() \ + do { \ + PyObject *o_none = Py_None; \ + PyObject *o_true = Py_True; \ + PyObject *o_false = Py_False; \ + PyObject *obj = PyList_New(0); \ + if (obj == NULL) { \ + return NULL; \ + } \ + \ + /* test Py_Is() */ \ + assert(Py_Is(obj, obj)); \ + assert(!Py_Is(obj, o_none)); \ + \ + /* test Py_None */ \ + assert(Py_Is(o_none, o_none)); \ + assert(!Py_Is(obj, o_none)); \ + \ + /* test Py_True */ \ + assert(Py_Is(o_true, o_true)); \ + assert(!Py_Is(o_false, o_true)); \ + assert(!Py_Is(obj, o_true)); \ + \ + /* test Py_False */ \ + assert(Py_Is(o_false, o_false)); \ + assert(!Py_Is(o_true, o_false)); \ + assert(!Py_Is(obj, o_false)); \ + \ + Py_DECREF(obj); \ + Py_RETURN_NONE; \ + } while (0) - return PyErr_NewExceptionWithDoc(name, doc, base, dict); +// Test Py_Is() macro +static PyObject* +test_py_is_macros(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + TEST_PY_IS(); } -static PyObject * -make_memoryview_from_NULL_pointer(PyObject *self, PyObject *Py_UNUSED(ignored)) +#undef Py_Is + +// Test Py_Is() function, after undefining its macro. +static PyObject* +test_py_is_funcs(PyObject *self, PyObject *Py_UNUSED(ignored)) { - Py_buffer info; - if (PyBuffer_FillInfo(&info, NULL, NULL, 1, 1, PyBUF_FULL_RO) < 0) - return NULL; - return PyMemoryView_FromBuffer(&info); + TEST_PY_IS(); } + +// type->tp_version_tag static PyObject * -test_from_contiguous(PyObject* self, PyObject *Py_UNUSED(ignored)) +type_get_version(PyObject *self, PyObject *type) { - int data[9] = {-1,-1,-1,-1,-1,-1,-1,-1,-1}; - int init[5] = {0, 1, 2, 3, 4}; - Py_ssize_t itemsize = sizeof(int); - Py_ssize_t shape = 5; - Py_ssize_t strides = 2 * itemsize; - Py_buffer view = { - data, - NULL, - 5 * itemsize, - itemsize, - 1, - 1, - NULL, - &shape, - &strides, - NULL, - NULL - }; - int *ptr; - int i; - - PyBuffer_FromContiguous(&view, init, view.len, 'C'); - ptr = view.buf; - for (i = 0; i < 5; i++) { - if (ptr[2*i] != i) { - PyErr_SetString(TestError, - "test_from_contiguous: incorrect result"); - return NULL; - } + if (!PyType_Check(type)) { + PyErr_SetString(PyExc_TypeError, "argument must be a type"); + return NULL; } - - view.buf = &data[8]; - view.strides[0] = -2 * itemsize; - - PyBuffer_FromContiguous(&view, init, view.len, 'C'); - ptr = view.buf; - for (i = 0; i < 5; i++) { - if (*(ptr-2*i) != i) { - PyErr_SetString(TestError, - "test_from_contiguous: incorrect result"); - return NULL; - } + PyObject *res = PyLong_FromUnsignedLong( + ((PyTypeObject *)type)->tp_version_tag); + if (res == NULL) { + assert(PyErr_Occurred()); + return NULL; } - - Py_RETURN_NONE; + return res; } -#if (defined(__linux__) || defined(__FreeBSD__)) && defined(__GNUC__) -extern PyTypeObject _PyBytesIOBuffer_Type; static PyObject * -test_pep3118_obsolete_write_locks(PyObject* self, PyObject *Py_UNUSED(ignored)) +type_assign_version(PyObject *self, PyObject *type) { - PyTypeObject *type = &_PyBytesIOBuffer_Type; - PyObject *b; - char *dummy[1]; - int ret, match; - - /* PyBuffer_FillInfo() */ - ret = PyBuffer_FillInfo(NULL, NULL, dummy, 1, 0, PyBUF_SIMPLE); - match = PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_BufferError); - PyErr_Clear(); - if (ret != -1 || match == 0) - goto error; - - /* bytesiobuf_getbuffer() */ - b = type->tp_alloc(type, 0); - if (b == NULL) { + if (!PyType_Check(type)) { + PyErr_SetString(PyExc_TypeError, "argument must be a type"); return NULL; } + int res = PyUnstable_Type_AssignVersionTag((PyTypeObject *)type); + return PyLong_FromLong(res); +} - ret = PyObject_GetBuffer(b, NULL, PyBUF_SIMPLE); - Py_DECREF(b); - match = PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_BufferError); - PyErr_Clear(); - if (ret != -1 || match == 0) - goto error; - - Py_RETURN_NONE; -error: - PyErr_SetString(TestError, - "test_pep3118_obsolete_write_locks: failure"); - return NULL; +static PyObject * +type_get_tp_bases(PyObject *self, PyObject *type) +{ + PyObject *bases = ((PyTypeObject *)type)->tp_bases; + if (bases == NULL) { + Py_RETURN_NONE; + } + return Py_NewRef(bases); } -#endif -/* This tests functions that historically supported write locks. It is - wrong to call getbuffer() with view==NULL and a compliant getbufferproc - is entitled to segfault in that case. */ static PyObject * -getbuffer_with_null_view(PyObject* self, PyObject *obj) +type_get_tp_mro(PyObject *self, PyObject *type) { - if (PyObject_GetBuffer(obj, NULL, PyBUF_SIMPLE) < 0) - return NULL; - - Py_RETURN_NONE; + PyObject *mro = ((PyTypeObject *)type)->tp_mro; + if (mro == NULL) { + Py_RETURN_NONE; + } + return Py_NewRef(mro); } -/* PyBuffer_SizeFromFormat() */ + +/* We only use 2 in test_capi/test_misc.py. */ +#define NUM_BASIC_STATIC_TYPES 2 +static PyTypeObject BasicStaticTypes[NUM_BASIC_STATIC_TYPES] = { +#define INIT_BASIC_STATIC_TYPE \ + { \ + PyVarObject_HEAD_INIT(NULL, 0) \ + .tp_name = "BasicStaticType", \ + .tp_basicsize = sizeof(PyObject), \ + } + INIT_BASIC_STATIC_TYPE, + INIT_BASIC_STATIC_TYPE, +#undef INIT_BASIC_STATIC_TYPE +}; +static int num_basic_static_types_used = 0; + static PyObject * -test_PyBuffer_SizeFromFormat(PyObject *self, PyObject *args) +get_basic_static_type(PyObject *self, PyObject *args) { - const char *format; - Py_ssize_t result; - - if (!PyArg_ParseTuple(args, "s:test_PyBuffer_SizeFromFormat", - &format)) { + PyObject *base = NULL; + if (!PyArg_ParseTuple(args, "|O", &base)) { return NULL; } + assert(base == NULL || PyType_Check(base)); - result = PyBuffer_SizeFromFormat(format); - if (result == -1) { + if(num_basic_static_types_used >= NUM_BASIC_STATIC_TYPES) { + PyErr_SetString(PyExc_RuntimeError, "no more available basic static types"); return NULL; } + PyTypeObject *cls = &BasicStaticTypes[num_basic_static_types_used++]; - return PyLong_FromSsize_t(result); + if (base != NULL) { + cls->tp_bases = Py_BuildValue("(O)", base); + if (cls->tp_bases == NULL) { + return NULL; + } + cls->tp_base = (PyTypeObject *)Py_NewRef(base); + } + if (PyType_Ready(cls) < 0) { + Py_DECREF(cls->tp_bases); + Py_DECREF(cls->tp_base); + return NULL; + } + return (PyObject *)cls; } -/* Test that the fatal error from not having a current thread doesn't - cause an infinite loop. Run via Lib/test/test_capi.py */ + +// Test PyThreadState C API static PyObject * -crash_no_current_thread(PyObject *self, PyObject *Py_UNUSED(ignored)) +test_tstate_capi(PyObject *self, PyObject *Py_UNUSED(args)) { - Py_BEGIN_ALLOW_THREADS - /* Using PyThreadState_Get() directly allows the test to pass in - !pydebug mode. However, the test only actually tests anything - in pydebug mode, since that's where the infinite loop was in - the first place. */ - PyThreadState_Get(); - Py_END_ALLOW_THREADS - return NULL; -} + // PyThreadState_Get() + PyThreadState *tstate = PyThreadState_Get(); + assert(tstate != NULL); -/* To run some code in a sub-interpreter. */ -static PyObject * -run_in_subinterp(PyObject *self, PyObject *args) -{ - const char *code; - int r; - PyThreadState *substate, *mainstate; - /* only initialise 'cflags.cf_flags' to test backwards compatibility */ - PyCompilerFlags cflags = {0}; + // PyThreadState_GET() + PyThreadState *tstate2 = PyThreadState_Get(); + assert(tstate2 == tstate); - if (!PyArg_ParseTuple(args, "s:run_in_subinterp", - &code)) - return NULL; + // private _PyThreadState_UncheckedGet() + PyThreadState *tstate3 = _PyThreadState_UncheckedGet(); + assert(tstate3 == tstate); - mainstate = PyThreadState_Get(); + // PyThreadState_EnterTracing(), PyThreadState_LeaveTracing() + PyThreadState_EnterTracing(tstate); + PyThreadState_LeaveTracing(tstate); - PyThreadState_Swap(NULL); + // PyThreadState_GetDict(): no tstate argument + PyObject *dict = PyThreadState_GetDict(); + // PyThreadState_GetDict() API can return NULL if PyDict_New() fails, + // but it should not occur in practice. + assert(dict != NULL); + assert(PyDict_Check(dict)); + // dict is a borrowed reference - substate = Py_NewInterpreter(); - if (substate == NULL) { - /* Since no new thread state was created, there is no exception to - propagate; raise a fresh one after swapping in the old thread - state. */ - PyThreadState_Swap(mainstate); - PyErr_SetString(PyExc_RuntimeError, "sub-interpreter creation failed"); - return NULL; - } - r = PyRun_SimpleStringFlags(code, &cflags); - Py_EndInterpreter(substate); + // private _PyThreadState_GetDict() + PyObject *dict2 = _PyThreadState_GetDict(tstate); + assert(dict2 == dict); + // dict2 is a borrowed reference - PyThreadState_Swap(mainstate); + // PyThreadState_GetInterpreter() + PyInterpreterState *interp = PyThreadState_GetInterpreter(tstate); + assert(interp != NULL); - return PyLong_FromLong(r); + // PyThreadState_GetFrame() + PyFrameObject*frame = PyThreadState_GetFrame(tstate); + assert(frame != NULL); + assert(PyFrame_Check(frame)); + Py_DECREF(frame); + + // PyThreadState_GetID() + uint64_t id = PyThreadState_GetID(tstate); + assert(id >= 1); + + Py_RETURN_NONE; } -static int -check_time_rounding(int round) +static PyObject * +frame_getlocals(PyObject *self, PyObject *frame) { - if (round != _PyTime_ROUND_FLOOR - && round != _PyTime_ROUND_CEILING - && round != _PyTime_ROUND_HALF_EVEN - && round != _PyTime_ROUND_UP) { - PyErr_SetString(PyExc_ValueError, "invalid rounding"); - return -1; + if (!PyFrame_Check(frame)) { + PyErr_SetString(PyExc_TypeError, "argument must be a frame"); + return NULL; } - return 0; + return PyFrame_GetLocals((PyFrameObject *)frame); } static PyObject * -test_pytime_object_to_time_t(PyObject *self, PyObject *args) +frame_getglobals(PyObject *self, PyObject *frame) { - PyObject *obj; - time_t sec; - int round; - if (!PyArg_ParseTuple(args, "Oi:pytime_object_to_time_t", &obj, &round)) - return NULL; - if (check_time_rounding(round) < 0) - return NULL; - if (_PyTime_ObjectToTime_t(obj, &sec, round) == -1) + if (!PyFrame_Check(frame)) { + PyErr_SetString(PyExc_TypeError, "argument must be a frame"); return NULL; - return _PyLong_FromTime_t(sec); + } + return PyFrame_GetGlobals((PyFrameObject *)frame); } static PyObject * -test_pytime_object_to_timeval(PyObject *self, PyObject *args) +frame_getgenerator(PyObject *self, PyObject *frame) { - PyObject *obj; - time_t sec; - long usec; - int round; - if (!PyArg_ParseTuple(args, "Oi:pytime_object_to_timeval", &obj, &round)) - return NULL; - if (check_time_rounding(round) < 0) - return NULL; - if (_PyTime_ObjectToTimeval(obj, &sec, &usec, round) == -1) + if (!PyFrame_Check(frame)) { + PyErr_SetString(PyExc_TypeError, "argument must be a frame"); return NULL; - return Py_BuildValue("Nl", _PyLong_FromTime_t(sec), usec); + } + return PyFrame_GetGenerator((PyFrameObject *)frame); } static PyObject * -test_pytime_object_to_timespec(PyObject *self, PyObject *args) +frame_getbuiltins(PyObject *self, PyObject *frame) { - PyObject *obj; - time_t sec; - long nsec; - int round; - if (!PyArg_ParseTuple(args, "Oi:pytime_object_to_timespec", &obj, &round)) - return NULL; - if (check_time_rounding(round) < 0) - return NULL; - if (_PyTime_ObjectToTimespec(obj, &sec, &nsec, round) == -1) + if (!PyFrame_Check(frame)) { + PyErr_SetString(PyExc_TypeError, "argument must be a frame"); return NULL; - return Py_BuildValue("Nl", _PyLong_FromTime_t(sec), nsec); + } + return PyFrame_GetBuiltins((PyFrameObject *)frame); } -static void -slot_tp_del(PyObject *self) +static PyObject * +frame_getlasti(PyObject *self, PyObject *frame) { - _Py_IDENTIFIER(__tp_del__); - PyObject *del, *res; - PyObject *error_type, *error_value, *error_traceback; - - /* Temporarily resurrect the object. */ - assert(Py_REFCNT(self) == 0); - Py_SET_REFCNT(self, 1); - - /* Save the current exception, if any. */ - PyErr_Fetch(&error_type, &error_value, &error_traceback); - - /* Execute __del__ method, if any. */ - del = _PyObject_LookupSpecialId(self, &PyId___tp_del__); - if (del != NULL) { - res = PyObject_CallNoArgs(del); - if (res == NULL) - PyErr_WriteUnraisable(del); - else - Py_DECREF(res); - Py_DECREF(del); - } - - /* Restore the saved exception. */ - PyErr_Restore(error_type, error_value, error_traceback); - - /* Undo the temporary resurrection; can't use DECREF here, it would - * cause a recursive call. - */ - assert(Py_REFCNT(self) > 0); - Py_SET_REFCNT(self, Py_REFCNT(self) - 1); - if (Py_REFCNT(self) == 0) { - /* this is the normal path out */ - return; + if (!PyFrame_Check(frame)) { + PyErr_SetString(PyExc_TypeError, "argument must be a frame"); + return NULL; } - - /* __del__ resurrected it! Make it look like the original Py_DECREF - * never happened. - */ - { - Py_ssize_t refcnt = Py_REFCNT(self); - _Py_NewReference(self); - Py_SET_REFCNT(self, refcnt); + int lasti = PyFrame_GetLasti((PyFrameObject *)frame); + if (lasti < 0) { + assert(lasti == -1); + Py_RETURN_NONE; } - assert(!PyType_IS_GC(Py_TYPE(self)) || PyObject_GC_IsTracked(self)); - /* If Py_REF_DEBUG macro is defined, _Py_NewReference() increased - _Py_RefTotal, so we need to undo that. */ -#ifdef Py_REF_DEBUG - _Py_RefTotal--; -#endif + return PyLong_FromLong(lasti); } static PyObject * -with_tp_del(PyObject *self, PyObject *args) +frame_new(PyObject *self, PyObject *args) { - PyObject *obj; - PyTypeObject *tp; - - if (!PyArg_ParseTuple(args, "O:with_tp_del", &obj)) + PyObject *code, *globals, *locals; + if (!PyArg_ParseTuple(args, "OOO", &code, &globals, &locals)) { return NULL; - tp = (PyTypeObject *) obj; - if (!PyType_Check(obj) || !PyType_HasFeature(tp, Py_TPFLAGS_HEAPTYPE)) { - PyErr_Format(PyExc_TypeError, - "heap type expected, got %R", obj); + } + if (!PyCode_Check(code)) { + PyErr_SetString(PyExc_TypeError, "argument must be a code object"); return NULL; } - tp->tp_del = slot_tp_del; - Py_INCREF(obj); - return obj; + PyThreadState *tstate = PyThreadState_Get(); + + return (PyObject *)PyFrame_New(tstate, (PyCodeObject *)code, globals, locals); } static PyObject * -without_gc(PyObject *Py_UNUSED(self), PyObject *obj) +test_frame_getvar(PyObject *self, PyObject *args) { - PyTypeObject *tp = (PyTypeObject*)obj; - if (!PyType_Check(obj) || !PyType_HasFeature(tp, Py_TPFLAGS_HEAPTYPE)) { - return PyErr_Format(PyExc_TypeError, "heap type expected, got %R", obj); + PyObject *frame, *name; + if (!PyArg_ParseTuple(args, "OO", &frame, &name)) { + return NULL; } - if (PyType_IS_GC(tp)) { - // Don't try this at home, kids: - tp->tp_flags -= Py_TPFLAGS_HAVE_GC; - tp->tp_free = PyObject_Del; - tp->tp_traverse = NULL; - tp->tp_clear = NULL; + if (!PyFrame_Check(frame)) { + PyErr_SetString(PyExc_TypeError, "argument must be a frame"); + return NULL; } - assert(!PyType_IS_GC(tp)); - Py_INCREF(obj); - return obj; -} - -static PyMethodDef ml; -static PyObject * -create_cfunction(PyObject *self, PyObject *args) -{ - return PyCFunction_NewEx(&ml, self, NULL); + return PyFrame_GetVar((PyFrameObject *)frame, name); } -static PyMethodDef ml = { - "create_cfunction", - create_cfunction, - METH_NOARGS, - NULL -}; - static PyObject * -_test_incref(PyObject *ob) +test_frame_getvarstring(PyObject *self, PyObject *args) { - Py_INCREF(ob); - return ob; -} + PyObject *frame; + const char *name; + if (!PyArg_ParseTuple(args, "Oy", &frame, &name)) { + return NULL; + } + if (!PyFrame_Check(frame)) { + PyErr_SetString(PyExc_TypeError, "argument must be a frame"); + return NULL; + } -static PyObject * -test_xincref_doesnt_leak(PyObject *ob, PyObject *Py_UNUSED(ignored)) -{ - PyObject *obj = PyLong_FromLong(0); - Py_XINCREF(_test_incref(obj)); - Py_DECREF(obj); - Py_DECREF(obj); - Py_DECREF(obj); - Py_RETURN_NONE; + return PyFrame_GetVarString((PyFrameObject *)frame, name); } + static PyObject * -test_incref_doesnt_leak(PyObject *ob, PyObject *Py_UNUSED(ignored)) +eval_get_func_name(PyObject *self, PyObject *func) { - PyObject *obj = PyLong_FromLong(0); - Py_INCREF(_test_incref(obj)); - Py_DECREF(obj); - Py_DECREF(obj); - Py_DECREF(obj); - Py_RETURN_NONE; + return PyUnicode_FromString(PyEval_GetFuncName(func)); } static PyObject * -test_xdecref_doesnt_leak(PyObject *ob, PyObject *Py_UNUSED(ignored)) +eval_get_func_desc(PyObject *self, PyObject *func) { - Py_XDECREF(PyLong_FromLong(0)); - Py_RETURN_NONE; + return PyUnicode_FromString(PyEval_GetFuncDesc(func)); } static PyObject * -test_decref_doesnt_leak(PyObject *ob, PyObject *Py_UNUSED(ignored)) +gen_get_code(PyObject *self, PyObject *gen) { - Py_DECREF(PyLong_FromLong(0)); - Py_RETURN_NONE; + if (!PyGen_Check(gen)) { + PyErr_SetString(PyExc_TypeError, "argument must be a generator object"); + return NULL; + } + return (PyObject *)PyGen_GetCode((PyGenObject *)gen); } static PyObject * -test_structseq_newtype_doesnt_leak(PyObject *Py_UNUSED(self), - PyObject *Py_UNUSED(args)) +eval_eval_code_ex(PyObject *mod, PyObject *pos_args) { - PyStructSequence_Desc descr; - PyStructSequence_Field descr_fields[3]; + PyObject *result = NULL; + PyObject *code; + PyObject *globals; + PyObject *locals = NULL; + PyObject *args = NULL; + PyObject *kwargs = NULL; + PyObject *defaults = NULL; + PyObject *kw_defaults = NULL; + PyObject *closure = NULL; - descr_fields[0] = (PyStructSequence_Field){"foo", "foo value"}; - descr_fields[1] = (PyStructSequence_Field){NULL, "some hidden value"}; - descr_fields[2] = (PyStructSequence_Field){0, NULL}; + PyObject **c_kwargs = NULL; - descr.name = "_testcapi.test_descr"; - descr.doc = "This is used to test for memory leaks in NewType"; - descr.fields = descr_fields; - descr.n_in_sequence = 1; + if (!PyArg_UnpackTuple(pos_args, + "eval_code_ex", + 2, + 8, + &code, + &globals, + &locals, + &args, + &kwargs, + &defaults, + &kw_defaults, + &closure)) + { + goto exit; + } - PyTypeObject* structseq_type = PyStructSequence_NewType(&descr); - assert(structseq_type != NULL); - assert(PyType_Check(structseq_type)); - assert(PyType_FastSubclass(structseq_type, Py_TPFLAGS_TUPLE_SUBCLASS)); - Py_DECREF(structseq_type); + if (!PyCode_Check(code)) { + PyErr_SetString(PyExc_TypeError, + "code must be a Python code object"); + goto exit; + } - Py_RETURN_NONE; -} + if (!PyDict_Check(globals)) { + PyErr_SetString(PyExc_TypeError, "globals must be a dict"); + goto exit; + } -static PyObject * -test_structseq_newtype_null_descr_doc(PyObject *Py_UNUSED(self), - PyObject *Py_UNUSED(args)) -{ - PyStructSequence_Field descr_fields[1] = { - (PyStructSequence_Field){NULL, NULL} - }; - // Test specifically for NULL .doc field. - PyStructSequence_Desc descr = {"_testcapi.test_descr", NULL, &descr_fields[0], 0}; + if (locals && !PyMapping_Check(locals)) { + PyErr_SetString(PyExc_TypeError, "locals must be a mapping"); + goto exit; + } + if (locals == Py_None) { + locals = NULL; + } - PyTypeObject* structseq_type = PyStructSequence_NewType(&descr); - assert(structseq_type != NULL); - assert(PyType_Check(structseq_type)); - assert(PyType_FastSubclass(structseq_type, Py_TPFLAGS_TUPLE_SUBCLASS)); - Py_DECREF(structseq_type); + PyObject **c_args = NULL; + Py_ssize_t c_args_len = 0; - Py_RETURN_NONE; -} + if (args) + { + if (!PyTuple_Check(args)) { + PyErr_SetString(PyExc_TypeError, "args must be a tuple"); + goto exit; + } else { + c_args = &PyTuple_GET_ITEM(args, 0); + c_args_len = PyTuple_Size(args); + } + } -static PyObject * -test_incref_decref_API(PyObject *ob, PyObject *Py_UNUSED(ignored)) -{ - PyObject *obj = PyLong_FromLong(0); - Py_IncRef(obj); - Py_DecRef(obj); - Py_DecRef(obj); - Py_RETURN_NONE; -} + Py_ssize_t c_kwargs_len = 0; -static PyObject * -test_pymem_alloc0(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - void *ptr; + if (kwargs) + { + if (!PyDict_Check(kwargs)) { + PyErr_SetString(PyExc_TypeError, "keywords must be a dict"); + goto exit; + } else { + c_kwargs_len = PyDict_Size(kwargs); + if (c_kwargs_len > 0) { + c_kwargs = PyMem_NEW(PyObject*, 2 * c_kwargs_len); + if (!c_kwargs) { + PyErr_NoMemory(); + goto exit; + } - ptr = PyMem_RawMalloc(0); - if (ptr == NULL) { - PyErr_SetString(PyExc_RuntimeError, "PyMem_RawMalloc(0) returns NULL"); - return NULL; - } - PyMem_RawFree(ptr); + Py_ssize_t i = 0; + Py_ssize_t pos = 0; - ptr = PyMem_RawCalloc(0, 0); - if (ptr == NULL) { - PyErr_SetString(PyExc_RuntimeError, "PyMem_RawCalloc(0, 0) returns NULL"); - return NULL; + while (PyDict_Next(kwargs, + &pos, + &c_kwargs[i], + &c_kwargs[i + 1])) + { + i += 2; + } + c_kwargs_len = i / 2; + /* XXX This is broken if the caller deletes dict items! */ + } + } } - PyMem_RawFree(ptr); - ptr = PyMem_Malloc(0); - if (ptr == NULL) { - PyErr_SetString(PyExc_RuntimeError, "PyMem_Malloc(0) returns NULL"); - return NULL; - } - PyMem_Free(ptr); - ptr = PyMem_Calloc(0, 0); - if (ptr == NULL) { - PyErr_SetString(PyExc_RuntimeError, "PyMem_Calloc(0, 0) returns NULL"); - return NULL; - } - PyMem_Free(ptr); + PyObject **c_defaults = NULL; + Py_ssize_t c_defaults_len = 0; - ptr = PyObject_Malloc(0); - if (ptr == NULL) { - PyErr_SetString(PyExc_RuntimeError, "PyObject_Malloc(0) returns NULL"); - return NULL; + if (defaults && PyTuple_Check(defaults)) { + c_defaults = &PyTuple_GET_ITEM(defaults, 0); + c_defaults_len = PyTuple_Size(defaults); } - PyObject_Free(ptr); - ptr = PyObject_Calloc(0, 0); - if (ptr == NULL) { - PyErr_SetString(PyExc_RuntimeError, "PyObject_Calloc(0, 0) returns NULL"); - return NULL; + if (kw_defaults && !PyDict_Check(kw_defaults)) { + PyErr_SetString(PyExc_TypeError, "kw_defaults must be a dict"); + goto exit; } - PyObject_Free(ptr); - Py_RETURN_NONE; -} - -typedef struct { - PyMemAllocatorEx alloc; + if (closure && !PyTuple_Check(closure)) { + PyErr_SetString(PyExc_TypeError, "closure must be a tuple of cells"); + goto exit; + } - size_t malloc_size; - size_t calloc_nelem; - size_t calloc_elsize; - void *realloc_ptr; - size_t realloc_new_size; - void *free_ptr; - void *ctx; -} alloc_hook_t; -static void* hook_malloc(void* ctx, size_t size) -{ - alloc_hook_t *hook = (alloc_hook_t *)ctx; - hook->ctx = ctx; - hook->malloc_size = size; - return hook->alloc.malloc(hook->alloc.ctx, size); -} + result = PyEval_EvalCodeEx( + code, + globals, + locals, + c_args, + (int)c_args_len, + c_kwargs, + (int)c_kwargs_len, + c_defaults, + (int)c_defaults_len, + kw_defaults, + closure + ); -static void* hook_calloc(void* ctx, size_t nelem, size_t elsize) -{ - alloc_hook_t *hook = (alloc_hook_t *)ctx; - hook->ctx = ctx; - hook->calloc_nelem = nelem; - hook->calloc_elsize = elsize; - return hook->alloc.calloc(hook->alloc.ctx, nelem, elsize); -} +exit: + if (c_kwargs) { + PyMem_DEL(c_kwargs); + } -static void* hook_realloc(void* ctx, void* ptr, size_t new_size) -{ - alloc_hook_t *hook = (alloc_hook_t *)ctx; - hook->ctx = ctx; - hook->realloc_ptr = ptr; - hook->realloc_new_size = new_size; - return hook->alloc.realloc(hook->alloc.ctx, ptr, new_size); + return result; } -static void hook_free(void *ctx, void *ptr) +static PyObject * +get_feature_macros(PyObject *self, PyObject *Py_UNUSED(args)) { - alloc_hook_t *hook = (alloc_hook_t *)ctx; - hook->ctx = ctx; - hook->free_ptr = ptr; - hook->alloc.free(hook->alloc.ctx, ptr); + PyObject *result = PyDict_New(); + if (!result) { + return NULL; + } + int res; +#include "_testcapi_feature_macros.inc" + return result; } static PyObject * -test_setallocators(PyMemAllocatorDomain domain) +test_code_api(PyObject *self, PyObject *Py_UNUSED(args)) { - PyObject *res = NULL; - const char *error_msg; - alloc_hook_t hook; - PyMemAllocatorEx alloc; - size_t size, size2, nelem, elsize; - void *ptr, *ptr2; - - memset(&hook, 0, sizeof(hook)); - - alloc.ctx = &hook; - alloc.malloc = &hook_malloc; - alloc.calloc = &hook_calloc; - alloc.realloc = &hook_realloc; - alloc.free = &hook_free; - PyMem_GetAllocator(domain, &hook.alloc); - PyMem_SetAllocator(domain, &alloc); - - /* malloc, realloc, free */ - size = 42; - hook.ctx = NULL; - switch(domain) - { - case PYMEM_DOMAIN_RAW: ptr = PyMem_RawMalloc(size); break; - case PYMEM_DOMAIN_MEM: ptr = PyMem_Malloc(size); break; - case PYMEM_DOMAIN_OBJ: ptr = PyObject_Malloc(size); break; - default: ptr = NULL; break; - } - -#define CHECK_CTX(FUNC) \ - if (hook.ctx != &hook) { \ - error_msg = FUNC " wrong context"; \ - goto fail; \ - } \ - hook.ctx = NULL; /* reset for next check */ - - if (ptr == NULL) { - error_msg = "malloc failed"; - goto fail; - } - CHECK_CTX("malloc"); - if (hook.malloc_size != size) { - error_msg = "malloc invalid size"; - goto fail; + PyCodeObject *co = PyCode_NewEmpty("_testcapi", "dummy", 1); + if (co == NULL) { + return NULL; } - - size2 = 200; - switch(domain) + /* co_code */ { - case PYMEM_DOMAIN_RAW: ptr2 = PyMem_RawRealloc(ptr, size2); break; - case PYMEM_DOMAIN_MEM: ptr2 = PyMem_Realloc(ptr, size2); break; - case PYMEM_DOMAIN_OBJ: ptr2 = PyObject_Realloc(ptr, size2); break; - default: ptr2 = NULL; break; - } - - if (ptr2 == NULL) { - error_msg = "realloc failed"; - goto fail; - } - CHECK_CTX("realloc"); - if (hook.realloc_ptr != ptr - || hook.realloc_new_size != size2) { - error_msg = "realloc invalid parameters"; - goto fail; + PyObject *co_code = PyCode_GetCode(co); + if (co_code == NULL) { + goto fail; + } + assert(PyBytes_CheckExact(co_code)); + if (PyObject_Length(co_code) == 0) { + PyErr_SetString(PyExc_ValueError, "empty co_code"); + Py_DECREF(co_code); + goto fail; + } + Py_DECREF(co_code); } - - switch(domain) + /* co_varnames */ { - case PYMEM_DOMAIN_RAW: PyMem_RawFree(ptr2); break; - case PYMEM_DOMAIN_MEM: PyMem_Free(ptr2); break; - case PYMEM_DOMAIN_OBJ: PyObject_Free(ptr2); break; + PyObject *co_varnames = PyCode_GetVarnames(co); + if (co_varnames == NULL) { + goto fail; + } + if (!PyTuple_CheckExact(co_varnames)) { + PyErr_SetString(PyExc_TypeError, "co_varnames not tuple"); + Py_DECREF(co_varnames); + goto fail; + } + if (PyTuple_GET_SIZE(co_varnames) != 0) { + PyErr_SetString(PyExc_ValueError, "non-empty co_varnames"); + Py_DECREF(co_varnames); + goto fail; + } + Py_DECREF(co_varnames); } - - CHECK_CTX("free"); - if (hook.free_ptr != ptr2) { - error_msg = "free invalid pointer"; - goto fail; + /* co_cellvars */ + { + PyObject *co_cellvars = PyCode_GetCellvars(co); + if (co_cellvars == NULL) { + goto fail; + } + if (!PyTuple_CheckExact(co_cellvars)) { + PyErr_SetString(PyExc_TypeError, "co_cellvars not tuple"); + Py_DECREF(co_cellvars); + goto fail; + } + if (PyTuple_GET_SIZE(co_cellvars) != 0) { + PyErr_SetString(PyExc_ValueError, "non-empty co_cellvars"); + Py_DECREF(co_cellvars); + goto fail; + } + Py_DECREF(co_cellvars); } - - /* calloc, free */ - nelem = 2; - elsize = 5; - switch(domain) + /* co_freevars */ { - case PYMEM_DOMAIN_RAW: ptr = PyMem_RawCalloc(nelem, elsize); break; - case PYMEM_DOMAIN_MEM: ptr = PyMem_Calloc(nelem, elsize); break; - case PYMEM_DOMAIN_OBJ: ptr = PyObject_Calloc(nelem, elsize); break; - default: ptr = NULL; break; + PyObject *co_freevars = PyCode_GetFreevars(co); + if (co_freevars == NULL) { + goto fail; + } + if (!PyTuple_CheckExact(co_freevars)) { + PyErr_SetString(PyExc_TypeError, "co_freevars not tuple"); + Py_DECREF(co_freevars); + goto fail; + } + if (PyTuple_GET_SIZE(co_freevars) != 0) { + PyErr_SetString(PyExc_ValueError, "non-empty co_freevars"); + Py_DECREF(co_freevars); + goto fail; + } + Py_DECREF(co_freevars); } + Py_DECREF(co); + Py_RETURN_NONE; +fail: + Py_DECREF(co); + return NULL; +} - if (ptr == NULL) { - error_msg = "calloc failed"; - goto fail; +static int +record_func(PyObject *obj, PyFrameObject *f, int what, PyObject *arg) +{ + assert(PyList_Check(obj)); + PyObject *what_obj = NULL; + PyObject *line_obj = NULL; + PyObject *tuple = NULL; + int res = -1; + what_obj = PyLong_FromLong(what); + if (what_obj == NULL) { + goto error; } - CHECK_CTX("calloc"); - if (hook.calloc_nelem != nelem || hook.calloc_elsize != elsize) { - error_msg = "calloc invalid nelem or elsize"; - goto fail; + int line = PyFrame_GetLineNumber(f); + line_obj = PyLong_FromLong(line); + if (line_obj == NULL) { + goto error; } - - hook.free_ptr = NULL; - switch(domain) - { - case PYMEM_DOMAIN_RAW: PyMem_RawFree(ptr); break; - case PYMEM_DOMAIN_MEM: PyMem_Free(ptr); break; - case PYMEM_DOMAIN_OBJ: PyObject_Free(ptr); break; + tuple = PyTuple_Pack(3, what_obj, line_obj, arg); + if (tuple == NULL) { + goto error; } - - CHECK_CTX("calloc free"); - if (hook.free_ptr != ptr) { - error_msg = "calloc free invalid pointer"; - goto fail; + PyTuple_SET_ITEM(tuple, 0, what_obj); + if (PyList_Append(obj, tuple)) { + goto error; } - - Py_INCREF(Py_None); - res = Py_None; - goto finally; - -fail: - PyErr_SetString(PyExc_RuntimeError, error_msg); - -finally: - PyMem_SetAllocator(domain, &hook.alloc); + res = 0; +error: + Py_XDECREF(what_obj); + Py_XDECREF(line_obj); + Py_XDECREF(tuple); return res; - -#undef CHECK_CTX } static PyObject * -test_pymem_setrawallocators(PyObject *self, PyObject *Py_UNUSED(ignored)) +settrace_to_record(PyObject *self, PyObject *list) { - return test_setallocators(PYMEM_DOMAIN_RAW); + + if (!PyList_Check(list)) { + PyErr_SetString(PyExc_TypeError, "argument must be a list"); + return NULL; + } + PyEval_SetTrace(record_func, list); + Py_RETURN_NONE; } -static PyObject * -test_pymem_setallocators(PyObject *self, PyObject *Py_UNUSED(ignored)) +static int +error_func(PyObject *obj, PyFrameObject *f, int what, PyObject *arg) { - return test_setallocators(PYMEM_DOMAIN_MEM); + assert(PyList_Check(obj)); + /* Only raise if list is empty, otherwise append None + * This ensures that we only raise once */ + if (PyList_GET_SIZE(obj)) { + return 0; + } + if (PyList_Append(obj, Py_None)) { + return -1; + } + PyErr_SetString(PyExc_Exception, "an exception"); + return -1; } static PyObject * -test_pyobject_setallocators(PyObject *self, PyObject *Py_UNUSED(ignored)) +settrace_to_error(PyObject *self, PyObject *list) { - 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)) { + if (!PyList_Check(list)) { + PyErr_SetString(PyExc_TypeError, "argument must be a list"); return NULL; } - fm_setup_hooks(); - Py_RETURN_NONE; -} - -static PyObject* -remove_mem_hooks(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - fm_remove_hooks(); + PyEval_SetTrace(error_func, list); Py_RETURN_NONE; } -PyDoc_STRVAR(docstring_empty, -"" -); - -PyDoc_STRVAR(docstring_no_signature, -"This docstring has no signature." -); - -PyDoc_STRVAR(docstring_with_invalid_signature, -"docstring_with_invalid_signature($module, /, boo)\n" -"\n" -"This docstring has an invalid signature." -); - -PyDoc_STRVAR(docstring_with_invalid_signature2, -"docstring_with_invalid_signature2($module, /, boo)\n" -"\n" -"--\n" -"\n" -"This docstring also has an invalid signature." -); - -PyDoc_STRVAR(docstring_with_signature, -"docstring_with_signature($module, /, sig)\n" -"--\n" -"\n" -"This docstring has a valid signature." -); - -PyDoc_STRVAR(docstring_with_signature_but_no_doc, -"docstring_with_signature_but_no_doc($module, /, sig)\n" -"--\n" -"\n" -); - -PyDoc_STRVAR(docstring_with_signature_and_extra_newlines, -"docstring_with_signature_and_extra_newlines($module, /, parameter)\n" -"--\n" -"\n" -"\n" -"This docstring has a valid signature and some extra newlines." -); - -PyDoc_STRVAR(docstring_with_signature_with_defaults, -"docstring_with_signature_with_defaults(module, s='avocado',\n" -" b=b'bytes', d=3.14, i=35, n=None, t=True, f=False,\n" -" local=the_number_three, sys=sys.maxsize,\n" -" exp=sys.maxsize - 1)\n" -"--\n" -"\n" -"\n" -"\n" -"This docstring has a valid signature with parameters,\n" -"and the parameters take defaults of varying types." -); - -typedef struct { - PyThread_type_lock start_event; - PyThread_type_lock exit_event; - PyObject *callback; -} test_c_thread_t; - -static void -temporary_c_thread(void *data) -{ - test_c_thread_t *test_c_thread = data; - PyGILState_STATE state; - PyObject *res; - - PyThread_release_lock(test_c_thread->start_event); - - /* Allocate a Python thread state for this thread */ - state = PyGILState_Ensure(); - - res = PyObject_CallNoArgs(test_c_thread->callback); - Py_CLEAR(test_c_thread->callback); - - if (res == NULL) { - PyErr_Print(); - } - else { - Py_DECREF(res); - } - - /* Destroy the Python thread state for this thread */ - PyGILState_Release(state); - - PyThread_release_lock(test_c_thread->exit_event); -} - -static test_c_thread_t test_c_thread; - -static PyObject * -call_in_temporary_c_thread(PyObject *self, PyObject *args) -{ - PyObject *res = NULL; - PyObject *callback = NULL; - long thread; - int wait = 1; - if (!PyArg_ParseTuple(args, "O|i", &callback, &wait)) - { - return NULL; - } - - test_c_thread.start_event = PyThread_allocate_lock(); - test_c_thread.exit_event = PyThread_allocate_lock(); - test_c_thread.callback = NULL; - if (!test_c_thread.start_event || !test_c_thread.exit_event) { - PyErr_SetString(PyExc_RuntimeError, "could not allocate lock"); - goto exit; - } - - test_c_thread.callback = Py_NewRef(callback); - - PyThread_acquire_lock(test_c_thread.start_event, 1); - PyThread_acquire_lock(test_c_thread.exit_event, 1); - - thread = PyThread_start_new_thread(temporary_c_thread, &test_c_thread); - if (thread == -1) { - PyErr_SetString(PyExc_RuntimeError, "unable to start the thread"); - PyThread_release_lock(test_c_thread.start_event); - PyThread_release_lock(test_c_thread.exit_event); - goto exit; - } - - PyThread_acquire_lock(test_c_thread.start_event, 1); - PyThread_release_lock(test_c_thread.start_event); - - if (!wait) { - Py_RETURN_NONE; - } - - Py_BEGIN_ALLOW_THREADS - PyThread_acquire_lock(test_c_thread.exit_event, 1); - PyThread_release_lock(test_c_thread.exit_event); - Py_END_ALLOW_THREADS - - res = Py_NewRef(Py_None); - -exit: - Py_CLEAR(test_c_thread.callback); - if (test_c_thread.start_event) { - PyThread_free_lock(test_c_thread.start_event); - test_c_thread.start_event = NULL; - } - if (test_c_thread.exit_event) { - PyThread_free_lock(test_c_thread.exit_event); - test_c_thread.exit_event = NULL; - } - return res; -} - static PyObject * -join_temporary_c_thread(PyObject *self, PyObject *Py_UNUSED(ignored)) +clear_managed_dict(PyObject *self, PyObject *obj) { - Py_BEGIN_ALLOW_THREADS - PyThread_acquire_lock(test_c_thread.exit_event, 1); - PyThread_release_lock(test_c_thread.exit_event); - Py_END_ALLOW_THREADS - Py_CLEAR(test_c_thread.callback); - PyThread_free_lock(test_c_thread.start_event); - test_c_thread.start_event = NULL; - PyThread_free_lock(test_c_thread.exit_event); - test_c_thread.exit_event = NULL; + _PyObject_ClearManagedDict(obj); Py_RETURN_NONE; } -/* marshal */ -static PyObject* -pymarshal_write_long_to_file(PyObject* self, PyObject *args) +static PyObject * +test_macros(PyObject *self, PyObject *Py_UNUSED(args)) { - long value; - PyObject *filename; - int version; - FILE *fp; - - if (!PyArg_ParseTuple(args, "lOi:pymarshal_write_long_to_file", - &value, &filename, &version)) - return NULL; + struct MyStruct { + int x; + }; + wchar_t array[3]; - fp = _Py_fopen_obj(filename, "wb"); - if (fp == NULL) { - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } + // static_assert(), Py_BUILD_ASSERT() + static_assert(1 == 1, "bug"); + Py_BUILD_ASSERT(1 == 1); - PyMarshal_WriteLongToFile(value, fp, version); - fclose(fp); - if (PyErr_Occurred()) - return NULL; - Py_RETURN_NONE; -} + // Py_MIN(), Py_MAX(), Py_ABS() + assert(Py_MIN(5, 11) == 5); + assert(Py_MAX(5, 11) == 11); + assert(Py_ABS(-5) == 5); -static PyObject* -pymarshal_write_object_to_file(PyObject* self, PyObject *args) -{ - PyObject *obj; - PyObject *filename; - int version; - FILE *fp; + // Py_STRINGIFY() + assert(strcmp(Py_STRINGIFY(123), "123") == 0); - if (!PyArg_ParseTuple(args, "OOi:pymarshal_write_object_to_file", - &obj, &filename, &version)) - return NULL; + // Py_MEMBER_SIZE(), Py_ARRAY_LENGTH() + assert(Py_MEMBER_SIZE(struct MyStruct, x) == sizeof(int)); + assert(Py_ARRAY_LENGTH(array) == 3); - fp = _Py_fopen_obj(filename, "wb"); - if (fp == NULL) { - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } + // Py_CHARMASK() + int c = 0xab00 | 7; + assert(Py_CHARMASK(c) == 7); - PyMarshal_WriteObjectToFile(obj, fp, version); + // _Py_IS_TYPE_SIGNED() + assert(_Py_IS_TYPE_SIGNED(int)); + assert(!_Py_IS_TYPE_SIGNED(unsigned int)); - fclose(fp); - if (PyErr_Occurred()) - return NULL; Py_RETURN_NONE; } -static PyObject* -pymarshal_read_short_from_file(PyObject* self, PyObject *args) -{ - int value; - long pos; - PyObject *filename; - FILE *fp; - - if (!PyArg_ParseTuple(args, "O:pymarshal_read_short_from_file", &filename)) - return NULL; - - fp = _Py_fopen_obj(filename, "rb"); - if (fp == NULL) { - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } - - value = PyMarshal_ReadShortFromFile(fp); - pos = ftell(fp); - - fclose(fp); - if (PyErr_Occurred()) - return NULL; - return Py_BuildValue("il", value, pos); -} - -static PyObject* -pymarshal_read_long_from_file(PyObject* self, PyObject *args) -{ - long value, pos; - PyObject *filename; - FILE *fp; - - if (!PyArg_ParseTuple(args, "O:pymarshal_read_long_from_file", &filename)) - return NULL; - - fp = _Py_fopen_obj(filename, "rb"); - if (fp == NULL) { - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } - - value = PyMarshal_ReadLongFromFile(fp); - pos = ftell(fp); - - fclose(fp); - if (PyErr_Occurred()) - return NULL; - return Py_BuildValue("ll", value, pos); -} - -static PyObject* -pymarshal_read_last_object_from_file(PyObject* self, PyObject *args) -{ - PyObject *obj; - long pos; - PyObject *filename; - FILE *fp; - - if (!PyArg_ParseTuple(args, "O:pymarshal_read_last_object_from_file", &filename)) - return NULL; - - fp = _Py_fopen_obj(filename, "rb"); - if (fp == NULL) { - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } - - obj = PyMarshal_ReadLastObjectFromFile(fp); - pos = ftell(fp); - - fclose(fp); - return Py_BuildValue("Nl", obj, pos); -} - -static PyObject* -pymarshal_read_object_from_file(PyObject* self, PyObject *args) -{ - PyObject *obj; - long pos; - PyObject *filename; - FILE *fp; - - if (!PyArg_ParseTuple(args, "O:pymarshal_read_object_from_file", &filename)) - return NULL; - - fp = _Py_fopen_obj(filename, "rb"); - if (fp == NULL) { - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } - - obj = PyMarshal_ReadObjectFromFile(fp); - pos = ftell(fp); - - fclose(fp); - return Py_BuildValue("Nl", obj, pos); -} - -static PyObject* -return_null_without_error(PyObject *self, PyObject *args) -{ - /* invalid call: return NULL without setting an error, - * _Py_CheckFunctionResult() must detect such bug at runtime. */ - PyErr_Clear(); - return NULL; -} - -static PyObject* -return_result_with_error(PyObject *self, PyObject *args) -{ - /* invalid call: return a result with an error set, - * _Py_CheckFunctionResult() must detect such bug at runtime. */ - PyErr_SetNone(PyExc_ValueError); - Py_RETURN_NONE; -} - -static PyObject* -getitem_with_error(PyObject *self, PyObject *args) -{ - PyObject *map, *key; - if (!PyArg_ParseTuple(args, "OO", &map, &key)) { - return NULL; - } - - PyErr_SetString(PyExc_ValueError, "bug"); - return PyObject_GetItem(map, key); -} - -static PyObject * -test_pytime_fromseconds(PyObject *self, PyObject *args) -{ - int seconds; - if (!PyArg_ParseTuple(args, "i", &seconds)) { - return NULL; - } - _PyTime_t ts = _PyTime_FromSeconds(seconds); - return _PyTime_AsNanosecondsObject(ts); -} - -static PyObject * -test_pytime_fromsecondsobject(PyObject *self, PyObject *args) -{ - PyObject *obj; - int round; - if (!PyArg_ParseTuple(args, "Oi", &obj, &round)) { - return NULL; - } - if (check_time_rounding(round) < 0) { - return NULL; - } - _PyTime_t ts; - if (_PyTime_FromSecondsObject(&ts, obj, round) == -1) { - return NULL; - } - return _PyTime_AsNanosecondsObject(ts); -} - -static PyObject * -test_pytime_assecondsdouble(PyObject *self, PyObject *args) -{ - PyObject *obj; - if (!PyArg_ParseTuple(args, "O", &obj)) { - return NULL; - } - _PyTime_t ts; - if (_PyTime_FromNanosecondsObject(&ts, obj) < 0) { - return NULL; - } - double d = _PyTime_AsSecondsDouble(ts); - return PyFloat_FromDouble(d); -} - -static PyObject * -test_PyTime_AsTimeval(PyObject *self, PyObject *args) -{ - PyObject *obj; - int round; - if (!PyArg_ParseTuple(args, "Oi", &obj, &round)) { - return NULL; - } - if (check_time_rounding(round) < 0) { - return NULL; - } - _PyTime_t t; - if (_PyTime_FromNanosecondsObject(&t, obj) < 0) { - return NULL; - } - struct timeval tv; - if (_PyTime_AsTimeval(t, &tv, round) < 0) { - return NULL; - } - - PyObject *seconds = PyLong_FromLongLong(tv.tv_sec); - if (seconds == NULL) { - return NULL; - } - return Py_BuildValue("Nl", seconds, (long)tv.tv_usec); -} - -static PyObject * -test_PyTime_AsTimeval_clamp(PyObject *self, PyObject *args) -{ - PyObject *obj; - int round; - if (!PyArg_ParseTuple(args, "Oi", &obj, &round)) { - return NULL; - } - if (check_time_rounding(round) < 0) { - return NULL; - } - _PyTime_t t; - if (_PyTime_FromNanosecondsObject(&t, obj) < 0) { - return NULL; - } - struct timeval tv; - _PyTime_AsTimeval_clamp(t, &tv, round); - - PyObject *seconds = PyLong_FromLongLong(tv.tv_sec); - if (seconds == NULL) { - return NULL; - } - return Py_BuildValue("Nl", seconds, (long)tv.tv_usec); -} - -#ifdef HAVE_CLOCK_GETTIME -static PyObject * -test_PyTime_AsTimespec(PyObject *self, PyObject *args) -{ - PyObject *obj; - if (!PyArg_ParseTuple(args, "O", &obj)) { - return NULL; - } - _PyTime_t t; - if (_PyTime_FromNanosecondsObject(&t, obj) < 0) { - return NULL; - } - struct timespec ts; - if (_PyTime_AsTimespec(t, &ts) == -1) { - return NULL; - } - return Py_BuildValue("Nl", _PyLong_FromTime_t(ts.tv_sec), ts.tv_nsec); -} - -static PyObject * -test_PyTime_AsTimespec_clamp(PyObject *self, PyObject *args) -{ - PyObject *obj; - if (!PyArg_ParseTuple(args, "O", &obj)) { - return NULL; - } - _PyTime_t t; - if (_PyTime_FromNanosecondsObject(&t, obj) < 0) { - return NULL; - } - struct timespec ts; - _PyTime_AsTimespec_clamp(t, &ts); - return Py_BuildValue("Nl", _PyLong_FromTime_t(ts.tv_sec), ts.tv_nsec); -} -#endif - -static PyObject * -test_PyTime_AsMilliseconds(PyObject *self, PyObject *args) -{ - PyObject *obj; - int round; - if (!PyArg_ParseTuple(args, "Oi", &obj, &round)) { - return NULL; - } - _PyTime_t t; - if (_PyTime_FromNanosecondsObject(&t, obj) < 0) { - return NULL; - } - if (check_time_rounding(round) < 0) { - return NULL; - } - _PyTime_t ms = _PyTime_AsMilliseconds(t, round); - _PyTime_t ns = _PyTime_FromNanoseconds(ms); - return _PyTime_AsNanosecondsObject(ns); -} - -static PyObject * -test_PyTime_AsMicroseconds(PyObject *self, PyObject *args) -{ - PyObject *obj; - int round; - if (!PyArg_ParseTuple(args, "Oi", &obj, &round)) { - return NULL; - } - _PyTime_t t; - if (_PyTime_FromNanosecondsObject(&t, obj) < 0) { - return NULL; - } - if (check_time_rounding(round) < 0) { - return NULL; - } - _PyTime_t us = _PyTime_AsMicroseconds(t, round); - _PyTime_t ns = _PyTime_FromNanoseconds(us); - return _PyTime_AsNanosecondsObject(ns); -} - -static PyObject* -pymem_buffer_overflow(PyObject *self, PyObject *args) -{ - char *buffer; - - /* Deliberate buffer overflow to check that PyMem_Free() detects - the overflow when debug hooks are installed. */ - buffer = PyMem_Malloc(16); - if (buffer == NULL) { - PyErr_NoMemory(); - return NULL; - } - buffer[16] = 'x'; - PyMem_Free(buffer); - - Py_RETURN_NONE; -} - -static PyObject* -pymem_api_misuse(PyObject *self, PyObject *args) -{ - char *buffer; - - /* Deliberate misusage of Python allocators: - allococate with PyMem but release with PyMem_Raw. */ - buffer = PyMem_Malloc(16); - PyMem_RawFree(buffer); - - Py_RETURN_NONE; -} - -static PyObject* -pymem_malloc_without_gil(PyObject *self, PyObject *args) -{ - char *buffer; - - /* Deliberate bug to test debug hooks on Python memory allocators: - call PyMem_Malloc() without holding the GIL */ - Py_BEGIN_ALLOW_THREADS - buffer = PyMem_Malloc(10); - Py_END_ALLOW_THREADS - - PyMem_Free(buffer); - - Py_RETURN_NONE; -} - - -static PyObject* -test_pymem_getallocatorsname(PyObject *self, PyObject *args) -{ - const char *name = _PyMem_GetCurrentAllocatorName(); - if (name == NULL) { - PyErr_SetString(PyExc_RuntimeError, "cannot get allocators name"); - return NULL; - } - return PyUnicode_FromString(name); -} - - -static PyObject* -test_pyobject_is_freed(const char *test_name, PyObject *op) -{ - if (!_PyObject_IsFreed(op)) { - return raiseTestError(test_name, "object is not seen as freed"); - } - Py_RETURN_NONE; -} - - -static PyObject* -check_pyobject_null_is_freed(PyObject *self, PyObject *Py_UNUSED(args)) -{ - PyObject *op = NULL; - return test_pyobject_is_freed("check_pyobject_null_is_freed", op); -} - - -static PyObject* -check_pyobject_uninitialized_is_freed(PyObject *self, PyObject *Py_UNUSED(args)) -{ - PyObject *op = (PyObject *)PyObject_Malloc(sizeof(PyObject)); - if (op == NULL) { - return NULL; - } - /* Initialize reference count to avoid early crash in ceval or GC */ - Py_SET_REFCNT(op, 1); - /* object fields like ob_type are uninitialized! */ - return test_pyobject_is_freed("check_pyobject_uninitialized_is_freed", op); -} - - -static PyObject* -check_pyobject_forbidden_bytes_is_freed(PyObject *self, PyObject *Py_UNUSED(args)) -{ - /* Allocate an incomplete PyObject structure: truncate 'ob_type' field */ - PyObject *op = (PyObject *)PyObject_Malloc(offsetof(PyObject, ob_type)); - if (op == NULL) { - return NULL; - } - /* Initialize reference count to avoid early crash in ceval or GC */ - Py_SET_REFCNT(op, 1); - /* ob_type field is after the memory block: part of "forbidden bytes" - when using debug hooks on memory allocators! */ - return test_pyobject_is_freed("check_pyobject_forbidden_bytes_is_freed", op); -} - - -static PyObject* -check_pyobject_freed_is_freed(PyObject *self, PyObject *Py_UNUSED(args)) -{ - /* This test would fail if run with the address sanitizer */ -#ifdef _Py_ADDRESS_SANITIZER - Py_RETURN_NONE; -#else - PyObject *op = PyObject_CallNoArgs((PyObject *)&PyBaseObject_Type); - if (op == NULL) { - return NULL; - } - Py_TYPE(op)->tp_dealloc(op); - /* Reset reference count to avoid early crash in ceval or GC */ - Py_SET_REFCNT(op, 1); - /* object memory is freed! */ - return test_pyobject_is_freed("check_pyobject_freed_is_freed", op); -#endif -} - - -static PyObject* -pyobject_malloc_without_gil(PyObject *self, PyObject *args) -{ - char *buffer; - - /* Deliberate bug to test debug hooks on Python memory allocators: - call PyObject_Malloc() without holding the GIL */ - Py_BEGIN_ALLOW_THREADS - buffer = PyObject_Malloc(10); - Py_END_ALLOW_THREADS - - PyObject_Free(buffer); - - Py_RETURN_NONE; -} - -static PyObject * -tracemalloc_track(PyObject *self, PyObject *args) -{ - unsigned int domain; - PyObject *ptr_obj; - void *ptr; - Py_ssize_t size; - int release_gil = 0; - int res; - - if (!PyArg_ParseTuple(args, "IOn|i", &domain, &ptr_obj, &size, &release_gil)) - return NULL; - ptr = PyLong_AsVoidPtr(ptr_obj); - if (PyErr_Occurred()) - return NULL; - - if (release_gil) { - Py_BEGIN_ALLOW_THREADS - res = PyTraceMalloc_Track(domain, (uintptr_t)ptr, size); - Py_END_ALLOW_THREADS - } - else { - res = PyTraceMalloc_Track(domain, (uintptr_t)ptr, size); - } - - if (res < 0) { - PyErr_SetString(PyExc_RuntimeError, "PyTraceMalloc_Track error"); - return NULL; - } - - Py_RETURN_NONE; -} - -static PyObject * -tracemalloc_untrack(PyObject *self, PyObject *args) -{ - unsigned int domain; - PyObject *ptr_obj; - void *ptr; - int res; - - if (!PyArg_ParseTuple(args, "IO", &domain, &ptr_obj)) - return NULL; - ptr = PyLong_AsVoidPtr(ptr_obj); - if (PyErr_Occurred()) - return NULL; - - res = PyTraceMalloc_Untrack(domain, (uintptr_t)ptr); - if (res < 0) { - PyErr_SetString(PyExc_RuntimeError, "PyTraceMalloc_Untrack error"); - return NULL; - } - - Py_RETURN_NONE; -} - -static PyObject * -tracemalloc_get_traceback(PyObject *self, PyObject *args) -{ - unsigned int domain; - PyObject *ptr_obj; - void *ptr; - - if (!PyArg_ParseTuple(args, "IO", &domain, &ptr_obj)) - return NULL; - ptr = PyLong_AsVoidPtr(ptr_obj); - if (PyErr_Occurred()) - return NULL; - - return _PyTraceMalloc_GetTraceback(domain, (uintptr_t)ptr); -} - -static PyObject * -dict_get_version(PyObject *self, PyObject *args) -{ - PyDictObject *dict; - uint64_t version; - - if (!PyArg_ParseTuple(args, "O!", &PyDict_Type, &dict)) - return NULL; - - version = dict->ma_version_tag; - - static_assert(sizeof(unsigned long long) >= sizeof(version), - "version is larger than unsigned long long"); - return PyLong_FromUnsignedLongLong((unsigned long long)version); -} - - -static PyObject * -raise_SIGINT_then_send_None(PyObject *self, PyObject *args) -{ - _Py_IDENTIFIER(send); - PyGenObject *gen; - - if (!PyArg_ParseTuple(args, "O!", &PyGen_Type, &gen)) - return NULL; - - /* This is used in a test to check what happens if a signal arrives just - as we're in the process of entering a yield from chain (see - bpo-30039). - - Needs to be done in C, because: - - we don't have a Python wrapper for raise() - - we need to make sure that the Python-level signal handler doesn't run - *before* we enter the generator frame, which is impossible in Python - because we check for signals before every bytecode operation. - */ - raise(SIGINT); - return _PyObject_CallMethodIdOneArg((PyObject *)gen, &PyId_send, Py_None); -} - - -static int -fastcall_args(PyObject *args, PyObject ***stack, Py_ssize_t *nargs) -{ - if (args == Py_None) { - *stack = NULL; - *nargs = 0; - } - else if (PyTuple_Check(args)) { - *stack = ((PyTupleObject *)args)->ob_item; - *nargs = PyTuple_GET_SIZE(args); - } - else { - PyErr_SetString(PyExc_TypeError, "args must be None or a tuple"); - return -1; - } - return 0; -} - - -static PyObject * -test_pyobject_fastcall(PyObject *self, PyObject *args) -{ - PyObject *func, *func_args; - PyObject **stack; - Py_ssize_t nargs; - - if (!PyArg_ParseTuple(args, "OO", &func, &func_args)) { - return NULL; - } - - if (fastcall_args(func_args, &stack, &nargs) < 0) { - return NULL; - } - return _PyObject_FastCall(func, stack, nargs); -} - - -static PyObject * -test_pyobject_fastcalldict(PyObject *self, PyObject *args) -{ - PyObject *func, *func_args, *kwargs; - PyObject **stack; - Py_ssize_t nargs; - - if (!PyArg_ParseTuple(args, "OOO", &func, &func_args, &kwargs)) { - return NULL; - } - - if (fastcall_args(func_args, &stack, &nargs) < 0) { - return NULL; - } - - if (kwargs == Py_None) { - kwargs = NULL; - } - else if (!PyDict_Check(kwargs)) { - PyErr_SetString(PyExc_TypeError, "kwnames must be None or a dict"); - return NULL; - } - - return PyObject_VectorcallDict(func, stack, nargs, kwargs); -} - - -static PyObject * -test_pyobject_vectorcall(PyObject *self, PyObject *args) -{ - PyObject *func, *func_args, *kwnames = NULL; - PyObject **stack; - Py_ssize_t nargs, nkw; - - if (!PyArg_ParseTuple(args, "OOO", &func, &func_args, &kwnames)) { - return NULL; - } - - if (fastcall_args(func_args, &stack, &nargs) < 0) { - return NULL; - } - - if (kwnames == Py_None) { - kwnames = NULL; - } - else if (PyTuple_Check(kwnames)) { - nkw = PyTuple_GET_SIZE(kwnames); - if (nargs < nkw) { - PyErr_SetString(PyExc_ValueError, "kwnames longer than args"); - return NULL; - } - nargs -= nkw; - } - else { - PyErr_SetString(PyExc_TypeError, "kwnames must be None or a tuple"); - return NULL; - } - return PyObject_Vectorcall(func, stack, nargs, kwnames); -} - - -static PyObject * -test_pyvectorcall_call(PyObject *self, PyObject *args) -{ - PyObject *func; - PyObject *argstuple; - PyObject *kwargs = NULL; - - if (!PyArg_ParseTuple(args, "OO|O", &func, &argstuple, &kwargs)) { - return NULL; - } - - if (!PyTuple_Check(argstuple)) { - PyErr_SetString(PyExc_TypeError, "args must be a tuple"); - return NULL; - } - if (kwargs != NULL && !PyDict_Check(kwargs)) { - PyErr_SetString(PyExc_TypeError, "kwargs must be a dict"); - return NULL; - } - - return PyVectorcall_Call(func, argstuple, kwargs); -} - - -static PyObject* -stack_pointer(PyObject *self, PyObject *args) -{ - int v = 5; - return PyLong_FromVoidPtr(&v); -} - - -#ifdef W_STOPCODE -static PyObject* -py_w_stopcode(PyObject *self, PyObject *args) -{ - int sig, status; - if (!PyArg_ParseTuple(args, "i", &sig)) { - return NULL; - } - status = W_STOPCODE(sig); - return PyLong_FromLong(status); -} -#endif - - -static PyObject * -get_mapping_keys(PyObject* self, PyObject *obj) -{ - return PyMapping_Keys(obj); -} - -static PyObject * -get_mapping_values(PyObject* self, PyObject *obj) -{ - return PyMapping_Values(obj); -} - -static PyObject * -get_mapping_items(PyObject* self, PyObject *obj) -{ - return PyMapping_Items(obj); -} - -static PyObject * -test_mapping_has_key_string(PyObject *self, PyObject *Py_UNUSED(args)) -{ - PyObject *context = PyDict_New(); - PyObject *val = PyLong_FromLong(1); - - // Since this uses `const char*` it is easier to test this in C: - PyDict_SetItemString(context, "a", val); - if (!PyMapping_HasKeyString(context, "a")) { - PyErr_SetString(PyExc_RuntimeError, - "Existing mapping key does not exist"); - return NULL; - } - if (PyMapping_HasKeyString(context, "b")) { - PyErr_SetString(PyExc_RuntimeError, - "Missing mapping key exists"); - return NULL; - } - - Py_DECREF(val); - Py_DECREF(context); - Py_RETURN_NONE; -} - -static PyObject * -mapping_has_key(PyObject* self, PyObject *args) -{ - PyObject *context, *key; - if (!PyArg_ParseTuple(args, "OO", &context, &key)) { - return NULL; - } - return PyLong_FromLong(PyMapping_HasKey(context, key)); -} - -static PyObject * -sequence_set_slice(PyObject* self, PyObject *args) -{ - PyObject *sequence, *obj; - Py_ssize_t i1, i2; - if (!PyArg_ParseTuple(args, "OnnO", &sequence, &i1, &i2, &obj)) { - return NULL; - } - - int res = PySequence_SetSlice(sequence, i1, i2, obj); - if (res == -1) { - return NULL; - } - Py_RETURN_NONE; -} - -static PyObject * -sequence_del_slice(PyObject* self, PyObject *args) -{ - PyObject *sequence; - Py_ssize_t i1, i2; - if (!PyArg_ParseTuple(args, "Onn", &sequence, &i1, &i2)) { - return NULL; - } - - int res = PySequence_DelSlice(sequence, i1, i2); - if (res == -1) { - return NULL; - } - Py_RETURN_NONE; -} - -static PyObject * -test_pythread_tss_key_state(PyObject *self, PyObject *args) -{ - Py_tss_t tss_key = Py_tss_NEEDS_INIT; - if (PyThread_tss_is_created(&tss_key)) { - return raiseTestError("test_pythread_tss_key_state", - "TSS key not in an uninitialized state at " - "creation time"); - } - if (PyThread_tss_create(&tss_key) != 0) { - PyErr_SetString(PyExc_RuntimeError, "PyThread_tss_create failed"); - return NULL; - } - if (!PyThread_tss_is_created(&tss_key)) { - return raiseTestError("test_pythread_tss_key_state", - "PyThread_tss_create succeeded, " - "but with TSS key in an uninitialized state"); - } - if (PyThread_tss_create(&tss_key) != 0) { - return raiseTestError("test_pythread_tss_key_state", - "PyThread_tss_create unsuccessful with " - "an already initialized key"); - } -#define CHECK_TSS_API(expr) \ - (void)(expr); \ - if (!PyThread_tss_is_created(&tss_key)) { \ - return raiseTestError("test_pythread_tss_key_state", \ - "TSS key initialization state was not " \ - "preserved after calling " #expr); } - CHECK_TSS_API(PyThread_tss_set(&tss_key, NULL)); - CHECK_TSS_API(PyThread_tss_get(&tss_key)); -#undef CHECK_TSS_API - PyThread_tss_delete(&tss_key); - if (PyThread_tss_is_created(&tss_key)) { - return raiseTestError("test_pythread_tss_key_state", - "PyThread_tss_delete called, but did not " - "set the key state to uninitialized"); - } - - Py_tss_t *ptr_key = PyThread_tss_alloc(); - if (ptr_key == NULL) { - PyErr_SetString(PyExc_RuntimeError, "PyThread_tss_alloc failed"); - return NULL; - } - if (PyThread_tss_is_created(ptr_key)) { - return raiseTestError("test_pythread_tss_key_state", - "TSS key not in an uninitialized state at " - "allocation time"); - } - PyThread_tss_free(ptr_key); - ptr_key = NULL; - Py_RETURN_NONE; -} - - -static PyObject* -new_hamt(PyObject *self, PyObject *args) -{ - return _PyContext_NewHamtForTests(); -} - - -/* def bad_get(self, obj, cls): - cls() - return repr(self) -*/ -static PyObject* -bad_get(PyObject *module, PyObject *const *args, Py_ssize_t nargs) -{ - PyObject *self, *obj, *cls; - if (!_PyArg_UnpackStack(args, nargs, "bad_get", 3, 3, &self, &obj, &cls)) { - return NULL; - } - - PyObject *res = PyObject_CallNoArgs(cls); - if (res == NULL) { - return NULL; - } - Py_DECREF(res); - - return PyObject_Repr(self); -} - - -#ifdef Py_REF_DEBUG -static PyObject * -negative_refcount(PyObject *self, PyObject *Py_UNUSED(args)) -{ - PyObject *obj = PyUnicode_FromString("negative_refcount"); - if (obj == NULL) { - return NULL; - } - assert(Py_REFCNT(obj) == 1); - - Py_SET_REFCNT(obj, 0); - /* Py_DECREF() must call _Py_NegativeRefcount() and abort Python */ - Py_DECREF(obj); - - Py_RETURN_NONE; -} -#endif - - -static PyObject* -test_write_unraisable_exc(PyObject *self, PyObject *args) -{ - PyObject *exc, *err_msg, *obj; - if (!PyArg_ParseTuple(args, "OOO", &exc, &err_msg, &obj)) { - return NULL; - } - - const char *err_msg_utf8; - if (err_msg != Py_None) { - err_msg_utf8 = PyUnicode_AsUTF8(err_msg); - if (err_msg_utf8 == NULL) { - return NULL; - } - } - else { - err_msg_utf8 = NULL; - } - - PyErr_SetObject((PyObject *)Py_TYPE(exc), exc); - _PyErr_WriteUnraisableMsg(err_msg_utf8, obj); - Py_RETURN_NONE; -} - - -static PyObject * -sequence_getitem(PyObject *self, PyObject *args) -{ - PyObject *seq; - Py_ssize_t i; - if (!PyArg_ParseTuple(args, "On", &seq, &i)) { - return NULL; - } - return PySequence_GetItem(seq, i); -} - - -static PyObject * -sequence_setitem(PyObject *self, PyObject *args) -{ - Py_ssize_t i; - PyObject *seq, *val; - if (!PyArg_ParseTuple(args, "OnO", &seq, &i, &val)) { - return NULL; - } - if (PySequence_SetItem(seq, i, val)) { - return NULL; - } - Py_RETURN_NONE; -} - - -/* Functions for testing C calling conventions (METH_*) are named meth_*, - * e.g. "meth_varargs" for METH_VARARGS. - * - * They all return a tuple of their C-level arguments, with None instead - * of NULL and Python tuples instead of C arrays. - */ - - -static PyObject* -_null_to_none(PyObject* obj) -{ - if (obj == NULL) { - Py_RETURN_NONE; - } - Py_INCREF(obj); - return obj; -} - -static PyObject* -meth_varargs(PyObject* self, PyObject* args) -{ - return Py_BuildValue("NO", _null_to_none(self), args); -} - -static PyObject* -meth_varargs_keywords(PyObject* self, PyObject* args, PyObject* kwargs) -{ - return Py_BuildValue("NON", _null_to_none(self), args, _null_to_none(kwargs)); -} - -static PyObject* -meth_o(PyObject* self, PyObject* obj) -{ - return Py_BuildValue("NO", _null_to_none(self), obj); -} - -static PyObject* -meth_noargs(PyObject* self, PyObject* ignored) -{ - return _null_to_none(self); -} - -static PyObject* -_fastcall_to_tuple(PyObject* const* args, Py_ssize_t nargs) -{ - PyObject *tuple = PyTuple_New(nargs); - if (tuple == NULL) { - return NULL; - } - for (Py_ssize_t i=0; i < nargs; i++) { - Py_INCREF(args[i]); - PyTuple_SET_ITEM(tuple, i, args[i]); - } - return tuple; -} - -static PyObject* -meth_fastcall(PyObject* self, PyObject* const* args, Py_ssize_t nargs) -{ - return Py_BuildValue( - "NN", _null_to_none(self), _fastcall_to_tuple(args, nargs) - ); -} - -static PyObject* -meth_fastcall_keywords(PyObject* self, PyObject* const* args, - Py_ssize_t nargs, PyObject* kwargs) -{ - PyObject *pyargs = _fastcall_to_tuple(args, nargs); - if (pyargs == NULL) { - return NULL; - } - assert(args != NULL || nargs == 0); - PyObject* const* args_offset = args == NULL ? NULL : args + nargs; - PyObject *pykwargs = PyObject_Vectorcall((PyObject*)&PyDict_Type, - args_offset, 0, kwargs); - return Py_BuildValue("NNN", _null_to_none(self), pyargs, pykwargs); -} - - -static PyObject* -pynumber_tobase(PyObject *module, PyObject *args) -{ - PyObject *obj; - int base; - if (!PyArg_ParseTuple(args, "Oi:pynumber_tobase", - &obj, &base)) { - return NULL; - } - return PyNumber_ToBase(obj, base); -} - - -static PyObject* -test_set_type_size(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - PyObject *obj = PyList_New(0); - if (obj == NULL) { - return NULL; - } - - // Ensure that following tests don't modify the object, - // to ensure that Py_DECREF() will not crash. - assert(Py_TYPE(obj) == &PyList_Type); - assert(Py_SIZE(obj) == 0); - - // bpo-39573: Test Py_SET_TYPE() and Py_SET_SIZE() functions. - Py_SET_TYPE(obj, &PyList_Type); - Py_SET_SIZE(obj, 0); - - Py_DECREF(obj); - Py_RETURN_NONE; -} - - -#define TEST_REFCOUNT() \ - do { \ - PyObject *obj = PyList_New(0); \ - if (obj == NULL) { \ - return NULL; \ - } \ - assert(Py_REFCNT(obj) == 1); \ - \ - /* test Py_NewRef() */ \ - PyObject *ref = Py_NewRef(obj); \ - assert(ref == obj); \ - assert(Py_REFCNT(obj) == 2); \ - Py_DECREF(ref); \ - \ - /* test Py_XNewRef() */ \ - PyObject *xref = Py_XNewRef(obj); \ - assert(xref == obj); \ - assert(Py_REFCNT(obj) == 2); \ - Py_DECREF(xref); \ - \ - assert(Py_XNewRef(NULL) == NULL); \ - \ - Py_DECREF(obj); \ - Py_RETURN_NONE; \ - } while (0) \ - - -// Test Py_NewRef() and Py_XNewRef() macros -static PyObject* -test_refcount_macros(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - TEST_REFCOUNT(); -} - -#undef Py_NewRef -#undef Py_XNewRef - -// Test Py_NewRef() and Py_XNewRef() functions, after undefining macros. -static PyObject* -test_refcount_funcs(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - TEST_REFCOUNT(); -} - - -// Test Py_Is() function -#define TEST_PY_IS() \ - do { \ - PyObject *o_none = Py_None; \ - PyObject *o_true = Py_True; \ - PyObject *o_false = Py_False; \ - PyObject *obj = PyList_New(0); \ - if (obj == NULL) { \ - return NULL; \ - } \ - \ - /* test Py_Is() */ \ - assert(Py_Is(obj, obj)); \ - assert(!Py_Is(obj, o_none)); \ - \ - /* test Py_None */ \ - assert(Py_Is(o_none, o_none)); \ - assert(!Py_Is(obj, o_none)); \ - \ - /* test Py_True */ \ - assert(Py_Is(o_true, o_true)); \ - assert(!Py_Is(o_false, o_true)); \ - assert(!Py_Is(obj, o_true)); \ - \ - /* test Py_False */ \ - assert(Py_Is(o_false, o_false)); \ - assert(!Py_Is(o_true, o_false)); \ - assert(!Py_Is(obj, o_false)); \ - \ - Py_DECREF(obj); \ - Py_RETURN_NONE; \ - } while (0) - -// Test Py_Is() macro -static PyObject* -test_py_is_macros(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - TEST_PY_IS(); -} - -#undef Py_Is - -// Test Py_Is() function, after undefining its macro. -static PyObject* -test_py_is_funcs(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - TEST_PY_IS(); -} - - -static PyObject * -test_fatal_error(PyObject *self, PyObject *args) -{ - char *message; - int release_gil = 0; - if (!PyArg_ParseTuple(args, "y|i:fatal_error", &message, &release_gil)) - return NULL; - if (release_gil) { - Py_BEGIN_ALLOW_THREADS - Py_FatalError(message); - Py_END_ALLOW_THREADS - } - else { - Py_FatalError(message); - } - // Py_FatalError() does not return, but exits the process. - Py_RETURN_NONE; -} - -// type->tp_version_tag -static PyObject * -type_get_version(PyObject *self, PyObject *type) -{ - if (!PyType_Check(type)) { - PyErr_SetString(PyExc_TypeError, "argument must be a type"); - return NULL; - } - PyObject *res = PyLong_FromUnsignedLong( - ((PyTypeObject *)type)->tp_version_tag); - if (res == NULL) { - assert(PyErr_Occurred()); - return NULL; - } - return res; -} - - -// Test PyThreadState C API -static PyObject * -test_tstate_capi(PyObject *self, PyObject *Py_UNUSED(args)) -{ - // PyThreadState_Get() - PyThreadState *tstate = PyThreadState_Get(); - assert(tstate != NULL); - - // PyThreadState_GET() - PyThreadState *tstate2 = PyThreadState_Get(); - assert(tstate2 == tstate); - - // private _PyThreadState_UncheckedGet() - PyThreadState *tstate3 = _PyThreadState_UncheckedGet(); - assert(tstate3 == tstate); - - // PyThreadState_EnterTracing(), PyThreadState_LeaveTracing() - PyThreadState_EnterTracing(tstate); - PyThreadState_LeaveTracing(tstate); - - // PyThreadState_GetDict(): no tstate argument - PyObject *dict = PyThreadState_GetDict(); - // PyThreadState_GetDict() API can return NULL if PyDict_New() fails, - // but it should not occur in practice. - assert(dict != NULL); - assert(PyDict_Check(dict)); - // dict is a borrowed reference - - // private _PyThreadState_GetDict() - PyObject *dict2 = _PyThreadState_GetDict(tstate); - assert(dict2 == dict); - // dict2 is a borrowed reference - - // PyThreadState_GetInterpreter() - PyInterpreterState *interp = PyThreadState_GetInterpreter(tstate); - assert(interp != NULL); - - // PyThreadState_GetFrame() - PyFrameObject*frame = PyThreadState_GetFrame(tstate); - assert(frame != NULL); - assert(PyFrame_Check(frame)); - Py_DECREF(frame); - - // PyThreadState_GetID() - uint64_t id = PyThreadState_GetID(tstate); - assert(id >= 1); - - Py_RETURN_NONE; -} - - -// Test PyFloat_Pack2(), PyFloat_Pack4() and PyFloat_Pack8() -static PyObject * -test_float_pack(PyObject *self, PyObject *args) -{ - int size; - double d; - int le; - if (!PyArg_ParseTuple(args, "idi", &size, &d, &le)) { - return NULL; - } - switch (size) - { - case 2: - { - char data[2]; - if (PyFloat_Pack2(d, data, le) < 0) { - return NULL; - } - return PyBytes_FromStringAndSize(data, Py_ARRAY_LENGTH(data)); - } - case 4: - { - char data[4]; - if (PyFloat_Pack4(d, data, le) < 0) { - return NULL; - } - return PyBytes_FromStringAndSize(data, Py_ARRAY_LENGTH(data)); - } - case 8: - { - char data[8]; - if (PyFloat_Pack8(d, data, le) < 0) { - return NULL; - } - return PyBytes_FromStringAndSize(data, Py_ARRAY_LENGTH(data)); - } - default: break; - } - - PyErr_SetString(PyExc_ValueError, "size must 2, 4 or 8"); - return NULL; -} - - -// Test PyFloat_Unpack2(), PyFloat_Unpack4() and PyFloat_Unpack8() -static PyObject * -test_float_unpack(PyObject *self, PyObject *args) -{ - assert(!PyErr_Occurred()); - const char *data; - Py_ssize_t size; - int le; - if (!PyArg_ParseTuple(args, "y#i", &data, &size, &le)) { - return NULL; - } - double d; - switch (size) - { - case 2: - d = PyFloat_Unpack2(data, le); - break; - case 4: - d = PyFloat_Unpack4(data, le); - break; - case 8: - d = PyFloat_Unpack8(data, le); - break; - default: - PyErr_SetString(PyExc_ValueError, "data length must 2, 4 or 8 bytes"); - return NULL; - } - - if (d == -1.0 && PyErr_Occurred()) { - return NULL; - } - return PyFloat_FromDouble(d); -} - -static PyObject * -frame_getlocals(PyObject *self, PyObject *frame) -{ - if (!PyFrame_Check(frame)) { - PyErr_SetString(PyExc_TypeError, "argument must be a frame"); - return NULL; - } - return PyFrame_GetLocals((PyFrameObject *)frame); -} - -static PyObject * -frame_getglobals(PyObject *self, PyObject *frame) -{ - if (!PyFrame_Check(frame)) { - PyErr_SetString(PyExc_TypeError, "argument must be a frame"); - return NULL; - } - return PyFrame_GetGlobals((PyFrameObject *)frame); -} - -static PyObject * -frame_getgenerator(PyObject *self, PyObject *frame) -{ - if (!PyFrame_Check(frame)) { - PyErr_SetString(PyExc_TypeError, "argument must be a frame"); - return NULL; - } - return PyFrame_GetGenerator((PyFrameObject *)frame); -} - -static PyObject * -frame_getbuiltins(PyObject *self, PyObject *frame) -{ - if (!PyFrame_Check(frame)) { - PyErr_SetString(PyExc_TypeError, "argument must be a frame"); - return NULL; - } - return PyFrame_GetBuiltins((PyFrameObject *)frame); -} - -static PyObject * -frame_getlasti(PyObject *self, PyObject *frame) -{ - if (!PyFrame_Check(frame)) { - PyErr_SetString(PyExc_TypeError, "argument must be a frame"); - return NULL; - } - int lasti = PyFrame_GetLasti((PyFrameObject *)frame); - if (lasti < 0) { - assert(lasti == -1); - Py_RETURN_NONE; - } - return PyLong_FromLong(lasti); -} - -static PyObject * -frame_new(PyObject *self, PyObject *args) -{ - PyObject *code, *globals, *locals; - if (!PyArg_ParseTuple(args, "OOO", &code, &globals, &locals)) { - return NULL; - } - if (!PyCode_Check(code)) { - PyErr_SetString(PyExc_TypeError, "argument must be a code object"); - return NULL; - } - PyThreadState *tstate = PyThreadState_Get(); - - return (PyObject *)PyFrame_New(tstate, (PyCodeObject *)code, globals, locals); -} - -static PyObject * -eval_get_func_name(PyObject *self, PyObject *func) -{ - return PyUnicode_FromString(PyEval_GetFuncName(func)); -} - -static PyObject * -eval_get_func_desc(PyObject *self, PyObject *func) -{ - return PyUnicode_FromString(PyEval_GetFuncDesc(func)); -} - -static PyObject * -eval_eval_code_ex(PyObject *mod, PyObject *pos_args) -{ - PyObject *result = NULL; - PyObject *code; - PyObject *globals; - PyObject *locals = NULL; - PyObject *args = NULL; - PyObject *kwargs = NULL; - PyObject *defaults = NULL; - PyObject *kw_defaults = NULL; - PyObject *closure = NULL; - - PyObject **c_kwargs = NULL; - - if (!PyArg_UnpackTuple(pos_args, - "eval_code_ex", - 2, - 8, - &code, - &globals, - &locals, - &args, - &kwargs, - &defaults, - &kw_defaults, - &closure)) - { - goto exit; - } - - if (!PyCode_Check(code)) { - PyErr_SetString(PyExc_TypeError, - "code must be a Python code object"); - goto exit; - } - - if (!PyDict_Check(globals)) { - PyErr_SetString(PyExc_TypeError, "globals must be a dict"); - goto exit; - } - - if (locals && !PyMapping_Check(locals)) { - PyErr_SetString(PyExc_TypeError, "locals must be a mapping"); - goto exit; - } - if (locals == Py_None) { - locals = NULL; - } - - PyObject **c_args = NULL; - Py_ssize_t c_args_len = 0; - - if (args) - { - if (!PyTuple_Check(args)) { - PyErr_SetString(PyExc_TypeError, "args must be a tuple"); - goto exit; - } else { - c_args = &PyTuple_GET_ITEM(args, 0); - c_args_len = PyTuple_Size(args); - } - } - - Py_ssize_t c_kwargs_len = 0; - - if (kwargs) - { - if (!PyDict_Check(kwargs)) { - PyErr_SetString(PyExc_TypeError, "keywords must be a dict"); - goto exit; - } else { - c_kwargs_len = PyDict_Size(kwargs); - if (c_kwargs_len > 0) { - c_kwargs = PyMem_NEW(PyObject*, 2 * c_kwargs_len); - if (!c_kwargs) { - PyErr_NoMemory(); - goto exit; - } - - Py_ssize_t i = 0; - Py_ssize_t pos = 0; - - while (PyDict_Next(kwargs, - &pos, - &c_kwargs[i], - &c_kwargs[i + 1])) - { - i += 2; - } - c_kwargs_len = i / 2; - /* XXX This is broken if the caller deletes dict items! */ - } - } - } - - - PyObject **c_defaults = NULL; - Py_ssize_t c_defaults_len = 0; - - if (defaults && PyTuple_Check(defaults)) { - c_defaults = &PyTuple_GET_ITEM(defaults, 0); - c_defaults_len = PyTuple_Size(defaults); - } - - if (kw_defaults && !PyDict_Check(kw_defaults)) { - PyErr_SetString(PyExc_TypeError, "kw_defaults must be a dict"); - goto exit; - } - - if (closure && !PyTuple_Check(closure)) { - PyErr_SetString(PyExc_TypeError, "closure must be a tuple of cells"); - goto exit; - } - - - result = PyEval_EvalCodeEx( - code, - globals, - locals, - c_args, - c_args_len, - c_kwargs, - c_kwargs_len, - c_defaults, - c_defaults_len, - kw_defaults, - closure - ); - -exit: - if (c_kwargs) { - PyMem_DEL(c_kwargs); - } - - return result; -} - -static PyObject * -get_feature_macros(PyObject *self, PyObject *Py_UNUSED(args)) -{ - PyObject *result = PyDict_New(); - if (!result) { - return NULL; - } - int res; -#include "_testcapi_feature_macros.inc" - return result; -} - -static PyObject * -test_code_api(PyObject *self, PyObject *Py_UNUSED(args)) -{ - PyCodeObject *co = PyCode_NewEmpty("_testcapi", "dummy", 1); - if (co == NULL) { - return NULL; - } - /* co_code */ - { - PyObject *co_code = PyCode_GetCode(co); - if (co_code == NULL) { - goto fail; - } - assert(PyBytes_CheckExact(co_code)); - if (PyObject_Length(co_code) == 0) { - PyErr_SetString(PyExc_ValueError, "empty co_code"); - Py_DECREF(co_code); - goto fail; - } - Py_DECREF(co_code); - } - /* co_varnames */ - { - PyObject *co_varnames = PyCode_GetVarnames(co); - if (co_varnames == NULL) { - goto fail; - } - if (!PyTuple_CheckExact(co_varnames)) { - PyErr_SetString(PyExc_TypeError, "co_varnames not tuple"); - Py_DECREF(co_varnames); - goto fail; - } - if (PyTuple_GET_SIZE(co_varnames) != 0) { - PyErr_SetString(PyExc_ValueError, "non-empty co_varnames"); - Py_DECREF(co_varnames); - goto fail; - } - Py_DECREF(co_varnames); - } - /* co_cellvars */ - { - PyObject *co_cellvars = PyCode_GetCellvars(co); - if (co_cellvars == NULL) { - goto fail; - } - if (!PyTuple_CheckExact(co_cellvars)) { - PyErr_SetString(PyExc_TypeError, "co_cellvars not tuple"); - Py_DECREF(co_cellvars); - goto fail; - } - if (PyTuple_GET_SIZE(co_cellvars) != 0) { - PyErr_SetString(PyExc_ValueError, "non-empty co_cellvars"); - Py_DECREF(co_cellvars); - goto fail; - } - Py_DECREF(co_cellvars); - } - /* co_freevars */ - { - PyObject *co_freevars = PyCode_GetFreevars(co); - if (co_freevars == NULL) { - goto fail; - } - if (!PyTuple_CheckExact(co_freevars)) { - PyErr_SetString(PyExc_TypeError, "co_freevars not tuple"); - Py_DECREF(co_freevars); - goto fail; - } - if (PyTuple_GET_SIZE(co_freevars) != 0) { - PyErr_SetString(PyExc_ValueError, "non-empty co_freevars"); - Py_DECREF(co_freevars); - goto fail; - } - Py_DECREF(co_freevars); - } - Py_DECREF(co); - Py_RETURN_NONE; -fail: - Py_DECREF(co); - return NULL; -} - -static int -record_func(PyObject *obj, PyFrameObject *f, int what, PyObject *arg) -{ - assert(PyList_Check(obj)); - PyObject *what_obj = NULL; - PyObject *line_obj = NULL; - PyObject *tuple = NULL; - int res = -1; - what_obj = PyLong_FromLong(what); - if (what_obj == NULL) { - goto error; - } - int line = PyFrame_GetLineNumber(f); - line_obj = PyLong_FromLong(line); - if (line_obj == NULL) { - goto error; - } - tuple = PyTuple_Pack(3, what_obj, line_obj, arg); - if (tuple == NULL) { - goto error; - } - PyTuple_SET_ITEM(tuple, 0, what_obj); - if (PyList_Append(obj, tuple)) { - goto error; - } - res = 0; -error: - Py_XDECREF(what_obj); - Py_XDECREF(line_obj); - Py_XDECREF(tuple); - return res; -} - -static PyObject * -settrace_to_record(PyObject *self, PyObject *list) -{ - - if (!PyList_Check(list)) { - PyErr_SetString(PyExc_TypeError, "argument must be a list"); - return NULL; - } - PyEval_SetTrace(record_func, list); - Py_RETURN_NONE; -} - -static PyObject *negative_dictoffset(PyObject *, PyObject *); - -static PyObject * -function_get_code(PyObject *self, PyObject *func) -{ - PyObject *code = PyFunction_GetCode(func); - if (code != NULL) { - Py_INCREF(code); - return code; - } else { - return NULL; - } -} - -static PyObject * -function_get_globals(PyObject *self, PyObject *func) -{ - PyObject *globals = PyFunction_GetGlobals(func); - if (globals != NULL) { - Py_INCREF(globals); - return globals; - } else { - return NULL; - } -} - -static PyObject * -function_get_module(PyObject *self, PyObject *func) -{ - PyObject *module = PyFunction_GetModule(func); - if (module != NULL) { - Py_INCREF(module); - return module; - } else { - return NULL; - } -} - -static PyObject *test_buildvalue_issue38913(PyObject *, PyObject *); -static PyObject *getargs_s_hash_int(PyObject *, PyObject *, PyObject*); -static PyObject *getargs_s_hash_int2(PyObject *, PyObject *, PyObject*); -static PyObject *gh_99240_clear_args(PyObject *, PyObject *); - -static PyMethodDef TestMethods[] = { - {"raise_exception", raise_exception, METH_VARARGS}, - {"raise_memoryerror", raise_memoryerror, METH_NOARGS}, - {"set_errno", set_errno, METH_VARARGS}, - {"test_config", test_config, METH_NOARGS}, - {"test_sizeof_c_types", test_sizeof_c_types, METH_NOARGS}, - {"test_datetime_capi", test_datetime_capi, METH_NOARGS}, - {"datetime_check_date", datetime_check_date, METH_VARARGS}, - {"datetime_check_time", datetime_check_time, METH_VARARGS}, - {"datetime_check_datetime", datetime_check_datetime, METH_VARARGS}, - {"datetime_check_delta", datetime_check_delta, METH_VARARGS}, - {"datetime_check_tzinfo", datetime_check_tzinfo, METH_VARARGS}, - {"make_timezones_capi", make_timezones_capi, METH_NOARGS}, - {"get_timezones_offset_zero", get_timezones_offset_zero, METH_NOARGS}, - {"get_timezone_utc_capi", get_timezone_utc_capi, METH_VARARGS}, - {"get_date_fromdate", get_date_fromdate, METH_VARARGS}, - {"get_datetime_fromdateandtime", get_datetime_fromdateandtime, METH_VARARGS}, - {"get_datetime_fromdateandtimeandfold", get_datetime_fromdateandtimeandfold, METH_VARARGS}, - {"get_time_fromtime", get_time_fromtime, METH_VARARGS}, - {"get_time_fromtimeandfold", get_time_fromtimeandfold, METH_VARARGS}, - {"get_delta_fromdsu", get_delta_fromdsu, METH_VARARGS}, - {"get_date_fromtimestamp", get_date_fromtimestamp, METH_VARARGS}, - {"get_datetime_fromtimestamp", get_datetime_fromtimestamp, METH_VARARGS}, - {"PyDateTime_GET", test_PyDateTime_GET, METH_O}, - {"PyDateTime_DATE_GET", test_PyDateTime_DATE_GET, METH_O}, - {"PyDateTime_TIME_GET", test_PyDateTime_TIME_GET, METH_O}, - {"PyDateTime_DELTA_GET", test_PyDateTime_DELTA_GET, METH_O}, - {"test_gc_control", test_gc_control, METH_NOARGS}, - {"test_list_api", test_list_api, METH_NOARGS}, - {"test_dict_iteration", test_dict_iteration, METH_NOARGS}, - {"dict_getitem_knownhash", dict_getitem_knownhash, METH_VARARGS}, - {"test_lazy_hash_inheritance", test_lazy_hash_inheritance,METH_NOARGS}, - {"test_long_api", test_long_api, METH_NOARGS}, - {"test_xincref_doesnt_leak",test_xincref_doesnt_leak, METH_NOARGS}, - {"test_incref_doesnt_leak", test_incref_doesnt_leak, METH_NOARGS}, - {"test_xdecref_doesnt_leak",test_xdecref_doesnt_leak, METH_NOARGS}, - {"test_decref_doesnt_leak", test_decref_doesnt_leak, METH_NOARGS}, - {"test_structseq_newtype_doesnt_leak", - test_structseq_newtype_doesnt_leak, METH_NOARGS}, - {"test_structseq_newtype_null_descr_doc", - test_structseq_newtype_null_descr_doc, METH_NOARGS}, - {"test_incref_decref_API", test_incref_decref_API, METH_NOARGS}, - {"test_long_and_overflow", test_long_and_overflow, METH_NOARGS}, - {"test_long_as_double", test_long_as_double, METH_NOARGS}, - {"test_long_as_size_t", test_long_as_size_t, METH_NOARGS}, - {"test_long_as_unsigned_long_long_mask", - test_long_as_unsigned_long_long_mask, METH_NOARGS}, - {"test_long_numbits", test_long_numbits, METH_NOARGS}, - {"test_k_code", test_k_code, METH_NOARGS}, - {"test_empty_argparse", test_empty_argparse, METH_NOARGS}, - {"parse_tuple_and_keywords", parse_tuple_and_keywords, METH_VARARGS}, - {"pyobject_repr_from_null", pyobject_repr_from_null, METH_NOARGS}, - {"pyobject_str_from_null", pyobject_str_from_null, METH_NOARGS}, - {"pyobject_bytes_from_null", pyobject_bytes_from_null, METH_NOARGS}, - {"test_string_from_format", (PyCFunction)test_string_from_format, METH_NOARGS}, - {"test_with_docstring", test_with_docstring, METH_NOARGS, - PyDoc_STR("This is a pretty normal docstring.")}, - {"test_string_to_double", test_string_to_double, METH_NOARGS}, - {"test_unicode_compare_with_ascii", test_unicode_compare_with_ascii, - METH_NOARGS}, - {"test_capsule", (PyCFunction)test_capsule, METH_NOARGS}, - {"test_from_contiguous", (PyCFunction)test_from_contiguous, METH_NOARGS}, -#if (defined(__linux__) || defined(__FreeBSD__)) && defined(__GNUC__) - {"test_pep3118_obsolete_write_locks", (PyCFunction)test_pep3118_obsolete_write_locks, METH_NOARGS}, -#endif - {"getbuffer_with_null_view", getbuffer_with_null_view, METH_O}, - {"PyBuffer_SizeFromFormat", test_PyBuffer_SizeFromFormat, METH_VARARGS}, - {"test_buildvalue_N", test_buildvalue_N, METH_NOARGS}, - {"negative_dictoffset", negative_dictoffset, METH_NOARGS}, - {"test_buildvalue_issue38913", test_buildvalue_issue38913, METH_NOARGS}, - {"get_args", get_args, METH_VARARGS}, - {"test_get_statictype_slots", test_get_statictype_slots, METH_NOARGS}, - {"test_get_type_name", test_get_type_name, METH_NOARGS}, - {"test_get_type_qualname", test_get_type_qualname, METH_NOARGS}, - {"test_type_from_ephemeral_spec", test_type_from_ephemeral_spec, METH_NOARGS}, - {"get_kwargs", _PyCFunction_CAST(get_kwargs), - METH_VARARGS|METH_KEYWORDS}, - {"getargs_tuple", getargs_tuple, METH_VARARGS}, - {"getargs_keywords", _PyCFunction_CAST(getargs_keywords), - METH_VARARGS|METH_KEYWORDS}, - {"getargs_keyword_only", _PyCFunction_CAST(getargs_keyword_only), - METH_VARARGS|METH_KEYWORDS}, - {"getargs_positional_only_and_keywords", - _PyCFunction_CAST(getargs_positional_only_and_keywords), - METH_VARARGS|METH_KEYWORDS}, - {"getargs_b", getargs_b, METH_VARARGS}, - {"getargs_B", getargs_B, METH_VARARGS}, - {"getargs_h", getargs_h, METH_VARARGS}, - {"getargs_H", getargs_H, METH_VARARGS}, - {"getargs_I", getargs_I, METH_VARARGS}, - {"getargs_k", getargs_k, METH_VARARGS}, - {"getargs_i", getargs_i, METH_VARARGS}, - {"getargs_l", getargs_l, METH_VARARGS}, - {"getargs_n", getargs_n, METH_VARARGS}, - {"getargs_p", getargs_p, METH_VARARGS}, - {"getargs_L", getargs_L, METH_VARARGS}, - {"getargs_K", getargs_K, METH_VARARGS}, - {"test_longlong_api", test_longlong_api, METH_NOARGS}, - {"test_long_long_and_overflow",test_long_long_and_overflow, METH_NOARGS}, - {"test_L_code", test_L_code, METH_NOARGS}, - {"getargs_f", getargs_f, METH_VARARGS}, - {"getargs_d", getargs_d, METH_VARARGS}, - {"getargs_D", getargs_D, METH_VARARGS}, - {"getargs_S", getargs_S, METH_VARARGS}, - {"getargs_Y", getargs_Y, METH_VARARGS}, - {"getargs_U", getargs_U, METH_VARARGS}, - {"getargs_c", getargs_c, METH_VARARGS}, - {"getargs_C", getargs_C, METH_VARARGS}, - {"getargs_s", getargs_s, METH_VARARGS}, - {"getargs_s_star", getargs_s_star, METH_VARARGS}, - {"getargs_s_hash", getargs_s_hash, METH_VARARGS}, - {"getargs_s_hash_int", _PyCFunction_CAST(getargs_s_hash_int), - METH_VARARGS|METH_KEYWORDS}, - {"getargs_s_hash_int2", _PyCFunction_CAST(getargs_s_hash_int2), - METH_VARARGS|METH_KEYWORDS}, - {"gh_99240_clear_args", gh_99240_clear_args, METH_VARARGS}, - {"getargs_z", getargs_z, METH_VARARGS}, - {"getargs_z_star", getargs_z_star, METH_VARARGS}, - {"getargs_z_hash", getargs_z_hash, METH_VARARGS}, - {"getargs_y", getargs_y, METH_VARARGS}, - {"getargs_y_star", getargs_y_star, METH_VARARGS}, - {"getargs_y_hash", getargs_y_hash, METH_VARARGS}, - {"getargs_u", getargs_u, METH_VARARGS}, - {"getargs_u_hash", getargs_u_hash, METH_VARARGS}, - {"getargs_Z", getargs_Z, METH_VARARGS}, - {"getargs_Z_hash", getargs_Z_hash, METH_VARARGS}, - {"getargs_w_star", getargs_w_star, METH_VARARGS}, - {"getargs_es", getargs_es, METH_VARARGS}, - {"getargs_et", getargs_et, METH_VARARGS}, - {"getargs_es_hash", getargs_es_hash, METH_VARARGS}, - {"getargs_et_hash", getargs_et_hash, METH_VARARGS}, - {"codec_incrementalencoder", - (PyCFunction)codec_incrementalencoder, METH_VARARGS}, - {"codec_incrementaldecoder", - (PyCFunction)codec_incrementaldecoder, METH_VARARGS}, - {"test_s_code", test_s_code, METH_NOARGS}, -#if USE_UNICODE_WCHAR_CACHE - {"test_u_code", test_u_code, METH_NOARGS}, - {"test_Z_code", test_Z_code, METH_NOARGS}, -#endif /* USE_UNICODE_WCHAR_CACHE */ - {"test_widechar", test_widechar, METH_NOARGS}, - {"unicode_aswidechar", unicode_aswidechar, METH_VARARGS}, - {"unicode_aswidecharstring",unicode_aswidecharstring, METH_VARARGS}, - {"unicode_asucs4", unicode_asucs4, METH_VARARGS}, - {"unicode_asutf8", unicode_asutf8, METH_VARARGS}, - {"unicode_asutf8andsize", unicode_asutf8andsize, METH_VARARGS}, - {"unicode_findchar", unicode_findchar, METH_VARARGS}, - {"unicode_copycharacters", unicode_copycharacters, METH_VARARGS}, -#if USE_UNICODE_WCHAR_CACHE - {"unicode_legacy_string", unicode_legacy_string, METH_VARARGS}, -#endif /* USE_UNICODE_WCHAR_CACHE */ - {"_test_thread_state", test_thread_state, METH_VARARGS}, - {"_pending_threadfunc", pending_threadfunc, METH_VARARGS}, -#ifdef HAVE_GETTIMEOFDAY - {"profile_int", profile_int, METH_NOARGS}, -#endif - {"traceback_print", traceback_print, METH_VARARGS}, - {"exception_print", exception_print, METH_VARARGS}, - {"set_exception", test_set_exception, METH_O}, - {"set_exc_info", test_set_exc_info, METH_VARARGS}, - {"argparsing", argparsing, METH_VARARGS}, - {"code_newempty", code_newempty, METH_VARARGS}, - {"eval_code_ex", eval_eval_code_ex, METH_VARARGS}, - {"make_exception_with_doc", _PyCFunction_CAST(make_exception_with_doc), - METH_VARARGS | METH_KEYWORDS}, - {"make_memoryview_from_NULL_pointer", make_memoryview_from_NULL_pointer, - METH_NOARGS}, - {"crash_no_current_thread", crash_no_current_thread, METH_NOARGS}, - {"run_in_subinterp", run_in_subinterp, METH_VARARGS}, - {"pytime_object_to_time_t", test_pytime_object_to_time_t, METH_VARARGS}, - {"pytime_object_to_timeval", test_pytime_object_to_timeval, METH_VARARGS}, - {"pytime_object_to_timespec", test_pytime_object_to_timespec, METH_VARARGS}, - {"with_tp_del", with_tp_del, METH_VARARGS}, - {"create_cfunction", create_cfunction, METH_NOARGS}, - {"test_pymem_alloc0", test_pymem_alloc0, METH_NOARGS}, - {"test_pymem_setrawallocators",test_pymem_setrawallocators, METH_NOARGS}, - {"test_pymem_setallocators",test_pymem_setallocators, METH_NOARGS}, - {"test_pyobject_setallocators",test_pyobject_setallocators, METH_NOARGS}, - {"set_nomemory", (PyCFunction)set_nomemory, METH_VARARGS, - PyDoc_STR("set_nomemory(start:int, stop:int = 0)")}, - {"remove_mem_hooks", remove_mem_hooks, METH_NOARGS, - PyDoc_STR("Remove memory hooks.")}, - {"no_docstring", - (PyCFunction)test_with_docstring, METH_NOARGS}, - {"docstring_empty", - (PyCFunction)test_with_docstring, METH_NOARGS, - docstring_empty}, - {"docstring_no_signature", - (PyCFunction)test_with_docstring, METH_NOARGS, - docstring_no_signature}, - {"docstring_with_invalid_signature", - (PyCFunction)test_with_docstring, METH_NOARGS, - docstring_with_invalid_signature}, - {"docstring_with_invalid_signature2", - (PyCFunction)test_with_docstring, METH_NOARGS, - docstring_with_invalid_signature2}, - {"docstring_with_signature", - (PyCFunction)test_with_docstring, METH_NOARGS, - docstring_with_signature}, - {"docstring_with_signature_but_no_doc", - (PyCFunction)test_with_docstring, METH_NOARGS, - docstring_with_signature_but_no_doc}, - {"docstring_with_signature_and_extra_newlines", - (PyCFunction)test_with_docstring, METH_NOARGS, - docstring_with_signature_and_extra_newlines}, - {"docstring_with_signature_with_defaults", - (PyCFunction)test_with_docstring, METH_NOARGS, - docstring_with_signature_with_defaults}, - {"call_in_temporary_c_thread", call_in_temporary_c_thread, METH_VARARGS, - PyDoc_STR("set_error_class(error_class) -> None")}, - {"join_temporary_c_thread", join_temporary_c_thread, METH_NOARGS}, - {"pymarshal_write_long_to_file", - pymarshal_write_long_to_file, METH_VARARGS}, - {"pymarshal_write_object_to_file", - pymarshal_write_object_to_file, METH_VARARGS}, - {"pymarshal_read_short_from_file", - pymarshal_read_short_from_file, METH_VARARGS}, - {"pymarshal_read_long_from_file", - pymarshal_read_long_from_file, METH_VARARGS}, - {"pymarshal_read_last_object_from_file", - pymarshal_read_last_object_from_file, METH_VARARGS}, - {"pymarshal_read_object_from_file", - pymarshal_read_object_from_file, METH_VARARGS}, - {"return_null_without_error", return_null_without_error, METH_NOARGS}, - {"return_result_with_error", return_result_with_error, METH_NOARGS}, - {"getitem_with_error", getitem_with_error, METH_VARARGS}, - {"Py_CompileString", pycompilestring, METH_O}, - {"PyTime_FromSeconds", test_pytime_fromseconds, METH_VARARGS}, - {"PyTime_FromSecondsObject", test_pytime_fromsecondsobject, METH_VARARGS}, - {"PyTime_AsSecondsDouble", test_pytime_assecondsdouble, METH_VARARGS}, - {"PyTime_AsTimeval", test_PyTime_AsTimeval, METH_VARARGS}, - {"PyTime_AsTimeval_clamp", test_PyTime_AsTimeval_clamp, METH_VARARGS}, -#ifdef HAVE_CLOCK_GETTIME - {"PyTime_AsTimespec", test_PyTime_AsTimespec, METH_VARARGS}, - {"PyTime_AsTimespec_clamp", test_PyTime_AsTimespec_clamp, METH_VARARGS}, -#endif - {"PyTime_AsMilliseconds", test_PyTime_AsMilliseconds, METH_VARARGS}, - {"PyTime_AsMicroseconds", test_PyTime_AsMicroseconds, METH_VARARGS}, - {"pymem_buffer_overflow", pymem_buffer_overflow, METH_NOARGS}, - {"pymem_api_misuse", pymem_api_misuse, METH_NOARGS}, - {"pymem_malloc_without_gil", pymem_malloc_without_gil, METH_NOARGS}, - {"pymem_getallocatorsname", test_pymem_getallocatorsname, METH_NOARGS}, - {"check_pyobject_null_is_freed", check_pyobject_null_is_freed, METH_NOARGS}, - {"check_pyobject_uninitialized_is_freed", check_pyobject_uninitialized_is_freed, METH_NOARGS}, - {"check_pyobject_forbidden_bytes_is_freed", check_pyobject_forbidden_bytes_is_freed, METH_NOARGS}, - {"check_pyobject_freed_is_freed", check_pyobject_freed_is_freed, METH_NOARGS}, - {"pyobject_malloc_without_gil", pyobject_malloc_without_gil, METH_NOARGS}, - {"tracemalloc_track", tracemalloc_track, METH_VARARGS}, - {"tracemalloc_untrack", tracemalloc_untrack, METH_VARARGS}, - {"tracemalloc_get_traceback", tracemalloc_get_traceback, METH_VARARGS}, - {"dict_get_version", dict_get_version, METH_VARARGS}, - {"raise_SIGINT_then_send_None", raise_SIGINT_then_send_None, METH_VARARGS}, - {"pyobject_fastcall", test_pyobject_fastcall, METH_VARARGS}, - {"pyobject_fastcalldict", test_pyobject_fastcalldict, METH_VARARGS}, - {"pyobject_vectorcall", test_pyobject_vectorcall, METH_VARARGS}, - {"pyvectorcall_call", test_pyvectorcall_call, METH_VARARGS}, - {"stack_pointer", stack_pointer, METH_NOARGS}, -#ifdef W_STOPCODE - {"W_STOPCODE", py_w_stopcode, METH_VARARGS}, -#endif - {"get_mapping_keys", get_mapping_keys, METH_O}, - {"get_mapping_values", get_mapping_values, METH_O}, - {"get_mapping_items", get_mapping_items, METH_O}, - {"test_mapping_has_key_string", test_mapping_has_key_string, METH_NOARGS}, - {"mapping_has_key", mapping_has_key, METH_VARARGS}, - {"sequence_set_slice", sequence_set_slice, METH_VARARGS}, - {"sequence_del_slice", sequence_del_slice, METH_VARARGS}, - {"test_pythread_tss_key_state", test_pythread_tss_key_state, METH_VARARGS}, - {"hamt", new_hamt, METH_NOARGS}, - {"bad_get", _PyCFunction_CAST(bad_get), METH_FASTCALL}, -#ifdef Py_REF_DEBUG - {"negative_refcount", negative_refcount, METH_NOARGS}, -#endif - {"write_unraisable_exc", test_write_unraisable_exc, METH_VARARGS}, - {"sequence_getitem", sequence_getitem, METH_VARARGS}, - {"sequence_setitem", sequence_setitem, METH_VARARGS}, - {"meth_varargs", meth_varargs, METH_VARARGS}, - {"meth_varargs_keywords", _PyCFunction_CAST(meth_varargs_keywords), METH_VARARGS|METH_KEYWORDS}, - {"meth_o", meth_o, METH_O}, - {"meth_noargs", meth_noargs, METH_NOARGS}, - {"meth_fastcall", _PyCFunction_CAST(meth_fastcall), METH_FASTCALL}, - {"meth_fastcall_keywords", _PyCFunction_CAST(meth_fastcall_keywords), METH_FASTCALL|METH_KEYWORDS}, - {"pynumber_tobase", pynumber_tobase, METH_VARARGS}, - {"without_gc", without_gc, METH_O}, - {"test_set_type_size", test_set_type_size, METH_NOARGS}, - {"test_refcount_macros", test_refcount_macros, METH_NOARGS}, - {"test_refcount_funcs", test_refcount_funcs, METH_NOARGS}, - {"test_py_is_macros", test_py_is_macros, METH_NOARGS}, - {"test_py_is_funcs", test_py_is_funcs, METH_NOARGS}, - {"fatal_error", test_fatal_error, METH_VARARGS, - PyDoc_STR("fatal_error(message, release_gil=False): call Py_FatalError(message)")}, - {"type_get_version", type_get_version, METH_O, PyDoc_STR("type->tp_version_tag")}, - {"test_tstate_capi", test_tstate_capi, METH_NOARGS, NULL}, - {"float_pack", test_float_pack, METH_VARARGS, NULL}, - {"float_unpack", test_float_unpack, METH_VARARGS, NULL}, - {"frame_getlocals", frame_getlocals, METH_O, NULL}, - {"frame_getglobals", frame_getglobals, METH_O, NULL}, - {"frame_getgenerator", frame_getgenerator, METH_O, NULL}, - {"frame_getbuiltins", frame_getbuiltins, METH_O, NULL}, - {"frame_getlasti", frame_getlasti, METH_O, NULL}, - {"frame_new", frame_new, METH_VARARGS, NULL}, - {"eval_get_func_name", eval_get_func_name, METH_O, NULL}, - {"eval_get_func_desc", eval_get_func_desc, METH_O, NULL}, - {"get_feature_macros", get_feature_macros, METH_NOARGS, NULL}, - {"test_code_api", test_code_api, METH_NOARGS, NULL}, - {"settrace_to_record", settrace_to_record, METH_O, NULL}, - {"function_get_code", function_get_code, METH_O, NULL}, - {"function_get_globals", function_get_globals, METH_O, NULL}, - {"function_get_module", function_get_module, METH_O, NULL}, - {NULL, NULL} /* sentinel */ -}; - -typedef struct { - char bool_member; - char byte_member; - unsigned char ubyte_member; - short short_member; - unsigned short ushort_member; - int int_member; - unsigned int uint_member; - long long_member; - unsigned long ulong_member; - Py_ssize_t pyssizet_member; - float float_member; - double double_member; - char inplace_member[6]; - long long longlong_member; - unsigned long long ulonglong_member; -} all_structmembers; - -typedef struct { - PyObject_HEAD - all_structmembers structmembers; -} test_structmembers; - -static struct PyMemberDef test_members[] = { - {"T_BOOL", T_BOOL, offsetof(test_structmembers, structmembers.bool_member), 0, NULL}, - {"T_BYTE", T_BYTE, offsetof(test_structmembers, structmembers.byte_member), 0, NULL}, - {"T_UBYTE", T_UBYTE, offsetof(test_structmembers, structmembers.ubyte_member), 0, NULL}, - {"T_SHORT", T_SHORT, offsetof(test_structmembers, structmembers.short_member), 0, NULL}, - {"T_USHORT", T_USHORT, offsetof(test_structmembers, structmembers.ushort_member), 0, NULL}, - {"T_INT", T_INT, offsetof(test_structmembers, structmembers.int_member), 0, NULL}, - {"T_UINT", T_UINT, offsetof(test_structmembers, structmembers.uint_member), 0, NULL}, - {"T_LONG", T_LONG, offsetof(test_structmembers, structmembers.long_member), 0, NULL}, - {"T_ULONG", T_ULONG, offsetof(test_structmembers, structmembers.ulong_member), 0, NULL}, - {"T_PYSSIZET", T_PYSSIZET, offsetof(test_structmembers, structmembers.pyssizet_member), 0, NULL}, - {"T_FLOAT", T_FLOAT, offsetof(test_structmembers, structmembers.float_member), 0, NULL}, - {"T_DOUBLE", T_DOUBLE, offsetof(test_structmembers, structmembers.double_member), 0, NULL}, - {"T_STRING_INPLACE", T_STRING_INPLACE, offsetof(test_structmembers, structmembers.inplace_member), 0, NULL}, - {"T_LONGLONG", T_LONGLONG, offsetof(test_structmembers, structmembers.longlong_member), 0, NULL}, - {"T_ULONGLONG", T_ULONGLONG, offsetof(test_structmembers, structmembers.ulonglong_member), 0, NULL}, - {NULL} -}; - - -static PyObject * -test_structmembers_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) -{ - static char *keywords[] = { - "T_BOOL", "T_BYTE", "T_UBYTE", "T_SHORT", "T_USHORT", - "T_INT", "T_UINT", "T_LONG", "T_ULONG", "T_PYSSIZET", - "T_FLOAT", "T_DOUBLE", "T_STRING_INPLACE", - "T_LONGLONG", "T_ULONGLONG", - NULL}; - static const char fmt[] = "|bbBhHiIlknfds#LK"; - test_structmembers *ob; - const char *s = NULL; - Py_ssize_t string_len = 0; - ob = PyObject_New(test_structmembers, type); - if (ob == NULL) - return NULL; - memset(&ob->structmembers, 0, sizeof(all_structmembers)); - if (!PyArg_ParseTupleAndKeywords(args, kwargs, fmt, keywords, - &ob->structmembers.bool_member, - &ob->structmembers.byte_member, - &ob->structmembers.ubyte_member, - &ob->structmembers.short_member, - &ob->structmembers.ushort_member, - &ob->structmembers.int_member, - &ob->structmembers.uint_member, - &ob->structmembers.long_member, - &ob->structmembers.ulong_member, - &ob->structmembers.pyssizet_member, - &ob->structmembers.float_member, - &ob->structmembers.double_member, - &s, &string_len - , &ob->structmembers.longlong_member, - &ob->structmembers.ulonglong_member - )) { - Py_DECREF(ob); - return NULL; - } - if (s != NULL) { - if (string_len > 5) { - Py_DECREF(ob); - PyErr_SetString(PyExc_ValueError, "string too long"); - return NULL; - } - strcpy(ob->structmembers.inplace_member, s); - } - else { - strcpy(ob->structmembers.inplace_member, ""); - } - return (PyObject *)ob; -} - -static void -test_structmembers_free(PyObject *ob) -{ - PyObject_Free(ob); -} - -static PyTypeObject test_structmembersType = { - PyVarObject_HEAD_INIT(NULL, 0) - "test_structmembersType", - sizeof(test_structmembers), /* tp_basicsize */ - 0, /* tp_itemsize */ - test_structmembers_free, /* destructor tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - PyObject_GenericSetAttr, /* tp_setattro */ - 0, /* tp_as_buffer */ - 0, /* tp_flags */ - "Type containing all structmember types", - 0, /* traverseproc tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - test_members, /* tp_members */ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - test_structmembers_new, /* tp_new */ -}; - - -typedef struct { - PyObject_HEAD -} matmulObject; - -static PyObject * -matmulType_matmul(PyObject *self, PyObject *other) -{ - return Py_BuildValue("(sOO)", "matmul", self, other); -} - -static PyObject * -matmulType_imatmul(PyObject *self, PyObject *other) -{ - return Py_BuildValue("(sOO)", "imatmul", self, other); -} - -static void -matmulType_dealloc(PyObject *self) -{ - Py_TYPE(self)->tp_free(self); -} - -static PyNumberMethods matmulType_as_number = { - 0, /* nb_add */ - 0, /* nb_subtract */ - 0, /* nb_multiply */ - 0, /* nb_remainde r*/ - 0, /* nb_divmod */ - 0, /* nb_power */ - 0, /* nb_negative */ - 0, /* tp_positive */ - 0, /* tp_absolute */ - 0, /* tp_bool */ - 0, /* nb_invert */ - 0, /* nb_lshift */ - 0, /* nb_rshift */ - 0, /* nb_and */ - 0, /* nb_xor */ - 0, /* nb_or */ - 0, /* nb_int */ - 0, /* nb_reserved */ - 0, /* nb_float */ - 0, /* nb_inplace_add */ - 0, /* nb_inplace_subtract */ - 0, /* nb_inplace_multiply */ - 0, /* nb_inplace_remainder */ - 0, /* nb_inplace_power */ - 0, /* nb_inplace_lshift */ - 0, /* nb_inplace_rshift */ - 0, /* nb_inplace_and */ - 0, /* nb_inplace_xor */ - 0, /* nb_inplace_or */ - 0, /* nb_floor_divide */ - 0, /* nb_true_divide */ - 0, /* nb_inplace_floor_divide */ - 0, /* nb_inplace_true_divide */ - 0, /* nb_index */ - matmulType_matmul, /* nb_matrix_multiply */ - matmulType_imatmul /* nb_matrix_inplace_multiply */ -}; - -static PyTypeObject matmulType = { - PyVarObject_HEAD_INIT(NULL, 0) - "matmulType", - sizeof(matmulObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - matmulType_dealloc, /* destructor tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - &matmulType_as_number, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - PyObject_GenericSetAttr, /* tp_setattro */ - 0, /* tp_as_buffer */ - 0, /* tp_flags */ - "C level type with matrix operations defined", - 0, /* traverseproc tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - 0, /* tp_members */ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - PyType_GenericNew, /* tp_new */ - PyObject_Del, /* tp_free */ -}; - -typedef struct { - PyObject_HEAD -} ipowObject; - -static PyObject * -ipowType_ipow(PyObject *self, PyObject *other, PyObject *mod) -{ - return Py_BuildValue("OO", other, mod); -} - -static PyNumberMethods ipowType_as_number = { - .nb_inplace_power = ipowType_ipow -}; - -static PyTypeObject ipowType = { - PyVarObject_HEAD_INIT(NULL, 0) - .tp_name = "ipowType", - .tp_basicsize = sizeof(ipowObject), - .tp_as_number = &ipowType_as_number, - .tp_new = PyType_GenericNew -}; - -typedef struct { - PyObject_HEAD - PyObject *ao_iterator; -} awaitObject; - - -static PyObject * -awaitObject_new(PyTypeObject *type, PyObject *args, PyObject *kwds) -{ - PyObject *v; - awaitObject *ao; - - if (!PyArg_UnpackTuple(args, "awaitObject", 1, 1, &v)) - return NULL; - - ao = (awaitObject *)type->tp_alloc(type, 0); - if (ao == NULL) { - return NULL; - } - - Py_INCREF(v); - ao->ao_iterator = v; - - return (PyObject *)ao; -} - - -static void -awaitObject_dealloc(awaitObject *ao) -{ - Py_CLEAR(ao->ao_iterator); - Py_TYPE(ao)->tp_free(ao); -} - - -static PyObject * -awaitObject_await(awaitObject *ao) -{ - Py_INCREF(ao->ao_iterator); - return ao->ao_iterator; -} - -static PyAsyncMethods awaitType_as_async = { - (unaryfunc)awaitObject_await, /* am_await */ - 0, /* am_aiter */ - 0, /* am_anext */ - 0, /* am_send */ -}; - - -static PyTypeObject awaitType = { - PyVarObject_HEAD_INIT(NULL, 0) - "awaitType", - sizeof(awaitObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)awaitObject_dealloc, /* destructor tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - &awaitType_as_async, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - PyObject_GenericSetAttr, /* tp_setattro */ - 0, /* tp_as_buffer */ - 0, /* tp_flags */ - "C level type with tp_as_async", - 0, /* traverseproc tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - 0, /* tp_members */ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - awaitObject_new, /* tp_new */ - PyObject_Del, /* tp_free */ -}; - - -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_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 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 */ - PyDoc_STR("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) +static PyObject * +function_get_code(PyObject *self, PyObject *func) { - PyObject *type = (PyObject *)&PyRecursingInfinitelyError_Type; + PyObject *code = PyFunction_GetCode(func); + if (code != NULL) { + return Py_NewRef(code); + } else { + return NULL; + } +} - /* Instantiating this exception starts infinite recursion. */ - Py_INCREF(type); - PyErr_SetObject(type, NULL); - return -1; +static PyObject * +function_get_globals(PyObject *self, PyObject *func) +{ + PyObject *globals = PyFunction_GetGlobals(func); + if (globals != NULL) { + return Py_NewRef(globals); + } else { + return NULL; + } } +static PyObject * +function_get_module(PyObject *self, PyObject *func) +{ + PyObject *module = PyFunction_GetModule(func); + if (module != NULL) { + return Py_NewRef(module); + } else { + return NULL; + } +} -/* Test bpo-35983: create a subclass of "list" which checks that instances - * are not deallocated twice */ +static PyObject * +function_get_defaults(PyObject *self, PyObject *func) +{ + PyObject *defaults = PyFunction_GetDefaults(func); + if (defaults != NULL) { + return Py_NewRef(defaults); + } else if (PyErr_Occurred()) { + return NULL; + } else { + Py_RETURN_NONE; // This can happen when `defaults` are set to `None` + } +} -typedef struct { - PyListObject list; - int deallocated; -} MyListObject; +static PyObject * +function_set_defaults(PyObject *self, PyObject *args) +{ + PyObject *func = NULL, *defaults = NULL; + if (!PyArg_ParseTuple(args, "OO", &func, &defaults)) { + return NULL; + } + int result = PyFunction_SetDefaults(func, defaults); + if (result == -1) + return NULL; + Py_RETURN_NONE; +} static PyObject * -MyList_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +function_get_kw_defaults(PyObject *self, PyObject *func) { - PyObject* op = PyList_Type.tp_new(type, args, kwds); - ((MyListObject*)op)->deallocated = 0; - return op; + PyObject *defaults = PyFunction_GetKwDefaults(func); + if (defaults != NULL) { + return Py_NewRef(defaults); + } else if (PyErr_Occurred()) { + return NULL; + } else { + Py_RETURN_NONE; // This can happen when `kwdefaults` are set to `None` + } } -void -MyList_dealloc(MyListObject* op) +static PyObject * +function_set_kw_defaults(PyObject *self, PyObject *args) { - if (op->deallocated) { - /* We cannot raise exceptions here but we still want the testsuite - * to fail when we hit this */ - Py_FatalError("MyList instance deallocated twice"); + PyObject *func = NULL, *defaults = NULL; + if (!PyArg_ParseTuple(args, "OO", &func, &defaults)) { + return NULL; } - op->deallocated = 1; - PyList_Type.tp_dealloc((PyObject *)op); + int result = PyFunction_SetKwDefaults(func, defaults); + if (result == -1) + return NULL; + Py_RETURN_NONE; } -static PyTypeObject MyList_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "MyList", - sizeof(MyListObject), - 0, - (destructor)MyList_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 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 */ - 0, /* 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, /* &PyList_Type */ /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - MyList_new, /* tp_new */ +struct atexit_data { + int called; }; - -/* Test PEP 560 */ - -typedef struct { - PyObject_HEAD - PyObject *item; -} PyGenericAliasObject; - static void -generic_alias_dealloc(PyGenericAliasObject *self) +callback(void *data) { - Py_CLEAR(self->item); - Py_TYPE(self)->tp_free((PyObject *)self); + ((struct atexit_data *)data)->called += 1; } static PyObject * -generic_alias_mro_entries(PyGenericAliasObject *self, PyObject *bases) +test_atexit(PyObject *self, PyObject *Py_UNUSED(args)) { - return PyTuple_Pack(1, self->item); -} + PyThreadState *oldts = PyThreadState_Swap(NULL); + PyThreadState *tstate = Py_NewInterpreter(); -static PyMethodDef generic_alias_methods[] = { - {"__mro_entries__", _PyCFunction_CAST(generic_alias_mro_entries), METH_O, NULL}, - {NULL} /* sentinel */ -}; + struct atexit_data data = {0}; + int res = _Py_AtExit(tstate->interp, callback, (void *)&data); + Py_EndInterpreter(tstate); + PyThreadState_Swap(oldts); + if (res < 0) { + return NULL; + } + if (data.called == 0) { + PyErr_SetString(PyExc_RuntimeError, "atexit callback not called"); + return NULL; + } + Py_RETURN_NONE; +} -static PyTypeObject GenericAlias_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "GenericAlias", - sizeof(PyGenericAliasObject), - 0, - .tp_dealloc = (destructor)generic_alias_dealloc, - .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, - .tp_methods = generic_alias_methods, -}; static PyObject * -generic_alias_new(PyObject *item) +sys_getobject(PyObject *Py_UNUSED(module), PyObject *arg) { - PyGenericAliasObject *o = PyObject_New(PyGenericAliasObject, &GenericAlias_Type); - if (o == NULL) { + const char *name; + Py_ssize_t size; + if (!PyArg_Parse(arg, "z#", &name, &size)) { return NULL; } - Py_INCREF(item); - o->item = item; - return (PyObject*) o; + PyObject *result = PySys_GetObject(name); + if (result == NULL) { + result = PyExc_AttributeError; + } + return Py_NewRef(result); } -typedef struct { - PyObject_HEAD -} PyGenericObject; - static PyObject * -generic_class_getitem(PyObject *type, PyObject *item) +sys_setobject(PyObject *Py_UNUSED(module), PyObject *args) { - return generic_alias_new(item); + const char *name; + Py_ssize_t size; + PyObject *value; + if (!PyArg_ParseTuple(args, "z#O", &name, &size, &value)) { + return NULL; + } + NULLABLE(value); + RETURN_INT(PySys_SetObject(name, value)); } -static PyMethodDef generic_methods[] = { - {"__class_getitem__", generic_class_getitem, METH_O|METH_CLASS, NULL}, - {NULL} /* sentinel */ -}; -static PyTypeObject Generic_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "Generic", - sizeof(PyGenericObject), - 0, - .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, - .tp_methods = generic_methods, +static PyObject *test_buildvalue_issue38913(PyObject *, PyObject *); + +static PyMethodDef TestMethods[] = { + {"set_errno", set_errno, METH_VARARGS}, + {"test_config", test_config, METH_NOARGS}, + {"test_sizeof_c_types", test_sizeof_c_types, METH_NOARGS}, + {"test_list_api", test_list_api, METH_NOARGS}, + {"test_dict_iteration", test_dict_iteration, METH_NOARGS}, + {"dict_getitem_knownhash", dict_getitem_knownhash, METH_VARARGS}, + {"test_lazy_hash_inheritance", test_lazy_hash_inheritance,METH_NOARGS}, + {"test_xincref_doesnt_leak",test_xincref_doesnt_leak, METH_NOARGS}, + {"test_incref_doesnt_leak", test_incref_doesnt_leak, METH_NOARGS}, + {"test_xdecref_doesnt_leak",test_xdecref_doesnt_leak, METH_NOARGS}, + {"test_decref_doesnt_leak", test_decref_doesnt_leak, METH_NOARGS}, + {"test_structseq_newtype_doesnt_leak", + test_structseq_newtype_doesnt_leak, METH_NOARGS}, + {"test_structseq_newtype_null_descr_doc", + test_structseq_newtype_null_descr_doc, METH_NOARGS}, + {"test_incref_decref_API", test_incref_decref_API, METH_NOARGS}, + {"pyobject_repr_from_null", pyobject_repr_from_null, METH_NOARGS}, + {"pyobject_str_from_null", pyobject_str_from_null, METH_NOARGS}, + {"pyobject_bytes_from_null", pyobject_bytes_from_null, METH_NOARGS}, + {"test_string_to_double", test_string_to_double, METH_NOARGS}, + {"test_capsule", (PyCFunction)test_capsule, METH_NOARGS}, + {"test_from_contiguous", (PyCFunction)test_from_contiguous, METH_NOARGS}, +#if (defined(__linux__) || defined(__FreeBSD__)) && defined(__GNUC__) + {"test_pep3118_obsolete_write_locks", (PyCFunction)test_pep3118_obsolete_write_locks, METH_NOARGS}, +#endif + {"getbuffer_with_null_view", getbuffer_with_null_view, METH_O}, + {"PyBuffer_SizeFromFormat", test_PyBuffer_SizeFromFormat, METH_VARARGS}, + {"test_buildvalue_N", test_buildvalue_N, METH_NOARGS}, + {"test_buildvalue_issue38913", test_buildvalue_issue38913, METH_NOARGS}, + {"test_get_statictype_slots", test_get_statictype_slots, METH_NOARGS}, + {"test_get_type_name", test_get_type_name, METH_NOARGS}, + {"test_get_type_qualname", test_get_type_qualname, METH_NOARGS}, + {"test_get_type_dict", test_get_type_dict, METH_NOARGS}, + {"_test_thread_state", test_thread_state, METH_VARARGS}, +#ifndef MS_WINDOWS + {"_spawn_pthread_waiter", spawn_pthread_waiter, METH_NOARGS}, + {"_end_spawned_pthread", end_spawned_pthread, METH_NOARGS}, +#endif + {"_pending_threadfunc", pending_threadfunc, METH_VARARGS}, +#ifdef HAVE_GETTIMEOFDAY + {"profile_int", profile_int, METH_NOARGS}, +#endif + {"argparsing", argparsing, METH_VARARGS}, + {"code_newempty", code_newempty, METH_VARARGS}, + {"eval_code_ex", eval_eval_code_ex, METH_VARARGS}, + {"make_memoryview_from_NULL_pointer", make_memoryview_from_NULL_pointer, + METH_NOARGS}, + {"crash_no_current_thread", crash_no_current_thread, METH_NOARGS}, + {"test_current_tstate_matches", test_current_tstate_matches, METH_NOARGS}, + {"run_in_subinterp", run_in_subinterp, METH_VARARGS}, + {"run_in_subinterp_with_config", + _PyCFunction_CAST(run_in_subinterp_with_config), + METH_VARARGS | METH_KEYWORDS}, + {"get_crossinterp_data", get_crossinterp_data, METH_VARARGS}, + {"restore_crossinterp_data", restore_crossinterp_data, METH_VARARGS}, + {"create_cfunction", create_cfunction, METH_NOARGS}, + {"call_in_temporary_c_thread", call_in_temporary_c_thread, METH_VARARGS, + PyDoc_STR("set_error_class(error_class) -> None")}, + {"join_temporary_c_thread", join_temporary_c_thread, METH_NOARGS}, + {"pymarshal_write_long_to_file", + pymarshal_write_long_to_file, METH_VARARGS}, + {"pymarshal_write_object_to_file", + pymarshal_write_object_to_file, METH_VARARGS}, + {"pymarshal_read_short_from_file", + pymarshal_read_short_from_file, METH_VARARGS}, + {"pymarshal_read_long_from_file", + pymarshal_read_long_from_file, METH_VARARGS}, + {"pymarshal_read_last_object_from_file", + pymarshal_read_last_object_from_file, METH_VARARGS}, + {"pymarshal_read_object_from_file", + pymarshal_read_object_from_file, METH_VARARGS}, + {"return_null_without_error", return_null_without_error, METH_NOARGS}, + {"return_result_with_error", return_result_with_error, METH_NOARGS}, + {"getitem_with_error", getitem_with_error, METH_VARARGS}, + {"Py_CompileString", pycompilestring, METH_O}, + {"dict_get_version", dict_get_version, METH_VARARGS}, + {"raise_SIGINT_then_send_None", raise_SIGINT_then_send_None, METH_VARARGS}, + {"stack_pointer", stack_pointer, METH_NOARGS}, +#ifdef W_STOPCODE + {"W_STOPCODE", py_w_stopcode, METH_VARARGS}, +#endif + {"test_pythread_tss_key_state", test_pythread_tss_key_state, METH_VARARGS}, + {"hamt", new_hamt, METH_NOARGS}, + {"bad_get", _PyCFunction_CAST(bad_get), METH_FASTCALL}, +#ifdef Py_REF_DEBUG + {"negative_refcount", negative_refcount, METH_NOARGS}, + {"decref_freed_object", decref_freed_object, METH_NOARGS}, +#endif + {"meth_varargs", meth_varargs, METH_VARARGS}, + {"meth_varargs_keywords", _PyCFunction_CAST(meth_varargs_keywords), METH_VARARGS|METH_KEYWORDS}, + {"meth_o", meth_o, METH_O}, + {"meth_noargs", meth_noargs, METH_NOARGS}, + {"meth_fastcall", _PyCFunction_CAST(meth_fastcall), METH_FASTCALL}, + {"meth_fastcall_keywords", _PyCFunction_CAST(meth_fastcall_keywords), METH_FASTCALL|METH_KEYWORDS}, + {"pynumber_tobase", pynumber_tobase, METH_VARARGS}, + {"test_set_type_size", test_set_type_size, METH_NOARGS}, + {"test_py_clear", test_py_clear, METH_NOARGS}, + {"test_py_setref", test_py_setref, METH_NOARGS}, + {"test_refcount_macros", test_refcount_macros, METH_NOARGS}, + {"test_refcount_funcs", test_refcount_funcs, METH_NOARGS}, + {"test_py_is_macros", test_py_is_macros, METH_NOARGS}, + {"test_py_is_funcs", test_py_is_funcs, METH_NOARGS}, + {"type_get_version", type_get_version, METH_O, PyDoc_STR("type->tp_version_tag")}, + {"type_assign_version", type_assign_version, METH_O, PyDoc_STR("PyUnstable_Type_AssignVersionTag")}, + {"type_get_tp_bases", type_get_tp_bases, METH_O}, + {"type_get_tp_mro", type_get_tp_mro, METH_O}, + {"get_basic_static_type", get_basic_static_type, METH_VARARGS, NULL}, + {"test_tstate_capi", test_tstate_capi, METH_NOARGS, NULL}, + {"frame_getlocals", frame_getlocals, METH_O, NULL}, + {"frame_getglobals", frame_getglobals, METH_O, NULL}, + {"frame_getgenerator", frame_getgenerator, METH_O, NULL}, + {"frame_getbuiltins", frame_getbuiltins, METH_O, NULL}, + {"frame_getlasti", frame_getlasti, METH_O, NULL}, + {"frame_new", frame_new, METH_VARARGS, NULL}, + {"frame_getvar", test_frame_getvar, METH_VARARGS, NULL}, + {"frame_getvarstring", test_frame_getvarstring, METH_VARARGS, NULL}, + {"eval_get_func_name", eval_get_func_name, METH_O, NULL}, + {"eval_get_func_desc", eval_get_func_desc, METH_O, NULL}, + {"gen_get_code", gen_get_code, METH_O, NULL}, + {"get_feature_macros", get_feature_macros, METH_NOARGS, NULL}, + {"test_code_api", test_code_api, METH_NOARGS, NULL}, + {"settrace_to_error", settrace_to_error, METH_O, NULL}, + {"settrace_to_record", settrace_to_record, METH_O, NULL}, + {"test_macros", test_macros, METH_NOARGS, NULL}, + {"clear_managed_dict", clear_managed_dict, METH_O, NULL}, + {"function_get_code", function_get_code, METH_O, NULL}, + {"function_get_globals", function_get_globals, METH_O, NULL}, + {"function_get_module", function_get_module, METH_O, NULL}, + {"function_get_defaults", function_get_defaults, METH_O, NULL}, + {"function_set_defaults", function_set_defaults, METH_VARARGS, NULL}, + {"function_get_kw_defaults", function_get_kw_defaults, METH_O, NULL}, + {"function_set_kw_defaults", function_set_kw_defaults, METH_VARARGS, NULL}, + {"test_atexit", test_atexit, METH_NOARGS}, + {"sys_getobject", sys_getobject, METH_O}, + {"sys_setobject", sys_setobject, METH_VARARGS}, + {NULL, NULL} /* sentinel */ }; -/* Test PEP 590 */ - typedef struct { PyObject_HEAD - vectorcallfunc vectorcall; -} MethodDescriptorObject; - -static PyObject * -MethodDescriptor_vectorcall(PyObject *callable, PyObject *const *args, - size_t nargsf, PyObject *kwnames) -{ - /* True if using the vectorcall function in MethodDescriptorObject - * but False for MethodDescriptor2Object */ - MethodDescriptorObject *md = (MethodDescriptorObject *)callable; - return PyBool_FromLong(md->vectorcall != NULL); -} - -static PyObject * -MethodDescriptor_new(PyTypeObject* type, PyObject* args, PyObject *kw) -{ - MethodDescriptorObject *op = (MethodDescriptorObject *)type->tp_alloc(type, 0); - op->vectorcall = MethodDescriptor_vectorcall; - return (PyObject *)op; -} +} matmulObject; static PyObject * -func_descr_get(PyObject *func, PyObject *obj, PyObject *type) +matmulType_matmul(PyObject *self, PyObject *other) { - if (obj == Py_None || obj == NULL) { - Py_INCREF(func); - return func; - } - return PyMethod_New(func, obj); + return Py_BuildValue("(sOO)", "matmul", self, other); } static PyObject * -nop_descr_get(PyObject *func, PyObject *obj, PyObject *type) +matmulType_imatmul(PyObject *self, PyObject *other) { - Py_INCREF(func); - return func; + return Py_BuildValue("(sOO)", "imatmul", self, other); } -static PyObject * -call_return_args(PyObject *self, PyObject *args, PyObject *kwargs) +static void +matmulType_dealloc(PyObject *self) { - Py_INCREF(args); - return args; + Py_TYPE(self)->tp_free(self); } -static PyTypeObject MethodDescriptorBase_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "MethodDescriptorBase", - sizeof(MethodDescriptorObject), - .tp_new = MethodDescriptor_new, - .tp_call = PyVectorcall_Call, - .tp_vectorcall_offset = offsetof(MethodDescriptorObject, vectorcall), - .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | - Py_TPFLAGS_METHOD_DESCRIPTOR | Py_TPFLAGS_HAVE_VECTORCALL, - .tp_descr_get = func_descr_get, -}; - -static PyTypeObject MethodDescriptorDerived_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "MethodDescriptorDerived", - .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, +static PyNumberMethods matmulType_as_number = { + 0, /* nb_add */ + 0, /* nb_subtract */ + 0, /* nb_multiply */ + 0, /* nb_remainde r*/ + 0, /* nb_divmod */ + 0, /* nb_power */ + 0, /* nb_negative */ + 0, /* tp_positive */ + 0, /* tp_absolute */ + 0, /* tp_bool */ + 0, /* nb_invert */ + 0, /* nb_lshift */ + 0, /* nb_rshift */ + 0, /* nb_and */ + 0, /* nb_xor */ + 0, /* nb_or */ + 0, /* nb_int */ + 0, /* nb_reserved */ + 0, /* nb_float */ + 0, /* nb_inplace_add */ + 0, /* nb_inplace_subtract */ + 0, /* nb_inplace_multiply */ + 0, /* nb_inplace_remainder */ + 0, /* nb_inplace_power */ + 0, /* nb_inplace_lshift */ + 0, /* nb_inplace_rshift */ + 0, /* nb_inplace_and */ + 0, /* nb_inplace_xor */ + 0, /* nb_inplace_or */ + 0, /* nb_floor_divide */ + 0, /* nb_true_divide */ + 0, /* nb_inplace_floor_divide */ + 0, /* nb_inplace_true_divide */ + 0, /* nb_index */ + matmulType_matmul, /* nb_matrix_multiply */ + matmulType_imatmul /* nb_matrix_inplace_multiply */ }; -static PyTypeObject MethodDescriptorNopGet_Type = { +static PyTypeObject matmulType = { PyVarObject_HEAD_INIT(NULL, 0) - "MethodDescriptorNopGet", - .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, - .tp_call = call_return_args, - .tp_descr_get = nop_descr_get, + "matmulType", + sizeof(matmulObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + matmulType_dealloc, /* destructor tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + 0, /* tp_repr */ + &matmulType_as_number, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + PyObject_GenericSetAttr, /* tp_setattro */ + 0, /* tp_as_buffer */ + 0, /* tp_flags */ + "C level type with matrix operations defined", + 0, /* traverseproc tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + PyType_GenericNew, /* tp_new */ + PyObject_Del, /* tp_free */ }; typedef struct { - MethodDescriptorObject base; - vectorcallfunc vectorcall; -} MethodDescriptor2Object; + PyObject_HEAD +} ipowObject; static PyObject * -MethodDescriptor2_new(PyTypeObject* type, PyObject* args, PyObject *kw) +ipowType_ipow(PyObject *self, PyObject *other, PyObject *mod) { - MethodDescriptor2Object *op = PyObject_New(MethodDescriptor2Object, type); - op->base.vectorcall = NULL; - op->vectorcall = MethodDescriptor_vectorcall; - return (PyObject *)op; + return Py_BuildValue("OO", other, mod); } -static PyTypeObject MethodDescriptor2_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "MethodDescriptor2", - sizeof(MethodDescriptor2Object), - .tp_new = MethodDescriptor2_new, - .tp_call = PyVectorcall_Call, - .tp_vectorcall_offset = offsetof(MethodDescriptor2Object, vectorcall), - .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_VECTORCALL, -}; - -PyDoc_STRVAR(heapdocctype__doc__, -"HeapDocCType(arg1, arg2)\n" -"--\n" -"\n" -"somedoc"); - -typedef struct { - PyObject_HEAD -} HeapDocCTypeObject; - -static PyType_Slot HeapDocCType_slots[] = { - {Py_tp_doc, (char*)heapdocctype__doc__}, - {0}, -}; - -static PyType_Spec HeapDocCType_spec = { - "_testcapi.HeapDocCType", - sizeof(HeapDocCTypeObject), - 0, - Py_TPFLAGS_DEFAULT, - HeapDocCType_slots -}; - -typedef struct { - PyObject_HEAD -} HeapTypeNameObject; - -static PyType_Slot HeapTypeNameType_slots[] = { - {0}, +static PyNumberMethods ipowType_as_number = { + .nb_inplace_power = ipowType_ipow }; -static PyType_Spec HeapTypeNameType_Spec = { - .name = "_testcapi.HeapTypeNameType", - .basicsize = sizeof(HeapTypeNameObject), - .flags = Py_TPFLAGS_DEFAULT, - .slots = HeapTypeNameType_slots, +static PyTypeObject ipowType = { + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name = "ipowType", + .tp_basicsize = sizeof(ipowObject), + .tp_as_number = &ipowType_as_number, + .tp_new = PyType_GenericNew }; typedef struct { PyObject_HEAD -} NullTpDocTypeObject; - -static PyType_Slot NullTpDocType_slots[] = { - {Py_tp_doc, NULL}, - {0, 0}, -}; + PyObject *ao_iterator; +} awaitObject; -static PyType_Spec NullTpDocType_spec = { - "_testcapi.NullTpDocType", - sizeof(NullTpDocTypeObject), - 0, - Py_TPFLAGS_DEFAULT, - NullTpDocType_slots -}; +static PyObject * +awaitObject_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyObject *v; + awaitObject *ao; -PyDoc_STRVAR(heapgctype__doc__, -"A heap type with GC, and with overridden dealloc.\n\n" -"The 'value' attribute is set to 10 in __init__."); + if (!PyArg_UnpackTuple(args, "awaitObject", 1, 1, &v)) + return NULL; -typedef struct { - PyObject_HEAD - int value; -} HeapCTypeObject; + ao = (awaitObject *)type->tp_alloc(type, 0); + if (ao == NULL) { + return NULL; + } -static struct PyMemberDef heapctype_members[] = { - {"value", T_INT, offsetof(HeapCTypeObject, value)}, - {NULL} /* Sentinel */ -}; + ao->ao_iterator = Py_NewRef(v); -static int -heapctype_init(PyObject *self, PyObject *args, PyObject *kwargs) -{ - ((HeapCTypeObject *)self)->value = 10; - return 0; + return (PyObject *)ao; } -static int -heapgcctype_traverse(HeapCTypeObject *self, visitproc visit, void *arg) -{ - Py_VISIT(Py_TYPE(self)); - return 0; -} static void -heapgcctype_dealloc(HeapCTypeObject *self) +awaitObject_dealloc(awaitObject *ao) { - PyTypeObject *tp = Py_TYPE(self); - PyObject_GC_UnTrack(self); - PyObject_GC_Del(self); - Py_DECREF(tp); + Py_CLEAR(ao->ao_iterator); + Py_TYPE(ao)->tp_free(ao); } -static PyType_Slot HeapGcCType_slots[] = { - {Py_tp_init, heapctype_init}, - {Py_tp_members, heapctype_members}, - {Py_tp_dealloc, heapgcctype_dealloc}, - {Py_tp_traverse, heapgcctype_traverse}, - {Py_tp_doc, (char*)heapgctype__doc__}, - {0, 0}, -}; - -static PyType_Spec HeapGcCType_spec = { - "_testcapi.HeapGcCType", - sizeof(HeapCTypeObject), - 0, - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, - HeapGcCType_slots -}; - -PyDoc_STRVAR(heapctype__doc__, -"A heap type without GC, but with overridden dealloc.\n\n" -"The 'value' attribute is set to 10 in __init__."); -static void -heapctype_dealloc(HeapCTypeObject *self) +static PyObject * +awaitObject_await(awaitObject *ao) { - PyTypeObject *tp = Py_TYPE(self); - PyObject_Free(self); - Py_DECREF(tp); + return Py_NewRef(ao->ao_iterator); } -static PyType_Slot HeapCType_slots[] = { - {Py_tp_init, heapctype_init}, - {Py_tp_members, heapctype_members}, - {Py_tp_dealloc, heapctype_dealloc}, - {Py_tp_doc, (char*)heapctype__doc__}, - {0, 0}, -}; - -static PyType_Spec HeapCType_spec = { - "_testcapi.HeapCType", - sizeof(HeapCTypeObject), - 0, - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, - HeapCType_slots +static PyAsyncMethods awaitType_as_async = { + (unaryfunc)awaitObject_await, /* am_await */ + 0, /* am_aiter */ + 0, /* am_anext */ + 0, /* am_send */ }; -PyDoc_STRVAR(heapctypesubclass__doc__, -"Subclass of HeapCType, without GC.\n\n" -"__init__ sets the 'value' attribute to 10 and 'value2' to 20."); - -typedef struct { - HeapCTypeObject base; - int value2; -} HeapCTypeSubclassObject; - -static int -heapctypesubclass_init(PyObject *self, PyObject *args, PyObject *kwargs) -{ - /* Call __init__ of the superclass */ - if (heapctype_init(self, args, kwargs) < 0) { - return -1; - } - /* Initialize additional element */ - ((HeapCTypeSubclassObject *)self)->value2 = 20; - return 0; -} - -static struct PyMemberDef heapctypesubclass_members[] = { - {"value2", T_INT, offsetof(HeapCTypeSubclassObject, value2)}, - {NULL} /* Sentinel */ -}; -static PyType_Slot HeapCTypeSubclass_slots[] = { - {Py_tp_init, heapctypesubclass_init}, - {Py_tp_members, heapctypesubclass_members}, - {Py_tp_doc, (char*)heapctypesubclass__doc__}, - {0, 0}, +static PyTypeObject awaitType = { + PyVarObject_HEAD_INIT(NULL, 0) + "awaitType", + sizeof(awaitObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)awaitObject_dealloc, /* destructor tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + &awaitType_as_async, /* tp_as_async */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + PyObject_GenericGetAttr, /* tp_getattro */ + PyObject_GenericSetAttr, /* tp_setattro */ + 0, /* tp_as_buffer */ + 0, /* tp_flags */ + "C level type with tp_as_async", + 0, /* traverseproc tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + awaitObject_new, /* tp_new */ + PyObject_Del, /* tp_free */ }; -static PyType_Spec HeapCTypeSubclass_spec = { - "_testcapi.HeapCTypeSubclass", - sizeof(HeapCTypeSubclassObject), - 0, - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, - HeapCTypeSubclass_slots -}; -PyDoc_STRVAR(heapctypewithbuffer__doc__, -"Heap type with buffer support.\n\n" -"The buffer is set to [b'1', b'2', b'3', b'4']"); +/* Test bpo-35983: create a subclass of "list" which checks that instances + * are not deallocated twice */ typedef struct { - HeapCTypeObject base; - char buffer[4]; -} HeapCTypeWithBufferObject; - -static int -heapctypewithbuffer_getbuffer(HeapCTypeWithBufferObject *self, Py_buffer *view, int flags) -{ - self->buffer[0] = '1'; - self->buffer[1] = '2'; - self->buffer[2] = '3'; - self->buffer[3] = '4'; - return PyBuffer_FillInfo( - view, (PyObject*)self, (void *)self->buffer, 4, 1, flags); -} - -static void -heapctypewithbuffer_releasebuffer(HeapCTypeWithBufferObject *self, Py_buffer *view) -{ - assert(view->obj == (void*) self); -} - -static PyType_Slot HeapCTypeWithBuffer_slots[] = { - {Py_bf_getbuffer, heapctypewithbuffer_getbuffer}, - {Py_bf_releasebuffer, heapctypewithbuffer_releasebuffer}, - {Py_tp_doc, (char*)heapctypewithbuffer__doc__}, - {0, 0}, -}; - -static PyType_Spec HeapCTypeWithBuffer_spec = { - "_testcapi.HeapCTypeWithBuffer", - sizeof(HeapCTypeWithBufferObject), - 0, - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, - HeapCTypeWithBuffer_slots -}; - -PyDoc_STRVAR(heapctypesubclasswithfinalizer__doc__, -"Subclass of HeapCType with a finalizer that reassigns __class__.\n\n" -"__class__ is set to plain HeapCTypeSubclass during finalization.\n" -"__init__ sets the 'value' attribute to 10 and 'value2' to 20."); + PyListObject list; + int deallocated; +} MyListObject; -static int -heapctypesubclasswithfinalizer_init(PyObject *self, PyObject *args, PyObject *kwargs) +static PyObject * +MyList_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { - PyTypeObject *base = (PyTypeObject *)PyType_GetSlot(Py_TYPE(self), Py_tp_base); - initproc base_init = PyType_GetSlot(base, Py_tp_init); - base_init(self, args, kwargs); - return 0; + PyObject* op = PyList_Type.tp_new(type, args, kwds); + ((MyListObject*)op)->deallocated = 0; + return op; } -static void -heapctypesubclasswithfinalizer_finalize(PyObject *self) +void +MyList_dealloc(MyListObject* op) { - PyObject *error_type, *error_value, *error_traceback, *m; - PyObject *oldtype = NULL, *newtype = NULL, *refcnt = NULL; - - /* Save the current exception, if any. */ - PyErr_Fetch(&error_type, &error_value, &error_traceback); - - m = PyState_FindModule(&_testcapimodule); - if (m == NULL) { - goto cleanup_finalize; - } - oldtype = PyObject_GetAttrString(m, "HeapCTypeSubclassWithFinalizer"); - newtype = PyObject_GetAttrString(m, "HeapCTypeSubclass"); - if (oldtype == NULL || newtype == NULL) { - goto cleanup_finalize; - } - - if (PyObject_SetAttrString(self, "__class__", newtype) < 0) { - goto cleanup_finalize; - } - refcnt = PyLong_FromSsize_t(Py_REFCNT(oldtype)); - if (refcnt == NULL) { - goto cleanup_finalize; - } - if (PyObject_SetAttrString(oldtype, "refcnt_in_del", refcnt) < 0) { - goto cleanup_finalize; - } - Py_DECREF(refcnt); - refcnt = PyLong_FromSsize_t(Py_REFCNT(newtype)); - if (refcnt == NULL) { - goto cleanup_finalize; - } - if (PyObject_SetAttrString(newtype, "refcnt_in_del", refcnt) < 0) { - goto cleanup_finalize; + if (op->deallocated) { + /* We cannot raise exceptions here but we still want the testsuite + * to fail when we hit this */ + Py_FatalError("MyList instance deallocated twice"); } - -cleanup_finalize: - Py_XDECREF(oldtype); - Py_XDECREF(newtype); - Py_XDECREF(refcnt); - - /* Restore the saved exception. */ - PyErr_Restore(error_type, error_value, error_traceback); + op->deallocated = 1; + PyList_Type.tp_dealloc((PyObject *)op); } -static PyType_Slot HeapCTypeSubclassWithFinalizer_slots[] = { - {Py_tp_init, heapctypesubclasswithfinalizer_init}, - {Py_tp_members, heapctypesubclass_members}, - {Py_tp_finalize, heapctypesubclasswithfinalizer_finalize}, - {Py_tp_doc, (char*)heapctypesubclasswithfinalizer__doc__}, - {0, 0}, -}; - -static PyType_Spec HeapCTypeSubclassWithFinalizer_spec = { - "_testcapi.HeapCTypeSubclassWithFinalizer", - sizeof(HeapCTypeSubclassObject), +static PyTypeObject MyList_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "MyList", + sizeof(MyListObject), 0, - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_FINALIZE, - HeapCTypeSubclassWithFinalizer_slots + (destructor)MyList_dealloc, /* tp_dealloc */ + 0, /* tp_vectorcall_offset */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_as_async */ + 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 */ + 0, /* 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, /* &PyList_Type */ /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + MyList_new, /* tp_new */ }; +/* Test PEP 560 */ + typedef struct { PyObject_HEAD - PyObject *dict; -} HeapCTypeWithDictObject; + PyObject *item; +} PyGenericAliasObject; static void -heapctypewithdict_dealloc(HeapCTypeWithDictObject* self) +generic_alias_dealloc(PyGenericAliasObject *self) { - - PyTypeObject *tp = Py_TYPE(self); - Py_XDECREF(self->dict); - PyObject_Free(self); - Py_DECREF(tp); + Py_CLEAR(self->item); + Py_TYPE(self)->tp_free((PyObject *)self); } -static PyGetSetDef heapctypewithdict_getsetlist[] = { - {"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict}, - {NULL} /* Sentinel */ -}; - -static struct PyMemberDef heapctypewithdict_members[] = { - {"dictobj", T_OBJECT, offsetof(HeapCTypeWithDictObject, dict)}, - {"__dictoffset__", T_PYSSIZET, offsetof(HeapCTypeWithDictObject, dict), READONLY}, - {NULL} /* Sentinel */ -}; - -static PyType_Slot HeapCTypeWithDict_slots[] = { - {Py_tp_members, heapctypewithdict_members}, - {Py_tp_getset, heapctypewithdict_getsetlist}, - {Py_tp_dealloc, heapctypewithdict_dealloc}, - {0, 0}, -}; - -static PyType_Spec HeapCTypeWithDict_spec = { - "_testcapi.HeapCTypeWithDict", - sizeof(HeapCTypeWithDictObject), - 0, - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, - HeapCTypeWithDict_slots -}; - -static PyType_Spec HeapCTypeWithDict2_spec = { - "_testcapi.HeapCTypeWithDict2", - sizeof(HeapCTypeWithDictObject), - 0, - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, - HeapCTypeWithDict_slots -}; - -static struct PyMemberDef heapctypewithnegativedict_members[] = { - {"dictobj", T_OBJECT, offsetof(HeapCTypeWithDictObject, dict)}, - {"__dictoffset__", T_PYSSIZET, -(Py_ssize_t)sizeof(void*), READONLY}, - {NULL} /* Sentinel */ -}; - -static PyType_Slot HeapCTypeWithNegativeDict_slots[] = { - {Py_tp_members, heapctypewithnegativedict_members}, - {Py_tp_getset, heapctypewithdict_getsetlist}, - {Py_tp_dealloc, heapctypewithdict_dealloc}, - {0, 0}, -}; - -static PyType_Spec HeapCTypeWithNegativeDict_spec = { - "_testcapi.HeapCTypeWithNegativeDict", - sizeof(HeapCTypeWithDictObject), - 0, - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, - HeapCTypeWithNegativeDict_slots -}; - -typedef struct { - PyObject_HEAD - PyObject *weakreflist; -} HeapCTypeWithWeakrefObject; - -static struct PyMemberDef heapctypewithweakref_members[] = { - {"weakreflist", T_OBJECT, offsetof(HeapCTypeWithWeakrefObject, weakreflist)}, - {"__weaklistoffset__", T_PYSSIZET, - offsetof(HeapCTypeWithWeakrefObject, weakreflist), READONLY}, - {NULL} /* Sentinel */ -}; - -static void -heapctypewithweakref_dealloc(HeapCTypeWithWeakrefObject* self) +static PyObject * +generic_alias_mro_entries(PyGenericAliasObject *self, PyObject *bases) { - - PyTypeObject *tp = Py_TYPE(self); - if (self->weakreflist != NULL) - PyObject_ClearWeakRefs((PyObject *) self); - Py_XDECREF(self->weakreflist); - PyObject_Free(self); - Py_DECREF(tp); + return PyTuple_Pack(1, self->item); } -static PyType_Slot HeapCTypeWithWeakref_slots[] = { - {Py_tp_members, heapctypewithweakref_members}, - {Py_tp_dealloc, heapctypewithweakref_dealloc}, - {0, 0}, -}; - -static PyType_Spec HeapCTypeWithWeakref_spec = { - "_testcapi.HeapCTypeWithWeakref", - sizeof(HeapCTypeWithWeakrefObject), - 0, - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, - HeapCTypeWithWeakref_slots +static PyMethodDef generic_alias_methods[] = { + {"__mro_entries__", _PyCFunction_CAST(generic_alias_mro_entries), METH_O, NULL}, + {NULL} /* sentinel */ }; -static PyType_Spec HeapCTypeWithWeakref2_spec = { - "_testcapi.HeapCTypeWithWeakref2", - sizeof(HeapCTypeWithWeakrefObject), +static PyTypeObject GenericAlias_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "GenericAlias", + sizeof(PyGenericAliasObject), 0, - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, - HeapCTypeWithWeakref_slots -}; - -PyDoc_STRVAR(heapctypesetattr__doc__, -"A heap type without GC, but with overridden __setattr__.\n\n" -"The 'value' attribute is set to 10 in __init__ and updated via attribute setting."); - -typedef struct { - PyObject_HEAD - long value; -} HeapCTypeSetattrObject; - -static struct PyMemberDef heapctypesetattr_members[] = { - {"pvalue", T_LONG, offsetof(HeapCTypeSetattrObject, value)}, - {NULL} /* Sentinel */ + .tp_dealloc = (destructor)generic_alias_dealloc, + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + .tp_methods = generic_alias_methods, }; -static int -heapctypesetattr_init(PyObject *self, PyObject *args, PyObject *kwargs) +static PyObject * +generic_alias_new(PyObject *item) { - ((HeapCTypeSetattrObject *)self)->value = 10; - return 0; + PyGenericAliasObject *o = PyObject_New(PyGenericAliasObject, &GenericAlias_Type); + if (o == NULL) { + return NULL; + } + o->item = Py_NewRef(item); + return (PyObject*) o; } -static void -heapctypesetattr_dealloc(HeapCTypeSetattrObject *self) -{ - PyTypeObject *tp = Py_TYPE(self); - PyObject_Free(self); - Py_DECREF(tp); -} +typedef struct { + PyObject_HEAD +} PyGenericObject; -static int -heapctypesetattr_setattro(HeapCTypeSetattrObject *self, PyObject *attr, PyObject *value) +static PyObject * +generic_class_getitem(PyObject *type, PyObject *item) { - PyObject *svalue = PyUnicode_FromString("value"); - if (svalue == NULL) - return -1; - int eq = PyObject_RichCompareBool(svalue, attr, Py_EQ); - Py_DECREF(svalue); - if (eq < 0) - return -1; - if (!eq) { - return PyObject_GenericSetAttr((PyObject*) self, attr, value); - } - if (value == NULL) { - self->value = 0; - return 0; - } - PyObject *ivalue = PyNumber_Long(value); - if (ivalue == NULL) - return -1; - long v = PyLong_AsLong(ivalue); - Py_DECREF(ivalue); - if (v == -1 && PyErr_Occurred()) - return -1; - self->value = v; - return 0; + return generic_alias_new(item); } -static PyType_Slot HeapCTypeSetattr_slots[] = { - {Py_tp_init, heapctypesetattr_init}, - {Py_tp_members, heapctypesetattr_members}, - {Py_tp_setattro, heapctypesetattr_setattro}, - {Py_tp_dealloc, heapctypesetattr_dealloc}, - {Py_tp_doc, (char*)heapctypesetattr__doc__}, - {0, 0}, +static PyMethodDef generic_methods[] = { + {"__class_getitem__", generic_class_getitem, METH_O|METH_CLASS, NULL}, + {NULL} /* sentinel */ }; -static PyType_Spec HeapCTypeSetattr_spec = { - "_testcapi.HeapCTypeSetattr", - sizeof(HeapCTypeSetattrObject), +static PyTypeObject Generic_Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "Generic", + sizeof(PyGenericObject), 0, - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, - HeapCTypeSetattr_slots + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + .tp_methods = generic_methods, }; static PyMethodDef meth_instance_methods[] = { @@ -7973,11 +3874,6 @@ PyInit__testcapi(void) Py_SET_TYPE(&_HashInheritanceTester_Type, &PyType_Type); - Py_SET_TYPE(&test_structmembersType, &PyType_Type); - Py_INCREF(&test_structmembersType); - /* don't use a name starting with "test", since we don't want - test_capi to automatically call this */ - PyModule_AddObject(m, "_test_structmembersType", (PyObject *)&test_structmembersType); if (PyType_Ready(&matmulType) < 0) return NULL; Py_INCREF(&matmulType); @@ -7999,29 +3895,6 @@ PyInit__testcapi(void) Py_INCREF(&MyList_Type); PyModule_AddObject(m, "MyList", (PyObject *)&MyList_Type); - if (PyType_Ready(&MethodDescriptorBase_Type) < 0) - return NULL; - Py_INCREF(&MethodDescriptorBase_Type); - PyModule_AddObject(m, "MethodDescriptorBase", (PyObject *)&MethodDescriptorBase_Type); - - MethodDescriptorDerived_Type.tp_base = &MethodDescriptorBase_Type; - if (PyType_Ready(&MethodDescriptorDerived_Type) < 0) - return NULL; - Py_INCREF(&MethodDescriptorDerived_Type); - PyModule_AddObject(m, "MethodDescriptorDerived", (PyObject *)&MethodDescriptorDerived_Type); - - MethodDescriptorNopGet_Type.tp_base = &MethodDescriptorBase_Type; - if (PyType_Ready(&MethodDescriptorNopGet_Type) < 0) - return NULL; - Py_INCREF(&MethodDescriptorNopGet_Type); - PyModule_AddObject(m, "MethodDescriptorNopGet", (PyObject *)&MethodDescriptorNopGet_Type); - - MethodDescriptor2_Type.tp_base = &MethodDescriptorBase_Type; - if (PyType_Ready(&MethodDescriptor2_Type) < 0) - return NULL; - Py_INCREF(&MethodDescriptor2_Type); - PyModule_AddObject(m, "MethodDescriptor2", (PyObject *)&MethodDescriptor2_Type); - if (PyType_Ready(&GenericAlias_Type) < 0) return NULL; Py_INCREF(&GenericAlias_Type); @@ -8047,14 +3920,6 @@ PyInit__testcapi(void) Py_INCREF(&MethStatic_Type); PyModule_AddObject(m, "MethStatic", (PyObject *)&MethStatic_Type); - 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)); @@ -8076,132 +3941,104 @@ PyInit__testcapi(void) PyModule_AddObject(m, "ULLONG_MAX", PyLong_FromUnsignedLongLong(ULLONG_MAX)); PyModule_AddObject(m, "PY_SSIZE_T_MAX", PyLong_FromSsize_t(PY_SSIZE_T_MAX)); PyModule_AddObject(m, "PY_SSIZE_T_MIN", PyLong_FromSsize_t(PY_SSIZE_T_MIN)); + PyModule_AddObject(m, "SIZEOF_WCHAR_T", PyLong_FromSsize_t(sizeof(wchar_t))); PyModule_AddObject(m, "SIZEOF_TIME_T", PyLong_FromSsize_t(sizeof(time_t))); PyModule_AddObject(m, "Py_Version", PyLong_FromUnsignedLong(Py_Version)); Py_INCREF(&PyInstanceMethod_Type); PyModule_AddObject(m, "instancemethod", (PyObject *)&PyInstanceMethod_Type); PyModule_AddIntConstant(m, "the_number_three", 3); - PyObject *v; -#ifdef WITH_PYMALLOC - v = Py_True; -#else - v = Py_False; -#endif - Py_INCREF(v); - PyModule_AddObject(m, "WITH_PYMALLOC", v); TestError = PyErr_NewException("_testcapi.error", NULL, NULL); Py_INCREF(TestError); PyModule_AddObject(m, "error", TestError); - PyObject *HeapDocCType = PyType_FromSpec(&HeapDocCType_spec); - if (HeapDocCType == NULL) { + if (PyType_Ready(&ContainerNoGC_type) < 0) { return NULL; } - PyModule_AddObject(m, "HeapDocCType", HeapDocCType); + Py_INCREF(&ContainerNoGC_type); + if (PyModule_AddObject(m, "ContainerNoGC", + (PyObject *) &ContainerNoGC_type) < 0) + return NULL; - /* bpo-41832: Add a new type to test PyType_FromSpec() - now can accept a NULL tp_doc slot. */ - PyObject *NullTpDocType = PyType_FromSpec(&NullTpDocType_spec); - if (NullTpDocType == NULL) { + /* Include tests from the _testcapi/ directory */ + if (_PyTestCapi_Init_Vectorcall(m) < 0) { return NULL; } - PyModule_AddObject(m, "NullTpDocType", NullTpDocType); - - PyObject *HeapGcCType = PyType_FromSpec(&HeapGcCType_spec); - if (HeapGcCType == NULL) { + if (_PyTestCapi_Init_Heaptype(m) < 0) { return NULL; } - PyModule_AddObject(m, "HeapGcCType", HeapGcCType); - - PyObject *HeapCType = PyType_FromSpec(&HeapCType_spec); - if (HeapCType == NULL) { + if (_PyTestCapi_Init_Abstract(m) < 0) { return NULL; } - PyObject *subclass_bases = PyTuple_Pack(1, HeapCType); - if (subclass_bases == NULL) { + if (_PyTestCapi_Init_Unicode(m) < 0) { return NULL; } - PyObject *HeapCTypeSubclass = PyType_FromSpecWithBases(&HeapCTypeSubclass_spec, subclass_bases); - if (HeapCTypeSubclass == NULL) { + if (_PyTestCapi_Init_GetArgs(m) < 0) { return NULL; } - Py_DECREF(subclass_bases); - PyModule_AddObject(m, "HeapCTypeSubclass", HeapCTypeSubclass); - - PyObject *HeapCTypeWithDict = PyType_FromSpec(&HeapCTypeWithDict_spec); - if (HeapCTypeWithDict == NULL) { + if (_PyTestCapi_Init_PyTime(m) < 0) { return NULL; } - PyModule_AddObject(m, "HeapCTypeWithDict", HeapCTypeWithDict); - - PyObject *HeapCTypeWithDict2 = PyType_FromSpec(&HeapCTypeWithDict2_spec); - if (HeapCTypeWithDict2 == NULL) { + if (_PyTestCapi_Init_DateTime(m) < 0) { return NULL; } - PyModule_AddObject(m, "HeapCTypeWithDict2", HeapCTypeWithDict2); - - PyObject *HeapCTypeWithNegativeDict = PyType_FromSpec(&HeapCTypeWithNegativeDict_spec); - if (HeapCTypeWithNegativeDict == NULL) { + if (_PyTestCapi_Init_Docstring(m) < 0) { return NULL; } - PyModule_AddObject(m, "HeapCTypeWithNegativeDict", HeapCTypeWithNegativeDict); - - PyObject *HeapCTypeWithWeakref = PyType_FromSpec(&HeapCTypeWithWeakref_spec); - if (HeapCTypeWithWeakref == NULL) { + if (_PyTestCapi_Init_Mem(m) < 0) { return NULL; } - PyModule_AddObject(m, "HeapCTypeWithWeakref", HeapCTypeWithWeakref); - - PyObject *HeapCTypeWithBuffer = PyType_FromSpec(&HeapCTypeWithBuffer_spec); - if (HeapCTypeWithBuffer == NULL) { + if (_PyTestCapi_Init_Watchers(m) < 0) { return NULL; } - PyModule_AddObject(m, "HeapCTypeWithBuffer", HeapCTypeWithBuffer); - - PyObject *HeapCTypeWithWeakref2 = PyType_FromSpec(&HeapCTypeWithWeakref2_spec); - if (HeapCTypeWithWeakref2 == NULL) { + if (_PyTestCapi_Init_Long(m) < 0) { return NULL; } - PyModule_AddObject(m, "HeapCTypeWithWeakref2", HeapCTypeWithWeakref2); - - PyObject *HeapCTypeSetattr = PyType_FromSpec(&HeapCTypeSetattr_spec); - if (HeapCTypeSetattr == NULL) { + if (_PyTestCapi_Init_Float(m) < 0) { return NULL; } - PyModule_AddObject(m, "HeapCTypeSetattr", HeapCTypeSetattr); - - PyObject *subclass_with_finalizer_bases = PyTuple_Pack(1, HeapCTypeSubclass); - if (subclass_with_finalizer_bases == NULL) { + if (_PyTestCapi_Init_Dict(m) < 0) { + return NULL; + } + if (_PyTestCapi_Init_Structmember(m) < 0) { + return NULL; + } + if (_PyTestCapi_Init_Exceptions(m) < 0) { + return NULL; + } + if (_PyTestCapi_Init_Code(m) < 0) { + return NULL; + } + if (_PyTestCapi_Init_Buffer(m) < 0) { + return NULL; + } + if (_PyTestCapi_Init_PyOS(m) < 0) { + return NULL; + } + if (_PyTestCapi_Init_Immortal(m) < 0) { return NULL; } - PyObject *HeapCTypeSubclassWithFinalizer = PyType_FromSpecWithBases( - &HeapCTypeSubclassWithFinalizer_spec, subclass_with_finalizer_bases); - if (HeapCTypeSubclassWithFinalizer == NULL) { + if (_PyTestCapi_Init_GC(m) < 0) { return NULL; } - Py_DECREF(subclass_with_finalizer_bases); - PyModule_AddObject(m, "HeapCTypeSubclassWithFinalizer", HeapCTypeSubclassWithFinalizer); - if (PyType_Ready(&ContainerNoGC_type) < 0) { +#ifndef LIMITED_API_AVAILABLE + PyModule_AddObjectRef(m, "LIMITED_API_AVAILABLE", Py_False); +#else + PyModule_AddObjectRef(m, "LIMITED_API_AVAILABLE", Py_True); + if (_PyTestCapi_Init_VectorcallLimited(m) < 0) { return NULL; } - Py_INCREF(&ContainerNoGC_type); - if (PyModule_AddObject(m, "ContainerNoGC", - (PyObject *) &ContainerNoGC_type) < 0) + if (_PyTestCapi_Init_HeaptypeRelative(m) < 0) { return NULL; + } +#endif PyState_AddModule(m, &_testcapimodule); return m; } -static PyObject * -negative_dictoffset(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - return PyType_FromSpec(&HeapCTypeWithNegativeDict_spec); -} - /* Test the C API exposed when PY_SSIZE_T_CLEAN is not defined */ #undef Py_BuildValue @@ -8243,56 +4080,5 @@ test_buildvalue_issue38913(PyObject *self, PyObject *Py_UNUSED(ignored)) } PyErr_Clear(); - - Py_RETURN_NONE; -} - -#undef PyArg_ParseTupleAndKeywords -PyAPI_FUNC(int) PyArg_ParseTupleAndKeywords(PyObject *, PyObject *, - const char *, char **, ...); - -static PyObject * -getargs_s_hash_int(PyObject *self, PyObject *args, PyObject *kwargs) -{ - static char *keywords[] = {"", "", "x", NULL}; - Py_buffer buf = {NULL}; - const char *s; - int len; - int i = 0; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "w*|s#i", keywords, &buf, &s, &len, &i)) - return NULL; - PyBuffer_Release(&buf); - Py_RETURN_NONE; -} - -static PyObject * -getargs_s_hash_int2(PyObject *self, PyObject *args, PyObject *kwargs) -{ - static char *keywords[] = {"", "", "x", NULL}; - Py_buffer buf = {NULL}; - const char *s; - int len; - int i = 0; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "w*|(s#)i", keywords, &buf, &s, &len, &i)) - return NULL; - PyBuffer_Release(&buf); - Py_RETURN_NONE; -} - -static PyObject * -gh_99240_clear_args(PyObject *self, PyObject *args) -{ - char *a = NULL; - char *b = NULL; - - if (!PyArg_ParseTuple(args, "eses", "idna", &a, "idna", &b)) { - if (a || b) { - PyErr_Clear(); - PyErr_SetString(PyExc_AssertionError, "Arguments are not cleared."); - } - return NULL; - } - PyMem_Free(a); - PyMem_Free(b); Py_RETURN_NONE; } diff --git a/Modules/_testclinic.c b/Modules/_testclinic.c index 91fdee24..6ff55a27 100644 --- a/Modules/_testclinic.c +++ b/Modules/_testclinic.c @@ -9,6 +9,19 @@ #include "Python.h" + +// Used for clone_with_conv_f1 and clone_with_conv_v2 +typedef struct { + const char *name; +} custom_t; + +static int +custom_converter(PyObject *obj, custom_t *val) +{ + return 1; +} + + #include "clinic/_testclinic.c.h" @@ -1117,6 +1130,70 @@ gh_99240_double_free_impl(PyObject *module, char *a, char *b) } +/*[clinic input] +_testclinic.clone_f1 as clone_f1 + path: str +[clinic start generated code]*/ + +static PyObject * +clone_f1_impl(PyObject *module, const char *path) +/*[clinic end generated code: output=8c30b5620ba86715 input=9c614b7f025ebf70]*/ +{ + Py_RETURN_NONE; +} + + +/*[clinic input] +_testclinic.clone_f2 as clone_f2 = _testclinic.clone_f1 +[clinic start generated code]*/ + +static PyObject * +clone_f2_impl(PyObject *module, const char *path) +/*[clinic end generated code: output=6aa1c39bec3f5d9b input=1aaaf47d6ed2324a]*/ +{ + Py_RETURN_NONE; +} + + +/*[python input] +class custom_t_converter(CConverter): + type = 'custom_t' + converter = 'custom_converter' + + def pre_render(self): + self.c_default = f'''{{ + .name = "{self.function.name}", + }}''' + +[python start generated code]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=b2fb801e99a06bf6]*/ + + +/*[clinic input] +_testclinic.clone_with_conv_f1 as clone_with_conv_f1 + path: custom_t = None +[clinic start generated code]*/ + +static PyObject * +clone_with_conv_f1_impl(PyObject *module, custom_t path) +/*[clinic end generated code: output=f7e030ffd5439cb0 input=bc77bc80dec3f46d]*/ +{ + return PyUnicode_FromString(path.name); +} + + +/*[clinic input] +_testclinic.clone_with_conv_f2 as clone_with_conv_f2 = _testclinic.clone_with_conv_f1 +[clinic start generated code]*/ + +static PyObject * +clone_with_conv_f2_impl(PyObject *module, custom_t path) +/*[clinic end generated code: output=9d7fdd6a75eecee4 input=cff459a205fa83bb]*/ +{ + return PyUnicode_FromString(path.name); +} + + static PyMethodDef tester_methods[] = { TEST_EMPTY_FUNCTION_METHODDEF OBJECTS_CONVERTER_METHODDEF @@ -1168,6 +1245,10 @@ static PyMethodDef tester_methods[] = { GH_32092_KW_PASS_METHODDEF GH_99233_REFCOUNT_METHODDEF GH_99240_DOUBLE_FREE_METHODDEF + CLONE_F1_METHODDEF + CLONE_F2_METHODDEF + CLONE_WITH_CONV_F1_METHODDEF + CLONE_WITH_CONV_F2_METHODDEF {NULL, NULL} }; diff --git a/Modules/_testinternalcapi.c b/Modules/_testinternalcapi.c index 238de749..4e063a86 100644 --- a/Modules/_testinternalcapi.c +++ b/Modules/_testinternalcapi.c @@ -12,20 +12,84 @@ #define PY_SSIZE_T_CLEAN #include "Python.h" +#include "frameobject.h" +#include "interpreteridobject.h" // _PyInterpreterID_LookUp() #include "pycore_atomic_funcs.h" // _Py_atomic_int_get() #include "pycore_bitutils.h" // _Py_bswap32() +#include "pycore_bytesobject.h" // _PyBytes_Find() +#include "pycore_compile.h" // _PyCompile_CodeGen, _PyCompile_OptimizeCfg, _PyCompile_Assemble +#include "pycore_ceval.h" // _PyEval_AddPendingCall #include "pycore_fileutils.h" // _Py_normpath #include "pycore_frame.h" // _PyInterpreterFrame #include "pycore_gc.h" // PyGC_Head #include "pycore_hashtable.h" // _Py_hashtable_new() #include "pycore_initconfig.h" // _Py_GetConfigsAsDict() -#include "pycore_pathconfig.h" // _PyPathConfig_ClearGlobal() #include "pycore_interp.h" // _PyInterpreterState_GetConfigCopy() +#include "pycore_pathconfig.h" // _PyPathConfig_ClearGlobal() #include "pycore_pyerrors.h" // _Py_UTF8_Edit_Cost() #include "pycore_pystate.h" // _PyThreadState_GET() #include "osdefs.h" // MAXPATHLEN +#include "clinic/_testinternalcapi.c.h" + + +#define MODULE_NAME "_testinternalcapi" + + +static PyObject * +_get_current_module(void) +{ + // We ensured it was imported in _run_script(). + PyObject *name = PyUnicode_FromString(MODULE_NAME); + if (name == NULL) { + return NULL; + } + PyObject *mod = PyImport_GetModule(name); + Py_DECREF(name); + if (mod == NULL) { + return NULL; + } + assert(mod != Py_None); + return mod; +} + + +/* module state *************************************************************/ + +typedef struct { + PyObject *record_list; +} module_state; +static inline module_state * +get_module_state(PyObject *mod) +{ + assert(mod != NULL); + module_state *state = PyModule_GetState(mod); + assert(state != NULL); + return state; +} + +static int +traverse_module_state(module_state *state, visitproc visit, void *arg) +{ + Py_VISIT(state->record_list); + return 0; +} + +static int +clear_module_state(module_state *state) +{ + Py_CLEAR(state->record_list); + return 0; +} + + +/* module functions *********************************************************/ + +/*[clinic input] +module _testinternalcapi +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=7bb583d8c9eb9a78]*/ static PyObject * get_configs(PyObject *self, PyObject *Py_UNUSED(args)) { @@ -38,9 +102,7 @@ get_recursion_depth(PyObject *self, PyObject *Py_UNUSED(args)) { PyThreadState *tstate = _PyThreadState_GET(); - /* subtract one to ignore the frame of the get_recursion_depth() call */ - - return PyLong_FromLong(tstate->recursion_limit - tstate->recursion_remaining - 1); + return PyLong_FromLong(tstate->py_recursion_limit - tstate->py_recursion_remaining); } @@ -380,6 +442,118 @@ test_edit_cost(PyObject *self, PyObject *Py_UNUSED(args)) } +static int +check_bytes_find(const char *haystack0, const char *needle0, + int offset, Py_ssize_t expected) +{ + Py_ssize_t len_haystack = strlen(haystack0); + Py_ssize_t len_needle = strlen(needle0); + Py_ssize_t result_1 = _PyBytes_Find(haystack0, len_haystack, + needle0, len_needle, offset); + if (result_1 != expected) { + PyErr_Format(PyExc_AssertionError, + "Incorrect result_1: '%s' in '%s' (offset=%zd)", + needle0, haystack0, offset); + return -1; + } + // Allocate new buffer with no NULL terminator. + char *haystack = PyMem_Malloc(len_haystack); + if (haystack == NULL) { + PyErr_NoMemory(); + return -1; + } + char *needle = PyMem_Malloc(len_needle); + if (needle == NULL) { + PyMem_Free(haystack); + PyErr_NoMemory(); + return -1; + } + memcpy(haystack, haystack0, len_haystack); + memcpy(needle, needle0, len_needle); + Py_ssize_t result_2 = _PyBytes_Find(haystack, len_haystack, + needle, len_needle, offset); + PyMem_Free(haystack); + PyMem_Free(needle); + if (result_2 != expected) { + PyErr_Format(PyExc_AssertionError, + "Incorrect result_2: '%s' in '%s' (offset=%zd)", + needle0, haystack0, offset); + return -1; + } + return 0; +} + +static int +check_bytes_find_large(Py_ssize_t len_haystack, Py_ssize_t len_needle, + const char *needle) +{ + char *zeros = PyMem_RawCalloc(len_haystack, 1); + if (zeros == NULL) { + PyErr_NoMemory(); + return -1; + } + Py_ssize_t res = _PyBytes_Find(zeros, len_haystack, needle, len_needle, 0); + PyMem_RawFree(zeros); + if (res != -1) { + PyErr_Format(PyExc_AssertionError, + "check_bytes_find_large(%zd, %zd) found %zd", + len_haystack, len_needle, res); + return -1; + } + return 0; +} + +static PyObject * +test_bytes_find(PyObject *self, PyObject *Py_UNUSED(args)) +{ + #define CHECK(H, N, O, E) do { \ + if (check_bytes_find(H, N, O, E) < 0) { \ + return NULL; \ + } \ + } while (0) + + CHECK("", "", 0, 0); + CHECK("Python", "", 0, 0); + CHECK("Python", "", 3, 3); + CHECK("Python", "", 6, 6); + CHECK("Python", "yth", 0, 1); + CHECK("ython", "yth", 1, 1); + CHECK("thon", "yth", 2, -1); + CHECK("Python", "thon", 0, 2); + CHECK("ython", "thon", 1, 2); + CHECK("thon", "thon", 2, 2); + CHECK("hon", "thon", 3, -1); + CHECK("Pytho", "zz", 0, -1); + CHECK("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "ab", 0, -1); + CHECK("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "ba", 0, -1); + CHECK("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "bb", 0, -1); + CHECK("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab", "ab", 0, 30); + CHECK("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaba", "ba", 0, 30); + CHECK("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaabb", "bb", 0, 30); + #undef CHECK + + // Hunt for segfaults + // n, m chosen here so that (n - m) % (m + 1) == 0 + // This would make default_find in fastsearch.h access haystack[n]. + if (check_bytes_find_large(2048, 2, "ab") < 0) { + return NULL; + } + if (check_bytes_find_large(4096, 16, "0123456789abcdef") < 0) { + return NULL; + } + if (check_bytes_find_large(8192, 2, "ab") < 0) { + return NULL; + } + if (check_bytes_find_large(16384, 4, "abcd") < 0) { + return NULL; + } + if (check_bytes_find_large(32768, 2, "ab") < 0) { + return NULL; + } + Py_RETURN_NONE; +} + + static PyObject * normalize_path(PyObject *self, PyObject *filename) { @@ -492,20 +666,25 @@ decode_locale_ex(PyObject *self, PyObject *args) return res; } -static PyObject *record_list = NULL; - static PyObject * set_eval_frame_default(PyObject *self, PyObject *Py_UNUSED(args)) { + module_state *state = get_module_state(self); _PyInterpreterState_SetEvalFrameFunc(PyInterpreterState_Get(), _PyEval_EvalFrameDefault); - Py_CLEAR(record_list); + Py_CLEAR(state->record_list); Py_RETURN_NONE; } static PyObject * record_eval(PyThreadState *tstate, struct _PyInterpreterFrame *f, int exc) { - PyList_Append(record_list, f->f_func->func_name); + if (PyFunction_Check(f->f_funcobj)) { + PyObject *module = _get_current_module(); + assert(module != NULL); + module_state *state = get_module_state(module); + Py_DECREF(module); + PyList_Append(state->record_list, ((PyFunctionObject *)f->f_funcobj)->func_name); + } return _PyEval_EvalFrameDefault(tstate, f, exc); } @@ -513,19 +692,366 @@ record_eval(PyThreadState *tstate, struct _PyInterpreterFrame *f, int exc) static PyObject * set_eval_frame_record(PyObject *self, PyObject *list) { + module_state *state = get_module_state(self); if (!PyList_Check(list)) { PyErr_SetString(PyExc_TypeError, "argument must be a list"); return NULL; } - Py_CLEAR(record_list); - Py_INCREF(list); - record_list = list; + Py_XSETREF(state->record_list, Py_NewRef(list)); _PyInterpreterState_SetEvalFrameFunc(PyInterpreterState_Get(), record_eval); Py_RETURN_NONE; } +/*[clinic input] + +_testinternalcapi.compiler_codegen -> object + + ast: object + filename: object + optimize: int + compile_mode: int = 0 + +Apply compiler code generation to an AST. +[clinic start generated code]*/ + +static PyObject * +_testinternalcapi_compiler_codegen_impl(PyObject *module, PyObject *ast, + PyObject *filename, int optimize, + int compile_mode) +/*[clinic end generated code: output=40a68f6e13951cc8 input=a0e00784f1517cd7]*/ +{ + PyCompilerFlags *flags = NULL; + return _PyCompile_CodeGen(ast, filename, flags, optimize, compile_mode); +} + + +/*[clinic input] + +_testinternalcapi.optimize_cfg -> object + + instructions: object + consts: object + nlocals: int + +Apply compiler optimizations to an instruction list. +[clinic start generated code]*/ + +static PyObject * +_testinternalcapi_optimize_cfg_impl(PyObject *module, PyObject *instructions, + PyObject *consts, int nlocals) +/*[clinic end generated code: output=57c53c3a3dfd1df0 input=6a96d1926d58d7e5]*/ +{ + return _PyCompile_OptimizeCfg(instructions, consts, nlocals); +} + +static int +get_nonnegative_int_from_dict(PyObject *dict, const char *key) { + PyObject *obj = PyDict_GetItemString(dict, key); + if (obj == NULL) { + return -1; + } + return PyLong_AsLong(obj); +} + +/*[clinic input] + +_testinternalcapi.assemble_code_object -> object + + filename: object + instructions: object + metadata: object + +Create a code object for the given instructions. +[clinic start generated code]*/ + +static PyObject * +_testinternalcapi_assemble_code_object_impl(PyObject *module, + PyObject *filename, + PyObject *instructions, + PyObject *metadata) +/*[clinic end generated code: output=38003dc16a930f48 input=e713ad77f08fb3a8]*/ + +{ + assert(PyDict_Check(metadata)); + _PyCompile_CodeUnitMetadata umd; + + umd.u_name = PyDict_GetItemString(metadata, "name"); + umd.u_qualname = PyDict_GetItemString(metadata, "qualname"); + + assert(PyUnicode_Check(umd.u_name)); + assert(PyUnicode_Check(umd.u_qualname)); + + umd.u_consts = PyDict_GetItemString(metadata, "consts"); + umd.u_names = PyDict_GetItemString(metadata, "names"); + umd.u_varnames = PyDict_GetItemString(metadata, "varnames"); + umd.u_cellvars = PyDict_GetItemString(metadata, "cellvars"); + umd.u_freevars = PyDict_GetItemString(metadata, "freevars"); + umd.u_fasthidden = PyDict_GetItemString(metadata, "fasthidden"); + + assert(PyDict_Check(umd.u_consts)); + assert(PyDict_Check(umd.u_names)); + assert(PyDict_Check(umd.u_varnames)); + assert(PyDict_Check(umd.u_cellvars)); + assert(PyDict_Check(umd.u_freevars)); + assert(PyDict_Check(umd.u_fasthidden)); + + umd.u_argcount = get_nonnegative_int_from_dict(metadata, "argcount"); + umd.u_posonlyargcount = get_nonnegative_int_from_dict(metadata, "posonlyargcount"); + umd.u_kwonlyargcount = get_nonnegative_int_from_dict(metadata, "kwonlyargcount"); + umd.u_firstlineno = get_nonnegative_int_from_dict(metadata, "firstlineno"); + + assert(umd.u_argcount >= 0); + assert(umd.u_posonlyargcount >= 0); + assert(umd.u_kwonlyargcount >= 0); + assert(umd.u_firstlineno >= 0); + + return (PyObject*)_PyCompile_Assemble(&umd, filename, instructions); +} + + +static PyObject * +get_interp_settings(PyObject *self, PyObject *args) +{ + int interpid = -1; + if (!PyArg_ParseTuple(args, "|i:get_interp_settings", &interpid)) { + return NULL; + } + + PyInterpreterState *interp = NULL; + if (interpid < 0) { + PyThreadState *tstate = _PyThreadState_GET(); + interp = tstate ? tstate->interp : _PyInterpreterState_Main(); + } + else if (interpid == 0) { + interp = _PyInterpreterState_Main(); + } + else { + PyErr_Format(PyExc_NotImplementedError, + "%zd", interpid); + return NULL; + } + assert(interp != NULL); + + PyObject *settings = PyDict_New(); + if (settings == NULL) { + return NULL; + } + + /* Add the feature flags. */ + PyObject *flags = PyLong_FromUnsignedLong(interp->feature_flags); + if (flags == NULL) { + Py_DECREF(settings); + return NULL; + } + int res = PyDict_SetItemString(settings, "feature_flags", flags); + Py_DECREF(flags); + if (res != 0) { + Py_DECREF(settings); + return NULL; + } + + /* "own GIL" */ + PyObject *own_gil = interp->ceval.own_gil ? Py_True : Py_False; + if (PyDict_SetItemString(settings, "own_gil", own_gil) != 0) { + Py_DECREF(settings); + return NULL; + } + + return settings; +} + + +static PyObject * +clear_extension(PyObject *self, PyObject *args) +{ + PyObject *name = NULL, *filename = NULL; + if (!PyArg_ParseTuple(args, "OO:clear_extension", &name, &filename)) { + return NULL; + } + if (_PyImport_ClearExtension(name, filename) < 0) { + return NULL; + } + Py_RETURN_NONE; +} + +static PyObject * +write_perf_map_entry(PyObject *self, PyObject *args) +{ + PyObject *code_addr_v; + const void *code_addr; + unsigned int code_size; + const char *entry_name; + + if (!PyArg_ParseTuple(args, "OIs", &code_addr_v, &code_size, &entry_name)) + return NULL; + code_addr = PyLong_AsVoidPtr(code_addr_v); + if (code_addr == NULL) { + return NULL; + } + + int ret = PyUnstable_WritePerfMapEntry(code_addr, code_size, entry_name); + if (ret < 0) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + return PyLong_FromLong(ret); +} -static PyMethodDef TestMethods[] = { +static PyObject * +perf_map_state_teardown(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(ignored)) +{ + PyUnstable_PerfMapState_Fini(); + Py_RETURN_NONE; +} + +static PyObject * +iframe_getcode(PyObject *self, PyObject *frame) +{ + if (!PyFrame_Check(frame)) { + PyErr_SetString(PyExc_TypeError, "argument must be a frame"); + return NULL; + } + struct _PyInterpreterFrame *f = ((PyFrameObject *)frame)->f_frame; + return PyUnstable_InterpreterFrame_GetCode(f); +} + +static PyObject * +iframe_getline(PyObject *self, PyObject *frame) +{ + if (!PyFrame_Check(frame)) { + PyErr_SetString(PyExc_TypeError, "argument must be a frame"); + return NULL; + } + struct _PyInterpreterFrame *f = ((PyFrameObject *)frame)->f_frame; + return PyLong_FromLong(PyUnstable_InterpreterFrame_GetLine(f)); +} + +static PyObject * +iframe_getlasti(PyObject *self, PyObject *frame) +{ + if (!PyFrame_Check(frame)) { + PyErr_SetString(PyExc_TypeError, "argument must be a frame"); + return NULL; + } + struct _PyInterpreterFrame *f = ((PyFrameObject *)frame)->f_frame; + return PyLong_FromLong(PyUnstable_InterpreterFrame_GetLasti(f)); +} + + +static int _pending_callback(void *arg) +{ + /* we assume the argument is callable object to which we own a reference */ + PyObject *callable = (PyObject *)arg; + PyObject *r = PyObject_CallNoArgs(callable); + Py_DECREF(callable); + Py_XDECREF(r); + return r != NULL ? 0 : -1; +} + +/* The following requests n callbacks to _pending_callback. It can be + * run from any python thread. + */ +static PyObject * +pending_threadfunc(PyObject *self, PyObject *args, PyObject *kwargs) +{ + PyObject *callable; + int ensure_added = 0; + static char *kwlist[] = {"", "ensure_added", NULL}; + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "O|$p:pending_threadfunc", kwlist, + &callable, &ensure_added)) + { + return NULL; + } + PyInterpreterState *interp = PyInterpreterState_Get(); + + /* create the reference for the callbackwhile we hold the lock */ + Py_INCREF(callable); + + int r; + Py_BEGIN_ALLOW_THREADS + r = _PyEval_AddPendingCall(interp, &_pending_callback, callable, 0); + Py_END_ALLOW_THREADS + if (r < 0) { + /* unsuccessful add */ + if (!ensure_added) { + Py_DECREF(callable); + Py_RETURN_FALSE; + } + do { + Py_BEGIN_ALLOW_THREADS + r = _PyEval_AddPendingCall(interp, &_pending_callback, callable, 0); + Py_END_ALLOW_THREADS + } while (r < 0); + } + + Py_RETURN_TRUE; +} + + +static struct { + int64_t interpid; +} pending_identify_result; + +static int +_pending_identify_callback(void *arg) +{ + PyThread_type_lock mutex = (PyThread_type_lock)arg; + assert(pending_identify_result.interpid == -1); + PyThreadState *tstate = PyThreadState_Get(); + pending_identify_result.interpid = PyInterpreterState_GetID(tstate->interp); + PyThread_release_lock(mutex); + return 0; +} + +static PyObject * +pending_identify(PyObject *self, PyObject *args) +{ + PyObject *interpid; + if (!PyArg_ParseTuple(args, "O:pending_identify", &interpid)) { + return NULL; + } + PyInterpreterState *interp = _PyInterpreterID_LookUp(interpid); + if (interp == NULL) { + if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_ValueError, "interpreter not found"); + } + return NULL; + } + + pending_identify_result.interpid = -1; + + PyThread_type_lock mutex = PyThread_allocate_lock(); + if (mutex == NULL) { + return NULL; + } + PyThread_acquire_lock(mutex, WAIT_LOCK); + /* It gets released in _pending_identify_callback(). */ + + int r; + do { + Py_BEGIN_ALLOW_THREADS + r = _PyEval_AddPendingCall(interp, + &_pending_identify_callback, (void *)mutex, + 0); + Py_END_ALLOW_THREADS + } while (r < 0); + + /* Wait for the pending call to complete. */ + PyThread_acquire_lock(mutex, WAIT_LOCK); + PyThread_release_lock(mutex); + PyThread_free_lock(mutex); + + PyObject *res = PyLong_FromLongLong(pending_identify_result.interpid); + pending_identify_result.interpid = -1; + if (res == NULL) { + return NULL; + } + return res; +} + + +static PyMethodDef module_functions[] = { {"get_configs", get_configs, METH_NOARGS}, {"get_recursion_depth", get_recursion_depth, METH_NOARGS}, {"test_bswap", test_bswap, METH_NOARGS}, @@ -537,45 +1063,90 @@ static PyMethodDef TestMethods[] = { {"reset_path_config", test_reset_path_config, METH_NOARGS}, {"test_atomic_funcs", test_atomic_funcs, METH_NOARGS}, {"test_edit_cost", test_edit_cost, METH_NOARGS}, + {"test_bytes_find", test_bytes_find, METH_NOARGS}, {"normalize_path", normalize_path, METH_O, NULL}, {"get_getpath_codeobject", get_getpath_codeobject, METH_NOARGS, NULL}, {"EncodeLocaleEx", encode_locale_ex, METH_VARARGS}, {"DecodeLocaleEx", decode_locale_ex, METH_VARARGS}, {"set_eval_frame_default", set_eval_frame_default, METH_NOARGS, NULL}, {"set_eval_frame_record", set_eval_frame_record, METH_O, NULL}, + _TESTINTERNALCAPI_COMPILER_CODEGEN_METHODDEF + _TESTINTERNALCAPI_OPTIMIZE_CFG_METHODDEF + _TESTINTERNALCAPI_ASSEMBLE_CODE_OBJECT_METHODDEF + {"get_interp_settings", get_interp_settings, METH_VARARGS, NULL}, + {"clear_extension", clear_extension, METH_VARARGS, NULL}, + {"write_perf_map_entry", write_perf_map_entry, METH_VARARGS}, + {"perf_map_state_teardown", perf_map_state_teardown, METH_NOARGS}, + {"iframe_getcode", iframe_getcode, METH_O, NULL}, + {"iframe_getline", iframe_getline, METH_O, NULL}, + {"iframe_getlasti", iframe_getlasti, METH_O, NULL}, + {"pending_threadfunc", _PyCFunction_CAST(pending_threadfunc), + METH_VARARGS | METH_KEYWORDS}, + {"pending_identify", pending_identify, METH_VARARGS, NULL}, {NULL, NULL} /* sentinel */ }; -static struct PyModuleDef _testcapimodule = { - PyModuleDef_HEAD_INIT, - "_testinternalcapi", - NULL, - -1, - TestMethods, - NULL, - NULL, - NULL, - NULL +/* initialization function */ + +static int +module_exec(PyObject *module) +{ + if (_PyModule_Add(module, "SIZEOF_PYGC_HEAD", + PyLong_FromSsize_t(sizeof(PyGC_Head))) < 0) { + return 1; + } + + return 0; +} + +static struct PyModuleDef_Slot module_slots[] = { + {Py_mod_exec, module_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, + {0, NULL}, }; +static int +module_traverse(PyObject *module, visitproc visit, void *arg) +{ + module_state *state = get_module_state(module); + assert(state != NULL); + traverse_module_state(state, visit, arg); + return 0; +} -PyMODINIT_FUNC -PyInit__testinternalcapi(void) +static int +module_clear(PyObject *module) { - PyObject *module = PyModule_Create(&_testcapimodule); - if (module == NULL) { - return NULL; - } + module_state *state = get_module_state(module); + assert(state != NULL); + (void)clear_module_state(state); + return 0; +} - if (PyModule_AddObject(module, "SIZEOF_PYGC_HEAD", - PyLong_FromSsize_t(sizeof(PyGC_Head))) < 0) { - goto error; - } +static void +module_free(void *module) +{ + module_state *state = get_module_state(module); + assert(state != NULL); + (void)clear_module_state(state); +} - return module; +static struct PyModuleDef _testcapimodule = { + .m_base = PyModuleDef_HEAD_INIT, + .m_name = MODULE_NAME, + .m_doc = NULL, + .m_size = sizeof(module_state), + .m_methods = module_functions, + .m_slots = module_slots, + .m_traverse = module_traverse, + .m_clear = module_clear, + .m_free = (freefunc)module_free, +}; -error: - Py_DECREF(module); - return NULL; + +PyMODINIT_FUNC +PyInit__testinternalcapi(void) +{ + return PyModuleDef_Init(&_testcapimodule); } diff --git a/Modules/_testmultiphase.c b/Modules/_testmultiphase.c index b8993a29..ca71b615 100644 --- a/Modules/_testmultiphase.c +++ b/Modules/_testmultiphase.c @@ -57,8 +57,7 @@ Example_demo(ExampleObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "|O:demo", &o)) return NULL; if (o != NULL && PyUnicode_Check(o)) { - Py_INCREF(o); - return o; + return Py_NewRef(o); } Py_RETURN_NONE; } @@ -77,8 +76,7 @@ Example_getattro(ExampleObject *self, PyObject *name) if (self->x_attr != NULL) { PyObject *v = PyDict_GetItemWithError(self->x_attr, name); if (v != NULL) { - Py_INCREF(v); - return v; + return Py_NewRef(v); } else if (PyErr_Occurred()) { return NULL; @@ -151,8 +149,7 @@ _testmultiphase_StateAccessType_get_defining_module_impl(StateAccessTypeObject * return NULL; } assert(PyType_GetModuleByDef(Py_TYPE(self), &def_meth_state_access) == retval); - Py_INCREF(retval); - return retval; + return Py_NewRef(retval); } /*[clinic input] @@ -444,6 +441,7 @@ static int execfunc(PyObject *m) static PyModuleDef_Slot main_slots[] = { {Py_mod_exec, execfunc}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL}, }; @@ -683,6 +681,27 @@ PyInit__testmultiphase_export_unreported_exception(void) return PyModuleDef_Init(&main_def); } +static PyObject* +createfunc_noop(PyObject *spec, PyModuleDef *def) +{ + return PyModule_New("spam"); +} + +static PyModuleDef_Slot slots_multiple_create_slots[] = { + {Py_mod_create, createfunc_noop}, + {Py_mod_create, createfunc_noop}, + {0, NULL}, +}; + +static PyModuleDef def_multiple_create_slots = TEST_MODULE_DEF( + "_testmultiphase_multiple_create_slots", slots_multiple_create_slots, NULL); + +PyMODINIT_FUNC +PyInit__testmultiphase_multiple_create_slots(void) +{ + return PyModuleDef_Init(&def_multiple_create_slots); +} + static PyObject* createfunc_null(PyObject *spec, PyModuleDef *def) { @@ -748,6 +767,7 @@ PyInit__testmultiphase_create_unreported_exception(void) static PyModuleDef_Slot slots_nonmodule_with_exec_slots[] = { {Py_mod_create, createfunc_nonmodule}, {Py_mod_exec, execfunc}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL}, }; @@ -768,6 +788,7 @@ execfunc_err(PyObject *mod) static PyModuleDef_Slot slots_exec_err[] = { {Py_mod_exec, execfunc_err}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL}, }; @@ -789,6 +810,7 @@ execfunc_raise(PyObject *spec) static PyModuleDef_Slot slots_exec_raise[] = { {Py_mod_exec, execfunc_raise}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL}, }; @@ -810,6 +832,7 @@ execfunc_unreported_exception(PyObject *mod) static PyModuleDef_Slot slots_exec_unreported_exception[] = { {Py_mod_exec, execfunc_unreported_exception}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL}, }; @@ -848,6 +871,7 @@ meth_state_access_exec(PyObject *m) static PyModuleDef_Slot meth_state_access_slots[] = { {Py_mod_exec, meth_state_access_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; @@ -889,13 +913,57 @@ PyInit__test_module_state_shared(void) } -/*** Helper for imp test ***/ +/* multiple interpreters support */ + +static PyModuleDef_Slot slots_multiple_multiple_interpreters_slots[] = { + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, + {0, NULL}, +}; -static PyModuleDef imp_dummy_def = TEST_MODULE_DEF("imp_dummy", main_slots, testexport_methods); +static PyModuleDef def_multiple_multiple_interpreters_slots = TEST_MODULE_DEF( + "_testmultiphase_multiple_multiple_interpreters_slots", + slots_multiple_multiple_interpreters_slots, + NULL); PyMODINIT_FUNC -PyInit_imp_dummy(void) +PyInit__testmultiphase_multiple_multiple_interpreters_slots(void) { - return PyModuleDef_Init(&imp_dummy_def); + return PyModuleDef_Init(&def_multiple_multiple_interpreters_slots); } +static PyModuleDef_Slot non_isolated_slots[] = { + {Py_mod_exec, execfunc}, + {Py_mod_multiple_interpreters, Py_MOD_MULTIPLE_INTERPRETERS_NOT_SUPPORTED}, + {0, NULL}, +}; + +static PyModuleDef non_isolated_def = TEST_MODULE_DEF("_test_non_isolated", + non_isolated_slots, + testexport_methods); + +PyMODINIT_FUNC +PyInit__test_non_isolated(void) +{ + return PyModuleDef_Init(&non_isolated_def); +} + + +static PyModuleDef_Slot shared_gil_only_slots[] = { + {Py_mod_exec, execfunc}, + /* Note that Py_MOD_MULTIPLE_INTERPRETERS_SUPPORTED is the default. + We put it here explicitly to draw attention to the contrast + with Py_MOD_PER_INTERPRETER_GIL_SUPPORTED. */ + {Py_mod_multiple_interpreters, Py_MOD_MULTIPLE_INTERPRETERS_SUPPORTED}, + {0, NULL}, +}; + +static PyModuleDef shared_gil_only_def = TEST_MODULE_DEF("_test_shared_gil_only", + shared_gil_only_slots, + testexport_methods); + +PyMODINIT_FUNC +PyInit__test_shared_gil_only(void) +{ + return PyModuleDef_Init(&shared_gil_only_def); +} diff --git a/Modules/_testsinglephase.c b/Modules/_testsinglephase.c new file mode 100644 index 00000000..dca7abff --- /dev/null +++ b/Modules/_testsinglephase.c @@ -0,0 +1,483 @@ + +/* Testing module for single-phase initialization of extension modules + */ +#ifndef Py_BUILD_CORE_BUILTIN +# define Py_BUILD_CORE_MODULE 1 +#endif + +//#include <time.h> +#include "Python.h" +#include "pycore_namespace.h" // _PyNamespace_New() + + +typedef struct { + _PyTime_t initialized; + PyObject *error; + PyObject *int_const; + PyObject *str_const; +} module_state; + + +/* Process-global state is only used by _testsinglephase + since it's the only one that does not support re-init. */ +static struct { + int initialized_count; + module_state module; +} global_state = { + +#define NOT_INITIALIZED -1 + .initialized_count = NOT_INITIALIZED, +}; + +static void clear_state(module_state *state); + +static void +clear_global_state(void) +{ + clear_state(&global_state.module); + global_state.initialized_count = NOT_INITIALIZED; +} + + +static inline module_state * +get_module_state(PyObject *module) +{ + PyModuleDef *def = PyModule_GetDef(module); + if (def->m_size == -1) { + return &global_state.module; + } + else if (def->m_size == 0) { + return NULL; + } + else { + module_state *state = (module_state*)PyModule_GetState(module); + assert(state != NULL); + return state; + } +} + +static void +clear_state(module_state *state) +{ + state->initialized = 0; + Py_CLEAR(state->error); + Py_CLEAR(state->int_const); + Py_CLEAR(state->str_const); +} + +static int +_set_initialized(_PyTime_t *initialized) +{ + /* We go strictly monotonic to ensure each time is unique. */ + _PyTime_t prev; + if (_PyTime_GetMonotonicClockWithInfo(&prev, NULL) != 0) { + return -1; + } + /* We do a busy sleep since the interval should be super short. */ + _PyTime_t t; + do { + if (_PyTime_GetMonotonicClockWithInfo(&t, NULL) != 0) { + return -1; + } + } while (t == prev); + + *initialized = t; + return 0; +} + +static int +init_state(module_state *state) +{ + assert(state->initialized == 0 && + state->error == NULL && + state->int_const == NULL && + state->str_const == NULL); + + if (_set_initialized(&state->initialized) != 0) { + goto error; + } + assert(state->initialized > 0); + + /* Add an exception type */ + state->error = PyErr_NewException("_testsinglephase.error", NULL, NULL); + if (state->error == NULL) { + goto error; + } + + state->int_const = PyLong_FromLong(1969); + if (state->int_const == NULL) { + goto error; + } + + state->str_const = PyUnicode_FromString("something different"); + if (state->str_const == NULL) { + goto error; + } + + return 0; + +error: + clear_state(state); + return -1; +} + + +static int +init_module(PyObject *module, module_state *state) +{ + if (PyModule_AddObjectRef(module, "error", state->error) != 0) { + return -1; + } + if (PyModule_AddObjectRef(module, "int_const", state->int_const) != 0) { + return -1; + } + if (PyModule_AddObjectRef(module, "str_const", state->str_const) != 0) { + return -1; + } + + double d = _PyTime_AsSecondsDouble(state->initialized); + PyObject *initialized = PyFloat_FromDouble(d); + if (initialized == NULL) { + return -1; + } + int rc = PyModule_AddObjectRef(module, "_module_initialized", initialized); + Py_DECREF(initialized); + if (rc < 0) { + return -1; + } + + return 0; +} + + +PyDoc_STRVAR(common_state_initialized_doc, +"state_initialized()\n\ +\n\ +Return the seconds-since-epoch when the module state was initialized."); + +static PyObject * +common_state_initialized(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + module_state *state = get_module_state(self); + if (state == NULL) { + Py_RETURN_NONE; + } + double d = _PyTime_AsSecondsDouble(state->initialized); + return PyFloat_FromDouble(d); +} + +#define STATE_INITIALIZED_METHODDEF \ + {"state_initialized", common_state_initialized, METH_NOARGS, \ + common_state_initialized_doc} + + +PyDoc_STRVAR(common_look_up_self_doc, +"look_up_self()\n\ +\n\ +Return the module associated with this module's def.m_base.m_index."); + +static PyObject * +common_look_up_self(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyModuleDef *def = PyModule_GetDef(self); + if (def == NULL) { + return NULL; + } + return Py_NewRef( + PyState_FindModule(def)); +} + +#define LOOK_UP_SELF_METHODDEF \ + {"look_up_self", common_look_up_self, METH_NOARGS, common_look_up_self_doc} + + +/* Function of two integers returning integer */ + +PyDoc_STRVAR(common_sum_doc, +"sum(i,j)\n\ +\n\ +Return the sum of i and j."); + +static PyObject * +common_sum(PyObject *self, PyObject *args) +{ + long i, j; + long res; + if (!PyArg_ParseTuple(args, "ll:sum", &i, &j)) + return NULL; + res = i + j; + return PyLong_FromLong(res); +} + +#define SUM_METHODDEF \ + {"sum", common_sum, METH_VARARGS, common_sum_doc} + + +PyDoc_STRVAR(basic_initialized_count_doc, +"initialized_count()\n\ +\n\ +Return how many times the module has been initialized."); + +static PyObject * +basic_initialized_count(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + assert(PyModule_GetDef(self)->m_size == -1); + return PyLong_FromLong(global_state.initialized_count); +} + +#define INITIALIZED_COUNT_METHODDEF \ + {"initialized_count", basic_initialized_count, METH_NOARGS, \ + basic_initialized_count_doc} + + +PyDoc_STRVAR(basic__clear_globals_doc, +"_clear_globals()\n\ +\n\ +Free all global state and set it to uninitialized."); + +static PyObject * +basic__clear_globals(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + assert(PyModule_GetDef(self)->m_size == -1); + clear_global_state(); + Py_RETURN_NONE; +} + +#define _CLEAR_GLOBALS_METHODDEF \ + {"_clear_globals", basic__clear_globals, METH_NOARGS, \ + basic__clear_globals_doc} + + +PyDoc_STRVAR(basic__clear_module_state_doc, "_clear_module_state()\n\ +\n\ +Free the module state and set it to uninitialized."); + +static PyObject * +basic__clear_module_state(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + module_state *state = get_module_state(self); + if (state != NULL) { + clear_state(state); + } + Py_RETURN_NONE; +} + +#define _CLEAR_MODULE_STATE_METHODDEF \ + {"_clear_module_state", basic__clear_module_state, METH_NOARGS, \ + basic__clear_module_state_doc} + + +/*********************************************/ +/* the _testsinglephase module (and aliases) */ +/*********************************************/ + +/* This ia more typical of legacy extensions in the wild: + - single-phase init + - no module state + - does not support repeated initialization + (so m_copy is used) + - the module def is cached in _PyRuntime.extensions + (by name/filename) + + Also note that, because the module has single-phase init, + it is cached in interp->module_by_index (using mod->md_def->m_base.m_index). + */ + +static PyMethodDef TestMethods_Basic[] = { + LOOK_UP_SELF_METHODDEF, + SUM_METHODDEF, + STATE_INITIALIZED_METHODDEF, + INITIALIZED_COUNT_METHODDEF, + _CLEAR_GLOBALS_METHODDEF, + {NULL, NULL} /* sentinel */ +}; + +static struct PyModuleDef _testsinglephase_basic = { + PyModuleDef_HEAD_INIT, + .m_name = "_testsinglephase", + .m_doc = PyDoc_STR("Test module _testsinglephase"), + .m_size = -1, // no module state + .m_methods = TestMethods_Basic, +}; + +static PyObject * +init__testsinglephase_basic(PyModuleDef *def) +{ + if (global_state.initialized_count == -1) { + global_state.initialized_count = 0; + } + + PyObject *module = PyModule_Create(def); + if (module == NULL) { + return NULL; + } + + module_state *state = &global_state.module; + // It may have been set by a previous run or under a different name. + clear_state(state); + if (init_state(state) < 0) { + Py_CLEAR(module); + return NULL; + } + + if (init_module(module, state) < 0) { + Py_CLEAR(module); + goto finally; + } + + global_state.initialized_count++; + +finally: + return module; +} + +PyMODINIT_FUNC +PyInit__testsinglephase(void) +{ + return init__testsinglephase_basic(&_testsinglephase_basic); +} + + +PyMODINIT_FUNC +PyInit__testsinglephase_basic_wrapper(void) +{ + return PyInit__testsinglephase(); +} + + +PyMODINIT_FUNC +PyInit__testsinglephase_basic_copy(void) +{ + static struct PyModuleDef def = { + PyModuleDef_HEAD_INIT, + .m_name = "_testsinglephase_basic_copy", + .m_doc = PyDoc_STR("Test module _testsinglephase_basic_copy"), + .m_size = -1, // no module state + .m_methods = TestMethods_Basic, + }; + return init__testsinglephase_basic(&def); +} + + +/*******************************************/ +/* the _testsinglephase_with_reinit module */ +/*******************************************/ + +/* This ia less typical of legacy extensions in the wild: + - single-phase init (same as _testsinglephase above) + - no module state + - supports repeated initialization + (so m_copy is not used) + - the module def is not cached in _PyRuntime.extensions + + At this point most modules would reach for multi-phase init (PEP 489). + However, module state has been around a while (PEP 3121), + and most extensions predate multi-phase init. + + (This module is basically the same as _testsinglephase, + but supports repeated initialization.) + */ + +static PyMethodDef TestMethods_Reinit[] = { + LOOK_UP_SELF_METHODDEF, + SUM_METHODDEF, + STATE_INITIALIZED_METHODDEF, + {NULL, NULL} /* sentinel */ +}; + +static struct PyModuleDef _testsinglephase_with_reinit = { + PyModuleDef_HEAD_INIT, + .m_name = "_testsinglephase_with_reinit", + .m_doc = PyDoc_STR("Test module _testsinglephase_with_reinit"), + .m_size = 0, + .m_methods = TestMethods_Reinit, +}; + +PyMODINIT_FUNC +PyInit__testsinglephase_with_reinit(void) +{ + /* We purposefully do not try PyState_FindModule() first here + since we want to check the behavior of re-loading the module. */ + PyObject *module = PyModule_Create(&_testsinglephase_with_reinit); + if (module == NULL) { + return NULL; + } + + assert(get_module_state(module) == NULL); + + module_state state = {0}; + if (init_state(&state) < 0) { + Py_CLEAR(module); + return NULL; + } + + if (init_module(module, &state) < 0) { + Py_CLEAR(module); + goto finally; + } + +finally: + /* We only needed the module state for setting the module attrs. */ + clear_state(&state); + return module; +} + + +/******************************************/ +/* the _testsinglephase_with_state module */ +/******************************************/ + +/* This is less typical of legacy extensions in the wild: + - single-phase init (same as _testsinglephase above) + - has some module state + - supports repeated initialization + (so m_copy is not used) + - the module def is not cached in _PyRuntime.extensions + + At this point most modules would reach for multi-phase init (PEP 489). + However, module state has been around a while (PEP 3121), + and most extensions predate multi-phase init. + */ + +static PyMethodDef TestMethods_WithState[] = { + LOOK_UP_SELF_METHODDEF, + SUM_METHODDEF, + STATE_INITIALIZED_METHODDEF, + _CLEAR_MODULE_STATE_METHODDEF, + {NULL, NULL} /* sentinel */ +}; + +static struct PyModuleDef _testsinglephase_with_state = { + PyModuleDef_HEAD_INIT, + .m_name = "_testsinglephase_with_state", + .m_doc = PyDoc_STR("Test module _testsinglephase_with_state"), + .m_size = sizeof(module_state), + .m_methods = TestMethods_WithState, +}; + +PyMODINIT_FUNC +PyInit__testsinglephase_with_state(void) +{ + /* We purposefully do not try PyState_FindModule() first here + since we want to check the behavior of re-loading the module. */ + PyObject *module = PyModule_Create(&_testsinglephase_with_state); + if (module == NULL) { + return NULL; + } + + module_state *state = get_module_state(module); + assert(state != NULL); + if (init_state(state) < 0) { + Py_CLEAR(module); + return NULL; + } + + if (init_module(module, state) < 0) { + clear_state(state); + Py_CLEAR(module); + goto finally; + } + +finally: + return module; +} diff --git a/Modules/_threadmodule.c b/Modules/_threadmodule.c index 879c94a1..04f4400a 100644 --- a/Modules/_threadmodule.c +++ b/Modules/_threadmodule.c @@ -81,6 +81,7 @@ lock_dealloc(lockobject *self) static PyLockStatus acquire_timed(PyThread_type_lock lock, _PyTime_t timeout) { + PyThreadState *tstate = _PyThreadState_GET(); _PyTime_t endtime = 0; if (timeout > 0) { endtime = _PyDeadline_Init(timeout); @@ -103,7 +104,7 @@ acquire_timed(PyThread_type_lock lock, _PyTime_t timeout) /* Run signal handlers if we were interrupted. Propagate * exceptions from signal handlers, such as KeyboardInterrupt, by * passing up PY_LOCK_INTR. */ - if (Py_MakePendingCalls() < 0) { + if (_PyEval_MakePendingCalls(tstate) < 0) { return PY_LOCK_INTR; } @@ -135,7 +136,7 @@ lock_acquire_parse_args(PyObject *args, PyObject *kwds, *timeout = unset_timeout ; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|iO:acquire", kwlist, + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|pO:acquire", kwlist, &blocking, &timeout_obj)) return -1; @@ -839,11 +840,6 @@ local_traverse(localobject *self, visitproc visit, void *arg) return 0; } -#define HEAD_LOCK(runtime) \ - PyThread_acquire_lock((runtime)->interpreters.mutex, WAIT_LOCK) -#define HEAD_UNLOCK(runtime) \ - PyThread_release_lock((runtime)->interpreters.mutex) - static int local_clear(localobject *self) { @@ -951,7 +947,7 @@ local_setattro(localobject *self, PyObject *name, PyObject *v) } if (r == 1) { PyErr_Format(PyExc_AttributeError, - "'%.50s' object attribute '%U' is read-only", + "'%.100s' object attribute '%U' is read-only", Py_TYPE(self)->tp_name, name); return -1; } @@ -1079,13 +1075,7 @@ thread_run(void *boot_raw) PyThreadState *tstate; tstate = boot->tstate; - tstate->thread_id = PyThread_get_thread_ident(); -#ifdef PY_HAVE_THREAD_NATIVE_ID - tstate->native_thread_id = PyThread_get_thread_native_id(); -#else - tstate->native_thread_id = 0; -#endif - _PyThreadState_SetCurrent(tstate); + _PyThreadState_Bind(tstate); PyEval_AcquireThread(tstate); tstate->interp->threads.count++; @@ -1112,6 +1102,24 @@ thread_run(void *boot_raw) // to open the libgcc_s.so library (ex: EMFILE error). } +static PyObject * +thread_daemon_threads_allowed(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + PyInterpreterState *interp = _PyInterpreterState_Get(); + if (interp->feature_flags & Py_RTFLAGS_DAEMON_THREADS) { + Py_RETURN_TRUE; + } + else { + Py_RETURN_FALSE; + } +} + +PyDoc_STRVAR(daemon_threads_allowed_doc, +"daemon_threads_allowed()\n\ +\n\ +Return True if daemon threads are allowed in the current interpreter,\n\ +and False otherwise.\n"); + static PyObject * thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs) { @@ -1137,22 +1145,35 @@ thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs) return NULL; } + if (PySys_Audit("_thread.start_new_thread", "OOO", + func, args, kwargs ? kwargs : Py_None) < 0) { + return NULL; + } + PyInterpreterState *interp = _PyInterpreterState_GET(); - if (interp->config._isolated_interpreter) { + if (!_PyInterpreterState_HasFeature(interp, Py_RTFLAGS_THREADS)) { PyErr_SetString(PyExc_RuntimeError, "thread is not supported for isolated subinterpreters"); return NULL; } + if (interp->finalizing) { + PyErr_SetString(PyExc_RuntimeError, + "can't create new thread at interpreter shutdown"); + return NULL; + } struct bootstate *boot = PyMem_NEW(struct bootstate, 1); if (boot == NULL) { return PyErr_NoMemory(); } boot->interp = _PyInterpreterState_GET(); - boot->tstate = _PyThreadState_Prealloc(boot->interp); + boot->tstate = _PyThreadState_New(boot->interp); if (boot->tstate == NULL) { PyMem_Free(boot); - return PyErr_NoMemory(); + if (!PyErr_Occurred()) { + return PyErr_NoMemory(); + } + return NULL; } boot->runtime = runtime; boot->func = Py_NewRef(func); @@ -1553,6 +1574,8 @@ static PyMethodDef thread_methods[] = { METH_VARARGS, start_new_doc}, {"start_new", (PyCFunction)thread_PyThread_start_new_thread, METH_VARARGS, start_new_doc}, + {"daemon_threads_allowed", (PyCFunction)thread_daemon_threads_allowed, + METH_NOARGS, daemon_threads_allowed_doc}, {"allocate_lock", thread_PyThread_allocate_lock, METH_NOARGS, allocate_doc}, {"allocate", thread_PyThread_allocate_lock, @@ -1648,8 +1671,8 @@ thread_module_exec(PyObject *module) // Round towards minus infinity timeout_max = floor(timeout_max); - if (PyModule_AddObject(module, "TIMEOUT_MAX", - PyFloat_FromDouble(timeout_max)) < 0) { + if (_PyModule_Add(module, "TIMEOUT_MAX", + PyFloat_FromDouble(timeout_max)) < 0) { return -1; } @@ -1693,6 +1716,7 @@ The 'threading' module provides a more convenient interface."); static PyModuleDef_Slot thread_module_slots[] = { {Py_mod_exec, thread_module_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; diff --git a/Modules/_tkinter.c b/Modules/_tkinter.c index 4807ad59..5abde84e 100644 --- a/Modules/_tkinter.c +++ b/Modules/_tkinter.c @@ -32,6 +32,8 @@ Copyright (C) 1994 Steen Lumholt. # include "pycore_fileutils.h" // _Py_stat() #endif +#include "pycore_long.h" + #ifdef MS_WINDOWS #include <windows.h> #endif @@ -58,8 +60,17 @@ Copyright (C) 1994 Steen Lumholt. #error "Tk older than 8.5.12 not supported" #endif +#ifndef TCL_WITH_EXTERNAL_TOMMATH +#define TCL_NO_TOMMATH_H +#endif #include <tclTomMath.h> +#if defined(TCL_WITH_EXTERNAL_TOMMATH) || (TK_HEX_VERSION >= 0x08070000) +#define USE_DEPRECATED_TOMMATH_API 0 +#else +#define USE_DEPRECATED_TOMMATH_API 1 +#endif + #if !(defined(MS_WINDOWS) || defined(__CYGWIN__)) #define HAVE_CREATEFILEHANDLER #endif @@ -119,7 +130,7 @@ Copyright (C) 1994 Steen Lumholt. #define WAIT_FOR_STDIN static PyObject * -_get_tcl_lib_path() +_get_tcl_lib_path(void) { static PyObject *tcl_library_path = NULL; static int already_checked = 0; @@ -321,12 +332,6 @@ static PyObject *Tkinter_TclError; static int quitMainLoop = 0; static int errorInCmd = 0; static PyObject *excInCmd; -static PyObject *valInCmd; -static PyObject *trbInCmd; - -#ifdef TKINTER_PROTECT_LOADTK -static int tk_load_failed = 0; -#endif static PyObject *Tkapp_UnicodeResult(TkappObject *); @@ -532,17 +537,7 @@ Tcl_AppInit(Tcl_Interp *interp) return TCL_OK; } -#ifdef TKINTER_PROTECT_LOADTK - if (tk_load_failed) { - PySys_WriteStderr("Tk_Init error: %s\n", TKINTER_LOADTK_ERRMSG); - return TCL_ERROR; - } -#endif - if (Tk_Init(interp) == TCL_ERROR) { -#ifdef TKINTER_PROTECT_LOADTK - tk_load_failed = 1; -#endif PySys_WriteStderr("Tk_Init error: %s\n", Tcl_GetStringResult(interp)); return TCL_ERROR; } @@ -635,12 +630,6 @@ Tkapp_New(const char *screenName, const char *className, Tcl_SetVar(v->interp, "_tkinter_skip_tk_init", "1", TCL_GLOBAL_ONLY); } -#ifdef TKINTER_PROTECT_LOADTK - else if (tk_load_failed) { - Tcl_SetVar(v->interp, - "_tkinter_tk_failed", "1", TCL_GLOBAL_ONLY); - } -#endif /* some initial arguments need to be in argv */ if (sync || use) { @@ -702,18 +691,6 @@ Tkapp_New(const char *screenName, const char *className, if (Tcl_AppInit(v->interp) != TCL_OK) { PyObject *result = Tkinter_Error(v); -#ifdef TKINTER_PROTECT_LOADTK - if (wantTk) { - const char *_tkinter_tk_failed; - _tkinter_tk_failed = Tcl_GetVar(v->interp, - "_tkinter_tk_failed", TCL_GLOBAL_ONLY); - - if ( _tkinter_tk_failed != NULL && - strcmp(_tkinter_tk_failed, "1") == 0) { - tk_load_failed = 1; - } - } -#endif Py_DECREF((PyObject *)v); return (TkappObject *)result; } @@ -784,16 +761,14 @@ PyTclObject_string(PyTclObject *self, void *ignored) if (!self->string) return NULL; } - Py_INCREF(self->string); - return self->string; + return Py_NewRef(self->string); } static PyObject * PyTclObject_str(PyTclObject *self) { if (self->string) { - Py_INCREF(self->string); - return self->string; + return Py_NewRef(self->string); } /* XXX Could cache result if it is non-ASCII. */ return unicodeFromTclObj(self->value); @@ -890,7 +865,8 @@ asBignumObj(PyObject *value) const char *hexchars; mp_int bigValue; - neg = Py_SIZE(value) < 0; + assert(PyLong_Check(value)); + neg = _PyLong_IsNegative((PyLongObject *)value); hexstr = _PyLong_Format(value, 16); if (hexstr == NULL) return NULL; @@ -900,8 +876,9 @@ asBignumObj(PyObject *value) return NULL; } hexchars += neg + 2; /* skip sign and "0x" */ - mp_init(&bigValue); - if (mp_read_radix(&bigValue, hexchars, 16) != MP_OKAY) { + if (mp_init(&bigValue) != MP_OKAY || + mp_read_radix(&bigValue, hexchars, 16) != MP_OKAY) + { mp_clear(&bigValue); Py_DECREF(hexstr); PyErr_NoMemory(); @@ -1083,20 +1060,33 @@ static PyObject* fromBignumObj(TkappObject *tkapp, Tcl_Obj *value) { mp_int bigValue; + mp_err err; +#if USE_DEPRECATED_TOMMATH_API unsigned long numBytes; +#else + size_t numBytes; +#endif unsigned char *bytes; PyObject *res; if (Tcl_GetBignumFromObj(Tkapp_Interp(tkapp), value, &bigValue) != TCL_OK) return Tkinter_Error(tkapp); +#if USE_DEPRECATED_TOMMATH_API numBytes = mp_unsigned_bin_size(&bigValue); +#else + numBytes = mp_ubin_size(&bigValue); +#endif bytes = PyMem_Malloc(numBytes); if (bytes == NULL) { mp_clear(&bigValue); return PyErr_NoMemory(); } - if (mp_to_unsigned_bin_n(&bigValue, bytes, - &numBytes) != MP_OKAY) { +#if USE_DEPRECATED_TOMMATH_API + err = mp_to_unsigned_bin_n(&bigValue, bytes, &numBytes); +#else + err = mp_to_ubin(&bigValue, bytes, numBytes, NULL); +#endif + if (err != MP_OKAY) { mp_clear(&bigValue); PyMem_Free(bytes); return PyErr_NoMemory(); @@ -1107,8 +1097,7 @@ fromBignumObj(TkappObject *tkapp, Tcl_Obj *value) PyMem_Free(bytes); if (res != NULL && bigValue.sign == MP_NEG) { PyObject *res2 = PyNumber_Negative(res); - Py_DECREF(res); - res = res2; + Py_SETREF(res, res2); } mp_clear(&bigValue); return res; @@ -1225,7 +1214,7 @@ typedef struct Tkapp_CallEvent { PyObject *args; int flags; PyObject **res; - PyObject **exc_type, **exc_value, **exc_tb; + PyObject **exc; Tcl_Condition *done; } Tkapp_CallEvent; @@ -1342,7 +1331,7 @@ Tkapp_CallProc(Tkapp_CallEvent *e, int flags) ENTER_PYTHON objv = Tkapp_CallArgs(e->args, objStore, &objc); if (!objv) { - PyErr_Fetch(e->exc_type, e->exc_value, e->exc_tb); + *(e->exc) = PyErr_GetRaisedException(); *(e->res) = NULL; } LEAVE_PYTHON @@ -1357,7 +1346,7 @@ Tkapp_CallProc(Tkapp_CallEvent *e, int flags) *(e->res) = Tkapp_ObjectResult(e->self); } if (*(e->res) == NULL) { - PyErr_Fetch(e->exc_type, e->exc_value, e->exc_tb); + *(e->exc) = PyErr_GetRaisedException(); } LEAVE_PYTHON @@ -1404,7 +1393,7 @@ Tkapp_Call(PyObject *selfptr, PyObject *args) marshal the parameters to the interpreter thread. */ Tkapp_CallEvent *ev; Tcl_Condition cond = NULL; - PyObject *exc_type, *exc_value, *exc_tb; + PyObject *exc; if (!WaitForMainloop(self)) return NULL; ev = (Tkapp_CallEvent*)attemptckalloc(sizeof(Tkapp_CallEvent)); @@ -1416,18 +1405,18 @@ Tkapp_Call(PyObject *selfptr, PyObject *args) ev->self = self; ev->args = args; ev->res = &res; - ev->exc_type = &exc_type; - ev->exc_value = &exc_value; - ev->exc_tb = &exc_tb; + ev->exc = &exc; ev->done = &cond; Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond, &call_mutex); if (res == NULL) { - if (exc_type) - PyErr_Restore(exc_type, exc_value, exc_tb); - else - PyErr_SetObject(Tkinter_TclError, exc_value); + if (exc) { + PyErr_SetRaisedException(exc); + } + else { + PyErr_SetObject(Tkinter_TclError, exc); + } } Tcl_ConditionFinalize(&cond); } @@ -1581,8 +1570,7 @@ typedef struct VarEvent { int flags; EventFunc func; PyObject **res; - PyObject **exc_type; - PyObject **exc_val; + PyObject **exc; Tcl_Condition *cond; } VarEvent; @@ -1646,12 +1634,7 @@ var_perform(VarEvent *ev) { *(ev->res) = ev->func(ev->self, ev->args, ev->flags); if (!*(ev->res)) { - PyObject *exc, *val, *tb; - PyErr_Fetch(&exc, &val, &tb); - PyErr_NormalizeException(&exc, &val, &tb); - *(ev->exc_type) = exc; - *(ev->exc_val) = val; - Py_XDECREF(tb); + *(ev->exc) = PyErr_GetRaisedException();; } } @@ -1675,7 +1658,7 @@ var_invoke(EventFunc func, PyObject *selfptr, PyObject *args, int flags) TkappObject *self = (TkappObject*)selfptr; if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) { VarEvent *ev; - PyObject *res, *exc_type, *exc_val; + PyObject *res, *exc; Tcl_Condition cond = NULL; /* The current thread is not the interpreter thread. Marshal @@ -1694,16 +1677,14 @@ var_invoke(EventFunc func, PyObject *selfptr, PyObject *args, int flags) ev->flags = flags; ev->func = func; ev->res = &res; - ev->exc_type = &exc_type; - ev->exc_val = &exc_val; + ev->exc = &exc; ev->cond = &cond; ev->ev.proc = (Tcl_EventProc*)var_proc; Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond, &var_mutex); Tcl_ConditionFinalize(&cond); if (!res) { - PyErr_SetObject(exc_type, exc_val); - Py_DECREF(exc_type); - Py_DECREF(exc_val); + PyErr_SetObject((PyObject*)Py_TYPE(exc), exc); + Py_DECREF(exc); return NULL; } return res; @@ -1736,8 +1717,7 @@ SetVar(TkappObject *self, PyObject *args, int flags) if (!ok) Tkinter_Error(self); else { - res = Py_None; - Py_INCREF(res); + res = Py_NewRef(Py_None); } LEAVE_OVERLAP_TCL break; @@ -1755,8 +1735,7 @@ SetVar(TkappObject *self, PyObject *args, int flags) if (!ok) Tkinter_Error(self); else { - res = Py_None; - Py_INCREF(res); + res = Py_NewRef(Py_None); } LEAVE_OVERLAP_TCL break; @@ -1842,8 +1821,7 @@ UnsetVar(TkappObject *self, PyObject *args, int flags) if (code == TCL_ERROR) res = Tkinter_Error(self); else { - Py_INCREF(Py_None); - res = Py_None; + res = Py_NewRef(Py_None); } LEAVE_OVERLAP_TCL return res; @@ -1883,8 +1861,7 @@ _tkinter_tkapp_getint(TkappObject *self, PyObject *arg) PyObject *result; if (PyLong_Check(arg)) { - Py_INCREF(arg); - return arg; + return Py_NewRef(arg); } if (PyTclObject_Check(arg)) { @@ -1928,8 +1905,7 @@ _tkinter_tkapp_getdouble(TkappObject *self, PyObject *arg) double v; if (PyFloat_Check(arg)) { - Py_INCREF(arg); - return arg; + return Py_NewRef(arg); } if (PyNumber_Check(arg)) { @@ -1968,7 +1944,7 @@ _tkinter_tkapp_getboolean(TkappObject *self, PyObject *arg) int v; if (PyLong_Check(arg)) { /* int or bool */ - return PyBool_FromLong(Py_SIZE(arg) != 0); + return PyBool_FromLong(!_PyLong_IsZero((PyLongObject *)arg)); } if (PyTclObject_Check(arg)) { @@ -2145,8 +2121,7 @@ _tkinter_tkapp_splitlist(TkappObject *self, PyObject *arg) return v; } if (PyTuple_Check(arg)) { - Py_INCREF(arg); - return arg; + return Py_NewRef(arg); } if (PyList_Check(arg)) { return PySequence_Tuple(arg); @@ -2172,8 +2147,7 @@ _tkinter_tkapp_splitlist(TkappObject *self, PyObject *arg) for (i = 0; i < argc; i++) { PyObject *s = unicodeFromTclString(argv[i]); if (!s) { - Py_DECREF(v); - v = NULL; + Py_SETREF(v, NULL); goto finally; } PyTuple_SET_ITEM(v, i, s); @@ -2198,7 +2172,7 @@ static int PythonCmd_Error(Tcl_Interp *interp) { errorInCmd = 1; - PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd); + excInCmd = PyErr_GetRaisedException(); LEAVE_PYTHON return TCL_ERROR; } @@ -2322,10 +2296,8 @@ _tkinter_tkapp_createcommand_impl(TkappObject *self, const char *name, data = PyMem_NEW(PythonCmd_ClientData, 1); if (!data) return PyErr_NoMemory(); - Py_INCREF(self); - Py_INCREF(func); - data->self = (PyObject *) self; - data->func = func; + data->self = Py_NewRef(self); + data->func = Py_NewRef(func); if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) { Tcl_Condition cond = NULL; CommandEvent *ev = (CommandEvent*)attemptckalloc(sizeof(CommandEvent)); @@ -2430,10 +2402,8 @@ NewFHCD(PyObject *func, PyObject *file, int id) FileHandler_ClientData *p; p = PyMem_NEW(FileHandler_ClientData, 1); if (p != NULL) { - Py_XINCREF(func); - Py_XINCREF(file); - p->func = func; - p->file = file; + p->func = Py_XNewRef(func); + p->file = Py_XNewRef(file); p->id = id; p->next = HeadFHCD; HeadFHCD = p; @@ -2472,7 +2442,7 @@ FileHandler(ClientData clientData, int mask) res = PyObject_CallFunction(func, "Oi", file, mask); if (res == NULL) { errorInCmd = 1; - PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd); + excInCmd = PyErr_GetRaisedException(); } Py_XDECREF(res); LEAVE_PYTHON @@ -2591,13 +2561,11 @@ Tktt_New(PyObject *func) if (v == NULL) return NULL; - Py_INCREF(func); v->token = NULL; - v->func = func; + v->func = Py_NewRef(func); /* Extra reference, deleted when called or when handler is deleted */ - Py_INCREF(v); - return v; + return (TkttObject*)Py_NewRef(v); } static void @@ -2644,7 +2612,7 @@ TimerHandler(ClientData clientData) if (res == NULL) { errorInCmd = 1; - PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd); + excInCmd = PyErr_GetRaisedException(); } else Py_DECREF(res); @@ -2741,8 +2709,8 @@ _tkinter_tkapp_mainloop_impl(TkappObject *self, int threshold) if (errorInCmd) { errorInCmd = 0; - PyErr_Restore(excInCmd, valInCmd, trbInCmd); - excInCmd = valInCmd = trbInCmd = NULL; + PyErr_SetRaisedException(excInCmd); + excInCmd = NULL; return NULL; } Py_RETURN_NONE; @@ -2803,18 +2771,6 @@ _tkinter_tkapp_loadtk_impl(TkappObject *self) const char * _tk_exists = NULL; int err; -#ifdef TKINTER_PROTECT_LOADTK - /* Up to Tk 8.4.13, Tk_Init deadlocks on the second call when the - * first call failed. - * To avoid the deadlock, we just refuse the second call through - * a static variable. - */ - if (tk_load_failed) { - PyErr_SetString(Tkinter_TclError, TKINTER_LOADTK_ERRMSG); - return NULL; - } -#endif - /* We want to guard against calling Tk_Init() multiple times */ CHECK_TCL_APPARTMENT; ENTER_TCL @@ -2834,9 +2790,6 @@ _tkinter_tkapp_loadtk_impl(TkappObject *self) if (_tk_exists == NULL || strcmp(_tk_exists, "1") != 0) { if (Tk_Init(interp) == TCL_ERROR) { Tkinter_Error(self); -#ifdef TKINTER_PROTECT_LOADTK - tk_load_failed = 1; -#endif return NULL; } } @@ -2848,7 +2801,7 @@ Tkapp_WantObjects(PyObject *self, PyObject *args) { int wantobjects = -1; - if (!PyArg_ParseTuple(args, "|i:wantobjects", &wantobjects)) + if (!PyArg_ParseTuple(args, "|p:wantobjects", &wantobjects)) return NULL; if (wantobjects == -1) return PyBool_FromLong(((TkappObject*)self)->wantobjects); @@ -2940,9 +2893,8 @@ _flatten1(FlattenContext* context, PyObject* item, int depth) if (context->size + 1 > context->maxsize && !_bump(context, 1)) return 0; - Py_INCREF(o); PyTuple_SET_ITEM(context->tuple, - context->size++, o); + context->size++, Py_NewRef(o)); } } } else { @@ -2995,11 +2947,11 @@ _tkinter.create screenName: str(accept={str, NoneType}) = None baseName: str = "" className: str = "Tk" - interactive: bool(accept={int}) = False - wantobjects: bool(accept={int}) = False - wantTk: bool(accept={int}) = True + interactive: bool = False + wantobjects: bool = False + wantTk: bool = True if false, then Tk_Init() doesn't get called - sync: bool(accept={int}) = False + sync: bool = False if true, then pass -sync to wish use: str(accept={str, NoneType}) = None if not None, then pass -use to wish @@ -3012,7 +2964,7 @@ _tkinter_create_impl(PyObject *module, const char *screenName, const char *baseName, const char *className, int interactive, int wantobjects, int wantTk, int sync, const char *use) -/*[clinic end generated code: output=e3315607648e6bb4 input=da9b17ee7358d862]*/ +/*[clinic end generated code: output=e3315607648e6bb4 input=09afef9adea70a19]*/ { /* XXX baseName is not used anymore; * try getting rid of it. */ @@ -3204,8 +3156,8 @@ EventHook(void) #endif if (errorInCmd) { errorInCmd = 0; - PyErr_Restore(excInCmd, valInCmd, trbInCmd); - excInCmd = valInCmd = trbInCmd = NULL; + PyErr_SetRaisedException(excInCmd); + excInCmd = NULL; PyErr_Print(); } PyEval_SaveThread(); @@ -3266,8 +3218,7 @@ PyInit__tkinter(void) Py_DECREF(m); return NULL; } - Py_INCREF(o); - if (PyModule_AddObject(m, "TclError", o)) { + if (PyModule_AddObject(m, "TclError", Py_NewRef(o))) { Py_DECREF(o); Py_DECREF(m); return NULL; @@ -3355,20 +3306,6 @@ PyInit__tkinter(void) } PyTclObject_Type = o; -#ifdef TK_AQUA - /* Tk_MacOSXSetupTkNotifier must be called before Tcl's subsystems - * start waking up. Note that Tcl_FindExecutable will do this, this - * code must be above it! The original warning from - * tkMacOSXAppInit.c is copied below. - * - * NB - You have to swap in the Tk Notifier BEFORE you start up the - * Tcl interpreter for now. It probably should work to do this - * in the other order, but for now it doesn't seem to. - * - */ - Tk_MacOSXSetupTkNotifier(); -#endif - /* This helps the dynamic loader; in Unicode aware Tcl versions it also helps Tcl find its encodings. */ diff --git a/Modules/_tracemalloc.c b/Modules/_tracemalloc.c index 44a1f7b6..f3f4af9a 100644 --- a/Modules/_tracemalloc.c +++ b/Modules/_tracemalloc.c @@ -1,1044 +1,12 @@ #include "Python.h" -#include "pycore_fileutils.h" // _Py_write_noraise() -#include "pycore_gc.h" // PyGC_Head -#include "pycore_hashtable.h" // _Py_hashtable_t -#include "pycore_pymem.h" // _Py_tracemalloc_config -#include "pycore_runtime.h" // _Py_ID() -#include "pycore_traceback.h" -#include <pycore_frame.h> -#include <stdlib.h> // malloc() - -#include "clinic/_tracemalloc.c.h" - -/*[clinic input] -module _tracemalloc -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=708a98302fc46e5f]*/ - -_Py_DECLARE_STR(anon_unknown, "<unknown>"); - -/* Trace memory blocks allocated by PyMem_RawMalloc() */ -#define TRACE_RAW_MALLOC - -/* Forward declaration */ -static void tracemalloc_stop(void); -static void* raw_malloc(size_t size); -static void raw_free(void *ptr); - -#ifdef Py_DEBUG -# define TRACE_DEBUG -#endif - -#define TO_PTR(key) ((const void *)(uintptr_t)(key)) -#define FROM_PTR(key) ((uintptr_t)(key)) - -/* Protected by the GIL */ -static struct { - PyMemAllocatorEx mem; - PyMemAllocatorEx raw; - PyMemAllocatorEx obj; -} allocators; - - -#if defined(TRACE_RAW_MALLOC) -/* This lock is needed because tracemalloc_free() is called without - the GIL held from PyMem_RawFree(). It cannot acquire the lock because it - would introduce a deadlock in _PyThreadState_DeleteCurrent(). */ -static PyThread_type_lock tables_lock; -# define TABLES_LOCK() PyThread_acquire_lock(tables_lock, 1) -# define TABLES_UNLOCK() PyThread_release_lock(tables_lock) -#else - /* variables are protected by the GIL */ -# define TABLES_LOCK() -# define TABLES_UNLOCK() -#endif - - -#define DEFAULT_DOMAIN 0 - -/* Pack the frame_t structure to reduce the memory footprint on 64-bit - architectures: 12 bytes instead of 16. */ -typedef struct -#ifdef __GNUC__ -__attribute__((packed)) -#elif defined(_MSC_VER) -#pragma pack(push, 4) -#endif -{ - /* filename cannot be NULL: "<unknown>" is used if the Python frame - filename is NULL */ - PyObject *filename; - unsigned int lineno; -} frame_t; -#ifdef _MSC_VER -#pragma pack(pop) -#endif - - -typedef struct { - Py_uhash_t hash; - /* Number of frames stored */ - uint16_t nframe; - /* Total number of frames the traceback had */ - uint16_t total_nframe; - frame_t frames[1]; -} traceback_t; - -#define TRACEBACK_SIZE(NFRAME) \ - (sizeof(traceback_t) + sizeof(frame_t) * (NFRAME - 1)) - -/* The maximum number of frames is either: - - The maximum number of frames we can store in `traceback_t.nframe` - - The maximum memory size_t we can allocate */ -static const unsigned long MAX_NFRAME = Py_MIN(UINT16_MAX, ((SIZE_MAX - sizeof(traceback_t)) / sizeof(frame_t) + 1)); - - -static traceback_t tracemalloc_empty_traceback; - -/* Trace of a memory block */ -typedef struct { - /* Size of the memory block in bytes */ - size_t size; - - /* Traceback where the memory block was allocated */ - traceback_t *traceback; -} trace_t; - - -/* Size in bytes of currently traced memory. - Protected by TABLES_LOCK(). */ -static size_t tracemalloc_traced_memory = 0; - -/* Peak size in bytes of traced memory. - Protected by TABLES_LOCK(). */ -static size_t tracemalloc_peak_traced_memory = 0; - -/* Hash table used as a set to intern filenames: - PyObject* => PyObject*. - Protected by the GIL */ -static _Py_hashtable_t *tracemalloc_filenames = NULL; - -/* Buffer to store a new traceback in traceback_new(). - Protected by the GIL. */ -static traceback_t *tracemalloc_traceback = NULL; - -/* Hash table used as a set to intern tracebacks: - traceback_t* => traceback_t* - Protected by the GIL */ -static _Py_hashtable_t *tracemalloc_tracebacks = NULL; - -/* pointer (void*) => trace (trace_t*). - Protected by TABLES_LOCK(). */ -static _Py_hashtable_t *tracemalloc_traces = NULL; - -/* domain (unsigned int) => traces (_Py_hashtable_t). - Protected by TABLES_LOCK(). */ -static _Py_hashtable_t *tracemalloc_domains = NULL; - - -#ifdef TRACE_DEBUG -static void -tracemalloc_error(const char *format, ...) -{ - va_list ap; - fprintf(stderr, "tracemalloc: "); - va_start(ap, format); - vfprintf(stderr, format, ap); - va_end(ap); - fprintf(stderr, "\n"); - fflush(stderr); -} -#endif - - -#if defined(TRACE_RAW_MALLOC) -#define REENTRANT_THREADLOCAL - -static Py_tss_t tracemalloc_reentrant_key = Py_tss_NEEDS_INIT; - -/* Any non-NULL pointer can be used */ -#define REENTRANT Py_True - -static int -get_reentrant(void) -{ - void *ptr; - - assert(PyThread_tss_is_created(&tracemalloc_reentrant_key)); - ptr = PyThread_tss_get(&tracemalloc_reentrant_key); - if (ptr != NULL) { - assert(ptr == REENTRANT); - return 1; - } - else - return 0; -} - -static void -set_reentrant(int reentrant) -{ - assert(reentrant == 0 || reentrant == 1); - assert(PyThread_tss_is_created(&tracemalloc_reentrant_key)); - - if (reentrant) { - assert(!get_reentrant()); - PyThread_tss_set(&tracemalloc_reentrant_key, REENTRANT); - } - else { - assert(get_reentrant()); - PyThread_tss_set(&tracemalloc_reentrant_key, NULL); - } -} - -#else - -/* TRACE_RAW_MALLOC not defined: variable protected by the GIL */ -static int tracemalloc_reentrant = 0; - -static int -get_reentrant(void) -{ - return tracemalloc_reentrant; -} - -static void -set_reentrant(int reentrant) -{ - assert(reentrant != tracemalloc_reentrant); - tracemalloc_reentrant = reentrant; -} -#endif - - -static Py_uhash_t -hashtable_hash_pyobject(const void *key) -{ - PyObject *obj = (PyObject *)key; - return PyObject_Hash(obj); -} - - -static int -hashtable_compare_unicode(const void *key1, const void *key2) -{ - PyObject *obj1 = (PyObject *)key1; - PyObject *obj2 = (PyObject *)key2; - if (obj1 != NULL && obj2 != NULL) { - return (PyUnicode_Compare(obj1, obj2) == 0); - } - else { - return obj1 == obj2; - } -} - - -static Py_uhash_t -hashtable_hash_uint(const void *key_raw) -{ - unsigned int key = (unsigned int)FROM_PTR(key_raw); - return (Py_uhash_t)key; -} - - -static _Py_hashtable_t * -hashtable_new(_Py_hashtable_hash_func hash_func, - _Py_hashtable_compare_func compare_func, - _Py_hashtable_destroy_func key_destroy_func, - _Py_hashtable_destroy_func value_destroy_func) -{ - _Py_hashtable_allocator_t hashtable_alloc = {malloc, free}; - return _Py_hashtable_new_full(hash_func, compare_func, - key_destroy_func, value_destroy_func, - &hashtable_alloc); -} - - -static void* -raw_malloc(size_t size) -{ - return allocators.raw.malloc(allocators.raw.ctx, size); -} - -static void -raw_free(void *ptr) -{ - allocators.raw.free(allocators.raw.ctx, ptr); -} - - -static Py_uhash_t -hashtable_hash_traceback(const void *key) -{ - const traceback_t *traceback = (const traceback_t *)key; - return traceback->hash; -} - - -static int -hashtable_compare_traceback(const void *key1, const void *key2) -{ - const traceback_t *traceback1 = (const traceback_t *)key1; - const traceback_t *traceback2 = (const traceback_t *)key2; - - if (traceback1->nframe != traceback2->nframe) { - return 0; - } - if (traceback1->total_nframe != traceback2->total_nframe) { - return 0; - } - - for (int i=0; i < traceback1->nframe; i++) { - const frame_t *frame1 = &traceback1->frames[i]; - const frame_t *frame2 = &traceback2->frames[i]; - - if (frame1->lineno != frame2->lineno) { - return 0; - } - if (frame1->filename != frame2->filename) { - assert(PyUnicode_Compare(frame1->filename, frame2->filename) != 0); - return 0; - } - } - return 1; -} - - -static void -tracemalloc_get_frame(_PyInterpreterFrame *pyframe, frame_t *frame) -{ - frame->filename = &_Py_STR(anon_unknown); - int lineno = _PyInterpreterFrame_GetLine(pyframe); - if (lineno < 0) { - lineno = 0; - } - frame->lineno = (unsigned int)lineno; - - PyObject *filename = pyframe->f_code->co_filename; - - if (filename == NULL) { -#ifdef TRACE_DEBUG - tracemalloc_error("failed to get the filename of the code object"); -#endif - return; - } - - if (!PyUnicode_Check(filename)) { -#ifdef TRACE_DEBUG - tracemalloc_error("filename is not a unicode string"); -#endif - return; - } - if (!PyUnicode_IS_READY(filename)) { - /* Don't make a Unicode string ready to avoid reentrant calls - to tracemalloc_malloc() or tracemalloc_realloc() */ -#ifdef TRACE_DEBUG - tracemalloc_error("filename is not a ready unicode string"); -#endif - return; - } - - /* intern the filename */ - _Py_hashtable_entry_t *entry; - entry = _Py_hashtable_get_entry(tracemalloc_filenames, filename); - if (entry != NULL) { - filename = (PyObject *)entry->key; - } - else { - /* tracemalloc_filenames is responsible to keep a reference - to the filename */ - Py_INCREF(filename); - if (_Py_hashtable_set(tracemalloc_filenames, filename, NULL) < 0) { - Py_DECREF(filename); -#ifdef TRACE_DEBUG - tracemalloc_error("failed to intern the filename"); -#endif - return; - } - } - - /* the tracemalloc_filenames table keeps a reference to the filename */ - frame->filename = filename; -} - - -static Py_uhash_t -traceback_hash(traceback_t *traceback) -{ - /* code based on tuplehash() of Objects/tupleobject.c */ - Py_uhash_t x, y; /* Unsigned for defined overflow behavior. */ - int len = traceback->nframe; - Py_uhash_t mult = _PyHASH_MULTIPLIER; - frame_t *frame; - - x = 0x345678UL; - frame = traceback->frames; - while (--len >= 0) { - y = (Py_uhash_t)PyObject_Hash(frame->filename); - y ^= (Py_uhash_t)frame->lineno; - frame++; - - x = (x ^ y) * mult; - /* the cast might truncate len; that doesn't change hash stability */ - mult += (Py_uhash_t)(82520UL + len + len); - } - x ^= traceback->total_nframe; - x += 97531UL; - return x; -} - - -static void -traceback_get_frames(traceback_t *traceback) -{ - PyThreadState *tstate = PyGILState_GetThisThreadState(); - if (tstate == NULL) { -#ifdef TRACE_DEBUG - tracemalloc_error("failed to get the current thread state"); -#endif - return; - } - - _PyInterpreterFrame *pyframe = tstate->cframe->current_frame; - for (;;) { - while (pyframe && _PyFrame_IsIncomplete(pyframe)) { - pyframe = pyframe->previous; - } - if (pyframe == NULL) { - break; - } - if (traceback->nframe < _Py_tracemalloc_config.max_nframe) { - tracemalloc_get_frame(pyframe, &traceback->frames[traceback->nframe]); - assert(traceback->frames[traceback->nframe].filename != NULL); - traceback->nframe++; - } - if (traceback->total_nframe < UINT16_MAX) { - traceback->total_nframe++; - } - - pyframe = pyframe->previous; - } -} - - -static traceback_t * -traceback_new(void) -{ - traceback_t *traceback; - _Py_hashtable_entry_t *entry; - - assert(PyGILState_Check()); - - /* get frames */ - traceback = tracemalloc_traceback; - traceback->nframe = 0; - traceback->total_nframe = 0; - traceback_get_frames(traceback); - if (traceback->nframe == 0) - return &tracemalloc_empty_traceback; - traceback->hash = traceback_hash(traceback); - - /* intern the traceback */ - entry = _Py_hashtable_get_entry(tracemalloc_tracebacks, traceback); - if (entry != NULL) { - traceback = (traceback_t *)entry->key; - } - else { - traceback_t *copy; - size_t traceback_size; - - traceback_size = TRACEBACK_SIZE(traceback->nframe); - - copy = raw_malloc(traceback_size); - if (copy == NULL) { -#ifdef TRACE_DEBUG - tracemalloc_error("failed to intern the traceback: malloc failed"); -#endif - return NULL; - } - memcpy(copy, traceback, traceback_size); - - if (_Py_hashtable_set(tracemalloc_tracebacks, copy, NULL) < 0) { - raw_free(copy); -#ifdef TRACE_DEBUG - tracemalloc_error("failed to intern the traceback: putdata failed"); -#endif - return NULL; - } - traceback = copy; - } - return traceback; -} - - -static _Py_hashtable_t* -tracemalloc_create_traces_table(void) -{ - return hashtable_new(_Py_hashtable_hash_ptr, - _Py_hashtable_compare_direct, - NULL, raw_free); -} - - -static _Py_hashtable_t* -tracemalloc_create_domains_table(void) -{ - return hashtable_new(hashtable_hash_uint, - _Py_hashtable_compare_direct, - NULL, - (_Py_hashtable_destroy_func)_Py_hashtable_destroy); -} - - -static _Py_hashtable_t* -tracemalloc_get_traces_table(unsigned int domain) -{ - if (domain == DEFAULT_DOMAIN) { - return tracemalloc_traces; - } - else { - return _Py_hashtable_get(tracemalloc_domains, TO_PTR(domain)); - } -} - - -static void -tracemalloc_remove_trace(unsigned int domain, uintptr_t ptr) -{ - assert(_Py_tracemalloc_config.tracing); - - _Py_hashtable_t *traces = tracemalloc_get_traces_table(domain); - if (!traces) { - return; - } - - trace_t *trace = _Py_hashtable_steal(traces, TO_PTR(ptr)); - if (!trace) { - return; - } - assert(tracemalloc_traced_memory >= trace->size); - tracemalloc_traced_memory -= trace->size; - raw_free(trace); -} - -#define REMOVE_TRACE(ptr) \ - tracemalloc_remove_trace(DEFAULT_DOMAIN, (uintptr_t)(ptr)) - - -static int -tracemalloc_add_trace(unsigned int domain, uintptr_t ptr, - size_t size) -{ - assert(_Py_tracemalloc_config.tracing); - - traceback_t *traceback = traceback_new(); - if (traceback == NULL) { - return -1; - } - - _Py_hashtable_t *traces = tracemalloc_get_traces_table(domain); - if (traces == NULL) { - traces = tracemalloc_create_traces_table(); - if (traces == NULL) { - return -1; - } - - if (_Py_hashtable_set(tracemalloc_domains, TO_PTR(domain), traces) < 0) { - _Py_hashtable_destroy(traces); - return -1; - } - } - - trace_t *trace = _Py_hashtable_get(traces, TO_PTR(ptr)); - if (trace != NULL) { - /* the memory block is already tracked */ - assert(tracemalloc_traced_memory >= trace->size); - tracemalloc_traced_memory -= trace->size; - - trace->size = size; - trace->traceback = traceback; - } - else { - trace = raw_malloc(sizeof(trace_t)); - if (trace == NULL) { - return -1; - } - trace->size = size; - trace->traceback = traceback; - - int res = _Py_hashtable_set(traces, TO_PTR(ptr), trace); - if (res != 0) { - raw_free(trace); - return res; - } - } - - assert(tracemalloc_traced_memory <= SIZE_MAX - size); - tracemalloc_traced_memory += size; - if (tracemalloc_traced_memory > tracemalloc_peak_traced_memory) { - tracemalloc_peak_traced_memory = tracemalloc_traced_memory; - } - return 0; -} - -#define ADD_TRACE(ptr, size) \ - tracemalloc_add_trace(DEFAULT_DOMAIN, (uintptr_t)(ptr), size) - - -static void* -tracemalloc_alloc(int use_calloc, void *ctx, size_t nelem, size_t elsize) -{ - PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx; - void *ptr; - - assert(elsize == 0 || nelem <= SIZE_MAX / elsize); - - if (use_calloc) - ptr = alloc->calloc(alloc->ctx, nelem, elsize); - else - ptr = alloc->malloc(alloc->ctx, nelem * elsize); - if (ptr == NULL) - return NULL; - - TABLES_LOCK(); - if (ADD_TRACE(ptr, nelem * elsize) < 0) { - /* Failed to allocate a trace for the new memory block */ - TABLES_UNLOCK(); - alloc->free(alloc->ctx, ptr); - return NULL; - } - TABLES_UNLOCK(); - return ptr; -} - - -static void* -tracemalloc_realloc(void *ctx, void *ptr, size_t new_size) -{ - PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx; - void *ptr2; - - ptr2 = alloc->realloc(alloc->ctx, ptr, new_size); - if (ptr2 == NULL) - return NULL; - - if (ptr != NULL) { - /* an existing memory block has been resized */ - - TABLES_LOCK(); - - /* tracemalloc_add_trace() updates the trace if there is already - a trace at address ptr2 */ - if (ptr2 != ptr) { - REMOVE_TRACE(ptr); - } - - if (ADD_TRACE(ptr2, new_size) < 0) { - /* Memory allocation failed. The error cannot be reported to - the caller, because realloc() may already have shrunk the - memory block and so removed bytes. - - This case is very unlikely: a hash entry has just been - released, so the hash table should have at least one free entry. - - The GIL and the table lock ensures that only one thread is - allocating memory. */ - Py_FatalError("tracemalloc_realloc() failed to allocate a trace"); - } - TABLES_UNLOCK(); - } - else { - /* new allocation */ - - TABLES_LOCK(); - if (ADD_TRACE(ptr2, new_size) < 0) { - /* Failed to allocate a trace for the new memory block */ - TABLES_UNLOCK(); - alloc->free(alloc->ctx, ptr2); - return NULL; - } - TABLES_UNLOCK(); - } - return ptr2; -} - - -static void -tracemalloc_free(void *ctx, void *ptr) -{ - PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx; - - if (ptr == NULL) - return; - - /* GIL cannot be locked in PyMem_RawFree() because it would introduce - a deadlock in _PyThreadState_DeleteCurrent(). */ - - alloc->free(alloc->ctx, ptr); - - TABLES_LOCK(); - REMOVE_TRACE(ptr); - TABLES_UNLOCK(); -} - - -static void* -tracemalloc_alloc_gil(int use_calloc, void *ctx, size_t nelem, size_t elsize) -{ - void *ptr; - - if (get_reentrant()) { - PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx; - if (use_calloc) - return alloc->calloc(alloc->ctx, nelem, elsize); - else - return alloc->malloc(alloc->ctx, nelem * elsize); - } - - /* Ignore reentrant call. PyObjet_Malloc() calls PyMem_Malloc() for - allocations larger than 512 bytes, don't trace the same memory - allocation twice. */ - set_reentrant(1); - - ptr = tracemalloc_alloc(use_calloc, ctx, nelem, elsize); - - set_reentrant(0); - return ptr; -} - - -static void* -tracemalloc_malloc_gil(void *ctx, size_t size) -{ - return tracemalloc_alloc_gil(0, ctx, 1, size); -} - - -static void* -tracemalloc_calloc_gil(void *ctx, size_t nelem, size_t elsize) -{ - return tracemalloc_alloc_gil(1, ctx, nelem, elsize); -} - - -static void* -tracemalloc_realloc_gil(void *ctx, void *ptr, size_t new_size) -{ - void *ptr2; - - if (get_reentrant()) { - /* Reentrant call to PyMem_Realloc() and PyMem_RawRealloc(). - Example: PyMem_RawRealloc() is called internally by pymalloc - (_PyObject_Malloc() and _PyObject_Realloc()) to allocate a new - arena (new_arena()). */ - PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx; - - ptr2 = alloc->realloc(alloc->ctx, ptr, new_size); - if (ptr2 != NULL && ptr != NULL) { - TABLES_LOCK(); - REMOVE_TRACE(ptr); - TABLES_UNLOCK(); - } - return ptr2; - } - - /* Ignore reentrant call. PyObjet_Realloc() calls PyMem_Realloc() for - allocations larger than 512 bytes. Don't trace the same memory - allocation twice. */ - set_reentrant(1); - - ptr2 = tracemalloc_realloc(ctx, ptr, new_size); - - set_reentrant(0); - return ptr2; -} - - -#ifdef TRACE_RAW_MALLOC -static void* -tracemalloc_raw_alloc(int use_calloc, void *ctx, size_t nelem, size_t elsize) -{ - PyGILState_STATE gil_state; - void *ptr; - - if (get_reentrant()) { - PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx; - if (use_calloc) - return alloc->calloc(alloc->ctx, nelem, elsize); - else - return alloc->malloc(alloc->ctx, nelem * elsize); - } - - /* Ignore reentrant call. PyGILState_Ensure() may call PyMem_RawMalloc() - indirectly which would call PyGILState_Ensure() if reentrant are not - disabled. */ - set_reentrant(1); - - gil_state = PyGILState_Ensure(); - ptr = tracemalloc_alloc(use_calloc, ctx, nelem, elsize); - PyGILState_Release(gil_state); - - set_reentrant(0); - return ptr; -} - - -static void* -tracemalloc_raw_malloc(void *ctx, size_t size) -{ - return tracemalloc_raw_alloc(0, ctx, 1, size); -} - - -static void* -tracemalloc_raw_calloc(void *ctx, size_t nelem, size_t elsize) -{ - return tracemalloc_raw_alloc(1, ctx, nelem, elsize); -} - - -static void* -tracemalloc_raw_realloc(void *ctx, void *ptr, size_t new_size) -{ - PyGILState_STATE gil_state; - void *ptr2; - - if (get_reentrant()) { - /* Reentrant call to PyMem_RawRealloc(). */ - PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx; - - ptr2 = alloc->realloc(alloc->ctx, ptr, new_size); - - if (ptr2 != NULL && ptr != NULL) { - TABLES_LOCK(); - REMOVE_TRACE(ptr); - TABLES_UNLOCK(); - } - return ptr2; - } - - /* Ignore reentrant call. PyGILState_Ensure() may call PyMem_RawMalloc() - indirectly which would call PyGILState_Ensure() if reentrant calls are - not disabled. */ - set_reentrant(1); - - gil_state = PyGILState_Ensure(); - ptr2 = tracemalloc_realloc(ctx, ptr, new_size); - PyGILState_Release(gil_state); - - set_reentrant(0); - return ptr2; -} -#endif /* TRACE_RAW_MALLOC */ - - -static void -tracemalloc_clear_filename(void *value) -{ - PyObject *filename = (PyObject *)value; - Py_DECREF(filename); -} - - -/* reentrant flag must be set to call this function and GIL must be held */ -static void -tracemalloc_clear_traces(void) -{ - /* The GIL protects variables against concurrent access */ - assert(PyGILState_Check()); - - TABLES_LOCK(); - _Py_hashtable_clear(tracemalloc_traces); - _Py_hashtable_clear(tracemalloc_domains); - tracemalloc_traced_memory = 0; - tracemalloc_peak_traced_memory = 0; - TABLES_UNLOCK(); - - _Py_hashtable_clear(tracemalloc_tracebacks); - - _Py_hashtable_clear(tracemalloc_filenames); -} - - -static int -tracemalloc_init(void) -{ - if (_Py_tracemalloc_config.initialized == TRACEMALLOC_FINALIZED) { - PyErr_SetString(PyExc_RuntimeError, - "the tracemalloc module has been unloaded"); - return -1; - } - - if (_Py_tracemalloc_config.initialized == TRACEMALLOC_INITIALIZED) - return 0; - - PyMem_GetAllocator(PYMEM_DOMAIN_RAW, &allocators.raw); - -#ifdef REENTRANT_THREADLOCAL - if (PyThread_tss_create(&tracemalloc_reentrant_key) != 0) { -#ifdef MS_WINDOWS - PyErr_SetFromWindowsErr(0); -#else - PyErr_SetFromErrno(PyExc_OSError); -#endif - return -1; - } -#endif - -#if defined(TRACE_RAW_MALLOC) - if (tables_lock == NULL) { - tables_lock = PyThread_allocate_lock(); - if (tables_lock == NULL) { - PyErr_SetString(PyExc_RuntimeError, "cannot allocate lock"); - return -1; - } - } -#endif - - tracemalloc_filenames = hashtable_new(hashtable_hash_pyobject, - hashtable_compare_unicode, - tracemalloc_clear_filename, NULL); - - tracemalloc_tracebacks = hashtable_new(hashtable_hash_traceback, - hashtable_compare_traceback, - NULL, raw_free); - - tracemalloc_traces = tracemalloc_create_traces_table(); - tracemalloc_domains = tracemalloc_create_domains_table(); - - if (tracemalloc_filenames == NULL || tracemalloc_tracebacks == NULL - || tracemalloc_traces == NULL || tracemalloc_domains == NULL) { - PyErr_NoMemory(); - return -1; - } - - tracemalloc_empty_traceback.nframe = 1; - tracemalloc_empty_traceback.total_nframe = 1; - /* borrowed reference */ - tracemalloc_empty_traceback.frames[0].filename = &_Py_STR(anon_unknown); - tracemalloc_empty_traceback.frames[0].lineno = 0; - tracemalloc_empty_traceback.hash = traceback_hash(&tracemalloc_empty_traceback); - - _Py_tracemalloc_config.initialized = TRACEMALLOC_INITIALIZED; - return 0; -} - - -static void -tracemalloc_deinit(void) -{ - if (_Py_tracemalloc_config.initialized != TRACEMALLOC_INITIALIZED) - return; - _Py_tracemalloc_config.initialized = TRACEMALLOC_FINALIZED; - - tracemalloc_stop(); - - /* destroy hash tables */ - _Py_hashtable_destroy(tracemalloc_domains); - _Py_hashtable_destroy(tracemalloc_traces); - _Py_hashtable_destroy(tracemalloc_tracebacks); - _Py_hashtable_destroy(tracemalloc_filenames); - -#if defined(TRACE_RAW_MALLOC) - if (tables_lock != NULL) { - PyThread_free_lock(tables_lock); - tables_lock = NULL; - } -#endif - -#ifdef REENTRANT_THREADLOCAL - PyThread_tss_delete(&tracemalloc_reentrant_key); -#endif -} - - -static int -tracemalloc_start(int max_nframe) -{ - PyMemAllocatorEx alloc; - size_t size; - - if (max_nframe < 1 || (unsigned long) max_nframe > MAX_NFRAME) { - PyErr_Format(PyExc_ValueError, - "the number of frames must be in range [1; %lu]", - MAX_NFRAME); - return -1; - } - - if (tracemalloc_init() < 0) { - return -1; - } - - if (_Py_tracemalloc_config.tracing) { - /* hook already installed: do nothing */ - return 0; - } - - _Py_tracemalloc_config.max_nframe = max_nframe; - - /* allocate a buffer to store a new traceback */ - size = TRACEBACK_SIZE(max_nframe); - assert(tracemalloc_traceback == NULL); - tracemalloc_traceback = raw_malloc(size); - if (tracemalloc_traceback == NULL) { - PyErr_NoMemory(); - return -1; - } - -#ifdef TRACE_RAW_MALLOC - alloc.malloc = tracemalloc_raw_malloc; - alloc.calloc = tracemalloc_raw_calloc; - alloc.realloc = tracemalloc_raw_realloc; - alloc.free = tracemalloc_free; - - alloc.ctx = &allocators.raw; - PyMem_GetAllocator(PYMEM_DOMAIN_RAW, &allocators.raw); - PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &alloc); -#endif - - alloc.malloc = tracemalloc_malloc_gil; - alloc.calloc = tracemalloc_calloc_gil; - alloc.realloc = tracemalloc_realloc_gil; - alloc.free = tracemalloc_free; - - alloc.ctx = &allocators.mem; - PyMem_GetAllocator(PYMEM_DOMAIN_MEM, &allocators.mem); - PyMem_SetAllocator(PYMEM_DOMAIN_MEM, &alloc); - - alloc.ctx = &allocators.obj; - PyMem_GetAllocator(PYMEM_DOMAIN_OBJ, &allocators.obj); - PyMem_SetAllocator(PYMEM_DOMAIN_OBJ, &alloc); - - /* everything is ready: start tracing Python memory allocations */ - _Py_tracemalloc_config.tracing = 1; - - return 0; -} - - -static void -tracemalloc_stop(void) -{ - if (!_Py_tracemalloc_config.tracing) - return; - - /* stop tracing Python memory allocations */ - _Py_tracemalloc_config.tracing = 0; - - /* unregister the hook on memory allocators */ -#ifdef TRACE_RAW_MALLOC - PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &allocators.raw); -#endif - PyMem_SetAllocator(PYMEM_DOMAIN_MEM, &allocators.mem); - PyMem_SetAllocator(PYMEM_DOMAIN_OBJ, &allocators.obj); - - tracemalloc_clear_traces(); +#include "clinic/_tracemalloc.c.h" - /* release memory */ - raw_free(tracemalloc_traceback); - tracemalloc_traceback = NULL; -} +/*[clinic input] +module _tracemalloc +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=708a98302fc46e5f]*/ /*[clinic input] @@ -1051,7 +19,7 @@ static PyObject * _tracemalloc_is_tracing_impl(PyObject *module) /*[clinic end generated code: output=2d763b42601cd3ef input=af104b0a00192f63]*/ { - return PyBool_FromLong(_Py_tracemalloc_config.tracing); + return PyBool_FromLong(_PyTraceMalloc_IsTracing()); } @@ -1065,264 +33,11 @@ static PyObject * _tracemalloc_clear_traces_impl(PyObject *module) /*[clinic end generated code: output=a86080ee41b84197 input=0dab5b6c785183a5]*/ { - if (!_Py_tracemalloc_config.tracing) - Py_RETURN_NONE; - - set_reentrant(1); - tracemalloc_clear_traces(); - set_reentrant(0); - + _PyTraceMalloc_ClearTraces(); Py_RETURN_NONE; } -static PyObject* -frame_to_pyobject(frame_t *frame) -{ - PyObject *frame_obj, *lineno_obj; - - frame_obj = PyTuple_New(2); - if (frame_obj == NULL) - return NULL; - - Py_INCREF(frame->filename); - PyTuple_SET_ITEM(frame_obj, 0, frame->filename); - - lineno_obj = PyLong_FromUnsignedLong(frame->lineno); - if (lineno_obj == NULL) { - Py_DECREF(frame_obj); - return NULL; - } - PyTuple_SET_ITEM(frame_obj, 1, lineno_obj); - - return frame_obj; -} - - -static PyObject* -traceback_to_pyobject(traceback_t *traceback, _Py_hashtable_t *intern_table) -{ - PyObject *frames; - - if (intern_table != NULL) { - frames = _Py_hashtable_get(intern_table, (const void *)traceback); - if (frames) { - Py_INCREF(frames); - return frames; - } - } - - frames = PyTuple_New(traceback->nframe); - if (frames == NULL) - return NULL; - - for (int i=0; i < traceback->nframe; i++) { - PyObject *frame = frame_to_pyobject(&traceback->frames[i]); - if (frame == NULL) { - Py_DECREF(frames); - return NULL; - } - PyTuple_SET_ITEM(frames, i, frame); - } - - if (intern_table != NULL) { - if (_Py_hashtable_set(intern_table, traceback, frames) < 0) { - Py_DECREF(frames); - PyErr_NoMemory(); - return NULL; - } - /* intern_table keeps a new reference to frames */ - Py_INCREF(frames); - } - return frames; -} - - -static PyObject* -trace_to_pyobject(unsigned int domain, const trace_t *trace, - _Py_hashtable_t *intern_tracebacks) -{ - PyObject *trace_obj = NULL; - PyObject *obj; - - trace_obj = PyTuple_New(4); - if (trace_obj == NULL) - return NULL; - - obj = PyLong_FromSize_t(domain); - if (obj == NULL) { - Py_DECREF(trace_obj); - return NULL; - } - PyTuple_SET_ITEM(trace_obj, 0, obj); - - obj = PyLong_FromSize_t(trace->size); - if (obj == NULL) { - Py_DECREF(trace_obj); - return NULL; - } - PyTuple_SET_ITEM(trace_obj, 1, obj); - - obj = traceback_to_pyobject(trace->traceback, intern_tracebacks); - if (obj == NULL) { - Py_DECREF(trace_obj); - return NULL; - } - PyTuple_SET_ITEM(trace_obj, 2, obj); - - obj = PyLong_FromUnsignedLong(trace->traceback->total_nframe); - if (obj == NULL) { - Py_DECREF(trace_obj); - return NULL; - } - PyTuple_SET_ITEM(trace_obj, 3, obj); - - return trace_obj; -} - - -typedef struct { - _Py_hashtable_t *traces; - _Py_hashtable_t *domains; - _Py_hashtable_t *tracebacks; - PyObject *list; - unsigned int domain; -} get_traces_t; - - -static int -tracemalloc_copy_trace(_Py_hashtable_t *traces, - const void *key, const void *value, - void *user_data) -{ - _Py_hashtable_t *traces2 = (_Py_hashtable_t *)user_data; - - trace_t *trace = (trace_t *)value; - - trace_t *trace2 = raw_malloc(sizeof(trace_t)); - if (trace2 == NULL) { - return -1; - } - *trace2 = *trace; - if (_Py_hashtable_set(traces2, key, trace2) < 0) { - raw_free(trace2); - return -1; - } - return 0; -} - - -static _Py_hashtable_t* -tracemalloc_copy_traces(_Py_hashtable_t *traces) -{ - _Py_hashtable_t *traces2 = tracemalloc_create_traces_table(); - if (traces2 == NULL) { - return NULL; - } - - int err = _Py_hashtable_foreach(traces, - tracemalloc_copy_trace, - traces2); - if (err) { - _Py_hashtable_destroy(traces2); - return NULL; - } - return traces2; -} - - -static int -tracemalloc_copy_domain(_Py_hashtable_t *domains, - const void *key, const void *value, - void *user_data) -{ - _Py_hashtable_t *domains2 = (_Py_hashtable_t *)user_data; - - unsigned int domain = (unsigned int)FROM_PTR(key); - _Py_hashtable_t *traces = (_Py_hashtable_t *)value; - - _Py_hashtable_t *traces2 = tracemalloc_copy_traces(traces); - if (traces2 == NULL) { - return -1; - } - if (_Py_hashtable_set(domains2, TO_PTR(domain), traces2) < 0) { - _Py_hashtable_destroy(traces2); - return -1; - } - return 0; -} - - -static _Py_hashtable_t* -tracemalloc_copy_domains(_Py_hashtable_t *domains) -{ - _Py_hashtable_t *domains2 = tracemalloc_create_domains_table(); - if (domains2 == NULL) { - return NULL; - } - - int err = _Py_hashtable_foreach(domains, - tracemalloc_copy_domain, - domains2); - if (err) { - _Py_hashtable_destroy(domains2); - return NULL; - } - return domains2; -} - - -static int -tracemalloc_get_traces_fill(_Py_hashtable_t *traces, - const void *key, const void *value, - void *user_data) -{ - get_traces_t *get_traces = user_data; - - const trace_t *trace = (const trace_t *)value; - - PyObject *tuple = trace_to_pyobject(get_traces->domain, trace, - get_traces->tracebacks); - if (tuple == NULL) { - return 1; - } - - int res = PyList_Append(get_traces->list, tuple); - Py_DECREF(tuple); - if (res < 0) { - return 1; - } - - return 0; -} - - -static int -tracemalloc_get_traces_domain(_Py_hashtable_t *domains, - const void *key, const void *value, - void *user_data) -{ - get_traces_t *get_traces = user_data; - - unsigned int domain = (unsigned int)FROM_PTR(key); - _Py_hashtable_t *traces = (_Py_hashtable_t *)value; - - get_traces->domain = domain; - return _Py_hashtable_foreach(traces, - tracemalloc_get_traces_fill, - get_traces); -} - - -static void -tracemalloc_pyobject_decref(void *value) -{ - PyObject *obj = (PyObject *)value; - Py_DECREF(obj); -} - - - /*[clinic input] _tracemalloc._get_traces @@ -1338,107 +53,7 @@ static PyObject * _tracemalloc__get_traces_impl(PyObject *module) /*[clinic end generated code: output=e9929876ced4b5cc input=6c7d2230b24255aa]*/ { - get_traces_t get_traces; - get_traces.domain = DEFAULT_DOMAIN; - get_traces.traces = NULL; - get_traces.domains = NULL; - get_traces.tracebacks = NULL; - get_traces.list = PyList_New(0); - if (get_traces.list == NULL) - goto error; - - if (!_Py_tracemalloc_config.tracing) - return get_traces.list; - - /* the traceback hash table is used temporarily to intern traceback tuple - of (filename, lineno) tuples */ - get_traces.tracebacks = hashtable_new(_Py_hashtable_hash_ptr, - _Py_hashtable_compare_direct, - NULL, tracemalloc_pyobject_decref); - if (get_traces.tracebacks == NULL) { - goto no_memory; - } - - // Copy all traces so tracemalloc_get_traces_fill() doesn't have to disable - // temporarily tracemalloc which would impact other threads and so would - // miss allocations while get_traces() is called. - TABLES_LOCK(); - get_traces.traces = tracemalloc_copy_traces(tracemalloc_traces); - TABLES_UNLOCK(); - - if (get_traces.traces == NULL) { - goto no_memory; - } - - TABLES_LOCK(); - get_traces.domains = tracemalloc_copy_domains(tracemalloc_domains); - TABLES_UNLOCK(); - - if (get_traces.domains == NULL) { - goto no_memory; - } - - // Convert traces to a list of tuples - set_reentrant(1); - int err = _Py_hashtable_foreach(get_traces.traces, - tracemalloc_get_traces_fill, - &get_traces); - if (!err) { - err = _Py_hashtable_foreach(get_traces.domains, - tracemalloc_get_traces_domain, - &get_traces); - } - set_reentrant(0); - if (err) { - goto error; - } - - goto finally; - -no_memory: - PyErr_NoMemory(); - -error: - Py_CLEAR(get_traces.list); - -finally: - if (get_traces.tracebacks != NULL) { - _Py_hashtable_destroy(get_traces.tracebacks); - } - if (get_traces.traces != NULL) { - _Py_hashtable_destroy(get_traces.traces); - } - if (get_traces.domains != NULL) { - _Py_hashtable_destroy(get_traces.domains); - } - - return get_traces.list; -} - - -static traceback_t* -tracemalloc_get_traceback(unsigned int domain, uintptr_t ptr) -{ - - if (!_Py_tracemalloc_config.tracing) - return NULL; - - trace_t *trace; - TABLES_LOCK(); - _Py_hashtable_t *traces = tracemalloc_get_traces_table(domain); - if (traces) { - trace = _Py_hashtable_get(traces, TO_PTR(ptr)); - } - else { - trace = NULL; - } - TABLES_UNLOCK(); - - if (!trace) { - return NULL; - } - - return trace->traceback; + return _PyTraceMalloc_GetTraces(); } @@ -1460,66 +75,9 @@ static PyObject * _tracemalloc__get_object_traceback(PyObject *module, PyObject *obj) /*[clinic end generated code: output=41ee0553a658b0aa input=29495f1b21c53212]*/ { - PyTypeObject *type; - void *ptr; - traceback_t *traceback; - - type = Py_TYPE(obj); - if (PyType_IS_GC(type)) { - ptr = (void *)((char *)obj - sizeof(PyGC_Head)); - } - else { - ptr = (void *)obj; - } - - traceback = tracemalloc_get_traceback(DEFAULT_DOMAIN, (uintptr_t)ptr); - if (traceback == NULL) - Py_RETURN_NONE; - - return traceback_to_pyobject(traceback, NULL); -} - - -#define PUTS(fd, str) _Py_write_noraise(fd, str, (int)strlen(str)) - -static void -_PyMem_DumpFrame(int fd, frame_t * frame) -{ - PUTS(fd, " File \""); - _Py_DumpASCII(fd, frame->filename); - PUTS(fd, "\", line "); - _Py_DumpDecimal(fd, frame->lineno); - PUTS(fd, "\n"); -} - -/* Dump the traceback where a memory block was allocated into file descriptor - fd. The function may block on TABLES_LOCK() but it is unlikely. */ -void -_PyMem_DumpTraceback(int fd, const void *ptr) -{ - traceback_t *traceback; - int i; - - if (!_Py_tracemalloc_config.tracing) { - PUTS(fd, "Enable tracemalloc to get the memory block " - "allocation traceback\n\n"); - return; - } - - traceback = tracemalloc_get_traceback(DEFAULT_DOMAIN, (uintptr_t)ptr); - if (traceback == NULL) - return; - - PUTS(fd, "Memory block allocated at (most recent call first):\n"); - for (i=0; i < traceback->nframe; i++) { - _PyMem_DumpFrame(fd, &traceback->frames[i]); - } - PUTS(fd, "\n"); + return _PyTraceMalloc_GetObjectTraceback(obj); } -#undef PUTS - - /*[clinic input] _tracemalloc.start @@ -1537,7 +95,7 @@ static PyObject * _tracemalloc_start_impl(PyObject *module, int nframe) /*[clinic end generated code: output=caae05c23c159d3c input=40d849b5b29d1933]*/ { - if (tracemalloc_start(nframe) < 0) { + if (_PyTraceMalloc_Start(nframe) < 0) { return NULL; } Py_RETURN_NONE; @@ -1556,7 +114,7 @@ static PyObject * _tracemalloc_stop_impl(PyObject *module) /*[clinic end generated code: output=c3c42ae03e3955cd input=7478f075e51dae18]*/ { - tracemalloc_stop(); + _PyTraceMalloc_Stop(); Py_RETURN_NONE; } @@ -1574,22 +132,9 @@ static PyObject * _tracemalloc_get_traceback_limit_impl(PyObject *module) /*[clinic end generated code: output=d556d9306ba95567 input=da3cd977fc68ae3b]*/ { - return PyLong_FromLong(_Py_tracemalloc_config.max_nframe); -} - - -static int -tracemalloc_get_tracemalloc_memory_cb(_Py_hashtable_t *domains, - const void *key, const void *value, - void *user_data) -{ - const _Py_hashtable_t *traces = value; - size_t *size = (size_t*)user_data; - *size += _Py_hashtable_size(traces); - return 0; + return PyLong_FromLong(_PyTraceMalloc_GetTracebackLimit()); } - /*[clinic input] _tracemalloc.get_tracemalloc_memory @@ -1602,22 +147,10 @@ static PyObject * _tracemalloc_get_tracemalloc_memory_impl(PyObject *module) /*[clinic end generated code: output=e3f14e280a55f5aa input=5d919c0f4d5132ad]*/ { - size_t size; - - size = _Py_hashtable_size(tracemalloc_tracebacks); - size += _Py_hashtable_size(tracemalloc_filenames); - - TABLES_LOCK(); - size += _Py_hashtable_size(tracemalloc_traces); - _Py_hashtable_foreach(tracemalloc_domains, - tracemalloc_get_tracemalloc_memory_cb, &size); - TABLES_UNLOCK(); - - return PyLong_FromSize_t(size); + return PyLong_FromSize_t(_PyTraceMalloc_GetMemory()); } - /*[clinic input] _tracemalloc.get_traced_memory @@ -1630,17 +163,7 @@ static PyObject * _tracemalloc_get_traced_memory_impl(PyObject *module) /*[clinic end generated code: output=5b167189adb9e782 input=61ddb5478400ff66]*/ { - Py_ssize_t size, peak_size; - - if (!_Py_tracemalloc_config.tracing) - return Py_BuildValue("ii", 0, 0); - - TABLES_LOCK(); - size = tracemalloc_traced_memory; - peak_size = tracemalloc_peak_traced_memory; - TABLES_UNLOCK(); - - return Py_BuildValue("nn", size, peak_size); + return _PyTraceMalloc_GetTracedMemory(); } /*[clinic input] @@ -1656,14 +179,7 @@ static PyObject * _tracemalloc_reset_peak_impl(PyObject *module) /*[clinic end generated code: output=140c2870f691dbb2 input=18afd0635066e9ce]*/ { - if (!_Py_tracemalloc_config.tracing) { - Py_RETURN_NONE; - } - - TABLES_LOCK(); - tracemalloc_peak_traced_memory = tracemalloc_traced_memory; - TABLES_UNLOCK(); - + _PyTraceMalloc_ResetPeak(); Py_RETURN_NONE; } @@ -1703,123 +219,10 @@ PyInit__tracemalloc(void) if (m == NULL) return NULL; - if (tracemalloc_init() < 0) { + if (_PyTraceMalloc_Init() < 0) { Py_DECREF(m); return NULL; } return m; } - - -int -_PyTraceMalloc_Init(int nframe) -{ - assert(PyGILState_Check()); - if (nframe == 0) { - return 0; - } - return tracemalloc_start(nframe); -} - - -void -_PyTraceMalloc_Fini(void) -{ - assert(PyGILState_Check()); - tracemalloc_deinit(); -} - -int -PyTraceMalloc_Track(unsigned int domain, uintptr_t ptr, - size_t size) -{ - int res; - PyGILState_STATE gil_state; - - if (!_Py_tracemalloc_config.tracing) { - /* tracemalloc is not tracing: do nothing */ - return -2; - } - - gil_state = PyGILState_Ensure(); - - TABLES_LOCK(); - res = tracemalloc_add_trace(domain, ptr, size); - TABLES_UNLOCK(); - - PyGILState_Release(gil_state); - return res; -} - - -int -PyTraceMalloc_Untrack(unsigned int domain, uintptr_t ptr) -{ - if (!_Py_tracemalloc_config.tracing) { - /* tracemalloc is not tracing: do nothing */ - return -2; - } - - TABLES_LOCK(); - tracemalloc_remove_trace(domain, ptr); - TABLES_UNLOCK(); - - return 0; -} - - -/* If the object memory block is already traced, update its trace - with the current Python traceback. - - Do nothing if tracemalloc is not tracing memory allocations - or if the object memory block is not already traced. */ -int -_PyTraceMalloc_NewReference(PyObject *op) -{ - assert(PyGILState_Check()); - - if (!_Py_tracemalloc_config.tracing) { - /* tracemalloc is not tracing: do nothing */ - return -1; - } - - uintptr_t ptr; - PyTypeObject *type = Py_TYPE(op); - if (PyType_IS_GC(type)) { - ptr = (uintptr_t)((char *)op - sizeof(PyGC_Head)); - } - else { - ptr = (uintptr_t)op; - } - - int res = -1; - - TABLES_LOCK(); - trace_t *trace = _Py_hashtable_get(tracemalloc_traces, TO_PTR(ptr)); - if (trace != NULL) { - /* update the traceback of the memory block */ - traceback_t *traceback = traceback_new(); - if (traceback != NULL) { - trace->traceback = traceback; - res = 0; - } - } - /* else: cannot track the object, its memory block size is unknown */ - TABLES_UNLOCK(); - - return res; -} - - -PyObject* -_PyTraceMalloc_GetTraceback(unsigned int domain, uintptr_t ptr) -{ - traceback_t *traceback; - - traceback = tracemalloc_get_traceback(domain, ptr); - if (traceback == NULL) - Py_RETURN_NONE; - - return traceback_to_pyobject(traceback, NULL); -} diff --git a/Modules/_typingmodule.c b/Modules/_typingmodule.c index 8b6faa64..39a124a2 100644 --- a/Modules/_typingmodule.c +++ b/Modules/_typingmodule.c @@ -1,6 +1,12 @@ /* typing accelerator C extension: _typing module. */ +#ifndef Py_BUILD_CORE +#define Py_BUILD_CORE +#endif + #include "Python.h" +#include "internal/pycore_interp.h" +#include "internal/pycore_typevarobject.h" #include "clinic/_typingmodule.c.h" /*[clinic input] @@ -23,8 +29,7 @@ static PyObject * _typing__idfunc(PyObject *module, PyObject *x) /*[clinic end generated code: output=63c38be4a6ec5f2c input=49f17284b43de451]*/ { - Py_INCREF(x); - return x; + return Py_NewRef(x); } @@ -36,7 +41,33 @@ static PyMethodDef typing_methods[] = { PyDoc_STRVAR(typing_doc, "Accelerators for the typing module.\n"); +static int +_typing_exec(PyObject *m) +{ + PyInterpreterState *interp = PyInterpreterState_Get(); + +#define EXPORT_TYPE(name, typename) \ + if (PyModule_AddObjectRef(m, name, \ + (PyObject *)interp->cached_objects.typename) < 0) { \ + return -1; \ + } + + EXPORT_TYPE("TypeVar", typevar_type); + EXPORT_TYPE("TypeVarTuple", typevartuple_type); + EXPORT_TYPE("ParamSpec", paramspec_type); + EXPORT_TYPE("ParamSpecArgs", paramspecargs_type); + EXPORT_TYPE("ParamSpecKwargs", paramspeckwargs_type); + EXPORT_TYPE("Generic", generic_type); +#undef EXPORT_TYPE + if (PyModule_AddObjectRef(m, "TypeAliasType", (PyObject *)&_PyTypeAlias_Type) < 0) { + return -1; + } + return 0; +} + static struct PyModuleDef_Slot _typingmodule_slots[] = { + {Py_mod_exec, _typing_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; diff --git a/Modules/_uuidmodule.c b/Modules/_uuidmodule.c index eae38f5c..ed3b2fed 100644 --- a/Modules/_uuidmodule.c +++ b/Modules/_uuidmodule.c @@ -106,6 +106,7 @@ static PyMethodDef uuid_methods[] = { static PyModuleDef_Slot uuid_slots[] = { {Py_mod_exec, uuid_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; diff --git a/Modules/_weakref.c b/Modules/_weakref.c index 157a852a..387b8fa9 100644 --- a/Modules/_weakref.c +++ b/Modules/_weakref.c @@ -174,6 +174,7 @@ weakref_exec(PyObject *module) static struct PyModuleDef_Slot weakref_slots[] = { {Py_mod_exec, weakref_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; diff --git a/Modules/_winapi.c b/Modules/_winapi.c index f6bb07fd..77275408 100644 --- a/Modules/_winapi.c +++ b/Modules/_winapi.c @@ -39,8 +39,11 @@ #include "structmember.h" // PyMemberDef +#ifndef WINDOWS_LEAN_AND_MEAN #define WINDOWS_LEAN_AND_MEAN +#endif #include "windows.h" +#include <winioctl.h> #include <crtdbg.h> #include "winreparse.h" @@ -63,22 +66,13 @@ #define T_HANDLE T_POINTER -/* Grab CancelIoEx dynamically from kernel32 */ -static int has_CancelIoEx = -1; -static BOOL (CALLBACK *Py_CancelIoEx)(HANDLE, LPOVERLAPPED); - -static int -check_CancelIoEx() -{ - if (has_CancelIoEx == -1) - { - HINSTANCE hKernel32 = GetModuleHandle("KERNEL32"); - * (FARPROC *) &Py_CancelIoEx = GetProcAddress(hKernel32, - "CancelIoEx"); - has_CancelIoEx = (Py_CancelIoEx != NULL); - } - return has_CancelIoEx; -} +// winbase.h limits the STARTF_* flags to the desktop API as of 10.0.19041. +#ifndef STARTF_USESHOWWINDOW +#define STARTF_USESHOWWINDOW 0x00000001 +#endif +#ifndef STARTF_USESTDHANDLES +#define STARTF_USESTDHANDLES 0x00000100 +#endif typedef struct { PyTypeObject *overlapped_type; @@ -134,13 +128,12 @@ overlapped_dealloc(OverlappedObject *self) PyObject_GC_UnTrack(self); if (self->pending) { - if (check_CancelIoEx() && - Py_CancelIoEx(self->handle, &self->overlapped) && + if (CancelIoEx(self->handle, &self->overlapped) && GetOverlappedResult(self->handle, &self->overlapped, &bytes, TRUE)) { /* The operation is no longer pending -- nothing to do. */ } - else if (_Py_IsFinalizing()) + else if (_Py_IsInterpreterFinalizing(PyInterpreterState_Get())) { /* The operation is still pending -- give a warning. This will probably only happen on Windows XP. */ @@ -291,8 +284,7 @@ _winapi_Overlapped_getbuffer_impl(OverlappedObject *self) return NULL; } res = self->read_buffer ? self->read_buffer : Py_None; - Py_INCREF(res); - return res; + return Py_NewRef(res); } /*[clinic input] @@ -307,10 +299,7 @@ _winapi_Overlapped_cancel_impl(OverlappedObject *self) if (self->pending) { Py_BEGIN_ALLOW_THREADS - if (check_CancelIoEx()) - res = Py_CancelIoEx(self->handle, &self->overlapped); - else - res = CancelIo(self->handle); + res = CancelIoEx(self->handle, &self->overlapped); Py_END_ALLOW_THREADS } @@ -405,13 +394,13 @@ _winapi_CloseHandle_impl(PyObject *module, HANDLE handle) _winapi.ConnectNamedPipe handle: HANDLE - overlapped as use_overlapped: bool(accept={int}) = False + overlapped as use_overlapped: bool = False [clinic start generated code]*/ static PyObject * _winapi_ConnectNamedPipe_impl(PyObject *module, HANDLE handle, int use_overlapped) -/*[clinic end generated code: output=335a0e7086800671 input=34f937c1c86e5e68]*/ +/*[clinic end generated code: output=335a0e7086800671 input=a80e56e8bd370e31]*/ { BOOL success; OverlappedObject *overlapped = NULL; @@ -656,8 +645,10 @@ _winapi_CreateJunction_impl(PyObject *module, LPCWSTR src_path, cleanup: ret = GetLastError(); - CloseHandle(token); - CloseHandle(junction); + if (token != NULL) + CloseHandle(token); + if (junction != NULL) + CloseHandle(junction); PyMem_RawFree(rdb); if (ret != 0) @@ -805,6 +796,17 @@ getenvironment(PyObject* environment) } envsize = PyList_GET_SIZE(keys); + + if (envsize == 0) { + // A environment block must be terminated by two null characters -- + // one for the last string and one for the block. + buffer = PyMem_Calloc(2, sizeof(wchar_t)); + if (!buffer) { + PyErr_NoMemory(); + } + goto cleanup; + } + if (PyList_GET_SIZE(values) != envsize) { PyErr_SetString(PyExc_RuntimeError, "environment changed size during iteration"); @@ -878,7 +880,8 @@ getenvironment(PyObject* environment) *p++ = L'\0'; assert(p == end); - error: +cleanup: +error: Py_XDECREF(keys); Py_XDECREF(values); return buffer; @@ -1089,14 +1092,6 @@ _winapi_CreateProcess_impl(PyObject *module, return NULL; } - PyInterpreterState *interp = PyInterpreterState_Get(); - const PyConfig *config = _PyInterpreterState_GetConfig(interp); - if (config->_isolated_interpreter) { - PyErr_SetString(PyExc_RuntimeError, - "subprocess not supported for isolated subinterpreters"); - return NULL; - } - ZeroMemory(&si, sizeof(si)); si.StartupInfo.cb = sizeof(si); @@ -1229,8 +1224,10 @@ _winapi_ExitProcess_impl(PyObject *module, UINT ExitCode) /*[clinic end generated code: output=a387deb651175301 input=4f05466a9406c558]*/ { #if defined(Py_DEBUG) +#ifdef MS_WINDOWS_DESKTOP SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOALIGNMENTFAULTEXCEPT| SEM_NOGPFAULTERRORBOX|SEM_NOOPENFILEERRORBOX); +#endif _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG); #endif @@ -1539,66 +1536,58 @@ _winapi_PeekNamedPipe_impl(PyObject *module, HANDLE handle, int size) /*[clinic input] _winapi.LCMapStringEx - locale: unicode + locale: LPCWSTR flags: DWORD src: unicode [clinic start generated code]*/ static PyObject * -_winapi_LCMapStringEx_impl(PyObject *module, PyObject *locale, DWORD flags, +_winapi_LCMapStringEx_impl(PyObject *module, LPCWSTR locale, DWORD flags, PyObject *src) -/*[clinic end generated code: output=8ea4c9d85a4a1f23 input=2fa6ebc92591731b]*/ +/*[clinic end generated code: output=b90e6b26e028ff0a input=3e3dcd9b8164012f]*/ { if (flags & (LCMAP_SORTHANDLE | LCMAP_HASH | LCMAP_BYTEREV | LCMAP_SORTKEY)) { return PyErr_Format(PyExc_ValueError, "unsupported flags"); } - wchar_t *locale_ = PyUnicode_AsWideCharString(locale, NULL); - if (!locale_) { - return NULL; - } - Py_ssize_t srcLenAsSsize; - int srcLen; - wchar_t *src_ = PyUnicode_AsWideCharString(src, &srcLenAsSsize); + Py_ssize_t src_size; + wchar_t *src_ = PyUnicode_AsWideCharString(src, &src_size); if (!src_) { - PyMem_Free(locale_); return NULL; } - srcLen = (int)srcLenAsSsize; - if (srcLen != srcLenAsSsize) { - srcLen = -1; + if (src_size > INT_MAX) { + PyMem_Free(src_); + PyErr_SetString(PyExc_OverflowError, "input string is too long"); + return NULL; } - int dest_size = LCMapStringEx(locale_, flags, src_, srcLen, NULL, 0, + int dest_size = LCMapStringEx(locale, flags, src_, (int)src_size, NULL, 0, NULL, NULL, 0); - if (dest_size == 0) { - PyMem_Free(locale_); + if (dest_size <= 0) { + DWORD error = GetLastError(); PyMem_Free(src_); - return PyErr_SetFromWindowsErr(0); + return PyErr_SetFromWindowsErr(error); } wchar_t* dest = PyMem_NEW(wchar_t, dest_size); if (dest == NULL) { - PyMem_Free(locale_); PyMem_Free(src_); return PyErr_NoMemory(); } - int nmapped = LCMapStringEx(locale_, flags, src_, srcLen, dest, dest_size, + int nmapped = LCMapStringEx(locale, flags, src_, (int)src_size, dest, dest_size, NULL, NULL, 0); - if (nmapped == 0) { + if (nmapped <= 0) { DWORD error = GetLastError(); - PyMem_Free(locale_); PyMem_Free(src_); PyMem_DEL(dest); return PyErr_SetFromWindowsErr(error); } - PyObject *ret = PyUnicode_FromWideChar(dest, dest_size); - PyMem_Free(locale_); PyMem_Free(src_); + PyObject *ret = PyUnicode_FromWideChar(dest, nmapped); PyMem_DEL(dest); return ret; @@ -1609,13 +1598,13 @@ _winapi.ReadFile handle: HANDLE size: DWORD - overlapped as use_overlapped: bool(accept={int}) = False + overlapped as use_overlapped: bool = False [clinic start generated code]*/ static PyObject * _winapi_ReadFile_impl(PyObject *module, HANDLE handle, DWORD size, int use_overlapped) -/*[clinic end generated code: output=d3d5b44a8201b944 input=08c439d03a11aac5]*/ +/*[clinic end generated code: output=d3d5b44a8201b944 input=4f82f8e909ad91ad]*/ { DWORD nread; PyObject *buf; @@ -1895,13 +1884,13 @@ _winapi.WriteFile handle: HANDLE buffer: object - overlapped as use_overlapped: bool(accept={int}) = False + overlapped as use_overlapped: bool = False [clinic start generated code]*/ static PyObject * _winapi_WriteFile_impl(PyObject *module, HANDLE handle, PyObject *buffer, int use_overlapped) -/*[clinic end generated code: output=2ca80f6bf3fa92e3 input=11eae2a03aa32731]*/ +/*[clinic end generated code: output=2ca80f6bf3fa92e3 input=2badb008c8a2e2a0]*/ { Py_buffer _buf, *buf; DWORD len, written; @@ -1986,6 +1975,7 @@ _winapi_GetFileType_impl(PyObject *module, HANDLE handle) return result; } + /*[clinic input] _winapi._mimetypes_read_windows_registry @@ -2093,6 +2083,87 @@ _winapi__mimetypes_read_windows_registry_impl(PyObject *module, #undef CB_TYPE } +/*[clinic input] +_winapi.NeedCurrentDirectoryForExePath -> bool + + exe_name: LPCWSTR + / +[clinic start generated code]*/ + +static int +_winapi_NeedCurrentDirectoryForExePath_impl(PyObject *module, + LPCWSTR exe_name) +/*[clinic end generated code: output=a65ec879502b58fc input=972aac88a1ec2f00]*/ +{ + BOOL result; + + Py_BEGIN_ALLOW_THREADS + result = NeedCurrentDirectoryForExePathW(exe_name); + Py_END_ALLOW_THREADS + + return result; +} + + +/*[clinic input] +_winapi.CopyFile2 + + existing_file_name: LPCWSTR + new_file_name: LPCWSTR + flags: DWORD + progress_routine: object = None + +Copies a file from one name to a new name. + +This is implemented using the CopyFile2 API, which preserves all stat +and metadata information apart from security attributes. + +progress_routine is reserved for future use, but is currently not +implemented. Its value is ignored. +[clinic start generated code]*/ + +static PyObject * +_winapi_CopyFile2_impl(PyObject *module, LPCWSTR existing_file_name, + LPCWSTR new_file_name, DWORD flags, + PyObject *progress_routine) +/*[clinic end generated code: output=43d960d9df73d984 input=fb976b8d1492d130]*/ +{ + HRESULT hr; + COPYFILE2_EXTENDED_PARAMETERS params = { sizeof(COPYFILE2_EXTENDED_PARAMETERS) }; + + if (PySys_Audit("_winapi.CopyFile2", "uuI", + existing_file_name, new_file_name, flags) < 0) { + return NULL; + } + + params.dwCopyFlags = flags; + /* For future implementation. We ignore the value for now so that + users only have to test for 'CopyFile2' existing and not whether + the additional parameter exists. + if (progress_routine != Py_None) { + params.pProgressRoutine = _winapi_CopyFile2ProgressRoutine; + params.pvCallbackContext = Py_NewRef(progress_routine); + } + */ + Py_BEGIN_ALLOW_THREADS; + hr = CopyFile2(existing_file_name, new_file_name, ¶ms); + Py_END_ALLOW_THREADS; + /* For future implementation. + if (progress_routine != Py_None) { + Py_DECREF(progress_routine); + } + */ + if (FAILED(hr)) { + if ((hr & 0xFFFF0000) == 0x80070000) { + PyErr_SetFromWindowsErr(hr & 0xFFFF); + } else { + PyErr_SetFromWindowsErr(hr); + } + return NULL; + } + Py_RETURN_NONE; +} + static PyMethodDef winapi_functions[] = { _WINAPI_CLOSEHANDLE_METHODDEF @@ -2128,6 +2199,8 @@ static PyMethodDef winapi_functions[] = { _WINAPI_GETACP_METHODDEF _WINAPI_GETFILETYPE_METHODDEF _WINAPI__MIMETYPES_READ_WINDOWS_REGISTRY_METHODDEF + _WINAPI_NEEDCURRENTDIRECTORYFOREXEPATH_METHODDEF + _WINAPI_COPYFILE2_METHODDEF {NULL, NULL} }; @@ -2164,6 +2237,7 @@ static int winapi_exec(PyObject *m) WINAPI_CONSTANT(F_DWORD, CREATE_NEW_PROCESS_GROUP); WINAPI_CONSTANT(F_DWORD, DUPLICATE_SAME_ACCESS); WINAPI_CONSTANT(F_DWORD, DUPLICATE_CLOSE_SOURCE); + WINAPI_CONSTANT(F_DWORD, ERROR_ACCESS_DENIED); WINAPI_CONSTANT(F_DWORD, ERROR_ALREADY_EXISTS); WINAPI_CONSTANT(F_DWORD, ERROR_BROKEN_PIPE); WINAPI_CONSTANT(F_DWORD, ERROR_IO_PENDING); @@ -2177,6 +2251,7 @@ static int winapi_exec(PyObject *m) WINAPI_CONSTANT(F_DWORD, ERROR_OPERATION_ABORTED); WINAPI_CONSTANT(F_DWORD, ERROR_PIPE_BUSY); WINAPI_CONSTANT(F_DWORD, ERROR_PIPE_CONNECTED); + WINAPI_CONSTANT(F_DWORD, ERROR_PRIVILEGE_NOT_HELD); WINAPI_CONSTANT(F_DWORD, ERROR_SEM_TIMEOUT); WINAPI_CONSTANT(F_DWORD, FILE_FLAG_FIRST_PIPE_INSTANCE); WINAPI_CONSTANT(F_DWORD, FILE_FLAG_OVERLAPPED); @@ -2270,6 +2345,34 @@ static int winapi_exec(PyObject *m) WINAPI_CONSTANT(F_DWORD, LCMAP_TRADITIONAL_CHINESE); WINAPI_CONSTANT(F_DWORD, LCMAP_UPPERCASE); + WINAPI_CONSTANT(F_DWORD, COPY_FILE_ALLOW_DECRYPTED_DESTINATION); + WINAPI_CONSTANT(F_DWORD, COPY_FILE_COPY_SYMLINK); + WINAPI_CONSTANT(F_DWORD, COPY_FILE_FAIL_IF_EXISTS); + WINAPI_CONSTANT(F_DWORD, COPY_FILE_NO_BUFFERING); + WINAPI_CONSTANT(F_DWORD, COPY_FILE_NO_OFFLOAD); + WINAPI_CONSTANT(F_DWORD, COPY_FILE_OPEN_SOURCE_FOR_WRITE); + WINAPI_CONSTANT(F_DWORD, COPY_FILE_RESTARTABLE); + WINAPI_CONSTANT(F_DWORD, COPY_FILE_REQUEST_SECURITY_PRIVILEGES); + WINAPI_CONSTANT(F_DWORD, COPY_FILE_RESUME_FROM_PAUSE); +#ifndef COPY_FILE_REQUEST_COMPRESSED_TRAFFIC + // Only defined in newer WinSDKs + #define COPY_FILE_REQUEST_COMPRESSED_TRAFFIC 0x10000000 +#endif + WINAPI_CONSTANT(F_DWORD, COPY_FILE_REQUEST_COMPRESSED_TRAFFIC); + + WINAPI_CONSTANT(F_DWORD, COPYFILE2_CALLBACK_CHUNK_STARTED); + WINAPI_CONSTANT(F_DWORD, COPYFILE2_CALLBACK_CHUNK_FINISHED); + WINAPI_CONSTANT(F_DWORD, COPYFILE2_CALLBACK_STREAM_STARTED); + WINAPI_CONSTANT(F_DWORD, COPYFILE2_CALLBACK_STREAM_FINISHED); + WINAPI_CONSTANT(F_DWORD, COPYFILE2_CALLBACK_POLL_CONTINUE); + WINAPI_CONSTANT(F_DWORD, COPYFILE2_CALLBACK_ERROR); + + WINAPI_CONSTANT(F_DWORD, COPYFILE2_PROGRESS_CONTINUE); + WINAPI_CONSTANT(F_DWORD, COPYFILE2_PROGRESS_CANCEL); + WINAPI_CONSTANT(F_DWORD, COPYFILE2_PROGRESS_STOP); + WINAPI_CONSTANT(F_DWORD, COPYFILE2_PROGRESS_QUIET); + WINAPI_CONSTANT(F_DWORD, COPYFILE2_PROGRESS_PAUSE); + WINAPI_CONSTANT("i", NULL); return 0; @@ -2277,6 +2380,7 @@ static int winapi_exec(PyObject *m) static PyModuleDef_Slot winapi_slots[] = { {Py_mod_exec, winapi_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; diff --git a/Modules/_xxinterpchannelsmodule.c b/Modules/_xxinterpchannelsmodule.c new file mode 100644 index 00000000..1d7e7f1d --- /dev/null +++ b/Modules/_xxinterpchannelsmodule.c @@ -0,0 +1,2464 @@ + +/* interpreters module */ +/* low-level access to interpreter primitives */ + +#include "Python.h" +#include "interpreteridobject.h" + + +/* +This module has the following process-global state: + +_globals (static struct globals): + module_count (int) + channels (struct _channels): + numopen (int64_t) + next_id; (int64_t) + mutex (PyThread_type_lock) + head (linked list of struct _channelref *): + id (int64_t) + objcount (Py_ssize_t) + next (struct _channelref *): + ... + chan (struct _channel *): + open (int) + mutex (PyThread_type_lock) + closing (struct _channel_closing *): + ref (struct _channelref *): + ... + ends (struct _channelends *): + numsendopen (int64_t) + numrecvopen (int64_t) + send (struct _channelend *): + interp (int64_t) + open (int) + next (struct _channelend *) + recv (struct _channelend *): + ... + queue (struct _channelqueue *): + count (int64_t) + first (struct _channelitem *): + next (struct _channelitem *): + ... + data (_PyCrossInterpreterData *): + data (void *) + obj (PyObject *) + interp (int64_t) + new_object (xid_newobjectfunc) + free (xid_freefunc) + last (struct _channelitem *): + ... + +The above state includes the following allocations by the module: + +* 1 top-level mutex (to protect the rest of the state) +* for each channel: + * 1 struct _channelref + * 1 struct _channel + * 0-1 struct _channel_closing + * 1 struct _channelends + * 2 struct _channelend + * 1 struct _channelqueue +* for each item in each channel: + * 1 struct _channelitem + * 1 _PyCrossInterpreterData + +The only objects in that global state are the references held by each +channel's queue, which are safely managed via the _PyCrossInterpreterData_*() +API.. The module does not create any objects that are shared globally. +*/ + +#define MODULE_NAME "_xxinterpchannels" + + +#define GLOBAL_MALLOC(TYPE) \ + PyMem_RawMalloc(sizeof(TYPE)) +#define GLOBAL_FREE(VAR) \ + PyMem_RawFree(VAR) + + +static PyInterpreterState * +_get_current_interp(void) +{ + // PyInterpreterState_Get() aborts if lookup fails, so don't need + // to check the result for NULL. + return PyInterpreterState_Get(); +} + +static PyObject * +_get_current_module(void) +{ + PyObject *name = PyUnicode_FromString(MODULE_NAME); + if (name == NULL) { + return NULL; + } + PyObject *mod = PyImport_GetModule(name); + Py_DECREF(name); + if (mod == NULL) { + return NULL; + } + assert(mod != Py_None); + return mod; +} + +static PyObject * +get_module_from_owned_type(PyTypeObject *cls) +{ + assert(cls != NULL); + return _get_current_module(); + // XXX Use the more efficient API now that we use heap types: + //return PyType_GetModule(cls); +} + +static struct PyModuleDef moduledef; + +static PyObject * +get_module_from_type(PyTypeObject *cls) +{ + assert(cls != NULL); + return _get_current_module(); + // XXX Use the more efficient API now that we use heap types: + //return PyType_GetModuleByDef(cls, &moduledef); +} + +static PyObject * +add_new_exception(PyObject *mod, const char *name, PyObject *base) +{ + assert(!PyObject_HasAttrString(mod, name)); + PyObject *exctype = PyErr_NewException(name, base, NULL); + if (exctype == NULL) { + return NULL; + } + int res = PyModule_AddType(mod, (PyTypeObject *)exctype); + if (res < 0) { + Py_DECREF(exctype); + return NULL; + } + return exctype; +} + +#define ADD_NEW_EXCEPTION(MOD, NAME, BASE) \ + add_new_exception(MOD, MODULE_NAME "." Py_STRINGIFY(NAME), BASE) + +static PyTypeObject * +add_new_type(PyObject *mod, PyType_Spec *spec, crossinterpdatafunc shared) +{ + PyTypeObject *cls = (PyTypeObject *)PyType_FromMetaclass( + NULL, mod, spec, NULL); + if (cls == NULL) { + return NULL; + } + if (PyModule_AddType(mod, cls) < 0) { + Py_DECREF(cls); + return NULL; + } + if (shared != NULL) { + if (_PyCrossInterpreterData_RegisterClass(cls, shared)) { + Py_DECREF(cls); + return NULL; + } + } + return cls; +} + +static int +_release_xid_data(_PyCrossInterpreterData *data, int ignoreexc) +{ + PyObject *exc; + if (ignoreexc) { + exc = PyErr_GetRaisedException(); + } + int res = _PyCrossInterpreterData_Release(data); + if (res < 0) { + /* The owning interpreter is already destroyed. */ + if (ignoreexc) { + // XXX Emit a warning? + PyErr_Clear(); + } + } + if (ignoreexc) { + PyErr_SetRaisedException(exc); + } + return res; +} + + +/* module state *************************************************************/ + +typedef struct { + /* heap types */ + PyTypeObject *ChannelIDType; + + /* exceptions */ + PyObject *ChannelError; + PyObject *ChannelNotFoundError; + PyObject *ChannelClosedError; + PyObject *ChannelEmptyError; + PyObject *ChannelNotEmptyError; +} module_state; + +static inline module_state * +get_module_state(PyObject *mod) +{ + assert(mod != NULL); + module_state *state = PyModule_GetState(mod); + assert(state != NULL); + return state; +} + +static int +traverse_module_state(module_state *state, visitproc visit, void *arg) +{ + /* heap types */ + Py_VISIT(state->ChannelIDType); + + /* exceptions */ + Py_VISIT(state->ChannelError); + Py_VISIT(state->ChannelNotFoundError); + Py_VISIT(state->ChannelClosedError); + Py_VISIT(state->ChannelEmptyError); + Py_VISIT(state->ChannelNotEmptyError); + + return 0; +} + +static int +clear_module_state(module_state *state) +{ + /* heap types */ + if (state->ChannelIDType != NULL) { + (void)_PyCrossInterpreterData_UnregisterClass(state->ChannelIDType); + } + Py_CLEAR(state->ChannelIDType); + + /* exceptions */ + Py_CLEAR(state->ChannelError); + Py_CLEAR(state->ChannelNotFoundError); + Py_CLEAR(state->ChannelClosedError); + Py_CLEAR(state->ChannelEmptyError); + Py_CLEAR(state->ChannelNotEmptyError); + + return 0; +} + + +/* channel-specific code ****************************************************/ + +#define CHANNEL_SEND 1 +#define CHANNEL_BOTH 0 +#define CHANNEL_RECV -1 + +/* channel errors */ + +#define ERR_CHANNEL_NOT_FOUND -2 +#define ERR_CHANNEL_CLOSED -3 +#define ERR_CHANNEL_INTERP_CLOSED -4 +#define ERR_CHANNEL_EMPTY -5 +#define ERR_CHANNEL_NOT_EMPTY -6 +#define ERR_CHANNEL_MUTEX_INIT -7 +#define ERR_CHANNELS_MUTEX_INIT -8 +#define ERR_NO_NEXT_CHANNEL_ID -9 + +static int +exceptions_init(PyObject *mod) +{ + module_state *state = get_module_state(mod); + if (state == NULL) { + return -1; + } + +#define ADD(NAME, BASE) \ + do { \ + assert(state->NAME == NULL); \ + state->NAME = ADD_NEW_EXCEPTION(mod, NAME, BASE); \ + if (state->NAME == NULL) { \ + return -1; \ + } \ + } while (0) + + // A channel-related operation failed. + ADD(ChannelError, PyExc_RuntimeError); + // An operation tried to use a channel that doesn't exist. + ADD(ChannelNotFoundError, state->ChannelError); + // An operation tried to use a closed channel. + ADD(ChannelClosedError, state->ChannelError); + // An operation tried to pop from an empty channel. + ADD(ChannelEmptyError, state->ChannelError); + // An operation tried to close a non-empty channel. + ADD(ChannelNotEmptyError, state->ChannelError); +#undef ADD + + return 0; +} + +static int +handle_channel_error(int err, PyObject *mod, int64_t cid) +{ + if (err == 0) { + assert(!PyErr_Occurred()); + return 0; + } + assert(err < 0); + module_state *state = get_module_state(mod); + assert(state != NULL); + if (err == ERR_CHANNEL_NOT_FOUND) { + PyErr_Format(state->ChannelNotFoundError, + "channel %" PRId64 " not found", cid); + } + else if (err == ERR_CHANNEL_CLOSED) { + PyErr_Format(state->ChannelClosedError, + "channel %" PRId64 " is closed", cid); + } + else if (err == ERR_CHANNEL_INTERP_CLOSED) { + PyErr_Format(state->ChannelClosedError, + "channel %" PRId64 " is already closed", cid); + } + else if (err == ERR_CHANNEL_EMPTY) { + PyErr_Format(state->ChannelEmptyError, + "channel %" PRId64 " is empty", cid); + } + else if (err == ERR_CHANNEL_NOT_EMPTY) { + PyErr_Format(state->ChannelNotEmptyError, + "channel %" PRId64 " may not be closed " + "if not empty (try force=True)", + cid); + } + else if (err == ERR_CHANNEL_MUTEX_INIT) { + PyErr_SetString(state->ChannelError, + "can't initialize mutex for new channel"); + } + else if (err == ERR_CHANNELS_MUTEX_INIT) { + PyErr_SetString(state->ChannelError, + "can't initialize mutex for channel management"); + } + else if (err == ERR_NO_NEXT_CHANNEL_ID) { + PyErr_SetString(state->ChannelError, + "failed to get a channel ID"); + } + else { + assert(PyErr_Occurred()); + } + return 1; +} + +/* the channel queue */ + +struct _channelitem; + +typedef struct _channelitem { + _PyCrossInterpreterData *data; + struct _channelitem *next; +} _channelitem; + +static _channelitem * +_channelitem_new(void) +{ + _channelitem *item = GLOBAL_MALLOC(_channelitem); + if (item == NULL) { + PyErr_NoMemory(); + return NULL; + } + item->data = NULL; + item->next = NULL; + return item; +} + +static void +_channelitem_clear(_channelitem *item) +{ + if (item->data != NULL) { + (void)_release_xid_data(item->data, 1); + // It was allocated in _channel_send(). + GLOBAL_FREE(item->data); + item->data = NULL; + } + item->next = NULL; +} + +static void +_channelitem_free(_channelitem *item) +{ + _channelitem_clear(item); + GLOBAL_FREE(item); +} + +static void +_channelitem_free_all(_channelitem *item) +{ + while (item != NULL) { + _channelitem *last = item; + item = item->next; + _channelitem_free(last); + } +} + +static _PyCrossInterpreterData * +_channelitem_popped(_channelitem *item) +{ + _PyCrossInterpreterData *data = item->data; + item->data = NULL; + _channelitem_free(item); + return data; +} + +typedef struct _channelqueue { + int64_t count; + _channelitem *first; + _channelitem *last; +} _channelqueue; + +static _channelqueue * +_channelqueue_new(void) +{ + _channelqueue *queue = GLOBAL_MALLOC(_channelqueue); + if (queue == NULL) { + PyErr_NoMemory(); + return NULL; + } + queue->count = 0; + queue->first = NULL; + queue->last = NULL; + return queue; +} + +static void +_channelqueue_clear(_channelqueue *queue) +{ + _channelitem_free_all(queue->first); + queue->count = 0; + queue->first = NULL; + queue->last = NULL; +} + +static void +_channelqueue_free(_channelqueue *queue) +{ + _channelqueue_clear(queue); + GLOBAL_FREE(queue); +} + +static int +_channelqueue_put(_channelqueue *queue, _PyCrossInterpreterData *data) +{ + _channelitem *item = _channelitem_new(); + if (item == NULL) { + return -1; + } + item->data = data; + + queue->count += 1; + if (queue->first == NULL) { + queue->first = item; + } + else { + queue->last->next = item; + } + queue->last = item; + return 0; +} + +static _PyCrossInterpreterData * +_channelqueue_get(_channelqueue *queue) +{ + _channelitem *item = queue->first; + if (item == NULL) { + return NULL; + } + queue->first = item->next; + if (queue->last == item) { + queue->last = NULL; + } + queue->count -= 1; + + return _channelitem_popped(item); +} + +static void +_channelqueue_drop_interpreter(_channelqueue *queue, int64_t interp) +{ + _channelitem *prev = NULL; + _channelitem *next = queue->first; + while (next != NULL) { + _channelitem *item = next; + next = item->next; + if (item->data->interp == interp) { + if (prev == NULL) { + queue->first = item->next; + } + else { + prev->next = item->next; + } + _channelitem_free(item); + queue->count -= 1; + } + else { + prev = item; + } + } +} + +/* channel-interpreter associations */ + +struct _channelend; + +typedef struct _channelend { + struct _channelend *next; + int64_t interp; + int open; +} _channelend; + +static _channelend * +_channelend_new(int64_t interp) +{ + _channelend *end = GLOBAL_MALLOC(_channelend); + if (end == NULL) { + PyErr_NoMemory(); + return NULL; + } + end->next = NULL; + end->interp = interp; + end->open = 1; + return end; +} + +static void +_channelend_free(_channelend *end) +{ + GLOBAL_FREE(end); +} + +static void +_channelend_free_all(_channelend *end) +{ + while (end != NULL) { + _channelend *last = end; + end = end->next; + _channelend_free(last); + } +} + +static _channelend * +_channelend_find(_channelend *first, int64_t interp, _channelend **pprev) +{ + _channelend *prev = NULL; + _channelend *end = first; + while (end != NULL) { + if (end->interp == interp) { + break; + } + prev = end; + end = end->next; + } + if (pprev != NULL) { + *pprev = prev; + } + return end; +} + +typedef struct _channelassociations { + // Note that the list entries are never removed for interpreter + // for which the channel is closed. This should not be a problem in + // practice. Also, a channel isn't automatically closed when an + // interpreter is destroyed. + int64_t numsendopen; + int64_t numrecvopen; + _channelend *send; + _channelend *recv; +} _channelends; + +static _channelends * +_channelends_new(void) +{ + _channelends *ends = GLOBAL_MALLOC(_channelends); + if (ends== NULL) { + return NULL; + } + ends->numsendopen = 0; + ends->numrecvopen = 0; + ends->send = NULL; + ends->recv = NULL; + return ends; +} + +static void +_channelends_clear(_channelends *ends) +{ + _channelend_free_all(ends->send); + ends->send = NULL; + ends->numsendopen = 0; + + _channelend_free_all(ends->recv); + ends->recv = NULL; + ends->numrecvopen = 0; +} + +static void +_channelends_free(_channelends *ends) +{ + _channelends_clear(ends); + GLOBAL_FREE(ends); +} + +static _channelend * +_channelends_add(_channelends *ends, _channelend *prev, int64_t interp, + int send) +{ + _channelend *end = _channelend_new(interp); + if (end == NULL) { + return NULL; + } + + if (prev == NULL) { + if (send) { + ends->send = end; + } + else { + ends->recv = end; + } + } + else { + prev->next = end; + } + if (send) { + ends->numsendopen += 1; + } + else { + ends->numrecvopen += 1; + } + return end; +} + +static int +_channelends_associate(_channelends *ends, int64_t interp, int send) +{ + _channelend *prev; + _channelend *end = _channelend_find(send ? ends->send : ends->recv, + interp, &prev); + if (end != NULL) { + if (!end->open) { + return ERR_CHANNEL_CLOSED; + } + // already associated + return 0; + } + if (_channelends_add(ends, prev, interp, send) == NULL) { + return -1; + } + return 0; +} + +static int +_channelends_is_open(_channelends *ends) +{ + if (ends->numsendopen != 0 || ends->numrecvopen != 0) { + return 1; + } + if (ends->send == NULL && ends->recv == NULL) { + return 1; + } + return 0; +} + +static void +_channelends_close_end(_channelends *ends, _channelend *end, int send) +{ + end->open = 0; + if (send) { + ends->numsendopen -= 1; + } + else { + ends->numrecvopen -= 1; + } +} + +static int +_channelends_close_interpreter(_channelends *ends, int64_t interp, int which) +{ + _channelend *prev; + _channelend *end; + if (which >= 0) { // send/both + end = _channelend_find(ends->send, interp, &prev); + if (end == NULL) { + // never associated so add it + end = _channelends_add(ends, prev, interp, 1); + if (end == NULL) { + return -1; + } + } + _channelends_close_end(ends, end, 1); + } + if (which <= 0) { // recv/both + end = _channelend_find(ends->recv, interp, &prev); + if (end == NULL) { + // never associated so add it + end = _channelends_add(ends, prev, interp, 0); + if (end == NULL) { + return -1; + } + } + _channelends_close_end(ends, end, 0); + } + return 0; +} + +static void +_channelends_drop_interpreter(_channelends *ends, int64_t interp) +{ + _channelend *end; + end = _channelend_find(ends->send, interp, NULL); + if (end != NULL) { + _channelends_close_end(ends, end, 1); + } + end = _channelend_find(ends->recv, interp, NULL); + if (end != NULL) { + _channelends_close_end(ends, end, 0); + } +} + +static void +_channelends_close_all(_channelends *ends, int which, int force) +{ + // XXX Handle the ends. + // XXX Handle force is True. + + // Ensure all the "send"-associated interpreters are closed. + _channelend *end; + for (end = ends->send; end != NULL; end = end->next) { + _channelends_close_end(ends, end, 1); + } + + // Ensure all the "recv"-associated interpreters are closed. + for (end = ends->recv; end != NULL; end = end->next) { + _channelends_close_end(ends, end, 0); + } +} + +/* channels */ + +struct _channel; +struct _channel_closing; +static void _channel_clear_closing(struct _channel *); +static void _channel_finish_closing(struct _channel *); + +typedef struct _channel { + PyThread_type_lock mutex; + _channelqueue *queue; + _channelends *ends; + int open; + struct _channel_closing *closing; +} _PyChannelState; + +static _PyChannelState * +_channel_new(PyThread_type_lock mutex) +{ + _PyChannelState *chan = GLOBAL_MALLOC(_PyChannelState); + if (chan == NULL) { + return NULL; + } + chan->mutex = mutex; + chan->queue = _channelqueue_new(); + if (chan->queue == NULL) { + GLOBAL_FREE(chan); + return NULL; + } + chan->ends = _channelends_new(); + if (chan->ends == NULL) { + _channelqueue_free(chan->queue); + GLOBAL_FREE(chan); + return NULL; + } + chan->open = 1; + chan->closing = NULL; + return chan; +} + +static void +_channel_free(_PyChannelState *chan) +{ + _channel_clear_closing(chan); + PyThread_acquire_lock(chan->mutex, WAIT_LOCK); + _channelqueue_free(chan->queue); + _channelends_free(chan->ends); + PyThread_release_lock(chan->mutex); + + PyThread_free_lock(chan->mutex); + GLOBAL_FREE(chan); +} + +static int +_channel_add(_PyChannelState *chan, int64_t interp, + _PyCrossInterpreterData *data) +{ + int res = -1; + PyThread_acquire_lock(chan->mutex, WAIT_LOCK); + + if (!chan->open) { + res = ERR_CHANNEL_CLOSED; + goto done; + } + if (_channelends_associate(chan->ends, interp, 1) != 0) { + res = ERR_CHANNEL_INTERP_CLOSED; + goto done; + } + + if (_channelqueue_put(chan->queue, data) != 0) { + goto done; + } + + res = 0; +done: + PyThread_release_lock(chan->mutex); + return res; +} + +static int +_channel_next(_PyChannelState *chan, int64_t interp, + _PyCrossInterpreterData **res) +{ + int err = 0; + PyThread_acquire_lock(chan->mutex, WAIT_LOCK); + + if (!chan->open) { + err = ERR_CHANNEL_CLOSED; + goto done; + } + if (_channelends_associate(chan->ends, interp, 0) != 0) { + err = ERR_CHANNEL_INTERP_CLOSED; + goto done; + } + + _PyCrossInterpreterData *data = _channelqueue_get(chan->queue); + if (data == NULL && !PyErr_Occurred() && chan->closing != NULL) { + chan->open = 0; + } + *res = data; + +done: + PyThread_release_lock(chan->mutex); + if (chan->queue->count == 0) { + _channel_finish_closing(chan); + } + return err; +} + +static int +_channel_close_interpreter(_PyChannelState *chan, int64_t interp, int end) +{ + PyThread_acquire_lock(chan->mutex, WAIT_LOCK); + + int res = -1; + if (!chan->open) { + res = ERR_CHANNEL_CLOSED; + goto done; + } + + if (_channelends_close_interpreter(chan->ends, interp, end) != 0) { + goto done; + } + chan->open = _channelends_is_open(chan->ends); + + res = 0; +done: + PyThread_release_lock(chan->mutex); + return res; +} + +static void +_channel_drop_interpreter(_PyChannelState *chan, int64_t interp) +{ + PyThread_acquire_lock(chan->mutex, WAIT_LOCK); + + _channelqueue_drop_interpreter(chan->queue, interp); + _channelends_drop_interpreter(chan->ends, interp); + chan->open = _channelends_is_open(chan->ends); + + PyThread_release_lock(chan->mutex); +} + +static int +_channel_close_all(_PyChannelState *chan, int end, int force) +{ + int res = -1; + PyThread_acquire_lock(chan->mutex, WAIT_LOCK); + + if (!chan->open) { + res = ERR_CHANNEL_CLOSED; + goto done; + } + + if (!force && chan->queue->count > 0) { + res = ERR_CHANNEL_NOT_EMPTY; + goto done; + } + + chan->open = 0; + + // We *could* also just leave these in place, since we've marked + // the channel as closed already. + _channelends_close_all(chan->ends, end, force); + + res = 0; +done: + PyThread_release_lock(chan->mutex); + return res; +} + +/* the set of channels */ + +struct _channelref; + +typedef struct _channelref { + int64_t id; + _PyChannelState *chan; + struct _channelref *next; + Py_ssize_t objcount; +} _channelref; + +static _channelref * +_channelref_new(int64_t id, _PyChannelState *chan) +{ + _channelref *ref = GLOBAL_MALLOC(_channelref); + if (ref == NULL) { + return NULL; + } + ref->id = id; + ref->chan = chan; + ref->next = NULL; + ref->objcount = 0; + return ref; +} + +//static void +//_channelref_clear(_channelref *ref) +//{ +// ref->id = -1; +// ref->chan = NULL; +// ref->next = NULL; +// ref->objcount = 0; +//} + +static void +_channelref_free(_channelref *ref) +{ + if (ref->chan != NULL) { + _channel_clear_closing(ref->chan); + } + //_channelref_clear(ref); + GLOBAL_FREE(ref); +} + +static _channelref * +_channelref_find(_channelref *first, int64_t id, _channelref **pprev) +{ + _channelref *prev = NULL; + _channelref *ref = first; + while (ref != NULL) { + if (ref->id == id) { + break; + } + prev = ref; + ref = ref->next; + } + if (pprev != NULL) { + *pprev = prev; + } + return ref; +} + +typedef struct _channels { + PyThread_type_lock mutex; + _channelref *head; + int64_t numopen; + int64_t next_id; +} _channels; + +static void +_channels_init(_channels *channels, PyThread_type_lock mutex) +{ + channels->mutex = mutex; + channels->head = NULL; + channels->numopen = 0; + channels->next_id = 0; +} + +static void +_channels_fini(_channels *channels) +{ + assert(channels->numopen == 0); + assert(channels->head == NULL); + if (channels->mutex != NULL) { + PyThread_free_lock(channels->mutex); + channels->mutex = NULL; + } +} + +static int64_t +_channels_next_id(_channels *channels) // needs lock +{ + int64_t id = channels->next_id; + if (id < 0) { + /* overflow */ + return -1; + } + channels->next_id += 1; + return id; +} + +static int +_channels_lookup(_channels *channels, int64_t id, PyThread_type_lock *pmutex, + _PyChannelState **res) +{ + int err = -1; + _PyChannelState *chan = NULL; + PyThread_acquire_lock(channels->mutex, WAIT_LOCK); + if (pmutex != NULL) { + *pmutex = NULL; + } + + _channelref *ref = _channelref_find(channels->head, id, NULL); + if (ref == NULL) { + err = ERR_CHANNEL_NOT_FOUND; + goto done; + } + if (ref->chan == NULL || !ref->chan->open) { + err = ERR_CHANNEL_CLOSED; + goto done; + } + + if (pmutex != NULL) { + // The mutex will be closed by the caller. + *pmutex = channels->mutex; + } + + chan = ref->chan; + err = 0; + +done: + if (pmutex == NULL || *pmutex == NULL) { + PyThread_release_lock(channels->mutex); + } + *res = chan; + return err; +} + +static int64_t +_channels_add(_channels *channels, _PyChannelState *chan) +{ + int64_t cid = -1; + PyThread_acquire_lock(channels->mutex, WAIT_LOCK); + + // Create a new ref. + int64_t id = _channels_next_id(channels); + if (id < 0) { + cid = ERR_NO_NEXT_CHANNEL_ID; + goto done; + } + _channelref *ref = _channelref_new(id, chan); + if (ref == NULL) { + goto done; + } + + // Add it to the list. + // We assume that the channel is a new one (not already in the list). + ref->next = channels->head; + channels->head = ref; + channels->numopen += 1; + + cid = id; +done: + PyThread_release_lock(channels->mutex); + return cid; +} + +/* forward */ +static int _channel_set_closing(struct _channelref *, PyThread_type_lock); + +static int +_channels_close(_channels *channels, int64_t cid, _PyChannelState **pchan, + int end, int force) +{ + int res = -1; + PyThread_acquire_lock(channels->mutex, WAIT_LOCK); + if (pchan != NULL) { + *pchan = NULL; + } + + _channelref *ref = _channelref_find(channels->head, cid, NULL); + if (ref == NULL) { + res = ERR_CHANNEL_NOT_FOUND; + goto done; + } + + if (ref->chan == NULL) { + res = ERR_CHANNEL_CLOSED; + goto done; + } + else if (!force && end == CHANNEL_SEND && ref->chan->closing != NULL) { + res = ERR_CHANNEL_CLOSED; + goto done; + } + else { + int err = _channel_close_all(ref->chan, end, force); + if (err != 0) { + if (end == CHANNEL_SEND && err == ERR_CHANNEL_NOT_EMPTY) { + if (ref->chan->closing != NULL) { + res = ERR_CHANNEL_CLOSED; + goto done; + } + // Mark the channel as closing and return. The channel + // will be cleaned up in _channel_next(). + PyErr_Clear(); + int err = _channel_set_closing(ref, channels->mutex); + if (err != 0) { + res = err; + goto done; + } + if (pchan != NULL) { + *pchan = ref->chan; + } + res = 0; + } + else { + res = err; + } + goto done; + } + if (pchan != NULL) { + *pchan = ref->chan; + } + else { + _channel_free(ref->chan); + } + ref->chan = NULL; + } + + res = 0; +done: + PyThread_release_lock(channels->mutex); + return res; +} + +static void +_channels_remove_ref(_channels *channels, _channelref *ref, _channelref *prev, + _PyChannelState **pchan) +{ + if (ref == channels->head) { + channels->head = ref->next; + } + else { + prev->next = ref->next; + } + channels->numopen -= 1; + + if (pchan != NULL) { + *pchan = ref->chan; + } + _channelref_free(ref); +} + +static int +_channels_remove(_channels *channels, int64_t id, _PyChannelState **pchan) +{ + int res = -1; + PyThread_acquire_lock(channels->mutex, WAIT_LOCK); + + if (pchan != NULL) { + *pchan = NULL; + } + + _channelref *prev = NULL; + _channelref *ref = _channelref_find(channels->head, id, &prev); + if (ref == NULL) { + res = ERR_CHANNEL_NOT_FOUND; + goto done; + } + + _channels_remove_ref(channels, ref, prev, pchan); + + res = 0; +done: + PyThread_release_lock(channels->mutex); + return res; +} + +static int +_channels_add_id_object(_channels *channels, int64_t id) +{ + int res = -1; + PyThread_acquire_lock(channels->mutex, WAIT_LOCK); + + _channelref *ref = _channelref_find(channels->head, id, NULL); + if (ref == NULL) { + res = ERR_CHANNEL_NOT_FOUND; + goto done; + } + ref->objcount += 1; + + res = 0; +done: + PyThread_release_lock(channels->mutex); + return res; +} + +static void +_channels_drop_id_object(_channels *channels, int64_t id) +{ + PyThread_acquire_lock(channels->mutex, WAIT_LOCK); + + _channelref *prev = NULL; + _channelref *ref = _channelref_find(channels->head, id, &prev); + if (ref == NULL) { + // Already destroyed. + goto done; + } + ref->objcount -= 1; + + // Destroy if no longer used. + if (ref->objcount == 0) { + _PyChannelState *chan = NULL; + _channels_remove_ref(channels, ref, prev, &chan); + if (chan != NULL) { + _channel_free(chan); + } + } + +done: + PyThread_release_lock(channels->mutex); +} + +static int64_t * +_channels_list_all(_channels *channels, int64_t *count) +{ + int64_t *cids = NULL; + PyThread_acquire_lock(channels->mutex, WAIT_LOCK); + int64_t *ids = PyMem_NEW(int64_t, (Py_ssize_t)(channels->numopen)); + if (ids == NULL) { + goto done; + } + _channelref *ref = channels->head; + for (int64_t i=0; ref != NULL; ref = ref->next, i++) { + ids[i] = ref->id; + } + *count = channels->numopen; + + cids = ids; +done: + PyThread_release_lock(channels->mutex); + return cids; +} + +static void +_channels_drop_interpreter(_channels *channels, int64_t interp) +{ + PyThread_acquire_lock(channels->mutex, WAIT_LOCK); + + _channelref *ref = channels->head; + for (; ref != NULL; ref = ref->next) { + if (ref->chan != NULL) { + _channel_drop_interpreter(ref->chan, interp); + } + } + + PyThread_release_lock(channels->mutex); +} + +/* support for closing non-empty channels */ + +struct _channel_closing { + struct _channelref *ref; +}; + +static int +_channel_set_closing(struct _channelref *ref, PyThread_type_lock mutex) { + struct _channel *chan = ref->chan; + if (chan == NULL) { + // already closed + return 0; + } + int res = -1; + PyThread_acquire_lock(chan->mutex, WAIT_LOCK); + if (chan->closing != NULL) { + res = ERR_CHANNEL_CLOSED; + goto done; + } + chan->closing = GLOBAL_MALLOC(struct _channel_closing); + if (chan->closing == NULL) { + goto done; + } + chan->closing->ref = ref; + + res = 0; +done: + PyThread_release_lock(chan->mutex); + return res; +} + +static void +_channel_clear_closing(struct _channel *chan) { + PyThread_acquire_lock(chan->mutex, WAIT_LOCK); + if (chan->closing != NULL) { + GLOBAL_FREE(chan->closing); + chan->closing = NULL; + } + PyThread_release_lock(chan->mutex); +} + +static void +_channel_finish_closing(struct _channel *chan) { + struct _channel_closing *closing = chan->closing; + if (closing == NULL) { + return; + } + _channelref *ref = closing->ref; + _channel_clear_closing(chan); + // Do the things that would have been done in _channels_close(). + ref->chan = NULL; + _channel_free(chan); +} + +/* "high"-level channel-related functions */ + +static int64_t +_channel_create(_channels *channels) +{ + PyThread_type_lock mutex = PyThread_allocate_lock(); + if (mutex == NULL) { + return ERR_CHANNEL_MUTEX_INIT; + } + _PyChannelState *chan = _channel_new(mutex); + if (chan == NULL) { + PyThread_free_lock(mutex); + return -1; + } + int64_t id = _channels_add(channels, chan); + if (id < 0) { + _channel_free(chan); + } + return id; +} + +static int +_channel_destroy(_channels *channels, int64_t id) +{ + _PyChannelState *chan = NULL; + int err = _channels_remove(channels, id, &chan); + if (err != 0) { + return err; + } + if (chan != NULL) { + _channel_free(chan); + } + return 0; +} + +static int +_channel_send(_channels *channels, int64_t id, PyObject *obj) +{ + PyInterpreterState *interp = _get_current_interp(); + if (interp == NULL) { + return -1; + } + + // Look up the channel. + PyThread_type_lock mutex = NULL; + _PyChannelState *chan = NULL; + int err = _channels_lookup(channels, id, &mutex, &chan); + if (err != 0) { + return err; + } + assert(chan != NULL); + // Past this point we are responsible for releasing the mutex. + + if (chan->closing != NULL) { + PyThread_release_lock(mutex); + return ERR_CHANNEL_CLOSED; + } + + // Convert the object to cross-interpreter data. + _PyCrossInterpreterData *data = GLOBAL_MALLOC(_PyCrossInterpreterData); + if (data == NULL) { + PyThread_release_lock(mutex); + return -1; + } + if (_PyObject_GetCrossInterpreterData(obj, data) != 0) { + PyThread_release_lock(mutex); + GLOBAL_FREE(data); + return -1; + } + + // Add the data to the channel. + int res = _channel_add(chan, PyInterpreterState_GetID(interp), data); + PyThread_release_lock(mutex); + if (res != 0) { + // We may chain an exception here: + (void)_release_xid_data(data, 0); + GLOBAL_FREE(data); + return res; + } + + return 0; +} + +static int +_channel_recv(_channels *channels, int64_t id, PyObject **res) +{ + int err; + *res = NULL; + + PyInterpreterState *interp = _get_current_interp(); + if (interp == NULL) { + // XXX Is this always an error? + if (PyErr_Occurred()) { + return -1; + } + return 0; + } + + // Look up the channel. + PyThread_type_lock mutex = NULL; + _PyChannelState *chan = NULL; + err = _channels_lookup(channels, id, &mutex, &chan); + if (err != 0) { + return err; + } + assert(chan != NULL); + // Past this point we are responsible for releasing the mutex. + + // Pop off the next item from the channel. + _PyCrossInterpreterData *data = NULL; + err = _channel_next(chan, PyInterpreterState_GetID(interp), &data); + PyThread_release_lock(mutex); + if (err != 0) { + return err; + } + else if (data == NULL) { + assert(!PyErr_Occurred()); + return 0; + } + + // Convert the data back to an object. + PyObject *obj = _PyCrossInterpreterData_NewObject(data); + if (obj == NULL) { + assert(PyErr_Occurred()); + (void)_release_xid_data(data, 1); + // It was allocated in _channel_send(). + GLOBAL_FREE(data); + return -1; + } + int release_res = _release_xid_data(data, 0); + // It was allocated in _channel_send(). + GLOBAL_FREE(data); + if (release_res < 0) { + // The source interpreter has been destroyed already. + assert(PyErr_Occurred()); + Py_DECREF(obj); + return -1; + } + + *res = obj; + return 0; +} + +static int +_channel_drop(_channels *channels, int64_t id, int send, int recv) +{ + PyInterpreterState *interp = _get_current_interp(); + if (interp == NULL) { + return -1; + } + + // Look up the channel. + PyThread_type_lock mutex = NULL; + _PyChannelState *chan = NULL; + int err = _channels_lookup(channels, id, &mutex, &chan); + if (err != 0) { + return err; + } + // Past this point we are responsible for releasing the mutex. + + // Close one or both of the two ends. + int res = _channel_close_interpreter(chan, PyInterpreterState_GetID(interp), send-recv); + PyThread_release_lock(mutex); + return res; +} + +static int +_channel_close(_channels *channels, int64_t id, int end, int force) +{ + return _channels_close(channels, id, NULL, end, force); +} + +static int +_channel_is_associated(_channels *channels, int64_t cid, int64_t interp, + int send) +{ + _PyChannelState *chan = NULL; + int err = _channels_lookup(channels, cid, NULL, &chan); + if (err != 0) { + return err; + } + else if (send && chan->closing != NULL) { + return ERR_CHANNEL_CLOSED; + } + + _channelend *end = _channelend_find(send ? chan->ends->send : chan->ends->recv, + interp, NULL); + + return (end != NULL && end->open); +} + +/* ChannelID class */ + +typedef struct channelid { + PyObject_HEAD + int64_t id; + int end; + int resolve; + _channels *channels; +} channelid; + +struct channel_id_converter_data { + PyObject *module; + int64_t cid; +}; + +static int +channel_id_converter(PyObject *arg, void *ptr) +{ + int64_t cid; + struct channel_id_converter_data *data = ptr; + module_state *state = get_module_state(data->module); + assert(state != NULL); + if (PyObject_TypeCheck(arg, state->ChannelIDType)) { + cid = ((channelid *)arg)->id; + } + else if (PyIndex_Check(arg)) { + cid = PyLong_AsLongLong(arg); + if (cid == -1 && PyErr_Occurred()) { + return 0; + } + if (cid < 0) { + PyErr_Format(PyExc_ValueError, + "channel ID must be a non-negative int, got %R", arg); + return 0; + } + } + else { + PyErr_Format(PyExc_TypeError, + "channel ID must be an int, got %.100s", + Py_TYPE(arg)->tp_name); + return 0; + } + data->cid = cid; + return 1; +} + +static int +newchannelid(PyTypeObject *cls, int64_t cid, int end, _channels *channels, + int force, int resolve, channelid **res) +{ + *res = NULL; + + channelid *self = PyObject_New(channelid, cls); + if (self == NULL) { + return -1; + } + self->id = cid; + self->end = end; + self->resolve = resolve; + self->channels = channels; + + int err = _channels_add_id_object(channels, cid); + if (err != 0) { + if (force && err == ERR_CHANNEL_NOT_FOUND) { + assert(!PyErr_Occurred()); + } + else { + Py_DECREF((PyObject *)self); + return err; + } + } + + *res = self; + return 0; +} + +static _channels * _global_channels(void); + +static PyObject * +_channelid_new(PyObject *mod, PyTypeObject *cls, + PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"id", "send", "recv", "force", "_resolve", NULL}; + int64_t cid; + struct channel_id_converter_data cid_data = { + .module = mod, + }; + int send = -1; + int recv = -1; + int force = 0; + int resolve = 0; + if (!PyArg_ParseTupleAndKeywords(args, kwds, + "O&|$pppp:ChannelID.__new__", kwlist, + channel_id_converter, &cid_data, + &send, &recv, &force, &resolve)) { + return NULL; + } + cid = cid_data.cid; + + // Handle "send" and "recv". + if (send == 0 && recv == 0) { + PyErr_SetString(PyExc_ValueError, + "'send' and 'recv' cannot both be False"); + return NULL; + } + + int end = 0; + if (send == 1) { + if (recv == 0 || recv == -1) { + end = CHANNEL_SEND; + } + } + else if (recv == 1) { + end = CHANNEL_RECV; + } + + PyObject *id = NULL; + int err = newchannelid(cls, cid, end, _global_channels(), + force, resolve, + (channelid **)&id); + if (handle_channel_error(err, mod, cid)) { + assert(id == NULL); + return NULL; + } + assert(id != NULL); + return id; +} + +static void +channelid_dealloc(PyObject *self) +{ + int64_t cid = ((channelid *)self)->id; + _channels *channels = ((channelid *)self)->channels; + + PyTypeObject *tp = Py_TYPE(self); + tp->tp_free(self); + /* "Instances of heap-allocated types hold a reference to their type." + * See: https://docs.python.org/3.11/howto/isolating-extensions.html#garbage-collection-protocol + * See: https://docs.python.org/3.11/c-api/typeobj.html#c.PyTypeObject.tp_traverse + */ + // XXX Why don't we implement Py_TPFLAGS_HAVE_GC, e.g. Py_tp_traverse, + // like we do for _abc._abc_data? + Py_DECREF(tp); + + _channels_drop_id_object(channels, cid); +} + +static PyObject * +channelid_repr(PyObject *self) +{ + PyTypeObject *type = Py_TYPE(self); + const char *name = _PyType_Name(type); + + channelid *cid = (channelid *)self; + const char *fmt; + if (cid->end == CHANNEL_SEND) { + fmt = "%s(%" PRId64 ", send=True)"; + } + else if (cid->end == CHANNEL_RECV) { + fmt = "%s(%" PRId64 ", recv=True)"; + } + else { + fmt = "%s(%" PRId64 ")"; + } + return PyUnicode_FromFormat(fmt, name, cid->id); +} + +static PyObject * +channelid_str(PyObject *self) +{ + channelid *cid = (channelid *)self; + return PyUnicode_FromFormat("%" PRId64 "", cid->id); +} + +static PyObject * +channelid_int(PyObject *self) +{ + channelid *cid = (channelid *)self; + return PyLong_FromLongLong(cid->id); +} + +static Py_hash_t +channelid_hash(PyObject *self) +{ + channelid *cid = (channelid *)self; + PyObject *id = PyLong_FromLongLong(cid->id); + if (id == NULL) { + return -1; + } + Py_hash_t hash = PyObject_Hash(id); + Py_DECREF(id); + return hash; +} + +static PyObject * +channelid_richcompare(PyObject *self, PyObject *other, int op) +{ + PyObject *res = NULL; + if (op != Py_EQ && op != Py_NE) { + Py_RETURN_NOTIMPLEMENTED; + } + + PyObject *mod = get_module_from_type(Py_TYPE(self)); + if (mod == NULL) { + return NULL; + } + module_state *state = get_module_state(mod); + if (state == NULL) { + goto done; + } + + if (!PyObject_TypeCheck(self, state->ChannelIDType)) { + res = Py_NewRef(Py_NotImplemented); + goto done; + } + + channelid *cid = (channelid *)self; + int equal; + if (PyObject_TypeCheck(other, state->ChannelIDType)) { + channelid *othercid = (channelid *)other; + equal = (cid->end == othercid->end) && (cid->id == othercid->id); + } + else if (PyLong_Check(other)) { + /* Fast path */ + int overflow; + long long othercid = PyLong_AsLongLongAndOverflow(other, &overflow); + if (othercid == -1 && PyErr_Occurred()) { + goto done; + } + equal = !overflow && (othercid >= 0) && (cid->id == othercid); + } + else if (PyNumber_Check(other)) { + PyObject *pyid = PyLong_FromLongLong(cid->id); + if (pyid == NULL) { + goto done; + } + res = PyObject_RichCompare(pyid, other, op); + Py_DECREF(pyid); + goto done; + } + else { + res = Py_NewRef(Py_NotImplemented); + goto done; + } + + if ((op == Py_EQ && equal) || (op == Py_NE && !equal)) { + res = Py_NewRef(Py_True); + } + else { + res = Py_NewRef(Py_False); + } + +done: + Py_DECREF(mod); + return res; +} + +static PyObject * +_channel_from_cid(PyObject *cid, int end) +{ + PyObject *highlevel = PyImport_ImportModule("interpreters"); + if (highlevel == NULL) { + PyErr_Clear(); + highlevel = PyImport_ImportModule("test.support.interpreters"); + if (highlevel == NULL) { + return NULL; + } + } + const char *clsname = (end == CHANNEL_RECV) ? "RecvChannel" : + "SendChannel"; + PyObject *cls = PyObject_GetAttrString(highlevel, clsname); + Py_DECREF(highlevel); + if (cls == NULL) { + return NULL; + } + PyObject *chan = PyObject_CallFunctionObjArgs(cls, cid, NULL); + Py_DECREF(cls); + if (chan == NULL) { + return NULL; + } + return chan; +} + +struct _channelid_xid { + int64_t id; + int end; + int resolve; +}; + +static PyObject * +_channelid_from_xid(_PyCrossInterpreterData *data) +{ + struct _channelid_xid *xid = (struct _channelid_xid *)data->data; + + // It might not be imported yet, so we can't use _get_current_module(). + PyObject *mod = PyImport_ImportModule(MODULE_NAME); + if (mod == NULL) { + return NULL; + } + assert(mod != Py_None); + module_state *state = get_module_state(mod); + if (state == NULL) { + return NULL; + } + + // Note that we do not preserve the "resolve" flag. + PyObject *cid = NULL; + int err = newchannelid(state->ChannelIDType, xid->id, xid->end, + _global_channels(), 0, 0, + (channelid **)&cid); + if (err != 0) { + assert(cid == NULL); + (void)handle_channel_error(err, mod, xid->id); + goto done; + } + assert(cid != NULL); + if (xid->end == 0) { + goto done; + } + if (!xid->resolve) { + goto done; + } + + /* Try returning a high-level channel end but fall back to the ID. */ + PyObject *chan = _channel_from_cid(cid, xid->end); + if (chan == NULL) { + PyErr_Clear(); + goto done; + } + Py_DECREF(cid); + cid = chan; + +done: + Py_DECREF(mod); + return cid; +} + +static int +_channelid_shared(PyThreadState *tstate, PyObject *obj, + _PyCrossInterpreterData *data) +{ + if (_PyCrossInterpreterData_InitWithSize( + data, tstate->interp, sizeof(struct _channelid_xid), obj, + _channelid_from_xid + ) < 0) + { + return -1; + } + struct _channelid_xid *xid = (struct _channelid_xid *)data->data; + xid->id = ((channelid *)obj)->id; + xid->end = ((channelid *)obj)->end; + xid->resolve = ((channelid *)obj)->resolve; + return 0; +} + +static PyObject * +channelid_end(PyObject *self, void *end) +{ + int force = 1; + channelid *cid = (channelid *)self; + if (end != NULL) { + PyObject *id = NULL; + int err = newchannelid(Py_TYPE(self), cid->id, *(int *)end, + cid->channels, force, cid->resolve, + (channelid **)&id); + if (err != 0) { + assert(id == NULL); + PyObject *mod = get_module_from_type(Py_TYPE(self)); + if (mod == NULL) { + return NULL; + } + (void)handle_channel_error(err, mod, cid->id); + Py_DECREF(mod); + return NULL; + } + assert(id != NULL); + return id; + } + + if (cid->end == CHANNEL_SEND) { + return PyUnicode_InternFromString("send"); + } + if (cid->end == CHANNEL_RECV) { + return PyUnicode_InternFromString("recv"); + } + return PyUnicode_InternFromString("both"); +} + +static int _channelid_end_send = CHANNEL_SEND; +static int _channelid_end_recv = CHANNEL_RECV; + +static PyGetSetDef channelid_getsets[] = { + {"end", (getter)channelid_end, NULL, + PyDoc_STR("'send', 'recv', or 'both'")}, + {"send", (getter)channelid_end, NULL, + PyDoc_STR("the 'send' end of the channel"), &_channelid_end_send}, + {"recv", (getter)channelid_end, NULL, + PyDoc_STR("the 'recv' end of the channel"), &_channelid_end_recv}, + {NULL} +}; + +PyDoc_STRVAR(channelid_doc, +"A channel ID identifies a channel and may be used as an int."); + +static PyType_Slot ChannelIDType_slots[] = { + {Py_tp_dealloc, (destructor)channelid_dealloc}, + {Py_tp_doc, (void *)channelid_doc}, + {Py_tp_repr, (reprfunc)channelid_repr}, + {Py_tp_str, (reprfunc)channelid_str}, + {Py_tp_hash, channelid_hash}, + {Py_tp_richcompare, channelid_richcompare}, + {Py_tp_getset, channelid_getsets}, + // number slots + {Py_nb_int, (unaryfunc)channelid_int}, + {Py_nb_index, (unaryfunc)channelid_int}, + {0, NULL}, +}; + +static PyType_Spec ChannelIDType_spec = { + .name = MODULE_NAME ".ChannelID", + .basicsize = sizeof(channelid), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_DISALLOW_INSTANTIATION | Py_TPFLAGS_IMMUTABLETYPE), + .slots = ChannelIDType_slots, +}; + + +/* module level code ********************************************************/ + +/* globals is the process-global state for the module. It holds all + the data that we need to share between interpreters, so it cannot + hold PyObject values. */ +static struct globals { + int module_count; + _channels channels; +} _globals = {0}; + +static int +_globals_init(void) +{ + // XXX This isn't thread-safe. + _globals.module_count++; + if (_globals.module_count > 1) { + // Already initialized. + return 0; + } + + assert(_globals.channels.mutex == NULL); + PyThread_type_lock mutex = PyThread_allocate_lock(); + if (mutex == NULL) { + return ERR_CHANNELS_MUTEX_INIT; + } + _channels_init(&_globals.channels, mutex); + return 0; +} + +static void +_globals_fini(void) +{ + // XXX This isn't thread-safe. + _globals.module_count--; + if (_globals.module_count > 0) { + return; + } + + _channels_fini(&_globals.channels); +} + +static _channels * +_global_channels(void) { + return &_globals.channels; +} + + +static void +clear_interpreter(void *data) +{ + if (_globals.module_count == 0) { + return; + } + PyInterpreterState *interp = (PyInterpreterState *)data; + assert(interp == _get_current_interp()); + int64_t id = PyInterpreterState_GetID(interp); + _channels_drop_interpreter(&_globals.channels, id); +} + + +static PyObject * +channel_create(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + int64_t cid = _channel_create(&_globals.channels); + if (cid < 0) { + (void)handle_channel_error(-1, self, cid); + return NULL; + } + module_state *state = get_module_state(self); + if (state == NULL) { + return NULL; + } + PyObject *id = NULL; + int err = newchannelid(state->ChannelIDType, cid, 0, + &_globals.channels, 0, 0, + (channelid **)&id); + if (handle_channel_error(err, self, cid)) { + assert(id == NULL); + err = _channel_destroy(&_globals.channels, cid); + if (handle_channel_error(err, self, cid)) { + // XXX issue a warning? + } + return NULL; + } + assert(id != NULL); + assert(((channelid *)id)->channels != NULL); + return id; +} + +PyDoc_STRVAR(channel_create_doc, +"channel_create() -> cid\n\ +\n\ +Create a new cross-interpreter channel and return a unique generated ID."); + +static PyObject * +channel_destroy(PyObject *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"cid", NULL}; + int64_t cid; + struct channel_id_converter_data cid_data = { + .module = self, + }; + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&:channel_destroy", kwlist, + channel_id_converter, &cid_data)) { + return NULL; + } + cid = cid_data.cid; + + int err = _channel_destroy(&_globals.channels, cid); + if (handle_channel_error(err, self, cid)) { + return NULL; + } + Py_RETURN_NONE; +} + +PyDoc_STRVAR(channel_destroy_doc, +"channel_destroy(cid)\n\ +\n\ +Close and finalize the channel. Afterward attempts to use the channel\n\ +will behave as though it never existed."); + +static PyObject * +channel_list_all(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + int64_t count = 0; + int64_t *cids = _channels_list_all(&_globals.channels, &count); + if (cids == NULL) { + if (count == 0) { + return PyList_New(0); + } + return NULL; + } + PyObject *ids = PyList_New((Py_ssize_t)count); + if (ids == NULL) { + goto finally; + } + module_state *state = get_module_state(self); + if (state == NULL) { + Py_DECREF(ids); + ids = NULL; + goto finally; + } + int64_t *cur = cids; + for (int64_t i=0; i < count; cur++, i++) { + PyObject *id = NULL; + int err = newchannelid(state->ChannelIDType, *cur, 0, + &_globals.channels, 0, 0, + (channelid **)&id); + if (handle_channel_error(err, self, *cur)) { + assert(id == NULL); + Py_SETREF(ids, NULL); + break; + } + assert(id != NULL); + PyList_SET_ITEM(ids, (Py_ssize_t)i, id); + } + +finally: + PyMem_Free(cids); + return ids; +} + +PyDoc_STRVAR(channel_list_all_doc, +"channel_list_all() -> [cid]\n\ +\n\ +Return the list of all IDs for active channels."); + +static PyObject * +channel_list_interpreters(PyObject *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"cid", "send", NULL}; + int64_t cid; /* Channel ID */ + struct channel_id_converter_data cid_data = { + .module = self, + }; + int send = 0; /* Send or receive end? */ + int64_t id; + PyObject *ids, *id_obj; + PyInterpreterState *interp; + + if (!PyArg_ParseTupleAndKeywords( + args, kwds, "O&$p:channel_list_interpreters", + kwlist, channel_id_converter, &cid_data, &send)) { + return NULL; + } + cid = cid_data.cid; + + ids = PyList_New(0); + if (ids == NULL) { + goto except; + } + + interp = PyInterpreterState_Head(); + while (interp != NULL) { + id = PyInterpreterState_GetID(interp); + assert(id >= 0); + int res = _channel_is_associated(&_globals.channels, cid, id, send); + if (res < 0) { + (void)handle_channel_error(res, self, cid); + goto except; + } + if (res) { + id_obj = _PyInterpreterState_GetIDObject(interp); + if (id_obj == NULL) { + goto except; + } + res = PyList_Insert(ids, 0, id_obj); + Py_DECREF(id_obj); + if (res < 0) { + goto except; + } + } + interp = PyInterpreterState_Next(interp); + } + + goto finally; + +except: + Py_CLEAR(ids); + +finally: + return ids; +} + +PyDoc_STRVAR(channel_list_interpreters_doc, +"channel_list_interpreters(cid, *, send) -> [id]\n\ +\n\ +Return the list of all interpreter IDs associated with an end of the channel.\n\ +\n\ +The 'send' argument should be a boolean indicating whether to use the send or\n\ +receive end."); + + +static PyObject * +channel_send(PyObject *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"cid", "obj", NULL}; + int64_t cid; + struct channel_id_converter_data cid_data = { + .module = self, + }; + PyObject *obj; + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&O:channel_send", kwlist, + channel_id_converter, &cid_data, &obj)) { + return NULL; + } + cid = cid_data.cid; + + int err = _channel_send(&_globals.channels, cid, obj); + if (handle_channel_error(err, self, cid)) { + return NULL; + } + Py_RETURN_NONE; +} + +PyDoc_STRVAR(channel_send_doc, +"channel_send(cid, obj)\n\ +\n\ +Add the object's data to the channel's queue."); + +static PyObject * +channel_recv(PyObject *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"cid", "default", NULL}; + int64_t cid; + struct channel_id_converter_data cid_data = { + .module = self, + }; + PyObject *dflt = NULL; + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&|O:channel_recv", kwlist, + channel_id_converter, &cid_data, &dflt)) { + return NULL; + } + cid = cid_data.cid; + + PyObject *obj = NULL; + int err = _channel_recv(&_globals.channels, cid, &obj); + if (handle_channel_error(err, self, cid)) { + return NULL; + } + Py_XINCREF(dflt); + if (obj == NULL) { + // Use the default. + if (dflt == NULL) { + (void)handle_channel_error(ERR_CHANNEL_EMPTY, self, cid); + return NULL; + } + obj = Py_NewRef(dflt); + } + Py_XDECREF(dflt); + return obj; +} + +PyDoc_STRVAR(channel_recv_doc, +"channel_recv(cid, [default]) -> obj\n\ +\n\ +Return a new object from the data at the front of the channel's queue.\n\ +\n\ +If there is nothing to receive then raise ChannelEmptyError, unless\n\ +a default value is provided. In that case return it."); + +static PyObject * +channel_close(PyObject *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"cid", "send", "recv", "force", NULL}; + int64_t cid; + struct channel_id_converter_data cid_data = { + .module = self, + }; + int send = 0; + int recv = 0; + int force = 0; + if (!PyArg_ParseTupleAndKeywords(args, kwds, + "O&|$ppp:channel_close", kwlist, + channel_id_converter, &cid_data, + &send, &recv, &force)) { + return NULL; + } + cid = cid_data.cid; + + int err = _channel_close(&_globals.channels, cid, send-recv, force); + if (handle_channel_error(err, self, cid)) { + return NULL; + } + Py_RETURN_NONE; +} + +PyDoc_STRVAR(channel_close_doc, +"channel_close(cid, *, send=None, recv=None, force=False)\n\ +\n\ +Close the channel for all interpreters.\n\ +\n\ +If the channel is empty then the keyword args are ignored and both\n\ +ends are immediately closed. Otherwise, if 'force' is True then\n\ +all queued items are released and both ends are immediately\n\ +closed.\n\ +\n\ +If the channel is not empty *and* 'force' is False then following\n\ +happens:\n\ +\n\ + * recv is True (regardless of send):\n\ + - raise ChannelNotEmptyError\n\ + * recv is None and send is None:\n\ + - raise ChannelNotEmptyError\n\ + * send is True and recv is not True:\n\ + - fully close the 'send' end\n\ + - close the 'recv' end to interpreters not already receiving\n\ + - fully close it once empty\n\ +\n\ +Closing an already closed channel results in a ChannelClosedError.\n\ +\n\ +Once the channel's ID has no more ref counts in any interpreter\n\ +the channel will be destroyed."); + +static PyObject * +channel_release(PyObject *self, PyObject *args, PyObject *kwds) +{ + // Note that only the current interpreter is affected. + static char *kwlist[] = {"cid", "send", "recv", "force", NULL}; + int64_t cid; + struct channel_id_converter_data cid_data = { + .module = self, + }; + int send = 0; + int recv = 0; + int force = 0; + if (!PyArg_ParseTupleAndKeywords(args, kwds, + "O&|$ppp:channel_release", kwlist, + channel_id_converter, &cid_data, + &send, &recv, &force)) { + return NULL; + } + cid = cid_data.cid; + if (send == 0 && recv == 0) { + send = 1; + recv = 1; + } + + // XXX Handle force is True. + // XXX Fix implicit release. + + int err = _channel_drop(&_globals.channels, cid, send, recv); + if (handle_channel_error(err, self, cid)) { + return NULL; + } + Py_RETURN_NONE; +} + +PyDoc_STRVAR(channel_release_doc, +"channel_release(cid, *, send=None, recv=None, force=True)\n\ +\n\ +Close the channel for the current interpreter. 'send' and 'recv'\n\ +(bool) may be used to indicate the ends to close. By default both\n\ +ends are closed. Closing an already closed end is a noop."); + +static PyObject * +channel__channel_id(PyObject *self, PyObject *args, PyObject *kwds) +{ + module_state *state = get_module_state(self); + if (state == NULL) { + return NULL; + } + PyTypeObject *cls = state->ChannelIDType; + PyObject *mod = get_module_from_owned_type(cls); + if (mod == NULL) { + return NULL; + } + PyObject *cid = _channelid_new(mod, cls, args, kwds); + Py_DECREF(mod); + return cid; +} + +static PyMethodDef module_functions[] = { + {"create", channel_create, + METH_NOARGS, channel_create_doc}, + {"destroy", _PyCFunction_CAST(channel_destroy), + METH_VARARGS | METH_KEYWORDS, channel_destroy_doc}, + {"list_all", channel_list_all, + METH_NOARGS, channel_list_all_doc}, + {"list_interpreters", _PyCFunction_CAST(channel_list_interpreters), + METH_VARARGS | METH_KEYWORDS, channel_list_interpreters_doc}, + {"send", _PyCFunction_CAST(channel_send), + METH_VARARGS | METH_KEYWORDS, channel_send_doc}, + {"recv", _PyCFunction_CAST(channel_recv), + METH_VARARGS | METH_KEYWORDS, channel_recv_doc}, + {"close", _PyCFunction_CAST(channel_close), + METH_VARARGS | METH_KEYWORDS, channel_close_doc}, + {"release", _PyCFunction_CAST(channel_release), + METH_VARARGS | METH_KEYWORDS, channel_release_doc}, + {"_channel_id", _PyCFunction_CAST(channel__channel_id), + METH_VARARGS | METH_KEYWORDS, NULL}, + + {NULL, NULL} /* sentinel */ +}; + + +/* initialization function */ + +PyDoc_STRVAR(module_doc, +"This module provides primitive operations to manage Python interpreters.\n\ +The 'interpreters' module provides a more convenient interface."); + +static int +module_exec(PyObject *mod) +{ + if (_globals_init() != 0) { + return -1; + } + + /* Add exception types */ + if (exceptions_init(mod) != 0) { + goto error; + } + + /* Add other types */ + module_state *state = get_module_state(mod); + if (state == NULL) { + goto error; + } + + // ChannelID + state->ChannelIDType = add_new_type( + mod, &ChannelIDType_spec, _channelid_shared); + if (state->ChannelIDType == NULL) { + goto error; + } + + // Make sure chnnels drop objects owned by this interpreter + PyInterpreterState *interp = _get_current_interp(); + _Py_AtExit(interp, clear_interpreter, (void *)interp); + + return 0; + +error: + _globals_fini(); + return -1; +} + +static struct PyModuleDef_Slot module_slots[] = { + {Py_mod_exec, module_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, + {0, NULL}, +}; + +static int +module_traverse(PyObject *mod, visitproc visit, void *arg) +{ + module_state *state = get_module_state(mod); + assert(state != NULL); + traverse_module_state(state, visit, arg); + return 0; +} + +static int +module_clear(PyObject *mod) +{ + module_state *state = get_module_state(mod); + assert(state != NULL); + clear_module_state(state); + return 0; +} + +static void +module_free(void *mod) +{ + module_state *state = get_module_state(mod); + assert(state != NULL); + clear_module_state(state); + _globals_fini(); +} + +static struct PyModuleDef moduledef = { + .m_base = PyModuleDef_HEAD_INIT, + .m_name = MODULE_NAME, + .m_doc = module_doc, + .m_size = sizeof(module_state), + .m_methods = module_functions, + .m_slots = module_slots, + .m_traverse = module_traverse, + .m_clear = module_clear, + .m_free = (freefunc)module_free, +}; + +PyMODINIT_FUNC +PyInit__xxinterpchannels(void) +{ + return PyModuleDef_Init(&moduledef); +} diff --git a/Modules/_xxsubinterpretersmodule.c b/Modules/_xxsubinterpretersmodule.c index e5b96be8..4801f37d 100644 --- a/Modules/_xxsubinterpretersmodule.c +++ b/Modules/_xxsubinterpretersmodule.c @@ -1,24 +1,22 @@ /* interpreters module */ /* low-level access to interpreter primitives */ -#ifndef Py_BUILD_CORE_BUILTIN -# define Py_BUILD_CORE_MODULE 1 -#endif #include "Python.h" -#include "pycore_frame.h" -#include "pycore_pystate.h" // _PyThreadState_GET() -#include "pycore_interpreteridobject.h" +#include "interpreteridobject.h" -static char * +#define MODULE_NAME "_xxsubinterpreters" + + +static const char * _copy_raw_string(PyObject *strobj) { const char *str = PyUnicode_AsUTF8(strobj); if (str == NULL) { return NULL; } - char *copied = PyMem_Malloc(strlen(str)+1); + char *copied = PyMem_RawMalloc(strlen(str)+1); if (copied == NULL) { PyErr_NoMemory(); return NULL; @@ -28,18 +26,94 @@ _copy_raw_string(PyObject *strobj) } static PyInterpreterState * -_get_current(void) +_get_current_interp(void) { // PyInterpreterState_Get() aborts if lookup fails, so don't need // to check the result for NULL. return PyInterpreterState_Get(); } +static PyObject * +add_new_exception(PyObject *mod, const char *name, PyObject *base) +{ + assert(!PyObject_HasAttrString(mod, name)); + PyObject *exctype = PyErr_NewException(name, base, NULL); + if (exctype == NULL) { + return NULL; + } + int res = PyModule_AddType(mod, (PyTypeObject *)exctype); + if (res < 0) { + Py_DECREF(exctype); + return NULL; + } + return exctype; +} + +#define ADD_NEW_EXCEPTION(MOD, NAME, BASE) \ + add_new_exception(MOD, MODULE_NAME "." Py_STRINGIFY(NAME), BASE) + +static int +_release_xid_data(_PyCrossInterpreterData *data, int ignoreexc) +{ + PyObject *exc; + if (ignoreexc) { + exc = PyErr_GetRaisedException(); + } + int res = _PyCrossInterpreterData_Release(data); + if (res < 0) { + /* The owning interpreter is already destroyed. */ + _PyCrossInterpreterData_Clear(NULL, data); + if (ignoreexc) { + // XXX Emit a warning? + PyErr_Clear(); + } + } + if (ignoreexc) { + PyErr_SetRaisedException(exc); + } + return res; +} + + +/* module state *************************************************************/ + +typedef struct { + /* exceptions */ + PyObject *RunFailedError; +} module_state; + +static inline module_state * +get_module_state(PyObject *mod) +{ + assert(mod != NULL); + module_state *state = PyModule_GetState(mod); + assert(state != NULL); + return state; +} + +static int +traverse_module_state(module_state *state, visitproc visit, void *arg) +{ + /* exceptions */ + Py_VISIT(state->RunFailedError); + + return 0; +} + +static int +clear_module_state(module_state *state) +{ + /* exceptions */ + Py_CLEAR(state->RunFailedError); + + return 0; +} + /* data-sharing-specific code ***********************************************/ struct _sharednsitem { - char *name; + const char *name; _PyCrossInterpreterData data; }; @@ -63,10 +137,10 @@ static void _sharednsitem_clear(struct _sharednsitem *item) { if (item->name != NULL) { - PyMem_Free(item->name); + PyMem_RawFree((void *)item->name); item->name = NULL; } - _PyCrossInterpreterData_Release(&item->data); + (void)_release_xid_data(&item->data, 1); } static int @@ -169,1661 +243,119 @@ _sharedns_apply(_sharedns *shared, PyObject *ns) // of the exception in the calling interpreter. typedef struct _sharedexception { - char *name; - char *msg; + const char *name; + const char *msg; } _sharedexception; -static _sharedexception * -_sharedexception_new(void) -{ - _sharedexception *err = PyMem_NEW(_sharedexception, 1); - if (err == NULL) { - PyErr_NoMemory(); - return NULL; - } - err->name = NULL; - err->msg = NULL; - return err; -} +static const struct _sharedexception no_exception = { + .name = NULL, + .msg = NULL, +}; static void _sharedexception_clear(_sharedexception *exc) { if (exc->name != NULL) { - PyMem_Free(exc->name); + PyMem_RawFree((void *)exc->name); } if (exc->msg != NULL) { - PyMem_Free(exc->msg); - } -} - -static void -_sharedexception_free(_sharedexception *exc) -{ - _sharedexception_clear(exc); - PyMem_Free(exc); -} - -static _sharedexception * -_sharedexception_bind(PyObject *exctype, PyObject *exc, PyObject *tb) -{ - assert(exctype != NULL); - char *failure = NULL; - - _sharedexception *err = _sharedexception_new(); - if (err == NULL) { - goto finally; - } - - PyObject *name = PyUnicode_FromFormat("%S", exctype); - if (name == NULL) { - failure = "unable to format exception type name"; - goto finally; - } - err->name = _copy_raw_string(name); - Py_DECREF(name); - if (err->name == NULL) { - if (PyErr_ExceptionMatches(PyExc_MemoryError)) { - failure = "out of memory copying exception type name"; - } else { - failure = "unable to encode and copy exception type name"; - } - goto finally; - } - - if (exc != NULL) { - PyObject *msg = PyUnicode_FromFormat("%S", exc); - if (msg == NULL) { - failure = "unable to format exception message"; - goto finally; - } - err->msg = _copy_raw_string(msg); - Py_DECREF(msg); - if (err->msg == NULL) { - if (PyErr_ExceptionMatches(PyExc_MemoryError)) { - failure = "out of memory copying exception message"; - } else { - failure = "unable to encode and copy exception message"; - } - goto finally; - } - } - -finally: - if (failure != NULL) { - PyErr_Clear(); - if (err->name != NULL) { - PyMem_Free(err->name); - err->name = NULL; - } - err->msg = failure; - } - return err; -} - -static void -_sharedexception_apply(_sharedexception *exc, PyObject *wrapperclass) -{ - if (exc->name != NULL) { - if (exc->msg != NULL) { - PyErr_Format(wrapperclass, "%s: %s", exc->name, exc->msg); - } - else { - PyErr_SetString(wrapperclass, exc->name); - } - } - else if (exc->msg != NULL) { - PyErr_SetString(wrapperclass, exc->msg); - } - else { - PyErr_SetNone(wrapperclass); - } -} - - -/* channel-specific code ****************************************************/ - -#define CHANNEL_SEND 1 -#define CHANNEL_BOTH 0 -#define CHANNEL_RECV -1 - -static PyObject *ChannelError; -static PyObject *ChannelNotFoundError; -static PyObject *ChannelClosedError; -static PyObject *ChannelEmptyError; -static PyObject *ChannelNotEmptyError; - -static int -channel_exceptions_init(PyObject *ns) -{ - // XXX Move the exceptions into per-module memory? - - // A channel-related operation failed. - ChannelError = PyErr_NewException("_xxsubinterpreters.ChannelError", - PyExc_RuntimeError, NULL); - if (ChannelError == NULL) { - return -1; - } - if (PyDict_SetItemString(ns, "ChannelError", ChannelError) != 0) { - return -1; - } - - // An operation tried to use a channel that doesn't exist. - ChannelNotFoundError = PyErr_NewException( - "_xxsubinterpreters.ChannelNotFoundError", ChannelError, NULL); - if (ChannelNotFoundError == NULL) { - return -1; - } - if (PyDict_SetItemString(ns, "ChannelNotFoundError", ChannelNotFoundError) != 0) { - return -1; - } - - // An operation tried to use a closed channel. - ChannelClosedError = PyErr_NewException( - "_xxsubinterpreters.ChannelClosedError", ChannelError, NULL); - if (ChannelClosedError == NULL) { - return -1; - } - if (PyDict_SetItemString(ns, "ChannelClosedError", ChannelClosedError) != 0) { - return -1; - } - - // An operation tried to pop from an empty channel. - ChannelEmptyError = PyErr_NewException( - "_xxsubinterpreters.ChannelEmptyError", ChannelError, NULL); - if (ChannelEmptyError == NULL) { - return -1; - } - if (PyDict_SetItemString(ns, "ChannelEmptyError", ChannelEmptyError) != 0) { - return -1; - } - - // An operation tried to close a non-empty channel. - ChannelNotEmptyError = PyErr_NewException( - "_xxsubinterpreters.ChannelNotEmptyError", ChannelError, NULL); - if (ChannelNotEmptyError == NULL) { - return -1; - } - if (PyDict_SetItemString(ns, "ChannelNotEmptyError", ChannelNotEmptyError) != 0) { - return -1; - } - - return 0; -} - -/* the channel queue */ - -struct _channelitem; - -typedef struct _channelitem { - _PyCrossInterpreterData *data; - struct _channelitem *next; -} _channelitem; - -static _channelitem * -_channelitem_new(void) -{ - _channelitem *item = PyMem_NEW(_channelitem, 1); - if (item == NULL) { - PyErr_NoMemory(); - return NULL; - } - item->data = NULL; - item->next = NULL; - return item; -} - -static void -_channelitem_clear(_channelitem *item) -{ - if (item->data != NULL) { - _PyCrossInterpreterData_Release(item->data); - PyMem_Free(item->data); - item->data = NULL; - } - item->next = NULL; -} - -static void -_channelitem_free(_channelitem *item) -{ - _channelitem_clear(item); - PyMem_Free(item); -} - -static void -_channelitem_free_all(_channelitem *item) -{ - while (item != NULL) { - _channelitem *last = item; - item = item->next; - _channelitem_free(last); - } -} - -static _PyCrossInterpreterData * -_channelitem_popped(_channelitem *item) -{ - _PyCrossInterpreterData *data = item->data; - item->data = NULL; - _channelitem_free(item); - return data; -} - -typedef struct _channelqueue { - int64_t count; - _channelitem *first; - _channelitem *last; -} _channelqueue; - -static _channelqueue * -_channelqueue_new(void) -{ - _channelqueue *queue = PyMem_NEW(_channelqueue, 1); - if (queue == NULL) { - PyErr_NoMemory(); - return NULL; - } - queue->count = 0; - queue->first = NULL; - queue->last = NULL; - return queue; -} - -static void -_channelqueue_clear(_channelqueue *queue) -{ - _channelitem_free_all(queue->first); - queue->count = 0; - queue->first = NULL; - queue->last = NULL; -} - -static void -_channelqueue_free(_channelqueue *queue) -{ - _channelqueue_clear(queue); - PyMem_Free(queue); -} - -static int -_channelqueue_put(_channelqueue *queue, _PyCrossInterpreterData *data) -{ - _channelitem *item = _channelitem_new(); - if (item == NULL) { - return -1; - } - item->data = data; - - queue->count += 1; - if (queue->first == NULL) { - queue->first = item; - } - else { - queue->last->next = item; - } - queue->last = item; - return 0; -} - -static _PyCrossInterpreterData * -_channelqueue_get(_channelqueue *queue) -{ - _channelitem *item = queue->first; - if (item == NULL) { - return NULL; - } - queue->first = item->next; - if (queue->last == item) { - queue->last = NULL; - } - queue->count -= 1; - - return _channelitem_popped(item); -} - -/* channel-interpreter associations */ - -struct _channelend; - -typedef struct _channelend { - struct _channelend *next; - int64_t interp; - int open; -} _channelend; - -static _channelend * -_channelend_new(int64_t interp) -{ - _channelend *end = PyMem_NEW(_channelend, 1); - if (end == NULL) { - PyErr_NoMemory(); - return NULL; - } - end->next = NULL; - end->interp = interp; - end->open = 1; - return end; -} - -static void -_channelend_free(_channelend *end) -{ - PyMem_Free(end); -} - -static void -_channelend_free_all(_channelend *end) -{ - while (end != NULL) { - _channelend *last = end; - end = end->next; - _channelend_free(last); - } -} - -static _channelend * -_channelend_find(_channelend *first, int64_t interp, _channelend **pprev) -{ - _channelend *prev = NULL; - _channelend *end = first; - while (end != NULL) { - if (end->interp == interp) { - break; - } - prev = end; - end = end->next; - } - if (pprev != NULL) { - *pprev = prev; - } - return end; -} - -typedef struct _channelassociations { - // Note that the list entries are never removed for interpreter - // for which the channel is closed. This should not be a problem in - // practice. Also, a channel isn't automatically closed when an - // interpreter is destroyed. - int64_t numsendopen; - int64_t numrecvopen; - _channelend *send; - _channelend *recv; -} _channelends; - -static _channelends * -_channelends_new(void) -{ - _channelends *ends = PyMem_NEW(_channelends, 1); - if (ends== NULL) { - return NULL; - } - ends->numsendopen = 0; - ends->numrecvopen = 0; - ends->send = NULL; - ends->recv = NULL; - return ends; -} - -static void -_channelends_clear(_channelends *ends) -{ - _channelend_free_all(ends->send); - ends->send = NULL; - ends->numsendopen = 0; - - _channelend_free_all(ends->recv); - ends->recv = NULL; - ends->numrecvopen = 0; -} - -static void -_channelends_free(_channelends *ends) -{ - _channelends_clear(ends); - PyMem_Free(ends); -} - -static _channelend * -_channelends_add(_channelends *ends, _channelend *prev, int64_t interp, - int send) -{ - _channelend *end = _channelend_new(interp); - if (end == NULL) { - return NULL; - } - - if (prev == NULL) { - if (send) { - ends->send = end; - } - else { - ends->recv = end; - } - } - else { - prev->next = end; - } - if (send) { - ends->numsendopen += 1; + PyMem_RawFree((void *)exc->msg); } - else { - ends->numrecvopen += 1; - } - return end; } -static int -_channelends_associate(_channelends *ends, int64_t interp, int send) -{ - _channelend *prev; - _channelend *end = _channelend_find(send ? ends->send : ends->recv, - interp, &prev); - if (end != NULL) { - if (!end->open) { - PyErr_SetString(ChannelClosedError, "channel already closed"); - return -1; - } - // already associated - return 0; - } - if (_channelends_add(ends, prev, interp, send) == NULL) { - return -1; - } - return 0; -} - -static int -_channelends_is_open(_channelends *ends) -{ - if (ends->numsendopen != 0 || ends->numrecvopen != 0) { - return 1; - } - if (ends->send == NULL && ends->recv == NULL) { - return 1; - } - return 0; -} - -static void -_channelends_close_end(_channelends *ends, _channelend *end, int send) -{ - end->open = 0; - if (send) { - ends->numsendopen -= 1; - } - else { - ends->numrecvopen -= 1; - } -} - -static int -_channelends_close_interpreter(_channelends *ends, int64_t interp, int which) -{ - _channelend *prev; - _channelend *end; - if (which >= 0) { // send/both - end = _channelend_find(ends->send, interp, &prev); - if (end == NULL) { - // never associated so add it - end = _channelends_add(ends, prev, interp, 1); - if (end == NULL) { - return -1; - } - } - _channelends_close_end(ends, end, 1); - } - if (which <= 0) { // recv/both - end = _channelend_find(ends->recv, interp, &prev); - if (end == NULL) { - // never associated so add it - end = _channelends_add(ends, prev, interp, 0); - if (end == NULL) { - return -1; - } - } - _channelends_close_end(ends, end, 0); - } - return 0; -} - -static void -_channelends_close_all(_channelends *ends, int which, int force) -{ - // XXX Handle the ends. - // XXX Handle force is True. - - // Ensure all the "send"-associated interpreters are closed. - _channelend *end; - for (end = ends->send; end != NULL; end = end->next) { - _channelends_close_end(ends, end, 1); - } - - // Ensure all the "recv"-associated interpreters are closed. - for (end = ends->recv; end != NULL; end = end->next) { - _channelends_close_end(ends, end, 0); - } -} - -/* channels */ - -struct _channel; -struct _channel_closing; -static void _channel_clear_closing(struct _channel *); -static void _channel_finish_closing(struct _channel *); - -typedef struct _channel { - PyThread_type_lock mutex; - _channelqueue *queue; - _channelends *ends; - int open; - struct _channel_closing *closing; -} _PyChannelState; - -static _PyChannelState * -_channel_new(void) -{ - _PyChannelState *chan = PyMem_NEW(_PyChannelState, 1); - if (chan == NULL) { - return NULL; - } - chan->mutex = PyThread_allocate_lock(); - if (chan->mutex == NULL) { - PyMem_Free(chan); - PyErr_SetString(ChannelError, - "can't initialize mutex for new channel"); - return NULL; - } - chan->queue = _channelqueue_new(); - if (chan->queue == NULL) { - PyMem_Free(chan); - return NULL; - } - chan->ends = _channelends_new(); - if (chan->ends == NULL) { - _channelqueue_free(chan->queue); - PyMem_Free(chan); - return NULL; - } - chan->open = 1; - chan->closing = NULL; - return chan; -} - -static void -_channel_free(_PyChannelState *chan) -{ - _channel_clear_closing(chan); - PyThread_acquire_lock(chan->mutex, WAIT_LOCK); - _channelqueue_free(chan->queue); - _channelends_free(chan->ends); - PyThread_release_lock(chan->mutex); - - PyThread_free_lock(chan->mutex); - PyMem_Free(chan); -} - -static int -_channel_add(_PyChannelState *chan, int64_t interp, - _PyCrossInterpreterData *data) -{ - int res = -1; - PyThread_acquire_lock(chan->mutex, WAIT_LOCK); - - if (!chan->open) { - PyErr_SetString(ChannelClosedError, "channel closed"); - goto done; - } - if (_channelends_associate(chan->ends, interp, 1) != 0) { - goto done; - } - - if (_channelqueue_put(chan->queue, data) != 0) { - goto done; - } - - res = 0; -done: - PyThread_release_lock(chan->mutex); - return res; -} - -static _PyCrossInterpreterData * -_channel_next(_PyChannelState *chan, int64_t interp) -{ - _PyCrossInterpreterData *data = NULL; - PyThread_acquire_lock(chan->mutex, WAIT_LOCK); - - if (!chan->open) { - PyErr_SetString(ChannelClosedError, "channel closed"); - goto done; - } - if (_channelends_associate(chan->ends, interp, 0) != 0) { - goto done; - } - - data = _channelqueue_get(chan->queue); - if (data == NULL && !PyErr_Occurred() && chan->closing != NULL) { - chan->open = 0; - } - -done: - PyThread_release_lock(chan->mutex); - if (chan->queue->count == 0) { - _channel_finish_closing(chan); - } - return data; -} - -static int -_channel_close_interpreter(_PyChannelState *chan, int64_t interp, int end) -{ - PyThread_acquire_lock(chan->mutex, WAIT_LOCK); - - int res = -1; - if (!chan->open) { - PyErr_SetString(ChannelClosedError, "channel already closed"); - goto done; - } - - if (_channelends_close_interpreter(chan->ends, interp, end) != 0) { - goto done; - } - chan->open = _channelends_is_open(chan->ends); - - res = 0; -done: - PyThread_release_lock(chan->mutex); - return res; -} - -static int -_channel_close_all(_PyChannelState *chan, int end, int force) -{ - int res = -1; - PyThread_acquire_lock(chan->mutex, WAIT_LOCK); - - if (!chan->open) { - PyErr_SetString(ChannelClosedError, "channel already closed"); - goto done; - } - - if (!force && chan->queue->count > 0) { - PyErr_SetString(ChannelNotEmptyError, - "may not be closed if not empty (try force=True)"); - goto done; - } - - chan->open = 0; - - // We *could* also just leave these in place, since we've marked - // the channel as closed already. - _channelends_close_all(chan->ends, end, force); - - res = 0; -done: - PyThread_release_lock(chan->mutex); - return res; -} - -/* the set of channels */ - -struct _channelref; - -typedef struct _channelref { - int64_t id; - _PyChannelState *chan; - struct _channelref *next; - Py_ssize_t objcount; -} _channelref; - -static _channelref * -_channelref_new(int64_t id, _PyChannelState *chan) -{ - _channelref *ref = PyMem_NEW(_channelref, 1); - if (ref == NULL) { - return NULL; - } - ref->id = id; - ref->chan = chan; - ref->next = NULL; - ref->objcount = 0; - return ref; -} - -//static void -//_channelref_clear(_channelref *ref) -//{ -// ref->id = -1; -// ref->chan = NULL; -// ref->next = NULL; -// ref->objcount = 0; -//} - -static void -_channelref_free(_channelref *ref) -{ - if (ref->chan != NULL) { - _channel_clear_closing(ref->chan); - } - //_channelref_clear(ref); - PyMem_Free(ref); -} - -static _channelref * -_channelref_find(_channelref *first, int64_t id, _channelref **pprev) -{ - _channelref *prev = NULL; - _channelref *ref = first; - while (ref != NULL) { - if (ref->id == id) { - break; - } - prev = ref; - ref = ref->next; - } - if (pprev != NULL) { - *pprev = prev; - } - return ref; -} - -typedef struct _channels { - PyThread_type_lock mutex; - _channelref *head; - int64_t numopen; - int64_t next_id; -} _channels; - -static int -_channels_init(_channels *channels) -{ - if (channels->mutex == NULL) { - channels->mutex = PyThread_allocate_lock(); - if (channels->mutex == NULL) { - PyErr_SetString(ChannelError, - "can't initialize mutex for channel management"); - return -1; - } - } - channels->head = NULL; - channels->numopen = 0; - channels->next_id = 0; - return 0; -} - -static int64_t -_channels_next_id(_channels *channels) // needs lock -{ - int64_t id = channels->next_id; - if (id < 0) { - /* overflow */ - PyErr_SetString(ChannelError, - "failed to get a channel ID"); - return -1; - } - channels->next_id += 1; - return id; -} - -static _PyChannelState * -_channels_lookup(_channels *channels, int64_t id, PyThread_type_lock *pmutex) -{ - _PyChannelState *chan = NULL; - PyThread_acquire_lock(channels->mutex, WAIT_LOCK); - if (pmutex != NULL) { - *pmutex = NULL; - } - - _channelref *ref = _channelref_find(channels->head, id, NULL); - if (ref == NULL) { - PyErr_Format(ChannelNotFoundError, "channel %" PRId64 " not found", id); - goto done; - } - if (ref->chan == NULL || !ref->chan->open) { - PyErr_Format(ChannelClosedError, "channel %" PRId64 " closed", id); - goto done; - } - - if (pmutex != NULL) { - // The mutex will be closed by the caller. - *pmutex = channels->mutex; - } - - chan = ref->chan; -done: - if (pmutex == NULL || *pmutex == NULL) { - PyThread_release_lock(channels->mutex); - } - return chan; -} - -static int64_t -_channels_add(_channels *channels, _PyChannelState *chan) -{ - int64_t cid = -1; - PyThread_acquire_lock(channels->mutex, WAIT_LOCK); - - // Create a new ref. - int64_t id = _channels_next_id(channels); - if (id < 0) { - goto done; - } - _channelref *ref = _channelref_new(id, chan); - if (ref == NULL) { - goto done; - } - - // Add it to the list. - // We assume that the channel is a new one (not already in the list). - ref->next = channels->head; - channels->head = ref; - channels->numopen += 1; - - cid = id; -done: - PyThread_release_lock(channels->mutex); - return cid; -} - -/* forward */ -static int _channel_set_closing(struct _channelref *, PyThread_type_lock); - -static int -_channels_close(_channels *channels, int64_t cid, _PyChannelState **pchan, - int end, int force) -{ - int res = -1; - PyThread_acquire_lock(channels->mutex, WAIT_LOCK); - if (pchan != NULL) { - *pchan = NULL; - } - - _channelref *ref = _channelref_find(channels->head, cid, NULL); - if (ref == NULL) { - PyErr_Format(ChannelNotFoundError, "channel %" PRId64 " not found", cid); - goto done; - } - - if (ref->chan == NULL) { - PyErr_Format(ChannelClosedError, "channel %" PRId64 " closed", cid); - goto done; - } - else if (!force && end == CHANNEL_SEND && ref->chan->closing != NULL) { - PyErr_Format(ChannelClosedError, "channel %" PRId64 " closed", cid); - goto done; - } - else { - if (_channel_close_all(ref->chan, end, force) != 0) { - if (end == CHANNEL_SEND && - PyErr_ExceptionMatches(ChannelNotEmptyError)) { - if (ref->chan->closing != NULL) { - PyErr_Format(ChannelClosedError, - "channel %" PRId64 " closed", cid); - goto done; - } - // Mark the channel as closing and return. The channel - // will be cleaned up in _channel_next(). - PyErr_Clear(); - if (_channel_set_closing(ref, channels->mutex) != 0) { - goto done; - } - if (pchan != NULL) { - *pchan = ref->chan; - } - res = 0; - } - goto done; - } - if (pchan != NULL) { - *pchan = ref->chan; - } - else { - _channel_free(ref->chan); - } - ref->chan = NULL; - } - - res = 0; -done: - PyThread_release_lock(channels->mutex); - return res; -} - -static void -_channels_remove_ref(_channels *channels, _channelref *ref, _channelref *prev, - _PyChannelState **pchan) -{ - if (ref == channels->head) { - channels->head = ref->next; - } - else { - prev->next = ref->next; - } - channels->numopen -= 1; - - if (pchan != NULL) { - *pchan = ref->chan; - } - _channelref_free(ref); -} - -static int -_channels_remove(_channels *channels, int64_t id, _PyChannelState **pchan) -{ - int res = -1; - PyThread_acquire_lock(channels->mutex, WAIT_LOCK); - - if (pchan != NULL) { - *pchan = NULL; - } - - _channelref *prev = NULL; - _channelref *ref = _channelref_find(channels->head, id, &prev); - if (ref == NULL) { - PyErr_Format(ChannelNotFoundError, "channel %" PRId64 " not found", id); - goto done; - } - - _channels_remove_ref(channels, ref, prev, pchan); - - res = 0; -done: - PyThread_release_lock(channels->mutex); - return res; -} - -static int -_channels_add_id_object(_channels *channels, int64_t id) -{ - int res = -1; - PyThread_acquire_lock(channels->mutex, WAIT_LOCK); - - _channelref *ref = _channelref_find(channels->head, id, NULL); - if (ref == NULL) { - PyErr_Format(ChannelNotFoundError, "channel %" PRId64 " not found", id); - goto done; - } - ref->objcount += 1; - - res = 0; -done: - PyThread_release_lock(channels->mutex); - return res; -} - -static void -_channels_drop_id_object(_channels *channels, int64_t id) -{ - PyThread_acquire_lock(channels->mutex, WAIT_LOCK); - - _channelref *prev = NULL; - _channelref *ref = _channelref_find(channels->head, id, &prev); - if (ref == NULL) { - // Already destroyed. - goto done; - } - ref->objcount -= 1; - - // Destroy if no longer used. - if (ref->objcount == 0) { - _PyChannelState *chan = NULL; - _channels_remove_ref(channels, ref, prev, &chan); - if (chan != NULL) { - _channel_free(chan); - } - } - -done: - PyThread_release_lock(channels->mutex); -} - -static int64_t * -_channels_list_all(_channels *channels, int64_t *count) -{ - int64_t *cids = NULL; - PyThread_acquire_lock(channels->mutex, WAIT_LOCK); - int64_t *ids = PyMem_NEW(int64_t, (Py_ssize_t)(channels->numopen)); - if (ids == NULL) { - goto done; - } - _channelref *ref = channels->head; - for (int64_t i=0; ref != NULL; ref = ref->next, i++) { - ids[i] = ref->id; - } - *count = channels->numopen; - - cids = ids; -done: - PyThread_release_lock(channels->mutex); - return cids; -} - -/* support for closing non-empty channels */ - -struct _channel_closing { - struct _channelref *ref; -}; - -static int -_channel_set_closing(struct _channelref *ref, PyThread_type_lock mutex) { - struct _channel *chan = ref->chan; - if (chan == NULL) { - // already closed - return 0; - } - int res = -1; - PyThread_acquire_lock(chan->mutex, WAIT_LOCK); - if (chan->closing != NULL) { - PyErr_SetString(ChannelClosedError, "channel closed"); - goto done; - } - chan->closing = PyMem_NEW(struct _channel_closing, 1); - if (chan->closing == NULL) { - goto done; - } - chan->closing->ref = ref; - - res = 0; -done: - PyThread_release_lock(chan->mutex); - return res; -} - -static void -_channel_clear_closing(struct _channel *chan) { - PyThread_acquire_lock(chan->mutex, WAIT_LOCK); - if (chan->closing != NULL) { - PyMem_Free(chan->closing); - chan->closing = NULL; - } - PyThread_release_lock(chan->mutex); -} - -static void -_channel_finish_closing(struct _channel *chan) { - struct _channel_closing *closing = chan->closing; - if (closing == NULL) { - return; - } - _channelref *ref = closing->ref; - _channel_clear_closing(chan); - // Do the things that would have been done in _channels_close(). - ref->chan = NULL; - _channel_free(chan); -} - -/* "high"-level channel-related functions */ - -static int64_t -_channel_create(_channels *channels) -{ - _PyChannelState *chan = _channel_new(); - if (chan == NULL) { - return -1; - } - int64_t id = _channels_add(channels, chan); - if (id < 0) { - _channel_free(chan); - return -1; - } - return id; -} - -static int -_channel_destroy(_channels *channels, int64_t id) -{ - _PyChannelState *chan = NULL; - if (_channels_remove(channels, id, &chan) != 0) { - return -1; - } - if (chan != NULL) { - _channel_free(chan); - } - return 0; -} - -static int -_channel_send(_channels *channels, int64_t id, PyObject *obj) -{ - PyInterpreterState *interp = _get_current(); - if (interp == NULL) { - return -1; - } - - // Look up the channel. - PyThread_type_lock mutex = NULL; - _PyChannelState *chan = _channels_lookup(channels, id, &mutex); - if (chan == NULL) { - return -1; - } - // Past this point we are responsible for releasing the mutex. - - if (chan->closing != NULL) { - PyErr_Format(ChannelClosedError, "channel %" PRId64 " closed", id); - PyThread_release_lock(mutex); - return -1; - } - - // Convert the object to cross-interpreter data. - _PyCrossInterpreterData *data = PyMem_NEW(_PyCrossInterpreterData, 1); - if (data == NULL) { - PyThread_release_lock(mutex); - return -1; - } - if (_PyObject_GetCrossInterpreterData(obj, data) != 0) { - PyThread_release_lock(mutex); - PyMem_Free(data); - return -1; - } - - // Add the data to the channel. - int res = _channel_add(chan, PyInterpreterState_GetID(interp), data); - PyThread_release_lock(mutex); - if (res != 0) { - _PyCrossInterpreterData_Release(data); - PyMem_Free(data); - return -1; - } - - return 0; -} - -static PyObject * -_channel_recv(_channels *channels, int64_t id) -{ - PyInterpreterState *interp = _get_current(); - if (interp == NULL) { - return NULL; - } - - // Look up the channel. - PyThread_type_lock mutex = NULL; - _PyChannelState *chan = _channels_lookup(channels, id, &mutex); - if (chan == NULL) { - return NULL; - } - // Past this point we are responsible for releasing the mutex. - - // Pop off the next item from the channel. - _PyCrossInterpreterData *data = _channel_next(chan, PyInterpreterState_GetID(interp)); - PyThread_release_lock(mutex); - if (data == NULL) { - return NULL; - } - - // Convert the data back to an object. - PyObject *obj = _PyCrossInterpreterData_NewObject(data); - _PyCrossInterpreterData_Release(data); - PyMem_Free(data); - if (obj == NULL) { - return NULL; - } - - return obj; -} - -static int -_channel_drop(_channels *channels, int64_t id, int send, int recv) -{ - PyInterpreterState *interp = _get_current(); - if (interp == NULL) { - return -1; - } - - // Look up the channel. - PyThread_type_lock mutex = NULL; - _PyChannelState *chan = _channels_lookup(channels, id, &mutex); - if (chan == NULL) { - return -1; - } - // Past this point we are responsible for releasing the mutex. - - // Close one or both of the two ends. - int res = _channel_close_interpreter(chan, PyInterpreterState_GetID(interp), send-recv); - PyThread_release_lock(mutex); - return res; -} - -static int -_channel_close(_channels *channels, int64_t id, int end, int force) -{ - return _channels_close(channels, id, NULL, end, force); -} - -static int -_channel_is_associated(_channels *channels, int64_t cid, int64_t interp, - int send) -{ - _PyChannelState *chan = _channels_lookup(channels, cid, NULL); - if (chan == NULL) { - return -1; - } else if (send && chan->closing != NULL) { - PyErr_Format(ChannelClosedError, "channel %" PRId64 " closed", cid); - return -1; - } - - _channelend *end = _channelend_find(send ? chan->ends->send : chan->ends->recv, - interp, NULL); - - return (end != NULL && end->open); -} - -/* ChannelID class */ - -static PyTypeObject ChannelIDtype; - -typedef struct channelid { - PyObject_HEAD - int64_t id; - int end; - int resolve; - _channels *channels; -} channelid; - -static int -channel_id_converter(PyObject *arg, void *ptr) -{ - int64_t cid; - if (PyObject_TypeCheck(arg, &ChannelIDtype)) { - cid = ((channelid *)arg)->id; - } - else if (PyIndex_Check(arg)) { - cid = PyLong_AsLongLong(arg); - if (cid == -1 && PyErr_Occurred()) { - return 0; - } - if (cid < 0) { - PyErr_Format(PyExc_ValueError, - "channel ID must be a non-negative int, got %R", arg); - return 0; - } - } - else { - PyErr_Format(PyExc_TypeError, - "channel ID must be an int, got %.100s", - Py_TYPE(arg)->tp_name); - return 0; - } - *(int64_t *)ptr = cid; - return 1; -} - -static channelid * -newchannelid(PyTypeObject *cls, int64_t cid, int end, _channels *channels, - int force, int resolve) -{ - channelid *self = PyObject_New(channelid, cls); - if (self == NULL) { - return NULL; - } - self->id = cid; - self->end = end; - self->resolve = resolve; - self->channels = channels; - - if (_channels_add_id_object(channels, cid) != 0) { - if (force && PyErr_ExceptionMatches(ChannelNotFoundError)) { - PyErr_Clear(); - } - else { - Py_DECREF((PyObject *)self); - return NULL; - } - } - - return self; -} - -static _channels * _global_channels(void); - -static PyObject * -channelid_new(PyTypeObject *cls, PyObject *args, PyObject *kwds) -{ - static char *kwlist[] = {"id", "send", "recv", "force", "_resolve", NULL}; - int64_t cid; - int send = -1; - int recv = -1; - int force = 0; - int resolve = 0; - if (!PyArg_ParseTupleAndKeywords(args, kwds, - "O&|$pppp:ChannelID.__new__", kwlist, - channel_id_converter, &cid, &send, &recv, &force, &resolve)) - return NULL; - - // Handle "send" and "recv". - if (send == 0 && recv == 0) { - PyErr_SetString(PyExc_ValueError, - "'send' and 'recv' cannot both be False"); - return NULL; - } - - int end = 0; - if (send == 1) { - if (recv == 0 || recv == -1) { - end = CHANNEL_SEND; - } - } - else if (recv == 1) { - end = CHANNEL_RECV; - } - - return (PyObject *)newchannelid(cls, cid, end, _global_channels(), - force, resolve); -} - -static void -channelid_dealloc(PyObject *v) -{ - int64_t cid = ((channelid *)v)->id; - _channels *channels = ((channelid *)v)->channels; - Py_TYPE(v)->tp_free(v); - - _channels_drop_id_object(channels, cid); -} - -static PyObject * -channelid_repr(PyObject *self) -{ - PyTypeObject *type = Py_TYPE(self); - const char *name = _PyType_Name(type); - - channelid *cid = (channelid *)self; - const char *fmt; - if (cid->end == CHANNEL_SEND) { - fmt = "%s(%" PRId64 ", send=True)"; - } - else if (cid->end == CHANNEL_RECV) { - fmt = "%s(%" PRId64 ", recv=True)"; - } - else { - fmt = "%s(%" PRId64 ")"; - } - return PyUnicode_FromFormat(fmt, name, cid->id); -} - -static PyObject * -channelid_str(PyObject *self) -{ - channelid *cid = (channelid *)self; - return PyUnicode_FromFormat("%" PRId64 "", cid->id); -} - -static PyObject * -channelid_int(PyObject *self) -{ - channelid *cid = (channelid *)self; - return PyLong_FromLongLong(cid->id); -} - -static PyNumberMethods channelid_as_number = { - 0, /* nb_add */ - 0, /* nb_subtract */ - 0, /* nb_multiply */ - 0, /* nb_remainder */ - 0, /* nb_divmod */ - 0, /* nb_power */ - 0, /* nb_negative */ - 0, /* nb_positive */ - 0, /* nb_absolute */ - 0, /* nb_bool */ - 0, /* nb_invert */ - 0, /* nb_lshift */ - 0, /* nb_rshift */ - 0, /* nb_and */ - 0, /* nb_xor */ - 0, /* nb_or */ - (unaryfunc)channelid_int, /* nb_int */ - 0, /* nb_reserved */ - 0, /* nb_float */ - - 0, /* nb_inplace_add */ - 0, /* nb_inplace_subtract */ - 0, /* nb_inplace_multiply */ - 0, /* nb_inplace_remainder */ - 0, /* nb_inplace_power */ - 0, /* nb_inplace_lshift */ - 0, /* nb_inplace_rshift */ - 0, /* nb_inplace_and */ - 0, /* nb_inplace_xor */ - 0, /* nb_inplace_or */ - - 0, /* nb_floor_divide */ - 0, /* nb_true_divide */ - 0, /* nb_inplace_floor_divide */ - 0, /* nb_inplace_true_divide */ - - (unaryfunc)channelid_int, /* nb_index */ -}; - -static Py_hash_t -channelid_hash(PyObject *self) -{ - channelid *cid = (channelid *)self; - PyObject *id = PyLong_FromLongLong(cid->id); - if (id == NULL) { - return -1; - } - Py_hash_t hash = PyObject_Hash(id); - Py_DECREF(id); - return hash; -} - -static PyObject * -channelid_richcompare(PyObject *self, PyObject *other, int op) -{ - if (op != Py_EQ && op != Py_NE) { - Py_RETURN_NOTIMPLEMENTED; - } - - if (!PyObject_TypeCheck(self, &ChannelIDtype)) { - Py_RETURN_NOTIMPLEMENTED; - } - - channelid *cid = (channelid *)self; - int equal; - if (PyObject_TypeCheck(other, &ChannelIDtype)) { - channelid *othercid = (channelid *)other; - equal = (cid->end == othercid->end) && (cid->id == othercid->id); - } - else if (PyLong_Check(other)) { - /* Fast path */ - int overflow; - long long othercid = PyLong_AsLongLongAndOverflow(other, &overflow); - if (othercid == -1 && PyErr_Occurred()) { - return NULL; - } - equal = !overflow && (othercid >= 0) && (cid->id == othercid); - } - else if (PyNumber_Check(other)) { - PyObject *pyid = PyLong_FromLongLong(cid->id); - if (pyid == NULL) { - return NULL; - } - PyObject *res = PyObject_RichCompare(pyid, other, op); - Py_DECREF(pyid); - return res; - } - else { - Py_RETURN_NOTIMPLEMENTED; - } - - if ((op == Py_EQ && equal) || (op == Py_NE && !equal)) { - Py_RETURN_TRUE; - } - Py_RETURN_FALSE; -} - -static PyObject * -_channel_from_cid(PyObject *cid, int end) -{ - PyObject *highlevel = PyImport_ImportModule("interpreters"); - if (highlevel == NULL) { - PyErr_Clear(); - highlevel = PyImport_ImportModule("test.support.interpreters"); - if (highlevel == NULL) { - return NULL; - } - } - const char *clsname = (end == CHANNEL_RECV) ? "RecvChannel" : - "SendChannel"; - PyObject *cls = PyObject_GetAttrString(highlevel, clsname); - Py_DECREF(highlevel); - if (cls == NULL) { - return NULL; - } - PyObject *chan = PyObject_CallFunctionObjArgs(cls, cid, NULL); - Py_DECREF(cls); - if (chan == NULL) { - return NULL; - } - return chan; -} - -struct _channelid_xid { - int64_t id; - int end; - int resolve; -}; - -static PyObject * -_channelid_from_xid(_PyCrossInterpreterData *data) +static const char * +_sharedexception_bind(PyObject *exc, _sharedexception *sharedexc) { - struct _channelid_xid *xid = (struct _channelid_xid *)data->data; - // Note that we do not preserve the "resolve" flag. - PyObject *cid = (PyObject *)newchannelid(&ChannelIDtype, xid->id, xid->end, - _global_channels(), 0, 0); - if (xid->end == 0) { - return cid; + assert(exc != NULL); + const char *failure = NULL; + + PyObject *nameobj = PyUnicode_FromFormat("%S", Py_TYPE(exc)); + if (nameobj == NULL) { + failure = "unable to format exception type name"; + goto error; } - if (!xid->resolve) { - return cid; + sharedexc->name = _copy_raw_string(nameobj); + Py_DECREF(nameobj); + if (sharedexc->name == NULL) { + if (PyErr_ExceptionMatches(PyExc_MemoryError)) { + failure = "out of memory copying exception type name"; + } else { + failure = "unable to encode and copy exception type name"; + } + goto error; } - /* Try returning a high-level channel end but fall back to the ID. */ - PyObject *chan = _channel_from_cid(cid, xid->end); - if (chan == NULL) { - PyErr_Clear(); - return cid; + if (exc != NULL) { + PyObject *msgobj = PyUnicode_FromFormat("%S", exc); + if (msgobj == NULL) { + failure = "unable to format exception message"; + goto error; + } + sharedexc->msg = _copy_raw_string(msgobj); + Py_DECREF(msgobj); + if (sharedexc->msg == NULL) { + if (PyErr_ExceptionMatches(PyExc_MemoryError)) { + failure = "out of memory copying exception message"; + } else { + failure = "unable to encode and copy exception message"; + } + goto error; + } } - Py_DECREF(cid); - return chan; -} -static int -_channelid_shared(PyObject *obj, _PyCrossInterpreterData *data) -{ - struct _channelid_xid *xid = PyMem_NEW(struct _channelid_xid, 1); - if (xid == NULL) { - return -1; - } - xid->id = ((channelid *)obj)->id; - xid->end = ((channelid *)obj)->end; - xid->resolve = ((channelid *)obj)->resolve; + return NULL; - data->data = xid; - Py_INCREF(obj); - data->obj = obj; - data->new_object = _channelid_from_xid; - data->free = PyMem_Free; - return 0; +error: + assert(failure != NULL); + PyErr_Clear(); + _sharedexception_clear(sharedexc); + *sharedexc = no_exception; + return failure; } -static PyObject * -channelid_end(PyObject *self, void *end) +static void +_sharedexception_apply(_sharedexception *exc, PyObject *wrapperclass) { - int force = 1; - channelid *cid = (channelid *)self; - if (end != NULL) { - return (PyObject *)newchannelid(Py_TYPE(self), cid->id, *(int *)end, - cid->channels, force, cid->resolve); + if (exc->name != NULL) { + if (exc->msg != NULL) { + PyErr_Format(wrapperclass, "%s: %s", exc->name, exc->msg); + } + else { + PyErr_SetString(wrapperclass, exc->name); + } } - - if (cid->end == CHANNEL_SEND) { - return PyUnicode_InternFromString("send"); + else if (exc->msg != NULL) { + PyErr_SetString(wrapperclass, exc->msg); } - if (cid->end == CHANNEL_RECV) { - return PyUnicode_InternFromString("recv"); + else { + PyErr_SetNone(wrapperclass); } - return PyUnicode_InternFromString("both"); } -static int _channelid_end_send = CHANNEL_SEND; -static int _channelid_end_recv = CHANNEL_RECV; - -static PyGetSetDef channelid_getsets[] = { - {"end", (getter)channelid_end, NULL, - PyDoc_STR("'send', 'recv', or 'both'")}, - {"send", (getter)channelid_end, NULL, - PyDoc_STR("the 'send' end of the channel"), &_channelid_end_send}, - {"recv", (getter)channelid_end, NULL, - PyDoc_STR("the 'recv' end of the channel"), &_channelid_end_recv}, - {NULL} -}; - -PyDoc_STRVAR(channelid_doc, -"A channel ID identifies a channel and may be used as an int."); - -static PyTypeObject ChannelIDtype = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "_xxsubinterpreters.ChannelID", /* tp_name */ - sizeof(channelid), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)channelid_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - (reprfunc)channelid_repr, /* tp_repr */ - &channelid_as_number, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - channelid_hash, /* tp_hash */ - 0, /* tp_call */ - (reprfunc)channelid_str, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - // Use Py_TPFLAGS_DISALLOW_INSTANTIATION so the type cannot be instantiated - // from Python code. We do this because there is a strong relationship - // between channel IDs and the channel lifecycle, so this limitation avoids - // related complications. Use the _channel_id() function instead. - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE - | Py_TPFLAGS_DISALLOW_INSTANTIATION, /* tp_flags */ - channelid_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - channelid_richcompare, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - 0, /* tp_members */ - channelid_getsets, /* tp_getset */ -}; - /* interpreter-specific code ************************************************/ -static PyObject * RunFailedError = NULL; - static int -interp_exceptions_init(PyObject *ns) +exceptions_init(PyObject *mod) { - // XXX Move the exceptions into per-module memory? - - if (RunFailedError == NULL) { - // An uncaught exception came out of interp_run_string(). - RunFailedError = PyErr_NewException("_xxsubinterpreters.RunFailedError", - PyExc_RuntimeError, NULL); - if (RunFailedError == NULL) { - return -1; - } - if (PyDict_SetItemString(ns, "RunFailedError", RunFailedError) != 0) { - return -1; - } + module_state *state = get_module_state(mod); + if (state == NULL) { + return -1; } +#define ADD(NAME, BASE) \ + do { \ + assert(state->NAME == NULL); \ + state->NAME = ADD_NEW_EXCEPTION(mod, NAME, BASE); \ + if (state->NAME == NULL) { \ + return -1; \ + } \ + } while (0) + + // An uncaught exception came out of interp_run_string(). + ADD(RunFailedError, PyExc_RuntimeError); +#undef ADD + return 0; } @@ -1838,7 +370,7 @@ _is_running(PyInterpreterState *interp) } assert(!PyErr_Occurred()); - _PyInterpreterFrame *frame = tstate->cframe->current_frame; + struct _PyInterpreterFrame *frame = tstate->cframe->current_frame; if (frame == NULL) { return 0; } @@ -1861,12 +393,9 @@ _ensure_not_running(PyInterpreterState *interp) static int _run_script(PyInterpreterState *interp, const char *codestr, - _sharedns *shared, _sharedexception **exc) + _sharedns *shared, _sharedexception *sharedexc) { - PyObject *exctype = NULL; PyObject *excval = NULL; - PyObject *tb = NULL; - PyObject *main_mod = _PyInterpreterState_GetMainModule(interp); if (main_mod == NULL) { goto error; @@ -1896,35 +425,31 @@ _run_script(PyInterpreterState *interp, const char *codestr, Py_DECREF(result); // We throw away the result. } - *exc = NULL; + *sharedexc = no_exception; return 0; error: - PyErr_Fetch(&exctype, &excval, &tb); - - _sharedexception *sharedexc = _sharedexception_bind(exctype, excval, tb); - Py_XDECREF(exctype); - Py_XDECREF(excval); - Py_XDECREF(tb); - if (sharedexc == NULL) { - fprintf(stderr, "RunFailedError: script raised an uncaught exception"); + excval = PyErr_GetRaisedException(); + const char *failure = _sharedexception_bind(excval, sharedexc); + if (failure != NULL) { + fprintf(stderr, + "RunFailedError: script raised an uncaught exception (%s)", + failure); PyErr_Clear(); - sharedexc = NULL; - } - else { - assert(!PyErr_Occurred()); } - *exc = sharedexc; + Py_XDECREF(excval); + assert(!PyErr_Occurred()); return -1; } static int -_run_script_in_interpreter(PyInterpreterState *interp, const char *codestr, - PyObject *shareables) +_run_script_in_interpreter(PyObject *mod, PyInterpreterState *interp, + const char *codestr, PyObject *shareables) { if (_ensure_not_running(interp) < 0) { return -1; } + module_state *state = get_module_state(mod); _sharedns *shared = _get_shared_ns(shareables); if (shared == NULL && PyErr_Occurred()) { @@ -1941,7 +466,7 @@ _run_script_in_interpreter(PyInterpreterState *interp, const char *codestr, } // Run the script. - _sharedexception *exc = NULL; + _sharedexception exc = {NULL, NULL}; int result = _run_script(interp, codestr, shared, &exc); // Switch back. @@ -1950,9 +475,9 @@ _run_script_in_interpreter(PyInterpreterState *interp, const char *codestr, } // Propagate any exception out to the caller. - if (exc != NULL) { - _sharedexception_apply(exc, RunFailedError); - _sharedexception_free(exc); + if (exc.name != NULL) { + assert(state != NULL); + _sharedexception_apply(&exc, state->RunFailedError); } else if (result != 0) { // We were unable to allocate a shared exception. @@ -1969,27 +494,6 @@ _run_script_in_interpreter(PyInterpreterState *interp, const char *codestr, /* module level code ********************************************************/ -/* globals is the process-global state for the module. It holds all - the data that we need to share between interpreters, so it cannot - hold PyObject values. */ -static struct globals { - _channels channels; -} _globals = {{0}}; - -static int -_init_globals(void) -{ - if (_channels_init(&_globals.channels) != 0) { - return -1; - } - return 0; -} - -static _channels * -_global_channels(void) { - return &_globals.channels; -} - static PyObject * interp_create(PyObject *self, PyObject *args, PyObject *kwds) { @@ -2002,17 +506,26 @@ interp_create(PyObject *self, PyObject *args, PyObject *kwds) } // Create and initialize the new interpreter. - PyThreadState *save_tstate = _PyThreadState_GET(); + PyThreadState *save_tstate = PyThreadState_Get(); + assert(save_tstate != NULL); + const PyInterpreterConfig config = isolated + ? (PyInterpreterConfig)_PyInterpreterConfig_INIT + : (PyInterpreterConfig)_PyInterpreterConfig_LEGACY_INIT; // XXX Possible GILState issues? - PyThreadState *tstate = _Py_NewInterpreter(isolated); + PyThreadState *tstate = NULL; + PyStatus status = Py_NewInterpreterFromConfig(&tstate, &config); PyThreadState_Swap(save_tstate); - if (tstate == NULL) { + if (PyStatus_Exception(status)) { /* Since no new thread state was created, there is no exception to propagate; raise a fresh one after swapping in the old thread state. */ + _PyErr_SetFromPyStatus(status); + PyObject *exc = PyErr_GetRaisedException(); PyErr_SetString(PyExc_RuntimeError, "interpreter creation failed"); + _PyErr_ChainExceptions1(exc); return NULL; } + assert(tstate != NULL); PyInterpreterState *interp = PyThreadState_GetInterpreter(tstate); PyObject *idobj = _PyInterpreterState_GetIDObject(interp); if (idobj == NULL) { @@ -2050,7 +563,7 @@ interp_destroy(PyObject *self, PyObject *args, PyObject *kwds) } // Ensure we don't try to destroy the current interpreter. - PyInterpreterState *current = _get_current(); + PyInterpreterState *current = _get_current_interp(); if (current == NULL) { return NULL; } @@ -2127,7 +640,7 @@ Return a list containing the ID of every existing interpreter."); static PyObject * interp_get_current(PyObject *self, PyObject *Py_UNUSED(ignored)) { - PyInterpreterState *interp =_get_current(); + PyInterpreterState *interp =_get_current_interp(); if (interp == NULL) { return NULL; } @@ -2185,7 +698,7 @@ interp_run_string(PyObject *self, PyObject *args, PyObject *kwds) } // Run the code in the interpreter. - if (_run_script_in_interpreter(interp, codestr, shared) != 0) { + if (_run_script_in_interpreter(self, interp, codestr, shared) != 0) { return NULL; } Py_RETURN_NONE; @@ -2252,296 +765,6 @@ PyDoc_STRVAR(is_running_doc, \n\ Return whether or not the identified interpreter is running."); -static PyObject * -channel_create(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - int64_t cid = _channel_create(&_globals.channels); - if (cid < 0) { - return NULL; - } - PyObject *id = (PyObject *)newchannelid(&ChannelIDtype, cid, 0, - &_globals.channels, 0, 0); - if (id == NULL) { - if (_channel_destroy(&_globals.channels, cid) != 0) { - // XXX issue a warning? - } - return NULL; - } - assert(((channelid *)id)->channels != NULL); - return id; -} - -PyDoc_STRVAR(channel_create_doc, -"channel_create() -> cid\n\ -\n\ -Create a new cross-interpreter channel and return a unique generated ID."); - -static PyObject * -channel_destroy(PyObject *self, PyObject *args, PyObject *kwds) -{ - static char *kwlist[] = {"cid", NULL}; - int64_t cid; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&:channel_destroy", kwlist, - channel_id_converter, &cid)) { - return NULL; - } - - if (_channel_destroy(&_globals.channels, cid) != 0) { - return NULL; - } - Py_RETURN_NONE; -} - -PyDoc_STRVAR(channel_destroy_doc, -"channel_destroy(cid)\n\ -\n\ -Close and finalize the channel. Afterward attempts to use the channel\n\ -will behave as though it never existed."); - -static PyObject * -channel_list_all(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - int64_t count = 0; - int64_t *cids = _channels_list_all(&_globals.channels, &count); - if (cids == NULL) { - if (count == 0) { - return PyList_New(0); - } - return NULL; - } - PyObject *ids = PyList_New((Py_ssize_t)count); - if (ids == NULL) { - goto finally; - } - int64_t *cur = cids; - for (int64_t i=0; i < count; cur++, i++) { - PyObject *id = (PyObject *)newchannelid(&ChannelIDtype, *cur, 0, - &_globals.channels, 0, 0); - if (id == NULL) { - Py_DECREF(ids); - ids = NULL; - break; - } - PyList_SET_ITEM(ids, i, id); - } - -finally: - PyMem_Free(cids); - return ids; -} - -PyDoc_STRVAR(channel_list_all_doc, -"channel_list_all() -> [cid]\n\ -\n\ -Return the list of all IDs for active channels."); - -static PyObject * -channel_list_interpreters(PyObject *self, PyObject *args, PyObject *kwds) -{ - static char *kwlist[] = {"cid", "send", NULL}; - int64_t cid; /* Channel ID */ - int send = 0; /* Send or receive end? */ - int64_t id; - PyObject *ids, *id_obj; - PyInterpreterState *interp; - - if (!PyArg_ParseTupleAndKeywords( - args, kwds, "O&$p:channel_list_interpreters", - kwlist, channel_id_converter, &cid, &send)) { - return NULL; - } - - ids = PyList_New(0); - if (ids == NULL) { - goto except; - } - - interp = PyInterpreterState_Head(); - while (interp != NULL) { - id = PyInterpreterState_GetID(interp); - assert(id >= 0); - int res = _channel_is_associated(&_globals.channels, cid, id, send); - if (res < 0) { - goto except; - } - if (res) { - id_obj = _PyInterpreterState_GetIDObject(interp); - if (id_obj == NULL) { - goto except; - } - res = PyList_Insert(ids, 0, id_obj); - Py_DECREF(id_obj); - if (res < 0) { - goto except; - } - } - interp = PyInterpreterState_Next(interp); - } - - goto finally; - -except: - Py_XDECREF(ids); - ids = NULL; - -finally: - return ids; -} - -PyDoc_STRVAR(channel_list_interpreters_doc, -"channel_list_interpreters(cid, *, send) -> [id]\n\ -\n\ -Return the list of all interpreter IDs associated with an end of the channel.\n\ -\n\ -The 'send' argument should be a boolean indicating whether to use the send or\n\ -receive end."); - - -static PyObject * -channel_send(PyObject *self, PyObject *args, PyObject *kwds) -{ - static char *kwlist[] = {"cid", "obj", NULL}; - int64_t cid; - PyObject *obj; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&O:channel_send", kwlist, - channel_id_converter, &cid, &obj)) { - return NULL; - } - - if (_channel_send(&_globals.channels, cid, obj) != 0) { - return NULL; - } - Py_RETURN_NONE; -} - -PyDoc_STRVAR(channel_send_doc, -"channel_send(cid, obj)\n\ -\n\ -Add the object's data to the channel's queue."); - -static PyObject * -channel_recv(PyObject *self, PyObject *args, PyObject *kwds) -{ - static char *kwlist[] = {"cid", "default", NULL}; - int64_t cid; - PyObject *dflt = NULL; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&|O:channel_recv", kwlist, - channel_id_converter, &cid, &dflt)) { - return NULL; - } - Py_XINCREF(dflt); - - PyObject *obj = _channel_recv(&_globals.channels, cid); - if (obj != NULL) { - Py_XDECREF(dflt); - return obj; - } else if (PyErr_Occurred()) { - Py_XDECREF(dflt); - return NULL; - } else if (dflt != NULL) { - return dflt; - } else { - PyErr_Format(ChannelEmptyError, "channel %" PRId64 " is empty", cid); - return NULL; - } -} - -PyDoc_STRVAR(channel_recv_doc, -"channel_recv(cid, [default]) -> obj\n\ -\n\ -Return a new object from the data at the front of the channel's queue.\n\ -\n\ -If there is nothing to receive then raise ChannelEmptyError, unless\n\ -a default value is provided. In that case return it."); - -static PyObject * -channel_close(PyObject *self, PyObject *args, PyObject *kwds) -{ - static char *kwlist[] = {"cid", "send", "recv", "force", NULL}; - int64_t cid; - int send = 0; - int recv = 0; - int force = 0; - if (!PyArg_ParseTupleAndKeywords(args, kwds, - "O&|$ppp:channel_close", kwlist, - channel_id_converter, &cid, &send, &recv, &force)) { - return NULL; - } - - if (_channel_close(&_globals.channels, cid, send-recv, force) != 0) { - return NULL; - } - Py_RETURN_NONE; -} - -PyDoc_STRVAR(channel_close_doc, -"channel_close(cid, *, send=None, recv=None, force=False)\n\ -\n\ -Close the channel for all interpreters.\n\ -\n\ -If the channel is empty then the keyword args are ignored and both\n\ -ends are immediately closed. Otherwise, if 'force' is True then\n\ -all queued items are released and both ends are immediately\n\ -closed.\n\ -\n\ -If the channel is not empty *and* 'force' is False then following\n\ -happens:\n\ -\n\ - * recv is True (regardless of send):\n\ - - raise ChannelNotEmptyError\n\ - * recv is None and send is None:\n\ - - raise ChannelNotEmptyError\n\ - * send is True and recv is not True:\n\ - - fully close the 'send' end\n\ - - close the 'recv' end to interpreters not already receiving\n\ - - fully close it once empty\n\ -\n\ -Closing an already closed channel results in a ChannelClosedError.\n\ -\n\ -Once the channel's ID has no more ref counts in any interpreter\n\ -the channel will be destroyed."); - -static PyObject * -channel_release(PyObject *self, PyObject *args, PyObject *kwds) -{ - // Note that only the current interpreter is affected. - static char *kwlist[] = {"cid", "send", "recv", "force", NULL}; - int64_t cid; - int send = 0; - int recv = 0; - int force = 0; - if (!PyArg_ParseTupleAndKeywords(args, kwds, - "O&|$ppp:channel_release", kwlist, - channel_id_converter, &cid, &send, &recv, &force)) { - return NULL; - } - if (send == 0 && recv == 0) { - send = 1; - recv = 1; - } - - // XXX Handle force is True. - // XXX Fix implicit release. - - if (_channel_drop(&_globals.channels, cid, send, recv) != 0) { - return NULL; - } - Py_RETURN_NONE; -} - -PyDoc_STRVAR(channel_release_doc, -"channel_release(cid, *, send=None, recv=None, force=True)\n\ -\n\ -Close the channel for the current interpreter. 'send' and 'recv'\n\ -(bool) may be used to indicate the ends to close. By default both\n\ -ends are closed. Closing an already closed end is a noop."); - -static PyObject * -channel__channel_id(PyObject *self, PyObject *args, PyObject *kwds) -{ - return channelid_new(&ChannelIDtype, args, kwds); -} - static PyMethodDef module_functions[] = { {"create", _PyCFunction_CAST(interp_create), METH_VARARGS | METH_KEYWORDS, create_doc}, @@ -2553,6 +776,7 @@ static PyMethodDef module_functions[] = { METH_NOARGS, get_current_doc}, {"get_main", interp_get_main, METH_NOARGS, get_main_doc}, + {"is_running", _PyCFunction_CAST(interp_is_running), METH_VARARGS | METH_KEYWORDS, is_running_doc}, {"run_string", _PyCFunction_CAST(interp_run_string), @@ -2561,25 +785,6 @@ static PyMethodDef module_functions[] = { {"is_shareable", _PyCFunction_CAST(object_is_shareable), METH_VARARGS | METH_KEYWORDS, is_shareable_doc}, - {"channel_create", channel_create, - METH_NOARGS, channel_create_doc}, - {"channel_destroy", _PyCFunction_CAST(channel_destroy), - METH_VARARGS | METH_KEYWORDS, channel_destroy_doc}, - {"channel_list_all", channel_list_all, - METH_NOARGS, channel_list_all_doc}, - {"channel_list_interpreters", _PyCFunction_CAST(channel_list_interpreters), - METH_VARARGS | METH_KEYWORDS, channel_list_interpreters_doc}, - {"channel_send", _PyCFunction_CAST(channel_send), - METH_VARARGS | METH_KEYWORDS, channel_send_doc}, - {"channel_recv", _PyCFunction_CAST(channel_recv), - METH_VARARGS | METH_KEYWORDS, channel_recv_doc}, - {"channel_close", _PyCFunction_CAST(channel_close), - METH_VARARGS | METH_KEYWORDS, channel_close_doc}, - {"channel_release", _PyCFunction_CAST(channel_release), - METH_VARARGS | METH_KEYWORDS, channel_release_doc}, - {"_channel_id", _PyCFunction_CAST(channel__channel_id), - METH_VARARGS | METH_KEYWORDS, NULL}, - {NULL, NULL} /* sentinel */ }; @@ -2590,59 +795,71 @@ PyDoc_STRVAR(module_doc, "This module provides primitive operations to manage Python interpreters.\n\ The 'interpreters' module provides a more convenient interface."); -static struct PyModuleDef interpretersmodule = { - PyModuleDef_HEAD_INIT, - "_xxsubinterpreters", /* m_name */ - module_doc, /* m_doc */ - -1, /* m_size */ - module_functions, /* m_methods */ - NULL, /* m_slots */ - NULL, /* m_traverse */ - NULL, /* m_clear */ - NULL /* m_free */ -}; - - -PyMODINIT_FUNC -PyInit__xxsubinterpreters(void) +static int +module_exec(PyObject *mod) { - if (_init_globals() != 0) { - return NULL; + /* Add exception types */ + if (exceptions_init(mod) != 0) { + goto error; } - /* Initialize types */ - if (PyType_Ready(&ChannelIDtype) != 0) { - return NULL; + // PyInterpreterID + if (PyModule_AddType(mod, &_PyInterpreterID_Type) < 0) { + goto error; } - /* Create the module */ - PyObject *module = PyModule_Create(&interpretersmodule); - if (module == NULL) { - return NULL; - } + return 0; - /* Add exception types */ - PyObject *ns = PyModule_GetDict(module); // borrowed - if (interp_exceptions_init(ns) != 0) { - return NULL; - } - if (channel_exceptions_init(ns) != 0) { - return NULL; - } +error: + return -1; +} - /* Add other types */ - Py_INCREF(&ChannelIDtype); - if (PyDict_SetItemString(ns, "ChannelID", (PyObject *)&ChannelIDtype) != 0) { - return NULL; - } - Py_INCREF(&_PyInterpreterID_Type); - if (PyDict_SetItemString(ns, "InterpreterID", (PyObject *)&_PyInterpreterID_Type) != 0) { - return NULL; - } +static struct PyModuleDef_Slot module_slots[] = { + {Py_mod_exec, module_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, + {0, NULL}, +}; - if (_PyCrossInterpreterData_RegisterClass(&ChannelIDtype, _channelid_shared)) { - return NULL; - } +static int +module_traverse(PyObject *mod, visitproc visit, void *arg) +{ + module_state *state = get_module_state(mod); + assert(state != NULL); + traverse_module_state(state, visit, arg); + return 0; +} + +static int +module_clear(PyObject *mod) +{ + module_state *state = get_module_state(mod); + assert(state != NULL); + clear_module_state(state); + return 0; +} + +static void +module_free(void *mod) +{ + module_state *state = get_module_state(mod); + assert(state != NULL); + clear_module_state(state); +} + +static struct PyModuleDef moduledef = { + .m_base = PyModuleDef_HEAD_INIT, + .m_name = MODULE_NAME, + .m_doc = module_doc, + .m_size = sizeof(module_state), + .m_methods = module_functions, + .m_slots = module_slots, + .m_traverse = module_traverse, + .m_clear = module_clear, + .m_free = (freefunc)module_free, +}; - return module; +PyMODINIT_FUNC +PyInit__xxsubinterpreters(void) +{ + return PyModuleDef_Init(&moduledef); } diff --git a/Modules/_xxtestfuzz/fuzzer.c b/Modules/_xxtestfuzz/fuzzer.c index 366e81a5..37d40282 100644 --- a/Modules/_xxtestfuzz/fuzzer.c +++ b/Modules/_xxtestfuzz/fuzzer.c @@ -142,7 +142,7 @@ static int fuzz_struct_unpack(const char* data, size_t size) { } -#define MAX_JSON_TEST_SIZE 0x10000 +#define MAX_JSON_TEST_SIZE 0x100000 PyObject* json_loads_method = NULL; /* Called by LLVMFuzzerTestOneInput for initialization */ @@ -335,7 +335,7 @@ static int fuzz_sre_match(const char* data, size_t size) { return 0; } -#define MAX_CSV_TEST_SIZE 0x10000 +#define MAX_CSV_TEST_SIZE 0x100000 PyObject* csv_module = NULL; PyObject* csv_error = NULL; /* Called by LLVMFuzzerTestOneInput for initialization */ @@ -393,7 +393,7 @@ static int fuzz_csv_reader(const char* data, size_t size) { return 0; } -#define MAX_AST_LITERAL_EVAL_TEST_SIZE 0x10000 +#define MAX_AST_LITERAL_EVAL_TEST_SIZE 0x100000 PyObject* ast_literal_eval_method = NULL; /* Called by LLVMFuzzerTestOneInput for initialization */ static int init_ast_literal_eval(void) { @@ -459,6 +459,9 @@ int LLVMFuzzerInitialize(int *argc, char ***argv) { PyConfig config; PyConfig_InitPythonConfig(&config); config.install_signal_handlers = 0; + /* Raise the limit above the default allows exercising larger things + * now that we fall back to the _pylong module for large values. */ + config.int_max_str_digits = 8086; PyStatus status; status = PyConfig_SetBytesString(&config, &config.program_name, *argv[0]); if (PyStatus_Exception(status)) { @@ -523,13 +526,20 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { #if !defined(_Py_FUZZ_ONE) || defined(_Py_FUZZ_fuzz_sre_compile) static int SRE_COMPILE_INITIALIZED = 0; if (!SRE_COMPILE_INITIALIZED && !init_sre_compile()) { - PyErr_Print(); - abort(); + if (!PyErr_ExceptionMatches(PyExc_DeprecationWarning)) { + PyErr_Print(); + abort(); + } + else { + PyErr_Clear(); + } } else { SRE_COMPILE_INITIALIZED = 1; } - rv |= _run_fuzz(data, size, fuzz_sre_compile); + if (SRE_COMPILE_INITIALIZED) { + rv |= _run_fuzz(data, size, fuzz_sre_compile); + } #endif #if !defined(_Py_FUZZ_ONE) || defined(_Py_FUZZ_fuzz_sre_match) static int SRE_MATCH_INITIALIZED = 0; diff --git a/Modules/_zoneinfo.c b/Modules/_zoneinfo.c index 55975f4e..38b806c2 100644 --- a/Modules/_zoneinfo.c +++ b/Modules/_zoneinfo.c @@ -12,10 +12,13 @@ #include "datetime.h" -// Imports -static PyObject *io_open = NULL; -static PyObject *_tzpath_find_tzfile = NULL; -static PyObject *_common_mod = NULL; +#include "clinic/_zoneinfo.c.h" +/*[clinic input] +module zoneinfo +class zoneinfo.ZoneInfo "PyObject *" "PyTypeObject *" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=d12c73c0eef36df8]*/ + typedef struct TransitionRuleType TransitionRuleType; typedef struct StrongCacheNode StrongCacheNode; @@ -83,15 +86,21 @@ struct StrongCacheNode { PyObject *zone; }; -static PyTypeObject PyZoneInfo_ZoneInfoType; +typedef struct { + PyTypeObject *ZoneInfoType; + + // Imports + PyObject *io_open; + PyObject *_tzpath_find_tzfile; + PyObject *_common_mod; -// Globals -static PyObject *TIMEDELTA_CACHE = NULL; -static PyObject *ZONEINFO_WEAK_CACHE = NULL; -static StrongCacheNode *ZONEINFO_STRONG_CACHE = NULL; -static size_t ZONEINFO_STRONG_CACHE_MAX_SIZE = 8; + // Caches + PyObject *TIMEDELTA_CACHE; + PyObject *ZONEINFO_WEAK_CACHE; + StrongCacheNode *ZONEINFO_STRONG_CACHE; -static _ttinfo NO_TTINFO = {NULL, NULL, NULL, 0}; + _ttinfo NO_TTINFO; +} zoneinfo_state; // Constants static const int EPOCHORDINAL = 719163; @@ -107,9 +116,12 @@ static const int SOURCE_NOCACHE = 0; static const int SOURCE_CACHE = 1; static const int SOURCE_FILE = 2; +static const size_t ZONEINFO_STRONG_CACHE_MAX_SIZE = 8; + // Forward declarations static int -load_data(PyZoneInfo_ZoneInfo *self, PyObject *file_obj); +load_data(zoneinfo_state *state, PyZoneInfo_ZoneInfo *self, + PyObject *file_obj); static void utcoff_to_dstoff(size_t *trans_idx, long *utcoffs, long *dstoffs, unsigned char *isdsts, size_t num_transitions, @@ -120,7 +132,7 @@ ts_to_local(size_t *trans_idx, int64_t *trans_utc, long *utcoff, size_t num_transitions); static int -parse_tz_str(PyObject *tz_str_obj, _tzrule *out); +parse_tz_str(zoneinfo_state *state, PyObject *tz_str_obj, _tzrule *out); static Py_ssize_t parse_abbr(const char *const p, PyObject **abbr); @@ -139,26 +151,27 @@ find_tzrule_ttinfo_fromutc(_tzrule *rule, int64_t ts, int year, unsigned char *fold); static int -build_ttinfo(long utcoffset, long dstoffset, PyObject *tzname, _ttinfo *out); +build_ttinfo(zoneinfo_state *state, long utcoffset, long dstoffset, + PyObject *tzname, _ttinfo *out); static void xdecref_ttinfo(_ttinfo *ttinfo); static int ttinfo_eq(const _ttinfo *const tti0, const _ttinfo *const tti1); static int -build_tzrule(PyObject *std_abbr, PyObject *dst_abbr, long std_offset, - long dst_offset, TransitionRuleType *start, +build_tzrule(zoneinfo_state *state, PyObject *std_abbr, PyObject *dst_abbr, + long std_offset, long dst_offset, TransitionRuleType *start, TransitionRuleType *end, _tzrule *out); static void free_tzrule(_tzrule *tzrule); static PyObject * -load_timedelta(long seconds); +load_timedelta(zoneinfo_state *state, long seconds); static int get_local_timestamp(PyObject *dt, int64_t *local_ts); static _ttinfo * -find_ttinfo(PyZoneInfo_ZoneInfo *self, PyObject *dt); +find_ttinfo(zoneinfo_state *state, PyZoneInfo_ZoneInfo *self, PyObject *dt); static int ymd_to_ord(int y, int m, int d); @@ -169,27 +182,57 @@ static size_t _bisect(const int64_t value, const int64_t *arr, size_t size); static int -eject_from_strong_cache(const PyTypeObject *const type, PyObject *key); +eject_from_strong_cache(zoneinfo_state *state, const PyTypeObject *const type, + PyObject *key); static void -clear_strong_cache(const PyTypeObject *const type); +clear_strong_cache(zoneinfo_state *state, const PyTypeObject *const type); static void -update_strong_cache(const PyTypeObject *const type, PyObject *key, - PyObject *zone); +update_strong_cache(zoneinfo_state *state, const PyTypeObject *const type, + PyObject *key, PyObject *zone); static PyObject * -zone_from_strong_cache(const PyTypeObject *const type, PyObject *const key); +zone_from_strong_cache(zoneinfo_state *state, const PyTypeObject *const type, + PyObject *const key); + +static inline zoneinfo_state * +zoneinfo_get_state(PyObject *mod) +{ + zoneinfo_state *state = (zoneinfo_state *)PyModule_GetState(mod); + assert(state != NULL); + return state; +} + +static inline zoneinfo_state * +zoneinfo_get_state_by_cls(PyTypeObject *cls) +{ + zoneinfo_state *state = (zoneinfo_state *)_PyType_GetModuleState(cls); + assert(state != NULL); + return state; +} + +static struct PyModuleDef zoneinfomodule; + +static inline zoneinfo_state * +zoneinfo_get_state_by_self(PyTypeObject *self) +{ + PyObject *mod = PyType_GetModuleByDef(self, &zoneinfomodule); + assert(mod != NULL); + return zoneinfo_get_state(mod); +} static PyObject * -zoneinfo_new_instance(PyTypeObject *type, PyObject *key) +zoneinfo_new_instance(zoneinfo_state *state, PyTypeObject *type, PyObject *key) { PyObject *file_obj = NULL; PyObject *file_path = NULL; - file_path = PyObject_CallFunctionObjArgs(_tzpath_find_tzfile, key, NULL); + file_path = PyObject_CallFunctionObjArgs(state->_tzpath_find_tzfile, + key, NULL); if (file_path == NULL) { return NULL; } else if (file_path == Py_None) { - file_obj = PyObject_CallMethod(_common_mod, "load_tzdata", "O", key); + PyObject *meth = state->_common_mod; + file_obj = PyObject_CallMethod(meth, "load_tzdata", "O", key); if (file_obj == NULL) { Py_DECREF(file_path); return NULL; @@ -202,37 +245,34 @@ zoneinfo_new_instance(PyTypeObject *type, PyObject *key) } if (file_obj == NULL) { - file_obj = PyObject_CallFunction(io_open, "Os", file_path, "rb"); + PyObject *func = state->io_open; + file_obj = PyObject_CallFunction(func, "Os", file_path, "rb"); if (file_obj == NULL) { goto error; } } - if (load_data((PyZoneInfo_ZoneInfo *)self, file_obj)) { + if (load_data(state, (PyZoneInfo_ZoneInfo *)self, file_obj)) { goto error; } PyObject *rv = PyObject_CallMethod(file_obj, "close", NULL); - Py_DECREF(file_obj); - file_obj = NULL; + Py_SETREF(file_obj, NULL); if (rv == NULL) { goto error; } Py_DECREF(rv); - ((PyZoneInfo_ZoneInfo *)self)->key = key; - Py_INCREF(key); + ((PyZoneInfo_ZoneInfo *)self)->key = Py_NewRef(key); goto cleanup; error: - Py_XDECREF(self); - self = NULL; + Py_CLEAR(self); cleanup: if (file_obj != NULL) { - PyObject *exc, *val, *tb; - PyErr_Fetch(&exc, &val, &tb); + PyObject *exc = PyErr_GetRaisedException(); PyObject *tmp = PyObject_CallMethod(file_obj, "close", NULL); - _PyErr_ChainExceptions(exc, val, tb); + _PyErr_ChainExceptions1(exc); if (tmp == NULL) { Py_CLEAR(self); } @@ -244,10 +284,10 @@ cleanup: } static PyObject * -get_weak_cache(PyTypeObject *type) +get_weak_cache(zoneinfo_state *state, PyTypeObject *type) { - if (type == &PyZoneInfo_ZoneInfoType) { - return ZONEINFO_WEAK_CACHE; + if (type == state->ZoneInfoType) { + return state->ZONEINFO_WEAK_CACHE; } else { PyObject *cache = @@ -269,12 +309,13 @@ zoneinfo_new(PyTypeObject *type, PyObject *args, PyObject *kw) return NULL; } - PyObject *instance = zone_from_strong_cache(type, key); + zoneinfo_state *state = zoneinfo_get_state_by_self(type); + PyObject *instance = zone_from_strong_cache(state, type, key); if (instance != NULL || PyErr_Occurred()) { return instance; } - PyObject *weak_cache = get_weak_cache(type); + PyObject *weak_cache = get_weak_cache(state, type); instance = PyObject_CallMethod(weak_cache, "get", "O", key, Py_None); if (instance == NULL) { return NULL; @@ -282,7 +323,7 @@ zoneinfo_new(PyTypeObject *type, PyObject *args, PyObject *kw) if (instance == Py_None) { Py_DECREF(instance); - PyObject *tmp = zoneinfo_new_instance(type, key); + PyObject *tmp = zoneinfo_new_instance(state, type, key); if (tmp == NULL) { return NULL; } @@ -296,14 +337,32 @@ zoneinfo_new(PyTypeObject *type, PyObject *args, PyObject *kw) ((PyZoneInfo_ZoneInfo *)instance)->source = SOURCE_CACHE; } - update_strong_cache(type, key, instance); + update_strong_cache(state, type, key, instance); return instance; } +static int +zoneinfo_traverse(PyZoneInfo_ZoneInfo *self, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(self)); + Py_VISIT(self->key); + return 0; +} + +static int +zoneinfo_clear(PyZoneInfo_ZoneInfo *self) +{ + Py_CLEAR(self->key); + Py_CLEAR(self->file_repr); + return 0; +} + static void zoneinfo_dealloc(PyObject *obj_self) { PyZoneInfo_ZoneInfo *self = (PyZoneInfo_ZoneInfo *)obj_self; + PyTypeObject *tp = Py_TYPE(self); + PyObject_GC_UnTrack(self); if (self->weakreflist != NULL) { PyObject_ClearWeakRefs(obj_self); @@ -332,26 +391,31 @@ zoneinfo_dealloc(PyObject *obj_self) free_tzrule(&(self->tzrule_after)); - Py_XDECREF(self->key); - Py_XDECREF(self->file_repr); - - Py_TYPE(self)->tp_free((PyObject *)self); + zoneinfo_clear(self); + tp->tp_free(obj_self); + Py_DECREF(tp); } +/*[clinic input] +@classmethod +zoneinfo.ZoneInfo.from_file + + cls: defining_class + file_obj: object + / + key: object = None + +Create a ZoneInfo file from a file object. +[clinic start generated code]*/ + static PyObject * -zoneinfo_from_file(PyTypeObject *type, PyObject *args, PyObject *kwargs) +zoneinfo_ZoneInfo_from_file_impl(PyTypeObject *type, PyTypeObject *cls, + PyObject *file_obj, PyObject *key) +/*[clinic end generated code: output=77887d1d56a48324 input=d26111f29eed6863]*/ { - PyObject *file_obj = NULL; PyObject *file_repr = NULL; - PyObject *key = Py_None; PyZoneInfo_ZoneInfo *self = NULL; - static char *kwlist[] = {"", "key", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O", kwlist, &file_obj, - &key)) { - return NULL; - } - PyObject *obj_self = (PyObject *)(type->tp_alloc(type, 0)); self = (PyZoneInfo_ZoneInfo *)obj_self; if (self == NULL) { @@ -363,32 +427,40 @@ zoneinfo_from_file(PyTypeObject *type, PyObject *args, PyObject *kwargs) goto error; } - if (load_data(self, file_obj)) { + zoneinfo_state *state = zoneinfo_get_state_by_cls(cls); + if (load_data(state, self, file_obj)) { goto error; } self->source = SOURCE_FILE; self->file_repr = file_repr; - self->key = key; - Py_INCREF(key); - + self->key = Py_NewRef(key); return obj_self; + error: Py_XDECREF(file_repr); Py_XDECREF(self); return NULL; } +/*[clinic input] +@classmethod +zoneinfo.ZoneInfo.no_cache + + cls: defining_class + / + key: object + +Get a new instance of ZoneInfo, bypassing the cache. +[clinic start generated code]*/ + static PyObject * -zoneinfo_no_cache(PyTypeObject *cls, PyObject *args, PyObject *kwargs) +zoneinfo_ZoneInfo_no_cache_impl(PyTypeObject *type, PyTypeObject *cls, + PyObject *key) +/*[clinic end generated code: output=b0b09b3344c171b7 input=0238f3d56b1ea3f1]*/ { - static char *kwlist[] = {"key", NULL}; - PyObject *key = NULL; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O", kwlist, &key)) { - return NULL; - } - - PyObject *out = zoneinfo_new_instance(cls, key); + zoneinfo_state *state = zoneinfo_get_state_by_cls(cls); + PyObject *out = zoneinfo_new_instance(state, type, key); if (out != NULL) { ((PyZoneInfo_ZoneInfo *)out)->source = SOURCE_NOCACHE; } @@ -396,19 +468,25 @@ zoneinfo_no_cache(PyTypeObject *cls, PyObject *args, PyObject *kwargs) return out; } -static PyObject * -zoneinfo_clear_cache(PyObject *cls, PyObject *args, PyObject *kwargs) -{ - PyObject *only_keys = NULL; - static char *kwlist[] = {"only_keys", NULL}; +/*[clinic input] +@classmethod +zoneinfo.ZoneInfo.clear_cache - if (!(PyArg_ParseTupleAndKeywords(args, kwargs, "|$O", kwlist, - &only_keys))) { - return NULL; - } + cls: defining_class + / + * + only_keys: object = None + +Clear the ZoneInfo cache. +[clinic start generated code]*/ - PyTypeObject *type = (PyTypeObject *)cls; - PyObject *weak_cache = get_weak_cache(type); +static PyObject * +zoneinfo_ZoneInfo_clear_cache_impl(PyTypeObject *type, PyTypeObject *cls, + PyObject *only_keys) +/*[clinic end generated code: output=114d9b7c8a22e660 input=e32ca3bb396788ba]*/ +{ + zoneinfo_state *state = zoneinfo_get_state_by_cls(cls); + PyObject *weak_cache = get_weak_cache(state, type); if (only_keys == NULL || only_keys == Py_None) { PyObject *rv = PyObject_CallMethod(weak_cache, "clear", NULL); @@ -416,7 +494,7 @@ zoneinfo_clear_cache(PyObject *cls, PyObject *args, PyObject *kwargs) Py_DECREF(rv); } - clear_strong_cache(type); + clear_strong_cache(state, type); } else { PyObject *item = NULL; @@ -433,7 +511,7 @@ zoneinfo_clear_cache(PyObject *cls, PyObject *args, PyObject *kwargs) while ((item = PyIter_Next(iter))) { // Remove from strong cache - if (eject_from_strong_cache(type, item) < 0) { + if (eject_from_strong_cache(state, type, item) < 0) { Py_DECREF(item); break; } @@ -459,37 +537,72 @@ zoneinfo_clear_cache(PyObject *cls, PyObject *args, PyObject *kwargs) Py_RETURN_NONE; } +/*[clinic input] +zoneinfo.ZoneInfo.utcoffset + + cls: defining_class + dt: object + / + +Retrieve a timedelta representing the UTC offset in a zone at the given datetime. +[clinic start generated code]*/ + static PyObject * -zoneinfo_utcoffset(PyObject *self, PyObject *dt) +zoneinfo_ZoneInfo_utcoffset_impl(PyObject *self, PyTypeObject *cls, + PyObject *dt) +/*[clinic end generated code: output=b71016c319ba1f91 input=2bb6c5364938f19c]*/ { - _ttinfo *tti = find_ttinfo((PyZoneInfo_ZoneInfo *)self, dt); + zoneinfo_state *state = zoneinfo_get_state_by_cls(cls); + _ttinfo *tti = find_ttinfo(state, (PyZoneInfo_ZoneInfo *)self, dt); if (tti == NULL) { return NULL; } - Py_INCREF(tti->utcoff); - return tti->utcoff; + return Py_NewRef(tti->utcoff); } +/*[clinic input] +zoneinfo.ZoneInfo.dst + + cls: defining_class + dt: object + / + +Retrieve a timedelta representing the amount of DST applied in a zone at the given datetime. +[clinic start generated code]*/ + static PyObject * -zoneinfo_dst(PyObject *self, PyObject *dt) +zoneinfo_ZoneInfo_dst_impl(PyObject *self, PyTypeObject *cls, PyObject *dt) +/*[clinic end generated code: output=cb6168d7723a6ae6 input=2167fb80cf8645c6]*/ { - _ttinfo *tti = find_ttinfo((PyZoneInfo_ZoneInfo *)self, dt); + zoneinfo_state *state = zoneinfo_get_state_by_cls(cls); + _ttinfo *tti = find_ttinfo(state, (PyZoneInfo_ZoneInfo *)self, dt); if (tti == NULL) { return NULL; } - Py_INCREF(tti->dstoff); - return tti->dstoff; + return Py_NewRef(tti->dstoff); } +/*[clinic input] +zoneinfo.ZoneInfo.tzname + + cls: defining_class + dt: object + / + +Retrieve a string containing the abbreviation for the time zone that applies in a zone at a given datetime. +[clinic start generated code]*/ + static PyObject * -zoneinfo_tzname(PyObject *self, PyObject *dt) +zoneinfo_ZoneInfo_tzname_impl(PyObject *self, PyTypeObject *cls, + PyObject *dt) +/*[clinic end generated code: output=3b6ae6c3053ea75a input=15a59a4f92ed1f1f]*/ { - _ttinfo *tti = find_ttinfo((PyZoneInfo_ZoneInfo *)self, dt); + zoneinfo_state *state = zoneinfo_get_state_by_cls(cls); + _ttinfo *tti = find_ttinfo(state, (PyZoneInfo_ZoneInfo *)self, dt); if (tti == NULL) { return NULL; } - Py_INCREF(tti->tzname); - return tti->tzname; + return Py_NewRef(tti->tzname); } #define GET_DT_TZINFO PyDateTime_DATE_GET_TZINFO @@ -581,14 +694,19 @@ zoneinfo_fromutc(PyObject *obj_self, PyObject *dt) } else { PyObject *replace = PyObject_GetAttrString(tmp, "replace"); + Py_DECREF(tmp); + if (replace == NULL) { + return NULL; + } PyObject *args = PyTuple_New(0); + if (args == NULL) { + Py_DECREF(replace); + return NULL; + } PyObject *kwargs = PyDict_New(); - - Py_DECREF(tmp); - if (args == NULL || kwargs == NULL || replace == NULL) { - Py_XDECREF(args); - Py_XDECREF(kwargs); - Py_XDECREF(replace); + if (kwargs == NULL) { + Py_DECREF(replace); + Py_DECREF(args); return NULL; } @@ -633,8 +751,7 @@ static PyObject * zoneinfo_str(PyZoneInfo_ZoneInfo *self) { if (!(self->key == Py_None)) { - Py_INCREF(self->key); - return self->key; + return Py_NewRef(self->key); } else { return zoneinfo_repr(self); @@ -659,14 +776,8 @@ zoneinfo_reduce(PyObject *obj_self, PyObject *unused) PyZoneInfo_ZoneInfo *self = (PyZoneInfo_ZoneInfo *)obj_self; if (self->source == SOURCE_FILE) { // Objects constructed from files cannot be pickled. - PyObject *pickle = PyImport_ImportModule("pickle"); - if (pickle == NULL) { - return NULL; - } - PyObject *pickle_error = - PyObject_GetAttrString(pickle, "PicklingError"); - Py_DECREF(pickle); + _PyImport_GetModuleAttrString("pickle", "PicklingError"); if (pickle_error == NULL) { return NULL; } @@ -689,28 +800,37 @@ zoneinfo_reduce(PyObject *obj_self, PyObject *unused) return rv; } +/*[clinic input] +@classmethod +zoneinfo.ZoneInfo._unpickle + + cls: defining_class + key: object + from_cache: unsigned_char(bitwise=True) + / + +Private method used in unpickling. +[clinic start generated code]*/ + static PyObject * -zoneinfo__unpickle(PyTypeObject *cls, PyObject *args) +zoneinfo_ZoneInfo__unpickle_impl(PyTypeObject *type, PyTypeObject *cls, + PyObject *key, unsigned char from_cache) +/*[clinic end generated code: output=556712fc709deecb input=6ac8c73eed3de316]*/ { - PyObject *key; - unsigned char from_cache; - if (!PyArg_ParseTuple(args, "OB", &key, &from_cache)) { - return NULL; - } - if (from_cache) { PyObject *val_args = Py_BuildValue("(O)", key); if (val_args == NULL) { return NULL; } - PyObject *rv = zoneinfo_new(cls, val_args, NULL); + PyObject *rv = zoneinfo_new(type, val_args, NULL); Py_DECREF(val_args); return rv; } else { - return zoneinfo_new_instance(cls, key); + zoneinfo_state *state = zoneinfo_get_state_by_cls(cls); + return zoneinfo_new_instance(state, type, key); } } @@ -728,14 +848,14 @@ zoneinfo__unpickle(PyTypeObject *cls, PyObject *args) * This returns a new reference to the timedelta. */ static PyObject * -load_timedelta(long seconds) +load_timedelta(zoneinfo_state *state, long seconds) { PyObject *rv; PyObject *pyoffset = PyLong_FromLong(seconds); if (pyoffset == NULL) { return NULL; } - rv = PyDict_GetItemWithError(TIMEDELTA_CACHE, pyoffset); + rv = PyDict_GetItemWithError(state->TIMEDELTA_CACHE, pyoffset); if (rv == NULL) { if (PyErr_Occurred()) { goto error; @@ -747,7 +867,7 @@ load_timedelta(long seconds) goto error; } - rv = PyDict_SetDefault(TIMEDELTA_CACHE, pyoffset, tmp); + rv = PyDict_SetDefault(state->TIMEDELTA_CACHE, pyoffset, tmp); Py_DECREF(tmp); } @@ -764,25 +884,25 @@ error: * initialized _ttinfo objects. */ static int -build_ttinfo(long utcoffset, long dstoffset, PyObject *tzname, _ttinfo *out) +build_ttinfo(zoneinfo_state *state, long utcoffset, long dstoffset, + PyObject *tzname, _ttinfo *out) { out->utcoff = NULL; out->dstoff = NULL; out->tzname = NULL; out->utcoff_seconds = utcoffset; - out->utcoff = load_timedelta(utcoffset); + out->utcoff = load_timedelta(state, utcoffset); if (out->utcoff == NULL) { return -1; } - out->dstoff = load_timedelta(dstoffset); + out->dstoff = load_timedelta(state, dstoffset); if (out->dstoff == NULL) { return -1; } - out->tzname = tzname; - Py_INCREF(tzname); + out->tzname = Py_NewRef(tzname); return 0; } @@ -833,7 +953,7 @@ end: * the object only needs to be freed / deallocated if this succeeds. */ static int -load_data(PyZoneInfo_ZoneInfo *self, PyObject *file_obj) +load_data(zoneinfo_state *state, PyZoneInfo_ZoneInfo *self, PyObject *file_obj) { PyObject *data_tuple = NULL; @@ -851,7 +971,8 @@ load_data(PyZoneInfo_ZoneInfo *self, PyObject *file_obj) size_t ttinfos_allocated = 0; - data_tuple = PyObject_CallMethod(_common_mod, "load_data", "O", file_obj); + data_tuple = PyObject_CallMethod(state->_common_mod, "load_data", "O", + file_obj); if (data_tuple == NULL) { goto error; @@ -1009,7 +1130,9 @@ load_data(PyZoneInfo_ZoneInfo *self, PyObject *file_obj) } ttinfos_allocated++; - if (build_ttinfo(utcoff[i], dstoff[i], tzname, &(self->_ttinfos[i]))) { + int rc = build_ttinfo(state, utcoff[i], dstoff[i], tzname, + &(self->_ttinfos[i])); + if (rc) { goto error; } } @@ -1041,7 +1164,7 @@ load_data(PyZoneInfo_ZoneInfo *self, PyObject *file_obj) } if (tz_str != Py_None && PyObject_IsTrue(tz_str)) { - if (parse_tz_str(tz_str, &(self->tzrule_after))) { + if (parse_tz_str(state, tz_str, &(self->tzrule_after))) { goto error; } } @@ -1060,8 +1183,8 @@ load_data(PyZoneInfo_ZoneInfo *self, PyObject *file_obj) } _ttinfo *tti = &(self->_ttinfos[idx]); - build_tzrule(tti->tzname, NULL, tti->utcoff_seconds, 0, NULL, NULL, - &(self->tzrule_after)); + build_tzrule(state, tti->tzname, NULL, tti->utcoff_seconds, 0, NULL, + NULL, &(self->tzrule_after)); // We've abused the build_tzrule constructor to construct an STD-only // rule mimicking whatever ttinfo we've picked up, but it's possible @@ -1069,9 +1192,7 @@ load_data(PyZoneInfo_ZoneInfo *self, PyObject *file_obj) // that the dstoff is set correctly in that case. if (PyObject_IsTrue(tti->dstoff)) { _ttinfo *tti_after = &(self->tzrule_after.std); - Py_DECREF(tti_after->dstoff); - tti_after->dstoff = tti->dstoff; - Py_INCREF(tti_after->dstoff); + Py_SETREF(tti_after->dstoff, Py_NewRef(tti->dstoff)); } } @@ -1462,7 +1583,7 @@ find_tzrule_ttinfo_fromutc(_tzrule *rule, int64_t ts, int year, * https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html */ static int -parse_tz_str(PyObject *tz_str_obj, _tzrule *out) +parse_tz_str(zoneinfo_state *state, PyObject *tz_str_obj, _tzrule *out) { PyObject *std_abbr = NULL; PyObject *dst_abbr = NULL; @@ -1554,7 +1675,8 @@ parse_tz_str(PyObject *tz_str_obj, _tzrule *out) } complete: - build_tzrule(std_abbr, dst_abbr, std_offset, dst_offset, start, end, out); + build_tzrule(state, std_abbr, dst_abbr, std_offset, dst_offset, + start, end, out); Py_DECREF(std_abbr); Py_XDECREF(dst_abbr); @@ -1592,11 +1714,11 @@ static Py_ssize_t parse_abbr(const char *const p, PyObject **abbr) { const char *ptr = p; - char buff = *ptr; const char *str_start; const char *str_end; if (*ptr == '<') { + char buff; ptr++; str_start = ptr; while ((buff = *ptr) != '>') { @@ -1912,8 +2034,8 @@ parse_transition_time(const char *const p, int8_t *hour, int8_t *minute, * Returns 0 on success. */ static int -build_tzrule(PyObject *std_abbr, PyObject *dst_abbr, long std_offset, - long dst_offset, TransitionRuleType *start, +build_tzrule(zoneinfo_state *state, PyObject *std_abbr, PyObject *dst_abbr, + long std_offset, long dst_offset, TransitionRuleType *start, TransitionRuleType *end, _tzrule *out) { _tzrule rv = {{0}}; @@ -1921,13 +2043,13 @@ build_tzrule(PyObject *std_abbr, PyObject *dst_abbr, long std_offset, rv.start = start; rv.end = end; - if (build_ttinfo(std_offset, 0, std_abbr, &rv.std)) { + if (build_ttinfo(state, std_offset, 0, std_abbr, &rv.std)) { goto error; } if (dst_abbr != NULL) { rv.dst_diff = dst_offset - std_offset; - if (build_ttinfo(dst_offset, rv.dst_diff, dst_abbr, &rv.dst)) { + if (build_ttinfo(state, dst_offset, rv.dst_diff, dst_abbr, &rv.dst)) { goto error; } } @@ -2131,7 +2253,7 @@ _bisect(const int64_t value, const int64_t *arr, size_t size) /* Find the ttinfo rules that apply at a given local datetime. */ static _ttinfo * -find_ttinfo(PyZoneInfo_ZoneInfo *self, PyObject *dt) +find_ttinfo(zoneinfo_state *state, PyZoneInfo_ZoneInfo *self, PyObject *dt) { // datetime.time has a .tzinfo attribute that passes None as the dt // argument; it only really has meaning for fixed-offset zones. @@ -2140,7 +2262,7 @@ find_ttinfo(PyZoneInfo_ZoneInfo *self, PyObject *dt) return &(self->tzrule_after.std); } else { - return &NO_TTINFO; + return &(state->NO_TTINFO); } } @@ -2273,13 +2395,10 @@ strong_cache_node_new(PyObject *key, PyObject *zone) return NULL; } - Py_INCREF(key); - Py_INCREF(zone); - node->next = NULL; node->prev = NULL; - node->key = key; - node->zone = zone; + node->key = Py_NewRef(key); + node->zone = Py_NewRef(zone); return node; } @@ -2319,10 +2438,10 @@ strong_cache_free(StrongCacheNode *root) * the front of the cache. */ static void -remove_from_strong_cache(StrongCacheNode *node) +remove_from_strong_cache(zoneinfo_state *state, StrongCacheNode *node) { - if (ZONEINFO_STRONG_CACHE == node) { - ZONEINFO_STRONG_CACHE = node->next; + if (state->ZONEINFO_STRONG_CACHE == node) { + state->ZONEINFO_STRONG_CACHE = node->next; } if (node->prev != NULL) { @@ -2368,15 +2487,17 @@ find_in_strong_cache(const StrongCacheNode *const root, PyObject *const key) * This function is used to enable the per-key functionality in clear_cache. */ static int -eject_from_strong_cache(const PyTypeObject *const type, PyObject *key) +eject_from_strong_cache(zoneinfo_state *state, const PyTypeObject *const type, + PyObject *key) { - if (type != &PyZoneInfo_ZoneInfoType) { + if (type != state->ZoneInfoType) { return 0; } - StrongCacheNode *node = find_in_strong_cache(ZONEINFO_STRONG_CACHE, key); + StrongCacheNode *cache = state->ZONEINFO_STRONG_CACHE; + StrongCacheNode *node = find_in_strong_cache(cache, key); if (node != NULL) { - remove_from_strong_cache(node); + remove_from_strong_cache(state, node); strong_cache_node_free(node); } @@ -2392,14 +2513,15 @@ eject_from_strong_cache(const PyTypeObject *const type, PyObject *key) * it is not at the front of the cache, it needs to be moved there. */ static void -move_strong_cache_node_to_front(StrongCacheNode **root, StrongCacheNode *node) +move_strong_cache_node_to_front(zoneinfo_state *state, StrongCacheNode **root, + StrongCacheNode *node) { StrongCacheNode *root_p = *root; if (root_p == node) { return; } - remove_from_strong_cache(node); + remove_from_strong_cache(state, node); node->prev = NULL; node->next = root_p; @@ -2421,18 +2543,20 @@ move_strong_cache_node_to_front(StrongCacheNode **root, StrongCacheNode *node) * always returns a cache miss for subclasses. */ static PyObject * -zone_from_strong_cache(const PyTypeObject *const type, PyObject *const key) +zone_from_strong_cache(zoneinfo_state *state, const PyTypeObject *const type, + PyObject *const key) { - if (type != &PyZoneInfo_ZoneInfoType) { + if (type != state->ZoneInfoType) { return NULL; // Strong cache currently only implemented for base class } - StrongCacheNode *node = find_in_strong_cache(ZONEINFO_STRONG_CACHE, key); + StrongCacheNode *cache = state->ZONEINFO_STRONG_CACHE; + StrongCacheNode *node = find_in_strong_cache(cache, key); if (node != NULL) { - move_strong_cache_node_to_front(&ZONEINFO_STRONG_CACHE, node); - Py_INCREF(node->zone); - return node->zone; + StrongCacheNode **root = &(state->ZONEINFO_STRONG_CACHE); + move_strong_cache_node_to_front(state, root, node); + return Py_NewRef(node->zone); } return NULL; // Cache miss @@ -2445,16 +2569,16 @@ zone_from_strong_cache(const PyTypeObject *const type, PyObject *const key) * the cache to at most ZONEINFO_STRONG_CACHE_MAX_SIZE). */ static void -update_strong_cache(const PyTypeObject *const type, PyObject *key, - PyObject *zone) +update_strong_cache(zoneinfo_state *state, const PyTypeObject *const type, + PyObject *key, PyObject *zone) { - if (type != &PyZoneInfo_ZoneInfoType) { + if (type != state->ZoneInfoType) { return; } StrongCacheNode *new_node = strong_cache_node_new(key, zone); - - move_strong_cache_node_to_front(&ZONEINFO_STRONG_CACHE, new_node); + StrongCacheNode **root = &(state->ZONEINFO_STRONG_CACHE); + move_strong_cache_node_to_front(state, root, new_node); StrongCacheNode *node = new_node->next; for (size_t i = 1; i < ZONEINFO_STRONG_CACHE_MAX_SIZE; ++i) { @@ -2479,53 +2603,40 @@ update_strong_cache(const PyTypeObject *const type, PyObject *key, * for everything except the base class. */ void -clear_strong_cache(const PyTypeObject *const type) +clear_strong_cache(zoneinfo_state *state, const PyTypeObject *const type) { - if (type != &PyZoneInfo_ZoneInfoType) { + if (type != state->ZoneInfoType) { return; } - strong_cache_free(ZONEINFO_STRONG_CACHE); - ZONEINFO_STRONG_CACHE = NULL; + strong_cache_free(state->ZONEINFO_STRONG_CACHE); + state->ZONEINFO_STRONG_CACHE = NULL; } static PyObject * new_weak_cache(void) { - PyObject *weakref_module = PyImport_ImportModule("weakref"); - if (weakref_module == NULL) { + PyObject *WeakValueDictionary = + _PyImport_GetModuleAttrString("weakref", "WeakValueDictionary"); + if (WeakValueDictionary == NULL) { return NULL; } - - PyObject *weak_cache = - PyObject_CallMethod(weakref_module, "WeakValueDictionary", ""); - Py_DECREF(weakref_module); + PyObject *weak_cache = PyObject_CallNoArgs(WeakValueDictionary); + Py_DECREF(WeakValueDictionary); return weak_cache; } +// This function is not idempotent and must be called on a new module object. static int -initialize_caches(void) +initialize_caches(zoneinfo_state *state) { - // TODO: Move to a PyModule_GetState / PEP 573 based caching system. - if (TIMEDELTA_CACHE == NULL) { - TIMEDELTA_CACHE = PyDict_New(); - } - else { - Py_INCREF(TIMEDELTA_CACHE); - } - - if (TIMEDELTA_CACHE == NULL) { + state->TIMEDELTA_CACHE = PyDict_New(); + if (state->TIMEDELTA_CACHE == NULL) { return -1; } - if (ZONEINFO_WEAK_CACHE == NULL) { - ZONEINFO_WEAK_CACHE = new_weak_cache(); - } - else { - Py_INCREF(ZONEINFO_WEAK_CACHE); - } - - if (ZONEINFO_WEAK_CACHE == NULL) { + state->ZONEINFO_WEAK_CACHE = new_weak_cache(); + if (state->ZONEINFO_WEAK_CACHE == NULL) { return -1; } @@ -2552,31 +2663,18 @@ zoneinfo_init_subclass(PyTypeObject *cls, PyObject *args, PyObject **kwargs) ///// // Specify the ZoneInfo type static PyMethodDef zoneinfo_methods[] = { - {"clear_cache", (PyCFunction)(void (*)(void))zoneinfo_clear_cache, - METH_VARARGS | METH_KEYWORDS | METH_CLASS, - PyDoc_STR("Clear the ZoneInfo cache.")}, - {"no_cache", (PyCFunction)(void (*)(void))zoneinfo_no_cache, - METH_VARARGS | METH_KEYWORDS | METH_CLASS, - PyDoc_STR("Get a new instance of ZoneInfo, bypassing the cache.")}, - {"from_file", (PyCFunction)(void (*)(void))zoneinfo_from_file, - METH_VARARGS | METH_KEYWORDS | METH_CLASS, - PyDoc_STR("Create a ZoneInfo file from a file object.")}, - {"utcoffset", (PyCFunction)zoneinfo_utcoffset, METH_O, - PyDoc_STR("Retrieve a timedelta representing the UTC offset in a zone at " - "the given datetime.")}, - {"dst", (PyCFunction)zoneinfo_dst, METH_O, - PyDoc_STR("Retrieve a timedelta representing the amount of DST applied " - "in a zone at the given datetime.")}, - {"tzname", (PyCFunction)zoneinfo_tzname, METH_O, - PyDoc_STR("Retrieve a string containing the abbreviation for the time " - "zone that applies in a zone at a given datetime.")}, + ZONEINFO_ZONEINFO_CLEAR_CACHE_METHODDEF + ZONEINFO_ZONEINFO_NO_CACHE_METHODDEF + ZONEINFO_ZONEINFO_FROM_FILE_METHODDEF + ZONEINFO_ZONEINFO_UTCOFFSET_METHODDEF + ZONEINFO_ZONEINFO_DST_METHODDEF + ZONEINFO_ZONEINFO_TZNAME_METHODDEF {"fromutc", (PyCFunction)zoneinfo_fromutc, METH_O, PyDoc_STR("Given a datetime with local time in UTC, retrieve an adjusted " "datetime in local time.")}, {"__reduce__", (PyCFunction)zoneinfo_reduce, METH_NOARGS, PyDoc_STR("Function for serialization with the pickle protocol.")}, - {"_unpickle", (PyCFunction)zoneinfo__unpickle, METH_VARARGS | METH_CLASS, - PyDoc_STR("Private method used in unpickling.")}, + ZONEINFO_ZONEINFO__UNPICKLE_METHODDEF {"__init_subclass__", (PyCFunction)(void (*)(void))zoneinfo_init_subclass, METH_VARARGS | METH_KEYWORDS | METH_CLASS, PyDoc_STR("Function to initialize subclasses.")}, @@ -2589,55 +2687,88 @@ static PyMemberDef zoneinfo_members[] = { .type = T_OBJECT_EX, .flags = READONLY, .doc = NULL}, + {.name = "__weaklistoffset__", + .offset = offsetof(PyZoneInfo_ZoneInfo, weakreflist), + .type = T_PYSSIZET, + .flags = READONLY}, {NULL}, /* Sentinel */ }; -static PyTypeObject PyZoneInfo_ZoneInfoType = { - PyVarObject_HEAD_INIT(NULL, 0) // - .tp_name = "zoneinfo.ZoneInfo", - .tp_basicsize = sizeof(PyZoneInfo_ZoneInfo), - .tp_weaklistoffset = offsetof(PyZoneInfo_ZoneInfo, weakreflist), - .tp_repr = (reprfunc)zoneinfo_repr, - .tp_str = (reprfunc)zoneinfo_str, - .tp_getattro = PyObject_GenericGetAttr, - .tp_flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE), - /* .tp_doc = zoneinfo_doc, */ - .tp_methods = zoneinfo_methods, - .tp_members = zoneinfo_members, - .tp_new = zoneinfo_new, - .tp_dealloc = zoneinfo_dealloc, +static PyType_Slot zoneinfo_slots[] = { + {Py_tp_repr, zoneinfo_repr}, + {Py_tp_str, zoneinfo_str}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_methods, zoneinfo_methods}, + {Py_tp_members, zoneinfo_members}, + {Py_tp_new, zoneinfo_new}, + {Py_tp_dealloc, zoneinfo_dealloc}, + {Py_tp_traverse, zoneinfo_traverse}, + {Py_tp_clear, zoneinfo_clear}, + {0, NULL}, +}; + +static PyType_Spec zoneinfo_spec = { + .name = "zoneinfo.ZoneInfo", + .basicsize = sizeof(PyZoneInfo_ZoneInfo), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE), + .slots = zoneinfo_slots, }; ///// // Specify the _zoneinfo module static PyMethodDef module_methods[] = {{NULL, NULL}}; -static void -module_free(void *m) + +static int +module_traverse(PyObject *mod, visitproc visit, void *arg) { - Py_XDECREF(_tzpath_find_tzfile); - _tzpath_find_tzfile = NULL; + zoneinfo_state *state = zoneinfo_get_state(mod); - Py_XDECREF(_common_mod); - _common_mod = NULL; + Py_VISIT(state->ZoneInfoType); + Py_VISIT(state->io_open); + Py_VISIT(state->_tzpath_find_tzfile); + Py_VISIT(state->_common_mod); + Py_VISIT(state->TIMEDELTA_CACHE); + Py_VISIT(state->ZONEINFO_WEAK_CACHE); - Py_XDECREF(io_open); - io_open = NULL; + StrongCacheNode *node = state->ZONEINFO_STRONG_CACHE; + while (node != NULL) { + StrongCacheNode *next = node->next; + Py_VISIT(node->key); + Py_VISIT(node->zone); + node = next; + } - xdecref_ttinfo(&NO_TTINFO); + Py_VISIT(state->NO_TTINFO.utcoff); + Py_VISIT(state->NO_TTINFO.dstoff); + Py_VISIT(state->NO_TTINFO.tzname); - if (TIMEDELTA_CACHE != NULL && Py_REFCNT(TIMEDELTA_CACHE) > 1) { - Py_DECREF(TIMEDELTA_CACHE); - } else { - Py_CLEAR(TIMEDELTA_CACHE); - } + return 0; +} - if (ZONEINFO_WEAK_CACHE != NULL && Py_REFCNT(ZONEINFO_WEAK_CACHE) > 1) { - Py_DECREF(ZONEINFO_WEAK_CACHE); - } else { - Py_CLEAR(ZONEINFO_WEAK_CACHE); - } +static int +module_clear(PyObject *mod) +{ + zoneinfo_state *state = zoneinfo_get_state(mod); + + Py_CLEAR(state->ZoneInfoType); + Py_CLEAR(state->io_open); + Py_CLEAR(state->_tzpath_find_tzfile); + Py_CLEAR(state->_common_mod); + Py_CLEAR(state->TIMEDELTA_CACHE); + Py_CLEAR(state->ZONEINFO_WEAK_CACHE); + clear_strong_cache(state, state->ZoneInfoType); + Py_CLEAR(state->NO_TTINFO.utcoff); + Py_CLEAR(state->NO_TTINFO.dstoff); + Py_CLEAR(state->NO_TTINFO.tzname); + + return 0; +} - clear_strong_cache(&PyZoneInfo_ZoneInfoType); +static void +module_free(void *mod) +{ + (void)module_clear((PyObject *)mod); } static int @@ -2647,55 +2778,45 @@ zoneinfomodule_exec(PyObject *m) if (PyDateTimeAPI == NULL) { goto error; } - PyZoneInfo_ZoneInfoType.tp_base = PyDateTimeAPI->TZInfoType; - if (PyType_Ready(&PyZoneInfo_ZoneInfoType) < 0) { - goto error; - } - if (PyModule_AddObjectRef(m, "ZoneInfo", (PyObject *)&PyZoneInfo_ZoneInfoType) < 0) { + zoneinfo_state *state = zoneinfo_get_state(m); + PyObject *base = (PyObject *)PyDateTimeAPI->TZInfoType; + state->ZoneInfoType = (PyTypeObject *)PyType_FromModuleAndSpec(m, + &zoneinfo_spec, base); + if (state->ZoneInfoType == NULL) { goto error; } - /* Populate imports */ - PyObject *_tzpath_module = PyImport_ImportModule("zoneinfo._tzpath"); - if (_tzpath_module == NULL) { + int rc = PyModule_AddObjectRef(m, "ZoneInfo", + (PyObject *)state->ZoneInfoType); + if (rc < 0) { goto error; } - _tzpath_find_tzfile = - PyObject_GetAttrString(_tzpath_module, "find_tzfile"); - Py_DECREF(_tzpath_module); - if (_tzpath_find_tzfile == NULL) { - goto error; - } - - PyObject *io_module = PyImport_ImportModule("io"); - if (io_module == NULL) { + /* Populate imports */ + state->_tzpath_find_tzfile = + _PyImport_GetModuleAttrString("zoneinfo._tzpath", "find_tzfile"); + if (state->_tzpath_find_tzfile == NULL) { goto error; } - io_open = PyObject_GetAttrString(io_module, "open"); - Py_DECREF(io_module); - if (io_open == NULL) { + state->io_open = _PyImport_GetModuleAttrString("io", "open"); + if (state->io_open == NULL) { goto error; } - _common_mod = PyImport_ImportModule("zoneinfo._common"); - if (_common_mod == NULL) { + state->_common_mod = PyImport_ImportModule("zoneinfo._common"); + if (state->_common_mod == NULL) { goto error; } - if (NO_TTINFO.utcoff == NULL) { - NO_TTINFO.utcoff = Py_None; - NO_TTINFO.dstoff = Py_None; - NO_TTINFO.tzname = Py_None; - - for (size_t i = 0; i < 3; ++i) { - Py_INCREF(Py_None); - } + if (state->NO_TTINFO.utcoff == NULL) { + state->NO_TTINFO.utcoff = Py_NewRef(Py_None); + state->NO_TTINFO.dstoff = Py_NewRef(Py_None); + state->NO_TTINFO.tzname = Py_NewRef(Py_None); } - if (initialize_caches()) { + if (initialize_caches(state)) { goto error; } @@ -2706,16 +2827,22 @@ error: } static PyModuleDef_Slot zoneinfomodule_slots[] = { - {Py_mod_exec, zoneinfomodule_exec}, {0, NULL}}; + {Py_mod_exec, zoneinfomodule_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, + {0, NULL}, +}; static struct PyModuleDef zoneinfomodule = { - PyModuleDef_HEAD_INIT, + .m_base = PyModuleDef_HEAD_INIT, .m_name = "_zoneinfo", .m_doc = "C implementation of the zoneinfo module", - .m_size = 0, + .m_size = sizeof(zoneinfo_state), .m_methods = module_methods, .m_slots = zoneinfomodule_slots, - .m_free = (freefunc)module_free}; + .m_traverse = module_traverse, + .m_clear = module_clear, + .m_free = module_free, +}; PyMODINIT_FUNC PyInit__zoneinfo(void) diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c index a04e6a4e..6680820d 100644 --- a/Modules/arraymodule.c +++ b/Modules/arraymodule.c @@ -13,7 +13,6 @@ #include "pycore_bytesobject.h" // _PyBytes_Repeat #include "structmember.h" // PyMemberDef #include <stddef.h> // offsetof() -#include <stddef.h> /*[clinic input] module array @@ -58,9 +57,10 @@ typedef struct { PyTypeObject *ArrayType; PyTypeObject *ArrayIterType; + PyObject *array_reconstructor; + PyObject *str_read; PyObject *str_write; - PyObject *str__array_reconstructor; PyObject *str___dict__; PyObject *str_iter; } array_state; @@ -708,8 +708,7 @@ array_richcompare(PyObject *v, PyObject *w, int op) res = Py_False; else res = Py_True; - Py_INCREF(res); - return res; + return Py_NewRef(res); } if (va->ob_descr == wa->ob_descr && va->ob_descr->compareitems != NULL) { @@ -732,8 +731,7 @@ array_richcompare(PyObject *v, PyObject *w, int op) default: return NULL; /* cannot happen */ } PyObject *res = cmp ? Py_True : Py_False; - Py_INCREF(res); - return res; + return Py_NewRef(res); } @@ -741,10 +739,12 @@ array_richcompare(PyObject *v, PyObject *w, int op) k = 1; for (i = 0; i < Py_SIZE(va) && i < Py_SIZE(wa); i++) { vi = getarrayitem(v, i); + if (vi == NULL) { + return NULL; + } wi = getarrayitem(w, i); - if (vi == NULL || wi == NULL) { - Py_XDECREF(vi); - Py_XDECREF(wi); + if (wi == NULL) { + Py_DECREF(vi); return NULL; } k = PyObject_RichCompareBool(vi, wi, Py_EQ); @@ -777,18 +777,15 @@ array_richcompare(PyObject *v, PyObject *w, int op) res = Py_True; else res = Py_False; - Py_INCREF(res); - return res; + return Py_NewRef(res); } /* We have an item that differs. First, shortcuts for EQ/NE */ if (op == Py_EQ) { - Py_INCREF(Py_False); - res = Py_False; + res = Py_NewRef(Py_False); } else if (op == Py_NE) { - Py_INCREF(Py_True); - res = Py_True; + res = Py_NewRef(Py_True); } else { /* Compare the final item again using the proper operator */ @@ -1059,8 +1056,7 @@ array_inplace_concat(arrayobject *self, PyObject *bb) } if (array_do_extend(state, self, bb) == -1) return NULL; - Py_INCREF(self); - return (PyObject *)self; + return Py_NewRef(self); } static PyObject * @@ -1084,8 +1080,7 @@ array_inplace_repeat(arrayobject *self, Py_ssize_t n) _PyBytes_Repeat(self->ob_item, n*size, self->ob_item, size); } - Py_INCREF(self); - return (PyObject *)self; + return Py_NewRef(self); } @@ -1779,9 +1774,9 @@ static PyObject * array_array___sizeof___impl(arrayobject *self) /*[clinic end generated code: output=d8e1c61ebbe3eaed input=805586565bf2b3c6]*/ { - Py_ssize_t res; - res = _PyObject_SIZE(Py_TYPE(self)) + self->allocated * self->ob_descr->itemsize; - return PyLong_FromSsize_t(res); + size_t res = _PyObject_SIZE(Py_TYPE(self)); + res += (size_t)self->allocated * (size_t)self->ob_descr->itemsize; + return PyLong_FromSize_t(res); } @@ -1946,9 +1941,8 @@ make_array(PyTypeObject *arraytype, char typecode, PyObject *items) Py_DECREF(typecode_obj); return NULL; } - Py_INCREF(items); PyTuple_SET_ITEM(new_args, 0, typecode_obj); - PyTuple_SET_ITEM(new_args, 1, items); + PyTuple_SET_ITEM(new_args, 1, Py_NewRef(items)); array_obj = array_new(arraytype, new_args, NULL); Py_DECREF(new_args); @@ -2192,22 +2186,17 @@ array_array___reduce_ex___impl(arrayobject *self, PyTypeObject *cls, PyObject *array_str; int typecode = self->ob_descr->typecode; int mformat_code; - static PyObject *array_reconstructor = NULL; long protocol; array_state *state = get_array_state_by_class(cls); assert(state != NULL); - if (array_reconstructor == NULL) { - PyObject *array_module = PyImport_ImportModule("array"); - if (array_module == NULL) - return NULL; - array_reconstructor = PyObject_GetAttr( - array_module, - state->str__array_reconstructor); - Py_DECREF(array_module); - if (array_reconstructor == NULL) + if (state->array_reconstructor == NULL) { + state->array_reconstructor = _PyImport_GetModuleAttrString( + "array", "_array_reconstructor"); + if (state->array_reconstructor == NULL) { return NULL; + } } if (!PyLong_Check(value)) { @@ -2223,8 +2212,7 @@ array_array___reduce_ex___impl(arrayobject *self, PyTypeObject *cls, return NULL; } if (dict == NULL) { - dict = Py_None; - Py_INCREF(dict); + dict = Py_NewRef(Py_None); } mformat_code = typecode_to_mformat_code(typecode); @@ -2258,8 +2246,10 @@ array_array___reduce_ex___impl(arrayobject *self, PyTypeObject *cls, Py_DECREF(dict); return NULL; } + + assert(state->array_reconstructor != NULL); result = Py_BuildValue( - "O(OCiN)O", array_reconstructor, Py_TYPE(self), typecode, + "O(OCiN)O", state->array_reconstructor, Py_TYPE(self), typecode, mformat_code, array_str, dict); Py_DECREF(dict); return result; @@ -2309,6 +2299,7 @@ static PyMethodDef array_methods[] = { ARRAY_ARRAY_TOBYTES_METHODDEF ARRAY_ARRAY_TOUNICODE_METHODDEF ARRAY_ARRAY___SIZEOF___METHODDEF + {"__class_getitem__", Py_GenericAlias, METH_O|METH_CLASS, PyDoc_STR("See PEP 585")}, {NULL, NULL} /* sentinel */ }; @@ -2573,8 +2564,7 @@ array_buffer_getbuf(arrayobject *self, Py_buffer *view, int flags) } view->buf = (void *)self->ob_item; - view->obj = (PyObject*)self; - Py_INCREF(self); + view->obj = Py_NewRef(self); if (view->buf == NULL) view->buf = (void *)emptybuf; view->len = Py_SIZE(self) * self->ob_descr->itemsize; @@ -2886,8 +2876,7 @@ array_iter(arrayobject *ao) if (it == NULL) return NULL; - Py_INCREF(ao); - it->ao = ao; + it->ao = (arrayobject*)Py_NewRef(ao); it->index = 0; it->getitem = ao->ob_descr->getitem; PyObject_GC_Track(it); @@ -3018,6 +3007,7 @@ array_traverse(PyObject *module, visitproc visit, void *arg) array_state *state = get_array_state(module); Py_VISIT(state->ArrayType); Py_VISIT(state->ArrayIterType); + Py_VISIT(state->array_reconstructor); return 0; } @@ -3027,9 +3017,9 @@ array_clear(PyObject *module) array_state *state = get_array_state(module); Py_CLEAR(state->ArrayType); Py_CLEAR(state->ArrayIterType); + Py_CLEAR(state->array_reconstructor); Py_CLEAR(state->str_read); Py_CLEAR(state->str_write); - Py_CLEAR(state->str__array_reconstructor); Py_CLEAR(state->str___dict__); Py_CLEAR(state->str_iter); return 0; @@ -3072,10 +3062,10 @@ array_modexec(PyObject *m) PyObject *typecodes; const struct arraydescr *descr; + state->array_reconstructor = NULL; /* Add interned strings */ ADD_INTERNED(state, read); ADD_INTERNED(state, write); - ADD_INTERNED(state, _array_reconstructor); ADD_INTERNED(state, __dict__); ADD_INTERNED(state, iter); @@ -3083,19 +3073,14 @@ array_modexec(PyObject *m) CREATE_TYPE(m, state->ArrayIterType, &arrayiter_spec); Py_SET_TYPE(state->ArrayIterType, &PyType_Type); - Py_INCREF((PyObject *)state->ArrayType); - if (PyModule_AddObject(m, "ArrayType", (PyObject *)state->ArrayType) < 0) { + if (PyModule_AddObject(m, "ArrayType", + Py_NewRef((PyObject *)state->ArrayType)) < 0) { Py_DECREF((PyObject *)state->ArrayType); return -1; } - PyObject *abc_mod = PyImport_ImportModule("collections.abc"); - if (!abc_mod) { - Py_DECREF((PyObject *)state->ArrayType); - return -1; - } - PyObject *mutablesequence = PyObject_GetAttrString(abc_mod, "MutableSequence"); - Py_DECREF(abc_mod); + PyObject *mutablesequence = _PyImport_GetModuleAttrString( + "collections.abc", "MutableSequence"); if (!mutablesequence) { Py_DECREF((PyObject *)state->ArrayType); return -1; @@ -3128,6 +3113,7 @@ array_modexec(PyObject *m) static PyModuleDef_Slot arrayslots[] = { {Py_mod_exec, array_modexec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; diff --git a/Modules/atexitmodule.c b/Modules/atexitmodule.c index a1c511e0..5882d405 100644 --- a/Modules/atexitmodule.c +++ b/Modules/atexitmodule.c @@ -7,6 +7,7 @@ */ #include "Python.h" +#include "pycore_atexit.h" #include "pycore_initconfig.h" // _PyStatus_NO_MEMORY #include "pycore_interp.h" // PyInterpreterState.atexit #include "pycore_pystate.h" // _PyInterpreterState_GET @@ -22,10 +23,36 @@ get_atexit_state(void) } +int +_Py_AtExit(PyInterpreterState *interp, + atexit_datacallbackfunc func, void *data) +{ + assert(interp == _PyInterpreterState_GET()); + atexit_callback *callback = PyMem_Malloc(sizeof(atexit_callback)); + if (callback == NULL) { + PyErr_NoMemory(); + return -1; + } + callback->func = func; + callback->data = data; + callback->next = NULL; + + struct atexit_state *state = &interp->atexit; + if (state->ll_callbacks == NULL) { + state->ll_callbacks = callback; + state->last_ll_callback = callback; + } + else { + state->last_ll_callback->next = callback; + } + return 0; +} + + static void atexit_delete_cb(struct atexit_state *state, int i) { - atexit_callback *cb = state->callbacks[i]; + atexit_py_callback *cb = state->callbacks[i]; state->callbacks[i] = NULL; Py_DECREF(cb->func); @@ -39,7 +66,7 @@ atexit_delete_cb(struct atexit_state *state, int i) static void atexit_cleanup(struct atexit_state *state) { - atexit_callback *cb; + atexit_py_callback *cb; for (int i = 0; i < state->ncallbacks; i++) { cb = state->callbacks[i]; if (cb == NULL) @@ -60,7 +87,7 @@ _PyAtExit_Init(PyInterpreterState *interp) state->callback_len = 32; state->ncallbacks = 0; - state->callbacks = PyMem_New(atexit_callback*, state->callback_len); + state->callbacks = PyMem_New(atexit_py_callback*, state->callback_len); if (state->callbacks == NULL) { return _PyStatus_NO_MEMORY(); } @@ -75,6 +102,18 @@ _PyAtExit_Fini(PyInterpreterState *interp) atexit_cleanup(state); PyMem_Free(state->callbacks); state->callbacks = NULL; + + atexit_callback *next = state->ll_callbacks; + state->ll_callbacks = NULL; + while (next != NULL) { + atexit_callback *callback = next; + next = callback->next; + atexit_datacallbackfunc exitfunc = callback->func; + void *data = callback->data; + // It was allocated in _PyAtExit_AddCallback(). + PyMem_Free(callback); + exitfunc(data); + } } @@ -88,7 +127,7 @@ atexit_callfuncs(struct atexit_state *state) } for (int i = state->ncallbacks - 1; i >= 0; i--) { - atexit_callback *cb = state->callbacks[i]; + atexit_py_callback *cb = state->callbacks[i]; if (cb == NULL) { continue; } @@ -152,17 +191,17 @@ atexit_register(PyObject *module, PyObject *args, PyObject *kwargs) struct atexit_state *state = get_atexit_state(); if (state->ncallbacks >= state->callback_len) { - atexit_callback **r; + atexit_py_callback **r; state->callback_len += 16; - size_t size = sizeof(atexit_callback*) * (size_t)state->callback_len; - r = (atexit_callback**)PyMem_Realloc(state->callbacks, size); + size_t size = sizeof(atexit_py_callback*) * (size_t)state->callback_len; + r = (atexit_py_callback**)PyMem_Realloc(state->callbacks, size); if (r == NULL) { return PyErr_NoMemory(); } state->callbacks = r; } - atexit_callback *callback = PyMem_Malloc(sizeof(atexit_callback)); + atexit_py_callback *callback = PyMem_Malloc(sizeof(atexit_py_callback)); if (callback == NULL) { return PyErr_NoMemory(); } @@ -233,7 +272,7 @@ atexit_unregister(PyObject *module, PyObject *func) struct atexit_state *state = get_atexit_state(); for (int i = 0; i < state->ncallbacks; i++) { - atexit_callback *cb = state->callbacks[i]; + atexit_py_callback *cb = state->callbacks[i]; if (cb == NULL) { continue; } @@ -275,12 +314,18 @@ upon normal program termination.\n\ Two public functions, register and unregister, are defined.\n\ "); +static PyModuleDef_Slot atexitmodule_slots[] = { + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, + {0, NULL} +}; + static struct PyModuleDef atexitmodule = { PyModuleDef_HEAD_INIT, .m_name = "atexit", .m_doc = atexit__doc__, .m_size = 0, .m_methods = atexit_methods, + .m_slots = atexitmodule_slots, }; PyMODINIT_FUNC diff --git a/Modules/audioop.c b/Modules/audioop.c index b764dd97..604306d4 100644 --- a/Modules/audioop.c +++ b/Modules/audioop.c @@ -75,6 +75,8 @@ static const int16_t seg_uend[8] = { static int16_t search(int16_t val, const int16_t *table, int size) { + assert(0 <= size); + assert(size < INT16_MAX); int i; for (i = 0; i < size; i++) { @@ -186,6 +188,7 @@ st_14linear2ulaw(int16_t pcm_val) /* 2's complement (14-bit range) */ if (seg >= 8) /* out of range, return maximum value. */ return (unsigned char) (0x7F ^ mask); else { + assert(seg >= 0); uval = (unsigned char) (seg << 4) | ((pcm_val >> (seg + 1)) & 0xF); return (uval ^ mask); } @@ -316,13 +319,13 @@ static const int stepsizeTable[89] = { #ifdef WORDS_BIGENDIAN #define GETINT24(cp, i) ( \ ((unsigned char *)(cp) + (i))[2] + \ - (((unsigned char *)(cp) + (i))[1] << 8) + \ - (((signed char *)(cp) + (i))[0] << 16) ) + (((unsigned char *)(cp) + (i))[1] * (1 << 8)) + \ + (((signed char *)(cp) + (i))[0] * (1 << 16)) ) #else #define GETINT24(cp, i) ( \ ((unsigned char *)(cp) + (i))[0] + \ - (((unsigned char *)(cp) + (i))[1] << 8) + \ - (((signed char *)(cp) + (i))[2] << 16) ) + (((unsigned char *)(cp) + (i))[1] * (1 << 8)) + \ + (((signed char *)(cp) + (i))[2] * (1 << 16)) ) #endif @@ -363,10 +366,10 @@ static const int stepsizeTable[89] = { } while(0) -#define GETSAMPLE32(size, cp, i) ( \ - (size == 1) ? (int)GETINT8((cp), (i)) << 24 : \ - (size == 2) ? (int)GETINT16((cp), (i)) << 16 : \ - (size == 3) ? (int)GETINT24((cp), (i)) << 8 : \ +#define GETSAMPLE32(size, cp, i) ( \ + (size == 1) ? (int)GETINT8((cp), (i)) * (1 << 24) : \ + (size == 2) ? (int)GETINT16((cp), (i)) * (1 << 16) : \ + (size == 3) ? (int)GETINT24((cp), (i)) * (1 << 8) : \ (int)GETINT32((cp), (i))) #define SETSAMPLE32(size, cp, i, val) do { \ @@ -1468,8 +1471,7 @@ audioop_ratecv_impl(PyObject *module, Py_buffer *fragment, int width, len = (Py_ssize_t)(ncp - PyBytes_AsString(str)); rv = PyBytes_FromStringAndSize (PyBytes_AsString(str), len); - Py_DECREF(str); - str = rv; + Py_SETREF(str, rv); if (str == NULL) goto exit; rv = Py_BuildValue("(O(iO))", str, d, samps); @@ -1574,7 +1576,7 @@ audioop_ulaw2lin_impl(PyObject *module, Py_buffer *fragment, int width) cp = fragment->buf; for (i = 0; i < fragment->len*width; i += width) { - int val = st_ulaw2linear16(*cp++) << 16; + int val = st_ulaw2linear16(*cp++) * (1 << 16); SETSAMPLE32(width, ncp, i, val); } return rv; @@ -1648,7 +1650,7 @@ audioop_alaw2lin_impl(PyObject *module, Py_buffer *fragment, int width) cp = fragment->buf; for (i = 0; i < fragment->len*width; i += width) { - val = st_alaw2linear16(*cp++) << 16; + val = st_alaw2linear16(*cp++) * (1 << 16); SETSAMPLE32(width, ncp, i, val); } return rv; @@ -1773,7 +1775,7 @@ audioop_lin2adpcm_impl(PyObject *module, Py_buffer *fragment, int width, /* Step 6 - Output value */ if ( bufferstep ) { - outputbuffer = (delta << 4) & 0xf0; + outputbuffer = (delta * (1 << 4)) & 0xf0; } else { *ncp++ = (delta & 0x0f) | outputbuffer; } @@ -1891,7 +1893,7 @@ audioop_adpcm2lin_impl(PyObject *module, Py_buffer *fragment, int width, step = stepsizeTable[index]; /* Step 6 - Output value */ - SETSAMPLE32(width, ncp, i, valpred << 16); + SETSAMPLE32(width, ncp, i, valpred * (1 << 16)); } rv = Py_BuildValue("(O(ii))", str, valpred, index); @@ -1973,6 +1975,7 @@ audioop_exec(PyObject* module) static PyModuleDef_Slot audioop_slots[] = { {Py_mod_exec, audioop_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; diff --git a/Modules/binascii.c b/Modules/binascii.c index afe49885..4ecff479 100644 --- a/Modules/binascii.c +++ b/Modules/binascii.c @@ -303,14 +303,14 @@ binascii.b2a_uu data: Py_buffer / * - backtick: bool(accept={int}) = False + backtick: bool = False Uuencode line of data. [clinic start generated code]*/ static PyObject * binascii_b2a_uu_impl(PyObject *module, Py_buffer *data, int backtick) -/*[clinic end generated code: output=b1b99de62d9bbeb8 input=b26bc8d32b6ed2f6]*/ +/*[clinic end generated code: output=b1b99de62d9bbeb8 input=beb27822241095cd]*/ { unsigned char *ascii_data; const unsigned char *bin_data; @@ -375,7 +375,7 @@ binascii.a2b_base64 data: ascii_buffer / * - strict_mode: bool(accept={int}) = False + strict_mode: bool = False Decode a line of base64 data. @@ -386,7 +386,7 @@ Decode a line of base64 data. static PyObject * binascii_a2b_base64_impl(PyObject *module, Py_buffer *data, int strict_mode) -/*[clinic end generated code: output=5409557788d4f975 input=3a30c4e3528317c6]*/ +/*[clinic end generated code: output=5409557788d4f975 input=c0c15fd0f8f9a62d]*/ { assert(data->len >= 0); @@ -521,14 +521,14 @@ binascii.b2a_base64 data: Py_buffer / * - newline: bool(accept={int}) = True + newline: bool = True Base64-code line of data. [clinic start generated code]*/ static PyObject * binascii_b2a_base64_impl(PyObject *module, Py_buffer *data, int newline) -/*[clinic end generated code: output=4ad62c8e8485d3b3 input=6083dac5777fa45d]*/ +/*[clinic end generated code: output=4ad62c8e8485d3b3 input=0e20ff59c5f2e3e1]*/ { unsigned char *ascii_data; const unsigned char *bin_data; @@ -952,14 +952,14 @@ binascii_unhexlify_impl(PyObject *module, Py_buffer *hexstr) binascii.a2b_qp data: ascii_buffer - header: bool(accept={int}) = False + header: bool = False Decode a string of qp-encoded data. [clinic start generated code]*/ static PyObject * binascii_a2b_qp_impl(PyObject *module, Py_buffer *data, int header) -/*[clinic end generated code: output=e99f7846cfb9bc53 input=bf6766fea76cce8f]*/ +/*[clinic end generated code: output=e99f7846cfb9bc53 input=bdfb31598d4e47b9]*/ { Py_ssize_t in, out; char ch; @@ -1024,10 +1024,7 @@ binascii_a2b_qp_impl(PyObject *module, Py_buffer *data, int header) out++; } } - if ((rv = PyBytes_FromStringAndSize((char *)odata, out)) == NULL) { - PyMem_Free(odata); - return NULL; - } + rv = PyBytes_FromStringAndSize((char *)odata, out); PyMem_Free(odata); return rv; } @@ -1051,9 +1048,9 @@ to_hex (unsigned char ch, unsigned char *s) binascii.b2a_qp data: Py_buffer - quotetabs: bool(accept={int}) = False - istext: bool(accept={int}) = True - header: bool(accept={int}) = False + quotetabs: bool = False + istext: bool = True + header: bool = False Encode a string using quoted-printable encoding. @@ -1065,7 +1062,7 @@ are both encoded. When quotetabs is set, space and tabs are encoded. static PyObject * binascii_b2a_qp_impl(PyObject *module, Py_buffer *data, int quotetabs, int istext, int header) -/*[clinic end generated code: output=e9884472ebb1a94c input=21fb7eea4a184ba6]*/ +/*[clinic end generated code: output=e9884472ebb1a94c input=e9102879afb0defd]*/ { Py_ssize_t in, out; const unsigned char *databuf; @@ -1232,10 +1229,7 @@ binascii_b2a_qp_impl(PyObject *module, Py_buffer *data, int quotetabs, } } } - if ((rv = PyBytes_FromStringAndSize((char *)odata, out)) == NULL) { - PyMem_Free(odata); - return NULL; - } + rv = PyBytes_FromStringAndSize((char *)odata, out); PyMem_Free(odata); return rv; } @@ -1297,6 +1291,7 @@ binascii_exec(PyObject *module) { static PyModuleDef_Slot binascii_slots[] = { {Py_mod_exec, binascii_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; diff --git a/Modules/cjkcodecs/_codecs_cn.c b/Modules/cjkcodecs/_codecs_cn.c index 8a62f7e2..e2c7908c 100644 --- a/Modules/cjkcodecs/_codecs_cn.c +++ b/Modules/cjkcodecs/_codecs_cn.c @@ -453,14 +453,14 @@ DECODER(hz) } -BEGIN_MAPPINGS_LIST +BEGIN_MAPPINGS_LIST(4) MAPPING_DECONLY(gb2312) MAPPING_DECONLY(gbkext) MAPPING_ENCONLY(gbcommon) MAPPING_ENCDEC(gb18030ext) END_MAPPINGS_LIST -BEGIN_CODECS_LIST +BEGIN_CODECS_LIST(4) CODEC_STATELESS(gb2312) CODEC_STATELESS(gbk) CODEC_STATELESS(gb18030) diff --git a/Modules/cjkcodecs/_codecs_hk.c b/Modules/cjkcodecs/_codecs_hk.c index 4f21569a..e7273bf1 100644 --- a/Modules/cjkcodecs/_codecs_hk.c +++ b/Modules/cjkcodecs/_codecs_hk.c @@ -6,6 +6,10 @@ #define USING_IMPORTED_MAPS +#define CJK_MOD_SPECIFIC_STATE \ + const encode_map *big5_encmap; \ + const decode_map *big5_decmap; + #include "cjkcodecs.h" #include "mappings_hk.h" @@ -13,16 +17,12 @@ * BIG5HKSCS codec */ -static const encode_map *big5_encmap = NULL; -static const decode_map *big5_decmap = NULL; - CODEC_INIT(big5hkscs) { - static int initialized = 0; - - if (!initialized && IMPORT_MAP(tw, big5, &big5_encmap, &big5_decmap)) + cjkcodecs_module_state *st = codec->modstate; + if (IMPORT_MAP(tw, big5, &st->big5_encmap, &st->big5_decmap)) { return -1; - initialized = 1; + } return 0; } @@ -81,7 +81,7 @@ ENCODER(big5hkscs) } } } - else if (TRYMAP_ENC(big5, code, c)) + else if (TRYMAP_ENC_ST(big5, code, c)) ; else return 1; @@ -122,7 +122,7 @@ DECODER(big5hkscs) REQUIRE_INBUF(2); if (0xc6 > c || c > 0xc8 || (c < 0xc7 && INBYTE2 < 0xa1)) { - if (TRYMAP_DEC(big5, decoded, c, INBYTE2)) { + if (TRYMAP_DEC_ST(big5, decoded, c, INBYTE2)) { OUTCHAR(decoded); NEXT_IN(2); continue; @@ -177,14 +177,13 @@ DECODER(big5hkscs) return 0; } - -BEGIN_MAPPINGS_LIST +BEGIN_MAPPINGS_LIST(3) MAPPING_DECONLY(big5hkscs) MAPPING_ENCONLY(big5hkscs_bmp) MAPPING_ENCONLY(big5hkscs_nonbmp) END_MAPPINGS_LIST -BEGIN_CODECS_LIST +BEGIN_CODECS_LIST(1) CODEC_STATELESS_WINIT(big5hkscs) END_CODECS_LIST diff --git a/Modules/cjkcodecs/_codecs_iso2022.c b/Modules/cjkcodecs/_codecs_iso2022.c index 7394cf67..86bb73b9 100644 --- a/Modules/cjkcodecs/_codecs_iso2022.c +++ b/Modules/cjkcodecs/_codecs_iso2022.c @@ -10,6 +10,27 @@ #define EMULATE_JISX0213_2000_ENCODE_INVALID MAP_UNMAPPABLE #define EMULATE_JISX0213_2000_DECODE_INVALID MAP_UNMAPPABLE +#define CJK_MOD_SPECIFIC_STATE \ + /* kr */ \ + const encode_map *cp949_encmap; \ + const decode_map *ksx1001_decmap; \ + \ + /* jp */ \ + const encode_map *jisxcommon_encmap; \ + const decode_map *jisx0208_decmap; \ + const decode_map *jisx0212_decmap; \ + const encode_map *jisx0213_bmp_encmap; \ + const decode_map *jisx0213_1_bmp_decmap; \ + const decode_map *jisx0213_2_bmp_decmap; \ + const encode_map *jisx0213_emp_encmap; \ + const decode_map *jisx0213_1_emp_decmap; \ + const decode_map *jisx0213_2_emp_decmap; \ + \ + /* cn */ \ + const encode_map *gbcommon_encmap; \ + const decode_map *gb2312_decmap; + + #include "cjkcodecs.h" #include "alg_jisx0201.h" #include "emu_jisx0213_2000.h" @@ -90,7 +111,7 @@ #define STATE_CLEARFLAG(f) do { ((state)->c[4]) &= ~(f); } while (0) #define STATE_CLEARFLAGS() do { ((state)->c[4]) = 0; } while (0) -#define ISO2022_CONFIG ((const struct iso2022_config *)config) +#define ISO2022_CONFIG ((const struct iso2022_config *)(codec->config)) #define CONFIG_ISSET(flag) (ISO2022_CONFIG->flags & (flag)) #define CONFIG_DESIGNATIONS (ISO2022_CONFIG->designations) @@ -101,9 +122,12 @@ /*-*- internal data structures -*-*/ -typedef int (*iso2022_init_func)(void); -typedef Py_UCS4 (*iso2022_decode_func)(const unsigned char *data); -typedef DBCHAR (*iso2022_encode_func)(const Py_UCS4 *data, Py_ssize_t *length); +typedef int (*iso2022_init_func)(const MultibyteCodec *codec); +typedef Py_UCS4 (*iso2022_decode_func)(const MultibyteCodec *codec, + const unsigned char *data); +typedef DBCHAR (*iso2022_encode_func)(const MultibyteCodec *codec, + const Py_UCS4 *data, + Py_ssize_t *length); struct iso2022_designation { unsigned char mark; @@ -124,9 +148,11 @@ struct iso2022_config { CODEC_INIT(iso2022) { const struct iso2022_designation *desig; - for (desig = CONFIG_DESIGNATIONS; desig->mark; desig++) - if (desig->initializer != NULL && desig->initializer() != 0) + for (desig = CONFIG_DESIGNATIONS; desig->mark; desig++) { + if (desig->initializer != NULL && desig->initializer(codec) != 0) { return -1; + } + } return 0; } @@ -182,7 +208,7 @@ ENCODER(iso2022) encoded = MAP_UNMAPPABLE; for (dsg = CONFIG_DESIGNATIONS; dsg->mark; dsg++) { Py_ssize_t length = 1; - encoded = dsg->encoder(&c, &length); + encoded = dsg->encoder(codec, &c, &length); if (encoded == MAP_MULTIPLE_AVAIL) { /* this implementation won't work for pair * of non-bmp characters. */ @@ -193,7 +219,7 @@ ENCODER(iso2022) } else length = 2; - encoded = dsg->encoder(&c, &length); + encoded = dsg->encoder(codec, &c, &length); if (encoded != MAP_UNMAPPABLE) { insize = length; break; @@ -288,7 +314,7 @@ DECODER_RESET(iso2022) } static Py_ssize_t -iso2022processesc(const void *config, MultibyteCodec_State *state, +iso2022processesc(const MultibyteCodec *codec, MultibyteCodec_State *state, const unsigned char **inbuf, Py_ssize_t *inleft) { unsigned char charset, designation; @@ -388,7 +414,7 @@ iso2022processesc(const void *config, MultibyteCodec_State *state, } static Py_ssize_t -iso2022processg2(const void *config, MultibyteCodec_State *state, +iso2022processg2(const MultibyteCodec *codec, MultibyteCodec_State *state, const unsigned char **inbuf, Py_ssize_t *inleft, _PyUnicodeWriter *writer) { @@ -442,14 +468,14 @@ DECODER(iso2022) case ESC: REQUIRE_INBUF(2); if (IS_ISO2022ESC(INBYTE2)) { - err = iso2022processesc(config, state, + err = iso2022processesc(codec, state, inbuf, &inleft); if (err != 0) return err; } else if (CONFIG_ISSET(USE_G2) && INBYTE2 == 'N') {/* SS2 */ REQUIRE_INBUF(3); - err = iso2022processg2(config, state, + err = iso2022processg2(codec, state, inbuf, &inleft, writer); if (err != 0) return err; @@ -517,7 +543,7 @@ bypass: } REQUIRE_INBUF(dsg->width); - decoded = dsg->decoder(*inbuf); + decoded = dsg->decoder(codec, *inbuf); if (decoded == MAP_UNMAPPABLE) return dsg->width; @@ -538,64 +564,38 @@ bypass: return 0; } -/*-*- mapping table holders -*-*/ - -#define ENCMAP(enc) static const encode_map *enc##_encmap = NULL; -#define DECMAP(enc) static const decode_map *enc##_decmap = NULL; - -/* kr */ -ENCMAP(cp949) -DECMAP(ksx1001) - -/* jp */ -ENCMAP(jisxcommon) -DECMAP(jisx0208) -DECMAP(jisx0212) -ENCMAP(jisx0213_bmp) -DECMAP(jisx0213_1_bmp) -DECMAP(jisx0213_2_bmp) -ENCMAP(jisx0213_emp) -DECMAP(jisx0213_1_emp) -DECMAP(jisx0213_2_emp) - -/* cn */ -ENCMAP(gbcommon) -DECMAP(gb2312) - -/* tw */ - /*-*- mapping access functions -*-*/ static int -ksx1001_init(void) +ksx1001_init(const MultibyteCodec *codec) { - static int initialized = 0; - - if (!initialized && ( - IMPORT_MAP(kr, cp949, &cp949_encmap, NULL) || - IMPORT_MAP(kr, ksx1001, NULL, &ksx1001_decmap))) + cjkcodecs_module_state *st = codec->modstate; + if (IMPORT_MAP(kr, cp949, &st->cp949_encmap, NULL) || + IMPORT_MAP(kr, ksx1001, NULL, &st->ksx1001_decmap)) + { return -1; - initialized = 1; + } return 0; } static Py_UCS4 -ksx1001_decoder(const unsigned char *data) +ksx1001_decoder(const MultibyteCodec *codec, const unsigned char *data) { Py_UCS4 u; - if (TRYMAP_DEC(ksx1001, u, data[0], data[1])) + if (TRYMAP_DEC_ST(ksx1001, u, data[0], data[1])) return u; else return MAP_UNMAPPABLE; } static DBCHAR -ksx1001_encoder(const Py_UCS4 *data, Py_ssize_t *length) +ksx1001_encoder(const MultibyteCodec *codec, const Py_UCS4 *data, + Py_ssize_t *length) { DBCHAR coded; assert(*length == 1); if (*data < 0x10000) { - if (TRYMAP_ENC(cp949, coded, *data)) { + if (TRYMAP_ENC_ST(cp949, coded, *data)) { if (!(coded & 0x8000)) return coded; } @@ -604,39 +604,39 @@ ksx1001_encoder(const Py_UCS4 *data, Py_ssize_t *length) } static int -jisx0208_init(void) +jisx0208_init(const MultibyteCodec *codec) { - static int initialized = 0; - - if (!initialized && ( - IMPORT_MAP(jp, jisxcommon, &jisxcommon_encmap, NULL) || - IMPORT_MAP(jp, jisx0208, NULL, &jisx0208_decmap))) + cjkcodecs_module_state *st = codec->modstate; + if (IMPORT_MAP(jp, jisxcommon, &st->jisxcommon_encmap, NULL) || + IMPORT_MAP(jp, jisx0208, NULL, &st->jisx0208_decmap)) + { return -1; - initialized = 1; + } return 0; } static Py_UCS4 -jisx0208_decoder(const unsigned char *data) +jisx0208_decoder(const MultibyteCodec *codec, const unsigned char *data) { Py_UCS4 u; if (data[0] == 0x21 && data[1] == 0x40) /* F/W REVERSE SOLIDUS */ return 0xff3c; - else if (TRYMAP_DEC(jisx0208, u, data[0], data[1])) + else if (TRYMAP_DEC_ST(jisx0208, u, data[0], data[1])) return u; else return MAP_UNMAPPABLE; } static DBCHAR -jisx0208_encoder(const Py_UCS4 *data, Py_ssize_t *length) +jisx0208_encoder(const MultibyteCodec *codec, const Py_UCS4 *data, + Py_ssize_t *length) { DBCHAR coded; assert(*length == 1); if (*data < 0x10000) { if (*data == 0xff3c) /* F/W REVERSE SOLIDUS */ return 0x2140; - else if (TRYMAP_ENC(jisxcommon, coded, *data)) { + else if (TRYMAP_ENC_ST(jisxcommon, coded, *data)) { if (!(coded & 0x8000)) return coded; } @@ -645,35 +645,35 @@ jisx0208_encoder(const Py_UCS4 *data, Py_ssize_t *length) } static int -jisx0212_init(void) +jisx0212_init(const MultibyteCodec *codec) { - static int initialized = 0; - - if (!initialized && ( - IMPORT_MAP(jp, jisxcommon, &jisxcommon_encmap, NULL) || - IMPORT_MAP(jp, jisx0212, NULL, &jisx0212_decmap))) + cjkcodecs_module_state *st = codec->modstate; + if (IMPORT_MAP(jp, jisxcommon, &st->jisxcommon_encmap, NULL) || + IMPORT_MAP(jp, jisx0212, NULL, &st->jisx0212_decmap)) + { return -1; - initialized = 1; + } return 0; } static Py_UCS4 -jisx0212_decoder(const unsigned char *data) +jisx0212_decoder(const MultibyteCodec *codec, const unsigned char *data) { Py_UCS4 u; - if (TRYMAP_DEC(jisx0212, u, data[0], data[1])) + if (TRYMAP_DEC_ST(jisx0212, u, data[0], data[1])) return u; else return MAP_UNMAPPABLE; } static DBCHAR -jisx0212_encoder(const Py_UCS4 *data, Py_ssize_t *length) +jisx0212_encoder(const MultibyteCodec *codec, const Py_UCS4 *data, + Py_ssize_t *length) { DBCHAR coded; assert(*length == 1); if (*data < 0x10000) { - if (TRYMAP_ENC(jisxcommon, coded, *data)) { + if (TRYMAP_ENC_ST(jisxcommon, coded, *data)) { if (coded & 0x8000) return coded & 0x7fff; } @@ -682,44 +682,37 @@ jisx0212_encoder(const Py_UCS4 *data, Py_ssize_t *length) } static int -jisx0213_init(void) +jisx0213_init(const MultibyteCodec *codec) { - static int initialized = 0; - - if (!initialized && ( - jisx0208_init() || - IMPORT_MAP(jp, jisx0213_bmp, - &jisx0213_bmp_encmap, NULL) || - IMPORT_MAP(jp, jisx0213_1_bmp, - NULL, &jisx0213_1_bmp_decmap) || - IMPORT_MAP(jp, jisx0213_2_bmp, - NULL, &jisx0213_2_bmp_decmap) || - IMPORT_MAP(jp, jisx0213_emp, - &jisx0213_emp_encmap, NULL) || - IMPORT_MAP(jp, jisx0213_1_emp, - NULL, &jisx0213_1_emp_decmap) || - IMPORT_MAP(jp, jisx0213_2_emp, - NULL, &jisx0213_2_emp_decmap) || - IMPORT_MAP(jp, jisx0213_pair, &jisx0213_pair_encmap, - &jisx0213_pair_decmap))) + cjkcodecs_module_state *st = codec->modstate; + if (jisx0208_init(codec) || + IMPORT_MAP(jp, jisx0213_bmp, &st->jisx0213_bmp_encmap, NULL) || + IMPORT_MAP(jp, jisx0213_1_bmp, NULL, &st->jisx0213_1_bmp_decmap) || + IMPORT_MAP(jp, jisx0213_2_bmp, NULL, &st->jisx0213_2_bmp_decmap) || + IMPORT_MAP(jp, jisx0213_emp, &st->jisx0213_emp_encmap, NULL) || + IMPORT_MAP(jp, jisx0213_1_emp, NULL, &st->jisx0213_1_emp_decmap) || + IMPORT_MAP(jp, jisx0213_2_emp, NULL, &st->jisx0213_2_emp_decmap) || + IMPORT_MAP(jp, jisx0213_pair, + &jisx0213_pair_encmap, &jisx0213_pair_decmap)) + { return -1; - initialized = 1; + } return 0; } #define config ((void *)2000) static Py_UCS4 -jisx0213_2000_1_decoder(const unsigned char *data) +jisx0213_2000_1_decoder(const MultibyteCodec *codec, const unsigned char *data) { Py_UCS4 u; - EMULATE_JISX0213_2000_DECODE_PLANE1(u, data[0], data[1]) + EMULATE_JISX0213_2000_DECODE_PLANE1(config, u, data[0], data[1]) else if (data[0] == 0x21 && data[1] == 0x40) /* F/W REVERSE SOLIDUS */ return 0xff3c; - else if (TRYMAP_DEC(jisx0208, u, data[0], data[1])) + else if (TRYMAP_DEC_ST(jisx0208, u, data[0], data[1])) ; - else if (TRYMAP_DEC(jisx0213_1_bmp, u, data[0], data[1])) + else if (TRYMAP_DEC_ST(jisx0213_1_bmp, u, data[0], data[1])) ; - else if (TRYMAP_DEC(jisx0213_1_emp, u, data[0], data[1])) + else if (TRYMAP_DEC_ST(jisx0213_1_emp, u, data[0], data[1])) u |= 0x20000; else if (TRYMAP_DEC(jisx0213_pair, u, data[0], data[1])) ; @@ -729,13 +722,13 @@ jisx0213_2000_1_decoder(const unsigned char *data) } static Py_UCS4 -jisx0213_2000_2_decoder(const unsigned char *data) +jisx0213_2000_2_decoder(const MultibyteCodec *codec, const unsigned char *data) { Py_UCS4 u; - EMULATE_JISX0213_2000_DECODE_PLANE2_CHAR(u, data[0], data[1]) - if (TRYMAP_DEC(jisx0213_2_bmp, u, data[0], data[1])) + EMULATE_JISX0213_2000_DECODE_PLANE2_CHAR(config, u, data[0], data[1]) + if (TRYMAP_DEC_ST(jisx0213_2_bmp, u, data[0], data[1])) ; - else if (TRYMAP_DEC(jisx0213_2_emp, u, data[0], data[1])) + else if (TRYMAP_DEC_ST(jisx0213_2_emp, u, data[0], data[1])) u |= 0x20000; else return MAP_UNMAPPABLE; @@ -744,16 +737,16 @@ jisx0213_2000_2_decoder(const unsigned char *data) #undef config static Py_UCS4 -jisx0213_2004_1_decoder(const unsigned char *data) +jisx0213_2004_1_decoder(const MultibyteCodec *codec, const unsigned char *data) { Py_UCS4 u; if (data[0] == 0x21 && data[1] == 0x40) /* F/W REVERSE SOLIDUS */ return 0xff3c; - else if (TRYMAP_DEC(jisx0208, u, data[0], data[1])) + else if (TRYMAP_DEC_ST(jisx0208, u, data[0], data[1])) ; - else if (TRYMAP_DEC(jisx0213_1_bmp, u, data[0], data[1])) + else if (TRYMAP_DEC_ST(jisx0213_1_bmp, u, data[0], data[1])) ; - else if (TRYMAP_DEC(jisx0213_1_emp, u, data[0], data[1])) + else if (TRYMAP_DEC_ST(jisx0213_1_emp, u, data[0], data[1])) u |= 0x20000; else if (TRYMAP_DEC(jisx0213_pair, u, data[0], data[1])) ; @@ -763,12 +756,12 @@ jisx0213_2004_1_decoder(const unsigned char *data) } static Py_UCS4 -jisx0213_2004_2_decoder(const unsigned char *data) +jisx0213_2004_2_decoder(const MultibyteCodec *codec, const unsigned char *data) { Py_UCS4 u; - if (TRYMAP_DEC(jisx0213_2_bmp, u, data[0], data[1])) + if (TRYMAP_DEC_ST(jisx0213_2_bmp, u, data[0], data[1])) ; - else if (TRYMAP_DEC(jisx0213_2_emp, u, data[0], data[1])) + else if (TRYMAP_DEC_ST(jisx0213_2_emp, u, data[0], data[1])) u |= 0x20000; else return MAP_UNMAPPABLE; @@ -776,7 +769,8 @@ jisx0213_2004_2_decoder(const unsigned char *data) } static DBCHAR -jisx0213_encoder(const Py_UCS4 *data, Py_ssize_t *length, void *config) +jisx0213_encoder(const MultibyteCodec *codec, const Py_UCS4 *data, + Py_ssize_t *length, const void *config) { DBCHAR coded; @@ -784,19 +778,19 @@ jisx0213_encoder(const Py_UCS4 *data, Py_ssize_t *length, void *config) case 1: /* first character */ if (*data >= 0x10000) { if ((*data) >> 16 == 0x20000 >> 16) { - EMULATE_JISX0213_2000_ENCODE_EMP(coded, *data) - else if (TRYMAP_ENC(jisx0213_emp, coded, (*data) & 0xffff)) + EMULATE_JISX0213_2000_ENCODE_EMP(config, coded, *data) + else if (TRYMAP_ENC_ST(jisx0213_emp, coded, (*data) & 0xffff)) return coded; } return MAP_UNMAPPABLE; } - EMULATE_JISX0213_2000_ENCODE_BMP(coded, *data) - else if (TRYMAP_ENC(jisx0213_bmp, coded, *data)) { + EMULATE_JISX0213_2000_ENCODE_BMP(config, coded, *data) + else if (TRYMAP_ENC_ST(jisx0213_bmp, coded, *data)) { if (coded == MULTIC) return MAP_MULTIPLE_AVAIL; } - else if (TRYMAP_ENC(jisxcommon, coded, *data)) { + else if (TRYMAP_ENC_ST(jisxcommon, coded, *data)) { if (coded & 0x8000) return MAP_UNMAPPABLE; } @@ -827,9 +821,10 @@ jisx0213_encoder(const Py_UCS4 *data, Py_ssize_t *length, void *config) } static DBCHAR -jisx0213_2000_1_encoder(const Py_UCS4 *data, Py_ssize_t *length) +jisx0213_2000_1_encoder(const MultibyteCodec *codec, const Py_UCS4 *data, + Py_ssize_t *length) { - DBCHAR coded = jisx0213_encoder(data, length, (void *)2000); + DBCHAR coded = jisx0213_encoder(codec, data, length, (void *)2000); if (coded == MAP_UNMAPPABLE || coded == MAP_MULTIPLE_AVAIL) return coded; else if (coded & 0x8000) @@ -839,12 +834,13 @@ jisx0213_2000_1_encoder(const Py_UCS4 *data, Py_ssize_t *length) } static DBCHAR -jisx0213_2000_1_encoder_paironly(const Py_UCS4 *data, Py_ssize_t *length) +jisx0213_2000_1_encoder_paironly(const MultibyteCodec *codec, + const Py_UCS4 *data, Py_ssize_t *length) { DBCHAR coded; Py_ssize_t ilength = *length; - coded = jisx0213_encoder(data, length, (void *)2000); + coded = jisx0213_encoder(codec, data, length, (void *)2000); switch (ilength) { case 1: if (coded == MAP_MULTIPLE_AVAIL) @@ -862,9 +858,10 @@ jisx0213_2000_1_encoder_paironly(const Py_UCS4 *data, Py_ssize_t *length) } static DBCHAR -jisx0213_2000_2_encoder(const Py_UCS4 *data, Py_ssize_t *length) +jisx0213_2000_2_encoder(const MultibyteCodec *codec, const Py_UCS4 *data, + Py_ssize_t *length) { - DBCHAR coded = jisx0213_encoder(data, length, (void *)2000); + DBCHAR coded = jisx0213_encoder(codec, data, length, (void *)2000); if (coded == MAP_UNMAPPABLE || coded == MAP_MULTIPLE_AVAIL) return coded; else if (coded & 0x8000) @@ -874,9 +871,10 @@ jisx0213_2000_2_encoder(const Py_UCS4 *data, Py_ssize_t *length) } static DBCHAR -jisx0213_2004_1_encoder(const Py_UCS4 *data, Py_ssize_t *length) +jisx0213_2004_1_encoder(const MultibyteCodec *codec, const Py_UCS4 *data, + Py_ssize_t *length) { - DBCHAR coded = jisx0213_encoder(data, length, NULL); + DBCHAR coded = jisx0213_encoder(codec, data, length, NULL); if (coded == MAP_UNMAPPABLE || coded == MAP_MULTIPLE_AVAIL) return coded; else if (coded & 0x8000) @@ -886,12 +884,13 @@ jisx0213_2004_1_encoder(const Py_UCS4 *data, Py_ssize_t *length) } static DBCHAR -jisx0213_2004_1_encoder_paironly(const Py_UCS4 *data, Py_ssize_t *length) +jisx0213_2004_1_encoder_paironly(const MultibyteCodec *codec, + const Py_UCS4 *data, Py_ssize_t *length) { DBCHAR coded; Py_ssize_t ilength = *length; - coded = jisx0213_encoder(data, length, NULL); + coded = jisx0213_encoder(codec, data, length, NULL); switch (ilength) { case 1: if (coded == MAP_MULTIPLE_AVAIL) @@ -909,9 +908,10 @@ jisx0213_2004_1_encoder_paironly(const Py_UCS4 *data, Py_ssize_t *length) } static DBCHAR -jisx0213_2004_2_encoder(const Py_UCS4 *data, Py_ssize_t *length) +jisx0213_2004_2_encoder(const MultibyteCodec *codec, const Py_UCS4 *data, + Py_ssize_t *length) { - DBCHAR coded = jisx0213_encoder(data, length, NULL); + DBCHAR coded = jisx0213_encoder(codec, data, length, NULL); if (coded == MAP_UNMAPPABLE || coded == MAP_MULTIPLE_AVAIL) return coded; else if (coded & 0x8000) @@ -921,7 +921,7 @@ jisx0213_2004_2_encoder(const Py_UCS4 *data, Py_ssize_t *length) } static Py_UCS4 -jisx0201_r_decoder(const unsigned char *data) +jisx0201_r_decoder(const MultibyteCodec *codec, const unsigned char *data) { Py_UCS4 u; JISX0201_R_DECODE_CHAR(*data, u) @@ -931,7 +931,8 @@ jisx0201_r_decoder(const unsigned char *data) } static DBCHAR -jisx0201_r_encoder(const Py_UCS4 *data, Py_ssize_t *length) +jisx0201_r_encoder(const MultibyteCodec *codec, const Py_UCS4 *data, + Py_ssize_t *length) { DBCHAR coded; JISX0201_R_ENCODE(*data, coded) @@ -941,7 +942,7 @@ jisx0201_r_encoder(const Py_UCS4 *data, Py_ssize_t *length) } static Py_UCS4 -jisx0201_k_decoder(const unsigned char *data) +jisx0201_k_decoder(const MultibyteCodec *codec, const unsigned char *data) { Py_UCS4 u; JISX0201_K_DECODE_CHAR(*data ^ 0x80, u) @@ -951,7 +952,8 @@ jisx0201_k_decoder(const unsigned char *data) } static DBCHAR -jisx0201_k_encoder(const Py_UCS4 *data, Py_ssize_t *length) +jisx0201_k_encoder(const MultibyteCodec *codec, const Py_UCS4 *data, + Py_ssize_t *length) { DBCHAR coded; JISX0201_K_ENCODE(*data, coded) @@ -961,35 +963,35 @@ jisx0201_k_encoder(const Py_UCS4 *data, Py_ssize_t *length) } static int -gb2312_init(void) +gb2312_init(const MultibyteCodec *codec) { - static int initialized = 0; - - if (!initialized && ( - IMPORT_MAP(cn, gbcommon, &gbcommon_encmap, NULL) || - IMPORT_MAP(cn, gb2312, NULL, &gb2312_decmap))) + cjkcodecs_module_state *st = codec->modstate; + if (IMPORT_MAP(cn, gbcommon, &st->gbcommon_encmap, NULL) || + IMPORT_MAP(cn, gb2312, NULL, &st->gb2312_decmap)) + { return -1; - initialized = 1; + } return 0; } static Py_UCS4 -gb2312_decoder(const unsigned char *data) +gb2312_decoder(const MultibyteCodec *codec, const unsigned char *data) { Py_UCS4 u; - if (TRYMAP_DEC(gb2312, u, data[0], data[1])) + if (TRYMAP_DEC_ST(gb2312, u, data[0], data[1])) return u; else return MAP_UNMAPPABLE; } static DBCHAR -gb2312_encoder(const Py_UCS4 *data, Py_ssize_t *length) +gb2312_encoder(const MultibyteCodec *codec, const Py_UCS4 *data, + Py_ssize_t *length) { DBCHAR coded; assert(*length == 1); if (*data < 0x10000) { - if (TRYMAP_ENC(gbcommon, coded, *data)) { + if (TRYMAP_ENC_ST(gbcommon, coded, *data)) { if (!(coded & 0x8000)) return coded; } @@ -999,13 +1001,14 @@ gb2312_encoder(const Py_UCS4 *data, Py_ssize_t *length) static Py_UCS4 -dummy_decoder(const unsigned char *data) +dummy_decoder(const MultibyteCodec *codec, const unsigned char *data) { return MAP_UNMAPPABLE; } static DBCHAR -dummy_encoder(const Py_UCS4 *data, Py_ssize_t *length) +dummy_encoder(const MultibyteCodec *codec, const Py_UCS4 *data, + Py_ssize_t *length) { return MAP_UNMAPPABLE; } @@ -1119,18 +1122,19 @@ static const struct iso2022_designation iso2022_jp_ext_designations[] = { CONFIGDEF(jp_ext, NO_SHIFT | USE_JISX0208_EXT) -BEGIN_MAPPINGS_LIST +BEGIN_MAPPINGS_LIST(0) /* no mapping table here */ END_MAPPINGS_LIST -#define ISO2022_CODEC(variation) { \ +#define ISO2022_CODEC(variation) \ +NEXT_CODEC = (MultibyteCodec){ \ "iso2022_" #variation, \ &iso2022_##variation##_config, \ iso2022_codec_init, \ _STATEFUL_METHODS(iso2022) \ -}, +}; -BEGIN_CODECS_LIST +BEGIN_CODECS_LIST(7) ISO2022_CODEC(kr) ISO2022_CODEC(jp) ISO2022_CODEC(jp_1) diff --git a/Modules/cjkcodecs/_codecs_jp.c b/Modules/cjkcodecs/_codecs_jp.c index 3a332953..f7127487 100644 --- a/Modules/cjkcodecs/_codecs_jp.c +++ b/Modules/cjkcodecs/_codecs_jp.c @@ -164,7 +164,7 @@ ENCODER(euc_jis_2004) insize = 1; if (c <= 0xFFFF) { - EMULATE_JISX0213_2000_ENCODE_BMP(code, c) + EMULATE_JISX0213_2000_ENCODE_BMP(codec->config, code, c) else if (TRYMAP_ENC(jisx0213_bmp, code, c)) { if (code == MULTIC) { if (inlen - *inpos < 2) { @@ -215,7 +215,7 @@ ENCODER(euc_jis_2004) return 1; } else if (c >> 16 == EMPBASE >> 16) { - EMULATE_JISX0213_2000_ENCODE_EMP(code, c) + EMULATE_JISX0213_2000_ENCODE_EMP(codec->config, code, c) else if (TRYMAP_ENC(jisx0213_emp, code, c & 0xffff)) ; else @@ -271,7 +271,7 @@ DECODER(euc_jis_2004) c3 = INBYTE3 ^ 0x80; /* JIS X 0213 Plane 2 or JIS X 0212 (see NOTES) */ - EMULATE_JISX0213_2000_DECODE_PLANE2(writer, c2, c3) + EMULATE_JISX0213_2000_DECODE_PLANE2(codec->config, writer, c2, c3) else if (TRYMAP_DEC(jisx0213_2_bmp, decoded, c2, c3)) OUTCHAR(decoded); else if (TRYMAP_DEC(jisx0213_2_emp, code, c2, c3)) { @@ -293,7 +293,7 @@ DECODER(euc_jis_2004) c2 = INBYTE2 ^ 0x80; /* JIS X 0213 Plane 1 */ - EMULATE_JISX0213_2000_DECODE_PLANE1(writer, c, c2) + EMULATE_JISX0213_2000_DECODE_PLANE1(codec->config, writer, c, c2) else if (c == 0x21 && c2 == 0x40) OUTCHAR(0xff3c); else if (c == 0x22 && c2 == 0x32) @@ -582,7 +582,7 @@ ENCODER(shift_jis_2004) if (code == NOCHAR) { if (c <= 0xffff) { - EMULATE_JISX0213_2000_ENCODE_BMP(code, c) + EMULATE_JISX0213_2000_ENCODE_BMP(codec->config, code, c) else if (TRYMAP_ENC(jisx0213_bmp, code, c)) { if (code == MULTIC) { if (inlen - *inpos < 2) { @@ -625,7 +625,7 @@ ENCODER(shift_jis_2004) return 1; } else if (c >> 16 == EMPBASE >> 16) { - EMULATE_JISX0213_2000_ENCODE_EMP(code, c) + EMULATE_JISX0213_2000_ENCODE_EMP(codec->config, code, c) else if (TRYMAP_ENC(jisx0213_emp, code, c&0xffff)) ; else @@ -686,7 +686,7 @@ DECODER(shift_jis_2004) if (c1 < 0x5e) { /* Plane 1 */ c1 += 0x21; - EMULATE_JISX0213_2000_DECODE_PLANE1(writer, + EMULATE_JISX0213_2000_DECODE_PLANE1(codec->config, writer, c1, c2) else if (TRYMAP_DEC(jisx0208, decoded, c1, c2)) OUTCHAR(decoded); @@ -708,7 +708,7 @@ DECODER(shift_jis_2004) else c1 -= 0x3d; - EMULATE_JISX0213_2000_DECODE_PLANE2(writer, + EMULATE_JISX0213_2000_DECODE_PLANE2(codec->config, writer, c1, c2) else if (TRYMAP_DEC(jisx0213_2_bmp, decoded, c1, c2)) OUTCHAR(decoded); @@ -733,7 +733,7 @@ DECODER(shift_jis_2004) } -BEGIN_MAPPINGS_LIST +BEGIN_MAPPINGS_LIST(11) MAPPING_DECONLY(jisx0208) MAPPING_DECONLY(jisx0212) MAPPING_ENCONLY(jisxcommon) @@ -747,14 +747,19 @@ BEGIN_MAPPINGS_LIST MAPPING_ENCDEC(cp932ext) END_MAPPINGS_LIST -BEGIN_CODECS_LIST +#define CODEC_CUSTOM(NAME, N, METH) \ + NEXT_CODEC = (MultibyteCodec){NAME, (void *)N, NULL, _STATELESS_METHODS(METH)}; + +BEGIN_CODECS_LIST(7) CODEC_STATELESS(shift_jis) CODEC_STATELESS(cp932) CODEC_STATELESS(euc_jp) CODEC_STATELESS(shift_jis_2004) CODEC_STATELESS(euc_jis_2004) - { "euc_jisx0213", (void *)2000, NULL, _STATELESS_METHODS(euc_jis_2004) }, - { "shift_jisx0213", (void *)2000, NULL, _STATELESS_METHODS(shift_jis_2004) }, + CODEC_CUSTOM("euc_jisx0213", 2000, euc_jis_2004) + CODEC_CUSTOM("shift_jisx0213", 2000, shift_jis_2004) END_CODECS_LIST +#undef CODEC_CUSTOM + I_AM_A_MODULE_FOR(jp) diff --git a/Modules/cjkcodecs/_codecs_kr.c b/Modules/cjkcodecs/_codecs_kr.c index 6d6acb5c..fd9a9fd9 100644 --- a/Modules/cjkcodecs/_codecs_kr.c +++ b/Modules/cjkcodecs/_codecs_kr.c @@ -60,7 +60,7 @@ ENCODER(euc_kr) } else { /* Mapping is found in CP949 extension, - but we encode it in KS X 1001:1998 Annex 3, + but we encode it in KS X 1001:1998, make-up sequence for EUC-KR. */ REQUIRE_OUTBUF(8); @@ -120,7 +120,7 @@ DECODER(euc_kr) if (c == EUCKR_JAMO_FIRSTBYTE && INBYTE2 == EUCKR_JAMO_FILLER) { - /* KS X 1001:1998 Annex 3 make-up sequence */ + /* KS X 1001:1998 make-up sequence */ DBCHAR cho, jung, jong; REQUIRE_INBUF(8); @@ -453,13 +453,13 @@ DECODER(johab) #undef FILL -BEGIN_MAPPINGS_LIST +BEGIN_MAPPINGS_LIST(3) MAPPING_DECONLY(ksx1001) MAPPING_ENCONLY(cp949) MAPPING_DECONLY(cp949ext) END_MAPPINGS_LIST -BEGIN_CODECS_LIST +BEGIN_CODECS_LIST(3) CODEC_STATELESS(euc_kr) CODEC_STATELESS(cp949) CODEC_STATELESS(johab) diff --git a/Modules/cjkcodecs/_codecs_tw.c b/Modules/cjkcodecs/_codecs_tw.c index 722b26b1..3e440991 100644 --- a/Modules/cjkcodecs/_codecs_tw.c +++ b/Modules/cjkcodecs/_codecs_tw.c @@ -130,12 +130,12 @@ DECODER(cp950) -BEGIN_MAPPINGS_LIST +BEGIN_MAPPINGS_LIST(2) MAPPING_ENCDEC(big5) MAPPING_ENCDEC(cp950ext) END_MAPPINGS_LIST -BEGIN_CODECS_LIST +BEGIN_CODECS_LIST(2) CODEC_STATELESS(big5) CODEC_STATELESS(cp950) END_CODECS_LIST diff --git a/Modules/cjkcodecs/cjkcodecs.h b/Modules/cjkcodecs/cjkcodecs.h index ba8fad26..36bc7024 100644 --- a/Modules/cjkcodecs/cjkcodecs.h +++ b/Modules/cjkcodecs/cjkcodecs.h @@ -60,37 +60,55 @@ struct pair_encodemap { DBCHAR code; }; -static const MultibyteCodec *codec_list; -static const struct dbcs_map *mapping_list; +#ifndef CJK_MOD_SPECIFIC_STATE +#define CJK_MOD_SPECIFIC_STATE +#endif + +typedef struct _cjk_mod_state { + int num_mappings; + int num_codecs; + struct dbcs_map *mapping_list; + MultibyteCodec *codec_list; + + CJK_MOD_SPECIFIC_STATE +} cjkcodecs_module_state; + +static inline cjkcodecs_module_state * +get_module_state(PyObject *mod) +{ + void *state = PyModule_GetState(mod); + assert(state != NULL); + return (cjkcodecs_module_state *)state; +} #define CODEC_INIT(encoding) \ - static int encoding##_codec_init(const void *config) + static int encoding##_codec_init(const MultibyteCodec *codec) #define ENCODER_INIT(encoding) \ static int encoding##_encode_init( \ - MultibyteCodec_State *state, const void *config) + MultibyteCodec_State *state, const MultibyteCodec *codec) #define ENCODER(encoding) \ static Py_ssize_t encoding##_encode( \ - MultibyteCodec_State *state, const void *config, \ + MultibyteCodec_State *state, const MultibyteCodec *codec, \ int kind, const void *data, \ Py_ssize_t *inpos, Py_ssize_t inlen, \ unsigned char **outbuf, Py_ssize_t outleft, int flags) #define ENCODER_RESET(encoding) \ static Py_ssize_t encoding##_encode_reset( \ - MultibyteCodec_State *state, const void *config, \ + MultibyteCodec_State *state, const MultibyteCodec *codec, \ unsigned char **outbuf, Py_ssize_t outleft) #define DECODER_INIT(encoding) \ static int encoding##_decode_init( \ - MultibyteCodec_State *state, const void *config) + MultibyteCodec_State *state, const MultibyteCodec *codec) #define DECODER(encoding) \ static Py_ssize_t encoding##_decode( \ - MultibyteCodec_State *state, const void *config, \ + MultibyteCodec_State *state, const MultibyteCodec *codec, \ const unsigned char **inbuf, Py_ssize_t inleft, \ _PyUnicodeWriter *writer) #define DECODER_RESET(encoding) \ static Py_ssize_t encoding##_decode_reset( \ - MultibyteCodec_State *state, const void *config) + MultibyteCodec_State *state, const MultibyteCodec *codec) #define NEXT_IN(i) \ do { \ @@ -193,6 +211,9 @@ static const struct dbcs_map *mapping_list; (m)->bottom]) != NOCHAR) #define TRYMAP_ENC(charset, assi, uni) \ _TRYMAP_ENC(&charset##_encmap[(uni) >> 8], assi, (uni) & 0xff) +#define TRYMAP_ENC_ST(charset, assi, uni) \ + _TRYMAP_ENC(&(codec->modstate->charset##_encmap)[(uni) >> 8], \ + assi, (uni) & 0xff) #define _TRYMAP_DEC(m, assi, val) \ ((m)->map != NULL && \ @@ -201,17 +222,45 @@ static const struct dbcs_map *mapping_list; ((assi) = (m)->map[(val) - (m)->bottom]) != UNIINV) #define TRYMAP_DEC(charset, assi, c1, c2) \ _TRYMAP_DEC(&charset##_decmap[c1], assi, c2) +#define TRYMAP_DEC_ST(charset, assi, c1, c2) \ + _TRYMAP_DEC(&(codec->modstate->charset##_decmap)[c1], assi, c2) + +#define BEGIN_MAPPINGS_LIST(NUM) \ +static int \ +add_mappings(cjkcodecs_module_state *st) \ +{ \ + int idx = 0; \ + (void)idx; \ + st->num_mappings = NUM; \ + st->mapping_list = PyMem_Calloc(NUM, sizeof(struct dbcs_map)); \ + if (st->mapping_list == NULL) { \ + return -1; \ + } -#define BEGIN_MAPPINGS_LIST static const struct dbcs_map _mapping_list[] = { -#define MAPPING_ENCONLY(enc) {#enc, (void*)enc##_encmap, NULL}, -#define MAPPING_DECONLY(enc) {#enc, NULL, (void*)enc##_decmap}, -#define MAPPING_ENCDEC(enc) {#enc, (void*)enc##_encmap, (void*)enc##_decmap}, -#define END_MAPPINGS_LIST \ - {"", NULL, NULL} }; \ - static const struct dbcs_map *mapping_list = \ - (const struct dbcs_map *)_mapping_list; +#define MAPPING_ENCONLY(enc) \ + st->mapping_list[idx++] = (struct dbcs_map){#enc, (void*)enc##_encmap, NULL}; +#define MAPPING_DECONLY(enc) \ + st->mapping_list[idx++] = (struct dbcs_map){#enc, NULL, (void*)enc##_decmap}; +#define MAPPING_ENCDEC(enc) \ + st->mapping_list[idx++] = (struct dbcs_map){#enc, (void*)enc##_encmap, (void*)enc##_decmap}; + +#define END_MAPPINGS_LIST \ + assert(st->num_mappings == idx); \ + return 0; \ +} + +#define BEGIN_CODECS_LIST(NUM) \ +static int \ +add_codecs(cjkcodecs_module_state *st) \ +{ \ + int idx = 0; \ + (void)idx; \ + st->num_codecs = NUM; \ + st->codec_list = PyMem_Calloc(NUM, sizeof(MultibyteCodec)); \ + if (st->codec_list == NULL) { \ + return -1; \ + } -#define BEGIN_CODECS_LIST static const MultibyteCodec _codec_list[] = { #define _STATEFUL_METHODS(enc) \ enc##_encode, \ enc##_encode_init, \ @@ -222,92 +271,129 @@ static const struct dbcs_map *mapping_list; #define _STATELESS_METHODS(enc) \ enc##_encode, NULL, NULL, \ enc##_decode, NULL, NULL, -#define CODEC_STATEFUL(enc) { \ - #enc, NULL, NULL, \ - _STATEFUL_METHODS(enc) \ -}, -#define CODEC_STATELESS(enc) { \ - #enc, NULL, NULL, \ - _STATELESS_METHODS(enc) \ -}, -#define CODEC_STATELESS_WINIT(enc) { \ - #enc, NULL, \ - enc##_codec_init, \ - _STATELESS_METHODS(enc) \ -}, -#define END_CODECS_LIST \ - {"", NULL,} }; \ - static const MultibyteCodec *codec_list = \ - (const MultibyteCodec *)_codec_list; + +#define NEXT_CODEC \ + st->codec_list[idx++] + +#define CODEC_STATEFUL(enc) \ + NEXT_CODEC = (MultibyteCodec){#enc, NULL, NULL, _STATEFUL_METHODS(enc)}; +#define CODEC_STATELESS(enc) \ + NEXT_CODEC = (MultibyteCodec){#enc, NULL, NULL, _STATELESS_METHODS(enc)}; +#define CODEC_STATELESS_WINIT(enc) \ + NEXT_CODEC = (MultibyteCodec){#enc, NULL, enc##_codec_init, _STATELESS_METHODS(enc)}; + +#define END_CODECS_LIST \ + assert(st->num_codecs == idx); \ + for (int i = 0; i < st->num_codecs; i++) { \ + st->codec_list[i].modstate = st; \ + } \ + return 0; \ +} static PyObject * getmultibytecodec(void) { - PyObject *mod = PyImport_ImportModuleNoBlock("_multibytecodec"); - if (mod == NULL) { + return _PyImport_GetModuleAttrString("_multibytecodec", "__create_codec"); +} + +static void +destroy_codec_capsule(PyObject *capsule) +{ + void *ptr = PyCapsule_GetPointer(capsule, CODEC_CAPSULE); + codec_capsule *data = (codec_capsule *)ptr; + Py_DECREF(data->cjk_module); + PyMem_Free(ptr); +} + +static codec_capsule * +capsulate_codec(PyObject *mod, const MultibyteCodec *codec) +{ + codec_capsule *data = PyMem_Malloc(sizeof(codec_capsule)); + if (data == NULL) { + PyErr_NoMemory(); return NULL; } - - PyObject *cofunc = PyObject_GetAttrString(mod, "__create_codec"); - Py_DECREF(mod); - return cofunc; + data->codec = codec; + data->cjk_module = Py_NewRef(mod); + return data; } static PyObject * -getcodec(PyObject *self, PyObject *encoding) +_getcodec(PyObject *self, const MultibyteCodec *codec) { - PyObject *codecobj, *r, *cofunc; - const MultibyteCodec *codec; - const char *enc; - - if (!PyUnicode_Check(encoding)) { - PyErr_SetString(PyExc_TypeError, - "encoding name must be a string."); + PyObject *cofunc = getmultibytecodec(); + if (cofunc == NULL) { return NULL; } - enc = PyUnicode_AsUTF8(encoding); - if (enc == NULL) - return NULL; - cofunc = getmultibytecodec(); - if (cofunc == NULL) + codec_capsule *data = capsulate_codec(self, codec); + if (data == NULL) { + Py_DECREF(cofunc); + return NULL; + } + PyObject *codecobj = PyCapsule_New(data, CODEC_CAPSULE, + destroy_codec_capsule); + if (codecobj == NULL) { + PyMem_Free(data); + Py_DECREF(cofunc); return NULL; + } - for (codec = codec_list; codec->encoding[0]; codec++) - if (strcmp(codec->encoding, enc) == 0) - break; + PyObject *res = PyObject_CallOneArg(cofunc, codecobj); + Py_DECREF(codecobj); + Py_DECREF(cofunc); + return res; +} - if (codec->encoding[0] == '\0') { - PyErr_SetString(PyExc_LookupError, - "no such codec is supported."); +static PyObject * +getcodec(PyObject *self, PyObject *encoding) +{ + if (!PyUnicode_Check(encoding)) { + PyErr_SetString(PyExc_TypeError, + "encoding name must be a string."); return NULL; } - - codecobj = PyCapsule_New((void *)codec, PyMultibyteCodec_CAPSULE_NAME, NULL); - if (codecobj == NULL) + const char *enc = PyUnicode_AsUTF8(encoding); + if (enc == NULL) { return NULL; + } - r = PyObject_CallOneArg(cofunc, codecobj); - Py_DECREF(codecobj); - Py_DECREF(cofunc); + cjkcodecs_module_state *st = get_module_state(self); + for (int i = 0; i < st->num_codecs; i++) { + const MultibyteCodec *codec = &st->codec_list[i]; + if (strcmp(codec->encoding, enc) == 0) { + return _getcodec(self, codec); + } + } - return r; + PyErr_SetString(PyExc_LookupError, + "no such codec is supported."); + return NULL; } +static int add_mappings(cjkcodecs_module_state *); +static int add_codecs(cjkcodecs_module_state *); static int register_maps(PyObject *module) { - const struct dbcs_map *h; + // Init module state. + cjkcodecs_module_state *st = get_module_state(module); + if (add_mappings(st) < 0) { + return -1; + } + if (add_codecs(st) < 0) { + return -1; + } - for (h = mapping_list; h->charset[0] != '\0'; h++) { + for (int i = 0; i < st->num_mappings; i++) { + const struct dbcs_map *h = &st->mapping_list[i]; char mhname[256] = "__map_"; strcpy(mhname + sizeof("__map_") - 1, h->charset); - PyObject *capsule = PyCapsule_New((void *)h, - PyMultibyteCodec_CAPSULE_NAME, NULL); + PyObject *capsule = PyCapsule_New((void *)h, MAP_CAPSULE, NULL); if (capsule == NULL) { return -1; } @@ -371,14 +457,14 @@ importmap(const char *modname, const char *symbol, o = PyObject_GetAttrString(mod, symbol); if (o == NULL) goto errorexit; - else if (!PyCapsule_IsValid(o, PyMultibyteCodec_CAPSULE_NAME)) { + else if (!PyCapsule_IsValid(o, MAP_CAPSULE)) { PyErr_SetString(PyExc_ValueError, "map data must be a Capsule."); goto errorexit; } else { struct dbcs_map *map; - map = PyCapsule_GetPointer(o, PyMultibyteCodec_CAPSULE_NAME); + map = PyCapsule_GetPointer(o, MAP_CAPSULE); if (encmap != NULL) *encmap = map->encmap; if (decmap != NULL) @@ -401,6 +487,13 @@ _cjk_exec(PyObject *module) return register_maps(module); } +static void +_cjk_free(void *mod) +{ + cjkcodecs_module_state *st = get_module_state((PyObject *)mod); + PyMem_Free(st->mapping_list); + PyMem_Free(st->codec_list); +} static struct PyMethodDef _cjk_methods[] = { {"getcodec", (PyCFunction)getcodec, METH_O, ""}, @@ -409,6 +502,7 @@ static struct PyMethodDef _cjk_methods[] = { static PyModuleDef_Slot _cjk_slots[] = { {Py_mod_exec, _cjk_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; @@ -416,9 +510,10 @@ static PyModuleDef_Slot _cjk_slots[] = { static struct PyModuleDef _cjk_module = { \ PyModuleDef_HEAD_INIT, \ .m_name = "_codecs_"#loc, \ - .m_size = 0, \ + .m_size = sizeof(cjkcodecs_module_state), \ .m_methods = _cjk_methods, \ .m_slots = _cjk_slots, \ + .m_free = _cjk_free, \ }; \ \ PyMODINIT_FUNC \ diff --git a/Modules/cjkcodecs/clinic/multibytecodec.c.h b/Modules/cjkcodecs/clinic/multibytecodec.c.h index 8f850aa8..1b41c231 100644 --- a/Modules/cjkcodecs/clinic/multibytecodec.c.h +++ b/Modules/cjkcodecs/clinic/multibytecodec.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_multibytecodec_MultibyteCodec_encode__doc__, "encode($self, /, input, errors=None)\n" "--\n" @@ -25,8 +31,31 @@ static PyObject * _multibytecodec_MultibyteCodec_encode(MultibyteCodecObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(input), &_Py_ID(errors), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"input", "errors", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "encode", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "encode", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *input; @@ -88,8 +117,31 @@ static PyObject * _multibytecodec_MultibyteCodec_decode(MultibyteCodecObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(input), &_Py_ID(errors), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"input", "errors", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "decode", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "decode", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; Py_buffer input = {NULL, NULL}; @@ -156,8 +208,31 @@ static PyObject * _multibytecodec_MultibyteIncrementalEncoder_encode(MultibyteIncrementalEncoderObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(input), &_Py_ID(final), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"input", "final", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "encode", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "encode", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *input; @@ -171,8 +246,8 @@ _multibytecodec_MultibyteIncrementalEncoder_encode(MultibyteIncrementalEncoderOb if (!noptargs) { goto skip_optional_pos; } - final = _PyLong_AsInt(args[1]); - if (final == -1 && PyErr_Occurred()) { + final = PyObject_IsTrue(args[1]); + if (final < 0) { goto exit; } skip_optional_pos: @@ -262,8 +337,31 @@ static PyObject * _multibytecodec_MultibyteIncrementalDecoder_decode(MultibyteIncrementalDecoderObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(input), &_Py_ID(final), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"input", "final", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "decode", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "decode", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; Py_buffer input = {NULL, NULL}; @@ -283,8 +381,8 @@ _multibytecodec_MultibyteIncrementalDecoder_decode(MultibyteIncrementalDecoderOb if (!noptargs) { goto skip_optional_pos; } - final = _PyLong_AsInt(args[1]); - if (final == -1 && PyErr_Occurred()) { + final = PyObject_IsTrue(args[1]); + if (final < 0) { goto exit; } skip_optional_pos: @@ -492,8 +590,19 @@ static PyObject * _multibytecodec_MultibyteStreamWriter_write(MultibyteStreamWriterObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + static const char * const _keywords[] = {"", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "write", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "write", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *strobj; @@ -525,8 +634,19 @@ static PyObject * _multibytecodec_MultibyteStreamWriter_writelines(MultibyteStreamWriterObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + static const char * const _keywords[] = {"", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "writelines", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "writelines", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *lines; @@ -570,4 +690,4 @@ PyDoc_STRVAR(_multibytecodec___create_codec__doc__, #define _MULTIBYTECODEC___CREATE_CODEC_METHODDEF \ {"__create_codec", (PyCFunction)_multibytecodec___create_codec, METH_O, _multibytecodec___create_codec__doc__}, -/*[clinic end generated code: output=9e4e3da5ca3c8288 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=5f0e8dacddb0ac76 input=a9049054013a1b77]*/ diff --git a/Modules/cjkcodecs/emu_jisx0213_2000.h b/Modules/cjkcodecs/emu_jisx0213_2000.h index a5d5a706..c30c948a 100644 --- a/Modules/cjkcodecs/emu_jisx0213_2000.h +++ b/Modules/cjkcodecs/emu_jisx0213_2000.h @@ -5,8 +5,8 @@ # define EMULATE_JISX0213_2000_ENCODE_INVALID 1 #endif -#define EMULATE_JISX0213_2000_ENCODE_BMP(assi, c) \ - if (config == (void *)2000 && ( \ +#define EMULATE_JISX0213_2000_ENCODE_BMP(config, assi, c) \ + if ((config) == (void *)2000 && ( \ (c) == 0x9B1C || (c) == 0x4FF1 || \ (c) == 0x525D || (c) == 0x541E || \ (c) == 0x5653 || (c) == 0x59F8 || \ @@ -14,12 +14,12 @@ (c) == 0x7626 || (c) == 0x7E6B)) { \ return EMULATE_JISX0213_2000_ENCODE_INVALID; \ } \ - else if (config == (void *)2000 && (c) == 0x9B1D) { \ + else if ((config) == (void *)2000 && (c) == 0x9B1D) { \ (assi) = 0x8000 | 0x7d3b; \ } -#define EMULATE_JISX0213_2000_ENCODE_EMP(assi, c) \ - if (config == (void *)2000 && (c) == 0x20B9F) { \ +#define EMULATE_JISX0213_2000_ENCODE_EMP(config, assi, c) \ + if ((config) == (void *)2000 && (c) == 0x20B9F) { \ return EMULATE_JISX0213_2000_ENCODE_INVALID; \ } @@ -27,8 +27,8 @@ # define EMULATE_JISX0213_2000_DECODE_INVALID 2 #endif -#define EMULATE_JISX0213_2000_DECODE_PLANE1(assi, c1, c2) \ - if (config == (void *)2000 && \ +#define EMULATE_JISX0213_2000_DECODE_PLANE1(config, assi, c1, c2) \ + if ((config) == (void *)2000 && \ (((c1) == 0x2E && (c2) == 0x21) || \ ((c1) == 0x2F && (c2) == 0x7E) || \ ((c1) == 0x4F && (c2) == 0x54) || \ @@ -42,13 +42,13 @@ return EMULATE_JISX0213_2000_DECODE_INVALID; \ } -#define EMULATE_JISX0213_2000_DECODE_PLANE2(writer, c1, c2) \ - if (config == (void *)2000 && (c1) == 0x7D && (c2) == 0x3B) { \ +#define EMULATE_JISX0213_2000_DECODE_PLANE2(config, writer, c1, c2) \ + if ((config) == (void *)2000 && (c1) == 0x7D && (c2) == 0x3B) { \ OUTCHAR(0x9B1D); \ } -#define EMULATE_JISX0213_2000_DECODE_PLANE2_CHAR(assi, c1, c2) \ - if (config == (void *)2000 && (c1) == 0x7D && (c2) == 0x3B) { \ +#define EMULATE_JISX0213_2000_DECODE_PLANE2_CHAR(config, assi, c1, c2) \ + if ((config) == (void *)2000 && (c1) == 0x7D && (c2) == 0x3B) { \ (assi) = 0x9B1D; \ } diff --git a/Modules/cjkcodecs/mappings_hk.h b/Modules/cjkcodecs/mappings_hk.h index 1b1d70e7..9012ae35 100644 --- a/Modules/cjkcodecs/mappings_hk.h +++ b/Modules/cjkcodecs/mappings_hk.h @@ -1,3 +1,4 @@ +// AUTO-GENERATED FILE FROM genmap_tchinese.py: DO NOT EDIT static const ucs2_t __big5hkscs_decmap[6219] = { 17392,19506,17923,17830,17784,29287,19831,17843,31921,19682,31941,15253,18230, 18244,19527,19520,17087,13847,29522,28299,28882,19543,41809,18255,17882,19589, diff --git a/Modules/cjkcodecs/mappings_tw.h b/Modules/cjkcodecs/mappings_tw.h index ec3f9f74..ceb4bc56 100644 --- a/Modules/cjkcodecs/mappings_tw.h +++ b/Modules/cjkcodecs/mappings_tw.h @@ -1,3 +1,4 @@ +// AUTO-GENERATED FILE FROM genmap_tchinese.py: DO NOT EDIT static const ucs2_t __big5_decmap[16702] = { 12288,65292,12289,12290,65294,8226,65307,65306,65311,65281,65072,8230,8229, 65104,65380,65106,183,65108,65109,65110,65111,65372,8211,65073,8212,65075, @@ -2631,3 +2632,4 @@ static const struct unim_index cp950ext_encmap[256] = { 0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{__cp950ext_encmap+342,81,104},{ __cp950ext_encmap+366,15,229}, }; + diff --git a/Modules/cjkcodecs/multibytecodec.c b/Modules/cjkcodecs/multibytecodec.c index 4769ab26..b501e4fb 100644 --- a/Modules/cjkcodecs/multibytecodec.c +++ b/Modules/cjkcodecs/multibytecodec.c @@ -19,26 +19,27 @@ typedef struct { PyTypeObject *writer_type; PyTypeObject *multibytecodec_type; PyObject *str_write; -} _multibytecodec_state; +} module_state; -static _multibytecodec_state * -_multibytecodec_get_state(PyObject *module) +static module_state * +get_module_state(PyObject *module) { - _multibytecodec_state *state = PyModule_GetState(module); + module_state *state = PyModule_GetState(module); assert(state != NULL); return state; } static struct PyModuleDef _multibytecodecmodule; -static _multibytecodec_state * -_multibyte_codec_find_state_by_type(PyTypeObject *type) + +static module_state * +find_state_by_def(PyTypeObject *type) { PyObject *module = PyType_GetModuleByDef(type, &_multibytecodecmodule); assert(module != NULL); - return _multibytecodec_get_state(module); + return get_module_state(module); } -#define clinic_get_state() _multibyte_codec_find_state_by_type(type) +#define clinic_get_state() find_state_by_def(type) /*[clinic input] module _multibytecodec class _multibytecodec.MultibyteCodec "MultibyteCodecObject *" "clinic_get_state()->multibytecodec_type" @@ -66,7 +67,7 @@ typedef struct { static char *incnewkwarglist[] = {"errors", NULL}; static char *streamkwarglist[] = {"stream", "errors", NULL}; -static PyObject *multibytecodec_encode(MultibyteCodec *, +static PyObject *multibytecodec_encode(const MultibyteCodec *, MultibyteCodec_State *, PyObject *, Py_ssize_t *, PyObject *, int); @@ -141,8 +142,7 @@ codecctx_errors_get(MultibyteStatefulCodecContext *self, void *Py_UNUSED(ignored else if (self->errors == ERROR_REPLACE) errors = "replace"; else { - Py_INCREF(self->errors); - return self->errors; + return Py_NewRef(self->errors); } return PyUnicode_FromString(errors); @@ -221,7 +221,7 @@ expand_encodebuffer(MultibyteEncodeBuffer *buf, Py_ssize_t esize) */ static int -multibytecodec_encerror(MultibyteCodec *codec, +multibytecodec_encerror(const MultibyteCodec *codec, MultibyteCodec_State *state, MultibyteEncodeBuffer *buf, PyObject *errors, Py_ssize_t e) @@ -272,7 +272,7 @@ multibytecodec_encerror(MultibyteCodec *codec, for (;;) { Py_ssize_t outleft = (Py_ssize_t)(buf->outbuf_end - buf->outbuf); - r = codec->encode(state, codec->config, + r = codec->encode(state, codec, kind, data, &inpos, 1, &buf->outbuf, outleft, 0); if (r == MBERR_TOOSMALL) { @@ -341,8 +341,7 @@ multibytecodec_encerror(MultibyteCodec *codec, goto errorexit; } else { - Py_INCREF(tobj); - retstr = tobj; + retstr = Py_NewRef(tobj); } assert(PyBytes_Check(retstr)); @@ -376,7 +375,7 @@ errorexit: } static int -multibytecodec_decerror(MultibyteCodec *codec, +multibytecodec_decerror(const MultibyteCodec *codec, MultibyteCodec_State *state, MultibyteDecodeBuffer *buf, PyObject *errors, Py_ssize_t e) @@ -480,7 +479,7 @@ errorexit: } static PyObject * -multibytecodec_encode(MultibyteCodec *codec, +multibytecodec_encode(const MultibyteCodec *codec, MultibyteCodec_State *state, PyObject *text, Py_ssize_t *inpos_t, PyObject *errors, int flags) @@ -522,7 +521,7 @@ multibytecodec_encode(MultibyteCodec *codec, * error callbacks can relocate the cursor anywhere on buffer*/ Py_ssize_t outleft = (Py_ssize_t)(buf.outbuf_end - buf.outbuf); - r = codec->encode(state, codec->config, + r = codec->encode(state, codec, kind, data, &buf.inpos, buf.inlen, &buf.outbuf, outleft, flags); @@ -539,7 +538,7 @@ multibytecodec_encode(MultibyteCodec *codec, Py_ssize_t outleft; outleft = (Py_ssize_t)(buf.outbuf_end - buf.outbuf); - r = codec->encreset(state, codec->config, &buf.outbuf, + r = codec->encreset(state, codec, &buf.outbuf, outleft); if (r == 0) break; @@ -617,7 +616,7 @@ _multibytecodec_MultibyteCodec_encode_impl(MultibyteCodecObject *self, } if (self->codec->encinit != NULL && - self->codec->encinit(&state, self->codec->config) != 0) + self->codec->encinit(&state, self->codec) != 0) goto errorexit; r = multibytecodec_encode(self->codec, &state, input, NULL, errorcb, @@ -681,7 +680,7 @@ _multibytecodec_MultibyteCodec_decode_impl(MultibyteCodecObject *self, buf.inbuf_end = buf.inbuf_top + datalen; if (self->codec->decinit != NULL && - self->codec->decinit(&state, self->codec->config) != 0) + self->codec->decinit(&state, self->codec) != 0) goto errorexit; while (buf.inbuf < buf.inbuf_end) { @@ -689,7 +688,7 @@ _multibytecodec_MultibyteCodec_decode_impl(MultibyteCodecObject *self, inleft = (Py_ssize_t)(buf.inbuf_end - buf.inbuf); - r = self->codec->decode(&state, self->codec->config, + r = self->codec->decode(&state, self->codec, &buf.inbuf, inleft, &buf.writer); if (r == 0) break; @@ -721,9 +720,17 @@ static struct PyMethodDef multibytecodec_methods[] = { }; static int -multibytecodec_traverse(PyObject *self, visitproc visit, void *arg) +multibytecodec_clear(MultibyteCodecObject *self) +{ + Py_CLEAR(self->cjk_module); + return 0; +} + +static int +multibytecodec_traverse(MultibyteCodecObject *self, visitproc visit, void *arg) { Py_VISIT(Py_TYPE(self)); + Py_VISIT(self->cjk_module); return 0; } @@ -732,6 +739,7 @@ multibytecodec_dealloc(MultibyteCodecObject *self) { PyObject_GC_UnTrack(self); PyTypeObject *tp = Py_TYPE(self); + (void)multibytecodec_clear(self); tp->tp_free(self); Py_DECREF(tp); } @@ -741,6 +749,7 @@ static PyType_Slot multibytecodec_slots[] = { {Py_tp_getattro, PyObject_GenericGetAttr}, {Py_tp_methods, multibytecodec_methods}, {Py_tp_traverse, multibytecodec_traverse}, + {Py_tp_clear, multibytecodec_clear}, {0, NULL}, }; @@ -786,11 +795,9 @@ encoder_encode_stateful(MultibyteStatefulEncoderContext *ctx, if (ctx->pending) { PyObject *inbuf_tmp; - Py_INCREF(ctx->pending); - origpending = ctx->pending; + origpending = Py_NewRef(ctx->pending); - Py_INCREF(ctx->pending); - inbuf_tmp = ctx->pending; + inbuf_tmp = Py_NewRef(ctx->pending); PyUnicode_Append(&inbuf_tmp, unistr); if (inbuf_tmp == NULL) goto errorexit; @@ -800,8 +807,7 @@ encoder_encode_stateful(MultibyteStatefulEncoderContext *ctx, else { origpending = NULL; - Py_INCREF(unistr); - inbuf = unistr; + inbuf = Py_NewRef(unistr); } if (PyUnicode_READY(inbuf) < 0) goto errorexit; @@ -882,7 +888,7 @@ decoder_feed_buffer(MultibyteStatefulDecoderContext *ctx, inleft = (Py_ssize_t)(buf->inbuf_end - buf->inbuf); - r = ctx->codec->decode(&ctx->state, ctx->codec->config, + r = ctx->codec->decode(&ctx->state, ctx->codec, &buf->inbuf, inleft, &buf->writer); if (r == 0 || r == MBERR_TOOFEW) break; @@ -898,14 +904,14 @@ decoder_feed_buffer(MultibyteStatefulDecoderContext *ctx, _multibytecodec.MultibyteIncrementalEncoder.encode input: object - final: bool(accept={int}) = False + final: bool = False [clinic start generated code]*/ static PyObject * _multibytecodec_MultibyteIncrementalEncoder_encode_impl(MultibyteIncrementalEncoderObject *self, PyObject *input, int final) -/*[clinic end generated code: output=123361b6c505e2c1 input=093a1ddbb2fc6721]*/ +/*[clinic end generated code: output=123361b6c505e2c1 input=bd5f7d40d43e99b0]*/ { return encoder_encode_stateful(STATEFUL_ECTX(self), input, final); } @@ -985,8 +991,7 @@ _multibytecodec_MultibyteIncrementalEncoder_setstate_impl(MultibyteIncrementalEn goto errorexit; } - Py_CLEAR(self->pending); - self->pending = pending; + Py_XSETREF(self->pending, pending); memcpy(self->state.c, statebytes+1+statebytes[0], sizeof(self->state.c)); @@ -1010,7 +1015,7 @@ _multibytecodec_MultibyteIncrementalEncoder_reset_impl(MultibyteIncrementalEncod Py_ssize_t r; if (self->codec->encreset != NULL) { outbuf = buffer; - r = self->codec->encreset(&self->state, self->codec->config, + r = self->codec->encreset(&self->state, self->codec, &outbuf, sizeof(buffer)); if (r != 0) return NULL; @@ -1046,7 +1051,7 @@ mbiencoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds) if (codec == NULL) goto errorexit; - _multibytecodec_state *state = _multibyte_codec_find_state_by_type(type); + module_state *state = find_state_by_def(type); if (!MultibyteCodec_Check(state, codec)) { PyErr_SetString(PyExc_TypeError, "codec is unexpected type"); goto errorexit; @@ -1058,7 +1063,7 @@ mbiencoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds) if (self->errors == NULL) goto errorexit; if (self->codec->encinit != NULL && - self->codec->encinit(&self->state, self->codec->config) != 0) + self->codec->encinit(&self->state, self->codec) != 0) goto errorexit; Py_DECREF(codec); @@ -1120,14 +1125,14 @@ static PyType_Spec encoder_spec = { _multibytecodec.MultibyteIncrementalDecoder.decode input: Py_buffer - final: bool(accept={int}) = False + final: bool = False [clinic start generated code]*/ static PyObject * _multibytecodec_MultibyteIncrementalDecoder_decode_impl(MultibyteIncrementalDecoderObject *self, Py_buffer *input, int final) -/*[clinic end generated code: output=b9b9090e8a9ce2ba input=c9132b24d503eb1d]*/ +/*[clinic end generated code: output=b9b9090e8a9ce2ba input=8795fbb20860027a]*/ { MultibyteDecodeBuffer buf; char *data, *wdata = NULL; @@ -1287,7 +1292,7 @@ _multibytecodec_MultibyteIncrementalDecoder_reset_impl(MultibyteIncrementalDecod /*[clinic end generated code: output=da423b1782c23ed1 input=3b63b3be85b2fb45]*/ { if (self->codec->decreset != NULL && - self->codec->decreset(&self->state, self->codec->config) != 0) + self->codec->decreset(&self->state, self->codec) != 0) return NULL; self->pendingsize = 0; @@ -1321,7 +1326,7 @@ mbidecoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds) if (codec == NULL) goto errorexit; - _multibytecodec_state *state = _multibyte_codec_find_state_by_type(type); + module_state *state = find_state_by_def(type); if (!MultibyteCodec_Check(state, codec)) { PyErr_SetString(PyExc_TypeError, "codec is unexpected type"); goto errorexit; @@ -1333,7 +1338,7 @@ mbidecoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds) if (self->errors == NULL) goto errorexit; if (self->codec->decinit != NULL && - self->codec->decinit(&self->state, self->codec->config) != 0) + self->codec->decinit(&self->state, self->codec) != 0) goto errorexit; Py_DECREF(codec); @@ -1443,8 +1448,7 @@ mbstreamreader_iread(MultibyteStreamReaderObject *self, memcpy(ctrdata + self->pendingsize, PyBytes_AS_STRING(cres), PyBytes_GET_SIZE(cres)); - Py_DECREF(cres); - cres = ctr; + Py_SETREF(cres, ctr); self->pendingsize = 0; } @@ -1470,8 +1474,7 @@ mbstreamreader_iread(MultibyteStreamReaderObject *self, goto errorexit; } - Py_DECREF(cres); - cres = NULL; + Py_SETREF(cres, NULL); if (sizehint < 0 || buf.writer.pos != 0 || rsize == 0) break; @@ -1597,7 +1600,7 @@ _multibytecodec_MultibyteStreamReader_reset_impl(MultibyteStreamReaderObject *se /*[clinic end generated code: output=138490370a680abc input=5d4140db84b5e1e2]*/ { if (self->codec->decreset != NULL && - self->codec->decreset(&self->state, self->codec->config) != 0) + self->codec->decreset(&self->state, self->codec) != 0) return NULL; self->pendingsize = 0; @@ -1638,21 +1641,20 @@ mbstreamreader_new(PyTypeObject *type, PyObject *args, PyObject *kwds) if (codec == NULL) goto errorexit; - _multibytecodec_state *state = _multibyte_codec_find_state_by_type(type); + module_state *state = find_state_by_def(type); if (!MultibyteCodec_Check(state, codec)) { PyErr_SetString(PyExc_TypeError, "codec is unexpected type"); goto errorexit; } self->codec = ((MultibyteCodecObject *)codec)->codec; - self->stream = stream; - Py_INCREF(stream); + self->stream = Py_NewRef(stream); self->pendingsize = 0; self->errors = internal_error_callback(errors); if (self->errors == NULL) goto errorexit; if (self->codec->decinit != NULL && - self->codec->decinit(&self->state, self->codec->config) != 0) + self->codec->decinit(&self->state, self->codec) != 0) goto errorexit; Py_DECREF(codec); @@ -1744,7 +1746,7 @@ _multibytecodec_MultibyteStreamWriter_write_impl(MultibyteStreamWriterObject *se PyObject *strobj) /*[clinic end generated code: output=68ade3aea26410ac input=199f26f68bd8425a]*/ { - _multibytecodec_state *state = PyType_GetModuleState(cls); + module_state *state = PyType_GetModuleState(cls); assert(state != NULL); if (mbstreamwriter_iwrite(self, strobj, state->str_write)) { return NULL; @@ -1775,7 +1777,7 @@ _multibytecodec_MultibyteStreamWriter_writelines_impl(MultibyteStreamWriterObjec return NULL; } - _multibytecodec_state *state = PyType_GetModuleState(cls); + module_state *state = PyType_GetModuleState(cls); assert(state != NULL); for (i = 0; i < PySequence_Length(lines); i++) { /* length can be changed even within this loop */ @@ -1826,7 +1828,7 @@ _multibytecodec_MultibyteStreamWriter_reset_impl(MultibyteStreamWriterObject *se assert(PyBytes_Check(pwrt)); - _multibytecodec_state *state = PyType_GetModuleState(cls); + module_state *state = PyType_GetModuleState(cls); assert(state != NULL); if (PyBytes_Size(pwrt) > 0) { @@ -1862,21 +1864,20 @@ mbstreamwriter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) if (codec == NULL) goto errorexit; - _multibytecodec_state *state = _multibyte_codec_find_state_by_type(type); + module_state *state = find_state_by_def(type); if (!MultibyteCodec_Check(state, codec)) { PyErr_SetString(PyExc_TypeError, "codec is unexpected type"); goto errorexit; } self->codec = ((MultibyteCodecObject *)codec)->codec; - self->stream = stream; - Py_INCREF(stream); + self->stream = Py_NewRef(stream); self->pending = NULL; self->errors = internal_error_callback(errors); if (self->errors == NULL) goto errorexit; if (self->codec->encinit != NULL && - self->codec->encinit(&self->state, self->codec->config) != 0) + self->codec->encinit(&self->state, self->codec) != 0) goto errorexit; Py_DECREF(codec); @@ -1962,22 +1963,23 @@ _multibytecodec___create_codec(PyObject *module, PyObject *arg) /*[clinic end generated code: output=cfa3dce8260e809d input=6840b2a6b183fcfa]*/ { MultibyteCodecObject *self; - MultibyteCodec *codec; - if (!PyCapsule_IsValid(arg, PyMultibyteCodec_CAPSULE_NAME)) { + if (!PyCapsule_IsValid(arg, CODEC_CAPSULE)) { PyErr_SetString(PyExc_ValueError, "argument type invalid"); return NULL; } - codec = PyCapsule_GetPointer(arg, PyMultibyteCodec_CAPSULE_NAME); - if (codec->codecinit != NULL && codec->codecinit(codec->config) != 0) + codec_capsule *data = PyCapsule_GetPointer(arg, CODEC_CAPSULE); + const MultibyteCodec *codec = data->codec; + if (codec->codecinit != NULL && codec->codecinit(codec) != 0) return NULL; - _multibytecodec_state *state = _multibytecodec_get_state(module); + module_state *state = get_module_state(module); self = PyObject_GC_New(MultibyteCodecObject, state->multibytecodec_type); if (self == NULL) return NULL; self->codec = codec; + self->cjk_module = Py_NewRef(data->cjk_module); PyObject_GC_Track(self); return (PyObject *)self; @@ -1986,7 +1988,7 @@ _multibytecodec___create_codec(PyObject *module, PyObject *arg) static int _multibytecodec_traverse(PyObject *mod, visitproc visit, void *arg) { - _multibytecodec_state *state = _multibytecodec_get_state(mod); + module_state *state = get_module_state(mod); Py_VISIT(state->multibytecodec_type); Py_VISIT(state->encoder_type); Py_VISIT(state->decoder_type); @@ -1998,7 +2000,7 @@ _multibytecodec_traverse(PyObject *mod, visitproc visit, void *arg) static int _multibytecodec_clear(PyObject *mod) { - _multibytecodec_state *state = _multibytecodec_get_state(mod); + module_state *state = get_module_state(mod); Py_CLEAR(state->multibytecodec_type); Py_CLEAR(state->encoder_type); Py_CLEAR(state->decoder_type); @@ -2032,7 +2034,7 @@ _multibytecodec_free(void *mod) static int _multibytecodec_exec(PyObject *mod) { - _multibytecodec_state *state = _multibytecodec_get_state(mod); + module_state *state = get_module_state(mod); state->str_write = PyUnicode_InternFromString("write"); if (state->str_write == NULL) { return -1; @@ -2060,13 +2062,14 @@ static struct PyMethodDef _multibytecodec_methods[] = { static PyModuleDef_Slot _multibytecodec_slots[] = { {Py_mod_exec, _multibytecodec_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; static struct PyModuleDef _multibytecodecmodule = { .m_base = PyModuleDef_HEAD_INIT, .m_name = "_multibytecodec", - .m_size = sizeof(_multibytecodec_state), + .m_size = sizeof(module_state), .m_methods = _multibytecodec_methods, .m_slots = _multibytecodec_slots, .m_traverse = _multibytecodec_traverse, diff --git a/Modules/cjkcodecs/multibytecodec.h b/Modules/cjkcodecs/multibytecodec.h index 69404ba9..f5936220 100644 --- a/Modules/cjkcodecs/multibytecodec.h +++ b/Modules/cjkcodecs/multibytecodec.h @@ -27,28 +27,31 @@ typedef struct { unsigned char c[8]; } MultibyteCodec_State; -typedef int (*mbcodec_init)(const void *config); +struct _cjk_mod_state; +struct _multibyte_codec; + +typedef int (*mbcodec_init)(const struct _multibyte_codec *codec); typedef Py_ssize_t (*mbencode_func)(MultibyteCodec_State *state, - const void *config, + const struct _multibyte_codec *codec, int kind, const void *data, Py_ssize_t *inpos, Py_ssize_t inlen, unsigned char **outbuf, Py_ssize_t outleft, int flags); typedef int (*mbencodeinit_func)(MultibyteCodec_State *state, - const void *config); + const struct _multibyte_codec *codec); typedef Py_ssize_t (*mbencodereset_func)(MultibyteCodec_State *state, - const void *config, + const struct _multibyte_codec *codec, unsigned char **outbuf, Py_ssize_t outleft); typedef Py_ssize_t (*mbdecode_func)(MultibyteCodec_State *state, - const void *config, + const struct _multibyte_codec *codec, const unsigned char **inbuf, Py_ssize_t inleft, _PyUnicodeWriter *writer); typedef int (*mbdecodeinit_func)(MultibyteCodec_State *state, - const void *config); + const struct _multibyte_codec *codec); typedef Py_ssize_t (*mbdecodereset_func)(MultibyteCodec_State *state, - const void *config); + const struct _multibyte_codec *codec); -typedef struct { +typedef struct _multibyte_codec { const char *encoding; const void *config; mbcodec_init codecinit; @@ -58,18 +61,20 @@ typedef struct { mbdecode_func decode; mbdecodeinit_func decinit; mbdecodereset_func decreset; + struct _cjk_mod_state *modstate; } MultibyteCodec; typedef struct { PyObject_HEAD - MultibyteCodec *codec; + const MultibyteCodec *codec; + PyObject *cjk_module; } MultibyteCodecObject; #define MultibyteCodec_Check(state, op) Py_IS_TYPE((op), state->multibytecodec_type) #define _MultibyteStatefulCodec_HEAD \ PyObject_HEAD \ - MultibyteCodec *codec; \ + const MultibyteCodec *codec; \ MultibyteCodec_State state; \ PyObject *errors; typedef struct { @@ -130,7 +135,13 @@ typedef struct { #define MBENC_FLUSH 0x0001 /* encode all characters encodable */ #define MBENC_MAX MBENC_FLUSH -#define PyMultibyteCodec_CAPSULE_NAME "multibytecodec.__map_*" +typedef struct { + const MultibyteCodec *codec; + PyObject *cjk_module; +} codec_capsule; + +#define MAP_CAPSULE "multibytecodec.map" +#define CODEC_CAPSULE "multibytecodec.codec" #ifdef __cplusplus diff --git a/Modules/clinic/_abc.c.h b/Modules/clinic/_abc.c.h index 8d3832e1..2adec818 100644 --- a/Modules/clinic/_abc.c.h +++ b/Modules/clinic/_abc.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_abc__reset_registry__doc__, "_reset_registry($module, self, /)\n" "--\n" @@ -159,4 +165,4 @@ _abc_get_cache_token(PyObject *module, PyObject *Py_UNUSED(ignored)) { return _abc_get_cache_token_impl(module); } -/*[clinic end generated code: output=babb3ce445fa9b21 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=c2e69611a495c98d input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_asynciomodule.c.h b/Modules/clinic/_asynciomodule.c.h index add6bb2e..6a780a80 100644 --- a/Modules/clinic/_asynciomodule.c.h +++ b/Modules/clinic/_asynciomodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_asyncio_Future___init____doc__, "Future(*, loop=None)\n" "--\n" @@ -26,8 +32,31 @@ static int _asyncio_Future___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(loop), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"loop", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "Future", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "Future", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -83,15 +112,19 @@ PyDoc_STRVAR(_asyncio_Future_exception__doc__, "InvalidStateError."); #define _ASYNCIO_FUTURE_EXCEPTION_METHODDEF \ - {"exception", (PyCFunction)_asyncio_Future_exception, METH_NOARGS, _asyncio_Future_exception__doc__}, + {"exception", _PyCFunction_CAST(_asyncio_Future_exception), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _asyncio_Future_exception__doc__}, static PyObject * -_asyncio_Future_exception_impl(FutureObj *self); +_asyncio_Future_exception_impl(FutureObj *self, PyTypeObject *cls); static PyObject * -_asyncio_Future_exception(FutureObj *self, PyObject *Py_UNUSED(ignored)) +_asyncio_Future_exception(FutureObj *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - return _asyncio_Future_exception_impl(self); + if (nargs) { + PyErr_SetString(PyExc_TypeError, "exception() takes no arguments"); + return NULL; + } + return _asyncio_Future_exception_impl(self, cls); } PyDoc_STRVAR(_asyncio_Future_set_result__doc__, @@ -104,7 +137,42 @@ PyDoc_STRVAR(_asyncio_Future_set_result__doc__, "InvalidStateError."); #define _ASYNCIO_FUTURE_SET_RESULT_METHODDEF \ - {"set_result", (PyCFunction)_asyncio_Future_set_result, METH_O, _asyncio_Future_set_result__doc__}, + {"set_result", _PyCFunction_CAST(_asyncio_Future_set_result), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _asyncio_Future_set_result__doc__}, + +static PyObject * +_asyncio_Future_set_result_impl(FutureObj *self, PyTypeObject *cls, + PyObject *result); + +static PyObject * +_asyncio_Future_set_result(FutureObj *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + + static const char * const _keywords[] = {"", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "set_result", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject *result; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + result = args[0]; + return_value = _asyncio_Future_set_result_impl(self, cls, result); + +exit: + return return_value; +} PyDoc_STRVAR(_asyncio_Future_set_exception__doc__, "set_exception($self, exception, /)\n" @@ -116,7 +184,42 @@ PyDoc_STRVAR(_asyncio_Future_set_exception__doc__, "InvalidStateError."); #define _ASYNCIO_FUTURE_SET_EXCEPTION_METHODDEF \ - {"set_exception", (PyCFunction)_asyncio_Future_set_exception, METH_O, _asyncio_Future_set_exception__doc__}, + {"set_exception", _PyCFunction_CAST(_asyncio_Future_set_exception), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _asyncio_Future_set_exception__doc__}, + +static PyObject * +_asyncio_Future_set_exception_impl(FutureObj *self, PyTypeObject *cls, + PyObject *exception); + +static PyObject * +_asyncio_Future_set_exception(FutureObj *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + + static const char * const _keywords[] = {"", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "set_exception", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject *exception; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + exception = args[0]; + return_value = _asyncio_Future_set_exception_impl(self, cls, exception); + +exit: + return return_value; +} PyDoc_STRVAR(_asyncio_Future_add_done_callback__doc__, "add_done_callback($self, fn, /, *, context=<unrepresentable>)\n" @@ -129,18 +232,41 @@ PyDoc_STRVAR(_asyncio_Future_add_done_callback__doc__, "scheduled with call_soon."); #define _ASYNCIO_FUTURE_ADD_DONE_CALLBACK_METHODDEF \ - {"add_done_callback", _PyCFunction_CAST(_asyncio_Future_add_done_callback), METH_FASTCALL|METH_KEYWORDS, _asyncio_Future_add_done_callback__doc__}, + {"add_done_callback", _PyCFunction_CAST(_asyncio_Future_add_done_callback), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _asyncio_Future_add_done_callback__doc__}, static PyObject * -_asyncio_Future_add_done_callback_impl(FutureObj *self, PyObject *fn, - PyObject *context); +_asyncio_Future_add_done_callback_impl(FutureObj *self, PyTypeObject *cls, + PyObject *fn, PyObject *context); static PyObject * -_asyncio_Future_add_done_callback(FutureObj *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +_asyncio_Future_add_done_callback(FutureObj *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(context), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "context", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "add_done_callback", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "add_done_callback", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *fn; @@ -156,7 +282,7 @@ _asyncio_Future_add_done_callback(FutureObj *self, PyObject *const *args, Py_ssi } context = args[1]; skip_optional_kwonly: - return_value = _asyncio_Future_add_done_callback_impl(self, fn, context); + return_value = _asyncio_Future_add_done_callback_impl(self, cls, fn, context); exit: return return_value; @@ -171,7 +297,42 @@ PyDoc_STRVAR(_asyncio_Future_remove_done_callback__doc__, "Returns the number of callbacks removed."); #define _ASYNCIO_FUTURE_REMOVE_DONE_CALLBACK_METHODDEF \ - {"remove_done_callback", (PyCFunction)_asyncio_Future_remove_done_callback, METH_O, _asyncio_Future_remove_done_callback__doc__}, + {"remove_done_callback", _PyCFunction_CAST(_asyncio_Future_remove_done_callback), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _asyncio_Future_remove_done_callback__doc__}, + +static PyObject * +_asyncio_Future_remove_done_callback_impl(FutureObj *self, PyTypeObject *cls, + PyObject *fn); + +static PyObject * +_asyncio_Future_remove_done_callback(FutureObj *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + + static const char * const _keywords[] = {"", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "remove_done_callback", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject *fn; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + fn = args[0]; + return_value = _asyncio_Future_remove_done_callback_impl(self, cls, fn); + +exit: + return return_value; +} PyDoc_STRVAR(_asyncio_Future_cancel__doc__, "cancel($self, /, msg=None)\n" @@ -184,17 +345,41 @@ PyDoc_STRVAR(_asyncio_Future_cancel__doc__, "return True."); #define _ASYNCIO_FUTURE_CANCEL_METHODDEF \ - {"cancel", _PyCFunction_CAST(_asyncio_Future_cancel), METH_FASTCALL|METH_KEYWORDS, _asyncio_Future_cancel__doc__}, + {"cancel", _PyCFunction_CAST(_asyncio_Future_cancel), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _asyncio_Future_cancel__doc__}, static PyObject * -_asyncio_Future_cancel_impl(FutureObj *self, PyObject *msg); +_asyncio_Future_cancel_impl(FutureObj *self, PyTypeObject *cls, + PyObject *msg); static PyObject * -_asyncio_Future_cancel(FutureObj *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +_asyncio_Future_cancel(FutureObj *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(msg), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"msg", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "cancel", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "cancel", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *msg = Py_None; @@ -208,7 +393,7 @@ _asyncio_Future_cancel(FutureObj *self, PyObject *const *args, Py_ssize_t nargs, } msg = args[0]; skip_optional_pos: - return_value = _asyncio_Future_cancel_impl(self, msg); + return_value = _asyncio_Future_cancel_impl(self, cls, msg); exit: return return_value; @@ -260,15 +445,19 @@ PyDoc_STRVAR(_asyncio_Future_get_loop__doc__, "Return the event loop the Future is bound to."); #define _ASYNCIO_FUTURE_GET_LOOP_METHODDEF \ - {"get_loop", (PyCFunction)_asyncio_Future_get_loop, METH_NOARGS, _asyncio_Future_get_loop__doc__}, + {"get_loop", _PyCFunction_CAST(_asyncio_Future_get_loop), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _asyncio_Future_get_loop__doc__}, static PyObject * -_asyncio_Future_get_loop_impl(FutureObj *self); +_asyncio_Future_get_loop_impl(FutureObj *self, PyTypeObject *cls); static PyObject * -_asyncio_Future_get_loop(FutureObj *self, PyObject *Py_UNUSED(ignored)) +_asyncio_Future_get_loop(FutureObj *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - return _asyncio_Future_get_loop_impl(self); + if (nargs) { + PyErr_SetString(PyExc_TypeError, "get_loop() takes no arguments"); + return NULL; + } + return _asyncio_Future_get_loop_impl(self, cls); } PyDoc_STRVAR(_asyncio_Future__make_cancelled_error__doc__, @@ -293,22 +482,46 @@ _asyncio_Future__make_cancelled_error(FutureObj *self, PyObject *Py_UNUSED(ignor } PyDoc_STRVAR(_asyncio_Task___init____doc__, -"Task(coro, *, loop=None, name=None, context=None)\n" +"Task(coro, *, loop=None, name=None, context=None, eager_start=False)\n" "--\n" "\n" "A coroutine wrapped in a Future."); static int _asyncio_Task___init___impl(TaskObj *self, PyObject *coro, PyObject *loop, - PyObject *name, PyObject *context); + PyObject *name, PyObject *context, + int eager_start); static int _asyncio_Task___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; - static const char * const _keywords[] = {"coro", "loop", "name", "context", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "Task", 0}; - PyObject *argsbuf[4]; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 5 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(coro), &_Py_ID(loop), &_Py_ID(name), &_Py_ID(context), &_Py_ID(eager_start), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"coro", "loop", "name", "context", "eager_start", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "Task", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[5]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); Py_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 1; @@ -316,6 +529,7 @@ _asyncio_Task___init__(PyObject *self, PyObject *args, PyObject *kwargs) PyObject *loop = Py_None; PyObject *name = Py_None; PyObject *context = Py_None; + int eager_start = 0; fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 1, 0, argsbuf); if (!fastargs) { @@ -337,9 +551,18 @@ _asyncio_Task___init__(PyObject *self, PyObject *args, PyObject *kwargs) goto skip_optional_kwonly; } } - context = fastargs[3]; + if (fastargs[3]) { + context = fastargs[3]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + eager_start = PyObject_IsTrue(fastargs[4]); + if (eager_start < 0) { + goto exit; + } skip_optional_kwonly: - return_value = _asyncio_Task___init___impl((TaskObj *)self, coro, loop, name, context); + return_value = _asyncio_Task___init___impl((TaskObj *)self, coro, loop, name, context, eager_start); exit: return return_value; @@ -401,8 +624,31 @@ static PyObject * _asyncio_Task_cancel(TaskObj *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(msg), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"msg", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "cancel", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "cancel", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *msg = Py_None; @@ -491,17 +737,41 @@ PyDoc_STRVAR(_asyncio_Task_get_stack__doc__, "returned for a suspended coroutine."); #define _ASYNCIO_TASK_GET_STACK_METHODDEF \ - {"get_stack", _PyCFunction_CAST(_asyncio_Task_get_stack), METH_FASTCALL|METH_KEYWORDS, _asyncio_Task_get_stack__doc__}, + {"get_stack", _PyCFunction_CAST(_asyncio_Task_get_stack), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _asyncio_Task_get_stack__doc__}, static PyObject * -_asyncio_Task_get_stack_impl(TaskObj *self, PyObject *limit); +_asyncio_Task_get_stack_impl(TaskObj *self, PyTypeObject *cls, + PyObject *limit); static PyObject * -_asyncio_Task_get_stack(TaskObj *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +_asyncio_Task_get_stack(TaskObj *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(limit), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"limit", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "get_stack", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "get_stack", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *limit = Py_None; @@ -515,7 +785,7 @@ _asyncio_Task_get_stack(TaskObj *self, PyObject *const *args, Py_ssize_t nargs, } limit = args[0]; skip_optional_kwonly: - return_value = _asyncio_Task_get_stack_impl(self, limit); + return_value = _asyncio_Task_get_stack_impl(self, cls, limit); exit: return return_value; @@ -534,18 +804,41 @@ PyDoc_STRVAR(_asyncio_Task_print_stack__doc__, "to sys.stderr."); #define _ASYNCIO_TASK_PRINT_STACK_METHODDEF \ - {"print_stack", _PyCFunction_CAST(_asyncio_Task_print_stack), METH_FASTCALL|METH_KEYWORDS, _asyncio_Task_print_stack__doc__}, + {"print_stack", _PyCFunction_CAST(_asyncio_Task_print_stack), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _asyncio_Task_print_stack__doc__}, static PyObject * -_asyncio_Task_print_stack_impl(TaskObj *self, PyObject *limit, - PyObject *file); +_asyncio_Task_print_stack_impl(TaskObj *self, PyTypeObject *cls, + PyObject *limit, PyObject *file); static PyObject * -_asyncio_Task_print_stack(TaskObj *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +_asyncio_Task_print_stack(TaskObj *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(limit), &_Py_ID(file), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"limit", "file", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "print_stack", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "print_stack", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *limit = Py_None; @@ -566,7 +859,7 @@ _asyncio_Task_print_stack(TaskObj *self, PyObject *const *args, Py_ssize_t nargs } file = args[1]; skip_optional_kwonly: - return_value = _asyncio_Task_print_stack_impl(self, limit, file); + return_value = _asyncio_Task_print_stack_impl(self, cls, limit, file); exit: return return_value; @@ -605,6 +898,23 @@ _asyncio_Task_get_coro(TaskObj *self, PyObject *Py_UNUSED(ignored)) return _asyncio_Task_get_coro_impl(self); } +PyDoc_STRVAR(_asyncio_Task_get_context__doc__, +"get_context($self, /)\n" +"--\n" +"\n"); + +#define _ASYNCIO_TASK_GET_CONTEXT_METHODDEF \ + {"get_context", (PyCFunction)_asyncio_Task_get_context, METH_NOARGS, _asyncio_Task_get_context__doc__}, + +static PyObject * +_asyncio_Task_get_context_impl(TaskObj *self); + +static PyObject * +_asyncio_Task_get_context(TaskObj *self, PyObject *Py_UNUSED(ignored)) +{ + return _asyncio_Task_get_context_impl(self); +} + PyDoc_STRVAR(_asyncio_Task_get_name__doc__, "get_name($self, /)\n" "--\n" @@ -688,45 +998,6 @@ _asyncio_get_event_loop(PyObject *module, PyObject *Py_UNUSED(ignored)) return _asyncio_get_event_loop_impl(module); } -PyDoc_STRVAR(_asyncio__get_event_loop__doc__, -"_get_event_loop($module, /, stacklevel=3)\n" -"--\n" -"\n"); - -#define _ASYNCIO__GET_EVENT_LOOP_METHODDEF \ - {"_get_event_loop", _PyCFunction_CAST(_asyncio__get_event_loop), METH_FASTCALL|METH_KEYWORDS, _asyncio__get_event_loop__doc__}, - -static PyObject * -_asyncio__get_event_loop_impl(PyObject *module, int stacklevel); - -static PyObject * -_asyncio__get_event_loop(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"stacklevel", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "_get_event_loop", 0}; - PyObject *argsbuf[1]; - Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; - int stacklevel = 3; - - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); - if (!args) { - goto exit; - } - if (!noptargs) { - goto skip_optional_pos; - } - stacklevel = _PyLong_AsInt(args[0]); - if (stacklevel == -1 && PyErr_Occurred()) { - goto exit; - } -skip_optional_pos: - return_value = _asyncio__get_event_loop_impl(module, stacklevel); - -exit: - return return_value; -} - PyDoc_STRVAR(_asyncio_get_running_loop__doc__, "get_running_loop($module, /)\n" "--\n" @@ -765,8 +1036,31 @@ static PyObject * _asyncio__register_task(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(task), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"task", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "_register_task", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "_register_task", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *task; @@ -781,6 +1075,63 @@ exit: return return_value; } +PyDoc_STRVAR(_asyncio__register_eager_task__doc__, +"_register_eager_task($module, /, task)\n" +"--\n" +"\n" +"Register a new task in asyncio as executed by loop.\n" +"\n" +"Returns None."); + +#define _ASYNCIO__REGISTER_EAGER_TASK_METHODDEF \ + {"_register_eager_task", _PyCFunction_CAST(_asyncio__register_eager_task), METH_FASTCALL|METH_KEYWORDS, _asyncio__register_eager_task__doc__}, + +static PyObject * +_asyncio__register_eager_task_impl(PyObject *module, PyObject *task); + +static PyObject * +_asyncio__register_eager_task(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(task), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"task", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "_register_eager_task", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject *task; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + task = args[0]; + return_value = _asyncio__register_eager_task_impl(module, task); + +exit: + return return_value; +} + PyDoc_STRVAR(_asyncio__unregister_task__doc__, "_unregister_task($module, /, task)\n" "--\n" @@ -799,8 +1150,31 @@ static PyObject * _asyncio__unregister_task(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(task), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"task", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "_unregister_task", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "_unregister_task", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *task; @@ -815,6 +1189,63 @@ exit: return return_value; } +PyDoc_STRVAR(_asyncio__unregister_eager_task__doc__, +"_unregister_eager_task($module, /, task)\n" +"--\n" +"\n" +"Unregister a task.\n" +"\n" +"Returns None."); + +#define _ASYNCIO__UNREGISTER_EAGER_TASK_METHODDEF \ + {"_unregister_eager_task", _PyCFunction_CAST(_asyncio__unregister_eager_task), METH_FASTCALL|METH_KEYWORDS, _asyncio__unregister_eager_task__doc__}, + +static PyObject * +_asyncio__unregister_eager_task_impl(PyObject *module, PyObject *task); + +static PyObject * +_asyncio__unregister_eager_task(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(task), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"task", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "_unregister_eager_task", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject *task; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + task = args[0]; + return_value = _asyncio__unregister_eager_task_impl(module, task); + +exit: + return return_value; +} + PyDoc_STRVAR(_asyncio__enter_task__doc__, "_enter_task($module, /, loop, task)\n" "--\n" @@ -835,8 +1266,31 @@ static PyObject * _asyncio__enter_task(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(loop), &_Py_ID(task), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"loop", "task", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "_enter_task", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "_enter_task", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject *loop; PyObject *task; @@ -873,8 +1327,31 @@ static PyObject * _asyncio__leave_task(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(loop), &_Py_ID(task), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"loop", "task", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "_leave_task", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "_leave_task", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject *loop; PyObject *task; @@ -890,4 +1367,124 @@ _asyncio__leave_task(PyObject *module, PyObject *const *args, Py_ssize_t nargs, exit: return return_value; } -/*[clinic end generated code: output=b4e678c915567934 input=a9049054013a1b77]*/ + +PyDoc_STRVAR(_asyncio__swap_current_task__doc__, +"_swap_current_task($module, /, loop, task)\n" +"--\n" +"\n" +"Temporarily swap in the supplied task and return the original one (or None).\n" +"\n" +"This is intended for use during eager coroutine execution."); + +#define _ASYNCIO__SWAP_CURRENT_TASK_METHODDEF \ + {"_swap_current_task", _PyCFunction_CAST(_asyncio__swap_current_task), METH_FASTCALL|METH_KEYWORDS, _asyncio__swap_current_task__doc__}, + +static PyObject * +_asyncio__swap_current_task_impl(PyObject *module, PyObject *loop, + PyObject *task); + +static PyObject * +_asyncio__swap_current_task(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(loop), &_Py_ID(task), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"loop", "task", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "_swap_current_task", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + PyObject *loop; + PyObject *task; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); + if (!args) { + goto exit; + } + loop = args[0]; + task = args[1]; + return_value = _asyncio__swap_current_task_impl(module, loop, task); + +exit: + return return_value; +} + +PyDoc_STRVAR(_asyncio_current_task__doc__, +"current_task($module, /, loop=None)\n" +"--\n" +"\n" +"Return a currently executed task."); + +#define _ASYNCIO_CURRENT_TASK_METHODDEF \ + {"current_task", _PyCFunction_CAST(_asyncio_current_task), METH_FASTCALL|METH_KEYWORDS, _asyncio_current_task__doc__}, + +static PyObject * +_asyncio_current_task_impl(PyObject *module, PyObject *loop); + +static PyObject * +_asyncio_current_task(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(loop), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"loop", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "current_task", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *loop = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + loop = args[0]; +skip_optional_pos: + return_value = _asyncio_current_task_impl(module, loop); + +exit: + return return_value; +} +/*[clinic end generated code: output=6b0e283177b07639 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_bisectmodule.c.h b/Modules/clinic/_bisectmodule.c.h index 2f0a3575..7944f521 100644 --- a/Modules/clinic/_bisectmodule.c.h +++ b/Modules/clinic/_bisectmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_bisect_bisect_right__doc__, "bisect_right($module, /, a, x, lo=0, hi=None, *, key=None)\n" "--\n" @@ -13,7 +19,9 @@ PyDoc_STRVAR(_bisect_bisect_right__doc__, "insert just after the rightmost x already there.\n" "\n" "Optional args lo (default 0) and hi (default len(a)) bound the\n" -"slice of a to be searched."); +"slice of a to be searched.\n" +"\n" +"A custom key function can be supplied to customize the sort order."); #define _BISECT_BISECT_RIGHT_METHODDEF \ {"bisect_right", _PyCFunction_CAST(_bisect_bisect_right), METH_FASTCALL|METH_KEYWORDS, _bisect_bisect_right__doc__}, @@ -26,8 +34,31 @@ static PyObject * _bisect_bisect_right(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 5 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), &_Py_ID(x), &_Py_ID(lo), &_Py_ID(hi), &_Py_ID(key), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"a", "x", "lo", "hi", "key", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "bisect_right", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "bisect_right", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; PyObject *a; @@ -96,7 +127,9 @@ PyDoc_STRVAR(_bisect_insort_right__doc__, "If x is already in a, insert it to the right of the rightmost x.\n" "\n" "Optional args lo (default 0) and hi (default len(a)) bound the\n" -"slice of a to be searched."); +"slice of a to be searched.\n" +"\n" +"A custom key function can be supplied to customize the sort order."); #define _BISECT_INSORT_RIGHT_METHODDEF \ {"insort_right", _PyCFunction_CAST(_bisect_insort_right), METH_FASTCALL|METH_KEYWORDS, _bisect_insort_right__doc__}, @@ -109,8 +142,31 @@ static PyObject * _bisect_insort_right(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 5 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), &_Py_ID(x), &_Py_ID(lo), &_Py_ID(hi), &_Py_ID(key), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"a", "x", "lo", "hi", "key", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "insort_right", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "insort_right", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; PyObject *a; @@ -176,7 +232,9 @@ PyDoc_STRVAR(_bisect_bisect_left__doc__, "insert just before the leftmost x already there.\n" "\n" "Optional args lo (default 0) and hi (default len(a)) bound the\n" -"slice of a to be searched."); +"slice of a to be searched.\n" +"\n" +"A custom key function can be supplied to customize the sort order."); #define _BISECT_BISECT_LEFT_METHODDEF \ {"bisect_left", _PyCFunction_CAST(_bisect_bisect_left), METH_FASTCALL|METH_KEYWORDS, _bisect_bisect_left__doc__}, @@ -189,8 +247,31 @@ static PyObject * _bisect_bisect_left(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 5 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), &_Py_ID(x), &_Py_ID(lo), &_Py_ID(hi), &_Py_ID(key), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"a", "x", "lo", "hi", "key", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "bisect_left", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "bisect_left", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; PyObject *a; @@ -259,7 +340,9 @@ PyDoc_STRVAR(_bisect_insort_left__doc__, "If x is already in a, insert it to the left of the leftmost x.\n" "\n" "Optional args lo (default 0) and hi (default len(a)) bound the\n" -"slice of a to be searched."); +"slice of a to be searched.\n" +"\n" +"A custom key function can be supplied to customize the sort order."); #define _BISECT_INSORT_LEFT_METHODDEF \ {"insort_left", _PyCFunction_CAST(_bisect_insort_left), METH_FASTCALL|METH_KEYWORDS, _bisect_insort_left__doc__}, @@ -272,8 +355,31 @@ static PyObject * _bisect_insort_left(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 5 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), &_Py_ID(x), &_Py_ID(lo), &_Py_ID(hi), &_Py_ID(key), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"a", "x", "lo", "hi", "key", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "insort_left", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "insort_left", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; PyObject *a; @@ -327,4 +433,4 @@ skip_optional_kwonly: exit: return return_value; } -/*[clinic end generated code: output=ee8c32ff8d3d1fac input=a9049054013a1b77]*/ +/*[clinic end generated code: output=5a7fa64bf9b262f3 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_bz2module.c.h b/Modules/clinic/_bz2module.c.h index 3ed72f8b..d7797d63 100644 --- a/Modules/clinic/_bz2module.c.h +++ b/Modules/clinic/_bz2module.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_bz2_BZ2Compressor_compress__doc__, "compress($self, data, /)\n" "--\n" @@ -65,6 +71,48 @@ _bz2_BZ2Compressor_flush(BZ2Compressor *self, PyObject *Py_UNUSED(ignored)) return _bz2_BZ2Compressor_flush_impl(self); } +PyDoc_STRVAR(_bz2_BZ2Compressor__doc__, +"BZ2Compressor(compresslevel=9, /)\n" +"--\n" +"\n" +"Create a compressor object for compressing data incrementally.\n" +"\n" +" compresslevel\n" +" Compression level, as a number between 1 and 9.\n" +"\n" +"For one-shot compression, use the compress() function instead."); + +static PyObject * +_bz2_BZ2Compressor_impl(PyTypeObject *type, int compresslevel); + +static PyObject * +_bz2_BZ2Compressor(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + PyTypeObject *base_tp = clinic_state()->bz2_compressor_type; + int compresslevel = 9; + + if ((type == base_tp || type->tp_init == base_tp->tp_init) && + !_PyArg_NoKeywords("BZ2Compressor", kwargs)) { + goto exit; + } + if (!_PyArg_CheckPositional("BZ2Compressor", PyTuple_GET_SIZE(args), 0, 1)) { + goto exit; + } + if (PyTuple_GET_SIZE(args) < 1) { + goto skip_optional; + } + compresslevel = _PyLong_AsInt(PyTuple_GET_ITEM(args, 0)); + if (compresslevel == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional: + return_value = _bz2_BZ2Compressor_impl(type, compresslevel); + +exit: + return return_value; +} + PyDoc_STRVAR(_bz2_BZ2Decompressor_decompress__doc__, "decompress($self, /, data, max_length=-1)\n" "--\n" @@ -95,8 +143,31 @@ static PyObject * _bz2_BZ2Decompressor_decompress(BZ2Decompressor *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(data), &_Py_ID(max_length), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"data", "max_length", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "decompress", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "decompress", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; Py_buffer data = {NULL, NULL}; @@ -139,4 +210,35 @@ exit: return return_value; } -/*[clinic end generated code: output=a1175204a414fe2a input=a9049054013a1b77]*/ + +PyDoc_STRVAR(_bz2_BZ2Decompressor__doc__, +"BZ2Decompressor()\n" +"--\n" +"\n" +"Create a decompressor object for decompressing data incrementally.\n" +"\n" +"For one-shot decompression, use the decompress() function instead."); + +static PyObject * +_bz2_BZ2Decompressor_impl(PyTypeObject *type); + +static PyObject * +_bz2_BZ2Decompressor(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + PyTypeObject *base_tp = clinic_state()->bz2_decompressor_type; + + if ((type == base_tp || type->tp_init == base_tp->tp_init) && + !_PyArg_NoPositional("BZ2Decompressor", args)) { + goto exit; + } + if ((type == base_tp || type->tp_init == base_tp->tp_init) && + !_PyArg_NoKeywords("BZ2Decompressor", kwargs)) { + goto exit; + } + return_value = _bz2_BZ2Decompressor_impl(type); + +exit: + return return_value; +} +/*[clinic end generated code: output=805400e4805098ec input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_codecsmodule.c.h b/Modules/clinic/_codecsmodule.c.h index 29e9d5ea..f11bcc88 100644 --- a/Modules/clinic/_codecsmodule.c.h +++ b/Modules/clinic/_codecsmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_codecs_register__doc__, "register($module, search_function, /)\n" "--\n" @@ -86,8 +92,31 @@ static PyObject * _codecs_encode(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(obj), &_Py_ID(encoding), &_Py_ID(errors), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"obj", "encoding", "errors", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "encode", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "encode", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *obj; @@ -163,8 +192,31 @@ static PyObject * _codecs_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(obj), &_Py_ID(encoding), &_Py_ID(errors), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"obj", "encoding", "errors", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "decode", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "decode", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *obj; @@ -398,8 +450,8 @@ _codecs_utf_7_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 3) { goto skip_optional; } - final = _PyLong_AsInt(args[2]); - if (final == -1 && PyErr_Occurred()) { + final = PyObject_IsTrue(args[2]); + if (final < 0) { goto exit; } skip_optional: @@ -468,8 +520,8 @@ _codecs_utf_8_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 3) { goto skip_optional; } - final = _PyLong_AsInt(args[2]); - if (final == -1 && PyErr_Occurred()) { + final = PyObject_IsTrue(args[2]); + if (final < 0) { goto exit; } skip_optional: @@ -538,8 +590,8 @@ _codecs_utf_16_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 3) { goto skip_optional; } - final = _PyLong_AsInt(args[2]); - if (final == -1 && PyErr_Occurred()) { + final = PyObject_IsTrue(args[2]); + if (final < 0) { goto exit; } skip_optional: @@ -608,8 +660,8 @@ _codecs_utf_16_le_decode(PyObject *module, PyObject *const *args, Py_ssize_t nar if (nargs < 3) { goto skip_optional; } - final = _PyLong_AsInt(args[2]); - if (final == -1 && PyErr_Occurred()) { + final = PyObject_IsTrue(args[2]); + if (final < 0) { goto exit; } skip_optional: @@ -678,8 +730,8 @@ _codecs_utf_16_be_decode(PyObject *module, PyObject *const *args, Py_ssize_t nar if (nargs < 3) { goto skip_optional; } - final = _PyLong_AsInt(args[2]); - if (final == -1 && PyErr_Occurred()) { + final = PyObject_IsTrue(args[2]); + if (final < 0) { goto exit; } skip_optional: @@ -757,8 +809,8 @@ _codecs_utf_16_ex_decode(PyObject *module, PyObject *const *args, Py_ssize_t nar if (nargs < 4) { goto skip_optional; } - final = _PyLong_AsInt(args[3]); - if (final == -1 && PyErr_Occurred()) { + final = PyObject_IsTrue(args[3]); + if (final < 0) { goto exit; } skip_optional: @@ -827,8 +879,8 @@ _codecs_utf_32_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 3) { goto skip_optional; } - final = _PyLong_AsInt(args[2]); - if (final == -1 && PyErr_Occurred()) { + final = PyObject_IsTrue(args[2]); + if (final < 0) { goto exit; } skip_optional: @@ -897,8 +949,8 @@ _codecs_utf_32_le_decode(PyObject *module, PyObject *const *args, Py_ssize_t nar if (nargs < 3) { goto skip_optional; } - final = _PyLong_AsInt(args[2]); - if (final == -1 && PyErr_Occurred()) { + final = PyObject_IsTrue(args[2]); + if (final < 0) { goto exit; } skip_optional: @@ -967,8 +1019,8 @@ _codecs_utf_32_be_decode(PyObject *module, PyObject *const *args, Py_ssize_t nar if (nargs < 3) { goto skip_optional; } - final = _PyLong_AsInt(args[2]); - if (final == -1 && PyErr_Occurred()) { + final = PyObject_IsTrue(args[2]); + if (final < 0) { goto exit; } skip_optional: @@ -1046,8 +1098,8 @@ _codecs_utf_32_ex_decode(PyObject *module, PyObject *const *args, Py_ssize_t nar if (nargs < 4) { goto skip_optional; } - final = _PyLong_AsInt(args[3]); - if (final == -1 && PyErr_Occurred()) { + final = PyObject_IsTrue(args[3]); + if (final < 0) { goto exit; } skip_optional: @@ -1126,8 +1178,8 @@ _codecs_unicode_escape_decode(PyObject *module, PyObject *const *args, Py_ssize_ if (nargs < 3) { goto skip_optional; } - final = _PyLong_AsInt(args[2]); - if (final == -1 && PyErr_Occurred()) { + final = PyObject_IsTrue(args[2]); + if (final < 0) { goto exit; } skip_optional: @@ -1206,8 +1258,8 @@ _codecs_raw_unicode_escape_decode(PyObject *module, PyObject *const *args, Py_ss if (nargs < 3) { goto skip_optional; } - final = _PyLong_AsInt(args[2]); - if (final == -1 && PyErr_Occurred()) { + final = PyObject_IsTrue(args[2]); + if (final < 0) { goto exit; } skip_optional: @@ -1469,8 +1521,8 @@ _codecs_mbcs_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 3) { goto skip_optional; } - final = _PyLong_AsInt(args[2]); - if (final == -1 && PyErr_Occurred()) { + final = PyObject_IsTrue(args[2]); + if (final < 0) { goto exit; } skip_optional: @@ -1543,8 +1595,8 @@ _codecs_oem_decode(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 3) { goto skip_optional; } - final = _PyLong_AsInt(args[2]); - if (final == -1 && PyErr_Occurred()) { + final = PyObject_IsTrue(args[2]); + if (final < 0) { goto exit; } skip_optional: @@ -1622,8 +1674,8 @@ _codecs_code_page_decode(PyObject *module, PyObject *const *args, Py_ssize_t nar if (nargs < 4) { goto skip_optional; } - final = _PyLong_AsInt(args[3]); - if (final == -1 && PyErr_Occurred()) { + final = PyObject_IsTrue(args[3]); + if (final < 0) { goto exit; } skip_optional: @@ -2817,4 +2869,4 @@ exit: #ifndef _CODECS_CODE_PAGE_ENCODE_METHODDEF #define _CODECS_CODE_PAGE_ENCODE_METHODDEF #endif /* !defined(_CODECS_CODE_PAGE_ENCODE_METHODDEF) */ -/*[clinic end generated code: output=92250568c3a6f0a0 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=603da07cf8dfeb4b input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_collectionsmodule.c.h b/Modules/clinic/_collectionsmodule.c.h index e53acd6a..3882d069 100644 --- a/Modules/clinic/_collectionsmodule.c.h +++ b/Modules/clinic/_collectionsmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_collections__count_elements__doc__, "_count_elements($module, mapping, iterable, /)\n" "--\n" @@ -40,11 +46,11 @@ static PyObject * tuplegetter_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + PyTypeObject *base_tp = clinic_state()->tuplegetter_type; Py_ssize_t index; PyObject *doc; - if ((type == &tuplegetter_type || - type->tp_init == tuplegetter_type.tp_init) && + if ((type == base_tp || type->tp_init == base_tp->tp_init) && !_PyArg_NoKeywords("_tuplegetter", kwargs)) { goto exit; } @@ -69,4 +75,4 @@ tuplegetter_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=36b0948c4676c831 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=00e516317d2b8bed input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_contextvarsmodule.c.h b/Modules/clinic/_contextvarsmodule.c.h index b1885e41..461d4845 100644 --- a/Modules/clinic/_contextvarsmodule.c.h +++ b/Modules/clinic/_contextvarsmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_contextvars_copy_context__doc__, "copy_context($module, /)\n" "--\n" @@ -18,4 +24,4 @@ _contextvars_copy_context(PyObject *module, PyObject *Py_UNUSED(ignored)) { return _contextvars_copy_context_impl(module); } -/*[clinic end generated code: output=26e07024451baf52 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=1736c27450823e70 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_cryptmodule.c.h b/Modules/clinic/_cryptmodule.c.h index 401d0462..97b70b3c 100644 --- a/Modules/clinic/_cryptmodule.c.h +++ b/Modules/clinic/_cryptmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(crypt_crypt__doc__, "crypt($module, word, salt, /)\n" "--\n" @@ -60,4 +66,4 @@ crypt_crypt(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=6f61ab29e361f9d0 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=235ccef9211184f4 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_csv.c.h b/Modules/clinic/_csv.c.h index ae5dec74..89009463 100644 --- a/Modules/clinic/_csv.c.h +++ b/Modules/clinic/_csv.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_csv_list_dialects__doc__, "list_dialects($module, /)\n" "--\n" @@ -40,8 +46,31 @@ static PyObject * _csv_unregister_dialect(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(name), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"name", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "unregister_dialect", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "unregister_dialect", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *name; @@ -74,8 +103,31 @@ static PyObject * _csv_get_dialect(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(name), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"name", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "get_dialect", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "get_dialect", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *name; @@ -111,8 +163,31 @@ static PyObject * _csv_field_size_limit(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(new_limit), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"new_limit", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "field_size_limit", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "field_size_limit", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *new_limit = NULL; @@ -131,4 +206,4 @@ skip_optional_pos: exit: return return_value; } -/*[clinic end generated code: output=6235abc491b02188 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=94374e41eb2806ee input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_curses_panel.c.h b/Modules/clinic/_curses_panel.c.h index 31101c10..bb6cc90f 100644 --- a/Modules/clinic/_curses_panel.c.h +++ b/Modules/clinic/_curses_panel.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_curses_panel_panel_bottom__doc__, "bottom($self, /)\n" "--\n" @@ -163,8 +169,19 @@ static PyObject * _curses_panel_panel_move(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + static const char * const _keywords[] = {"", "", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "move", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "move", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; int y; int x; @@ -223,8 +240,19 @@ static PyObject * _curses_panel_panel_replace(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + static const char * const _keywords[] = {"", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "replace", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "replace", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyCursesWindowObject *win; @@ -260,8 +288,19 @@ static PyObject * _curses_panel_panel_set_userptr(PyCursesPanelObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + static const char * const _keywords[] = {"", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "set_userptr", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "set_userptr", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *obj; @@ -383,4 +422,4 @@ _curses_panel_update_panels(PyObject *module, PyObject *Py_UNUSED(ignored)) { return _curses_panel_update_panels_impl(module); } -/*[clinic end generated code: output=c471aed62bc31e79 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=8d0533681891523c input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_cursesmodule.c.h b/Modules/clinic/_cursesmodule.c.h index c7d1eca6..9d99d41a 100644 --- a/Modules/clinic/_cursesmodule.c.h +++ b/Modules/clinic/_cursesmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_curses_window_addch__doc__, "addch([y, x,] ch, [attr=_curses.A_NORMAL])\n" "Paint the character.\n" @@ -1742,7 +1748,7 @@ _curses_window_touchline(PyCursesWindowObject *self, PyObject *args) } break; case 3: - if (!PyArg_ParseTuple(args, "iii:touchline", &start, &count, &changed)) { + if (!PyArg_ParseTuple(args, "iip:touchline", &start, &count, &changed)) { goto exit; } group_right_1 = 1; @@ -1935,8 +1941,8 @@ _curses_cbreak(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 1) { goto skip_optional; } - flag = _PyLong_AsInt(args[0]); - if (flag == -1 && PyErr_Occurred()) { + flag = PyObject_IsTrue(args[0]); + if (flag < 0) { goto exit; } skip_optional: @@ -2171,8 +2177,8 @@ _curses_echo(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 1) { goto skip_optional; } - flag = _PyLong_AsInt(args[0]); - if (flag == -1 && PyErr_Occurred()) { + flag = PyObject_IsTrue(args[0]); + if (flag < 0) { goto exit; } skip_optional: @@ -2678,8 +2684,31 @@ static PyObject * _curses_setupterm(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(term), &_Py_ID(fd), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"term", "fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "setupterm", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "setupterm", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; const char *term = NULL; @@ -2871,8 +2900,8 @@ _curses_intrflush(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int flag; - flag = _PyLong_AsInt(arg); - if (flag == -1 && PyErr_Occurred()) { + flag = PyObject_IsTrue(arg); + if (flag < 0) { goto exit; } return_value = _curses_intrflush_impl(module, flag); @@ -3035,8 +3064,8 @@ _curses_meta(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int yes; - yes = _PyLong_AsInt(arg); - if (yes == -1 && PyErr_Occurred()) { + yes = PyObject_IsTrue(arg); + if (yes < 0) { goto exit; } return_value = _curses_meta_impl(module, yes); @@ -3279,8 +3308,8 @@ _curses_nl(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 1) { goto skip_optional; } - flag = _PyLong_AsInt(args[0]); - if (flag == -1 && PyErr_Occurred()) { + flag = PyObject_IsTrue(args[0]); + if (flag < 0) { goto exit; } skip_optional: @@ -3511,8 +3540,8 @@ _curses_qiflush(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 1) { goto skip_optional; } - flag = _PyLong_AsInt(args[0]); - if (flag == -1 && PyErr_Occurred()) { + flag = PyObject_IsTrue(args[0]); + if (flag < 0) { goto exit; } skip_optional: @@ -3574,8 +3603,8 @@ _curses_raw(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 1) { goto skip_optional; } - flag = _PyLong_AsInt(args[0]); - if (flag == -1 && PyErr_Occurred()) { + flag = PyObject_IsTrue(args[0]); + if (flag < 0) { goto exit; } skip_optional: @@ -4135,8 +4164,8 @@ _curses_use_env(PyObject *module, PyObject *arg) PyObject *return_value = NULL; int flag; - flag = _PyLong_AsInt(arg); - if (flag == -1 && PyErr_Occurred()) { + flag = PyObject_IsTrue(arg); + if (flag < 0) { goto exit; } return_value = _curses_use_env_impl(module, flag); @@ -4284,4 +4313,4 @@ _curses_has_extended_color_support(PyObject *module, PyObject *Py_UNUSED(ignored #ifndef _CURSES_USE_DEFAULT_COLORS_METHODDEF #define _CURSES_USE_DEFAULT_COLORS_METHODDEF #endif /* !defined(_CURSES_USE_DEFAULT_COLORS_METHODDEF) */ -/*[clinic end generated code: output=1e2a8a160a0fe811 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=27a2364193b503c1 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_datetimemodule.c.h b/Modules/clinic/_datetimemodule.c.h index 31d2f75f..51e51e37 100644 --- a/Modules/clinic/_datetimemodule.c.h +++ b/Modules/clinic/_datetimemodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(datetime_date_fromtimestamp__doc__, "fromtimestamp($type, timestamp, /)\n" "--\n" @@ -22,8 +28,31 @@ static PyObject * iso_calendar_date_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(year), &_Py_ID(week), &_Py_ID(weekday), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"year", "week", "weekday", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "IsoCalendarDate", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "IsoCalendarDate", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -74,8 +103,31 @@ static PyObject * datetime_datetime_now(PyTypeObject *type, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(tz), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"tz", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "now", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "now", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *tz = Py_None; @@ -94,4 +146,4 @@ skip_optional_pos: exit: return return_value; } -/*[clinic end generated code: output=1a3da7479e443e17 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=42654669940e0e3a input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_dbmmodule.c.h b/Modules/clinic/_dbmmodule.c.h index 8157716a..172dc4b9 100644 --- a/Modules/clinic/_dbmmodule.c.h +++ b/Modules/clinic/_dbmmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_dbm_dbm_close__doc__, "close($self, /)\n" "--\n" @@ -59,8 +65,19 @@ static PyObject * _dbm_dbm_get(dbmobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + static const char * const _keywords[] = {"", "", NULL}; - static _PyArg_Parser _parser = {"s#|O:get", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .format = "s#|O:get", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE const char *key; Py_ssize_t key_length; PyObject *default_value = Py_None; @@ -94,8 +111,19 @@ static PyObject * _dbm_dbm_setdefault(dbmobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + static const char * const _keywords[] = {"", "", NULL}; - static _PyArg_Parser _parser = {"s#|O:setdefault", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .format = "s#|O:setdefault", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE const char *key; Py_ssize_t key_length; PyObject *default_value = NULL; @@ -172,4 +200,4 @@ skip_optional: exit: return return_value; } -/*[clinic end generated code: output=5798278a05032d0e input=a9049054013a1b77]*/ +/*[clinic end generated code: output=28dcf736654137c2 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_elementtree.c.h b/Modules/clinic/_elementtree.c.h index 047203ee..a0bc751c 100644 --- a/Modules/clinic/_elementtree.c.h +++ b/Modules/clinic/_elementtree.c.h @@ -2,29 +2,54 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_elementtree_Element_append__doc__, "append($self, subelement, /)\n" "--\n" "\n"); #define _ELEMENTTREE_ELEMENT_APPEND_METHODDEF \ - {"append", (PyCFunction)_elementtree_Element_append, METH_O, _elementtree_Element_append__doc__}, + {"append", _PyCFunction_CAST(_elementtree_Element_append), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _elementtree_Element_append__doc__}, static PyObject * -_elementtree_Element_append_impl(ElementObject *self, PyObject *subelement); +_elementtree_Element_append_impl(ElementObject *self, PyTypeObject *cls, + PyObject *subelement); static PyObject * -_elementtree_Element_append(ElementObject *self, PyObject *arg) +_elementtree_Element_append(ElementObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + + static const char * const _keywords[] = {"", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "append", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; PyObject *subelement; - if (!PyObject_TypeCheck(arg, &Element_Type)) { - _PyArg_BadArgument("append", "argument", (&Element_Type)->tp_name, arg); + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { goto exit; } - subelement = arg; - return_value = _elementtree_Element_append_impl(self, subelement); + if (!PyObject_TypeCheck(args[0], clinic_state()->Element_Type)) { + _PyArg_BadArgument("append", "argument 1", (clinic_state()->Element_Type)->tp_name, args[0]); + goto exit; + } + subelement = args[0]; + return_value = _elementtree_Element_append_impl(self, cls, subelement); exit: return return_value; @@ -53,15 +78,19 @@ PyDoc_STRVAR(_elementtree_Element___copy____doc__, "\n"); #define _ELEMENTTREE_ELEMENT___COPY___METHODDEF \ - {"__copy__", (PyCFunction)_elementtree_Element___copy__, METH_NOARGS, _elementtree_Element___copy____doc__}, + {"__copy__", _PyCFunction_CAST(_elementtree_Element___copy__), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _elementtree_Element___copy____doc__}, static PyObject * -_elementtree_Element___copy___impl(ElementObject *self); +_elementtree_Element___copy___impl(ElementObject *self, PyTypeObject *cls); static PyObject * -_elementtree_Element___copy__(ElementObject *self, PyObject *Py_UNUSED(ignored)) +_elementtree_Element___copy__(ElementObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - return _elementtree_Element___copy___impl(self); + if (nargs) { + PyErr_SetString(PyExc_TypeError, "__copy__() takes no arguments"); + return NULL; + } + return _elementtree_Element___copy___impl(self, cls); } PyDoc_STRVAR(_elementtree_Element___deepcopy____doc__, @@ -100,20 +129,20 @@ PyDoc_STRVAR(_elementtree_Element___sizeof____doc__, #define _ELEMENTTREE_ELEMENT___SIZEOF___METHODDEF \ {"__sizeof__", (PyCFunction)_elementtree_Element___sizeof__, METH_NOARGS, _elementtree_Element___sizeof____doc__}, -static Py_ssize_t +static size_t _elementtree_Element___sizeof___impl(ElementObject *self); static PyObject * _elementtree_Element___sizeof__(ElementObject *self, PyObject *Py_UNUSED(ignored)) { PyObject *return_value = NULL; - Py_ssize_t _return_value; + size_t _return_value; _return_value = _elementtree_Element___sizeof___impl(self); - if ((_return_value == -1) && PyErr_Occurred()) { + if ((_return_value == (size_t)-1) && PyErr_Occurred()) { goto exit; } - return_value = PyLong_FromSsize_t(_return_value); + return_value = PyLong_FromSize_t(_return_value); exit: return return_value; @@ -142,7 +171,42 @@ PyDoc_STRVAR(_elementtree_Element___setstate____doc__, "\n"); #define _ELEMENTTREE_ELEMENT___SETSTATE___METHODDEF \ - {"__setstate__", (PyCFunction)_elementtree_Element___setstate__, METH_O, _elementtree_Element___setstate____doc__}, + {"__setstate__", _PyCFunction_CAST(_elementtree_Element___setstate__), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _elementtree_Element___setstate____doc__}, + +static PyObject * +_elementtree_Element___setstate___impl(ElementObject *self, + PyTypeObject *cls, PyObject *state); + +static PyObject * +_elementtree_Element___setstate__(ElementObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + + static const char * const _keywords[] = {"", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "__setstate__", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject *state; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + state = args[0]; + return_value = _elementtree_Element___setstate___impl(self, cls, state); + +exit: + return return_value; +} PyDoc_STRVAR(_elementtree_Element_extend__doc__, "extend($self, elements, /)\n" @@ -150,7 +214,42 @@ PyDoc_STRVAR(_elementtree_Element_extend__doc__, "\n"); #define _ELEMENTTREE_ELEMENT_EXTEND_METHODDEF \ - {"extend", (PyCFunction)_elementtree_Element_extend, METH_O, _elementtree_Element_extend__doc__}, + {"extend", _PyCFunction_CAST(_elementtree_Element_extend), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _elementtree_Element_extend__doc__}, + +static PyObject * +_elementtree_Element_extend_impl(ElementObject *self, PyTypeObject *cls, + PyObject *elements); + +static PyObject * +_elementtree_Element_extend(ElementObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + + static const char * const _keywords[] = {"", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "extend", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject *elements; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + elements = args[0]; + return_value = _elementtree_Element_extend_impl(self, cls, elements); + +exit: + return return_value; +} PyDoc_STRVAR(_elementtree_Element_find__doc__, "find($self, /, path, namespaces=None)\n" @@ -158,18 +257,41 @@ PyDoc_STRVAR(_elementtree_Element_find__doc__, "\n"); #define _ELEMENTTREE_ELEMENT_FIND_METHODDEF \ - {"find", _PyCFunction_CAST(_elementtree_Element_find), METH_FASTCALL|METH_KEYWORDS, _elementtree_Element_find__doc__}, + {"find", _PyCFunction_CAST(_elementtree_Element_find), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _elementtree_Element_find__doc__}, static PyObject * -_elementtree_Element_find_impl(ElementObject *self, PyObject *path, - PyObject *namespaces); +_elementtree_Element_find_impl(ElementObject *self, PyTypeObject *cls, + PyObject *path, PyObject *namespaces); static PyObject * -_elementtree_Element_find(ElementObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +_elementtree_Element_find(ElementObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(namespaces), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", "namespaces", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "find", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "find", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *path; @@ -185,7 +307,7 @@ _elementtree_Element_find(ElementObject *self, PyObject *const *args, Py_ssize_t } namespaces = args[1]; skip_optional_pos: - return_value = _elementtree_Element_find_impl(self, path, namespaces); + return_value = _elementtree_Element_find_impl(self, cls, path, namespaces); exit: return return_value; @@ -197,19 +319,42 @@ PyDoc_STRVAR(_elementtree_Element_findtext__doc__, "\n"); #define _ELEMENTTREE_ELEMENT_FINDTEXT_METHODDEF \ - {"findtext", _PyCFunction_CAST(_elementtree_Element_findtext), METH_FASTCALL|METH_KEYWORDS, _elementtree_Element_findtext__doc__}, + {"findtext", _PyCFunction_CAST(_elementtree_Element_findtext), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _elementtree_Element_findtext__doc__}, static PyObject * -_elementtree_Element_findtext_impl(ElementObject *self, PyObject *path, - PyObject *default_value, +_elementtree_Element_findtext_impl(ElementObject *self, PyTypeObject *cls, + PyObject *path, PyObject *default_value, PyObject *namespaces); static PyObject * -_elementtree_Element_findtext(ElementObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +_elementtree_Element_findtext(ElementObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(default), &_Py_ID(namespaces), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", "default", "namespaces", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "findtext", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "findtext", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *path; @@ -232,7 +377,7 @@ _elementtree_Element_findtext(ElementObject *self, PyObject *const *args, Py_ssi } namespaces = args[2]; skip_optional_pos: - return_value = _elementtree_Element_findtext_impl(self, path, default_value, namespaces); + return_value = _elementtree_Element_findtext_impl(self, cls, path, default_value, namespaces); exit: return return_value; @@ -244,18 +389,41 @@ PyDoc_STRVAR(_elementtree_Element_findall__doc__, "\n"); #define _ELEMENTTREE_ELEMENT_FINDALL_METHODDEF \ - {"findall", _PyCFunction_CAST(_elementtree_Element_findall), METH_FASTCALL|METH_KEYWORDS, _elementtree_Element_findall__doc__}, + {"findall", _PyCFunction_CAST(_elementtree_Element_findall), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _elementtree_Element_findall__doc__}, static PyObject * -_elementtree_Element_findall_impl(ElementObject *self, PyObject *path, - PyObject *namespaces); +_elementtree_Element_findall_impl(ElementObject *self, PyTypeObject *cls, + PyObject *path, PyObject *namespaces); static PyObject * -_elementtree_Element_findall(ElementObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +_elementtree_Element_findall(ElementObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(namespaces), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", "namespaces", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "findall", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "findall", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *path; @@ -271,7 +439,7 @@ _elementtree_Element_findall(ElementObject *self, PyObject *const *args, Py_ssiz } namespaces = args[1]; skip_optional_pos: - return_value = _elementtree_Element_findall_impl(self, path, namespaces); + return_value = _elementtree_Element_findall_impl(self, cls, path, namespaces); exit: return return_value; @@ -283,18 +451,41 @@ PyDoc_STRVAR(_elementtree_Element_iterfind__doc__, "\n"); #define _ELEMENTTREE_ELEMENT_ITERFIND_METHODDEF \ - {"iterfind", _PyCFunction_CAST(_elementtree_Element_iterfind), METH_FASTCALL|METH_KEYWORDS, _elementtree_Element_iterfind__doc__}, + {"iterfind", _PyCFunction_CAST(_elementtree_Element_iterfind), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _elementtree_Element_iterfind__doc__}, static PyObject * -_elementtree_Element_iterfind_impl(ElementObject *self, PyObject *path, - PyObject *namespaces); +_elementtree_Element_iterfind_impl(ElementObject *self, PyTypeObject *cls, + PyObject *path, PyObject *namespaces); static PyObject * -_elementtree_Element_iterfind(ElementObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +_elementtree_Element_iterfind(ElementObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(namespaces), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", "namespaces", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "iterfind", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "iterfind", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *path; @@ -310,7 +501,7 @@ _elementtree_Element_iterfind(ElementObject *self, PyObject *const *args, Py_ssi } namespaces = args[1]; skip_optional_pos: - return_value = _elementtree_Element_iterfind_impl(self, path, namespaces); + return_value = _elementtree_Element_iterfind_impl(self, cls, path, namespaces); exit: return return_value; @@ -332,8 +523,31 @@ static PyObject * _elementtree_Element_get(ElementObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(key), &_Py_ID(default), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"key", "default", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "get", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "get", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *key; @@ -361,17 +575,41 @@ PyDoc_STRVAR(_elementtree_Element_iter__doc__, "\n"); #define _ELEMENTTREE_ELEMENT_ITER_METHODDEF \ - {"iter", _PyCFunction_CAST(_elementtree_Element_iter), METH_FASTCALL|METH_KEYWORDS, _elementtree_Element_iter__doc__}, + {"iter", _PyCFunction_CAST(_elementtree_Element_iter), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _elementtree_Element_iter__doc__}, static PyObject * -_elementtree_Element_iter_impl(ElementObject *self, PyObject *tag); +_elementtree_Element_iter_impl(ElementObject *self, PyTypeObject *cls, + PyObject *tag); static PyObject * -_elementtree_Element_iter(ElementObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +_elementtree_Element_iter(ElementObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(tag), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"tag", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "iter", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "iter", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *tag = Py_None; @@ -385,7 +623,7 @@ _elementtree_Element_iter(ElementObject *self, PyObject *const *args, Py_ssize_t } tag = args[0]; skip_optional_pos: - return_value = _elementtree_Element_iter_impl(self, tag); + return_value = _elementtree_Element_iter_impl(self, cls, tag); exit: return return_value; @@ -397,15 +635,19 @@ PyDoc_STRVAR(_elementtree_Element_itertext__doc__, "\n"); #define _ELEMENTTREE_ELEMENT_ITERTEXT_METHODDEF \ - {"itertext", (PyCFunction)_elementtree_Element_itertext, METH_NOARGS, _elementtree_Element_itertext__doc__}, + {"itertext", _PyCFunction_CAST(_elementtree_Element_itertext), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _elementtree_Element_itertext__doc__}, static PyObject * -_elementtree_Element_itertext_impl(ElementObject *self); +_elementtree_Element_itertext_impl(ElementObject *self, PyTypeObject *cls); static PyObject * -_elementtree_Element_itertext(ElementObject *self, PyObject *Py_UNUSED(ignored)) +_elementtree_Element_itertext(ElementObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - return _elementtree_Element_itertext_impl(self); + if (nargs) { + PyErr_SetString(PyExc_TypeError, "itertext() takes no arguments"); + return NULL; + } + return _elementtree_Element_itertext_impl(self, cls); } PyDoc_STRVAR(_elementtree_Element_insert__doc__, @@ -442,8 +684,8 @@ _elementtree_Element_insert(ElementObject *self, PyObject *const *args, Py_ssize } index = ival; } - if (!PyObject_TypeCheck(args[1], &Element_Type)) { - _PyArg_BadArgument("insert", "argument 2", (&Element_Type)->tp_name, args[1]); + if (!PyObject_TypeCheck(args[1], clinic_state()->Element_Type)) { + _PyArg_BadArgument("insert", "argument 2", (clinic_state()->Element_Type)->tp_name, args[1]); goto exit; } subelement = args[1]; @@ -493,20 +735,35 @@ PyDoc_STRVAR(_elementtree_Element_makeelement__doc__, "\n"); #define _ELEMENTTREE_ELEMENT_MAKEELEMENT_METHODDEF \ - {"makeelement", _PyCFunction_CAST(_elementtree_Element_makeelement), METH_FASTCALL, _elementtree_Element_makeelement__doc__}, + {"makeelement", _PyCFunction_CAST(_elementtree_Element_makeelement), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _elementtree_Element_makeelement__doc__}, static PyObject * -_elementtree_Element_makeelement_impl(ElementObject *self, PyObject *tag, - PyObject *attrib); +_elementtree_Element_makeelement_impl(ElementObject *self, PyTypeObject *cls, + PyObject *tag, PyObject *attrib); static PyObject * -_elementtree_Element_makeelement(ElementObject *self, PyObject *const *args, Py_ssize_t nargs) +_elementtree_Element_makeelement(ElementObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + + static const char * const _keywords[] = {"", "", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "makeelement", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; PyObject *tag; PyObject *attrib; - if (!_PyArg_CheckPositional("makeelement", nargs, 2, 2)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); + if (!args) { goto exit; } tag = args[0]; @@ -515,7 +772,7 @@ _elementtree_Element_makeelement(ElementObject *self, PyObject *const *args, Py_ goto exit; } attrib = args[1]; - return_value = _elementtree_Element_makeelement_impl(self, tag, attrib); + return_value = _elementtree_Element_makeelement_impl(self, cls, tag, attrib); exit: return return_value; @@ -538,8 +795,8 @@ _elementtree_Element_remove(ElementObject *self, PyObject *arg) PyObject *return_value = NULL; PyObject *subelement; - if (!PyObject_TypeCheck(arg, &Element_Type)) { - _PyArg_BadArgument("remove", "argument", (&Element_Type)->tp_name, arg); + if (!PyObject_TypeCheck(arg, clinic_state()->Element_Type)) { + _PyArg_BadArgument("remove", "argument", (clinic_state()->Element_Type)->tp_name, arg); goto exit; } subelement = arg; @@ -590,8 +847,31 @@ static int _elementtree_TreeBuilder___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 5 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(element_factory), &_Py_ID(comment_factory), &_Py_ID(pi_factory), &_Py_ID(insert_comments), &_Py_ID(insert_pis), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"element_factory", "comment_factory", "pi_factory", "insert_comments", "insert_pis", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "TreeBuilder", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "TreeBuilder", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -801,8 +1081,31 @@ static int _elementtree_XMLParser___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(target), &_Py_ID(encoding), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"target", "encoding", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "XMLParser", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "XMLParser", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -915,4 +1218,4 @@ skip_optional: exit: return return_value; } -/*[clinic end generated code: output=3fd6fa2ce1aeca76 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=40767b1a98e54b60 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_functoolsmodule.c.h b/Modules/clinic/_functoolsmodule.c.h new file mode 100644 index 00000000..9c79e643 --- /dev/null +++ b/Modules/clinic/_functoolsmodule.c.h @@ -0,0 +1,104 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + +PyDoc_STRVAR(_functools_cmp_to_key__doc__, +"cmp_to_key($module, /, mycmp)\n" +"--\n" +"\n" +"Convert a cmp= function into a key= function.\n" +"\n" +" mycmp\n" +" Function that compares two objects."); + +#define _FUNCTOOLS_CMP_TO_KEY_METHODDEF \ + {"cmp_to_key", _PyCFunction_CAST(_functools_cmp_to_key), METH_FASTCALL|METH_KEYWORDS, _functools_cmp_to_key__doc__}, + +static PyObject * +_functools_cmp_to_key_impl(PyObject *module, PyObject *mycmp); + +static PyObject * +_functools_cmp_to_key(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(mycmp), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"mycmp", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "cmp_to_key", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject *mycmp; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + mycmp = args[0]; + return_value = _functools_cmp_to_key_impl(module, mycmp); + +exit: + return return_value; +} + +PyDoc_STRVAR(_functools__lru_cache_wrapper_cache_info__doc__, +"cache_info($self, /)\n" +"--\n" +"\n" +"Report cache statistics"); + +#define _FUNCTOOLS__LRU_CACHE_WRAPPER_CACHE_INFO_METHODDEF \ + {"cache_info", (PyCFunction)_functools__lru_cache_wrapper_cache_info, METH_NOARGS, _functools__lru_cache_wrapper_cache_info__doc__}, + +static PyObject * +_functools__lru_cache_wrapper_cache_info_impl(PyObject *self); + +static PyObject * +_functools__lru_cache_wrapper_cache_info(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _functools__lru_cache_wrapper_cache_info_impl(self); +} + +PyDoc_STRVAR(_functools__lru_cache_wrapper_cache_clear__doc__, +"cache_clear($self, /)\n" +"--\n" +"\n" +"Clear the cache and cache statistics"); + +#define _FUNCTOOLS__LRU_CACHE_WRAPPER_CACHE_CLEAR_METHODDEF \ + {"cache_clear", (PyCFunction)_functools__lru_cache_wrapper_cache_clear, METH_NOARGS, _functools__lru_cache_wrapper_cache_clear__doc__}, + +static PyObject * +_functools__lru_cache_wrapper_cache_clear_impl(PyObject *self); + +static PyObject * +_functools__lru_cache_wrapper_cache_clear(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _functools__lru_cache_wrapper_cache_clear_impl(self); +} +/*[clinic end generated code: output=7e7f3bcf9ed61f23 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_gdbmmodule.c.h b/Modules/clinic/_gdbmmodule.c.h index e4cb1e94..5c6aeeee 100644 --- a/Modules/clinic/_gdbmmodule.c.h +++ b/Modules/clinic/_gdbmmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_gdbm_gdbm_get__doc__, "get($self, key, default=None, /)\n" "--\n" @@ -162,8 +168,19 @@ static PyObject * _gdbm_gdbm_nextkey(gdbmobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + static const char * const _keywords[] = {"", NULL}; - static _PyArg_Parser _parser = {"s#:nextkey", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .format = "s#:nextkey", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE const char *key; Py_ssize_t key_length; @@ -305,4 +322,4 @@ skip_optional: exit: return return_value; } -/*[clinic end generated code: output=617117d16956ac4d input=a9049054013a1b77]*/ +/*[clinic end generated code: output=c6e721d82335adb3 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_hashopenssl.c.h b/Modules/clinic/_hashopenssl.c.h index 5d84f4ac..fb61a444 100644 --- a/Modules/clinic/_hashopenssl.c.h +++ b/Modules/clinic/_hashopenssl.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(EVP_copy__doc__, "copy($self, /)\n" "--\n" @@ -83,8 +89,31 @@ static PyObject * EVPXOF_digest(EVPobject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(length), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"length", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "digest", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "digest", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t length; @@ -130,8 +159,31 @@ static PyObject * EVPXOF_hexdigest(EVPobject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(length), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"length", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "hexdigest", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "hexdigest", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t length; @@ -181,8 +233,31 @@ static PyObject * EVP_new(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(name), &_Py_ID(string), &_Py_ID(usedforsecurity), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"name", "string", "usedforsecurity", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "new", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "new", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *name_obj; @@ -235,8 +310,31 @@ static PyObject * _hashlib_openssl_md5(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "openssl_md5", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "openssl_md5", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *data_obj = NULL; @@ -287,8 +385,31 @@ static PyObject * _hashlib_openssl_sha1(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "openssl_sha1", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "openssl_sha1", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *data_obj = NULL; @@ -339,8 +460,31 @@ static PyObject * _hashlib_openssl_sha224(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "openssl_sha224", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "openssl_sha224", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *data_obj = NULL; @@ -391,8 +535,31 @@ static PyObject * _hashlib_openssl_sha256(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "openssl_sha256", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "openssl_sha256", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *data_obj = NULL; @@ -443,8 +610,31 @@ static PyObject * _hashlib_openssl_sha384(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "openssl_sha384", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "openssl_sha384", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *data_obj = NULL; @@ -495,8 +685,31 @@ static PyObject * _hashlib_openssl_sha512(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "openssl_sha512", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "openssl_sha512", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *data_obj = NULL; @@ -549,8 +762,31 @@ static PyObject * _hashlib_openssl_sha3_224(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "openssl_sha3_224", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "openssl_sha3_224", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *data_obj = NULL; @@ -605,8 +841,31 @@ static PyObject * _hashlib_openssl_sha3_256(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "openssl_sha3_256", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "openssl_sha3_256", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *data_obj = NULL; @@ -661,8 +920,31 @@ static PyObject * _hashlib_openssl_sha3_384(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "openssl_sha3_384", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "openssl_sha3_384", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *data_obj = NULL; @@ -717,8 +999,31 @@ static PyObject * _hashlib_openssl_sha3_512(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "openssl_sha3_512", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "openssl_sha3_512", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *data_obj = NULL; @@ -773,8 +1078,31 @@ static PyObject * _hashlib_openssl_shake_128(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "openssl_shake_128", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "openssl_shake_128", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *data_obj = NULL; @@ -829,8 +1157,31 @@ static PyObject * _hashlib_openssl_shake_256(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "openssl_shake_256", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "openssl_shake_256", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *data_obj = NULL; @@ -885,8 +1236,31 @@ static PyObject * pbkdf2_hmac(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 5 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(hash_name), &_Py_ID(password), &_Py_ID(salt), &_Py_ID(iterations), &_Py_ID(dklen), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"hash_name", "password", "salt", "iterations", "dklen", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "pbkdf2_hmac", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "pbkdf2_hmac", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 4; const char *hash_name; @@ -971,8 +1345,31 @@ static PyObject * _hashlib_scrypt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 7 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(password), &_Py_ID(salt), &_Py_ID(n), &_Py_ID(r), &_Py_ID(p), &_Py_ID(maxmem), &_Py_ID(dklen), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"password", "salt", "n", "r", "p", "maxmem", "dklen", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "scrypt", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "scrypt", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[7]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; Py_buffer password = {NULL, NULL}; @@ -1087,8 +1484,31 @@ static PyObject * _hashlib_hmac_singleshot(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(key), &_Py_ID(msg), &_Py_ID(digest), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"key", "msg", "digest", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "hmac_digest", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "hmac_digest", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_buffer key = {NULL, NULL}; Py_buffer msg = {NULL, NULL}; @@ -1145,8 +1565,31 @@ static PyObject * _hashlib_hmac_new(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(key), &_Py_ID(msg), &_Py_ID(digestmod), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"key", "msg", "digestmod", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "hmac_new", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "hmac_new", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; Py_buffer key = {NULL, NULL}; @@ -1220,8 +1663,31 @@ static PyObject * _hashlib_HMAC_update(HMACobject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(msg), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"msg", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "update", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "update", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *msg; @@ -1385,4 +1851,4 @@ exit: #ifndef _HASHLIB_SCRYPT_METHODDEF #define _HASHLIB_SCRYPT_METHODDEF #endif /* !defined(_HASHLIB_SCRYPT_METHODDEF) */ -/*[clinic end generated code: output=69f2374071bff707 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=b339e255db698147 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_heapqmodule.c.h b/Modules/clinic/_heapqmodule.c.h index 8d73b5b4..3ee3f517 100644 --- a/Modules/clinic/_heapqmodule.c.h +++ b/Modules/clinic/_heapqmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_heapq_heappush__doc__, "heappush($module, heap, item, /)\n" "--\n" @@ -265,4 +271,4 @@ _heapq__heapify_max(PyObject *module, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=9a22715a8bf0c91d input=a9049054013a1b77]*/ +/*[clinic end generated code: output=29e99a48c57f82bb input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_localemodule.c.h b/Modules/clinic/_localemodule.c.h index 06942635..e6b99962 100644 --- a/Modules/clinic/_localemodule.c.h +++ b/Modules/clinic/_localemodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_locale_setlocale__doc__, "setlocale($module, category, locale=<unrepresentable>, /)\n" "--\n" @@ -602,4 +608,4 @@ _locale_getencoding(PyObject *module, PyObject *Py_UNUSED(ignored)) #ifndef _LOCALE_BIND_TEXTDOMAIN_CODESET_METHODDEF #define _LOCALE_BIND_TEXTDOMAIN_CODESET_METHODDEF #endif /* !defined(_LOCALE_BIND_TEXTDOMAIN_CODESET_METHODDEF) */ -/*[clinic end generated code: output=cfde12e987960245 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=406842c3441559cb input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_lsprof.c.h b/Modules/clinic/_lsprof.c.h index dfc003eb..5fcc7ae0 100644 --- a/Modules/clinic/_lsprof.c.h +++ b/Modules/clinic/_lsprof.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_lsprof_Profiler_getstats__doc__, "getstats($self, /)\n" "--\n" @@ -45,4 +51,4 @@ _lsprof_Profiler_getstats(ProfilerObject *self, PyTypeObject *cls, PyObject *con } return _lsprof_Profiler_getstats_impl(self, cls); } -/*[clinic end generated code: output=0615a53cce828f06 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=7425d3481349629a input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_lzmamodule.c.h b/Modules/clinic/_lzmamodule.c.h index d98af74b..9b396a56 100644 --- a/Modules/clinic/_lzmamodule.c.h +++ b/Modules/clinic/_lzmamodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_lzma_LZMACompressor_compress__doc__, "compress($self, data, /)\n" "--\n" @@ -95,8 +101,31 @@ static PyObject * _lzma_LZMADecompressor_decompress(Decompressor *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(data), &_Py_ID(max_length), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"data", "max_length", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "decompress", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "decompress", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; Py_buffer data = {NULL, NULL}; @@ -140,7 +169,7 @@ exit: return return_value; } -PyDoc_STRVAR(_lzma_LZMADecompressor___init____doc__, +PyDoc_STRVAR(_lzma_LZMADecompressor__doc__, "LZMADecompressor(format=FORMAT_AUTO, memlimit=None, filters=None)\n" "--\n" "\n" @@ -163,16 +192,39 @@ PyDoc_STRVAR(_lzma_LZMADecompressor___init____doc__, "\n" "For one-shot decompression, use the decompress() function instead."); -static int -_lzma_LZMADecompressor___init___impl(Decompressor *self, int format, - PyObject *memlimit, PyObject *filters); +static PyObject * +_lzma_LZMADecompressor_impl(PyTypeObject *type, int format, + PyObject *memlimit, PyObject *filters); -static int -_lzma_LZMADecompressor___init__(PyObject *self, PyObject *args, PyObject *kwargs) +static PyObject * +_lzma_LZMADecompressor(PyTypeObject *type, PyObject *args, PyObject *kwargs) { - int return_value = -1; + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(format), &_Py_ID(memlimit), &_Py_ID(filters), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"format", "memlimit", "filters", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "LZMADecompressor", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "LZMADecompressor", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -205,7 +257,7 @@ _lzma_LZMADecompressor___init__(PyObject *self, PyObject *args, PyObject *kwargs } filters = fastargs[2]; skip_optional_pos: - return_value = _lzma_LZMADecompressor___init___impl((Decompressor *)self, format, memlimit, filters); + return_value = _lzma_LZMADecompressor_impl(type, format, memlimit, filters); exit: return return_value; @@ -286,4 +338,4 @@ exit: return return_value; } -/*[clinic end generated code: output=bce20bac13b0f252 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=96c1fbdada1ef232 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_opcode.c.h b/Modules/clinic/_opcode.c.h index d7e96a95..3bd3ba02 100644 --- a/Modules/clinic/_opcode.c.h +++ b/Modules/clinic/_opcode.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_opcode_stack_effect__doc__, "stack_effect($module, opcode, oparg=None, /, *, jump=None)\n" "--\n" @@ -19,8 +25,31 @@ static PyObject * _opcode_stack_effect(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(jump), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "", "jump", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "stack_effect", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "stack_effect", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; int opcode; @@ -74,4 +103,4 @@ _opcode_get_specialization_stats(PyObject *module, PyObject *Py_UNUSED(ignored)) { return _opcode_get_specialization_stats_impl(module); } -/*[clinic end generated code: output=b904260bf022f953 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=21e3d53a659c651a input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_operator.c.h b/Modules/clinic/_operator.c.h index 3b5be7bf..b68e6e01 100644 --- a/Modules/clinic/_operator.c.h +++ b/Modules/clinic/_operator.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_operator_truth__doc__, "truth($module, a, /)\n" "--\n" @@ -1486,4 +1492,4 @@ _operator__compare_digest(PyObject *module, PyObject *const *args, Py_ssize_t na exit: return return_value; } -/*[clinic end generated code: output=44164c4fbd67e5c5 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=227cbcfed44f736e input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_pickle.c.h b/Modules/clinic/_pickle.c.h index 5dc62fe1..539acc34 100644 --- a/Modules/clinic/_pickle.c.h +++ b/Modules/clinic/_pickle.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_pickle_Pickler_clear_memo__doc__, "clear_memo($self, /)\n" "--\n" @@ -32,7 +38,42 @@ PyDoc_STRVAR(_pickle_Pickler_dump__doc__, "Write a pickled representation of the given object to the open file."); #define _PICKLE_PICKLER_DUMP_METHODDEF \ - {"dump", (PyCFunction)_pickle_Pickler_dump, METH_O, _pickle_Pickler_dump__doc__}, + {"dump", _PyCFunction_CAST(_pickle_Pickler_dump), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _pickle_Pickler_dump__doc__}, + +static PyObject * +_pickle_Pickler_dump_impl(PicklerObject *self, PyTypeObject *cls, + PyObject *obj); + +static PyObject * +_pickle_Pickler_dump(PicklerObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + + static const char * const _keywords[] = {"", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "dump", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject *obj; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + obj = args[0]; + return_value = _pickle_Pickler_dump_impl(self, cls, obj); + +exit: + return return_value; +} PyDoc_STRVAR(_pickle_Pickler___sizeof____doc__, "__sizeof__($self, /)\n" @@ -43,20 +84,20 @@ PyDoc_STRVAR(_pickle_Pickler___sizeof____doc__, #define _PICKLE_PICKLER___SIZEOF___METHODDEF \ {"__sizeof__", (PyCFunction)_pickle_Pickler___sizeof__, METH_NOARGS, _pickle_Pickler___sizeof____doc__}, -static Py_ssize_t +static size_t _pickle_Pickler___sizeof___impl(PicklerObject *self); static PyObject * _pickle_Pickler___sizeof__(PicklerObject *self, PyObject *Py_UNUSED(ignored)) { PyObject *return_value = NULL; - Py_ssize_t _return_value; + size_t _return_value; _return_value = _pickle_Pickler___sizeof___impl(self); - if ((_return_value == -1) && PyErr_Occurred()) { + if ((_return_value == (size_t)-1) && PyErr_Occurred()) { goto exit; } - return_value = PyLong_FromSsize_t(_return_value); + return_value = PyLong_FromSize_t(_return_value); exit: return return_value; @@ -106,8 +147,31 @@ static int _pickle_Pickler___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(file), &_Py_ID(protocol), &_Py_ID(fix_imports), &_Py_ID(buffer_callback), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"file", "protocol", "fix_imports", "buffer_callback", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "Pickler", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "Pickler", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -213,15 +277,19 @@ PyDoc_STRVAR(_pickle_Unpickler_load__doc__, "specified therein."); #define _PICKLE_UNPICKLER_LOAD_METHODDEF \ - {"load", (PyCFunction)_pickle_Unpickler_load, METH_NOARGS, _pickle_Unpickler_load__doc__}, + {"load", _PyCFunction_CAST(_pickle_Unpickler_load), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _pickle_Unpickler_load__doc__}, static PyObject * -_pickle_Unpickler_load_impl(UnpicklerObject *self); +_pickle_Unpickler_load_impl(UnpicklerObject *self, PyTypeObject *cls); static PyObject * -_pickle_Unpickler_load(UnpicklerObject *self, PyObject *Py_UNUSED(ignored)) +_pickle_Unpickler_load(UnpicklerObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - return _pickle_Unpickler_load_impl(self); + if (nargs) { + PyErr_SetString(PyExc_TypeError, "load() takes no arguments"); + return NULL; + } + return _pickle_Unpickler_load_impl(self, cls); } PyDoc_STRVAR(_pickle_Unpickler_find_class__doc__, @@ -238,26 +306,41 @@ PyDoc_STRVAR(_pickle_Unpickler_find_class__doc__, "needed. Both arguments passed are str objects."); #define _PICKLE_UNPICKLER_FIND_CLASS_METHODDEF \ - {"find_class", _PyCFunction_CAST(_pickle_Unpickler_find_class), METH_FASTCALL, _pickle_Unpickler_find_class__doc__}, + {"find_class", _PyCFunction_CAST(_pickle_Unpickler_find_class), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _pickle_Unpickler_find_class__doc__}, static PyObject * -_pickle_Unpickler_find_class_impl(UnpicklerObject *self, +_pickle_Unpickler_find_class_impl(UnpicklerObject *self, PyTypeObject *cls, PyObject *module_name, PyObject *global_name); static PyObject * -_pickle_Unpickler_find_class(UnpicklerObject *self, PyObject *const *args, Py_ssize_t nargs) +_pickle_Unpickler_find_class(UnpicklerObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + + static const char * const _keywords[] = {"", "", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "find_class", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; PyObject *module_name; PyObject *global_name; - if (!_PyArg_CheckPositional("find_class", nargs, 2, 2)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); + if (!args) { goto exit; } module_name = args[0]; global_name = args[1]; - return_value = _pickle_Unpickler_find_class_impl(self, module_name, global_name); + return_value = _pickle_Unpickler_find_class_impl(self, cls, module_name, global_name); exit: return return_value; @@ -272,20 +355,20 @@ PyDoc_STRVAR(_pickle_Unpickler___sizeof____doc__, #define _PICKLE_UNPICKLER___SIZEOF___METHODDEF \ {"__sizeof__", (PyCFunction)_pickle_Unpickler___sizeof__, METH_NOARGS, _pickle_Unpickler___sizeof____doc__}, -static Py_ssize_t +static size_t _pickle_Unpickler___sizeof___impl(UnpicklerObject *self); static PyObject * _pickle_Unpickler___sizeof__(UnpicklerObject *self, PyObject *Py_UNUSED(ignored)) { PyObject *return_value = NULL; - Py_ssize_t _return_value; + size_t _return_value; _return_value = _pickle_Unpickler___sizeof___impl(self); - if ((_return_value == -1) && PyErr_Occurred()) { + if ((_return_value == (size_t)-1) && PyErr_Occurred()) { goto exit; } - return_value = PyLong_FromSsize_t(_return_value); + return_value = PyLong_FromSize_t(_return_value); exit: return return_value; @@ -326,8 +409,31 @@ static int _pickle_Unpickler___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 5 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(file), &_Py_ID(fix_imports), &_Py_ID(encoding), &_Py_ID(errors), &_Py_ID(buffers), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"file", "fix_imports", "encoding", "errors", "buffers", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "Unpickler", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "Unpickler", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -497,8 +603,31 @@ static PyObject * _pickle_dump(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 5 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(obj), &_Py_ID(file), &_Py_ID(protocol), &_Py_ID(fix_imports), &_Py_ID(buffer_callback), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"obj", "file", "protocol", "fix_imports", "buffer_callback", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "dump", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "dump", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; PyObject *obj; @@ -578,8 +707,31 @@ static PyObject * _pickle_dumps(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(obj), &_Py_ID(protocol), &_Py_ID(fix_imports), &_Py_ID(buffer_callback), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"obj", "protocol", "fix_imports", "buffer_callback", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "dumps", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "dumps", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *obj; @@ -663,8 +815,31 @@ static PyObject * _pickle_load(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 5 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(file), &_Py_ID(fix_imports), &_Py_ID(encoding), &_Py_ID(errors), &_Py_ID(buffers), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"file", "fix_imports", "encoding", "errors", "buffers", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "load", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "load", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *file; @@ -766,8 +941,31 @@ static PyObject * _pickle_loads(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(fix_imports), &_Py_ID(encoding), &_Py_ID(errors), &_Py_ID(buffers), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "fix_imports", "encoding", "errors", "buffers", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "loads", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "loads", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *data; @@ -836,4 +1034,4 @@ skip_optional_kwonly: exit: return return_value; } -/*[clinic end generated code: output=1bb1ead3c828e108 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=a0e04b85e7bae626 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_posixsubprocess.c.h b/Modules/clinic/_posixsubprocess.c.h new file mode 100644 index 00000000..f08878cf --- /dev/null +++ b/Modules/clinic/_posixsubprocess.c.h @@ -0,0 +1,162 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + +PyDoc_STRVAR(subprocess_fork_exec__doc__, +"fork_exec($module, args, executable_list, close_fds, pass_fds, cwd,\n" +" env, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite,\n" +" errpipe_read, errpipe_write, restore_signals, call_setsid,\n" +" pgid_to_set, gid, extra_groups, uid, child_umask, preexec_fn,\n" +" allow_vfork, /)\n" +"--\n" +"\n" +"Spawn a fresh new child process.\n" +"\n" +"Fork a child process, close parent file descriptors as appropriate in the\n" +"child and duplicate the few that are needed before calling exec() in the\n" +"child process.\n" +"\n" +"If close_fds is True, close file descriptors 3 and higher, except those listed\n" +"in the sorted tuple pass_fds.\n" +"\n" +"The preexec_fn, if supplied, will be called immediately before closing file\n" +"descriptors and exec.\n" +"\n" +"WARNING: preexec_fn is NOT SAFE if your application uses threads.\n" +" It may trigger infrequent, difficult to debug deadlocks.\n" +"\n" +"If an error occurs in the child process before the exec, it is\n" +"serialized and written to the errpipe_write fd per subprocess.py.\n" +"\n" +"Returns: the child process\'s PID.\n" +"\n" +"Raises: Only on an error in the parent process."); + +#define SUBPROCESS_FORK_EXEC_METHODDEF \ + {"fork_exec", _PyCFunction_CAST(subprocess_fork_exec), METH_FASTCALL, subprocess_fork_exec__doc__}, + +static PyObject * +subprocess_fork_exec_impl(PyObject *module, PyObject *process_args, + PyObject *executable_list, int close_fds, + PyObject *py_fds_to_keep, PyObject *cwd_obj, + PyObject *env_list, int p2cread, int p2cwrite, + int c2pread, int c2pwrite, int errread, + int errwrite, int errpipe_read, int errpipe_write, + int restore_signals, int call_setsid, + pid_t pgid_to_set, PyObject *gid_object, + PyObject *extra_groups_packed, + PyObject *uid_object, int child_umask, + PyObject *preexec_fn, int allow_vfork); + +static PyObject * +subprocess_fork_exec(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *process_args; + PyObject *executable_list; + int close_fds; + PyObject *py_fds_to_keep; + PyObject *cwd_obj; + PyObject *env_list; + int p2cread; + int p2cwrite; + int c2pread; + int c2pwrite; + int errread; + int errwrite; + int errpipe_read; + int errpipe_write; + int restore_signals; + int call_setsid; + pid_t pgid_to_set; + PyObject *gid_object; + PyObject *extra_groups_packed; + PyObject *uid_object; + int child_umask; + PyObject *preexec_fn; + int allow_vfork; + + if (!_PyArg_CheckPositional("fork_exec", nargs, 23, 23)) { + goto exit; + } + process_args = args[0]; + executable_list = args[1]; + close_fds = PyObject_IsTrue(args[2]); + if (close_fds < 0) { + goto exit; + } + if (!PyTuple_Check(args[3])) { + _PyArg_BadArgument("fork_exec", "argument 4", "tuple", args[3]); + goto exit; + } + py_fds_to_keep = args[3]; + cwd_obj = args[4]; + env_list = args[5]; + p2cread = _PyLong_AsInt(args[6]); + if (p2cread == -1 && PyErr_Occurred()) { + goto exit; + } + p2cwrite = _PyLong_AsInt(args[7]); + if (p2cwrite == -1 && PyErr_Occurred()) { + goto exit; + } + c2pread = _PyLong_AsInt(args[8]); + if (c2pread == -1 && PyErr_Occurred()) { + goto exit; + } + c2pwrite = _PyLong_AsInt(args[9]); + if (c2pwrite == -1 && PyErr_Occurred()) { + goto exit; + } + errread = _PyLong_AsInt(args[10]); + if (errread == -1 && PyErr_Occurred()) { + goto exit; + } + errwrite = _PyLong_AsInt(args[11]); + if (errwrite == -1 && PyErr_Occurred()) { + goto exit; + } + errpipe_read = _PyLong_AsInt(args[12]); + if (errpipe_read == -1 && PyErr_Occurred()) { + goto exit; + } + errpipe_write = _PyLong_AsInt(args[13]); + if (errpipe_write == -1 && PyErr_Occurred()) { + goto exit; + } + restore_signals = PyObject_IsTrue(args[14]); + if (restore_signals < 0) { + goto exit; + } + call_setsid = PyObject_IsTrue(args[15]); + if (call_setsid < 0) { + goto exit; + } + pgid_to_set = PyLong_AsPid(args[16]); + if (pgid_to_set == -1 && PyErr_Occurred()) { + goto exit; + } + gid_object = args[17]; + extra_groups_packed = args[18]; + uid_object = args[19]; + child_umask = _PyLong_AsInt(args[20]); + if (child_umask == -1 && PyErr_Occurred()) { + goto exit; + } + preexec_fn = args[21]; + allow_vfork = PyObject_IsTrue(args[22]); + if (allow_vfork < 0) { + goto exit; + } + return_value = subprocess_fork_exec_impl(module, process_args, executable_list, close_fds, py_fds_to_keep, cwd_obj, env_list, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, errpipe_read, errpipe_write, restore_signals, call_setsid, pgid_to_set, gid_object, extra_groups_packed, uid_object, child_umask, preexec_fn, allow_vfork); + +exit: + return return_value; +} +/*[clinic end generated code: output=46d71e86845c93d7 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_queuemodule.c.h b/Modules/clinic/_queuemodule.c.h index b0b00f81..94fb59a5 100644 --- a/Modules/clinic/_queuemodule.c.h +++ b/Modules/clinic/_queuemodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(simplequeue_new__doc__, "SimpleQueue()\n" "--\n" @@ -15,14 +21,13 @@ static PyObject * simplequeue_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + PyTypeObject *base_tp = simplequeue_get_state_by_type(type)->SimpleQueueType; - if ((type == simplequeue_get_state_by_type(type)->SimpleQueueType || - type->tp_init == simplequeue_get_state_by_type(type)->SimpleQueueType->tp_init) && + if ((type == base_tp || type->tp_init == base_tp->tp_init) && !_PyArg_NoPositional("SimpleQueue", args)) { goto exit; } - if ((type == simplequeue_get_state_by_type(type)->SimpleQueueType || - type->tp_init == simplequeue_get_state_by_type(type)->SimpleQueueType->tp_init) && + if ((type == base_tp || type->tp_init == base_tp->tp_init) && !_PyArg_NoKeywords("SimpleQueue", kwargs)) { goto exit; } @@ -52,8 +57,31 @@ static PyObject * _queue_SimpleQueue_put(simplequeueobject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(item), &_Py_ID(block), &_Py_ID(timeout), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"item", "block", "timeout", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "put", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "put", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *item; @@ -104,8 +132,31 @@ static PyObject * _queue_SimpleQueue_put_nowait(simplequeueobject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(item), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"item", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "put_nowait", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "put_nowait", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *item; @@ -145,8 +196,31 @@ static PyObject * _queue_SimpleQueue_get(simplequeueobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(block), &_Py_ID(timeout), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"block", "timeout", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "get", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "get", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int block = 1; @@ -257,4 +331,4 @@ _queue_SimpleQueue_qsize(simplequeueobject *self, PyObject *Py_UNUSED(ignored)) exit: return return_value; } -/*[clinic end generated code: output=88ec8033aeb7241c input=a9049054013a1b77]*/ +/*[clinic end generated code: output=9a72a8d1b5767f6a input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_randommodule.c.h b/Modules/clinic/_randommodule.c.h index 503c1f93..ec8531ce 100644 --- a/Modules/clinic/_randommodule.c.h +++ b/Modules/clinic/_randommodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_random_Random_random__doc__, "random($self, /)\n" "--\n" @@ -109,4 +115,4 @@ _random_Random_getrandbits(RandomObject *self, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=d144826cde89e605 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=bc17406a886824fc input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_ssl.c.h b/Modules/clinic/_ssl.c.h index 67b125f3..9f967ddc 100644 --- a/Modules/clinic/_ssl.c.h +++ b/Modules/clinic/_ssl.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_ssl__SSLSocket_do_handshake__doc__, "do_handshake($self, /)\n" "--\n" @@ -348,8 +354,31 @@ static PyObject * _ssl__SSLSocket_get_channel_binding(PySSLSocket *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(cb_type), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"cb_type", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "get_channel_binding", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "get_channel_binding", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; const char *cb_type = "tls-unique"; @@ -406,10 +435,10 @@ static PyObject * _ssl__SSLContext(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + PyTypeObject *base_tp = get_state_type(type)->PySSLContext_Type; int proto_version; - if ((type == get_state_type(type)->PySSLContext_Type || - type->tp_init == get_state_type(type)->PySSLContext_Type->tp_init) && + if ((type == base_tp || type->tp_init == base_tp->tp_init) && !_PyArg_NoKeywords("_SSLContext", kwargs)) { goto exit; } @@ -531,8 +560,31 @@ static PyObject * _ssl__SSLContext_load_cert_chain(PySSLContext *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(certfile), &_Py_ID(keyfile), &_Py_ID(password), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"certfile", "keyfile", "password", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "load_cert_chain", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "load_cert_chain", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *certfile; @@ -579,8 +631,31 @@ static PyObject * _ssl__SSLContext_load_verify_locations(PySSLContext *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(cafile), &_Py_ID(capath), &_Py_ID(cadata), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"cafile", "capath", "cadata", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "load_verify_locations", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "load_verify_locations", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *cafile = Py_None; @@ -640,8 +715,31 @@ static PyObject * _ssl__SSLContext__wrap_socket(PySSLContext *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 5 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(sock), &_Py_ID(server_side), &_Py_ID(server_hostname), &_Py_ID(owner), &_Py_ID(session), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"sock", "server_side", "server_hostname", "owner", "session", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "_wrap_socket", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "_wrap_socket", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; PyObject *sock; @@ -659,8 +757,8 @@ _ssl__SSLContext__wrap_socket(PySSLContext *self, PyObject *const *args, Py_ssiz goto exit; } sock = args[0]; - server_side = _PyLong_AsInt(args[1]); - if (server_side == -1 && PyErr_Occurred()) { + server_side = PyObject_IsTrue(args[1]); + if (server_side < 0) { goto exit; } if (!noptargs) { @@ -709,8 +807,31 @@ static PyObject * _ssl__SSLContext__wrap_bio(PySSLContext *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 6 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(incoming), &_Py_ID(outgoing), &_Py_ID(server_side), &_Py_ID(server_hostname), &_Py_ID(owner), &_Py_ID(session), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"incoming", "outgoing", "server_side", "server_hostname", "owner", "session", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "_wrap_bio", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "_wrap_bio", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[6]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3; PySSLMemoryBIO *incoming; @@ -734,8 +855,8 @@ _ssl__SSLContext__wrap_bio(PySSLContext *self, PyObject *const *args, Py_ssize_t goto exit; } outgoing = (PySSLMemoryBIO *)args[1]; - server_side = _PyLong_AsInt(args[2]); - if (server_side == -1 && PyErr_Occurred()) { + server_side = PyObject_IsTrue(args[2]); + if (server_side < 0) { goto exit; } if (!noptargs) { @@ -853,8 +974,31 @@ static PyObject * _ssl__SSLContext_get_ca_certs(PySSLContext *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(binary_form), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"binary_form", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "get_ca_certs", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "get_ca_certs", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int binary_form = 0; @@ -884,14 +1028,13 @@ static PyObject * _ssl_MemoryBIO(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + PyTypeObject *base_tp = get_state_type(type)->PySSLMemoryBIO_Type; - if ((type == get_state_type(type)->PySSLMemoryBIO_Type || - type->tp_init == get_state_type(type)->PySSLMemoryBIO_Type->tp_init) && + if ((type == base_tp || type->tp_init == base_tp->tp_init) && !_PyArg_NoPositional("MemoryBIO", args)) { goto exit; } - if ((type == get_state_type(type)->PySSLMemoryBIO_Type || - type->tp_init == get_state_type(type)->PySSLMemoryBIO_Type->tp_init) && + if ((type == base_tp || type->tp_init == base_tp->tp_init) && !_PyArg_NoKeywords("MemoryBIO", kwargs)) { goto exit; } @@ -1090,37 +1233,6 @@ exit: return return_value; } -PyDoc_STRVAR(_ssl_RAND_pseudo_bytes__doc__, -"RAND_pseudo_bytes($module, n, /)\n" -"--\n" -"\n" -"Generate n pseudo-random bytes.\n" -"\n" -"Return a pair (bytes, is_cryptographic). is_cryptographic is True\n" -"if the bytes generated are cryptographically strong."); - -#define _SSL_RAND_PSEUDO_BYTES_METHODDEF \ - {"RAND_pseudo_bytes", (PyCFunction)_ssl_RAND_pseudo_bytes, METH_O, _ssl_RAND_pseudo_bytes__doc__}, - -static PyObject * -_ssl_RAND_pseudo_bytes_impl(PyObject *module, int n); - -static PyObject * -_ssl_RAND_pseudo_bytes(PyObject *module, PyObject *arg) -{ - PyObject *return_value = NULL; - int n; - - n = _PyLong_AsInt(arg); - if (n == -1 && PyErr_Occurred()) { - goto exit; - } - return_value = _ssl_RAND_pseudo_bytes_impl(module, n); - -exit: - return return_value; -} - PyDoc_STRVAR(_ssl_RAND_status__doc__, "RAND_status($module, /)\n" "--\n" @@ -1181,8 +1293,31 @@ static PyObject * _ssl_txt2obj(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(txt), &_Py_ID(name), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"txt", "name", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "txt2obj", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "txt2obj", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; const char *txt; @@ -1271,8 +1406,31 @@ static PyObject * _ssl_enum_certificates(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(store_name), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"store_name", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "enum_certificates", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "enum_certificates", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; const char *store_name; @@ -1324,8 +1482,31 @@ static PyObject * _ssl_enum_crls(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(store_name), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"store_name", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "enum_crls", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "enum_crls", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; const char *store_name; @@ -1361,4 +1542,4 @@ exit: #ifndef _SSL_ENUM_CRLS_METHODDEF #define _SSL_ENUM_CRLS_METHODDEF #endif /* !defined(_SSL_ENUM_CRLS_METHODDEF) */ -/*[clinic end generated code: output=2a488dd0cbc777df input=a9049054013a1b77]*/ +/*[clinic end generated code: output=4d9b81fa81f520f0 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_statisticsmodule.c.h b/Modules/clinic/_statisticsmodule.c.h index 03543e41..4dedadd2 100644 --- a/Modules/clinic/_statisticsmodule.c.h +++ b/Modules/clinic/_statisticsmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_statistics__normal_dist_inv_cdf__doc__, "_normal_dist_inv_cdf($module, p, mu, sigma, /)\n" "--\n" @@ -65,4 +71,4 @@ _statistics__normal_dist_inv_cdf(PyObject *module, PyObject *const *args, Py_ssi exit: return return_value; } -/*[clinic end generated code: output=b807a8243e7801e6 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=6899dc752cc6b457 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_struct.c.h b/Modules/clinic/_struct.c.h index 39b8ccb5..c3cf179e 100644 --- a/Modules/clinic/_struct.c.h +++ b/Modules/clinic/_struct.c.h @@ -2,7 +2,13 @@ preserve [clinic start generated code]*/ -PyDoc_STRVAR(Struct___init____doc__, +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + +PyDoc_STRVAR(Struct__doc__, "Struct(format)\n" "--\n" "\n" @@ -13,15 +19,38 @@ PyDoc_STRVAR(Struct___init____doc__, "\n" "See help(struct) for more on format strings."); -static int -Struct___init___impl(PyStructObject *self, PyObject *format); +static PyObject * +Struct_impl(PyTypeObject *type, PyObject *format); -static int -Struct___init__(PyObject *self, PyObject *args, PyObject *kwargs) +static PyObject * +Struct(PyTypeObject *type, PyObject *args, PyObject *kwargs) { - int return_value = -1; + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(format), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"format", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "Struct", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "Struct", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -32,7 +61,7 @@ Struct___init__(PyObject *self, PyObject *args, PyObject *kwargs) goto exit; } format = fastargs[0]; - return_value = Struct___init___impl((PyStructObject *)self, format); + return_value = Struct_impl(type, format); exit: return return_value; @@ -103,8 +132,31 @@ static PyObject * Struct_unpack_from(PyStructObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(buffer), &_Py_ID(offset), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"buffer", "offset", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "unpack_from", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "unpack_from", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; Py_buffer buffer = {NULL, NULL}; @@ -285,8 +337,31 @@ static PyObject * unpack_from(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(buffer), &_Py_ID(offset), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "buffer", "offset", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "unpack_from", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "unpack_from", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; PyStructObject *s_object = NULL; @@ -376,4 +451,4 @@ exit: return return_value; } -/*[clinic end generated code: output=2065c9b007be631c input=a9049054013a1b77]*/ +/*[clinic end generated code: output=f3d6e06f80368998 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_testclinic.c.h b/Modules/clinic/_testclinic.c.h index c97ac1c6..cc69f5c3 100644 --- a/Modules/clinic/_testclinic.c.h +++ b/Modules/clinic/_testclinic.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(test_empty_function__doc__, "test_empty_function($module, /)\n" "--\n" @@ -1248,8 +1254,31 @@ static PyObject * keywords(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), &_Py_ID(b), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"a", "b", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "keywords", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "keywords", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject *a; PyObject *b; @@ -1281,8 +1310,31 @@ static PyObject * keywords_kwonly(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), &_Py_ID(b), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"a", "b", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "keywords_kwonly", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "keywords_kwonly", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject *a; PyObject *b; @@ -1314,8 +1366,31 @@ static PyObject * keywords_opt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), &_Py_ID(b), &_Py_ID(c), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"a", "b", "c", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "keywords_opt", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "keywords_opt", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *a; @@ -1360,8 +1435,31 @@ static PyObject * keywords_opt_kwonly(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), &_Py_ID(b), &_Py_ID(c), &_Py_ID(d), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"a", "b", "c", "d", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "keywords_opt_kwonly", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "keywords_opt_kwonly", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *a; @@ -1417,8 +1515,31 @@ static PyObject * keywords_kwonly_opt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), &_Py_ID(b), &_Py_ID(c), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"a", "b", "c", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "keywords_kwonly_opt", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "keywords_kwonly_opt", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *a; @@ -1462,8 +1583,31 @@ static PyObject * posonly_keywords(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(b), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "b", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "posonly_keywords", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "posonly_keywords", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject *a; PyObject *b; @@ -1495,8 +1639,31 @@ static PyObject * posonly_kwonly(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(b), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "b", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "posonly_kwonly", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "posonly_kwonly", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject *a; PyObject *b; @@ -1529,8 +1696,31 @@ static PyObject * posonly_keywords_kwonly(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(b), &_Py_ID(c), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "b", "c", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "posonly_keywords_kwonly", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "posonly_keywords_kwonly", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; PyObject *a; PyObject *b; @@ -1565,8 +1755,31 @@ static PyObject * posonly_keywords_opt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(b), &_Py_ID(c), &_Py_ID(d), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "b", "c", "d", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "posonly_keywords_opt", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "posonly_keywords_opt", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; PyObject *a; @@ -1613,8 +1826,31 @@ static PyObject * posonly_opt_keywords_opt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(c), &_Py_ID(d), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "", "c", "d", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "posonly_opt_keywords_opt", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "posonly_opt_keywords_opt", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *a; @@ -1666,8 +1902,31 @@ static PyObject * posonly_kwonly_opt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(b), &_Py_ID(c), &_Py_ID(d), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "b", "c", "d", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "posonly_kwonly_opt", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "posonly_kwonly_opt", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; PyObject *a; @@ -1714,8 +1973,31 @@ static PyObject * posonly_opt_kwonly_opt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(c), &_Py_ID(d), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "", "c", "d", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "posonly_opt_kwonly_opt", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "posonly_opt_kwonly_opt", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *a; @@ -1767,8 +2049,31 @@ static PyObject * posonly_keywords_kwonly_opt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(b), &_Py_ID(c), &_Py_ID(d), &_Py_ID(e), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "b", "c", "d", "e", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "posonly_keywords_kwonly_opt", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "posonly_keywords_kwonly_opt", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3; PyObject *a; @@ -1819,8 +2124,31 @@ static PyObject * posonly_keywords_opt_kwonly_opt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(b), &_Py_ID(c), &_Py_ID(d), &_Py_ID(e), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "b", "c", "d", "e", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "posonly_keywords_opt_kwonly_opt", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "posonly_keywords_opt_kwonly_opt", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; PyObject *a; @@ -1880,8 +2208,31 @@ static PyObject * posonly_opt_keywords_opt_kwonly_opt(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(c), &_Py_ID(d), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "", "c", "d", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "posonly_opt_keywords_opt_kwonly_opt", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "posonly_opt_keywords_opt_kwonly_opt", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *a; @@ -1936,8 +2287,31 @@ static PyObject * keyword_only_parameter(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"a", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "keyword_only_parameter", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "keyword_only_parameter", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *a; @@ -1968,8 +2342,31 @@ static PyObject * posonly_vararg(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(b), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "b", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "posonly_vararg", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "posonly_vararg", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; PyObject *a; PyObject *b; @@ -2040,8 +2437,31 @@ static PyObject * vararg(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"a", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "vararg", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "vararg", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject *a; PyObject *__clinic_args = NULL; @@ -2075,8 +2495,31 @@ static PyObject * vararg_with_default(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), &_Py_ID(b), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"a", "b", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "vararg_with_default", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "vararg_with_default", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = Py_MIN(nargs, 1) + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *a; @@ -2119,8 +2562,31 @@ static PyObject * vararg_with_only_defaults(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(b), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"b", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "vararg_with_only_defaults", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "vararg_with_only_defaults", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = 0 + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *__clinic_args = NULL; @@ -2160,8 +2626,31 @@ static PyObject * gh_32092_oob(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(pos1), &_Py_ID(pos2), &_Py_ID(kw1), &_Py_ID(kw2), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"pos1", "pos2", "kw1", "kw2", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "gh_32092_oob", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "gh_32092_oob", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = Py_MIN(nargs, 2) + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; PyObject *pos1; @@ -2212,8 +2701,31 @@ static PyObject * gh_32092_kw_pass(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(pos), &_Py_ID(kw), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"pos", "kw", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "gh_32092_kw_pass", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "gh_32092_kw_pass", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = Py_MIN(nargs, 1) + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *pos; @@ -2305,4 +2817,262 @@ gh_99240_double_free(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=6b719efc1b8bd2c8 input=a9049054013a1b77]*/ + +PyDoc_STRVAR(clone_f1__doc__, +"clone_f1($module, /, path)\n" +"--\n" +"\n"); + +#define CLONE_F1_METHODDEF \ + {"clone_f1", _PyCFunction_CAST(clone_f1), METH_FASTCALL|METH_KEYWORDS, clone_f1__doc__}, + +static PyObject * +clone_f1_impl(PyObject *module, const char *path); + +static PyObject * +clone_f1(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"path", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "clone_f1", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + const char *path; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("clone_f1", "argument 'path'", "str", args[0]); + goto exit; + } + Py_ssize_t path_length; + path = PyUnicode_AsUTF8AndSize(args[0], &path_length); + if (path == NULL) { + goto exit; + } + if (strlen(path) != (size_t)path_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + return_value = clone_f1_impl(module, path); + +exit: + return return_value; +} + +PyDoc_STRVAR(clone_f2__doc__, +"clone_f2($module, /, path)\n" +"--\n" +"\n"); + +#define CLONE_F2_METHODDEF \ + {"clone_f2", _PyCFunction_CAST(clone_f2), METH_FASTCALL|METH_KEYWORDS, clone_f2__doc__}, + +static PyObject * +clone_f2_impl(PyObject *module, const char *path); + +static PyObject * +clone_f2(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"path", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "clone_f2", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + const char *path; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("clone_f2", "argument 'path'", "str", args[0]); + goto exit; + } + Py_ssize_t path_length; + path = PyUnicode_AsUTF8AndSize(args[0], &path_length); + if (path == NULL) { + goto exit; + } + if (strlen(path) != (size_t)path_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + return_value = clone_f2_impl(module, path); + +exit: + return return_value; +} + +PyDoc_STRVAR(clone_with_conv_f1__doc__, +"clone_with_conv_f1($module, /, path=None)\n" +"--\n" +"\n"); + +#define CLONE_WITH_CONV_F1_METHODDEF \ + {"clone_with_conv_f1", _PyCFunction_CAST(clone_with_conv_f1), METH_FASTCALL|METH_KEYWORDS, clone_with_conv_f1__doc__}, + +static PyObject * +clone_with_conv_f1_impl(PyObject *module, custom_t path); + +static PyObject * +clone_with_conv_f1(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"path", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "clone_with_conv_f1", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + custom_t path = { + .name = "clone_with_conv_f1", + }; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (!custom_converter(args[0], &path)) { + goto exit; + } +skip_optional_pos: + return_value = clone_with_conv_f1_impl(module, path); + +exit: + return return_value; +} + +PyDoc_STRVAR(clone_with_conv_f2__doc__, +"clone_with_conv_f2($module, /, path=None)\n" +"--\n" +"\n"); + +#define CLONE_WITH_CONV_F2_METHODDEF \ + {"clone_with_conv_f2", _PyCFunction_CAST(clone_with_conv_f2), METH_FASTCALL|METH_KEYWORDS, clone_with_conv_f2__doc__}, + +static PyObject * +clone_with_conv_f2_impl(PyObject *module, custom_t path); + +static PyObject * +clone_with_conv_f2(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"path", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "clone_with_conv_f2", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + custom_t path = { + .name = "clone_with_conv_f2", + }; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (!custom_converter(args[0], &path)) { + goto exit; + } +skip_optional_pos: + return_value = clone_with_conv_f2_impl(module, path); + +exit: + return return_value; +} +/*[clinic end generated code: output=f58202a6e5df2d16 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_testinternalcapi.c.h b/Modules/clinic/_testinternalcapi.c.h new file mode 100644 index 00000000..f5124125 --- /dev/null +++ b/Modules/clinic/_testinternalcapi.c.h @@ -0,0 +1,209 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + +PyDoc_STRVAR(_testinternalcapi_compiler_codegen__doc__, +"compiler_codegen($module, /, ast, filename, optimize, compile_mode=0)\n" +"--\n" +"\n" +"Apply compiler code generation to an AST."); + +#define _TESTINTERNALCAPI_COMPILER_CODEGEN_METHODDEF \ + {"compiler_codegen", _PyCFunction_CAST(_testinternalcapi_compiler_codegen), METH_FASTCALL|METH_KEYWORDS, _testinternalcapi_compiler_codegen__doc__}, + +static PyObject * +_testinternalcapi_compiler_codegen_impl(PyObject *module, PyObject *ast, + PyObject *filename, int optimize, + int compile_mode); + +static PyObject * +_testinternalcapi_compiler_codegen(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(ast), &_Py_ID(filename), &_Py_ID(optimize), &_Py_ID(compile_mode), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"ast", "filename", "optimize", "compile_mode", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "compiler_codegen", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[4]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3; + PyObject *ast; + PyObject *filename; + int optimize; + int compile_mode = 0; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 3, 4, 0, argsbuf); + if (!args) { + goto exit; + } + ast = args[0]; + filename = args[1]; + optimize = _PyLong_AsInt(args[2]); + if (optimize == -1 && PyErr_Occurred()) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + compile_mode = _PyLong_AsInt(args[3]); + if (compile_mode == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional_pos: + return_value = _testinternalcapi_compiler_codegen_impl(module, ast, filename, optimize, compile_mode); + +exit: + return return_value; +} + +PyDoc_STRVAR(_testinternalcapi_optimize_cfg__doc__, +"optimize_cfg($module, /, instructions, consts, nlocals)\n" +"--\n" +"\n" +"Apply compiler optimizations to an instruction list."); + +#define _TESTINTERNALCAPI_OPTIMIZE_CFG_METHODDEF \ + {"optimize_cfg", _PyCFunction_CAST(_testinternalcapi_optimize_cfg), METH_FASTCALL|METH_KEYWORDS, _testinternalcapi_optimize_cfg__doc__}, + +static PyObject * +_testinternalcapi_optimize_cfg_impl(PyObject *module, PyObject *instructions, + PyObject *consts, int nlocals); + +static PyObject * +_testinternalcapi_optimize_cfg(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(instructions), &_Py_ID(consts), &_Py_ID(nlocals), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"instructions", "consts", "nlocals", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "optimize_cfg", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[3]; + PyObject *instructions; + PyObject *consts; + int nlocals; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 3, 3, 0, argsbuf); + if (!args) { + goto exit; + } + instructions = args[0]; + consts = args[1]; + nlocals = _PyLong_AsInt(args[2]); + if (nlocals == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = _testinternalcapi_optimize_cfg_impl(module, instructions, consts, nlocals); + +exit: + return return_value; +} + +PyDoc_STRVAR(_testinternalcapi_assemble_code_object__doc__, +"assemble_code_object($module, /, filename, instructions, metadata)\n" +"--\n" +"\n" +"Create a code object for the given instructions."); + +#define _TESTINTERNALCAPI_ASSEMBLE_CODE_OBJECT_METHODDEF \ + {"assemble_code_object", _PyCFunction_CAST(_testinternalcapi_assemble_code_object), METH_FASTCALL|METH_KEYWORDS, _testinternalcapi_assemble_code_object__doc__}, + +static PyObject * +_testinternalcapi_assemble_code_object_impl(PyObject *module, + PyObject *filename, + PyObject *instructions, + PyObject *metadata); + +static PyObject * +_testinternalcapi_assemble_code_object(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(filename), &_Py_ID(instructions), &_Py_ID(metadata), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"filename", "instructions", "metadata", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "assemble_code_object", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[3]; + PyObject *filename; + PyObject *instructions; + PyObject *metadata; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 3, 3, 0, argsbuf); + if (!args) { + goto exit; + } + filename = args[0]; + instructions = args[1]; + metadata = args[2]; + return_value = _testinternalcapi_assemble_code_object_impl(module, filename, instructions, metadata); + +exit: + return return_value; +} +/*[clinic end generated code: output=2965f1578b986218 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_testmultiphase.c.h b/Modules/clinic/_testmultiphase.c.h index eabaea63..42ec7475 100644 --- a/Modules/clinic/_testmultiphase.c.h +++ b/Modules/clinic/_testmultiphase.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_testmultiphase_StateAccessType_get_defining_module__doc__, "get_defining_module($self, /)\n" "--\n" @@ -73,8 +79,31 @@ static PyObject * _testmultiphase_StateAccessType_increment_count_clinic(StateAccessTypeObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(n), &_Py_ID(twice), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"n", "twice", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "increment_count_clinic", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "increment_count_clinic", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int n = 1; @@ -133,4 +162,4 @@ _testmultiphase_StateAccessType_get_count(StateAccessTypeObject *self, PyTypeObj } return _testmultiphase_StateAccessType_get_count_impl(self, cls); } -/*[clinic end generated code: output=48739d81c3834078 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=52ea97ab2f03bb6d input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_tkinter.c.h b/Modules/clinic/_tkinter.c.h index 9103565e..96c6ee26 100644 --- a/Modules/clinic/_tkinter.c.h +++ b/Modules/clinic/_tkinter.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_tkinter_tkapp_eval__doc__, "eval($self, script, /)\n" "--\n" @@ -741,29 +747,29 @@ _tkinter_create(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (nargs < 4) { goto skip_optional; } - interactive = _PyLong_AsInt(args[3]); - if (interactive == -1 && PyErr_Occurred()) { + interactive = PyObject_IsTrue(args[3]); + if (interactive < 0) { goto exit; } if (nargs < 5) { goto skip_optional; } - wantobjects = _PyLong_AsInt(args[4]); - if (wantobjects == -1 && PyErr_Occurred()) { + wantobjects = PyObject_IsTrue(args[4]); + if (wantobjects < 0) { goto exit; } if (nargs < 6) { goto skip_optional; } - wantTk = _PyLong_AsInt(args[5]); - if (wantTk == -1 && PyErr_Occurred()) { + wantTk = PyObject_IsTrue(args[5]); + if (wantTk < 0) { goto exit; } if (nargs < 7) { goto skip_optional; } - sync = _PyLong_AsInt(args[6]); - if (sync == -1 && PyErr_Occurred()) { + sync = PyObject_IsTrue(args[6]); + if (sync < 0) { goto exit; } if (nargs < 8) { @@ -859,4 +865,4 @@ exit: #ifndef _TKINTER_TKAPP_DELETEFILEHANDLER_METHODDEF #define _TKINTER_TKAPP_DELETEFILEHANDLER_METHODDEF #endif /* !defined(_TKINTER_TKAPP_DELETEFILEHANDLER_METHODDEF) */ -/*[clinic end generated code: output=b0667ac928eb0c28 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=2a4e3bf8448604b5 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_tracemalloc.c.h b/Modules/clinic/_tracemalloc.c.h index 20c4d5d8..a89cd9aa 100644 --- a/Modules/clinic/_tracemalloc.c.h +++ b/Modules/clinic/_tracemalloc.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_tracemalloc_is_tracing__doc__, "is_tracing($module, /)\n" "--\n" @@ -212,4 +218,4 @@ _tracemalloc_reset_peak(PyObject *module, PyObject *Py_UNUSED(ignored)) { return _tracemalloc_reset_peak_impl(module); } -/*[clinic end generated code: output=2ae4fe05f1a340c9 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=44e3f8553aae2535 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_typingmodule.c.h b/Modules/clinic/_typingmodule.c.h index ea415e67..f980aa0d 100644 --- a/Modules/clinic/_typingmodule.c.h +++ b/Modules/clinic/_typingmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_typing__idfunc__doc__, "_idfunc($module, x, /)\n" "--\n" @@ -9,4 +15,4 @@ PyDoc_STRVAR(_typing__idfunc__doc__, #define _TYPING__IDFUNC_METHODDEF \ {"_idfunc", (PyCFunction)_typing__idfunc, METH_O, _typing__idfunc__doc__}, -/*[clinic end generated code: output=e7ea2a3cb7ab301a input=a9049054013a1b77]*/ +/*[clinic end generated code: output=97457fda45072c7d input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_weakref.c.h b/Modules/clinic/_weakref.c.h index 541cba75..48feb042 100644 --- a/Modules/clinic/_weakref.c.h +++ b/Modules/clinic/_weakref.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_weakref_getweakrefcount__doc__, "getweakrefcount($module, object, /)\n" "--\n" @@ -110,4 +116,4 @@ skip_optional: exit: return return_value; } -/*[clinic end generated code: output=f4be6b8177fbceb8 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=28265e89d583273d input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_winapi.c.h b/Modules/clinic/_winapi.c.h index 5364d9a2..1394a8fc 100644 --- a/Modules/clinic/_winapi.c.h +++ b/Modules/clinic/_winapi.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_winapi_Overlapped_GetOverlappedResult__doc__, "GetOverlappedResult($self, wait, /)\n" "--\n" @@ -106,8 +112,31 @@ static PyObject * _winapi_ConnectNamedPipe(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(handle), &_Py_ID(overlapped), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"handle", "overlapped", NULL}; - static _PyArg_Parser _parser = {"" F_HANDLE "|i:ConnectNamedPipe", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .format = "" F_HANDLE "|p:ConnectNamedPipe", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE HANDLE handle; int use_overlapped = 0; @@ -210,9 +239,7 @@ _winapi_CreateFileMapping(PyObject *module, PyObject *const *args, Py_ssize_t na exit: /* Cleanup for name */ - #if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *)name); - #endif /* USE_UNICODE_WCHAR_CACHE */ return return_value; } @@ -243,11 +270,7 @@ _winapi_CreateJunction(PyObject *module, PyObject *const *args, Py_ssize_t nargs _PyArg_BadArgument("CreateJunction", "argument 1", "str", args[0]); goto exit; } - #if USE_UNICODE_WCHAR_CACHE - src_path = _PyUnicode_AsUnicode(args[0]); - #else /* USE_UNICODE_WCHAR_CACHE */ src_path = PyUnicode_AsWideCharString(args[0], NULL); - #endif /* USE_UNICODE_WCHAR_CACHE */ if (src_path == NULL) { goto exit; } @@ -255,11 +278,7 @@ _winapi_CreateJunction(PyObject *module, PyObject *const *args, Py_ssize_t nargs _PyArg_BadArgument("CreateJunction", "argument 2", "str", args[1]); goto exit; } - #if USE_UNICODE_WCHAR_CACHE - dst_path = _PyUnicode_AsUnicode(args[1]); - #else /* USE_UNICODE_WCHAR_CACHE */ dst_path = PyUnicode_AsWideCharString(args[1], NULL); - #endif /* USE_UNICODE_WCHAR_CACHE */ if (dst_path == NULL) { goto exit; } @@ -267,13 +286,9 @@ _winapi_CreateJunction(PyObject *module, PyObject *const *args, Py_ssize_t nargs exit: /* Cleanup for src_path */ - #if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *)src_path); - #endif /* USE_UNICODE_WCHAR_CACHE */ /* Cleanup for dst_path */ - #if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *)dst_path); - #endif /* USE_UNICODE_WCHAR_CACHE */ return return_value; } @@ -412,13 +427,9 @@ _winapi_CreateProcess(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: /* Cleanup for application_name */ - #if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *)application_name); - #endif /* USE_UNICODE_WCHAR_CACHE */ /* Cleanup for current_directory */ - #if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *)current_directory); - #endif /* USE_UNICODE_WCHAR_CACHE */ return return_value; } @@ -793,9 +804,7 @@ _winapi_OpenFileMapping(PyObject *module, PyObject *const *args, Py_ssize_t narg exit: /* Cleanup for name */ - #if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *)name); - #endif /* USE_UNICODE_WCHAR_CACHE */ return return_value; } @@ -875,26 +884,52 @@ PyDoc_STRVAR(_winapi_LCMapStringEx__doc__, {"LCMapStringEx", _PyCFunction_CAST(_winapi_LCMapStringEx), METH_FASTCALL|METH_KEYWORDS, _winapi_LCMapStringEx__doc__}, static PyObject * -_winapi_LCMapStringEx_impl(PyObject *module, PyObject *locale, DWORD flags, +_winapi_LCMapStringEx_impl(PyObject *module, LPCWSTR locale, DWORD flags, PyObject *src); static PyObject * _winapi_LCMapStringEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(locale), &_Py_ID(flags), &_Py_ID(src), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"locale", "flags", "src", NULL}; - static _PyArg_Parser _parser = {"UkU:LCMapStringEx", _keywords, 0}; - PyObject *locale; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .format = "O&kU:LCMapStringEx", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + LPCWSTR locale = NULL; DWORD flags; PyObject *src; if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - &locale, &flags, &src)) { + _PyUnicode_WideCharString_Converter, &locale, &flags, &src)) { goto exit; } return_value = _winapi_LCMapStringEx_impl(module, locale, flags, src); exit: + /* Cleanup for locale */ + PyMem_Free((void *)locale); + return return_value; } @@ -914,8 +949,31 @@ static PyObject * _winapi_ReadFile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(handle), &_Py_ID(size), &_Py_ID(overlapped), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"handle", "size", "overlapped", NULL}; - static _PyArg_Parser _parser = {"" F_HANDLE "k|i:ReadFile", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .format = "" F_HANDLE "k|p:ReadFile", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE HANDLE handle; DWORD size; int use_overlapped = 0; @@ -1139,8 +1197,31 @@ static PyObject * _winapi_WriteFile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(handle), &_Py_ID(buffer), &_Py_ID(overlapped), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"handle", "buffer", "overlapped", NULL}; - static _PyArg_Parser _parser = {"" F_HANDLE "O|i:WriteFile", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .format = "" F_HANDLE "O|p:WriteFile", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE HANDLE handle; PyObject *buffer; int use_overlapped = 0; @@ -1188,8 +1269,31 @@ static PyObject * _winapi_GetFileType(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(handle), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"handle", NULL}; - static _PyArg_Parser _parser = {"" F_HANDLE ":GetFileType", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .format = "" F_HANDLE ":GetFileType", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE HANDLE handle; DWORD _return_value; @@ -1227,8 +1331,31 @@ static PyObject * _winapi__mimetypes_read_windows_registry(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(on_type_read), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"on_type_read", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "_mimetypes_read_windows_registry", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "_mimetypes_read_windows_registry", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *on_type_read; @@ -1242,4 +1369,114 @@ _winapi__mimetypes_read_windows_registry(PyObject *module, PyObject *const *args exit: return return_value; } -/*[clinic end generated code: output=9c08a7371fcf5dd4 input=a9049054013a1b77]*/ + +PyDoc_STRVAR(_winapi_NeedCurrentDirectoryForExePath__doc__, +"NeedCurrentDirectoryForExePath($module, exe_name, /)\n" +"--\n" +"\n"); + +#define _WINAPI_NEEDCURRENTDIRECTORYFOREXEPATH_METHODDEF \ + {"NeedCurrentDirectoryForExePath", (PyCFunction)_winapi_NeedCurrentDirectoryForExePath, METH_O, _winapi_NeedCurrentDirectoryForExePath__doc__}, + +static int +_winapi_NeedCurrentDirectoryForExePath_impl(PyObject *module, + LPCWSTR exe_name); + +static PyObject * +_winapi_NeedCurrentDirectoryForExePath(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + LPCWSTR exe_name = NULL; + int _return_value; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("NeedCurrentDirectoryForExePath", "argument", "str", arg); + goto exit; + } + exe_name = PyUnicode_AsWideCharString(arg, NULL); + if (exe_name == NULL) { + goto exit; + } + _return_value = _winapi_NeedCurrentDirectoryForExePath_impl(module, exe_name); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyBool_FromLong((long)_return_value); + +exit: + /* Cleanup for exe_name */ + PyMem_Free((void *)exe_name); + + return return_value; +} + +PyDoc_STRVAR(_winapi_CopyFile2__doc__, +"CopyFile2($module, /, existing_file_name, new_file_name, flags,\n" +" progress_routine=None)\n" +"--\n" +"\n" +"Copies a file from one name to a new name.\n" +"\n" +"This is implemented using the CopyFile2 API, which preserves all stat\n" +"and metadata information apart from security attributes.\n" +"\n" +"progress_routine is reserved for future use, but is currently not\n" +"implemented. Its value is ignored."); + +#define _WINAPI_COPYFILE2_METHODDEF \ + {"CopyFile2", _PyCFunction_CAST(_winapi_CopyFile2), METH_FASTCALL|METH_KEYWORDS, _winapi_CopyFile2__doc__}, + +static PyObject * +_winapi_CopyFile2_impl(PyObject *module, LPCWSTR existing_file_name, + LPCWSTR new_file_name, DWORD flags, + PyObject *progress_routine); + +static PyObject * +_winapi_CopyFile2(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(existing_file_name), &_Py_ID(new_file_name), &_Py_ID(flags), &_Py_ID(progress_routine), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"existing_file_name", "new_file_name", "flags", "progress_routine", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .format = "O&O&k|O:CopyFile2", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + LPCWSTR existing_file_name = NULL; + LPCWSTR new_file_name = NULL; + DWORD flags; + PyObject *progress_routine = Py_None; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + _PyUnicode_WideCharString_Converter, &existing_file_name, _PyUnicode_WideCharString_Converter, &new_file_name, &flags, &progress_routine)) { + goto exit; + } + return_value = _winapi_CopyFile2_impl(module, existing_file_name, new_file_name, flags, progress_routine); + +exit: + /* Cleanup for existing_file_name */ + PyMem_Free((void *)existing_file_name); + /* Cleanup for new_file_name */ + PyMem_Free((void *)new_file_name); + + return return_value; +} +/*[clinic end generated code: output=9d43ae4bdbe1126a input=a9049054013a1b77]*/ diff --git a/Modules/clinic/_zoneinfo.c.h b/Modules/clinic/_zoneinfo.c.h new file mode 100644 index 00000000..ae62865e --- /dev/null +++ b/Modules/clinic/_zoneinfo.c.h @@ -0,0 +1,375 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + +PyDoc_STRVAR(zoneinfo_ZoneInfo_from_file__doc__, +"from_file($type, file_obj, /, key=None)\n" +"--\n" +"\n" +"Create a ZoneInfo file from a file object."); + +#define ZONEINFO_ZONEINFO_FROM_FILE_METHODDEF \ + {"from_file", _PyCFunction_CAST(zoneinfo_ZoneInfo_from_file), METH_METHOD|METH_FASTCALL|METH_KEYWORDS|METH_CLASS, zoneinfo_ZoneInfo_from_file__doc__}, + +static PyObject * +zoneinfo_ZoneInfo_from_file_impl(PyTypeObject *type, PyTypeObject *cls, + PyObject *file_obj, PyObject *key); + +static PyObject * +zoneinfo_ZoneInfo_from_file(PyTypeObject *type, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(key), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"", "key", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "from_file", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + PyObject *file_obj; + PyObject *key = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); + if (!args) { + goto exit; + } + file_obj = args[0]; + if (!noptargs) { + goto skip_optional_pos; + } + key = args[1]; +skip_optional_pos: + return_value = zoneinfo_ZoneInfo_from_file_impl(type, cls, file_obj, key); + +exit: + return return_value; +} + +PyDoc_STRVAR(zoneinfo_ZoneInfo_no_cache__doc__, +"no_cache($type, /, key)\n" +"--\n" +"\n" +"Get a new instance of ZoneInfo, bypassing the cache."); + +#define ZONEINFO_ZONEINFO_NO_CACHE_METHODDEF \ + {"no_cache", _PyCFunction_CAST(zoneinfo_ZoneInfo_no_cache), METH_METHOD|METH_FASTCALL|METH_KEYWORDS|METH_CLASS, zoneinfo_ZoneInfo_no_cache__doc__}, + +static PyObject * +zoneinfo_ZoneInfo_no_cache_impl(PyTypeObject *type, PyTypeObject *cls, + PyObject *key); + +static PyObject * +zoneinfo_ZoneInfo_no_cache(PyTypeObject *type, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(key), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"key", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "no_cache", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject *key; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + key = args[0]; + return_value = zoneinfo_ZoneInfo_no_cache_impl(type, cls, key); + +exit: + return return_value; +} + +PyDoc_STRVAR(zoneinfo_ZoneInfo_clear_cache__doc__, +"clear_cache($type, /, *, only_keys=None)\n" +"--\n" +"\n" +"Clear the ZoneInfo cache."); + +#define ZONEINFO_ZONEINFO_CLEAR_CACHE_METHODDEF \ + {"clear_cache", _PyCFunction_CAST(zoneinfo_ZoneInfo_clear_cache), METH_METHOD|METH_FASTCALL|METH_KEYWORDS|METH_CLASS, zoneinfo_ZoneInfo_clear_cache__doc__}, + +static PyObject * +zoneinfo_ZoneInfo_clear_cache_impl(PyTypeObject *type, PyTypeObject *cls, + PyObject *only_keys); + +static PyObject * +zoneinfo_ZoneInfo_clear_cache(PyTypeObject *type, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(only_keys), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"only_keys", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "clear_cache", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *only_keys = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 0, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_kwonly; + } + only_keys = args[0]; +skip_optional_kwonly: + return_value = zoneinfo_ZoneInfo_clear_cache_impl(type, cls, only_keys); + +exit: + return return_value; +} + +PyDoc_STRVAR(zoneinfo_ZoneInfo_utcoffset__doc__, +"utcoffset($self, dt, /)\n" +"--\n" +"\n" +"Retrieve a timedelta representing the UTC offset in a zone at the given datetime."); + +#define ZONEINFO_ZONEINFO_UTCOFFSET_METHODDEF \ + {"utcoffset", _PyCFunction_CAST(zoneinfo_ZoneInfo_utcoffset), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, zoneinfo_ZoneInfo_utcoffset__doc__}, + +static PyObject * +zoneinfo_ZoneInfo_utcoffset_impl(PyObject *self, PyTypeObject *cls, + PyObject *dt); + +static PyObject * +zoneinfo_ZoneInfo_utcoffset(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + + static const char * const _keywords[] = {"", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "utcoffset", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject *dt; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + dt = args[0]; + return_value = zoneinfo_ZoneInfo_utcoffset_impl(self, cls, dt); + +exit: + return return_value; +} + +PyDoc_STRVAR(zoneinfo_ZoneInfo_dst__doc__, +"dst($self, dt, /)\n" +"--\n" +"\n" +"Retrieve a timedelta representing the amount of DST applied in a zone at the given datetime."); + +#define ZONEINFO_ZONEINFO_DST_METHODDEF \ + {"dst", _PyCFunction_CAST(zoneinfo_ZoneInfo_dst), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, zoneinfo_ZoneInfo_dst__doc__}, + +static PyObject * +zoneinfo_ZoneInfo_dst_impl(PyObject *self, PyTypeObject *cls, PyObject *dt); + +static PyObject * +zoneinfo_ZoneInfo_dst(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + + static const char * const _keywords[] = {"", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "dst", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject *dt; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + dt = args[0]; + return_value = zoneinfo_ZoneInfo_dst_impl(self, cls, dt); + +exit: + return return_value; +} + +PyDoc_STRVAR(zoneinfo_ZoneInfo_tzname__doc__, +"tzname($self, dt, /)\n" +"--\n" +"\n" +"Retrieve a string containing the abbreviation for the time zone that applies in a zone at a given datetime."); + +#define ZONEINFO_ZONEINFO_TZNAME_METHODDEF \ + {"tzname", _PyCFunction_CAST(zoneinfo_ZoneInfo_tzname), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, zoneinfo_ZoneInfo_tzname__doc__}, + +static PyObject * +zoneinfo_ZoneInfo_tzname_impl(PyObject *self, PyTypeObject *cls, + PyObject *dt); + +static PyObject * +zoneinfo_ZoneInfo_tzname(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + + static const char * const _keywords[] = {"", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "tzname", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject *dt; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + dt = args[0]; + return_value = zoneinfo_ZoneInfo_tzname_impl(self, cls, dt); + +exit: + return return_value; +} + +PyDoc_STRVAR(zoneinfo_ZoneInfo__unpickle__doc__, +"_unpickle($type, key, from_cache, /)\n" +"--\n" +"\n" +"Private method used in unpickling."); + +#define ZONEINFO_ZONEINFO__UNPICKLE_METHODDEF \ + {"_unpickle", _PyCFunction_CAST(zoneinfo_ZoneInfo__unpickle), METH_METHOD|METH_FASTCALL|METH_KEYWORDS|METH_CLASS, zoneinfo_ZoneInfo__unpickle__doc__}, + +static PyObject * +zoneinfo_ZoneInfo__unpickle_impl(PyTypeObject *type, PyTypeObject *cls, + PyObject *key, unsigned char from_cache); + +static PyObject * +zoneinfo_ZoneInfo__unpickle(PyTypeObject *type, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + + static const char * const _keywords[] = {"", "", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "_unpickle", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + PyObject *key; + unsigned char from_cache; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); + if (!args) { + goto exit; + } + key = args[0]; + { + unsigned long ival = PyLong_AsUnsignedLongMask(args[1]); + if (ival == (unsigned long)-1 && PyErr_Occurred()) { + goto exit; + } + else { + from_cache = (unsigned char) ival; + } + } + return_value = zoneinfo_ZoneInfo__unpickle_impl(type, cls, key, from_cache); + +exit: + return return_value; +} +/*[clinic end generated code: output=54051388dfc408af input=a9049054013a1b77]*/ diff --git a/Modules/clinic/arraymodule.c.h b/Modules/clinic/arraymodule.c.h index 6358ba2f..e68c3920 100644 --- a/Modules/clinic/arraymodule.c.h +++ b/Modules/clinic/arraymodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(array_array___copy____doc__, "__copy__($self, /)\n" "--\n" @@ -154,8 +160,19 @@ static PyObject * array_array_extend(arrayobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + static const char * const _keywords[] = {"", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "extend", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "extend", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *bb; @@ -297,8 +314,19 @@ static PyObject * array_array_fromfile(arrayobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + static const char * const _keywords[] = {"", "", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "fromfile", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "fromfile", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject *f; Py_ssize_t n; @@ -342,8 +370,19 @@ static PyObject * array_array_tofile(arrayobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + static const char * const _keywords[] = {"", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "tofile", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "tofile", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *f; @@ -584,8 +623,19 @@ static PyObject * array_array___reduce_ex__(arrayobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + static const char * const _keywords[] = {"", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "__reduce_ex__", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "__reduce_ex__", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *value; @@ -630,4 +680,4 @@ PyDoc_STRVAR(array_arrayiterator___setstate____doc__, #define ARRAY_ARRAYITERATOR___SETSTATE___METHODDEF \ {"__setstate__", (PyCFunction)array_arrayiterator___setstate__, METH_O, array_arrayiterator___setstate____doc__}, -/*[clinic end generated code: output=85a5fec90d9615b9 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=69bc1451f7bda234 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/audioop.c.h b/Modules/clinic/audioop.c.h index 43103855..1a7ccf8b 100644 --- a/Modules/clinic/audioop.c.h +++ b/Modules/clinic/audioop.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(audioop_getsample__doc__, "getsample($module, fragment, width, index, /)\n" "--\n" @@ -1309,4 +1315,4 @@ exit: return return_value; } -/*[clinic end generated code: output=a581c3893ef8ad75 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=9a7e36f1179f0223 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/binascii.c.h b/Modules/clinic/binascii.c.h index 2c766edd..63566dfb 100644 --- a/Modules/clinic/binascii.c.h +++ b/Modules/clinic/binascii.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(binascii_a2b_uu__doc__, "a2b_uu($module, data, /)\n" "--\n" @@ -49,8 +55,31 @@ static PyObject * binascii_b2a_uu(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(backtick), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "backtick", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "b2a_uu", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "b2a_uu", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; Py_buffer data = {NULL, NULL}; @@ -70,8 +99,8 @@ binascii_b2a_uu(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj if (!noptargs) { goto skip_optional_kwonly; } - backtick = _PyLong_AsInt(args[1]); - if (backtick == -1 && PyErr_Occurred()) { + backtick = PyObject_IsTrue(args[1]); + if (backtick < 0) { goto exit; } skip_optional_kwonly: @@ -106,8 +135,31 @@ static PyObject * binascii_a2b_base64(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(strict_mode), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "strict_mode", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "a2b_base64", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "a2b_base64", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; Py_buffer data = {NULL, NULL}; @@ -123,8 +175,8 @@ binascii_a2b_base64(PyObject *module, PyObject *const *args, Py_ssize_t nargs, P if (!noptargs) { goto skip_optional_kwonly; } - strict_mode = _PyLong_AsInt(args[1]); - if (strict_mode == -1 && PyErr_Occurred()) { + strict_mode = PyObject_IsTrue(args[1]); + if (strict_mode < 0) { goto exit; } skip_optional_kwonly: @@ -154,8 +206,31 @@ static PyObject * binascii_b2a_base64(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(newline), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "newline", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "b2a_base64", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "b2a_base64", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; Py_buffer data = {NULL, NULL}; @@ -175,8 +250,8 @@ binascii_b2a_base64(PyObject *module, PyObject *const *args, Py_ssize_t nargs, P if (!noptargs) { goto skip_optional_kwonly; } - newline = _PyLong_AsInt(args[1]); - if (newline == -1 && PyErr_Occurred()) { + newline = PyObject_IsTrue(args[1]); + if (newline < 0) { goto exit; } skip_optional_kwonly: @@ -322,8 +397,31 @@ static PyObject * binascii_b2a_hex(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(data), &_Py_ID(sep), &_Py_ID(bytes_per_sep), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"data", "sep", "bytes_per_sep", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "b2a_hex", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "b2a_hex", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; Py_buffer data = {NULL, NULL}; @@ -392,8 +490,31 @@ static PyObject * binascii_hexlify(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(data), &_Py_ID(sep), &_Py_ID(bytes_per_sep), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"data", "sep", "bytes_per_sep", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "hexlify", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "hexlify", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; Py_buffer data = {NULL, NULL}; @@ -519,8 +640,31 @@ static PyObject * binascii_a2b_qp(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(data), &_Py_ID(header), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"data", "header", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "a2b_qp", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "a2b_qp", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; Py_buffer data = {NULL, NULL}; @@ -536,8 +680,8 @@ binascii_a2b_qp(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj if (!noptargs) { goto skip_optional_pos; } - header = _PyLong_AsInt(args[1]); - if (header == -1 && PyErr_Occurred()) { + header = PyObject_IsTrue(args[1]); + if (header < 0) { goto exit; } skip_optional_pos: @@ -572,8 +716,31 @@ static PyObject * binascii_b2a_qp(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(data), &_Py_ID(quotetabs), &_Py_ID(istext), &_Py_ID(header), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"data", "quotetabs", "istext", "header", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "b2a_qp", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "b2a_qp", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; Py_buffer data = {NULL, NULL}; @@ -596,8 +763,8 @@ binascii_b2a_qp(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj goto skip_optional_pos; } if (args[1]) { - quotetabs = _PyLong_AsInt(args[1]); - if (quotetabs == -1 && PyErr_Occurred()) { + quotetabs = PyObject_IsTrue(args[1]); + if (quotetabs < 0) { goto exit; } if (!--noptargs) { @@ -605,16 +772,16 @@ binascii_b2a_qp(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj } } if (args[2]) { - istext = _PyLong_AsInt(args[2]); - if (istext == -1 && PyErr_Occurred()) { + istext = PyObject_IsTrue(args[2]); + if (istext < 0) { goto exit; } if (!--noptargs) { goto skip_optional_pos; } } - header = _PyLong_AsInt(args[3]); - if (header == -1 && PyErr_Occurred()) { + header = PyObject_IsTrue(args[3]); + if (header < 0) { goto exit; } skip_optional_pos: @@ -628,4 +795,4 @@ exit: return return_value; } -/*[clinic end generated code: output=ba9ed7b810b8762d input=a9049054013a1b77]*/ +/*[clinic end generated code: output=ab156917c9db79d2 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/cmathmodule.c.h b/Modules/clinic/cmathmodule.c.h index ab556922..941448e7 100644 --- a/Modules/clinic/cmathmodule.c.h +++ b/Modules/clinic/cmathmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(cmath_acos__doc__, "acos($module, z, /)\n" "--\n" @@ -638,7 +644,7 @@ PyDoc_STRVAR(cmath_log__doc__, "\n" "log(z[, base]) -> the logarithm of z to the given base.\n" "\n" -"If the base not specified, returns the natural logarithm (base e) of z."); +"If the base is not specified, returns the natural logarithm (base e) of z."); #define CMATH_LOG_METHODDEF \ {"log", _PyCFunction_CAST(cmath_log), METH_FASTCALL, cmath_log__doc__}, @@ -893,8 +899,31 @@ static PyObject * cmath_isclose(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), &_Py_ID(b), &_Py_ID(rel_tol), &_Py_ID(abs_tol), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"a", "b", "rel_tol", "abs_tol", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "isclose", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "isclose", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; Py_complex a; @@ -953,4 +982,4 @@ skip_optional_kwonly: exit: return return_value; } -/*[clinic end generated code: output=b8e445fcd2a3da65 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=87f609786ef270cd input=a9049054013a1b77]*/ diff --git a/Modules/clinic/fcntlmodule.c.h b/Modules/clinic/fcntlmodule.c.h index c41f088f..20eb50b0 100644 --- a/Modules/clinic/fcntlmodule.c.h +++ b/Modules/clinic/fcntlmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(fcntl_fcntl__doc__, "fcntl($module, fd, cmd, arg=0, /)\n" "--\n" @@ -243,4 +249,4 @@ skip_optional: exit: return return_value; } -/*[clinic end generated code: output=b8cb14ab35de4c6a input=a9049054013a1b77]*/ +/*[clinic end generated code: output=1db859412172dd53 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/gcmodule.c.h b/Modules/clinic/gcmodule.c.h index 5391b8be..2d18e2ee 100644 --- a/Modules/clinic/gcmodule.c.h +++ b/Modules/clinic/gcmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(gc_enable__doc__, "enable($module, /)\n" "--\n" @@ -88,8 +94,31 @@ static PyObject * gc_collect(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(generation), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"generation", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "collect", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "collect", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int generation = NUM_GENERATIONS - 1; @@ -242,8 +271,31 @@ static PyObject * gc_get_objects(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(generation), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"generation", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "get_objects", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "get_objects", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; Py_ssize_t generation = -1; @@ -372,4 +424,4 @@ gc_get_freeze_count(PyObject *module, PyObject *Py_UNUSED(ignored)) exit: return return_value; } -/*[clinic end generated code: output=71f7136d6e3f2323 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=66432ac0e17fd04f input=a9049054013a1b77]*/ diff --git a/Modules/clinic/grpmodule.c.h b/Modules/clinic/grpmodule.c.h index 3dd35e7e..4914bc9a 100644 --- a/Modules/clinic/grpmodule.c.h +++ b/Modules/clinic/grpmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(grp_getgrgid__doc__, "getgrgid($module, /, id)\n" "--\n" @@ -20,8 +26,31 @@ static PyObject * grp_getgrgid(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(id), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"id", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "getgrgid", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "getgrgid", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *id; @@ -54,8 +83,31 @@ static PyObject * grp_getgrnam(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(name), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"name", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "getgrnam", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "getgrnam", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *name; @@ -97,4 +149,4 @@ grp_getgrall(PyObject *module, PyObject *Py_UNUSED(ignored)) { return grp_getgrall_impl(module); } -/*[clinic end generated code: output=ba680465f71ed779 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=0916fdbcdeaf5d7d input=a9049054013a1b77]*/ diff --git a/Modules/clinic/itertoolsmodule.c.h b/Modules/clinic/itertoolsmodule.c.h index 81608ccc..32278bf7 100644 --- a/Modules/clinic/itertoolsmodule.c.h +++ b/Modules/clinic/itertoolsmodule.c.h @@ -2,6 +2,91 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + +PyDoc_STRVAR(batched_new__doc__, +"batched(iterable, n)\n" +"--\n" +"\n" +"Batch data into tuples of length n. The last batch may be shorter than n.\n" +"\n" +"Loops over the input iterable and accumulates data into tuples\n" +"up to size n. The input is consumed lazily, just enough to\n" +"fill a batch. The result is yielded as soon as a batch is full\n" +"or when the input iterable is exhausted.\n" +"\n" +" >>> for batch in batched(\'ABCDEFG\', 3):\n" +" ... print(batch)\n" +" ...\n" +" (\'A\', \'B\', \'C\')\n" +" (\'D\', \'E\', \'F\')\n" +" (\'G\',)"); + +static PyObject * +batched_new_impl(PyTypeObject *type, PyObject *iterable, Py_ssize_t n); + +static PyObject * +batched_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(iterable), &_Py_ID(n), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"iterable", "n", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "batched", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + PyObject * const *fastargs; + Py_ssize_t nargs = PyTuple_GET_SIZE(args); + PyObject *iterable; + Py_ssize_t n; + + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 2, 2, 0, argsbuf); + if (!fastargs) { + goto exit; + } + iterable = fastargs[0]; + { + Py_ssize_t ival = -1; + PyObject *iobj = _PyNumber_Index(fastargs[1]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + n = ival; + } + return_value = batched_new_impl(type, iterable, n); + +exit: + return return_value; +} + PyDoc_STRVAR(pairwise_new__doc__, "pairwise(iterable, /)\n" "--\n" @@ -17,10 +102,10 @@ static PyObject * pairwise_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + PyTypeObject *base_tp = clinic_state()->pairwise_type; PyObject *iterable; - if ((type == &pairwise_type || - type->tp_init == pairwise_type.tp_init) && + if ((type == base_tp || type->tp_init == base_tp->tp_init) && !_PyArg_NoKeywords("pairwise", kwargs)) { goto exit; } @@ -54,8 +139,31 @@ static PyObject * itertools_groupby(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(iterable), &_Py_ID(key), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"iterable", "key", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "groupby", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "groupby", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -87,19 +195,19 @@ static PyObject * itertools__grouper(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + PyTypeObject *base_tp = clinic_state()->_grouper_type; PyObject *parent; PyObject *tgtkey; - if ((type == &_grouper_type || - type->tp_init == _grouper_type.tp_init) && + if ((type == base_tp || type->tp_init == base_tp->tp_init) && !_PyArg_NoKeywords("_grouper", kwargs)) { goto exit; } if (!_PyArg_CheckPositional("_grouper", PyTuple_GET_SIZE(args), 2, 2)) { goto exit; } - if (!PyObject_TypeCheck(PyTuple_GET_ITEM(args, 0), &groupby_type)) { - _PyArg_BadArgument("_grouper", "argument 1", (&groupby_type)->tp_name, PyTuple_GET_ITEM(args, 0)); + if (!PyObject_TypeCheck(PyTuple_GET_ITEM(args, 0), clinic_state_by_cls()->groupby_type)) { + _PyArg_BadArgument("_grouper", "argument 1", (clinic_state_by_cls()->groupby_type)->tp_name, PyTuple_GET_ITEM(args, 0)); goto exit; } parent = PyTuple_GET_ITEM(args, 0); @@ -124,12 +232,12 @@ static PyObject * itertools_teedataobject(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + PyTypeObject *base_tp = clinic_state()->teedataobject_type; PyObject *it; PyObject *values; PyObject *next; - if ((type == &teedataobject_type || - type->tp_init == teedataobject_type.tp_init) && + if ((type == base_tp || type->tp_init == base_tp->tp_init) && !_PyArg_NoKeywords("teedataobject", kwargs)) { goto exit; } @@ -162,10 +270,10 @@ static PyObject * itertools__tee(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + PyTypeObject *base_tp = clinic_state()->tee_type; PyObject *iterable; - if ((type == &tee_type || - type->tp_init == tee_type.tp_init) && + if ((type == base_tp || type->tp_init == base_tp->tp_init) && !_PyArg_NoKeywords("_tee", kwargs)) { goto exit; } @@ -237,10 +345,10 @@ static PyObject * itertools_cycle(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + PyTypeObject *base_tp = clinic_state()->cycle_type; PyObject *iterable; - if ((type == &cycle_type || - type->tp_init == cycle_type.tp_init) && + if ((type == base_tp || type->tp_init == base_tp->tp_init) && !_PyArg_NoKeywords("cycle", kwargs)) { goto exit; } @@ -269,11 +377,11 @@ static PyObject * itertools_dropwhile(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + PyTypeObject *base_tp = clinic_state()->dropwhile_type; PyObject *func; PyObject *seq; - if ((type == &dropwhile_type || - type->tp_init == dropwhile_type.tp_init) && + if ((type == base_tp || type->tp_init == base_tp->tp_init) && !_PyArg_NoKeywords("dropwhile", kwargs)) { goto exit; } @@ -301,11 +409,11 @@ static PyObject * itertools_takewhile(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + PyTypeObject *base_tp = clinic_state()->takewhile_type; PyObject *func; PyObject *seq; - if ((type == &takewhile_type || - type->tp_init == takewhile_type.tp_init) && + if ((type == base_tp || type->tp_init == base_tp->tp_init) && !_PyArg_NoKeywords("takewhile", kwargs)) { goto exit; } @@ -333,11 +441,11 @@ static PyObject * itertools_starmap(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + PyTypeObject *base_tp = clinic_state()->starmap_type; PyObject *func; PyObject *seq; - if ((type == &starmap_type || - type->tp_init == starmap_type.tp_init) && + if ((type == base_tp || type->tp_init == base_tp->tp_init) && !_PyArg_NoKeywords("starmap", kwargs)) { goto exit; } @@ -377,8 +485,31 @@ static PyObject * itertools_combinations(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(iterable), &_Py_ID(r), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"iterable", "r", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "combinations", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "combinations", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -425,8 +556,31 @@ static PyObject * itertools_combinations_with_replacement(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(iterable), &_Py_ID(r), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"iterable", "r", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "combinations_with_replacement", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "combinations_with_replacement", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -472,8 +626,31 @@ static PyObject * itertools_permutations(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(iterable), &_Py_ID(r), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"iterable", "r", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "permutations", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "permutations", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -511,8 +688,31 @@ static PyObject * itertools_accumulate(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(iterable), &_Py_ID(func), &_Py_ID(initial), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"iterable", "func", "initial", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "accumulate", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "accumulate", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -563,8 +763,31 @@ static PyObject * itertools_compress(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(data), &_Py_ID(selectors), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"data", "selectors", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "compress", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "compress", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -598,11 +821,11 @@ static PyObject * itertools_filterfalse(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + PyTypeObject *base_tp = clinic_state()->filterfalse_type; PyObject *func; PyObject *seq; - if ((type == &filterfalse_type || - type->tp_init == filterfalse_type.tp_init) && + if ((type == base_tp || type->tp_init == base_tp->tp_init) && !_PyArg_NoKeywords("filterfalse", kwargs)) { goto exit; } @@ -638,8 +861,31 @@ static PyObject * itertools_count(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(start), &_Py_ID(step), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"start", "step", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "count", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "count", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -667,4 +913,4 @@ skip_optional_pos: exit: return return_value; } -/*[clinic end generated code: output=659251a811ff89ed input=a9049054013a1b77]*/ +/*[clinic end generated code: output=111cbd102c2a23c9 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/mathmodule.c.h b/Modules/clinic/mathmodule.c.h index efabbf97..c16c1b08 100644 --- a/Modules/clinic/mathmodule.c.h +++ b/Modules/clinic/mathmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(math_ceil__doc__, "ceil($module, x, /)\n" "--\n" @@ -180,49 +186,6 @@ exit: return return_value; } -PyDoc_STRVAR(math_log__doc__, -"log(x, [base=math.e])\n" -"Return the logarithm of x to the given base.\n" -"\n" -"If the base not specified, returns the natural logarithm (base e) of x."); - -#define MATH_LOG_METHODDEF \ - {"log", (PyCFunction)math_log, METH_VARARGS, math_log__doc__}, - -static PyObject * -math_log_impl(PyObject *module, PyObject *x, int group_right_1, - PyObject *base); - -static PyObject * -math_log(PyObject *module, PyObject *args) -{ - PyObject *return_value = NULL; - PyObject *x; - int group_right_1 = 0; - PyObject *base = NULL; - - switch (PyTuple_GET_SIZE(args)) { - case 1: - if (!PyArg_ParseTuple(args, "O:log", &x)) { - goto exit; - } - break; - case 2: - if (!PyArg_ParseTuple(args, "OO:log", &x, &base)) { - goto exit; - } - group_right_1 = 1; - break; - default: - PyErr_SetString(PyExc_TypeError, "math.log requires 1 to 2 arguments"); - goto exit; - } - return_value = math_log_impl(module, x, group_right_1, base); - -exit: - return return_value; -} - PyDoc_STRVAR(math_log2__doc__, "log2($module, x, /)\n" "--\n" @@ -327,6 +290,43 @@ exit: return return_value; } +PyDoc_STRVAR(math_sumprod__doc__, +"sumprod($module, p, q, /)\n" +"--\n" +"\n" +"Return the sum of products of values from two iterables p and q.\n" +"\n" +"Roughly equivalent to:\n" +"\n" +" sum(itertools.starmap(operator.mul, zip(p, q, strict=True)))\n" +"\n" +"For float and mixed int/float inputs, the intermediate products\n" +"and sums are computed with extended precision."); + +#define MATH_SUMPROD_METHODDEF \ + {"sumprod", _PyCFunction_CAST(math_sumprod), METH_FASTCALL, math_sumprod__doc__}, + +static PyObject * +math_sumprod_impl(PyObject *module, PyObject *p, PyObject *q); + +static PyObject * +math_sumprod(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *p; + PyObject *q; + + if (!_PyArg_CheckPositional("sumprod", nargs, 2, 2)) { + goto exit; + } + p = args[0]; + q = args[1]; + return_value = math_sumprod_impl(module, p, q); + +exit: + return return_value; +} + PyDoc_STRVAR(math_pow__doc__, "pow($module, x, y, /)\n" "--\n" @@ -578,8 +578,31 @@ static PyObject * math_isclose(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(a), &_Py_ID(b), &_Py_ID(rel_tol), &_Py_ID(abs_tol), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"a", "b", "rel_tol", "abs_tol", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "isclose", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "isclose", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; double a; @@ -673,8 +696,31 @@ static PyObject * math_prod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(start), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "start", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "prod", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "prod", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *iterable; @@ -780,25 +826,59 @@ exit: } PyDoc_STRVAR(math_nextafter__doc__, -"nextafter($module, x, y, /)\n" +"nextafter($module, x, y, /, *, steps=None)\n" "--\n" "\n" -"Return the next floating-point value after x towards y."); +"Return the floating-point value the given number of steps after x towards y.\n" +"\n" +"If steps is not specified or is None, it defaults to 1.\n" +"\n" +"Raises a TypeError, if x or y is not a double, or if steps is not an integer.\n" +"Raises ValueError if steps is negative."); #define MATH_NEXTAFTER_METHODDEF \ - {"nextafter", _PyCFunction_CAST(math_nextafter), METH_FASTCALL, math_nextafter__doc__}, + {"nextafter", _PyCFunction_CAST(math_nextafter), METH_FASTCALL|METH_KEYWORDS, math_nextafter__doc__}, static PyObject * -math_nextafter_impl(PyObject *module, double x, double y); +math_nextafter_impl(PyObject *module, double x, double y, PyObject *steps); static PyObject * -math_nextafter(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +math_nextafter(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(steps), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"", "", "steps", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "nextafter", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[3]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; double x; double y; + PyObject *steps = Py_None; - if (!_PyArg_CheckPositional("nextafter", nargs, 2, 2)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); + if (!args) { goto exit; } if (PyFloat_CheckExact(args[0])) { @@ -821,7 +901,12 @@ math_nextafter(PyObject *module, PyObject *const *args, Py_ssize_t nargs) goto exit; } } - return_value = math_nextafter_impl(module, x, y); + if (!noptargs) { + goto skip_optional_kwonly; + } + steps = args[2]; +skip_optional_kwonly: + return_value = math_nextafter_impl(module, x, y, steps); exit: return return_value; @@ -865,4 +950,4 @@ math_ulp(PyObject *module, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=965f99dabaa72165 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=91a0357265a2a553 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/md5module.c.h b/Modules/clinic/md5module.c.h index 999406ba..b4602104 100644 --- a/Modules/clinic/md5module.c.h +++ b/Modules/clinic/md5module.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(MD5Type_copy__doc__, "copy($self, /)\n" "--\n" @@ -85,8 +91,31 @@ static PyObject * _md5_md5(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "md5", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "md5", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *string = NULL; @@ -119,4 +148,4 @@ skip_optional_kwonly: exit: return return_value; } -/*[clinic end generated code: output=e5dac1237beb2788 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=b4924c9905cc9f34 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/overlapped.c.h b/Modules/clinic/overlapped.c.h index 6673cbfe..9d9f2cbf 100644 --- a/Modules/clinic/overlapped.c.h +++ b/Modules/clinic/overlapped.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_overlapped_CreateIoCompletionPort__doc__, "CreateIoCompletionPort($module, handle, port, key, concurrency, /)\n" "--\n" @@ -26,8 +32,22 @@ _overlapped_CreateIoCompletionPort(PyObject *module, PyObject *const *args, Py_s ULONG_PTR CompletionKey; DWORD NumberOfConcurrentThreads; - if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE""F_HANDLE""F_ULONG_PTR"k:CreateIoCompletionPort", - &FileHandle, &ExistingCompletionPort, &CompletionKey, &NumberOfConcurrentThreads)) { + if (!_PyArg_CheckPositional("CreateIoCompletionPort", nargs, 4, 4)) { + goto exit; + } + FileHandle = PyLong_AsVoidPtr(args[0]); + if (!FileHandle && PyErr_Occurred()) { + goto exit; + } + ExistingCompletionPort = PyLong_AsVoidPtr(args[1]); + if (!ExistingCompletionPort && PyErr_Occurred()) { + goto exit; + } + CompletionKey = (uintptr_t)PyLong_AsVoidPtr(args[2]); + if (!CompletionKey && PyErr_Occurred()) { + goto exit; + } + if (!_PyLong_UnsignedLong_Converter(args[3], &NumberOfConcurrentThreads)) { goto exit; } return_value = _overlapped_CreateIoCompletionPort_impl(module, FileHandle, ExistingCompletionPort, CompletionKey, NumberOfConcurrentThreads); @@ -59,8 +79,14 @@ _overlapped_GetQueuedCompletionStatus(PyObject *module, PyObject *const *args, P HANDLE CompletionPort; DWORD Milliseconds; - if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"k:GetQueuedCompletionStatus", - &CompletionPort, &Milliseconds)) { + if (!_PyArg_CheckPositional("GetQueuedCompletionStatus", nargs, 2, 2)) { + goto exit; + } + CompletionPort = PyLong_AsVoidPtr(args[0]); + if (!CompletionPort && PyErr_Occurred()) { + goto exit; + } + if (!_PyLong_UnsignedLong_Converter(args[1], &Milliseconds)) { goto exit; } return_value = _overlapped_GetQueuedCompletionStatus_impl(module, CompletionPort, Milliseconds); @@ -94,8 +120,22 @@ _overlapped_PostQueuedCompletionStatus(PyObject *module, PyObject *const *args, ULONG_PTR CompletionKey; OVERLAPPED *Overlapped; - if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"k"F_ULONG_PTR""F_POINTER":PostQueuedCompletionStatus", - &CompletionPort, &NumberOfBytes, &CompletionKey, &Overlapped)) { + if (!_PyArg_CheckPositional("PostQueuedCompletionStatus", nargs, 4, 4)) { + goto exit; + } + CompletionPort = PyLong_AsVoidPtr(args[0]); + if (!CompletionPort && PyErr_Occurred()) { + goto exit; + } + if (!_PyLong_UnsignedLong_Converter(args[1], &NumberOfBytes)) { + goto exit; + } + CompletionKey = (uintptr_t)PyLong_AsVoidPtr(args[2]); + if (!CompletionKey && PyErr_Occurred()) { + goto exit; + } + Overlapped = PyLong_AsVoidPtr(args[3]); + if (!Overlapped && PyErr_Occurred()) { goto exit; } return_value = _overlapped_PostQueuedCompletionStatus_impl(module, CompletionPort, NumberOfBytes, CompletionKey, Overlapped); @@ -129,8 +169,22 @@ _overlapped_RegisterWaitWithQueue(PyObject *module, PyObject *const *args, Py_ss OVERLAPPED *Overlapped; DWORD Milliseconds; - if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE""F_HANDLE""F_POINTER"k:RegisterWaitWithQueue", - &Object, &CompletionPort, &Overlapped, &Milliseconds)) { + if (!_PyArg_CheckPositional("RegisterWaitWithQueue", nargs, 4, 4)) { + goto exit; + } + Object = PyLong_AsVoidPtr(args[0]); + if (!Object && PyErr_Occurred()) { + goto exit; + } + CompletionPort = PyLong_AsVoidPtr(args[1]); + if (!CompletionPort && PyErr_Occurred()) { + goto exit; + } + Overlapped = PyLong_AsVoidPtr(args[2]); + if (!Overlapped && PyErr_Occurred()) { + goto exit; + } + if (!_PyLong_UnsignedLong_Converter(args[3], &Milliseconds)) { goto exit; } return_value = _overlapped_RegisterWaitWithQueue_impl(module, Object, CompletionPort, Overlapped, Milliseconds); @@ -157,7 +211,8 @@ _overlapped_UnregisterWait(PyObject *module, PyObject *arg) PyObject *return_value = NULL; HANDLE WaitHandle; - if (!PyArg_Parse(arg, ""F_HANDLE":UnregisterWait", &WaitHandle)) { + WaitHandle = PyLong_AsVoidPtr(arg); + if (!WaitHandle && PyErr_Occurred()) { goto exit; } return_value = _overlapped_UnregisterWait_impl(module, WaitHandle); @@ -186,8 +241,15 @@ _overlapped_UnregisterWaitEx(PyObject *module, PyObject *const *args, Py_ssize_t HANDLE WaitHandle; HANDLE Event; - if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE""F_HANDLE":UnregisterWaitEx", - &WaitHandle, &Event)) { + if (!_PyArg_CheckPositional("UnregisterWaitEx", nargs, 2, 2)) { + goto exit; + } + WaitHandle = PyLong_AsVoidPtr(args[0]); + if (!WaitHandle && PyErr_Occurred()) { + goto exit; + } + Event = PyLong_AsVoidPtr(args[1]); + if (!Event && PyErr_Occurred()) { goto exit; } return_value = _overlapped_UnregisterWaitEx_impl(module, WaitHandle, Event); @@ -222,17 +284,36 @@ _overlapped_CreateEvent(PyObject *module, PyObject *const *args, Py_ssize_t narg BOOL InitialState; const Py_UNICODE *Name = NULL; - if (!_PyArg_ParseStack(args, nargs, "OiiO&:CreateEvent", - &EventAttributes, &ManualReset, &InitialState, _PyUnicode_WideCharString_Opt_Converter, &Name)) { + if (!_PyArg_CheckPositional("CreateEvent", nargs, 4, 4)) { + goto exit; + } + EventAttributes = args[0]; + ManualReset = _PyLong_AsInt(args[1]); + if (ManualReset == -1 && PyErr_Occurred()) { + goto exit; + } + InitialState = _PyLong_AsInt(args[2]); + if (InitialState == -1 && PyErr_Occurred()) { + goto exit; + } + if (args[3] == Py_None) { + Name = NULL; + } + else if (PyUnicode_Check(args[3])) { + Name = PyUnicode_AsWideCharString(args[3], NULL); + if (Name == NULL) { + goto exit; + } + } + else { + _PyArg_BadArgument("CreateEvent", "argument 4", "str or None", args[3]); goto exit; } return_value = _overlapped_CreateEvent_impl(module, EventAttributes, ManualReset, InitialState, Name); exit: /* Cleanup for Name */ - #if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *)Name); - #endif /* USE_UNICODE_WCHAR_CACHE */ return return_value; } @@ -255,7 +336,8 @@ _overlapped_SetEvent(PyObject *module, PyObject *arg) PyObject *return_value = NULL; HANDLE Handle; - if (!PyArg_Parse(arg, ""F_HANDLE":SetEvent", &Handle)) { + Handle = PyLong_AsVoidPtr(arg); + if (!Handle && PyErr_Occurred()) { goto exit; } return_value = _overlapped_SetEvent_impl(module, Handle); @@ -282,7 +364,8 @@ _overlapped_ResetEvent(PyObject *module, PyObject *arg) PyObject *return_value = NULL; HANDLE Handle; - if (!PyArg_Parse(arg, ""F_HANDLE":ResetEvent", &Handle)) { + Handle = PyLong_AsVoidPtr(arg); + if (!Handle && PyErr_Occurred()) { goto exit; } return_value = _overlapped_ResetEvent_impl(module, Handle); @@ -312,8 +395,15 @@ _overlapped_BindLocal(PyObject *module, PyObject *const *args, Py_ssize_t nargs) HANDLE Socket; int Family; - if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"i:BindLocal", - &Socket, &Family)) { + if (!_PyArg_CheckPositional("BindLocal", nargs, 2, 2)) { + goto exit; + } + Socket = PyLong_AsVoidPtr(args[0]); + if (!Socket && PyErr_Occurred()) { + goto exit; + } + Family = _PyLong_AsInt(args[1]); + if (Family == -1 && PyErr_Occurred()) { goto exit; } return_value = _overlapped_BindLocal_impl(module, Socket, Family); @@ -340,7 +430,7 @@ _overlapped_FormatMessage(PyObject *module, PyObject *arg) PyObject *return_value = NULL; DWORD code; - if (!PyArg_Parse(arg, "k:FormatMessage", &code)) { + if (!_PyLong_UnsignedLong_Converter(arg, &code)) { goto exit; } return_value = _overlapped_FormatMessage_impl(module, code); @@ -362,14 +452,49 @@ static PyObject * _overlapped_Overlapped(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(event), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"event", NULL}; - static _PyArg_Parser _parser = {"|"F_HANDLE":Overlapped", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "Overlapped", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject * const *fastargs; + Py_ssize_t nargs = PyTuple_GET_SIZE(args); + Py_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 0; HANDLE event = INVALID_HANDLE_VALUE; - if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, - &event)) { + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 0, 1, 0, argsbuf); + if (!fastargs) { goto exit; } + if (!noptargs) { + goto skip_optional_pos; + } + event = PyLong_AsVoidPtr(fastargs[0]); + if (!event && PyErr_Occurred()) { + goto exit; + } +skip_optional_pos: return_value = _overlapped_Overlapped_impl(type, event); exit: @@ -415,10 +540,17 @@ _overlapped_Overlapped_getresult(OverlappedObject *self, PyObject *const *args, PyObject *return_value = NULL; BOOL wait = FALSE; - if (!_PyArg_ParseStack(args, nargs, "|i:getresult", - &wait)) { + if (!_PyArg_CheckPositional("getresult", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + wait = _PyLong_AsInt(args[0]); + if (wait == -1 && PyErr_Occurred()) { goto exit; } +skip_optional: return_value = _overlapped_Overlapped_getresult_impl(self, wait); exit: @@ -445,8 +577,14 @@ _overlapped_Overlapped_ReadFile(OverlappedObject *self, PyObject *const *args, P HANDLE handle; DWORD size; - if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"k:ReadFile", - &handle, &size)) { + if (!_PyArg_CheckPositional("ReadFile", nargs, 2, 2)) { + goto exit; + } + handle = PyLong_AsVoidPtr(args[0]); + if (!handle && PyErr_Occurred()) { + goto exit; + } + if (!_PyLong_UnsignedLong_Converter(args[1], &size)) { goto exit; } return_value = _overlapped_Overlapped_ReadFile_impl(self, handle, size); @@ -475,8 +613,18 @@ _overlapped_Overlapped_ReadFileInto(OverlappedObject *self, PyObject *const *arg HANDLE handle; Py_buffer bufobj = {NULL, NULL}; - if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"y*:ReadFileInto", - &handle, &bufobj)) { + if (!_PyArg_CheckPositional("ReadFileInto", nargs, 2, 2)) { + goto exit; + } + handle = PyLong_AsVoidPtr(args[0]); + if (!handle && PyErr_Occurred()) { + goto exit; + } + if (PyObject_GetBuffer(args[1], &bufobj, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&bufobj, 'C')) { + _PyArg_BadArgument("ReadFileInto", "argument 2", "contiguous buffer", args[1]); goto exit; } return_value = _overlapped_Overlapped_ReadFileInto_impl(self, handle, &bufobj); @@ -511,10 +659,23 @@ _overlapped_Overlapped_WSARecv(OverlappedObject *self, PyObject *const *args, Py DWORD size; DWORD flags = 0; - if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"k|k:WSARecv", - &handle, &size, &flags)) { + if (!_PyArg_CheckPositional("WSARecv", nargs, 2, 3)) { + goto exit; + } + handle = PyLong_AsVoidPtr(args[0]); + if (!handle && PyErr_Occurred()) { + goto exit; + } + if (!_PyLong_UnsignedLong_Converter(args[1], &size)) { goto exit; } + if (nargs < 3) { + goto skip_optional; + } + if (!_PyLong_UnsignedLong_Converter(args[2], &flags)) { + goto exit; + } +skip_optional: return_value = _overlapped_Overlapped_WSARecv_impl(self, handle, size, flags); exit: @@ -543,8 +704,21 @@ _overlapped_Overlapped_WSARecvInto(OverlappedObject *self, PyObject *const *args Py_buffer bufobj = {NULL, NULL}; DWORD flags; - if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"y*k:WSARecvInto", - &handle, &bufobj, &flags)) { + if (!_PyArg_CheckPositional("WSARecvInto", nargs, 3, 3)) { + goto exit; + } + handle = PyLong_AsVoidPtr(args[0]); + if (!handle && PyErr_Occurred()) { + goto exit; + } + if (PyObject_GetBuffer(args[1], &bufobj, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&bufobj, 'C')) { + _PyArg_BadArgument("WSARecvInto", "argument 2", "contiguous buffer", args[1]); + goto exit; + } + if (!_PyLong_UnsignedLong_Converter(args[2], &flags)) { goto exit; } return_value = _overlapped_Overlapped_WSARecvInto_impl(self, handle, &bufobj, flags); @@ -578,8 +752,18 @@ _overlapped_Overlapped_WriteFile(OverlappedObject *self, PyObject *const *args, HANDLE handle; Py_buffer bufobj = {NULL, NULL}; - if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"y*:WriteFile", - &handle, &bufobj)) { + if (!_PyArg_CheckPositional("WriteFile", nargs, 2, 2)) { + goto exit; + } + handle = PyLong_AsVoidPtr(args[0]); + if (!handle && PyErr_Occurred()) { + goto exit; + } + if (PyObject_GetBuffer(args[1], &bufobj, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&bufobj, 'C')) { + _PyArg_BadArgument("WriteFile", "argument 2", "contiguous buffer", args[1]); goto exit; } return_value = _overlapped_Overlapped_WriteFile_impl(self, handle, &bufobj); @@ -614,8 +798,21 @@ _overlapped_Overlapped_WSASend(OverlappedObject *self, PyObject *const *args, Py Py_buffer bufobj = {NULL, NULL}; DWORD flags; - if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"y*k:WSASend", - &handle, &bufobj, &flags)) { + if (!_PyArg_CheckPositional("WSASend", nargs, 3, 3)) { + goto exit; + } + handle = PyLong_AsVoidPtr(args[0]); + if (!handle && PyErr_Occurred()) { + goto exit; + } + if (PyObject_GetBuffer(args[1], &bufobj, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&bufobj, 'C')) { + _PyArg_BadArgument("WSASend", "argument 2", "contiguous buffer", args[1]); + goto exit; + } + if (!_PyLong_UnsignedLong_Converter(args[2], &flags)) { goto exit; } return_value = _overlapped_Overlapped_WSASend_impl(self, handle, &bufobj, flags); @@ -650,8 +847,15 @@ _overlapped_Overlapped_AcceptEx(OverlappedObject *self, PyObject *const *args, P HANDLE ListenSocket; HANDLE AcceptSocket; - if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE""F_HANDLE":AcceptEx", - &ListenSocket, &AcceptSocket)) { + if (!_PyArg_CheckPositional("AcceptEx", nargs, 2, 2)) { + goto exit; + } + ListenSocket = PyLong_AsVoidPtr(args[0]); + if (!ListenSocket && PyErr_Occurred()) { + goto exit; + } + AcceptSocket = PyLong_AsVoidPtr(args[1]); + if (!AcceptSocket && PyErr_Occurred()) { goto exit; } return_value = _overlapped_Overlapped_AcceptEx_impl(self, ListenSocket, AcceptSocket); @@ -683,10 +887,18 @@ _overlapped_Overlapped_ConnectEx(OverlappedObject *self, PyObject *const *args, HANDLE ConnectSocket; PyObject *AddressObj; - if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"O!:ConnectEx", - &ConnectSocket, &PyTuple_Type, &AddressObj)) { + if (!_PyArg_CheckPositional("ConnectEx", nargs, 2, 2)) { + goto exit; + } + ConnectSocket = PyLong_AsVoidPtr(args[0]); + if (!ConnectSocket && PyErr_Occurred()) { + goto exit; + } + if (!PyTuple_Check(args[1])) { + _PyArg_BadArgument("ConnectEx", "argument 2", "tuple", args[1]); goto exit; } + AddressObj = args[1]; return_value = _overlapped_Overlapped_ConnectEx_impl(self, ConnectSocket, AddressObj); exit: @@ -712,8 +924,14 @@ _overlapped_Overlapped_DisconnectEx(OverlappedObject *self, PyObject *const *arg HANDLE Socket; DWORD flags; - if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"k:DisconnectEx", - &Socket, &flags)) { + if (!_PyArg_CheckPositional("DisconnectEx", nargs, 2, 2)) { + goto exit; + } + Socket = PyLong_AsVoidPtr(args[0]); + if (!Socket && PyErr_Occurred()) { + goto exit; + } + if (!_PyLong_UnsignedLong_Converter(args[1], &flags)) { goto exit; } return_value = _overlapped_Overlapped_DisconnectEx_impl(self, Socket, flags); @@ -751,8 +969,30 @@ _overlapped_Overlapped_TransmitFile(OverlappedObject *self, PyObject *const *arg DWORD count_per_send; DWORD flags; - if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE""F_HANDLE"kkkkk:TransmitFile", - &Socket, &File, &offset, &offset_high, &count_to_write, &count_per_send, &flags)) { + if (!_PyArg_CheckPositional("TransmitFile", nargs, 7, 7)) { + goto exit; + } + Socket = PyLong_AsVoidPtr(args[0]); + if (!Socket && PyErr_Occurred()) { + goto exit; + } + File = PyLong_AsVoidPtr(args[1]); + if (!File && PyErr_Occurred()) { + goto exit; + } + if (!_PyLong_UnsignedLong_Converter(args[2], &offset)) { + goto exit; + } + if (!_PyLong_UnsignedLong_Converter(args[3], &offset_high)) { + goto exit; + } + if (!_PyLong_UnsignedLong_Converter(args[4], &count_to_write)) { + goto exit; + } + if (!_PyLong_UnsignedLong_Converter(args[5], &count_per_send)) { + goto exit; + } + if (!_PyLong_UnsignedLong_Converter(args[6], &flags)) { goto exit; } return_value = _overlapped_Overlapped_TransmitFile_impl(self, Socket, File, offset, offset_high, count_to_write, count_per_send, flags); @@ -780,7 +1020,8 @@ _overlapped_Overlapped_ConnectNamedPipe(OverlappedObject *self, PyObject *arg) PyObject *return_value = NULL; HANDLE Pipe; - if (!PyArg_Parse(arg, ""F_HANDLE":ConnectNamedPipe", &Pipe)) { + Pipe = PyLong_AsVoidPtr(arg); + if (!Pipe && PyErr_Occurred()) { goto exit; } return_value = _overlapped_Overlapped_ConnectNamedPipe_impl(self, Pipe); @@ -812,11 +1053,7 @@ _overlapped_Overlapped_ConnectPipe(OverlappedObject *self, PyObject *arg) _PyArg_BadArgument("ConnectPipe", "argument", "str", arg); goto exit; } - #if USE_UNICODE_WCHAR_CACHE - Address = _PyUnicode_AsUnicode(arg); - #else /* USE_UNICODE_WCHAR_CACHE */ Address = PyUnicode_AsWideCharString(arg, NULL); - #endif /* USE_UNICODE_WCHAR_CACHE */ if (Address == NULL) { goto exit; } @@ -824,9 +1061,7 @@ _overlapped_Overlapped_ConnectPipe(OverlappedObject *self, PyObject *arg) exit: /* Cleanup for Address */ - #if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *)Address); - #endif /* USE_UNICODE_WCHAR_CACHE */ return return_value; } @@ -851,10 +1086,18 @@ _overlapped_WSAConnect(PyObject *module, PyObject *const *args, Py_ssize_t nargs HANDLE ConnectSocket; PyObject *AddressObj; - if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"O!:WSAConnect", - &ConnectSocket, &PyTuple_Type, &AddressObj)) { + if (!_PyArg_CheckPositional("WSAConnect", nargs, 2, 2)) { goto exit; } + ConnectSocket = PyLong_AsVoidPtr(args[0]); + if (!ConnectSocket && PyErr_Occurred()) { + goto exit; + } + if (!PyTuple_Check(args[1])) { + _PyArg_BadArgument("WSAConnect", "argument 2", "tuple", args[1]); + goto exit; + } + AddressObj = args[1]; return_value = _overlapped_WSAConnect_impl(module, ConnectSocket, AddressObj); exit: @@ -884,10 +1127,28 @@ _overlapped_Overlapped_WSASendTo(OverlappedObject *self, PyObject *const *args, DWORD flags; PyObject *AddressObj; - if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"y*kO!:WSASendTo", - &handle, &bufobj, &flags, &PyTuple_Type, &AddressObj)) { + if (!_PyArg_CheckPositional("WSASendTo", nargs, 4, 4)) { + goto exit; + } + handle = PyLong_AsVoidPtr(args[0]); + if (!handle && PyErr_Occurred()) { + goto exit; + } + if (PyObject_GetBuffer(args[1], &bufobj, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&bufobj, 'C')) { + _PyArg_BadArgument("WSASendTo", "argument 2", "contiguous buffer", args[1]); + goto exit; + } + if (!_PyLong_UnsignedLong_Converter(args[2], &flags)) { + goto exit; + } + if (!PyTuple_Check(args[3])) { + _PyArg_BadArgument("WSASendTo", "argument 4", "tuple", args[3]); goto exit; } + AddressObj = args[3]; return_value = _overlapped_Overlapped_WSASendTo_impl(self, handle, &bufobj, flags, AddressObj); exit: @@ -921,10 +1182,23 @@ _overlapped_Overlapped_WSARecvFrom(OverlappedObject *self, PyObject *const *args DWORD size; DWORD flags = 0; - if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"k|k:WSARecvFrom", - &handle, &size, &flags)) { + if (!_PyArg_CheckPositional("WSARecvFrom", nargs, 2, 3)) { goto exit; } + handle = PyLong_AsVoidPtr(args[0]); + if (!handle && PyErr_Occurred()) { + goto exit; + } + if (!_PyLong_UnsignedLong_Converter(args[1], &size)) { + goto exit; + } + if (nargs < 3) { + goto skip_optional; + } + if (!_PyLong_UnsignedLong_Converter(args[2], &flags)) { + goto exit; + } +skip_optional: return_value = _overlapped_Overlapped_WSARecvFrom_impl(self, handle, size, flags); exit: @@ -954,10 +1228,30 @@ _overlapped_Overlapped_WSARecvFromInto(OverlappedObject *self, PyObject *const * DWORD size; DWORD flags = 0; - if (!_PyArg_ParseStack(args, nargs, ""F_HANDLE"y*k|k:WSARecvFromInto", - &handle, &bufobj, &size, &flags)) { + if (!_PyArg_CheckPositional("WSARecvFromInto", nargs, 3, 4)) { + goto exit; + } + handle = PyLong_AsVoidPtr(args[0]); + if (!handle && PyErr_Occurred()) { + goto exit; + } + if (PyObject_GetBuffer(args[1], &bufobj, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&bufobj, 'C')) { + _PyArg_BadArgument("WSARecvFromInto", "argument 2", "contiguous buffer", args[1]); + goto exit; + } + if (!_PyLong_UnsignedLong_Converter(args[2], &size)) { + goto exit; + } + if (nargs < 4) { + goto skip_optional; + } + if (!_PyLong_UnsignedLong_Converter(args[3], &flags)) { goto exit; } +skip_optional: return_value = _overlapped_Overlapped_WSARecvFromInto_impl(self, handle, &bufobj, size, flags); exit: @@ -968,4 +1262,4 @@ exit: return return_value; } -/*[clinic end generated code: output=5023f7748f0e073e input=a9049054013a1b77]*/ +/*[clinic end generated code: output=b2e89694b8de3d00 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/posixmodule.c.h b/Modules/clinic/posixmodule.c.h index b66cd857..5924c4ab 100644 --- a/Modules/clinic/posixmodule.c.h +++ b/Modules/clinic/posixmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(os_stat__doc__, "stat($module, /, path, *, dir_fd=None, follow_symlinks=True)\n" "--\n" @@ -37,8 +43,31 @@ static PyObject * os_stat(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(dir_fd), &_Py_ID(follow_symlinks), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", "dir_fd", "follow_symlinks", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "stat", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "stat", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; path_t path = PATH_T_INITIALIZE("stat", "path", 0, 1); @@ -96,8 +125,31 @@ static PyObject * os_lstat(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(dir_fd), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", "dir_fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "lstat", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "lstat", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; path_t path = PATH_T_INITIALIZE("lstat", "path", 0, 0); @@ -169,8 +221,31 @@ static PyObject * os_access(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 5 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(mode), &_Py_ID(dir_fd), &_Py_ID(effective_ids), &_Py_ID(follow_symlinks), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", "mode", "dir_fd", "effective_ids", "follow_symlinks", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "access", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "access", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; path_t path = PATH_T_INITIALIZE("access", "path", 0, 0); @@ -306,8 +381,31 @@ static PyObject * os_chdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "chdir", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "chdir", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; path_t path = PATH_T_INITIALIZE("chdir", "path", 0, PATH_HAVE_FCHDIR); @@ -348,8 +446,31 @@ static PyObject * os_fchdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(fd), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "fchdir", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "fchdir", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int fd; @@ -380,6 +501,9 @@ PyDoc_STRVAR(os_chmod__doc__, " If this functionality is unavailable, using it raises an exception.\n" " mode\n" " Operating-system mode bitfield.\n" +" Be careful when using number literals for *mode*. The conventional UNIX notation for\n" +" numeric modes uses an octal base, which needs to be indicated with a ``0o`` prefix in\n" +" Python.\n" " dir_fd\n" " If not None, it should be a file descriptor open to a directory,\n" " and path should be relative; path will then be relative to that\n" @@ -405,8 +529,31 @@ static PyObject * os_chmod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(mode), &_Py_ID(dir_fd), &_Py_ID(follow_symlinks), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", "mode", "dir_fd", "follow_symlinks", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "chmod", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "chmod", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; path_t path = PATH_T_INITIALIZE("chmod", "path", 0, PATH_HAVE_FCHMOD); @@ -458,6 +605,14 @@ PyDoc_STRVAR(os_fchmod__doc__, "\n" "Change the access permissions of the file given by file descriptor fd.\n" "\n" +" fd\n" +" The file descriptor of the file to be modified.\n" +" mode\n" +" Operating-system mode bitfield.\n" +" Be careful when using number literals for *mode*. The conventional UNIX notation for\n" +" numeric modes uses an octal base, which needs to be indicated with a ``0o`` prefix in\n" +" Python.\n" +"\n" "Equivalent to os.chmod(fd, mode)."); #define OS_FCHMOD_METHODDEF \ @@ -470,8 +625,31 @@ static PyObject * os_fchmod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(fd), &_Py_ID(mode), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"fd", "mode", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "fchmod", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "fchmod", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; int fd; int mode; @@ -517,8 +695,31 @@ static PyObject * os_lchmod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(mode), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", "mode", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "lchmod", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "lchmod", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; path_t path = PATH_T_INITIALIZE("lchmod", "path", 0, 0); int mode; @@ -570,8 +771,31 @@ static PyObject * os_chflags(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(flags), &_Py_ID(follow_symlinks), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", "flags", "follow_symlinks", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "chflags", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "chflags", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; path_t path = PATH_T_INITIALIZE("chflags", "path", 0, 0); @@ -630,8 +854,31 @@ static PyObject * os_lchflags(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(flags), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", "flags", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "lchflags", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "lchflags", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; path_t path = PATH_T_INITIALIZE("lchflags", "path", 0, 0); unsigned long flags; @@ -677,8 +924,31 @@ static PyObject * os_chroot(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "chroot", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "chroot", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; path_t path = PATH_T_INITIALIZE("chroot", "path", 0, 0); @@ -718,8 +988,31 @@ static PyObject * os_fsync(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(fd), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "fsync", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "fsync", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int fd; @@ -778,8 +1071,31 @@ static PyObject * os_fdatasync(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(fd), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "fdatasync", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "fdatasync", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int fd; @@ -841,8 +1157,31 @@ static PyObject * os_chown(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 5 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(uid), &_Py_ID(gid), &_Py_ID(dir_fd), &_Py_ID(follow_symlinks), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", "uid", "gid", "dir_fd", "follow_symlinks", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "chown", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "chown", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3; path_t path = PATH_T_INITIALIZE("chown", "path", 0, PATH_HAVE_FCHOWN); @@ -911,8 +1250,31 @@ static PyObject * os_fchown(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(fd), &_Py_ID(uid), &_Py_ID(gid), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"fd", "uid", "gid", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "fchown", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "fchown", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; int fd; uid_t uid; @@ -961,8 +1323,31 @@ static PyObject * os_lchown(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(uid), &_Py_ID(gid), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", "uid", "gid", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "lchown", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "lchown", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; path_t path = PATH_T_INITIALIZE("lchown", "path", 0, 0); uid_t uid; @@ -1058,8 +1443,31 @@ static PyObject * os_link(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 5 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(src), &_Py_ID(dst), &_Py_ID(src_dir_fd), &_Py_ID(dst_dir_fd), &_Py_ID(follow_symlinks), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", "follow_symlinks", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "link", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "link", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; path_t src = PATH_T_INITIALIZE("link", "src", 0, 0); @@ -1142,8 +1550,31 @@ static PyObject * os_listdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "listdir", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "listdir", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; path_t path = PATH_T_INITIALIZE("listdir", "path", 1, PATH_HAVE_FDOPENDIR); @@ -1170,6 +1601,184 @@ exit: #if defined(MS_WINDOWS) +PyDoc_STRVAR(os_listdrives__doc__, +"listdrives($module, /)\n" +"--\n" +"\n" +"Return a list containing the names of drives in the system.\n" +"\n" +"A drive name typically looks like \'C:\\\\\'."); + +#define OS_LISTDRIVES_METHODDEF \ + {"listdrives", (PyCFunction)os_listdrives, METH_NOARGS, os_listdrives__doc__}, + +static PyObject * +os_listdrives_impl(PyObject *module); + +static PyObject * +os_listdrives(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return os_listdrives_impl(module); +} + +#endif /* defined(MS_WINDOWS) */ + +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(os_listvolumes__doc__, +"listvolumes($module, /)\n" +"--\n" +"\n" +"Return a list containing the volumes in the system.\n" +"\n" +"Volumes are typically represented as a GUID path."); + +#define OS_LISTVOLUMES_METHODDEF \ + {"listvolumes", (PyCFunction)os_listvolumes, METH_NOARGS, os_listvolumes__doc__}, + +static PyObject * +os_listvolumes_impl(PyObject *module); + +static PyObject * +os_listvolumes(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return os_listvolumes_impl(module); +} + +#endif /* defined(MS_WINDOWS) */ + +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(os_listmounts__doc__, +"listmounts($module, /, volume)\n" +"--\n" +"\n" +"Return a list containing mount points for a particular volume.\n" +"\n" +"\'volume\' should be a GUID path as returned from os.listvolumes."); + +#define OS_LISTMOUNTS_METHODDEF \ + {"listmounts", _PyCFunction_CAST(os_listmounts), METH_FASTCALL|METH_KEYWORDS, os_listmounts__doc__}, + +static PyObject * +os_listmounts_impl(PyObject *module, path_t *volume); + +static PyObject * +os_listmounts(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(volume), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"volume", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "listmounts", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + path_t volume = PATH_T_INITIALIZE("listmounts", "volume", 0, 0); + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!path_converter(args[0], &volume)) { + goto exit; + } + return_value = os_listmounts_impl(module, &volume); + +exit: + /* Cleanup for volume */ + path_cleanup(&volume); + + return return_value; +} + +#endif /* defined(MS_WINDOWS) */ + +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(os__path_isdevdrive__doc__, +"_path_isdevdrive($module, /, path)\n" +"--\n" +"\n" +"Determines whether the specified path is on a Windows Dev Drive."); + +#define OS__PATH_ISDEVDRIVE_METHODDEF \ + {"_path_isdevdrive", _PyCFunction_CAST(os__path_isdevdrive), METH_FASTCALL|METH_KEYWORDS, os__path_isdevdrive__doc__}, + +static PyObject * +os__path_isdevdrive_impl(PyObject *module, path_t *path); + +static PyObject * +os__path_isdevdrive(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"path", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "_path_isdevdrive", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + path_t path = PATH_T_INITIALIZE("_path_isdevdrive", "path", 0, 0); + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!path_converter(args[0], &path)) { + goto exit; + } + return_value = os__path_isdevdrive_impl(module, &path); + +exit: + /* Cleanup for path */ + path_cleanup(&path); + + return return_value; +} + +#endif /* defined(MS_WINDOWS) */ + +#if defined(MS_WINDOWS) + PyDoc_STRVAR(os__getfullpathname__doc__, "_getfullpathname($module, path, /)\n" "--\n" @@ -1253,8 +1862,31 @@ static PyObject * os__getvolumepathname(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "_getvolumepathname", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "_getvolumepathname", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; path_t path = PATH_T_INITIALIZE("_getvolumepathname", "path", 0, 0); @@ -1294,8 +1926,31 @@ static PyObject * os__path_splitroot(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "_path_splitroot", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "_path_splitroot", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; path_t path = PATH_T_INITIALIZE("_path_splitroot", "path", 0, 0); @@ -1317,6 +1972,242 @@ exit: #endif /* defined(MS_WINDOWS) */ +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(os__path_isdir__doc__, +"_path_isdir($module, /, path)\n" +"--\n" +"\n" +"Return true if the pathname refers to an existing directory."); + +#define OS__PATH_ISDIR_METHODDEF \ + {"_path_isdir", _PyCFunction_CAST(os__path_isdir), METH_FASTCALL|METH_KEYWORDS, os__path_isdir__doc__}, + +static PyObject * +os__path_isdir_impl(PyObject *module, PyObject *path); + +static PyObject * +os__path_isdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"path", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "_path_isdir", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject *path; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + path = args[0]; + return_value = os__path_isdir_impl(module, path); + +exit: + return return_value; +} + +#endif /* defined(MS_WINDOWS) */ + +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(os__path_isfile__doc__, +"_path_isfile($module, /, path)\n" +"--\n" +"\n" +"Test whether a path is a regular file"); + +#define OS__PATH_ISFILE_METHODDEF \ + {"_path_isfile", _PyCFunction_CAST(os__path_isfile), METH_FASTCALL|METH_KEYWORDS, os__path_isfile__doc__}, + +static PyObject * +os__path_isfile_impl(PyObject *module, PyObject *path); + +static PyObject * +os__path_isfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"path", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "_path_isfile", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject *path; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + path = args[0]; + return_value = os__path_isfile_impl(module, path); + +exit: + return return_value; +} + +#endif /* defined(MS_WINDOWS) */ + +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(os__path_exists__doc__, +"_path_exists($module, /, path)\n" +"--\n" +"\n" +"Test whether a path exists. Returns False for broken symbolic links"); + +#define OS__PATH_EXISTS_METHODDEF \ + {"_path_exists", _PyCFunction_CAST(os__path_exists), METH_FASTCALL|METH_KEYWORDS, os__path_exists__doc__}, + +static PyObject * +os__path_exists_impl(PyObject *module, PyObject *path); + +static PyObject * +os__path_exists(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"path", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "_path_exists", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject *path; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + path = args[0]; + return_value = os__path_exists_impl(module, path); + +exit: + return return_value; +} + +#endif /* defined(MS_WINDOWS) */ + +#if defined(MS_WINDOWS) + +PyDoc_STRVAR(os__path_islink__doc__, +"_path_islink($module, /, path)\n" +"--\n" +"\n" +"Test whether a path is a symbolic link"); + +#define OS__PATH_ISLINK_METHODDEF \ + {"_path_islink", _PyCFunction_CAST(os__path_islink), METH_FASTCALL|METH_KEYWORDS, os__path_islink__doc__}, + +static PyObject * +os__path_islink_impl(PyObject *module, PyObject *path); + +static PyObject * +os__path_islink(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"path", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "_path_islink", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject *path; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + path = args[0]; + return_value = os__path_islink_impl(module, path); + +exit: + return return_value; +} + +#endif /* defined(MS_WINDOWS) */ + PyDoc_STRVAR(os__path_normpath__doc__, "_path_normpath($module, /, path)\n" "--\n" @@ -1333,8 +2224,31 @@ static PyObject * os__path_normpath(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "_path_normpath", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "_path_normpath", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *path; @@ -1373,8 +2287,31 @@ static PyObject * os_mkdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(mode), &_Py_ID(dir_fd), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", "mode", "dir_fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "mkdir", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "mkdir", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; path_t path = PATH_T_INITIALIZE("mkdir", "path", 0, 0); @@ -1467,8 +2404,31 @@ static PyObject * os_getpriority(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(which), &_Py_ID(who), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"which", "who", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "getpriority", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "getpriority", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; int which; int who; @@ -1511,8 +2471,31 @@ static PyObject * os_setpriority(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(which), &_Py_ID(who), &_Py_ID(priority), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"which", "who", "priority", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "setpriority", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "setpriority", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; int which; int who; @@ -1565,8 +2548,31 @@ static PyObject * os_rename(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(src), &_Py_ID(dst), &_Py_ID(src_dir_fd), &_Py_ID(dst_dir_fd), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "rename", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "rename", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; path_t src = PATH_T_INITIALIZE("rename", "src", 0, 0); @@ -1633,8 +2639,31 @@ static PyObject * os_replace(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(src), &_Py_ID(dst), &_Py_ID(src_dir_fd), &_Py_ID(dst_dir_fd), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"src", "dst", "src_dir_fd", "dst_dir_fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "replace", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "replace", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; path_t src = PATH_T_INITIALIZE("replace", "src", 0, 0); @@ -1699,8 +2728,31 @@ static PyObject * os_rmdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(dir_fd), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", "dir_fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "rmdir", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "rmdir", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; path_t path = PATH_T_INITIALIZE("rmdir", "path", 0, 0); @@ -1747,8 +2799,31 @@ static PyObject * os_system(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(command), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"command", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "system", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "system", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; const Py_UNICODE *command = NULL; long _return_value; @@ -1761,11 +2836,7 @@ os_system(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k _PyArg_BadArgument("system", "argument 'command'", "str", args[0]); goto exit; } - #if USE_UNICODE_WCHAR_CACHE - command = _PyUnicode_AsUnicode(args[0]); - #else /* USE_UNICODE_WCHAR_CACHE */ command = PyUnicode_AsWideCharString(args[0], NULL); - #endif /* USE_UNICODE_WCHAR_CACHE */ if (command == NULL) { goto exit; } @@ -1777,9 +2848,7 @@ os_system(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k exit: /* Cleanup for command */ - #if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *)command); - #endif /* USE_UNICODE_WCHAR_CACHE */ return return_value; } @@ -1804,8 +2873,31 @@ static PyObject * os_system(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(command), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"command", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "system", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "system", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *command = NULL; long _return_value; @@ -1885,8 +2977,31 @@ static PyObject * os_unlink(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(dir_fd), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", "dir_fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "unlink", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "unlink", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; path_t path = PATH_T_INITIALIZE("unlink", "path", 0, 0); @@ -1936,8 +3051,31 @@ static PyObject * os_remove(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(dir_fd), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", "dir_fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "remove", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "remove", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; path_t path = PATH_T_INITIALIZE("remove", "path", 0, 0); @@ -2031,8 +3169,31 @@ static PyObject * os_utime(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 5 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(times), &_Py_ID(ns), &_Py_ID(dir_fd), &_Py_ID(follow_symlinks), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", "times", "ns", "dir_fd", "follow_symlinks", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "utime", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "utime", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; path_t path = PATH_T_INITIALIZE("utime", "path", 0, PATH_UTIME_HAVE_FD); @@ -2105,8 +3266,31 @@ static PyObject * os__exit(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(status), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"status", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "_exit", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "_exit", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int status; @@ -2193,8 +3377,31 @@ static PyObject * os_execve(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(argv), &_Py_ID(env), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", "argv", "env", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "execve", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "execve", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; path_t path = PATH_T_INITIALIZE("execve", "path", 0, PATH_HAVE_FEXECVE); PyObject *argv; @@ -2265,8 +3472,31 @@ static PyObject * os_posix_spawn(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 7 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(file_actions), &_Py_ID(setpgroup), &_Py_ID(resetids), &_Py_ID(setsid), &_Py_ID(setsigmask), &_Py_ID(setsigdef), &_Py_ID(scheduler), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "", "", "file_actions", "setpgroup", "resetids", "setsid", "setsigmask", "setsigdef", "scheduler", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "posix_spawn", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "posix_spawn", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[10]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3; path_t path = PATH_T_INITIALIZE("posix_spawn", "path", 0, 0); @@ -2305,8 +3535,8 @@ os_posix_spawn(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje } } if (args[5]) { - resetids = _PyLong_AsInt(args[5]); - if (resetids == -1 && PyErr_Occurred()) { + resetids = PyObject_IsTrue(args[5]); + if (resetids < 0) { goto exit; } if (!--noptargs) { @@ -2314,8 +3544,8 @@ os_posix_spawn(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje } } if (args[6]) { - setsid = _PyLong_AsInt(args[6]); - if (setsid == -1 && PyErr_Occurred()) { + setsid = PyObject_IsTrue(args[6]); + if (setsid < 0) { goto exit; } if (!--noptargs) { @@ -2392,8 +3622,31 @@ static PyObject * os_posix_spawnp(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 7 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(file_actions), &_Py_ID(setpgroup), &_Py_ID(resetids), &_Py_ID(setsid), &_Py_ID(setsigmask), &_Py_ID(setsigdef), &_Py_ID(scheduler), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "", "", "file_actions", "setpgroup", "resetids", "setsid", "setsigmask", "setsigdef", "scheduler", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "posix_spawnp", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "posix_spawnp", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[10]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3; path_t path = PATH_T_INITIALIZE("posix_spawnp", "path", 0, 0); @@ -2432,8 +3685,8 @@ os_posix_spawnp(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj } } if (args[5]) { - resetids = _PyLong_AsInt(args[5]); - if (resetids == -1 && PyErr_Occurred()) { + resetids = PyObject_IsTrue(args[5]); + if (resetids < 0) { goto exit; } if (!--noptargs) { @@ -2441,8 +3694,8 @@ os_posix_spawnp(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj } } if (args[6]) { - setsid = _PyLong_AsInt(args[6]); - if (setsid == -1 && PyErr_Occurred()) { + setsid = PyObject_IsTrue(args[6]); + if (setsid < 0) { goto exit; } if (!--noptargs) { @@ -2612,8 +3865,31 @@ static PyObject * os_register_at_fork(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(before), &_Py_ID(after_in_child), &_Py_ID(after_in_parent), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"before", "after_in_child", "after_in_parent", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "register_at_fork", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "register_at_fork", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *before = NULL; @@ -2715,8 +3991,31 @@ static PyObject * os_sched_get_priority_max(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(policy), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"policy", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "sched_get_priority_max", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "sched_get_priority_max", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int policy; @@ -2754,8 +4053,31 @@ static PyObject * os_sched_get_priority_min(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(policy), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"policy", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "sched_get_priority_min", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "sched_get_priority_min", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int policy; @@ -2826,8 +4148,31 @@ static PyObject * os_sched_param(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(sched_priority), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"sched_priority", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "sched_param", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "sched_param", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -3495,8 +4840,31 @@ static PyObject * os_getpgid(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(pid), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"pid", NULL}; - static _PyArg_Parser _parser = {"" _Py_PARSE_PID ":getpgid", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .format = "" _Py_PARSE_PID ":getpgid", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE pid_t pid; if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, @@ -3956,8 +5324,31 @@ static PyObject * os_wait3(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(options), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"options", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "wait3", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "wait3", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int options; @@ -3998,8 +5389,31 @@ static PyObject * os_wait4(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(pid), &_Py_ID(options), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"pid", "options", NULL}; - static _PyArg_Parser _parser = {"" _Py_PARSE_PID "i:wait4", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .format = "" _Py_PARSE_PID "i:wait4", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE pid_t pid; int options; @@ -4182,8 +5596,31 @@ static PyObject * os_pidfd_open(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(pid), &_Py_ID(flags), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"pid", "flags", NULL}; - static _PyArg_Parser _parser = {"" _Py_PARSE_PID "|O&:pidfd_open", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .format = "" _Py_PARSE_PID "|O&:pidfd_open", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE pid_t pid; unsigned int flags = 0; @@ -4199,6 +5636,147 @@ exit: #endif /* (defined(__linux__) && defined(__NR_pidfd_open)) */ +#if defined(HAVE_SETNS) + +PyDoc_STRVAR(os_setns__doc__, +"setns($module, /, fd, nstype=0)\n" +"--\n" +"\n" +"Move the calling thread into different namespaces.\n" +"\n" +" fd\n" +" A file descriptor to a namespace.\n" +" nstype\n" +" Type of namespace."); + +#define OS_SETNS_METHODDEF \ + {"setns", _PyCFunction_CAST(os_setns), METH_FASTCALL|METH_KEYWORDS, os_setns__doc__}, + +static PyObject * +os_setns_impl(PyObject *module, int fd, int nstype); + +static PyObject * +os_setns(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(fd), &_Py_ID(nstype), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"fd", "nstype", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "setns", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + int fd; + int nstype = 0; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); + if (!args) { + goto exit; + } + if (!_PyLong_FileDescriptor_Converter(args[0], &fd)) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + nstype = _PyLong_AsInt(args[1]); + if (nstype == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional_pos: + return_value = os_setns_impl(module, fd, nstype); + +exit: + return return_value; +} + +#endif /* defined(HAVE_SETNS) */ + +#if defined(HAVE_UNSHARE) + +PyDoc_STRVAR(os_unshare__doc__, +"unshare($module, /, flags)\n" +"--\n" +"\n" +"Disassociate parts of a process (or thread) execution context.\n" +"\n" +" flags\n" +" Namespaces to be unshared."); + +#define OS_UNSHARE_METHODDEF \ + {"unshare", _PyCFunction_CAST(os_unshare), METH_FASTCALL|METH_KEYWORDS, os_unshare__doc__}, + +static PyObject * +os_unshare_impl(PyObject *module, int flags); + +static PyObject * +os_unshare(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(flags), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"flags", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "unshare", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + int flags; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + flags = _PyLong_AsInt(args[0]); + if (flags == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = os_unshare_impl(module, flags); + +exit: + return return_value; +} + +#endif /* defined(HAVE_UNSHARE) */ + #if (defined(HAVE_READLINK) || defined(MS_WINDOWS)) PyDoc_STRVAR(os_readlink__doc__, @@ -4223,8 +5801,31 @@ static PyObject * os_readlink(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(dir_fd), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", "dir_fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "readlink", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "readlink", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; path_t path = PATH_T_INITIALIZE("readlink", "path", 0, 0); @@ -4284,8 +5885,31 @@ static PyObject * os_symlink(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(src), &_Py_ID(dst), &_Py_ID(target_is_directory), &_Py_ID(dir_fd), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"src", "dst", "target_is_directory", "dir_fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "symlink", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "symlink", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; path_t src = PATH_T_INITIALIZE("symlink", "src", 0, 0); @@ -4534,8 +6158,31 @@ static PyObject * os_open(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(flags), &_Py_ID(mode), &_Py_ID(dir_fd), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", "flags", "mode", "dir_fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "open", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "open", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; path_t path = PATH_T_INITIALIZE("open", "path", 0, 0); @@ -4604,8 +6251,31 @@ static PyObject * os_close(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(fd), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "close", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "close", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int fd; @@ -4710,8 +6380,31 @@ static PyObject * os_dup2(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(fd), &_Py_ID(fd2), &_Py_ID(inheritable), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"fd", "fd2", "inheritable", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "dup2", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "dup2", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; int fd; @@ -4803,13 +6496,22 @@ exit: #endif /* defined(HAVE_LOCKF) */ PyDoc_STRVAR(os_lseek__doc__, -"lseek($module, fd, position, how, /)\n" +"lseek($module, fd, position, whence, /)\n" "--\n" "\n" "Set the position of a file descriptor. Return the new position.\n" "\n" -"Return the new cursor position in number of bytes\n" -"relative to the beginning of the file."); +" fd\n" +" An open file descriptor, as returned by os.open().\n" +" position\n" +" Position, interpreted relative to \'whence\'.\n" +" whence\n" +" The relative position to seek from. Valid values are:\n" +" - SEEK_SET: seek from the start of the file.\n" +" - SEEK_CUR: seek from the current file position.\n" +" - SEEK_END: seek from the end of the file.\n" +"\n" +"The return value is the number of bytes relative to the beginning of the file."); #define OS_LSEEK_METHODDEF \ {"lseek", _PyCFunction_CAST(os_lseek), METH_FASTCALL, os_lseek__doc__}, @@ -5139,8 +6841,31 @@ static PyObject * os_sendfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 7 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(out_fd), &_Py_ID(in_fd), &_Py_ID(offset), &_Py_ID(count), &_Py_ID(headers), &_Py_ID(trailers), &_Py_ID(flags), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"out_fd", "in_fd", "offset", "count", "headers", "trailers", "flags", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "sendfile", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "sendfile", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[7]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 4; int out_fd; @@ -5218,8 +6943,31 @@ static PyObject * os_sendfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 7 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(out_fd), &_Py_ID(in_fd), &_Py_ID(offset), &_Py_ID(count), &_Py_ID(headers), &_Py_ID(trailers), &_Py_ID(flags), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"out_fd", "in_fd", "offset", "count", "headers", "trailers", "flags", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "sendfile", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "sendfile", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[7]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 4; int out_fd; @@ -5304,8 +7052,31 @@ static PyObject * os_sendfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(out_fd), &_Py_ID(in_fd), &_Py_ID(offset), &_Py_ID(count), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"out_fd", "in_fd", "offset", "count", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "sendfile", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "sendfile", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; int out_fd; int in_fd; @@ -5409,8 +7180,31 @@ static PyObject * os_fstat(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(fd), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "fstat", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "fstat", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int fd; @@ -5738,8 +7532,31 @@ static PyObject * os_copy_file_range(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 5 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(src), &_Py_ID(dst), &_Py_ID(count), &_Py_ID(offset_src), &_Py_ID(offset_dst), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"src", "dst", "count", "offset_src", "offset_dst", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "copy_file_range", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "copy_file_range", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3; int src; @@ -5829,8 +7646,31 @@ static PyObject * os_splice(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 6 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(src), &_Py_ID(dst), &_Py_ID(count), &_Py_ID(offset_src), &_Py_ID(offset_dst), &_Py_ID(flags), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"src", "dst", "count", "offset_src", "offset_dst", "flags", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "splice", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "splice", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[6]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3; int src; @@ -5914,8 +7754,31 @@ static PyObject * os_mkfifo(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(mode), &_Py_ID(dir_fd), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", "mode", "dir_fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "mkfifo", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "mkfifo", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; path_t path = PATH_T_INITIALIZE("mkfifo", "path", 0, 0); @@ -5991,8 +7854,31 @@ static PyObject * os_mknod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(mode), &_Py_ID(device), &_Py_ID(dir_fd), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", "mode", "device", "dir_fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "mknod", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "mknod", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; path_t path = PATH_T_INITIALIZE("mknod", "path", 0, 0); @@ -6223,8 +8109,31 @@ static PyObject * os_truncate(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(length), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", "length", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "truncate", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "truncate", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; path_t path = PATH_T_INITIALIZE("truncate", "path", 0, PATH_HAVE_FTRUNCATE); Py_off_t length; @@ -6601,8 +8510,31 @@ static PyObject * os_WIFCONTINUED(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(status), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"status", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "WIFCONTINUED", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "WIFCONTINUED", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int status; int _return_value; @@ -6645,8 +8577,31 @@ static PyObject * os_WIFSTOPPED(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(status), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"status", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "WIFSTOPPED", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "WIFSTOPPED", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int status; int _return_value; @@ -6689,8 +8644,31 @@ static PyObject * os_WIFSIGNALED(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(status), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"status", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "WIFSIGNALED", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "WIFSIGNALED", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int status; int _return_value; @@ -6733,8 +8711,31 @@ static PyObject * os_WIFEXITED(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(status), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"status", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "WIFEXITED", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "WIFEXITED", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int status; int _return_value; @@ -6777,8 +8778,31 @@ static PyObject * os_WEXITSTATUS(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(status), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"status", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "WEXITSTATUS", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "WEXITSTATUS", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int status; int _return_value; @@ -6821,8 +8845,31 @@ static PyObject * os_WTERMSIG(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(status), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"status", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "WTERMSIG", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "WTERMSIG", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int status; int _return_value; @@ -6865,8 +8912,31 @@ static PyObject * os_WSTOPSIG(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(status), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"status", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "WSTOPSIG", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "WSTOPSIG", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int status; int _return_value; @@ -6947,8 +9017,31 @@ static PyObject * os_statvfs(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "statvfs", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "statvfs", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; path_t path = PATH_T_INITIALIZE("statvfs", "path", 0, PATH_HAVE_FSTATVFS); @@ -6988,8 +9081,31 @@ static PyObject * os__getdiskusage(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "_getdiskusage", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "_getdiskusage", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; path_t path = PATH_T_INITIALIZE("_getdiskusage", "path", 0, 0); @@ -7078,8 +9194,31 @@ static PyObject * os_pathconf(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(name), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", "name", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "pathconf", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "pathconf", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; path_t path = PATH_T_INITIALIZE("pathconf", "path", 0, PATH_HAVE_FPATHCONF); int name; @@ -7244,8 +9383,31 @@ static PyObject * os_startfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 5 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(filepath), &_Py_ID(operation), &_Py_ID(arguments), &_Py_ID(cwd), &_Py_ID(show_cmd), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"filepath", "operation", "arguments", "cwd", "show_cmd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "startfile", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "startfile", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; path_t filepath = PATH_T_INITIALIZE("startfile", "filepath", 0, 0); @@ -7269,11 +9431,7 @@ os_startfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject _PyArg_BadArgument("startfile", "argument 'operation'", "str", args[1]); goto exit; } - #if USE_UNICODE_WCHAR_CACHE - operation = _PyUnicode_AsUnicode(args[1]); - #else /* USE_UNICODE_WCHAR_CACHE */ operation = PyUnicode_AsWideCharString(args[1], NULL); - #endif /* USE_UNICODE_WCHAR_CACHE */ if (operation == NULL) { goto exit; } @@ -7286,11 +9444,7 @@ os_startfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject _PyArg_BadArgument("startfile", "argument 'arguments'", "str", args[2]); goto exit; } - #if USE_UNICODE_WCHAR_CACHE - arguments = _PyUnicode_AsUnicode(args[2]); - #else /* USE_UNICODE_WCHAR_CACHE */ arguments = PyUnicode_AsWideCharString(args[2], NULL); - #endif /* USE_UNICODE_WCHAR_CACHE */ if (arguments == NULL) { goto exit; } @@ -7317,13 +9471,9 @@ exit: /* Cleanup for filepath */ path_cleanup(&filepath); /* Cleanup for operation */ - #if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *)operation); - #endif /* USE_UNICODE_WCHAR_CACHE */ /* Cleanup for arguments */ - #if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *)arguments); - #endif /* USE_UNICODE_WCHAR_CACHE */ /* Cleanup for cwd */ path_cleanup(&cwd); @@ -7377,8 +9527,31 @@ static PyObject * os_device_encoding(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(fd), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "device_encoding", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "device_encoding", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int fd; @@ -7548,8 +9721,31 @@ static PyObject * os_getxattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(attribute), &_Py_ID(follow_symlinks), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", "attribute", "follow_symlinks", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "getxattr", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "getxattr", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; path_t path = PATH_T_INITIALIZE("getxattr", "path", 0, 1); @@ -7612,8 +9808,31 @@ static PyObject * os_setxattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 5 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(attribute), &_Py_ID(value), &_Py_ID(flags), &_Py_ID(follow_symlinks), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", "attribute", "value", "flags", "follow_symlinks", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "setxattr", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "setxattr", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3; path_t path = PATH_T_INITIALIZE("setxattr", "path", 0, 1); @@ -7701,8 +9920,31 @@ static PyObject * os_removexattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(attribute), &_Py_ID(follow_symlinks), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", "attribute", "follow_symlinks", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "removexattr", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "removexattr", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; path_t path = PATH_T_INITIALIZE("removexattr", "path", 0, 1); @@ -7764,8 +10006,31 @@ static PyObject * os_listxattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), &_Py_ID(follow_symlinks), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", "follow_symlinks", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "listxattr", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "listxattr", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; path_t path = PATH_T_INITIALIZE("listxattr", "path", 1, 1); @@ -7859,8 +10124,31 @@ static PyObject * os_memfd_create(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(name), &_Py_ID(flags), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"name", "flags", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "memfd_create", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "memfd_create", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *name = NULL; @@ -7910,8 +10198,31 @@ static PyObject * os_eventfd(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(initval), &_Py_ID(flags), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"initval", "flags", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "eventfd", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "eventfd", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; unsigned int initval; @@ -7958,8 +10269,31 @@ static PyObject * os_eventfd_read(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(fd), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "eventfd_read", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "eventfd_read", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int fd; @@ -7996,8 +10330,31 @@ static PyObject * os_eventfd_write(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(fd), &_Py_ID(value), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"fd", "value", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "eventfd_write", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "eventfd_write", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; int fd; unsigned long long value; @@ -8232,8 +10589,6 @@ exit: #endif /* defined(MS_WINDOWS) */ -#if !defined(MS_WINDOWS) - PyDoc_STRVAR(os_get_blocking__doc__, "get_blocking($module, fd, /)\n" "--\n" @@ -8269,10 +10624,6 @@ exit: return return_value; } -#endif /* !defined(MS_WINDOWS) */ - -#if !defined(MS_WINDOWS) - PyDoc_STRVAR(os_set_blocking__doc__, "set_blocking($module, fd, blocking, /)\n" "--\n" @@ -8302,8 +10653,8 @@ os_set_blocking(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (fd == -1 && PyErr_Occurred()) { goto exit; } - blocking = _PyLong_AsInt(args[1]); - if (blocking == -1 && PyErr_Occurred()) { + blocking = PyObject_IsTrue(args[1]); + if (blocking < 0) { goto exit; } return_value = os_set_blocking_impl(module, fd, blocking); @@ -8312,8 +10663,6 @@ exit: return return_value; } -#endif /* !defined(MS_WINDOWS) */ - PyDoc_STRVAR(os_DirEntry_is_symlink__doc__, "is_symlink($self, /)\n" "--\n" @@ -8346,6 +10695,38 @@ exit: return return_value; } +PyDoc_STRVAR(os_DirEntry_is_junction__doc__, +"is_junction($self, /)\n" +"--\n" +"\n" +"Return True if the entry is a junction; cached per entry."); + +#define OS_DIRENTRY_IS_JUNCTION_METHODDEF \ + {"is_junction", _PyCFunction_CAST(os_DirEntry_is_junction), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, os_DirEntry_is_junction__doc__}, + +static int +os_DirEntry_is_junction_impl(DirEntry *self, PyTypeObject *defining_class); + +static PyObject * +os_DirEntry_is_junction(DirEntry *self, PyTypeObject *defining_class, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + int _return_value; + + if (nargs) { + PyErr_SetString(PyExc_TypeError, "is_junction() takes no arguments"); + goto exit; + } + _return_value = os_DirEntry_is_junction_impl(self, defining_class); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyBool_FromLong((long)_return_value); + +exit: + return return_value; +} + PyDoc_STRVAR(os_DirEntry_stat__doc__, "stat($self, /, *, follow_symlinks=True)\n" "--\n" @@ -8363,8 +10744,31 @@ static PyObject * os_DirEntry_stat(DirEntry *self, PyTypeObject *defining_class, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(follow_symlinks), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"follow_symlinks", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "stat", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "stat", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int follow_symlinks = 1; @@ -8404,8 +10808,31 @@ static PyObject * os_DirEntry_is_dir(DirEntry *self, PyTypeObject *defining_class, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(follow_symlinks), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"follow_symlinks", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "is_dir", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "is_dir", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int follow_symlinks = 1; @@ -8450,8 +10877,31 @@ static PyObject * os_DirEntry_is_file(DirEntry *self, PyTypeObject *defining_class, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(follow_symlinks), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"follow_symlinks", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "is_file", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "is_file", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int follow_symlinks = 1; @@ -8537,8 +10987,31 @@ static PyObject * os_scandir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "scandir", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "scandir", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; path_t path = PATH_T_INITIALIZE("scandir", "path", 1, PATH_HAVE_FDOPENDIR); @@ -8583,8 +11056,31 @@ static PyObject * os_fspath(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "fspath", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "fspath", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *path; @@ -8617,8 +11113,31 @@ static PyObject * os_getrandom(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(size), &_Py_ID(flags), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"size", "flags", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "getrandom", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "getrandom", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; Py_ssize_t size; @@ -8656,7 +11175,7 @@ exit: #endif /* defined(HAVE_GETRANDOM_SYSCALL) */ -#if defined(MS_WINDOWS) +#if (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_APP) || defined(MS_WINDOWS_SYSTEM)) PyDoc_STRVAR(os__add_dll_directory__doc__, "_add_dll_directory($module, /, path)\n" @@ -8681,8 +11200,31 @@ static PyObject * os__add_dll_directory(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(path), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"path", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "_add_dll_directory", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "_add_dll_directory", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; path_t path = PATH_T_INITIALIZE("_add_dll_directory", "path", 0, 0); @@ -8702,9 +11244,9 @@ exit: return return_value; } -#endif /* defined(MS_WINDOWS) */ +#endif /* (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_APP) || defined(MS_WINDOWS_SYSTEM)) */ -#if defined(MS_WINDOWS) +#if (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_APP) || defined(MS_WINDOWS_SYSTEM)) PyDoc_STRVAR(os__remove_dll_directory__doc__, "_remove_dll_directory($module, /, cookie)\n" @@ -8726,8 +11268,31 @@ static PyObject * os__remove_dll_directory(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(cookie), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"cookie", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "_remove_dll_directory", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "_remove_dll_directory", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *cookie; @@ -8742,7 +11307,7 @@ exit: return return_value; } -#endif /* defined(MS_WINDOWS) */ +#endif /* (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_APP) || defined(MS_WINDOWS_SYSTEM)) */ #if (defined(WIFEXITED) || defined(MS_WINDOWS)) @@ -8774,8 +11339,31 @@ static PyObject * os_waitstatus_to_exitcode(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(status), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"status", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "waitstatus_to_exitcode", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "waitstatus_to_exitcode", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *status_obj; @@ -8852,6 +11440,22 @@ exit: #define OS_LINK_METHODDEF #endif /* !defined(OS_LINK_METHODDEF) */ +#ifndef OS_LISTDRIVES_METHODDEF + #define OS_LISTDRIVES_METHODDEF +#endif /* !defined(OS_LISTDRIVES_METHODDEF) */ + +#ifndef OS_LISTVOLUMES_METHODDEF + #define OS_LISTVOLUMES_METHODDEF +#endif /* !defined(OS_LISTVOLUMES_METHODDEF) */ + +#ifndef OS_LISTMOUNTS_METHODDEF + #define OS_LISTMOUNTS_METHODDEF +#endif /* !defined(OS_LISTMOUNTS_METHODDEF) */ + +#ifndef OS__PATH_ISDEVDRIVE_METHODDEF + #define OS__PATH_ISDEVDRIVE_METHODDEF +#endif /* !defined(OS__PATH_ISDEVDRIVE_METHODDEF) */ + #ifndef OS__GETFULLPATHNAME_METHODDEF #define OS__GETFULLPATHNAME_METHODDEF #endif /* !defined(OS__GETFULLPATHNAME_METHODDEF) */ @@ -8868,6 +11472,22 @@ exit: #define OS__PATH_SPLITROOT_METHODDEF #endif /* !defined(OS__PATH_SPLITROOT_METHODDEF) */ +#ifndef OS__PATH_ISDIR_METHODDEF + #define OS__PATH_ISDIR_METHODDEF +#endif /* !defined(OS__PATH_ISDIR_METHODDEF) */ + +#ifndef OS__PATH_ISFILE_METHODDEF + #define OS__PATH_ISFILE_METHODDEF +#endif /* !defined(OS__PATH_ISFILE_METHODDEF) */ + +#ifndef OS__PATH_EXISTS_METHODDEF + #define OS__PATH_EXISTS_METHODDEF +#endif /* !defined(OS__PATH_EXISTS_METHODDEF) */ + +#ifndef OS__PATH_ISLINK_METHODDEF + #define OS__PATH_ISLINK_METHODDEF +#endif /* !defined(OS__PATH_ISLINK_METHODDEF) */ + #ifndef OS_NICE_METHODDEF #define OS_NICE_METHODDEF #endif /* !defined(OS_NICE_METHODDEF) */ @@ -9096,6 +11716,14 @@ exit: #define OS_PIDFD_OPEN_METHODDEF #endif /* !defined(OS_PIDFD_OPEN_METHODDEF) */ +#ifndef OS_SETNS_METHODDEF + #define OS_SETNS_METHODDEF +#endif /* !defined(OS_SETNS_METHODDEF) */ + +#ifndef OS_UNSHARE_METHODDEF + #define OS_UNSHARE_METHODDEF +#endif /* !defined(OS_UNSHARE_METHODDEF) */ + #ifndef OS_READLINK_METHODDEF #define OS_READLINK_METHODDEF #endif /* !defined(OS_READLINK_METHODDEF) */ @@ -9356,14 +11984,6 @@ exit: #define OS_SET_HANDLE_INHERITABLE_METHODDEF #endif /* !defined(OS_SET_HANDLE_INHERITABLE_METHODDEF) */ -#ifndef OS_GET_BLOCKING_METHODDEF - #define OS_GET_BLOCKING_METHODDEF -#endif /* !defined(OS_GET_BLOCKING_METHODDEF) */ - -#ifndef OS_SET_BLOCKING_METHODDEF - #define OS_SET_BLOCKING_METHODDEF -#endif /* !defined(OS_SET_BLOCKING_METHODDEF) */ - #ifndef OS_GETRANDOM_METHODDEF #define OS_GETRANDOM_METHODDEF #endif /* !defined(OS_GETRANDOM_METHODDEF) */ @@ -9379,4 +11999,4 @@ exit: #ifndef OS_WAITSTATUS_TO_EXITCODE_METHODDEF #define OS_WAITSTATUS_TO_EXITCODE_METHODDEF #endif /* !defined(OS_WAITSTATUS_TO_EXITCODE_METHODDEF) */ -/*[clinic end generated code: output=8dd784bf1e41b881 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=6646be70849f971f input=a9049054013a1b77]*/ diff --git a/Modules/clinic/pwdmodule.c.h b/Modules/clinic/pwdmodule.c.h index cb830624..f2603eaf 100644 --- a/Modules/clinic/pwdmodule.c.h +++ b/Modules/clinic/pwdmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(pwd_getpwuid__doc__, "getpwuid($module, uidobj, /)\n" "--\n" @@ -74,4 +80,4 @@ pwd_getpwall(PyObject *module, PyObject *Py_UNUSED(ignored)) #ifndef PWD_GETPWALL_METHODDEF #define PWD_GETPWALL_METHODDEF #endif /* !defined(PWD_GETPWALL_METHODDEF) */ -/*[clinic end generated code: output=7fceab7f1a85da36 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=a95bc08653cda56b input=a9049054013a1b77]*/ diff --git a/Modules/clinic/pyexpat.c.h b/Modules/clinic/pyexpat.c.h index b2648320..34937c5d 100644 --- a/Modules/clinic/pyexpat.c.h +++ b/Modules/clinic/pyexpat.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(pyexpat_xmlparser_Parse__doc__, "Parse($self, data, isfinal=False, /)\n" "--\n" @@ -21,8 +27,19 @@ static PyObject * pyexpat_xmlparser_Parse(xmlparseobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + static const char * const _keywords[] = {"", "", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "Parse", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "Parse", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject *data; int isfinal = 0; @@ -35,8 +52,8 @@ pyexpat_xmlparser_Parse(xmlparseobject *self, PyTypeObject *cls, PyObject *const if (nargs < 2) { goto skip_optional_posonly; } - isfinal = _PyLong_AsInt(args[1]); - if (isfinal == -1 && PyErr_Occurred()) { + isfinal = PyObject_IsTrue(args[1]); + if (isfinal < 0) { goto exit; } skip_optional_posonly: @@ -63,8 +80,19 @@ static PyObject * pyexpat_xmlparser_ParseFile(xmlparseobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + static const char * const _keywords[] = {"", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "ParseFile", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "ParseFile", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *file; @@ -175,8 +203,19 @@ static PyObject * pyexpat_xmlparser_ExternalEntityParserCreate(xmlparseobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + static const char * const _keywords[] = {"", "", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "ExternalEntityParserCreate", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "ExternalEntityParserCreate", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; const char *context; const char *encoding = NULL; @@ -282,8 +321,19 @@ static PyObject * pyexpat_xmlparser_UseForeignDTD(xmlparseobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + static const char * const _keywords[] = {"", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "UseForeignDTD", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "UseForeignDTD", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int flag = 1; @@ -325,8 +375,31 @@ static PyObject * pyexpat_ParserCreate(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(encoding), &_Py_ID(namespace_separator), &_Py_ID(intern), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"encoding", "namespace_separator", "intern", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "ParserCreate", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "ParserCreate", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; const char *encoding = NULL; @@ -425,4 +498,4 @@ exit: #ifndef PYEXPAT_XMLPARSER_USEFOREIGNDTD_METHODDEF #define PYEXPAT_XMLPARSER_USEFOREIGNDTD_METHODDEF #endif /* !defined(PYEXPAT_XMLPARSER_USEFOREIGNDTD_METHODDEF) */ -/*[clinic end generated code: output=3e333b89da3aa58c input=a9049054013a1b77]*/ +/*[clinic end generated code: output=63efc62e24a7b5a7 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/readline.c.h b/Modules/clinic/readline.c.h index c64a84ed..e36d651f 100644 --- a/Modules/clinic/readline.c.h +++ b/Modules/clinic/readline.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(readline_parse_and_bind__doc__, "parse_and_bind($module, string, /)\n" "--\n" @@ -685,4 +691,4 @@ readline_redisplay(PyObject *module, PyObject *Py_UNUSED(ignored)) #ifndef READLINE_CLEAR_HISTORY_METHODDEF #define READLINE_CLEAR_HISTORY_METHODDEF #endif /* !defined(READLINE_CLEAR_HISTORY_METHODDEF) */ -/*[clinic end generated code: output=1fd4c04c2e7ba475 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=9097fcb749c19e27 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/resource.c.h b/Modules/clinic/resource.c.h index c591823e..d0ca8e71 100644 --- a/Modules/clinic/resource.c.h +++ b/Modules/clinic/resource.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + #if defined(HAVE_GETRUSAGE) PyDoc_STRVAR(resource_getrusage__doc__, @@ -95,41 +101,42 @@ exit: #if defined(HAVE_PRLIMIT) PyDoc_STRVAR(resource_prlimit__doc__, -"prlimit(pid, resource, [limits])"); +"prlimit($module, pid, resource, limits=None, /)\n" +"--\n" +"\n"); #define RESOURCE_PRLIMIT_METHODDEF \ - {"prlimit", (PyCFunction)resource_prlimit, METH_VARARGS, resource_prlimit__doc__}, + {"prlimit", _PyCFunction_CAST(resource_prlimit), METH_FASTCALL, resource_prlimit__doc__}, static PyObject * resource_prlimit_impl(PyObject *module, pid_t pid, int resource, - int group_right_1, PyObject *limits); + PyObject *limits); static PyObject * -resource_prlimit(PyObject *module, PyObject *args) +resource_prlimit(PyObject *module, PyObject *const *args, Py_ssize_t nargs) { PyObject *return_value = NULL; pid_t pid; int resource; - int group_right_1 = 0; - PyObject *limits = NULL; - - switch (PyTuple_GET_SIZE(args)) { - case 2: - if (!PyArg_ParseTuple(args, "" _Py_PARSE_PID "i:prlimit", &pid, &resource)) { - goto exit; - } - break; - case 3: - if (!PyArg_ParseTuple(args, "" _Py_PARSE_PID "iO:prlimit", &pid, &resource, &limits)) { - goto exit; - } - group_right_1 = 1; - break; - default: - PyErr_SetString(PyExc_TypeError, "resource.prlimit requires 2 to 3 arguments"); - goto exit; + PyObject *limits = Py_None; + + if (!_PyArg_CheckPositional("prlimit", nargs, 2, 3)) { + goto exit; + } + pid = PyLong_AsPid(args[0]); + if (pid == -1 && PyErr_Occurred()) { + goto exit; + } + resource = _PyLong_AsInt(args[1]); + if (resource == -1 && PyErr_Occurred()) { + goto exit; + } + if (nargs < 3) { + goto skip_optional; } - return_value = resource_prlimit_impl(module, pid, resource, group_right_1, limits); + limits = args[2]; +skip_optional: + return_value = resource_prlimit_impl(module, pid, resource, limits); exit: return return_value; @@ -171,4 +178,4 @@ exit: #ifndef RESOURCE_PRLIMIT_METHODDEF #define RESOURCE_PRLIMIT_METHODDEF #endif /* !defined(RESOURCE_PRLIMIT_METHODDEF) */ -/*[clinic end generated code: output=7c57d4f3688d3f07 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=2fbec74335a57230 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/selectmodule.c.h b/Modules/clinic/selectmodule.c.h index daa75427..f44ca1d7 100644 --- a/Modules/clinic/selectmodule.c.h +++ b/Modules/clinic/selectmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(select_select__doc__, "select($module, rlist, wlist, xlist, timeout=None, /)\n" "--\n" @@ -522,8 +528,31 @@ static PyObject * select_epoll(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(sizehint), &_Py_ID(flags), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"sizehint", "flags", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "epoll", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "epoll", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -665,8 +694,31 @@ static PyObject * select_epoll_register(pyEpoll_Object *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(fd), &_Py_ID(eventmask), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"fd", "eventmask", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "register", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "register", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; int fd; @@ -719,8 +771,31 @@ static PyObject * select_epoll_modify(pyEpoll_Object *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(fd), &_Py_ID(eventmask), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"fd", "eventmask", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "modify", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "modify", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; int fd; unsigned int eventmask; @@ -765,8 +840,31 @@ static PyObject * select_epoll_unregister(pyEpoll_Object *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(fd), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"fd", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "unregister", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "unregister", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int fd; @@ -813,8 +911,31 @@ static PyObject * select_epoll_poll(pyEpoll_Object *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(timeout), &_Py_ID(maxevents), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"timeout", "maxevents", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "poll", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "poll", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *timeout_obj = Py_None; @@ -940,14 +1061,13 @@ static PyObject * select_kqueue(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + PyTypeObject *base_tp = _selectstate_by_type(type)->kqueue_queue_Type; - if ((type == _selectstate_by_type(type)->kqueue_queue_Type || - type->tp_init == _selectstate_by_type(type)->kqueue_queue_Type->tp_init) && + if ((type == base_tp || type->tp_init == base_tp->tp_init) && !_PyArg_NoPositional("kqueue", args)) { goto exit; } - if ((type == _selectstate_by_type(type)->kqueue_queue_Type || - type->tp_init == _selectstate_by_type(type)->kqueue_queue_Type->tp_init) && + if ((type == base_tp || type->tp_init == base_tp->tp_init) && !_PyArg_NoKeywords("kqueue", kwargs)) { goto exit; } @@ -1189,4 +1309,4 @@ exit: #ifndef SELECT_KQUEUE_CONTROL_METHODDEF #define SELECT_KQUEUE_CONTROL_METHODDEF #endif /* !defined(SELECT_KQUEUE_CONTROL_METHODDEF) */ -/*[clinic end generated code: output=e77cc5c8a6c77860 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=64516114287e894d input=a9049054013a1b77]*/ diff --git a/Modules/clinic/sha1module.c.h b/Modules/clinic/sha1module.c.h index e2338e4a..ad15ddaa 100644 --- a/Modules/clinic/sha1module.c.h +++ b/Modules/clinic/sha1module.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(SHA1Type_copy__doc__, "copy($self, /)\n" "--\n" @@ -85,8 +91,31 @@ static PyObject * _sha1_sha1(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "sha1", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "sha1", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *string = NULL; @@ -119,4 +148,4 @@ skip_optional_kwonly: exit: return return_value; } -/*[clinic end generated code: output=322d77ba0a4282fc input=a9049054013a1b77]*/ +/*[clinic end generated code: output=4d1293ca3472acdb input=a9049054013a1b77]*/ diff --git a/Modules/clinic/sha256module.c.h b/Modules/clinic/sha256module.c.h deleted file mode 100644 index b94c1c54..00000000 --- a/Modules/clinic/sha256module.c.h +++ /dev/null @@ -1,173 +0,0 @@ -/*[clinic input] -preserve -[clinic start generated code]*/ - -PyDoc_STRVAR(SHA256Type_copy__doc__, -"copy($self, /)\n" -"--\n" -"\n" -"Return a copy of the hash object."); - -#define SHA256TYPE_COPY_METHODDEF \ - {"copy", _PyCFunction_CAST(SHA256Type_copy), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, SHA256Type_copy__doc__}, - -static PyObject * -SHA256Type_copy_impl(SHAobject *self, PyTypeObject *cls); - -static PyObject * -SHA256Type_copy(SHAobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - if (nargs) { - PyErr_SetString(PyExc_TypeError, "copy() takes no arguments"); - return NULL; - } - return SHA256Type_copy_impl(self, cls); -} - -PyDoc_STRVAR(SHA256Type_digest__doc__, -"digest($self, /)\n" -"--\n" -"\n" -"Return the digest value as a bytes object."); - -#define SHA256TYPE_DIGEST_METHODDEF \ - {"digest", (PyCFunction)SHA256Type_digest, METH_NOARGS, SHA256Type_digest__doc__}, - -static PyObject * -SHA256Type_digest_impl(SHAobject *self); - -static PyObject * -SHA256Type_digest(SHAobject *self, PyObject *Py_UNUSED(ignored)) -{ - return SHA256Type_digest_impl(self); -} - -PyDoc_STRVAR(SHA256Type_hexdigest__doc__, -"hexdigest($self, /)\n" -"--\n" -"\n" -"Return the digest value as a string of hexadecimal digits."); - -#define SHA256TYPE_HEXDIGEST_METHODDEF \ - {"hexdigest", (PyCFunction)SHA256Type_hexdigest, METH_NOARGS, SHA256Type_hexdigest__doc__}, - -static PyObject * -SHA256Type_hexdigest_impl(SHAobject *self); - -static PyObject * -SHA256Type_hexdigest(SHAobject *self, PyObject *Py_UNUSED(ignored)) -{ - return SHA256Type_hexdigest_impl(self); -} - -PyDoc_STRVAR(SHA256Type_update__doc__, -"update($self, obj, /)\n" -"--\n" -"\n" -"Update this hash object\'s state with the provided string."); - -#define SHA256TYPE_UPDATE_METHODDEF \ - {"update", (PyCFunction)SHA256Type_update, METH_O, SHA256Type_update__doc__}, - -PyDoc_STRVAR(_sha256_sha256__doc__, -"sha256($module, /, string=b\'\', *, usedforsecurity=True)\n" -"--\n" -"\n" -"Return a new SHA-256 hash object; optionally initialized with a string."); - -#define _SHA256_SHA256_METHODDEF \ - {"sha256", _PyCFunction_CAST(_sha256_sha256), METH_FASTCALL|METH_KEYWORDS, _sha256_sha256__doc__}, - -static PyObject * -_sha256_sha256_impl(PyObject *module, PyObject *string, int usedforsecurity); - -static PyObject * -_sha256_sha256(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "sha256", 0}; - PyObject *argsbuf[2]; - Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; - PyObject *string = NULL; - int usedforsecurity = 1; - - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); - if (!args) { - goto exit; - } - if (!noptargs) { - goto skip_optional_pos; - } - if (args[0]) { - string = args[0]; - if (!--noptargs) { - goto skip_optional_pos; - } - } -skip_optional_pos: - if (!noptargs) { - goto skip_optional_kwonly; - } - usedforsecurity = PyObject_IsTrue(args[1]); - if (usedforsecurity < 0) { - goto exit; - } -skip_optional_kwonly: - return_value = _sha256_sha256_impl(module, string, usedforsecurity); - -exit: - return return_value; -} - -PyDoc_STRVAR(_sha256_sha224__doc__, -"sha224($module, /, string=b\'\', *, usedforsecurity=True)\n" -"--\n" -"\n" -"Return a new SHA-224 hash object; optionally initialized with a string."); - -#define _SHA256_SHA224_METHODDEF \ - {"sha224", _PyCFunction_CAST(_sha256_sha224), METH_FASTCALL|METH_KEYWORDS, _sha256_sha224__doc__}, - -static PyObject * -_sha256_sha224_impl(PyObject *module, PyObject *string, int usedforsecurity); - -static PyObject * -_sha256_sha224(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "sha224", 0}; - PyObject *argsbuf[2]; - Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; - PyObject *string = NULL; - int usedforsecurity = 1; - - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); - if (!args) { - goto exit; - } - if (!noptargs) { - goto skip_optional_pos; - } - if (args[0]) { - string = args[0]; - if (!--noptargs) { - goto skip_optional_pos; - } - } -skip_optional_pos: - if (!noptargs) { - goto skip_optional_kwonly; - } - usedforsecurity = PyObject_IsTrue(args[1]); - if (usedforsecurity < 0) { - goto exit; - } -skip_optional_kwonly: - return_value = _sha256_sha224_impl(module, string, usedforsecurity); - -exit: - return return_value; -} -/*[clinic end generated code: output=58b48051890d3fde input=a9049054013a1b77]*/ diff --git a/Modules/clinic/sha2module.c.h b/Modules/clinic/sha2module.c.h new file mode 100644 index 00000000..8f855ca3 --- /dev/null +++ b/Modules/clinic/sha2module.c.h @@ -0,0 +1,440 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + +PyDoc_STRVAR(SHA256Type_copy__doc__, +"copy($self, /)\n" +"--\n" +"\n" +"Return a copy of the hash object."); + +#define SHA256TYPE_COPY_METHODDEF \ + {"copy", _PyCFunction_CAST(SHA256Type_copy), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, SHA256Type_copy__doc__}, + +static PyObject * +SHA256Type_copy_impl(SHA256object *self, PyTypeObject *cls); + +static PyObject * +SHA256Type_copy(SHA256object *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + if (nargs) { + PyErr_SetString(PyExc_TypeError, "copy() takes no arguments"); + return NULL; + } + return SHA256Type_copy_impl(self, cls); +} + +PyDoc_STRVAR(SHA512Type_copy__doc__, +"copy($self, /)\n" +"--\n" +"\n" +"Return a copy of the hash object."); + +#define SHA512TYPE_COPY_METHODDEF \ + {"copy", _PyCFunction_CAST(SHA512Type_copy), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, SHA512Type_copy__doc__}, + +static PyObject * +SHA512Type_copy_impl(SHA512object *self, PyTypeObject *cls); + +static PyObject * +SHA512Type_copy(SHA512object *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + if (nargs) { + PyErr_SetString(PyExc_TypeError, "copy() takes no arguments"); + return NULL; + } + return SHA512Type_copy_impl(self, cls); +} + +PyDoc_STRVAR(SHA256Type_digest__doc__, +"digest($self, /)\n" +"--\n" +"\n" +"Return the digest value as a bytes object."); + +#define SHA256TYPE_DIGEST_METHODDEF \ + {"digest", (PyCFunction)SHA256Type_digest, METH_NOARGS, SHA256Type_digest__doc__}, + +static PyObject * +SHA256Type_digest_impl(SHA256object *self); + +static PyObject * +SHA256Type_digest(SHA256object *self, PyObject *Py_UNUSED(ignored)) +{ + return SHA256Type_digest_impl(self); +} + +PyDoc_STRVAR(SHA512Type_digest__doc__, +"digest($self, /)\n" +"--\n" +"\n" +"Return the digest value as a bytes object."); + +#define SHA512TYPE_DIGEST_METHODDEF \ + {"digest", (PyCFunction)SHA512Type_digest, METH_NOARGS, SHA512Type_digest__doc__}, + +static PyObject * +SHA512Type_digest_impl(SHA512object *self); + +static PyObject * +SHA512Type_digest(SHA512object *self, PyObject *Py_UNUSED(ignored)) +{ + return SHA512Type_digest_impl(self); +} + +PyDoc_STRVAR(SHA256Type_hexdigest__doc__, +"hexdigest($self, /)\n" +"--\n" +"\n" +"Return the digest value as a string of hexadecimal digits."); + +#define SHA256TYPE_HEXDIGEST_METHODDEF \ + {"hexdigest", (PyCFunction)SHA256Type_hexdigest, METH_NOARGS, SHA256Type_hexdigest__doc__}, + +static PyObject * +SHA256Type_hexdigest_impl(SHA256object *self); + +static PyObject * +SHA256Type_hexdigest(SHA256object *self, PyObject *Py_UNUSED(ignored)) +{ + return SHA256Type_hexdigest_impl(self); +} + +PyDoc_STRVAR(SHA512Type_hexdigest__doc__, +"hexdigest($self, /)\n" +"--\n" +"\n" +"Return the digest value as a string of hexadecimal digits."); + +#define SHA512TYPE_HEXDIGEST_METHODDEF \ + {"hexdigest", (PyCFunction)SHA512Type_hexdigest, METH_NOARGS, SHA512Type_hexdigest__doc__}, + +static PyObject * +SHA512Type_hexdigest_impl(SHA512object *self); + +static PyObject * +SHA512Type_hexdigest(SHA512object *self, PyObject *Py_UNUSED(ignored)) +{ + return SHA512Type_hexdigest_impl(self); +} + +PyDoc_STRVAR(SHA256Type_update__doc__, +"update($self, obj, /)\n" +"--\n" +"\n" +"Update this hash object\'s state with the provided string."); + +#define SHA256TYPE_UPDATE_METHODDEF \ + {"update", (PyCFunction)SHA256Type_update, METH_O, SHA256Type_update__doc__}, + +PyDoc_STRVAR(SHA512Type_update__doc__, +"update($self, obj, /)\n" +"--\n" +"\n" +"Update this hash object\'s state with the provided string."); + +#define SHA512TYPE_UPDATE_METHODDEF \ + {"update", (PyCFunction)SHA512Type_update, METH_O, SHA512Type_update__doc__}, + +PyDoc_STRVAR(_sha2_sha256__doc__, +"sha256($module, /, string=b\'\', *, usedforsecurity=True)\n" +"--\n" +"\n" +"Return a new SHA-256 hash object; optionally initialized with a string."); + +#define _SHA2_SHA256_METHODDEF \ + {"sha256", _PyCFunction_CAST(_sha2_sha256), METH_FASTCALL|METH_KEYWORDS, _sha2_sha256__doc__}, + +static PyObject * +_sha2_sha256_impl(PyObject *module, PyObject *string, int usedforsecurity); + +static PyObject * +_sha2_sha256(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "sha256", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *string = NULL; + int usedforsecurity = 1; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[0]) { + string = args[0]; + if (!--noptargs) { + goto skip_optional_pos; + } + } +skip_optional_pos: + if (!noptargs) { + goto skip_optional_kwonly; + } + usedforsecurity = PyObject_IsTrue(args[1]); + if (usedforsecurity < 0) { + goto exit; + } +skip_optional_kwonly: + return_value = _sha2_sha256_impl(module, string, usedforsecurity); + +exit: + return return_value; +} + +PyDoc_STRVAR(_sha2_sha224__doc__, +"sha224($module, /, string=b\'\', *, usedforsecurity=True)\n" +"--\n" +"\n" +"Return a new SHA-224 hash object; optionally initialized with a string."); + +#define _SHA2_SHA224_METHODDEF \ + {"sha224", _PyCFunction_CAST(_sha2_sha224), METH_FASTCALL|METH_KEYWORDS, _sha2_sha224__doc__}, + +static PyObject * +_sha2_sha224_impl(PyObject *module, PyObject *string, int usedforsecurity); + +static PyObject * +_sha2_sha224(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "sha224", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *string = NULL; + int usedforsecurity = 1; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[0]) { + string = args[0]; + if (!--noptargs) { + goto skip_optional_pos; + } + } +skip_optional_pos: + if (!noptargs) { + goto skip_optional_kwonly; + } + usedforsecurity = PyObject_IsTrue(args[1]); + if (usedforsecurity < 0) { + goto exit; + } +skip_optional_kwonly: + return_value = _sha2_sha224_impl(module, string, usedforsecurity); + +exit: + return return_value; +} + +PyDoc_STRVAR(_sha2_sha512__doc__, +"sha512($module, /, string=b\'\', *, usedforsecurity=True)\n" +"--\n" +"\n" +"Return a new SHA-512 hash object; optionally initialized with a string."); + +#define _SHA2_SHA512_METHODDEF \ + {"sha512", _PyCFunction_CAST(_sha2_sha512), METH_FASTCALL|METH_KEYWORDS, _sha2_sha512__doc__}, + +static PyObject * +_sha2_sha512_impl(PyObject *module, PyObject *string, int usedforsecurity); + +static PyObject * +_sha2_sha512(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "sha512", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *string = NULL; + int usedforsecurity = 1; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[0]) { + string = args[0]; + if (!--noptargs) { + goto skip_optional_pos; + } + } +skip_optional_pos: + if (!noptargs) { + goto skip_optional_kwonly; + } + usedforsecurity = PyObject_IsTrue(args[1]); + if (usedforsecurity < 0) { + goto exit; + } +skip_optional_kwonly: + return_value = _sha2_sha512_impl(module, string, usedforsecurity); + +exit: + return return_value; +} + +PyDoc_STRVAR(_sha2_sha384__doc__, +"sha384($module, /, string=b\'\', *, usedforsecurity=True)\n" +"--\n" +"\n" +"Return a new SHA-384 hash object; optionally initialized with a string."); + +#define _SHA2_SHA384_METHODDEF \ + {"sha384", _PyCFunction_CAST(_sha2_sha384), METH_FASTCALL|METH_KEYWORDS, _sha2_sha384__doc__}, + +static PyObject * +_sha2_sha384_impl(PyObject *module, PyObject *string, int usedforsecurity); + +static PyObject * +_sha2_sha384(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(string), &_Py_ID(usedforsecurity), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "sha384", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *string = NULL; + int usedforsecurity = 1; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[0]) { + string = args[0]; + if (!--noptargs) { + goto skip_optional_pos; + } + } +skip_optional_pos: + if (!noptargs) { + goto skip_optional_kwonly; + } + usedforsecurity = PyObject_IsTrue(args[1]); + if (usedforsecurity < 0) { + goto exit; + } +skip_optional_kwonly: + return_value = _sha2_sha384_impl(module, string, usedforsecurity); + +exit: + return return_value; +} +/*[clinic end generated code: output=f81dacb48f3fee72 input=a9049054013a1b77]*/ diff --git a/Modules/_sha3/clinic/sha3module.c.h b/Modules/clinic/sha3module.c.h similarity index 82% rename from Modules/_sha3/clinic/sha3module.c.h rename to Modules/clinic/sha3module.c.h index 1c79c269..299803a3 100644 --- a/Modules/_sha3/clinic/sha3module.c.h +++ b/Modules/clinic/sha3module.c.h @@ -2,11 +2,17 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(py_sha3_new__doc__, "sha3_224(data=b\'\', /, *, usedforsecurity=True)\n" "--\n" "\n" -"Return a new BLAKE2b hash object."); +"Return a new SHA3 hash object."); static PyObject * py_sha3_new_impl(PyTypeObject *type, PyObject *data, int usedforsecurity); @@ -15,8 +21,31 @@ static PyObject * py_sha3_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(usedforsecurity), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "usedforsecurity", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "sha3_224", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "sha3_224", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -164,4 +193,4 @@ _sha3_shake_128_hexdigest(SHA3object *self, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=c8a97b34e80def62 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=907cb475f3dc9ee0 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/sha512module.c.h b/Modules/clinic/sha512module.c.h deleted file mode 100644 index b7227480..00000000 --- a/Modules/clinic/sha512module.c.h +++ /dev/null @@ -1,173 +0,0 @@ -/*[clinic input] -preserve -[clinic start generated code]*/ - -PyDoc_STRVAR(SHA512Type_copy__doc__, -"copy($self, /)\n" -"--\n" -"\n" -"Return a copy of the hash object."); - -#define SHA512TYPE_COPY_METHODDEF \ - {"copy", _PyCFunction_CAST(SHA512Type_copy), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, SHA512Type_copy__doc__}, - -static PyObject * -SHA512Type_copy_impl(SHAobject *self, PyTypeObject *cls); - -static PyObject * -SHA512Type_copy(SHAobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - if (nargs) { - PyErr_SetString(PyExc_TypeError, "copy() takes no arguments"); - return NULL; - } - return SHA512Type_copy_impl(self, cls); -} - -PyDoc_STRVAR(SHA512Type_digest__doc__, -"digest($self, /)\n" -"--\n" -"\n" -"Return the digest value as a bytes object."); - -#define SHA512TYPE_DIGEST_METHODDEF \ - {"digest", (PyCFunction)SHA512Type_digest, METH_NOARGS, SHA512Type_digest__doc__}, - -static PyObject * -SHA512Type_digest_impl(SHAobject *self); - -static PyObject * -SHA512Type_digest(SHAobject *self, PyObject *Py_UNUSED(ignored)) -{ - return SHA512Type_digest_impl(self); -} - -PyDoc_STRVAR(SHA512Type_hexdigest__doc__, -"hexdigest($self, /)\n" -"--\n" -"\n" -"Return the digest value as a string of hexadecimal digits."); - -#define SHA512TYPE_HEXDIGEST_METHODDEF \ - {"hexdigest", (PyCFunction)SHA512Type_hexdigest, METH_NOARGS, SHA512Type_hexdigest__doc__}, - -static PyObject * -SHA512Type_hexdigest_impl(SHAobject *self); - -static PyObject * -SHA512Type_hexdigest(SHAobject *self, PyObject *Py_UNUSED(ignored)) -{ - return SHA512Type_hexdigest_impl(self); -} - -PyDoc_STRVAR(SHA512Type_update__doc__, -"update($self, obj, /)\n" -"--\n" -"\n" -"Update this hash object\'s state with the provided string."); - -#define SHA512TYPE_UPDATE_METHODDEF \ - {"update", (PyCFunction)SHA512Type_update, METH_O, SHA512Type_update__doc__}, - -PyDoc_STRVAR(_sha512_sha512__doc__, -"sha512($module, /, string=b\'\', *, usedforsecurity=True)\n" -"--\n" -"\n" -"Return a new SHA-512 hash object; optionally initialized with a string."); - -#define _SHA512_SHA512_METHODDEF \ - {"sha512", _PyCFunction_CAST(_sha512_sha512), METH_FASTCALL|METH_KEYWORDS, _sha512_sha512__doc__}, - -static PyObject * -_sha512_sha512_impl(PyObject *module, PyObject *string, int usedforsecurity); - -static PyObject * -_sha512_sha512(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "sha512", 0}; - PyObject *argsbuf[2]; - Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; - PyObject *string = NULL; - int usedforsecurity = 1; - - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); - if (!args) { - goto exit; - } - if (!noptargs) { - goto skip_optional_pos; - } - if (args[0]) { - string = args[0]; - if (!--noptargs) { - goto skip_optional_pos; - } - } -skip_optional_pos: - if (!noptargs) { - goto skip_optional_kwonly; - } - usedforsecurity = PyObject_IsTrue(args[1]); - if (usedforsecurity < 0) { - goto exit; - } -skip_optional_kwonly: - return_value = _sha512_sha512_impl(module, string, usedforsecurity); - -exit: - return return_value; -} - -PyDoc_STRVAR(_sha512_sha384__doc__, -"sha384($module, /, string=b\'\', *, usedforsecurity=True)\n" -"--\n" -"\n" -"Return a new SHA-384 hash object; optionally initialized with a string."); - -#define _SHA512_SHA384_METHODDEF \ - {"sha384", _PyCFunction_CAST(_sha512_sha384), METH_FASTCALL|METH_KEYWORDS, _sha512_sha384__doc__}, - -static PyObject * -_sha512_sha384_impl(PyObject *module, PyObject *string, int usedforsecurity); - -static PyObject * -_sha512_sha384(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -{ - PyObject *return_value = NULL; - static const char * const _keywords[] = {"string", "usedforsecurity", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "sha384", 0}; - PyObject *argsbuf[2]; - Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; - PyObject *string = NULL; - int usedforsecurity = 1; - - args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); - if (!args) { - goto exit; - } - if (!noptargs) { - goto skip_optional_pos; - } - if (args[0]) { - string = args[0]; - if (!--noptargs) { - goto skip_optional_pos; - } - } -skip_optional_pos: - if (!noptargs) { - goto skip_optional_kwonly; - } - usedforsecurity = PyObject_IsTrue(args[1]); - if (usedforsecurity < 0) { - goto exit; - } -skip_optional_kwonly: - return_value = _sha512_sha384_impl(module, string, usedforsecurity); - -exit: - return return_value; -} -/*[clinic end generated code: output=60a0a1a28c07f391 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/signalmodule.c.h b/Modules/clinic/signalmodule.c.h index 8b1f316d..3b3c6ba1 100644 --- a/Modules/clinic/signalmodule.c.h +++ b/Modules/clinic/signalmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(signal_default_int_handler__doc__, "default_int_handler($module, signalnum, frame, /)\n" "--\n" @@ -699,4 +705,4 @@ exit: #ifndef SIGNAL_PIDFD_SEND_SIGNAL_METHODDEF #define SIGNAL_PIDFD_SEND_SIGNAL_METHODDEF #endif /* !defined(SIGNAL_PIDFD_SEND_SIGNAL_METHODDEF) */ -/*[clinic end generated code: output=9b3f9f1ae2ac2b94 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=2b54dc607f6e3146 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/socketmodule.c.h b/Modules/clinic/socketmodule.c.h index dab2b6dc..8ff1044d 100644 --- a/Modules/clinic/socketmodule.c.h +++ b/Modules/clinic/socketmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + static int sock_initobj_impl(PySocketSockObject *self, int family, int type, int proto, PyObject *fdobj); @@ -10,8 +16,31 @@ static int sock_initobj(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(family), &_Py_ID(type), &_Py_ID(proto), &_Py_ID(fileno), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"family", "type", "proto", "fileno", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "socket", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "socket", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -62,4 +91,4 @@ skip_optional_pos: exit: return return_value; } -/*[clinic end generated code: output=2433d6ac51bc962a input=a9049054013a1b77]*/ +/*[clinic end generated code: output=987155ac4b48a198 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/spwdmodule.c.h b/Modules/clinic/spwdmodule.c.h index 411d2344..f47aa9a7 100644 --- a/Modules/clinic/spwdmodule.c.h +++ b/Modules/clinic/spwdmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + #if defined(HAVE_GETSPNAM) PyDoc_STRVAR(spwd_getspnam__doc__, @@ -71,4 +77,4 @@ spwd_getspall(PyObject *module, PyObject *Py_UNUSED(ignored)) #ifndef SPWD_GETSPALL_METHODDEF #define SPWD_GETSPALL_METHODDEF #endif /* !defined(SPWD_GETSPALL_METHODDEF) */ -/*[clinic end generated code: output=eec8d0bedcd312e5 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=dd61827a7b708e11 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/symtablemodule.c.h b/Modules/clinic/symtablemodule.c.h index 2cd08f81..04fdb9f2 100644 --- a/Modules/clinic/symtablemodule.c.h +++ b/Modules/clinic/symtablemodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_symtable_symtable__doc__, "symtable($module, source, filename, startstr, /)\n" "--\n" @@ -48,4 +54,4 @@ _symtable_symtable(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=3f7ccf535d750238 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=07716ddbd6c7efe1 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/syslogmodule.c.h b/Modules/clinic/syslogmodule.c.h new file mode 100644 index 00000000..0ce66ad4 --- /dev/null +++ b/Modules/clinic/syslogmodule.c.h @@ -0,0 +1,257 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + +PyDoc_STRVAR(syslog_openlog__doc__, +"openlog($module, /, ident=<unrepresentable>, logoption=0,\n" +" facility=LOG_USER)\n" +"--\n" +"\n" +"Set logging options of subsequent syslog() calls."); + +#define SYSLOG_OPENLOG_METHODDEF \ + {"openlog", _PyCFunction_CAST(syslog_openlog), METH_FASTCALL|METH_KEYWORDS, syslog_openlog__doc__}, + +static PyObject * +syslog_openlog_impl(PyObject *module, PyObject *ident, long logopt, + long facility); + +static PyObject * +syslog_openlog(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(ident), &_Py_ID(logoption), &_Py_ID(facility), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"ident", "logoption", "facility", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "openlog", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[3]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *ident = NULL; + long logopt = 0; + long facility = LOG_USER; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 3, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[0]) { + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("openlog", "argument 'ident'", "str", args[0]); + goto exit; + } + if (PyUnicode_READY(args[0]) == -1) { + goto exit; + } + ident = args[0]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (args[1]) { + logopt = PyLong_AsLong(args[1]); + if (logopt == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + facility = PyLong_AsLong(args[2]); + if (facility == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional_pos: + return_value = syslog_openlog_impl(module, ident, logopt, facility); + +exit: + return return_value; +} + +PyDoc_STRVAR(syslog_syslog__doc__, +"syslog([priority=LOG_INFO,] message)\n" +"Send the string message to the system logger."); + +#define SYSLOG_SYSLOG_METHODDEF \ + {"syslog", (PyCFunction)syslog_syslog, METH_VARARGS, syslog_syslog__doc__}, + +static PyObject * +syslog_syslog_impl(PyObject *module, int group_left_1, int priority, + const char *message); + +static PyObject * +syslog_syslog(PyObject *module, PyObject *args) +{ + PyObject *return_value = NULL; + int group_left_1 = 0; + int priority = LOG_INFO; + const char *message; + + switch (PyTuple_GET_SIZE(args)) { + case 1: + if (!PyArg_ParseTuple(args, "s:syslog", &message)) { + goto exit; + } + break; + case 2: + if (!PyArg_ParseTuple(args, "is:syslog", &priority, &message)) { + goto exit; + } + group_left_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "syslog.syslog requires 1 to 2 arguments"); + goto exit; + } + return_value = syslog_syslog_impl(module, group_left_1, priority, message); + +exit: + return return_value; +} + +PyDoc_STRVAR(syslog_closelog__doc__, +"closelog($module, /)\n" +"--\n" +"\n" +"Reset the syslog module values and call the system library closelog()."); + +#define SYSLOG_CLOSELOG_METHODDEF \ + {"closelog", (PyCFunction)syslog_closelog, METH_NOARGS, syslog_closelog__doc__}, + +static PyObject * +syslog_closelog_impl(PyObject *module); + +static PyObject * +syslog_closelog(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return syslog_closelog_impl(module); +} + +PyDoc_STRVAR(syslog_setlogmask__doc__, +"setlogmask($module, maskpri, /)\n" +"--\n" +"\n" +"Set the priority mask to maskpri and return the previous mask value."); + +#define SYSLOG_SETLOGMASK_METHODDEF \ + {"setlogmask", (PyCFunction)syslog_setlogmask, METH_O, syslog_setlogmask__doc__}, + +static long +syslog_setlogmask_impl(PyObject *module, long maskpri); + +static PyObject * +syslog_setlogmask(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + long maskpri; + long _return_value; + + maskpri = PyLong_AsLong(arg); + if (maskpri == -1 && PyErr_Occurred()) { + goto exit; + } + _return_value = syslog_setlogmask_impl(module, maskpri); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromLong(_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(syslog_LOG_MASK__doc__, +"LOG_MASK($module, pri, /)\n" +"--\n" +"\n" +"Calculates the mask for the individual priority pri."); + +#define SYSLOG_LOG_MASK_METHODDEF \ + {"LOG_MASK", (PyCFunction)syslog_LOG_MASK, METH_O, syslog_LOG_MASK__doc__}, + +static long +syslog_LOG_MASK_impl(PyObject *module, long pri); + +static PyObject * +syslog_LOG_MASK(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + long pri; + long _return_value; + + pri = PyLong_AsLong(arg); + if (pri == -1 && PyErr_Occurred()) { + goto exit; + } + _return_value = syslog_LOG_MASK_impl(module, pri); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromLong(_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(syslog_LOG_UPTO__doc__, +"LOG_UPTO($module, pri, /)\n" +"--\n" +"\n" +"Calculates the mask for all priorities up to and including pri."); + +#define SYSLOG_LOG_UPTO_METHODDEF \ + {"LOG_UPTO", (PyCFunction)syslog_LOG_UPTO, METH_O, syslog_LOG_UPTO__doc__}, + +static long +syslog_LOG_UPTO_impl(PyObject *module, long pri); + +static PyObject * +syslog_LOG_UPTO(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + long pri; + long _return_value; + + pri = PyLong_AsLong(arg); + if (pri == -1 && PyErr_Occurred()) { + goto exit; + } + _return_value = syslog_LOG_UPTO_impl(module, pri); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromLong(_return_value); + +exit: + return return_value; +} +/*[clinic end generated code: output=3b1bdb16565b8fda input=a9049054013a1b77]*/ diff --git a/Modules/clinic/termios.c.h b/Modules/clinic/termios.c.h index 29858fe8..78863e53 100644 --- a/Modules/clinic/termios.c.h +++ b/Modules/clinic/termios.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(termios_tcgetattr__doc__, "tcgetattr($module, fd, /)\n" "--\n" @@ -286,4 +292,4 @@ termios_tcsetwinsize(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=ef9ab888876fac17 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=d286a3906a051869 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/unicodedata.c.h b/Modules/clinic/unicodedata.c.h index 835a776f..6102027d 100644 --- a/Modules/clinic/unicodedata.c.h +++ b/Modules/clinic/unicodedata.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(unicodedata_UCD_decimal__doc__, "decimal($self, chr, default=<unrepresentable>, /)\n" "--\n" @@ -559,4 +565,4 @@ unicodedata_UCD_lookup(PyObject *self, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=78d7a7ae57014502 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=aaf601d28b352353 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/zlibmodule.c.h b/Modules/clinic/zlibmodule.c.h index ad6a7d47..65412b24 100644 --- a/Modules/clinic/zlibmodule.c.h +++ b/Modules/clinic/zlibmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(zlib_compress__doc__, "compress($module, data, /, level=Z_DEFAULT_COMPRESSION, wbits=MAX_WBITS)\n" "--\n" @@ -25,8 +31,31 @@ static PyObject * zlib_compress(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(level), &_Py_ID(wbits), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "level", "wbits", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "compress", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "compress", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; Py_buffer data = {NULL, NULL}; @@ -96,8 +125,31 @@ static PyObject * zlib_decompress(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(wbits), &_Py_ID(bufsize), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "wbits", "bufsize", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "decompress", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "decompress", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; Py_buffer data = {NULL, NULL}; @@ -192,8 +244,31 @@ static PyObject * zlib_compressobj(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 6 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(level), &_Py_ID(method), &_Py_ID(wbits), &_Py_ID(memLevel), &_Py_ID(strategy), &_Py_ID(zdict), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"level", "method", "wbits", "memLevel", "strategy", "zdict", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "compressobj", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "compressobj", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[6]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int level = Z_DEFAULT_COMPRESSION; @@ -296,8 +371,31 @@ static PyObject * zlib_decompressobj(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(wbits), &_Py_ID(zdict), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"wbits", "zdict", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "decompressobj", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "decompressobj", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int wbits = MAX_WBITS; @@ -351,8 +449,19 @@ static PyObject * zlib_Compress_compress(compobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + static const char * const _keywords[] = {"", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "compress", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "compress", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_buffer data = {NULL, NULL}; @@ -406,8 +515,31 @@ static PyObject * zlib_Decompress_decompress(compobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(max_length), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "max_length", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "decompress", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "decompress", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; Py_buffer data = {NULL, NULL}; @@ -473,8 +605,19 @@ static PyObject * zlib_Compress_flush(compobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + static const char * const _keywords[] = {"", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "flush", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "flush", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int mode = Z_FINISH; @@ -565,8 +708,19 @@ static PyObject * zlib_Compress___deepcopy__(compobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + static const char * const _keywords[] = {"", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "__deepcopy__", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "__deepcopy__", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *memo; @@ -652,8 +806,19 @@ static PyObject * zlib_Decompress___deepcopy__(compobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + static const char * const _keywords[] = {"", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "__deepcopy__", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "__deepcopy__", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *memo; @@ -690,8 +855,19 @@ static PyObject * zlib_Decompress_flush(compobject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + static const char * const _keywords[] = {"", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "flush", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "flush", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t length = DEF_BUF_SIZE; @@ -721,6 +897,104 @@ exit: return return_value; } +PyDoc_STRVAR(zlib_ZlibDecompressor_decompress__doc__, +"decompress($self, /, data, max_length=-1)\n" +"--\n" +"\n" +"Decompress *data*, returning uncompressed data as bytes.\n" +"\n" +"If *max_length* is nonnegative, returns at most *max_length* bytes of\n" +"decompressed data. If this limit is reached and further output can be\n" +"produced, *self.needs_input* will be set to ``False``. In this case, the next\n" +"call to *decompress()* may provide *data* as b\'\' to obtain more of the output.\n" +"\n" +"If all of the input data was decompressed and returned (either because this\n" +"was less than *max_length* bytes, or because *max_length* was negative),\n" +"*self.needs_input* will be set to True.\n" +"\n" +"Attempting to decompress data after the end of stream is reached raises an\n" +"EOFError. Any data found after the end of the stream is ignored and saved in\n" +"the unused_data attribute."); + +#define ZLIB_ZLIBDECOMPRESSOR_DECOMPRESS_METHODDEF \ + {"decompress", _PyCFunction_CAST(zlib_ZlibDecompressor_decompress), METH_FASTCALL|METH_KEYWORDS, zlib_ZlibDecompressor_decompress__doc__}, + +static PyObject * +zlib_ZlibDecompressor_decompress_impl(ZlibDecompressor *self, + Py_buffer *data, Py_ssize_t max_length); + +static PyObject * +zlib_ZlibDecompressor_decompress(ZlibDecompressor *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(data), &_Py_ID(max_length), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"data", "max_length", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "decompress", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + Py_buffer data = {NULL, NULL}; + Py_ssize_t max_length = -1; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf); + if (!args) { + goto exit; + } + if (PyObject_GetBuffer(args[0], &data, PyBUF_SIMPLE) != 0) { + goto exit; + } + if (!PyBuffer_IsContiguous(&data, 'C')) { + _PyArg_BadArgument("decompress", "argument 'data'", "contiguous buffer", args[0]); + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + { + Py_ssize_t ival = -1; + PyObject *iobj = _PyNumber_Index(args[1]); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + max_length = ival; + } +skip_optional_pos: + return_value = zlib_ZlibDecompressor_decompress_impl(self, &data, max_length); + +exit: + /* Cleanup for data */ + if (data.obj) { + PyBuffer_Release(&data); + } + + return return_value; +} + PyDoc_STRVAR(zlib_adler32__doc__, "adler32($module, data, value=1, /)\n" "--\n" @@ -855,4 +1129,4 @@ exit: #ifndef ZLIB_DECOMPRESS___DEEPCOPY___METHODDEF #define ZLIB_DECOMPRESS___DEEPCOPY___METHODDEF #endif /* !defined(ZLIB_DECOMPRESS___DEEPCOPY___METHODDEF) */ -/*[clinic end generated code: output=757804b3ad33454f input=a9049054013a1b77]*/ +/*[clinic end generated code: output=57ff7b511ab23132 input=a9049054013a1b77]*/ diff --git a/Modules/cmathmodule.c b/Modules/cmathmodule.c index 2038ac26..25491e65 100644 --- a/Modules/cmathmodule.c +++ b/Modules/cmathmodule.c @@ -8,7 +8,6 @@ #include "Python.h" #include "pycore_pymath.h" // _PY_SHORT_FLOAT_REPR -#include "pycore_dtoa.h" // _Py_dg_stdnan() /* we need DBL_MAX, DBL_MIN, DBL_EPSILON, DBL_MANT_DIG and FLT_RADIX from float.h. We assume that FLT_RADIX is either 2 or 16. */ #include <float.h> @@ -88,53 +87,6 @@ else { #endif #define CM_SCALE_DOWN (-(CM_SCALE_UP+1)/2) -/* Constants cmath.inf, cmath.infj, cmath.nan, cmath.nanj. - cmath.nan and cmath.nanj are defined only when either - _PY_SHORT_FLOAT_REPR is 1 (which should be - the most common situation on machines using an IEEE 754 - representation), or Py_NAN is defined. */ - -static double -m_inf(void) -{ -#if _PY_SHORT_FLOAT_REPR == 1 - return _Py_dg_infinity(0); -#else - return Py_HUGE_VAL; -#endif -} - -static Py_complex -c_infj(void) -{ - Py_complex r; - r.real = 0.0; - r.imag = m_inf(); - return r; -} - -#if _PY_SHORT_FLOAT_REPR == 1 - -static double -m_nan(void) -{ -#if _PY_SHORT_FLOAT_REPR == 1 - return _Py_dg_stdnan(0); -#else - return Py_NAN; -#endif -} - -static Py_complex -c_nanj(void) -{ - Py_complex r; - r.real = 0.0; - r.imag = m_nan(); - return r; -} - -#endif /* forward declarations */ static Py_complex cmath_asinh_impl(PyObject *, Py_complex); @@ -829,7 +781,7 @@ cmath_sqrt_impl(PyObject *module, Py_complex z) ax = fabs(z.real); ay = fabs(z.imag); - if (ax < DBL_MIN && ay < DBL_MIN && (ax > 0. || ay > 0.)) { + if (ax < DBL_MIN && ay < DBL_MIN) { /* here we catch cases where hypot(ax, ay) is subnormal */ ax = ldexp(ax, CM_SCALE_UP); s = ldexp(sqrt(ax + hypot(ax, ldexp(ay, CM_SCALE_UP))), @@ -957,12 +909,12 @@ cmath.log log(z[, base]) -> the logarithm of z to the given base. -If the base not specified, returns the natural logarithm (base e) of z. +If the base is not specified, returns the natural logarithm (base e) of z. [clinic start generated code]*/ static PyObject * cmath_log_impl(PyObject *module, Py_complex x, PyObject *y_obj) -/*[clinic end generated code: output=4effdb7d258e0d94 input=230ed3a71ecd000a]*/ +/*[clinic end generated code: output=4effdb7d258e0d94 input=e1f81d4fcfd26497]*/ { Py_complex y; @@ -1013,7 +965,7 @@ cmath_phase_impl(PyObject *module, Py_complex z) double phi; errno = 0; - phi = c_atan2(z); + phi = c_atan2(z); /* should not cause any exception */ if (errno != 0) return math_error(); else @@ -1264,33 +1216,31 @@ static PyMethodDef cmath_methods[] = { static int cmath_exec(PyObject *mod) { - if (PyModule_AddObject(mod, "pi", PyFloat_FromDouble(Py_MATH_PI)) < 0) { + if (_PyModule_Add(mod, "pi", PyFloat_FromDouble(Py_MATH_PI)) < 0) { return -1; } - if (PyModule_AddObject(mod, "e", PyFloat_FromDouble(Py_MATH_E)) < 0) { + if (_PyModule_Add(mod, "e", PyFloat_FromDouble(Py_MATH_E)) < 0) { return -1; } // 2pi - if (PyModule_AddObject(mod, "tau", PyFloat_FromDouble(Py_MATH_TAU)) < 0) { + if (_PyModule_Add(mod, "tau", PyFloat_FromDouble(Py_MATH_TAU)) < 0) { return -1; } - if (PyModule_AddObject(mod, "inf", PyFloat_FromDouble(m_inf())) < 0) { + if (_PyModule_Add(mod, "inf", PyFloat_FromDouble(Py_INFINITY)) < 0) { return -1; } - if (PyModule_AddObject(mod, "infj", - PyComplex_FromCComplex(c_infj())) < 0) { + Py_complex infj = {0.0, Py_INFINITY}; + if (_PyModule_Add(mod, "infj", PyComplex_FromCComplex(infj)) < 0) { return -1; } -#if _PY_SHORT_FLOAT_REPR == 1 - if (PyModule_AddObject(mod, "nan", PyFloat_FromDouble(m_nan())) < 0) { + if (_PyModule_Add(mod, "nan", PyFloat_FromDouble(fabs(Py_NAN))) < 0) { return -1; } - if (PyModule_AddObject(mod, "nanj", - PyComplex_FromCComplex(c_nanj())) < 0) { + Py_complex nanj = {0.0, fabs(Py_NAN)}; + if (_PyModule_Add(mod, "nanj", PyComplex_FromCComplex(nanj)) < 0) { return -1; } -#endif /* initialize special value tables */ @@ -1411,6 +1361,7 @@ cmath_exec(PyObject *mod) static PyModuleDef_Slot cmath_slots[] = { {Py_mod_exec, cmath_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; diff --git a/Modules/errnomodule.c b/Modules/errnomodule.c index 4de41445..301ad831 100644 --- a/Modules/errnomodule.c +++ b/Modules/errnomodule.c @@ -5,7 +5,9 @@ /* Windows socket errors (WSA*) */ #ifdef MS_WINDOWS +#ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN +#endif #include <windows.h> /* The following constants were added to errno.h in VS2010 but have preferred WSA equivalents. */ @@ -79,9 +81,12 @@ end: static int errno_exec(PyObject *module) { - PyObject *module_dict = PyModule_GetDict(module); + PyObject *module_dict = PyModule_GetDict(module); // Borrowed ref. + if (module_dict == NULL) { + return -1; + } PyObject *error_dict = PyDict_New(); - if (!module_dict || !error_dict) { + if (error_dict == NULL) { return -1; } if (PyDict_SetItemString(module_dict, "errorcode", error_dict) < 0) { @@ -938,6 +943,7 @@ errno_exec(PyObject *module) static PyModuleDef_Slot errno_slots[] = { {Py_mod_exec, errno_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; diff --git a/Modules/faulthandler.c b/Modules/faulthandler.c index 04995d2e..3d360cb4 100644 --- a/Modules/faulthandler.c +++ b/Modules/faulthandler.c @@ -7,7 +7,6 @@ #include <object.h> #include <signal.h> -#include <signal.h> #include <stdlib.h> // abort() #if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK) && defined(HAVE_PTHREAD_H) # include <pthread.h> @@ -19,12 +18,6 @@ # include <sys/resource.h> #endif -/* Using an alternative stack requires sigaltstack() - and sigaction() SA_ONSTACK */ -#if defined(HAVE_SIGALTSTACK) && defined(HAVE_SIGACTION) -# define FAULTHANDLER_USE_ALT_STACK -#endif - #if defined(FAULTHANDLER_USE_ALT_STACK) && defined(HAVE_LINUX_AUXVEC_H) && defined(HAVE_SYS_AUXV_H) # include <linux/auxvec.h> // AT_MINSIGSTKSZ # include <sys/auxv.h> // getauxval() @@ -33,13 +26,6 @@ /* Allocate at maximum 100 MiB of the stack to raise the stack overflow */ #define STACK_OVERFLOW_MAX_SIZE (100 * 1024 * 1024) -#ifndef MS_WINDOWS - /* register() is useless on Windows, because only SIGSEGV, SIGABRT and - SIGILL can be handled by the process, and these signals can only be used - with enable(), not using register() */ -# define FAULTHANDLER_USER -#endif - #define PUTS(fd, str) _Py_write_noraise(fd, str, strlen(str)) @@ -59,12 +45,6 @@ #endif -#ifdef HAVE_SIGACTION -typedef struct sigaction _Py_sighandler_t; -#else -typedef PyOS_sighandler_t _Py_sighandler_t; -#endif - typedef struct { int signum; int enabled; @@ -73,47 +53,12 @@ typedef struct { int all_threads; } fault_handler_t; -static struct { - int enabled; - PyObject *file; - int fd; - int all_threads; - PyInterpreterState *interp; -#ifdef MS_WINDOWS - void *exc_handler; -#endif -} fatal_error = {0, NULL, -1, 0}; - -static struct { - PyObject *file; - int fd; - PY_TIMEOUT_T timeout_us; /* timeout in microseconds */ - int repeat; - PyInterpreterState *interp; - int exit; - char *header; - size_t header_len; - /* The main thread always holds this lock. It is only released when - faulthandler_thread() is interrupted before this thread exits, or at - Python exit. */ - PyThread_type_lock cancel_event; - /* released by child thread when joined */ - PyThread_type_lock running; -} thread; +#define fatal_error _PyRuntime.faulthandler.fatal_error +#define thread _PyRuntime.faulthandler.thread #ifdef FAULTHANDLER_USER -typedef struct { - int enabled; - PyObject *file; - int fd; - int all_threads; - int chain; - _Py_sighandler_t previous; - PyInterpreterState *interp; -} user_signal_t; - -static user_signal_t *user_signals; - +#define user_signals _PyRuntime.faulthandler.user_signals +typedef struct faulthandler_user_signal user_signal_t; static void faulthandler_user(int signum); #endif /* FAULTHANDLER_USER */ @@ -135,8 +80,8 @@ static const size_t faulthandler_nsignals = \ Py_ARRAY_LENGTH(faulthandler_handlers); #ifdef FAULTHANDLER_USE_ALT_STACK -static stack_t stack; -static stack_t old_stack; +# define stack _PyRuntime.faulthandler.stack +# define old_stack _PyRuntime.faulthandler.old_stack #endif @@ -175,7 +120,7 @@ faulthandler_get_fileno(PyObject **file_ptr) return -1; if (fd < 0) { PyErr_SetString(PyExc_ValueError, - "file is not a valid file descripter"); + "file is not a valid file descriptor"); return -1; } *file_ptr = NULL; @@ -271,7 +216,7 @@ faulthandler_dump_traceback_py(PyObject *self, int fd; if (!PyArg_ParseTupleAndKeywords(args, kwargs, - "|Oi:dump_traceback", kwlist, + "|Op:dump_traceback", kwlist, &file, &all_threads)) return NULL; @@ -469,11 +414,10 @@ faulthandler_allocate_stack(void) int err = sigaltstack(&stack, &old_stack); if (err) { + PyErr_SetFromErrno(PyExc_OSError); /* Release the stack to retry sigaltstack() next time */ PyMem_Free(stack.ss_sp); stack.ss_sp = NULL; - - PyErr_SetFromErrno(PyExc_OSError); return -1; } return 0; @@ -547,7 +491,7 @@ faulthandler_py_enable(PyObject *self, PyObject *args, PyObject *kwargs) PyThreadState *tstate; if (!PyArg_ParseTupleAndKeywords(args, kwargs, - "|Oi:enable", kwlist, &file, &all_threads)) + "|Op:enable", kwlist, &file, &all_threads)) return NULL; fd = faulthandler_get_fileno(&file); @@ -917,7 +861,7 @@ faulthandler_register_py(PyObject *self, int err; if (!PyArg_ParseTupleAndKeywords(args, kwargs, - "i|Oii:register", kwlist, + "i|Opp:register", kwlist, &signum, &file, &all_threads, &chain)) return NULL; @@ -1008,7 +952,7 @@ faulthandler_unregister_py(PyObject *self, PyObject *args) static void faulthandler_suppress_crash_report(void) { -#ifdef MS_WINDOWS +#ifdef MS_WINDOWS_DESKTOP UINT mode; /* Configure Windows to not display the Windows Error Reporting dialog */ @@ -1095,7 +1039,7 @@ faulthandler_fatal_error_thread(void *plock) static PyObject * faulthandler_fatal_error_c_thread(PyObject *self, PyObject *args) { - long thread; + long tid; PyThread_type_lock lock; faulthandler_suppress_crash_report(); @@ -1106,8 +1050,8 @@ faulthandler_fatal_error_c_thread(PyObject *self, PyObject *args) PyThread_acquire_lock(lock, WAIT_LOCK); - thread = PyThread_start_new_thread(faulthandler_fatal_error_thread, lock); - if (thread == -1) { + tid = PyThread_start_new_thread(faulthandler_fatal_error_thread, lock); + if (tid == -1) { PyThread_free_lock(lock); PyErr_SetString(PyExc_RuntimeError, "unable to start the thread"); return NULL; @@ -1253,7 +1197,7 @@ static PyMethodDef module_methods[] = { "if all_threads is True, into file")}, {"dump_traceback_later", _PyCFunction_CAST(faulthandler_dump_traceback_later), METH_VARARGS|METH_KEYWORDS, - PyDoc_STR("dump_traceback_later(timeout, repeat=False, file=sys.stderrn, exit=False):\n" + PyDoc_STR("dump_traceback_later(timeout, repeat=False, file=sys.stderr, exit=False):\n" "dump the traceback of all threads in timeout seconds,\n" "or each timeout seconds if repeat is True. If exit is True, " "call _exit(1) which is not safe.")}, @@ -1329,6 +1273,8 @@ PyExec_faulthandler(PyObject *module) { static PyModuleDef_Slot faulthandler_slots[] = { {Py_mod_exec, PyExec_faulthandler}, + // XXX gh-103092: fix isolation. + //{Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; @@ -1350,13 +1296,13 @@ PyInit_faulthandler(void) static int faulthandler_init_enable(void) { - PyObject *module = PyImport_ImportModule("faulthandler"); - if (module == NULL) { + PyObject *enable = _PyImport_GetModuleAttrString("faulthandler", "enable"); + if (enable == NULL) { return -1; } - PyObject *res = PyObject_CallMethodNoArgs(module, &_Py_ID(enable)); - Py_DECREF(module); + PyObject *res = PyObject_CallNoArgs(enable); + Py_DECREF(enable); if (res == NULL) { return -1; } diff --git a/Modules/fcntlmodule.c b/Modules/fcntlmodule.c index ea9b2bc1..2bca4021 100644 --- a/Modules/fcntlmodule.c +++ b/Modules/fcntlmodule.c @@ -8,6 +8,9 @@ #ifdef HAVE_SYS_FILE_H #include <sys/file.h> #endif +#ifdef HAVE_LINUX_FS_H +#include <linux/fs.h> +#endif #include <sys/ioctl.h> #include <fcntl.h> @@ -208,11 +211,12 @@ fcntl_ioctl_impl(PyObject *module, int fd, unsigned int code, if (mutate_arg && (len <= IOCTL_BUFSZ)) { memcpy(str, buf, len); } - PyBuffer_Release(&pstr); /* No further access to str below this point */ if (ret < 0) { PyErr_SetFromErrno(PyExc_OSError); + PyBuffer_Release(&pstr); return NULL; } + PyBuffer_Release(&pstr); if (mutate_arg) { return PyLong_FromLong(ret); } @@ -237,8 +241,8 @@ fcntl_ioctl_impl(PyObject *module, int fd, unsigned int code, ret = ioctl(fd, code, buf); Py_END_ALLOW_THREADS if (ret < 0) { - PyBuffer_Release(&pstr); PyErr_SetFromErrno(PyExc_OSError); + PyBuffer_Release(&pstr); return NULL; } PyBuffer_Release(&pstr); @@ -572,6 +576,12 @@ all_ins(PyObject* m) #ifdef F_GETPIPE_SZ if (PyModule_AddIntMacro(m, F_GETPIPE_SZ)) return -1; #endif +#ifdef FICLONE + if (PyModule_AddIntMacro(m, FICLONE)) return -1; +#endif +#ifdef FICLONERANGE + if (PyModule_AddIntMacro(m, FICLONERANGE)) return -1; +#endif /* OS X specifics */ #ifdef F_FULLFSYNC @@ -677,6 +687,7 @@ fcntl_exec(PyObject *module) static PyModuleDef_Slot fcntl_slots[] = { {Py_mod_exec, fcntl_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; diff --git a/Modules/gc_weakref.txt b/Modules/gc_weakref.txt index 6d07cce1..f53fb99d 100644 --- a/Modules/gc_weakref.txt +++ b/Modules/gc_weakref.txt @@ -47,7 +47,7 @@ soon as we execute Python code, threads other than the gc thread can run too, and they can do ordinary things with weakrefs that end up resurrecting CT while gc is running. - https://www.python.org/sf/1055820 + https://bugs.python.org/issue1055820 shows how innocent it can be, and also how nasty. Variants of the three focused test cases attached to that bug report are now part of Python's diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c index dcd46fef..26ddcdd5 100644 --- a/Modules/gcmodule.c +++ b/Modules/gcmodule.c @@ -418,8 +418,20 @@ validate_list(PyGC_Head *head, enum flagstates flags) static void update_refs(PyGC_Head *containers) { + PyGC_Head *next; PyGC_Head *gc = GC_NEXT(containers); - for (; gc != containers; gc = GC_NEXT(gc)) { + + while (gc != containers) { + next = GC_NEXT(gc); + /* Move any object that might have become immortal to the + * permanent generation as the reference count is not accurately + * reflecting the actual number of live references to this object + */ + if (_Py_IsImmortal(FROM_GC(gc))) { + gc_list_move(gc, &get_gc_state()->permanent_generation.head); + gc = next; + continue; + } gc_reset_refs(gc, Py_REFCNT(FROM_GC(gc))); /* Python's cyclic gc should never see an incoming refcount * of 0: if something decref'ed to 0, it should have been @@ -440,6 +452,7 @@ update_refs(PyGC_Head *containers) * check instead of an assert? */ _PyObject_ASSERT(FROM_GC(gc), gc_get_refs(gc) != 0); + gc = next; } } @@ -794,9 +807,12 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old) if (! _PyType_SUPPORTS_WEAKREFS(Py_TYPE(op))) continue; - /* It supports weakrefs. Does it have any? */ - wrlist = (PyWeakReference **) - _PyObject_GET_WEAKREFS_LISTPTR(op); + /* It supports weakrefs. Does it have any? + * + * This is never triggered for static types so we can avoid the + * (slightly) more costly _PyObject_GET_WEAKREFS_LISTPTR(). + */ + wrlist = _PyObject_GET_WEAKREFS_LISTPTR_FROM_OFFSET(op); /* `op` may have some weakrefs. March over the list, clear * all the weakrefs, and move the weakrefs with callbacks @@ -1372,10 +1388,19 @@ invoke_gc_callback(PyThreadState *tstate, const char *phase, return; } } + + PyObject *phase_obj = PyUnicode_FromString(phase); + if (phase_obj == NULL) { + Py_XDECREF(info); + PyErr_WriteUnraisable(NULL); + return; + } + + PyObject *stack[] = {phase_obj, info}; for (Py_ssize_t i=0; i<PyList_GET_SIZE(gcstate->callbacks); i++) { PyObject *r, *cb = PyList_GET_ITEM(gcstate->callbacks, i); Py_INCREF(cb); /* make sure cb doesn't go away */ - r = PyObject_CallFunction(cb, "sO", phase, info); + r = PyObject_Vectorcall(cb, stack, 2, NULL); if (r == NULL) { PyErr_WriteUnraisable(cb); } @@ -1384,6 +1409,7 @@ invoke_gc_callback(PyThreadState *tstate, const char *phase, } Py_DECREF(cb); } + Py_DECREF(phase_obj); Py_XDECREF(info); assert(!_PyErr_Occurred(tstate)); } @@ -1867,8 +1893,7 @@ gc_is_tracked(PyObject *module, PyObject *obj) result = Py_True; else result = Py_False; - Py_INCREF(result); - return result; + return Py_NewRef(result); } /*[clinic input] @@ -2019,6 +2044,7 @@ gcmodule_exec(PyObject *module) static PyModuleDef_Slot gcmodule_slots[] = { {Py_mod_exec, gcmodule_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; @@ -2080,11 +2106,10 @@ PyGC_Collect(void) n = 0; } else { - PyObject *exc, *value, *tb; gcstate->collecting = 1; - _PyErr_Fetch(tstate, &exc, &value, &tb); + PyObject *exc = _PyErr_GetRaisedException(tstate); n = gc_collect_with_callback(tstate, NUM_GENERATIONS - 1); - _PyErr_Restore(tstate, exc, value, tb); + _PyErr_SetRaisedException(tstate, exc); gcstate->collecting = 0; } @@ -2150,23 +2175,6 @@ _PyGC_DumpShutdownStats(PyInterpreterState *interp) } -static void -gc_fini_untrack(PyGC_Head *list) -{ - PyGC_Head *gc; - for (gc = GC_NEXT(list); gc != list; gc = GC_NEXT(list)) { - PyObject *op = FROM_GC(gc); - _PyObject_GC_UNTRACK(op); - // gh-92036: If a deallocator function expect the object to be tracked - // by the GC (ex: func_dealloc()), it can crash if called on an object - // which is no longer tracked by the GC. Leak one strong reference on - // purpose so the object is never deleted and its deallocator is not - // called. - Py_INCREF(op); - } -} - - void _PyGC_Fini(PyInterpreterState *interp) { @@ -2174,17 +2182,9 @@ _PyGC_Fini(PyInterpreterState *interp) Py_CLEAR(gcstate->garbage); Py_CLEAR(gcstate->callbacks); - if (!_Py_IsMainInterpreter(interp)) { - // bpo-46070: Explicitly untrack all objects currently tracked by the - // GC. Otherwise, if an object is used later by another interpreter, - // calling PyObject_GC_UnTrack() on the object crashs if the previous - // or the next object of the PyGC_Head structure became a dangling - // pointer. - for (int i = 0; i < NUM_GENERATIONS; i++) { - PyGC_Head *gen = GEN_HEAD(gcstate, i); - gc_fini_untrack(gen); - } - } + /* We expect that none of this interpreters objects are shared + with other interpreters. + See https://github.com/python/cpython/issues/90228. */ } /* for debugging */ @@ -2249,6 +2249,20 @@ PyObject_IS_GC(PyObject *obj) return _PyObject_IS_GC(obj); } +void +_Py_ScheduleGC(PyInterpreterState *interp) +{ + GCState *gcstate = &interp->gc; + if (gcstate->collecting == 1) { + return; + } + struct _ceval_state *ceval = &interp->ceval; + if (!_Py_atomic_load_relaxed(&ceval->gc_scheduled)) { + _Py_atomic_store_relaxed(&ceval->gc_scheduled, 1); + _Py_atomic_store_relaxed(&ceval->eval_breaker, 1); + } +} + void _PyObject_GC_Link(PyObject *op) { @@ -2266,12 +2280,19 @@ _PyObject_GC_Link(PyObject *op) !gcstate->collecting && !_PyErr_Occurred(tstate)) { - gcstate->collecting = 1; - gc_collect_generations(tstate); - gcstate->collecting = 0; + _Py_ScheduleGC(tstate->interp); } } +void +_Py_RunGC(PyThreadState *tstate) +{ + GCState *gcstate = &tstate->interp->gc; + gcstate->collecting = 1; + gc_collect_generations(tstate); + gcstate->collecting = 0; +} + static PyObject * gc_alloc(size_t basicsize, size_t presize) { @@ -2306,7 +2327,6 @@ _PyObject_GC_New(PyTypeObject *tp) PyVarObject * _PyObject_GC_NewVar(PyTypeObject *tp, Py_ssize_t nitems) { - size_t size; PyVarObject *op; if (nitems < 0) { @@ -2314,7 +2334,7 @@ _PyObject_GC_NewVar(PyTypeObject *tp, Py_ssize_t nitems) return NULL; } size_t presize = _PyType_PreHeaderSize(tp); - size = _PyObject_VAR_SIZE(tp, nitems); + size_t size = _PyObject_VAR_SIZE(tp, nitems); op = (PyVarObject *)gc_alloc(size, presize); if (op == NULL) { return NULL; @@ -2323,20 +2343,34 @@ _PyObject_GC_NewVar(PyTypeObject *tp, Py_ssize_t nitems) return op; } +PyObject * +PyUnstable_Object_GC_NewWithExtraData(PyTypeObject *tp, size_t extra_size) +{ + size_t presize = _PyType_PreHeaderSize(tp); + PyObject *op = gc_alloc(_PyObject_SIZE(tp) + extra_size, presize); + if (op == NULL) { + return NULL; + } + memset(op, 0, _PyObject_SIZE(tp) + extra_size); + _PyObject_Init(op, tp); + return op; +} + PyVarObject * _PyObject_GC_Resize(PyVarObject *op, Py_ssize_t nitems) { const size_t basicsize = _PyObject_VAR_SIZE(Py_TYPE(op), nitems); + const size_t presize = _PyType_PreHeaderSize(((PyObject *)op)->ob_type); _PyObject_ASSERT((PyObject *)op, !_PyObject_GC_IS_TRACKED(op)); - if (basicsize > PY_SSIZE_T_MAX - sizeof(PyGC_Head)) { + if (basicsize > (size_t)PY_SSIZE_T_MAX - presize) { return (PyVarObject *)PyErr_NoMemory(); } - - PyGC_Head *g = AS_GC(op); - g = (PyGC_Head *)PyObject_Realloc(g, sizeof(PyGC_Head) + basicsize); - if (g == NULL) + char *mem = (char *)op - presize; + mem = (char *)PyObject_Realloc(mem, presize + basicsize); + if (mem == NULL) { return (PyVarObject *)PyErr_NoMemory(); - op = (PyVarObject *) FROM_GC(g); + } + op = (PyVarObject *) (mem + presize); Py_SET_SIZE(op, nitems); return op; } @@ -2380,3 +2414,27 @@ PyObject_GC_IsFinalized(PyObject *obj) } return 0; } + +void +PyUnstable_GC_VisitObjects(gcvisitobjects_t callback, void *arg) +{ + size_t i; + GCState *gcstate = get_gc_state(); + int origenstate = gcstate->enabled; + gcstate->enabled = 0; + for (i = 0; i < NUM_GENERATIONS; i++) { + PyGC_Head *gc_list, *gc; + gc_list = GEN_HEAD(gcstate, i); + for (gc = GC_NEXT(gc_list); gc != gc_list; gc = GC_NEXT(gc)) { + PyObject *op = FROM_GC(gc); + Py_INCREF(op); + int res = callback(op, arg); + Py_DECREF(op); + if (!res) { + goto done; + } + } + } +done: + gcstate->enabled = origenstate; +} diff --git a/Modules/getaddrinfo.c b/Modules/getaddrinfo.c index 0b4620ed..f1c28d7d 100644 --- a/Modules/getaddrinfo.c +++ b/Modules/getaddrinfo.c @@ -342,7 +342,11 @@ getaddrinfo(const char*hostname, const char*servname, pai->ai_socktype = SOCK_DGRAM; pai->ai_protocol = IPPROTO_UDP; } - port = htons((u_short)atoi(servname)); + long maybe_port = strtol(servname, NULL, 10); + if (maybe_port < 0 || maybe_port > 0xffff) { + ERR(EAI_SERVICE); + } + port = htons((u_short)maybe_port); } else { struct servent *sp; const char *proto; diff --git a/Modules/getbuildinfo.c b/Modules/getbuildinfo.c index 7cb7397a..a24750b7 100644 --- a/Modules/getbuildinfo.c +++ b/Modules/getbuildinfo.c @@ -31,12 +31,18 @@ #define GITBRANCH "" #endif +static int initialized = 0; +static char buildinfo[50 + sizeof(GITVERSION) + + ((sizeof(GITTAG) > sizeof(GITBRANCH)) ? + sizeof(GITTAG) : sizeof(GITBRANCH))]; + const char * Py_GetBuildInfo(void) { - static char buildinfo[50 + sizeof(GITVERSION) + - ((sizeof(GITTAG) > sizeof(GITBRANCH)) ? - sizeof(GITTAG) : sizeof(GITBRANCH))]; + if (initialized) { + return buildinfo; + } + initialized = 1; const char *revision = _Py_gitversion(); const char *sep = *revision ? ":" : ""; const char *gitid = _Py_gitidentifier(); diff --git a/Modules/getpath.c b/Modules/getpath.c index ceacf36d..b9914a0c 100644 --- a/Modules/getpath.c +++ b/Modules/getpath.c @@ -125,8 +125,7 @@ getpath_isabs(PyObject *Py_UNUSED(self), PyObject *args) r = _Py_isabs(path) ? Py_True : Py_False; PyMem_Free((void *)path); } - Py_XINCREF(r); - return r; + return Py_XNewRef(r); } @@ -153,11 +152,10 @@ getpath_hassuffix(PyObject *Py_UNUSED(self), PyObject *args) wcscmp(&path[len - suffixLen], suffix) != 0 #endif ) { - r = Py_False; + r = Py_NewRef(Py_False); } else { - r = Py_True; + r = Py_NewRef(Py_True); } - Py_INCREF(r); PyMem_Free((void *)suffix); } PyMem_Free((void *)path); @@ -187,8 +185,7 @@ getpath_isdir(PyObject *Py_UNUSED(self), PyObject *args) #endif PyMem_Free((void *)path); } - Py_XINCREF(r); - return r; + return Py_XNewRef(r); } @@ -213,8 +210,7 @@ getpath_isfile(PyObject *Py_UNUSED(self), PyObject *args) #endif PyMem_Free((void *)path); } - Py_XINCREF(r); - return r; + return Py_XNewRef(r); } @@ -231,12 +227,11 @@ getpath_isxfile(PyObject *Py_UNUSED(self), PyObject *args) path = PyUnicode_AsWideCharString(pathobj, &cchPath); if (path) { #ifdef MS_WINDOWS - const wchar_t *ext; DWORD attr = GetFileAttributesW(path); r = (attr != INVALID_FILE_ATTRIBUTES) && !(attr & FILE_ATTRIBUTE_DIRECTORY) && - SUCCEEDED(PathCchFindExtension(path, cchPath + 1, &ext)) && - (CompareStringOrdinal(ext, -1, L".exe", -1, 1 /* ignore case */) == CSTR_EQUAL) + (cchPath >= 4) && + (CompareStringOrdinal(path + cchPath - 4, -1, L".exe", -1, 1 /* ignore case */) == CSTR_EQUAL) ? Py_True : Py_False; #else struct stat st; @@ -247,8 +242,7 @@ getpath_isxfile(PyObject *Py_UNUSED(self), PyObject *args) #endif PyMem_Free((void *)path); } - Py_XINCREF(r); - return r; + return Py_XNewRef(r); } @@ -347,11 +341,12 @@ getpath_readlines(PyObject *Py_UNUSED(self), PyObject *args) return NULL; } FILE *fp = _Py_wfopen(path, L"rb"); - PyMem_Free((void *)path); if (!fp) { PyErr_SetFromErrno(PyExc_OSError); + PyMem_Free((void *)path); return NULL; } + PyMem_Free((void *)path); r = PyList_New(0); if (!r) { @@ -452,7 +447,10 @@ getpath_realpath(PyObject *Py_UNUSED(self) , PyObject *args) if (s) { *s = L'\0'; } - path2 = _Py_normpath(_Py_join_relfile(path, resolved), -1); + path2 = _Py_join_relfile(path, resolved); + if (path2) { + path2 = _Py_normpath(path2, -1); + } PyMem_RawFree((void *)path); path = path2; } @@ -488,8 +486,7 @@ done: goto done; } if (!S_ISLNK(st.st_mode)) { - Py_INCREF(pathobj); - r = pathobj; + r = Py_NewRef(pathobj); goto done; } wchar_t resolved[MAXPATHLEN+1]; @@ -504,8 +501,7 @@ done: return r; #endif - Py_INCREF(pathobj); - return pathobj; + return Py_NewRef(pathobj); } @@ -591,8 +587,7 @@ wchar_to_dict(PyObject *dict, const char *key, const wchar_t *s) return 0; } } else { - u = Py_None; - Py_INCREF(u); + u = Py_NewRef(Py_None); } r = PyDict_SetItemString(dict, key, u) == 0; Py_DECREF(u); @@ -617,8 +612,7 @@ decode_to_dict(PyObject *dict, const char *key, const char *s) return 0; } } else { - u = Py_None; - Py_INCREF(u); + u = Py_NewRef(Py_None); } r = PyDict_SetItemString(dict, key, u) == 0; Py_DECREF(u); @@ -755,10 +749,12 @@ static int library_to_dict(PyObject *dict, const char *key) { #ifdef MS_WINDOWS +#ifdef Py_ENABLE_SHARED extern HMODULE PyWin_DLLhModule; if (PyWin_DLLhModule) { return winmodule_to_dict(dict, key, PyWin_DLLhModule); } +#endif #elif defined(WITH_NEXT_FRAMEWORK) static char modPath[MAXPATHLEN + 1]; static int modPathInitialized = -1; diff --git a/Modules/getpath.py b/Modules/getpath.py index 74f918cf..9913fcba 100644 --- a/Modules/getpath.py +++ b/Modules/getpath.py @@ -441,7 +441,7 @@ if not real_executable_dir: # ****************************************************************************** # The contents of an optional ._pth file are used to totally override -# sys.path calcualation. Its presence also implies isolated mode and +# sys.path calculation. Its presence also implies isolated mode and # no-site (unless explicitly requested) pth = None pth_dir = None diff --git a/Modules/grpmodule.c b/Modules/grpmodule.c index f6298ca0..f5709296 100644 --- a/Modules/grpmodule.c +++ b/Modules/grpmodule.c @@ -65,8 +65,14 @@ mkgrent(PyObject *module, struct group *p) Py_DECREF(v); return NULL; } - for (member = p->gr_mem; *member != NULL; member++) { - PyObject *x = PyUnicode_DecodeFSDefault(*member); + for (member = p->gr_mem; ; member++) { + char *group_member; + // member can be misaligned + memcpy(&group_member, member, sizeof(group_member)); + if (group_member == NULL) { + break; + } + PyObject *x = PyUnicode_DecodeFSDefault(group_member); if (x == NULL || PyList_Append(w, x) != 0) { Py_XDECREF(x); Py_DECREF(w); @@ -327,6 +333,7 @@ grpmodule_exec(PyObject *module) static PyModuleDef_Slot grpmodule_slots[] = { {Py_mod_exec, grpmodule_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; diff --git a/Modules/hashlib.h b/Modules/hashlib.h index 56ae7a5e..a8bad9dd 100644 --- a/Modules/hashlib.h +++ b/Modules/hashlib.h @@ -37,6 +37,13 @@ * LEAVE_HASHLIB block or explicitly acquire and release the lock inside * a PY_BEGIN / END_ALLOW_THREADS block if they wish to release the GIL for * an operation. + * + * These only drop the GIL if the lock acquisition itself is likely to + * block. Thus the non-blocking acquire gating the GIL release for a + * blocking lock acquisition. The intent of these macros is to surround + * the assumed always "fast" operations that you aren't releasing the + * GIL around. Otherwise use code similar to what you see in hash + * function update() methods. */ #include "pythread.h" @@ -53,7 +60,7 @@ PyThread_release_lock((obj)->lock); \ } -/* TODO(gps): We should probably make this a module or EVPobject attribute +/* TODO(gpshead): We should make this a module or class attribute * to allow the user to optimize based on the platform they're using. */ #define HASHLIB_GIL_MINSIZE 2048 diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c index d5cdfc59..ae63bae7 100644 --- a/Modules/itertoolsmodule.c +++ b/Modules/itertoolsmodule.c @@ -2,54 +2,262 @@ #include "Python.h" #include "pycore_call.h" // _PyObject_CallNoArgs() #include "pycore_long.h" // _PyLong_GetZero() +#include "pycore_moduleobject.h" // _PyModule_GetState() +#include "pycore_typeobject.h" // _PyType_GetModuleState() #include "pycore_object.h" // _PyObject_GC_TRACK() #include "pycore_tuple.h" // _PyTuple_ITEMS() +#include "structmember.h" // PyMemberDef #include <stddef.h> // offsetof() /* Itertools module written and maintained by Raymond D. Hettinger <python@rcn.com> */ +typedef struct { + PyTypeObject *accumulate_type; + PyTypeObject *batched_type; + PyTypeObject *chain_type; + PyTypeObject *combinations_type; + PyTypeObject *compress_type; + PyTypeObject *count_type; + PyTypeObject *cwr_type; + PyTypeObject *cycle_type; + PyTypeObject *dropwhile_type; + PyTypeObject *filterfalse_type; + PyTypeObject *groupby_type; + PyTypeObject *_grouper_type; + PyTypeObject *islice_type; + PyTypeObject *pairwise_type; + PyTypeObject *permutations_type; + PyTypeObject *product_type; + PyTypeObject *repeat_type; + PyTypeObject *starmap_type; + PyTypeObject *takewhile_type; + PyTypeObject *tee_type; + PyTypeObject *teedataobject_type; + PyTypeObject *ziplongest_type; +} itertools_state; + +static inline itertools_state * +get_module_state(PyObject *mod) +{ + void *state = _PyModule_GetState(mod); + assert(state != NULL); + return (itertools_state *)state; +} + +static inline itertools_state * +get_module_state_by_cls(PyTypeObject *cls) +{ + void *state = _PyType_GetModuleState(cls); + assert(state != NULL); + return (itertools_state *)state; +} + +static struct PyModuleDef itertoolsmodule; + +static inline itertools_state * +find_state_by_type(PyTypeObject *tp) +{ + PyObject *mod = PyType_GetModuleByDef(tp, &itertoolsmodule); + assert(mod != NULL); + return get_module_state(mod); +} + /*[clinic input] module itertools -class itertools.groupby "groupbyobject *" "&groupby_type" -class itertools._grouper "_grouperobject *" "&_grouper_type" -class itertools.teedataobject "teedataobject *" "&teedataobject_type" -class itertools._tee "teeobject *" "&tee_type" -class itertools.cycle "cycleobject *" "&cycle_type" -class itertools.dropwhile "dropwhileobject *" "&dropwhile_type" -class itertools.takewhile "takewhileobject *" "&takewhile_type" -class itertools.starmap "starmapobject *" "&starmap_type" -class itertools.chain "chainobject *" "&chain_type" -class itertools.combinations "combinationsobject *" "&combinations_type" -class itertools.combinations_with_replacement "cwr_object *" "&cwr_type" -class itertools.permutations "permutationsobject *" "&permutations_type" -class itertools.accumulate "accumulateobject *" "&accumulate_type" -class itertools.compress "compressobject *" "&compress_type" -class itertools.filterfalse "filterfalseobject *" "&filterfalse_type" -class itertools.count "countobject *" "&count_type" -class itertools.pairwise "pairwiseobject *" "&pairwise_type" +class itertools.groupby "groupbyobject *" "clinic_state()->groupby_type" +class itertools._grouper "_grouperobject *" "clinic_state()->_grouper_type" +class itertools.teedataobject "teedataobject *" "clinic_state()->teedataobject_type" +class itertools._tee "teeobject *" "clinic_state()->tee_type" +class itertools.batched "batchedobject *" "clinic_state()->batched_type" +class itertools.cycle "cycleobject *" "clinic_state()->cycle_type" +class itertools.dropwhile "dropwhileobject *" "clinic_state()->dropwhile_type" +class itertools.takewhile "takewhileobject *" "clinic_state()->takewhile_type" +class itertools.starmap "starmapobject *" "clinic_state()->starmap_type" +class itertools.chain "chainobject *" "clinic_state()->chain_type" +class itertools.combinations "combinationsobject *" "clinic_state()->combinations_type" +class itertools.combinations_with_replacement "cwr_object *" "clinic_state()->cwr_type" +class itertools.permutations "permutationsobject *" "clinic_state()->permutations_type" +class itertools.accumulate "accumulateobject *" "clinic_state()->accumulate_type" +class itertools.compress "compressobject *" "clinic_state()->compress_type" +class itertools.filterfalse "filterfalseobject *" "clinic_state()->filterfalse_type" +class itertools.count "countobject *" "clinic_state()->count_type" +class itertools.pairwise "pairwiseobject *" "clinic_state()->pairwise_type" [clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=6498ed21fbe1bf94]*/ - -static PyTypeObject groupby_type; -static PyTypeObject _grouper_type; -static PyTypeObject teedataobject_type; -static PyTypeObject tee_type; -static PyTypeObject cycle_type; -static PyTypeObject dropwhile_type; -static PyTypeObject takewhile_type; -static PyTypeObject starmap_type; -static PyTypeObject combinations_type; -static PyTypeObject cwr_type; -static PyTypeObject permutations_type; -static PyTypeObject accumulate_type; -static PyTypeObject compress_type; -static PyTypeObject filterfalse_type; -static PyTypeObject count_type; -static PyTypeObject pairwise_type; +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=aa48fe4de9d4080f]*/ +#define clinic_state() (find_state_by_type(type)) +#define clinic_state_by_cls() (get_module_state_by_cls(base_tp)) #include "clinic/itertoolsmodule.c.h" +#undef clinic_state_by_cls +#undef clinic_state + +/* Deprecation of pickle support: GH-101588 *********************************/ + +#define ITERTOOL_PICKLE_DEPRECATION \ + if (PyErr_WarnEx( \ + PyExc_DeprecationWarning, \ + "Pickle, copy, and deepcopy support will be " \ + "removed from itertools in Python 3.14.", 1) < 0) { \ + return NULL; \ + } + +/* batched object ************************************************************/ + +/* Note: The built-in zip() function includes a "strict" argument + that was needed because that function would silently truncate data, + and there was no easy way for a user to detect the data loss. + The same reasoning does not apply to batched() which never drops data. + Instead, batched() produces a shorter tuple which can be handled + as the user sees fit. If requested, it would be reasonable to add + "fillvalue" support which had demonstrated value in zip_longest(). + For now, the API is kept simple and clean. + */ + +typedef struct { + PyObject_HEAD + PyObject *it; + Py_ssize_t batch_size; +} batchedobject; + +/*[clinic input] +@classmethod +itertools.batched.__new__ as batched_new + iterable: object + n: Py_ssize_t +Batch data into tuples of length n. The last batch may be shorter than n. + +Loops over the input iterable and accumulates data into tuples +up to size n. The input is consumed lazily, just enough to +fill a batch. The result is yielded as soon as a batch is full +or when the input iterable is exhausted. + + >>> for batch in batched('ABCDEFG', 3): + ... print(batch) + ... + ('A', 'B', 'C') + ('D', 'E', 'F') + ('G',) + +[clinic start generated code]*/ + +static PyObject * +batched_new_impl(PyTypeObject *type, PyObject *iterable, Py_ssize_t n) +/*[clinic end generated code: output=7ebc954d655371b6 input=ffd70726927c5129]*/ +{ + PyObject *it; + batchedobject *bo; + + if (n < 1) { + /* We could define the n==0 case to return an empty iterator + but that is at odds with the idea that batching should + never throw-away input data. + */ + PyErr_SetString(PyExc_ValueError, "n must be at least one"); + return NULL; + } + it = PyObject_GetIter(iterable); + if (it == NULL) { + return NULL; + } + + /* create batchedobject structure */ + bo = (batchedobject *)type->tp_alloc(type, 0); + if (bo == NULL) { + Py_DECREF(it); + return NULL; + } + bo->batch_size = n; + bo->it = it; + return (PyObject *)bo; +} + +static void +batched_dealloc(batchedobject *bo) +{ + PyTypeObject *tp = Py_TYPE(bo); + PyObject_GC_UnTrack(bo); + Py_XDECREF(bo->it); + tp->tp_free(bo); + Py_DECREF(tp); +} + +static int +batched_traverse(batchedobject *bo, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(bo)); + Py_VISIT(bo->it); + return 0; +} + +static PyObject * +batched_next(batchedobject *bo) +{ + Py_ssize_t i; + Py_ssize_t n = bo->batch_size; + PyObject *it = bo->it; + PyObject *item; + PyObject *result; + + if (it == NULL) { + return NULL; + } + result = PyTuple_New(n); + if (result == NULL) { + return NULL; + } + iternextfunc iternext = *Py_TYPE(it)->tp_iternext; + PyObject **items = _PyTuple_ITEMS(result); + for (i=0 ; i < n ; i++) { + item = iternext(it); + if (item == NULL) { + goto null_item; + } + items[i] = item; + } + return result; + + null_item: + if (PyErr_Occurred()) { + if (!PyErr_ExceptionMatches(PyExc_StopIteration)) { + /* Input raised an exception other than StopIteration */ + Py_CLEAR(bo->it); + Py_DECREF(result); + return NULL; + } + PyErr_Clear(); + } + if (i == 0) { + Py_CLEAR(bo->it); + Py_DECREF(result); + return NULL; + } + _PyTuple_Resize(&result, i); + return result; +} + +static PyType_Slot batched_slots[] = { + {Py_tp_dealloc, batched_dealloc}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_doc, (void *)batched_new__doc__}, + {Py_tp_traverse, batched_traverse}, + {Py_tp_iter, PyObject_SelfIter}, + {Py_tp_iternext, batched_next}, + {Py_tp_alloc, PyType_GenericAlloc}, + {Py_tp_new, batched_new}, + {Py_tp_free, PyObject_GC_Del}, + {0, NULL}, +}; + +static PyType_Spec batched_spec = { + .name = "itertools.batched", + .basicsize = sizeof(batchedobject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = batched_slots, +}; + /* pairwise object ***********************************************************/ @@ -94,15 +302,18 @@ pairwise_new_impl(PyTypeObject *type, PyObject *iterable) static void pairwise_dealloc(pairwiseobject *po) { + PyTypeObject *tp = Py_TYPE(po); PyObject_GC_UnTrack(po); Py_XDECREF(po->it); Py_XDECREF(po->old); - Py_TYPE(po)->tp_free(po); + tp->tp_free(po); + Py_DECREF(tp); } static int pairwise_traverse(pairwiseobject *po, visitproc visit, void *arg) { + Py_VISIT(Py_TYPE(po)); Py_VISIT(po->it); Py_VISIT(po->old); return 0; @@ -137,48 +348,25 @@ pairwise_next(pairwiseobject *po) return result; } -static PyTypeObject pairwise_type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "itertools.pairwise", /* tp_name */ - sizeof(pairwiseobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)pairwise_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ - pairwise_new__doc__, /* tp_doc */ - (traverseproc)pairwise_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)pairwise_next, /* 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 */ - 0, /* tp_init */ - PyType_GenericAlloc, /* tp_alloc */ - pairwise_new, /* tp_new */ - PyObject_GC_Del, /* tp_free */ +static PyType_Slot pairwise_slots[] = { + {Py_tp_dealloc, pairwise_dealloc}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_doc, (void *)pairwise_new__doc__}, + {Py_tp_traverse, pairwise_traverse}, + {Py_tp_iter, PyObject_SelfIter}, + {Py_tp_iternext, pairwise_next}, + {Py_tp_alloc, PyType_GenericAlloc}, + {Py_tp_new, pairwise_new}, + {Py_tp_free, PyObject_GC_Del}, + {0, NULL}, +}; + +static PyType_Spec pairwise_spec = { + .name = "itertools.pairwise", + .basicsize = sizeof(pairwiseobject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = pairwise_slots, }; @@ -192,6 +380,7 @@ typedef struct { PyObject *currkey; PyObject *currvalue; const void *currgrouper; /* borrowed reference */ + itertools_state *state; } groupbyobject; static PyObject *_grouper_create(groupbyobject *, PyObject *); @@ -222,31 +411,34 @@ itertools_groupby_impl(PyTypeObject *type, PyObject *it, PyObject *keyfunc) gbo->tgtkey = NULL; gbo->currkey = NULL; gbo->currvalue = NULL; - gbo->keyfunc = keyfunc; - Py_INCREF(keyfunc); + gbo->keyfunc = Py_NewRef(keyfunc); gbo->it = PyObject_GetIter(it); if (gbo->it == NULL) { Py_DECREF(gbo); return NULL; } + gbo->state = find_state_by_type(type); return (PyObject *)gbo; } static void groupby_dealloc(groupbyobject *gbo) { + PyTypeObject *tp = Py_TYPE(gbo); PyObject_GC_UnTrack(gbo); Py_XDECREF(gbo->it); Py_XDECREF(gbo->keyfunc); Py_XDECREF(gbo->tgtkey); Py_XDECREF(gbo->currkey); Py_XDECREF(gbo->currvalue); - Py_TYPE(gbo)->tp_free(gbo); + tp->tp_free(gbo); + Py_DECREF(tp); } static int groupby_traverse(groupbyobject *gbo, visitproc visit, void *arg) { + Py_VISIT(Py_TYPE(gbo)); Py_VISIT(gbo->it); Py_VISIT(gbo->keyfunc); Py_VISIT(gbo->tgtkey); @@ -265,8 +457,7 @@ groupby_step(groupbyobject *gbo) return -1; if (gbo->keyfunc == Py_None) { - newkey = newvalue; - Py_INCREF(newvalue); + newkey = Py_NewRef(newvalue); } else { newkey = PyObject_CallOneArg(gbo->keyfunc, newvalue); if (newkey == NULL) { @@ -325,6 +516,7 @@ groupby_reduce(groupbyobject *lz, PyObject *Py_UNUSED(ignored)) /* reduce as a 'new' call with an optional 'setstate' if groupby * has started */ + ITERTOOL_PICKLE_DEPRECATION; PyObject *value; if (lz->tgtkey && lz->currkey && lz->currvalue) value = Py_BuildValue("O(OO)(OOO)", Py_TYPE(lz), @@ -341,6 +533,7 @@ PyDoc_STRVAR(reduce_doc, "Return state information for pickling."); static PyObject * groupby_setstate(groupbyobject *lz, PyObject *state) { + ITERTOOL_PICKLE_DEPRECATION; PyObject *currkey, *currvalue, *tgtkey; if (!PyTuple_Check(state)) { PyErr_SetString(PyExc_TypeError, "state is not a tuple"); @@ -368,50 +561,26 @@ static PyMethodDef groupby_methods[] = { {NULL, NULL} /* sentinel */ }; -static PyTypeObject groupby_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "itertools.groupby", /* tp_name */ - sizeof(groupbyobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)groupby_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ - itertools_groupby__doc__, /* tp_doc */ - (traverseproc)groupby_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)groupby_next, /* tp_iternext */ - groupby_methods, /* 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 */ - 0, /* tp_init */ - 0, /* tp_alloc */ - itertools_groupby, /* tp_new */ - PyObject_GC_Del, /* tp_free */ +static PyType_Slot groupby_slots[] = { + {Py_tp_dealloc, groupby_dealloc}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_doc, (void *)itertools_groupby__doc__}, + {Py_tp_traverse, groupby_traverse}, + {Py_tp_iter, PyObject_SelfIter}, + {Py_tp_iternext, groupby_next}, + {Py_tp_methods, groupby_methods}, + {Py_tp_new, itertools_groupby}, + {Py_tp_free, PyObject_GC_Del}, + {0, NULL}, }; +static PyType_Spec groupby_spec = { + .name = "itertools.groupby", + .basicsize= sizeof(groupbyobject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = groupby_slots, +}; /* _grouper object (internal) ************************************************/ @@ -425,7 +594,7 @@ typedef struct { @classmethod itertools._grouper.__new__ - parent: object(subclass_of='&groupby_type') + parent: object(subclass_of='clinic_state_by_cls()->groupby_type') tgtkey: object / [clinic start generated code]*/ @@ -433,7 +602,7 @@ itertools._grouper.__new__ static PyObject * itertools__grouper_impl(PyTypeObject *type, PyObject *parent, PyObject *tgtkey) -/*[clinic end generated code: output=462efb1cdebb5914 input=dc180d7771fc8c59]*/ +/*[clinic end generated code: output=462efb1cdebb5914 input=afe05eb477118f12]*/ { return _grouper_create((groupbyobject*) parent, tgtkey); } @@ -441,15 +610,12 @@ itertools__grouper_impl(PyTypeObject *type, PyObject *parent, static PyObject * _grouper_create(groupbyobject *parent, PyObject *tgtkey) { - _grouperobject *igo; - - igo = PyObject_GC_New(_grouperobject, &_grouper_type); + itertools_state *state = parent->state; + _grouperobject *igo = PyObject_GC_New(_grouperobject, state->_grouper_type); if (igo == NULL) return NULL; - igo->parent = (PyObject *)parent; - Py_INCREF(parent); - igo->tgtkey = tgtkey; - Py_INCREF(tgtkey); + igo->parent = Py_NewRef(parent); + igo->tgtkey = Py_NewRef(tgtkey); parent->currgrouper = igo; /* borrowed reference */ PyObject_GC_Track(igo); @@ -459,15 +625,18 @@ _grouper_create(groupbyobject *parent, PyObject *tgtkey) static void _grouper_dealloc(_grouperobject *igo) { + PyTypeObject *tp = Py_TYPE(igo); PyObject_GC_UnTrack(igo); Py_DECREF(igo->parent); Py_DECREF(igo->tgtkey); PyObject_GC_Del(igo); + Py_DECREF(tp); } static int _grouper_traverse(_grouperobject *igo, visitproc visit, void *arg) { + Py_VISIT(Py_TYPE(igo)); Py_VISIT(igo->parent); Py_VISIT(igo->tgtkey); return 0; @@ -503,6 +672,7 @@ _grouper_next(_grouperobject *igo) static PyObject * _grouper_reduce(_grouperobject *lz, PyObject *Py_UNUSED(ignored)) { + ITERTOOL_PICKLE_DEPRECATION; if (((groupbyobject *)lz->parent)->currgrouper != lz) { return Py_BuildValue("N(())", _PyEval_GetBuiltin(&_Py_ID(iter))); } @@ -515,48 +685,24 @@ static PyMethodDef _grouper_methods[] = { {NULL, NULL} /* sentinel */ }; +static PyType_Slot _grouper_slots[] = { + {Py_tp_dealloc, _grouper_dealloc}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_traverse, _grouper_traverse}, + {Py_tp_iter, PyObject_SelfIter}, + {Py_tp_iternext, _grouper_next}, + {Py_tp_methods, _grouper_methods}, + {Py_tp_new, itertools__grouper}, + {Py_tp_free, PyObject_GC_Del}, + {0, NULL}, +}; -static PyTypeObject _grouper_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "itertools._grouper", /* tp_name */ - sizeof(_grouperobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)_grouper_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ - 0, /* tp_doc */ - (traverseproc)_grouper_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)_grouper_next, /* tp_iternext */ - _grouper_methods, /* 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 */ - 0, /* tp_init */ - 0, /* tp_alloc */ - itertools__grouper, /* tp_new */ - PyObject_GC_Del, /* tp_free */ +static PyType_Spec _grouper_spec = { + .name = "itertools._grouper", + .basicsize = sizeof(_grouperobject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = _grouper_slots, }; @@ -586,33 +732,32 @@ typedef struct { teedataobject *dataobj; int index; /* 0 <= index <= LINKCELLS */ PyObject *weakreflist; + itertools_state *state; } teeobject; static PyObject * -teedataobject_newinternal(PyObject *it) +teedataobject_newinternal(itertools_state *state, PyObject *it) { teedataobject *tdo; - tdo = PyObject_GC_New(teedataobject, &teedataobject_type); + tdo = PyObject_GC_New(teedataobject, state->teedataobject_type); if (tdo == NULL) return NULL; tdo->running = 0; tdo->numread = 0; tdo->nextlink = NULL; - Py_INCREF(it); - tdo->it = it; + tdo->it = Py_NewRef(it); PyObject_GC_Track(tdo); return (PyObject *)tdo; } static PyObject * -teedataobject_jumplink(teedataobject *tdo) +teedataobject_jumplink(itertools_state *state, teedataobject *tdo) { if (tdo->nextlink == NULL) - tdo->nextlink = teedataobject_newinternal(tdo->it); - Py_XINCREF(tdo->nextlink); - return tdo->nextlink; + tdo->nextlink = teedataobject_newinternal(state, tdo->it); + return Py_XNewRef(tdo->nextlink); } static PyObject * @@ -639,8 +784,7 @@ teedataobject_getitem(teedataobject *tdo, int i) tdo->numread++; tdo->values[i] = value; } - Py_INCREF(value); - return value; + return Py_NewRef(value); } static int @@ -648,6 +792,7 @@ teedataobject_traverse(teedataobject *tdo, visitproc visit, void * arg) { int i; + Py_VISIT(Py_TYPE(tdo)); Py_VISIT(tdo->it); for (i = 0; i < tdo->numread; i++) Py_VISIT(tdo->values[i]); @@ -656,14 +801,13 @@ teedataobject_traverse(teedataobject *tdo, visitproc visit, void * arg) } static void -teedataobject_safe_decref(PyObject *obj) +teedataobject_safe_decref(PyObject *obj, PyTypeObject *tdo_type) { - while (obj && Py_IS_TYPE(obj, &teedataobject_type) && + while (obj && Py_IS_TYPE(obj, tdo_type) && Py_REFCNT(obj) == 1) { PyObject *nextlink = ((teedataobject *)obj)->nextlink; ((teedataobject *)obj)->nextlink = NULL; - Py_DECREF(obj); - obj = nextlink; + Py_SETREF(obj, nextlink); } Py_XDECREF(obj); } @@ -679,21 +823,25 @@ teedataobject_clear(teedataobject *tdo) Py_CLEAR(tdo->values[i]); tmp = tdo->nextlink; tdo->nextlink = NULL; - teedataobject_safe_decref(tmp); + itertools_state *state = get_module_state_by_cls(Py_TYPE(tdo)); + teedataobject_safe_decref(tmp, state->teedataobject_type); return 0; } static void teedataobject_dealloc(teedataobject *tdo) { + PyTypeObject *tp = Py_TYPE(tdo); PyObject_GC_UnTrack(tdo); teedataobject_clear(tdo); PyObject_GC_Del(tdo); + Py_DECREF(tp); } static PyObject * teedataobject_reduce(teedataobject *tdo, PyObject *Py_UNUSED(ignored)) { + ITERTOOL_PICKLE_DEPRECATION; int i; /* create a temporary list of already iterated values */ PyObject *values = PyList_New(tdo->numread); @@ -727,9 +875,10 @@ itertools_teedataobject_impl(PyTypeObject *type, PyObject *it, teedataobject *tdo; Py_ssize_t i, len; - assert(type == &teedataobject_type); + itertools_state *state = get_module_state_by_cls(type); + assert(type == state->teedataobject_type); - tdo = (teedataobject *)teedataobject_newinternal(it); + tdo = (teedataobject *)teedataobject_newinternal(state, it); if (!tdo) return NULL; @@ -745,11 +894,10 @@ itertools_teedataobject_impl(PyTypeObject *type, PyObject *it, if (len == LINKCELLS) { if (next != Py_None) { - if (!Py_IS_TYPE(next, &teedataobject_type)) + if (!Py_IS_TYPE(next, state->teedataobject_type)) goto err; assert(tdo->nextlink == NULL); - Py_INCREF(next); - tdo->nextlink = next; + tdo->nextlink = Py_NewRef(next); } } else { if (next != Py_None) @@ -769,47 +917,24 @@ static PyMethodDef teedataobject_methods[] = { {NULL, NULL} /* sentinel */ }; -static PyTypeObject teedataobject_type = { - PyVarObject_HEAD_INIT(0, 0) /* Must fill in type value later */ - "itertools._tee_dataobject", /* tp_name */ - sizeof(teedataobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)teedataobject_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ - itertools_teedataobject__doc__, /* tp_doc */ - (traverseproc)teedataobject_traverse, /* tp_traverse */ - (inquiry)teedataobject_clear, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - teedataobject_methods, /* 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 */ - 0, /* tp_init */ - 0, /* tp_alloc */ - itertools_teedataobject, /* tp_new */ - PyObject_GC_Del, /* tp_free */ +static PyType_Slot teedataobject_slots[] = { + {Py_tp_dealloc, teedataobject_dealloc}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_doc, (void *)itertools_teedataobject__doc__}, + {Py_tp_traverse, teedataobject_traverse}, + {Py_tp_clear, teedataobject_clear}, + {Py_tp_methods, teedataobject_methods}, + {Py_tp_new, itertools_teedataobject}, + {Py_tp_free, PyObject_GC_Del}, + {0, NULL}, +}; + +static PyType_Spec teedataobject_spec = { + .name = "itertools._tee_dataobject", + .basicsize = sizeof(teedataobject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = teedataobject_slots, }; @@ -819,7 +944,7 @@ tee_next(teeobject *to) PyObject *value, *link; if (to->index >= LINKCELLS) { - link = teedataobject_jumplink(to->dataobj); + link = teedataobject_jumplink(to->state, to->dataobj); if (link == NULL) return NULL; Py_SETREF(to->dataobj, (teedataobject *)link); @@ -835,6 +960,7 @@ tee_next(teeobject *to) static int tee_traverse(teeobject *to, visitproc visit, void *arg) { + Py_VISIT(Py_TYPE(to)); Py_VISIT((PyObject *)to->dataobj); return 0; } @@ -844,13 +970,13 @@ tee_copy(teeobject *to, PyObject *Py_UNUSED(ignored)) { teeobject *newto; - newto = PyObject_GC_New(teeobject, &tee_type); + newto = PyObject_GC_New(teeobject, Py_TYPE(to)); if (newto == NULL) return NULL; - Py_INCREF(to->dataobj); - newto->dataobj = to->dataobj; + newto->dataobj = (teedataobject*)Py_NewRef(to->dataobj); newto->index = to->index; newto->weakreflist = NULL; + newto->state = to->state; PyObject_GC_Track(newto); return (PyObject *)newto; } @@ -858,7 +984,7 @@ tee_copy(teeobject *to, PyObject *Py_UNUSED(ignored)) PyDoc_STRVAR(teecopy_doc, "Returns an independent iterator."); static PyObject * -tee_fromiterable(PyObject *iterable) +tee_fromiterable(itertools_state *state, PyObject *iterable) { teeobject *to; PyObject *it; @@ -866,17 +992,17 @@ tee_fromiterable(PyObject *iterable) it = PyObject_GetIter(iterable); if (it == NULL) return NULL; - if (PyObject_TypeCheck(it, &tee_type)) { + if (PyObject_TypeCheck(it, state->tee_type)) { to = (teeobject *)tee_copy((teeobject *)it, NULL); goto done; } - PyObject *dataobj = teedataobject_newinternal(it); + PyObject *dataobj = teedataobject_newinternal(state, it); if (!dataobj) { to = NULL; goto done; } - to = PyObject_GC_New(teeobject, &tee_type); + to = PyObject_GC_New(teeobject, state->tee_type); if (to == NULL) { Py_DECREF(dataobj); goto done; @@ -884,6 +1010,7 @@ tee_fromiterable(PyObject *iterable) to->dataobj = (teedataobject *)dataobj; to->index = 0; to->weakreflist = NULL; + to->state = state; PyObject_GC_Track(to); done: Py_DECREF(it); @@ -902,7 +1029,8 @@ static PyObject * itertools__tee_impl(PyTypeObject *type, PyObject *iterable) /*[clinic end generated code: output=b02d3fd26c810c3f input=adc0779d2afe37a2]*/ { - return tee_fromiterable(iterable); + itertools_state *state = get_module_state_by_cls(type); + return tee_fromiterable(state, iterable); } static int @@ -917,27 +1045,32 @@ tee_clear(teeobject *to) static void tee_dealloc(teeobject *to) { + PyTypeObject *tp = Py_TYPE(to); PyObject_GC_UnTrack(to); tee_clear(to); PyObject_GC_Del(to); + Py_DECREF(tp); } static PyObject * tee_reduce(teeobject *to, PyObject *Py_UNUSED(ignored)) { + ITERTOOL_PICKLE_DEPRECATION; return Py_BuildValue("O(())(Oi)", Py_TYPE(to), to->dataobj, to->index); } static PyObject * tee_setstate(teeobject *to, PyObject *state) { + ITERTOOL_PICKLE_DEPRECATION; teedataobject *tdo; int index; if (!PyTuple_Check(state)) { PyErr_SetString(PyExc_TypeError, "state is not a tuple"); return NULL; } - if (!PyArg_ParseTuple(state, "O!i", &teedataobject_type, &tdo, &index)) { + PyTypeObject *tdo_type = to->state->teedataobject_type; + if (!PyArg_ParseTuple(state, "O!i", tdo_type, &tdo, &index)) { return NULL; } if (index < 0 || index > LINKCELLS) { @@ -957,47 +1090,31 @@ static PyMethodDef tee_methods[] = { {NULL, NULL} /* sentinel */ }; -static PyTypeObject tee_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "itertools._tee", /* tp_name */ - sizeof(teeobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)tee_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 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_HAVE_GC, /* tp_flags */ - itertools__tee__doc__, /* tp_doc */ - (traverseproc)tee_traverse, /* tp_traverse */ - (inquiry)tee_clear, /* tp_clear */ - 0, /* tp_richcompare */ - offsetof(teeobject, weakreflist), /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)tee_next, /* tp_iternext */ - tee_methods, /* 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 */ - 0, /* tp_init */ - 0, /* tp_alloc */ - itertools__tee, /* tp_new */ - PyObject_GC_Del, /* tp_free */ +static PyMemberDef tee_members[] = { + {"__weaklistoffset__", T_PYSSIZET, offsetof(teeobject, weakreflist), READONLY}, + {NULL}, +}; + +static PyType_Slot tee_slots[] = { + {Py_tp_dealloc, tee_dealloc}, + {Py_tp_doc, (void *)itertools__tee__doc__}, + {Py_tp_traverse, tee_traverse}, + {Py_tp_clear, tee_clear}, + {Py_tp_iter, PyObject_SelfIter}, + {Py_tp_iternext, tee_next}, + {Py_tp_methods, tee_methods}, + {Py_tp_members, tee_members}, + {Py_tp_new, itertools__tee}, + {Py_tp_free, PyObject_GC_Del}, + {0, NULL}, +}; + +static PyType_Spec tee_spec = { + .name = "itertools._tee", + .basicsize = sizeof(teeobject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = tee_slots, }; /*[clinic input] @@ -1039,7 +1156,8 @@ itertools_tee_impl(PyObject *module, PyObject *iterable, Py_ssize_t n) copyable = it; } else { - copyable = tee_fromiterable(it); + itertools_state *state = get_module_state(module); + copyable = tee_fromiterable(state, it); Py_DECREF(it); if (copyable == NULL) { Py_DECREF(result); @@ -1123,15 +1241,18 @@ itertools_cycle_impl(PyTypeObject *type, PyObject *iterable) static void cycle_dealloc(cycleobject *lz) { + PyTypeObject *tp = Py_TYPE(lz); PyObject_GC_UnTrack(lz); Py_XDECREF(lz->it); Py_XDECREF(lz->saved); - Py_TYPE(lz)->tp_free(lz); + tp->tp_free(lz); + Py_DECREF(tp); } static int cycle_traverse(cycleobject *lz, visitproc visit, void *arg) { + Py_VISIT(Py_TYPE(lz)); Py_VISIT(lz->it); Py_VISIT(lz->saved); return 0; @@ -1164,13 +1285,13 @@ cycle_next(cycleobject *lz) lz->index++; if (lz->index >= PyList_GET_SIZE(lz->saved)) lz->index = 0; - Py_INCREF(item); - return item; + return Py_NewRef(item); } static PyObject * cycle_reduce(cycleobject *lz, PyObject *Py_UNUSED(ignored)) { + ITERTOOL_PICKLE_DEPRECATION; /* Create a new cycle with the iterator tuple, then set the saved state */ if (lz->it == NULL) { PyObject *it = PyObject_GetIter(lz->saved); @@ -1194,6 +1315,7 @@ cycle_reduce(cycleobject *lz, PyObject *Py_UNUSED(ignored)) static PyObject * cycle_setstate(cycleobject *lz, PyObject *state) { + ITERTOOL_PICKLE_DEPRECATION; PyObject *saved=NULL; int firstpass; if (!PyTuple_Check(state)) { @@ -1219,48 +1341,25 @@ static PyMethodDef cycle_methods[] = { {NULL, NULL} /* sentinel */ }; -static PyTypeObject cycle_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "itertools.cycle", /* tp_name */ - sizeof(cycleobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)cycle_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ - itertools_cycle__doc__, /* tp_doc */ - (traverseproc)cycle_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)cycle_next, /* tp_iternext */ - cycle_methods, /* 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 */ - 0, /* tp_init */ - 0, /* tp_alloc */ - itertools_cycle, /* tp_new */ - PyObject_GC_Del, /* tp_free */ +static PyType_Slot cycle_slots[] = { + {Py_tp_dealloc, cycle_dealloc}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_doc, (void *)itertools_cycle__doc__}, + {Py_tp_traverse, cycle_traverse}, + {Py_tp_iter, PyObject_SelfIter}, + {Py_tp_iternext, cycle_next}, + {Py_tp_methods, cycle_methods}, + {Py_tp_new, itertools_cycle}, + {Py_tp_free, PyObject_GC_Del}, + {0, NULL}, +}; + +static PyType_Spec cycle_spec = { + .name = "itertools.cycle", + .basicsize = sizeof(cycleobject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = cycle_slots, }; @@ -1302,8 +1401,7 @@ itertools_dropwhile_impl(PyTypeObject *type, PyObject *func, PyObject *seq) Py_DECREF(it); return NULL; } - Py_INCREF(func); - lz->func = func; + lz->func = Py_NewRef(func); lz->it = it; lz->start = 0; @@ -1313,15 +1411,18 @@ itertools_dropwhile_impl(PyTypeObject *type, PyObject *func, PyObject *seq) static void dropwhile_dealloc(dropwhileobject *lz) { + PyTypeObject *tp = Py_TYPE(lz); PyObject_GC_UnTrack(lz); Py_XDECREF(lz->func); Py_XDECREF(lz->it); - Py_TYPE(lz)->tp_free(lz); + tp->tp_free(lz); + Py_DECREF(tp); } static int dropwhile_traverse(dropwhileobject *lz, visitproc visit, void *arg) { + Py_VISIT(Py_TYPE(lz)); Py_VISIT(lz->it); Py_VISIT(lz->func); return 0; @@ -1363,12 +1464,14 @@ dropwhile_next(dropwhileobject *lz) static PyObject * dropwhile_reduce(dropwhileobject *lz, PyObject *Py_UNUSED(ignored)) { + ITERTOOL_PICKLE_DEPRECATION; return Py_BuildValue("O(OO)l", Py_TYPE(lz), lz->func, lz->it, lz->start); } static PyObject * dropwhile_setstate(dropwhileobject *lz, PyObject *state) { + ITERTOOL_PICKLE_DEPRECATION; int start = PyObject_IsTrue(state); if (start < 0) return NULL; @@ -1384,48 +1487,25 @@ static PyMethodDef dropwhile_methods[] = { {NULL, NULL} /* sentinel */ }; -static PyTypeObject dropwhile_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "itertools.dropwhile", /* tp_name */ - sizeof(dropwhileobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)dropwhile_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ - itertools_dropwhile__doc__, /* tp_doc */ - (traverseproc)dropwhile_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)dropwhile_next, /* tp_iternext */ - dropwhile_methods, /* 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 */ - 0, /* tp_init */ - 0, /* tp_alloc */ - itertools_dropwhile, /* tp_new */ - PyObject_GC_Del, /* tp_free */ +static PyType_Slot dropwhile_slots[] = { + {Py_tp_dealloc, dropwhile_dealloc}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_doc, (void *)itertools_dropwhile__doc__}, + {Py_tp_traverse, dropwhile_traverse}, + {Py_tp_iter, PyObject_SelfIter}, + {Py_tp_iternext, dropwhile_next}, + {Py_tp_methods, dropwhile_methods}, + {Py_tp_new, itertools_dropwhile}, + {Py_tp_free, PyObject_GC_Del}, + {0, NULL}, +}; + +static PyType_Spec dropwhile_spec = { + .name = "itertools.dropwhile", + .basicsize = sizeof(dropwhileobject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = dropwhile_slots, }; @@ -1465,8 +1545,7 @@ itertools_takewhile_impl(PyTypeObject *type, PyObject *func, PyObject *seq) Py_DECREF(it); return NULL; } - Py_INCREF(func); - lz->func = func; + lz->func = Py_NewRef(func); lz->it = it; lz->stop = 0; @@ -1476,15 +1555,18 @@ itertools_takewhile_impl(PyTypeObject *type, PyObject *func, PyObject *seq) static void takewhile_dealloc(takewhileobject *lz) { + PyTypeObject *tp = Py_TYPE(lz); PyObject_GC_UnTrack(lz); Py_XDECREF(lz->func); Py_XDECREF(lz->it); - Py_TYPE(lz)->tp_free(lz); + tp->tp_free(lz); + Py_DECREF(tp); } static int takewhile_traverse(takewhileobject *lz, visitproc visit, void *arg) { + Py_VISIT(Py_TYPE(lz)); Py_VISIT(lz->it); Py_VISIT(lz->func); return 0; @@ -1522,12 +1604,14 @@ takewhile_next(takewhileobject *lz) static PyObject * takewhile_reduce(takewhileobject *lz, PyObject *Py_UNUSED(ignored)) { + ITERTOOL_PICKLE_DEPRECATION; return Py_BuildValue("O(OO)l", Py_TYPE(lz), lz->func, lz->it, lz->stop); } static PyObject * takewhile_reduce_setstate(takewhileobject *lz, PyObject *state) { + ITERTOOL_PICKLE_DEPRECATION; int stop = PyObject_IsTrue(state); if (stop < 0) @@ -1544,48 +1628,25 @@ static PyMethodDef takewhile_reduce_methods[] = { {NULL, NULL} /* sentinel */ }; -static PyTypeObject takewhile_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "itertools.takewhile", /* tp_name */ - sizeof(takewhileobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)takewhile_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ - itertools_takewhile__doc__, /* tp_doc */ - (traverseproc)takewhile_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)takewhile_next, /* tp_iternext */ - takewhile_reduce_methods, /* 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 */ - 0, /* tp_init */ - 0, /* tp_alloc */ - itertools_takewhile, /* tp_new */ - PyObject_GC_Del, /* tp_free */ +static PyType_Slot takewhile_slots[] = { + {Py_tp_dealloc, takewhile_dealloc}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_doc, (void *)itertools_takewhile__doc__}, + {Py_tp_traverse, takewhile_traverse}, + {Py_tp_iter, PyObject_SelfIter}, + {Py_tp_iternext, takewhile_next}, + {Py_tp_methods, takewhile_reduce_methods}, + {Py_tp_new, itertools_takewhile}, + {Py_tp_free, PyObject_GC_Del}, + {0, NULL}, +}; + +static PyType_Spec takewhile_spec = { + .name = "itertools.takewhile", + .basicsize = sizeof(takewhileobject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = takewhile_slots, }; @@ -1600,8 +1661,6 @@ typedef struct { Py_ssize_t cnt; } isliceobject; -static PyTypeObject islice_type; - static PyObject * islice_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { @@ -1611,7 +1670,9 @@ islice_new(PyTypeObject *type, PyObject *args, PyObject *kwds) Py_ssize_t numargs; isliceobject *lz; - if ((type == &islice_type || type->tp_init == islice_type.tp_init) && + itertools_state *st = find_state_by_type(type); + PyTypeObject *islice_type = st->islice_type; + if ((type == islice_type || type->tp_init == islice_type->tp_init) && !_PyArg_NoKeywords("islice", kwds)) return NULL; @@ -1690,14 +1751,17 @@ islice_new(PyTypeObject *type, PyObject *args, PyObject *kwds) static void islice_dealloc(isliceobject *lz) { + PyTypeObject *tp = Py_TYPE(lz); PyObject_GC_UnTrack(lz); Py_XDECREF(lz->it); - Py_TYPE(lz)->tp_free(lz); + tp->tp_free(lz); + Py_DECREF(tp); } static int islice_traverse(isliceobject *lz, visitproc visit, void *arg) { + Py_VISIT(Py_TYPE(lz)); Py_VISIT(lz->it); return 0; } @@ -1744,6 +1808,7 @@ empty: static PyObject * islice_reduce(isliceobject *lz, PyObject *Py_UNUSED(ignored)) { + ITERTOOL_PICKLE_DEPRECATION; /* When unpickled, generate a new object with the same bounds, * then 'setstate' with the next and count */ @@ -1762,8 +1827,7 @@ islice_reduce(isliceobject *lz, PyObject *Py_UNUSED(ignored)) return Py_BuildValue("O(Nn)n", Py_TYPE(lz), empty_it, 0, 0); } if (lz->stop == -1) { - stop = Py_None; - Py_INCREF(stop); + stop = Py_NewRef(Py_None); } else { stop = PyLong_FromSsize_t(lz->stop); if (stop == NULL) @@ -1777,6 +1841,7 @@ islice_reduce(isliceobject *lz, PyObject *Py_UNUSED(ignored)) static PyObject * islice_setstate(isliceobject *lz, PyObject *state) { + ITERTOOL_PICKLE_DEPRECATION; Py_ssize_t cnt = PyLong_AsSsize_t(state); if (cnt == -1 && PyErr_Occurred()) @@ -1804,48 +1869,25 @@ specified as another value, step determines how many values are\n\ skipped between successive calls. Works like a slice() on a list\n\ but returns an iterator."); -static PyTypeObject islice_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "itertools.islice", /* tp_name */ - sizeof(isliceobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)islice_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ - islice_doc, /* tp_doc */ - (traverseproc)islice_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)islice_next, /* tp_iternext */ - islice_methods, /* 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 */ - 0, /* tp_init */ - 0, /* tp_alloc */ - islice_new, /* tp_new */ - PyObject_GC_Del, /* tp_free */ +static PyType_Slot islice_slots[] = { + {Py_tp_dealloc, islice_dealloc}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_doc, (void *)islice_doc}, + {Py_tp_traverse, islice_traverse}, + {Py_tp_iter, PyObject_SelfIter}, + {Py_tp_iternext, islice_next}, + {Py_tp_methods, islice_methods}, + {Py_tp_new, islice_new}, + {Py_tp_free, PyObject_GC_Del}, + {0, NULL}, +}; + +static PyType_Spec islice_spec = { + .name = "itertools.islice", + .basicsize = sizeof(isliceobject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = islice_slots, }; @@ -1884,8 +1926,7 @@ itertools_starmap_impl(PyTypeObject *type, PyObject *func, PyObject *seq) Py_DECREF(it); return NULL; } - Py_INCREF(func); - lz->func = func; + lz->func = Py_NewRef(func); lz->it = it; return (PyObject *)lz; @@ -1894,15 +1935,18 @@ itertools_starmap_impl(PyTypeObject *type, PyObject *func, PyObject *seq) static void starmap_dealloc(starmapobject *lz) { + PyTypeObject *tp = Py_TYPE(lz); PyObject_GC_UnTrack(lz); Py_XDECREF(lz->func); Py_XDECREF(lz->it); - Py_TYPE(lz)->tp_free(lz); + tp->tp_free(lz); + Py_DECREF(tp); } static int starmap_traverse(starmapobject *lz, visitproc visit, void *arg) { + Py_VISIT(Py_TYPE(lz)); Py_VISIT(lz->it); Py_VISIT(lz->func); return 0; @@ -1933,6 +1977,7 @@ starmap_next(starmapobject *lz) static PyObject * starmap_reduce(starmapobject *lz, PyObject *Py_UNUSED(ignored)) { + ITERTOOL_PICKLE_DEPRECATION; /* Just pickle the iterator */ return Py_BuildValue("O(OO)", Py_TYPE(lz), lz->func, lz->it); } @@ -1943,48 +1988,25 @@ static PyMethodDef starmap_methods[] = { {NULL, NULL} /* sentinel */ }; -static PyTypeObject starmap_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "itertools.starmap", /* tp_name */ - sizeof(starmapobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)starmap_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ - itertools_starmap__doc__, /* tp_doc */ - (traverseproc)starmap_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)starmap_next, /* tp_iternext */ - starmap_methods, /* 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 */ - 0, /* tp_init */ - 0, /* tp_alloc */ - itertools_starmap, /* tp_new */ - PyObject_GC_Del, /* tp_free */ +static PyType_Slot starmap_slots[] = { + {Py_tp_dealloc, starmap_dealloc}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_doc, (void *)itertools_starmap__doc__}, + {Py_tp_traverse, starmap_traverse}, + {Py_tp_iter, PyObject_SelfIter}, + {Py_tp_iternext, starmap_next}, + {Py_tp_methods, starmap_methods}, + {Py_tp_new, itertools_starmap}, + {Py_tp_free, PyObject_GC_Del}, + {0, NULL}, +}; + +static PyType_Spec starmap_spec = { + .name = "itertools.starmap", + .basicsize = sizeof(starmapobject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = starmap_slots, }; @@ -1996,8 +2018,6 @@ typedef struct { PyObject *active; /* Currently running input iterator */ } chainobject; -static PyTypeObject chain_type; - static PyObject * chain_new_internal(PyTypeObject *type, PyObject *source) { @@ -2019,7 +2039,9 @@ chain_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { PyObject *source; - if ((type == &chain_type || type->tp_init == chain_type.tp_init) && + itertools_state *state = find_state_by_type(type); + PyTypeObject *chain_type = state->chain_type; + if ((type == chain_type || type->tp_init == chain_type->tp_init) && !_PyArg_NoKeywords("chain", kwds)) return NULL; @@ -2054,15 +2076,18 @@ itertools_chain_from_iterable(PyTypeObject *type, PyObject *arg) static void chain_dealloc(chainobject *lz) { + PyTypeObject *tp = Py_TYPE(lz); PyObject_GC_UnTrack(lz); Py_XDECREF(lz->active); Py_XDECREF(lz->source); - Py_TYPE(lz)->tp_free(lz); + tp->tp_free(lz); + Py_DECREF(tp); } static int chain_traverse(chainobject *lz, visitproc visit, void *arg) { + Py_VISIT(Py_TYPE(lz)); Py_VISIT(lz->source); Py_VISIT(lz->active); return 0; @@ -2109,6 +2134,7 @@ chain_next(chainobject *lz) static PyObject * chain_reduce(chainobject *lz, PyObject *Py_UNUSED(ignored)) { + ITERTOOL_PICKLE_DEPRECATION; if (lz->source) { /* we can't pickle function objects (itertools.from_iterable) so * we must use setstate to replace the iterable. One day we @@ -2128,6 +2154,7 @@ chain_reduce(chainobject *lz, PyObject *Py_UNUSED(ignored)) static PyObject * chain_setstate(chainobject *lz, PyObject *state) { + ITERTOOL_PICKLE_DEPRECATION; PyObject *source, *active=NULL; if (!PyTuple_Check(state)) { @@ -2167,48 +2194,25 @@ static PyMethodDef chain_methods[] = { {NULL, NULL} /* sentinel */ }; -static PyTypeObject chain_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "itertools.chain", /* tp_name */ - sizeof(chainobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)chain_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ - chain_doc, /* tp_doc */ - (traverseproc)chain_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)chain_next, /* tp_iternext */ - chain_methods, /* 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 */ - 0, /* tp_init */ - 0, /* tp_alloc */ - chain_new, /* tp_new */ - PyObject_GC_Del, /* tp_free */ +static PyType_Slot chain_slots[] = { + {Py_tp_dealloc, chain_dealloc}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_doc, (void *)chain_doc}, + {Py_tp_traverse, chain_traverse}, + {Py_tp_iter, PyObject_SelfIter}, + {Py_tp_iternext, chain_next}, + {Py_tp_methods, chain_methods}, + {Py_tp_new, chain_new}, + {Py_tp_free, PyObject_GC_Del}, + {0, NULL}, +}; + +static PyType_Spec chain_spec = { + .name = "itertools.chain", + .basicsize = sizeof(chainobject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = chain_slots, }; @@ -2222,8 +2226,6 @@ typedef struct { int stopped; /* set to 1 when the iterator is exhausted */ } productobject; -static PyTypeObject product_type; - static PyObject * product_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { @@ -2310,22 +2312,22 @@ error: static void product_dealloc(productobject *lz) { + PyTypeObject *tp = Py_TYPE(lz); PyObject_GC_UnTrack(lz); Py_XDECREF(lz->pools); Py_XDECREF(lz->result); if (lz->indices != NULL) PyMem_Free(lz->indices); - Py_TYPE(lz)->tp_free(lz); + tp->tp_free(lz); + Py_DECREF(tp); } static PyObject * product_sizeof(productobject *lz, void *unused) { - Py_ssize_t res; - - res = _PyObject_SIZE(Py_TYPE(lz)); - res += PyTuple_GET_SIZE(lz->pools) * sizeof(Py_ssize_t); - return PyLong_FromSsize_t(res); + size_t res = _PyObject_SIZE(Py_TYPE(lz)); + res += (size_t)PyTuple_GET_SIZE(lz->pools) * sizeof(Py_ssize_t); + return PyLong_FromSize_t(res); } PyDoc_STRVAR(sizeof_doc, "Returns size in memory, in bytes."); @@ -2333,6 +2335,7 @@ PyDoc_STRVAR(sizeof_doc, "Returns size in memory, in bytes."); static int product_traverse(productobject *lz, visitproc visit, void *arg) { + Py_VISIT(Py_TYPE(lz)); Py_VISIT(lz->pools); Py_VISIT(lz->result); return 0; @@ -2417,8 +2420,7 @@ product_next(productobject *lz) goto empty; } - Py_INCREF(result); - return result; + return Py_NewRef(result); empty: lz->stopped = 1; @@ -2428,6 +2430,7 @@ empty: static PyObject * product_reduce(productobject *lz, PyObject *Py_UNUSED(ignored)) { + ITERTOOL_PICKLE_DEPRECATION; if (lz->stopped) { return Py_BuildValue("O(())", Py_TYPE(lz)); } else if (lz->result == NULL) { @@ -2458,6 +2461,7 @@ product_reduce(productobject *lz, PyObject *Py_UNUSED(ignored)) static PyObject * product_setstate(productobject *lz, PyObject *state) { + ITERTOOL_PICKLE_DEPRECATION; PyObject *result; Py_ssize_t n, i; @@ -2525,48 +2529,25 @@ product(A, repeat=4) means the same as product(A, A, A, A).\n\n\ product('ab', range(3)) --> ('a',0) ('a',1) ('a',2) ('b',0) ('b',1) ('b',2)\n\ product((0,1), (0,1), (0,1)) --> (0,0,0) (0,0,1) (0,1,0) (0,1,1) (1,0,0) ..."); -static PyTypeObject product_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "itertools.product", /* tp_name */ - sizeof(productobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)product_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ - product_doc, /* tp_doc */ - (traverseproc)product_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)product_next, /* tp_iternext */ - product_methods, /* 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 */ - 0, /* tp_init */ - 0, /* tp_alloc */ - product_new, /* tp_new */ - PyObject_GC_Del, /* tp_free */ +static PyType_Slot product_slots[] = { + {Py_tp_dealloc, product_dealloc}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_doc, (void *)product_doc}, + {Py_tp_traverse, product_traverse}, + {Py_tp_iter, PyObject_SelfIter}, + {Py_tp_iternext, product_next}, + {Py_tp_methods, product_methods}, + {Py_tp_new, product_new}, + {Py_tp_free, PyObject_GC_Del}, + {0, NULL}, +}; + +static PyType_Spec product_spec = { + .name = "itertools.product", + .basicsize = sizeof(productobject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = product_slots, }; @@ -2644,27 +2625,28 @@ error: static void combinations_dealloc(combinationsobject *co) { + PyTypeObject *tp = Py_TYPE(co); PyObject_GC_UnTrack(co); Py_XDECREF(co->pool); Py_XDECREF(co->result); if (co->indices != NULL) PyMem_Free(co->indices); - Py_TYPE(co)->tp_free(co); + tp->tp_free(co); + Py_DECREF(tp); } static PyObject * combinations_sizeof(combinationsobject *co, void *unused) { - Py_ssize_t res; - - res = _PyObject_SIZE(Py_TYPE(co)); - res += co->r * sizeof(Py_ssize_t); - return PyLong_FromSsize_t(res); + size_t res = _PyObject_SIZE(Py_TYPE(co)); + res += (size_t)co->r * sizeof(Py_ssize_t); + return PyLong_FromSize_t(res); } static int combinations_traverse(combinationsobject *co, visitproc visit, void *arg) { + Py_VISIT(Py_TYPE(co)); Py_VISIT(co->pool); Py_VISIT(co->result); return 0; @@ -2748,8 +2730,7 @@ combinations_next(combinationsobject *co) } } - Py_INCREF(result); - return result; + return Py_NewRef(result); empty: co->stopped = 1; @@ -2759,6 +2740,7 @@ empty: static PyObject * combinations_reduce(combinationsobject *lz, PyObject *Py_UNUSED(ignored)) { + ITERTOOL_PICKLE_DEPRECATION; if (lz->result == NULL) { return Py_BuildValue("O(On)", Py_TYPE(lz), lz->pool, lz->r); } else if (lz->stopped) { @@ -2788,6 +2770,7 @@ combinations_reduce(combinationsobject *lz, PyObject *Py_UNUSED(ignored)) static PyObject * combinations_setstate(combinationsobject *lz, PyObject *state) { + ITERTOOL_PICKLE_DEPRECATION; PyObject *result; Py_ssize_t i; Py_ssize_t n = PyTuple_GET_SIZE(lz->pool); @@ -2836,48 +2819,25 @@ static PyMethodDef combinations_methods[] = { {NULL, NULL} /* sentinel */ }; -static PyTypeObject combinations_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "itertools.combinations", /* tp_name */ - sizeof(combinationsobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)combinations_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ - itertools_combinations__doc__, /* tp_doc */ - (traverseproc)combinations_traverse,/* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)combinations_next, /* tp_iternext */ - combinations_methods, /* 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 */ - 0, /* tp_init */ - 0, /* tp_alloc */ - itertools_combinations, /* tp_new */ - PyObject_GC_Del, /* tp_free */ +static PyType_Slot combinations_slots[] = { + {Py_tp_dealloc, combinations_dealloc}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_doc, (void *)itertools_combinations__doc__}, + {Py_tp_traverse, combinations_traverse}, + {Py_tp_iter, PyObject_SelfIter}, + {Py_tp_iternext, combinations_next}, + {Py_tp_methods, combinations_methods}, + {Py_tp_new, itertools_combinations}, + {Py_tp_free, PyObject_GC_Del}, + {0, NULL}, +}; + +static PyType_Spec combinations_spec = { + .name = "itertools.combinations", + .basicsize = sizeof(combinationsobject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = combinations_slots, }; @@ -2981,27 +2941,28 @@ error: static void cwr_dealloc(cwrobject *co) { + PyTypeObject *tp = Py_TYPE(co); PyObject_GC_UnTrack(co); Py_XDECREF(co->pool); Py_XDECREF(co->result); if (co->indices != NULL) PyMem_Free(co->indices); - Py_TYPE(co)->tp_free(co); + tp->tp_free(co); + Py_DECREF(tp); } static PyObject * cwr_sizeof(cwrobject *co, void *unused) { - Py_ssize_t res; - - res = _PyObject_SIZE(Py_TYPE(co)); - res += co->r * sizeof(Py_ssize_t); - return PyLong_FromSsize_t(res); + size_t res = _PyObject_SIZE(Py_TYPE(co)); + res += (size_t)co->r * sizeof(Py_ssize_t); + return PyLong_FromSize_t(res); } static int cwr_traverse(cwrobject *co, visitproc visit, void *arg) { + Py_VISIT(Py_TYPE(co)); Py_VISIT(co->pool); Py_VISIT(co->result); return 0; @@ -3079,8 +3040,7 @@ cwr_next(cwrobject *co) } } - Py_INCREF(result); - return result; + return Py_NewRef(result); empty: co->stopped = 1; @@ -3090,6 +3050,7 @@ empty: static PyObject * cwr_reduce(cwrobject *lz, PyObject *Py_UNUSED(ignored)) { + ITERTOOL_PICKLE_DEPRECATION; if (lz->result == NULL) { return Py_BuildValue("O(On)", Py_TYPE(lz), lz->pool, lz->r); } else if (lz->stopped) { @@ -3118,6 +3079,7 @@ cwr_reduce(cwrobject *lz, PyObject *Py_UNUSED(ignored)) static PyObject * cwr_setstate(cwrobject *lz, PyObject *state) { + ITERTOOL_PICKLE_DEPRECATION; PyObject *result; Py_ssize_t n, i; @@ -3163,48 +3125,25 @@ static PyMethodDef cwr_methods[] = { {NULL, NULL} /* sentinel */ }; -static PyTypeObject cwr_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "itertools.combinations_with_replacement", /* tp_name */ - sizeof(cwrobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)cwr_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ - itertools_combinations_with_replacement__doc__, /* tp_doc */ - (traverseproc)cwr_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)cwr_next, /* tp_iternext */ - cwr_methods, /* 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 */ - 0, /* tp_init */ - 0, /* tp_alloc */ - itertools_combinations_with_replacement, /* tp_new */ - PyObject_GC_Del, /* tp_free */ +static PyType_Slot cwr_slots[] = { + {Py_tp_dealloc, cwr_dealloc}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_doc, (void *)itertools_combinations_with_replacement__doc__}, + {Py_tp_traverse, cwr_traverse}, + {Py_tp_iter, PyObject_SelfIter}, + {Py_tp_iternext, cwr_next}, + {Py_tp_methods, cwr_methods}, + {Py_tp_new, itertools_combinations_with_replacement}, + {Py_tp_free, PyObject_GC_Del}, + {0, NULL}, +}; + +static PyType_Spec cwr_spec = { + .name = "itertools.combinations_with_replacement", + .basicsize = sizeof(cwrobject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = cwr_slots, }; @@ -3327,28 +3266,29 @@ error: static void permutations_dealloc(permutationsobject *po) { + PyTypeObject *tp = Py_TYPE(po); PyObject_GC_UnTrack(po); Py_XDECREF(po->pool); Py_XDECREF(po->result); PyMem_Free(po->indices); PyMem_Free(po->cycles); - Py_TYPE(po)->tp_free(po); + tp->tp_free(po); + Py_DECREF(tp); } static PyObject * permutations_sizeof(permutationsobject *po, void *unused) { - Py_ssize_t res; - - res = _PyObject_SIZE(Py_TYPE(po)); - res += PyTuple_GET_SIZE(po->pool) * sizeof(Py_ssize_t); - res += po->r * sizeof(Py_ssize_t); - return PyLong_FromSsize_t(res); + size_t res = _PyObject_SIZE(Py_TYPE(po)); + res += (size_t)PyTuple_GET_SIZE(po->pool) * sizeof(Py_ssize_t); + res += (size_t)po->r * sizeof(Py_ssize_t); + return PyLong_FromSize_t(res); } static int permutations_traverse(permutationsobject *po, visitproc visit, void *arg) { + Py_VISIT(Py_TYPE(po)); Py_VISIT(po->pool); Py_VISIT(po->result); return 0; @@ -3437,8 +3377,7 @@ permutations_next(permutationsobject *po) if (i < 0) goto empty; } - Py_INCREF(result); - return result; + return Py_NewRef(result); empty: po->stopped = 1; @@ -3448,6 +3387,7 @@ empty: static PyObject * permutations_reduce(permutationsobject *po, PyObject *Py_UNUSED(ignored)) { + ITERTOOL_PICKLE_DEPRECATION; if (po->result == NULL) { return Py_BuildValue("O(On)", Py_TYPE(po), po->pool, po->r); } else if (po->stopped) { @@ -3490,6 +3430,7 @@ permutations_reduce(permutationsobject *po, PyObject *Py_UNUSED(ignored)) static PyObject * permutations_setstate(permutationsobject *po, PyObject *state) { + ITERTOOL_PICKLE_DEPRECATION; PyObject *indices, *cycles, *result; Py_ssize_t n, i; @@ -3555,48 +3496,25 @@ static PyMethodDef permuations_methods[] = { {NULL, NULL} /* sentinel */ }; -static PyTypeObject permutations_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "itertools.permutations", /* tp_name */ - sizeof(permutationsobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)permutations_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ - itertools_permutations__doc__, /* tp_doc */ - (traverseproc)permutations_traverse,/* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)permutations_next, /* tp_iternext */ - permuations_methods, /* 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 */ - 0, /* tp_init */ - 0, /* tp_alloc */ - itertools_permutations, /* tp_new */ - PyObject_GC_Del, /* tp_free */ +static PyType_Slot permutations_slots[] = { + {Py_tp_dealloc, permutations_dealloc}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_doc, (void *)itertools_permutations__doc__}, + {Py_tp_traverse, permutations_traverse}, + {Py_tp_iter, PyObject_SelfIter}, + {Py_tp_iternext, permutations_next}, + {Py_tp_methods, permuations_methods}, + {Py_tp_new, itertools_permutations}, + {Py_tp_free, PyObject_GC_Del}, + {0, NULL}, +}; + +static PyType_Spec permutations_spec = { + .name = "itertools.permutations", + .basicsize = sizeof(permutationsobject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = permutations_slots, }; @@ -3608,6 +3526,7 @@ typedef struct { PyObject *it; PyObject *binop; PyObject *initial; + itertools_state *state; } accumulateobject; /*[clinic input] @@ -3641,30 +3560,32 @@ itertools_accumulate_impl(PyTypeObject *type, PyObject *iterable, } if (binop != Py_None) { - Py_XINCREF(binop); - lz->binop = binop; + lz->binop = Py_XNewRef(binop); } lz->total = NULL; lz->it = it; - Py_XINCREF(initial); - lz->initial = initial; + lz->initial = Py_XNewRef(initial); + lz->state = find_state_by_type(type); return (PyObject *)lz; } static void accumulate_dealloc(accumulateobject *lz) { + PyTypeObject *tp = Py_TYPE(lz); PyObject_GC_UnTrack(lz); Py_XDECREF(lz->binop); Py_XDECREF(lz->total); Py_XDECREF(lz->it); Py_XDECREF(lz->initial); - Py_TYPE(lz)->tp_free(lz); + tp->tp_free(lz); + Py_DECREF(tp); } static int accumulate_traverse(accumulateobject *lz, visitproc visit, void *arg) { + Py_VISIT(Py_TYPE(lz)); Py_VISIT(lz->binop); Py_VISIT(lz->it); Py_VISIT(lz->total); @@ -3679,18 +3600,15 @@ accumulate_next(accumulateobject *lz) if (lz->initial != Py_None) { lz->total = lz->initial; - Py_INCREF(Py_None); - lz->initial = Py_None; - Py_INCREF(lz->total); - return lz->total; + lz->initial = Py_NewRef(Py_None); + return Py_NewRef(lz->total); } val = (*Py_TYPE(lz->it)->tp_iternext)(lz->it); if (val == NULL) return NULL; if (lz->total == NULL) { - Py_INCREF(val); - lz->total = val; + lz->total = Py_NewRef(val); return lz->total; } @@ -3710,13 +3628,14 @@ accumulate_next(accumulateobject *lz) static PyObject * accumulate_reduce(accumulateobject *lz, PyObject *Py_UNUSED(ignored)) { + ITERTOOL_PICKLE_DEPRECATION; + itertools_state *state = lz->state; + if (lz->initial != Py_None) { PyObject *it; assert(lz->total == NULL); - if (PyType_Ready(&chain_type) < 0) - return NULL; - it = PyObject_CallFunction((PyObject *)&chain_type, "(O)O", + it = PyObject_CallFunction((PyObject *)(state->chain_type), "(O)O", lz->initial, lz->it); if (it == NULL) return NULL; @@ -3726,11 +3645,7 @@ accumulate_reduce(accumulateobject *lz, PyObject *Py_UNUSED(ignored)) if (lz->total == Py_None) { PyObject *it; - if (PyType_Ready(&chain_type) < 0) - return NULL; - if (PyType_Ready(&islice_type) < 0) - return NULL; - it = PyObject_CallFunction((PyObject *)&chain_type, "(O)O", + it = PyObject_CallFunction((PyObject *)(state->chain_type), "(O)O", lz->total, lz->it); if (it == NULL) return NULL; @@ -3738,7 +3653,8 @@ accumulate_reduce(accumulateobject *lz, PyObject *Py_UNUSED(ignored)) it, lz->binop ? lz->binop : Py_None); if (it == NULL) return NULL; - return Py_BuildValue("O(NiO)", &islice_type, it, 1, Py_None); + + return Py_BuildValue("O(NiO)", state->islice_type, it, 1, Py_None); } return Py_BuildValue("O(OO)O", Py_TYPE(lz), lz->it, lz->binop?lz->binop:Py_None, @@ -3748,6 +3664,7 @@ accumulate_reduce(accumulateobject *lz, PyObject *Py_UNUSED(ignored)) static PyObject * accumulate_setstate(accumulateobject *lz, PyObject *state) { + ITERTOOL_PICKLE_DEPRECATION; Py_INCREF(state); Py_XSETREF(lz->total, state); Py_RETURN_NONE; @@ -3761,48 +3678,25 @@ static PyMethodDef accumulate_methods[] = { {NULL, NULL} /* sentinel */ }; -static PyTypeObject accumulate_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "itertools.accumulate", /* tp_name */ - sizeof(accumulateobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)accumulate_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ - itertools_accumulate__doc__, /* tp_doc */ - (traverseproc)accumulate_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)accumulate_next, /* tp_iternext */ - accumulate_methods, /* 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 */ - 0, /* tp_init */ - 0, /* tp_alloc */ - itertools_accumulate, /* tp_new */ - PyObject_GC_Del, /* tp_free */ +static PyType_Slot accumulate_slots[] = { + {Py_tp_dealloc, accumulate_dealloc}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_doc, (void *)itertools_accumulate__doc__}, + {Py_tp_traverse, accumulate_traverse}, + {Py_tp_iter, PyObject_SelfIter}, + {Py_tp_iternext, accumulate_next}, + {Py_tp_methods, accumulate_methods}, + {Py_tp_new, itertools_accumulate}, + {Py_tp_free, PyObject_GC_Del}, + {0, NULL}, +}; + +static PyType_Spec accumulate_spec = { + .name = "itertools.accumulate", + .basicsize = sizeof(accumulateobject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = accumulate_slots, }; @@ -3863,15 +3757,18 @@ fail: static void compress_dealloc(compressobject *lz) { + PyTypeObject *tp = Py_TYPE(lz); PyObject_GC_UnTrack(lz); Py_XDECREF(lz->data); Py_XDECREF(lz->selectors); - Py_TYPE(lz)->tp_free(lz); + tp->tp_free(lz); + Py_DECREF(tp); } static int compress_traverse(compressobject *lz, visitproc visit, void *arg) { + Py_VISIT(Py_TYPE(lz)); Py_VISIT(lz->data); Py_VISIT(lz->selectors); return 0; @@ -3916,6 +3813,7 @@ compress_next(compressobject *lz) static PyObject * compress_reduce(compressobject *lz, PyObject *Py_UNUSED(ignored)) { + ITERTOOL_PICKLE_DEPRECATION; return Py_BuildValue("O(OO)", Py_TYPE(lz), lz->data, lz->selectors); } @@ -3926,48 +3824,25 @@ static PyMethodDef compress_methods[] = { {NULL, NULL} /* sentinel */ }; -static PyTypeObject compress_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "itertools.compress", /* tp_name */ - sizeof(compressobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)compress_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ - itertools_compress__doc__, /* tp_doc */ - (traverseproc)compress_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)compress_next, /* tp_iternext */ - compress_methods, /* 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 */ - 0, /* tp_init */ - 0, /* tp_alloc */ - itertools_compress, /* tp_new */ - PyObject_GC_Del, /* tp_free */ +static PyType_Slot compress_slots[] = { + {Py_tp_dealloc, compress_dealloc}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_doc, (void *)itertools_compress__doc__}, + {Py_tp_traverse, compress_traverse}, + {Py_tp_iter, PyObject_SelfIter}, + {Py_tp_iternext, compress_next}, + {Py_tp_methods, compress_methods}, + {Py_tp_new, itertools_compress}, + {Py_tp_free, PyObject_GC_Del}, + {0, NULL}, +}; + +static PyType_Spec compress_spec = { + .name = "itertools.compress", + .basicsize = sizeof(compressobject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = compress_slots, }; @@ -4008,8 +3883,7 @@ itertools_filterfalse_impl(PyTypeObject *type, PyObject *func, PyObject *seq) Py_DECREF(it); return NULL; } - Py_INCREF(func); - lz->func = func; + lz->func = Py_NewRef(func); lz->it = it; return (PyObject *)lz; @@ -4018,15 +3892,18 @@ itertools_filterfalse_impl(PyTypeObject *type, PyObject *func, PyObject *seq) static void filterfalse_dealloc(filterfalseobject *lz) { + PyTypeObject *tp = Py_TYPE(lz); PyObject_GC_UnTrack(lz); Py_XDECREF(lz->func); Py_XDECREF(lz->it); - Py_TYPE(lz)->tp_free(lz); + tp->tp_free(lz); + Py_DECREF(tp); } static int filterfalse_traverse(filterfalseobject *lz, visitproc visit, void *arg) { + Py_VISIT(Py_TYPE(lz)); Py_VISIT(lz->it); Py_VISIT(lz->func); return 0; @@ -4069,6 +3946,7 @@ filterfalse_next(filterfalseobject *lz) static PyObject * filterfalse_reduce(filterfalseobject *lz, PyObject *Py_UNUSED(ignored)) { + ITERTOOL_PICKLE_DEPRECATION; return Py_BuildValue("O(OO)", Py_TYPE(lz), lz->func, lz->it); } @@ -4078,48 +3956,25 @@ static PyMethodDef filterfalse_methods[] = { {NULL, NULL} /* sentinel */ }; -static PyTypeObject filterfalse_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "itertools.filterfalse", /* tp_name */ - sizeof(filterfalseobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)filterfalse_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ - itertools_filterfalse__doc__, /* tp_doc */ - (traverseproc)filterfalse_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)filterfalse_next, /* tp_iternext */ - filterfalse_methods, /* 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 */ - 0, /* tp_init */ - 0, /* tp_alloc */ - itertools_filterfalse, /* tp_new */ - PyObject_GC_Del, /* tp_free */ +static PyType_Slot filterfalse_slots[] = { + {Py_tp_dealloc, filterfalse_dealloc}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_doc, (void *)itertools_filterfalse__doc__}, + {Py_tp_traverse, filterfalse_traverse}, + {Py_tp_iter, PyObject_SelfIter}, + {Py_tp_iternext, filterfalse_next}, + {Py_tp_methods, filterfalse_methods}, + {Py_tp_new, itertools_filterfalse}, + {Py_tp_free, PyObject_GC_Del}, + {0, NULL}, +}; + +static PyType_Spec filterfalse_spec = { + .name = "itertools.filterfalse", + .basicsize = sizeof(filterfalseobject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = filterfalse_slots, }; @@ -4245,15 +4100,18 @@ itertools_count_impl(PyTypeObject *type, PyObject *long_cnt, static void count_dealloc(countobject *lz) { + PyTypeObject *tp = Py_TYPE(lz); PyObject_GC_UnTrack(lz); Py_XDECREF(lz->long_cnt); Py_XDECREF(lz->long_step); - Py_TYPE(lz)->tp_free(lz); + tp->tp_free(lz); + Py_DECREF(tp); } static int count_traverse(countobject *lz, visitproc visit, void *arg) { + Py_VISIT(Py_TYPE(lz)); Py_VISIT(lz->long_cnt); Py_VISIT(lz->long_step); return 0; @@ -4316,6 +4174,7 @@ count_repr(countobject *lz) static PyObject * count_reduce(countobject *lz, PyObject *Py_UNUSED(ignored)) { + ITERTOOL_PICKLE_DEPRECATION; if (lz->cnt == PY_SSIZE_T_MAX) return Py_BuildValue("O(OO)", Py_TYPE(lz), lz->long_cnt, lz->long_step); return Py_BuildValue("O(n)", Py_TYPE(lz), lz->cnt); @@ -4327,48 +4186,26 @@ static PyMethodDef count_methods[] = { {NULL, NULL} /* sentinel */ }; -static PyTypeObject count_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "itertools.count", /* tp_name */ - sizeof(countobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)count_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - (reprfunc)count_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ - itertools_count__doc__, /* tp_doc */ - (traverseproc)count_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)count_next, /* tp_iternext */ - count_methods, /* 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 */ - 0, /* tp_init */ - 0, /* tp_alloc */ - itertools_count, /* tp_new */ - PyObject_GC_Del, /* tp_free */ +static PyType_Slot count_slots[] = { + {Py_tp_dealloc, count_dealloc}, + {Py_tp_repr, count_repr}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_doc, (void *)itertools_count__doc__}, + {Py_tp_traverse, count_traverse}, + {Py_tp_iter, PyObject_SelfIter}, + {Py_tp_iternext, count_next}, + {Py_tp_methods, count_methods}, + {Py_tp_new, itertools_count}, + {Py_tp_free, PyObject_GC_Del}, + {0, NULL}, +}; + +static PyType_Spec count_spec = { + .name = "itertools.count", + .basicsize = sizeof(countobject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = count_slots, }; @@ -4380,8 +4217,6 @@ typedef struct { Py_ssize_t cnt; } repeatobject; -static PyTypeObject repeat_type; - static PyObject * repeat_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { @@ -4403,8 +4238,7 @@ repeat_new(PyTypeObject *type, PyObject *args, PyObject *kwds) ro = (repeatobject *)type->tp_alloc(type, 0); if (ro == NULL) return NULL; - Py_INCREF(element); - ro->element = element; + ro->element = Py_NewRef(element); ro->cnt = cnt; return (PyObject *)ro; } @@ -4412,14 +4246,17 @@ repeat_new(PyTypeObject *type, PyObject *args, PyObject *kwds) static void repeat_dealloc(repeatobject *ro) { + PyTypeObject *tp = Py_TYPE(ro); PyObject_GC_UnTrack(ro); Py_XDECREF(ro->element); - Py_TYPE(ro)->tp_free(ro); + tp->tp_free(ro); + Py_DECREF(tp); } static int repeat_traverse(repeatobject *ro, visitproc visit, void *arg) { + Py_VISIT(Py_TYPE(ro)); Py_VISIT(ro->element); return 0; } @@ -4431,8 +4268,7 @@ repeat_next(repeatobject *ro) return NULL; if (ro->cnt > 0) ro->cnt--; - Py_INCREF(ro->element); - return ro->element; + return Py_NewRef(ro->element); } static PyObject * @@ -4462,6 +4298,7 @@ PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list( static PyObject * repeat_reduce(repeatobject *ro, PyObject *Py_UNUSED(ignored)) { + ITERTOOL_PICKLE_DEPRECATION; /* unpickle this so that a new repeat iterator is constructed with an * object, then call __setstate__ on it to set cnt */ @@ -4482,48 +4319,26 @@ PyDoc_STRVAR(repeat_doc, for the specified number of times. If not specified, returns the object\n\ endlessly."); -static PyTypeObject repeat_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "itertools.repeat", /* tp_name */ - sizeof(repeatobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)repeat_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - (reprfunc)repeat_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ - repeat_doc, /* tp_doc */ - (traverseproc)repeat_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)repeat_next, /* tp_iternext */ - repeat_methods, /* 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 */ - 0, /* tp_init */ - 0, /* tp_alloc */ - repeat_new, /* tp_new */ - PyObject_GC_Del, /* tp_free */ +static PyType_Slot repeat_slots[] = { + {Py_tp_dealloc, repeat_dealloc}, + {Py_tp_repr, repeat_repr}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_doc, (void *)repeat_doc}, + {Py_tp_traverse, repeat_traverse}, + {Py_tp_iter, PyObject_SelfIter}, + {Py_tp_iternext, repeat_next}, + {Py_tp_methods, repeat_methods}, + {Py_tp_new, repeat_new}, + {Py_tp_free, PyObject_GC_Del}, + {0, NULL}, +}; + +static PyType_Spec repeat_spec = { + .name = "itertools.repeat", + .basicsize = sizeof(repeatobject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = repeat_slots, }; @@ -4538,8 +4353,6 @@ typedef struct { PyObject *fillvalue; } ziplongestobject; -static PyTypeObject ziplongest_type; - static PyObject * zip_longest_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { @@ -4604,24 +4417,26 @@ zip_longest_new(PyTypeObject *type, PyObject *args, PyObject *kwds) lz->tuplesize = tuplesize; lz->numactive = tuplesize; lz->result = result; - Py_INCREF(fillvalue); - lz->fillvalue = fillvalue; + lz->fillvalue = Py_NewRef(fillvalue); return (PyObject *)lz; } static void zip_longest_dealloc(ziplongestobject *lz) { + PyTypeObject *tp = Py_TYPE(lz); PyObject_GC_UnTrack(lz); Py_XDECREF(lz->ittuple); Py_XDECREF(lz->result); Py_XDECREF(lz->fillvalue); - Py_TYPE(lz)->tp_free(lz); + tp->tp_free(lz); + Py_DECREF(tp); } static int zip_longest_traverse(ziplongestobject *lz, visitproc visit, void *arg) { + Py_VISIT(Py_TYPE(lz)); Py_VISIT(lz->ittuple); Py_VISIT(lz->result); Py_VISIT(lz->fillvalue); @@ -4647,8 +4462,7 @@ zip_longest_next(ziplongestobject *lz) for (i=0 ; i < tuplesize ; i++) { it = PyTuple_GET_ITEM(lz->ittuple, i); if (it == NULL) { - Py_INCREF(lz->fillvalue); - item = lz->fillvalue; + item = Py_NewRef(lz->fillvalue); } else { item = PyIter_Next(it); if (item == NULL) { @@ -4658,8 +4472,7 @@ zip_longest_next(ziplongestobject *lz) Py_DECREF(result); return NULL; } else { - Py_INCREF(lz->fillvalue); - item = lz->fillvalue; + item = Py_NewRef(lz->fillvalue); PyTuple_SET_ITEM(lz->ittuple, i, NULL); Py_DECREF(it); } @@ -4681,8 +4494,7 @@ zip_longest_next(ziplongestobject *lz) for (i=0 ; i < tuplesize ; i++) { it = PyTuple_GET_ITEM(lz->ittuple, i); if (it == NULL) { - Py_INCREF(lz->fillvalue); - item = lz->fillvalue; + item = Py_NewRef(lz->fillvalue); } else { item = PyIter_Next(it); if (item == NULL) { @@ -4692,8 +4504,7 @@ zip_longest_next(ziplongestobject *lz) Py_DECREF(result); return NULL; } else { - Py_INCREF(lz->fillvalue); - item = lz->fillvalue; + item = Py_NewRef(lz->fillvalue); PyTuple_SET_ITEM(lz->ittuple, i, NULL); Py_DECREF(it); } @@ -4708,7 +4519,7 @@ zip_longest_next(ziplongestobject *lz) static PyObject * zip_longest_reduce(ziplongestobject *lz, PyObject *Py_UNUSED(ignored)) { - + ITERTOOL_PICKLE_DEPRECATION; /* Create a new tuple with empty sequences where appropriate to pickle. * Then use setstate to set the fillvalue */ @@ -4735,6 +4546,7 @@ zip_longest_reduce(ziplongestobject *lz, PyObject *Py_UNUSED(ignored)) static PyObject * zip_longest_setstate(ziplongestobject *lz, PyObject *state) { + ITERTOOL_PICKLE_DEPRECATION; Py_INCREF(state); Py_XSETREF(lz->fillvalue, state); Py_RETURN_NONE; @@ -4759,48 +4571,25 @@ are exhausted, the fillvalue is substituted in their place. The fillvalue\n\ defaults to None or can be specified by a keyword argument.\n\ "); -static PyTypeObject ziplongest_type = { - PyVarObject_HEAD_INIT(NULL, 0) - "itertools.zip_longest", /* tp_name */ - sizeof(ziplongestobject), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)zip_longest_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ - zip_longest_doc, /* tp_doc */ - (traverseproc)zip_longest_traverse, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)zip_longest_next, /* tp_iternext */ - zip_longest_methods, /* 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 */ - 0, /* tp_init */ - 0, /* tp_alloc */ - zip_longest_new, /* tp_new */ - PyObject_GC_Del, /* tp_free */ +static PyType_Slot ziplongest_slots[] = { + {Py_tp_dealloc, zip_longest_dealloc}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_doc, (void *)zip_longest_doc}, + {Py_tp_traverse, zip_longest_traverse}, + {Py_tp_iter, PyObject_SelfIter}, + {Py_tp_iternext, zip_longest_next}, + {Py_tp_methods, zip_longest_methods}, + {Py_tp_new, zip_longest_new}, + {Py_tp_free, PyObject_GC_Del}, + {0, NULL}, +}; + +static PyType_Spec ziplongest_spec = { + .name = "itertools.zip_longest", + .basicsize = sizeof(ziplongestobject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = ziplongest_slots, }; @@ -4816,6 +4605,7 @@ repeat(elem [,n]) --> elem, elem, elem, ... endlessly or up to n times\n\ \n\ Iterators terminating on the shortest input sequence:\n\ accumulate(p[, func]) --> p0, p0+p1, p0+p1+p2\n\ +batched(p, n) --> [p0, p1, ..., p_n-1], [p_n, p_n+1, ..., p_2n-1], ...\n\ chain(p, q, ...) --> p0, p1, ... plast, q0, q1, ...\n\ chain.from_iterable([p, q, ...]) --> p0, p1, ... plast, q0, q1, ...\n\ compress(data, selectors) --> (d[0] if s[0]), (d[1] if s[1]), ...\n\ @@ -4838,45 +4628,114 @@ combinations_with_replacement(p, r)\n\ "); static int -itertoolsmodule_exec(PyObject *m) -{ - PyTypeObject *typelist[] = { - &accumulate_type, - &combinations_type, - &cwr_type, - &cycle_type, - &dropwhile_type, - &takewhile_type, - &islice_type, - &starmap_type, - &chain_type, - &compress_type, - &filterfalse_type, - &count_type, - &ziplongest_type, - &pairwise_type, - &permutations_type, - &product_type, - &repeat_type, - &groupby_type, - &_grouper_type, - &tee_type, - &teedataobject_type - }; - - Py_SET_TYPE(&teedataobject_type, &PyType_Type); - - for (size_t i = 0; i < Py_ARRAY_LENGTH(typelist); i++) { - if (PyModule_AddType(m, typelist[i]) < 0) { - return -1; - } - } +itertoolsmodule_traverse(PyObject *mod, visitproc visit, void *arg) +{ + itertools_state *state = get_module_state(mod); + Py_VISIT(state->accumulate_type); + Py_VISIT(state->batched_type); + Py_VISIT(state->chain_type); + Py_VISIT(state->combinations_type); + Py_VISIT(state->compress_type); + Py_VISIT(state->count_type); + Py_VISIT(state->cwr_type); + Py_VISIT(state->cycle_type); + Py_VISIT(state->dropwhile_type); + Py_VISIT(state->filterfalse_type); + Py_VISIT(state->groupby_type); + Py_VISIT(state->_grouper_type); + Py_VISIT(state->islice_type); + Py_VISIT(state->pairwise_type); + Py_VISIT(state->permutations_type); + Py_VISIT(state->product_type); + Py_VISIT(state->repeat_type); + Py_VISIT(state->starmap_type); + Py_VISIT(state->takewhile_type); + Py_VISIT(state->tee_type); + Py_VISIT(state->teedataobject_type); + Py_VISIT(state->ziplongest_type); + return 0; +} +static int +itertoolsmodule_clear(PyObject *mod) +{ + itertools_state *state = get_module_state(mod); + Py_CLEAR(state->accumulate_type); + Py_CLEAR(state->batched_type); + Py_CLEAR(state->chain_type); + Py_CLEAR(state->combinations_type); + Py_CLEAR(state->compress_type); + Py_CLEAR(state->count_type); + Py_CLEAR(state->cwr_type); + Py_CLEAR(state->cycle_type); + Py_CLEAR(state->dropwhile_type); + Py_CLEAR(state->filterfalse_type); + Py_CLEAR(state->groupby_type); + Py_CLEAR(state->_grouper_type); + Py_CLEAR(state->islice_type); + Py_CLEAR(state->pairwise_type); + Py_CLEAR(state->permutations_type); + Py_CLEAR(state->product_type); + Py_CLEAR(state->repeat_type); + Py_CLEAR(state->starmap_type); + Py_CLEAR(state->takewhile_type); + Py_CLEAR(state->tee_type); + Py_CLEAR(state->teedataobject_type); + Py_CLEAR(state->ziplongest_type); + return 0; +} + +static void +itertoolsmodule_free(void *mod) +{ + (void)itertoolsmodule_clear((PyObject *)mod); +} + +#define ADD_TYPE(module, type, spec) \ +do { \ + type = (PyTypeObject *)PyType_FromModuleAndSpec(module, spec, NULL); \ + if (type == NULL) { \ + return -1; \ + } \ + if (PyModule_AddType(module, type) < 0) { \ + return -1; \ + } \ +} while (0) + +static int +itertoolsmodule_exec(PyObject *mod) +{ + itertools_state *state = get_module_state(mod); + ADD_TYPE(mod, state->accumulate_type, &accumulate_spec); + ADD_TYPE(mod, state->batched_type, &batched_spec); + ADD_TYPE(mod, state->chain_type, &chain_spec); + ADD_TYPE(mod, state->combinations_type, &combinations_spec); + ADD_TYPE(mod, state->compress_type, &compress_spec); + ADD_TYPE(mod, state->count_type, &count_spec); + ADD_TYPE(mod, state->cwr_type, &cwr_spec); + ADD_TYPE(mod, state->cycle_type, &cycle_spec); + ADD_TYPE(mod, state->dropwhile_type, &dropwhile_spec); + ADD_TYPE(mod, state->filterfalse_type, &filterfalse_spec); + ADD_TYPE(mod, state->groupby_type, &groupby_spec); + ADD_TYPE(mod, state->_grouper_type, &_grouper_spec); + ADD_TYPE(mod, state->islice_type, &islice_spec); + ADD_TYPE(mod, state->pairwise_type, &pairwise_spec); + ADD_TYPE(mod, state->permutations_type, &permutations_spec); + ADD_TYPE(mod, state->product_type, &product_spec); + ADD_TYPE(mod, state->repeat_type, &repeat_spec); + ADD_TYPE(mod, state->starmap_type, &starmap_spec); + ADD_TYPE(mod, state->takewhile_type, &takewhile_spec); + ADD_TYPE(mod, state->tee_type, &tee_spec); + ADD_TYPE(mod, state->teedataobject_type, &teedataobject_spec); + ADD_TYPE(mod, state->ziplongest_type, &ziplongest_spec); + + Py_SET_TYPE(state->teedataobject_type, &PyType_Type); return 0; } static struct PyModuleDef_Slot itertoolsmodule_slots[] = { {Py_mod_exec, itertoolsmodule_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; @@ -4887,15 +4746,15 @@ static PyMethodDef module_methods[] = { static struct PyModuleDef itertoolsmodule = { - PyModuleDef_HEAD_INIT, - "itertools", - module_doc, - 0, - module_methods, - itertoolsmodule_slots, - NULL, - NULL, - NULL + .m_base = PyModuleDef_HEAD_INIT, + .m_name = "itertools", + .m_doc = module_doc, + .m_size = sizeof(itertools_state), + .m_methods = module_methods, + .m_slots = itertoolsmodule_slots, + .m_traverse = itertoolsmodule_traverse, + .m_clear = itertoolsmodule_clear, + .m_free = itertoolsmodule_free, }; PyMODINIT_FUNC diff --git a/Modules/main.c b/Modules/main.c index 6904e3f7..7edfeb33 100644 --- a/Modules/main.c +++ b/Modules/main.c @@ -296,10 +296,10 @@ pymain_run_module(const wchar_t *modname, int set_argv0) Py_DECREF(module); return pymain_exit_err_print(); } - _Py_UnhandledKeyboardInterrupt = 0; + _PyRuntime.signals.unhandled_keyboard_interrupt = 0; result = PyObject_Call(runmodule, runargs, NULL); if (!result && PyErr_Occurred() == PyExc_KeyboardInterrupt) { - _Py_UnhandledKeyboardInterrupt = 1; + _PyRuntime.signals.unhandled_keyboard_interrupt = 1; } Py_DECREF(runpy); Py_DECREF(runmodule); @@ -479,12 +479,23 @@ error: } +static void +pymain_set_inspect(PyConfig *config, int inspect) +{ + config->inspect = inspect; +_Py_COMP_DIAG_PUSH +_Py_COMP_DIAG_IGNORE_DEPR_DECLS + Py_InspectFlag = inspect; +_Py_COMP_DIAG_POP +} + + static int pymain_run_stdin(PyConfig *config) { if (stdin_is_interactive(config)) { - config->inspect = 0; - Py_InspectFlag = 0; /* do exit on SystemExit */ + // do exit on SystemExit + pymain_set_inspect(config, 0); int exitcode; if (pymain_run_startup(config, &exitcode)) { @@ -517,16 +528,14 @@ pymain_repl(PyConfig *config, int *exitcode) /* Check this environment variable at the end, to give programs the opportunity to set it from Python. */ if (!config->inspect && _Py_GetEnv(config->use_environment, "PYTHONINSPECT")) { - config->inspect = 1; - Py_InspectFlag = 1; + pymain_set_inspect(config, 1); } if (!(config->inspect && stdin_is_interactive(config) && config_run_code(config))) { return; } - config->inspect = 0; - Py_InspectFlag = 0; + pymain_set_inspect(config, 0); if (pymain_run_interactive_hook(exitcode)) { return; } @@ -687,7 +696,7 @@ Py_RunMain(void) pymain_free(); - if (_Py_UnhandledKeyboardInterrupt) { + if (_PyRuntime.signals.unhandled_keyboard_interrupt) { exitcode = exit_sigint(); } diff --git a/Modules/makesetup b/Modules/makesetup index 08303814..f000c9cd 100755 --- a/Modules/makesetup +++ b/Modules/makesetup @@ -262,12 +262,15 @@ sed -e 's/[ ]*#.*//' -e '/^[ ]*$/d' | esac # custom flags first, PY_STDMODULE_CFLAGS may contain -I with system libmpdec case $doconfig in - no) cc="$cc $cpps \$(PY_STDMODULE_CFLAGS) \$(CCSHARED)";; + no) + cc="$cc $cpps \$(PY_STDMODULE_CFLAGS) \$(CCSHARED)" + rule="$obj: $src \$(MODULE_${mods_upper}_DEPS) \$(MODULE_DEPS_SHARED) \$(PYTHON_HEADERS); $cc -c $src -o $obj" + ;; *) - cc="$cc $cpps \$(PY_BUILTIN_MODULE_CFLAGS)";; + cc="$cc $cpps \$(PY_BUILTIN_MODULE_CFLAGS)" + rule="$obj: $src \$(MODULE_${mods_upper}_DEPS) \$(MODULE_DEPS_STATIC) \$(PYTHON_HEADERS); $cc -c $src -o $obj" + ;; esac - # force rebuild when header file or module build flavor (static/shared) is changed - rule="$obj: $src \$(MODULE_${mods_upper}_DEPS) \$(PYTHON_HEADERS) Modules/config.c; $cc -c $src -o $obj" echo "$rule" >>$rulesf done case $doconfig in diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index 0a907a0c..7b1104ba 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -55,18 +55,19 @@ raised for division by zero and mod by zero. #ifndef Py_BUILD_CORE_BUILTIN # define Py_BUILD_CORE_MODULE 1 #endif -#define NEEDS_PY_IDENTIFIER #include "Python.h" #include "pycore_bitutils.h" // _Py_bit_length() #include "pycore_call.h" // _PyObject_CallNoArgs() -#include "pycore_dtoa.h" // _Py_dg_infinity() #include "pycore_long.h" // _PyLong_GetZero() +#include "pycore_moduleobject.h" // _PyModule_GetState() +#include "pycore_object.h" // _PyObject_LookupSpecial() #include "pycore_pymath.h" // _PY_SHORT_FLOAT_REPR /* For DBL_EPSILON in _math.h */ #include <float.h> /* For _Py_log1p with workarounds for buggy handling of zeros. */ #include "_math.h" +#include <stdbool.h> #include "clinic/mathmodule.c.h" @@ -76,6 +77,127 @@ module math /*[clinic end generated code: output=da39a3ee5e6b4b0d input=76bc7002685dd942]*/ +typedef struct { + PyObject *str___ceil__; + PyObject *str___floor__; + PyObject *str___trunc__; +} math_module_state; + +static inline math_module_state* +get_math_module_state(PyObject *module) +{ + void *state = _PyModule_GetState(module); + assert(state != NULL); + return (math_module_state *)state; +} + +/* +Double and triple length extended precision algorithms from: + + Accurate Sum and Dot Product + by Takeshi Ogita, Siegfried M. Rump, and Shin’Ichi Oishi + https://doi.org/10.1137/030601818 + https://www.tuhh.de/ti3/paper/rump/OgRuOi05.pdf + +*/ + +typedef struct{ double hi; double lo; } DoubleLength; + +static DoubleLength +dl_fast_sum(double a, double b) +{ + /* Algorithm 1.1. Compensated summation of two floating point numbers. */ + assert(fabs(a) >= fabs(b)); + double x = a + b; + double y = (a - x) + b; + return (DoubleLength) {x, y}; +} + +static DoubleLength +dl_sum(double a, double b) +{ + /* Algorithm 3.1 Error-free transformation of the sum */ + double x = a + b; + double z = x - a; + double y = (a - (x - z)) + (b - z); + return (DoubleLength) {x, y}; +} + +#ifndef UNRELIABLE_FMA + +static DoubleLength +dl_mul(double x, double y) +{ + /* Algorithm 3.5. Error-free transformation of a product */ + double z = x * y; + double zz = fma(x, y, -z); + return (DoubleLength) {z, zz}; +} + +#else + +/* + The default implementation of dl_mul() depends on the C math library + having an accurate fma() function as required by § 7.12.13.1 of the + C99 standard. + + The UNRELIABLE_FMA option is provided as a slower but accurate + alternative for builds where the fma() function is found wanting. + The speed penalty may be modest (17% slower on an Apple M1 Max), + so don't hesitate to enable this build option. + + The algorithms are from the T. J. Dekker paper: + A Floating-Point Technique for Extending the Available Precision + https://csclub.uwaterloo.ca/~pbarfuss/dekker1971.pdf +*/ + +static DoubleLength +dl_split(double x) { + // Dekker (5.5) and (5.6). + double t = x * 134217729.0; // Veltkamp constant = 2.0 ** 27 + 1 + double hi = t - (t - x); + double lo = x - hi; + return (DoubleLength) {hi, lo}; +} + +static DoubleLength +dl_mul(double x, double y) +{ + // Dekker (5.12) and mul12() + DoubleLength xx = dl_split(x); + DoubleLength yy = dl_split(y); + double p = xx.hi * yy.hi; + double q = xx.hi * yy.lo + xx.lo * yy.hi; + double z = p + q; + double zz = p - z + q + xx.lo * yy.lo; + return (DoubleLength) {z, zz}; +} + +#endif + +typedef struct { double hi; double lo; double tiny; } TripleLength; + +static const TripleLength tl_zero = {0.0, 0.0, 0.0}; + +static TripleLength +tl_fma(double x, double y, TripleLength total) +{ + /* Algorithm 5.10 with SumKVert for K=3 */ + DoubleLength pr = dl_mul(x, y); + DoubleLength sm = dl_sum(total.hi, pr.hi); + DoubleLength r1 = dl_sum(total.lo, pr.lo); + DoubleLength r2 = dl_sum(r1.hi, sm.lo); + return (TripleLength) {sm.hi, r2.hi, total.tiny + r1.lo + r2.lo}; +} + +static double +tl_to_d(TripleLength total) +{ + DoubleLength last = dl_sum(total.lo, total.hi); + return total.tiny + last.lo + last.hi; +} + + /* sin(pi*x), giving accurate results for all finite x (especially x integral or close to an integer). This is here for use in the @@ -85,10 +207,6 @@ module math static const double pi = 3.141592653589793238462643383279502884197; static const double logpi = 1.144729885849400174143427351353058711647; -#if !defined(HAVE_ERF) || !defined(HAVE_ERFC) -static const double sqrtpi = 1.772453850905516027298167483341145182798; -#endif /* !defined(HAVE_ERF) || !defined(HAVE_ERFC) */ - /* Version of PyFloat_AsDouble() with in-line fast paths for exact floats and integers. Gives a substantial @@ -146,7 +264,9 @@ m_sinpi(double x) return copysign(1.0, x)*r; } -/* Implementation of the real gamma function. In extensive but non-exhaustive +/* Implementation of the real gamma function. Kept here to work around + issues (see e.g. gh-70309) with quality of libm's tgamma/lgamma implementations + on various platforms (Windows, MacOS). In extensive but non-exhaustive random tests, this function proved accurate to within <= 10 ulps across the entire float domain. Note that accuracy may depend on the quality of the system math functions, the pow function in particular. Special cases @@ -268,34 +388,6 @@ lanczos_sum(double x) return num/den; } -/* Constant for +infinity, generated in the same way as float('inf'). */ - -static double -m_inf(void) -{ -#if _PY_SHORT_FLOAT_REPR == 1 - return _Py_dg_infinity(0); -#else - return Py_HUGE_VAL; -#endif -} - -/* Constant nan value, generated in the same way as float('nan'). */ -/* We don't currently assume that Py_NAN is defined everywhere. */ - -#if _PY_SHORT_FLOAT_REPR == 1 - -static double -m_nan(void) -{ -#if _PY_SHORT_FLOAT_REPR == 1 - return _Py_dg_stdnan(0); -#else - return Py_NAN; -#endif -} - -#endif static double m_tgamma(double x) @@ -314,7 +406,7 @@ m_tgamma(double x) if (x == 0.0) { errno = EDOM; /* tgamma(+-0.0) = +-inf, divide-by-zero */ - return copysign(Py_HUGE_VAL, x); + return copysign(Py_INFINITY, x); } /* integer arguments */ @@ -442,163 +534,6 @@ m_lgamma(double x) return r; } -#if !defined(HAVE_ERF) || !defined(HAVE_ERFC) - -/* - Implementations of the error function erf(x) and the complementary error - function erfc(x). - - Method: we use a series approximation for erf for small x, and a continued - fraction approximation for erfc(x) for larger x; - combined with the relations erf(-x) = -erf(x) and erfc(x) = 1.0 - erf(x), - this gives us erf(x) and erfc(x) for all x. - - The series expansion used is: - - erf(x) = x*exp(-x*x)/sqrt(pi) * [ - 2/1 + 4/3 x**2 + 8/15 x**4 + 16/105 x**6 + ...] - - The coefficient of x**(2k-2) here is 4**k*factorial(k)/factorial(2*k). - This series converges well for smallish x, but slowly for larger x. - - The continued fraction expansion used is: - - erfc(x) = x*exp(-x*x)/sqrt(pi) * [1/(0.5 + x**2 -) 0.5/(2.5 + x**2 - ) - 3.0/(4.5 + x**2 - ) 7.5/(6.5 + x**2 - ) ...] - - after the first term, the general term has the form: - - k*(k-0.5)/(2*k+0.5 + x**2 - ...). - - This expansion converges fast for larger x, but convergence becomes - infinitely slow as x approaches 0.0. The (somewhat naive) continued - fraction evaluation algorithm used below also risks overflow for large x; - but for large x, erfc(x) == 0.0 to within machine precision. (For - example, erfc(30.0) is approximately 2.56e-393). - - Parameters: use series expansion for abs(x) < ERF_SERIES_CUTOFF and - continued fraction expansion for ERF_SERIES_CUTOFF <= abs(x) < - ERFC_CONTFRAC_CUTOFF. ERFC_SERIES_TERMS and ERFC_CONTFRAC_TERMS are the - numbers of terms to use for the relevant expansions. */ - -#define ERF_SERIES_CUTOFF 1.5 -#define ERF_SERIES_TERMS 25 -#define ERFC_CONTFRAC_CUTOFF 30.0 -#define ERFC_CONTFRAC_TERMS 50 - -/* - Error function, via power series. - - Given a finite float x, return an approximation to erf(x). - Converges reasonably fast for small x. -*/ - -static double -m_erf_series(double x) -{ - double x2, acc, fk, result; - int i, saved_errno; - - x2 = x * x; - acc = 0.0; - fk = (double)ERF_SERIES_TERMS + 0.5; - for (i = 0; i < ERF_SERIES_TERMS; i++) { - acc = 2.0 + x2 * acc / fk; - fk -= 1.0; - } - /* Make sure the exp call doesn't affect errno; - see m_erfc_contfrac for more. */ - saved_errno = errno; - result = acc * x * exp(-x2) / sqrtpi; - errno = saved_errno; - return result; -} - -/* - Complementary error function, via continued fraction expansion. - - Given a positive float x, return an approximation to erfc(x). Converges - reasonably fast for x large (say, x > 2.0), and should be safe from - overflow if x and nterms are not too large. On an IEEE 754 machine, with x - <= 30.0, we're safe up to nterms = 100. For x >= 30.0, erfc(x) is smaller - than the smallest representable nonzero float. */ - -static double -m_erfc_contfrac(double x) -{ - double x2, a, da, p, p_last, q, q_last, b, result; - int i, saved_errno; - - if (x >= ERFC_CONTFRAC_CUTOFF) - return 0.0; - - x2 = x*x; - a = 0.0; - da = 0.5; - p = 1.0; p_last = 0.0; - q = da + x2; q_last = 1.0; - for (i = 0; i < ERFC_CONTFRAC_TERMS; i++) { - double temp; - a += da; - da += 2.0; - b = da + x2; - temp = p; p = b*p - a*p_last; p_last = temp; - temp = q; q = b*q - a*q_last; q_last = temp; - } - /* Issue #8986: On some platforms, exp sets errno on underflow to zero; - save the current errno value so that we can restore it later. */ - saved_errno = errno; - result = p / q * x * exp(-x2) / sqrtpi; - errno = saved_errno; - return result; -} - -#endif /* !defined(HAVE_ERF) || !defined(HAVE_ERFC) */ - -/* Error function erf(x), for general x */ - -static double -m_erf(double x) -{ -#ifdef HAVE_ERF - return erf(x); -#else - double absx, cf; - - if (Py_IS_NAN(x)) - return x; - absx = fabs(x); - if (absx < ERF_SERIES_CUTOFF) - return m_erf_series(x); - else { - cf = m_erfc_contfrac(absx); - return x > 0.0 ? 1.0 - cf : cf - 1.0; - } -#endif -} - -/* Complementary error function erfc(x), for general x. */ - -static double -m_erfc(double x) -{ -#ifdef HAVE_ERFC - return erfc(x); -#else - double absx, cf; - - if (Py_IS_NAN(x)) - return x; - absx = fabs(x); - if (absx < ERF_SERIES_CUTOFF) - return 1.0 - m_erf_series(x); - else { - cf = m_erfc_contfrac(absx); - return x > 0.0 ? cf : 2.0 - cf; - } -#endif -} - /* wrapper for atan2 that deals directly with special cases before delegating to the platform libm for the remaining cases. This @@ -785,25 +720,7 @@ m_log2(double x) } if (x > 0.0) { -#ifdef HAVE_LOG2 return log2(x); -#else - double m; - int e; - m = frexp(x, &e); - /* We want log2(m * 2**e) == log(m) / log(2) + e. Care is needed when - * x is just greater than 1.0: in that case e is 1, log(m) is negative, - * and we get significant cancellation error from the addition of - * log(m) / log(2) to e. The slight rewrite of the expression below - * avoids this problem. - */ - if (x >= 1.0) { - return log(2.0 * m) / log(2.0) + (e - 1); - } - else { - return log(m) / log(2.0) + e; - } -#endif } else if (x == 0.0) { errno = EDOM; @@ -890,7 +807,7 @@ long_lcm(PyObject *a, PyObject *b) { PyObject *g, *m, *f, *ab; - if (Py_SIZE(a) == 0 || Py_SIZE(b) == 0) { + if (_PyLong_IsZero((PyLongObject *)a) || _PyLong_IsZero((PyLongObject *)b)) { return PyLong_FromLong(0); } g = _PyLong_GCD(a, b); @@ -1036,9 +953,7 @@ is_error(double x) */ static PyObject * -math_1_to_whatever(PyObject *arg, double (*func) (double), - PyObject *(*from_double_func) (double), - int can_overflow) +math_1(PyObject *arg, double (*func) (double), int can_overflow) { double x, r; x = PyFloat_AsDouble(arg); @@ -1064,7 +979,7 @@ math_1_to_whatever(PyObject *arg, double (*func) (double), /* this branch unnecessary on most platforms */ return NULL; - return (*from_double_func)(r); + return PyFloat_FromDouble(r); } /* variant of math_1, to be used when the function being wrapped is known to @@ -1112,12 +1027,6 @@ math_1a(PyObject *arg, double (*func) (double)) OverflowError. */ -static PyObject * -math_1(PyObject *arg, double (*func) (double), int can_overflow) -{ - return math_1_to_whatever(arg, func, PyFloat_FromDouble, can_overflow); -} - static PyObject * math_2(PyObject *const *args, Py_ssize_t nargs, double (*func) (double, double), const char *funcname) @@ -1215,10 +1124,10 @@ static PyObject * math_ceil(PyObject *module, PyObject *number) /*[clinic end generated code: output=6c3b8a78bc201c67 input=2725352806399cab]*/ { - _Py_IDENTIFIER(__ceil__); if (!PyFloat_CheckExact(number)) { - PyObject *method = _PyObject_LookupSpecialId(number, &PyId___ceil__); + math_module_state *state = get_math_module_state(module); + PyObject *method = _PyObject_LookupSpecial(number, state->str___ceil__); if (method != NULL) { PyObject *result = _PyObject_CallNoArgs(method); Py_DECREF(method); @@ -1245,10 +1154,10 @@ FUNC1(cos, cos, 0, FUNC1(cosh, cosh, 1, "cosh($module, x, /)\n--\n\n" "Return the hyperbolic cosine of x.") -FUNC1A(erf, m_erf, +FUNC1A(erf, erf, "erf($module, x, /)\n--\n\n" "Error function at x.") -FUNC1A(erfc, m_erfc, +FUNC1A(erfc, erfc, "erfc($module, x, /)\n--\n\n" "Complementary error function at x.") FUNC1(exp, exp, 1, @@ -1283,14 +1192,13 @@ math_floor(PyObject *module, PyObject *number) { double x; - _Py_IDENTIFIER(__floor__); - if (PyFloat_CheckExact(number)) { x = PyFloat_AS_DOUBLE(number); } else { - PyObject *method = _PyObject_LookupSpecialId(number, &PyId___floor__); + math_module_state *state = get_math_module_state(module); + PyObject *method = _PyObject_LookupSpecial(number, state->str___floor__); if (method != NULL) { PyObject *result = _PyObject_CallNoArgs(method); Py_DECREF(method); @@ -1343,30 +1251,30 @@ FUNC1(tanh, tanh, 0, Dickinson's post at <http://bugs.python.org/file10357/msum4.py>. See those links for more details, proofs and other references. - Note 1: IEEE 754R floating point semantics are assumed, - but the current implementation does not re-establish special - value semantics across iterations (i.e. handling -Inf + Inf). + Note 1: IEEE 754 floating-point semantics with a rounding mode of + roundTiesToEven are assumed. - Note 2: No provision is made for intermediate overflow handling; - therefore, sum([1e+308, 1e-308, 1e+308]) returns 1e+308 while - sum([1e+308, 1e+308, 1e-308]) raises an OverflowError due to the + Note 2: No provision is made for intermediate overflow handling; + therefore, fsum([1e+308, -1e+308, 1e+308]) returns 1e+308 while + fsum([1e+308, 1e+308, -1e+308]) raises an OverflowError due to the overflow of the first partial sum. - Note 3: The intermediate values lo, yr, and hi are declared volatile so - aggressive compilers won't algebraically reduce lo to always be exactly 0.0. - Also, the volatile declaration forces the values to be stored in memory as - regular doubles instead of extended long precision (80-bit) values. This - prevents double rounding because any addition or subtraction of two doubles - can be resolved exactly into double-sized hi and lo values. As long as the - hi value gets forced into a double before yr and lo are computed, the extra - bits in downstream extended precision operations (x87 for example) will be - exactly zero and therefore can be losslessly stored back into a double, - thereby preventing double rounding. - - Note 4: A similar implementation is in Modules/cmathmodule.c. - Be sure to update both when making changes. - - Note 5: The signature of math.fsum() differs from builtins.sum() + Note 3: The algorithm has two potential sources of fragility. First, C + permits arithmetic operations on `double`s to be performed in an + intermediate format whose range and precision may be greater than those of + `double` (see for example C99 §5.2.4.2.2, paragraph 8). This can happen for + example on machines using the now largely historical x87 FPUs. In this case, + `fsum` can produce incorrect results. If `FLT_EVAL_METHOD` is `0` or `1`, or + `FLT_EVAL_METHOD` is `2` and `long double` is identical to `double`, then we + should be safe from this source of errors. Second, an aggressively + optimizing compiler can re-associate operations so that (for example) the + statement `yr = hi - x;` is treated as `yr = (x + y) - x` and then + re-associated as `yr = y + (x - x)`, giving `y = yr` and `lo = 0.0`. That + re-association would be in violation of the C standard, and should not occur + except possibly in the presence of unsafe optimizations (e.g., -ffast-math, + -fassociative-math). Such optimizations should be avoided for this module. + + Note 4: The signature of math.fsum() differs from builtins.sum() because the start argument doesn't make sense in the context of accurate summation. Since the partials table is collapsed before returning a result, sum(seq2, start=sum(seq1)) may not equal the @@ -1452,7 +1360,7 @@ math_fsum(PyObject *module, PyObject *seq) Py_ssize_t i, j, n = 0, m = NUM_PARTIALS; double x, y, t, ps[NUM_PARTIALS], *p = ps; double xsave, special_sum = 0.0, inf_sum = 0.0; - volatile double hi, yr, lo; + double hi, yr, lo = 0.0; iter = PyObject_GetIter(seq); if (iter == NULL) @@ -1789,13 +1697,13 @@ math_isqrt(PyObject *module, PyObject *n) return NULL; } - if (_PyLong_Sign(n) < 0) { + if (_PyLong_IsNegative((PyLongObject *)n)) { PyErr_SetString( PyExc_ValueError, "isqrt() argument must be nonnegative"); goto error; } - if (_PyLong_Sign(n) == 0) { + if (_PyLong_IsZero((PyLongObject *)n)) { Py_DECREF(n); return PyLong_FromLong(0); } @@ -2034,8 +1942,7 @@ factorial_odd_part(unsigned long n) inner = PyLong_FromLong(1); if (inner == NULL) return NULL; - outer = inner; - Py_INCREF(outer); + outer = Py_NewRef(inner); upper = 3; for (i = _Py_bit_length(n) - 2; i >= 0; i--) { @@ -2056,8 +1963,7 @@ factorial_odd_part(unsigned long n) Py_DECREF(partial); if (tmp == NULL) goto error; - Py_DECREF(inner); - inner = tmp; + Py_SETREF(inner, tmp); /* Now inner is the product of all odd integers j in the range (0, n/2**i], giving the inner product in the formula above. */ @@ -2065,8 +1971,7 @@ factorial_odd_part(unsigned long n) tmp = PyNumber_Multiply(outer, inner); if (tmp == NULL) goto error; - Py_DECREF(outer); - outer = tmp; + Py_SETREF(outer, tmp); } Py_DECREF(inner); return outer; @@ -2156,19 +2061,19 @@ static PyObject * math_trunc(PyObject *module, PyObject *x) /*[clinic end generated code: output=34b9697b707e1031 input=2168b34e0a09134d]*/ { - _Py_IDENTIFIER(__trunc__); PyObject *trunc, *result; if (PyFloat_CheckExact(x)) { return PyFloat_Type.tp_as_number->nb_int(x); } - if (Py_TYPE(x)->tp_dict == NULL) { + if (!_PyType_IsReady(Py_TYPE(x))) { if (PyType_Ready(Py_TYPE(x)) < 0) return NULL; } - trunc = _PyObject_LookupSpecialId(x, &PyId___trunc__); + math_module_state *state = get_math_module_state(module); + trunc = _PyObject_LookupSpecial(x, state->str___trunc__); if (trunc == NULL) { if (!PyErr_Occurred()) PyErr_Format(PyExc_TypeError, @@ -2312,7 +2217,7 @@ math_modf_impl(PyObject *module, double x) in that int is larger than PY_SSIZE_T_MAX. */ static PyObject* -loghelper(PyObject* arg, double (*func)(double), const char *funcname) +loghelper(PyObject* arg, double (*func)(double)) { /* If it is int, do it ourselves. */ if (PyLong_Check(arg)) { @@ -2320,7 +2225,7 @@ loghelper(PyObject* arg, double (*func)(double), const char *funcname) Py_ssize_t e; /* Negative or zero inputs give a ValueError. */ - if (Py_SIZE(arg) <= 0) { + if (!_PyLong_IsPositive((PyLongObject *)arg)) { PyErr_SetString(PyExc_ValueError, "math domain error"); return NULL; @@ -2350,33 +2255,22 @@ loghelper(PyObject* arg, double (*func)(double), const char *funcname) } -/*[clinic input] -math.log - - x: object - [ - base: object(c_default="NULL") = math.e - ] - / - -Return the logarithm of x to the given base. - -If the base not specified, returns the natural logarithm (base e) of x. -[clinic start generated code]*/ - +/* AC: cannot convert yet, see gh-102839 and gh-89381, waiting + for support of multiple signatures */ static PyObject * -math_log_impl(PyObject *module, PyObject *x, int group_right_1, - PyObject *base) -/*[clinic end generated code: output=7b5a39e526b73fc9 input=0f62d5726cbfebbd]*/ +math_log(PyObject *module, PyObject * const *args, Py_ssize_t nargs) { PyObject *num, *den; PyObject *ans; - num = loghelper(x, m_log, "log"); - if (num == NULL || base == NULL) + if (!_PyArg_CheckPositional("log", nargs, 1, 2)) + return NULL; + + num = loghelper(args[0], m_log); + if (num == NULL || nargs == 1) return num; - den = loghelper(base, m_log, "log"); + den = loghelper(args[1], m_log); if (den == NULL) { Py_DECREF(num); return NULL; @@ -2388,6 +2282,10 @@ math_log_impl(PyObject *module, PyObject *x, int group_right_1, return ans; } +PyDoc_STRVAR(math_log_doc, +"log(x, [base=math.e])\n\ +Return the logarithm of x to the given base.\n\n\ +If the base is not specified, returns the natural logarithm (base e) of x."); /*[clinic input] math.log2 @@ -2402,7 +2300,7 @@ static PyObject * math_log2(PyObject *module, PyObject *x) /*[clinic end generated code: output=5425899a4d5d6acb input=08321262bae4f39b]*/ { - return loghelper(x, m_log2, "log2"); + return loghelper(x, m_log2); } @@ -2419,7 +2317,7 @@ static PyObject * math_log10(PyObject *module, PyObject *x) /*[clinic end generated code: output=be72a64617df9c6f input=b2469d02c6469e53]*/ { - return loghelper(x, m_log10, "log10"); + return loghelper(x, m_log10); } @@ -2474,6 +2372,7 @@ that are almost always correctly rounded, four techniques are used: * lossless scaling using a power-of-two scaling factor * accurate squaring using Veltkamp-Dekker splitting [1] + or an equivalent with an fma() call * compensated summation using a variant of the Neumaier algorithm [2] * differential correction of the square root [3] @@ -2512,9 +2411,8 @@ Since lo**2 is less than 1/2 ulp(csum), we have csum+lo*lo == csum. To minimize loss of information during the accumulation of fractional values, each term has a separate accumulator. This also breaks up sequential dependencies in the inner loop so the CPU can maximize -floating point throughput. [4] On a 2.6 GHz Haswell, adding one -dimension has an incremental cost of only 5ns -- for example when -moving from hypot(x,y) to hypot(x,y,z). +floating point throughput. [4] On an Apple M1 Max, hypot(*vec) +takes only 3.33 µsec when len(vec) == 1000. The square root differential correction is needed because a correctly rounded square root of a correctly rounded sum of @@ -2532,14 +2430,21 @@ algorithm, effectively doubling the number of accurate bits. This technique is used in Dekker's SQRT2 algorithm and again in Borges' ALGORITHM 4 and 5. -Without proof for all cases, hypot() cannot claim to be always -correctly rounded. However for n <= 1000, prior to the final addition -that rounds the overall result, the internal accuracy of "h" together -with its correction of "x / (2.0 * h)" is at least 100 bits. [6] -Also, hypot() was tested against a Decimal implementation with -prec=300. After 100 million trials, no incorrectly rounded examples -were found. In addition, perfect commutativity (all permutations are -exactly equal) was verified for 1 billion random inputs with n=5. [7] +The hypot() function is faithfully rounded (less than 1 ulp error) +and usually correctly rounded (within 1/2 ulp). The squaring +step is exact. The Neumaier summation computes as if in doubled +precision (106 bits) and has the advantage that its input squares +are non-negative so that the condition number of the sum is one. +The square root with a differential correction is likewise computed +as if in doubled precision. + +For n <= 1000, prior to the final addition that rounds the overall +result, the internal accuracy of "h" together with its correction of +"x / (2.0 * h)" is at least 100 bits. [6] Also, hypot() was tested +against a Decimal implementation with prec=300. After 100 million +trials, no incorrectly rounded examples were found. In addition, +perfect commutativity (all permutations are exactly equal) was +verified for 1 billion random inputs with n=5. [7] References: @@ -2556,9 +2461,8 @@ References: static inline double vector_norm(Py_ssize_t n, double *vec, double max, int found_nan) { - const double T27 = 134217729.0; /* ldexp(1.0, 27) + 1.0) */ - double x, scale, oldcsum, csum = 1.0, frac1 = 0.0, frac2 = 0.0, frac3 = 0.0; - double t, hi, lo, h; + double x, h, scale, csum = 1.0, frac1 = 0.0, frac2 = 0.0; + DoubleLength pr, sm; int max_e; Py_ssize_t i; @@ -2572,82 +2476,37 @@ vector_norm(Py_ssize_t n, double *vec, double max, int found_nan) return max; } frexp(max, &max_e); - if (max_e >= -1023) { - scale = ldexp(1.0, -max_e); - assert(max * scale >= 0.5); - assert(max * scale < 1.0); + if (max_e < -1023) { + /* When max_e < -1023, ldexp(1.0, -max_e) would overflow. */ for (i=0 ; i < n ; i++) { - x = vec[i]; - assert(Py_IS_FINITE(x) && fabs(x) <= max); - - x *= scale; - assert(fabs(x) < 1.0); - - t = x * T27; - hi = t - (t - x); - lo = x - hi; - assert(hi + lo == x); - - x = hi * hi; - assert(x <= 1.0); - assert(fabs(csum) >= fabs(x)); - oldcsum = csum; - csum += x; - frac1 += (oldcsum - csum) + x; - - x = 2.0 * hi * lo; - assert(fabs(csum) >= fabs(x)); - oldcsum = csum; - csum += x; - frac2 += (oldcsum - csum) + x; - - assert(csum + lo * lo == csum); - frac3 += lo * lo; - } - h = sqrt(csum - 1.0 + (frac1 + frac2 + frac3)); - - x = h; - t = x * T27; - hi = t - (t - x); - lo = x - hi; - assert (hi + lo == x); - - x = -hi * hi; - assert(fabs(csum) >= fabs(x)); - oldcsum = csum; - csum += x; - frac1 += (oldcsum - csum) + x; - - x = -2.0 * hi * lo; - assert(fabs(csum) >= fabs(x)); - oldcsum = csum; - csum += x; - frac2 += (oldcsum - csum) + x; - - x = -lo * lo; - assert(fabs(csum) >= fabs(x)); - oldcsum = csum; - csum += x; - frac3 += (oldcsum - csum) + x; - - x = csum - 1.0 + (frac1 + frac2 + frac3); - return (h + x / (2.0 * h)) / scale; - } - /* When max_e < -1023, ldexp(1.0, -max_e) overflows. - So instead of multiplying by a scale, we just divide by *max*. - */ + vec[i] /= DBL_MIN; // convert subnormals to normals + } + return DBL_MIN * vector_norm(n, vec, max / DBL_MIN, found_nan); + } + scale = ldexp(1.0, -max_e); + assert(max * scale >= 0.5); + assert(max * scale < 1.0); for (i=0 ; i < n ; i++) { x = vec[i]; assert(Py_IS_FINITE(x) && fabs(x) <= max); - x /= max; - x = x*x; - assert(x <= 1.0); - assert(fabs(csum) >= fabs(x)); - oldcsum = csum; - csum += x; - frac1 += (oldcsum - csum) + x; - } - return max * sqrt(csum - 1.0 + frac1); + x *= scale; // lossless scaling + assert(fabs(x) < 1.0); + pr = dl_mul(x, x); // lossless squaring + assert(pr.hi <= 1.0); + sm = dl_fast_sum(csum, pr.hi); // lossless addition + csum = sm.hi; + frac1 += pr.lo; // lossy addition + frac2 += sm.lo; // lossy addition + } + h = sqrt(csum - 1.0 + (frac1 + frac2)); + pr = dl_mul(-h, h); + sm = dl_fast_sum(csum, pr.hi); + csum = sm.hi; + frac1 += pr.lo; + frac2 += sm.lo; + x = csum - 1.0 + (frac1 + frac2); + h += x / (2.0 * h); // differential correction + return h / scale; } #define NUM_STACK_ELEMS 16 @@ -2808,6 +2667,247 @@ For example, the hypotenuse of a 3/4/5 right triangle is:\n\ 5.0\n\ "); +/** sumprod() ***************************************************************/ + +/* Forward declaration */ +static inline int _check_long_mult_overflow(long a, long b); + +static inline bool +long_add_would_overflow(long a, long b) +{ + return (a > 0) ? (b > LONG_MAX - a) : (b < LONG_MIN - a); +} + +/*[clinic input] +math.sumprod + + p: object + q: object + / + +Return the sum of products of values from two iterables p and q. + +Roughly equivalent to: + + sum(itertools.starmap(operator.mul, zip(p, q, strict=True))) + +For float and mixed int/float inputs, the intermediate products +and sums are computed with extended precision. +[clinic start generated code]*/ + +static PyObject * +math_sumprod_impl(PyObject *module, PyObject *p, PyObject *q) +/*[clinic end generated code: output=6722dbfe60664554 input=82be54fe26f87e30]*/ +{ + PyObject *p_i = NULL, *q_i = NULL, *term_i = NULL, *new_total = NULL; + PyObject *p_it, *q_it, *total; + iternextfunc p_next, q_next; + bool p_stopped = false, q_stopped = false; + bool int_path_enabled = true, int_total_in_use = false; + bool flt_path_enabled = true, flt_total_in_use = false; + long int_total = 0; + TripleLength flt_total = tl_zero; + + p_it = PyObject_GetIter(p); + if (p_it == NULL) { + return NULL; + } + q_it = PyObject_GetIter(q); + if (q_it == NULL) { + Py_DECREF(p_it); + return NULL; + } + total = PyLong_FromLong(0); + if (total == NULL) { + Py_DECREF(p_it); + Py_DECREF(q_it); + return NULL; + } + p_next = *Py_TYPE(p_it)->tp_iternext; + q_next = *Py_TYPE(q_it)->tp_iternext; + while (1) { + bool finished; + + assert (p_i == NULL); + assert (q_i == NULL); + assert (term_i == NULL); + assert (new_total == NULL); + + assert (p_it != NULL); + assert (q_it != NULL); + assert (total != NULL); + + p_i = p_next(p_it); + if (p_i == NULL) { + if (PyErr_Occurred()) { + if (!PyErr_ExceptionMatches(PyExc_StopIteration)) { + goto err_exit; + } + PyErr_Clear(); + } + p_stopped = true; + } + q_i = q_next(q_it); + if (q_i == NULL) { + if (PyErr_Occurred()) { + if (!PyErr_ExceptionMatches(PyExc_StopIteration)) { + goto err_exit; + } + PyErr_Clear(); + } + q_stopped = true; + } + if (p_stopped != q_stopped) { + PyErr_Format(PyExc_ValueError, "Inputs are not the same length"); + goto err_exit; + } + finished = p_stopped & q_stopped; + + if (int_path_enabled) { + + if (!finished && PyLong_CheckExact(p_i) & PyLong_CheckExact(q_i)) { + int overflow; + long int_p, int_q, int_prod; + + int_p = PyLong_AsLongAndOverflow(p_i, &overflow); + if (overflow) { + goto finalize_int_path; + } + int_q = PyLong_AsLongAndOverflow(q_i, &overflow); + if (overflow) { + goto finalize_int_path; + } + if (_check_long_mult_overflow(int_p, int_q)) { + goto finalize_int_path; + } + int_prod = int_p * int_q; + if (long_add_would_overflow(int_total, int_prod)) { + goto finalize_int_path; + } + int_total += int_prod; + int_total_in_use = true; + Py_CLEAR(p_i); + Py_CLEAR(q_i); + continue; + } + + finalize_int_path: + // We're finished, overflowed, or have a non-int + int_path_enabled = false; + if (int_total_in_use) { + term_i = PyLong_FromLong(int_total); + if (term_i == NULL) { + goto err_exit; + } + new_total = PyNumber_Add(total, term_i); + if (new_total == NULL) { + goto err_exit; + } + Py_SETREF(total, new_total); + new_total = NULL; + Py_CLEAR(term_i); + int_total = 0; // An ounce of prevention, ... + int_total_in_use = false; + } + } + + if (flt_path_enabled) { + + if (!finished) { + double flt_p, flt_q; + bool p_type_float = PyFloat_CheckExact(p_i); + bool q_type_float = PyFloat_CheckExact(q_i); + if (p_type_float && q_type_float) { + flt_p = PyFloat_AS_DOUBLE(p_i); + flt_q = PyFloat_AS_DOUBLE(q_i); + } else if (p_type_float && (PyLong_CheckExact(q_i) || PyBool_Check(q_i))) { + /* We care about float/int pairs and int/float pairs because + they arise naturally in several use cases such as price + times quantity, measurements with integer weights, or + data selected by a vector of bools. */ + flt_p = PyFloat_AS_DOUBLE(p_i); + flt_q = PyLong_AsDouble(q_i); + if (flt_q == -1.0 && PyErr_Occurred()) { + PyErr_Clear(); + goto finalize_flt_path; + } + } else if (q_type_float && (PyLong_CheckExact(p_i) || PyBool_Check(q_i))) { + flt_q = PyFloat_AS_DOUBLE(q_i); + flt_p = PyLong_AsDouble(p_i); + if (flt_p == -1.0 && PyErr_Occurred()) { + PyErr_Clear(); + goto finalize_flt_path; + } + } else { + goto finalize_flt_path; + } + TripleLength new_flt_total = tl_fma(flt_p, flt_q, flt_total); + if (isfinite(new_flt_total.hi)) { + flt_total = new_flt_total; + flt_total_in_use = true; + Py_CLEAR(p_i); + Py_CLEAR(q_i); + continue; + } + } + + finalize_flt_path: + // We're finished, overflowed, have a non-float, or got a non-finite value + flt_path_enabled = false; + if (flt_total_in_use) { + term_i = PyFloat_FromDouble(tl_to_d(flt_total)); + if (term_i == NULL) { + goto err_exit; + } + new_total = PyNumber_Add(total, term_i); + if (new_total == NULL) { + goto err_exit; + } + Py_SETREF(total, new_total); + new_total = NULL; + Py_CLEAR(term_i); + flt_total = tl_zero; + flt_total_in_use = false; + } + } + + assert(!int_total_in_use); + assert(!flt_total_in_use); + if (finished) { + goto normal_exit; + } + term_i = PyNumber_Multiply(p_i, q_i); + if (term_i == NULL) { + goto err_exit; + } + new_total = PyNumber_Add(total, term_i); + if (new_total == NULL) { + goto err_exit; + } + Py_SETREF(total, new_total); + new_total = NULL; + Py_CLEAR(p_i); + Py_CLEAR(q_i); + Py_CLEAR(term_i); + } + + normal_exit: + Py_DECREF(p_it); + Py_DECREF(q_it); + return total; + + err_exit: + Py_DECREF(p_it); + Py_DECREF(q_it); + Py_DECREF(total); + Py_XDECREF(p_i); + Py_XDECREF(q_i); + Py_XDECREF(term_i); + Py_XDECREF(new_total); + return NULL; +} + + /* pow can't use math_2, but needs its own wrapper: the problem is that an infinite result can arise either as a result of overflow (in which case OverflowError should be raised) or as a result of @@ -3141,8 +3241,7 @@ math_prod_impl(PyObject *module, PyObject *iterable, PyObject *start) long i_result = PyLong_AsLongAndOverflow(result, &overflow); /* If this already overflowed, don't even enter the loop. */ if (overflow == 0) { - Py_DECREF(result); - result = NULL; + Py_SETREF(result, NULL); } /* Loop over all the items in the iterable until we finish, we overflow * or we found a non integer element */ @@ -3189,8 +3288,7 @@ math_prod_impl(PyObject *module, PyObject *iterable, PyObject *start) */ if (PyFloat_CheckExact(result)) { double f_result = PyFloat_AS_DOUBLE(result); - Py_DECREF(result); - result = NULL; + Py_SETREF(result, NULL); while(result == NULL) { item = PyIter_Next(iter); if (item == NULL) { @@ -3239,8 +3337,7 @@ math_prod_impl(PyObject *module, PyObject *iterable, PyObject *start) if (item == NULL) { /* error, or end-of-sequence */ if (PyErr_Occurred()) { - Py_DECREF(result); - result = NULL; + Py_SETREF(result, NULL); } break; } @@ -3507,8 +3604,7 @@ perm_comb(PyObject *n, unsigned long long k, int iscomb) return PyLong_FromLong(1); } if (k == 1) { - Py_INCREF(n); - return n; + return Py_NewRef(n); } /* P(n, k) = P(n, j) * P(n-j, k-j) */ @@ -3591,12 +3687,12 @@ math_perm_impl(PyObject *module, PyObject *n, PyObject *k) } assert(PyLong_CheckExact(n) && PyLong_CheckExact(k)); - if (Py_SIZE(n) < 0) { + if (_PyLong_IsNegative((PyLongObject *)n)) { PyErr_SetString(PyExc_ValueError, "n must be a non-negative integer"); goto error; } - if (Py_SIZE(k) < 0) { + if (_PyLong_IsNegative((PyLongObject *)k)) { PyErr_SetString(PyExc_ValueError, "k must be a non-negative integer"); goto error; @@ -3683,12 +3779,12 @@ math_comb_impl(PyObject *module, PyObject *n, PyObject *k) } assert(PyLong_CheckExact(n) && PyLong_CheckExact(k)); - if (Py_SIZE(n) < 0) { + if (_PyLong_IsNegative((PyLongObject *)n)) { PyErr_SetString(PyExc_ValueError, "n must be a non-negative integer"); goto error; } - if (Py_SIZE(k) < 0) { + if (_PyLong_IsNegative((PyLongObject *)k)) { PyErr_SetString(PyExc_ValueError, "k must be a non-negative integer"); goto error; @@ -3720,7 +3816,8 @@ math_comb_impl(PyObject *module, PyObject *n, PyObject *k) if (temp == NULL) { goto error; } - if (Py_SIZE(temp) < 0) { + assert(PyLong_Check(temp)); + if (_PyLong_IsNegative((PyLongObject *)temp)) { Py_DECREF(temp); result = PyLong_FromLong(0); goto done; @@ -3767,13 +3864,20 @@ math.nextafter x: double y: double / + * + steps: object = None -Return the next floating-point value after x towards y. +Return the floating-point value the given number of steps after x towards y. + +If steps is not specified or is None, it defaults to 1. + +Raises a TypeError, if x or y is not a double, or if steps is not an integer. +Raises ValueError if steps is negative. [clinic start generated code]*/ static PyObject * -math_nextafter_impl(PyObject *module, double x, double y) -/*[clinic end generated code: output=750c8266c1c540ce input=02b2d50cd1d9f9b6]*/ +math_nextafter_impl(PyObject *module, double x, double y, PyObject *steps) +/*[clinic end generated code: output=cc6511f02afc099e input=7f2a5842112af2b4]*/ { #if defined(_AIX) if (x == y) { @@ -3788,7 +3892,101 @@ math_nextafter_impl(PyObject *module, double x, double y) return PyFloat_FromDouble(y); } #endif - return PyFloat_FromDouble(nextafter(x, y)); + if (steps == Py_None) { + // fast path: we default to one step. + return PyFloat_FromDouble(nextafter(x, y)); + } + steps = PyNumber_Index(steps); + if (steps == NULL) { + return NULL; + } + assert(PyLong_CheckExact(steps)); + if (_PyLong_IsNegative((PyLongObject *)steps)) { + PyErr_SetString(PyExc_ValueError, + "steps must be a non-negative integer"); + Py_DECREF(steps); + return NULL; + } + + unsigned long long usteps_ull = PyLong_AsUnsignedLongLong(steps); + // Conveniently, uint64_t and double have the same number of bits + // on all the platforms we care about. + // So if an overflow occurs, we can just use UINT64_MAX. + Py_DECREF(steps); + if (usteps_ull >= UINT64_MAX) { + // This branch includes the case where an error occurred, since + // (unsigned long long)(-1) = ULLONG_MAX >= UINT64_MAX. Note that + // usteps_ull can be strictly larger than UINT64_MAX on a machine + // where unsigned long long has width > 64 bits. + if (PyErr_Occurred()) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) { + PyErr_Clear(); + } + else { + return NULL; + } + } + usteps_ull = UINT64_MAX; + } + assert(usteps_ull <= UINT64_MAX); + uint64_t usteps = (uint64_t)usteps_ull; + + if (usteps == 0) { + return PyFloat_FromDouble(x); + } + if (Py_IS_NAN(x)) { + return PyFloat_FromDouble(x); + } + if (Py_IS_NAN(y)) { + return PyFloat_FromDouble(y); + } + + // We assume that double and uint64_t have the same endianness. + // This is not guaranteed by the C-standard, but it is true for + // all platforms we care about. (The most likely form of violation + // would be a "mixed-endian" double.) + union pun {double f; uint64_t i;}; + union pun ux = {x}, uy = {y}; + if (ux.i == uy.i) { + return PyFloat_FromDouble(x); + } + + const uint64_t sign_bit = 1ULL<<63; + + uint64_t ax = ux.i & ~sign_bit; + uint64_t ay = uy.i & ~sign_bit; + + // opposite signs + if (((ux.i ^ uy.i) & sign_bit)) { + // NOTE: ax + ay can never overflow, because their most significant bit + // ain't set. + if (ax + ay <= usteps) { + return PyFloat_FromDouble(uy.f); + // This comparison has to use <, because <= would get +0.0 vs -0.0 + // wrong. + } else if (ax < usteps) { + union pun result = {.i = (uy.i & sign_bit) | (usteps - ax)}; + return PyFloat_FromDouble(result.f); + } else { + ux.i -= usteps; + return PyFloat_FromDouble(ux.f); + } + // same sign + } else if (ax > ay) { + if (ax - ay >= usteps) { + ux.i -= usteps; + return PyFloat_FromDouble(ux.f); + } else { + return PyFloat_FromDouble(uy.f); + } + } else { + if (ay - ax >= usteps) { + ux.i += usteps; + return PyFloat_FromDouble(ux.f); + } else { + return PyFloat_FromDouble(uy.f); + } + } } @@ -3812,7 +4010,7 @@ math_ulp_impl(PyObject *module, double x) if (Py_IS_INFINITY(x)) { return x; } - double inf = m_inf(); + double inf = Py_INFINITY; double x2 = nextafter(x, inf); if (Py_IS_INFINITY(x2)) { /* special case: x is the largest positive representable float */ @@ -3825,27 +4023,55 @@ math_ulp_impl(PyObject *module, double x) static int math_exec(PyObject *module) { - if (PyModule_AddObject(module, "pi", PyFloat_FromDouble(Py_MATH_PI)) < 0) { + + math_module_state *state = get_math_module_state(module); + state->str___ceil__ = PyUnicode_InternFromString("__ceil__"); + if (state->str___ceil__ == NULL) { + return -1; + } + state->str___floor__ = PyUnicode_InternFromString("__floor__"); + if (state->str___floor__ == NULL) { + return -1; + } + state->str___trunc__ = PyUnicode_InternFromString("__trunc__"); + if (state->str___trunc__ == NULL) { + return -1; + } + if (_PyModule_Add(module, "pi", PyFloat_FromDouble(Py_MATH_PI)) < 0) { return -1; } - if (PyModule_AddObject(module, "e", PyFloat_FromDouble(Py_MATH_E)) < 0) { + if (_PyModule_Add(module, "e", PyFloat_FromDouble(Py_MATH_E)) < 0) { return -1; } // 2pi - if (PyModule_AddObject(module, "tau", PyFloat_FromDouble(Py_MATH_TAU)) < 0) { + if (_PyModule_Add(module, "tau", PyFloat_FromDouble(Py_MATH_TAU)) < 0) { return -1; } - if (PyModule_AddObject(module, "inf", PyFloat_FromDouble(m_inf())) < 0) { + if (_PyModule_Add(module, "inf", PyFloat_FromDouble(Py_INFINITY)) < 0) { return -1; } -#if _PY_SHORT_FLOAT_REPR == 1 - if (PyModule_AddObject(module, "nan", PyFloat_FromDouble(m_nan())) < 0) { + if (_PyModule_Add(module, "nan", PyFloat_FromDouble(fabs(Py_NAN))) < 0) { return -1; } -#endif return 0; } +static int +math_clear(PyObject *module) +{ + math_module_state *state = get_math_module_state(module); + Py_CLEAR(state->str___ceil__); + Py_CLEAR(state->str___floor__); + Py_CLEAR(state->str___trunc__); + return 0; +} + +static void +math_free(void *module) +{ + math_clear((PyObject *)module); +} + static PyMethodDef math_methods[] = { {"acos", math_acos, METH_O, math_acos_doc}, {"acosh", math_acosh, METH_O, math_acosh_doc}, @@ -3883,7 +4109,7 @@ static PyMethodDef math_methods[] = { {"lcm", _PyCFunction_CAST(math_lcm), METH_FASTCALL, math_lcm_doc}, MATH_LDEXP_METHODDEF {"lgamma", math_lgamma, METH_O, math_lgamma_doc}, - MATH_LOG_METHODDEF + {"log", _PyCFunction_CAST(math_log), METH_FASTCALL, math_log_doc}, {"log1p", math_log1p, METH_O, math_log1p_doc}, MATH_LOG10_METHODDEF MATH_LOG2_METHODDEF @@ -3896,6 +4122,7 @@ static PyMethodDef math_methods[] = { {"sqrt", math_sqrt, METH_O, math_sqrt_doc}, {"tan", math_tan, METH_O, math_tan_doc}, {"tanh", math_tanh, METH_O, math_tanh_doc}, + MATH_SUMPROD_METHODDEF MATH_TRUNC_METHODDEF MATH_PROD_METHODDEF MATH_PERM_METHODDEF @@ -3907,6 +4134,7 @@ static PyMethodDef math_methods[] = { static PyModuleDef_Slot math_slots[] = { {Py_mod_exec, math_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; @@ -3918,9 +4146,11 @@ static struct PyModuleDef mathmodule = { PyModuleDef_HEAD_INIT, .m_name = "math", .m_doc = module_doc, - .m_size = 0, + .m_size = sizeof(math_module_state), .m_methods = math_methods, .m_slots = math_slots, + .m_clear = math_clear, + .m_free = math_free, }; PyMODINIT_FUNC diff --git a/Modules/md5module.c b/Modules/md5module.c index 48b11e07..2122f8b1 100644 --- a/Modules/md5module.c +++ b/Modules/md5module.c @@ -22,6 +22,7 @@ #include "Python.h" #include "hashlib.h" #include "pycore_strhex.h" // _Py_strhex() +#include "pycore_typeobject.h" // _PyType_GetModuleState() /*[clinic input] module _md5 @@ -43,283 +44,19 @@ typedef long long MD5_INT64; /* 64-bit integer */ #define MD5_BLOCKSIZE 64 #define MD5_DIGESTSIZE 16 -/* The structure for storing MD5 info */ +#include "_hacl/Hacl_Hash_MD5.h" -struct md5_state { - MD5_INT64 length; - MD5_INT32 state[4], curlen; - unsigned char buf[MD5_BLOCKSIZE]; -}; typedef struct { PyObject_HEAD - - struct md5_state hash_state; + // Prevents undefined behavior via multiple threads entering the C API. + // The lock will be NULL before threaded access has been enabled. + PyThread_type_lock lock; + Hacl_Streaming_MD5_state *hash_state; } MD5object; #include "clinic/md5module.c.h" -/* ------------------------------------------------------------------------ - * - * This code for the MD5 algorithm was noted as public domain. The - * original headers are pasted below. - * - * Several changes have been made to make it more compatible with the - * Python environment and desired interface. - * - */ - -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, https://www.libtom.net - */ - -/* rotate the hard way (platform optimizations could be done) */ -#define ROLc(x, y) ( (((unsigned long)(x)<<(unsigned long)((y)&31)) | (((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL) - -/* Endian Neutral macros that work on all platforms */ - -#define STORE32L(x, y) \ - { (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \ - (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } - -#define LOAD32L(x, y) \ - { x = ((unsigned long)((y)[3] & 255)<<24) | \ - ((unsigned long)((y)[2] & 255)<<16) | \ - ((unsigned long)((y)[1] & 255)<<8) | \ - ((unsigned long)((y)[0] & 255)); } - -#define STORE64L(x, y) \ - { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \ - (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \ - (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \ - (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } - - -/* MD5 macros */ - -#define F(x,y,z) (z ^ (x & (y ^ z))) -#define G(x,y,z) (y ^ (z & (y ^ x))) -#define H(x,y,z) (x^y^z) -#define I(x,y,z) (y^(x|(~z))) - -#define FF(a,b,c,d,M,s,t) \ - a = (a + F(b,c,d) + M + t); a = ROLc(a, s) + b; - -#define GG(a,b,c,d,M,s,t) \ - a = (a + G(b,c,d) + M + t); a = ROLc(a, s) + b; - -#define HH(a,b,c,d,M,s,t) \ - a = (a + H(b,c,d) + M + t); a = ROLc(a, s) + b; - -#define II(a,b,c,d,M,s,t) \ - a = (a + I(b,c,d) + M + t); a = ROLc(a, s) + b; - - -static void md5_compress(struct md5_state *md5, const unsigned char *buf) -{ - MD5_INT32 i, W[16], a, b, c, d; - - assert(md5 != NULL); - assert(buf != NULL); - - /* copy the state into 512-bits into W[0..15] */ - for (i = 0; i < 16; i++) { - LOAD32L(W[i], buf + (4*i)); - } - - /* copy state */ - a = md5->state[0]; - b = md5->state[1]; - c = md5->state[2]; - d = md5->state[3]; - - FF(a,b,c,d,W[0],7,0xd76aa478UL) - FF(d,a,b,c,W[1],12,0xe8c7b756UL) - FF(c,d,a,b,W[2],17,0x242070dbUL) - FF(b,c,d,a,W[3],22,0xc1bdceeeUL) - FF(a,b,c,d,W[4],7,0xf57c0fafUL) - FF(d,a,b,c,W[5],12,0x4787c62aUL) - FF(c,d,a,b,W[6],17,0xa8304613UL) - FF(b,c,d,a,W[7],22,0xfd469501UL) - FF(a,b,c,d,W[8],7,0x698098d8UL) - FF(d,a,b,c,W[9],12,0x8b44f7afUL) - FF(c,d,a,b,W[10],17,0xffff5bb1UL) - FF(b,c,d,a,W[11],22,0x895cd7beUL) - FF(a,b,c,d,W[12],7,0x6b901122UL) - FF(d,a,b,c,W[13],12,0xfd987193UL) - FF(c,d,a,b,W[14],17,0xa679438eUL) - FF(b,c,d,a,W[15],22,0x49b40821UL) - GG(a,b,c,d,W[1],5,0xf61e2562UL) - GG(d,a,b,c,W[6],9,0xc040b340UL) - GG(c,d,a,b,W[11],14,0x265e5a51UL) - GG(b,c,d,a,W[0],20,0xe9b6c7aaUL) - GG(a,b,c,d,W[5],5,0xd62f105dUL) - GG(d,a,b,c,W[10],9,0x02441453UL) - GG(c,d,a,b,W[15],14,0xd8a1e681UL) - GG(b,c,d,a,W[4],20,0xe7d3fbc8UL) - GG(a,b,c,d,W[9],5,0x21e1cde6UL) - GG(d,a,b,c,W[14],9,0xc33707d6UL) - GG(c,d,a,b,W[3],14,0xf4d50d87UL) - GG(b,c,d,a,W[8],20,0x455a14edUL) - GG(a,b,c,d,W[13],5,0xa9e3e905UL) - GG(d,a,b,c,W[2],9,0xfcefa3f8UL) - GG(c,d,a,b,W[7],14,0x676f02d9UL) - GG(b,c,d,a,W[12],20,0x8d2a4c8aUL) - HH(a,b,c,d,W[5],4,0xfffa3942UL) - HH(d,a,b,c,W[8],11,0x8771f681UL) - HH(c,d,a,b,W[11],16,0x6d9d6122UL) - HH(b,c,d,a,W[14],23,0xfde5380cUL) - HH(a,b,c,d,W[1],4,0xa4beea44UL) - HH(d,a,b,c,W[4],11,0x4bdecfa9UL) - HH(c,d,a,b,W[7],16,0xf6bb4b60UL) - HH(b,c,d,a,W[10],23,0xbebfbc70UL) - HH(a,b,c,d,W[13],4,0x289b7ec6UL) - HH(d,a,b,c,W[0],11,0xeaa127faUL) - HH(c,d,a,b,W[3],16,0xd4ef3085UL) - HH(b,c,d,a,W[6],23,0x04881d05UL) - HH(a,b,c,d,W[9],4,0xd9d4d039UL) - HH(d,a,b,c,W[12],11,0xe6db99e5UL) - HH(c,d,a,b,W[15],16,0x1fa27cf8UL) - HH(b,c,d,a,W[2],23,0xc4ac5665UL) - II(a,b,c,d,W[0],6,0xf4292244UL) - II(d,a,b,c,W[7],10,0x432aff97UL) - II(c,d,a,b,W[14],15,0xab9423a7UL) - II(b,c,d,a,W[5],21,0xfc93a039UL) - II(a,b,c,d,W[12],6,0x655b59c3UL) - II(d,a,b,c,W[3],10,0x8f0ccc92UL) - II(c,d,a,b,W[10],15,0xffeff47dUL) - II(b,c,d,a,W[1],21,0x85845dd1UL) - II(a,b,c,d,W[8],6,0x6fa87e4fUL) - II(d,a,b,c,W[15],10,0xfe2ce6e0UL) - II(c,d,a,b,W[6],15,0xa3014314UL) - II(b,c,d,a,W[13],21,0x4e0811a1UL) - II(a,b,c,d,W[4],6,0xf7537e82UL) - II(d,a,b,c,W[11],10,0xbd3af235UL) - II(c,d,a,b,W[2],15,0x2ad7d2bbUL) - II(b,c,d,a,W[9],21,0xeb86d391UL) - - md5->state[0] = md5->state[0] + a; - md5->state[1] = md5->state[1] + b; - md5->state[2] = md5->state[2] + c; - md5->state[3] = md5->state[3] + d; -} - - -/** - Initialize the hash state - @param md5 The hash state you wish to initialize -*/ -static void -md5_init(struct md5_state *md5) -{ - assert(md5 != NULL); - md5->state[0] = 0x67452301UL; - md5->state[1] = 0xefcdab89UL; - md5->state[2] = 0x98badcfeUL; - md5->state[3] = 0x10325476UL; - md5->curlen = 0; - md5->length = 0; -} - -/** - Process a block of memory though the hash - @param md5 The hash state - @param in The data to hash - @param inlen The length of the data (octets) -*/ -static void -md5_process(struct md5_state *md5, const unsigned char *in, Py_ssize_t inlen) -{ - Py_ssize_t n; - - assert(md5 != NULL); - assert(in != NULL); - assert(md5->curlen <= sizeof(md5->buf)); - - while (inlen > 0) { - if (md5->curlen == 0 && inlen >= MD5_BLOCKSIZE) { - md5_compress(md5, in); - md5->length += MD5_BLOCKSIZE * 8; - in += MD5_BLOCKSIZE; - inlen -= MD5_BLOCKSIZE; - } else { - n = Py_MIN(inlen, (Py_ssize_t)(MD5_BLOCKSIZE - md5->curlen)); - memcpy(md5->buf + md5->curlen, in, (size_t)n); - md5->curlen += (MD5_INT32)n; - in += n; - inlen -= n; - if (md5->curlen == MD5_BLOCKSIZE) { - md5_compress(md5, md5->buf); - md5->length += 8*MD5_BLOCKSIZE; - md5->curlen = 0; - } - } - } -} - -/** - Terminate the hash to get the digest - @param md5 The hash state - @param out [out] The destination of the hash (16 bytes) -*/ -static void -md5_done(struct md5_state *md5, unsigned char *out) -{ - int i; - - assert(md5 != NULL); - assert(out != NULL); - assert(md5->curlen < sizeof(md5->buf)); - - /* increase the length of the message */ - md5->length += md5->curlen * 8; - - /* append the '1' bit */ - md5->buf[md5->curlen++] = (unsigned char)0x80; - - /* if the length is currently above 56 bytes we append zeros - * then compress. Then we can fall back to padding zeros and length - * encoding like normal. - */ - if (md5->curlen > 56) { - while (md5->curlen < 64) { - md5->buf[md5->curlen++] = (unsigned char)0; - } - md5_compress(md5, md5->buf); - md5->curlen = 0; - } - - /* pad up to 56 bytes of zeroes */ - while (md5->curlen < 56) { - md5->buf[md5->curlen++] = (unsigned char)0; - } - - /* store length */ - STORE64L(md5->length, md5->buf+56); - md5_compress(md5, md5->buf); - - /* copy output */ - for (i = 0; i < 4; i++) { - STORE32L(md5->state[i], out+(4*i)); - } -} - -/* .Source: /cvs/libtom/libtomcrypt/src/hashes/md5.c,v $ */ -/* .Revision: 1.10 $ */ -/* .Date: 2007/05/12 14:25:28 $ */ - -/* - * End of copied MD5 code. - * - * ------------------------------------------------------------------------ - */ typedef struct { PyTypeObject* md5_type; @@ -337,6 +74,7 @@ static MD5object * newMD5object(MD5State * st) { MD5object *md5 = (MD5object *)PyObject_GC_New(MD5object, st->md5_type); + md5->lock = NULL; PyObject_GC_Track(md5); return md5; } @@ -350,8 +88,12 @@ MD5_traverse(PyObject *ptr, visitproc visit, void *arg) } static void -MD5_dealloc(PyObject *ptr) +MD5_dealloc(MD5object *ptr) { + Hacl_Streaming_MD5_legacy_free(ptr->hash_state); + if (ptr->lock != NULL) { + PyThread_free_lock(ptr->lock); + } PyTypeObject *tp = Py_TYPE(ptr); PyObject_GC_UnTrack(ptr); PyObject_GC_Del(ptr); @@ -373,13 +115,15 @@ static PyObject * MD5Type_copy_impl(MD5object *self, PyTypeObject *cls) /*[clinic end generated code: output=bf055e08244bf5ee input=d89087dcfb2a8620]*/ { - MD5State *st = PyType_GetModuleState(cls); + MD5State *st = _PyType_GetModuleState(cls); MD5object *newobj; if ((newobj = newMD5object(st))==NULL) return NULL; - newobj->hash_state = self->hash_state; + ENTER_HASHLIB(self); + newobj->hash_state = Hacl_Streaming_MD5_legacy_copy(self->hash_state); + LEAVE_HASHLIB(self); return (PyObject *)newobj; } @@ -394,10 +138,9 @@ MD5Type_digest_impl(MD5object *self) /*[clinic end generated code: output=eb691dc4190a07ec input=bc0c4397c2994be6]*/ { unsigned char digest[MD5_DIGESTSIZE]; - struct md5_state temp; - - temp = self->hash_state; - md5_done(&temp, digest); + ENTER_HASHLIB(self); + Hacl_Streaming_MD5_legacy_finish(self->hash_state, digest); + LEAVE_HASHLIB(self); return PyBytes_FromStringAndSize((const char *)digest, MD5_DIGESTSIZE); } @@ -412,15 +155,23 @@ MD5Type_hexdigest_impl(MD5object *self) /*[clinic end generated code: output=17badced1f3ac932 input=b60b19de644798dd]*/ { unsigned char digest[MD5_DIGESTSIZE]; - struct md5_state temp; - - /* Get the raw (binary) digest value */ - temp = self->hash_state; - md5_done(&temp, digest); - + ENTER_HASHLIB(self); + Hacl_Streaming_MD5_legacy_finish(self->hash_state, digest); + LEAVE_HASHLIB(self); return _Py_strhex((const char*)digest, MD5_DIGESTSIZE); } +static void update(Hacl_Streaming_MD5_state *state, uint8_t *buf, Py_ssize_t len) { +#if PY_SSIZE_T_MAX > UINT32_MAX + while (len > UINT32_MAX) { + Hacl_Streaming_MD5_legacy_update(state, buf, UINT32_MAX); + len -= UINT32_MAX; + buf += UINT32_MAX; + } +#endif + Hacl_Streaming_MD5_legacy_update(state, buf, (uint32_t) len); +} + /*[clinic input] MD5Type.update @@ -438,7 +189,18 @@ MD5Type_update(MD5object *self, PyObject *obj) GET_BUFFER_VIEW_OR_ERROUT(obj, &buf); - md5_process(&self->hash_state, buf.buf, buf.len); + if (self->lock == NULL && buf.len >= HASHLIB_GIL_MINSIZE) { + self->lock = PyThread_allocate_lock(); + } + if (self->lock != NULL) { + Py_BEGIN_ALLOW_THREADS + PyThread_acquire_lock(self->lock, 1); + update(self->hash_state, buf.buf, buf.len); + PyThread_release_lock(self->lock); + Py_END_ALLOW_THREADS + } else { + update(self->hash_state, buf.buf, buf.len); + } PyBuffer_Release(&buf); Py_RETURN_NONE; @@ -531,7 +293,7 @@ _md5_md5_impl(PyObject *module, PyObject *string, int usedforsecurity) return NULL; } - md5_init(&new->hash_state); + new->hash_state = Hacl_Streaming_MD5_legacy_create_in(); if (PyErr_Occurred()) { Py_DECREF(new); @@ -540,7 +302,15 @@ _md5_md5_impl(PyObject *module, PyObject *string, int usedforsecurity) return NULL; } if (string) { - md5_process(&new->hash_state, buf.buf, buf.len); + if (buf.len >= HASHLIB_GIL_MINSIZE) { + /* We do not initialize self->lock here as this is the constructor + * where it is not yet possible to have concurrent access. */ + Py_BEGIN_ALLOW_THREADS + update(new->hash_state, buf.buf, buf.len); + Py_END_ALLOW_THREADS + } else { + update(new->hash_state, buf.buf, buf.len); + } PyBuffer_Release(&buf); } @@ -601,6 +371,7 @@ md5_exec(PyObject *m) static PyModuleDef_Slot _md5_slots[] = { {Py_mod_exec, md5_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; diff --git a/Modules/mmapmodule.c b/Modules/mmapmodule.c index ec364657..c5e6c27f 100644 --- a/Modules/mmapmodule.c +++ b/Modules/mmapmodule.c @@ -29,6 +29,10 @@ #include "structmember.h" // PyMemberDef #include <stddef.h> // offsetof() +// to support MS_WINDOWS_SYSTEM OpenFileMappingA / CreateFileMappingA +// need to be replaced with OpenFileMappingW / CreateFileMappingW +#if !defined(MS_WINDOWS) || defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_GAMES) + #ifndef MS_WINDOWS #define UNIX # ifdef HAVE_FCNTL_H @@ -120,18 +124,6 @@ typedef struct { access_mode access; } mmap_object; -typedef struct { - PyTypeObject *mmap_object_type; -} mmap_state; - -static mmap_state * -get_mmap_state(PyObject *module) -{ - mmap_state *state = PyModule_GetState(module); - assert(state); - return state; -} - static int mmap_object_traverse(mmap_object *m_obj, visitproc visit, void *arg) { @@ -235,6 +227,14 @@ do { \ return err; \ } \ } while (0) +#define CHECK_VALID_OR_RELEASE(err, buffer) \ +do { \ + if (self->map_handle == NULL) { \ + PyErr_SetString(PyExc_ValueError, "mmap closed or invalid"); \ + PyBuffer_Release(&(buffer)); \ + return (err); \ + } \ +} while (0) #endif /* MS_WINDOWS */ #ifdef UNIX @@ -245,6 +245,14 @@ do { \ return err; \ } \ } while (0) +#define CHECK_VALID_OR_RELEASE(err, buffer) \ +do { \ + if (self->data == NULL) { \ + PyErr_SetString(PyExc_ValueError, "mmap closed or invalid"); \ + PyBuffer_Release(&(buffer)); \ + return (err); \ + } \ +} while (0) #endif /* UNIX */ static PyObject * @@ -292,7 +300,8 @@ mmap_read_method(mmap_object *self, CHECK_VALID(NULL); if (!PyArg_ParseTuple(args, "|O&:read", _Py_convert_optional_to_ssize_t, &num_bytes)) - return(NULL); + return NULL; + CHECK_VALID(NULL); /* silently 'adjust' out-of-range requests */ remaining = (self->pos < self->size) ? self->size - self->pos : 0; @@ -333,12 +342,18 @@ mmap_gfind(mmap_object *self, end = self->size; Py_ssize_t res; - if (reverse) { + CHECK_VALID_OR_RELEASE(NULL, view); + if (end < start) { + res = -1; + } + else if (reverse) { + assert(0 <= start && start <= end && end <= self->size); res = _PyBytes_ReverseFind( self->data + start, end - start, view.buf, view.len, start); } else { + assert(0 <= start && start <= end && end <= self->size); res = _PyBytes_Find( self->data + start, end - start, view.buf, view.len, start); @@ -396,7 +411,7 @@ mmap_write_method(mmap_object *self, CHECK_VALID(NULL); if (!PyArg_ParseTuple(args, "y*:write", &data)) - return(NULL); + return NULL; if (!is_writable(self)) { PyBuffer_Release(&data); @@ -409,6 +424,7 @@ mmap_write_method(mmap_object *self, return NULL; } + CHECK_VALID_OR_RELEASE(NULL, data); memcpy(&self->data[self->pos], data.buf, data.len); self->pos += data.len; PyBuffer_Release(&data); @@ -428,6 +444,7 @@ mmap_write_byte_method(mmap_object *self, if (!is_writable(self)) return NULL; + CHECK_VALID(NULL); if (self->pos < self->size) { self->data[self->pos++] = value; Py_RETURN_NONE; @@ -514,7 +531,7 @@ mmap_resize_method(mmap_object *self, CloseHandle(self->map_handle); /* if the file mapping still exists, it cannot be resized. */ if (self->tagname) { - self->map_handle = OpenFileMapping(FILE_MAP_WRITE, FALSE, + self->map_handle = OpenFileMappingA(FILE_MAP_WRITE, FALSE, self->tagname); if (self->map_handle) { PyErr_SetFromWindowsErr(ERROR_USER_MAPPED_FILE); @@ -543,7 +560,7 @@ mmap_resize_method(mmap_object *self, /* create a new file mapping and map a new view */ /* FIXME: call CreateFileMappingW with wchar_t tagname */ - self->map_handle = CreateFileMapping( + self->map_handle = CreateFileMappingA( self->file_handle, NULL, PAGE_READWRITE, @@ -659,7 +676,7 @@ mmap_flush_method(mmap_object *self, PyObject *args) if (self->access == ACCESS_READ || self->access == ACCESS_COPY) Py_RETURN_NONE; -#ifdef MS_WINDOWS +#if defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_APP) || defined(MS_WINDOWS_SYSTEM) if (!FlushViewOfFile(self->data+offset, size)) { PyErr_SetFromWindowsErr(GetLastError()); return NULL; @@ -732,6 +749,7 @@ mmap_move_method(mmap_object *self, PyObject *args) if (self->size - dest < cnt || self->size - src < cnt) goto bounds; + CHECK_VALID(NULL); memmove(&self->data[dest], &self->data[src], cnt); Py_RETURN_NONE; @@ -758,8 +776,7 @@ mmap__enter__method(mmap_object *self, PyObject *args) { CHECK_VALID(NULL); - Py_INCREF(self); - return (PyObject *)self; + return Py_NewRef(self); } static PyObject * @@ -817,12 +834,11 @@ mmap__repr__method(PyObject *self) static PyObject * mmap__sizeof__method(mmap_object *self, void *unused) { - Py_ssize_t res; - - res = _PyObject_SIZE(Py_TYPE(self)); - if (self->tagname) + size_t res = _PyObject_SIZE(Py_TYPE(self)); + if (self->tagname) { res += strlen(self->tagname) + 1; - return PyLong_FromSsize_t(res); + } + return PyLong_FromSize_t(res); } #endif @@ -857,6 +873,7 @@ mmap_madvise_method(mmap_object *self, PyObject *args) length = self->size - start; } + CHECK_VALID(NULL); if (madvise(self->data + start, length, option) != 0) { PyErr_SetFromErrno(PyExc_OSError); return NULL; @@ -955,6 +972,7 @@ mmap_subscript(mmap_object *self, PyObject *item) "mmap index out of range"); return NULL; } + CHECK_VALID(NULL); return PyLong_FromLong(Py_CHARMASK(self->data[i])); } else if (PySlice_Check(item)) { @@ -965,6 +983,7 @@ mmap_subscript(mmap_object *self, PyObject *item) } slicelen = PySlice_AdjustIndices(self->size, &start, &stop, step); + CHECK_VALID(NULL); if (slicelen <= 0) return PyBytes_FromStringAndSize("", 0); else if (step == 1) @@ -978,6 +997,7 @@ mmap_subscript(mmap_object *self, PyObject *item) if (result_buf == NULL) return PyErr_NoMemory(); + for (cur = start, i = 0; i < slicelen; cur += step, i++) { result_buf[i] = self->data[cur]; @@ -1062,6 +1082,7 @@ mmap_ass_subscript(mmap_object *self, PyObject *item, PyObject *value) "in range(0, 256)"); return -1; } + CHECK_VALID(-1); self->data[i] = (char) v; return 0; } @@ -1087,6 +1108,7 @@ mmap_ass_subscript(mmap_object *self, PyObject *item, PyObject *value) return -1; } + CHECK_VALID_OR_RELEASE(-1, vbuf); if (slicelen == 0) { } else if (step == 1) { @@ -1330,10 +1352,11 @@ new_mmap_object(PyTypeObject *type, PyObject *args, PyObject *kwdict) } } - m_obj->data = mmap(NULL, map_size, - prot, flags, - fd, offset); + Py_BEGIN_ALLOW_THREADS + m_obj->data = mmap(NULL, map_size, prot, flags, fd, offset); + Py_END_ALLOW_THREADS + int saved_errno = errno; if (devzero != -1) { close(devzero); } @@ -1341,6 +1364,7 @@ new_mmap_object(PyTypeObject *type, PyObject *args, PyObject *kwdict) if (m_obj->data == (char *)-1) { m_obj->data = NULL; Py_DECREF(m_obj); + errno = saved_errno; PyErr_SetFromErrno(PyExc_OSError); return NULL; } @@ -1528,12 +1552,12 @@ new_mmap_object(PyTypeObject *type, PyObject *args, PyObject *kwdict) off_lo = (DWORD)(offset & 0xFFFFFFFF); /* For files, it would be sufficient to pass 0 as size. For anonymous maps, we have to pass the size explicitly. */ - m_obj->map_handle = CreateFileMapping(m_obj->file_handle, - NULL, - flProtect, - size_hi, - size_lo, - m_obj->tagname); + m_obj->map_handle = CreateFileMappingA(m_obj->file_handle, + NULL, + flProtect, + size_hi, + size_lo, + m_obj->tagname); if (m_obj->map_handle != NULL) { m_obj->data = (char *) MapViewOfFile(m_obj->map_handle, dwDesiredAccess, @@ -1555,46 +1579,23 @@ new_mmap_object(PyTypeObject *type, PyObject *args, PyObject *kwdict) } #endif /* MS_WINDOWS */ -static int -mmap_traverse(PyObject *module, visitproc visit, void *arg) -{ - mmap_state *state = get_mmap_state(module); - Py_VISIT(state->mmap_object_type); - return 0; -} - -static int -mmap_clear(PyObject *module) -{ - mmap_state *state = get_mmap_state(module); - Py_CLEAR(state->mmap_object_type); - return 0; -} - -static void -mmap_free(void *module) -{ - mmap_clear((PyObject *)module); -} - static int mmap_exec(PyObject *module) { - mmap_state *state = get_mmap_state(module); - Py_INCREF(PyExc_OSError); if (PyModule_AddObject(module, "error", PyExc_OSError) < 0) { Py_DECREF(PyExc_OSError); return -1; } - state->mmap_object_type = (PyTypeObject *)PyType_FromModuleAndSpec(module, - &mmap_object_spec, - NULL); - if (state->mmap_object_type == NULL) { + PyObject *mmap_object_type = PyType_FromModuleAndSpec(module, + &mmap_object_spec, NULL); + if (mmap_object_type == NULL) { return -1; } - if (PyModule_AddType(module, state->mmap_object_type) < 0) { + int rc = PyModule_AddType(module, (PyTypeObject *)mmap_object_type); + Py_DECREF(mmap_object_type); + if (rc < 0) { return -1; } @@ -1640,6 +1641,12 @@ mmap_exec(PyObject *module) // Mostly a no-op on Linux and NetBSD, but useful on OpenBSD // for stack usage (even on x86 arch) ADD_INT_MACRO(module, MAP_STACK); +#endif +#ifdef MAP_ALIGNED_SUPER + ADD_INT_MACRO(module, MAP_ALIGNED_SUPER); +#endif +#ifdef MAP_CONCEAL + ADD_INT_MACRO(module, MAP_CONCEAL); #endif if (PyModule_AddIntConstant(module, "PAGESIZE", (long)my_getpagesize()) < 0 ) { return -1; @@ -1740,17 +1747,15 @@ mmap_exec(PyObject *module) static PyModuleDef_Slot mmap_slots[] = { {Py_mod_exec, mmap_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; static struct PyModuleDef mmapmodule = { - PyModuleDef_HEAD_INIT, + .m_base = PyModuleDef_HEAD_INIT, .m_name = "mmap", - .m_size = sizeof(mmap_state), + .m_size = 0, .m_slots = mmap_slots, - .m_traverse = mmap_traverse, - .m_clear = mmap_clear, - .m_free = mmap_free, }; PyMODINIT_FUNC @@ -1758,3 +1763,5 @@ PyInit_mmap(void) { return PyModuleDef_Init(&mmapmodule); } + +#endif /* !MS_WINDOWS || MS_WINDOWS_DESKTOP || MS_WINDOWS_GAMES */ diff --git a/Modules/nismodule.c b/Modules/nismodule.c index 39b99116..6d094490 100644 --- a/Modules/nismodule.c +++ b/Modules/nismodule.c @@ -458,8 +458,7 @@ nis_maps (PyObject *module, PyObject *args, PyObject *kwdict) if (!str || PyList_Append(list, str) < 0) { Py_XDECREF(str); - Py_DECREF(list); - list = NULL; + Py_SETREF(list, NULL); break; } Py_DECREF(str); @@ -503,6 +502,9 @@ nis_exec(PyObject *module) static PyModuleDef_Slot nis_slots[] = { {Py_mod_exec, nis_exec}, + // XXX gh-103092: fix isolation. + {Py_mod_multiple_interpreters, Py_MOD_MULTIPLE_INTERPRETERS_NOT_SUPPORTED}, + //{Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; diff --git a/Modules/ossaudiodev.c b/Modules/ossaudiodev.c index 0568b6dc..2319eac4 100644 --- a/Modules/ossaudiodev.c +++ b/Modules/ossaudiodev.c @@ -20,7 +20,6 @@ #ifndef Py_BUILD_CORE_BUILTIN # define Py_BUILD_CORE_MODULE 1 #endif -#define NEEDS_PY_IDENTIFIER #define PY_SSIZE_T_CLEAN #include "Python.h" @@ -535,16 +534,13 @@ oss_close(oss_audio_t *self, PyObject *unused) static PyObject * oss_self(PyObject *self, PyObject *unused) { - Py_INCREF(self); - return self; + return Py_NewRef(self); } static PyObject * oss_exit(PyObject *self, PyObject *unused) { - _Py_IDENTIFIER(close); - - PyObject *ret = _PyObject_CallMethodIdNoArgs(self, &PyId_close); + PyObject *ret = PyObject_CallMethod(self, "close", NULL); if (!ret) return NULL; Py_DECREF(ret); @@ -573,7 +569,7 @@ oss_setparameters(oss_audio_t *self, PyObject *args) if (!_is_fd_valid(self->fd)) return NULL; - if (!PyArg_ParseTuple(args, "iii|i:setparameters", + if (!PyArg_ParseTuple(args, "iii|p:setparameters", &wanted_fmt, &wanted_channels, &wanted_rate, &strict)) return NULL; @@ -1138,10 +1134,8 @@ PyInit_ossaudiodev(void) NULL, NULL); if (OSSAudioError) { /* Each call to PyModule_AddObject decrefs it; compensate: */ - Py_INCREF(OSSAudioError); - Py_INCREF(OSSAudioError); - PyModule_AddObject(m, "error", OSSAudioError); - PyModule_AddObject(m, "OSSAudioError", OSSAudioError); + PyModule_AddObject(m, "error", Py_NewRef(OSSAudioError)); + PyModule_AddObject(m, "OSSAudioError", Py_NewRef(OSSAudioError)); } /* Build 'control_labels' and 'control_names' lists and add them diff --git a/Modules/overlapped.c b/Modules/overlapped.c index 9334dcaa..afdd78d1 100644 --- a/Modules/overlapped.c +++ b/Modules/overlapped.c @@ -32,27 +32,41 @@ #define T_HANDLE T_POINTER /*[python input] -class OVERLAPPED_converter(CConverter): - type = 'OVERLAPPED *' +class pointer_converter(CConverter): format_unit = '"F_POINTER"' -class HANDLE_converter(CConverter): + def parse_arg(self, argname, displayname): + return """ + {paramname} = PyLong_AsVoidPtr({argname}); + if (!{paramname} && PyErr_Occurred()) {{{{ + goto exit; + }}}} + """.format(argname=argname, paramname=self.parser_name) + +class OVERLAPPED_converter(pointer_converter): + type = 'OVERLAPPED *' + +class HANDLE_converter(pointer_converter): type = 'HANDLE' - format_unit = '"F_HANDLE"' -class ULONG_PTR_converter(CConverter): +class ULONG_PTR_converter(pointer_converter): type = 'ULONG_PTR' - format_unit = '"F_ULONG_PTR"' -class DWORD_converter(CConverter): + def parse_arg(self, argname, displayname): + return """ + {paramname} = (uintptr_t)PyLong_AsVoidPtr({argname}); + if (!{paramname} && PyErr_Occurred()) {{{{ + goto exit; + }}}} + """.format(argname=argname, paramname=self.parser_name) + +class DWORD_converter(unsigned_long_converter): type = 'DWORD' - format_unit = 'k' -class BOOL_converter(CConverter): +class BOOL_converter(int_converter): type = 'BOOL' - format_unit = 'i' [python start generated code]*/ -/*[python end generated code: output=da39a3ee5e6b4b0d input=83bb8c2c2514f2a8]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=8a07ea3018f4cec8]*/ /*[clinic input] module _overlapped @@ -105,18 +119,6 @@ typedef struct { }; } OverlappedObject; -typedef struct { - PyTypeObject *overlapped_type; -} OverlappedState; - -static inline OverlappedState* -overlapped_get_state(PyObject *module) -{ - void *state = PyModule_GetState(module); - assert(state != NULL); - return (OverlappedState *)state; -} - static inline void steal_buffer(Py_buffer * dst, Py_buffer * src) @@ -365,8 +367,9 @@ _overlapped_RegisterWaitWithQueue_impl(PyObject *module, HANDLE Object, &NewWaitObject, Object, PostToQueueCallback, pdata, Milliseconds, WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE)) { + SetFromWindowsErr(0); PyMem_RawFree(pdata); - return SetFromWindowsErr(0); + return NULL; } return Py_BuildValue(F_HANDLE, NewWaitObject); @@ -910,8 +913,7 @@ _overlapped_Overlapped_getresult_impl(OverlappedObject *self, BOOL wait) _PyBytes_Resize(&self->allocated_buffer, transferred)) return NULL; - Py_INCREF(self->allocated_buffer); - return self->allocated_buffer; + return Py_NewRef(self->allocated_buffer); case TYPE_READ_FROM: assert(PyBytes_CheckExact(self->read_from.allocated_buffer)); @@ -938,14 +940,12 @@ _overlapped_Overlapped_getresult_impl(OverlappedObject *self, BOOL wait) } // first item: message - Py_INCREF(self->read_from.allocated_buffer); PyTuple_SET_ITEM(self->read_from.result, 0, - self->read_from.allocated_buffer); + Py_NewRef(self->read_from.allocated_buffer)); // second item: address PyTuple_SET_ITEM(self->read_from.result, 1, addr); - Py_INCREF(self->read_from.result); - return self->read_from.result; + return Py_NewRef(self->read_from.result); case TYPE_READ_FROM_INTO: // unparse the address addr = unparse_address((SOCKADDR*)&self->read_from_into.address, @@ -968,8 +968,7 @@ _overlapped_Overlapped_getresult_impl(OverlappedObject *self, BOOL wait) // second item: address PyTuple_SET_ITEM(self->read_from_into.result, 1, addr); - Py_INCREF(self->read_from_into.result); - return self->read_from_into.result; + return Py_NewRef(self->read_from_into.result); default: return PyLong_FromUnsignedLong((unsigned long) transferred); } @@ -1346,7 +1345,7 @@ static int parse_address(PyObject *obj, SOCKADDR *Address, int Length) { PyObject *Host_obj; - Py_UNICODE *Host; + wchar_t *Host; unsigned short Port; unsigned long FlowInfo; unsigned long ScopeId; @@ -1358,11 +1357,7 @@ parse_address(PyObject *obj, SOCKADDR *Address, int Length) if (!PyArg_ParseTuple(obj, "UH", &Host_obj, &Port)) { return -1; } -#if USE_UNICODE_WCHAR_CACHE - Host = (wchar_t *)_PyUnicode_AsUnicode(Host_obj); -#else /* USE_UNICODE_WCHAR_CACHE */ Host = PyUnicode_AsWideCharString(Host_obj, NULL); -#endif /* USE_UNICODE_WCHAR_CACHE */ if (Host == NULL) { return -1; } @@ -1374,9 +1369,7 @@ parse_address(PyObject *obj, SOCKADDR *Address, int Length) else { ((SOCKADDR_IN*)Address)->sin_port = htons(Port); } -#if !USE_UNICODE_WCHAR_CACHE PyMem_Free(Host); -#endif /* USE_UNICODE_WCHAR_CACHE */ return Length; } case 4: { @@ -1386,11 +1379,7 @@ parse_address(PyObject *obj, SOCKADDR *Address, int Length) { return -1; } -#if USE_UNICODE_WCHAR_CACHE - Host = (wchar_t *)_PyUnicode_AsUnicode(Host_obj); -#else /* USE_UNICODE_WCHAR_CACHE */ Host = PyUnicode_AsWideCharString(Host_obj, NULL); -#endif /* USE_UNICODE_WCHAR_CACHE */ if (Host == NULL) { return -1; } @@ -1404,9 +1393,7 @@ parse_address(PyObject *obj, SOCKADDR *Address, int Length) ((SOCKADDR_IN6*)Address)->sin6_flowinfo = FlowInfo; ((SOCKADDR_IN6*)Address)->sin6_scope_id = ScopeId; } -#if !USE_UNICODE_WCHAR_CACHE PyMem_Free(Host); -#endif /* USE_UNICODE_WCHAR_CACHE */ return Length; } default: @@ -2008,28 +1995,6 @@ static PyMethodDef overlapped_functions[] = { {NULL} }; -static int -overlapped_traverse(PyObject *module, visitproc visit, void *arg) -{ - OverlappedState *state = overlapped_get_state(module); - Py_VISIT(state->overlapped_type); - return 0; -} - -static int -overlapped_clear(PyObject *module) -{ - OverlappedState *state = overlapped_get_state(module); - Py_CLEAR(state->overlapped_type); - return 0; -} - -static void -overlapped_free(void *module) -{ - overlapped_clear((PyObject *)module); -} - #define WINAPI_CONSTANT(fmt, con) \ do { \ PyObject *value = Py_BuildValue(fmt, con); \ @@ -2057,14 +2022,15 @@ overlapped_exec(PyObject *module) return -1; } - OverlappedState *st = overlapped_get_state(module); - st->overlapped_type = (PyTypeObject *)PyType_FromModuleAndSpec( + PyTypeObject *overlapped_type = (PyTypeObject *)PyType_FromModuleAndSpec( module, &overlapped_type_spec, NULL); - if (st->overlapped_type == NULL) { + if (overlapped_type == NULL) { return -1; } - if (PyModule_AddType(module, st->overlapped_type) < 0) { + int rc = PyModule_AddType(module, overlapped_type); + Py_DECREF(overlapped_type); + if (rc < 0) { return -1; } @@ -2085,18 +2051,15 @@ overlapped_exec(PyObject *module) static PyModuleDef_Slot overlapped_slots[] = { {Py_mod_exec, overlapped_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; static struct PyModuleDef overlapped_module = { - PyModuleDef_HEAD_INIT, + .m_base = PyModuleDef_HEAD_INIT, .m_name = "_overlapped", - .m_size = sizeof(OverlappedState), .m_methods = overlapped_functions, .m_slots = overlapped_slots, - .m_traverse = overlapped_traverse, - .m_clear = overlapped_clear, - .m_free = overlapped_free }; PyMODINIT_FUNC diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 150bb78c..b9ca2865 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -10,16 +10,6 @@ #define PY_SSIZE_T_CLEAN #include "Python.h" -// Include <windows.h> before pycore internal headers. FSCTL_GET_REPARSE_POINT -// is not exported by <windows.h> if the WIN32_LEAN_AND_MEAN macro is defined, -// whereas pycore_condvar.h defines the WIN32_LEAN_AND_MEAN macro. -#ifdef MS_WINDOWS -# include <windows.h> -# include <pathcch.h> -# include <lmcons.h> // UNLEN -# include "osdefs.h" // SEP -# define HAVE_SYMLINK -#endif #ifdef __VXWORKS__ # include "pycore_bitutils.h" // _Py_popcount32() @@ -34,10 +24,24 @@ #include "pycore_pystate.h" // _PyInterpreterState_GET() #include "pycore_signal.h" // Py_NSIG +#ifdef MS_WINDOWS +# include <windows.h> +# if !defined(MS_WINDOWS_GAMES) || defined(MS_WINDOWS_DESKTOP) +# include <pathcch.h> +# endif +# include <winioctl.h> +# include <lmcons.h> // UNLEN +# include "osdefs.h" // SEP +# if defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) +# define HAVE_SYMLINK +# endif /* MS_WINDOWS_DESKTOP | MS_WINDOWS_SYSTEM */ +#endif + #include "structmember.h" // PyMemberDef #ifndef MS_WINDOWS # include "posixmodule.h" #else +# include "pycore_fileutils_windows.h" # include "winreparse.h" #endif @@ -72,6 +76,8 @@ */ #if defined(__APPLE__) +#include <mach/mach.h> + #if defined(__has_builtin) #if __has_builtin(__builtin_available) #define HAVE_BUILTIN_AVAILABLE 1 @@ -169,6 +175,14 @@ # define HAVE_PWRITEV_RUNTIME (pwritev != NULL) # endif +# ifdef HAVE_MKFIFOAT +# define HAVE_MKFIFOAT_RUNTIME (mkfifoat != NULL) +# endif + +# ifdef HAVE_MKNODAT +# define HAVE_MKNODAT_RUNTIME (mknodat != NULL) +# endif + #endif #ifdef HAVE_FUTIMESAT @@ -272,8 +286,9 @@ corresponding Unix manual entries for more information on calls."); # undef HAVE_SCHED_SETAFFINITY #endif -#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__) && !defined(__FreeBSD_kernel__) && !defined(__GNU__) +#if defined(HAVE_SYS_XATTR_H) && defined(HAVE_LINUX_LIMITS_H) && !defined(__FreeBSD_kernel__) && !defined(__GNU__) # define USE_XATTRS +# include <linux/limits.h> // Needed for XATTR_SIZE_MAX on musl libc. #endif #ifdef USE_XATTRS @@ -309,7 +324,7 @@ corresponding Unix manual entries for more information on calls."); # include <sys/syscall.h> #endif -#if defined(MS_WINDOWS) +#ifdef HAVE_WINDOWS_CONSOLE_IO # define TERMSIZE_USE_CONIO #elif defined(HAVE_SYS_IOCTL_H) # include <sys/ioctl.h> @@ -319,7 +334,7 @@ corresponding Unix manual entries for more information on calls."); # if defined(TIOCGWINSZ) # define TERMSIZE_USE_IOCTL # endif -#endif /* MS_WINDOWS */ +#endif /* HAVE_WINDOWS_CONSOLE_IO */ /* Various compilers have only certain posix functions */ /* XXX Gosh I wish these were all moved into pyconfig.h */ @@ -327,21 +342,25 @@ corresponding Unix manual entries for more information on calls."); # define HAVE_OPENDIR 1 # define HAVE_SYSTEM 1 # include <process.h> -#else -# ifdef _MSC_VER - /* Microsoft compiler */ +#elif defined( _MSC_VER) + /* Microsoft compiler */ +# if defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_APP) || defined(MS_WINDOWS_SYSTEM) # define HAVE_GETPPID 1 +# endif /* MS_WINDOWS_DESKTOP | MS_WINDOWS_APP | MS_WINDOWS_SYSTEM */ +# if defined(MS_WINDOWS_DESKTOP) # define HAVE_GETLOGIN 1 +# endif /* MS_WINDOWS_DESKTOP */ +# if defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) # define HAVE_SPAWNV 1 # define HAVE_EXECV 1 # define HAVE_WSPAWNV 1 # define HAVE_WEXECV 1 -# define HAVE_PIPE 1 # define HAVE_SYSTEM 1 # define HAVE_CWAIT 1 -# define HAVE_FSYNC 1 -# define fsync _commit -# endif /* _MSC_VER */ +# endif /* MS_WINDOWS_DESKTOP | MS_WINDOWS_SYSTEM */ +# define HAVE_PIPE 1 +# define HAVE_FSYNC 1 +# define fsync _commit #endif /* ! __WATCOMC__ || __QNX__ */ /*[clinic input] @@ -495,9 +514,11 @@ extern char *ctermid_r(char *); #ifdef MS_WINDOWS # define INITFUNC PyInit_nt # define MODNAME "nt" +# define MODNAME_OBJ &_Py_ID(nt) #else # define INITFUNC PyInit_posix # define MODNAME "posix" +# define MODNAME_OBJ &_Py_ID(posix) #endif #if defined(__sun) @@ -563,18 +584,21 @@ run_at_forkers(PyObject *lst, int reverse) void PyOS_BeforeFork(void) { - run_at_forkers(_PyInterpreterState_GET()->before_forkers, 1); + PyInterpreterState *interp = _PyInterpreterState_GET(); + run_at_forkers(interp->before_forkers, 1); - _PyImport_AcquireLock(); + _PyImport_AcquireLock(interp); } void PyOS_AfterFork_Parent(void) { - if (_PyImport_ReleaseLock() <= 0) + PyInterpreterState *interp = _PyInterpreterState_GET(); + if (_PyImport_ReleaseLock(interp) <= 0) { Py_FatalError("failed releasing import lock after fork"); + } - run_at_forkers(_PyInterpreterState_GET()->after_forkers_parent, 0); + run_at_forkers(interp->after_forkers_parent, 0); } void @@ -583,7 +607,7 @@ PyOS_AfterFork_Child(void) PyStatus status; _PyRuntimeState *runtime = &_PyRuntime; - status = _PyGILState_Reinit(runtime); + status = _PyRuntimeState_ReInitThreads(runtime); if (_PyStatus_EXCEPTION(status)) { goto fatal_error; } @@ -600,23 +624,23 @@ PyOS_AfterFork_Child(void) goto fatal_error; } - status = _PyImport_ReInitLock(); + status = _PyImport_ReInitLock(tstate->interp); if (_PyStatus_EXCEPTION(status)) { goto fatal_error; } _PySignal_AfterFork(); - status = _PyRuntimeState_ReInitThreads(runtime); + status = _PyInterpreterState_DeleteExceptMain(runtime); if (_PyStatus_EXCEPTION(status)) { goto fatal_error; } + assert(_PyThreadState_GET() == tstate); - status = _PyInterpreterState_DeleteExceptMain(runtime); + status = _PyPerfTrampoline_AfterFork_Child(); if (_PyStatus_EXCEPTION(status)) { goto fatal_error; } - assert(_PyThreadState_GET() == tstate); run_at_forkers(tstate->interp->after_forkers_child, 0); return; @@ -653,8 +677,11 @@ PyOS_AfterFork(void) #ifdef MS_WINDOWS /* defined in fileutils.c */ void _Py_time_t_to_FILE_TIME(time_t, int, FILETIME *); -void _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *, - ULONG, struct _Py_stat_struct *); +void _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *, ULONG, + FILE_BASIC_INFO *, FILE_ID_INFO *, + struct _Py_stat_struct *); +void _Py_stat_basic_info_to_stat(FILE_STAT_BASIC_INFORMATION *, + struct _Py_stat_struct *); #endif @@ -973,6 +1000,7 @@ typedef struct { #if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM) PyObject *SchedParamType; #endif + newfunc statresult_new_orig; PyObject *StatResultType; PyObject *StatVFSResultType; PyObject *TerminalSizeType; @@ -1110,11 +1138,9 @@ typedef struct { static void path_cleanup(path_t *path) { -#if !USE_UNICODE_WCHAR_CACHE wchar_t *wide = (wchar_t *)path->wide; path->wide = NULL; PyMem_Free(wide); -#endif /* USE_UNICODE_WCHAR_CACHE */ Py_CLEAR(path->object); Py_CLEAR(path->cleanup); } @@ -1125,7 +1151,7 @@ path_converter(PyObject *o, void *p) path_t *path = (path_t *)p; PyObject *bytes = NULL; Py_ssize_t length = 0; - int is_index, is_buffer, is_bytes, is_unicode; + int is_index, is_bytes, is_unicode; const char *narrow; #ifdef MS_WINDOWS PyObject *wo = NULL; @@ -1163,11 +1189,10 @@ path_converter(PyObject *o, void *p) /* Only call this here so that we don't treat the return value of os.fspath() as an fd or buffer. */ is_index = path->allow_fd && PyIndex_Check(o); - is_buffer = PyObject_CheckBuffer(o); is_bytes = PyBytes_Check(o); is_unicode = PyUnicode_Check(o); - if (!is_index && !is_buffer && !is_unicode && !is_bytes) { + if (!is_index && !is_unicode && !is_bytes) { /* Inline PyOS_FSPath() for better error messages. */ PyObject *func, *res; @@ -1196,20 +1221,12 @@ path_converter(PyObject *o, void *p) } /* still owns a reference to the original object */ - Py_DECREF(o); - o = res; + Py_SETREF(o, res); } if (is_unicode) { #ifdef MS_WINDOWS -#if USE_UNICODE_WCHAR_CACHE -_Py_COMP_DIAG_PUSH -_Py_COMP_DIAG_IGNORE_DEPR_DECLS - wide = PyUnicode_AsUnicodeAndSize(o, &length); -_Py_COMP_DIAG_POP -#else /* USE_UNICODE_WCHAR_CACHE */ wide = PyUnicode_AsWideCharString(o, &length); -#endif /* USE_UNICODE_WCHAR_CACHE */ if (!wide) { goto error_exit; } @@ -1225,9 +1242,7 @@ _Py_COMP_DIAG_POP path->wide = wide; path->narrow = FALSE; path->fd = -1; -#if !USE_UNICODE_WCHAR_CACHE wide = NULL; -#endif /* USE_UNICODE_WCHAR_CACHE */ goto success_exit; #else if (!PyUnicode_FSConverter(o, &bytes)) { @@ -1236,29 +1251,7 @@ _Py_COMP_DIAG_POP #endif } else if (is_bytes) { - bytes = o; - Py_INCREF(bytes); - } - else if (is_buffer) { - /* XXX Replace PyObject_CheckBuffer with PyBytes_Check in other code - after removing support of non-bytes buffer objects. */ - if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, - "%s%s%s should be %s, not %.200s", - path->function_name ? path->function_name : "", - path->function_name ? ": " : "", - path->argument_name ? path->argument_name : "path", - path->allow_fd && path->nullable ? "string, bytes, os.PathLike, " - "integer or None" : - path->allow_fd ? "string, bytes, os.PathLike or integer" : - path->nullable ? "string, bytes, os.PathLike or None" : - "string, bytes or os.PathLike", - _PyType_Name(Py_TYPE(o)))) { - goto error_exit; - } - bytes = PyBytes_FromObject(o); - if (!bytes) { - goto error_exit; - } + bytes = Py_NewRef(o); } else if (is_index) { if (!_fd_converter(o, &path->fd)) { @@ -1303,15 +1296,8 @@ _Py_COMP_DIAG_POP goto error_exit; } -#if USE_UNICODE_WCHAR_CACHE -_Py_COMP_DIAG_PUSH -_Py_COMP_DIAG_IGNORE_DEPR_DECLS - wide = PyUnicode_AsUnicodeAndSize(wo, &length); -_Py_COMP_DIAG_POP -#else /* USE_UNICODE_WCHAR_CACHE */ wide = PyUnicode_AsWideCharString(wo, &length); Py_DECREF(wo); -#endif /* USE_UNICODE_WCHAR_CACHE */ if (!wide) { goto error_exit; } @@ -1326,11 +1312,7 @@ _Py_COMP_DIAG_POP path->wide = wide; path->narrow = TRUE; Py_DECREF(bytes); -#if USE_UNICODE_WCHAR_CACHE - path->cleanup = wo; -#else /* USE_UNICODE_WCHAR_CACHE */ wide = NULL; -#endif /* USE_UNICODE_WCHAR_CACHE */ #else path->wide = NULL; path->narrow = narrow; @@ -1354,11 +1336,7 @@ _Py_COMP_DIAG_POP Py_XDECREF(o); Py_XDECREF(bytes); #ifdef MS_WINDOWS -#if USE_UNICODE_WCHAR_CACHE - Py_XDECREF(wo); -#else /* USE_UNICODE_WCHAR_CACHE */ PyMem_Free(wide); -#endif /* USE_UNICODE_WCHAR_CACHE */ #endif return 0; } @@ -1551,32 +1529,6 @@ error: } #endif /* HAVE_SIGSET_T */ -#ifdef MS_WINDOWS - -static int -win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag) -{ - char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; - _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer; - DWORD n_bytes_returned; - - if (0 == DeviceIoControl( - reparse_point_handle, - FSCTL_GET_REPARSE_POINT, - NULL, 0, /* in buffer */ - target_buffer, sizeof(target_buffer), - &n_bytes_returned, - NULL)) /* we're not using OVERLAPPED_IO */ - return FALSE; - - if (reparse_tag) - *reparse_tag = rdb->ReparseTag; - - return TRUE; -} - -#endif /* MS_WINDOWS */ - /* Return a dictionary corresponding to the POSIX environment table */ #if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED)) /* On Darwin/MacOSX a shared library or framework has no access to @@ -1604,7 +1556,7 @@ convertenviron(void) #ifdef MS_WINDOWS /* _wenviron must be initialized in this way if the program is started through main() instead of wmain(). */ - _wgetenv(L""); + (void)_wgetenv(L""); e = _wenviron; #elif defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED)) /* environ is not accessible as an extern in a shared object on OSX; use @@ -1853,6 +1805,10 @@ attributes_from_dir(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *re if (n && (pszFile[n - 1] == L'\\' || pszFile[n - 1] == L'/')) { // cannot use PyMem_Malloc here because we do not hold the GIL filename = (LPCWSTR)malloc((n + 1) * sizeof(filename[0])); + if(!filename) { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return FALSE; + } wcsncpy_s((LPWSTR)filename, n + 1, pszFile, n); while (--n > 0 && (filename[n] == L'\\' || filename[n] == L'/')) { ((LPWSTR)filename)[n] = L'\0'; @@ -1875,12 +1831,40 @@ attributes_from_dir(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *re return TRUE; } + +static void +update_st_mode_from_path(const wchar_t *path, DWORD attr, + struct _Py_stat_struct *result) +{ + if (!(attr & FILE_ATTRIBUTE_DIRECTORY)) { + /* Fix the file execute permissions. This hack sets S_IEXEC if + the filename has an extension that is commonly used by files + that CreateProcessW can execute. A real implementation calls + GetSecurityInfo, OpenThreadToken/OpenProcessToken, and + AccessCheck to check for generic read, write, and execute + access. */ + const wchar_t *fileExtension = wcsrchr(path, '.'); + if (fileExtension) { + if (_wcsicmp(fileExtension, L".exe") == 0 || + _wcsicmp(fileExtension, L".bat") == 0 || + _wcsicmp(fileExtension, L".cmd") == 0 || + _wcsicmp(fileExtension, L".com") == 0) { + result->st_mode |= 0111; + } + } + } +} + + static int -win32_xstat_impl(const wchar_t *path, struct _Py_stat_struct *result, - BOOL traverse) +win32_xstat_slow_impl(const wchar_t *path, struct _Py_stat_struct *result, + BOOL traverse) { HANDLE hFile; BY_HANDLE_FILE_INFORMATION fileInfo; + FILE_BASIC_INFO basicInfo; + FILE_ID_INFO idInfo; + FILE_ID_INFO *pIdInfo = &idInfo; FILE_ATTRIBUTE_TAG_INFO tagInfo = { 0 }; DWORD fileType, error; BOOL isUnhandledTag = FALSE; @@ -2010,12 +1994,14 @@ win32_xstat_impl(const wchar_t *path, struct _Py_stat_struct *result, for an unhandled tag. */ } else if (!isUnhandledTag) { CloseHandle(hFile); - return win32_xstat_impl(path, result, TRUE); + return win32_xstat_slow_impl(path, result, TRUE); } } } - if (!GetFileInformationByHandle(hFile, &fileInfo)) { + if (!GetFileInformationByHandle(hFile, &fileInfo) || + !GetFileInformationByHandleEx(hFile, FileBasicInfo, + &basicInfo, sizeof(basicInfo))) { switch (GetLastError()) { case ERROR_INVALID_PARAMETER: case ERROR_INVALID_FUNCTION: @@ -2031,26 +2017,14 @@ win32_xstat_impl(const wchar_t *path, struct _Py_stat_struct *result, } } - _Py_attribute_data_to_stat(&fileInfo, tagInfo.ReparseTag, result); - - if (!(fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { - /* Fix the file execute permissions. This hack sets S_IEXEC if - the filename has an extension that is commonly used by files - that CreateProcessW can execute. A real implementation calls - GetSecurityInfo, OpenThreadToken/OpenProcessToken, and - AccessCheck to check for generic read, write, and execute - access. */ - const wchar_t *fileExtension = wcsrchr(path, '.'); - if (fileExtension) { - if (_wcsicmp(fileExtension, L".exe") == 0 || - _wcsicmp(fileExtension, L".bat") == 0 || - _wcsicmp(fileExtension, L".cmd") == 0 || - _wcsicmp(fileExtension, L".com") == 0) { - result->st_mode |= 0111; - } - } + if (!GetFileInformationByHandleEx(hFile, FileIdInfo, &idInfo, sizeof(idInfo))) { + /* Failed to get FileIdInfo, so do not pass it along */ + pIdInfo = NULL; } + _Py_attribute_data_to_stat(&fileInfo, tagInfo.ReparseTag, &basicInfo, pIdInfo, result); + update_st_mode_from_path(path, fileInfo.dwFileAttributes, result); + cleanup: if (hFile != INVALID_HANDLE_VALUE) { /* Preserve last error if we are failing */ @@ -2066,6 +2040,39 @@ cleanup: return retval; } +static int +win32_xstat_impl(const wchar_t *path, struct _Py_stat_struct *result, + BOOL traverse) +{ + FILE_STAT_BASIC_INFORMATION statInfo; + if (_Py_GetFileInformationByName(path, FileStatBasicByNameInfo, + &statInfo, sizeof(statInfo))) { + if (// Cannot use fast path for reparse points ... + !(statInfo.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) + // ... unless it's a name surrogate (symlink) and we're not following + || (!traverse && IsReparseTagNameSurrogate(statInfo.ReparseTag)) + ) { + _Py_stat_basic_info_to_stat(&statInfo, result); + update_st_mode_from_path(path, statInfo.FileAttributes, result); + return 0; + } + } else { + switch(GetLastError()) { + case ERROR_FILE_NOT_FOUND: + case ERROR_PATH_NOT_FOUND: + case ERROR_NOT_READY: + case ERROR_BAD_NET_NAME: + /* These errors aren't worth retrying with the slow path */ + return -1; + case ERROR_NOT_SUPPORTED: + /* indicates the API couldn't be loaded */ + break; + } + } + + return win32_xstat_slow_impl(path, result, traverse); +} + static int win32_xstat(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse) { @@ -2073,6 +2080,10 @@ win32_xstat(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse) setting it to a POSIX error. Callers should use GetLastError. */ int code = win32_xstat_impl(path, result, traverse); errno = 0; + + /* ctime is only deprecated from 3.12, so we copy birthtime across */ + result->st_ctime = result->st_birthtime; + result->st_ctime_nsec = result->st_birthtime_nsec; return code; } /* About the following functions: win32_lstat_w, win32_stat, win32_stat_w @@ -2143,9 +2154,12 @@ static PyStructSequence_Field stat_result_fields[] = { #ifdef HAVE_STRUCT_STAT_ST_GEN {"st_gen", "generation number"}, #endif -#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME +#if defined(HAVE_STRUCT_STAT_ST_BIRTHTIME) || defined(MS_WINDOWS) {"st_birthtime", "time of creation"}, #endif +#ifdef MS_WINDOWS + {"st_birthtime_ns", "time of creation in nanoseconds"}, +#endif #ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES {"st_file_attributes", "Windows file attribute bits"}, #endif @@ -2188,16 +2202,22 @@ static PyStructSequence_Field stat_result_fields[] = { #define ST_GEN_IDX ST_FLAGS_IDX #endif -#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME +#if defined(HAVE_STRUCT_STAT_ST_BIRTHTIME) || defined(MS_WINDOWS) #define ST_BIRTHTIME_IDX (ST_GEN_IDX+1) #else #define ST_BIRTHTIME_IDX ST_GEN_IDX #endif -#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES -#define ST_FILE_ATTRIBUTES_IDX (ST_BIRTHTIME_IDX+1) +#ifdef MS_WINDOWS +#define ST_BIRTHTIME_NS_IDX (ST_BIRTHTIME_IDX+1) +#else +#define ST_BIRTHTIME_NS_IDX ST_BIRTHTIME_IDX +#endif + +#if defined(HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES) || defined(MS_WINDOWS) +#define ST_FILE_ATTRIBUTES_IDX (ST_BIRTHTIME_NS_IDX+1) #else -#define ST_FILE_ATTRIBUTES_IDX ST_BIRTHTIME_IDX +#define ST_FILE_ATTRIBUTES_IDX ST_BIRTHTIME_NS_IDX #endif #ifdef HAVE_STRUCT_STAT_ST_FSTYPE @@ -2274,7 +2294,6 @@ static PyStructSequence_Desc waitid_result_desc = { 5 }; #endif -static newfunc structseq_new; static PyObject * statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds) @@ -2282,6 +2301,19 @@ statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds) PyStructSequence *result; int i; + // ht_module doesn't get set in PyStructSequence_NewType(), + // so we can't use PyType_GetModule(). + PyObject *mod = PyImport_GetModule(MODNAME_OBJ); + if (mod == NULL) { + return NULL; + } + _posixstate *state = get_posix_state(mod); + Py_DECREF(mod); + if (state == NULL) { + return NULL; + } +#define structseq_new state->statresult_new_orig + result = (PyStructSequence*)structseq_new(type, args, kwds); if (!result) return NULL; @@ -2291,8 +2323,7 @@ statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds) for (i = 7; i <= 9; i++) { if (result->ob_item[i+3] == Py_None) { Py_DECREF(Py_None); - Py_INCREF(result->ob_item[i]); - result->ob_item[i+3] = result->ob_item[i]; + result->ob_item[i+3] = Py_NewRef(result->ob_item[i]); } } return (PyObject*)result; @@ -2355,7 +2386,7 @@ _posix_free(void *module) } static void -fill_time(PyObject *module, PyObject *v, int index, time_t sec, unsigned long nsec) +fill_time(PyObject *module, PyObject *v, int s_index, int f_index, int ns_index, time_t sec, unsigned long nsec) { PyObject *s = _PyLong_FromTime_t(sec); PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec); @@ -2379,12 +2410,18 @@ fill_time(PyObject *module, PyObject *v, int index, time_t sec, unsigned long ns goto exit; } - PyStructSequence_SET_ITEM(v, index, s); - PyStructSequence_SET_ITEM(v, index+3, float_s); - PyStructSequence_SET_ITEM(v, index+6, ns_total); - s = NULL; - float_s = NULL; - ns_total = NULL; + if (s_index >= 0) { + PyStructSequence_SET_ITEM(v, s_index, s); + s = NULL; + } + if (f_index >= 0) { + PyStructSequence_SET_ITEM(v, f_index, float_s); + float_s = NULL; + } + if (ns_index >= 0) { + PyStructSequence_SET_ITEM(v, ns_index, ns_total); + ns_total = NULL; + } exit: Py_XDECREF(s); Py_XDECREF(ns_fractional); @@ -2393,6 +2430,33 @@ exit: Py_XDECREF(float_s); } +#ifdef MS_WINDOWS +static PyObject* +_pystat_l128_from_l64_l64(uint64_t low, uint64_t high) +{ + PyObject *o_low = PyLong_FromUnsignedLongLong(low); + if (!o_low || !high) { + return o_low; + } + PyObject *o_high = PyLong_FromUnsignedLongLong(high); + PyObject *l64 = o_high ? PyLong_FromLong(64) : NULL; + if (!l64) { + Py_XDECREF(o_high); + Py_DECREF(o_low); + return NULL; + } + Py_SETREF(o_high, PyNumber_Lshift(o_high, l64)); + Py_DECREF(l64); + if (!o_high) { + Py_DECREF(o_low); + return NULL; + } + Py_SETREF(o_low, PyNumber_Add(o_low, o_high)); + Py_DECREF(o_high); + return o_low; +} +#endif + /* pack a system stat C structure into the Python stat tuple (used by posix_stat() and posix_fstat()) */ static PyObject* @@ -2405,12 +2469,13 @@ _pystat_fromstructstat(PyObject *module, STRUCT_STAT *st) return NULL; PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode)); +#ifdef MS_WINDOWS + PyStructSequence_SET_ITEM(v, 1, _pystat_l128_from_l64_l64(st->st_ino, st->st_ino_high)); + PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLongLong(st->st_dev)); +#else static_assert(sizeof(unsigned long long) >= sizeof(st->st_ino), "stat.st_ino is larger than unsigned long long"); PyStructSequence_SET_ITEM(v, 1, PyLong_FromUnsignedLongLong(st->st_ino)); -#ifdef MS_WINDOWS - PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev)); -#else PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev)); #endif PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink)); @@ -2440,9 +2505,9 @@ _pystat_fromstructstat(PyObject *module, STRUCT_STAT *st) #else ansec = mnsec = cnsec = 0; #endif - fill_time(module, v, 7, st->st_atime, ansec); - fill_time(module, v, 8, st->st_mtime, mnsec); - fill_time(module, v, 9, st->st_ctime, cnsec); + fill_time(module, v, 7, 10, 13, st->st_atime, ansec); + fill_time(module, v, 8, 11, 14, st->st_mtime, mnsec); + fill_time(module, v, 9, 12, 15, st->st_ctime, cnsec); #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX, @@ -2460,7 +2525,7 @@ _pystat_fromstructstat(PyObject *module, STRUCT_STAT *st) PyStructSequence_SET_ITEM(v, ST_GEN_IDX, PyLong_FromLong((long)st->st_gen)); #endif -#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME +#if defined(HAVE_STRUCT_STAT_ST_BIRTHTIME) { PyObject *val; unsigned long bsec,bnsec; @@ -2474,6 +2539,9 @@ _pystat_fromstructstat(PyObject *module, STRUCT_STAT *st) PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX, val); } +#elif defined(MS_WINDOWS) + fill_time(module, v, -1, ST_BIRTHTIME_IDX, ST_BIRTHTIME_NS_IDX, + st->st_birthtime, st->st_birthtime_nsec); #endif #ifdef HAVE_STRUCT_STAT_ST_FLAGS PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX, @@ -3208,6 +3276,9 @@ os.chmod mode: int Operating-system mode bitfield. + Be careful when using number literals for *mode*. The conventional UNIX notation for + numeric modes uses an octal base, which needs to be indicated with a ``0o`` prefix in + Python. * @@ -3233,7 +3304,7 @@ dir_fd and follow_symlinks may not be implemented on your platform. static PyObject * os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd, int follow_symlinks) -/*[clinic end generated code: output=5cf6a94915cc7bff input=989081551c00293b]*/ +/*[clinic end generated code: output=5cf6a94915cc7bff input=674a14bc998de09d]*/ { int result; @@ -3363,7 +3434,12 @@ os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd, os.fchmod fd: int + The file descriptor of the file to be modified. mode: int + Operating-system mode bitfield. + Be careful when using number literals for *mode*. The conventional UNIX notation for + numeric modes uses an octal base, which needs to be indicated with a ``0o`` prefix in + Python. Change the access permissions of the file given by file descriptor fd. @@ -3372,7 +3448,7 @@ Equivalent to os.chmod(fd, mode). static PyObject * os_fchmod_impl(PyObject *module, int fd, int mode) -/*[clinic end generated code: output=afd9bc05b4e426b3 input=8ab11975ca01ee5b]*/ +/*[clinic end generated code: output=afd9bc05b4e426b3 input=b5594618bbbc22df]*/ { int res; int async_err = 0; @@ -3801,9 +3877,10 @@ posix_getcwd(int use_bytes) return NULL; } if (!len) { + PyErr_SetFromWindowsErr(0); if (wbuf2 != wbuf) PyMem_RawFree(wbuf2); - return PyErr_SetFromWindowsErr(0); + return NULL; } PyObject *resobj = PyUnicode_FromWideChar(wbuf2, len); @@ -3851,8 +3928,9 @@ posix_getcwd(int use_bytes) return PyErr_NoMemory(); } if (cwd == NULL) { + posix_error(); PyMem_RawFree(buf); - return posix_error(); + return NULL; } PyObject *obj; @@ -4064,8 +4142,8 @@ _listdir_windows_no_opendir(path_t *path, PyObject *list) int error = GetLastError(); if (error == ERROR_FILE_NOT_FOUND) goto exit; - Py_DECREF(list); - list = path_error(path); + path_error(path); + Py_CLEAR(list); goto exit; } do { @@ -4078,14 +4156,12 @@ _listdir_windows_no_opendir(path_t *path, PyObject *list) Py_SETREF(v, PyUnicode_EncodeFSDefault(v)); } if (v == NULL) { - Py_DECREF(list); - list = NULL; + Py_CLEAR(list); break; } if (PyList_Append(list, v) != 0) { Py_DECREF(v); - Py_DECREF(list); - list = NULL; + Py_CLEAR(list); break; } Py_DECREF(v); @@ -4096,8 +4172,8 @@ _listdir_windows_no_opendir(path_t *path, PyObject *list) /* FindNextFile sets error to ERROR_NO_MORE_FILES if it got to the end of the directory. */ if (!result && GetLastError() != ERROR_NO_MORE_FILES) { - Py_DECREF(list); - list = path_error(path); + path_error(path); + Py_CLEAR(list); goto exit; } } while (result == TRUE); @@ -4106,8 +4182,8 @@ exit: if (hFindFile != INVALID_HANDLE_VALUE) { if (FindClose(hFindFile) == FALSE) { if (list != NULL) { - Py_DECREF(list); - list = path_error(path); + path_error(path); + Py_CLEAR(list); } } } @@ -4155,8 +4231,8 @@ _posix_listdir(path_t *path, PyObject *list) const char *name; if (path->narrow) { name = path->narrow; - /* only return bytes if they specified a bytes-like object */ - return_str = !PyObject_CheckBuffer(path->object); + /* only return bytes if they specified a bytes object */ + return_str = !PyBytes_Check(path->object); } else { name = "."; @@ -4169,7 +4245,8 @@ _posix_listdir(path_t *path, PyObject *list) } if (dirp == NULL) { - list = path_error(path); + path_error(path); + list = NULL; #ifdef HAVE_FDOPENDIR if (fd != -1) { Py_BEGIN_ALLOW_THREADS @@ -4191,8 +4268,8 @@ _posix_listdir(path_t *path, PyObject *list) if (errno == 0) { break; } else { - Py_DECREF(list); - list = path_error(path); + path_error(path); + Py_CLEAR(list); goto exit; } } @@ -4268,7 +4345,287 @@ os_listdir_impl(PyObject *module, path_t *path) #endif } + #ifdef MS_WINDOWS + +/*[clinic input] +os.listdrives + +Return a list containing the names of drives in the system. + +A drive name typically looks like 'C:\\'. + +[clinic start generated code]*/ + +static PyObject * +os_listdrives_impl(PyObject *module) +/*[clinic end generated code: output=aaece9dacdf682b5 input=1af9ccc9e583798e]*/ +{ + /* Number of possible drives is limited, so 256 should always be enough. + On the day when it is not, listmounts() will have to be used. */ + wchar_t buffer[256]; + DWORD buflen = Py_ARRAY_LENGTH(buffer); + PyObject *result = NULL; + if (PySys_Audit("os.listdrives", NULL) < 0) { + return NULL; + } + + Py_BEGIN_ALLOW_THREADS; + buflen = GetLogicalDriveStringsW(buflen, buffer); + Py_END_ALLOW_THREADS; + + if (!buflen) { + PyErr_SetFromWindowsErr(0); + return NULL; + } else if (buflen >= Py_ARRAY_LENGTH(buffer)) { + PyErr_SetFromWindowsErr(ERROR_MORE_DATA); + return NULL; + } + + /* buflen includes a null terminator, so remove it */ + PyObject *str = PyUnicode_FromWideChar(buffer, buflen - 1); + if (str) { + PyObject *nullchar = PyUnicode_FromStringAndSize("\0", 1); + if (nullchar) { + result = PyUnicode_Split(str, nullchar, -1); + Py_DECREF(nullchar); + } + Py_DECREF(str); + } + return result; +} + +/*[clinic input] +os.listvolumes + +Return a list containing the volumes in the system. + +Volumes are typically represented as a GUID path. + +[clinic start generated code]*/ + +static PyObject * +os_listvolumes_impl(PyObject *module) +/*[clinic end generated code: output=534e10ea2bf9d386 input=f6e4e70371f11e99]*/ +{ + PyObject *result = PyList_New(0); + HANDLE find = INVALID_HANDLE_VALUE; + wchar_t buffer[MAX_PATH + 1]; + if (!result) { + return NULL; + } + if (PySys_Audit("os.listvolumes", NULL) < 0) { + Py_DECREF(result); + return NULL; + } + + int err = 0; + Py_BEGIN_ALLOW_THREADS; + find = FindFirstVolumeW(buffer, Py_ARRAY_LENGTH(buffer)); + if (find == INVALID_HANDLE_VALUE) { + err = GetLastError(); + } + Py_END_ALLOW_THREADS; + + while (!err) { + PyObject *s = PyUnicode_FromWideChar(buffer, -1); + if (!s || PyList_Append(result, s) < 0) { + Py_XDECREF(s); + Py_CLEAR(result); + break; + } + Py_DECREF(s); + + Py_BEGIN_ALLOW_THREADS; + if (!FindNextVolumeW(find, buffer, Py_ARRAY_LENGTH(buffer))) { + err = GetLastError(); + } + Py_END_ALLOW_THREADS; + } + + if (find != INVALID_HANDLE_VALUE) { + Py_BEGIN_ALLOW_THREADS; + FindVolumeClose(find); + Py_END_ALLOW_THREADS; + } + if (err && err != ERROR_NO_MORE_FILES) { + PyErr_SetFromWindowsErr(err); + Py_XDECREF(result); + result = NULL; + } + return result; +} + + +/*[clinic input] +os.listmounts + + volume: path_t + +Return a list containing mount points for a particular volume. + +'volume' should be a GUID path as returned from os.listvolumes. + +[clinic start generated code]*/ + +static PyObject * +os_listmounts_impl(PyObject *module, path_t *volume) +/*[clinic end generated code: output=06da49679de4512e input=a8a27178e3f67845]*/ +{ + wchar_t default_buffer[MAX_PATH + 1]; + DWORD buflen = Py_ARRAY_LENGTH(default_buffer); + LPWSTR buffer = default_buffer; + DWORD attributes; + PyObject *str = NULL; + PyObject *nullchar = NULL; + PyObject *result = NULL; + + /* Ensure we have a valid volume path before continuing */ + Py_BEGIN_ALLOW_THREADS + attributes = GetFileAttributesW(volume->wide); + Py_END_ALLOW_THREADS + if (attributes == INVALID_FILE_ATTRIBUTES && + GetLastError() == ERROR_UNRECOGNIZED_VOLUME) + { + return PyErr_SetFromWindowsErr(ERROR_UNRECOGNIZED_VOLUME); + } + + if (PySys_Audit("os.listmounts", "O", volume->object) < 0) { + return NULL; + } + + while (1) { + BOOL success; + Py_BEGIN_ALLOW_THREADS + success = GetVolumePathNamesForVolumeNameW(volume->wide, buffer, + buflen, &buflen); + Py_END_ALLOW_THREADS + if (success) { + break; + } + if (GetLastError() != ERROR_MORE_DATA) { + PyErr_SetFromWindowsErr(0); + goto exit; + } + if (buffer != default_buffer) { + PyMem_Free((void *)buffer); + } + buffer = (wchar_t*)PyMem_Malloc(sizeof(wchar_t) * buflen); + if (!buffer) { + PyErr_NoMemory(); + goto exit; + } + } + if (buflen < 2) { + result = PyList_New(0); + goto exit; + } + // buflen includes two null terminators, one for the last string + // and one for the array of strings. + str = PyUnicode_FromWideChar(buffer, buflen - 2); + nullchar = PyUnicode_FromStringAndSize("\0", 1); + if (str && nullchar) { + result = PyUnicode_Split(str, nullchar, -1); + } +exit: + if (buffer != default_buffer) { + PyMem_Free(buffer); + } + Py_XDECREF(nullchar); + Py_XDECREF(str); + return result; +} + + +/*[clinic input] +os._path_isdevdrive + + path: path_t + +Determines whether the specified path is on a Windows Dev Drive. + +[clinic start generated code]*/ + +static PyObject * +os__path_isdevdrive_impl(PyObject *module, path_t *path) +/*[clinic end generated code: output=1f437ea6677433a2 input=ee83e4996a48e23d]*/ +{ +#ifndef PERSISTENT_VOLUME_STATE_DEV_VOLUME + /* This flag will be documented at + https://learn.microsoft.com/windows-hardware/drivers/ddi/ntifs/ns-ntifs-_file_fs_persistent_volume_information + after release, and will be available in the latest WinSDK. + We include the flag to avoid a specific version dependency + on the latest WinSDK. */ + const int PERSISTENT_VOLUME_STATE_DEV_VOLUME = 0x00002000; +#endif + int err = 0; + PyObject *r = NULL; + wchar_t volume[MAX_PATH]; + + Py_BEGIN_ALLOW_THREADS + if (!GetVolumePathNameW(path->wide, volume, MAX_PATH)) { + /* invalid path of some kind */ + /* Note that this also includes the case where a volume is mounted + in a path longer than 260 characters. This is likely to be rare + and problematic for other reasons, so a (soft) failure in this + check seems okay. */ + err = GetLastError(); + } else if (GetDriveTypeW(volume) != DRIVE_FIXED) { + /* only care about local dev drives */ + r = Py_False; + } else { + HANDLE hVolume = CreateFileW( + volume, + FILE_READ_ATTRIBUTES, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS, + NULL + ); + if (hVolume == INVALID_HANDLE_VALUE) { + err = GetLastError(); + } else { + FILE_FS_PERSISTENT_VOLUME_INFORMATION volumeState = {0}; + volumeState.Version = 1; + volumeState.FlagMask = PERSISTENT_VOLUME_STATE_DEV_VOLUME; + if (!DeviceIoControl( + hVolume, + FSCTL_QUERY_PERSISTENT_VOLUME_STATE, + &volumeState, + sizeof(volumeState), + &volumeState, + sizeof(volumeState), + NULL, + NULL + )) { + err = GetLastError(); + } + CloseHandle(hVolume); + if (err == ERROR_INVALID_PARAMETER) { + /* not supported on this platform */ + r = Py_False; + } else if (!err) { + r = (volumeState.VolumeFlags & PERSISTENT_VOLUME_STATE_DEV_VOLUME) + ? Py_True : Py_False; + } + } + } + Py_END_ALLOW_THREADS + + if (err) { + PyErr_SetFromWindowsErr(err); + return NULL; + } + + if (r) { + return Py_NewRef(r); + } + + return NULL; +} + + int _PyOS_getfullpathname(const wchar_t *path, wchar_t **abspath_p) { @@ -4512,12 +4869,390 @@ os__path_splitroot_impl(PyObject *module, path_t *path) } else { result = Py_BuildValue("Os", path->object, ""); } - PyMem_Free(buffer); + PyMem_Free(buffer); + + return result; +} + + +/*[clinic input] +os._path_isdir + + path: 'O' + +Return true if the pathname refers to an existing directory. + +[clinic start generated code]*/ + +static PyObject * +os__path_isdir_impl(PyObject *module, PyObject *path) +/*[clinic end generated code: output=00faea0af309669d input=b1d2571cf7291aaf]*/ +{ + HANDLE hfile; + BOOL close_file = TRUE; + FILE_BASIC_INFO info; + path_t _path = PATH_T_INITIALIZE("isdir", "path", 0, 1); + int result; + BOOL slow_path = TRUE; + FILE_STAT_BASIC_INFORMATION statInfo; + + if (!path_converter(path, &_path)) { + path_cleanup(&_path); + if (PyErr_ExceptionMatches(PyExc_ValueError)) { + PyErr_Clear(); + Py_RETURN_FALSE; + } + return NULL; + } + + Py_BEGIN_ALLOW_THREADS + if (_path.wide) { + if (_Py_GetFileInformationByName(_path.wide, FileStatBasicByNameInfo, + &statInfo, sizeof(statInfo))) { + if (!(statInfo.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) { + slow_path = FALSE; + result = statInfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY; + } else if (!(statInfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { + slow_path = FALSE; + result = 0; + } + } else if (_Py_GetFileInformationByName_ErrorIsTrustworthy(GetLastError())) { + slow_path = FALSE; + result = 0; + } + } + if (slow_path) { + if (_path.fd != -1) { + hfile = _Py_get_osfhandle_noraise(_path.fd); + close_file = FALSE; + } + else { + hfile = CreateFileW(_path.wide, FILE_READ_ATTRIBUTES, 0, NULL, + OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); + } + if (hfile != INVALID_HANDLE_VALUE) { + if (GetFileInformationByHandleEx(hfile, FileBasicInfo, &info, + sizeof(info))) + { + result = info.FileAttributes & FILE_ATTRIBUTE_DIRECTORY; + } + else { + result = 0; + } + if (close_file) { + CloseHandle(hfile); + } + } + else { + STRUCT_STAT st; + switch (GetLastError()) { + case ERROR_ACCESS_DENIED: + case ERROR_SHARING_VIOLATION: + case ERROR_CANT_ACCESS_FILE: + case ERROR_INVALID_PARAMETER: + if (STAT(_path.wide, &st)) { + result = 0; + } + else { + result = S_ISDIR(st.st_mode); + } + break; + default: + result = 0; + } + } + } + Py_END_ALLOW_THREADS + + path_cleanup(&_path); + if (result) { + Py_RETURN_TRUE; + } + Py_RETURN_FALSE; +} + + +/*[clinic input] +os._path_isfile + + path: 'O' + +Test whether a path is a regular file + +[clinic start generated code]*/ + +static PyObject * +os__path_isfile_impl(PyObject *module, PyObject *path) +/*[clinic end generated code: output=2394ed7c4b5cfd85 input=de22d74960ade365]*/ +{ + HANDLE hfile; + BOOL close_file = TRUE; + FILE_BASIC_INFO info; + path_t _path = PATH_T_INITIALIZE("isfile", "path", 0, 1); + int result; + BOOL slow_path = TRUE; + FILE_STAT_BASIC_INFORMATION statInfo; + + if (!path_converter(path, &_path)) { + path_cleanup(&_path); + if (PyErr_ExceptionMatches(PyExc_ValueError)) { + PyErr_Clear(); + Py_RETURN_FALSE; + } + return NULL; + } + + Py_BEGIN_ALLOW_THREADS + if (_path.wide) { + if (_Py_GetFileInformationByName(_path.wide, FileStatBasicByNameInfo, + &statInfo, sizeof(statInfo))) { + if (!(statInfo.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) { + slow_path = FALSE; + result = !(statInfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY); + } else if (statInfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + slow_path = FALSE; + result = 0; + } + } else if (_Py_GetFileInformationByName_ErrorIsTrustworthy(GetLastError())) { + slow_path = FALSE; + result = 0; + } + } + if (slow_path) { + if (_path.fd != -1) { + hfile = _Py_get_osfhandle_noraise(_path.fd); + close_file = FALSE; + } + else { + hfile = CreateFileW(_path.wide, FILE_READ_ATTRIBUTES, 0, NULL, + OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); + } + if (hfile != INVALID_HANDLE_VALUE) { + if (GetFileInformationByHandleEx(hfile, FileBasicInfo, &info, + sizeof(info))) + { + result = !(info.FileAttributes & FILE_ATTRIBUTE_DIRECTORY); + } + else { + result = 0; + } + if (close_file) { + CloseHandle(hfile); + } + } + else { + STRUCT_STAT st; + switch (GetLastError()) { + case ERROR_ACCESS_DENIED: + case ERROR_SHARING_VIOLATION: + case ERROR_CANT_ACCESS_FILE: + case ERROR_INVALID_PARAMETER: + if (STAT(_path.wide, &st)) { + result = 0; + } + else { + result = S_ISREG(st.st_mode); + } + break; + default: + result = 0; + } + } + } + Py_END_ALLOW_THREADS + + path_cleanup(&_path); + if (result) { + Py_RETURN_TRUE; + } + Py_RETURN_FALSE; +} + + +/*[clinic input] +os._path_exists + + path: 'O' + +Test whether a path exists. Returns False for broken symbolic links + +[clinic start generated code]*/ + +static PyObject * +os__path_exists_impl(PyObject *module, PyObject *path) +/*[clinic end generated code: output=f508c3b35e13a249 input=380f77cdfa0f7ae8]*/ +{ + HANDLE hfile; + BOOL close_file = TRUE; + path_t _path = PATH_T_INITIALIZE("exists", "path", 0, 1); + int result; + BOOL slow_path = TRUE; + FILE_STAT_BASIC_INFORMATION statInfo; + + if (!path_converter(path, &_path)) { + path_cleanup(&_path); + if (PyErr_ExceptionMatches(PyExc_ValueError)) { + PyErr_Clear(); + Py_RETURN_FALSE; + } + return NULL; + } + + Py_BEGIN_ALLOW_THREADS + if (_path.wide) { + if (_Py_GetFileInformationByName(_path.wide, FileStatBasicByNameInfo, + &statInfo, sizeof(statInfo))) { + if (!(statInfo.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) { + slow_path = FALSE; + result = 1; + } + } else if (_Py_GetFileInformationByName_ErrorIsTrustworthy(GetLastError())) { + slow_path = FALSE; + result = 0; + } + } + if (slow_path) { + if (_path.fd != -1) { + hfile = _Py_get_osfhandle_noraise(_path.fd); + close_file = FALSE; + } + else { + hfile = CreateFileW(_path.wide, FILE_READ_ATTRIBUTES, 0, NULL, + OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); + } + if (hfile != INVALID_HANDLE_VALUE) { + result = 1; + if (close_file) { + CloseHandle(hfile); + } + } + else { + STRUCT_STAT st; + switch (GetLastError()) { + case ERROR_ACCESS_DENIED: + case ERROR_SHARING_VIOLATION: + case ERROR_CANT_ACCESS_FILE: + case ERROR_INVALID_PARAMETER: + if (STAT(_path.wide, &st)) { + result = 0; + } + else { + result = 1; + } + break; + default: + result = 0; + } + } + } + Py_END_ALLOW_THREADS + + path_cleanup(&_path); + if (result) { + Py_RETURN_TRUE; + } + Py_RETURN_FALSE; +} + + +/*[clinic input] +os._path_islink + + path: 'O' + +Test whether a path is a symbolic link + +[clinic start generated code]*/ + +static PyObject * +os__path_islink_impl(PyObject *module, PyObject *path) +/*[clinic end generated code: output=6d8640b1a390c054 input=38a3cb937ccf59bf]*/ +{ + HANDLE hfile; + BOOL close_file = TRUE; + FILE_ATTRIBUTE_TAG_INFO info; + path_t _path = PATH_T_INITIALIZE("islink", "path", 0, 1); + int result; + BOOL slow_path = TRUE; + FILE_STAT_BASIC_INFORMATION statInfo; + + if (!path_converter(path, &_path)) { + path_cleanup(&_path); + if (PyErr_ExceptionMatches(PyExc_ValueError)) { + PyErr_Clear(); + Py_RETURN_FALSE; + } + return NULL; + } + + Py_BEGIN_ALLOW_THREADS + if (_path.wide) { + if (_Py_GetFileInformationByName(_path.wide, FileStatBasicByNameInfo, + &statInfo, sizeof(statInfo))) { + slow_path = FALSE; + if (statInfo.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { + result = (statInfo.ReparseTag == IO_REPARSE_TAG_SYMLINK); + } + else { + result = 0; + } + } else if (_Py_GetFileInformationByName_ErrorIsTrustworthy(GetLastError())) { + slow_path = FALSE; + result = 0; + } + } + if (slow_path) { + if (_path.fd != -1) { + hfile = _Py_get_osfhandle_noraise(_path.fd); + close_file = FALSE; + } + else { + hfile = CreateFileW(_path.wide, FILE_READ_ATTRIBUTES, 0, NULL, + OPEN_EXISTING, + FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, + NULL); + } + if (hfile != INVALID_HANDLE_VALUE) { + if (GetFileInformationByHandleEx(hfile, FileAttributeTagInfo, &info, + sizeof(info))) + { + result = (info.ReparseTag == IO_REPARSE_TAG_SYMLINK); + } + else { + result = 0; + } + if (close_file) { + CloseHandle(hfile); + } + } + else { + STRUCT_STAT st; + switch (GetLastError()) { + case ERROR_ACCESS_DENIED: + case ERROR_SHARING_VIOLATION: + case ERROR_CANT_ACCESS_FILE: + case ERROR_INVALID_PARAMETER: + if (LSTAT(_path.wide, &st)) { + result = 0; + } + else { + result = S_ISLNK(st.st_mode); + } + break; + default: + result = 0; + } + } + } + Py_END_ALLOW_THREADS - return result; + path_cleanup(&_path); + if (result) { + Py_RETURN_TRUE; + } + Py_RETURN_FALSE; } - #endif /* MS_WINDOWS */ @@ -4543,7 +5278,9 @@ os__path_normpath_impl(PyObject *module, PyObject *path) if (!buffer) { return NULL; } - PyObject *result = PyUnicode_FromWideChar(_Py_normpath(buffer, len), -1); + Py_ssize_t norm_len; + wchar_t *norm_path = _Py_normpath_and_size(buffer, len, &norm_len); + PyObject *result = PyUnicode_FromWideChar(norm_path, norm_len); PyMem_Free(buffer); return result; } @@ -5682,7 +6419,7 @@ parse_envlist(PyObject* env, Py_ssize_t *envc_ptr) { Py_ssize_t i, pos, envc; PyObject *keys=NULL, *vals=NULL; - PyObject *key, *val, *key2, *val2, *keyval; + PyObject *key2, *val2, *keyval; EXECV_CHAR **envlist; i = PyMapping_Size(env); @@ -5707,10 +6444,14 @@ parse_envlist(PyObject* env, Py_ssize_t *envc_ptr) } for (pos = 0; pos < i; pos++) { - key = PyList_GetItem(keys, pos); - val = PyList_GetItem(vals, pos); - if (!key || !val) + PyObject *key = PyList_GetItem(keys, pos); // Borrowed ref. + if (key == NULL) { + goto error; + } + PyObject *val = PyList_GetItem(vals, pos); // Borrowed ref. + if (val == NULL) { goto error; + } #if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV) if (!PyUnicode_FSDecoder(key, &key2)) @@ -5824,6 +6565,13 @@ os_execv_impl(PyObject *module, path_t *path, PyObject *argv) EXECV_CHAR **argvlist; Py_ssize_t argc; + PyInterpreterState *interp = _PyInterpreterState_GET(); + if (!_PyInterpreterState_HasFeature(interp, Py_RTFLAGS_EXEC)) { + PyErr_SetString(PyExc_RuntimeError, + "exec not supported for isolated subinterpreters"); + return NULL; + } + /* execv has two arguments: (path, argv), where argv is a list or tuple of strings. */ @@ -5864,8 +6612,9 @@ os_execv_impl(PyObject *module, path_t *path, PyObject *argv) /* If we get here it's definitely an error */ + posix_error(); free_string_array(argvlist, argc); - return posix_error(); + return NULL; } @@ -5890,6 +6639,13 @@ os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env) EXECV_CHAR **envlist; Py_ssize_t argc, envc; + PyInterpreterState *interp = _PyInterpreterState_GET(); + if (!_PyInterpreterState_HasFeature(interp, Py_RTFLAGS_EXEC)) { + PyErr_SetString(PyExc_RuntimeError, + "exec not supported for isolated subinterpreters"); + return NULL; + } + /* execve has three arguments: (path, argv, env), where argv is a list or tuple of strings and env is a dictionary like posix.environ. */ @@ -6162,11 +6918,12 @@ parse_file_actions(PyObject *file_actions, } errno = posix_spawn_file_actions_addopen(file_actionsp, fd, PyBytes_AS_STRING(path), oflag, (mode_t)mode); - Py_DECREF(path); if (errno) { posix_error(); + Py_DECREF(path); goto fail; } + Py_DECREF(path); break; } case POSIX_SPAWN_CLOSE: { @@ -6362,9 +7119,9 @@ os.posix_spawn A sequence of file action tuples. setpgroup: object = NULL The pgroup to use with the POSIX_SPAWN_SETPGROUP flag. - resetids: bool(accept={int}) = False + resetids: bool = False If the value is `true` the POSIX_SPAWN_RESETIDS will be activated. - setsid: bool(accept={int}) = False + setsid: bool = False If the value is `true` the POSIX_SPAWN_SETSID or POSIX_SPAWN_SETSID_NP will be activated. setsigmask: object(c_default='NULL') = () The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag. @@ -6382,7 +7139,7 @@ os_posix_spawn_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *setpgroup, int resetids, int setsid, PyObject *setsigmask, PyObject *setsigdef, PyObject *scheduler) -/*[clinic end generated code: output=14a1098c566bc675 input=8c6305619a00ad04]*/ +/*[clinic end generated code: output=14a1098c566bc675 input=808aed1090d84e33]*/ { return py_posix_spawn(0, module, path, argv, env, file_actions, setpgroup, resetids, setsid, setsigmask, setsigdef, @@ -6408,9 +7165,9 @@ os.posix_spawnp A sequence of file action tuples. setpgroup: object = NULL The pgroup to use with the POSIX_SPAWN_SETPGROUP flag. - resetids: bool(accept={int}) = False + resetids: bool = False If the value is `True` the POSIX_SPAWN_RESETIDS will be activated. - setsid: bool(accept={int}) = False + setsid: bool = False If the value is `True` the POSIX_SPAWN_SETSID or POSIX_SPAWN_SETSID_NP will be activated. setsigmask: object(c_default='NULL') = () The sigmask to use with the POSIX_SPAWN_SETSIGMASK flag. @@ -6428,7 +7185,7 @@ os_posix_spawnp_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *setpgroup, int resetids, int setsid, PyObject *setsigmask, PyObject *setsigdef, PyObject *scheduler) -/*[clinic end generated code: output=7b9aaefe3031238d input=c1911043a22028da]*/ +/*[clinic end generated code: output=7b9aaefe3031238d input=9e89e616116752a1]*/ { return py_posix_spawn(1, module, path, argv, env, file_actions, setpgroup, resetids, setsid, setsigmask, setsigdef, @@ -6563,12 +7320,15 @@ os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv) _Py_END_SUPPRESS_IPH Py_END_ALLOW_THREADS + int saved_errno = errno; free_string_array(argvlist, argc); - if (spawnval == -1) - return posix_error(); - else - return Py_BuildValue(_Py_PARSE_INTPTR, spawnval); + if (spawnval == -1) { + errno = saved_errno; + posix_error(); + return NULL; + } + return Py_BuildValue(_Py_PARSE_INTPTR, spawnval); } /*[clinic input] @@ -6760,6 +7520,104 @@ os_register_at_fork_impl(PyObject *module, PyObject *before, } #endif /* HAVE_FORK */ +// Common code to raise a warning if we detect there is more than one thread +// running in the process. Best effort, silent if unable to count threads. +// Constraint: Quick. Never overcounts. Never leaves an error set. +// +// This code might do an import, thus acquiring the import lock, which +// PyOS_BeforeFork() also does. As this should only be called from +// the parent process, it is in the same thread so that works. +static void warn_about_fork_with_threads(const char* name) { + // TODO: Consider making an `os` module API to return the current number + // of threads in the process. That'd presumably use this platform code but + // raise an error rather than using the inaccurate fallback. + Py_ssize_t num_python_threads = 0; +#if defined(__APPLE__) && defined(HAVE_GETPID) + mach_port_t macos_self = mach_task_self(); + mach_port_t macos_task; + if (task_for_pid(macos_self, getpid(), &macos_task) == KERN_SUCCESS) { + thread_array_t macos_threads; + mach_msg_type_number_t macos_n_threads; + if (task_threads(macos_task, &macos_threads, + &macos_n_threads) == KERN_SUCCESS) { + num_python_threads = macos_n_threads; + } + } +#elif defined(__linux__) + // Linux /proc/self/stat 20th field is the number of threads. + FILE* proc_stat = fopen("/proc/self/stat", "r"); + if (proc_stat) { + size_t n; + // Size chosen arbitrarily. ~60% more bytes than a 20th column index + // observed on the author's workstation. + char stat_line[160]; + n = fread(&stat_line, 1, 159, proc_stat); + stat_line[n] = '\0'; + fclose(proc_stat); + + char *saveptr = NULL; + char *field = strtok_r(stat_line, " ", &saveptr); + unsigned int idx; + for (idx = 19; idx && field; --idx) { + field = strtok_r(NULL, " ", &saveptr); + } + if (idx == 0 && field) { // found the 20th field + num_python_threads = atoi(field); // 0 on error + } + } +#endif + if (num_python_threads <= 0) { + // Fall back to just the number our threading module knows about. + // An incomplete view of the world, but better than nothing. + PyObject *threading = PyImport_GetModule(&_Py_ID(threading)); + if (!threading) { + PyErr_Clear(); + return; + } + PyObject *threading_active = + PyObject_GetAttr(threading, &_Py_ID(_active)); + if (!threading_active) { + PyErr_Clear(); + Py_DECREF(threading); + return; + } + PyObject *threading_limbo = + PyObject_GetAttr(threading, &_Py_ID(_limbo)); + if (!threading_limbo) { + PyErr_Clear(); + Py_DECREF(threading); + Py_DECREF(threading_active); + return; + } + Py_DECREF(threading); + // Duplicating what threading.active_count() does but without holding + // threading._active_limbo_lock so our count could be inaccurate if + // these dicts are mid-update from another thread. Not a big deal. + // Worst case if someone replaced threading._active or threading._limbo + // with non-dicts, we get -1 from *Length() below and undercount. + // Nobody should, but we're best effort so we clear errors and move on. + num_python_threads = (PyMapping_Length(threading_active) + + PyMapping_Length(threading_limbo)); + PyErr_Clear(); + Py_DECREF(threading_active); + Py_DECREF(threading_limbo); + } + if (num_python_threads > 1) { + PyErr_WarnFormat( + PyExc_DeprecationWarning, 1, +#ifdef HAVE_GETPID + "This process (pid=%d) is multi-threaded, " +#else + "This process is multi-threaded, " +#endif + "use of %s() may lead to deadlocks in the child.", +#ifdef HAVE_GETPID + getpid(), +#endif + name); + PyErr_Clear(); + } +} #ifdef HAVE_FORK1 /*[clinic input] @@ -6776,21 +7634,31 @@ os_fork1_impl(PyObject *module) { pid_t pid; - if (!_Py_IsMainInterpreter(_PyInterpreterState_GET())) { + PyInterpreterState *interp = _PyInterpreterState_GET(); + if (interp->finalizing) { + PyErr_SetString(PyExc_RuntimeError, + "can't fork at interpreter shutdown"); + return NULL; + } + if (!_Py_IsMainInterpreter(interp)) { PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters"); return NULL; } PyOS_BeforeFork(); pid = fork1(); + int saved_errno = errno; if (pid == 0) { /* child: this clobbers and resets the import lock. */ PyOS_AfterFork_Child(); } else { + warn_about_fork_with_threads("fork1"); /* parent: release the import lock. */ PyOS_AfterFork_Parent(); } - if (pid == -1) + if (pid == -1) { + errno = saved_errno; return posix_error(); + } return PyLong_FromPid(pid); } #endif /* HAVE_FORK1 */ @@ -6811,7 +7679,12 @@ os_fork_impl(PyObject *module) { pid_t pid; PyInterpreterState *interp = _PyInterpreterState_GET(); - if (interp->config._isolated_interpreter) { + if (interp->finalizing) { + PyErr_SetString(PyExc_RuntimeError, + "can't fork at interpreter shutdown"); + return NULL; + } + if (!_PyInterpreterState_HasFeature(interp, Py_RTFLAGS_FORK)) { PyErr_SetString(PyExc_RuntimeError, "fork not supported for isolated subinterpreters"); return NULL; @@ -6821,15 +7694,19 @@ os_fork_impl(PyObject *module) } PyOS_BeforeFork(); pid = fork(); + int saved_errno = errno; if (pid == 0) { /* child: this clobbers and resets the import lock. */ PyOS_AfterFork_Child(); } else { + warn_about_fork_with_threads("fork"); /* parent: release the import lock. */ PyOS_AfterFork_Parent(); } - if (pid == -1) + if (pid == -1) { + errno = saved_errno; return posix_error(); + } return PyLong_FromPid(pid); } #endif /* HAVE_FORK */ @@ -6925,8 +7802,7 @@ os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority) res = PyStructSequence_New(type); if (!res) return NULL; - Py_INCREF(sched_priority); - PyStructSequence_SET_ITEM(res, 0, sched_priority); + PyStructSequence_SET_ITEM(res, 0, Py_NewRef(sched_priority)); return res; } @@ -7367,13 +8243,17 @@ os_openpty_impl(PyObject *module) /* change permission of slave */ if (grantpt(master_fd) < 0) { + int saved_errno = errno; PyOS_setsig(SIGCHLD, sig_saved); + errno = saved_errno; goto posix_error; } /* unlock slave */ if (unlockpt(master_fd) < 0) { + int saved_errno = errno; PyOS_setsig(SIGCHLD, sig_saved); + errno = saved_errno; goto posix_error; } @@ -7482,7 +8362,13 @@ os_forkpty_impl(PyObject *module) int master_fd = -1; pid_t pid; - if (!_Py_IsMainInterpreter(_PyInterpreterState_GET())) { + PyInterpreterState *interp = _PyInterpreterState_GET(); + if (interp->finalizing) { + PyErr_SetString(PyExc_RuntimeError, + "can't fork at interpreter shutdown"); + return NULL; + } + if (!_Py_IsMainInterpreter(interp)) { PyErr_SetString(PyExc_RuntimeError, "fork not supported for subinterpreters"); return NULL; } @@ -7495,6 +8381,7 @@ os_forkpty_impl(PyObject *module) /* child: this clobbers and resets the import lock. */ PyOS_AfterFork_Child(); } else { + warn_about_fork_with_threads("forkpty"); /* parent: release the import lock. */ PyOS_AfterFork_Parent(); } @@ -7554,7 +8441,7 @@ os_getgid_impl(PyObject *module) #endif /* HAVE_GETGID */ -#ifdef HAVE_GETPID +#if defined(HAVE_GETPID) /*[clinic input] os.getpid @@ -7565,9 +8452,13 @@ static PyObject * os_getpid_impl(PyObject *module) /*[clinic end generated code: output=9ea6fdac01ed2b3c input=5a9a00f0ab68aa00]*/ { +#if !defined(MS_WINDOWS) || defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) return PyLong_FromPid(getpid()); +#else + return PyLong_FromUnsignedLong(GetCurrentProcessId()); +#endif } -#endif /* HAVE_GETPID */ +#endif /* defined(HAVE_GETPID) */ #ifdef NGROUPS_MAX #define MAX_GROUPS NGROUPS_MAX @@ -7726,8 +8617,9 @@ os_getgroups_impl(PyObject *module) n = getgroups(n, grouplist); if (n == -1) { + posix_error(); PyMem_Free(grouplist); - return posix_error(); + return NULL; } PyObject *result = PyList_New(n); @@ -7867,43 +8759,32 @@ os_setpgrp_impl(PyObject *module) #ifdef HAVE_GETPPID #ifdef MS_WINDOWS -#include <tlhelp32.h> +#include <processsnapshot.h> static PyObject* -win32_getppid() +win32_getppid(void) { - HANDLE snapshot; - pid_t mypid; + DWORD error; PyObject* result = NULL; - BOOL have_record; - PROCESSENTRY32 pe; - - mypid = getpid(); /* This function never fails */ - - snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); - if (snapshot == INVALID_HANDLE_VALUE) - return PyErr_SetFromWindowsErr(GetLastError()); - - pe.dwSize = sizeof(pe); - have_record = Process32First(snapshot, &pe); - while (have_record) { - if (mypid == (pid_t)pe.th32ProcessID) { - /* We could cache the ulong value in a static variable. */ - result = PyLong_FromPid((pid_t)pe.th32ParentProcessID); - break; - } + HANDLE process = GetCurrentProcess(); - have_record = Process32Next(snapshot, &pe); + HPSS snapshot = NULL; + error = PssCaptureSnapshot(process, PSS_CAPTURE_NONE, 0, &snapshot); + if (error != ERROR_SUCCESS) { + return PyErr_SetFromWindowsErr(error); } - /* If our loop exits and our pid was not found (result will be NULL) - * then GetLastError will return ERROR_NO_MORE_FILES. This is an - * error anyway, so let's raise it. */ - if (!result) - result = PyErr_SetFromWindowsErr(GetLastError()); - - CloseHandle(snapshot); + PSS_PROCESS_INFORMATION info; + error = PssQuerySnapshot(snapshot, PSS_QUERY_PROCESS_INFORMATION, &info, + sizeof(info)); + if (error == ERROR_SUCCESS) { + result = PyLong_FromUnsignedLong(info.ParentProcessId); + } + else { + result = PyErr_SetFromWindowsErr(error); + } + PssFreeSnapshot(process, snapshot); return result; } #endif /*MS_WINDOWS*/ @@ -8031,6 +8912,7 @@ os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal) DWORD err; HANDLE handle; +#ifdef HAVE_WINDOWS_CONSOLE_IO /* Console processes which share a common console can be sent CTRL+C or CTRL+BREAK events, provided they handle said events. */ if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) { @@ -8038,9 +8920,11 @@ os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal) err = GetLastError(); PyErr_SetFromWindowsErr(err); } - else + else { Py_RETURN_NONE; + } } +#endif /* HAVE_WINDOWS_CONSOLE_IO */ /* If the signal is outside of what GenerateConsoleCtrlEvent can use, attempt to open and terminate the process. */ @@ -8054,8 +8938,7 @@ os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal) err = GetLastError(); result = PyErr_SetFromWindowsErr(err); } else { - Py_INCREF(Py_None); - result = Py_None; + result = Py_NewRef(Py_None); } CloseHandle(handle); @@ -8299,8 +9182,9 @@ os_setgroups(PyObject *module, PyObject *groups) } if (setgroups(len, grouplist) < 0) { + posix_error(); PyMem_Free(grouplist); - return posix_error(); + return NULL; } PyMem_Free(grouplist); Py_RETURN_NONE; @@ -8323,11 +9207,7 @@ wait_helper(PyObject *module, pid_t pid, int status, struct rusage *ru) memset(ru, 0, sizeof(*ru)); } - PyObject *m = PyImport_ImportModule("resource"); - if (m == NULL) - return NULL; - struct_rusage = PyObject_GetAttr(m, get_posix_state(module)->struct_rusage); - Py_DECREF(m); + struct_rusage = _PyImport_GetModuleAttrString("resource", "struct_rusage"); if (struct_rusage == NULL) return NULL; @@ -8636,6 +9516,64 @@ os_pidfd_open_impl(PyObject *module, pid_t pid, unsigned int flags) #endif +#ifdef HAVE_SETNS +/*[clinic input] +os.setns + fd: fildes + A file descriptor to a namespace. + nstype: int = 0 + Type of namespace. + +Move the calling thread into different namespaces. +[clinic start generated code]*/ + +static PyObject * +os_setns_impl(PyObject *module, int fd, int nstype) +/*[clinic end generated code: output=5dbd055bfb66ecd0 input=42787871226bf3ee]*/ +{ + int res; + + Py_BEGIN_ALLOW_THREADS + res = setns(fd, nstype); + Py_END_ALLOW_THREADS + + if (res != 0) { + return posix_error(); + } + + Py_RETURN_NONE; +} +#endif + + +#ifdef HAVE_UNSHARE +/*[clinic input] +os.unshare + flags: int + Namespaces to be unshared. + +Disassociate parts of a process (or thread) execution context. +[clinic start generated code]*/ + +static PyObject * +os_unshare_impl(PyObject *module, int flags) +/*[clinic end generated code: output=1b3177906dd237ee input=9e065db3232b8b1b]*/ +{ + int res; + + Py_BEGIN_ALLOW_THREADS + res = unshare(flags); + Py_END_ALLOW_THREADS + + if (res != 0) { + return posix_error(); + } + + Py_RETURN_NONE; +} +#endif + + #if defined(HAVE_READLINK) || defined(MS_WINDOWS) /*[clinic input] os.readlink @@ -9037,11 +9975,6 @@ build_times_result(PyObject *module, double user, double system, } -#ifndef MS_WINDOWS -#define NEED_TICKS_PER_SECOND -static long ticks_per_second = -1; -#endif /* MS_WINDOWS */ - /*[clinic input] os.times @@ -9077,20 +10010,22 @@ os_times_impl(PyObject *module) } #else /* MS_WINDOWS */ { - - struct tms t; clock_t c; errno = 0; c = times(&t); - if (c == (clock_t) -1) + if (c == (clock_t) -1) { return posix_error(); + } + assert(_PyRuntime.time.ticks_per_second_initialized); +#define ticks_per_second _PyRuntime.time.ticks_per_second return build_times_result(module, (double)t.tms_utime / ticks_per_second, (double)t.tms_stime / ticks_per_second, (double)t.tms_cutime / ticks_per_second, (double)t.tms_cstime / ticks_per_second, (double)c / ticks_per_second); +#undef ticks_per_second } #endif /* MS_WINDOWS */ #endif /* HAVE_TIMES */ @@ -9387,11 +10322,6 @@ os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable) static int dup3_works = -1; #endif - if (fd < 0 || fd2 < 0) { - posix_error(); - return -1; - } - /* dup2() can fail with EINTR if the target FD is already open, because it * then has to be closed. See os_close_impl() for why we don't handle EINTR * upon close(), and therefore below. @@ -9511,19 +10441,24 @@ os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length) os.lseek -> Py_off_t fd: int + An open file descriptor, as returned by os.open(). position: Py_off_t - how: int + Position, interpreted relative to 'whence'. + whence as how: int + The relative position to seek from. Valid values are: + - SEEK_SET: seek from the start of the file. + - SEEK_CUR: seek from the current file position. + - SEEK_END: seek from the end of the file. / Set the position of a file descriptor. Return the new position. -Return the new cursor position in number of bytes -relative to the beginning of the file. +The return value is the number of bytes relative to the beginning of the file. [clinic start generated code]*/ static Py_off_t os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how) -/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/ +/*[clinic end generated code: output=971e1efb6b30bd2f input=f096e754c5367504]*/ { Py_off_t result; @@ -9696,10 +10631,13 @@ os_readv_impl(PyObject *module, int fd, PyObject *buffers) Py_END_ALLOW_THREADS } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); + int saved_errno = errno; iov_cleanup(iov, buf, cnt); if (n < 0) { - if (!async_err) + if (!async_err) { + errno = saved_errno; posix_error(); + } return -1; } @@ -9748,8 +10686,11 @@ os_pread_impl(PyObject *module, int fd, Py_ssize_t length, Py_off_t offset) } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); if (n < 0) { + if (!async_err) { + posix_error(); + } Py_DECREF(buffer); - return (!async_err) ? posix_error() : NULL; + return NULL; } if (n != length) _PyBytes_Resize(&buffer, n); @@ -9846,9 +10787,11 @@ os_preadv_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset, #endif + int saved_errno = errno; iov_cleanup(iov, buf, cnt); if (n < 0) { if (!async_err) { + errno = saved_errno; posix_error(); } return -1; @@ -10017,24 +10960,26 @@ os_sendfile_impl(PyObject *module, int out_fd, int in_fd, PyObject *offobj, } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); _Py_END_SUPPRESS_IPH + int saved_errno = errno; if (sf.headers != NULL) iov_cleanup(sf.headers, hbuf, sf.hdr_cnt); if (sf.trailers != NULL) iov_cleanup(sf.trailers, tbuf, sf.trl_cnt); if (ret < 0) { - if ((errno == EAGAIN) || (errno == EBUSY)) { + if ((saved_errno == EAGAIN) || (saved_errno == EBUSY)) { if (sbytes != 0) { // some data has been sent goto done; } - else { - // no data has been sent; upper application is supposed - // to retry on EAGAIN or EBUSY - return posix_error(); - } + // no data has been sent; upper application is supposed + // to retry on EAGAIN or EBUSY } - return (!async_err) ? posix_error() : NULL; + if (!async_err) { + errno = saved_errno; + posix_error(); + } + return NULL; } goto done; @@ -10351,10 +11296,10 @@ os_writev_impl(PyObject *module, int fd, PyObject *buffers) Py_END_ALLOW_THREADS } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals())); - iov_cleanup(iov, buf, cnt); if (result < 0 && !async_err) posix_error(); + iov_cleanup(iov, buf, cnt); return result; } #endif /* HAVE_WRITEV */ @@ -10489,13 +11434,13 @@ os_pwritev_impl(PyObject *module, int fd, PyObject *buffers, Py_off_t offset, #endif - iov_cleanup(iov, buf, cnt); if (result < 0) { if (!async_err) { posix_error(); } - return -1; + result = -1; } + iov_cleanup(iov, buf, cnt); return result; } @@ -11057,12 +12002,13 @@ win32_putenv(PyObject *name, PyObject *value) Prefer _wputenv() to be compatible with C libraries using CRT variables and CRT functions using these variables (ex: getenv()). */ int err = _wputenv(env); - PyMem_Free(env); if (err) { posix_error(); + PyMem_Free(env); return NULL; } + PyMem_Free(env); Py_RETURN_NONE; } @@ -12555,7 +13501,7 @@ setup_confname_table(struct constdef *table, size_t tablesize, } Py_DECREF(o); } - return PyModule_AddObject(module, tablename, d); + return _PyModule_Add(module, tablename, d); } /* Return -1 on failure, 0 on success. */ @@ -12617,7 +13563,7 @@ static int has_ShellExecute = -1; static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR, LPCWSTR, INT); static int -check_ShellExecute() +check_ShellExecute(void) { HINSTANCE hShell32; @@ -12904,10 +13850,12 @@ os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute, Py_END_ALLOW_THREADS; if (result < 0) { - Py_DECREF(buffer); - if (errno == ERANGE) + if (errno == ERANGE) { + Py_DECREF(buffer); continue; + } path_error(path); + Py_DECREF(buffer); return NULL; } @@ -13107,15 +14055,13 @@ os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks) PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start, trace - start); if (!attribute) { - Py_DECREF(result); - result = NULL; + Py_SETREF(result, NULL); goto exit; } error = PyList_Append(result, attribute); Py_DECREF(attribute); if (error) { - Py_DECREF(result); - result = NULL; + Py_SETREF(result, NULL); goto exit; } start = trace + 1; @@ -13327,24 +14273,11 @@ os_get_terminal_size_impl(PyObject *module, int fd) #ifdef TERMSIZE_USE_CONIO { - DWORD nhandle; HANDLE handle; CONSOLE_SCREEN_BUFFER_INFO csbi; - switch (fd) { - case 0: nhandle = STD_INPUT_HANDLE; - break; - case 1: nhandle = STD_OUTPUT_HANDLE; - break; - case 2: nhandle = STD_ERROR_HANDLE; - break; - default: - return PyErr_Format(PyExc_ValueError, "bad file descriptor"); - } - handle = GetStdHandle(nhandle); - if (handle == NULL) - return PyErr_Format(PyExc_OSError, "handle cannot be retrieved"); + handle = _Py_get_osfhandle(fd); if (handle == INVALID_HANDLE_VALUE) - return PyErr_SetFromWindowsErr(0); + return NULL; if (!GetConsoleScreenBufferInfo(handle, &csbi)) return PyErr_SetFromWindowsErr(0); @@ -13385,7 +14318,9 @@ os_cpu_count_impl(PyObject *module) { int ncpu = 0; #ifdef MS_WINDOWS +#ifdef MS_WINDOWS_DESKTOP ncpu = GetActiveProcessorCount(ALL_PROCESSOR_GROUPS); +#endif #elif defined(__hpux) ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL); #elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN) @@ -13457,6 +14392,10 @@ os_set_inheritable_impl(PyObject *module, int fd, int inheritable) #ifdef MS_WINDOWS +#ifndef HANDLE_FLAG_INHERIT +#define HANDLE_FLAG_INHERIT 0x00000001 +#endif + /*[clinic input] os.get_handle_inheritable -> bool handle: intptr_t @@ -13503,7 +14442,6 @@ os_set_handle_inheritable_impl(PyObject *module, intptr_t handle, } #endif /* MS_WINDOWS */ -#ifndef MS_WINDOWS /*[clinic input] os.get_blocking -> bool fd: int @@ -13529,7 +14467,7 @@ os_get_blocking_impl(PyObject *module, int fd) /*[clinic input] os.set_blocking fd: int - blocking: bool(accept={int}) + blocking: bool / Set the blocking mode of the specified file descriptor. @@ -13540,7 +14478,7 @@ clear the O_NONBLOCK flag otherwise. static PyObject * os_set_blocking_impl(PyObject *module, int fd, int blocking) -/*[clinic end generated code: output=384eb43aa0762a9d input=bf5c8efdc5860ff3]*/ +/*[clinic end generated code: output=384eb43aa0762a9d input=7e9dfc9b14804dd4]*/ { int result; @@ -13551,7 +14489,6 @@ os_set_blocking_impl(PyObject *module, int fd, int blocking) return NULL; Py_RETURN_NONE; } -#endif /* !MS_WINDOWS */ /*[clinic input] @@ -13622,6 +14559,25 @@ os_DirEntry_is_symlink_impl(DirEntry *self, PyTypeObject *defining_class) #endif } +/*[clinic input] +os.DirEntry.is_junction -> bool + defining_class: defining_class + / + +Return True if the entry is a junction; cached per entry. +[clinic start generated code]*/ + +static int +os_DirEntry_is_junction_impl(DirEntry *self, PyTypeObject *defining_class) +/*[clinic end generated code: output=7061a07b0ef2cd1f input=475cd36fb7d4723f]*/ +{ +#ifdef MS_WINDOWS + return self->win32_lstat.st_reparse_tag == IO_REPARSE_TAG_MOUNT_POINT; +#else + return 0; +#endif +} + static PyObject * DirEntry_fetch_stat(PyObject *module, DirEntry *self, int follow_symlinks) { @@ -13632,15 +14588,8 @@ DirEntry_fetch_stat(PyObject *module, DirEntry *self, int follow_symlinks) #ifdef MS_WINDOWS if (!PyUnicode_FSDecoder(self->path, &ub)) return NULL; -#if USE_UNICODE_WCHAR_CACHE -_Py_COMP_DIAG_PUSH -_Py_COMP_DIAG_IGNORE_DEPR_DECLS - const wchar_t *path = PyUnicode_AsUnicode(ub); -_Py_COMP_DIAG_POP -#else /* USE_UNICODE_WCHAR_CACHE */ wchar_t *path = PyUnicode_AsWideCharString(ub, NULL); Py_DECREF(ub); -#endif /* USE_UNICODE_WCHAR_CACHE */ #else /* POSIX */ if (!PyUnicode_FSConverter(self->path, &ub)) return NULL; @@ -13673,14 +14622,19 @@ _Py_COMP_DIAG_POP } Py_END_ALLOW_THREADS } -#if defined(MS_WINDOWS) && !USE_UNICODE_WCHAR_CACHE + + int saved_errno = errno; +#if defined(MS_WINDOWS) PyMem_Free(path); -#else /* USE_UNICODE_WCHAR_CACHE */ +#else Py_DECREF(ub); -#endif /* USE_UNICODE_WCHAR_CACHE */ +#endif - if (result != 0) - return path_object_error(self->path); + if (result != 0) { + errno = saved_errno; + path_object_error(self->path); + return NULL; + } return _pystat_fromstructstat(module, &st); } @@ -13696,8 +14650,7 @@ DirEntry_get_lstat(PyTypeObject *defining_class, DirEntry *self) self->lstat = DirEntry_fetch_stat(module, self, 0); #endif } - Py_XINCREF(self->lstat); - return self->lstat; + return Py_XNewRef(self->lstat); } /*[clinic input] @@ -13733,8 +14686,7 @@ os_DirEntry_stat_impl(DirEntry *self, PyTypeObject *defining_class, } } - Py_XINCREF(self->stat); - return self->stat; + return Py_XNewRef(self->stat); } /* Set exception and return -1 on error, 0 for False, 1 for True */ @@ -13871,22 +14823,17 @@ os_DirEntry_inode_impl(DirEntry *self) if (!PyUnicode_FSDecoder(self->path, &unicode)) return NULL; -#if USE_UNICODE_WCHAR_CACHE -_Py_COMP_DIAG_PUSH -_Py_COMP_DIAG_IGNORE_DEPR_DECLS - const wchar_t *path = PyUnicode_AsUnicode(unicode); - result = LSTAT(path, &stat); - Py_DECREF(unicode); -_Py_COMP_DIAG_POP -#else /* USE_UNICODE_WCHAR_CACHE */ wchar_t *path = PyUnicode_AsWideCharString(unicode, NULL); Py_DECREF(unicode); result = LSTAT(path, &stat); + + int saved_errno = errno; PyMem_Free(path); -#endif /* USE_UNICODE_WCHAR_CACHE */ - if (result != 0) + if (result != 0) { + errno = saved_errno; return path_object_error(self->path); + } self->win32_file_index = stat.st_ino; self->got_file_index = 1; @@ -13917,8 +14864,7 @@ static PyObject * os_DirEntry___fspath___impl(DirEntry *self) /*[clinic end generated code: output=6dd7f7ef752e6f4f input=3c49d0cf38df4fac]*/ { - Py_INCREF(self->path); - return self->path; + return Py_NewRef(self->path); } static PyMemberDef DirEntry_members[] = { @@ -13935,6 +14881,7 @@ static PyMethodDef DirEntry_methods[] = { OS_DIRENTRY_IS_DIR_METHODDEF OS_DIRENTRY_IS_FILE_METHODDEF OS_DIRENTRY_IS_SYMLINK_METHODDEF + OS_DIRENTRY_IS_JUNCTION_METHODDEF OS_DIRENTRY_STAT_METHODDEF OS_DIRENTRY_INODE_METHODDEF OS_DIRENTRY___FSPATH___METHODDEF @@ -14037,7 +14984,7 @@ DirEntry_from_find_data(PyObject *module, path_t *path, WIN32_FIND_DATAW *dataW) } find_data_to_file_info(dataW, &file_info, &reparse_tag); - _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat); + _Py_attribute_data_to_stat(&file_info, reparse_tag, NULL, NULL, &entry->win32_lstat); return (PyObject *)entry; @@ -14111,7 +15058,7 @@ DirEntry_from_posix_info(PyObject *module, path_t *path, const char *name, goto error; } - if (!path->narrow || !PyObject_CheckBuffer(path->object)) { + if (!path->narrow || !PyBytes_Check(path->object)) { entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len); if (joined_path) entry->path = PyUnicode_DecodeFSDefault(joined_path); @@ -14126,8 +15073,7 @@ DirEntry_from_posix_info(PyObject *module, path_t *path, const char *name, goto error; if (path->fd != -1) { - entry->path = entry->name; - Py_INCREF(entry->path); + entry->path = Py_NewRef(entry->name); } else if (!entry->path) goto error; @@ -14318,8 +15264,7 @@ ScandirIterator_close(ScandirIterator *self, PyObject *args) static PyObject * ScandirIterator_enter(PyObject *self, PyObject *args) { - Py_INCREF(self); - return self; + return Py_NewRef(self); } static PyObject * @@ -14332,10 +15277,9 @@ ScandirIterator_exit(ScandirIterator *self, PyObject *args) static void ScandirIterator_finalize(ScandirIterator *iterator) { - PyObject *error_type, *error_value, *error_traceback; /* Save the current exception, if any. */ - PyErr_Fetch(&error_type, &error_value, &error_traceback); + PyObject *exc = PyErr_GetRaisedException(); if (!ScandirIterator_is_closed(iterator)) { ScandirIterator_closedir(iterator); @@ -14352,7 +15296,7 @@ ScandirIterator_finalize(ScandirIterator *iterator) path_cleanup(&iterator->path); /* Restore the saved exception. */ - PyErr_Restore(error_type, error_value, error_traceback); + PyErr_SetRaisedException(exc); } static void @@ -14453,12 +15397,12 @@ os_scandir_impl(PyObject *module, path_t *path) iterator->handle = FindFirstFileW(path_strW, &iterator->file_data); Py_END_ALLOW_THREADS - PyMem_Free(path_strW); - if (iterator->handle == INVALID_HANDLE_VALUE) { path_error(&iterator->path); + PyMem_Free(path_strW); goto error; } + PyMem_Free(path_strW); #else /* POSIX */ errno = 0; #ifdef HAVE_FDOPENDIR @@ -14527,8 +15471,7 @@ PyOS_FSPath(PyObject *path) PyObject *path_repr = NULL; if (PyUnicode_Check(path) || PyBytes_Check(path)) { - Py_INCREF(path); - return path; + return Py_NewRef(path); } func = _PyObject_LookupSpecial(path, &_Py_ID(__fspath__)); @@ -14637,14 +15580,12 @@ error: } #endif /* HAVE_GETRANDOM_SYSCALL */ -#ifdef MS_WINDOWS +#if defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_APP) || defined(MS_WINDOWS_SYSTEM) + /* bpo-36085: Helper functions for managing DLL search directories * on win32 */ -typedef DLL_DIRECTORY_COOKIE (WINAPI *PAddDllDirectory)(PCWSTR newDirectory); -typedef BOOL (WINAPI *PRemoveDllDirectory)(DLL_DIRECTORY_COOKIE cookie); - /*[clinic input] os._add_dll_directory @@ -14664,8 +15605,6 @@ static PyObject * os__add_dll_directory_impl(PyObject *module, path_t *path) /*[clinic end generated code: output=80b025daebb5d683 input=1de3e6c13a5808c8]*/ { - HMODULE hKernel32; - PAddDllDirectory AddDllDirectory; DLL_DIRECTORY_COOKIE cookie = 0; DWORD err = 0; @@ -14673,14 +15612,8 @@ os__add_dll_directory_impl(PyObject *module, path_t *path) return NULL; } - /* For Windows 7, we have to load this. As this will be a fairly - infrequent operation, just do it each time. Kernel32 is always - loaded. */ Py_BEGIN_ALLOW_THREADS - if (!(hKernel32 = GetModuleHandleW(L"kernel32")) || - !(AddDllDirectory = (PAddDllDirectory)GetProcAddress( - hKernel32, "AddDllDirectory")) || - !(cookie = (*AddDllDirectory)(path->wide))) { + if (!(cookie = AddDllDirectory(path->wide))) { err = GetLastError(); } Py_END_ALLOW_THREADS @@ -14709,8 +15642,6 @@ static PyObject * os__remove_dll_directory_impl(PyObject *module, PyObject *cookie) /*[clinic end generated code: output=594350433ae535bc input=c1d16a7e7d9dc5dc]*/ { - HMODULE hKernel32; - PRemoveDllDirectory RemoveDllDirectory; DLL_DIRECTORY_COOKIE cookieValue; DWORD err = 0; @@ -14723,14 +15654,8 @@ os__remove_dll_directory_impl(PyObject *module, PyObject *cookie) cookieValue = (DLL_DIRECTORY_COOKIE)PyCapsule_GetPointer( cookie, "DLL directory cookie"); - /* For Windows 7, we have to load this. As this will be a fairly - infrequent operation, just do it each time. Kernel32 is always - loaded. */ Py_BEGIN_ALLOW_THREADS - if (!(hKernel32 = GetModuleHandleW(L"kernel32")) || - !(RemoveDllDirectory = (PRemoveDllDirectory)GetProcAddress( - hKernel32, "RemoveDllDirectory")) || - !(*RemoveDllDirectory)(cookieValue)) { + if (!RemoveDllDirectory(cookieValue)) { err = GetLastError(); } Py_END_ALLOW_THREADS @@ -14747,7 +15672,7 @@ os__remove_dll_directory_impl(PyObject *module, PyObject *cookie) Py_RETURN_NONE; } -#endif +#endif /* MS_WINDOWS_APP || MS_WINDOWS_SYSTEM */ /* Only check if WIFEXITED is available: expect that it comes @@ -14863,6 +15788,9 @@ static PyMethodDef posix_methods[] = { OS_GETCWDB_METHODDEF OS_LINK_METHODDEF OS_LISTDIR_METHODDEF + OS_LISTDRIVES_METHODDEF + OS_LISTMOUNTS_METHODDEF + OS_LISTVOLUMES_METHODDEF OS_LSTAT_METHODDEF OS_MKDIR_METHODDEF OS_NICE_METHODDEF @@ -15029,6 +15957,14 @@ static PyMethodDef posix_methods[] = { OS__ADD_DLL_DIRECTORY_METHODDEF OS__REMOVE_DLL_DIRECTORY_METHODDEF OS_WAITSTATUS_TO_EXITCODE_METHODDEF + OS_SETNS_METHODDEF + OS_UNSHARE_METHODDEF + + OS__PATH_ISDEVDRIVE_METHODDEF + OS__PATH_ISDIR_METHODDEF + OS__PATH_ISFILE_METHODDEF + OS__PATH_ISLINK_METHODDEF + OS__PATH_EXISTS_METHODDEF {NULL, NULL} /* Sentinel */ }; @@ -15145,6 +16081,18 @@ all_ins(PyObject *m) #ifdef PRIO_USER if (PyModule_AddIntMacro(m, PRIO_USER)) return -1; #endif +#ifdef PRIO_DARWIN_THREAD + if (PyModule_AddIntMacro(m, PRIO_DARWIN_THREAD)) return -1; +#endif +#ifdef PRIO_DARWIN_PROCESS + if (PyModule_AddIntMacro(m, PRIO_DARWIN_PROCESS)) return -1; +#endif +#ifdef PRIO_DARWIN_BG + if (PyModule_AddIntMacro(m, PRIO_DARWIN_BG)) return -1; +#endif +#ifdef PRIO_DARWIN_NONUI + if (PyModule_AddIntMacro(m, PRIO_DARWIN_NONUI)) return -1; +#endif #ifdef O_CLOEXEC if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1; #endif @@ -15354,6 +16302,9 @@ all_ins(PyObject *m) #ifdef P_PIDFD if (PyModule_AddIntMacro(m, P_PIDFD)) return -1; #endif +#ifdef PIDFD_NONBLOCK + if (PyModule_AddIntMacro(m, PIDFD_NONBLOCK)) return -1; +#endif #endif #ifdef WEXITED if (PyModule_AddIntMacro(m, WEXITED)) return -1; @@ -15471,6 +16422,53 @@ all_ins(PyObject *m) #ifdef SCHED_FX if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1; #endif + +/* constants for namespaces */ +#if defined(HAVE_SETNS) || defined(HAVE_UNSHARE) +#ifdef CLONE_FS + if (PyModule_AddIntMacro(m, CLONE_FS)) return -1; +#endif +#ifdef CLONE_FILES + if (PyModule_AddIntMacro(m, CLONE_FILES)) return -1; +#endif +#ifdef CLONE_NEWNS + if (PyModule_AddIntMacro(m, CLONE_NEWNS)) return -1; +#endif +#ifdef CLONE_NEWCGROUP + if (PyModule_AddIntMacro(m, CLONE_NEWCGROUP)) return -1; +#endif +#ifdef CLONE_NEWUTS + if (PyModule_AddIntMacro(m, CLONE_NEWUTS)) return -1; +#endif +#ifdef CLONE_NEWIPC + if (PyModule_AddIntMacro(m, CLONE_NEWIPC)) return -1; +#endif +#ifdef CLONE_NEWUSER + if (PyModule_AddIntMacro(m, CLONE_NEWUSER)) return -1; +#endif +#ifdef CLONE_NEWPID + if (PyModule_AddIntMacro(m, CLONE_NEWPID)) return -1; +#endif +#ifdef CLONE_NEWNET + if (PyModule_AddIntMacro(m, CLONE_NEWNET)) return -1; +#endif +#ifdef CLONE_NEWTIME + if (PyModule_AddIntMacro(m, CLONE_NEWTIME)) return -1; +#endif +#ifdef CLONE_SYSVSEM + if (PyModule_AddIntMacro(m, CLONE_SYSVSEM)) return -1; +#endif +#ifdef CLONE_THREAD + if (PyModule_AddIntMacro(m, CLONE_THREAD)) return -1; +#endif +#ifdef CLONE_SIGHAND + if (PyModule_AddIntMacro(m, CLONE_SIGHAND)) return -1; +#endif +#ifdef CLONE_VM + if (PyModule_AddIntMacro(m, CLONE_VM)) return -1; +#endif +#endif + #endif #ifdef USE_XATTRS @@ -15829,11 +16827,9 @@ posixmodule_exec(PyObject *m) #endif /* Initialize environ dictionary */ - PyObject *v = convertenviron(); - Py_XINCREF(v); - if (v == NULL || PyModule_AddObject(m, "environ", v) != 0) + if (_PyModule_Add(m, "environ", convertenviron()) != 0) { return -1; - Py_DECREF(v); + } if (all_ins(m)) return -1; @@ -15841,72 +16837,49 @@ posixmodule_exec(PyObject *m) if (setup_confname_tables(m)) return -1; - Py_INCREF(PyExc_OSError); - PyModule_AddObject(m, "error", PyExc_OSError); + if (PyModule_AddObjectRef(m, "error", PyExc_OSError) < 0) { + return -1; + } #if defined(HAVE_WAITID) && !defined(__APPLE__) waitid_result_desc.name = MODNAME ".waitid_result"; - PyObject *WaitidResultType = (PyObject *)PyStructSequence_NewType(&waitid_result_desc); - if (WaitidResultType == NULL) { + state->WaitidResultType = (PyObject *)PyStructSequence_NewType(&waitid_result_desc); + if (PyModule_AddObjectRef(m, "waitid_result", state->WaitidResultType) < 0) { return -1; } - Py_INCREF(WaitidResultType); - PyModule_AddObject(m, "waitid_result", WaitidResultType); - state->WaitidResultType = WaitidResultType; #endif stat_result_desc.name = "os.stat_result"; /* see issue #19209 */ stat_result_desc.fields[7].name = PyStructSequence_UnnamedField; stat_result_desc.fields[8].name = PyStructSequence_UnnamedField; stat_result_desc.fields[9].name = PyStructSequence_UnnamedField; - PyObject *StatResultType = (PyObject *)PyStructSequence_NewType(&stat_result_desc); - if (StatResultType == NULL) { + state->StatResultType = (PyObject *)PyStructSequence_NewType(&stat_result_desc); + if (PyModule_AddObjectRef(m, "stat_result", state->StatResultType) < 0) { return -1; } - Py_INCREF(StatResultType); - PyModule_AddObject(m, "stat_result", StatResultType); - state->StatResultType = StatResultType; - structseq_new = ((PyTypeObject *)StatResultType)->tp_new; - ((PyTypeObject *)StatResultType)->tp_new = statresult_new; + state->statresult_new_orig = ((PyTypeObject *)state->StatResultType)->tp_new; + ((PyTypeObject *)state->StatResultType)->tp_new = statresult_new; statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */ - PyObject *StatVFSResultType = (PyObject *)PyStructSequence_NewType(&statvfs_result_desc); - if (StatVFSResultType == NULL) { + state->StatVFSResultType = (PyObject *)PyStructSequence_NewType(&statvfs_result_desc); + if (PyModule_AddObjectRef(m, "statvfs_result", state->StatVFSResultType) < 0) { return -1; } - Py_INCREF(StatVFSResultType); - PyModule_AddObject(m, "statvfs_result", StatVFSResultType); - state->StatVFSResultType = StatVFSResultType; -#ifdef NEED_TICKS_PER_SECOND -# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK) - ticks_per_second = sysconf(_SC_CLK_TCK); -# elif defined(HZ) - ticks_per_second = HZ; -# else - ticks_per_second = 60; /* magic fallback value; may be bogus */ -# endif -#endif #if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM) sched_param_desc.name = MODNAME ".sched_param"; - PyObject *SchedParamType = (PyObject *)PyStructSequence_NewType(&sched_param_desc); - if (SchedParamType == NULL) { + state->SchedParamType = (PyObject *)PyStructSequence_NewType(&sched_param_desc); + if (PyModule_AddObjectRef(m, "sched_param", state->SchedParamType) < 0) { return -1; } - Py_INCREF(SchedParamType); - PyModule_AddObject(m, "sched_param", SchedParamType); - state->SchedParamType = SchedParamType; - ((PyTypeObject *)SchedParamType)->tp_new = os_sched_param; + ((PyTypeObject *)state->SchedParamType)->tp_new = os_sched_param; #endif /* initialize TerminalSize_info */ - PyObject *TerminalSizeType = (PyObject *)PyStructSequence_NewType(&TerminalSize_desc); - if (TerminalSizeType == NULL) { + state->TerminalSizeType = (PyObject *)PyStructSequence_NewType(&TerminalSize_desc); + if (PyModule_AddObjectRef(m, "terminal_size", state->TerminalSizeType) < 0) { return -1; } - Py_INCREF(TerminalSizeType); - PyModule_AddObject(m, "terminal_size", TerminalSizeType); - state->TerminalSizeType = TerminalSizeType; /* initialize scandir types */ PyObject *ScandirIteratorType = PyType_FromModuleAndSpec(m, &ScandirIteratorType_spec, NULL); @@ -15915,30 +16888,21 @@ posixmodule_exec(PyObject *m) } state->ScandirIteratorType = ScandirIteratorType; - PyObject *DirEntryType = PyType_FromModuleAndSpec(m, &DirEntryType_spec, NULL); - if (DirEntryType == NULL) { + state->DirEntryType = PyType_FromModuleAndSpec(m, &DirEntryType_spec, NULL); + if (PyModule_AddObjectRef(m, "DirEntry", state->DirEntryType) < 0) { return -1; } - Py_INCREF(DirEntryType); - PyModule_AddObject(m, "DirEntry", DirEntryType); - state->DirEntryType = DirEntryType; times_result_desc.name = MODNAME ".times_result"; - PyObject *TimesResultType = (PyObject *)PyStructSequence_NewType(×_result_desc); - if (TimesResultType == NULL) { + state->TimesResultType = (PyObject *)PyStructSequence_NewType(×_result_desc); + if (PyModule_AddObjectRef(m, "times_result", state->TimesResultType) < 0) { return -1; } - Py_INCREF(TimesResultType); - PyModule_AddObject(m, "times_result", TimesResultType); - state->TimesResultType = TimesResultType; - PyTypeObject *UnameResultType = PyStructSequence_NewType(&uname_result_desc); - if (UnameResultType == NULL) { + state->UnameResultType = (PyObject *)PyStructSequence_NewType(&uname_result_desc); + if (PyModule_AddObjectRef(m, "uname_result", state->UnameResultType) < 0) { return -1; } - Py_INCREF(UnameResultType); - PyModule_AddObject(m, "uname_result", (PyObject *)UnameResultType); - state->UnameResultType = (PyObject *)UnameResultType; if ((state->billion = PyLong_FromLong(1000000000)) == NULL) return -1; @@ -15980,14 +16944,13 @@ posixmodule_exec(PyObject *m) Py_DECREF(unicode); } - PyModule_AddObject(m, "_have_functions", list); - - return 0; + return _PyModule_Add(m, "_have_functions", list); } static PyModuleDef_Slot posixmodile_slots[] = { {Py_mod_exec, posixmodule_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; diff --git a/Modules/pwdmodule.c b/Modules/pwdmodule.c index a757380b..cc2e2a43 100644 --- a/Modules/pwdmodule.c +++ b/Modules/pwdmodule.c @@ -336,6 +336,7 @@ pwdmodule_exec(PyObject *module) static PyModuleDef_Slot pwdmodule_slots[] = { {Py_mod_exec, pwdmodule_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; diff --git a/Modules/pyexpat.c b/Modules/pyexpat.c index a74d8046..b2136041 100644 --- a/Modules/pyexpat.c +++ b/Modules/pyexpat.c @@ -710,7 +710,7 @@ pyexpat.xmlparser.Parse cls: defining_class data: object - isfinal: bool(accept={int}) = False + isfinal: bool = False / Parse XML data. @@ -721,7 +721,7 @@ Parse XML data. static PyObject * pyexpat_xmlparser_Parse_impl(xmlparseobject *self, PyTypeObject *cls, PyObject *data, int isfinal) -/*[clinic end generated code: output=8faffe07fe1f862a input=fc97f833558ca715]*/ +/*[clinic end generated code: output=8faffe07fe1f862a input=d0eb2a69fab3b9f1]*/ { const char *s; Py_ssize_t slen; @@ -959,8 +959,7 @@ pyexpat_xmlparser_ExternalEntityParserCreate_impl(xmlparseobject *self, new_parser->itself = XML_ExternalEntityParserCreate(self->itself, context, encoding); new_parser->handlers = 0; - new_parser->intern = self->intern; - Py_XINCREF(new_parser->intern); + new_parser->intern = Py_XNewRef(self->intern); if (self->buffer != NULL) { new_parser->buffer = PyMem_Malloc(new_parser->buffer_size); @@ -991,8 +990,7 @@ pyexpat_xmlparser_ExternalEntityParserCreate_impl(xmlparseobject *self, for (i = 0; handler_info[i].name != NULL; i++) { PyObject *handler = self->handlers[i]; if (handler != NULL) { - Py_INCREF(handler); - new_parser->handlers[i] = handler; + new_parser->handlers[i] = Py_NewRef(handler); handler_info[i].setter(new_parser->itself, handler_info[i].handler); } @@ -1078,26 +1076,39 @@ static struct PyMethodDef xmlparse_methods[] = { Make it as simple as possible. */ +static const unsigned char template_buffer[256] = + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, + 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, + 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, + 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, + 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, + 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, + 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, + 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, + 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, + 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, + 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, + 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255}; + + static int PyUnknownEncodingHandler(void *encodingHandlerData, const XML_Char *name, XML_Encoding *info) { - static unsigned char template_buffer[256] = {0}; - PyObject* u; + PyObject *u; int i; const void *data; - unsigned int kind; + int kind; if (PyErr_Occurred()) return XML_STATUS_ERROR; - if (template_buffer[1] == 0) { - for (i = 0; i < 256; i++) - template_buffer[i] = i; - } - - u = PyUnicode_Decode((char*) template_buffer, 256, name, "replace"); + u = PyUnicode_Decode((const char*) template_buffer, 256, name, "replace"); if (u == NULL || PyUnicode_READY(u)) { Py_XDECREF(u); return XML_STATUS_ERROR; @@ -1148,8 +1159,7 @@ newxmlparseobject(pyexpat_state *state, const char *encoding, self->in_callback = 0; self->ns_prefixes = 0; self->handlers = NULL; - self->intern = intern; - Py_XINCREF(self->intern); + self->intern = Py_XNewRef(intern); /* namespace_separator is either NULL or contains one char + \0 */ self->itself = XML_ParserCreate_MM(encoding, &ExpatMemoryHandler, @@ -1232,8 +1242,7 @@ xmlparse_handler_getter(xmlparseobject *self, struct HandlerInfo *hi) PyObject *result = self->handlers[handlernum]; if (result == NULL) result = Py_None; - Py_INCREF(result); - return result; + return Py_NewRef(result); } static int @@ -1365,9 +1374,7 @@ xmlparse_buffer_size_setter(xmlparseobject *self, PyObject *v, void *closure) /* check maximum */ if (new_buffer_size > INT_MAX) { - char errmsg[100]; - sprintf(errmsg, "buffer_size must not be greater than %i", INT_MAX); - PyErr_SetString(PyExc_ValueError, errmsg); + PyErr_Format(PyExc_ValueError, "buffer_size must not be greater than %i", INT_MAX); return -1; } @@ -1725,7 +1732,7 @@ add_error(PyObject *errors_module, PyObject *codes_dict, const int error_code = (int)error_index; /* NOTE: This keeps the source of truth regarding error - * messages with libexpat and (by definiton) in bulletproof sync + * messages with libexpat and (by definition) in bulletproof sync * with the other uses of the XML_ErrorString function * elsewhere within this file. pyexpat's copy of the messages * only acts as a fallback in case of outdated runtime libexpat, @@ -1768,14 +1775,18 @@ add_error(PyObject *errors_module, PyObject *codes_dict, static int add_errors_module(PyObject *mod) { + // add_submodule() returns a borrowed ref. PyObject *errors_module = add_submodule(mod, MODULE_NAME ".errors"); if (errors_module == NULL) { return -1; } PyObject *codes_dict = PyDict_New(); + if (codes_dict == NULL) { + return -1; + } PyObject *rev_codes_dict = PyDict_New(); - if (codes_dict == NULL || rev_codes_dict == NULL) { + if (rev_codes_dict == NULL) { goto error; } @@ -1796,19 +1807,17 @@ add_errors_module(PyObject *mod) goto error; } - Py_INCREF(codes_dict); - if (PyModule_AddObject(errors_module, "codes", codes_dict) < 0) { - Py_DECREF(codes_dict); + int rc = PyModule_AddObjectRef(errors_module, "codes", codes_dict); + Py_CLEAR(codes_dict); + if (rc < 0) { goto error; } - Py_CLEAR(codes_dict); - Py_INCREF(rev_codes_dict); - if (PyModule_AddObject(errors_module, "messages", rev_codes_dict) < 0) { - Py_DECREF(rev_codes_dict); + rc = PyModule_AddObjectRef(errors_module, "messages", rev_codes_dict); + Py_CLEAR(rev_codes_dict); + if (rc < 0) { goto error; } - Py_CLEAR(rev_codes_dict); return 0; @@ -1886,6 +1895,18 @@ error: } #endif +static void +pyexpat_capsule_destructor(PyObject *capsule) +{ + void *p = PyCapsule_GetPointer(capsule, PyExpat_CAPSULE_NAME); + if (p == NULL) { + PyErr_WriteUnraisable(capsule); + return; + } + PyMem_Free(p); +} + + static int pyexpat_exec(PyObject *mod) { @@ -1973,40 +1994,46 @@ pyexpat_exec(PyObject *mod) MYCONST(XML_PARAM_ENTITY_PARSING_ALWAYS); #undef MYCONST - static struct PyExpat_CAPI capi; + struct PyExpat_CAPI *capi = PyMem_Malloc(sizeof(*capi)); + if (capi == NULL) { + PyErr_NoMemory(); + return -1; + } /* initialize pyexpat dispatch table */ - capi.size = sizeof(capi); - capi.magic = PyExpat_CAPI_MAGIC; - capi.MAJOR_VERSION = XML_MAJOR_VERSION; - capi.MINOR_VERSION = XML_MINOR_VERSION; - capi.MICRO_VERSION = XML_MICRO_VERSION; - capi.ErrorString = XML_ErrorString; - capi.GetErrorCode = XML_GetErrorCode; - capi.GetErrorColumnNumber = XML_GetErrorColumnNumber; - capi.GetErrorLineNumber = XML_GetErrorLineNumber; - capi.Parse = XML_Parse; - capi.ParserCreate_MM = XML_ParserCreate_MM; - capi.ParserFree = XML_ParserFree; - capi.SetCharacterDataHandler = XML_SetCharacterDataHandler; - capi.SetCommentHandler = XML_SetCommentHandler; - capi.SetDefaultHandlerExpand = XML_SetDefaultHandlerExpand; - capi.SetElementHandler = XML_SetElementHandler; - capi.SetNamespaceDeclHandler = XML_SetNamespaceDeclHandler; - capi.SetProcessingInstructionHandler = XML_SetProcessingInstructionHandler; - capi.SetUnknownEncodingHandler = XML_SetUnknownEncodingHandler; - capi.SetUserData = XML_SetUserData; - capi.SetStartDoctypeDeclHandler = XML_SetStartDoctypeDeclHandler; - capi.SetEncoding = XML_SetEncoding; - capi.DefaultUnknownEncodingHandler = PyUnknownEncodingHandler; + capi->size = sizeof(*capi); + capi->magic = PyExpat_CAPI_MAGIC; + capi->MAJOR_VERSION = XML_MAJOR_VERSION; + capi->MINOR_VERSION = XML_MINOR_VERSION; + capi->MICRO_VERSION = XML_MICRO_VERSION; + capi->ErrorString = XML_ErrorString; + capi->GetErrorCode = XML_GetErrorCode; + capi->GetErrorColumnNumber = XML_GetErrorColumnNumber; + capi->GetErrorLineNumber = XML_GetErrorLineNumber; + capi->Parse = XML_Parse; + capi->ParserCreate_MM = XML_ParserCreate_MM; + capi->ParserFree = XML_ParserFree; + capi->SetCharacterDataHandler = XML_SetCharacterDataHandler; + capi->SetCommentHandler = XML_SetCommentHandler; + capi->SetDefaultHandlerExpand = XML_SetDefaultHandlerExpand; + capi->SetElementHandler = XML_SetElementHandler; + capi->SetNamespaceDeclHandler = XML_SetNamespaceDeclHandler; + capi->SetProcessingInstructionHandler = XML_SetProcessingInstructionHandler; + capi->SetUnknownEncodingHandler = XML_SetUnknownEncodingHandler; + capi->SetUserData = XML_SetUserData; + capi->SetStartDoctypeDeclHandler = XML_SetStartDoctypeDeclHandler; + capi->SetEncoding = XML_SetEncoding; + capi->DefaultUnknownEncodingHandler = PyUnknownEncodingHandler; #if XML_COMBINED_VERSION >= 20100 - capi.SetHashSalt = XML_SetHashSalt; + capi->SetHashSalt = XML_SetHashSalt; #else - capi.SetHashSalt = NULL; + capi->SetHashSalt = NULL; #endif /* export using capsule */ - PyObject *capi_object = PyCapsule_New(&capi, PyExpat_CAPSULE_NAME, NULL); + PyObject *capi_object = PyCapsule_New(capi, PyExpat_CAPSULE_NAME, + pyexpat_capsule_destructor); if (capi_object == NULL) { + PyMem_Free(capi); return -1; } @@ -2046,6 +2073,9 @@ pyexpat_free(void *module) static PyModuleDef_Slot pyexpat_slots[] = { {Py_mod_exec, pyexpat_exec}, + // XXX gh-103092: fix isolation. + {Py_mod_multiple_interpreters, Py_MOD_MULTIPLE_INTERPRETERS_NOT_SUPPORTED}, + //{Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; diff --git a/Modules/readline.c b/Modules/readline.c index 27b89de7..2824105a 100644 --- a/Modules/readline.c +++ b/Modules/readline.c @@ -11,7 +11,10 @@ #include <signal.h> #include <stddef.h> #include <stdlib.h> // free() +#ifdef HAVE_SYS_TIME_H #include <sys/time.h> +#endif +#include <time.h> #if defined(HAVE_SETLOCALE) /* GNU readline() mistakenly sets the LC_CTYPE locale. @@ -402,8 +405,7 @@ set_hook(const char *funcname, PyObject **hook_var, PyObject *function) Py_CLEAR(*hook_var); } else if (PyCallable_Check(function)) { - Py_INCREF(function); - Py_XSETREF(*hook_var, function); + Py_XSETREF(*hook_var, Py_NewRef(function)); } else { PyErr_Format(PyExc_TypeError, @@ -524,8 +526,7 @@ static PyObject * readline_get_begidx_impl(PyObject *module) /*[clinic end generated code: output=362616ee8ed1b2b1 input=e083b81c8eb4bac3]*/ { - Py_INCREF(readlinestate_global->begidx); - return readlinestate_global->begidx; + return Py_NewRef(readlinestate_global->begidx); } /* Get the ending index for the scope of the tab-completion */ @@ -540,8 +541,7 @@ static PyObject * readline_get_endidx_impl(PyObject *module) /*[clinic end generated code: output=7f763350b12d7517 input=d4c7e34a625fd770]*/ { - Py_INCREF(readlinestate_global->endidx); - return readlinestate_global->endidx; + return Py_NewRef(readlinestate_global->endidx); } /* Set the tab-completion word-delimiters that readline uses */ @@ -784,8 +784,7 @@ readline_get_completer_impl(PyObject *module) if (readlinestate_global->completer == NULL) { Py_RETURN_NONE; } - Py_INCREF(readlinestate_global->completer); - return readlinestate_global->completer; + return Py_NewRef(readlinestate_global->completer); } /* Private function to get current length of history. XXX It may be diff --git a/Modules/resource.c b/Modules/resource.c index d8bba2e3..3c89468c 100644 --- a/Modules/resource.c +++ b/Modules/resource.c @@ -1,7 +1,10 @@ #include "Python.h" #include <sys/resource.h> +#ifdef HAVE_SYS_TIME_H #include <sys/time.h> +#endif +#include <time.h> #include <string.h> #include <errno.h> #include <unistd.h> @@ -24,8 +27,16 @@ module resource class pid_t_converter(CConverter): type = 'pid_t' format_unit = '" _Py_PARSE_PID "' + + def parse_arg(self, argname, displayname): + return """ + {paramname} = PyLong_AsPid({argname}); + if ({paramname} == -1 && PyErr_Occurred()) {{{{ + goto exit; + }}}} + """.format(argname=argname, paramname=self.parser_name) [python start generated code]*/ -/*[python end generated code: output=da39a3ee5e6b4b0d input=0c1d19f640d57e48]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=5af1c116d56cbb5a]*/ #include "clinic/resource.c.h" @@ -268,17 +279,15 @@ resource.prlimit pid: pid_t resource: int - [ - limits: object - ] + limits: object = None / [clinic start generated code]*/ static PyObject * resource_prlimit_impl(PyObject *module, pid_t pid, int resource, - int group_right_1, PyObject *limits) -/*[clinic end generated code: output=ee976b393187a7a3 input=b77743bdccc83564]*/ + PyObject *limits) +/*[clinic end generated code: output=6ebc49ff8c3a816e input=54bb69c9585e33bf]*/ { struct rlimit old_limit, new_limit; int retval; @@ -294,7 +303,7 @@ resource_prlimit_impl(PyObject *module, pid_t pid, int resource, return NULL; } - if (group_right_1) { + if (limits != Py_None) { if (py2rlimit(limits, &new_limit) < 0) { return NULL; } @@ -508,6 +517,7 @@ resource_exec(PyObject *module) static struct PyModuleDef_Slot resource_slots[] = { {Py_mod_exec, resource_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c index 4eea928a..a88c3cb8 100644 --- a/Modules/selectmodule.c +++ b/Modules/selectmodule.c @@ -57,8 +57,10 @@ extern void bzero(void *, int); #endif #ifdef MS_WINDOWS -# define WIN32_LEAN_AND_MEAN -# include <winsock.h> +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +# endif +# include <winsock2.h> #else # define SOCKET int #endif @@ -1290,8 +1292,8 @@ newPyEpoll_Object(PyTypeObject *type, int sizehint, SOCKET fd) self->epfd = fd; } if (self->epfd < 0) { - Py_DECREF(self); PyErr_SetFromErrno(PyExc_OSError); + Py_DECREF(self); return NULL; } @@ -1652,8 +1654,7 @@ select_epoll___enter___impl(pyEpoll_Object *self) if (self->epfd < 0) return pyepoll_err_closed(); - Py_INCREF(self); - return (PyObject *)self; + return Py_NewRef(self); } /*[clinic input] @@ -1848,14 +1849,11 @@ static PyObject * kqueue_event_repr(kqueue_event_Object *s) { - char buf[1024]; - PyOS_snprintf( - buf, sizeof(buf), + return PyUnicode_FromFormat( "<select.kevent ident=%zu filter=%d flags=0x%x fflags=0x%x " "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); } static int @@ -1973,8 +1971,8 @@ newKqueue_Object(PyTypeObject *type, SOCKET fd) self->kqfd = fd; } if (self->kqfd < 0) { - Py_DECREF(self); PyErr_SetFromErrno(PyExc_OSError); + Py_DECREF(self); return NULL; } @@ -2650,6 +2648,7 @@ _select_exec(PyObject *m) static PyModuleDef_Slot _select_slots[] = { {Py_mod_exec, _select_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; diff --git a/Modules/sha1module.c b/Modules/sha1module.c index 9153557f..c66269b5 100644 --- a/Modules/sha1module.c +++ b/Modules/sha1module.c @@ -22,6 +22,7 @@ #include "Python.h" #include "hashlib.h" #include "pycore_strhex.h" // _Py_strhex() +#include "pycore_typeobject.h" // _PyType_GetModuleState() /*[clinic input] module _sha1 @@ -43,260 +44,18 @@ typedef long long SHA1_INT64; /* 64-bit integer */ #define SHA1_BLOCKSIZE 64 #define SHA1_DIGESTSIZE 20 -/* The structure for storing SHA1 info */ - -struct sha1_state { - SHA1_INT64 length; - SHA1_INT32 state[5], curlen; - unsigned char buf[SHA1_BLOCKSIZE]; -}; +#include "_hacl/Hacl_Hash_SHA1.h" typedef struct { PyObject_HEAD - - struct sha1_state hash_state; + // Prevents undefined behavior via multiple threads entering the C API. + // The lock will be NULL before threaded access has been enabled. + PyThread_type_lock lock; + Hacl_Streaming_SHA1_state *hash_state; } SHA1object; #include "clinic/sha1module.c.h" -/* ------------------------------------------------------------------------ - * - * This code for the SHA1 algorithm was noted as public domain. The - * original headers are pasted below. - * - * Several changes have been made to make it more compatible with the - * Python environment and desired interface. - * - */ - -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, https://www.libtom.net - */ - -/* rotate the hard way (platform optimizations could be done) */ -#define ROL(x, y) ( (((unsigned long)(x)<<(unsigned long)((y)&31)) | (((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL) -#define ROLc(x, y) ( (((unsigned long)(x)<<(unsigned long)((y)&31)) | (((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL) - -/* Endian Neutral macros that work on all platforms */ - -#define STORE32H(x, y) \ - { (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255); \ - (y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); } - -#define LOAD32H(x, y) \ - { x = ((unsigned long)((y)[0] & 255)<<24) | \ - ((unsigned long)((y)[1] & 255)<<16) | \ - ((unsigned long)((y)[2] & 255)<<8) | \ - ((unsigned long)((y)[3] & 255)); } - -#define STORE64H(x, y) \ - { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \ - (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \ - (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \ - (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); } - - -/* SHA1 macros */ - -#define F0(x,y,z) (z ^ (x & (y ^ z))) -#define F1(x,y,z) (x ^ y ^ z) -#define F2(x,y,z) ((x & y) | (z & (x | y))) -#define F3(x,y,z) (x ^ y ^ z) - -static void sha1_compress(struct sha1_state *sha1, unsigned char *buf) -{ - SHA1_INT32 a,b,c,d,e,W[80],i; - - /* copy the state into 512-bits into W[0..15] */ - for (i = 0; i < 16; i++) { - LOAD32H(W[i], buf + (4*i)); - } - - /* copy state */ - a = sha1->state[0]; - b = sha1->state[1]; - c = sha1->state[2]; - d = sha1->state[3]; - e = sha1->state[4]; - - /* expand it */ - for (i = 16; i < 80; i++) { - W[i] = ROL(W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16], 1); - } - - /* compress */ - /* round one */ - #define FF_0(a,b,c,d,e,i) e = (ROLc(a, 5) + F0(b,c,d) + e + W[i] + 0x5a827999UL); b = ROLc(b, 30); - #define FF_1(a,b,c,d,e,i) e = (ROLc(a, 5) + F1(b,c,d) + e + W[i] + 0x6ed9eba1UL); b = ROLc(b, 30); - #define FF_2(a,b,c,d,e,i) e = (ROLc(a, 5) + F2(b,c,d) + e + W[i] + 0x8f1bbcdcUL); b = ROLc(b, 30); - #define FF_3(a,b,c,d,e,i) e = (ROLc(a, 5) + F3(b,c,d) + e + W[i] + 0xca62c1d6UL); b = ROLc(b, 30); - - for (i = 0; i < 20; ) { - FF_0(a,b,c,d,e,i++); - FF_0(e,a,b,c,d,i++); - FF_0(d,e,a,b,c,i++); - FF_0(c,d,e,a,b,i++); - FF_0(b,c,d,e,a,i++); - } - - /* round two */ - for (; i < 40; ) { - FF_1(a,b,c,d,e,i++); - FF_1(e,a,b,c,d,i++); - FF_1(d,e,a,b,c,i++); - FF_1(c,d,e,a,b,i++); - FF_1(b,c,d,e,a,i++); - } - - /* round three */ - for (; i < 60; ) { - FF_2(a,b,c,d,e,i++); - FF_2(e,a,b,c,d,i++); - FF_2(d,e,a,b,c,i++); - FF_2(c,d,e,a,b,i++); - FF_2(b,c,d,e,a,i++); - } - - /* round four */ - for (; i < 80; ) { - FF_3(a,b,c,d,e,i++); - FF_3(e,a,b,c,d,i++); - FF_3(d,e,a,b,c,i++); - FF_3(c,d,e,a,b,i++); - FF_3(b,c,d,e,a,i++); - } - - #undef FF_0 - #undef FF_1 - #undef FF_2 - #undef FF_3 - - /* store */ - sha1->state[0] = sha1->state[0] + a; - sha1->state[1] = sha1->state[1] + b; - sha1->state[2] = sha1->state[2] + c; - sha1->state[3] = sha1->state[3] + d; - sha1->state[4] = sha1->state[4] + e; -} - -/** - Initialize the hash state - @param sha1 The hash state you wish to initialize -*/ -static void -sha1_init(struct sha1_state *sha1) -{ - assert(sha1 != NULL); - sha1->state[0] = 0x67452301UL; - sha1->state[1] = 0xefcdab89UL; - sha1->state[2] = 0x98badcfeUL; - sha1->state[3] = 0x10325476UL; - sha1->state[4] = 0xc3d2e1f0UL; - sha1->curlen = 0; - sha1->length = 0; -} - -/** - Process a block of memory though the hash - @param sha1 The hash state - @param in The data to hash - @param inlen The length of the data (octets) -*/ -static void -sha1_process(struct sha1_state *sha1, - const unsigned char *in, Py_ssize_t inlen) -{ - Py_ssize_t n; - - assert(sha1 != NULL); - assert(in != NULL); - assert(sha1->curlen <= sizeof(sha1->buf)); - - while (inlen > 0) { - if (sha1->curlen == 0 && inlen >= SHA1_BLOCKSIZE) { - sha1_compress(sha1, (unsigned char *)in); - sha1->length += SHA1_BLOCKSIZE * 8; - in += SHA1_BLOCKSIZE; - inlen -= SHA1_BLOCKSIZE; - } else { - n = Py_MIN(inlen, (Py_ssize_t)(SHA1_BLOCKSIZE - sha1->curlen)); - memcpy(sha1->buf + sha1->curlen, in, (size_t)n); - sha1->curlen += (SHA1_INT32)n; - in += n; - inlen -= n; - if (sha1->curlen == SHA1_BLOCKSIZE) { - sha1_compress(sha1, sha1->buf); - sha1->length += 8*SHA1_BLOCKSIZE; - sha1->curlen = 0; - } - } - } -} - -/** - Terminate the hash to get the digest - @param sha1 The hash state - @param out [out] The destination of the hash (20 bytes) -*/ -static void -sha1_done(struct sha1_state *sha1, unsigned char *out) -{ - int i; - - assert(sha1 != NULL); - assert(out != NULL); - assert(sha1->curlen < sizeof(sha1->buf)); - - /* increase the length of the message */ - sha1->length += sha1->curlen * 8; - - /* append the '1' bit */ - sha1->buf[sha1->curlen++] = (unsigned char)0x80; - - /* if the length is currently above 56 bytes we append zeros - * then compress. Then we can fall back to padding zeros and length - * encoding like normal. - */ - if (sha1->curlen > 56) { - while (sha1->curlen < 64) { - sha1->buf[sha1->curlen++] = (unsigned char)0; - } - sha1_compress(sha1, sha1->buf); - sha1->curlen = 0; - } - - /* pad up to 56 bytes of zeroes */ - while (sha1->curlen < 56) { - sha1->buf[sha1->curlen++] = (unsigned char)0; - } - - /* store length */ - STORE64H(sha1->length, sha1->buf+56); - sha1_compress(sha1, sha1->buf); - - /* copy output */ - for (i = 0; i < 5; i++) { - STORE32H(sha1->state[i], out+(4*i)); - } -} - - -/* .Source: /cvs/libtom/libtomcrypt/src/hashes/sha1.c,v $ */ -/* .Revision: 1.10 $ */ -/* .Date: 2007/05/12 14:25:28 $ */ - -/* - * End of copied SHA1 code. - * - * ------------------------------------------------------------------------ - */ typedef struct { PyTypeObject* sha1_type; @@ -314,6 +73,7 @@ static SHA1object * newSHA1object(SHA1State *st) { SHA1object *sha = (SHA1object *)PyObject_GC_New(SHA1object, st->sha1_type); + sha->lock = NULL; PyObject_GC_Track(sha); return sha; } @@ -328,8 +88,12 @@ SHA1_traverse(PyObject *ptr, visitproc visit, void *arg) } static void -SHA1_dealloc(PyObject *ptr) +SHA1_dealloc(SHA1object *ptr) { + Hacl_Streaming_SHA1_legacy_free(ptr->hash_state); + if (ptr->lock != NULL) { + PyThread_free_lock(ptr->lock); + } PyTypeObject *tp = Py_TYPE(ptr); PyObject_GC_UnTrack(ptr); PyObject_GC_Del(ptr); @@ -351,13 +115,15 @@ static PyObject * SHA1Type_copy_impl(SHA1object *self, PyTypeObject *cls) /*[clinic end generated code: output=b32d4461ce8bc7a7 input=6c22e66fcc34c58e]*/ { - SHA1State *st = PyType_GetModuleState(cls); + SHA1State *st = _PyType_GetModuleState(cls); SHA1object *newobj; if ((newobj = newSHA1object(st)) == NULL) return NULL; - newobj->hash_state = self->hash_state; + ENTER_HASHLIB(self); + newobj->hash_state = Hacl_Streaming_SHA1_legacy_copy(self->hash_state); + LEAVE_HASHLIB(self); return (PyObject *)newobj; } @@ -372,10 +138,9 @@ SHA1Type_digest_impl(SHA1object *self) /*[clinic end generated code: output=2f05302a7aa2b5cb input=13824b35407444bd]*/ { unsigned char digest[SHA1_DIGESTSIZE]; - struct sha1_state temp; - - temp = self->hash_state; - sha1_done(&temp, digest); + ENTER_HASHLIB(self); + Hacl_Streaming_SHA1_legacy_finish(self->hash_state, digest); + LEAVE_HASHLIB(self); return PyBytes_FromStringAndSize((const char *)digest, SHA1_DIGESTSIZE); } @@ -390,15 +155,23 @@ SHA1Type_hexdigest_impl(SHA1object *self) /*[clinic end generated code: output=4161fd71e68c6659 input=97691055c0c74ab0]*/ { unsigned char digest[SHA1_DIGESTSIZE]; - struct sha1_state temp; - - /* Get the raw (binary) digest value */ - temp = self->hash_state; - sha1_done(&temp, digest); - + ENTER_HASHLIB(self); + Hacl_Streaming_SHA1_legacy_finish(self->hash_state, digest); + LEAVE_HASHLIB(self); return _Py_strhex((const char *)digest, SHA1_DIGESTSIZE); } +static void update(Hacl_Streaming_SHA1_state *state, uint8_t *buf, Py_ssize_t len) { +#if PY_SSIZE_T_MAX > UINT32_MAX + while (len > UINT32_MAX) { + Hacl_Streaming_SHA1_legacy_update(state, buf, UINT32_MAX); + len -= UINT32_MAX; + buf += UINT32_MAX; + } +#endif + Hacl_Streaming_SHA1_legacy_update(state, buf, (uint32_t) len); +} + /*[clinic input] SHA1Type.update @@ -416,7 +189,18 @@ SHA1Type_update(SHA1object *self, PyObject *obj) GET_BUFFER_VIEW_OR_ERROUT(obj, &buf); - sha1_process(&self->hash_state, buf.buf, buf.len); + if (self->lock == NULL && buf.len >= HASHLIB_GIL_MINSIZE) { + self->lock = PyThread_allocate_lock(); + } + if (self->lock != NULL) { + Py_BEGIN_ALLOW_THREADS + PyThread_acquire_lock(self->lock, 1); + update(self->hash_state, buf.buf, buf.len); + PyThread_release_lock(self->lock); + Py_END_ALLOW_THREADS + } else { + update(self->hash_state, buf.buf, buf.len); + } PyBuffer_Release(&buf); Py_RETURN_NONE; @@ -509,7 +293,7 @@ _sha1_sha1_impl(PyObject *module, PyObject *string, int usedforsecurity) return NULL; } - sha1_init(&new->hash_state); + new->hash_state = Hacl_Streaming_SHA1_legacy_create_in(); if (PyErr_Occurred()) { Py_DECREF(new); @@ -518,7 +302,15 @@ _sha1_sha1_impl(PyObject *module, PyObject *string, int usedforsecurity) return NULL; } if (string) { - sha1_process(&new->hash_state, buf.buf, buf.len); + if (buf.len >= HASHLIB_GIL_MINSIZE) { + /* We do not initialize self->lock here as this is the constructor + * where it is not yet possible to have concurrent access. */ + Py_BEGIN_ALLOW_THREADS + update(new->hash_state, buf.buf, buf.len); + Py_END_ALLOW_THREADS + } else { + update(new->hash_state, buf.buf, buf.len); + } PyBuffer_Release(&buf); } @@ -583,6 +375,7 @@ _sha1_exec(PyObject *module) static PyModuleDef_Slot _sha1_slots[] = { {Py_mod_exec, _sha1_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; diff --git a/Modules/sha256module.c b/Modules/sha256module.c deleted file mode 100644 index 17ee8668..00000000 --- a/Modules/sha256module.c +++ /dev/null @@ -1,756 +0,0 @@ -/* SHA256 module */ - -/* This module provides an interface to NIST's SHA-256 and SHA-224 Algorithms */ - -/* See below for information about the original code this module was - based upon. Additional work performed by: - - Andrew Kuchling (amk@amk.ca) - Greg Stein (gstein@lyra.org) - Trevor Perrin (trevp@trevp.net) - - Copyright (C) 2005-2007 Gregory P. Smith (greg@krypto.org) - Licensed to PSF under a Contributor Agreement. - -*/ - -/* SHA objects */ -#ifndef Py_BUILD_CORE_BUILTIN -# define Py_BUILD_CORE_MODULE 1 -#endif - -#include "Python.h" -#include "pycore_bitutils.h" // _Py_bswap32() -#include "pycore_strhex.h" // _Py_strhex() -#include "structmember.h" // PyMemberDef -#include "hashlib.h" - -/*[clinic input] -module _sha256 -class SHA256Type "SHAobject *" "&PyType_Type" -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=71a39174d4f0a744]*/ - -/* Some useful types */ - -typedef unsigned char SHA_BYTE; -typedef uint32_t SHA_INT32; /* 32-bit integer */ - -/* The SHA block size and message digest sizes, in bytes */ - -#define SHA_BLOCKSIZE 64 -#define SHA_DIGESTSIZE 32 - -/* The structure for storing SHA info */ - -typedef struct { - PyObject_HEAD - SHA_INT32 digest[8]; /* Message digest */ - SHA_INT32 count_lo, count_hi; /* 64-bit bit count */ - SHA_BYTE data[SHA_BLOCKSIZE]; /* SHA data buffer */ - int local; /* unprocessed amount in data */ - int digestsize; -} SHAobject; - -#include "clinic/sha256module.c.h" - -typedef struct { - PyTypeObject* sha224_type; - PyTypeObject* sha256_type; -} _sha256_state; - -static inline _sha256_state* -_sha256_get_state(PyObject *module) -{ - void *state = PyModule_GetState(module); - assert(state != NULL); - return (_sha256_state *)state; -} - -/* When run on a little-endian CPU we need to perform byte reversal on an - array of longwords. */ - -#if PY_LITTLE_ENDIAN -static void longReverse(SHA_INT32 *buffer, int byteCount) -{ - byteCount /= sizeof(*buffer); - for (; byteCount--; buffer++) { - *buffer = _Py_bswap32(*buffer); - } -} -#endif - -static void SHAcopy(SHAobject *src, SHAobject *dest) -{ - dest->local = src->local; - dest->digestsize = src->digestsize; - dest->count_lo = src->count_lo; - dest->count_hi = src->count_hi; - memcpy(dest->digest, src->digest, sizeof(src->digest)); - memcpy(dest->data, src->data, sizeof(src->data)); -} - - -/* ------------------------------------------------------------------------ - * - * This code for the SHA-256 algorithm was noted as public domain. The - * original headers are pasted below. - * - * Several changes have been made to make it more compatible with the - * Python environment and desired interface. - * - */ - -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@iahu.ca, https://www.libtom.net - */ - - -/* SHA256 by Tom St Denis */ - -/* Various logical functions */ -#define ROR(x, y)\ -( ((((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)((y)&31)) | \ -((unsigned long)(x)<<(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL) -#define Ch(x,y,z) (z ^ (x & (y ^ z))) -#define Maj(x,y,z) (((x | y) & z) | (x & y)) -#define S(x, n) ROR((x),(n)) -#define R(x, n) (((x)&0xFFFFFFFFUL)>>(n)) -#define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22)) -#define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25)) -#define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3)) -#define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10)) - - -static void -sha_transform(SHAobject *sha_info) -{ - int i; - SHA_INT32 S[8], W[64], t0, t1; - - memcpy(W, sha_info->data, sizeof(sha_info->data)); -#if PY_LITTLE_ENDIAN - longReverse(W, (int)sizeof(sha_info->data)); -#endif - - for (i = 16; i < 64; ++i) { - W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16]; - } - for (i = 0; i < 8; ++i) { - S[i] = sha_info->digest[i]; - } - - /* Compress */ -#define RND(a,b,c,d,e,f,g,h,i,ki) \ - t0 = h + Sigma1(e) + Ch(e, f, g) + ki + W[i]; \ - t1 = Sigma0(a) + Maj(a, b, c); \ - d += t0; \ - h = t0 + t1; - - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],0,0x428a2f98); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],1,0x71374491); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],2,0xb5c0fbcf); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],3,0xe9b5dba5); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],4,0x3956c25b); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],5,0x59f111f1); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],6,0x923f82a4); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],7,0xab1c5ed5); - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],8,0xd807aa98); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],9,0x12835b01); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],10,0x243185be); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],11,0x550c7dc3); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],12,0x72be5d74); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],13,0x80deb1fe); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],14,0x9bdc06a7); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],15,0xc19bf174); - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],16,0xe49b69c1); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],17,0xefbe4786); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],18,0x0fc19dc6); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],19,0x240ca1cc); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],20,0x2de92c6f); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],21,0x4a7484aa); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],22,0x5cb0a9dc); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],23,0x76f988da); - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],24,0x983e5152); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],25,0xa831c66d); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],26,0xb00327c8); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],27,0xbf597fc7); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],28,0xc6e00bf3); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],29,0xd5a79147); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],30,0x06ca6351); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],31,0x14292967); - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],32,0x27b70a85); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],33,0x2e1b2138); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],34,0x4d2c6dfc); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],35,0x53380d13); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],36,0x650a7354); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],37,0x766a0abb); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],38,0x81c2c92e); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],39,0x92722c85); - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],40,0xa2bfe8a1); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],41,0xa81a664b); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],42,0xc24b8b70); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],43,0xc76c51a3); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],44,0xd192e819); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],45,0xd6990624); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],46,0xf40e3585); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],47,0x106aa070); - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],48,0x19a4c116); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],49,0x1e376c08); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],50,0x2748774c); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],51,0x34b0bcb5); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],52,0x391c0cb3); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],53,0x4ed8aa4a); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],54,0x5b9cca4f); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],55,0x682e6ff3); - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],56,0x748f82ee); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],57,0x78a5636f); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],58,0x84c87814); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],59,0x8cc70208); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],60,0x90befffa); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],61,0xa4506ceb); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],62,0xbef9a3f7); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],63,0xc67178f2); - -#undef RND - - /* feedback */ - for (i = 0; i < 8; i++) { - sha_info->digest[i] = sha_info->digest[i] + S[i]; - } - -} - - - -/* initialize the SHA digest */ - -static void -sha_init(SHAobject *sha_info) -{ - sha_info->digest[0] = 0x6A09E667L; - sha_info->digest[1] = 0xBB67AE85L; - sha_info->digest[2] = 0x3C6EF372L; - sha_info->digest[3] = 0xA54FF53AL; - sha_info->digest[4] = 0x510E527FL; - sha_info->digest[5] = 0x9B05688CL; - sha_info->digest[6] = 0x1F83D9ABL; - sha_info->digest[7] = 0x5BE0CD19L; - sha_info->count_lo = 0L; - sha_info->count_hi = 0L; - sha_info->local = 0; - sha_info->digestsize = 32; -} - -static void -sha224_init(SHAobject *sha_info) -{ - sha_info->digest[0] = 0xc1059ed8L; - sha_info->digest[1] = 0x367cd507L; - sha_info->digest[2] = 0x3070dd17L; - sha_info->digest[3] = 0xf70e5939L; - sha_info->digest[4] = 0xffc00b31L; - sha_info->digest[5] = 0x68581511L; - sha_info->digest[6] = 0x64f98fa7L; - sha_info->digest[7] = 0xbefa4fa4L; - sha_info->count_lo = 0L; - sha_info->count_hi = 0L; - sha_info->local = 0; - sha_info->digestsize = 28; -} - - -/* update the SHA digest */ - -static void -sha_update(SHAobject *sha_info, SHA_BYTE *buffer, Py_ssize_t count) -{ - Py_ssize_t i; - SHA_INT32 clo; - - clo = sha_info->count_lo + ((SHA_INT32) count << 3); - if (clo < sha_info->count_lo) { - ++sha_info->count_hi; - } - sha_info->count_lo = clo; - sha_info->count_hi += (SHA_INT32) count >> 29; - if (sha_info->local) { - i = SHA_BLOCKSIZE - sha_info->local; - if (i > count) { - i = count; - } - memcpy(((SHA_BYTE *) sha_info->data) + sha_info->local, buffer, i); - count -= i; - buffer += i; - sha_info->local += (int)i; - if (sha_info->local == SHA_BLOCKSIZE) { - sha_transform(sha_info); - } - else { - return; - } - } - while (count >= SHA_BLOCKSIZE) { - memcpy(sha_info->data, buffer, SHA_BLOCKSIZE); - buffer += SHA_BLOCKSIZE; - count -= SHA_BLOCKSIZE; - sha_transform(sha_info); - } - memcpy(sha_info->data, buffer, count); - sha_info->local = (int)count; -} - -/* finish computing the SHA digest */ - -static void -sha_final(unsigned char digest[SHA_DIGESTSIZE], SHAobject *sha_info) -{ - int count; - SHA_INT32 lo_bit_count, hi_bit_count; - - lo_bit_count = sha_info->count_lo; - hi_bit_count = sha_info->count_hi; - count = (int) ((lo_bit_count >> 3) & 0x3f); - ((SHA_BYTE *) sha_info->data)[count++] = 0x80; - if (count > SHA_BLOCKSIZE - 8) { - memset(((SHA_BYTE *) sha_info->data) + count, 0, - SHA_BLOCKSIZE - count); - sha_transform(sha_info); - memset((SHA_BYTE *) sha_info->data, 0, SHA_BLOCKSIZE - 8); - } - else { - memset(((SHA_BYTE *) sha_info->data) + count, 0, - SHA_BLOCKSIZE - 8 - count); - } - - /* GJS: note that we add the hi/lo in big-endian. sha_transform will - swap these values into host-order. */ - sha_info->data[56] = (hi_bit_count >> 24) & 0xff; - sha_info->data[57] = (hi_bit_count >> 16) & 0xff; - sha_info->data[58] = (hi_bit_count >> 8) & 0xff; - sha_info->data[59] = (hi_bit_count >> 0) & 0xff; - sha_info->data[60] = (lo_bit_count >> 24) & 0xff; - sha_info->data[61] = (lo_bit_count >> 16) & 0xff; - sha_info->data[62] = (lo_bit_count >> 8) & 0xff; - sha_info->data[63] = (lo_bit_count >> 0) & 0xff; - sha_transform(sha_info); - digest[ 0] = (unsigned char) ((sha_info->digest[0] >> 24) & 0xff); - digest[ 1] = (unsigned char) ((sha_info->digest[0] >> 16) & 0xff); - digest[ 2] = (unsigned char) ((sha_info->digest[0] >> 8) & 0xff); - digest[ 3] = (unsigned char) ((sha_info->digest[0] ) & 0xff); - digest[ 4] = (unsigned char) ((sha_info->digest[1] >> 24) & 0xff); - digest[ 5] = (unsigned char) ((sha_info->digest[1] >> 16) & 0xff); - digest[ 6] = (unsigned char) ((sha_info->digest[1] >> 8) & 0xff); - digest[ 7] = (unsigned char) ((sha_info->digest[1] ) & 0xff); - digest[ 8] = (unsigned char) ((sha_info->digest[2] >> 24) & 0xff); - digest[ 9] = (unsigned char) ((sha_info->digest[2] >> 16) & 0xff); - digest[10] = (unsigned char) ((sha_info->digest[2] >> 8) & 0xff); - digest[11] = (unsigned char) ((sha_info->digest[2] ) & 0xff); - digest[12] = (unsigned char) ((sha_info->digest[3] >> 24) & 0xff); - digest[13] = (unsigned char) ((sha_info->digest[3] >> 16) & 0xff); - digest[14] = (unsigned char) ((sha_info->digest[3] >> 8) & 0xff); - digest[15] = (unsigned char) ((sha_info->digest[3] ) & 0xff); - digest[16] = (unsigned char) ((sha_info->digest[4] >> 24) & 0xff); - digest[17] = (unsigned char) ((sha_info->digest[4] >> 16) & 0xff); - digest[18] = (unsigned char) ((sha_info->digest[4] >> 8) & 0xff); - digest[19] = (unsigned char) ((sha_info->digest[4] ) & 0xff); - digest[20] = (unsigned char) ((sha_info->digest[5] >> 24) & 0xff); - digest[21] = (unsigned char) ((sha_info->digest[5] >> 16) & 0xff); - digest[22] = (unsigned char) ((sha_info->digest[5] >> 8) & 0xff); - digest[23] = (unsigned char) ((sha_info->digest[5] ) & 0xff); - digest[24] = (unsigned char) ((sha_info->digest[6] >> 24) & 0xff); - digest[25] = (unsigned char) ((sha_info->digest[6] >> 16) & 0xff); - digest[26] = (unsigned char) ((sha_info->digest[6] >> 8) & 0xff); - digest[27] = (unsigned char) ((sha_info->digest[6] ) & 0xff); - digest[28] = (unsigned char) ((sha_info->digest[7] >> 24) & 0xff); - digest[29] = (unsigned char) ((sha_info->digest[7] >> 16) & 0xff); - digest[30] = (unsigned char) ((sha_info->digest[7] >> 8) & 0xff); - digest[31] = (unsigned char) ((sha_info->digest[7] ) & 0xff); -} - -/* - * End of copied SHA code. - * - * ------------------------------------------------------------------------ - */ - - -static SHAobject * -newSHA224object(_sha256_state *state) -{ - SHAobject *sha = (SHAobject *)PyObject_GC_New(SHAobject, - state->sha224_type); - PyObject_GC_Track(sha); - return sha; -} - -static SHAobject * -newSHA256object(_sha256_state *state) -{ - SHAobject *sha = (SHAobject *)PyObject_GC_New(SHAobject, - state->sha256_type); - PyObject_GC_Track(sha); - return sha; -} - -/* Internal methods for a hash object */ -static int -SHA_traverse(PyObject *ptr, visitproc visit, void *arg) -{ - Py_VISIT(Py_TYPE(ptr)); - return 0; -} - -static void -SHA_dealloc(PyObject *ptr) -{ - PyTypeObject *tp = Py_TYPE(ptr); - PyObject_GC_UnTrack(ptr); - PyObject_GC_Del(ptr); - Py_DECREF(tp); -} - - -/* External methods for a hash object */ - -/*[clinic input] -SHA256Type.copy - - cls:defining_class - -Return a copy of the hash object. -[clinic start generated code]*/ - -static PyObject * -SHA256Type_copy_impl(SHAobject *self, PyTypeObject *cls) -/*[clinic end generated code: output=9273f92c382be12f input=3137146fcb88e212]*/ -{ - SHAobject *newobj; - _sha256_state *state = PyType_GetModuleState(cls); - if (Py_IS_TYPE(self, state->sha256_type)) { - if ( (newobj = newSHA256object(state)) == NULL) { - return NULL; - } - } else { - if ( (newobj = newSHA224object(state))==NULL) { - return NULL; - } - } - - SHAcopy(self, newobj); - return (PyObject *)newobj; -} - -/*[clinic input] -SHA256Type.digest - -Return the digest value as a bytes object. -[clinic start generated code]*/ - -static PyObject * -SHA256Type_digest_impl(SHAobject *self) -/*[clinic end generated code: output=46616a5e909fbc3d input=f1f4cfea5cbde35c]*/ -{ - unsigned char digest[SHA_DIGESTSIZE]; - SHAobject temp; - - SHAcopy(self, &temp); - sha_final(digest, &temp); - return PyBytes_FromStringAndSize((const char *)digest, self->digestsize); -} - -/*[clinic input] -SHA256Type.hexdigest - -Return the digest value as a string of hexadecimal digits. -[clinic start generated code]*/ - -static PyObject * -SHA256Type_hexdigest_impl(SHAobject *self) -/*[clinic end generated code: output=725f8a7041ae97f3 input=0cc4c714693010d1]*/ -{ - unsigned char digest[SHA_DIGESTSIZE]; - SHAobject temp; - - /* Get the raw (binary) digest value */ - SHAcopy(self, &temp); - sha_final(digest, &temp); - - return _Py_strhex((const char *)digest, self->digestsize); -} - -/*[clinic input] -SHA256Type.update - - obj: object - / - -Update this hash object's state with the provided string. -[clinic start generated code]*/ - -static PyObject * -SHA256Type_update(SHAobject *self, PyObject *obj) -/*[clinic end generated code: output=0967fb2860c66af7 input=b2d449d5b30f0f5a]*/ -{ - Py_buffer buf; - - GET_BUFFER_VIEW_OR_ERROUT(obj, &buf); - - sha_update(self, buf.buf, buf.len); - - PyBuffer_Release(&buf); - Py_RETURN_NONE; -} - -static PyMethodDef SHA_methods[] = { - SHA256TYPE_COPY_METHODDEF - SHA256TYPE_DIGEST_METHODDEF - SHA256TYPE_HEXDIGEST_METHODDEF - SHA256TYPE_UPDATE_METHODDEF - {NULL, NULL} /* sentinel */ -}; - -static PyObject * -SHA256_get_block_size(PyObject *self, void *closure) -{ - return PyLong_FromLong(SHA_BLOCKSIZE); -} - -static PyObject * -SHA256_get_name(PyObject *self, void *closure) -{ - if (((SHAobject *)self)->digestsize == 32) - return PyUnicode_FromStringAndSize("sha256", 6); - else - return PyUnicode_FromStringAndSize("sha224", 6); -} - -static PyGetSetDef SHA_getseters[] = { - {"block_size", - (getter)SHA256_get_block_size, NULL, - NULL, - NULL}, - {"name", - (getter)SHA256_get_name, NULL, - NULL, - NULL}, - {NULL} /* Sentinel */ -}; - -static PyMemberDef SHA_members[] = { - {"digest_size", T_INT, offsetof(SHAobject, digestsize), READONLY, NULL}, - {NULL} /* Sentinel */ -}; - -static PyType_Slot sha256_types_slots[] = { - {Py_tp_dealloc, SHA_dealloc}, - {Py_tp_methods, SHA_methods}, - {Py_tp_members, SHA_members}, - {Py_tp_getset, SHA_getseters}, - {Py_tp_traverse, SHA_traverse}, - {0,0} -}; - -static PyType_Spec sha224_type_spec = { - .name = "_sha256.sha224", - .basicsize = sizeof(SHAobject), - .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION | - Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_HAVE_GC), - .slots = sha256_types_slots -}; - -static PyType_Spec sha256_type_spec = { - .name = "_sha256.sha256", - .basicsize = sizeof(SHAobject), - .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION | - Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_HAVE_GC), - .slots = sha256_types_slots -}; - -/* The single module-level function: new() */ - -/*[clinic input] -_sha256.sha256 - - string: object(c_default="NULL") = b'' - * - usedforsecurity: bool = True - -Return a new SHA-256 hash object; optionally initialized with a string. -[clinic start generated code]*/ - -static PyObject * -_sha256_sha256_impl(PyObject *module, PyObject *string, int usedforsecurity) -/*[clinic end generated code: output=a1de327e8e1185cf input=9be86301aeb14ea5]*/ -{ - Py_buffer buf; - - if (string) { - GET_BUFFER_VIEW_OR_ERROUT(string, &buf); - } - - _sha256_state *state = PyModule_GetState(module); - - SHAobject *new; - if ((new = newSHA256object(state)) == NULL) { - if (string) { - PyBuffer_Release(&buf); - } - return NULL; - } - - sha_init(new); - - if (PyErr_Occurred()) { - Py_DECREF(new); - if (string) { - PyBuffer_Release(&buf); - } - return NULL; - } - if (string) { - sha_update(new, buf.buf, buf.len); - PyBuffer_Release(&buf); - } - - return (PyObject *)new; -} - -/*[clinic input] -_sha256.sha224 - - string: object(c_default="NULL") = b'' - * - usedforsecurity: bool = True - -Return a new SHA-224 hash object; optionally initialized with a string. -[clinic start generated code]*/ - -static PyObject * -_sha256_sha224_impl(PyObject *module, PyObject *string, int usedforsecurity) -/*[clinic end generated code: output=08be6b36569bc69c input=9fcfb46e460860ac]*/ -{ - Py_buffer buf; - if (string) { - GET_BUFFER_VIEW_OR_ERROUT(string, &buf); - } - - _sha256_state *state = PyModule_GetState(module); - SHAobject *new; - if ((new = newSHA224object(state)) == NULL) { - if (string) { - PyBuffer_Release(&buf); - } - return NULL; - } - - sha224_init(new); - - if (PyErr_Occurred()) { - Py_DECREF(new); - if (string) { - PyBuffer_Release(&buf); - } - return NULL; - } - if (string) { - sha_update(new, buf.buf, buf.len); - PyBuffer_Release(&buf); - } - - return (PyObject *)new; -} - - -/* List of functions exported by this module */ - -static struct PyMethodDef SHA_functions[] = { - _SHA256_SHA256_METHODDEF - _SHA256_SHA224_METHODDEF - {NULL, NULL} /* Sentinel */ -}; - -static int -_sha256_traverse(PyObject *module, visitproc visit, void *arg) -{ - _sha256_state *state = _sha256_get_state(module); - Py_VISIT(state->sha224_type); - Py_VISIT(state->sha256_type); - return 0; -} - -static int -_sha256_clear(PyObject *module) -{ - _sha256_state *state = _sha256_get_state(module); - Py_CLEAR(state->sha224_type); - Py_CLEAR(state->sha256_type); - return 0; -} - -static void -_sha256_free(void *module) -{ - _sha256_clear((PyObject *)module); -} - -static int sha256_exec(PyObject *module) -{ - _sha256_state *state = _sha256_get_state(module); - - state->sha224_type = (PyTypeObject *)PyType_FromModuleAndSpec( - module, &sha224_type_spec, NULL); - - if (state->sha224_type == NULL) { - return -1; - } - - state->sha256_type = (PyTypeObject *)PyType_FromModuleAndSpec( - module, &sha256_type_spec, NULL); - - if (state->sha256_type == NULL) { - return -1; - } - - Py_INCREF((PyObject *)state->sha224_type); - if (PyModule_AddObject(module, "SHA224Type", (PyObject *)state->sha224_type) < 0) { - Py_DECREF((PyObject *)state->sha224_type); - return -1; - } - Py_INCREF((PyObject *)state->sha256_type); - if (PyModule_AddObject(module, "SHA256Type", (PyObject *)state->sha256_type) < 0) { - Py_DECREF((PyObject *)state->sha256_type); - return -1; - } - return 0; -} - -static PyModuleDef_Slot _sha256_slots[] = { - {Py_mod_exec, sha256_exec}, - {0, NULL} -}; - -static struct PyModuleDef _sha256module = { - PyModuleDef_HEAD_INIT, - .m_name = "_sha256", - .m_size = sizeof(_sha256_state), - .m_methods = SHA_functions, - .m_slots = _sha256_slots, - .m_traverse = _sha256_traverse, - .m_clear = _sha256_clear, - .m_free = _sha256_free -}; - -/* Initialize this module. */ -PyMODINIT_FUNC -PyInit__sha256(void) -{ - return PyModuleDef_Init(&_sha256module); -} diff --git a/Modules/sha2module.c b/Modules/sha2module.c new file mode 100644 index 00000000..db3774c8 --- /dev/null +++ b/Modules/sha2module.c @@ -0,0 +1,889 @@ +/* SHA2 module */ + +/* This provides an interface to NIST's SHA2 224, 256, 384, & 512 Algorithms */ + +/* See below for information about the original code this module was + based upon. Additional work performed by: + + Andrew Kuchling (amk@amk.ca) + Greg Stein (gstein@lyra.org) + Trevor Perrin (trevp@trevp.net) + Jonathan Protzenko (jonathan@protzenko.fr) + + Copyright (C) 2005-2007 Gregory P. Smith (greg@krypto.org) + Licensed to PSF under a Contributor Agreement. + +*/ + +/* SHA objects */ +#ifndef Py_BUILD_CORE_BUILTIN +# define Py_BUILD_CORE_MODULE 1 +#endif + +#include "Python.h" +#include "pycore_bitutils.h" // _Py_bswap32() +#include "pycore_moduleobject.h" // _PyModule_GetState() +#include "pycore_typeobject.h" // _PyType_GetModuleState() +#include "pycore_strhex.h" // _Py_strhex() +#include "structmember.h" // PyMemberDef +#include "hashlib.h" + +/*[clinic input] +module _sha2 +class SHA256Type "SHA256object *" "&PyType_Type" +class SHA512Type "SHA512object *" "&PyType_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=b5315a7b611c9afc]*/ + + +/* The SHA block sizes and maximum message digest sizes, in bytes */ + +#define SHA256_BLOCKSIZE 64 +#define SHA256_DIGESTSIZE 32 +#define SHA512_BLOCKSIZE 128 +#define SHA512_DIGESTSIZE 64 + +/* Our SHA2 implementations defer to the HACL* verified library. */ + +#include "_hacl/Hacl_Hash_SHA2.h" + +// TODO: Get rid of int digestsize in favor of Hacl state info? + +typedef struct { + PyObject_HEAD + int digestsize; + // Prevents undefined behavior via multiple threads entering the C API. + // The lock will be NULL before threaded access has been enabled. + PyThread_type_lock lock; + Hacl_Streaming_SHA2_state_sha2_256 *state; +} SHA256object; + +typedef struct { + PyObject_HEAD + int digestsize; + // Prevents undefined behavior via multiple threads entering the C API. + // The lock will be NULL before threaded access has been enabled. + PyThread_type_lock lock; + Hacl_Streaming_SHA2_state_sha2_512 *state; +} SHA512object; + +#include "clinic/sha2module.c.h" + +/* We shall use run-time type information in the remainder of this module to + * tell apart SHA2-224 and SHA2-256 */ +typedef struct { + PyTypeObject* sha224_type; + PyTypeObject* sha256_type; + PyTypeObject* sha384_type; + PyTypeObject* sha512_type; +} sha2_state; + +static inline sha2_state* +sha2_get_state(PyObject *module) +{ + void *state = _PyModule_GetState(module); + assert(state != NULL); + return (sha2_state *)state; +} + +static void SHA256copy(SHA256object *src, SHA256object *dest) +{ + dest->digestsize = src->digestsize; + dest->state = Hacl_Streaming_SHA2_copy_256(src->state); +} + +static void SHA512copy(SHA512object *src, SHA512object *dest) +{ + dest->digestsize = src->digestsize; + dest->state = Hacl_Streaming_SHA2_copy_512(src->state); +} + +static SHA256object * +newSHA224object(sha2_state *state) +{ + SHA256object *sha = (SHA256object *)PyObject_GC_New( + SHA256object, state->sha224_type); + if (!sha) { + return NULL; + } + sha->lock = NULL; + PyObject_GC_Track(sha); + return sha; +} + +static SHA256object * +newSHA256object(sha2_state *state) +{ + SHA256object *sha = (SHA256object *)PyObject_GC_New( + SHA256object, state->sha256_type); + if (!sha) { + return NULL; + } + sha->lock = NULL; + PyObject_GC_Track(sha); + return sha; +} + +static SHA512object * +newSHA384object(sha2_state *state) +{ + SHA512object *sha = (SHA512object *)PyObject_GC_New( + SHA512object, state->sha384_type); + if (!sha) { + return NULL; + } + sha->lock = NULL; + PyObject_GC_Track(sha); + return sha; +} + +static SHA512object * +newSHA512object(sha2_state *state) +{ + SHA512object *sha = (SHA512object *)PyObject_GC_New( + SHA512object, state->sha512_type); + if (!sha) { + return NULL; + } + sha->lock = NULL; + PyObject_GC_Track(sha); + return sha; +} + +/* Internal methods for our hash objects. */ + +static int +SHA2_traverse(PyObject *ptr, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(ptr)); + return 0; +} + +static void +SHA256_dealloc(SHA256object *ptr) +{ + Hacl_Streaming_SHA2_free_256(ptr->state); + if (ptr->lock != NULL) { + PyThread_free_lock(ptr->lock); + } + PyTypeObject *tp = Py_TYPE(ptr); + PyObject_GC_UnTrack(ptr); + PyObject_GC_Del(ptr); + Py_DECREF(tp); +} + +static void +SHA512_dealloc(SHA512object *ptr) +{ + Hacl_Streaming_SHA2_free_512(ptr->state); + if (ptr->lock != NULL) { + PyThread_free_lock(ptr->lock); + } + PyTypeObject *tp = Py_TYPE(ptr); + PyObject_GC_UnTrack(ptr); + PyObject_GC_Del(ptr); + Py_DECREF(tp); +} + +/* HACL* takes a uint32_t for the length of its parameter, but Py_ssize_t can be + * 64 bits so we loop in <4gig chunks when needed. */ + +static void update_256(Hacl_Streaming_SHA2_state_sha2_256 *state, uint8_t *buf, Py_ssize_t len) { + /* Note: we explicitly ignore the error code on the basis that it would take > + * 1 billion years to overflow the maximum admissible length for SHA2-256 + * (namely, 2^61-1 bytes). */ +#if PY_SSIZE_T_MAX > UINT32_MAX + while (len > UINT32_MAX) { + Hacl_Streaming_SHA2_update_256(state, buf, UINT32_MAX); + len -= UINT32_MAX; + buf += UINT32_MAX; + } +#endif + /* Cast to uint32_t is safe: len <= UINT32_MAX at this point. */ + Hacl_Streaming_SHA2_update_256(state, buf, (uint32_t) len); +} + +static void update_512(Hacl_Streaming_SHA2_state_sha2_512 *state, uint8_t *buf, Py_ssize_t len) { + /* Note: we explicitly ignore the error code on the basis that it would take > + * 1 billion years to overflow the maximum admissible length for this API + * (namely, 2^64-1 bytes). */ +#if PY_SSIZE_T_MAX > UINT32_MAX + while (len > UINT32_MAX) { + Hacl_Streaming_SHA2_update_512(state, buf, UINT32_MAX); + len -= UINT32_MAX; + buf += UINT32_MAX; + } +#endif + /* Cast to uint32_t is safe: len <= UINT32_MAX at this point. */ + Hacl_Streaming_SHA2_update_512(state, buf, (uint32_t) len); +} + + +/* External methods for our hash objects */ + +/*[clinic input] +SHA256Type.copy + + cls:defining_class + +Return a copy of the hash object. +[clinic start generated code]*/ + +static PyObject * +SHA256Type_copy_impl(SHA256object *self, PyTypeObject *cls) +/*[clinic end generated code: output=fabd515577805cd3 input=3137146fcb88e212]*/ +{ + SHA256object *newobj; + sha2_state *state = _PyType_GetModuleState(cls); + if (Py_IS_TYPE(self, state->sha256_type)) { + if ((newobj = newSHA256object(state)) == NULL) { + return NULL; + } + } else { + if ((newobj = newSHA224object(state)) == NULL) { + return NULL; + } + } + + ENTER_HASHLIB(self); + SHA256copy(self, newobj); + LEAVE_HASHLIB(self); + return (PyObject *)newobj; +} + +/*[clinic input] +SHA512Type.copy + + cls: defining_class + +Return a copy of the hash object. +[clinic start generated code]*/ + +static PyObject * +SHA512Type_copy_impl(SHA512object *self, PyTypeObject *cls) +/*[clinic end generated code: output=66d2a8ef20de8302 input=f673a18f66527c90]*/ +{ + SHA512object *newobj; + sha2_state *state = _PyType_GetModuleState(cls); + + if (Py_IS_TYPE((PyObject*)self, state->sha512_type)) { + if ((newobj = newSHA512object(state)) == NULL) { + return NULL; + } + } + else { + if ((newobj = newSHA384object(state)) == NULL) { + return NULL; + } + } + + ENTER_HASHLIB(self); + SHA512copy(self, newobj); + LEAVE_HASHLIB(self); + return (PyObject *)newobj; +} + +/*[clinic input] +SHA256Type.digest + +Return the digest value as a bytes object. +[clinic start generated code]*/ + +static PyObject * +SHA256Type_digest_impl(SHA256object *self) +/*[clinic end generated code: output=3a2e3997a98ee792 input=f1f4cfea5cbde35c]*/ +{ + uint8_t digest[SHA256_DIGESTSIZE]; + assert(self->digestsize <= SHA256_DIGESTSIZE); + ENTER_HASHLIB(self); + // HACL* performs copies under the hood so that self->state remains valid + // after this call. + Hacl_Streaming_SHA2_finish_256(self->state, digest); + LEAVE_HASHLIB(self); + return PyBytes_FromStringAndSize((const char *)digest, self->digestsize); +} + +/*[clinic input] +SHA512Type.digest + +Return the digest value as a bytes object. +[clinic start generated code]*/ + +static PyObject * +SHA512Type_digest_impl(SHA512object *self) +/*[clinic end generated code: output=dd8c6320070458e0 input=f6470dd359071f4b]*/ +{ + uint8_t digest[SHA512_DIGESTSIZE]; + assert(self->digestsize <= SHA512_DIGESTSIZE); + ENTER_HASHLIB(self); + // HACL* performs copies under the hood so that self->state remains valid + // after this call. + Hacl_Streaming_SHA2_finish_512(self->state, digest); + LEAVE_HASHLIB(self); + return PyBytes_FromStringAndSize((const char *)digest, self->digestsize); +} + +/*[clinic input] +SHA256Type.hexdigest + +Return the digest value as a string of hexadecimal digits. +[clinic start generated code]*/ + +static PyObject * +SHA256Type_hexdigest_impl(SHA256object *self) +/*[clinic end generated code: output=96cb68996a780ab3 input=0cc4c714693010d1]*/ +{ + uint8_t digest[SHA256_DIGESTSIZE]; + assert(self->digestsize <= SHA256_DIGESTSIZE); + ENTER_HASHLIB(self); + Hacl_Streaming_SHA2_finish_256(self->state, digest); + LEAVE_HASHLIB(self); + return _Py_strhex((const char *)digest, self->digestsize); +} + +/*[clinic input] +SHA512Type.hexdigest + +Return the digest value as a string of hexadecimal digits. +[clinic start generated code]*/ + +static PyObject * +SHA512Type_hexdigest_impl(SHA512object *self) +/*[clinic end generated code: output=cbd6f844aba1fe7c input=498b877b25cbe0a2]*/ +{ + uint8_t digest[SHA512_DIGESTSIZE]; + assert(self->digestsize <= SHA512_DIGESTSIZE); + ENTER_HASHLIB(self); + Hacl_Streaming_SHA2_finish_512(self->state, digest); + LEAVE_HASHLIB(self); + return _Py_strhex((const char *)digest, self->digestsize); +} + +/*[clinic input] +SHA256Type.update + + obj: object + / + +Update this hash object's state with the provided string. +[clinic start generated code]*/ + +static PyObject * +SHA256Type_update(SHA256object *self, PyObject *obj) +/*[clinic end generated code: output=1b240f965ddbd8c6 input=b2d449d5b30f0f5a]*/ +{ + Py_buffer buf; + + GET_BUFFER_VIEW_OR_ERROUT(obj, &buf); + + if (self->lock == NULL && buf.len >= HASHLIB_GIL_MINSIZE) { + self->lock = PyThread_allocate_lock(); + } + if (self->lock != NULL) { + Py_BEGIN_ALLOW_THREADS + PyThread_acquire_lock(self->lock, 1); + update_256(self->state, buf.buf, buf.len); + PyThread_release_lock(self->lock); + Py_END_ALLOW_THREADS + } else { + update_256(self->state, buf.buf, buf.len); + } + + PyBuffer_Release(&buf); + Py_RETURN_NONE; +} + +/*[clinic input] +SHA512Type.update + + obj: object + / + +Update this hash object's state with the provided string. +[clinic start generated code]*/ + +static PyObject * +SHA512Type_update(SHA512object *self, PyObject *obj) +/*[clinic end generated code: output=745f51057a985884 input=ded2b46656566283]*/ +{ + Py_buffer buf; + + GET_BUFFER_VIEW_OR_ERROUT(obj, &buf); + + if (self->lock == NULL && buf.len >= HASHLIB_GIL_MINSIZE) { + self->lock = PyThread_allocate_lock(); + } + if (self->lock != NULL) { + Py_BEGIN_ALLOW_THREADS + PyThread_acquire_lock(self->lock, 1); + update_512(self->state, buf.buf, buf.len); + PyThread_release_lock(self->lock); + Py_END_ALLOW_THREADS + } else { + update_512(self->state, buf.buf, buf.len); + } + + PyBuffer_Release(&buf); + Py_RETURN_NONE; +} + +static PyMethodDef SHA256_methods[] = { + SHA256TYPE_COPY_METHODDEF + SHA256TYPE_DIGEST_METHODDEF + SHA256TYPE_HEXDIGEST_METHODDEF + SHA256TYPE_UPDATE_METHODDEF + {NULL, NULL} /* sentinel */ +}; + +static PyMethodDef SHA512_methods[] = { + SHA512TYPE_COPY_METHODDEF + SHA512TYPE_DIGEST_METHODDEF + SHA512TYPE_HEXDIGEST_METHODDEF + SHA512TYPE_UPDATE_METHODDEF + {NULL, NULL} /* sentinel */ +}; + +static PyObject * +SHA256_get_block_size(PyObject *self, void *closure) +{ + return PyLong_FromLong(SHA256_BLOCKSIZE); +} + +static PyObject * +SHA512_get_block_size(PyObject *self, void *closure) +{ + return PyLong_FromLong(SHA512_BLOCKSIZE); +} + +static PyObject * +SHA256_get_digest_size(SHA256object *self, void *closure) +{ + return PyLong_FromLong(self->digestsize); +} + +static PyObject * +SHA512_get_digest_size(SHA512object *self, void *closure) +{ + return PyLong_FromLong(self->digestsize); +} + +static PyObject * +SHA256_get_name(SHA256object *self, void *closure) +{ + if (self->digestsize == 28) { + return PyUnicode_FromStringAndSize("sha224", 6); + } + return PyUnicode_FromStringAndSize("sha256", 6); +} + +static PyObject * +SHA512_get_name(SHA512object *self, void *closure) +{ + if (self->digestsize == 64) { + return PyUnicode_FromStringAndSize("sha512", 6); + } + return PyUnicode_FromStringAndSize("sha384", 6); +} + +static PyGetSetDef SHA256_getseters[] = { + {"block_size", + (getter)SHA256_get_block_size, NULL, + NULL, + NULL}, + {"name", + (getter)SHA256_get_name, NULL, + NULL, + NULL}, + {"digest_size", + (getter)SHA256_get_digest_size, NULL, + NULL, + NULL}, + {NULL} /* Sentinel */ +}; + +static PyGetSetDef SHA512_getseters[] = { + {"block_size", + (getter)SHA512_get_block_size, NULL, + NULL, + NULL}, + {"name", + (getter)SHA512_get_name, NULL, + NULL, + NULL}, + {"digest_size", + (getter)SHA512_get_digest_size, NULL, + NULL, + NULL}, + {NULL} /* Sentinel */ +}; + +static PyType_Slot sha256_types_slots[] = { + {Py_tp_dealloc, SHA256_dealloc}, + {Py_tp_methods, SHA256_methods}, + {Py_tp_getset, SHA256_getseters}, + {Py_tp_traverse, SHA2_traverse}, + {0,0} +}; + +static PyType_Slot sha512_type_slots[] = { + {Py_tp_dealloc, SHA512_dealloc}, + {Py_tp_methods, SHA512_methods}, + {Py_tp_getset, SHA512_getseters}, + {Py_tp_traverse, SHA2_traverse}, + {0,0} +}; + +// Using _PyType_GetModuleState() on these types is safe since they +// cannot be subclassed: they don't have the Py_TPFLAGS_BASETYPE flag. +static PyType_Spec sha224_type_spec = { + .name = "_sha2.SHA224Type", + .basicsize = sizeof(SHA256object), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION | + Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_HAVE_GC), + .slots = sha256_types_slots +}; + +static PyType_Spec sha256_type_spec = { + .name = "_sha2.SHA256Type", + .basicsize = sizeof(SHA256object), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION | + Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_HAVE_GC), + .slots = sha256_types_slots +}; + +static PyType_Spec sha384_type_spec = { + .name = "_sha2.SHA384Type", + .basicsize = sizeof(SHA512object), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION | + Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_HAVE_GC), + .slots = sha512_type_slots +}; + +static PyType_Spec sha512_type_spec = { + .name = "_sha2.SHA512Type", + .basicsize = sizeof(SHA512object), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION | + Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_HAVE_GC), + .slots = sha512_type_slots +}; + +/* The module-level constructors. */ + +/*[clinic input] +_sha2.sha256 + + string: object(c_default="NULL") = b'' + * + usedforsecurity: bool = True + +Return a new SHA-256 hash object; optionally initialized with a string. +[clinic start generated code]*/ + +static PyObject * +_sha2_sha256_impl(PyObject *module, PyObject *string, int usedforsecurity) +/*[clinic end generated code: output=243c9dd289931f87 input=6249da1de607280a]*/ +{ + Py_buffer buf; + + if (string) { + GET_BUFFER_VIEW_OR_ERROUT(string, &buf); + } + + sha2_state *state = sha2_get_state(module); + + SHA256object *new; + if ((new = newSHA256object(state)) == NULL) { + if (string) { + PyBuffer_Release(&buf); + } + return NULL; + } + + new->state = Hacl_Streaming_SHA2_create_in_256(); + new->digestsize = 32; + + if (PyErr_Occurred()) { + Py_DECREF(new); + if (string) { + PyBuffer_Release(&buf); + } + return NULL; + } + if (string) { + if (buf.len >= HASHLIB_GIL_MINSIZE) { + /* We do not initialize self->lock here as this is the constructor + * where it is not yet possible to have concurrent access. */ + Py_BEGIN_ALLOW_THREADS + update_256(new->state, buf.buf, buf.len); + Py_END_ALLOW_THREADS + } else { + update_256(new->state, buf.buf, buf.len); + } + PyBuffer_Release(&buf); + } + + return (PyObject *)new; +} + +/*[clinic input] +_sha2.sha224 + + string: object(c_default="NULL") = b'' + * + usedforsecurity: bool = True + +Return a new SHA-224 hash object; optionally initialized with a string. +[clinic start generated code]*/ + +static PyObject * +_sha2_sha224_impl(PyObject *module, PyObject *string, int usedforsecurity) +/*[clinic end generated code: output=68191f232e4a3843 input=c42bcba47fd7d2b7]*/ +{ + Py_buffer buf; + if (string) { + GET_BUFFER_VIEW_OR_ERROUT(string, &buf); + } + + sha2_state *state = sha2_get_state(module); + SHA256object *new; + if ((new = newSHA224object(state)) == NULL) { + if (string) { + PyBuffer_Release(&buf); + } + return NULL; + } + + new->state = Hacl_Streaming_SHA2_create_in_224(); + new->digestsize = 28; + + if (PyErr_Occurred()) { + Py_DECREF(new); + if (string) { + PyBuffer_Release(&buf); + } + return NULL; + } + if (string) { + if (buf.len >= HASHLIB_GIL_MINSIZE) { + /* We do not initialize self->lock here as this is the constructor + * where it is not yet possible to have concurrent access. */ + Py_BEGIN_ALLOW_THREADS + update_256(new->state, buf.buf, buf.len); + Py_END_ALLOW_THREADS + } else { + update_256(new->state, buf.buf, buf.len); + } + PyBuffer_Release(&buf); + } + + return (PyObject *)new; +} + +/*[clinic input] +_sha2.sha512 + + string: object(c_default="NULL") = b'' + * + usedforsecurity: bool = True + +Return a new SHA-512 hash object; optionally initialized with a string. +[clinic start generated code]*/ + +static PyObject * +_sha2_sha512_impl(PyObject *module, PyObject *string, int usedforsecurity) +/*[clinic end generated code: output=d55c8996eca214d7 input=0576ae2a6ebfad25]*/ +{ + SHA512object *new; + Py_buffer buf; + + sha2_state *state = sha2_get_state(module); + + if (string) + GET_BUFFER_VIEW_OR_ERROUT(string, &buf); + + if ((new = newSHA512object(state)) == NULL) { + if (string) + PyBuffer_Release(&buf); + return NULL; + } + + new->state = Hacl_Streaming_SHA2_create_in_512(); + new->digestsize = 64; + + if (PyErr_Occurred()) { + Py_DECREF(new); + if (string) + PyBuffer_Release(&buf); + return NULL; + } + if (string) { + if (buf.len >= HASHLIB_GIL_MINSIZE) { + /* We do not initialize self->lock here as this is the constructor + * where it is not yet possible to have concurrent access. */ + Py_BEGIN_ALLOW_THREADS + update_512(new->state, buf.buf, buf.len); + Py_END_ALLOW_THREADS + } else { + update_512(new->state, buf.buf, buf.len); + } + PyBuffer_Release(&buf); + } + + return (PyObject *)new; +} + +/*[clinic input] +_sha2.sha384 + + string: object(c_default="NULL") = b'' + * + usedforsecurity: bool = True + +Return a new SHA-384 hash object; optionally initialized with a string. +[clinic start generated code]*/ + +static PyObject * +_sha2_sha384_impl(PyObject *module, PyObject *string, int usedforsecurity) +/*[clinic end generated code: output=b29a0d81d51d1368 input=4e9199d8de0d2f9b]*/ +{ + SHA512object *new; + Py_buffer buf; + + sha2_state *state = sha2_get_state(module); + + if (string) + GET_BUFFER_VIEW_OR_ERROUT(string, &buf); + + if ((new = newSHA384object(state)) == NULL) { + if (string) + PyBuffer_Release(&buf); + return NULL; + } + + new->state = Hacl_Streaming_SHA2_create_in_384(); + new->digestsize = 48; + + if (PyErr_Occurred()) { + Py_DECREF(new); + if (string) + PyBuffer_Release(&buf); + return NULL; + } + if (string) { + if (buf.len >= HASHLIB_GIL_MINSIZE) { + /* We do not initialize self->lock here as this is the constructor + * where it is not yet possible to have concurrent access. */ + Py_BEGIN_ALLOW_THREADS + update_512(new->state, buf.buf, buf.len); + Py_END_ALLOW_THREADS + } else { + update_512(new->state, buf.buf, buf.len); + } + PyBuffer_Release(&buf); + } + + return (PyObject *)new; +} + +/* List of functions exported by this module */ + +static struct PyMethodDef SHA2_functions[] = { + _SHA2_SHA256_METHODDEF + _SHA2_SHA224_METHODDEF + _SHA2_SHA512_METHODDEF + _SHA2_SHA384_METHODDEF + {NULL, NULL} /* Sentinel */ +}; + +static int +_sha2_traverse(PyObject *module, visitproc visit, void *arg) +{ + sha2_state *state = sha2_get_state(module); + Py_VISIT(state->sha224_type); + Py_VISIT(state->sha256_type); + Py_VISIT(state->sha384_type); + Py_VISIT(state->sha512_type); + return 0; +} + +static int +_sha2_clear(PyObject *module) +{ + sha2_state *state = sha2_get_state(module); + Py_CLEAR(state->sha224_type); + Py_CLEAR(state->sha256_type); + Py_CLEAR(state->sha384_type); + Py_CLEAR(state->sha512_type); + return 0; +} + +static void +_sha2_free(void *module) +{ + _sha2_clear((PyObject *)module); +} + +/* Initialize this module. */ +static int sha2_exec(PyObject *module) +{ + sha2_state *state = sha2_get_state(module); + + state->sha224_type = (PyTypeObject *)PyType_FromModuleAndSpec( + module, &sha224_type_spec, NULL); + if (state->sha224_type == NULL) { + return -1; + } + state->sha256_type = (PyTypeObject *)PyType_FromModuleAndSpec( + module, &sha256_type_spec, NULL); + if (state->sha256_type == NULL) { + return -1; + } + state->sha384_type = (PyTypeObject *)PyType_FromModuleAndSpec( + module, &sha384_type_spec, NULL); + if (state->sha384_type == NULL) { + return -1; + } + state->sha512_type = (PyTypeObject *)PyType_FromModuleAndSpec( + module, &sha512_type_spec, NULL); + if (state->sha512_type == NULL) { + return -1; + } + + if (PyModule_AddType(module, state->sha224_type) < 0) { + return -1; + } + if (PyModule_AddType(module, state->sha256_type) < 0) { + return -1; + } + if (PyModule_AddType(module, state->sha384_type) < 0) { + return -1; + } + if (PyModule_AddType(module, state->sha512_type) < 0) { + return -1; + } + + return 0; +} + +static PyModuleDef_Slot _sha2_slots[] = { + {Py_mod_exec, sha2_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, + {0, NULL} +}; + +static struct PyModuleDef _sha2module = { + PyModuleDef_HEAD_INIT, + .m_name = "_sha2", + .m_size = sizeof(sha2_state), + .m_methods = SHA2_functions, + .m_slots = _sha2_slots, + .m_traverse = _sha2_traverse, + .m_clear = _sha2_clear, + .m_free = _sha2_free +}; + +PyMODINIT_FUNC +PyInit__sha2(void) +{ + return PyModuleDef_Init(&_sha2module); +} diff --git a/Modules/_sha3/sha3module.c b/Modules/sha3module.c similarity index 77% rename from Modules/_sha3/sha3module.c rename to Modules/sha3module.c index bd1dd596..558d2005 100644 --- a/Modules/_sha3/sha3module.c +++ b/Modules/sha3module.c @@ -21,23 +21,10 @@ #include "Python.h" #include "pycore_strhex.h" // _Py_strhex() -#include "../hashlib.h" - -#include "sha3.c" +#include "pycore_typeobject.h" // _PyType_GetModuleState() +#include "hashlib.h" #define SHA3_MAX_DIGESTSIZE 64 /* 64 Bytes (512 Bits) for 224 to 512 */ -#define SHA3_LANESIZE 0 -#define SHA3_state sha3_ctx_t -#define SHA3_init sha3_init -#define SHA3_process sha3_update -#define SHA3_done(state, digest) sha3_final(digest, state) -#define SHA3_squeeze(state, out, len) shake_xof(state), shake_out(state, out, len) -#define SHA3_copystate(dest, src) memcpy(&(dest), &(src), sizeof(SHA3_state)) - -// no optimization -#define KeccakOpt 0 - -typedef enum { SUCCESS = 1, FAIL = 0, BAD_HASHLEN = 2 } HashReturn; typedef struct { PyTypeObject *sha3_224_type; @@ -69,10 +56,14 @@ class _sha3.shake_256 "SHA3object *" "&SHAKE256type" /* The structure for storing SHA3 info */ +#include "_hacl/Hacl_Hash_SHA3.h" + typedef struct { PyObject_HEAD - SHA3_state hash_state; + // Prevents undefined behavior via multiple threads entering the C API. + // The lock will be NULL before threaded access has been enabled. PyThread_type_lock lock; + Hacl_Streaming_Keccak_state *hash_state; } SHA3object; #include "clinic/sha3module.c.h" @@ -89,6 +80,20 @@ newSHA3object(PyTypeObject *type) return newobj; } +static void sha3_update(Hacl_Streaming_Keccak_state *state, uint8_t *buf, Py_ssize_t len) { + /* Note: we explicitly ignore the error code on the basis that it would take > + * 1 billion years to hash more than 2^64 bytes. */ +#if PY_SSIZE_T_MAX > UINT32_MAX + while (len > UINT32_MAX) { + Hacl_Streaming_Keccak_update(state, buf, UINT32_MAX); + len -= UINT32_MAX; + buf += UINT32_MAX; + } +#endif + /* Cast to uint32_t is safe: len <= UINT32_MAX at this point. */ + Hacl_Streaming_Keccak_update(state, buf, (uint32_t) len); +} + /*[clinic input] @classmethod _sha3.sha3_224.__new__ as py_sha3_new @@ -97,16 +102,15 @@ _sha3.sha3_224.__new__ as py_sha3_new * usedforsecurity: bool = True -Return a new BLAKE2b hash object. +Return a new SHA3 hash object. [clinic start generated code]*/ static PyObject * py_sha3_new_impl(PyTypeObject *type, PyObject *data, int usedforsecurity) -/*[clinic end generated code: output=90409addc5d5e8b0 input=bcfcdf2e4368347a]*/ +/*[clinic end generated code: output=90409addc5d5e8b0 input=637e5f8f6a93982a]*/ { - HashReturn res; Py_buffer buf = {NULL, NULL}; - SHA3State *state = PyType_GetModuleState(type); + SHA3State *state = _PyType_GetModuleState(type); SHA3object *self = newSHA3object(type); if (self == NULL) { goto error; @@ -115,49 +119,37 @@ py_sha3_new_impl(PyTypeObject *type, PyObject *data, int usedforsecurity) assert(state != NULL); if (type == state->sha3_224_type) { - res = sha3_init(&self->hash_state, 28); + self->hash_state = Hacl_Streaming_Keccak_malloc(Spec_Hash_Definitions_SHA3_224); } else if (type == state->sha3_256_type) { - res = sha3_init(&self->hash_state, 32); + self->hash_state = Hacl_Streaming_Keccak_malloc(Spec_Hash_Definitions_SHA3_256); } else if (type == state->sha3_384_type) { - res = sha3_init(&self->hash_state, 48); + self->hash_state = Hacl_Streaming_Keccak_malloc(Spec_Hash_Definitions_SHA3_384); } else if (type == state->sha3_512_type) { - res = sha3_init(&self->hash_state, 64); + self->hash_state = Hacl_Streaming_Keccak_malloc(Spec_Hash_Definitions_SHA3_512); } else if (type == state->shake_128_type) { - res = sha3_init(&self->hash_state, 16); + self->hash_state = Hacl_Streaming_Keccak_malloc(Spec_Hash_Definitions_Shake128); } else if (type == state->shake_256_type) { - res = sha3_init(&self->hash_state, 32); + self->hash_state = Hacl_Streaming_Keccak_malloc(Spec_Hash_Definitions_Shake256); } else { PyErr_BadInternalCall(); goto error; } - if (res != SUCCESS) { - PyErr_SetString(PyExc_RuntimeError, - "internal error in SHA3 initialize()"); - goto error; - } - if (data) { GET_BUFFER_VIEW_OR_ERROR(data, &buf, goto error); if (buf.len >= HASHLIB_GIL_MINSIZE) { - /* invariant: New objects can't be accessed by other code yet, - * thus it's safe to release the GIL without locking the object. - */ + /* We do not initialize self->lock here as this is the constructor + * where it is not yet possible to have concurrent access. */ Py_BEGIN_ALLOW_THREADS - res = SHA3_process(&self->hash_state, buf.buf, buf.len); + sha3_update(self->hash_state, buf.buf, buf.len); Py_END_ALLOW_THREADS + } else { + sha3_update(self->hash_state, buf.buf, buf.len); } - else { - res = SHA3_process(&self->hash_state, buf.buf, buf.len); - } - if (res != SUCCESS) { - PyErr_SetString(PyExc_RuntimeError, - "internal error in SHA3 Update()"); - goto error; - } - PyBuffer_Release(&buf); } + PyBuffer_Release(&buf); + return (PyObject *)self; error: @@ -176,10 +168,10 @@ py_sha3_new_impl(PyTypeObject *type, PyObject *data, int usedforsecurity) static void SHA3_dealloc(SHA3object *self) { - if (self->lock) { + Hacl_Streaming_Keccak_free(self->hash_state); + if (self->lock != NULL) { PyThread_free_lock(self->lock); } - PyTypeObject *tp = Py_TYPE(self); PyObject_Free(self); Py_DECREF(tp); @@ -205,7 +197,7 @@ _sha3_sha3_224_copy_impl(SHA3object *self) return NULL; } ENTER_HASHLIB(self); - SHA3_copystate(newobj->hash_state, self->hash_state); + newobj->hash_state = Hacl_Streaming_Keccak_copy(self->hash_state); LEAVE_HASHLIB(self); return (PyObject *)newobj; } @@ -221,20 +213,14 @@ static PyObject * _sha3_sha3_224_digest_impl(SHA3object *self) /*[clinic end generated code: output=fd531842e20b2d5b input=5b2a659536bbd248]*/ { - unsigned char digest[SHA3_MAX_DIGESTSIZE + SHA3_LANESIZE]; - SHA3_state temp; - HashReturn res; - + unsigned char digest[SHA3_MAX_DIGESTSIZE]; + // This function errors out if the algorithm is Shake. Here, we know this + // not to be the case, and therefore do not perform error checking. ENTER_HASHLIB(self); - SHA3_copystate(temp, self->hash_state); + Hacl_Streaming_Keccak_finish(self->hash_state, digest); LEAVE_HASHLIB(self); - res = SHA3_done(&temp, digest); - if (res != SUCCESS) { - PyErr_SetString(PyExc_RuntimeError, "internal error in SHA3 Final()"); - return NULL; - } return PyBytes_FromStringAndSize((const char *)digest, - self->hash_state.mdlen); + Hacl_Streaming_Keccak_hash_len(self->hash_state)); } @@ -248,21 +234,12 @@ static PyObject * _sha3_sha3_224_hexdigest_impl(SHA3object *self) /*[clinic end generated code: output=75ad03257906918d input=2d91bb6e0d114ee3]*/ { - unsigned char digest[SHA3_MAX_DIGESTSIZE + SHA3_LANESIZE]; - SHA3_state temp; - HashReturn res; - - /* Get the raw (binary) digest value */ + unsigned char digest[SHA3_MAX_DIGESTSIZE]; ENTER_HASHLIB(self); - SHA3_copystate(temp, self->hash_state); + Hacl_Streaming_Keccak_finish(self->hash_state, digest); LEAVE_HASHLIB(self); - res = SHA3_done(&temp, digest); - if (res != SUCCESS) { - PyErr_SetString(PyExc_RuntimeError, "internal error in SHA3 Final()"); - return NULL; - } return _Py_strhex((const char *)digest, - self->hash_state.mdlen); + Hacl_Streaming_Keccak_hash_len(self->hash_state)); } @@ -280,36 +257,19 @@ _sha3_sha3_224_update(SHA3object *self, PyObject *data) /*[clinic end generated code: output=d3223352286ed357 input=a887f54dcc4ae227]*/ { Py_buffer buf; - HashReturn res; - GET_BUFFER_VIEW_OR_ERROUT(data, &buf); - - /* add new data, the function takes the length in bits not bytes */ if (self->lock == NULL && buf.len >= HASHLIB_GIL_MINSIZE) { self->lock = PyThread_allocate_lock(); } - /* Once a lock exists all code paths must be synchronized. We have to - * release the GIL even for small buffers as acquiring the lock may take - * an unlimited amount of time when another thread updates this object - * with lots of data. */ - if (self->lock) { + if (self->lock != NULL) { Py_BEGIN_ALLOW_THREADS PyThread_acquire_lock(self->lock, 1); - res = SHA3_process(&self->hash_state, buf.buf, buf.len); + sha3_update(self->hash_state, buf.buf, buf.len); PyThread_release_lock(self->lock); Py_END_ALLOW_THREADS + } else { + sha3_update(self->hash_state, buf.buf, buf.len); } - else { - res = SHA3_process(&self->hash_state, buf.buf, buf.len); - } - - if (res != SUCCESS) { - PyBuffer_Release(&buf); - PyErr_SetString(PyExc_RuntimeError, - "internal error in SHA3 Update()"); - return NULL; - } - PyBuffer_Release(&buf); Py_RETURN_NONE; } @@ -327,7 +287,7 @@ static PyMethodDef SHA3_methods[] = { static PyObject * SHA3_get_block_size(SHA3object *self, void *closure) { - int rate = self->hash_state.rsiz; + uint32_t rate = Hacl_Streaming_Keccak_block_len(self->hash_state); return PyLong_FromLong(rate); } @@ -337,7 +297,7 @@ SHA3_get_name(SHA3object *self, void *closure) { PyTypeObject *type = Py_TYPE(self); - SHA3State *state = PyType_GetModuleState(type); + SHA3State *state = _PyType_GetModuleState(type); assert(state != NULL); if (type == state->sha3_224_type) { @@ -362,14 +322,19 @@ SHA3_get_name(SHA3object *self, void *closure) static PyObject * SHA3_get_digest_size(SHA3object *self, void *closure) { - return PyLong_FromLong(self->hash_state.mdlen); + // Preserving previous behavior: variable-length algorithms return 0 + if (Hacl_Streaming_Keccak_is_shake(self->hash_state)) + return PyLong_FromLong(0); + else + return PyLong_FromLong(Hacl_Streaming_Keccak_hash_len(self->hash_state)); } static PyObject * SHA3_get_capacity_bits(SHA3object *self, void *closure) { - int capacity = 1600 - self->hash_state.rsiz * 8; + uint32_t rate = Hacl_Streaming_Keccak_block_len(self->hash_state) * 8; + int capacity = 1600 - rate; return PyLong_FromLong(capacity); } @@ -377,7 +342,7 @@ SHA3_get_capacity_bits(SHA3object *self, void *closure) static PyObject * SHA3_get_rate_bits(SHA3object *self, void *closure) { - unsigned int rate = self->hash_state.rsiz * 8; + uint32_t rate = Hacl_Streaming_Keccak_block_len(self->hash_state) * 8; return PyLong_FromLong(rate); } @@ -408,7 +373,7 @@ static PyGetSetDef SHA3_getseters[] = { {0,0} \ } -// Using PyType_GetModuleState() on these types is safe since they +// Using _PyType_GetModuleState() on these types is safe since they // cannot be subclassed: it does not have the Py_TPFLAGS_BASETYPE flag. #define SHA3_TYPE_SPEC(type_spec_obj, type_name, type_slots) \ static PyType_Spec type_spec_obj = { \ @@ -454,28 +419,26 @@ static PyObject * _SHAKE_digest(SHA3object *self, unsigned long digestlen, int hex) { unsigned char *digest = NULL; - SHA3_state temp; PyObject *result = NULL; if (digestlen >= (1 << 29)) { PyErr_SetString(PyExc_ValueError, "length is too large"); return NULL; } - /* ExtractLane needs at least SHA3_MAX_DIGESTSIZE + SHA3_LANESIZE and - * SHA3_LANESIZE extra space. - */ - digest = (unsigned char*)PyMem_Malloc(digestlen + SHA3_LANESIZE); + digest = (unsigned char*)PyMem_Malloc(digestlen); if (digest == NULL) { return PyErr_NoMemory(); } - /* Get the raw (binary) digest value */ - ENTER_HASHLIB(self); - SHA3_copystate(temp, self->hash_state); - LEAVE_HASHLIB(self); - SHA3_squeeze(&temp, digest, digestlen); + /* Get the raw (binary) digest value. The HACL functions errors out if: + * - the algorith is not shake -- not the case here + * - the output length is zero -- we follow the existing behavior and return + * an empty digest, without raising an error */ + if (digestlen > 0) { + Hacl_Streaming_Keccak_squeeze(self->hash_state, digest, digestlen); + } if (hex) { - result = _Py_strhex((const char *)digest, digestlen); + result = _Py_strhex((const char *)digest, digestlen); } else { result = PyBytes_FromStringAndSize((const char *)digest, digestlen); @@ -627,11 +590,8 @@ _sha3_exec(PyObject *m) init_sha3type(shake_256_type, SHAKE256_spec); #undef init_sha3type - if (PyModule_AddIntConstant(m, "keccakopt", KeccakOpt) < 0) { - return -1; - } if (PyModule_AddStringConstant(m, "implementation", - "tiny_sha3") < 0) { + "HACL") < 0) { return -1; } @@ -640,6 +600,7 @@ _sha3_exec(PyObject *m) static PyModuleDef_Slot _sha3_slots[] = { {Py_mod_exec, _sha3_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; diff --git a/Modules/sha512module.c b/Modules/sha512module.c deleted file mode 100644 index bf4408b4..00000000 --- a/Modules/sha512module.c +++ /dev/null @@ -1,819 +0,0 @@ -/* SHA512 module */ - -/* This module provides an interface to NIST's SHA-512 and SHA-384 Algorithms */ - -/* See below for information about the original code this module was - based upon. Additional work performed by: - - Andrew Kuchling (amk@amk.ca) - Greg Stein (gstein@lyra.org) - Trevor Perrin (trevp@trevp.net) - - Copyright (C) 2005-2007 Gregory P. Smith (greg@krypto.org) - Licensed to PSF under a Contributor Agreement. - -*/ - -/* SHA objects */ -#ifndef Py_BUILD_CORE_BUILTIN -# define Py_BUILD_CORE_MODULE 1 -#endif - -#include "Python.h" -#include "pycore_bitutils.h" // _Py_bswap64() -#include "pycore_strhex.h" // _Py_strhex() -#include "structmember.h" // PyMemberDef -#include "hashlib.h" - -/*[clinic input] -module _sha512 -class SHA512Type "SHAobject *" "&PyType_Type" -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=81a3ccde92bcfe8d]*/ - -/* Some useful types */ - -typedef unsigned char SHA_BYTE; -typedef uint32_t SHA_INT32; /* 32-bit integer */ -typedef uint64_t SHA_INT64; /* 64-bit integer */ - -/* The SHA block size and message digest sizes, in bytes */ - -#define SHA_BLOCKSIZE 128 -#define SHA_DIGESTSIZE 64 - -/* The structure for storing SHA info */ - -typedef struct { - PyObject_HEAD - SHA_INT64 digest[8]; /* Message digest */ - SHA_INT32 count_lo, count_hi; /* 64-bit bit count */ - SHA_BYTE data[SHA_BLOCKSIZE]; /* SHA data buffer */ - int local; /* unprocessed amount in data */ - int digestsize; -} SHAobject; - -#include "clinic/sha512module.c.h" - -/* When run on a little-endian CPU we need to perform byte reversal on an - array of longwords. */ - -#if PY_LITTLE_ENDIAN -static void longReverse(SHA_INT64 *buffer, int byteCount) -{ - byteCount /= sizeof(*buffer); - for (; byteCount--; buffer++) { - *buffer = _Py_bswap64(*buffer); - } -} -#endif - -static void SHAcopy(SHAobject *src, SHAobject *dest) -{ - dest->local = src->local; - dest->digestsize = src->digestsize; - dest->count_lo = src->count_lo; - dest->count_hi = src->count_hi; - memcpy(dest->digest, src->digest, sizeof(src->digest)); - memcpy(dest->data, src->data, sizeof(src->data)); -} - - -/* ------------------------------------------------------------------------ - * - * This code for the SHA-512 algorithm was noted as public domain. The - * original headers are pasted below. - * - * Several changes have been made to make it more compatible with the - * Python environment and desired interface. - * - */ - -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@iahu.ca, https://www.libtom.net - */ - - -/* SHA512 by Tom St Denis */ - -/* Various logical functions */ -#define ROR64(x, y) \ - ( ((((x) & 0xFFFFFFFFFFFFFFFFULL)>>((unsigned long long)(y) & 63)) | \ - ((x)<<((unsigned long long)(64-((y) & 63))))) & 0xFFFFFFFFFFFFFFFFULL) -#define Ch(x,y,z) (z ^ (x & (y ^ z))) -#define Maj(x,y,z) (((x | y) & z) | (x & y)) -#define S(x, n) ROR64((x),(n)) -#define R(x, n) (((x) & 0xFFFFFFFFFFFFFFFFULL) >> ((unsigned long long)n)) -#define Sigma0(x) (S(x, 28) ^ S(x, 34) ^ S(x, 39)) -#define Sigma1(x) (S(x, 14) ^ S(x, 18) ^ S(x, 41)) -#define Gamma0(x) (S(x, 1) ^ S(x, 8) ^ R(x, 7)) -#define Gamma1(x) (S(x, 19) ^ S(x, 61) ^ R(x, 6)) - - -static void -sha512_transform(SHAobject *sha_info) -{ - int i; - SHA_INT64 S[8], W[80], t0, t1; - - memcpy(W, sha_info->data, sizeof(sha_info->data)); -#if PY_LITTLE_ENDIAN - longReverse(W, (int)sizeof(sha_info->data)); -#endif - - for (i = 16; i < 80; ++i) { - W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16]; - } - for (i = 0; i < 8; ++i) { - S[i] = sha_info->digest[i]; - } - - /* Compress */ -#define RND(a,b,c,d,e,f,g,h,i,ki) \ - t0 = h + Sigma1(e) + Ch(e, f, g) + ki + W[i]; \ - t1 = Sigma0(a) + Maj(a, b, c); \ - d += t0; \ - h = t0 + t1; - - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],0,0x428a2f98d728ae22ULL); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],1,0x7137449123ef65cdULL); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],2,0xb5c0fbcfec4d3b2fULL); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],3,0xe9b5dba58189dbbcULL); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],4,0x3956c25bf348b538ULL); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],5,0x59f111f1b605d019ULL); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],6,0x923f82a4af194f9bULL); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],7,0xab1c5ed5da6d8118ULL); - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],8,0xd807aa98a3030242ULL); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],9,0x12835b0145706fbeULL); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],10,0x243185be4ee4b28cULL); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],11,0x550c7dc3d5ffb4e2ULL); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],12,0x72be5d74f27b896fULL); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],13,0x80deb1fe3b1696b1ULL); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],14,0x9bdc06a725c71235ULL); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],15,0xc19bf174cf692694ULL); - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],16,0xe49b69c19ef14ad2ULL); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],17,0xefbe4786384f25e3ULL); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],18,0x0fc19dc68b8cd5b5ULL); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],19,0x240ca1cc77ac9c65ULL); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],20,0x2de92c6f592b0275ULL); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],21,0x4a7484aa6ea6e483ULL); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],22,0x5cb0a9dcbd41fbd4ULL); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],23,0x76f988da831153b5ULL); - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],24,0x983e5152ee66dfabULL); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],25,0xa831c66d2db43210ULL); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],26,0xb00327c898fb213fULL); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],27,0xbf597fc7beef0ee4ULL); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],28,0xc6e00bf33da88fc2ULL); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],29,0xd5a79147930aa725ULL); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],30,0x06ca6351e003826fULL); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],31,0x142929670a0e6e70ULL); - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],32,0x27b70a8546d22ffcULL); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],33,0x2e1b21385c26c926ULL); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],34,0x4d2c6dfc5ac42aedULL); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],35,0x53380d139d95b3dfULL); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],36,0x650a73548baf63deULL); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],37,0x766a0abb3c77b2a8ULL); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],38,0x81c2c92e47edaee6ULL); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],39,0x92722c851482353bULL); - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],40,0xa2bfe8a14cf10364ULL); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],41,0xa81a664bbc423001ULL); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],42,0xc24b8b70d0f89791ULL); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],43,0xc76c51a30654be30ULL); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],44,0xd192e819d6ef5218ULL); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],45,0xd69906245565a910ULL); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],46,0xf40e35855771202aULL); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],47,0x106aa07032bbd1b8ULL); - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],48,0x19a4c116b8d2d0c8ULL); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],49,0x1e376c085141ab53ULL); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],50,0x2748774cdf8eeb99ULL); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],51,0x34b0bcb5e19b48a8ULL); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],52,0x391c0cb3c5c95a63ULL); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],53,0x4ed8aa4ae3418acbULL); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],54,0x5b9cca4f7763e373ULL); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],55,0x682e6ff3d6b2b8a3ULL); - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],56,0x748f82ee5defb2fcULL); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],57,0x78a5636f43172f60ULL); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],58,0x84c87814a1f0ab72ULL); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],59,0x8cc702081a6439ecULL); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],60,0x90befffa23631e28ULL); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],61,0xa4506cebde82bde9ULL); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],62,0xbef9a3f7b2c67915ULL); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],63,0xc67178f2e372532bULL); - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],64,0xca273eceea26619cULL); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],65,0xd186b8c721c0c207ULL); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],66,0xeada7dd6cde0eb1eULL); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],67,0xf57d4f7fee6ed178ULL); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],68,0x06f067aa72176fbaULL); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],69,0x0a637dc5a2c898a6ULL); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],70,0x113f9804bef90daeULL); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],71,0x1b710b35131c471bULL); - RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],72,0x28db77f523047d84ULL); - RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],73,0x32caab7b40c72493ULL); - RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],74,0x3c9ebe0a15c9bebcULL); - RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],75,0x431d67c49c100d4cULL); - RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],76,0x4cc5d4becb3e42b6ULL); - RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],77,0x597f299cfc657e2aULL); - RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],78,0x5fcb6fab3ad6faecULL); - RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],79,0x6c44198c4a475817ULL); - -#undef RND - - /* feedback */ - for (i = 0; i < 8; i++) { - sha_info->digest[i] = sha_info->digest[i] + S[i]; - } - -} - - - -/* initialize the SHA digest */ - -static void -sha512_init(SHAobject *sha_info) -{ - sha_info->digest[0] = Py_ULL(0x6a09e667f3bcc908); - sha_info->digest[1] = Py_ULL(0xbb67ae8584caa73b); - sha_info->digest[2] = Py_ULL(0x3c6ef372fe94f82b); - sha_info->digest[3] = Py_ULL(0xa54ff53a5f1d36f1); - sha_info->digest[4] = Py_ULL(0x510e527fade682d1); - sha_info->digest[5] = Py_ULL(0x9b05688c2b3e6c1f); - sha_info->digest[6] = Py_ULL(0x1f83d9abfb41bd6b); - sha_info->digest[7] = Py_ULL(0x5be0cd19137e2179); - sha_info->count_lo = 0L; - sha_info->count_hi = 0L; - sha_info->local = 0; - sha_info->digestsize = 64; -} - -static void -sha384_init(SHAobject *sha_info) -{ - sha_info->digest[0] = Py_ULL(0xcbbb9d5dc1059ed8); - sha_info->digest[1] = Py_ULL(0x629a292a367cd507); - sha_info->digest[2] = Py_ULL(0x9159015a3070dd17); - sha_info->digest[3] = Py_ULL(0x152fecd8f70e5939); - sha_info->digest[4] = Py_ULL(0x67332667ffc00b31); - sha_info->digest[5] = Py_ULL(0x8eb44a8768581511); - sha_info->digest[6] = Py_ULL(0xdb0c2e0d64f98fa7); - sha_info->digest[7] = Py_ULL(0x47b5481dbefa4fa4); - sha_info->count_lo = 0L; - sha_info->count_hi = 0L; - sha_info->local = 0; - sha_info->digestsize = 48; -} - - -/* update the SHA digest */ - -static void -sha512_update(SHAobject *sha_info, SHA_BYTE *buffer, Py_ssize_t count) -{ - Py_ssize_t i; - SHA_INT32 clo; - - clo = sha_info->count_lo + ((SHA_INT32) count << 3); - if (clo < sha_info->count_lo) { - ++sha_info->count_hi; - } - sha_info->count_lo = clo; - sha_info->count_hi += (SHA_INT32) count >> 29; - if (sha_info->local) { - i = SHA_BLOCKSIZE - sha_info->local; - if (i > count) { - i = count; - } - memcpy(((SHA_BYTE *) sha_info->data) + sha_info->local, buffer, i); - count -= i; - buffer += i; - sha_info->local += (int)i; - if (sha_info->local == SHA_BLOCKSIZE) { - sha512_transform(sha_info); - } - else { - return; - } - } - while (count >= SHA_BLOCKSIZE) { - memcpy(sha_info->data, buffer, SHA_BLOCKSIZE); - buffer += SHA_BLOCKSIZE; - count -= SHA_BLOCKSIZE; - sha512_transform(sha_info); - } - memcpy(sha_info->data, buffer, count); - sha_info->local = (int)count; -} - -/* finish computing the SHA digest */ - -static void -sha512_final(unsigned char digest[SHA_DIGESTSIZE], SHAobject *sha_info) -{ - int count; - SHA_INT32 lo_bit_count, hi_bit_count; - - lo_bit_count = sha_info->count_lo; - hi_bit_count = sha_info->count_hi; - count = (int) ((lo_bit_count >> 3) & 0x7f); - ((SHA_BYTE *) sha_info->data)[count++] = 0x80; - if (count > SHA_BLOCKSIZE - 16) { - memset(((SHA_BYTE *) sha_info->data) + count, 0, - SHA_BLOCKSIZE - count); - sha512_transform(sha_info); - memset((SHA_BYTE *) sha_info->data, 0, SHA_BLOCKSIZE - 16); - } - else { - memset(((SHA_BYTE *) sha_info->data) + count, 0, - SHA_BLOCKSIZE - 16 - count); - } - - /* GJS: note that we add the hi/lo in big-endian. sha512_transform will - swap these values into host-order. */ - sha_info->data[112] = 0; - sha_info->data[113] = 0; - sha_info->data[114] = 0; - sha_info->data[115] = 0; - sha_info->data[116] = 0; - sha_info->data[117] = 0; - sha_info->data[118] = 0; - sha_info->data[119] = 0; - sha_info->data[120] = (hi_bit_count >> 24) & 0xff; - sha_info->data[121] = (hi_bit_count >> 16) & 0xff; - sha_info->data[122] = (hi_bit_count >> 8) & 0xff; - sha_info->data[123] = (hi_bit_count >> 0) & 0xff; - sha_info->data[124] = (lo_bit_count >> 24) & 0xff; - sha_info->data[125] = (lo_bit_count >> 16) & 0xff; - sha_info->data[126] = (lo_bit_count >> 8) & 0xff; - sha_info->data[127] = (lo_bit_count >> 0) & 0xff; - sha512_transform(sha_info); - digest[ 0] = (unsigned char) ((sha_info->digest[0] >> 56) & 0xff); - digest[ 1] = (unsigned char) ((sha_info->digest[0] >> 48) & 0xff); - digest[ 2] = (unsigned char) ((sha_info->digest[0] >> 40) & 0xff); - digest[ 3] = (unsigned char) ((sha_info->digest[0] >> 32) & 0xff); - digest[ 4] = (unsigned char) ((sha_info->digest[0] >> 24) & 0xff); - digest[ 5] = (unsigned char) ((sha_info->digest[0] >> 16) & 0xff); - digest[ 6] = (unsigned char) ((sha_info->digest[0] >> 8) & 0xff); - digest[ 7] = (unsigned char) ((sha_info->digest[0] ) & 0xff); - digest[ 8] = (unsigned char) ((sha_info->digest[1] >> 56) & 0xff); - digest[ 9] = (unsigned char) ((sha_info->digest[1] >> 48) & 0xff); - digest[10] = (unsigned char) ((sha_info->digest[1] >> 40) & 0xff); - digest[11] = (unsigned char) ((sha_info->digest[1] >> 32) & 0xff); - digest[12] = (unsigned char) ((sha_info->digest[1] >> 24) & 0xff); - digest[13] = (unsigned char) ((sha_info->digest[1] >> 16) & 0xff); - digest[14] = (unsigned char) ((sha_info->digest[1] >> 8) & 0xff); - digest[15] = (unsigned char) ((sha_info->digest[1] ) & 0xff); - digest[16] = (unsigned char) ((sha_info->digest[2] >> 56) & 0xff); - digest[17] = (unsigned char) ((sha_info->digest[2] >> 48) & 0xff); - digest[18] = (unsigned char) ((sha_info->digest[2] >> 40) & 0xff); - digest[19] = (unsigned char) ((sha_info->digest[2] >> 32) & 0xff); - digest[20] = (unsigned char) ((sha_info->digest[2] >> 24) & 0xff); - digest[21] = (unsigned char) ((sha_info->digest[2] >> 16) & 0xff); - digest[22] = (unsigned char) ((sha_info->digest[2] >> 8) & 0xff); - digest[23] = (unsigned char) ((sha_info->digest[2] ) & 0xff); - digest[24] = (unsigned char) ((sha_info->digest[3] >> 56) & 0xff); - digest[25] = (unsigned char) ((sha_info->digest[3] >> 48) & 0xff); - digest[26] = (unsigned char) ((sha_info->digest[3] >> 40) & 0xff); - digest[27] = (unsigned char) ((sha_info->digest[3] >> 32) & 0xff); - digest[28] = (unsigned char) ((sha_info->digest[3] >> 24) & 0xff); - digest[29] = (unsigned char) ((sha_info->digest[3] >> 16) & 0xff); - digest[30] = (unsigned char) ((sha_info->digest[3] >> 8) & 0xff); - digest[31] = (unsigned char) ((sha_info->digest[3] ) & 0xff); - digest[32] = (unsigned char) ((sha_info->digest[4] >> 56) & 0xff); - digest[33] = (unsigned char) ((sha_info->digest[4] >> 48) & 0xff); - digest[34] = (unsigned char) ((sha_info->digest[4] >> 40) & 0xff); - digest[35] = (unsigned char) ((sha_info->digest[4] >> 32) & 0xff); - digest[36] = (unsigned char) ((sha_info->digest[4] >> 24) & 0xff); - digest[37] = (unsigned char) ((sha_info->digest[4] >> 16) & 0xff); - digest[38] = (unsigned char) ((sha_info->digest[4] >> 8) & 0xff); - digest[39] = (unsigned char) ((sha_info->digest[4] ) & 0xff); - digest[40] = (unsigned char) ((sha_info->digest[5] >> 56) & 0xff); - digest[41] = (unsigned char) ((sha_info->digest[5] >> 48) & 0xff); - digest[42] = (unsigned char) ((sha_info->digest[5] >> 40) & 0xff); - digest[43] = (unsigned char) ((sha_info->digest[5] >> 32) & 0xff); - digest[44] = (unsigned char) ((sha_info->digest[5] >> 24) & 0xff); - digest[45] = (unsigned char) ((sha_info->digest[5] >> 16) & 0xff); - digest[46] = (unsigned char) ((sha_info->digest[5] >> 8) & 0xff); - digest[47] = (unsigned char) ((sha_info->digest[5] ) & 0xff); - digest[48] = (unsigned char) ((sha_info->digest[6] >> 56) & 0xff); - digest[49] = (unsigned char) ((sha_info->digest[6] >> 48) & 0xff); - digest[50] = (unsigned char) ((sha_info->digest[6] >> 40) & 0xff); - digest[51] = (unsigned char) ((sha_info->digest[6] >> 32) & 0xff); - digest[52] = (unsigned char) ((sha_info->digest[6] >> 24) & 0xff); - digest[53] = (unsigned char) ((sha_info->digest[6] >> 16) & 0xff); - digest[54] = (unsigned char) ((sha_info->digest[6] >> 8) & 0xff); - digest[55] = (unsigned char) ((sha_info->digest[6] ) & 0xff); - digest[56] = (unsigned char) ((sha_info->digest[7] >> 56) & 0xff); - digest[57] = (unsigned char) ((sha_info->digest[7] >> 48) & 0xff); - digest[58] = (unsigned char) ((sha_info->digest[7] >> 40) & 0xff); - digest[59] = (unsigned char) ((sha_info->digest[7] >> 32) & 0xff); - digest[60] = (unsigned char) ((sha_info->digest[7] >> 24) & 0xff); - digest[61] = (unsigned char) ((sha_info->digest[7] >> 16) & 0xff); - digest[62] = (unsigned char) ((sha_info->digest[7] >> 8) & 0xff); - digest[63] = (unsigned char) ((sha_info->digest[7] ) & 0xff); -} - -/* - * End of copied SHA code. - * - * ------------------------------------------------------------------------ - */ - -typedef struct { - PyTypeObject* sha384_type; - PyTypeObject* sha512_type; -} SHA512State; - -static inline SHA512State* -sha512_get_state(PyObject *module) -{ - void *state = PyModule_GetState(module); - assert(state != NULL); - return (SHA512State *)state; -} - -static SHAobject * -newSHA384object(SHA512State *st) -{ - SHAobject *sha = (SHAobject *)PyObject_GC_New(SHAobject, st->sha384_type); - PyObject_GC_Track(sha); - return sha; -} - -static SHAobject * -newSHA512object(SHA512State *st) -{ - SHAobject *sha = (SHAobject *)PyObject_GC_New(SHAobject, st->sha512_type); - PyObject_GC_Track(sha); - return sha; -} - -/* Internal methods for a hash object */ -static int -SHA_traverse(PyObject *ptr, visitproc visit, void *arg) -{ - Py_VISIT(Py_TYPE(ptr)); - return 0; -} - -static void -SHA512_dealloc(PyObject *ptr) -{ - PyTypeObject *tp = Py_TYPE(ptr); - PyObject_GC_UnTrack(ptr); - PyObject_GC_Del(ptr); - Py_DECREF(tp); -} - - -/* External methods for a hash object */ - -/*[clinic input] -SHA512Type.copy - - cls: defining_class - -Return a copy of the hash object. -[clinic start generated code]*/ - -static PyObject * -SHA512Type_copy_impl(SHAobject *self, PyTypeObject *cls) -/*[clinic end generated code: output=85ea5b47837a08e6 input=f673a18f66527c90]*/ -{ - SHAobject *newobj; - SHA512State *st = PyType_GetModuleState(cls); - - if (Py_IS_TYPE((PyObject*)self, st->sha512_type)) { - if ( (newobj = newSHA512object(st))==NULL) { - return NULL; - } - } - else { - if ( (newobj = newSHA384object(st))==NULL) { - return NULL; - } - } - - SHAcopy(self, newobj); - return (PyObject *)newobj; -} - -/*[clinic input] -SHA512Type.digest - -Return the digest value as a bytes object. -[clinic start generated code]*/ - -static PyObject * -SHA512Type_digest_impl(SHAobject *self) -/*[clinic end generated code: output=1080bbeeef7dde1b input=f6470dd359071f4b]*/ -{ - unsigned char digest[SHA_DIGESTSIZE]; - SHAobject temp; - - SHAcopy(self, &temp); - sha512_final(digest, &temp); - return PyBytes_FromStringAndSize((const char *)digest, self->digestsize); -} - -/*[clinic input] -SHA512Type.hexdigest - -Return the digest value as a string of hexadecimal digits. -[clinic start generated code]*/ - -static PyObject * -SHA512Type_hexdigest_impl(SHAobject *self) -/*[clinic end generated code: output=7373305b8601e18b input=498b877b25cbe0a2]*/ -{ - unsigned char digest[SHA_DIGESTSIZE]; - SHAobject temp; - - /* Get the raw (binary) digest value */ - SHAcopy(self, &temp); - sha512_final(digest, &temp); - - return _Py_strhex((const char *)digest, self->digestsize); -} - -/*[clinic input] -SHA512Type.update - - obj: object - / - -Update this hash object's state with the provided string. -[clinic start generated code]*/ - -static PyObject * -SHA512Type_update(SHAobject *self, PyObject *obj) -/*[clinic end generated code: output=1cf333e73995a79e input=ded2b46656566283]*/ -{ - Py_buffer buf; - - GET_BUFFER_VIEW_OR_ERROUT(obj, &buf); - - sha512_update(self, buf.buf, buf.len); - - PyBuffer_Release(&buf); - Py_RETURN_NONE; -} - -static PyMethodDef SHA_methods[] = { - SHA512TYPE_COPY_METHODDEF - SHA512TYPE_DIGEST_METHODDEF - SHA512TYPE_HEXDIGEST_METHODDEF - SHA512TYPE_UPDATE_METHODDEF - {NULL, NULL} /* sentinel */ -}; - -static PyObject * -SHA512_get_block_size(PyObject *self, void *closure) -{ - return PyLong_FromLong(SHA_BLOCKSIZE); -} - -static PyObject * -SHA512_get_name(PyObject *self, void *closure) -{ - if (((SHAobject *)self)->digestsize == 64) - return PyUnicode_FromStringAndSize("sha512", 6); - else - return PyUnicode_FromStringAndSize("sha384", 6); -} - -static PyGetSetDef SHA_getseters[] = { - {"block_size", - (getter)SHA512_get_block_size, NULL, - NULL, - NULL}, - {"name", - (getter)SHA512_get_name, NULL, - NULL, - NULL}, - {NULL} /* Sentinel */ -}; - -static PyMemberDef SHA_members[] = { - {"digest_size", T_INT, offsetof(SHAobject, digestsize), READONLY, NULL}, - {NULL} /* Sentinel */ -}; - -static PyType_Slot sha512_sha384_type_slots[] = { - {Py_tp_dealloc, SHA512_dealloc}, - {Py_tp_methods, SHA_methods}, - {Py_tp_members, SHA_members}, - {Py_tp_getset, SHA_getseters}, - {Py_tp_traverse, SHA_traverse}, - {0,0} -}; - -static PyType_Spec sha512_sha384_type_spec = { - .name = "_sha512.sha384", - .basicsize = sizeof(SHAobject), - .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION | - Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_HAVE_GC), - .slots = sha512_sha384_type_slots -}; - -static PyType_Slot sha512_sha512_type_slots[] = { - {Py_tp_dealloc, SHA512_dealloc}, - {Py_tp_methods, SHA_methods}, - {Py_tp_members, SHA_members}, - {Py_tp_getset, SHA_getseters}, - {Py_tp_traverse, SHA_traverse}, - {0,0} -}; - -// Using PyType_GetModuleState() on this type is safe since -// it cannot be subclassed: it does not have the Py_TPFLAGS_BASETYPE flag. -static PyType_Spec sha512_sha512_type_spec = { - .name = "_sha512.sha512", - .basicsize = sizeof(SHAobject), - .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION | - Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_HAVE_GC), - .slots = sha512_sha512_type_slots -}; - -/* The single module-level function: new() */ - -/*[clinic input] -_sha512.sha512 - - string: object(c_default="NULL") = b'' - * - usedforsecurity: bool = True - -Return a new SHA-512 hash object; optionally initialized with a string. -[clinic start generated code]*/ - -static PyObject * -_sha512_sha512_impl(PyObject *module, PyObject *string, int usedforsecurity) -/*[clinic end generated code: output=a8d9e5f9e6a0831c input=23b4daebc2ebb9c9]*/ -{ - SHAobject *new; - Py_buffer buf; - - SHA512State *st = sha512_get_state(module); - - if (string) - GET_BUFFER_VIEW_OR_ERROUT(string, &buf); - - if ((new = newSHA512object(st)) == NULL) { - if (string) - PyBuffer_Release(&buf); - return NULL; - } - - sha512_init(new); - - if (PyErr_Occurred()) { - Py_DECREF(new); - if (string) - PyBuffer_Release(&buf); - return NULL; - } - if (string) { - sha512_update(new, buf.buf, buf.len); - PyBuffer_Release(&buf); - } - - return (PyObject *)new; -} - -/*[clinic input] -_sha512.sha384 - - string: object(c_default="NULL") = b'' - * - usedforsecurity: bool = True - -Return a new SHA-384 hash object; optionally initialized with a string. -[clinic start generated code]*/ - -static PyObject * -_sha512_sha384_impl(PyObject *module, PyObject *string, int usedforsecurity) -/*[clinic end generated code: output=da7d594a08027ac3 input=59ef72f039a6b431]*/ -{ - SHAobject *new; - Py_buffer buf; - - SHA512State *st = sha512_get_state(module); - - if (string) - GET_BUFFER_VIEW_OR_ERROUT(string, &buf); - - if ((new = newSHA384object(st)) == NULL) { - if (string) - PyBuffer_Release(&buf); - return NULL; - } - - sha384_init(new); - - if (PyErr_Occurred()) { - Py_DECREF(new); - if (string) - PyBuffer_Release(&buf); - return NULL; - } - if (string) { - sha512_update(new, buf.buf, buf.len); - PyBuffer_Release(&buf); - } - - return (PyObject *)new; -} - - -/* List of functions exported by this module */ - -static struct PyMethodDef SHA_functions[] = { - _SHA512_SHA512_METHODDEF - _SHA512_SHA384_METHODDEF - {NULL, NULL} /* Sentinel */ -}; - -static int -_sha512_traverse(PyObject *module, visitproc visit, void *arg) -{ - SHA512State *state = sha512_get_state(module); - Py_VISIT(state->sha384_type); - Py_VISIT(state->sha512_type); - return 0; -} - -static int -_sha512_clear(PyObject *module) -{ - SHA512State *state = sha512_get_state(module); - Py_CLEAR(state->sha384_type); - Py_CLEAR(state->sha512_type); - return 0; -} - -static void -_sha512_free(void *module) -{ - _sha512_clear((PyObject *)module); -} - - -/* Initialize this module. */ -static int -_sha512_exec(PyObject *m) -{ - SHA512State* st = sha512_get_state(m); - - st->sha384_type = (PyTypeObject *)PyType_FromModuleAndSpec( - m, &sha512_sha384_type_spec, NULL); - - st->sha512_type = (PyTypeObject *)PyType_FromModuleAndSpec( - m, &sha512_sha512_type_spec, NULL); - - if (st->sha384_type == NULL || st->sha512_type == NULL) { - return -1; - } - - Py_INCREF(st->sha384_type); - if (PyModule_AddObject(m, "SHA384Type", (PyObject *)st->sha384_type) < 0) { - Py_DECREF(st->sha384_type); - return -1; - } - - Py_INCREF(st->sha512_type); - if (PyModule_AddObject(m, "SHA384Type", (PyObject *)st->sha512_type) < 0) { - Py_DECREF(st->sha512_type); - return -1; - } - - return 0; -} - -static PyModuleDef_Slot _sha512_slots[] = { - {Py_mod_exec, _sha512_exec}, - {0, NULL} -}; - -static struct PyModuleDef _sha512module = { - PyModuleDef_HEAD_INIT, - .m_name = "_sha512", - .m_size = sizeof(SHA512State), - .m_methods = SHA_functions, - .m_slots = _sha512_slots, - .m_traverse = _sha512_traverse, - .m_clear = _sha512_clear, - .m_free = _sha512_free -}; - -PyMODINIT_FUNC -PyInit__sha512(void) -{ - return PyModuleDef_Init(&_sha512module); -} diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c index 60a8067f..00ea4343 100644 --- a/Modules/signalmodule.c +++ b/Modules/signalmodule.c @@ -23,7 +23,6 @@ #endif #ifdef MS_WINDOWS -# include <windows.h> # ifdef HAVE_PROCESS_H # include <process.h> # endif @@ -100,47 +99,13 @@ class sigset_t_converter(CConverter): may not be the thread that received the signal. */ -static volatile struct { - _Py_atomic_int tripped; - /* func is atomic to ensure that PyErr_SetInterrupt is async-signal-safe - * (even though it would probably be otherwise, anyway). - */ - _Py_atomic_address func; -} Handlers[Py_NSIG]; - -#ifdef MS_WINDOWS -#define INVALID_FD ((SOCKET_T)-1) - -static volatile struct { - SOCKET_T fd; - int warn_on_full_buffer; - int use_send; -} wakeup = {.fd = INVALID_FD, .warn_on_full_buffer = 1, .use_send = 0}; -#else -#define INVALID_FD (-1) -static volatile struct { -#ifdef __VXWORKS__ - int fd; -#else - sig_atomic_t fd; -#endif - int warn_on_full_buffer; -} wakeup = {.fd = INVALID_FD, .warn_on_full_buffer = 1}; -#endif - -/* Speed up sigcheck() when none tripped */ -static _Py_atomic_int is_tripped; - -typedef struct { - PyObject *default_handler; - PyObject *ignore_handler; -#ifdef MS_WINDOWS - HANDLE sigint_event; -#endif -} signal_state_t; +#define Handlers _PyRuntime.signals.handlers +#define wakeup _PyRuntime.signals.wakeup +#define is_tripped _PyRuntime.signals.is_tripped // State shared by all Python interpreters -static signal_state_t signal_global_state = {0}; +typedef struct _signals_runtime_state signal_state_t; +#define signal_global_state _PyRuntime.signals #if defined(HAVE_GETITIMER) || defined(HAVE_SETITIMER) # define PYHAVE_ITIMER_ERROR @@ -181,6 +146,10 @@ get_signal_state(PyObject *module) static inline int compare_handler(PyObject *func, PyObject *dfl_ign_handler) { + // See https://github.com/python/cpython/pull/102399 + if (func == NULL || dfl_ign_handler == NULL) { + return 0; + } assert(PyLong_CheckExact(dfl_ign_handler)); if (!PyLong_CheckExact(func)) { return 0; @@ -267,15 +236,13 @@ signal_default_int_handler_impl(PyObject *module, int signalnum, static int report_wakeup_write_error(void *data) { - PyObject *exc, *val, *tb; int save_errno = errno; errno = (int) (intptr_t) data; - PyErr_Fetch(&exc, &val, &tb); + PyObject *exc = PyErr_GetRaisedException(); PyErr_SetFromErrno(PyExc_OSError); - PySys_WriteStderr("Exception ignored when trying to write to the " - "signal wakeup fd:\n"); - PyErr_WriteUnraisable(NULL); - PyErr_Restore(exc, val, tb); + _PyErr_WriteUnraisableMsg("when trying to write to the signal wakeup fd", + NULL); + PyErr_SetRaisedException(exc); errno = save_errno; return 0; } @@ -284,16 +251,15 @@ report_wakeup_write_error(void *data) static int report_wakeup_send_error(void* data) { - PyObject *exc, *val, *tb; - PyErr_Fetch(&exc, &val, &tb); + int send_errno = (int) (intptr_t) data; + + PyObject *exc = PyErr_GetRaisedException(); /* PyErr_SetExcFromWindowsErr() invokes FormatMessage() which recognizes the error codes used by both GetLastError() and WSAGetLastError */ - PyErr_SetExcFromWindowsErr(PyExc_OSError, (int) (intptr_t) data); - PySys_WriteStderr("Exception ignored when trying to send to the " - "signal wakeup fd:\n"); - PyErr_WriteUnraisable(NULL); - PyErr_Restore(exc, val, tb); + PyErr_SetExcFromWindowsErr(PyExc_OSError, send_errno); + _PyErr_WriteUnraisableMsg("when trying to send to the signal wakeup fd", NULL); + PyErr_SetRaisedException(exc); return 0; } #endif /* MS_WINDOWS */ @@ -332,13 +298,7 @@ trip_signal(int sig_num) See bpo-30038 for more details. */ - int fd; -#ifdef MS_WINDOWS - fd = Py_SAFE_DOWNCAST(wakeup.fd, SOCKET_T, int); -#else - fd = wakeup.fd; -#endif - + int fd = wakeup.fd; if (fd != INVALID_FD) { unsigned char byte = (unsigned char)sig_num; #ifdef MS_WINDOWS @@ -354,7 +314,8 @@ trip_signal(int sig_num) still use it for this exceptional case. */ _PyEval_AddPendingCall(interp, report_wakeup_send_error, - (void *)(intptr_t) last_error); + (void *)(intptr_t) last_error, + 1); } } } @@ -373,7 +334,8 @@ trip_signal(int sig_num) still use it for this exceptional case. */ _PyEval_AddPendingCall(interp, report_wakeup_write_error, - (void *)(intptr_t)errno); + (void *)(intptr_t)errno, + 1); } } } @@ -408,7 +370,7 @@ signal_handler(int sig_num) #ifdef MS_WINDOWS if (sig_num == SIGINT) { signal_state_t *state = &signal_global_state; - SetEvent(state->sigint_event); + SetEvent((HANDLE)state->sigint_event); } #endif } @@ -823,7 +785,7 @@ signal_set_wakeup_fd(PyObject *self, PyObject *args, PyObject *kwds) } old_sockfd = wakeup.fd; - wakeup.fd = sockfd; + wakeup.fd = Py_SAFE_DOWNCAST(sockfd, SOCKET_T, int); wakeup.warn_on_full_buffer = warn_on_full_buffer; wakeup.use_send = is_socket; @@ -874,11 +836,7 @@ PySignal_SetWakeupFd(int fd) fd = -1; } -#ifdef MS_WINDOWS - int old_fd = Py_SAFE_DOWNCAST(wakeup.fd, SOCKET_T, int); -#else int old_fd = wakeup.fd; -#endif wakeup.fd = fd; wakeup.warn_on_full_buffer = 1; return old_fd; @@ -1655,6 +1613,8 @@ signal_module_exec(PyObject *m) signal_state_t *state = &signal_global_state; _signal_module_state *modstate = get_signal_state(m); + // XXX For proper isolation, these values must be guaranteed + // to be effectively const (e.g. immortal). modstate->default_handler = state->default_handler; // borrowed ref modstate->ignore_handler = state->ignore_handler; // borrowed ref @@ -1737,6 +1697,7 @@ _signal_module_free(void *module) static PyModuleDef_Slot signal_slots[] = { {Py_mod_exec, signal_module_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; @@ -1784,7 +1745,7 @@ _PySignal_Fini(void) #ifdef MS_WINDOWS if (state->sigint_event != NULL) { - CloseHandle(state->sigint_event); + CloseHandle((HANDLE)state->sigint_event); state->sigint_event = NULL; } #endif @@ -1799,6 +1760,19 @@ int PyErr_CheckSignals(void) { PyThreadState *tstate = _PyThreadState_GET(); + + /* Opportunistically check if the GC is scheduled to run and run it + if we have a request. This is done here because native code needs + to call this API if is going to run for some time without executing + Python code to ensure signals are handled. Checking for the GC here + allows long running native code to clean cycles created using the C-API + even if it doesn't run the evaluation loop */ + struct _ceval_state *interp_ceval_state = &tstate->interp->ceval; + if (_Py_atomic_load_relaxed(&interp_ceval_state->gc_scheduled)) { + _Py_atomic_store_relaxed(&interp_ceval_state->gc_scheduled, 0); + _Py_RunGC(tstate); + } + if (!_Py_ThreadCanHandleSignals(tstate->interp)) { return 0; } @@ -1832,10 +1806,7 @@ _PyErr_CheckSignalsTstate(PyThreadState *tstate) */ _Py_atomic_store(&is_tripped, 0); - _PyInterpreterFrame *frame = tstate->cframe->current_frame; - while (frame && _PyFrame_IsIncomplete(frame)) { - frame = frame->previous; - } + _PyInterpreterFrame *frame = _PyThreadState_GetFrame(tstate); signal_state_t *state = &signal_global_state; for (int i = 1; i < Py_NSIG; i++) { if (!_Py_atomic_load_relaxed(&Handlers[i].tripped)) { @@ -1997,7 +1968,7 @@ _PySignal_Init(int install_signal_handlers) #ifdef MS_WINDOWS /* Create manual-reset event, initially unset */ - state->sigint_event = CreateEvent(NULL, TRUE, FALSE, FALSE); + state->sigint_event = (void *)CreateEvent(NULL, TRUE, FALSE, FALSE); if (state->sigint_event == NULL) { PyErr_SetFromWindowsErr(0); return -1; diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index 0e319a4c..4ec68e22 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -108,6 +108,7 @@ Local naming conventions: #define PY_SSIZE_T_CLEAN #include "Python.h" #include "pycore_fileutils.h" // _Py_set_inheritable() +#include "pycore_moduleobject.h" // _PyModule_GetState #include "structmember.h" // PyMemberDef #ifdef _Py_MEMORY_SANITIZER @@ -247,6 +248,10 @@ shutdown(how) -- shut down traffic in one or both directions\n\ #include <net/if.h> #endif +#ifdef HAVE_NET_ETHERNET_H +#include <net/ethernet.h> +#endif + /* Generic socket object definitions and includes */ #define PySocket_BUILDING_SOCKET #include "socketmodule.h" @@ -266,15 +271,17 @@ shutdown(how) -- shut down traffic in one or both directions\n\ # include <fcntl.h> -#else +#else /* MS_WINDOWS */ /* MS_WINDOWS includes */ # ifdef HAVE_FCNTL_H # include <fcntl.h> # endif +/* Helpers needed for AF_HYPERV */ +# include <Rpc.h> + /* Macros based on the IPPROTO enum, see: https://bugs.python.org/issue29515 */ -#ifdef MS_WINDOWS #define IPPROTO_ICMP IPPROTO_ICMP #define IPPROTO_IGMP IPPROTO_IGMP #define IPPROTO_GGP IPPROTO_GGP @@ -305,7 +312,6 @@ shutdown(how) -- shut down traffic in one or both directions\n\ #define IPPROTO_PGM IPPROTO_PGM // WinSock2 only #define IPPROTO_L2TP IPPROTO_L2TP // WinSock2 only #define IPPROTO_SCTP IPPROTO_SCTP // WinSock2 only -#endif /* MS_WINDOWS */ /* Provides the IsWindows7SP1OrGreater() function */ #include <versionhelpers.h> @@ -332,22 +338,27 @@ static FlagRuntimeInfo win_runtime_flags[] = { /*[clinic input] module _socket -class _socket.socket "PySocketSockObject *" "&sock_type" +class _socket.socket "PySocketSockObject *" "clinic_state()->sock_type" [clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=7a8313d9b7f51988]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=2db2489bd2219fd8]*/ static int remove_unusable_flags(PyObject *m) { PyObject *dict; OSVERSIONINFOEX info; - DWORDLONG dwlConditionMask; dict = PyModule_GetDict(m); if (dict == NULL) { return -1; } - +#ifndef MS_WINDOWS_DESKTOP + info.dwOSVersionInfoSize = sizeof(info); + if (!GetVersionEx((OSVERSIONINFO*) &info)) { + PyErr_SetFromWindowsErr(0); + return -1; + } +#else /* set to Windows 10, except BuildNumber. */ memset(&info, 0, sizeof(info)); info.dwOSVersionInfoSize = sizeof(info); @@ -355,19 +366,30 @@ remove_unusable_flags(PyObject *m) info.dwMinorVersion = 0; /* set Condition Mask */ - dwlConditionMask = 0; + DWORDLONG dwlConditionMask = 0; VER_SET_CONDITION(dwlConditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL); VER_SET_CONDITION(dwlConditionMask, VER_MINORVERSION, VER_GREATER_EQUAL); VER_SET_CONDITION(dwlConditionMask, VER_BUILDNUMBER, VER_GREATER_EQUAL); +#endif for (int i=0; i<sizeof(win_runtime_flags)/sizeof(FlagRuntimeInfo); i++) { +#ifdef MS_WINDOWS_DESKTOP info.dwBuildNumber = win_runtime_flags[i].build_number; /* greater than or equal to the specified version? Compatibility Mode will not cheat VerifyVersionInfo(...) */ - if (VerifyVersionInfo( - &info, - VER_MAJORVERSION|VER_MINORVERSION|VER_BUILDNUMBER, - dwlConditionMask)) { + BOOL isSupported = VerifyVersionInfo( + &info, + VER_MAJORVERSION|VER_MINORVERSION|VER_BUILDNUMBER, + dwlConditionMask); +#else + /* note in this case 'info' is the actual OS version, whereas above + it is the version to compare against. */ + BOOL isSupported = info.dwMajorVersion > 10 || + (info.dwMajorVersion == 10 && info.dwMinorVersion > 0) || + (info.dwMajorVersion == 10 && info.dwMinorVersion == 0 && + info.dwBuildNumber >= win_runtime_flags[i].build_number); +#endif + if (isSupported) { break; } else { @@ -490,14 +512,14 @@ remove_unusable_flags(PyObject *m) #endif #endif -#ifdef MS_WINDOWS +#ifdef MS_WINDOWS_DESKTOP #define sockaddr_rc SOCKADDR_BTH_REDEF #define USE_BLUETOOTH 1 #define AF_BLUETOOTH AF_BTH #define BTPROTO_RFCOMM BTHPROTO_RFCOMM #define _BT_RC_MEMB(sa, memb) ((sa)->memb) -#endif +#endif /* MS_WINDOWS_DESKTOP */ /* Convert "sock_addr_t *" to "struct sockaddr *". */ #define SAS2SA(x) (&((x)->sa)) @@ -520,22 +542,59 @@ remove_unusable_flags(PyObject *m) #define INADDR_NONE (-1) #endif +typedef struct _socket_state { + /* The sock_type variable contains pointers to various functions, + some of which call new_sockobject(), which uses sock_type, so + there has to be a circular reference. */ + PyTypeObject *sock_type; + + /* Global variable holding the exception type for errors detected + by this module (but not argument type or memory errors, etc.). */ + PyObject *socket_herror; + PyObject *socket_gaierror; + + /* Default timeout for new sockets */ + _PyTime_t defaulttimeout; + +#if defined(HAVE_ACCEPT) || defined(HAVE_ACCEPT4) +#if defined(HAVE_ACCEPT4) && defined(SOCK_CLOEXEC) + /* accept4() is available on Linux 2.6.28+ and glibc 2.10 */ + int accept4_works; +#endif +#endif + +#ifdef SOCK_CLOEXEC + /* socket() and socketpair() fail with EINVAL on Linux kernel older + * than 2.6.27 if SOCK_CLOEXEC flag is set in the socket type. */ + int sock_cloexec_works; +#endif +} socket_state; + +static inline socket_state * +get_module_state(PyObject *mod) +{ + void *state = _PyModule_GetState(mod); + assert(state != NULL); + return (socket_state *)state; +} + +static struct PyModuleDef socketmodule; + +static inline socket_state * +find_module_state_by_def(PyTypeObject *type) +{ + PyObject *mod = PyType_GetModuleByDef(type, &socketmodule); + assert(mod != NULL); + return get_module_state(mod); +} + +#define clinic_state() (find_module_state_by_def(type)) #include "clinic/socketmodule.c.h" +#undef clinic_state /* XXX There's a problem here: *static* functions are not supposed to have a Py prefix (or use CapitalizedWords). Later... */ -/* Global variable holding the exception type for errors detected - by this module (but not argument type or memory errors, etc.). */ -static PyObject *socket_herror; -static PyObject *socket_gaierror; - -/* A forward reference to the socket type object. - The sock_type variable contains pointers to various functions, - some of which call new_sockobject(), which uses sock_type, so - there has to be a circular reference. */ -static PyTypeObject sock_type; - #if defined(HAVE_POLL_H) #include <poll.h> #elif defined(HAVE_SYS_POLL_H) @@ -599,11 +658,6 @@ select_error(void) # define SUPPRESS_DEPRECATED_CALL #endif -#ifdef MS_WINDOWS -/* Does WSASocket() support the WSA_FLAG_NO_HANDLE_INHERIT flag? */ -static int support_wsa_no_inherit = -1; -#endif - /* Convenience function to raise an error according to errno and return a NULL pointer from a function. */ @@ -625,7 +679,7 @@ set_error(void) #if defined(HAVE_GETHOSTBYNAME_R) || defined (HAVE_GETHOSTBYNAME) || defined (HAVE_GETHOSTBYADDR) static PyObject * -set_herror(int h_error) +set_herror(socket_state *state, int h_error) { PyObject *v; @@ -635,7 +689,7 @@ set_herror(int h_error) v = Py_BuildValue("(is)", h_error, "host not found"); #endif if (v != NULL) { - PyErr_SetObject(socket_herror, v); + PyErr_SetObject(state->socket_herror, v); Py_DECREF(v); } @@ -646,7 +700,7 @@ set_herror(int h_error) #ifdef HAVE_GETADDRINFO static PyObject * -set_gaierror(int error) +set_gaierror(socket_state *state, int error) { PyObject *v; @@ -662,7 +716,7 @@ set_gaierror(int error) v = Py_BuildValue("(is)", error, "getaddrinfo failed"); #endif if (v != NULL) { - PyErr_SetObject(socket_gaierror, v); + PyErr_SetObject(state->socket_gaierror, v); Py_DECREF(v); } @@ -975,11 +1029,8 @@ sock_call(PySocketSockObject *s, /* Initialize a new socket object. */ -/* Default timeout for new sockets */ -static _PyTime_t defaulttimeout = _PYTIME_FROMSECONDS(-1); - static int -init_sockobject(PySocketSockObject *s, +init_sockobject(socket_state *state, PySocketSockObject *s, SOCKET_T fd, int family, int type, int proto) { s->sock_fd = fd; @@ -1009,13 +1060,14 @@ init_sockobject(PySocketSockObject *s, else #endif { - s->sock_timeout = defaulttimeout; - if (defaulttimeout >= 0) { + s->sock_timeout = state->defaulttimeout; + if (state->defaulttimeout >= 0) { if (internal_setblocking(s, 0) == -1) { return -1; } } } + s->state = state; return 0; } @@ -1027,14 +1079,15 @@ init_sockobject(PySocketSockObject *s, in NEWOBJ()). */ static PySocketSockObject * -new_sockobject(SOCKET_T fd, int family, int type, int proto) +new_sockobject(socket_state *state, SOCKET_T fd, int family, int type, + int proto) { - PySocketSockObject *s; - s = (PySocketSockObject *) - PyType_GenericNew(&sock_type, NULL, NULL); - if (s == NULL) + PyTypeObject *tp = state->sock_type; + PySocketSockObject *s = (PySocketSockObject *)tp->tp_alloc(tp, 0); + if (s == NULL) { return NULL; - if (init_sockobject(s, fd, family, type, proto) == -1) { + } + if (init_sockobject(state, s, fd, family, type, proto) == -1) { Py_DECREF(s); return NULL; } @@ -1058,7 +1111,8 @@ static PyThread_type_lock netdb_lock; an error occurred; then an exception is raised. */ static int -setipaddr(const char *name, struct sockaddr *addr_ret, size_t addr_ret_size, int af) +setipaddr(socket_state *state, const char *name, struct sockaddr *addr_ret, + size_t addr_ret_size, int af) { struct addrinfo hints, *res; int error; @@ -1079,7 +1133,7 @@ setipaddr(const char *name, struct sockaddr *addr_ret, size_t addr_ret_size, int outcome of the first call. */ if (error) { res = NULL; // no-op, remind us that it is invalid; gh-100795 - set_gaierror(error); + set_gaierror(state, error); return -1; } switch (res->ai_family) { @@ -1190,7 +1244,7 @@ setipaddr(const char *name, struct sockaddr *addr_ret, size_t addr_ret_size, int Py_END_ALLOW_THREADS if (error) { res = NULL; // no-op, remind us that it is invalid; gh-100795 - set_gaierror(error); + set_gaierror(state, error); return -1; } if (res->ai_addrlen < addr_ret_size) @@ -1285,8 +1339,6 @@ setbdaddr(const char *name, bdaddr_t *bdaddr) static PyObject * makebdaddr(bdaddr_t *bdaddr) { - char buf[(6 * 2) + 5 + 1]; - #ifdef MS_WINDOWS int i; unsigned int octets[6]; @@ -1295,16 +1347,14 @@ makebdaddr(bdaddr_t *bdaddr) octets[i] = ((*bdaddr) >> (8 * i)) & 0xFF; } - sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X", + return PyUnicode_FromFormat("%02X:%02X:%02X:%02X:%02X:%02X", octets[5], octets[4], octets[3], octets[2], octets[1], octets[0]); #else - sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X", + return PyUnicode_FromFormat("%02X:%02X:%02X:%02X:%02X:%02X", bdaddr->b[5], bdaddr->b[4], bdaddr->b[3], bdaddr->b[2], bdaddr->b[1], bdaddr->b[0]); #endif - - return PyUnicode_FromString(buf); } #endif @@ -1591,6 +1641,35 @@ makesockaddr(SOCKET_T sockfd, struct sockaddr *addr, size_t addrlen, int proto) } #endif /* HAVE_SOCKADDR_ALG */ +#ifdef HAVE_AF_HYPERV + case AF_HYPERV: + { + SOCKADDR_HV *a = (SOCKADDR_HV *) addr; + + wchar_t *guidStr; + RPC_STATUS res = UuidToStringW(&a->VmId, &guidStr); + if (res != RPC_S_OK) { + PyErr_SetFromWindowsErr(res); + return 0; + } + PyObject *vmId = PyUnicode_FromWideChar(guidStr, -1); + res = RpcStringFreeW(&guidStr); + assert(res == RPC_S_OK); + + res = UuidToStringW(&a->ServiceId, &guidStr); + if (res != RPC_S_OK) { + Py_DECREF(vmId); + PyErr_SetFromWindowsErr(res); + return 0; + } + PyObject *serviceId = PyUnicode_FromWideChar(guidStr, -1); + res = RpcStringFreeW(&guidStr); + assert(res == RPC_S_OK); + + return Py_BuildValue("NN", vmId, serviceId); + } +#endif /* AF_HYPERV */ + /* More cases here... */ default: @@ -1820,6 +1899,11 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, /* RDS sockets use sockaddr_in: fall-through */ #endif /* AF_RDS */ +#ifdef AF_DIVERT + case AF_DIVERT: + /* FreeBSD divert(4) sockets use sockaddr_in: fall-through */ +#endif /* AF_DIVERT */ + case AF_INET: { struct maybe_idna host = {NULL, NULL}; @@ -1844,7 +1928,7 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, return 0; } struct sockaddr_in* addr = &addrbuf->in; - result = setipaddr(host.buf, (struct sockaddr *)addr, + result = setipaddr(s->state, host.buf, (struct sockaddr *)addr, sizeof(*addr), AF_INET); idna_cleanup(&host); if (result < 0) @@ -1889,7 +1973,7 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, return 0; } struct sockaddr_in6* addr = &addrbuf->in6; - result = setipaddr(host.buf, (struct sockaddr *)addr, + result = setipaddr(s->state, host.buf, (struct sockaddr *)addr, sizeof(*addr), AF_INET6); idna_cleanup(&host); if (result < 0) @@ -2390,6 +2474,76 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, return 1; } #endif /* HAVE_SOCKADDR_ALG */ +#ifdef HAVE_AF_HYPERV + case AF_HYPERV: + { + switch (s->sock_proto) { + case HV_PROTOCOL_RAW: + { + PyObject *vm_id_obj = NULL; + PyObject *service_id_obj = NULL; + + SOCKADDR_HV *addr = &addrbuf->hv; + + memset(addr, 0, sizeof(*addr)); + addr->Family = AF_HYPERV; + + if (!PyTuple_Check(args)) { + PyErr_Format(PyExc_TypeError, + "%s(): AF_HYPERV address must be tuple, not %.500s", + caller, Py_TYPE(args)->tp_name); + return 0; + } + if (!PyArg_ParseTuple(args, + "UU;AF_HYPERV address must be a str tuple (vm_id, service_id)", + &vm_id_obj, &service_id_obj)) + { + return 0; + } + + wchar_t *guid_str = PyUnicode_AsWideCharString(vm_id_obj, NULL); + if (guid_str == NULL) { + PyErr_Format(PyExc_ValueError, + "%s(): AF_HYPERV address vm_id is not a valid UUID string", + caller); + return 0; + } + RPC_STATUS rc = UuidFromStringW(guid_str, &addr->VmId); + PyMem_Free(guid_str); + if (rc != RPC_S_OK) { + PyErr_Format(PyExc_ValueError, + "%s(): AF_HYPERV address vm_id is not a valid UUID string", + caller); + return 0; + } + + guid_str = PyUnicode_AsWideCharString(service_id_obj, NULL); + if (guid_str == NULL) { + PyErr_Format(PyExc_ValueError, + "%s(): AF_HYPERV address service_id is not a valid UUID string", + caller); + return 0; + } + rc = UuidFromStringW(guid_str, &addr->ServiceId); + PyMem_Free(guid_str); + if (rc != RPC_S_OK) { + PyErr_Format(PyExc_ValueError, + "%s(): AF_HYPERV address service_id is not a valid UUID string", + caller); + return 0; + } + + *len_ret = sizeof(*addr); + return 1; + } + default: + PyErr_Format(PyExc_OSError, + "%s(): unsupported AF_HYPERV protocol: %d", + caller, s->sock_proto); + return 0; + } + } +#endif /* HAVE_AF_HYPERV */ /* More cases here... */ @@ -2540,6 +2694,13 @@ getsockaddrlen(PySocketSockObject *s, socklen_t *len_ret) return 1; } #endif /* HAVE_SOCKADDR_ALG */ +#ifdef HAVE_AF_HYPERV + case AF_HYPERV: + { + *len_ret = sizeof (SOCKADDR_HV); + return 1; + } +#endif /* HAVE_AF_HYPERV */ /* More cases here... */ @@ -2691,10 +2852,6 @@ struct sock_accept { }; #if defined(HAVE_ACCEPT) || defined(HAVE_ACCEPT4) -#if defined(HAVE_ACCEPT4) && defined(SOCK_CLOEXEC) -/* accept4() is available on Linux 2.6.28+ and glibc 2.10 */ -static int accept4_works = -1; -#endif static int sock_accept_impl(PySocketSockObject *s, void *data) @@ -2713,15 +2870,16 @@ sock_accept_impl(PySocketSockObject *s, void *data) #endif #if defined(HAVE_ACCEPT4) && defined(SOCK_CLOEXEC) - if (accept4_works != 0) { + socket_state *state = s->state; + if (state->accept4_works != 0) { ctx->result = accept4(s->sock_fd, addr, paddrlen, SOCK_CLOEXEC); - if (ctx->result == INVALID_SOCKET && accept4_works == -1) { + if (ctx->result == INVALID_SOCKET && state->accept4_works == -1) { /* On Linux older than 2.6.28, accept4() fails with ENOSYS */ - accept4_works = (errno != ENOSYS); + state->accept4_works = (errno != ENOSYS); } } - if (accept4_works == 0) + if (state->accept4_works == 0) ctx->result = accept(s->sock_fd, addr, paddrlen); #else ctx->result = accept(s->sock_fd, addr, paddrlen); @@ -2761,15 +2919,21 @@ sock_accept(PySocketSockObject *s, PyObject *Py_UNUSED(ignored)) newfd = ctx.result; #ifdef MS_WINDOWS +#if defined(MS_WINDOWS_APP) || defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) +#ifndef HANDLE_FLAG_INHERIT +#define HANDLE_FLAG_INHERIT 0x00000001 +#endif if (!SetHandleInformation((HANDLE)newfd, HANDLE_FLAG_INHERIT, 0)) { PyErr_SetFromWindowsErr(0); SOCKETCLOSE(newfd); goto finally; } +#endif #else #if defined(HAVE_ACCEPT4) && defined(SOCK_CLOEXEC) - if (!accept4_works) + socket_state *state = s->state; + if (!state->accept4_works) #endif { if (_Py_set_inheritable(newfd, 0, NULL) < 0) { @@ -2817,8 +2981,8 @@ sock_setblocking(PySocketSockObject *s, PyObject *arg) { long block; - block = PyLong_AsLong(arg); - if (block == -1 && PyErr_Occurred()) + block = PyObject_IsTrue(arg); + if (block < 0) return NULL; s->sock_timeout = _PyTime_FromSeconds(block ? -1 : 0); @@ -3411,7 +3575,8 @@ PyDoc_STRVAR(getsockname_doc, \n\ Return the address of the local endpoint. The format depends on the\n\ address family. For IPv4 sockets, the address info is a pair\n\ -(hostaddr, port)."); +(hostaddr, port). For IPv6 sockets, the address info is a 4-tuple\n\ +(hostaddr, port, flowinfo, scope_id)."); #endif @@ -3999,8 +4164,7 @@ makeval_recvmsg(ssize_t received, void *data) if (received < PyBytes_GET_SIZE(*buf)) _PyBytes_Resize(buf, received); - Py_XINCREF(*buf); - return *buf; + return Py_XNewRef(*buf); } /* s.recvmsg(bufsize[, ancbufsize[, flags]]) method */ @@ -4279,8 +4443,7 @@ sock_sendall(PySocketSockObject *s, PyObject *args) } while (len > 0); PyBuffer_Release(&pbuf); - Py_INCREF(Py_None); - res = Py_None; + res = Py_NewRef(Py_None); done: PyBuffer_Release(&pbuf); @@ -5064,10 +5227,9 @@ static void sock_finalize(PySocketSockObject *s) { SOCKET_T fd; - PyObject *error_type, *error_value, *error_traceback; /* Save the current exception, if any. */ - PyErr_Fetch(&error_type, &error_value, &error_traceback); + PyObject *exc = PyErr_GetRaisedException(); if (s->sock_fd != INVALID_SOCKET) { if (PyErr_ResourceWarning((PyObject *)s, 1, "unclosed %R", s)) { @@ -5091,16 +5253,26 @@ sock_finalize(PySocketSockObject *s) } /* Restore the saved exception. */ - PyErr_Restore(error_type, error_value, error_traceback); + PyErr_SetRaisedException(exc); +} + +static int +sock_traverse(PySocketSockObject *s, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(s)); + return 0; } static void sock_dealloc(PySocketSockObject *s) { - if (PyObject_CallFinalizerFromDealloc((PyObject *)s) < 0) + if (PyObject_CallFinalizerFromDealloc((PyObject *)s) < 0) { return; - - Py_TYPE(s)->tp_free((PyObject *)s); + } + PyTypeObject *tp = Py_TYPE(s); + PyObject_GC_UnTrack(s); + tp->tp_free((PyObject *)s); + Py_DECREF(tp); } @@ -5152,12 +5324,6 @@ sock_new(PyTypeObject *type, PyObject *args, PyObject *kwds) /* Initialize a new socket object. */ -#ifdef SOCK_CLOEXEC -/* socket() and socketpair() fail with EINVAL on Linux kernel older - * than 2.6.27 if SOCK_CLOEXEC flag is set in the socket type. */ -static int sock_cloexec_works = -1; -#endif - /*ARGSUSED*/ #ifndef HAVE_SOCKET @@ -5185,10 +5351,11 @@ sock_initobj_impl(PySocketSockObject *self, int family, int type, int proto, { SOCKET_T fd = INVALID_SOCKET; + socket_state *state = find_module_state_by_def(Py_TYPE(self)); #ifndef MS_WINDOWS #ifdef SOCK_CLOEXEC - int *atomic_flag_works = &sock_cloexec_works; + int *atomic_flag_works = &state->sock_cloexec_works; #else int *atomic_flag_works = NULL; #endif @@ -5232,6 +5399,13 @@ sock_initobj_impl(PySocketSockObject *self, int family, int type, int proto, set_error(); return -1; } + + if (!SetHandleInformation((HANDLE)fd, HANDLE_FLAG_INHERIT, 0)) { + PyErr_SetFromWindowsErr(0); + closesocket(fd); + return -1; + } + family = info.iAddressFamily; type = info.iSocketType; proto = info.iProtocol; @@ -5322,52 +5496,29 @@ sock_initobj_impl(PySocketSockObject *self, int family, int type, int proto, proto = 0; } #ifdef MS_WINDOWS - /* Windows implementation */ -#ifndef WSA_FLAG_NO_HANDLE_INHERIT -#define WSA_FLAG_NO_HANDLE_INHERIT 0x80 -#endif - Py_BEGIN_ALLOW_THREADS - if (support_wsa_no_inherit) { - fd = WSASocketW(family, type, proto, - NULL, 0, - WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT); - if (fd == INVALID_SOCKET) { - /* Windows 7 or Windows 2008 R2 without SP1 or the hotfix */ - support_wsa_no_inherit = 0; - fd = socket(family, type, proto); - } - } - else { - fd = socket(family, type, proto); - } + fd = WSASocketW(family, type, proto, + NULL, 0, + WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT); Py_END_ALLOW_THREADS if (fd == INVALID_SOCKET) { set_error(); return -1; } - - if (!support_wsa_no_inherit) { - if (!SetHandleInformation((HANDLE)fd, HANDLE_FLAG_INHERIT, 0)) { - closesocket(fd); - PyErr_SetFromWindowsErr(0); - return -1; - } - } #else /* UNIX */ Py_BEGIN_ALLOW_THREADS #ifdef SOCK_CLOEXEC - if (sock_cloexec_works != 0) { + if (state->sock_cloexec_works != 0) { fd = socket(family, type | SOCK_CLOEXEC, proto); - if (sock_cloexec_works == -1) { + if (state->sock_cloexec_works == -1) { if (fd >= 0) { - sock_cloexec_works = 1; + state->sock_cloexec_works = 1; } else if (errno == EINVAL) { /* Linux older than 2.6.27 does not support SOCK_CLOEXEC */ - sock_cloexec_works = 0; + state->sock_cloexec_works = 0; fd = socket(family, type, proto); } } @@ -5390,7 +5541,7 @@ sock_initobj_impl(PySocketSockObject *self, int family, int type, int proto, } #endif } - if (init_sockobject(self, fd, family, type, proto) == -1) { + if (init_sockobject(state, self, fd, family, type, proto) == -1) { SOCKETCLOSE(fd); return -1; } @@ -5402,55 +5553,26 @@ sock_initobj_impl(PySocketSockObject *self, int family, int type, int proto, /* Type object for socket objects. */ -static PyTypeObject sock_type = { - PyVarObject_HEAD_INIT(0, 0) /* Must fill in type value later */ - "_socket.socket", /* tp_name */ - sizeof(PySocketSockObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)sock_dealloc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - (reprfunc)sock_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - sock_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - sock_methods, /* tp_methods */ - sock_memberlist, /* tp_members */ - sock_getsetlist, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - sock_initobj, /* tp_init */ - PyType_GenericAlloc, /* tp_alloc */ - sock_new, /* tp_new */ - PyObject_Del, /* tp_free */ - 0, /* tp_is_gc */ - 0, /* tp_bases */ - 0, /* tp_mro */ - 0, /* tp_cache */ - 0, /* tp_subclasses */ - 0, /* tp_weaklist */ - 0, /* tp_del */ - 0, /* tp_version_tag */ - (destructor)sock_finalize, /* tp_finalize */ +static PyType_Slot sock_slots[] = { + {Py_tp_dealloc, sock_dealloc}, + {Py_tp_traverse, sock_traverse}, + {Py_tp_repr, sock_repr}, + {Py_tp_doc, (void *)sock_doc}, + {Py_tp_methods, sock_methods}, + {Py_tp_members, sock_memberlist}, + {Py_tp_getset, sock_getsetlist}, + {Py_tp_init, sock_initobj}, + {Py_tp_new, sock_new}, + {Py_tp_finalize, sock_finalize}, + {0, NULL}, +}; + +static PyType_Spec sock_spec = { + .name = "_socket.socket", + .basicsize = sizeof(PySocketSockObject), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_IMMUTABLETYPE), + .slots = sock_slots, }; @@ -5494,8 +5616,9 @@ socket_gethostname(PyObject *self, PyObject *unused) name, &size)) { + PyErr_SetFromWindowsErr(0); PyMem_Free(name); - return PyErr_SetFromWindowsErr(0); + return NULL; } result = PyUnicode_FromWideChar(name, size); @@ -5578,8 +5701,12 @@ socket_gethostbyname(PyObject *self, PyObject *args) if (PySys_Audit("socket.gethostbyname", "O", args) < 0) { goto finally; } - if (setipaddr(name, (struct sockaddr *)&addrbuf, sizeof(addrbuf), AF_INET) < 0) + socket_state *state = get_module_state(self); + int rc = setipaddr(state, name, (struct sockaddr *)&addrbuf, + sizeof(addrbuf), AF_INET); + if (rc < 0) { goto finally; + } ret = make_ipv4_addr(&addrbuf); finally: PyMem_Free(name); @@ -5610,7 +5737,8 @@ sock_decode_hostname(const char *name) /* Convenience function common to gethostbyname_ex and gethostbyaddr */ static PyObject * -gethost_common(struct hostent *h, struct sockaddr *addr, size_t alen, int af) +gethost_common(socket_state *state, struct hostent *h, struct sockaddr *addr, + size_t alen, int af) { char **pch; PyObject *rtn_tuple = (PyObject *)NULL; @@ -5621,7 +5749,7 @@ gethost_common(struct hostent *h, struct sockaddr *addr, size_t alen, int af) if (h == NULL) { /* Let's get real error message to return */ - set_herror(h_errno); + set_herror(state, h_errno); return NULL; } @@ -5656,9 +5784,15 @@ gethost_common(struct hostent *h, struct sockaddr *addr, size_t alen, int af) /* SF #1511317: h_aliases can be NULL */ if (h->h_aliases) { - for (pch = h->h_aliases; *pch != NULL; pch++) { + for (pch = h->h_aliases; ; pch++) { int status; - tmp = PyUnicode_FromString(*pch); + char *host_alias; + // pch can be misaligned + memcpy(&host_alias, pch, sizeof(host_alias)); + if (host_alias == NULL) { + break; + } + tmp = PyUnicode_FromString(host_alias); if (tmp == NULL) goto err; @@ -5670,8 +5804,14 @@ gethost_common(struct hostent *h, struct sockaddr *addr, size_t alen, int af) } } - for (pch = h->h_addr_list; *pch != NULL; pch++) { + for (pch = h->h_addr_list; ; pch++) { int status; + char *host_address; + // pch can be misaligned + memcpy(&host_address, pch, sizeof(host_address)); + if (host_address == NULL) { + break; + } switch (af) { @@ -5683,7 +5823,7 @@ gethost_common(struct hostent *h, struct sockaddr *addr, size_t alen, int af) #ifdef HAVE_SOCKADDR_SA_LEN sin.sin_len = sizeof(sin); #endif - memcpy(&sin.sin_addr, *pch, sizeof(sin.sin_addr)); + memcpy(&sin.sin_addr, host_address, sizeof(sin.sin_addr)); tmp = make_ipv4_addr(&sin); if (pch == h->h_addr_list && alen >= sizeof(sin)) @@ -5700,7 +5840,7 @@ gethost_common(struct hostent *h, struct sockaddr *addr, size_t alen, int af) #ifdef HAVE_SOCKADDR_SA_LEN sin6.sin6_len = sizeof(sin6); #endif - memcpy(&sin6.sin6_addr, *pch, sizeof(sin6.sin6_addr)); + memcpy(&sin6.sin6_addr, host_address, sizeof(sin6.sin6_addr)); tmp = make_ipv6_addr(&sin6); if (pch == h->h_addr_list && alen >= sizeof(sin6)) @@ -5768,8 +5908,10 @@ socket_gethostbyname_ex(PyObject *self, PyObject *args) if (PySys_Audit("socket.gethostbyname", "O", args) < 0) { goto finally; } - if (setipaddr(name, SAS2SA(&addr), sizeof(addr), AF_INET) < 0) + socket_state *state = get_module_state(self); + if (setipaddr(state, name, SAS2SA(&addr), sizeof(addr), AF_INET) < 0) { goto finally; + } Py_BEGIN_ALLOW_THREADS #ifdef HAVE_GETHOSTBYNAME_R #if defined(HAVE_GETHOSTBYNAME_R_6_ARG) @@ -5795,7 +5937,7 @@ socket_gethostbyname_ex(PyObject *self, PyObject *args) Therefore, we cast the sockaddr_storage into sockaddr to access sa_family. */ sa = SAS2SA(&addr); - ret = gethost_common(h, SAS2SA(&addr), sizeof(addr), + ret = gethost_common(state, h, SAS2SA(&addr), sizeof(addr), sa->sa_family); #ifdef USE_GETHOSTBYNAME_LOCK PyThread_release_lock(netdb_lock); @@ -5851,8 +5993,10 @@ socket_gethostbyaddr(PyObject *self, PyObject *args) goto finally; } af = AF_UNSPEC; - if (setipaddr(ip_num, sa, sizeof(addr), af) < 0) + socket_state *state = get_module_state(self); + if (setipaddr(state, ip_num, sa, sizeof(addr), af) < 0) { goto finally; + } af = sa->sa_family; ap = NULL; /* al = 0; */ @@ -5893,7 +6037,7 @@ socket_gethostbyaddr(PyObject *self, PyObject *args) h = gethostbyaddr(ap, al, af); #endif /* HAVE_GETHOSTBYNAME_R */ Py_END_ALLOW_THREADS - ret = gethost_common(h, SAS2SA(&addr), sizeof(addr), af); + ret = gethost_common(state, h, SAS2SA(&addr), sizeof(addr), af); #ifdef USE_GETHOSTBYNAME_LOCK PyThread_release_lock(netdb_lock); #endif @@ -6056,8 +6200,9 @@ socket_dup(PyObject *self, PyObject *fdobj) #endif fd = PyLong_AsSocket_t(fdobj); - if (fd == (SOCKET_T)(-1) && PyErr_Occurred()) + if (fd == (SOCKET_T)(-1) && PyErr_Occurred()) { return NULL; + } #ifdef MS_WINDOWS if (WSADuplicateSocketW(fd, GetCurrentProcessId(), &info)) @@ -6066,24 +6211,27 @@ socket_dup(PyObject *self, PyObject *fdobj) newfd = WSASocketW(FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO, &info, 0, WSA_FLAG_OVERLAPPED); - if (newfd == INVALID_SOCKET) + if (newfd == INVALID_SOCKET) { return set_error(); + } if (!SetHandleInformation((HANDLE)newfd, HANDLE_FLAG_INHERIT, 0)) { - closesocket(newfd); PyErr_SetFromWindowsErr(0); + closesocket(newfd); return NULL; } #else /* On UNIX, dup can be used to duplicate the file descriptor of a socket */ newfd = _Py_dup(fd); - if (newfd == INVALID_SOCKET) + if (newfd == INVALID_SOCKET) { return NULL; + } #endif newfdobj = PyLong_FromSocket_t(newfd); - if (newfdobj == NULL) + if (newfdobj == NULL) { SOCKETCLOSE(newfd); + } return newfdobj; } @@ -6108,8 +6256,9 @@ socket_socketpair(PyObject *self, PyObject *args) SOCKET_T sv[2]; int family, type = SOCK_STREAM, proto = 0; PyObject *res = NULL; + socket_state *state = get_module_state(self); #ifdef SOCK_CLOEXEC - int *atomic_flag_works = &sock_cloexec_works; + int *atomic_flag_works = &state->sock_cloexec_works; #else int *atomic_flag_works = NULL; #endif @@ -6127,15 +6276,15 @@ socket_socketpair(PyObject *self, PyObject *args) /* Create a pair of socket fds */ Py_BEGIN_ALLOW_THREADS #ifdef SOCK_CLOEXEC - if (sock_cloexec_works != 0) { + if (state->sock_cloexec_works != 0) { ret = socketpair(family, type | SOCK_CLOEXEC, proto, sv); - if (sock_cloexec_works == -1) { + if (state->sock_cloexec_works == -1) { if (ret >= 0) { - sock_cloexec_works = 1; + state->sock_cloexec_works = 1; } else if (errno == EINVAL) { /* Linux older than 2.6.27 does not support SOCK_CLOEXEC */ - sock_cloexec_works = 0; + state->sock_cloexec_works = 0; ret = socketpair(family, type, proto, sv); } } @@ -6155,10 +6304,10 @@ socket_socketpair(PyObject *self, PyObject *args) if (_Py_set_inheritable(sv[1], 0, atomic_flag_works) < 0) goto finally; - s0 = new_sockobject(sv[0], family, type, proto); + s0 = new_sockobject(state, sv[0], family, type, proto); if (s0 == NULL) goto finally; - s1 = new_sockobject(sv[1], family, type, proto); + s1 = new_sockobject(state, sv[1], family, type, proto); if (s1 == NULL) goto finally; res = PyTuple_Pack(2, s0, s1); @@ -6515,11 +6664,12 @@ socket_inet_ntop(PyObject *self, PyObject *args) /* inet_ntop guarantee NUL-termination of resulting string. */ retval = inet_ntop(af, packed_ip.buf, ip, sizeof(ip)); - PyBuffer_Release(&packed_ip); if (!retval) { PyErr_SetFromErrno(PyExc_OSError); + PyBuffer_Release(&packed_ip); return NULL; } else { + PyBuffer_Release(&packed_ip); return PyUnicode_FromString(retval); } } @@ -6539,7 +6689,7 @@ socket_getaddrinfo(PyObject *self, PyObject *args, PyObject* kwargs) struct addrinfo *res0 = NULL; PyObject *hobj = NULL; PyObject *pobj = (PyObject *)NULL; - char pbuf[30]; + PyObject *pstr = NULL; const char *hptr, *pptr; int family, socktype, protocol, flags; int error; @@ -6569,11 +6719,13 @@ socket_getaddrinfo(PyObject *self, PyObject *args, PyObject* kwargs) return NULL; } if (PyLong_CheckExact(pobj)) { - long value = PyLong_AsLong(pobj); - if (value == -1 && PyErr_Occurred()) + pstr = PyObject_Str(pobj); + if (pstr == NULL) + goto err; + assert(PyUnicode_Check(pstr)); + pptr = PyUnicode_AsUTF8(pstr); + if (pptr == NULL) goto err; - PyOS_snprintf(pbuf, sizeof(pbuf), "%ld", value); - pptr = pbuf; } else if (PyUnicode_Check(pobj)) { pptr = PyUnicode_AsUTF8(pobj); if (pptr == NULL) @@ -6611,7 +6763,8 @@ socket_getaddrinfo(PyObject *self, PyObject *args, PyObject* kwargs) Py_END_ALLOW_THREADS if (error) { res0 = NULL; // gh-100795 - set_gaierror(error); + socket_state *state = get_module_state(self); + set_gaierror(state, error); goto err; } @@ -6639,12 +6792,14 @@ socket_getaddrinfo(PyObject *self, PyObject *args, PyObject* kwargs) Py_DECREF(single); } Py_XDECREF(idna); + Py_XDECREF(pstr); if (res0) freeaddrinfo(res0); return all; err: Py_XDECREF(all); Py_XDECREF(idna); + Py_XDECREF(pstr); if (res0) freeaddrinfo(res0); return (PyObject *)NULL; @@ -6708,7 +6863,8 @@ socket_getnameinfo(PyObject *self, PyObject *args) Py_END_ALLOW_THREADS if (error) { res = NULL; // gh-100795 - set_gaierror(error); + socket_state *state = get_module_state(self); + set_gaierror(state, error); goto fail; } if (res->ai_next) { @@ -6737,10 +6893,13 @@ socket_getnameinfo(PyObject *self, PyObject *args) } #endif } + Py_BEGIN_ALLOW_THREADS error = getnameinfo(res->ai_addr, (socklen_t) res->ai_addrlen, hbuf, sizeof(hbuf), pbuf, sizeof(pbuf), flags); + Py_END_ALLOW_THREADS if (error) { - set_gaierror(error); + socket_state *state = get_module_state(self); + set_gaierror(state, error); goto fail; } @@ -6766,11 +6925,12 @@ Get host and port for a sockaddr."); static PyObject * socket_getdefaulttimeout(PyObject *self, PyObject *Py_UNUSED(ignored)) { - if (defaulttimeout < 0) { + socket_state *state = get_module_state(self); + if (state->defaulttimeout < 0) { Py_RETURN_NONE; } else { - double seconds = _PyTime_AsSecondsDouble(defaulttimeout); + double seconds = _PyTime_AsSecondsDouble(state->defaulttimeout); return PyFloat_FromDouble(seconds); } } @@ -6790,7 +6950,8 @@ socket_setdefaulttimeout(PyObject *self, PyObject *arg) if (socket_parse_timeout(&timeout, arg) < 0) return NULL; - defaulttimeout = timeout; + socket_state *state = get_module_state(self); + state->defaulttimeout = timeout; Py_RETURN_NONE; } @@ -6847,8 +7008,8 @@ socket_if_nameindex(PyObject *self, PyObject *arg) ni = if_nameindex(); if (ni == NULL) { - Py_DECREF(list); PyErr_SetFromErrno(PyExc_OSError); + Py_DECREF(list); return NULL; } @@ -7176,7 +7337,7 @@ sock_destroy_api(PyObject *capsule) } static PySocketModule_APIObject * -sock_get_api(void) +sock_get_api(socket_state *state) { PySocketModule_APIObject *capi = PyMem_Malloc(sizeof(PySocketModule_APIObject)); if (capi == NULL) { @@ -7184,7 +7345,7 @@ sock_get_api(void) return NULL; } - capi->Sock_Type = (PyTypeObject *)Py_NewRef(&sock_type); + capi->Sock_Type = (PyTypeObject *)Py_NewRef(state->sock_type); capi->error = Py_NewRef(PyExc_OSError); capi->timeout_error = Py_NewRef(PyExc_TimeoutError); return capi; @@ -7206,1314 +7367,1459 @@ PyDoc_STRVAR(socket_doc, \n\ See the socket module for documentation."); -static struct PyModuleDef socketmodule = { - PyModuleDef_HEAD_INIT, - PySocket_MODULE_NAME, - socket_doc, - -1, - socket_methods, - NULL, - NULL, - NULL, - NULL -}; - -PyMODINIT_FUNC -PyInit__socket(void) +static int +socket_exec(PyObject *m) { - PyObject *m, *has_ipv6; + if (!os_init()) { + goto error; + } - if (!os_init()) - return NULL; + socket_state *state = get_module_state(m); + state->defaulttimeout = _PYTIME_FROMSECONDS(-1); -#ifdef MS_WINDOWS - if (support_wsa_no_inherit == -1) { - support_wsa_no_inherit = IsWindows7SP1OrGreater(); - } +#if defined(HAVE_ACCEPT) || defined(HAVE_ACCEPT4) +#if defined(HAVE_ACCEPT4) && defined(SOCK_CLOEXEC) + state->accept4_works = -1; +#endif #endif - Py_SET_TYPE(&sock_type, &PyType_Type); - m = PyModule_Create(&socketmodule); - if (m == NULL) - return NULL; +#ifdef SOCK_CLOEXEC + state->sock_cloexec_works = -1; +#endif - Py_INCREF(PyExc_OSError); - PyModule_AddObject(m, "error", PyExc_OSError); - socket_herror = PyErr_NewException("socket.herror", - PyExc_OSError, NULL); - if (socket_herror == NULL) - return NULL; - Py_INCREF(socket_herror); - PyModule_AddObject(m, "herror", socket_herror); - socket_gaierror = PyErr_NewException("socket.gaierror", PyExc_OSError, - NULL); - if (socket_gaierror == NULL) - return NULL; - Py_INCREF(socket_gaierror); - PyModule_AddObject(m, "gaierror", socket_gaierror); - PyModule_AddObjectRef(m, "timeout", PyExc_TimeoutError); +#define ADD_EXC(MOD, NAME, VAR, BASE) do { \ + VAR = PyErr_NewException("socket." NAME, BASE, NULL); \ + if (VAR == NULL) { \ + goto error; \ + } \ + if (PyModule_AddObjectRef(MOD, NAME, VAR) < 0) { \ + goto error; \ + } \ +} while (0) - Py_INCREF((PyObject *)&sock_type); - if (PyModule_AddObject(m, "SocketType", - (PyObject *)&sock_type) != 0) - return NULL; - Py_INCREF((PyObject *)&sock_type); - if (PyModule_AddObject(m, "socket", - (PyObject *)&sock_type) != 0) - return NULL; + ADD_EXC(m, "herror", state->socket_herror, PyExc_OSError); + ADD_EXC(m, "gaierror", state->socket_gaierror, PyExc_OSError); + +#undef ADD_EXC + + if (PyModule_AddObjectRef(m, "error", PyExc_OSError) < 0) { + goto error; + } + if (PyModule_AddObjectRef(m, "timeout", PyExc_TimeoutError) < 0) { + goto error; + } + + PyObject *sock_type = PyType_FromMetaclass(NULL, m, &sock_spec, NULL); + if (sock_type == NULL) { + goto error; + } + state->sock_type = (PyTypeObject *)sock_type; + if (PyModule_AddObjectRef(m, "SocketType", sock_type) < 0) { + goto error; + } + if (PyModule_AddType(m, state->sock_type) < 0) { + goto error; + } + PyObject *has_ipv6; #ifdef ENABLE_IPV6 has_ipv6 = Py_True; #else has_ipv6 = Py_False; #endif - Py_INCREF(has_ipv6); - PyModule_AddObject(m, "has_ipv6", has_ipv6); + if (PyModule_AddObjectRef(m, "has_ipv6", has_ipv6) < 0) { + goto error; + } /* Export C API */ - PySocketModule_APIObject *capi = sock_get_api(); + PySocketModule_APIObject *capi = sock_get_api(state); if (capi == NULL) { - Py_DECREF(m); - return NULL; + goto error; } PyObject *capsule = PyCapsule_New(capi, PySocket_CAPSULE_NAME, sock_destroy_api); if (capsule == NULL) { sock_free_api(capi); - Py_DECREF(m); - return NULL; + goto error; } - if (PyModule_AddObject(m, PySocket_CAPI_NAME, capsule) < 0) { - Py_DECREF(capsule); - Py_DECREF(m); - return NULL; + int rc = PyModule_AddObjectRef(m, PySocket_CAPI_NAME, capsule); + Py_DECREF(capsule); + if (rc < 0) { + goto error; } +#define ADD_INT_MACRO(MOD, INT) do { \ + if (PyModule_AddIntConstant(MOD, #INT, INT) < 0) { \ + goto error; \ + } \ +} while (0) + +#define ADD_INT_CONST(MOD, NAME, INT) do { \ + if (PyModule_AddIntConstant(MOD, NAME, INT) < 0) { \ + goto error; \ + } \ +} while (0) + +#define ADD_STR_CONST(MOD, NAME, STR) do { \ + if (PyModule_AddStringConstant(MOD, NAME, STR) < 0) { \ + goto error; \ + } \ +} while (0) + /* Address families (we only support AF_INET and AF_UNIX) */ #ifdef AF_UNSPEC - PyModule_AddIntMacro(m, AF_UNSPEC); + ADD_INT_MACRO(m, AF_UNSPEC); #endif - PyModule_AddIntMacro(m, AF_INET); + ADD_INT_MACRO(m, AF_INET); #if defined(AF_UNIX) - PyModule_AddIntMacro(m, AF_UNIX); + ADD_INT_MACRO(m, AF_UNIX); #endif /* AF_UNIX */ #ifdef AF_AX25 /* Amateur Radio AX.25 */ - PyModule_AddIntMacro(m, AF_AX25); + ADD_INT_MACRO(m, AF_AX25); #endif #ifdef AF_IPX - PyModule_AddIntMacro(m, AF_IPX); /* Novell IPX */ + ADD_INT_MACRO(m, AF_IPX); /* Novell IPX */ #endif #ifdef AF_APPLETALK /* Appletalk DDP */ - PyModule_AddIntMacro(m, AF_APPLETALK); + ADD_INT_MACRO(m, AF_APPLETALK); #endif #ifdef AF_NETROM /* Amateur radio NetROM */ - PyModule_AddIntMacro(m, AF_NETROM); + ADD_INT_MACRO(m, AF_NETROM); #endif #ifdef AF_BRIDGE /* Multiprotocol bridge */ - PyModule_AddIntMacro(m, AF_BRIDGE); + ADD_INT_MACRO(m, AF_BRIDGE); #endif #ifdef AF_ATMPVC /* ATM PVCs */ - PyModule_AddIntMacro(m, AF_ATMPVC); + ADD_INT_MACRO(m, AF_ATMPVC); #endif #ifdef AF_AAL5 /* Reserved for Werner's ATM */ - PyModule_AddIntMacro(m, AF_AAL5); + ADD_INT_MACRO(m, AF_AAL5); #endif #ifdef HAVE_SOCKADDR_ALG - PyModule_AddIntMacro(m, AF_ALG); /* Linux crypto */ + ADD_INT_MACRO(m, AF_ALG); /* Linux crypto */ #endif #ifdef AF_X25 /* Reserved for X.25 project */ - PyModule_AddIntMacro(m, AF_X25); + ADD_INT_MACRO(m, AF_X25); #endif #ifdef AF_INET6 - PyModule_AddIntMacro(m, AF_INET6); /* IP version 6 */ + ADD_INT_MACRO(m, AF_INET6); /* IP version 6 */ #endif #ifdef AF_ROSE /* Amateur Radio X.25 PLP */ - PyModule_AddIntMacro(m, AF_ROSE); + ADD_INT_MACRO(m, AF_ROSE); #endif #ifdef AF_DECnet /* Reserved for DECnet project */ - PyModule_AddIntMacro(m, AF_DECnet); + ADD_INT_MACRO(m, AF_DECnet); #endif #ifdef AF_NETBEUI /* Reserved for 802.2LLC project */ - PyModule_AddIntMacro(m, AF_NETBEUI); + ADD_INT_MACRO(m, AF_NETBEUI); #endif #ifdef AF_SECURITY /* Security callback pseudo AF */ - PyModule_AddIntMacro(m, AF_SECURITY); + ADD_INT_MACRO(m, AF_SECURITY); #endif #ifdef AF_KEY /* PF_KEY key management API */ - PyModule_AddIntMacro(m, AF_KEY); + ADD_INT_MACRO(m, AF_KEY); #endif #ifdef AF_NETLINK /* */ - PyModule_AddIntMacro(m, AF_NETLINK); - PyModule_AddIntMacro(m, NETLINK_ROUTE); + ADD_INT_MACRO(m, AF_NETLINK); + ADD_INT_MACRO(m, NETLINK_ROUTE); #ifdef NETLINK_SKIP - PyModule_AddIntMacro(m, NETLINK_SKIP); + ADD_INT_MACRO(m, NETLINK_SKIP); #endif #ifdef NETLINK_W1 - PyModule_AddIntMacro(m, NETLINK_W1); + ADD_INT_MACRO(m, NETLINK_W1); #endif - PyModule_AddIntMacro(m, NETLINK_USERSOCK); - PyModule_AddIntMacro(m, NETLINK_FIREWALL); + ADD_INT_MACRO(m, NETLINK_USERSOCK); + ADD_INT_MACRO(m, NETLINK_FIREWALL); #ifdef NETLINK_TCPDIAG - PyModule_AddIntMacro(m, NETLINK_TCPDIAG); + ADD_INT_MACRO(m, NETLINK_TCPDIAG); #endif #ifdef NETLINK_NFLOG - PyModule_AddIntMacro(m, NETLINK_NFLOG); + ADD_INT_MACRO(m, NETLINK_NFLOG); #endif #ifdef NETLINK_XFRM - PyModule_AddIntMacro(m, NETLINK_XFRM); + ADD_INT_MACRO(m, NETLINK_XFRM); #endif #ifdef NETLINK_ARPD - PyModule_AddIntMacro(m, NETLINK_ARPD); + ADD_INT_MACRO(m, NETLINK_ARPD); #endif #ifdef NETLINK_ROUTE6 - PyModule_AddIntMacro(m, NETLINK_ROUTE6); + ADD_INT_MACRO(m, NETLINK_ROUTE6); #endif - PyModule_AddIntMacro(m, NETLINK_IP6_FW); + ADD_INT_MACRO(m, NETLINK_IP6_FW); #ifdef NETLINK_DNRTMSG - PyModule_AddIntMacro(m, NETLINK_DNRTMSG); + ADD_INT_MACRO(m, NETLINK_DNRTMSG); #endif #ifdef NETLINK_TAPBASE - PyModule_AddIntMacro(m, NETLINK_TAPBASE); + ADD_INT_MACRO(m, NETLINK_TAPBASE); #endif #ifdef NETLINK_CRYPTO - PyModule_AddIntMacro(m, NETLINK_CRYPTO); + ADD_INT_MACRO(m, NETLINK_CRYPTO); #endif #endif /* AF_NETLINK */ #ifdef AF_QIPCRTR /* Qualcomm IPCROUTER */ - PyModule_AddIntMacro(m, AF_QIPCRTR); + ADD_INT_MACRO(m, AF_QIPCRTR); #endif #ifdef AF_VSOCK - PyModule_AddIntConstant(m, "AF_VSOCK", AF_VSOCK); - PyModule_AddIntConstant(m, "SO_VM_SOCKETS_BUFFER_SIZE", 0); - PyModule_AddIntConstant(m, "SO_VM_SOCKETS_BUFFER_MIN_SIZE", 1); - PyModule_AddIntConstant(m, "SO_VM_SOCKETS_BUFFER_MAX_SIZE", 2); - PyModule_AddIntConstant(m, "VMADDR_CID_ANY", 0xffffffff); - PyModule_AddIntConstant(m, "VMADDR_PORT_ANY", 0xffffffff); - PyModule_AddIntConstant(m, "VMADDR_CID_HOST", 2); - PyModule_AddIntConstant(m, "VM_SOCKETS_INVALID_VERSION", 0xffffffff); - PyModule_AddIntConstant(m, "IOCTL_VM_SOCKETS_GET_LOCAL_CID", _IO(7, 0xb9)); + ADD_INT_CONST(m, "AF_VSOCK", AF_VSOCK); + ADD_INT_CONST(m, "SO_VM_SOCKETS_BUFFER_SIZE", 0); + ADD_INT_CONST(m, "SO_VM_SOCKETS_BUFFER_MIN_SIZE", 1); + ADD_INT_CONST(m, "SO_VM_SOCKETS_BUFFER_MAX_SIZE", 2); + ADD_INT_CONST(m, "VMADDR_CID_ANY", 0xffffffff); + ADD_INT_CONST(m, "VMADDR_PORT_ANY", 0xffffffff); + ADD_INT_CONST(m, "VMADDR_CID_HOST", 2); + ADD_INT_CONST(m, "VM_SOCKETS_INVALID_VERSION", 0xffffffff); + ADD_INT_CONST(m, "IOCTL_VM_SOCKETS_GET_LOCAL_CID", _IO(7, 0xb9)); #endif #ifdef AF_ROUTE /* Alias to emulate 4.4BSD */ - PyModule_AddIntMacro(m, AF_ROUTE); + ADD_INT_MACRO(m, AF_ROUTE); #endif #ifdef AF_LINK - PyModule_AddIntMacro(m, AF_LINK); + ADD_INT_MACRO(m, AF_LINK); #endif #ifdef AF_ASH /* Ash */ - PyModule_AddIntMacro(m, AF_ASH); + ADD_INT_MACRO(m, AF_ASH); #endif #ifdef AF_ECONET /* Acorn Econet */ - PyModule_AddIntMacro(m, AF_ECONET); + ADD_INT_MACRO(m, AF_ECONET); #endif #ifdef AF_ATMSVC /* ATM SVCs */ - PyModule_AddIntMacro(m, AF_ATMSVC); + ADD_INT_MACRO(m, AF_ATMSVC); #endif #ifdef AF_SNA /* Linux SNA Project (nutters!) */ - PyModule_AddIntMacro(m, AF_SNA); + ADD_INT_MACRO(m, AF_SNA); #endif #ifdef AF_IRDA /* IRDA sockets */ - PyModule_AddIntMacro(m, AF_IRDA); + ADD_INT_MACRO(m, AF_IRDA); #endif #ifdef AF_PPPOX /* PPPoX sockets */ - PyModule_AddIntMacro(m, AF_PPPOX); + ADD_INT_MACRO(m, AF_PPPOX); #endif #ifdef AF_WANPIPE /* Wanpipe API Sockets */ - PyModule_AddIntMacro(m, AF_WANPIPE); + ADD_INT_MACRO(m, AF_WANPIPE); #endif #ifdef AF_LLC /* Linux LLC */ - PyModule_AddIntMacro(m, AF_LLC); + ADD_INT_MACRO(m, AF_LLC); #endif +#ifdef HAVE_AF_HYPERV + /* Hyper-V sockets */ + ADD_INT_MACRO(m, AF_HYPERV); + + /* for proto */ + ADD_INT_MACRO(m, HV_PROTOCOL_RAW); + + /* for setsockopt() */ + ADD_INT_MACRO(m, HVSOCKET_CONNECT_TIMEOUT); + ADD_INT_MACRO(m, HVSOCKET_CONNECT_TIMEOUT_MAX); + ADD_INT_MACRO(m, HVSOCKET_CONNECTED_SUSPEND); + ADD_INT_MACRO(m, HVSOCKET_ADDRESS_FLAG_PASSTHRU); + + /* for bind() or connect() */ + ADD_STR_CONST(m, "HV_GUID_ZERO", "00000000-0000-0000-0000-000000000000"); + ADD_STR_CONST(m, "HV_GUID_WILDCARD", "00000000-0000-0000-0000-000000000000"); + ADD_STR_CONST(m, "HV_GUID_BROADCAST", "FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF"); + ADD_STR_CONST(m, "HV_GUID_CHILDREN", "90DB8B89-0D35-4F79-8CE9-49EA0AC8B7CD"); + ADD_STR_CONST(m, "HV_GUID_LOOPBACK", "E0E16197-DD56-4A10-9195-5EE7A155A838"); + ADD_STR_CONST(m, "HV_GUID_PARENT", "A42E7CDA-D03F-480C-9CC2-A4DE20ABB878"); +#endif /* HAVE_AF_HYPERV */ #ifdef USE_BLUETOOTH - PyModule_AddIntMacro(m, AF_BLUETOOTH); + ADD_INT_MACRO(m, AF_BLUETOOTH); #ifdef BTPROTO_L2CAP - PyModule_AddIntMacro(m, BTPROTO_L2CAP); + ADD_INT_MACRO(m, BTPROTO_L2CAP); #endif /* BTPROTO_L2CAP */ #ifdef BTPROTO_HCI - PyModule_AddIntMacro(m, BTPROTO_HCI); - PyModule_AddIntMacro(m, SOL_HCI); + ADD_INT_MACRO(m, BTPROTO_HCI); + ADD_INT_MACRO(m, SOL_HCI); #if !defined(__NetBSD__) && !defined(__DragonFly__) - PyModule_AddIntMacro(m, HCI_FILTER); + ADD_INT_MACRO(m, HCI_FILTER); #if !defined(__FreeBSD__) - PyModule_AddIntMacro(m, HCI_TIME_STAMP); - PyModule_AddIntMacro(m, HCI_DATA_DIR); + ADD_INT_MACRO(m, HCI_TIME_STAMP); + ADD_INT_MACRO(m, HCI_DATA_DIR); #endif /* !__FreeBSD__ */ #endif /* !__NetBSD__ && !__DragonFly__ */ #endif /* BTPROTO_HCI */ #ifdef BTPROTO_RFCOMM - PyModule_AddIntMacro(m, BTPROTO_RFCOMM); + ADD_INT_MACRO(m, BTPROTO_RFCOMM); #endif /* BTPROTO_RFCOMM */ - PyModule_AddStringConstant(m, "BDADDR_ANY", "00:00:00:00:00:00"); - PyModule_AddStringConstant(m, "BDADDR_LOCAL", "00:00:00:FF:FF:FF"); + ADD_STR_CONST(m, "BDADDR_ANY", "00:00:00:00:00:00"); + ADD_STR_CONST(m, "BDADDR_LOCAL", "00:00:00:FF:FF:FF"); #ifdef BTPROTO_SCO - PyModule_AddIntMacro(m, BTPROTO_SCO); + ADD_INT_MACRO(m, BTPROTO_SCO); #endif /* BTPROTO_SCO */ #endif /* USE_BLUETOOTH */ #ifdef AF_CAN /* Controller Area Network */ - PyModule_AddIntMacro(m, AF_CAN); + ADD_INT_MACRO(m, AF_CAN); #endif #ifdef PF_CAN /* Controller Area Network */ - PyModule_AddIntMacro(m, PF_CAN); + ADD_INT_MACRO(m, PF_CAN); #endif /* Reliable Datagram Sockets */ #ifdef AF_RDS - PyModule_AddIntMacro(m, AF_RDS); + ADD_INT_MACRO(m, AF_RDS); #endif #ifdef PF_RDS - PyModule_AddIntMacro(m, PF_RDS); + ADD_INT_MACRO(m, PF_RDS); #endif /* Kernel event messages */ #ifdef PF_SYSTEM - PyModule_AddIntMacro(m, PF_SYSTEM); + ADD_INT_MACRO(m, PF_SYSTEM); #endif #ifdef AF_SYSTEM - PyModule_AddIntMacro(m, AF_SYSTEM); + ADD_INT_MACRO(m, AF_SYSTEM); +#endif + +/* FreeBSD divert(4) */ +#ifdef PF_DIVERT + PyModule_AddIntMacro(m, PF_DIVERT); +#endif +#ifdef AF_DIVERT + PyModule_AddIntMacro(m, AF_DIVERT); #endif #ifdef AF_PACKET - PyModule_AddIntMacro(m, AF_PACKET); + ADD_INT_MACRO(m, AF_PACKET); #endif #ifdef PF_PACKET - PyModule_AddIntMacro(m, PF_PACKET); + ADD_INT_MACRO(m, PF_PACKET); #endif #ifdef PACKET_HOST - PyModule_AddIntMacro(m, PACKET_HOST); + ADD_INT_MACRO(m, PACKET_HOST); #endif #ifdef PACKET_BROADCAST - PyModule_AddIntMacro(m, PACKET_BROADCAST); + ADD_INT_MACRO(m, PACKET_BROADCAST); #endif #ifdef PACKET_MULTICAST - PyModule_AddIntMacro(m, PACKET_MULTICAST); + ADD_INT_MACRO(m, PACKET_MULTICAST); #endif #ifdef PACKET_OTHERHOST - PyModule_AddIntMacro(m, PACKET_OTHERHOST); + ADD_INT_MACRO(m, PACKET_OTHERHOST); #endif #ifdef PACKET_OUTGOING - PyModule_AddIntMacro(m, PACKET_OUTGOING); + ADD_INT_MACRO(m, PACKET_OUTGOING); #endif #ifdef PACKET_LOOPBACK - PyModule_AddIntMacro(m, PACKET_LOOPBACK); + ADD_INT_MACRO(m, PACKET_LOOPBACK); #endif #ifdef PACKET_FASTROUTE - PyModule_AddIntMacro(m, PACKET_FASTROUTE); + ADD_INT_MACRO(m, PACKET_FASTROUTE); #endif #ifdef HAVE_LINUX_TIPC_H - PyModule_AddIntMacro(m, AF_TIPC); + ADD_INT_MACRO(m, AF_TIPC); /* for addresses */ - PyModule_AddIntMacro(m, TIPC_ADDR_NAMESEQ); - PyModule_AddIntMacro(m, TIPC_ADDR_NAME); - PyModule_AddIntMacro(m, TIPC_ADDR_ID); + ADD_INT_MACRO(m, TIPC_ADDR_NAMESEQ); + ADD_INT_MACRO(m, TIPC_ADDR_NAME); + ADD_INT_MACRO(m, TIPC_ADDR_ID); - PyModule_AddIntMacro(m, TIPC_ZONE_SCOPE); - PyModule_AddIntMacro(m, TIPC_CLUSTER_SCOPE); - PyModule_AddIntMacro(m, TIPC_NODE_SCOPE); + ADD_INT_MACRO(m, TIPC_ZONE_SCOPE); + ADD_INT_MACRO(m, TIPC_CLUSTER_SCOPE); + ADD_INT_MACRO(m, TIPC_NODE_SCOPE); /* for setsockopt() */ - PyModule_AddIntMacro(m, SOL_TIPC); - PyModule_AddIntMacro(m, TIPC_IMPORTANCE); - PyModule_AddIntMacro(m, TIPC_SRC_DROPPABLE); - PyModule_AddIntMacro(m, TIPC_DEST_DROPPABLE); - PyModule_AddIntMacro(m, TIPC_CONN_TIMEOUT); + ADD_INT_MACRO(m, SOL_TIPC); + ADD_INT_MACRO(m, TIPC_IMPORTANCE); + ADD_INT_MACRO(m, TIPC_SRC_DROPPABLE); + ADD_INT_MACRO(m, TIPC_DEST_DROPPABLE); + ADD_INT_MACRO(m, TIPC_CONN_TIMEOUT); - PyModule_AddIntMacro(m, TIPC_LOW_IMPORTANCE); - PyModule_AddIntMacro(m, TIPC_MEDIUM_IMPORTANCE); - PyModule_AddIntMacro(m, TIPC_HIGH_IMPORTANCE); - PyModule_AddIntMacro(m, TIPC_CRITICAL_IMPORTANCE); + ADD_INT_MACRO(m, TIPC_LOW_IMPORTANCE); + ADD_INT_MACRO(m, TIPC_MEDIUM_IMPORTANCE); + ADD_INT_MACRO(m, TIPC_HIGH_IMPORTANCE); + ADD_INT_MACRO(m, TIPC_CRITICAL_IMPORTANCE); /* for subscriptions */ - PyModule_AddIntMacro(m, TIPC_SUB_PORTS); - PyModule_AddIntMacro(m, TIPC_SUB_SERVICE); + ADD_INT_MACRO(m, TIPC_SUB_PORTS); + ADD_INT_MACRO(m, TIPC_SUB_SERVICE); #ifdef TIPC_SUB_CANCEL /* doesn't seem to be available everywhere */ - PyModule_AddIntMacro(m, TIPC_SUB_CANCEL); + ADD_INT_MACRO(m, TIPC_SUB_CANCEL); #endif - PyModule_AddIntMacro(m, TIPC_WAIT_FOREVER); - PyModule_AddIntMacro(m, TIPC_PUBLISHED); - PyModule_AddIntMacro(m, TIPC_WITHDRAWN); - PyModule_AddIntMacro(m, TIPC_SUBSCR_TIMEOUT); - PyModule_AddIntMacro(m, TIPC_CFG_SRV); - PyModule_AddIntMacro(m, TIPC_TOP_SRV); + ADD_INT_MACRO(m, TIPC_WAIT_FOREVER); + ADD_INT_MACRO(m, TIPC_PUBLISHED); + ADD_INT_MACRO(m, TIPC_WITHDRAWN); + ADD_INT_MACRO(m, TIPC_SUBSCR_TIMEOUT); + ADD_INT_MACRO(m, TIPC_CFG_SRV); + ADD_INT_MACRO(m, TIPC_TOP_SRV); #endif #ifdef HAVE_SOCKADDR_ALG /* Socket options */ - PyModule_AddIntMacro(m, ALG_SET_KEY); - PyModule_AddIntMacro(m, ALG_SET_IV); - PyModule_AddIntMacro(m, ALG_SET_OP); - PyModule_AddIntMacro(m, ALG_SET_AEAD_ASSOCLEN); - PyModule_AddIntMacro(m, ALG_SET_AEAD_AUTHSIZE); - PyModule_AddIntMacro(m, ALG_SET_PUBKEY); + ADD_INT_MACRO(m, ALG_SET_KEY); + ADD_INT_MACRO(m, ALG_SET_IV); + ADD_INT_MACRO(m, ALG_SET_OP); + ADD_INT_MACRO(m, ALG_SET_AEAD_ASSOCLEN); + ADD_INT_MACRO(m, ALG_SET_AEAD_AUTHSIZE); + ADD_INT_MACRO(m, ALG_SET_PUBKEY); /* Operations */ - PyModule_AddIntMacro(m, ALG_OP_DECRYPT); - PyModule_AddIntMacro(m, ALG_OP_ENCRYPT); - PyModule_AddIntMacro(m, ALG_OP_SIGN); - PyModule_AddIntMacro(m, ALG_OP_VERIFY); + ADD_INT_MACRO(m, ALG_OP_DECRYPT); + ADD_INT_MACRO(m, ALG_OP_ENCRYPT); + ADD_INT_MACRO(m, ALG_OP_SIGN); + ADD_INT_MACRO(m, ALG_OP_VERIFY); +#endif + +/* IEEE 802.3 protocol numbers required for a standard TCP/IP network stack */ +#ifdef ETHERTYPE_ARP + ADD_INT_MACRO(m, ETHERTYPE_ARP); +#endif +#ifdef ETHERTYPE_IP + ADD_INT_MACRO(m, ETHERTYPE_IP); +#endif +#ifdef ETHERTYPE_IPV6 + ADD_INT_MACRO(m, ETHERTYPE_IPV6); +#endif +#ifdef ETHERTYPE_VLAN + ADD_INT_MACRO(m, ETHERTYPE_VLAN); +#endif + +/* Linux pseudo-protocol for sniffing every packet */ +#ifdef ETH_P_ALL + ADD_INT_MACRO(m, ETH_P_ALL); #endif /* Socket types */ - PyModule_AddIntMacro(m, SOCK_STREAM); - PyModule_AddIntMacro(m, SOCK_DGRAM); + ADD_INT_MACRO(m, SOCK_STREAM); + ADD_INT_MACRO(m, SOCK_DGRAM); /* We have incomplete socket support. */ #ifdef SOCK_RAW /* SOCK_RAW is marked as optional in the POSIX specification */ - PyModule_AddIntMacro(m, SOCK_RAW); + ADD_INT_MACRO(m, SOCK_RAW); #endif #ifdef SOCK_SEQPACKET - PyModule_AddIntMacro(m, SOCK_SEQPACKET); + ADD_INT_MACRO(m, SOCK_SEQPACKET); #endif #if defined(SOCK_RDM) - PyModule_AddIntMacro(m, SOCK_RDM); + ADD_INT_MACRO(m, SOCK_RDM); #endif #ifdef SOCK_CLOEXEC - PyModule_AddIntMacro(m, SOCK_CLOEXEC); + ADD_INT_MACRO(m, SOCK_CLOEXEC); #endif #ifdef SOCK_NONBLOCK - PyModule_AddIntMacro(m, SOCK_NONBLOCK); + ADD_INT_MACRO(m, SOCK_NONBLOCK); #endif #ifdef SO_DEBUG - PyModule_AddIntMacro(m, SO_DEBUG); + ADD_INT_MACRO(m, SO_DEBUG); #endif #ifdef SO_ACCEPTCONN - PyModule_AddIntMacro(m, SO_ACCEPTCONN); + ADD_INT_MACRO(m, SO_ACCEPTCONN); #endif #ifdef SO_REUSEADDR - PyModule_AddIntMacro(m, SO_REUSEADDR); + ADD_INT_MACRO(m, SO_REUSEADDR); #endif #ifdef SO_EXCLUSIVEADDRUSE - PyModule_AddIntMacro(m, SO_EXCLUSIVEADDRUSE); + ADD_INT_MACRO(m, SO_EXCLUSIVEADDRUSE); #endif #ifdef SO_INCOMING_CPU - PyModule_AddIntMacro(m, SO_INCOMING_CPU); + ADD_INT_MACRO(m, SO_INCOMING_CPU); #endif #ifdef SO_KEEPALIVE - PyModule_AddIntMacro(m, SO_KEEPALIVE); + ADD_INT_MACRO(m, SO_KEEPALIVE); #endif #ifdef SO_DONTROUTE - PyModule_AddIntMacro(m, SO_DONTROUTE); + ADD_INT_MACRO(m, SO_DONTROUTE); #endif #ifdef SO_BROADCAST - PyModule_AddIntMacro(m, SO_BROADCAST); + ADD_INT_MACRO(m, SO_BROADCAST); #endif #ifdef SO_USELOOPBACK - PyModule_AddIntMacro(m, SO_USELOOPBACK); + ADD_INT_MACRO(m, SO_USELOOPBACK); #endif #ifdef SO_LINGER - PyModule_AddIntMacro(m, SO_LINGER); + ADD_INT_MACRO(m, SO_LINGER); #endif #ifdef SO_OOBINLINE - PyModule_AddIntMacro(m, SO_OOBINLINE); + ADD_INT_MACRO(m, SO_OOBINLINE); #endif #ifndef __GNU__ #ifdef SO_REUSEPORT - PyModule_AddIntMacro(m, SO_REUSEPORT); + ADD_INT_MACRO(m, SO_REUSEPORT); #endif #endif #ifdef SO_SNDBUF - PyModule_AddIntMacro(m, SO_SNDBUF); + ADD_INT_MACRO(m, SO_SNDBUF); #endif #ifdef SO_RCVBUF - PyModule_AddIntMacro(m, SO_RCVBUF); + ADD_INT_MACRO(m, SO_RCVBUF); #endif #ifdef SO_SNDLOWAT - PyModule_AddIntMacro(m, SO_SNDLOWAT); + ADD_INT_MACRO(m, SO_SNDLOWAT); #endif #ifdef SO_RCVLOWAT - PyModule_AddIntMacro(m, SO_RCVLOWAT); + ADD_INT_MACRO(m, SO_RCVLOWAT); #endif #ifdef SO_SNDTIMEO - PyModule_AddIntMacro(m, SO_SNDTIMEO); + ADD_INT_MACRO(m, SO_SNDTIMEO); #endif #ifdef SO_RCVTIMEO - PyModule_AddIntMacro(m, SO_RCVTIMEO); + ADD_INT_MACRO(m, SO_RCVTIMEO); #endif #ifdef SO_ERROR - PyModule_AddIntMacro(m, SO_ERROR); + ADD_INT_MACRO(m, SO_ERROR); #endif #ifdef SO_TYPE - PyModule_AddIntMacro(m, SO_TYPE); + ADD_INT_MACRO(m, SO_TYPE); #endif #ifdef SO_SETFIB - PyModule_AddIntMacro(m, SO_SETFIB); + ADD_INT_MACRO(m, SO_SETFIB); #endif #ifdef SO_PASSCRED - PyModule_AddIntMacro(m, SO_PASSCRED); + ADD_INT_MACRO(m, SO_PASSCRED); #endif #ifdef SO_PEERCRED - PyModule_AddIntMacro(m, SO_PEERCRED); + ADD_INT_MACRO(m, SO_PEERCRED); #endif #ifdef LOCAL_PEERCRED - PyModule_AddIntMacro(m, LOCAL_PEERCRED); + ADD_INT_MACRO(m, LOCAL_PEERCRED); #endif #ifdef SO_PASSSEC - PyModule_AddIntMacro(m, SO_PASSSEC); + ADD_INT_MACRO(m, SO_PASSSEC); #endif #ifdef SO_PEERSEC - PyModule_AddIntMacro(m, SO_PEERSEC); + ADD_INT_MACRO(m, SO_PEERSEC); #endif #ifdef SO_BINDTODEVICE - PyModule_AddIntMacro(m, SO_BINDTODEVICE); + ADD_INT_MACRO(m, SO_BINDTODEVICE); #endif #ifdef SO_PRIORITY - PyModule_AddIntMacro(m, SO_PRIORITY); + ADD_INT_MACRO(m, SO_PRIORITY); #endif #ifdef SO_MARK - PyModule_AddIntMacro(m, SO_MARK); + ADD_INT_MACRO(m, SO_MARK); +#endif +#ifdef SO_USER_COOKIE + ADD_INT_MACRO(m, SO_USER_COOKIE); +#endif +#ifdef SO_RTABLE + ADD_INT_MACRO(m, SO_RTABLE); #endif #ifdef SO_DOMAIN - PyModule_AddIntMacro(m, SO_DOMAIN); + ADD_INT_MACRO(m, SO_DOMAIN); #endif #ifdef SO_PROTOCOL - PyModule_AddIntMacro(m, SO_PROTOCOL); + ADD_INT_MACRO(m, SO_PROTOCOL); #endif #ifdef LOCAL_CREDS - PyModule_AddIntMacro(m, LOCAL_CREDS); + ADD_INT_MACRO(m, LOCAL_CREDS); #endif #ifdef LOCAL_CREDS_PERSISTENT - PyModule_AddIntMacro(m, LOCAL_CREDS_PERSISTENT); + ADD_INT_MACRO(m, LOCAL_CREDS_PERSISTENT); #endif /* Maximum number of connections for "listen" */ #ifdef SOMAXCONN - PyModule_AddIntMacro(m, SOMAXCONN); + ADD_INT_MACRO(m, SOMAXCONN); #else - PyModule_AddIntConstant(m, "SOMAXCONN", 5); /* Common value */ + ADD_INT_CONST(m, "SOMAXCONN", 5); /* Common value */ #endif /* Ancillary message types */ #ifdef SCM_RIGHTS - PyModule_AddIntMacro(m, SCM_RIGHTS); + ADD_INT_MACRO(m, SCM_RIGHTS); #endif #ifdef SCM_CREDENTIALS - PyModule_AddIntMacro(m, SCM_CREDENTIALS); + ADD_INT_MACRO(m, SCM_CREDENTIALS); #endif #ifdef SCM_CREDS - PyModule_AddIntMacro(m, SCM_CREDS); + ADD_INT_MACRO(m, SCM_CREDS); #endif #ifdef SCM_CREDS2 - PyModule_AddIntMacro(m, SCM_CREDS2); + ADD_INT_MACRO(m, SCM_CREDS2); #endif /* Flags for send, recv */ #ifdef MSG_OOB - PyModule_AddIntMacro(m, MSG_OOB); + ADD_INT_MACRO(m, MSG_OOB); #endif #ifdef MSG_PEEK - PyModule_AddIntMacro(m, MSG_PEEK); + ADD_INT_MACRO(m, MSG_PEEK); #endif #ifdef MSG_DONTROUTE - PyModule_AddIntMacro(m, MSG_DONTROUTE); + ADD_INT_MACRO(m, MSG_DONTROUTE); #endif #ifdef MSG_DONTWAIT - PyModule_AddIntMacro(m, MSG_DONTWAIT); + ADD_INT_MACRO(m, MSG_DONTWAIT); #endif #ifdef MSG_EOR - PyModule_AddIntMacro(m, MSG_EOR); + ADD_INT_MACRO(m, MSG_EOR); #endif #ifdef MSG_TRUNC // workaround for https://github.com/WebAssembly/wasi-libc/issues/305 #if defined(__wasi__) && !defined(__WASI_RIFLAGS_RECV_DATA_TRUNCATED) # define __WASI_RIFLAGS_RECV_DATA_TRUNCATED 2 #endif - PyModule_AddIntMacro(m, MSG_TRUNC); + ADD_INT_MACRO(m, MSG_TRUNC); #endif #ifdef MSG_CTRUNC - PyModule_AddIntMacro(m, MSG_CTRUNC); + ADD_INT_MACRO(m, MSG_CTRUNC); #endif #ifdef MSG_WAITALL - PyModule_AddIntMacro(m, MSG_WAITALL); + ADD_INT_MACRO(m, MSG_WAITALL); #endif #ifdef MSG_BTAG - PyModule_AddIntMacro(m, MSG_BTAG); + ADD_INT_MACRO(m, MSG_BTAG); #endif #ifdef MSG_ETAG - PyModule_AddIntMacro(m, MSG_ETAG); + ADD_INT_MACRO(m, MSG_ETAG); #endif #ifdef MSG_NOSIGNAL - PyModule_AddIntMacro(m, MSG_NOSIGNAL); + ADD_INT_MACRO(m, MSG_NOSIGNAL); #endif #ifdef MSG_NOTIFICATION - PyModule_AddIntMacro(m, MSG_NOTIFICATION); + ADD_INT_MACRO(m, MSG_NOTIFICATION); #endif #ifdef MSG_CMSG_CLOEXEC - PyModule_AddIntMacro(m, MSG_CMSG_CLOEXEC); + ADD_INT_MACRO(m, MSG_CMSG_CLOEXEC); #endif #ifdef MSG_ERRQUEUE - PyModule_AddIntMacro(m, MSG_ERRQUEUE); + ADD_INT_MACRO(m, MSG_ERRQUEUE); #endif #ifdef MSG_CONFIRM - PyModule_AddIntMacro(m, MSG_CONFIRM); + ADD_INT_MACRO(m, MSG_CONFIRM); #endif #ifdef MSG_MORE - PyModule_AddIntMacro(m, MSG_MORE); + ADD_INT_MACRO(m, MSG_MORE); #endif #ifdef MSG_EOF - PyModule_AddIntMacro(m, MSG_EOF); + ADD_INT_MACRO(m, MSG_EOF); #endif #ifdef MSG_BCAST - PyModule_AddIntMacro(m, MSG_BCAST); + ADD_INT_MACRO(m, MSG_BCAST); #endif #ifdef MSG_MCAST - PyModule_AddIntMacro(m, MSG_MCAST); + ADD_INT_MACRO(m, MSG_MCAST); #endif #ifdef MSG_FASTOPEN - PyModule_AddIntMacro(m, MSG_FASTOPEN); + ADD_INT_MACRO(m, MSG_FASTOPEN); #endif /* Protocol level and numbers, usable for [gs]etsockopt */ #ifdef SOL_SOCKET - PyModule_AddIntMacro(m, SOL_SOCKET); + ADD_INT_MACRO(m, SOL_SOCKET); #endif #ifdef SOL_IP - PyModule_AddIntMacro(m, SOL_IP); + ADD_INT_MACRO(m, SOL_IP); #else - PyModule_AddIntConstant(m, "SOL_IP", 0); + ADD_INT_CONST(m, "SOL_IP", 0); #endif #ifdef SOL_IPX - PyModule_AddIntMacro(m, SOL_IPX); + ADD_INT_MACRO(m, SOL_IPX); #endif #ifdef SOL_AX25 - PyModule_AddIntMacro(m, SOL_AX25); + ADD_INT_MACRO(m, SOL_AX25); #endif #ifdef SOL_ATALK - PyModule_AddIntMacro(m, SOL_ATALK); + ADD_INT_MACRO(m, SOL_ATALK); #endif #ifdef SOL_NETROM - PyModule_AddIntMacro(m, SOL_NETROM); + ADD_INT_MACRO(m, SOL_NETROM); #endif #ifdef SOL_ROSE - PyModule_AddIntMacro(m, SOL_ROSE); + ADD_INT_MACRO(m, SOL_ROSE); #endif #ifdef SOL_TCP - PyModule_AddIntMacro(m, SOL_TCP); + ADD_INT_MACRO(m, SOL_TCP); #else - PyModule_AddIntConstant(m, "SOL_TCP", 6); + ADD_INT_CONST(m, "SOL_TCP", 6); #endif #ifdef SOL_UDP - PyModule_AddIntMacro(m, SOL_UDP); + ADD_INT_MACRO(m, SOL_UDP); #else - PyModule_AddIntConstant(m, "SOL_UDP", 17); + ADD_INT_CONST(m, "SOL_UDP", 17); #endif #ifdef SOL_CAN_BASE - PyModule_AddIntMacro(m, SOL_CAN_BASE); + ADD_INT_MACRO(m, SOL_CAN_BASE); #endif #ifdef SOL_CAN_RAW - PyModule_AddIntMacro(m, SOL_CAN_RAW); - PyModule_AddIntMacro(m, CAN_RAW); + ADD_INT_MACRO(m, SOL_CAN_RAW); + ADD_INT_MACRO(m, CAN_RAW); #endif #if defined(HAVE_LINUX_CAN_H) || defined(HAVE_NETCAN_CAN_H) - PyModule_AddIntMacro(m, CAN_EFF_FLAG); - PyModule_AddIntMacro(m, CAN_RTR_FLAG); - PyModule_AddIntMacro(m, CAN_ERR_FLAG); + ADD_INT_MACRO(m, CAN_EFF_FLAG); + ADD_INT_MACRO(m, CAN_RTR_FLAG); + ADD_INT_MACRO(m, CAN_ERR_FLAG); - PyModule_AddIntMacro(m, CAN_SFF_MASK); - PyModule_AddIntMacro(m, CAN_EFF_MASK); - PyModule_AddIntMacro(m, CAN_ERR_MASK); + ADD_INT_MACRO(m, CAN_SFF_MASK); + ADD_INT_MACRO(m, CAN_EFF_MASK); + ADD_INT_MACRO(m, CAN_ERR_MASK); #ifdef CAN_ISOTP - PyModule_AddIntMacro(m, CAN_ISOTP); + ADD_INT_MACRO(m, CAN_ISOTP); #endif #ifdef CAN_J1939 - PyModule_AddIntMacro(m, CAN_J1939); + ADD_INT_MACRO(m, CAN_J1939); #endif #endif #if defined(HAVE_LINUX_CAN_RAW_H) || defined(HAVE_NETCAN_CAN_H) - PyModule_AddIntMacro(m, CAN_RAW_FILTER); + ADD_INT_MACRO(m, CAN_RAW_FILTER); #ifdef CAN_RAW_ERR_FILTER - PyModule_AddIntMacro(m, CAN_RAW_ERR_FILTER); + ADD_INT_MACRO(m, CAN_RAW_ERR_FILTER); #endif - PyModule_AddIntMacro(m, CAN_RAW_LOOPBACK); - PyModule_AddIntMacro(m, CAN_RAW_RECV_OWN_MSGS); + ADD_INT_MACRO(m, CAN_RAW_LOOPBACK); + ADD_INT_MACRO(m, CAN_RAW_RECV_OWN_MSGS); #endif #ifdef HAVE_LINUX_CAN_RAW_FD_FRAMES - PyModule_AddIntMacro(m, CAN_RAW_FD_FRAMES); + ADD_INT_MACRO(m, CAN_RAW_FD_FRAMES); #endif #ifdef HAVE_LINUX_CAN_RAW_JOIN_FILTERS - PyModule_AddIntMacro(m, CAN_RAW_JOIN_FILTERS); + ADD_INT_MACRO(m, CAN_RAW_JOIN_FILTERS); #endif #ifdef HAVE_LINUX_CAN_BCM_H - PyModule_AddIntMacro(m, CAN_BCM); + ADD_INT_MACRO(m, CAN_BCM); /* BCM opcodes */ - PyModule_AddIntConstant(m, "CAN_BCM_TX_SETUP", TX_SETUP); - PyModule_AddIntConstant(m, "CAN_BCM_TX_DELETE", TX_DELETE); - PyModule_AddIntConstant(m, "CAN_BCM_TX_READ", TX_READ); - PyModule_AddIntConstant(m, "CAN_BCM_TX_SEND", TX_SEND); - PyModule_AddIntConstant(m, "CAN_BCM_RX_SETUP", RX_SETUP); - PyModule_AddIntConstant(m, "CAN_BCM_RX_DELETE", RX_DELETE); - PyModule_AddIntConstant(m, "CAN_BCM_RX_READ", RX_READ); - PyModule_AddIntConstant(m, "CAN_BCM_TX_STATUS", TX_STATUS); - PyModule_AddIntConstant(m, "CAN_BCM_TX_EXPIRED", TX_EXPIRED); - PyModule_AddIntConstant(m, "CAN_BCM_RX_STATUS", RX_STATUS); - PyModule_AddIntConstant(m, "CAN_BCM_RX_TIMEOUT", RX_TIMEOUT); - PyModule_AddIntConstant(m, "CAN_BCM_RX_CHANGED", RX_CHANGED); + ADD_INT_CONST(m, "CAN_BCM_TX_SETUP", TX_SETUP); + ADD_INT_CONST(m, "CAN_BCM_TX_DELETE", TX_DELETE); + ADD_INT_CONST(m, "CAN_BCM_TX_READ", TX_READ); + ADD_INT_CONST(m, "CAN_BCM_TX_SEND", TX_SEND); + ADD_INT_CONST(m, "CAN_BCM_RX_SETUP", RX_SETUP); + ADD_INT_CONST(m, "CAN_BCM_RX_DELETE", RX_DELETE); + ADD_INT_CONST(m, "CAN_BCM_RX_READ", RX_READ); + ADD_INT_CONST(m, "CAN_BCM_TX_STATUS", TX_STATUS); + ADD_INT_CONST(m, "CAN_BCM_TX_EXPIRED", TX_EXPIRED); + ADD_INT_CONST(m, "CAN_BCM_RX_STATUS", RX_STATUS); + ADD_INT_CONST(m, "CAN_BCM_RX_TIMEOUT", RX_TIMEOUT); + ADD_INT_CONST(m, "CAN_BCM_RX_CHANGED", RX_CHANGED); /* BCM flags */ - PyModule_AddIntConstant(m, "CAN_BCM_SETTIMER", SETTIMER); - PyModule_AddIntConstant(m, "CAN_BCM_STARTTIMER", STARTTIMER); - PyModule_AddIntConstant(m, "CAN_BCM_TX_COUNTEVT", TX_COUNTEVT); - PyModule_AddIntConstant(m, "CAN_BCM_TX_ANNOUNCE", TX_ANNOUNCE); - PyModule_AddIntConstant(m, "CAN_BCM_TX_CP_CAN_ID", TX_CP_CAN_ID); - PyModule_AddIntConstant(m, "CAN_BCM_RX_FILTER_ID", RX_FILTER_ID); - PyModule_AddIntConstant(m, "CAN_BCM_RX_CHECK_DLC", RX_CHECK_DLC); - PyModule_AddIntConstant(m, "CAN_BCM_RX_NO_AUTOTIMER", RX_NO_AUTOTIMER); - PyModule_AddIntConstant(m, "CAN_BCM_RX_ANNOUNCE_RESUME", RX_ANNOUNCE_RESUME); - PyModule_AddIntConstant(m, "CAN_BCM_TX_RESET_MULTI_IDX", TX_RESET_MULTI_IDX); - PyModule_AddIntConstant(m, "CAN_BCM_RX_RTR_FRAME", RX_RTR_FRAME); + ADD_INT_CONST(m, "CAN_BCM_SETTIMER", SETTIMER); + ADD_INT_CONST(m, "CAN_BCM_STARTTIMER", STARTTIMER); + ADD_INT_CONST(m, "CAN_BCM_TX_COUNTEVT", TX_COUNTEVT); + ADD_INT_CONST(m, "CAN_BCM_TX_ANNOUNCE", TX_ANNOUNCE); + ADD_INT_CONST(m, "CAN_BCM_TX_CP_CAN_ID", TX_CP_CAN_ID); + ADD_INT_CONST(m, "CAN_BCM_RX_FILTER_ID", RX_FILTER_ID); + ADD_INT_CONST(m, "CAN_BCM_RX_CHECK_DLC", RX_CHECK_DLC); + ADD_INT_CONST(m, "CAN_BCM_RX_NO_AUTOTIMER", RX_NO_AUTOTIMER); + ADD_INT_CONST(m, "CAN_BCM_RX_ANNOUNCE_RESUME", RX_ANNOUNCE_RESUME); + ADD_INT_CONST(m, "CAN_BCM_TX_RESET_MULTI_IDX", TX_RESET_MULTI_IDX); + ADD_INT_CONST(m, "CAN_BCM_RX_RTR_FRAME", RX_RTR_FRAME); #ifdef CAN_FD_FRAME /* CAN_FD_FRAME was only introduced in the 4.8.x kernel series */ - PyModule_AddIntConstant(m, "CAN_BCM_CAN_FD_FRAME", CAN_FD_FRAME); + ADD_INT_CONST(m, "CAN_BCM_CAN_FD_FRAME", CAN_FD_FRAME); #endif #endif #ifdef HAVE_LINUX_CAN_J1939_H - PyModule_AddIntMacro(m, J1939_MAX_UNICAST_ADDR); - PyModule_AddIntMacro(m, J1939_IDLE_ADDR); - PyModule_AddIntMacro(m, J1939_NO_ADDR); - PyModule_AddIntMacro(m, J1939_NO_NAME); - PyModule_AddIntMacro(m, J1939_PGN_REQUEST); - PyModule_AddIntMacro(m, J1939_PGN_ADDRESS_CLAIMED); - PyModule_AddIntMacro(m, J1939_PGN_ADDRESS_COMMANDED); - PyModule_AddIntMacro(m, J1939_PGN_PDU1_MAX); - PyModule_AddIntMacro(m, J1939_PGN_MAX); - PyModule_AddIntMacro(m, J1939_NO_PGN); + ADD_INT_MACRO(m, J1939_MAX_UNICAST_ADDR); + ADD_INT_MACRO(m, J1939_IDLE_ADDR); + ADD_INT_MACRO(m, J1939_NO_ADDR); + ADD_INT_MACRO(m, J1939_NO_NAME); + ADD_INT_MACRO(m, J1939_PGN_REQUEST); + ADD_INT_MACRO(m, J1939_PGN_ADDRESS_CLAIMED); + ADD_INT_MACRO(m, J1939_PGN_ADDRESS_COMMANDED); + ADD_INT_MACRO(m, J1939_PGN_PDU1_MAX); + ADD_INT_MACRO(m, J1939_PGN_MAX); + ADD_INT_MACRO(m, J1939_NO_PGN); /* J1939 socket options */ - PyModule_AddIntMacro(m, SO_J1939_FILTER); - PyModule_AddIntMacro(m, SO_J1939_PROMISC); - PyModule_AddIntMacro(m, SO_J1939_SEND_PRIO); - PyModule_AddIntMacro(m, SO_J1939_ERRQUEUE); + ADD_INT_MACRO(m, SO_J1939_FILTER); + ADD_INT_MACRO(m, SO_J1939_PROMISC); + ADD_INT_MACRO(m, SO_J1939_SEND_PRIO); + ADD_INT_MACRO(m, SO_J1939_ERRQUEUE); - PyModule_AddIntMacro(m, SCM_J1939_DEST_ADDR); - PyModule_AddIntMacro(m, SCM_J1939_DEST_NAME); - PyModule_AddIntMacro(m, SCM_J1939_PRIO); - PyModule_AddIntMacro(m, SCM_J1939_ERRQUEUE); + ADD_INT_MACRO(m, SCM_J1939_DEST_ADDR); + ADD_INT_MACRO(m, SCM_J1939_DEST_NAME); + ADD_INT_MACRO(m, SCM_J1939_PRIO); + ADD_INT_MACRO(m, SCM_J1939_ERRQUEUE); - PyModule_AddIntMacro(m, J1939_NLA_PAD); - PyModule_AddIntMacro(m, J1939_NLA_BYTES_ACKED); + ADD_INT_MACRO(m, J1939_NLA_PAD); + ADD_INT_MACRO(m, J1939_NLA_BYTES_ACKED); - PyModule_AddIntMacro(m, J1939_EE_INFO_NONE); - PyModule_AddIntMacro(m, J1939_EE_INFO_TX_ABORT); + ADD_INT_MACRO(m, J1939_EE_INFO_NONE); + ADD_INT_MACRO(m, J1939_EE_INFO_TX_ABORT); - PyModule_AddIntMacro(m, J1939_FILTER_MAX); + ADD_INT_MACRO(m, J1939_FILTER_MAX); #endif #ifdef SOL_RDS - PyModule_AddIntMacro(m, SOL_RDS); + ADD_INT_MACRO(m, SOL_RDS); #endif #ifdef HAVE_SOCKADDR_ALG - PyModule_AddIntMacro(m, SOL_ALG); + ADD_INT_MACRO(m, SOL_ALG); #endif #ifdef RDS_CANCEL_SENT_TO - PyModule_AddIntMacro(m, RDS_CANCEL_SENT_TO); + ADD_INT_MACRO(m, RDS_CANCEL_SENT_TO); #endif #ifdef RDS_GET_MR - PyModule_AddIntMacro(m, RDS_GET_MR); + ADD_INT_MACRO(m, RDS_GET_MR); #endif #ifdef RDS_FREE_MR - PyModule_AddIntMacro(m, RDS_FREE_MR); + ADD_INT_MACRO(m, RDS_FREE_MR); #endif #ifdef RDS_RECVERR - PyModule_AddIntMacro(m, RDS_RECVERR); + ADD_INT_MACRO(m, RDS_RECVERR); #endif #ifdef RDS_CONG_MONITOR - PyModule_AddIntMacro(m, RDS_CONG_MONITOR); + ADD_INT_MACRO(m, RDS_CONG_MONITOR); #endif #ifdef RDS_GET_MR_FOR_DEST - PyModule_AddIntMacro(m, RDS_GET_MR_FOR_DEST); + ADD_INT_MACRO(m, RDS_GET_MR_FOR_DEST); #endif #ifdef IPPROTO_IP - PyModule_AddIntMacro(m, IPPROTO_IP); + ADD_INT_MACRO(m, IPPROTO_IP); #else - PyModule_AddIntConstant(m, "IPPROTO_IP", 0); + ADD_INT_CONST(m, "IPPROTO_IP", 0); #endif #ifdef IPPROTO_HOPOPTS - PyModule_AddIntMacro(m, IPPROTO_HOPOPTS); + ADD_INT_MACRO(m, IPPROTO_HOPOPTS); #endif #ifdef IPPROTO_ICMP - PyModule_AddIntMacro(m, IPPROTO_ICMP); + ADD_INT_MACRO(m, IPPROTO_ICMP); #else - PyModule_AddIntConstant(m, "IPPROTO_ICMP", 1); + ADD_INT_CONST(m, "IPPROTO_ICMP", 1); #endif #ifdef IPPROTO_IGMP - PyModule_AddIntMacro(m, IPPROTO_IGMP); + ADD_INT_MACRO(m, IPPROTO_IGMP); #endif #ifdef IPPROTO_GGP - PyModule_AddIntMacro(m, IPPROTO_GGP); + ADD_INT_MACRO(m, IPPROTO_GGP); #endif #ifdef IPPROTO_IPV4 - PyModule_AddIntMacro(m, IPPROTO_IPV4); + ADD_INT_MACRO(m, IPPROTO_IPV4); #endif #ifdef IPPROTO_IPV6 - PyModule_AddIntMacro(m, IPPROTO_IPV6); + ADD_INT_MACRO(m, IPPROTO_IPV6); #endif #ifdef IPPROTO_IPIP - PyModule_AddIntMacro(m, IPPROTO_IPIP); + ADD_INT_MACRO(m, IPPROTO_IPIP); #endif #ifdef IPPROTO_TCP - PyModule_AddIntMacro(m, IPPROTO_TCP); + ADD_INT_MACRO(m, IPPROTO_TCP); #else - PyModule_AddIntConstant(m, "IPPROTO_TCP", 6); + ADD_INT_CONST(m, "IPPROTO_TCP", 6); #endif #ifdef IPPROTO_EGP - PyModule_AddIntMacro(m, IPPROTO_EGP); + ADD_INT_MACRO(m, IPPROTO_EGP); #endif #ifdef IPPROTO_PUP - PyModule_AddIntMacro(m, IPPROTO_PUP); + ADD_INT_MACRO(m, IPPROTO_PUP); #endif #ifdef IPPROTO_UDP - PyModule_AddIntMacro(m, IPPROTO_UDP); + ADD_INT_MACRO(m, IPPROTO_UDP); #else - PyModule_AddIntConstant(m, "IPPROTO_UDP", 17); + ADD_INT_CONST(m, "IPPROTO_UDP", 17); #endif #ifdef IPPROTO_UDPLITE - PyModule_AddIntMacro(m, IPPROTO_UDPLITE); + ADD_INT_MACRO(m, IPPROTO_UDPLITE); #ifndef UDPLITE_SEND_CSCOV #define UDPLITE_SEND_CSCOV 10 #endif - PyModule_AddIntMacro(m, UDPLITE_SEND_CSCOV); + ADD_INT_MACRO(m, UDPLITE_SEND_CSCOV); #ifndef UDPLITE_RECV_CSCOV #define UDPLITE_RECV_CSCOV 11 #endif - PyModule_AddIntMacro(m, UDPLITE_RECV_CSCOV); + ADD_INT_MACRO(m, UDPLITE_RECV_CSCOV); #endif #ifdef IPPROTO_IDP - PyModule_AddIntMacro(m, IPPROTO_IDP); + ADD_INT_MACRO(m, IPPROTO_IDP); #endif #ifdef IPPROTO_HELLO - PyModule_AddIntMacro(m, IPPROTO_HELLO); + ADD_INT_MACRO(m, IPPROTO_HELLO); #endif #ifdef IPPROTO_ND - PyModule_AddIntMacro(m, IPPROTO_ND); + ADD_INT_MACRO(m, IPPROTO_ND); #endif #ifdef IPPROTO_TP - PyModule_AddIntMacro(m, IPPROTO_TP); + ADD_INT_MACRO(m, IPPROTO_TP); #endif #ifdef IPPROTO_ROUTING - PyModule_AddIntMacro(m, IPPROTO_ROUTING); + ADD_INT_MACRO(m, IPPROTO_ROUTING); #endif #ifdef IPPROTO_FRAGMENT - PyModule_AddIntMacro(m, IPPROTO_FRAGMENT); + ADD_INT_MACRO(m, IPPROTO_FRAGMENT); #endif #ifdef IPPROTO_RSVP - PyModule_AddIntMacro(m, IPPROTO_RSVP); + ADD_INT_MACRO(m, IPPROTO_RSVP); #endif #ifdef IPPROTO_GRE - PyModule_AddIntMacro(m, IPPROTO_GRE); + ADD_INT_MACRO(m, IPPROTO_GRE); #endif #ifdef IPPROTO_ESP - PyModule_AddIntMacro(m, IPPROTO_ESP); + ADD_INT_MACRO(m, IPPROTO_ESP); #endif #ifdef IPPROTO_AH - PyModule_AddIntMacro(m, IPPROTO_AH); + ADD_INT_MACRO(m, IPPROTO_AH); #endif #ifdef IPPROTO_MOBILE - PyModule_AddIntMacro(m, IPPROTO_MOBILE); + ADD_INT_MACRO(m, IPPROTO_MOBILE); #endif #ifdef IPPROTO_ICMPV6 - PyModule_AddIntMacro(m, IPPROTO_ICMPV6); + ADD_INT_MACRO(m, IPPROTO_ICMPV6); #endif #ifdef IPPROTO_NONE - PyModule_AddIntMacro(m, IPPROTO_NONE); + ADD_INT_MACRO(m, IPPROTO_NONE); #endif #ifdef IPPROTO_DSTOPTS - PyModule_AddIntMacro(m, IPPROTO_DSTOPTS); + ADD_INT_MACRO(m, IPPROTO_DSTOPTS); #endif #ifdef IPPROTO_XTP - PyModule_AddIntMacro(m, IPPROTO_XTP); + ADD_INT_MACRO(m, IPPROTO_XTP); #endif #ifdef IPPROTO_EON - PyModule_AddIntMacro(m, IPPROTO_EON); + ADD_INT_MACRO(m, IPPROTO_EON); #endif #ifdef IPPROTO_PIM - PyModule_AddIntMacro(m, IPPROTO_PIM); + ADD_INT_MACRO(m, IPPROTO_PIM); #endif #ifdef IPPROTO_IPCOMP - PyModule_AddIntMacro(m, IPPROTO_IPCOMP); + ADD_INT_MACRO(m, IPPROTO_IPCOMP); #endif #ifdef IPPROTO_VRRP - PyModule_AddIntMacro(m, IPPROTO_VRRP); + ADD_INT_MACRO(m, IPPROTO_VRRP); #endif #ifdef IPPROTO_SCTP - PyModule_AddIntMacro(m, IPPROTO_SCTP); + ADD_INT_MACRO(m, IPPROTO_SCTP); #endif #ifdef IPPROTO_BIP - PyModule_AddIntMacro(m, IPPROTO_BIP); + ADD_INT_MACRO(m, IPPROTO_BIP); #endif #ifdef IPPROTO_MPTCP - PyModule_AddIntMacro(m, IPPROTO_MPTCP); + ADD_INT_MACRO(m, IPPROTO_MPTCP); #endif /**/ #ifdef IPPROTO_RAW - PyModule_AddIntMacro(m, IPPROTO_RAW); + ADD_INT_MACRO(m, IPPROTO_RAW); #else - PyModule_AddIntConstant(m, "IPPROTO_RAW", 255); + ADD_INT_CONST(m, "IPPROTO_RAW", 255); #endif #ifdef IPPROTO_MAX - PyModule_AddIntMacro(m, IPPROTO_MAX); + ADD_INT_MACRO(m, IPPROTO_MAX); #endif #ifdef MS_WINDOWS - PyModule_AddIntMacro(m, IPPROTO_ICLFXBM); - PyModule_AddIntMacro(m, IPPROTO_ST); - PyModule_AddIntMacro(m, IPPROTO_CBT); - PyModule_AddIntMacro(m, IPPROTO_IGP); - PyModule_AddIntMacro(m, IPPROTO_RDP); - PyModule_AddIntMacro(m, IPPROTO_PGM); - PyModule_AddIntMacro(m, IPPROTO_L2TP); - PyModule_AddIntMacro(m, IPPROTO_SCTP); + ADD_INT_MACRO(m, IPPROTO_ICLFXBM); + ADD_INT_MACRO(m, IPPROTO_ST); + ADD_INT_MACRO(m, IPPROTO_CBT); + ADD_INT_MACRO(m, IPPROTO_IGP); + ADD_INT_MACRO(m, IPPROTO_RDP); + ADD_INT_MACRO(m, IPPROTO_PGM); + ADD_INT_MACRO(m, IPPROTO_L2TP); + ADD_INT_MACRO(m, IPPROTO_SCTP); #endif #ifdef SYSPROTO_CONTROL - PyModule_AddIntMacro(m, SYSPROTO_CONTROL); + ADD_INT_MACRO(m, SYSPROTO_CONTROL); #endif /* Some port configuration */ #ifdef IPPORT_RESERVED - PyModule_AddIntMacro(m, IPPORT_RESERVED); + ADD_INT_MACRO(m, IPPORT_RESERVED); #else - PyModule_AddIntConstant(m, "IPPORT_RESERVED", 1024); + ADD_INT_CONST(m, "IPPORT_RESERVED", 1024); #endif #ifdef IPPORT_USERRESERVED - PyModule_AddIntMacro(m, IPPORT_USERRESERVED); + ADD_INT_MACRO(m, IPPORT_USERRESERVED); #else - PyModule_AddIntConstant(m, "IPPORT_USERRESERVED", 5000); + ADD_INT_CONST(m, "IPPORT_USERRESERVED", 5000); #endif /* Some reserved IP v.4 addresses */ #ifdef INADDR_ANY - PyModule_AddIntMacro(m, INADDR_ANY); + ADD_INT_MACRO(m, INADDR_ANY); #else - PyModule_AddIntConstant(m, "INADDR_ANY", 0x00000000); + ADD_INT_CONST(m, "INADDR_ANY", 0x00000000); #endif #ifdef INADDR_BROADCAST - PyModule_AddIntMacro(m, INADDR_BROADCAST); + ADD_INT_MACRO(m, INADDR_BROADCAST); #else - PyModule_AddIntConstant(m, "INADDR_BROADCAST", 0xffffffff); + ADD_INT_CONST(m, "INADDR_BROADCAST", 0xffffffff); #endif #ifdef INADDR_LOOPBACK - PyModule_AddIntMacro(m, INADDR_LOOPBACK); + ADD_INT_MACRO(m, INADDR_LOOPBACK); #else - PyModule_AddIntConstant(m, "INADDR_LOOPBACK", 0x7F000001); + ADD_INT_CONST(m, "INADDR_LOOPBACK", 0x7F000001); #endif #ifdef INADDR_UNSPEC_GROUP - PyModule_AddIntMacro(m, INADDR_UNSPEC_GROUP); + ADD_INT_MACRO(m, INADDR_UNSPEC_GROUP); #else - PyModule_AddIntConstant(m, "INADDR_UNSPEC_GROUP", 0xe0000000); + ADD_INT_CONST(m, "INADDR_UNSPEC_GROUP", 0xe0000000); #endif #ifdef INADDR_ALLHOSTS_GROUP - PyModule_AddIntConstant(m, "INADDR_ALLHOSTS_GROUP", + ADD_INT_CONST(m, "INADDR_ALLHOSTS_GROUP", INADDR_ALLHOSTS_GROUP); #else - PyModule_AddIntConstant(m, "INADDR_ALLHOSTS_GROUP", 0xe0000001); + ADD_INT_CONST(m, "INADDR_ALLHOSTS_GROUP", 0xe0000001); #endif #ifdef INADDR_MAX_LOCAL_GROUP - PyModule_AddIntMacro(m, INADDR_MAX_LOCAL_GROUP); + ADD_INT_MACRO(m, INADDR_MAX_LOCAL_GROUP); #else - PyModule_AddIntConstant(m, "INADDR_MAX_LOCAL_GROUP", 0xe00000ff); + ADD_INT_CONST(m, "INADDR_MAX_LOCAL_GROUP", 0xe00000ff); #endif #ifdef INADDR_NONE - PyModule_AddIntMacro(m, INADDR_NONE); + ADD_INT_MACRO(m, INADDR_NONE); #else - PyModule_AddIntConstant(m, "INADDR_NONE", 0xffffffff); + ADD_INT_CONST(m, "INADDR_NONE", 0xffffffff); #endif /* IPv4 [gs]etsockopt options */ #ifdef IP_OPTIONS - PyModule_AddIntMacro(m, IP_OPTIONS); + ADD_INT_MACRO(m, IP_OPTIONS); #endif #ifdef IP_HDRINCL - PyModule_AddIntMacro(m, IP_HDRINCL); + ADD_INT_MACRO(m, IP_HDRINCL); #endif #ifdef IP_TOS - PyModule_AddIntMacro(m, IP_TOS); + ADD_INT_MACRO(m, IP_TOS); #endif #ifdef IP_TTL - PyModule_AddIntMacro(m, IP_TTL); + ADD_INT_MACRO(m, IP_TTL); #endif #ifdef IP_RECVOPTS - PyModule_AddIntMacro(m, IP_RECVOPTS); + ADD_INT_MACRO(m, IP_RECVOPTS); #endif #ifdef IP_RECVRETOPTS - PyModule_AddIntMacro(m, IP_RECVRETOPTS); + ADD_INT_MACRO(m, IP_RECVRETOPTS); #endif #ifdef IP_RECVTOS - PyModule_AddIntMacro(m, IP_RECVTOS); + ADD_INT_MACRO(m, IP_RECVTOS); #endif #ifdef IP_RECVDSTADDR - PyModule_AddIntMacro(m, IP_RECVDSTADDR); + ADD_INT_MACRO(m, IP_RECVDSTADDR); #endif #ifdef IP_RETOPTS - PyModule_AddIntMacro(m, IP_RETOPTS); + ADD_INT_MACRO(m, IP_RETOPTS); #endif #ifdef IP_MULTICAST_IF - PyModule_AddIntMacro(m, IP_MULTICAST_IF); + ADD_INT_MACRO(m, IP_MULTICAST_IF); #endif #ifdef IP_MULTICAST_TTL - PyModule_AddIntMacro(m, IP_MULTICAST_TTL); + ADD_INT_MACRO(m, IP_MULTICAST_TTL); #endif #ifdef IP_MULTICAST_LOOP - PyModule_AddIntMacro(m, IP_MULTICAST_LOOP); + ADD_INT_MACRO(m, IP_MULTICAST_LOOP); #endif #ifdef IP_ADD_MEMBERSHIP - PyModule_AddIntMacro(m, IP_ADD_MEMBERSHIP); + ADD_INT_MACRO(m, IP_ADD_MEMBERSHIP); #endif #ifdef IP_DROP_MEMBERSHIP - PyModule_AddIntMacro(m, IP_DROP_MEMBERSHIP); + ADD_INT_MACRO(m, IP_DROP_MEMBERSHIP); #endif #ifdef IP_DEFAULT_MULTICAST_TTL - PyModule_AddIntMacro(m, IP_DEFAULT_MULTICAST_TTL); + ADD_INT_MACRO(m, IP_DEFAULT_MULTICAST_TTL); #endif #ifdef IP_DEFAULT_MULTICAST_LOOP - PyModule_AddIntMacro(m, IP_DEFAULT_MULTICAST_LOOP); + ADD_INT_MACRO(m, IP_DEFAULT_MULTICAST_LOOP); #endif #ifdef IP_MAX_MEMBERSHIPS - PyModule_AddIntMacro(m, IP_MAX_MEMBERSHIPS); + ADD_INT_MACRO(m, IP_MAX_MEMBERSHIPS); #endif #ifdef IP_TRANSPARENT - PyModule_AddIntMacro(m, IP_TRANSPARENT); + ADD_INT_MACRO(m, IP_TRANSPARENT); +#endif +#ifdef IP_PKTINFO + ADD_INT_MACRO(m, IP_PKTINFO); #endif #ifdef IP_BIND_ADDRESS_NO_PORT - PyModule_AddIntMacro(m, IP_BIND_ADDRESS_NO_PORT); + ADD_INT_MACRO(m, IP_BIND_ADDRESS_NO_PORT); +#endif +#ifdef IP_UNBLOCK_SOURCE + ADD_INT_MACRO(m, IP_UNBLOCK_SOURCE); +#endif +#ifdef IP_BLOCK_SOURCE + ADD_INT_MACRO(m, IP_BLOCK_SOURCE); +#endif +#ifdef IP_ADD_SOURCE_MEMBERSHIP + ADD_INT_MACRO(m, IP_ADD_SOURCE_MEMBERSHIP); +#endif +#ifdef IP_DROP_SOURCE_MEMBERSHIP + ADD_INT_MACRO(m, IP_DROP_SOURCE_MEMBERSHIP); #endif /* IPv6 [gs]etsockopt options, defined in RFC2553 */ #ifdef IPV6_JOIN_GROUP - PyModule_AddIntMacro(m, IPV6_JOIN_GROUP); + ADD_INT_MACRO(m, IPV6_JOIN_GROUP); #endif #ifdef IPV6_LEAVE_GROUP - PyModule_AddIntMacro(m, IPV6_LEAVE_GROUP); + ADD_INT_MACRO(m, IPV6_LEAVE_GROUP); #endif #ifdef IPV6_MULTICAST_HOPS - PyModule_AddIntMacro(m, IPV6_MULTICAST_HOPS); + ADD_INT_MACRO(m, IPV6_MULTICAST_HOPS); #endif #ifdef IPV6_MULTICAST_IF - PyModule_AddIntMacro(m, IPV6_MULTICAST_IF); + ADD_INT_MACRO(m, IPV6_MULTICAST_IF); #endif #ifdef IPV6_MULTICAST_LOOP - PyModule_AddIntMacro(m, IPV6_MULTICAST_LOOP); + ADD_INT_MACRO(m, IPV6_MULTICAST_LOOP); #endif #ifdef IPV6_UNICAST_HOPS - PyModule_AddIntMacro(m, IPV6_UNICAST_HOPS); + ADD_INT_MACRO(m, IPV6_UNICAST_HOPS); #endif /* Additional IPV6 socket options, defined in RFC 3493 */ #ifdef IPV6_V6ONLY - PyModule_AddIntMacro(m, IPV6_V6ONLY); + ADD_INT_MACRO(m, IPV6_V6ONLY); #endif /* Advanced IPV6 socket options, from RFC 3542 */ #ifdef IPV6_CHECKSUM - PyModule_AddIntMacro(m, IPV6_CHECKSUM); + ADD_INT_MACRO(m, IPV6_CHECKSUM); #endif #ifdef IPV6_DONTFRAG - PyModule_AddIntMacro(m, IPV6_DONTFRAG); + ADD_INT_MACRO(m, IPV6_DONTFRAG); #endif #ifdef IPV6_DSTOPTS - PyModule_AddIntMacro(m, IPV6_DSTOPTS); + ADD_INT_MACRO(m, IPV6_DSTOPTS); #endif #ifdef IPV6_HOPLIMIT - PyModule_AddIntMacro(m, IPV6_HOPLIMIT); + ADD_INT_MACRO(m, IPV6_HOPLIMIT); #endif #ifdef IPV6_HOPOPTS - PyModule_AddIntMacro(m, IPV6_HOPOPTS); + ADD_INT_MACRO(m, IPV6_HOPOPTS); #endif #ifdef IPV6_NEXTHOP - PyModule_AddIntMacro(m, IPV6_NEXTHOP); + ADD_INT_MACRO(m, IPV6_NEXTHOP); #endif #ifdef IPV6_PATHMTU - PyModule_AddIntMacro(m, IPV6_PATHMTU); + ADD_INT_MACRO(m, IPV6_PATHMTU); #endif #ifdef IPV6_PKTINFO - PyModule_AddIntMacro(m, IPV6_PKTINFO); + ADD_INT_MACRO(m, IPV6_PKTINFO); #endif #ifdef IPV6_RECVDSTOPTS - PyModule_AddIntMacro(m, IPV6_RECVDSTOPTS); + ADD_INT_MACRO(m, IPV6_RECVDSTOPTS); #endif #ifdef IPV6_RECVHOPLIMIT - PyModule_AddIntMacro(m, IPV6_RECVHOPLIMIT); + ADD_INT_MACRO(m, IPV6_RECVHOPLIMIT); #endif #ifdef IPV6_RECVHOPOPTS - PyModule_AddIntMacro(m, IPV6_RECVHOPOPTS); + ADD_INT_MACRO(m, IPV6_RECVHOPOPTS); #endif #ifdef IPV6_RECVPKTINFO - PyModule_AddIntMacro(m, IPV6_RECVPKTINFO); + ADD_INT_MACRO(m, IPV6_RECVPKTINFO); #endif #ifdef IPV6_RECVRTHDR - PyModule_AddIntMacro(m, IPV6_RECVRTHDR); + ADD_INT_MACRO(m, IPV6_RECVRTHDR); #endif #ifdef IPV6_RECVTCLASS - PyModule_AddIntMacro(m, IPV6_RECVTCLASS); + ADD_INT_MACRO(m, IPV6_RECVTCLASS); #endif #ifdef IPV6_RTHDR - PyModule_AddIntMacro(m, IPV6_RTHDR); + ADD_INT_MACRO(m, IPV6_RTHDR); #endif #ifdef IPV6_RTHDRDSTOPTS - PyModule_AddIntMacro(m, IPV6_RTHDRDSTOPTS); + ADD_INT_MACRO(m, IPV6_RTHDRDSTOPTS); #endif #ifdef IPV6_RTHDR_TYPE_0 - PyModule_AddIntMacro(m, IPV6_RTHDR_TYPE_0); + ADD_INT_MACRO(m, IPV6_RTHDR_TYPE_0); #endif #ifdef IPV6_RECVPATHMTU - PyModule_AddIntMacro(m, IPV6_RECVPATHMTU); + ADD_INT_MACRO(m, IPV6_RECVPATHMTU); #endif #ifdef IPV6_TCLASS - PyModule_AddIntMacro(m, IPV6_TCLASS); + ADD_INT_MACRO(m, IPV6_TCLASS); #endif #ifdef IPV6_USE_MIN_MTU - PyModule_AddIntMacro(m, IPV6_USE_MIN_MTU); + ADD_INT_MACRO(m, IPV6_USE_MIN_MTU); #endif /* TCP options */ #ifdef TCP_NODELAY - PyModule_AddIntMacro(m, TCP_NODELAY); + ADD_INT_MACRO(m, TCP_NODELAY); #endif #ifdef TCP_MAXSEG - PyModule_AddIntMacro(m, TCP_MAXSEG); + ADD_INT_MACRO(m, TCP_MAXSEG); #endif #ifdef TCP_CORK - PyModule_AddIntMacro(m, TCP_CORK); + ADD_INT_MACRO(m, TCP_CORK); #endif #ifdef TCP_KEEPIDLE - PyModule_AddIntMacro(m, TCP_KEEPIDLE); + ADD_INT_MACRO(m, TCP_KEEPIDLE); #endif /* TCP_KEEPALIVE is OSX's TCP_KEEPIDLE equivalent */ #if defined(__APPLE__) && defined(TCP_KEEPALIVE) - PyModule_AddIntMacro(m, TCP_KEEPALIVE); + ADD_INT_MACRO(m, TCP_KEEPALIVE); #endif #ifdef TCP_KEEPINTVL - PyModule_AddIntMacro(m, TCP_KEEPINTVL); + ADD_INT_MACRO(m, TCP_KEEPINTVL); #endif #ifdef TCP_KEEPCNT - PyModule_AddIntMacro(m, TCP_KEEPCNT); + ADD_INT_MACRO(m, TCP_KEEPCNT); #endif #ifdef TCP_SYNCNT - PyModule_AddIntMacro(m, TCP_SYNCNT); + ADD_INT_MACRO(m, TCP_SYNCNT); #endif #ifdef TCP_LINGER2 - PyModule_AddIntMacro(m, TCP_LINGER2); + ADD_INT_MACRO(m, TCP_LINGER2); #endif #ifdef TCP_DEFER_ACCEPT - PyModule_AddIntMacro(m, TCP_DEFER_ACCEPT); + ADD_INT_MACRO(m, TCP_DEFER_ACCEPT); #endif #ifdef TCP_WINDOW_CLAMP - PyModule_AddIntMacro(m, TCP_WINDOW_CLAMP); + ADD_INT_MACRO(m, TCP_WINDOW_CLAMP); #endif #ifdef TCP_INFO - PyModule_AddIntMacro(m, TCP_INFO); + ADD_INT_MACRO(m, TCP_INFO); #endif #ifdef TCP_CONNECTION_INFO - PyModule_AddIntMacro(m, TCP_CONNECTION_INFO); + ADD_INT_MACRO(m, TCP_CONNECTION_INFO); #endif #ifdef TCP_QUICKACK - PyModule_AddIntMacro(m, TCP_QUICKACK); -#endif -#ifdef TCP_FASTOPEN - PyModule_AddIntMacro(m, TCP_FASTOPEN); + ADD_INT_MACRO(m, TCP_QUICKACK); #endif #ifdef TCP_CONGESTION - PyModule_AddIntMacro(m, TCP_CONGESTION); + ADD_INT_MACRO(m, TCP_CONGESTION); +#endif +#ifdef TCP_MD5SIG + ADD_INT_MACRO(m, TCP_MD5SIG); +#endif +#ifdef TCP_THIN_LINEAR_TIMEOUTS + ADD_INT_MACRO(m, TCP_THIN_LINEAR_TIMEOUTS); +#endif +#ifdef TCP_THIN_DUPACK + ADD_INT_MACRO(m, TCP_THIN_DUPACK); #endif #ifdef TCP_USER_TIMEOUT - PyModule_AddIntMacro(m, TCP_USER_TIMEOUT); + ADD_INT_MACRO(m, TCP_USER_TIMEOUT); +#endif +#ifdef TCP_REPAIR + ADD_INT_MACRO(m, TCP_REPAIR); +#endif +#ifdef TCP_REPAIR_QUEUE + ADD_INT_MACRO(m, TCP_REPAIR_QUEUE); +#endif +#ifdef TCP_QUEUE_SEQ + ADD_INT_MACRO(m, TCP_QUEUE_SEQ); +#endif +#ifdef TCP_REPAIR_OPTIONS + ADD_INT_MACRO(m, TCP_REPAIR_OPTIONS); +#endif +#ifdef TCP_FASTOPEN + ADD_INT_MACRO(m, TCP_FASTOPEN); +#endif +#ifdef TCP_TIMESTAMP + ADD_INT_MACRO(m, TCP_TIMESTAMP); #endif #ifdef TCP_NOTSENT_LOWAT - PyModule_AddIntMacro(m, TCP_NOTSENT_LOWAT); + ADD_INT_MACRO(m, TCP_NOTSENT_LOWAT); +#endif +#ifdef TCP_CC_INFO + ADD_INT_MACRO(m, TCP_CC_INFO); +#endif +#ifdef TCP_SAVE_SYN + ADD_INT_MACRO(m, TCP_SAVE_SYN); +#endif +#ifdef TCP_SAVED_SYN + ADD_INT_MACRO(m, TCP_SAVED_SYN); +#endif +#ifdef TCP_REPAIR_WINDOW + ADD_INT_MACRO(m, TCP_REPAIR_WINDOW); +#endif +#ifdef TCP_FASTOPEN_CONNECT + ADD_INT_MACRO(m, TCP_FASTOPEN_CONNECT); +#endif +#ifdef TCP_ULP + ADD_INT_MACRO(m, TCP_ULP); +#endif +#ifdef TCP_MD5SIG_EXT + ADD_INT_MACRO(m, TCP_MD5SIG_EXT); +#endif +#ifdef TCP_FASTOPEN_KEY + ADD_INT_MACRO(m, TCP_FASTOPEN_KEY); +#endif +#ifdef TCP_FASTOPEN_NO_COOKIE + ADD_INT_MACRO(m, TCP_FASTOPEN_NO_COOKIE); +#endif +#ifdef TCP_ZEROCOPY_RECEIVE + ADD_INT_MACRO(m, TCP_ZEROCOPY_RECEIVE); +#endif +#ifdef TCP_INQ + ADD_INT_MACRO(m, TCP_INQ); +#endif +#ifdef TCP_TX_DELAY + ADD_INT_MACRO(m, TCP_TX_DELAY); #endif /* IPX options */ #ifdef IPX_TYPE - PyModule_AddIntMacro(m, IPX_TYPE); + ADD_INT_MACRO(m, IPX_TYPE); #endif /* Reliable Datagram Sockets */ #ifdef RDS_CMSG_RDMA_ARGS - PyModule_AddIntMacro(m, RDS_CMSG_RDMA_ARGS); + ADD_INT_MACRO(m, RDS_CMSG_RDMA_ARGS); #endif #ifdef RDS_CMSG_RDMA_DEST - PyModule_AddIntMacro(m, RDS_CMSG_RDMA_DEST); + ADD_INT_MACRO(m, RDS_CMSG_RDMA_DEST); #endif #ifdef RDS_CMSG_RDMA_MAP - PyModule_AddIntMacro(m, RDS_CMSG_RDMA_MAP); + ADD_INT_MACRO(m, RDS_CMSG_RDMA_MAP); #endif #ifdef RDS_CMSG_RDMA_STATUS - PyModule_AddIntMacro(m, RDS_CMSG_RDMA_STATUS); + ADD_INT_MACRO(m, RDS_CMSG_RDMA_STATUS); #endif #ifdef RDS_CMSG_RDMA_UPDATE - PyModule_AddIntMacro(m, RDS_CMSG_RDMA_UPDATE); + ADD_INT_MACRO(m, RDS_CMSG_RDMA_UPDATE); #endif #ifdef RDS_RDMA_READWRITE - PyModule_AddIntMacro(m, RDS_RDMA_READWRITE); + ADD_INT_MACRO(m, RDS_RDMA_READWRITE); #endif #ifdef RDS_RDMA_FENCE - PyModule_AddIntMacro(m, RDS_RDMA_FENCE); + ADD_INT_MACRO(m, RDS_RDMA_FENCE); #endif #ifdef RDS_RDMA_INVALIDATE - PyModule_AddIntMacro(m, RDS_RDMA_INVALIDATE); + ADD_INT_MACRO(m, RDS_RDMA_INVALIDATE); #endif #ifdef RDS_RDMA_USE_ONCE - PyModule_AddIntMacro(m, RDS_RDMA_USE_ONCE); + ADD_INT_MACRO(m, RDS_RDMA_USE_ONCE); #endif #ifdef RDS_RDMA_DONTWAIT - PyModule_AddIntMacro(m, RDS_RDMA_DONTWAIT); + ADD_INT_MACRO(m, RDS_RDMA_DONTWAIT); #endif #ifdef RDS_RDMA_NOTIFY_ME - PyModule_AddIntMacro(m, RDS_RDMA_NOTIFY_ME); + ADD_INT_MACRO(m, RDS_RDMA_NOTIFY_ME); #endif #ifdef RDS_RDMA_SILENT - PyModule_AddIntMacro(m, RDS_RDMA_SILENT); + ADD_INT_MACRO(m, RDS_RDMA_SILENT); #endif /* get{addr,name}info parameters */ #ifdef EAI_ADDRFAMILY - PyModule_AddIntMacro(m, EAI_ADDRFAMILY); + ADD_INT_MACRO(m, EAI_ADDRFAMILY); #endif #ifdef EAI_AGAIN - PyModule_AddIntMacro(m, EAI_AGAIN); + ADD_INT_MACRO(m, EAI_AGAIN); #endif #ifdef EAI_BADFLAGS - PyModule_AddIntMacro(m, EAI_BADFLAGS); + ADD_INT_MACRO(m, EAI_BADFLAGS); #endif #ifdef EAI_FAIL - PyModule_AddIntMacro(m, EAI_FAIL); + ADD_INT_MACRO(m, EAI_FAIL); #endif #ifdef EAI_FAMILY - PyModule_AddIntMacro(m, EAI_FAMILY); + ADD_INT_MACRO(m, EAI_FAMILY); #endif #ifdef EAI_MEMORY - PyModule_AddIntMacro(m, EAI_MEMORY); + ADD_INT_MACRO(m, EAI_MEMORY); #endif #ifdef EAI_NODATA - PyModule_AddIntMacro(m, EAI_NODATA); + ADD_INT_MACRO(m, EAI_NODATA); #endif #ifdef EAI_NONAME - PyModule_AddIntMacro(m, EAI_NONAME); + ADD_INT_MACRO(m, EAI_NONAME); #endif #ifdef EAI_OVERFLOW - PyModule_AddIntMacro(m, EAI_OVERFLOW); + ADD_INT_MACRO(m, EAI_OVERFLOW); #endif #ifdef EAI_SERVICE - PyModule_AddIntMacro(m, EAI_SERVICE); + ADD_INT_MACRO(m, EAI_SERVICE); #endif #ifdef EAI_SOCKTYPE - PyModule_AddIntMacro(m, EAI_SOCKTYPE); + ADD_INT_MACRO(m, EAI_SOCKTYPE); #endif #ifdef EAI_SYSTEM - PyModule_AddIntMacro(m, EAI_SYSTEM); + ADD_INT_MACRO(m, EAI_SYSTEM); #endif #ifdef EAI_BADHINTS - PyModule_AddIntMacro(m, EAI_BADHINTS); + ADD_INT_MACRO(m, EAI_BADHINTS); #endif #ifdef EAI_PROTOCOL - PyModule_AddIntMacro(m, EAI_PROTOCOL); + ADD_INT_MACRO(m, EAI_PROTOCOL); #endif #ifdef EAI_MAX - PyModule_AddIntMacro(m, EAI_MAX); + ADD_INT_MACRO(m, EAI_MAX); #endif #ifdef AI_PASSIVE - PyModule_AddIntMacro(m, AI_PASSIVE); + ADD_INT_MACRO(m, AI_PASSIVE); #endif #ifdef AI_CANONNAME - PyModule_AddIntMacro(m, AI_CANONNAME); + ADD_INT_MACRO(m, AI_CANONNAME); #endif #ifdef AI_NUMERICHOST - PyModule_AddIntMacro(m, AI_NUMERICHOST); + ADD_INT_MACRO(m, AI_NUMERICHOST); #endif #ifdef AI_NUMERICSERV - PyModule_AddIntMacro(m, AI_NUMERICSERV); + ADD_INT_MACRO(m, AI_NUMERICSERV); #endif #ifdef AI_MASK - PyModule_AddIntMacro(m, AI_MASK); + ADD_INT_MACRO(m, AI_MASK); #endif #ifdef AI_ALL - PyModule_AddIntMacro(m, AI_ALL); + ADD_INT_MACRO(m, AI_ALL); #endif #ifdef AI_V4MAPPED_CFG - PyModule_AddIntMacro(m, AI_V4MAPPED_CFG); + ADD_INT_MACRO(m, AI_V4MAPPED_CFG); #endif #ifdef AI_ADDRCONFIG - PyModule_AddIntMacro(m, AI_ADDRCONFIG); + ADD_INT_MACRO(m, AI_ADDRCONFIG); #endif #ifdef AI_V4MAPPED - PyModule_AddIntMacro(m, AI_V4MAPPED); + ADD_INT_MACRO(m, AI_V4MAPPED); #endif #ifdef AI_DEFAULT - PyModule_AddIntMacro(m, AI_DEFAULT); + ADD_INT_MACRO(m, AI_DEFAULT); #endif #ifdef NI_MAXHOST - PyModule_AddIntMacro(m, NI_MAXHOST); + ADD_INT_MACRO(m, NI_MAXHOST); #endif #ifdef NI_MAXSERV - PyModule_AddIntMacro(m, NI_MAXSERV); + ADD_INT_MACRO(m, NI_MAXSERV); #endif #ifdef NI_NOFQDN - PyModule_AddIntMacro(m, NI_NOFQDN); + ADD_INT_MACRO(m, NI_NOFQDN); #endif #ifdef NI_NUMERICHOST - PyModule_AddIntMacro(m, NI_NUMERICHOST); + ADD_INT_MACRO(m, NI_NUMERICHOST); #endif #ifdef NI_NAMEREQD - PyModule_AddIntMacro(m, NI_NAMEREQD); + ADD_INT_MACRO(m, NI_NAMEREQD); #endif #ifdef NI_NUMERICSERV - PyModule_AddIntMacro(m, NI_NUMERICSERV); + ADD_INT_MACRO(m, NI_NUMERICSERV); #endif #ifdef NI_DGRAM - PyModule_AddIntMacro(m, NI_DGRAM); + ADD_INT_MACRO(m, NI_DGRAM); #endif /* shutdown() parameters */ #ifdef SHUT_RD - PyModule_AddIntMacro(m, SHUT_RD); + ADD_INT_MACRO(m, SHUT_RD); #elif defined(SD_RECEIVE) - PyModule_AddIntConstant(m, "SHUT_RD", SD_RECEIVE); + ADD_INT_CONST(m, "SHUT_RD", SD_RECEIVE); #else - PyModule_AddIntConstant(m, "SHUT_RD", 0); + ADD_INT_CONST(m, "SHUT_RD", 0); #endif #ifdef SHUT_WR - PyModule_AddIntMacro(m, SHUT_WR); + ADD_INT_MACRO(m, SHUT_WR); #elif defined(SD_SEND) - PyModule_AddIntConstant(m, "SHUT_WR", SD_SEND); + ADD_INT_CONST(m, "SHUT_WR", SD_SEND); #else - PyModule_AddIntConstant(m, "SHUT_WR", 1); + ADD_INT_CONST(m, "SHUT_WR", 1); #endif #ifdef SHUT_RDWR - PyModule_AddIntMacro(m, SHUT_RDWR); + ADD_INT_MACRO(m, SHUT_RDWR); #elif defined(SD_BOTH) - PyModule_AddIntConstant(m, "SHUT_RDWR", SD_BOTH); + ADD_INT_CONST(m, "SHUT_RDWR", SD_BOTH); #else - PyModule_AddIntConstant(m, "SHUT_RDWR", 2); + ADD_INT_CONST(m, "SHUT_RDWR", 2); #endif #ifdef SIO_RCVALL @@ -8529,22 +8835,26 @@ PyInit__socket(void) #endif }; int i; - for(i = 0; i<Py_ARRAY_LENGTH(codes); ++i) { - PyObject *tmp; - tmp = PyLong_FromUnsignedLong(codes[i]); - if (tmp == NULL) - return NULL; - PyModule_AddObject(m, names[i], tmp); + for (i = 0; i < Py_ARRAY_LENGTH(codes); ++i) { + PyObject *tmp = PyLong_FromUnsignedLong(codes[i]); + if (tmp == NULL) { + goto error; + } + int rc = PyModule_AddObjectRef(m, names[i], tmp); + Py_DECREF(tmp); + if (rc < 0) { + goto error; + } } } - PyModule_AddIntMacro(m, RCVALL_OFF); - PyModule_AddIntMacro(m, RCVALL_ON); - PyModule_AddIntMacro(m, RCVALL_SOCKETLEVELONLY); + ADD_INT_MACRO(m, RCVALL_OFF); + ADD_INT_MACRO(m, RCVALL_ON); + ADD_INT_MACRO(m, RCVALL_SOCKETLEVELONLY); #ifdef RCVALL_IPLEVEL - PyModule_AddIntMacro(m, RCVALL_IPLEVEL); + ADD_INT_MACRO(m, RCVALL_IPLEVEL); #endif #ifdef RCVALL_MAX - PyModule_AddIntMacro(m, RCVALL_MAX); + ADD_INT_MACRO(m, RCVALL_MAX); #endif #endif /* _MSTCPIP_ */ @@ -8556,10 +8866,66 @@ PyInit__socket(void) #ifdef MS_WINDOWS /* remove some flags on older version Windows during run-time */ if (remove_unusable_flags(m) < 0) { - Py_DECREF(m); - return NULL; + goto error; } #endif - return m; +#undef ADD_INT_MACRO +#undef ADD_INT_CONST +#undef ADD_STR_CONST + + return 0; + +error: + return -1; +} + +static struct PyModuleDef_Slot socket_slots[] = { + {Py_mod_exec, socket_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, + {0, NULL}, +}; + +static int +socket_traverse(PyObject *mod, visitproc visit, void *arg) +{ + socket_state *state = get_module_state(mod); + Py_VISIT(state->sock_type); + Py_VISIT(state->socket_herror); + Py_VISIT(state->socket_gaierror); + return 0; +} + +static int +socket_clear(PyObject *mod) +{ + socket_state *state = get_module_state(mod); + Py_CLEAR(state->sock_type); + Py_CLEAR(state->socket_herror); + Py_CLEAR(state->socket_gaierror); + return 0; +} + +static void +socket_free(void *mod) +{ + (void)socket_clear((PyObject *)mod); +} + +static struct PyModuleDef socketmodule = { + .m_base = PyModuleDef_HEAD_INIT, + .m_name = PySocket_MODULE_NAME, + .m_doc = socket_doc, + .m_size = sizeof(socket_state), + .m_methods = socket_methods, + .m_slots = socket_slots, + .m_traverse = socket_traverse, + .m_clear = socket_clear, + .m_free = socket_free, +}; + +PyMODINIT_FUNC +PyInit__socket(void) +{ + return PyModuleDef_Init(&socketmodule); } diff --git a/Modules/socketmodule.h b/Modules/socketmodule.h index 1b35b11c..f5ca0045 100644 --- a/Modules/socketmodule.h +++ b/Modules/socketmodule.h @@ -76,6 +76,15 @@ struct SOCKADDR_BTH_REDEF { # else typedef int socklen_t; # endif /* IPPROTO_IPV6 */ + +/* Remove ifdef once Py_WINVER >= 0x0604 + * socket.h only defines AF_HYPERV if _WIN32_WINNT is at that level or higher + * so for now it's just manually defined. + */ +# ifndef AF_HYPERV +# define AF_HYPERV 34 +# endif +# include <hvsocket.h> #endif /* MS_WINDOWS */ #ifdef HAVE_SYS_UN_H @@ -240,6 +249,11 @@ typedef int SOCKET_T; #define PyLong_AsSocket_t(fd) (SOCKET_T)PyLong_AsLongLong(fd) #endif +// AF_HYPERV is only supported on Windows +#if defined(AF_HYPERV) && defined(MS_WINDOWS) +# define HAVE_AF_HYPERV +#endif + /* Socket address */ typedef union sock_addr { struct sockaddr_in in; @@ -288,6 +302,9 @@ typedef union sock_addr { #ifdef HAVE_LINUX_TIPC_H struct sockaddr_tipc tipc; #endif +#ifdef HAVE_AF_HYPERV + SOCKADDR_HV hv; +#endif } sock_addr_t; /* The object holding a socket. It holds some extra information, @@ -305,6 +322,7 @@ typedef struct { sets a Python exception */ _PyTime_t sock_timeout; /* Operation timeout in seconds; 0.0 means non-blocking */ + struct _socket_state *state; } PySocketSockObject; /* --- C API ----------------------------------------------------*/ diff --git a/Modules/spwdmodule.c b/Modules/spwdmodule.c index 42123c93..13f1115f 100644 --- a/Modules/spwdmodule.c +++ b/Modules/spwdmodule.c @@ -224,6 +224,7 @@ spwdmodule_exec(PyObject *module) static PyModuleDef_Slot spwdmodule_slots[] = { {Py_mod_exec, spwdmodule_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; diff --git a/Modules/symtablemodule.c b/Modules/symtablemodule.c index c25ecc2b..1f09c23b 100644 --- a/Modules/symtablemodule.c +++ b/Modules/symtablemodule.c @@ -56,8 +56,7 @@ _symtable_symtable_impl(PyObject *module, PyObject *source, if (st == NULL) { return NULL; } - t = (PyObject *)st->st_top; - Py_INCREF(t); + t = Py_NewRef(st->st_top); _PySymtable_Free(st); return t; } @@ -67,12 +66,6 @@ static PyMethodDef symtable_methods[] = { {NULL, NULL} /* sentinel */ }; -static int -symtable_init_stentry_type(PyObject *m) -{ - return PyType_Ready(&PySTEntry_Type); -} - static int symtable_init_constants(PyObject *m) { @@ -92,6 +85,14 @@ symtable_init_constants(PyObject *m) if (PyModule_AddIntConstant(m, "TYPE_CLASS", ClassBlock) < 0) return -1; if (PyModule_AddIntConstant(m, "TYPE_MODULE", ModuleBlock) < 0) return -1; + if (PyModule_AddIntConstant(m, "TYPE_ANNOTATION", AnnotationBlock) < 0) + return -1; + if (PyModule_AddIntConstant(m, "TYPE_TYPE_VAR_BOUND", TypeVarBoundBlock) < 0) + return -1; + if (PyModule_AddIntConstant(m, "TYPE_TYPE_ALIAS", TypeAliasBlock) < 0) + return -1; + if (PyModule_AddIntConstant(m, "TYPE_TYPE_PARAM", TypeParamBlock) < 0) + return -1; if (PyModule_AddIntMacro(m, LOCAL) < 0) return -1; if (PyModule_AddIntMacro(m, GLOBAL_EXPLICIT) < 0) return -1; @@ -106,8 +107,8 @@ symtable_init_constants(PyObject *m) } static PyModuleDef_Slot symtable_slots[] = { - {Py_mod_exec, symtable_init_stentry_type}, {Py_mod_exec, symtable_init_constants}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; diff --git a/Modules/syslogmodule.c b/Modules/syslogmodule.c index 8416b634..6db8de9c 100644 --- a/Modules/syslogmodule.c +++ b/Modules/syslogmodule.c @@ -54,10 +54,23 @@ Revision history: #include <syslog.h> -/* only one instance, only one syslog, so globals should be ok */ -static PyObject *S_ident_o = NULL; /* identifier, held by openlog() */ +/*[clinic input] +module syslog +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=478f4ac94a1d4cae]*/ + +#include "clinic/syslogmodule.c.h" + +/* only one instance, only one syslog, so globals should be ok, + * these fields are writable from the main interpreter only. */ +static PyObject *S_ident_o = NULL; // identifier, held by openlog() static char S_log_open = 0; +static inline int +is_main_interpreter(void) +{ + return (PyInterpreterState_Get() == PyInterpreterState_Main()); +} static PyObject * syslog_get_argv(void) @@ -113,18 +126,29 @@ syslog_get_argv(void) } +/*[clinic input] +syslog.openlog + + ident: unicode = NULL + logoption as logopt: long = 0 + facility: long(c_default="LOG_USER") = LOG_USER + +Set logging options of subsequent syslog() calls. +[clinic start generated code]*/ + static PyObject * -syslog_openlog(PyObject * self, PyObject * args, PyObject *kwds) +syslog_openlog_impl(PyObject *module, PyObject *ident, long logopt, + long facility) +/*[clinic end generated code: output=5476c12829b6eb75 input=8a987a96a586eee7]*/ { - long logopt = 0; - long facility = LOG_USER; - PyObject *ident = NULL; - static char *keywords[] = {"ident", "logoption", "facility", 0}; - const char *ident_str = NULL; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, - "|Ull:openlog", keywords, &ident, &logopt, &facility)) + // Since the sys.openlog changes the process level state of syslog library, + // this operation is only allowed for the main interpreter. + if (!is_main_interpreter()) { + PyErr_SetString(PyExc_RuntimeError, "subinterpreter can't use syslog.openlog()"); return NULL; + } + + const char *ident_str = NULL; if (ident) { Py_INCREF(ident); @@ -158,55 +182,48 @@ syslog_openlog(PyObject * self, PyObject * args, PyObject *kwds) } -static PyObject * -syslog_syslog(PyObject * self, PyObject * args) -{ - PyObject *message_object; - const char *message; - int priority = LOG_INFO; - if (!PyArg_ParseTuple(args, "iU;[priority,] message string", - &priority, &message_object)) { - PyErr_Clear(); - if (!PyArg_ParseTuple(args, "U;[priority,] message string", - &message_object)) - return NULL; - } +/*[clinic input] +syslog.syslog - message = PyUnicode_AsUTF8(message_object); - if (message == NULL) - return NULL; + [ + priority: int(c_default="LOG_INFO") = LOG_INFO + ] + message: str + + / + +Send the string message to the system logger. +[clinic start generated code]*/ + +static PyObject * +syslog_syslog_impl(PyObject *module, int group_left_1, int priority, + const char *message) +/*[clinic end generated code: output=c3dbc73445a0e078 input=ac83d92b12ea3d4e]*/ +{ if (PySys_Audit("syslog.syslog", "is", priority, message) < 0) { return NULL; } /* if log is not opened, open it now */ if (!S_log_open) { - PyObject *openargs; - - /* Continue even if PyTuple_New fails, because openlog(3) is optional. - * So, we can still do logging in the unlikely event things are so hosed - * that we can't do this tuple. - */ - if ((openargs = PyTuple_New(0))) { - PyObject *openlog_ret = syslog_openlog(self, openargs, NULL); - Py_DECREF(openargs); - if (openlog_ret == NULL) { - return NULL; - } - Py_DECREF(openlog_ret); + if (!is_main_interpreter()) { + PyErr_SetString(PyExc_RuntimeError, "subinterpreter can't use syslog.syslog() " + "until the syslog is opened by the main interpreter"); + return NULL; } - else { + PyObject *openlog_ret = syslog_openlog_impl(module, NULL, 0, LOG_USER); + if (openlog_ret == NULL) { return NULL; } + Py_DECREF(openlog_ret); } /* Incref ident, because it can be decrefed if syslog.openlog() is * called when the GIL is released. */ - PyObject *ident = S_ident_o; - Py_XINCREF(ident); + PyObject *ident = Py_XNewRef(S_ident_o); #ifdef __APPLE__ // gh-98178: On macOS, libc syslog() is not thread-safe syslog(priority, "%s", message); @@ -219,9 +236,24 @@ syslog_syslog(PyObject * self, PyObject * args) Py_RETURN_NONE; } + +/*[clinic input] +syslog.closelog + +Reset the syslog module values and call the system library closelog(). +[clinic start generated code]*/ + static PyObject * -syslog_closelog(PyObject *self, PyObject *unused) +syslog_closelog_impl(PyObject *module) +/*[clinic end generated code: output=97890a80a24b1b84 input=fb77a54d447acf07]*/ { + // Since the sys.closelog changes the process level state of syslog library, + // this operation is only allowed for the main interpreter. + if (!is_main_interpreter()) { + PyErr_SetString(PyExc_RuntimeError, "sunbinterpreter can't use syslog.closelog()"); + return NULL; + } + if (PySys_Audit("syslog.closelog", NULL) < 0) { return NULL; } @@ -233,51 +265,67 @@ syslog_closelog(PyObject *self, PyObject *unused) Py_RETURN_NONE; } -static PyObject * -syslog_setlogmask(PyObject *self, PyObject *args) -{ - long maskpri, omaskpri; +/*[clinic input] +syslog.setlogmask -> long - if (!PyArg_ParseTuple(args, "l;mask for priority", &maskpri)) - return NULL; + maskpri: long + / + +Set the priority mask to maskpri and return the previous mask value. +[clinic start generated code]*/ + +static long +syslog_setlogmask_impl(PyObject *module, long maskpri) +/*[clinic end generated code: output=d6ed163917b434bf input=adff2c2b76c7629c]*/ +{ if (PySys_Audit("syslog.setlogmask", "l", maskpri) < 0) { - return NULL; + return -1; } - omaskpri = setlogmask(maskpri); - return PyLong_FromLong(omaskpri); + + return setlogmask(maskpri); } -static PyObject * -syslog_log_mask(PyObject *self, PyObject *args) +/*[clinic input] +syslog.LOG_MASK -> long + + pri: long + / + +Calculates the mask for the individual priority pri. +[clinic start generated code]*/ + +static long +syslog_LOG_MASK_impl(PyObject *module, long pri) +/*[clinic end generated code: output=c4a5bbfcc74c7c94 input=534829cb7fb5f7d2]*/ { - long mask; - long pri; - if (!PyArg_ParseTuple(args, "l:LOG_MASK", &pri)) - return NULL; - mask = LOG_MASK(pri); - return PyLong_FromLong(mask); + return LOG_MASK(pri); } -static PyObject * -syslog_log_upto(PyObject *self, PyObject *args) +/*[clinic input] +syslog.LOG_UPTO -> long + + pri: long + / + +Calculates the mask for all priorities up to and including pri. +[clinic start generated code]*/ + +static long +syslog_LOG_UPTO_impl(PyObject *module, long pri) +/*[clinic end generated code: output=9eab083c90601d7e input=5e906d6c406b7458]*/ { - long mask; - long pri; - if (!PyArg_ParseTuple(args, "l:LOG_UPTO", &pri)) - return NULL; - mask = LOG_UPTO(pri); - return PyLong_FromLong(mask); + return LOG_UPTO(pri); } /* List of functions defined in the module */ static PyMethodDef syslog_methods[] = { - {"openlog", _PyCFunction_CAST(syslog_openlog), METH_VARARGS | METH_KEYWORDS}, - {"closelog", syslog_closelog, METH_NOARGS}, - {"syslog", syslog_syslog, METH_VARARGS}, - {"setlogmask", syslog_setlogmask, METH_VARARGS}, - {"LOG_MASK", syslog_log_mask, METH_VARARGS}, - {"LOG_UPTO", syslog_log_upto, METH_VARARGS}, + SYSLOG_OPENLOG_METHODDEF + SYSLOG_CLOSELOG_METHODDEF + SYSLOG_SYSLOG_METHODDEF + SYSLOG_SETLOGMASK_METHODDEF + SYSLOG_LOG_MASK_METHODDEF + SYSLOG_LOG_UPTO_METHODDEF {NULL, NULL, 0} }; @@ -358,6 +406,7 @@ syslog_exec(PyObject *module) static PyModuleDef_Slot syslog_slots[] = { {Py_mod_exec, syslog_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; diff --git a/Modules/termios.c b/Modules/termios.c index fcc8f042..6dc82005 100644 --- a/Modules/termios.c +++ b/Modules/termios.c @@ -85,7 +85,7 @@ termios_tcgetattr_impl(PyObject *module, int fd) int r; Py_BEGIN_ALLOW_THREADS - r = tcgetattr(fd, &mode); + r = tcgetattr(fd, &mode); Py_END_ALLOW_THREADS if (r == -1) { return PyErr_SetFromErrno(state->TermiosError); @@ -372,7 +372,7 @@ termios_tcgetwinsize_impl(PyObject *module, int fd) #if defined(TIOCGWINSZ) termiosmodulestate *state = PyModule_GetState(module); struct winsize w; - int r; + int r; Py_BEGIN_ALLOW_THREADS r = ioctl(fd, TIOCGWINSZ, &w); @@ -1253,6 +1253,7 @@ termios_exec(PyObject *mod) static PyModuleDef_Slot termios_slots[] = { {Py_mod_exec, termios_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; diff --git a/Modules/timemodule.c b/Modules/timemodule.c index 18f9ddb9..f5b0f39e 100644 --- a/Modules/timemodule.c +++ b/Modules/timemodule.c @@ -30,7 +30,9 @@ # include <i86.h> #else # ifdef MS_WINDOWS -# define WIN32_LEAN_AND_MEAN +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +# endif # include <windows.h> # endif /* MS_WINDOWS */ #endif /* !__WATCOMC__ || __QNX__ */ @@ -62,6 +64,56 @@ #define SEC_TO_NS (1000 * 1000 * 1000) +#if defined(HAVE_TIMES) || defined(HAVE_CLOCK) +static int +check_ticks_per_second(long tps, const char *context) +{ + /* Effectively, check that _PyTime_MulDiv(t, SEC_TO_NS, ticks_per_second) + cannot overflow. */ + if (tps >= 0 && (_PyTime_t)tps > _PyTime_MAX / SEC_TO_NS) { + PyErr_Format(PyExc_OverflowError, "%s is too large", context); + return -1; + } + return 0; +} +#endif /* HAVE_TIMES || HAVE_CLOCK */ + +#ifdef HAVE_TIMES + +# define ticks_per_second _PyRuntime.time.ticks_per_second + +static void +ensure_ticks_per_second(void) +{ + if (_PyRuntime.time.ticks_per_second_initialized) { + return; + } + _PyRuntime.time.ticks_per_second_initialized = 1; +# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK) + ticks_per_second = sysconf(_SC_CLK_TCK); + if (ticks_per_second < 1) { + ticks_per_second = -1; + } +# elif defined(HZ) + ticks_per_second = HZ; +# else + ticks_per_second = 60; /* magic fallback value; may be bogus */ +# endif +} + +#endif /* HAVE_TIMES */ + + +PyStatus +_PyTime_Init(void) +{ +#ifdef HAVE_TIMES + ensure_ticks_per_second(); +#endif + return PyStatus_Ok(); +} + + /* Forward declarations */ static int pysleep(_PyTime_t timeout); @@ -140,18 +192,8 @@ Return the current time in nanoseconds since the Epoch."); static int _PyTime_GetClockWithInfo(_PyTime_t *tp, _Py_clock_info_t *info) { - static int initialized = 0; - - if (!initialized) { - initialized = 1; - - /* Make sure that _PyTime_MulDiv(ticks, SEC_TO_NS, CLOCKS_PER_SEC) - above cannot overflow */ - if ((_PyTime_t)CLOCKS_PER_SEC > _PyTime_MAX / SEC_TO_NS) { - PyErr_SetString(PyExc_OverflowError, - "CLOCKS_PER_SEC is too large"); - return -1; - } + if (check_ticks_per_second(CLOCKS_PER_SEC, "CLOCKS_PER_SEC") < 0) { + return -1; } if (info) { @@ -910,14 +952,9 @@ is not present, current time as returned by localtime() is used.\n\ static PyObject * time_strptime(PyObject *self, PyObject *args) { - PyObject *module, *func, *result; + PyObject *func, *result; - module = PyImport_ImportModule("_strptime"); - if (!module) - return NULL; - - func = PyObject_GetAttr(module, &_Py_ID(_strptime_time)); - Py_DECREF(module); + func = _PyImport_GetModuleAttrString("_strptime", "_strptime_time"); if (!func) { return NULL; } @@ -1100,7 +1137,9 @@ time_tzset(PyObject *self, PyObject *unused) return NULL; } +#if !defined(MS_WINDOWS) || defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) tzset(); +#endif /* Reset timezone, altzone, daylight and tzname */ if (init_timezone(m) < 0) { @@ -1313,36 +1352,10 @@ _PyTime_GetProcessTimeWithInfo(_PyTime_t *tp, _Py_clock_info_t *info) struct tms t; if (times(&t) != (clock_t)-1) { - static long ticks_per_second = -1; - - if (ticks_per_second == -1) { - long freq; -#if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK) - freq = sysconf(_SC_CLK_TCK); - if (freq < 1) { - freq = -1; - } -#elif defined(HZ) - freq = HZ; -#else - freq = 60; /* magic fallback value; may be bogus */ -#endif - - if (freq != -1) { - /* check that _PyTime_MulDiv(t, SEC_TO_NS, ticks_per_second) - cannot overflow below */ -#if LONG_MAX > _PyTime_MAX / SEC_TO_NS - if ((_PyTime_t)freq > _PyTime_MAX / SEC_TO_NS) { - PyErr_SetString(PyExc_OverflowError, - "_SC_CLK_TCK is too large"); - return -1; - } -#endif - - ticks_per_second = freq; - } + assert(_PyRuntime.time.ticks_per_second_initialized); + if (check_ticks_per_second(ticks_per_second, "_SC_CLK_TCK") < 0) { + return -1; } - if (ticks_per_second != -1) { if (info) { info->implementation = "times()"; @@ -1744,7 +1757,9 @@ init_timezone(PyObject *m) */ #ifdef HAVE_DECL_TZNAME PyObject *otz0, *otz1; +#if !defined(MS_WINDOWS) || defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) tzset(); +#endif PyModule_AddIntConstant(m, "timezone", _Py_timezone); #ifdef HAVE_ALTZONE PyModule_AddIntConstant(m, "altzone", altzone); @@ -1775,11 +1790,9 @@ init_timezone(PyObject *m) return -1; } #endif // MS_WINDOWS - PyObject *tzname_obj = Py_BuildValue("(NN)", otz0, otz1); - if (tzname_obj == NULL) { + if (_PyModule_Add(m, "tzname", Py_BuildValue("(NN)", otz0, otz1)) < 0) { return -1; } - PyModule_AddObject(m, "tzname", tzname_obj); #else // !HAVE_DECL_TZNAME static const time_t YEAR = (365 * 24 + 6) * 3600; time_t t; @@ -1822,10 +1835,9 @@ init_timezone(PyObject *m) PyModule_AddIntConstant(m, "daylight", janzone != julyzone); tzname_obj = Py_BuildValue("(zz)", janname, julyname); } - if (tzname_obj == NULL) { + if (_PyModule_Add(m, "tzname", tzname_obj) < 0) { return -1; } - PyModule_AddObject(m, "tzname", tzname_obj); #endif // !HAVE_DECL_TZNAME if (PyErr_Occurred()) { @@ -2092,6 +2104,7 @@ time_module_free(void *module) static struct PyModuleDef_Slot time_slots[] = { {Py_mod_exec, time_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; diff --git a/Modules/tkappinit.c b/Modules/tkappinit.c index 7616d9d3..4c4081e4 100644 --- a/Modules/tkappinit.c +++ b/Modules/tkappinit.c @@ -18,67 +18,14 @@ #include "tkinter.h" -#ifdef TKINTER_PROTECT_LOADTK -/* See Tkapp_TkInit in _tkinter.c for the usage of tk_load_faile */ -static int tk_load_failed; -#endif - int Tcl_AppInit(Tcl_Interp *interp) { const char *_tkinter_skip_tk_init; -#ifdef TKINTER_PROTECT_LOADTK - const char *_tkinter_tk_failed; -#endif -#ifdef TK_AQUA -#ifndef MAX_PATH_LEN -#define MAX_PATH_LEN 1024 -#endif - char tclLibPath[MAX_PATH_LEN], tkLibPath[MAX_PATH_LEN]; - Tcl_Obj* pathPtr; - - /* pre- Tcl_Init code copied from tkMacOSXAppInit.c */ - Tk_MacOSXOpenBundleResources (interp, "com.tcltk.tcllibrary", - tclLibPath, MAX_PATH_LEN, 0); - - if (tclLibPath[0] != '\0') { - Tcl_SetVar(interp, "tcl_library", tclLibPath, TCL_GLOBAL_ONLY); - Tcl_SetVar(interp, "tclDefaultLibrary", tclLibPath, TCL_GLOBAL_ONLY); - Tcl_SetVar(interp, "tcl_pkgPath", tclLibPath, TCL_GLOBAL_ONLY); - } - - if (tclLibPath[0] != '\0') { - Tcl_SetVar(interp, "tcl_library", tclLibPath, TCL_GLOBAL_ONLY); - Tcl_SetVar(interp, "tclDefaultLibrary", tclLibPath, TCL_GLOBAL_ONLY); - Tcl_SetVar(interp, "tcl_pkgPath", tclLibPath, TCL_GLOBAL_ONLY); - } -#endif if (Tcl_Init (interp) == TCL_ERROR) return TCL_ERROR; -#ifdef TK_AQUA - /* pre- Tk_Init code copied from tkMacOSXAppInit.c */ - Tk_MacOSXOpenBundleResources (interp, "com.tcltk.tklibrary", - tkLibPath, MAX_PATH_LEN, 1); - - if (tclLibPath[0] != '\0') { - pathPtr = Tcl_NewStringObj(tclLibPath, -1); - } else { - Tcl_Obj *pathPtr = TclGetLibraryPath(); - } - - if (tkLibPath[0] != '\0') { - Tcl_Obj *objPtr; - - Tcl_SetVar(interp, "tk_library", tkLibPath, TCL_GLOBAL_ONLY); - objPtr = Tcl_NewStringObj(tkLibPath, -1); - Tcl_ListObjAppendElement(NULL, pathPtr, objPtr); - } - - TclSetLibraryPath(pathPtr); -#endif - #ifdef WITH_XXX /* Initialize modules that don't require Tk */ #endif @@ -90,33 +37,12 @@ Tcl_AppInit(Tcl_Interp *interp) return TCL_OK; } -#ifdef TKINTER_PROTECT_LOADTK - _tkinter_tk_failed = Tcl_GetVar(interp, - "_tkinter_tk_failed", TCL_GLOBAL_ONLY); - - if (tk_load_failed || ( - _tkinter_tk_failed != NULL && - strcmp(_tkinter_tk_failed, "1") == 0)) { - Tcl_SetResult(interp, TKINTER_LOADTK_ERRMSG, TCL_STATIC); - return TCL_ERROR; - } -#endif - if (Tk_Init(interp) == TCL_ERROR) { -#ifdef TKINTER_PROTECT_LOADTK - tk_load_failed = 1; - Tcl_SetVar(interp, "_tkinter_tk_failed", "1", TCL_GLOBAL_ONLY); -#endif return TCL_ERROR; } Tk_MainWindow(interp); -#ifdef TK_AQUA - TkMacOSXInitAppleEvents(interp); - TkMacOSXInitMenus(interp); -#endif - #ifdef WITH_PIL /* 0.2b5 and later -- not yet released as of May 14 */ { extern void TkImaging_Init(Tcl_Interp *); diff --git a/Modules/tkinter.h b/Modules/tkinter.h index cb5a806b..40281c21 100644 --- a/Modules/tkinter.h +++ b/Modules/tkinter.h @@ -16,12 +16,4 @@ (TK_RELEASE_LEVEL << 8) | \ (TK_RELEASE_SERIAL << 0)) -/* Protect Tk 8.4.13 and older from a deadlock that happens when trying - * to load tk after a failed attempt. */ -#if TK_HEX_VERSION < 0x0804020e -#define TKINTER_PROTECT_LOADTK -#define TKINTER_LOADTK_ERRMSG \ - "Calling Tk_Init again after a previous call failed might deadlock" -#endif - #endif /* !TKINTER_H */ diff --git a/Modules/unicodedata.c b/Modules/unicodedata.c index 3c3937f6..41dcd5f8 100644 --- a/Modules/unicodedata.c +++ b/Modules/unicodedata.c @@ -159,8 +159,7 @@ unicodedata_UCD_decimal_impl(PyObject *self, int chr, return NULL; } else { - Py_INCREF(default_value); - return default_value; + return Py_NewRef(default_value); } } return PyLong_FromLong(rc); @@ -194,8 +193,7 @@ unicodedata_UCD_digit_impl(PyObject *self, int chr, PyObject *default_value) return NULL; } else { - Py_INCREF(default_value); - return default_value; + return Py_NewRef(default_value); } } return PyLong_FromLong(rc); @@ -246,8 +244,7 @@ unicodedata_UCD_numeric_impl(PyObject *self, int chr, return NULL; } else { - Py_INCREF(default_value); - return default_value; + return Py_NewRef(default_value); } } return PyFloat_FromDouble(rc); @@ -917,8 +914,7 @@ unicodedata_UCD_is_normalized_impl(PyObject *self, PyObject *form, result = (m == YES) ? Py_True : Py_False; } - Py_INCREF(result); - return result; + return Py_NewRef(result); } @@ -943,39 +939,34 @@ unicodedata_UCD_normalize_impl(PyObject *self, PyObject *form, if (PyUnicode_GET_LENGTH(input) == 0) { /* Special case empty input strings, since resizing them later would cause internal errors. */ - Py_INCREF(input); - return input; + return Py_NewRef(input); } if (PyUnicode_CompareWithASCIIString(form, "NFC") == 0) { if (is_normalized_quickcheck(self, input, true, false, true) == YES) { - Py_INCREF(input); - return input; + return Py_NewRef(input); } return nfc_nfkc(self, input, 0); } if (PyUnicode_CompareWithASCIIString(form, "NFKC") == 0) { if (is_normalized_quickcheck(self, input, true, true, true) == YES) { - Py_INCREF(input); - return input; + return Py_NewRef(input); } return nfc_nfkc(self, input, 1); } if (PyUnicode_CompareWithASCIIString(form, "NFD") == 0) { if (is_normalized_quickcheck(self, input, false, false, true) == YES) { - Py_INCREF(input); - return input; + return Py_NewRef(input); } return nfd_nfkd(self, input, 0); } if (PyUnicode_CompareWithASCIIString(form, "NFKD") == 0) { if (is_normalized_quickcheck(self, input, false, true, true) == YES) { - Py_INCREF(input); - return input; + return Py_NewRef(input); } return nfd_nfkd(self, input, 1); } @@ -1046,11 +1037,12 @@ is_unified_ideograph(Py_UCS4 code) (0x3400 <= code && code <= 0x4DBF) || /* CJK Ideograph Extension A */ (0x4E00 <= code && code <= 0x9FFF) || /* CJK Ideograph */ (0x20000 <= code && code <= 0x2A6DF) || /* CJK Ideograph Extension B */ - (0x2A700 <= code && code <= 0x2B738) || /* CJK Ideograph Extension C */ + (0x2A700 <= code && code <= 0x2B739) || /* CJK Ideograph Extension C */ (0x2B740 <= code && code <= 0x2B81D) || /* CJK Ideograph Extension D */ (0x2B820 <= code && code <= 0x2CEA1) || /* CJK Ideograph Extension E */ (0x2CEB0 <= code && code <= 0x2EBE0) || /* CJK Ideograph Extension F */ - (0x30000 <= code && code <= 0x3134A); /* CJK Ideograph Extension G */ + (0x30000 <= code && code <= 0x3134A) || /* CJK Ideograph Extension G */ + (0x31350 <= code && code <= 0x323AF); /* CJK Ideograph Extension H */ } /* macros used to determine if the given code point is in the PUA range that @@ -1369,8 +1361,7 @@ unicodedata_UCD_name_impl(PyObject *self, int chr, PyObject *default_value) return NULL; } else { - Py_INCREF(default_value); - return default_value; + return Py_NewRef(default_value); } } @@ -1525,6 +1516,7 @@ unicodedata_exec(PyObject *module) static PyModuleDef_Slot unicodedata_slots[] = { {Py_mod_exec, unicodedata_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; diff --git a/Modules/unicodedata_db.h b/Modules/unicodedata_db.h index f56fa035..4c4b2f58 100644 --- a/Modules/unicodedata_db.h +++ b/Modules/unicodedata_db.h @@ -1,13 +1,13 @@ /* this file was generated by Tools/unicode/makeunicodedata.py 3.3 */ -#define UNIDATA_VERSION "14.0.0" +#define UNIDATA_VERSION "15.0.0" /* a list of unique database records */ const _PyUnicode_DatabaseRecord _PyUnicode_Database_Records[] = { {0, 0, 0, 0, 0, 0}, - {13, 0, 15, 0, 5, 0}, - {13, 0, 17, 0, 5, 0}, - {13, 0, 16, 0, 5, 0}, - {13, 0, 18, 0, 5, 0}, + {13, 0, 15, 0, 0, 0}, + {13, 0, 17, 0, 0, 0}, + {13, 0, 16, 0, 0, 0}, + {13, 0, 18, 0, 0, 0}, {10, 0, 18, 0, 3, 0}, {26, 0, 19, 0, 3, 0}, {26, 0, 11, 0, 3, 0}, @@ -24,44 +24,44 @@ const _PyUnicode_DatabaseRecord _PyUnicode_Database_Records[] = { {29, 0, 19, 0, 3, 0}, {20, 0, 19, 0, 3, 0}, {2, 0, 1, 0, 3, 0}, - {10, 0, 13, 0, 5, 136}, + {10, 0, 13, 0, 0, 136}, {26, 0, 19, 0, 4, 0}, {28, 0, 11, 0, 4, 0}, {30, 0, 19, 0, 3, 0}, {29, 0, 19, 0, 4, 136}, - {30, 0, 19, 0, 5, 0}, + {30, 0, 19, 0, 0, 0}, {19, 0, 1, 0, 4, 136}, - {24, 0, 19, 1, 5, 0}, + {24, 0, 19, 1, 0, 0}, {14, 0, 15, 0, 4, 0}, {30, 0, 19, 0, 4, 0}, {29, 0, 19, 0, 3, 136}, {30, 0, 11, 0, 4, 0}, {27, 0, 11, 0, 4, 0}, {9, 0, 9, 0, 4, 136}, - {2, 0, 1, 0, 5, 136}, - {25, 0, 19, 1, 5, 0}, + {2, 0, 1, 0, 0, 136}, + {25, 0, 19, 1, 0, 0}, {9, 0, 19, 0, 4, 136}, - {1, 0, 1, 0, 5, 10}, + {1, 0, 1, 0, 0, 10}, {1, 0, 1, 0, 4, 0}, {27, 0, 19, 0, 4, 0}, {2, 0, 1, 0, 4, 0}, {2, 0, 1, 0, 4, 10}, - {2, 0, 1, 0, 5, 10}, - {1, 0, 1, 0, 5, 0}, + {2, 0, 1, 0, 0, 10}, + {1, 0, 1, 0, 0, 0}, {1, 0, 1, 0, 4, 136}, {2, 0, 1, 0, 4, 136}, - {2, 0, 1, 0, 5, 0}, - {19, 0, 1, 0, 5, 0}, - {1, 0, 1, 0, 5, 136}, - {3, 0, 1, 0, 5, 136}, - {18, 0, 1, 0, 5, 136}, - {18, 0, 19, 0, 5, 0}, - {18, 0, 1, 0, 5, 0}, - {29, 0, 19, 0, 5, 0}, + {2, 0, 1, 0, 0, 0}, + {19, 0, 1, 0, 0, 0}, + {1, 0, 1, 0, 0, 136}, + {3, 0, 1, 0, 0, 136}, + {18, 0, 1, 0, 0, 136}, + {18, 0, 19, 0, 0, 0}, + {18, 0, 1, 0, 0, 0}, + {29, 0, 19, 0, 0, 0}, {29, 0, 19, 0, 4, 0}, {18, 0, 19, 0, 4, 0}, {18, 0, 1, 0, 4, 0}, - {29, 0, 19, 0, 5, 136}, + {29, 0, 19, 0, 0, 136}, {4, 230, 14, 0, 4, 80}, {4, 230, 14, 0, 4, 0}, {4, 232, 14, 0, 4, 0}, @@ -77,173 +77,173 @@ const _PyUnicode_DatabaseRecord _PyUnicode_Database_Records[] = { {4, 0, 14, 0, 4, 0}, {4, 233, 14, 0, 4, 0}, {4, 234, 14, 0, 4, 0}, - {18, 0, 19, 0, 5, 170}, - {26, 0, 19, 0, 5, 170}, - {29, 0, 19, 0, 5, 138}, - {1, 0, 1, 0, 5, 138}, - {27, 0, 19, 0, 5, 0}, + {18, 0, 19, 0, 0, 170}, + {26, 0, 19, 0, 0, 170}, + {29, 0, 19, 0, 0, 138}, + {1, 0, 1, 0, 0, 138}, + {27, 0, 19, 0, 0, 0}, {1, 0, 1, 0, 4, 10}, - {30, 0, 1, 0, 5, 0}, - {4, 230, 14, 0, 5, 0}, - {6, 0, 14, 0, 5, 0}, - {26, 0, 1, 0, 5, 0}, - {21, 0, 19, 0, 5, 0}, - {28, 0, 11, 0, 5, 0}, - {4, 220, 14, 0, 5, 0}, - {4, 222, 14, 0, 5, 0}, - {4, 228, 14, 0, 5, 0}, - {4, 10, 14, 0, 5, 0}, - {4, 11, 14, 0, 5, 0}, - {4, 12, 14, 0, 5, 0}, - {4, 13, 14, 0, 5, 0}, - {4, 14, 14, 0, 5, 0}, - {4, 15, 14, 0, 5, 0}, - {4, 16, 14, 0, 5, 0}, - {4, 17, 14, 0, 5, 0}, - {4, 18, 14, 0, 5, 0}, - {4, 19, 14, 0, 5, 0}, - {4, 20, 14, 0, 5, 0}, - {4, 21, 14, 0, 5, 0}, - {4, 22, 14, 0, 5, 0}, - {21, 0, 4, 0, 5, 0}, - {4, 23, 14, 0, 5, 0}, - {26, 0, 4, 0, 5, 0}, - {4, 24, 14, 0, 5, 0}, - {4, 25, 14, 0, 5, 0}, - {19, 0, 4, 0, 5, 0}, - {14, 0, 12, 0, 5, 0}, - {27, 0, 5, 0, 5, 0}, - {26, 0, 11, 0, 5, 0}, - {28, 0, 5, 0, 5, 0}, - {26, 0, 13, 0, 5, 0}, - {26, 0, 5, 0, 5, 0}, - {4, 30, 14, 0, 5, 0}, - {4, 31, 14, 0, 5, 0}, - {4, 32, 14, 0, 5, 0}, - {14, 0, 5, 0, 5, 0}, - {19, 0, 5, 0, 5, 0}, - {19, 0, 5, 0, 5, 10}, - {18, 0, 5, 0, 5, 0}, - {4, 27, 14, 0, 5, 0}, - {4, 28, 14, 0, 5, 0}, - {4, 29, 14, 0, 5, 0}, - {4, 33, 14, 0, 5, 0}, - {4, 34, 14, 0, 5, 0}, - {4, 230, 14, 0, 5, 80}, - {4, 220, 14, 0, 5, 80}, - {7, 0, 12, 0, 5, 0}, - {26, 0, 12, 0, 5, 0}, - {4, 35, 14, 0, 5, 0}, - {19, 0, 5, 0, 5, 136}, - {7, 0, 9, 0, 5, 0}, - {30, 0, 5, 0, 5, 0}, - {4, 36, 14, 0, 5, 0}, - {4, 0, 14, 0, 5, 0}, - {7, 0, 4, 0, 5, 0}, - {18, 0, 4, 0, 5, 0}, - {26, 0, 19, 0, 5, 0}, - {28, 0, 4, 0, 5, 0}, - {29, 0, 5, 0, 5, 0}, - {5, 0, 1, 0, 5, 0}, - {19, 0, 1, 0, 5, 10}, - {4, 7, 14, 0, 5, 80}, - {4, 9, 14, 0, 5, 0}, - {19, 0, 1, 0, 5, 170}, - {7, 0, 1, 0, 5, 0}, - {4, 7, 14, 0, 5, 0}, - {5, 0, 1, 0, 5, 80}, - {5, 0, 1, 0, 5, 10}, - {9, 0, 1, 0, 5, 0}, - {4, 0, 14, 0, 5, 80}, - {4, 0, 14, 0, 5, 10}, - {4, 84, 14, 0, 5, 0}, - {4, 91, 14, 0, 5, 80}, - {9, 0, 19, 0, 5, 0}, - {4, 0, 1, 0, 5, 0}, - {4, 9, 14, 0, 5, 80}, - {19, 0, 1, 0, 5, 136}, - {4, 103, 14, 0, 5, 0}, - {4, 107, 14, 0, 5, 0}, - {4, 118, 14, 0, 5, 0}, - {4, 122, 14, 0, 5, 0}, - {26, 0, 1, 0, 5, 136}, - {4, 216, 14, 0, 5, 0}, - {22, 0, 19, 1, 5, 0}, - {23, 0, 19, 1, 5, 0}, - {4, 129, 14, 0, 5, 0}, - {4, 130, 14, 0, 5, 0}, - {4, 0, 14, 0, 5, 170}, - {4, 132, 14, 0, 5, 0}, - {4, 0, 14, 0, 5, 136}, + {30, 0, 1, 0, 0, 0}, + {4, 230, 14, 0, 0, 0}, + {6, 0, 14, 0, 0, 0}, + {26, 0, 1, 0, 0, 0}, + {21, 0, 19, 0, 0, 0}, + {28, 0, 11, 0, 0, 0}, + {4, 220, 14, 0, 0, 0}, + {4, 222, 14, 0, 0, 0}, + {4, 228, 14, 0, 0, 0}, + {4, 10, 14, 0, 0, 0}, + {4, 11, 14, 0, 0, 0}, + {4, 12, 14, 0, 0, 0}, + {4, 13, 14, 0, 0, 0}, + {4, 14, 14, 0, 0, 0}, + {4, 15, 14, 0, 0, 0}, + {4, 16, 14, 0, 0, 0}, + {4, 17, 14, 0, 0, 0}, + {4, 18, 14, 0, 0, 0}, + {4, 19, 14, 0, 0, 0}, + {4, 20, 14, 0, 0, 0}, + {4, 21, 14, 0, 0, 0}, + {4, 22, 14, 0, 0, 0}, + {21, 0, 4, 0, 0, 0}, + {4, 23, 14, 0, 0, 0}, + {26, 0, 4, 0, 0, 0}, + {4, 24, 14, 0, 0, 0}, + {4, 25, 14, 0, 0, 0}, + {19, 0, 4, 0, 0, 0}, + {14, 0, 12, 0, 0, 0}, + {27, 0, 5, 0, 0, 0}, + {26, 0, 11, 0, 0, 0}, + {28, 0, 5, 0, 0, 0}, + {26, 0, 13, 0, 0, 0}, + {26, 0, 5, 0, 0, 0}, + {4, 30, 14, 0, 0, 0}, + {4, 31, 14, 0, 0, 0}, + {4, 32, 14, 0, 0, 0}, + {14, 0, 5, 0, 0, 0}, + {19, 0, 5, 0, 0, 0}, + {19, 0, 5, 0, 0, 10}, + {18, 0, 5, 0, 0, 0}, + {4, 27, 14, 0, 0, 0}, + {4, 28, 14, 0, 0, 0}, + {4, 29, 14, 0, 0, 0}, + {4, 33, 14, 0, 0, 0}, + {4, 34, 14, 0, 0, 0}, + {4, 230, 14, 0, 0, 80}, + {4, 220, 14, 0, 0, 80}, + {7, 0, 12, 0, 0, 0}, + {26, 0, 12, 0, 0, 0}, + {4, 35, 14, 0, 0, 0}, + {19, 0, 5, 0, 0, 136}, + {7, 0, 9, 0, 0, 0}, + {30, 0, 5, 0, 0, 0}, + {4, 36, 14, 0, 0, 0}, + {4, 0, 14, 0, 0, 0}, + {7, 0, 4, 0, 0, 0}, + {18, 0, 4, 0, 0, 0}, + {26, 0, 19, 0, 0, 0}, + {28, 0, 4, 0, 0, 0}, + {29, 0, 5, 0, 0, 0}, + {5, 0, 1, 0, 0, 0}, + {19, 0, 1, 0, 0, 10}, + {4, 7, 14, 0, 0, 80}, + {4, 9, 14, 0, 0, 0}, + {19, 0, 1, 0, 0, 170}, + {7, 0, 1, 0, 0, 0}, + {4, 7, 14, 0, 0, 0}, + {5, 0, 1, 0, 0, 80}, + {5, 0, 1, 0, 0, 10}, + {9, 0, 1, 0, 0, 0}, + {4, 0, 14, 0, 0, 80}, + {4, 0, 14, 0, 0, 10}, + {4, 84, 14, 0, 0, 0}, + {4, 91, 14, 0, 0, 80}, + {9, 0, 19, 0, 0, 0}, + {4, 0, 1, 0, 0, 0}, + {4, 9, 14, 0, 0, 80}, + {19, 0, 1, 0, 0, 136}, + {4, 103, 14, 0, 0, 0}, + {4, 107, 14, 0, 0, 0}, + {4, 118, 14, 0, 0, 0}, + {4, 122, 14, 0, 0, 0}, + {26, 0, 1, 0, 0, 136}, + {4, 216, 14, 0, 0, 0}, + {22, 0, 19, 1, 0, 0}, + {23, 0, 19, 1, 0, 0}, + {4, 129, 14, 0, 0, 0}, + {4, 130, 14, 0, 0, 0}, + {4, 0, 14, 0, 0, 170}, + {4, 132, 14, 0, 0, 0}, + {4, 0, 14, 0, 0, 136}, {19, 0, 1, 0, 2, 0}, - {19, 0, 1, 0, 5, 80}, - {10, 0, 18, 0, 5, 0}, - {8, 0, 1, 0, 5, 0}, - {5, 9, 1, 0, 5, 0}, - {14, 0, 15, 0, 5, 0}, - {4, 1, 14, 0, 5, 0}, - {4, 234, 14, 0, 5, 0}, - {4, 214, 14, 0, 5, 0}, - {4, 202, 14, 0, 5, 0}, - {4, 232, 14, 0, 5, 0}, - {4, 218, 14, 0, 5, 0}, - {4, 233, 14, 0, 5, 0}, - {2, 0, 1, 0, 5, 138}, - {2, 0, 1, 0, 5, 170}, - {3, 0, 1, 0, 5, 10}, - {1, 0, 1, 0, 5, 170}, - {29, 0, 19, 0, 5, 170}, - {10, 0, 18, 0, 5, 170}, - {10, 0, 18, 0, 5, 136}, - {14, 0, 1, 0, 5, 0}, - {14, 0, 4, 0, 5, 0}, + {19, 0, 1, 0, 0, 80}, + {10, 0, 18, 0, 0, 0}, + {8, 0, 1, 0, 0, 0}, + {5, 9, 1, 0, 0, 0}, + {14, 0, 15, 0, 0, 0}, + {4, 1, 14, 0, 0, 0}, + {4, 234, 14, 0, 0, 0}, + {4, 214, 14, 0, 0, 0}, + {4, 202, 14, 0, 0, 0}, + {4, 232, 14, 0, 0, 0}, + {4, 218, 14, 0, 0, 0}, + {4, 233, 14, 0, 0, 0}, + {2, 0, 1, 0, 0, 138}, + {2, 0, 1, 0, 0, 170}, + {3, 0, 1, 0, 0, 10}, + {1, 0, 1, 0, 0, 170}, + {29, 0, 19, 0, 0, 170}, + {10, 0, 18, 0, 0, 170}, + {10, 0, 18, 0, 0, 136}, + {14, 0, 1, 0, 0, 0}, + {14, 0, 4, 0, 0, 0}, {21, 0, 19, 0, 4, 0}, - {21, 0, 19, 0, 5, 136}, - {26, 0, 19, 0, 5, 136}, + {21, 0, 19, 0, 0, 136}, + {26, 0, 19, 0, 0, 136}, {24, 0, 19, 0, 4, 0}, {25, 0, 19, 0, 4, 0}, - {22, 0, 19, 0, 5, 0}, - {24, 0, 19, 0, 5, 0}, + {22, 0, 19, 0, 0, 0}, + {24, 0, 19, 0, 0, 0}, {26, 0, 19, 0, 4, 136}, - {11, 0, 18, 0, 5, 0}, - {12, 0, 16, 0, 5, 0}, - {14, 0, 2, 0, 5, 0}, - {14, 0, 6, 0, 5, 0}, - {14, 0, 8, 0, 5, 0}, - {14, 0, 3, 0, 5, 0}, - {14, 0, 7, 0, 5, 0}, + {11, 0, 18, 0, 0, 0}, + {12, 0, 16, 0, 0, 0}, + {14, 0, 2, 0, 0, 0}, + {14, 0, 6, 0, 0, 0}, + {14, 0, 8, 0, 0, 0}, + {14, 0, 3, 0, 0, 0}, + {14, 0, 7, 0, 0, 0}, {26, 0, 11, 0, 4, 0}, {26, 0, 11, 0, 4, 136}, - {26, 0, 11, 0, 5, 136}, - {20, 0, 19, 0, 5, 0}, - {27, 0, 13, 0, 5, 0}, - {14, 0, 20, 0, 5, 0}, - {14, 0, 21, 0, 5, 0}, - {14, 0, 22, 0, 5, 0}, - {14, 0, 23, 0, 5, 0}, - {9, 0, 9, 0, 5, 136}, - {27, 0, 10, 0, 5, 136}, - {27, 0, 19, 0, 5, 136}, - {22, 0, 19, 1, 5, 136}, - {23, 0, 19, 1, 5, 136}, + {26, 0, 11, 0, 0, 136}, + {20, 0, 19, 0, 0, 0}, + {27, 0, 13, 0, 0, 0}, + {14, 0, 20, 0, 0, 0}, + {14, 0, 21, 0, 0, 0}, + {14, 0, 22, 0, 0, 0}, + {14, 0, 23, 0, 0, 0}, + {9, 0, 9, 0, 0, 136}, + {27, 0, 10, 0, 0, 136}, + {27, 0, 19, 0, 0, 136}, + {22, 0, 19, 1, 0, 136}, + {23, 0, 19, 1, 0, 136}, {18, 0, 1, 0, 4, 136}, - {28, 0, 11, 0, 5, 136}, + {28, 0, 11, 0, 0, 136}, {28, 0, 11, 0, 1, 0}, - {30, 0, 19, 0, 5, 136}, + {30, 0, 19, 0, 0, 136}, {30, 0, 19, 0, 4, 136}, {1, 0, 1, 0, 4, 170}, - {30, 0, 11, 0, 5, 0}, - {27, 0, 19, 1, 5, 136}, - {9, 0, 19, 0, 5, 136}, + {30, 0, 11, 0, 0, 0}, + {27, 0, 19, 1, 0, 136}, + {9, 0, 19, 0, 0, 136}, {8, 0, 1, 0, 4, 136}, - {8, 0, 1, 0, 5, 136}, - {27, 0, 19, 0, 5, 10}, - {30, 0, 19, 0, 5, 10}, - {27, 0, 19, 1, 5, 0}, + {8, 0, 1, 0, 0, 136}, + {27, 0, 19, 0, 0, 10}, + {30, 0, 19, 0, 0, 10}, + {27, 0, 19, 1, 0, 0}, {27, 0, 19, 1, 4, 0}, - {27, 0, 19, 1, 5, 10}, - {27, 0, 10, 0, 5, 0}, - {27, 0, 11, 0, 5, 0}, + {27, 0, 19, 1, 0, 10}, + {27, 0, 10, 0, 0, 0}, + {27, 0, 11, 0, 0, 0}, {27, 0, 19, 1, 4, 136}, {27, 0, 19, 1, 4, 10}, {30, 0, 19, 0, 2, 0}, @@ -252,10 +252,10 @@ const _PyUnicode_DatabaseRecord _PyUnicode_Database_Records[] = { {30, 0, 1, 0, 4, 136}, {9, 0, 19, 0, 4, 0}, {27, 0, 19, 0, 2, 0}, - {27, 0, 19, 1, 5, 170}, - {30, 0, 19, 1, 5, 0}, + {27, 0, 19, 1, 0, 170}, + {30, 0, 19, 1, 0, 0}, {30, 0, 19, 0, 2, 136}, - {10, 0, 18, 0, 0, 136}, + {10, 0, 18, 0, 5, 136}, {26, 0, 19, 0, 2, 0}, {18, 0, 1, 0, 2, 0}, {8, 0, 1, 0, 2, 0}, @@ -280,15 +280,16 @@ const _PyUnicode_DatabaseRecord _PyUnicode_Database_Records[] = { {30, 0, 1, 0, 2, 136}, {9, 0, 1, 0, 4, 0}, {9, 0, 19, 0, 2, 136}, - {29, 0, 1, 0, 5, 0}, - {15, 0, 1, 0, 5, 0}, + {29, 0, 1, 0, 0, 0}, + {15, 0, 1, 0, 0, 0}, {16, 0, 1, 0, 4, 0}, {19, 0, 1, 0, 2, 170}, - {19, 0, 4, 0, 5, 170}, - {4, 26, 14, 0, 5, 0}, - {19, 0, 4, 0, 5, 136}, - {23, 0, 19, 0, 5, 0}, - {28, 0, 5, 0, 5, 136}, + {0, 0, 0, 0, 2, 0}, + {19, 0, 4, 0, 0, 170}, + {4, 26, 14, 0, 0, 0}, + {19, 0, 4, 0, 0, 136}, + {23, 0, 19, 0, 0, 0}, + {28, 0, 5, 0, 0, 136}, {26, 0, 19, 0, 2, 136}, {22, 0, 19, 0, 2, 136}, {23, 0, 19, 0, 2, 136}, @@ -303,47 +304,47 @@ const _PyUnicode_DatabaseRecord _PyUnicode_Database_Records[] = { {27, 0, 19, 1, 2, 136}, {27, 0, 19, 0, 2, 136}, {28, 0, 11, 0, 2, 136}, - {26, 0, 19, 0, 0, 136}, - {26, 0, 11, 0, 0, 136}, - {28, 0, 11, 0, 0, 136}, - {22, 0, 19, 1, 0, 136}, - {23, 0, 19, 1, 0, 136}, - {27, 0, 10, 0, 0, 136}, - {26, 0, 13, 0, 0, 136}, - {21, 0, 10, 0, 0, 136}, - {7, 0, 9, 0, 0, 136}, - {27, 0, 19, 1, 0, 136}, - {27, 0, 19, 0, 0, 136}, - {1, 0, 1, 0, 0, 136}, - {29, 0, 19, 0, 0, 136}, - {20, 0, 19, 0, 0, 136}, - {2, 0, 1, 0, 0, 136}, + {26, 0, 19, 0, 5, 136}, + {26, 0, 11, 0, 5, 136}, + {28, 0, 11, 0, 5, 136}, + {22, 0, 19, 1, 5, 136}, + {23, 0, 19, 1, 5, 136}, + {27, 0, 10, 0, 5, 136}, + {26, 0, 13, 0, 5, 136}, + {21, 0, 10, 0, 5, 136}, + {7, 0, 9, 0, 5, 136}, + {27, 0, 19, 1, 5, 136}, + {27, 0, 19, 0, 5, 136}, + {1, 0, 1, 0, 5, 136}, + {29, 0, 19, 0, 5, 136}, + {20, 0, 19, 0, 5, 136}, + {2, 0, 1, 0, 5, 136}, {26, 0, 19, 0, 1, 136}, {22, 0, 19, 1, 1, 136}, {23, 0, 19, 1, 1, 136}, {19, 0, 1, 0, 1, 136}, {18, 0, 1, 0, 1, 136}, - {30, 0, 19, 0, 0, 136}, + {30, 0, 19, 0, 5, 136}, {30, 0, 19, 0, 1, 136}, {27, 0, 19, 0, 1, 136}, - {14, 0, 19, 0, 5, 0}, - {8, 0, 19, 0, 5, 0}, - {9, 0, 9, 0, 5, 0}, - {9, 0, 4, 0, 5, 0}, - {30, 0, 4, 0, 5, 0}, - {1, 0, 4, 0, 5, 0}, - {2, 0, 4, 0, 5, 0}, - {9, 0, 12, 0, 5, 0}, - {9, 0, 5, 0, 5, 0}, - {4, 9, 1, 0, 5, 0}, + {14, 0, 19, 0, 0, 0}, + {8, 0, 19, 0, 0, 0}, + {9, 0, 9, 0, 0, 0}, + {9, 0, 4, 0, 0, 0}, + {30, 0, 4, 0, 0, 0}, + {1, 0, 4, 0, 0, 0}, + {2, 0, 4, 0, 0, 0}, + {9, 0, 12, 0, 0, 0}, + {9, 0, 5, 0, 0, 0}, + {4, 9, 1, 0, 0, 0}, {4, 0, 14, 0, 2, 0}, {5, 6, 1, 0, 2, 0}, - {30, 0, 1, 0, 5, 170}, - {5, 216, 1, 0, 5, 0}, - {5, 226, 1, 0, 5, 0}, - {27, 0, 1, 0, 5, 136}, - {7, 0, 9, 0, 5, 136}, - {30, 0, 1, 0, 5, 136}, + {30, 0, 1, 0, 0, 170}, + {5, 216, 1, 0, 0, 0}, + {5, 226, 1, 0, 0, 0}, + {27, 0, 1, 0, 0, 136}, + {7, 0, 9, 0, 0, 136}, + {30, 0, 1, 0, 0, 136}, {30, 0, 1, 0, 4, 0}, {29, 0, 19, 0, 2, 0}, }; @@ -674,12 +675,12 @@ const char *_PyUnicode_BidirectionalNames[] = { NULL }; const char *_PyUnicode_EastAsianWidthNames[] = { - "F", + "N", "H", "W", "Na", "A", - "N", + "F", NULL }; static const char *decomp_prefix[] = { @@ -743,38 +744,38 @@ static const unsigned short index1[] = { 137, 138, 139, 140, 141, 142, 143, 144, 41, 41, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 137, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 137, 169, 170, 137, 171, 172, 173, 174, - 137, 175, 176, 177, 178, 179, 180, 137, 137, 181, 182, 183, 184, 137, - 185, 137, 186, 41, 41, 41, 41, 41, 41, 41, 187, 188, 41, 189, 137, 137, + 137, 175, 176, 177, 178, 179, 180, 181, 137, 182, 183, 184, 185, 137, + 186, 187, 188, 41, 41, 41, 41, 41, 41, 41, 189, 190, 41, 191, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 190, 41, 41, 41, 41, 41, 41, 41, 41, 191, 137, 137, + 137, 137, 137, 137, 192, 41, 41, 41, 41, 41, 41, 41, 41, 193, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 41, 41, 41, 41, 192, 137, 137, 137, 137, 137, 137, 137, 137, 137, + 137, 41, 41, 41, 41, 194, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 41, 41, 41, 41, 193, 194, 195, 196, 137, 137, 137, 137, 197, - 198, 199, 200, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 137, 137, 41, 41, 41, 41, 195, 196, 197, 198, 137, 137, 137, 137, 199, + 200, 201, 202, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 201, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 202, 203, 137, 137, 137, 137, 137, 137, 137, 137, + 101, 101, 101, 101, 101, 101, 101, 101, 203, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 204, 205, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 204, 101, 101, 205, 101, 101, 206, 137, 137, 137, + 137, 137, 137, 137, 206, 101, 101, 207, 101, 101, 208, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 207, 208, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, + 137, 209, 210, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 209, 210, 78, 211, - 212, 213, 214, 215, 216, 137, 217, 218, 219, 220, 221, 222, 223, 224, 78, - 78, 78, 78, 225, 226, 137, 137, 137, 137, 137, 137, 137, 137, 227, 137, - 228, 137, 229, 137, 137, 230, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 231, 232, 233, 234, 137, 137, 137, 137, 137, 235, 236, 237, 137, - 238, 239, 137, 137, 240, 241, 242, 243, 244, 137, 245, 246, 247, 248, - 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, + 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 211, 212, 78, 213, + 214, 215, 216, 217, 218, 137, 219, 220, 221, 222, 223, 224, 225, 226, 78, + 78, 78, 78, 227, 228, 137, 137, 137, 137, 137, 137, 137, 137, 229, 137, + 230, 231, 232, 137, 137, 233, 137, 137, 137, 234, 137, 137, 137, 137, + 137, 235, 236, 237, 238, 137, 137, 137, 137, 137, 239, 240, 241, 137, + 242, 243, 137, 137, 244, 245, 246, 247, 248, 137, 249, 250, 251, 252, + 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 137, 137, 137, 137, 137, 137, 137, 137, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, @@ -799,56 +800,56 @@ static const unsigned short index1[] = { 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 263, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 267, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 264, 101, 265, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 268, 101, 269, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 266, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 270, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 267, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 121, 121, 121, 121, 268, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 271, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 121, 121, 121, 121, 273, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 274, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, - 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 269, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 275, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 276, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 274, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, @@ -1214,7 +1215,7 @@ static const unsigned short index1[] = { 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 270, 137, 271, 272, 137, 137, 137, 137, + 137, 137, 137, 137, 137, 137, 277, 137, 278, 279, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, @@ -1287,7 +1288,7 @@ static const unsigned short index1[] = { 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 273, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 280, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, @@ -1324,7 +1325,7 @@ static const unsigned short index1[] = { 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, - 120, 273, + 120, 280, }; static const unsigned short index2[] = { @@ -1519,7 +1520,7 @@ static const unsigned short index2[] = { 48, 0, 0, 147, 48, 141, 156, 149, 141, 148, 141, 141, 0, 156, 149, 149, 0, 149, 149, 135, 144, 0, 0, 0, 0, 0, 0, 0, 148, 148, 0, 0, 0, 0, 0, 0, 48, 48, 0, 48, 48, 135, 135, 0, 0, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 0, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 135, + 146, 146, 146, 0, 48, 48, 141, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 135, 135, 141, 141, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, @@ -1545,76 +1546,76 @@ static const unsigned short index2[] = { 48, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 135, 48, 158, 135, 135, 135, 135, 161, 161, 144, 135, 135, 48, 0, - 0, 48, 48, 48, 48, 48, 0, 53, 0, 162, 162, 162, 162, 135, 135, 0, 0, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 0, 0, 158, 158, 48, 48, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 48, 80, 80, 80, 83, 83, 83, 83, 83, 83, 83, 83, 163, - 83, 83, 83, 83, 83, 83, 80, 83, 80, 80, 80, 86, 86, 80, 80, 80, 80, 80, - 80, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 150, 150, 150, 150, - 150, 150, 150, 150, 150, 150, 80, 86, 80, 86, 80, 164, 165, 166, 165, - 166, 141, 141, 48, 48, 48, 145, 48, 48, 48, 48, 0, 48, 48, 48, 48, 145, - 48, 48, 48, 48, 145, 48, 48, 48, 48, 145, 48, 48, 48, 48, 145, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 145, 48, 48, 48, 0, 0, 0, 0, 167, - 168, 169, 170, 169, 169, 171, 169, 171, 168, 168, 168, 168, 135, 141, - 168, 169, 81, 81, 144, 83, 81, 81, 48, 48, 48, 48, 48, 135, 135, 135, - 135, 135, 135, 169, 135, 135, 135, 135, 0, 135, 135, 135, 135, 169, 135, - 135, 135, 135, 169, 135, 135, 135, 135, 169, 135, 135, 135, 135, 169, - 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 169, 135, - 135, 135, 0, 80, 80, 80, 80, 80, 80, 80, 80, 86, 80, 80, 80, 80, 80, 80, - 0, 80, 80, 83, 83, 83, 83, 83, 80, 80, 80, 80, 83, 83, 0, 0, 0, 0, 0, 0, + 0, 48, 48, 48, 48, 48, 0, 53, 0, 162, 162, 162, 162, 135, 135, 135, 0, + 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 0, 0, 158, 158, 48, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 48, 80, 80, 80, 83, 83, 83, 83, 83, 83, 83, 83, + 163, 83, 83, 83, 83, 83, 83, 80, 83, 80, 80, 80, 86, 86, 80, 80, 80, 80, + 80, 80, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 150, 150, 150, + 150, 150, 150, 150, 150, 150, 150, 80, 86, 80, 86, 80, 164, 165, 166, + 165, 166, 141, 141, 48, 48, 48, 145, 48, 48, 48, 48, 0, 48, 48, 48, 48, + 145, 48, 48, 48, 48, 145, 48, 48, 48, 48, 145, 48, 48, 48, 48, 145, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 145, 48, 48, 48, 0, 0, 0, 0, + 167, 168, 169, 170, 169, 169, 171, 169, 171, 168, 168, 168, 168, 135, + 141, 168, 169, 81, 81, 144, 83, 81, 81, 48, 48, 48, 48, 48, 135, 135, + 135, 135, 135, 135, 169, 135, 135, 135, 135, 0, 135, 135, 135, 135, 169, + 135, 135, 135, 135, 169, 135, 135, 135, 135, 169, 135, 135, 135, 135, + 169, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 169, + 135, 135, 135, 0, 80, 80, 80, 80, 80, 80, 80, 80, 86, 80, 80, 80, 80, 80, + 80, 0, 80, 80, 83, 83, 83, 83, 83, 80, 80, 80, 80, 83, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 142, 48, 48, 48, 48, 141, 141, 135, 151, 135, - 135, 141, 135, 135, 135, 135, 135, 147, 141, 144, 144, 141, 141, 135, - 135, 48, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 83, 83, 83, - 83, 83, 83, 48, 48, 48, 48, 48, 48, 141, 141, 135, 135, 48, 48, 48, 48, - 135, 135, 135, 48, 141, 141, 141, 48, 48, 141, 141, 141, 141, 141, 141, - 141, 48, 48, 48, 135, 135, 135, 135, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 135, 141, 141, 135, 135, 141, 141, 141, 141, 141, 141, - 86, 48, 141, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 141, 141, - 141, 135, 80, 80, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 48, 48, 48, 48, 48, 48, 48, 48, 142, 48, 48, 48, 48, 141, 141, 135, 151, + 135, 135, 141, 135, 135, 135, 135, 135, 147, 141, 144, 144, 141, 141, + 135, 135, 48, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 83, 83, + 83, 83, 83, 83, 48, 48, 48, 48, 48, 48, 141, 141, 135, 135, 48, 48, 48, + 48, 135, 135, 135, 48, 141, 141, 141, 48, 48, 141, 141, 141, 141, 141, + 141, 141, 48, 48, 48, 135, 135, 135, 135, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 135, 141, 141, 135, 135, 141, 141, 141, 141, 141, + 141, 86, 48, 141, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 141, + 141, 141, 135, 80, 80, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 0, 44, 0, 0, 0, 0, 0, 44, 0, 0, 47, 47, 47, 47, + 44, 44, 44, 44, 44, 44, 44, 44, 0, 44, 0, 0, 0, 0, 0, 44, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 83, 51, 47, 47, 47, 172, 172, 172, 172, 172, 172, 172, 172, + 47, 47, 47, 47, 47, 83, 51, 47, 47, 47, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 48, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, - 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 48, 48, 48, 48, + 172, 172, 172, 172, 172, 172, 48, 173, 173, 173, 173, 173, 173, 173, 173, + 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 173, 173, 173, 173, 173, 173, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, - 173, 173, 173, 173, 173, 173, 173, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 173, 173, 173, 173, 173, 173, 173, 173, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, - 48, 48, 48, 48, 0, 0, 48, 48, 48, 48, 48, 48, 48, 0, 48, 0, 48, 48, 48, - 48, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 0, 0, 48, 48, 48, 48, 48, + 0, 48, 48, 48, 48, 0, 0, 48, 48, 48, 48, 48, 48, 48, 0, 48, 0, 48, 48, + 48, 48, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 0, 0, 48, 48, - 48, 48, 48, 48, 48, 0, 48, 0, 48, 48, 48, 48, 0, 0, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 0, 0, 48, + 48, 48, 48, 48, 48, 48, 0, 48, 0, 48, 48, 48, 48, 0, 0, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, - 48, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, + 48, 48, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 81, 81, - 81, 83, 83, 83, 83, 83, 83, 83, 83, 83, 150, 150, 150, 150, 150, 150, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 81, + 81, 81, 83, 83, 83, 83, 83, 83, 83, 83, 83, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 44, 44, 44, 44, 44, @@ -2259,7 +2260,7 @@ static const unsigned short index2[] = { 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, - 280, 280, 280, 280, 280, 280, 0, 0, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 281, 281, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, @@ -2267,22 +2268,23 @@ static const unsigned short index2[] = { 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, - 280, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 35, 35, 35, 35, 35, 35, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 35, 35, 35, 35, 0, 0, 0, 0, 0, - 281, 282, 281, 283, 283, 283, 283, 283, 283, 283, 283, 283, 219, 281, - 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 0, 281, 281, - 281, 281, 281, 0, 281, 0, 281, 281, 0, 281, 281, 0, 281, 281, 281, 281, - 281, 281, 281, 281, 281, 283, 131, 131, 131, 131, 131, 131, 131, 131, + 280, 280, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 35, 35, 35, + 35, 35, 35, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 35, 35, 35, 35, + 0, 0, 0, 0, 0, 282, 283, 282, 284, 284, 284, 284, 284, 284, 284, 284, + 284, 219, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, + 282, 0, 282, 282, 282, 282, 282, 0, 282, 0, 282, 282, 0, 282, 282, 0, + 282, 282, 282, 282, 282, 282, 282, 282, 282, 284, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, @@ -2299,26 +2301,26 @@ static const unsigned short index2[] = { 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 284, 199, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 285, 199, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, 131, 0, 0, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 0, 0, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 285, 26, 26, 26, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 286, 286, 286, 286, 286, 286, 286, 287, 288, 286, 0, 0, 0, 0, - 0, 0, 81, 81, 81, 81, 81, 81, 81, 86, 86, 86, 86, 86, 86, 86, 81, 81, - 286, 289, 289, 290, 290, 287, 288, 287, 288, 287, 288, 287, 288, 287, - 288, 287, 288, 287, 288, 287, 288, 253, 253, 287, 288, 286, 286, 286, - 286, 290, 290, 290, 291, 286, 291, 0, 286, 291, 286, 286, 289, 292, 293, - 292, 293, 292, 293, 294, 286, 286, 295, 296, 297, 297, 298, 0, 286, 299, - 294, 286, 0, 0, 0, 0, 131, 131, 131, 118, 131, 0, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 0, 0, 0, 0, 0, 0, + 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 286, 26, 26, 26, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 287, 287, 287, 287, 287, 287, 287, 288, 289, + 287, 0, 0, 0, 0, 0, 0, 81, 81, 81, 81, 81, 81, 81, 86, 86, 86, 86, 86, + 86, 86, 81, 81, 287, 290, 290, 291, 291, 288, 289, 288, 289, 288, 289, + 288, 289, 288, 289, 288, 289, 288, 289, 288, 289, 253, 253, 288, 289, + 287, 287, 287, 287, 291, 291, 291, 292, 287, 292, 0, 287, 292, 287, 287, + 290, 293, 294, 293, 294, 293, 294, 295, 287, 287, 296, 297, 298, 298, + 299, 0, 287, 300, 295, 287, 0, 0, 0, 0, 131, 131, 131, 118, 131, 0, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, @@ -2328,464 +2330,477 @@ static const unsigned short index2[] = { 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 0, 0, 177, 0, 300, 300, 301, 302, 301, 300, 300, - 303, 304, 300, 305, 306, 307, 306, 306, 308, 308, 308, 308, 308, 308, - 308, 308, 308, 308, 306, 300, 309, 310, 309, 300, 300, 311, 311, 311, - 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, 311, - 311, 311, 311, 311, 311, 311, 311, 311, 311, 303, 300, 304, 312, 313, - 312, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, - 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 314, 303, - 310, 304, 310, 303, 304, 315, 316, 317, 315, 315, 318, 318, 318, 318, - 318, 318, 318, 318, 318, 318, 319, 318, 318, 318, 318, 318, 318, 318, - 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, - 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, - 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 319, 319, 318, 318, - 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, - 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, - 318, 0, 0, 0, 318, 318, 318, 318, 318, 318, 0, 0, 318, 318, 318, 318, - 318, 318, 0, 0, 318, 318, 318, 318, 318, 318, 0, 0, 318, 318, 318, 0, 0, - 0, 302, 302, 310, 312, 320, 302, 302, 0, 321, 322, 322, 322, 322, 321, - 321, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 323, 323, 323, 26, 30, 0, 0, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 0, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 131, 131, 131, 131, 131, 131, 131, 131, 0, 0, 177, 0, 301, 301, 302, 303, + 302, 301, 301, 304, 305, 301, 306, 307, 308, 307, 307, 309, 309, 309, + 309, 309, 309, 309, 309, 309, 309, 307, 301, 310, 311, 310, 301, 301, + 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, + 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 312, 304, 301, + 305, 313, 314, 313, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, + 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, 315, + 315, 315, 304, 311, 305, 311, 304, 305, 316, 317, 318, 316, 316, 319, + 319, 319, 319, 319, 319, 319, 319, 319, 319, 320, 319, 319, 319, 319, + 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 320, + 320, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + 319, 319, 319, 319, 0, 0, 0, 319, 319, 319, 319, 319, 319, 0, 0, 319, + 319, 319, 319, 319, 319, 0, 0, 319, 319, 319, 319, 319, 319, 0, 0, 319, + 319, 319, 0, 0, 0, 303, 303, 311, 313, 321, 303, 303, 0, 322, 323, 323, + 323, 323, 322, 322, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 324, 324, 324, 26, 30, + 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 0, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 0, 0, 0, 0, 0, 83, 138, 83, 0, 0, 0, 0, 150, 150, 150, + 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 83, 138, 83, 0, 0, 0, 0, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, - 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 0, - 0, 0, 80, 80, 80, 80, 80, 80, 80, 80, 80, 324, 324, 324, 324, 324, 324, - 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, - 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, - 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, 324, - 324, 324, 324, 324, 324, 155, 155, 155, 155, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 155, 155, 26, 80, 80, 0, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 26, 0, 0, 0, 0, 0, + 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, + 150, 150, 0, 0, 0, 80, 80, 80, 80, 80, 80, 80, 80, 80, 325, 325, 325, + 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, + 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, + 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, + 325, 325, 325, 325, 325, 325, 325, 325, 155, 155, 155, 155, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 155, 155, 26, 80, + 80, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 80, 80, 80, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 80, 80, 80, 80, 80, 80, 80, 80, 86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 325, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, - 325, 325, 325, 325, 325, 325, 325, 325, 325, 325, 0, 0, 0, 0, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 150, 150, 150, 150, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 175, 48, 48, 48, 48, 48, 48, 48, 48, 175, 0, 0, - 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, + 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 0, 0, 0, + 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 150, 150, + 150, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 175, 48, 48, 48, 48, 48, 48, + 48, 48, 175, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 81, 81, 81, 81, 81, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 81, 81, 81, 81, 81, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 0, 83, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 83, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, - 48, 48, 83, 175, 175, 175, 175, 175, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 48, + 48, 48, 48, 48, 48, 48, 48, 83, 175, 175, 175, 175, 175, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 0, 0, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 0, 0, 0, 0, 0, 0, - 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 48, 48, 48, 48, 48, 48, 0, 0, 146, 146, 146, 146, 146, 146, 146, 146, + 146, 146, 0, 0, 0, 0, 0, 0, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, - 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 44, 44, 44, 44, 44, 44, 44, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, + 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 83, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 0, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 0, 44, 44, 44, 44, - 44, 44, 44, 0, 44, 44, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, - 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, - 47, 47, 47, 47, 47, 0, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 0, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 0, 44, 44, 44, 44, 44, 44, 44, 0, 44, 44, 0, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 0, 47, 47, 47, 47, 47, 47, 47, 0, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 53, 51, 51, 51, 51, - 51, 0, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 53, 51, 51, 51, 51, 51, 0, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, - 51, 51, 51, 51, 51, 51, 51, 51, 0, 51, 51, 51, 51, 51, 51, 51, 51, 51, 0, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 0, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 107, - 107, 107, 107, 107, 0, 0, 107, 0, 107, 107, 107, 107, 107, 107, 107, 107, + 0, 0, 0, 107, 107, 107, 107, 107, 107, 0, 0, 107, 0, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 0, 107, 107, 0, 0, 0, 107, 0, 0, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, 107, 107, + 0, 0, 0, 107, 0, 0, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, 104, + 327, 327, 327, 327, 327, 327, 327, 327, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, 104, 326, 326, 326, 326, - 326, 326, 326, 326, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 327, - 327, 326, 326, 326, 326, 326, 326, 326, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 328, 328, 327, 327, 327, 327, 327, 327, 327, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, 0, 0, 0, 0, 0, - 0, 0, 326, 326, 326, 326, 326, 326, 326, 326, 326, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 0, 107, 107, 0, 0, 0, 0, 0, 326, 326, 326, 326, 326, 107, 107, 107, + 107, 0, 0, 0, 0, 0, 0, 0, 0, 327, 327, 327, 327, 327, 327, 327, 327, 327, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 326, 326, 326, 326, 326, 326, 0, 0, 0, 138, 107, + 107, 107, 107, 107, 107, 0, 107, 107, 0, 0, 0, 0, 0, 327, 327, 327, 327, + 327, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 327, 327, 327, 327, 327, + 327, 0, 0, 0, 138, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, 0, 0, 0, 0, - 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 107, 0, 0, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, 0, 0, 0, 326, 326, - 107, 107, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, - 326, 326, 326, 326, 0, 0, 326, 326, 326, 326, 326, 326, 326, 326, 326, - 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, - 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, - 326, 326, 326, 326, 326, 326, 326, 326, 326, 107, 135, 135, 135, 0, 135, - 135, 0, 0, 0, 0, 0, 135, 86, 135, 81, 107, 107, 107, 107, 0, 107, 107, - 107, 0, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 0, 0, 81, 178, 86, 0, 0, 0, 0, 144, 326, 326, 326, 326, 326, - 326, 326, 326, 326, 0, 0, 0, 0, 0, 0, 0, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, + 0, 0, 0, 327, 327, 107, 107, 327, 327, 327, 327, 327, 327, 327, 327, 327, + 327, 327, 327, 327, 327, 327, 327, 0, 0, 327, 327, 327, 327, 327, 327, + 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, + 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, + 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, 107, 135, + 135, 135, 0, 135, 135, 0, 0, 0, 0, 0, 135, 86, 135, 81, 107, 107, 107, + 107, 0, 107, 107, 107, 0, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 326, 326, 104, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 0, 0, 81, 178, 86, 0, 0, 0, 0, 144, 327, + 327, 327, 327, 327, 327, 327, 327, 327, 0, 0, 0, 0, 0, 0, 0, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 326, 326, - 326, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, 107, 107, 107, 107, 327, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 327, 327, + 104, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 81, - 86, 0, 0, 0, 0, 326, 326, 326, 326, 326, 104, 104, 104, 104, 104, 104, - 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 327, 327, 327, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, 107, + 107, 107, 107, 328, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 81, 86, 0, 0, 0, 0, 327, 327, 327, 327, 327, 104, + 104, 104, 104, 104, 104, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 0, 0, 0, 138, 138, 138, 138, 138, 138, 138, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 0, 0, 326, 326, 326, 326, 326, 326, 326, - 326, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 0, 0, 0, 0, 0, 326, 326, 326, 326, 326, - 326, 326, 326, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 0, 0, 0, 0, 0, 0, 0, 104, 104, 104, - 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 326, 326, 326, 326, 326, 326, - 326, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, 0, 0, 138, 138, 138, 138, + 138, 138, 138, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, 0, 327, 327, + 327, 327, 327, 327, 327, 327, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, 0, 0, 0, 0, + 327, 327, 327, 327, 327, 327, 327, 327, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, 0, 0, 0, + 0, 0, 0, 104, 104, 104, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 327, + 327, 327, 327, 327, 327, 327, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 328, 328, - 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, - 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, - 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, - 328, 328, 328, 328, 328, 328, 328, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, - 329, 329, 329, 329, 329, 329, 329, 329, 329, 0, 0, 0, 0, 0, 0, 0, 326, - 326, 326, 326, 326, 326, 118, 118, 118, 118, 118, 118, 118, 118, 118, + 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, + 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, + 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, + 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 0, 0, 0, + 0, 0, 0, 0, 327, 327, 327, 327, 327, 327, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, - 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 81, 81, - 81, 81, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, + 118, 118, 81, 81, 81, 81, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, - 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, - 330, 330, 330, 0, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 0, 0, 0, 0, 0, 0, 0, 0, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, + 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, + 331, 331, 331, 331, 331, 331, 331, 0, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 0, 81, 81, 102, 0, 0, 107, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 107, 107, 107, 107, 107, 107, 107, 0, 81, 81, 102, 0, 0, 107, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 326, - 326, 326, 326, 326, 326, 326, 326, 326, 326, 107, 0, 0, 0, 0, 0, 0, 0, 0, - 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, - 118, 118, 118, 118, 118, 118, 118, 118, 86, 86, 81, 81, 81, 86, 81, 86, - 86, 86, 86, 331, 331, 331, 331, 113, 113, 113, 113, 113, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 81, - 86, 81, 86, 104, 104, 104, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 86, 86, 86, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 326, 326, 326, 326, 326, 326, 326, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 141, 135, 141, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 135, - 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 144, 83, - 83, 83, 83, 83, 83, 83, 0, 0, 0, 0, 155, 155, 155, 155, 155, 155, 155, - 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 144, 48, 48, 135, 135, 48, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 144, 135, 135, 141, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 142, - 48, 142, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 142, 48, - 48, 48, 48, 141, 141, 141, 135, 135, 135, 135, 141, 141, 144, 143, 83, - 83, 192, 83, 83, 83, 83, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 0, 0, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 0, 0, 0, 0, 0, 0, 81, 81, 81, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 151, 135, 135, - 135, 135, 141, 135, 152, 152, 135, 135, 135, 144, 144, 0, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 83, 83, 83, 83, 48, 141, 141, 48, 0, - 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 107, 107, 107, 107, 327, 327, 327, 327, 327, 327, 327, 327, 327, 327, + 107, 0, 0, 0, 0, 0, 0, 0, 0, 118, 118, 118, 118, 118, 118, 118, 118, 118, + 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 86, 86, + 81, 81, 81, 86, 81, 86, 86, 86, 86, 332, 332, 332, 332, 113, 113, 113, + 113, 113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 81, 86, 81, 86, 104, 104, 104, 104, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 327, 327, 327, + 327, 327, 327, 327, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 141, 135, 141, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 144, 83, 83, 83, 83, 83, 83, 83, 0, 0, 0, 0, 155, 155, 155, + 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, + 155, 155, 155, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 144, 48, + 48, 135, 135, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 144, 135, 135, 141, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 142, 48, 142, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 142, 48, 48, 48, 48, 141, 141, 141, 135, 135, 135, 135, 141, 141, + 144, 143, 83, 83, 192, 83, 83, 83, 83, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 192, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 146, 146, + 146, 146, 146, 146, 146, 146, 146, 146, 0, 0, 0, 0, 0, 0, 81, 81, 81, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 151, + 135, 135, 135, 135, 141, 135, 152, 152, 135, 135, 135, 144, 144, 0, 146, + 146, 146, 146, 146, 146, 146, 146, 146, 146, 83, 83, 83, 83, 48, 141, + 141, 48, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 147, 83, 83, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 135, 135, 141, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 147, 83, 83, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 135, 135, - 141, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 141, 141, 141, 135, - 135, 135, 135, 135, 135, 135, 135, 135, 141, 176, 48, 48, 48, 48, 83, 83, - 83, 83, 135, 147, 135, 135, 83, 141, 135, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 48, 83, 48, 83, 83, 83, 0, 150, 150, 150, 150, 150, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 141, 141, + 141, 135, 135, 135, 135, 135, 135, 135, 135, 135, 141, 176, 48, 48, 48, + 48, 83, 83, 83, 83, 135, 147, 135, 135, 83, 141, 135, 146, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 48, 83, 48, 83, 83, 83, 0, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, - 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 141, - 141, 141, 135, 135, 135, 141, 141, 135, 176, 147, 135, 83, 83, 83, 83, - 83, 83, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, - 48, 48, 48, 48, 48, 0, 48, 0, 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 83, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 150, 150, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 141, 141, 141, 135, 135, 135, 141, 141, 135, 176, 147, 135, 83, + 83, 83, 83, 83, 83, 135, 48, 48, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 48, 48, 48, 48, 48, 48, 48, 0, 48, 0, 48, 48, 48, 48, 0, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 83, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 135, 141, 141, 141, 135, 135, 135, 135, 135, 135, 147, 144, 0, 0, 0, 0, - 0, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 0, 0, 0, 0, 0, 0, - 135, 135, 141, 141, 0, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 48, 48, 0, - 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 0, 48, 48, - 48, 48, 48, 0, 147, 147, 48, 148, 141, 135, 141, 141, 141, 141, 0, 0, - 141, 141, 0, 0, 149, 149, 176, 0, 0, 48, 0, 0, 0, 0, 0, 0, 148, 0, 0, 0, - 0, 0, 48, 48, 48, 48, 48, 141, 141, 0, 0, 81, 81, 81, 81, 81, 81, 81, 0, - 0, 0, 81, 81, 81, 81, 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 135, 141, 141, 141, 135, 135, 135, 135, 135, 135, 147, + 144, 0, 0, 0, 0, 0, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 0, + 0, 0, 0, 0, 0, 135, 135, 141, 141, 0, 48, 48, 48, 48, 48, 48, 48, 48, 0, + 0, 48, 48, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, + 0, 48, 48, 48, 48, 48, 0, 147, 147, 48, 148, 141, 135, 141, 141, 141, + 141, 0, 0, 141, 141, 0, 0, 149, 149, 176, 0, 0, 48, 0, 0, 0, 0, 0, 0, + 148, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 141, 141, 0, 0, 81, 81, 81, 81, + 81, 81, 81, 0, 0, 0, 81, 81, 81, 81, 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 141, 141, 141, - 135, 135, 135, 135, 135, 135, 135, 135, 141, 141, 144, 135, 135, 141, - 147, 48, 48, 48, 48, 83, 83, 83, 83, 83, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 146, 83, 83, 0, 83, 81, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 141, + 141, 141, 135, 135, 135, 135, 135, 135, 135, 135, 141, 141, 144, 135, + 135, 141, 147, 48, 48, 48, 48, 83, 83, 83, 83, 83, 146, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 83, 83, 0, 83, 81, 48, 48, 48, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 148, 141, 141, 135, 135, 135, - 135, 135, 135, 141, 151, 149, 149, 148, 149, 135, 135, 141, 144, 147, 48, - 48, 83, 48, 0, 0, 0, 0, 0, 0, 0, 0, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 146, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 148, 141, 141, 135, + 135, 135, 135, 135, 135, 141, 151, 149, 149, 148, 149, 135, 135, 141, + 144, 147, 48, 48, 83, 48, 0, 0, 0, 0, 0, 0, 0, 0, 146, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 148, 141, 141, 135, 135, 135, 135, 0, 0, 141, - 141, 149, 149, 135, 135, 141, 144, 147, 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 48, 48, 48, - 48, 135, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 148, 141, 141, 135, 135, 135, + 135, 0, 0, 141, 141, 149, 149, 135, 135, 141, 144, 147, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, + 83, 48, 48, 48, 48, 135, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 141, 141, 141, 135, 135, 135, 135, 135, 135, 135, 135, - 141, 141, 135, 141, 144, 135, 83, 83, 83, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 0, 0, 0, 0, 0, 0, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 141, 141, 141, 135, 135, 135, 135, + 135, 135, 135, 135, 141, 141, 135, 141, 144, 135, 83, 83, 83, 48, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 146, 146, 146, 146, 146, 146, 146, 146, 146, + 146, 0, 0, 0, 0, 0, 0, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 135, 141, 135, 141, 141, 135, 135, 135, 135, 135, 135, 176, 147, 48, - 83, 0, 0, 0, 0, 0, 0, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, + 48, 48, 48, 48, 48, 48, 48, 135, 141, 135, 141, 141, 135, 135, 135, 135, + 135, 135, 176, 147, 48, 83, 0, 0, 0, 0, 0, 0, 146, 146, 146, 146, 146, + 146, 146, 146, 146, 146, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 0, 0, 135, 135, 135, 141, 141, 135, 135, 135, 135, 141, 135, 135, + 135, 135, 144, 0, 0, 0, 0, 146, 146, 146, 146, 146, 146, 146, 146, 146, + 146, 150, 150, 83, 83, 83, 80, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 135, 135, 135, - 141, 141, 135, 135, 135, 135, 141, 135, 135, 135, 135, 144, 0, 0, 0, 0, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 150, 150, 83, 83, 83, - 80, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, + 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 141, 141, 141, 135, 135, 135, 135, 135, 135, 135, 135, - 135, 141, 144, 147, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 141, 141, 141, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 141, 144, 147, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, + 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 150, 150, 150, 150, - 150, 150, 150, 150, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, - 48, 48, 48, 48, 48, 0, 0, 48, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 0, - 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 148, 141, 141, 141, 141, 141, 0, 141, - 149, 0, 0, 135, 135, 176, 144, 48, 141, 48, 141, 147, 83, 83, 83, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 0, + 47, 47, 47, 47, 47, 47, 47, 146, 146, 146, 146, 146, 146, 146, 146, 146, + 146, 150, 150, 150, 150, 150, 150, 150, 150, 150, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 48, 0, 0, 48, 48, 48, + 48, 48, 48, 48, 48, 0, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 148, 141, 141, + 141, 141, 141, 0, 141, 149, 0, 0, 135, 135, 176, 144, 48, 141, 48, 141, + 147, 83, 83, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 146, 146, 146, 146, 146, 146, + 146, 146, 146, 146, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, - 48, 48, 48, 48, 48, 48, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 141, 141, 141, 135, 135, 135, - 135, 0, 0, 135, 135, 141, 141, 141, 141, 144, 48, 83, 48, 141, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 48, 135, 135, 135, 135, 135, 135, 156, 156, 135, 135, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 141, 141, + 141, 135, 135, 135, 135, 0, 0, 135, 135, 141, 141, 141, 141, 144, 48, 83, + 48, 141, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 48, 135, 135, 135, 135, 135, 135, 156, 156, 135, 135, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 135, - 144, 135, 135, 135, 135, 141, 48, 135, 135, 135, 135, 83, 83, 83, 83, 83, - 83, 83, 83, 144, 0, 0, 0, 0, 0, 0, 0, 0, 48, 135, 135, 135, 135, 135, - 135, 141, 141, 135, 135, 135, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 135, - 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 141, 135, - 144, 83, 83, 83, 48, 83, 83, 83, 83, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 135, 144, 135, 135, 135, 135, 141, 48, 135, 135, 135, + 135, 83, 83, 83, 83, 83, 83, 83, 83, 144, 0, 0, 0, 0, 0, 0, 0, 0, 48, + 135, 135, 135, 135, 135, 135, 141, 141, 135, 135, 135, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 141, 135, 144, 83, 83, 83, 48, 83, 83, 83, 83, 83, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 141, 135, 135, 135, 135, 135, 135, 135, 0, 135, 135, 135, 135, 135, 135, - 141, 332, 48, 83, 83, 83, 83, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 150, 150, 150, 150, 150, 150, - 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 0, 0, 0, - 83, 83, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 135, 135, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 83, 83, 83, 83, + 83, 83, 83, 83, 83, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 141, 135, + 135, 135, 135, 135, 135, 135, 0, 135, 135, 135, 135, 135, 135, 141, 333, + 48, 83, 83, 83, 83, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 146, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 150, 150, 150, 150, 150, 150, 150, 150, + 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 0, 0, 0, 83, 83, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, - 135, 135, 135, 135, 135, 135, 0, 141, 135, 135, 135, 135, 135, 135, 135, - 141, 135, 135, 141, 135, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 135, 135, 135, 135, 0, 141, 135, 135, 135, 135, 135, 135, 135, 141, 135, + 135, 141, 135, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, - 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 0, 48, 48, 0, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 135, 135, 135, 135, 135, 135, 0, 0, 0, 135, 0, 135, 135, 0, - 135, 135, 135, 147, 135, 144, 144, 48, 135, 0, 0, 0, 0, 0, 0, 0, 0, 146, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 0, 0, 0, 0, 0, 0, 48, 48, - 48, 48, 48, 48, 0, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 135, 135, 135, 135, 135, 135, 0, 0, 0, 135, 0, 135, 135, 0, 135, 135, + 135, 147, 135, 144, 144, 48, 135, 0, 0, 0, 0, 0, 0, 0, 0, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 146, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, + 48, 0, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 141, 141, 141, 141, 141, 0, 135, 135, 0, 141, 141, 135, 141, - 144, 48, 0, 0, 0, 0, 0, 0, 0, 146, 146, 146, 146, 146, 146, 146, 146, - 146, 146, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 141, 141, 141, 141, 141, 0, 135, 135, 0, 141, 141, 135, 141, 144, 48, 0, + 0, 0, 0, 0, 0, 0, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 135, 135, 141, - 141, 83, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, - 150, 150, 150, 150, 150, 150, 150, 150, 26, 26, 26, 26, 26, 26, 26, 26, - 85, 85, 85, 85, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 48, 48, 48, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 135, 135, 141, 141, 83, 83, 0, 0, + 0, 0, 0, 0, 0, 135, 135, 48, 141, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 48, 48, 141, 141, 135, 135, 135, 135, 135, 0, 0, 0, 141, 141, 135, 176, + 144, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 146, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 175, 175, 175, 175, 175, 175, 175, 175, - 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, + 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 150, 150, 150, 150, + 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, + 150, 150, 150, 26, 26, 26, 26, 26, 26, 26, 26, 85, 85, 85, 85, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, - 175, 175, 175, 175, 175, 0, 83, 83, 83, 83, 83, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, 0, + 83, 83, 83, 83, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 83, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 48, 83, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 192, 192, 192, 192, 192, 192, 192, 192, 192, + 192, 192, 192, 192, 192, 192, 192, 135, 48, 48, 48, 48, 48, 48, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 0, 0, 0, 0, 83, 83, 48, 48, 48, 48, + 48, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 0, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 0, 0, 0, 0, 83, + 83, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 0, 146, 146, 146, 146, 146, 146, 146, + 146, 146, 146, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 0, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 0, 0, 0, - 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 178, 178, - 178, 178, 178, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, + 48, 48, 0, 0, 178, 178, 178, 178, 178, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 81, 81, 81, 81, 81, 81, 81, 83, 83, 83, 83, 83, - 80, 80, 80, 80, 53, 53, 53, 53, 83, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 0, 150, 150, 150, 150, - 150, 150, 150, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 81, 81, 81, 81, 81, 81, + 81, 83, 83, 83, 83, 83, 80, 80, 80, 80, 53, 53, 53, 53, 83, 80, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 0, + 150, 150, 150, 150, 150, 150, 150, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -2793,30 +2808,30 @@ static const unsigned short index2[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 150, 150, 150, 150, 150, 150, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, - 150, 150, 150, 83, 83, 83, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 150, 150, 150, 150, 150, 150, 83, 83, 83, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 135, - 48, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 0, 0, 0, 0, 135, 48, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, + 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, - 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 0, 0, 0, - 0, 0, 0, 0, 135, 135, 135, 135, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, - 53, 53, 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 141, 141, 141, 0, 0, 0, 0, 0, 0, 0, 135, 135, 135, 135, 53, 53, 53, 53, + 53, 53, 53, 53, 53, 53, 53, 53, 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 254, - 253, 254, 333, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 334, 334, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 254, 254, 253, 254, 334, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 335, 335, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, @@ -2824,17 +2839,17 @@ static const unsigned short index2[] = { 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 0, 0, 0, - 0, 0, 0, 0, 0, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 0, 0, 0, 0, 0, 0, 0, 0, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 172, 172, 172, 172, 172, 172, 172, 172, 172, 0, 0, 0, 0, 0, 0, 0, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -2843,14 +2858,14 @@ static const unsigned short index2[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 254, 254, 254, 254, 0, 254, 254, 254, 254, 254, - 254, 254, 0, 254, 254, 0, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 254, 254, 254, 254, 0, + 254, 254, 254, 254, 254, 254, 254, 0, 254, 254, 0, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 0, 0, 0, 0, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 172, 172, 172, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 172, 172, 172, 172, 0, 0, 0, - 0, 0, 0, 0, 0, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 0, 0, 172, 172, 172, 0, 0, 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 172, 172, 172, 172, 0, 0, 0, 0, 0, 0, 0, 0, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, @@ -2860,73 +2875,74 @@ static const unsigned short index2[] = { 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 172, 172, 172, 172, 172, 172, 172, 172, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, - 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 80, 135, 178, - 83, 177, 177, 177, 177, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 0, 0, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 0, 0, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 0, 0, 80, 135, 178, 83, 177, 177, 177, 177, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, - 135, 135, 135, 135, 135, 135, 0, 0, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 0, 0, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, - 135, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 135, 135, 135, 135, 135, 135, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 0, 0, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 0, 0, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 336, 336, + 336, 336, 336, 336, 336, 337, 337, 178, 178, 178, 80, 80, 80, 338, 337, + 337, 337, 337, 337, 177, 177, 177, 177, 177, 177, 177, 177, 86, 86, 86, + 86, 86, 86, 86, 86, 80, 80, 81, 81, 81, 81, 81, 86, 86, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 335, 335, 335, 335, 335, 335, 335, - 336, 336, 178, 178, 178, 80, 80, 80, 337, 336, 336, 336, 336, 336, 177, - 177, 177, 177, 177, 177, 177, 177, 86, 86, 86, 86, 86, 86, 86, 86, 80, - 80, 81, 81, 81, 81, 81, 86, 86, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 81, 81, 81, 81, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 336, 336, 336, 336, 336, 336, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 81, 81, 81, 81, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 335, 335, 335, 335, 335, 335, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 26, 26, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 81, 81, 81, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 81, 81, 81, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 150, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 150, + 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, + 150, 150, 150, 150, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, - 150, 150, 150, 150, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, + 150, 150, 150, 150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 0, 0, 0, 0, 0, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 35, 35, 35, 35, 35, 35, 35, 35, 35, @@ -2966,26 +2982,26 @@ static const unsigned short index2[] = { 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 0, 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 338, 35, 35, 35, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 339, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 230, 35, 35, 35, 35, 35, 35, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 338, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 339, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 230, 35, 35, 35, 35, 35, 35, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 338, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 49, 49, 49, 49, 339, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 230, 35, 35, 35, 35, 35, 35, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 338, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 49, 49, 49, 49, 49, 49, 49, 49, 339, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 230, 35, 35, 35, 35, 35, 35, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 338, 35, 35, 35, 35, 35, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 339, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 35, 230, 35, 35, 35, 35, 35, 35, 49, 35, 0, 0, 339, 339, 339, 339, - 339, 339, 339, 339, 339, 339, 339, 339, 339, 339, 339, 339, 339, 339, - 339, 339, 339, 339, 339, 339, 339, 339, 339, 339, 339, 339, 339, 339, - 339, 339, 339, 339, 339, 339, 339, 339, 339, 339, 339, 339, 339, 339, - 339, 339, 339, 339, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 35, 35, 230, 35, 35, 35, 35, 35, 35, 49, 35, 0, 0, 340, 340, 340, 340, + 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, + 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, + 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, 340, + 340, 340, 340, 340, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, @@ -3001,36 +3017,48 @@ static const unsigned short index2[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 48, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, + 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 47, + 47, 47, 47, 47, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 81, 81, 81, + 81, 81, 81, 0, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 0, 0, 81, 81, 81, 81, 81, 81, 81, 0, 81, 81, 0, 81, 81, 81, + 81, 81, 0, 0, 0, 0, 0, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 81, 81, 81, 81, - 81, 81, 0, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, - 81, 81, 0, 0, 81, 81, 81, 81, 81, 81, 81, 0, 81, 81, 0, 81, 81, 81, 81, - 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 0, 0, 0, 81, 81, 81, 81, 81, 81, 81, 53, 53, 53, 53, 53, 53, 53, 0, - 0, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 0, 0, 0, 0, 48, 80, + 48, 48, 48, 48, 48, 48, 0, 0, 0, 81, 81, 81, 81, 81, 81, 81, 53, 53, 53, + 53, 53, 53, 53, 0, 0, 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, + 0, 0, 0, 0, 48, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 81, 81, 81, 81, 146, 146, 146, 146, - 146, 146, 146, 146, 146, 146, 0, 0, 0, 0, 0, 85, 0, 0, 0, 0, 0, 0, 0, 0, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 81, 81, 81, 81, 146, + 146, 146, 146, 146, 146, 146, 146, 146, 146, 0, 0, 0, 0, 0, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, - 48, 0, 48, 48, 48, 48, 0, 48, 48, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 0, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 0, 0, 0, 0, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 53, 182, 182, 86, 81, + 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 48, + 48, 48, 48, 48, 48, 0, 48, 48, 48, 48, 0, 48, 48, 0, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 0, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, @@ -3044,111 +3072,111 @@ static const unsigned short index2[] = { 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 0, 0, 326, 326, 326, 326, 326, 326, 326, - 326, 326, 86, 86, 86, 86, 86, 86, 86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 0, 0, 327, 327, 327, 327, + 327, 327, 327, 327, 327, 86, 86, 86, 86, 86, 86, 86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, - 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, 328, - 328, 328, 328, 328, 328, 328, 328, 328, 328, 329, 329, 329, 329, 329, - 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, - 329, 81, 81, 81, 81, 81, 81, 147, 137, 0, 0, 0, 0, 136, 136, 136, 136, - 136, 136, 136, 136, 136, 136, 0, 0, 0, 0, 104, 104, 0, 0, 0, 0, 0, 0, 0, + 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 329, 330, 330, + 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, + 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, 330, + 330, 330, 330, 330, 81, 81, 81, 81, 81, 81, 147, 137, 0, 0, 0, 0, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 0, 0, 0, 0, 104, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 331, 331, 331, 331, - 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, - 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, - 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, - 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 133, - 331, 331, 331, 111, 331, 331, 331, 331, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 332, + 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, + 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, + 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, + 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, + 332, 332, 133, 332, 332, 332, 111, 332, 332, 332, 332, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 331, 331, 331, 331, - 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, - 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, - 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 133, - 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, 331, - 331, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, 131, 131, - 131, 0, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 0, - 131, 131, 0, 131, 0, 0, 131, 0, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 0, 131, 131, 131, 131, 0, 131, 0, 131, 0, 0, 0, 0, 0, 0, 131, - 0, 0, 0, 0, 131, 0, 131, 0, 131, 0, 131, 131, 131, 0, 131, 131, 0, 131, - 0, 0, 131, 0, 131, 0, 131, 0, 131, 0, 131, 0, 131, 131, 0, 131, 0, 0, - 131, 131, 131, 131, 0, 131, 131, 131, 131, 131, 131, 131, 0, 131, 131, - 131, 131, 0, 131, 131, 131, 131, 0, 131, 0, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 0, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 0, 0, 0, 0, 0, 131, 131, 131, 0, 131, - 131, 131, 131, 131, 0, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 332, + 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, + 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, + 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, + 332, 332, 133, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, + 332, 332, 332, 332, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 78, 78, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 243, 26, 26, 26, 26, 26, 26, 26, 26, + 131, 131, 131, 131, 0, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 0, 131, 131, 0, 131, 0, 0, 131, 0, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 0, 131, 131, 131, 131, 0, 131, 0, 131, 0, + 0, 0, 0, 0, 0, 131, 0, 0, 0, 0, 131, 0, 131, 0, 131, 0, 131, 131, 131, 0, + 131, 131, 0, 131, 0, 0, 131, 0, 131, 0, 131, 0, 131, 0, 131, 0, 131, 131, + 0, 131, 0, 0, 131, 131, 131, 131, 0, 131, 131, 131, 131, 131, 131, 131, + 0, 131, 131, 131, 131, 0, 131, 131, 131, 131, 0, 131, 0, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 0, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 0, 0, 0, 0, 0, 131, + 131, 131, 0, 131, 131, 131, 131, 131, 0, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 78, 78, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 243, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 243, 0, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 243, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 155, 155, 26, 26, 26, - 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 155, + 155, 26, 26, 26, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, - 246, 246, 340, 26, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, + 246, 246, 246, 246, 246, 341, 26, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, - 246, 246, 246, 246, 246, 246, 246, 341, 341, 341, 341, 341, 341, 341, - 341, 341, 341, 341, 341, 341, 341, 341, 341, 341, 341, 341, 341, 341, - 341, 341, 341, 341, 341, 226, 226, 226, 26, 26, 26, 341, 341, 341, 341, - 341, 341, 341, 341, 341, 341, 341, 341, 341, 341, 341, 341, 341, 341, - 341, 341, 341, 341, 341, 341, 341, 341, 341, 341, 341, 341, 272, 341, - 246, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 341, 341, 341, - 341, 341, 341, 341, 341, 341, 341, 341, 341, 341, 341, 341, 341, 341, - 341, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 274, 274, - 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 274, 274, 274, 274, 274, 274, + 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 342, 342, 342, 342, + 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, + 342, 342, 342, 342, 342, 342, 342, 342, 226, 226, 226, 26, 26, 26, 342, + 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, + 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, + 342, 272, 342, 246, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, 342, + 342, 342, 342, 342, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 274, 274, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, - 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 0, 0, 0, 0, 274, 274, - 274, 274, 274, 274, 274, 274, 274, 0, 0, 0, 0, 0, 0, 0, 274, 274, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 243, 243, 243, 243, 243, 243, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, + 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 274, 0, + 0, 0, 0, 274, 274, 274, 274, 274, 274, 274, 274, 274, 0, 0, 0, 0, 0, 0, + 0, 274, 274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 243, 243, 243, + 243, 243, 243, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 26, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, 243, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 243, 243, 243, 243, 243, 243, 243, 243, 243, 26, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 26, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 26, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 26, 26, - 26, 26, 243, 243, 243, 243, 243, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 26, 26, 26, 243, 26, 26, 26, 243, 243, 243, 342, 342, - 342, 342, 342, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 26, 26, 26, 26, 243, 243, 243, 243, 243, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, 243, 26, 26, 26, 243, 26, 26, 26, + 243, 243, 243, 343, 343, 343, 343, 343, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 26, 243, 26, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, + 243, 26, 243, 26, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, @@ -3161,71 +3189,72 @@ static const unsigned short index2[] = { 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 26, 26, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, 26, 26, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 243, 243, 243, 243, 26, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 243, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 243, 26, 26, 26, 26, 26, 26, 26, + 243, 243, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 243, 243, + 243, 243, 26, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 243, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 243, 243, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 243, + 26, 26, 26, 26, 26, 26, 243, 243, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 243, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, + 243, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 243, 243, 243, 243, 243, 243, 243, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 26, 26, 26, 26, 26, 26, 243, 26, 26, - 26, 243, 243, 243, 26, 26, 243, 243, 243, 0, 0, 0, 0, 0, 243, 243, 243, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 243, 243, 0, 0, 0, 26, 26, - 26, 26, 243, 243, 243, 243, 243, 243, 243, 243, 243, 0, 0, 0, 26, 26, 26, + 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 26, 26, 26, 26, 26, 26, + 243, 26, 26, 26, 243, 243, 243, 26, 26, 243, 243, 243, 0, 0, 0, 0, 243, + 243, 243, 243, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 243, 243, 0, + 0, 0, 26, 26, 26, 26, 243, 243, 243, 243, 243, 243, 243, 243, 243, 0, 0, + 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 0, 0, 0, 0, - 243, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 0, 0, 0, 0, 0, 0, 243, 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 0, 0, 0, 0, 243, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, - 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 26, - 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, + 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 0, 0, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 243, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 26, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 26, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 26, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 26, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, @@ -3237,22 +3266,22 @@ static const unsigned short index2[] = { 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 243, 243, 243, 243, 243, 243, 243, 243, 243, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 0, 0, 243, 243, 243, 243, 243, 0, 0, 0, 243, 243, 243, 243, - 243, 0, 0, 0, 243, 243, 243, 243, 243, 243, 243, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, 0, 0, 0, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 0, 0, 0, 0, 0, 0, 0, 243, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 0, 0, 0, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 0, - 0, 0, 0, 0, 243, 243, 243, 243, 243, 243, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 0, 0, 0, 0, 0, 0, 243, - 243, 243, 243, 243, 243, 243, 243, 0, 0, 0, 0, 0, 0, 0, 0, 243, 243, 243, - 243, 243, 243, 243, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, + 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 0, 243, 243, + 243, 243, 243, 243, 243, 0, 0, 0, 0, 0, 0, 0, 0, 243, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, 243, 0, 0, 0, 0, 243, 243, 243, + 243, 243, 243, 243, 243, 243, 0, 0, 0, 0, 0, 0, 0, 243, 243, 243, 243, + 243, 243, 243, 243, 243, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, @@ -3260,32 +3289,34 @@ static const unsigned short index2[] = { 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 339, 339, 339, 339, 339, 339, 339, 339, - 339, 339, 0, 0, 0, 0, 0, 0, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 340, 340, 340, 340, 340, 340, 340, 340, + 340, 340, 0, 0, 0, 0, 0, 0, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 172, 172, 172, 0, 0, 0, 0, 0, 0, 0, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 281, 281, 281, 281, 281, + 281, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 281, 281, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 172, 172, 172, 0, 0, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, @@ -3294,9 +3325,8 @@ static const unsigned short index2[] = { 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, @@ -3308,30 +3338,63 @@ static const unsigned short index2[] = { 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, - 280, 280, 280, 280, 280, 280, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 172, 172, 172, 172, 172, 172, 172, + 280, 280, 280, 280, 280, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 0, 0, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 177, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 177, 177, 177, 177, 177, 177, 177, 177, 177, - 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 281, 281, 281, + 281, 281, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 0, 177, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, - 177, 177, 177, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 177, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, @@ -3344,8 +3407,8 @@ static const unsigned short index2[] = { 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, - 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, + 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, @@ -3354,7 +3417,7 @@ static const unsigned short index2[] = { 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, - 279, 279, 279, 0, 0, + 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 0, 0, }; /* decomposition data */ @@ -3420,121 +3483,120 @@ static const unsigned int decomp_data[] = { 259, 121, 514, 32, 774, 514, 32, 775, 514, 32, 778, 514, 32, 808, 514, 32, 771, 514, 32, 779, 259, 611, 259, 108, 259, 115, 259, 120, 259, 661, 256, 768, 256, 769, 256, 787, 512, 776, 769, 256, 697, 514, 32, 837, 256, - 59, 514, 32, 769, 512, 168, 769, 512, 913, 769, 256, 183, 512, 917, 769, - 512, 919, 769, 512, 921, 769, 512, 927, 769, 512, 933, 769, 512, 937, - 769, 512, 970, 769, 512, 921, 776, 512, 933, 776, 512, 945, 769, 512, - 949, 769, 512, 951, 769, 512, 953, 769, 512, 971, 769, 512, 953, 776, - 512, 965, 776, 512, 959, 769, 512, 965, 769, 512, 969, 769, 258, 946, - 258, 952, 258, 933, 512, 978, 769, 512, 978, 776, 258, 966, 258, 960, - 258, 954, 258, 961, 258, 962, 258, 920, 258, 949, 258, 931, 512, 1045, - 768, 512, 1045, 776, 512, 1043, 769, 512, 1030, 776, 512, 1050, 769, 512, - 1048, 768, 512, 1059, 774, 512, 1048, 774, 512, 1080, 774, 512, 1077, - 768, 512, 1077, 776, 512, 1075, 769, 512, 1110, 776, 512, 1082, 769, 512, - 1080, 768, 512, 1091, 774, 512, 1140, 783, 512, 1141, 783, 512, 1046, - 774, 512, 1078, 774, 512, 1040, 774, 512, 1072, 774, 512, 1040, 776, 512, - 1072, 776, 512, 1045, 774, 512, 1077, 774, 512, 1240, 776, 512, 1241, - 776, 512, 1046, 776, 512, 1078, 776, 512, 1047, 776, 512, 1079, 776, 512, - 1048, 772, 512, 1080, 772, 512, 1048, 776, 512, 1080, 776, 512, 1054, - 776, 512, 1086, 776, 512, 1256, 776, 512, 1257, 776, 512, 1069, 776, 512, - 1101, 776, 512, 1059, 772, 512, 1091, 772, 512, 1059, 776, 512, 1091, - 776, 512, 1059, 779, 512, 1091, 779, 512, 1063, 776, 512, 1095, 776, 512, - 1067, 776, 512, 1099, 776, 514, 1381, 1410, 512, 1575, 1619, 512, 1575, - 1620, 512, 1608, 1620, 512, 1575, 1621, 512, 1610, 1620, 514, 1575, 1652, - 514, 1608, 1652, 514, 1735, 1652, 514, 1610, 1652, 512, 1749, 1620, 512, - 1729, 1620, 512, 1746, 1620, 512, 2344, 2364, 512, 2352, 2364, 512, 2355, - 2364, 512, 2325, 2364, 512, 2326, 2364, 512, 2327, 2364, 512, 2332, 2364, - 512, 2337, 2364, 512, 2338, 2364, 512, 2347, 2364, 512, 2351, 2364, 512, - 2503, 2494, 512, 2503, 2519, 512, 2465, 2492, 512, 2466, 2492, 512, 2479, - 2492, 512, 2610, 2620, 512, 2616, 2620, 512, 2582, 2620, 512, 2583, 2620, - 512, 2588, 2620, 512, 2603, 2620, 512, 2887, 2902, 512, 2887, 2878, 512, - 2887, 2903, 512, 2849, 2876, 512, 2850, 2876, 512, 2962, 3031, 512, 3014, - 3006, 512, 3015, 3006, 512, 3014, 3031, 512, 3142, 3158, 512, 3263, 3285, - 512, 3270, 3285, 512, 3270, 3286, 512, 3270, 3266, 512, 3274, 3285, 512, - 3398, 3390, 512, 3399, 3390, 512, 3398, 3415, 512, 3545, 3530, 512, 3545, - 3535, 512, 3548, 3530, 512, 3545, 3551, 514, 3661, 3634, 514, 3789, 3762, - 514, 3755, 3737, 514, 3755, 3745, 257, 3851, 512, 3906, 4023, 512, 3916, - 4023, 512, 3921, 4023, 512, 3926, 4023, 512, 3931, 4023, 512, 3904, 4021, - 512, 3953, 3954, 512, 3953, 3956, 512, 4018, 3968, 514, 4018, 3969, 512, - 4019, 3968, 514, 4019, 3969, 512, 3953, 3968, 512, 3986, 4023, 512, 3996, - 4023, 512, 4001, 4023, 512, 4006, 4023, 512, 4011, 4023, 512, 3984, 4021, - 512, 4133, 4142, 259, 4316, 512, 6917, 6965, 512, 6919, 6965, 512, 6921, - 6965, 512, 6923, 6965, 512, 6925, 6965, 512, 6929, 6965, 512, 6970, 6965, - 512, 6972, 6965, 512, 6974, 6965, 512, 6975, 6965, 512, 6978, 6965, 259, - 65, 259, 198, 259, 66, 259, 68, 259, 69, 259, 398, 259, 71, 259, 72, 259, - 73, 259, 74, 259, 75, 259, 76, 259, 77, 259, 78, 259, 79, 259, 546, 259, - 80, 259, 82, 259, 84, 259, 85, 259, 87, 259, 97, 259, 592, 259, 593, 259, - 7426, 259, 98, 259, 100, 259, 101, 259, 601, 259, 603, 259, 604, 259, - 103, 259, 107, 259, 109, 259, 331, 259, 111, 259, 596, 259, 7446, 259, - 7447, 259, 112, 259, 116, 259, 117, 259, 7453, 259, 623, 259, 118, 259, - 7461, 259, 946, 259, 947, 259, 948, 259, 966, 259, 967, 261, 105, 261, - 114, 261, 117, 261, 118, 261, 946, 261, 947, 261, 961, 261, 966, 261, - 967, 259, 1085, 259, 594, 259, 99, 259, 597, 259, 240, 259, 604, 259, - 102, 259, 607, 259, 609, 259, 613, 259, 616, 259, 617, 259, 618, 259, - 7547, 259, 669, 259, 621, 259, 7557, 259, 671, 259, 625, 259, 624, 259, - 626, 259, 627, 259, 628, 259, 629, 259, 632, 259, 642, 259, 643, 259, - 427, 259, 649, 259, 650, 259, 7452, 259, 651, 259, 652, 259, 122, 259, - 656, 259, 657, 259, 658, 259, 952, 512, 65, 805, 512, 97, 805, 512, 66, - 775, 512, 98, 775, 512, 66, 803, 512, 98, 803, 512, 66, 817, 512, 98, - 817, 512, 199, 769, 512, 231, 769, 512, 68, 775, 512, 100, 775, 512, 68, - 803, 512, 100, 803, 512, 68, 817, 512, 100, 817, 512, 68, 807, 512, 100, - 807, 512, 68, 813, 512, 100, 813, 512, 274, 768, 512, 275, 768, 512, 274, - 769, 512, 275, 769, 512, 69, 813, 512, 101, 813, 512, 69, 816, 512, 101, - 816, 512, 552, 774, 512, 553, 774, 512, 70, 775, 512, 102, 775, 512, 71, - 772, 512, 103, 772, 512, 72, 775, 512, 104, 775, 512, 72, 803, 512, 104, - 803, 512, 72, 776, 512, 104, 776, 512, 72, 807, 512, 104, 807, 512, 72, - 814, 512, 104, 814, 512, 73, 816, 512, 105, 816, 512, 207, 769, 512, 239, - 769, 512, 75, 769, 512, 107, 769, 512, 75, 803, 512, 107, 803, 512, 75, - 817, 512, 107, 817, 512, 76, 803, 512, 108, 803, 512, 7734, 772, 512, - 7735, 772, 512, 76, 817, 512, 108, 817, 512, 76, 813, 512, 108, 813, 512, - 77, 769, 512, 109, 769, 512, 77, 775, 512, 109, 775, 512, 77, 803, 512, - 109, 803, 512, 78, 775, 512, 110, 775, 512, 78, 803, 512, 110, 803, 512, - 78, 817, 512, 110, 817, 512, 78, 813, 512, 110, 813, 512, 213, 769, 512, - 245, 769, 512, 213, 776, 512, 245, 776, 512, 332, 768, 512, 333, 768, - 512, 332, 769, 512, 333, 769, 512, 80, 769, 512, 112, 769, 512, 80, 775, - 512, 112, 775, 512, 82, 775, 512, 114, 775, 512, 82, 803, 512, 114, 803, - 512, 7770, 772, 512, 7771, 772, 512, 82, 817, 512, 114, 817, 512, 83, - 775, 512, 115, 775, 512, 83, 803, 512, 115, 803, 512, 346, 775, 512, 347, - 775, 512, 352, 775, 512, 353, 775, 512, 7778, 775, 512, 7779, 775, 512, - 84, 775, 512, 116, 775, 512, 84, 803, 512, 116, 803, 512, 84, 817, 512, - 116, 817, 512, 84, 813, 512, 116, 813, 512, 85, 804, 512, 117, 804, 512, - 85, 816, 512, 117, 816, 512, 85, 813, 512, 117, 813, 512, 360, 769, 512, - 361, 769, 512, 362, 776, 512, 363, 776, 512, 86, 771, 512, 118, 771, 512, - 86, 803, 512, 118, 803, 512, 87, 768, 512, 119, 768, 512, 87, 769, 512, - 119, 769, 512, 87, 776, 512, 119, 776, 512, 87, 775, 512, 119, 775, 512, - 87, 803, 512, 119, 803, 512, 88, 775, 512, 120, 775, 512, 88, 776, 512, - 120, 776, 512, 89, 775, 512, 121, 775, 512, 90, 770, 512, 122, 770, 512, - 90, 803, 512, 122, 803, 512, 90, 817, 512, 122, 817, 512, 104, 817, 512, - 116, 776, 512, 119, 778, 512, 121, 778, 514, 97, 702, 512, 383, 775, 512, - 65, 803, 512, 97, 803, 512, 65, 777, 512, 97, 777, 512, 194, 769, 512, - 226, 769, 512, 194, 768, 512, 226, 768, 512, 194, 777, 512, 226, 777, - 512, 194, 771, 512, 226, 771, 512, 7840, 770, 512, 7841, 770, 512, 258, - 769, 512, 259, 769, 512, 258, 768, 512, 259, 768, 512, 258, 777, 512, - 259, 777, 512, 258, 771, 512, 259, 771, 512, 7840, 774, 512, 7841, 774, - 512, 69, 803, 512, 101, 803, 512, 69, 777, 512, 101, 777, 512, 69, 771, - 512, 101, 771, 512, 202, 769, 512, 234, 769, 512, 202, 768, 512, 234, - 768, 512, 202, 777, 512, 234, 777, 512, 202, 771, 512, 234, 771, 512, - 7864, 770, 512, 7865, 770, 512, 73, 777, 512, 105, 777, 512, 73, 803, - 512, 105, 803, 512, 79, 803, 512, 111, 803, 512, 79, 777, 512, 111, 777, - 512, 212, 769, 512, 244, 769, 512, 212, 768, 512, 244, 768, 512, 212, - 777, 512, 244, 777, 512, 212, 771, 512, 244, 771, 512, 7884, 770, 512, - 7885, 770, 512, 416, 769, 512, 417, 769, 512, 416, 768, 512, 417, 768, - 512, 416, 777, 512, 417, 777, 512, 416, 771, 512, 417, 771, 512, 416, - 803, 512, 417, 803, 512, 85, 803, 512, 117, 803, 512, 85, 777, 512, 117, - 777, 512, 431, 769, 512, 432, 769, 512, 431, 768, 512, 432, 768, 512, - 431, 777, 512, 432, 777, 512, 431, 771, 512, 432, 771, 512, 431, 803, - 512, 432, 803, 512, 89, 768, 512, 121, 768, 512, 89, 803, 512, 121, 803, - 512, 89, 777, 512, 121, 777, 512, 89, 771, 512, 121, 771, 512, 945, 787, - 512, 945, 788, 512, 7936, 768, 512, 7937, 768, 512, 7936, 769, 512, 7937, - 769, 512, 7936, 834, 512, 7937, 834, 512, 913, 787, 512, 913, 788, 512, - 7944, 768, 512, 7945, 768, 512, 7944, 769, 512, 7945, 769, 512, 7944, - 834, 512, 7945, 834, 512, 949, 787, 512, 949, 788, 512, 7952, 768, 512, - 7953, 768, 512, 7952, 769, 512, 7953, 769, 512, 917, 787, 512, 917, 788, - 512, 7960, 768, 512, 7961, 768, 512, 7960, 769, 512, 7961, 769, 512, 951, - 787, 512, 951, 788, 512, 7968, 768, 512, 7969, 768, 512, 7968, 769, 512, - 7969, 769, 512, 7968, 834, 512, 7969, 834, 512, 919, 787, 512, 919, 788, - 512, 7976, 768, 512, 7977, 768, 512, 7976, 769, 512, 7977, 769, 512, - 7976, 834, 512, 7977, 834, 512, 953, 787, 512, 953, 788, 512, 7984, 768, - 512, 7985, 768, 512, 7984, 769, 512, 7985, 769, 512, 7984, 834, 512, + 59, 512, 168, 769, 512, 913, 769, 256, 183, 512, 917, 769, 512, 919, 769, + 512, 921, 769, 512, 927, 769, 512, 933, 769, 512, 937, 769, 512, 970, + 769, 512, 921, 776, 512, 933, 776, 512, 945, 769, 512, 949, 769, 512, + 951, 769, 512, 953, 769, 512, 971, 769, 512, 953, 776, 512, 965, 776, + 512, 959, 769, 512, 965, 769, 512, 969, 769, 258, 946, 258, 952, 258, + 933, 512, 978, 769, 512, 978, 776, 258, 966, 258, 960, 258, 954, 258, + 961, 258, 962, 258, 920, 258, 949, 258, 931, 512, 1045, 768, 512, 1045, + 776, 512, 1043, 769, 512, 1030, 776, 512, 1050, 769, 512, 1048, 768, 512, + 1059, 774, 512, 1048, 774, 512, 1080, 774, 512, 1077, 768, 512, 1077, + 776, 512, 1075, 769, 512, 1110, 776, 512, 1082, 769, 512, 1080, 768, 512, + 1091, 774, 512, 1140, 783, 512, 1141, 783, 512, 1046, 774, 512, 1078, + 774, 512, 1040, 774, 512, 1072, 774, 512, 1040, 776, 512, 1072, 776, 512, + 1045, 774, 512, 1077, 774, 512, 1240, 776, 512, 1241, 776, 512, 1046, + 776, 512, 1078, 776, 512, 1047, 776, 512, 1079, 776, 512, 1048, 772, 512, + 1080, 772, 512, 1048, 776, 512, 1080, 776, 512, 1054, 776, 512, 1086, + 776, 512, 1256, 776, 512, 1257, 776, 512, 1069, 776, 512, 1101, 776, 512, + 1059, 772, 512, 1091, 772, 512, 1059, 776, 512, 1091, 776, 512, 1059, + 779, 512, 1091, 779, 512, 1063, 776, 512, 1095, 776, 512, 1067, 776, 512, + 1099, 776, 514, 1381, 1410, 512, 1575, 1619, 512, 1575, 1620, 512, 1608, + 1620, 512, 1575, 1621, 512, 1610, 1620, 514, 1575, 1652, 514, 1608, 1652, + 514, 1735, 1652, 514, 1610, 1652, 512, 1749, 1620, 512, 1729, 1620, 512, + 1746, 1620, 512, 2344, 2364, 512, 2352, 2364, 512, 2355, 2364, 512, 2325, + 2364, 512, 2326, 2364, 512, 2327, 2364, 512, 2332, 2364, 512, 2337, 2364, + 512, 2338, 2364, 512, 2347, 2364, 512, 2351, 2364, 512, 2503, 2494, 512, + 2503, 2519, 512, 2465, 2492, 512, 2466, 2492, 512, 2479, 2492, 512, 2610, + 2620, 512, 2616, 2620, 512, 2582, 2620, 512, 2583, 2620, 512, 2588, 2620, + 512, 2603, 2620, 512, 2887, 2902, 512, 2887, 2878, 512, 2887, 2903, 512, + 2849, 2876, 512, 2850, 2876, 512, 2962, 3031, 512, 3014, 3006, 512, 3015, + 3006, 512, 3014, 3031, 512, 3142, 3158, 512, 3263, 3285, 512, 3270, 3285, + 512, 3270, 3286, 512, 3270, 3266, 512, 3274, 3285, 512, 3398, 3390, 512, + 3399, 3390, 512, 3398, 3415, 512, 3545, 3530, 512, 3545, 3535, 512, 3548, + 3530, 512, 3545, 3551, 514, 3661, 3634, 514, 3789, 3762, 514, 3755, 3737, + 514, 3755, 3745, 257, 3851, 512, 3906, 4023, 512, 3916, 4023, 512, 3921, + 4023, 512, 3926, 4023, 512, 3931, 4023, 512, 3904, 4021, 512, 3953, 3954, + 512, 3953, 3956, 512, 4018, 3968, 514, 4018, 3969, 512, 4019, 3968, 514, + 4019, 3969, 512, 3953, 3968, 512, 3986, 4023, 512, 3996, 4023, 512, 4001, + 4023, 512, 4006, 4023, 512, 4011, 4023, 512, 3984, 4021, 512, 4133, 4142, + 259, 4316, 512, 6917, 6965, 512, 6919, 6965, 512, 6921, 6965, 512, 6923, + 6965, 512, 6925, 6965, 512, 6929, 6965, 512, 6970, 6965, 512, 6972, 6965, + 512, 6974, 6965, 512, 6975, 6965, 512, 6978, 6965, 259, 65, 259, 198, + 259, 66, 259, 68, 259, 69, 259, 398, 259, 71, 259, 72, 259, 73, 259, 74, + 259, 75, 259, 76, 259, 77, 259, 78, 259, 79, 259, 546, 259, 80, 259, 82, + 259, 84, 259, 85, 259, 87, 259, 592, 259, 593, 259, 7426, 259, 98, 259, + 100, 259, 101, 259, 601, 259, 603, 259, 604, 259, 103, 259, 107, 259, + 109, 259, 331, 259, 596, 259, 7446, 259, 7447, 259, 112, 259, 116, 259, + 117, 259, 7453, 259, 623, 259, 118, 259, 7461, 259, 946, 259, 947, 259, + 948, 259, 966, 259, 967, 261, 105, 261, 114, 261, 117, 261, 118, 261, + 946, 261, 947, 261, 961, 261, 966, 261, 967, 259, 1085, 259, 594, 259, + 99, 259, 597, 259, 240, 259, 102, 259, 607, 259, 609, 259, 613, 259, 616, + 259, 617, 259, 618, 259, 7547, 259, 669, 259, 621, 259, 7557, 259, 671, + 259, 625, 259, 624, 259, 626, 259, 627, 259, 628, 259, 629, 259, 632, + 259, 642, 259, 643, 259, 427, 259, 649, 259, 650, 259, 7452, 259, 651, + 259, 652, 259, 122, 259, 656, 259, 657, 259, 658, 259, 952, 512, 65, 805, + 512, 97, 805, 512, 66, 775, 512, 98, 775, 512, 66, 803, 512, 98, 803, + 512, 66, 817, 512, 98, 817, 512, 199, 769, 512, 231, 769, 512, 68, 775, + 512, 100, 775, 512, 68, 803, 512, 100, 803, 512, 68, 817, 512, 100, 817, + 512, 68, 807, 512, 100, 807, 512, 68, 813, 512, 100, 813, 512, 274, 768, + 512, 275, 768, 512, 274, 769, 512, 275, 769, 512, 69, 813, 512, 101, 813, + 512, 69, 816, 512, 101, 816, 512, 552, 774, 512, 553, 774, 512, 70, 775, + 512, 102, 775, 512, 71, 772, 512, 103, 772, 512, 72, 775, 512, 104, 775, + 512, 72, 803, 512, 104, 803, 512, 72, 776, 512, 104, 776, 512, 72, 807, + 512, 104, 807, 512, 72, 814, 512, 104, 814, 512, 73, 816, 512, 105, 816, + 512, 207, 769, 512, 239, 769, 512, 75, 769, 512, 107, 769, 512, 75, 803, + 512, 107, 803, 512, 75, 817, 512, 107, 817, 512, 76, 803, 512, 108, 803, + 512, 7734, 772, 512, 7735, 772, 512, 76, 817, 512, 108, 817, 512, 76, + 813, 512, 108, 813, 512, 77, 769, 512, 109, 769, 512, 77, 775, 512, 109, + 775, 512, 77, 803, 512, 109, 803, 512, 78, 775, 512, 110, 775, 512, 78, + 803, 512, 110, 803, 512, 78, 817, 512, 110, 817, 512, 78, 813, 512, 110, + 813, 512, 213, 769, 512, 245, 769, 512, 213, 776, 512, 245, 776, 512, + 332, 768, 512, 333, 768, 512, 332, 769, 512, 333, 769, 512, 80, 769, 512, + 112, 769, 512, 80, 775, 512, 112, 775, 512, 82, 775, 512, 114, 775, 512, + 82, 803, 512, 114, 803, 512, 7770, 772, 512, 7771, 772, 512, 82, 817, + 512, 114, 817, 512, 83, 775, 512, 115, 775, 512, 83, 803, 512, 115, 803, + 512, 346, 775, 512, 347, 775, 512, 352, 775, 512, 353, 775, 512, 7778, + 775, 512, 7779, 775, 512, 84, 775, 512, 116, 775, 512, 84, 803, 512, 116, + 803, 512, 84, 817, 512, 116, 817, 512, 84, 813, 512, 116, 813, 512, 85, + 804, 512, 117, 804, 512, 85, 816, 512, 117, 816, 512, 85, 813, 512, 117, + 813, 512, 360, 769, 512, 361, 769, 512, 362, 776, 512, 363, 776, 512, 86, + 771, 512, 118, 771, 512, 86, 803, 512, 118, 803, 512, 87, 768, 512, 119, + 768, 512, 87, 769, 512, 119, 769, 512, 87, 776, 512, 119, 776, 512, 87, + 775, 512, 119, 775, 512, 87, 803, 512, 119, 803, 512, 88, 775, 512, 120, + 775, 512, 88, 776, 512, 120, 776, 512, 89, 775, 512, 121, 775, 512, 90, + 770, 512, 122, 770, 512, 90, 803, 512, 122, 803, 512, 90, 817, 512, 122, + 817, 512, 104, 817, 512, 116, 776, 512, 119, 778, 512, 121, 778, 514, 97, + 702, 512, 383, 775, 512, 65, 803, 512, 97, 803, 512, 65, 777, 512, 97, + 777, 512, 194, 769, 512, 226, 769, 512, 194, 768, 512, 226, 768, 512, + 194, 777, 512, 226, 777, 512, 194, 771, 512, 226, 771, 512, 7840, 770, + 512, 7841, 770, 512, 258, 769, 512, 259, 769, 512, 258, 768, 512, 259, + 768, 512, 258, 777, 512, 259, 777, 512, 258, 771, 512, 259, 771, 512, + 7840, 774, 512, 7841, 774, 512, 69, 803, 512, 101, 803, 512, 69, 777, + 512, 101, 777, 512, 69, 771, 512, 101, 771, 512, 202, 769, 512, 234, 769, + 512, 202, 768, 512, 234, 768, 512, 202, 777, 512, 234, 777, 512, 202, + 771, 512, 234, 771, 512, 7864, 770, 512, 7865, 770, 512, 73, 777, 512, + 105, 777, 512, 73, 803, 512, 105, 803, 512, 79, 803, 512, 111, 803, 512, + 79, 777, 512, 111, 777, 512, 212, 769, 512, 244, 769, 512, 212, 768, 512, + 244, 768, 512, 212, 777, 512, 244, 777, 512, 212, 771, 512, 244, 771, + 512, 7884, 770, 512, 7885, 770, 512, 416, 769, 512, 417, 769, 512, 416, + 768, 512, 417, 768, 512, 416, 777, 512, 417, 777, 512, 416, 771, 512, + 417, 771, 512, 416, 803, 512, 417, 803, 512, 85, 803, 512, 117, 803, 512, + 85, 777, 512, 117, 777, 512, 431, 769, 512, 432, 769, 512, 431, 768, 512, + 432, 768, 512, 431, 777, 512, 432, 777, 512, 431, 771, 512, 432, 771, + 512, 431, 803, 512, 432, 803, 512, 89, 768, 512, 121, 768, 512, 89, 803, + 512, 121, 803, 512, 89, 777, 512, 121, 777, 512, 89, 771, 512, 121, 771, + 512, 945, 787, 512, 945, 788, 512, 7936, 768, 512, 7937, 768, 512, 7936, + 769, 512, 7937, 769, 512, 7936, 834, 512, 7937, 834, 512, 913, 787, 512, + 913, 788, 512, 7944, 768, 512, 7945, 768, 512, 7944, 769, 512, 7945, 769, + 512, 7944, 834, 512, 7945, 834, 512, 949, 787, 512, 949, 788, 512, 7952, + 768, 512, 7953, 768, 512, 7952, 769, 512, 7953, 769, 512, 917, 787, 512, + 917, 788, 512, 7960, 768, 512, 7961, 768, 512, 7960, 769, 512, 7961, 769, + 512, 951, 787, 512, 951, 788, 512, 7968, 768, 512, 7969, 768, 512, 7968, + 769, 512, 7969, 769, 512, 7968, 834, 512, 7969, 834, 512, 919, 787, 512, + 919, 788, 512, 7976, 768, 512, 7977, 768, 512, 7976, 769, 512, 7977, 769, + 512, 7976, 834, 512, 7977, 834, 512, 953, 787, 512, 953, 788, 512, 7984, + 768, 512, 7985, 768, 512, 7984, 769, 512, 7985, 769, 512, 7984, 834, 512, 7985, 834, 512, 921, 787, 512, 921, 788, 512, 7992, 768, 512, 7993, 768, 512, 7992, 769, 512, 7993, 769, 512, 7992, 834, 512, 7993, 834, 512, 959, 787, 512, 959, 788, 512, 8000, 768, 512, 8001, 768, 512, 8000, 769, 512, @@ -3561,124 +3623,121 @@ static const unsigned int decomp_data[] = { 8045, 837, 512, 8046, 837, 512, 8047, 837, 512, 945, 774, 512, 945, 772, 512, 8048, 837, 512, 945, 837, 512, 940, 837, 512, 945, 834, 512, 8118, 837, 512, 913, 774, 512, 913, 772, 512, 913, 768, 256, 902, 512, 913, - 837, 514, 32, 787, 256, 953, 514, 32, 787, 514, 32, 834, 512, 168, 834, - 512, 8052, 837, 512, 951, 837, 512, 942, 837, 512, 951, 834, 512, 8134, - 837, 512, 917, 768, 256, 904, 512, 919, 768, 256, 905, 512, 919, 837, - 512, 8127, 768, 512, 8127, 769, 512, 8127, 834, 512, 953, 774, 512, 953, - 772, 512, 970, 768, 256, 912, 512, 953, 834, 512, 970, 834, 512, 921, - 774, 512, 921, 772, 512, 921, 768, 256, 906, 512, 8190, 768, 512, 8190, - 769, 512, 8190, 834, 512, 965, 774, 512, 965, 772, 512, 971, 768, 256, - 944, 512, 961, 787, 512, 961, 788, 512, 965, 834, 512, 971, 834, 512, - 933, 774, 512, 933, 772, 512, 933, 768, 256, 910, 512, 929, 788, 512, - 168, 768, 256, 901, 256, 96, 512, 8060, 837, 512, 969, 837, 512, 974, - 837, 512, 969, 834, 512, 8182, 837, 512, 927, 768, 256, 908, 512, 937, - 768, 256, 911, 512, 937, 837, 256, 180, 514, 32, 788, 256, 8194, 256, - 8195, 258, 32, 258, 32, 258, 32, 258, 32, 258, 32, 257, 32, 258, 32, 258, - 32, 258, 32, 257, 8208, 514, 32, 819, 258, 46, 514, 46, 46, 770, 46, 46, - 46, 257, 32, 514, 8242, 8242, 770, 8242, 8242, 8242, 514, 8245, 8245, - 770, 8245, 8245, 8245, 514, 33, 33, 514, 32, 773, 514, 63, 63, 514, 63, - 33, 514, 33, 63, 1026, 8242, 8242, 8242, 8242, 258, 32, 259, 48, 259, - 105, 259, 52, 259, 53, 259, 54, 259, 55, 259, 56, 259, 57, 259, 43, 259, - 8722, 259, 61, 259, 40, 259, 41, 259, 110, 261, 48, 261, 49, 261, 50, - 261, 51, 261, 52, 261, 53, 261, 54, 261, 55, 261, 56, 261, 57, 261, 43, - 261, 8722, 261, 61, 261, 40, 261, 41, 261, 97, 261, 101, 261, 111, 261, - 120, 261, 601, 261, 104, 261, 107, 261, 108, 261, 109, 261, 110, 261, - 112, 261, 115, 261, 116, 514, 82, 115, 770, 97, 47, 99, 770, 97, 47, 115, - 262, 67, 514, 176, 67, 770, 99, 47, 111, 770, 99, 47, 117, 258, 400, 514, - 176, 70, 262, 103, 262, 72, 262, 72, 262, 72, 262, 104, 262, 295, 262, - 73, 262, 73, 262, 76, 262, 108, 262, 78, 514, 78, 111, 262, 80, 262, 81, - 262, 82, 262, 82, 262, 82, 515, 83, 77, 770, 84, 69, 76, 515, 84, 77, - 262, 90, 256, 937, 262, 90, 256, 75, 256, 197, 262, 66, 262, 67, 262, - 101, 262, 69, 262, 70, 262, 77, 262, 111, 258, 1488, 258, 1489, 258, - 1490, 258, 1491, 262, 105, 770, 70, 65, 88, 262, 960, 262, 947, 262, 915, - 262, 928, 262, 8721, 262, 68, 262, 100, 262, 101, 262, 105, 262, 106, - 772, 49, 8260, 55, 772, 49, 8260, 57, 1028, 49, 8260, 49, 48, 772, 49, - 8260, 51, 772, 50, 8260, 51, 772, 49, 8260, 53, 772, 50, 8260, 53, 772, - 51, 8260, 53, 772, 52, 8260, 53, 772, 49, 8260, 54, 772, 53, 8260, 54, - 772, 49, 8260, 56, 772, 51, 8260, 56, 772, 53, 8260, 56, 772, 55, 8260, - 56, 516, 49, 8260, 258, 73, 514, 73, 73, 770, 73, 73, 73, 514, 73, 86, - 258, 86, 514, 86, 73, 770, 86, 73, 73, 1026, 86, 73, 73, 73, 514, 73, 88, - 258, 88, 514, 88, 73, 770, 88, 73, 73, 258, 76, 258, 67, 258, 68, 258, - 77, 258, 105, 514, 105, 105, 770, 105, 105, 105, 514, 105, 118, 258, 118, - 514, 118, 105, 770, 118, 105, 105, 1026, 118, 105, 105, 105, 514, 105, - 120, 258, 120, 514, 120, 105, 770, 120, 105, 105, 258, 108, 258, 99, 258, - 100, 258, 109, 772, 48, 8260, 51, 512, 8592, 824, 512, 8594, 824, 512, - 8596, 824, 512, 8656, 824, 512, 8660, 824, 512, 8658, 824, 512, 8707, - 824, 512, 8712, 824, 512, 8715, 824, 512, 8739, 824, 512, 8741, 824, 514, - 8747, 8747, 770, 8747, 8747, 8747, 514, 8750, 8750, 770, 8750, 8750, - 8750, 512, 8764, 824, 512, 8771, 824, 512, 8773, 824, 512, 8776, 824, - 512, 61, 824, 512, 8801, 824, 512, 8781, 824, 512, 60, 824, 512, 62, 824, - 512, 8804, 824, 512, 8805, 824, 512, 8818, 824, 512, 8819, 824, 512, - 8822, 824, 512, 8823, 824, 512, 8826, 824, 512, 8827, 824, 512, 8834, - 824, 512, 8835, 824, 512, 8838, 824, 512, 8839, 824, 512, 8866, 824, 512, - 8872, 824, 512, 8873, 824, 512, 8875, 824, 512, 8828, 824, 512, 8829, - 824, 512, 8849, 824, 512, 8850, 824, 512, 8882, 824, 512, 8883, 824, 512, - 8884, 824, 512, 8885, 824, 256, 12296, 256, 12297, 263, 49, 263, 50, 263, - 51, 263, 52, 263, 53, 263, 54, 263, 55, 263, 56, 263, 57, 519, 49, 48, - 519, 49, 49, 519, 49, 50, 519, 49, 51, 519, 49, 52, 519, 49, 53, 519, 49, - 54, 519, 49, 55, 519, 49, 56, 519, 49, 57, 519, 50, 48, 770, 40, 49, 41, - 770, 40, 50, 41, 770, 40, 51, 41, 770, 40, 52, 41, 770, 40, 53, 41, 770, - 40, 54, 41, 770, 40, 55, 41, 770, 40, 56, 41, 770, 40, 57, 41, 1026, 40, - 49, 48, 41, 1026, 40, 49, 49, 41, 1026, 40, 49, 50, 41, 1026, 40, 49, 51, - 41, 1026, 40, 49, 52, 41, 1026, 40, 49, 53, 41, 1026, 40, 49, 54, 41, - 1026, 40, 49, 55, 41, 1026, 40, 49, 56, 41, 1026, 40, 49, 57, 41, 1026, - 40, 50, 48, 41, 514, 49, 46, 514, 50, 46, 514, 51, 46, 514, 52, 46, 514, - 53, 46, 514, 54, 46, 514, 55, 46, 514, 56, 46, 514, 57, 46, 770, 49, 48, - 46, 770, 49, 49, 46, 770, 49, 50, 46, 770, 49, 51, 46, 770, 49, 52, 46, - 770, 49, 53, 46, 770, 49, 54, 46, 770, 49, 55, 46, 770, 49, 56, 46, 770, - 49, 57, 46, 770, 50, 48, 46, 770, 40, 97, 41, 770, 40, 98, 41, 770, 40, - 99, 41, 770, 40, 100, 41, 770, 40, 101, 41, 770, 40, 102, 41, 770, 40, - 103, 41, 770, 40, 104, 41, 770, 40, 105, 41, 770, 40, 106, 41, 770, 40, - 107, 41, 770, 40, 108, 41, 770, 40, 109, 41, 770, 40, 110, 41, 770, 40, - 111, 41, 770, 40, 112, 41, 770, 40, 113, 41, 770, 40, 114, 41, 770, 40, - 115, 41, 770, 40, 116, 41, 770, 40, 117, 41, 770, 40, 118, 41, 770, 40, - 119, 41, 770, 40, 120, 41, 770, 40, 121, 41, 770, 40, 122, 41, 263, 65, - 263, 66, 263, 67, 263, 68, 263, 69, 263, 70, 263, 71, 263, 72, 263, 73, - 263, 74, 263, 75, 263, 76, 263, 77, 263, 78, 263, 79, 263, 80, 263, 81, - 263, 82, 263, 83, 263, 84, 263, 85, 263, 86, 263, 87, 263, 88, 263, 89, - 263, 90, 263, 97, 263, 98, 263, 99, 263, 100, 263, 101, 263, 102, 263, - 103, 263, 104, 263, 105, 263, 106, 263, 107, 263, 108, 263, 109, 263, - 110, 263, 111, 263, 112, 263, 113, 263, 114, 263, 115, 263, 116, 263, - 117, 263, 118, 263, 119, 263, 120, 263, 121, 263, 122, 263, 48, 1026, - 8747, 8747, 8747, 8747, 770, 58, 58, 61, 514, 61, 61, 770, 61, 61, 61, - 512, 10973, 824, 261, 106, 259, 86, 259, 11617, 258, 27597, 258, 40863, - 258, 19968, 258, 20008, 258, 20022, 258, 20031, 258, 20057, 258, 20101, - 258, 20108, 258, 20128, 258, 20154, 258, 20799, 258, 20837, 258, 20843, - 258, 20866, 258, 20886, 258, 20907, 258, 20960, 258, 20981, 258, 20992, - 258, 21147, 258, 21241, 258, 21269, 258, 21274, 258, 21304, 258, 21313, - 258, 21340, 258, 21353, 258, 21378, 258, 21430, 258, 21448, 258, 21475, - 258, 22231, 258, 22303, 258, 22763, 258, 22786, 258, 22794, 258, 22805, - 258, 22823, 258, 22899, 258, 23376, 258, 23424, 258, 23544, 258, 23567, - 258, 23586, 258, 23608, 258, 23662, 258, 23665, 258, 24027, 258, 24037, - 258, 24049, 258, 24062, 258, 24178, 258, 24186, 258, 24191, 258, 24308, - 258, 24318, 258, 24331, 258, 24339, 258, 24400, 258, 24417, 258, 24435, - 258, 24515, 258, 25096, 258, 25142, 258, 25163, 258, 25903, 258, 25908, - 258, 25991, 258, 26007, 258, 26020, 258, 26041, 258, 26080, 258, 26085, - 258, 26352, 258, 26376, 258, 26408, 258, 27424, 258, 27490, 258, 27513, - 258, 27571, 258, 27595, 258, 27604, 258, 27611, 258, 27663, 258, 27668, - 258, 27700, 258, 28779, 258, 29226, 258, 29238, 258, 29243, 258, 29247, - 258, 29255, 258, 29273, 258, 29275, 258, 29356, 258, 29572, 258, 29577, - 258, 29916, 258, 29926, 258, 29976, 258, 29983, 258, 29992, 258, 30000, - 258, 30091, 258, 30098, 258, 30326, 258, 30333, 258, 30382, 258, 30399, - 258, 30446, 258, 30683, 258, 30690, 258, 30707, 258, 31034, 258, 31160, - 258, 31166, 258, 31348, 258, 31435, 258, 31481, 258, 31859, 258, 31992, - 258, 32566, 258, 32593, 258, 32650, 258, 32701, 258, 32769, 258, 32780, - 258, 32786, 258, 32819, 258, 32895, 258, 32905, 258, 33251, 258, 33258, - 258, 33267, 258, 33276, 258, 33292, 258, 33307, 258, 33311, 258, 33390, - 258, 33394, 258, 33400, 258, 34381, 258, 34411, 258, 34880, 258, 34892, - 258, 34915, 258, 35198, 258, 35211, 258, 35282, 258, 35328, 258, 35895, - 258, 35910, 258, 35925, 258, 35960, 258, 35997, 258, 36196, 258, 36208, - 258, 36275, 258, 36523, 258, 36554, 258, 36763, 258, 36784, 258, 36789, - 258, 37009, 258, 37193, 258, 37318, 258, 37324, 258, 37329, 258, 38263, - 258, 38272, 258, 38428, 258, 38582, 258, 38585, 258, 38632, 258, 38737, - 258, 38750, 258, 38754, 258, 38761, 258, 38859, 258, 38893, 258, 38899, - 258, 38913, 258, 39080, 258, 39131, 258, 39135, 258, 39318, 258, 39321, - 258, 39340, 258, 39592, 258, 39640, 258, 39647, 258, 39717, 258, 39727, - 258, 39730, 258, 39740, 258, 39770, 258, 40165, 258, 40565, 258, 40575, - 258, 40613, 258, 40635, 258, 40643, 258, 40653, 258, 40657, 258, 40697, - 258, 40701, 258, 40718, 258, 40723, 258, 40736, 258, 40763, 258, 40778, - 258, 40786, 258, 40845, 258, 40860, 258, 40864, 264, 32, 258, 12306, 258, - 21313, 258, 21316, 258, 21317, 512, 12363, 12441, 512, 12365, 12441, 512, + 837, 514, 32, 787, 256, 953, 514, 32, 834, 512, 168, 834, 512, 8052, 837, + 512, 951, 837, 512, 942, 837, 512, 951, 834, 512, 8134, 837, 512, 917, + 768, 256, 904, 512, 919, 768, 256, 905, 512, 919, 837, 512, 8127, 768, + 512, 8127, 769, 512, 8127, 834, 512, 953, 774, 512, 953, 772, 512, 970, + 768, 256, 912, 512, 953, 834, 512, 970, 834, 512, 921, 774, 512, 921, + 772, 512, 921, 768, 256, 906, 512, 8190, 768, 512, 8190, 769, 512, 8190, + 834, 512, 965, 774, 512, 965, 772, 512, 971, 768, 256, 944, 512, 961, + 787, 512, 961, 788, 512, 965, 834, 512, 971, 834, 512, 933, 774, 512, + 933, 772, 512, 933, 768, 256, 910, 512, 929, 788, 512, 168, 768, 256, + 901, 256, 96, 512, 8060, 837, 512, 969, 837, 512, 974, 837, 512, 969, + 834, 512, 8182, 837, 512, 927, 768, 256, 908, 512, 937, 768, 256, 911, + 512, 937, 837, 256, 180, 514, 32, 788, 256, 8194, 256, 8195, 258, 32, + 257, 8208, 514, 32, 819, 258, 46, 514, 46, 46, 770, 46, 46, 46, 514, + 8242, 8242, 770, 8242, 8242, 8242, 514, 8245, 8245, 770, 8245, 8245, + 8245, 514, 33, 33, 514, 32, 773, 514, 63, 63, 514, 63, 33, 514, 33, 63, + 1026, 8242, 8242, 8242, 8242, 259, 48, 259, 105, 259, 52, 259, 53, 259, + 54, 259, 55, 259, 56, 259, 57, 259, 43, 259, 8722, 259, 61, 259, 40, 259, + 41, 259, 110, 261, 48, 261, 49, 261, 50, 261, 51, 261, 52, 261, 53, 261, + 54, 261, 55, 261, 56, 261, 57, 261, 43, 261, 8722, 261, 61, 261, 40, 261, + 41, 261, 97, 261, 101, 261, 111, 261, 120, 261, 601, 261, 104, 261, 107, + 261, 108, 261, 109, 261, 110, 261, 112, 261, 115, 261, 116, 514, 82, 115, + 770, 97, 47, 99, 770, 97, 47, 115, 262, 67, 514, 176, 67, 770, 99, 47, + 111, 770, 99, 47, 117, 258, 400, 514, 176, 70, 262, 103, 262, 72, 262, + 104, 262, 295, 262, 73, 262, 76, 262, 108, 262, 78, 514, 78, 111, 262, + 80, 262, 81, 262, 82, 515, 83, 77, 770, 84, 69, 76, 515, 84, 77, 262, 90, + 256, 937, 256, 75, 256, 197, 262, 66, 262, 101, 262, 69, 262, 70, 262, + 77, 262, 111, 258, 1488, 258, 1489, 258, 1490, 258, 1491, 262, 105, 770, + 70, 65, 88, 262, 960, 262, 947, 262, 915, 262, 928, 262, 8721, 262, 68, + 262, 100, 262, 106, 772, 49, 8260, 55, 772, 49, 8260, 57, 1028, 49, 8260, + 49, 48, 772, 49, 8260, 51, 772, 50, 8260, 51, 772, 49, 8260, 53, 772, 50, + 8260, 53, 772, 51, 8260, 53, 772, 52, 8260, 53, 772, 49, 8260, 54, 772, + 53, 8260, 54, 772, 49, 8260, 56, 772, 51, 8260, 56, 772, 53, 8260, 56, + 772, 55, 8260, 56, 516, 49, 8260, 258, 73, 514, 73, 73, 770, 73, 73, 73, + 514, 73, 86, 258, 86, 514, 86, 73, 770, 86, 73, 73, 1026, 86, 73, 73, 73, + 514, 73, 88, 258, 88, 514, 88, 73, 770, 88, 73, 73, 258, 76, 258, 67, + 258, 68, 258, 77, 258, 105, 514, 105, 105, 770, 105, 105, 105, 514, 105, + 118, 258, 118, 514, 118, 105, 770, 118, 105, 105, 1026, 118, 105, 105, + 105, 514, 105, 120, 258, 120, 514, 120, 105, 770, 120, 105, 105, 258, + 108, 258, 99, 258, 100, 258, 109, 772, 48, 8260, 51, 512, 8592, 824, 512, + 8594, 824, 512, 8596, 824, 512, 8656, 824, 512, 8660, 824, 512, 8658, + 824, 512, 8707, 824, 512, 8712, 824, 512, 8715, 824, 512, 8739, 824, 512, + 8741, 824, 514, 8747, 8747, 770, 8747, 8747, 8747, 514, 8750, 8750, 770, + 8750, 8750, 8750, 512, 8764, 824, 512, 8771, 824, 512, 8773, 824, 512, + 8776, 824, 512, 61, 824, 512, 8801, 824, 512, 8781, 824, 512, 60, 824, + 512, 62, 824, 512, 8804, 824, 512, 8805, 824, 512, 8818, 824, 512, 8819, + 824, 512, 8822, 824, 512, 8823, 824, 512, 8826, 824, 512, 8827, 824, 512, + 8834, 824, 512, 8835, 824, 512, 8838, 824, 512, 8839, 824, 512, 8866, + 824, 512, 8872, 824, 512, 8873, 824, 512, 8875, 824, 512, 8828, 824, 512, + 8829, 824, 512, 8849, 824, 512, 8850, 824, 512, 8882, 824, 512, 8883, + 824, 512, 8884, 824, 512, 8885, 824, 256, 12296, 256, 12297, 263, 49, + 263, 50, 263, 51, 263, 52, 263, 53, 263, 54, 263, 55, 263, 56, 263, 57, + 519, 49, 48, 519, 49, 49, 519, 49, 50, 519, 49, 51, 519, 49, 52, 519, 49, + 53, 519, 49, 54, 519, 49, 55, 519, 49, 56, 519, 49, 57, 519, 50, 48, 770, + 40, 49, 41, 770, 40, 50, 41, 770, 40, 51, 41, 770, 40, 52, 41, 770, 40, + 53, 41, 770, 40, 54, 41, 770, 40, 55, 41, 770, 40, 56, 41, 770, 40, 57, + 41, 1026, 40, 49, 48, 41, 1026, 40, 49, 49, 41, 1026, 40, 49, 50, 41, + 1026, 40, 49, 51, 41, 1026, 40, 49, 52, 41, 1026, 40, 49, 53, 41, 1026, + 40, 49, 54, 41, 1026, 40, 49, 55, 41, 1026, 40, 49, 56, 41, 1026, 40, 49, + 57, 41, 1026, 40, 50, 48, 41, 514, 49, 46, 514, 50, 46, 514, 51, 46, 514, + 52, 46, 514, 53, 46, 514, 54, 46, 514, 55, 46, 514, 56, 46, 514, 57, 46, + 770, 49, 48, 46, 770, 49, 49, 46, 770, 49, 50, 46, 770, 49, 51, 46, 770, + 49, 52, 46, 770, 49, 53, 46, 770, 49, 54, 46, 770, 49, 55, 46, 770, 49, + 56, 46, 770, 49, 57, 46, 770, 50, 48, 46, 770, 40, 97, 41, 770, 40, 98, + 41, 770, 40, 99, 41, 770, 40, 100, 41, 770, 40, 101, 41, 770, 40, 102, + 41, 770, 40, 103, 41, 770, 40, 104, 41, 770, 40, 105, 41, 770, 40, 106, + 41, 770, 40, 107, 41, 770, 40, 108, 41, 770, 40, 109, 41, 770, 40, 110, + 41, 770, 40, 111, 41, 770, 40, 112, 41, 770, 40, 113, 41, 770, 40, 114, + 41, 770, 40, 115, 41, 770, 40, 116, 41, 770, 40, 117, 41, 770, 40, 118, + 41, 770, 40, 119, 41, 770, 40, 120, 41, 770, 40, 121, 41, 770, 40, 122, + 41, 263, 65, 263, 66, 263, 67, 263, 68, 263, 69, 263, 70, 263, 71, 263, + 72, 263, 73, 263, 74, 263, 75, 263, 76, 263, 77, 263, 78, 263, 79, 263, + 80, 263, 81, 263, 82, 263, 83, 263, 84, 263, 85, 263, 86, 263, 87, 263, + 88, 263, 89, 263, 90, 263, 97, 263, 98, 263, 99, 263, 100, 263, 101, 263, + 102, 263, 103, 263, 104, 263, 105, 263, 106, 263, 107, 263, 108, 263, + 109, 263, 110, 263, 111, 263, 112, 263, 113, 263, 114, 263, 115, 263, + 116, 263, 117, 263, 118, 263, 119, 263, 120, 263, 121, 263, 122, 263, 48, + 1026, 8747, 8747, 8747, 8747, 770, 58, 58, 61, 514, 61, 61, 770, 61, 61, + 61, 512, 10973, 824, 261, 106, 259, 86, 259, 11617, 258, 27597, 258, + 40863, 258, 19968, 258, 20008, 258, 20022, 258, 20031, 258, 20057, 258, + 20101, 258, 20108, 258, 20128, 258, 20154, 258, 20799, 258, 20837, 258, + 20843, 258, 20866, 258, 20886, 258, 20907, 258, 20960, 258, 20981, 258, + 20992, 258, 21147, 258, 21241, 258, 21269, 258, 21274, 258, 21304, 258, + 21313, 258, 21340, 258, 21353, 258, 21378, 258, 21430, 258, 21448, 258, + 21475, 258, 22231, 258, 22303, 258, 22763, 258, 22786, 258, 22794, 258, + 22805, 258, 22823, 258, 22899, 258, 23376, 258, 23424, 258, 23544, 258, + 23567, 258, 23586, 258, 23608, 258, 23662, 258, 23665, 258, 24027, 258, + 24037, 258, 24049, 258, 24062, 258, 24178, 258, 24186, 258, 24191, 258, + 24308, 258, 24318, 258, 24331, 258, 24339, 258, 24400, 258, 24417, 258, + 24435, 258, 24515, 258, 25096, 258, 25142, 258, 25163, 258, 25903, 258, + 25908, 258, 25991, 258, 26007, 258, 26020, 258, 26041, 258, 26080, 258, + 26085, 258, 26352, 258, 26376, 258, 26408, 258, 27424, 258, 27490, 258, + 27513, 258, 27571, 258, 27595, 258, 27604, 258, 27611, 258, 27663, 258, + 27668, 258, 27700, 258, 28779, 258, 29226, 258, 29238, 258, 29243, 258, + 29247, 258, 29255, 258, 29273, 258, 29275, 258, 29356, 258, 29572, 258, + 29577, 258, 29916, 258, 29926, 258, 29976, 258, 29983, 258, 29992, 258, + 30000, 258, 30091, 258, 30098, 258, 30326, 258, 30333, 258, 30382, 258, + 30399, 258, 30446, 258, 30683, 258, 30690, 258, 30707, 258, 31034, 258, + 31160, 258, 31166, 258, 31348, 258, 31435, 258, 31481, 258, 31859, 258, + 31992, 258, 32566, 258, 32593, 258, 32650, 258, 32701, 258, 32769, 258, + 32780, 258, 32786, 258, 32819, 258, 32895, 258, 32905, 258, 33251, 258, + 33258, 258, 33267, 258, 33276, 258, 33292, 258, 33307, 258, 33311, 258, + 33390, 258, 33394, 258, 33400, 258, 34381, 258, 34411, 258, 34880, 258, + 34892, 258, 34915, 258, 35198, 258, 35211, 258, 35282, 258, 35328, 258, + 35895, 258, 35910, 258, 35925, 258, 35960, 258, 35997, 258, 36196, 258, + 36208, 258, 36275, 258, 36523, 258, 36554, 258, 36763, 258, 36784, 258, + 36789, 258, 37009, 258, 37193, 258, 37318, 258, 37324, 258, 37329, 258, + 38263, 258, 38272, 258, 38428, 258, 38582, 258, 38585, 258, 38632, 258, + 38737, 258, 38750, 258, 38754, 258, 38761, 258, 38859, 258, 38893, 258, + 38899, 258, 38913, 258, 39080, 258, 39131, 258, 39135, 258, 39318, 258, + 39321, 258, 39340, 258, 39592, 258, 39640, 258, 39647, 258, 39717, 258, + 39727, 258, 39730, 258, 39740, 258, 39770, 258, 40165, 258, 40565, 258, + 40575, 258, 40613, 258, 40635, 258, 40643, 258, 40653, 258, 40657, 258, + 40697, 258, 40701, 258, 40718, 258, 40723, 258, 40736, 258, 40763, 258, + 40778, 258, 40786, 258, 40845, 258, 40860, 258, 40864, 264, 32, 258, + 12306, 258, 21316, 258, 21317, 512, 12363, 12441, 512, 12365, 12441, 512, 12367, 12441, 512, 12369, 12441, 512, 12371, 12441, 512, 12373, 12441, 512, 12375, 12441, 512, 12377, 12441, 512, 12379, 12441, 512, 12381, 12441, 512, 12383, 12441, 512, 12385, 12441, 512, 12388, 12441, 512, @@ -3844,43 +3903,42 @@ static const unsigned int decomp_data[] = { 51, 49, 26085, 778, 103, 97, 108, 259, 1098, 259, 1100, 259, 42863, 259, 67, 259, 70, 259, 81, 259, 294, 259, 339, 259, 42791, 259, 43831, 259, 619, 259, 43858, 259, 653, 256, 35912, 256, 26356, 256, 36554, 256, - 36040, 256, 28369, 256, 20018, 256, 21477, 256, 40860, 256, 40860, 256, - 22865, 256, 37329, 256, 21895, 256, 22856, 256, 25078, 256, 30313, 256, - 32645, 256, 34367, 256, 34746, 256, 35064, 256, 37007, 256, 27138, 256, - 27931, 256, 28889, 256, 29662, 256, 33853, 256, 37226, 256, 39409, 256, - 20098, 256, 21365, 256, 27396, 256, 29211, 256, 34349, 256, 40478, 256, - 23888, 256, 28651, 256, 34253, 256, 35172, 256, 25289, 256, 33240, 256, - 34847, 256, 24266, 256, 26391, 256, 28010, 256, 29436, 256, 37070, 256, - 20358, 256, 20919, 256, 21214, 256, 25796, 256, 27347, 256, 29200, 256, - 30439, 256, 32769, 256, 34310, 256, 34396, 256, 36335, 256, 38706, 256, - 39791, 256, 40442, 256, 30860, 256, 31103, 256, 32160, 256, 33737, 256, - 37636, 256, 40575, 256, 35542, 256, 22751, 256, 24324, 256, 31840, 256, - 32894, 256, 29282, 256, 30922, 256, 36034, 256, 38647, 256, 22744, 256, - 23650, 256, 27155, 256, 28122, 256, 28431, 256, 32047, 256, 32311, 256, - 38475, 256, 21202, 256, 32907, 256, 20956, 256, 20940, 256, 31260, 256, - 32190, 256, 33777, 256, 38517, 256, 35712, 256, 25295, 256, 27138, 256, - 35582, 256, 20025, 256, 23527, 256, 24594, 256, 29575, 256, 30064, 256, - 21271, 256, 30971, 256, 20415, 256, 24489, 256, 19981, 256, 27852, 256, - 25976, 256, 32034, 256, 21443, 256, 22622, 256, 30465, 256, 33865, 256, - 35498, 256, 27578, 256, 36784, 256, 27784, 256, 25342, 256, 33509, 256, - 25504, 256, 30053, 256, 20142, 256, 20841, 256, 20937, 256, 26753, 256, - 31975, 256, 33391, 256, 35538, 256, 37327, 256, 21237, 256, 21570, 256, - 22899, 256, 24300, 256, 26053, 256, 28670, 256, 31018, 256, 38317, 256, - 39530, 256, 40599, 256, 40654, 256, 21147, 256, 26310, 256, 27511, 256, - 36706, 256, 24180, 256, 24976, 256, 25088, 256, 25754, 256, 28451, 256, - 29001, 256, 29833, 256, 31178, 256, 32244, 256, 32879, 256, 36646, 256, - 34030, 256, 36899, 256, 37706, 256, 21015, 256, 21155, 256, 21693, 256, - 28872, 256, 35010, 256, 35498, 256, 24265, 256, 24565, 256, 25467, 256, - 27566, 256, 31806, 256, 29557, 256, 20196, 256, 22265, 256, 23527, 256, - 23994, 256, 24604, 256, 29618, 256, 29801, 256, 32666, 256, 32838, 256, - 37428, 256, 38646, 256, 38728, 256, 38936, 256, 20363, 256, 31150, 256, - 37300, 256, 38584, 256, 24801, 256, 20102, 256, 20698, 256, 23534, 256, - 23615, 256, 26009, 256, 27138, 256, 29134, 256, 30274, 256, 34044, 256, - 36988, 256, 40845, 256, 26248, 256, 38446, 256, 21129, 256, 26491, 256, - 26611, 256, 27969, 256, 28316, 256, 29705, 256, 30041, 256, 30827, 256, - 32016, 256, 39006, 256, 20845, 256, 25134, 256, 38520, 256, 20523, 256, - 23833, 256, 28138, 256, 36650, 256, 24459, 256, 24900, 256, 26647, 256, - 29575, 256, 38534, 256, 21033, 256, 21519, 256, 23653, 256, 26131, 256, + 36040, 256, 28369, 256, 20018, 256, 21477, 256, 40860, 256, 22865, 256, + 37329, 256, 21895, 256, 22856, 256, 25078, 256, 30313, 256, 32645, 256, + 34367, 256, 34746, 256, 35064, 256, 37007, 256, 27138, 256, 27931, 256, + 28889, 256, 29662, 256, 33853, 256, 37226, 256, 39409, 256, 20098, 256, + 21365, 256, 27396, 256, 29211, 256, 34349, 256, 40478, 256, 23888, 256, + 28651, 256, 34253, 256, 35172, 256, 25289, 256, 33240, 256, 34847, 256, + 24266, 256, 26391, 256, 28010, 256, 29436, 256, 37070, 256, 20358, 256, + 20919, 256, 21214, 256, 25796, 256, 27347, 256, 29200, 256, 30439, 256, + 32769, 256, 34310, 256, 34396, 256, 36335, 256, 38706, 256, 39791, 256, + 40442, 256, 30860, 256, 31103, 256, 32160, 256, 33737, 256, 37636, 256, + 40575, 256, 35542, 256, 22751, 256, 24324, 256, 31840, 256, 32894, 256, + 29282, 256, 30922, 256, 36034, 256, 38647, 256, 22744, 256, 23650, 256, + 27155, 256, 28122, 256, 28431, 256, 32047, 256, 32311, 256, 38475, 256, + 21202, 256, 32907, 256, 20956, 256, 20940, 256, 31260, 256, 32190, 256, + 33777, 256, 38517, 256, 35712, 256, 25295, 256, 35582, 256, 20025, 256, + 23527, 256, 24594, 256, 29575, 256, 30064, 256, 21271, 256, 30971, 256, + 20415, 256, 24489, 256, 19981, 256, 27852, 256, 25976, 256, 32034, 256, + 21443, 256, 22622, 256, 30465, 256, 33865, 256, 35498, 256, 27578, 256, + 36784, 256, 27784, 256, 25342, 256, 33509, 256, 25504, 256, 30053, 256, + 20142, 256, 20841, 256, 20937, 256, 26753, 256, 31975, 256, 33391, 256, + 35538, 256, 37327, 256, 21237, 256, 21570, 256, 22899, 256, 24300, 256, + 26053, 256, 28670, 256, 31018, 256, 38317, 256, 39530, 256, 40599, 256, + 40654, 256, 21147, 256, 26310, 256, 27511, 256, 36706, 256, 24180, 256, + 24976, 256, 25088, 256, 25754, 256, 28451, 256, 29001, 256, 29833, 256, + 31178, 256, 32244, 256, 32879, 256, 36646, 256, 34030, 256, 36899, 256, + 37706, 256, 21015, 256, 21155, 256, 21693, 256, 28872, 256, 35010, 256, + 24265, 256, 24565, 256, 25467, 256, 27566, 256, 31806, 256, 29557, 256, + 20196, 256, 22265, 256, 23994, 256, 24604, 256, 29618, 256, 29801, 256, + 32666, 256, 32838, 256, 37428, 256, 38646, 256, 38728, 256, 38936, 256, + 20363, 256, 31150, 256, 37300, 256, 38584, 256, 24801, 256, 20102, 256, + 20698, 256, 23534, 256, 23615, 256, 26009, 256, 29134, 256, 30274, 256, + 34044, 256, 36988, 256, 40845, 256, 26248, 256, 38446, 256, 21129, 256, + 26491, 256, 26611, 256, 27969, 256, 28316, 256, 29705, 256, 30041, 256, + 30827, 256, 32016, 256, 39006, 256, 20845, 256, 25134, 256, 38520, 256, + 20523, 256, 23833, 256, 28138, 256, 36650, 256, 24459, 256, 24900, 256, + 26647, 256, 38534, 256, 21033, 256, 21519, 256, 23653, 256, 26131, 256, 26446, 256, 26792, 256, 27877, 256, 29702, 256, 30178, 256, 32633, 256, 35023, 256, 35041, 256, 37324, 256, 38626, 256, 21311, 256, 28346, 256, 21533, 256, 29136, 256, 29848, 256, 34298, 256, 38563, 256, 40023, 256, @@ -3898,65 +3956,60 @@ static const unsigned int decomp_data[] = { 25935, 256, 26082, 256, 26257, 256, 26757, 256, 28023, 256, 28186, 256, 28450, 256, 29038, 256, 29227, 256, 29730, 256, 30865, 256, 31038, 256, 31049, 256, 31048, 256, 31056, 256, 31062, 256, 31069, 256, 31117, 256, - 31118, 256, 31296, 256, 31361, 256, 31680, 256, 32244, 256, 32265, 256, - 32321, 256, 32626, 256, 32773, 256, 33261, 256, 33401, 256, 33401, 256, - 33879, 256, 35088, 256, 35222, 256, 35585, 256, 35641, 256, 36051, 256, - 36104, 256, 36790, 256, 36920, 256, 38627, 256, 38911, 256, 38971, 256, - 24693, 256, 148206, 256, 33304, 256, 20006, 256, 20917, 256, 20840, 256, - 20352, 256, 20805, 256, 20864, 256, 21191, 256, 21242, 256, 21917, 256, - 21845, 256, 21913, 256, 21986, 256, 22618, 256, 22707, 256, 22852, 256, - 22868, 256, 23138, 256, 23336, 256, 24274, 256, 24281, 256, 24425, 256, - 24493, 256, 24792, 256, 24910, 256, 24840, 256, 24974, 256, 24928, 256, - 25074, 256, 25140, 256, 25540, 256, 25628, 256, 25682, 256, 25942, 256, - 26228, 256, 26391, 256, 26395, 256, 26454, 256, 27513, 256, 27578, 256, - 27969, 256, 28379, 256, 28363, 256, 28450, 256, 28702, 256, 29038, 256, - 30631, 256, 29237, 256, 29359, 256, 29482, 256, 29809, 256, 29958, 256, - 30011, 256, 30237, 256, 30239, 256, 30410, 256, 30427, 256, 30452, 256, - 30538, 256, 30528, 256, 30924, 256, 31409, 256, 31680, 256, 31867, 256, - 32091, 256, 32244, 256, 32574, 256, 32773, 256, 33618, 256, 33775, 256, - 34681, 256, 35137, 256, 35206, 256, 35222, 256, 35519, 256, 35576, 256, - 35531, 256, 35585, 256, 35582, 256, 35565, 256, 35641, 256, 35722, 256, - 36104, 256, 36664, 256, 36978, 256, 37273, 256, 37494, 256, 38524, 256, - 38627, 256, 38742, 256, 38875, 256, 38911, 256, 38923, 256, 38971, 256, - 39698, 256, 40860, 256, 141386, 256, 141380, 256, 144341, 256, 15261, - 256, 16408, 256, 16441, 256, 152137, 256, 154832, 256, 163539, 256, - 40771, 256, 40846, 514, 102, 102, 514, 102, 105, 514, 102, 108, 770, 102, - 102, 105, 770, 102, 102, 108, 514, 383, 116, 514, 115, 116, 514, 1396, - 1398, 514, 1396, 1381, 514, 1396, 1387, 514, 1406, 1398, 514, 1396, 1389, - 512, 1497, 1460, 512, 1522, 1463, 262, 1506, 262, 1488, 262, 1491, 262, - 1492, 262, 1499, 262, 1500, 262, 1501, 262, 1512, 262, 1514, 262, 43, - 512, 1513, 1473, 512, 1513, 1474, 512, 64329, 1473, 512, 64329, 1474, - 512, 1488, 1463, 512, 1488, 1464, 512, 1488, 1468, 512, 1489, 1468, 512, - 1490, 1468, 512, 1491, 1468, 512, 1492, 1468, 512, 1493, 1468, 512, 1494, - 1468, 512, 1496, 1468, 512, 1497, 1468, 512, 1498, 1468, 512, 1499, 1468, - 512, 1500, 1468, 512, 1502, 1468, 512, 1504, 1468, 512, 1505, 1468, 512, - 1507, 1468, 512, 1508, 1468, 512, 1510, 1468, 512, 1511, 1468, 512, 1512, - 1468, 512, 1513, 1468, 512, 1514, 1468, 512, 1493, 1465, 512, 1489, 1471, - 512, 1499, 1471, 512, 1508, 1471, 514, 1488, 1500, 267, 1649, 268, 1649, - 267, 1659, 268, 1659, 269, 1659, 270, 1659, 267, 1662, 268, 1662, 269, - 1662, 270, 1662, 267, 1664, 268, 1664, 269, 1664, 270, 1664, 267, 1658, - 268, 1658, 269, 1658, 270, 1658, 267, 1663, 268, 1663, 269, 1663, 270, - 1663, 267, 1657, 268, 1657, 269, 1657, 270, 1657, 267, 1700, 268, 1700, - 269, 1700, 270, 1700, 267, 1702, 268, 1702, 269, 1702, 270, 1702, 267, - 1668, 268, 1668, 269, 1668, 270, 1668, 267, 1667, 268, 1667, 269, 1667, - 270, 1667, 267, 1670, 268, 1670, 269, 1670, 270, 1670, 267, 1671, 268, - 1671, 269, 1671, 270, 1671, 267, 1677, 268, 1677, 267, 1676, 268, 1676, - 267, 1678, 268, 1678, 267, 1672, 268, 1672, 267, 1688, 268, 1688, 267, - 1681, 268, 1681, 267, 1705, 268, 1705, 269, 1705, 270, 1705, 267, 1711, - 268, 1711, 269, 1711, 270, 1711, 267, 1715, 268, 1715, 269, 1715, 270, - 1715, 267, 1713, 268, 1713, 269, 1713, 270, 1713, 267, 1722, 268, 1722, - 267, 1723, 268, 1723, 269, 1723, 270, 1723, 267, 1728, 268, 1728, 267, - 1729, 268, 1729, 269, 1729, 270, 1729, 267, 1726, 268, 1726, 269, 1726, - 270, 1726, 267, 1746, 268, 1746, 267, 1747, 268, 1747, 267, 1709, 268, - 1709, 269, 1709, 270, 1709, 267, 1735, 268, 1735, 267, 1734, 268, 1734, - 267, 1736, 268, 1736, 267, 1655, 267, 1739, 268, 1739, 267, 1733, 268, - 1733, 267, 1737, 268, 1737, 267, 1744, 268, 1744, 269, 1744, 270, 1744, - 269, 1609, 270, 1609, 523, 1574, 1575, 524, 1574, 1575, 523, 1574, 1749, - 524, 1574, 1749, 523, 1574, 1608, 524, 1574, 1608, 523, 1574, 1735, 524, - 1574, 1735, 523, 1574, 1734, 524, 1574, 1734, 523, 1574, 1736, 524, 1574, - 1736, 523, 1574, 1744, 524, 1574, 1744, 525, 1574, 1744, 523, 1574, 1609, - 524, 1574, 1609, 525, 1574, 1609, 267, 1740, 268, 1740, 269, 1740, 270, - 1740, 523, 1574, 1580, 523, 1574, 1581, 523, 1574, 1605, 523, 1574, 1609, + 31118, 256, 31296, 256, 31361, 256, 31680, 256, 32265, 256, 32321, 256, + 32626, 256, 32773, 256, 33261, 256, 33401, 256, 33879, 256, 35088, 256, + 35222, 256, 35585, 256, 35641, 256, 36051, 256, 36104, 256, 36790, 256, + 38627, 256, 38911, 256, 38971, 256, 24693, 256, 148206, 256, 33304, 256, + 20006, 256, 20917, 256, 20840, 256, 20352, 256, 20805, 256, 20864, 256, + 21191, 256, 21242, 256, 21845, 256, 21913, 256, 21986, 256, 22707, 256, + 22852, 256, 22868, 256, 23138, 256, 23336, 256, 24274, 256, 24281, 256, + 24425, 256, 24493, 256, 24792, 256, 24910, 256, 24840, 256, 24928, 256, + 25140, 256, 25540, 256, 25628, 256, 25682, 256, 25942, 256, 26395, 256, + 26454, 256, 27513, 256, 28379, 256, 28363, 256, 28702, 256, 30631, 256, + 29237, 256, 29359, 256, 29809, 256, 29958, 256, 30011, 256, 30237, 256, + 30239, 256, 30427, 256, 30452, 256, 30538, 256, 30528, 256, 30924, 256, + 31409, 256, 31867, 256, 32091, 256, 32574, 256, 33618, 256, 33775, 256, + 34681, 256, 35137, 256, 35206, 256, 35519, 256, 35531, 256, 35565, 256, + 35722, 256, 36664, 256, 36978, 256, 37273, 256, 37494, 256, 38524, 256, + 38875, 256, 38923, 256, 39698, 256, 141386, 256, 141380, 256, 144341, + 256, 15261, 256, 16408, 256, 16441, 256, 152137, 256, 154832, 256, + 163539, 256, 40771, 256, 40846, 514, 102, 102, 514, 102, 105, 514, 102, + 108, 770, 102, 102, 105, 770, 102, 102, 108, 514, 383, 116, 514, 115, + 116, 514, 1396, 1398, 514, 1396, 1381, 514, 1396, 1387, 514, 1406, 1398, + 514, 1396, 1389, 512, 1497, 1460, 512, 1522, 1463, 262, 1506, 262, 1488, + 262, 1491, 262, 1492, 262, 1499, 262, 1500, 262, 1501, 262, 1512, 262, + 1514, 262, 43, 512, 1513, 1473, 512, 1513, 1474, 512, 64329, 1473, 512, + 64329, 1474, 512, 1488, 1463, 512, 1488, 1464, 512, 1488, 1468, 512, + 1489, 1468, 512, 1490, 1468, 512, 1491, 1468, 512, 1492, 1468, 512, 1493, + 1468, 512, 1494, 1468, 512, 1496, 1468, 512, 1497, 1468, 512, 1498, 1468, + 512, 1499, 1468, 512, 1500, 1468, 512, 1502, 1468, 512, 1504, 1468, 512, + 1505, 1468, 512, 1507, 1468, 512, 1508, 1468, 512, 1510, 1468, 512, 1511, + 1468, 512, 1512, 1468, 512, 1513, 1468, 512, 1514, 1468, 512, 1493, 1465, + 512, 1489, 1471, 512, 1499, 1471, 512, 1508, 1471, 514, 1488, 1500, 267, + 1649, 268, 1649, 267, 1659, 268, 1659, 269, 1659, 270, 1659, 267, 1662, + 268, 1662, 269, 1662, 270, 1662, 267, 1664, 268, 1664, 269, 1664, 270, + 1664, 267, 1658, 268, 1658, 269, 1658, 270, 1658, 267, 1663, 268, 1663, + 269, 1663, 270, 1663, 267, 1657, 268, 1657, 269, 1657, 270, 1657, 267, + 1700, 268, 1700, 269, 1700, 270, 1700, 267, 1702, 268, 1702, 269, 1702, + 270, 1702, 267, 1668, 268, 1668, 269, 1668, 270, 1668, 267, 1667, 268, + 1667, 269, 1667, 270, 1667, 267, 1670, 268, 1670, 269, 1670, 270, 1670, + 267, 1671, 268, 1671, 269, 1671, 270, 1671, 267, 1677, 268, 1677, 267, + 1676, 268, 1676, 267, 1678, 268, 1678, 267, 1672, 268, 1672, 267, 1688, + 268, 1688, 267, 1681, 268, 1681, 267, 1705, 268, 1705, 269, 1705, 270, + 1705, 267, 1711, 268, 1711, 269, 1711, 270, 1711, 267, 1715, 268, 1715, + 269, 1715, 270, 1715, 267, 1713, 268, 1713, 269, 1713, 270, 1713, 267, + 1722, 268, 1722, 267, 1723, 268, 1723, 269, 1723, 270, 1723, 267, 1728, + 268, 1728, 267, 1729, 268, 1729, 269, 1729, 270, 1729, 267, 1726, 268, + 1726, 269, 1726, 270, 1726, 267, 1746, 268, 1746, 267, 1747, 268, 1747, + 267, 1709, 268, 1709, 269, 1709, 270, 1709, 267, 1735, 268, 1735, 267, + 1734, 268, 1734, 267, 1736, 268, 1736, 267, 1655, 267, 1739, 268, 1739, + 267, 1733, 268, 1733, 267, 1737, 268, 1737, 267, 1744, 268, 1744, 269, + 1744, 270, 1744, 269, 1609, 270, 1609, 523, 1574, 1575, 524, 1574, 1575, + 523, 1574, 1749, 524, 1574, 1749, 523, 1574, 1608, 524, 1574, 1608, 523, + 1574, 1735, 524, 1574, 1735, 523, 1574, 1734, 524, 1574, 1734, 523, 1574, + 1736, 524, 1574, 1736, 523, 1574, 1744, 524, 1574, 1744, 525, 1574, 1744, + 523, 1574, 1609, 524, 1574, 1609, 525, 1574, 1609, 267, 1740, 268, 1740, + 269, 1740, 270, 1740, 523, 1574, 1580, 523, 1574, 1581, 523, 1574, 1605, 523, 1574, 1610, 523, 1576, 1580, 523, 1576, 1581, 523, 1576, 1582, 523, 1576, 1605, 523, 1576, 1609, 523, 1576, 1610, 523, 1578, 1580, 523, 1578, 1581, 523, 1578, 1582, 523, 1578, 1605, 523, 1578, 1609, 523, 1578, 1610, @@ -3980,172 +4033,171 @@ static const unsigned int decomp_data[] = { 1610, 523, 1584, 1648, 523, 1585, 1648, 523, 1609, 1648, 779, 32, 1612, 1617, 779, 32, 1613, 1617, 779, 32, 1614, 1617, 779, 32, 1615, 1617, 779, 32, 1616, 1617, 779, 32, 1617, 1648, 524, 1574, 1585, 524, 1574, 1586, - 524, 1574, 1605, 524, 1574, 1606, 524, 1574, 1609, 524, 1574, 1610, 524, - 1576, 1585, 524, 1576, 1586, 524, 1576, 1605, 524, 1576, 1606, 524, 1576, - 1609, 524, 1576, 1610, 524, 1578, 1585, 524, 1578, 1586, 524, 1578, 1605, - 524, 1578, 1606, 524, 1578, 1609, 524, 1578, 1610, 524, 1579, 1585, 524, - 1579, 1586, 524, 1579, 1605, 524, 1579, 1606, 524, 1579, 1609, 524, 1579, - 1610, 524, 1601, 1609, 524, 1601, 1610, 524, 1602, 1609, 524, 1602, 1610, - 524, 1603, 1575, 524, 1603, 1604, 524, 1603, 1605, 524, 1603, 1609, 524, - 1603, 1610, 524, 1604, 1605, 524, 1604, 1609, 524, 1604, 1610, 524, 1605, - 1575, 524, 1605, 1605, 524, 1606, 1585, 524, 1606, 1586, 524, 1606, 1605, - 524, 1606, 1606, 524, 1606, 1609, 524, 1606, 1610, 524, 1609, 1648, 524, - 1610, 1585, 524, 1610, 1586, 524, 1610, 1605, 524, 1610, 1606, 524, 1610, - 1609, 524, 1610, 1610, 525, 1574, 1580, 525, 1574, 1581, 525, 1574, 1582, - 525, 1574, 1605, 525, 1574, 1607, 525, 1576, 1580, 525, 1576, 1581, 525, - 1576, 1582, 525, 1576, 1605, 525, 1576, 1607, 525, 1578, 1580, 525, 1578, - 1581, 525, 1578, 1582, 525, 1578, 1605, 525, 1578, 1607, 525, 1579, 1605, - 525, 1580, 1581, 525, 1580, 1605, 525, 1581, 1580, 525, 1581, 1605, 525, - 1582, 1580, 525, 1582, 1605, 525, 1587, 1580, 525, 1587, 1581, 525, 1587, - 1582, 525, 1587, 1605, 525, 1589, 1581, 525, 1589, 1582, 525, 1589, 1605, - 525, 1590, 1580, 525, 1590, 1581, 525, 1590, 1582, 525, 1590, 1605, 525, - 1591, 1581, 525, 1592, 1605, 525, 1593, 1580, 525, 1593, 1605, 525, 1594, - 1580, 525, 1594, 1605, 525, 1601, 1580, 525, 1601, 1581, 525, 1601, 1582, - 525, 1601, 1605, 525, 1602, 1581, 525, 1602, 1605, 525, 1603, 1580, 525, - 1603, 1581, 525, 1603, 1582, 525, 1603, 1604, 525, 1603, 1605, 525, 1604, - 1580, 525, 1604, 1581, 525, 1604, 1582, 525, 1604, 1605, 525, 1604, 1607, - 525, 1605, 1580, 525, 1605, 1581, 525, 1605, 1582, 525, 1605, 1605, 525, - 1606, 1580, 525, 1606, 1581, 525, 1606, 1582, 525, 1606, 1605, 525, 1606, - 1607, 525, 1607, 1580, 525, 1607, 1605, 525, 1607, 1648, 525, 1610, 1580, - 525, 1610, 1581, 525, 1610, 1582, 525, 1610, 1605, 525, 1610, 1607, 526, - 1574, 1605, 526, 1574, 1607, 526, 1576, 1605, 526, 1576, 1607, 526, 1578, - 1605, 526, 1578, 1607, 526, 1579, 1605, 526, 1579, 1607, 526, 1587, 1605, - 526, 1587, 1607, 526, 1588, 1605, 526, 1588, 1607, 526, 1603, 1604, 526, - 1603, 1605, 526, 1604, 1605, 526, 1606, 1605, 526, 1606, 1607, 526, 1610, - 1605, 526, 1610, 1607, 782, 1600, 1614, 1617, 782, 1600, 1615, 1617, 782, - 1600, 1616, 1617, 523, 1591, 1609, 523, 1591, 1610, 523, 1593, 1609, 523, - 1593, 1610, 523, 1594, 1609, 523, 1594, 1610, 523, 1587, 1609, 523, 1587, - 1610, 523, 1588, 1609, 523, 1588, 1610, 523, 1581, 1609, 523, 1581, 1610, - 523, 1580, 1609, 523, 1580, 1610, 523, 1582, 1609, 523, 1582, 1610, 523, - 1589, 1609, 523, 1589, 1610, 523, 1590, 1609, 523, 1590, 1610, 523, 1588, - 1580, 523, 1588, 1581, 523, 1588, 1582, 523, 1588, 1605, 523, 1588, 1585, - 523, 1587, 1585, 523, 1589, 1585, 523, 1590, 1585, 524, 1591, 1609, 524, - 1591, 1610, 524, 1593, 1609, 524, 1593, 1610, 524, 1594, 1609, 524, 1594, - 1610, 524, 1587, 1609, 524, 1587, 1610, 524, 1588, 1609, 524, 1588, 1610, - 524, 1581, 1609, 524, 1581, 1610, 524, 1580, 1609, 524, 1580, 1610, 524, - 1582, 1609, 524, 1582, 1610, 524, 1589, 1609, 524, 1589, 1610, 524, 1590, - 1609, 524, 1590, 1610, 524, 1588, 1580, 524, 1588, 1581, 524, 1588, 1582, - 524, 1588, 1605, 524, 1588, 1585, 524, 1587, 1585, 524, 1589, 1585, 524, - 1590, 1585, 525, 1588, 1580, 525, 1588, 1581, 525, 1588, 1582, 525, 1588, - 1605, 525, 1587, 1607, 525, 1588, 1607, 525, 1591, 1605, 526, 1587, 1580, - 526, 1587, 1581, 526, 1587, 1582, 526, 1588, 1580, 526, 1588, 1581, 526, - 1588, 1582, 526, 1591, 1605, 526, 1592, 1605, 524, 1575, 1611, 523, 1575, - 1611, 781, 1578, 1580, 1605, 780, 1578, 1581, 1580, 781, 1578, 1581, - 1580, 781, 1578, 1581, 1605, 781, 1578, 1582, 1605, 781, 1578, 1605, - 1580, 781, 1578, 1605, 1581, 781, 1578, 1605, 1582, 780, 1580, 1605, - 1581, 781, 1580, 1605, 1581, 780, 1581, 1605, 1610, 780, 1581, 1605, - 1609, 781, 1587, 1581, 1580, 781, 1587, 1580, 1581, 780, 1587, 1580, - 1609, 780, 1587, 1605, 1581, 781, 1587, 1605, 1581, 781, 1587, 1605, - 1580, 780, 1587, 1605, 1605, 781, 1587, 1605, 1605, 780, 1589, 1581, - 1581, 781, 1589, 1581, 1581, 780, 1589, 1605, 1605, 780, 1588, 1581, - 1605, 781, 1588, 1581, 1605, 780, 1588, 1580, 1610, 780, 1588, 1605, - 1582, 781, 1588, 1605, 1582, 780, 1588, 1605, 1605, 781, 1588, 1605, - 1605, 780, 1590, 1581, 1609, 780, 1590, 1582, 1605, 781, 1590, 1582, - 1605, 780, 1591, 1605, 1581, 781, 1591, 1605, 1581, 781, 1591, 1605, - 1605, 780, 1591, 1605, 1610, 780, 1593, 1580, 1605, 780, 1593, 1605, - 1605, 781, 1593, 1605, 1605, 780, 1593, 1605, 1609, 780, 1594, 1605, - 1605, 780, 1594, 1605, 1610, 780, 1594, 1605, 1609, 780, 1601, 1582, - 1605, 781, 1601, 1582, 1605, 780, 1602, 1605, 1581, 780, 1602, 1605, - 1605, 780, 1604, 1581, 1605, 780, 1604, 1581, 1610, 780, 1604, 1581, - 1609, 781, 1604, 1580, 1580, 780, 1604, 1580, 1580, 780, 1604, 1582, - 1605, 781, 1604, 1582, 1605, 780, 1604, 1605, 1581, 781, 1604, 1605, - 1581, 781, 1605, 1581, 1580, 781, 1605, 1581, 1605, 780, 1605, 1581, - 1610, 781, 1605, 1580, 1581, 781, 1605, 1580, 1605, 781, 1605, 1582, - 1580, 781, 1605, 1582, 1605, 781, 1605, 1580, 1582, 781, 1607, 1605, - 1580, 781, 1607, 1605, 1605, 781, 1606, 1581, 1605, 780, 1606, 1581, - 1609, 780, 1606, 1580, 1605, 781, 1606, 1580, 1605, 780, 1606, 1580, - 1609, 780, 1606, 1605, 1610, 780, 1606, 1605, 1609, 780, 1610, 1605, - 1605, 781, 1610, 1605, 1605, 780, 1576, 1582, 1610, 780, 1578, 1580, - 1610, 780, 1578, 1580, 1609, 780, 1578, 1582, 1610, 780, 1578, 1582, - 1609, 780, 1578, 1605, 1610, 780, 1578, 1605, 1609, 780, 1580, 1605, - 1610, 780, 1580, 1581, 1609, 780, 1580, 1605, 1609, 780, 1587, 1582, - 1609, 780, 1589, 1581, 1610, 780, 1588, 1581, 1610, 780, 1590, 1581, - 1610, 780, 1604, 1580, 1610, 780, 1604, 1605, 1610, 780, 1610, 1581, - 1610, 780, 1610, 1580, 1610, 780, 1610, 1605, 1610, 780, 1605, 1605, - 1610, 780, 1602, 1605, 1610, 780, 1606, 1581, 1610, 781, 1602, 1605, - 1581, 781, 1604, 1581, 1605, 780, 1593, 1605, 1610, 780, 1603, 1605, - 1610, 781, 1606, 1580, 1581, 780, 1605, 1582, 1610, 781, 1604, 1580, - 1605, 780, 1603, 1605, 1605, 780, 1604, 1580, 1605, 780, 1606, 1580, - 1581, 780, 1580, 1581, 1610, 780, 1581, 1580, 1610, 780, 1605, 1580, - 1610, 780, 1601, 1605, 1610, 780, 1576, 1581, 1610, 781, 1603, 1605, - 1605, 781, 1593, 1580, 1605, 781, 1589, 1605, 1605, 780, 1587, 1582, - 1610, 780, 1606, 1580, 1610, 779, 1589, 1604, 1746, 779, 1602, 1604, - 1746, 1035, 1575, 1604, 1604, 1607, 1035, 1575, 1603, 1576, 1585, 1035, - 1605, 1581, 1605, 1583, 1035, 1589, 1604, 1593, 1605, 1035, 1585, 1587, - 1608, 1604, 1035, 1593, 1604, 1610, 1607, 1035, 1608, 1587, 1604, 1605, - 779, 1589, 1604, 1609, 4619, 1589, 1604, 1609, 32, 1575, 1604, 1604, - 1607, 32, 1593, 1604, 1610, 1607, 32, 1608, 1587, 1604, 1605, 2059, 1580, - 1604, 32, 1580, 1604, 1575, 1604, 1607, 1035, 1585, 1740, 1575, 1604, - 265, 44, 265, 12289, 265, 12290, 265, 58, 265, 59, 265, 33, 265, 63, 265, - 12310, 265, 12311, 265, 8230, 265, 8229, 265, 8212, 265, 8211, 265, 95, - 265, 95, 265, 40, 265, 41, 265, 123, 265, 125, 265, 12308, 265, 12309, - 265, 12304, 265, 12305, 265, 12298, 265, 12299, 265, 12296, 265, 12297, - 265, 12300, 265, 12301, 265, 12302, 265, 12303, 265, 91, 265, 93, 258, - 8254, 258, 8254, 258, 8254, 258, 8254, 258, 95, 258, 95, 258, 95, 271, - 44, 271, 12289, 271, 46, 271, 59, 271, 58, 271, 63, 271, 33, 271, 8212, - 271, 40, 271, 41, 271, 123, 271, 125, 271, 12308, 271, 12309, 271, 35, - 271, 38, 271, 42, 271, 43, 271, 45, 271, 60, 271, 62, 271, 61, 271, 92, - 271, 36, 271, 37, 271, 64, 523, 32, 1611, 526, 1600, 1611, 523, 32, 1612, - 523, 32, 1613, 523, 32, 1614, 526, 1600, 1614, 523, 32, 1615, 526, 1600, - 1615, 523, 32, 1616, 526, 1600, 1616, 523, 32, 1617, 526, 1600, 1617, - 523, 32, 1618, 526, 1600, 1618, 267, 1569, 267, 1570, 268, 1570, 267, - 1571, 268, 1571, 267, 1572, 268, 1572, 267, 1573, 268, 1573, 267, 1574, - 268, 1574, 269, 1574, 270, 1574, 267, 1575, 268, 1575, 267, 1576, 268, - 1576, 269, 1576, 270, 1576, 267, 1577, 268, 1577, 267, 1578, 268, 1578, - 269, 1578, 270, 1578, 267, 1579, 268, 1579, 269, 1579, 270, 1579, 267, - 1580, 268, 1580, 269, 1580, 270, 1580, 267, 1581, 268, 1581, 269, 1581, - 270, 1581, 267, 1582, 268, 1582, 269, 1582, 270, 1582, 267, 1583, 268, - 1583, 267, 1584, 268, 1584, 267, 1585, 268, 1585, 267, 1586, 268, 1586, - 267, 1587, 268, 1587, 269, 1587, 270, 1587, 267, 1588, 268, 1588, 269, - 1588, 270, 1588, 267, 1589, 268, 1589, 269, 1589, 270, 1589, 267, 1590, - 268, 1590, 269, 1590, 270, 1590, 267, 1591, 268, 1591, 269, 1591, 270, - 1591, 267, 1592, 268, 1592, 269, 1592, 270, 1592, 267, 1593, 268, 1593, - 269, 1593, 270, 1593, 267, 1594, 268, 1594, 269, 1594, 270, 1594, 267, - 1601, 268, 1601, 269, 1601, 270, 1601, 267, 1602, 268, 1602, 269, 1602, - 270, 1602, 267, 1603, 268, 1603, 269, 1603, 270, 1603, 267, 1604, 268, - 1604, 269, 1604, 270, 1604, 267, 1605, 268, 1605, 269, 1605, 270, 1605, - 267, 1606, 268, 1606, 269, 1606, 270, 1606, 267, 1607, 268, 1607, 269, - 1607, 270, 1607, 267, 1608, 268, 1608, 267, 1609, 268, 1609, 267, 1610, - 268, 1610, 269, 1610, 270, 1610, 523, 1604, 1570, 524, 1604, 1570, 523, - 1604, 1571, 524, 1604, 1571, 523, 1604, 1573, 524, 1604, 1573, 523, 1604, - 1575, 524, 1604, 1575, 264, 33, 264, 34, 264, 35, 264, 36, 264, 37, 264, - 38, 264, 39, 264, 40, 264, 41, 264, 42, 264, 43, 264, 44, 264, 45, 264, - 46, 264, 47, 264, 48, 264, 49, 264, 50, 264, 51, 264, 52, 264, 53, 264, - 54, 264, 55, 264, 56, 264, 57, 264, 58, 264, 59, 264, 60, 264, 61, 264, - 62, 264, 63, 264, 64, 264, 65, 264, 66, 264, 67, 264, 68, 264, 69, 264, - 70, 264, 71, 264, 72, 264, 73, 264, 74, 264, 75, 264, 76, 264, 77, 264, - 78, 264, 79, 264, 80, 264, 81, 264, 82, 264, 83, 264, 84, 264, 85, 264, - 86, 264, 87, 264, 88, 264, 89, 264, 90, 264, 91, 264, 92, 264, 93, 264, - 94, 264, 95, 264, 96, 264, 97, 264, 98, 264, 99, 264, 100, 264, 101, 264, - 102, 264, 103, 264, 104, 264, 105, 264, 106, 264, 107, 264, 108, 264, - 109, 264, 110, 264, 111, 264, 112, 264, 113, 264, 114, 264, 115, 264, - 116, 264, 117, 264, 118, 264, 119, 264, 120, 264, 121, 264, 122, 264, - 123, 264, 124, 264, 125, 264, 126, 264, 10629, 264, 10630, 272, 12290, - 272, 12300, 272, 12301, 272, 12289, 272, 12539, 272, 12530, 272, 12449, - 272, 12451, 272, 12453, 272, 12455, 272, 12457, 272, 12515, 272, 12517, - 272, 12519, 272, 12483, 272, 12540, 272, 12450, 272, 12452, 272, 12454, - 272, 12456, 272, 12458, 272, 12459, 272, 12461, 272, 12463, 272, 12465, - 272, 12467, 272, 12469, 272, 12471, 272, 12473, 272, 12475, 272, 12477, - 272, 12479, 272, 12481, 272, 12484, 272, 12486, 272, 12488, 272, 12490, - 272, 12491, 272, 12492, 272, 12493, 272, 12494, 272, 12495, 272, 12498, - 272, 12501, 272, 12504, 272, 12507, 272, 12510, 272, 12511, 272, 12512, - 272, 12513, 272, 12514, 272, 12516, 272, 12518, 272, 12520, 272, 12521, - 272, 12522, 272, 12523, 272, 12524, 272, 12525, 272, 12527, 272, 12531, - 272, 12441, 272, 12442, 272, 12644, 272, 12593, 272, 12594, 272, 12595, - 272, 12596, 272, 12597, 272, 12598, 272, 12599, 272, 12600, 272, 12601, - 272, 12602, 272, 12603, 272, 12604, 272, 12605, 272, 12606, 272, 12607, - 272, 12608, 272, 12609, 272, 12610, 272, 12611, 272, 12612, 272, 12613, - 272, 12614, 272, 12615, 272, 12616, 272, 12617, 272, 12618, 272, 12619, - 272, 12620, 272, 12621, 272, 12622, 272, 12623, 272, 12624, 272, 12625, - 272, 12626, 272, 12627, 272, 12628, 272, 12629, 272, 12630, 272, 12631, - 272, 12632, 272, 12633, 272, 12634, 272, 12635, 272, 12636, 272, 12637, - 272, 12638, 272, 12639, 272, 12640, 272, 12641, 272, 12642, 272, 12643, - 264, 162, 264, 163, 264, 172, 264, 175, 264, 166, 264, 165, 264, 8361, - 272, 9474, 272, 8592, 272, 8593, 272, 8594, 272, 8595, 272, 9632, 272, - 9675, 259, 720, 259, 721, 259, 230, 259, 665, 259, 595, 259, 675, 259, - 43878, 259, 677, 259, 676, 259, 598, 259, 599, 259, 7569, 259, 600, 259, - 606, 259, 681, 259, 612, 259, 610, 259, 608, 259, 667, 259, 295, 259, - 668, 259, 615, 259, 644, 259, 682, 259, 683, 259, 620, 259, 122628, 259, + 524, 1574, 1605, 524, 1574, 1606, 524, 1574, 1610, 524, 1576, 1585, 524, + 1576, 1586, 524, 1576, 1605, 524, 1576, 1606, 524, 1576, 1609, 524, 1576, + 1610, 524, 1578, 1585, 524, 1578, 1586, 524, 1578, 1605, 524, 1578, 1606, + 524, 1578, 1609, 524, 1578, 1610, 524, 1579, 1585, 524, 1579, 1586, 524, + 1579, 1605, 524, 1579, 1606, 524, 1579, 1609, 524, 1579, 1610, 524, 1601, + 1609, 524, 1601, 1610, 524, 1602, 1609, 524, 1602, 1610, 524, 1603, 1575, + 524, 1603, 1604, 524, 1603, 1605, 524, 1603, 1609, 524, 1603, 1610, 524, + 1604, 1605, 524, 1604, 1609, 524, 1604, 1610, 524, 1605, 1575, 524, 1605, + 1605, 524, 1606, 1585, 524, 1606, 1586, 524, 1606, 1605, 524, 1606, 1606, + 524, 1606, 1609, 524, 1606, 1610, 524, 1609, 1648, 524, 1610, 1585, 524, + 1610, 1586, 524, 1610, 1605, 524, 1610, 1606, 524, 1610, 1609, 524, 1610, + 1610, 525, 1574, 1580, 525, 1574, 1581, 525, 1574, 1582, 525, 1574, 1605, + 525, 1574, 1607, 525, 1576, 1580, 525, 1576, 1581, 525, 1576, 1582, 525, + 1576, 1605, 525, 1576, 1607, 525, 1578, 1580, 525, 1578, 1581, 525, 1578, + 1582, 525, 1578, 1605, 525, 1578, 1607, 525, 1579, 1605, 525, 1580, 1581, + 525, 1580, 1605, 525, 1581, 1580, 525, 1581, 1605, 525, 1582, 1580, 525, + 1582, 1605, 525, 1587, 1580, 525, 1587, 1581, 525, 1587, 1582, 525, 1587, + 1605, 525, 1589, 1581, 525, 1589, 1582, 525, 1589, 1605, 525, 1590, 1580, + 525, 1590, 1581, 525, 1590, 1582, 525, 1590, 1605, 525, 1591, 1581, 525, + 1592, 1605, 525, 1593, 1580, 525, 1593, 1605, 525, 1594, 1580, 525, 1594, + 1605, 525, 1601, 1580, 525, 1601, 1581, 525, 1601, 1582, 525, 1601, 1605, + 525, 1602, 1581, 525, 1602, 1605, 525, 1603, 1580, 525, 1603, 1581, 525, + 1603, 1582, 525, 1603, 1604, 525, 1603, 1605, 525, 1604, 1580, 525, 1604, + 1581, 525, 1604, 1582, 525, 1604, 1605, 525, 1604, 1607, 525, 1605, 1580, + 525, 1605, 1581, 525, 1605, 1582, 525, 1605, 1605, 525, 1606, 1580, 525, + 1606, 1581, 525, 1606, 1582, 525, 1606, 1605, 525, 1606, 1607, 525, 1607, + 1580, 525, 1607, 1605, 525, 1607, 1648, 525, 1610, 1580, 525, 1610, 1581, + 525, 1610, 1582, 525, 1610, 1605, 525, 1610, 1607, 526, 1574, 1605, 526, + 1574, 1607, 526, 1576, 1605, 526, 1576, 1607, 526, 1578, 1605, 526, 1578, + 1607, 526, 1579, 1605, 526, 1579, 1607, 526, 1587, 1605, 526, 1587, 1607, + 526, 1588, 1605, 526, 1588, 1607, 526, 1603, 1604, 526, 1603, 1605, 526, + 1604, 1605, 526, 1606, 1605, 526, 1606, 1607, 526, 1610, 1605, 526, 1610, + 1607, 782, 1600, 1614, 1617, 782, 1600, 1615, 1617, 782, 1600, 1616, + 1617, 523, 1591, 1609, 523, 1591, 1610, 523, 1593, 1609, 523, 1593, 1610, + 523, 1594, 1609, 523, 1594, 1610, 523, 1587, 1609, 523, 1587, 1610, 523, + 1588, 1609, 523, 1588, 1610, 523, 1581, 1609, 523, 1581, 1610, 523, 1580, + 1609, 523, 1580, 1610, 523, 1582, 1609, 523, 1582, 1610, 523, 1589, 1609, + 523, 1589, 1610, 523, 1590, 1609, 523, 1590, 1610, 523, 1588, 1580, 523, + 1588, 1581, 523, 1588, 1582, 523, 1588, 1605, 523, 1588, 1585, 523, 1587, + 1585, 523, 1589, 1585, 523, 1590, 1585, 524, 1591, 1609, 524, 1591, 1610, + 524, 1593, 1609, 524, 1593, 1610, 524, 1594, 1609, 524, 1594, 1610, 524, + 1587, 1609, 524, 1587, 1610, 524, 1588, 1609, 524, 1588, 1610, 524, 1581, + 1609, 524, 1581, 1610, 524, 1580, 1609, 524, 1580, 1610, 524, 1582, 1609, + 524, 1582, 1610, 524, 1589, 1609, 524, 1589, 1610, 524, 1590, 1609, 524, + 1590, 1610, 524, 1588, 1580, 524, 1588, 1581, 524, 1588, 1582, 524, 1588, + 1605, 524, 1588, 1585, 524, 1587, 1585, 524, 1589, 1585, 524, 1590, 1585, + 525, 1588, 1580, 525, 1588, 1581, 525, 1588, 1582, 525, 1588, 1605, 525, + 1587, 1607, 525, 1588, 1607, 525, 1591, 1605, 526, 1587, 1580, 526, 1587, + 1581, 526, 1587, 1582, 526, 1588, 1580, 526, 1588, 1581, 526, 1588, 1582, + 526, 1591, 1605, 526, 1592, 1605, 524, 1575, 1611, 523, 1575, 1611, 781, + 1578, 1580, 1605, 780, 1578, 1581, 1580, 781, 1578, 1581, 1580, 781, + 1578, 1581, 1605, 781, 1578, 1582, 1605, 781, 1578, 1605, 1580, 781, + 1578, 1605, 1581, 781, 1578, 1605, 1582, 780, 1580, 1605, 1581, 781, + 1580, 1605, 1581, 780, 1581, 1605, 1610, 780, 1581, 1605, 1609, 781, + 1587, 1581, 1580, 781, 1587, 1580, 1581, 780, 1587, 1580, 1609, 780, + 1587, 1605, 1581, 781, 1587, 1605, 1581, 781, 1587, 1605, 1580, 780, + 1587, 1605, 1605, 781, 1587, 1605, 1605, 780, 1589, 1581, 1581, 781, + 1589, 1581, 1581, 780, 1589, 1605, 1605, 780, 1588, 1581, 1605, 781, + 1588, 1581, 1605, 780, 1588, 1580, 1610, 780, 1588, 1605, 1582, 781, + 1588, 1605, 1582, 780, 1588, 1605, 1605, 781, 1588, 1605, 1605, 780, + 1590, 1581, 1609, 780, 1590, 1582, 1605, 781, 1590, 1582, 1605, 780, + 1591, 1605, 1581, 781, 1591, 1605, 1581, 781, 1591, 1605, 1605, 780, + 1591, 1605, 1610, 780, 1593, 1580, 1605, 780, 1593, 1605, 1605, 781, + 1593, 1605, 1605, 780, 1593, 1605, 1609, 780, 1594, 1605, 1605, 780, + 1594, 1605, 1610, 780, 1594, 1605, 1609, 780, 1601, 1582, 1605, 781, + 1601, 1582, 1605, 780, 1602, 1605, 1581, 780, 1602, 1605, 1605, 780, + 1604, 1581, 1605, 780, 1604, 1581, 1610, 780, 1604, 1581, 1609, 781, + 1604, 1580, 1580, 780, 1604, 1580, 1580, 780, 1604, 1582, 1605, 781, + 1604, 1582, 1605, 780, 1604, 1605, 1581, 781, 1604, 1605, 1581, 781, + 1605, 1581, 1580, 781, 1605, 1581, 1605, 780, 1605, 1581, 1610, 781, + 1605, 1580, 1581, 781, 1605, 1580, 1605, 781, 1605, 1582, 1580, 781, + 1605, 1582, 1605, 781, 1605, 1580, 1582, 781, 1607, 1605, 1580, 781, + 1607, 1605, 1605, 781, 1606, 1581, 1605, 780, 1606, 1581, 1609, 780, + 1606, 1580, 1605, 781, 1606, 1580, 1605, 780, 1606, 1580, 1609, 780, + 1606, 1605, 1610, 780, 1606, 1605, 1609, 780, 1610, 1605, 1605, 781, + 1610, 1605, 1605, 780, 1576, 1582, 1610, 780, 1578, 1580, 1610, 780, + 1578, 1580, 1609, 780, 1578, 1582, 1610, 780, 1578, 1582, 1609, 780, + 1578, 1605, 1610, 780, 1578, 1605, 1609, 780, 1580, 1605, 1610, 780, + 1580, 1581, 1609, 780, 1580, 1605, 1609, 780, 1587, 1582, 1609, 780, + 1589, 1581, 1610, 780, 1588, 1581, 1610, 780, 1590, 1581, 1610, 780, + 1604, 1580, 1610, 780, 1604, 1605, 1610, 780, 1610, 1581, 1610, 780, + 1610, 1580, 1610, 780, 1610, 1605, 1610, 780, 1605, 1605, 1610, 780, + 1602, 1605, 1610, 780, 1606, 1581, 1610, 781, 1602, 1605, 1581, 781, + 1604, 1581, 1605, 780, 1593, 1605, 1610, 780, 1603, 1605, 1610, 781, + 1606, 1580, 1581, 780, 1605, 1582, 1610, 781, 1604, 1580, 1605, 780, + 1603, 1605, 1605, 780, 1604, 1580, 1605, 780, 1606, 1580, 1581, 780, + 1580, 1581, 1610, 780, 1581, 1580, 1610, 780, 1605, 1580, 1610, 780, + 1601, 1605, 1610, 780, 1576, 1581, 1610, 781, 1603, 1605, 1605, 781, + 1593, 1580, 1605, 781, 1589, 1605, 1605, 780, 1587, 1582, 1610, 780, + 1606, 1580, 1610, 779, 1589, 1604, 1746, 779, 1602, 1604, 1746, 1035, + 1575, 1604, 1604, 1607, 1035, 1575, 1603, 1576, 1585, 1035, 1605, 1581, + 1605, 1583, 1035, 1589, 1604, 1593, 1605, 1035, 1585, 1587, 1608, 1604, + 1035, 1593, 1604, 1610, 1607, 1035, 1608, 1587, 1604, 1605, 779, 1589, + 1604, 1609, 4619, 1589, 1604, 1609, 32, 1575, 1604, 1604, 1607, 32, 1593, + 1604, 1610, 1607, 32, 1608, 1587, 1604, 1605, 2059, 1580, 1604, 32, 1580, + 1604, 1575, 1604, 1607, 1035, 1585, 1740, 1575, 1604, 265, 44, 265, + 12289, 265, 12290, 265, 58, 265, 59, 265, 33, 265, 63, 265, 12310, 265, + 12311, 265, 8230, 265, 8229, 265, 8212, 265, 8211, 265, 95, 265, 40, 265, + 41, 265, 123, 265, 125, 265, 12308, 265, 12309, 265, 12304, 265, 12305, + 265, 12298, 265, 12299, 265, 12296, 265, 12297, 265, 12300, 265, 12301, + 265, 12302, 265, 12303, 265, 91, 265, 93, 258, 8254, 258, 95, 271, 44, + 271, 12289, 271, 46, 271, 59, 271, 58, 271, 63, 271, 33, 271, 8212, 271, + 40, 271, 41, 271, 123, 271, 125, 271, 12308, 271, 12309, 271, 35, 271, + 38, 271, 42, 271, 43, 271, 45, 271, 60, 271, 62, 271, 61, 271, 92, 271, + 36, 271, 37, 271, 64, 523, 32, 1611, 526, 1600, 1611, 523, 32, 1612, 523, + 32, 1613, 523, 32, 1614, 526, 1600, 1614, 523, 32, 1615, 526, 1600, 1615, + 523, 32, 1616, 526, 1600, 1616, 523, 32, 1617, 526, 1600, 1617, 523, 32, + 1618, 526, 1600, 1618, 267, 1569, 267, 1570, 268, 1570, 267, 1571, 268, + 1571, 267, 1572, 268, 1572, 267, 1573, 268, 1573, 267, 1574, 268, 1574, + 269, 1574, 270, 1574, 267, 1575, 268, 1575, 267, 1576, 268, 1576, 269, + 1576, 270, 1576, 267, 1577, 268, 1577, 267, 1578, 268, 1578, 269, 1578, + 270, 1578, 267, 1579, 268, 1579, 269, 1579, 270, 1579, 267, 1580, 268, + 1580, 269, 1580, 270, 1580, 267, 1581, 268, 1581, 269, 1581, 270, 1581, + 267, 1582, 268, 1582, 269, 1582, 270, 1582, 267, 1583, 268, 1583, 267, + 1584, 268, 1584, 267, 1585, 268, 1585, 267, 1586, 268, 1586, 267, 1587, + 268, 1587, 269, 1587, 270, 1587, 267, 1588, 268, 1588, 269, 1588, 270, + 1588, 267, 1589, 268, 1589, 269, 1589, 270, 1589, 267, 1590, 268, 1590, + 269, 1590, 270, 1590, 267, 1591, 268, 1591, 269, 1591, 270, 1591, 267, + 1592, 268, 1592, 269, 1592, 270, 1592, 267, 1593, 268, 1593, 269, 1593, + 270, 1593, 267, 1594, 268, 1594, 269, 1594, 270, 1594, 267, 1601, 268, + 1601, 269, 1601, 270, 1601, 267, 1602, 268, 1602, 269, 1602, 270, 1602, + 267, 1603, 268, 1603, 269, 1603, 270, 1603, 267, 1604, 268, 1604, 269, + 1604, 270, 1604, 267, 1605, 268, 1605, 269, 1605, 270, 1605, 267, 1606, + 268, 1606, 269, 1606, 270, 1606, 267, 1607, 268, 1607, 269, 1607, 270, + 1607, 267, 1608, 268, 1608, 267, 1609, 268, 1609, 267, 1610, 268, 1610, + 269, 1610, 270, 1610, 523, 1604, 1570, 524, 1604, 1570, 523, 1604, 1571, + 524, 1604, 1571, 523, 1604, 1573, 524, 1604, 1573, 523, 1604, 1575, 524, + 1604, 1575, 264, 33, 264, 34, 264, 35, 264, 36, 264, 37, 264, 38, 264, + 39, 264, 40, 264, 41, 264, 42, 264, 43, 264, 44, 264, 45, 264, 46, 264, + 47, 264, 48, 264, 49, 264, 50, 264, 51, 264, 52, 264, 53, 264, 54, 264, + 55, 264, 56, 264, 57, 264, 58, 264, 59, 264, 60, 264, 61, 264, 62, 264, + 63, 264, 64, 264, 65, 264, 66, 264, 67, 264, 68, 264, 69, 264, 70, 264, + 71, 264, 72, 264, 73, 264, 74, 264, 75, 264, 76, 264, 77, 264, 78, 264, + 79, 264, 80, 264, 81, 264, 82, 264, 83, 264, 84, 264, 85, 264, 86, 264, + 87, 264, 88, 264, 89, 264, 90, 264, 91, 264, 92, 264, 93, 264, 94, 264, + 95, 264, 96, 264, 97, 264, 98, 264, 99, 264, 100, 264, 101, 264, 102, + 264, 103, 264, 104, 264, 105, 264, 106, 264, 107, 264, 108, 264, 109, + 264, 110, 264, 111, 264, 112, 264, 113, 264, 114, 264, 115, 264, 116, + 264, 117, 264, 118, 264, 119, 264, 120, 264, 121, 264, 122, 264, 123, + 264, 124, 264, 125, 264, 126, 264, 10629, 264, 10630, 272, 12290, 272, + 12300, 272, 12301, 272, 12289, 272, 12539, 272, 12530, 272, 12449, 272, + 12451, 272, 12453, 272, 12455, 272, 12457, 272, 12515, 272, 12517, 272, + 12519, 272, 12483, 272, 12540, 272, 12450, 272, 12452, 272, 12454, 272, + 12456, 272, 12458, 272, 12459, 272, 12461, 272, 12463, 272, 12465, 272, + 12467, 272, 12469, 272, 12471, 272, 12473, 272, 12475, 272, 12477, 272, + 12479, 272, 12481, 272, 12484, 272, 12486, 272, 12488, 272, 12490, 272, + 12491, 272, 12492, 272, 12493, 272, 12494, 272, 12495, 272, 12498, 272, + 12501, 272, 12504, 272, 12507, 272, 12510, 272, 12511, 272, 12512, 272, + 12513, 272, 12514, 272, 12516, 272, 12518, 272, 12520, 272, 12521, 272, + 12522, 272, 12523, 272, 12524, 272, 12525, 272, 12527, 272, 12531, 272, + 12441, 272, 12442, 272, 12644, 272, 12593, 272, 12594, 272, 12595, 272, + 12596, 272, 12597, 272, 12598, 272, 12599, 272, 12600, 272, 12601, 272, + 12602, 272, 12603, 272, 12604, 272, 12605, 272, 12606, 272, 12607, 272, + 12608, 272, 12609, 272, 12610, 272, 12611, 272, 12612, 272, 12613, 272, + 12614, 272, 12615, 272, 12616, 272, 12617, 272, 12618, 272, 12619, 272, + 12620, 272, 12621, 272, 12622, 272, 12623, 272, 12624, 272, 12625, 272, + 12626, 272, 12627, 272, 12628, 272, 12629, 272, 12630, 272, 12631, 272, + 12632, 272, 12633, 272, 12634, 272, 12635, 272, 12636, 272, 12637, 272, + 12638, 272, 12639, 272, 12640, 272, 12641, 272, 12642, 272, 12643, 264, + 162, 264, 163, 264, 172, 264, 175, 264, 166, 264, 165, 264, 8361, 272, + 9474, 272, 8592, 272, 8593, 272, 8594, 272, 8595, 272, 9632, 272, 9675, + 259, 720, 259, 721, 259, 230, 259, 665, 259, 595, 259, 675, 259, 43878, + 259, 677, 259, 676, 259, 598, 259, 599, 259, 7569, 259, 600, 259, 606, + 259, 681, 259, 612, 259, 610, 259, 608, 259, 667, 259, 295, 259, 668, + 259, 615, 259, 644, 259, 682, 259, 683, 259, 620, 259, 122628, 259, 42894, 259, 622, 259, 122629, 259, 654, 259, 122630, 259, 248, 259, 630, 259, 631, 259, 113, 259, 634, 259, 122632, 259, 637, 259, 638, 259, 640, 259, 680, 259, 678, 259, 43879, 259, 679, 259, 648, 259, 11377, 259, 655, @@ -4157,281 +4209,141 @@ static const unsigned int decomp_data[] = { 512, 119128, 119141, 512, 119135, 119150, 512, 119135, 119151, 512, 119135, 119152, 512, 119135, 119153, 512, 119135, 119154, 512, 119225, 119141, 512, 119226, 119141, 512, 119227, 119150, 512, 119228, 119150, - 512, 119227, 119151, 512, 119228, 119151, 262, 65, 262, 66, 262, 67, 262, - 68, 262, 69, 262, 70, 262, 71, 262, 72, 262, 73, 262, 74, 262, 75, 262, - 76, 262, 77, 262, 78, 262, 79, 262, 80, 262, 81, 262, 82, 262, 83, 262, - 84, 262, 85, 262, 86, 262, 87, 262, 88, 262, 89, 262, 90, 262, 97, 262, - 98, 262, 99, 262, 100, 262, 101, 262, 102, 262, 103, 262, 104, 262, 105, - 262, 106, 262, 107, 262, 108, 262, 109, 262, 110, 262, 111, 262, 112, - 262, 113, 262, 114, 262, 115, 262, 116, 262, 117, 262, 118, 262, 119, - 262, 120, 262, 121, 262, 122, 262, 65, 262, 66, 262, 67, 262, 68, 262, - 69, 262, 70, 262, 71, 262, 72, 262, 73, 262, 74, 262, 75, 262, 76, 262, - 77, 262, 78, 262, 79, 262, 80, 262, 81, 262, 82, 262, 83, 262, 84, 262, - 85, 262, 86, 262, 87, 262, 88, 262, 89, 262, 90, 262, 97, 262, 98, 262, - 99, 262, 100, 262, 101, 262, 102, 262, 103, 262, 105, 262, 106, 262, 107, - 262, 108, 262, 109, 262, 110, 262, 111, 262, 112, 262, 113, 262, 114, - 262, 115, 262, 116, 262, 117, 262, 118, 262, 119, 262, 120, 262, 121, - 262, 122, 262, 65, 262, 66, 262, 67, 262, 68, 262, 69, 262, 70, 262, 71, - 262, 72, 262, 73, 262, 74, 262, 75, 262, 76, 262, 77, 262, 78, 262, 79, - 262, 80, 262, 81, 262, 82, 262, 83, 262, 84, 262, 85, 262, 86, 262, 87, - 262, 88, 262, 89, 262, 90, 262, 97, 262, 98, 262, 99, 262, 100, 262, 101, - 262, 102, 262, 103, 262, 104, 262, 105, 262, 106, 262, 107, 262, 108, - 262, 109, 262, 110, 262, 111, 262, 112, 262, 113, 262, 114, 262, 115, - 262, 116, 262, 117, 262, 118, 262, 119, 262, 120, 262, 121, 262, 122, - 262, 65, 262, 67, 262, 68, 262, 71, 262, 74, 262, 75, 262, 78, 262, 79, - 262, 80, 262, 81, 262, 83, 262, 84, 262, 85, 262, 86, 262, 87, 262, 88, - 262, 89, 262, 90, 262, 97, 262, 98, 262, 99, 262, 100, 262, 102, 262, - 104, 262, 105, 262, 106, 262, 107, 262, 108, 262, 109, 262, 110, 262, - 112, 262, 113, 262, 114, 262, 115, 262, 116, 262, 117, 262, 118, 262, - 119, 262, 120, 262, 121, 262, 122, 262, 65, 262, 66, 262, 67, 262, 68, - 262, 69, 262, 70, 262, 71, 262, 72, 262, 73, 262, 74, 262, 75, 262, 76, - 262, 77, 262, 78, 262, 79, 262, 80, 262, 81, 262, 82, 262, 83, 262, 84, - 262, 85, 262, 86, 262, 87, 262, 88, 262, 89, 262, 90, 262, 97, 262, 98, - 262, 99, 262, 100, 262, 101, 262, 102, 262, 103, 262, 104, 262, 105, 262, - 106, 262, 107, 262, 108, 262, 109, 262, 110, 262, 111, 262, 112, 262, - 113, 262, 114, 262, 115, 262, 116, 262, 117, 262, 118, 262, 119, 262, - 120, 262, 121, 262, 122, 262, 65, 262, 66, 262, 68, 262, 69, 262, 70, - 262, 71, 262, 74, 262, 75, 262, 76, 262, 77, 262, 78, 262, 79, 262, 80, - 262, 81, 262, 83, 262, 84, 262, 85, 262, 86, 262, 87, 262, 88, 262, 89, - 262, 97, 262, 98, 262, 99, 262, 100, 262, 101, 262, 102, 262, 103, 262, - 104, 262, 105, 262, 106, 262, 107, 262, 108, 262, 109, 262, 110, 262, - 111, 262, 112, 262, 113, 262, 114, 262, 115, 262, 116, 262, 117, 262, - 118, 262, 119, 262, 120, 262, 121, 262, 122, 262, 65, 262, 66, 262, 68, - 262, 69, 262, 70, 262, 71, 262, 73, 262, 74, 262, 75, 262, 76, 262, 77, - 262, 79, 262, 83, 262, 84, 262, 85, 262, 86, 262, 87, 262, 88, 262, 89, - 262, 97, 262, 98, 262, 99, 262, 100, 262, 101, 262, 102, 262, 103, 262, - 104, 262, 105, 262, 106, 262, 107, 262, 108, 262, 109, 262, 110, 262, - 111, 262, 112, 262, 113, 262, 114, 262, 115, 262, 116, 262, 117, 262, - 118, 262, 119, 262, 120, 262, 121, 262, 122, 262, 65, 262, 66, 262, 67, - 262, 68, 262, 69, 262, 70, 262, 71, 262, 72, 262, 73, 262, 74, 262, 75, - 262, 76, 262, 77, 262, 78, 262, 79, 262, 80, 262, 81, 262, 82, 262, 83, - 262, 84, 262, 85, 262, 86, 262, 87, 262, 88, 262, 89, 262, 90, 262, 97, - 262, 98, 262, 99, 262, 100, 262, 101, 262, 102, 262, 103, 262, 104, 262, - 105, 262, 106, 262, 107, 262, 108, 262, 109, 262, 110, 262, 111, 262, - 112, 262, 113, 262, 114, 262, 115, 262, 116, 262, 117, 262, 118, 262, - 119, 262, 120, 262, 121, 262, 122, 262, 65, 262, 66, 262, 67, 262, 68, - 262, 69, 262, 70, 262, 71, 262, 72, 262, 73, 262, 74, 262, 75, 262, 76, - 262, 77, 262, 78, 262, 79, 262, 80, 262, 81, 262, 82, 262, 83, 262, 84, - 262, 85, 262, 86, 262, 87, 262, 88, 262, 89, 262, 90, 262, 97, 262, 98, - 262, 99, 262, 100, 262, 101, 262, 102, 262, 103, 262, 104, 262, 105, 262, - 106, 262, 107, 262, 108, 262, 109, 262, 110, 262, 111, 262, 112, 262, - 113, 262, 114, 262, 115, 262, 116, 262, 117, 262, 118, 262, 119, 262, - 120, 262, 121, 262, 122, 262, 65, 262, 66, 262, 67, 262, 68, 262, 69, - 262, 70, 262, 71, 262, 72, 262, 73, 262, 74, 262, 75, 262, 76, 262, 77, - 262, 78, 262, 79, 262, 80, 262, 81, 262, 82, 262, 83, 262, 84, 262, 85, - 262, 86, 262, 87, 262, 88, 262, 89, 262, 90, 262, 97, 262, 98, 262, 99, - 262, 100, 262, 101, 262, 102, 262, 103, 262, 104, 262, 105, 262, 106, - 262, 107, 262, 108, 262, 109, 262, 110, 262, 111, 262, 112, 262, 113, - 262, 114, 262, 115, 262, 116, 262, 117, 262, 118, 262, 119, 262, 120, - 262, 121, 262, 122, 262, 65, 262, 66, 262, 67, 262, 68, 262, 69, 262, 70, - 262, 71, 262, 72, 262, 73, 262, 74, 262, 75, 262, 76, 262, 77, 262, 78, - 262, 79, 262, 80, 262, 81, 262, 82, 262, 83, 262, 84, 262, 85, 262, 86, - 262, 87, 262, 88, 262, 89, 262, 90, 262, 97, 262, 98, 262, 99, 262, 100, - 262, 101, 262, 102, 262, 103, 262, 104, 262, 105, 262, 106, 262, 107, - 262, 108, 262, 109, 262, 110, 262, 111, 262, 112, 262, 113, 262, 114, - 262, 115, 262, 116, 262, 117, 262, 118, 262, 119, 262, 120, 262, 121, - 262, 122, 262, 65, 262, 66, 262, 67, 262, 68, 262, 69, 262, 70, 262, 71, - 262, 72, 262, 73, 262, 74, 262, 75, 262, 76, 262, 77, 262, 78, 262, 79, - 262, 80, 262, 81, 262, 82, 262, 83, 262, 84, 262, 85, 262, 86, 262, 87, - 262, 88, 262, 89, 262, 90, 262, 97, 262, 98, 262, 99, 262, 100, 262, 101, - 262, 102, 262, 103, 262, 104, 262, 105, 262, 106, 262, 107, 262, 108, - 262, 109, 262, 110, 262, 111, 262, 112, 262, 113, 262, 114, 262, 115, - 262, 116, 262, 117, 262, 118, 262, 119, 262, 120, 262, 121, 262, 122, - 262, 65, 262, 66, 262, 67, 262, 68, 262, 69, 262, 70, 262, 71, 262, 72, - 262, 73, 262, 74, 262, 75, 262, 76, 262, 77, 262, 78, 262, 79, 262, 80, - 262, 81, 262, 82, 262, 83, 262, 84, 262, 85, 262, 86, 262, 87, 262, 88, - 262, 89, 262, 90, 262, 97, 262, 98, 262, 99, 262, 100, 262, 101, 262, - 102, 262, 103, 262, 104, 262, 105, 262, 106, 262, 107, 262, 108, 262, - 109, 262, 110, 262, 111, 262, 112, 262, 113, 262, 114, 262, 115, 262, - 116, 262, 117, 262, 118, 262, 119, 262, 120, 262, 121, 262, 122, 262, - 305, 262, 567, 262, 913, 262, 914, 262, 915, 262, 916, 262, 917, 262, - 918, 262, 919, 262, 920, 262, 921, 262, 922, 262, 923, 262, 924, 262, - 925, 262, 926, 262, 927, 262, 928, 262, 929, 262, 1012, 262, 931, 262, - 932, 262, 933, 262, 934, 262, 935, 262, 936, 262, 937, 262, 8711, 262, - 945, 262, 946, 262, 947, 262, 948, 262, 949, 262, 950, 262, 951, 262, - 952, 262, 953, 262, 954, 262, 955, 262, 956, 262, 957, 262, 958, 262, - 959, 262, 960, 262, 961, 262, 962, 262, 963, 262, 964, 262, 965, 262, - 966, 262, 967, 262, 968, 262, 969, 262, 8706, 262, 1013, 262, 977, 262, - 1008, 262, 981, 262, 1009, 262, 982, 262, 913, 262, 914, 262, 915, 262, - 916, 262, 917, 262, 918, 262, 919, 262, 920, 262, 921, 262, 922, 262, - 923, 262, 924, 262, 925, 262, 926, 262, 927, 262, 928, 262, 929, 262, - 1012, 262, 931, 262, 932, 262, 933, 262, 934, 262, 935, 262, 936, 262, - 937, 262, 8711, 262, 945, 262, 946, 262, 947, 262, 948, 262, 949, 262, - 950, 262, 951, 262, 952, 262, 953, 262, 954, 262, 955, 262, 956, 262, - 957, 262, 958, 262, 959, 262, 960, 262, 961, 262, 962, 262, 963, 262, - 964, 262, 965, 262, 966, 262, 967, 262, 968, 262, 969, 262, 8706, 262, - 1013, 262, 977, 262, 1008, 262, 981, 262, 1009, 262, 982, 262, 913, 262, - 914, 262, 915, 262, 916, 262, 917, 262, 918, 262, 919, 262, 920, 262, - 921, 262, 922, 262, 923, 262, 924, 262, 925, 262, 926, 262, 927, 262, - 928, 262, 929, 262, 1012, 262, 931, 262, 932, 262, 933, 262, 934, 262, - 935, 262, 936, 262, 937, 262, 8711, 262, 945, 262, 946, 262, 947, 262, - 948, 262, 949, 262, 950, 262, 951, 262, 952, 262, 953, 262, 954, 262, - 955, 262, 956, 262, 957, 262, 958, 262, 959, 262, 960, 262, 961, 262, - 962, 262, 963, 262, 964, 262, 965, 262, 966, 262, 967, 262, 968, 262, - 969, 262, 8706, 262, 1013, 262, 977, 262, 1008, 262, 981, 262, 1009, 262, - 982, 262, 913, 262, 914, 262, 915, 262, 916, 262, 917, 262, 918, 262, - 919, 262, 920, 262, 921, 262, 922, 262, 923, 262, 924, 262, 925, 262, - 926, 262, 927, 262, 928, 262, 929, 262, 1012, 262, 931, 262, 932, 262, - 933, 262, 934, 262, 935, 262, 936, 262, 937, 262, 8711, 262, 945, 262, - 946, 262, 947, 262, 948, 262, 949, 262, 950, 262, 951, 262, 952, 262, - 953, 262, 954, 262, 955, 262, 956, 262, 957, 262, 958, 262, 959, 262, - 960, 262, 961, 262, 962, 262, 963, 262, 964, 262, 965, 262, 966, 262, - 967, 262, 968, 262, 969, 262, 8706, 262, 1013, 262, 977, 262, 1008, 262, - 981, 262, 1009, 262, 982, 262, 913, 262, 914, 262, 915, 262, 916, 262, - 917, 262, 918, 262, 919, 262, 920, 262, 921, 262, 922, 262, 923, 262, - 924, 262, 925, 262, 926, 262, 927, 262, 928, 262, 929, 262, 1012, 262, - 931, 262, 932, 262, 933, 262, 934, 262, 935, 262, 936, 262, 937, 262, - 8711, 262, 945, 262, 946, 262, 947, 262, 948, 262, 949, 262, 950, 262, - 951, 262, 952, 262, 953, 262, 954, 262, 955, 262, 956, 262, 957, 262, - 958, 262, 959, 262, 960, 262, 961, 262, 962, 262, 963, 262, 964, 262, - 965, 262, 966, 262, 967, 262, 968, 262, 969, 262, 8706, 262, 1013, 262, - 977, 262, 1008, 262, 981, 262, 1009, 262, 982, 262, 988, 262, 989, 262, - 48, 262, 49, 262, 50, 262, 51, 262, 52, 262, 53, 262, 54, 262, 55, 262, - 56, 262, 57, 262, 48, 262, 49, 262, 50, 262, 51, 262, 52, 262, 53, 262, - 54, 262, 55, 262, 56, 262, 57, 262, 48, 262, 49, 262, 50, 262, 51, 262, - 52, 262, 53, 262, 54, 262, 55, 262, 56, 262, 57, 262, 48, 262, 49, 262, - 50, 262, 51, 262, 52, 262, 53, 262, 54, 262, 55, 262, 56, 262, 57, 262, - 48, 262, 49, 262, 50, 262, 51, 262, 52, 262, 53, 262, 54, 262, 55, 262, - 56, 262, 57, 262, 1575, 262, 1576, 262, 1580, 262, 1583, 262, 1608, 262, - 1586, 262, 1581, 262, 1591, 262, 1610, 262, 1603, 262, 1604, 262, 1605, - 262, 1606, 262, 1587, 262, 1593, 262, 1601, 262, 1589, 262, 1602, 262, - 1585, 262, 1588, 262, 1578, 262, 1579, 262, 1582, 262, 1584, 262, 1590, - 262, 1592, 262, 1594, 262, 1646, 262, 1722, 262, 1697, 262, 1647, 262, - 1576, 262, 1580, 262, 1607, 262, 1581, 262, 1610, 262, 1603, 262, 1604, - 262, 1605, 262, 1606, 262, 1587, 262, 1593, 262, 1601, 262, 1589, 262, - 1602, 262, 1588, 262, 1578, 262, 1579, 262, 1582, 262, 1590, 262, 1594, - 262, 1580, 262, 1581, 262, 1610, 262, 1604, 262, 1606, 262, 1587, 262, - 1593, 262, 1589, 262, 1602, 262, 1588, 262, 1582, 262, 1590, 262, 1594, - 262, 1722, 262, 1647, 262, 1576, 262, 1580, 262, 1607, 262, 1581, 262, - 1591, 262, 1610, 262, 1603, 262, 1605, 262, 1606, 262, 1587, 262, 1593, - 262, 1601, 262, 1589, 262, 1602, 262, 1588, 262, 1578, 262, 1579, 262, - 1582, 262, 1590, 262, 1592, 262, 1594, 262, 1646, 262, 1697, 262, 1575, - 262, 1576, 262, 1580, 262, 1583, 262, 1607, 262, 1608, 262, 1586, 262, - 1581, 262, 1591, 262, 1610, 262, 1604, 262, 1605, 262, 1606, 262, 1587, - 262, 1593, 262, 1601, 262, 1589, 262, 1602, 262, 1585, 262, 1588, 262, - 1578, 262, 1579, 262, 1582, 262, 1584, 262, 1590, 262, 1592, 262, 1594, - 262, 1576, 262, 1580, 262, 1583, 262, 1608, 262, 1586, 262, 1581, 262, - 1591, 262, 1610, 262, 1604, 262, 1605, 262, 1606, 262, 1587, 262, 1593, + 512, 119227, 119151, 512, 119228, 119151, 262, 65, 262, 71, 262, 74, 262, + 75, 262, 79, 262, 83, 262, 84, 262, 85, 262, 86, 262, 87, 262, 88, 262, + 89, 262, 97, 262, 98, 262, 99, 262, 102, 262, 107, 262, 109, 262, 110, + 262, 112, 262, 113, 262, 114, 262, 115, 262, 116, 262, 117, 262, 118, + 262, 119, 262, 120, 262, 121, 262, 122, 262, 305, 262, 567, 262, 913, + 262, 914, 262, 916, 262, 917, 262, 918, 262, 919, 262, 920, 262, 921, + 262, 922, 262, 923, 262, 924, 262, 925, 262, 926, 262, 927, 262, 929, + 262, 1012, 262, 931, 262, 932, 262, 933, 262, 934, 262, 935, 262, 936, + 262, 937, 262, 8711, 262, 945, 262, 946, 262, 948, 262, 949, 262, 950, + 262, 951, 262, 952, 262, 953, 262, 954, 262, 955, 262, 956, 262, 957, + 262, 958, 262, 959, 262, 961, 262, 962, 262, 963, 262, 964, 262, 965, + 262, 966, 262, 967, 262, 968, 262, 969, 262, 8706, 262, 1013, 262, 977, + 262, 1008, 262, 981, 262, 1009, 262, 982, 262, 988, 262, 989, 262, 48, + 262, 49, 262, 50, 262, 51, 262, 52, 262, 53, 262, 54, 262, 55, 262, 56, + 262, 57, 259, 1072, 259, 1073, 259, 1074, 259, 1075, 259, 1076, 259, + 1077, 259, 1078, 259, 1079, 259, 1080, 259, 1082, 259, 1083, 259, 1084, + 259, 1086, 259, 1087, 259, 1088, 259, 1089, 259, 1090, 259, 1091, 259, + 1092, 259, 1093, 259, 1094, 259, 1095, 259, 1096, 259, 1099, 259, 1101, + 259, 1102, 259, 42633, 259, 1241, 259, 1110, 259, 1112, 259, 1257, 259, + 1199, 259, 1231, 261, 1072, 261, 1073, 261, 1074, 261, 1075, 261, 1076, + 261, 1077, 261, 1078, 261, 1079, 261, 1080, 261, 1082, 261, 1083, 261, + 1086, 261, 1087, 261, 1089, 261, 1091, 261, 1092, 261, 1093, 261, 1094, + 261, 1095, 261, 1096, 261, 1098, 261, 1099, 261, 1169, 261, 1110, 261, + 1109, 261, 1119, 259, 1195, 259, 42577, 259, 1201, 262, 1575, 262, 1576, + 262, 1580, 262, 1583, 262, 1608, 262, 1586, 262, 1581, 262, 1591, 262, + 1610, 262, 1603, 262, 1604, 262, 1605, 262, 1606, 262, 1587, 262, 1593, 262, 1601, 262, 1589, 262, 1602, 262, 1585, 262, 1588, 262, 1578, 262, - 1579, 262, 1582, 262, 1584, 262, 1590, 262, 1592, 262, 1594, 514, 48, 46, - 514, 48, 44, 514, 49, 44, 514, 50, 44, 514, 51, 44, 514, 52, 44, 514, 53, - 44, 514, 54, 44, 514, 55, 44, 514, 56, 44, 514, 57, 44, 770, 40, 65, 41, - 770, 40, 66, 41, 770, 40, 67, 41, 770, 40, 68, 41, 770, 40, 69, 41, 770, - 40, 70, 41, 770, 40, 71, 41, 770, 40, 72, 41, 770, 40, 73, 41, 770, 40, - 74, 41, 770, 40, 75, 41, 770, 40, 76, 41, 770, 40, 77, 41, 770, 40, 78, - 41, 770, 40, 79, 41, 770, 40, 80, 41, 770, 40, 81, 41, 770, 40, 82, 41, - 770, 40, 83, 41, 770, 40, 84, 41, 770, 40, 85, 41, 770, 40, 86, 41, 770, - 40, 87, 41, 770, 40, 88, 41, 770, 40, 89, 41, 770, 40, 90, 41, 770, - 12308, 83, 12309, 263, 67, 263, 82, 519, 67, 68, 519, 87, 90, 266, 65, - 266, 66, 266, 67, 266, 68, 266, 69, 266, 70, 266, 71, 266, 72, 266, 73, - 266, 74, 266, 75, 266, 76, 266, 77, 266, 78, 266, 79, 266, 80, 266, 81, - 266, 82, 266, 83, 266, 84, 266, 85, 266, 86, 266, 87, 266, 88, 266, 89, - 266, 90, 522, 72, 86, 522, 77, 86, 522, 83, 68, 522, 83, 83, 778, 80, 80, - 86, 522, 87, 67, 515, 77, 67, 515, 77, 68, 515, 77, 82, 522, 68, 74, 522, - 12411, 12363, 522, 12467, 12467, 266, 12469, 266, 25163, 266, 23383, 266, - 21452, 266, 12487, 266, 20108, 266, 22810, 266, 35299, 266, 22825, 266, - 20132, 266, 26144, 266, 28961, 266, 26009, 266, 21069, 266, 24460, 266, - 20877, 266, 26032, 266, 21021, 266, 32066, 266, 29983, 266, 36009, 266, - 22768, 266, 21561, 266, 28436, 266, 25237, 266, 25429, 266, 19968, 266, - 19977, 266, 36938, 266, 24038, 266, 20013, 266, 21491, 266, 25351, 266, - 36208, 266, 25171, 266, 31105, 266, 31354, 266, 21512, 266, 28288, 266, - 26377, 266, 26376, 266, 30003, 266, 21106, 266, 21942, 266, 37197, 770, - 12308, 26412, 12309, 770, 12308, 19977, 12309, 770, 12308, 20108, 12309, - 770, 12308, 23433, 12309, 770, 12308, 28857, 12309, 770, 12308, 25171, - 12309, 770, 12308, 30423, 12309, 770, 12308, 21213, 12309, 770, 12308, - 25943, 12309, 263, 24471, 263, 21487, 262, 48, 262, 49, 262, 50, 262, 51, - 262, 52, 262, 53, 262, 54, 262, 55, 262, 56, 262, 57, 256, 20029, 256, - 20024, 256, 20033, 256, 131362, 256, 20320, 256, 20398, 256, 20411, 256, - 20482, 256, 20602, 256, 20633, 256, 20711, 256, 20687, 256, 13470, 256, - 132666, 256, 20813, 256, 20820, 256, 20836, 256, 20855, 256, 132380, 256, - 13497, 256, 20839, 256, 20877, 256, 132427, 256, 20887, 256, 20900, 256, - 20172, 256, 20908, 256, 20917, 256, 168415, 256, 20981, 256, 20995, 256, - 13535, 256, 21051, 256, 21062, 256, 21106, 256, 21111, 256, 13589, 256, - 21191, 256, 21193, 256, 21220, 256, 21242, 256, 21253, 256, 21254, 256, - 21271, 256, 21321, 256, 21329, 256, 21338, 256, 21363, 256, 21373, 256, - 21375, 256, 21375, 256, 21375, 256, 133676, 256, 28784, 256, 21450, 256, - 21471, 256, 133987, 256, 21483, 256, 21489, 256, 21510, 256, 21662, 256, - 21560, 256, 21576, 256, 21608, 256, 21666, 256, 21750, 256, 21776, 256, - 21843, 256, 21859, 256, 21892, 256, 21892, 256, 21913, 256, 21931, 256, - 21939, 256, 21954, 256, 22294, 256, 22022, 256, 22295, 256, 22097, 256, - 22132, 256, 20999, 256, 22766, 256, 22478, 256, 22516, 256, 22541, 256, - 22411, 256, 22578, 256, 22577, 256, 22700, 256, 136420, 256, 22770, 256, - 22775, 256, 22790, 256, 22810, 256, 22818, 256, 22882, 256, 136872, 256, - 136938, 256, 23020, 256, 23067, 256, 23079, 256, 23000, 256, 23142, 256, - 14062, 256, 14076, 256, 23304, 256, 23358, 256, 23358, 256, 137672, 256, - 23491, 256, 23512, 256, 23527, 256, 23539, 256, 138008, 256, 23551, 256, - 23558, 256, 24403, 256, 23586, 256, 14209, 256, 23648, 256, 23662, 256, - 23744, 256, 23693, 256, 138724, 256, 23875, 256, 138726, 256, 23918, 256, - 23915, 256, 23932, 256, 24033, 256, 24034, 256, 14383, 256, 24061, 256, - 24104, 256, 24125, 256, 24169, 256, 14434, 256, 139651, 256, 14460, 256, - 24240, 256, 24243, 256, 24246, 256, 24266, 256, 172946, 256, 24318, 256, - 140081, 256, 140081, 256, 33281, 256, 24354, 256, 24354, 256, 14535, 256, - 144056, 256, 156122, 256, 24418, 256, 24427, 256, 14563, 256, 24474, 256, - 24525, 256, 24535, 256, 24569, 256, 24705, 256, 14650, 256, 14620, 256, - 24724, 256, 141012, 256, 24775, 256, 24904, 256, 24908, 256, 24910, 256, - 24908, 256, 24954, 256, 24974, 256, 25010, 256, 24996, 256, 25007, 256, - 25054, 256, 25074, 256, 25078, 256, 25104, 256, 25115, 256, 25181, 256, - 25265, 256, 25300, 256, 25424, 256, 142092, 256, 25405, 256, 25340, 256, - 25448, 256, 25475, 256, 25572, 256, 142321, 256, 25634, 256, 25541, 256, - 25513, 256, 14894, 256, 25705, 256, 25726, 256, 25757, 256, 25719, 256, - 14956, 256, 25935, 256, 25964, 256, 143370, 256, 26083, 256, 26360, 256, - 26185, 256, 15129, 256, 26257, 256, 15112, 256, 15076, 256, 20882, 256, - 20885, 256, 26368, 256, 26268, 256, 32941, 256, 17369, 256, 26391, 256, - 26395, 256, 26401, 256, 26462, 256, 26451, 256, 144323, 256, 15177, 256, - 26618, 256, 26501, 256, 26706, 256, 26757, 256, 144493, 256, 26766, 256, - 26655, 256, 26900, 256, 15261, 256, 26946, 256, 27043, 256, 27114, 256, - 27304, 256, 145059, 256, 27355, 256, 15384, 256, 27425, 256, 145575, 256, - 27476, 256, 15438, 256, 27506, 256, 27551, 256, 27578, 256, 27579, 256, - 146061, 256, 138507, 256, 146170, 256, 27726, 256, 146620, 256, 27839, - 256, 27853, 256, 27751, 256, 27926, 256, 27966, 256, 28023, 256, 27969, - 256, 28009, 256, 28024, 256, 28037, 256, 146718, 256, 27956, 256, 28207, - 256, 28270, 256, 15667, 256, 28363, 256, 28359, 256, 147153, 256, 28153, - 256, 28526, 256, 147294, 256, 147342, 256, 28614, 256, 28729, 256, 28702, - 256, 28699, 256, 15766, 256, 28746, 256, 28797, 256, 28791, 256, 28845, - 256, 132389, 256, 28997, 256, 148067, 256, 29084, 256, 148395, 256, - 29224, 256, 29237, 256, 29264, 256, 149000, 256, 29312, 256, 29333, 256, - 149301, 256, 149524, 256, 29562, 256, 29579, 256, 16044, 256, 29605, 256, - 16056, 256, 16056, 256, 29767, 256, 29788, 256, 29809, 256, 29829, 256, - 29898, 256, 16155, 256, 29988, 256, 150582, 256, 30014, 256, 150674, 256, - 30064, 256, 139679, 256, 30224, 256, 151457, 256, 151480, 256, 151620, - 256, 16380, 256, 16392, 256, 30452, 256, 151795, 256, 151794, 256, - 151833, 256, 151859, 256, 30494, 256, 30495, 256, 30495, 256, 30538, 256, - 16441, 256, 30603, 256, 16454, 256, 16534, 256, 152605, 256, 30798, 256, - 30860, 256, 30924, 256, 16611, 256, 153126, 256, 31062, 256, 153242, 256, - 153285, 256, 31119, 256, 31211, 256, 16687, 256, 31296, 256, 31306, 256, - 31311, 256, 153980, 256, 154279, 256, 154279, 256, 31470, 256, 16898, - 256, 154539, 256, 31686, 256, 31689, 256, 16935, 256, 154752, 256, 31954, - 256, 17056, 256, 31976, 256, 31971, 256, 32000, 256, 155526, 256, 32099, - 256, 17153, 256, 32199, 256, 32258, 256, 32325, 256, 17204, 256, 156200, - 256, 156231, 256, 17241, 256, 156377, 256, 32634, 256, 156478, 256, - 32661, 256, 32762, 256, 32773, 256, 156890, 256, 156963, 256, 32864, 256, - 157096, 256, 32880, 256, 144223, 256, 17365, 256, 32946, 256, 33027, 256, - 17419, 256, 33086, 256, 23221, 256, 157607, 256, 157621, 256, 144275, - 256, 144284, 256, 33281, 256, 33284, 256, 36766, 256, 17515, 256, 33425, - 256, 33419, 256, 33437, 256, 21171, 256, 33457, 256, 33459, 256, 33469, - 256, 33510, 256, 158524, 256, 33509, 256, 33565, 256, 33635, 256, 33709, - 256, 33571, 256, 33725, 256, 33767, 256, 33879, 256, 33619, 256, 33738, - 256, 33740, 256, 33756, 256, 158774, 256, 159083, 256, 158933, 256, - 17707, 256, 34033, 256, 34035, 256, 34070, 256, 160714, 256, 34148, 256, - 159532, 256, 17757, 256, 17761, 256, 159665, 256, 159954, 256, 17771, - 256, 34384, 256, 34396, 256, 34407, 256, 34409, 256, 34473, 256, 34440, - 256, 34574, 256, 34530, 256, 34681, 256, 34600, 256, 34667, 256, 34694, - 256, 17879, 256, 34785, 256, 34817, 256, 17913, 256, 34912, 256, 34915, - 256, 161383, 256, 35031, 256, 35038, 256, 17973, 256, 35066, 256, 13499, - 256, 161966, 256, 162150, 256, 18110, 256, 18119, 256, 35488, 256, 35565, - 256, 35722, 256, 35925, 256, 162984, 256, 36011, 256, 36033, 256, 36123, - 256, 36215, 256, 163631, 256, 133124, 256, 36299, 256, 36284, 256, 36336, - 256, 133342, 256, 36564, 256, 36664, 256, 165330, 256, 165357, 256, + 1579, 262, 1582, 262, 1584, 262, 1590, 262, 1592, 262, 1594, 262, 1646, + 262, 1722, 262, 1697, 262, 1647, 262, 1607, 514, 48, 46, 514, 48, 44, + 514, 49, 44, 514, 50, 44, 514, 51, 44, 514, 52, 44, 514, 53, 44, 514, 54, + 44, 514, 55, 44, 514, 56, 44, 514, 57, 44, 770, 40, 65, 41, 770, 40, 66, + 41, 770, 40, 67, 41, 770, 40, 68, 41, 770, 40, 69, 41, 770, 40, 70, 41, + 770, 40, 71, 41, 770, 40, 72, 41, 770, 40, 73, 41, 770, 40, 74, 41, 770, + 40, 75, 41, 770, 40, 76, 41, 770, 40, 77, 41, 770, 40, 78, 41, 770, 40, + 79, 41, 770, 40, 80, 41, 770, 40, 81, 41, 770, 40, 82, 41, 770, 40, 83, + 41, 770, 40, 84, 41, 770, 40, 85, 41, 770, 40, 86, 41, 770, 40, 87, 41, + 770, 40, 88, 41, 770, 40, 89, 41, 770, 40, 90, 41, 770, 12308, 83, 12309, + 519, 67, 68, 519, 87, 90, 266, 65, 266, 66, 266, 67, 266, 68, 266, 69, + 266, 70, 266, 71, 266, 72, 266, 73, 266, 74, 266, 75, 266, 76, 266, 77, + 266, 78, 266, 79, 266, 80, 266, 81, 266, 82, 266, 83, 266, 84, 266, 85, + 266, 86, 266, 87, 266, 88, 266, 89, 266, 90, 522, 72, 86, 522, 83, 68, + 522, 83, 83, 778, 80, 80, 86, 522, 87, 67, 515, 77, 67, 515, 77, 68, 515, + 77, 82, 522, 68, 74, 522, 12411, 12363, 522, 12467, 12467, 266, 12469, + 266, 25163, 266, 23383, 266, 21452, 266, 12487, 266, 20108, 266, 22810, + 266, 35299, 266, 22825, 266, 20132, 266, 26144, 266, 28961, 266, 26009, + 266, 21069, 266, 24460, 266, 20877, 266, 26032, 266, 21021, 266, 32066, + 266, 29983, 266, 36009, 266, 22768, 266, 21561, 266, 28436, 266, 25237, + 266, 25429, 266, 19968, 266, 19977, 266, 36938, 266, 24038, 266, 20013, + 266, 21491, 266, 25351, 266, 36208, 266, 25171, 266, 31105, 266, 31354, + 266, 21512, 266, 28288, 266, 26377, 266, 26376, 266, 30003, 266, 21106, + 266, 21942, 266, 37197, 770, 12308, 26412, 12309, 770, 12308, 19977, + 12309, 770, 12308, 20108, 12309, 770, 12308, 23433, 12309, 770, 12308, + 28857, 12309, 770, 12308, 25171, 12309, 770, 12308, 30423, 12309, 770, + 12308, 21213, 12309, 770, 12308, 25943, 12309, 263, 24471, 263, 21487, + 256, 20029, 256, 20024, 256, 20033, 256, 131362, 256, 20320, 256, 20411, + 256, 20482, 256, 20602, 256, 20633, 256, 20687, 256, 13470, 256, 132666, + 256, 20820, 256, 20836, 256, 20855, 256, 132380, 256, 13497, 256, 20839, + 256, 20877, 256, 132427, 256, 20887, 256, 20900, 256, 20172, 256, 20908, + 256, 168415, 256, 20981, 256, 20995, 256, 13535, 256, 21051, 256, 21062, + 256, 21106, 256, 21111, 256, 13589, 256, 21253, 256, 21254, 256, 21321, + 256, 21338, 256, 21363, 256, 21373, 256, 21375, 256, 133676, 256, 28784, + 256, 21450, 256, 21471, 256, 133987, 256, 21483, 256, 21489, 256, 21510, + 256, 21662, 256, 21560, 256, 21576, 256, 21608, 256, 21666, 256, 21750, + 256, 21776, 256, 21843, 256, 21859, 256, 21892, 256, 21931, 256, 21939, + 256, 21954, 256, 22294, 256, 22295, 256, 22097, 256, 22132, 256, 22766, + 256, 22478, 256, 22516, 256, 22541, 256, 22411, 256, 22578, 256, 22577, + 256, 22700, 256, 136420, 256, 22770, 256, 22775, 256, 22790, 256, 22810, + 256, 22818, 256, 22882, 256, 136872, 256, 136938, 256, 23020, 256, 23067, + 256, 23079, 256, 23000, 256, 23142, 256, 14062, 256, 14076, 256, 23304, + 256, 23358, 256, 137672, 256, 23491, 256, 23512, 256, 23539, 256, 138008, + 256, 23551, 256, 23558, 256, 24403, 256, 23586, 256, 14209, 256, 23648, + 256, 23744, 256, 23693, 256, 138724, 256, 23875, 256, 138726, 256, 23918, + 256, 23915, 256, 23932, 256, 24033, 256, 24034, 256, 14383, 256, 24061, + 256, 24104, 256, 24125, 256, 24169, 256, 14434, 256, 139651, 256, 14460, + 256, 24240, 256, 24243, 256, 24246, 256, 172946, 256, 24318, 256, 140081, + 256, 33281, 256, 24354, 256, 14535, 256, 144056, 256, 156122, 256, 24418, + 256, 24427, 256, 14563, 256, 24474, 256, 24525, 256, 24535, 256, 24569, + 256, 24705, 256, 14650, 256, 14620, 256, 141012, 256, 24775, 256, 24904, + 256, 24908, 256, 24954, 256, 25010, 256, 24996, 256, 25007, 256, 25054, + 256, 25104, 256, 25115, 256, 25181, 256, 25265, 256, 25300, 256, 25424, + 256, 142092, 256, 25405, 256, 25340, 256, 25448, 256, 25475, 256, 25572, + 256, 142321, 256, 25634, 256, 25541, 256, 25513, 256, 14894, 256, 25705, + 256, 25726, 256, 25757, 256, 25719, 256, 14956, 256, 25964, 256, 143370, + 256, 26083, 256, 26360, 256, 26185, 256, 15129, 256, 15112, 256, 15076, + 256, 20882, 256, 20885, 256, 26368, 256, 26268, 256, 32941, 256, 17369, + 256, 26401, 256, 26462, 256, 26451, 256, 144323, 256, 15177, 256, 26618, + 256, 26501, 256, 26706, 256, 144493, 256, 26766, 256, 26655, 256, 26900, + 256, 26946, 256, 27043, 256, 27114, 256, 27304, 256, 145059, 256, 27355, + 256, 15384, 256, 27425, 256, 145575, 256, 27476, 256, 15438, 256, 27506, + 256, 27551, 256, 27579, 256, 146061, 256, 138507, 256, 146170, 256, + 27726, 256, 146620, 256, 27839, 256, 27853, 256, 27751, 256, 27926, 256, + 27966, 256, 28009, 256, 28024, 256, 28037, 256, 146718, 256, 27956, 256, + 28207, 256, 28270, 256, 15667, 256, 28359, 256, 147153, 256, 28153, 256, + 28526, 256, 147294, 256, 147342, 256, 28614, 256, 28729, 256, 28699, 256, + 15766, 256, 28746, 256, 28797, 256, 28791, 256, 28845, 256, 132389, 256, + 28997, 256, 148067, 256, 29084, 256, 148395, 256, 29224, 256, 29264, 256, + 149000, 256, 29312, 256, 29333, 256, 149301, 256, 149524, 256, 29562, + 256, 29579, 256, 16044, 256, 29605, 256, 16056, 256, 29767, 256, 29788, + 256, 29829, 256, 29898, 256, 16155, 256, 29988, 256, 150582, 256, 30014, + 256, 150674, 256, 139679, 256, 30224, 256, 151457, 256, 151480, 256, + 151620, 256, 16380, 256, 16392, 256, 151795, 256, 151794, 256, 151833, + 256, 151859, 256, 30494, 256, 30495, 256, 30603, 256, 16454, 256, 16534, + 256, 152605, 256, 30798, 256, 16611, 256, 153126, 256, 153242, 256, + 153285, 256, 31211, 256, 16687, 256, 31306, 256, 31311, 256, 153980, 256, + 154279, 256, 31470, 256, 16898, 256, 154539, 256, 31686, 256, 31689, 256, + 16935, 256, 154752, 256, 31954, 256, 17056, 256, 31976, 256, 31971, 256, + 32000, 256, 155526, 256, 32099, 256, 17153, 256, 32199, 256, 32258, 256, + 32325, 256, 17204, 256, 156200, 256, 156231, 256, 17241, 256, 156377, + 256, 32634, 256, 156478, 256, 32661, 256, 32762, 256, 156890, 256, + 156963, 256, 32864, 256, 157096, 256, 32880, 256, 144223, 256, 17365, + 256, 32946, 256, 33027, 256, 17419, 256, 33086, 256, 23221, 256, 157607, + 256, 157621, 256, 144275, 256, 144284, 256, 33284, 256, 36766, 256, + 17515, 256, 33425, 256, 33419, 256, 33437, 256, 21171, 256, 33457, 256, + 33459, 256, 33469, 256, 33510, 256, 158524, 256, 33565, 256, 33635, 256, + 33709, 256, 33571, 256, 33725, 256, 33767, 256, 33619, 256, 33738, 256, + 33740, 256, 33756, 256, 158774, 256, 159083, 256, 158933, 256, 17707, + 256, 34033, 256, 34035, 256, 34070, 256, 160714, 256, 34148, 256, 159532, + 256, 17757, 256, 17761, 256, 159665, 256, 159954, 256, 17771, 256, 34384, + 256, 34407, 256, 34409, 256, 34473, 256, 34440, 256, 34574, 256, 34530, + 256, 34600, 256, 34667, 256, 34694, 256, 17879, 256, 34785, 256, 34817, + 256, 17913, 256, 34912, 256, 34915, 256, 161383, 256, 35031, 256, 35038, + 256, 17973, 256, 35066, 256, 13499, 256, 161966, 256, 162150, 256, 18110, + 256, 18119, 256, 35488, 256, 35925, 256, 162984, 256, 36011, 256, 36033, + 256, 36123, 256, 36215, 256, 163631, 256, 133124, 256, 36299, 256, 36284, + 256, 36336, 256, 133342, 256, 36564, 256, 165330, 256, 165357, 256, 37012, 256, 37105, 256, 37137, 256, 165678, 256, 37147, 256, 37432, 256, 37591, 256, 37592, 256, 37500, 256, 37881, 256, 37909, 256, 166906, 256, 38283, 256, 18837, 256, 38327, 256, 167287, 256, 18918, 256, 38595, 256, 23986, 256, 38691, 256, 168261, 256, 168474, 256, 19054, 256, 19062, 256, - 38880, 256, 168970, 256, 19122, 256, 169110, 256, 38923, 256, 38923, 256, - 38953, 256, 169398, 256, 39138, 256, 19251, 256, 39209, 256, 39335, 256, - 39362, 256, 39422, 256, 19406, 256, 170800, 256, 39698, 256, 40000, 256, - 40189, 256, 19662, 256, 19693, 256, 40295, 256, 172238, 256, 19704, 256, - 172293, 256, 172558, 256, 172689, 256, 40635, 256, 19798, 256, 40697, - 256, 40702, 256, 40709, 256, 40719, 256, 40726, 256, 40763, 256, 173568, + 38880, 256, 168970, 256, 19122, 256, 169110, 256, 38953, 256, 169398, + 256, 39138, 256, 19251, 256, 39209, 256, 39335, 256, 39362, 256, 39422, + 256, 19406, 256, 170800, 256, 40000, 256, 40189, 256, 19662, 256, 19693, + 256, 40295, 256, 172238, 256, 19704, 256, 172293, 256, 172558, 256, + 172689, 256, 40635, 256, 19798, 256, 40697, 256, 40702, 256, 40709, 256, + 40719, 256, 40726, 256, 40763, 256, 173568, }; /* index tables for the decomposition data */ @@ -4478,9 +4390,9 @@ static const unsigned char decomp_index1[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 84, 85, 0, 0, 0, 0, 86, 87, 88, 89, 90, 91, 92, 93, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 94, 95, 0, 0, 0, 0, 96, 97, 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 94, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 95, 96, 0, 0, 0, 0, 97, 98, 99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -4501,7 +4413,7 @@ static const unsigned char decomp_index1[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 100, 101, 102, 103, 104, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 101, 102, 103, 104, 105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -4849,116 +4761,116 @@ static const unsigned short decomp_index2[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 894, 896, 0, 898, 900, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 903, 0, 0, 0, 0, - 0, 905, 0, 0, 0, 908, 0, 0, 0, 0, 0, 910, 913, 916, 919, 921, 924, 927, - 0, 930, 0, 933, 936, 939, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 942, 945, 948, 951, 954, 957, 960, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 963, 966, - 969, 972, 975, 0, 978, 980, 982, 984, 987, 990, 992, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 994, 996, 998, 0, - 1000, 1002, 0, 0, 0, 1004, 0, 0, 0, 0, 0, 0, 1006, 1009, 0, 1012, 0, 0, - 0, 1015, 0, 0, 0, 0, 1018, 1021, 1024, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1027, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1030, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1033, 1036, 0, 1039, 0, 0, 0, 1042, 0, 0, 0, - 0, 1045, 1048, 1051, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1054, 1057, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 905, 0, 0, 0, 908, 0, 0, 0, 0, 0, 15, 910, 913, 916, 918, 921, 924, 0, + 927, 0, 930, 933, 936, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 939, 942, 945, 948, 951, 954, 957, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 960, 963, + 966, 969, 972, 0, 975, 977, 979, 981, 984, 987, 989, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 991, 993, 995, 0, + 997, 999, 0, 0, 0, 1001, 0, 0, 0, 0, 0, 0, 1003, 1006, 0, 1009, 0, 0, 0, + 1012, 0, 0, 0, 0, 1015, 1018, 1021, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1024, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1027, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1030, 1033, 0, 1036, 0, 0, 0, 1039, 0, 0, 0, 0, + 1042, 1045, 1048, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1051, 1054, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1060, 1063, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1066, 1069, 1072, 1075, 0, 0, 1078, 1081, 0, 0, 1084, 1087, - 1090, 1093, 1096, 1099, 0, 0, 1102, 1105, 1108, 1111, 1114, 1117, 0, 0, - 1120, 1123, 1126, 1129, 1132, 1135, 1138, 1141, 1144, 1147, 1150, 1153, - 0, 0, 1156, 1159, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1162, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1057, 1060, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1063, 1066, 1069, 1072, 0, 0, 1075, 1078, 0, 0, 1081, 1084, + 1087, 1090, 1093, 1096, 0, 0, 1099, 1102, 1105, 1108, 1111, 1114, 0, 0, + 1117, 1120, 1123, 1126, 1129, 1132, 1135, 1138, 1141, 1144, 1147, 1150, + 0, 0, 1153, 1156, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1159, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1165, 1168, 1171, 1174, 1177, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1162, 1165, 1168, 1171, 1174, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1180, 1183, 1186, 1189, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1177, 1180, 1183, 1186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1192, 0, 1195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1198, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1189, 0, 1192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1201, 0, 0, 0, - 0, 0, 0, 0, 1204, 0, 0, 1207, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1210, - 1213, 1216, 1219, 1222, 1225, 1228, 1231, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1198, 0, 0, 0, + 0, 0, 0, 0, 1201, 0, 0, 1204, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1207, + 1210, 1213, 1216, 1219, 1222, 1225, 1228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1234, 1237, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1240, 1243, - 0, 1246, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1231, 1234, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1237, 1240, + 0, 1243, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1249, 0, 0, 1252, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1246, 0, 0, 1249, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1255, 1258, 1261, 0, 0, 1264, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1252, 1255, 1258, 0, 0, 1261, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1267, 0, 0, 1270, 1273, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1276, 1279, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1264, 0, 0, 1267, 1270, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1273, 1276, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1282, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1279, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1285, 1288, 1291, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1282, 1285, 1288, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1294, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1291, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1297, 0, 0, 0, 0, 0, 0, 1300, 1303, 0, 1306, 1309, 0, 0, 0, 0, + 0, 0, 0, 1294, 0, 0, 0, 0, 0, 0, 1297, 1300, 0, 1303, 1306, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1312, 1315, 1318, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1309, 1312, 1315, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1321, 0, 1324, 1327, 1330, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1318, 0, 1321, 1324, 1327, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1333, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1330, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1336, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1333, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1339, 1342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1336, 1339, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1345, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1342, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1347, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1350, 0, 0, 0, 0, 1353, 0, 0, 0, 0, 1356, 0, 0, 0, 0, 1359, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1362, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1365, 0, - 1368, 1371, 1374, 1377, 1380, 0, 0, 0, 0, 0, 0, 0, 1383, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1386, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1389, 0, 0, 0, 0, 1392, 0, 0, 0, 0, 1395, 0, 0, 0, 0, 1398, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1401, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1344, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1347, 0, 0, 0, 0, 1350, 0, 0, 0, 0, 1353, 0, 0, 0, 0, 1356, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1359, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1362, 0, + 1365, 1368, 1371, 1374, 1377, 0, 0, 0, 0, 0, 0, 0, 1380, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1383, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1386, 0, 0, 0, 0, 1389, 0, 0, 0, 0, 1392, 0, 0, 0, 0, 1395, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1398, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1404, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1401, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -4967,676 +4879,678 @@ static const unsigned short decomp_index2[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1407, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1409, 0, 1412, 0, 1415, 0, 1418, 0, 1421, 0, 0, - 0, 1424, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1427, 0, 1430, - 0, 0, 1433, 1436, 0, 1439, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1404, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1406, 0, 1409, 0, 1412, 0, 1415, 0, 1418, 0, 0, + 0, 1421, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1424, 0, 1427, + 0, 0, 1430, 1433, 0, 1436, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1442, 1444, 1446, 0, - 1448, 1450, 1452, 1454, 1456, 1458, 1460, 1462, 1464, 1466, 1468, 0, - 1470, 1472, 1474, 1476, 1478, 1480, 1482, 1484, 1486, 1488, 1490, 1492, - 1494, 1496, 1498, 1500, 1502, 1504, 0, 1506, 1508, 1510, 1512, 1514, - 1516, 1518, 1520, 1522, 1524, 1526, 1528, 1530, 1532, 1534, 1536, 1538, - 1540, 1542, 1544, 1546, 1548, 1550, 1552, 1554, 1556, 1558, 1560, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1562, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1564, 1566, 1568, 1570, 1572, 1574, 1576, 1578, 1580, 1582, 1584, 1586, - 1588, 1590, 1592, 1594, 1596, 1598, 1600, 1602, 1604, 1606, 1608, 1610, - 1612, 1614, 1616, 1618, 1620, 1622, 1624, 1626, 1628, 1630, 1632, 1634, - 1636, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1638, 1641, 1644, - 1647, 1650, 1653, 1656, 1659, 1662, 1665, 1668, 1671, 1674, 1677, 1680, - 1683, 1686, 1689, 1692, 1695, 1698, 1701, 1704, 1707, 1710, 1713, 1716, - 1719, 1722, 1725, 1728, 1731, 1734, 1737, 1740, 1743, 1746, 1749, 1752, - 1755, 1758, 1761, 1764, 1767, 1770, 1773, 1776, 1779, 1782, 1785, 1788, - 1791, 1794, 1797, 1800, 1803, 1806, 1809, 1812, 1815, 1818, 1821, 1824, - 1827, 1830, 1833, 1836, 1839, 1842, 1845, 1848, 1851, 1854, 1857, 1860, - 1863, 1866, 1869, 1872, 1875, 1878, 1881, 1884, 1887, 1890, 1893, 1896, - 1899, 1902, 1905, 1908, 1911, 1914, 1917, 1920, 1923, 1926, 1929, 1932, - 1935, 1938, 1941, 1944, 1947, 1950, 1953, 1956, 1959, 1962, 1965, 1968, - 1971, 1974, 1977, 1980, 1983, 1986, 1989, 1992, 1995, 1998, 2001, 2004, - 2007, 2010, 2013, 2016, 2019, 2022, 2025, 2028, 2031, 2034, 2037, 2040, - 2043, 2046, 2049, 2052, 2055, 2058, 2061, 2064, 2067, 2070, 2073, 2076, - 2079, 2082, 2085, 2088, 2091, 2094, 2097, 2100, 2103, 0, 0, 0, 0, 2106, - 2109, 2112, 2115, 2118, 2121, 2124, 2127, 2130, 2133, 2136, 2139, 2142, - 2145, 2148, 2151, 2154, 2157, 2160, 2163, 2166, 2169, 2172, 2175, 2178, - 2181, 2184, 2187, 2190, 2193, 2196, 2199, 2202, 2205, 2208, 2211, 2214, - 2217, 2220, 2223, 2226, 2229, 2232, 2235, 2238, 2241, 2244, 2247, 2250, - 2253, 2256, 2259, 2262, 2265, 2268, 2271, 2274, 2277, 2280, 2283, 2286, - 2289, 2292, 2295, 2298, 2301, 2304, 2307, 2310, 2313, 2316, 2319, 2322, - 2325, 2328, 2331, 2334, 2337, 2340, 2343, 2346, 2349, 2352, 2355, 2358, - 2361, 2364, 2367, 2370, 2373, 0, 0, 0, 0, 0, 0, 2376, 2379, 2382, 2385, - 2388, 2391, 2394, 2397, 2400, 2403, 2406, 2409, 2412, 2415, 2418, 2421, - 2424, 2427, 2430, 2433, 2436, 2439, 0, 0, 2442, 2445, 2448, 2451, 2454, - 2457, 0, 0, 2460, 2463, 2466, 2469, 2472, 2475, 2478, 2481, 2484, 2487, - 2490, 2493, 2496, 2499, 2502, 2505, 2508, 2511, 2514, 2517, 2520, 2523, - 2526, 2529, 2532, 2535, 2538, 2541, 2544, 2547, 2550, 2553, 2556, 2559, - 2562, 2565, 2568, 2571, 0, 0, 2574, 2577, 2580, 2583, 2586, 2589, 0, 0, - 2592, 2595, 2598, 2601, 2604, 2607, 2610, 2613, 0, 2616, 0, 2619, 0, - 2622, 0, 2625, 2628, 2631, 2634, 2637, 2640, 2643, 2646, 2649, 2652, - 2655, 2658, 2661, 2664, 2667, 2670, 2673, 2676, 2679, 2681, 2684, 2686, - 2689, 2691, 2694, 2696, 2699, 2701, 2704, 2706, 2709, 0, 0, 2711, 2714, - 2717, 2720, 2723, 2726, 2729, 2732, 2735, 2738, 2741, 2744, 2747, 2750, - 2753, 2756, 2759, 2762, 2765, 2768, 2771, 2774, 2777, 2780, 2783, 2786, - 2789, 2792, 2795, 2798, 2801, 2804, 2807, 2810, 2813, 2816, 2819, 2822, - 2825, 2828, 2831, 2834, 2837, 2840, 2843, 2846, 2849, 2852, 2855, 2858, - 2861, 2864, 2867, 0, 2870, 2873, 2876, 2879, 2882, 2885, 2887, 2890, - 2893, 2895, 2898, 2901, 2904, 2907, 2910, 0, 2913, 2916, 2919, 2922, - 2924, 2927, 2929, 2932, 2935, 2938, 2941, 2944, 2947, 2950, 0, 0, 2952, - 2955, 2958, 2961, 2964, 2967, 0, 2969, 2972, 2975, 2978, 2981, 2984, - 2987, 2989, 2992, 2995, 2998, 3001, 3004, 3007, 3010, 3012, 3015, 3018, - 3020, 0, 0, 3022, 3025, 3028, 0, 3031, 3034, 3037, 3040, 3042, 3045, - 3047, 3050, 3052, 0, 3055, 3057, 3059, 3061, 3063, 3065, 3067, 3069, - 3071, 3073, 3075, 0, 0, 0, 0, 0, 0, 3077, 0, 0, 0, 0, 0, 3079, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 3082, 3084, 3087, 0, 0, 0, 0, 0, 0, 0, 0, - 3091, 0, 0, 0, 3093, 3096, 0, 3100, 3103, 0, 0, 0, 0, 3107, 0, 3110, 0, - 0, 0, 0, 0, 0, 0, 0, 3113, 3116, 3119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 3122, 0, 0, 0, 0, 0, 0, 0, 3127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 3129, 3131, 0, 0, 3133, 3135, 3137, 3139, 3141, 3143, - 3145, 3147, 3149, 3151, 3153, 3155, 3157, 3159, 3161, 3163, 3165, 3167, - 3169, 3171, 3173, 3175, 3177, 3179, 3181, 3183, 3185, 0, 3187, 3189, - 3191, 3193, 3195, 3197, 3199, 3201, 3203, 3205, 3207, 3209, 3211, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 3213, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 3216, 3220, 3224, 3226, 0, 3229, 3233, 3237, 0, 3239, 3242, 3244, - 3246, 3248, 3250, 3252, 3254, 3256, 3258, 3260, 0, 3262, 3264, 0, 0, - 3267, 3269, 3271, 3273, 3275, 0, 0, 3277, 3280, 3284, 0, 3287, 0, 3289, - 0, 3291, 0, 3293, 3295, 3297, 3299, 0, 3301, 3303, 3305, 0, 3307, 3309, - 3311, 3313, 3315, 3317, 3319, 0, 3321, 3325, 3327, 3329, 3331, 3333, 0, - 0, 0, 0, 3335, 3337, 3339, 3341, 3343, 0, 0, 0, 0, 0, 0, 3345, 3349, - 3353, 3358, 3362, 3366, 3370, 3374, 3378, 3382, 3386, 3390, 3394, 3398, - 3402, 3406, 3409, 3411, 3414, 3418, 3421, 3423, 3426, 3430, 3435, 3438, - 3440, 3443, 3447, 3449, 3451, 3453, 3455, 3457, 3460, 3464, 3467, 3469, - 3472, 3476, 3481, 3484, 3486, 3489, 3493, 3495, 3497, 3499, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 3501, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 3505, 3508, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3511, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 3514, 3517, 3520, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3523, 0, 0, 0, 0, 3526, - 0, 0, 3529, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 3532, 0, 3535, 0, 0, 0, 0, 0, 3538, 3541, 0, 3545, 3548, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3552, 0, 0, 3555, 0, 0, 3558, - 0, 3561, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 3564, 0, 3567, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3570, 3573, 3576, 3579, - 3582, 0, 0, 3585, 3588, 0, 0, 3591, 3594, 0, 0, 0, 0, 0, 0, 3597, 3600, - 0, 0, 3603, 3606, 0, 0, 3609, 3612, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3615, - 3618, 3621, 3624, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 3627, 3630, 3633, 3636, 0, 0, 0, 0, 0, 0, 3639, 3642, - 3645, 3648, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3651, 3653, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 3655, 3657, 3659, 3661, 3663, 3665, 3667, 3669, - 3671, 3673, 3676, 3679, 3682, 3685, 3688, 3691, 3694, 3697, 3700, 3703, - 3706, 3710, 3714, 3718, 3722, 3726, 3730, 3734, 3738, 3742, 3747, 3752, - 3757, 3762, 3767, 3772, 3777, 3782, 3787, 3792, 3797, 3800, 3803, 3806, - 3809, 3812, 3815, 3818, 3821, 3824, 3828, 3832, 3836, 3840, 3844, 3848, - 3852, 3856, 3860, 3864, 3868, 3872, 3876, 3880, 3884, 3888, 3892, 3896, - 3900, 3904, 3908, 3912, 3916, 3920, 3924, 3928, 3932, 3936, 3940, 3944, - 3948, 3952, 3956, 3960, 3964, 3968, 3972, 3974, 3976, 3978, 3980, 3982, - 3984, 3986, 3988, 3990, 3992, 3994, 3996, 3998, 4000, 4002, 4004, 4006, - 4008, 4010, 4012, 4014, 4016, 4018, 4020, 4022, 4024, 4026, 4028, 4030, - 4032, 4034, 4036, 4038, 4040, 4042, 4044, 4046, 4048, 4050, 4052, 4054, - 4056, 4058, 4060, 4062, 4064, 4066, 4068, 4070, 4072, 4074, 4076, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 4078, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4083, 4087, 4090, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 4094, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4097, 4099, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4101, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4103, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 4105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4107, - 4109, 4111, 4113, 4115, 4117, 4119, 4121, 4123, 4125, 4127, 4129, 4131, - 4133, 4135, 4137, 4139, 4141, 4143, 4145, 4147, 4149, 4151, 4153, 4155, - 4157, 4159, 4161, 4163, 4165, 4167, 4169, 4171, 4173, 4175, 4177, 4179, - 4181, 4183, 4185, 4187, 4189, 4191, 4193, 4195, 4197, 4199, 4201, 4203, - 4205, 4207, 4209, 4211, 4213, 4215, 4217, 4219, 4221, 4223, 4225, 4227, - 4229, 4231, 4233, 4235, 4237, 4239, 4241, 4243, 4245, 4247, 4249, 4251, - 4253, 4255, 4257, 4259, 4261, 4263, 4265, 4267, 4269, 4271, 4273, 4275, - 4277, 4279, 4281, 4283, 4285, 4287, 4289, 4291, 4293, 4295, 4297, 4299, - 4301, 4303, 4305, 4307, 4309, 4311, 4313, 4315, 4317, 4319, 4321, 4323, - 4325, 4327, 4329, 4331, 4333, 4335, 4337, 4339, 4341, 4343, 4345, 4347, - 4349, 4351, 4353, 4355, 4357, 4359, 4361, 4363, 4365, 4367, 4369, 4371, - 4373, 4375, 4377, 4379, 4381, 4383, 4385, 4387, 4389, 4391, 4393, 4395, - 4397, 4399, 4401, 4403, 4405, 4407, 4409, 4411, 4413, 4415, 4417, 4419, - 4421, 4423, 4425, 4427, 4429, 4431, 4433, 4435, 4437, 4439, 4441, 4443, - 4445, 4447, 4449, 4451, 4453, 4455, 4457, 4459, 4461, 4463, 4465, 4467, - 4469, 4471, 4473, 4475, 4477, 4479, 4481, 4483, 4485, 4487, 4489, 4491, - 4493, 4495, 4497, 4499, 4501, 4503, 4505, 4507, 4509, 4511, 4513, 4515, - 4517, 4519, 4521, 4523, 4525, 4527, 4529, 4531, 4533, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1439, 1441, 1443, 0, + 1445, 1447, 1449, 1451, 1453, 1455, 1457, 1459, 1461, 1463, 1465, 0, + 1467, 1469, 1471, 1473, 1475, 1477, 1479, 6, 1481, 1483, 1485, 1487, + 1489, 1491, 1493, 1495, 1497, 1499, 0, 1501, 1503, 1505, 25, 1507, 1509, + 1511, 1513, 1515, 1517, 1519, 1521, 1523, 1525, 1527, 1529, 1531, 1533, + 1535, 1537, 1539, 1541, 1543, 1545, 1547, 1549, 1551, 1553, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1555, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1557, + 1559, 1561, 1563, 1497, 1565, 1567, 1569, 1571, 1573, 1575, 1577, 1579, + 1581, 1583, 1585, 1587, 1589, 1591, 1593, 1595, 1597, 1599, 1601, 1603, + 1605, 1607, 1609, 1611, 1613, 1615, 1617, 1619, 1621, 1623, 1625, 1627, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4535, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4537, 0, 4539, - 4541, 4543, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4545, 0, - 4548, 0, 4551, 0, 4554, 0, 4557, 0, 4560, 0, 4563, 0, 4566, 0, 4569, 0, - 4572, 0, 4575, 0, 4578, 0, 0, 4581, 0, 4584, 0, 4587, 0, 0, 0, 0, 0, 0, - 4590, 4593, 0, 4596, 4599, 0, 4602, 4605, 0, 4608, 4611, 0, 4614, 4617, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4620, - 0, 0, 0, 0, 0, 0, 4623, 4626, 0, 4629, 4632, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 4635, 0, 4638, 0, 4641, 0, 4644, 0, 4647, 0, 4650, 0, 4653, 0, - 4656, 0, 4659, 0, 4662, 0, 4665, 0, 4668, 0, 0, 4671, 0, 4674, 0, 4677, - 0, 0, 0, 0, 0, 0, 4680, 4683, 0, 4686, 4689, 0, 4692, 4695, 0, 4698, - 4701, 0, 4704, 4707, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 4710, 0, 0, 4713, 4716, 4719, 4722, 0, 0, 0, 4725, 4728, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1629, 1632, 1635, 1638, + 1641, 1644, 1647, 1650, 1653, 1656, 1659, 1662, 1665, 1668, 1671, 1674, + 1677, 1680, 1683, 1686, 1689, 1692, 1695, 1698, 1701, 1704, 1707, 1710, + 1713, 1716, 1719, 1722, 1725, 1728, 1731, 1734, 1737, 1740, 1743, 1746, + 1749, 1752, 1755, 1758, 1761, 1764, 1767, 1770, 1773, 1776, 1779, 1782, + 1785, 1788, 1791, 1794, 1797, 1800, 1803, 1806, 1809, 1812, 1815, 1818, + 1821, 1824, 1827, 1830, 1833, 1836, 1839, 1842, 1845, 1848, 1851, 1854, + 1857, 1860, 1863, 1866, 1869, 1872, 1875, 1878, 1881, 1884, 1887, 1890, + 1893, 1896, 1899, 1902, 1905, 1908, 1911, 1914, 1917, 1920, 1923, 1926, + 1929, 1932, 1935, 1938, 1941, 1944, 1947, 1950, 1953, 1956, 1959, 1962, + 1965, 1968, 1971, 1974, 1977, 1980, 1983, 1986, 1989, 1992, 1995, 1998, + 2001, 2004, 2007, 2010, 2013, 2016, 2019, 2022, 2025, 2028, 2031, 2034, + 2037, 2040, 2043, 2046, 2049, 2052, 2055, 2058, 2061, 2064, 2067, 2070, + 2073, 2076, 2079, 2082, 2085, 2088, 2091, 2094, 0, 0, 0, 0, 2097, 2100, + 2103, 2106, 2109, 2112, 2115, 2118, 2121, 2124, 2127, 2130, 2133, 2136, + 2139, 2142, 2145, 2148, 2151, 2154, 2157, 2160, 2163, 2166, 2169, 2172, + 2175, 2178, 2181, 2184, 2187, 2190, 2193, 2196, 2199, 2202, 2205, 2208, + 2211, 2214, 2217, 2220, 2223, 2226, 2229, 2232, 2235, 2238, 2241, 2244, + 2247, 2250, 2253, 2256, 2259, 2262, 2265, 2268, 2271, 2274, 2277, 2280, + 2283, 2286, 2289, 2292, 2295, 2298, 2301, 2304, 2307, 2310, 2313, 2316, + 2319, 2322, 2325, 2328, 2331, 2334, 2337, 2340, 2343, 2346, 2349, 2352, + 2355, 2358, 2361, 2364, 0, 0, 0, 0, 0, 0, 2367, 2370, 2373, 2376, 2379, + 2382, 2385, 2388, 2391, 2394, 2397, 2400, 2403, 2406, 2409, 2412, 2415, + 2418, 2421, 2424, 2427, 2430, 0, 0, 2433, 2436, 2439, 2442, 2445, 2448, + 0, 0, 2451, 2454, 2457, 2460, 2463, 2466, 2469, 2472, 2475, 2478, 2481, + 2484, 2487, 2490, 2493, 2496, 2499, 2502, 2505, 2508, 2511, 2514, 2517, + 2520, 2523, 2526, 2529, 2532, 2535, 2538, 2541, 2544, 2547, 2550, 2553, + 2556, 2559, 2562, 0, 0, 2565, 2568, 2571, 2574, 2577, 2580, 0, 0, 2583, + 2586, 2589, 2592, 2595, 2598, 2601, 2604, 0, 2607, 0, 2610, 0, 2613, 0, + 2616, 2619, 2622, 2625, 2628, 2631, 2634, 2637, 2640, 2643, 2646, 2649, + 2652, 2655, 2658, 2661, 2664, 2667, 2670, 2672, 2675, 2677, 2680, 2682, + 2685, 2687, 2690, 2692, 2695, 2697, 2700, 0, 0, 2702, 2705, 2708, 2711, + 2714, 2717, 2720, 2723, 2726, 2729, 2732, 2735, 2738, 2741, 2744, 2747, + 2750, 2753, 2756, 2759, 2762, 2765, 2768, 2771, 2774, 2777, 2780, 2783, + 2786, 2789, 2792, 2795, 2798, 2801, 2804, 2807, 2810, 2813, 2816, 2819, + 2822, 2825, 2828, 2831, 2834, 2837, 2840, 2843, 2846, 2849, 2852, 2855, + 2858, 0, 2861, 2864, 2867, 2870, 2873, 2876, 2878, 2881, 2884, 2881, + 2886, 2889, 2892, 2895, 2898, 0, 2901, 2904, 2907, 2910, 2912, 2915, + 2917, 2920, 2923, 2926, 2929, 2932, 2935, 2938, 0, 0, 2940, 2943, 2946, + 2949, 2952, 2955, 0, 2957, 2960, 2963, 2966, 2969, 2972, 2975, 2977, + 2980, 2983, 2986, 2989, 2992, 2995, 2998, 3000, 3003, 3006, 3008, 0, 0, + 3010, 3013, 3016, 0, 3019, 3022, 3025, 3028, 3030, 3033, 3035, 3038, + 3040, 0, 3043, 3045, 3047, 3047, 3047, 3047, 3047, 1, 3047, 3047, 3047, + 0, 0, 0, 0, 0, 0, 3049, 0, 0, 0, 0, 0, 3051, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3054, 3056, 3059, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3063, + 3066, 0, 3070, 3073, 0, 0, 0, 0, 3077, 0, 3080, 0, 0, 0, 0, 0, 0, 0, 0, + 3083, 3086, 3089, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3092, 0, 0, 0, + 0, 0, 0, 0, 3047, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3097, + 3099, 0, 0, 3101, 3103, 3105, 3107, 3109, 3111, 3113, 3115, 3117, 3119, + 3121, 3123, 3125, 3127, 3129, 3131, 3133, 3135, 3137, 3139, 3141, 3143, + 3145, 3147, 3149, 3151, 3153, 0, 3155, 3157, 3159, 3161, 3163, 3165, + 3167, 3169, 3171, 3173, 3175, 3177, 3179, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3181, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3184, 3188, 3192, + 3194, 0, 3197, 3201, 3205, 0, 3207, 3210, 3212, 3212, 3212, 3214, 3216, + 3218, 3218, 3220, 3222, 0, 3224, 3226, 0, 0, 3229, 3231, 3233, 3233, + 3233, 0, 0, 3235, 3238, 3242, 0, 3245, 0, 3247, 0, 3245, 0, 3249, 3251, + 3253, 3192, 0, 3255, 3257, 3259, 0, 3261, 3263, 3265, 3267, 3269, 3271, + 3273, 0, 3275, 3279, 3281, 3283, 3285, 3287, 0, 0, 0, 0, 3289, 3291, + 3255, 3273, 3293, 0, 0, 0, 0, 0, 0, 3295, 3299, 3303, 3308, 3312, 3316, + 3320, 3324, 3328, 3332, 3336, 3340, 3344, 3348, 3352, 3356, 3359, 3361, + 3364, 3368, 3371, 3373, 3376, 3380, 3385, 3388, 3390, 3393, 3397, 3399, + 3401, 3403, 3405, 3407, 3410, 3414, 3417, 3419, 3422, 3426, 3431, 3434, + 3436, 3439, 3443, 3445, 3447, 3449, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3451, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3455, 3458, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3461, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3464, + 3467, 3470, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 3473, 0, 0, 0, 0, 3476, 0, 0, 3479, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3482, 0, 3485, + 0, 0, 0, 0, 0, 3488, 3491, 0, 3495, 3498, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 3502, 0, 0, 3505, 0, 0, 3508, 0, 3511, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3514, 0, 3517, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 3520, 3523, 3526, 3529, 3532, 0, 0, 3535, 3538, + 0, 0, 3541, 3544, 0, 0, 0, 0, 0, 0, 3547, 3550, 0, 0, 3553, 3556, 0, 0, + 3559, 3562, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3565, 3568, 3571, 3574, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3577, + 3580, 3583, 3586, 0, 0, 0, 0, 0, 0, 3589, 3592, 3595, 3598, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 3601, 3603, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3605, 3607, 3609, 3611, 3613, 3615, 3617, 3619, 3621, 3623, 3626, 3629, + 3632, 3635, 3638, 3641, 3644, 3647, 3650, 3653, 3656, 3660, 3664, 3668, + 3672, 3676, 3680, 3684, 3688, 3692, 3697, 3702, 3707, 3712, 3717, 3722, + 3727, 3732, 3737, 3742, 3747, 3750, 3753, 3756, 3759, 3762, 3765, 3768, + 3771, 3774, 3778, 3782, 3786, 3790, 3794, 3798, 3802, 3806, 3810, 3814, + 3818, 3822, 3826, 3830, 3834, 3838, 3842, 3846, 3850, 3854, 3858, 3862, + 3866, 3870, 3874, 3878, 3882, 3886, 3890, 3894, 3898, 3902, 3906, 3910, + 3914, 3918, 3922, 3924, 3926, 3928, 3930, 3932, 3934, 3936, 3938, 3940, + 3942, 3944, 3946, 3948, 3950, 3952, 3954, 3956, 3958, 3960, 3962, 3964, + 3966, 3968, 3970, 3972, 3974, 3976, 3978, 3980, 3982, 3984, 3986, 3988, + 3990, 3992, 3994, 3996, 3998, 4000, 4002, 4004, 4006, 4008, 4010, 4012, + 4014, 4016, 4018, 4020, 4022, 4024, 4026, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 4028, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 4731, 4733, 4735, 4737, 4739, 4741, 4743, 4745, 4747, 4749, 4751, - 4753, 4755, 4757, 4759, 4761, 4763, 4765, 4767, 4769, 4771, 4773, 4775, - 4777, 4779, 4781, 4783, 4785, 4787, 4789, 4791, 4793, 4795, 4797, 4799, - 4801, 4803, 4805, 4807, 4809, 4811, 4813, 4815, 4817, 4819, 4821, 4823, - 4825, 4827, 4829, 4831, 4833, 4835, 4837, 4839, 4841, 4843, 4845, 4847, - 4849, 4851, 4853, 4855, 4857, 4859, 4861, 4863, 4865, 4867, 4869, 4871, - 4873, 4875, 4877, 4879, 4881, 4883, 4885, 4887, 4889, 4891, 4893, 4895, - 4897, 4899, 4901, 4903, 4905, 4907, 4909, 4911, 4913, 4915, 4917, 0, 0, - 0, 4919, 4921, 4923, 4925, 4927, 4929, 4931, 4933, 4935, 4937, 4939, - 4941, 4943, 4945, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 4033, 4037, 4040, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 4947, 4951, 4955, 4959, 4963, 4967, 4971, 4975, 4979, - 4983, 4987, 4991, 4995, 4999, 5003, 5008, 5013, 5018, 5023, 5028, 5033, - 5038, 5043, 5048, 5053, 5058, 5063, 5068, 5073, 5078, 5086, 0, 5093, - 5097, 5101, 5105, 5109, 5113, 5117, 5121, 5125, 5129, 5133, 5137, 5141, - 5145, 5149, 5153, 5157, 5161, 5165, 5169, 5173, 5177, 5181, 5185, 5189, - 5193, 5197, 5201, 5205, 5209, 5213, 5217, 5221, 5225, 5229, 5233, 5237, - 5239, 5241, 5243, 0, 0, 0, 0, 0, 0, 0, 0, 5245, 5249, 5252, 5255, 5258, - 5261, 5264, 5267, 5270, 5273, 5276, 5279, 5282, 5285, 5288, 5291, 5294, - 5296, 5298, 5300, 5302, 5304, 5306, 5308, 5310, 5312, 5314, 5316, 5318, - 5320, 5322, 5325, 5328, 5331, 5334, 5337, 5340, 5343, 5346, 5349, 5352, - 5355, 5358, 5361, 5364, 5370, 5375, 0, 5378, 5380, 5382, 5384, 5386, - 5388, 5390, 5392, 5394, 5396, 5398, 5400, 5402, 5404, 5406, 5408, 5410, - 5412, 5414, 5416, 5418, 5420, 5422, 5424, 5426, 5428, 5430, 5432, 5434, - 5436, 5438, 5440, 5442, 5444, 5446, 5448, 5450, 5452, 5454, 5456, 5458, - 5460, 5462, 5464, 5466, 5468, 5470, 5472, 5474, 5476, 5479, 5482, 5485, - 5488, 5491, 5494, 5497, 5500, 5503, 5506, 5509, 5512, 5515, 5518, 5521, - 5524, 5527, 5530, 5533, 5536, 5539, 5542, 5545, 5548, 5552, 5556, 5560, - 5563, 5567, 5570, 5574, 5576, 5578, 5580, 5582, 5584, 5586, 5588, 5590, - 5592, 5594, 5596, 5598, 5600, 5602, 5604, 5606, 5608, 5610, 5612, 5614, - 5616, 5618, 5620, 5622, 5624, 5626, 5628, 5630, 5632, 5634, 5636, 5638, - 5640, 5642, 5644, 5646, 5648, 5650, 5652, 5654, 5656, 5658, 5660, 5662, - 5664, 5666, 5668, 5671, 5676, 5681, 5686, 5690, 5695, 5699, 5703, 5709, - 5714, 5718, 5722, 5726, 5731, 5736, 5740, 5744, 5747, 5751, 5756, 5761, - 5764, 5770, 5777, 5783, 5787, 5793, 5799, 5804, 5808, 5812, 5816, 5821, - 5827, 5832, 5836, 5840, 5844, 5847, 5850, 5853, 5856, 5860, 5864, 5870, - 5874, 5879, 5885, 5889, 5892, 5895, 5901, 5906, 5912, 5916, 5922, 5925, - 5929, 5933, 5937, 5941, 5945, 5950, 5954, 5957, 5961, 5965, 5969, 5974, - 5978, 5982, 5986, 5992, 5997, 6000, 6006, 6009, 6014, 6019, 6023, 6027, - 6031, 6036, 6039, 6043, 6048, 6051, 6057, 6061, 6064, 6067, 6070, 6073, - 6076, 6079, 6082, 6085, 6088, 6091, 6095, 6099, 6103, 6107, 6111, 6115, - 6119, 6123, 6127, 6131, 6135, 6139, 6143, 6147, 6151, 6155, 6158, 6161, - 6165, 6168, 6171, 6174, 6178, 6182, 6185, 6188, 6191, 6194, 6197, 6202, - 6205, 6208, 6211, 6214, 6217, 6220, 6223, 6226, 6230, 6235, 6238, 6241, - 6244, 6247, 6250, 6253, 6256, 6260, 6264, 6268, 6272, 6275, 6278, 6281, - 6284, 6287, 6290, 6293, 6296, 6299, 6302, 6306, 6310, 6313, 6317, 6321, - 6325, 6328, 6332, 6336, 6341, 6344, 6348, 6352, 6356, 6360, 6366, 6373, - 6376, 6379, 6382, 6385, 6388, 6391, 6394, 6397, 6400, 6403, 6406, 6409, - 6412, 6415, 6418, 6421, 6424, 6427, 6432, 6435, 6438, 6441, 6446, 6450, - 6453, 6456, 6459, 6462, 6465, 6468, 6471, 6474, 6477, 6480, 6484, 6487, - 6490, 6494, 6498, 6501, 6506, 6510, 6513, 6516, 6519, 6522, 6526, 6530, - 6533, 6536, 6539, 6542, 6545, 6548, 6551, 6554, 6557, 6561, 6565, 6569, - 6573, 6577, 6581, 6585, 6589, 6593, 6597, 6601, 6605, 6609, 6613, 6617, - 6621, 6625, 6629, 6633, 6637, 6641, 6645, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6649, 6651, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6653, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 6655, 6657, 6659, 0, 0, 0, 6661, 6663, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6665, 6667, 6669, - 6671, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6673, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6675, 6677, 6679, 6681, 6683, 6685, - 6687, 6689, 6691, 6693, 6695, 6697, 6699, 6701, 6703, 6705, 6707, 6709, - 6711, 6713, 6715, 6717, 6719, 6721, 6723, 6725, 6727, 6729, 6731, 6733, - 6735, 6737, 6739, 6741, 6743, 6745, 6747, 6749, 6751, 6753, 6755, 6757, - 6759, 6761, 6763, 6765, 6767, 6769, 6771, 6773, 6775, 6777, 6779, 6781, - 6783, 6785, 6787, 6789, 6791, 6793, 6795, 6797, 6799, 6801, 6803, 6805, - 6807, 6809, 6811, 6813, 6815, 6817, 6819, 6821, 6823, 6825, 6827, 6829, - 6831, 6833, 6835, 6837, 6839, 6841, 6843, 6845, 6847, 6849, 6851, 6853, - 6855, 6857, 6859, 6861, 6863, 6865, 6867, 6869, 6871, 6873, 6875, 6877, - 6879, 6881, 6883, 6885, 6887, 6889, 6891, 6893, 6895, 6897, 6899, 6901, - 6903, 6905, 6907, 6909, 6911, 6913, 6915, 6917, 6919, 6921, 6923, 6925, - 6927, 6929, 6931, 6933, 6935, 6937, 6939, 6941, 6943, 6945, 6947, 6949, - 6951, 6953, 6955, 6957, 6959, 6961, 6963, 6965, 6967, 6969, 6971, 6973, - 6975, 6977, 6979, 6981, 6983, 6985, 6987, 6989, 6991, 6993, 6995, 6997, - 6999, 7001, 7003, 7005, 7007, 7009, 7011, 7013, 7015, 7017, 7019, 7021, - 7023, 7025, 7027, 7029, 7031, 7033, 7035, 7037, 7039, 7041, 7043, 7045, - 7047, 7049, 7051, 7053, 7055, 7057, 7059, 7061, 7063, 7065, 7067, 7069, - 7071, 7073, 7075, 7077, 7079, 7081, 7083, 7085, 7087, 7089, 7091, 7093, - 7095, 7097, 7099, 7101, 7103, 7105, 7107, 7109, 7111, 7113, 7115, 7117, - 7119, 7121, 7123, 7125, 7127, 7129, 7131, 7133, 7135, 7137, 7139, 7141, - 7143, 7145, 7147, 7149, 7151, 7153, 7155, 7157, 7159, 7161, 7163, 7165, - 7167, 7169, 7171, 7173, 7175, 7177, 7179, 7181, 7183, 7185, 7187, 7189, - 7191, 7193, 7195, 7197, 7199, 7201, 7203, 7205, 7207, 7209, 7211, 7213, - 0, 0, 7215, 0, 7217, 0, 0, 7219, 7221, 7223, 7225, 7227, 7229, 7231, - 7233, 7235, 7237, 0, 7239, 0, 7241, 0, 0, 7243, 7245, 0, 0, 0, 7247, - 7249, 7251, 7253, 7255, 7257, 7259, 7261, 7263, 7265, 7267, 7269, 7271, - 7273, 7275, 7277, 7279, 7281, 7283, 7285, 7287, 7289, 7291, 7293, 7295, - 7297, 7299, 7301, 7303, 7305, 7307, 7309, 7311, 7313, 7315, 7317, 7319, - 7321, 7323, 7325, 7327, 7329, 7331, 7333, 7335, 7337, 7339, 7341, 7343, - 7345, 7347, 7349, 7351, 7353, 7355, 7357, 7359, 7361, 7363, 7365, 7367, - 7369, 7371, 7373, 7375, 7377, 7379, 7381, 0, 0, 7383, 7385, 7387, 7389, - 7391, 7393, 7395, 7397, 7399, 7401, 7403, 7405, 7407, 7409, 7411, 7413, - 7415, 7417, 7419, 7421, 7423, 7425, 7427, 7429, 7431, 7433, 7435, 7437, - 7439, 7441, 7443, 7445, 7447, 7449, 7451, 7453, 7455, 7457, 7459, 7461, - 7463, 7465, 7467, 7469, 7471, 7473, 7475, 7477, 7479, 7481, 7483, 7485, - 7487, 7489, 7491, 7493, 7495, 7497, 7499, 7501, 7503, 7505, 7507, 7509, - 7511, 7513, 7515, 7517, 7519, 7521, 7523, 7525, 7527, 7529, 7531, 7533, - 7535, 7537, 7539, 7541, 7543, 7545, 7547, 7549, 7551, 7553, 7555, 7557, - 7559, 7561, 7563, 7565, 7567, 7569, 7571, 7573, 7575, 7577, 7579, 7581, - 7583, 7585, 7587, 7589, 7591, 7593, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 7595, 7598, 7601, 7604, 7608, 7612, 7615, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 7618, 7621, 7624, 7627, 7630, 0, 0, 0, 0, 0, 7633, 0, 7636, - 7639, 7641, 7643, 7645, 7647, 7649, 7651, 7653, 7655, 7657, 7659, 7662, - 7665, 7668, 7671, 7674, 7677, 7680, 7683, 7686, 7689, 7692, 7695, 0, - 7698, 7701, 7704, 7707, 7710, 0, 7713, 0, 7716, 7719, 0, 7722, 7725, 0, - 7728, 7731, 7734, 7737, 7740, 7743, 7746, 7749, 7752, 7755, 7758, 7760, - 7762, 7764, 7766, 7768, 7770, 7772, 7774, 7776, 7778, 7780, 7782, 7784, - 7786, 7788, 7790, 7792, 7794, 7796, 7798, 7800, 7802, 7804, 7806, 7808, - 7810, 7812, 7814, 7816, 7818, 7820, 7822, 7824, 7826, 7828, 7830, 7832, - 7834, 7836, 7838, 7840, 7842, 7844, 7846, 7848, 7850, 7852, 7854, 7856, - 7858, 7860, 7862, 7864, 7866, 7868, 7870, 7872, 7874, 7876, 7878, 7880, - 7882, 7884, 7886, 7888, 7890, 7892, 7894, 7896, 7898, 7900, 7902, 7904, - 7906, 7908, 7910, 7912, 7914, 7916, 7918, 7920, 7922, 7924, 7926, 7928, - 7930, 7932, 7934, 7936, 7938, 7940, 7942, 7944, 7946, 7948, 7950, 7952, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 7954, 7956, 7958, 7960, 7962, 7964, 7966, - 7968, 7970, 7972, 7974, 7976, 7978, 7980, 7982, 7984, 7986, 7988, 7990, - 7992, 7994, 7996, 7998, 8000, 8003, 8006, 8009, 8012, 8015, 8018, 8021, - 8024, 8027, 8030, 8033, 8036, 8039, 8042, 8045, 8048, 8051, 8054, 8056, - 8058, 8060, 8062, 8065, 8068, 8071, 8074, 8077, 8080, 8083, 8086, 8089, - 8092, 8095, 8098, 8101, 8104, 8107, 8110, 8113, 8116, 8119, 8122, 8125, - 8128, 8131, 8134, 8137, 8140, 8143, 8146, 8149, 8152, 8155, 8158, 8161, - 8164, 8167, 8170, 8173, 8176, 8179, 8182, 8185, 8188, 8191, 8194, 8197, - 8200, 8203, 8206, 8209, 8212, 8215, 8218, 8221, 8224, 8227, 8230, 8233, - 8236, 8239, 8242, 8245, 8248, 8251, 8254, 8257, 8260, 8263, 8266, 8269, - 8272, 8275, 8278, 8281, 8284, 8287, 8290, 8293, 8296, 8299, 8302, 8305, - 8308, 8311, 8314, 8317, 8320, 8323, 8326, 8329, 8332, 8335, 8338, 8341, - 8344, 8348, 8352, 8356, 8360, 8364, 8368, 8371, 8374, 8377, 8380, 8383, - 8386, 8389, 8392, 8395, 8398, 8401, 8404, 8407, 8410, 8413, 8416, 8419, - 8422, 8425, 8428, 8431, 8434, 8437, 8440, 8443, 8446, 8449, 8452, 8455, - 8458, 8461, 8464, 8467, 8470, 8473, 8476, 8479, 8482, 8485, 8488, 8491, - 8494, 8497, 8500, 8503, 8506, 8509, 8512, 8515, 8518, 8521, 8524, 8527, - 8530, 8533, 8536, 8539, 8542, 8545, 8548, 8551, 8554, 8557, 8560, 8563, - 8566, 8569, 8572, 8575, 8578, 8581, 8584, 8587, 8590, 8593, 8596, 8599, - 8602, 8605, 8608, 8611, 8614, 8617, 8620, 8623, 8626, 8629, 8632, 8635, - 8638, 8641, 8644, 8647, 8650, 8653, 8656, 8659, 8662, 8665, 8668, 8671, - 8674, 8677, 8680, 8683, 8686, 8689, 8692, 8695, 8698, 8701, 8704, 8707, - 8710, 8713, 8716, 8719, 8722, 8725, 8728, 8731, 8734, 8737, 8740, 8743, - 8746, 8749, 8752, 8755, 8758, 8761, 8764, 8767, 8770, 8773, 8776, 8779, - 8782, 8785, 8788, 8791, 8794, 8798, 8802, 8806, 8809, 8812, 8815, 8818, - 8821, 8824, 8827, 8830, 8833, 8836, 8839, 8842, 8845, 8848, 8851, 8854, - 8857, 8860, 8863, 8866, 8869, 8872, 8875, 8878, 8881, 8884, 8887, 8890, - 8893, 8896, 8899, 8902, 8905, 8908, 8911, 8914, 8917, 8920, 8923, 8926, - 8929, 8932, 8935, 8938, 8941, 8944, 8947, 8950, 8953, 8956, 8959, 8962, - 8965, 8968, 8971, 8974, 8977, 8980, 8983, 8986, 8989, 8992, 8995, 8998, - 9001, 9004, 9007, 9010, 9013, 9016, 9019, 9022, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9025, 9029, 9033, 9037, 9041, 9045, 9049, - 9053, 9057, 9061, 9065, 9069, 9073, 9077, 9081, 9085, 9089, 9093, 9097, - 9101, 9105, 9109, 9113, 9117, 9121, 9125, 9129, 9133, 9137, 9141, 9145, - 9149, 9153, 9157, 9161, 9165, 9169, 9173, 9177, 9181, 9185, 9189, 9193, - 9197, 9201, 9205, 9209, 9213, 9217, 9221, 9225, 9229, 9233, 9237, 9241, - 9245, 9249, 9253, 9257, 9261, 9265, 9269, 9273, 9277, 0, 0, 9281, 9285, - 9289, 9293, 9297, 9301, 9305, 9309, 9313, 9317, 9321, 9325, 9329, 9333, - 9337, 9341, 9345, 9349, 9353, 9357, 9361, 9365, 9369, 9373, 9377, 9381, - 9385, 9389, 9393, 9397, 9401, 9405, 9409, 9413, 9417, 9421, 9425, 9429, - 9433, 9437, 9441, 9445, 9449, 9453, 9457, 9461, 9465, 9469, 9473, 9477, - 9481, 9485, 9489, 9493, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 9497, 9501, 9505, 9510, 9515, 9520, 9525, 9530, 9535, 9540, 9544, 9563, - 9572, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9577, - 9579, 9581, 9583, 9585, 9587, 9589, 9591, 9593, 9595, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9597, 9599, 9601, 9603, - 9605, 9607, 9609, 9611, 9613, 9615, 9617, 9619, 9621, 9623, 9625, 9627, - 9629, 9631, 9633, 9635, 9637, 0, 0, 9639, 9641, 9643, 9645, 9647, 9649, - 9651, 9653, 9655, 9657, 9659, 9661, 0, 9663, 9665, 9667, 9669, 9671, - 9673, 9675, 9677, 9679, 9681, 9683, 9685, 9687, 9689, 9691, 9693, 9695, - 9697, 9699, 0, 9701, 9703, 9705, 9707, 0, 0, 0, 0, 9709, 9712, 9715, 0, - 9718, 0, 9721, 9724, 9727, 9730, 9733, 9736, 9739, 9742, 9745, 9748, - 9751, 9753, 9755, 9757, 9759, 9761, 9763, 9765, 9767, 9769, 9771, 9773, - 9775, 9777, 9779, 9781, 9783, 9785, 9787, 9789, 9791, 9793, 9795, 9797, - 9799, 9801, 9803, 9805, 9807, 9809, 9811, 9813, 9815, 9817, 9819, 9821, - 9823, 9825, 9827, 9829, 9831, 9833, 9835, 9837, 9839, 9841, 9843, 9845, - 9847, 9849, 9851, 9853, 9855, 9857, 9859, 9861, 9863, 9865, 9867, 9869, - 9871, 9873, 9875, 9877, 9879, 9881, 9883, 9885, 9887, 9889, 9891, 9893, - 9895, 9897, 9899, 9901, 9903, 9905, 9907, 9909, 9911, 9913, 9915, 9917, - 9919, 9921, 9923, 9925, 9927, 9929, 9931, 9933, 9935, 9937, 9939, 9941, - 9943, 9945, 9947, 9949, 9951, 9953, 9955, 9957, 9959, 9961, 9963, 9965, - 9967, 9969, 9971, 9973, 9975, 9977, 9979, 9981, 9983, 9985, 9988, 9991, - 9994, 9997, 10000, 10003, 10006, 0, 0, 0, 0, 10009, 10011, 10013, 10015, - 10017, 10019, 10021, 10023, 10025, 10027, 10029, 10031, 10033, 10035, - 10037, 10039, 10041, 10043, 10045, 10047, 10049, 10051, 10053, 10055, - 10057, 10059, 10061, 10063, 10065, 10067, 10069, 10071, 10073, 10075, - 10077, 10079, 10081, 10083, 10085, 10087, 10089, 10091, 10093, 10095, - 10097, 10099, 10101, 10103, 10105, 10107, 10109, 10111, 10113, 10115, - 10117, 10119, 10121, 10123, 10125, 10127, 10129, 10131, 10133, 10135, - 10137, 10139, 10141, 10143, 10145, 10147, 10149, 10151, 10153, 10155, - 10157, 10159, 10161, 10163, 10165, 10167, 10169, 10171, 10173, 10175, - 10177, 10179, 10181, 10183, 10185, 10187, 10189, 10191, 10193, 10195, - 10197, 10199, 10201, 10203, 10205, 10207, 10209, 10211, 10213, 10215, - 10217, 10219, 10221, 10223, 10225, 10227, 10229, 10231, 10233, 10235, - 10237, 10239, 10241, 10243, 10245, 10247, 10249, 10251, 10253, 10255, - 10257, 10259, 10261, 10263, 10265, 10267, 10269, 10271, 10273, 10275, - 10277, 10279, 10281, 10283, 10285, 10287, 10289, 10291, 10293, 10295, - 10297, 10299, 10301, 10303, 10305, 10307, 10309, 10311, 10313, 10315, - 10317, 10319, 10321, 10323, 10325, 10327, 10329, 10331, 10333, 10335, - 10337, 10339, 10341, 10343, 10345, 10347, 10349, 10351, 10353, 10355, - 10357, 10359, 10361, 10363, 10365, 10367, 10369, 10371, 10373, 10375, - 10377, 10379, 10381, 10383, 10385, 10387, 0, 0, 0, 10389, 10391, 10393, - 10395, 10397, 10399, 0, 0, 10401, 10403, 10405, 10407, 10409, 10411, 0, - 0, 10413, 10415, 10417, 10419, 10421, 10423, 0, 0, 10425, 10427, 10429, - 0, 0, 0, 10431, 10433, 10435, 10437, 10439, 10441, 10443, 0, 10445, - 10447, 10449, 10451, 10453, 10455, 10457, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 10459, 10461, 10463, 10465, 10467, 0, 10469, - 10471, 10473, 10475, 10477, 10479, 10481, 10483, 10485, 10487, 10489, - 10491, 10493, 10495, 10497, 10499, 10501, 10503, 10505, 10507, 10509, - 10511, 10513, 10515, 10517, 10519, 10521, 10523, 10525, 10527, 10529, - 10531, 10533, 10535, 10537, 10539, 10541, 10543, 10545, 10547, 10549, - 10551, 0, 10553, 10555, 10557, 10559, 10561, 10563, 10565, 10567, 10569, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4044, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4047, 4049, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4051, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4053, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 10571, 0, 10574, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10577, 0, 0, + 4055, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4057, 4059, 4061, 4063, 4065, + 4067, 4069, 4071, 4073, 4075, 4077, 4079, 4081, 4083, 4085, 4087, 4089, + 4091, 4093, 4095, 4097, 4099, 4101, 4103, 4105, 4107, 4109, 4111, 4113, + 4115, 4117, 4119, 4121, 4123, 4125, 4127, 4129, 4131, 4133, 4135, 4137, + 4139, 4141, 4143, 4145, 4147, 4149, 4151, 4153, 4155, 4157, 4159, 4161, + 4163, 4165, 4167, 4169, 4171, 4173, 4175, 4177, 4179, 4181, 4183, 4185, + 4187, 4189, 4191, 4193, 4195, 4197, 4199, 4201, 4203, 4205, 4207, 4209, + 4211, 4213, 4215, 4217, 4219, 4221, 4223, 4225, 4227, 4229, 4231, 4233, + 4235, 4237, 4239, 4241, 4243, 4245, 4247, 4249, 4251, 4253, 4255, 4257, + 4259, 4261, 4263, 4265, 4267, 4269, 4271, 4273, 4275, 4277, 4279, 4281, + 4283, 4285, 4287, 4289, 4291, 4293, 4295, 4297, 4299, 4301, 4303, 4305, + 4307, 4309, 4311, 4313, 4315, 4317, 4319, 4321, 4323, 4325, 4327, 4329, + 4331, 4333, 4335, 4337, 4339, 4341, 4343, 4345, 4347, 4349, 4351, 4353, + 4355, 4357, 4359, 4361, 4363, 4365, 4367, 4369, 4371, 4373, 4375, 4377, + 4379, 4381, 4383, 4385, 4387, 4389, 4391, 4393, 4395, 4397, 4399, 4401, + 4403, 4405, 4407, 4409, 4411, 4413, 4415, 4417, 4419, 4421, 4423, 4425, + 4427, 4429, 4431, 4433, 4435, 4437, 4439, 4441, 4443, 4445, 4447, 4449, + 4451, 4453, 4455, 4457, 4459, 4461, 4463, 4465, 4467, 4469, 4471, 4473, + 4475, 4477, 4479, 4481, 4483, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 4485, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4487, 0, 4103, 4489, 4491, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4493, 0, 4496, 0, 4499, 0, 4502, + 0, 4505, 0, 4508, 0, 4511, 0, 4514, 0, 4517, 0, 4520, 0, 4523, 0, 4526, + 0, 0, 4529, 0, 4532, 0, 4535, 0, 0, 0, 0, 0, 0, 4538, 4541, 0, 4544, + 4547, 0, 4550, 4553, 0, 4556, 4559, 0, 4562, 4565, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4568, 0, 0, 0, 0, 0, 0, + 4571, 4574, 0, 4577, 4580, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4583, 0, + 4586, 0, 4589, 0, 4592, 0, 4595, 0, 4598, 0, 4601, 0, 4604, 0, 4607, 0, + 4610, 0, 4613, 0, 4616, 0, 0, 4619, 0, 4622, 0, 4625, 0, 0, 0, 0, 0, 0, + 4628, 4631, 0, 4634, 4637, 0, 4640, 4643, 0, 4646, 4649, 0, 4652, 4655, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4658, + 0, 0, 4661, 4664, 4667, 4670, 0, 0, 0, 4673, 4676, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4679, 4681, 4683, + 4685, 4687, 4689, 4691, 4693, 4695, 4697, 4699, 4701, 4703, 4705, 4707, + 4709, 4711, 4713, 4715, 4717, 4719, 4721, 4723, 4725, 4727, 4729, 4731, + 4733, 4735, 4737, 4739, 4741, 4743, 4745, 4747, 4749, 4751, 4753, 4755, + 4757, 4759, 4761, 4763, 4765, 4767, 4769, 4771, 4773, 4775, 4777, 4779, + 4781, 4783, 4785, 4787, 4789, 4791, 4793, 4795, 4797, 4799, 4801, 4803, + 4805, 4807, 4809, 4811, 4813, 4815, 4817, 4819, 4821, 4823, 4825, 4827, + 4829, 4831, 4833, 4835, 4837, 4839, 4841, 4843, 4845, 4847, 4849, 4851, + 4853, 4855, 4857, 4859, 4861, 4863, 4865, 0, 0, 0, 4867, 4869, 4871, + 4873, 4875, 4877, 4879, 4881, 4883, 4885, 4887, 4889, 4891, 4893, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 10580, 10583, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4895, + 4899, 4903, 4907, 4911, 4915, 4919, 4923, 4927, 4931, 4935, 4939, 4943, + 4947, 4951, 4956, 4961, 4966, 4971, 4976, 4981, 4986, 4991, 4996, 5001, + 5006, 5011, 5016, 5021, 5026, 5034, 0, 5041, 5045, 5049, 5053, 5057, + 5061, 5065, 5069, 5073, 5077, 5081, 5085, 5089, 5093, 5097, 5101, 5105, + 5109, 5113, 5117, 5121, 5125, 5129, 5133, 5137, 5141, 5145, 5149, 5153, + 5157, 5161, 5165, 5169, 5173, 5177, 5181, 5185, 5187, 5189, 5191, 0, 0, + 0, 0, 0, 0, 0, 0, 5193, 5197, 5200, 5203, 5206, 5209, 5212, 5215, 5218, + 5221, 5224, 5227, 5230, 5233, 5236, 5239, 5242, 5244, 5246, 5248, 5250, + 5252, 5254, 5256, 5258, 5260, 5262, 5264, 5266, 5268, 5270, 5273, 5276, + 5279, 5282, 5285, 5288, 5291, 5294, 5297, 5300, 5303, 5306, 5309, 5312, + 5318, 5323, 0, 5326, 5328, 5330, 5332, 5334, 5336, 5338, 5340, 5342, + 5344, 5346, 5348, 5350, 5352, 5354, 5356, 5358, 5360, 5362, 5364, 5366, + 5368, 5370, 5372, 5374, 5376, 5378, 5380, 5382, 5384, 5386, 5388, 5390, + 5392, 5394, 5396, 5398, 5400, 5402, 5404, 5406, 5408, 5410, 5412, 5414, + 5416, 5418, 5420, 5422, 5424, 5427, 5430, 5433, 5436, 5439, 5442, 5445, + 5448, 5451, 5454, 5457, 5460, 5463, 5466, 5469, 5472, 5475, 5478, 5481, + 5484, 5487, 5490, 5493, 5496, 5500, 5504, 5508, 5511, 5515, 5518, 5522, + 5524, 5526, 5528, 5530, 5532, 5534, 5536, 5538, 5540, 5542, 5544, 5546, + 5548, 5550, 5552, 5554, 5556, 5558, 5560, 5562, 5564, 5566, 5568, 5570, + 5572, 5574, 5576, 5578, 5580, 5582, 5584, 5586, 5588, 5590, 5592, 5594, + 5596, 5598, 5600, 5602, 5604, 5606, 5608, 5610, 5612, 5614, 5616, 5619, + 5624, 5629, 5634, 5638, 5643, 5647, 5651, 5657, 5662, 5666, 5670, 5674, + 5679, 5684, 5688, 5692, 5695, 5699, 5704, 5709, 5712, 5718, 5725, 5731, + 5735, 5741, 5747, 5752, 5756, 5760, 5764, 5769, 5775, 5780, 5784, 5788, + 5792, 5795, 5798, 5801, 5804, 5808, 5812, 5818, 5822, 5827, 5833, 5837, + 5840, 5843, 5849, 5854, 5860, 5864, 5870, 5873, 5877, 5881, 5885, 5889, + 5893, 5898, 5902, 5905, 5909, 5913, 5917, 5922, 5926, 5930, 5934, 5940, + 5945, 5948, 5954, 5957, 5962, 5967, 5971, 5975, 5979, 5984, 5987, 5991, + 5996, 5999, 6005, 6009, 6012, 6015, 6018, 6021, 6024, 6027, 6030, 6033, + 6036, 6039, 6043, 6047, 6051, 6055, 6059, 6063, 6067, 6071, 6075, 6079, + 6083, 6087, 6091, 6095, 6099, 6103, 6106, 6109, 6113, 6116, 6119, 6122, + 6126, 6130, 6133, 6136, 6139, 6142, 6145, 6150, 6153, 6156, 6159, 6162, + 6165, 6168, 6171, 6174, 6178, 6183, 6186, 6189, 6192, 6195, 6198, 6201, + 6204, 6208, 6212, 6216, 6220, 6223, 6226, 6229, 6232, 6235, 6238, 6241, + 6244, 6247, 6250, 6254, 6258, 6261, 6265, 6269, 6273, 6276, 6280, 6284, + 6289, 6292, 6296, 6300, 6304, 6308, 6314, 6321, 6324, 6327, 6330, 6333, + 6336, 6339, 6342, 6345, 6348, 6351, 6354, 6357, 6360, 6363, 6366, 6369, + 6372, 6375, 6380, 6383, 6386, 6389, 6394, 6398, 6401, 6404, 6407, 6410, + 6413, 6416, 6419, 6422, 6425, 6428, 6432, 6435, 6438, 6442, 6446, 6449, + 6454, 6458, 6461, 6464, 6467, 6470, 6474, 6478, 6481, 6484, 6487, 6490, + 6493, 6496, 6499, 6502, 6505, 6509, 6513, 6517, 6521, 6525, 6529, 6533, + 6537, 6541, 6545, 6549, 6553, 6557, 6561, 6565, 6569, 6573, 6577, 6581, + 6585, 6589, 6593, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6597, 6599, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 6601, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6603, 6605, + 6607, 0, 0, 0, 6609, 6611, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6613, 6615, 6617, 6619, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 6621, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 6623, 6625, 6627, 6629, 6631, 6633, 6635, 6637, 6637, 6639, + 6641, 6643, 6645, 6647, 6649, 6651, 6653, 6655, 6657, 6659, 6661, 6663, + 6665, 6667, 6669, 6671, 6673, 6675, 6677, 6679, 6681, 6683, 6685, 6687, + 6689, 6691, 6693, 6695, 6697, 6699, 6701, 6703, 6705, 6707, 6709, 6711, + 6713, 6715, 6717, 6719, 6721, 6723, 6725, 6727, 6729, 6731, 6733, 6735, + 6737, 6739, 6741, 6743, 6745, 6747, 6749, 6751, 6753, 6755, 6757, 6759, + 6761, 6763, 6765, 6767, 6769, 6771, 6773, 6775, 6777, 6779, 6781, 6783, + 6785, 6787, 6789, 6791, 6793, 6795, 6797, 6799, 6801, 6803, 6661, 6805, + 6807, 6809, 6811, 6813, 6815, 6817, 6819, 6821, 6823, 6825, 6827, 6829, + 6831, 6833, 6835, 6837, 6839, 6841, 6843, 6845, 6847, 6849, 6851, 6853, + 6855, 6857, 6859, 6861, 6863, 6865, 6867, 6869, 6871, 6873, 6875, 6877, + 6879, 6881, 6883, 6885, 6887, 6889, 6891, 6893, 6895, 6897, 6899, 6901, + 6903, 6905, 6907, 6909, 6911, 6913, 6915, 6917, 6919, 6921, 6923, 6925, + 6927, 6929, 6931, 6933, 6935, 6937, 6939, 6841, 6941, 6943, 6945, 6947, + 6949, 6951, 6953, 6955, 6809, 6957, 6959, 6961, 6963, 6965, 6967, 6969, + 6971, 6973, 6975, 6977, 6979, 6981, 6983, 6985, 6987, 6989, 6991, 6993, + 6995, 6661, 6997, 6999, 7001, 7003, 7005, 7007, 7009, 7011, 7013, 7015, + 7017, 7019, 7021, 7023, 7025, 7027, 7029, 7031, 7033, 7035, 7037, 7039, + 7041, 7043, 7045, 7047, 7049, 6813, 7051, 7053, 7055, 7057, 7059, 7061, + 7063, 7065, 7067, 7069, 7071, 7073, 7075, 7077, 7079, 7081, 7083, 7085, + 7087, 7089, 7091, 7093, 7095, 7097, 7099, 7101, 7103, 7105, 7107, 7109, + 7111, 7113, 7115, 7117, 7119, 7121, 7123, 7125, 7127, 7129, 7131, 7133, + 7135, 7137, 7139, 7141, 7143, 7145, 7147, 7149, 0, 0, 7151, 0, 7153, 0, + 0, 7155, 7157, 7159, 7161, 7163, 7165, 7167, 7169, 7171, 7173, 0, 7175, + 0, 7177, 0, 0, 7179, 7181, 0, 0, 0, 7183, 7185, 7187, 7189, 7191, 7193, + 7195, 7197, 7199, 7201, 7203, 7205, 7207, 7209, 7211, 7213, 7215, 7217, + 7219, 7221, 7223, 7225, 7227, 7229, 7231, 7233, 7235, 7237, 7239, 7241, + 7243, 7245, 7247, 7249, 7251, 7253, 7255, 7257, 7259, 7261, 7263, 7265, + 7267, 7269, 7271, 6919, 7273, 7275, 7277, 7279, 7281, 7283, 7283, 7285, + 7287, 7289, 7291, 7293, 7295, 7297, 7299, 7179, 7301, 7303, 7305, 7307, + 7309, 7311, 0, 0, 7313, 7315, 7317, 7319, 7321, 7323, 7325, 7327, 7207, + 7329, 7331, 7333, 7151, 7335, 7337, 7339, 7341, 7343, 7345, 7347, 7349, + 7351, 7353, 7355, 7357, 7225, 7359, 7227, 7361, 7363, 7365, 7367, 7369, + 7153, 6703, 7371, 7373, 7375, 6843, 7017, 7377, 7379, 7241, 7381, 7243, + 7383, 7385, 7387, 7157, 7389, 7391, 7393, 7395, 7397, 7159, 7399, 7401, + 7403, 7405, 7407, 7409, 7271, 7411, 7413, 6919, 7415, 7279, 7417, 7419, + 7421, 7423, 7425, 7289, 7427, 7177, 7429, 7291, 6805, 7431, 7293, 7433, + 7297, 7435, 7437, 7439, 7441, 7443, 7301, 7169, 7445, 7303, 7447, 7305, + 7449, 6637, 7451, 7453, 7455, 7457, 7459, 7461, 7463, 7465, 7467, 7469, + 7471, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7473, 7476, 7479, 7482, + 7486, 7490, 7493, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7496, 7499, 7502, + 7505, 7508, 0, 0, 0, 0, 0, 7511, 0, 7514, 7517, 7519, 7521, 7523, 7525, + 7527, 7529, 7531, 7533, 7535, 7537, 7540, 7543, 7546, 7549, 7552, 7555, + 7558, 7561, 7564, 7567, 7570, 7573, 0, 7576, 7579, 7582, 7585, 7588, 0, + 7591, 0, 7594, 7597, 0, 7600, 7603, 0, 7606, 7609, 7612, 7615, 7618, + 7621, 7624, 7627, 7630, 7633, 7636, 7638, 7640, 7642, 7644, 7646, 7648, + 7650, 7652, 7654, 7656, 7658, 7660, 7662, 7664, 7666, 7668, 7670, 7672, + 7674, 7676, 7678, 7680, 7682, 7684, 7686, 7688, 7690, 7692, 7694, 7696, + 7698, 7700, 7702, 7704, 7706, 7708, 7710, 7712, 7714, 7716, 7718, 7720, + 7722, 7724, 7726, 7728, 7730, 7732, 7734, 7736, 7738, 7740, 7742, 7744, + 7746, 7748, 7750, 7752, 7754, 7756, 7758, 7760, 7762, 7764, 7766, 7768, + 7770, 7772, 7774, 7776, 7778, 7780, 7782, 7784, 7786, 7788, 7790, 7792, + 7794, 7796, 7798, 7800, 7802, 7804, 7806, 7808, 7810, 7812, 7814, 7816, + 7818, 7820, 7822, 7824, 7826, 7828, 7830, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 7832, 7834, 7836, 7838, 7840, 7842, 7844, 7846, 7848, 7850, 7852, 7854, + 7856, 7858, 7860, 7862, 7864, 7866, 7868, 7870, 7872, 7874, 7876, 7878, + 7881, 7884, 7887, 7890, 7893, 7896, 7899, 7902, 7905, 7908, 7911, 7914, + 7917, 7920, 7923, 7926, 7929, 7932, 7934, 7936, 7938, 7940, 7943, 7946, + 7923, 7949, 7952, 7955, 7958, 7961, 7964, 7967, 7970, 7973, 7976, 7979, + 7982, 7985, 7988, 7991, 7994, 7997, 8000, 8003, 8006, 8009, 8012, 8015, + 8018, 8021, 8024, 8027, 8030, 8033, 8036, 8039, 8042, 8045, 8048, 8051, + 8054, 8057, 8060, 8063, 8066, 8069, 8072, 8075, 8078, 8081, 8084, 8087, + 8090, 8093, 8096, 8099, 8102, 8105, 8108, 8111, 8114, 8117, 8120, 8123, + 8126, 8129, 8132, 8135, 8138, 8141, 8144, 8147, 8150, 8153, 8156, 8159, + 8162, 8165, 8168, 8171, 8174, 8177, 8180, 8183, 8186, 8189, 8192, 8195, + 8198, 8201, 8204, 8207, 8210, 8213, 8216, 8219, 8223, 8227, 8231, 8235, + 8239, 8243, 8246, 8249, 8252, 7926, 8255, 8258, 8261, 8264, 8267, 8270, + 8273, 8276, 8279, 8282, 8285, 8288, 8291, 8294, 8297, 8300, 8303, 8306, + 8309, 8312, 8315, 8318, 8321, 8324, 8327, 8330, 8333, 8336, 8339, 8342, + 8345, 8348, 8351, 8354, 8357, 8360, 8363, 8366, 8369, 8372, 8375, 8378, + 8381, 8384, 8387, 8390, 8393, 8396, 8399, 8402, 8405, 8408, 8411, 8414, + 8417, 8420, 8423, 8426, 8429, 8432, 8435, 8438, 8441, 8444, 8447, 8450, + 8453, 8456, 8459, 8462, 8465, 8468, 8471, 8474, 8477, 8480, 8483, 8486, + 8489, 8492, 8495, 8498, 8501, 8504, 8507, 8510, 8513, 8516, 8519, 8522, + 8525, 8528, 8531, 8534, 8537, 8540, 8543, 8546, 8549, 8552, 8555, 8558, + 8561, 8564, 8567, 8570, 8573, 8576, 8579, 8582, 8585, 8588, 8591, 8594, + 8597, 8600, 8603, 8606, 8609, 8612, 8615, 8618, 8621, 8624, 8627, 8630, + 8633, 8636, 8639, 8642, 8645, 8648, 8651, 8654, 8657, 8660, 8663, 8666, + 8670, 8674, 8678, 8681, 8684, 8687, 8690, 8693, 8696, 8699, 8702, 8705, + 8708, 8711, 8714, 8717, 8720, 8723, 8726, 8729, 8732, 8735, 8738, 8741, + 8744, 8747, 8750, 8753, 8756, 8759, 8762, 8765, 8768, 8771, 8774, 8777, + 8780, 8783, 8786, 8789, 8792, 8795, 8798, 8801, 8804, 8807, 8810, 8813, + 8816, 8819, 8822, 8825, 8828, 8831, 8834, 8837, 8840, 8843, 8846, 8849, + 8852, 8855, 8858, 8861, 8864, 8867, 8870, 8873, 8876, 8879, 8882, 8885, + 8888, 8891, 8894, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 8897, 8901, 8905, 8909, 8913, 8917, 8921, 8925, 8929, 8933, 8937, 8941, + 8945, 8949, 8953, 8957, 8961, 8965, 8969, 8973, 8977, 8981, 8985, 8989, + 8993, 8997, 9001, 9005, 9009, 9013, 9017, 9021, 9025, 9029, 9033, 9037, + 9041, 9045, 9049, 9053, 9057, 9061, 9065, 9069, 9073, 9077, 9081, 9085, + 9089, 9093, 9097, 9101, 9105, 9109, 9113, 9117, 9121, 9125, 9129, 9133, + 9137, 9141, 9145, 9149, 0, 0, 9153, 9157, 9161, 9165, 9169, 9173, 9177, + 9181, 9185, 9189, 9193, 9197, 9201, 9205, 9209, 9213, 9217, 9221, 9225, + 9229, 9233, 9237, 9241, 9245, 9249, 9253, 9257, 9261, 9265, 9269, 9273, + 9277, 9281, 9285, 9289, 9293, 9297, 9301, 9305, 9309, 9313, 9317, 9321, + 9325, 9329, 9333, 9337, 9341, 9345, 9349, 9353, 9357, 9361, 9365, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9369, 9373, 9377, 9382, 9387, + 9392, 9397, 9402, 9407, 9412, 9416, 9435, 9444, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9449, 9451, 9453, 9455, 9457, 9459, + 9461, 9463, 9465, 9467, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 9469, 9471, 9473, 9475, 9475, 9477, 9479, 9481, 9483, + 9485, 9487, 9489, 9491, 9493, 9495, 9497, 9499, 9501, 9503, 9505, 9507, + 0, 0, 9509, 9511, 9513, 9513, 9513, 9513, 9515, 9515, 9515, 9517, 9519, + 9521, 0, 9523, 9525, 9527, 9529, 9531, 9533, 9535, 9537, 9539, 9541, + 9543, 9545, 9547, 9549, 9551, 9553, 9555, 9557, 9559, 0, 9561, 9563, + 9565, 9567, 0, 0, 0, 0, 9569, 9572, 9575, 0, 9578, 0, 9581, 9584, 9587, + 9590, 9593, 9596, 9599, 9602, 9605, 9608, 9611, 9613, 9615, 9617, 9619, + 9621, 9623, 9625, 9627, 9629, 9631, 9633, 9635, 9637, 9639, 9641, 9643, + 9645, 9647, 9649, 9651, 9653, 9655, 9657, 9659, 9661, 9663, 9665, 9667, + 9669, 9671, 9673, 9675, 9677, 9679, 9681, 9683, 9685, 9687, 9689, 9691, + 9693, 9695, 9697, 9699, 9701, 9703, 9705, 9707, 9709, 9711, 9713, 9715, + 9717, 9719, 9721, 9723, 9725, 9727, 9729, 9731, 9733, 9735, 9737, 9739, + 9741, 9743, 9745, 9747, 9749, 9751, 9753, 9755, 9757, 9759, 9761, 9763, + 9765, 9767, 9769, 9771, 9773, 9775, 9777, 9779, 9781, 9783, 9785, 9787, + 9789, 9791, 9793, 9795, 9797, 9799, 9801, 9803, 9805, 9807, 9809, 9811, + 9813, 9815, 9817, 9819, 9821, 9823, 9825, 9827, 9829, 9831, 9833, 9835, + 9837, 9839, 9841, 9843, 9845, 9848, 9851, 9854, 9857, 9860, 9863, 9866, + 0, 0, 0, 0, 9869, 9871, 9873, 9875, 9877, 9879, 9881, 9883, 9885, 9887, + 9889, 9891, 9893, 9895, 9897, 9899, 9901, 9903, 9905, 9907, 9909, 9911, + 9913, 9915, 9917, 9919, 9921, 9923, 9925, 9927, 9929, 9931, 9933, 9935, + 9937, 9939, 9941, 9943, 9945, 9947, 9949, 9951, 9953, 9955, 9957, 9959, + 9961, 9963, 9965, 9967, 9969, 9971, 9973, 9975, 9977, 9979, 9981, 9983, + 9985, 9987, 9989, 9991, 9993, 9995, 9997, 9999, 10001, 10003, 10005, + 10007, 10009, 10011, 10013, 10015, 10017, 10019, 10021, 10023, 10025, + 10027, 10029, 10031, 10033, 10035, 10037, 10039, 10041, 10043, 10045, + 10047, 10049, 10051, 10053, 10055, 10057, 10059, 10061, 10063, 10065, + 10067, 10069, 10071, 10073, 10075, 10077, 10079, 10081, 10083, 10085, + 10087, 10089, 10091, 10093, 10095, 10097, 10099, 10101, 10103, 10105, + 10107, 10109, 10111, 10113, 10115, 10117, 10119, 10121, 10123, 10125, + 10127, 10129, 10131, 10133, 10135, 10137, 10139, 10141, 10143, 10145, + 10147, 10149, 10151, 10153, 10155, 10157, 10159, 10161, 10163, 10165, + 10167, 10169, 10171, 10173, 10175, 10177, 10179, 10181, 10183, 10185, + 10187, 10189, 10191, 10193, 10195, 10197, 10199, 10201, 10203, 10205, + 10207, 10209, 10211, 10213, 10215, 10217, 10219, 10221, 10223, 10225, + 10227, 10229, 10231, 10233, 10235, 10237, 10239, 10241, 10243, 10245, + 10247, 0, 0, 0, 10249, 10251, 10253, 10255, 10257, 10259, 0, 0, 10261, + 10263, 10265, 10267, 10269, 10271, 0, 0, 10273, 10275, 10277, 10279, + 10281, 10283, 0, 0, 10285, 10287, 10289, 0, 0, 0, 10291, 10293, 10295, + 10297, 10299, 10301, 10303, 0, 10305, 10307, 10309, 10311, 10313, 10315, + 10317, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10319, + 10321, 10323, 10325, 10327, 0, 10329, 10331, 10333, 10335, 10337, 10339, + 10341, 10343, 10345, 10347, 10349, 10351, 10353, 10355, 10357, 10359, + 10361, 10363, 10365, 10367, 10369, 10371, 10373, 10375, 10377, 10379, + 10381, 10383, 10385, 10387, 10389, 10391, 10393, 10395, 10397, 10399, + 10401, 10403, 10405, 10407, 10409, 10411, 0, 10413, 10415, 10417, 10419, + 10421, 10423, 10425, 10427, 10429, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10431, 0, 10434, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 10437, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10440, 10443, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 10446, 10449, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 10452, 10455, 0, 10458, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10461, 10464, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10467, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10470, 10473, + 10476, 10479, 10482, 10485, 10488, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 10491, 10494, 10497, 10500, 10503, 10506, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 10509, 3253, 3192, 3289, 3257, 3259, 10511, 3212, 3218, + 10513, 10515, 3220, 3261, 3224, 10517, 3229, 3231, 3233, 10519, 10521, + 10523, 10525, 10527, 10529, 10531, 3245, 10533, 10535, 10537, 3291, 3255, + 10539, 3210, 3214, 3273, 3293, 10541, 3222, 10543, 10545, 3263, 10547, + 10549, 10551, 10553, 10555, 10557, 10559, 10561, 10563, 10565, 10567, + 10509, 3253, 3192, 3289, 3257, 3259, 10511, 3212, 3218, 10513, 10515, + 3220, 3261, 3224, 10517, 3229, 3231, 3233, 10519, 10521, 10523, 10525, + 10527, 10529, 10531, 3245, 10533, 10535, 10537, 3291, 3255, 10539, 3210, + 0, 3273, 3293, 10541, 3222, 10543, 10545, 3263, 10547, 10549, 10551, + 10553, 10555, 10557, 10559, 10561, 10563, 10565, 10567, 10509, 3253, + 3192, 3289, 3257, 3259, 10511, 3212, 3218, 10513, 10515, 3220, 3261, + 3224, 10517, 3229, 3231, 3233, 10519, 10521, 10523, 10525, 10527, 10529, + 10531, 3245, 10533, 10535, 10537, 3291, 3255, 10539, 3210, 3214, 3273, + 3293, 10541, 3222, 10543, 10545, 3263, 10547, 10549, 10551, 10553, 10555, + 10557, 10559, 10561, 10563, 10565, 10567, 10509, 0, 3192, 3289, 0, 0, + 10511, 0, 0, 10513, 10515, 0, 0, 3224, 10517, 3229, 3231, 0, 10519, + 10521, 10523, 10525, 10527, 10529, 10531, 3245, 10533, 10535, 10537, + 3291, 0, 10539, 0, 3214, 3273, 3293, 10541, 3222, 10543, 10545, 0, 10547, + 10549, 10551, 10553, 10555, 10557, 10559, 10561, 10563, 10565, 10567, + 10509, 3253, 3192, 3289, 3257, 3259, 10511, 3212, 3218, 10513, 10515, + 3220, 3261, 3224, 10517, 3229, 3231, 3233, 10519, 10521, 10523, 10525, + 10527, 10529, 10531, 3245, 10533, 10535, 10537, 3291, 3255, 10539, 3210, + 3214, 3273, 3293, 10541, 3222, 10543, 10545, 3263, 10547, 10549, 10551, + 10553, 10555, 10557, 10559, 10561, 10563, 10565, 10567, 10509, 3253, 0, + 3289, 3257, 3259, 10511, 0, 0, 10513, 10515, 3220, 3261, 3224, 10517, + 3229, 3231, 0, 10519, 10521, 10523, 10525, 10527, 10529, 10531, 0, 10533, + 10535, 10537, 3291, 3255, 10539, 3210, 3214, 3273, 3293, 10541, 3222, + 10543, 10545, 3263, 10547, 10549, 10551, 10553, 10555, 10557, 10559, + 10561, 10563, 10565, 10567, 10509, 3253, 0, 3289, 3257, 3259, 10511, 0, + 3218, 10513, 10515, 3220, 3261, 0, 10517, 0, 0, 0, 10519, 10521, 10523, + 10525, 10527, 10529, 10531, 0, 10533, 10535, 10537, 3291, 3255, 10539, + 3210, 3214, 3273, 3293, 10541, 3222, 10543, 10545, 3263, 10547, 10549, + 10551, 10553, 10555, 10557, 10559, 10561, 10563, 10565, 10567, 10509, + 3253, 3192, 3289, 3257, 3259, 10511, 3212, 3218, 10513, 10515, 3220, + 3261, 3224, 10517, 3229, 3231, 3233, 10519, 10521, 10523, 10525, 10527, + 10529, 10531, 3245, 10533, 10535, 10537, 3291, 3255, 10539, 3210, 3214, + 3273, 3293, 10541, 3222, 10543, 10545, 3263, 10547, 10549, 10551, 10553, + 10555, 10557, 10559, 10561, 10563, 10565, 10567, 10509, 3253, 3192, 3289, + 3257, 3259, 10511, 3212, 3218, 10513, 10515, 3220, 3261, 3224, 10517, + 3229, 3231, 3233, 10519, 10521, 10523, 10525, 10527, 10529, 10531, 3245, + 10533, 10535, 10537, 3291, 3255, 10539, 3210, 3214, 3273, 3293, 10541, + 3222, 10543, 10545, 3263, 10547, 10549, 10551, 10553, 10555, 10557, + 10559, 10561, 10563, 10565, 10567, 10509, 3253, 3192, 3289, 3257, 3259, + 10511, 3212, 3218, 10513, 10515, 3220, 3261, 3224, 10517, 3229, 3231, + 3233, 10519, 10521, 10523, 10525, 10527, 10529, 10531, 3245, 10533, + 10535, 10537, 3291, 3255, 10539, 3210, 3214, 3273, 3293, 10541, 3222, + 10543, 10545, 3263, 10547, 10549, 10551, 10553, 10555, 10557, 10559, + 10561, 10563, 10565, 10567, 10509, 3253, 3192, 3289, 3257, 3259, 10511, + 3212, 3218, 10513, 10515, 3220, 3261, 3224, 10517, 3229, 3231, 3233, + 10519, 10521, 10523, 10525, 10527, 10529, 10531, 3245, 10533, 10535, + 10537, 3291, 3255, 10539, 3210, 3214, 3273, 3293, 10541, 3222, 10543, + 10545, 3263, 10547, 10549, 10551, 10553, 10555, 10557, 10559, 10561, + 10563, 10565, 10567, 10509, 3253, 3192, 3289, 3257, 3259, 10511, 3212, + 3218, 10513, 10515, 3220, 3261, 3224, 10517, 3229, 3231, 3233, 10519, + 10521, 10523, 10525, 10527, 10529, 10531, 3245, 10533, 10535, 10537, + 3291, 3255, 10539, 3210, 3214, 3273, 3293, 10541, 3222, 10543, 10545, + 3263, 10547, 10549, 10551, 10553, 10555, 10557, 10559, 10561, 10563, + 10565, 10567, 10509, 3253, 3192, 3289, 3257, 3259, 10511, 3212, 3218, + 10513, 10515, 3220, 3261, 3224, 10517, 3229, 3231, 3233, 10519, 10521, + 10523, 10525, 10527, 10529, 10531, 3245, 10533, 10535, 10537, 3291, 3255, + 10539, 3210, 3214, 3273, 3293, 10541, 3222, 10543, 10545, 3263, 10547, + 10549, 10551, 10553, 10555, 10557, 10559, 10561, 10563, 10565, 10567, + 10569, 10571, 0, 0, 10573, 10575, 3283, 10577, 10579, 10581, 10583, + 10585, 10587, 10589, 10591, 10593, 10595, 10597, 10599, 3285, 10601, + 10603, 10605, 10607, 10609, 10611, 10613, 10615, 10617, 10619, 10621, + 10623, 3281, 10625, 10627, 10629, 10631, 10633, 10635, 10637, 10639, + 10641, 10643, 10645, 10647, 3279, 10649, 10651, 10653, 10655, 10657, + 10659, 10661, 10663, 10665, 10667, 10669, 10671, 10673, 10675, 10677, + 10679, 10573, 10575, 3283, 10577, 10579, 10581, 10583, 10585, 10587, + 10589, 10591, 10593, 10595, 10597, 10599, 3285, 10601, 10603, 10605, + 10607, 10609, 10611, 10613, 10615, 10617, 10619, 10621, 10623, 3281, + 10625, 10627, 10629, 10631, 10633, 10635, 10637, 10639, 10641, 10643, + 10645, 10647, 3279, 10649, 10651, 10653, 10655, 10657, 10659, 10661, + 10663, 10665, 10667, 10669, 10671, 10673, 10675, 10677, 10679, 10573, + 10575, 3283, 10577, 10579, 10581, 10583, 10585, 10587, 10589, 10591, + 10593, 10595, 10597, 10599, 3285, 10601, 10603, 10605, 10607, 10609, + 10611, 10613, 10615, 10617, 10619, 10621, 10623, 3281, 10625, 10627, + 10629, 10631, 10633, 10635, 10637, 10639, 10641, 10643, 10645, 10647, + 3279, 10649, 10651, 10653, 10655, 10657, 10659, 10661, 10663, 10665, + 10667, 10669, 10671, 10673, 10675, 10677, 10679, 10573, 10575, 3283, + 10577, 10579, 10581, 10583, 10585, 10587, 10589, 10591, 10593, 10595, + 10597, 10599, 3285, 10601, 10603, 10605, 10607, 10609, 10611, 10613, + 10615, 10617, 10619, 10621, 10623, 3281, 10625, 10627, 10629, 10631, + 10633, 10635, 10637, 10639, 10641, 10643, 10645, 10647, 3279, 10649, + 10651, 10653, 10655, 10657, 10659, 10661, 10663, 10665, 10667, 10669, + 10671, 10673, 10675, 10677, 10679, 10573, 10575, 3283, 10577, 10579, + 10581, 10583, 10585, 10587, 10589, 10591, 10593, 10595, 10597, 10599, + 3285, 10601, 10603, 10605, 10607, 10609, 10611, 10613, 10615, 10617, + 10619, 10621, 10623, 3281, 10625, 10627, 10629, 10631, 10633, 10635, + 10637, 10639, 10641, 10643, 10645, 10647, 3279, 10649, 10651, 10653, + 10655, 10657, 10659, 10661, 10663, 10665, 10667, 10669, 10671, 10673, + 10675, 10677, 10679, 10681, 10683, 0, 0, 10685, 10687, 10689, 10691, + 10693, 10695, 10697, 10699, 10701, 10703, 10685, 10687, 10689, 10691, + 10693, 10695, 10697, 10699, 10701, 10703, 10685, 10687, 10689, 10691, + 10693, 10695, 10697, 10699, 10701, 10703, 10685, 10687, 10689, 10691, + 10693, 10695, 10697, 10699, 10701, 10703, 10685, 10687, 10689, 10691, + 10693, 10695, 10697, 10699, 10701, 10703, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10705, 10707, 10709, 10711, + 10713, 10715, 10717, 10719, 10721, 10723, 10725, 10727, 10729, 10731, + 10733, 10735, 10737, 10739, 10741, 10743, 10745, 10747, 10749, 10751, + 10753, 10755, 10757, 10759, 10761, 10763, 10765, 10767, 10769, 10771, + 10773, 10775, 10777, 10779, 10781, 10783, 10785, 10787, 10789, 10791, + 10793, 10795, 10797, 10799, 10801, 10803, 10805, 10807, 10809, 10811, + 10813, 10815, 10817, 10819, 10821, 10823, 10825, 10827, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10829, 10831, 10833, 10835, 0, 10837, + 10839, 10841, 10843, 10845, 10847, 10849, 10851, 10853, 10855, 10857, + 10859, 10861, 10863, 10865, 10867, 10869, 10871, 10873, 10875, 10877, + 10879, 10881, 10883, 10885, 10887, 10889, 0, 10831, 10833, 0, 10891, 0, + 0, 10841, 0, 10845, 10847, 10849, 10851, 10853, 10855, 10857, 10859, + 10861, 10863, 0, 10867, 10869, 10871, 10873, 0, 10877, 0, 10881, 0, 0, 0, + 0, 0, 0, 10833, 0, 0, 0, 0, 10841, 0, 10845, 0, 10849, 0, 10853, 10855, + 10857, 0, 10861, 10863, 0, 10867, 0, 0, 10873, 0, 10877, 0, 10881, 0, + 10885, 0, 10889, 0, 10831, 10833, 0, 10891, 0, 0, 10841, 10843, 10845, + 10847, 0, 10851, 10853, 10855, 10857, 10859, 10861, 10863, 0, 10867, + 10869, 10871, 10873, 0, 10877, 10879, 10881, 10883, 0, 10887, 0, 10829, + 10831, 10833, 10835, 10891, 10837, 10839, 10841, 10843, 10845, 0, 10849, + 10851, 10853, 10855, 10857, 10859, 10861, 10863, 10865, 10867, 10869, + 10871, 10873, 10875, 10877, 10879, 10881, 0, 0, 0, 0, 0, 10831, 10833, + 10835, 0, 10837, 10839, 10841, 10843, 10845, 0, 10849, 10851, 10853, + 10855, 10857, 10859, 10861, 10863, 10865, 10867, 10869, 10871, 10873, + 10875, 10877, 10879, 10881, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 10893, 10896, 10899, 10902, 10905, 10908, 10911, 10914, + 10917, 10920, 10923, 0, 0, 0, 0, 0, 10926, 10930, 10934, 10938, 10942, + 10946, 10950, 10954, 10958, 10962, 10966, 10970, 10974, 10978, 10982, + 10986, 10990, 10994, 10998, 11002, 11006, 11010, 11014, 11018, 11022, + 11026, 11030, 3926, 3956, 11034, 11037, 0, 11040, 11042, 11044, 11046, + 11048, 11050, 11052, 11054, 11056, 11058, 11060, 11062, 11064, 11066, + 11068, 11070, 11072, 11074, 11076, 11078, 11080, 11082, 11084, 11086, + 11088, 11090, 11092, 6348, 11095, 11098, 11101, 11105, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11108, 11111, + 11114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11117, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 11120, 11123, 11126, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 11128, 11130, 11132, 11134, 11136, 11138, 11140, 11142, 11144, + 11146, 11148, 11150, 11152, 11154, 11156, 11158, 11160, 11162, 11164, + 11166, 11168, 11170, 11172, 11174, 11176, 11178, 11180, 11182, 11184, + 11186, 11188, 11190, 11192, 11194, 11196, 11198, 11200, 11202, 11204, + 11206, 11208, 11210, 11212, 11214, 0, 0, 0, 0, 11216, 11220, 11224, + 11228, 11232, 11236, 11240, 11244, 11248, 0, 0, 0, 0, 0, 0, 0, 11252, + 11254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10685, 10687, 10689, + 10691, 10693, 10695, 10697, 10699, 10701, 10703, 0, 0, 0, 0, 0, 0, 11256, + 11258, 11260, 11262, 11264, 7195, 11266, 11268, 11270, 11272, 7197, + 11274, 11276, 11278, 7199, 11280, 11282, 11284, 11286, 11288, 11290, + 11292, 11294, 11296, 11298, 11300, 11302, 7315, 11304, 11306, 11308, + 11310, 11312, 11314, 11316, 11318, 11320, 7325, 7201, 7203, 7327, 11322, + 11324, 6817, 11326, 7205, 11328, 11330, 11332, 11334, 11334, 11334, + 11336, 11338, 11340, 11342, 11344, 11346, 11348, 11350, 11352, 11354, + 11356, 11358, 11360, 11362, 11364, 11366, 11368, 11370, 11370, 7331, + 11372, 11374, 11376, 11378, 7209, 11380, 11382, 11384, 7123, 11386, + 11388, 11390, 11392, 11394, 11396, 11398, 11400, 11402, 11404, 11406, + 11408, 11410, 11412, 11414, 11416, 11418, 11420, 11422, 11424, 11426, + 11428, 11430, 11432, 11434, 11436, 11436, 11438, 11440, 11442, 6809, + 11444, 11446, 11448, 11450, 11452, 11454, 11456, 11458, 7219, 11460, + 11462, 11464, 11466, 11468, 11470, 11472, 11474, 11476, 11478, 11480, + 11482, 11484, 11486, 11488, 11490, 11492, 11494, 11496, 11498, 11500, + 6701, 11502, 11504, 11506, 11506, 11508, 11510, 11510, 11512, 11514, + 11516, 11518, 11520, 11522, 11524, 11526, 11528, 11530, 11532, 11534, + 11536, 7221, 11538, 11540, 11542, 11544, 7355, 11544, 11546, 7225, 11548, + 11550, 11552, 11554, 7227, 6647, 11556, 11558, 11560, 11562, 11564, + 11566, 11568, 11570, 11572, 11574, 11576, 11578, 11580, 11582, 11584, + 11586, 11588, 11590, 11592, 11594, 11596, 11598, 7229, 11600, 11602, + 11604, 11606, 11608, 11610, 7233, 11612, 11614, 11616, 11618, 11620, + 11622, 11624, 11626, 6703, 7371, 11628, 11630, 11632, 11634, 11636, + 11638, 11640, 11642, 7235, 11644, 11646, 11648, 11650, 7457, 11652, + 11654, 11656, 11658, 11660, 11662, 11664, 11666, 11668, 11670, 11672, + 11674, 11676, 6843, 11678, 11680, 11682, 11684, 11686, 11688, 11690, + 11692, 11694, 11696, 11698, 7237, 7017, 11700, 11702, 11704, 11706, + 11708, 11710, 11712, 11714, 7379, 11716, 11718, 11720, 11722, 11724, + 11726, 11728, 11730, 7381, 11732, 11734, 11736, 11738, 11740, 11742, + 11744, 11746, 11748, 11750, 11752, 11754, 7385, 11756, 11758, 11760, + 11762, 11764, 11766, 11768, 11770, 11772, 11774, 11776, 11776, 11778, + 11780, 7389, 11782, 11784, 11786, 11788, 11790, 11792, 11794, 6815, + 11796, 11798, 11800, 11802, 11804, 11806, 11808, 7401, 11810, 11812, + 11814, 11816, 11818, 11820, 11820, 7403, 7461, 11822, 11824, 11826, + 11828, 11830, 6739, 7407, 11832, 11834, 7259, 11836, 11838, 7167, 11840, + 11842, 7267, 11844, 11846, 11848, 11850, 11850, 11852, 11854, 11856, + 11858, 11860, 11862, 11864, 11866, 11868, 11870, 11872, 11874, 11876, + 11878, 11880, 11882, 11884, 11886, 11888, 11890, 11892, 11894, 11896, + 11898, 11900, 11902, 11904, 7279, 11906, 11908, 11910, 11912, 11914, + 11916, 11918, 11920, 11922, 11924, 11926, 11928, 11930, 11932, 11934, + 11936, 11508, 11938, 11940, 11942, 11944, 11946, 11948, 11950, 11952, + 11954, 11956, 11958, 11960, 6851, 11962, 11964, 11966, 11968, 11970, + 11972, 7285, 11974, 11976, 11978, 11980, 11982, 11984, 11986, 11988, + 11990, 11992, 11994, 11996, 11998, 12000, 12002, 12004, 12006, 12008, + 12010, 12012, 6729, 12014, 12016, 12018, 12020, 12022, 12024, 7421, + 12026, 12028, 12030, 12032, 12034, 12036, 12038, 12040, 12042, 12044, + 12046, 12048, 12050, 12052, 12054, 12056, 12058, 12060, 12062, 12064, + 7431, 7433, 12066, 12068, 12070, 12072, 12074, 12076, 12078, 12080, + 12082, 12084, 12086, 12088, 12090, 7435, 12092, 12094, 12096, 12098, + 12100, 12102, 12104, 12106, 12108, 12110, 12112, 12114, 12116, 12118, + 12120, 12122, 12124, 12126, 12128, 12130, 12132, 12134, 12136, 12138, + 12140, 12142, 12144, 12146, 12148, 12150, 7447, 7447, 12152, 12154, + 12156, 12158, 12160, 12162, 12164, 12166, 12168, 12170, 7449, 12172, + 12174, 12176, 12178, 12180, 12182, 12184, 12186, 12188, 12190, 12192, + 12194, 12196, 12198, 12200, 12202, 12204, 12206, 12208, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 10586, 10589, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10592, 10595, 0, - 10598, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 10601, 10604, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10607, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10610, 10613, 10616, 10619, 10622, - 10625, 10628, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10631, 10634, - 10637, 10640, 10643, 10646, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 10649, 10651, 10653, 10655, 10657, 10659, 10661, 10663, 10665, 10667, - 10669, 10671, 10673, 10675, 10677, 10679, 10681, 10683, 10685, 10687, - 10689, 10691, 10693, 10695, 10697, 10699, 10701, 10703, 10705, 10707, - 10709, 10711, 10713, 10715, 10717, 10719, 10721, 10723, 10725, 10727, - 10729, 10731, 10733, 10735, 10737, 10739, 10741, 10743, 10745, 10747, - 10749, 10751, 10753, 10755, 10757, 10759, 10761, 10763, 10765, 10767, - 10769, 10771, 10773, 10775, 10777, 10779, 10781, 10783, 10785, 10787, - 10789, 10791, 10793, 10795, 10797, 10799, 10801, 10803, 10805, 10807, - 10809, 10811, 10813, 10815, 10817, 0, 10819, 10821, 10823, 10825, 10827, - 10829, 10831, 10833, 10835, 10837, 10839, 10841, 10843, 10845, 10847, - 10849, 10851, 10853, 10855, 10857, 10859, 10861, 10863, 10865, 10867, - 10869, 10871, 10873, 10875, 10877, 10879, 10881, 10883, 10885, 10887, - 10889, 10891, 10893, 10895, 10897, 10899, 10901, 10903, 10905, 10907, - 10909, 10911, 10913, 10915, 10917, 10919, 10921, 10923, 10925, 10927, - 10929, 10931, 10933, 10935, 10937, 10939, 10941, 10943, 10945, 10947, - 10949, 10951, 10953, 10955, 10957, 10959, 0, 10961, 10963, 0, 0, 10965, - 0, 0, 10967, 10969, 0, 0, 10971, 10973, 10975, 10977, 0, 10979, 10981, - 10983, 10985, 10987, 10989, 10991, 10993, 10995, 10997, 10999, 11001, 0, - 11003, 0, 11005, 11007, 11009, 11011, 11013, 11015, 11017, 0, 11019, - 11021, 11023, 11025, 11027, 11029, 11031, 11033, 11035, 11037, 11039, - 11041, 11043, 11045, 11047, 11049, 11051, 11053, 11055, 11057, 11059, - 11061, 11063, 11065, 11067, 11069, 11071, 11073, 11075, 11077, 11079, - 11081, 11083, 11085, 11087, 11089, 11091, 11093, 11095, 11097, 11099, - 11101, 11103, 11105, 11107, 11109, 11111, 11113, 11115, 11117, 11119, - 11121, 11123, 11125, 11127, 11129, 11131, 11133, 11135, 11137, 11139, - 11141, 11143, 11145, 11147, 0, 11149, 11151, 11153, 11155, 0, 0, 11157, - 11159, 11161, 11163, 11165, 11167, 11169, 11171, 0, 11173, 11175, 11177, - 11179, 11181, 11183, 11185, 0, 11187, 11189, 11191, 11193, 11195, 11197, - 11199, 11201, 11203, 11205, 11207, 11209, 11211, 11213, 11215, 11217, - 11219, 11221, 11223, 11225, 11227, 11229, 11231, 11233, 11235, 11237, - 11239, 11241, 0, 11243, 11245, 11247, 11249, 0, 11251, 11253, 11255, - 11257, 11259, 0, 11261, 0, 0, 0, 11263, 11265, 11267, 11269, 11271, - 11273, 11275, 0, 11277, 11279, 11281, 11283, 11285, 11287, 11289, 11291, - 11293, 11295, 11297, 11299, 11301, 11303, 11305, 11307, 11309, 11311, - 11313, 11315, 11317, 11319, 11321, 11323, 11325, 11327, 11329, 11331, - 11333, 11335, 11337, 11339, 11341, 11343, 11345, 11347, 11349, 11351, - 11353, 11355, 11357, 11359, 11361, 11363, 11365, 11367, 11369, 11371, - 11373, 11375, 11377, 11379, 11381, 11383, 11385, 11387, 11389, 11391, - 11393, 11395, 11397, 11399, 11401, 11403, 11405, 11407, 11409, 11411, - 11413, 11415, 11417, 11419, 11421, 11423, 11425, 11427, 11429, 11431, - 11433, 11435, 11437, 11439, 11441, 11443, 11445, 11447, 11449, 11451, - 11453, 11455, 11457, 11459, 11461, 11463, 11465, 11467, 11469, 11471, - 11473, 11475, 11477, 11479, 11481, 11483, 11485, 11487, 11489, 11491, - 11493, 11495, 11497, 11499, 11501, 11503, 11505, 11507, 11509, 11511, - 11513, 11515, 11517, 11519, 11521, 11523, 11525, 11527, 11529, 11531, - 11533, 11535, 11537, 11539, 11541, 11543, 11545, 11547, 11549, 11551, - 11553, 11555, 11557, 11559, 11561, 11563, 11565, 11567, 11569, 11571, - 11573, 11575, 11577, 11579, 11581, 11583, 11585, 11587, 11589, 11591, - 11593, 11595, 11597, 11599, 11601, 11603, 11605, 11607, 11609, 11611, - 11613, 11615, 11617, 11619, 11621, 11623, 11625, 11627, 11629, 11631, - 11633, 11635, 11637, 11639, 11641, 11643, 11645, 11647, 11649, 11651, - 11653, 11655, 11657, 11659, 11661, 11663, 11665, 11667, 11669, 11671, - 11673, 11675, 11677, 11679, 11681, 11683, 11685, 11687, 11689, 11691, - 11693, 11695, 11697, 11699, 11701, 11703, 11705, 11707, 11709, 11711, - 11713, 11715, 11717, 11719, 11721, 11723, 11725, 11727, 11729, 11731, - 11733, 11735, 11737, 11739, 11741, 11743, 11745, 11747, 11749, 11751, - 11753, 11755, 11757, 11759, 11761, 11763, 11765, 11767, 11769, 11771, - 11773, 11775, 11777, 11779, 11781, 11783, 11785, 11787, 11789, 11791, - 11793, 11795, 11797, 11799, 11801, 11803, 11805, 11807, 11809, 11811, - 11813, 11815, 11817, 11819, 11821, 11823, 11825, 11827, 11829, 11831, - 11833, 11835, 11837, 11839, 11841, 11843, 11845, 11847, 11849, 11851, - 11853, 11855, 11857, 11859, 11861, 11863, 11865, 11867, 11869, 11871, - 11873, 11875, 11877, 11879, 11881, 11883, 11885, 11887, 11889, 11891, - 11893, 11895, 11897, 11899, 11901, 11903, 11905, 11907, 11909, 11911, - 11913, 11915, 11917, 11919, 11921, 11923, 11925, 11927, 11929, 11931, - 11933, 11935, 11937, 11939, 11941, 11943, 11945, 11947, 11949, 11951, - 11953, 11955, 0, 0, 11957, 11959, 11961, 11963, 11965, 11967, 11969, - 11971, 11973, 11975, 11977, 11979, 11981, 11983, 11985, 11987, 11989, - 11991, 11993, 11995, 11997, 11999, 12001, 12003, 12005, 12007, 12009, - 12011, 12013, 12015, 12017, 12019, 12021, 12023, 12025, 12027, 12029, - 12031, 12033, 12035, 12037, 12039, 12041, 12043, 12045, 12047, 12049, - 12051, 12053, 12055, 12057, 12059, 12061, 12063, 12065, 12067, 12069, - 12071, 12073, 12075, 12077, 12079, 12081, 12083, 12085, 12087, 12089, - 12091, 12093, 12095, 12097, 12099, 12101, 12103, 12105, 12107, 12109, - 12111, 12113, 12115, 12117, 12119, 12121, 12123, 12125, 12127, 12129, - 12131, 12133, 12135, 12137, 12139, 12141, 12143, 12145, 12147, 12149, - 12151, 12153, 12155, 12157, 12159, 12161, 12163, 12165, 12167, 12169, - 12171, 12173, 12175, 12177, 12179, 12181, 12183, 12185, 12187, 12189, - 12191, 12193, 12195, 12197, 12199, 12201, 12203, 12205, 12207, 12209, - 12211, 12213, 12215, 12217, 12219, 12221, 12223, 12225, 12227, 12229, - 12231, 12233, 12235, 12237, 12239, 12241, 12243, 12245, 12247, 12249, - 12251, 12253, 12255, 12257, 12259, 12261, 12263, 12265, 12267, 12269, - 12271, 12273, 12275, 12277, 12279, 12281, 12283, 12285, 12287, 12289, - 12291, 12293, 12295, 12297, 12299, 12301, 12303, 12305, 12307, 12309, - 12311, 12313, 12315, 12317, 12319, 12321, 12323, 12325, 12327, 12329, - 12331, 12333, 12335, 12337, 12339, 12341, 12343, 12345, 12347, 12349, - 12351, 12353, 12355, 12357, 12359, 12361, 12363, 12365, 12367, 12369, - 12371, 12373, 12375, 12377, 12379, 12381, 12383, 12385, 12387, 12389, - 12391, 12393, 12395, 12397, 12399, 12401, 12403, 12405, 12407, 12409, - 12411, 12413, 12415, 12417, 12419, 12421, 12423, 12425, 12427, 12429, - 12431, 12433, 12435, 12437, 12439, 12441, 12443, 12445, 12447, 12449, - 12451, 12453, 12455, 12457, 12459, 12461, 12463, 12465, 12467, 12469, - 12471, 12473, 12475, 12477, 12479, 12481, 12483, 12485, 12487, 12489, - 12491, 12493, 12495, 12497, 12499, 12501, 12503, 12505, 12507, 12509, - 12511, 12513, 12515, 12517, 12519, 12521, 12523, 12525, 12527, 12529, - 12531, 12533, 12535, 12537, 12539, 0, 0, 12541, 12543, 12545, 12547, - 12549, 12551, 12553, 12555, 12557, 12559, 12561, 12563, 12565, 12567, - 12569, 12571, 12573, 12575, 12577, 12579, 12581, 12583, 12585, 12587, - 12589, 12591, 12593, 12595, 12597, 12599, 12601, 12603, 12605, 12607, - 12609, 12611, 12613, 12615, 12617, 12619, 12621, 12623, 12625, 12627, - 12629, 12631, 12633, 12635, 12637, 12639, 12641, 12643, 12645, 12647, 0, - 12649, 12651, 12653, 12655, 12657, 12659, 12661, 12663, 12665, 12667, - 12669, 12671, 12673, 12675, 12677, 12679, 12681, 12683, 12685, 12687, - 12689, 12691, 12693, 12695, 12697, 12699, 12701, 0, 12703, 12705, 0, - 12707, 0, 0, 12709, 0, 12711, 12713, 12715, 12717, 12719, 12721, 12723, - 12725, 12727, 12729, 0, 12731, 12733, 12735, 12737, 0, 12739, 0, 12741, - 0, 0, 0, 0, 0, 0, 12743, 0, 0, 0, 0, 12745, 0, 12747, 0, 12749, 0, 12751, - 12753, 12755, 0, 12757, 12759, 0, 12761, 0, 0, 12763, 0, 12765, 0, 12767, - 0, 12769, 0, 12771, 0, 12773, 12775, 0, 12777, 0, 0, 12779, 12781, 12783, - 12785, 0, 12787, 12789, 12791, 12793, 12795, 12797, 12799, 0, 12801, - 12803, 12805, 12807, 0, 12809, 12811, 12813, 12815, 0, 12817, 0, 12819, - 12821, 12823, 12825, 12827, 12829, 12831, 12833, 12835, 12837, 0, 12839, - 12841, 12843, 12845, 12847, 12849, 12851, 12853, 12855, 12857, 12859, - 12861, 12863, 12865, 12867, 12869, 12871, 0, 0, 0, 0, 0, 12873, 12875, - 12877, 0, 12879, 12881, 12883, 12885, 12887, 0, 12889, 12891, 12893, - 12895, 12897, 12899, 12901, 12903, 12905, 12907, 12909, 12911, 12913, - 12915, 12917, 12919, 12921, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 12923, 12926, 12929, 12932, 12935, 12938, 12941, 12944, - 12947, 12950, 12953, 0, 0, 0, 0, 0, 12956, 12960, 12964, 12968, 12972, - 12976, 12980, 12984, 12988, 12992, 12996, 13000, 13004, 13008, 13012, - 13016, 13020, 13024, 13028, 13032, 13036, 13040, 13044, 13048, 13052, - 13056, 13060, 13064, 13066, 13068, 13071, 0, 13074, 13076, 13078, 13080, - 13082, 13084, 13086, 13088, 13090, 13092, 13094, 13096, 13098, 13100, - 13102, 13104, 13106, 13108, 13110, 13112, 13114, 13116, 13118, 13120, - 13122, 13124, 13126, 13129, 13132, 13135, 13138, 13142, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13145, 13148, - 13151, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13154, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 13157, 13160, 13163, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 13165, 13167, 13169, 13171, 13173, 13175, 13177, 13179, 13181, - 13183, 13185, 13187, 13189, 13191, 13193, 13195, 13197, 13199, 13201, - 13203, 13205, 13207, 13209, 13211, 13213, 13215, 13217, 13219, 13221, - 13223, 13225, 13227, 13229, 13231, 13233, 13235, 13237, 13239, 13241, - 13243, 13245, 13247, 13249, 13251, 0, 0, 0, 0, 13253, 13257, 13261, - 13265, 13269, 13273, 13277, 13281, 13285, 0, 0, 0, 0, 0, 0, 0, 13289, - 13291, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13293, 13295, 13297, - 13299, 13301, 13303, 13305, 13307, 13309, 13311, 0, 0, 0, 0, 0, 0, 13313, - 13315, 13317, 13319, 13321, 13323, 13325, 13327, 13329, 13331, 13333, - 13335, 13337, 13339, 13341, 13343, 13345, 13347, 13349, 13351, 13353, - 13355, 13357, 13359, 13361, 13363, 13365, 13367, 13369, 13371, 13373, - 13375, 13377, 13379, 13381, 13383, 13385, 13387, 13389, 13391, 13393, - 13395, 13397, 13399, 13401, 13403, 13405, 13407, 13409, 13411, 13413, - 13415, 13417, 13419, 13421, 13423, 13425, 13427, 13429, 13431, 13433, - 13435, 13437, 13439, 13441, 13443, 13445, 13447, 13449, 13451, 13453, - 13455, 13457, 13459, 13461, 13463, 13465, 13467, 13469, 13471, 13473, - 13475, 13477, 13479, 13481, 13483, 13485, 13487, 13489, 13491, 13493, - 13495, 13497, 13499, 13501, 13503, 13505, 13507, 13509, 13511, 13513, - 13515, 13517, 13519, 13521, 13523, 13525, 13527, 13529, 13531, 13533, - 13535, 13537, 13539, 13541, 13543, 13545, 13547, 13549, 13551, 13553, - 13555, 13557, 13559, 13561, 13563, 13565, 13567, 13569, 13571, 13573, - 13575, 13577, 13579, 13581, 13583, 13585, 13587, 13589, 13591, 13593, - 13595, 13597, 13599, 13601, 13603, 13605, 13607, 13609, 13611, 13613, - 13615, 13617, 13619, 13621, 13623, 13625, 13627, 13629, 13631, 13633, - 13635, 13637, 13639, 13641, 13643, 13645, 13647, 13649, 13651, 13653, - 13655, 13657, 13659, 13661, 13663, 13665, 13667, 13669, 13671, 13673, - 13675, 13677, 13679, 13681, 13683, 13685, 13687, 13689, 13691, 13693, - 13695, 13697, 13699, 13701, 13703, 13705, 13707, 13709, 13711, 13713, - 13715, 13717, 13719, 13721, 13723, 13725, 13727, 13729, 13731, 13733, - 13735, 13737, 13739, 13741, 13743, 13745, 13747, 13749, 13751, 13753, - 13755, 13757, 13759, 13761, 13763, 13765, 13767, 13769, 13771, 13773, - 13775, 13777, 13779, 13781, 13783, 13785, 13787, 13789, 13791, 13793, - 13795, 13797, 13799, 13801, 13803, 13805, 13807, 13809, 13811, 13813, - 13815, 13817, 13819, 13821, 13823, 13825, 13827, 13829, 13831, 13833, - 13835, 13837, 13839, 13841, 13843, 13845, 13847, 13849, 13851, 13853, - 13855, 13857, 13859, 13861, 13863, 13865, 13867, 13869, 13871, 13873, - 13875, 13877, 13879, 13881, 13883, 13885, 13887, 13889, 13891, 13893, - 13895, 13897, 13899, 13901, 13903, 13905, 13907, 13909, 13911, 13913, - 13915, 13917, 13919, 13921, 13923, 13925, 13927, 13929, 13931, 13933, - 13935, 13937, 13939, 13941, 13943, 13945, 13947, 13949, 13951, 13953, - 13955, 13957, 13959, 13961, 13963, 13965, 13967, 13969, 13971, 13973, - 13975, 13977, 13979, 13981, 13983, 13985, 13987, 13989, 13991, 13993, - 13995, 13997, 13999, 14001, 14003, 14005, 14007, 14009, 14011, 14013, - 14015, 14017, 14019, 14021, 14023, 14025, 14027, 14029, 14031, 14033, - 14035, 14037, 14039, 14041, 14043, 14045, 14047, 14049, 14051, 14053, - 14055, 14057, 14059, 14061, 14063, 14065, 14067, 14069, 14071, 14073, - 14075, 14077, 14079, 14081, 14083, 14085, 14087, 14089, 14091, 14093, - 14095, 14097, 14099, 14101, 14103, 14105, 14107, 14109, 14111, 14113, - 14115, 14117, 14119, 14121, 14123, 14125, 14127, 14129, 14131, 14133, - 14135, 14137, 14139, 14141, 14143, 14145, 14147, 14149, 14151, 14153, - 14155, 14157, 14159, 14161, 14163, 14165, 14167, 14169, 14171, 14173, - 14175, 14177, 14179, 14181, 14183, 14185, 14187, 14189, 14191, 14193, - 14195, 14197, 14199, 14201, 14203, 14205, 14207, 14209, 14211, 14213, - 14215, 14217, 14219, 14221, 14223, 14225, 14227, 14229, 14231, 14233, - 14235, 14237, 14239, 14241, 14243, 14245, 14247, 14249, 14251, 14253, - 14255, 14257, 14259, 14261, 14263, 14265, 14267, 14269, 14271, 14273, - 14275, 14277, 14279, 14281, 14283, 14285, 14287, 14289, 14291, 14293, - 14295, 14297, 14299, 14301, 14303, 14305, 14307, 14309, 14311, 14313, - 14315, 14317, 14319, 14321, 14323, 14325, 14327, 14329, 14331, 14333, - 14335, 14337, 14339, 14341, 14343, 14345, 14347, 14349, 14351, 14353, - 14355, 14357, 14359, 14361, 14363, 14365, 14367, 14369, 14371, 14373, - 14375, 14377, 14379, 14381, 14383, 14385, 14387, 14389, 14391, 14393, - 14395, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; /* NFC pairs */ @@ -6107,7 +6021,7 @@ static const change_record change_records_3_2_0[] = { { 19, 30, 255, 255, 255, 0 }, { 255, 8, 255, 255, 255, 0 }, { 255, 27, 255, 255, 255, 0 }, - { 255, 255, 255, 255, 5, 0 }, + { 255, 255, 255, 255, 0, 0 }, { 255, 22, 255, 255, 255, 0 }, { 255, 23, 255, 255, 255, 0 }, { 9, 255, 255, 255, 255, 0 }, @@ -6145,56 +6059,57 @@ static const unsigned char changes_3_2_0_index[] = { 2, 122, 123, 124, 125, 126, 127, 2, 128, 129, 130, 131, 132, 133, 134, 52, 52, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 2, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 2, 159, 160, 2, - 161, 162, 163, 164, 2, 165, 166, 167, 168, 169, 170, 2, 2, 171, 172, 173, - 174, 2, 175, 2, 176, 52, 52, 52, 52, 52, 52, 52, 177, 178, 52, 179, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 180, 52, 52, 52, - 52, 52, 52, 52, 52, 181, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 52, 52, 52, 52, 182, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 52, 52, 52, 52, 183, - 184, 185, 186, 2, 2, 2, 2, 187, 188, 189, 190, 52, 52, 52, 52, 52, 52, + 161, 162, 163, 164, 2, 165, 166, 167, 168, 169, 170, 171, 2, 172, 173, + 174, 175, 2, 176, 177, 178, 52, 52, 52, 52, 52, 52, 52, 179, 180, 52, + 181, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 182, 52, + 52, 52, 52, 52, 52, 52, 52, 183, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 52, 52, 52, 52, + 184, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 52, 52, 52, + 52, 185, 186, 187, 188, 2, 2, 2, 2, 189, 190, 191, 192, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 102, 52, 52, 52, 52, 52, 52, 52, 52, 52, 191, 192, 2, + 52, 52, 52, 52, 52, 52, 52, 102, 52, 52, 52, 52, 52, 52, 52, 52, 52, 183, + 193, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 194, 52, + 52, 195, 52, 52, 196, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 197, 198, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 199, 181, 2, 2, 200, 201, + 202, 203, 204, 2, 2, 205, 2, 2, 2, 206, 207, 208, 52, 52, 52, 52, 52, + 209, 2, 2, 2, 2, 2, 2, 2, 2, 210, 2, 211, 212, 213, 2, 2, 214, 2, 2, 2, + 215, 2, 2, 2, 2, 2, 216, 52, 217, 218, 2, 2, 2, 2, 2, 219, 220, 221, 2, + 222, 223, 2, 2, 224, 225, 52, 226, 227, 2, 52, 52, 52, 52, 52, 52, 52, + 228, 229, 230, 231, 232, 52, 52, 233, 234, 52, 235, 2, 2, 2, 2, 2, 2, 2, + 2, 236, 237, 97, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 86, 238, 2, + 239, 240, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 193, 52, 52, - 194, 52, 52, 195, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 196, 197, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 198, 179, 2, 2, 199, 200, - 201, 202, 203, 2, 2, 204, 2, 2, 2, 205, 206, 207, 52, 52, 52, 52, 52, - 208, 2, 2, 2, 2, 2, 2, 2, 2, 209, 2, 210, 2, 211, 2, 2, 212, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 213, 52, 214, 215, 2, 2, 2, 2, 2, 216, 217, 218, 2, 219, - 220, 2, 2, 221, 222, 52, 223, 224, 2, 52, 52, 52, 52, 52, 52, 52, 225, - 226, 227, 228, 229, 52, 52, 230, 231, 52, 232, 2, 2, 2, 2, 2, 2, 2, 2, - 233, 234, 97, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 86, 235, 2, - 236, 237, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 241, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 242, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 238, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 239, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 243, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 240, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 244, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 241, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 242, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 243, - 52, 244, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 2, 2, 245, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 246, + 52, 247, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 245, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 248, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 246, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 238, 2, 2, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 249, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 241, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 247, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 250, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, 251, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -6426,7 +6341,7 @@ static const unsigned char changes_3_2_0_index[] = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 52, 248, 2, 2, + 2, 2, 2, 2, 2, 2, 52, 252, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -6490,7 +6405,7 @@ static const unsigned char changes_3_2_0_index[] = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, }; static const unsigned char changes_3_2_0_data[] = { @@ -6621,7 +6536,7 @@ static const unsigned char changes_3_2_0_data[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 20, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 9, 9, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, @@ -6636,7 +6551,7 @@ static const unsigned char changes_3_2_0_data[] = { 0, 0, 9, 0, 0, 9, 0, 0, 9, 0, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, + 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -7298,7 +7213,7 @@ static const unsigned char changes_3_2_0_data[] = { 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, @@ -7333,7 +7248,7 @@ static const unsigned char changes_3_2_0_data[] = { 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 0, 9, 9, 9, 9, 0, 9, 9, 9, 9, @@ -7411,119 +7326,124 @@ static const unsigned char changes_3_2_0_data[] = { 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, - 0, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 0, 9, 9, 0, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 0, 9, 9, 9, 9, 9, 9, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, + 9, 9, 9, 9, 0, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 0, 0, 0, 9, 0, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 9, + 9, 9, 9, 0, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 0, + 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, - 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, + 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, + 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, + 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, - 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, + 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, + 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -7532,109 +7452,120 @@ static const unsigned char changes_3_2_0_data[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, - 9, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 9, 9, 9, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, - 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, + 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 57, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 57, 0, 0, 0, 0, 0, 0, 9, - 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 57, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 0, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, - 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, - 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 0, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 0, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 9, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, + 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -7702,18 +7633,18 @@ static const unsigned char changes_3_2_0_data[] = { 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, @@ -7730,12 +7661,12 @@ static const unsigned char changes_3_2_0_data[] = { 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, - 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 9, - 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, + 9, 9, 9, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, + 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, @@ -7797,7 +7728,7 @@ static const unsigned char changes_3_2_0_data[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, @@ -7819,14 +7750,20 @@ static const unsigned char changes_3_2_0_data[] = { 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, }; static const change_record* get_change_3_2_0(Py_UCS4 n) diff --git a/Modules/unicodename_db.h b/Modules/unicodename_db.h index 69047048..f6320c43 100644 --- a/Modules/unicodename_db.h +++ b/Modules/unicodename_db.h @@ -12,742 +12,744 @@ static const unsigned char lexicon[] = { 65, 206, 67, 79, 77, 80, 65, 84, 73, 66, 73, 76, 73, 84, 217, 83, 89, 77, 66, 79, 204, 68, 73, 71, 73, 212, 86, 79, 87, 69, 204, 84, 65, 78, 71, 85, 212, 70, 79, 82, 77, 128, 67, 65, 78, 65, 68, 73, 65, 206, 83, 89, - 76, 76, 65, 66, 73, 67, 211, 83, 73, 71, 78, 87, 82, 73, 84, 73, 78, 199, - 65, 78, 196, 84, 73, 77, 69, 211, 66, 65, 77, 85, 205, 83, 67, 82, 73, + 76, 76, 65, 66, 73, 67, 211, 65, 78, 196, 83, 73, 71, 78, 87, 82, 73, 84, + 73, 78, 199, 84, 73, 77, 69, 211, 66, 65, 77, 85, 205, 83, 67, 82, 73, 80, 212, 66, 79, 76, 196, 65, 78, 65, 84, 79, 76, 73, 65, 206, 72, 65, 78, 71, 85, 204, 78, 85, 77, 66, 69, 210, 76, 73, 78, 69, 65, 210, 67, 79, 77, 66, 73, 78, 73, 78, 199, 76, 73, 71, 65, 84, 85, 82, 197, 71, 82, 69, 69, 203, 69, 84, 72, 73, 79, 80, 73, 195, 77, 85, 83, 73, 67, 65, - 204, 70, 79, 210, 75, 72, 73, 84, 65, 206, 193, 67, 89, 82, 73, 76, 76, - 73, 195, 73, 84, 65, 76, 73, 195, 84, 65, 77, 73, 204, 76, 69, 70, 212, + 204, 67, 89, 82, 73, 76, 76, 73, 195, 70, 79, 210, 75, 72, 73, 84, 65, + 206, 193, 73, 84, 65, 76, 73, 195, 84, 65, 77, 73, 204, 76, 69, 70, 212, 78, 85, 83, 72, 213, 67, 73, 82, 67, 76, 69, 196, 82, 65, 68, 73, 67, 65, 204, 83, 65, 78, 83, 45, 83, 69, 82, 73, 198, 82, 73, 71, 72, 212, 83, - 81, 85, 65, 82, 197, 70, 73, 78, 65, 204, 84, 65, 201, 68, 79, 85, 66, - 76, 197, 65, 82, 82, 79, 87, 128, 65, 66, 79, 86, 69, 128, 83, 73, 71, - 78, 128, 86, 65, 201, 77, 79, 68, 73, 70, 73, 69, 210, 66, 69, 76, 79, + 81, 85, 65, 82, 197, 77, 79, 68, 73, 70, 73, 69, 210, 70, 73, 78, 65, + 204, 84, 65, 201, 68, 79, 85, 66, 76, 197, 83, 73, 71, 78, 128, 65, 82, + 82, 79, 87, 128, 65, 66, 79, 86, 69, 128, 86, 65, 201, 66, 69, 76, 79, 87, 128, 72, 69, 78, 84, 65, 73, 71, 65, 78, 193, 66, 76, 65, 67, 203, - 65, 82, 82, 79, 215, 87, 72, 73, 84, 197, 65, 128, 86, 65, 82, 73, 65, - 84, 73, 79, 206, 66, 82, 65, 73, 76, 76, 197, 80, 65, 84, 84, 69, 82, - 206, 85, 128, 73, 128, 75, 65, 84, 65, 75, 65, 78, 193, 66, 89, 90, 65, - 78, 84, 73, 78, 197, 79, 128, 68, 79, 212, 73, 83, 79, 76, 65, 84, 69, - 196, 77, 65, 82, 75, 128, 194, 77, 89, 65, 78, 77, 65, 210, 79, 198, 86, - 69, 82, 84, 73, 67, 65, 204, 77, 73, 68, 68, 76, 197, 75, 65, 78, 71, 88, + 87, 72, 73, 84, 197, 65, 82, 82, 79, 215, 65, 128, 85, 128, 86, 65, 82, + 73, 65, 84, 73, 79, 206, 73, 128, 66, 82, 65, 73, 76, 76, 197, 80, 65, + 84, 84, 69, 82, 206, 75, 65, 84, 65, 75, 65, 78, 193, 66, 89, 90, 65, 78, + 84, 73, 78, 197, 79, 128, 68, 79, 212, 73, 83, 79, 76, 65, 84, 69, 196, + 77, 65, 82, 75, 128, 194, 79, 198, 77, 89, 65, 78, 77, 65, 210, 86, 69, + 82, 84, 73, 67, 65, 204, 77, 73, 68, 68, 76, 197, 75, 65, 78, 71, 88, 201, 75, 73, 75, 65, 75, 85, 201, 77, 69, 78, 68, 197, 84, 73, 66, 69, 84, 65, 206, 77, 65, 82, 203, 72, 69, 65, 86, 217, 73, 78, 73, 84, 73, - 65, 204, 72, 77, 79, 78, 199, 79, 78, 197, 77, 69, 69, 205, 67, 79, 80, - 84, 73, 195, 75, 72, 77, 69, 210, 65, 66, 79, 86, 197, 82, 73, 71, 72, + 65, 204, 72, 77, 79, 78, 199, 79, 78, 197, 77, 69, 69, 205, 65, 66, 79, + 86, 197, 67, 79, 80, 84, 73, 195, 75, 72, 77, 69, 210, 82, 73, 71, 72, 84, 87, 65, 82, 68, 211, 90, 78, 65, 77, 69, 78, 78, 217, 67, 65, 82, 82, - 73, 69, 210, 89, 69, 200, 71, 69, 79, 82, 71, 73, 65, 206, 67, 72, 69, - 82, 79, 75, 69, 197, 77, 79, 78, 71, 79, 76, 73, 65, 206, 84, 87, 207, - 68, 69, 86, 65, 78, 65, 71, 65, 82, 201, 83, 84, 82, 79, 75, 69, 128, 72, - 79, 79, 75, 128, 80, 76, 85, 211, 79, 78, 69, 128, 84, 87, 79, 128, 76, + 73, 69, 210, 89, 69, 200, 68, 69, 86, 65, 78, 65, 71, 65, 82, 201, 71, + 69, 79, 82, 71, 73, 65, 206, 72, 79, 79, 75, 128, 67, 72, 69, 82, 79, 75, + 69, 197, 77, 79, 78, 71, 79, 76, 73, 65, 206, 84, 87, 207, 83, 84, 82, + 79, 75, 69, 128, 79, 78, 69, 128, 80, 76, 85, 211, 84, 87, 79, 128, 76, 79, 87, 69, 210, 66, 79, 216, 83, 81, 85, 65, 82, 69, 196, 83, 89, 77, 66, 79, 76, 128, 80, 72, 65, 83, 69, 45, 197, 84, 72, 82, 69, 197, 85, - 80, 80, 69, 210, 76, 69, 70, 84, 87, 65, 82, 68, 211, 84, 207, 67, 79, - 78, 83, 79, 78, 65, 78, 212, 77, 73, 65, 207, 86, 79, 67, 65, 76, 73, - 195, 68, 82, 65, 87, 73, 78, 71, 211, 84, 73, 76, 197, 68, 85, 80, 76, - 79, 89, 65, 206, 74, 79, 78, 71, 83, 69, 79, 78, 199, 80, 65, 82, 69, 78, - 84, 72, 69, 83, 73, 90, 69, 196, 84, 72, 65, 205, 71, 79, 78, 68, 201, - 65, 76, 69, 198, 76, 79, 215, 85, 208, 71, 76, 65, 71, 79, 76, 73, 84, - 73, 195, 72, 65, 76, 198, 72, 69, 66, 82, 69, 215, 72, 73, 71, 200, 70, - 79, 85, 82, 128, 79, 86, 69, 210, 84, 72, 82, 69, 69, 128, 73, 78, 68, + 80, 80, 69, 210, 86, 79, 67, 65, 76, 73, 195, 76, 69, 70, 84, 87, 65, 82, + 68, 211, 84, 207, 67, 79, 78, 83, 79, 78, 65, 78, 212, 77, 73, 65, 207, + 68, 82, 65, 87, 73, 78, 71, 211, 84, 73, 76, 197, 68, 85, 80, 76, 79, 89, + 65, 206, 74, 79, 78, 71, 83, 69, 79, 78, 199, 80, 65, 82, 69, 78, 84, 72, + 69, 83, 73, 90, 69, 196, 84, 72, 65, 205, 71, 79, 78, 68, 201, 76, 79, + 215, 65, 76, 69, 198, 72, 65, 76, 198, 85, 208, 70, 79, 85, 82, 128, 71, + 76, 65, 71, 79, 76, 73, 84, 73, 195, 72, 69, 66, 82, 69, 215, 72, 73, 71, + 200, 84, 72, 82, 69, 69, 128, 79, 86, 69, 210, 72, 65, 128, 73, 78, 68, 69, 216, 77, 65, 76, 65, 89, 65, 76, 65, 205, 83, 73, 89, 65, 209, 68, - 79, 87, 206, 72, 65, 128, 80, 65, 72, 65, 87, 200, 67, 72, 79, 83, 69, - 79, 78, 199, 66, 65, 76, 73, 78, 69, 83, 197, 72, 65, 76, 70, 87, 73, 68, - 84, 200, 72, 65, 78, 68, 45, 70, 73, 83, 212, 77, 69, 82, 79, 73, 84, 73, - 195, 84, 85, 82, 78, 69, 196, 70, 73, 86, 69, 128, 73, 68, 69, 79, 71, - 82, 65, 80, 72, 73, 195, 76, 73, 71, 72, 212, 73, 68, 69, 79, 71, 82, 65, - 205, 75, 65, 128, 80, 72, 65, 83, 69, 45, 196, 84, 79, 128, 65, 76, 67, - 72, 69, 77, 73, 67, 65, 204, 78, 69, 85, 77, 197, 66, 82, 65, 72, 77, - 201, 84, 79, 78, 197, 66, 65, 82, 128, 83, 73, 78, 72, 65, 76, 193, 82, - 65, 128, 78, 85, 77, 69, 82, 73, 195, 80, 65, 128, 89, 65, 128, 76, 65, - 128, 77, 65, 128, 83, 73, 88, 128, 84, 72, 85, 77, 194, 72, 85, 78, 71, - 65, 82, 73, 65, 206, 69, 73, 71, 72, 84, 128, 76, 79, 78, 199, 66, 65, - 82, 194, 72, 65, 200, 78, 65, 128, 83, 69, 86, 69, 78, 128, 66, 76, 79, - 67, 203, 68, 79, 84, 211, 78, 73, 78, 69, 128, 78, 79, 82, 84, 200, 82, - 73, 71, 72, 84, 128, 84, 72, 79, 85, 83, 65, 78, 68, 128, 83, 65, 128, - 70, 85, 76, 76, 87, 73, 68, 84, 200, 90, 90, 89, 88, 128, 90, 90, 89, 84, - 128, 90, 90, 89, 82, 88, 128, 90, 90, 89, 82, 128, 90, 90, 89, 80, 128, - 90, 90, 89, 65, 128, 90, 90, 89, 128, 90, 90, 85, 88, 128, 90, 90, 85, - 82, 88, 128, 90, 90, 85, 82, 128, 90, 90, 85, 80, 128, 90, 90, 85, 128, - 90, 90, 83, 89, 65, 128, 90, 90, 83, 65, 128, 90, 90, 79, 88, 128, 90, - 90, 79, 80, 128, 90, 90, 79, 128, 90, 90, 73, 88, 128, 90, 90, 73, 84, - 128, 90, 90, 73, 80, 128, 90, 90, 73, 69, 88, 128, 90, 90, 73, 69, 84, - 128, 90, 90, 73, 69, 80, 128, 90, 90, 73, 69, 128, 90, 90, 73, 128, 90, - 90, 69, 88, 128, 90, 90, 69, 80, 128, 90, 90, 69, 69, 128, 90, 90, 69, - 128, 90, 90, 65, 88, 128, 90, 90, 65, 84, 128, 90, 90, 65, 80, 128, 90, - 90, 65, 65, 128, 90, 90, 65, 128, 90, 89, 71, 79, 83, 128, 90, 87, 83, - 80, 128, 90, 87, 78, 74, 128, 90, 87, 78, 66, 83, 80, 128, 90, 87, 74, - 128, 90, 87, 202, 90, 87, 65, 82, 65, 75, 65, 89, 128, 90, 87, 65, 128, - 90, 85, 84, 128, 90, 85, 79, 88, 128, 90, 85, 79, 80, 128, 90, 85, 79, - 128, 90, 85, 77, 128, 90, 85, 66, 85, 82, 128, 90, 85, 53, 128, 90, 85, - 181, 90, 213, 90, 83, 72, 65, 128, 90, 82, 65, 128, 90, 81, 65, 80, 72, - 193, 90, 79, 84, 128, 90, 79, 79, 128, 90, 79, 77, 66, 73, 69, 128, 90, - 79, 65, 128, 90, 77, 69, 89, 84, 83, 65, 128, 90, 76, 65, 77, 193, 90, - 76, 65, 128, 90, 76, 193, 90, 74, 69, 128, 90, 73, 90, 50, 128, 90, 73, - 81, 65, 65, 128, 90, 73, 80, 80, 69, 82, 45, 77, 79, 85, 84, 200, 90, 73, - 78, 79, 82, 128, 90, 73, 76, 68, 69, 128, 90, 73, 71, 90, 65, 199, 90, - 73, 71, 128, 90, 73, 68, 193, 90, 73, 66, 128, 90, 73, 194, 90, 73, 51, - 128, 90, 201, 90, 72, 89, 88, 128, 90, 72, 89, 84, 128, 90, 72, 89, 82, - 88, 128, 90, 72, 89, 82, 128, 90, 72, 89, 80, 128, 90, 72, 89, 128, 90, - 72, 87, 69, 128, 90, 72, 87, 65, 128, 90, 72, 85, 88, 128, 90, 72, 85, - 84, 128, 90, 72, 85, 82, 88, 128, 90, 72, 85, 82, 128, 90, 72, 85, 80, - 128, 90, 72, 85, 79, 88, 128, 90, 72, 85, 79, 80, 128, 90, 72, 85, 79, - 128, 90, 72, 85, 128, 90, 72, 79, 88, 128, 90, 72, 79, 84, 128, 90, 72, - 79, 80, 128, 90, 72, 79, 79, 128, 90, 72, 79, 73, 128, 90, 72, 79, 128, - 90, 72, 73, 86, 69, 84, 69, 128, 90, 72, 73, 76, 128, 90, 72, 73, 128, - 90, 72, 69, 88, 128, 90, 72, 69, 84, 128, 90, 72, 69, 80, 128, 90, 72, - 69, 69, 128, 90, 72, 69, 128, 90, 72, 197, 90, 72, 65, 89, 73, 78, 128, - 90, 72, 65, 88, 128, 90, 72, 65, 84, 128, 90, 72, 65, 82, 128, 90, 72, - 65, 80, 128, 90, 72, 65, 73, 78, 128, 90, 72, 65, 65, 128, 90, 72, 65, - 128, 90, 72, 128, 90, 69, 86, 79, 75, 128, 90, 69, 85, 83, 128, 90, 69, - 84, 65, 128, 90, 69, 82, 79, 128, 90, 69, 82, 207, 90, 69, 78, 128, 90, - 69, 77, 76, 89, 65, 128, 90, 69, 77, 76, 74, 65, 128, 90, 69, 76, 79, - 128, 90, 69, 66, 82, 193, 90, 69, 50, 128, 90, 197, 90, 65, 89, 78, 128, - 90, 65, 89, 73, 78, 45, 89, 79, 68, 72, 128, 90, 65, 89, 73, 78, 128, 90, - 65, 89, 73, 206, 90, 65, 86, 73, 89, 65, 78, 73, 128, 90, 65, 84, 65, - 128, 90, 65, 82, 81, 65, 128, 90, 65, 82, 76, 128, 90, 65, 81, 69, 198, - 90, 65, 80, 89, 65, 84, 89, 77, 73, 128, 90, 65, 80, 89, 65, 84, 79, 89, - 128, 90, 65, 80, 89, 65, 84, 79, 217, 90, 65, 80, 89, 65, 84, 65, 89, 65, - 128, 90, 65, 78, 79, 90, 72, 69, 75, 128, 90, 65, 78, 65, 66, 65, 90, 65, - 210, 90, 65, 77, 88, 128, 90, 65, 76, 128, 90, 65, 204, 90, 65, 75, 82, - 89, 84, 79, 69, 128, 90, 65, 75, 82, 89, 84, 65, 89, 65, 128, 90, 65, 75, - 82, 89, 84, 65, 89, 193, 90, 65, 73, 78, 128, 90, 65, 73, 206, 90, 65, - 73, 128, 90, 65, 72, 128, 90, 65, 200, 90, 65, 71, 128, 90, 65, 69, 70, - 128, 90, 65, 68, 69, 82, 90, 72, 75, 65, 128, 90, 65, 55, 128, 90, 193, - 90, 48, 49, 54, 72, 128, 90, 48, 49, 54, 71, 128, 90, 48, 49, 54, 70, - 128, 90, 48, 49, 54, 69, 128, 90, 48, 49, 54, 68, 128, 90, 48, 49, 54, - 67, 128, 90, 48, 49, 54, 66, 128, 90, 48, 49, 54, 65, 128, 90, 48, 49, - 54, 128, 90, 48, 49, 53, 73, 128, 90, 48, 49, 53, 72, 128, 90, 48, 49, - 53, 71, 128, 90, 48, 49, 53, 70, 128, 90, 48, 49, 53, 69, 128, 90, 48, - 49, 53, 68, 128, 90, 48, 49, 53, 67, 128, 90, 48, 49, 53, 66, 128, 90, - 48, 49, 53, 65, 128, 90, 48, 49, 53, 128, 90, 48, 49, 52, 128, 90, 48, - 49, 51, 128, 90, 48, 49, 50, 128, 90, 48, 49, 49, 128, 90, 48, 49, 48, - 128, 90, 48, 48, 57, 128, 90, 48, 48, 56, 128, 90, 48, 48, 55, 128, 90, - 48, 48, 54, 128, 90, 48, 48, 53, 65, 128, 90, 48, 48, 53, 128, 90, 48, - 48, 52, 65, 128, 90, 48, 48, 52, 128, 90, 48, 48, 51, 66, 128, 90, 48, - 48, 51, 65, 128, 90, 48, 48, 51, 128, 90, 48, 48, 50, 68, 128, 90, 48, - 48, 50, 67, 128, 90, 48, 48, 50, 66, 128, 90, 48, 48, 50, 65, 128, 90, - 48, 48, 50, 128, 90, 48, 48, 49, 128, 90, 128, 218, 89, 89, 88, 128, 89, - 89, 84, 128, 89, 89, 82, 88, 128, 89, 89, 82, 128, 89, 89, 80, 128, 89, - 89, 69, 128, 89, 89, 65, 65, 128, 89, 89, 65, 128, 89, 89, 128, 89, 87, - 79, 79, 128, 89, 87, 79, 128, 89, 87, 73, 73, 128, 89, 87, 73, 128, 89, - 87, 69, 128, 89, 87, 65, 65, 128, 89, 87, 65, 128, 89, 86, 128, 89, 85, - 88, 128, 89, 85, 87, 79, 81, 128, 89, 85, 85, 75, 65, 76, 69, 65, 80, 73, - 78, 84, 85, 128, 89, 85, 85, 128, 89, 85, 84, 128, 89, 85, 83, 128, 89, - 85, 211, 89, 85, 82, 88, 128, 89, 85, 82, 128, 89, 85, 81, 128, 89, 85, - 209, 89, 85, 80, 128, 89, 85, 79, 88, 128, 89, 85, 79, 84, 128, 89, 85, - 79, 80, 128, 89, 85, 79, 77, 128, 89, 85, 79, 128, 89, 85, 78, 128, 89, - 85, 77, 128, 89, 85, 74, 128, 89, 85, 73, 128, 89, 85, 69, 81, 128, 89, - 85, 69, 128, 89, 85, 68, 72, 128, 89, 85, 68, 200, 89, 85, 65, 78, 128, - 89, 85, 65, 69, 78, 128, 89, 85, 45, 89, 69, 79, 128, 89, 85, 45, 89, 69, - 128, 89, 85, 45, 85, 128, 89, 85, 45, 79, 128, 89, 85, 45, 73, 128, 89, - 85, 45, 69, 79, 128, 89, 85, 45, 69, 128, 89, 85, 45, 65, 69, 128, 89, - 85, 45, 65, 128, 89, 85, 45, 52, 128, 89, 85, 45, 51, 128, 89, 85, 45, - 50, 128, 89, 85, 45, 49, 128, 89, 85, 128, 89, 213, 89, 82, 89, 128, 89, - 80, 83, 73, 76, 73, 128, 89, 80, 79, 82, 82, 79, 73, 128, 89, 80, 79, 75, - 82, 73, 83, 73, 83, 128, 89, 80, 79, 75, 82, 73, 83, 73, 211, 89, 80, 79, - 71, 69, 71, 82, 65, 77, 77, 69, 78, 73, 128, 89, 79, 89, 128, 89, 79, 88, - 128, 89, 79, 87, 68, 128, 89, 79, 85, 84, 72, 70, 85, 76, 78, 69, 83, 83, - 128, 89, 79, 85, 84, 72, 70, 85, 204, 89, 79, 213, 89, 79, 84, 128, 89, - 79, 212, 89, 79, 82, 73, 128, 89, 79, 81, 128, 89, 79, 209, 89, 79, 80, - 128, 89, 79, 79, 128, 89, 79, 77, 79, 128, 89, 79, 71, 72, 128, 89, 79, - 68, 128, 89, 79, 196, 89, 79, 65, 128, 89, 79, 45, 89, 79, 128, 89, 79, - 45, 89, 69, 79, 128, 89, 79, 45, 89, 65, 69, 128, 89, 79, 45, 89, 65, - 128, 89, 79, 45, 79, 128, 89, 79, 45, 73, 128, 89, 79, 45, 69, 79, 128, - 89, 79, 45, 65, 69, 128, 89, 79, 45, 65, 128, 89, 79, 45, 54, 128, 89, - 79, 45, 53, 128, 89, 79, 45, 52, 128, 89, 79, 45, 51, 128, 89, 79, 45, - 50, 128, 89, 79, 45, 49, 128, 89, 207, 89, 73, 90, 69, 84, 128, 89, 73, - 88, 128, 89, 73, 87, 78, 128, 89, 73, 84, 128, 89, 73, 80, 128, 89, 73, - 78, 71, 128, 89, 73, 73, 128, 89, 73, 72, 128, 89, 73, 199, 89, 73, 69, - 88, 128, 89, 73, 69, 84, 128, 89, 73, 69, 80, 128, 89, 73, 69, 69, 128, - 89, 73, 69, 128, 89, 73, 68, 68, 73, 83, 200, 89, 73, 45, 85, 128, 89, - 73, 128, 89, 72, 69, 128, 89, 72, 65, 128, 89, 70, 69, 83, 73, 83, 128, - 89, 70, 69, 83, 73, 211, 89, 70, 69, 206, 89, 69, 90, 73, 68, 201, 89, - 69, 89, 128, 89, 69, 87, 128, 89, 69, 85, 88, 128, 89, 69, 85, 82, 65, - 69, 128, 89, 69, 85, 81, 128, 89, 69, 85, 77, 128, 89, 69, 85, 65, 69, - 84, 128, 89, 69, 85, 65, 69, 128, 89, 69, 84, 73, 86, 128, 89, 69, 83, - 84, 85, 128, 89, 69, 83, 73, 69, 85, 78, 71, 45, 83, 83, 65, 78, 71, 75, - 73, 89, 69, 79, 75, 128, 89, 69, 83, 73, 69, 85, 78, 71, 45, 83, 73, 79, - 83, 128, 89, 69, 83, 73, 69, 85, 78, 71, 45, 80, 65, 78, 83, 73, 79, 83, - 128, 89, 69, 83, 73, 69, 85, 78, 71, 45, 77, 73, 69, 85, 77, 128, 89, 69, - 83, 73, 69, 85, 78, 71, 45, 75, 73, 89, 69, 79, 75, 128, 89, 69, 83, 73, - 69, 85, 78, 71, 45, 75, 72, 73, 69, 85, 75, 72, 128, 89, 69, 83, 73, 69, - 85, 78, 71, 45, 72, 73, 69, 85, 72, 128, 89, 69, 83, 73, 69, 85, 78, 71, - 128, 89, 69, 82, 85, 128, 89, 69, 82, 213, 89, 69, 82, 73, 128, 89, 69, - 82, 65, 200, 89, 69, 82, 128, 89, 69, 79, 82, 73, 78, 72, 73, 69, 85, 72, - 128, 89, 69, 79, 45, 89, 65, 128, 89, 69, 79, 45, 85, 128, 89, 69, 79, - 45, 79, 128, 89, 69, 78, 73, 83, 69, 201, 89, 69, 78, 65, 80, 128, 89, - 69, 78, 128, 89, 69, 206, 89, 69, 76, 76, 79, 87, 128, 89, 69, 76, 76, - 79, 215, 89, 69, 73, 78, 128, 89, 69, 72, 128, 89, 69, 69, 71, 128, 89, - 69, 69, 128, 89, 69, 65, 210, 89, 69, 65, 128, 89, 65, 90, 90, 128, 89, - 65, 90, 72, 128, 89, 65, 90, 128, 89, 65, 89, 68, 128, 89, 65, 89, 65, - 78, 78, 65, 128, 89, 65, 89, 128, 89, 65, 87, 78, 73, 78, 199, 89, 65, - 87, 78, 128, 89, 65, 87, 128, 89, 65, 86, 128, 89, 65, 85, 128, 89, 65, - 84, 84, 128, 89, 65, 84, 73, 128, 89, 65, 84, 72, 128, 89, 65, 84, 128, - 89, 65, 83, 83, 128, 89, 65, 83, 72, 128, 89, 65, 83, 128, 89, 65, 82, - 82, 128, 89, 65, 82, 78, 128, 89, 65, 82, 128, 89, 65, 210, 89, 65, 81, - 128, 89, 65, 80, 128, 89, 65, 78, 83, 65, 89, 65, 128, 89, 65, 78, 71, - 128, 89, 65, 78, 199, 89, 65, 78, 128, 89, 65, 77, 79, 75, 128, 89, 65, - 77, 65, 75, 75, 65, 78, 128, 89, 65, 77, 128, 89, 65, 76, 128, 89, 65, - 75, 72, 72, 128, 89, 65, 75, 72, 128, 89, 65, 75, 65, 83, 72, 128, 89, - 65, 75, 128, 89, 65, 74, 85, 82, 86, 69, 68, 73, 195, 89, 65, 74, 128, - 89, 65, 73, 128, 89, 65, 72, 72, 128, 89, 65, 72, 128, 89, 65, 71, 78, - 128, 89, 65, 71, 72, 72, 128, 89, 65, 71, 72, 128, 89, 65, 71, 128, 89, - 65, 70, 213, 89, 65, 70, 128, 89, 65, 69, 77, 77, 65, 69, 128, 89, 65, - 68, 72, 128, 89, 65, 68, 68, 72, 128, 89, 65, 68, 68, 128, 89, 65, 68, - 128, 89, 65, 67, 72, 128, 89, 65, 66, 72, 128, 89, 65, 66, 128, 89, 65, - 65, 82, 85, 128, 89, 65, 65, 73, 128, 89, 65, 65, 68, 79, 128, 89, 65, - 45, 89, 79, 128, 89, 65, 45, 85, 128, 89, 65, 45, 79, 128, 89, 65, 45, - 53, 128, 89, 65, 45, 52, 128, 89, 65, 45, 51, 128, 89, 65, 45, 50, 128, - 89, 65, 45, 49, 128, 89, 48, 48, 56, 128, 89, 48, 48, 55, 128, 89, 48, - 48, 54, 128, 89, 48, 48, 53, 128, 89, 48, 48, 52, 128, 89, 48, 48, 51, - 128, 89, 48, 48, 50, 128, 89, 48, 48, 49, 65, 128, 89, 48, 48, 49, 128, - 89, 45, 67, 82, 69, 197, 88, 89, 88, 128, 88, 89, 85, 128, 88, 89, 84, - 128, 88, 89, 82, 88, 128, 88, 89, 82, 128, 88, 89, 80, 128, 88, 89, 79, - 79, 74, 128, 88, 89, 79, 79, 128, 88, 89, 79, 128, 88, 89, 73, 128, 88, - 89, 69, 69, 205, 88, 89, 69, 69, 128, 88, 89, 69, 128, 88, 89, 65, 65, - 128, 88, 89, 65, 128, 88, 89, 128, 88, 87, 73, 128, 88, 87, 69, 69, 128, - 88, 87, 69, 128, 88, 87, 65, 65, 128, 88, 87, 65, 128, 88, 87, 128, 88, - 215, 88, 86, 69, 128, 88, 86, 65, 128, 88, 85, 79, 88, 128, 88, 85, 79, - 128, 88, 85, 128, 88, 83, 72, 65, 65, 89, 65, 84, 72, 73, 89, 65, 128, - 88, 79, 88, 128, 88, 79, 84, 128, 88, 79, 82, 128, 88, 79, 80, 72, 128, - 88, 79, 80, 128, 88, 79, 65, 128, 88, 79, 128, 88, 73, 88, 128, 88, 73, - 84, 128, 88, 73, 82, 79, 206, 88, 73, 80, 128, 88, 73, 69, 88, 128, 88, - 73, 69, 84, 128, 88, 73, 69, 80, 128, 88, 73, 69, 128, 88, 73, 65, 78, - 71, 81, 201, 88, 73, 65, 66, 128, 88, 73, 128, 88, 72, 69, 89, 78, 128, - 88, 71, 128, 88, 69, 89, 78, 128, 88, 69, 83, 84, 69, 211, 88, 69, 72, - 128, 88, 69, 69, 128, 88, 69, 128, 88, 65, 85, 83, 128, 88, 65, 85, 128, - 88, 65, 80, 72, 128, 88, 65, 78, 128, 88, 65, 65, 128, 88, 65, 128, 88, - 48, 48, 56, 65, 128, 88, 48, 48, 56, 128, 88, 48, 48, 55, 128, 88, 48, - 48, 54, 65, 128, 88, 48, 48, 54, 128, 88, 48, 48, 53, 128, 88, 48, 48, - 52, 66, 128, 88, 48, 48, 52, 65, 128, 88, 48, 48, 52, 128, 88, 48, 48, - 51, 128, 88, 48, 48, 50, 128, 88, 48, 48, 49, 128, 88, 45, 216, 88, 45, - 82, 65, 89, 128, 87, 90, 128, 87, 89, 78, 78, 128, 87, 89, 78, 206, 87, - 86, 73, 128, 87, 86, 69, 128, 87, 86, 65, 128, 87, 86, 128, 87, 85, 80, - 128, 87, 85, 79, 88, 128, 87, 85, 79, 80, 128, 87, 85, 79, 128, 87, 85, - 78, 74, 207, 87, 85, 78, 128, 87, 85, 76, 85, 128, 87, 85, 76, 213, 87, - 85, 73, 128, 87, 85, 69, 128, 87, 85, 65, 69, 84, 128, 87, 85, 65, 69, - 78, 128, 87, 85, 128, 87, 82, 217, 87, 82, 79, 78, 71, 128, 87, 82, 73, - 83, 212, 87, 82, 73, 78, 75, 76, 69, 83, 128, 87, 82, 73, 78, 75, 76, 69, - 211, 87, 82, 73, 78, 75, 76, 69, 68, 128, 87, 82, 69, 83, 84, 76, 69, 82, - 83, 128, 87, 82, 69, 78, 67, 72, 128, 87, 82, 69, 65, 84, 200, 87, 82, - 65, 80, 80, 69, 196, 87, 82, 65, 80, 128, 87, 79, 88, 128, 87, 79, 87, - 128, 87, 79, 82, 83, 72, 73, 80, 128, 87, 79, 82, 82, 73, 69, 196, 87, - 79, 82, 77, 128, 87, 79, 82, 76, 196, 87, 79, 82, 75, 69, 82, 128, 87, - 79, 82, 75, 128, 87, 79, 82, 203, 87, 79, 82, 68, 83, 80, 65, 67, 69, - 128, 87, 79, 82, 196, 87, 79, 80, 128, 87, 79, 79, 78, 128, 87, 79, 79, - 76, 128, 87, 79, 79, 68, 83, 45, 67, 82, 69, 197, 87, 79, 79, 68, 128, - 87, 79, 78, 128, 87, 79, 206, 87, 79, 77, 69, 78, 211, 87, 79, 77, 69, - 206, 87, 79, 77, 65, 78, 211, 87, 79, 77, 65, 78, 128, 87, 79, 77, 65, - 206, 87, 79, 76, 79, 83, 79, 128, 87, 79, 76, 198, 87, 79, 69, 128, 87, - 79, 65, 128, 87, 79, 45, 55, 128, 87, 79, 45, 54, 128, 87, 79, 45, 53, - 128, 87, 79, 45, 52, 128, 87, 79, 45, 51, 128, 87, 79, 45, 50, 128, 87, - 79, 45, 49, 128, 87, 73, 84, 72, 79, 85, 212, 87, 73, 84, 72, 73, 78, - 128, 87, 73, 84, 72, 73, 206, 87, 73, 82, 69, 196, 87, 73, 78, 84, 69, - 82, 128, 87, 73, 78, 75, 73, 78, 199, 87, 73, 78, 75, 128, 87, 73, 78, - 74, 65, 128, 87, 73, 78, 71, 83, 128, 87, 73, 78, 69, 128, 87, 73, 78, - 197, 87, 73, 78, 68, 85, 128, 87, 73, 78, 68, 79, 87, 128, 87, 73, 78, - 68, 128, 87, 73, 78, 196, 87, 73, 78, 128, 87, 73, 76, 84, 69, 196, 87, - 73, 71, 78, 89, 65, 78, 128, 87, 73, 71, 71, 76, 217, 87, 73, 71, 71, 76, - 69, 83, 128, 87, 73, 68, 84, 72, 128, 87, 73, 68, 69, 78, 73, 78, 199, - 87, 73, 68, 69, 45, 72, 69, 65, 68, 69, 196, 87, 73, 68, 197, 87, 73, 65, - 78, 71, 87, 65, 65, 75, 128, 87, 73, 65, 78, 71, 128, 87, 73, 45, 53, - 128, 87, 73, 45, 52, 128, 87, 73, 45, 51, 128, 87, 73, 45, 50, 128, 87, - 73, 45, 49, 128, 87, 72, 79, 76, 197, 87, 72, 73, 84, 69, 45, 70, 69, 65, - 84, 72, 69, 82, 69, 196, 87, 72, 73, 84, 69, 128, 87, 72, 69, 69, 76, 69, - 196, 87, 72, 69, 69, 76, 67, 72, 65, 73, 82, 128, 87, 72, 69, 69, 76, 67, - 72, 65, 73, 210, 87, 72, 69, 69, 76, 128, 87, 72, 69, 69, 204, 87, 72, - 69, 65, 84, 128, 87, 72, 65, 76, 69, 128, 87, 72, 128, 87, 71, 128, 87, - 69, 88, 128, 87, 69, 85, 88, 128, 87, 69, 212, 87, 69, 83, 84, 69, 82, - 206, 87, 69, 83, 84, 45, 67, 82, 69, 197, 87, 69, 83, 84, 128, 87, 69, - 83, 212, 87, 69, 80, 128, 87, 69, 79, 128, 87, 69, 78, 128, 87, 69, 76, - 76, 128, 87, 69, 73, 71, 72, 212, 87, 69, 73, 69, 82, 83, 84, 82, 65, 83, - 211, 87, 69, 73, 128, 87, 69, 69, 78, 128, 87, 69, 68, 71, 69, 45, 84, - 65, 73, 76, 69, 196, 87, 69, 68, 71, 69, 128, 87, 69, 68, 68, 73, 78, 71, - 128, 87, 69, 66, 128, 87, 69, 65, 82, 217, 87, 69, 65, 80, 79, 78, 128, - 87, 69, 45, 52, 128, 87, 69, 45, 51, 128, 87, 69, 45, 50, 128, 87, 69, - 45, 49, 128, 87, 67, 128, 87, 66, 128, 87, 65, 89, 128, 87, 65, 217, 87, - 65, 88, 73, 78, 199, 87, 65, 88, 128, 87, 65, 87, 45, 65, 89, 73, 78, 45, - 82, 69, 83, 72, 128, 87, 65, 87, 128, 87, 65, 215, 87, 65, 86, 217, 87, - 65, 86, 73, 78, 199, 87, 65, 86, 69, 83, 128, 87, 65, 86, 69, 128, 87, - 65, 86, 197, 87, 65, 85, 128, 87, 65, 84, 84, 79, 128, 87, 65, 84, 69, - 82, 77, 69, 76, 79, 78, 128, 87, 65, 84, 69, 82, 128, 87, 65, 84, 69, - 210, 87, 65, 84, 67, 72, 128, 87, 65, 84, 128, 87, 65, 83, 84, 73, 78, - 71, 128, 87, 65, 83, 84, 69, 66, 65, 83, 75, 69, 84, 128, 87, 65, 83, 83, - 65, 76, 76, 65, 77, 128, 87, 65, 83, 76, 65, 128, 87, 65, 83, 76, 193, - 87, 65, 83, 65, 76, 76, 65, 77, 128, 87, 65, 83, 65, 76, 76, 65, 205, 87, - 65, 83, 45, 83, 65, 76, 65, 65, 77, 128, 87, 65, 82, 78, 73, 78, 199, 87, - 65, 82, 65, 78, 199, 87, 65, 81, 70, 65, 128, 87, 65, 80, 128, 87, 65, - 78, 73, 78, 199, 87, 65, 78, 71, 75, 85, 79, 81, 128, 87, 65, 78, 68, 69, - 82, 69, 82, 128, 87, 65, 78, 68, 128, 87, 65, 78, 67, 72, 207, 87, 65, - 78, 128, 87, 65, 76, 76, 80, 76, 65, 78, 197, 87, 65, 76, 76, 128, 87, - 65, 76, 204, 87, 65, 76, 75, 128, 87, 65, 76, 203, 87, 65, 73, 84, 73, - 78, 71, 128, 87, 65, 73, 83, 84, 128, 87, 65, 73, 128, 87, 65, 70, 70, - 76, 69, 128, 87, 65, 69, 78, 128, 87, 65, 69, 128, 87, 65, 68, 68, 65, - 128, 87, 65, 65, 86, 85, 128, 87, 65, 65, 74, 73, 66, 128, 87, 65, 65, - 65, 76, 73, 72, 69, 197, 87, 65, 45, 84, 65, 65, 65, 76, 65, 65, 128, 87, - 65, 45, 83, 65, 76, 76, 65, 77, 128, 87, 65, 45, 65, 65, 76, 73, 72, 128, - 87, 65, 45, 53, 128, 87, 65, 45, 52, 128, 87, 65, 45, 51, 128, 87, 65, - 45, 50, 128, 87, 65, 45, 49, 128, 87, 193, 87, 48, 50, 53, 128, 87, 48, - 50, 52, 65, 128, 87, 48, 50, 52, 128, 87, 48, 50, 51, 128, 87, 48, 50, - 50, 128, 87, 48, 50, 49, 128, 87, 48, 50, 48, 128, 87, 48, 49, 57, 128, - 87, 48, 49, 56, 65, 128, 87, 48, 49, 56, 128, 87, 48, 49, 55, 65, 128, - 87, 48, 49, 55, 128, 87, 48, 49, 54, 128, 87, 48, 49, 53, 128, 87, 48, - 49, 52, 65, 128, 87, 48, 49, 52, 128, 87, 48, 49, 51, 128, 87, 48, 49, - 50, 128, 87, 48, 49, 49, 128, 87, 48, 49, 48, 65, 128, 87, 48, 49, 48, - 128, 87, 48, 48, 57, 65, 128, 87, 48, 48, 57, 128, 87, 48, 48, 56, 128, - 87, 48, 48, 55, 128, 87, 48, 48, 54, 128, 87, 48, 48, 53, 128, 87, 48, - 48, 52, 128, 87, 48, 48, 51, 65, 128, 87, 48, 48, 51, 128, 87, 48, 48, - 50, 128, 87, 48, 48, 49, 128, 86, 90, 77, 69, 84, 128, 86, 90, 128, 86, - 89, 88, 128, 86, 89, 84, 128, 86, 89, 83, 79, 75, 79, 128, 86, 89, 83, - 79, 75, 207, 86, 89, 82, 88, 128, 86, 89, 82, 128, 86, 89, 80, 128, 86, - 89, 128, 86, 88, 128, 86, 87, 74, 128, 86, 87, 65, 128, 86, 87, 128, 86, - 85, 88, 128, 86, 85, 85, 128, 86, 85, 84, 128, 86, 85, 82, 88, 128, 86, - 85, 82, 128, 86, 85, 80, 128, 86, 85, 76, 71, 65, 210, 86, 85, 76, 67, - 65, 78, 85, 83, 128, 86, 85, 69, 81, 128, 86, 84, 83, 128, 86, 84, 128, - 86, 83, 57, 57, 128, 86, 83, 57, 56, 128, 86, 83, 57, 55, 128, 86, 83, - 57, 54, 128, 86, 83, 57, 53, 128, 86, 83, 57, 52, 128, 86, 83, 57, 51, - 128, 86, 83, 57, 50, 128, 86, 83, 57, 49, 128, 86, 83, 57, 48, 128, 86, - 83, 57, 128, 86, 83, 56, 57, 128, 86, 83, 56, 56, 128, 86, 83, 56, 55, - 128, 86, 83, 56, 54, 128, 86, 83, 56, 53, 128, 86, 83, 56, 52, 128, 86, - 83, 56, 51, 128, 86, 83, 56, 50, 128, 86, 83, 56, 49, 128, 86, 83, 56, - 48, 128, 86, 83, 56, 128, 86, 83, 55, 57, 128, 86, 83, 55, 56, 128, 86, - 83, 55, 55, 128, 86, 83, 55, 54, 128, 86, 83, 55, 53, 128, 86, 83, 55, - 52, 128, 86, 83, 55, 51, 128, 86, 83, 55, 50, 128, 86, 83, 55, 49, 128, - 86, 83, 55, 48, 128, 86, 83, 55, 128, 86, 83, 54, 57, 128, 86, 83, 54, - 56, 128, 86, 83, 54, 55, 128, 86, 83, 54, 54, 128, 86, 83, 54, 53, 128, - 86, 83, 54, 52, 128, 86, 83, 54, 51, 128, 86, 83, 54, 50, 128, 86, 83, - 54, 49, 128, 86, 83, 54, 48, 128, 86, 83, 54, 128, 86, 83, 53, 57, 128, - 86, 83, 53, 56, 128, 86, 83, 53, 55, 128, 86, 83, 53, 54, 128, 86, 83, - 53, 53, 128, 86, 83, 53, 52, 128, 86, 83, 53, 51, 128, 86, 83, 53, 50, - 128, 86, 83, 53, 49, 128, 86, 83, 53, 48, 128, 86, 83, 53, 128, 86, 83, - 52, 57, 128, 86, 83, 52, 56, 128, 86, 83, 52, 55, 128, 86, 83, 52, 54, - 128, 86, 83, 52, 53, 128, 86, 83, 52, 52, 128, 86, 83, 52, 51, 128, 86, - 83, 52, 50, 128, 86, 83, 52, 49, 128, 86, 83, 52, 48, 128, 86, 83, 52, - 128, 86, 83, 51, 57, 128, 86, 83, 51, 56, 128, 86, 83, 51, 55, 128, 86, - 83, 51, 54, 128, 86, 83, 51, 53, 128, 86, 83, 51, 52, 128, 86, 83, 51, - 51, 128, 86, 83, 51, 50, 128, 86, 83, 51, 49, 128, 86, 83, 51, 48, 128, - 86, 83, 51, 128, 86, 83, 50, 57, 128, 86, 83, 50, 56, 128, 86, 83, 50, - 55, 128, 86, 83, 50, 54, 128, 86, 83, 50, 53, 54, 128, 86, 83, 50, 53, - 53, 128, 86, 83, 50, 53, 52, 128, 86, 83, 50, 53, 51, 128, 86, 83, 50, - 53, 50, 128, 86, 83, 50, 53, 49, 128, 86, 83, 50, 53, 48, 128, 86, 83, - 50, 53, 128, 86, 83, 50, 52, 57, 128, 86, 83, 50, 52, 56, 128, 86, 83, - 50, 52, 55, 128, 86, 83, 50, 52, 54, 128, 86, 83, 50, 52, 53, 128, 86, - 83, 50, 52, 52, 128, 86, 83, 50, 52, 51, 128, 86, 83, 50, 52, 50, 128, - 86, 83, 50, 52, 49, 128, 86, 83, 50, 52, 48, 128, 86, 83, 50, 52, 128, - 86, 83, 50, 51, 57, 128, 86, 83, 50, 51, 56, 128, 86, 83, 50, 51, 55, - 128, 86, 83, 50, 51, 54, 128, 86, 83, 50, 51, 53, 128, 86, 83, 50, 51, - 52, 128, 86, 83, 50, 51, 51, 128, 86, 83, 50, 51, 50, 128, 86, 83, 50, - 51, 49, 128, 86, 83, 50, 51, 48, 128, 86, 83, 50, 51, 128, 86, 83, 50, - 50, 57, 128, 86, 83, 50, 50, 56, 128, 86, 83, 50, 50, 55, 128, 86, 83, - 50, 50, 54, 128, 86, 83, 50, 50, 53, 128, 86, 83, 50, 50, 52, 128, 86, - 83, 50, 50, 51, 128, 86, 83, 50, 50, 50, 128, 86, 83, 50, 50, 49, 128, - 86, 83, 50, 50, 48, 128, 86, 83, 50, 50, 128, 86, 83, 50, 49, 57, 128, - 86, 83, 50, 49, 56, 128, 86, 83, 50, 49, 55, 128, 86, 83, 50, 49, 54, - 128, 86, 83, 50, 49, 53, 128, 86, 83, 50, 49, 52, 128, 86, 83, 50, 49, - 51, 128, 86, 83, 50, 49, 50, 128, 86, 83, 50, 49, 49, 128, 86, 83, 50, - 49, 48, 128, 86, 83, 50, 49, 128, 86, 83, 50, 48, 57, 128, 86, 83, 50, - 48, 56, 128, 86, 83, 50, 48, 55, 128, 86, 83, 50, 48, 54, 128, 86, 83, - 50, 48, 53, 128, 86, 83, 50, 48, 52, 128, 86, 83, 50, 48, 51, 128, 86, - 83, 50, 48, 50, 128, 86, 83, 50, 48, 49, 128, 86, 83, 50, 48, 48, 128, - 86, 83, 50, 48, 128, 86, 83, 50, 128, 86, 83, 49, 57, 57, 128, 86, 83, - 49, 57, 56, 128, 86, 83, 49, 57, 55, 128, 86, 83, 49, 57, 54, 128, 86, - 83, 49, 57, 53, 128, 86, 83, 49, 57, 52, 128, 86, 83, 49, 57, 51, 128, - 86, 83, 49, 57, 50, 128, 86, 83, 49, 57, 49, 128, 86, 83, 49, 57, 48, - 128, 86, 83, 49, 57, 128, 86, 83, 49, 56, 57, 128, 86, 83, 49, 56, 56, - 128, 86, 83, 49, 56, 55, 128, 86, 83, 49, 56, 54, 128, 86, 83, 49, 56, - 53, 128, 86, 83, 49, 56, 52, 128, 86, 83, 49, 56, 51, 128, 86, 83, 49, - 56, 50, 128, 86, 83, 49, 56, 49, 128, 86, 83, 49, 56, 48, 128, 86, 83, - 49, 56, 128, 86, 83, 49, 55, 57, 128, 86, 83, 49, 55, 56, 128, 86, 83, - 49, 55, 55, 128, 86, 83, 49, 55, 54, 128, 86, 83, 49, 55, 53, 128, 86, - 83, 49, 55, 52, 128, 86, 83, 49, 55, 51, 128, 86, 83, 49, 55, 50, 128, - 86, 83, 49, 55, 49, 128, 86, 83, 49, 55, 48, 128, 86, 83, 49, 55, 128, - 86, 83, 49, 54, 57, 128, 86, 83, 49, 54, 56, 128, 86, 83, 49, 54, 55, - 128, 86, 83, 49, 54, 54, 128, 86, 83, 49, 54, 53, 128, 86, 83, 49, 54, - 52, 128, 86, 83, 49, 54, 51, 128, 86, 83, 49, 54, 50, 128, 86, 83, 49, - 54, 49, 128, 86, 83, 49, 54, 48, 128, 86, 83, 49, 54, 128, 86, 83, 49, - 53, 57, 128, 86, 83, 49, 53, 56, 128, 86, 83, 49, 53, 55, 128, 86, 83, - 49, 53, 54, 128, 86, 83, 49, 53, 53, 128, 86, 83, 49, 53, 52, 128, 86, - 83, 49, 53, 51, 128, 86, 83, 49, 53, 50, 128, 86, 83, 49, 53, 49, 128, - 86, 83, 49, 53, 48, 128, 86, 83, 49, 53, 128, 86, 83, 49, 52, 57, 128, - 86, 83, 49, 52, 56, 128, 86, 83, 49, 52, 55, 128, 86, 83, 49, 52, 54, - 128, 86, 83, 49, 52, 53, 128, 86, 83, 49, 52, 52, 128, 86, 83, 49, 52, - 51, 128, 86, 83, 49, 52, 50, 128, 86, 83, 49, 52, 49, 128, 86, 83, 49, - 52, 48, 128, 86, 83, 49, 52, 128, 86, 83, 49, 51, 57, 128, 86, 83, 49, - 51, 56, 128, 86, 83, 49, 51, 55, 128, 86, 83, 49, 51, 54, 128, 86, 83, - 49, 51, 53, 128, 86, 83, 49, 51, 52, 128, 86, 83, 49, 51, 51, 128, 86, - 83, 49, 51, 50, 128, 86, 83, 49, 51, 49, 128, 86, 83, 49, 51, 48, 128, - 86, 83, 49, 51, 128, 86, 83, 49, 50, 57, 128, 86, 83, 49, 50, 56, 128, - 86, 83, 49, 50, 55, 128, 86, 83, 49, 50, 54, 128, 86, 83, 49, 50, 53, - 128, 86, 83, 49, 50, 52, 128, 86, 83, 49, 50, 51, 128, 86, 83, 49, 50, - 50, 128, 86, 83, 49, 50, 49, 128, 86, 83, 49, 50, 48, 128, 86, 83, 49, - 50, 128, 86, 83, 49, 49, 57, 128, 86, 83, 49, 49, 56, 128, 86, 83, 49, - 49, 55, 128, 86, 83, 49, 49, 54, 128, 86, 83, 49, 49, 53, 128, 86, 83, - 49, 49, 52, 128, 86, 83, 49, 49, 51, 128, 86, 83, 49, 49, 50, 128, 86, - 83, 49, 49, 49, 128, 86, 83, 49, 49, 48, 128, 86, 83, 49, 49, 128, 86, - 83, 49, 48, 57, 128, 86, 83, 49, 48, 56, 128, 86, 83, 49, 48, 55, 128, - 86, 83, 49, 48, 54, 128, 86, 83, 49, 48, 53, 128, 86, 83, 49, 48, 52, - 128, 86, 83, 49, 48, 51, 128, 86, 83, 49, 48, 50, 128, 86, 83, 49, 48, - 49, 128, 86, 83, 49, 48, 48, 128, 86, 83, 49, 48, 128, 86, 83, 49, 128, - 86, 83, 128, 86, 82, 65, 75, 72, 73, 89, 193, 86, 82, 65, 67, 72, 89, - 128, 86, 81, 128, 86, 79, 88, 128, 86, 79, 87, 69, 76, 45, 67, 65, 82, - 82, 73, 69, 210, 86, 79, 87, 128, 86, 79, 85, 128, 86, 79, 84, 128, 86, - 79, 211, 86, 79, 80, 128, 86, 79, 79, 73, 128, 86, 79, 79, 128, 86, 79, - 77, 73, 84, 73, 78, 71, 128, 86, 79, 77, 128, 86, 79, 76, 85, 77, 197, - 86, 79, 76, 84, 65, 71, 197, 86, 79, 76, 76, 69, 89, 66, 65, 76, 76, 128, - 86, 79, 76, 67, 65, 78, 79, 128, 86, 79, 76, 65, 80, 85, 203, 86, 79, 73, - 68, 69, 196, 86, 79, 73, 196, 86, 79, 73, 67, 73, 78, 71, 128, 86, 79, - 73, 67, 69, 76, 69, 83, 211, 86, 79, 73, 67, 69, 196, 86, 79, 68, 128, - 86, 79, 67, 65, 76, 73, 90, 65, 84, 73, 79, 206, 86, 79, 67, 65, 204, 86, - 79, 128, 86, 73, 89, 79, 128, 86, 73, 88, 128, 86, 73, 84, 82, 73, 79, - 76, 45, 50, 128, 86, 73, 84, 82, 73, 79, 76, 128, 86, 73, 84, 72, 75, 85, - 81, 201, 86, 73, 84, 65, 69, 45, 50, 128, 86, 73, 84, 65, 69, 128, 86, - 73, 84, 128, 86, 73, 83, 73, 71, 79, 84, 72, 73, 195, 86, 73, 83, 65, 82, - 71, 65, 89, 65, 128, 86, 73, 83, 65, 82, 71, 65, 128, 86, 73, 83, 65, 82, - 71, 193, 86, 73, 82, 73, 65, 77, 128, 86, 73, 82, 71, 79, 128, 86, 73, - 82, 71, 65, 128, 86, 73, 82, 65, 77, 65, 128, 86, 73, 80, 128, 86, 73, - 79, 76, 73, 78, 128, 86, 73, 78, 69, 71, 65, 82, 45, 51, 128, 86, 73, 78, - 69, 71, 65, 82, 45, 50, 128, 86, 73, 78, 69, 71, 65, 82, 128, 86, 73, 78, - 69, 71, 65, 210, 86, 73, 78, 69, 128, 86, 73, 78, 197, 86, 73, 78, 128, - 86, 73, 76, 76, 65, 71, 69, 128, 86, 73, 73, 128, 86, 73, 71, 73, 78, 84, - 73, 76, 69, 128, 86, 73, 69, 88, 128, 86, 73, 69, 87, 73, 78, 199, 86, - 73, 69, 87, 69, 82, 128, 86, 73, 69, 87, 68, 65, 84, 193, 86, 73, 69, 84, - 78, 65, 77, 69, 83, 197, 86, 73, 69, 84, 128, 86, 73, 69, 212, 86, 73, - 69, 80, 128, 86, 73, 69, 128, 86, 73, 68, 74, 45, 50, 128, 86, 73, 68, - 74, 128, 86, 73, 68, 69, 79, 67, 65, 83, 83, 69, 84, 84, 69, 128, 86, 73, - 68, 69, 207, 86, 73, 68, 65, 128, 86, 73, 67, 84, 79, 82, 217, 86, 73, - 66, 82, 65, 84, 73, 79, 206, 86, 72, 65, 128, 86, 70, 65, 128, 86, 69, - 89, 90, 128, 86, 69, 88, 128, 86, 69, 87, 128, 86, 69, 215, 86, 69, 85, - 88, 128, 86, 69, 85, 77, 128, 86, 69, 85, 65, 69, 80, 69, 78, 128, 86, - 69, 85, 65, 69, 128, 86, 69, 83, 84, 65, 128, 86, 69, 83, 84, 128, 86, - 69, 83, 83, 69, 204, 86, 69, 82, 217, 86, 69, 82, 84, 73, 67, 65, 76, 76, - 89, 128, 86, 69, 82, 84, 73, 67, 65, 76, 76, 217, 86, 69, 82, 84, 73, 67, - 65, 76, 45, 48, 54, 45, 48, 54, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, - 48, 54, 45, 48, 53, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 54, 45, - 48, 52, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 54, 45, 48, 51, 128, - 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 54, 45, 48, 50, 128, 86, 69, 82, - 84, 73, 67, 65, 76, 45, 48, 54, 45, 48, 49, 128, 86, 69, 82, 84, 73, 67, - 65, 76, 45, 48, 54, 45, 48, 48, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, - 48, 53, 45, 48, 54, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 53, 45, - 48, 53, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 53, 45, 48, 52, 128, - 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 53, 45, 48, 51, 128, 86, 69, 82, - 84, 73, 67, 65, 76, 45, 48, 53, 45, 48, 50, 128, 86, 69, 82, 84, 73, 67, - 65, 76, 45, 48, 53, 45, 48, 49, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, - 48, 53, 45, 48, 48, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 52, 45, - 48, 54, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 52, 45, 48, 53, 128, - 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 52, 45, 48, 52, 128, 86, 69, 82, - 84, 73, 67, 65, 76, 45, 48, 52, 45, 48, 51, 128, 86, 69, 82, 84, 73, 67, - 65, 76, 45, 48, 52, 45, 48, 50, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, - 48, 52, 45, 48, 49, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 52, 45, - 48, 48, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 51, 45, 48, 54, 128, - 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 51, 45, 48, 53, 128, 86, 69, 82, - 84, 73, 67, 65, 76, 45, 48, 51, 45, 48, 52, 128, 86, 69, 82, 84, 73, 67, - 65, 76, 45, 48, 51, 45, 48, 51, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, - 48, 51, 45, 48, 50, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 51, 45, - 48, 49, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 51, 45, 48, 48, 128, - 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 50, 45, 48, 54, 128, 86, 69, 82, - 84, 73, 67, 65, 76, 45, 48, 50, 45, 48, 53, 128, 86, 69, 82, 84, 73, 67, - 65, 76, 45, 48, 50, 45, 48, 52, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, - 48, 50, 45, 48, 51, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 50, 45, - 48, 50, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 50, 45, 48, 49, 128, - 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 50, 45, 48, 48, 128, 86, 69, 82, - 84, 73, 67, 65, 76, 45, 48, 49, 45, 48, 54, 128, 86, 69, 82, 84, 73, 67, - 65, 76, 45, 48, 49, 45, 48, 53, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, - 48, 49, 45, 48, 52, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 49, 45, - 48, 51, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 49, 45, 48, 50, 128, - 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 49, 45, 48, 49, 128, 86, 69, 82, - 84, 73, 67, 65, 76, 45, 48, 49, 45, 48, 48, 128, 86, 69, 82, 84, 73, 67, - 65, 76, 45, 48, 48, 45, 48, 54, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, - 48, 48, 45, 48, 53, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 48, 45, - 48, 52, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 48, 45, 48, 51, 128, - 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 48, 45, 48, 50, 128, 86, 69, 82, - 84, 73, 67, 65, 76, 45, 48, 48, 45, 48, 49, 128, 86, 69, 82, 84, 73, 67, - 65, 76, 45, 48, 48, 45, 48, 48, 128, 86, 69, 82, 84, 73, 67, 65, 76, 128, - 86, 69, 82, 83, 73, 67, 76, 69, 128, 86, 69, 82, 83, 197, 86, 69, 82, 71, - 69, 128, 86, 69, 82, 68, 73, 71, 82, 73, 83, 128, 86, 69, 82, 128, 86, - 69, 80, 128, 86, 69, 78, 68, 128, 86, 69, 76, 73, 128, 86, 69, 73, 76, - 128, 86, 69, 72, 73, 67, 76, 69, 128, 86, 69, 72, 128, 86, 69, 200, 86, - 69, 69, 128, 86, 69, 197, 86, 69, 68, 69, 128, 86, 69, 67, 84, 79, 210, - 86, 67, 128, 86, 65, 89, 65, 78, 78, 65, 128, 86, 65, 88, 128, 86, 65, - 86, 128, 86, 65, 214, 86, 65, 85, 128, 86, 65, 84, 72, 89, 128, 86, 65, - 84, 128, 86, 65, 83, 84, 78, 69, 83, 211, 86, 65, 83, 73, 83, 128, 86, - 65, 82, 89, 211, 86, 65, 82, 73, 75, 65, 128, 86, 65, 82, 73, 65, 78, 84, - 128, 86, 65, 82, 73, 65, 78, 212, 86, 65, 82, 73, 65, 128, 86, 65, 82, - 73, 193, 86, 65, 82, 69, 73, 65, 201, 86, 65, 82, 69, 73, 193, 86, 65, - 82, 65, 65, 75, 65, 78, 128, 86, 65, 80, 79, 85, 82, 83, 128, 86, 65, 80, - 128, 86, 65, 78, 69, 128, 86, 65, 77, 80, 73, 82, 69, 128, 86, 65, 77, - 65, 71, 79, 77, 85, 75, 72, 65, 128, 86, 65, 77, 65, 71, 79, 77, 85, 75, - 72, 193, 86, 65, 76, 76, 69, 89, 128, 86, 65, 75, 65, 73, 89, 65, 82, 65, - 65, 128, 86, 65, 74, 128, 86, 65, 73, 128, 86, 65, 72, 128, 86, 65, 200, - 86, 65, 65, 86, 85, 128, 86, 65, 65, 128, 86, 193, 86, 48, 52, 48, 65, - 128, 86, 48, 52, 48, 128, 86, 48, 51, 57, 128, 86, 48, 51, 56, 128, 86, - 48, 51, 55, 65, 128, 86, 48, 51, 55, 128, 86, 48, 51, 54, 128, 86, 48, - 51, 53, 128, 86, 48, 51, 52, 128, 86, 48, 51, 51, 65, 128, 86, 48, 51, - 51, 128, 86, 48, 51, 50, 128, 86, 48, 51, 49, 65, 128, 86, 48, 51, 49, - 128, 86, 48, 51, 48, 65, 128, 86, 48, 51, 48, 128, 86, 48, 50, 57, 65, - 128, 86, 48, 50, 57, 128, 86, 48, 50, 56, 65, 128, 86, 48, 50, 56, 128, - 86, 48, 50, 55, 128, 86, 48, 50, 54, 128, 86, 48, 50, 53, 128, 86, 48, - 50, 52, 128, 86, 48, 50, 51, 65, 128, 86, 48, 50, 51, 128, 86, 48, 50, - 50, 128, 86, 48, 50, 49, 128, 86, 48, 50, 48, 76, 128, 86, 48, 50, 48, - 75, 128, 86, 48, 50, 48, 74, 128, 86, 48, 50, 48, 73, 128, 86, 48, 50, - 48, 72, 128, 86, 48, 50, 48, 71, 128, 86, 48, 50, 48, 70, 128, 86, 48, - 50, 48, 69, 128, 86, 48, 50, 48, 68, 128, 86, 48, 50, 48, 67, 128, 86, - 48, 50, 48, 66, 128, 86, 48, 50, 48, 65, 128, 86, 48, 50, 48, 128, 86, - 48, 49, 57, 128, 86, 48, 49, 56, 128, 86, 48, 49, 55, 128, 86, 48, 49, - 54, 128, 86, 48, 49, 53, 128, 86, 48, 49, 52, 128, 86, 48, 49, 51, 128, - 86, 48, 49, 50, 66, 128, 86, 48, 49, 50, 65, 128, 86, 48, 49, 50, 128, - 86, 48, 49, 49, 67, 128, 86, 48, 49, 49, 66, 128, 86, 48, 49, 49, 65, - 128, 86, 48, 49, 49, 128, 86, 48, 49, 48, 128, 86, 48, 48, 57, 128, 86, - 48, 48, 56, 128, 86, 48, 48, 55, 66, 128, 86, 48, 48, 55, 65, 128, 86, - 48, 48, 55, 128, 86, 48, 48, 54, 128, 86, 48, 48, 53, 128, 86, 48, 48, - 52, 128, 86, 48, 48, 51, 128, 86, 48, 48, 50, 65, 128, 86, 48, 48, 50, - 128, 86, 48, 48, 49, 73, 128, 86, 48, 48, 49, 72, 128, 86, 48, 48, 49, - 71, 128, 86, 48, 48, 49, 70, 128, 86, 48, 48, 49, 69, 128, 86, 48, 48, - 49, 68, 128, 86, 48, 48, 49, 67, 128, 86, 48, 48, 49, 66, 128, 86, 48, - 48, 49, 65, 128, 86, 48, 48, 49, 128, 85, 90, 85, 128, 85, 90, 72, 65, - 75, 75, 85, 128, 85, 90, 51, 128, 85, 90, 179, 85, 90, 128, 85, 89, 71, - 72, 85, 210, 85, 89, 65, 78, 78, 65, 128, 85, 89, 128, 85, 87, 85, 128, - 85, 85, 89, 65, 78, 78, 65, 128, 85, 85, 85, 85, 128, 85, 85, 85, 51, - 128, 85, 85, 85, 50, 128, 85, 85, 69, 128, 85, 84, 85, 75, 73, 128, 85, - 83, 83, 85, 51, 128, 85, 83, 83, 85, 128, 85, 83, 72, 88, 128, 85, 83, - 72, 85, 77, 88, 128, 85, 83, 72, 69, 78, 78, 65, 128, 85, 83, 72, 50, - 128, 85, 83, 72, 128, 85, 83, 200, 85, 83, 69, 196, 85, 83, 69, 45, 50, - 128, 85, 83, 69, 45, 49, 128, 85, 83, 69, 128, 85, 83, 197, 85, 82, 85, - 218, 85, 82, 85, 83, 128, 85, 82, 85, 68, 65, 128, 85, 82, 85, 68, 193, - 85, 82, 85, 128, 85, 82, 213, 85, 82, 78, 128, 85, 82, 73, 78, 69, 128, - 85, 82, 73, 51, 128, 85, 82, 73, 128, 85, 82, 65, 78, 85, 83, 128, 85, - 82, 65, 128, 85, 82, 52, 128, 85, 82, 50, 128, 85, 82, 178, 85, 80, 87, - 65, 82, 68, 83, 128, 85, 80, 87, 65, 82, 68, 211, 85, 80, 87, 65, 82, 68, - 128, 85, 80, 87, 65, 82, 196, 85, 80, 84, 85, 82, 78, 128, 85, 80, 83, - 73, 76, 79, 78, 128, 85, 80, 83, 73, 76, 79, 206, 85, 80, 83, 73, 68, 69, - 45, 68, 79, 87, 206, 85, 80, 82, 73, 71, 72, 212, 85, 80, 80, 69, 82, - 128, 85, 80, 65, 68, 72, 77, 65, 78, 73, 89, 65, 128, 85, 80, 45, 80, 79, - 73, 78, 84, 73, 78, 199, 85, 79, 78, 128, 85, 79, 71, 128, 85, 78, 78, - 128, 85, 78, 77, 65, 82, 82, 73, 69, 196, 85, 78, 75, 78, 79, 87, 78, - 128, 85, 78, 75, 128, 85, 78, 73, 86, 69, 82, 83, 65, 204, 85, 78, 73, - 84, 89, 128, 85, 78, 73, 84, 69, 196, 85, 78, 73, 84, 128, 85, 78, 73, - 212, 85, 78, 73, 79, 78, 128, 85, 78, 73, 79, 206, 85, 78, 73, 70, 79, - 82, 77, 128, 85, 78, 73, 70, 73, 69, 196, 85, 78, 73, 67, 79, 82, 206, - 85, 78, 69, 86, 69, 206, 85, 78, 68, 207, 85, 78, 68, 69, 82, 84, 73, 69, - 128, 85, 78, 68, 69, 82, 76, 73, 78, 197, 85, 78, 68, 69, 82, 68, 79, 84, - 128, 85, 78, 68, 69, 82, 66, 65, 82, 128, 85, 78, 68, 69, 82, 128, 85, - 78, 68, 69, 210, 85, 78, 67, 73, 193, 85, 78, 67, 69, 82, 84, 65, 73, 78, - 84, 217, 85, 78, 66, 76, 69, 78, 68, 69, 196, 85, 78, 65, 83, 80, 73, 82, - 65, 84, 69, 68, 128, 85, 78, 65, 80, 128, 85, 78, 65, 77, 85, 83, 69, - 196, 85, 78, 65, 128, 85, 206, 85, 77, 85, 77, 128, 85, 77, 85, 205, 85, - 77, 66, 82, 69, 76, 76, 65, 128, 85, 77, 66, 82, 69, 76, 76, 193, 85, 77, - 66, 73, 78, 128, 85, 75, 85, 128, 85, 75, 82, 65, 73, 78, 73, 65, 206, - 85, 75, 65, 82, 65, 128, 85, 75, 65, 82, 193, 85, 75, 128, 85, 73, 90, - 128, 85, 73, 88, 128, 85, 73, 85, 90, 128, 85, 73, 85, 88, 128, 85, 73, - 85, 81, 128, 85, 73, 85, 67, 128, 85, 73, 81, 128, 85, 73, 76, 76, 69, - 65, 78, 78, 128, 85, 73, 71, 72, 85, 210, 85, 73, 67, 128, 85, 72, 68, - 128, 85, 71, 65, 82, 73, 84, 73, 195, 85, 69, 90, 128, 85, 69, 89, 128, - 85, 69, 88, 128, 85, 69, 78, 128, 85, 69, 73, 128, 85, 69, 69, 128, 85, - 69, 67, 128, 85, 69, 65, 128, 85, 68, 85, 71, 128, 85, 68, 65, 84, 84, - 65, 128, 85, 68, 65, 84, 84, 193, 85, 68, 65, 82, 75, 65, 128, 85, 68, - 65, 65, 84, 128, 85, 68, 128, 85, 196, 85, 66, 85, 70, 73, 76, 73, 128, - 85, 66, 72, 65, 89, 65, 84, 207, 85, 66, 65, 68, 65, 77, 65, 128, 85, 66, - 128, 85, 65, 84, 72, 128, 85, 65, 78, 71, 128, 85, 65, 128, 85, 178, 85, - 48, 52, 50, 128, 85, 48, 52, 49, 128, 85, 48, 52, 48, 128, 85, 48, 51, - 57, 128, 85, 48, 51, 56, 128, 85, 48, 51, 55, 128, 85, 48, 51, 54, 128, - 85, 48, 51, 53, 128, 85, 48, 51, 52, 128, 85, 48, 51, 51, 128, 85, 48, - 51, 50, 65, 128, 85, 48, 51, 50, 128, 85, 48, 51, 49, 128, 85, 48, 51, - 48, 128, 85, 48, 50, 57, 65, 128, 85, 48, 50, 57, 128, 85, 48, 50, 56, - 128, 85, 48, 50, 55, 128, 85, 48, 50, 54, 128, 85, 48, 50, 53, 128, 85, - 48, 50, 52, 128, 85, 48, 50, 51, 65, 128, 85, 48, 50, 51, 128, 85, 48, - 50, 50, 128, 85, 48, 50, 49, 128, 85, 48, 50, 48, 128, 85, 48, 49, 57, - 128, 85, 48, 49, 56, 128, 85, 48, 49, 55, 128, 85, 48, 49, 54, 128, 85, - 48, 49, 53, 128, 85, 48, 49, 52, 128, 85, 48, 49, 51, 128, 85, 48, 49, - 50, 128, 85, 48, 49, 49, 128, 85, 48, 49, 48, 128, 85, 48, 48, 57, 128, - 85, 48, 48, 56, 128, 85, 48, 48, 55, 128, 85, 48, 48, 54, 66, 128, 85, - 48, 48, 54, 65, 128, 85, 48, 48, 54, 128, 85, 48, 48, 53, 128, 85, 48, - 48, 52, 128, 85, 48, 48, 51, 128, 85, 48, 48, 50, 128, 85, 48, 48, 49, - 128, 85, 45, 83, 72, 65, 80, 69, 196, 85, 45, 73, 45, 73, 128, 85, 45, - 69, 79, 45, 69, 85, 128, 85, 45, 66, 82, 74, 71, 85, 128, 85, 45, 53, - 128, 84, 90, 85, 128, 84, 90, 79, 65, 128, 84, 90, 79, 128, 84, 90, 73, - 210, 84, 90, 73, 128, 84, 90, 69, 69, 128, 84, 90, 69, 128, 84, 90, 65, - 65, 128, 84, 90, 65, 128, 84, 90, 128, 84, 89, 210, 84, 89, 80, 69, 45, - 183, 84, 89, 80, 69, 45, 54, 128, 84, 89, 80, 69, 45, 182, 84, 89, 80, - 69, 45, 53, 128, 84, 89, 80, 69, 45, 181, 84, 89, 80, 69, 45, 52, 128, - 84, 89, 80, 69, 45, 180, 84, 89, 80, 69, 45, 51, 128, 84, 89, 80, 69, 45, - 179, 84, 89, 80, 69, 45, 178, 84, 89, 80, 69, 45, 49, 45, 50, 128, 84, - 89, 80, 69, 45, 177, 84, 89, 80, 197, 84, 89, 79, 128, 84, 89, 73, 128, - 84, 89, 69, 128, 84, 89, 65, 89, 128, 84, 89, 65, 128, 84, 88, 87, 86, - 128, 84, 88, 87, 214, 84, 88, 72, 69, 69, 202, 84, 88, 65, 128, 84, 87, - 79, 79, 128, 84, 87, 79, 45, 87, 65, 217, 84, 87, 79, 45, 84, 72, 73, 82, - 84, 89, 128, 84, 87, 79, 45, 76, 73, 78, 197, 84, 87, 79, 45, 72, 69, 65, - 68, 69, 196, 84, 87, 79, 45, 69, 205, 84, 87, 79, 45, 67, 73, 82, 67, 76, - 197, 84, 87, 73, 83, 84, 73, 78, 71, 128, 84, 87, 73, 83, 84, 69, 196, - 84, 87, 73, 73, 128, 84, 87, 73, 128, 84, 87, 69, 78, 84, 89, 45, 84, 87, - 79, 128, 84, 87, 69, 78, 84, 89, 45, 84, 87, 207, 84, 87, 69, 78, 84, 89, - 45, 84, 72, 82, 69, 69, 128, 84, 87, 69, 78, 84, 89, 45, 83, 73, 88, 128, - 84, 87, 69, 78, 84, 89, 45, 83, 69, 86, 69, 78, 128, 84, 87, 69, 78, 84, - 89, 45, 79, 78, 69, 128, 84, 87, 69, 78, 84, 89, 45, 78, 73, 78, 69, 128, - 84, 87, 69, 78, 84, 89, 45, 70, 79, 85, 82, 128, 84, 87, 69, 78, 84, 89, - 45, 70, 73, 86, 69, 128, 84, 87, 69, 78, 84, 89, 45, 70, 73, 86, 197, 84, - 87, 69, 78, 84, 89, 45, 69, 73, 71, 72, 84, 200, 84, 87, 69, 78, 84, 89, - 45, 69, 73, 71, 72, 84, 128, 84, 87, 69, 78, 84, 89, 128, 84, 87, 69, 78, - 84, 217, 84, 87, 69, 78, 84, 73, 69, 84, 72, 83, 128, 84, 87, 69, 78, 84, - 73, 69, 84, 72, 128, 84, 87, 69, 76, 86, 69, 45, 84, 72, 73, 82, 84, 89, - 128, 84, 87, 69, 76, 86, 69, 128, 84, 87, 69, 76, 86, 197, 84, 87, 69, - 76, 70, 84, 72, 83, 128, 84, 87, 69, 76, 70, 84, 72, 128, 84, 87, 69, - 128, 84, 87, 65, 65, 128, 84, 87, 65, 128, 84, 86, 82, 73, 68, 79, 128, - 84, 86, 73, 77, 65, 68, 85, 210, 84, 85, 88, 69, 68, 79, 128, 84, 85, 88, - 128, 84, 85, 85, 77, 85, 128, 84, 85, 85, 128, 84, 85, 84, 84, 89, 128, - 84, 85, 84, 69, 89, 65, 83, 65, 84, 128, 84, 85, 84, 128, 84, 85, 82, 88, - 128, 84, 85, 82, 85, 128, 84, 85, 82, 84, 76, 69, 128, 84, 85, 82, 79, - 50, 128, 84, 85, 82, 78, 83, 84, 73, 76, 69, 128, 84, 85, 82, 206, 84, - 85, 82, 75, 73, 83, 200, 84, 85, 82, 75, 73, 195, 84, 85, 82, 75, 69, 89, - 128, 84, 85, 82, 66, 65, 78, 128, 84, 85, 82, 128, 84, 85, 210, 84, 85, - 80, 78, 73, 128, 84, 85, 80, 128, 84, 85, 79, 88, 128, 84, 85, 79, 84, - 128, 84, 85, 79, 80, 128, 84, 85, 79, 128, 84, 85, 78, 78, 89, 128, 84, - 85, 77, 69, 84, 69, 83, 128, 84, 85, 77, 66, 76, 69, 210, 84, 85, 77, 65, - 69, 128, 84, 85, 77, 128, 84, 85, 205, 84, 85, 76, 73, 80, 128, 84, 85, - 75, 87, 69, 78, 84, 73, 83, 128, 84, 85, 75, 128, 84, 85, 71, 82, 73, - 203, 84, 85, 71, 50, 128, 84, 85, 71, 178, 84, 85, 66, 69, 128, 84, 85, - 66, 128, 84, 85, 65, 82, 69, 199, 84, 85, 65, 69, 80, 128, 84, 85, 65, - 69, 128, 84, 85, 45, 84, 79, 128, 84, 85, 45, 52, 128, 84, 85, 45, 51, - 128, 84, 85, 45, 50, 128, 84, 85, 45, 49, 128, 84, 213, 84, 84, 85, 85, - 128, 84, 84, 85, 68, 68, 65, 71, 128, 84, 84, 85, 68, 68, 65, 65, 71, - 128, 84, 84, 85, 128, 84, 84, 84, 72, 65, 128, 84, 84, 84, 65, 128, 84, - 84, 83, 85, 128, 84, 84, 83, 79, 128, 84, 84, 83, 73, 128, 84, 84, 83, - 69, 69, 128, 84, 84, 83, 69, 128, 84, 84, 83, 65, 128, 84, 84, 79, 79, - 128, 84, 84, 73, 73, 128, 84, 84, 73, 128, 84, 84, 72, 87, 69, 128, 84, - 84, 72, 85, 128, 84, 84, 72, 79, 79, 128, 84, 84, 72, 79, 128, 84, 84, - 72, 73, 128, 84, 84, 72, 69, 69, 128, 84, 84, 72, 69, 128, 84, 84, 72, - 65, 65, 128, 84, 84, 72, 128, 84, 84, 69, 72, 69, 72, 128, 84, 84, 69, - 72, 69, 200, 84, 84, 69, 72, 128, 84, 84, 69, 200, 84, 84, 69, 69, 128, - 84, 84, 65, 89, 65, 78, 78, 65, 128, 84, 84, 65, 85, 128, 84, 84, 65, 73, - 128, 84, 84, 65, 65, 128, 84, 84, 50, 128, 84, 83, 87, 69, 128, 84, 83, - 87, 66, 128, 84, 83, 87, 65, 128, 84, 83, 86, 128, 84, 83, 83, 69, 128, - 84, 83, 83, 65, 128, 84, 83, 79, 214, 84, 83, 73, 85, 128, 84, 83, 72, - 85, 71, 83, 128, 84, 83, 72, 79, 79, 75, 128, 84, 83, 72, 79, 79, 203, - 84, 83, 72, 79, 79, 74, 128, 84, 83, 72, 69, 83, 128, 84, 83, 72, 69, 71, - 128, 84, 83, 72, 69, 199, 84, 83, 72, 69, 69, 74, 128, 84, 83, 72, 69, - 128, 84, 83, 72, 65, 194, 84, 83, 72, 65, 128, 84, 83, 69, 82, 69, 128, - 84, 83, 69, 69, 66, 128, 84, 83, 65, 84, 193, 84, 83, 65, 68, 73, 128, - 84, 83, 65, 68, 201, 84, 83, 65, 66, 128, 84, 83, 65, 65, 68, 73, 89, - 128, 84, 83, 65, 65, 128, 84, 83, 193, 84, 82, 89, 66, 76, 73, 79, 206, - 84, 82, 89, 65, 83, 79, 83, 84, 82, 69, 76, 78, 65, 89, 65, 128, 84, 82, - 89, 65, 83, 79, 80, 79, 86, 79, 68, 78, 65, 89, 65, 128, 84, 82, 89, 65, - 83, 79, 71, 76, 65, 83, 78, 65, 89, 65, 128, 84, 82, 89, 65, 83, 75, 65, - 128, 84, 82, 85, 84, 72, 128, 84, 82, 85, 78, 75, 128, 84, 82, 85, 78, - 67, 65, 84, 69, 196, 84, 82, 85, 77, 80, 69, 84, 128, 84, 82, 85, 77, 80, - 45, 57, 128, 84, 82, 85, 77, 80, 45, 56, 128, 84, 82, 85, 77, 80, 45, 55, - 128, 84, 82, 85, 77, 80, 45, 54, 128, 84, 82, 85, 77, 80, 45, 53, 128, - 84, 82, 85, 77, 80, 45, 52, 128, 84, 82, 85, 77, 80, 45, 51, 128, 84, 82, - 85, 77, 80, 45, 50, 49, 128, 84, 82, 85, 77, 80, 45, 50, 48, 128, 84, 82, - 85, 77, 80, 45, 50, 128, 84, 82, 85, 77, 80, 45, 49, 57, 128, 84, 82, 85, - 77, 80, 45, 49, 56, 128, 84, 82, 85, 77, 80, 45, 49, 55, 128, 84, 82, 85, - 77, 80, 45, 49, 54, 128, 84, 82, 85, 77, 80, 45, 49, 53, 128, 84, 82, 85, - 77, 80, 45, 49, 52, 128, 84, 82, 85, 77, 80, 45, 49, 51, 128, 84, 82, 85, - 77, 80, 45, 49, 50, 128, 84, 82, 85, 77, 80, 45, 49, 49, 128, 84, 82, 85, - 77, 80, 45, 49, 48, 128, 84, 82, 85, 77, 80, 45, 49, 128, 84, 82, 85, 69, - 128, 84, 82, 85, 197, 84, 82, 85, 67, 75, 128, 84, 82, 79, 80, 73, 67, - 65, 204, 84, 82, 79, 80, 72, 89, 128, 84, 82, 79, 77, 73, 75, 79, 83, 89, - 78, 65, 71, 77, 65, 128, 84, 82, 79, 77, 73, 75, 79, 80, 83, 73, 70, 73, - 83, 84, 79, 78, 128, 84, 82, 79, 77, 73, 75, 79, 80, 65, 82, 65, 75, 65, - 76, 69, 83, 77, 65, 128, 84, 82, 79, 77, 73, 75, 79, 78, 128, 84, 82, 79, - 77, 73, 75, 79, 206, 84, 82, 79, 77, 73, 75, 79, 76, 89, 71, 73, 83, 77, - 65, 128, 84, 82, 79, 76, 76, 69, 89, 66, 85, 83, 128, 84, 82, 79, 76, 76, - 69, 89, 128, 84, 82, 79, 76, 76, 128, 84, 82, 79, 75, 85, 84, 65, 83, 84, - 201, 84, 82, 79, 69, 90, 69, 78, 73, 65, 206, 84, 82, 73, 85, 77, 80, 72, - 128, 84, 82, 73, 84, 79, 211, 84, 82, 73, 84, 73, 77, 79, 82, 73, 79, 78, - 128, 84, 82, 73, 83, 73, 77, 79, 85, 128, 84, 82, 73, 83, 69, 77, 69, - 128, 84, 82, 73, 80, 79, 68, 128, 84, 82, 73, 80, 76, 73, 128, 84, 82, - 73, 80, 76, 69, 128, 84, 82, 73, 80, 76, 197, 84, 82, 73, 79, 206, 84, - 82, 73, 76, 76, 73, 79, 78, 83, 128, 84, 82, 73, 76, 76, 128, 84, 82, 73, - 73, 83, 65, 80, 128, 84, 82, 73, 71, 82, 65, 77, 77, 79, 211, 84, 82, 73, - 71, 82, 65, 205, 84, 82, 73, 71, 79, 82, 71, 79, 78, 128, 84, 82, 73, 70, - 79, 78, 73, 65, 83, 128, 84, 82, 73, 70, 79, 76, 73, 65, 84, 197, 84, 82, - 73, 68, 69, 78, 84, 128, 84, 82, 73, 68, 69, 78, 212, 84, 82, 73, 67, 79, - 76, 79, 78, 128, 84, 82, 73, 65, 78, 71, 85, 76, 65, 210, 84, 82, 73, 65, - 78, 71, 76, 69, 45, 82, 79, 85, 78, 196, 84, 82, 73, 65, 78, 71, 76, 69, - 45, 72, 69, 65, 68, 69, 196, 84, 82, 73, 65, 78, 71, 76, 69, 128, 84, 82, - 73, 65, 78, 71, 76, 197, 84, 82, 73, 65, 128, 84, 82, 73, 128, 84, 82, - 69, 83, 86, 69, 84, 76, 89, 128, 84, 82, 69, 83, 86, 69, 84, 76, 79, 128, - 84, 82, 69, 83, 86, 69, 84, 76, 65, 89, 65, 128, 84, 82, 69, 83, 73, 76, - 76, 79, 128, 84, 82, 69, 78, 68, 128, 84, 82, 69, 78, 196, 84, 82, 69, - 77, 79, 76, 79, 45, 51, 128, 84, 82, 69, 77, 79, 76, 79, 45, 50, 128, 84, - 82, 69, 77, 79, 76, 79, 45, 49, 128, 84, 82, 69, 69, 128, 84, 82, 69, - 197, 84, 82, 69, 68, 69, 67, 73, 76, 69, 128, 84, 82, 69, 65, 68, 73, 78, - 71, 128, 84, 82, 65, 89, 128, 84, 82, 65, 86, 69, 76, 45, 87, 65, 76, 76, - 80, 76, 65, 78, 197, 84, 82, 65, 86, 69, 76, 45, 70, 76, 79, 79, 82, 80, - 76, 65, 78, 197, 84, 82, 65, 80, 69, 90, 73, 85, 77, 128, 84, 82, 65, 80, - 128, 84, 82, 65, 78, 83, 86, 69, 82, 83, 65, 204, 84, 82, 65, 78, 83, 80, - 79, 83, 73, 84, 73, 79, 206, 84, 82, 65, 78, 83, 80, 76, 85, 84, 79, 128, - 84, 82, 65, 78, 83, 77, 73, 212, 84, 82, 65, 78, 83, 77, 73, 83, 83, 73, - 79, 78, 128, 84, 82, 65, 78, 83, 77, 73, 83, 83, 73, 79, 206, 84, 82, 65, - 77, 87, 65, 89, 128, 84, 82, 65, 77, 128, 84, 82, 65, 205, 84, 82, 65, - 73, 78, 128, 84, 82, 65, 73, 206, 84, 82, 65, 73, 76, 73, 78, 199, 84, - 82, 65, 70, 70, 73, 67, 128, 84, 82, 65, 70, 70, 73, 195, 84, 82, 65, 68, - 73, 84, 73, 79, 78, 65, 204, 84, 82, 65, 68, 197, 84, 82, 65, 67, 84, 79, - 82, 128, 84, 82, 65, 67, 75, 66, 65, 76, 76, 128, 84, 82, 65, 67, 75, - 128, 84, 82, 65, 128, 84, 82, 128, 84, 79, 88, 128, 84, 79, 87, 69, 82, - 128, 84, 79, 87, 65, 82, 68, 211, 84, 79, 86, 128, 84, 79, 85, 82, 78, - 79, 73, 211, 84, 79, 85, 67, 72, 84, 79, 78, 197, 84, 79, 85, 67, 72, 73, - 78, 199, 84, 79, 85, 67, 72, 69, 211, 84, 79, 85, 67, 200, 84, 79, 84, - 207, 84, 79, 84, 65, 204, 84, 79, 84, 128, 84, 79, 83, 128, 84, 79, 82, - 84, 79, 73, 83, 197, 84, 79, 82, 83, 79, 45, 87, 65, 76, 76, 80, 76, 65, - 78, 197, 84, 79, 82, 83, 79, 45, 70, 76, 79, 79, 82, 80, 76, 65, 78, 197, - 84, 79, 82, 83, 79, 128, 84, 79, 82, 78, 65, 68, 79, 128, 84, 79, 82, 67, - 85, 76, 85, 83, 128, 84, 79, 82, 67, 85, 76, 85, 211, 84, 79, 82, 67, 72, - 128, 84, 79, 81, 128, 84, 79, 80, 66, 65, 82, 128, 84, 79, 80, 45, 76, - 73, 71, 72, 84, 69, 196, 84, 79, 80, 128, 84, 79, 208, 84, 79, 79, 84, - 72, 66, 82, 85, 83, 72, 128, 84, 79, 79, 84, 72, 128, 84, 79, 79, 78, - 128, 84, 79, 79, 76, 66, 79, 88, 128, 84, 79, 78, 79, 83, 128, 84, 79, - 78, 71, 85, 69, 128, 84, 79, 78, 71, 85, 197, 84, 79, 78, 71, 128, 84, - 79, 78, 69, 45, 86, 128, 84, 79, 78, 69, 45, 83, 128, 84, 79, 78, 69, 45, - 77, 128, 84, 79, 78, 69, 45, 74, 128, 84, 79, 78, 69, 45, 71, 128, 84, - 79, 78, 69, 45, 68, 128, 84, 79, 78, 69, 45, 66, 128, 84, 79, 78, 69, 45, - 56, 128, 84, 79, 78, 69, 45, 55, 128, 84, 79, 78, 69, 45, 54, 128, 84, - 79, 78, 69, 45, 53, 128, 84, 79, 78, 69, 45, 52, 128, 84, 79, 78, 69, 45, - 51, 128, 84, 79, 78, 69, 45, 50, 128, 84, 79, 78, 69, 45, 49, 128, 84, - 79, 78, 69, 128, 84, 79, 78, 65, 204, 84, 79, 77, 80, 73, 128, 84, 79, - 77, 65, 84, 79, 128, 84, 79, 76, 79, 78, 71, 128, 84, 79, 75, 89, 207, - 84, 79, 73, 76, 69, 84, 128, 84, 79, 71, 69, 84, 72, 69, 82, 128, 84, 79, - 68, 207, 84, 79, 67, 72, 75, 65, 128, 84, 79, 65, 78, 68, 65, 75, 72, 73, - 65, 84, 128, 84, 79, 65, 128, 84, 79, 45, 82, 65, 128, 84, 79, 45, 54, - 128, 84, 79, 45, 53, 128, 84, 79, 45, 52, 128, 84, 79, 45, 51, 128, 84, - 79, 45, 50, 128, 84, 79, 45, 49, 128, 84, 78, 128, 84, 76, 86, 128, 84, - 76, 85, 128, 84, 76, 73, 128, 84, 76, 72, 89, 65, 128, 84, 76, 72, 87, - 69, 128, 84, 76, 72, 85, 128, 84, 76, 72, 79, 79, 128, 84, 76, 72, 79, - 128, 84, 76, 72, 73, 128, 84, 76, 72, 69, 69, 128, 84, 76, 72, 69, 128, - 84, 76, 72, 65, 128, 84, 76, 69, 69, 128, 84, 76, 65, 128, 84, 74, 69, - 128, 84, 73, 88, 128, 84, 73, 87, 82, 128, 84, 73, 87, 78, 128, 84, 73, - 87, 65, 218, 84, 73, 84, 85, 65, 69, 80, 128, 84, 73, 84, 76, 79, 128, - 84, 73, 84, 76, 207, 84, 73, 84, 193, 84, 73, 84, 128, 84, 73, 82, 89, - 65, 75, 128, 84, 73, 82, 84, 193, 84, 73, 82, 79, 78, 73, 65, 206, 84, - 73, 82, 72, 85, 84, 193, 84, 73, 82, 69, 196, 84, 73, 82, 128, 84, 73, - 210, 84, 73, 80, 80, 73, 128, 84, 73, 80, 69, 72, 65, 128, 84, 73, 80, - 128, 84, 73, 208, 84, 73, 78, 89, 128, 84, 73, 78, 217, 84, 73, 78, 78, - 69, 128, 84, 73, 78, 67, 84, 85, 82, 69, 128, 84, 73, 78, 65, 71, 77, 65, - 128, 84, 73, 77, 69, 83, 128, 84, 73, 77, 69, 210, 84, 73, 77, 69, 128, - 84, 73, 76, 84, 73, 78, 71, 128, 84, 73, 76, 84, 73, 78, 199, 84, 73, 76, - 84, 128, 84, 73, 76, 69, 83, 128, 84, 73, 76, 68, 69, 128, 84, 73, 76, - 68, 197, 84, 73, 76, 128, 84, 73, 204, 84, 73, 75, 72, 89, 128, 84, 73, - 75, 72, 65, 89, 65, 128, 84, 73, 75, 72, 65, 89, 193, 84, 73, 75, 69, 85, - 84, 45, 84, 72, 73, 69, 85, 84, 72, 128, 84, 73, 75, 69, 85, 84, 45, 83, - 73, 79, 83, 45, 75, 73, 89, 69, 79, 75, 128, 84, 73, 75, 69, 85, 84, 45, - 83, 73, 79, 83, 128, 84, 73, 75, 69, 85, 84, 45, 82, 73, 69, 85, 76, 128, - 84, 73, 75, 69, 85, 84, 45, 80, 73, 69, 85, 80, 128, 84, 73, 75, 69, 85, - 84, 45, 77, 73, 69, 85, 77, 128, 84, 73, 75, 69, 85, 84, 45, 75, 73, 89, - 69, 79, 75, 128, 84, 73, 75, 69, 85, 84, 45, 67, 73, 69, 85, 67, 128, 84, - 73, 75, 69, 85, 84, 45, 67, 72, 73, 69, 85, 67, 72, 128, 84, 73, 75, 69, - 85, 84, 128, 84, 73, 75, 69, 85, 212, 84, 73, 71, 72, 84, 76, 89, 45, 67, - 76, 79, 83, 69, 196, 84, 73, 71, 72, 212, 84, 73, 71, 69, 82, 128, 84, - 73, 71, 69, 210, 84, 73, 70, 73, 78, 65, 71, 200, 84, 73, 69, 88, 128, - 84, 73, 69, 80, 128, 84, 73, 197, 84, 73, 67, 75, 69, 84, 83, 128, 84, - 73, 67, 75, 69, 84, 128, 84, 73, 67, 75, 128, 84, 73, 67, 203, 84, 73, - 65, 82, 65, 128, 84, 73, 50, 128, 84, 73, 45, 55, 128, 84, 73, 45, 54, - 128, 84, 73, 45, 53, 128, 84, 73, 45, 52, 128, 84, 73, 45, 51, 128, 84, - 73, 45, 50, 128, 84, 73, 45, 49, 128, 84, 72, 90, 128, 84, 72, 89, 79, - 79, 205, 84, 72, 87, 79, 79, 128, 84, 72, 87, 79, 128, 84, 72, 87, 73, - 73, 128, 84, 72, 87, 73, 128, 84, 72, 87, 69, 69, 128, 84, 72, 87, 65, - 65, 128, 84, 72, 87, 65, 128, 84, 72, 85, 82, 211, 84, 72, 85, 82, 73, - 83, 65, 218, 84, 72, 85, 78, 71, 128, 84, 72, 85, 78, 68, 69, 82, 83, 84, - 79, 82, 77, 128, 84, 72, 85, 78, 68, 69, 82, 128, 84, 72, 85, 78, 68, 69, + 79, 87, 206, 80, 65, 72, 65, 87, 200, 67, 72, 79, 83, 69, 79, 78, 199, + 66, 65, 76, 73, 78, 69, 83, 197, 70, 73, 86, 69, 128, 72, 65, 76, 70, 87, + 73, 68, 84, 200, 72, 65, 78, 68, 45, 70, 73, 83, 212, 77, 69, 82, 79, 73, + 84, 73, 195, 84, 85, 82, 78, 69, 196, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 73, 195, 75, 65, 128, 76, 73, 71, 72, 212, 73, 68, 69, 79, 71, 82, 65, + 205, 80, 72, 65, 83, 69, 45, 196, 84, 79, 128, 65, 76, 67, 72, 69, 77, + 73, 67, 65, 204, 78, 69, 85, 77, 197, 66, 82, 65, 72, 77, 201, 84, 79, + 78, 197, 66, 65, 82, 128, 82, 65, 128, 83, 73, 78, 72, 65, 76, 193, 78, + 85, 77, 69, 82, 73, 195, 80, 65, 128, 83, 73, 88, 128, 89, 65, 128, 69, + 73, 71, 72, 84, 128, 76, 65, 128, 77, 65, 128, 83, 69, 86, 69, 78, 128, + 84, 72, 85, 77, 194, 72, 85, 78, 71, 65, 82, 73, 65, 206, 78, 73, 78, 69, + 128, 76, 79, 78, 199, 78, 65, 128, 66, 65, 82, 194, 72, 65, 200, 82, 73, + 71, 72, 84, 128, 66, 76, 79, 67, 203, 68, 79, 84, 211, 78, 79, 82, 84, + 200, 83, 65, 128, 84, 72, 79, 85, 83, 65, 78, 68, 128, 84, 65, 128, 90, + 90, 89, 88, 128, 90, 90, 89, 84, 128, 90, 90, 89, 82, 88, 128, 90, 90, + 89, 82, 128, 90, 90, 89, 80, 128, 90, 90, 89, 65, 128, 90, 90, 89, 128, + 90, 90, 85, 88, 128, 90, 90, 85, 82, 88, 128, 90, 90, 85, 82, 128, 90, + 90, 85, 80, 128, 90, 90, 85, 128, 90, 90, 83, 89, 65, 128, 90, 90, 83, + 65, 128, 90, 90, 79, 88, 128, 90, 90, 79, 80, 128, 90, 90, 79, 128, 90, + 90, 73, 88, 128, 90, 90, 73, 84, 128, 90, 90, 73, 80, 128, 90, 90, 73, + 69, 88, 128, 90, 90, 73, 69, 84, 128, 90, 90, 73, 69, 80, 128, 90, 90, + 73, 69, 128, 90, 90, 73, 128, 90, 90, 69, 88, 128, 90, 90, 69, 80, 128, + 90, 90, 69, 69, 128, 90, 90, 69, 128, 90, 90, 65, 88, 128, 90, 90, 65, + 84, 128, 90, 90, 65, 80, 128, 90, 90, 65, 65, 128, 90, 90, 65, 128, 90, + 89, 71, 79, 83, 128, 90, 87, 83, 80, 128, 90, 87, 78, 74, 128, 90, 87, + 78, 66, 83, 80, 128, 90, 87, 74, 128, 90, 87, 202, 90, 87, 65, 82, 65, + 75, 65, 89, 128, 90, 87, 65, 128, 90, 85, 84, 128, 90, 85, 79, 88, 128, + 90, 85, 79, 80, 128, 90, 85, 79, 128, 90, 85, 77, 128, 90, 85, 66, 85, + 82, 128, 90, 85, 53, 128, 90, 85, 181, 90, 213, 90, 83, 72, 65, 128, 90, + 82, 65, 128, 90, 81, 65, 80, 72, 193, 90, 79, 84, 128, 90, 79, 79, 128, + 90, 79, 77, 66, 73, 69, 128, 90, 79, 65, 128, 90, 77, 69, 89, 84, 83, 65, + 128, 90, 76, 65, 77, 193, 90, 76, 65, 128, 90, 76, 193, 90, 74, 69, 128, + 90, 73, 90, 50, 128, 90, 73, 81, 65, 65, 128, 90, 73, 80, 80, 69, 82, 45, + 77, 79, 85, 84, 200, 90, 73, 78, 79, 82, 128, 90, 73, 76, 68, 69, 128, + 90, 73, 71, 90, 65, 199, 90, 73, 71, 128, 90, 73, 68, 193, 90, 73, 66, + 128, 90, 73, 194, 90, 73, 51, 128, 90, 201, 90, 72, 89, 88, 128, 90, 72, + 89, 84, 128, 90, 72, 89, 82, 88, 128, 90, 72, 89, 82, 128, 90, 72, 89, + 80, 128, 90, 72, 89, 128, 90, 72, 87, 69, 128, 90, 72, 87, 65, 128, 90, + 72, 85, 88, 128, 90, 72, 85, 84, 128, 90, 72, 85, 82, 88, 128, 90, 72, + 85, 82, 128, 90, 72, 85, 80, 128, 90, 72, 85, 79, 88, 128, 90, 72, 85, + 79, 80, 128, 90, 72, 85, 79, 128, 90, 72, 85, 128, 90, 72, 79, 88, 128, + 90, 72, 79, 84, 128, 90, 72, 79, 80, 128, 90, 72, 79, 79, 128, 90, 72, + 79, 73, 128, 90, 72, 79, 128, 90, 72, 73, 86, 69, 84, 69, 128, 90, 72, + 73, 76, 128, 90, 72, 73, 128, 90, 72, 69, 88, 128, 90, 72, 69, 84, 128, + 90, 72, 69, 80, 128, 90, 72, 69, 69, 128, 90, 72, 69, 128, 90, 72, 197, + 90, 72, 65, 89, 73, 78, 128, 90, 72, 65, 88, 128, 90, 72, 65, 84, 128, + 90, 72, 65, 82, 128, 90, 72, 65, 80, 128, 90, 72, 65, 73, 78, 128, 90, + 72, 65, 65, 128, 90, 72, 65, 128, 90, 72, 128, 90, 69, 86, 79, 75, 128, + 90, 69, 85, 83, 128, 90, 69, 84, 65, 128, 90, 69, 82, 79, 128, 90, 69, + 82, 207, 90, 69, 78, 128, 90, 69, 77, 76, 89, 65, 128, 90, 69, 77, 76, + 74, 65, 128, 90, 69, 76, 79, 128, 90, 69, 66, 82, 193, 90, 69, 50, 128, + 90, 197, 90, 65, 89, 78, 128, 90, 65, 89, 73, 78, 45, 89, 79, 68, 72, + 128, 90, 65, 89, 73, 78, 128, 90, 65, 89, 73, 206, 90, 65, 86, 73, 89, + 65, 78, 73, 128, 90, 65, 84, 65, 128, 90, 65, 82, 81, 65, 128, 90, 65, + 82, 76, 128, 90, 65, 81, 69, 198, 90, 65, 80, 89, 65, 84, 89, 77, 73, + 128, 90, 65, 80, 89, 65, 84, 79, 89, 128, 90, 65, 80, 89, 65, 84, 79, + 217, 90, 65, 80, 89, 65, 84, 65, 89, 65, 128, 90, 65, 78, 79, 90, 72, 69, + 75, 128, 90, 65, 78, 65, 66, 65, 90, 65, 210, 90, 65, 77, 88, 128, 90, + 65, 76, 128, 90, 65, 204, 90, 65, 75, 82, 89, 84, 79, 69, 128, 90, 65, + 75, 82, 89, 84, 65, 89, 65, 128, 90, 65, 75, 82, 89, 84, 65, 89, 193, 90, + 65, 73, 78, 128, 90, 65, 73, 206, 90, 65, 73, 128, 90, 65, 72, 128, 90, + 65, 200, 90, 65, 71, 128, 90, 65, 69, 70, 128, 90, 65, 68, 69, 82, 90, + 72, 75, 65, 128, 90, 65, 55, 128, 90, 193, 90, 48, 49, 54, 72, 128, 90, + 48, 49, 54, 71, 128, 90, 48, 49, 54, 70, 128, 90, 48, 49, 54, 69, 128, + 90, 48, 49, 54, 68, 128, 90, 48, 49, 54, 67, 128, 90, 48, 49, 54, 66, + 128, 90, 48, 49, 54, 65, 128, 90, 48, 49, 54, 128, 90, 48, 49, 53, 73, + 128, 90, 48, 49, 53, 72, 128, 90, 48, 49, 53, 71, 128, 90, 48, 49, 53, + 70, 128, 90, 48, 49, 53, 69, 128, 90, 48, 49, 53, 68, 128, 90, 48, 49, + 53, 67, 128, 90, 48, 49, 53, 66, 128, 90, 48, 49, 53, 65, 128, 90, 48, + 49, 53, 128, 90, 48, 49, 52, 128, 90, 48, 49, 51, 128, 90, 48, 49, 50, + 128, 90, 48, 49, 49, 128, 90, 48, 49, 48, 128, 90, 48, 48, 57, 128, 90, + 48, 48, 56, 128, 90, 48, 48, 55, 128, 90, 48, 48, 54, 128, 90, 48, 48, + 53, 65, 128, 90, 48, 48, 53, 128, 90, 48, 48, 52, 65, 128, 90, 48, 48, + 52, 128, 90, 48, 48, 51, 66, 128, 90, 48, 48, 51, 65, 128, 90, 48, 48, + 51, 128, 90, 48, 48, 50, 68, 128, 90, 48, 48, 50, 67, 128, 90, 48, 48, + 50, 66, 128, 90, 48, 48, 50, 65, 128, 90, 48, 48, 50, 128, 90, 48, 48, + 49, 128, 90, 128, 218, 89, 89, 88, 128, 89, 89, 84, 128, 89, 89, 82, 88, + 128, 89, 89, 82, 128, 89, 89, 80, 128, 89, 89, 69, 128, 89, 89, 65, 65, + 128, 89, 89, 65, 128, 89, 89, 128, 89, 87, 79, 79, 128, 89, 87, 79, 128, + 89, 87, 73, 73, 128, 89, 87, 73, 128, 89, 87, 69, 128, 89, 87, 65, 65, + 128, 89, 87, 65, 128, 89, 86, 128, 89, 85, 88, 128, 89, 85, 87, 79, 81, + 128, 89, 85, 85, 75, 65, 76, 69, 65, 80, 73, 78, 84, 85, 128, 89, 85, 85, + 128, 89, 85, 84, 128, 89, 85, 83, 128, 89, 85, 211, 89, 85, 82, 88, 128, + 89, 85, 82, 128, 89, 85, 81, 128, 89, 85, 209, 89, 85, 80, 128, 89, 85, + 79, 88, 128, 89, 85, 79, 84, 128, 89, 85, 79, 80, 128, 89, 85, 79, 77, + 128, 89, 85, 79, 128, 89, 85, 78, 128, 89, 85, 77, 128, 89, 85, 74, 128, + 89, 85, 73, 128, 89, 85, 69, 81, 128, 89, 85, 69, 128, 89, 85, 68, 72, + 128, 89, 85, 68, 200, 89, 85, 65, 78, 128, 89, 85, 65, 69, 78, 128, 89, + 85, 45, 89, 69, 79, 128, 89, 85, 45, 89, 69, 128, 89, 85, 45, 85, 128, + 89, 85, 45, 79, 128, 89, 85, 45, 73, 128, 89, 85, 45, 69, 79, 128, 89, + 85, 45, 69, 128, 89, 85, 45, 65, 69, 128, 89, 85, 45, 65, 128, 89, 85, + 45, 52, 128, 89, 85, 45, 51, 128, 89, 85, 45, 50, 128, 89, 85, 45, 49, + 128, 89, 85, 128, 89, 213, 89, 82, 89, 128, 89, 80, 83, 73, 76, 73, 128, + 89, 80, 79, 82, 82, 79, 73, 128, 89, 80, 79, 75, 82, 73, 83, 73, 83, 128, + 89, 80, 79, 75, 82, 73, 83, 73, 211, 89, 80, 79, 71, 69, 71, 82, 65, 77, + 77, 69, 78, 73, 128, 89, 79, 89, 128, 89, 79, 88, 128, 89, 79, 87, 68, + 128, 89, 79, 85, 84, 72, 70, 85, 76, 78, 69, 83, 83, 128, 89, 79, 85, 84, + 72, 70, 85, 204, 89, 79, 213, 89, 79, 84, 128, 89, 79, 212, 89, 79, 82, + 73, 128, 89, 79, 81, 128, 89, 79, 209, 89, 79, 80, 128, 89, 79, 79, 128, + 89, 79, 77, 79, 128, 89, 79, 71, 72, 128, 89, 79, 68, 128, 89, 79, 196, + 89, 79, 65, 128, 89, 79, 45, 89, 79, 128, 89, 79, 45, 89, 69, 79, 128, + 89, 79, 45, 89, 65, 69, 128, 89, 79, 45, 89, 65, 128, 89, 79, 45, 79, + 128, 89, 79, 45, 73, 128, 89, 79, 45, 69, 79, 128, 89, 79, 45, 65, 69, + 128, 89, 79, 45, 65, 128, 89, 79, 45, 54, 128, 89, 79, 45, 53, 128, 89, + 79, 45, 52, 128, 89, 79, 45, 51, 128, 89, 79, 45, 50, 128, 89, 79, 45, + 49, 128, 89, 207, 89, 73, 90, 69, 84, 128, 89, 73, 88, 128, 89, 73, 87, + 78, 128, 89, 73, 84, 128, 89, 73, 80, 128, 89, 73, 78, 71, 128, 89, 73, + 73, 128, 89, 73, 72, 128, 89, 73, 199, 89, 73, 69, 88, 128, 89, 73, 69, + 84, 128, 89, 73, 69, 80, 128, 89, 73, 69, 69, 128, 89, 73, 69, 128, 89, + 73, 68, 68, 73, 83, 200, 89, 73, 45, 85, 128, 89, 73, 128, 89, 72, 69, + 128, 89, 72, 65, 128, 89, 70, 69, 83, 73, 83, 128, 89, 70, 69, 83, 73, + 211, 89, 70, 69, 206, 89, 69, 90, 73, 68, 201, 89, 69, 89, 128, 89, 69, + 87, 128, 89, 69, 85, 88, 128, 89, 69, 85, 82, 65, 69, 128, 89, 69, 85, + 81, 128, 89, 69, 85, 77, 128, 89, 69, 85, 65, 69, 84, 128, 89, 69, 85, + 65, 69, 128, 89, 69, 84, 73, 86, 128, 89, 69, 83, 84, 85, 128, 89, 69, + 83, 73, 69, 85, 78, 71, 45, 83, 83, 65, 78, 71, 75, 73, 89, 69, 79, 75, + 128, 89, 69, 83, 73, 69, 85, 78, 71, 45, 83, 73, 79, 83, 128, 89, 69, 83, + 73, 69, 85, 78, 71, 45, 80, 65, 78, 83, 73, 79, 83, 128, 89, 69, 83, 73, + 69, 85, 78, 71, 45, 77, 73, 69, 85, 77, 128, 89, 69, 83, 73, 69, 85, 78, + 71, 45, 75, 73, 89, 69, 79, 75, 128, 89, 69, 83, 73, 69, 85, 78, 71, 45, + 75, 72, 73, 69, 85, 75, 72, 128, 89, 69, 83, 73, 69, 85, 78, 71, 45, 72, + 73, 69, 85, 72, 128, 89, 69, 83, 73, 69, 85, 78, 71, 128, 89, 69, 82, 85, + 128, 89, 69, 82, 213, 89, 69, 82, 73, 128, 89, 69, 82, 65, 200, 89, 69, + 82, 128, 89, 69, 79, 82, 73, 78, 72, 73, 69, 85, 72, 128, 89, 69, 79, 45, + 89, 65, 128, 89, 69, 79, 45, 85, 128, 89, 69, 79, 45, 79, 128, 89, 69, + 78, 73, 83, 69, 201, 89, 69, 78, 65, 80, 128, 89, 69, 78, 128, 89, 69, + 206, 89, 69, 76, 76, 79, 87, 128, 89, 69, 76, 76, 79, 215, 89, 69, 73, + 78, 128, 89, 69, 72, 128, 89, 69, 69, 71, 128, 89, 69, 69, 128, 89, 69, + 65, 210, 89, 69, 65, 128, 89, 65, 90, 90, 128, 89, 65, 90, 72, 128, 89, + 65, 90, 128, 89, 65, 89, 68, 128, 89, 65, 89, 65, 78, 78, 65, 128, 89, + 65, 89, 128, 89, 65, 87, 78, 73, 78, 199, 89, 65, 87, 78, 128, 89, 65, + 87, 128, 89, 65, 86, 128, 89, 65, 85, 128, 89, 65, 84, 84, 128, 89, 65, + 84, 73, 128, 89, 65, 84, 72, 128, 89, 65, 84, 128, 89, 65, 83, 83, 128, + 89, 65, 83, 72, 128, 89, 65, 83, 128, 89, 65, 82, 82, 128, 89, 65, 82, + 78, 128, 89, 65, 82, 128, 89, 65, 210, 89, 65, 81, 128, 89, 65, 80, 128, + 89, 65, 78, 83, 65, 89, 65, 128, 89, 65, 78, 71, 128, 89, 65, 78, 199, + 89, 65, 78, 128, 89, 65, 77, 79, 75, 128, 89, 65, 77, 65, 75, 75, 65, 78, + 128, 89, 65, 77, 128, 89, 65, 76, 128, 89, 65, 75, 72, 72, 128, 89, 65, + 75, 72, 128, 89, 65, 75, 65, 83, 72, 128, 89, 65, 75, 128, 89, 65, 74, + 85, 82, 86, 69, 68, 73, 195, 89, 65, 74, 128, 89, 65, 73, 128, 89, 65, + 72, 72, 128, 89, 65, 72, 128, 89, 65, 71, 78, 128, 89, 65, 71, 72, 72, + 128, 89, 65, 71, 72, 128, 89, 65, 71, 128, 89, 65, 70, 213, 89, 65, 70, + 128, 89, 65, 69, 77, 77, 65, 69, 128, 89, 65, 68, 72, 128, 89, 65, 68, + 68, 72, 128, 89, 65, 68, 68, 128, 89, 65, 68, 128, 89, 65, 67, 72, 128, + 89, 65, 66, 72, 128, 89, 65, 66, 128, 89, 65, 65, 82, 85, 128, 89, 65, + 65, 73, 128, 89, 65, 65, 68, 79, 128, 89, 65, 45, 89, 79, 128, 89, 65, + 45, 85, 128, 89, 65, 45, 79, 128, 89, 65, 45, 53, 128, 89, 65, 45, 52, + 128, 89, 65, 45, 51, 128, 89, 65, 45, 50, 128, 89, 65, 45, 49, 128, 89, + 48, 48, 56, 128, 89, 48, 48, 55, 128, 89, 48, 48, 54, 128, 89, 48, 48, + 53, 128, 89, 48, 48, 52, 128, 89, 48, 48, 51, 128, 89, 48, 48, 50, 128, + 89, 48, 48, 49, 65, 128, 89, 48, 48, 49, 128, 89, 45, 67, 82, 69, 197, + 88, 89, 88, 128, 88, 89, 85, 128, 88, 89, 84, 128, 88, 89, 82, 88, 128, + 88, 89, 82, 128, 88, 89, 80, 128, 88, 89, 79, 79, 74, 128, 88, 89, 79, + 79, 128, 88, 89, 79, 128, 88, 89, 73, 128, 88, 89, 69, 69, 205, 88, 89, + 69, 69, 128, 88, 89, 69, 128, 88, 89, 65, 65, 128, 88, 89, 65, 128, 88, + 89, 128, 88, 87, 73, 128, 88, 87, 69, 69, 128, 88, 87, 69, 128, 88, 87, + 65, 65, 128, 88, 87, 65, 128, 88, 87, 128, 88, 215, 88, 86, 69, 128, 88, + 86, 65, 128, 88, 85, 79, 88, 128, 88, 85, 79, 128, 88, 85, 128, 88, 83, + 72, 65, 65, 89, 65, 84, 72, 73, 89, 65, 128, 88, 79, 88, 128, 88, 79, 84, + 128, 88, 79, 82, 128, 88, 79, 80, 72, 128, 88, 79, 80, 128, 88, 79, 65, + 128, 88, 79, 128, 88, 73, 88, 128, 88, 73, 84, 128, 88, 73, 82, 79, 206, + 88, 73, 80, 128, 88, 73, 69, 88, 128, 88, 73, 69, 84, 128, 88, 73, 69, + 80, 128, 88, 73, 69, 128, 88, 73, 65, 78, 71, 81, 201, 88, 73, 65, 66, + 128, 88, 73, 128, 88, 72, 69, 89, 78, 128, 88, 71, 128, 88, 69, 89, 78, + 128, 88, 69, 83, 84, 69, 211, 88, 69, 72, 128, 88, 69, 69, 128, 88, 69, + 128, 88, 65, 85, 83, 128, 88, 65, 85, 128, 88, 65, 80, 72, 128, 88, 65, + 78, 128, 88, 65, 65, 128, 88, 65, 128, 88, 48, 48, 56, 65, 128, 88, 48, + 48, 56, 128, 88, 48, 48, 55, 128, 88, 48, 48, 54, 65, 128, 88, 48, 48, + 54, 128, 88, 48, 48, 53, 128, 88, 48, 48, 52, 66, 128, 88, 48, 48, 52, + 65, 128, 88, 48, 48, 52, 128, 88, 48, 48, 51, 128, 88, 48, 48, 50, 128, + 88, 48, 48, 49, 128, 88, 45, 216, 88, 45, 82, 65, 89, 128, 87, 90, 128, + 87, 89, 78, 78, 128, 87, 89, 78, 206, 87, 86, 73, 128, 87, 86, 69, 128, + 87, 86, 65, 128, 87, 86, 128, 87, 85, 80, 128, 87, 85, 79, 88, 128, 87, + 85, 79, 80, 128, 87, 85, 79, 128, 87, 85, 78, 74, 207, 87, 85, 78, 128, + 87, 85, 76, 85, 128, 87, 85, 76, 213, 87, 85, 73, 128, 87, 85, 69, 128, + 87, 85, 65, 69, 84, 128, 87, 85, 65, 69, 78, 128, 87, 85, 128, 87, 82, + 217, 87, 82, 79, 78, 71, 128, 87, 82, 73, 83, 212, 87, 82, 73, 78, 75, + 76, 69, 83, 128, 87, 82, 73, 78, 75, 76, 69, 211, 87, 82, 73, 78, 75, 76, + 69, 68, 128, 87, 82, 69, 83, 84, 76, 69, 82, 83, 128, 87, 82, 69, 78, 67, + 72, 128, 87, 82, 69, 65, 84, 200, 87, 82, 65, 80, 80, 69, 196, 87, 82, + 65, 80, 128, 87, 79, 88, 128, 87, 79, 87, 128, 87, 79, 82, 83, 72, 73, + 80, 128, 87, 79, 82, 82, 73, 69, 196, 87, 79, 82, 77, 128, 87, 79, 82, + 76, 196, 87, 79, 82, 75, 69, 82, 128, 87, 79, 82, 75, 128, 87, 79, 82, + 203, 87, 79, 82, 68, 83, 80, 65, 67, 69, 128, 87, 79, 82, 196, 87, 79, + 80, 128, 87, 79, 79, 78, 128, 87, 79, 79, 76, 128, 87, 79, 79, 68, 83, + 45, 67, 82, 69, 197, 87, 79, 79, 68, 128, 87, 79, 78, 128, 87, 79, 206, + 87, 79, 77, 69, 78, 211, 87, 79, 77, 69, 206, 87, 79, 77, 65, 78, 211, + 87, 79, 77, 65, 78, 128, 87, 79, 77, 65, 206, 87, 79, 76, 79, 83, 79, + 128, 87, 79, 76, 198, 87, 79, 69, 128, 87, 79, 65, 128, 87, 79, 45, 55, + 128, 87, 79, 45, 54, 128, 87, 79, 45, 53, 128, 87, 79, 45, 52, 128, 87, + 79, 45, 51, 128, 87, 79, 45, 50, 128, 87, 79, 45, 49, 128, 87, 73, 84, + 72, 79, 85, 212, 87, 73, 84, 72, 73, 78, 128, 87, 73, 84, 72, 73, 206, + 87, 73, 82, 69, 76, 69, 83, 83, 128, 87, 73, 82, 69, 196, 87, 73, 78, 84, + 69, 82, 128, 87, 73, 78, 75, 73, 78, 199, 87, 73, 78, 75, 128, 87, 73, + 78, 74, 65, 128, 87, 73, 78, 71, 83, 128, 87, 73, 78, 71, 128, 87, 73, + 78, 69, 128, 87, 73, 78, 197, 87, 73, 78, 68, 85, 128, 87, 73, 78, 68, + 79, 87, 128, 87, 73, 78, 68, 128, 87, 73, 78, 196, 87, 73, 78, 128, 87, + 73, 76, 84, 69, 196, 87, 73, 71, 78, 89, 65, 78, 128, 87, 73, 71, 71, 76, + 217, 87, 73, 71, 71, 76, 69, 83, 128, 87, 73, 68, 84, 72, 128, 87, 73, + 68, 69, 78, 73, 78, 199, 87, 73, 68, 69, 45, 72, 69, 65, 68, 69, 196, 87, + 73, 68, 197, 87, 73, 65, 78, 71, 87, 65, 65, 75, 128, 87, 73, 65, 78, 71, + 128, 87, 73, 45, 53, 128, 87, 73, 45, 52, 128, 87, 73, 45, 51, 128, 87, + 73, 45, 50, 128, 87, 73, 45, 49, 128, 87, 72, 79, 76, 197, 87, 72, 73, + 84, 69, 45, 70, 69, 65, 84, 72, 69, 82, 69, 196, 87, 72, 73, 84, 69, 128, + 87, 72, 69, 69, 76, 69, 196, 87, 72, 69, 69, 76, 67, 72, 65, 73, 82, 128, + 87, 72, 69, 69, 76, 67, 72, 65, 73, 210, 87, 72, 69, 69, 76, 128, 87, 72, + 69, 69, 204, 87, 72, 69, 65, 84, 128, 87, 72, 65, 76, 69, 128, 87, 72, + 128, 87, 71, 128, 87, 69, 88, 128, 87, 69, 85, 88, 128, 87, 69, 212, 87, + 69, 83, 84, 69, 82, 206, 87, 69, 83, 84, 45, 67, 82, 69, 197, 87, 69, 83, + 84, 128, 87, 69, 83, 212, 87, 69, 80, 128, 87, 69, 79, 128, 87, 69, 78, + 128, 87, 69, 76, 76, 128, 87, 69, 73, 71, 72, 212, 87, 69, 73, 69, 82, + 83, 84, 82, 65, 83, 211, 87, 69, 73, 128, 87, 69, 69, 78, 128, 87, 69, + 68, 71, 69, 45, 84, 65, 73, 76, 69, 196, 87, 69, 68, 71, 69, 128, 87, 69, + 68, 68, 73, 78, 71, 128, 87, 69, 66, 128, 87, 69, 65, 82, 217, 87, 69, + 65, 80, 79, 78, 128, 87, 69, 45, 52, 128, 87, 69, 45, 51, 128, 87, 69, + 45, 50, 128, 87, 69, 45, 49, 128, 87, 67, 128, 87, 66, 128, 87, 65, 89, + 128, 87, 65, 217, 87, 65, 88, 73, 78, 199, 87, 65, 88, 128, 87, 65, 87, + 45, 65, 89, 73, 78, 45, 82, 69, 83, 72, 128, 87, 65, 87, 128, 87, 65, + 215, 87, 65, 86, 217, 87, 65, 86, 73, 78, 199, 87, 65, 86, 69, 83, 128, + 87, 65, 86, 69, 128, 87, 65, 86, 197, 87, 65, 85, 128, 87, 65, 84, 84, + 79, 128, 87, 65, 84, 69, 82, 77, 69, 76, 79, 78, 128, 87, 65, 84, 69, 82, + 128, 87, 65, 84, 69, 210, 87, 65, 84, 67, 72, 128, 87, 65, 84, 128, 87, + 65, 83, 84, 73, 78, 71, 128, 87, 65, 83, 84, 69, 66, 65, 83, 75, 69, 84, + 128, 87, 65, 83, 83, 65, 76, 76, 65, 77, 128, 87, 65, 83, 76, 65, 128, + 87, 65, 83, 76, 193, 87, 65, 83, 65, 76, 76, 65, 77, 128, 87, 65, 83, 65, + 76, 76, 65, 205, 87, 65, 83, 45, 83, 65, 76, 65, 65, 77, 128, 87, 65, 82, + 78, 73, 78, 199, 87, 65, 82, 65, 78, 199, 87, 65, 81, 70, 65, 128, 87, + 65, 80, 128, 87, 65, 78, 73, 78, 199, 87, 65, 78, 71, 75, 85, 79, 81, + 128, 87, 65, 78, 68, 69, 82, 69, 82, 128, 87, 65, 78, 68, 128, 87, 65, + 78, 67, 72, 207, 87, 65, 78, 128, 87, 65, 76, 76, 80, 76, 65, 78, 197, + 87, 65, 76, 76, 69, 196, 87, 65, 76, 76, 128, 87, 65, 76, 204, 87, 65, + 76, 75, 128, 87, 65, 76, 203, 87, 65, 73, 84, 73, 78, 71, 128, 87, 65, + 73, 83, 84, 128, 87, 65, 73, 128, 87, 65, 70, 70, 76, 69, 128, 87, 65, + 69, 78, 128, 87, 65, 69, 128, 87, 65, 68, 68, 65, 128, 87, 65, 65, 86, + 85, 128, 87, 65, 65, 74, 73, 66, 128, 87, 65, 65, 65, 76, 73, 72, 69, + 197, 87, 65, 45, 84, 65, 65, 65, 76, 65, 65, 128, 87, 65, 45, 83, 65, 76, + 76, 65, 77, 128, 87, 65, 45, 65, 65, 76, 73, 72, 128, 87, 65, 45, 53, + 128, 87, 65, 45, 52, 128, 87, 65, 45, 51, 128, 87, 65, 45, 50, 128, 87, + 65, 45, 49, 128, 87, 193, 87, 48, 50, 53, 128, 87, 48, 50, 52, 65, 128, + 87, 48, 50, 52, 128, 87, 48, 50, 51, 128, 87, 48, 50, 50, 128, 87, 48, + 50, 49, 128, 87, 48, 50, 48, 128, 87, 48, 49, 57, 128, 87, 48, 49, 56, + 65, 128, 87, 48, 49, 56, 128, 87, 48, 49, 55, 65, 128, 87, 48, 49, 55, + 128, 87, 48, 49, 54, 128, 87, 48, 49, 53, 128, 87, 48, 49, 52, 65, 128, + 87, 48, 49, 52, 128, 87, 48, 49, 51, 128, 87, 48, 49, 50, 128, 87, 48, + 49, 49, 128, 87, 48, 49, 48, 65, 128, 87, 48, 49, 48, 128, 87, 48, 48, + 57, 65, 128, 87, 48, 48, 57, 128, 87, 48, 48, 56, 128, 87, 48, 48, 55, + 128, 87, 48, 48, 54, 128, 87, 48, 48, 53, 128, 87, 48, 48, 52, 128, 87, + 48, 48, 51, 65, 128, 87, 48, 48, 51, 128, 87, 48, 48, 50, 128, 87, 48, + 48, 49, 128, 86, 90, 77, 69, 84, 128, 86, 90, 128, 86, 89, 88, 128, 86, + 89, 84, 128, 86, 89, 83, 79, 75, 79, 128, 86, 89, 83, 79, 75, 207, 86, + 89, 82, 88, 128, 86, 89, 82, 128, 86, 89, 80, 128, 86, 89, 128, 86, 88, + 128, 86, 87, 74, 128, 86, 87, 65, 128, 86, 87, 128, 86, 85, 88, 128, 86, + 85, 85, 128, 86, 85, 84, 128, 86, 85, 82, 88, 128, 86, 85, 82, 128, 86, + 85, 80, 128, 86, 85, 76, 71, 65, 210, 86, 85, 76, 67, 65, 78, 85, 83, + 128, 86, 85, 69, 81, 128, 86, 84, 83, 128, 86, 84, 128, 86, 83, 57, 57, + 128, 86, 83, 57, 56, 128, 86, 83, 57, 55, 128, 86, 83, 57, 54, 128, 86, + 83, 57, 53, 128, 86, 83, 57, 52, 128, 86, 83, 57, 51, 128, 86, 83, 57, + 50, 128, 86, 83, 57, 49, 128, 86, 83, 57, 48, 128, 86, 83, 57, 128, 86, + 83, 56, 57, 128, 86, 83, 56, 56, 128, 86, 83, 56, 55, 128, 86, 83, 56, + 54, 128, 86, 83, 56, 53, 128, 86, 83, 56, 52, 128, 86, 83, 56, 51, 128, + 86, 83, 56, 50, 128, 86, 83, 56, 49, 128, 86, 83, 56, 48, 128, 86, 83, + 56, 128, 86, 83, 55, 57, 128, 86, 83, 55, 56, 128, 86, 83, 55, 55, 128, + 86, 83, 55, 54, 128, 86, 83, 55, 53, 128, 86, 83, 55, 52, 128, 86, 83, + 55, 51, 128, 86, 83, 55, 50, 128, 86, 83, 55, 49, 128, 86, 83, 55, 48, + 128, 86, 83, 55, 128, 86, 83, 54, 57, 128, 86, 83, 54, 56, 128, 86, 83, + 54, 55, 128, 86, 83, 54, 54, 128, 86, 83, 54, 53, 128, 86, 83, 54, 52, + 128, 86, 83, 54, 51, 128, 86, 83, 54, 50, 128, 86, 83, 54, 49, 128, 86, + 83, 54, 48, 128, 86, 83, 54, 128, 86, 83, 53, 57, 128, 86, 83, 53, 56, + 128, 86, 83, 53, 55, 128, 86, 83, 53, 54, 128, 86, 83, 53, 53, 128, 86, + 83, 53, 52, 128, 86, 83, 53, 51, 128, 86, 83, 53, 50, 128, 86, 83, 53, + 49, 128, 86, 83, 53, 48, 128, 86, 83, 53, 128, 86, 83, 52, 57, 128, 86, + 83, 52, 56, 128, 86, 83, 52, 55, 128, 86, 83, 52, 54, 128, 86, 83, 52, + 53, 128, 86, 83, 52, 52, 128, 86, 83, 52, 51, 128, 86, 83, 52, 50, 128, + 86, 83, 52, 49, 128, 86, 83, 52, 48, 128, 86, 83, 52, 128, 86, 83, 51, + 57, 128, 86, 83, 51, 56, 128, 86, 83, 51, 55, 128, 86, 83, 51, 54, 128, + 86, 83, 51, 53, 128, 86, 83, 51, 52, 128, 86, 83, 51, 51, 128, 86, 83, + 51, 50, 128, 86, 83, 51, 49, 128, 86, 83, 51, 48, 128, 86, 83, 51, 128, + 86, 83, 50, 57, 128, 86, 83, 50, 56, 128, 86, 83, 50, 55, 128, 86, 83, + 50, 54, 128, 86, 83, 50, 53, 54, 128, 86, 83, 50, 53, 53, 128, 86, 83, + 50, 53, 52, 128, 86, 83, 50, 53, 51, 128, 86, 83, 50, 53, 50, 128, 86, + 83, 50, 53, 49, 128, 86, 83, 50, 53, 48, 128, 86, 83, 50, 53, 128, 86, + 83, 50, 52, 57, 128, 86, 83, 50, 52, 56, 128, 86, 83, 50, 52, 55, 128, + 86, 83, 50, 52, 54, 128, 86, 83, 50, 52, 53, 128, 86, 83, 50, 52, 52, + 128, 86, 83, 50, 52, 51, 128, 86, 83, 50, 52, 50, 128, 86, 83, 50, 52, + 49, 128, 86, 83, 50, 52, 48, 128, 86, 83, 50, 52, 128, 86, 83, 50, 51, + 57, 128, 86, 83, 50, 51, 56, 128, 86, 83, 50, 51, 55, 128, 86, 83, 50, + 51, 54, 128, 86, 83, 50, 51, 53, 128, 86, 83, 50, 51, 52, 128, 86, 83, + 50, 51, 51, 128, 86, 83, 50, 51, 50, 128, 86, 83, 50, 51, 49, 128, 86, + 83, 50, 51, 48, 128, 86, 83, 50, 51, 128, 86, 83, 50, 50, 57, 128, 86, + 83, 50, 50, 56, 128, 86, 83, 50, 50, 55, 128, 86, 83, 50, 50, 54, 128, + 86, 83, 50, 50, 53, 128, 86, 83, 50, 50, 52, 128, 86, 83, 50, 50, 51, + 128, 86, 83, 50, 50, 50, 128, 86, 83, 50, 50, 49, 128, 86, 83, 50, 50, + 48, 128, 86, 83, 50, 50, 128, 86, 83, 50, 49, 57, 128, 86, 83, 50, 49, + 56, 128, 86, 83, 50, 49, 55, 128, 86, 83, 50, 49, 54, 128, 86, 83, 50, + 49, 53, 128, 86, 83, 50, 49, 52, 128, 86, 83, 50, 49, 51, 128, 86, 83, + 50, 49, 50, 128, 86, 83, 50, 49, 49, 128, 86, 83, 50, 49, 48, 128, 86, + 83, 50, 49, 128, 86, 83, 50, 48, 57, 128, 86, 83, 50, 48, 56, 128, 86, + 83, 50, 48, 55, 128, 86, 83, 50, 48, 54, 128, 86, 83, 50, 48, 53, 128, + 86, 83, 50, 48, 52, 128, 86, 83, 50, 48, 51, 128, 86, 83, 50, 48, 50, + 128, 86, 83, 50, 48, 49, 128, 86, 83, 50, 48, 48, 128, 86, 83, 50, 48, + 128, 86, 83, 50, 128, 86, 83, 49, 57, 57, 128, 86, 83, 49, 57, 56, 128, + 86, 83, 49, 57, 55, 128, 86, 83, 49, 57, 54, 128, 86, 83, 49, 57, 53, + 128, 86, 83, 49, 57, 52, 128, 86, 83, 49, 57, 51, 128, 86, 83, 49, 57, + 50, 128, 86, 83, 49, 57, 49, 128, 86, 83, 49, 57, 48, 128, 86, 83, 49, + 57, 128, 86, 83, 49, 56, 57, 128, 86, 83, 49, 56, 56, 128, 86, 83, 49, + 56, 55, 128, 86, 83, 49, 56, 54, 128, 86, 83, 49, 56, 53, 128, 86, 83, + 49, 56, 52, 128, 86, 83, 49, 56, 51, 128, 86, 83, 49, 56, 50, 128, 86, + 83, 49, 56, 49, 128, 86, 83, 49, 56, 48, 128, 86, 83, 49, 56, 128, 86, + 83, 49, 55, 57, 128, 86, 83, 49, 55, 56, 128, 86, 83, 49, 55, 55, 128, + 86, 83, 49, 55, 54, 128, 86, 83, 49, 55, 53, 128, 86, 83, 49, 55, 52, + 128, 86, 83, 49, 55, 51, 128, 86, 83, 49, 55, 50, 128, 86, 83, 49, 55, + 49, 128, 86, 83, 49, 55, 48, 128, 86, 83, 49, 55, 128, 86, 83, 49, 54, + 57, 128, 86, 83, 49, 54, 56, 128, 86, 83, 49, 54, 55, 128, 86, 83, 49, + 54, 54, 128, 86, 83, 49, 54, 53, 128, 86, 83, 49, 54, 52, 128, 86, 83, + 49, 54, 51, 128, 86, 83, 49, 54, 50, 128, 86, 83, 49, 54, 49, 128, 86, + 83, 49, 54, 48, 128, 86, 83, 49, 54, 128, 86, 83, 49, 53, 57, 128, 86, + 83, 49, 53, 56, 128, 86, 83, 49, 53, 55, 128, 86, 83, 49, 53, 54, 128, + 86, 83, 49, 53, 53, 128, 86, 83, 49, 53, 52, 128, 86, 83, 49, 53, 51, + 128, 86, 83, 49, 53, 50, 128, 86, 83, 49, 53, 49, 128, 86, 83, 49, 53, + 48, 128, 86, 83, 49, 53, 128, 86, 83, 49, 52, 57, 128, 86, 83, 49, 52, + 56, 128, 86, 83, 49, 52, 55, 128, 86, 83, 49, 52, 54, 128, 86, 83, 49, + 52, 53, 128, 86, 83, 49, 52, 52, 128, 86, 83, 49, 52, 51, 128, 86, 83, + 49, 52, 50, 128, 86, 83, 49, 52, 49, 128, 86, 83, 49, 52, 48, 128, 86, + 83, 49, 52, 128, 86, 83, 49, 51, 57, 128, 86, 83, 49, 51, 56, 128, 86, + 83, 49, 51, 55, 128, 86, 83, 49, 51, 54, 128, 86, 83, 49, 51, 53, 128, + 86, 83, 49, 51, 52, 128, 86, 83, 49, 51, 51, 128, 86, 83, 49, 51, 50, + 128, 86, 83, 49, 51, 49, 128, 86, 83, 49, 51, 48, 128, 86, 83, 49, 51, + 128, 86, 83, 49, 50, 57, 128, 86, 83, 49, 50, 56, 128, 86, 83, 49, 50, + 55, 128, 86, 83, 49, 50, 54, 128, 86, 83, 49, 50, 53, 128, 86, 83, 49, + 50, 52, 128, 86, 83, 49, 50, 51, 128, 86, 83, 49, 50, 50, 128, 86, 83, + 49, 50, 49, 128, 86, 83, 49, 50, 48, 128, 86, 83, 49, 50, 128, 86, 83, + 49, 49, 57, 128, 86, 83, 49, 49, 56, 128, 86, 83, 49, 49, 55, 128, 86, + 83, 49, 49, 54, 128, 86, 83, 49, 49, 53, 128, 86, 83, 49, 49, 52, 128, + 86, 83, 49, 49, 51, 128, 86, 83, 49, 49, 50, 128, 86, 83, 49, 49, 49, + 128, 86, 83, 49, 49, 48, 128, 86, 83, 49, 49, 128, 86, 83, 49, 48, 57, + 128, 86, 83, 49, 48, 56, 128, 86, 83, 49, 48, 55, 128, 86, 83, 49, 48, + 54, 128, 86, 83, 49, 48, 53, 128, 86, 83, 49, 48, 52, 128, 86, 83, 49, + 48, 51, 128, 86, 83, 49, 48, 50, 128, 86, 83, 49, 48, 49, 128, 86, 83, + 49, 48, 48, 128, 86, 83, 49, 48, 128, 86, 83, 49, 128, 86, 83, 128, 86, + 82, 65, 75, 72, 73, 89, 193, 86, 82, 65, 67, 72, 89, 128, 86, 81, 128, + 86, 79, 88, 128, 86, 79, 87, 69, 76, 45, 67, 65, 82, 82, 73, 69, 210, 86, + 79, 87, 128, 86, 79, 85, 128, 86, 79, 84, 128, 86, 79, 211, 86, 79, 80, + 128, 86, 79, 79, 73, 128, 86, 79, 79, 128, 86, 79, 77, 73, 84, 73, 78, + 71, 128, 86, 79, 77, 128, 86, 79, 76, 85, 77, 197, 86, 79, 76, 84, 65, + 71, 197, 86, 79, 76, 76, 69, 89, 66, 65, 76, 76, 128, 86, 79, 76, 67, 65, + 78, 79, 128, 86, 79, 76, 65, 80, 85, 203, 86, 79, 73, 68, 69, 196, 86, + 79, 73, 196, 86, 79, 73, 67, 73, 78, 71, 128, 86, 79, 73, 67, 69, 76, 69, + 83, 211, 86, 79, 73, 67, 69, 196, 86, 79, 68, 128, 86, 79, 67, 65, 76, + 73, 90, 65, 84, 73, 79, 206, 86, 79, 67, 65, 204, 86, 79, 128, 86, 73, + 89, 79, 128, 86, 73, 88, 128, 86, 73, 84, 82, 73, 79, 76, 45, 50, 128, + 86, 73, 84, 82, 73, 79, 76, 128, 86, 73, 84, 72, 75, 85, 81, 201, 86, 73, + 84, 65, 69, 45, 50, 128, 86, 73, 84, 65, 69, 128, 86, 73, 84, 128, 86, + 73, 83, 73, 71, 79, 84, 72, 73, 195, 86, 73, 83, 65, 82, 71, 65, 89, 65, + 128, 86, 73, 83, 65, 82, 71, 65, 128, 86, 73, 83, 65, 82, 71, 193, 86, + 73, 82, 73, 65, 77, 128, 86, 73, 82, 71, 79, 128, 86, 73, 82, 71, 65, + 128, 86, 73, 82, 65, 77, 65, 128, 86, 73, 80, 128, 86, 73, 79, 76, 73, + 78, 128, 86, 73, 78, 69, 71, 65, 82, 45, 51, 128, 86, 73, 78, 69, 71, 65, + 82, 45, 50, 128, 86, 73, 78, 69, 71, 65, 82, 128, 86, 73, 78, 69, 71, 65, + 210, 86, 73, 78, 69, 128, 86, 73, 78, 197, 86, 73, 78, 128, 86, 73, 76, + 76, 65, 71, 69, 128, 86, 73, 73, 128, 86, 73, 71, 73, 78, 84, 73, 76, 69, + 128, 86, 73, 69, 88, 128, 86, 73, 69, 87, 73, 78, 199, 86, 73, 69, 87, + 69, 82, 128, 86, 73, 69, 87, 68, 65, 84, 193, 86, 73, 69, 84, 78, 65, 77, + 69, 83, 197, 86, 73, 69, 84, 128, 86, 73, 69, 212, 86, 73, 69, 80, 128, + 86, 73, 69, 128, 86, 73, 68, 74, 45, 50, 128, 86, 73, 68, 74, 128, 86, + 73, 68, 69, 79, 67, 65, 83, 83, 69, 84, 84, 69, 128, 86, 73, 68, 69, 207, + 86, 73, 68, 65, 128, 86, 73, 67, 84, 79, 82, 217, 86, 73, 66, 82, 65, 84, + 73, 79, 206, 86, 72, 65, 128, 86, 70, 65, 128, 86, 69, 89, 90, 128, 86, + 69, 88, 128, 86, 69, 87, 128, 86, 69, 215, 86, 69, 85, 88, 128, 86, 69, + 85, 77, 128, 86, 69, 85, 65, 69, 80, 69, 78, 128, 86, 69, 85, 65, 69, + 128, 86, 69, 83, 84, 65, 128, 86, 69, 83, 84, 128, 86, 69, 83, 83, 69, + 204, 86, 69, 82, 217, 86, 69, 82, 84, 73, 67, 65, 76, 76, 89, 128, 86, + 69, 82, 84, 73, 67, 65, 76, 76, 217, 86, 69, 82, 84, 73, 67, 65, 76, 45, + 48, 54, 45, 48, 54, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 54, 45, + 48, 53, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 54, 45, 48, 52, 128, + 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 54, 45, 48, 51, 128, 86, 69, 82, + 84, 73, 67, 65, 76, 45, 48, 54, 45, 48, 50, 128, 86, 69, 82, 84, 73, 67, + 65, 76, 45, 48, 54, 45, 48, 49, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, + 48, 54, 45, 48, 48, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 53, 45, + 48, 54, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 53, 45, 48, 53, 128, + 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 53, 45, 48, 52, 128, 86, 69, 82, + 84, 73, 67, 65, 76, 45, 48, 53, 45, 48, 51, 128, 86, 69, 82, 84, 73, 67, + 65, 76, 45, 48, 53, 45, 48, 50, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, + 48, 53, 45, 48, 49, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 53, 45, + 48, 48, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 52, 45, 48, 54, 128, + 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 52, 45, 48, 53, 128, 86, 69, 82, + 84, 73, 67, 65, 76, 45, 48, 52, 45, 48, 52, 128, 86, 69, 82, 84, 73, 67, + 65, 76, 45, 48, 52, 45, 48, 51, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, + 48, 52, 45, 48, 50, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 52, 45, + 48, 49, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 52, 45, 48, 48, 128, + 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 51, 45, 48, 54, 128, 86, 69, 82, + 84, 73, 67, 65, 76, 45, 48, 51, 45, 48, 53, 128, 86, 69, 82, 84, 73, 67, + 65, 76, 45, 48, 51, 45, 48, 52, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, + 48, 51, 45, 48, 51, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 51, 45, + 48, 50, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 51, 45, 48, 49, 128, + 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 51, 45, 48, 48, 128, 86, 69, 82, + 84, 73, 67, 65, 76, 45, 48, 50, 45, 48, 54, 128, 86, 69, 82, 84, 73, 67, + 65, 76, 45, 48, 50, 45, 48, 53, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, + 48, 50, 45, 48, 52, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 50, 45, + 48, 51, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 50, 45, 48, 50, 128, + 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 50, 45, 48, 49, 128, 86, 69, 82, + 84, 73, 67, 65, 76, 45, 48, 50, 45, 48, 48, 128, 86, 69, 82, 84, 73, 67, + 65, 76, 45, 48, 49, 45, 48, 54, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, + 48, 49, 45, 48, 53, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 49, 45, + 48, 52, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 49, 45, 48, 51, 128, + 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 49, 45, 48, 50, 128, 86, 69, 82, + 84, 73, 67, 65, 76, 45, 48, 49, 45, 48, 49, 128, 86, 69, 82, 84, 73, 67, + 65, 76, 45, 48, 49, 45, 48, 48, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, + 48, 48, 45, 48, 54, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 48, 45, + 48, 53, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 48, 45, 48, 52, 128, + 86, 69, 82, 84, 73, 67, 65, 76, 45, 48, 48, 45, 48, 51, 128, 86, 69, 82, + 84, 73, 67, 65, 76, 45, 48, 48, 45, 48, 50, 128, 86, 69, 82, 84, 73, 67, + 65, 76, 45, 48, 48, 45, 48, 49, 128, 86, 69, 82, 84, 73, 67, 65, 76, 45, + 48, 48, 45, 48, 48, 128, 86, 69, 82, 84, 73, 67, 65, 76, 128, 86, 69, 82, + 83, 73, 67, 76, 69, 128, 86, 69, 82, 83, 197, 86, 69, 82, 71, 69, 128, + 86, 69, 82, 68, 73, 71, 82, 73, 83, 128, 86, 69, 82, 128, 86, 69, 80, + 128, 86, 69, 78, 68, 128, 86, 69, 76, 73, 128, 86, 69, 73, 76, 128, 86, + 69, 72, 73, 67, 76, 69, 128, 86, 69, 72, 128, 86, 69, 200, 86, 69, 69, + 128, 86, 69, 197, 86, 69, 68, 69, 128, 86, 69, 67, 84, 79, 210, 86, 67, + 128, 86, 65, 89, 65, 78, 78, 65, 128, 86, 65, 88, 128, 86, 65, 86, 128, + 86, 65, 214, 86, 65, 85, 128, 86, 65, 84, 72, 89, 128, 86, 65, 84, 128, + 86, 65, 83, 84, 78, 69, 83, 211, 86, 65, 83, 73, 83, 128, 86, 65, 82, 89, + 211, 86, 65, 82, 73, 75, 65, 128, 86, 65, 82, 73, 65, 78, 84, 128, 86, + 65, 82, 73, 65, 78, 212, 86, 65, 82, 73, 65, 128, 86, 65, 82, 73, 193, + 86, 65, 82, 69, 73, 65, 201, 86, 65, 82, 69, 73, 193, 86, 65, 82, 65, 65, + 75, 65, 78, 128, 86, 65, 80, 79, 85, 82, 83, 128, 86, 65, 80, 128, 86, + 65, 78, 69, 128, 86, 65, 77, 80, 73, 82, 69, 128, 86, 65, 77, 65, 71, 79, + 77, 85, 75, 72, 65, 128, 86, 65, 77, 65, 71, 79, 77, 85, 75, 72, 193, 86, + 65, 76, 76, 69, 89, 128, 86, 65, 75, 65, 73, 89, 65, 82, 65, 65, 128, 86, + 65, 74, 128, 86, 65, 73, 128, 86, 65, 72, 128, 86, 65, 200, 86, 65, 65, + 86, 85, 128, 86, 65, 65, 128, 86, 193, 86, 48, 52, 48, 65, 128, 86, 48, + 52, 48, 128, 86, 48, 51, 57, 128, 86, 48, 51, 56, 128, 86, 48, 51, 55, + 65, 128, 86, 48, 51, 55, 128, 86, 48, 51, 54, 128, 86, 48, 51, 53, 128, + 86, 48, 51, 52, 128, 86, 48, 51, 51, 65, 128, 86, 48, 51, 51, 128, 86, + 48, 51, 50, 128, 86, 48, 51, 49, 65, 128, 86, 48, 51, 49, 128, 86, 48, + 51, 48, 65, 128, 86, 48, 51, 48, 128, 86, 48, 50, 57, 65, 128, 86, 48, + 50, 57, 128, 86, 48, 50, 56, 65, 128, 86, 48, 50, 56, 128, 86, 48, 50, + 55, 128, 86, 48, 50, 54, 128, 86, 48, 50, 53, 128, 86, 48, 50, 52, 128, + 86, 48, 50, 51, 65, 128, 86, 48, 50, 51, 128, 86, 48, 50, 50, 128, 86, + 48, 50, 49, 128, 86, 48, 50, 48, 76, 128, 86, 48, 50, 48, 75, 128, 86, + 48, 50, 48, 74, 128, 86, 48, 50, 48, 73, 128, 86, 48, 50, 48, 72, 128, + 86, 48, 50, 48, 71, 128, 86, 48, 50, 48, 70, 128, 86, 48, 50, 48, 69, + 128, 86, 48, 50, 48, 68, 128, 86, 48, 50, 48, 67, 128, 86, 48, 50, 48, + 66, 128, 86, 48, 50, 48, 65, 128, 86, 48, 50, 48, 128, 86, 48, 49, 57, + 128, 86, 48, 49, 56, 128, 86, 48, 49, 55, 128, 86, 48, 49, 54, 128, 86, + 48, 49, 53, 128, 86, 48, 49, 52, 128, 86, 48, 49, 51, 128, 86, 48, 49, + 50, 66, 128, 86, 48, 49, 50, 65, 128, 86, 48, 49, 50, 128, 86, 48, 49, + 49, 68, 128, 86, 48, 49, 49, 67, 128, 86, 48, 49, 49, 66, 128, 86, 48, + 49, 49, 65, 128, 86, 48, 49, 49, 128, 86, 48, 49, 48, 128, 86, 48, 48, + 57, 128, 86, 48, 48, 56, 128, 86, 48, 48, 55, 66, 128, 86, 48, 48, 55, + 65, 128, 86, 48, 48, 55, 128, 86, 48, 48, 54, 128, 86, 48, 48, 53, 128, + 86, 48, 48, 52, 128, 86, 48, 48, 51, 128, 86, 48, 48, 50, 65, 128, 86, + 48, 48, 50, 128, 86, 48, 48, 49, 73, 128, 86, 48, 48, 49, 72, 128, 86, + 48, 48, 49, 71, 128, 86, 48, 48, 49, 70, 128, 86, 48, 48, 49, 69, 128, + 86, 48, 48, 49, 68, 128, 86, 48, 48, 49, 67, 128, 86, 48, 48, 49, 66, + 128, 86, 48, 48, 49, 65, 128, 86, 48, 48, 49, 128, 85, 90, 85, 128, 85, + 90, 72, 65, 75, 75, 85, 128, 85, 90, 51, 128, 85, 90, 179, 85, 90, 128, + 85, 89, 71, 72, 85, 210, 85, 89, 65, 78, 78, 65, 128, 85, 89, 128, 85, + 87, 85, 128, 85, 85, 89, 65, 78, 78, 65, 128, 85, 85, 85, 85, 128, 85, + 85, 85, 51, 128, 85, 85, 85, 50, 128, 85, 85, 69, 128, 85, 84, 85, 75, + 73, 128, 85, 83, 83, 85, 51, 128, 85, 83, 83, 85, 128, 85, 83, 72, 88, + 128, 85, 83, 72, 85, 77, 88, 128, 85, 83, 72, 69, 78, 78, 65, 128, 85, + 83, 72, 50, 128, 85, 83, 72, 128, 85, 83, 200, 85, 83, 69, 196, 85, 83, + 69, 45, 50, 128, 85, 83, 69, 45, 49, 128, 85, 83, 69, 128, 85, 83, 197, + 85, 82, 85, 218, 85, 82, 85, 83, 128, 85, 82, 85, 68, 65, 128, 85, 82, + 85, 68, 193, 85, 82, 85, 128, 85, 82, 213, 85, 82, 78, 128, 85, 82, 73, + 78, 69, 128, 85, 82, 73, 51, 128, 85, 82, 73, 128, 85, 82, 65, 78, 85, + 83, 128, 85, 82, 65, 128, 85, 82, 52, 128, 85, 82, 50, 128, 85, 82, 178, + 85, 80, 87, 65, 82, 68, 83, 128, 85, 80, 87, 65, 82, 68, 211, 85, 80, 87, + 65, 82, 68, 128, 85, 80, 87, 65, 82, 196, 85, 80, 84, 85, 82, 78, 128, + 85, 80, 83, 73, 76, 79, 78, 128, 85, 80, 83, 73, 76, 79, 206, 85, 80, 83, + 73, 68, 69, 45, 68, 79, 87, 206, 85, 80, 82, 73, 71, 72, 212, 85, 80, 80, + 69, 82, 128, 85, 80, 65, 68, 72, 77, 65, 78, 73, 89, 65, 128, 85, 80, 45, + 80, 79, 73, 78, 84, 73, 78, 199, 85, 79, 78, 128, 85, 79, 71, 128, 85, + 78, 78, 128, 85, 78, 77, 65, 82, 82, 73, 69, 196, 85, 78, 75, 78, 79, 87, + 78, 128, 85, 78, 75, 128, 85, 78, 73, 86, 69, 82, 83, 65, 204, 85, 78, + 73, 84, 89, 128, 85, 78, 73, 84, 69, 196, 85, 78, 73, 84, 128, 85, 78, + 73, 212, 85, 78, 73, 79, 78, 128, 85, 78, 73, 79, 206, 85, 78, 73, 70, + 79, 82, 77, 128, 85, 78, 73, 70, 73, 69, 196, 85, 78, 73, 67, 79, 82, + 206, 85, 78, 69, 86, 69, 206, 85, 78, 68, 207, 85, 78, 68, 69, 82, 84, + 73, 69, 128, 85, 78, 68, 69, 82, 76, 73, 78, 197, 85, 78, 68, 69, 82, 68, + 79, 84, 128, 85, 78, 68, 69, 82, 66, 65, 82, 128, 85, 78, 68, 69, 82, + 128, 85, 78, 68, 69, 210, 85, 78, 67, 73, 193, 85, 78, 67, 69, 82, 84, + 65, 73, 78, 84, 217, 85, 78, 66, 76, 69, 78, 68, 69, 196, 85, 78, 65, 83, + 80, 73, 82, 65, 84, 69, 68, 128, 85, 78, 65, 80, 128, 85, 78, 65, 77, 85, + 83, 69, 196, 85, 78, 65, 128, 85, 206, 85, 77, 85, 77, 128, 85, 77, 85, + 205, 85, 77, 66, 82, 69, 76, 76, 65, 128, 85, 77, 66, 82, 69, 76, 76, + 193, 85, 77, 66, 73, 78, 128, 85, 75, 85, 128, 85, 75, 82, 65, 73, 78, + 73, 65, 206, 85, 75, 65, 82, 65, 128, 85, 75, 65, 82, 193, 85, 75, 128, + 85, 73, 90, 128, 85, 73, 88, 128, 85, 73, 85, 90, 128, 85, 73, 85, 88, + 128, 85, 73, 85, 81, 128, 85, 73, 85, 67, 128, 85, 73, 81, 128, 85, 73, + 76, 76, 69, 65, 78, 78, 128, 85, 73, 71, 72, 85, 210, 85, 73, 67, 128, + 85, 72, 68, 128, 85, 71, 65, 82, 73, 84, 73, 195, 85, 69, 90, 128, 85, + 69, 89, 128, 85, 69, 88, 128, 85, 69, 78, 128, 85, 69, 73, 128, 85, 69, + 69, 128, 85, 69, 67, 128, 85, 69, 65, 128, 85, 68, 85, 71, 128, 85, 68, + 65, 84, 84, 65, 128, 85, 68, 65, 84, 84, 193, 85, 68, 65, 82, 75, 65, + 128, 85, 68, 65, 65, 84, 128, 85, 68, 128, 85, 196, 85, 66, 85, 70, 73, + 76, 73, 128, 85, 66, 72, 65, 89, 65, 84, 207, 85, 66, 65, 68, 65, 77, 65, + 128, 85, 66, 128, 85, 65, 84, 72, 128, 85, 65, 78, 71, 128, 85, 65, 128, + 85, 178, 85, 48, 52, 50, 128, 85, 48, 52, 49, 128, 85, 48, 52, 48, 128, + 85, 48, 51, 57, 128, 85, 48, 51, 56, 128, 85, 48, 51, 55, 128, 85, 48, + 51, 54, 128, 85, 48, 51, 53, 128, 85, 48, 51, 52, 128, 85, 48, 51, 51, + 128, 85, 48, 51, 50, 65, 128, 85, 48, 51, 50, 128, 85, 48, 51, 49, 128, + 85, 48, 51, 48, 128, 85, 48, 50, 57, 65, 128, 85, 48, 50, 57, 128, 85, + 48, 50, 56, 128, 85, 48, 50, 55, 128, 85, 48, 50, 54, 128, 85, 48, 50, + 53, 128, 85, 48, 50, 52, 128, 85, 48, 50, 51, 65, 128, 85, 48, 50, 51, + 128, 85, 48, 50, 50, 128, 85, 48, 50, 49, 128, 85, 48, 50, 48, 128, 85, + 48, 49, 57, 128, 85, 48, 49, 56, 128, 85, 48, 49, 55, 128, 85, 48, 49, + 54, 128, 85, 48, 49, 53, 128, 85, 48, 49, 52, 128, 85, 48, 49, 51, 128, + 85, 48, 49, 50, 128, 85, 48, 49, 49, 128, 85, 48, 49, 48, 128, 85, 48, + 48, 57, 128, 85, 48, 48, 56, 128, 85, 48, 48, 55, 128, 85, 48, 48, 54, + 66, 128, 85, 48, 48, 54, 65, 128, 85, 48, 48, 54, 128, 85, 48, 48, 53, + 128, 85, 48, 48, 52, 128, 85, 48, 48, 51, 128, 85, 48, 48, 50, 128, 85, + 48, 48, 49, 128, 85, 45, 83, 72, 65, 80, 69, 196, 85, 45, 73, 45, 73, + 128, 85, 45, 69, 79, 45, 69, 85, 128, 85, 45, 66, 82, 74, 71, 85, 128, + 85, 45, 53, 128, 84, 90, 85, 128, 84, 90, 79, 65, 128, 84, 90, 79, 128, + 84, 90, 73, 210, 84, 90, 73, 128, 84, 90, 69, 69, 128, 84, 90, 69, 128, + 84, 90, 65, 65, 128, 84, 90, 65, 128, 84, 90, 128, 84, 89, 210, 84, 89, + 80, 69, 45, 183, 84, 89, 80, 69, 45, 54, 128, 84, 89, 80, 69, 45, 182, + 84, 89, 80, 69, 45, 53, 128, 84, 89, 80, 69, 45, 181, 84, 89, 80, 69, 45, + 52, 128, 84, 89, 80, 69, 45, 180, 84, 89, 80, 69, 45, 51, 128, 84, 89, + 80, 69, 45, 179, 84, 89, 80, 69, 45, 178, 84, 89, 80, 69, 45, 49, 45, 50, + 128, 84, 89, 80, 69, 45, 177, 84, 89, 80, 197, 84, 89, 79, 128, 84, 89, + 73, 128, 84, 89, 69, 128, 84, 89, 65, 89, 128, 84, 89, 65, 128, 84, 88, + 87, 86, 128, 84, 88, 87, 214, 84, 88, 72, 69, 69, 202, 84, 88, 65, 128, + 84, 87, 79, 79, 128, 84, 87, 79, 45, 87, 65, 217, 84, 87, 79, 45, 84, 72, + 73, 82, 84, 89, 128, 84, 87, 79, 45, 76, 73, 78, 197, 84, 87, 79, 45, 72, + 69, 65, 68, 69, 196, 84, 87, 79, 45, 69, 205, 84, 87, 79, 45, 67, 73, 82, + 67, 76, 197, 84, 87, 73, 83, 84, 73, 78, 71, 128, 84, 87, 73, 83, 84, 69, + 196, 84, 87, 73, 73, 128, 84, 87, 73, 128, 84, 87, 69, 78, 84, 89, 45, + 84, 87, 79, 128, 84, 87, 69, 78, 84, 89, 45, 84, 87, 207, 84, 87, 69, 78, + 84, 89, 45, 84, 72, 82, 69, 69, 128, 84, 87, 69, 78, 84, 89, 45, 83, 73, + 88, 128, 84, 87, 69, 78, 84, 89, 45, 83, 69, 86, 69, 78, 128, 84, 87, 69, + 78, 84, 89, 45, 79, 78, 69, 128, 84, 87, 69, 78, 84, 89, 45, 78, 73, 78, + 69, 128, 84, 87, 69, 78, 84, 89, 45, 70, 79, 85, 82, 128, 84, 87, 69, 78, + 84, 89, 45, 70, 73, 86, 69, 128, 84, 87, 69, 78, 84, 89, 45, 70, 73, 86, + 197, 84, 87, 69, 78, 84, 89, 45, 69, 73, 71, 72, 84, 200, 84, 87, 69, 78, + 84, 89, 45, 69, 73, 71, 72, 84, 128, 84, 87, 69, 78, 84, 89, 128, 84, 87, + 69, 78, 84, 217, 84, 87, 69, 78, 84, 73, 69, 84, 72, 83, 128, 84, 87, 69, + 78, 84, 73, 69, 84, 72, 128, 84, 87, 69, 76, 86, 69, 45, 84, 72, 73, 82, + 84, 89, 128, 84, 87, 69, 76, 86, 69, 128, 84, 87, 69, 76, 86, 197, 84, + 87, 69, 76, 70, 84, 72, 83, 128, 84, 87, 69, 76, 70, 84, 72, 128, 84, 87, + 69, 128, 84, 87, 65, 65, 128, 84, 87, 65, 128, 84, 86, 82, 73, 68, 79, + 128, 84, 86, 73, 77, 65, 68, 85, 210, 84, 85, 88, 69, 68, 79, 128, 84, + 85, 88, 128, 84, 85, 85, 77, 85, 128, 84, 85, 85, 128, 84, 85, 84, 84, + 89, 128, 84, 85, 84, 69, 89, 65, 83, 65, 84, 128, 84, 85, 84, 128, 84, + 85, 82, 88, 128, 84, 85, 82, 85, 128, 84, 85, 82, 84, 76, 69, 128, 84, + 85, 82, 79, 50, 128, 84, 85, 82, 78, 83, 84, 73, 76, 69, 128, 84, 85, 82, + 206, 84, 85, 82, 75, 73, 83, 200, 84, 85, 82, 75, 73, 195, 84, 85, 82, + 75, 69, 89, 128, 84, 85, 82, 66, 65, 78, 128, 84, 85, 82, 128, 84, 85, + 210, 84, 85, 80, 78, 73, 128, 84, 85, 80, 128, 84, 85, 79, 88, 128, 84, + 85, 79, 84, 128, 84, 85, 79, 80, 128, 84, 85, 79, 128, 84, 85, 78, 78, + 89, 128, 84, 85, 77, 69, 84, 69, 83, 128, 84, 85, 77, 66, 76, 69, 210, + 84, 85, 77, 65, 69, 128, 84, 85, 77, 128, 84, 85, 205, 84, 85, 76, 73, + 80, 128, 84, 85, 75, 87, 69, 78, 84, 73, 83, 128, 84, 85, 75, 128, 84, + 85, 71, 82, 73, 203, 84, 85, 71, 50, 128, 84, 85, 71, 178, 84, 85, 66, + 69, 128, 84, 85, 66, 128, 84, 85, 65, 82, 69, 199, 84, 85, 65, 69, 80, + 128, 84, 85, 65, 69, 128, 84, 85, 45, 84, 79, 128, 84, 85, 45, 52, 128, + 84, 85, 45, 51, 128, 84, 85, 45, 50, 128, 84, 85, 45, 49, 128, 84, 213, + 84, 84, 85, 85, 128, 84, 84, 85, 68, 68, 65, 71, 128, 84, 84, 85, 68, 68, + 65, 65, 71, 128, 84, 84, 85, 128, 84, 84, 84, 72, 65, 128, 84, 84, 84, + 65, 128, 84, 84, 83, 85, 128, 84, 84, 83, 79, 128, 84, 84, 83, 73, 128, + 84, 84, 83, 69, 69, 128, 84, 84, 83, 69, 128, 84, 84, 83, 65, 128, 84, + 84, 79, 79, 128, 84, 84, 73, 73, 128, 84, 84, 73, 128, 84, 84, 72, 87, + 69, 128, 84, 84, 72, 85, 128, 84, 84, 72, 79, 79, 128, 84, 84, 72, 79, + 128, 84, 84, 72, 73, 128, 84, 84, 72, 69, 69, 128, 84, 84, 72, 69, 128, + 84, 84, 72, 65, 65, 128, 84, 84, 72, 128, 84, 84, 69, 72, 69, 72, 128, + 84, 84, 69, 72, 69, 200, 84, 84, 69, 72, 128, 84, 84, 69, 200, 84, 84, + 69, 69, 128, 84, 84, 65, 89, 65, 78, 78, 65, 128, 84, 84, 65, 85, 128, + 84, 84, 65, 73, 128, 84, 84, 65, 65, 128, 84, 84, 50, 128, 84, 83, 87, + 69, 128, 84, 83, 87, 66, 128, 84, 83, 87, 65, 128, 84, 83, 86, 128, 84, + 83, 83, 69, 128, 84, 83, 83, 65, 128, 84, 83, 79, 214, 84, 83, 73, 85, + 128, 84, 83, 72, 85, 71, 83, 128, 84, 83, 72, 79, 79, 75, 128, 84, 83, + 72, 79, 79, 203, 84, 83, 72, 79, 79, 74, 128, 84, 83, 72, 69, 83, 128, + 84, 83, 72, 69, 71, 128, 84, 83, 72, 69, 199, 84, 83, 72, 69, 69, 74, + 128, 84, 83, 72, 69, 128, 84, 83, 72, 65, 194, 84, 83, 72, 65, 128, 84, + 83, 69, 82, 69, 128, 84, 83, 69, 69, 66, 128, 84, 83, 65, 84, 193, 84, + 83, 65, 68, 73, 128, 84, 83, 65, 68, 201, 84, 83, 65, 66, 128, 84, 83, + 65, 65, 68, 73, 89, 128, 84, 83, 65, 65, 128, 84, 83, 193, 84, 82, 89, + 66, 76, 73, 79, 206, 84, 82, 89, 65, 83, 79, 83, 84, 82, 69, 76, 78, 65, + 89, 65, 128, 84, 82, 89, 65, 83, 79, 80, 79, 86, 79, 68, 78, 65, 89, 65, + 128, 84, 82, 89, 65, 83, 79, 71, 76, 65, 83, 78, 65, 89, 65, 128, 84, 82, + 89, 65, 83, 75, 65, 128, 84, 82, 85, 84, 72, 128, 84, 82, 85, 78, 75, + 128, 84, 82, 85, 78, 67, 65, 84, 69, 196, 84, 82, 85, 77, 80, 69, 84, + 128, 84, 82, 85, 77, 80, 45, 57, 128, 84, 82, 85, 77, 80, 45, 56, 128, + 84, 82, 85, 77, 80, 45, 55, 128, 84, 82, 85, 77, 80, 45, 54, 128, 84, 82, + 85, 77, 80, 45, 53, 128, 84, 82, 85, 77, 80, 45, 52, 128, 84, 82, 85, 77, + 80, 45, 51, 128, 84, 82, 85, 77, 80, 45, 50, 49, 128, 84, 82, 85, 77, 80, + 45, 50, 48, 128, 84, 82, 85, 77, 80, 45, 50, 128, 84, 82, 85, 77, 80, 45, + 49, 57, 128, 84, 82, 85, 77, 80, 45, 49, 56, 128, 84, 82, 85, 77, 80, 45, + 49, 55, 128, 84, 82, 85, 77, 80, 45, 49, 54, 128, 84, 82, 85, 77, 80, 45, + 49, 53, 128, 84, 82, 85, 77, 80, 45, 49, 52, 128, 84, 82, 85, 77, 80, 45, + 49, 51, 128, 84, 82, 85, 77, 80, 45, 49, 50, 128, 84, 82, 85, 77, 80, 45, + 49, 49, 128, 84, 82, 85, 77, 80, 45, 49, 48, 128, 84, 82, 85, 77, 80, 45, + 49, 128, 84, 82, 85, 69, 128, 84, 82, 85, 197, 84, 82, 85, 67, 75, 128, + 84, 82, 79, 80, 73, 67, 65, 204, 84, 82, 79, 80, 72, 89, 128, 84, 82, 79, + 77, 73, 75, 79, 83, 89, 78, 65, 71, 77, 65, 128, 84, 82, 79, 77, 73, 75, + 79, 80, 83, 73, 70, 73, 83, 84, 79, 78, 128, 84, 82, 79, 77, 73, 75, 79, + 80, 65, 82, 65, 75, 65, 76, 69, 83, 77, 65, 128, 84, 82, 79, 77, 73, 75, + 79, 78, 128, 84, 82, 79, 77, 73, 75, 79, 206, 84, 82, 79, 77, 73, 75, 79, + 76, 89, 71, 73, 83, 77, 65, 128, 84, 82, 79, 76, 76, 69, 89, 66, 85, 83, + 128, 84, 82, 79, 76, 76, 69, 89, 128, 84, 82, 79, 76, 76, 128, 84, 82, + 79, 75, 85, 84, 65, 83, 84, 201, 84, 82, 79, 69, 90, 69, 78, 73, 65, 206, + 84, 82, 73, 85, 77, 80, 72, 128, 84, 82, 73, 84, 79, 211, 84, 82, 73, 84, + 73, 77, 79, 82, 73, 79, 78, 128, 84, 82, 73, 83, 73, 77, 79, 85, 128, 84, + 82, 73, 83, 69, 77, 69, 128, 84, 82, 73, 80, 79, 68, 128, 84, 82, 73, 80, + 76, 73, 128, 84, 82, 73, 80, 76, 69, 128, 84, 82, 73, 80, 76, 197, 84, + 82, 73, 79, 206, 84, 82, 73, 76, 76, 73, 79, 78, 83, 128, 84, 82, 73, 76, + 76, 128, 84, 82, 73, 73, 83, 65, 80, 128, 84, 82, 73, 71, 82, 65, 77, 77, + 79, 211, 84, 82, 73, 71, 82, 65, 205, 84, 82, 73, 71, 79, 82, 71, 79, 78, + 128, 84, 82, 73, 70, 79, 78, 73, 65, 83, 128, 84, 82, 73, 70, 79, 76, 73, + 65, 84, 197, 84, 82, 73, 68, 69, 78, 84, 128, 84, 82, 73, 68, 69, 78, + 212, 84, 82, 73, 67, 79, 76, 79, 78, 128, 84, 82, 73, 65, 78, 71, 85, 76, + 65, 210, 84, 82, 73, 65, 78, 71, 76, 69, 45, 82, 79, 85, 78, 196, 84, 82, + 73, 65, 78, 71, 76, 69, 45, 72, 69, 65, 68, 69, 196, 84, 82, 73, 65, 78, + 71, 76, 69, 128, 84, 82, 73, 65, 78, 71, 76, 197, 84, 82, 73, 65, 128, + 84, 82, 73, 128, 84, 82, 69, 83, 86, 69, 84, 76, 89, 128, 84, 82, 69, 83, + 86, 69, 84, 76, 79, 128, 84, 82, 69, 83, 86, 69, 84, 76, 65, 89, 65, 128, + 84, 82, 69, 83, 73, 76, 76, 79, 128, 84, 82, 69, 78, 68, 128, 84, 82, 69, + 78, 196, 84, 82, 69, 77, 79, 76, 79, 45, 51, 128, 84, 82, 69, 77, 79, 76, + 79, 45, 50, 128, 84, 82, 69, 77, 79, 76, 79, 45, 49, 128, 84, 82, 69, 69, + 128, 84, 82, 69, 197, 84, 82, 69, 68, 69, 67, 73, 76, 69, 128, 84, 82, + 69, 65, 68, 73, 78, 71, 128, 84, 82, 65, 89, 128, 84, 82, 65, 86, 69, 76, + 45, 87, 65, 76, 76, 80, 76, 65, 78, 197, 84, 82, 65, 86, 69, 76, 45, 70, + 76, 79, 79, 82, 80, 76, 65, 78, 197, 84, 82, 65, 80, 69, 90, 73, 85, 77, + 128, 84, 82, 65, 80, 128, 84, 82, 65, 78, 83, 86, 69, 82, 83, 65, 204, + 84, 82, 65, 78, 83, 80, 79, 83, 73, 84, 73, 79, 206, 84, 82, 65, 78, 83, + 80, 76, 85, 84, 79, 128, 84, 82, 65, 78, 83, 77, 73, 212, 84, 82, 65, 78, + 83, 77, 73, 83, 83, 73, 79, 78, 128, 84, 82, 65, 78, 83, 77, 73, 83, 83, + 73, 79, 206, 84, 82, 65, 77, 87, 65, 89, 128, 84, 82, 65, 77, 128, 84, + 82, 65, 205, 84, 82, 65, 73, 78, 128, 84, 82, 65, 73, 206, 84, 82, 65, + 73, 76, 73, 78, 199, 84, 82, 65, 70, 70, 73, 67, 128, 84, 82, 65, 70, 70, + 73, 195, 84, 82, 65, 68, 73, 84, 73, 79, 78, 65, 204, 84, 82, 65, 68, + 197, 84, 82, 65, 67, 84, 79, 82, 128, 84, 82, 65, 67, 75, 66, 65, 76, 76, + 128, 84, 82, 65, 67, 75, 128, 84, 82, 65, 128, 84, 82, 128, 84, 79, 89, + 79, 82, 128, 84, 79, 88, 128, 84, 79, 87, 69, 82, 128, 84, 79, 87, 65, + 82, 68, 211, 84, 79, 86, 128, 84, 79, 85, 82, 78, 79, 73, 211, 84, 79, + 85, 67, 72, 84, 79, 78, 197, 84, 79, 85, 67, 72, 73, 78, 199, 84, 79, 85, + 67, 72, 69, 211, 84, 79, 85, 67, 200, 84, 79, 84, 207, 84, 79, 84, 65, + 204, 84, 79, 84, 128, 84, 79, 83, 128, 84, 79, 82, 84, 79, 73, 83, 197, + 84, 79, 82, 83, 79, 45, 87, 65, 76, 76, 80, 76, 65, 78, 197, 84, 79, 82, + 83, 79, 45, 70, 76, 79, 79, 82, 80, 76, 65, 78, 197, 84, 79, 82, 83, 79, + 128, 84, 79, 82, 78, 65, 68, 79, 128, 84, 79, 82, 67, 85, 76, 85, 83, + 128, 84, 79, 82, 67, 85, 76, 85, 211, 84, 79, 82, 67, 72, 128, 84, 79, + 81, 128, 84, 79, 80, 66, 65, 82, 128, 84, 79, 80, 45, 76, 73, 71, 72, 84, + 69, 196, 84, 79, 80, 128, 84, 79, 208, 84, 79, 79, 84, 72, 66, 82, 85, + 83, 72, 128, 84, 79, 79, 84, 72, 128, 84, 79, 79, 78, 128, 84, 79, 79, + 76, 66, 79, 88, 128, 84, 79, 78, 79, 83, 128, 84, 79, 78, 71, 85, 69, + 128, 84, 79, 78, 71, 85, 197, 84, 79, 78, 71, 128, 84, 79, 78, 69, 45, + 86, 128, 84, 79, 78, 69, 45, 83, 128, 84, 79, 78, 69, 45, 77, 128, 84, + 79, 78, 69, 45, 74, 128, 84, 79, 78, 69, 45, 71, 128, 84, 79, 78, 69, 45, + 68, 128, 84, 79, 78, 69, 45, 66, 128, 84, 79, 78, 69, 45, 56, 128, 84, + 79, 78, 69, 45, 55, 128, 84, 79, 78, 69, 45, 54, 128, 84, 79, 78, 69, 45, + 53, 128, 84, 79, 78, 69, 45, 52, 128, 84, 79, 78, 69, 45, 51, 128, 84, + 79, 78, 69, 45, 50, 128, 84, 79, 78, 69, 45, 49, 128, 84, 79, 78, 69, + 128, 84, 79, 78, 65, 204, 84, 79, 77, 80, 73, 128, 84, 79, 77, 65, 84, + 79, 128, 84, 79, 76, 79, 78, 71, 128, 84, 79, 75, 89, 207, 84, 79, 73, + 76, 69, 84, 128, 84, 79, 71, 69, 84, 72, 69, 82, 128, 84, 79, 68, 207, + 84, 79, 67, 72, 75, 65, 128, 84, 79, 65, 78, 68, 65, 75, 72, 73, 65, 84, + 128, 84, 79, 65, 128, 84, 79, 45, 82, 65, 128, 84, 79, 45, 54, 128, 84, + 79, 45, 53, 128, 84, 79, 45, 52, 128, 84, 79, 45, 51, 128, 84, 79, 45, + 50, 128, 84, 79, 45, 49, 128, 84, 78, 128, 84, 76, 86, 128, 84, 76, 85, + 128, 84, 76, 73, 128, 84, 76, 72, 89, 65, 128, 84, 76, 72, 87, 69, 128, + 84, 76, 72, 85, 128, 84, 76, 72, 79, 79, 128, 84, 76, 72, 79, 128, 84, + 76, 72, 73, 128, 84, 76, 72, 69, 69, 128, 84, 76, 72, 69, 128, 84, 76, + 72, 65, 128, 84, 76, 69, 69, 128, 84, 76, 65, 128, 84, 74, 69, 128, 84, + 73, 88, 128, 84, 73, 87, 82, 128, 84, 73, 87, 78, 128, 84, 73, 87, 65, + 218, 84, 73, 84, 85, 65, 69, 80, 128, 84, 73, 84, 76, 79, 128, 84, 73, + 84, 76, 207, 84, 73, 84, 193, 84, 73, 84, 128, 84, 73, 82, 89, 65, 75, + 128, 84, 73, 82, 84, 193, 84, 73, 82, 79, 78, 73, 65, 206, 84, 73, 82, + 72, 85, 84, 193, 84, 73, 82, 69, 196, 84, 73, 82, 128, 84, 73, 210, 84, + 73, 80, 80, 73, 128, 84, 73, 80, 69, 72, 65, 128, 84, 73, 80, 128, 84, + 73, 208, 84, 73, 78, 89, 128, 84, 73, 78, 217, 84, 73, 78, 78, 69, 128, + 84, 73, 78, 67, 84, 85, 82, 69, 128, 84, 73, 78, 65, 71, 77, 65, 128, 84, + 73, 77, 69, 83, 128, 84, 73, 77, 69, 210, 84, 73, 77, 69, 128, 84, 73, + 76, 84, 73, 78, 71, 128, 84, 73, 76, 84, 73, 78, 199, 84, 73, 76, 84, + 128, 84, 73, 76, 69, 83, 128, 84, 73, 76, 68, 69, 128, 84, 73, 76, 68, + 197, 84, 73, 76, 128, 84, 73, 204, 84, 73, 75, 72, 89, 128, 84, 73, 75, + 72, 65, 89, 65, 128, 84, 73, 75, 72, 65, 89, 193, 84, 73, 75, 69, 85, 84, + 45, 84, 72, 73, 69, 85, 84, 72, 128, 84, 73, 75, 69, 85, 84, 45, 83, 73, + 79, 83, 45, 75, 73, 89, 69, 79, 75, 128, 84, 73, 75, 69, 85, 84, 45, 83, + 73, 79, 83, 128, 84, 73, 75, 69, 85, 84, 45, 82, 73, 69, 85, 76, 128, 84, + 73, 75, 69, 85, 84, 45, 80, 73, 69, 85, 80, 128, 84, 73, 75, 69, 85, 84, + 45, 77, 73, 69, 85, 77, 128, 84, 73, 75, 69, 85, 84, 45, 75, 73, 89, 69, + 79, 75, 128, 84, 73, 75, 69, 85, 84, 45, 67, 73, 69, 85, 67, 128, 84, 73, + 75, 69, 85, 84, 45, 67, 72, 73, 69, 85, 67, 72, 128, 84, 73, 75, 69, 85, + 84, 128, 84, 73, 75, 69, 85, 212, 84, 73, 71, 72, 84, 76, 89, 45, 67, 76, + 79, 83, 69, 196, 84, 73, 71, 72, 212, 84, 73, 71, 69, 82, 128, 84, 73, + 71, 69, 210, 84, 73, 70, 73, 78, 65, 71, 200, 84, 73, 69, 88, 128, 84, + 73, 69, 80, 128, 84, 73, 197, 84, 73, 67, 75, 69, 84, 83, 128, 84, 73, + 67, 75, 69, 84, 128, 84, 73, 67, 75, 128, 84, 73, 67, 203, 84, 73, 65, + 82, 65, 128, 84, 73, 50, 128, 84, 73, 45, 55, 128, 84, 73, 45, 54, 128, + 84, 73, 45, 53, 128, 84, 73, 45, 52, 128, 84, 73, 45, 51, 128, 84, 73, + 45, 50, 128, 84, 73, 45, 49, 128, 84, 72, 90, 128, 84, 72, 89, 79, 79, + 205, 84, 72, 87, 79, 79, 128, 84, 72, 87, 79, 128, 84, 72, 87, 73, 73, + 128, 84, 72, 87, 73, 128, 84, 72, 87, 69, 69, 128, 84, 72, 87, 65, 65, + 128, 84, 72, 87, 65, 128, 84, 72, 85, 82, 211, 84, 72, 85, 82, 73, 83, + 65, 218, 84, 72, 85, 78, 71, 128, 84, 72, 85, 78, 68, 69, 82, 83, 84, 79, + 82, 77, 128, 84, 72, 85, 78, 68, 69, 82, 128, 84, 72, 85, 78, 68, 69, 210, 84, 72, 85, 77, 66, 211, 84, 72, 85, 77, 66, 128, 84, 72, 82, 79, 87, 73, 78, 199, 84, 72, 82, 79, 85, 71, 72, 128, 84, 72, 82, 79, 85, 71, 200, 84, 72, 82, 69, 69, 45, 84, 72, 73, 82, 84, 89, 128, 84, 72, 82, 69, @@ -910,274 +912,274 @@ static const unsigned char lexicon[] = { 65, 212, 83, 87, 65, 83, 200, 83, 87, 65, 80, 80, 73, 78, 71, 128, 83, 87, 65, 78, 128, 83, 87, 65, 65, 128, 83, 87, 128, 83, 86, 65, 83, 84, 201, 83, 86, 65, 82, 73, 84, 65, 128, 83, 86, 65, 82, 73, 84, 193, 83, - 85, 88, 128, 83, 85, 85, 128, 83, 85, 84, 82, 193, 83, 85, 84, 128, 83, - 85, 83, 80, 69, 78, 83, 73, 79, 206, 83, 85, 83, 72, 73, 128, 83, 85, 82, - 89, 65, 128, 83, 85, 82, 88, 128, 83, 85, 82, 82, 79, 85, 78, 68, 128, - 83, 85, 82, 82, 79, 85, 78, 196, 83, 85, 82, 70, 69, 82, 128, 83, 85, 82, - 70, 65, 67, 197, 83, 85, 82, 69, 128, 83, 85, 82, 65, 78, 71, 128, 83, - 85, 82, 57, 128, 83, 85, 82, 128, 83, 85, 210, 83, 85, 80, 82, 65, 76, - 73, 78, 69, 65, 210, 83, 85, 80, 69, 82, 86, 73, 83, 69, 128, 83, 85, 80, - 69, 82, 86, 73, 76, 76, 65, 73, 78, 128, 83, 85, 80, 69, 82, 83, 69, 84, - 128, 83, 85, 80, 69, 82, 83, 69, 212, 83, 85, 80, 69, 82, 83, 67, 82, 73, - 80, 212, 83, 85, 80, 69, 82, 73, 77, 80, 79, 83, 69, 196, 83, 85, 80, 69, - 82, 72, 69, 82, 79, 128, 83, 85, 80, 69, 82, 70, 73, 88, 69, 196, 83, 85, - 80, 69, 210, 83, 85, 80, 128, 83, 85, 79, 88, 128, 83, 85, 79, 80, 128, - 83, 85, 79, 128, 83, 85, 78, 83, 69, 212, 83, 85, 78, 82, 73, 83, 69, - 128, 83, 85, 78, 82, 73, 83, 197, 83, 85, 78, 71, 76, 65, 83, 83, 69, 83, - 128, 83, 85, 78, 71, 128, 83, 85, 78, 70, 76, 79, 87, 69, 82, 128, 83, - 85, 78, 68, 65, 78, 69, 83, 197, 83, 85, 78, 128, 83, 85, 206, 83, 85, - 77, 77, 69, 82, 128, 83, 85, 77, 77, 65, 84, 73, 79, 78, 128, 83, 85, 77, - 77, 65, 84, 73, 79, 206, 83, 85, 77, 65, 83, 72, 128, 83, 85, 77, 128, - 83, 85, 76, 70, 85, 82, 128, 83, 85, 75, 85, 78, 128, 83, 85, 75, 85, - 206, 83, 85, 75, 85, 128, 83, 85, 75, 213, 83, 85, 73, 84, 65, 66, 76, - 69, 128, 83, 85, 73, 212, 83, 85, 72, 85, 82, 128, 83, 85, 69, 128, 83, - 85, 68, 50, 128, 83, 85, 68, 128, 83, 85, 67, 75, 73, 78, 199, 83, 85, - 67, 75, 69, 68, 128, 83, 85, 67, 203, 83, 85, 67, 67, 69, 69, 68, 83, - 128, 83, 85, 67, 67, 69, 69, 68, 211, 83, 85, 67, 67, 69, 69, 68, 128, - 83, 85, 67, 67, 69, 69, 196, 83, 85, 66, 85, 78, 73, 84, 128, 83, 85, 66, - 83, 84, 73, 84, 85, 84, 73, 79, 206, 83, 85, 66, 83, 84, 73, 84, 85, 84, - 69, 128, 83, 85, 66, 83, 84, 73, 84, 85, 84, 197, 83, 85, 66, 83, 69, 84, - 128, 83, 85, 66, 83, 69, 212, 83, 85, 66, 83, 67, 82, 73, 80, 212, 83, - 85, 66, 80, 85, 78, 67, 84, 73, 83, 128, 83, 85, 66, 76, 73, 78, 69, 65, - 210, 83, 85, 66, 76, 73, 77, 65, 84, 73, 79, 78, 128, 83, 85, 66, 76, 73, - 77, 65, 84, 69, 45, 51, 128, 83, 85, 66, 76, 73, 77, 65, 84, 69, 45, 50, - 128, 83, 85, 66, 76, 73, 77, 65, 84, 69, 128, 83, 85, 66, 76, 73, 77, 65, - 84, 197, 83, 85, 66, 74, 79, 73, 78, 69, 82, 128, 83, 85, 66, 74, 79, 73, - 78, 69, 196, 83, 85, 66, 74, 69, 67, 84, 128, 83, 85, 66, 73, 84, 79, - 128, 83, 85, 66, 72, 65, 65, 78, 65, 72, 213, 83, 85, 66, 71, 82, 79, 85, - 80, 128, 83, 85, 66, 71, 82, 79, 85, 208, 83, 85, 66, 128, 83, 85, 65, - 77, 128, 83, 85, 65, 69, 84, 128, 83, 85, 65, 69, 78, 128, 83, 85, 65, - 69, 128, 83, 85, 65, 66, 128, 83, 85, 65, 128, 83, 85, 45, 56, 128, 83, - 85, 45, 55, 128, 83, 85, 45, 54, 128, 83, 85, 45, 53, 128, 83, 85, 45, - 52, 128, 83, 85, 45, 51, 128, 83, 85, 45, 50, 128, 83, 85, 45, 49, 128, - 83, 213, 83, 84, 88, 128, 83, 84, 87, 65, 128, 83, 84, 85, 80, 65, 128, - 83, 84, 85, 70, 70, 69, 196, 83, 84, 85, 68, 89, 128, 83, 84, 85, 68, 73, - 207, 83, 84, 85, 67, 75, 45, 79, 85, 212, 83, 84, 83, 128, 83, 84, 82, - 79, 78, 199, 83, 84, 82, 79, 75, 69, 83, 128, 83, 84, 82, 79, 75, 69, - 211, 83, 84, 82, 79, 75, 69, 45, 57, 128, 83, 84, 82, 79, 75, 69, 45, 56, - 128, 83, 84, 82, 79, 75, 69, 45, 55, 128, 83, 84, 82, 79, 75, 69, 45, 54, - 128, 83, 84, 82, 79, 75, 69, 45, 53, 128, 83, 84, 82, 79, 75, 69, 45, 52, - 128, 83, 84, 82, 79, 75, 69, 45, 51, 128, 83, 84, 82, 79, 75, 69, 45, 50, - 128, 83, 84, 82, 79, 75, 69, 45, 49, 49, 128, 83, 84, 82, 79, 75, 69, 45, - 49, 48, 128, 83, 84, 82, 79, 75, 69, 45, 49, 128, 83, 84, 82, 79, 75, - 197, 83, 84, 82, 73, 80, 69, 128, 83, 84, 82, 73, 78, 71, 128, 83, 84, - 82, 73, 78, 199, 83, 84, 82, 73, 75, 69, 84, 72, 82, 79, 85, 71, 72, 128, - 83, 84, 82, 73, 75, 197, 83, 84, 82, 73, 68, 69, 128, 83, 84, 82, 73, 67, - 84, 76, 217, 83, 84, 82, 69, 84, 67, 72, 69, 196, 83, 84, 82, 69, 84, 67, - 72, 128, 83, 84, 82, 69, 83, 211, 83, 84, 82, 69, 78, 71, 84, 72, 128, - 83, 84, 82, 69, 76, 193, 83, 84, 82, 69, 65, 77, 69, 82, 128, 83, 84, 82, - 65, 87, 66, 69, 82, 82, 89, 128, 83, 84, 82, 65, 87, 128, 83, 84, 82, 65, - 84, 85, 77, 45, 50, 128, 83, 84, 82, 65, 84, 85, 77, 128, 83, 84, 82, 65, - 84, 85, 205, 83, 84, 82, 65, 84, 73, 65, 206, 83, 84, 82, 65, 78, 78, 79, - 128, 83, 84, 82, 65, 78, 78, 207, 83, 84, 82, 65, 73, 78, 69, 82, 128, - 83, 84, 82, 65, 73, 71, 72, 84, 78, 69, 83, 83, 128, 83, 84, 82, 65, 73, - 71, 72, 84, 128, 83, 84, 82, 65, 73, 71, 72, 212, 83, 84, 82, 65, 73, 70, - 128, 83, 84, 82, 65, 71, 71, 73, 83, 77, 65, 84, 65, 128, 83, 84, 79, 86, - 69, 128, 83, 84, 79, 82, 69, 128, 83, 84, 79, 80, 87, 65, 84, 67, 72, - 128, 83, 84, 79, 80, 80, 73, 78, 71, 128, 83, 84, 79, 80, 80, 65, 71, 69, - 128, 83, 84, 79, 80, 73, 84, 83, 65, 128, 83, 84, 79, 80, 73, 84, 83, - 193, 83, 84, 79, 80, 128, 83, 84, 79, 208, 83, 84, 79, 78, 69, 128, 83, - 84, 79, 67, 75, 128, 83, 84, 79, 67, 203, 83, 84, 73, 82, 82, 85, 208, - 83, 84, 73, 77, 77, 69, 128, 83, 84, 73, 76, 204, 83, 84, 73, 76, 197, - 83, 84, 73, 71, 77, 65, 128, 83, 84, 73, 67, 75, 73, 78, 199, 83, 84, 73, - 67, 203, 83, 84, 69, 84, 72, 79, 83, 67, 79, 80, 69, 128, 83, 84, 69, 82, - 69, 79, 128, 83, 84, 69, 80, 128, 83, 84, 69, 78, 79, 71, 82, 65, 80, 72, - 73, 195, 83, 84, 69, 77, 128, 83, 84, 69, 65, 77, 217, 83, 84, 69, 65, - 77, 73, 78, 199, 83, 84, 69, 65, 77, 128, 83, 84, 69, 65, 205, 83, 84, - 65, 86, 82, 79, 85, 128, 83, 84, 65, 86, 82, 79, 83, 128, 83, 84, 65, 86, - 82, 79, 211, 83, 84, 65, 85, 82, 79, 83, 128, 83, 84, 65, 84, 89, 65, - 128, 83, 84, 65, 84, 89, 193, 83, 84, 65, 84, 85, 197, 83, 84, 65, 84, - 73, 79, 78, 128, 83, 84, 65, 84, 69, 82, 83, 128, 83, 84, 65, 84, 69, - 128, 83, 84, 65, 82, 84, 73, 78, 199, 83, 84, 65, 82, 84, 128, 83, 84, - 65, 82, 212, 83, 84, 65, 82, 83, 128, 83, 84, 65, 82, 82, 69, 196, 83, - 84, 65, 82, 75, 128, 83, 84, 65, 82, 128, 83, 84, 65, 210, 83, 84, 65, - 78, 68, 83, 84, 73, 76, 76, 128, 83, 84, 65, 78, 68, 73, 78, 199, 83, 84, - 65, 78, 68, 65, 82, 196, 83, 84, 65, 78, 68, 128, 83, 84, 65, 78, 128, - 83, 84, 65, 77, 80, 69, 196, 83, 84, 65, 76, 76, 73, 79, 78, 128, 83, 84, - 65, 70, 70, 128, 83, 84, 65, 70, 198, 83, 84, 65, 68, 73, 85, 77, 128, - 83, 84, 65, 67, 75, 69, 196, 83, 84, 65, 67, 67, 65, 84, 79, 128, 83, 84, - 65, 67, 67, 65, 84, 73, 83, 83, 73, 77, 79, 128, 83, 84, 50, 128, 83, 83, - 89, 88, 128, 83, 83, 89, 84, 128, 83, 83, 89, 82, 88, 128, 83, 83, 89, - 82, 128, 83, 83, 89, 80, 128, 83, 83, 89, 128, 83, 83, 85, 88, 128, 83, - 83, 85, 85, 128, 83, 83, 85, 84, 128, 83, 83, 85, 80, 128, 83, 83, 79, - 88, 128, 83, 83, 79, 84, 128, 83, 83, 79, 80, 128, 83, 83, 79, 79, 128, - 83, 83, 79, 128, 83, 83, 73, 88, 128, 83, 83, 73, 84, 128, 83, 83, 73, - 80, 128, 83, 83, 73, 73, 128, 83, 83, 73, 69, 88, 128, 83, 83, 73, 69, - 80, 128, 83, 83, 73, 69, 128, 83, 83, 72, 73, 78, 128, 83, 83, 72, 69, - 128, 83, 83, 69, 88, 128, 83, 83, 69, 80, 128, 83, 83, 69, 69, 128, 83, - 83, 65, 88, 128, 83, 83, 65, 85, 128, 83, 83, 65, 84, 128, 83, 83, 65, - 80, 128, 83, 83, 65, 78, 71, 89, 69, 83, 73, 69, 85, 78, 71, 128, 83, 83, - 65, 78, 71, 89, 69, 79, 82, 73, 78, 72, 73, 69, 85, 72, 128, 83, 83, 65, - 78, 71, 84, 73, 75, 69, 85, 84, 45, 80, 73, 69, 85, 80, 128, 83, 83, 65, - 78, 71, 84, 73, 75, 69, 85, 84, 128, 83, 83, 65, 78, 71, 84, 72, 73, 69, - 85, 84, 72, 128, 83, 83, 65, 78, 71, 83, 73, 79, 83, 45, 84, 73, 75, 69, - 85, 84, 128, 83, 83, 65, 78, 71, 83, 73, 79, 83, 45, 80, 73, 69, 85, 80, - 128, 83, 83, 65, 78, 71, 83, 73, 79, 83, 45, 75, 73, 89, 69, 79, 75, 128, - 83, 83, 65, 78, 71, 83, 73, 79, 83, 128, 83, 83, 65, 78, 71, 82, 73, 69, - 85, 76, 45, 75, 72, 73, 69, 85, 75, 72, 128, 83, 83, 65, 78, 71, 82, 73, - 69, 85, 76, 128, 83, 83, 65, 78, 71, 80, 73, 69, 85, 80, 128, 83, 83, 65, - 78, 71, 78, 73, 69, 85, 78, 128, 83, 83, 65, 78, 71, 77, 73, 69, 85, 77, - 128, 83, 83, 65, 78, 71, 73, 69, 85, 78, 71, 128, 83, 83, 65, 78, 71, 72, - 73, 69, 85, 72, 128, 83, 83, 65, 78, 71, 67, 73, 69, 85, 67, 45, 72, 73, - 69, 85, 72, 128, 83, 83, 65, 78, 71, 67, 73, 69, 85, 67, 128, 83, 83, 65, - 78, 71, 65, 82, 65, 69, 65, 128, 83, 83, 65, 73, 128, 83, 83, 65, 65, - 128, 83, 83, 51, 128, 83, 83, 50, 128, 83, 82, 69, 68, 78, 197, 83, 82, - 128, 83, 81, 85, 73, 83, 200, 83, 81, 85, 73, 82, 82, 69, 204, 83, 81, - 85, 73, 71, 71, 76, 197, 83, 81, 85, 73, 68, 128, 83, 81, 85, 69, 69, 90, - 69, 68, 128, 83, 81, 85, 69, 69, 90, 197, 83, 81, 85, 65, 212, 83, 81, - 85, 65, 82, 69, 83, 128, 83, 81, 85, 65, 82, 69, 68, 128, 83, 81, 85, 65, - 82, 69, 128, 83, 80, 89, 128, 83, 80, 87, 65, 128, 83, 80, 85, 78, 71, - 211, 83, 80, 82, 79, 85, 84, 128, 83, 80, 82, 73, 78, 71, 83, 128, 83, - 80, 82, 73, 78, 71, 128, 83, 80, 82, 69, 67, 72, 71, 69, 83, 65, 78, 199, - 83, 80, 82, 69, 65, 68, 128, 83, 80, 82, 69, 65, 196, 83, 80, 79, 85, 84, - 73, 78, 199, 83, 80, 79, 84, 128, 83, 80, 79, 82, 84, 211, 83, 80, 79, - 79, 78, 128, 83, 80, 79, 79, 204, 83, 80, 79, 78, 71, 69, 128, 83, 80, - 79, 128, 83, 80, 76, 73, 84, 84, 73, 78, 199, 83, 80, 76, 73, 84, 128, - 83, 80, 76, 73, 212, 83, 80, 76, 65, 89, 69, 68, 128, 83, 80, 76, 65, 83, - 72, 73, 78, 199, 83, 80, 73, 82, 73, 84, 85, 211, 83, 80, 73, 82, 73, 84, - 128, 83, 80, 73, 82, 73, 212, 83, 80, 73, 82, 65, 78, 84, 128, 83, 80, - 73, 82, 65, 76, 128, 83, 80, 73, 82, 65, 204, 83, 80, 73, 78, 69, 128, - 83, 80, 73, 68, 69, 82, 217, 83, 80, 73, 68, 69, 82, 128, 83, 80, 73, 68, - 69, 210, 83, 80, 73, 67, 69, 128, 83, 80, 73, 128, 83, 80, 72, 69, 82, - 73, 67, 65, 204, 83, 80, 69, 83, 77, 73, 76, 207, 83, 80, 69, 78, 212, - 83, 80, 69, 69, 68, 66, 79, 65, 84, 128, 83, 80, 69, 69, 67, 72, 128, 83, - 80, 69, 69, 67, 200, 83, 80, 69, 67, 73, 65, 76, 128, 83, 80, 69, 65, 82, - 128, 83, 80, 69, 65, 75, 73, 78, 199, 83, 80, 69, 65, 75, 69, 82, 128, - 83, 80, 69, 65, 75, 69, 210, 83, 80, 69, 65, 75, 45, 78, 79, 45, 69, 86, - 73, 204, 83, 80, 69, 128, 83, 80, 65, 84, 72, 73, 128, 83, 80, 65, 82, - 75, 76, 73, 78, 199, 83, 80, 65, 82, 75, 76, 69, 83, 128, 83, 80, 65, 82, - 75, 76, 69, 82, 128, 83, 80, 65, 82, 75, 76, 69, 128, 83, 80, 65, 71, 72, - 69, 84, 84, 73, 128, 83, 80, 65, 68, 69, 83, 128, 83, 80, 65, 68, 197, - 83, 80, 65, 67, 73, 78, 199, 83, 80, 65, 67, 197, 83, 80, 65, 128, 83, - 79, 89, 79, 77, 66, 207, 83, 79, 89, 128, 83, 79, 87, 73, 76, 207, 83, - 79, 87, 128, 83, 79, 85, 84, 72, 69, 82, 206, 83, 79, 85, 84, 72, 45, 83, - 76, 65, 86, 69, 217, 83, 79, 85, 84, 200, 83, 79, 85, 82, 67, 69, 128, - 83, 79, 85, 78, 68, 128, 83, 79, 85, 78, 196, 83, 79, 85, 78, 65, 80, - 128, 83, 79, 85, 128, 83, 79, 83, 128, 83, 79, 82, 79, 67, 72, 89, 193, - 83, 79, 82, 73, 128, 83, 79, 82, 193, 83, 79, 81, 128, 83, 79, 79, 206, - 83, 79, 78, 74, 65, 77, 128, 83, 79, 78, 71, 128, 83, 79, 78, 128, 83, - 79, 77, 80, 69, 78, 199, 83, 79, 77, 128, 83, 79, 205, 83, 79, 76, 73, - 68, 85, 83, 128, 83, 79, 76, 73, 68, 85, 211, 83, 79, 76, 73, 196, 83, - 79, 76, 68, 73, 69, 82, 128, 83, 79, 72, 128, 83, 79, 71, 68, 73, 65, - 206, 83, 79, 70, 84, 87, 65, 82, 69, 45, 70, 85, 78, 67, 84, 73, 79, 206, - 83, 79, 70, 84, 78, 69, 83, 83, 128, 83, 79, 70, 84, 66, 65, 76, 76, 128, - 83, 79, 70, 212, 83, 79, 198, 83, 79, 67, 75, 83, 128, 83, 79, 67, 73, - 69, 84, 89, 128, 83, 79, 67, 67, 69, 210, 83, 79, 65, 80, 128, 83, 79, - 65, 128, 83, 79, 45, 55, 128, 83, 79, 45, 54, 128, 83, 79, 45, 53, 128, - 83, 79, 45, 52, 128, 83, 79, 45, 51, 128, 83, 79, 45, 50, 128, 83, 79, - 45, 49, 128, 83, 207, 83, 78, 79, 87, 77, 65, 78, 128, 83, 78, 79, 87, - 77, 65, 206, 83, 78, 79, 87, 70, 76, 65, 75, 69, 128, 83, 78, 79, 87, 66, - 79, 65, 82, 68, 69, 82, 128, 83, 78, 79, 87, 128, 83, 78, 79, 215, 83, - 78, 79, 85, 84, 128, 83, 78, 79, 85, 212, 83, 78, 69, 69, 90, 73, 78, - 199, 83, 78, 65, 208, 83, 78, 65, 75, 69, 128, 83, 78, 65, 75, 197, 83, - 78, 65, 73, 76, 128, 83, 78, 193, 83, 77, 79, 75, 73, 78, 199, 83, 77, - 73, 82, 75, 73, 78, 199, 83, 77, 73, 76, 73, 78, 199, 83, 77, 73, 76, 69, - 128, 83, 77, 73, 76, 197, 83, 77, 69, 65, 82, 128, 83, 77, 65, 83, 200, - 83, 77, 65, 76, 76, 69, 210, 83, 77, 65, 76, 76, 128, 83, 76, 85, 82, - 128, 83, 76, 79, 90, 72, 73, 84, 73, 69, 128, 83, 76, 79, 90, 72, 73, 84, - 73, 197, 83, 76, 79, 87, 76, 89, 128, 83, 76, 79, 87, 128, 83, 76, 79, - 215, 83, 76, 79, 86, 79, 128, 83, 76, 79, 84, 72, 128, 83, 76, 79, 212, - 83, 76, 79, 80, 73, 78, 199, 83, 76, 79, 80, 69, 128, 83, 76, 79, 65, - 206, 83, 76, 73, 78, 71, 128, 83, 76, 73, 71, 72, 84, 76, 217, 83, 76, - 73, 68, 73, 78, 71, 128, 83, 76, 73, 68, 69, 82, 128, 83, 76, 73, 68, 69, - 128, 83, 76, 73, 67, 69, 128, 83, 76, 73, 67, 197, 83, 76, 69, 85, 84, - 200, 83, 76, 69, 69, 80, 217, 83, 76, 69, 69, 80, 73, 78, 199, 83, 76, - 69, 69, 208, 83, 76, 69, 68, 128, 83, 76, 65, 86, 79, 78, 73, 195, 83, - 76, 65, 86, 69, 128, 83, 76, 65, 83, 72, 128, 83, 76, 65, 83, 200, 83, - 76, 65, 78, 84, 69, 196, 83, 75, 87, 65, 128, 83, 75, 87, 128, 83, 75, - 85, 78, 75, 128, 83, 75, 85, 76, 76, 128, 83, 75, 85, 76, 204, 83, 75, - 79, 66, 65, 128, 83, 75, 76, 73, 82, 79, 206, 83, 75, 73, 78, 128, 83, - 75, 73, 69, 82, 128, 83, 75, 201, 83, 75, 69, 87, 69, 196, 83, 75, 65, - 84, 69, 66, 79, 65, 82, 68, 128, 83, 75, 65, 84, 69, 128, 83, 75, 65, 77, - 69, 89, 84, 83, 193, 83, 75, 128, 83, 74, 69, 128, 83, 73, 90, 197, 83, - 73, 88, 84, 89, 45, 70, 79, 85, 82, 84, 72, 83, 128, 83, 73, 88, 84, 89, - 45, 70, 79, 85, 82, 84, 72, 128, 83, 73, 88, 84, 89, 45, 70, 79, 85, 82, - 84, 200, 83, 73, 88, 84, 89, 128, 83, 73, 88, 84, 217, 83, 73, 88, 84, - 72, 83, 128, 83, 73, 88, 84, 72, 211, 83, 73, 88, 84, 72, 128, 83, 73, - 88, 84, 69, 69, 78, 84, 72, 83, 128, 83, 73, 88, 84, 69, 69, 78, 84, 72, - 45, 50, 128, 83, 73, 88, 84, 69, 69, 78, 84, 72, 45, 49, 128, 83, 73, 88, - 84, 69, 69, 78, 84, 72, 128, 83, 73, 88, 84, 69, 69, 78, 84, 200, 83, 73, - 88, 84, 69, 69, 78, 128, 83, 73, 88, 84, 69, 69, 206, 83, 73, 88, 45, 84, - 72, 73, 82, 84, 89, 128, 83, 73, 88, 45, 83, 84, 82, 73, 78, 199, 83, 73, - 88, 45, 80, 69, 82, 45, 69, 205, 83, 73, 88, 45, 76, 73, 78, 197, 83, 73, - 216, 83, 73, 84, 69, 128, 83, 73, 83, 65, 128, 83, 73, 82, 82, 65, 72, - 128, 83, 73, 82, 73, 78, 71, 85, 128, 83, 73, 79, 83, 45, 84, 72, 73, 69, - 85, 84, 72, 128, 83, 73, 79, 83, 45, 83, 83, 65, 78, 71, 83, 73, 79, 83, - 128, 83, 73, 79, 83, 45, 82, 73, 69, 85, 76, 128, 83, 73, 79, 83, 45, 80, - 73, 69, 85, 80, 45, 75, 73, 89, 69, 79, 75, 128, 83, 73, 79, 83, 45, 80, - 72, 73, 69, 85, 80, 72, 128, 83, 73, 79, 83, 45, 80, 65, 78, 83, 73, 79, - 83, 128, 83, 73, 79, 83, 45, 78, 73, 69, 85, 78, 128, 83, 73, 79, 83, 45, - 77, 73, 69, 85, 77, 128, 83, 73, 79, 83, 45, 75, 72, 73, 69, 85, 75, 72, - 128, 83, 73, 79, 83, 45, 75, 65, 80, 89, 69, 79, 85, 78, 80, 73, 69, 85, - 80, 128, 83, 73, 79, 83, 45, 73, 69, 85, 78, 71, 128, 83, 73, 79, 83, 45, - 72, 73, 69, 85, 72, 128, 83, 73, 79, 83, 45, 67, 73, 69, 85, 67, 128, 83, - 73, 79, 83, 45, 67, 72, 73, 69, 85, 67, 72, 128, 83, 73, 79, 211, 83, 73, - 78, 85, 83, 79, 73, 196, 83, 73, 78, 79, 76, 79, 71, 73, 67, 65, 204, 83, - 73, 78, 78, 89, 73, 73, 89, 72, 69, 128, 83, 73, 78, 75, 73, 78, 71, 128, - 83, 73, 78, 71, 76, 69, 45, 83, 72, 73, 70, 84, 45, 51, 128, 83, 73, 78, - 71, 76, 69, 45, 83, 72, 73, 70, 84, 45, 50, 128, 83, 73, 78, 71, 76, 69, - 45, 76, 73, 78, 197, 83, 73, 78, 71, 76, 69, 128, 83, 73, 78, 71, 76, - 197, 83, 73, 78, 71, 65, 65, 84, 128, 83, 73, 78, 197, 83, 73, 78, 68, - 72, 201, 83, 73, 78, 128, 83, 73, 206, 83, 73, 77, 85, 76, 84, 65, 78, - 69, 79, 85, 83, 128, 83, 73, 77, 85, 76, 84, 65, 78, 69, 79, 85, 211, 83, - 73, 77, 80, 76, 73, 70, 73, 69, 196, 83, 73, 77, 73, 76, 65, 82, 128, 83, - 73, 77, 73, 76, 65, 210, 83, 73, 77, 65, 78, 83, 73, 211, 83, 73, 77, 65, - 76, 85, 78, 71, 85, 206, 83, 73, 77, 65, 128, 83, 73, 76, 86, 69, 82, - 128, 83, 73, 76, 75, 128, 83, 73, 76, 73, 81, 85, 193, 83, 73, 76, 72, - 79, 85, 69, 84, 84, 69, 128, 83, 73, 76, 72, 79, 85, 69, 84, 84, 197, 83, - 73, 76, 65, 51, 128, 83, 73, 75, 73, 128, 83, 73, 75, 50, 128, 83, 73, - 75, 178, 83, 73, 71, 78, 83, 128, 83, 73, 71, 77, 79, 73, 196, 83, 73, - 71, 77, 65, 128, 83, 73, 71, 77, 193, 83, 73, 71, 69, 204, 83, 73, 71, - 52, 128, 83, 73, 71, 180, 83, 73, 71, 128, 83, 73, 69, 69, 128, 83, 73, - 68, 69, 87, 65, 89, 211, 83, 73, 68, 69, 128, 83, 73, 68, 197, 83, 73, - 68, 68, 72, 73, 128, 83, 73, 68, 68, 72, 65, 77, 128, 83, 73, 68, 68, 72, - 65, 205, 83, 73, 67, 75, 78, 69, 83, 83, 128, 83, 73, 67, 75, 76, 69, - 128, 83, 73, 66, 197, 83, 73, 65, 128, 83, 73, 45, 54, 128, 83, 73, 45, - 53, 128, 83, 73, 45, 52, 128, 83, 73, 45, 51, 128, 83, 73, 45, 50, 128, - 83, 73, 45, 49, 128, 83, 201, 83, 72, 89, 88, 128, 83, 72, 89, 84, 128, - 83, 72, 89, 82, 88, 128, 83, 72, 89, 82, 128, 83, 72, 89, 80, 128, 83, - 72, 89, 69, 128, 83, 72, 89, 65, 128, 83, 72, 89, 128, 83, 72, 87, 79, - 89, 128, 83, 72, 87, 79, 79, 128, 83, 72, 87, 79, 128, 83, 72, 87, 73, - 73, 128, 83, 72, 87, 73, 128, 83, 72, 87, 69, 128, 83, 72, 87, 197, 83, - 72, 87, 65, 65, 128, 83, 72, 87, 65, 128, 83, 72, 86, 128, 83, 72, 85, - 88, 128, 83, 72, 85, 85, 128, 83, 72, 85, 84, 84, 76, 69, 67, 79, 67, 75, - 128, 83, 72, 85, 84, 128, 83, 72, 85, 82, 88, 128, 83, 72, 85, 82, 128, - 83, 72, 85, 80, 128, 83, 72, 85, 79, 88, 128, 83, 72, 85, 79, 80, 128, - 83, 72, 85, 79, 128, 83, 72, 85, 77, 128, 83, 72, 85, 76, 128, 83, 72, - 85, 70, 70, 76, 197, 83, 72, 85, 69, 81, 128, 83, 72, 85, 69, 78, 83, 72, - 85, 69, 84, 128, 83, 72, 85, 66, 85, 82, 128, 83, 72, 85, 65, 78, 71, 88, - 73, 128, 83, 72, 85, 50, 128, 83, 72, 85, 178, 83, 72, 85, 128, 83, 72, - 84, 65, 80, 73, 67, 128, 83, 72, 84, 65, 128, 83, 72, 82, 85, 71, 128, - 83, 72, 82, 79, 79, 128, 83, 72, 82, 79, 128, 83, 72, 82, 73, 78, 69, - 128, 83, 72, 82, 73, 77, 80, 128, 83, 72, 82, 73, 73, 128, 83, 72, 82, - 73, 128, 83, 72, 82, 65, 65, 128, 83, 72, 82, 65, 128, 83, 72, 79, 89, - 128, 83, 72, 79, 88, 128, 83, 72, 79, 87, 69, 82, 128, 83, 72, 79, 85, - 76, 68, 69, 82, 69, 196, 83, 72, 79, 85, 76, 68, 69, 210, 83, 72, 79, 85, - 128, 83, 72, 79, 84, 128, 83, 72, 79, 82, 84, 83, 128, 83, 72, 79, 82, - 84, 211, 83, 72, 79, 82, 84, 72, 65, 78, 196, 83, 72, 79, 82, 84, 69, 78, - 69, 82, 128, 83, 72, 79, 82, 84, 67, 65, 75, 69, 128, 83, 72, 79, 82, 84, - 45, 84, 87, 73, 71, 45, 89, 82, 128, 83, 72, 79, 82, 84, 45, 84, 87, 73, - 71, 45, 84, 89, 210, 83, 72, 79, 82, 84, 45, 84, 87, 73, 71, 45, 83, 79, - 204, 83, 72, 79, 82, 84, 45, 84, 87, 73, 71, 45, 79, 83, 211, 83, 72, 79, - 82, 84, 45, 84, 87, 73, 71, 45, 78, 65, 85, 196, 83, 72, 79, 82, 84, 45, - 84, 87, 73, 71, 45, 77, 65, 68, 210, 83, 72, 79, 82, 84, 45, 84, 87, 73, - 71, 45, 72, 65, 71, 65, 76, 204, 83, 72, 79, 82, 84, 45, 84, 87, 73, 71, - 45, 66, 74, 65, 82, 75, 65, 206, 83, 72, 79, 82, 84, 45, 84, 87, 73, 71, - 45, 65, 210, 83, 72, 79, 82, 84, 128, 83, 72, 79, 82, 212, 83, 72, 79, - 81, 128, 83, 72, 79, 209, 83, 72, 79, 80, 80, 73, 78, 199, 83, 72, 79, - 80, 128, 83, 72, 79, 79, 84, 73, 78, 199, 83, 72, 79, 79, 84, 128, 83, - 72, 79, 79, 73, 128, 83, 72, 79, 79, 128, 83, 72, 79, 71, 201, 83, 72, - 79, 199, 83, 72, 79, 69, 83, 128, 83, 72, 79, 69, 128, 83, 72, 79, 197, - 83, 72, 79, 67, 75, 69, 196, 83, 72, 79, 65, 128, 83, 72, 79, 128, 83, - 72, 73, 89, 89, 65, 65, 76, 65, 65, 128, 83, 72, 73, 84, 65, 128, 83, 72, - 73, 84, 193, 83, 72, 73, 82, 212, 83, 72, 73, 82, 65, 69, 128, 83, 72, - 73, 82, 128, 83, 72, 73, 210, 83, 72, 73, 81, 128, 83, 72, 73, 78, 84, - 207, 83, 72, 73, 78, 73, 71, 128, 83, 72, 73, 78, 68, 193, 83, 72, 73, - 206, 83, 72, 73, 77, 65, 128, 83, 72, 73, 77, 193, 83, 72, 73, 77, 128, - 83, 72, 73, 205, 83, 72, 73, 73, 78, 128, 83, 72, 73, 73, 128, 83, 72, - 73, 70, 212, 83, 72, 73, 69, 76, 68, 128, 83, 72, 73, 68, 128, 83, 72, - 73, 196, 83, 72, 72, 65, 128, 83, 72, 72, 193, 83, 72, 69, 88, 128, 83, - 72, 69, 86, 65, 128, 83, 72, 69, 85, 88, 128, 83, 72, 69, 85, 79, 81, + 85, 88, 128, 83, 85, 85, 128, 83, 85, 84, 85, 72, 128, 83, 85, 84, 82, + 193, 83, 85, 84, 128, 83, 85, 83, 80, 69, 78, 83, 73, 79, 206, 83, 85, + 83, 72, 73, 128, 83, 85, 82, 89, 65, 128, 83, 85, 82, 88, 128, 83, 85, + 82, 82, 79, 85, 78, 68, 128, 83, 85, 82, 82, 79, 85, 78, 196, 83, 85, 82, + 70, 69, 82, 128, 83, 85, 82, 70, 65, 67, 197, 83, 85, 82, 69, 128, 83, + 85, 82, 65, 78, 71, 128, 83, 85, 82, 57, 128, 83, 85, 82, 128, 83, 85, + 210, 83, 85, 80, 82, 65, 76, 73, 78, 69, 65, 210, 83, 85, 80, 69, 82, 86, + 73, 83, 69, 128, 83, 85, 80, 69, 82, 86, 73, 76, 76, 65, 73, 78, 128, 83, + 85, 80, 69, 82, 83, 69, 84, 128, 83, 85, 80, 69, 82, 83, 69, 212, 83, 85, + 80, 69, 82, 83, 67, 82, 73, 80, 212, 83, 85, 80, 69, 82, 73, 77, 80, 79, + 83, 69, 196, 83, 85, 80, 69, 82, 72, 69, 82, 79, 128, 83, 85, 80, 69, 82, + 70, 73, 88, 69, 196, 83, 85, 80, 69, 210, 83, 85, 80, 128, 83, 85, 79, + 88, 128, 83, 85, 79, 80, 128, 83, 85, 79, 128, 83, 85, 78, 83, 69, 212, + 83, 85, 78, 82, 73, 83, 69, 128, 83, 85, 78, 82, 73, 83, 197, 83, 85, 78, + 71, 76, 65, 83, 83, 69, 83, 128, 83, 85, 78, 71, 128, 83, 85, 78, 70, 76, + 79, 87, 69, 82, 128, 83, 85, 78, 68, 65, 78, 69, 83, 197, 83, 85, 78, + 128, 83, 85, 206, 83, 85, 77, 77, 69, 82, 128, 83, 85, 77, 77, 65, 84, + 73, 79, 78, 128, 83, 85, 77, 77, 65, 84, 73, 79, 206, 83, 85, 77, 65, 83, + 72, 128, 83, 85, 77, 128, 83, 85, 76, 70, 85, 82, 128, 83, 85, 75, 85, + 78, 128, 83, 85, 75, 85, 206, 83, 85, 75, 85, 128, 83, 85, 75, 213, 83, + 85, 73, 84, 65, 66, 76, 69, 128, 83, 85, 73, 212, 83, 85, 72, 85, 82, + 128, 83, 85, 69, 128, 83, 85, 68, 50, 128, 83, 85, 68, 128, 83, 85, 67, + 75, 73, 78, 199, 83, 85, 67, 75, 69, 68, 128, 83, 85, 67, 203, 83, 85, + 67, 67, 69, 69, 68, 83, 128, 83, 85, 67, 67, 69, 69, 68, 211, 83, 85, 67, + 67, 69, 69, 68, 128, 83, 85, 67, 67, 69, 69, 196, 83, 85, 66, 85, 78, 73, + 84, 128, 83, 85, 66, 83, 84, 73, 84, 85, 84, 73, 79, 206, 83, 85, 66, 83, + 84, 73, 84, 85, 84, 69, 128, 83, 85, 66, 83, 84, 73, 84, 85, 84, 197, 83, + 85, 66, 83, 69, 84, 128, 83, 85, 66, 83, 69, 212, 83, 85, 66, 83, 67, 82, + 73, 80, 212, 83, 85, 66, 80, 85, 78, 67, 84, 73, 83, 128, 83, 85, 66, 76, + 73, 78, 69, 65, 210, 83, 85, 66, 76, 73, 77, 65, 84, 73, 79, 78, 128, 83, + 85, 66, 76, 73, 77, 65, 84, 69, 45, 51, 128, 83, 85, 66, 76, 73, 77, 65, + 84, 69, 45, 50, 128, 83, 85, 66, 76, 73, 77, 65, 84, 69, 128, 83, 85, 66, + 76, 73, 77, 65, 84, 197, 83, 85, 66, 74, 79, 73, 78, 69, 82, 128, 83, 85, + 66, 74, 79, 73, 78, 69, 196, 83, 85, 66, 74, 69, 67, 84, 128, 83, 85, 66, + 73, 84, 79, 128, 83, 85, 66, 72, 65, 65, 78, 65, 72, 213, 83, 85, 66, 71, + 82, 79, 85, 80, 128, 83, 85, 66, 71, 82, 79, 85, 208, 83, 85, 66, 128, + 83, 85, 65, 77, 128, 83, 85, 65, 69, 84, 128, 83, 85, 65, 69, 78, 128, + 83, 85, 65, 69, 128, 83, 85, 65, 66, 128, 83, 85, 65, 128, 83, 85, 45, + 56, 128, 83, 85, 45, 55, 128, 83, 85, 45, 54, 128, 83, 85, 45, 53, 128, + 83, 85, 45, 52, 128, 83, 85, 45, 51, 128, 83, 85, 45, 50, 128, 83, 85, + 45, 49, 128, 83, 213, 83, 84, 88, 128, 83, 84, 87, 65, 128, 83, 84, 85, + 80, 65, 128, 83, 84, 85, 70, 70, 69, 196, 83, 84, 85, 68, 89, 128, 83, + 84, 85, 68, 73, 207, 83, 84, 85, 67, 75, 45, 79, 85, 212, 83, 84, 83, + 128, 83, 84, 82, 79, 78, 199, 83, 84, 82, 79, 75, 69, 83, 128, 83, 84, + 82, 79, 75, 69, 211, 83, 84, 82, 79, 75, 69, 45, 57, 128, 83, 84, 82, 79, + 75, 69, 45, 56, 128, 83, 84, 82, 79, 75, 69, 45, 55, 128, 83, 84, 82, 79, + 75, 69, 45, 54, 128, 83, 84, 82, 79, 75, 69, 45, 53, 128, 83, 84, 82, 79, + 75, 69, 45, 52, 128, 83, 84, 82, 79, 75, 69, 45, 51, 128, 83, 84, 82, 79, + 75, 69, 45, 50, 128, 83, 84, 82, 79, 75, 69, 45, 49, 49, 128, 83, 84, 82, + 79, 75, 69, 45, 49, 48, 128, 83, 84, 82, 79, 75, 69, 45, 49, 128, 83, 84, + 82, 79, 75, 197, 83, 84, 82, 73, 80, 69, 128, 83, 84, 82, 73, 78, 71, + 128, 83, 84, 82, 73, 78, 199, 83, 84, 82, 73, 75, 69, 84, 72, 82, 79, 85, + 71, 72, 128, 83, 84, 82, 73, 75, 197, 83, 84, 82, 73, 68, 69, 128, 83, + 84, 82, 73, 67, 84, 76, 217, 83, 84, 82, 69, 84, 67, 72, 69, 196, 83, 84, + 82, 69, 84, 67, 72, 128, 83, 84, 82, 69, 83, 211, 83, 84, 82, 69, 78, 71, + 84, 72, 128, 83, 84, 82, 69, 76, 193, 83, 84, 82, 69, 65, 77, 69, 82, + 128, 83, 84, 82, 65, 87, 66, 69, 82, 82, 89, 128, 83, 84, 82, 65, 87, + 128, 83, 84, 82, 65, 84, 85, 77, 45, 50, 128, 83, 84, 82, 65, 84, 85, 77, + 128, 83, 84, 82, 65, 84, 85, 205, 83, 84, 82, 65, 84, 73, 65, 206, 83, + 84, 82, 65, 78, 78, 79, 128, 83, 84, 82, 65, 78, 78, 207, 83, 84, 82, 65, + 73, 78, 69, 82, 128, 83, 84, 82, 65, 73, 71, 72, 84, 78, 69, 83, 83, 128, + 83, 84, 82, 65, 73, 71, 72, 84, 128, 83, 84, 82, 65, 73, 71, 72, 212, 83, + 84, 82, 65, 73, 70, 128, 83, 84, 82, 65, 71, 71, 73, 83, 77, 65, 84, 65, + 128, 83, 84, 79, 86, 69, 128, 83, 84, 79, 82, 69, 128, 83, 84, 79, 80, + 87, 65, 84, 67, 72, 128, 83, 84, 79, 80, 80, 73, 78, 71, 128, 83, 84, 79, + 80, 80, 65, 71, 69, 128, 83, 84, 79, 80, 73, 84, 83, 65, 128, 83, 84, 79, + 80, 73, 84, 83, 193, 83, 84, 79, 80, 128, 83, 84, 79, 208, 83, 84, 79, + 78, 69, 128, 83, 84, 79, 67, 75, 128, 83, 84, 79, 67, 203, 83, 84, 73, + 82, 82, 85, 208, 83, 84, 73, 77, 77, 69, 128, 83, 84, 73, 76, 204, 83, + 84, 73, 76, 197, 83, 84, 73, 71, 77, 65, 128, 83, 84, 73, 67, 75, 73, 78, + 199, 83, 84, 73, 67, 203, 83, 84, 69, 84, 72, 79, 83, 67, 79, 80, 69, + 128, 83, 84, 69, 82, 69, 79, 128, 83, 84, 69, 80, 128, 83, 84, 69, 78, + 79, 71, 82, 65, 80, 72, 73, 195, 83, 84, 69, 77, 128, 83, 84, 69, 65, 77, + 217, 83, 84, 69, 65, 77, 73, 78, 199, 83, 84, 69, 65, 77, 128, 83, 84, + 69, 65, 205, 83, 84, 65, 86, 82, 79, 85, 128, 83, 84, 65, 86, 82, 79, 83, + 128, 83, 84, 65, 86, 82, 79, 211, 83, 84, 65, 85, 82, 79, 83, 128, 83, + 84, 65, 84, 89, 65, 128, 83, 84, 65, 84, 89, 193, 83, 84, 65, 84, 85, + 197, 83, 84, 65, 84, 73, 79, 78, 128, 83, 84, 65, 84, 69, 82, 83, 128, + 83, 84, 65, 84, 69, 128, 83, 84, 65, 82, 84, 73, 78, 199, 83, 84, 65, 82, + 84, 128, 83, 84, 65, 82, 212, 83, 84, 65, 82, 83, 128, 83, 84, 65, 82, + 82, 69, 196, 83, 84, 65, 82, 75, 128, 83, 84, 65, 82, 128, 83, 84, 65, + 210, 83, 84, 65, 78, 68, 83, 84, 73, 76, 76, 128, 83, 84, 65, 78, 68, 73, + 78, 199, 83, 84, 65, 78, 68, 65, 82, 196, 83, 84, 65, 78, 68, 128, 83, + 84, 65, 78, 128, 83, 84, 65, 77, 80, 69, 196, 83, 84, 65, 76, 76, 73, 79, + 78, 128, 83, 84, 65, 70, 70, 128, 83, 84, 65, 70, 198, 83, 84, 65, 68, + 73, 85, 77, 128, 83, 84, 65, 67, 75, 69, 196, 83, 84, 65, 67, 67, 65, 84, + 79, 128, 83, 84, 65, 67, 67, 65, 84, 73, 83, 83, 73, 77, 79, 128, 83, 84, + 50, 128, 83, 83, 89, 88, 128, 83, 83, 89, 84, 128, 83, 83, 89, 82, 88, + 128, 83, 83, 89, 82, 128, 83, 83, 89, 80, 128, 83, 83, 89, 128, 83, 83, + 85, 88, 128, 83, 83, 85, 85, 128, 83, 83, 85, 84, 128, 83, 83, 85, 80, + 128, 83, 83, 79, 88, 128, 83, 83, 79, 84, 128, 83, 83, 79, 80, 128, 83, + 83, 79, 79, 128, 83, 83, 79, 128, 83, 83, 73, 88, 128, 83, 83, 73, 84, + 128, 83, 83, 73, 80, 128, 83, 83, 73, 73, 128, 83, 83, 73, 69, 88, 128, + 83, 83, 73, 69, 80, 128, 83, 83, 73, 69, 128, 83, 83, 72, 73, 78, 128, + 83, 83, 72, 69, 128, 83, 83, 69, 88, 128, 83, 83, 69, 80, 128, 83, 83, + 69, 69, 128, 83, 83, 65, 88, 128, 83, 83, 65, 85, 128, 83, 83, 65, 84, + 128, 83, 83, 65, 80, 128, 83, 83, 65, 78, 71, 89, 69, 83, 73, 69, 85, 78, + 71, 128, 83, 83, 65, 78, 71, 89, 69, 79, 82, 73, 78, 72, 73, 69, 85, 72, + 128, 83, 83, 65, 78, 71, 84, 73, 75, 69, 85, 84, 45, 80, 73, 69, 85, 80, + 128, 83, 83, 65, 78, 71, 84, 73, 75, 69, 85, 84, 128, 83, 83, 65, 78, 71, + 84, 72, 73, 69, 85, 84, 72, 128, 83, 83, 65, 78, 71, 83, 73, 79, 83, 45, + 84, 73, 75, 69, 85, 84, 128, 83, 83, 65, 78, 71, 83, 73, 79, 83, 45, 80, + 73, 69, 85, 80, 128, 83, 83, 65, 78, 71, 83, 73, 79, 83, 45, 75, 73, 89, + 69, 79, 75, 128, 83, 83, 65, 78, 71, 83, 73, 79, 83, 128, 83, 83, 65, 78, + 71, 82, 73, 69, 85, 76, 45, 75, 72, 73, 69, 85, 75, 72, 128, 83, 83, 65, + 78, 71, 82, 73, 69, 85, 76, 128, 83, 83, 65, 78, 71, 80, 73, 69, 85, 80, + 128, 83, 83, 65, 78, 71, 78, 73, 69, 85, 78, 128, 83, 83, 65, 78, 71, 77, + 73, 69, 85, 77, 128, 83, 83, 65, 78, 71, 73, 69, 85, 78, 71, 128, 83, 83, + 65, 78, 71, 72, 73, 69, 85, 72, 128, 83, 83, 65, 78, 71, 67, 73, 69, 85, + 67, 45, 72, 73, 69, 85, 72, 128, 83, 83, 65, 78, 71, 67, 73, 69, 85, 67, + 128, 83, 83, 65, 78, 71, 65, 82, 65, 69, 65, 128, 83, 83, 65, 73, 128, + 83, 83, 65, 65, 128, 83, 83, 51, 128, 83, 83, 50, 128, 83, 82, 69, 68, + 78, 197, 83, 82, 128, 83, 81, 85, 73, 83, 200, 83, 81, 85, 73, 82, 82, + 69, 204, 83, 81, 85, 73, 71, 71, 76, 197, 83, 81, 85, 73, 68, 128, 83, + 81, 85, 69, 69, 90, 69, 68, 128, 83, 81, 85, 69, 69, 90, 197, 83, 81, 85, + 65, 212, 83, 81, 85, 65, 82, 69, 83, 128, 83, 81, 85, 65, 82, 69, 68, + 128, 83, 81, 85, 65, 82, 69, 128, 83, 80, 89, 128, 83, 80, 87, 65, 128, + 83, 80, 85, 78, 71, 211, 83, 80, 82, 79, 85, 84, 128, 83, 80, 82, 73, 78, + 71, 83, 128, 83, 80, 82, 73, 78, 71, 128, 83, 80, 82, 69, 67, 72, 71, 69, + 83, 65, 78, 199, 83, 80, 82, 69, 65, 68, 128, 83, 80, 82, 69, 65, 196, + 83, 80, 79, 85, 84, 73, 78, 199, 83, 80, 79, 84, 128, 83, 80, 79, 82, 84, + 211, 83, 80, 79, 79, 78, 128, 83, 80, 79, 79, 204, 83, 80, 79, 78, 71, + 69, 128, 83, 80, 79, 128, 83, 80, 76, 73, 84, 84, 73, 78, 199, 83, 80, + 76, 73, 84, 128, 83, 80, 76, 73, 212, 83, 80, 76, 65, 89, 69, 68, 128, + 83, 80, 76, 65, 83, 72, 73, 78, 199, 83, 80, 73, 82, 73, 84, 85, 211, 83, + 80, 73, 82, 73, 84, 128, 83, 80, 73, 82, 73, 212, 83, 80, 73, 82, 65, 78, + 84, 128, 83, 80, 73, 82, 65, 76, 128, 83, 80, 73, 82, 65, 204, 83, 80, + 73, 78, 69, 128, 83, 80, 73, 68, 69, 82, 217, 83, 80, 73, 68, 69, 82, + 128, 83, 80, 73, 68, 69, 210, 83, 80, 73, 67, 69, 128, 83, 80, 73, 128, + 83, 80, 72, 69, 82, 73, 67, 65, 204, 83, 80, 69, 83, 77, 73, 76, 207, 83, + 80, 69, 78, 212, 83, 80, 69, 69, 68, 66, 79, 65, 84, 128, 83, 80, 69, 69, + 67, 72, 128, 83, 80, 69, 69, 67, 200, 83, 80, 69, 67, 73, 65, 76, 128, + 83, 80, 69, 65, 82, 128, 83, 80, 69, 65, 75, 73, 78, 199, 83, 80, 69, 65, + 75, 69, 82, 128, 83, 80, 69, 65, 75, 69, 210, 83, 80, 69, 65, 75, 45, 78, + 79, 45, 69, 86, 73, 204, 83, 80, 69, 128, 83, 80, 65, 84, 72, 73, 128, + 83, 80, 65, 82, 75, 76, 73, 78, 199, 83, 80, 65, 82, 75, 76, 69, 83, 128, + 83, 80, 65, 82, 75, 76, 69, 82, 128, 83, 80, 65, 82, 75, 76, 69, 128, 83, + 80, 65, 71, 72, 69, 84, 84, 73, 128, 83, 80, 65, 68, 69, 83, 128, 83, 80, + 65, 68, 197, 83, 80, 65, 67, 73, 78, 199, 83, 80, 65, 67, 197, 83, 80, + 65, 128, 83, 79, 89, 79, 77, 66, 207, 83, 79, 89, 128, 83, 79, 87, 73, + 76, 207, 83, 79, 87, 128, 83, 79, 85, 84, 72, 69, 82, 206, 83, 79, 85, + 84, 72, 45, 83, 76, 65, 86, 69, 217, 83, 79, 85, 84, 200, 83, 79, 85, 82, + 67, 69, 128, 83, 79, 85, 78, 68, 128, 83, 79, 85, 78, 196, 83, 79, 85, + 78, 65, 80, 128, 83, 79, 85, 128, 83, 79, 83, 128, 83, 79, 82, 79, 67, + 72, 89, 193, 83, 79, 82, 73, 128, 83, 79, 82, 193, 83, 79, 81, 128, 83, + 79, 79, 206, 83, 79, 78, 74, 65, 77, 128, 83, 79, 78, 71, 128, 83, 79, + 78, 128, 83, 79, 77, 80, 69, 78, 199, 83, 79, 77, 128, 83, 79, 205, 83, + 79, 76, 73, 68, 85, 83, 128, 83, 79, 76, 73, 68, 85, 211, 83, 79, 76, 73, + 196, 83, 79, 76, 68, 73, 69, 82, 128, 83, 79, 72, 128, 83, 79, 71, 68, + 73, 65, 206, 83, 79, 70, 84, 87, 65, 82, 69, 45, 70, 85, 78, 67, 84, 73, + 79, 206, 83, 79, 70, 84, 78, 69, 83, 83, 128, 83, 79, 70, 84, 66, 65, 76, + 76, 128, 83, 79, 70, 212, 83, 79, 198, 83, 79, 67, 75, 83, 128, 83, 79, + 67, 73, 69, 84, 89, 128, 83, 79, 67, 67, 69, 210, 83, 79, 65, 80, 128, + 83, 79, 65, 128, 83, 79, 45, 55, 128, 83, 79, 45, 54, 128, 83, 79, 45, + 53, 128, 83, 79, 45, 52, 128, 83, 79, 45, 51, 128, 83, 79, 45, 50, 128, + 83, 79, 45, 49, 128, 83, 207, 83, 78, 79, 87, 77, 65, 78, 128, 83, 78, + 79, 87, 77, 65, 206, 83, 78, 79, 87, 70, 76, 65, 75, 69, 128, 83, 78, 79, + 87, 66, 79, 65, 82, 68, 69, 82, 128, 83, 78, 79, 87, 128, 83, 78, 79, + 215, 83, 78, 79, 85, 84, 128, 83, 78, 79, 85, 212, 83, 78, 69, 69, 90, + 73, 78, 199, 83, 78, 65, 208, 83, 78, 65, 75, 69, 128, 83, 78, 65, 75, + 197, 83, 78, 65, 73, 76, 128, 83, 78, 193, 83, 77, 79, 75, 73, 78, 199, + 83, 77, 73, 82, 75, 73, 78, 199, 83, 77, 73, 76, 73, 78, 199, 83, 77, 73, + 76, 69, 128, 83, 77, 73, 76, 197, 83, 77, 69, 65, 82, 128, 83, 77, 65, + 83, 200, 83, 77, 65, 76, 76, 69, 210, 83, 77, 65, 76, 76, 128, 83, 76, + 85, 82, 128, 83, 76, 79, 90, 72, 73, 84, 73, 69, 128, 83, 76, 79, 90, 72, + 73, 84, 73, 197, 83, 76, 79, 87, 76, 89, 128, 83, 76, 79, 87, 128, 83, + 76, 79, 215, 83, 76, 79, 86, 79, 128, 83, 76, 79, 84, 72, 128, 83, 76, + 79, 212, 83, 76, 79, 80, 73, 78, 199, 83, 76, 79, 80, 69, 128, 83, 76, + 79, 65, 206, 83, 76, 73, 78, 71, 128, 83, 76, 73, 71, 72, 84, 76, 217, + 83, 76, 73, 68, 73, 78, 71, 128, 83, 76, 73, 68, 69, 82, 128, 83, 76, 73, + 68, 69, 128, 83, 76, 73, 67, 69, 128, 83, 76, 73, 67, 197, 83, 76, 69, + 85, 84, 200, 83, 76, 69, 69, 80, 217, 83, 76, 69, 69, 80, 73, 78, 199, + 83, 76, 69, 69, 208, 83, 76, 69, 68, 128, 83, 76, 65, 86, 79, 78, 73, + 195, 83, 76, 65, 86, 69, 128, 83, 76, 65, 83, 72, 128, 83, 76, 65, 83, + 200, 83, 76, 65, 78, 84, 69, 196, 83, 75, 87, 65, 128, 83, 75, 87, 128, + 83, 75, 85, 78, 75, 128, 83, 75, 85, 76, 76, 128, 83, 75, 85, 76, 204, + 83, 75, 79, 66, 65, 128, 83, 75, 76, 73, 82, 79, 206, 83, 75, 73, 78, + 128, 83, 75, 73, 69, 82, 128, 83, 75, 201, 83, 75, 69, 87, 69, 196, 83, + 75, 65, 84, 69, 66, 79, 65, 82, 68, 128, 83, 75, 65, 84, 69, 128, 83, 75, + 65, 77, 69, 89, 84, 83, 193, 83, 75, 128, 83, 74, 69, 128, 83, 73, 90, + 197, 83, 73, 88, 84, 89, 45, 70, 79, 85, 82, 84, 72, 83, 128, 83, 73, 88, + 84, 89, 45, 70, 79, 85, 82, 84, 72, 128, 83, 73, 88, 84, 89, 45, 70, 79, + 85, 82, 84, 200, 83, 73, 88, 84, 89, 128, 83, 73, 88, 84, 217, 83, 73, + 88, 84, 72, 83, 128, 83, 73, 88, 84, 72, 211, 83, 73, 88, 84, 72, 128, + 83, 73, 88, 84, 69, 69, 78, 84, 72, 83, 128, 83, 73, 88, 84, 69, 69, 78, + 84, 72, 45, 50, 128, 83, 73, 88, 84, 69, 69, 78, 84, 72, 45, 49, 128, 83, + 73, 88, 84, 69, 69, 78, 84, 72, 128, 83, 73, 88, 84, 69, 69, 78, 84, 200, + 83, 73, 88, 84, 69, 69, 78, 128, 83, 73, 88, 84, 69, 69, 206, 83, 73, 88, + 45, 84, 72, 73, 82, 84, 89, 128, 83, 73, 88, 45, 83, 84, 82, 73, 78, 199, + 83, 73, 88, 45, 80, 69, 82, 45, 69, 205, 83, 73, 88, 45, 76, 73, 78, 197, + 83, 73, 216, 83, 73, 84, 69, 128, 83, 73, 83, 65, 128, 83, 73, 82, 82, + 65, 72, 128, 83, 73, 82, 73, 78, 71, 85, 128, 83, 73, 79, 83, 45, 84, 72, + 73, 69, 85, 84, 72, 128, 83, 73, 79, 83, 45, 83, 83, 65, 78, 71, 83, 73, + 79, 83, 128, 83, 73, 79, 83, 45, 82, 73, 69, 85, 76, 128, 83, 73, 79, 83, + 45, 80, 73, 69, 85, 80, 45, 75, 73, 89, 69, 79, 75, 128, 83, 73, 79, 83, + 45, 80, 72, 73, 69, 85, 80, 72, 128, 83, 73, 79, 83, 45, 80, 65, 78, 83, + 73, 79, 83, 128, 83, 73, 79, 83, 45, 78, 73, 69, 85, 78, 128, 83, 73, 79, + 83, 45, 77, 73, 69, 85, 77, 128, 83, 73, 79, 83, 45, 75, 72, 73, 69, 85, + 75, 72, 128, 83, 73, 79, 83, 45, 75, 65, 80, 89, 69, 79, 85, 78, 80, 73, + 69, 85, 80, 128, 83, 73, 79, 83, 45, 73, 69, 85, 78, 71, 128, 83, 73, 79, + 83, 45, 72, 73, 69, 85, 72, 128, 83, 73, 79, 83, 45, 67, 73, 69, 85, 67, + 128, 83, 73, 79, 83, 45, 67, 72, 73, 69, 85, 67, 72, 128, 83, 73, 79, + 211, 83, 73, 78, 85, 83, 79, 73, 196, 83, 73, 78, 79, 76, 79, 71, 73, 67, + 65, 204, 83, 73, 78, 78, 89, 73, 73, 89, 72, 69, 128, 83, 73, 78, 75, 73, + 78, 71, 128, 83, 73, 78, 71, 76, 69, 45, 83, 72, 73, 70, 84, 45, 51, 128, + 83, 73, 78, 71, 76, 69, 45, 83, 72, 73, 70, 84, 45, 50, 128, 83, 73, 78, + 71, 76, 69, 45, 76, 73, 78, 197, 83, 73, 78, 71, 76, 69, 128, 83, 73, 78, + 71, 76, 197, 83, 73, 78, 71, 65, 65, 84, 128, 83, 73, 78, 197, 83, 73, + 78, 68, 72, 201, 83, 73, 78, 128, 83, 73, 206, 83, 73, 77, 85, 76, 84, + 65, 78, 69, 79, 85, 83, 128, 83, 73, 77, 85, 76, 84, 65, 78, 69, 79, 85, + 211, 83, 73, 77, 80, 76, 73, 70, 73, 69, 196, 83, 73, 77, 73, 76, 65, 82, + 128, 83, 73, 77, 73, 76, 65, 210, 83, 73, 77, 65, 78, 83, 73, 211, 83, + 73, 77, 65, 76, 85, 78, 71, 85, 206, 83, 73, 77, 65, 128, 83, 73, 76, 86, + 69, 82, 128, 83, 73, 76, 75, 128, 83, 73, 76, 73, 81, 85, 193, 83, 73, + 76, 72, 79, 85, 69, 84, 84, 69, 128, 83, 73, 76, 72, 79, 85, 69, 84, 84, + 197, 83, 73, 76, 65, 51, 128, 83, 73, 75, 73, 128, 83, 73, 75, 50, 128, + 83, 73, 75, 178, 83, 73, 71, 78, 83, 128, 83, 73, 71, 77, 79, 73, 196, + 83, 73, 71, 77, 65, 128, 83, 73, 71, 77, 193, 83, 73, 71, 69, 204, 83, + 73, 71, 52, 128, 83, 73, 71, 180, 83, 73, 71, 128, 83, 73, 69, 69, 128, + 83, 73, 68, 69, 87, 65, 89, 211, 83, 73, 68, 69, 128, 83, 73, 68, 197, + 83, 73, 68, 68, 72, 73, 128, 83, 73, 68, 68, 72, 65, 77, 128, 83, 73, 68, + 68, 72, 65, 205, 83, 73, 67, 75, 78, 69, 83, 83, 128, 83, 73, 67, 75, 76, + 69, 128, 83, 73, 66, 197, 83, 73, 65, 128, 83, 73, 45, 54, 128, 83, 73, + 45, 53, 128, 83, 73, 45, 52, 128, 83, 73, 45, 51, 128, 83, 73, 45, 50, + 128, 83, 73, 45, 49, 128, 83, 201, 83, 72, 89, 88, 128, 83, 72, 89, 84, + 128, 83, 72, 89, 82, 88, 128, 83, 72, 89, 82, 128, 83, 72, 89, 80, 128, + 83, 72, 89, 69, 128, 83, 72, 89, 65, 128, 83, 72, 89, 128, 83, 72, 87, + 79, 89, 128, 83, 72, 87, 79, 79, 128, 83, 72, 87, 79, 128, 83, 72, 87, + 73, 73, 128, 83, 72, 87, 73, 128, 83, 72, 87, 69, 128, 83, 72, 87, 197, + 83, 72, 87, 65, 65, 128, 83, 72, 87, 65, 128, 83, 72, 86, 128, 83, 72, + 85, 88, 128, 83, 72, 85, 85, 128, 83, 72, 85, 84, 84, 76, 69, 67, 79, 67, + 75, 128, 83, 72, 85, 84, 128, 83, 72, 85, 82, 88, 128, 83, 72, 85, 82, + 128, 83, 72, 85, 80, 128, 83, 72, 85, 79, 88, 128, 83, 72, 85, 79, 80, + 128, 83, 72, 85, 79, 128, 83, 72, 85, 77, 128, 83, 72, 85, 76, 128, 83, + 72, 85, 70, 70, 76, 197, 83, 72, 85, 69, 81, 128, 83, 72, 85, 69, 78, 83, + 72, 85, 69, 84, 128, 83, 72, 85, 66, 85, 82, 128, 83, 72, 85, 65, 78, 71, + 88, 73, 128, 83, 72, 85, 50, 128, 83, 72, 85, 178, 83, 72, 85, 128, 83, + 72, 84, 65, 80, 73, 67, 128, 83, 72, 84, 65, 128, 83, 72, 82, 85, 71, + 128, 83, 72, 82, 79, 79, 128, 83, 72, 82, 79, 128, 83, 72, 82, 73, 78, + 69, 128, 83, 72, 82, 73, 77, 80, 128, 83, 72, 82, 73, 73, 128, 83, 72, + 82, 73, 128, 83, 72, 82, 65, 65, 128, 83, 72, 82, 65, 128, 83, 72, 79, + 89, 128, 83, 72, 79, 88, 128, 83, 72, 79, 87, 69, 82, 128, 83, 72, 79, + 85, 76, 68, 69, 82, 69, 196, 83, 72, 79, 85, 76, 68, 69, 210, 83, 72, 79, + 85, 128, 83, 72, 79, 84, 128, 83, 72, 79, 82, 84, 83, 128, 83, 72, 79, + 82, 84, 211, 83, 72, 79, 82, 84, 72, 65, 78, 196, 83, 72, 79, 82, 84, 69, + 78, 69, 82, 128, 83, 72, 79, 82, 84, 67, 65, 75, 69, 128, 83, 72, 79, 82, + 84, 45, 84, 87, 73, 71, 45, 89, 82, 128, 83, 72, 79, 82, 84, 45, 84, 87, + 73, 71, 45, 84, 89, 210, 83, 72, 79, 82, 84, 45, 84, 87, 73, 71, 45, 83, + 79, 204, 83, 72, 79, 82, 84, 45, 84, 87, 73, 71, 45, 79, 83, 211, 83, 72, + 79, 82, 84, 45, 84, 87, 73, 71, 45, 78, 65, 85, 196, 83, 72, 79, 82, 84, + 45, 84, 87, 73, 71, 45, 77, 65, 68, 210, 83, 72, 79, 82, 84, 45, 84, 87, + 73, 71, 45, 72, 65, 71, 65, 76, 204, 83, 72, 79, 82, 84, 45, 84, 87, 73, + 71, 45, 66, 74, 65, 82, 75, 65, 206, 83, 72, 79, 82, 84, 45, 84, 87, 73, + 71, 45, 65, 210, 83, 72, 79, 82, 84, 128, 83, 72, 79, 82, 212, 83, 72, + 79, 81, 128, 83, 72, 79, 209, 83, 72, 79, 80, 80, 73, 78, 199, 83, 72, + 79, 80, 128, 83, 72, 79, 79, 84, 73, 78, 199, 83, 72, 79, 79, 84, 128, + 83, 72, 79, 79, 73, 128, 83, 72, 79, 79, 128, 83, 72, 79, 71, 201, 83, + 72, 79, 199, 83, 72, 79, 69, 83, 128, 83, 72, 79, 69, 128, 83, 72, 79, + 197, 83, 72, 79, 67, 75, 69, 196, 83, 72, 79, 65, 128, 83, 72, 79, 128, + 83, 72, 73, 89, 89, 65, 65, 76, 65, 65, 128, 83, 72, 73, 84, 65, 128, 83, + 72, 73, 84, 193, 83, 72, 73, 82, 212, 83, 72, 73, 82, 65, 69, 128, 83, + 72, 73, 82, 128, 83, 72, 73, 210, 83, 72, 73, 81, 128, 83, 72, 73, 78, + 84, 207, 83, 72, 73, 78, 73, 71, 128, 83, 72, 73, 78, 68, 193, 83, 72, + 73, 206, 83, 72, 73, 77, 65, 128, 83, 72, 73, 77, 193, 83, 72, 73, 77, + 128, 83, 72, 73, 205, 83, 72, 73, 73, 78, 128, 83, 72, 73, 73, 128, 83, + 72, 73, 70, 212, 83, 72, 73, 69, 76, 68, 128, 83, 72, 73, 68, 128, 83, + 72, 73, 196, 83, 72, 72, 65, 128, 83, 72, 72, 193, 83, 72, 69, 88, 128, + 83, 72, 69, 86, 65, 128, 83, 72, 69, 85, 88, 128, 83, 72, 69, 85, 79, 81, 128, 83, 72, 69, 85, 65, 69, 81, 84, 85, 128, 83, 72, 69, 85, 65, 69, 81, 128, 83, 72, 69, 85, 65, 69, 128, 83, 72, 69, 84, 128, 83, 72, 69, 212, 83, 72, 69, 83, 72, 76, 65, 77, 128, 83, 72, 69, 83, 72, 73, 71, 128, 83, @@ -1716,136 +1718,137 @@ static const unsigned char lexicon[] = { 128, 81, 85, 69, 69, 206, 81, 85, 69, 128, 81, 85, 68, 68, 73, 83, 193, 81, 85, 66, 85, 84, 83, 128, 81, 85, 65, 84, 69, 82, 78, 73, 79, 206, 81, 85, 65, 82, 84, 69, 82, 83, 128, 81, 85, 65, 82, 84, 69, 82, 211, 81, 85, - 65, 82, 84, 69, 82, 128, 81, 85, 65, 78, 84, 73, 84, 217, 81, 85, 65, 68, - 82, 85, 80, 76, 197, 81, 85, 65, 68, 82, 65, 78, 84, 128, 81, 85, 65, 68, - 82, 65, 78, 212, 81, 85, 65, 68, 67, 79, 76, 79, 78, 128, 81, 85, 65, 68, - 128, 81, 85, 65, 196, 81, 85, 65, 128, 81, 85, 128, 81, 208, 81, 79, 88, - 128, 81, 79, 84, 128, 81, 79, 80, 72, 128, 81, 79, 80, 65, 128, 81, 79, - 80, 128, 81, 79, 79, 128, 81, 79, 207, 81, 79, 70, 128, 81, 79, 198, 81, - 79, 65, 128, 81, 79, 128, 81, 78, 128, 81, 73, 88, 128, 81, 73, 84, 83, - 65, 128, 81, 73, 84, 128, 81, 73, 80, 128, 81, 73, 73, 128, 81, 73, 70, - 128, 81, 73, 69, 88, 128, 81, 73, 69, 84, 128, 81, 73, 69, 80, 128, 81, - 73, 69, 128, 81, 73, 128, 81, 72, 87, 73, 128, 81, 72, 87, 69, 69, 128, - 81, 72, 87, 69, 128, 81, 72, 87, 65, 65, 128, 81, 72, 87, 65, 128, 81, - 72, 85, 128, 81, 72, 79, 80, 72, 128, 81, 72, 79, 128, 81, 72, 73, 128, - 81, 72, 69, 69, 128, 81, 72, 69, 128, 81, 72, 65, 85, 128, 81, 72, 65, - 65, 128, 81, 72, 65, 128, 81, 71, 65, 128, 81, 69, 84, 65, 78, 65, 128, - 81, 69, 69, 128, 81, 69, 128, 81, 65, 89, 128, 81, 65, 85, 128, 81, 65, - 84, 65, 78, 128, 81, 65, 82, 78, 69, 217, 81, 65, 82, 128, 81, 65, 81, - 128, 81, 65, 80, 72, 128, 81, 65, 77, 65, 84, 83, 128, 81, 65, 77, 65, - 84, 211, 81, 65, 76, 193, 81, 65, 73, 82, 84, 72, 82, 65, 128, 81, 65, - 73, 128, 81, 65, 70, 128, 81, 65, 198, 81, 65, 68, 77, 65, 128, 81, 65, - 65, 73, 128, 81, 65, 65, 70, 85, 128, 81, 65, 65, 70, 128, 81, 48, 48, - 55, 128, 81, 48, 48, 54, 128, 81, 48, 48, 53, 128, 81, 48, 48, 52, 128, - 81, 48, 48, 51, 128, 81, 48, 48, 50, 128, 81, 48, 48, 49, 128, 80, 90, - 128, 80, 89, 88, 128, 80, 89, 84, 128, 80, 89, 82, 88, 128, 80, 89, 82, - 128, 80, 89, 80, 128, 80, 87, 79, 89, 128, 80, 87, 79, 79, 128, 80, 87, - 79, 128, 80, 87, 207, 80, 87, 73, 73, 128, 80, 87, 73, 128, 80, 87, 69, - 69, 128, 80, 87, 69, 128, 80, 87, 65, 65, 128, 80, 87, 128, 80, 86, 128, - 80, 85, 90, 90, 76, 197, 80, 85, 88, 128, 80, 85, 85, 84, 128, 80, 85, - 85, 128, 80, 85, 84, 82, 69, 70, 65, 67, 84, 73, 79, 78, 128, 80, 85, 84, - 78, 65, 89, 65, 128, 80, 85, 84, 128, 80, 85, 212, 80, 85, 83, 72, 80, - 73, 78, 128, 80, 85, 83, 72, 80, 73, 75, 65, 128, 80, 85, 83, 72, 73, 78, - 199, 80, 85, 82, 88, 128, 80, 85, 82, 83, 69, 128, 80, 85, 82, 80, 76, - 197, 80, 85, 82, 78, 65, 77, 65, 128, 80, 85, 82, 73, 84, 89, 128, 80, - 85, 82, 73, 70, 89, 128, 80, 85, 82, 128, 80, 85, 81, 128, 80, 85, 80, - 128, 80, 85, 79, 88, 128, 80, 85, 79, 80, 128, 80, 85, 79, 128, 80, 85, - 78, 71, 65, 65, 77, 128, 80, 85, 78, 71, 128, 80, 85, 78, 67, 84, 85, - 211, 80, 85, 78, 67, 84, 85, 65, 84, 73, 79, 78, 128, 80, 85, 78, 67, 84, - 85, 65, 84, 73, 79, 206, 80, 85, 77, 80, 128, 80, 85, 77, 128, 80, 85, - 70, 70, 69, 68, 128, 80, 85, 69, 128, 80, 85, 67, 75, 128, 80, 85, 66, - 76, 73, 195, 80, 85, 194, 80, 85, 65, 81, 128, 80, 85, 65, 69, 128, 80, - 85, 65, 67, 72, 85, 197, 80, 85, 50, 128, 80, 85, 49, 128, 80, 85, 128, - 80, 84, 72, 65, 72, 193, 80, 84, 69, 128, 80, 83, 73, 76, 201, 80, 83, - 73, 70, 73, 83, 84, 79, 83, 89, 78, 65, 71, 77, 65, 128, 80, 83, 73, 70, - 73, 83, 84, 79, 80, 65, 82, 65, 75, 65, 76, 69, 83, 77, 65, 128, 80, 83, - 73, 70, 73, 83, 84, 79, 206, 80, 83, 73, 70, 73, 83, 84, 79, 76, 89, 71, - 73, 83, 77, 65, 128, 80, 83, 73, 128, 80, 83, 65, 76, 84, 69, 210, 80, - 83, 128, 80, 82, 79, 86, 69, 128, 80, 82, 79, 84, 79, 86, 65, 82, 89, - 211, 80, 82, 79, 84, 79, 211, 80, 82, 79, 84, 69, 67, 84, 69, 196, 80, - 82, 79, 83, 84, 65, 89, 65, 128, 80, 82, 79, 83, 71, 69, 71, 82, 65, 77, - 77, 69, 78, 73, 128, 80, 82, 79, 83, 69, 82, 80, 73, 78, 65, 128, 80, 82, - 79, 80, 79, 82, 84, 73, 79, 78, 65, 204, 80, 82, 79, 80, 79, 82, 84, 73, - 79, 78, 128, 80, 82, 79, 80, 69, 82, 84, 217, 80, 82, 79, 80, 69, 76, 76, - 69, 210, 80, 82, 79, 79, 70, 128, 80, 82, 79, 76, 79, 78, 71, 69, 196, - 80, 82, 79, 76, 65, 84, 73, 79, 78, 197, 80, 82, 79, 74, 69, 67, 84, 79, - 82, 128, 80, 82, 79, 74, 69, 67, 84, 73, 86, 69, 128, 80, 82, 79, 74, 69, - 67, 84, 73, 79, 78, 128, 80, 82, 79, 72, 73, 66, 73, 84, 69, 196, 80, 82, - 79, 71, 82, 69, 83, 83, 128, 80, 82, 79, 71, 82, 65, 205, 80, 82, 79, 70, - 79, 85, 78, 68, 128, 80, 82, 79, 68, 85, 67, 84, 128, 80, 82, 79, 68, 85, - 67, 212, 80, 82, 79, 66, 73, 78, 199, 80, 82, 73, 90, 78, 65, 203, 80, - 82, 73, 86, 65, 84, 69, 128, 80, 82, 73, 86, 65, 84, 197, 80, 82, 73, 86, - 65, 67, 217, 80, 82, 73, 83, 72, 84, 72, 65, 77, 65, 84, 82, 193, 80, 82, - 73, 78, 84, 83, 128, 80, 82, 73, 78, 84, 69, 82, 128, 80, 82, 73, 78, 84, - 69, 210, 80, 82, 73, 78, 84, 128, 80, 82, 73, 78, 212, 80, 82, 73, 78, - 67, 69, 83, 83, 128, 80, 82, 73, 78, 67, 69, 128, 80, 82, 73, 77, 69, - 128, 80, 82, 73, 77, 197, 80, 82, 69, 86, 73, 79, 85, 211, 80, 82, 69, - 84, 90, 69, 76, 128, 80, 82, 69, 83, 83, 69, 196, 80, 82, 69, 83, 69, 84, - 128, 80, 82, 69, 83, 69, 78, 84, 65, 84, 73, 79, 206, 80, 82, 69, 83, 67, - 82, 73, 80, 84, 73, 79, 206, 80, 82, 69, 80, 79, 78, 68, 69, 82, 65, 78, - 67, 69, 128, 80, 82, 69, 78, 75, 72, 65, 128, 80, 82, 69, 71, 78, 65, 78, - 212, 80, 82, 69, 70, 73, 88, 69, 196, 80, 82, 69, 70, 65, 67, 197, 80, - 82, 69, 67, 73, 80, 73, 84, 65, 84, 69, 128, 80, 82, 69, 67, 69, 68, 73, - 78, 199, 80, 82, 69, 67, 69, 68, 69, 83, 128, 80, 82, 69, 67, 69, 68, 69, - 211, 80, 82, 69, 67, 69, 68, 69, 196, 80, 82, 69, 67, 69, 68, 69, 128, - 80, 82, 69, 67, 69, 68, 197, 80, 82, 65, 89, 69, 210, 80, 82, 65, 77, 45, - 80, 73, 73, 128, 80, 82, 65, 77, 45, 80, 73, 201, 80, 82, 65, 77, 45, 77, - 85, 79, 89, 128, 80, 82, 65, 77, 45, 77, 85, 79, 217, 80, 82, 65, 77, 45, - 66, 85, 79, 78, 128, 80, 82, 65, 77, 45, 66, 85, 79, 206, 80, 82, 65, 77, - 45, 66, 69, 73, 128, 80, 82, 65, 77, 45, 66, 69, 201, 80, 82, 65, 77, - 128, 80, 82, 65, 205, 80, 82, 128, 80, 80, 86, 128, 80, 80, 77, 128, 80, - 80, 65, 128, 80, 79, 89, 128, 80, 79, 88, 128, 80, 79, 87, 69, 82, 211, - 80, 79, 87, 69, 82, 128, 80, 79, 87, 69, 210, 80, 79, 87, 68, 69, 82, 69, - 196, 80, 79, 87, 68, 69, 82, 128, 80, 79, 86, 89, 83, 72, 69, 128, 80, - 79, 86, 89, 83, 72, 197, 80, 79, 86, 79, 68, 78, 89, 128, 80, 79, 85, 82, - 73, 78, 199, 80, 79, 85, 78, 196, 80, 79, 85, 76, 84, 82, 217, 80, 79, - 85, 67, 72, 128, 80, 79, 84, 84, 69, 196, 80, 79, 84, 65, 84, 79, 128, - 80, 79, 84, 65, 66, 76, 197, 80, 79, 212, 80, 79, 83, 84, 80, 79, 83, 73, - 84, 73, 79, 206, 80, 79, 83, 84, 66, 79, 88, 128, 80, 79, 83, 84, 65, - 204, 80, 79, 83, 84, 128, 80, 79, 83, 212, 80, 79, 83, 83, 69, 83, 83, - 73, 79, 78, 128, 80, 79, 83, 83, 69, 83, 83, 73, 79, 206, 80, 79, 83, 73, - 84, 73, 79, 78, 83, 128, 80, 79, 83, 73, 84, 73, 79, 78, 128, 80, 79, 83, - 69, 73, 68, 79, 78, 128, 80, 79, 82, 84, 65, 66, 76, 197, 80, 79, 82, 82, - 69, 67, 84, 85, 83, 128, 80, 79, 82, 82, 69, 67, 84, 85, 211, 80, 79, 80, - 80, 73, 78, 199, 80, 79, 80, 80, 69, 82, 128, 80, 79, 80, 67, 79, 82, 78, - 128, 80, 79, 80, 128, 80, 79, 208, 80, 79, 79, 68, 76, 69, 128, 80, 79, - 79, 128, 80, 79, 78, 68, 79, 128, 80, 79, 206, 80, 79, 77, 77, 69, 69, - 128, 80, 79, 77, 77, 69, 197, 80, 79, 76, 85, 80, 79, 86, 79, 68, 78, 65, - 89, 65, 128, 80, 79, 76, 79, 128, 80, 79, 76, 78, 65, 89, 65, 128, 80, - 79, 76, 76, 85, 128, 80, 79, 76, 75, 85, 76, 73, 90, 77, 89, 128, 80, 79, - 76, 73, 83, 72, 128, 80, 79, 76, 73, 83, 200, 80, 79, 76, 73, 67, 197, - 80, 79, 76, 201, 80, 79, 76, 69, 128, 80, 79, 76, 197, 80, 79, 75, 82, - 89, 84, 73, 69, 128, 80, 79, 75, 79, 74, 73, 128, 80, 79, 73, 78, 84, - 211, 80, 79, 73, 78, 84, 79, 128, 80, 79, 73, 78, 84, 69, 82, 128, 80, - 79, 73, 78, 84, 69, 196, 80, 79, 73, 78, 84, 128, 80, 79, 73, 78, 212, - 80, 79, 69, 84, 82, 217, 80, 79, 69, 84, 73, 195, 80, 79, 68, 86, 69, 82, - 84, 75, 65, 128, 80, 79, 68, 67, 72, 65, 83, 72, 73, 69, 77, 128, 80, 79, - 68, 67, 72, 65, 83, 72, 73, 69, 128, 80, 79, 68, 67, 72, 65, 83, 72, 73, - 197, 80, 79, 68, 65, 84, 85, 83, 128, 80, 79, 67, 75, 69, 212, 80, 79, - 65, 128, 80, 207, 80, 78, 69, 85, 77, 65, 84, 65, 128, 80, 76, 85, 84, - 207, 80, 76, 85, 84, 65, 128, 80, 76, 85, 83, 45, 77, 73, 78, 85, 211, - 80, 76, 85, 83, 128, 80, 76, 85, 82, 65, 76, 128, 80, 76, 85, 78, 71, 69, - 82, 128, 80, 76, 85, 77, 69, 196, 80, 76, 85, 77, 128, 80, 76, 85, 75, - 128, 80, 76, 85, 71, 128, 80, 76, 85, 128, 80, 76, 79, 87, 128, 80, 76, - 79, 80, 72, 85, 128, 80, 76, 72, 65, 85, 128, 80, 76, 69, 84, 72, 82, 79, - 78, 128, 80, 76, 69, 65, 68, 73, 78, 199, 80, 76, 68, 128, 80, 76, 65, - 89, 73, 78, 199, 80, 76, 65, 89, 71, 82, 79, 85, 78, 196, 80, 76, 65, 84, - 69, 128, 80, 76, 65, 83, 84, 73, 67, 83, 128, 80, 76, 65, 78, 84, 128, - 80, 76, 65, 78, 69, 84, 128, 80, 76, 65, 78, 69, 128, 80, 76, 65, 78, 67, - 203, 80, 76, 65, 75, 128, 80, 76, 65, 71, 73, 79, 211, 80, 76, 65, 67, - 69, 72, 79, 76, 68, 69, 82, 128, 80, 76, 65, 67, 69, 72, 79, 76, 68, 69, - 210, 80, 76, 65, 67, 197, 80, 76, 65, 67, 65, 82, 68, 128, 80, 76, 65, - 128, 80, 73, 90, 90, 73, 67, 65, 84, 79, 128, 80, 73, 90, 90, 65, 128, - 80, 73, 88, 128, 80, 73, 87, 82, 128, 80, 73, 84, 67, 72, 70, 79, 82, 75, - 128, 80, 73, 84, 67, 72, 70, 79, 82, 203, 80, 73, 84, 128, 80, 73, 83, - 84, 79, 76, 128, 80, 73, 83, 69, 76, 69, 72, 128, 80, 73, 83, 67, 69, 83, - 128, 80, 73, 82, 73, 71, 128, 80, 73, 82, 73, 199, 80, 73, 82, 73, 69, - 69, 78, 128, 80, 73, 82, 65, 67, 89, 128, 80, 73, 82, 50, 128, 80, 73, - 80, 73, 78, 71, 128, 80, 73, 80, 65, 69, 77, 71, 66, 73, 69, 69, 128, 80, - 73, 80, 65, 69, 77, 66, 65, 128, 80, 73, 80, 128, 80, 73, 78, 87, 72, 69, - 69, 204, 80, 73, 78, 69, 65, 80, 80, 76, 69, 128, 80, 73, 78, 197, 80, - 73, 78, 67, 72, 73, 78, 199, 80, 73, 78, 67, 72, 69, 196, 80, 73, 78, 65, - 84, 65, 128, 80, 73, 78, 65, 82, 66, 79, 82, 65, 83, 128, 80, 73, 76, 76, + 65, 82, 84, 69, 82, 128, 81, 85, 65, 79, 65, 82, 128, 81, 85, 65, 78, 84, + 73, 84, 217, 81, 85, 65, 68, 82, 85, 80, 76, 197, 81, 85, 65, 68, 82, 65, + 78, 84, 128, 81, 85, 65, 68, 82, 65, 78, 212, 81, 85, 65, 68, 67, 79, 76, + 79, 78, 128, 81, 85, 65, 68, 128, 81, 85, 65, 196, 81, 85, 65, 128, 81, + 85, 128, 81, 208, 81, 79, 88, 128, 81, 79, 84, 128, 81, 79, 80, 72, 128, + 81, 79, 80, 65, 128, 81, 79, 80, 128, 81, 79, 79, 128, 81, 79, 207, 81, + 79, 70, 128, 81, 79, 198, 81, 79, 65, 128, 81, 79, 128, 81, 78, 128, 81, + 73, 88, 128, 81, 73, 84, 83, 65, 128, 81, 73, 84, 128, 81, 73, 80, 128, + 81, 73, 73, 128, 81, 73, 70, 128, 81, 73, 69, 88, 128, 81, 73, 69, 84, + 128, 81, 73, 69, 80, 128, 81, 73, 69, 128, 81, 73, 128, 81, 72, 87, 73, + 128, 81, 72, 87, 69, 69, 128, 81, 72, 87, 69, 128, 81, 72, 87, 65, 65, + 128, 81, 72, 87, 65, 128, 81, 72, 85, 128, 81, 72, 79, 80, 72, 128, 81, + 72, 79, 128, 81, 72, 73, 128, 81, 72, 69, 69, 128, 81, 72, 69, 128, 81, + 72, 65, 85, 128, 81, 72, 65, 65, 128, 81, 72, 65, 128, 81, 71, 65, 128, + 81, 69, 84, 65, 78, 65, 128, 81, 69, 69, 128, 81, 69, 128, 81, 65, 89, + 128, 81, 65, 85, 128, 81, 65, 84, 65, 78, 128, 81, 65, 83, 82, 128, 81, + 65, 82, 78, 69, 217, 81, 65, 82, 128, 81, 65, 81, 128, 81, 65, 80, 72, + 128, 81, 65, 77, 65, 84, 83, 128, 81, 65, 77, 65, 84, 211, 81, 65, 76, + 193, 81, 65, 73, 82, 84, 72, 82, 65, 128, 81, 65, 73, 128, 81, 65, 70, + 128, 81, 65, 198, 81, 65, 68, 77, 65, 128, 81, 65, 65, 73, 128, 81, 65, + 65, 70, 85, 128, 81, 65, 65, 70, 128, 81, 48, 48, 55, 128, 81, 48, 48, + 54, 128, 81, 48, 48, 53, 128, 81, 48, 48, 52, 128, 81, 48, 48, 51, 128, + 81, 48, 48, 50, 128, 81, 48, 48, 49, 128, 80, 90, 128, 80, 89, 88, 128, + 80, 89, 84, 128, 80, 89, 82, 88, 128, 80, 89, 82, 128, 80, 89, 80, 128, + 80, 87, 79, 89, 128, 80, 87, 79, 79, 128, 80, 87, 79, 128, 80, 87, 207, + 80, 87, 73, 73, 128, 80, 87, 73, 128, 80, 87, 69, 69, 128, 80, 87, 69, + 128, 80, 87, 65, 65, 128, 80, 87, 128, 80, 86, 128, 80, 85, 90, 90, 76, + 197, 80, 85, 88, 128, 80, 85, 85, 84, 128, 80, 85, 85, 128, 80, 85, 84, + 82, 69, 70, 65, 67, 84, 73, 79, 78, 128, 80, 85, 84, 78, 65, 89, 65, 128, + 80, 85, 84, 128, 80, 85, 212, 80, 85, 83, 72, 80, 73, 78, 128, 80, 85, + 83, 72, 80, 73, 75, 65, 128, 80, 85, 83, 72, 73, 78, 199, 80, 85, 82, 88, + 128, 80, 85, 82, 83, 69, 128, 80, 85, 82, 80, 76, 197, 80, 85, 82, 78, + 65, 77, 65, 128, 80, 85, 82, 73, 84, 89, 128, 80, 85, 82, 73, 70, 89, + 128, 80, 85, 82, 128, 80, 85, 81, 128, 80, 85, 80, 128, 80, 85, 79, 88, + 128, 80, 85, 79, 80, 128, 80, 85, 79, 128, 80, 85, 78, 71, 65, 65, 77, + 128, 80, 85, 78, 71, 128, 80, 85, 78, 67, 84, 85, 211, 80, 85, 78, 67, + 84, 85, 65, 84, 73, 79, 78, 128, 80, 85, 78, 67, 84, 85, 65, 84, 73, 79, + 206, 80, 85, 77, 80, 128, 80, 85, 77, 128, 80, 85, 70, 70, 69, 68, 128, + 80, 85, 69, 128, 80, 85, 67, 75, 128, 80, 85, 66, 76, 73, 195, 80, 85, + 194, 80, 85, 65, 81, 128, 80, 85, 65, 69, 128, 80, 85, 65, 67, 72, 85, + 197, 80, 85, 50, 128, 80, 85, 49, 128, 80, 85, 128, 80, 84, 72, 65, 72, + 193, 80, 84, 69, 128, 80, 83, 73, 76, 201, 80, 83, 73, 70, 73, 83, 84, + 79, 83, 89, 78, 65, 71, 77, 65, 128, 80, 83, 73, 70, 73, 83, 84, 79, 80, + 65, 82, 65, 75, 65, 76, 69, 83, 77, 65, 128, 80, 83, 73, 70, 73, 83, 84, + 79, 206, 80, 83, 73, 70, 73, 83, 84, 79, 76, 89, 71, 73, 83, 77, 65, 128, + 80, 83, 73, 128, 80, 83, 65, 76, 84, 69, 210, 80, 83, 128, 80, 82, 79, + 86, 69, 128, 80, 82, 79, 84, 79, 86, 65, 82, 89, 211, 80, 82, 79, 84, 79, + 211, 80, 82, 79, 84, 69, 67, 84, 69, 196, 80, 82, 79, 83, 84, 65, 89, 65, + 128, 80, 82, 79, 83, 71, 69, 71, 82, 65, 77, 77, 69, 78, 73, 128, 80, 82, + 79, 83, 69, 82, 80, 73, 78, 65, 128, 80, 82, 79, 80, 79, 82, 84, 73, 79, + 78, 65, 204, 80, 82, 79, 80, 79, 82, 84, 73, 79, 78, 128, 80, 82, 79, 80, + 69, 82, 84, 217, 80, 82, 79, 80, 69, 76, 76, 69, 210, 80, 82, 79, 79, 70, + 128, 80, 82, 79, 76, 79, 78, 71, 69, 196, 80, 82, 79, 76, 65, 84, 73, 79, + 78, 197, 80, 82, 79, 74, 69, 67, 84, 79, 82, 128, 80, 82, 79, 74, 69, 67, + 84, 73, 86, 69, 128, 80, 82, 79, 74, 69, 67, 84, 73, 79, 78, 128, 80, 82, + 79, 72, 73, 66, 73, 84, 69, 196, 80, 82, 79, 71, 82, 69, 83, 83, 128, 80, + 82, 79, 71, 82, 65, 205, 80, 82, 79, 70, 79, 85, 78, 68, 128, 80, 82, 79, + 68, 85, 67, 84, 128, 80, 82, 79, 68, 85, 67, 212, 80, 82, 79, 66, 73, 78, + 199, 80, 82, 73, 90, 78, 65, 203, 80, 82, 73, 86, 65, 84, 69, 128, 80, + 82, 73, 86, 65, 84, 197, 80, 82, 73, 86, 65, 67, 217, 80, 82, 73, 83, 72, + 84, 72, 65, 77, 65, 84, 82, 193, 80, 82, 73, 78, 84, 83, 128, 80, 82, 73, + 78, 84, 69, 82, 128, 80, 82, 73, 78, 84, 69, 210, 80, 82, 73, 78, 84, + 128, 80, 82, 73, 78, 212, 80, 82, 73, 78, 67, 69, 83, 83, 128, 80, 82, + 73, 78, 67, 69, 128, 80, 82, 73, 77, 69, 128, 80, 82, 73, 77, 197, 80, + 82, 69, 86, 73, 79, 85, 211, 80, 82, 69, 84, 90, 69, 76, 128, 80, 82, 69, + 83, 83, 69, 196, 80, 82, 69, 83, 69, 84, 128, 80, 82, 69, 83, 69, 78, 84, + 65, 84, 73, 79, 206, 80, 82, 69, 83, 67, 82, 73, 80, 84, 73, 79, 206, 80, + 82, 69, 80, 79, 78, 68, 69, 82, 65, 78, 67, 69, 128, 80, 82, 69, 78, 75, + 72, 65, 128, 80, 82, 69, 71, 78, 65, 78, 212, 80, 82, 69, 70, 73, 88, 69, + 196, 80, 82, 69, 70, 65, 67, 197, 80, 82, 69, 67, 73, 80, 73, 84, 65, 84, + 69, 128, 80, 82, 69, 67, 69, 68, 73, 78, 199, 80, 82, 69, 67, 69, 68, 69, + 83, 128, 80, 82, 69, 67, 69, 68, 69, 211, 80, 82, 69, 67, 69, 68, 69, + 196, 80, 82, 69, 67, 69, 68, 69, 128, 80, 82, 69, 67, 69, 68, 197, 80, + 82, 65, 89, 69, 210, 80, 82, 65, 77, 45, 80, 73, 73, 128, 80, 82, 65, 77, + 45, 80, 73, 201, 80, 82, 65, 77, 45, 77, 85, 79, 89, 128, 80, 82, 65, 77, + 45, 77, 85, 79, 217, 80, 82, 65, 77, 45, 66, 85, 79, 78, 128, 80, 82, 65, + 77, 45, 66, 85, 79, 206, 80, 82, 65, 77, 45, 66, 69, 73, 128, 80, 82, 65, + 77, 45, 66, 69, 201, 80, 82, 65, 77, 128, 80, 82, 65, 205, 80, 82, 128, + 80, 80, 86, 128, 80, 80, 77, 128, 80, 80, 65, 128, 80, 79, 89, 128, 80, + 79, 88, 128, 80, 79, 87, 69, 82, 211, 80, 79, 87, 69, 82, 128, 80, 79, + 87, 69, 210, 80, 79, 87, 68, 69, 82, 69, 196, 80, 79, 87, 68, 69, 82, + 128, 80, 79, 86, 89, 83, 72, 69, 128, 80, 79, 86, 89, 83, 72, 197, 80, + 79, 86, 79, 68, 78, 89, 128, 80, 79, 85, 82, 73, 78, 199, 80, 79, 85, 78, + 196, 80, 79, 85, 76, 84, 82, 217, 80, 79, 85, 67, 72, 128, 80, 79, 84, + 84, 69, 196, 80, 79, 84, 65, 84, 79, 128, 80, 79, 84, 65, 66, 76, 197, + 80, 79, 212, 80, 79, 83, 84, 80, 79, 83, 73, 84, 73, 79, 206, 80, 79, 83, + 84, 66, 79, 88, 128, 80, 79, 83, 84, 65, 204, 80, 79, 83, 84, 128, 80, + 79, 83, 212, 80, 79, 83, 83, 69, 83, 83, 73, 79, 78, 128, 80, 79, 83, 83, + 69, 83, 83, 73, 79, 206, 80, 79, 83, 73, 84, 73, 79, 78, 83, 128, 80, 79, + 83, 73, 84, 73, 79, 78, 128, 80, 79, 83, 69, 73, 68, 79, 78, 128, 80, 79, + 82, 84, 65, 66, 76, 197, 80, 79, 82, 82, 69, 67, 84, 85, 83, 128, 80, 79, + 82, 82, 69, 67, 84, 85, 211, 80, 79, 80, 80, 73, 78, 199, 80, 79, 80, 80, + 69, 82, 128, 80, 79, 80, 67, 79, 82, 78, 128, 80, 79, 80, 128, 80, 79, + 208, 80, 79, 79, 68, 76, 69, 128, 80, 79, 79, 128, 80, 79, 78, 68, 79, + 128, 80, 79, 206, 80, 79, 77, 77, 69, 69, 128, 80, 79, 77, 77, 69, 197, + 80, 79, 76, 85, 80, 79, 86, 79, 68, 78, 65, 89, 65, 128, 80, 79, 76, 79, + 128, 80, 79, 76, 78, 65, 89, 65, 128, 80, 79, 76, 76, 85, 128, 80, 79, + 76, 75, 85, 76, 73, 90, 77, 89, 128, 80, 79, 76, 73, 83, 72, 128, 80, 79, + 76, 73, 83, 200, 80, 79, 76, 73, 67, 197, 80, 79, 76, 201, 80, 79, 76, + 69, 128, 80, 79, 76, 197, 80, 79, 75, 82, 89, 84, 73, 69, 128, 80, 79, + 75, 79, 74, 73, 128, 80, 79, 73, 78, 84, 211, 80, 79, 73, 78, 84, 79, + 128, 80, 79, 73, 78, 84, 69, 82, 128, 80, 79, 73, 78, 84, 69, 196, 80, + 79, 73, 78, 84, 128, 80, 79, 73, 78, 212, 80, 79, 69, 84, 82, 217, 80, + 79, 69, 84, 73, 195, 80, 79, 68, 86, 69, 82, 84, 75, 65, 128, 80, 79, 68, + 67, 72, 65, 83, 72, 73, 69, 77, 128, 80, 79, 68, 67, 72, 65, 83, 72, 73, + 69, 128, 80, 79, 68, 67, 72, 65, 83, 72, 73, 197, 80, 79, 68, 65, 84, 85, + 83, 128, 80, 79, 67, 75, 69, 212, 80, 79, 65, 128, 80, 207, 80, 78, 69, + 85, 77, 65, 84, 65, 128, 80, 76, 85, 84, 207, 80, 76, 85, 84, 65, 128, + 80, 76, 85, 83, 45, 77, 73, 78, 85, 211, 80, 76, 85, 83, 128, 80, 76, 85, + 82, 65, 76, 128, 80, 76, 85, 78, 71, 69, 82, 128, 80, 76, 85, 77, 69, + 196, 80, 76, 85, 77, 128, 80, 76, 85, 75, 128, 80, 76, 85, 71, 128, 80, + 76, 85, 128, 80, 76, 79, 87, 128, 80, 76, 79, 80, 72, 85, 128, 80, 76, + 72, 65, 85, 128, 80, 76, 69, 84, 72, 82, 79, 78, 128, 80, 76, 69, 65, 68, + 73, 78, 199, 80, 76, 68, 128, 80, 76, 65, 89, 73, 78, 199, 80, 76, 65, + 89, 71, 82, 79, 85, 78, 196, 80, 76, 65, 84, 69, 128, 80, 76, 65, 83, 84, + 73, 67, 83, 128, 80, 76, 65, 78, 84, 128, 80, 76, 65, 78, 69, 84, 128, + 80, 76, 65, 78, 69, 128, 80, 76, 65, 78, 67, 203, 80, 76, 65, 75, 128, + 80, 76, 65, 71, 73, 79, 211, 80, 76, 65, 67, 69, 72, 79, 76, 68, 69, 82, + 128, 80, 76, 65, 67, 69, 72, 79, 76, 68, 69, 210, 80, 76, 65, 67, 197, + 80, 76, 65, 67, 65, 82, 68, 128, 80, 76, 65, 128, 80, 73, 90, 90, 73, 67, + 65, 84, 79, 128, 80, 73, 90, 90, 65, 128, 80, 73, 88, 128, 80, 73, 87, + 82, 128, 80, 73, 84, 67, 72, 70, 79, 82, 75, 128, 80, 73, 84, 67, 72, 70, + 79, 82, 203, 80, 73, 84, 128, 80, 73, 83, 84, 79, 76, 128, 80, 73, 83, + 69, 76, 69, 72, 128, 80, 73, 83, 67, 69, 83, 128, 80, 73, 82, 73, 71, + 128, 80, 73, 82, 73, 199, 80, 73, 82, 73, 69, 69, 78, 128, 80, 73, 82, + 65, 67, 89, 128, 80, 73, 82, 50, 128, 80, 73, 80, 73, 78, 71, 128, 80, + 73, 80, 65, 69, 77, 71, 66, 73, 69, 69, 128, 80, 73, 80, 65, 69, 77, 66, + 65, 128, 80, 73, 80, 128, 80, 73, 78, 87, 72, 69, 69, 204, 80, 73, 78, + 203, 80, 73, 78, 69, 65, 80, 80, 76, 69, 128, 80, 73, 78, 197, 80, 73, + 78, 67, 72, 73, 78, 199, 80, 73, 78, 67, 72, 69, 196, 80, 73, 78, 65, 84, + 65, 128, 80, 73, 78, 65, 82, 66, 79, 82, 65, 83, 128, 80, 73, 76, 76, 128, 80, 73, 76, 197, 80, 73, 76, 67, 82, 79, 215, 80, 73, 75, 85, 82, 85, 128, 80, 73, 75, 79, 128, 80, 73, 71, 128, 80, 73, 199, 80, 73, 69, 88, 128, 80, 73, 69, 85, 80, 45, 84, 72, 73, 69, 85, 84, 72, 128, 80, 73, @@ -1916,2286 +1919,2298 @@ static const unsigned char lexicon[] = { 65, 76, 128, 80, 69, 68, 69, 83, 84, 65, 204, 80, 69, 68, 65, 204, 80, 69, 65, 78, 85, 84, 83, 128, 80, 69, 65, 75, 211, 80, 69, 65, 67, 79, 67, 75, 128, 80, 69, 65, 67, 72, 128, 80, 69, 65, 67, 69, 128, 80, 69, 65, - 67, 197, 80, 68, 73, 128, 80, 68, 70, 128, 80, 68, 128, 80, 67, 128, 80, - 65, 90, 69, 82, 128, 80, 65, 89, 69, 82, 79, 75, 128, 80, 65, 89, 65, 78, - 78, 65, 128, 80, 65, 89, 128, 80, 65, 88, 128, 80, 65, 87, 78, 128, 80, - 65, 87, 206, 80, 65, 215, 80, 65, 86, 73, 89, 65, 78, 73, 128, 80, 65, - 85, 83, 197, 80, 65, 85, 75, 128, 80, 65, 85, 128, 80, 65, 213, 80, 65, - 84, 84, 217, 80, 65, 84, 84, 69, 82, 78, 128, 80, 65, 84, 72, 65, 77, 65, - 83, 65, 84, 128, 80, 65, 84, 72, 65, 75, 75, 85, 128, 80, 65, 84, 200, - 80, 65, 84, 65, 75, 128, 80, 65, 84, 65, 72, 128, 80, 65, 84, 128, 80, - 65, 83, 85, 81, 128, 80, 65, 83, 83, 80, 79, 82, 212, 80, 65, 83, 83, 73, - 86, 69, 45, 80, 85, 76, 76, 45, 85, 80, 45, 79, 85, 84, 80, 85, 212, 80, - 65, 83, 83, 73, 86, 69, 45, 80, 85, 76, 76, 45, 68, 79, 87, 78, 45, 79, - 85, 84, 80, 85, 212, 80, 65, 83, 83, 73, 77, 66, 65, 78, 71, 128, 80, 65, - 83, 83, 69, 78, 71, 69, 210, 80, 65, 83, 83, 69, 196, 80, 65, 83, 72, 84, - 65, 128, 80, 65, 83, 72, 65, 69, 128, 80, 65, 83, 69, 81, 128, 80, 65, - 83, 65, 78, 71, 65, 206, 80, 65, 82, 85, 77, 128, 80, 65, 82, 84, 217, - 80, 65, 82, 84, 78, 69, 82, 83, 72, 73, 208, 80, 65, 82, 84, 73, 65, 76, - 76, 89, 45, 82, 69, 67, 89, 67, 76, 69, 196, 80, 65, 82, 84, 73, 65, 204, - 80, 65, 82, 84, 72, 73, 65, 206, 80, 65, 82, 212, 80, 65, 82, 82, 79, 84, - 128, 80, 65, 82, 75, 128, 80, 65, 82, 73, 67, 72, 79, 78, 128, 80, 65, - 82, 69, 83, 84, 73, 71, 77, 69, 78, 79, 206, 80, 65, 82, 69, 82, 69, 78, - 128, 80, 65, 82, 69, 78, 84, 72, 69, 83, 73, 83, 128, 80, 65, 82, 69, 78, - 84, 72, 69, 83, 73, 211, 80, 65, 82, 69, 78, 84, 72, 69, 83, 69, 211, 80, - 65, 82, 65, 80, 72, 82, 65, 83, 197, 80, 65, 82, 65, 76, 76, 69, 76, 79, - 71, 82, 65, 77, 128, 80, 65, 82, 65, 76, 76, 69, 76, 128, 80, 65, 82, 65, - 76, 76, 69, 204, 80, 65, 82, 65, 75, 76, 73, 84, 73, 75, 73, 128, 80, 65, - 82, 65, 75, 76, 73, 84, 73, 75, 201, 80, 65, 82, 65, 75, 76, 73, 84, 128, - 80, 65, 82, 65, 75, 65, 76, 69, 83, 77, 193, 80, 65, 82, 65, 71, 82, 65, - 80, 72, 85, 211, 80, 65, 82, 65, 71, 82, 65, 80, 72, 79, 83, 128, 80, 65, - 82, 65, 71, 82, 65, 80, 72, 128, 80, 65, 82, 65, 71, 82, 65, 80, 200, 80, - 65, 82, 65, 67, 72, 85, 84, 69, 128, 80, 65, 82, 65, 128, 80, 65, 82, - 128, 80, 65, 80, 89, 82, 85, 83, 128, 80, 65, 80, 69, 82, 67, 76, 73, 80, - 83, 128, 80, 65, 80, 69, 82, 67, 76, 73, 80, 128, 80, 65, 80, 69, 82, - 128, 80, 65, 80, 69, 210, 80, 65, 80, 128, 80, 65, 208, 80, 65, 207, 80, - 65, 78, 89, 85, 75, 85, 128, 80, 65, 78, 89, 73, 75, 85, 128, 80, 65, 78, - 89, 69, 67, 69, 75, 128, 80, 65, 78, 89, 65, 78, 71, 71, 65, 128, 80, 65, - 78, 89, 65, 75, 82, 65, 128, 80, 65, 78, 84, 73, 128, 80, 65, 78, 84, - 201, 80, 65, 78, 83, 73, 79, 83, 45, 80, 73, 69, 85, 80, 128, 80, 65, 78, - 83, 73, 79, 83, 45, 75, 65, 80, 89, 69, 79, 85, 78, 80, 73, 69, 85, 80, - 128, 80, 65, 78, 79, 78, 71, 79, 78, 65, 78, 128, 80, 65, 78, 79, 76, 79, - 78, 71, 128, 80, 65, 78, 71, 87, 73, 83, 65, 68, 128, 80, 65, 78, 71, 82, - 65, 78, 71, 75, 69, 80, 128, 80, 65, 78, 71, 79, 76, 65, 84, 128, 80, 65, - 78, 71, 76, 79, 78, 71, 128, 80, 65, 78, 71, 76, 65, 89, 65, 82, 128, 80, - 65, 78, 71, 75, 79, 78, 128, 80, 65, 78, 71, 75, 65, 84, 128, 80, 65, 78, - 71, 72, 85, 76, 85, 128, 80, 65, 78, 71, 128, 80, 65, 78, 69, 85, 76, 69, - 85, 78, 71, 128, 80, 65, 78, 68, 193, 80, 65, 78, 67, 65, 75, 69, 83, - 128, 80, 65, 78, 65, 77, 128, 80, 65, 78, 65, 69, 76, 65, 69, 78, 71, - 128, 80, 65, 78, 128, 80, 65, 206, 80, 65, 77, 85, 78, 71, 75, 65, 72, - 128, 80, 65, 77, 85, 68, 80, 79, 68, 128, 80, 65, 77, 83, 72, 65, 69, - 128, 80, 65, 77, 80, 72, 89, 76, 73, 65, 206, 80, 65, 77, 73, 78, 71, 75, - 65, 76, 128, 80, 65, 77, 69, 80, 69, 84, 128, 80, 65, 77, 69, 78, 69, 78, - 71, 128, 80, 65, 77, 65, 68, 65, 128, 80, 65, 77, 65, 68, 193, 80, 65, - 77, 65, 65, 69, 72, 128, 80, 65, 76, 85, 84, 65, 128, 80, 65, 76, 79, 67, - 72, 75, 65, 128, 80, 65, 76, 77, 89, 82, 69, 78, 197, 80, 65, 76, 77, - 211, 80, 65, 76, 77, 128, 80, 65, 76, 205, 80, 65, 76, 76, 65, 87, 65, - 128, 80, 65, 76, 76, 65, 83, 128, 80, 65, 76, 75, 65, 128, 80, 65, 76, - 201, 80, 65, 76, 69, 84, 84, 69, 128, 80, 65, 76, 65, 85, 78, 199, 80, - 65, 76, 65, 84, 65, 76, 73, 90, 69, 196, 80, 65, 76, 65, 84, 65, 76, 73, - 90, 65, 84, 73, 79, 78, 128, 80, 65, 76, 65, 84, 65, 204, 80, 65, 75, 80, - 65, 203, 80, 65, 73, 89, 65, 78, 78, 79, 73, 128, 80, 65, 73, 82, 84, 72, - 82, 65, 128, 80, 65, 73, 82, 69, 196, 80, 65, 73, 78, 84, 66, 82, 85, 83, - 72, 128, 80, 65, 73, 128, 80, 65, 72, 76, 65, 86, 201, 80, 65, 72, 128, - 80, 65, 71, 79, 68, 65, 128, 80, 65, 71, 69, 83, 128, 80, 65, 71, 69, 82, - 128, 80, 65, 71, 197, 80, 65, 68, 77, 193, 80, 65, 68, 68, 76, 197, 80, - 65, 68, 68, 73, 78, 199, 80, 65, 68, 193, 80, 65, 68, 128, 80, 65, 67, - 75, 73, 78, 71, 128, 80, 65, 67, 75, 65, 71, 69, 128, 80, 65, 65, 84, 85, - 128, 80, 65, 65, 83, 69, 78, 84, 79, 128, 80, 65, 65, 82, 65, 77, 128, - 80, 65, 65, 82, 65, 69, 128, 80, 65, 65, 77, 128, 80, 65, 65, 73, 128, - 80, 65, 65, 45, 80, 73, 76, 76, 65, 128, 80, 65, 65, 128, 80, 50, 128, - 80, 48, 49, 49, 128, 80, 48, 49, 48, 128, 80, 48, 48, 57, 128, 80, 48, - 48, 56, 128, 80, 48, 48, 55, 128, 80, 48, 48, 54, 128, 80, 48, 48, 53, - 128, 80, 48, 48, 52, 128, 80, 48, 48, 51, 65, 128, 80, 48, 48, 51, 128, - 80, 48, 48, 50, 128, 80, 48, 48, 49, 65, 128, 80, 48, 48, 49, 128, 79, - 90, 128, 79, 89, 83, 84, 69, 82, 128, 79, 89, 82, 65, 78, 73, 83, 77, - 193, 79, 89, 65, 78, 78, 65, 128, 79, 88, 73, 65, 128, 79, 88, 73, 193, - 79, 88, 69, 73, 65, 201, 79, 88, 69, 73, 193, 79, 87, 76, 128, 79, 86, - 69, 82, 83, 84, 82, 85, 67, 203, 79, 86, 69, 82, 82, 73, 68, 69, 128, 79, - 86, 69, 82, 76, 79, 78, 199, 79, 86, 69, 82, 76, 73, 78, 69, 128, 79, 86, - 69, 82, 76, 65, 89, 128, 79, 86, 69, 82, 76, 65, 217, 79, 86, 69, 82, 76, - 65, 80, 80, 73, 78, 199, 79, 86, 69, 82, 76, 65, 80, 128, 79, 86, 69, 82, - 76, 65, 73, 68, 128, 79, 86, 69, 82, 76, 65, 73, 196, 79, 86, 69, 82, 72, - 69, 65, 84, 69, 196, 79, 86, 69, 82, 66, 65, 82, 128, 79, 86, 65, 76, - 128, 79, 86, 65, 204, 79, 85, 84, 76, 73, 78, 69, 196, 79, 85, 84, 76, - 73, 78, 69, 128, 79, 85, 84, 69, 210, 79, 85, 84, 66, 79, 216, 79, 85, - 78, 75, 73, 193, 79, 85, 78, 67, 69, 128, 79, 85, 78, 67, 197, 79, 84, - 85, 128, 79, 84, 84, 79, 77, 65, 206, 79, 84, 84, 69, 82, 128, 79, 84, - 84, 65, 86, 193, 79, 84, 84, 128, 79, 84, 83, 69, 67, 72, 75, 65, 128, - 79, 84, 72, 69, 82, 211, 79, 84, 72, 69, 210, 79, 84, 72, 65, 76, 65, - 206, 79, 84, 72, 65, 76, 128, 79, 83, 79, 75, 65, 128, 79, 83, 79, 75, - 193, 79, 83, 77, 65, 78, 89, 193, 79, 83, 67, 128, 79, 83, 65, 71, 197, - 79, 82, 84, 72, 79, 71, 79, 78, 65, 204, 79, 82, 84, 72, 79, 68, 79, 216, - 79, 82, 78, 65, 84, 197, 79, 82, 78, 65, 77, 69, 78, 84, 83, 128, 79, 82, - 78, 65, 77, 69, 78, 84, 128, 79, 82, 78, 65, 77, 69, 78, 212, 79, 82, 75, - 72, 79, 206, 79, 82, 73, 89, 193, 79, 82, 73, 71, 73, 78, 65, 204, 79, - 82, 73, 71, 73, 78, 128, 79, 82, 69, 45, 50, 128, 79, 82, 68, 73, 78, 65, - 204, 79, 82, 68, 69, 210, 79, 82, 67, 72, 73, 68, 128, 79, 82, 65, 78, - 71, 85, 84, 65, 78, 128, 79, 82, 65, 78, 71, 197, 79, 80, 84, 73, 79, - 206, 79, 80, 84, 73, 67, 65, 204, 79, 80, 80, 82, 69, 83, 83, 73, 79, 78, - 128, 79, 80, 80, 79, 83, 73, 84, 73, 79, 78, 128, 79, 80, 80, 79, 83, 73, - 78, 199, 79, 80, 80, 79, 83, 69, 128, 79, 80, 72, 73, 85, 67, 72, 85, 83, - 128, 79, 80, 69, 82, 65, 84, 79, 82, 128, 79, 80, 69, 82, 65, 84, 79, - 210, 79, 80, 69, 82, 65, 84, 73, 78, 199, 79, 80, 69, 78, 73, 78, 199, - 79, 80, 69, 78, 45, 80, 128, 79, 80, 69, 78, 45, 79, 85, 84, 76, 73, 78, - 69, 196, 79, 80, 69, 78, 45, 79, 128, 79, 80, 69, 78, 45, 207, 79, 80, - 69, 78, 45, 72, 69, 65, 68, 69, 196, 79, 80, 69, 78, 45, 67, 73, 82, 67, - 85, 73, 84, 45, 79, 85, 84, 80, 85, 212, 79, 80, 69, 78, 128, 79, 80, 69, - 206, 79, 79, 90, 69, 128, 79, 79, 89, 65, 78, 78, 65, 128, 79, 79, 85, - 128, 79, 79, 77, 85, 128, 79, 79, 72, 128, 79, 79, 69, 128, 79, 79, 66, - 79, 79, 70, 73, 76, 73, 128, 79, 78, 85, 128, 79, 78, 83, 85, 128, 79, - 78, 78, 128, 79, 78, 75, 65, 82, 128, 79, 78, 73, 79, 78, 128, 79, 78, - 69, 83, 69, 76, 70, 128, 79, 78, 69, 45, 87, 65, 217, 79, 78, 69, 45, 84, - 72, 73, 82, 84, 89, 128, 79, 78, 69, 45, 80, 73, 69, 67, 197, 79, 78, 69, - 45, 76, 73, 78, 197, 79, 78, 69, 45, 72, 85, 78, 68, 82, 69, 68, 45, 65, - 78, 68, 45, 83, 73, 88, 84, 73, 69, 84, 72, 128, 79, 78, 67, 79, 77, 73, - 78, 199, 79, 78, 65, 80, 128, 79, 78, 45, 79, 70, 198, 79, 77, 73, 83, - 83, 73, 79, 206, 79, 77, 73, 67, 82, 79, 78, 128, 79, 77, 73, 67, 82, 79, - 206, 79, 77, 69, 84, 128, 79, 77, 69, 71, 65, 128, 79, 77, 69, 71, 193, - 79, 77, 65, 76, 79, 78, 128, 79, 76, 73, 86, 69, 128, 79, 76, 73, 71, 79, - 206, 79, 76, 68, 128, 79, 75, 84, 207, 79, 75, 65, 82, 65, 128, 79, 75, - 65, 82, 193, 79, 74, 73, 66, 87, 65, 217, 79, 74, 69, 79, 78, 128, 79, - 73, 78, 128, 79, 73, 76, 128, 79, 73, 204, 79, 72, 77, 128, 79, 72, 205, - 79, 71, 82, 69, 128, 79, 71, 79, 78, 69, 75, 128, 79, 71, 79, 78, 69, - 203, 79, 71, 72, 65, 205, 79, 70, 70, 73, 67, 69, 82, 128, 79, 70, 70, - 73, 67, 69, 128, 79, 70, 70, 73, 67, 197, 79, 70, 70, 128, 79, 69, 89, - 128, 79, 69, 82, 128, 79, 69, 75, 128, 79, 69, 69, 128, 79, 68, 69, 78, - 128, 79, 68, 68, 128, 79, 68, 196, 79, 67, 84, 79, 80, 85, 83, 128, 79, - 67, 84, 79, 66, 69, 82, 128, 79, 67, 84, 69, 212, 79, 67, 84, 65, 71, 79, - 78, 65, 204, 79, 67, 84, 65, 71, 79, 78, 128, 79, 67, 210, 79, 67, 76, - 79, 67, 75, 128, 79, 67, 72, 75, 79, 77, 128, 79, 67, 67, 76, 85, 83, 73, - 79, 78, 128, 79, 66, 83, 84, 82, 85, 67, 84, 73, 79, 78, 128, 79, 66, 83, - 69, 82, 86, 69, 210, 79, 66, 79, 76, 211, 79, 66, 79, 204, 79, 66, 79, - 70, 73, 76, 73, 128, 79, 66, 76, 73, 81, 85, 197, 79, 66, 76, 65, 75, 79, - 128, 79, 66, 76, 65, 67, 72, 75, 79, 128, 79, 66, 74, 69, 67, 212, 79, - 66, 69, 76, 85, 83, 128, 79, 66, 69, 76, 79, 83, 128, 79, 66, 128, 79, - 65, 89, 128, 79, 65, 75, 128, 79, 65, 66, 79, 65, 70, 73, 76, 73, 128, - 79, 193, 79, 48, 53, 49, 128, 79, 48, 53, 48, 66, 128, 79, 48, 53, 48, - 65, 128, 79, 48, 53, 48, 128, 79, 48, 52, 57, 128, 79, 48, 52, 56, 128, - 79, 48, 52, 55, 128, 79, 48, 52, 54, 128, 79, 48, 52, 53, 128, 79, 48, - 52, 52, 128, 79, 48, 52, 51, 128, 79, 48, 52, 50, 128, 79, 48, 52, 49, - 128, 79, 48, 52, 48, 128, 79, 48, 51, 57, 128, 79, 48, 51, 56, 128, 79, - 48, 51, 55, 128, 79, 48, 51, 54, 68, 128, 79, 48, 51, 54, 67, 128, 79, - 48, 51, 54, 66, 128, 79, 48, 51, 54, 65, 128, 79, 48, 51, 54, 128, 79, - 48, 51, 53, 128, 79, 48, 51, 52, 128, 79, 48, 51, 51, 65, 128, 79, 48, - 51, 51, 128, 79, 48, 51, 50, 128, 79, 48, 51, 49, 128, 79, 48, 51, 48, - 65, 128, 79, 48, 51, 48, 128, 79, 48, 50, 57, 65, 128, 79, 48, 50, 57, - 128, 79, 48, 50, 56, 128, 79, 48, 50, 55, 128, 79, 48, 50, 54, 128, 79, - 48, 50, 53, 65, 128, 79, 48, 50, 53, 128, 79, 48, 50, 52, 65, 128, 79, - 48, 50, 52, 128, 79, 48, 50, 51, 128, 79, 48, 50, 50, 128, 79, 48, 50, - 49, 128, 79, 48, 50, 48, 65, 128, 79, 48, 50, 48, 128, 79, 48, 49, 57, - 65, 128, 79, 48, 49, 57, 128, 79, 48, 49, 56, 128, 79, 48, 49, 55, 128, - 79, 48, 49, 54, 128, 79, 48, 49, 53, 128, 79, 48, 49, 52, 128, 79, 48, - 49, 51, 128, 79, 48, 49, 50, 128, 79, 48, 49, 49, 128, 79, 48, 49, 48, - 67, 128, 79, 48, 49, 48, 66, 128, 79, 48, 49, 48, 65, 128, 79, 48, 49, - 48, 128, 79, 48, 48, 57, 128, 79, 48, 48, 56, 128, 79, 48, 48, 55, 128, - 79, 48, 48, 54, 70, 128, 79, 48, 48, 54, 69, 128, 79, 48, 48, 54, 68, - 128, 79, 48, 48, 54, 67, 128, 79, 48, 48, 54, 66, 128, 79, 48, 48, 54, - 65, 128, 79, 48, 48, 54, 128, 79, 48, 48, 53, 65, 128, 79, 48, 48, 53, - 128, 79, 48, 48, 52, 128, 79, 48, 48, 51, 128, 79, 48, 48, 50, 128, 79, - 48, 48, 49, 65, 128, 79, 48, 48, 49, 128, 79, 45, 89, 69, 128, 79, 45, - 79, 45, 73, 128, 79, 45, 69, 128, 78, 90, 89, 88, 128, 78, 90, 89, 84, - 128, 78, 90, 89, 82, 88, 128, 78, 90, 89, 82, 128, 78, 90, 89, 80, 128, - 78, 90, 89, 128, 78, 90, 85, 88, 128, 78, 90, 85, 82, 88, 128, 78, 90, - 85, 82, 128, 78, 90, 85, 81, 128, 78, 90, 85, 80, 128, 78, 90, 85, 79, - 88, 128, 78, 90, 85, 79, 128, 78, 90, 85, 206, 78, 90, 85, 128, 78, 90, - 79, 88, 128, 78, 90, 79, 80, 128, 78, 90, 73, 88, 128, 78, 90, 73, 84, - 128, 78, 90, 73, 80, 128, 78, 90, 73, 69, 88, 128, 78, 90, 73, 69, 80, - 128, 78, 90, 73, 69, 128, 78, 90, 73, 128, 78, 90, 69, 88, 128, 78, 90, - 69, 85, 77, 128, 78, 90, 69, 128, 78, 90, 65, 88, 128, 78, 90, 65, 84, - 128, 78, 90, 65, 81, 128, 78, 90, 65, 80, 128, 78, 90, 65, 128, 78, 90, - 193, 78, 89, 87, 65, 128, 78, 89, 85, 88, 128, 78, 89, 85, 85, 128, 78, - 89, 85, 84, 128, 78, 89, 85, 80, 128, 78, 89, 85, 79, 88, 128, 78, 89, - 85, 79, 80, 128, 78, 89, 85, 79, 128, 78, 89, 85, 78, 128, 78, 89, 85, - 69, 128, 78, 89, 85, 128, 78, 89, 79, 88, 128, 78, 89, 79, 84, 128, 78, - 89, 79, 80, 128, 78, 89, 79, 79, 128, 78, 89, 79, 78, 128, 78, 89, 79, - 65, 128, 78, 89, 79, 128, 78, 89, 74, 65, 128, 78, 89, 73, 88, 128, 78, - 89, 73, 84, 128, 78, 89, 73, 212, 78, 89, 73, 211, 78, 89, 73, 210, 78, - 89, 73, 80, 128, 78, 89, 73, 78, 45, 68, 79, 128, 78, 89, 73, 78, 128, - 78, 89, 73, 73, 128, 78, 89, 73, 69, 88, 128, 78, 89, 73, 69, 84, 128, - 78, 89, 73, 69, 80, 128, 78, 89, 73, 69, 128, 78, 89, 73, 65, 75, 69, 78, - 199, 78, 89, 73, 128, 78, 89, 201, 78, 89, 72, 65, 128, 78, 89, 69, 84, - 128, 78, 89, 69, 212, 78, 89, 69, 78, 128, 78, 89, 69, 72, 128, 78, 89, - 69, 200, 78, 89, 69, 69, 128, 78, 89, 69, 128, 78, 89, 196, 78, 89, 67, - 65, 128, 78, 89, 65, 85, 128, 78, 89, 65, 74, 128, 78, 89, 65, 73, 128, - 78, 89, 65, 72, 128, 78, 89, 65, 69, 77, 65, 69, 128, 78, 89, 65, 65, - 128, 78, 87, 79, 79, 128, 78, 87, 79, 128, 78, 87, 73, 73, 128, 78, 87, - 73, 128, 78, 87, 69, 128, 78, 87, 65, 65, 128, 78, 87, 65, 128, 78, 87, - 128, 78, 86, 128, 78, 85, 88, 128, 78, 85, 85, 78, 128, 78, 85, 85, 128, - 78, 85, 84, 73, 76, 76, 85, 128, 78, 85, 84, 128, 78, 85, 212, 78, 85, - 82, 88, 128, 78, 85, 82, 128, 78, 85, 80, 128, 78, 85, 79, 88, 128, 78, - 85, 79, 80, 128, 78, 85, 79, 128, 78, 85, 78, 85, 90, 128, 78, 85, 78, - 85, 218, 78, 85, 78, 71, 128, 78, 85, 78, 65, 86, 85, 212, 78, 85, 78, - 65, 86, 73, 203, 78, 85, 78, 128, 78, 85, 206, 78, 85, 77, 69, 82, 207, - 78, 85, 77, 69, 82, 65, 84, 79, 210, 78, 85, 77, 69, 82, 65, 204, 78, 85, - 77, 66, 69, 82, 83, 128, 78, 85, 77, 66, 69, 82, 128, 78, 85, 77, 128, - 78, 85, 76, 76, 128, 78, 85, 76, 204, 78, 85, 76, 128, 78, 85, 75, 84, - 65, 128, 78, 85, 75, 84, 193, 78, 85, 69, 78, 71, 128, 78, 85, 69, 128, - 78, 85, 66, 73, 65, 206, 78, 85, 65, 69, 128, 78, 85, 49, 49, 128, 78, - 85, 49, 177, 78, 85, 48, 50, 50, 65, 128, 78, 85, 48, 50, 50, 128, 78, - 85, 48, 50, 49, 128, 78, 85, 48, 50, 48, 128, 78, 85, 48, 49, 57, 128, - 78, 85, 48, 49, 56, 65, 128, 78, 85, 48, 49, 56, 128, 78, 85, 48, 49, 55, - 128, 78, 85, 48, 49, 54, 128, 78, 85, 48, 49, 53, 128, 78, 85, 48, 49, - 52, 128, 78, 85, 48, 49, 51, 128, 78, 85, 48, 49, 50, 128, 78, 85, 48, - 49, 49, 65, 128, 78, 85, 48, 49, 49, 128, 78, 85, 48, 49, 48, 65, 128, - 78, 85, 48, 49, 48, 128, 78, 85, 48, 48, 57, 128, 78, 85, 48, 48, 56, - 128, 78, 85, 48, 48, 55, 128, 78, 85, 48, 48, 54, 128, 78, 85, 48, 48, - 53, 128, 78, 85, 48, 48, 52, 128, 78, 85, 48, 48, 51, 128, 78, 85, 48, - 48, 50, 128, 78, 85, 48, 48, 49, 128, 78, 85, 45, 51, 128, 78, 85, 45, - 50, 128, 78, 85, 45, 49, 128, 78, 84, 88, 73, 86, 128, 78, 84, 88, 65, - 128, 78, 84, 85, 85, 128, 78, 84, 85, 77, 128, 78, 84, 85, 74, 128, 78, - 84, 213, 78, 84, 83, 65, 85, 128, 78, 84, 83, 65, 128, 78, 84, 79, 81, - 80, 69, 78, 128, 78, 84, 79, 71, 128, 78, 84, 79, 199, 78, 84, 73, 69, - 197, 78, 84, 72, 65, 85, 128, 78, 84, 69, 85, 78, 71, 66, 65, 128, 78, - 84, 69, 85, 77, 128, 78, 84, 69, 78, 128, 78, 84, 69, 69, 128, 78, 84, - 65, 80, 128, 78, 84, 65, 208, 78, 84, 65, 65, 128, 78, 84, 65, 128, 78, - 83, 85, 79, 212, 78, 83, 85, 78, 128, 78, 83, 85, 77, 128, 78, 83, 79, - 77, 128, 78, 83, 73, 69, 69, 84, 128, 78, 83, 73, 69, 69, 80, 128, 78, - 83, 73, 69, 69, 128, 78, 83, 72, 85, 84, 128, 78, 83, 72, 85, 212, 78, - 83, 72, 85, 79, 80, 128, 78, 83, 72, 85, 69, 128, 78, 83, 72, 73, 69, 69, - 128, 78, 83, 72, 69, 69, 128, 78, 83, 72, 65, 81, 128, 78, 83, 72, 65, - 128, 78, 83, 69, 85, 65, 69, 78, 128, 78, 83, 69, 78, 128, 78, 83, 65, - 128, 78, 82, 89, 88, 128, 78, 82, 89, 84, 128, 78, 82, 89, 82, 88, 128, - 78, 82, 89, 82, 128, 78, 82, 89, 80, 128, 78, 82, 89, 128, 78, 82, 85, - 88, 128, 78, 82, 85, 84, 128, 78, 82, 85, 82, 88, 128, 78, 82, 85, 82, - 128, 78, 82, 85, 80, 128, 78, 82, 85, 65, 128, 78, 82, 85, 128, 78, 82, - 79, 88, 128, 78, 82, 79, 80, 128, 78, 82, 79, 128, 78, 82, 69, 88, 128, - 78, 82, 69, 84, 128, 78, 82, 69, 211, 78, 82, 69, 80, 128, 78, 82, 69, - 128, 78, 82, 65, 88, 128, 78, 82, 65, 84, 128, 78, 82, 65, 80, 128, 78, - 82, 65, 128, 78, 81, 73, 71, 128, 78, 81, 65, 128, 78, 80, 76, 65, 128, - 78, 80, 65, 128, 78, 79, 90, 72, 75, 65, 128, 78, 79, 89, 128, 78, 79, - 88, 128, 78, 79, 87, 67, 128, 78, 79, 86, 73, 76, 69, 128, 78, 79, 86, - 69, 77, 66, 69, 82, 128, 78, 79, 84, 84, 79, 128, 78, 79, 84, 69, 83, - 128, 78, 79, 84, 69, 72, 69, 65, 68, 128, 78, 79, 84, 69, 72, 69, 65, - 196, 78, 79, 84, 69, 66, 79, 79, 75, 128, 78, 79, 84, 69, 66, 79, 79, - 203, 78, 79, 84, 69, 128, 78, 79, 84, 197, 78, 79, 84, 67, 72, 69, 196, - 78, 79, 84, 67, 72, 128, 78, 79, 84, 65, 84, 73, 79, 206, 78, 79, 84, - 128, 78, 79, 212, 78, 79, 83, 69, 128, 78, 79, 83, 197, 78, 79, 82, 84, - 72, 87, 69, 83, 212, 78, 79, 82, 84, 72, 69, 82, 206, 78, 79, 82, 84, 72, - 69, 65, 83, 84, 45, 80, 79, 73, 78, 84, 73, 78, 199, 78, 79, 82, 77, 65, - 204, 78, 79, 82, 68, 73, 195, 78, 79, 210, 78, 79, 80, 128, 78, 79, 79, - 78, 85, 128, 78, 79, 79, 128, 78, 79, 78, 70, 79, 82, 75, 73, 78, 71, - 128, 78, 79, 78, 45, 80, 79, 84, 65, 66, 76, 197, 78, 79, 78, 45, 74, 79, - 73, 78, 69, 82, 128, 78, 79, 78, 45, 66, 82, 69, 65, 75, 73, 78, 199, 78, - 79, 78, 128, 78, 79, 77, 73, 83, 77, 193, 78, 79, 77, 73, 78, 65, 204, - 78, 79, 75, 72, 85, 75, 128, 78, 79, 68, 69, 128, 78, 79, 65, 128, 78, - 79, 45, 66, 82, 69, 65, 203, 78, 79, 45, 53, 128, 78, 79, 45, 52, 128, - 78, 79, 45, 51, 128, 78, 79, 45, 50, 128, 78, 79, 45, 49, 128, 78, 78, - 85, 85, 128, 78, 78, 85, 128, 78, 78, 79, 79, 128, 78, 78, 78, 85, 85, - 128, 78, 78, 78, 85, 128, 78, 78, 78, 79, 79, 128, 78, 78, 78, 79, 128, - 78, 78, 78, 73, 73, 128, 78, 78, 78, 73, 128, 78, 78, 78, 69, 69, 128, - 78, 78, 78, 69, 128, 78, 78, 78, 65, 85, 128, 78, 78, 78, 65, 73, 128, - 78, 78, 78, 65, 65, 128, 78, 78, 78, 65, 128, 78, 78, 78, 128, 78, 78, - 72, 65, 128, 78, 78, 71, 79, 79, 128, 78, 78, 71, 79, 128, 78, 78, 71, - 73, 73, 128, 78, 78, 71, 73, 128, 78, 78, 71, 65, 65, 128, 78, 78, 71, - 65, 128, 78, 78, 71, 128, 78, 78, 66, 83, 80, 128, 78, 77, 128, 78, 76, - 65, 85, 128, 78, 76, 48, 50, 48, 128, 78, 76, 48, 49, 57, 128, 78, 76, - 48, 49, 56, 128, 78, 76, 48, 49, 55, 65, 128, 78, 76, 48, 49, 55, 128, - 78, 76, 48, 49, 54, 128, 78, 76, 48, 49, 53, 128, 78, 76, 48, 49, 52, - 128, 78, 76, 48, 49, 51, 128, 78, 76, 48, 49, 50, 128, 78, 76, 48, 49, - 49, 128, 78, 76, 48, 49, 48, 128, 78, 76, 48, 48, 57, 128, 78, 76, 48, - 48, 56, 128, 78, 76, 48, 48, 55, 128, 78, 76, 48, 48, 54, 128, 78, 76, - 48, 48, 53, 65, 128, 78, 76, 48, 48, 53, 128, 78, 76, 48, 48, 52, 128, - 78, 76, 48, 48, 51, 128, 78, 76, 48, 48, 50, 128, 78, 76, 48, 48, 49, - 128, 78, 76, 128, 78, 75, 79, 77, 128, 78, 75, 207, 78, 75, 73, 78, 68, - 73, 128, 78, 75, 65, 85, 128, 78, 75, 65, 65, 82, 65, 69, 128, 78, 75, - 65, 128, 78, 74, 89, 88, 128, 78, 74, 89, 84, 128, 78, 74, 89, 82, 88, - 128, 78, 74, 89, 82, 128, 78, 74, 89, 80, 128, 78, 74, 89, 128, 78, 74, - 85, 88, 128, 78, 74, 85, 82, 88, 128, 78, 74, 85, 82, 128, 78, 74, 85, - 81, 65, 128, 78, 74, 85, 80, 128, 78, 74, 85, 79, 88, 128, 78, 74, 85, - 79, 128, 78, 74, 85, 69, 81, 128, 78, 74, 85, 65, 69, 128, 78, 74, 85, - 128, 78, 74, 79, 88, 128, 78, 74, 79, 84, 128, 78, 74, 79, 80, 128, 78, - 74, 79, 79, 128, 78, 74, 79, 128, 78, 74, 73, 88, 128, 78, 74, 73, 84, - 128, 78, 74, 73, 80, 128, 78, 74, 73, 69, 88, 128, 78, 74, 73, 69, 84, - 128, 78, 74, 73, 69, 80, 128, 78, 74, 73, 69, 69, 128, 78, 74, 73, 69, - 128, 78, 74, 73, 128, 78, 74, 201, 78, 74, 69, 85, 88, 128, 78, 74, 69, - 85, 84, 128, 78, 74, 69, 85, 65, 69, 78, 65, 128, 78, 74, 69, 85, 65, 69, - 77, 128, 78, 74, 69, 69, 69, 69, 128, 78, 74, 69, 69, 128, 78, 74, 69, - 197, 78, 74, 69, 128, 78, 74, 65, 81, 128, 78, 74, 65, 80, 128, 78, 74, - 65, 69, 77, 76, 73, 128, 78, 74, 65, 69, 77, 128, 78, 74, 65, 65, 128, - 78, 73, 90, 75, 207, 78, 73, 88, 128, 78, 73, 84, 82, 69, 128, 78, 73, - 83, 65, 71, 128, 78, 73, 82, 85, 71, 85, 128, 78, 73, 80, 128, 78, 73, - 78, 84, 72, 128, 78, 73, 78, 74, 65, 128, 78, 73, 78, 69, 84, 89, 128, - 78, 73, 78, 69, 84, 217, 78, 73, 78, 69, 84, 69, 69, 78, 128, 78, 73, 78, - 69, 84, 69, 69, 206, 78, 73, 78, 69, 45, 84, 72, 73, 82, 84, 89, 128, 78, - 73, 78, 197, 78, 73, 78, 68, 65, 50, 128, 78, 73, 78, 68, 65, 178, 78, - 73, 78, 57, 128, 78, 73, 78, 128, 78, 73, 77, 128, 78, 73, 205, 78, 73, - 75, 79, 76, 83, 66, 85, 82, 199, 78, 73, 75, 72, 65, 72, 73, 84, 128, 78, - 73, 75, 65, 72, 73, 84, 128, 78, 73, 75, 65, 128, 78, 73, 72, 83, 72, 86, - 65, 83, 65, 128, 78, 73, 71, 73, 68, 65, 77, 73, 78, 128, 78, 73, 71, 73, - 68, 65, 69, 83, 72, 128, 78, 73, 71, 72, 84, 128, 78, 73, 71, 72, 212, - 78, 73, 71, 71, 65, 72, 73, 84, 65, 128, 78, 73, 69, 88, 128, 78, 73, 69, - 85, 78, 45, 84, 73, 75, 69, 85, 84, 128, 78, 73, 69, 85, 78, 45, 84, 72, - 73, 69, 85, 84, 72, 128, 78, 73, 69, 85, 78, 45, 83, 73, 79, 83, 128, 78, - 73, 69, 85, 78, 45, 82, 73, 69, 85, 76, 128, 78, 73, 69, 85, 78, 45, 80, - 73, 69, 85, 80, 128, 78, 73, 69, 85, 78, 45, 80, 65, 78, 83, 73, 79, 83, - 128, 78, 73, 69, 85, 78, 45, 75, 73, 89, 69, 79, 75, 128, 78, 73, 69, 85, - 78, 45, 72, 73, 69, 85, 72, 128, 78, 73, 69, 85, 78, 45, 67, 73, 69, 85, - 67, 128, 78, 73, 69, 85, 78, 45, 67, 72, 73, 69, 85, 67, 72, 128, 78, 73, - 69, 85, 206, 78, 73, 69, 80, 128, 78, 73, 69, 128, 78, 73, 66, 128, 78, - 73, 65, 128, 78, 73, 50, 128, 78, 73, 45, 84, 69, 128, 78, 73, 45, 55, - 128, 78, 73, 45, 54, 128, 78, 73, 45, 53, 128, 78, 73, 45, 52, 128, 78, - 73, 45, 51, 128, 78, 73, 45, 50, 128, 78, 73, 45, 49, 128, 78, 72, 85, - 69, 128, 78, 72, 74, 65, 128, 78, 72, 65, 89, 128, 78, 72, 128, 78, 71, - 89, 69, 128, 78, 71, 86, 69, 128, 78, 71, 85, 85, 128, 78, 71, 85, 79, - 88, 128, 78, 71, 85, 79, 84, 128, 78, 71, 85, 79, 128, 78, 71, 85, 65, - 78, 128, 78, 71, 85, 65, 69, 84, 128, 78, 71, 85, 65, 69, 128, 78, 71, - 79, 88, 128, 78, 71, 79, 85, 128, 78, 71, 79, 213, 78, 71, 79, 84, 128, - 78, 71, 79, 81, 128, 78, 71, 79, 80, 128, 78, 71, 79, 78, 128, 78, 71, - 79, 77, 128, 78, 71, 79, 69, 72, 128, 78, 71, 79, 69, 200, 78, 71, 207, - 78, 71, 75, 89, 69, 69, 128, 78, 71, 75, 87, 65, 69, 78, 128, 78, 71, 75, - 85, 80, 128, 78, 71, 75, 85, 78, 128, 78, 71, 75, 85, 77, 128, 78, 71, - 75, 85, 69, 78, 90, 69, 85, 77, 128, 78, 71, 75, 85, 197, 78, 71, 75, 73, - 78, 68, 201, 78, 71, 75, 73, 69, 69, 128, 78, 71, 75, 69, 85, 88, 128, - 78, 71, 75, 69, 85, 82, 73, 128, 78, 71, 75, 69, 85, 65, 69, 81, 128, 78, - 71, 75, 69, 85, 65, 69, 77, 128, 78, 71, 75, 65, 81, 128, 78, 71, 75, 65, - 80, 128, 78, 71, 75, 65, 65, 77, 73, 128, 78, 71, 75, 65, 128, 78, 71, - 73, 69, 88, 128, 78, 71, 73, 69, 80, 128, 78, 71, 73, 69, 128, 78, 71, - 72, 65, 128, 78, 71, 71, 87, 65, 69, 78, 128, 78, 71, 71, 85, 82, 65, 69, - 128, 78, 71, 71, 85, 80, 128, 78, 71, 71, 85, 79, 81, 128, 78, 71, 71, - 85, 79, 209, 78, 71, 71, 85, 79, 78, 128, 78, 71, 71, 85, 79, 77, 128, - 78, 71, 71, 85, 77, 128, 78, 71, 71, 85, 69, 69, 84, 128, 78, 71, 71, 85, - 65, 69, 83, 72, 65, 197, 78, 71, 71, 85, 65, 69, 206, 78, 71, 71, 85, 65, - 128, 78, 71, 71, 85, 128, 78, 71, 71, 79, 79, 128, 78, 71, 71, 79, 128, - 78, 71, 71, 73, 128, 78, 71, 71, 69, 85, 88, 128, 78, 71, 71, 69, 85, 65, - 69, 84, 128, 78, 71, 71, 69, 85, 65, 69, 128, 78, 71, 71, 69, 213, 78, - 71, 71, 69, 78, 128, 78, 71, 71, 69, 69, 84, 128, 78, 71, 71, 69, 69, 69, - 69, 128, 78, 71, 71, 69, 69, 128, 78, 71, 71, 69, 128, 78, 71, 71, 65, - 80, 128, 78, 71, 71, 65, 65, 77, 65, 69, 128, 78, 71, 71, 65, 65, 77, - 128, 78, 71, 71, 65, 65, 128, 78, 71, 71, 128, 78, 71, 69, 88, 128, 78, - 71, 69, 85, 82, 69, 85, 84, 128, 78, 71, 69, 80, 128, 78, 71, 69, 78, - 128, 78, 71, 69, 69, 128, 78, 71, 69, 65, 68, 65, 76, 128, 78, 71, 65, - 88, 128, 78, 71, 65, 85, 128, 78, 71, 65, 84, 128, 78, 71, 65, 211, 78, - 71, 65, 81, 128, 78, 71, 65, 80, 128, 78, 71, 65, 78, 71, 85, 128, 78, - 71, 65, 78, 128, 78, 71, 65, 73, 128, 78, 71, 65, 72, 128, 78, 71, 65, - 65, 73, 128, 78, 71, 193, 78, 70, 128, 78, 69, 88, 212, 78, 69, 88, 128, - 78, 69, 87, 83, 80, 65, 80, 69, 82, 128, 78, 69, 87, 76, 73, 78, 69, 128, - 78, 69, 87, 76, 73, 78, 197, 78, 69, 87, 193, 78, 69, 87, 128, 78, 69, - 215, 78, 69, 85, 84, 82, 65, 76, 128, 78, 69, 85, 84, 82, 65, 204, 78, - 69, 85, 84, 69, 82, 128, 78, 69, 84, 87, 79, 82, 75, 69, 196, 78, 69, - 212, 78, 69, 83, 84, 73, 78, 199, 78, 69, 83, 84, 69, 196, 78, 69, 83, - 84, 128, 78, 69, 83, 212, 78, 69, 83, 83, 85, 83, 128, 78, 69, 82, 196, - 78, 69, 81, 85, 68, 65, 65, 128, 78, 69, 80, 84, 85, 78, 69, 128, 78, 69, - 80, 84, 85, 78, 197, 78, 69, 80, 79, 83, 84, 79, 89, 65, 78, 78, 65, 89, - 65, 128, 78, 69, 80, 128, 78, 69, 79, 128, 78, 69, 207, 78, 69, 78, 79, - 69, 128, 78, 69, 78, 65, 78, 79, 128, 78, 69, 78, 128, 78, 69, 77, 75, - 65, 128, 78, 69, 76, 128, 78, 69, 73, 84, 72, 69, 210, 78, 69, 71, 65, - 84, 73, 86, 197, 78, 69, 71, 65, 84, 73, 79, 206, 78, 69, 71, 65, 84, 69, - 196, 78, 69, 69, 68, 76, 69, 128, 78, 69, 67, 75, 84, 73, 69, 128, 78, - 69, 67, 75, 128, 78, 69, 66, 69, 78, 83, 84, 73, 77, 77, 69, 128, 78, 69, - 45, 75, 79, 128, 78, 68, 85, 88, 128, 78, 68, 85, 84, 128, 78, 68, 85, - 82, 88, 128, 78, 68, 85, 82, 128, 78, 68, 85, 80, 128, 78, 68, 85, 78, - 128, 78, 68, 213, 78, 68, 79, 88, 128, 78, 68, 79, 84, 128, 78, 68, 79, - 80, 128, 78, 68, 79, 79, 128, 78, 68, 79, 78, 128, 78, 68, 79, 77, 66, - 85, 128, 78, 68, 79, 76, 197, 78, 68, 73, 88, 128, 78, 68, 73, 84, 128, - 78, 68, 73, 81, 128, 78, 68, 73, 80, 128, 78, 68, 73, 69, 88, 128, 78, - 68, 73, 69, 128, 78, 68, 73, 68, 65, 128, 78, 68, 73, 65, 81, 128, 78, - 68, 69, 88, 128, 78, 68, 69, 85, 88, 128, 78, 68, 69, 85, 84, 128, 78, - 68, 69, 85, 65, 69, 82, 69, 69, 128, 78, 68, 69, 80, 128, 78, 68, 69, 69, - 128, 78, 68, 69, 128, 78, 68, 65, 88, 128, 78, 68, 65, 84, 128, 78, 68, - 65, 80, 128, 78, 68, 65, 77, 128, 78, 68, 65, 65, 78, 71, 71, 69, 85, 65, - 69, 84, 128, 78, 68, 65, 65, 128, 78, 68, 65, 193, 78, 67, 72, 65, 85, - 128, 78, 67, 65, 128, 78, 66, 89, 88, 128, 78, 66, 89, 84, 128, 78, 66, - 89, 82, 88, 128, 78, 66, 89, 82, 128, 78, 66, 89, 80, 128, 78, 66, 89, - 128, 78, 66, 85, 88, 128, 78, 66, 85, 84, 128, 78, 66, 85, 82, 88, 128, - 78, 66, 85, 82, 128, 78, 66, 85, 80, 128, 78, 66, 85, 128, 78, 66, 79, - 88, 128, 78, 66, 79, 84, 128, 78, 66, 79, 80, 128, 78, 66, 79, 128, 78, - 66, 73, 88, 128, 78, 66, 73, 84, 128, 78, 66, 73, 80, 128, 78, 66, 73, - 69, 88, 128, 78, 66, 73, 69, 80, 128, 78, 66, 73, 69, 128, 78, 66, 73, - 128, 78, 66, 72, 128, 78, 66, 65, 88, 128, 78, 66, 65, 84, 128, 78, 66, - 65, 80, 128, 78, 66, 65, 128, 78, 65, 90, 65, 210, 78, 65, 89, 65, 78, - 78, 65, 128, 78, 65, 89, 128, 78, 65, 88, 73, 65, 206, 78, 65, 88, 128, - 78, 65, 85, 84, 72, 83, 128, 78, 65, 85, 83, 69, 65, 84, 69, 196, 78, 65, - 85, 68, 73, 218, 78, 65, 84, 85, 82, 65, 204, 78, 65, 84, 84, 73, 76, 73, - 203, 78, 65, 84, 73, 79, 78, 65, 204, 78, 65, 83, 75, 65, 80, 201, 78, - 65, 83, 72, 73, 128, 78, 65, 83, 65, 76, 73, 90, 69, 196, 78, 65, 83, 65, - 76, 73, 90, 65, 84, 73, 79, 78, 128, 78, 65, 83, 65, 76, 73, 90, 65, 84, - 73, 79, 206, 78, 65, 83, 65, 204, 78, 65, 82, 82, 79, 215, 78, 65, 82, - 128, 78, 65, 81, 128, 78, 65, 79, 211, 78, 65, 78, 83, 65, 78, 65, 81, - 128, 78, 65, 78, 71, 77, 79, 78, 84, 72, 79, 128, 78, 65, 78, 68, 73, 78, - 65, 71, 65, 82, 201, 78, 65, 78, 68, 128, 78, 65, 78, 65, 128, 78, 65, - 77, 69, 128, 78, 65, 77, 197, 78, 65, 77, 50, 128, 78, 65, 75, 65, 65, - 82, 193, 78, 65, 75, 128, 78, 65, 73, 82, 193, 78, 65, 73, 204, 78, 65, - 71, 82, 201, 78, 65, 71, 65, 82, 128, 78, 65, 71, 65, 128, 78, 65, 71, - 193, 78, 65, 71, 128, 78, 65, 199, 78, 65, 69, 128, 78, 65, 66, 76, 65, - 128, 78, 65, 66, 65, 84, 65, 69, 65, 206, 78, 65, 65, 83, 73, 75, 89, 65, - 89, 65, 128, 78, 65, 65, 75, 83, 73, 75, 89, 65, 89, 65, 128, 78, 65, 65, - 73, 128, 78, 65, 193, 78, 65, 52, 128, 78, 65, 50, 128, 78, 65, 45, 57, - 128, 78, 65, 45, 56, 128, 78, 65, 45, 55, 128, 78, 65, 45, 54, 128, 78, - 65, 45, 53, 128, 78, 65, 45, 52, 128, 78, 65, 45, 51, 128, 78, 65, 45, - 50, 128, 78, 65, 45, 49, 128, 78, 48, 52, 50, 128, 78, 48, 52, 49, 128, - 78, 48, 52, 48, 128, 78, 48, 51, 57, 128, 78, 48, 51, 56, 128, 78, 48, - 51, 55, 65, 128, 78, 48, 51, 55, 128, 78, 48, 51, 54, 128, 78, 48, 51, - 53, 65, 128, 78, 48, 51, 53, 128, 78, 48, 51, 52, 65, 128, 78, 48, 51, - 52, 128, 78, 48, 51, 51, 65, 128, 78, 48, 51, 51, 128, 78, 48, 51, 50, - 128, 78, 48, 51, 49, 128, 78, 48, 51, 48, 128, 78, 48, 50, 57, 128, 78, - 48, 50, 56, 128, 78, 48, 50, 55, 128, 78, 48, 50, 54, 128, 78, 48, 50, - 53, 65, 128, 78, 48, 50, 53, 128, 78, 48, 50, 52, 128, 78, 48, 50, 51, - 128, 78, 48, 50, 50, 128, 78, 48, 50, 49, 128, 78, 48, 50, 48, 128, 78, - 48, 49, 57, 128, 78, 48, 49, 56, 66, 128, 78, 48, 49, 56, 65, 128, 78, - 48, 49, 56, 128, 78, 48, 49, 55, 128, 78, 48, 49, 54, 128, 78, 48, 49, - 53, 128, 78, 48, 49, 52, 128, 78, 48, 49, 51, 128, 78, 48, 49, 50, 128, - 78, 48, 49, 49, 128, 78, 48, 49, 48, 128, 78, 48, 48, 57, 128, 78, 48, - 48, 56, 128, 78, 48, 48, 55, 128, 78, 48, 48, 54, 128, 78, 48, 48, 53, - 128, 78, 48, 48, 52, 128, 78, 48, 48, 51, 128, 78, 48, 48, 50, 128, 78, - 48, 48, 49, 128, 78, 45, 77, 85, 45, 77, 79, 45, 50, 128, 78, 45, 77, 85, - 45, 77, 79, 45, 49, 128, 78, 45, 67, 82, 69, 197, 78, 45, 65, 82, 217, - 77, 90, 128, 77, 89, 88, 128, 77, 89, 84, 128, 77, 89, 83, 76, 73, 84, - 69, 128, 77, 89, 80, 128, 77, 89, 65, 128, 77, 89, 193, 77, 87, 79, 79, - 128, 77, 87, 79, 128, 77, 87, 73, 73, 128, 77, 87, 73, 128, 77, 87, 69, - 69, 128, 77, 87, 69, 128, 77, 87, 65, 65, 128, 77, 87, 65, 128, 77, 87, - 128, 77, 215, 77, 86, 83, 128, 77, 86, 79, 80, 128, 77, 86, 73, 128, 77, - 86, 69, 85, 65, 69, 78, 71, 65, 77, 128, 77, 86, 128, 77, 214, 77, 85, - 88, 128, 77, 85, 85, 86, 85, 90, 72, 65, 75, 75, 85, 128, 77, 85, 85, 83, - 73, 75, 65, 84, 79, 65, 78, 128, 77, 85, 85, 82, 68, 72, 65, 74, 193, 77, - 85, 85, 128, 77, 85, 84, 72, 65, 76, 73, 89, 65, 128, 77, 85, 84, 128, - 77, 85, 83, 73, 67, 128, 77, 85, 83, 73, 195, 77, 85, 83, 72, 82, 79, 79, - 77, 128, 77, 85, 83, 72, 51, 128, 77, 85, 83, 72, 179, 77, 85, 83, 72, - 128, 77, 85, 83, 200, 77, 85, 83, 128, 77, 85, 82, 88, 128, 77, 85, 82, - 71, 85, 50, 128, 77, 85, 82, 69, 128, 77, 85, 82, 68, 65, 128, 77, 85, - 82, 68, 193, 77, 85, 82, 128, 77, 85, 81, 68, 65, 77, 128, 77, 85, 80, - 128, 77, 85, 79, 88, 128, 77, 85, 79, 84, 128, 77, 85, 79, 80, 128, 77, - 85, 79, 77, 65, 69, 128, 77, 85, 79, 128, 77, 85, 78, 83, 85, 66, 128, - 77, 85, 78, 65, 72, 128, 77, 85, 78, 128, 77, 85, 76, 84, 73, 83, 69, 84, + 67, 197, 80, 69, 193, 80, 68, 73, 128, 80, 68, 70, 128, 80, 68, 128, 80, + 67, 128, 80, 65, 90, 69, 82, 128, 80, 65, 89, 69, 82, 79, 75, 128, 80, + 65, 89, 65, 78, 78, 65, 128, 80, 65, 89, 128, 80, 65, 88, 128, 80, 65, + 87, 78, 128, 80, 65, 87, 206, 80, 65, 215, 80, 65, 86, 73, 89, 65, 78, + 73, 128, 80, 65, 85, 83, 197, 80, 65, 85, 75, 128, 80, 65, 85, 128, 80, + 65, 213, 80, 65, 84, 84, 217, 80, 65, 84, 84, 69, 82, 78, 128, 80, 65, + 84, 72, 65, 77, 65, 83, 65, 84, 128, 80, 65, 84, 72, 65, 75, 75, 85, 128, + 80, 65, 84, 200, 80, 65, 84, 65, 75, 128, 80, 65, 84, 65, 72, 128, 80, + 65, 84, 128, 80, 65, 83, 85, 81, 128, 80, 65, 83, 83, 80, 79, 82, 212, + 80, 65, 83, 83, 73, 86, 69, 45, 80, 85, 76, 76, 45, 85, 80, 45, 79, 85, + 84, 80, 85, 212, 80, 65, 83, 83, 73, 86, 69, 45, 80, 85, 76, 76, 45, 68, + 79, 87, 78, 45, 79, 85, 84, 80, 85, 212, 80, 65, 83, 83, 73, 77, 66, 65, + 78, 71, 128, 80, 65, 83, 83, 69, 78, 71, 69, 210, 80, 65, 83, 83, 69, + 196, 80, 65, 83, 72, 84, 65, 128, 80, 65, 83, 72, 65, 69, 128, 80, 65, + 83, 69, 81, 128, 80, 65, 83, 65, 78, 71, 65, 206, 80, 65, 82, 85, 77, + 128, 80, 65, 82, 84, 217, 80, 65, 82, 84, 78, 69, 82, 83, 72, 73, 208, + 80, 65, 82, 84, 73, 65, 76, 76, 89, 45, 82, 69, 67, 89, 67, 76, 69, 196, + 80, 65, 82, 84, 73, 65, 204, 80, 65, 82, 84, 72, 73, 65, 206, 80, 65, 82, + 212, 80, 65, 82, 82, 79, 84, 128, 80, 65, 82, 75, 128, 80, 65, 82, 73, + 67, 72, 79, 78, 128, 80, 65, 82, 69, 83, 84, 73, 71, 77, 69, 78, 79, 206, + 80, 65, 82, 69, 82, 69, 78, 128, 80, 65, 82, 69, 78, 84, 72, 69, 83, 73, + 83, 128, 80, 65, 82, 69, 78, 84, 72, 69, 83, 73, 211, 80, 65, 82, 69, 78, + 84, 72, 69, 83, 69, 211, 80, 65, 82, 65, 80, 72, 82, 65, 83, 197, 80, 65, + 82, 65, 76, 76, 69, 76, 79, 71, 82, 65, 77, 128, 80, 65, 82, 65, 76, 76, + 69, 76, 128, 80, 65, 82, 65, 76, 76, 69, 204, 80, 65, 82, 65, 75, 76, 73, + 84, 73, 75, 73, 128, 80, 65, 82, 65, 75, 76, 73, 84, 73, 75, 201, 80, 65, + 82, 65, 75, 76, 73, 84, 128, 80, 65, 82, 65, 75, 65, 76, 69, 83, 77, 193, + 80, 65, 82, 65, 71, 82, 65, 80, 72, 85, 211, 80, 65, 82, 65, 71, 82, 65, + 80, 72, 79, 83, 128, 80, 65, 82, 65, 71, 82, 65, 80, 72, 128, 80, 65, 82, + 65, 71, 82, 65, 80, 200, 80, 65, 82, 65, 67, 72, 85, 84, 69, 128, 80, 65, + 82, 65, 128, 80, 65, 82, 128, 80, 65, 80, 89, 82, 85, 83, 128, 80, 65, + 80, 69, 82, 67, 76, 73, 80, 83, 128, 80, 65, 80, 69, 82, 67, 76, 73, 80, + 128, 80, 65, 80, 69, 82, 128, 80, 65, 80, 69, 210, 80, 65, 80, 128, 80, + 65, 208, 80, 65, 207, 80, 65, 78, 89, 85, 75, 85, 128, 80, 65, 78, 89, + 73, 75, 85, 128, 80, 65, 78, 89, 69, 67, 69, 75, 128, 80, 65, 78, 89, 65, + 78, 71, 71, 65, 128, 80, 65, 78, 89, 65, 75, 82, 65, 128, 80, 65, 78, 84, + 73, 128, 80, 65, 78, 84, 201, 80, 65, 78, 83, 73, 79, 83, 45, 80, 73, 69, + 85, 80, 128, 80, 65, 78, 83, 73, 79, 83, 45, 75, 65, 80, 89, 69, 79, 85, + 78, 80, 73, 69, 85, 80, 128, 80, 65, 78, 79, 78, 71, 79, 78, 65, 78, 128, + 80, 65, 78, 79, 76, 79, 78, 71, 128, 80, 65, 78, 71, 87, 73, 83, 65, 68, + 128, 80, 65, 78, 71, 82, 65, 78, 71, 75, 69, 80, 128, 80, 65, 78, 71, 79, + 76, 65, 84, 128, 80, 65, 78, 71, 76, 79, 78, 71, 128, 80, 65, 78, 71, 76, + 65, 89, 65, 82, 128, 80, 65, 78, 71, 75, 79, 78, 128, 80, 65, 78, 71, 75, + 65, 84, 128, 80, 65, 78, 71, 72, 85, 76, 85, 128, 80, 65, 78, 71, 128, + 80, 65, 78, 69, 85, 76, 69, 85, 78, 71, 128, 80, 65, 78, 68, 193, 80, 65, + 78, 67, 65, 75, 69, 83, 128, 80, 65, 78, 65, 77, 128, 80, 65, 78, 65, 69, + 76, 65, 69, 78, 71, 128, 80, 65, 78, 128, 80, 65, 206, 80, 65, 77, 85, + 78, 71, 75, 65, 72, 128, 80, 65, 77, 85, 68, 80, 79, 68, 128, 80, 65, 77, + 83, 72, 65, 69, 128, 80, 65, 77, 80, 72, 89, 76, 73, 65, 206, 80, 65, 77, + 73, 78, 71, 75, 65, 76, 128, 80, 65, 77, 69, 80, 69, 84, 128, 80, 65, 77, + 69, 78, 69, 78, 71, 128, 80, 65, 77, 65, 68, 65, 128, 80, 65, 77, 65, 68, + 193, 80, 65, 77, 65, 65, 69, 72, 128, 80, 65, 76, 85, 84, 65, 128, 80, + 65, 76, 79, 67, 72, 75, 65, 128, 80, 65, 76, 77, 89, 82, 69, 78, 197, 80, + 65, 76, 77, 211, 80, 65, 76, 77, 128, 80, 65, 76, 205, 80, 65, 76, 76, + 65, 87, 65, 128, 80, 65, 76, 76, 65, 83, 128, 80, 65, 76, 75, 65, 128, + 80, 65, 76, 201, 80, 65, 76, 69, 84, 84, 69, 128, 80, 65, 76, 65, 85, 78, + 199, 80, 65, 76, 65, 84, 65, 76, 73, 90, 69, 196, 80, 65, 76, 65, 84, 65, + 76, 73, 90, 65, 84, 73, 79, 78, 128, 80, 65, 76, 65, 84, 65, 204, 80, 65, + 75, 80, 65, 203, 80, 65, 73, 89, 65, 78, 78, 79, 73, 128, 80, 65, 73, 82, + 84, 72, 82, 65, 128, 80, 65, 73, 82, 69, 196, 80, 65, 73, 78, 84, 66, 82, + 85, 83, 72, 128, 80, 65, 73, 128, 80, 65, 72, 76, 65, 86, 201, 80, 65, + 72, 128, 80, 65, 71, 79, 68, 65, 128, 80, 65, 71, 69, 83, 128, 80, 65, + 71, 69, 82, 128, 80, 65, 71, 197, 80, 65, 68, 77, 193, 80, 65, 68, 68, + 76, 197, 80, 65, 68, 68, 73, 78, 199, 80, 65, 68, 193, 80, 65, 68, 128, + 80, 65, 67, 75, 73, 78, 71, 128, 80, 65, 67, 75, 65, 71, 69, 128, 80, 65, + 65, 84, 85, 128, 80, 65, 65, 83, 69, 78, 84, 79, 128, 80, 65, 65, 82, 65, + 77, 128, 80, 65, 65, 82, 65, 69, 128, 80, 65, 65, 77, 128, 80, 65, 65, + 73, 128, 80, 65, 65, 45, 80, 73, 76, 76, 65, 128, 80, 65, 65, 128, 80, + 50, 128, 80, 48, 49, 49, 128, 80, 48, 49, 48, 128, 80, 48, 48, 57, 128, + 80, 48, 48, 56, 128, 80, 48, 48, 55, 128, 80, 48, 48, 54, 128, 80, 48, + 48, 53, 128, 80, 48, 48, 52, 128, 80, 48, 48, 51, 65, 128, 80, 48, 48, + 51, 128, 80, 48, 48, 50, 128, 80, 48, 48, 49, 65, 128, 80, 48, 48, 49, + 128, 79, 90, 128, 79, 89, 83, 84, 69, 82, 128, 79, 89, 82, 65, 78, 73, + 83, 77, 193, 79, 89, 65, 78, 78, 65, 128, 79, 88, 73, 65, 128, 79, 88, + 73, 193, 79, 88, 69, 73, 65, 201, 79, 88, 69, 73, 193, 79, 87, 76, 128, + 79, 86, 69, 82, 83, 84, 82, 85, 67, 203, 79, 86, 69, 82, 82, 73, 68, 69, + 128, 79, 86, 69, 82, 76, 79, 78, 199, 79, 86, 69, 82, 76, 73, 78, 69, + 128, 79, 86, 69, 82, 76, 65, 89, 128, 79, 86, 69, 82, 76, 65, 217, 79, + 86, 69, 82, 76, 65, 80, 80, 73, 78, 199, 79, 86, 69, 82, 76, 65, 80, 128, + 79, 86, 69, 82, 76, 65, 73, 68, 128, 79, 86, 69, 82, 76, 65, 73, 196, 79, + 86, 69, 82, 72, 69, 65, 84, 69, 196, 79, 86, 69, 82, 66, 65, 82, 128, 79, + 86, 65, 76, 128, 79, 86, 65, 204, 79, 85, 84, 76, 73, 78, 69, 196, 79, + 85, 84, 76, 73, 78, 69, 128, 79, 85, 84, 69, 210, 79, 85, 84, 66, 79, + 216, 79, 85, 78, 75, 73, 193, 79, 85, 78, 67, 69, 128, 79, 85, 78, 67, + 197, 79, 84, 85, 128, 79, 84, 84, 79, 77, 65, 206, 79, 84, 84, 69, 82, + 128, 79, 84, 84, 65, 86, 193, 79, 84, 84, 128, 79, 84, 83, 69, 67, 72, + 75, 65, 128, 79, 84, 72, 69, 82, 211, 79, 84, 72, 69, 210, 79, 84, 72, + 65, 76, 65, 206, 79, 84, 72, 65, 76, 128, 79, 83, 79, 75, 65, 128, 79, + 83, 79, 75, 193, 79, 83, 77, 65, 78, 89, 193, 79, 83, 67, 128, 79, 83, + 65, 71, 197, 79, 82, 84, 72, 79, 71, 79, 78, 65, 204, 79, 82, 84, 72, 79, + 68, 79, 216, 79, 82, 78, 65, 84, 197, 79, 82, 78, 65, 77, 69, 78, 84, 83, + 128, 79, 82, 78, 65, 77, 69, 78, 84, 128, 79, 82, 78, 65, 77, 69, 78, + 212, 79, 82, 75, 72, 79, 206, 79, 82, 73, 89, 193, 79, 82, 73, 71, 73, + 78, 65, 204, 79, 82, 73, 71, 73, 78, 128, 79, 82, 69, 45, 50, 128, 79, + 82, 68, 73, 78, 65, 204, 79, 82, 68, 69, 210, 79, 82, 67, 85, 83, 128, + 79, 82, 67, 72, 73, 68, 128, 79, 82, 65, 78, 71, 85, 84, 65, 78, 128, 79, + 82, 65, 78, 71, 197, 79, 80, 84, 73, 79, 206, 79, 80, 84, 73, 67, 65, + 204, 79, 80, 80, 82, 69, 83, 83, 73, 79, 78, 128, 79, 80, 80, 79, 83, 73, + 84, 73, 79, 78, 128, 79, 80, 80, 79, 83, 73, 78, 199, 79, 80, 80, 79, 83, + 69, 128, 79, 80, 72, 73, 85, 67, 72, 85, 83, 128, 79, 80, 69, 82, 65, 84, + 79, 82, 128, 79, 80, 69, 82, 65, 84, 79, 210, 79, 80, 69, 82, 65, 84, 73, + 78, 199, 79, 80, 69, 78, 73, 78, 199, 79, 80, 69, 78, 45, 80, 128, 79, + 80, 69, 78, 45, 79, 85, 84, 76, 73, 78, 69, 196, 79, 80, 69, 78, 45, 79, + 128, 79, 80, 69, 78, 45, 207, 79, 80, 69, 78, 45, 72, 69, 65, 68, 69, + 196, 79, 80, 69, 78, 45, 67, 73, 82, 67, 85, 73, 84, 45, 79, 85, 84, 80, + 85, 212, 79, 80, 69, 78, 128, 79, 80, 69, 206, 79, 79, 90, 69, 128, 79, + 79, 89, 65, 78, 78, 65, 128, 79, 79, 85, 128, 79, 79, 77, 85, 128, 79, + 79, 72, 128, 79, 79, 69, 128, 79, 79, 66, 79, 79, 70, 73, 76, 73, 128, + 79, 78, 85, 128, 79, 78, 83, 85, 128, 79, 78, 78, 128, 79, 78, 75, 65, + 82, 128, 79, 78, 73, 79, 78, 128, 79, 78, 69, 83, 69, 76, 70, 128, 79, + 78, 69, 45, 87, 65, 217, 79, 78, 69, 45, 84, 72, 73, 82, 84, 89, 128, 79, + 78, 69, 45, 80, 73, 69, 67, 197, 79, 78, 69, 45, 76, 73, 78, 197, 79, 78, + 69, 45, 72, 85, 78, 68, 82, 69, 68, 45, 65, 78, 68, 45, 83, 73, 88, 84, + 73, 69, 84, 72, 128, 79, 78, 67, 79, 77, 73, 78, 199, 79, 78, 65, 80, + 128, 79, 78, 45, 79, 70, 198, 79, 77, 73, 83, 83, 73, 79, 206, 79, 77, + 73, 67, 82, 79, 78, 128, 79, 77, 73, 67, 82, 79, 206, 79, 77, 69, 84, + 128, 79, 77, 69, 71, 65, 128, 79, 77, 69, 71, 193, 79, 77, 65, 76, 79, + 78, 128, 79, 76, 73, 86, 69, 128, 79, 76, 73, 71, 79, 206, 79, 76, 68, + 128, 79, 75, 84, 207, 79, 75, 65, 82, 65, 128, 79, 75, 65, 82, 193, 79, + 74, 79, 68, 128, 79, 74, 73, 66, 87, 65, 217, 79, 74, 69, 79, 78, 128, + 79, 73, 78, 128, 79, 73, 76, 128, 79, 73, 204, 79, 72, 77, 128, 79, 72, + 205, 79, 71, 82, 69, 128, 79, 71, 79, 78, 69, 75, 128, 79, 71, 79, 78, + 69, 203, 79, 71, 72, 65, 205, 79, 70, 70, 73, 67, 69, 82, 128, 79, 70, + 70, 73, 67, 69, 128, 79, 70, 70, 73, 67, 197, 79, 70, 70, 128, 79, 69, + 89, 128, 79, 69, 82, 128, 79, 69, 75, 128, 79, 69, 69, 128, 79, 68, 69, + 78, 128, 79, 68, 68, 128, 79, 68, 196, 79, 67, 84, 79, 80, 85, 83, 128, + 79, 67, 84, 79, 66, 69, 82, 128, 79, 67, 84, 69, 212, 79, 67, 84, 65, 71, + 79, 78, 65, 204, 79, 67, 84, 65, 71, 79, 78, 128, 79, 67, 210, 79, 67, + 76, 79, 67, 75, 128, 79, 67, 72, 75, 79, 77, 128, 79, 67, 67, 85, 76, 84, + 65, 84, 73, 79, 78, 128, 79, 67, 67, 76, 85, 83, 73, 79, 78, 128, 79, 66, + 83, 84, 82, 85, 67, 84, 73, 79, 78, 128, 79, 66, 83, 69, 82, 86, 69, 210, + 79, 66, 79, 76, 211, 79, 66, 79, 204, 79, 66, 79, 70, 73, 76, 73, 128, + 79, 66, 76, 73, 81, 85, 197, 79, 66, 76, 65, 75, 79, 128, 79, 66, 76, 65, + 67, 72, 75, 79, 128, 79, 66, 74, 69, 67, 212, 79, 66, 69, 76, 85, 83, + 128, 79, 66, 69, 76, 79, 83, 128, 79, 66, 128, 79, 65, 89, 128, 79, 65, + 75, 128, 79, 65, 66, 79, 65, 70, 73, 76, 73, 128, 79, 193, 79, 48, 53, + 49, 128, 79, 48, 53, 48, 66, 128, 79, 48, 53, 48, 65, 128, 79, 48, 53, + 48, 128, 79, 48, 52, 57, 128, 79, 48, 52, 56, 128, 79, 48, 52, 55, 128, + 79, 48, 52, 54, 128, 79, 48, 52, 53, 128, 79, 48, 52, 52, 128, 79, 48, + 52, 51, 128, 79, 48, 52, 50, 128, 79, 48, 52, 49, 128, 79, 48, 52, 48, + 128, 79, 48, 51, 57, 128, 79, 48, 51, 56, 128, 79, 48, 51, 55, 128, 79, + 48, 51, 54, 68, 128, 79, 48, 51, 54, 67, 128, 79, 48, 51, 54, 66, 128, + 79, 48, 51, 54, 65, 128, 79, 48, 51, 54, 128, 79, 48, 51, 53, 128, 79, + 48, 51, 52, 128, 79, 48, 51, 51, 65, 128, 79, 48, 51, 51, 128, 79, 48, + 51, 50, 128, 79, 48, 51, 49, 128, 79, 48, 51, 48, 65, 128, 79, 48, 51, + 48, 128, 79, 48, 50, 57, 65, 128, 79, 48, 50, 57, 128, 79, 48, 50, 56, + 128, 79, 48, 50, 55, 128, 79, 48, 50, 54, 128, 79, 48, 50, 53, 65, 128, + 79, 48, 50, 53, 128, 79, 48, 50, 52, 65, 128, 79, 48, 50, 52, 128, 79, + 48, 50, 51, 128, 79, 48, 50, 50, 128, 79, 48, 50, 49, 128, 79, 48, 50, + 48, 65, 128, 79, 48, 50, 48, 128, 79, 48, 49, 57, 65, 128, 79, 48, 49, + 57, 128, 79, 48, 49, 56, 128, 79, 48, 49, 55, 128, 79, 48, 49, 54, 128, + 79, 48, 49, 53, 128, 79, 48, 49, 52, 128, 79, 48, 49, 51, 128, 79, 48, + 49, 50, 128, 79, 48, 49, 49, 128, 79, 48, 49, 48, 67, 128, 79, 48, 49, + 48, 66, 128, 79, 48, 49, 48, 65, 128, 79, 48, 49, 48, 128, 79, 48, 48, + 57, 128, 79, 48, 48, 56, 128, 79, 48, 48, 55, 128, 79, 48, 48, 54, 70, + 128, 79, 48, 48, 54, 69, 128, 79, 48, 48, 54, 68, 128, 79, 48, 48, 54, + 67, 128, 79, 48, 48, 54, 66, 128, 79, 48, 48, 54, 65, 128, 79, 48, 48, + 54, 128, 79, 48, 48, 53, 65, 128, 79, 48, 48, 53, 128, 79, 48, 48, 52, + 128, 79, 48, 48, 51, 128, 79, 48, 48, 50, 128, 79, 48, 48, 49, 65, 128, + 79, 48, 48, 49, 128, 79, 45, 89, 69, 128, 79, 45, 79, 45, 73, 128, 79, + 45, 69, 128, 78, 90, 89, 88, 128, 78, 90, 89, 84, 128, 78, 90, 89, 82, + 88, 128, 78, 90, 89, 82, 128, 78, 90, 89, 80, 128, 78, 90, 89, 128, 78, + 90, 85, 88, 128, 78, 90, 85, 82, 88, 128, 78, 90, 85, 82, 128, 78, 90, + 85, 81, 128, 78, 90, 85, 80, 128, 78, 90, 85, 79, 88, 128, 78, 90, 85, + 79, 128, 78, 90, 85, 206, 78, 90, 85, 128, 78, 90, 79, 88, 128, 78, 90, + 79, 80, 128, 78, 90, 73, 88, 128, 78, 90, 73, 84, 128, 78, 90, 73, 80, + 128, 78, 90, 73, 69, 88, 128, 78, 90, 73, 69, 80, 128, 78, 90, 73, 69, + 128, 78, 90, 73, 128, 78, 90, 69, 88, 128, 78, 90, 69, 85, 77, 128, 78, + 90, 69, 128, 78, 90, 65, 88, 128, 78, 90, 65, 84, 128, 78, 90, 65, 81, + 128, 78, 90, 65, 80, 128, 78, 90, 65, 128, 78, 90, 193, 78, 89, 87, 65, + 128, 78, 89, 85, 88, 128, 78, 89, 85, 85, 128, 78, 89, 85, 84, 128, 78, + 89, 85, 80, 128, 78, 89, 85, 79, 88, 128, 78, 89, 85, 79, 80, 128, 78, + 89, 85, 79, 128, 78, 89, 85, 78, 128, 78, 89, 85, 69, 128, 78, 89, 85, + 128, 78, 89, 79, 88, 128, 78, 89, 79, 84, 128, 78, 89, 79, 80, 128, 78, + 89, 79, 79, 128, 78, 89, 79, 78, 128, 78, 89, 79, 65, 128, 78, 89, 79, + 128, 78, 89, 74, 65, 128, 78, 89, 73, 88, 128, 78, 89, 73, 84, 128, 78, + 89, 73, 212, 78, 89, 73, 211, 78, 89, 73, 210, 78, 89, 73, 80, 128, 78, + 89, 73, 78, 45, 68, 79, 128, 78, 89, 73, 78, 128, 78, 89, 73, 73, 128, + 78, 89, 73, 69, 88, 128, 78, 89, 73, 69, 84, 128, 78, 89, 73, 69, 80, + 128, 78, 89, 73, 69, 128, 78, 89, 73, 65, 75, 69, 78, 199, 78, 89, 73, + 128, 78, 89, 201, 78, 89, 72, 65, 128, 78, 89, 69, 84, 128, 78, 89, 69, + 212, 78, 89, 69, 78, 128, 78, 89, 69, 72, 128, 78, 89, 69, 200, 78, 89, + 69, 69, 128, 78, 89, 69, 128, 78, 89, 196, 78, 89, 67, 65, 128, 78, 89, + 65, 85, 128, 78, 89, 65, 74, 128, 78, 89, 65, 73, 128, 78, 89, 65, 72, + 128, 78, 89, 65, 69, 77, 65, 69, 128, 78, 89, 65, 65, 128, 78, 87, 79, + 79, 128, 78, 87, 79, 128, 78, 87, 73, 73, 128, 78, 87, 73, 128, 78, 87, + 69, 128, 78, 87, 65, 65, 128, 78, 87, 65, 128, 78, 87, 128, 78, 86, 128, + 78, 85, 88, 128, 78, 85, 85, 78, 128, 78, 85, 85, 128, 78, 85, 84, 73, + 76, 76, 85, 128, 78, 85, 84, 128, 78, 85, 212, 78, 85, 82, 88, 128, 78, + 85, 82, 128, 78, 85, 80, 128, 78, 85, 79, 88, 128, 78, 85, 79, 80, 128, + 78, 85, 79, 128, 78, 85, 78, 85, 90, 128, 78, 85, 78, 85, 218, 78, 85, + 78, 71, 128, 78, 85, 78, 65, 86, 85, 212, 78, 85, 78, 65, 86, 73, 203, + 78, 85, 78, 128, 78, 85, 206, 78, 85, 77, 69, 82, 207, 78, 85, 77, 69, + 82, 65, 84, 79, 210, 78, 85, 77, 69, 82, 65, 204, 78, 85, 77, 66, 69, 82, + 83, 128, 78, 85, 77, 66, 69, 82, 128, 78, 85, 77, 128, 78, 85, 76, 76, + 128, 78, 85, 76, 204, 78, 85, 76, 128, 78, 85, 75, 84, 65, 128, 78, 85, + 75, 84, 193, 78, 85, 69, 78, 71, 128, 78, 85, 69, 128, 78, 85, 66, 73, + 65, 206, 78, 85, 65, 69, 128, 78, 85, 49, 49, 128, 78, 85, 49, 177, 78, + 85, 48, 50, 50, 65, 128, 78, 85, 48, 50, 50, 128, 78, 85, 48, 50, 49, + 128, 78, 85, 48, 50, 48, 128, 78, 85, 48, 49, 57, 128, 78, 85, 48, 49, + 56, 65, 128, 78, 85, 48, 49, 56, 128, 78, 85, 48, 49, 55, 128, 78, 85, + 48, 49, 54, 128, 78, 85, 48, 49, 53, 128, 78, 85, 48, 49, 52, 128, 78, + 85, 48, 49, 51, 128, 78, 85, 48, 49, 50, 128, 78, 85, 48, 49, 49, 65, + 128, 78, 85, 48, 49, 49, 128, 78, 85, 48, 49, 48, 65, 128, 78, 85, 48, + 49, 48, 128, 78, 85, 48, 48, 57, 128, 78, 85, 48, 48, 56, 128, 78, 85, + 48, 48, 55, 128, 78, 85, 48, 48, 54, 128, 78, 85, 48, 48, 53, 128, 78, + 85, 48, 48, 52, 128, 78, 85, 48, 48, 51, 128, 78, 85, 48, 48, 50, 128, + 78, 85, 48, 48, 49, 128, 78, 85, 45, 51, 128, 78, 85, 45, 50, 128, 78, + 85, 45, 49, 128, 78, 84, 88, 73, 86, 128, 78, 84, 88, 65, 128, 78, 84, + 85, 85, 128, 78, 84, 85, 77, 128, 78, 84, 85, 74, 128, 78, 84, 213, 78, + 84, 83, 65, 85, 128, 78, 84, 83, 65, 128, 78, 84, 79, 81, 80, 69, 78, + 128, 78, 84, 79, 71, 128, 78, 84, 79, 199, 78, 84, 73, 69, 197, 78, 84, + 72, 65, 85, 128, 78, 84, 69, 85, 78, 71, 66, 65, 128, 78, 84, 69, 85, 77, + 128, 78, 84, 69, 78, 128, 78, 84, 69, 69, 128, 78, 84, 65, 80, 128, 78, + 84, 65, 208, 78, 84, 65, 65, 128, 78, 84, 65, 128, 78, 83, 85, 79, 212, + 78, 83, 85, 78, 128, 78, 83, 85, 77, 128, 78, 83, 79, 77, 128, 78, 83, + 73, 69, 69, 84, 128, 78, 83, 73, 69, 69, 80, 128, 78, 83, 73, 69, 69, + 128, 78, 83, 72, 85, 84, 128, 78, 83, 72, 85, 212, 78, 83, 72, 85, 79, + 80, 128, 78, 83, 72, 85, 69, 128, 78, 83, 72, 73, 69, 69, 128, 78, 83, + 72, 69, 69, 128, 78, 83, 72, 65, 81, 128, 78, 83, 72, 65, 128, 78, 83, + 69, 85, 65, 69, 78, 128, 78, 83, 69, 78, 128, 78, 83, 65, 128, 78, 82, + 89, 88, 128, 78, 82, 89, 84, 128, 78, 82, 89, 82, 88, 128, 78, 82, 89, + 82, 128, 78, 82, 89, 80, 128, 78, 82, 89, 128, 78, 82, 85, 88, 128, 78, + 82, 85, 84, 128, 78, 82, 85, 82, 88, 128, 78, 82, 85, 82, 128, 78, 82, + 85, 80, 128, 78, 82, 85, 65, 128, 78, 82, 85, 128, 78, 82, 79, 88, 128, + 78, 82, 79, 80, 128, 78, 82, 79, 128, 78, 82, 69, 88, 128, 78, 82, 69, + 84, 128, 78, 82, 69, 211, 78, 82, 69, 80, 128, 78, 82, 69, 128, 78, 82, + 65, 88, 128, 78, 82, 65, 84, 128, 78, 82, 65, 80, 128, 78, 82, 65, 128, + 78, 81, 73, 71, 128, 78, 81, 65, 128, 78, 80, 76, 65, 128, 78, 80, 65, + 128, 78, 79, 90, 72, 75, 65, 128, 78, 79, 89, 128, 78, 79, 88, 128, 78, + 79, 87, 67, 128, 78, 79, 86, 73, 76, 69, 128, 78, 79, 86, 69, 77, 66, 69, + 82, 128, 78, 79, 84, 84, 79, 128, 78, 79, 84, 69, 83, 128, 78, 79, 84, + 69, 72, 69, 65, 68, 128, 78, 79, 84, 69, 72, 69, 65, 196, 78, 79, 84, 69, + 66, 79, 79, 75, 128, 78, 79, 84, 69, 66, 79, 79, 203, 78, 79, 84, 69, + 128, 78, 79, 84, 197, 78, 79, 84, 67, 72, 69, 196, 78, 79, 84, 67, 72, + 128, 78, 79, 84, 65, 84, 73, 79, 206, 78, 79, 84, 128, 78, 79, 212, 78, + 79, 83, 69, 128, 78, 79, 83, 197, 78, 79, 82, 84, 72, 87, 69, 83, 212, + 78, 79, 82, 84, 72, 69, 82, 206, 78, 79, 82, 84, 72, 69, 65, 83, 84, 45, + 80, 79, 73, 78, 84, 73, 78, 199, 78, 79, 82, 77, 65, 204, 78, 79, 82, 68, + 73, 195, 78, 79, 210, 78, 79, 80, 128, 78, 79, 79, 78, 85, 128, 78, 79, + 79, 128, 78, 79, 78, 70, 79, 82, 75, 73, 78, 71, 128, 78, 79, 78, 45, 80, + 79, 84, 65, 66, 76, 197, 78, 79, 78, 45, 74, 79, 73, 78, 69, 82, 128, 78, + 79, 78, 45, 66, 82, 69, 65, 75, 73, 78, 199, 78, 79, 78, 128, 78, 79, 77, + 73, 83, 77, 193, 78, 79, 77, 73, 78, 65, 204, 78, 79, 75, 72, 85, 75, + 128, 78, 79, 68, 69, 128, 78, 79, 65, 128, 78, 79, 45, 66, 82, 69, 65, + 203, 78, 79, 45, 53, 128, 78, 79, 45, 52, 128, 78, 79, 45, 51, 128, 78, + 79, 45, 50, 128, 78, 79, 45, 49, 128, 78, 78, 85, 85, 128, 78, 78, 85, + 128, 78, 78, 79, 79, 128, 78, 78, 78, 85, 85, 128, 78, 78, 78, 85, 128, + 78, 78, 78, 79, 79, 128, 78, 78, 78, 79, 128, 78, 78, 78, 73, 73, 128, + 78, 78, 78, 73, 128, 78, 78, 78, 69, 69, 128, 78, 78, 78, 69, 128, 78, + 78, 78, 65, 85, 128, 78, 78, 78, 65, 73, 128, 78, 78, 78, 65, 65, 128, + 78, 78, 78, 65, 128, 78, 78, 78, 128, 78, 78, 72, 65, 128, 78, 78, 71, + 79, 79, 128, 78, 78, 71, 79, 128, 78, 78, 71, 73, 73, 128, 78, 78, 71, + 73, 128, 78, 78, 71, 65, 65, 128, 78, 78, 71, 65, 128, 78, 78, 71, 128, + 78, 78, 66, 83, 80, 128, 78, 77, 128, 78, 76, 65, 85, 128, 78, 76, 48, + 50, 48, 128, 78, 76, 48, 49, 57, 128, 78, 76, 48, 49, 56, 128, 78, 76, + 48, 49, 55, 65, 128, 78, 76, 48, 49, 55, 128, 78, 76, 48, 49, 54, 128, + 78, 76, 48, 49, 53, 128, 78, 76, 48, 49, 52, 128, 78, 76, 48, 49, 51, + 128, 78, 76, 48, 49, 50, 128, 78, 76, 48, 49, 49, 128, 78, 76, 48, 49, + 48, 128, 78, 76, 48, 48, 57, 128, 78, 76, 48, 48, 56, 128, 78, 76, 48, + 48, 55, 128, 78, 76, 48, 48, 54, 128, 78, 76, 48, 48, 53, 65, 128, 78, + 76, 48, 48, 53, 128, 78, 76, 48, 48, 52, 128, 78, 76, 48, 48, 51, 128, + 78, 76, 48, 48, 50, 128, 78, 76, 48, 48, 49, 128, 78, 76, 128, 78, 75, + 79, 77, 128, 78, 75, 207, 78, 75, 73, 78, 68, 73, 128, 78, 75, 65, 85, + 128, 78, 75, 65, 65, 82, 65, 69, 128, 78, 75, 65, 128, 78, 74, 89, 88, + 128, 78, 74, 89, 84, 128, 78, 74, 89, 82, 88, 128, 78, 74, 89, 82, 128, + 78, 74, 89, 80, 128, 78, 74, 89, 128, 78, 74, 85, 88, 128, 78, 74, 85, + 82, 88, 128, 78, 74, 85, 82, 128, 78, 74, 85, 81, 65, 128, 78, 74, 85, + 80, 128, 78, 74, 85, 79, 88, 128, 78, 74, 85, 79, 128, 78, 74, 85, 69, + 81, 128, 78, 74, 85, 65, 69, 128, 78, 74, 85, 128, 78, 74, 79, 88, 128, + 78, 74, 79, 84, 128, 78, 74, 79, 80, 128, 78, 74, 79, 79, 128, 78, 74, + 79, 128, 78, 74, 73, 88, 128, 78, 74, 73, 84, 128, 78, 74, 73, 80, 128, + 78, 74, 73, 69, 88, 128, 78, 74, 73, 69, 84, 128, 78, 74, 73, 69, 80, + 128, 78, 74, 73, 69, 69, 128, 78, 74, 73, 69, 128, 78, 74, 73, 128, 78, + 74, 201, 78, 74, 69, 85, 88, 128, 78, 74, 69, 85, 84, 128, 78, 74, 69, + 85, 65, 69, 78, 65, 128, 78, 74, 69, 85, 65, 69, 77, 128, 78, 74, 69, 69, + 69, 69, 128, 78, 74, 69, 69, 128, 78, 74, 69, 197, 78, 74, 69, 128, 78, + 74, 65, 81, 128, 78, 74, 65, 80, 128, 78, 74, 65, 69, 77, 76, 73, 128, + 78, 74, 65, 69, 77, 128, 78, 74, 65, 65, 128, 78, 73, 90, 75, 207, 78, + 73, 88, 128, 78, 73, 84, 82, 69, 128, 78, 73, 83, 65, 71, 128, 78, 73, + 82, 85, 71, 85, 128, 78, 73, 80, 128, 78, 73, 78, 84, 72, 128, 78, 73, + 78, 74, 65, 128, 78, 73, 78, 69, 84, 89, 128, 78, 73, 78, 69, 84, 217, + 78, 73, 78, 69, 84, 69, 69, 78, 128, 78, 73, 78, 69, 84, 69, 69, 206, 78, + 73, 78, 69, 45, 84, 72, 73, 82, 84, 89, 128, 78, 73, 78, 69, 45, 76, 73, + 75, 197, 78, 73, 78, 197, 78, 73, 78, 68, 65, 50, 128, 78, 73, 78, 68, + 65, 178, 78, 73, 78, 57, 128, 78, 73, 78, 128, 78, 73, 77, 128, 78, 73, + 205, 78, 73, 75, 79, 76, 83, 66, 85, 82, 199, 78, 73, 75, 72, 65, 72, 73, + 84, 128, 78, 73, 75, 65, 72, 73, 84, 128, 78, 73, 75, 65, 128, 78, 73, + 72, 83, 72, 86, 65, 83, 65, 128, 78, 73, 71, 73, 68, 65, 77, 73, 78, 128, + 78, 73, 71, 73, 68, 65, 69, 83, 72, 128, 78, 73, 71, 72, 84, 128, 78, 73, + 71, 72, 212, 78, 73, 71, 71, 65, 72, 73, 84, 65, 128, 78, 73, 69, 88, + 128, 78, 73, 69, 85, 78, 45, 84, 73, 75, 69, 85, 84, 128, 78, 73, 69, 85, + 78, 45, 84, 72, 73, 69, 85, 84, 72, 128, 78, 73, 69, 85, 78, 45, 83, 73, + 79, 83, 128, 78, 73, 69, 85, 78, 45, 82, 73, 69, 85, 76, 128, 78, 73, 69, + 85, 78, 45, 80, 73, 69, 85, 80, 128, 78, 73, 69, 85, 78, 45, 80, 65, 78, + 83, 73, 79, 83, 128, 78, 73, 69, 85, 78, 45, 75, 73, 89, 69, 79, 75, 128, + 78, 73, 69, 85, 78, 45, 72, 73, 69, 85, 72, 128, 78, 73, 69, 85, 78, 45, + 67, 73, 69, 85, 67, 128, 78, 73, 69, 85, 78, 45, 67, 72, 73, 69, 85, 67, + 72, 128, 78, 73, 69, 85, 206, 78, 73, 69, 80, 128, 78, 73, 69, 128, 78, + 73, 66, 128, 78, 73, 65, 128, 78, 73, 50, 128, 78, 73, 45, 84, 69, 128, + 78, 73, 45, 55, 128, 78, 73, 45, 54, 128, 78, 73, 45, 53, 128, 78, 73, + 45, 52, 128, 78, 73, 45, 51, 128, 78, 73, 45, 50, 128, 78, 73, 45, 49, + 128, 78, 72, 85, 69, 128, 78, 72, 74, 65, 128, 78, 72, 65, 89, 128, 78, + 72, 128, 78, 71, 89, 69, 128, 78, 71, 86, 69, 128, 78, 71, 85, 85, 128, + 78, 71, 85, 79, 88, 128, 78, 71, 85, 79, 84, 128, 78, 71, 85, 79, 128, + 78, 71, 85, 65, 78, 128, 78, 71, 85, 65, 69, 84, 128, 78, 71, 85, 65, 69, + 128, 78, 71, 79, 88, 128, 78, 71, 79, 85, 128, 78, 71, 79, 213, 78, 71, + 79, 84, 128, 78, 71, 79, 81, 128, 78, 71, 79, 80, 128, 78, 71, 79, 78, + 128, 78, 71, 79, 77, 128, 78, 71, 79, 69, 72, 128, 78, 71, 79, 69, 200, + 78, 71, 207, 78, 71, 75, 89, 69, 69, 128, 78, 71, 75, 87, 65, 69, 78, + 128, 78, 71, 75, 85, 80, 128, 78, 71, 75, 85, 78, 128, 78, 71, 75, 85, + 77, 128, 78, 71, 75, 85, 69, 78, 90, 69, 85, 77, 128, 78, 71, 75, 85, + 197, 78, 71, 75, 73, 78, 68, 201, 78, 71, 75, 73, 69, 69, 128, 78, 71, + 75, 69, 85, 88, 128, 78, 71, 75, 69, 85, 82, 73, 128, 78, 71, 75, 69, 85, + 65, 69, 81, 128, 78, 71, 75, 69, 85, 65, 69, 77, 128, 78, 71, 75, 65, 81, + 128, 78, 71, 75, 65, 80, 128, 78, 71, 75, 65, 65, 77, 73, 128, 78, 71, + 75, 65, 128, 78, 71, 73, 69, 88, 128, 78, 71, 73, 69, 80, 128, 78, 71, + 73, 69, 128, 78, 71, 72, 65, 128, 78, 71, 71, 87, 65, 69, 78, 128, 78, + 71, 71, 85, 82, 65, 69, 128, 78, 71, 71, 85, 80, 128, 78, 71, 71, 85, 79, + 81, 128, 78, 71, 71, 85, 79, 209, 78, 71, 71, 85, 79, 78, 128, 78, 71, + 71, 85, 79, 77, 128, 78, 71, 71, 85, 77, 128, 78, 71, 71, 85, 69, 69, 84, + 128, 78, 71, 71, 85, 65, 69, 83, 72, 65, 197, 78, 71, 71, 85, 65, 69, + 206, 78, 71, 71, 85, 65, 128, 78, 71, 71, 85, 128, 78, 71, 71, 79, 79, + 128, 78, 71, 71, 79, 128, 78, 71, 71, 73, 128, 78, 71, 71, 69, 85, 88, + 128, 78, 71, 71, 69, 85, 65, 69, 84, 128, 78, 71, 71, 69, 85, 65, 69, + 128, 78, 71, 71, 69, 213, 78, 71, 71, 69, 78, 128, 78, 71, 71, 69, 69, + 84, 128, 78, 71, 71, 69, 69, 69, 69, 128, 78, 71, 71, 69, 69, 128, 78, + 71, 71, 69, 128, 78, 71, 71, 65, 80, 128, 78, 71, 71, 65, 65, 77, 65, 69, + 128, 78, 71, 71, 65, 65, 77, 128, 78, 71, 71, 65, 65, 128, 78, 71, 71, + 128, 78, 71, 69, 88, 128, 78, 71, 69, 85, 82, 69, 85, 84, 128, 78, 71, + 69, 80, 128, 78, 71, 69, 78, 128, 78, 71, 69, 69, 128, 78, 71, 69, 65, + 68, 65, 76, 128, 78, 71, 65, 88, 128, 78, 71, 65, 85, 128, 78, 71, 65, + 84, 128, 78, 71, 65, 211, 78, 71, 65, 81, 128, 78, 71, 65, 80, 128, 78, + 71, 65, 78, 71, 85, 128, 78, 71, 65, 78, 128, 78, 71, 65, 73, 128, 78, + 71, 65, 72, 128, 78, 71, 65, 65, 73, 128, 78, 71, 193, 78, 70, 128, 78, + 69, 88, 212, 78, 69, 88, 128, 78, 69, 87, 83, 80, 65, 80, 69, 82, 128, + 78, 69, 87, 76, 73, 78, 69, 128, 78, 69, 87, 76, 73, 78, 197, 78, 69, 87, + 193, 78, 69, 87, 128, 78, 69, 215, 78, 69, 85, 84, 82, 65, 76, 128, 78, + 69, 85, 84, 82, 65, 204, 78, 69, 85, 84, 69, 82, 128, 78, 69, 84, 87, 79, + 82, 75, 69, 196, 78, 69, 212, 78, 69, 83, 84, 73, 78, 199, 78, 69, 83, + 84, 69, 196, 78, 69, 83, 84, 128, 78, 69, 83, 212, 78, 69, 83, 83, 85, + 83, 128, 78, 69, 82, 196, 78, 69, 81, 85, 68, 65, 65, 128, 78, 69, 80, + 84, 85, 78, 69, 128, 78, 69, 80, 84, 85, 78, 197, 78, 69, 80, 79, 83, 84, + 79, 89, 65, 78, 78, 65, 89, 65, 128, 78, 69, 80, 128, 78, 69, 79, 128, + 78, 69, 207, 78, 69, 78, 79, 69, 128, 78, 69, 78, 65, 78, 79, 128, 78, + 69, 78, 128, 78, 69, 77, 75, 65, 128, 78, 69, 76, 128, 78, 69, 73, 84, + 72, 69, 210, 78, 69, 71, 65, 84, 73, 86, 197, 78, 69, 71, 65, 84, 73, 79, + 206, 78, 69, 71, 65, 84, 69, 196, 78, 69, 69, 68, 76, 69, 128, 78, 69, + 67, 75, 84, 73, 69, 128, 78, 69, 67, 75, 128, 78, 69, 66, 69, 78, 83, 84, + 73, 77, 77, 69, 128, 78, 69, 45, 75, 79, 128, 78, 68, 85, 88, 128, 78, + 68, 85, 84, 128, 78, 68, 85, 82, 88, 128, 78, 68, 85, 82, 128, 78, 68, + 85, 80, 128, 78, 68, 85, 78, 128, 78, 68, 213, 78, 68, 79, 88, 128, 78, + 68, 79, 84, 128, 78, 68, 79, 80, 128, 78, 68, 79, 79, 128, 78, 68, 79, + 78, 128, 78, 68, 79, 77, 66, 85, 128, 78, 68, 79, 76, 197, 78, 68, 73, + 88, 128, 78, 68, 73, 84, 128, 78, 68, 73, 81, 128, 78, 68, 73, 80, 128, + 78, 68, 73, 69, 88, 128, 78, 68, 73, 69, 128, 78, 68, 73, 68, 65, 128, + 78, 68, 73, 65, 81, 128, 78, 68, 69, 88, 128, 78, 68, 69, 85, 88, 128, + 78, 68, 69, 85, 84, 128, 78, 68, 69, 85, 65, 69, 82, 69, 69, 128, 78, 68, + 69, 80, 128, 78, 68, 69, 69, 128, 78, 68, 69, 128, 78, 68, 65, 88, 128, + 78, 68, 65, 84, 128, 78, 68, 65, 80, 128, 78, 68, 65, 77, 128, 78, 68, + 65, 65, 78, 71, 71, 69, 85, 65, 69, 84, 128, 78, 68, 65, 65, 128, 78, 68, + 65, 193, 78, 67, 72, 65, 85, 128, 78, 67, 65, 128, 78, 66, 89, 88, 128, + 78, 66, 89, 84, 128, 78, 66, 89, 82, 88, 128, 78, 66, 89, 82, 128, 78, + 66, 89, 80, 128, 78, 66, 89, 128, 78, 66, 85, 88, 128, 78, 66, 85, 84, + 128, 78, 66, 85, 82, 88, 128, 78, 66, 85, 82, 128, 78, 66, 85, 80, 128, + 78, 66, 85, 128, 78, 66, 79, 88, 128, 78, 66, 79, 84, 128, 78, 66, 79, + 80, 128, 78, 66, 79, 128, 78, 66, 73, 88, 128, 78, 66, 73, 84, 128, 78, + 66, 73, 80, 128, 78, 66, 73, 69, 88, 128, 78, 66, 73, 69, 80, 128, 78, + 66, 73, 69, 128, 78, 66, 73, 128, 78, 66, 72, 128, 78, 66, 65, 88, 128, + 78, 66, 65, 84, 128, 78, 66, 65, 80, 128, 78, 66, 65, 128, 78, 65, 90, + 65, 210, 78, 65, 89, 65, 78, 78, 65, 128, 78, 65, 89, 128, 78, 65, 88, + 73, 65, 206, 78, 65, 88, 128, 78, 65, 85, 84, 72, 83, 128, 78, 65, 85, + 83, 69, 65, 84, 69, 196, 78, 65, 85, 68, 73, 218, 78, 65, 84, 85, 82, 65, + 204, 78, 65, 84, 84, 73, 76, 73, 203, 78, 65, 84, 73, 79, 78, 65, 204, + 78, 65, 83, 75, 65, 80, 201, 78, 65, 83, 72, 73, 128, 78, 65, 83, 65, 76, + 73, 90, 69, 196, 78, 65, 83, 65, 76, 73, 90, 65, 84, 73, 79, 78, 128, 78, + 65, 83, 65, 76, 73, 90, 65, 84, 73, 79, 206, 78, 65, 83, 65, 204, 78, 65, + 82, 82, 79, 215, 78, 65, 82, 128, 78, 65, 81, 128, 78, 65, 79, 211, 78, + 65, 78, 83, 65, 78, 65, 81, 128, 78, 65, 78, 71, 77, 79, 78, 84, 72, 79, + 128, 78, 65, 78, 68, 73, 78, 65, 71, 65, 82, 201, 78, 65, 78, 68, 128, + 78, 65, 78, 65, 128, 78, 65, 77, 69, 128, 78, 65, 77, 197, 78, 65, 77, + 50, 128, 78, 65, 75, 65, 65, 82, 193, 78, 65, 75, 128, 78, 65, 73, 82, + 193, 78, 65, 73, 204, 78, 65, 71, 82, 201, 78, 65, 71, 65, 82, 128, 78, + 65, 71, 65, 128, 78, 65, 71, 193, 78, 65, 71, 128, 78, 65, 199, 78, 65, + 69, 128, 78, 65, 66, 76, 65, 128, 78, 65, 66, 65, 84, 65, 69, 65, 206, + 78, 65, 65, 83, 73, 75, 89, 65, 89, 65, 128, 78, 65, 65, 75, 83, 73, 75, + 89, 65, 89, 65, 128, 78, 65, 65, 73, 128, 78, 65, 193, 78, 65, 52, 128, + 78, 65, 50, 128, 78, 65, 45, 57, 128, 78, 65, 45, 56, 128, 78, 65, 45, + 55, 128, 78, 65, 45, 54, 128, 78, 65, 45, 53, 128, 78, 65, 45, 52, 128, + 78, 65, 45, 51, 128, 78, 65, 45, 50, 128, 78, 65, 45, 49, 128, 78, 48, + 52, 50, 128, 78, 48, 52, 49, 128, 78, 48, 52, 48, 128, 78, 48, 51, 57, + 128, 78, 48, 51, 56, 128, 78, 48, 51, 55, 65, 128, 78, 48, 51, 55, 128, + 78, 48, 51, 54, 128, 78, 48, 51, 53, 65, 128, 78, 48, 51, 53, 128, 78, + 48, 51, 52, 65, 128, 78, 48, 51, 52, 128, 78, 48, 51, 51, 65, 128, 78, + 48, 51, 51, 128, 78, 48, 51, 50, 128, 78, 48, 51, 49, 128, 78, 48, 51, + 48, 128, 78, 48, 50, 57, 128, 78, 48, 50, 56, 128, 78, 48, 50, 55, 128, + 78, 48, 50, 54, 128, 78, 48, 50, 53, 65, 128, 78, 48, 50, 53, 128, 78, + 48, 50, 52, 128, 78, 48, 50, 51, 128, 78, 48, 50, 50, 128, 78, 48, 50, + 49, 128, 78, 48, 50, 48, 128, 78, 48, 49, 57, 128, 78, 48, 49, 56, 66, + 128, 78, 48, 49, 56, 65, 128, 78, 48, 49, 56, 128, 78, 48, 49, 55, 128, + 78, 48, 49, 54, 128, 78, 48, 49, 53, 128, 78, 48, 49, 52, 128, 78, 48, + 49, 51, 128, 78, 48, 49, 50, 128, 78, 48, 49, 49, 128, 78, 48, 49, 48, + 128, 78, 48, 48, 57, 128, 78, 48, 48, 56, 128, 78, 48, 48, 55, 128, 78, + 48, 48, 54, 128, 78, 48, 48, 53, 128, 78, 48, 48, 52, 128, 78, 48, 48, + 51, 128, 78, 48, 48, 50, 128, 78, 48, 48, 49, 128, 78, 45, 77, 85, 45, + 77, 79, 45, 50, 128, 78, 45, 77, 85, 45, 77, 79, 45, 49, 128, 78, 45, 67, + 82, 69, 197, 78, 45, 65, 82, 217, 77, 90, 128, 77, 89, 88, 128, 77, 89, + 84, 128, 77, 89, 83, 76, 73, 84, 69, 128, 77, 89, 80, 128, 77, 89, 65, + 128, 77, 89, 193, 77, 87, 79, 79, 128, 77, 87, 79, 128, 77, 87, 73, 73, + 128, 77, 87, 73, 128, 77, 87, 69, 69, 128, 77, 87, 69, 128, 77, 87, 65, + 65, 128, 77, 87, 65, 128, 77, 87, 128, 77, 215, 77, 86, 83, 128, 77, 86, + 79, 80, 128, 77, 86, 73, 128, 77, 86, 69, 85, 65, 69, 78, 71, 65, 77, + 128, 77, 86, 128, 77, 214, 77, 85, 88, 128, 77, 85, 85, 86, 85, 90, 72, + 65, 75, 75, 85, 128, 77, 85, 85, 83, 73, 75, 65, 84, 79, 65, 78, 128, 77, + 85, 85, 82, 68, 72, 65, 74, 193, 77, 85, 85, 128, 77, 85, 84, 72, 65, 76, + 73, 89, 65, 128, 77, 85, 84, 128, 77, 85, 83, 73, 67, 128, 77, 85, 83, + 73, 195, 77, 85, 83, 72, 82, 79, 79, 77, 128, 77, 85, 83, 72, 51, 128, + 77, 85, 83, 72, 179, 77, 85, 83, 72, 128, 77, 85, 83, 200, 77, 85, 83, + 128, 77, 85, 82, 88, 128, 77, 85, 82, 71, 85, 50, 128, 77, 85, 82, 69, + 128, 77, 85, 82, 68, 65, 128, 77, 85, 82, 68, 193, 77, 85, 82, 128, 77, + 85, 81, 68, 65, 77, 128, 77, 85, 80, 128, 77, 85, 79, 88, 128, 77, 85, + 79, 84, 128, 77, 85, 79, 80, 128, 77, 85, 79, 77, 65, 69, 128, 77, 85, + 79, 128, 77, 85, 78, 83, 85, 66, 128, 77, 85, 78, 68, 65, 82, 201, 77, + 85, 78, 65, 72, 128, 77, 85, 78, 128, 77, 85, 76, 84, 73, 83, 69, 84, 128, 77, 85, 76, 84, 73, 83, 69, 212, 77, 85, 76, 84, 73, 80, 76, 73, 67, 65, 84, 73, 79, 78, 128, 77, 85, 76, 84, 73, 80, 76, 73, 67, 65, 84, 73, 79, 206, 77, 85, 76, 84, 73, 80, 76, 69, 128, 77, 85, 76, 84, 73, 80, 76, 197, 77, 85, 76, 84, 73, 79, 67, 85, 76, 65, 210, 77, 85, 76, 84, 73, 77, 65, 80, 128, 77, 85, 76, 84, 201, 77, 85, 76, 84, 65, 78, 201, 77, 85, 75, 80, 72, 82, 69, 78, 71, 128, 77, 85, 75, 75, 85, 82, 85, 78, 73, 128, - 77, 85, 73, 78, 128, 77, 85, 71, 83, 128, 77, 85, 71, 128, 77, 85, 199, - 77, 85, 69, 78, 128, 77, 85, 69, 128, 77, 85, 67, 72, 128, 77, 85, 67, - 200, 77, 85, 67, 65, 65, 68, 128, 77, 85, 65, 83, 128, 77, 85, 65, 78, - 128, 77, 85, 65, 69, 128, 77, 85, 45, 71, 65, 65, 72, 76, 65, 193, 77, - 85, 45, 52, 128, 77, 85, 45, 51, 128, 77, 85, 45, 50, 128, 77, 85, 45, - 49, 128, 77, 213, 77, 84, 65, 86, 82, 85, 76, 201, 77, 83, 128, 77, 82, - 207, 77, 82, 65, 67, 72, 78, 89, 128, 77, 82, 65, 67, 72, 78, 79, 84, 73, - 75, 72, 65, 89, 65, 128, 77, 82, 65, 67, 72, 78, 79, 128, 77, 82, 65, 67, - 72, 78, 65, 89, 65, 128, 77, 210, 77, 81, 128, 77, 80, 65, 128, 77, 79, - 89, 65, 73, 128, 77, 79, 88, 128, 77, 79, 86, 73, 197, 77, 79, 86, 69, - 211, 77, 79, 86, 69, 77, 69, 78, 84, 45, 87, 65, 76, 76, 80, 76, 65, 78, - 197, 77, 79, 86, 69, 77, 69, 78, 84, 45, 72, 73, 78, 71, 197, 77, 79, 86, - 69, 77, 69, 78, 84, 45, 70, 76, 79, 79, 82, 80, 76, 65, 78, 197, 77, 79, - 86, 69, 77, 69, 78, 84, 45, 68, 73, 65, 71, 79, 78, 65, 204, 77, 79, 86, - 69, 77, 69, 78, 84, 128, 77, 79, 86, 69, 77, 69, 78, 212, 77, 79, 86, 69, - 196, 77, 79, 86, 69, 128, 77, 79, 85, 84, 72, 128, 77, 79, 85, 83, 69, - 128, 77, 79, 85, 83, 197, 77, 79, 85, 78, 84, 65, 73, 78, 83, 128, 77, - 79, 85, 78, 84, 65, 73, 78, 128, 77, 79, 85, 78, 84, 65, 73, 206, 77, 79, - 85, 78, 212, 77, 79, 85, 78, 68, 128, 77, 79, 85, 78, 196, 77, 79, 84, - 79, 82, 87, 65, 89, 128, 77, 79, 84, 79, 82, 73, 90, 69, 196, 77, 79, 84, - 79, 82, 67, 89, 67, 76, 69, 128, 77, 79, 84, 79, 210, 77, 79, 84, 72, 69, - 82, 128, 77, 79, 84, 72, 69, 210, 77, 79, 84, 128, 77, 79, 83, 81, 85, - 73, 84, 79, 128, 77, 79, 83, 81, 85, 69, 128, 77, 79, 82, 84, 85, 85, 77, - 128, 77, 79, 82, 84, 65, 82, 128, 77, 79, 82, 80, 72, 79, 76, 79, 71, 73, - 67, 65, 204, 77, 79, 82, 78, 73, 78, 71, 128, 77, 79, 80, 128, 77, 79, - 79, 83, 69, 45, 67, 82, 69, 197, 77, 79, 79, 78, 128, 77, 79, 79, 206, - 77, 79, 79, 77, 80, 85, 81, 128, 77, 79, 79, 77, 69, 85, 84, 128, 77, 79, - 79, 68, 128, 77, 79, 79, 196, 77, 79, 79, 128, 77, 79, 78, 84, 73, 69, - 69, 78, 128, 77, 79, 78, 84, 72, 128, 77, 79, 78, 84, 200, 77, 79, 78, - 83, 84, 69, 82, 128, 77, 79, 78, 79, 83, 84, 65, 66, 76, 197, 77, 79, 78, - 79, 83, 80, 65, 67, 197, 77, 79, 78, 79, 82, 65, 73, 76, 128, 77, 79, 78, - 79, 71, 82, 65, 80, 200, 77, 79, 78, 79, 71, 82, 65, 77, 77, 79, 211, 77, - 79, 78, 79, 71, 82, 65, 205, 77, 79, 78, 79, 70, 79, 78, 73, 65, 83, 128, - 77, 79, 78, 79, 67, 85, 76, 65, 210, 77, 79, 78, 79, 67, 76, 69, 128, 77, - 79, 78, 75, 69, 89, 128, 77, 79, 78, 75, 69, 217, 77, 79, 78, 73, 128, - 77, 79, 78, 71, 75, 69, 85, 65, 69, 81, 128, 77, 79, 78, 69, 89, 45, 77, - 79, 85, 84, 200, 77, 79, 78, 69, 217, 77, 79, 78, 128, 77, 79, 206, 77, - 79, 76, 128, 77, 79, 75, 72, 65, 83, 83, 65, 83, 128, 77, 79, 72, 65, 77, - 77, 65, 196, 77, 79, 68, 85, 76, 207, 77, 79, 68, 73, 70, 73, 69, 82, 45, - 57, 128, 77, 79, 68, 73, 70, 73, 69, 82, 45, 56, 128, 77, 79, 68, 73, 70, - 73, 69, 82, 45, 55, 128, 77, 79, 68, 73, 70, 73, 69, 82, 45, 54, 128, 77, - 79, 68, 73, 70, 73, 69, 82, 45, 53, 128, 77, 79, 68, 73, 70, 73, 69, 82, - 45, 52, 128, 77, 79, 68, 73, 70, 73, 69, 82, 45, 51, 128, 77, 79, 68, 73, - 70, 73, 69, 82, 45, 50, 128, 77, 79, 68, 73, 70, 73, 69, 82, 45, 49, 54, - 128, 77, 79, 68, 73, 70, 73, 69, 82, 45, 49, 53, 128, 77, 79, 68, 73, 70, - 73, 69, 82, 45, 49, 52, 128, 77, 79, 68, 73, 70, 73, 69, 82, 45, 49, 51, - 128, 77, 79, 68, 73, 70, 73, 69, 82, 45, 49, 50, 128, 77, 79, 68, 73, 70, - 73, 69, 82, 45, 49, 49, 128, 77, 79, 68, 73, 70, 73, 69, 82, 45, 49, 48, - 128, 77, 79, 68, 73, 70, 73, 69, 82, 128, 77, 79, 68, 201, 77, 79, 68, - 69, 83, 84, 89, 128, 77, 79, 68, 69, 82, 206, 77, 79, 68, 69, 77, 128, - 77, 79, 68, 69, 76, 83, 128, 77, 79, 68, 69, 76, 128, 77, 79, 68, 69, - 128, 77, 79, 66, 73, 76, 197, 77, 79, 65, 128, 77, 79, 45, 54, 128, 77, - 79, 45, 53, 128, 77, 79, 45, 52, 128, 77, 79, 45, 51, 128, 77, 207, 77, - 78, 89, 65, 205, 77, 78, 65, 83, 128, 77, 77, 83, 80, 128, 77, 77, 128, - 77, 205, 77, 76, 65, 128, 77, 76, 128, 77, 75, 80, 65, 82, 65, 209, 77, - 73, 88, 128, 77, 73, 84, 128, 77, 73, 83, 82, 65, 128, 77, 73, 82, 82, - 79, 82, 128, 77, 73, 82, 82, 79, 210, 77, 73, 82, 73, 66, 65, 65, 82, 85, - 128, 77, 73, 82, 73, 128, 77, 73, 82, 69, 68, 128, 77, 73, 80, 128, 77, - 73, 78, 89, 128, 77, 73, 78, 85, 83, 45, 79, 82, 45, 80, 76, 85, 211, 77, - 73, 78, 85, 83, 128, 77, 73, 78, 78, 65, 206, 77, 73, 78, 73, 83, 84, 69, - 82, 128, 77, 73, 78, 73, 77, 73, 90, 69, 128, 77, 73, 78, 73, 77, 65, - 128, 77, 73, 78, 73, 68, 73, 83, 67, 128, 77, 73, 78, 73, 66, 85, 83, - 128, 77, 73, 77, 69, 128, 77, 73, 77, 128, 77, 73, 76, 76, 73, 79, 78, - 83, 128, 77, 73, 76, 76, 73, 79, 78, 211, 77, 73, 76, 76, 69, 84, 128, - 77, 73, 76, 76, 197, 77, 73, 76, 204, 77, 73, 76, 75, 217, 77, 73, 76, - 75, 128, 77, 73, 76, 73, 84, 65, 82, 217, 77, 73, 76, 128, 77, 73, 75, - 85, 82, 79, 78, 128, 77, 73, 75, 82, 79, 206, 77, 73, 75, 82, 73, 128, - 77, 73, 73, 78, 128, 77, 73, 73, 77, 128, 77, 73, 73, 128, 77, 73, 199, - 77, 73, 69, 88, 128, 77, 73, 69, 85, 77, 45, 84, 73, 75, 69, 85, 84, 128, - 77, 73, 69, 85, 77, 45, 83, 83, 65, 78, 71, 83, 73, 79, 83, 128, 77, 73, - 69, 85, 77, 45, 83, 83, 65, 78, 71, 78, 73, 69, 85, 78, 128, 77, 73, 69, - 85, 77, 45, 82, 73, 69, 85, 76, 128, 77, 73, 69, 85, 77, 45, 80, 73, 69, - 85, 80, 45, 83, 73, 79, 83, 128, 77, 73, 69, 85, 77, 45, 80, 73, 69, 85, - 80, 128, 77, 73, 69, 85, 77, 45, 80, 65, 78, 83, 73, 79, 83, 128, 77, 73, - 69, 85, 77, 45, 78, 73, 69, 85, 78, 128, 77, 73, 69, 85, 77, 45, 67, 73, - 69, 85, 67, 128, 77, 73, 69, 85, 77, 45, 67, 72, 73, 69, 85, 67, 72, 128, - 77, 73, 69, 85, 205, 77, 73, 69, 80, 128, 77, 73, 69, 69, 128, 77, 73, - 69, 128, 77, 73, 68, 76, 73, 78, 197, 77, 73, 68, 68, 76, 69, 45, 87, 69, - 76, 83, 200, 77, 73, 68, 68, 76, 69, 128, 77, 73, 68, 45, 76, 69, 86, 69, - 204, 77, 73, 196, 77, 73, 67, 82, 79, 83, 67, 79, 80, 69, 128, 77, 73, - 67, 82, 79, 80, 72, 79, 78, 69, 128, 77, 73, 67, 82, 79, 66, 69, 128, 77, - 73, 67, 82, 207, 77, 73, 67, 210, 77, 73, 45, 55, 128, 77, 73, 45, 54, - 128, 77, 73, 45, 53, 128, 77, 73, 45, 52, 128, 77, 73, 45, 51, 128, 77, - 73, 45, 50, 128, 77, 73, 45, 49, 128, 77, 72, 90, 128, 77, 72, 65, 128, - 77, 72, 128, 77, 71, 85, 88, 128, 77, 71, 85, 84, 128, 77, 71, 85, 82, - 88, 128, 77, 71, 85, 82, 128, 77, 71, 85, 80, 128, 77, 71, 85, 79, 88, - 128, 77, 71, 85, 79, 80, 128, 77, 71, 85, 79, 128, 77, 71, 85, 128, 77, - 71, 79, 88, 128, 77, 71, 79, 84, 128, 77, 71, 79, 80, 128, 77, 71, 79, - 128, 77, 71, 207, 77, 71, 73, 69, 88, 128, 77, 71, 73, 69, 128, 77, 71, - 69, 88, 128, 77, 71, 69, 80, 128, 77, 71, 69, 128, 77, 71, 66, 85, 128, - 77, 71, 66, 79, 79, 128, 77, 71, 66, 79, 70, 85, 77, 128, 77, 71, 66, 79, - 128, 77, 71, 66, 73, 128, 77, 71, 66, 69, 85, 78, 128, 77, 71, 66, 69, - 78, 128, 77, 71, 66, 69, 69, 128, 77, 71, 66, 69, 128, 77, 71, 66, 65, - 83, 65, 81, 128, 77, 71, 66, 65, 83, 65, 128, 77, 71, 65, 88, 128, 77, - 71, 65, 84, 128, 77, 71, 65, 80, 128, 77, 71, 65, 128, 77, 71, 128, 77, - 70, 79, 78, 128, 77, 70, 79, 206, 77, 70, 79, 128, 77, 70, 73, 89, 65, - 81, 128, 77, 70, 73, 69, 69, 128, 77, 70, 69, 85, 84, 128, 77, 70, 69, - 85, 81, 128, 77, 70, 69, 85, 65, 69, 128, 77, 70, 65, 65, 128, 77, 69, - 90, 90, 79, 128, 77, 69, 88, 128, 77, 69, 85, 212, 77, 69, 85, 81, 128, - 77, 69, 85, 78, 74, 79, 77, 78, 68, 69, 85, 81, 128, 77, 69, 85, 78, 128, - 77, 69, 84, 82, 79, 128, 77, 69, 84, 82, 73, 67, 65, 204, 77, 69, 84, 82, - 73, 65, 128, 77, 69, 84, 82, 69, 84, 69, 211, 77, 69, 84, 79, 66, 69, 76, - 85, 83, 128, 77, 69, 84, 69, 75, 128, 77, 69, 84, 69, 71, 128, 77, 69, - 84, 65, 76, 128, 77, 69, 84, 193, 77, 69, 83, 83, 69, 78, 73, 65, 206, - 77, 69, 83, 83, 65, 71, 69, 128, 77, 69, 83, 83, 65, 71, 197, 77, 69, 83, - 79, 128, 77, 69, 83, 73, 128, 77, 69, 83, 72, 128, 77, 69, 82, 80, 69, - 82, 83, 79, 78, 128, 77, 69, 82, 75, 72, 65, 128, 77, 69, 82, 75, 72, - 193, 77, 69, 82, 73, 68, 73, 65, 78, 83, 128, 77, 69, 82, 73, 128, 77, - 69, 82, 71, 69, 128, 77, 69, 82, 67, 85, 82, 89, 128, 77, 69, 82, 67, 85, - 82, 217, 77, 69, 78, 79, 82, 65, 200, 77, 69, 78, 79, 69, 128, 77, 69, - 78, 68, 85, 84, 128, 77, 69, 78, 128, 77, 69, 77, 79, 128, 77, 69, 77, - 66, 69, 82, 83, 72, 73, 80, 128, 77, 69, 77, 66, 69, 82, 128, 77, 69, 77, - 66, 69, 210, 77, 69, 77, 45, 81, 79, 80, 72, 128, 77, 69, 77, 128, 77, - 69, 205, 77, 69, 76, 84, 73, 78, 199, 77, 69, 76, 79, 68, 73, 195, 77, - 69, 76, 73, 75, 128, 77, 69, 73, 90, 73, 128, 77, 69, 71, 65, 84, 79, 78, - 128, 77, 69, 71, 65, 80, 72, 79, 78, 69, 128, 77, 69, 71, 65, 76, 73, - 128, 77, 69, 69, 84, 79, 82, 85, 128, 77, 69, 69, 84, 69, 201, 77, 69, - 69, 84, 128, 77, 69, 69, 77, 85, 128, 77, 69, 69, 77, 128, 77, 69, 69, - 202, 77, 69, 69, 69, 69, 128, 77, 69, 68, 73, 85, 77, 128, 77, 69, 68, - 73, 85, 205, 77, 69, 68, 73, 69, 86, 65, 204, 77, 69, 68, 73, 67, 73, 78, - 69, 128, 77, 69, 68, 73, 67, 65, 204, 77, 69, 68, 73, 65, 204, 77, 69, - 68, 69, 70, 65, 73, 68, 82, 73, 206, 77, 69, 68, 65, 76, 128, 77, 69, 67, - 72, 73, 75, 128, 77, 69, 67, 72, 73, 203, 77, 69, 67, 72, 65, 78, 73, 67, - 65, 204, 77, 69, 65, 84, 128, 77, 69, 65, 212, 77, 69, 65, 83, 85, 82, - 69, 196, 77, 69, 65, 83, 85, 82, 69, 128, 77, 69, 65, 83, 85, 82, 197, - 77, 69, 45, 77, 65, 128, 77, 69, 45, 50, 128, 77, 69, 45, 49, 128, 77, - 68, 85, 206, 77, 196, 77, 67, 72, 213, 77, 67, 72, 65, 206, 77, 67, 128, - 77, 195, 77, 66, 85, 85, 128, 77, 66, 85, 79, 81, 128, 77, 66, 85, 79, - 128, 77, 66, 85, 69, 128, 77, 66, 85, 65, 69, 77, 128, 77, 66, 85, 65, - 69, 128, 77, 66, 79, 79, 128, 77, 66, 79, 128, 77, 66, 73, 84, 128, 77, - 66, 73, 212, 77, 66, 73, 82, 73, 69, 69, 78, 128, 77, 66, 73, 128, 77, - 66, 69, 85, 88, 128, 77, 66, 69, 85, 82, 73, 128, 77, 66, 69, 85, 77, - 128, 77, 66, 69, 82, 65, 69, 128, 77, 66, 69, 78, 128, 77, 66, 69, 69, - 75, 69, 69, 84, 128, 77, 66, 69, 69, 128, 77, 66, 69, 128, 77, 66, 65, - 81, 128, 77, 66, 65, 78, 89, 73, 128, 77, 66, 65, 65, 82, 65, 69, 128, - 77, 66, 65, 65, 75, 69, 84, 128, 77, 66, 65, 65, 128, 77, 66, 65, 193, - 77, 66, 193, 77, 66, 52, 128, 77, 66, 51, 128, 77, 66, 50, 128, 77, 65, - 89, 69, 203, 77, 65, 89, 65, 78, 78, 65, 128, 77, 65, 89, 65, 206, 77, - 65, 89, 128, 77, 65, 88, 73, 77, 73, 90, 69, 128, 77, 65, 88, 73, 77, 65, - 128, 77, 65, 88, 128, 77, 65, 85, 128, 77, 65, 84, 84, 79, 67, 75, 128, - 77, 65, 84, 82, 73, 88, 128, 77, 65, 84, 69, 82, 73, 65, 76, 83, 128, 77, - 65, 84, 128, 77, 65, 83, 213, 77, 65, 83, 83, 73, 78, 71, 128, 77, 65, - 83, 83, 65, 71, 69, 128, 77, 65, 83, 79, 82, 193, 77, 65, 83, 75, 128, - 77, 65, 83, 203, 77, 65, 83, 72, 70, 65, 65, 84, 128, 77, 65, 83, 72, 50, - 128, 77, 65, 83, 67, 85, 76, 73, 78, 197, 77, 65, 83, 65, 82, 65, 205, - 77, 65, 82, 89, 128, 77, 65, 82, 87, 65, 82, 201, 77, 65, 82, 85, 75, 85, - 128, 77, 65, 82, 84, 89, 82, 73, 193, 77, 65, 82, 84, 73, 65, 204, 77, - 65, 82, 82, 89, 73, 78, 199, 77, 65, 82, 82, 73, 65, 71, 197, 77, 65, 82, - 82, 65, 84, 65, 78, 128, 77, 65, 82, 75, 211, 77, 65, 82, 75, 69, 82, - 128, 77, 65, 82, 75, 45, 52, 128, 77, 65, 82, 75, 45, 51, 128, 77, 65, - 82, 75, 45, 50, 128, 77, 65, 82, 75, 45, 49, 128, 77, 65, 82, 69, 128, - 77, 65, 82, 67, 72, 69, 206, 77, 65, 82, 67, 72, 128, 77, 65, 82, 67, 65, - 84, 79, 45, 83, 84, 65, 67, 67, 65, 84, 79, 128, 77, 65, 82, 67, 65, 84, - 79, 128, 77, 65, 82, 67, 65, 83, 73, 84, 69, 128, 77, 65, 82, 66, 85, 84, - 65, 128, 77, 65, 82, 66, 85, 84, 193, 77, 65, 82, 128, 77, 65, 81, 65, - 70, 128, 77, 65, 81, 128, 77, 65, 80, 76, 197, 77, 65, 80, 73, 81, 128, - 77, 65, 208, 77, 65, 79, 128, 77, 65, 78, 85, 65, 204, 77, 65, 78, 84, - 69, 76, 80, 73, 69, 67, 197, 77, 65, 78, 83, 89, 79, 78, 128, 77, 65, 78, - 83, 85, 65, 69, 128, 77, 65, 78, 78, 65, 218, 77, 65, 78, 78, 65, 128, - 77, 65, 78, 73, 67, 72, 65, 69, 65, 206, 77, 65, 78, 71, 79, 128, 77, 65, - 78, 71, 65, 76, 65, 77, 128, 77, 65, 78, 68, 65, 82, 73, 78, 128, 77, 65, - 78, 68, 65, 73, 76, 73, 78, 199, 77, 65, 78, 68, 65, 73, 195, 77, 65, 78, - 67, 72, 213, 77, 65, 78, 65, 212, 77, 65, 78, 65, 67, 76, 69, 83, 128, - 77, 65, 77, 77, 79, 84, 72, 128, 77, 65, 76, 84, 69, 83, 197, 77, 65, 76, - 207, 77, 65, 76, 69, 69, 82, 73, 128, 77, 65, 76, 197, 77, 65, 76, 65, - 75, 79, 206, 77, 65, 75, 83, 85, 82, 65, 128, 77, 65, 75, 83, 85, 82, - 193, 77, 65, 75, 65, 83, 65, 210, 77, 65, 73, 90, 69, 128, 77, 65, 73, - 89, 65, 77, 79, 75, 128, 77, 65, 73, 84, 65, 73, 75, 72, 85, 128, 77, 65, - 73, 82, 85, 128, 77, 65, 73, 77, 85, 65, 78, 128, 77, 65, 73, 77, 65, 76, - 65, 73, 128, 77, 65, 73, 76, 66, 79, 216, 77, 65, 73, 75, 85, 82, 79, - 128, 77, 65, 73, 68, 69, 78, 128, 77, 65, 73, 128, 77, 65, 72, 74, 79, - 78, 199, 77, 65, 72, 72, 65, 128, 77, 65, 72, 65, 80, 82, 65, 78, 65, - 128, 77, 65, 72, 65, 80, 65, 75, 72, 128, 77, 65, 72, 65, 74, 65, 78, - 201, 77, 65, 72, 65, 65, 80, 82, 65, 65, 78, 193, 77, 65, 72, 128, 77, - 65, 71, 78, 73, 70, 89, 73, 78, 199, 77, 65, 71, 78, 69, 84, 128, 77, 65, - 71, 73, 195, 77, 65, 71, 69, 128, 77, 65, 69, 83, 73, 128, 77, 65, 69, - 78, 89, 73, 128, 77, 65, 69, 78, 74, 69, 84, 128, 77, 65, 69, 77, 86, 69, - 85, 88, 128, 77, 65, 69, 77, 75, 80, 69, 78, 128, 77, 65, 69, 77, 71, 66, - 73, 69, 69, 128, 77, 65, 69, 77, 66, 71, 66, 73, 69, 69, 128, 77, 65, 69, - 77, 66, 65, 128, 77, 65, 69, 77, 128, 77, 65, 69, 76, 69, 69, 128, 77, - 65, 69, 75, 69, 85, 80, 128, 77, 65, 68, 89, 65, 128, 77, 65, 68, 85, - 128, 77, 65, 68, 68, 65, 72, 128, 77, 65, 68, 68, 65, 200, 77, 65, 68, - 68, 65, 128, 77, 65, 68, 68, 193, 77, 65, 67, 82, 79, 78, 45, 71, 82, 65, - 86, 69, 128, 77, 65, 67, 82, 79, 78, 45, 66, 82, 69, 86, 69, 128, 77, 65, - 67, 82, 79, 78, 45, 65, 67, 85, 84, 69, 128, 77, 65, 67, 82, 79, 78, 128, - 77, 65, 67, 82, 79, 206, 77, 65, 67, 72, 73, 78, 69, 128, 77, 65, 65, 89, - 89, 65, 65, 128, 77, 65, 65, 73, 128, 77, 65, 65, 128, 77, 65, 50, 128, - 77, 65, 45, 55, 128, 77, 65, 45, 54, 128, 77, 65, 45, 53, 128, 77, 65, - 45, 52, 128, 77, 65, 45, 51, 128, 77, 65, 45, 50, 128, 77, 65, 45, 49, - 128, 77, 49, 57, 183, 77, 49, 57, 182, 77, 49, 57, 181, 77, 49, 57, 180, - 77, 49, 57, 179, 77, 49, 57, 178, 77, 49, 57, 177, 77, 49, 57, 176, 77, - 49, 56, 185, 77, 49, 56, 184, 77, 49, 56, 183, 77, 49, 56, 182, 77, 49, - 56, 181, 77, 49, 56, 180, 77, 49, 56, 179, 77, 49, 56, 178, 77, 49, 56, - 177, 77, 49, 56, 176, 77, 49, 55, 185, 77, 49, 55, 184, 77, 49, 55, 183, - 77, 49, 55, 182, 77, 49, 55, 181, 77, 49, 55, 180, 77, 49, 55, 179, 77, - 49, 55, 178, 77, 49, 55, 177, 77, 49, 55, 176, 77, 49, 54, 185, 77, 49, - 54, 184, 77, 49, 54, 183, 77, 49, 54, 182, 77, 49, 54, 181, 77, 49, 54, - 180, 77, 49, 54, 179, 77, 49, 54, 178, 77, 49, 54, 177, 77, 49, 54, 176, - 77, 49, 53, 185, 77, 49, 53, 184, 77, 49, 53, 183, 77, 49, 53, 182, 77, - 49, 53, 181, 77, 49, 53, 180, 77, 49, 53, 179, 77, 49, 53, 178, 77, 49, - 53, 177, 77, 49, 53, 176, 77, 49, 52, 185, 77, 49, 52, 184, 77, 49, 52, - 183, 77, 49, 52, 182, 77, 49, 52, 181, 77, 49, 52, 180, 77, 49, 52, 179, - 77, 49, 52, 178, 77, 49, 52, 177, 77, 49, 52, 176, 77, 49, 51, 185, 77, - 49, 51, 184, 77, 49, 51, 183, 77, 49, 51, 182, 77, 49, 51, 181, 77, 49, - 51, 180, 77, 49, 51, 179, 77, 49, 51, 178, 77, 49, 51, 177, 77, 49, 51, - 176, 77, 49, 50, 185, 77, 49, 50, 184, 77, 49, 50, 183, 77, 49, 50, 182, - 77, 49, 50, 181, 77, 49, 50, 180, 77, 49, 50, 179, 77, 49, 50, 178, 77, - 49, 50, 177, 77, 49, 50, 176, 77, 49, 49, 185, 77, 49, 49, 184, 77, 49, - 49, 183, 77, 49, 49, 182, 77, 49, 49, 181, 77, 49, 49, 180, 77, 49, 49, - 179, 77, 49, 49, 178, 77, 49, 49, 177, 77, 49, 49, 176, 77, 49, 48, 185, - 77, 49, 48, 184, 77, 49, 48, 183, 77, 49, 48, 182, 77, 49, 48, 181, 77, - 49, 48, 180, 77, 49, 48, 179, 77, 49, 48, 178, 77, 49, 48, 177, 77, 49, - 48, 176, 77, 48, 57, 185, 77, 48, 57, 184, 77, 48, 57, 183, 77, 48, 57, - 182, 77, 48, 57, 181, 77, 48, 57, 180, 77, 48, 57, 179, 77, 48, 57, 178, - 77, 48, 57, 177, 77, 48, 57, 176, 77, 48, 56, 185, 77, 48, 56, 184, 77, - 48, 56, 183, 77, 48, 56, 182, 77, 48, 56, 181, 77, 48, 56, 180, 77, 48, - 56, 179, 77, 48, 56, 178, 77, 48, 56, 177, 77, 48, 56, 176, 77, 48, 55, - 185, 77, 48, 55, 184, 77, 48, 55, 183, 77, 48, 55, 182, 77, 48, 55, 181, - 77, 48, 55, 180, 77, 48, 55, 179, 77, 48, 55, 178, 77, 48, 55, 177, 77, - 48, 55, 176, 77, 48, 54, 185, 77, 48, 54, 184, 77, 48, 54, 183, 77, 48, - 54, 182, 77, 48, 54, 181, 77, 48, 54, 180, 77, 48, 54, 179, 77, 48, 54, - 178, 77, 48, 54, 177, 77, 48, 54, 176, 77, 48, 53, 185, 77, 48, 53, 184, - 77, 48, 53, 183, 77, 48, 53, 182, 77, 48, 53, 181, 77, 48, 53, 180, 77, - 48, 53, 179, 77, 48, 53, 178, 77, 48, 53, 177, 77, 48, 53, 176, 77, 48, - 52, 185, 77, 48, 52, 184, 77, 48, 52, 183, 77, 48, 52, 182, 77, 48, 52, - 181, 77, 48, 52, 52, 128, 77, 48, 52, 180, 77, 48, 52, 51, 128, 77, 48, - 52, 179, 77, 48, 52, 50, 128, 77, 48, 52, 178, 77, 48, 52, 49, 128, 77, - 48, 52, 177, 77, 48, 52, 48, 65, 128, 77, 48, 52, 48, 128, 77, 48, 52, - 176, 77, 48, 51, 57, 128, 77, 48, 51, 185, 77, 48, 51, 56, 128, 77, 48, - 51, 184, 77, 48, 51, 55, 128, 77, 48, 51, 183, 77, 48, 51, 54, 128, 77, - 48, 51, 182, 77, 48, 51, 53, 128, 77, 48, 51, 181, 77, 48, 51, 52, 128, - 77, 48, 51, 180, 77, 48, 51, 51, 66, 128, 77, 48, 51, 51, 65, 128, 77, - 48, 51, 51, 128, 77, 48, 51, 179, 77, 48, 51, 50, 128, 77, 48, 51, 178, - 77, 48, 51, 49, 65, 128, 77, 48, 51, 49, 128, 77, 48, 51, 177, 77, 48, - 51, 48, 128, 77, 48, 51, 176, 77, 48, 50, 57, 128, 77, 48, 50, 185, 77, - 48, 50, 56, 65, 128, 77, 48, 50, 56, 128, 77, 48, 50, 184, 77, 48, 50, - 55, 128, 77, 48, 50, 183, 77, 48, 50, 54, 128, 77, 48, 50, 182, 77, 48, - 50, 53, 128, 77, 48, 50, 181, 77, 48, 50, 52, 65, 128, 77, 48, 50, 52, - 128, 77, 48, 50, 180, 77, 48, 50, 51, 128, 77, 48, 50, 179, 77, 48, 50, - 50, 65, 128, 77, 48, 50, 50, 128, 77, 48, 50, 178, 77, 48, 50, 49, 128, - 77, 48, 50, 177, 77, 48, 50, 48, 128, 77, 48, 50, 176, 77, 48, 49, 57, - 128, 77, 48, 49, 185, 77, 48, 49, 56, 128, 77, 48, 49, 184, 77, 48, 49, - 55, 65, 128, 77, 48, 49, 55, 128, 77, 48, 49, 183, 77, 48, 49, 54, 65, - 128, 77, 48, 49, 54, 128, 77, 48, 49, 182, 77, 48, 49, 53, 65, 128, 77, - 48, 49, 53, 128, 77, 48, 49, 181, 77, 48, 49, 52, 128, 77, 48, 49, 180, - 77, 48, 49, 51, 128, 77, 48, 49, 179, 77, 48, 49, 50, 72, 128, 77, 48, - 49, 50, 71, 128, 77, 48, 49, 50, 70, 128, 77, 48, 49, 50, 69, 128, 77, - 48, 49, 50, 68, 128, 77, 48, 49, 50, 67, 128, 77, 48, 49, 50, 66, 128, - 77, 48, 49, 50, 65, 128, 77, 48, 49, 50, 128, 77, 48, 49, 178, 77, 48, - 49, 49, 128, 77, 48, 49, 177, 77, 48, 49, 48, 65, 128, 77, 48, 49, 48, - 128, 77, 48, 49, 176, 77, 48, 48, 57, 128, 77, 48, 48, 185, 77, 48, 48, - 56, 128, 77, 48, 48, 184, 77, 48, 48, 55, 128, 77, 48, 48, 183, 77, 48, - 48, 54, 128, 77, 48, 48, 182, 77, 48, 48, 53, 128, 77, 48, 48, 181, 77, - 48, 48, 52, 128, 77, 48, 48, 180, 77, 48, 48, 51, 65, 128, 77, 48, 48, - 51, 128, 77, 48, 48, 179, 77, 48, 48, 50, 128, 77, 48, 48, 178, 77, 48, - 48, 49, 66, 128, 77, 48, 48, 49, 65, 128, 77, 48, 48, 49, 128, 77, 48, - 48, 177, 76, 218, 76, 89, 89, 128, 76, 89, 88, 128, 76, 89, 84, 128, 76, - 89, 82, 88, 128, 76, 89, 82, 128, 76, 89, 80, 128, 76, 89, 73, 84, 128, - 76, 89, 73, 78, 199, 76, 89, 68, 73, 65, 206, 76, 89, 67, 73, 65, 206, - 76, 88, 128, 76, 87, 79, 79, 128, 76, 87, 79, 128, 76, 87, 73, 73, 128, - 76, 87, 73, 128, 76, 87, 69, 128, 76, 87, 65, 65, 128, 76, 87, 65, 128, - 76, 85, 88, 128, 76, 85, 85, 128, 76, 85, 84, 128, 76, 85, 82, 88, 128, - 76, 85, 80, 128, 76, 85, 79, 88, 128, 76, 85, 79, 84, 128, 76, 85, 79, - 80, 128, 76, 85, 79, 128, 76, 85, 78, 71, 83, 73, 128, 76, 85, 78, 71, - 83, 128, 76, 85, 78, 65, 84, 197, 76, 85, 205, 76, 85, 76, 128, 76, 85, - 73, 83, 128, 76, 85, 72, 85, 82, 128, 76, 85, 72, 128, 76, 85, 200, 76, - 85, 71, 71, 65, 71, 69, 128, 76, 85, 71, 65, 76, 128, 76, 85, 71, 65, - 204, 76, 85, 69, 128, 76, 85, 197, 76, 85, 66, 128, 76, 85, 65, 69, 80, - 128, 76, 85, 51, 128, 76, 85, 50, 128, 76, 85, 178, 76, 82, 79, 128, 76, - 82, 77, 128, 76, 82, 73, 128, 76, 82, 69, 128, 76, 79, 90, 69, 78, 71, - 69, 128, 76, 79, 90, 69, 78, 71, 197, 76, 79, 88, 128, 76, 79, 87, 69, - 82, 69, 196, 76, 79, 87, 45, 82, 69, 86, 69, 82, 83, 69, 68, 45, 185, 76, - 79, 87, 45, 77, 73, 196, 76, 79, 87, 45, 70, 65, 76, 76, 73, 78, 199, 76, - 79, 87, 45, 185, 76, 79, 86, 197, 76, 79, 85, 82, 69, 128, 76, 79, 85, - 68, 83, 80, 69, 65, 75, 69, 82, 128, 76, 79, 85, 68, 76, 217, 76, 79, 84, - 85, 83, 128, 76, 79, 84, 85, 211, 76, 79, 84, 73, 79, 206, 76, 79, 84, - 128, 76, 79, 83, 83, 76, 69, 83, 83, 128, 76, 79, 82, 82, 89, 128, 76, - 79, 82, 82, 65, 73, 78, 69, 128, 76, 79, 81, 128, 76, 79, 80, 128, 76, - 79, 79, 84, 128, 76, 79, 79, 80, 69, 196, 76, 79, 79, 80, 128, 76, 79, - 79, 208, 76, 79, 79, 78, 128, 76, 79, 79, 203, 76, 79, 79, 128, 76, 79, - 78, 83, 85, 77, 128, 76, 79, 78, 71, 65, 128, 76, 79, 78, 71, 193, 76, - 79, 78, 71, 45, 76, 69, 71, 71, 69, 196, 76, 79, 78, 71, 45, 66, 82, 65, - 78, 67, 72, 45, 89, 82, 128, 76, 79, 78, 71, 45, 66, 82, 65, 78, 67, 72, - 45, 83, 79, 204, 76, 79, 78, 71, 45, 66, 82, 65, 78, 67, 72, 45, 79, 83, - 211, 76, 79, 78, 71, 45, 66, 82, 65, 78, 67, 72, 45, 77, 65, 68, 210, 76, - 79, 78, 71, 45, 66, 82, 65, 78, 67, 72, 45, 72, 65, 71, 65, 76, 204, 76, - 79, 78, 71, 45, 66, 82, 65, 78, 67, 72, 45, 65, 210, 76, 79, 77, 77, 65, - 69, 128, 76, 79, 77, 75, 65, 128, 76, 79, 77, 128, 76, 79, 205, 76, 79, - 76, 76, 73, 80, 79, 80, 128, 76, 79, 76, 76, 128, 76, 79, 71, 210, 76, - 79, 71, 79, 84, 89, 80, 197, 76, 79, 71, 79, 71, 82, 65, 205, 76, 79, 71, - 128, 76, 79, 68, 69, 83, 84, 79, 78, 69, 128, 76, 79, 67, 79, 77, 79, 84, - 73, 86, 69, 128, 76, 79, 67, 75, 73, 78, 71, 45, 83, 72, 73, 70, 212, 76, - 79, 67, 65, 84, 73, 86, 69, 128, 76, 79, 67, 65, 84, 73, 79, 78, 45, 87, - 65, 76, 76, 80, 76, 65, 78, 197, 76, 79, 67, 65, 84, 73, 79, 78, 45, 70, - 76, 79, 79, 82, 80, 76, 65, 78, 197, 76, 79, 67, 65, 84, 73, 79, 78, 128, - 76, 79, 67, 65, 84, 73, 79, 206, 76, 79, 66, 83, 84, 69, 82, 128, 76, 79, - 65, 128, 76, 78, 128, 76, 76, 85, 85, 128, 76, 76, 79, 79, 128, 76, 76, - 76, 85, 85, 128, 76, 76, 76, 85, 128, 76, 76, 76, 79, 79, 128, 76, 76, - 76, 79, 128, 76, 76, 76, 73, 73, 128, 76, 76, 76, 73, 128, 76, 76, 76, - 69, 69, 128, 76, 76, 76, 69, 128, 76, 76, 76, 65, 85, 128, 76, 76, 76, - 65, 73, 128, 76, 76, 76, 65, 65, 128, 76, 76, 76, 65, 128, 76, 76, 76, - 128, 76, 76, 72, 65, 128, 76, 76, 65, 77, 65, 128, 76, 74, 85, 68, 73, - 74, 69, 128, 76, 74, 69, 128, 76, 74, 128, 76, 73, 90, 65, 82, 68, 128, - 76, 73, 88, 128, 76, 73, 87, 78, 128, 76, 73, 86, 82, 197, 76, 73, 84, - 84, 76, 69, 128, 76, 73, 84, 84, 76, 197, 76, 73, 84, 84, 69, 210, 76, - 73, 84, 82, 193, 76, 73, 84, 200, 76, 73, 83, 213, 76, 73, 83, 128, 76, - 73, 82, 193, 76, 73, 81, 85, 73, 68, 128, 76, 73, 81, 85, 73, 196, 76, - 73, 81, 128, 76, 73, 80, 83, 84, 73, 67, 75, 128, 76, 73, 80, 211, 76, - 73, 208, 76, 73, 78, 75, 73, 78, 199, 76, 73, 78, 75, 69, 196, 76, 73, - 78, 203, 76, 73, 78, 71, 83, 65, 128, 76, 73, 78, 69, 83, 128, 76, 73, - 78, 69, 211, 76, 73, 78, 69, 45, 57, 128, 76, 73, 78, 69, 45, 55, 128, - 76, 73, 78, 69, 45, 51, 128, 76, 73, 78, 69, 45, 49, 128, 76, 73, 77, 77, - 85, 52, 128, 76, 73, 77, 77, 85, 50, 128, 76, 73, 77, 77, 85, 128, 76, - 73, 77, 77, 213, 76, 73, 77, 73, 84, 69, 196, 76, 73, 77, 73, 84, 65, 84, - 73, 79, 78, 128, 76, 73, 77, 73, 84, 128, 76, 73, 77, 69, 128, 76, 73, - 77, 66, 213, 76, 73, 77, 66, 211, 76, 73, 77, 194, 76, 73, 76, 89, 128, - 76, 73, 76, 73, 84, 72, 128, 76, 73, 76, 128, 76, 73, 71, 72, 84, 78, 73, - 78, 71, 128, 76, 73, 71, 72, 84, 78, 73, 78, 199, 76, 73, 71, 72, 84, 72, - 79, 85, 83, 69, 128, 76, 73, 71, 72, 84, 128, 76, 73, 71, 65, 84, 73, 78, - 199, 76, 73, 70, 84, 69, 82, 128, 76, 73, 70, 69, 128, 76, 73, 69, 88, - 128, 76, 73, 69, 84, 128, 76, 73, 69, 80, 128, 76, 73, 69, 69, 128, 76, - 73, 69, 128, 76, 73, 68, 128, 76, 73, 67, 75, 73, 78, 199, 76, 73, 66, - 82, 65, 128, 76, 73, 66, 69, 82, 84, 89, 128, 76, 73, 65, 66, 73, 76, 73, - 84, 217, 76, 72, 73, 73, 128, 76, 72, 65, 86, 73, 89, 65, 78, 73, 128, - 76, 72, 65, 199, 76, 72, 65, 65, 128, 76, 72, 128, 76, 69, 90, 72, 128, - 76, 69, 90, 200, 76, 69, 88, 128, 76, 69, 86, 73, 84, 65, 84, 73, 78, 71, - 128, 76, 69, 86, 69, 76, 45, 51, 128, 76, 69, 86, 69, 76, 45, 50, 128, - 76, 69, 85, 77, 128, 76, 69, 85, 65, 69, 80, 128, 76, 69, 85, 65, 69, 77, - 128, 76, 69, 85, 128, 76, 69, 213, 76, 69, 84, 84, 69, 82, 83, 128, 76, - 69, 84, 84, 69, 82, 128, 76, 69, 212, 76, 69, 83, 83, 69, 210, 76, 69, - 83, 83, 45, 84, 72, 65, 78, 128, 76, 69, 83, 83, 45, 84, 72, 65, 206, 76, - 69, 83, 72, 128, 76, 69, 80, 67, 72, 193, 76, 69, 80, 128, 76, 69, 79, - 80, 65, 82, 68, 128, 76, 69, 79, 128, 76, 69, 78, 84, 73, 67, 85, 76, 65, - 210, 76, 69, 78, 73, 83, 128, 76, 69, 78, 73, 211, 76, 69, 78, 71, 84, - 72, 69, 78, 69, 82, 128, 76, 69, 78, 71, 84, 72, 45, 55, 128, 76, 69, 78, - 71, 84, 72, 45, 54, 128, 76, 69, 78, 71, 84, 72, 45, 53, 128, 76, 69, 78, - 71, 84, 72, 45, 52, 128, 76, 69, 78, 71, 84, 72, 45, 51, 128, 76, 69, 78, - 71, 84, 72, 45, 50, 128, 76, 69, 78, 71, 84, 72, 45, 49, 128, 76, 69, 78, - 71, 84, 200, 76, 69, 78, 71, 65, 128, 76, 69, 78, 71, 193, 76, 69, 77, - 79, 78, 128, 76, 69, 77, 79, 73, 128, 76, 69, 76, 69, 84, 128, 76, 69, - 76, 69, 212, 76, 69, 203, 76, 69, 73, 77, 77, 65, 128, 76, 69, 73, 77, - 77, 193, 76, 69, 73, 128, 76, 69, 71, 83, 128, 76, 69, 71, 73, 79, 78, - 128, 76, 69, 71, 69, 84, 79, 211, 76, 69, 71, 128, 76, 69, 199, 76, 69, - 70, 84, 87, 65, 82, 68, 83, 128, 76, 69, 70, 84, 45, 84, 79, 45, 82, 73, - 71, 72, 212, 76, 69, 70, 84, 45, 83, 84, 69, 205, 76, 69, 70, 84, 45, 83, - 73, 68, 197, 76, 69, 70, 84, 45, 83, 72, 65, 68, 69, 196, 76, 69, 70, 84, - 45, 80, 79, 73, 78, 84, 73, 78, 199, 76, 69, 70, 84, 45, 76, 73, 71, 72, - 84, 69, 196, 76, 69, 70, 84, 45, 72, 65, 78, 68, 69, 196, 76, 69, 70, 84, - 45, 72, 65, 78, 196, 76, 69, 70, 84, 45, 70, 65, 67, 73, 78, 199, 76, 69, - 70, 84, 128, 76, 69, 69, 82, 65, 69, 87, 65, 128, 76, 69, 69, 75, 128, - 76, 69, 69, 69, 69, 128, 76, 69, 68, 71, 69, 82, 128, 76, 69, 65, 84, 72, - 69, 82, 128, 76, 69, 65, 78, 73, 78, 199, 76, 69, 65, 70, 217, 76, 69, - 65, 70, 128, 76, 69, 65, 198, 76, 69, 65, 68, 69, 82, 128, 76, 69, 65, - 196, 76, 68, 65, 78, 128, 76, 68, 50, 128, 76, 67, 201, 76, 67, 197, 76, - 65, 90, 217, 76, 65, 89, 65, 78, 78, 65, 128, 76, 65, 88, 128, 76, 65, - 87, 128, 76, 65, 215, 76, 65, 85, 76, 65, 128, 76, 65, 85, 75, 65, 218, - 76, 65, 85, 74, 128, 76, 65, 85, 71, 72, 73, 78, 71, 128, 76, 65, 84, 73, - 78, 65, 84, 197, 76, 65, 84, 73, 75, 128, 76, 65, 84, 69, 82, 65, 204, - 76, 65, 84, 197, 76, 65, 83, 212, 76, 65, 82, 89, 78, 71, 69, 65, 204, - 76, 65, 82, 201, 76, 65, 82, 71, 69, 83, 84, 128, 76, 65, 82, 71, 69, - 210, 76, 65, 82, 71, 69, 128, 76, 65, 82, 71, 197, 76, 65, 81, 128, 76, - 65, 80, 65, 81, 128, 76, 65, 207, 76, 65, 78, 84, 69, 82, 78, 128, 76, - 65, 78, 84, 65, 78, 71, 128, 76, 65, 78, 71, 85, 65, 71, 197, 76, 65, 78, - 69, 83, 128, 76, 65, 78, 196, 76, 65, 78, 128, 76, 65, 77, 80, 128, 76, - 65, 77, 69, 68, 72, 128, 76, 65, 77, 69, 68, 128, 76, 65, 77, 69, 196, - 76, 65, 77, 69, 128, 76, 65, 77, 197, 76, 65, 77, 68, 65, 128, 76, 65, - 77, 68, 128, 76, 65, 77, 66, 68, 193, 76, 65, 77, 65, 68, 72, 128, 76, - 65, 76, 128, 76, 65, 204, 76, 65, 75, 75, 72, 65, 78, 71, 89, 65, 79, - 128, 76, 65, 75, 72, 65, 78, 128, 76, 65, 75, 72, 128, 76, 65, 75, 200, - 76, 65, 75, 45, 55, 52, 57, 128, 76, 65, 75, 45, 55, 50, 52, 128, 76, 65, - 75, 45, 54, 54, 56, 128, 76, 65, 75, 45, 54, 52, 56, 128, 76, 65, 75, 45, - 54, 52, 184, 76, 65, 75, 45, 54, 51, 54, 128, 76, 65, 75, 45, 54, 49, 55, - 128, 76, 65, 75, 45, 54, 49, 183, 76, 65, 75, 45, 54, 48, 56, 128, 76, - 65, 75, 45, 53, 53, 48, 128, 76, 65, 75, 45, 52, 57, 53, 128, 76, 65, 75, - 45, 52, 57, 51, 128, 76, 65, 75, 45, 52, 57, 50, 128, 76, 65, 75, 45, 52, - 57, 48, 128, 76, 65, 75, 45, 52, 56, 51, 128, 76, 65, 75, 45, 52, 55, 48, - 128, 76, 65, 75, 45, 52, 53, 55, 128, 76, 65, 75, 45, 52, 53, 48, 128, - 76, 65, 75, 45, 52, 52, 57, 128, 76, 65, 75, 45, 52, 52, 185, 76, 65, 75, - 45, 52, 52, 49, 128, 76, 65, 75, 45, 51, 57, 48, 128, 76, 65, 75, 45, 51, - 56, 52, 128, 76, 65, 75, 45, 51, 56, 51, 128, 76, 65, 75, 45, 51, 52, 56, - 128, 76, 65, 75, 45, 51, 52, 55, 128, 76, 65, 75, 45, 51, 52, 51, 128, - 76, 65, 75, 45, 50, 54, 54, 128, 76, 65, 75, 45, 50, 54, 53, 128, 76, 65, - 75, 45, 50, 51, 56, 128, 76, 65, 75, 45, 50, 50, 56, 128, 76, 65, 75, 45, - 50, 50, 53, 128, 76, 65, 75, 45, 50, 50, 48, 128, 76, 65, 75, 45, 50, 49, - 57, 128, 76, 65, 75, 45, 50, 49, 48, 128, 76, 65, 75, 45, 49, 52, 50, - 128, 76, 65, 75, 45, 49, 51, 48, 128, 76, 65, 75, 45, 48, 57, 50, 128, - 76, 65, 75, 45, 48, 56, 49, 128, 76, 65, 75, 45, 48, 56, 177, 76, 65, 75, - 45, 48, 56, 48, 128, 76, 65, 75, 45, 48, 55, 185, 76, 65, 75, 45, 48, 54, - 50, 128, 76, 65, 75, 45, 48, 53, 49, 128, 76, 65, 75, 45, 48, 53, 48, - 128, 76, 65, 75, 45, 48, 51, 48, 128, 76, 65, 75, 45, 48, 50, 53, 128, - 76, 65, 75, 45, 48, 50, 49, 128, 76, 65, 75, 45, 48, 50, 48, 128, 76, 65, - 75, 45, 48, 48, 51, 128, 76, 65, 74, 65, 78, 89, 65, 76, 65, 78, 128, 76, - 65, 73, 78, 199, 76, 65, 201, 76, 65, 72, 83, 72, 85, 128, 76, 65, 72, - 128, 76, 65, 71, 85, 83, 128, 76, 65, 71, 213, 76, 65, 71, 65, 82, 128, - 76, 65, 71, 65, 210, 76, 65, 71, 65, 66, 128, 76, 65, 71, 65, 194, 76, - 65, 69, 86, 128, 76, 65, 69, 128, 76, 65, 68, 217, 76, 65, 68, 68, 69, - 82, 128, 76, 65, 67, 82, 79, 83, 83, 197, 76, 65, 67, 75, 128, 76, 65, - 67, 65, 128, 76, 65, 66, 79, 85, 82, 73, 78, 71, 128, 76, 65, 66, 79, 82, - 128, 76, 65, 66, 73, 65, 76, 73, 90, 65, 84, 73, 79, 206, 76, 65, 66, 73, - 65, 204, 76, 65, 66, 69, 76, 128, 76, 65, 66, 65, 84, 128, 76, 65, 194, - 76, 65, 65, 78, 65, 69, 128, 76, 65, 65, 78, 128, 76, 65, 65, 77, 85, - 128, 76, 65, 65, 73, 128, 76, 54, 128, 76, 52, 128, 76, 51, 128, 76, 50, - 128, 76, 48, 48, 54, 65, 128, 76, 48, 48, 50, 65, 128, 76, 45, 84, 89, - 80, 197, 76, 45, 83, 72, 65, 80, 69, 196, 75, 89, 85, 82, 73, 73, 128, - 75, 89, 85, 128, 75, 89, 79, 128, 75, 89, 76, 73, 83, 77, 65, 128, 75, - 89, 73, 128, 75, 89, 69, 128, 75, 89, 65, 84, 72, 79, 211, 75, 89, 65, - 65, 128, 75, 89, 65, 128, 75, 88, 87, 73, 128, 75, 88, 87, 69, 69, 128, - 75, 88, 87, 69, 128, 75, 88, 87, 65, 65, 128, 75, 88, 87, 65, 128, 75, - 88, 85, 128, 75, 88, 79, 128, 75, 88, 73, 128, 75, 88, 69, 69, 128, 75, - 88, 69, 128, 75, 88, 65, 65, 128, 75, 88, 65, 128, 75, 87, 86, 128, 75, - 87, 85, 51, 49, 56, 128, 75, 87, 79, 79, 128, 75, 87, 79, 128, 75, 87, - 77, 128, 75, 87, 73, 73, 128, 75, 87, 73, 128, 75, 87, 69, 69, 128, 75, - 87, 69, 128, 75, 87, 66, 128, 75, 87, 65, 89, 128, 75, 87, 65, 69, 84, - 128, 75, 87, 65, 65, 128, 75, 86, 65, 128, 75, 86, 128, 75, 85, 90, 72, - 73, 128, 75, 85, 88, 128, 75, 85, 86, 128, 75, 85, 85, 72, 128, 75, 85, - 84, 128, 75, 85, 83, 77, 65, 128, 75, 85, 83, 72, 85, 50, 128, 75, 85, - 83, 72, 85, 178, 75, 85, 82, 88, 128, 75, 85, 82, 85, 90, 69, 73, 82, 79, - 128, 75, 85, 82, 84, 128, 75, 85, 82, 79, 79, 78, 69, 128, 75, 85, 82, - 128, 75, 85, 210, 75, 85, 81, 128, 75, 85, 80, 78, 65, 89, 65, 128, 75, - 85, 79, 88, 128, 75, 85, 79, 80, 128, 75, 85, 79, 208, 75, 85, 79, 77, - 128, 75, 85, 79, 128, 75, 85, 78, 71, 128, 75, 85, 78, 68, 68, 65, 76, - 73, 89, 65, 128, 75, 85, 76, 128, 75, 85, 204, 75, 85, 71, 128, 75, 85, - 70, 73, 83, 77, 65, 128, 75, 85, 69, 84, 128, 75, 85, 66, 128, 75, 85, - 65, 86, 128, 75, 85, 65, 66, 128, 75, 85, 65, 128, 75, 85, 55, 128, 75, - 85, 52, 128, 75, 85, 180, 75, 85, 51, 128, 75, 85, 179, 75, 85, 45, 55, - 128, 75, 85, 45, 54, 128, 75, 85, 45, 53, 128, 75, 85, 45, 52, 128, 75, - 85, 45, 51, 128, 75, 85, 45, 50, 128, 75, 85, 45, 49, 128, 75, 84, 128, - 75, 83, 83, 85, 85, 128, 75, 83, 83, 85, 128, 75, 83, 83, 79, 79, 128, - 75, 83, 83, 79, 128, 75, 83, 83, 73, 73, 128, 75, 83, 83, 73, 128, 75, - 83, 83, 69, 69, 128, 75, 83, 83, 69, 128, 75, 83, 83, 65, 85, 128, 75, - 83, 83, 65, 73, 128, 75, 83, 83, 65, 65, 128, 75, 83, 83, 65, 128, 75, - 83, 83, 128, 75, 83, 73, 128, 75, 82, 89, 90, 72, 69, 86, 65, 89, 65, - 128, 75, 82, 89, 90, 72, 69, 77, 128, 75, 82, 89, 90, 72, 69, 205, 75, - 82, 89, 90, 72, 128, 75, 82, 89, 90, 200, 75, 82, 89, 85, 75, 79, 86, 65, - 89, 65, 128, 75, 82, 89, 85, 75, 79, 86, 65, 89, 193, 75, 82, 89, 85, 75, - 128, 75, 82, 89, 85, 203, 75, 82, 79, 78, 79, 83, 128, 75, 82, 69, 77, - 65, 83, 84, 73, 128, 75, 82, 65, 84, 73, 77, 79, 89, 80, 79, 82, 82, 79, - 79, 78, 128, 75, 82, 65, 84, 73, 77, 79, 75, 79, 85, 70, 73, 83, 77, 65, - 128, 75, 82, 65, 84, 73, 77, 65, 84, 65, 128, 75, 82, 65, 84, 73, 77, - 193, 75, 80, 85, 128, 75, 80, 79, 81, 128, 75, 80, 79, 79, 128, 75, 80, - 79, 128, 75, 80, 73, 128, 75, 80, 69, 85, 88, 128, 75, 80, 69, 69, 128, - 75, 80, 69, 128, 75, 80, 65, 82, 65, 81, 128, 75, 80, 65, 78, 128, 75, - 80, 65, 72, 128, 75, 80, 65, 128, 75, 80, 128, 75, 79, 88, 128, 75, 79, - 86, 85, 85, 128, 75, 79, 86, 128, 75, 79, 84, 79, 128, 75, 79, 82, 85, - 78, 65, 128, 75, 79, 82, 79, 78, 73, 83, 128, 75, 79, 82, 79, 78, 128, - 75, 79, 82, 69, 65, 206, 75, 79, 82, 65, 78, 73, 195, 75, 79, 81, 78, 68, - 79, 78, 128, 75, 79, 80, 80, 65, 128, 75, 79, 80, 128, 75, 79, 79, 86, - 128, 75, 79, 79, 80, 79, 128, 75, 79, 79, 77, 85, 85, 84, 128, 75, 79, - 79, 66, 128, 75, 79, 79, 128, 75, 79, 78, 84, 69, 86, 77, 65, 128, 75, - 79, 78, 84, 69, 86, 77, 193, 75, 79, 77, 201, 75, 79, 77, 66, 85, 86, 65, - 128, 75, 79, 77, 66, 85, 86, 193, 75, 79, 77, 66, 213, 75, 79, 75, 79, - 128, 75, 79, 75, 69, 128, 75, 79, 75, 128, 75, 79, 203, 75, 79, 73, 78, - 73, 128, 75, 79, 73, 128, 75, 79, 201, 75, 79, 72, 128, 75, 79, 71, 72, - 79, 77, 128, 75, 79, 69, 84, 128, 75, 79, 66, 89, 76, 65, 128, 75, 79, - 66, 128, 75, 79, 65, 76, 65, 128, 75, 79, 65, 128, 75, 79, 45, 75, 73, - 128, 75, 79, 45, 51, 128, 75, 79, 45, 50, 128, 75, 79, 45, 49, 128, 75, - 78, 85, 67, 75, 76, 69, 83, 128, 75, 78, 85, 67, 75, 76, 69, 128, 75, 78, - 79, 84, 128, 75, 78, 79, 66, 83, 128, 75, 78, 73, 71, 72, 84, 45, 82, 79, - 79, 75, 128, 75, 78, 73, 71, 72, 84, 45, 81, 85, 69, 69, 78, 128, 75, 78, - 73, 71, 72, 84, 45, 66, 73, 83, 72, 79, 80, 128, 75, 78, 73, 71, 72, 84, - 128, 75, 78, 73, 71, 72, 212, 75, 78, 73, 70, 69, 128, 75, 78, 73, 70, - 197, 75, 78, 69, 69, 76, 73, 78, 199, 75, 77, 128, 75, 205, 75, 76, 89, - 85, 67, 72, 69, 86, 79, 89, 128, 75, 76, 89, 85, 67, 72, 69, 86, 65, 89, - 65, 128, 75, 76, 89, 85, 67, 72, 69, 86, 65, 89, 193, 75, 76, 89, 85, 67, - 72, 69, 80, 79, 86, 79, 68, 78, 89, 128, 75, 76, 89, 85, 67, 72, 69, 80, - 79, 86, 79, 68, 78, 65, 89, 65, 128, 75, 76, 89, 85, 67, 72, 69, 78, 69, - 80, 79, 83, 84, 79, 89, 65, 78, 78, 89, 128, 75, 76, 89, 85, 67, 72, 69, - 78, 69, 80, 79, 83, 84, 79, 89, 65, 78, 78, 65, 89, 65, 128, 75, 76, 89, - 85, 67, 72, 128, 75, 76, 73, 84, 79, 78, 128, 75, 76, 65, 83, 77, 65, - 128, 75, 76, 65, 83, 77, 193, 75, 76, 65, 128, 75, 76, 128, 75, 75, 79, - 128, 75, 75, 73, 128, 75, 75, 69, 69, 128, 75, 75, 69, 128, 75, 75, 65, - 128, 75, 75, 128, 75, 74, 69, 128, 75, 73, 89, 69, 79, 75, 45, 84, 73, - 75, 69, 85, 84, 128, 75, 73, 89, 69, 79, 75, 45, 83, 73, 79, 83, 45, 75, - 73, 89, 69, 79, 75, 128, 75, 73, 89, 69, 79, 75, 45, 82, 73, 69, 85, 76, - 128, 75, 73, 89, 69, 79, 75, 45, 80, 73, 69, 85, 80, 128, 75, 73, 89, 69, - 79, 75, 45, 78, 73, 69, 85, 78, 128, 75, 73, 89, 69, 79, 75, 45, 75, 72, - 73, 69, 85, 75, 72, 128, 75, 73, 89, 69, 79, 75, 45, 67, 72, 73, 69, 85, - 67, 72, 128, 75, 73, 89, 69, 79, 203, 75, 73, 88, 128, 75, 73, 87, 73, - 70, 82, 85, 73, 84, 128, 75, 73, 87, 128, 75, 73, 86, 128, 75, 73, 84, - 69, 128, 75, 73, 84, 128, 75, 73, 83, 83, 73, 78, 199, 75, 73, 83, 83, - 128, 75, 73, 83, 211, 75, 73, 83, 73, 77, 53, 128, 75, 73, 83, 73, 77, - 181, 75, 73, 83, 72, 128, 75, 73, 83, 65, 76, 128, 75, 73, 82, 79, 87, - 65, 84, 84, 79, 128, 75, 73, 82, 79, 77, 69, 69, 84, 79, 82, 85, 128, 75, - 73, 82, 79, 71, 85, 82, 65, 77, 85, 128, 75, 73, 82, 79, 128, 75, 73, 82, - 71, 72, 73, 218, 75, 73, 81, 128, 75, 73, 80, 128, 75, 73, 208, 75, 73, - 78, 83, 72, 73, 80, 128, 75, 73, 78, 78, 193, 75, 73, 78, 68, 69, 82, 71, - 65, 82, 84, 69, 78, 128, 75, 73, 77, 79, 78, 79, 128, 75, 73, 76, 76, 69, - 82, 128, 75, 73, 73, 90, 72, 128, 75, 73, 73, 128, 75, 73, 72, 128, 75, - 73, 69, 88, 128, 75, 73, 69, 86, 65, 206, 75, 73, 69, 80, 128, 75, 73, - 69, 69, 77, 128, 75, 73, 69, 128, 75, 73, 68, 128, 75, 73, 196, 75, 73, - 67, 75, 128, 75, 73, 66, 128, 75, 73, 65, 86, 128, 75, 73, 65, 66, 128, - 75, 73, 45, 56, 128, 75, 73, 45, 55, 128, 75, 73, 45, 54, 128, 75, 73, - 45, 53, 128, 75, 73, 45, 52, 128, 75, 73, 45, 51, 128, 75, 73, 45, 50, - 128, 75, 73, 45, 49, 128, 75, 72, 90, 128, 75, 72, 87, 65, 73, 128, 75, - 72, 85, 69, 78, 45, 76, 85, 197, 75, 72, 85, 69, 206, 75, 72, 85, 68, 65, - 87, 65, 68, 201, 75, 72, 85, 68, 65, 77, 128, 75, 72, 85, 65, 84, 128, - 75, 72, 79, 85, 128, 75, 72, 79, 212, 75, 72, 79, 78, 78, 65, 128, 75, - 72, 79, 78, 128, 75, 72, 79, 77, 85, 84, 128, 75, 72, 79, 75, 72, 76, 79, - 205, 75, 72, 79, 74, 75, 201, 75, 72, 79, 128, 75, 72, 207, 75, 72, 77, - 213, 75, 72, 73, 84, 128, 75, 72, 73, 78, 89, 65, 128, 75, 72, 73, 69, - 85, 75, 200, 75, 72, 73, 128, 75, 72, 201, 75, 72, 72, 79, 128, 75, 72, - 72, 65, 128, 75, 72, 69, 84, 72, 128, 75, 72, 69, 73, 128, 75, 72, 69, - 69, 128, 75, 72, 69, 128, 75, 72, 65, 86, 128, 75, 72, 65, 82, 79, 83, - 72, 84, 72, 201, 75, 72, 65, 82, 128, 75, 72, 65, 80, 72, 128, 75, 72, - 65, 78, 199, 75, 72, 65, 78, 68, 193, 75, 72, 65, 77, 84, 201, 75, 72, - 65, 77, 73, 76, 79, 128, 75, 72, 65, 75, 65, 83, 83, 73, 65, 206, 75, 72, - 65, 73, 128, 75, 72, 65, 72, 128, 75, 72, 65, 200, 75, 72, 65, 70, 128, - 75, 72, 65, 66, 128, 75, 72, 65, 65, 128, 75, 71, 128, 75, 69, 89, 67, - 65, 80, 128, 75, 69, 89, 67, 65, 208, 75, 69, 89, 66, 79, 65, 82, 68, - 128, 75, 69, 89, 66, 79, 65, 82, 196, 75, 69, 88, 128, 75, 69, 86, 128, - 75, 69, 85, 89, 69, 85, 88, 128, 75, 69, 85, 83, 72, 69, 85, 65, 69, 80, - 128, 75, 69, 85, 83, 69, 85, 88, 128, 75, 69, 85, 80, 85, 81, 128, 75, - 69, 85, 79, 212, 75, 69, 85, 77, 128, 75, 69, 85, 75, 69, 85, 84, 78, 68, - 65, 128, 75, 69, 85, 75, 65, 81, 128, 75, 69, 85, 65, 69, 84, 77, 69, 85, - 78, 128, 75, 69, 85, 65, 69, 82, 73, 128, 75, 69, 84, 84, 201, 75, 69, - 83, 72, 50, 128, 75, 69, 82, 69, 84, 128, 75, 69, 79, 87, 128, 75, 69, - 78, 84, 73, 77, 65, 84, 65, 128, 75, 69, 78, 84, 73, 77, 65, 84, 193, 75, - 69, 78, 84, 73, 77, 193, 75, 69, 78, 65, 84, 128, 75, 69, 78, 128, 75, - 69, 206, 75, 69, 77, 80, 85, 76, 128, 75, 69, 77, 80, 85, 204, 75, 69, - 77, 80, 76, 73, 128, 75, 69, 77, 80, 76, 201, 75, 69, 77, 80, 72, 82, 69, - 78, 71, 128, 75, 69, 77, 66, 65, 78, 71, 128, 75, 69, 76, 86, 73, 206, - 75, 69, 72, 69, 72, 128, 75, 69, 72, 69, 200, 75, 69, 72, 128, 75, 69, - 70, 85, 76, 65, 128, 75, 69, 69, 86, 128, 75, 69, 69, 83, 85, 128, 75, - 69, 69, 80, 73, 78, 199, 75, 69, 69, 78, 71, 128, 75, 69, 69, 66, 128, - 75, 69, 66, 128, 75, 69, 65, 65, 69, 128, 75, 67, 65, 76, 128, 75, 66, - 128, 75, 65, 90, 65, 75, 200, 75, 65, 89, 65, 78, 78, 65, 128, 75, 65, - 89, 65, 200, 75, 65, 88, 128, 75, 65, 87, 86, 128, 75, 65, 87, 73, 128, - 75, 65, 87, 66, 128, 75, 65, 86, 89, 75, 65, 128, 75, 65, 86, 89, 75, - 193, 75, 65, 86, 128, 75, 65, 85, 86, 128, 75, 65, 85, 78, 65, 128, 75, - 65, 85, 206, 75, 65, 85, 66, 128, 75, 65, 84, 79, 128, 75, 65, 84, 72, - 73, 83, 84, 73, 128, 75, 65, 84, 72, 65, 75, 193, 75, 65, 84, 65, 86, 65, - 83, 77, 65, 128, 75, 65, 84, 65, 86, 193, 75, 65, 84, 65, 75, 65, 78, 65, - 45, 72, 73, 82, 65, 71, 65, 78, 193, 75, 65, 83, 82, 65, 84, 65, 78, 128, - 75, 65, 83, 82, 65, 84, 65, 206, 75, 65, 83, 82, 65, 128, 75, 65, 83, 82, - 193, 75, 65, 83, 75, 65, 76, 128, 75, 65, 83, 75, 65, 204, 75, 65, 83, - 72, 77, 73, 82, 201, 75, 65, 82, 83, 72, 65, 78, 65, 128, 75, 65, 82, 79, - 82, 73, 73, 128, 75, 65, 82, 79, 82, 65, 78, 128, 75, 65, 82, 79, 82, - 128, 75, 65, 82, 207, 75, 65, 82, 69, 206, 75, 65, 82, 65, 84, 84, 79, - 128, 75, 65, 82, 65, 78, 128, 75, 65, 80, 89, 69, 79, 85, 78, 83, 83, 65, - 78, 71, 80, 73, 69, 85, 80, 128, 75, 65, 80, 89, 69, 79, 85, 78, 82, 73, - 69, 85, 76, 128, 75, 65, 80, 89, 69, 79, 85, 78, 80, 72, 73, 69, 85, 80, - 72, 128, 75, 65, 80, 89, 69, 79, 85, 78, 77, 73, 69, 85, 77, 128, 75, 65, - 80, 80, 65, 128, 75, 65, 80, 80, 193, 75, 65, 80, 79, 128, 75, 65, 80, - 72, 128, 75, 65, 80, 65, 76, 128, 75, 65, 80, 65, 128, 75, 65, 208, 75, - 65, 78, 84, 65, 74, 193, 75, 65, 78, 78, 65, 68, 193, 75, 65, 78, 71, 65, - 82, 79, 79, 128, 75, 65, 78, 71, 128, 75, 65, 78, 199, 75, 65, 78, 65, - 75, 79, 128, 75, 65, 77, 52, 128, 75, 65, 77, 50, 128, 75, 65, 77, 128, - 75, 65, 75, 79, 128, 75, 65, 75, 65, 66, 65, 84, 128, 75, 65, 75, 128, - 75, 65, 203, 75, 65, 73, 86, 128, 75, 65, 73, 84, 72, 201, 75, 65, 73, - 82, 73, 128, 75, 65, 73, 66, 128, 75, 65, 73, 128, 75, 65, 201, 75, 65, - 70, 65, 128, 75, 65, 70, 128, 75, 65, 198, 75, 65, 68, 53, 128, 75, 65, - 68, 181, 75, 65, 68, 52, 128, 75, 65, 68, 51, 128, 75, 65, 68, 179, 75, - 65, 68, 50, 128, 75, 65, 68, 128, 75, 65, 67, 72, 75, 65, 128, 75, 65, - 66, 193, 75, 65, 66, 128, 75, 65, 65, 86, 128, 75, 65, 65, 73, 128, 75, - 65, 65, 70, 85, 128, 75, 65, 65, 70, 128, 75, 65, 65, 67, 85, 128, 75, - 65, 65, 66, 65, 128, 75, 65, 65, 66, 128, 75, 65, 50, 128, 75, 65, 178, - 75, 65, 45, 75, 69, 128, 75, 65, 45, 57, 128, 75, 65, 45, 56, 128, 75, - 65, 45, 55, 128, 75, 65, 45, 54, 128, 75, 65, 45, 53, 128, 75, 65, 45, - 52, 128, 75, 65, 45, 51, 128, 75, 65, 45, 50, 128, 75, 65, 45, 49, 49, - 128, 75, 65, 45, 49, 48, 128, 75, 65, 45, 49, 128, 75, 48, 48, 56, 128, - 75, 48, 48, 55, 128, 75, 48, 48, 54, 128, 75, 48, 48, 53, 128, 75, 48, - 48, 52, 128, 75, 48, 48, 51, 128, 75, 48, 48, 50, 128, 75, 48, 48, 49, - 128, 74, 87, 65, 128, 74, 85, 85, 128, 74, 85, 84, 128, 74, 85, 83, 84, - 73, 70, 73, 67, 65, 84, 73, 79, 78, 128, 74, 85, 80, 73, 84, 69, 82, 128, - 74, 85, 79, 84, 128, 74, 85, 79, 80, 128, 74, 85, 78, 79, 128, 74, 85, - 78, 71, 83, 69, 79, 78, 199, 74, 85, 78, 69, 128, 74, 85, 76, 89, 128, - 74, 85, 71, 71, 76, 73, 78, 71, 128, 74, 85, 69, 85, 73, 128, 74, 85, 68, - 85, 76, 128, 74, 85, 68, 71, 69, 128, 74, 85, 68, 69, 79, 45, 83, 80, 65, - 78, 73, 83, 200, 74, 79, 89, 83, 84, 73, 67, 75, 128, 74, 79, 89, 79, 85, - 211, 74, 79, 89, 128, 74, 79, 86, 69, 128, 74, 79, 212, 74, 79, 78, 71, - 128, 74, 79, 78, 193, 74, 79, 75, 69, 82, 128, 74, 79, 73, 78, 84, 83, - 128, 74, 79, 73, 78, 69, 68, 128, 74, 79, 73, 78, 128, 74, 79, 65, 128, - 74, 78, 89, 65, 128, 74, 74, 89, 88, 128, 74, 74, 89, 84, 128, 74, 74, - 89, 80, 128, 74, 74, 89, 128, 74, 74, 85, 88, 128, 74, 74, 85, 84, 128, - 74, 74, 85, 82, 88, 128, 74, 74, 85, 82, 128, 74, 74, 85, 80, 128, 74, - 74, 85, 79, 88, 128, 74, 74, 85, 79, 80, 128, 74, 74, 85, 79, 128, 74, - 74, 85, 128, 74, 74, 79, 88, 128, 74, 74, 79, 84, 128, 74, 74, 79, 80, - 128, 74, 74, 79, 128, 74, 74, 73, 88, 128, 74, 74, 73, 84, 128, 74, 74, - 73, 80, 128, 74, 74, 73, 69, 88, 128, 74, 74, 73, 69, 84, 128, 74, 74, - 73, 69, 80, 128, 74, 74, 73, 69, 128, 74, 74, 73, 128, 74, 74, 69, 69, - 128, 74, 74, 69, 128, 74, 74, 65, 128, 74, 73, 76, 128, 74, 73, 73, 77, - 128, 74, 73, 73, 128, 74, 73, 72, 86, 65, 77, 85, 76, 73, 89, 65, 128, - 74, 73, 71, 83, 65, 215, 74, 73, 65, 128, 74, 72, 79, 88, 128, 74, 72, - 79, 128, 74, 72, 69, 72, 128, 74, 72, 65, 89, 73, 78, 128, 74, 72, 65, - 78, 128, 74, 72, 65, 77, 128, 74, 72, 65, 65, 128, 74, 72, 65, 128, 74, - 69, 85, 128, 74, 69, 82, 85, 83, 65, 76, 69, 77, 128, 74, 69, 82, 65, - 206, 74, 69, 82, 65, 128, 74, 69, 82, 128, 74, 69, 72, 128, 74, 69, 200, - 74, 69, 71, 79, 71, 65, 78, 128, 74, 69, 69, 77, 128, 74, 69, 69, 205, - 74, 69, 65, 78, 83, 128, 74, 65, 89, 78, 128, 74, 65, 89, 73, 78, 128, - 74, 65, 89, 65, 78, 78, 65, 128, 74, 65, 87, 128, 74, 65, 86, 73, 89, 65, - 78, 73, 128, 74, 65, 86, 65, 78, 69, 83, 197, 74, 65, 85, 128, 74, 65, - 82, 128, 74, 65, 80, 65, 78, 69, 83, 197, 74, 65, 80, 65, 78, 128, 74, - 65, 78, 85, 65, 82, 89, 128, 74, 65, 76, 76, 65, 74, 65, 76, 65, 76, 79, - 85, 72, 79, 85, 128, 74, 65, 76, 76, 128, 74, 65, 73, 206, 74, 65, 73, - 128, 74, 65, 72, 128, 74, 65, 68, 69, 128, 74, 65, 67, 75, 83, 128, 74, - 65, 67, 75, 45, 79, 45, 76, 65, 78, 84, 69, 82, 78, 128, 74, 65, 67, 203, - 74, 45, 83, 73, 77, 80, 76, 73, 70, 73, 69, 196, 73, 90, 72, 73, 84, 83, - 65, 128, 73, 90, 72, 73, 84, 83, 193, 73, 90, 72, 69, 128, 73, 90, 65, - 75, 65, 89, 193, 73, 89, 69, 75, 128, 73, 89, 65, 78, 78, 65, 128, 73, - 85, 74, 65, 128, 73, 84, 211, 73, 84, 69, 82, 65, 84, 73, 79, 206, 73, - 84, 69, 77, 128, 73, 83, 83, 72, 65, 82, 128, 73, 83, 79, 83, 67, 69, 76, - 69, 211, 73, 83, 79, 78, 128, 73, 83, 79, 206, 73, 83, 79, 76, 65, 84, - 69, 128, 73, 83, 76, 65, 78, 68, 128, 73, 83, 72, 77, 65, 65, 77, 128, - 73, 83, 69, 78, 45, 73, 83, 69, 78, 128, 73, 83, 65, 75, 73, 193, 73, 83, - 45, 80, 73, 76, 76, 65, 128, 73, 82, 85, 89, 65, 78, 78, 65, 128, 73, 82, - 85, 85, 89, 65, 78, 78, 65, 128, 73, 82, 79, 78, 45, 67, 79, 80, 80, 69, - 210, 73, 82, 79, 78, 128, 73, 82, 66, 128, 73, 79, 84, 73, 70, 73, 69, - 196, 73, 79, 84, 65, 84, 69, 196, 73, 79, 84, 65, 128, 73, 79, 84, 193, - 73, 79, 82, 128, 73, 79, 78, 71, 128, 73, 79, 68, 72, 65, 68, 72, 128, - 73, 78, 86, 73, 83, 73, 66, 76, 197, 73, 78, 86, 69, 82, 84, 69, 68, 128, - 73, 78, 86, 69, 82, 84, 69, 196, 73, 78, 86, 69, 82, 84, 69, 66, 82, 65, - 84, 69, 128, 73, 78, 86, 69, 82, 83, 197, 73, 78, 84, 82, 79, 68, 85, 67, - 69, 82, 128, 73, 78, 84, 73, 128, 73, 78, 84, 69, 82, 83, 89, 76, 76, 65, - 66, 73, 195, 73, 78, 84, 69, 82, 83, 69, 67, 84, 73, 79, 78, 128, 73, 78, - 84, 69, 82, 83, 69, 67, 84, 73, 79, 206, 73, 78, 84, 69, 82, 83, 69, 67, - 84, 73, 78, 199, 73, 78, 84, 69, 82, 82, 79, 66, 65, 78, 71, 128, 73, 78, - 84, 69, 82, 82, 79, 66, 65, 78, 199, 73, 78, 84, 69, 82, 80, 79, 76, 65, - 84, 73, 79, 206, 73, 78, 84, 69, 82, 76, 79, 67, 75, 69, 196, 73, 78, 84, - 69, 82, 76, 73, 78, 69, 65, 210, 73, 78, 84, 69, 82, 76, 65, 67, 69, 196, - 73, 78, 84, 69, 82, 73, 79, 210, 73, 78, 84, 69, 82, 69, 83, 212, 73, 78, - 84, 69, 82, 67, 65, 76, 65, 84, 69, 128, 73, 78, 84, 69, 71, 82, 65, 84, - 73, 79, 78, 128, 73, 78, 84, 69, 71, 82, 65, 84, 73, 79, 206, 73, 78, 84, - 69, 71, 82, 65, 76, 128, 73, 78, 84, 69, 71, 82, 65, 204, 73, 78, 83, 85, - 76, 65, 210, 73, 78, 83, 84, 82, 85, 77, 69, 78, 84, 65, 204, 73, 78, 83, - 73, 68, 69, 128, 73, 78, 83, 73, 68, 197, 73, 78, 83, 69, 82, 84, 73, 79, - 206, 73, 78, 83, 69, 82, 212, 73, 78, 83, 69, 67, 84, 128, 73, 78, 83, - 67, 82, 73, 80, 84, 73, 79, 78, 65, 204, 73, 78, 80, 85, 212, 73, 78, 78, - 79, 67, 69, 78, 67, 69, 128, 73, 78, 78, 78, 128, 73, 78, 78, 69, 82, - 128, 73, 78, 78, 69, 210, 73, 78, 78, 128, 73, 78, 73, 78, 71, 85, 128, - 73, 78, 72, 73, 66, 73, 212, 73, 78, 72, 69, 82, 69, 78, 212, 73, 78, 72, - 65, 76, 69, 128, 73, 78, 71, 87, 65, 90, 128, 73, 78, 70, 79, 82, 77, 65, - 84, 73, 79, 206, 73, 78, 70, 76, 85, 69, 78, 67, 69, 128, 73, 78, 70, 73, - 78, 73, 84, 89, 128, 73, 78, 70, 73, 78, 73, 84, 217, 73, 78, 68, 85, 83, - 84, 82, 73, 65, 204, 73, 78, 68, 73, 82, 69, 67, 212, 73, 78, 68, 73, 67, - 84, 73, 79, 206, 73, 78, 68, 73, 67, 65, 84, 79, 82, 128, 73, 78, 68, 73, - 67, 65, 84, 79, 210, 73, 78, 68, 73, 195, 73, 78, 68, 73, 65, 206, 73, - 78, 68, 69, 88, 128, 73, 78, 68, 69, 80, 69, 78, 68, 69, 78, 212, 73, 78, - 67, 82, 69, 77, 69, 78, 84, 128, 73, 78, 67, 82, 69, 65, 83, 69, 211, 73, - 78, 67, 82, 69, 65, 83, 69, 128, 73, 78, 67, 82, 69, 65, 83, 197, 73, 78, - 67, 79, 77, 80, 76, 69, 84, 197, 73, 78, 67, 79, 77, 73, 78, 199, 73, 78, - 67, 76, 85, 68, 73, 78, 199, 73, 78, 67, 72, 128, 73, 78, 66, 79, 216, - 73, 78, 65, 80, 128, 73, 78, 45, 65, 76, 65, 70, 128, 73, 77, 80, 69, 82, - 73, 65, 204, 73, 77, 80, 69, 82, 70, 69, 67, 84, 85, 205, 73, 77, 80, 69, - 82, 70, 69, 67, 84, 65, 128, 73, 77, 80, 69, 82, 70, 69, 67, 84, 193, 73, - 77, 78, 128, 73, 77, 73, 83, 69, 79, 211, 73, 77, 73, 78, 51, 128, 73, - 77, 73, 78, 128, 73, 77, 73, 206, 73, 77, 73, 70, 84, 72, 79, 82, 79, 78, - 128, 73, 77, 73, 70, 84, 72, 79, 82, 65, 128, 73, 77, 73, 70, 79, 78, 79, - 78, 128, 73, 77, 73, 68, 73, 65, 82, 71, 79, 78, 128, 73, 77, 65, 71, - 197, 73, 77, 65, 65, 76, 65, 128, 73, 76, 85, 89, 65, 78, 78, 65, 128, - 73, 76, 85, 89, 128, 73, 76, 85, 85, 89, 65, 78, 78, 65, 128, 73, 76, 85, - 84, 128, 73, 76, 73, 77, 77, 85, 52, 128, 73, 76, 73, 77, 77, 85, 51, - 128, 73, 76, 73, 77, 77, 85, 128, 73, 76, 73, 77, 77, 213, 73, 76, 50, - 128, 73, 75, 65, 82, 65, 128, 73, 75, 65, 82, 193, 73, 74, 128, 73, 73, - 89, 65, 78, 78, 65, 128, 73, 71, 73, 128, 73, 71, 201, 73, 71, 71, 87, - 83, 128, 73, 70, 73, 78, 128, 73, 69, 85, 78, 71, 45, 84, 73, 75, 69, 85, - 84, 128, 73, 69, 85, 78, 71, 45, 84, 72, 73, 69, 85, 84, 72, 128, 73, 69, - 85, 78, 71, 45, 82, 73, 69, 85, 76, 128, 73, 69, 85, 78, 71, 45, 80, 73, - 69, 85, 80, 128, 73, 69, 85, 78, 71, 45, 80, 72, 73, 69, 85, 80, 72, 128, - 73, 69, 85, 78, 71, 45, 67, 73, 69, 85, 67, 128, 73, 69, 85, 78, 71, 45, - 67, 72, 73, 69, 85, 67, 72, 128, 73, 69, 85, 78, 199, 73, 68, 76, 69, - 128, 73, 68, 73, 77, 128, 73, 68, 73, 205, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 68, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 68, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 68, - 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 68, 54, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 68, 53, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 68, 52, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 68, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 68, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 68, - 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 68, 48, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 70, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 67, 69, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 67, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 67, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, - 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 65, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 57, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 67, 56, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 67, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 67, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, - 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 52, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 51, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 67, 50, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 67, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 67, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, - 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, 69, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, 68, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 66, 67, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 66, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 66, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, - 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, 56, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, 55, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 66, 54, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 66, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 66, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, - 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, 50, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, 49, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 66, 48, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 65, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 65, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, - 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, 67, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, 66, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 65, 65, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 65, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 65, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, - 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, 54, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, 53, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 65, 52, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 65, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 65, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, - 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, 48, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 70, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 57, 69, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 57, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 57, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, - 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 65, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 57, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 57, 56, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 57, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 57, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, - 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 52, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 51, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 57, 50, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 57, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 57, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, - 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, 69, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, 68, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 56, 67, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 56, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 56, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, - 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, 56, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, 55, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 56, 54, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 56, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 56, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, - 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, 50, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, 49, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 56, 48, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 55, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 55, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, - 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, 67, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, 66, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 55, 65, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 55, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 55, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, - 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, 54, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, 53, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 55, 52, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 55, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 55, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, - 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, 48, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 54, 68, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 54, 67, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 54, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 54, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 54, - 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 54, 56, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 54, 55, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 54, 54, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 54, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 54, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 54, - 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 54, 50, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 54, 49, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 54, 48, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 53, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 53, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, - 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 67, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 66, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 53, 65, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 53, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 53, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, - 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 54, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 53, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 53, 52, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 53, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 53, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, - 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 48, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, 70, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 52, 69, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 52, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 52, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, - 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, 65, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, 57, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 52, 56, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 52, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 52, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, - 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, 52, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, 51, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 52, 50, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 52, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 52, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, - 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, 69, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, 68, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 51, 67, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 51, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 51, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, - 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, 56, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, 55, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 51, 54, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 51, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 51, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, - 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, 50, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, 49, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 51, 48, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 50, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 50, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, - 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, 67, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, 66, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 50, 65, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 50, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 50, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, - 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, 54, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, 53, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 50, 52, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 50, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 50, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, - 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, 48, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, 70, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 49, 69, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 49, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 49, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, - 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, 65, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, 57, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 49, 56, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 49, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 49, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, - 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, 52, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, 51, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 49, 50, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 49, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 49, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, - 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, 69, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, 68, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 48, 67, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 48, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 48, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, - 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, 56, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, 55, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 48, 54, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 65, 48, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 65, 48, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, - 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, 50, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, 49, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 65, 48, 48, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 70, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 70, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, - 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, 67, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, 66, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 70, 65, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 70, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 70, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, - 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, 54, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, 53, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 70, 52, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 70, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 70, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, - 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, 48, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, 70, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 69, 69, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 69, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 69, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, - 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, 65, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, 57, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 69, 56, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 69, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 69, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, - 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, 52, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, 51, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 69, 50, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 69, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 69, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, - 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, 69, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, 68, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 68, 67, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 68, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 68, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, - 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, 56, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, 55, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 68, 54, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 68, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 68, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, - 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, 50, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, 49, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 68, 48, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 67, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 67, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, - 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, 67, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, 66, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 67, 65, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 67, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 67, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, - 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, 54, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, 53, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 67, 52, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 67, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 67, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, - 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, 48, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, 70, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 66, 69, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 66, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 66, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, - 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, 65, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, 57, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 66, 56, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 66, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 66, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, - 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, 52, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, 51, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 66, 50, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 66, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 66, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, - 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, 69, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, 68, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 65, 67, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 65, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 65, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, - 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, 56, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, 55, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 65, 54, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 65, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 65, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, - 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, 50, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, 49, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 65, 48, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 57, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 57, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, - 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, 67, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, 66, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 57, 65, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 57, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 57, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, - 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, 54, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, 53, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 57, 52, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 57, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 57, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, - 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, 48, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, 70, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 56, 69, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 56, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 56, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, - 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, 65, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, 57, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 56, 56, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 56, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 56, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, - 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, 52, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, 51, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 56, 50, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 56, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 56, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, - 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, 69, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, 68, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 55, 67, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 55, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 55, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, - 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, 56, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, 55, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 55, 54, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 55, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 55, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, - 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, 50, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, 49, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 55, 48, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 54, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 54, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, - 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, 67, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, 66, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 54, 65, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 54, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 54, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, - 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, 54, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, 53, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 54, 52, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 54, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 54, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, - 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, 48, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, 70, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 53, 69, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 53, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 53, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, - 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, 65, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, 57, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 53, 56, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 53, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 53, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, - 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, 52, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, 51, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 53, 50, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 53, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 53, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, - 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, 69, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, 68, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 52, 67, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 52, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 52, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, - 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, 56, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, 55, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 52, 54, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 52, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 52, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, - 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, 50, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, 49, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 52, 48, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 51, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 51, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, - 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, 67, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, 66, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 51, 65, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 51, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 51, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, - 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, 54, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, 53, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 51, 52, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 51, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 51, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, - 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, 48, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, 70, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 50, 69, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 50, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 50, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, - 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, 65, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, 57, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 50, 56, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 50, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 50, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, - 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, 52, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, 51, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 50, 50, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 50, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 50, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, - 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, 69, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, 68, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 49, 67, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 49, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 49, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, - 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, 56, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, 55, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 49, 54, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 49, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 49, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, - 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, 50, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, 49, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 49, 48, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 48, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 48, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, - 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, 67, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, 66, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 48, 65, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 48, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 48, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, - 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, 54, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, 53, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 70, 57, 48, 52, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 70, 57, 48, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 70, 57, 48, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, - 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, 48, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 57, 49, 52, 68, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 57, 48, 52, 65, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 56, 68, 55, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 56, 67, 65, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 56, 57, 69, - 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 55, 68, 52, 50, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 55, 65, 55, 65, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 55, 57, 56, 49, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 55, 54, 68, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 55, 53, 51, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 55, 53, 49, - 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 55, 49, 50, 49, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 55, 48, 66, 57, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 54, 70, 49, 52, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 54, 69, 56, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 54, 55, 50, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 54, 55, 48, - 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 54, 55, 48, 56, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 54, 54, 50, 48, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 54, 53, 66, 48, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 54, 53, 57, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 54, 53, 53, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 54, 51, 53, - 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 54, 51, 48, 55, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 54, 50, 57, 53, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 54, 50, 53, 51, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 54, 50, 52, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 53, 70, 56, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 53, 68, 69, - 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 53, 66, 56, 57, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 53, 66, 53, 55, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 53, 57, 50, 57, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 53, 57, 49, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 53, 56, 70, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 53, 53, 66, - 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 53, 52, 51, 57, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 53, 52, 48, 56, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 53, 51, 70, 51, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 53, 51, 67, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 53, 50, 68, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 53, 50, 55, - 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 53, 50, 52, 68, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 53, 50, 49, 68, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 53, 49, 56, 68, 128, 73, 68, 69, 79, 71, 82, 65, - 80, 72, 45, 52, 69, 65, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 52, 69, 56, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 52, 69, 50, - 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 52, 69, 48, 57, 128, 73, - 68, 69, 79, 71, 82, 65, 80, 72, 45, 52, 69, 48, 48, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 65, 49, 68, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 65, 49, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 65, 49, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 65, 49, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 65, 49, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 49, - 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 49, 55, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 49, 54, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 49, 53, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 65, 49, 52, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 65, 49, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 65, 49, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 65, 49, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 65, 49, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, - 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 69, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 68, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 67, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 66, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 65, 48, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 65, 48, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 65, 48, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 65, 48, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, - 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 53, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 52, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 51, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 50, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 65, 48, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 65, 48, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 57, 70, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 57, 70, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, - 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 67, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 66, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 65, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 57, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 57, 70, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 57, 70, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 57, 70, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 57, 70, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, - 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 51, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 50, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 49, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 48, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 57, 69, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 57, 69, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 57, 69, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 57, 69, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, - 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 65, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 57, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 56, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 55, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 57, 69, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 57, 69, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 57, 69, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 57, 69, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, - 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 49, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 48, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 70, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 69, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 57, 68, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 57, 68, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 57, 68, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 57, 68, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, - 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 56, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 55, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 54, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 53, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 57, 68, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 57, 68, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 57, 68, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 57, 68, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, - 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 70, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 69, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 68, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 67, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 57, 67, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 57, 67, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 57, 67, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 57, 67, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, - 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 54, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 53, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 52, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 51, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 57, 67, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 57, 67, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 57, 67, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 57, 66, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, - 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 68, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 67, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 66, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 65, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 57, 66, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 57, 66, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 57, 66, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 57, 66, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, - 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 52, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 51, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 50, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 49, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 57, 66, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 57, 65, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 57, 65, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 57, 65, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, - 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 66, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 65, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 57, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 56, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 57, 65, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 57, 65, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 57, 65, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 57, 65, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, - 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 50, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 49, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 48, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 70, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 57, 57, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 57, 57, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 57, 57, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 57, 57, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, - 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 57, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 56, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 55, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 54, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 57, 57, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 57, 57, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 57, 57, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 57, 57, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, - 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 48, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 70, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 69, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 68, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 57, 56, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 57, 56, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 57, 56, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 57, 56, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, - 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 55, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 54, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 53, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 52, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 57, 56, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 57, 56, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 57, 56, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 57, 56, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, - 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 69, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 68, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 67, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 66, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 57, 55, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 57, 55, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 57, 55, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 57, 55, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, - 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 53, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 52, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 51, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 50, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 57, 55, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 57, 55, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 57, 54, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 57, 54, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, - 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 67, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 66, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 65, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 57, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 57, 54, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 57, 54, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 57, 54, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 57, 54, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, - 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 51, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 50, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 49, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 48, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 57, 53, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 57, 53, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 57, 53, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 57, 53, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, - 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 65, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 57, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 56, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 55, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 57, 53, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 57, 53, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 57, 53, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 57, 53, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, - 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 49, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 48, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 70, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 69, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 57, 52, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 57, 52, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 57, 52, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 57, 52, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, - 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 56, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 55, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 54, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 53, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 57, 52, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 57, 52, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 57, 52, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 57, 52, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, - 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 70, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 69, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 68, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 67, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 57, 51, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 57, 51, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 57, 51, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 57, 51, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, - 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 54, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 53, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 52, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 51, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 57, 51, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 57, 51, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 57, 51, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 57, 50, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, - 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 68, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 67, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 66, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 65, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 57, 50, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 57, 50, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 57, 50, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 57, 50, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, - 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 52, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 51, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 50, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 49, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 57, 50, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 57, 49, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 57, 49, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 57, 49, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, - 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 66, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 65, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 57, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 56, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 57, 49, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 57, 49, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 57, 49, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 57, 49, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, - 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 50, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 49, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 48, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 70, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 57, 48, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 57, 48, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 57, 48, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 57, 48, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, - 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 57, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 56, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 55, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 54, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 57, 48, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 57, 48, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 57, 48, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 57, 48, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, - 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 48, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 70, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 69, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 68, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 56, 70, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 56, 70, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 56, 70, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 56, 70, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, - 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 55, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 54, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 53, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 52, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 56, 70, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 56, 70, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 56, 70, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 56, 70, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, - 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 69, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 68, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 67, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 66, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 56, 69, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 56, 69, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 56, 69, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 56, 69, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, - 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 53, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 52, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 51, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 50, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 56, 69, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 56, 69, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 56, 68, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 56, 68, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, - 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 67, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 66, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 65, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 57, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 56, 68, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 56, 68, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 56, 68, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 56, 68, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, - 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 51, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 50, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 49, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 48, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 56, 67, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 56, 67, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 56, 67, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 56, 67, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, - 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 65, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 57, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 56, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 55, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 56, 67, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 56, 67, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 56, 67, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 56, 67, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, - 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 49, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 48, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 70, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 69, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 56, 66, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 56, 66, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 56, 66, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 56, 66, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, - 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 56, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 55, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 54, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 53, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 56, 66, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 56, 66, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 56, 66, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 56, 66, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, - 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 70, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 69, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 68, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 67, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 56, 65, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 56, 65, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 56, 65, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 56, 65, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, - 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 54, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 53, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 52, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 51, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 56, 65, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 56, 65, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 56, 65, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 56, 57, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, - 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 68, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 67, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 66, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 65, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 56, 57, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 56, 57, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 56, 57, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 56, 57, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, - 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 52, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 51, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 50, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 49, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 56, 57, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 56, 56, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 56, 56, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 56, 56, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, - 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 66, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 65, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 57, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 56, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 56, 56, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 56, 56, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 56, 56, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 56, 56, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, - 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 50, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 49, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 48, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 70, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 56, 55, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 56, 55, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 56, 55, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 56, 55, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, - 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 57, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 56, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 55, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 54, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 56, 55, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 56, 55, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 56, 55, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 56, 55, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, - 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 48, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 70, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 69, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 68, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 56, 54, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 56, 54, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 56, 54, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 56, 54, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, - 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 55, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 54, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 53, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 52, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 56, 54, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 56, 54, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 56, 54, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 56, 54, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, - 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 69, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 68, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 67, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 66, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 56, 53, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 56, 53, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 56, 53, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 56, 53, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, - 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 53, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 52, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 51, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 50, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 56, 53, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 56, 53, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 56, 52, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 56, 52, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, - 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 67, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 66, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 65, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 57, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 56, 52, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 56, 52, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 56, 52, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 56, 52, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, - 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 51, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 50, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 49, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 48, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 56, 51, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 56, 51, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 56, 51, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 56, 51, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, - 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 65, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 57, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 56, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 55, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 56, 51, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 56, 51, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 56, 51, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 56, 51, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, - 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 49, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 48, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 70, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 69, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 56, 50, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 56, 50, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 56, 50, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 56, 50, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, - 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 56, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 55, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 54, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 53, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 56, 50, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 56, 50, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 56, 50, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 56, 50, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, - 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 70, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 69, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 68, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 67, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 56, 49, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 56, 49, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 56, 49, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 56, 49, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, - 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 54, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 53, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 52, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 51, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 56, 49, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 56, 49, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 56, 49, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 56, 48, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, - 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 68, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 67, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 66, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 65, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 56, 48, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 72, 45, 50, 70, 56, 48, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, - 50, 70, 56, 48, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, - 56, 48, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, - 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 52, 128, - 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 51, 128, 73, 68, - 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 50, 128, 73, 68, 69, 79, - 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 49, 128, 73, 68, 69, 79, 71, 82, - 65, 80, 72, 45, 50, 70, 56, 48, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, - 200, 73, 68, 69, 78, 84, 73, 70, 73, 67, 65, 84, 73, 79, 78, 128, 73, 68, - 69, 78, 84, 73, 70, 73, 67, 65, 84, 73, 79, 206, 73, 68, 69, 78, 84, 73, - 67, 65, 204, 73, 67, 79, 78, 128, 73, 67, 72, 79, 85, 128, 73, 67, 72, - 79, 83, 128, 73, 67, 72, 73, 77, 65, 84, 79, 83, 128, 73, 67, 72, 65, 68, - 73, 78, 128, 73, 67, 69, 76, 65, 78, 68, 73, 67, 45, 89, 82, 128, 73, 66, - 73, 70, 73, 76, 73, 128, 73, 65, 85, 68, 65, 128, 73, 48, 49, 53, 128, - 73, 48, 49, 52, 128, 73, 48, 49, 51, 128, 73, 48, 49, 50, 128, 73, 48, - 49, 49, 65, 128, 73, 48, 49, 49, 128, 73, 48, 49, 48, 65, 128, 73, 48, - 49, 48, 128, 73, 48, 48, 57, 65, 128, 73, 48, 48, 57, 128, 73, 48, 48, - 56, 128, 73, 48, 48, 55, 128, 73, 48, 48, 54, 128, 73, 48, 48, 53, 65, - 128, 73, 48, 48, 53, 128, 73, 48, 48, 52, 128, 73, 48, 48, 51, 128, 73, - 48, 48, 50, 128, 73, 48, 48, 49, 128, 73, 45, 89, 85, 128, 73, 45, 89, - 79, 128, 73, 45, 89, 69, 79, 128, 73, 45, 89, 69, 128, 73, 45, 89, 65, - 69, 128, 73, 45, 89, 65, 45, 79, 128, 73, 45, 89, 65, 128, 73, 45, 79, - 45, 73, 128, 73, 45, 79, 128, 73, 45, 69, 85, 128, 73, 45, 66, 69, 65, - 77, 128, 73, 45, 65, 82, 65, 69, 65, 128, 73, 45, 65, 128, 72, 90, 90, - 90, 71, 128, 72, 90, 90, 90, 128, 72, 90, 90, 80, 128, 72, 90, 90, 128, - 72, 90, 87, 71, 128, 72, 90, 87, 128, 72, 90, 84, 128, 72, 90, 71, 128, - 72, 89, 83, 84, 69, 82, 69, 83, 73, 211, 72, 89, 80, 79, 68, 73, 65, 83, - 84, 79, 76, 69, 128, 72, 89, 80, 72, 69, 78, 65, 84, 73, 79, 206, 72, 89, - 80, 72, 69, 78, 45, 77, 73, 78, 85, 83, 128, 72, 89, 80, 72, 69, 78, 128, - 72, 89, 80, 72, 69, 206, 72, 89, 71, 73, 69, 73, 65, 128, 72, 89, 71, 73, - 69, 65, 128, 72, 88, 87, 71, 128, 72, 88, 85, 79, 88, 128, 72, 88, 85, - 79, 84, 128, 72, 88, 85, 79, 80, 128, 72, 88, 85, 79, 128, 72, 88, 79, - 88, 128, 72, 88, 79, 84, 128, 72, 88, 79, 80, 128, 72, 88, 79, 128, 72, - 88, 73, 88, 128, 72, 88, 73, 84, 128, 72, 88, 73, 80, 128, 72, 88, 73, - 69, 88, 128, 72, 88, 73, 69, 84, 128, 72, 88, 73, 69, 80, 128, 72, 88, - 73, 69, 128, 72, 88, 73, 128, 72, 88, 69, 88, 128, 72, 88, 69, 80, 128, - 72, 88, 69, 128, 72, 88, 65, 88, 128, 72, 88, 65, 84, 128, 72, 88, 65, - 80, 128, 72, 88, 65, 128, 72, 87, 85, 128, 72, 87, 65, 73, 82, 128, 72, - 87, 65, 72, 128, 72, 85, 86, 65, 128, 72, 85, 83, 72, 69, 196, 72, 85, - 83, 72, 128, 72, 85, 82, 65, 78, 128, 72, 85, 79, 84, 128, 72, 85, 78, - 68, 82, 69, 68, 83, 128, 72, 85, 78, 68, 82, 69, 68, 211, 72, 85, 78, 68, - 82, 69, 68, 128, 72, 85, 78, 68, 82, 69, 196, 72, 85, 78, 128, 72, 85, - 77, 208, 72, 85, 77, 65, 78, 128, 72, 85, 77, 65, 206, 72, 85, 76, 50, - 128, 72, 85, 73, 73, 84, 79, 128, 72, 85, 71, 71, 73, 78, 71, 128, 72, - 85, 71, 71, 73, 78, 199, 72, 85, 66, 50, 128, 72, 85, 66, 178, 72, 85, - 66, 128, 72, 85, 65, 82, 65, 68, 68, 79, 128, 72, 85, 65, 78, 128, 72, - 85, 45, 51, 128, 72, 85, 45, 50, 128, 72, 85, 45, 49, 128, 72, 84, 84, - 65, 128, 72, 84, 83, 128, 72, 84, 74, 128, 72, 82, 89, 86, 78, 73, 193, - 72, 80, 87, 71, 128, 72, 80, 65, 128, 72, 80, 128, 72, 79, 85, 83, 197, - 72, 79, 85, 82, 71, 76, 65, 83, 83, 128, 72, 79, 85, 82, 71, 76, 65, 83, - 211, 72, 79, 85, 82, 128, 72, 79, 85, 210, 72, 79, 84, 69, 76, 128, 72, - 79, 84, 65, 128, 72, 79, 83, 80, 73, 84, 65, 76, 128, 72, 79, 82, 83, 69, - 128, 72, 79, 82, 83, 197, 72, 79, 82, 82, 128, 72, 79, 82, 78, 83, 128, - 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 76, 217, 72, 79, 82, 73, 90, 79, - 78, 84, 65, 76, 45, 48, 54, 45, 48, 54, 128, 72, 79, 82, 73, 90, 79, 78, - 84, 65, 76, 45, 48, 54, 45, 48, 53, 128, 72, 79, 82, 73, 90, 79, 78, 84, - 65, 76, 45, 48, 54, 45, 48, 52, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, - 76, 45, 48, 54, 45, 48, 51, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, - 45, 48, 54, 45, 48, 50, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, - 48, 54, 45, 48, 49, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, - 54, 45, 48, 48, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 53, - 45, 48, 54, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 53, 45, - 48, 53, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 53, 45, 48, - 52, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 53, 45, 48, 51, - 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 53, 45, 48, 50, 128, - 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 53, 45, 48, 49, 128, 72, - 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 53, 45, 48, 48, 128, 72, 79, - 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 52, 45, 48, 54, 128, 72, 79, 82, - 73, 90, 79, 78, 84, 65, 76, 45, 48, 52, 45, 48, 53, 128, 72, 79, 82, 73, - 90, 79, 78, 84, 65, 76, 45, 48, 52, 45, 48, 52, 128, 72, 79, 82, 73, 90, - 79, 78, 84, 65, 76, 45, 48, 52, 45, 48, 51, 128, 72, 79, 82, 73, 90, 79, - 78, 84, 65, 76, 45, 48, 52, 45, 48, 50, 128, 72, 79, 82, 73, 90, 79, 78, - 84, 65, 76, 45, 48, 52, 45, 48, 49, 128, 72, 79, 82, 73, 90, 79, 78, 84, - 65, 76, 45, 48, 52, 45, 48, 48, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, - 76, 45, 48, 51, 45, 48, 54, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, - 45, 48, 51, 45, 48, 53, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, - 48, 51, 45, 48, 52, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, - 51, 45, 48, 51, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 51, - 45, 48, 50, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 51, 45, - 48, 49, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 51, 45, 48, - 48, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 50, 45, 48, 54, - 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 50, 45, 48, 53, 128, - 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 50, 45, 48, 52, 128, 72, - 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 50, 45, 48, 51, 128, 72, 79, - 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 50, 45, 48, 50, 128, 72, 79, 82, - 73, 90, 79, 78, 84, 65, 76, 45, 48, 50, 45, 48, 49, 128, 72, 79, 82, 73, - 90, 79, 78, 84, 65, 76, 45, 48, 50, 45, 48, 48, 128, 72, 79, 82, 73, 90, - 79, 78, 84, 65, 76, 45, 48, 49, 45, 48, 54, 128, 72, 79, 82, 73, 90, 79, - 78, 84, 65, 76, 45, 48, 49, 45, 48, 53, 128, 72, 79, 82, 73, 90, 79, 78, - 84, 65, 76, 45, 48, 49, 45, 48, 52, 128, 72, 79, 82, 73, 90, 79, 78, 84, - 65, 76, 45, 48, 49, 45, 48, 51, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, - 76, 45, 48, 49, 45, 48, 50, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, - 45, 48, 49, 45, 48, 49, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, - 48, 49, 45, 48, 48, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, - 48, 45, 48, 54, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 48, - 45, 48, 53, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 48, 45, - 48, 52, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 48, 45, 48, - 51, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 48, 45, 48, 50, - 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 48, 45, 48, 49, 128, - 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 48, 45, 48, 48, 128, 72, - 79, 82, 73, 90, 79, 78, 84, 65, 76, 128, 72, 79, 82, 73, 90, 79, 78, 84, - 65, 204, 72, 79, 82, 73, 128, 72, 79, 82, 193, 72, 79, 79, 85, 128, 72, - 79, 79, 82, 85, 128, 72, 79, 79, 80, 128, 72, 79, 79, 78, 128, 72, 79, - 79, 75, 69, 68, 128, 72, 79, 79, 75, 69, 196, 72, 79, 78, 69, 89, 66, 69, - 69, 128, 72, 79, 78, 69, 217, 72, 79, 77, 79, 84, 72, 69, 84, 73, 67, - 128, 72, 79, 77, 79, 84, 72, 69, 84, 73, 195, 72, 79, 76, 79, 128, 72, - 79, 76, 76, 79, 215, 72, 79, 76, 69, 128, 72, 79, 76, 68, 73, 78, 199, - 72, 79, 76, 65, 77, 128, 72, 79, 76, 65, 205, 72, 79, 75, 65, 128, 72, - 79, 67, 75, 69, 217, 72, 79, 67, 72, 79, 128, 72, 79, 45, 56, 128, 72, - 79, 45, 55, 128, 72, 79, 45, 54, 128, 72, 79, 45, 53, 128, 72, 79, 45, - 52, 128, 72, 79, 45, 51, 128, 72, 79, 45, 50, 128, 72, 79, 45, 49, 128, - 72, 78, 85, 84, 128, 72, 78, 85, 79, 88, 128, 72, 78, 85, 79, 128, 72, - 78, 85, 66, 128, 72, 78, 79, 88, 128, 72, 78, 79, 84, 128, 72, 78, 79, - 80, 128, 72, 78, 73, 88, 128, 72, 78, 73, 84, 128, 72, 78, 73, 80, 128, - 72, 78, 73, 69, 88, 128, 72, 78, 73, 69, 84, 128, 72, 78, 73, 69, 80, - 128, 72, 78, 73, 69, 128, 72, 78, 73, 128, 72, 78, 69, 88, 128, 72, 78, - 69, 80, 128, 72, 78, 69, 128, 72, 78, 65, 88, 128, 72, 78, 65, 85, 128, - 72, 78, 65, 84, 128, 72, 78, 65, 80, 128, 72, 78, 65, 128, 72, 77, 89, - 88, 128, 72, 77, 89, 82, 88, 128, 72, 77, 89, 82, 128, 72, 77, 89, 80, - 128, 72, 77, 89, 128, 72, 77, 85, 88, 128, 72, 77, 85, 84, 128, 72, 77, - 85, 82, 88, 128, 72, 77, 85, 82, 128, 72, 77, 85, 80, 128, 72, 77, 85, - 79, 88, 128, 72, 77, 85, 79, 80, 128, 72, 77, 85, 79, 128, 72, 77, 85, - 128, 72, 77, 79, 88, 128, 72, 77, 79, 84, 128, 72, 77, 79, 80, 128, 72, - 77, 79, 128, 72, 77, 73, 88, 128, 72, 77, 73, 84, 128, 72, 77, 73, 80, - 128, 72, 77, 73, 69, 88, 128, 72, 77, 73, 69, 80, 128, 72, 77, 73, 69, - 128, 72, 77, 73, 128, 72, 77, 69, 128, 72, 77, 65, 88, 128, 72, 77, 65, - 84, 128, 72, 77, 65, 80, 128, 72, 77, 65, 128, 72, 76, 89, 88, 128, 72, - 76, 89, 84, 128, 72, 76, 89, 82, 88, 128, 72, 76, 89, 82, 128, 72, 76, - 89, 80, 128, 72, 76, 89, 128, 72, 76, 85, 88, 128, 72, 76, 85, 84, 128, - 72, 76, 85, 82, 88, 128, 72, 76, 85, 82, 128, 72, 76, 85, 80, 128, 72, - 76, 85, 79, 88, 128, 72, 76, 85, 79, 80, 128, 72, 76, 85, 79, 128, 72, - 76, 85, 128, 72, 76, 79, 88, 128, 72, 76, 79, 80, 128, 72, 76, 79, 128, - 72, 76, 73, 88, 128, 72, 76, 73, 84, 128, 72, 76, 73, 80, 128, 72, 76, - 73, 69, 88, 128, 72, 76, 73, 69, 80, 128, 72, 76, 73, 69, 128, 72, 76, - 73, 128, 72, 76, 69, 88, 128, 72, 76, 69, 80, 128, 72, 76, 69, 128, 72, - 76, 65, 88, 128, 72, 76, 65, 85, 128, 72, 76, 65, 84, 128, 72, 76, 65, - 80, 128, 72, 76, 65, 128, 72, 76, 128, 72, 75, 128, 72, 73, 90, 66, 128, - 72, 73, 89, 79, 128, 72, 73, 84, 84, 73, 78, 199, 72, 73, 83, 84, 79, 82, - 73, 195, 72, 73, 82, 73, 81, 128, 72, 73, 80, 80, 79, 80, 79, 84, 65, 77, - 85, 83, 128, 72, 73, 78, 71, 69, 68, 128, 72, 73, 78, 71, 69, 196, 72, - 73, 78, 71, 69, 128, 72, 73, 78, 68, 213, 72, 73, 75, 73, 78, 199, 72, - 73, 71, 72, 45, 83, 80, 69, 69, 196, 72, 73, 71, 72, 45, 82, 69, 86, 69, - 82, 83, 69, 68, 45, 185, 72, 73, 71, 72, 45, 76, 79, 215, 72, 73, 71, 72, - 45, 72, 69, 69, 76, 69, 196, 72, 73, 69, 88, 128, 72, 73, 69, 85, 72, 45, - 83, 73, 79, 83, 128, 72, 73, 69, 85, 72, 45, 82, 73, 69, 85, 76, 128, 72, - 73, 69, 85, 72, 45, 80, 73, 69, 85, 80, 128, 72, 73, 69, 85, 72, 45, 78, - 73, 69, 85, 78, 128, 72, 73, 69, 85, 72, 45, 77, 73, 69, 85, 77, 128, 72, - 73, 69, 85, 200, 72, 73, 69, 82, 79, 71, 76, 89, 80, 72, 73, 195, 72, 73, - 68, 73, 78, 199, 72, 73, 68, 69, 84, 128, 72, 73, 68, 69, 128, 72, 73, - 66, 73, 83, 67, 85, 83, 128, 72, 73, 45, 82, 69, 83, 128, 72, 73, 45, 55, - 128, 72, 73, 45, 54, 128, 72, 73, 45, 53, 128, 72, 73, 45, 52, 128, 72, - 73, 45, 51, 128, 72, 73, 45, 50, 128, 72, 73, 45, 49, 128, 72, 72, 89, - 85, 128, 72, 72, 89, 79, 128, 72, 72, 89, 73, 128, 72, 72, 89, 69, 69, - 128, 72, 72, 89, 69, 128, 72, 72, 89, 65, 65, 128, 72, 72, 89, 65, 128, - 72, 72, 87, 73, 128, 72, 72, 87, 69, 69, 128, 72, 72, 87, 69, 128, 72, - 72, 87, 65, 128, 72, 72, 85, 128, 72, 72, 73, 128, 72, 72, 69, 69, 128, - 72, 72, 69, 128, 72, 72, 65, 65, 128, 72, 71, 128, 72, 69, 89, 84, 128, - 72, 69, 88, 73, 70, 79, 82, 205, 72, 69, 88, 65, 71, 82, 65, 205, 72, 69, - 88, 65, 71, 79, 78, 128, 72, 69, 82, 85, 84, 85, 128, 72, 69, 82, 85, - 128, 72, 69, 82, 77, 73, 84, 73, 65, 206, 72, 69, 82, 77, 73, 79, 78, 73, - 65, 206, 72, 69, 82, 77, 69, 83, 128, 72, 69, 82, 69, 128, 72, 69, 82, - 66, 128, 72, 69, 82, 65, 69, 85, 205, 72, 69, 78, 71, 128, 72, 69, 78, - 199, 72, 69, 77, 80, 128, 72, 69, 76, 77, 69, 84, 128, 72, 69, 76, 77, - 69, 212, 72, 69, 76, 205, 72, 69, 76, 76, 83, 67, 72, 82, 69, 73, 66, 69, - 210, 72, 69, 76, 73, 88, 128, 72, 69, 76, 73, 67, 79, 80, 84, 69, 82, - 128, 72, 69, 75, 85, 84, 65, 65, 82, 85, 128, 72, 69, 73, 83, 69, 73, - 128, 72, 69, 73, 71, 72, 84, 128, 72, 69, 69, 73, 128, 72, 69, 68, 71, - 69, 72, 79, 71, 128, 72, 69, 65, 86, 89, 128, 72, 69, 65, 86, 69, 78, 76, - 217, 72, 69, 65, 86, 69, 78, 128, 72, 69, 65, 86, 69, 206, 72, 69, 65, - 82, 84, 83, 128, 72, 69, 65, 82, 84, 45, 83, 72, 65, 80, 69, 196, 72, 69, - 65, 82, 84, 128, 72, 69, 65, 82, 212, 72, 69, 65, 82, 73, 78, 199, 72, - 69, 65, 82, 45, 78, 79, 45, 69, 86, 73, 204, 72, 69, 65, 68, 83, 84, 82, - 79, 75, 69, 128, 72, 69, 65, 68, 83, 84, 79, 78, 69, 128, 72, 69, 65, 68, - 83, 84, 79, 78, 197, 72, 69, 65, 68, 83, 67, 65, 82, 70, 128, 72, 69, 65, - 68, 80, 72, 79, 78, 69, 128, 72, 69, 65, 68, 73, 78, 71, 128, 72, 69, 65, - 68, 45, 66, 65, 78, 68, 65, 71, 69, 128, 72, 69, 45, 55, 128, 72, 69, 45, - 54, 128, 72, 69, 45, 53, 128, 72, 69, 45, 52, 128, 72, 69, 45, 51, 128, - 72, 69, 45, 50, 128, 72, 69, 45, 49, 128, 72, 68, 82, 128, 72, 67, 128, - 72, 66, 65, 83, 65, 45, 69, 83, 65, 83, 193, 72, 66, 65, 83, 193, 72, 65, - 89, 65, 78, 78, 65, 128, 72, 65, 87, 74, 128, 72, 65, 86, 69, 128, 72, - 65, 85, 80, 84, 83, 84, 73, 77, 77, 69, 128, 72, 65, 213, 72, 65, 84, 82, - 65, 206, 72, 65, 84, 72, 73, 128, 72, 65, 84, 69, 128, 72, 65, 84, 67, - 72, 73, 78, 199, 72, 65, 84, 65, 198, 72, 65, 83, 69, 210, 72, 65, 83, - 65, 78, 84, 65, 128, 72, 65, 82, 80, 79, 79, 78, 128, 72, 65, 82, 80, 79, - 79, 206, 72, 65, 82, 77, 79, 78, 73, 67, 128, 72, 65, 82, 75, 76, 69, 65, - 206, 72, 65, 82, 68, 78, 69, 83, 83, 128, 72, 65, 82, 196, 72, 65, 82, - 66, 65, 72, 65, 89, 128, 72, 65, 80, 80, 217, 72, 65, 78, 85, 78, 79, - 207, 72, 65, 78, 73, 70, 201, 72, 65, 78, 71, 90, 72, 79, 213, 72, 65, - 78, 68, 83, 72, 65, 75, 69, 128, 72, 65, 78, 68, 83, 128, 72, 65, 78, 68, - 211, 72, 65, 78, 68, 76, 69, 83, 128, 72, 65, 78, 68, 76, 69, 128, 72, - 65, 78, 68, 66, 65, 76, 76, 128, 72, 65, 78, 68, 66, 65, 71, 128, 72, 65, - 78, 68, 45, 79, 86, 65, 76, 128, 72, 65, 78, 68, 45, 79, 86, 65, 204, 72, - 65, 78, 68, 45, 72, 79, 79, 75, 128, 72, 65, 78, 68, 45, 72, 79, 79, 203, - 72, 65, 78, 68, 45, 72, 73, 78, 71, 69, 128, 72, 65, 78, 68, 45, 72, 73, - 78, 71, 197, 72, 65, 78, 68, 45, 70, 76, 65, 84, 128, 72, 65, 78, 68, 45, - 70, 76, 65, 212, 72, 65, 78, 68, 45, 70, 73, 83, 84, 128, 72, 65, 78, 68, - 45, 67, 85, 82, 76, 73, 67, 85, 69, 128, 72, 65, 78, 68, 45, 67, 85, 82, - 76, 73, 67, 85, 197, 72, 65, 78, 68, 45, 67, 85, 80, 128, 72, 65, 78, 68, - 45, 67, 85, 208, 72, 65, 78, 68, 45, 67, 76, 65, 87, 128, 72, 65, 78, 68, - 45, 67, 76, 65, 215, 72, 65, 78, 68, 45, 67, 73, 82, 67, 76, 69, 128, 72, - 65, 78, 68, 45, 67, 73, 82, 67, 76, 197, 72, 65, 78, 68, 45, 65, 78, 71, - 76, 69, 128, 72, 65, 78, 68, 45, 65, 78, 71, 76, 197, 72, 65, 78, 68, - 128, 72, 65, 78, 45, 65, 75, 65, 84, 128, 72, 65, 77, 90, 65, 128, 72, - 65, 77, 90, 193, 72, 65, 77, 83, 84, 69, 210, 72, 65, 77, 83, 65, 128, - 72, 65, 77, 77, 69, 82, 128, 72, 65, 77, 77, 69, 210, 72, 65, 77, 66, 85, - 82, 71, 69, 82, 128, 72, 65, 76, 81, 65, 128, 72, 65, 76, 79, 128, 72, - 65, 76, 70, 45, 67, 73, 82, 67, 76, 197, 72, 65, 76, 70, 45, 50, 128, 72, - 65, 76, 70, 45, 49, 128, 72, 65, 76, 70, 128, 72, 65, 76, 66, 69, 82, 68, - 128, 72, 65, 76, 65, 78, 84, 65, 128, 72, 65, 73, 84, 85, 128, 72, 65, - 73, 211, 72, 65, 73, 82, 67, 85, 84, 128, 72, 65, 71, 76, 65, 218, 72, - 65, 71, 76, 128, 72, 65, 70, 85, 75, 72, 65, 128, 72, 65, 70, 85, 75, 72, - 128, 72, 65, 69, 71, 204, 72, 65, 68, 69, 83, 128, 72, 65, 65, 82, 85, - 128, 72, 65, 65, 77, 128, 72, 65, 193, 72, 65, 45, 72, 65, 128, 72, 65, - 45, 57, 128, 72, 65, 45, 56, 128, 72, 65, 45, 55, 128, 72, 65, 45, 54, - 128, 72, 65, 45, 53, 128, 72, 65, 45, 52, 128, 72, 65, 45, 51, 128, 72, - 65, 45, 50, 128, 72, 65, 45, 49, 49, 128, 72, 65, 45, 49, 48, 128, 72, - 65, 45, 49, 128, 72, 48, 48, 56, 128, 72, 48, 48, 55, 128, 72, 48, 48, - 54, 65, 128, 72, 48, 48, 54, 128, 72, 48, 48, 53, 128, 72, 48, 48, 52, - 128, 72, 48, 48, 51, 128, 72, 48, 48, 50, 128, 72, 48, 48, 49, 128, 72, - 45, 84, 89, 80, 197, 71, 89, 85, 128, 71, 89, 79, 78, 128, 71, 89, 79, - 128, 71, 89, 73, 128, 71, 89, 70, 213, 71, 89, 69, 69, 128, 71, 89, 65, - 83, 128, 71, 89, 65, 65, 128, 71, 89, 65, 128, 71, 89, 128, 71, 87, 85, - 128, 71, 87, 73, 128, 71, 87, 69, 69, 128, 71, 87, 69, 128, 71, 87, 65, - 65, 128, 71, 87, 65, 128, 71, 87, 128, 71, 86, 65, 78, 71, 128, 71, 86, - 128, 71, 85, 82, 85, 83, 72, 128, 71, 85, 82, 85, 78, 128, 71, 85, 82, - 77, 85, 75, 72, 201, 71, 85, 82, 65, 77, 85, 84, 79, 78, 128, 71, 85, 82, - 65, 71, 197, 71, 85, 82, 55, 128, 71, 85, 78, 85, 128, 71, 85, 78, 213, - 71, 85, 78, 74, 65, 76, 193, 71, 85, 205, 71, 85, 76, 128, 71, 85, 74, - 65, 82, 65, 84, 201, 71, 85, 73, 84, 65, 82, 128, 71, 85, 73, 68, 197, - 71, 85, 199, 71, 85, 69, 73, 128, 71, 85, 69, 72, 128, 71, 85, 69, 200, - 71, 85, 68, 128, 71, 85, 196, 71, 85, 65, 82, 68, 83, 77, 65, 78, 128, - 71, 85, 65, 82, 68, 69, 68, 78, 69, 83, 83, 128, 71, 85, 65, 82, 68, 69, - 196, 71, 85, 65, 82, 68, 128, 71, 85, 65, 82, 65, 78, 201, 71, 85, 193, - 71, 85, 178, 71, 84, 69, 210, 71, 83, 85, 77, 128, 71, 83, 85, 205, 71, - 82, 213, 71, 82, 79, 87, 73, 78, 199, 71, 82, 79, 85, 78, 68, 128, 71, - 82, 79, 78, 84, 72, 73, 83, 77, 65, 84, 65, 128, 71, 82, 79, 77, 79, 80, - 79, 86, 79, 68, 78, 65, 89, 65, 128, 71, 82, 79, 77, 79, 80, 79, 86, 79, - 68, 78, 65, 89, 193, 71, 82, 79, 77, 79, 75, 82, 89, 90, 72, 69, 86, 65, - 89, 65, 128, 71, 82, 79, 77, 79, 75, 82, 89, 90, 72, 69, 86, 65, 89, 193, - 71, 82, 79, 77, 78, 65, 89, 65, 128, 71, 82, 79, 77, 78, 65, 89, 193, 71, - 82, 73, 78, 78, 73, 78, 199, 71, 82, 73, 77, 65, 67, 73, 78, 199, 71, 82, - 69, 71, 79, 82, 73, 65, 206, 71, 82, 69, 69, 78, 128, 71, 82, 69, 69, - 206, 71, 82, 69, 65, 84, 78, 69, 83, 83, 128, 71, 82, 69, 65, 84, 69, 82, - 45, 84, 72, 65, 78, 128, 71, 82, 69, 65, 84, 69, 82, 45, 84, 72, 65, 206, - 71, 82, 69, 65, 84, 69, 210, 71, 82, 69, 65, 212, 71, 82, 65, 86, 69, 89, - 65, 82, 196, 71, 82, 65, 86, 69, 45, 77, 65, 67, 82, 79, 78, 128, 71, 82, - 65, 86, 69, 45, 65, 67, 85, 84, 69, 45, 71, 82, 65, 86, 69, 128, 71, 82, - 65, 86, 197, 71, 82, 65, 84, 69, 82, 128, 71, 82, 65, 83, 83, 128, 71, - 82, 65, 83, 211, 71, 82, 65, 83, 208, 71, 82, 65, 80, 72, 69, 77, 197, - 71, 82, 65, 80, 69, 83, 128, 71, 82, 65, 78, 84, 72, 193, 71, 82, 65, 77, - 77, 193, 71, 82, 65, 73, 78, 128, 71, 82, 65, 70, 128, 71, 82, 65, 68, - 85, 65, 84, 73, 79, 206, 71, 82, 65, 68, 85, 65, 76, 128, 71, 82, 65, 67, - 69, 128, 71, 82, 65, 67, 197, 71, 80, 65, 128, 71, 79, 82, 84, 72, 77, - 73, 75, 79, 206, 71, 79, 82, 84, 128, 71, 79, 82, 73, 76, 76, 65, 128, - 71, 79, 82, 71, 79, 84, 69, 82, 73, 128, 71, 79, 82, 71, 79, 83, 89, 78, - 84, 72, 69, 84, 79, 78, 128, 71, 79, 82, 71, 79, 206, 71, 79, 82, 71, 73, - 128, 71, 79, 82, 65, 90, 68, 207, 71, 79, 82, 65, 128, 71, 79, 79, 196, - 71, 79, 78, 71, 128, 71, 79, 76, 85, 66, 67, 72, 73, 203, 71, 79, 76, 70, - 69, 82, 128, 71, 79, 76, 68, 128, 71, 79, 75, 128, 71, 79, 73, 78, 199, - 71, 79, 71, 71, 76, 69, 83, 128, 71, 79, 66, 76, 73, 78, 128, 71, 79, 65, - 76, 128, 71, 79, 65, 204, 71, 79, 65, 128, 71, 78, 89, 73, 83, 128, 71, - 78, 65, 86, 73, 89, 65, 78, 73, 128, 71, 76, 79, 87, 73, 78, 199, 71, 76, - 79, 86, 69, 83, 128, 71, 76, 79, 86, 69, 128, 71, 76, 79, 84, 84, 65, - 204, 71, 76, 79, 66, 197, 71, 76, 73, 83, 83, 65, 78, 68, 207, 71, 76, - 69, 73, 67, 200, 71, 76, 65, 71, 79, 76, 73, 128, 71, 76, 65, 128, 71, - 74, 69, 128, 71, 73, 88, 128, 71, 73, 84, 128, 71, 73, 83, 72, 128, 71, - 73, 83, 200, 71, 73, 83, 65, 76, 128, 71, 73, 82, 85, 68, 65, 65, 128, - 71, 73, 82, 76, 211, 71, 73, 82, 76, 128, 71, 73, 82, 65, 70, 70, 197, - 71, 73, 82, 51, 128, 71, 73, 82, 179, 71, 73, 82, 50, 128, 71, 73, 82, - 178, 71, 73, 80, 128, 71, 73, 78, 73, 73, 128, 71, 73, 77, 69, 76, 45, - 72, 69, 84, 72, 128, 71, 73, 77, 69, 76, 128, 71, 73, 77, 69, 204, 71, - 73, 77, 128, 71, 73, 71, 65, 128, 71, 73, 71, 128, 71, 73, 70, 212, 71, - 73, 69, 84, 128, 71, 73, 68, 73, 77, 128, 71, 73, 66, 66, 79, 85, 211, - 71, 73, 66, 65, 128, 71, 73, 52, 128, 71, 73, 180, 71, 72, 90, 128, 71, - 72, 87, 65, 128, 71, 72, 85, 78, 78, 65, 128, 71, 72, 85, 78, 78, 193, - 71, 72, 85, 128, 71, 72, 79, 85, 128, 71, 72, 79, 83, 84, 128, 71, 72, - 79, 128, 71, 72, 73, 77, 69, 76, 128, 71, 72, 73, 128, 71, 72, 72, 65, - 128, 71, 72, 69, 89, 83, 128, 71, 72, 69, 85, 88, 128, 71, 72, 69, 85, - 78, 128, 71, 72, 69, 85, 71, 72, 69, 85, 65, 69, 77, 128, 71, 72, 69, 85, - 71, 72, 69, 78, 128, 71, 72, 69, 85, 65, 69, 82, 65, 69, 128, 71, 72, 69, - 85, 65, 69, 71, 72, 69, 85, 65, 69, 128, 71, 72, 69, 84, 128, 71, 72, 69, - 69, 128, 71, 72, 69, 128, 71, 72, 197, 71, 72, 65, 89, 78, 128, 71, 72, - 65, 82, 65, 69, 128, 71, 72, 65, 80, 128, 71, 72, 65, 78, 128, 71, 72, - 65, 77, 77, 65, 128, 71, 72, 65, 77, 65, 76, 128, 71, 72, 65, 73, 78, 85, + 77, 85, 73, 78, 128, 77, 85, 72, 79, 82, 128, 77, 85, 71, 83, 128, 77, + 85, 71, 128, 77, 85, 199, 77, 85, 69, 78, 128, 77, 85, 69, 128, 77, 85, + 67, 72, 128, 77, 85, 67, 200, 77, 85, 67, 65, 65, 68, 128, 77, 85, 65, + 83, 128, 77, 85, 65, 78, 128, 77, 85, 65, 69, 128, 77, 85, 45, 71, 65, + 65, 72, 76, 65, 193, 77, 85, 45, 52, 128, 77, 85, 45, 51, 128, 77, 85, + 45, 50, 128, 77, 85, 45, 49, 128, 77, 213, 77, 84, 65, 86, 82, 85, 76, + 201, 77, 83, 128, 77, 82, 207, 77, 82, 65, 67, 72, 78, 89, 128, 77, 82, + 65, 67, 72, 78, 79, 84, 73, 75, 72, 65, 89, 65, 128, 77, 82, 65, 67, 72, + 78, 79, 128, 77, 82, 65, 67, 72, 78, 65, 89, 65, 128, 77, 210, 77, 81, + 128, 77, 80, 65, 128, 77, 79, 89, 65, 73, 128, 77, 79, 88, 128, 77, 79, + 86, 73, 197, 77, 79, 86, 69, 211, 77, 79, 86, 69, 77, 69, 78, 84, 45, 87, + 65, 76, 76, 80, 76, 65, 78, 197, 77, 79, 86, 69, 77, 69, 78, 84, 45, 72, + 73, 78, 71, 197, 77, 79, 86, 69, 77, 69, 78, 84, 45, 70, 76, 79, 79, 82, + 80, 76, 65, 78, 197, 77, 79, 86, 69, 77, 69, 78, 84, 45, 68, 73, 65, 71, + 79, 78, 65, 204, 77, 79, 86, 69, 77, 69, 78, 84, 128, 77, 79, 86, 69, 77, + 69, 78, 212, 77, 79, 86, 69, 196, 77, 79, 86, 69, 128, 77, 79, 85, 84, + 72, 128, 77, 79, 85, 83, 69, 128, 77, 79, 85, 83, 197, 77, 79, 85, 78, + 84, 65, 73, 78, 83, 128, 77, 79, 85, 78, 84, 65, 73, 78, 128, 77, 79, 85, + 78, 84, 65, 73, 206, 77, 79, 85, 78, 212, 77, 79, 85, 78, 68, 128, 77, + 79, 85, 78, 196, 77, 79, 84, 79, 82, 87, 65, 89, 128, 77, 79, 84, 79, 82, + 73, 90, 69, 196, 77, 79, 84, 79, 82, 67, 89, 67, 76, 69, 128, 77, 79, 84, + 79, 210, 77, 79, 84, 72, 69, 82, 128, 77, 79, 84, 72, 69, 210, 77, 79, + 84, 128, 77, 79, 83, 81, 85, 73, 84, 79, 128, 77, 79, 83, 81, 85, 69, + 128, 77, 79, 82, 84, 85, 85, 77, 128, 77, 79, 82, 84, 65, 82, 128, 77, + 79, 82, 80, 72, 79, 76, 79, 71, 73, 67, 65, 204, 77, 79, 82, 78, 73, 78, + 71, 128, 77, 79, 80, 128, 77, 79, 79, 83, 69, 45, 67, 82, 69, 197, 77, + 79, 79, 83, 69, 128, 77, 79, 79, 78, 128, 77, 79, 79, 206, 77, 79, 79, + 77, 80, 85, 81, 128, 77, 79, 79, 77, 69, 85, 84, 128, 77, 79, 79, 68, + 128, 77, 79, 79, 196, 77, 79, 79, 128, 77, 79, 78, 84, 73, 69, 69, 78, + 128, 77, 79, 78, 84, 72, 128, 77, 79, 78, 84, 200, 77, 79, 78, 83, 84, + 69, 82, 128, 77, 79, 78, 79, 83, 84, 65, 66, 76, 197, 77, 79, 78, 79, 83, + 80, 65, 67, 197, 77, 79, 78, 79, 82, 65, 73, 76, 128, 77, 79, 78, 79, 71, + 82, 65, 80, 200, 77, 79, 78, 79, 71, 82, 65, 77, 77, 79, 211, 77, 79, 78, + 79, 71, 82, 65, 205, 77, 79, 78, 79, 70, 79, 78, 73, 65, 83, 128, 77, 79, + 78, 79, 67, 85, 76, 65, 210, 77, 79, 78, 79, 67, 76, 69, 128, 77, 79, 78, + 75, 69, 89, 128, 77, 79, 78, 75, 69, 217, 77, 79, 78, 73, 128, 77, 79, + 78, 71, 75, 69, 85, 65, 69, 81, 128, 77, 79, 78, 69, 89, 45, 77, 79, 85, + 84, 200, 77, 79, 78, 69, 217, 77, 79, 78, 128, 77, 79, 206, 77, 79, 76, + 128, 77, 79, 75, 72, 65, 83, 83, 65, 83, 128, 77, 79, 72, 65, 77, 77, 65, + 196, 77, 79, 68, 85, 76, 207, 77, 79, 68, 73, 70, 73, 69, 82, 45, 57, + 128, 77, 79, 68, 73, 70, 73, 69, 82, 45, 56, 128, 77, 79, 68, 73, 70, 73, + 69, 82, 45, 55, 128, 77, 79, 68, 73, 70, 73, 69, 82, 45, 54, 128, 77, 79, + 68, 73, 70, 73, 69, 82, 45, 53, 128, 77, 79, 68, 73, 70, 73, 69, 82, 45, + 52, 128, 77, 79, 68, 73, 70, 73, 69, 82, 45, 51, 128, 77, 79, 68, 73, 70, + 73, 69, 82, 45, 50, 128, 77, 79, 68, 73, 70, 73, 69, 82, 45, 49, 54, 128, + 77, 79, 68, 73, 70, 73, 69, 82, 45, 49, 53, 128, 77, 79, 68, 73, 70, 73, + 69, 82, 45, 49, 52, 128, 77, 79, 68, 73, 70, 73, 69, 82, 45, 49, 51, 128, + 77, 79, 68, 73, 70, 73, 69, 82, 45, 49, 50, 128, 77, 79, 68, 73, 70, 73, + 69, 82, 45, 49, 49, 128, 77, 79, 68, 73, 70, 73, 69, 82, 45, 49, 48, 128, + 77, 79, 68, 73, 70, 73, 69, 82, 128, 77, 79, 68, 201, 77, 79, 68, 69, 83, + 84, 89, 128, 77, 79, 68, 69, 82, 206, 77, 79, 68, 69, 77, 128, 77, 79, + 68, 69, 76, 83, 128, 77, 79, 68, 69, 76, 128, 77, 79, 68, 69, 128, 77, + 79, 66, 73, 76, 197, 77, 79, 65, 128, 77, 79, 45, 54, 128, 77, 79, 45, + 53, 128, 77, 79, 45, 52, 128, 77, 79, 45, 51, 128, 77, 207, 77, 78, 89, + 65, 205, 77, 78, 65, 83, 128, 77, 77, 83, 80, 128, 77, 77, 128, 77, 205, + 77, 76, 65, 128, 77, 76, 128, 77, 75, 80, 65, 82, 65, 209, 77, 73, 88, + 128, 77, 73, 84, 128, 77, 73, 83, 82, 65, 128, 77, 73, 82, 82, 79, 82, + 128, 77, 73, 82, 82, 79, 210, 77, 73, 82, 73, 66, 65, 65, 82, 85, 128, + 77, 73, 82, 73, 128, 77, 73, 82, 69, 68, 128, 77, 73, 80, 128, 77, 73, + 78, 89, 128, 77, 73, 78, 85, 83, 45, 79, 82, 45, 80, 76, 85, 211, 77, 73, + 78, 85, 83, 128, 77, 73, 78, 78, 65, 206, 77, 73, 78, 73, 83, 84, 69, 82, + 128, 77, 73, 78, 73, 77, 73, 90, 69, 128, 77, 73, 78, 73, 77, 65, 128, + 77, 73, 78, 73, 68, 73, 83, 67, 128, 77, 73, 78, 73, 66, 85, 83, 128, 77, + 73, 78, 68, 85, 128, 77, 73, 77, 69, 128, 77, 73, 77, 128, 77, 73, 76, + 76, 73, 79, 78, 83, 128, 77, 73, 76, 76, 73, 79, 78, 211, 77, 73, 76, 76, + 69, 84, 128, 77, 73, 76, 76, 197, 77, 73, 76, 204, 77, 73, 76, 75, 217, + 77, 73, 76, 75, 128, 77, 73, 76, 73, 84, 65, 82, 217, 77, 73, 76, 128, + 77, 73, 75, 85, 82, 79, 78, 128, 77, 73, 75, 82, 79, 206, 77, 73, 75, 82, + 73, 128, 77, 73, 73, 78, 128, 77, 73, 73, 77, 128, 77, 73, 73, 128, 77, + 73, 199, 77, 73, 69, 88, 128, 77, 73, 69, 85, 77, 45, 84, 73, 75, 69, 85, + 84, 128, 77, 73, 69, 85, 77, 45, 83, 83, 65, 78, 71, 83, 73, 79, 83, 128, + 77, 73, 69, 85, 77, 45, 83, 83, 65, 78, 71, 78, 73, 69, 85, 78, 128, 77, + 73, 69, 85, 77, 45, 82, 73, 69, 85, 76, 128, 77, 73, 69, 85, 77, 45, 80, + 73, 69, 85, 80, 45, 83, 73, 79, 83, 128, 77, 73, 69, 85, 77, 45, 80, 73, + 69, 85, 80, 128, 77, 73, 69, 85, 77, 45, 80, 65, 78, 83, 73, 79, 83, 128, + 77, 73, 69, 85, 77, 45, 78, 73, 69, 85, 78, 128, 77, 73, 69, 85, 77, 45, + 67, 73, 69, 85, 67, 128, 77, 73, 69, 85, 77, 45, 67, 72, 73, 69, 85, 67, + 72, 128, 77, 73, 69, 85, 205, 77, 73, 69, 80, 128, 77, 73, 69, 69, 128, + 77, 73, 69, 128, 77, 73, 68, 76, 73, 78, 197, 77, 73, 68, 68, 76, 69, 45, + 87, 69, 76, 83, 200, 77, 73, 68, 68, 76, 69, 128, 77, 73, 68, 45, 76, 69, + 86, 69, 204, 77, 73, 68, 45, 72, 69, 73, 71, 72, 212, 77, 73, 196, 77, + 73, 67, 82, 79, 83, 67, 79, 80, 69, 128, 77, 73, 67, 82, 79, 80, 72, 79, + 78, 69, 128, 77, 73, 67, 82, 79, 66, 69, 128, 77, 73, 67, 82, 207, 77, + 73, 67, 210, 77, 73, 45, 55, 128, 77, 73, 45, 54, 128, 77, 73, 45, 53, + 128, 77, 73, 45, 52, 128, 77, 73, 45, 51, 128, 77, 73, 45, 50, 128, 77, + 73, 45, 49, 128, 77, 72, 90, 128, 77, 72, 65, 128, 77, 72, 128, 77, 71, + 85, 88, 128, 77, 71, 85, 84, 128, 77, 71, 85, 82, 88, 128, 77, 71, 85, + 82, 128, 77, 71, 85, 80, 128, 77, 71, 85, 79, 88, 128, 77, 71, 85, 79, + 80, 128, 77, 71, 85, 79, 128, 77, 71, 85, 128, 77, 71, 79, 88, 128, 77, + 71, 79, 84, 128, 77, 71, 79, 80, 128, 77, 71, 79, 128, 77, 71, 207, 77, + 71, 73, 69, 88, 128, 77, 71, 73, 69, 128, 77, 71, 69, 88, 128, 77, 71, + 69, 80, 128, 77, 71, 69, 128, 77, 71, 66, 85, 128, 77, 71, 66, 79, 79, + 128, 77, 71, 66, 79, 70, 85, 77, 128, 77, 71, 66, 79, 128, 77, 71, 66, + 73, 128, 77, 71, 66, 69, 85, 78, 128, 77, 71, 66, 69, 78, 128, 77, 71, + 66, 69, 69, 128, 77, 71, 66, 69, 128, 77, 71, 66, 65, 83, 65, 81, 128, + 77, 71, 66, 65, 83, 65, 128, 77, 71, 65, 88, 128, 77, 71, 65, 84, 128, + 77, 71, 65, 80, 128, 77, 71, 65, 128, 77, 71, 128, 77, 70, 79, 78, 128, + 77, 70, 79, 206, 77, 70, 79, 128, 77, 70, 73, 89, 65, 81, 128, 77, 70, + 73, 69, 69, 128, 77, 70, 69, 85, 84, 128, 77, 70, 69, 85, 81, 128, 77, + 70, 69, 85, 65, 69, 128, 77, 70, 65, 65, 128, 77, 69, 90, 90, 79, 128, + 77, 69, 88, 128, 77, 69, 85, 212, 77, 69, 85, 81, 128, 77, 69, 85, 78, + 74, 79, 77, 78, 68, 69, 85, 81, 128, 77, 69, 85, 78, 128, 77, 69, 84, 82, + 79, 128, 77, 69, 84, 82, 73, 67, 65, 204, 77, 69, 84, 82, 73, 65, 128, + 77, 69, 84, 82, 69, 84, 69, 211, 77, 69, 84, 79, 66, 69, 76, 85, 83, 128, + 77, 69, 84, 69, 75, 128, 77, 69, 84, 69, 71, 128, 77, 69, 84, 65, 76, + 128, 77, 69, 84, 193, 77, 69, 83, 83, 69, 78, 73, 65, 206, 77, 69, 83, + 83, 65, 71, 69, 128, 77, 69, 83, 83, 65, 71, 197, 77, 69, 83, 79, 128, + 77, 69, 83, 73, 128, 77, 69, 83, 72, 128, 77, 69, 82, 80, 69, 82, 83, 79, + 78, 128, 77, 69, 82, 75, 72, 65, 128, 77, 69, 82, 75, 72, 193, 77, 69, + 82, 73, 68, 73, 65, 78, 83, 128, 77, 69, 82, 73, 128, 77, 69, 82, 71, 69, + 128, 77, 69, 82, 67, 85, 82, 89, 128, 77, 69, 82, 67, 85, 82, 217, 77, + 69, 78, 79, 82, 65, 200, 77, 69, 78, 79, 69, 128, 77, 69, 78, 68, 85, 84, + 128, 77, 69, 78, 128, 77, 69, 77, 79, 128, 77, 69, 77, 66, 69, 82, 83, + 72, 73, 80, 128, 77, 69, 77, 66, 69, 82, 128, 77, 69, 77, 66, 69, 210, + 77, 69, 77, 45, 81, 79, 80, 72, 128, 77, 69, 77, 128, 77, 69, 205, 77, + 69, 76, 84, 73, 78, 199, 77, 69, 76, 79, 68, 73, 195, 77, 69, 76, 73, 75, + 128, 77, 69, 73, 90, 73, 128, 77, 69, 71, 65, 84, 79, 78, 128, 77, 69, + 71, 65, 80, 72, 79, 78, 69, 128, 77, 69, 71, 65, 76, 73, 128, 77, 69, 69, + 84, 79, 82, 85, 128, 77, 69, 69, 84, 69, 201, 77, 69, 69, 84, 128, 77, + 69, 69, 77, 85, 128, 77, 69, 69, 77, 128, 77, 69, 69, 202, 77, 69, 69, + 69, 69, 128, 77, 69, 68, 73, 85, 77, 128, 77, 69, 68, 73, 85, 205, 77, + 69, 68, 73, 69, 86, 65, 204, 77, 69, 68, 73, 67, 73, 78, 69, 128, 77, 69, + 68, 73, 67, 65, 204, 77, 69, 68, 73, 65, 204, 77, 69, 68, 69, 70, 65, 73, + 68, 82, 73, 206, 77, 69, 68, 65, 76, 128, 77, 69, 67, 72, 73, 75, 128, + 77, 69, 67, 72, 73, 203, 77, 69, 67, 72, 65, 78, 73, 67, 65, 204, 77, 69, + 65, 84, 128, 77, 69, 65, 212, 77, 69, 65, 83, 85, 82, 69, 196, 77, 69, + 65, 83, 85, 82, 69, 128, 77, 69, 65, 83, 85, 82, 197, 77, 69, 45, 77, 65, + 128, 77, 69, 45, 50, 128, 77, 69, 45, 49, 128, 77, 68, 85, 206, 77, 196, + 77, 67, 72, 213, 77, 67, 72, 65, 206, 77, 67, 128, 77, 195, 77, 66, 85, + 85, 128, 77, 66, 85, 79, 81, 128, 77, 66, 85, 79, 128, 77, 66, 85, 69, + 128, 77, 66, 85, 65, 69, 77, 128, 77, 66, 85, 65, 69, 128, 77, 66, 79, + 79, 128, 77, 66, 79, 128, 77, 66, 73, 84, 128, 77, 66, 73, 212, 77, 66, + 73, 82, 73, 69, 69, 78, 128, 77, 66, 73, 128, 77, 66, 69, 85, 88, 128, + 77, 66, 69, 85, 82, 73, 128, 77, 66, 69, 85, 77, 128, 77, 66, 69, 82, 65, + 69, 128, 77, 66, 69, 78, 128, 77, 66, 69, 69, 75, 69, 69, 84, 128, 77, + 66, 69, 69, 128, 77, 66, 69, 128, 77, 66, 65, 81, 128, 77, 66, 65, 78, + 89, 73, 128, 77, 66, 65, 65, 82, 65, 69, 128, 77, 66, 65, 65, 75, 69, 84, + 128, 77, 66, 65, 65, 128, 77, 66, 65, 193, 77, 66, 193, 77, 66, 52, 128, + 77, 66, 51, 128, 77, 66, 50, 128, 77, 65, 89, 69, 203, 77, 65, 89, 65, + 78, 78, 65, 128, 77, 65, 89, 65, 206, 77, 65, 89, 128, 77, 65, 88, 73, + 77, 73, 90, 69, 128, 77, 65, 88, 73, 77, 65, 128, 77, 65, 88, 128, 77, + 65, 85, 128, 77, 65, 84, 84, 79, 67, 75, 128, 77, 65, 84, 82, 73, 88, + 128, 77, 65, 84, 69, 82, 73, 65, 76, 83, 128, 77, 65, 84, 128, 77, 65, + 83, 213, 77, 65, 83, 83, 73, 78, 71, 128, 77, 65, 83, 83, 65, 71, 69, + 128, 77, 65, 83, 79, 82, 193, 77, 65, 83, 75, 128, 77, 65, 83, 203, 77, + 65, 83, 72, 70, 65, 65, 84, 128, 77, 65, 83, 72, 50, 128, 77, 65, 83, 67, + 85, 76, 73, 78, 197, 77, 65, 83, 65, 82, 65, 205, 77, 65, 82, 89, 128, + 77, 65, 82, 87, 65, 82, 201, 77, 65, 82, 85, 75, 85, 128, 77, 65, 82, 84, + 89, 82, 73, 193, 77, 65, 82, 84, 73, 65, 204, 77, 65, 82, 82, 89, 73, 78, + 199, 77, 65, 82, 82, 73, 65, 71, 197, 77, 65, 82, 82, 65, 84, 65, 78, + 128, 77, 65, 82, 75, 211, 77, 65, 82, 75, 69, 82, 128, 77, 65, 82, 75, + 45, 52, 128, 77, 65, 82, 75, 45, 51, 128, 77, 65, 82, 75, 45, 50, 128, + 77, 65, 82, 75, 45, 49, 128, 77, 65, 82, 69, 128, 77, 65, 82, 67, 72, 69, + 206, 77, 65, 82, 67, 72, 128, 77, 65, 82, 67, 65, 84, 79, 45, 83, 84, 65, + 67, 67, 65, 84, 79, 128, 77, 65, 82, 67, 65, 84, 79, 128, 77, 65, 82, 67, + 65, 83, 73, 84, 69, 128, 77, 65, 82, 66, 85, 84, 65, 128, 77, 65, 82, 66, + 85, 84, 193, 77, 65, 82, 65, 67, 65, 83, 128, 77, 65, 82, 128, 77, 65, + 81, 65, 70, 128, 77, 65, 81, 128, 77, 65, 80, 76, 197, 77, 65, 80, 73, + 81, 128, 77, 65, 208, 77, 65, 79, 128, 77, 65, 78, 85, 65, 204, 77, 65, + 78, 84, 69, 76, 80, 73, 69, 67, 197, 77, 65, 78, 83, 89, 79, 78, 128, 77, + 65, 78, 83, 85, 65, 69, 128, 77, 65, 78, 78, 65, 218, 77, 65, 78, 78, 65, + 128, 77, 65, 78, 73, 67, 72, 65, 69, 65, 206, 77, 65, 78, 71, 79, 128, + 77, 65, 78, 71, 65, 76, 65, 77, 128, 77, 65, 78, 68, 65, 82, 73, 78, 128, + 77, 65, 78, 68, 65, 73, 76, 73, 78, 199, 77, 65, 78, 68, 65, 73, 195, 77, + 65, 78, 67, 72, 213, 77, 65, 78, 65, 212, 77, 65, 78, 65, 67, 76, 69, 83, + 128, 77, 65, 77, 77, 79, 84, 72, 128, 77, 65, 76, 84, 69, 83, 197, 77, + 65, 76, 207, 77, 65, 76, 69, 69, 82, 73, 128, 77, 65, 76, 197, 77, 65, + 76, 65, 75, 79, 206, 77, 65, 75, 83, 85, 82, 65, 128, 77, 65, 75, 83, 85, + 82, 193, 77, 65, 75, 69, 77, 65, 75, 69, 128, 77, 65, 75, 65, 83, 65, + 210, 77, 65, 73, 90, 69, 128, 77, 65, 73, 89, 65, 77, 79, 75, 128, 77, + 65, 73, 84, 65, 73, 75, 72, 85, 128, 77, 65, 73, 82, 85, 128, 77, 65, 73, + 77, 85, 65, 78, 128, 77, 65, 73, 77, 65, 76, 65, 73, 128, 77, 65, 73, 76, + 66, 79, 216, 77, 65, 73, 75, 85, 82, 79, 128, 77, 65, 73, 68, 69, 78, + 128, 77, 65, 73, 128, 77, 65, 72, 74, 79, 78, 199, 77, 65, 72, 72, 65, + 128, 77, 65, 72, 65, 80, 82, 65, 78, 65, 128, 77, 65, 72, 65, 80, 65, 75, + 72, 128, 77, 65, 72, 65, 74, 65, 78, 201, 77, 65, 72, 65, 65, 80, 82, 65, + 65, 78, 193, 77, 65, 72, 128, 77, 65, 71, 78, 73, 70, 89, 73, 78, 199, + 77, 65, 71, 78, 69, 84, 128, 77, 65, 71, 73, 195, 77, 65, 71, 69, 128, + 77, 65, 69, 83, 73, 128, 77, 65, 69, 78, 89, 73, 128, 77, 65, 69, 78, 74, + 69, 84, 128, 77, 65, 69, 77, 86, 69, 85, 88, 128, 77, 65, 69, 77, 75, 80, + 69, 78, 128, 77, 65, 69, 77, 71, 66, 73, 69, 69, 128, 77, 65, 69, 77, 66, + 71, 66, 73, 69, 69, 128, 77, 65, 69, 77, 66, 65, 128, 77, 65, 69, 77, + 128, 77, 65, 69, 76, 69, 69, 128, 77, 65, 69, 75, 69, 85, 80, 128, 77, + 65, 68, 89, 65, 128, 77, 65, 68, 85, 128, 77, 65, 68, 68, 65, 72, 128, + 77, 65, 68, 68, 65, 200, 77, 65, 68, 68, 65, 128, 77, 65, 68, 68, 193, + 77, 65, 67, 82, 79, 78, 45, 71, 82, 65, 86, 69, 128, 77, 65, 67, 82, 79, + 78, 45, 66, 82, 69, 86, 69, 128, 77, 65, 67, 82, 79, 78, 45, 65, 67, 85, + 84, 69, 128, 77, 65, 67, 82, 79, 78, 128, 77, 65, 67, 82, 79, 206, 77, + 65, 67, 72, 73, 78, 69, 128, 77, 65, 65, 89, 89, 65, 65, 128, 77, 65, 65, + 73, 128, 77, 65, 65, 128, 77, 65, 50, 128, 77, 65, 45, 55, 128, 77, 65, + 45, 54, 128, 77, 65, 45, 53, 128, 77, 65, 45, 52, 128, 77, 65, 45, 51, + 128, 77, 65, 45, 50, 128, 77, 65, 45, 49, 128, 77, 49, 57, 183, 77, 49, + 57, 182, 77, 49, 57, 181, 77, 49, 57, 180, 77, 49, 57, 179, 77, 49, 57, + 178, 77, 49, 57, 177, 77, 49, 57, 176, 77, 49, 56, 185, 77, 49, 56, 184, + 77, 49, 56, 183, 77, 49, 56, 182, 77, 49, 56, 181, 77, 49, 56, 180, 77, + 49, 56, 179, 77, 49, 56, 178, 77, 49, 56, 177, 77, 49, 56, 176, 77, 49, + 55, 185, 77, 49, 55, 184, 77, 49, 55, 183, 77, 49, 55, 182, 77, 49, 55, + 181, 77, 49, 55, 180, 77, 49, 55, 179, 77, 49, 55, 178, 77, 49, 55, 177, + 77, 49, 55, 176, 77, 49, 54, 185, 77, 49, 54, 184, 77, 49, 54, 183, 77, + 49, 54, 182, 77, 49, 54, 181, 77, 49, 54, 180, 77, 49, 54, 179, 77, 49, + 54, 178, 77, 49, 54, 177, 77, 49, 54, 176, 77, 49, 53, 185, 77, 49, 53, + 184, 77, 49, 53, 183, 77, 49, 53, 182, 77, 49, 53, 181, 77, 49, 53, 180, + 77, 49, 53, 179, 77, 49, 53, 178, 77, 49, 53, 177, 77, 49, 53, 176, 77, + 49, 52, 185, 77, 49, 52, 184, 77, 49, 52, 183, 77, 49, 52, 182, 77, 49, + 52, 181, 77, 49, 52, 180, 77, 49, 52, 179, 77, 49, 52, 178, 77, 49, 52, + 177, 77, 49, 52, 176, 77, 49, 51, 185, 77, 49, 51, 184, 77, 49, 51, 183, + 77, 49, 51, 182, 77, 49, 51, 181, 77, 49, 51, 180, 77, 49, 51, 179, 77, + 49, 51, 178, 77, 49, 51, 177, 77, 49, 51, 176, 77, 49, 50, 185, 77, 49, + 50, 184, 77, 49, 50, 183, 77, 49, 50, 182, 77, 49, 50, 181, 77, 49, 50, + 180, 77, 49, 50, 179, 77, 49, 50, 178, 77, 49, 50, 177, 77, 49, 50, 176, + 77, 49, 49, 185, 77, 49, 49, 184, 77, 49, 49, 183, 77, 49, 49, 182, 77, + 49, 49, 181, 77, 49, 49, 180, 77, 49, 49, 179, 77, 49, 49, 178, 77, 49, + 49, 177, 77, 49, 49, 176, 77, 49, 48, 185, 77, 49, 48, 184, 77, 49, 48, + 183, 77, 49, 48, 182, 77, 49, 48, 181, 77, 49, 48, 180, 77, 49, 48, 179, + 77, 49, 48, 178, 77, 49, 48, 177, 77, 49, 48, 176, 77, 48, 57, 185, 77, + 48, 57, 184, 77, 48, 57, 183, 77, 48, 57, 182, 77, 48, 57, 181, 77, 48, + 57, 180, 77, 48, 57, 179, 77, 48, 57, 178, 77, 48, 57, 177, 77, 48, 57, + 176, 77, 48, 56, 185, 77, 48, 56, 184, 77, 48, 56, 183, 77, 48, 56, 182, + 77, 48, 56, 181, 77, 48, 56, 180, 77, 48, 56, 179, 77, 48, 56, 178, 77, + 48, 56, 177, 77, 48, 56, 176, 77, 48, 55, 185, 77, 48, 55, 184, 77, 48, + 55, 183, 77, 48, 55, 182, 77, 48, 55, 181, 77, 48, 55, 180, 77, 48, 55, + 179, 77, 48, 55, 178, 77, 48, 55, 177, 77, 48, 55, 176, 77, 48, 54, 185, + 77, 48, 54, 184, 77, 48, 54, 183, 77, 48, 54, 182, 77, 48, 54, 181, 77, + 48, 54, 180, 77, 48, 54, 179, 77, 48, 54, 178, 77, 48, 54, 177, 77, 48, + 54, 176, 77, 48, 53, 185, 77, 48, 53, 184, 77, 48, 53, 183, 77, 48, 53, + 182, 77, 48, 53, 181, 77, 48, 53, 180, 77, 48, 53, 179, 77, 48, 53, 178, + 77, 48, 53, 177, 77, 48, 53, 176, 77, 48, 52, 185, 77, 48, 52, 184, 77, + 48, 52, 183, 77, 48, 52, 182, 77, 48, 52, 181, 77, 48, 52, 52, 128, 77, + 48, 52, 180, 77, 48, 52, 51, 128, 77, 48, 52, 179, 77, 48, 52, 50, 128, + 77, 48, 52, 178, 77, 48, 52, 49, 128, 77, 48, 52, 177, 77, 48, 52, 48, + 65, 128, 77, 48, 52, 48, 128, 77, 48, 52, 176, 77, 48, 51, 57, 128, 77, + 48, 51, 185, 77, 48, 51, 56, 128, 77, 48, 51, 184, 77, 48, 51, 55, 128, + 77, 48, 51, 183, 77, 48, 51, 54, 128, 77, 48, 51, 182, 77, 48, 51, 53, + 128, 77, 48, 51, 181, 77, 48, 51, 52, 128, 77, 48, 51, 180, 77, 48, 51, + 51, 66, 128, 77, 48, 51, 51, 65, 128, 77, 48, 51, 51, 128, 77, 48, 51, + 179, 77, 48, 51, 50, 128, 77, 48, 51, 178, 77, 48, 51, 49, 65, 128, 77, + 48, 51, 49, 128, 77, 48, 51, 177, 77, 48, 51, 48, 128, 77, 48, 51, 176, + 77, 48, 50, 57, 128, 77, 48, 50, 185, 77, 48, 50, 56, 65, 128, 77, 48, + 50, 56, 128, 77, 48, 50, 184, 77, 48, 50, 55, 128, 77, 48, 50, 183, 77, + 48, 50, 54, 128, 77, 48, 50, 182, 77, 48, 50, 53, 128, 77, 48, 50, 181, + 77, 48, 50, 52, 65, 128, 77, 48, 50, 52, 128, 77, 48, 50, 180, 77, 48, + 50, 51, 128, 77, 48, 50, 179, 77, 48, 50, 50, 65, 128, 77, 48, 50, 50, + 128, 77, 48, 50, 178, 77, 48, 50, 49, 128, 77, 48, 50, 177, 77, 48, 50, + 48, 128, 77, 48, 50, 176, 77, 48, 49, 57, 128, 77, 48, 49, 185, 77, 48, + 49, 56, 128, 77, 48, 49, 184, 77, 48, 49, 55, 65, 128, 77, 48, 49, 55, + 128, 77, 48, 49, 183, 77, 48, 49, 54, 65, 128, 77, 48, 49, 54, 128, 77, + 48, 49, 182, 77, 48, 49, 53, 65, 128, 77, 48, 49, 53, 128, 77, 48, 49, + 181, 77, 48, 49, 52, 128, 77, 48, 49, 180, 77, 48, 49, 51, 128, 77, 48, + 49, 179, 77, 48, 49, 50, 72, 128, 77, 48, 49, 50, 71, 128, 77, 48, 49, + 50, 70, 128, 77, 48, 49, 50, 69, 128, 77, 48, 49, 50, 68, 128, 77, 48, + 49, 50, 67, 128, 77, 48, 49, 50, 66, 128, 77, 48, 49, 50, 65, 128, 77, + 48, 49, 50, 128, 77, 48, 49, 178, 77, 48, 49, 49, 128, 77, 48, 49, 177, + 77, 48, 49, 48, 65, 128, 77, 48, 49, 48, 128, 77, 48, 49, 176, 77, 48, + 48, 57, 128, 77, 48, 48, 185, 77, 48, 48, 56, 128, 77, 48, 48, 184, 77, + 48, 48, 55, 128, 77, 48, 48, 183, 77, 48, 48, 54, 128, 77, 48, 48, 182, + 77, 48, 48, 53, 128, 77, 48, 48, 181, 77, 48, 48, 52, 128, 77, 48, 48, + 180, 77, 48, 48, 51, 65, 128, 77, 48, 48, 51, 128, 77, 48, 48, 179, 77, + 48, 48, 50, 128, 77, 48, 48, 178, 77, 48, 48, 49, 66, 128, 77, 48, 48, + 49, 65, 128, 77, 48, 48, 49, 128, 77, 48, 48, 177, 76, 218, 76, 89, 89, + 128, 76, 89, 88, 128, 76, 89, 84, 128, 76, 89, 82, 88, 128, 76, 89, 82, + 128, 76, 89, 80, 128, 76, 89, 73, 84, 128, 76, 89, 73, 78, 199, 76, 89, + 68, 73, 65, 206, 76, 89, 67, 73, 65, 206, 76, 88, 128, 76, 87, 79, 79, + 128, 76, 87, 79, 128, 76, 87, 73, 73, 128, 76, 87, 73, 128, 76, 87, 69, + 128, 76, 87, 65, 65, 128, 76, 87, 65, 128, 76, 85, 88, 128, 76, 85, 85, + 128, 76, 85, 84, 128, 76, 85, 82, 88, 128, 76, 85, 80, 128, 76, 85, 79, + 88, 128, 76, 85, 79, 84, 128, 76, 85, 79, 80, 128, 76, 85, 79, 128, 76, + 85, 78, 71, 83, 73, 128, 76, 85, 78, 71, 83, 128, 76, 85, 78, 65, 84, + 197, 76, 85, 78, 65, 210, 76, 85, 205, 76, 85, 76, 128, 76, 85, 73, 83, + 128, 76, 85, 72, 85, 82, 128, 76, 85, 72, 128, 76, 85, 200, 76, 85, 71, + 71, 65, 71, 69, 128, 76, 85, 71, 65, 76, 128, 76, 85, 71, 65, 204, 76, + 85, 69, 128, 76, 85, 197, 76, 85, 66, 128, 76, 85, 65, 69, 80, 128, 76, + 85, 51, 128, 76, 85, 50, 128, 76, 85, 178, 76, 82, 79, 128, 76, 82, 77, + 128, 76, 82, 73, 128, 76, 82, 69, 128, 76, 79, 90, 69, 78, 71, 69, 128, + 76, 79, 90, 69, 78, 71, 197, 76, 79, 88, 128, 76, 79, 87, 69, 82, 69, + 196, 76, 79, 87, 45, 82, 69, 86, 69, 82, 83, 69, 68, 45, 185, 76, 79, 87, + 45, 77, 73, 196, 76, 79, 87, 45, 70, 65, 76, 76, 73, 78, 199, 76, 79, 87, + 45, 185, 76, 79, 86, 197, 76, 79, 85, 82, 69, 128, 76, 79, 85, 68, 83, + 80, 69, 65, 75, 69, 82, 128, 76, 79, 85, 68, 76, 217, 76, 79, 84, 85, 83, + 128, 76, 79, 84, 85, 211, 76, 79, 84, 73, 79, 206, 76, 79, 84, 128, 76, + 79, 83, 212, 76, 79, 83, 83, 76, 69, 83, 83, 128, 76, 79, 82, 82, 89, + 128, 76, 79, 82, 82, 65, 73, 78, 69, 128, 76, 79, 81, 128, 76, 79, 80, + 128, 76, 79, 79, 84, 128, 76, 79, 79, 80, 69, 196, 76, 79, 79, 80, 128, + 76, 79, 79, 208, 76, 79, 79, 78, 128, 76, 79, 79, 203, 76, 79, 79, 128, + 76, 79, 78, 83, 85, 77, 128, 76, 79, 78, 71, 65, 128, 76, 79, 78, 71, + 193, 76, 79, 78, 71, 45, 76, 69, 71, 71, 69, 196, 76, 79, 78, 71, 45, 66, + 82, 65, 78, 67, 72, 45, 89, 82, 128, 76, 79, 78, 71, 45, 66, 82, 65, 78, + 67, 72, 45, 83, 79, 204, 76, 79, 78, 71, 45, 66, 82, 65, 78, 67, 72, 45, + 79, 83, 211, 76, 79, 78, 71, 45, 66, 82, 65, 78, 67, 72, 45, 77, 65, 68, + 210, 76, 79, 78, 71, 45, 66, 82, 65, 78, 67, 72, 45, 72, 65, 71, 65, 76, + 204, 76, 79, 78, 71, 45, 66, 82, 65, 78, 67, 72, 45, 65, 210, 76, 79, 77, + 77, 65, 69, 128, 76, 79, 77, 75, 65, 128, 76, 79, 77, 128, 76, 79, 205, + 76, 79, 76, 76, 73, 80, 79, 80, 128, 76, 79, 76, 76, 128, 76, 79, 71, + 210, 76, 79, 71, 79, 84, 89, 80, 197, 76, 79, 71, 79, 71, 82, 65, 205, + 76, 79, 71, 128, 76, 79, 68, 69, 83, 84, 79, 78, 69, 128, 76, 79, 67, 79, + 77, 79, 84, 73, 86, 69, 128, 76, 79, 67, 75, 73, 78, 71, 45, 83, 72, 73, + 70, 212, 76, 79, 67, 65, 84, 73, 86, 69, 128, 76, 79, 67, 65, 84, 73, 79, + 78, 45, 87, 65, 76, 76, 80, 76, 65, 78, 197, 76, 79, 67, 65, 84, 73, 79, + 78, 45, 70, 76, 79, 79, 82, 80, 76, 65, 78, 197, 76, 79, 67, 65, 84, 73, + 79, 78, 128, 76, 79, 67, 65, 84, 73, 79, 206, 76, 79, 66, 83, 84, 69, 82, + 128, 76, 79, 65, 128, 76, 78, 128, 76, 76, 85, 85, 128, 76, 76, 79, 79, + 128, 76, 76, 76, 85, 85, 128, 76, 76, 76, 85, 128, 76, 76, 76, 79, 79, + 128, 76, 76, 76, 79, 128, 76, 76, 76, 73, 73, 128, 76, 76, 76, 73, 128, + 76, 76, 76, 69, 69, 128, 76, 76, 76, 69, 128, 76, 76, 76, 65, 85, 128, + 76, 76, 76, 65, 73, 128, 76, 76, 76, 65, 65, 128, 76, 76, 76, 65, 128, + 76, 76, 76, 128, 76, 76, 72, 65, 128, 76, 76, 65, 77, 65, 128, 76, 74, + 85, 68, 73, 74, 69, 128, 76, 74, 69, 128, 76, 74, 128, 76, 73, 90, 65, + 82, 68, 128, 76, 73, 88, 128, 76, 73, 87, 78, 128, 76, 73, 86, 82, 197, + 76, 73, 84, 84, 76, 69, 128, 76, 73, 84, 84, 76, 197, 76, 73, 84, 84, 69, + 210, 76, 73, 84, 82, 193, 76, 73, 84, 200, 76, 73, 83, 213, 76, 73, 83, + 128, 76, 73, 82, 193, 76, 73, 81, 85, 73, 68, 128, 76, 73, 81, 85, 73, + 196, 76, 73, 81, 128, 76, 73, 80, 83, 84, 73, 67, 75, 128, 76, 73, 80, + 211, 76, 73, 208, 76, 73, 78, 75, 73, 78, 199, 76, 73, 78, 75, 69, 196, + 76, 73, 78, 203, 76, 73, 78, 71, 83, 65, 128, 76, 73, 78, 69, 83, 128, + 76, 73, 78, 69, 211, 76, 73, 78, 69, 45, 57, 128, 76, 73, 78, 69, 45, 55, + 128, 76, 73, 78, 69, 45, 51, 128, 76, 73, 78, 69, 45, 49, 128, 76, 73, + 77, 77, 85, 52, 128, 76, 73, 77, 77, 85, 50, 128, 76, 73, 77, 77, 85, + 128, 76, 73, 77, 77, 213, 76, 73, 77, 73, 84, 69, 196, 76, 73, 77, 73, + 84, 65, 84, 73, 79, 78, 128, 76, 73, 77, 73, 84, 128, 76, 73, 77, 69, + 128, 76, 73, 77, 66, 213, 76, 73, 77, 66, 211, 76, 73, 77, 194, 76, 73, + 76, 89, 128, 76, 73, 76, 73, 84, 72, 128, 76, 73, 76, 128, 76, 73, 71, + 72, 84, 78, 73, 78, 71, 128, 76, 73, 71, 72, 84, 78, 73, 78, 199, 76, 73, + 71, 72, 84, 72, 79, 85, 83, 69, 128, 76, 73, 71, 72, 84, 128, 76, 73, 71, + 65, 84, 73, 78, 199, 76, 73, 70, 84, 69, 82, 128, 76, 73, 70, 69, 128, + 76, 73, 69, 88, 128, 76, 73, 69, 84, 128, 76, 73, 69, 80, 128, 76, 73, + 69, 69, 128, 76, 73, 69, 128, 76, 73, 68, 128, 76, 73, 67, 75, 73, 78, + 199, 76, 73, 66, 82, 65, 128, 76, 73, 66, 69, 82, 84, 89, 128, 76, 73, + 65, 66, 73, 76, 73, 84, 217, 76, 72, 73, 73, 128, 76, 72, 65, 86, 73, 89, + 65, 78, 73, 128, 76, 72, 65, 199, 76, 72, 65, 65, 128, 76, 72, 128, 76, + 69, 90, 72, 128, 76, 69, 90, 200, 76, 69, 88, 128, 76, 69, 86, 73, 84, + 65, 84, 73, 78, 71, 128, 76, 69, 86, 69, 76, 45, 51, 128, 76, 69, 86, 69, + 76, 45, 50, 128, 76, 69, 85, 77, 128, 76, 69, 85, 65, 69, 80, 128, 76, + 69, 85, 65, 69, 77, 128, 76, 69, 85, 128, 76, 69, 213, 76, 69, 84, 84, + 69, 82, 83, 128, 76, 69, 84, 84, 69, 82, 128, 76, 69, 212, 76, 69, 83, + 83, 69, 210, 76, 69, 83, 83, 45, 84, 72, 65, 78, 128, 76, 69, 83, 83, 45, + 84, 72, 65, 206, 76, 69, 83, 72, 128, 76, 69, 80, 67, 72, 193, 76, 69, + 80, 128, 76, 69, 79, 80, 65, 82, 68, 128, 76, 69, 79, 128, 76, 69, 78, + 84, 73, 67, 85, 76, 65, 210, 76, 69, 78, 73, 83, 128, 76, 69, 78, 73, + 211, 76, 69, 78, 71, 84, 72, 69, 78, 69, 82, 128, 76, 69, 78, 71, 84, 72, + 45, 55, 128, 76, 69, 78, 71, 84, 72, 45, 54, 128, 76, 69, 78, 71, 84, 72, + 45, 53, 128, 76, 69, 78, 71, 84, 72, 45, 52, 128, 76, 69, 78, 71, 84, 72, + 45, 51, 128, 76, 69, 78, 71, 84, 72, 45, 50, 128, 76, 69, 78, 71, 84, 72, + 45, 49, 128, 76, 69, 78, 71, 84, 200, 76, 69, 78, 71, 65, 128, 76, 69, + 78, 71, 193, 76, 69, 77, 79, 78, 128, 76, 69, 77, 79, 73, 128, 76, 69, + 76, 69, 84, 128, 76, 69, 76, 69, 212, 76, 69, 203, 76, 69, 73, 77, 77, + 65, 128, 76, 69, 73, 77, 77, 193, 76, 69, 73, 128, 76, 69, 71, 83, 128, + 76, 69, 71, 73, 79, 78, 128, 76, 69, 71, 69, 84, 79, 211, 76, 69, 71, + 128, 76, 69, 199, 76, 69, 70, 84, 87, 65, 82, 68, 83, 128, 76, 69, 70, + 84, 45, 84, 79, 45, 82, 73, 71, 72, 212, 76, 69, 70, 84, 45, 83, 84, 69, + 205, 76, 69, 70, 84, 45, 83, 73, 68, 197, 76, 69, 70, 84, 45, 83, 72, 65, + 68, 69, 196, 76, 69, 70, 84, 45, 80, 79, 73, 78, 84, 73, 78, 199, 76, 69, + 70, 84, 45, 76, 73, 71, 72, 84, 69, 196, 76, 69, 70, 84, 45, 72, 65, 78, + 68, 69, 196, 76, 69, 70, 84, 45, 72, 65, 78, 196, 76, 69, 70, 84, 45, 70, + 65, 67, 73, 78, 199, 76, 69, 70, 84, 128, 76, 69, 69, 82, 65, 69, 87, 65, + 128, 76, 69, 69, 75, 128, 76, 69, 69, 69, 69, 128, 76, 69, 68, 71, 69, + 82, 128, 76, 69, 65, 84, 72, 69, 82, 128, 76, 69, 65, 78, 73, 78, 199, + 76, 69, 65, 70, 217, 76, 69, 65, 70, 128, 76, 69, 65, 198, 76, 69, 65, + 68, 69, 82, 128, 76, 69, 65, 196, 76, 68, 65, 78, 128, 76, 68, 50, 128, + 76, 67, 201, 76, 67, 197, 76, 65, 90, 217, 76, 65, 89, 65, 78, 78, 65, + 128, 76, 65, 88, 128, 76, 65, 87, 128, 76, 65, 215, 76, 65, 85, 76, 65, + 128, 76, 65, 85, 75, 65, 218, 76, 65, 85, 74, 128, 76, 65, 85, 71, 72, + 73, 78, 71, 128, 76, 65, 84, 73, 78, 65, 84, 197, 76, 65, 84, 73, 75, + 128, 76, 65, 84, 69, 82, 65, 204, 76, 65, 84, 197, 76, 65, 83, 212, 76, + 65, 82, 89, 78, 71, 69, 65, 204, 76, 65, 82, 201, 76, 65, 82, 71, 69, 83, + 84, 128, 76, 65, 82, 71, 69, 210, 76, 65, 82, 71, 69, 128, 76, 65, 82, + 71, 197, 76, 65, 81, 128, 76, 65, 80, 65, 81, 128, 76, 65, 207, 76, 65, + 78, 84, 69, 82, 78, 128, 76, 65, 78, 84, 65, 78, 71, 128, 76, 65, 78, 71, + 85, 65, 71, 197, 76, 65, 78, 69, 83, 128, 76, 65, 78, 196, 76, 65, 78, + 128, 76, 65, 77, 80, 128, 76, 65, 77, 69, 68, 72, 128, 76, 65, 77, 69, + 68, 128, 76, 65, 77, 69, 196, 76, 65, 77, 69, 128, 76, 65, 77, 197, 76, + 65, 77, 68, 65, 128, 76, 65, 77, 68, 128, 76, 65, 77, 66, 68, 193, 76, + 65, 77, 65, 68, 72, 128, 76, 65, 76, 128, 76, 65, 204, 76, 65, 75, 75, + 72, 65, 78, 71, 89, 65, 79, 128, 76, 65, 75, 72, 65, 78, 128, 76, 65, 75, + 72, 128, 76, 65, 75, 200, 76, 65, 75, 45, 55, 52, 57, 128, 76, 65, 75, + 45, 55, 50, 52, 128, 76, 65, 75, 45, 54, 54, 56, 128, 76, 65, 75, 45, 54, + 52, 56, 128, 76, 65, 75, 45, 54, 52, 184, 76, 65, 75, 45, 54, 51, 54, + 128, 76, 65, 75, 45, 54, 49, 55, 128, 76, 65, 75, 45, 54, 49, 183, 76, + 65, 75, 45, 54, 48, 56, 128, 76, 65, 75, 45, 53, 53, 48, 128, 76, 65, 75, + 45, 52, 57, 53, 128, 76, 65, 75, 45, 52, 57, 51, 128, 76, 65, 75, 45, 52, + 57, 50, 128, 76, 65, 75, 45, 52, 57, 48, 128, 76, 65, 75, 45, 52, 56, 51, + 128, 76, 65, 75, 45, 52, 55, 48, 128, 76, 65, 75, 45, 52, 53, 55, 128, + 76, 65, 75, 45, 52, 53, 48, 128, 76, 65, 75, 45, 52, 52, 57, 128, 76, 65, + 75, 45, 52, 52, 185, 76, 65, 75, 45, 52, 52, 49, 128, 76, 65, 75, 45, 51, + 57, 48, 128, 76, 65, 75, 45, 51, 56, 52, 128, 76, 65, 75, 45, 51, 56, 51, + 128, 76, 65, 75, 45, 51, 52, 56, 128, 76, 65, 75, 45, 51, 52, 55, 128, + 76, 65, 75, 45, 51, 52, 51, 128, 76, 65, 75, 45, 50, 54, 54, 128, 76, 65, + 75, 45, 50, 54, 53, 128, 76, 65, 75, 45, 50, 51, 56, 128, 76, 65, 75, 45, + 50, 50, 56, 128, 76, 65, 75, 45, 50, 50, 53, 128, 76, 65, 75, 45, 50, 50, + 48, 128, 76, 65, 75, 45, 50, 49, 57, 128, 76, 65, 75, 45, 50, 49, 48, + 128, 76, 65, 75, 45, 49, 52, 50, 128, 76, 65, 75, 45, 49, 51, 48, 128, + 76, 65, 75, 45, 48, 57, 50, 128, 76, 65, 75, 45, 48, 56, 49, 128, 76, 65, + 75, 45, 48, 56, 177, 76, 65, 75, 45, 48, 56, 48, 128, 76, 65, 75, 45, 48, + 55, 185, 76, 65, 75, 45, 48, 54, 50, 128, 76, 65, 75, 45, 48, 53, 49, + 128, 76, 65, 75, 45, 48, 53, 48, 128, 76, 65, 75, 45, 48, 51, 48, 128, + 76, 65, 75, 45, 48, 50, 53, 128, 76, 65, 75, 45, 48, 50, 49, 128, 76, 65, + 75, 45, 48, 50, 48, 128, 76, 65, 75, 45, 48, 48, 51, 128, 76, 65, 74, 65, + 78, 89, 65, 76, 65, 78, 128, 76, 65, 73, 78, 199, 76, 65, 201, 76, 65, + 72, 83, 72, 85, 128, 76, 65, 72, 128, 76, 65, 71, 85, 83, 128, 76, 65, + 71, 213, 76, 65, 71, 65, 82, 128, 76, 65, 71, 65, 210, 76, 65, 71, 65, + 66, 128, 76, 65, 71, 65, 194, 76, 65, 69, 86, 128, 76, 65, 69, 128, 76, + 65, 68, 217, 76, 65, 68, 68, 69, 82, 128, 76, 65, 67, 82, 79, 83, 83, + 197, 76, 65, 67, 75, 128, 76, 65, 67, 65, 128, 76, 65, 66, 79, 85, 82, + 73, 78, 71, 128, 76, 65, 66, 79, 82, 128, 76, 65, 66, 73, 65, 76, 73, 90, + 65, 84, 73, 79, 206, 76, 65, 66, 73, 65, 204, 76, 65, 66, 69, 76, 128, + 76, 65, 66, 65, 84, 128, 76, 65, 194, 76, 65, 65, 78, 65, 69, 128, 76, + 65, 65, 78, 128, 76, 65, 65, 77, 85, 128, 76, 65, 65, 73, 128, 76, 54, + 128, 76, 52, 128, 76, 51, 128, 76, 50, 128, 76, 48, 48, 54, 65, 128, 76, + 48, 48, 50, 65, 128, 76, 45, 84, 89, 80, 197, 76, 45, 83, 72, 65, 80, 69, + 196, 75, 89, 85, 82, 73, 73, 128, 75, 89, 85, 128, 75, 89, 79, 128, 75, + 89, 76, 73, 83, 77, 65, 128, 75, 89, 73, 128, 75, 89, 69, 128, 75, 89, + 65, 84, 72, 79, 211, 75, 89, 65, 65, 128, 75, 89, 65, 128, 75, 88, 87, + 73, 128, 75, 88, 87, 69, 69, 128, 75, 88, 87, 69, 128, 75, 88, 87, 65, + 65, 128, 75, 88, 87, 65, 128, 75, 88, 85, 128, 75, 88, 79, 128, 75, 88, + 73, 128, 75, 88, 69, 69, 128, 75, 88, 69, 128, 75, 88, 65, 65, 128, 75, + 88, 65, 128, 75, 87, 86, 128, 75, 87, 85, 51, 49, 56, 128, 75, 87, 79, + 79, 128, 75, 87, 79, 128, 75, 87, 77, 128, 75, 87, 73, 73, 128, 75, 87, + 73, 128, 75, 87, 69, 69, 128, 75, 87, 69, 128, 75, 87, 66, 128, 75, 87, + 65, 89, 128, 75, 87, 65, 69, 84, 128, 75, 87, 65, 65, 128, 75, 86, 65, + 128, 75, 86, 128, 75, 85, 90, 72, 73, 128, 75, 85, 88, 128, 75, 85, 86, + 128, 75, 85, 85, 72, 128, 75, 85, 84, 128, 75, 85, 83, 77, 65, 128, 75, + 85, 83, 72, 85, 50, 128, 75, 85, 83, 72, 85, 178, 75, 85, 82, 88, 128, + 75, 85, 82, 85, 90, 69, 73, 82, 79, 128, 75, 85, 82, 84, 128, 75, 85, 82, + 79, 79, 78, 69, 128, 75, 85, 82, 128, 75, 85, 210, 75, 85, 81, 128, 75, + 85, 80, 78, 65, 89, 65, 128, 75, 85, 79, 88, 128, 75, 85, 79, 80, 128, + 75, 85, 79, 208, 75, 85, 79, 77, 128, 75, 85, 79, 128, 75, 85, 78, 71, + 128, 75, 85, 78, 68, 68, 65, 76, 73, 89, 65, 128, 75, 85, 76, 128, 75, + 85, 204, 75, 85, 71, 128, 75, 85, 70, 73, 83, 77, 65, 128, 75, 85, 69, + 84, 128, 75, 85, 66, 128, 75, 85, 65, 86, 128, 75, 85, 65, 66, 128, 75, + 85, 65, 128, 75, 85, 55, 128, 75, 85, 52, 128, 75, 85, 180, 75, 85, 51, + 128, 75, 85, 179, 75, 85, 45, 55, 128, 75, 85, 45, 54, 128, 75, 85, 45, + 53, 128, 75, 85, 45, 52, 128, 75, 85, 45, 51, 128, 75, 85, 45, 50, 128, + 75, 85, 45, 49, 128, 75, 84, 128, 75, 83, 83, 85, 85, 128, 75, 83, 83, + 85, 128, 75, 83, 83, 79, 79, 128, 75, 83, 83, 79, 128, 75, 83, 83, 73, + 73, 128, 75, 83, 83, 73, 128, 75, 83, 83, 69, 69, 128, 75, 83, 83, 69, + 128, 75, 83, 83, 65, 85, 128, 75, 83, 83, 65, 73, 128, 75, 83, 83, 65, + 65, 128, 75, 83, 83, 65, 128, 75, 83, 83, 128, 75, 83, 73, 128, 75, 82, + 89, 90, 72, 69, 86, 65, 89, 65, 128, 75, 82, 89, 90, 72, 69, 77, 128, 75, + 82, 89, 90, 72, 69, 205, 75, 82, 89, 90, 72, 128, 75, 82, 89, 90, 200, + 75, 82, 89, 85, 75, 79, 86, 65, 89, 65, 128, 75, 82, 89, 85, 75, 79, 86, + 65, 89, 193, 75, 82, 89, 85, 75, 128, 75, 82, 89, 85, 203, 75, 82, 79, + 78, 79, 83, 128, 75, 82, 69, 77, 65, 83, 84, 73, 128, 75, 82, 65, 84, 73, + 77, 79, 89, 80, 79, 82, 82, 79, 79, 78, 128, 75, 82, 65, 84, 73, 77, 79, + 75, 79, 85, 70, 73, 83, 77, 65, 128, 75, 82, 65, 84, 73, 77, 65, 84, 65, + 128, 75, 82, 65, 84, 73, 77, 193, 75, 80, 85, 128, 75, 80, 79, 81, 128, + 75, 80, 79, 79, 128, 75, 80, 79, 128, 75, 80, 73, 128, 75, 80, 69, 85, + 88, 128, 75, 80, 69, 69, 128, 75, 80, 69, 128, 75, 80, 65, 82, 65, 81, + 128, 75, 80, 65, 78, 128, 75, 80, 65, 72, 128, 75, 80, 65, 128, 75, 80, + 128, 75, 79, 88, 128, 75, 79, 86, 85, 85, 128, 75, 79, 86, 128, 75, 79, + 84, 79, 128, 75, 79, 82, 85, 78, 65, 128, 75, 79, 82, 79, 78, 73, 83, + 128, 75, 79, 82, 79, 78, 128, 75, 79, 82, 69, 65, 206, 75, 79, 82, 65, + 78, 73, 195, 75, 79, 81, 78, 68, 79, 78, 128, 75, 79, 80, 80, 65, 128, + 75, 79, 80, 128, 75, 79, 79, 86, 128, 75, 79, 79, 80, 79, 128, 75, 79, + 79, 77, 85, 85, 84, 128, 75, 79, 79, 66, 128, 75, 79, 79, 128, 75, 79, + 78, 84, 69, 86, 77, 65, 128, 75, 79, 78, 84, 69, 86, 77, 193, 75, 79, 77, + 201, 75, 79, 77, 66, 85, 86, 65, 128, 75, 79, 77, 66, 85, 86, 193, 75, + 79, 77, 66, 213, 75, 79, 75, 79, 128, 75, 79, 75, 69, 128, 75, 79, 75, + 128, 75, 79, 203, 75, 79, 73, 78, 73, 128, 75, 79, 73, 128, 75, 79, 201, + 75, 79, 72, 128, 75, 79, 71, 72, 79, 77, 128, 75, 79, 69, 84, 128, 75, + 79, 66, 89, 76, 65, 128, 75, 79, 66, 128, 75, 79, 65, 76, 65, 128, 75, + 79, 65, 128, 75, 79, 45, 75, 73, 128, 75, 79, 45, 51, 128, 75, 79, 45, + 50, 128, 75, 79, 45, 49, 128, 75, 78, 85, 67, 75, 76, 69, 83, 128, 75, + 78, 85, 67, 75, 76, 69, 128, 75, 78, 79, 84, 128, 75, 78, 79, 66, 83, + 128, 75, 78, 73, 71, 72, 84, 45, 82, 79, 79, 75, 128, 75, 78, 73, 71, 72, + 84, 45, 81, 85, 69, 69, 78, 128, 75, 78, 73, 71, 72, 84, 45, 66, 73, 83, + 72, 79, 80, 128, 75, 78, 73, 71, 72, 84, 128, 75, 78, 73, 71, 72, 212, + 75, 78, 73, 70, 69, 128, 75, 78, 73, 70, 197, 75, 78, 69, 69, 76, 73, 78, + 199, 75, 77, 128, 75, 205, 75, 76, 89, 85, 67, 72, 69, 86, 79, 89, 128, + 75, 76, 89, 85, 67, 72, 69, 86, 65, 89, 65, 128, 75, 76, 89, 85, 67, 72, + 69, 86, 65, 89, 193, 75, 76, 89, 85, 67, 72, 69, 80, 79, 86, 79, 68, 78, + 89, 128, 75, 76, 89, 85, 67, 72, 69, 80, 79, 86, 79, 68, 78, 65, 89, 65, + 128, 75, 76, 89, 85, 67, 72, 69, 78, 69, 80, 79, 83, 84, 79, 89, 65, 78, + 78, 89, 128, 75, 76, 89, 85, 67, 72, 69, 78, 69, 80, 79, 83, 84, 79, 89, + 65, 78, 78, 65, 89, 65, 128, 75, 76, 89, 85, 67, 72, 128, 75, 76, 73, 84, + 79, 78, 128, 75, 76, 65, 83, 77, 65, 128, 75, 76, 65, 83, 77, 193, 75, + 76, 65, 128, 75, 76, 128, 75, 75, 79, 128, 75, 75, 73, 128, 75, 75, 69, + 69, 128, 75, 75, 69, 128, 75, 75, 65, 128, 75, 75, 128, 75, 74, 69, 128, + 75, 73, 89, 69, 79, 75, 45, 84, 73, 75, 69, 85, 84, 128, 75, 73, 89, 69, + 79, 75, 45, 83, 73, 79, 83, 45, 75, 73, 89, 69, 79, 75, 128, 75, 73, 89, + 69, 79, 75, 45, 82, 73, 69, 85, 76, 128, 75, 73, 89, 69, 79, 75, 45, 80, + 73, 69, 85, 80, 128, 75, 73, 89, 69, 79, 75, 45, 78, 73, 69, 85, 78, 128, + 75, 73, 89, 69, 79, 75, 45, 75, 72, 73, 69, 85, 75, 72, 128, 75, 73, 89, + 69, 79, 75, 45, 67, 72, 73, 69, 85, 67, 72, 128, 75, 73, 89, 69, 79, 203, + 75, 73, 88, 128, 75, 73, 87, 73, 70, 82, 85, 73, 84, 128, 75, 73, 87, + 128, 75, 73, 86, 128, 75, 73, 84, 69, 128, 75, 73, 84, 128, 75, 73, 83, + 83, 73, 78, 199, 75, 73, 83, 83, 128, 75, 73, 83, 211, 75, 73, 83, 73, + 77, 53, 128, 75, 73, 83, 73, 77, 181, 75, 73, 83, 72, 128, 75, 73, 83, + 65, 76, 128, 75, 73, 82, 79, 87, 65, 84, 84, 79, 128, 75, 73, 82, 79, 77, + 69, 69, 84, 79, 82, 85, 128, 75, 73, 82, 79, 71, 85, 82, 65, 77, 85, 128, + 75, 73, 82, 79, 128, 75, 73, 82, 71, 72, 73, 218, 75, 73, 81, 128, 75, + 73, 80, 128, 75, 73, 208, 75, 73, 78, 83, 72, 73, 80, 128, 75, 73, 78, + 78, 193, 75, 73, 78, 68, 69, 82, 71, 65, 82, 84, 69, 78, 128, 75, 73, 77, + 79, 78, 79, 128, 75, 73, 76, 76, 69, 82, 128, 75, 73, 73, 90, 72, 128, + 75, 73, 73, 128, 75, 73, 72, 128, 75, 73, 69, 88, 128, 75, 73, 69, 86, + 65, 206, 75, 73, 69, 80, 128, 75, 73, 69, 69, 77, 128, 75, 73, 69, 128, + 75, 73, 68, 128, 75, 73, 196, 75, 73, 67, 75, 128, 75, 73, 66, 128, 75, + 73, 65, 86, 128, 75, 73, 65, 66, 128, 75, 73, 45, 56, 128, 75, 73, 45, + 55, 128, 75, 73, 45, 54, 128, 75, 73, 45, 53, 128, 75, 73, 45, 52, 128, + 75, 73, 45, 51, 128, 75, 73, 45, 50, 128, 75, 73, 45, 49, 128, 75, 72, + 90, 128, 75, 72, 87, 65, 73, 128, 75, 72, 85, 69, 78, 45, 76, 85, 197, + 75, 72, 85, 69, 206, 75, 72, 85, 68, 65, 87, 65, 68, 201, 75, 72, 85, 68, + 65, 77, 128, 75, 72, 85, 65, 84, 128, 75, 72, 79, 85, 128, 75, 72, 79, + 212, 75, 72, 79, 78, 78, 65, 128, 75, 72, 79, 78, 128, 75, 72, 79, 77, + 85, 84, 128, 75, 72, 79, 75, 72, 76, 79, 205, 75, 72, 79, 74, 75, 201, + 75, 72, 79, 128, 75, 72, 207, 75, 72, 77, 213, 75, 72, 73, 84, 128, 75, + 72, 73, 78, 89, 65, 128, 75, 72, 73, 69, 85, 75, 200, 75, 72, 73, 128, + 75, 72, 201, 75, 72, 72, 79, 128, 75, 72, 72, 65, 128, 75, 72, 69, 84, + 72, 128, 75, 72, 69, 73, 128, 75, 72, 69, 69, 128, 75, 72, 69, 128, 75, + 72, 65, 86, 128, 75, 72, 65, 82, 79, 83, 72, 84, 72, 201, 75, 72, 65, 82, + 128, 75, 72, 65, 80, 72, 128, 75, 72, 65, 78, 199, 75, 72, 65, 78, 68, + 65, 128, 75, 72, 65, 78, 68, 193, 75, 72, 65, 77, 84, 201, 75, 72, 65, + 77, 73, 76, 79, 128, 75, 72, 65, 75, 65, 83, 83, 73, 65, 206, 75, 72, 65, + 73, 128, 75, 72, 65, 72, 128, 75, 72, 65, 200, 75, 72, 65, 70, 128, 75, + 72, 65, 66, 128, 75, 72, 65, 65, 128, 75, 71, 128, 75, 69, 89, 67, 65, + 80, 128, 75, 69, 89, 67, 65, 208, 75, 69, 89, 66, 79, 65, 82, 68, 128, + 75, 69, 89, 66, 79, 65, 82, 196, 75, 69, 88, 128, 75, 69, 86, 128, 75, + 69, 85, 89, 69, 85, 88, 128, 75, 69, 85, 83, 72, 69, 85, 65, 69, 80, 128, + 75, 69, 85, 83, 69, 85, 88, 128, 75, 69, 85, 80, 85, 81, 128, 75, 69, 85, + 79, 212, 75, 69, 85, 77, 128, 75, 69, 85, 75, 69, 85, 84, 78, 68, 65, + 128, 75, 69, 85, 75, 65, 81, 128, 75, 69, 85, 65, 69, 84, 77, 69, 85, 78, + 128, 75, 69, 85, 65, 69, 82, 73, 128, 75, 69, 84, 84, 201, 75, 69, 83, + 72, 50, 128, 75, 69, 82, 69, 84, 128, 75, 69, 79, 87, 128, 75, 69, 78, + 84, 73, 77, 65, 84, 65, 128, 75, 69, 78, 84, 73, 77, 65, 84, 193, 75, 69, + 78, 84, 73, 77, 193, 75, 69, 78, 65, 84, 128, 75, 69, 78, 128, 75, 69, + 206, 75, 69, 77, 80, 85, 76, 128, 75, 69, 77, 80, 85, 204, 75, 69, 77, + 80, 76, 73, 128, 75, 69, 77, 80, 76, 201, 75, 69, 77, 80, 72, 82, 69, 78, + 71, 128, 75, 69, 77, 66, 65, 78, 71, 128, 75, 69, 76, 86, 73, 206, 75, + 69, 72, 69, 72, 128, 75, 69, 72, 69, 200, 75, 69, 72, 128, 75, 69, 70, + 85, 76, 65, 128, 75, 69, 69, 86, 128, 75, 69, 69, 83, 85, 128, 75, 69, + 69, 80, 73, 78, 199, 75, 69, 69, 78, 71, 128, 75, 69, 69, 66, 128, 75, + 69, 66, 128, 75, 69, 65, 65, 69, 128, 75, 67, 65, 76, 128, 75, 66, 128, + 75, 65, 90, 65, 75, 200, 75, 65, 89, 65, 78, 78, 65, 128, 75, 65, 89, 65, + 200, 75, 65, 88, 128, 75, 65, 87, 86, 128, 75, 65, 87, 73, 128, 75, 65, + 87, 201, 75, 65, 87, 66, 128, 75, 65, 86, 89, 75, 65, 128, 75, 65, 86, + 89, 75, 193, 75, 65, 86, 128, 75, 65, 85, 86, 128, 75, 65, 85, 78, 65, + 128, 75, 65, 85, 206, 75, 65, 85, 66, 128, 75, 65, 84, 79, 128, 75, 65, + 84, 72, 73, 83, 84, 73, 128, 75, 65, 84, 72, 65, 75, 193, 75, 65, 84, 65, + 86, 65, 83, 77, 65, 128, 75, 65, 84, 65, 86, 193, 75, 65, 84, 65, 75, 65, + 78, 65, 45, 72, 73, 82, 65, 71, 65, 78, 193, 75, 65, 83, 82, 65, 84, 65, + 78, 128, 75, 65, 83, 82, 65, 84, 65, 206, 75, 65, 83, 82, 65, 128, 75, + 65, 83, 82, 193, 75, 65, 83, 75, 65, 76, 128, 75, 65, 83, 75, 65, 204, + 75, 65, 83, 72, 77, 73, 82, 201, 75, 65, 82, 83, 72, 65, 78, 65, 128, 75, + 65, 82, 79, 82, 73, 73, 128, 75, 65, 82, 79, 82, 65, 78, 128, 75, 65, 82, + 79, 82, 128, 75, 65, 82, 207, 75, 65, 82, 69, 206, 75, 65, 82, 65, 84, + 84, 79, 128, 75, 65, 82, 65, 78, 128, 75, 65, 80, 89, 69, 79, 85, 78, 83, + 83, 65, 78, 71, 80, 73, 69, 85, 80, 128, 75, 65, 80, 89, 69, 79, 85, 78, + 82, 73, 69, 85, 76, 128, 75, 65, 80, 89, 69, 79, 85, 78, 80, 72, 73, 69, + 85, 80, 72, 128, 75, 65, 80, 89, 69, 79, 85, 78, 77, 73, 69, 85, 77, 128, + 75, 65, 80, 80, 65, 128, 75, 65, 80, 80, 193, 75, 65, 80, 79, 128, 75, + 65, 80, 72, 128, 75, 65, 80, 65, 76, 128, 75, 65, 80, 65, 128, 75, 65, + 208, 75, 65, 78, 84, 65, 74, 193, 75, 65, 78, 78, 65, 68, 193, 75, 65, + 78, 71, 65, 82, 79, 79, 128, 75, 65, 78, 71, 128, 75, 65, 78, 199, 75, + 65, 78, 65, 75, 79, 128, 75, 65, 77, 52, 128, 75, 65, 77, 50, 128, 75, + 65, 77, 128, 75, 65, 75, 84, 79, 86, 73, 203, 75, 65, 75, 79, 128, 75, + 65, 75, 65, 66, 65, 84, 128, 75, 65, 75, 128, 75, 65, 203, 75, 65, 73, + 86, 128, 75, 65, 73, 84, 72, 201, 75, 65, 73, 82, 73, 128, 75, 65, 73, + 66, 128, 75, 65, 73, 128, 75, 65, 201, 75, 65, 70, 65, 128, 75, 65, 70, + 128, 75, 65, 198, 75, 65, 68, 53, 128, 75, 65, 68, 181, 75, 65, 68, 52, + 128, 75, 65, 68, 51, 128, 75, 65, 68, 179, 75, 65, 68, 50, 128, 75, 65, + 68, 128, 75, 65, 67, 72, 75, 65, 128, 75, 65, 66, 193, 75, 65, 66, 128, + 75, 65, 65, 86, 128, 75, 65, 65, 73, 128, 75, 65, 65, 70, 85, 128, 75, + 65, 65, 70, 128, 75, 65, 65, 67, 85, 128, 75, 65, 65, 66, 65, 128, 75, + 65, 65, 66, 128, 75, 65, 50, 128, 75, 65, 178, 75, 65, 45, 75, 69, 128, + 75, 65, 45, 57, 128, 75, 65, 45, 56, 128, 75, 65, 45, 55, 128, 75, 65, + 45, 54, 128, 75, 65, 45, 53, 128, 75, 65, 45, 52, 128, 75, 65, 45, 51, + 128, 75, 65, 45, 50, 128, 75, 65, 45, 49, 49, 128, 75, 65, 45, 49, 48, + 128, 75, 65, 45, 49, 128, 75, 48, 48, 56, 128, 75, 48, 48, 55, 128, 75, + 48, 48, 54, 128, 75, 48, 48, 53, 128, 75, 48, 48, 52, 128, 75, 48, 48, + 51, 128, 75, 48, 48, 50, 128, 75, 48, 48, 49, 128, 74, 87, 65, 128, 74, + 85, 85, 128, 74, 85, 84, 128, 74, 85, 83, 84, 73, 70, 73, 67, 65, 84, 73, + 79, 78, 128, 74, 85, 80, 73, 84, 69, 82, 128, 74, 85, 79, 84, 128, 74, + 85, 79, 80, 128, 74, 85, 78, 79, 128, 74, 85, 78, 71, 83, 69, 79, 78, + 199, 74, 85, 78, 69, 128, 74, 85, 76, 89, 128, 74, 85, 71, 71, 76, 73, + 78, 71, 128, 74, 85, 69, 85, 73, 128, 74, 85, 68, 85, 76, 128, 74, 85, + 68, 71, 69, 128, 74, 85, 68, 69, 79, 45, 83, 80, 65, 78, 73, 83, 200, 74, + 79, 89, 83, 84, 73, 67, 75, 128, 74, 79, 89, 79, 85, 211, 74, 79, 89, + 128, 74, 79, 86, 69, 128, 74, 79, 212, 74, 79, 78, 71, 128, 74, 79, 78, + 193, 74, 79, 75, 69, 82, 128, 74, 79, 73, 78, 84, 83, 128, 74, 79, 73, + 78, 69, 68, 128, 74, 79, 73, 78, 128, 74, 79, 65, 128, 74, 78, 89, 65, + 128, 74, 74, 89, 88, 128, 74, 74, 89, 84, 128, 74, 74, 89, 80, 128, 74, + 74, 89, 128, 74, 74, 85, 88, 128, 74, 74, 85, 84, 128, 74, 74, 85, 82, + 88, 128, 74, 74, 85, 82, 128, 74, 74, 85, 80, 128, 74, 74, 85, 79, 88, + 128, 74, 74, 85, 79, 80, 128, 74, 74, 85, 79, 128, 74, 74, 85, 128, 74, + 74, 79, 88, 128, 74, 74, 79, 84, 128, 74, 74, 79, 80, 128, 74, 74, 79, + 128, 74, 74, 73, 88, 128, 74, 74, 73, 84, 128, 74, 74, 73, 80, 128, 74, + 74, 73, 69, 88, 128, 74, 74, 73, 69, 84, 128, 74, 74, 73, 69, 80, 128, + 74, 74, 73, 69, 128, 74, 74, 73, 128, 74, 74, 69, 69, 128, 74, 74, 69, + 128, 74, 74, 65, 128, 74, 73, 76, 128, 74, 73, 73, 77, 128, 74, 73, 73, + 128, 74, 73, 72, 86, 65, 77, 85, 76, 73, 89, 65, 128, 74, 73, 71, 83, 65, + 215, 74, 73, 65, 128, 74, 72, 79, 88, 128, 74, 72, 79, 128, 74, 72, 69, + 72, 128, 74, 72, 65, 89, 73, 78, 128, 74, 72, 65, 78, 128, 74, 72, 65, + 77, 128, 74, 72, 65, 65, 128, 74, 72, 65, 128, 74, 69, 85, 128, 74, 69, + 82, 85, 83, 65, 76, 69, 77, 128, 74, 69, 82, 65, 206, 74, 69, 82, 65, + 128, 74, 69, 82, 128, 74, 69, 76, 76, 89, 70, 73, 83, 72, 128, 74, 69, + 72, 128, 74, 69, 200, 74, 69, 71, 79, 71, 65, 78, 128, 74, 69, 69, 77, + 128, 74, 69, 69, 205, 74, 69, 65, 78, 83, 128, 74, 65, 89, 78, 128, 74, + 65, 89, 73, 78, 128, 74, 65, 89, 65, 78, 78, 65, 128, 74, 65, 87, 128, + 74, 65, 86, 73, 89, 65, 78, 73, 128, 74, 65, 86, 65, 78, 69, 83, 197, 74, + 65, 85, 128, 74, 65, 82, 128, 74, 65, 80, 65, 78, 69, 83, 197, 74, 65, + 80, 65, 78, 128, 74, 65, 78, 85, 65, 82, 89, 128, 74, 65, 76, 76, 65, 74, + 65, 76, 65, 76, 79, 85, 72, 79, 85, 128, 74, 65, 76, 76, 128, 74, 65, 73, + 206, 74, 65, 73, 128, 74, 65, 72, 128, 74, 65, 68, 69, 128, 74, 65, 67, + 75, 83, 128, 74, 65, 67, 75, 45, 79, 45, 76, 65, 78, 84, 69, 82, 78, 128, + 74, 65, 67, 203, 74, 45, 83, 73, 77, 80, 76, 73, 70, 73, 69, 196, 73, 90, + 72, 73, 84, 83, 65, 128, 73, 90, 72, 73, 84, 83, 193, 73, 90, 72, 69, + 128, 73, 90, 65, 75, 65, 89, 193, 73, 89, 69, 75, 128, 73, 89, 65, 78, + 78, 65, 128, 73, 85, 74, 65, 128, 73, 84, 211, 73, 84, 69, 82, 65, 84, + 73, 79, 206, 73, 84, 69, 77, 128, 73, 83, 83, 72, 65, 82, 128, 73, 83, + 79, 83, 67, 69, 76, 69, 211, 73, 83, 79, 78, 128, 73, 83, 79, 206, 73, + 83, 79, 76, 65, 84, 69, 128, 73, 83, 76, 65, 78, 68, 128, 73, 83, 72, 77, + 65, 65, 77, 128, 73, 83, 69, 78, 45, 73, 83, 69, 78, 128, 73, 83, 65, 75, + 73, 193, 73, 83, 45, 80, 73, 76, 76, 65, 128, 73, 82, 85, 89, 65, 78, 78, + 65, 128, 73, 82, 85, 85, 89, 65, 78, 78, 65, 128, 73, 82, 79, 78, 45, 67, + 79, 80, 80, 69, 210, 73, 82, 79, 78, 128, 73, 82, 66, 128, 73, 79, 84, + 73, 70, 73, 69, 196, 73, 79, 84, 65, 84, 69, 196, 73, 79, 84, 65, 128, + 73, 79, 84, 193, 73, 79, 82, 128, 73, 79, 78, 71, 128, 73, 79, 68, 72, + 65, 68, 72, 128, 73, 78, 86, 73, 83, 73, 66, 76, 197, 73, 78, 86, 69, 82, + 84, 69, 68, 128, 73, 78, 86, 69, 82, 84, 69, 196, 73, 78, 86, 69, 82, 84, + 69, 66, 82, 65, 84, 69, 128, 73, 78, 86, 69, 82, 83, 197, 73, 78, 84, 82, + 79, 68, 85, 67, 69, 82, 128, 73, 78, 84, 73, 128, 73, 78, 84, 69, 82, 83, + 89, 76, 76, 65, 66, 73, 195, 73, 78, 84, 69, 82, 83, 69, 67, 84, 73, 79, + 78, 128, 73, 78, 84, 69, 82, 83, 69, 67, 84, 73, 79, 206, 73, 78, 84, 69, + 82, 83, 69, 67, 84, 73, 78, 199, 73, 78, 84, 69, 82, 82, 79, 66, 65, 78, + 71, 128, 73, 78, 84, 69, 82, 82, 79, 66, 65, 78, 199, 73, 78, 84, 69, 82, + 80, 79, 76, 65, 84, 73, 79, 206, 73, 78, 84, 69, 82, 76, 79, 67, 75, 69, + 196, 73, 78, 84, 69, 82, 76, 73, 78, 69, 65, 210, 73, 78, 84, 69, 82, 76, + 65, 67, 69, 196, 73, 78, 84, 69, 82, 73, 79, 210, 73, 78, 84, 69, 82, 69, + 83, 212, 73, 78, 84, 69, 82, 67, 65, 76, 65, 84, 69, 128, 73, 78, 84, 69, + 71, 82, 65, 84, 73, 79, 78, 128, 73, 78, 84, 69, 71, 82, 65, 84, 73, 79, + 206, 73, 78, 84, 69, 71, 82, 65, 76, 128, 73, 78, 84, 69, 71, 82, 65, + 204, 73, 78, 83, 85, 76, 65, 210, 73, 78, 83, 84, 82, 85, 77, 69, 78, 84, + 65, 204, 73, 78, 83, 73, 68, 69, 128, 73, 78, 83, 73, 68, 197, 73, 78, + 83, 69, 82, 84, 73, 79, 206, 73, 78, 83, 69, 82, 212, 73, 78, 83, 69, 67, + 84, 128, 73, 78, 83, 67, 82, 73, 80, 84, 73, 79, 78, 65, 204, 73, 78, 80, + 85, 212, 73, 78, 78, 79, 67, 69, 78, 67, 69, 128, 73, 78, 78, 78, 128, + 73, 78, 78, 69, 82, 128, 73, 78, 78, 69, 210, 73, 78, 78, 128, 73, 78, + 73, 78, 71, 85, 128, 73, 78, 72, 73, 66, 73, 212, 73, 78, 72, 69, 82, 69, + 78, 212, 73, 78, 72, 65, 76, 69, 128, 73, 78, 71, 87, 65, 90, 128, 73, + 78, 70, 79, 82, 77, 65, 84, 73, 79, 206, 73, 78, 70, 76, 85, 69, 78, 67, + 69, 128, 73, 78, 70, 73, 78, 73, 84, 89, 128, 73, 78, 70, 73, 78, 73, 84, + 217, 73, 78, 68, 85, 83, 84, 82, 73, 65, 204, 73, 78, 68, 73, 82, 69, 67, + 212, 73, 78, 68, 73, 67, 84, 73, 79, 206, 73, 78, 68, 73, 67, 65, 84, 79, + 82, 128, 73, 78, 68, 73, 67, 65, 84, 79, 210, 73, 78, 68, 73, 195, 73, + 78, 68, 73, 65, 206, 73, 78, 68, 69, 88, 128, 73, 78, 68, 69, 80, 69, 78, + 68, 69, 78, 212, 73, 78, 67, 82, 69, 77, 69, 78, 84, 128, 73, 78, 67, 82, + 69, 65, 83, 69, 211, 73, 78, 67, 82, 69, 65, 83, 69, 128, 73, 78, 67, 82, + 69, 65, 83, 197, 73, 78, 67, 79, 77, 80, 76, 69, 84, 197, 73, 78, 67, 79, + 77, 73, 78, 199, 73, 78, 67, 76, 85, 68, 73, 78, 199, 73, 78, 67, 72, + 128, 73, 78, 66, 79, 216, 73, 78, 65, 80, 128, 73, 78, 45, 65, 76, 65, + 70, 128, 73, 77, 80, 69, 82, 73, 65, 204, 73, 77, 80, 69, 82, 70, 69, 67, + 84, 85, 205, 73, 77, 80, 69, 82, 70, 69, 67, 84, 65, 128, 73, 77, 80, 69, + 82, 70, 69, 67, 84, 193, 73, 77, 78, 128, 73, 77, 73, 83, 69, 79, 211, + 73, 77, 73, 78, 51, 128, 73, 77, 73, 78, 128, 73, 77, 73, 206, 73, 77, + 73, 70, 84, 72, 79, 82, 79, 78, 128, 73, 77, 73, 70, 84, 72, 79, 82, 65, + 128, 73, 77, 73, 70, 79, 78, 79, 78, 128, 73, 77, 73, 68, 73, 65, 82, 71, + 79, 78, 128, 73, 77, 65, 71, 197, 73, 77, 65, 65, 76, 65, 128, 73, 76, + 85, 89, 65, 78, 78, 65, 128, 73, 76, 85, 89, 128, 73, 76, 85, 85, 89, 65, + 78, 78, 65, 128, 73, 76, 85, 84, 128, 73, 76, 73, 77, 77, 85, 52, 128, + 73, 76, 73, 77, 77, 85, 51, 128, 73, 76, 73, 77, 77, 85, 128, 73, 76, 73, + 77, 77, 213, 73, 76, 50, 128, 73, 75, 73, 82, 128, 73, 75, 65, 82, 65, + 128, 73, 75, 65, 82, 193, 73, 74, 128, 73, 73, 89, 65, 78, 78, 65, 128, + 73, 71, 73, 128, 73, 71, 201, 73, 71, 71, 87, 83, 128, 73, 70, 73, 78, + 128, 73, 69, 85, 78, 71, 45, 84, 73, 75, 69, 85, 84, 128, 73, 69, 85, 78, + 71, 45, 84, 72, 73, 69, 85, 84, 72, 128, 73, 69, 85, 78, 71, 45, 82, 73, + 69, 85, 76, 128, 73, 69, 85, 78, 71, 45, 80, 73, 69, 85, 80, 128, 73, 69, + 85, 78, 71, 45, 80, 72, 73, 69, 85, 80, 72, 128, 73, 69, 85, 78, 71, 45, + 67, 73, 69, 85, 67, 128, 73, 69, 85, 78, 71, 45, 67, 72, 73, 69, 85, 67, + 72, 128, 73, 69, 85, 78, 199, 73, 68, 76, 69, 128, 73, 68, 73, 77, 128, + 73, 68, 73, 205, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 68, 57, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 68, 56, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 68, 55, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 68, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 68, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 68, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 68, 51, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 68, 50, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 68, 49, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 68, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 67, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 67, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 68, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 67, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 66, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 67, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 67, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 67, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 55, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 54, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 53, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 67, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 67, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 67, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 49, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 67, 48, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, 70, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 66, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 66, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 66, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, 66, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, 65, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, 57, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 66, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 66, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 66, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, 53, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, 52, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 66, 51, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 66, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 66, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 66, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, 70, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, 69, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, 68, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 65, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 65, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 65, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, 57, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, 56, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, 55, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 65, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 65, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 65, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, 51, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, 50, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 65, 49, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 65, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 57, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 57, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 68, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 67, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 66, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 57, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 57, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 57, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 55, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 54, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 53, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 57, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 57, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 57, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 49, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 57, 48, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, 70, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 56, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 56, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 56, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, 66, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, 65, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, 57, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 56, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 56, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 56, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, 53, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, 52, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 56, 51, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 56, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 56, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 56, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, 70, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, 69, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, 68, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 55, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 55, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 55, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, 57, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, 56, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, 55, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 55, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 55, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 55, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, 51, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, 50, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 55, 49, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 55, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 54, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 54, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 54, 66, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 54, 65, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 54, 57, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 54, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 54, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 54, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 54, 53, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 54, 52, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 54, 51, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 54, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 54, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 54, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 70, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 69, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 68, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 53, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 53, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 53, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 57, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 56, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 55, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 53, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 53, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 53, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 51, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 50, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 53, 49, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 53, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 52, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 52, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, 68, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, 67, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, 66, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 52, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 52, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 52, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, 55, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, 54, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, 53, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 52, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 52, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 52, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, 49, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 52, 48, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, 70, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 51, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 51, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 51, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, 66, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, 65, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, 57, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 51, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 51, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 51, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, 53, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, 52, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 51, 51, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 51, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 51, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 51, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, 70, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, 69, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, 68, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 50, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 50, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 50, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, 57, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, 56, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, 55, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 50, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 50, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 50, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, 51, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, 50, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 50, 49, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 50, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 49, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 49, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, 68, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, 67, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, 66, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 49, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 49, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 49, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, 55, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, 54, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, 53, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 49, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 49, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 49, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, 49, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 49, 48, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, 70, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 48, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 48, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 48, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, 66, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, 65, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, 57, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 48, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 48, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 48, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, 53, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, 52, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 65, 48, 51, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 65, 48, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 65, 48, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 65, 48, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, 70, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, 69, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, 68, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 70, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 70, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 70, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, 57, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, 56, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, 55, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 70, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 70, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 70, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, 51, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, 50, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 70, 49, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 70, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 69, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 69, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, 68, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, 67, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, 66, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 69, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 69, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 69, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, 55, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, 54, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, 53, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 69, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 69, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 69, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, 49, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 69, 48, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, 70, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 68, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 68, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 68, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, 66, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, 65, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, 57, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 68, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 68, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 68, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, 53, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, 52, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 68, 51, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 68, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 68, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 68, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, 70, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, 69, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, 68, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 67, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 67, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 67, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, 57, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, 56, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, 55, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 67, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 67, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 67, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, 51, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, 50, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 67, 49, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 67, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 66, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 66, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, 68, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, 67, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, 66, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 66, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 66, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 66, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, 55, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, 54, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, 53, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 66, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 66, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 66, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, 49, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 66, 48, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, 70, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 65, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 65, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 65, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, 66, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, 65, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, 57, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 65, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 65, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 65, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, 53, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, 52, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 65, 51, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 65, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 65, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 65, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, 70, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, 69, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, 68, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 57, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 57, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 57, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, 57, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, 56, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, 55, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 57, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 57, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 57, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, 51, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, 50, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 57, 49, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 57, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 56, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 56, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, 68, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, 67, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, 66, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 56, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 56, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 56, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, 55, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, 54, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, 53, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 56, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 56, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 56, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, 49, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 56, 48, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, 70, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 55, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 55, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 55, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, 66, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, 65, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, 57, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 55, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 55, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 55, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, 53, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, 52, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 55, 51, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 55, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 55, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 55, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, 70, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, 69, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, 68, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 54, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 54, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 54, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, 57, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, 56, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, 55, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 54, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 54, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 54, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, 51, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, 50, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 54, 49, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 54, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 53, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 53, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, 68, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, 67, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, 66, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 53, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 53, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 53, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, 55, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, 54, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, 53, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 53, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 53, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 53, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, 49, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 53, 48, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, 70, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 52, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 52, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 52, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, 66, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, 65, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, 57, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 52, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 52, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 52, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, 53, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, 52, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 52, 51, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 52, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 52, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 52, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, 70, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, 69, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, 68, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 51, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 51, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 51, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, 57, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, 56, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, 55, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 51, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 51, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 51, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, 51, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, 50, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 51, 49, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 51, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 50, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 50, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, 68, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, 67, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, 66, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 50, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 50, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 50, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, 55, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, 54, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, 53, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 50, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 50, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 50, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, 49, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 50, 48, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, 70, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 49, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 49, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 49, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, 66, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, 65, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, 57, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 49, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 49, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 49, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, 53, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, 52, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 49, 51, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 49, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 49, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 49, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, 70, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, 69, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, 68, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 48, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 48, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 48, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, 57, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, 56, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, 55, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 48, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 70, 57, 48, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, + 57, 48, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, 51, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, 50, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 70, 57, 48, 49, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 70, 57, 48, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 57, 49, 52, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 57, + 48, 52, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 56, 68, 55, 48, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 56, 67, 65, 57, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 56, 57, 69, 51, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 55, 68, 52, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 55, 65, 55, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 55, + 57, 56, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 55, 54, 68, 55, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 55, 53, 51, 51, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 55, 53, 49, 70, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 55, 49, 50, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 55, 48, 66, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 54, + 70, 49, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 54, 69, 56, 48, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 54, 55, 50, 67, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 54, 55, 48, 57, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 54, 55, 48, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 54, 54, 50, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 54, + 53, 66, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 54, 53, 57, 57, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 54, 53, 53, 55, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 54, 51, 53, 53, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 54, 51, 48, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 54, 50, 57, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 54, + 50, 53, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 54, 50, 52, 66, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 53, 70, 56, 67, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 53, 68, 69, 54, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 53, 66, 56, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 53, 66, 53, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 53, + 57, 50, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 53, 57, 49, 65, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 53, 56, 70, 48, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 53, 53, 66, 54, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 53, 52, 51, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 53, 52, 48, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 53, + 51, 70, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 53, 51, 67, 67, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 53, 50, 68, 68, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 53, 50, 55, 50, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 53, 50, 52, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 53, 50, 49, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 53, + 49, 56, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 52, 69, 65, 52, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 52, 69, 56, 67, 128, 73, 68, + 69, 79, 71, 82, 65, 80, 72, 45, 52, 69, 50, 68, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 52, 69, 48, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, + 72, 45, 52, 69, 48, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 65, 49, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, + 49, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 49, 66, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 49, 65, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 49, 57, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 49, 56, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 65, 49, 55, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 65, 49, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 65, 49, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 65, 49, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, + 49, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 49, 50, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 49, 49, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 49, 48, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 70, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 65, 48, 69, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 65, 48, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 65, 48, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 65, 48, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, + 48, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 57, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 56, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 55, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 54, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 65, 48, 53, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 65, 48, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 65, 48, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 65, 48, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, + 48, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 65, 48, 48, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 70, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 69, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 68, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 70, 67, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 70, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 70, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 70, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 70, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 55, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 54, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 53, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 70, 52, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 70, 51, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 70, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 70, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 70, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 69, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 69, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 68, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 67, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 66, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 69, 65, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 69, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 69, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 69, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 69, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 53, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 52, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 51, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 69, 50, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 69, 49, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 69, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 68, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 68, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 68, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 67, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 66, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 65, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 57, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 68, 56, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 68, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 68, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 68, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 68, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 51, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 50, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 49, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 68, 48, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 67, 70, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 67, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 67, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 67, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 67, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 65, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 57, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 56, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 55, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 67, 54, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 67, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 67, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 67, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 67, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 49, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 67, 48, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 70, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 69, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 66, 68, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 66, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 66, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 66, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 66, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 56, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 55, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 54, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 66, 53, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 66, 52, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 66, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 66, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 66, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 66, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 70, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 69, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 68, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 67, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 65, 66, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 65, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 65, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 65, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 65, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 54, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 53, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 52, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 65, 51, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 65, 50, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 65, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 65, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 57, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 57, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 68, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 67, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 66, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 65, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 57, 57, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 57, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 57, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 57, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 57, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 52, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 51, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 50, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 57, 49, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 57, 48, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 56, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 56, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 56, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 56, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 66, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 65, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 57, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 56, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 56, 55, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 56, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 56, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 56, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 56, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 50, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 49, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 56, 48, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 70, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 55, 69, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 55, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 55, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 55, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 55, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 57, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 56, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 55, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 54, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 55, 53, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 55, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 55, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 55, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 55, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 55, 48, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 70, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 69, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 68, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 54, 67, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 54, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 54, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 54, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 54, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 55, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 54, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 53, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 54, 52, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 54, 51, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 54, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 54, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 54, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 53, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 69, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 68, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 67, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 66, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 53, 65, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 53, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 53, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 53, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 53, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 53, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 52, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 51, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 53, 50, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 53, 49, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 53, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 52, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 52, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 52, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 67, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 66, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 65, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 57, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 52, 56, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 52, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 52, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 52, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 52, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 51, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 50, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 49, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 52, 48, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 51, 70, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 51, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 51, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 51, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 51, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 65, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 57, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 56, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 55, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 51, 54, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 51, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 51, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 51, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 51, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 49, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 51, 48, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 70, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 69, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 50, 68, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 50, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 50, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 50, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 50, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 56, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 55, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 54, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 50, 53, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 50, 52, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 50, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 50, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 50, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 50, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 70, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 69, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 68, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 67, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 49, 66, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 49, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 49, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 49, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 49, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 54, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 53, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 52, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 49, 51, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 49, 50, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 49, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 49, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 48, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 48, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 68, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 67, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 66, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 65, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 48, 57, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 57, 48, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 57, 48, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 57, 48, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, + 48, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 52, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 51, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 50, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 57, 48, 49, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 57, 48, 48, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 70, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 70, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 70, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 70, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 66, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 65, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 57, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 56, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 70, 55, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 70, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 70, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 70, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 70, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 50, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 49, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 70, 48, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 70, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 69, 69, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 69, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 69, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 69, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 69, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 57, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 56, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 55, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 54, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 69, 53, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 69, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 69, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 69, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 69, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 69, 48, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 70, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 69, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 68, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 68, 67, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 68, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 68, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 68, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 68, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 55, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 54, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 53, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 68, 52, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 68, 51, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 68, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 68, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 68, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 67, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 69, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 68, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 67, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 66, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 67, 65, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 67, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 67, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 67, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 67, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 53, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 52, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 51, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 67, 50, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 67, 49, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 67, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 66, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 66, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 66, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 67, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 66, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 65, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 57, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 66, 56, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 66, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 66, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 66, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 66, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 51, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 50, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 49, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 66, 48, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 65, 70, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 65, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 65, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 65, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 65, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 65, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 57, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 56, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 55, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 65, 54, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 65, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 65, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 65, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 65, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 49, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 65, 48, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 70, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 69, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 57, 68, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 57, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 57, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 57, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 57, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 56, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 55, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 54, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 57, 53, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 57, 52, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 57, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 57, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 57, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 57, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 70, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 69, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 68, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 67, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 56, 66, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 56, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 56, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 56, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 56, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 54, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 53, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 52, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 56, 51, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 56, 50, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 56, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 56, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 55, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 55, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 68, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 67, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 66, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 65, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 55, 57, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 55, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 55, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 55, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 55, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 52, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 51, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 50, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 55, 49, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 55, 48, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 54, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 54, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 54, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 54, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 66, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 65, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 57, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 56, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 54, 55, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 54, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 54, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 54, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 54, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 50, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 49, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 54, 48, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 70, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 53, 69, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 53, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 53, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 53, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 53, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 57, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 56, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 55, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 54, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 53, 53, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 53, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 53, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 53, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 53, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 53, 48, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 70, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 69, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 68, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 52, 67, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 52, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 52, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 52, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 52, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 55, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 54, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 53, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 52, 52, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 52, 51, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 52, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 52, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 52, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 51, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 69, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 68, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 67, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 66, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 51, 65, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 51, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 51, 56, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 51, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 51, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 53, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 52, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 51, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 51, 50, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 51, 49, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 51, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 50, 70, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 50, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 50, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 67, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 66, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 65, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 57, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 50, 56, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 50, 55, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 50, 54, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 50, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 50, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 51, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 50, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 49, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 50, 48, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 49, 70, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 49, 69, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 49, 68, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 49, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 49, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 65, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 57, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 56, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 55, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 49, 54, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 49, 53, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 49, 52, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 49, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 49, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 49, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 49, 48, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 70, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 69, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 48, 68, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 48, 67, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 48, 66, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 48, 65, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 48, 57, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 56, + 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 55, 128, 73, + 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 54, 128, 73, 68, 69, + 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, 48, 53, 128, 73, 68, 69, 79, 71, + 82, 65, 80, 72, 45, 50, 70, 56, 48, 52, 128, 73, 68, 69, 79, 71, 82, 65, + 80, 72, 45, 50, 70, 56, 48, 51, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, + 45, 50, 70, 56, 48, 50, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, + 70, 56, 48, 49, 128, 73, 68, 69, 79, 71, 82, 65, 80, 72, 45, 50, 70, 56, + 48, 48, 128, 73, 68, 69, 79, 71, 82, 65, 80, 200, 73, 68, 69, 78, 84, 73, + 70, 73, 67, 65, 84, 73, 79, 78, 128, 73, 68, 69, 78, 84, 73, 70, 73, 67, + 65, 84, 73, 79, 206, 73, 68, 69, 78, 84, 73, 67, 65, 204, 73, 68, 68, + 128, 73, 67, 79, 78, 128, 73, 67, 72, 79, 85, 128, 73, 67, 72, 79, 83, + 128, 73, 67, 72, 73, 77, 65, 84, 79, 83, 128, 73, 67, 72, 65, 68, 73, 78, + 128, 73, 67, 69, 76, 65, 78, 68, 73, 67, 45, 89, 82, 128, 73, 66, 73, 70, + 73, 76, 73, 128, 73, 65, 85, 68, 65, 128, 73, 48, 49, 53, 128, 73, 48, + 49, 52, 128, 73, 48, 49, 51, 128, 73, 48, 49, 50, 128, 73, 48, 49, 49, + 65, 128, 73, 48, 49, 49, 128, 73, 48, 49, 48, 65, 128, 73, 48, 49, 48, + 128, 73, 48, 48, 57, 65, 128, 73, 48, 48, 57, 128, 73, 48, 48, 56, 128, + 73, 48, 48, 55, 128, 73, 48, 48, 54, 128, 73, 48, 48, 53, 65, 128, 73, + 48, 48, 53, 128, 73, 48, 48, 52, 128, 73, 48, 48, 51, 128, 73, 48, 48, + 50, 128, 73, 48, 48, 49, 128, 73, 45, 89, 85, 128, 73, 45, 89, 79, 128, + 73, 45, 89, 69, 79, 128, 73, 45, 89, 69, 128, 73, 45, 89, 65, 69, 128, + 73, 45, 89, 65, 45, 79, 128, 73, 45, 89, 65, 128, 73, 45, 79, 45, 73, + 128, 73, 45, 79, 128, 73, 45, 69, 85, 128, 73, 45, 66, 69, 65, 77, 128, + 73, 45, 65, 82, 65, 69, 65, 128, 73, 45, 65, 128, 72, 90, 90, 90, 71, + 128, 72, 90, 90, 90, 128, 72, 90, 90, 80, 128, 72, 90, 90, 128, 72, 90, + 87, 71, 128, 72, 90, 87, 128, 72, 90, 84, 128, 72, 90, 71, 128, 72, 89, + 83, 84, 69, 82, 69, 83, 73, 211, 72, 89, 80, 79, 68, 73, 65, 83, 84, 79, + 76, 69, 128, 72, 89, 80, 72, 69, 78, 65, 84, 73, 79, 206, 72, 89, 80, 72, + 69, 78, 45, 77, 73, 78, 85, 83, 128, 72, 89, 80, 72, 69, 78, 128, 72, 89, + 80, 72, 69, 206, 72, 89, 71, 73, 69, 73, 65, 128, 72, 89, 71, 73, 69, 65, + 128, 72, 89, 65, 67, 73, 78, 84, 72, 128, 72, 88, 87, 71, 128, 72, 88, + 85, 79, 88, 128, 72, 88, 85, 79, 84, 128, 72, 88, 85, 79, 80, 128, 72, + 88, 85, 79, 128, 72, 88, 79, 88, 128, 72, 88, 79, 84, 128, 72, 88, 79, + 80, 128, 72, 88, 79, 128, 72, 88, 73, 88, 128, 72, 88, 73, 84, 128, 72, + 88, 73, 80, 128, 72, 88, 73, 69, 88, 128, 72, 88, 73, 69, 84, 128, 72, + 88, 73, 69, 80, 128, 72, 88, 73, 69, 128, 72, 88, 73, 128, 72, 88, 69, + 88, 128, 72, 88, 69, 80, 128, 72, 88, 69, 128, 72, 88, 65, 88, 128, 72, + 88, 65, 84, 128, 72, 88, 65, 80, 128, 72, 88, 65, 128, 72, 87, 85, 128, + 72, 87, 65, 73, 82, 128, 72, 87, 65, 72, 128, 72, 85, 86, 65, 128, 72, + 85, 83, 72, 69, 196, 72, 85, 83, 72, 128, 72, 85, 82, 65, 78, 128, 72, + 85, 79, 84, 128, 72, 85, 78, 68, 82, 69, 68, 83, 128, 72, 85, 78, 68, 82, + 69, 68, 211, 72, 85, 78, 68, 82, 69, 68, 128, 72, 85, 78, 68, 82, 69, + 196, 72, 85, 78, 128, 72, 85, 77, 208, 72, 85, 77, 65, 78, 128, 72, 85, + 77, 65, 206, 72, 85, 76, 50, 128, 72, 85, 73, 73, 84, 79, 128, 72, 85, + 71, 71, 73, 78, 71, 128, 72, 85, 71, 71, 73, 78, 199, 72, 85, 66, 50, + 128, 72, 85, 66, 178, 72, 85, 66, 128, 72, 85, 65, 82, 65, 68, 68, 79, + 128, 72, 85, 65, 78, 128, 72, 85, 45, 51, 128, 72, 85, 45, 50, 128, 72, + 85, 45, 49, 128, 72, 84, 84, 65, 128, 72, 84, 83, 128, 72, 84, 74, 128, + 72, 82, 89, 86, 78, 73, 193, 72, 80, 87, 71, 128, 72, 80, 65, 128, 72, + 80, 128, 72, 79, 85, 83, 197, 72, 79, 85, 82, 71, 76, 65, 83, 83, 128, + 72, 79, 85, 82, 71, 76, 65, 83, 211, 72, 79, 85, 82, 128, 72, 79, 85, + 210, 72, 79, 84, 69, 76, 128, 72, 79, 84, 65, 128, 72, 79, 83, 80, 73, + 84, 65, 76, 128, 72, 79, 82, 83, 69, 128, 72, 79, 82, 83, 197, 72, 79, + 82, 82, 128, 72, 79, 82, 78, 83, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, + 76, 76, 89, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 76, 217, 72, 79, + 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 54, 45, 48, 54, 128, 72, 79, 82, + 73, 90, 79, 78, 84, 65, 76, 45, 48, 54, 45, 48, 53, 128, 72, 79, 82, 73, + 90, 79, 78, 84, 65, 76, 45, 48, 54, 45, 48, 52, 128, 72, 79, 82, 73, 90, + 79, 78, 84, 65, 76, 45, 48, 54, 45, 48, 51, 128, 72, 79, 82, 73, 90, 79, + 78, 84, 65, 76, 45, 48, 54, 45, 48, 50, 128, 72, 79, 82, 73, 90, 79, 78, + 84, 65, 76, 45, 48, 54, 45, 48, 49, 128, 72, 79, 82, 73, 90, 79, 78, 84, + 65, 76, 45, 48, 54, 45, 48, 48, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, + 76, 45, 48, 53, 45, 48, 54, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, + 45, 48, 53, 45, 48, 53, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, + 48, 53, 45, 48, 52, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, + 53, 45, 48, 51, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 53, + 45, 48, 50, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 53, 45, + 48, 49, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 53, 45, 48, + 48, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 52, 45, 48, 54, + 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 52, 45, 48, 53, 128, + 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 52, 45, 48, 52, 128, 72, + 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 52, 45, 48, 51, 128, 72, 79, + 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 52, 45, 48, 50, 128, 72, 79, 82, + 73, 90, 79, 78, 84, 65, 76, 45, 48, 52, 45, 48, 49, 128, 72, 79, 82, 73, + 90, 79, 78, 84, 65, 76, 45, 48, 52, 45, 48, 48, 128, 72, 79, 82, 73, 90, + 79, 78, 84, 65, 76, 45, 48, 51, 45, 48, 54, 128, 72, 79, 82, 73, 90, 79, + 78, 84, 65, 76, 45, 48, 51, 45, 48, 53, 128, 72, 79, 82, 73, 90, 79, 78, + 84, 65, 76, 45, 48, 51, 45, 48, 52, 128, 72, 79, 82, 73, 90, 79, 78, 84, + 65, 76, 45, 48, 51, 45, 48, 51, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, + 76, 45, 48, 51, 45, 48, 50, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, + 45, 48, 51, 45, 48, 49, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, + 48, 51, 45, 48, 48, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, + 50, 45, 48, 54, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 50, + 45, 48, 53, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 50, 45, + 48, 52, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 50, 45, 48, + 51, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 50, 45, 48, 50, + 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 50, 45, 48, 49, 128, + 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 50, 45, 48, 48, 128, 72, + 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 49, 45, 48, 54, 128, 72, 79, + 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 49, 45, 48, 53, 128, 72, 79, 82, + 73, 90, 79, 78, 84, 65, 76, 45, 48, 49, 45, 48, 52, 128, 72, 79, 82, 73, + 90, 79, 78, 84, 65, 76, 45, 48, 49, 45, 48, 51, 128, 72, 79, 82, 73, 90, + 79, 78, 84, 65, 76, 45, 48, 49, 45, 48, 50, 128, 72, 79, 82, 73, 90, 79, + 78, 84, 65, 76, 45, 48, 49, 45, 48, 49, 128, 72, 79, 82, 73, 90, 79, 78, + 84, 65, 76, 45, 48, 49, 45, 48, 48, 128, 72, 79, 82, 73, 90, 79, 78, 84, + 65, 76, 45, 48, 48, 45, 48, 54, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, + 76, 45, 48, 48, 45, 48, 53, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, + 45, 48, 48, 45, 48, 52, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, + 48, 48, 45, 48, 51, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, + 48, 45, 48, 50, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 48, + 45, 48, 49, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 45, 48, 48, 45, + 48, 48, 128, 72, 79, 82, 73, 90, 79, 78, 84, 65, 76, 128, 72, 79, 82, 73, + 90, 79, 78, 84, 65, 204, 72, 79, 82, 73, 128, 72, 79, 82, 193, 72, 79, + 79, 85, 128, 72, 79, 79, 82, 85, 128, 72, 79, 79, 80, 128, 72, 79, 79, + 78, 128, 72, 79, 79, 75, 69, 68, 128, 72, 79, 79, 75, 69, 196, 72, 79, + 78, 69, 89, 66, 69, 69, 128, 72, 79, 78, 69, 217, 72, 79, 77, 79, 84, 72, + 69, 84, 73, 67, 128, 72, 79, 77, 79, 84, 72, 69, 84, 73, 195, 72, 79, 76, + 79, 128, 72, 79, 76, 76, 79, 215, 72, 79, 76, 69, 128, 72, 79, 76, 68, + 73, 78, 199, 72, 79, 76, 65, 77, 128, 72, 79, 76, 65, 205, 72, 79, 75, + 65, 128, 72, 79, 67, 75, 69, 217, 72, 79, 67, 72, 79, 128, 72, 79, 45, + 56, 128, 72, 79, 45, 55, 128, 72, 79, 45, 54, 128, 72, 79, 45, 53, 128, + 72, 79, 45, 52, 128, 72, 79, 45, 51, 128, 72, 79, 45, 50, 128, 72, 79, + 45, 49, 128, 72, 78, 85, 84, 128, 72, 78, 85, 79, 88, 128, 72, 78, 85, + 79, 128, 72, 78, 85, 66, 128, 72, 78, 79, 88, 128, 72, 78, 79, 84, 128, + 72, 78, 79, 80, 128, 72, 78, 73, 88, 128, 72, 78, 73, 84, 128, 72, 78, + 73, 80, 128, 72, 78, 73, 69, 88, 128, 72, 78, 73, 69, 84, 128, 72, 78, + 73, 69, 80, 128, 72, 78, 73, 69, 128, 72, 78, 73, 128, 72, 78, 69, 88, + 128, 72, 78, 69, 80, 128, 72, 78, 69, 128, 72, 78, 65, 88, 128, 72, 78, + 65, 85, 128, 72, 78, 65, 84, 128, 72, 78, 65, 80, 128, 72, 78, 65, 128, + 72, 77, 89, 88, 128, 72, 77, 89, 82, 88, 128, 72, 77, 89, 82, 128, 72, + 77, 89, 80, 128, 72, 77, 89, 128, 72, 77, 85, 88, 128, 72, 77, 85, 84, + 128, 72, 77, 85, 82, 88, 128, 72, 77, 85, 82, 128, 72, 77, 85, 80, 128, + 72, 77, 85, 79, 88, 128, 72, 77, 85, 79, 80, 128, 72, 77, 85, 79, 128, + 72, 77, 85, 128, 72, 77, 79, 88, 128, 72, 77, 79, 84, 128, 72, 77, 79, + 80, 128, 72, 77, 79, 128, 72, 77, 73, 88, 128, 72, 77, 73, 84, 128, 72, + 77, 73, 80, 128, 72, 77, 73, 69, 88, 128, 72, 77, 73, 69, 80, 128, 72, + 77, 73, 69, 128, 72, 77, 73, 128, 72, 77, 69, 128, 72, 77, 65, 88, 128, + 72, 77, 65, 84, 128, 72, 77, 65, 80, 128, 72, 77, 65, 128, 72, 76, 89, + 88, 128, 72, 76, 89, 84, 128, 72, 76, 89, 82, 88, 128, 72, 76, 89, 82, + 128, 72, 76, 89, 80, 128, 72, 76, 89, 128, 72, 76, 85, 88, 128, 72, 76, + 85, 84, 128, 72, 76, 85, 82, 88, 128, 72, 76, 85, 82, 128, 72, 76, 85, + 80, 128, 72, 76, 85, 79, 88, 128, 72, 76, 85, 79, 80, 128, 72, 76, 85, + 79, 128, 72, 76, 85, 128, 72, 76, 79, 88, 128, 72, 76, 79, 80, 128, 72, + 76, 79, 128, 72, 76, 73, 88, 128, 72, 76, 73, 84, 128, 72, 76, 73, 80, + 128, 72, 76, 73, 69, 88, 128, 72, 76, 73, 69, 80, 128, 72, 76, 73, 69, + 128, 72, 76, 73, 128, 72, 76, 69, 88, 128, 72, 76, 69, 80, 128, 72, 76, + 69, 128, 72, 76, 65, 88, 128, 72, 76, 65, 85, 128, 72, 76, 65, 84, 128, + 72, 76, 65, 80, 128, 72, 76, 65, 128, 72, 76, 128, 72, 75, 128, 72, 73, + 90, 66, 128, 72, 73, 89, 79, 128, 72, 73, 84, 84, 73, 78, 199, 72, 73, + 83, 84, 79, 82, 73, 195, 72, 73, 82, 73, 81, 128, 72, 73, 80, 80, 79, 80, + 79, 84, 65, 77, 85, 83, 128, 72, 73, 78, 71, 69, 68, 128, 72, 73, 78, 71, + 69, 196, 72, 73, 78, 71, 69, 128, 72, 73, 78, 68, 213, 72, 73, 75, 73, + 78, 199, 72, 73, 71, 72, 45, 83, 80, 69, 69, 196, 72, 73, 71, 72, 45, 82, + 69, 86, 69, 82, 83, 69, 68, 45, 185, 72, 73, 71, 72, 45, 76, 79, 215, 72, + 73, 71, 72, 45, 72, 69, 69, 76, 69, 196, 72, 73, 69, 88, 128, 72, 73, 69, + 85, 72, 45, 83, 73, 79, 83, 128, 72, 73, 69, 85, 72, 45, 82, 73, 69, 85, + 76, 128, 72, 73, 69, 85, 72, 45, 80, 73, 69, 85, 80, 128, 72, 73, 69, 85, + 72, 45, 78, 73, 69, 85, 78, 128, 72, 73, 69, 85, 72, 45, 77, 73, 69, 85, + 77, 128, 72, 73, 69, 85, 200, 72, 73, 69, 82, 79, 71, 76, 89, 80, 72, 73, + 195, 72, 73, 68, 73, 78, 199, 72, 73, 68, 69, 84, 128, 72, 73, 68, 69, + 128, 72, 73, 66, 73, 83, 67, 85, 83, 128, 72, 73, 45, 82, 69, 83, 128, + 72, 73, 45, 55, 128, 72, 73, 45, 54, 128, 72, 73, 45, 53, 128, 72, 73, + 45, 52, 128, 72, 73, 45, 51, 128, 72, 73, 45, 50, 128, 72, 73, 45, 49, + 128, 72, 72, 89, 85, 128, 72, 72, 89, 79, 128, 72, 72, 89, 73, 128, 72, + 72, 89, 69, 69, 128, 72, 72, 89, 69, 128, 72, 72, 89, 65, 65, 128, 72, + 72, 89, 65, 128, 72, 72, 87, 73, 128, 72, 72, 87, 69, 69, 128, 72, 72, + 87, 69, 128, 72, 72, 87, 65, 128, 72, 72, 85, 128, 72, 72, 73, 128, 72, + 72, 69, 69, 128, 72, 72, 69, 128, 72, 72, 65, 65, 128, 72, 71, 128, 72, + 69, 89, 84, 128, 72, 69, 88, 73, 70, 79, 82, 205, 72, 69, 88, 65, 71, 82, + 65, 205, 72, 69, 88, 65, 71, 79, 78, 128, 72, 69, 82, 85, 84, 85, 128, + 72, 69, 82, 85, 128, 72, 69, 82, 77, 73, 84, 73, 65, 206, 72, 69, 82, 77, + 73, 79, 78, 73, 65, 206, 72, 69, 82, 77, 69, 83, 128, 72, 69, 82, 69, + 128, 72, 69, 82, 66, 128, 72, 69, 82, 65, 69, 85, 205, 72, 69, 78, 71, + 128, 72, 69, 78, 199, 72, 69, 77, 80, 128, 72, 69, 76, 77, 69, 84, 128, + 72, 69, 76, 77, 69, 212, 72, 69, 76, 205, 72, 69, 76, 76, 83, 67, 72, 82, + 69, 73, 66, 69, 210, 72, 69, 76, 73, 88, 128, 72, 69, 76, 73, 67, 79, 80, + 84, 69, 82, 128, 72, 69, 75, 85, 84, 65, 65, 82, 85, 128, 72, 69, 73, 83, + 69, 73, 128, 72, 69, 73, 71, 72, 84, 128, 72, 69, 69, 73, 128, 72, 69, + 68, 71, 69, 72, 79, 71, 128, 72, 69, 65, 86, 89, 128, 72, 69, 65, 86, 69, + 78, 76, 217, 72, 69, 65, 86, 69, 78, 128, 72, 69, 65, 86, 69, 206, 72, + 69, 65, 82, 84, 83, 128, 72, 69, 65, 82, 84, 45, 83, 72, 65, 80, 69, 196, + 72, 69, 65, 82, 84, 128, 72, 69, 65, 82, 212, 72, 69, 65, 82, 73, 78, + 199, 72, 69, 65, 82, 45, 78, 79, 45, 69, 86, 73, 204, 72, 69, 65, 68, 83, + 84, 82, 79, 75, 69, 128, 72, 69, 65, 68, 83, 84, 79, 78, 69, 128, 72, 69, + 65, 68, 83, 84, 79, 78, 197, 72, 69, 65, 68, 83, 67, 65, 82, 70, 128, 72, + 69, 65, 68, 80, 72, 79, 78, 69, 128, 72, 69, 65, 68, 73, 78, 71, 128, 72, + 69, 65, 68, 45, 66, 65, 78, 68, 65, 71, 69, 128, 72, 69, 45, 55, 128, 72, + 69, 45, 54, 128, 72, 69, 45, 53, 128, 72, 69, 45, 52, 128, 72, 69, 45, + 51, 128, 72, 69, 45, 50, 128, 72, 69, 45, 49, 128, 72, 68, 82, 128, 72, + 67, 128, 72, 66, 65, 83, 65, 45, 69, 83, 65, 83, 193, 72, 66, 65, 83, + 193, 72, 65, 89, 65, 78, 78, 65, 128, 72, 65, 87, 74, 128, 72, 65, 86, + 69, 128, 72, 65, 85, 80, 84, 83, 84, 73, 77, 77, 69, 128, 72, 65, 85, 77, + 69, 65, 128, 72, 65, 213, 72, 65, 84, 82, 65, 206, 72, 65, 84, 72, 73, + 128, 72, 65, 84, 69, 128, 72, 65, 84, 67, 72, 73, 78, 199, 72, 65, 84, + 65, 198, 72, 65, 83, 69, 210, 72, 65, 83, 65, 78, 84, 65, 128, 72, 65, + 82, 80, 79, 79, 78, 128, 72, 65, 82, 80, 79, 79, 206, 72, 65, 82, 77, 79, + 78, 73, 67, 128, 72, 65, 82, 75, 76, 69, 65, 206, 72, 65, 82, 68, 78, 69, + 83, 83, 128, 72, 65, 82, 196, 72, 65, 82, 66, 65, 72, 65, 89, 128, 72, + 65, 80, 80, 217, 72, 65, 78, 85, 78, 79, 207, 72, 65, 78, 73, 70, 201, + 72, 65, 78, 71, 90, 72, 79, 213, 72, 65, 78, 68, 83, 72, 65, 75, 69, 128, + 72, 65, 78, 68, 83, 128, 72, 65, 78, 68, 211, 72, 65, 78, 68, 76, 69, 83, + 128, 72, 65, 78, 68, 76, 69, 128, 72, 65, 78, 68, 66, 65, 76, 76, 128, + 72, 65, 78, 68, 66, 65, 71, 128, 72, 65, 78, 68, 45, 79, 86, 65, 76, 128, + 72, 65, 78, 68, 45, 79, 86, 65, 204, 72, 65, 78, 68, 45, 72, 79, 79, 75, + 128, 72, 65, 78, 68, 45, 72, 79, 79, 203, 72, 65, 78, 68, 45, 72, 73, 78, + 71, 69, 128, 72, 65, 78, 68, 45, 72, 73, 78, 71, 197, 72, 65, 78, 68, 45, + 70, 76, 65, 84, 128, 72, 65, 78, 68, 45, 70, 76, 65, 212, 72, 65, 78, 68, + 45, 70, 73, 83, 84, 128, 72, 65, 78, 68, 45, 67, 85, 82, 76, 73, 67, 85, + 69, 128, 72, 65, 78, 68, 45, 67, 85, 82, 76, 73, 67, 85, 197, 72, 65, 78, + 68, 45, 67, 85, 80, 128, 72, 65, 78, 68, 45, 67, 85, 208, 72, 65, 78, 68, + 45, 67, 76, 65, 87, 128, 72, 65, 78, 68, 45, 67, 76, 65, 215, 72, 65, 78, + 68, 45, 67, 73, 82, 67, 76, 69, 128, 72, 65, 78, 68, 45, 67, 73, 82, 67, + 76, 197, 72, 65, 78, 68, 45, 65, 78, 71, 76, 69, 128, 72, 65, 78, 68, 45, + 65, 78, 71, 76, 197, 72, 65, 78, 68, 128, 72, 65, 78, 45, 65, 75, 65, 84, + 128, 72, 65, 77, 90, 65, 128, 72, 65, 77, 90, 193, 72, 65, 77, 83, 84, + 69, 210, 72, 65, 77, 83, 65, 128, 72, 65, 77, 77, 69, 82, 128, 72, 65, + 77, 77, 69, 210, 72, 65, 77, 66, 85, 82, 71, 69, 82, 128, 72, 65, 76, 81, + 65, 128, 72, 65, 76, 79, 128, 72, 65, 76, 70, 45, 67, 73, 82, 67, 76, + 197, 72, 65, 76, 70, 45, 50, 128, 72, 65, 76, 70, 45, 49, 128, 72, 65, + 76, 70, 128, 72, 65, 76, 66, 69, 82, 68, 128, 72, 65, 76, 65, 78, 84, 65, + 128, 72, 65, 73, 84, 85, 128, 72, 65, 73, 211, 72, 65, 73, 82, 67, 85, + 84, 128, 72, 65, 71, 76, 65, 218, 72, 65, 71, 76, 128, 72, 65, 70, 85, + 75, 72, 65, 128, 72, 65, 70, 85, 75, 72, 128, 72, 65, 69, 71, 204, 72, + 65, 68, 69, 83, 128, 72, 65, 65, 82, 85, 128, 72, 65, 65, 77, 128, 72, + 65, 193, 72, 65, 45, 72, 65, 128, 72, 65, 45, 57, 128, 72, 65, 45, 56, + 128, 72, 65, 45, 55, 128, 72, 65, 45, 54, 128, 72, 65, 45, 53, 128, 72, + 65, 45, 52, 128, 72, 65, 45, 51, 128, 72, 65, 45, 50, 128, 72, 65, 45, + 49, 49, 128, 72, 65, 45, 49, 48, 128, 72, 65, 45, 49, 128, 72, 48, 48, + 56, 128, 72, 48, 48, 55, 128, 72, 48, 48, 54, 65, 128, 72, 48, 48, 54, + 128, 72, 48, 48, 53, 128, 72, 48, 48, 52, 128, 72, 48, 48, 51, 128, 72, + 48, 48, 50, 128, 72, 48, 48, 49, 128, 72, 45, 84, 89, 80, 197, 71, 89, + 85, 128, 71, 89, 79, 78, 128, 71, 89, 79, 128, 71, 89, 73, 128, 71, 89, + 70, 213, 71, 89, 69, 69, 128, 71, 89, 65, 83, 128, 71, 89, 65, 65, 128, + 71, 89, 65, 128, 71, 89, 128, 71, 87, 85, 128, 71, 87, 73, 128, 71, 87, + 69, 69, 128, 71, 87, 69, 128, 71, 87, 65, 65, 128, 71, 87, 65, 128, 71, + 87, 128, 71, 86, 65, 78, 71, 128, 71, 86, 128, 71, 85, 82, 85, 83, 72, + 128, 71, 85, 82, 85, 78, 128, 71, 85, 82, 77, 85, 75, 72, 201, 71, 85, + 82, 65, 77, 85, 84, 79, 78, 128, 71, 85, 82, 65, 71, 197, 71, 85, 82, 55, + 128, 71, 85, 78, 85, 128, 71, 85, 78, 213, 71, 85, 78, 74, 65, 76, 193, + 71, 85, 205, 71, 85, 76, 128, 71, 85, 74, 65, 82, 65, 84, 201, 71, 85, + 73, 84, 65, 82, 128, 71, 85, 73, 68, 197, 71, 85, 199, 71, 85, 69, 73, + 128, 71, 85, 69, 72, 128, 71, 85, 69, 200, 71, 85, 68, 128, 71, 85, 196, + 71, 85, 65, 82, 68, 83, 77, 65, 78, 128, 71, 85, 65, 82, 68, 69, 68, 78, + 69, 83, 83, 128, 71, 85, 65, 82, 68, 69, 196, 71, 85, 65, 82, 68, 128, + 71, 85, 65, 82, 65, 78, 201, 71, 85, 193, 71, 85, 178, 71, 84, 69, 210, + 71, 83, 85, 77, 128, 71, 83, 85, 205, 71, 82, 213, 71, 82, 79, 87, 73, + 78, 199, 71, 82, 79, 85, 78, 68, 128, 71, 82, 79, 78, 84, 72, 73, 83, 77, + 65, 84, 65, 128, 71, 82, 79, 77, 79, 80, 79, 86, 79, 68, 78, 65, 89, 65, + 128, 71, 82, 79, 77, 79, 80, 79, 86, 79, 68, 78, 65, 89, 193, 71, 82, 79, + 77, 79, 75, 82, 89, 90, 72, 69, 86, 65, 89, 65, 128, 71, 82, 79, 77, 79, + 75, 82, 89, 90, 72, 69, 86, 65, 89, 193, 71, 82, 79, 77, 78, 65, 89, 65, + 128, 71, 82, 79, 77, 78, 65, 89, 193, 71, 82, 73, 78, 78, 73, 78, 199, + 71, 82, 73, 77, 65, 67, 73, 78, 199, 71, 82, 69, 217, 71, 82, 69, 71, 79, + 82, 73, 65, 206, 71, 82, 69, 69, 78, 128, 71, 82, 69, 69, 206, 71, 82, + 69, 65, 84, 78, 69, 83, 83, 128, 71, 82, 69, 65, 84, 69, 82, 45, 84, 72, + 65, 78, 128, 71, 82, 69, 65, 84, 69, 82, 45, 84, 72, 65, 206, 71, 82, 69, + 65, 84, 69, 210, 71, 82, 69, 65, 212, 71, 82, 65, 86, 69, 89, 65, 82, + 196, 71, 82, 65, 86, 69, 45, 77, 65, 67, 82, 79, 78, 128, 71, 82, 65, 86, + 69, 45, 65, 67, 85, 84, 69, 45, 71, 82, 65, 86, 69, 128, 71, 82, 65, 86, + 197, 71, 82, 65, 84, 69, 82, 128, 71, 82, 65, 83, 83, 128, 71, 82, 65, + 83, 211, 71, 82, 65, 83, 208, 71, 82, 65, 80, 72, 69, 77, 197, 71, 82, + 65, 80, 69, 83, 128, 71, 82, 65, 78, 84, 72, 193, 71, 82, 65, 77, 77, + 193, 71, 82, 65, 73, 78, 128, 71, 82, 65, 70, 128, 71, 82, 65, 68, 85, + 65, 84, 73, 79, 206, 71, 82, 65, 68, 85, 65, 76, 128, 71, 82, 65, 67, 69, + 128, 71, 82, 65, 67, 197, 71, 80, 65, 128, 71, 79, 82, 84, 72, 77, 73, + 75, 79, 206, 71, 79, 82, 84, 128, 71, 79, 82, 73, 76, 76, 65, 128, 71, + 79, 82, 71, 79, 84, 69, 82, 73, 128, 71, 79, 82, 71, 79, 83, 89, 78, 84, + 72, 69, 84, 79, 78, 128, 71, 79, 82, 71, 79, 206, 71, 79, 82, 71, 73, + 128, 71, 79, 82, 65, 90, 68, 207, 71, 79, 82, 65, 128, 71, 79, 79, 83, + 69, 128, 71, 79, 79, 196, 71, 79, 78, 71, 71, 79, 78, 71, 128, 71, 79, + 76, 85, 66, 67, 72, 73, 203, 71, 79, 76, 70, 69, 82, 128, 71, 79, 76, 68, + 128, 71, 79, 75, 128, 71, 79, 73, 78, 199, 71, 79, 71, 71, 76, 69, 83, + 128, 71, 79, 66, 76, 73, 78, 128, 71, 79, 65, 76, 128, 71, 79, 65, 204, + 71, 79, 65, 128, 71, 78, 89, 73, 83, 128, 71, 78, 65, 86, 73, 89, 65, 78, + 73, 128, 71, 76, 79, 87, 73, 78, 199, 71, 76, 79, 86, 69, 83, 128, 71, + 76, 79, 86, 69, 128, 71, 76, 79, 84, 84, 65, 204, 71, 76, 79, 66, 197, + 71, 76, 73, 83, 83, 65, 78, 68, 207, 71, 76, 69, 73, 67, 200, 71, 76, 65, + 71, 79, 76, 73, 128, 71, 76, 65, 128, 71, 74, 69, 128, 71, 73, 88, 128, + 71, 73, 84, 128, 71, 73, 83, 72, 128, 71, 73, 83, 200, 71, 73, 83, 65, + 76, 128, 71, 73, 82, 85, 68, 65, 65, 128, 71, 73, 82, 76, 211, 71, 73, + 82, 76, 128, 71, 73, 82, 65, 70, 70, 197, 71, 73, 82, 51, 128, 71, 73, + 82, 179, 71, 73, 82, 50, 128, 71, 73, 82, 178, 71, 73, 80, 128, 71, 73, + 78, 73, 73, 128, 71, 73, 78, 71, 69, 210, 71, 73, 77, 69, 76, 45, 72, 69, + 84, 72, 128, 71, 73, 77, 69, 76, 128, 71, 73, 77, 69, 204, 71, 73, 77, + 128, 71, 73, 71, 65, 128, 71, 73, 71, 128, 71, 73, 70, 212, 71, 73, 69, + 84, 128, 71, 73, 68, 73, 77, 128, 71, 73, 66, 66, 79, 85, 211, 71, 73, + 66, 65, 128, 71, 73, 52, 128, 71, 73, 180, 71, 72, 90, 128, 71, 72, 87, + 65, 128, 71, 72, 85, 78, 78, 65, 128, 71, 72, 85, 78, 78, 193, 71, 72, + 85, 128, 71, 72, 79, 85, 128, 71, 72, 79, 83, 84, 128, 71, 72, 79, 128, + 71, 72, 73, 77, 69, 76, 128, 71, 72, 73, 128, 71, 72, 72, 65, 128, 71, + 72, 69, 89, 83, 128, 71, 72, 69, 85, 88, 128, 71, 72, 69, 85, 78, 128, + 71, 72, 69, 85, 71, 72, 69, 85, 65, 69, 77, 128, 71, 72, 69, 85, 71, 72, + 69, 78, 128, 71, 72, 69, 85, 65, 69, 82, 65, 69, 128, 71, 72, 69, 85, 65, + 69, 71, 72, 69, 85, 65, 69, 128, 71, 72, 69, 84, 128, 71, 72, 69, 69, + 128, 71, 72, 69, 128, 71, 72, 197, 71, 72, 65, 89, 78, 128, 71, 72, 65, + 82, 65, 69, 128, 71, 72, 65, 80, 128, 71, 72, 65, 78, 128, 71, 72, 65, + 77, 77, 65, 128, 71, 72, 65, 77, 65, 76, 128, 71, 72, 65, 73, 78, 85, 128, 71, 72, 65, 73, 78, 128, 71, 72, 65, 73, 206, 71, 72, 65, 68, 128, 71, 72, 65, 65, 77, 65, 69, 128, 71, 72, 65, 65, 128, 71, 71, 87, 73, 128, 71, 71, 87, 69, 69, 128, 71, 71, 87, 69, 128, 71, 71, 87, 65, 65, @@ -4260,155 +4275,157 @@ static const unsigned char lexicon[] = { 128, 70, 86, 83, 50, 128, 70, 86, 83, 49, 128, 70, 85, 88, 128, 70, 85, 84, 128, 70, 85, 83, 69, 128, 70, 85, 83, 193, 70, 85, 82, 88, 128, 70, 85, 80, 128, 70, 85, 78, 69, 82, 65, 204, 70, 85, 78, 67, 84, 73, 79, 78, - 65, 204, 70, 85, 78, 67, 84, 73, 79, 78, 128, 70, 85, 76, 76, 78, 69, 83, - 83, 128, 70, 85, 76, 204, 70, 85, 74, 73, 128, 70, 85, 69, 84, 128, 70, - 85, 69, 204, 70, 85, 69, 128, 70, 85, 65, 128, 70, 84, 72, 79, 82, 193, - 70, 83, 73, 128, 70, 82, 79, 87, 78, 73, 78, 71, 128, 70, 82, 79, 87, 78, - 73, 78, 199, 70, 82, 79, 87, 78, 128, 70, 82, 79, 87, 206, 70, 82, 79, - 78, 84, 45, 84, 73, 76, 84, 69, 196, 70, 82, 79, 78, 84, 45, 70, 65, 67, - 73, 78, 199, 70, 82, 79, 78, 212, 70, 82, 79, 205, 70, 82, 79, 71, 128, - 70, 82, 79, 199, 70, 82, 73, 84, 85, 128, 70, 82, 73, 69, 83, 128, 70, - 82, 73, 69, 196, 70, 82, 73, 67, 65, 84, 73, 86, 69, 128, 70, 82, 69, 84, - 66, 79, 65, 82, 68, 128, 70, 82, 69, 78, 67, 200, 70, 82, 69, 69, 90, 73, - 78, 199, 70, 82, 69, 69, 128, 70, 82, 69, 197, 70, 82, 65, 78, 75, 211, - 70, 82, 65, 78, 195, 70, 82, 65, 77, 69, 83, 128, 70, 82, 65, 77, 69, - 128, 70, 82, 65, 77, 197, 70, 82, 65, 75, 84, 85, 210, 70, 82, 65, 71, - 82, 65, 78, 84, 128, 70, 82, 65, 71, 77, 69, 78, 84, 128, 70, 82, 65, 67, - 84, 73, 79, 206, 70, 79, 88, 128, 70, 79, 216, 70, 79, 85, 82, 84, 69, - 69, 78, 128, 70, 79, 85, 82, 84, 69, 69, 206, 70, 79, 85, 82, 45, 84, 72, - 73, 82, 84, 89, 128, 70, 79, 85, 82, 45, 83, 84, 82, 73, 78, 199, 70, 79, - 85, 82, 45, 80, 69, 82, 45, 69, 205, 70, 79, 85, 82, 45, 76, 73, 78, 197, - 70, 79, 85, 210, 70, 79, 85, 78, 84, 65, 73, 78, 128, 70, 79, 85, 78, 84, - 65, 73, 206, 70, 79, 83, 84, 69, 82, 73, 78, 71, 128, 70, 79, 82, 87, 65, - 82, 68, 128, 70, 79, 82, 87, 65, 82, 196, 70, 79, 82, 84, 89, 45, 70, 73, - 86, 197, 70, 79, 82, 84, 89, 128, 70, 79, 82, 84, 217, 70, 79, 82, 84, - 85, 78, 197, 70, 79, 82, 84, 73, 69, 84, 72, 128, 70, 79, 82, 84, 69, - 128, 70, 79, 82, 77, 211, 70, 79, 82, 77, 69, 69, 128, 70, 79, 82, 77, - 69, 197, 70, 79, 82, 77, 65, 84, 84, 73, 78, 71, 128, 70, 79, 82, 77, 65, - 212, 70, 79, 82, 75, 69, 196, 70, 79, 82, 69, 72, 69, 65, 196, 70, 79, - 82, 67, 69, 83, 128, 70, 79, 82, 67, 69, 128, 70, 79, 80, 128, 70, 79, - 79, 84, 83, 84, 79, 79, 76, 128, 70, 79, 79, 84, 80, 82, 73, 78, 84, 83, - 128, 70, 79, 79, 84, 78, 79, 84, 197, 70, 79, 79, 84, 66, 65, 76, 76, + 65, 204, 70, 85, 78, 67, 84, 73, 79, 78, 128, 70, 85, 76, 76, 87, 73, 68, + 84, 200, 70, 85, 76, 76, 78, 69, 83, 83, 128, 70, 85, 76, 204, 70, 85, + 74, 73, 128, 70, 85, 69, 84, 128, 70, 85, 69, 204, 70, 85, 69, 128, 70, + 85, 65, 128, 70, 84, 72, 79, 82, 193, 70, 83, 73, 128, 70, 82, 79, 87, + 78, 73, 78, 71, 128, 70, 82, 79, 87, 78, 73, 78, 199, 70, 82, 79, 87, 78, + 128, 70, 82, 79, 87, 206, 70, 82, 79, 78, 84, 45, 84, 73, 76, 84, 69, + 196, 70, 82, 79, 78, 84, 45, 70, 65, 67, 73, 78, 199, 70, 82, 79, 78, + 212, 70, 82, 79, 205, 70, 82, 79, 71, 128, 70, 82, 79, 199, 70, 82, 73, + 84, 85, 128, 70, 82, 73, 69, 83, 128, 70, 82, 73, 69, 196, 70, 82, 73, + 67, 65, 84, 73, 86, 69, 128, 70, 82, 69, 84, 66, 79, 65, 82, 68, 128, 70, + 82, 69, 78, 67, 200, 70, 82, 69, 69, 90, 73, 78, 199, 70, 82, 69, 69, + 128, 70, 82, 69, 197, 70, 82, 65, 78, 75, 211, 70, 82, 65, 78, 195, 70, + 82, 65, 77, 69, 83, 128, 70, 82, 65, 77, 69, 128, 70, 82, 65, 77, 197, + 70, 82, 65, 75, 84, 85, 210, 70, 82, 65, 71, 82, 65, 78, 84, 128, 70, 82, + 65, 71, 77, 69, 78, 84, 128, 70, 82, 65, 67, 84, 73, 79, 206, 70, 79, 88, + 128, 70, 79, 216, 70, 79, 85, 82, 84, 69, 69, 78, 128, 70, 79, 85, 82, + 84, 69, 69, 206, 70, 79, 85, 82, 45, 84, 72, 73, 82, 84, 89, 128, 70, 79, + 85, 82, 45, 83, 84, 82, 73, 78, 199, 70, 79, 85, 82, 45, 80, 69, 82, 45, + 69, 205, 70, 79, 85, 82, 45, 76, 73, 78, 197, 70, 79, 85, 210, 70, 79, + 85, 78, 84, 65, 73, 78, 128, 70, 79, 85, 78, 84, 65, 73, 206, 70, 79, 83, + 84, 69, 82, 73, 78, 71, 128, 70, 79, 82, 87, 65, 82, 68, 128, 70, 79, 82, + 87, 65, 82, 196, 70, 79, 82, 84, 89, 45, 70, 73, 86, 197, 70, 79, 82, 84, + 89, 128, 70, 79, 82, 84, 217, 70, 79, 82, 84, 85, 78, 69, 128, 70, 79, + 82, 84, 85, 78, 197, 70, 79, 82, 84, 73, 69, 84, 72, 128, 70, 79, 82, 84, + 69, 128, 70, 79, 82, 77, 211, 70, 79, 82, 77, 69, 69, 128, 70, 79, 82, + 77, 69, 197, 70, 79, 82, 77, 65, 84, 84, 73, 78, 71, 128, 70, 79, 82, 77, + 65, 212, 70, 79, 82, 75, 69, 196, 70, 79, 82, 69, 72, 69, 65, 196, 70, + 79, 82, 67, 69, 83, 128, 70, 79, 82, 67, 69, 128, 70, 79, 80, 128, 70, + 79, 79, 84, 83, 84, 79, 79, 76, 128, 70, 79, 79, 84, 80, 82, 73, 78, 84, + 83, 128, 70, 79, 79, 84, 78, 79, 84, 197, 70, 79, 79, 84, 66, 65, 76, 76, 128, 70, 79, 79, 84, 128, 70, 79, 79, 76, 128, 70, 79, 79, 68, 128, 70, 79, 79, 128, 70, 79, 78, 212, 70, 79, 78, 71, 77, 65, 78, 128, 70, 79, 78, 68, 85, 69, 128, 70, 79, 77, 128, 70, 79, 76, 76, 89, 128, 70, 79, - 76, 76, 79, 87, 73, 78, 71, 128, 70, 79, 76, 68, 69, 82, 128, 70, 79, 76, - 68, 69, 196, 70, 79, 71, 71, 89, 128, 70, 79, 71, 128, 70, 207, 70, 77, - 128, 70, 76, 89, 73, 78, 199, 70, 76, 89, 128, 70, 76, 85, 84, 84, 69, - 82, 73, 78, 71, 128, 70, 76, 85, 84, 84, 69, 82, 73, 78, 199, 70, 76, 85, - 84, 69, 128, 70, 76, 85, 83, 72, 69, 196, 70, 76, 79, 87, 73, 78, 199, - 70, 76, 79, 87, 69, 82, 83, 128, 70, 76, 79, 87, 69, 210, 70, 76, 79, 85, - 82, 73, 83, 72, 128, 70, 76, 79, 82, 69, 84, 84, 69, 128, 70, 76, 79, 82, - 65, 204, 70, 76, 79, 80, 80, 217, 70, 76, 79, 79, 82, 128, 70, 76, 79, - 79, 210, 70, 76, 73, 80, 128, 70, 76, 73, 71, 72, 84, 128, 70, 76, 73, - 67, 203, 70, 76, 69, 88, 85, 83, 128, 70, 76, 69, 88, 69, 196, 70, 76, - 69, 88, 128, 70, 76, 69, 85, 82, 79, 78, 128, 70, 76, 69, 85, 82, 45, 68, - 69, 45, 76, 73, 83, 128, 70, 76, 65, 84, 84, 69, 78, 69, 196, 70, 76, 65, - 84, 78, 69, 83, 83, 128, 70, 76, 65, 84, 66, 82, 69, 65, 68, 128, 70, 76, - 65, 83, 72, 128, 70, 76, 65, 77, 73, 78, 71, 79, 128, 70, 76, 65, 77, 69, - 128, 70, 76, 65, 71, 83, 128, 70, 76, 65, 71, 45, 53, 128, 70, 76, 65, - 71, 45, 52, 128, 70, 76, 65, 71, 45, 51, 128, 70, 76, 65, 71, 45, 50, - 128, 70, 76, 65, 71, 45, 49, 128, 70, 76, 65, 71, 128, 70, 76, 65, 199, - 70, 76, 65, 128, 70, 76, 128, 70, 73, 88, 69, 68, 45, 70, 79, 82, 205, - 70, 73, 88, 128, 70, 73, 86, 69, 45, 84, 72, 73, 82, 84, 89, 128, 70, 73, - 86, 69, 45, 76, 73, 78, 197, 70, 73, 84, 90, 80, 65, 84, 82, 73, 67, 203, - 70, 73, 84, 65, 128, 70, 73, 84, 128, 70, 73, 83, 84, 69, 196, 70, 73, - 83, 72, 73, 78, 199, 70, 73, 83, 72, 72, 79, 79, 75, 128, 70, 73, 83, 72, - 72, 79, 79, 203, 70, 73, 83, 72, 69, 89, 69, 128, 70, 73, 83, 72, 128, - 70, 73, 83, 200, 70, 73, 82, 83, 212, 70, 73, 82, 73, 128, 70, 73, 82, - 69, 87, 79, 82, 75, 83, 128, 70, 73, 82, 69, 87, 79, 82, 203, 70, 73, 82, - 69, 67, 82, 65, 67, 75, 69, 82, 128, 70, 73, 82, 69, 128, 70, 73, 82, - 197, 70, 73, 80, 128, 70, 73, 78, 73, 84, 197, 70, 73, 78, 71, 69, 82, - 83, 128, 70, 73, 78, 71, 69, 82, 211, 70, 73, 78, 71, 69, 82, 78, 65, 73, - 76, 83, 128, 70, 73, 78, 71, 69, 82, 69, 196, 70, 73, 78, 71, 69, 82, 45, - 80, 79, 83, 212, 70, 73, 78, 71, 69, 82, 128, 70, 73, 78, 71, 69, 210, - 70, 73, 78, 65, 78, 67, 73, 65, 76, 128, 70, 73, 78, 65, 76, 128, 70, 73, - 76, 205, 70, 73, 76, 76, 69, 82, 45, 50, 128, 70, 73, 76, 76, 69, 82, 45, - 49, 128, 70, 73, 76, 76, 69, 82, 128, 70, 73, 76, 76, 69, 196, 70, 73, - 76, 76, 128, 70, 73, 76, 204, 70, 73, 76, 197, 70, 73, 73, 128, 70, 73, - 71, 85, 82, 69, 45, 51, 128, 70, 73, 71, 85, 82, 69, 45, 50, 128, 70, 73, - 71, 85, 82, 69, 45, 49, 128, 70, 73, 71, 85, 82, 69, 128, 70, 73, 71, 85, - 82, 197, 70, 73, 71, 72, 84, 128, 70, 73, 70, 84, 89, 128, 70, 73, 70, - 84, 217, 70, 73, 70, 84, 72, 83, 128, 70, 73, 70, 84, 72, 128, 70, 73, - 70, 84, 69, 69, 78, 128, 70, 73, 70, 84, 69, 69, 206, 70, 73, 69, 76, 68, - 128, 70, 73, 69, 76, 196, 70, 72, 84, 79, 82, 193, 70, 70, 76, 128, 70, - 70, 73, 128, 70, 69, 85, 88, 128, 70, 69, 85, 70, 69, 85, 65, 69, 84, - 128, 70, 69, 84, 72, 128, 70, 69, 83, 84, 73, 86, 65, 76, 128, 70, 69, - 82, 82, 89, 128, 70, 69, 82, 82, 73, 211, 70, 69, 82, 77, 65, 84, 65, - 128, 70, 69, 82, 77, 65, 84, 193, 70, 69, 79, 200, 70, 69, 78, 199, 70, - 69, 78, 67, 69, 82, 128, 70, 69, 78, 67, 69, 128, 70, 69, 77, 73, 78, 73, - 78, 197, 70, 69, 77, 65, 76, 69, 128, 70, 69, 77, 65, 76, 197, 70, 69, - 76, 76, 79, 87, 83, 72, 73, 80, 128, 70, 69, 73, 128, 70, 69, 72, 213, - 70, 69, 72, 128, 70, 69, 200, 70, 69, 69, 78, 71, 128, 70, 69, 69, 77, - 128, 70, 69, 69, 68, 128, 70, 69, 69, 196, 70, 69, 69, 128, 70, 69, 66, - 82, 85, 65, 82, 89, 128, 70, 69, 65, 84, 72, 69, 82, 128, 70, 69, 65, 84, - 72, 69, 210, 70, 69, 65, 82, 78, 128, 70, 69, 65, 82, 70, 85, 204, 70, - 69, 65, 82, 128, 70, 65, 89, 65, 78, 78, 65, 128, 70, 65, 89, 128, 70, - 65, 88, 128, 70, 65, 216, 70, 65, 84, 73, 71, 85, 69, 128, 70, 65, 84, - 72, 69, 82, 128, 70, 65, 84, 72, 69, 210, 70, 65, 84, 72, 65, 84, 65, 78, - 128, 70, 65, 84, 72, 65, 84, 65, 206, 70, 65, 84, 72, 65, 128, 70, 65, - 84, 72, 193, 70, 65, 84, 128, 70, 65, 83, 84, 128, 70, 65, 82, 83, 201, - 70, 65, 82, 128, 70, 65, 81, 128, 70, 65, 80, 128, 70, 65, 78, 71, 128, - 70, 65, 78, 69, 82, 79, 83, 73, 211, 70, 65, 78, 128, 70, 65, 77, 73, 76, - 89, 128, 70, 65, 77, 128, 70, 65, 76, 76, 69, 206, 70, 65, 76, 65, 70, - 69, 76, 128, 70, 65, 74, 128, 70, 65, 73, 82, 89, 128, 70, 65, 73, 76, - 85, 82, 69, 128, 70, 65, 73, 72, 85, 128, 70, 65, 73, 66, 128, 70, 65, - 72, 82, 69, 78, 72, 69, 73, 84, 128, 70, 65, 67, 84, 79, 82, 89, 128, 70, - 65, 67, 84, 79, 210, 70, 65, 67, 83, 73, 77, 73, 76, 197, 70, 65, 67, 73, - 78, 71, 83, 128, 70, 65, 67, 69, 45, 54, 128, 70, 65, 67, 69, 45, 53, - 128, 70, 65, 67, 69, 45, 52, 128, 70, 65, 67, 69, 45, 51, 128, 70, 65, - 67, 69, 45, 50, 128, 70, 65, 67, 69, 45, 49, 128, 70, 65, 65, 77, 65, 69, - 128, 70, 65, 65, 73, 128, 70, 65, 65, 70, 85, 128, 70, 48, 53, 51, 128, - 70, 48, 53, 50, 128, 70, 48, 53, 49, 67, 128, 70, 48, 53, 49, 66, 128, - 70, 48, 53, 49, 65, 128, 70, 48, 53, 49, 128, 70, 48, 53, 48, 128, 70, - 48, 52, 57, 128, 70, 48, 52, 56, 128, 70, 48, 52, 55, 65, 128, 70, 48, - 52, 55, 128, 70, 48, 52, 54, 65, 128, 70, 48, 52, 54, 128, 70, 48, 52, - 53, 65, 128, 70, 48, 52, 53, 128, 70, 48, 52, 52, 128, 70, 48, 52, 51, - 128, 70, 48, 52, 50, 128, 70, 48, 52, 49, 128, 70, 48, 52, 48, 128, 70, - 48, 51, 57, 128, 70, 48, 51, 56, 65, 128, 70, 48, 51, 56, 128, 70, 48, - 51, 55, 65, 128, 70, 48, 51, 55, 128, 70, 48, 51, 54, 128, 70, 48, 51, - 53, 128, 70, 48, 51, 52, 128, 70, 48, 51, 51, 128, 70, 48, 51, 50, 128, - 70, 48, 51, 49, 65, 128, 70, 48, 51, 49, 128, 70, 48, 51, 48, 128, 70, - 48, 50, 57, 128, 70, 48, 50, 56, 128, 70, 48, 50, 55, 128, 70, 48, 50, - 54, 128, 70, 48, 50, 53, 128, 70, 48, 50, 52, 128, 70, 48, 50, 51, 128, - 70, 48, 50, 50, 128, 70, 48, 50, 49, 65, 128, 70, 48, 50, 49, 128, 70, - 48, 50, 48, 128, 70, 48, 49, 57, 128, 70, 48, 49, 56, 128, 70, 48, 49, - 55, 128, 70, 48, 49, 54, 128, 70, 48, 49, 53, 128, 70, 48, 49, 52, 128, - 70, 48, 49, 51, 65, 128, 70, 48, 49, 51, 128, 70, 48, 49, 50, 128, 70, - 48, 49, 49, 128, 70, 48, 49, 48, 128, 70, 48, 48, 57, 128, 70, 48, 48, - 56, 128, 70, 48, 48, 55, 128, 70, 48, 48, 54, 128, 70, 48, 48, 53, 128, - 70, 48, 48, 52, 128, 70, 48, 48, 51, 128, 70, 48, 48, 50, 128, 70, 48, - 48, 49, 65, 128, 70, 48, 48, 49, 128, 69, 90, 83, 128, 69, 90, 69, 78, - 128, 69, 90, 69, 206, 69, 89, 89, 89, 128, 69, 89, 69, 83, 128, 69, 89, - 69, 211, 69, 89, 69, 76, 65, 83, 72, 69, 211, 69, 89, 69, 71, 76, 65, 83, - 83, 69, 83, 128, 69, 89, 69, 71, 65, 90, 69, 45, 87, 65, 76, 76, 80, 76, - 65, 78, 197, 69, 89, 69, 71, 65, 90, 69, 45, 70, 76, 79, 79, 82, 80, 76, - 65, 78, 197, 69, 89, 69, 66, 82, 79, 87, 211, 69, 89, 69, 66, 82, 79, - 215, 69, 89, 197, 69, 89, 66, 69, 89, 70, 73, 76, 73, 128, 69, 89, 65, - 78, 78, 65, 128, 69, 88, 84, 82, 69, 77, 69, 76, 217, 69, 88, 84, 82, 65, - 84, 69, 82, 82, 69, 83, 84, 82, 73, 65, 204, 69, 88, 84, 82, 65, 45, 76, - 79, 215, 69, 88, 84, 82, 65, 45, 72, 73, 71, 200, 69, 88, 84, 82, 193, - 69, 88, 84, 73, 78, 71, 85, 73, 83, 72, 69, 82, 128, 69, 88, 84, 69, 78, - 83, 73, 79, 78, 128, 69, 88, 84, 69, 78, 68, 69, 68, 128, 69, 88, 84, 69, - 78, 68, 69, 196, 69, 88, 80, 82, 69, 83, 83, 73, 79, 78, 76, 69, 83, 211, - 69, 88, 80, 79, 78, 69, 78, 212, 69, 88, 80, 76, 79, 68, 73, 78, 199, 69, - 88, 79, 128, 69, 88, 207, 69, 88, 73, 83, 84, 83, 128, 69, 88, 73, 83, - 84, 128, 69, 88, 72, 65, 85, 83, 84, 73, 79, 78, 128, 69, 88, 72, 65, 76, - 69, 128, 69, 88, 67, 76, 65, 77, 65, 84, 73, 79, 78, 128, 69, 88, 67, 76, - 65, 77, 65, 84, 73, 79, 206, 69, 88, 67, 73, 84, 69, 77, 69, 78, 84, 128, - 69, 88, 67, 72, 65, 78, 71, 69, 128, 69, 88, 67, 69, 83, 83, 128, 69, 88, - 67, 69, 76, 76, 69, 78, 84, 128, 69, 87, 69, 128, 69, 86, 69, 82, 217, - 69, 86, 69, 82, 71, 82, 69, 69, 206, 69, 86, 69, 78, 73, 78, 71, 128, 69, - 85, 82, 79, 80, 69, 65, 206, 69, 85, 82, 79, 80, 69, 45, 65, 70, 82, 73, - 67, 65, 128, 69, 85, 82, 79, 45, 67, 85, 82, 82, 69, 78, 67, 217, 69, 85, - 82, 207, 69, 85, 76, 69, 210, 69, 85, 45, 85, 128, 69, 85, 45, 79, 128, - 69, 85, 45, 69, 85, 128, 69, 85, 45, 69, 79, 128, 69, 85, 45, 69, 128, - 69, 85, 45, 65, 128, 69, 84, 88, 128, 69, 84, 78, 65, 72, 84, 65, 128, - 69, 84, 72, 69, 204, 69, 84, 69, 82, 79, 206, 69, 84, 69, 82, 78, 73, 84, - 89, 128, 69, 84, 69, 82, 78, 73, 84, 217, 69, 84, 66, 128, 69, 83, 90, - 128, 69, 83, 85, 75, 85, 85, 68, 79, 128, 69, 83, 84, 73, 77, 65, 84, 69, - 83, 128, 69, 83, 84, 73, 77, 65, 84, 69, 196, 69, 83, 72, 69, 51, 128, - 69, 83, 72, 50, 49, 128, 69, 83, 72, 49, 54, 128, 69, 83, 67, 65, 80, 69, + 76, 76, 79, 87, 73, 78, 71, 128, 70, 79, 76, 68, 73, 78, 199, 70, 79, 76, + 68, 69, 82, 128, 70, 79, 76, 68, 69, 196, 70, 79, 71, 71, 89, 128, 70, + 79, 71, 128, 70, 207, 70, 77, 128, 70, 76, 89, 73, 78, 199, 70, 76, 89, + 128, 70, 76, 85, 84, 84, 69, 82, 73, 78, 71, 128, 70, 76, 85, 84, 84, 69, + 82, 73, 78, 199, 70, 76, 85, 84, 69, 128, 70, 76, 85, 83, 72, 69, 196, + 70, 76, 79, 87, 73, 78, 199, 70, 76, 79, 87, 69, 82, 83, 128, 70, 76, 79, + 87, 69, 210, 70, 76, 79, 85, 82, 73, 83, 72, 128, 70, 76, 79, 82, 69, 84, + 84, 69, 128, 70, 76, 79, 82, 65, 204, 70, 76, 79, 80, 80, 217, 70, 76, + 79, 79, 82, 128, 70, 76, 79, 79, 210, 70, 76, 73, 80, 128, 70, 76, 73, + 71, 72, 84, 128, 70, 76, 73, 67, 203, 70, 76, 69, 88, 85, 83, 128, 70, + 76, 69, 88, 69, 196, 70, 76, 69, 88, 128, 70, 76, 69, 85, 82, 79, 78, + 128, 70, 76, 69, 85, 82, 45, 68, 69, 45, 76, 73, 83, 128, 70, 76, 65, 84, + 84, 69, 78, 69, 196, 70, 76, 65, 84, 78, 69, 83, 83, 128, 70, 76, 65, 84, + 66, 82, 69, 65, 68, 128, 70, 76, 65, 83, 72, 128, 70, 76, 65, 77, 73, 78, + 71, 79, 128, 70, 76, 65, 77, 69, 128, 70, 76, 65, 71, 83, 128, 70, 76, + 65, 71, 45, 53, 128, 70, 76, 65, 71, 45, 52, 128, 70, 76, 65, 71, 45, 51, + 128, 70, 76, 65, 71, 45, 50, 128, 70, 76, 65, 71, 45, 49, 128, 70, 76, + 65, 71, 128, 70, 76, 65, 199, 70, 76, 65, 128, 70, 76, 128, 70, 73, 88, + 69, 68, 45, 70, 79, 82, 205, 70, 73, 88, 128, 70, 73, 86, 69, 45, 84, 72, + 73, 82, 84, 89, 128, 70, 73, 86, 69, 45, 76, 73, 78, 197, 70, 73, 86, 69, + 45, 76, 73, 75, 197, 70, 73, 84, 90, 80, 65, 84, 82, 73, 67, 203, 70, 73, + 84, 65, 128, 70, 73, 84, 128, 70, 73, 83, 84, 69, 196, 70, 73, 83, 72, + 73, 78, 199, 70, 73, 83, 72, 72, 79, 79, 75, 128, 70, 73, 83, 72, 72, 79, + 79, 203, 70, 73, 83, 72, 69, 89, 69, 128, 70, 73, 83, 200, 70, 73, 82, + 83, 212, 70, 73, 82, 73, 128, 70, 73, 82, 69, 87, 79, 82, 75, 83, 128, + 70, 73, 82, 69, 87, 79, 82, 203, 70, 73, 82, 69, 67, 82, 65, 67, 75, 69, + 82, 128, 70, 73, 82, 69, 128, 70, 73, 82, 197, 70, 73, 80, 128, 70, 73, + 78, 73, 84, 197, 70, 73, 78, 71, 69, 82, 83, 128, 70, 73, 78, 71, 69, 82, + 211, 70, 73, 78, 71, 69, 82, 78, 65, 73, 76, 83, 128, 70, 73, 78, 71, 69, + 82, 69, 196, 70, 73, 78, 71, 69, 82, 45, 80, 79, 83, 212, 70, 73, 78, 71, + 69, 82, 128, 70, 73, 78, 71, 69, 210, 70, 73, 78, 65, 78, 67, 73, 65, 76, + 128, 70, 73, 78, 65, 76, 128, 70, 73, 76, 205, 70, 73, 76, 76, 69, 82, + 45, 50, 128, 70, 73, 76, 76, 69, 82, 45, 49, 128, 70, 73, 76, 76, 69, 82, + 128, 70, 73, 76, 76, 69, 196, 70, 73, 76, 76, 128, 70, 73, 76, 204, 70, + 73, 76, 197, 70, 73, 73, 128, 70, 73, 71, 85, 82, 69, 45, 51, 128, 70, + 73, 71, 85, 82, 69, 45, 50, 128, 70, 73, 71, 85, 82, 69, 45, 49, 128, 70, + 73, 71, 85, 82, 69, 128, 70, 73, 71, 85, 82, 197, 70, 73, 71, 72, 84, + 128, 70, 73, 70, 84, 89, 128, 70, 73, 70, 84, 217, 70, 73, 70, 84, 72, + 83, 128, 70, 73, 70, 84, 72, 128, 70, 73, 70, 84, 69, 69, 78, 128, 70, + 73, 70, 84, 69, 69, 206, 70, 73, 69, 76, 68, 128, 70, 73, 69, 76, 196, + 70, 72, 84, 79, 82, 193, 70, 70, 76, 128, 70, 70, 73, 128, 70, 69, 85, + 88, 128, 70, 69, 85, 70, 69, 85, 65, 69, 84, 128, 70, 69, 84, 72, 128, + 70, 69, 83, 84, 73, 86, 65, 76, 128, 70, 69, 82, 82, 89, 128, 70, 69, 82, + 82, 73, 211, 70, 69, 82, 77, 65, 84, 65, 128, 70, 69, 82, 77, 65, 84, + 193, 70, 69, 79, 200, 70, 69, 78, 199, 70, 69, 78, 67, 69, 82, 128, 70, + 69, 78, 67, 69, 128, 70, 69, 77, 73, 78, 73, 78, 197, 70, 69, 77, 65, 76, + 69, 128, 70, 69, 77, 65, 76, 197, 70, 69, 76, 76, 79, 87, 83, 72, 73, 80, + 128, 70, 69, 73, 128, 70, 69, 72, 213, 70, 69, 72, 128, 70, 69, 200, 70, + 69, 69, 78, 71, 128, 70, 69, 69, 77, 128, 70, 69, 69, 68, 128, 70, 69, + 69, 196, 70, 69, 69, 128, 70, 69, 66, 82, 85, 65, 82, 89, 128, 70, 69, + 65, 84, 72, 69, 82, 128, 70, 69, 65, 84, 72, 69, 210, 70, 69, 65, 82, 78, + 128, 70, 69, 65, 82, 70, 85, 204, 70, 69, 65, 82, 128, 70, 65, 89, 65, + 78, 78, 65, 128, 70, 65, 89, 128, 70, 65, 88, 128, 70, 65, 216, 70, 65, + 84, 73, 71, 85, 69, 128, 70, 65, 84, 72, 69, 82, 128, 70, 65, 84, 72, 69, + 210, 70, 65, 84, 72, 65, 84, 65, 78, 128, 70, 65, 84, 72, 65, 84, 65, + 206, 70, 65, 84, 72, 65, 128, 70, 65, 84, 72, 193, 70, 65, 84, 128, 70, + 65, 83, 84, 128, 70, 65, 82, 83, 201, 70, 65, 82, 128, 70, 65, 81, 128, + 70, 65, 80, 128, 70, 65, 78, 71, 128, 70, 65, 78, 69, 82, 79, 83, 73, + 211, 70, 65, 78, 128, 70, 65, 77, 73, 76, 89, 128, 70, 65, 77, 128, 70, + 65, 76, 76, 69, 206, 70, 65, 76, 65, 70, 69, 76, 128, 70, 65, 74, 128, + 70, 65, 73, 82, 89, 128, 70, 65, 73, 76, 85, 82, 69, 128, 70, 65, 73, 72, + 85, 128, 70, 65, 73, 66, 128, 70, 65, 72, 82, 69, 78, 72, 69, 73, 84, + 128, 70, 65, 67, 84, 79, 82, 89, 128, 70, 65, 67, 84, 79, 210, 70, 65, + 67, 83, 73, 77, 73, 76, 197, 70, 65, 67, 73, 78, 71, 83, 128, 70, 65, 67, + 69, 45, 54, 128, 70, 65, 67, 69, 45, 53, 128, 70, 65, 67, 69, 45, 52, + 128, 70, 65, 67, 69, 45, 51, 128, 70, 65, 67, 69, 45, 50, 128, 70, 65, + 67, 69, 45, 49, 128, 70, 65, 65, 77, 65, 69, 128, 70, 65, 65, 73, 128, + 70, 65, 65, 70, 85, 128, 70, 48, 53, 51, 128, 70, 48, 53, 50, 128, 70, + 48, 53, 49, 67, 128, 70, 48, 53, 49, 66, 128, 70, 48, 53, 49, 65, 128, + 70, 48, 53, 49, 128, 70, 48, 53, 48, 128, 70, 48, 52, 57, 128, 70, 48, + 52, 56, 128, 70, 48, 52, 55, 65, 128, 70, 48, 52, 55, 128, 70, 48, 52, + 54, 65, 128, 70, 48, 52, 54, 128, 70, 48, 52, 53, 65, 128, 70, 48, 52, + 53, 128, 70, 48, 52, 52, 128, 70, 48, 52, 51, 128, 70, 48, 52, 50, 128, + 70, 48, 52, 49, 128, 70, 48, 52, 48, 128, 70, 48, 51, 57, 128, 70, 48, + 51, 56, 65, 128, 70, 48, 51, 56, 128, 70, 48, 51, 55, 65, 128, 70, 48, + 51, 55, 128, 70, 48, 51, 54, 128, 70, 48, 51, 53, 128, 70, 48, 51, 52, + 128, 70, 48, 51, 51, 128, 70, 48, 51, 50, 128, 70, 48, 51, 49, 65, 128, + 70, 48, 51, 49, 128, 70, 48, 51, 48, 128, 70, 48, 50, 57, 128, 70, 48, + 50, 56, 128, 70, 48, 50, 55, 128, 70, 48, 50, 54, 128, 70, 48, 50, 53, + 128, 70, 48, 50, 52, 128, 70, 48, 50, 51, 128, 70, 48, 50, 50, 128, 70, + 48, 50, 49, 65, 128, 70, 48, 50, 49, 128, 70, 48, 50, 48, 128, 70, 48, + 49, 57, 128, 70, 48, 49, 56, 128, 70, 48, 49, 55, 128, 70, 48, 49, 54, + 128, 70, 48, 49, 53, 128, 70, 48, 49, 52, 128, 70, 48, 49, 51, 65, 128, + 70, 48, 49, 51, 128, 70, 48, 49, 50, 128, 70, 48, 49, 49, 128, 70, 48, + 49, 48, 128, 70, 48, 48, 57, 128, 70, 48, 48, 56, 128, 70, 48, 48, 55, + 128, 70, 48, 48, 54, 128, 70, 48, 48, 53, 128, 70, 48, 48, 52, 128, 70, + 48, 48, 51, 128, 70, 48, 48, 50, 128, 70, 48, 48, 49, 65, 128, 70, 48, + 48, 49, 128, 69, 90, 83, 128, 69, 90, 69, 78, 128, 69, 90, 69, 206, 69, + 89, 89, 89, 128, 69, 89, 69, 83, 128, 69, 89, 69, 211, 69, 89, 69, 76, + 65, 83, 72, 69, 211, 69, 89, 69, 71, 76, 65, 83, 83, 69, 83, 128, 69, 89, + 69, 71, 65, 90, 69, 45, 87, 65, 76, 76, 80, 76, 65, 78, 197, 69, 89, 69, + 71, 65, 90, 69, 45, 70, 76, 79, 79, 82, 80, 76, 65, 78, 197, 69, 89, 69, + 66, 82, 79, 87, 211, 69, 89, 69, 66, 82, 79, 215, 69, 89, 197, 69, 89, + 66, 69, 89, 70, 73, 76, 73, 128, 69, 89, 65, 78, 78, 65, 128, 69, 88, 84, + 82, 69, 77, 69, 76, 217, 69, 88, 84, 82, 65, 84, 69, 82, 82, 69, 83, 84, + 82, 73, 65, 204, 69, 88, 84, 82, 65, 45, 76, 79, 215, 69, 88, 84, 82, 65, + 45, 72, 73, 71, 200, 69, 88, 84, 82, 193, 69, 88, 84, 73, 78, 71, 85, 73, + 83, 72, 69, 82, 128, 69, 88, 84, 69, 78, 83, 73, 79, 78, 128, 69, 88, 84, + 69, 78, 68, 69, 68, 128, 69, 88, 84, 69, 78, 68, 69, 196, 69, 88, 80, 82, + 69, 83, 83, 73, 79, 78, 76, 69, 83, 211, 69, 88, 80, 79, 78, 69, 78, 212, + 69, 88, 80, 76, 79, 68, 73, 78, 199, 69, 88, 79, 128, 69, 88, 207, 69, + 88, 73, 83, 84, 83, 128, 69, 88, 73, 83, 84, 128, 69, 88, 72, 65, 85, 83, + 84, 73, 79, 78, 128, 69, 88, 72, 65, 76, 69, 128, 69, 88, 67, 76, 65, 77, + 65, 84, 73, 79, 78, 128, 69, 88, 67, 76, 65, 77, 65, 84, 73, 79, 206, 69, + 88, 67, 73, 84, 69, 77, 69, 78, 84, 128, 69, 88, 67, 72, 65, 78, 71, 69, + 128, 69, 88, 67, 69, 83, 83, 128, 69, 88, 67, 69, 76, 76, 69, 78, 84, + 128, 69, 87, 69, 128, 69, 86, 69, 82, 217, 69, 86, 69, 82, 71, 82, 69, + 69, 206, 69, 86, 69, 78, 73, 78, 71, 128, 69, 85, 82, 79, 80, 69, 65, + 206, 69, 85, 82, 79, 80, 69, 45, 65, 70, 82, 73, 67, 65, 128, 69, 85, 82, + 79, 45, 67, 85, 82, 82, 69, 78, 67, 217, 69, 85, 82, 207, 69, 85, 76, 69, + 210, 69, 85, 45, 85, 128, 69, 85, 45, 79, 128, 69, 85, 45, 69, 85, 128, + 69, 85, 45, 69, 79, 128, 69, 85, 45, 69, 128, 69, 85, 45, 65, 128, 69, + 84, 88, 128, 69, 84, 84, 128, 69, 84, 78, 65, 72, 84, 65, 128, 69, 84, + 72, 69, 204, 69, 84, 69, 82, 79, 206, 69, 84, 69, 82, 78, 73, 84, 89, + 128, 69, 84, 69, 82, 78, 73, 84, 217, 69, 84, 66, 128, 69, 83, 90, 128, + 69, 83, 85, 75, 85, 85, 68, 79, 128, 69, 83, 84, 73, 77, 65, 84, 69, 83, + 128, 69, 83, 84, 73, 77, 65, 84, 69, 196, 69, 83, 72, 69, 51, 128, 69, + 83, 72, 50, 49, 128, 69, 83, 72, 49, 54, 128, 69, 83, 67, 65, 80, 69, 128, 69, 83, 67, 128, 69, 83, 65, 128, 69, 83, 45, 84, 69, 128, 69, 83, 45, 51, 128, 69, 83, 45, 50, 128, 69, 83, 45, 49, 128, 69, 82, 82, 79, 82, 45, 66, 65, 82, 82, 69, 196, 69, 82, 82, 128, 69, 82, 73, 211, 69, @@ -4464,101 +4481,102 @@ static const unsigned char lexicon[] = { 89, 128, 69, 71, 73, 82, 128, 69, 71, 71, 83, 128, 69, 71, 71, 128, 69, 69, 89, 65, 78, 78, 65, 128, 69, 69, 75, 65, 65, 128, 69, 69, 72, 128, 69, 69, 66, 69, 69, 70, 73, 76, 73, 128, 69, 68, 73, 84, 79, 82, 73, 65, - 204, 69, 68, 73, 78, 128, 69, 68, 68, 128, 69, 67, 83, 128, 69, 66, 69, - 70, 73, 76, 73, 128, 69, 65, 83, 84, 69, 82, 206, 69, 65, 83, 84, 128, - 69, 65, 83, 212, 69, 65, 82, 84, 72, 76, 217, 69, 65, 82, 84, 72, 128, - 69, 65, 82, 84, 200, 69, 65, 82, 76, 217, 69, 65, 77, 72, 65, 78, 67, 72, - 79, 76, 76, 128, 69, 65, 71, 76, 69, 128, 69, 65, 68, 72, 65, 68, 72, - 128, 69, 65, 66, 72, 65, 68, 72, 128, 69, 178, 69, 48, 51, 56, 128, 69, - 48, 51, 55, 128, 69, 48, 51, 54, 128, 69, 48, 51, 52, 65, 128, 69, 48, - 51, 52, 128, 69, 48, 51, 51, 128, 69, 48, 51, 50, 128, 69, 48, 51, 49, - 128, 69, 48, 51, 48, 128, 69, 48, 50, 57, 128, 69, 48, 50, 56, 65, 128, - 69, 48, 50, 56, 128, 69, 48, 50, 55, 128, 69, 48, 50, 54, 128, 69, 48, - 50, 53, 128, 69, 48, 50, 52, 128, 69, 48, 50, 51, 128, 69, 48, 50, 50, - 128, 69, 48, 50, 49, 128, 69, 48, 50, 48, 65, 128, 69, 48, 50, 48, 128, - 69, 48, 49, 57, 128, 69, 48, 49, 56, 128, 69, 48, 49, 55, 65, 128, 69, - 48, 49, 55, 128, 69, 48, 49, 54, 65, 128, 69, 48, 49, 54, 128, 69, 48, - 49, 53, 128, 69, 48, 49, 52, 128, 69, 48, 49, 51, 128, 69, 48, 49, 50, - 128, 69, 48, 49, 49, 128, 69, 48, 49, 48, 128, 69, 48, 48, 57, 65, 128, - 69, 48, 48, 57, 128, 69, 48, 48, 56, 65, 128, 69, 48, 48, 56, 128, 69, - 48, 48, 55, 128, 69, 48, 48, 54, 128, 69, 48, 48, 53, 128, 69, 48, 48, - 52, 128, 69, 48, 48, 51, 128, 69, 48, 48, 50, 128, 69, 48, 48, 49, 128, - 69, 45, 77, 65, 73, 204, 68, 90, 90, 72, 69, 128, 68, 90, 90, 69, 128, - 68, 90, 90, 65, 128, 68, 90, 89, 73, 128, 68, 90, 89, 65, 89, 128, 68, - 90, 87, 69, 128, 68, 90, 85, 128, 68, 90, 79, 128, 68, 90, 74, 69, 128, - 68, 90, 73, 84, 65, 128, 68, 90, 73, 128, 68, 90, 72, 79, 73, 128, 68, - 90, 72, 69, 128, 68, 90, 72, 65, 128, 68, 90, 69, 76, 79, 128, 68, 90, - 69, 69, 128, 68, 90, 69, 128, 68, 90, 65, 89, 128, 68, 90, 65, 65, 128, - 68, 90, 65, 128, 68, 90, 128, 68, 218, 68, 89, 79, 128, 68, 89, 207, 68, - 89, 78, 65, 77, 73, 195, 68, 89, 69, 72, 128, 68, 89, 69, 200, 68, 89, - 65, 78, 128, 68, 87, 79, 128, 68, 87, 69, 128, 68, 87, 65, 128, 68, 86, - 85, 77, 89, 193, 68, 86, 79, 69, 84, 79, 67, 72, 73, 69, 128, 68, 86, 79, - 69, 67, 72, 69, 76, 78, 79, 80, 79, 86, 79, 68, 78, 65, 89, 65, 128, 68, - 86, 79, 69, 67, 72, 69, 76, 78, 79, 80, 79, 86, 79, 68, 78, 65, 89, 193, - 68, 86, 79, 69, 67, 72, 69, 76, 78, 79, 75, 82, 89, 90, 72, 69, 86, 65, - 89, 65, 128, 68, 86, 79, 69, 67, 72, 69, 76, 78, 65, 89, 65, 128, 68, 86, - 79, 69, 67, 72, 69, 76, 78, 65, 89, 193, 68, 86, 73, 83, 86, 65, 82, 65, - 128, 68, 86, 68, 128, 68, 86, 193, 68, 86, 128, 68, 85, 84, 73, 69, 83, - 128, 68, 85, 83, 75, 128, 68, 85, 83, 72, 69, 78, 78, 65, 128, 68, 85, - 82, 65, 84, 73, 79, 78, 128, 68, 85, 82, 50, 128, 68, 85, 80, 79, 78, 68, - 73, 85, 211, 68, 85, 79, 88, 128, 68, 85, 79, 128, 68, 85, 78, 52, 128, - 68, 85, 78, 51, 128, 68, 85, 78, 179, 68, 85, 77, 80, 76, 73, 78, 71, - 128, 68, 85, 77, 128, 68, 85, 204, 68, 85, 72, 128, 68, 85, 71, 85, 68, - 128, 68, 85, 199, 68, 85, 68, 65, 128, 68, 85, 67, 75, 128, 68, 85, 66, - 50, 128, 68, 85, 66, 128, 68, 85, 194, 68, 82, 89, 128, 68, 82, 217, 68, - 82, 85, 77, 83, 84, 73, 67, 75, 83, 128, 68, 82, 85, 77, 128, 68, 82, 85, - 205, 68, 82, 79, 80, 83, 128, 68, 82, 79, 80, 76, 69, 84, 128, 68, 82, - 79, 80, 45, 83, 72, 65, 68, 79, 87, 69, 196, 68, 82, 79, 208, 68, 82, 79, - 79, 76, 73, 78, 199, 68, 82, 79, 77, 69, 68, 65, 82, 217, 68, 82, 73, 86, - 69, 128, 68, 82, 73, 86, 197, 68, 82, 73, 78, 75, 128, 68, 82, 73, 204, - 68, 82, 69, 83, 83, 128, 68, 82, 69, 65, 77, 217, 68, 82, 65, 85, 71, 72, - 84, 211, 68, 82, 65, 77, 128, 68, 82, 65, 205, 68, 82, 65, 71, 79, 78, - 128, 68, 82, 65, 71, 79, 206, 68, 82, 65, 70, 84, 73, 78, 199, 68, 82, - 65, 67, 72, 77, 65, 83, 128, 68, 82, 65, 67, 72, 77, 65, 128, 68, 82, 65, - 67, 72, 77, 193, 68, 79, 87, 78, 87, 65, 82, 68, 83, 128, 68, 79, 87, 78, - 87, 65, 82, 68, 211, 68, 79, 87, 78, 87, 65, 82, 196, 68, 79, 87, 78, 83, - 67, 65, 76, 73, 78, 199, 68, 79, 87, 78, 45, 80, 79, 73, 78, 84, 73, 78, - 199, 68, 79, 87, 78, 128, 68, 79, 86, 69, 128, 68, 79, 86, 197, 68, 79, - 85, 71, 72, 78, 85, 84, 128, 68, 79, 85, 66, 84, 128, 68, 79, 85, 66, 76, - 69, 196, 68, 79, 85, 66, 76, 69, 45, 83, 84, 82, 85, 67, 203, 68, 79, 85, - 66, 76, 69, 45, 76, 73, 78, 69, 196, 68, 79, 85, 66, 76, 69, 45, 76, 73, - 78, 197, 68, 79, 85, 66, 76, 69, 45, 69, 78, 68, 69, 196, 68, 79, 85, 66, - 76, 69, 128, 68, 79, 84, 84, 69, 68, 45, 80, 128, 68, 79, 84, 84, 69, 68, - 45, 78, 128, 68, 79, 84, 84, 69, 68, 45, 76, 128, 68, 79, 84, 84, 69, 68, - 128, 68, 79, 84, 84, 69, 196, 68, 79, 84, 83, 45, 56, 128, 68, 79, 84, - 83, 45, 55, 56, 128, 68, 79, 84, 83, 45, 55, 128, 68, 79, 84, 83, 45, 54, - 56, 128, 68, 79, 84, 83, 45, 54, 55, 56, 128, 68, 79, 84, 83, 45, 54, 55, - 128, 68, 79, 84, 83, 45, 54, 128, 68, 79, 84, 83, 45, 53, 56, 128, 68, - 79, 84, 83, 45, 53, 55, 56, 128, 68, 79, 84, 83, 45, 53, 55, 128, 68, 79, - 84, 83, 45, 53, 54, 56, 128, 68, 79, 84, 83, 45, 53, 54, 55, 56, 128, 68, - 79, 84, 83, 45, 53, 54, 55, 128, 68, 79, 84, 83, 45, 53, 54, 128, 68, 79, - 84, 83, 45, 53, 128, 68, 79, 84, 83, 45, 52, 56, 128, 68, 79, 84, 83, 45, - 52, 55, 56, 128, 68, 79, 84, 83, 45, 52, 55, 128, 68, 79, 84, 83, 45, 52, - 54, 56, 128, 68, 79, 84, 83, 45, 52, 54, 55, 56, 128, 68, 79, 84, 83, 45, - 52, 54, 55, 128, 68, 79, 84, 83, 45, 52, 54, 128, 68, 79, 84, 83, 45, 52, - 53, 56, 128, 68, 79, 84, 83, 45, 52, 53, 55, 56, 128, 68, 79, 84, 83, 45, - 52, 53, 55, 128, 68, 79, 84, 83, 45, 52, 53, 54, 56, 128, 68, 79, 84, 83, - 45, 52, 53, 54, 55, 56, 128, 68, 79, 84, 83, 45, 52, 53, 54, 55, 128, 68, - 79, 84, 83, 45, 52, 53, 54, 128, 68, 79, 84, 83, 45, 52, 53, 128, 68, 79, - 84, 83, 45, 52, 128, 68, 79, 84, 83, 45, 51, 56, 128, 68, 79, 84, 83, 45, - 51, 55, 56, 128, 68, 79, 84, 83, 45, 51, 55, 128, 68, 79, 84, 83, 45, 51, - 54, 56, 128, 68, 79, 84, 83, 45, 51, 54, 55, 56, 128, 68, 79, 84, 83, 45, - 51, 54, 55, 128, 68, 79, 84, 83, 45, 51, 54, 128, 68, 79, 84, 83, 45, 51, - 53, 56, 128, 68, 79, 84, 83, 45, 51, 53, 55, 56, 128, 68, 79, 84, 83, 45, - 51, 53, 55, 128, 68, 79, 84, 83, 45, 51, 53, 54, 56, 128, 68, 79, 84, 83, - 45, 51, 53, 54, 55, 56, 128, 68, 79, 84, 83, 45, 51, 53, 54, 55, 128, 68, - 79, 84, 83, 45, 51, 53, 54, 128, 68, 79, 84, 83, 45, 51, 53, 128, 68, 79, - 84, 83, 45, 51, 52, 56, 128, 68, 79, 84, 83, 45, 51, 52, 55, 56, 128, 68, - 79, 84, 83, 45, 51, 52, 55, 128, 68, 79, 84, 83, 45, 51, 52, 54, 56, 128, - 68, 79, 84, 83, 45, 51, 52, 54, 55, 56, 128, 68, 79, 84, 83, 45, 51, 52, - 54, 55, 128, 68, 79, 84, 83, 45, 51, 52, 54, 128, 68, 79, 84, 83, 45, 51, - 52, 53, 56, 128, 68, 79, 84, 83, 45, 51, 52, 53, 55, 56, 128, 68, 79, 84, - 83, 45, 51, 52, 53, 55, 128, 68, 79, 84, 83, 45, 51, 52, 53, 54, 56, 128, - 68, 79, 84, 83, 45, 51, 52, 53, 54, 55, 56, 128, 68, 79, 84, 83, 45, 51, - 52, 53, 54, 55, 128, 68, 79, 84, 83, 45, 51, 52, 53, 54, 128, 68, 79, 84, - 83, 45, 51, 52, 53, 128, 68, 79, 84, 83, 45, 51, 52, 128, 68, 79, 84, 83, - 45, 51, 128, 68, 79, 84, 83, 45, 50, 56, 128, 68, 79, 84, 83, 45, 50, 55, - 56, 128, 68, 79, 84, 83, 45, 50, 55, 128, 68, 79, 84, 83, 45, 50, 54, 56, + 204, 69, 68, 73, 78, 128, 69, 68, 68, 128, 69, 67, 83, 128, 69, 67, 76, + 73, 80, 83, 69, 128, 69, 66, 69, 70, 73, 76, 73, 128, 69, 65, 83, 84, 69, + 82, 206, 69, 65, 83, 84, 128, 69, 65, 83, 212, 69, 65, 82, 84, 72, 76, + 217, 69, 65, 82, 84, 72, 128, 69, 65, 82, 84, 200, 69, 65, 82, 76, 217, + 69, 65, 77, 72, 65, 78, 67, 72, 79, 76, 76, 128, 69, 65, 71, 76, 69, 128, + 69, 65, 68, 72, 65, 68, 72, 128, 69, 65, 66, 72, 65, 68, 72, 128, 69, + 178, 69, 48, 51, 56, 128, 69, 48, 51, 55, 128, 69, 48, 51, 54, 128, 69, + 48, 51, 52, 65, 128, 69, 48, 51, 52, 128, 69, 48, 51, 51, 128, 69, 48, + 51, 50, 128, 69, 48, 51, 49, 128, 69, 48, 51, 48, 128, 69, 48, 50, 57, + 128, 69, 48, 50, 56, 65, 128, 69, 48, 50, 56, 128, 69, 48, 50, 55, 128, + 69, 48, 50, 54, 128, 69, 48, 50, 53, 128, 69, 48, 50, 52, 128, 69, 48, + 50, 51, 128, 69, 48, 50, 50, 128, 69, 48, 50, 49, 128, 69, 48, 50, 48, + 65, 128, 69, 48, 50, 48, 128, 69, 48, 49, 57, 128, 69, 48, 49, 56, 128, + 69, 48, 49, 55, 65, 128, 69, 48, 49, 55, 128, 69, 48, 49, 54, 65, 128, + 69, 48, 49, 54, 128, 69, 48, 49, 53, 128, 69, 48, 49, 52, 128, 69, 48, + 49, 51, 128, 69, 48, 49, 50, 128, 69, 48, 49, 49, 128, 69, 48, 49, 48, + 128, 69, 48, 48, 57, 65, 128, 69, 48, 48, 57, 128, 69, 48, 48, 56, 65, + 128, 69, 48, 48, 56, 128, 69, 48, 48, 55, 128, 69, 48, 48, 54, 128, 69, + 48, 48, 53, 128, 69, 48, 48, 52, 128, 69, 48, 48, 51, 128, 69, 48, 48, + 50, 128, 69, 48, 48, 49, 128, 69, 45, 77, 65, 73, 204, 68, 90, 90, 72, + 69, 128, 68, 90, 90, 69, 128, 68, 90, 90, 65, 128, 68, 90, 89, 73, 128, + 68, 90, 89, 65, 89, 128, 68, 90, 87, 69, 128, 68, 90, 85, 128, 68, 90, + 79, 128, 68, 90, 74, 69, 128, 68, 90, 73, 84, 65, 128, 68, 90, 73, 128, + 68, 90, 72, 79, 73, 128, 68, 90, 72, 69, 128, 68, 90, 72, 65, 128, 68, + 90, 69, 76, 79, 128, 68, 90, 69, 69, 128, 68, 90, 69, 128, 68, 90, 65, + 89, 128, 68, 90, 65, 65, 128, 68, 90, 65, 128, 68, 90, 128, 68, 218, 68, + 89, 79, 128, 68, 89, 207, 68, 89, 78, 65, 77, 73, 195, 68, 89, 69, 72, + 128, 68, 89, 69, 200, 68, 89, 65, 78, 128, 68, 87, 79, 128, 68, 87, 69, + 128, 68, 87, 65, 128, 68, 86, 85, 77, 89, 193, 68, 86, 79, 69, 84, 79, + 67, 72, 73, 69, 128, 68, 86, 79, 69, 67, 72, 69, 76, 78, 79, 80, 79, 86, + 79, 68, 78, 65, 89, 65, 128, 68, 86, 79, 69, 67, 72, 69, 76, 78, 79, 80, + 79, 86, 79, 68, 78, 65, 89, 193, 68, 86, 79, 69, 67, 72, 69, 76, 78, 79, + 75, 82, 89, 90, 72, 69, 86, 65, 89, 65, 128, 68, 86, 79, 69, 67, 72, 69, + 76, 78, 65, 89, 65, 128, 68, 86, 79, 69, 67, 72, 69, 76, 78, 65, 89, 193, + 68, 86, 73, 83, 86, 65, 82, 65, 128, 68, 86, 68, 128, 68, 86, 193, 68, + 86, 128, 68, 85, 84, 73, 69, 83, 128, 68, 85, 83, 75, 128, 68, 85, 83, + 72, 69, 78, 78, 65, 128, 68, 85, 82, 65, 84, 73, 79, 78, 128, 68, 85, 82, + 50, 128, 68, 85, 80, 79, 78, 68, 73, 85, 211, 68, 85, 79, 88, 128, 68, + 85, 79, 128, 68, 85, 78, 52, 128, 68, 85, 78, 51, 128, 68, 85, 78, 179, + 68, 85, 77, 80, 76, 73, 78, 71, 128, 68, 85, 77, 128, 68, 85, 204, 68, + 85, 72, 128, 68, 85, 71, 85, 68, 128, 68, 85, 199, 68, 85, 68, 65, 128, + 68, 85, 67, 75, 128, 68, 85, 66, 50, 128, 68, 85, 66, 128, 68, 85, 194, + 68, 82, 89, 128, 68, 82, 217, 68, 82, 85, 77, 83, 84, 73, 67, 75, 83, + 128, 68, 82, 85, 77, 128, 68, 82, 85, 205, 68, 82, 79, 80, 83, 128, 68, + 82, 79, 80, 76, 69, 84, 128, 68, 82, 79, 80, 45, 83, 72, 65, 68, 79, 87, + 69, 196, 68, 82, 79, 208, 68, 82, 79, 79, 76, 73, 78, 199, 68, 82, 79, + 77, 69, 68, 65, 82, 217, 68, 82, 73, 86, 69, 128, 68, 82, 73, 86, 197, + 68, 82, 73, 78, 75, 128, 68, 82, 73, 204, 68, 82, 69, 83, 83, 128, 68, + 82, 69, 65, 77, 217, 68, 82, 65, 85, 71, 72, 84, 211, 68, 82, 65, 77, + 128, 68, 82, 65, 205, 68, 82, 65, 71, 79, 78, 128, 68, 82, 65, 71, 79, + 206, 68, 82, 65, 70, 84, 73, 78, 199, 68, 82, 65, 67, 72, 77, 65, 83, + 128, 68, 82, 65, 67, 72, 77, 65, 128, 68, 82, 65, 67, 72, 77, 193, 68, + 79, 87, 78, 87, 65, 82, 68, 83, 128, 68, 79, 87, 78, 87, 65, 82, 68, 211, + 68, 79, 87, 78, 87, 65, 82, 196, 68, 79, 87, 78, 83, 67, 65, 76, 73, 78, + 199, 68, 79, 87, 78, 45, 80, 79, 73, 78, 84, 73, 78, 199, 68, 79, 87, 78, + 128, 68, 79, 86, 69, 128, 68, 79, 86, 197, 68, 79, 85, 71, 72, 78, 85, + 84, 128, 68, 79, 85, 66, 84, 128, 68, 79, 85, 66, 76, 69, 196, 68, 79, + 85, 66, 76, 69, 45, 83, 84, 82, 85, 67, 203, 68, 79, 85, 66, 76, 69, 45, + 76, 73, 78, 69, 196, 68, 79, 85, 66, 76, 69, 45, 76, 73, 78, 197, 68, 79, + 85, 66, 76, 69, 45, 69, 78, 68, 69, 196, 68, 79, 85, 66, 76, 69, 128, 68, + 79, 84, 84, 69, 68, 45, 80, 128, 68, 79, 84, 84, 69, 68, 45, 78, 128, 68, + 79, 84, 84, 69, 68, 45, 76, 128, 68, 79, 84, 84, 69, 68, 128, 68, 79, 84, + 84, 69, 196, 68, 79, 84, 83, 45, 56, 128, 68, 79, 84, 83, 45, 55, 56, + 128, 68, 79, 84, 83, 45, 55, 128, 68, 79, 84, 83, 45, 54, 56, 128, 68, + 79, 84, 83, 45, 54, 55, 56, 128, 68, 79, 84, 83, 45, 54, 55, 128, 68, 79, + 84, 83, 45, 54, 128, 68, 79, 84, 83, 45, 53, 56, 128, 68, 79, 84, 83, 45, + 53, 55, 56, 128, 68, 79, 84, 83, 45, 53, 55, 128, 68, 79, 84, 83, 45, 53, + 54, 56, 128, 68, 79, 84, 83, 45, 53, 54, 55, 56, 128, 68, 79, 84, 83, 45, + 53, 54, 55, 128, 68, 79, 84, 83, 45, 53, 54, 128, 68, 79, 84, 83, 45, 53, + 128, 68, 79, 84, 83, 45, 52, 56, 128, 68, 79, 84, 83, 45, 52, 55, 56, + 128, 68, 79, 84, 83, 45, 52, 55, 128, 68, 79, 84, 83, 45, 52, 54, 56, + 128, 68, 79, 84, 83, 45, 52, 54, 55, 56, 128, 68, 79, 84, 83, 45, 52, 54, + 55, 128, 68, 79, 84, 83, 45, 52, 54, 128, 68, 79, 84, 83, 45, 52, 53, 56, + 128, 68, 79, 84, 83, 45, 52, 53, 55, 56, 128, 68, 79, 84, 83, 45, 52, 53, + 55, 128, 68, 79, 84, 83, 45, 52, 53, 54, 56, 128, 68, 79, 84, 83, 45, 52, + 53, 54, 55, 56, 128, 68, 79, 84, 83, 45, 52, 53, 54, 55, 128, 68, 79, 84, + 83, 45, 52, 53, 54, 128, 68, 79, 84, 83, 45, 52, 53, 128, 68, 79, 84, 83, + 45, 52, 128, 68, 79, 84, 83, 45, 51, 56, 128, 68, 79, 84, 83, 45, 51, 55, + 56, 128, 68, 79, 84, 83, 45, 51, 55, 128, 68, 79, 84, 83, 45, 51, 54, 56, + 128, 68, 79, 84, 83, 45, 51, 54, 55, 56, 128, 68, 79, 84, 83, 45, 51, 54, + 55, 128, 68, 79, 84, 83, 45, 51, 54, 128, 68, 79, 84, 83, 45, 51, 53, 56, + 128, 68, 79, 84, 83, 45, 51, 53, 55, 56, 128, 68, 79, 84, 83, 45, 51, 53, + 55, 128, 68, 79, 84, 83, 45, 51, 53, 54, 56, 128, 68, 79, 84, 83, 45, 51, + 53, 54, 55, 56, 128, 68, 79, 84, 83, 45, 51, 53, 54, 55, 128, 68, 79, 84, + 83, 45, 51, 53, 54, 128, 68, 79, 84, 83, 45, 51, 53, 128, 68, 79, 84, 83, + 45, 51, 52, 56, 128, 68, 79, 84, 83, 45, 51, 52, 55, 56, 128, 68, 79, 84, + 83, 45, 51, 52, 55, 128, 68, 79, 84, 83, 45, 51, 52, 54, 56, 128, 68, 79, + 84, 83, 45, 51, 52, 54, 55, 56, 128, 68, 79, 84, 83, 45, 51, 52, 54, 55, + 128, 68, 79, 84, 83, 45, 51, 52, 54, 128, 68, 79, 84, 83, 45, 51, 52, 53, + 56, 128, 68, 79, 84, 83, 45, 51, 52, 53, 55, 56, 128, 68, 79, 84, 83, 45, + 51, 52, 53, 55, 128, 68, 79, 84, 83, 45, 51, 52, 53, 54, 56, 128, 68, 79, + 84, 83, 45, 51, 52, 53, 54, 55, 56, 128, 68, 79, 84, 83, 45, 51, 52, 53, + 54, 55, 128, 68, 79, 84, 83, 45, 51, 52, 53, 54, 128, 68, 79, 84, 83, 45, + 51, 52, 53, 128, 68, 79, 84, 83, 45, 51, 52, 128, 68, 79, 84, 83, 45, 51, + 128, 68, 79, 84, 83, 45, 50, 56, 128, 68, 79, 84, 83, 45, 50, 55, 56, + 128, 68, 79, 84, 83, 45, 50, 55, 128, 68, 79, 84, 83, 45, 50, 54, 56, 128, 68, 79, 84, 83, 45, 50, 54, 55, 56, 128, 68, 79, 84, 83, 45, 50, 54, 55, 128, 68, 79, 84, 83, 45, 50, 54, 128, 68, 79, 84, 83, 45, 50, 53, 56, 128, 68, 79, 84, 83, 45, 50, 53, 55, 56, 128, 68, 79, 84, 83, 45, 50, 53, @@ -4669,172 +4687,173 @@ static const unsigned char lexicon[] = { 128, 68, 79, 84, 83, 45, 49, 50, 51, 128, 68, 79, 84, 83, 45, 49, 50, 128, 68, 79, 84, 83, 45, 49, 128, 68, 79, 84, 83, 128, 68, 79, 84, 76, 69, 83, 211, 68, 79, 82, 85, 128, 68, 79, 82, 79, 77, 197, 68, 79, 79, - 82, 128, 68, 79, 79, 78, 71, 128, 68, 79, 78, 71, 128, 68, 79, 77, 73, - 78, 207, 68, 79, 77, 65, 73, 206, 68, 79, 76, 80, 72, 73, 78, 128, 68, - 79, 76, 76, 83, 128, 68, 79, 76, 76, 65, 210, 68, 79, 76, 73, 85, 77, - 128, 68, 79, 75, 77, 65, 73, 128, 68, 79, 73, 84, 128, 68, 79, 73, 78, - 199, 68, 79, 73, 128, 68, 79, 71, 82, 193, 68, 79, 71, 128, 68, 79, 199, - 68, 79, 69, 211, 68, 79, 68, 79, 128, 68, 79, 68, 69, 75, 65, 84, 65, - 128, 68, 79, 67, 85, 77, 69, 78, 84, 128, 68, 79, 67, 85, 77, 69, 78, - 212, 68, 79, 66, 82, 79, 128, 68, 79, 65, 67, 72, 65, 83, 72, 77, 69, 69, - 128, 68, 79, 65, 67, 72, 65, 83, 72, 77, 69, 197, 68, 79, 65, 128, 68, - 79, 45, 79, 128, 68, 78, 193, 68, 77, 128, 68, 205, 68, 76, 85, 128, 68, - 76, 79, 128, 68, 76, 73, 128, 68, 76, 72, 89, 65, 128, 68, 76, 72, 65, - 128, 68, 76, 69, 69, 128, 68, 76, 65, 128, 68, 76, 128, 68, 75, 65, 82, - 128, 68, 75, 65, 210, 68, 74, 69, 82, 86, 73, 128, 68, 74, 69, 82, 86, - 128, 68, 74, 69, 128, 68, 74, 65, 128, 68, 73, 90, 90, 217, 68, 73, 89, - 193, 68, 73, 86, 79, 82, 67, 197, 68, 73, 86, 73, 83, 73, 79, 78, 128, - 68, 73, 86, 73, 83, 73, 79, 206, 68, 73, 86, 73, 78, 199, 68, 73, 86, 73, - 78, 65, 84, 73, 79, 78, 128, 68, 73, 86, 73, 68, 69, 83, 128, 68, 73, 86, - 73, 68, 69, 82, 83, 128, 68, 73, 86, 73, 68, 69, 82, 128, 68, 73, 86, 73, - 68, 69, 196, 68, 73, 86, 73, 68, 69, 128, 68, 73, 86, 73, 68, 197, 68, - 73, 86, 69, 211, 68, 73, 86, 69, 82, 71, 69, 78, 67, 69, 128, 68, 73, 84, - 84, 207, 68, 73, 83, 84, 79, 82, 84, 73, 79, 78, 128, 68, 73, 83, 84, 73, - 78, 71, 85, 73, 83, 72, 128, 68, 73, 83, 84, 73, 76, 76, 128, 68, 73, 83, - 83, 79, 76, 86, 69, 45, 50, 128, 68, 73, 83, 83, 79, 76, 86, 69, 128, 68, - 73, 83, 80, 85, 84, 69, 196, 68, 73, 83, 80, 69, 82, 83, 73, 79, 78, 128, - 68, 73, 83, 75, 128, 68, 73, 83, 73, 77, 79, 85, 128, 68, 73, 83, 72, - 128, 68, 73, 83, 71, 85, 73, 83, 69, 196, 68, 73, 83, 67, 79, 78, 84, 73, - 78, 85, 79, 85, 211, 68, 73, 83, 195, 68, 73, 83, 65, 80, 80, 79, 73, 78, - 84, 69, 196, 68, 73, 83, 65, 66, 76, 69, 196, 68, 73, 82, 71, 193, 68, - 73, 82, 69, 67, 84, 76, 217, 68, 73, 82, 69, 67, 84, 73, 79, 78, 65, 204, - 68, 73, 82, 69, 67, 84, 73, 79, 206, 68, 73, 80, 84, 69, 128, 68, 73, 80, - 80, 69, 82, 128, 68, 73, 80, 76, 79, 85, 78, 128, 68, 73, 80, 76, 73, - 128, 68, 73, 80, 76, 201, 68, 73, 78, 71, 66, 65, 212, 68, 73, 206, 68, - 73, 77, 77, 73, 78, 71, 128, 68, 73, 77, 73, 78, 85, 84, 73, 79, 78, 45, - 51, 128, 68, 73, 77, 73, 78, 85, 84, 73, 79, 78, 45, 50, 128, 68, 73, 77, - 73, 78, 85, 84, 73, 79, 78, 45, 49, 128, 68, 73, 77, 73, 78, 73, 83, 72, - 77, 69, 78, 84, 128, 68, 73, 77, 73, 68, 73, 193, 68, 73, 77, 69, 78, 83, - 73, 79, 78, 65, 204, 68, 73, 77, 69, 78, 83, 73, 79, 206, 68, 73, 77, 50, - 128, 68, 73, 77, 178, 68, 73, 76, 128, 68, 73, 71, 82, 65, 80, 72, 128, - 68, 73, 71, 82, 65, 80, 200, 68, 73, 71, 82, 65, 77, 77, 79, 211, 68, 73, - 71, 82, 65, 77, 77, 193, 68, 73, 71, 82, 65, 205, 68, 73, 71, 79, 82, 71, - 79, 78, 128, 68, 73, 71, 79, 82, 71, 79, 206, 68, 73, 71, 73, 84, 83, - 128, 68, 73, 71, 65, 77, 77, 65, 128, 68, 73, 71, 193, 68, 73, 70, 84, - 79, 71, 71, 79, 211, 68, 73, 70, 79, 78, 73, 65, 83, 128, 68, 73, 70, 70, - 73, 67, 85, 76, 84, 217, 68, 73, 70, 70, 73, 67, 85, 76, 84, 73, 69, 83, - 128, 68, 73, 70, 70, 69, 82, 69, 78, 84, 73, 65, 76, 128, 68, 73, 70, 70, - 69, 82, 69, 78, 67, 197, 68, 73, 70, 65, 84, 128, 68, 73, 69, 83, 73, 83, - 128, 68, 73, 69, 83, 73, 211, 68, 73, 69, 83, 69, 204, 68, 73, 69, 80, - 128, 68, 73, 197, 68, 73, 66, 128, 68, 73, 65, 84, 79, 78, 79, 206, 68, - 73, 65, 84, 79, 78, 73, 75, 201, 68, 73, 65, 83, 84, 79, 76, 201, 68, 73, - 65, 77, 79, 78, 68, 83, 128, 68, 73, 65, 77, 79, 78, 68, 128, 68, 73, 65, - 77, 79, 78, 196, 68, 73, 65, 77, 69, 84, 69, 210, 68, 73, 65, 76, 89, 84, - 73, 75, 65, 128, 68, 73, 65, 76, 89, 84, 73, 75, 193, 68, 73, 65, 76, 69, - 67, 84, 45, 208, 68, 73, 65, 71, 79, 78, 65, 76, 128, 68, 73, 65, 69, 82, - 69, 83, 73, 90, 69, 196, 68, 73, 65, 69, 82, 69, 83, 73, 83, 45, 82, 73, - 78, 71, 128, 68, 73, 65, 69, 82, 69, 83, 73, 83, 128, 68, 73, 65, 69, 82, - 69, 83, 73, 211, 68, 72, 79, 85, 128, 68, 72, 79, 79, 128, 68, 72, 79, - 128, 68, 72, 73, 73, 128, 68, 72, 72, 85, 128, 68, 72, 72, 79, 79, 128, - 68, 72, 72, 79, 128, 68, 72, 72, 73, 128, 68, 72, 72, 69, 69, 128, 68, - 72, 72, 69, 128, 68, 72, 72, 65, 128, 68, 72, 69, 69, 128, 68, 72, 65, - 82, 77, 65, 128, 68, 72, 65, 77, 69, 68, 72, 128, 68, 72, 65, 76, 69, 84, - 72, 128, 68, 72, 65, 76, 65, 84, 72, 128, 68, 72, 65, 76, 128, 68, 72, - 65, 68, 72, 69, 128, 68, 72, 65, 65, 76, 85, 128, 68, 72, 65, 65, 128, - 68, 72, 65, 128, 68, 69, 90, 200, 68, 69, 89, 84, 69, 82, 79, 213, 68, - 69, 89, 84, 69, 82, 79, 211, 68, 69, 88, 73, 65, 128, 68, 69, 86, 73, 67, - 197, 68, 69, 86, 69, 76, 79, 80, 77, 69, 78, 84, 128, 68, 69, 85, 78, 71, - 128, 68, 69, 83, 75, 84, 79, 208, 68, 69, 83, 203, 68, 69, 83, 73, 71, - 78, 128, 68, 69, 83, 73, 128, 68, 69, 83, 69, 82, 84, 128, 68, 69, 83, - 69, 82, 212, 68, 69, 83, 69, 82, 69, 212, 68, 69, 83, 67, 82, 73, 80, 84, - 73, 79, 206, 68, 69, 83, 67, 69, 78, 68, 73, 78, 199, 68, 69, 83, 67, 69, - 78, 68, 69, 82, 128, 68, 69, 82, 69, 84, 45, 72, 73, 68, 69, 84, 128, 68, - 69, 82, 69, 84, 128, 68, 69, 82, 69, 76, 73, 67, 212, 68, 69, 82, 66, 73, - 84, 83, 65, 128, 68, 69, 80, 84, 72, 128, 68, 69, 80, 65, 82, 84, 85, 82, - 69, 128, 68, 69, 80, 65, 82, 84, 77, 69, 78, 212, 68, 69, 80, 65, 82, 84, - 73, 78, 199, 68, 69, 78, 84, 73, 83, 84, 82, 217, 68, 69, 78, 84, 65, - 204, 68, 69, 78, 79, 77, 73, 78, 65, 84, 79, 82, 128, 68, 69, 78, 79, 77, - 73, 78, 65, 84, 79, 210, 68, 69, 78, 78, 69, 78, 128, 68, 69, 78, 71, - 128, 68, 69, 78, 197, 68, 69, 78, 65, 82, 73, 85, 211, 68, 69, 77, 69, - 83, 84, 86, 69, 78, 78, 217, 68, 69, 76, 84, 65, 128, 68, 69, 76, 84, - 193, 68, 69, 76, 84, 128, 68, 69, 76, 80, 72, 73, 195, 68, 69, 76, 73, - 86, 69, 82, 217, 68, 69, 76, 73, 86, 69, 82, 65, 78, 67, 69, 128, 68, 69, - 76, 73, 77, 73, 84, 69, 82, 128, 68, 69, 76, 73, 77, 73, 84, 69, 210, 68, - 69, 76, 73, 67, 73, 79, 85, 211, 68, 69, 76, 69, 84, 73, 79, 206, 68, 69, - 76, 69, 84, 69, 128, 68, 69, 76, 69, 84, 197, 68, 69, 75, 65, 128, 68, - 69, 75, 128, 68, 69, 73, 128, 68, 69, 72, 73, 128, 68, 69, 71, 82, 69, - 69, 83, 128, 68, 69, 71, 82, 69, 197, 68, 69, 70, 73, 78, 73, 84, 73, 79, - 78, 128, 68, 69, 70, 69, 67, 84, 73, 86, 69, 78, 69, 83, 211, 68, 69, 69, - 82, 128, 68, 69, 69, 80, 76, 89, 128, 68, 69, 69, 76, 128, 68, 69, 67, - 82, 69, 83, 67, 69, 78, 68, 79, 128, 68, 69, 67, 82, 69, 65, 83, 69, 128, - 68, 69, 67, 82, 69, 65, 83, 197, 68, 69, 67, 79, 82, 65, 84, 73, 86, 197, - 68, 69, 67, 79, 82, 65, 84, 73, 79, 78, 128, 68, 69, 67, 73, 83, 73, 86, - 69, 78, 69, 83, 83, 128, 68, 69, 67, 73, 77, 65, 204, 68, 69, 67, 73, 68, - 85, 79, 85, 211, 68, 69, 67, 69, 77, 66, 69, 82, 128, 68, 69, 67, 65, 89, - 69, 68, 128, 68, 69, 66, 73, 212, 68, 69, 65, 84, 72, 128, 68, 69, 65, - 198, 68, 69, 65, 68, 128, 68, 68, 87, 65, 128, 68, 68, 85, 88, 128, 68, - 68, 85, 84, 128, 68, 68, 85, 82, 88, 128, 68, 68, 85, 82, 128, 68, 68, - 85, 80, 128, 68, 68, 85, 79, 88, 128, 68, 68, 85, 79, 80, 128, 68, 68, - 85, 79, 128, 68, 68, 85, 128, 68, 68, 79, 88, 128, 68, 68, 79, 84, 128, - 68, 68, 79, 80, 128, 68, 68, 79, 65, 128, 68, 68, 73, 88, 128, 68, 68, - 73, 84, 128, 68, 68, 73, 80, 128, 68, 68, 73, 69, 88, 128, 68, 68, 73, - 69, 80, 128, 68, 68, 73, 69, 128, 68, 68, 73, 128, 68, 68, 72, 85, 128, - 68, 68, 72, 79, 128, 68, 68, 72, 69, 69, 128, 68, 68, 72, 69, 128, 68, - 68, 72, 65, 65, 128, 68, 68, 72, 65, 128, 68, 68, 69, 88, 128, 68, 68, - 69, 80, 128, 68, 68, 69, 69, 128, 68, 68, 69, 128, 68, 68, 68, 72, 65, - 128, 68, 68, 68, 65, 128, 68, 68, 65, 89, 65, 78, 78, 65, 128, 68, 68, - 65, 88, 128, 68, 68, 65, 84, 128, 68, 68, 65, 80, 128, 68, 68, 65, 76, - 128, 68, 68, 65, 204, 68, 68, 65, 72, 65, 76, 128, 68, 68, 65, 72, 65, - 204, 68, 68, 65, 65, 128, 68, 67, 83, 128, 68, 67, 72, 69, 128, 68, 67, - 52, 128, 68, 67, 51, 128, 68, 67, 50, 128, 68, 67, 49, 128, 68, 194, 68, - 65, 89, 45, 78, 73, 71, 72, 84, 128, 68, 65, 217, 68, 65, 87, 66, 128, - 68, 65, 86, 73, 89, 65, 78, 73, 128, 68, 65, 86, 73, 68, 128, 68, 65, 84, - 197, 68, 65, 83, 73, 65, 128, 68, 65, 83, 73, 193, 68, 65, 83, 72, 69, - 196, 68, 65, 83, 72, 128, 68, 65, 83, 200, 68, 65, 83, 69, 73, 65, 128, - 68, 65, 82, 84, 128, 68, 65, 82, 75, 69, 78, 73, 78, 71, 128, 68, 65, 82, - 75, 69, 78, 73, 78, 199, 68, 65, 82, 203, 68, 65, 82, 71, 65, 128, 68, - 65, 82, 65, 52, 128, 68, 65, 82, 65, 51, 128, 68, 65, 82, 128, 68, 65, - 80, 45, 80, 82, 65, 205, 68, 65, 80, 45, 80, 73, 201, 68, 65, 80, 45, 77, - 85, 79, 217, 68, 65, 80, 45, 66, 85, 79, 206, 68, 65, 80, 45, 66, 69, - 201, 68, 65, 208, 68, 65, 78, 84, 65, 89, 65, 76, 65, 78, 128, 68, 65, - 78, 84, 65, 74, 193, 68, 65, 78, 71, 79, 128, 68, 65, 78, 71, 128, 68, - 65, 78, 199, 68, 65, 78, 68, 65, 128, 68, 65, 78, 67, 73, 78, 71, 128, - 68, 65, 78, 67, 69, 82, 128, 68, 65, 77, 80, 128, 68, 65, 77, 208, 68, - 65, 77, 77, 65, 84, 65, 78, 128, 68, 65, 77, 77, 65, 84, 65, 206, 68, 65, - 77, 77, 65, 128, 68, 65, 77, 77, 193, 68, 65, 77, 65, 82, 85, 128, 68, - 65, 76, 69, 84, 72, 45, 82, 69, 83, 72, 128, 68, 65, 76, 69, 84, 128, 68, - 65, 76, 69, 212, 68, 65, 76, 68, 65, 128, 68, 65, 76, 65, 84, 72, 128, - 68, 65, 76, 65, 84, 200, 68, 65, 76, 65, 84, 128, 68, 65, 73, 82, 128, - 68, 65, 73, 78, 71, 128, 68, 65, 73, 128, 68, 65, 72, 89, 65, 65, 85, 83, - 72, 45, 50, 128, 68, 65, 72, 89, 65, 65, 85, 83, 72, 128, 68, 65, 71, 83, - 128, 68, 65, 71, 71, 69, 82, 128, 68, 65, 71, 71, 69, 210, 68, 65, 71, - 69, 83, 72, 128, 68, 65, 71, 69, 83, 200, 68, 65, 71, 66, 65, 83, 73, 78, - 78, 65, 128, 68, 65, 71, 65, 218, 68, 65, 71, 65, 76, 71, 65, 128, 68, - 65, 71, 51, 128, 68, 65, 199, 68, 65, 69, 78, 71, 128, 68, 65, 69, 199, - 68, 65, 68, 128, 68, 65, 196, 68, 65, 65, 83, 85, 128, 68, 65, 65, 76, - 73, 128, 68, 65, 65, 68, 72, 85, 128, 68, 48, 54, 55, 72, 128, 68, 48, - 54, 55, 71, 128, 68, 48, 54, 55, 70, 128, 68, 48, 54, 55, 69, 128, 68, - 48, 54, 55, 68, 128, 68, 48, 54, 55, 67, 128, 68, 48, 54, 55, 66, 128, - 68, 48, 54, 55, 65, 128, 68, 48, 54, 55, 128, 68, 48, 54, 54, 128, 68, - 48, 54, 53, 128, 68, 48, 54, 52, 128, 68, 48, 54, 51, 128, 68, 48, 54, - 50, 128, 68, 48, 54, 49, 128, 68, 48, 54, 48, 128, 68, 48, 53, 57, 128, - 68, 48, 53, 56, 128, 68, 48, 53, 55, 128, 68, 48, 53, 54, 128, 68, 48, - 53, 53, 128, 68, 48, 53, 52, 65, 128, 68, 48, 53, 52, 128, 68, 48, 53, - 51, 128, 68, 48, 53, 50, 65, 128, 68, 48, 53, 50, 128, 68, 48, 53, 49, - 128, 68, 48, 53, 48, 73, 128, 68, 48, 53, 48, 72, 128, 68, 48, 53, 48, - 71, 128, 68, 48, 53, 48, 70, 128, 68, 48, 53, 48, 69, 128, 68, 48, 53, - 48, 68, 128, 68, 48, 53, 48, 67, 128, 68, 48, 53, 48, 66, 128, 68, 48, - 53, 48, 65, 128, 68, 48, 53, 48, 128, 68, 48, 52, 57, 128, 68, 48, 52, - 56, 65, 128, 68, 48, 52, 56, 128, 68, 48, 52, 55, 128, 68, 48, 52, 54, - 65, 128, 68, 48, 52, 54, 128, 68, 48, 52, 53, 128, 68, 48, 52, 52, 128, - 68, 48, 52, 51, 128, 68, 48, 52, 50, 128, 68, 48, 52, 49, 128, 68, 48, - 52, 48, 128, 68, 48, 51, 57, 128, 68, 48, 51, 56, 128, 68, 48, 51, 55, - 128, 68, 48, 51, 54, 128, 68, 48, 51, 53, 128, 68, 48, 51, 52, 65, 128, - 68, 48, 51, 52, 128, 68, 48, 51, 51, 128, 68, 48, 51, 50, 128, 68, 48, - 51, 49, 65, 128, 68, 48, 51, 49, 128, 68, 48, 51, 48, 128, 68, 48, 50, - 57, 128, 68, 48, 50, 56, 128, 68, 48, 50, 55, 65, 128, 68, 48, 50, 55, - 128, 68, 48, 50, 54, 128, 68, 48, 50, 53, 128, 68, 48, 50, 52, 128, 68, - 48, 50, 51, 128, 68, 48, 50, 50, 128, 68, 48, 50, 49, 128, 68, 48, 50, - 48, 128, 68, 48, 49, 57, 128, 68, 48, 49, 56, 128, 68, 48, 49, 55, 128, - 68, 48, 49, 54, 128, 68, 48, 49, 53, 128, 68, 48, 49, 52, 128, 68, 48, - 49, 51, 128, 68, 48, 49, 50, 128, 68, 48, 49, 49, 128, 68, 48, 49, 48, - 128, 68, 48, 48, 57, 128, 68, 48, 48, 56, 65, 128, 68, 48, 48, 56, 128, - 68, 48, 48, 55, 128, 68, 48, 48, 54, 128, 68, 48, 48, 53, 128, 68, 48, - 48, 52, 128, 68, 48, 48, 51, 128, 68, 48, 48, 50, 128, 68, 48, 48, 49, - 128, 67, 89, 88, 128, 67, 89, 84, 128, 67, 89, 82, 88, 128, 67, 89, 82, - 69, 78, 65, 73, 195, 67, 89, 82, 128, 67, 89, 80, 82, 79, 45, 77, 73, 78, - 79, 65, 206, 67, 89, 80, 82, 73, 79, 212, 67, 89, 80, 69, 82, 85, 83, - 128, 67, 89, 80, 128, 67, 89, 76, 73, 78, 68, 82, 73, 67, 73, 84, 89, + 82, 128, 68, 79, 79, 78, 71, 128, 68, 79, 78, 75, 69, 89, 128, 68, 79, + 78, 71, 128, 68, 79, 77, 73, 78, 207, 68, 79, 77, 65, 73, 206, 68, 79, + 76, 80, 72, 73, 78, 128, 68, 79, 76, 76, 83, 128, 68, 79, 76, 76, 65, + 210, 68, 79, 76, 73, 85, 77, 128, 68, 79, 75, 77, 65, 73, 128, 68, 79, + 73, 84, 128, 68, 79, 73, 78, 199, 68, 79, 73, 128, 68, 79, 71, 82, 193, + 68, 79, 71, 128, 68, 79, 199, 68, 79, 69, 211, 68, 79, 68, 79, 128, 68, + 79, 68, 69, 75, 65, 84, 65, 128, 68, 79, 67, 85, 77, 69, 78, 84, 128, 68, + 79, 67, 85, 77, 69, 78, 212, 68, 79, 66, 82, 79, 128, 68, 79, 65, 67, 72, + 65, 83, 72, 77, 69, 69, 128, 68, 79, 65, 67, 72, 65, 83, 72, 77, 69, 197, + 68, 79, 65, 128, 68, 79, 45, 79, 128, 68, 78, 193, 68, 77, 128, 68, 205, + 68, 76, 85, 128, 68, 76, 79, 128, 68, 76, 73, 128, 68, 76, 72, 89, 65, + 128, 68, 76, 72, 65, 128, 68, 76, 69, 69, 128, 68, 76, 65, 128, 68, 76, + 128, 68, 75, 65, 82, 128, 68, 75, 65, 210, 68, 74, 69, 82, 86, 73, 128, + 68, 74, 69, 82, 86, 128, 68, 74, 69, 128, 68, 74, 65, 128, 68, 73, 90, + 90, 217, 68, 73, 89, 193, 68, 73, 86, 79, 82, 67, 197, 68, 73, 86, 73, + 83, 73, 79, 78, 128, 68, 73, 86, 73, 83, 73, 79, 206, 68, 73, 86, 73, 78, + 199, 68, 73, 86, 73, 78, 65, 84, 73, 79, 78, 128, 68, 73, 86, 73, 68, 69, + 83, 128, 68, 73, 86, 73, 68, 69, 82, 83, 128, 68, 73, 86, 73, 68, 69, 82, + 128, 68, 73, 86, 73, 68, 69, 196, 68, 73, 86, 73, 68, 69, 128, 68, 73, + 86, 73, 68, 197, 68, 73, 86, 69, 211, 68, 73, 86, 69, 82, 71, 69, 78, 67, + 69, 128, 68, 73, 84, 84, 207, 68, 73, 83, 84, 79, 82, 84, 73, 79, 78, + 128, 68, 73, 83, 84, 73, 78, 71, 85, 73, 83, 72, 128, 68, 73, 83, 84, 73, + 76, 76, 128, 68, 73, 83, 83, 79, 76, 86, 69, 45, 50, 128, 68, 73, 83, 83, + 79, 76, 86, 69, 128, 68, 73, 83, 80, 85, 84, 69, 196, 68, 73, 83, 80, 69, + 82, 83, 73, 79, 78, 128, 68, 73, 83, 75, 128, 68, 73, 83, 73, 77, 79, 85, + 128, 68, 73, 83, 72, 128, 68, 73, 83, 71, 85, 73, 83, 69, 196, 68, 73, + 83, 67, 79, 78, 84, 73, 78, 85, 79, 85, 211, 68, 73, 83, 195, 68, 73, 83, + 65, 80, 80, 79, 73, 78, 84, 69, 196, 68, 73, 83, 65, 66, 76, 69, 196, 68, + 73, 82, 71, 193, 68, 73, 82, 69, 67, 84, 76, 217, 68, 73, 82, 69, 67, 84, + 73, 79, 78, 65, 204, 68, 73, 82, 69, 67, 84, 73, 79, 206, 68, 73, 80, 84, + 69, 128, 68, 73, 80, 80, 69, 82, 128, 68, 73, 80, 76, 79, 85, 78, 128, + 68, 73, 80, 76, 73, 128, 68, 73, 80, 76, 201, 68, 73, 78, 71, 66, 65, + 212, 68, 73, 206, 68, 73, 77, 77, 73, 78, 71, 128, 68, 73, 77, 73, 78, + 85, 84, 73, 79, 78, 45, 51, 128, 68, 73, 77, 73, 78, 85, 84, 73, 79, 78, + 45, 50, 128, 68, 73, 77, 73, 78, 85, 84, 73, 79, 78, 45, 49, 128, 68, 73, + 77, 73, 78, 73, 83, 72, 77, 69, 78, 84, 128, 68, 73, 77, 73, 68, 73, 193, + 68, 73, 77, 69, 78, 83, 73, 79, 78, 65, 204, 68, 73, 77, 69, 78, 83, 73, + 79, 206, 68, 73, 77, 50, 128, 68, 73, 77, 178, 68, 73, 76, 128, 68, 73, + 71, 82, 65, 80, 72, 128, 68, 73, 71, 82, 65, 80, 200, 68, 73, 71, 82, 65, + 77, 77, 79, 211, 68, 73, 71, 82, 65, 77, 77, 193, 68, 73, 71, 82, 65, + 205, 68, 73, 71, 79, 82, 71, 79, 78, 128, 68, 73, 71, 79, 82, 71, 79, + 206, 68, 73, 71, 73, 84, 83, 128, 68, 73, 71, 65, 77, 77, 65, 128, 68, + 73, 71, 193, 68, 73, 70, 84, 79, 71, 71, 79, 211, 68, 73, 70, 79, 78, 73, + 65, 83, 128, 68, 73, 70, 70, 73, 67, 85, 76, 84, 217, 68, 73, 70, 70, 73, + 67, 85, 76, 84, 73, 69, 83, 128, 68, 73, 70, 70, 69, 82, 69, 78, 84, 73, + 65, 76, 128, 68, 73, 70, 70, 69, 82, 69, 78, 67, 197, 68, 73, 70, 65, 84, + 128, 68, 73, 69, 83, 73, 83, 128, 68, 73, 69, 83, 73, 211, 68, 73, 69, + 83, 69, 204, 68, 73, 69, 80, 128, 68, 73, 197, 68, 73, 66, 128, 68, 73, + 65, 84, 79, 78, 79, 206, 68, 73, 65, 84, 79, 78, 73, 75, 201, 68, 73, 65, + 83, 84, 79, 76, 201, 68, 73, 65, 77, 79, 78, 68, 83, 128, 68, 73, 65, 77, + 79, 78, 68, 128, 68, 73, 65, 77, 79, 78, 196, 68, 73, 65, 77, 69, 84, 69, + 210, 68, 73, 65, 76, 89, 84, 73, 75, 65, 128, 68, 73, 65, 76, 89, 84, 73, + 75, 193, 68, 73, 65, 76, 69, 67, 84, 45, 208, 68, 73, 65, 71, 79, 78, 65, + 76, 128, 68, 73, 65, 69, 82, 69, 83, 73, 90, 69, 196, 68, 73, 65, 69, 82, + 69, 83, 73, 83, 45, 82, 73, 78, 71, 128, 68, 73, 65, 69, 82, 69, 83, 73, + 83, 128, 68, 73, 65, 69, 82, 69, 83, 73, 211, 68, 72, 79, 85, 128, 68, + 72, 79, 79, 128, 68, 72, 79, 128, 68, 72, 73, 73, 128, 68, 72, 72, 85, + 128, 68, 72, 72, 79, 79, 128, 68, 72, 72, 79, 128, 68, 72, 72, 73, 128, + 68, 72, 72, 69, 69, 128, 68, 72, 72, 69, 128, 68, 72, 72, 65, 128, 68, + 72, 69, 69, 128, 68, 72, 65, 82, 77, 65, 128, 68, 72, 65, 77, 69, 68, 72, + 128, 68, 72, 65, 76, 69, 84, 72, 128, 68, 72, 65, 76, 65, 84, 72, 128, + 68, 72, 65, 76, 128, 68, 72, 65, 68, 72, 69, 128, 68, 72, 65, 65, 76, 85, + 128, 68, 72, 65, 65, 128, 68, 72, 65, 128, 68, 69, 90, 200, 68, 69, 89, + 84, 69, 82, 79, 213, 68, 69, 89, 84, 69, 82, 79, 211, 68, 69, 88, 73, 65, + 128, 68, 69, 86, 73, 67, 197, 68, 69, 86, 69, 76, 79, 80, 77, 69, 78, 84, + 128, 68, 69, 85, 78, 71, 128, 68, 69, 83, 75, 84, 79, 208, 68, 69, 83, + 203, 68, 69, 83, 73, 71, 78, 128, 68, 69, 83, 73, 128, 68, 69, 83, 69, + 82, 84, 128, 68, 69, 83, 69, 82, 212, 68, 69, 83, 69, 82, 69, 212, 68, + 69, 83, 67, 82, 73, 80, 84, 73, 79, 206, 68, 69, 83, 67, 69, 78, 68, 73, + 78, 199, 68, 69, 83, 67, 69, 78, 68, 69, 82, 128, 68, 69, 82, 69, 84, 45, + 72, 73, 68, 69, 84, 128, 68, 69, 82, 69, 84, 128, 68, 69, 82, 69, 76, 73, + 67, 212, 68, 69, 82, 66, 73, 84, 83, 65, 128, 68, 69, 80, 84, 72, 128, + 68, 69, 80, 65, 82, 84, 85, 82, 69, 128, 68, 69, 80, 65, 82, 84, 77, 69, + 78, 212, 68, 69, 80, 65, 82, 84, 73, 78, 199, 68, 69, 78, 84, 73, 83, 84, + 82, 217, 68, 69, 78, 84, 65, 204, 68, 69, 78, 79, 77, 73, 78, 65, 84, 79, + 82, 128, 68, 69, 78, 79, 77, 73, 78, 65, 84, 79, 210, 68, 69, 78, 78, 69, + 78, 128, 68, 69, 78, 71, 128, 68, 69, 78, 197, 68, 69, 78, 65, 82, 73, + 85, 211, 68, 69, 77, 69, 83, 84, 86, 69, 78, 78, 217, 68, 69, 76, 84, 65, + 128, 68, 69, 76, 84, 193, 68, 69, 76, 84, 128, 68, 69, 76, 80, 72, 73, + 195, 68, 69, 76, 73, 86, 69, 82, 217, 68, 69, 76, 73, 86, 69, 82, 65, 78, + 67, 69, 128, 68, 69, 76, 73, 77, 73, 84, 69, 82, 128, 68, 69, 76, 73, 77, + 73, 84, 69, 210, 68, 69, 76, 73, 67, 73, 79, 85, 211, 68, 69, 76, 69, 84, + 73, 79, 206, 68, 69, 76, 69, 84, 69, 128, 68, 69, 76, 69, 84, 197, 68, + 69, 75, 65, 128, 68, 69, 75, 128, 68, 69, 73, 128, 68, 69, 72, 73, 128, + 68, 69, 71, 82, 69, 69, 83, 128, 68, 69, 71, 82, 69, 197, 68, 69, 70, 73, + 78, 73, 84, 73, 79, 78, 128, 68, 69, 70, 69, 67, 84, 73, 86, 69, 78, 69, + 83, 211, 68, 69, 69, 82, 128, 68, 69, 69, 80, 76, 89, 128, 68, 69, 69, + 76, 128, 68, 69, 67, 82, 69, 83, 67, 69, 78, 68, 79, 128, 68, 69, 67, 82, + 69, 65, 83, 69, 128, 68, 69, 67, 82, 69, 65, 83, 197, 68, 69, 67, 79, 82, + 65, 84, 73, 86, 197, 68, 69, 67, 79, 82, 65, 84, 73, 79, 78, 128, 68, 69, + 67, 73, 83, 73, 86, 69, 78, 69, 83, 83, 128, 68, 69, 67, 73, 77, 65, 204, + 68, 69, 67, 73, 68, 85, 79, 85, 211, 68, 69, 67, 69, 77, 66, 69, 82, 128, + 68, 69, 67, 65, 89, 69, 68, 128, 68, 69, 66, 73, 212, 68, 69, 65, 84, 72, + 128, 68, 69, 65, 198, 68, 69, 65, 68, 128, 68, 68, 87, 65, 128, 68, 68, + 85, 88, 128, 68, 68, 85, 84, 128, 68, 68, 85, 82, 88, 128, 68, 68, 85, + 82, 128, 68, 68, 85, 80, 128, 68, 68, 85, 79, 88, 128, 68, 68, 85, 79, + 80, 128, 68, 68, 85, 79, 128, 68, 68, 85, 128, 68, 68, 79, 88, 128, 68, + 68, 79, 84, 128, 68, 68, 79, 80, 128, 68, 68, 79, 65, 128, 68, 68, 73, + 88, 128, 68, 68, 73, 84, 128, 68, 68, 73, 80, 128, 68, 68, 73, 69, 88, + 128, 68, 68, 73, 69, 80, 128, 68, 68, 73, 69, 128, 68, 68, 73, 128, 68, + 68, 72, 85, 128, 68, 68, 72, 79, 128, 68, 68, 72, 69, 69, 128, 68, 68, + 72, 69, 128, 68, 68, 72, 65, 65, 128, 68, 68, 72, 65, 128, 68, 68, 69, + 88, 128, 68, 68, 69, 80, 128, 68, 68, 69, 69, 128, 68, 68, 69, 128, 68, + 68, 68, 72, 65, 128, 68, 68, 68, 65, 128, 68, 68, 65, 89, 65, 78, 78, 65, + 128, 68, 68, 65, 88, 128, 68, 68, 65, 84, 128, 68, 68, 65, 80, 128, 68, + 68, 65, 76, 128, 68, 68, 65, 204, 68, 68, 65, 72, 65, 76, 128, 68, 68, + 65, 72, 65, 204, 68, 68, 65, 65, 128, 68, 67, 83, 128, 68, 67, 72, 69, + 128, 68, 67, 52, 128, 68, 67, 51, 128, 68, 67, 50, 128, 68, 67, 49, 128, + 68, 194, 68, 65, 89, 45, 78, 73, 71, 72, 84, 128, 68, 65, 217, 68, 65, + 87, 66, 128, 68, 65, 86, 73, 89, 65, 78, 73, 128, 68, 65, 86, 73, 68, + 128, 68, 65, 84, 197, 68, 65, 83, 73, 65, 128, 68, 65, 83, 73, 193, 68, + 65, 83, 72, 69, 196, 68, 65, 83, 72, 128, 68, 65, 83, 200, 68, 65, 83, + 69, 73, 65, 128, 68, 65, 82, 84, 128, 68, 65, 82, 75, 69, 78, 73, 78, 71, + 128, 68, 65, 82, 75, 69, 78, 73, 78, 199, 68, 65, 82, 203, 68, 65, 82, + 71, 65, 128, 68, 65, 82, 65, 52, 128, 68, 65, 82, 65, 51, 128, 68, 65, + 82, 128, 68, 65, 80, 45, 80, 82, 65, 205, 68, 65, 80, 45, 80, 73, 201, + 68, 65, 80, 45, 77, 85, 79, 217, 68, 65, 80, 45, 66, 85, 79, 206, 68, 65, + 80, 45, 66, 69, 201, 68, 65, 208, 68, 65, 78, 84, 65, 89, 65, 76, 65, 78, + 128, 68, 65, 78, 84, 65, 74, 193, 68, 65, 78, 71, 79, 128, 68, 65, 78, + 71, 128, 68, 65, 78, 199, 68, 65, 78, 68, 65, 128, 68, 65, 78, 67, 73, + 78, 71, 128, 68, 65, 78, 67, 69, 82, 128, 68, 65, 77, 80, 128, 68, 65, + 77, 208, 68, 65, 77, 77, 65, 84, 65, 78, 128, 68, 65, 77, 77, 65, 84, 65, + 206, 68, 65, 77, 77, 65, 128, 68, 65, 77, 77, 193, 68, 65, 77, 65, 82, + 85, 128, 68, 65, 77, 65, 71, 69, 68, 128, 68, 65, 77, 65, 71, 69, 196, + 68, 65, 76, 69, 84, 72, 45, 82, 69, 83, 72, 128, 68, 65, 76, 69, 84, 128, + 68, 65, 76, 69, 212, 68, 65, 76, 68, 65, 128, 68, 65, 76, 65, 84, 72, + 128, 68, 65, 76, 65, 84, 200, 68, 65, 76, 65, 84, 128, 68, 65, 73, 82, + 128, 68, 65, 73, 78, 71, 128, 68, 65, 73, 128, 68, 65, 72, 89, 65, 65, + 85, 83, 72, 45, 50, 128, 68, 65, 72, 89, 65, 65, 85, 83, 72, 128, 68, 65, + 71, 83, 128, 68, 65, 71, 71, 69, 82, 128, 68, 65, 71, 71, 69, 210, 68, + 65, 71, 69, 83, 72, 128, 68, 65, 71, 69, 83, 200, 68, 65, 71, 66, 65, 83, + 73, 78, 78, 65, 128, 68, 65, 71, 65, 218, 68, 65, 71, 65, 76, 71, 65, + 128, 68, 65, 71, 51, 128, 68, 65, 199, 68, 65, 69, 78, 71, 128, 68, 65, + 69, 199, 68, 65, 68, 128, 68, 65, 196, 68, 65, 65, 83, 85, 128, 68, 65, + 65, 76, 73, 128, 68, 65, 65, 68, 72, 85, 128, 68, 48, 54, 55, 72, 128, + 68, 48, 54, 55, 71, 128, 68, 48, 54, 55, 70, 128, 68, 48, 54, 55, 69, + 128, 68, 48, 54, 55, 68, 128, 68, 48, 54, 55, 67, 128, 68, 48, 54, 55, + 66, 128, 68, 48, 54, 55, 65, 128, 68, 48, 54, 55, 128, 68, 48, 54, 54, + 128, 68, 48, 54, 53, 128, 68, 48, 54, 52, 128, 68, 48, 54, 51, 128, 68, + 48, 54, 50, 128, 68, 48, 54, 49, 128, 68, 48, 54, 48, 128, 68, 48, 53, + 57, 128, 68, 48, 53, 56, 128, 68, 48, 53, 55, 128, 68, 48, 53, 54, 128, + 68, 48, 53, 53, 128, 68, 48, 53, 52, 65, 128, 68, 48, 53, 52, 128, 68, + 48, 53, 51, 128, 68, 48, 53, 50, 65, 128, 68, 48, 53, 50, 128, 68, 48, + 53, 49, 128, 68, 48, 53, 48, 73, 128, 68, 48, 53, 48, 72, 128, 68, 48, + 53, 48, 71, 128, 68, 48, 53, 48, 70, 128, 68, 48, 53, 48, 69, 128, 68, + 48, 53, 48, 68, 128, 68, 48, 53, 48, 67, 128, 68, 48, 53, 48, 66, 128, + 68, 48, 53, 48, 65, 128, 68, 48, 53, 48, 128, 68, 48, 52, 57, 128, 68, + 48, 52, 56, 65, 128, 68, 48, 52, 56, 128, 68, 48, 52, 55, 128, 68, 48, + 52, 54, 65, 128, 68, 48, 52, 54, 128, 68, 48, 52, 53, 128, 68, 48, 52, + 52, 128, 68, 48, 52, 51, 128, 68, 48, 52, 50, 128, 68, 48, 52, 49, 128, + 68, 48, 52, 48, 128, 68, 48, 51, 57, 128, 68, 48, 51, 56, 128, 68, 48, + 51, 55, 128, 68, 48, 51, 54, 128, 68, 48, 51, 53, 128, 68, 48, 51, 52, + 65, 128, 68, 48, 51, 52, 128, 68, 48, 51, 51, 128, 68, 48, 51, 50, 128, + 68, 48, 51, 49, 65, 128, 68, 48, 51, 49, 128, 68, 48, 51, 48, 128, 68, + 48, 50, 57, 128, 68, 48, 50, 56, 128, 68, 48, 50, 55, 65, 128, 68, 48, + 50, 55, 128, 68, 48, 50, 54, 128, 68, 48, 50, 53, 128, 68, 48, 50, 52, + 128, 68, 48, 50, 51, 128, 68, 48, 50, 50, 128, 68, 48, 50, 49, 128, 68, + 48, 50, 48, 128, 68, 48, 49, 57, 128, 68, 48, 49, 56, 128, 68, 48, 49, + 55, 128, 68, 48, 49, 54, 128, 68, 48, 49, 53, 128, 68, 48, 49, 52, 128, + 68, 48, 49, 51, 128, 68, 48, 49, 50, 128, 68, 48, 49, 49, 128, 68, 48, + 49, 48, 128, 68, 48, 48, 57, 128, 68, 48, 48, 56, 65, 128, 68, 48, 48, + 56, 128, 68, 48, 48, 55, 128, 68, 48, 48, 54, 128, 68, 48, 48, 53, 128, + 68, 48, 48, 52, 128, 68, 48, 48, 51, 128, 68, 48, 48, 50, 128, 68, 48, + 48, 49, 128, 67, 89, 88, 128, 67, 89, 84, 128, 67, 89, 82, 88, 128, 67, + 89, 82, 69, 78, 65, 73, 195, 67, 89, 82, 128, 67, 89, 80, 82, 79, 45, 77, + 73, 78, 79, 65, 206, 67, 89, 80, 82, 73, 79, 212, 67, 89, 80, 69, 82, 85, + 83, 128, 67, 89, 80, 128, 67, 89, 76, 73, 78, 68, 82, 73, 67, 73, 84, 89, 128, 67, 89, 67, 76, 79, 78, 69, 128, 67, 89, 65, 89, 128, 67, 89, 65, 87, 128, 67, 89, 65, 128, 67, 87, 79, 79, 128, 67, 87, 79, 128, 67, 87, 73, 73, 128, 67, 87, 73, 128, 67, 87, 69, 79, 82, 84, 72, 128, 67, 87, @@ -4899,1671 +4918,1672 @@ static const unsigned char lexicon[] = { 83, 84, 65, 78, 67, 89, 128, 67, 79, 78, 83, 69, 67, 85, 84, 73, 86, 197, 67, 79, 78, 74, 85, 78, 67, 84, 73, 79, 78, 128, 67, 79, 78, 74, 85, 71, 65, 84, 197, 67, 79, 78, 74, 79, 73, 78, 73, 78, 199, 67, 79, 78, 74, 79, - 73, 78, 69, 68, 128, 67, 79, 78, 74, 79, 73, 78, 69, 196, 67, 79, 78, 73, - 67, 65, 204, 67, 79, 78, 71, 82, 85, 69, 78, 212, 67, 79, 78, 71, 82, 65, - 84, 85, 76, 65, 84, 73, 79, 78, 128, 67, 79, 78, 70, 85, 83, 69, 196, 67, - 79, 78, 70, 79, 85, 78, 68, 69, 196, 67, 79, 78, 70, 76, 73, 67, 84, 128, - 67, 79, 78, 70, 69, 84, 84, 201, 67, 79, 78, 67, 65, 86, 69, 45, 83, 73, - 68, 69, 196, 67, 79, 78, 67, 65, 86, 69, 45, 80, 79, 73, 78, 84, 69, 196, - 67, 79, 77, 80, 85, 84, 69, 82, 83, 128, 67, 79, 77, 80, 85, 84, 69, 82, - 128, 67, 79, 77, 80, 82, 69, 83, 83, 73, 79, 78, 128, 67, 79, 77, 80, 82, - 69, 83, 83, 69, 196, 67, 79, 77, 80, 79, 83, 73, 84, 73, 79, 78, 128, 67, - 79, 77, 80, 79, 83, 73, 84, 73, 79, 206, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 55, 54, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 54, - 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 54, 54, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 55, 54, 53, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 55, 54, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 55, 54, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 54, 50, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 54, 49, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 55, 54, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 55, 53, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 53, - 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 53, 55, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 55, 53, 54, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 55, 53, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 55, 53, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 53, 51, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 53, 50, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 55, 53, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 55, 53, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 52, - 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 52, 56, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 55, 52, 55, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 55, 52, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 55, 52, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 52, 52, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 52, 51, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 55, 52, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 55, 52, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 52, - 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 51, 57, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 55, 51, 56, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 55, 51, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 55, 51, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 51, 53, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 51, 52, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 55, 51, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 55, 51, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 51, - 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 51, 48, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 55, 50, 57, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 55, 50, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 55, 50, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 50, 54, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 50, 53, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 55, 50, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 55, 50, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 50, - 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 50, 49, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 55, 50, 48, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 55, 49, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 55, 49, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 49, 55, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 49, 54, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 55, 49, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 55, 49, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 49, - 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 49, 50, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 55, 49, 49, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 55, 49, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 55, 48, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 48, 56, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 48, 55, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 55, 48, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 55, 48, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 48, - 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 48, 51, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 55, 48, 50, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 55, 48, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 55, 48, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 57, 57, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 57, 56, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 54, 57, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 54, 57, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 57, - 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 57, 52, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 54, 57, 51, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 54, 57, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 54, 57, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 57, 48, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 56, 57, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 54, 56, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 54, 56, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 56, - 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 56, 53, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 54, 56, 52, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 54, 56, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 54, 56, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 56, 49, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 56, 48, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 54, 55, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 54, 55, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 55, - 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 55, 54, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 54, 55, 53, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 54, 55, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 54, 55, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 55, 50, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 55, 49, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 54, 55, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 54, 54, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 54, - 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 54, 55, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 54, 54, 54, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 54, 54, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 54, 54, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 54, 51, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 54, 50, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 54, 54, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 54, 54, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 53, - 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 53, 56, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 54, 53, 55, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 54, 53, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 54, 53, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 53, 52, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 53, 51, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 54, 53, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 54, 53, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 53, - 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 52, 57, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 54, 52, 56, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 54, 52, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 54, 52, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 52, 53, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 52, 52, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 54, 52, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 54, 52, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 52, - 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 52, 48, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 54, 51, 57, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 54, 51, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 54, 51, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 51, 54, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 51, 53, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 54, 51, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 54, 51, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 51, - 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 51, 49, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 54, 51, 48, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 54, 50, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 54, 50, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 50, 55, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 50, 54, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 54, 50, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 54, 50, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 50, - 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 50, 50, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 54, 50, 49, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 54, 50, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 54, 49, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 49, 56, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 49, 55, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 54, 49, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 54, 49, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 49, - 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 49, 51, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 54, 49, 50, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 54, 49, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 54, 49, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 48, 57, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 48, 56, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 54, 48, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 54, 48, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 48, - 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 48, 52, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 54, 48, 51, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 54, 48, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 54, 48, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 48, 48, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 57, 57, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 53, 57, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 53, 57, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 57, - 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 57, 53, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 53, 57, 52, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 53, 57, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 53, 57, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 57, 49, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 57, 48, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 53, 56, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 53, 56, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 56, - 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 56, 54, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 53, 56, 53, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 53, 56, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 53, 56, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 56, 50, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 56, 49, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 53, 56, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 53, 55, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 55, - 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 55, 55, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 53, 55, 54, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 53, 55, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 53, 55, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 55, 51, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 55, 50, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 53, 55, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 53, 55, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 54, - 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 54, 56, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 53, 54, 55, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 53, 54, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 53, 54, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 54, 52, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 54, 51, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 53, 54, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 53, 54, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 54, - 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 53, 57, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 53, 53, 56, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 53, 53, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 53, 53, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 53, 53, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 53, 52, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 53, 53, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 53, 53, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 53, - 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 53, 48, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 53, 52, 57, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 53, 52, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 53, 52, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 52, 54, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 52, 53, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 53, 52, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 53, 52, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 52, - 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 52, 49, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 53, 52, 48, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 53, 51, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 53, 51, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 51, 55, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 51, 54, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 53, 51, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 53, 51, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 51, - 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 51, 50, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 53, 51, 49, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 53, 51, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 53, 50, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 50, 56, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 50, 55, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 53, 50, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 53, 50, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 50, - 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 50, 51, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 53, 50, 50, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 53, 50, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 53, 50, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 49, 57, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 49, 56, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 53, 49, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 53, 49, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 49, - 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 49, 52, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 53, 49, 51, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 53, 49, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 53, 49, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 49, 48, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 48, 57, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 53, 48, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 53, 48, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 48, - 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 48, 53, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 53, 48, 52, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 53, 48, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 53, 48, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 48, 49, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 48, 48, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 52, 57, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 52, 57, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 57, - 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 57, 54, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 52, 57, 53, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 52, 57, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 52, 57, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 57, 50, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 57, 49, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 52, 57, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 52, 56, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 56, - 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 56, 55, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 52, 56, 54, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 52, 56, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 52, 56, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 56, 51, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 56, 50, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 52, 56, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 52, 56, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 55, - 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 55, 56, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 52, 55, 55, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 52, 55, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 52, 55, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 55, 52, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 55, 51, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 52, 55, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 52, 55, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 55, - 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 54, 57, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 52, 54, 56, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 52, 54, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 52, 54, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 54, 53, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 54, 52, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 52, 54, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 52, 54, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 54, - 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 54, 48, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 52, 53, 57, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 52, 53, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 52, 53, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 53, 54, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 53, 53, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 52, 53, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 52, 53, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 53, - 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 53, 49, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 52, 53, 48, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 52, 52, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 52, 52, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 52, 55, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 52, 54, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 52, 52, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 52, 52, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 52, - 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 52, 50, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 52, 52, 49, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 52, 52, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 52, 51, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 51, 56, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 51, 55, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 52, 51, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 52, 51, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 51, - 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 51, 51, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 52, 51, 50, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 52, 51, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 52, 51, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 50, 57, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 50, 56, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 52, 50, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 52, 50, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 50, - 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 50, 52, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 52, 50, 51, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 52, 50, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 52, 50, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 50, 48, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 49, 57, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 52, 49, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 52, 49, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 49, - 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 49, 53, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 52, 49, 52, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 52, 49, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 52, 49, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 49, 49, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 49, 48, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 52, 48, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 52, 48, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 48, - 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 48, 54, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 52, 48, 53, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 52, 48, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 52, 48, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 48, 50, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 48, 49, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 52, 48, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 51, 57, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 57, - 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 57, 55, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 51, 57, 54, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 51, 57, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 51, 57, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 57, 51, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 57, 50, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 51, 57, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 51, 57, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 56, - 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 56, 56, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 51, 56, 55, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 51, 56, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 51, 56, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 56, 52, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 56, 51, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 51, 56, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 51, 56, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 56, - 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 55, 57, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 51, 55, 56, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 51, 55, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 51, 55, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 55, 53, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 55, 52, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 51, 55, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 51, 55, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 55, - 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 55, 48, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 51, 54, 57, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 51, 54, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 51, 54, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 54, 54, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 54, 53, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 51, 54, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 51, 54, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 54, - 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 54, 49, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 51, 54, 48, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 51, 53, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 51, 53, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 53, 55, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 53, 54, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 51, 53, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 51, 53, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 53, - 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 53, 50, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 51, 53, 49, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 51, 53, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 51, 52, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 52, 56, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 52, 55, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 51, 52, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 51, 52, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 52, - 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 52, 51, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 51, 52, 50, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 51, 52, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 51, 52, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 51, 57, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 51, 56, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 51, 51, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 51, 51, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 51, - 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 51, 52, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 51, 51, 51, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 51, 51, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 51, 51, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 51, 48, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 50, 57, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 51, 50, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 51, 50, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 50, - 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 50, 53, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 51, 50, 52, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 51, 50, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 51, 50, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 50, 49, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 50, 48, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 51, 49, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 51, 49, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 49, - 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 49, 54, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 51, 49, 53, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 51, 49, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 51, 49, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 49, 50, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 49, 49, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 51, 49, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 51, 48, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 48, - 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 48, 55, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 51, 48, 54, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 51, 48, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 51, 48, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 48, 51, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 48, 50, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 51, 48, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 51, 48, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 57, - 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 57, 56, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 50, 57, 55, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 50, 57, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 50, 57, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 57, 52, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 57, 51, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 50, 57, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 50, 57, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 57, - 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 56, 57, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 50, 56, 56, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 50, 56, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 50, 56, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 56, 53, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 56, 52, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 50, 56, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 50, 56, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 56, - 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 56, 48, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 50, 55, 57, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 50, 55, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 50, 55, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 55, 54, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 55, 53, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 50, 55, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 50, 55, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 55, - 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 55, 49, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 50, 55, 48, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 50, 54, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 50, 54, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 54, 55, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 54, 54, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 50, 54, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 50, 54, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 54, - 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 54, 50, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 50, 54, 49, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 50, 54, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 50, 53, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 53, 56, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 53, 55, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 50, 53, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 50, 53, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 53, - 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 53, 51, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 50, 53, 50, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 50, 53, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 50, 53, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 52, 57, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 52, 56, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 50, 52, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 50, 52, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 52, - 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 52, 52, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 50, 52, 51, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 50, 52, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 50, 52, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 52, 48, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 51, 57, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 50, 51, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 50, 51, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 51, - 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 51, 53, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 50, 51, 52, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 50, 51, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 50, 51, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 51, 49, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 51, 48, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 50, 50, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 50, 50, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 50, - 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 50, 54, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 50, 50, 53, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 50, 50, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 50, 50, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 50, 50, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 50, 49, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 50, 50, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 50, 49, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 49, - 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 49, 55, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 50, 49, 54, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 50, 49, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 50, 49, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 49, 51, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 49, 50, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 50, 49, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 50, 49, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 48, - 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 48, 56, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 50, 48, 55, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 50, 48, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 50, 48, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 48, 52, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 48, 51, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 50, 48, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 50, 48, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 48, - 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 57, 57, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 49, 57, 56, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 49, 57, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 49, 57, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 57, 53, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 57, 52, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 49, 57, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 49, 57, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 57, - 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 57, 48, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 49, 56, 57, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 49, 56, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 49, 56, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 56, 54, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 56, 53, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 49, 56, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 49, 56, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 56, - 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 56, 49, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 49, 56, 48, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 49, 55, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 49, 55, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 55, 55, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 55, 54, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 49, 55, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 49, 55, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 55, - 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 55, 50, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 49, 55, 49, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 49, 55, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 49, 54, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 54, 56, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 54, 55, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 49, 54, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 49, 54, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 54, - 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 54, 51, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 49, 54, 50, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 49, 54, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 49, 54, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 53, 57, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 53, 56, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 49, 53, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 49, 53, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 53, - 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 53, 52, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 49, 53, 51, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 49, 53, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 49, 53, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 53, 48, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 52, 57, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 49, 52, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 49, 52, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 52, - 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 52, 53, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 49, 52, 52, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 49, 52, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 49, 52, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 52, 49, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 52, 48, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 49, 51, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 49, 51, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 51, - 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 51, 54, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 49, 51, 53, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 49, 51, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 49, 51, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 51, 50, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 51, 49, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 49, 51, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 49, 50, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 50, - 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 50, 55, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 49, 50, 54, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 49, 50, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 49, 50, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 50, 51, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 50, 50, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 49, 50, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 49, 50, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 49, - 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 49, 56, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 49, 49, 55, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 49, 49, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 49, 49, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 49, 52, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 49, 51, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 49, 49, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 49, 49, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 49, - 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 48, 57, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 49, 48, 56, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 49, 48, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 49, 48, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 48, 53, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 48, 52, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 49, 48, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 49, 48, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 48, - 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 48, 48, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 48, 57, 57, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 48, 57, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 48, 57, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 57, 54, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 57, 53, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 48, 57, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 48, 57, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 57, - 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 57, 49, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 48, 57, 48, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 48, 56, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 48, 56, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 56, 55, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 56, 54, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 48, 56, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 48, 56, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 56, - 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 56, 50, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 48, 56, 49, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 48, 56, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 48, 55, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 55, 56, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 55, 55, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 48, 55, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 48, 55, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 55, - 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 55, 51, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 48, 55, 50, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 48, 55, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 48, 55, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 54, 57, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 54, 56, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 48, 54, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 48, 54, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 54, - 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 54, 52, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 48, 54, 51, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 48, 54, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 48, 54, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 54, 48, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 53, 57, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 48, 53, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 48, 53, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 53, - 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 53, 53, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 48, 53, 52, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 48, 53, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 48, 53, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 53, 49, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 53, 48, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 48, 52, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 48, 52, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 52, - 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 52, 54, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 48, 52, 53, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 48, 52, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 48, 52, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 52, 50, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 52, 49, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 48, 52, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 48, 51, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 51, - 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 51, 55, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 48, 51, 54, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 48, 51, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 48, 51, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 51, 51, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 51, 50, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 48, 51, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 48, 51, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 50, - 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 50, 56, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 48, 50, 55, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 48, 50, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 48, 50, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 50, 52, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 50, 51, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 48, 50, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 48, 50, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 50, - 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 49, 57, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 48, 49, 56, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 48, 49, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 48, 49, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 49, 53, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 49, 52, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 48, 49, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 48, 49, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 49, - 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 49, 48, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 84, 45, 48, 48, 57, 128, 67, 79, 77, 80, 79, 78, - 69, 78, 84, 45, 48, 48, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, - 48, 48, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 48, 54, 128, - 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 48, 53, 128, 67, 79, 77, 80, - 79, 78, 69, 78, 84, 45, 48, 48, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, - 84, 45, 48, 48, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 48, - 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 48, 49, 128, 67, 79, - 77, 80, 79, 78, 69, 78, 212, 67, 79, 77, 80, 76, 73, 65, 78, 67, 69, 128, - 67, 79, 77, 80, 76, 69, 84, 73, 79, 78, 128, 67, 79, 77, 80, 76, 69, 84, - 69, 68, 128, 67, 79, 77, 80, 76, 69, 77, 69, 78, 84, 128, 67, 79, 77, 80, - 65, 83, 83, 128, 67, 79, 77, 80, 65, 82, 69, 128, 67, 79, 77, 77, 79, - 206, 67, 79, 77, 77, 69, 82, 67, 73, 65, 204, 67, 79, 77, 77, 65, 78, 68, - 128, 67, 79, 77, 77, 65, 128, 67, 79, 77, 77, 193, 67, 79, 77, 69, 84, - 128, 67, 79, 77, 66, 73, 78, 69, 68, 128, 67, 79, 77, 66, 73, 78, 65, 84, - 73, 79, 78, 128, 67, 79, 77, 66, 128, 67, 79, 76, 85, 77, 78, 128, 67, - 79, 76, 79, 82, 128, 67, 79, 76, 76, 73, 83, 73, 79, 206, 67, 79, 76, 76, - 128, 67, 79, 76, 196, 67, 79, 73, 78, 128, 67, 79, 70, 70, 73, 78, 128, - 67, 79, 69, 78, 71, 128, 67, 79, 69, 78, 199, 67, 79, 68, 65, 128, 67, - 79, 67, 79, 78, 85, 84, 128, 67, 79, 67, 75, 84, 65, 73, 204, 67, 79, 67, - 75, 82, 79, 65, 67, 72, 128, 67, 79, 65, 84, 128, 67, 79, 65, 83, 84, 69, - 82, 128, 67, 79, 65, 128, 67, 77, 51, 48, 50, 128, 67, 77, 51, 48, 49, - 128, 67, 77, 49, 49, 52, 128, 67, 77, 49, 49, 50, 128, 67, 77, 49, 49, - 48, 128, 67, 77, 49, 48, 57, 128, 67, 77, 49, 48, 56, 128, 67, 77, 49, - 48, 55, 128, 67, 77, 49, 48, 53, 128, 67, 77, 49, 48, 52, 128, 67, 77, - 49, 48, 51, 128, 67, 77, 49, 48, 50, 128, 67, 77, 49, 48, 49, 128, 67, - 77, 49, 48, 48, 128, 67, 77, 48, 57, 57, 128, 67, 77, 48, 57, 56, 128, - 67, 77, 48, 57, 55, 128, 67, 77, 48, 57, 54, 128, 67, 77, 48, 57, 53, - 128, 67, 77, 48, 57, 52, 128, 67, 77, 48, 57, 50, 128, 67, 77, 48, 57, - 49, 128, 67, 77, 48, 57, 48, 128, 67, 77, 48, 56, 57, 128, 67, 77, 48, - 56, 56, 128, 67, 77, 48, 56, 55, 128, 67, 77, 48, 56, 54, 128, 67, 77, - 48, 56, 53, 128, 67, 77, 48, 56, 52, 128, 67, 77, 48, 56, 51, 128, 67, - 77, 48, 56, 50, 128, 67, 77, 48, 56, 49, 128, 67, 77, 48, 56, 48, 128, - 67, 77, 48, 55, 57, 128, 67, 77, 48, 55, 56, 128, 67, 77, 48, 55, 54, - 128, 67, 77, 48, 55, 53, 66, 128, 67, 77, 48, 55, 53, 128, 67, 77, 48, - 55, 52, 128, 67, 77, 48, 55, 51, 128, 67, 77, 48, 55, 50, 128, 67, 77, - 48, 55, 49, 128, 67, 77, 48, 55, 48, 128, 67, 77, 48, 54, 57, 128, 67, - 77, 48, 54, 56, 128, 67, 77, 48, 54, 55, 128, 67, 77, 48, 54, 54, 128, - 67, 77, 48, 54, 52, 128, 67, 77, 48, 54, 51, 128, 67, 77, 48, 54, 50, - 128, 67, 77, 48, 54, 49, 128, 67, 77, 48, 54, 48, 128, 67, 77, 48, 53, - 57, 128, 67, 77, 48, 53, 56, 128, 67, 77, 48, 53, 54, 128, 67, 77, 48, - 53, 53, 128, 67, 77, 48, 53, 52, 128, 67, 77, 48, 53, 51, 128, 67, 77, - 48, 53, 50, 128, 67, 77, 48, 53, 49, 128, 67, 77, 48, 53, 48, 128, 67, - 77, 48, 52, 57, 128, 67, 77, 48, 52, 55, 128, 67, 77, 48, 52, 54, 128, - 67, 77, 48, 52, 52, 128, 67, 77, 48, 52, 49, 128, 67, 77, 48, 52, 48, - 128, 67, 77, 48, 51, 57, 128, 67, 77, 48, 51, 56, 128, 67, 77, 48, 51, - 55, 128, 67, 77, 48, 51, 54, 128, 67, 77, 48, 51, 53, 128, 67, 77, 48, - 51, 52, 128, 67, 77, 48, 51, 51, 128, 67, 77, 48, 51, 48, 128, 67, 77, - 48, 50, 57, 128, 67, 77, 48, 50, 56, 128, 67, 77, 48, 50, 55, 128, 67, - 77, 48, 50, 54, 128, 67, 77, 48, 50, 53, 128, 67, 77, 48, 50, 52, 128, - 67, 77, 48, 50, 51, 128, 67, 77, 48, 50, 49, 128, 67, 77, 48, 49, 57, - 128, 67, 77, 48, 49, 55, 128, 67, 77, 48, 49, 53, 128, 67, 77, 48, 49, - 51, 128, 67, 77, 48, 49, 50, 66, 128, 67, 77, 48, 49, 50, 128, 67, 77, - 48, 49, 49, 128, 67, 77, 48, 49, 48, 128, 67, 77, 48, 48, 57, 128, 67, - 77, 48, 48, 56, 128, 67, 77, 48, 48, 55, 128, 67, 77, 48, 48, 54, 128, - 67, 77, 48, 48, 53, 128, 67, 77, 48, 48, 52, 128, 67, 77, 48, 48, 50, - 128, 67, 77, 48, 48, 49, 128, 67, 77, 128, 67, 205, 67, 76, 85, 83, 84, - 69, 82, 45, 73, 78, 73, 84, 73, 65, 204, 67, 76, 85, 83, 84, 69, 82, 45, - 70, 73, 78, 65, 204, 67, 76, 85, 83, 84, 69, 210, 67, 76, 85, 66, 83, - 128, 67, 76, 85, 66, 45, 83, 80, 79, 75, 69, 196, 67, 76, 85, 66, 128, - 67, 76, 85, 194, 67, 76, 79, 87, 206, 67, 76, 79, 86, 69, 82, 128, 67, - 76, 79, 85, 68, 128, 67, 76, 79, 85, 196, 67, 76, 79, 84, 72, 69, 83, - 128, 67, 76, 79, 84, 72, 128, 67, 76, 79, 83, 69, 84, 128, 67, 76, 79, - 83, 69, 78, 69, 83, 83, 128, 67, 76, 79, 83, 69, 68, 128, 67, 76, 79, 83, - 197, 67, 76, 79, 67, 75, 87, 73, 83, 197, 67, 76, 79, 67, 203, 67, 76, - 73, 86, 73, 83, 128, 67, 76, 73, 80, 66, 79, 65, 82, 68, 128, 67, 76, 73, - 78, 75, 73, 78, 199, 67, 76, 73, 78, 71, 73, 78, 199, 67, 76, 73, 77, 66, - 73, 78, 71, 128, 67, 76, 73, 77, 65, 67, 85, 83, 128, 67, 76, 73, 70, 70, - 128, 67, 76, 73, 67, 75, 128, 67, 76, 73, 67, 203, 67, 76, 69, 70, 45, - 50, 128, 67, 76, 69, 70, 45, 49, 128, 67, 76, 69, 70, 128, 67, 76, 69, - 198, 67, 76, 69, 65, 86, 69, 82, 128, 67, 76, 69, 65, 210, 67, 76, 65, - 83, 83, 73, 67, 65, 204, 67, 76, 65, 80, 80, 73, 78, 199, 67, 76, 65, 80, - 80, 69, 210, 67, 76, 65, 78, 128, 67, 76, 65, 206, 67, 76, 65, 77, 83, - 72, 69, 76, 204, 67, 76, 65, 73, 77, 128, 67, 76, 128, 67, 73, 88, 128, - 67, 73, 86, 73, 76, 73, 65, 78, 128, 67, 73, 84, 89, 83, 67, 65, 80, 69, - 128, 67, 73, 84, 89, 83, 67, 65, 80, 197, 67, 73, 84, 201, 67, 73, 84, - 65, 84, 73, 79, 206, 67, 73, 84, 128, 67, 73, 82, 67, 85, 211, 67, 73, - 82, 67, 85, 77, 70, 76, 69, 88, 128, 67, 73, 82, 67, 85, 77, 70, 76, 69, - 216, 67, 73, 82, 67, 85, 76, 65, 84, 73, 79, 206, 67, 73, 82, 67, 76, 73, - 78, 71, 128, 67, 73, 82, 67, 76, 73, 78, 199, 67, 73, 82, 67, 76, 69, 83, - 128, 67, 73, 82, 67, 76, 69, 211, 67, 73, 82, 67, 76, 69, 68, 128, 67, - 73, 80, 128, 67, 73, 78, 78, 65, 66, 65, 82, 128, 67, 73, 78, 69, 77, 65, - 128, 67, 73, 206, 67, 73, 77, 128, 67, 73, 205, 67, 73, 73, 128, 67, 73, - 69, 88, 128, 67, 73, 69, 85, 67, 45, 83, 83, 65, 78, 71, 80, 73, 69, 85, - 80, 128, 67, 73, 69, 85, 67, 45, 80, 73, 69, 85, 80, 128, 67, 73, 69, 85, - 67, 45, 73, 69, 85, 78, 71, 128, 67, 73, 69, 85, 195, 67, 73, 69, 84, - 128, 67, 73, 69, 80, 128, 67, 73, 69, 128, 67, 72, 89, 88, 128, 67, 72, - 89, 84, 128, 67, 72, 89, 82, 88, 128, 67, 72, 89, 82, 128, 67, 72, 89, - 80, 128, 67, 72, 87, 86, 128, 67, 72, 85, 88, 128, 67, 72, 85, 82, 88, - 128, 67, 72, 85, 82, 67, 72, 128, 67, 72, 85, 82, 128, 67, 72, 85, 80, - 128, 67, 72, 85, 79, 88, 128, 67, 72, 85, 79, 84, 128, 67, 72, 85, 79, - 80, 128, 67, 72, 85, 79, 128, 67, 72, 85, 76, 65, 128, 67, 72, 85, 128, - 67, 72, 82, 89, 83, 65, 78, 84, 72, 69, 77, 85, 77, 128, 67, 72, 82, 79, - 78, 79, 85, 128, 67, 72, 82, 79, 78, 79, 78, 128, 67, 72, 82, 79, 77, - 193, 67, 72, 82, 79, 193, 67, 72, 82, 73, 86, 73, 128, 67, 72, 82, 73, - 83, 84, 77, 65, 83, 128, 67, 72, 82, 73, 83, 84, 77, 65, 211, 67, 72, 79, - 89, 128, 67, 72, 79, 88, 128, 67, 72, 79, 84, 128, 67, 72, 79, 82, 69, - 86, 77, 193, 67, 72, 79, 82, 65, 83, 77, 73, 65, 206, 67, 72, 79, 80, 83, - 84, 73, 67, 75, 83, 128, 67, 72, 79, 80, 128, 67, 72, 79, 75, 69, 128, - 67, 72, 79, 69, 128, 67, 72, 79, 67, 79, 76, 65, 84, 197, 67, 72, 79, 65, - 128, 67, 72, 73, 84, 85, 69, 85, 77, 83, 83, 65, 78, 71, 83, 73, 79, 83, - 128, 67, 72, 73, 84, 85, 69, 85, 77, 83, 83, 65, 78, 71, 67, 73, 69, 85, - 67, 128, 67, 72, 73, 84, 85, 69, 85, 77, 83, 73, 79, 83, 128, 67, 72, 73, - 84, 85, 69, 85, 77, 67, 73, 69, 85, 67, 128, 67, 72, 73, 84, 85, 69, 85, - 77, 67, 72, 73, 69, 85, 67, 72, 128, 67, 72, 73, 82, 79, 78, 128, 67, 72, - 73, 82, 69, 84, 128, 67, 72, 73, 80, 77, 85, 78, 75, 128, 67, 72, 73, 78, - 79, 79, 203, 67, 72, 73, 78, 71, 128, 67, 72, 73, 78, 69, 83, 197, 67, - 72, 73, 78, 128, 67, 72, 73, 77, 69, 128, 67, 72, 73, 77, 128, 67, 72, - 73, 76, 76, 213, 67, 72, 73, 76, 68, 82, 69, 206, 67, 72, 73, 76, 68, - 128, 67, 72, 73, 76, 128, 67, 72, 73, 75, 201, 67, 72, 73, 69, 85, 67, - 72, 45, 75, 72, 73, 69, 85, 75, 72, 128, 67, 72, 73, 69, 85, 67, 72, 45, - 72, 73, 69, 85, 72, 128, 67, 72, 73, 69, 85, 67, 200, 67, 72, 73, 67, 75, - 69, 78, 128, 67, 72, 73, 67, 75, 128, 67, 72, 73, 128, 67, 72, 201, 67, - 72, 72, 73, 77, 128, 67, 72, 72, 65, 128, 67, 72, 69, 88, 128, 67, 72, - 69, 86, 82, 79, 78, 128, 67, 72, 69, 86, 82, 79, 206, 67, 72, 69, 84, - 128, 67, 72, 69, 83, 84, 78, 85, 84, 128, 67, 72, 69, 83, 84, 128, 67, - 72, 69, 83, 211, 67, 72, 69, 82, 89, 128, 67, 72, 69, 82, 82, 217, 67, - 72, 69, 82, 82, 73, 69, 83, 128, 67, 72, 69, 81, 85, 69, 82, 69, 196, 67, - 72, 69, 80, 128, 67, 72, 69, 76, 89, 85, 83, 84, 75, 65, 128, 67, 72, 69, - 76, 78, 85, 128, 67, 72, 69, 73, 78, 65, 80, 128, 67, 72, 69, 73, 75, 72, - 69, 73, 128, 67, 72, 69, 73, 75, 72, 65, 78, 128, 67, 72, 69, 69, 83, - 197, 67, 72, 69, 69, 82, 73, 78, 199, 67, 72, 69, 69, 77, 128, 67, 72, - 69, 69, 75, 211, 67, 72, 69, 69, 75, 128, 67, 72, 69, 69, 128, 67, 72, - 69, 67, 75, 69, 210, 67, 72, 69, 67, 75, 128, 67, 72, 69, 67, 203, 67, - 72, 197, 67, 72, 65, 88, 128, 67, 72, 65, 86, 73, 89, 65, 78, 73, 128, - 67, 72, 65, 84, 84, 65, 87, 65, 128, 67, 72, 65, 84, 128, 67, 72, 65, 83, - 72, 75, 65, 128, 67, 72, 65, 83, 72, 75, 193, 67, 72, 65, 82, 84, 128, - 67, 72, 65, 82, 212, 67, 72, 65, 82, 73, 79, 84, 128, 67, 72, 65, 82, 73, - 79, 212, 67, 72, 65, 82, 65, 67, 84, 69, 82, 83, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 70, 66, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 70, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 70, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 70, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 70, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 70, 54, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 70, 53, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 70, 52, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 70, 51, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 70, 50, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 70, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 70, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 69, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 69, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 69, 68, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 69, 67, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 69, 66, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 69, 65, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 69, 57, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 69, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 69, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 69, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 69, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 69, 52, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 69, 51, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 69, 50, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 69, 49, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 69, 48, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 68, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 68, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 68, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 68, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 68, 66, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 68, 65, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 68, 57, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 68, 56, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 68, 55, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 68, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 68, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 68, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 68, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 68, 50, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 68, 49, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 68, 48, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 67, 70, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 67, 69, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 67, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 67, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 67, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 67, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 67, 57, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 67, 56, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 67, 55, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 67, 54, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 67, 53, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 67, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 67, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 67, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 67, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 67, 48, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 66, 70, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 66, 69, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 66, 68, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 66, 67, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 66, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 66, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 66, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 66, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 66, 55, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 66, 54, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 66, 53, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 66, 52, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 66, 51, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 66, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 66, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 66, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 65, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 65, 69, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 65, 68, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 65, 67, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 65, 66, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 65, 65, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 65, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 65, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 65, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 65, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 65, 53, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 65, 52, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 65, 51, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 65, 50, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 65, 49, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 65, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 57, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 57, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 57, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 57, 67, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 57, 66, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 57, 65, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 57, 57, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 57, 56, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 57, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 57, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 57, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 57, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 57, 51, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 57, 50, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 57, 49, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 57, 48, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 56, 70, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 56, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 56, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 56, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 56, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 56, 65, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 56, 57, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 56, 56, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 56, 55, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 56, 54, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 56, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 56, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 56, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 56, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 56, 49, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 56, 48, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 55, 70, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 55, 69, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 55, 68, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 55, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 55, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 55, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 55, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 55, 56, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 55, 55, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 55, 54, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 55, 53, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 55, 52, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 55, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 55, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 55, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 55, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 54, 70, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 54, 69, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 54, 68, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 54, 67, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 54, 66, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 54, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 54, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 54, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 54, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 54, 54, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 54, 53, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 54, 52, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 54, 51, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 54, 50, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 54, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 54, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 53, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 53, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 53, 68, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 53, 67, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 53, 66, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 53, 65, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 53, 57, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 53, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 53, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 53, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 53, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 53, 52, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 53, 51, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 53, 50, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 53, 49, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 53, 48, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 52, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 52, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 52, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 52, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 52, 66, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 52, 65, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 52, 57, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 52, 56, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 52, 55, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 52, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 52, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 52, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 52, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 52, 50, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 52, 49, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 52, 48, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 51, 70, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 51, 69, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 51, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 51, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 51, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 51, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 51, 57, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 51, 56, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 51, 55, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 51, 54, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 51, 53, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 51, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 51, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 51, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 51, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 51, 48, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 50, 70, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 50, 69, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 50, 68, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 50, 67, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 50, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 50, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 50, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 50, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 50, 55, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 50, 54, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 50, 53, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 50, 52, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 50, 51, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 50, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 50, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 50, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 49, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 49, 69, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 49, 68, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 49, 67, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 49, 66, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 49, 65, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 49, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 49, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 49, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 49, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 49, 53, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 49, 52, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 49, 51, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 49, 50, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 49, 49, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 49, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 48, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 48, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 48, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 48, 67, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 48, 66, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 48, 65, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 48, 57, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 50, 48, 56, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 50, 48, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 50, 48, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 50, 48, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, - 48, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 48, 51, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 48, 50, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 48, 49, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 48, 48, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 49, 70, 70, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 49, 70, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 49, 70, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 49, 70, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, - 70, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 70, 65, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 70, 57, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 70, 56, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 70, 55, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 49, 70, 54, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 49, 70, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 49, 70, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 49, 70, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, - 70, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 70, 49, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 70, 48, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 69, 70, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 69, 69, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 49, 69, 68, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 49, 69, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 49, 69, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 49, 69, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, - 69, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 69, 56, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 69, 55, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 69, 54, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 69, 53, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 49, 69, 52, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 49, 69, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 49, 69, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 49, 69, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, - 69, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 68, 70, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 68, 69, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 68, 68, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 68, 67, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 49, 68, 66, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 49, 68, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 49, 68, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 49, 68, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, - 68, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 68, 54, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 68, 53, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 68, 52, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 68, 51, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 49, 68, 50, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 49, 68, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 49, 68, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 49, 67, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, - 67, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 67, 68, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 67, 67, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 67, 66, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 67, 65, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 49, 67, 57, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 49, 67, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 49, 67, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 49, 67, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, - 67, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 67, 52, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 67, 51, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 67, 50, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 67, 49, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 49, 67, 48, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 49, 66, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 49, 66, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 49, 66, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, - 66, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 66, 66, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 66, 65, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 66, 57, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 66, 56, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 49, 66, 55, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 49, 66, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 49, 66, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 49, 66, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, - 66, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 66, 50, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 66, 49, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 66, 48, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 65, 70, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 49, 65, 69, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 49, 65, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 49, 65, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 49, 65, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, - 65, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 65, 57, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 65, 56, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 65, 55, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 65, 54, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 49, 65, 53, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 49, 65, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 49, 65, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 49, 65, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, - 65, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 65, 48, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 57, 70, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 57, 69, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 57, 68, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 49, 57, 67, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 49, 57, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 49, 57, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 49, 57, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, - 57, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 57, 55, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 57, 54, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 57, 53, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 57, 52, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 49, 57, 51, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 49, 57, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 49, 57, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 49, 57, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, - 56, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 56, 69, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 56, 68, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 56, 67, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 56, 66, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 49, 56, 65, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 49, 56, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 49, 56, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 49, 56, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, - 56, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 56, 53, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 56, 52, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 56, 51, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 56, 50, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 49, 56, 49, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 49, 56, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 49, 55, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 49, 55, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, - 55, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 55, 67, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 55, 66, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 55, 65, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 55, 57, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 66, 49, 55, 56, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 66, 49, 55, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 66, 49, 55, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 66, 49, 55, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, - 55, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 55, 51, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 55, 50, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 55, 49, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 55, 48, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 68, 53, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 68, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 68, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 68, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 68, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 68, 48, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 67, 70, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 67, 69, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 67, 68, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 67, 67, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 67, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 67, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 67, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 67, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 67, 55, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 67, 54, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 67, 53, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 67, 52, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 67, 51, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 67, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 67, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 67, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 66, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 66, 69, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 66, 68, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 66, 67, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 66, 66, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 66, 65, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 66, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 66, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 66, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 66, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 66, 53, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 66, 52, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 66, 51, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 66, 50, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 66, 49, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 66, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 65, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 65, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 65, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 65, 67, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 65, 66, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 65, 65, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 65, 57, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 65, 56, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 65, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 65, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 65, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 65, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 65, 51, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 65, 50, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 65, 49, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 65, 48, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 57, 70, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 57, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 57, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 57, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 57, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 57, 65, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 57, 57, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 57, 56, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 57, 55, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 57, 54, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 57, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 57, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 57, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 57, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 57, 49, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 57, 48, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 56, 70, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 56, 69, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 56, 68, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 56, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 56, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 56, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 56, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 56, 56, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 56, 55, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 56, 54, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 56, 53, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 56, 52, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 56, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 56, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 56, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 56, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 55, 70, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 55, 69, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 55, 68, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 55, 67, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 55, 66, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 55, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 55, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 55, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 55, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 55, 54, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 55, 53, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 55, 52, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 55, 51, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 55, 50, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 55, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 55, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 54, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 54, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 54, 68, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 54, 67, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 54, 66, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 54, 65, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 54, 57, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 54, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 54, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 54, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 54, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 54, 52, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 54, 51, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 54, 50, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 54, 49, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 54, 48, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 53, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 53, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 53, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 53, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 53, 66, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 53, 65, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 53, 57, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 53, 56, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 53, 55, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 53, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 53, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 53, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 53, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 53, 50, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 53, 49, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 53, 48, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 52, 70, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 52, 69, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 52, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 52, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 52, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 52, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 52, 57, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 52, 56, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 52, 55, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 52, 54, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 52, 53, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 52, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 52, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 52, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 52, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 52, 48, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 51, 70, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 51, 69, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 51, 68, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 51, 67, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 51, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 51, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 51, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 51, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 51, 55, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 51, 54, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 51, 53, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 51, 52, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 51, 51, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 51, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 51, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 51, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 50, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 50, 69, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 50, 68, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 50, 67, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 50, 66, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 50, 65, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 50, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 50, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 50, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 50, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 50, 53, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 50, 52, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 50, 51, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 50, 50, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 50, 49, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 50, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 49, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 49, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 49, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 49, 67, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 49, 66, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 49, 65, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 49, 57, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 49, 56, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 49, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 49, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 49, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 49, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 49, 51, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 49, 50, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 49, 49, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 49, 48, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 48, 70, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 48, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 48, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 48, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 48, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 48, 65, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 48, 57, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 48, 56, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 48, 55, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 67, 48, 54, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 67, 48, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 67, 48, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 67, 48, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, - 48, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 48, 49, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 48, 48, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 70, 70, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 70, 69, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 70, 68, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 70, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 70, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 70, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 70, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 70, 56, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 70, 55, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 70, 54, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 70, 53, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 70, 52, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 70, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 70, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 70, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 70, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 69, 70, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 69, 69, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 69, 68, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 69, 67, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 69, 66, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 69, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 69, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 69, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 69, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 69, 54, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 69, 53, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 69, 52, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 69, 51, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 69, 50, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 69, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 69, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 68, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 68, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 68, 68, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 68, 67, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 68, 66, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 68, 65, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 68, 57, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 68, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 68, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 68, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 68, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 68, 52, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 68, 51, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 68, 50, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 68, 49, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 68, 48, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 67, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 67, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 67, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 67, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 67, 66, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 67, 65, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 67, 57, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 67, 56, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 67, 55, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 67, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 67, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 67, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 67, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 67, 50, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 67, 49, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 67, 48, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 66, 70, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 66, 69, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 66, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 66, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 66, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 66, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 66, 57, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 66, 56, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 66, 55, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 66, 54, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 66, 53, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 66, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 66, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 66, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 66, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 66, 48, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 65, 70, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 65, 69, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 65, 68, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 65, 67, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 65, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 65, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 65, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 65, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 65, 55, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 65, 54, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 65, 53, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 65, 52, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 65, 51, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 65, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 65, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 65, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 57, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 57, 69, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 57, 68, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 57, 67, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 57, 66, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 57, 65, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 57, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 57, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 57, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 57, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 57, 53, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 57, 52, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 57, 51, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 57, 50, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 57, 49, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 57, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 56, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 56, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 56, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 56, 67, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 56, 66, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 56, 65, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 56, 57, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 56, 56, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 56, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 56, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 56, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 56, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 56, 51, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 56, 50, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 56, 49, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 56, 48, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 55, 70, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 55, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 55, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 55, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 55, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 55, 65, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 55, 57, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 55, 56, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 55, 55, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 55, 54, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 55, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 55, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 55, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 55, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 55, 49, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 55, 48, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 54, 70, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 54, 69, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 54, 68, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 54, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 54, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 54, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 54, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 54, 56, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 54, 55, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 54, 54, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 54, 53, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 54, 52, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 54, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 54, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 54, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 54, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 53, 70, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 53, 69, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 53, 68, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 53, 67, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 53, 66, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 53, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 53, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 53, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 53, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 53, 54, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 53, 53, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 53, 52, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 53, 51, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 53, 50, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 53, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 53, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 52, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 52, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 52, 68, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 52, 67, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 52, 66, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 52, 65, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 52, 57, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 52, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 52, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 52, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 52, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 52, 52, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 52, 51, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 52, 50, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 52, 49, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 52, 48, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 51, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 51, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 51, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 51, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 51, 66, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 51, 65, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 51, 57, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 51, 56, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 51, 55, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 51, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 51, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 51, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 51, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 51, 50, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 51, 49, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 51, 48, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 50, 70, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 50, 69, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 50, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 50, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 50, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 50, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 50, 57, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 50, 56, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 50, 55, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 50, 54, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 50, 53, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 50, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 50, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 50, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 50, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 50, 48, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 49, 70, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 49, 69, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 49, 68, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 49, 67, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 49, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 49, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 49, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 49, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 49, 55, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 49, 54, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 49, 53, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 49, 52, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 49, 51, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 49, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 49, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 49, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 48, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 48, 69, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 48, 68, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 48, 67, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 48, 66, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 48, 65, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 48, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 45, 49, 56, 66, 48, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, - 56, 66, 48, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, - 48, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 48, 53, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 48, 52, 128, 67, - 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 48, 51, 128, 67, 72, 65, - 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 48, 50, 128, 67, 72, 65, 82, 65, - 67, 84, 69, 82, 45, 49, 56, 66, 48, 49, 128, 67, 72, 65, 82, 65, 67, 84, - 69, 82, 45, 49, 56, 66, 48, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, - 128, 67, 72, 65, 82, 65, 67, 84, 69, 210, 67, 72, 65, 82, 128, 67, 72, - 65, 80, 84, 69, 82, 128, 67, 72, 65, 80, 128, 67, 72, 65, 78, 71, 128, - 67, 72, 65, 78, 128, 67, 72, 65, 77, 75, 79, 128, 67, 72, 65, 77, 73, 76, - 79, 78, 128, 67, 72, 65, 77, 73, 76, 73, 128, 67, 72, 65, 205, 67, 72, - 65, 75, 77, 193, 67, 72, 65, 73, 78, 83, 128, 67, 72, 65, 68, 65, 128, - 67, 72, 65, 196, 67, 72, 65, 65, 128, 67, 71, 74, 128, 67, 69, 88, 128, - 67, 69, 86, 73, 84, 85, 128, 67, 69, 82, 69, 83, 128, 67, 69, 82, 69, 77, - 79, 78, 89, 128, 67, 69, 82, 69, 75, 128, 67, 69, 82, 45, 87, 65, 128, - 67, 69, 80, 128, 67, 69, 79, 78, 71, 67, 72, 73, 69, 85, 77, 83, 83, 65, - 78, 71, 83, 73, 79, 83, 128, 67, 69, 79, 78, 71, 67, 72, 73, 69, 85, 77, - 83, 83, 65, 78, 71, 67, 73, 69, 85, 67, 128, 67, 69, 79, 78, 71, 67, 72, - 73, 69, 85, 77, 83, 73, 79, 83, 128, 67, 69, 79, 78, 71, 67, 72, 73, 69, - 85, 77, 67, 73, 69, 85, 67, 128, 67, 69, 79, 78, 71, 67, 72, 73, 69, 85, - 77, 67, 72, 73, 69, 85, 67, 72, 128, 67, 69, 78, 84, 85, 82, 73, 65, 204, - 67, 69, 78, 84, 82, 69, 76, 73, 78, 197, 67, 69, 78, 84, 82, 69, 68, 128, - 67, 69, 78, 84, 82, 69, 196, 67, 69, 78, 84, 82, 69, 128, 67, 69, 78, 84, - 82, 197, 67, 69, 78, 84, 82, 65, 76, 73, 90, 65, 84, 73, 79, 206, 67, 69, - 78, 128, 67, 69, 76, 84, 73, 195, 67, 69, 76, 83, 73, 85, 83, 128, 67, - 69, 76, 69, 66, 82, 65, 84, 73, 79, 78, 128, 67, 69, 73, 82, 84, 128, 67, - 69, 73, 76, 73, 78, 71, 128, 67, 69, 73, 76, 73, 78, 199, 67, 69, 69, 86, - 128, 67, 69, 69, 66, 128, 67, 69, 69, 128, 67, 69, 68, 73, 76, 76, 65, - 128, 67, 69, 68, 73, 76, 76, 193, 67, 69, 68, 201, 67, 69, 67, 69, 75, - 128, 67, 69, 67, 65, 75, 128, 67, 69, 67, 65, 203, 67, 69, 65, 76, 67, - 128, 67, 67, 85, 128, 67, 67, 79, 128, 67, 67, 73, 128, 67, 67, 72, 85, - 128, 67, 67, 72, 79, 128, 67, 67, 72, 73, 128, 67, 67, 72, 72, 85, 128, - 67, 67, 72, 72, 79, 128, 67, 67, 72, 72, 73, 128, 67, 67, 72, 72, 69, 69, - 128, 67, 67, 72, 72, 69, 128, 67, 67, 72, 72, 65, 65, 128, 67, 67, 72, - 72, 65, 128, 67, 67, 72, 69, 69, 128, 67, 67, 72, 69, 128, 67, 67, 72, - 65, 65, 128, 67, 67, 72, 65, 128, 67, 67, 72, 128, 67, 67, 69, 69, 128, - 67, 67, 65, 65, 128, 67, 65, 89, 78, 128, 67, 65, 89, 65, 78, 78, 65, - 128, 67, 65, 88, 128, 67, 65, 86, 69, 128, 67, 65, 85, 84, 73, 79, 206, - 67, 65, 85, 76, 68, 82, 79, 78, 128, 67, 65, 85, 68, 65, 84, 197, 67, 65, - 85, 68, 65, 128, 67, 65, 85, 67, 65, 83, 73, 65, 206, 67, 65, 85, 128, - 67, 65, 84, 65, 87, 65, 128, 67, 65, 84, 128, 67, 65, 212, 67, 65, 83, - 84, 76, 69, 128, 67, 65, 83, 75, 69, 212, 67, 65, 82, 89, 83, 84, 73, 65, - 206, 67, 65, 82, 84, 87, 72, 69, 69, 76, 128, 67, 65, 82, 84, 82, 73, 68, - 71, 69, 128, 67, 65, 82, 84, 128, 67, 65, 82, 211, 67, 65, 82, 82, 79, - 84, 128, 67, 65, 82, 82, 73, 65, 71, 197, 67, 65, 82, 80, 69, 78, 84, 82, - 217, 67, 65, 82, 208, 67, 65, 82, 79, 85, 83, 69, 204, 67, 65, 82, 79, - 78, 128, 67, 65, 82, 79, 206, 67, 65, 82, 73, 203, 67, 65, 82, 73, 65, - 206, 67, 65, 82, 69, 84, 128, 67, 65, 82, 69, 212, 67, 65, 82, 197, 67, - 65, 82, 68, 83, 128, 67, 65, 82, 196, 67, 65, 82, 128, 67, 65, 210, 67, - 65, 80, 85, 212, 67, 65, 80, 84, 73, 86, 69, 128, 67, 65, 80, 82, 73, 67, - 79, 82, 78, 128, 67, 65, 80, 80, 69, 196, 67, 65, 80, 79, 128, 67, 65, - 80, 73, 84, 85, 76, 85, 77, 128, 67, 65, 80, 73, 84, 65, 76, 128, 67, 65, - 78, 84, 73, 76, 76, 65, 84, 73, 79, 206, 67, 65, 78, 79, 69, 128, 67, 65, - 78, 78, 79, 78, 128, 67, 65, 78, 78, 69, 196, 67, 65, 78, 199, 67, 65, - 78, 69, 128, 67, 65, 78, 68, 89, 128, 67, 65, 78, 68, 82, 65, 66, 73, 78, - 68, 85, 128, 67, 65, 78, 68, 82, 65, 66, 73, 78, 68, 213, 67, 65, 78, 68, - 82, 65, 128, 67, 65, 78, 68, 82, 193, 67, 65, 78, 68, 76, 69, 128, 67, - 65, 78, 67, 69, 82, 128, 67, 65, 78, 67, 69, 76, 76, 65, 84, 73, 79, 206, - 67, 65, 78, 67, 69, 76, 128, 67, 65, 78, 67, 69, 204, 67, 65, 78, 128, - 67, 65, 77, 80, 73, 78, 71, 128, 67, 65, 77, 78, 85, 195, 67, 65, 77, 69, - 82, 65, 128, 67, 65, 77, 69, 82, 193, 67, 65, 77, 69, 76, 128, 67, 65, - 76, 89, 65, 128, 67, 65, 76, 89, 193, 67, 65, 76, 88, 128, 67, 65, 76, - 76, 128, 67, 65, 76, 204, 67, 65, 76, 69, 78, 68, 65, 82, 128, 67, 65, - 76, 69, 78, 68, 65, 210, 67, 65, 76, 67, 85, 76, 65, 84, 79, 82, 128, 67, - 65, 76, 67, 128, 67, 65, 75, 82, 65, 128, 67, 65, 75, 197, 67, 65, 73, - 128, 67, 65, 72, 128, 67, 65, 69, 83, 85, 82, 65, 128, 67, 65, 68, 85, - 67, 69, 85, 83, 128, 67, 65, 68, 193, 67, 65, 67, 84, 85, 83, 128, 67, - 65, 66, 76, 69, 87, 65, 89, 128, 67, 65, 66, 73, 78, 69, 84, 128, 67, 65, - 66, 66, 65, 71, 69, 45, 84, 82, 69, 69, 128, 67, 65, 65, 78, 71, 128, 67, - 65, 65, 73, 128, 67, 193, 67, 48, 50, 52, 128, 67, 48, 50, 51, 128, 67, - 48, 50, 50, 128, 67, 48, 50, 49, 128, 67, 48, 50, 48, 128, 67, 48, 49, - 57, 128, 67, 48, 49, 56, 128, 67, 48, 49, 55, 128, 67, 48, 49, 54, 128, - 67, 48, 49, 53, 128, 67, 48, 49, 52, 128, 67, 48, 49, 51, 128, 67, 48, - 49, 50, 128, 67, 48, 49, 49, 128, 67, 48, 49, 48, 65, 128, 67, 48, 49, - 48, 128, 67, 48, 48, 57, 128, 67, 48, 48, 56, 128, 67, 48, 48, 55, 128, - 67, 48, 48, 54, 128, 67, 48, 48, 53, 128, 67, 48, 48, 52, 128, 67, 48, - 48, 51, 128, 67, 48, 48, 50, 67, 128, 67, 48, 48, 50, 66, 128, 67, 48, - 48, 50, 65, 128, 67, 48, 48, 50, 128, 67, 48, 48, 49, 128, 67, 45, 83, - 73, 77, 80, 76, 73, 70, 73, 69, 196, 67, 45, 51, 57, 128, 67, 45, 49, 56, - 128, 66, 90, 85, 78, 199, 66, 90, 72, 201, 66, 89, 84, 197, 66, 89, 69, - 76, 79, 82, 85, 83, 83, 73, 65, 78, 45, 85, 75, 82, 65, 73, 78, 73, 65, - 206, 66, 88, 71, 128, 66, 87, 73, 128, 66, 87, 69, 69, 128, 66, 87, 69, - 128, 66, 87, 65, 128, 66, 85, 85, 77, 73, 83, 72, 128, 66, 85, 84, 84, - 79, 78, 128, 66, 85, 84, 84, 79, 206, 66, 85, 84, 84, 69, 82, 70, 76, 89, - 128, 66, 85, 84, 84, 69, 82, 128, 66, 85, 212, 66, 85, 83, 84, 211, 66, - 85, 83, 212, 66, 85, 83, 83, 89, 69, 82, 85, 128, 66, 85, 83, 73, 78, 69, - 83, 211, 66, 85, 211, 66, 85, 82, 213, 66, 85, 82, 82, 73, 84, 79, 128, - 66, 85, 82, 50, 128, 66, 85, 210, 66, 85, 79, 89, 128, 66, 85, 79, 88, - 128, 66, 85, 79, 80, 128, 66, 85, 78, 78, 217, 66, 85, 78, 71, 128, 66, - 85, 77, 80, 217, 66, 85, 76, 85, 71, 128, 66, 85, 76, 85, 199, 66, 85, - 76, 76, 83, 69, 89, 69, 128, 66, 85, 76, 76, 211, 66, 85, 76, 76, 72, 79, - 82, 78, 128, 66, 85, 76, 76, 72, 79, 82, 206, 66, 85, 76, 76, 69, 84, - 128, 66, 85, 76, 76, 69, 212, 66, 85, 76, 76, 128, 66, 85, 76, 66, 128, - 66, 85, 75, 89, 128, 66, 85, 73, 76, 68, 73, 78, 71, 83, 128, 66, 85, 73, - 76, 68, 73, 78, 71, 128, 66, 85, 73, 76, 68, 73, 78, 199, 66, 85, 72, 73, - 196, 66, 85, 71, 73, 78, 69, 83, 197, 66, 85, 71, 128, 66, 85, 70, 70, - 65, 76, 79, 128, 66, 85, 68, 128, 66, 85, 67, 75, 76, 69, 128, 66, 85, - 67, 75, 69, 84, 128, 66, 85, 66, 66, 76, 69, 83, 128, 66, 85, 66, 66, 76, - 69, 128, 66, 85, 66, 66, 76, 197, 66, 83, 84, 65, 82, 128, 66, 83, 75, - 85, 210, 66, 83, 75, 65, 173, 66, 83, 68, 85, 211, 66, 82, 85, 83, 200, - 66, 82, 79, 87, 206, 66, 82, 79, 79, 77, 128, 66, 82, 79, 78, 90, 69, - 128, 66, 82, 79, 75, 69, 206, 66, 82, 79, 67, 67, 79, 76, 73, 128, 66, - 82, 79, 65, 196, 66, 82, 73, 83, 84, 76, 69, 128, 66, 82, 73, 71, 72, 84, - 78, 69, 83, 211, 66, 82, 73, 69, 70, 83, 128, 66, 82, 73, 69, 70, 67, 65, - 83, 69, 128, 66, 82, 73, 68, 71, 197, 66, 82, 73, 68, 197, 66, 82, 73, - 67, 75, 128, 66, 82, 73, 128, 66, 82, 69, 86, 73, 83, 128, 66, 82, 69, - 86, 69, 45, 77, 65, 67, 82, 79, 78, 128, 66, 82, 69, 86, 197, 66, 82, 69, - 65, 84, 72, 217, 66, 82, 69, 65, 84, 200, 66, 82, 69, 65, 83, 84, 45, 70, - 69, 69, 68, 73, 78, 71, 128, 66, 82, 69, 65, 75, 84, 72, 82, 79, 85, 71, - 72, 128, 66, 82, 68, 193, 66, 82, 65, 78, 67, 72, 73, 78, 199, 66, 82, - 65, 78, 67, 72, 69, 83, 128, 66, 82, 65, 78, 67, 72, 128, 66, 82, 65, 78, - 67, 200, 66, 82, 65, 75, 67, 69, 84, 128, 66, 82, 65, 73, 78, 128, 66, - 82, 65, 67, 75, 69, 84, 211, 66, 82, 65, 67, 75, 69, 84, 69, 196, 66, 82, - 65, 67, 75, 69, 84, 128, 66, 82, 65, 67, 75, 69, 212, 66, 82, 65, 67, 69, - 128, 66, 81, 128, 66, 80, 72, 128, 66, 79, 89, 211, 66, 79, 89, 128, 66, - 79, 88, 73, 78, 199, 66, 79, 87, 84, 73, 69, 128, 66, 79, 87, 84, 73, - 197, 66, 79, 87, 76, 73, 78, 71, 128, 66, 79, 87, 76, 128, 66, 79, 87, - 204, 66, 79, 87, 73, 78, 199, 66, 79, 215, 66, 79, 85, 81, 85, 69, 84, - 128, 66, 79, 85, 81, 85, 69, 212, 66, 79, 85, 78, 68, 65, 82, 217, 66, - 79, 84, 84, 79, 77, 45, 83, 72, 65, 68, 69, 196, 66, 79, 84, 84, 79, 77, - 45, 76, 73, 71, 72, 84, 69, 196, 66, 79, 84, 84, 79, 77, 128, 66, 79, 84, - 84, 79, 205, 66, 79, 84, 84, 76, 69, 128, 66, 79, 84, 84, 76, 197, 66, - 79, 84, 200, 66, 79, 82, 90, 89, 128, 66, 79, 82, 90, 65, 89, 65, 128, - 66, 79, 82, 85, 84, 79, 128, 66, 79, 82, 65, 88, 45, 51, 128, 66, 79, 82, - 65, 88, 45, 50, 128, 66, 79, 82, 65, 88, 128, 66, 79, 80, 79, 77, 79, 70, - 207, 66, 79, 79, 84, 83, 128, 66, 79, 79, 84, 128, 66, 79, 79, 77, 69, - 82, 65, 78, 71, 128, 66, 79, 79, 75, 83, 128, 66, 79, 79, 75, 77, 65, 82, - 75, 128, 66, 79, 79, 75, 77, 65, 82, 203, 66, 79, 78, 69, 128, 66, 79, - 77, 66, 128, 66, 79, 77, 128, 66, 79, 76, 84, 128, 66, 79, 76, 212, 66, - 79, 72, 65, 73, 82, 73, 195, 66, 79, 68, 89, 128, 66, 79, 68, 217, 66, - 79, 65, 82, 128, 66, 79, 65, 128, 66, 76, 85, 69, 66, 69, 82, 82, 73, 69, - 83, 128, 66, 76, 85, 69, 128, 66, 76, 85, 197, 66, 76, 79, 87, 73, 78, - 199, 66, 76, 79, 87, 70, 73, 83, 72, 128, 66, 76, 79, 215, 66, 76, 79, - 83, 83, 79, 77, 128, 66, 76, 79, 79, 68, 128, 66, 76, 79, 78, 196, 66, - 76, 79, 67, 75, 45, 55, 128, 66, 76, 79, 67, 75, 45, 54, 128, 66, 76, 79, - 67, 75, 45, 53, 128, 66, 76, 79, 67, 75, 45, 52, 128, 66, 76, 79, 67, 75, - 45, 51, 128, 66, 76, 79, 67, 75, 45, 50, 128, 66, 76, 79, 67, 75, 45, 49, - 51, 53, 56, 128, 66, 76, 79, 67, 75, 128, 66, 76, 73, 78, 203, 66, 76, - 65, 78, 75, 128, 66, 76, 65, 78, 203, 66, 76, 65, 68, 197, 66, 76, 65, - 67, 75, 76, 69, 84, 84, 69, 210, 66, 76, 65, 67, 75, 70, 79, 79, 212, 66, - 76, 65, 67, 75, 45, 76, 69, 84, 84, 69, 210, 66, 76, 65, 67, 75, 45, 70, - 69, 65, 84, 72, 69, 82, 69, 196, 66, 76, 65, 67, 75, 128, 66, 75, 65, - 173, 66, 73, 84, 84, 69, 82, 128, 66, 73, 84, 73, 78, 199, 66, 73, 84, - 197, 66, 73, 84, 67, 79, 73, 206, 66, 73, 83, 79, 78, 128, 66, 73, 83, - 77, 85, 84, 200, 66, 73, 83, 77, 73, 76, 76, 65, 200, 66, 73, 83, 72, 79, - 208, 66, 73, 83, 69, 67, 84, 73, 78, 199, 66, 73, 83, 65, 72, 128, 66, - 73, 82, 85, 128, 66, 73, 82, 84, 72, 68, 65, 217, 66, 73, 82, 71, 65, - 128, 66, 73, 82, 71, 193, 66, 73, 82, 68, 128, 66, 73, 79, 72, 65, 90, - 65, 82, 196, 66, 73, 78, 79, 86, 73, 76, 69, 128, 66, 73, 78, 79, 67, 85, - 76, 65, 210, 66, 73, 78, 68, 73, 78, 199, 66, 73, 78, 68, 73, 128, 66, - 73, 78, 65, 82, 217, 66, 73, 76, 76, 73, 79, 78, 83, 128, 66, 73, 76, 76, - 73, 65, 82, 68, 83, 128, 66, 73, 76, 76, 69, 196, 66, 73, 76, 65, 66, 73, - 65, 204, 66, 73, 75, 73, 78, 73, 128, 66, 73, 71, 128, 66, 73, 199, 66, - 73, 69, 84, 128, 66, 73, 68, 69, 78, 84, 65, 204, 66, 73, 68, 65, 75, 85, - 79, 206, 66, 73, 67, 89, 67, 76, 73, 83, 84, 128, 66, 73, 67, 89, 67, 76, - 69, 83, 128, 66, 73, 67, 89, 67, 76, 69, 128, 66, 73, 67, 69, 80, 83, - 128, 66, 73, 66, 76, 69, 45, 67, 82, 69, 197, 66, 73, 66, 128, 66, 201, - 66, 72, 85, 128, 66, 72, 79, 79, 128, 66, 72, 79, 128, 66, 72, 73, 128, - 66, 72, 69, 84, 72, 128, 66, 72, 69, 69, 128, 66, 72, 69, 128, 66, 72, - 65, 84, 84, 73, 80, 82, 79, 76, 213, 66, 72, 65, 77, 128, 66, 72, 65, 73, - 75, 83, 85, 75, 201, 66, 72, 65, 65, 128, 66, 72, 65, 128, 66, 69, 89, - 89, 65, 76, 128, 66, 69, 88, 128, 66, 69, 86, 69, 82, 65, 71, 69, 128, - 66, 69, 86, 69, 82, 65, 71, 197, 66, 69, 84, 87, 69, 69, 78, 128, 66, 69, - 84, 87, 69, 69, 206, 66, 69, 84, 72, 128, 66, 69, 84, 65, 128, 66, 69, - 84, 193, 66, 69, 212, 66, 69, 83, 73, 68, 197, 66, 69, 82, 75, 65, 78, - 65, 206, 66, 69, 82, 66, 69, 210, 66, 69, 80, 128, 66, 69, 79, 82, 195, - 66, 69, 78, 90, 69, 78, 197, 66, 69, 78, 84, 207, 66, 69, 78, 84, 128, - 66, 69, 78, 212, 66, 69, 78, 71, 65, 76, 201, 66, 69, 78, 68, 69, 128, - 66, 69, 78, 68, 128, 66, 69, 78, 196, 66, 69, 206, 66, 69, 76, 84, 128, - 66, 69, 76, 212, 66, 69, 76, 79, 215, 66, 69, 76, 76, 72, 79, 208, 66, - 69, 76, 76, 128, 66, 69, 76, 204, 66, 69, 76, 71, 84, 72, 79, 210, 66, - 69, 73, 84, 72, 128, 66, 69, 72, 73, 78, 196, 66, 69, 72, 69, 72, 128, - 66, 69, 72, 69, 200, 66, 69, 72, 128, 66, 69, 200, 66, 69, 71, 73, 78, - 78, 73, 78, 71, 128, 66, 69, 71, 73, 78, 78, 69, 82, 128, 66, 69, 71, 73, + 73, 78, 69, 82, 128, 67, 79, 78, 74, 79, 73, 78, 69, 68, 128, 67, 79, 78, + 74, 79, 73, 78, 69, 196, 67, 79, 78, 73, 67, 65, 204, 67, 79, 78, 71, 82, + 85, 69, 78, 212, 67, 79, 78, 71, 82, 65, 84, 85, 76, 65, 84, 73, 79, 78, + 128, 67, 79, 78, 70, 85, 83, 69, 196, 67, 79, 78, 70, 79, 85, 78, 68, 69, + 196, 67, 79, 78, 70, 76, 73, 67, 84, 128, 67, 79, 78, 70, 69, 84, 84, + 201, 67, 79, 78, 67, 65, 86, 69, 45, 83, 73, 68, 69, 196, 67, 79, 78, 67, + 65, 86, 69, 45, 80, 79, 73, 78, 84, 69, 196, 67, 79, 77, 80, 85, 84, 69, + 82, 83, 128, 67, 79, 77, 80, 85, 84, 69, 82, 128, 67, 79, 77, 80, 82, 69, + 83, 83, 73, 79, 78, 128, 67, 79, 77, 80, 82, 69, 83, 83, 69, 196, 67, 79, + 77, 80, 79, 83, 73, 84, 73, 79, 78, 128, 67, 79, 77, 80, 79, 83, 73, 84, + 73, 79, 206, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 54, 56, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 54, 55, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 55, 54, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 55, 54, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 54, 52, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 54, 51, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 55, 54, 50, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 55, 54, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, + 54, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 53, 57, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 53, 56, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 55, 53, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 55, 53, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 53, 53, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 53, 52, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 55, 53, 51, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 55, 53, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, + 53, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 53, 48, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 52, 57, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 55, 52, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 55, 52, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 52, 54, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 52, 53, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 55, 52, 52, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 55, 52, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, + 52, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 52, 49, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 52, 48, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 55, 51, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 55, 51, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 51, 55, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 51, 54, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 55, 51, 53, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 55, 51, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, + 51, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 51, 50, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 51, 49, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 55, 51, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 55, 50, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 50, 56, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 50, 55, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 55, 50, 54, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 55, 50, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, + 50, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 50, 51, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 50, 50, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 55, 50, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 55, 50, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 49, 57, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 49, 56, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 55, 49, 55, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 55, 49, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, + 49, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 49, 52, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 49, 51, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 55, 49, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 55, 49, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 49, 48, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 48, 57, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 55, 48, 56, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 55, 48, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, + 48, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 48, 53, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 48, 52, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 55, 48, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 55, 48, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 48, 49, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 55, 48, 48, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 54, 57, 57, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 54, 57, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, + 57, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 57, 54, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 57, 53, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 54, 57, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 54, 57, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 57, 50, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 57, 49, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 54, 57, 48, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 54, 56, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, + 56, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 56, 55, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 56, 54, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 54, 56, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 54, 56, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 56, 51, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 56, 50, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 54, 56, 49, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 54, 56, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, + 55, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 55, 56, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 55, 55, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 54, 55, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 54, 55, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 55, 52, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 55, 51, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 54, 55, 50, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 54, 55, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, + 55, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 54, 57, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 54, 56, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 54, 54, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 54, 54, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 54, 53, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 54, 52, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 54, 54, 51, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 54, 54, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, + 54, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 54, 48, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 53, 57, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 54, 53, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 54, 53, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 53, 54, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 53, 53, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 54, 53, 52, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 54, 53, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, + 53, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 53, 49, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 53, 48, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 54, 52, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 54, 52, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 52, 55, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 52, 54, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 54, 52, 53, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 54, 52, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, + 52, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 52, 50, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 52, 49, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 54, 52, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 54, 51, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 51, 56, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 51, 55, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 54, 51, 54, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 54, 51, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, + 51, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 51, 51, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 51, 50, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 54, 51, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 54, 51, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 50, 57, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 50, 56, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 54, 50, 55, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 54, 50, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, + 50, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 50, 52, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 50, 51, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 54, 50, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 54, 50, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 50, 48, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 49, 57, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 54, 49, 56, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 54, 49, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, + 49, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 49, 53, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 49, 52, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 54, 49, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 54, 49, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 49, 49, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 49, 48, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 54, 48, 57, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 54, 48, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, + 48, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 48, 54, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 48, 53, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 54, 48, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 54, 48, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 48, 50, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 54, 48, 49, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 54, 48, 48, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 53, 57, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, + 57, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 57, 55, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 57, 54, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 53, 57, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 53, 57, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 57, 51, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 57, 50, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 53, 57, 49, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 53, 57, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, + 56, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 56, 56, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 56, 55, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 53, 56, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 53, 56, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 56, 52, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 56, 51, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 53, 56, 50, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 53, 56, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, + 56, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 55, 57, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 55, 56, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 53, 55, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 53, 55, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 55, 53, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 55, 52, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 53, 55, 51, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 53, 55, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, + 55, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 55, 48, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 54, 57, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 53, 54, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 53, 54, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 54, 54, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 54, 53, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 53, 54, 52, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 53, 54, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, + 54, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 54, 49, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 54, 48, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 53, 53, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 53, 53, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 53, 55, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 53, 54, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 53, 53, 53, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 53, 53, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, + 53, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 53, 50, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 53, 49, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 53, 53, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 53, 52, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 52, 56, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 52, 55, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 53, 52, 54, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 53, 52, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, + 52, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 52, 51, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 52, 50, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 53, 52, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 53, 52, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 51, 57, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 51, 56, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 53, 51, 55, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 53, 51, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, + 51, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 51, 52, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 51, 51, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 53, 51, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 53, 51, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 51, 48, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 50, 57, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 53, 50, 56, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 53, 50, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, + 50, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 50, 53, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 50, 52, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 53, 50, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 53, 50, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 50, 49, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 50, 48, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 53, 49, 57, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 53, 49, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, + 49, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 49, 54, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 49, 53, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 53, 49, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 53, 49, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 49, 50, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 49, 49, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 53, 49, 48, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 53, 48, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, + 48, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 48, 55, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 48, 54, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 53, 48, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 53, 48, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 48, 51, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 53, 48, 50, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 53, 48, 49, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 53, 48, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, + 57, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 57, 56, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 57, 55, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 52, 57, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 52, 57, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 57, 52, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 57, 51, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 52, 57, 50, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 52, 57, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, + 57, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 56, 57, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 56, 56, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 52, 56, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 52, 56, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 56, 53, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 56, 52, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 52, 56, 51, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 52, 56, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, + 56, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 56, 48, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 55, 57, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 52, 55, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 52, 55, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 55, 54, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 55, 53, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 52, 55, 52, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 52, 55, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, + 55, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 55, 49, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 55, 48, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 52, 54, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 52, 54, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 54, 55, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 54, 54, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 52, 54, 53, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 52, 54, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, + 54, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 54, 50, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 54, 49, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 52, 54, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 52, 53, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 53, 56, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 53, 55, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 52, 53, 54, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 52, 53, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, + 53, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 53, 51, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 53, 50, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 52, 53, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 52, 53, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 52, 57, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 52, 56, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 52, 52, 55, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 52, 52, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, + 52, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 52, 52, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 52, 51, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 52, 52, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 52, 52, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 52, 48, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 51, 57, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 52, 51, 56, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 52, 51, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, + 51, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 51, 53, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 51, 52, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 52, 51, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 52, 51, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 51, 49, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 51, 48, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 52, 50, 57, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 52, 50, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, + 50, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 50, 54, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 50, 53, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 52, 50, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 52, 50, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 50, 50, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 50, 49, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 52, 50, 48, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 52, 49, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, + 49, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 49, 55, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 49, 54, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 52, 49, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 52, 49, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 49, 51, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 49, 50, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 52, 49, 49, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 52, 49, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, + 48, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 48, 56, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 48, 55, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 52, 48, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 52, 48, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 48, 52, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, 48, 51, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 52, 48, 50, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 52, 48, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 52, + 48, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 57, 57, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 57, 56, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 51, 57, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 51, 57, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 57, 53, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 57, 52, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 51, 57, 51, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 51, 57, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, + 57, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 57, 48, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 56, 57, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 51, 56, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 51, 56, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 56, 54, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 56, 53, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 51, 56, 52, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 51, 56, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, + 56, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 56, 49, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 56, 48, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 51, 55, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 51, 55, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 55, 55, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 55, 54, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 51, 55, 53, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 51, 55, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, + 55, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 55, 50, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 55, 49, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 51, 55, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 51, 54, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 54, 56, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 54, 55, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 51, 54, 54, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 51, 54, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, + 54, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 54, 51, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 54, 50, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 51, 54, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 51, 54, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 53, 57, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 53, 56, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 51, 53, 55, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 51, 53, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, + 53, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 53, 52, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 53, 51, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 51, 53, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 51, 53, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 53, 48, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 52, 57, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 51, 52, 56, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 51, 52, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, + 52, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 52, 53, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 52, 52, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 51, 52, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 51, 52, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 52, 49, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 52, 48, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 51, 51, 57, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 51, 51, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, + 51, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 51, 54, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 51, 53, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 51, 51, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 51, 51, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 51, 50, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 51, 49, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 51, 51, 48, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 51, 50, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, + 50, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 50, 55, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 50, 54, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 51, 50, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 51, 50, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 50, 51, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 50, 50, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 51, 50, 49, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 51, 50, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, + 49, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 49, 56, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 49, 55, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 51, 49, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 51, 49, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 49, 52, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 49, 51, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 51, 49, 50, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 51, 49, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, + 49, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 48, 57, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 48, 56, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 51, 48, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 51, 48, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 48, 53, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 48, 52, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 51, 48, 51, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 51, 48, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, + 48, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 51, 48, 48, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 57, 57, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 50, 57, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 50, 57, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 57, 54, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 57, 53, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 50, 57, 52, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 50, 57, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, + 57, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 57, 49, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 57, 48, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 50, 56, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 50, 56, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 56, 55, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 56, 54, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 50, 56, 53, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 50, 56, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, + 56, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 56, 50, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 56, 49, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 50, 56, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 50, 55, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 55, 56, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 55, 55, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 50, 55, 54, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 50, 55, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, + 55, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 55, 51, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 55, 50, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 50, 55, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 50, 55, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 54, 57, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 54, 56, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 50, 54, 55, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 50, 54, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, + 54, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 54, 52, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 54, 51, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 50, 54, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 50, 54, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 54, 48, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 53, 57, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 50, 53, 56, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 50, 53, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, + 53, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 53, 53, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 53, 52, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 50, 53, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 50, 53, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 53, 49, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 53, 48, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 50, 52, 57, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 50, 52, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, + 52, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 52, 54, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 52, 53, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 50, 52, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 50, 52, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 52, 50, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 52, 49, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 50, 52, 48, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 50, 51, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, + 51, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 51, 55, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 51, 54, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 50, 51, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 50, 51, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 51, 51, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 51, 50, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 50, 51, 49, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 50, 51, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, + 50, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 50, 56, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 50, 55, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 50, 50, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 50, 50, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 50, 52, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 50, 51, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 50, 50, 50, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 50, 50, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, + 50, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 49, 57, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 49, 56, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 50, 49, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 50, 49, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 49, 53, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 49, 52, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 50, 49, 51, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 50, 49, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, + 49, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 49, 48, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 48, 57, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 50, 48, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 50, 48, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 48, 54, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 48, 53, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 50, 48, 52, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 50, 48, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, + 48, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 48, 49, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 50, 48, 48, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 49, 57, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 49, 57, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 57, 55, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 57, 54, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 49, 57, 53, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 49, 57, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, + 57, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 57, 50, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 57, 49, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 49, 57, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 49, 56, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 56, 56, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 56, 55, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 49, 56, 54, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 49, 56, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, + 56, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 56, 51, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 56, 50, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 49, 56, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 49, 56, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 55, 57, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 55, 56, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 49, 55, 55, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 49, 55, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, + 55, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 55, 52, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 55, 51, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 49, 55, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 49, 55, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 55, 48, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 54, 57, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 49, 54, 56, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 49, 54, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, + 54, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 54, 53, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 54, 52, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 49, 54, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 49, 54, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 54, 49, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 54, 48, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 49, 53, 57, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 49, 53, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, + 53, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 53, 54, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 53, 53, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 49, 53, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 49, 53, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 53, 50, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 53, 49, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 49, 53, 48, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 49, 52, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, + 52, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 52, 55, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 52, 54, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 49, 52, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 49, 52, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 52, 51, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 52, 50, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 49, 52, 49, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 49, 52, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, + 51, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 51, 56, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 51, 55, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 49, 51, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 49, 51, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 51, 52, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 51, 51, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 49, 51, 50, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 49, 51, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, + 51, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 50, 57, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 50, 56, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 49, 50, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 49, 50, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 50, 53, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 50, 52, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 49, 50, 51, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 49, 50, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, + 50, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 50, 48, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 49, 57, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 49, 49, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 49, 49, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 49, 54, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 49, 53, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 49, 49, 52, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 49, 49, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, + 49, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 49, 49, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 49, 48, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 49, 48, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 49, 48, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 48, 55, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 48, 54, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 49, 48, 53, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 49, 48, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, + 48, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 48, 50, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 49, 48, 49, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 49, 48, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 48, 57, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 57, 56, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 57, 55, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 48, 57, 54, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 48, 57, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, + 57, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 57, 51, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 57, 50, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 48, 57, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 48, 57, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 56, 57, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 56, 56, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 48, 56, 55, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 48, 56, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, + 56, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 56, 52, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 56, 51, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 48, 56, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 48, 56, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 56, 48, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 55, 57, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 48, 55, 56, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 48, 55, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, + 55, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 55, 53, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 55, 52, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 48, 55, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 48, 55, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 55, 49, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 55, 48, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 48, 54, 57, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 48, 54, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, + 54, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 54, 54, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 54, 53, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 48, 54, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 48, 54, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 54, 50, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 54, 49, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 48, 54, 48, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 48, 53, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, + 53, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 53, 55, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 53, 54, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 48, 53, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 48, 53, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 53, 51, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 53, 50, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 48, 53, 49, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 48, 53, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, + 52, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 52, 56, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 52, 55, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 48, 52, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 48, 52, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 52, 52, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 52, 51, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 48, 52, 50, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 48, 52, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, + 52, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 51, 57, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 51, 56, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 48, 51, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 48, 51, 54, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 51, 53, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 51, 52, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 48, 51, 51, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 48, 51, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, + 51, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 51, 48, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 50, 57, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 48, 50, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 48, 50, 55, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 50, 54, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 50, 53, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 48, 50, 52, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 48, 50, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, + 50, 50, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 50, 49, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 50, 48, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 48, 49, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 48, 49, 56, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 49, 55, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 49, 54, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 48, 49, 53, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 48, 49, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, + 49, 51, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 49, 50, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 49, 49, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 48, 49, 48, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, + 45, 48, 48, 57, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 48, 56, + 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 48, 55, 128, 67, 79, 77, + 80, 79, 78, 69, 78, 84, 45, 48, 48, 54, 128, 67, 79, 77, 80, 79, 78, 69, + 78, 84, 45, 48, 48, 53, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, + 48, 52, 128, 67, 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 48, 51, 128, 67, + 79, 77, 80, 79, 78, 69, 78, 84, 45, 48, 48, 50, 128, 67, 79, 77, 80, 79, + 78, 69, 78, 84, 45, 48, 48, 49, 128, 67, 79, 77, 80, 79, 78, 69, 78, 212, + 67, 79, 77, 80, 76, 73, 65, 78, 67, 69, 128, 67, 79, 77, 80, 76, 69, 84, + 73, 79, 78, 128, 67, 79, 77, 80, 76, 69, 84, 69, 68, 128, 67, 79, 77, 80, + 76, 69, 77, 69, 78, 84, 128, 67, 79, 77, 80, 65, 83, 83, 128, 67, 79, 77, + 80, 65, 82, 69, 128, 67, 79, 77, 77, 79, 206, 67, 79, 77, 77, 69, 82, 67, + 73, 65, 204, 67, 79, 77, 77, 65, 78, 68, 128, 67, 79, 77, 77, 65, 128, + 67, 79, 77, 77, 193, 67, 79, 77, 69, 84, 128, 67, 79, 77, 66, 73, 78, 69, + 68, 128, 67, 79, 77, 66, 73, 78, 65, 84, 73, 79, 78, 128, 67, 79, 77, 66, + 128, 67, 79, 76, 85, 77, 78, 128, 67, 79, 76, 79, 82, 128, 67, 79, 76, + 76, 73, 83, 73, 79, 206, 67, 79, 76, 76, 128, 67, 79, 76, 196, 67, 79, + 73, 78, 128, 67, 79, 70, 70, 73, 78, 128, 67, 79, 69, 78, 71, 128, 67, + 79, 69, 78, 199, 67, 79, 68, 65, 128, 67, 79, 67, 79, 78, 85, 84, 128, + 67, 79, 67, 75, 84, 65, 73, 204, 67, 79, 67, 75, 82, 79, 65, 67, 72, 128, + 67, 79, 65, 84, 128, 67, 79, 65, 83, 84, 69, 82, 128, 67, 79, 65, 128, + 67, 77, 51, 48, 50, 128, 67, 77, 51, 48, 49, 128, 67, 77, 49, 49, 52, + 128, 67, 77, 49, 49, 50, 128, 67, 77, 49, 49, 48, 128, 67, 77, 49, 48, + 57, 128, 67, 77, 49, 48, 56, 128, 67, 77, 49, 48, 55, 128, 67, 77, 49, + 48, 53, 128, 67, 77, 49, 48, 52, 128, 67, 77, 49, 48, 51, 128, 67, 77, + 49, 48, 50, 128, 67, 77, 49, 48, 49, 128, 67, 77, 49, 48, 48, 128, 67, + 77, 48, 57, 57, 128, 67, 77, 48, 57, 56, 128, 67, 77, 48, 57, 55, 128, + 67, 77, 48, 57, 54, 128, 67, 77, 48, 57, 53, 128, 67, 77, 48, 57, 52, + 128, 67, 77, 48, 57, 50, 128, 67, 77, 48, 57, 49, 128, 67, 77, 48, 57, + 48, 128, 67, 77, 48, 56, 57, 128, 67, 77, 48, 56, 56, 128, 67, 77, 48, + 56, 55, 128, 67, 77, 48, 56, 54, 128, 67, 77, 48, 56, 53, 128, 67, 77, + 48, 56, 52, 128, 67, 77, 48, 56, 51, 128, 67, 77, 48, 56, 50, 128, 67, + 77, 48, 56, 49, 128, 67, 77, 48, 56, 48, 128, 67, 77, 48, 55, 57, 128, + 67, 77, 48, 55, 56, 128, 67, 77, 48, 55, 54, 128, 67, 77, 48, 55, 53, 66, + 128, 67, 77, 48, 55, 53, 128, 67, 77, 48, 55, 52, 128, 67, 77, 48, 55, + 51, 128, 67, 77, 48, 55, 50, 128, 67, 77, 48, 55, 49, 128, 67, 77, 48, + 55, 48, 128, 67, 77, 48, 54, 57, 128, 67, 77, 48, 54, 56, 128, 67, 77, + 48, 54, 55, 128, 67, 77, 48, 54, 54, 128, 67, 77, 48, 54, 52, 128, 67, + 77, 48, 54, 51, 128, 67, 77, 48, 54, 50, 128, 67, 77, 48, 54, 49, 128, + 67, 77, 48, 54, 48, 128, 67, 77, 48, 53, 57, 128, 67, 77, 48, 53, 56, + 128, 67, 77, 48, 53, 54, 128, 67, 77, 48, 53, 53, 128, 67, 77, 48, 53, + 52, 128, 67, 77, 48, 53, 51, 128, 67, 77, 48, 53, 50, 128, 67, 77, 48, + 53, 49, 128, 67, 77, 48, 53, 48, 128, 67, 77, 48, 52, 57, 128, 67, 77, + 48, 52, 55, 128, 67, 77, 48, 52, 54, 128, 67, 77, 48, 52, 52, 128, 67, + 77, 48, 52, 49, 128, 67, 77, 48, 52, 48, 128, 67, 77, 48, 51, 57, 128, + 67, 77, 48, 51, 56, 128, 67, 77, 48, 51, 55, 128, 67, 77, 48, 51, 54, + 128, 67, 77, 48, 51, 53, 128, 67, 77, 48, 51, 52, 128, 67, 77, 48, 51, + 51, 128, 67, 77, 48, 51, 48, 128, 67, 77, 48, 50, 57, 128, 67, 77, 48, + 50, 56, 128, 67, 77, 48, 50, 55, 128, 67, 77, 48, 50, 54, 128, 67, 77, + 48, 50, 53, 128, 67, 77, 48, 50, 52, 128, 67, 77, 48, 50, 51, 128, 67, + 77, 48, 50, 49, 128, 67, 77, 48, 49, 57, 128, 67, 77, 48, 49, 55, 128, + 67, 77, 48, 49, 53, 128, 67, 77, 48, 49, 51, 128, 67, 77, 48, 49, 50, 66, + 128, 67, 77, 48, 49, 50, 128, 67, 77, 48, 49, 49, 128, 67, 77, 48, 49, + 48, 128, 67, 77, 48, 48, 57, 128, 67, 77, 48, 48, 56, 128, 67, 77, 48, + 48, 55, 128, 67, 77, 48, 48, 54, 128, 67, 77, 48, 48, 53, 128, 67, 77, + 48, 48, 52, 128, 67, 77, 48, 48, 50, 128, 67, 77, 48, 48, 49, 128, 67, + 77, 128, 67, 205, 67, 76, 85, 83, 84, 69, 82, 45, 73, 78, 73, 84, 73, 65, + 204, 67, 76, 85, 83, 84, 69, 82, 45, 70, 73, 78, 65, 204, 67, 76, 85, 83, + 84, 69, 210, 67, 76, 85, 66, 83, 128, 67, 76, 85, 66, 45, 83, 80, 79, 75, + 69, 196, 67, 76, 85, 66, 128, 67, 76, 85, 194, 67, 76, 79, 87, 206, 67, + 76, 79, 86, 69, 82, 128, 67, 76, 79, 85, 68, 128, 67, 76, 79, 85, 196, + 67, 76, 79, 84, 72, 69, 83, 128, 67, 76, 79, 84, 72, 128, 67, 76, 79, 83, + 69, 84, 128, 67, 76, 79, 83, 69, 78, 69, 83, 83, 128, 67, 76, 79, 83, 69, + 68, 128, 67, 76, 79, 83, 197, 67, 76, 79, 67, 75, 87, 73, 83, 197, 67, + 76, 79, 67, 203, 67, 76, 73, 86, 73, 83, 128, 67, 76, 73, 80, 66, 79, 65, + 82, 68, 128, 67, 76, 73, 78, 75, 73, 78, 199, 67, 76, 73, 78, 71, 73, 78, + 199, 67, 76, 73, 77, 66, 73, 78, 71, 128, 67, 76, 73, 77, 65, 67, 85, 83, + 128, 67, 76, 73, 70, 70, 128, 67, 76, 73, 67, 75, 128, 67, 76, 73, 67, + 203, 67, 76, 69, 70, 45, 50, 128, 67, 76, 69, 70, 45, 49, 128, 67, 76, + 69, 70, 128, 67, 76, 69, 198, 67, 76, 69, 65, 86, 69, 82, 128, 67, 76, + 69, 65, 210, 67, 76, 65, 83, 83, 73, 67, 65, 204, 67, 76, 65, 80, 80, 73, + 78, 199, 67, 76, 65, 80, 80, 69, 210, 67, 76, 65, 78, 128, 67, 76, 65, + 206, 67, 76, 65, 77, 83, 72, 69, 76, 204, 67, 76, 65, 73, 77, 128, 67, + 76, 128, 67, 73, 88, 128, 67, 73, 86, 73, 76, 73, 65, 78, 128, 67, 73, + 84, 89, 83, 67, 65, 80, 69, 128, 67, 73, 84, 89, 83, 67, 65, 80, 197, 67, + 73, 84, 201, 67, 73, 84, 65, 84, 73, 79, 206, 67, 73, 84, 128, 67, 73, + 82, 67, 85, 211, 67, 73, 82, 67, 85, 77, 70, 76, 69, 88, 128, 67, 73, 82, + 67, 85, 77, 70, 76, 69, 216, 67, 73, 82, 67, 85, 76, 65, 84, 73, 79, 206, + 67, 73, 82, 67, 76, 73, 78, 71, 128, 67, 73, 82, 67, 76, 73, 78, 199, 67, + 73, 82, 67, 76, 69, 83, 128, 67, 73, 82, 67, 76, 69, 211, 67, 73, 82, 67, + 76, 69, 68, 128, 67, 73, 80, 128, 67, 73, 78, 78, 65, 66, 65, 82, 128, + 67, 73, 78, 69, 77, 65, 128, 67, 73, 206, 67, 73, 77, 128, 67, 73, 205, + 67, 73, 73, 128, 67, 73, 69, 88, 128, 67, 73, 69, 85, 67, 45, 83, 83, 65, + 78, 71, 80, 73, 69, 85, 80, 128, 67, 73, 69, 85, 67, 45, 80, 73, 69, 85, + 80, 128, 67, 73, 69, 85, 67, 45, 73, 69, 85, 78, 71, 128, 67, 73, 69, 85, + 195, 67, 73, 69, 84, 128, 67, 73, 69, 80, 128, 67, 73, 69, 128, 67, 72, + 89, 88, 128, 67, 72, 89, 84, 128, 67, 72, 89, 82, 88, 128, 67, 72, 89, + 82, 128, 67, 72, 89, 80, 128, 67, 72, 87, 86, 128, 67, 72, 85, 88, 128, + 67, 72, 85, 82, 88, 128, 67, 72, 85, 82, 67, 72, 128, 67, 72, 85, 82, + 128, 67, 72, 85, 80, 128, 67, 72, 85, 79, 88, 128, 67, 72, 85, 79, 84, + 128, 67, 72, 85, 79, 80, 128, 67, 72, 85, 79, 128, 67, 72, 85, 76, 65, + 128, 67, 72, 85, 128, 67, 72, 82, 89, 83, 65, 78, 84, 72, 69, 77, 85, 77, + 128, 67, 72, 82, 79, 78, 79, 85, 128, 67, 72, 82, 79, 78, 79, 78, 128, + 67, 72, 82, 79, 77, 193, 67, 72, 82, 79, 193, 67, 72, 82, 73, 86, 73, + 128, 67, 72, 82, 73, 83, 84, 77, 65, 83, 128, 67, 72, 82, 73, 83, 84, 77, + 65, 211, 67, 72, 79, 89, 128, 67, 72, 79, 88, 128, 67, 72, 79, 84, 128, + 67, 72, 79, 82, 69, 86, 77, 193, 67, 72, 79, 82, 65, 83, 77, 73, 65, 206, + 67, 72, 79, 80, 83, 84, 73, 67, 75, 83, 128, 67, 72, 79, 80, 128, 67, 72, + 79, 75, 69, 128, 67, 72, 79, 69, 128, 67, 72, 79, 67, 79, 76, 65, 84, + 197, 67, 72, 79, 65, 128, 67, 72, 73, 84, 85, 69, 85, 77, 83, 83, 65, 78, + 71, 83, 73, 79, 83, 128, 67, 72, 73, 84, 85, 69, 85, 77, 83, 83, 65, 78, + 71, 67, 73, 69, 85, 67, 128, 67, 72, 73, 84, 85, 69, 85, 77, 83, 73, 79, + 83, 128, 67, 72, 73, 84, 85, 69, 85, 77, 67, 73, 69, 85, 67, 128, 67, 72, + 73, 84, 85, 69, 85, 77, 67, 72, 73, 69, 85, 67, 72, 128, 67, 72, 73, 82, + 79, 78, 128, 67, 72, 73, 82, 69, 84, 128, 67, 72, 73, 80, 77, 85, 78, 75, + 128, 67, 72, 73, 78, 79, 79, 203, 67, 72, 73, 78, 71, 128, 67, 72, 73, + 78, 69, 83, 197, 67, 72, 73, 78, 128, 67, 72, 73, 77, 69, 128, 67, 72, + 73, 77, 128, 67, 72, 73, 76, 76, 213, 67, 72, 73, 76, 68, 82, 69, 206, + 67, 72, 73, 76, 68, 128, 67, 72, 73, 76, 128, 67, 72, 73, 75, 201, 67, + 72, 73, 69, 85, 67, 72, 45, 75, 72, 73, 69, 85, 75, 72, 128, 67, 72, 73, + 69, 85, 67, 72, 45, 72, 73, 69, 85, 72, 128, 67, 72, 73, 69, 85, 67, 200, + 67, 72, 73, 67, 75, 69, 78, 128, 67, 72, 73, 67, 75, 128, 67, 72, 73, + 128, 67, 72, 201, 67, 72, 72, 73, 77, 128, 67, 72, 72, 65, 128, 67, 72, + 69, 88, 128, 67, 72, 69, 86, 82, 79, 78, 128, 67, 72, 69, 86, 82, 79, + 206, 67, 72, 69, 84, 128, 67, 72, 69, 83, 84, 78, 85, 84, 128, 67, 72, + 69, 83, 84, 128, 67, 72, 69, 83, 211, 67, 72, 69, 82, 89, 128, 67, 72, + 69, 82, 82, 217, 67, 72, 69, 82, 82, 73, 69, 83, 128, 67, 72, 69, 81, 85, + 69, 82, 69, 196, 67, 72, 69, 80, 128, 67, 72, 69, 76, 89, 85, 83, 84, 75, + 65, 128, 67, 72, 69, 76, 78, 85, 128, 67, 72, 69, 73, 78, 65, 80, 128, + 67, 72, 69, 73, 75, 72, 69, 73, 128, 67, 72, 69, 73, 75, 72, 65, 78, 128, + 67, 72, 69, 69, 83, 197, 67, 72, 69, 69, 82, 73, 78, 199, 67, 72, 69, 69, + 77, 128, 67, 72, 69, 69, 75, 211, 67, 72, 69, 69, 75, 128, 67, 72, 69, + 69, 128, 67, 72, 69, 67, 75, 69, 210, 67, 72, 69, 67, 75, 128, 67, 72, + 69, 67, 203, 67, 72, 197, 67, 72, 65, 88, 128, 67, 72, 65, 86, 73, 89, + 65, 78, 73, 128, 67, 72, 65, 84, 84, 65, 87, 65, 128, 67, 72, 65, 84, + 128, 67, 72, 65, 83, 72, 75, 65, 128, 67, 72, 65, 83, 72, 75, 193, 67, + 72, 65, 82, 84, 128, 67, 72, 65, 82, 212, 67, 72, 65, 82, 73, 79, 84, + 128, 67, 72, 65, 82, 73, 79, 212, 67, 72, 65, 82, 65, 67, 84, 69, 82, 83, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 70, 66, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 70, 65, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 70, 57, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 50, 70, 56, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 50, 70, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 50, 70, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 50, 70, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, + 70, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 70, 51, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 70, 50, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 70, 49, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 70, 48, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 50, 69, 70, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 50, 69, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 50, 69, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 50, 69, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, + 69, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 69, 65, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 69, 57, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 69, 56, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 69, 55, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 50, 69, 54, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 50, 69, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 50, 69, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 50, 69, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, + 69, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 69, 49, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 69, 48, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 68, 70, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 68, 69, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 50, 68, 68, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 50, 68, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 50, 68, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 50, 68, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, + 68, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 68, 56, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 68, 55, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 68, 54, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 68, 53, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 50, 68, 52, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 50, 68, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 50, 68, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 50, 68, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, + 68, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 67, 70, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 67, 69, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 67, 68, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 67, 67, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 50, 67, 66, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 50, 67, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 50, 67, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 50, 67, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, + 67, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 67, 54, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 67, 53, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 67, 52, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 67, 51, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 50, 67, 50, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 50, 67, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 50, 67, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 50, 66, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, + 66, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 66, 68, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 66, 67, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 66, 66, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 66, 65, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 50, 66, 57, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 50, 66, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 50, 66, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 50, 66, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, + 66, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 66, 52, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 66, 51, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 66, 50, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 66, 49, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 50, 66, 48, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 50, 65, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 50, 65, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 50, 65, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, + 65, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 65, 66, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 65, 65, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 65, 57, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 65, 56, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 50, 65, 55, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 50, 65, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 50, 65, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 50, 65, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, + 65, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 65, 50, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 65, 49, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 65, 48, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 57, 70, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 50, 57, 69, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 50, 57, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 50, 57, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 50, 57, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, + 57, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 57, 57, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 57, 56, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 57, 55, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 57, 54, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 50, 57, 53, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 50, 57, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 50, 57, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 50, 57, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, + 57, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 57, 48, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 56, 70, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 56, 69, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 56, 68, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 50, 56, 67, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 50, 56, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 50, 56, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 50, 56, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, + 56, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 56, 55, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 56, 54, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 56, 53, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 56, 52, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 50, 56, 51, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 50, 56, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 50, 56, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 50, 56, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, + 55, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 55, 69, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 55, 68, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 55, 67, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 55, 66, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 50, 55, 65, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 50, 55, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 50, 55, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 50, 55, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, + 55, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 55, 53, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 55, 52, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 55, 51, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 55, 50, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 50, 55, 49, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 50, 55, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 50, 54, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 50, 54, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, + 54, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 54, 67, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 54, 66, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 54, 65, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 54, 57, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 50, 54, 56, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 50, 54, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 50, 54, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 50, 54, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, + 54, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 54, 51, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 54, 50, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 54, 49, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 54, 48, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 50, 53, 70, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 50, 53, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 50, 53, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 50, 53, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, + 53, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 53, 65, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 53, 57, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 53, 56, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 53, 55, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 50, 53, 54, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 50, 53, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 50, 53, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 50, 53, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, + 53, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 53, 49, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 53, 48, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 52, 70, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 52, 69, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 50, 52, 68, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 50, 52, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 50, 52, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 50, 52, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, + 52, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 52, 56, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 52, 55, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 52, 54, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 52, 53, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 50, 52, 52, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 50, 52, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 50, 52, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 50, 52, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, + 52, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 51, 70, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 51, 69, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 51, 68, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 51, 67, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 50, 51, 66, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 50, 51, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 50, 51, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 50, 51, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, + 51, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 51, 54, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 51, 53, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 51, 52, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 51, 51, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 50, 51, 50, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 50, 51, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 50, 51, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 50, 50, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, + 50, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 50, 68, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 50, 67, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 50, 66, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 50, 65, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 50, 50, 57, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 50, 50, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 50, 50, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 50, 50, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, + 50, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 50, 52, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 50, 51, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 50, 50, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 50, 49, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 50, 50, 48, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 50, 49, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 50, 49, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 50, 49, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, + 49, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 49, 66, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 49, 65, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 49, 57, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 49, 56, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 50, 49, 55, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 50, 49, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 50, 49, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 50, 49, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, + 49, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 49, 50, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 49, 49, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 49, 48, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 48, 70, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 50, 48, 69, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 50, 48, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 50, 48, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 50, 48, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, + 48, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 48, 57, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 48, 56, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 48, 55, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 48, 54, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 50, 48, 53, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 50, 48, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 50, 48, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 50, 48, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, + 48, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 50, 48, 48, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 70, 70, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 70, 69, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 70, 68, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 49, 70, 67, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 49, 70, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 49, 70, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 49, 70, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, + 70, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 70, 55, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 70, 54, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 70, 53, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 70, 52, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 49, 70, 51, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 49, 70, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 49, 70, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 49, 70, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, + 69, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 69, 69, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 69, 68, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 69, 67, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 69, 66, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 49, 69, 65, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 49, 69, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 49, 69, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 49, 69, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, + 69, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 69, 53, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 69, 52, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 69, 51, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 69, 50, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 49, 69, 49, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 49, 69, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 49, 68, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 49, 68, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, + 68, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 68, 67, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 68, 66, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 68, 65, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 68, 57, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 49, 68, 56, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 49, 68, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 49, 68, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 49, 68, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, + 68, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 68, 51, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 68, 50, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 68, 49, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 68, 48, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 49, 67, 70, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 49, 67, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 49, 67, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 49, 67, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, + 67, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 67, 65, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 67, 57, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 67, 56, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 67, 55, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 49, 67, 54, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 49, 67, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 49, 67, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 49, 67, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, + 67, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 67, 49, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 67, 48, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 66, 70, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 66, 69, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 49, 66, 68, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 49, 66, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 49, 66, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 49, 66, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, + 66, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 66, 56, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 66, 55, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 66, 54, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 66, 53, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 49, 66, 52, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 49, 66, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 49, 66, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 49, 66, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, + 66, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 65, 70, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 65, 69, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 65, 68, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 65, 67, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 49, 65, 66, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 49, 65, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 49, 65, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 49, 65, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, + 65, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 65, 54, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 65, 53, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 65, 52, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 65, 51, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 49, 65, 50, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 49, 65, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 49, 65, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 49, 57, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, + 57, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 57, 68, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 57, 67, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 57, 66, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 57, 65, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 49, 57, 57, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 49, 57, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 49, 57, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 49, 57, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, + 57, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 57, 52, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 57, 51, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 57, 50, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 57, 49, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 49, 57, 48, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 49, 56, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 49, 56, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 49, 56, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, + 56, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 56, 66, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 56, 65, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 56, 57, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 56, 56, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 49, 56, 55, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 49, 56, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 49, 56, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 49, 56, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, + 56, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 56, 50, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 56, 49, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 56, 48, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 55, 70, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 49, 55, 69, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 49, 55, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 49, 55, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 49, 55, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, + 55, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 55, 57, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 55, 56, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 55, 55, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 55, 54, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 66, 49, 55, 53, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 66, 49, 55, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 66, 49, 55, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 66, 49, 55, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, + 55, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 66, 49, 55, 48, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 68, 53, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 68, 52, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 68, 51, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 67, 68, 50, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 67, 68, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 67, 68, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 67, 67, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, + 67, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 67, 68, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 67, 67, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 67, 66, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 67, 65, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 67, 67, 57, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 67, 67, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 67, 67, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 67, 67, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, + 67, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 67, 52, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 67, 51, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 67, 50, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 67, 49, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 67, 67, 48, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 67, 66, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 67, 66, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 67, 66, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, + 66, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 66, 66, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 66, 65, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 66, 57, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 66, 56, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 67, 66, 55, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 67, 66, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 67, 66, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 67, 66, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, + 66, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 66, 50, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 66, 49, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 66, 48, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 65, 70, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 67, 65, 69, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 67, 65, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 67, 65, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 67, 65, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, + 65, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 65, 57, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 65, 56, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 65, 55, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 65, 54, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 67, 65, 53, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 67, 65, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 67, 65, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 67, 65, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, + 65, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 65, 48, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 57, 70, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 57, 69, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 57, 68, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 67, 57, 67, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 67, 57, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 67, 57, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 67, 57, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, + 57, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 57, 55, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 57, 54, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 57, 53, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 57, 52, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 67, 57, 51, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 67, 57, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 67, 57, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 67, 57, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, + 56, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 56, 69, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 56, 68, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 56, 67, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 56, 66, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 67, 56, 65, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 67, 56, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 67, 56, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 67, 56, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, + 56, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 56, 53, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 56, 52, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 56, 51, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 56, 50, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 67, 56, 49, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 67, 56, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 67, 55, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 67, 55, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, + 55, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 55, 67, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 55, 66, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 55, 65, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 55, 57, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 67, 55, 56, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 67, 55, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 67, 55, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 67, 55, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, + 55, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 55, 51, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 55, 50, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 55, 49, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 55, 48, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 67, 54, 70, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 67, 54, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 67, 54, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 67, 54, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, + 54, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 54, 65, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 54, 57, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 54, 56, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 54, 55, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 67, 54, 54, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 67, 54, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 67, 54, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 67, 54, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, + 54, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 54, 49, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 54, 48, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 53, 70, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 53, 69, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 67, 53, 68, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 67, 53, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 67, 53, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 67, 53, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, + 53, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 53, 56, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 53, 55, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 53, 54, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 53, 53, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 67, 53, 52, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 67, 53, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 67, 53, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 67, 53, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, + 53, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 52, 70, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 52, 69, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 52, 68, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 52, 67, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 67, 52, 66, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 67, 52, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 67, 52, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 67, 52, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, + 52, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 52, 54, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 52, 53, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 52, 52, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 52, 51, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 67, 52, 50, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 67, 52, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 67, 52, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 67, 51, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, + 51, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 51, 68, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 51, 67, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 51, 66, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 51, 65, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 67, 51, 57, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 67, 51, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 67, 51, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 67, 51, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, + 51, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 51, 52, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 51, 51, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 51, 50, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 51, 49, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 67, 51, 48, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 67, 50, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 67, 50, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 67, 50, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, + 50, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 50, 66, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 50, 65, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 50, 57, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 50, 56, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 67, 50, 55, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 67, 50, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 67, 50, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 67, 50, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, + 50, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 50, 50, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 50, 49, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 50, 48, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 49, 70, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 67, 49, 69, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 67, 49, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 67, 49, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 67, 49, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, + 49, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 49, 57, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 49, 56, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 49, 55, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 49, 54, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 67, 49, 53, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 67, 49, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 67, 49, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 67, 49, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, + 49, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 49, 48, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 48, 70, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 48, 69, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 48, 68, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 67, 48, 67, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 67, 48, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 67, 48, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 67, 48, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, + 48, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 48, 55, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 48, 54, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 48, 53, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 67, 48, 52, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 67, 48, 51, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 67, 48, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 67, 48, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 67, 48, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, + 70, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 70, 69, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 70, 68, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 70, 67, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 70, 66, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 66, 70, 65, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 66, 70, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 66, 70, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 66, 70, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, + 70, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 70, 53, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 70, 52, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 70, 51, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 70, 50, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 66, 70, 49, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 66, 70, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 66, 69, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 66, 69, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, + 69, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 69, 67, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 69, 66, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 69, 65, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 69, 57, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 66, 69, 56, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 66, 69, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 66, 69, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 66, 69, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, + 69, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 69, 51, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 69, 50, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 69, 49, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 69, 48, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 66, 68, 70, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 66, 68, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 66, 68, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 66, 68, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, + 68, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 68, 65, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 68, 57, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 68, 56, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 68, 55, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 66, 68, 54, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 66, 68, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 66, 68, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 66, 68, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, + 68, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 68, 49, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 68, 48, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 67, 70, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 67, 69, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 66, 67, 68, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 66, 67, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 66, 67, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 66, 67, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, + 67, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 67, 56, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 67, 55, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 67, 54, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 67, 53, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 66, 67, 52, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 66, 67, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 66, 67, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 66, 67, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, + 67, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 66, 70, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 66, 69, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 66, 68, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 66, 67, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 66, 66, 66, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 66, 66, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 66, 66, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 66, 66, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, + 66, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 66, 54, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 66, 53, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 66, 52, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 66, 51, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 66, 66, 50, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 66, 66, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 66, 66, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 66, 65, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, + 65, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 65, 68, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 65, 67, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 65, 66, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 65, 65, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 66, 65, 57, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 66, 65, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 66, 65, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 66, 65, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, + 65, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 65, 52, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 65, 51, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 65, 50, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 65, 49, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 66, 65, 48, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 66, 57, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 66, 57, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 66, 57, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, + 57, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 57, 66, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 57, 65, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 57, 57, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 57, 56, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 66, 57, 55, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 66, 57, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 66, 57, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 66, 57, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, + 57, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 57, 50, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 57, 49, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 57, 48, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 56, 70, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 66, 56, 69, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 66, 56, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 66, 56, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 66, 56, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, + 56, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 56, 57, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 56, 56, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 56, 55, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 56, 54, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 66, 56, 53, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 66, 56, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 66, 56, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 66, 56, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, + 56, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 56, 48, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 55, 70, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 55, 69, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 55, 68, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 66, 55, 67, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 66, 55, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 66, 55, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 66, 55, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, + 55, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 55, 55, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 55, 54, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 55, 53, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 55, 52, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 66, 55, 51, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 66, 55, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 66, 55, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 66, 55, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, + 54, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 54, 69, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 54, 68, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 54, 67, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 54, 66, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 66, 54, 65, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 66, 54, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 66, 54, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 66, 54, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, + 54, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 54, 53, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 54, 52, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 54, 51, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 54, 50, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 66, 54, 49, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 66, 54, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 66, 53, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 66, 53, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, + 53, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 53, 67, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 53, 66, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 53, 65, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 53, 57, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 66, 53, 56, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 66, 53, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 66, 53, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 66, 53, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, + 53, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 53, 51, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 53, 50, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 53, 49, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 53, 48, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 66, 52, 70, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 66, 52, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 66, 52, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 66, 52, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, + 52, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 52, 65, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 52, 57, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 52, 56, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 52, 55, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 66, 52, 54, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 66, 52, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 66, 52, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 66, 52, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, + 52, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 52, 49, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 52, 48, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 51, 70, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 51, 69, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 66, 51, 68, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 66, 51, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 66, 51, 66, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 66, 51, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, + 51, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 51, 56, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 51, 55, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 51, 54, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 51, 53, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 66, 51, 52, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 66, 51, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 66, 51, 50, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 66, 51, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, + 51, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 50, 70, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 50, 69, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 50, 68, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 50, 67, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 66, 50, 66, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 66, 50, 65, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 66, 50, 57, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 66, 50, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, + 50, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 50, 54, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 50, 53, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 50, 52, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 50, 51, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 66, 50, 50, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 66, 50, 49, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 66, 50, 48, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 66, 49, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, + 49, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 49, 68, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 49, 67, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 49, 66, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 49, 65, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 66, 49, 57, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 66, 49, 56, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 66, 49, 55, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 66, 49, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, + 49, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 49, 52, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 49, 51, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 49, 50, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 49, 49, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 66, 49, 48, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 66, 48, 70, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 66, 48, 69, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 66, 48, 68, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, + 48, 67, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 48, 66, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 48, 65, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 48, 57, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 48, 56, 128, 67, 72, 65, 82, 65, + 67, 84, 69, 82, 45, 49, 56, 66, 48, 55, 128, 67, 72, 65, 82, 65, 67, 84, + 69, 82, 45, 49, 56, 66, 48, 54, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, + 45, 49, 56, 66, 48, 53, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, + 56, 66, 48, 52, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, + 48, 51, 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 48, 50, + 128, 67, 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 48, 49, 128, 67, + 72, 65, 82, 65, 67, 84, 69, 82, 45, 49, 56, 66, 48, 48, 128, 67, 72, 65, + 82, 65, 67, 84, 69, 82, 128, 67, 72, 65, 82, 65, 67, 84, 69, 210, 67, 72, + 65, 82, 128, 67, 72, 65, 80, 84, 69, 82, 128, 67, 72, 65, 80, 128, 67, + 72, 65, 78, 71, 128, 67, 72, 65, 78, 128, 67, 72, 65, 77, 75, 79, 128, + 67, 72, 65, 77, 73, 76, 79, 78, 128, 67, 72, 65, 77, 73, 76, 73, 128, 67, + 72, 65, 205, 67, 72, 65, 75, 77, 193, 67, 72, 65, 73, 78, 83, 128, 67, + 72, 65, 68, 65, 128, 67, 72, 65, 196, 67, 72, 65, 65, 128, 67, 71, 74, + 128, 67, 69, 88, 128, 67, 69, 86, 73, 84, 85, 128, 67, 69, 82, 69, 83, + 128, 67, 69, 82, 69, 77, 79, 78, 89, 128, 67, 69, 82, 69, 75, 128, 67, + 69, 82, 45, 87, 65, 128, 67, 69, 80, 128, 67, 69, 79, 78, 71, 67, 72, 73, + 69, 85, 77, 83, 83, 65, 78, 71, 83, 73, 79, 83, 128, 67, 69, 79, 78, 71, + 67, 72, 73, 69, 85, 77, 83, 83, 65, 78, 71, 67, 73, 69, 85, 67, 128, 67, + 69, 79, 78, 71, 67, 72, 73, 69, 85, 77, 83, 73, 79, 83, 128, 67, 69, 79, + 78, 71, 67, 72, 73, 69, 85, 77, 67, 73, 69, 85, 67, 128, 67, 69, 79, 78, + 71, 67, 72, 73, 69, 85, 77, 67, 72, 73, 69, 85, 67, 72, 128, 67, 69, 78, + 84, 85, 82, 73, 65, 204, 67, 69, 78, 84, 82, 69, 76, 73, 78, 197, 67, 69, + 78, 84, 82, 69, 68, 128, 67, 69, 78, 84, 82, 69, 196, 67, 69, 78, 84, 82, + 69, 128, 67, 69, 78, 84, 82, 197, 67, 69, 78, 84, 82, 65, 76, 73, 90, 65, + 84, 73, 79, 206, 67, 69, 78, 128, 67, 69, 76, 84, 73, 195, 67, 69, 76, + 83, 73, 85, 83, 128, 67, 69, 76, 69, 66, 82, 65, 84, 73, 79, 78, 128, 67, + 69, 73, 82, 84, 128, 67, 69, 73, 76, 73, 78, 71, 128, 67, 69, 73, 76, 73, + 78, 199, 67, 69, 69, 86, 128, 67, 69, 69, 66, 128, 67, 69, 69, 128, 67, + 69, 68, 73, 76, 76, 65, 128, 67, 69, 68, 73, 76, 76, 193, 67, 69, 68, + 201, 67, 69, 67, 69, 75, 128, 67, 69, 67, 65, 75, 128, 67, 69, 67, 65, + 203, 67, 69, 65, 76, 67, 128, 67, 67, 85, 128, 67, 67, 79, 128, 67, 67, + 73, 128, 67, 67, 72, 85, 128, 67, 67, 72, 79, 128, 67, 67, 72, 73, 128, + 67, 67, 72, 72, 85, 128, 67, 67, 72, 72, 79, 128, 67, 67, 72, 72, 73, + 128, 67, 67, 72, 72, 69, 69, 128, 67, 67, 72, 72, 69, 128, 67, 67, 72, + 72, 65, 65, 128, 67, 67, 72, 72, 65, 128, 67, 67, 72, 69, 69, 128, 67, + 67, 72, 69, 128, 67, 67, 72, 65, 65, 128, 67, 67, 72, 65, 128, 67, 67, + 72, 128, 67, 67, 69, 69, 128, 67, 67, 65, 65, 128, 67, 65, 89, 78, 128, + 67, 65, 89, 65, 78, 78, 65, 128, 67, 65, 88, 128, 67, 65, 86, 69, 128, + 67, 65, 85, 84, 73, 79, 206, 67, 65, 85, 76, 68, 82, 79, 78, 128, 67, 65, + 85, 68, 65, 84, 197, 67, 65, 85, 68, 65, 128, 67, 65, 85, 67, 65, 83, 73, + 65, 206, 67, 65, 85, 128, 67, 65, 84, 65, 87, 65, 128, 67, 65, 84, 128, + 67, 65, 212, 67, 65, 83, 84, 76, 69, 128, 67, 65, 83, 75, 69, 212, 67, + 65, 82, 89, 83, 84, 73, 65, 206, 67, 65, 82, 84, 87, 72, 69, 69, 76, 128, + 67, 65, 82, 84, 82, 73, 68, 71, 69, 128, 67, 65, 82, 84, 128, 67, 65, 82, + 211, 67, 65, 82, 82, 79, 84, 128, 67, 65, 82, 82, 73, 65, 71, 197, 67, + 65, 82, 80, 69, 78, 84, 82, 217, 67, 65, 82, 208, 67, 65, 82, 79, 85, 83, + 69, 204, 67, 65, 82, 79, 78, 128, 67, 65, 82, 79, 206, 67, 65, 82, 73, + 203, 67, 65, 82, 73, 65, 206, 67, 65, 82, 69, 84, 128, 67, 65, 82, 69, + 212, 67, 65, 82, 197, 67, 65, 82, 68, 83, 128, 67, 65, 82, 196, 67, 65, + 82, 128, 67, 65, 210, 67, 65, 80, 85, 212, 67, 65, 80, 84, 73, 86, 69, + 128, 67, 65, 80, 82, 73, 67, 79, 82, 78, 128, 67, 65, 80, 80, 69, 196, + 67, 65, 80, 79, 128, 67, 65, 80, 73, 84, 85, 76, 85, 77, 128, 67, 65, 80, + 73, 84, 65, 76, 128, 67, 65, 78, 84, 73, 76, 76, 65, 84, 73, 79, 206, 67, + 65, 78, 79, 69, 128, 67, 65, 78, 78, 79, 78, 128, 67, 65, 78, 78, 69, + 196, 67, 65, 78, 199, 67, 65, 78, 69, 128, 67, 65, 78, 68, 89, 128, 67, + 65, 78, 68, 82, 65, 66, 73, 78, 68, 85, 128, 67, 65, 78, 68, 82, 65, 66, + 73, 78, 68, 213, 67, 65, 78, 68, 82, 65, 128, 67, 65, 78, 68, 82, 193, + 67, 65, 78, 68, 76, 69, 128, 67, 65, 78, 67, 69, 82, 128, 67, 65, 78, 67, + 69, 76, 76, 65, 84, 73, 79, 206, 67, 65, 78, 67, 69, 76, 128, 67, 65, 78, + 67, 69, 204, 67, 65, 78, 128, 67, 65, 77, 80, 73, 78, 71, 128, 67, 65, + 77, 78, 85, 195, 67, 65, 77, 69, 82, 65, 128, 67, 65, 77, 69, 82, 193, + 67, 65, 77, 69, 76, 128, 67, 65, 76, 89, 65, 128, 67, 65, 76, 89, 193, + 67, 65, 76, 88, 128, 67, 65, 76, 76, 128, 67, 65, 76, 204, 67, 65, 76, + 69, 78, 68, 65, 82, 128, 67, 65, 76, 69, 78, 68, 65, 210, 67, 65, 76, 67, + 85, 76, 65, 84, 79, 82, 128, 67, 65, 76, 67, 128, 67, 65, 75, 82, 65, + 128, 67, 65, 75, 197, 67, 65, 73, 128, 67, 65, 72, 128, 67, 65, 69, 83, + 85, 82, 65, 128, 67, 65, 68, 85, 67, 69, 85, 83, 128, 67, 65, 68, 193, + 67, 65, 67, 84, 85, 83, 128, 67, 65, 66, 76, 69, 87, 65, 89, 128, 67, 65, + 66, 73, 78, 69, 84, 128, 67, 65, 66, 66, 65, 71, 69, 45, 84, 82, 69, 69, + 128, 67, 65, 65, 78, 71, 128, 67, 65, 65, 73, 128, 67, 193, 67, 48, 50, + 52, 128, 67, 48, 50, 51, 128, 67, 48, 50, 50, 128, 67, 48, 50, 49, 128, + 67, 48, 50, 48, 128, 67, 48, 49, 57, 128, 67, 48, 49, 56, 128, 67, 48, + 49, 55, 128, 67, 48, 49, 54, 128, 67, 48, 49, 53, 128, 67, 48, 49, 52, + 128, 67, 48, 49, 51, 128, 67, 48, 49, 50, 128, 67, 48, 49, 49, 128, 67, + 48, 49, 48, 65, 128, 67, 48, 49, 48, 128, 67, 48, 48, 57, 128, 67, 48, + 48, 56, 128, 67, 48, 48, 55, 128, 67, 48, 48, 54, 128, 67, 48, 48, 53, + 128, 67, 48, 48, 52, 128, 67, 48, 48, 51, 128, 67, 48, 48, 50, 67, 128, + 67, 48, 48, 50, 66, 128, 67, 48, 48, 50, 65, 128, 67, 48, 48, 50, 128, + 67, 48, 48, 49, 128, 67, 45, 83, 73, 77, 80, 76, 73, 70, 73, 69, 196, 67, + 45, 51, 57, 128, 67, 45, 49, 56, 128, 66, 90, 85, 78, 199, 66, 90, 72, + 201, 66, 89, 84, 197, 66, 89, 69, 76, 79, 82, 85, 83, 83, 73, 65, 78, 45, + 85, 75, 82, 65, 73, 78, 73, 65, 206, 66, 88, 71, 128, 66, 87, 73, 128, + 66, 87, 69, 69, 128, 66, 87, 69, 128, 66, 87, 65, 128, 66, 85, 85, 77, + 73, 83, 72, 128, 66, 85, 84, 84, 79, 78, 128, 66, 85, 84, 84, 79, 206, + 66, 85, 84, 84, 69, 82, 70, 76, 89, 128, 66, 85, 84, 84, 69, 82, 128, 66, + 85, 212, 66, 85, 83, 84, 211, 66, 85, 83, 212, 66, 85, 83, 83, 89, 69, + 82, 85, 128, 66, 85, 83, 73, 78, 69, 83, 211, 66, 85, 211, 66, 85, 82, + 213, 66, 85, 82, 82, 73, 84, 79, 128, 66, 85, 82, 50, 128, 66, 85, 210, + 66, 85, 79, 89, 128, 66, 85, 79, 88, 128, 66, 85, 79, 80, 128, 66, 85, + 78, 78, 217, 66, 85, 78, 71, 128, 66, 85, 77, 80, 217, 66, 85, 76, 85, + 71, 128, 66, 85, 76, 85, 199, 66, 85, 76, 76, 83, 69, 89, 69, 128, 66, + 85, 76, 76, 211, 66, 85, 76, 76, 72, 79, 82, 78, 128, 66, 85, 76, 76, 72, + 79, 82, 206, 66, 85, 76, 76, 69, 84, 128, 66, 85, 76, 76, 69, 212, 66, + 85, 76, 76, 128, 66, 85, 76, 66, 128, 66, 85, 75, 89, 128, 66, 85, 73, + 76, 68, 73, 78, 71, 83, 128, 66, 85, 73, 76, 68, 73, 78, 71, 128, 66, 85, + 73, 76, 68, 73, 78, 199, 66, 85, 72, 73, 196, 66, 85, 71, 73, 78, 69, 83, + 197, 66, 85, 71, 128, 66, 85, 70, 70, 65, 76, 79, 128, 66, 85, 68, 128, + 66, 85, 67, 75, 76, 69, 128, 66, 85, 67, 75, 69, 84, 128, 66, 85, 66, 66, + 76, 69, 83, 128, 66, 85, 66, 66, 76, 69, 128, 66, 85, 66, 66, 76, 197, + 66, 83, 84, 65, 82, 128, 66, 83, 75, 85, 210, 66, 83, 75, 65, 173, 66, + 83, 68, 85, 211, 66, 82, 85, 83, 200, 66, 82, 79, 87, 206, 66, 82, 79, + 79, 77, 128, 66, 82, 79, 78, 90, 69, 128, 66, 82, 79, 75, 69, 206, 66, + 82, 79, 67, 67, 79, 76, 73, 128, 66, 82, 79, 65, 196, 66, 82, 73, 83, 84, + 76, 69, 128, 66, 82, 73, 71, 72, 84, 78, 69, 83, 211, 66, 82, 73, 69, 70, + 83, 128, 66, 82, 73, 69, 70, 67, 65, 83, 69, 128, 66, 82, 73, 68, 71, + 197, 66, 82, 73, 68, 197, 66, 82, 73, 67, 75, 128, 66, 82, 73, 128, 66, + 82, 69, 86, 73, 83, 128, 66, 82, 69, 86, 69, 45, 77, 65, 67, 82, 79, 78, + 128, 66, 82, 69, 86, 197, 66, 82, 69, 65, 84, 72, 217, 66, 82, 69, 65, + 84, 200, 66, 82, 69, 65, 83, 84, 45, 70, 69, 69, 68, 73, 78, 71, 128, 66, + 82, 69, 65, 75, 84, 72, 82, 79, 85, 71, 72, 128, 66, 82, 68, 193, 66, 82, + 65, 78, 67, 72, 73, 78, 199, 66, 82, 65, 78, 67, 72, 69, 83, 128, 66, 82, + 65, 78, 67, 72, 128, 66, 82, 65, 78, 67, 200, 66, 82, 65, 75, 67, 69, 84, + 128, 66, 82, 65, 73, 78, 128, 66, 82, 65, 67, 75, 69, 84, 211, 66, 82, + 65, 67, 75, 69, 84, 69, 196, 66, 82, 65, 67, 75, 69, 84, 128, 66, 82, 65, + 67, 75, 69, 212, 66, 82, 65, 67, 69, 128, 66, 81, 128, 66, 80, 72, 128, + 66, 79, 89, 211, 66, 79, 89, 128, 66, 79, 88, 73, 78, 199, 66, 79, 87, + 84, 73, 69, 128, 66, 79, 87, 84, 73, 197, 66, 79, 87, 76, 73, 78, 71, + 128, 66, 79, 87, 76, 128, 66, 79, 87, 204, 66, 79, 87, 73, 78, 199, 66, + 79, 215, 66, 79, 85, 81, 85, 69, 84, 128, 66, 79, 85, 81, 85, 69, 212, + 66, 79, 85, 78, 68, 65, 82, 217, 66, 79, 84, 84, 79, 77, 45, 83, 72, 65, + 68, 69, 196, 66, 79, 84, 84, 79, 77, 45, 76, 73, 71, 72, 84, 69, 196, 66, + 79, 84, 84, 79, 77, 128, 66, 79, 84, 84, 79, 205, 66, 79, 84, 84, 76, 69, + 128, 66, 79, 84, 84, 76, 197, 66, 79, 84, 200, 66, 79, 82, 90, 89, 128, + 66, 79, 82, 90, 65, 89, 65, 128, 66, 79, 82, 85, 84, 79, 128, 66, 79, 82, + 65, 88, 45, 51, 128, 66, 79, 82, 65, 88, 45, 50, 128, 66, 79, 82, 65, 88, + 128, 66, 79, 80, 79, 77, 79, 70, 207, 66, 79, 79, 84, 83, 128, 66, 79, + 79, 84, 128, 66, 79, 79, 77, 69, 82, 65, 78, 71, 128, 66, 79, 79, 75, 83, + 128, 66, 79, 79, 75, 77, 65, 82, 75, 128, 66, 79, 79, 75, 77, 65, 82, + 203, 66, 79, 78, 69, 128, 66, 79, 77, 66, 128, 66, 79, 77, 128, 66, 79, + 76, 84, 128, 66, 79, 76, 212, 66, 79, 72, 65, 73, 82, 73, 195, 66, 79, + 68, 89, 128, 66, 79, 68, 217, 66, 79, 65, 82, 128, 66, 79, 65, 128, 66, + 76, 85, 69, 66, 69, 82, 82, 73, 69, 83, 128, 66, 76, 85, 69, 128, 66, 76, + 85, 197, 66, 76, 79, 87, 73, 78, 199, 66, 76, 79, 87, 70, 73, 83, 72, + 128, 66, 76, 79, 215, 66, 76, 79, 83, 83, 79, 77, 128, 66, 76, 79, 79, + 68, 128, 66, 76, 79, 78, 196, 66, 76, 79, 67, 75, 45, 55, 128, 66, 76, + 79, 67, 75, 45, 54, 128, 66, 76, 79, 67, 75, 45, 53, 128, 66, 76, 79, 67, + 75, 45, 52, 128, 66, 76, 79, 67, 75, 45, 51, 128, 66, 76, 79, 67, 75, 45, + 50, 128, 66, 76, 79, 67, 75, 45, 49, 51, 53, 56, 128, 66, 76, 79, 67, 75, + 128, 66, 76, 73, 78, 203, 66, 76, 65, 78, 75, 128, 66, 76, 65, 78, 203, + 66, 76, 65, 68, 197, 66, 76, 65, 67, 75, 76, 69, 84, 84, 69, 210, 66, 76, + 65, 67, 75, 70, 79, 79, 212, 66, 76, 65, 67, 75, 45, 76, 69, 84, 84, 69, + 210, 66, 76, 65, 67, 75, 45, 70, 69, 65, 84, 72, 69, 82, 69, 196, 66, 76, + 65, 67, 75, 128, 66, 75, 65, 173, 66, 73, 84, 84, 69, 82, 128, 66, 73, + 84, 73, 78, 199, 66, 73, 84, 197, 66, 73, 84, 67, 79, 73, 206, 66, 73, + 83, 79, 78, 128, 66, 73, 83, 77, 85, 84, 200, 66, 73, 83, 77, 73, 76, 76, + 65, 200, 66, 73, 83, 72, 79, 208, 66, 73, 83, 69, 67, 84, 73, 78, 199, + 66, 73, 83, 65, 72, 128, 66, 73, 82, 85, 128, 66, 73, 82, 84, 72, 68, 65, + 217, 66, 73, 82, 71, 65, 128, 66, 73, 82, 71, 193, 66, 73, 82, 68, 128, + 66, 73, 79, 72, 65, 90, 65, 82, 196, 66, 73, 78, 79, 86, 73, 76, 69, 128, + 66, 73, 78, 79, 67, 85, 76, 65, 210, 66, 73, 78, 68, 73, 78, 199, 66, 73, + 78, 68, 73, 128, 66, 73, 78, 65, 82, 217, 66, 73, 76, 76, 73, 79, 78, 83, + 128, 66, 73, 76, 76, 73, 65, 82, 68, 83, 128, 66, 73, 76, 76, 69, 196, + 66, 73, 76, 65, 66, 73, 65, 204, 66, 73, 75, 73, 78, 73, 128, 66, 73, 71, + 128, 66, 73, 199, 66, 73, 69, 84, 128, 66, 73, 68, 69, 78, 84, 65, 204, + 66, 73, 68, 65, 75, 85, 79, 206, 66, 73, 67, 89, 67, 76, 73, 83, 84, 128, + 66, 73, 67, 89, 67, 76, 69, 83, 128, 66, 73, 67, 89, 67, 76, 69, 128, 66, + 73, 67, 69, 80, 83, 128, 66, 73, 66, 76, 69, 45, 67, 82, 69, 197, 66, 73, + 66, 128, 66, 201, 66, 72, 85, 128, 66, 72, 79, 79, 128, 66, 72, 79, 128, + 66, 72, 73, 128, 66, 72, 69, 84, 72, 128, 66, 72, 69, 69, 128, 66, 72, + 69, 128, 66, 72, 65, 84, 84, 73, 80, 82, 79, 76, 213, 66, 72, 65, 77, + 128, 66, 72, 65, 76, 69, 128, 66, 72, 65, 76, 197, 66, 72, 65, 73, 75, + 83, 85, 75, 201, 66, 72, 65, 65, 128, 66, 72, 65, 128, 66, 69, 89, 89, + 65, 76, 128, 66, 69, 88, 128, 66, 69, 86, 69, 82, 65, 71, 69, 128, 66, + 69, 86, 69, 82, 65, 71, 197, 66, 69, 84, 87, 69, 69, 78, 128, 66, 69, 84, + 87, 69, 69, 206, 66, 69, 84, 72, 128, 66, 69, 84, 65, 128, 66, 69, 84, + 193, 66, 69, 212, 66, 69, 83, 73, 68, 197, 66, 69, 82, 75, 65, 78, 65, + 206, 66, 69, 82, 66, 69, 210, 66, 69, 80, 128, 66, 69, 79, 82, 195, 66, + 69, 78, 90, 69, 78, 197, 66, 69, 78, 84, 207, 66, 69, 78, 84, 128, 66, + 69, 78, 212, 66, 69, 78, 71, 65, 76, 201, 66, 69, 78, 68, 69, 128, 66, + 69, 78, 68, 128, 66, 69, 78, 196, 66, 69, 206, 66, 69, 76, 84, 128, 66, + 69, 76, 212, 66, 69, 76, 79, 215, 66, 69, 76, 76, 72, 79, 208, 66, 69, + 76, 76, 128, 66, 69, 76, 204, 66, 69, 76, 71, 84, 72, 79, 210, 66, 69, + 73, 84, 72, 128, 66, 69, 72, 73, 78, 196, 66, 69, 72, 69, 72, 128, 66, + 69, 72, 69, 200, 66, 69, 72, 128, 66, 69, 200, 66, 69, 71, 73, 78, 78, + 73, 78, 71, 128, 66, 69, 71, 73, 78, 78, 69, 82, 128, 66, 69, 71, 73, 206, 66, 69, 70, 79, 82, 197, 66, 69, 69, 84, 76, 69, 128, 66, 69, 69, 84, 65, 128, 66, 69, 69, 210, 66, 69, 69, 72, 73, 86, 69, 128, 66, 69, 69, 72, 128, 66, 69, 69, 200, 66, 69, 67, 65, 85, 83, 69, 128, 66, 69, @@ -6729,10083 +6749,10122 @@ static const unsigned char lexicon[] = { 68, 69, 82, 77, 193, 65, 80, 76, 79, 85, 78, 128, 65, 80, 76, 201, 65, 80, 204, 65, 80, 73, 78, 128, 65, 80, 69, 83, 207, 65, 80, 67, 128, 65, 80, 65, 82, 84, 128, 65, 80, 65, 65, 84, 79, 128, 65, 79, 85, 128, 65, - 79, 82, 128, 65, 78, 85, 83, 86, 65, 82, 65, 89, 65, 128, 65, 78, 85, 83, - 86, 65, 82, 65, 128, 65, 78, 85, 83, 86, 65, 82, 193, 65, 78, 85, 68, 65, - 84, 84, 65, 128, 65, 78, 85, 68, 65, 84, 84, 193, 65, 78, 84, 73, 82, 69, - 83, 84, 82, 73, 67, 84, 73, 79, 78, 128, 65, 78, 84, 73, 77, 79, 78, 89, - 45, 50, 128, 65, 78, 84, 73, 77, 79, 78, 89, 128, 65, 78, 84, 73, 77, 79, - 78, 217, 65, 78, 84, 73, 77, 79, 78, 73, 65, 84, 69, 128, 65, 78, 84, 73, - 75, 69, 78, 79, 77, 65, 128, 65, 78, 84, 73, 75, 69, 78, 79, 75, 89, 76, - 73, 83, 77, 65, 128, 65, 78, 84, 73, 70, 79, 78, 73, 65, 128, 65, 78, 84, - 73, 67, 76, 79, 67, 75, 87, 73, 83, 69, 45, 82, 79, 84, 65, 84, 69, 196, - 65, 78, 84, 73, 67, 76, 79, 67, 75, 87, 73, 83, 69, 128, 65, 78, 84, 73, - 67, 76, 79, 67, 75, 87, 73, 83, 197, 65, 78, 84, 69, 78, 78, 65, 128, 65, - 78, 84, 69, 78, 78, 193, 65, 78, 84, 65, 82, 71, 79, 77, 85, 75, 72, 65, - 128, 65, 78, 83, 85, 218, 65, 78, 83, 72, 69, 128, 65, 78, 80, 69, 65, - 128, 65, 78, 207, 65, 78, 78, 85, 73, 84, 217, 65, 78, 78, 79, 84, 65, - 84, 73, 79, 206, 65, 78, 78, 65, 65, 85, 128, 65, 78, 75, 72, 128, 65, - 78, 74, 73, 128, 65, 78, 73, 77, 65, 76, 128, 65, 78, 72, 85, 78, 78, 65, - 128, 65, 78, 72, 85, 77, 65, 65, 128, 65, 78, 72, 85, 77, 128, 65, 78, - 72, 85, 128, 65, 78, 72, 65, 65, 128, 65, 78, 72, 128, 65, 78, 71, 85, - 76, 65, 82, 128, 65, 78, 71, 85, 73, 83, 72, 69, 196, 65, 78, 71, 83, 84, - 82, 79, 205, 65, 78, 71, 82, 217, 65, 78, 71, 76, 73, 67, 65, 78, 193, - 65, 78, 71, 76, 69, 68, 128, 65, 78, 71, 76, 69, 196, 65, 78, 71, 75, 72, - 65, 78, 75, 72, 85, 128, 65, 78, 71, 75, 65, 128, 65, 78, 71, 69, 210, - 65, 78, 71, 69, 76, 128, 65, 78, 71, 69, 68, 128, 65, 78, 68, 65, 80, - 128, 65, 78, 67, 79, 82, 65, 128, 65, 78, 67, 72, 79, 82, 128, 65, 78, - 65, 84, 82, 73, 67, 72, 73, 83, 77, 65, 128, 65, 78, 65, 84, 79, 77, 73, - 67, 65, 204, 65, 78, 65, 80, 128, 65, 78, 45, 78, 73, 83, 70, 128, 65, - 77, 85, 76, 69, 84, 128, 65, 77, 80, 83, 128, 65, 77, 80, 72, 79, 82, 65, - 128, 65, 77, 80, 69, 82, 83, 65, 78, 68, 128, 65, 77, 80, 69, 82, 83, 65, - 78, 196, 65, 77, 79, 85, 78, 212, 65, 77, 69, 82, 73, 67, 65, 83, 128, - 65, 77, 69, 82, 73, 67, 65, 206, 65, 77, 66, 85, 76, 65, 78, 67, 69, 128, - 65, 77, 66, 193, 65, 77, 66, 128, 65, 77, 65, 82, 128, 65, 77, 65, 210, - 65, 77, 65, 76, 71, 65, 77, 65, 84, 73, 79, 206, 65, 77, 65, 76, 71, 65, - 77, 128, 65, 76, 86, 69, 79, 76, 65, 210, 65, 76, 85, 77, 128, 65, 76, - 84, 69, 82, 78, 65, 84, 73, 86, 197, 65, 76, 84, 69, 82, 78, 65, 84, 73, - 79, 206, 65, 76, 84, 69, 82, 78, 65, 84, 73, 78, 71, 128, 65, 76, 84, 69, - 82, 78, 65, 84, 73, 78, 199, 65, 76, 84, 69, 82, 78, 65, 84, 69, 128, 65, - 76, 84, 69, 82, 78, 65, 84, 197, 65, 76, 84, 65, 128, 65, 76, 80, 72, 65, - 128, 65, 76, 80, 72, 193, 65, 76, 80, 65, 80, 82, 65, 78, 65, 128, 65, - 76, 80, 65, 80, 82, 65, 65, 78, 193, 65, 76, 80, 65, 128, 65, 76, 77, 79, - 83, 212, 65, 76, 76, 79, 128, 65, 76, 76, 73, 65, 78, 67, 69, 128, 65, - 76, 76, 201, 65, 76, 76, 65, 200, 65, 76, 76, 65, 65, 72, 128, 65, 76, - 75, 65, 76, 73, 45, 50, 128, 65, 76, 75, 65, 76, 73, 128, 65, 76, 73, 71, - 78, 69, 196, 65, 76, 73, 70, 85, 128, 65, 76, 73, 70, 128, 65, 76, 73, - 198, 65, 76, 73, 69, 78, 128, 65, 76, 73, 69, 206, 65, 76, 71, 73, 218, - 65, 76, 70, 65, 128, 65, 76, 69, 85, 212, 65, 76, 69, 82, 84, 128, 65, - 76, 69, 80, 72, 128, 65, 76, 69, 77, 66, 73, 67, 128, 65, 76, 69, 70, - 128, 65, 76, 66, 65, 78, 73, 65, 206, 65, 76, 65, 89, 78, 65, 65, 128, - 65, 76, 65, 89, 72, 73, 77, 65, 193, 65, 76, 65, 89, 72, 73, 205, 65, 76, - 65, 89, 72, 201, 65, 76, 65, 89, 72, 69, 128, 65, 76, 65, 89, 72, 197, - 65, 76, 65, 89, 72, 65, 193, 65, 76, 65, 82, 205, 65, 76, 65, 80, 72, - 128, 65, 76, 45, 76, 65, 75, 85, 78, 65, 128, 65, 76, 45, 74, 85, 90, - 128, 65, 75, 85, 82, 213, 65, 75, 84, 73, 69, 83, 69, 76, 83, 75, 65, 66, - 128, 65, 75, 83, 65, 128, 65, 75, 72, 77, 73, 77, 73, 195, 65, 75, 66, - 65, 210, 65, 75, 65, 82, 65, 128, 65, 75, 65, 82, 193, 65, 73, 89, 65, - 78, 78, 65, 128, 65, 73, 86, 73, 76, 73, 203, 65, 73, 86, 65, 128, 65, - 73, 84, 79, 206, 65, 73, 82, 80, 76, 65, 78, 69, 128, 65, 73, 82, 80, 76, - 65, 78, 197, 65, 73, 78, 213, 65, 73, 78, 78, 128, 65, 73, 76, 77, 128, - 65, 73, 75, 65, 82, 65, 128, 65, 73, 72, 86, 85, 83, 128, 65, 72, 83, 68, - 65, 128, 65, 72, 83, 65, 128, 65, 72, 79, 205, 65, 72, 65, 78, 199, 65, - 72, 65, 71, 71, 65, 210, 65, 72, 65, 68, 128, 65, 71, 85, 78, 71, 128, - 65, 71, 79, 71, 201, 65, 71, 71, 82, 65, 86, 65, 84, 73, 79, 78, 128, 65, - 71, 71, 82, 65, 86, 65, 84, 69, 196, 65, 71, 65, 73, 78, 83, 212, 65, 71, - 65, 73, 78, 128, 65, 70, 84, 69, 210, 65, 70, 83, 65, 65, 81, 128, 65, - 70, 82, 73, 67, 65, 206, 65, 70, 79, 82, 69, 77, 69, 78, 84, 73, 79, 78, - 69, 68, 128, 65, 70, 71, 72, 65, 78, 201, 65, 70, 70, 82, 73, 67, 65, 84, - 73, 79, 206, 65, 70, 70, 73, 216, 65, 69, 89, 65, 78, 78, 65, 128, 65, - 69, 89, 128, 65, 69, 83, 67, 85, 76, 65, 80, 73, 85, 83, 128, 65, 69, 83, - 67, 128, 65, 69, 83, 128, 65, 69, 82, 73, 65, 204, 65, 69, 82, 128, 65, - 69, 76, 65, 45, 80, 73, 76, 76, 65, 128, 65, 69, 76, 128, 65, 69, 75, - 128, 65, 69, 71, 69, 65, 206, 65, 69, 71, 128, 65, 69, 69, 89, 65, 78, - 78, 65, 128, 65, 69, 69, 128, 65, 69, 68, 65, 45, 80, 73, 76, 76, 65, - 128, 65, 69, 68, 128, 65, 69, 66, 128, 65, 68, 86, 65, 78, 84, 65, 71, - 69, 128, 65, 68, 86, 65, 78, 67, 69, 128, 65, 68, 85, 76, 84, 128, 65, - 68, 77, 73, 83, 83, 73, 79, 206, 65, 68, 77, 69, 84, 79, 83, 128, 65, 68, - 76, 65, 205, 65, 68, 72, 69, 83, 73, 86, 197, 65, 68, 69, 71, 128, 65, - 68, 69, 199, 65, 68, 68, 82, 69, 83, 83, 69, 196, 65, 68, 68, 82, 69, 83, - 211, 65, 68, 68, 65, 75, 128, 65, 68, 65, 203, 65, 67, 85, 84, 69, 45, - 77, 65, 67, 82, 79, 78, 128, 65, 67, 85, 84, 69, 45, 71, 82, 65, 86, 69, - 45, 65, 67, 85, 84, 69, 128, 65, 67, 85, 84, 197, 65, 67, 84, 85, 65, 76, - 76, 217, 65, 67, 84, 73, 86, 65, 84, 197, 65, 67, 82, 79, 80, 72, 79, 78, - 73, 195, 65, 67, 75, 78, 79, 87, 76, 69, 68, 71, 69, 128, 65, 67, 67, 85, - 77, 85, 76, 65, 84, 73, 79, 78, 128, 65, 67, 67, 79, 85, 78, 212, 65, 67, - 67, 79, 82, 68, 73, 79, 78, 128, 65, 67, 67, 79, 77, 77, 79, 68, 65, 84, - 73, 79, 78, 128, 65, 67, 67, 69, 80, 84, 128, 65, 67, 67, 69, 78, 84, 45, - 83, 84, 65, 67, 67, 65, 84, 79, 128, 65, 67, 67, 69, 78, 84, 128, 65, 67, - 67, 69, 78, 212, 65, 67, 65, 68, 69, 77, 217, 65, 66, 89, 83, 77, 65, - 204, 65, 66, 85, 78, 68, 65, 78, 67, 69, 128, 65, 66, 75, 72, 65, 83, 73, - 65, 206, 65, 66, 66, 82, 69, 86, 73, 65, 84, 73, 79, 206, 65, 66, 65, 70, - 73, 76, 73, 128, 65, 66, 65, 67, 85, 83, 128, 65, 66, 178, 65, 66, 49, - 57, 49, 128, 65, 66, 49, 56, 56, 128, 65, 66, 49, 56, 48, 128, 65, 66, - 49, 55, 49, 128, 65, 66, 49, 54, 52, 128, 65, 66, 49, 51, 49, 66, 128, - 65, 66, 49, 51, 49, 65, 128, 65, 66, 49, 50, 51, 128, 65, 66, 49, 50, 50, - 128, 65, 66, 49, 50, 48, 128, 65, 66, 49, 49, 56, 128, 65, 66, 48, 56, - 55, 128, 65, 66, 48, 56, 54, 128, 65, 66, 48, 56, 53, 128, 65, 66, 48, - 56, 50, 128, 65, 66, 48, 56, 49, 128, 65, 66, 48, 56, 48, 128, 65, 66, - 48, 55, 57, 128, 65, 66, 48, 55, 56, 128, 65, 66, 48, 55, 55, 128, 65, - 66, 48, 55, 54, 128, 65, 66, 48, 55, 52, 128, 65, 66, 48, 55, 51, 128, - 65, 66, 48, 55, 48, 128, 65, 66, 48, 54, 57, 128, 65, 66, 48, 54, 55, - 128, 65, 66, 48, 54, 54, 128, 65, 66, 48, 54, 53, 128, 65, 66, 48, 54, - 49, 128, 65, 66, 48, 54, 48, 128, 65, 66, 48, 53, 57, 128, 65, 66, 48, - 53, 56, 128, 65, 66, 48, 53, 55, 128, 65, 66, 48, 53, 54, 128, 65, 66, - 48, 53, 53, 128, 65, 66, 48, 53, 52, 128, 65, 66, 48, 53, 51, 128, 65, - 66, 48, 53, 49, 128, 65, 66, 48, 53, 48, 128, 65, 66, 48, 52, 57, 128, - 65, 66, 48, 52, 56, 128, 65, 66, 48, 52, 55, 128, 65, 66, 48, 52, 54, - 128, 65, 66, 48, 52, 53, 128, 65, 66, 48, 52, 52, 128, 65, 66, 48, 52, - 49, 128, 65, 66, 48, 52, 48, 128, 65, 66, 48, 51, 57, 128, 65, 66, 48, - 51, 56, 128, 65, 66, 48, 51, 55, 128, 65, 66, 48, 51, 52, 128, 65, 66, - 48, 51, 49, 128, 65, 66, 48, 51, 48, 128, 65, 66, 48, 50, 57, 128, 65, - 66, 48, 50, 56, 128, 65, 66, 48, 50, 55, 128, 65, 66, 48, 50, 54, 128, - 65, 66, 48, 50, 52, 128, 65, 66, 48, 50, 51, 77, 128, 65, 66, 48, 50, 51, - 128, 65, 66, 48, 50, 50, 77, 128, 65, 66, 48, 50, 50, 70, 128, 65, 66, - 48, 50, 50, 128, 65, 66, 48, 50, 49, 77, 128, 65, 66, 48, 50, 49, 70, - 128, 65, 66, 48, 50, 49, 128, 65, 66, 48, 50, 48, 128, 65, 66, 48, 49, - 55, 128, 65, 66, 48, 49, 54, 128, 65, 66, 48, 49, 51, 128, 65, 66, 48, - 49, 49, 128, 65, 66, 48, 49, 48, 128, 65, 66, 48, 48, 57, 128, 65, 66, - 48, 48, 56, 128, 65, 66, 48, 48, 55, 128, 65, 66, 48, 48, 54, 128, 65, - 66, 48, 48, 53, 128, 65, 66, 48, 48, 52, 128, 65, 66, 48, 48, 51, 128, - 65, 66, 48, 48, 50, 128, 65, 66, 48, 48, 49, 128, 65, 65, 90, 72, 65, 65, - 75, 75, 85, 128, 65, 65, 89, 73, 78, 128, 65, 65, 89, 65, 78, 78, 65, - 128, 65, 65, 89, 128, 65, 65, 87, 128, 65, 65, 79, 128, 65, 65, 74, 128, - 65, 65, 66, 65, 65, 70, 73, 76, 73, 128, 65, 65, 48, 51, 50, 128, 65, 65, - 48, 51, 49, 128, 65, 65, 48, 51, 48, 128, 65, 65, 48, 50, 57, 128, 65, - 65, 48, 50, 56, 128, 65, 65, 48, 50, 55, 128, 65, 65, 48, 50, 54, 128, - 65, 65, 48, 50, 53, 128, 65, 65, 48, 50, 52, 128, 65, 65, 48, 50, 51, - 128, 65, 65, 48, 50, 50, 128, 65, 65, 48, 50, 49, 128, 65, 65, 48, 50, - 48, 128, 65, 65, 48, 49, 57, 128, 65, 65, 48, 49, 56, 128, 65, 65, 48, - 49, 55, 128, 65, 65, 48, 49, 54, 128, 65, 65, 48, 49, 53, 128, 65, 65, - 48, 49, 52, 128, 65, 65, 48, 49, 51, 128, 65, 65, 48, 49, 50, 128, 65, - 65, 48, 49, 49, 128, 65, 65, 48, 49, 48, 128, 65, 65, 48, 48, 57, 128, - 65, 65, 48, 48, 56, 128, 65, 65, 48, 48, 55, 66, 128, 65, 65, 48, 48, 55, - 65, 128, 65, 65, 48, 48, 55, 128, 65, 65, 48, 48, 54, 128, 65, 65, 48, - 48, 53, 128, 65, 65, 48, 48, 52, 128, 65, 65, 48, 48, 51, 128, 65, 65, - 48, 48, 50, 128, 65, 65, 48, 48, 49, 128, 65, 56, 48, 55, 128, 65, 56, - 48, 54, 128, 65, 56, 48, 53, 128, 65, 56, 48, 52, 128, 65, 56, 48, 51, - 128, 65, 56, 48, 50, 128, 65, 56, 48, 49, 128, 65, 56, 48, 48, 128, 65, - 55, 51, 178, 65, 55, 50, 182, 65, 55, 49, 183, 65, 55, 49, 181, 65, 55, - 49, 180, 65, 55, 49, 179, 65, 55, 49, 178, 65, 55, 49, 177, 65, 55, 49, - 176, 65, 55, 48, 57, 45, 182, 65, 55, 48, 57, 45, 180, 65, 55, 48, 57, - 45, 179, 65, 55, 48, 57, 45, 178, 65, 55, 48, 185, 65, 55, 48, 184, 65, - 55, 48, 183, 65, 55, 48, 182, 65, 55, 48, 181, 65, 55, 48, 180, 65, 55, - 48, 179, 65, 55, 48, 178, 65, 55, 48, 177, 65, 54, 54, 52, 128, 65, 54, - 54, 51, 128, 65, 54, 54, 50, 128, 65, 54, 54, 49, 128, 65, 54, 54, 48, - 128, 65, 54, 53, 57, 128, 65, 54, 53, 56, 128, 65, 54, 53, 55, 128, 65, - 54, 53, 54, 128, 65, 54, 53, 53, 128, 65, 54, 53, 52, 128, 65, 54, 53, - 51, 128, 65, 54, 53, 50, 128, 65, 54, 53, 49, 128, 65, 54, 52, 57, 128, - 65, 54, 52, 56, 128, 65, 54, 52, 54, 128, 65, 54, 52, 53, 128, 65, 54, - 52, 52, 128, 65, 54, 52, 51, 128, 65, 54, 52, 50, 128, 65, 54, 52, 48, - 128, 65, 54, 51, 56, 128, 65, 54, 51, 55, 128, 65, 54, 51, 52, 128, 65, - 54, 50, 57, 128, 65, 54, 50, 56, 128, 65, 54, 50, 55, 128, 65, 54, 50, - 54, 128, 65, 54, 50, 52, 128, 65, 54, 50, 51, 128, 65, 54, 50, 50, 128, - 65, 54, 50, 49, 128, 65, 54, 50, 48, 128, 65, 54, 49, 57, 128, 65, 54, - 49, 56, 128, 65, 54, 49, 55, 128, 65, 54, 49, 54, 128, 65, 54, 49, 53, - 128, 65, 54, 49, 52, 128, 65, 54, 49, 51, 128, 65, 54, 49, 50, 128, 65, - 54, 49, 49, 128, 65, 54, 49, 48, 128, 65, 54, 48, 57, 128, 65, 54, 48, - 56, 128, 65, 54, 48, 54, 128, 65, 54, 48, 52, 128, 65, 54, 48, 51, 128, - 65, 54, 48, 50, 128, 65, 54, 48, 49, 128, 65, 54, 48, 48, 128, 65, 53, - 57, 56, 128, 65, 53, 57, 54, 128, 65, 53, 57, 53, 128, 65, 53, 57, 52, - 128, 65, 53, 57, 50, 128, 65, 53, 57, 49, 128, 65, 53, 56, 57, 128, 65, - 53, 56, 56, 128, 65, 53, 56, 55, 128, 65, 53, 56, 54, 128, 65, 53, 56, - 53, 128, 65, 53, 56, 52, 128, 65, 53, 56, 51, 128, 65, 53, 56, 50, 128, - 65, 53, 56, 49, 128, 65, 53, 56, 48, 128, 65, 53, 55, 57, 128, 65, 53, - 55, 56, 128, 65, 53, 55, 55, 128, 65, 53, 55, 54, 128, 65, 53, 55, 53, - 128, 65, 53, 55, 52, 128, 65, 53, 55, 51, 128, 65, 53, 55, 50, 128, 65, - 53, 55, 49, 128, 65, 53, 55, 48, 128, 65, 53, 54, 57, 128, 65, 53, 54, - 56, 128, 65, 53, 54, 54, 128, 65, 53, 54, 53, 128, 65, 53, 54, 52, 128, - 65, 53, 54, 51, 128, 65, 53, 53, 57, 128, 65, 53, 53, 55, 128, 65, 53, - 53, 54, 128, 65, 53, 53, 53, 128, 65, 53, 53, 52, 128, 65, 53, 53, 51, - 128, 65, 53, 53, 50, 128, 65, 53, 53, 49, 128, 65, 53, 53, 48, 128, 65, - 53, 52, 57, 128, 65, 53, 52, 56, 128, 65, 53, 52, 55, 128, 65, 53, 52, - 53, 128, 65, 53, 52, 50, 128, 65, 53, 52, 49, 128, 65, 53, 52, 48, 128, - 65, 53, 51, 57, 128, 65, 53, 51, 56, 128, 65, 53, 51, 55, 128, 65, 53, - 51, 54, 128, 65, 53, 51, 53, 128, 65, 53, 51, 52, 128, 65, 53, 51, 50, - 128, 65, 53, 51, 49, 128, 65, 53, 51, 48, 128, 65, 53, 50, 57, 128, 65, - 53, 50, 56, 128, 65, 53, 50, 55, 128, 65, 53, 50, 54, 128, 65, 53, 50, - 53, 128, 65, 53, 50, 52, 128, 65, 53, 50, 51, 128, 65, 53, 50, 50, 128, - 65, 53, 50, 49, 128, 65, 53, 50, 48, 128, 65, 53, 49, 57, 128, 65, 53, - 49, 56, 128, 65, 53, 49, 55, 128, 65, 53, 49, 54, 128, 65, 53, 49, 53, - 128, 65, 53, 49, 52, 128, 65, 53, 49, 51, 128, 65, 53, 49, 50, 128, 65, - 53, 49, 49, 128, 65, 53, 49, 48, 128, 65, 53, 48, 57, 128, 65, 53, 48, - 56, 128, 65, 53, 48, 55, 128, 65, 53, 48, 54, 128, 65, 53, 48, 53, 128, - 65, 53, 48, 52, 128, 65, 53, 48, 51, 128, 65, 53, 48, 50, 128, 65, 53, - 48, 49, 128, 65, 52, 57, 55, 128, 65, 52, 57, 54, 128, 65, 52, 57, 53, - 128, 65, 52, 57, 52, 128, 65, 52, 57, 51, 128, 65, 52, 57, 50, 128, 65, - 52, 57, 49, 128, 65, 52, 57, 48, 128, 65, 52, 56, 57, 128, 65, 52, 56, - 56, 128, 65, 52, 56, 55, 128, 65, 52, 56, 54, 128, 65, 52, 56, 53, 128, - 65, 52, 56, 52, 128, 65, 52, 56, 51, 128, 65, 52, 56, 50, 128, 65, 52, - 56, 49, 128, 65, 52, 56, 48, 128, 65, 52, 55, 57, 128, 65, 52, 55, 56, - 128, 65, 52, 55, 55, 128, 65, 52, 55, 54, 128, 65, 52, 55, 53, 128, 65, - 52, 55, 52, 128, 65, 52, 55, 51, 128, 65, 52, 55, 50, 128, 65, 52, 55, - 49, 128, 65, 52, 55, 48, 128, 65, 52, 54, 57, 128, 65, 52, 54, 56, 128, - 65, 52, 54, 55, 128, 65, 52, 54, 54, 128, 65, 52, 54, 53, 128, 65, 52, - 54, 52, 128, 65, 52, 54, 51, 128, 65, 52, 54, 50, 128, 65, 52, 54, 49, - 128, 65, 52, 54, 48, 128, 65, 52, 53, 57, 128, 65, 52, 53, 56, 128, 65, - 52, 53, 55, 65, 128, 65, 52, 53, 55, 128, 65, 52, 53, 54, 128, 65, 52, - 53, 53, 128, 65, 52, 53, 52, 128, 65, 52, 53, 51, 128, 65, 52, 53, 50, - 128, 65, 52, 53, 49, 128, 65, 52, 53, 48, 65, 128, 65, 52, 53, 48, 128, - 65, 52, 52, 57, 128, 65, 52, 52, 56, 128, 65, 52, 52, 55, 128, 65, 52, - 52, 54, 128, 65, 52, 52, 53, 128, 65, 52, 52, 52, 128, 65, 52, 52, 51, - 128, 65, 52, 52, 50, 128, 65, 52, 52, 49, 128, 65, 52, 52, 48, 128, 65, - 52, 51, 57, 128, 65, 52, 51, 56, 128, 65, 52, 51, 55, 128, 65, 52, 51, - 54, 128, 65, 52, 51, 53, 128, 65, 52, 51, 52, 128, 65, 52, 51, 51, 128, - 65, 52, 51, 50, 128, 65, 52, 51, 49, 128, 65, 52, 51, 48, 128, 65, 52, - 50, 57, 128, 65, 52, 50, 56, 128, 65, 52, 50, 55, 128, 65, 52, 50, 54, - 128, 65, 52, 50, 53, 128, 65, 52, 50, 52, 128, 65, 52, 50, 51, 128, 65, - 52, 50, 50, 128, 65, 52, 50, 49, 128, 65, 52, 50, 48, 128, 65, 52, 49, - 57, 128, 65, 52, 49, 56, 45, 86, 65, 83, 128, 65, 52, 49, 56, 128, 65, - 52, 49, 55, 45, 86, 65, 83, 128, 65, 52, 49, 55, 128, 65, 52, 49, 54, 45, - 86, 65, 83, 128, 65, 52, 49, 54, 128, 65, 52, 49, 53, 45, 86, 65, 83, - 128, 65, 52, 49, 53, 128, 65, 52, 49, 52, 45, 86, 65, 83, 128, 65, 52, - 49, 52, 128, 65, 52, 49, 51, 45, 86, 65, 83, 128, 65, 52, 49, 51, 128, - 65, 52, 49, 50, 45, 86, 65, 83, 128, 65, 52, 49, 50, 128, 65, 52, 49, 49, - 45, 86, 65, 83, 128, 65, 52, 49, 49, 128, 65, 52, 49, 48, 193, 65, 52, - 49, 48, 45, 86, 65, 83, 128, 65, 52, 49, 176, 65, 52, 48, 57, 45, 86, 65, - 83, 128, 65, 52, 48, 57, 128, 65, 52, 48, 56, 45, 86, 65, 83, 128, 65, - 52, 48, 56, 128, 65, 52, 48, 55, 45, 86, 65, 83, 128, 65, 52, 48, 55, - 128, 65, 52, 48, 54, 45, 86, 65, 83, 128, 65, 52, 48, 54, 128, 65, 52, - 48, 53, 45, 86, 65, 83, 128, 65, 52, 48, 53, 128, 65, 52, 48, 52, 45, 86, - 65, 83, 128, 65, 52, 48, 52, 128, 65, 52, 48, 51, 45, 86, 65, 83, 128, - 65, 52, 48, 51, 128, 65, 52, 48, 50, 45, 86, 65, 83, 128, 65, 52, 48, 50, - 128, 65, 52, 48, 49, 45, 86, 65, 83, 128, 65, 52, 48, 49, 128, 65, 52, - 48, 48, 45, 86, 65, 83, 128, 65, 52, 48, 48, 128, 65, 51, 57, 57, 128, - 65, 51, 57, 56, 128, 65, 51, 57, 55, 128, 65, 51, 57, 54, 128, 65, 51, - 57, 53, 128, 65, 51, 57, 52, 128, 65, 51, 57, 179, 65, 51, 57, 50, 128, - 65, 51, 57, 49, 128, 65, 51, 57, 48, 128, 65, 51, 56, 57, 128, 65, 51, - 56, 56, 128, 65, 51, 56, 55, 128, 65, 51, 56, 54, 65, 128, 65, 51, 56, - 54, 128, 65, 51, 56, 53, 128, 65, 51, 56, 52, 128, 65, 51, 56, 51, 65, - 128, 65, 51, 56, 179, 65, 51, 56, 50, 128, 65, 51, 56, 49, 65, 128, 65, - 51, 56, 49, 128, 65, 51, 56, 48, 128, 65, 51, 55, 57, 128, 65, 51, 55, - 56, 128, 65, 51, 55, 55, 128, 65, 51, 55, 54, 128, 65, 51, 55, 53, 128, - 65, 51, 55, 52, 128, 65, 51, 55, 51, 128, 65, 51, 55, 50, 128, 65, 51, - 55, 49, 65, 128, 65, 51, 55, 49, 128, 65, 51, 55, 48, 128, 65, 51, 54, - 57, 128, 65, 51, 54, 56, 65, 128, 65, 51, 54, 56, 128, 65, 51, 54, 55, - 128, 65, 51, 54, 54, 128, 65, 51, 54, 53, 128, 65, 51, 54, 52, 65, 128, - 65, 51, 54, 52, 128, 65, 51, 54, 51, 128, 65, 51, 54, 50, 128, 65, 51, - 54, 49, 128, 65, 51, 54, 48, 128, 65, 51, 53, 57, 65, 128, 65, 51, 53, - 57, 128, 65, 51, 53, 56, 128, 65, 51, 53, 55, 128, 65, 51, 53, 54, 128, - 65, 51, 53, 53, 128, 65, 51, 53, 52, 128, 65, 51, 53, 51, 128, 65, 51, - 53, 50, 128, 65, 51, 53, 49, 128, 65, 51, 53, 48, 128, 65, 51, 52, 57, - 128, 65, 51, 52, 56, 128, 65, 51, 52, 55, 128, 65, 51, 52, 54, 128, 65, - 51, 52, 53, 128, 65, 51, 52, 52, 128, 65, 51, 52, 51, 128, 65, 51, 52, - 50, 128, 65, 51, 52, 49, 128, 65, 51, 52, 48, 128, 65, 51, 51, 57, 128, - 65, 51, 51, 56, 128, 65, 51, 51, 55, 128, 65, 51, 51, 54, 67, 128, 65, - 51, 51, 54, 66, 128, 65, 51, 51, 54, 65, 128, 65, 51, 51, 54, 128, 65, - 51, 51, 53, 128, 65, 51, 51, 52, 128, 65, 51, 51, 51, 128, 65, 51, 51, - 50, 67, 128, 65, 51, 51, 50, 66, 128, 65, 51, 51, 50, 65, 128, 65, 51, - 51, 50, 128, 65, 51, 51, 49, 128, 65, 51, 51, 48, 128, 65, 51, 50, 57, - 65, 128, 65, 51, 50, 57, 128, 65, 51, 50, 56, 128, 65, 51, 50, 55, 128, - 65, 51, 50, 54, 128, 65, 51, 50, 53, 128, 65, 51, 50, 52, 128, 65, 51, - 50, 51, 128, 65, 51, 50, 50, 128, 65, 51, 50, 49, 128, 65, 51, 50, 48, - 128, 65, 51, 49, 57, 128, 65, 51, 49, 56, 128, 65, 51, 49, 55, 128, 65, - 51, 49, 54, 128, 65, 51, 49, 53, 128, 65, 51, 49, 52, 128, 65, 51, 49, - 51, 67, 128, 65, 51, 49, 51, 66, 128, 65, 51, 49, 51, 65, 128, 65, 51, - 49, 51, 128, 65, 51, 49, 50, 128, 65, 51, 49, 49, 128, 65, 51, 49, 48, - 128, 65, 51, 48, 57, 67, 128, 65, 51, 48, 57, 66, 128, 65, 51, 48, 57, - 65, 128, 65, 51, 48, 57, 128, 65, 51, 48, 56, 128, 65, 51, 48, 55, 128, - 65, 51, 48, 54, 128, 65, 51, 48, 53, 128, 65, 51, 48, 52, 128, 65, 51, - 48, 51, 128, 65, 51, 48, 50, 128, 65, 51, 48, 49, 128, 65, 51, 48, 48, - 128, 65, 50, 57, 57, 65, 128, 65, 50, 57, 57, 128, 65, 50, 57, 56, 128, - 65, 50, 57, 55, 128, 65, 50, 57, 54, 128, 65, 50, 57, 53, 128, 65, 50, - 57, 52, 65, 128, 65, 50, 57, 52, 128, 65, 50, 57, 51, 128, 65, 50, 57, - 50, 128, 65, 50, 57, 49, 128, 65, 50, 57, 48, 128, 65, 50, 56, 57, 65, - 128, 65, 50, 56, 57, 128, 65, 50, 56, 56, 128, 65, 50, 56, 55, 128, 65, - 50, 56, 54, 128, 65, 50, 56, 53, 128, 65, 50, 56, 52, 128, 65, 50, 56, - 51, 128, 65, 50, 56, 50, 128, 65, 50, 56, 49, 128, 65, 50, 56, 48, 128, - 65, 50, 55, 57, 128, 65, 50, 55, 56, 128, 65, 50, 55, 55, 128, 65, 50, - 55, 54, 128, 65, 50, 55, 53, 128, 65, 50, 55, 52, 128, 65, 50, 55, 51, - 128, 65, 50, 55, 50, 128, 65, 50, 55, 49, 128, 65, 50, 55, 48, 128, 65, - 50, 54, 57, 128, 65, 50, 54, 56, 128, 65, 50, 54, 55, 65, 128, 65, 50, - 54, 55, 128, 65, 50, 54, 54, 128, 65, 50, 54, 53, 128, 65, 50, 54, 52, - 128, 65, 50, 54, 51, 128, 65, 50, 54, 50, 128, 65, 50, 54, 49, 128, 65, - 50, 54, 48, 128, 65, 50, 53, 57, 128, 65, 50, 53, 56, 128, 65, 50, 53, - 55, 128, 65, 50, 53, 54, 128, 65, 50, 53, 53, 128, 65, 50, 53, 52, 128, - 65, 50, 53, 51, 128, 65, 50, 53, 50, 128, 65, 50, 53, 49, 128, 65, 50, - 53, 48, 128, 65, 50, 52, 57, 128, 65, 50, 52, 56, 128, 65, 50, 52, 55, - 128, 65, 50, 52, 54, 128, 65, 50, 52, 53, 128, 65, 50, 52, 52, 128, 65, - 50, 52, 51, 128, 65, 50, 52, 50, 128, 65, 50, 52, 49, 128, 65, 50, 52, - 48, 128, 65, 50, 51, 57, 128, 65, 50, 51, 56, 128, 65, 50, 51, 55, 128, - 65, 50, 51, 54, 128, 65, 50, 51, 53, 128, 65, 50, 51, 52, 128, 65, 50, - 51, 51, 128, 65, 50, 51, 50, 128, 65, 50, 51, 49, 128, 65, 50, 51, 48, - 128, 65, 50, 50, 57, 128, 65, 50, 50, 56, 128, 65, 50, 50, 55, 65, 128, - 65, 50, 50, 55, 128, 65, 50, 50, 54, 128, 65, 50, 50, 53, 128, 65, 50, - 50, 52, 128, 65, 50, 50, 51, 128, 65, 50, 50, 50, 128, 65, 50, 50, 49, - 128, 65, 50, 50, 48, 128, 65, 50, 49, 57, 128, 65, 50, 49, 56, 128, 65, - 50, 49, 55, 128, 65, 50, 49, 54, 65, 128, 65, 50, 49, 54, 128, 65, 50, - 49, 53, 65, 128, 65, 50, 49, 53, 128, 65, 50, 49, 52, 128, 65, 50, 49, - 51, 128, 65, 50, 49, 50, 128, 65, 50, 49, 49, 128, 65, 50, 49, 48, 128, - 65, 50, 48, 57, 65, 128, 65, 50, 48, 57, 128, 65, 50, 48, 56, 128, 65, - 50, 48, 55, 65, 128, 65, 50, 48, 55, 128, 65, 50, 48, 54, 128, 65, 50, - 48, 53, 128, 65, 50, 48, 52, 128, 65, 50, 48, 51, 128, 65, 50, 48, 50, - 66, 128, 65, 50, 48, 50, 65, 128, 65, 50, 48, 50, 128, 65, 50, 48, 49, - 128, 65, 50, 48, 48, 128, 65, 49, 57, 57, 128, 65, 49, 57, 56, 128, 65, - 49, 57, 55, 128, 65, 49, 57, 54, 128, 65, 49, 57, 53, 128, 65, 49, 57, - 52, 128, 65, 49, 57, 51, 128, 65, 49, 57, 50, 128, 65, 49, 57, 49, 128, - 65, 49, 57, 48, 128, 65, 49, 56, 57, 128, 65, 49, 56, 56, 128, 65, 49, - 56, 55, 128, 65, 49, 56, 54, 128, 65, 49, 56, 53, 128, 65, 49, 56, 52, - 128, 65, 49, 56, 51, 128, 65, 49, 56, 50, 128, 65, 49, 56, 49, 128, 65, - 49, 56, 48, 128, 65, 49, 55, 57, 128, 65, 49, 55, 56, 128, 65, 49, 55, - 55, 128, 65, 49, 55, 54, 128, 65, 49, 55, 53, 128, 65, 49, 55, 52, 128, - 65, 49, 55, 51, 128, 65, 49, 55, 50, 128, 65, 49, 55, 49, 128, 65, 49, - 55, 48, 128, 65, 49, 54, 57, 128, 65, 49, 54, 56, 128, 65, 49, 54, 55, - 128, 65, 49, 54, 54, 128, 65, 49, 54, 53, 128, 65, 49, 54, 52, 128, 65, - 49, 54, 51, 128, 65, 49, 54, 50, 128, 65, 49, 54, 49, 128, 65, 49, 54, - 48, 128, 65, 49, 53, 57, 128, 65, 49, 53, 56, 128, 65, 49, 53, 55, 128, - 65, 49, 53, 54, 128, 65, 49, 53, 53, 128, 65, 49, 53, 52, 128, 65, 49, - 53, 51, 128, 65, 49, 53, 50, 128, 65, 49, 53, 49, 128, 65, 49, 53, 48, - 128, 65, 49, 52, 57, 128, 65, 49, 52, 56, 128, 65, 49, 52, 55, 128, 65, - 49, 52, 54, 128, 65, 49, 52, 53, 128, 65, 49, 52, 52, 128, 65, 49, 52, - 51, 128, 65, 49, 52, 50, 128, 65, 49, 52, 49, 128, 65, 49, 52, 48, 128, - 65, 49, 51, 57, 128, 65, 49, 51, 56, 128, 65, 49, 51, 55, 128, 65, 49, - 51, 54, 128, 65, 49, 51, 53, 65, 128, 65, 49, 51, 53, 128, 65, 49, 51, - 52, 128, 65, 49, 51, 51, 128, 65, 49, 51, 50, 128, 65, 49, 51, 49, 67, - 128, 65, 49, 51, 49, 128, 65, 49, 51, 48, 128, 65, 49, 50, 57, 128, 65, - 49, 50, 56, 128, 65, 49, 50, 55, 128, 65, 49, 50, 54, 128, 65, 49, 50, - 53, 65, 128, 65, 49, 50, 53, 128, 65, 49, 50, 52, 128, 65, 49, 50, 51, - 128, 65, 49, 50, 50, 128, 65, 49, 50, 49, 128, 65, 49, 50, 48, 66, 128, - 65, 49, 50, 48, 128, 65, 49, 49, 57, 128, 65, 49, 49, 56, 128, 65, 49, - 49, 55, 128, 65, 49, 49, 54, 128, 65, 49, 49, 53, 65, 128, 65, 49, 49, - 53, 128, 65, 49, 49, 52, 128, 65, 49, 49, 51, 128, 65, 49, 49, 50, 128, - 65, 49, 49, 49, 128, 65, 49, 49, 48, 66, 128, 65, 49, 49, 48, 65, 128, - 65, 49, 49, 48, 128, 65, 49, 48, 57, 128, 65, 49, 48, 56, 128, 65, 49, - 48, 55, 67, 128, 65, 49, 48, 55, 66, 128, 65, 49, 48, 55, 65, 128, 65, - 49, 48, 55, 128, 65, 49, 48, 54, 128, 65, 49, 48, 53, 66, 128, 65, 49, - 48, 53, 65, 128, 65, 49, 48, 53, 128, 65, 49, 48, 52, 67, 128, 65, 49, - 48, 52, 66, 128, 65, 49, 48, 52, 65, 128, 65, 49, 48, 52, 128, 65, 49, - 48, 51, 128, 65, 49, 48, 50, 65, 128, 65, 49, 48, 50, 128, 65, 49, 48, - 49, 65, 128, 65, 49, 48, 49, 128, 65, 49, 48, 48, 65, 128, 65, 49, 48, - 48, 45, 49, 48, 50, 128, 65, 49, 48, 48, 128, 65, 48, 57, 57, 128, 65, - 48, 57, 56, 65, 128, 65, 48, 57, 56, 128, 65, 48, 57, 55, 65, 128, 65, - 48, 57, 55, 128, 65, 48, 57, 54, 128, 65, 48, 57, 53, 128, 65, 48, 57, - 52, 128, 65, 48, 57, 51, 128, 65, 48, 57, 50, 128, 65, 48, 57, 49, 128, - 65, 48, 57, 48, 128, 65, 48, 56, 57, 128, 65, 48, 56, 56, 128, 65, 48, - 56, 55, 128, 65, 48, 56, 54, 128, 65, 48, 56, 53, 128, 65, 48, 56, 52, - 128, 65, 48, 56, 51, 128, 65, 48, 56, 50, 128, 65, 48, 56, 49, 128, 65, - 48, 56, 48, 128, 65, 48, 55, 57, 128, 65, 48, 55, 56, 128, 65, 48, 55, - 55, 128, 65, 48, 55, 54, 128, 65, 48, 55, 53, 128, 65, 48, 55, 52, 128, - 65, 48, 55, 51, 128, 65, 48, 55, 50, 128, 65, 48, 55, 49, 128, 65, 48, - 55, 48, 128, 65, 48, 54, 57, 128, 65, 48, 54, 56, 128, 65, 48, 54, 55, - 128, 65, 48, 54, 54, 67, 128, 65, 48, 54, 54, 66, 128, 65, 48, 54, 54, - 65, 128, 65, 48, 54, 54, 128, 65, 48, 54, 53, 128, 65, 48, 54, 52, 128, - 65, 48, 54, 51, 128, 65, 48, 54, 50, 128, 65, 48, 54, 49, 128, 65, 48, - 54, 48, 128, 65, 48, 53, 57, 128, 65, 48, 53, 56, 128, 65, 48, 53, 55, - 128, 65, 48, 53, 54, 128, 65, 48, 53, 53, 128, 65, 48, 53, 52, 128, 65, - 48, 53, 51, 128, 65, 48, 53, 50, 128, 65, 48, 53, 49, 128, 65, 48, 53, - 48, 128, 65, 48, 52, 57, 128, 65, 48, 52, 56, 128, 65, 48, 52, 55, 128, - 65, 48, 52, 54, 66, 128, 65, 48, 52, 54, 65, 128, 65, 48, 52, 54, 128, - 65, 48, 52, 53, 65, 128, 65, 48, 52, 53, 128, 65, 48, 52, 52, 128, 65, - 48, 52, 51, 65, 128, 65, 48, 52, 51, 128, 65, 48, 52, 50, 65, 128, 65, - 48, 52, 50, 128, 65, 48, 52, 49, 65, 128, 65, 48, 52, 49, 128, 65, 48, - 52, 48, 65, 128, 65, 48, 52, 48, 128, 65, 48, 51, 57, 65, 128, 65, 48, - 51, 57, 128, 65, 48, 51, 56, 128, 65, 48, 51, 55, 128, 65, 48, 51, 54, - 128, 65, 48, 51, 53, 128, 65, 48, 51, 52, 128, 65, 48, 51, 51, 128, 65, - 48, 51, 50, 65, 128, 65, 48, 50, 56, 66, 128, 65, 48, 50, 54, 65, 128, - 65, 48, 49, 55, 65, 128, 65, 48, 49, 52, 65, 128, 65, 48, 49, 48, 65, - 128, 65, 48, 48, 54, 66, 128, 65, 48, 48, 54, 65, 128, 65, 48, 48, 53, - 65, 128, 65, 45, 87, 79, 128, 65, 45, 69, 85, 128, 45, 85, 205, 45, 80, - 72, 82, 85, 128, 45, 75, 72, 89, 85, 196, 45, 75, 72, 89, 73, 76, 128, - 45, 68, 90, 85, 196, 45, 67, 72, 65, 210, 45, 67, 72, 65, 76, 128, + 79, 82, 128, 65, 78, 89, 128, 65, 78, 85, 83, 86, 65, 82, 65, 89, 65, + 128, 65, 78, 85, 83, 86, 65, 82, 65, 128, 65, 78, 85, 83, 86, 65, 82, + 193, 65, 78, 85, 68, 65, 84, 84, 65, 128, 65, 78, 85, 68, 65, 84, 84, + 193, 65, 78, 84, 73, 82, 69, 83, 84, 82, 73, 67, 84, 73, 79, 78, 128, 65, + 78, 84, 73, 77, 79, 78, 89, 45, 50, 128, 65, 78, 84, 73, 77, 79, 78, 89, + 128, 65, 78, 84, 73, 77, 79, 78, 217, 65, 78, 84, 73, 77, 79, 78, 73, 65, + 84, 69, 128, 65, 78, 84, 73, 75, 69, 78, 79, 77, 65, 128, 65, 78, 84, 73, + 75, 69, 78, 79, 75, 89, 76, 73, 83, 77, 65, 128, 65, 78, 84, 73, 70, 79, + 78, 73, 65, 128, 65, 78, 84, 73, 67, 76, 79, 67, 75, 87, 73, 83, 69, 45, + 82, 79, 84, 65, 84, 69, 196, 65, 78, 84, 73, 67, 76, 79, 67, 75, 87, 73, + 83, 69, 128, 65, 78, 84, 73, 67, 76, 79, 67, 75, 87, 73, 83, 197, 65, 78, + 84, 69, 78, 78, 65, 128, 65, 78, 84, 69, 78, 78, 193, 65, 78, 84, 65, 82, + 71, 79, 77, 85, 75, 72, 65, 128, 65, 78, 83, 85, 218, 65, 78, 83, 72, 69, + 128, 65, 78, 80, 69, 65, 128, 65, 78, 207, 65, 78, 78, 85, 73, 84, 217, + 65, 78, 78, 79, 84, 65, 84, 73, 79, 206, 65, 78, 78, 65, 65, 85, 128, 65, + 78, 75, 72, 128, 65, 78, 74, 73, 128, 65, 78, 73, 77, 65, 76, 128, 65, + 78, 72, 85, 78, 78, 65, 128, 65, 78, 72, 85, 77, 65, 65, 128, 65, 78, 72, + 85, 77, 128, 65, 78, 72, 85, 128, 65, 78, 72, 65, 65, 128, 65, 78, 72, + 128, 65, 78, 71, 85, 76, 65, 82, 128, 65, 78, 71, 85, 73, 83, 72, 69, + 196, 65, 78, 71, 83, 84, 82, 79, 205, 65, 78, 71, 82, 217, 65, 78, 71, + 76, 73, 67, 65, 78, 193, 65, 78, 71, 76, 69, 68, 128, 65, 78, 71, 76, 69, + 196, 65, 78, 71, 75, 72, 65, 78, 75, 72, 85, 128, 65, 78, 71, 75, 65, + 128, 65, 78, 71, 69, 210, 65, 78, 71, 69, 76, 128, 65, 78, 71, 69, 68, + 128, 65, 78, 68, 65, 80, 128, 65, 78, 67, 79, 82, 65, 128, 65, 78, 67, + 72, 79, 82, 128, 65, 78, 65, 84, 82, 73, 67, 72, 73, 83, 77, 65, 128, 65, + 78, 65, 84, 79, 77, 73, 67, 65, 204, 65, 78, 65, 80, 128, 65, 78, 45, 78, + 73, 83, 70, 128, 65, 77, 85, 76, 69, 84, 128, 65, 77, 80, 83, 128, 65, + 77, 80, 72, 79, 82, 65, 128, 65, 77, 80, 69, 82, 83, 65, 78, 68, 128, 65, + 77, 80, 69, 82, 83, 65, 78, 196, 65, 77, 79, 85, 78, 212, 65, 77, 69, 82, + 73, 67, 65, 83, 128, 65, 77, 69, 82, 73, 67, 65, 206, 65, 77, 66, 85, 76, + 65, 78, 67, 69, 128, 65, 77, 66, 193, 65, 77, 66, 128, 65, 77, 65, 82, + 128, 65, 77, 65, 210, 65, 77, 65, 76, 71, 65, 77, 65, 84, 73, 79, 206, + 65, 77, 65, 76, 71, 65, 77, 128, 65, 76, 86, 69, 79, 76, 65, 210, 65, 76, + 85, 77, 128, 65, 76, 84, 69, 82, 78, 65, 84, 73, 86, 197, 65, 76, 84, 69, + 82, 78, 65, 84, 73, 79, 206, 65, 76, 84, 69, 82, 78, 65, 84, 73, 78, 71, + 128, 65, 76, 84, 69, 82, 78, 65, 84, 73, 78, 199, 65, 76, 84, 69, 82, 78, + 65, 84, 69, 128, 65, 76, 84, 69, 82, 78, 65, 84, 197, 65, 76, 84, 65, + 128, 65, 76, 80, 72, 65, 128, 65, 76, 80, 72, 193, 65, 76, 80, 65, 80, + 82, 65, 78, 65, 128, 65, 76, 80, 65, 80, 82, 65, 65, 78, 193, 65, 76, 80, + 65, 128, 65, 76, 77, 79, 83, 212, 65, 76, 76, 79, 128, 65, 76, 76, 73, + 65, 78, 67, 69, 128, 65, 76, 76, 201, 65, 76, 76, 65, 200, 65, 76, 76, + 65, 65, 72, 128, 65, 76, 75, 65, 76, 73, 45, 50, 128, 65, 76, 75, 65, 76, + 73, 128, 65, 76, 73, 71, 78, 69, 196, 65, 76, 73, 70, 85, 128, 65, 76, + 73, 70, 128, 65, 76, 73, 198, 65, 76, 73, 69, 78, 128, 65, 76, 73, 69, + 206, 65, 76, 71, 73, 218, 65, 76, 70, 65, 128, 65, 76, 69, 85, 212, 65, + 76, 69, 82, 84, 128, 65, 76, 69, 80, 72, 128, 65, 76, 69, 77, 66, 73, 67, + 128, 65, 76, 69, 70, 128, 65, 76, 66, 65, 78, 73, 65, 206, 65, 76, 65, + 89, 78, 65, 65, 128, 65, 76, 65, 89, 72, 73, 77, 65, 193, 65, 76, 65, 89, + 72, 73, 205, 65, 76, 65, 89, 72, 201, 65, 76, 65, 89, 72, 69, 128, 65, + 76, 65, 89, 72, 197, 65, 76, 65, 89, 72, 65, 193, 65, 76, 65, 82, 205, + 65, 76, 65, 80, 72, 128, 65, 76, 45, 76, 65, 75, 85, 78, 65, 128, 65, 76, + 45, 74, 85, 90, 128, 65, 75, 85, 82, 213, 65, 75, 84, 73, 69, 83, 69, 76, + 83, 75, 65, 66, 128, 65, 75, 83, 65, 128, 65, 75, 72, 77, 73, 77, 73, + 195, 65, 75, 66, 65, 210, 65, 75, 65, 82, 65, 128, 65, 75, 65, 82, 193, + 65, 73, 89, 65, 78, 78, 65, 128, 65, 73, 86, 73, 76, 73, 203, 65, 73, 86, + 65, 128, 65, 73, 84, 79, 206, 65, 73, 82, 80, 76, 65, 78, 69, 128, 65, + 73, 82, 80, 76, 65, 78, 197, 65, 73, 78, 213, 65, 73, 78, 78, 128, 65, + 73, 76, 77, 128, 65, 73, 75, 65, 82, 65, 128, 65, 73, 72, 86, 85, 83, + 128, 65, 72, 83, 68, 65, 128, 65, 72, 83, 65, 128, 65, 72, 79, 205, 65, + 72, 65, 78, 199, 65, 72, 65, 71, 71, 65, 210, 65, 72, 65, 68, 128, 65, + 71, 85, 78, 71, 128, 65, 71, 79, 71, 201, 65, 71, 71, 82, 65, 86, 65, 84, + 73, 79, 78, 128, 65, 71, 71, 82, 65, 86, 65, 84, 69, 196, 65, 71, 65, 73, + 78, 83, 212, 65, 71, 65, 73, 78, 128, 65, 70, 84, 69, 210, 65, 70, 83, + 65, 65, 81, 128, 65, 70, 82, 73, 67, 65, 206, 65, 70, 79, 82, 69, 77, 69, + 78, 84, 73, 79, 78, 69, 68, 128, 65, 70, 71, 72, 65, 78, 201, 65, 70, 70, + 82, 73, 67, 65, 84, 73, 79, 206, 65, 70, 70, 73, 216, 65, 69, 89, 65, 78, + 78, 65, 128, 65, 69, 89, 128, 65, 69, 83, 67, 85, 76, 65, 80, 73, 85, 83, + 128, 65, 69, 83, 67, 128, 65, 69, 83, 128, 65, 69, 82, 73, 65, 204, 65, + 69, 82, 128, 65, 69, 76, 65, 45, 80, 73, 76, 76, 65, 128, 65, 69, 76, + 128, 65, 69, 75, 128, 65, 69, 71, 69, 65, 206, 65, 69, 71, 128, 65, 69, + 69, 89, 65, 78, 78, 65, 128, 65, 69, 69, 128, 65, 69, 68, 65, 45, 80, 73, + 76, 76, 65, 128, 65, 69, 68, 128, 65, 69, 66, 128, 65, 68, 86, 65, 78, + 84, 65, 71, 69, 128, 65, 68, 86, 65, 78, 67, 69, 128, 65, 68, 85, 76, 84, + 128, 65, 68, 77, 73, 83, 83, 73, 79, 206, 65, 68, 77, 69, 84, 79, 83, + 128, 65, 68, 76, 65, 205, 65, 68, 72, 69, 83, 73, 86, 197, 65, 68, 69, + 71, 128, 65, 68, 69, 199, 65, 68, 68, 82, 69, 83, 83, 69, 196, 65, 68, + 68, 82, 69, 83, 211, 65, 68, 68, 65, 75, 128, 65, 68, 65, 203, 65, 67, + 85, 84, 69, 45, 77, 65, 67, 82, 79, 78, 128, 65, 67, 85, 84, 69, 45, 71, + 82, 65, 86, 69, 45, 65, 67, 85, 84, 69, 128, 65, 67, 85, 84, 197, 65, 67, + 84, 85, 65, 76, 76, 217, 65, 67, 84, 73, 86, 65, 84, 197, 65, 67, 82, 79, + 80, 72, 79, 78, 73, 195, 65, 67, 75, 78, 79, 87, 76, 69, 68, 71, 69, 128, + 65, 67, 67, 85, 77, 85, 76, 65, 84, 73, 79, 78, 128, 65, 67, 67, 79, 85, + 78, 212, 65, 67, 67, 79, 82, 68, 73, 79, 78, 128, 65, 67, 67, 79, 77, 77, + 79, 68, 65, 84, 73, 79, 78, 128, 65, 67, 67, 69, 80, 84, 128, 65, 67, 67, + 69, 78, 84, 45, 83, 84, 65, 67, 67, 65, 84, 79, 128, 65, 67, 67, 69, 78, + 84, 128, 65, 67, 67, 69, 78, 212, 65, 67, 65, 68, 69, 77, 217, 65, 66, + 89, 83, 77, 65, 204, 65, 66, 85, 78, 68, 65, 78, 67, 69, 128, 65, 66, 75, + 72, 65, 83, 73, 65, 206, 65, 66, 66, 82, 69, 86, 73, 65, 84, 73, 79, 206, + 65, 66, 65, 70, 73, 76, 73, 128, 65, 66, 65, 67, 85, 83, 128, 65, 66, + 178, 65, 66, 49, 57, 49, 128, 65, 66, 49, 56, 56, 128, 65, 66, 49, 56, + 48, 128, 65, 66, 49, 55, 49, 128, 65, 66, 49, 54, 52, 128, 65, 66, 49, + 51, 49, 66, 128, 65, 66, 49, 51, 49, 65, 128, 65, 66, 49, 50, 51, 128, + 65, 66, 49, 50, 50, 128, 65, 66, 49, 50, 48, 128, 65, 66, 49, 49, 56, + 128, 65, 66, 48, 56, 55, 128, 65, 66, 48, 56, 54, 128, 65, 66, 48, 56, + 53, 128, 65, 66, 48, 56, 50, 128, 65, 66, 48, 56, 49, 128, 65, 66, 48, + 56, 48, 128, 65, 66, 48, 55, 57, 128, 65, 66, 48, 55, 56, 128, 65, 66, + 48, 55, 55, 128, 65, 66, 48, 55, 54, 128, 65, 66, 48, 55, 52, 128, 65, + 66, 48, 55, 51, 128, 65, 66, 48, 55, 48, 128, 65, 66, 48, 54, 57, 128, + 65, 66, 48, 54, 55, 128, 65, 66, 48, 54, 54, 128, 65, 66, 48, 54, 53, + 128, 65, 66, 48, 54, 49, 128, 65, 66, 48, 54, 48, 128, 65, 66, 48, 53, + 57, 128, 65, 66, 48, 53, 56, 128, 65, 66, 48, 53, 55, 128, 65, 66, 48, + 53, 54, 128, 65, 66, 48, 53, 53, 128, 65, 66, 48, 53, 52, 128, 65, 66, + 48, 53, 51, 128, 65, 66, 48, 53, 49, 128, 65, 66, 48, 53, 48, 128, 65, + 66, 48, 52, 57, 128, 65, 66, 48, 52, 56, 128, 65, 66, 48, 52, 55, 128, + 65, 66, 48, 52, 54, 128, 65, 66, 48, 52, 53, 128, 65, 66, 48, 52, 52, + 128, 65, 66, 48, 52, 49, 128, 65, 66, 48, 52, 48, 128, 65, 66, 48, 51, + 57, 128, 65, 66, 48, 51, 56, 128, 65, 66, 48, 51, 55, 128, 65, 66, 48, + 51, 52, 128, 65, 66, 48, 51, 49, 128, 65, 66, 48, 51, 48, 128, 65, 66, + 48, 50, 57, 128, 65, 66, 48, 50, 56, 128, 65, 66, 48, 50, 55, 128, 65, + 66, 48, 50, 54, 128, 65, 66, 48, 50, 52, 128, 65, 66, 48, 50, 51, 77, + 128, 65, 66, 48, 50, 51, 128, 65, 66, 48, 50, 50, 77, 128, 65, 66, 48, + 50, 50, 70, 128, 65, 66, 48, 50, 50, 128, 65, 66, 48, 50, 49, 77, 128, + 65, 66, 48, 50, 49, 70, 128, 65, 66, 48, 50, 49, 128, 65, 66, 48, 50, 48, + 128, 65, 66, 48, 49, 55, 128, 65, 66, 48, 49, 54, 128, 65, 66, 48, 49, + 51, 128, 65, 66, 48, 49, 49, 128, 65, 66, 48, 49, 48, 128, 65, 66, 48, + 48, 57, 128, 65, 66, 48, 48, 56, 128, 65, 66, 48, 48, 55, 128, 65, 66, + 48, 48, 54, 128, 65, 66, 48, 48, 53, 128, 65, 66, 48, 48, 52, 128, 65, + 66, 48, 48, 51, 128, 65, 66, 48, 48, 50, 128, 65, 66, 48, 48, 49, 128, + 65, 65, 90, 72, 65, 65, 75, 75, 85, 128, 65, 65, 89, 73, 78, 128, 65, 65, + 89, 65, 78, 78, 65, 128, 65, 65, 89, 128, 65, 65, 87, 128, 65, 65, 79, + 128, 65, 65, 74, 128, 65, 65, 66, 65, 65, 70, 73, 76, 73, 128, 65, 65, + 48, 51, 50, 128, 65, 65, 48, 51, 49, 128, 65, 65, 48, 51, 48, 128, 65, + 65, 48, 50, 57, 128, 65, 65, 48, 50, 56, 128, 65, 65, 48, 50, 55, 128, + 65, 65, 48, 50, 54, 128, 65, 65, 48, 50, 53, 128, 65, 65, 48, 50, 52, + 128, 65, 65, 48, 50, 51, 128, 65, 65, 48, 50, 50, 128, 65, 65, 48, 50, + 49, 128, 65, 65, 48, 50, 48, 128, 65, 65, 48, 49, 57, 128, 65, 65, 48, + 49, 56, 128, 65, 65, 48, 49, 55, 128, 65, 65, 48, 49, 54, 128, 65, 65, + 48, 49, 53, 128, 65, 65, 48, 49, 52, 128, 65, 65, 48, 49, 51, 128, 65, + 65, 48, 49, 50, 128, 65, 65, 48, 49, 49, 128, 65, 65, 48, 49, 48, 128, + 65, 65, 48, 48, 57, 128, 65, 65, 48, 48, 56, 128, 65, 65, 48, 48, 55, 66, + 128, 65, 65, 48, 48, 55, 65, 128, 65, 65, 48, 48, 55, 128, 65, 65, 48, + 48, 54, 128, 65, 65, 48, 48, 53, 128, 65, 65, 48, 48, 52, 128, 65, 65, + 48, 48, 51, 128, 65, 65, 48, 48, 50, 128, 65, 65, 48, 48, 49, 128, 65, + 56, 48, 55, 128, 65, 56, 48, 54, 128, 65, 56, 48, 53, 128, 65, 56, 48, + 52, 128, 65, 56, 48, 51, 128, 65, 56, 48, 50, 128, 65, 56, 48, 49, 128, + 65, 56, 48, 48, 128, 65, 55, 51, 178, 65, 55, 50, 182, 65, 55, 49, 183, + 65, 55, 49, 181, 65, 55, 49, 180, 65, 55, 49, 179, 65, 55, 49, 178, 65, + 55, 49, 177, 65, 55, 49, 176, 65, 55, 48, 57, 45, 182, 65, 55, 48, 57, + 45, 180, 65, 55, 48, 57, 45, 179, 65, 55, 48, 57, 45, 178, 65, 55, 48, + 185, 65, 55, 48, 184, 65, 55, 48, 183, 65, 55, 48, 182, 65, 55, 48, 181, + 65, 55, 48, 180, 65, 55, 48, 179, 65, 55, 48, 178, 65, 55, 48, 177, 65, + 54, 54, 52, 128, 65, 54, 54, 51, 128, 65, 54, 54, 50, 128, 65, 54, 54, + 49, 128, 65, 54, 54, 48, 128, 65, 54, 53, 57, 128, 65, 54, 53, 56, 128, + 65, 54, 53, 55, 128, 65, 54, 53, 54, 128, 65, 54, 53, 53, 128, 65, 54, + 53, 52, 128, 65, 54, 53, 51, 128, 65, 54, 53, 50, 128, 65, 54, 53, 49, + 128, 65, 54, 52, 57, 128, 65, 54, 52, 56, 128, 65, 54, 52, 54, 128, 65, + 54, 52, 53, 128, 65, 54, 52, 52, 128, 65, 54, 52, 51, 128, 65, 54, 52, + 50, 128, 65, 54, 52, 48, 128, 65, 54, 51, 56, 128, 65, 54, 51, 55, 128, + 65, 54, 51, 52, 128, 65, 54, 50, 57, 128, 65, 54, 50, 56, 128, 65, 54, + 50, 55, 128, 65, 54, 50, 54, 128, 65, 54, 50, 52, 128, 65, 54, 50, 51, + 128, 65, 54, 50, 50, 128, 65, 54, 50, 49, 128, 65, 54, 50, 48, 128, 65, + 54, 49, 57, 128, 65, 54, 49, 56, 128, 65, 54, 49, 55, 128, 65, 54, 49, + 54, 128, 65, 54, 49, 53, 128, 65, 54, 49, 52, 128, 65, 54, 49, 51, 128, + 65, 54, 49, 50, 128, 65, 54, 49, 49, 128, 65, 54, 49, 48, 128, 65, 54, + 48, 57, 128, 65, 54, 48, 56, 128, 65, 54, 48, 54, 128, 65, 54, 48, 52, + 128, 65, 54, 48, 51, 128, 65, 54, 48, 50, 128, 65, 54, 48, 49, 128, 65, + 54, 48, 48, 128, 65, 53, 57, 56, 128, 65, 53, 57, 54, 128, 65, 53, 57, + 53, 128, 65, 53, 57, 52, 128, 65, 53, 57, 50, 128, 65, 53, 57, 49, 128, + 65, 53, 56, 57, 128, 65, 53, 56, 56, 128, 65, 53, 56, 55, 128, 65, 53, + 56, 54, 128, 65, 53, 56, 53, 128, 65, 53, 56, 52, 128, 65, 53, 56, 51, + 128, 65, 53, 56, 50, 128, 65, 53, 56, 49, 128, 65, 53, 56, 48, 128, 65, + 53, 55, 57, 128, 65, 53, 55, 56, 128, 65, 53, 55, 55, 128, 65, 53, 55, + 54, 128, 65, 53, 55, 53, 128, 65, 53, 55, 52, 128, 65, 53, 55, 51, 128, + 65, 53, 55, 50, 128, 65, 53, 55, 49, 128, 65, 53, 55, 48, 128, 65, 53, + 54, 57, 128, 65, 53, 54, 56, 128, 65, 53, 54, 54, 128, 65, 53, 54, 53, + 128, 65, 53, 54, 52, 128, 65, 53, 54, 51, 128, 65, 53, 53, 57, 128, 65, + 53, 53, 55, 128, 65, 53, 53, 54, 128, 65, 53, 53, 53, 128, 65, 53, 53, + 52, 128, 65, 53, 53, 51, 128, 65, 53, 53, 50, 128, 65, 53, 53, 49, 128, + 65, 53, 53, 48, 128, 65, 53, 52, 57, 128, 65, 53, 52, 56, 128, 65, 53, + 52, 55, 128, 65, 53, 52, 53, 128, 65, 53, 52, 50, 128, 65, 53, 52, 49, + 128, 65, 53, 52, 48, 128, 65, 53, 51, 57, 128, 65, 53, 51, 56, 128, 65, + 53, 51, 55, 128, 65, 53, 51, 54, 128, 65, 53, 51, 53, 128, 65, 53, 51, + 52, 128, 65, 53, 51, 50, 128, 65, 53, 51, 49, 128, 65, 53, 51, 48, 128, + 65, 53, 50, 57, 128, 65, 53, 50, 56, 128, 65, 53, 50, 55, 128, 65, 53, + 50, 54, 128, 65, 53, 50, 53, 128, 65, 53, 50, 52, 128, 65, 53, 50, 51, + 128, 65, 53, 50, 50, 128, 65, 53, 50, 49, 128, 65, 53, 50, 48, 128, 65, + 53, 49, 57, 128, 65, 53, 49, 56, 128, 65, 53, 49, 55, 128, 65, 53, 49, + 54, 128, 65, 53, 49, 53, 128, 65, 53, 49, 52, 128, 65, 53, 49, 51, 128, + 65, 53, 49, 50, 128, 65, 53, 49, 49, 128, 65, 53, 49, 48, 128, 65, 53, + 48, 57, 128, 65, 53, 48, 56, 128, 65, 53, 48, 55, 128, 65, 53, 48, 54, + 128, 65, 53, 48, 53, 128, 65, 53, 48, 52, 128, 65, 53, 48, 51, 128, 65, + 53, 48, 50, 128, 65, 53, 48, 49, 128, 65, 52, 57, 55, 128, 65, 52, 57, + 54, 128, 65, 52, 57, 53, 128, 65, 52, 57, 52, 128, 65, 52, 57, 51, 128, + 65, 52, 57, 50, 128, 65, 52, 57, 49, 128, 65, 52, 57, 48, 128, 65, 52, + 56, 57, 128, 65, 52, 56, 56, 128, 65, 52, 56, 55, 128, 65, 52, 56, 54, + 128, 65, 52, 56, 53, 128, 65, 52, 56, 52, 128, 65, 52, 56, 51, 128, 65, + 52, 56, 50, 128, 65, 52, 56, 49, 128, 65, 52, 56, 48, 128, 65, 52, 55, + 57, 128, 65, 52, 55, 56, 128, 65, 52, 55, 55, 128, 65, 52, 55, 54, 128, + 65, 52, 55, 53, 128, 65, 52, 55, 52, 128, 65, 52, 55, 51, 128, 65, 52, + 55, 50, 128, 65, 52, 55, 49, 128, 65, 52, 55, 48, 128, 65, 52, 54, 57, + 128, 65, 52, 54, 56, 128, 65, 52, 54, 55, 128, 65, 52, 54, 54, 128, 65, + 52, 54, 53, 128, 65, 52, 54, 52, 128, 65, 52, 54, 51, 128, 65, 52, 54, + 50, 128, 65, 52, 54, 49, 128, 65, 52, 54, 48, 128, 65, 52, 53, 57, 128, + 65, 52, 53, 56, 128, 65, 52, 53, 55, 65, 128, 65, 52, 53, 55, 128, 65, + 52, 53, 54, 128, 65, 52, 53, 53, 128, 65, 52, 53, 52, 128, 65, 52, 53, + 51, 128, 65, 52, 53, 50, 128, 65, 52, 53, 49, 128, 65, 52, 53, 48, 65, + 128, 65, 52, 53, 48, 128, 65, 52, 52, 57, 128, 65, 52, 52, 56, 128, 65, + 52, 52, 55, 128, 65, 52, 52, 54, 128, 65, 52, 52, 53, 128, 65, 52, 52, + 52, 128, 65, 52, 52, 51, 128, 65, 52, 52, 50, 128, 65, 52, 52, 49, 128, + 65, 52, 52, 48, 128, 65, 52, 51, 57, 128, 65, 52, 51, 56, 128, 65, 52, + 51, 55, 128, 65, 52, 51, 54, 128, 65, 52, 51, 53, 128, 65, 52, 51, 52, + 128, 65, 52, 51, 51, 128, 65, 52, 51, 50, 128, 65, 52, 51, 49, 128, 65, + 52, 51, 48, 128, 65, 52, 50, 57, 128, 65, 52, 50, 56, 128, 65, 52, 50, + 55, 128, 65, 52, 50, 54, 128, 65, 52, 50, 53, 128, 65, 52, 50, 52, 128, + 65, 52, 50, 51, 128, 65, 52, 50, 50, 128, 65, 52, 50, 49, 128, 65, 52, + 50, 48, 128, 65, 52, 49, 57, 128, 65, 52, 49, 56, 45, 86, 65, 83, 128, + 65, 52, 49, 56, 128, 65, 52, 49, 55, 45, 86, 65, 83, 128, 65, 52, 49, 55, + 128, 65, 52, 49, 54, 45, 86, 65, 83, 128, 65, 52, 49, 54, 128, 65, 52, + 49, 53, 45, 86, 65, 83, 128, 65, 52, 49, 53, 128, 65, 52, 49, 52, 45, 86, + 65, 83, 128, 65, 52, 49, 52, 128, 65, 52, 49, 51, 45, 86, 65, 83, 128, + 65, 52, 49, 51, 128, 65, 52, 49, 50, 45, 86, 65, 83, 128, 65, 52, 49, 50, + 128, 65, 52, 49, 49, 45, 86, 65, 83, 128, 65, 52, 49, 49, 128, 65, 52, + 49, 48, 193, 65, 52, 49, 48, 45, 86, 65, 83, 128, 65, 52, 49, 176, 65, + 52, 48, 57, 45, 86, 65, 83, 128, 65, 52, 48, 57, 128, 65, 52, 48, 56, 45, + 86, 65, 83, 128, 65, 52, 48, 56, 128, 65, 52, 48, 55, 45, 86, 65, 83, + 128, 65, 52, 48, 55, 128, 65, 52, 48, 54, 45, 86, 65, 83, 128, 65, 52, + 48, 54, 128, 65, 52, 48, 53, 45, 86, 65, 83, 128, 65, 52, 48, 53, 128, + 65, 52, 48, 52, 45, 86, 65, 83, 128, 65, 52, 48, 52, 128, 65, 52, 48, 51, + 45, 86, 65, 83, 128, 65, 52, 48, 51, 128, 65, 52, 48, 50, 45, 86, 65, 83, + 128, 65, 52, 48, 50, 128, 65, 52, 48, 49, 45, 86, 65, 83, 128, 65, 52, + 48, 49, 128, 65, 52, 48, 48, 45, 86, 65, 83, 128, 65, 52, 48, 48, 128, + 65, 51, 57, 57, 128, 65, 51, 57, 56, 128, 65, 51, 57, 55, 128, 65, 51, + 57, 54, 128, 65, 51, 57, 53, 128, 65, 51, 57, 52, 128, 65, 51, 57, 179, + 65, 51, 57, 50, 128, 65, 51, 57, 49, 128, 65, 51, 57, 48, 128, 65, 51, + 56, 57, 128, 65, 51, 56, 56, 128, 65, 51, 56, 55, 128, 65, 51, 56, 54, + 65, 128, 65, 51, 56, 54, 128, 65, 51, 56, 53, 128, 65, 51, 56, 52, 128, + 65, 51, 56, 51, 65, 128, 65, 51, 56, 179, 65, 51, 56, 50, 128, 65, 51, + 56, 49, 65, 128, 65, 51, 56, 49, 128, 65, 51, 56, 48, 128, 65, 51, 55, + 57, 128, 65, 51, 55, 56, 128, 65, 51, 55, 55, 128, 65, 51, 55, 54, 128, + 65, 51, 55, 53, 128, 65, 51, 55, 52, 128, 65, 51, 55, 51, 128, 65, 51, + 55, 50, 128, 65, 51, 55, 49, 65, 128, 65, 51, 55, 49, 128, 65, 51, 55, + 48, 128, 65, 51, 54, 57, 128, 65, 51, 54, 56, 65, 128, 65, 51, 54, 56, + 128, 65, 51, 54, 55, 128, 65, 51, 54, 54, 128, 65, 51, 54, 53, 128, 65, + 51, 54, 52, 65, 128, 65, 51, 54, 52, 128, 65, 51, 54, 51, 128, 65, 51, + 54, 50, 128, 65, 51, 54, 49, 128, 65, 51, 54, 48, 128, 65, 51, 53, 57, + 65, 128, 65, 51, 53, 57, 128, 65, 51, 53, 56, 128, 65, 51, 53, 55, 128, + 65, 51, 53, 54, 128, 65, 51, 53, 53, 128, 65, 51, 53, 52, 128, 65, 51, + 53, 51, 128, 65, 51, 53, 50, 128, 65, 51, 53, 49, 128, 65, 51, 53, 48, + 128, 65, 51, 52, 57, 128, 65, 51, 52, 56, 128, 65, 51, 52, 55, 128, 65, + 51, 52, 54, 128, 65, 51, 52, 53, 128, 65, 51, 52, 52, 128, 65, 51, 52, + 51, 128, 65, 51, 52, 50, 128, 65, 51, 52, 49, 128, 65, 51, 52, 48, 128, + 65, 51, 51, 57, 128, 65, 51, 51, 56, 128, 65, 51, 51, 55, 128, 65, 51, + 51, 54, 67, 128, 65, 51, 51, 54, 66, 128, 65, 51, 51, 54, 65, 128, 65, + 51, 51, 54, 128, 65, 51, 51, 53, 128, 65, 51, 51, 52, 128, 65, 51, 51, + 51, 128, 65, 51, 51, 50, 67, 128, 65, 51, 51, 50, 66, 128, 65, 51, 51, + 50, 65, 128, 65, 51, 51, 50, 128, 65, 51, 51, 49, 128, 65, 51, 51, 48, + 128, 65, 51, 50, 57, 65, 128, 65, 51, 50, 57, 128, 65, 51, 50, 56, 128, + 65, 51, 50, 55, 128, 65, 51, 50, 54, 128, 65, 51, 50, 53, 128, 65, 51, + 50, 52, 128, 65, 51, 50, 51, 128, 65, 51, 50, 50, 128, 65, 51, 50, 49, + 128, 65, 51, 50, 48, 128, 65, 51, 49, 57, 128, 65, 51, 49, 56, 128, 65, + 51, 49, 55, 128, 65, 51, 49, 54, 128, 65, 51, 49, 53, 128, 65, 51, 49, + 52, 128, 65, 51, 49, 51, 67, 128, 65, 51, 49, 51, 66, 128, 65, 51, 49, + 51, 65, 128, 65, 51, 49, 51, 128, 65, 51, 49, 50, 128, 65, 51, 49, 49, + 128, 65, 51, 49, 48, 128, 65, 51, 48, 57, 67, 128, 65, 51, 48, 57, 66, + 128, 65, 51, 48, 57, 65, 128, 65, 51, 48, 57, 128, 65, 51, 48, 56, 128, + 65, 51, 48, 55, 128, 65, 51, 48, 54, 128, 65, 51, 48, 53, 128, 65, 51, + 48, 52, 128, 65, 51, 48, 51, 128, 65, 51, 48, 50, 128, 65, 51, 48, 49, + 128, 65, 51, 48, 48, 128, 65, 50, 57, 57, 65, 128, 65, 50, 57, 57, 128, + 65, 50, 57, 56, 128, 65, 50, 57, 55, 128, 65, 50, 57, 54, 128, 65, 50, + 57, 53, 128, 65, 50, 57, 52, 65, 128, 65, 50, 57, 52, 128, 65, 50, 57, + 51, 128, 65, 50, 57, 50, 128, 65, 50, 57, 49, 128, 65, 50, 57, 48, 128, + 65, 50, 56, 57, 65, 128, 65, 50, 56, 57, 128, 65, 50, 56, 56, 128, 65, + 50, 56, 55, 128, 65, 50, 56, 54, 128, 65, 50, 56, 53, 128, 65, 50, 56, + 52, 128, 65, 50, 56, 51, 128, 65, 50, 56, 50, 128, 65, 50, 56, 49, 128, + 65, 50, 56, 48, 128, 65, 50, 55, 57, 128, 65, 50, 55, 56, 128, 65, 50, + 55, 55, 128, 65, 50, 55, 54, 128, 65, 50, 55, 53, 128, 65, 50, 55, 52, + 128, 65, 50, 55, 51, 128, 65, 50, 55, 50, 128, 65, 50, 55, 49, 128, 65, + 50, 55, 48, 128, 65, 50, 54, 57, 128, 65, 50, 54, 56, 128, 65, 50, 54, + 55, 65, 128, 65, 50, 54, 55, 128, 65, 50, 54, 54, 128, 65, 50, 54, 53, + 128, 65, 50, 54, 52, 128, 65, 50, 54, 51, 128, 65, 50, 54, 50, 128, 65, + 50, 54, 49, 128, 65, 50, 54, 48, 128, 65, 50, 53, 57, 128, 65, 50, 53, + 56, 128, 65, 50, 53, 55, 128, 65, 50, 53, 54, 128, 65, 50, 53, 53, 128, + 65, 50, 53, 52, 128, 65, 50, 53, 51, 128, 65, 50, 53, 50, 128, 65, 50, + 53, 49, 128, 65, 50, 53, 48, 128, 65, 50, 52, 57, 128, 65, 50, 52, 56, + 128, 65, 50, 52, 55, 128, 65, 50, 52, 54, 128, 65, 50, 52, 53, 128, 65, + 50, 52, 52, 128, 65, 50, 52, 51, 128, 65, 50, 52, 50, 128, 65, 50, 52, + 49, 128, 65, 50, 52, 48, 128, 65, 50, 51, 57, 128, 65, 50, 51, 56, 128, + 65, 50, 51, 55, 128, 65, 50, 51, 54, 128, 65, 50, 51, 53, 128, 65, 50, + 51, 52, 128, 65, 50, 51, 51, 128, 65, 50, 51, 50, 128, 65, 50, 51, 49, + 128, 65, 50, 51, 48, 128, 65, 50, 50, 57, 128, 65, 50, 50, 56, 128, 65, + 50, 50, 55, 65, 128, 65, 50, 50, 55, 128, 65, 50, 50, 54, 128, 65, 50, + 50, 53, 128, 65, 50, 50, 52, 128, 65, 50, 50, 51, 128, 65, 50, 50, 50, + 128, 65, 50, 50, 49, 128, 65, 50, 50, 48, 128, 65, 50, 49, 57, 128, 65, + 50, 49, 56, 128, 65, 50, 49, 55, 128, 65, 50, 49, 54, 65, 128, 65, 50, + 49, 54, 128, 65, 50, 49, 53, 65, 128, 65, 50, 49, 53, 128, 65, 50, 49, + 52, 128, 65, 50, 49, 51, 128, 65, 50, 49, 50, 128, 65, 50, 49, 49, 128, + 65, 50, 49, 48, 128, 65, 50, 48, 57, 65, 128, 65, 50, 48, 57, 128, 65, + 50, 48, 56, 128, 65, 50, 48, 55, 65, 128, 65, 50, 48, 55, 128, 65, 50, + 48, 54, 128, 65, 50, 48, 53, 128, 65, 50, 48, 52, 128, 65, 50, 48, 51, + 128, 65, 50, 48, 50, 66, 128, 65, 50, 48, 50, 65, 128, 65, 50, 48, 50, + 128, 65, 50, 48, 49, 128, 65, 50, 48, 48, 128, 65, 49, 57, 57, 128, 65, + 49, 57, 56, 128, 65, 49, 57, 55, 128, 65, 49, 57, 54, 128, 65, 49, 57, + 53, 128, 65, 49, 57, 52, 128, 65, 49, 57, 51, 128, 65, 49, 57, 50, 128, + 65, 49, 57, 49, 128, 65, 49, 57, 48, 128, 65, 49, 56, 57, 128, 65, 49, + 56, 56, 128, 65, 49, 56, 55, 128, 65, 49, 56, 54, 128, 65, 49, 56, 53, + 128, 65, 49, 56, 52, 128, 65, 49, 56, 51, 128, 65, 49, 56, 50, 128, 65, + 49, 56, 49, 128, 65, 49, 56, 48, 128, 65, 49, 55, 57, 128, 65, 49, 55, + 56, 128, 65, 49, 55, 55, 128, 65, 49, 55, 54, 128, 65, 49, 55, 53, 128, + 65, 49, 55, 52, 128, 65, 49, 55, 51, 128, 65, 49, 55, 50, 128, 65, 49, + 55, 49, 128, 65, 49, 55, 48, 128, 65, 49, 54, 57, 128, 65, 49, 54, 56, + 128, 65, 49, 54, 55, 128, 65, 49, 54, 54, 128, 65, 49, 54, 53, 128, 65, + 49, 54, 52, 128, 65, 49, 54, 51, 128, 65, 49, 54, 50, 128, 65, 49, 54, + 49, 128, 65, 49, 54, 48, 128, 65, 49, 53, 57, 128, 65, 49, 53, 56, 128, + 65, 49, 53, 55, 128, 65, 49, 53, 54, 128, 65, 49, 53, 53, 128, 65, 49, + 53, 52, 128, 65, 49, 53, 51, 128, 65, 49, 53, 50, 128, 65, 49, 53, 49, + 128, 65, 49, 53, 48, 128, 65, 49, 52, 57, 128, 65, 49, 52, 56, 128, 65, + 49, 52, 55, 128, 65, 49, 52, 54, 128, 65, 49, 52, 53, 128, 65, 49, 52, + 52, 128, 65, 49, 52, 51, 128, 65, 49, 52, 50, 128, 65, 49, 52, 49, 128, + 65, 49, 52, 48, 128, 65, 49, 51, 57, 128, 65, 49, 51, 56, 128, 65, 49, + 51, 55, 128, 65, 49, 51, 54, 128, 65, 49, 51, 53, 65, 128, 65, 49, 51, + 53, 128, 65, 49, 51, 52, 128, 65, 49, 51, 51, 128, 65, 49, 51, 50, 128, + 65, 49, 51, 49, 67, 128, 65, 49, 51, 49, 128, 65, 49, 51, 48, 128, 65, + 49, 50, 57, 128, 65, 49, 50, 56, 128, 65, 49, 50, 55, 128, 65, 49, 50, + 54, 128, 65, 49, 50, 53, 65, 128, 65, 49, 50, 53, 128, 65, 49, 50, 52, + 128, 65, 49, 50, 51, 128, 65, 49, 50, 50, 128, 65, 49, 50, 49, 128, 65, + 49, 50, 48, 66, 128, 65, 49, 50, 48, 128, 65, 49, 49, 57, 128, 65, 49, + 49, 56, 128, 65, 49, 49, 55, 128, 65, 49, 49, 54, 128, 65, 49, 49, 53, + 65, 128, 65, 49, 49, 53, 128, 65, 49, 49, 52, 128, 65, 49, 49, 51, 128, + 65, 49, 49, 50, 128, 65, 49, 49, 49, 128, 65, 49, 49, 48, 66, 128, 65, + 49, 49, 48, 65, 128, 65, 49, 49, 48, 128, 65, 49, 48, 57, 128, 65, 49, + 48, 56, 128, 65, 49, 48, 55, 67, 128, 65, 49, 48, 55, 66, 128, 65, 49, + 48, 55, 65, 128, 65, 49, 48, 55, 128, 65, 49, 48, 54, 128, 65, 49, 48, + 53, 66, 128, 65, 49, 48, 53, 65, 128, 65, 49, 48, 53, 128, 65, 49, 48, + 52, 67, 128, 65, 49, 48, 52, 66, 128, 65, 49, 48, 52, 65, 128, 65, 49, + 48, 52, 128, 65, 49, 48, 51, 128, 65, 49, 48, 50, 65, 128, 65, 49, 48, + 50, 128, 65, 49, 48, 49, 65, 128, 65, 49, 48, 49, 128, 65, 49, 48, 48, + 65, 128, 65, 49, 48, 48, 45, 49, 48, 50, 128, 65, 49, 48, 48, 128, 65, + 48, 57, 57, 128, 65, 48, 57, 56, 65, 128, 65, 48, 57, 56, 128, 65, 48, + 57, 55, 65, 128, 65, 48, 57, 55, 128, 65, 48, 57, 54, 128, 65, 48, 57, + 53, 128, 65, 48, 57, 52, 128, 65, 48, 57, 51, 128, 65, 48, 57, 50, 128, + 65, 48, 57, 49, 128, 65, 48, 57, 48, 128, 65, 48, 56, 57, 128, 65, 48, + 56, 56, 128, 65, 48, 56, 55, 128, 65, 48, 56, 54, 128, 65, 48, 56, 53, + 128, 65, 48, 56, 52, 128, 65, 48, 56, 51, 128, 65, 48, 56, 50, 128, 65, + 48, 56, 49, 128, 65, 48, 56, 48, 128, 65, 48, 55, 57, 128, 65, 48, 55, + 56, 128, 65, 48, 55, 55, 128, 65, 48, 55, 54, 128, 65, 48, 55, 53, 128, + 65, 48, 55, 52, 128, 65, 48, 55, 51, 128, 65, 48, 55, 50, 128, 65, 48, + 55, 49, 128, 65, 48, 55, 48, 128, 65, 48, 54, 57, 128, 65, 48, 54, 56, + 128, 65, 48, 54, 55, 128, 65, 48, 54, 54, 67, 128, 65, 48, 54, 54, 66, + 128, 65, 48, 54, 54, 65, 128, 65, 48, 54, 54, 128, 65, 48, 54, 53, 128, + 65, 48, 54, 52, 128, 65, 48, 54, 51, 128, 65, 48, 54, 50, 128, 65, 48, + 54, 49, 128, 65, 48, 54, 48, 128, 65, 48, 53, 57, 128, 65, 48, 53, 56, + 128, 65, 48, 53, 55, 128, 65, 48, 53, 54, 128, 65, 48, 53, 53, 128, 65, + 48, 53, 52, 128, 65, 48, 53, 51, 128, 65, 48, 53, 50, 128, 65, 48, 53, + 49, 128, 65, 48, 53, 48, 128, 65, 48, 52, 57, 128, 65, 48, 52, 56, 128, + 65, 48, 52, 55, 128, 65, 48, 52, 54, 66, 128, 65, 48, 52, 54, 65, 128, + 65, 48, 52, 54, 128, 65, 48, 52, 53, 65, 128, 65, 48, 52, 53, 128, 65, + 48, 52, 52, 128, 65, 48, 52, 51, 65, 128, 65, 48, 52, 51, 128, 65, 48, + 52, 50, 65, 128, 65, 48, 52, 50, 128, 65, 48, 52, 49, 65, 128, 65, 48, + 52, 49, 128, 65, 48, 52, 48, 65, 128, 65, 48, 52, 48, 128, 65, 48, 51, + 57, 65, 128, 65, 48, 51, 57, 128, 65, 48, 51, 56, 128, 65, 48, 51, 55, + 128, 65, 48, 51, 54, 128, 65, 48, 51, 53, 128, 65, 48, 51, 52, 128, 65, + 48, 51, 51, 128, 65, 48, 51, 50, 65, 128, 65, 48, 50, 56, 66, 128, 65, + 48, 50, 54, 65, 128, 65, 48, 49, 55, 65, 128, 65, 48, 49, 52, 65, 128, + 65, 48, 49, 48, 65, 128, 65, 48, 48, 54, 66, 128, 65, 48, 48, 54, 65, + 128, 65, 48, 48, 53, 65, 128, 65, 45, 87, 79, 128, 65, 45, 69, 85, 128, + 45, 85, 205, 45, 80, 72, 82, 85, 128, 45, 75, 72, 89, 85, 196, 45, 75, + 72, 89, 73, 76, 128, 45, 68, 90, 85, 196, 45, 67, 72, 65, 210, 45, 67, + 72, 65, 76, 128, }; static const unsigned int lexicon_offset[] = { 0, 0, 6, 11, 15, 19, 27, 34, 44, 49, 55, 64, 66, 69, 81, 89, 102, 108, - 113, 118, 124, 129, 137, 146, 157, 160, 165, 170, 176, 180, 189, 195, - 201, 207, 216, 224, 229, 237, 177, 244, 247, 253, 254, 262, 268, 273, - 277, 282, 289, 296, 306, 311, 317, 322, 325, 331, 337, 343, 348, 351, - 359, 365, 375, 380, 385, 390, 392, 401, 408, 415, 417, 419, 427, 341, - 436, 438, 441, 449, 454, 455, 462, 464, 472, 478, 484, 491, 496, 503, - 507, 512, 519, 524, 527, 531, 537, 542, 547, 557, 565, 572, 575, 583, - 591, 600, 603, 613, 620, 625, 629, 633, 637, 642, 645, 652, 659, 666, - 671, 676, 685, 687, 696, 700, 707, 715, 719, 727, 281, 736, 749, 753, - 758, 762, 765, 767, 777, 781, 787, 791, 796, 800, 806, 811, 820, 825, - 829, 832, 838, 846, 794, 854, 863, 872, 880, 886, 891, 902, 907, 915, - 918, 925, 928, 938, 943, 949, 953, 957, 964, 967, 974, 977, 657, 980, - 983, 986, 990, 995, 1004, 1010, 1014, 1018, 1021, 1024, 1030, 1035, 1039, - 1044, 602, 1049, 1055, 1064, 1067, 1076, 1081, 1086, 1092, 1097, 1102, - 1107, 1111, 1116, 1122, 1127, 1132, 1136, 1142, 1147, 1152, 1157, 1161, - 1166, 1171, 1176, 1182, 1188, 1194, 1199, 1203, 1208, 1213, 1218, 1222, - 1227, 1232, 1237, 1242, 1077, 1082, 1087, 1093, 1098, 1246, 1108, 1252, - 1257, 1262, 1269, 1273, 1276, 1285, 1112, 1289, 1117, 1123, 1128, 1293, - 1298, 1303, 1307, 1311, 1317, 1321, 1133, 1324, 1326, 1143, 1331, 1335, - 1148, 1341, 1153, 1345, 1349, 1356, 1158, 1360, 1368, 1373, 1377, 1380, - 1384, 1162, 1167, 1389, 1395, 1172, 1407, 1413, 1419, 1425, 1177, 1189, - 1195, 1429, 1433, 1437, 1440, 1200, 1444, 1446, 1451, 1456, 1462, 1467, - 1472, 1476, 1481, 1486, 1491, 1496, 1502, 1507, 1512, 1518, 1524, 1529, - 1533, 1538, 1543, 1548, 1553, 1558, 1562, 1570, 1575, 1579, 1584, 1589, - 1594, 1599, 1603, 1606, 1613, 1618, 1623, 1628, 1633, 1639, 1644, 1648, - 1204, 1651, 1657, 1662, 1667, 1672, 1209, 1676, 1680, 1687, 1694, 1214, - 1699, 1704, 1219, 1708, 1710, 1715, 1726, 1732, 1223, 1737, 1746, 1228, - 1751, 1757, 1762, 1767, 1777, 1786, 1794, 1233, 1804, 1813, 1822, 1827, - 1831, 1834, 1843, 1853, 1862, 1867, 1871, 1875, 1879, 1882, 1886, 1891, - 1238, 1901, 1243, 1905, 1907, 1913, 1919, 1925, 1931, 1937, 1943, 1949, - 1955, 1960, 1966, 1972, 1978, 1984, 1990, 1996, 2002, 2008, 2014, 2019, - 2024, 2029, 2034, 2039, 2044, 2049, 2054, 2059, 2064, 2070, 2075, 2081, - 2086, 2092, 2098, 2103, 2109, 2115, 2121, 2127, 2132, 2137, 2139, 2140, - 2144, 2148, 2153, 2157, 2161, 2165, 2170, 2174, 2177, 2182, 2186, 2191, - 2195, 2199, 2204, 2208, 2211, 2215, 2221, 2235, 2239, 2243, 2247, 2250, - 2255, 2259, 2263, 2266, 2270, 2275, 2280, 2285, 2290, 2294, 2298, 2302, - 2306, 2310, 2315, 2319, 2324, 2328, 2333, 2339, 2346, 2352, 2357, 2362, - 2367, 2373, 2378, 2384, 2389, 2394, 2399, 2404, 2409, 2412, 2414, 1094, - 2418, 2425, 2433, 2443, 2452, 2466, 2470, 2474, 2479, 2492, 2500, 2503, - 2507, 2510, 2515, 2519, 2522, 2526, 2530, 2535, 1721, 2540, 2544, 2547, - 2551, 2557, 2564, 2571, 2577, 2582, 2587, 2593, 2599, 2604, 2609, 2614, - 2619, 2624, 2629, 2554, 2634, 1712, 2636, 2642, 2646, 2651, 2655, 2659, - 1609, 1734, 2664, 2668, 2672, 2675, 2680, 2685, 2690, 2695, 2699, 2706, - 2711, 2714, 2718, 2722, 2729, 2735, 2739, 2745, 2749, 2753, 2758, 2765, - 2770, 2775, 2782, 2788, 2794, 2800, 2821, 2835, 2852, 2867, 2883, 2900, - 2915, 2924, 2929, 2933, 2938, 2943, 2947, 2959, 2966, 2972, 2342, 2978, - 2985, 2991, 2995, 2998, 3005, 3011, 3016, 3020, 3025, 3029, 3033, 2162, - 3037, 3042, 3047, 3051, 3056, 3064, 3068, 3075, 3080, 3084, 3088, 3092, - 3097, 3102, 3107, 3111, 3116, 3121, 3125, 3130, 3135, 3139, 3142, 3146, - 3150, 3158, 3163, 3167, 3171, 3177, 3186, 3190, 3194, 3200, 3205, 3212, - 3216, 3226, 3230, 3234, 3239, 3243, 3248, 3254, 3259, 3263, 3267, 3271, - 2567, 3279, 3284, 3290, 3295, 3299, 3304, 3309, 3313, 3319, 3324, 2166, - 3330, 3336, 3341, 3346, 3351, 3356, 3361, 3366, 3371, 3376, 3381, 3386, - 3391, 3396, 3401, 3406, 3412, 3417, 1109, 101, 3423, 3427, 3431, 3435, - 3440, 3444, 3448, 3454, 3459, 3463, 3467, 3472, 3477, 3481, 3486, 3490, - 3493, 3497, 3502, 3506, 3511, 3515, 3518, 3520, 3524, 3528, 3533, 3537, - 3540, 3553, 3557, 3561, 3565, 3570, 3574, 3578, 3581, 3585, 3589, 3594, - 3598, 3603, 3608, 3613, 3617, 3624, 3629, 3632, 3638, 3641, 3646, 3652, - 3656, 3660, 3663, 3668, 3672, 3677, 3681, 3685, 3688, 3694, 3699, 3704, - 3710, 3715, 3720, 3726, 3732, 3737, 3742, 3747, 3752, 3755, 988, 644, - 3761, 3764, 3769, 3773, 3777, 3781, 3785, 3788, 3792, 3797, 3802, 3806, - 3811, 3815, 3820, 3824, 3828, 3832, 3838, 3844, 3847, 3850, 150, 3856, - 3861, 3870, 3878, 3887, 3897, 3904, 3910, 3917, 3922, 3926, 3930, 3938, - 3945, 3950, 3955, 3962, 3967, 3971, 3981, 3985, 3989, 3994, 3999, 4009, - 2178, 4014, 4018, 4021, 4027, 4032, 4038, 4044, 4049, 4056, 4060, 4064, - 4068, 4073, 4078, 4083, 4088, 4093, 4098, 634, 601, 1270, 4103, 4110, - 4117, 4123, 4128, 4135, 4142, 4147, 4153, 4159, 4164, 4168, 4174, 4181, - 4186, 4190, 4194, 2187, 4200, 4208, 4214, 4222, 858, 4228, 4236, 4247, - 4251, 4261, 4267, 4272, 4277, 4282, 4287, 2192, 4292, 4297, 4312, 4318, - 4325, 4336, 4346, 4352, 4357, 4363, 4369, 4372, 4375, 4379, 4384, 4387, - 4394, 4403, 4408, 4412, 4416, 4420, 4424, 4429, 4435, 4446, 4450, 3498, - 4455, 4467, 4473, 4481, 4485, 4490, 4497, 4502, 4507, 4512, 1478, 4517, - 4520, 4523, 4527, 4530, 4536, 4540, 4554, 4558, 4561, 4565, 4571, 4577, - 4582, 4586, 4590, 4596, 4607, 4613, 4618, 4624, 4628, 4636, 4648, 4658, - 4664, 4669, 4678, 4686, 4697, 4704, 4710, 4716, 4720, 4726, 4735, 4744, - 4749, 4755, 4759, 4768, 4773, 4777, 4782, 4786, 4794, 4800, 4804, 4811, - 4816, 4820, 4826, 4832, 4839, 2200, 4848, 4859, 4869, 4878, 4883, 4888, - 4893, 4898, 1286, 4903, 4905, 4910, 4916, 4921, 4926, 4931, 4936, 4941, - 4946, 4952, 4957, 4963, 4968, 4973, 4978, 4984, 4989, 4994, 4999, 5004, - 5010, 5015, 5021, 5026, 5031, 5036, 5041, 5046, 5051, 5057, 5062, 5067, - 335, 384, 5072, 5078, 5081, 5085, 5089, 5096, 5102, 5107, 5111, 5115, - 5118, 5121, 5125, 5129, 5132, 5136, 5140, 5144, 5149, 5153, 5157, 5163, - 5172, 4829, 5177, 5181, 5184, 5189, 5194, 5199, 5204, 5209, 5214, 5219, - 5224, 5229, 5234, 5238, 5243, 5248, 5253, 5258, 5263, 5268, 5273, 5278, - 5283, 5288, 5292, 5297, 5302, 5307, 5312, 5317, 5322, 5327, 5332, 5337, - 5342, 5346, 5351, 5356, 5361, 5366, 5371, 5376, 5381, 5386, 5391, 5396, - 5400, 5405, 5410, 5415, 5420, 5425, 5430, 5435, 5440, 5445, 5450, 5454, - 5459, 5464, 5469, 5474, 5479, 5484, 5489, 5494, 5499, 5504, 5508, 5513, - 5518, 5523, 5528, 5533, 5538, 5543, 5548, 5553, 5558, 5562, 5567, 5572, - 5577, 5582, 5588, 5594, 5600, 5606, 5612, 5618, 5624, 5629, 5635, 5641, - 5647, 5653, 5659, 5665, 5671, 5677, 5683, 5689, 5694, 5700, 5706, 5712, - 5718, 5724, 5730, 5736, 5742, 5748, 5754, 5759, 5765, 5771, 5777, 5783, - 5789, 5795, 5801, 5807, 5813, 5819, 5824, 5830, 5836, 5842, 5848, 5854, - 5860, 5866, 5872, 5878, 5884, 5889, 5895, 5901, 5907, 5913, 5919, 5925, - 5931, 5937, 5943, 5949, 5954, 5958, 5964, 5970, 5976, 5982, 5988, 5994, - 6000, 6006, 6012, 6018, 6023, 6029, 6035, 6041, 6047, 6053, 6059, 6065, - 6071, 6077, 6083, 6088, 6094, 6100, 6106, 6112, 6118, 6124, 6130, 6136, - 6142, 6148, 6153, 6159, 6165, 6171, 6177, 6183, 6189, 6195, 6201, 6207, - 6213, 6218, 6224, 6230, 6236, 6242, 6248, 6254, 6260, 6266, 6272, 6278, - 6283, 6289, 6295, 6301, 6307, 6313, 6319, 6325, 6331, 6337, 6343, 6348, - 6354, 6360, 6366, 6372, 6378, 6384, 6390, 6396, 6402, 6408, 6413, 6419, - 6425, 6431, 6437, 6443, 6449, 6455, 6461, 6467, 6473, 6478, 6484, 6490, - 6496, 6502, 6508, 6514, 6520, 6526, 6532, 6538, 6543, 6549, 6555, 6561, - 6567, 6573, 6579, 6585, 6591, 6597, 6603, 6608, 6612, 6615, 6623, 6630, - 6633, 6637, 6650, 6654, 6658, 6662, 6665, 6669, 6674, 6678, 6687, 6691, - 6697, 6704, 6715, 6723, 6730, 6736, 6740, 6748, 6757, 6763, 6767, 6779, - 6784, 6787, 6792, 6796, 6806, 6814, 6822, 6830, 6836, 6840, 6850, 6860, - 6868, 6875, 6882, 6888, 6894, 6901, 6905, 6912, 6922, 6932, 6940, 6947, - 6952, 6956, 6960, 6968, 6972, 6982, 6987, 6994, 7001, 7009, 7019, 7024, - 7028, 7033, 7037, 7044, 7049, 7063, 7068, 7073, 7080, 3774, 7089, 7093, - 7097, 7102, 7106, 7110, 7113, 7118, 7123, 7132, 7138, 7144, 7149, 7155, - 7159, 7170, 7180, 7195, 7210, 7225, 7240, 7255, 7270, 7285, 7300, 7315, - 7330, 7345, 7360, 7375, 7390, 7405, 7420, 7435, 7450, 7465, 7480, 7495, - 7510, 7525, 7540, 7555, 7570, 7585, 7600, 7615, 7630, 7645, 7660, 7675, - 7690, 7705, 7720, 7735, 7750, 7765, 7780, 7795, 7810, 7825, 7840, 7855, - 7870, 7885, 7900, 7915, 7924, 7933, 7938, 7944, 7954, 7958, 7962, 7967, - 7972, 7977, 7985, 7989, 7992, 7996, 3221, 7999, 8004, 340, 545, 8010, - 8013, 8021, 8025, 8029, 8032, 8036, 8042, 8046, 8054, 8060, 8065, 8072, - 8080, 8087, 8093, 8098, 8105, 8111, 8120, 8128, 8132, 8137, 8145, 8157, - 8168, 8175, 8186, 8190, 8194, 8198, 8201, 8207, 3525, 8211, 8213, 8219, - 8224, 8229, 8234, 8240, 8245, 8250, 8255, 8260, 8266, 8271, 8276, 8282, - 8287, 8293, 8298, 8304, 8309, 8315, 8320, 8325, 8330, 8335, 8340, 8346, - 8351, 8356, 8361, 8367, 8373, 8379, 8385, 8391, 8397, 8403, 8409, 8415, - 8421, 8427, 8433, 8438, 8443, 8448, 8453, 8458, 8463, 8468, 8473, 8479, - 8485, 8490, 8496, 8502, 8508, 8513, 8518, 8523, 8528, 8534, 8540, 8545, - 8550, 8555, 8560, 8565, 8571, 8576, 8582, 8588, 8594, 8600, 8606, 8612, - 8618, 8624, 8630, 2209, 8031, 8635, 8639, 8647, 8651, 8654, 8657, 8663, - 8670, 1113, 8673, 8677, 8685, 8690, 8695, 8686, 8700, 2236, 8704, 8710, - 8716, 8721, 8726, 8733, 8741, 8746, 8750, 8753, 8757, 8763, 8769, 8773, - 1659, 627, 8776, 8780, 8785, 8791, 8796, 8800, 8803, 8807, 8813, 8818, - 8822, 8829, 8833, 8837, 8841, 793, 8661, 2260, 8844, 8852, 8859, 8866, - 8872, 8879, 8887, 8894, 8905, 8912, 8918, 8930, 1129, 1294, 1299, 8941, - 8945, 1304, 8949, 8953, 8962, 8970, 8974, 8983, 8989, 8995, 9000, 9004, - 9010, 9015, 9023, 9030, 2920, 9037, 9043, 9047, 9056, 9065, 9074, 9083, - 9089, 9094, 9099, 9110, 9119, 9131, 9136, 9144, 2295, 9148, 9150, 9155, - 9159, 9168, 9176, 1308, 168, 3816, 3821, 9182, 9186, 9195, 9201, 9206, - 9209, 9213, 9217, 9222, 9227, 9232, 9237, 9241, 9250, 9256, 2307, 9260, - 2912, 9264, 9272, 9276, 9280, 2311, 9284, 9288, 9292, 9296, 9300, 2316, - 9304, 9309, 9316, 9322, 9329, 9335, 9338, 9234, 9340, 9348, 9356, 9364, - 9367, 9372, 2329, 9377, 8697, 9380, 9382, 9387, 9392, 9397, 9402, 9407, - 9412, 9417, 9422, 9427, 9432, 9438, 9443, 9448, 9453, 9459, 9464, 9469, - 9474, 9479, 9484, 9489, 9495, 9500, 9505, 9510, 9515, 9520, 9525, 9530, - 9535, 9540, 9545, 9550, 9555, 9560, 9565, 9570, 9575, 9580, 9586, 9592, - 9597, 9602, 9607, 9612, 9617, 2340, 2347, 2353, 9622, 9630, 9636, 9644, - 2379, 2385, 9652, 2390, 2395, 2400, 2405, 9656, 9660, 9665, 9669, 9673, - 9677, 9682, 9686, 9691, 9695, 9698, 9701, 9707, 9714, 9720, 9727, 9733, - 9740, 9746, 9753, 9759, 9765, 9774, 9780, 9784, 9788, 9792, 9796, 9801, - 9805, 9810, 9814, 9820, 9824, 9829, 9836, 9847, 9855, 9865, 9871, 9881, - 9890, 9897, 9902, 9906, 9917, 9927, 9940, 9951, 9964, 9975, 9987, 9999, - 10011, 10022, 10035, 10048, 10055, 10061, 10072, 10082, 10096, 10103, - 10109, 10118, 10126, 10130, 10135, 10139, 10146, 10154, 10161, 10165, - 10171, 10175, 10181, 10191, 10195, 10200, 10205, 10212, 10218, 8874, - 10228, 10232, 10239, 10245, 10252, 10259, 10263, 10266, 10272, 10276, - 10281, 10286, 10291, 10295, 10301, 10309, 10316, 10322, 10326, 10329, - 10335, 10345, 10349, 10355, 10360, 10364, 10369, 10373, 10379, 10385, - 10390, 10396, 10401, 10406, 10411, 2232, 10416, 10418, 10423, 10431, - 10440, 10444, 10450, 10455, 10460, 10465, 10470, 10476, 10481, 10486, - 4592, 10491, 10496, 10500, 10506, 10511, 10517, 10522, 10527, 10533, - 10538, 10445, 10544, 10548, 10555, 10561, 10566, 10570, 7059, 10575, - 10584, 10589, 10594, 9312, 9319, 10599, 3094, 10603, 10608, 10613, 10618, - 10456, 10622, 10627, 10632, 10461, 10636, 10466, 10641, 10648, 10655, - 10661, 10668, 10674, 10680, 10685, 10692, 10697, 10702, 10707, 10713, - 10471, 10477, 10719, 10724, 10730, 10735, 10740, 10748, 1364, 10753, - 1037, 10756, 10764, 10780, 10796, 10811, 10819, 10825, 10831, 10840, - 10848, 10856, 10864, 10872, 10880, 10888, 10896, 10904, 10913, 10922, - 10930, 10939, 10948, 10957, 10966, 10975, 10984, 10993, 11002, 11011, - 11020, 11028, 11033, 11037, 11043, 11051, 11058, 11073, 11090, 11109, - 11118, 11126, 11141, 11152, 11160, 11166, 11176, 11186, 11194, 11200, - 11212, 11221, 11229, 11236, 11243, 11250, 11256, 11261, 11271, 11277, - 11285, 11295, 11302, 11312, 11322, 11332, 11340, 11347, 11356, 11366, - 11380, 11395, 11404, 11412, 11417, 11421, 11431, 11441, 11453, 11462, - 11468, 11473, 11483, 11493, 11503, 11508, 11512, 11522, 11531, 11536, - 11552, 11569, 11579, 11584, 11595, 11608, 11619, 11627, 11640, 11652, - 11660, 11665, 11669, 11675, 11680, 11688, 11696, 11703, 11714, 11719, - 11727, 11737, 11743, 11747, 11750, 11754, 11760, 11767, 11771, 11779, - 11788, 11796, 11803, 11808, 11812, 11817, 11821, 11825, 11833, 11848, - 11864, 11870, 11878, 11887, 11895, 11901, 11905, 11912, 11923, 11927, - 11930, 11941, 11947, 11952, 10487, 11960, 11966, 11973, 11979, 11984, - 11991, 11998, 12005, 12012, 12019, 12026, 12033, 12040, 12047, 12054, - 12061, 12068, 12075, 12082, 12089, 12094, 11086, 12099, 12105, 12112, - 12119, 12124, 12131, 12140, 12144, 12151, 12163, 12167, 12173, 12178, - 12183, 12188, 12193, 12198, 12203, 12206, 12210, 11437, 12214, 12218, - 12224, 12230, 12235, 12241, 12246, 12251, 12257, 12262, 12267, 10208, - 12272, 12276, 12280, 12284, 12289, 12294, 12299, 12307, 12313, 12318, - 12322, 12326, 12333, 12338, 12346, 12353, 12358, 12362, 12365, 12371, - 12378, 12382, 12385, 12390, 12394, 4631, 12400, 12409, 46, 12417, 12423, - 12428, 12433, 12441, 12448, 12453, 6977, 12459, 12465, 12470, 12474, - 12477, 12483, 12491, 12498, 12513, 12532, 12544, 12557, 12570, 12583, - 12597, 12610, 12625, 12632, 10492, 12638, 12652, 12657, 12663, 12668, - 12676, 12681, 9052, 12686, 12689, 12697, 12704, 12709, 12713, 12719, - 12723, 12728, 12733, 12738, 12743, 12748, 12753, 3099, 11174, 12758, - 12762, 12768, 12774, 12779, 12785, 12790, 10501, 12796, 12802, 12807, - 12812, 12820, 12826, 12839, 12847, 12854, 12860, 10507, 12866, 12874, - 12882, 12889, 12902, 12915, 12927, 12937, 12949, 12977, 12985, 12994, - 13001, 13013, 13020, 13030, 13039, 13047, 13054, 13059, 13065, 10512, - 13070, 13076, 13081, 13086, 13091, 10518, 13096, 13099, 13106, 13112, - 13126, 13139, 13150, 9840, 13161, 13167, 13176, 13184, 13191, 13197, - 13208, 13214, 13219, 13227, 4119, 13233, 13238, 12505, 13244, 13251, - 13256, 10523, 13262, 13267, 13274, 13280, 13286, 13291, 13299, 13307, - 13314, 13318, 13330, 13344, 13354, 13359, 13363, 13374, 13380, 13385, - 13390, 10528, 13394, 10534, 13399, 13402, 13407, 13419, 13426, 13431, - 13435, 13443, 13448, 13452, 13457, 13461, 13468, 13474, 10539, 10446, - 13481, 3104, 17, 13488, 13493, 13497, 13501, 13507, 13515, 13525, 13530, - 13535, 13542, 13549, 13553, 13564, 13574, 13583, 13592, 13604, 13609, - 13613, 13621, 13635, 13639, 13642, 13646, 13654, 13661, 13669, 13673, - 13684, 13692, 13696, 13703, 13708, 13712, 13718, 13723, 13729, 13734, - 13739, 13743, 13749, 13754, 13765, 13769, 13772, 13778, 13785, 13791, - 13796, 13802, 13808, 13815, 13826, 13836, 13846, 13855, 13862, 13871, - 13875, 10549, 10556, 10562, 10567, 13881, 13887, 13893, 13898, 13904, - 10571, 13910, 13913, 13920, 13925, 13931, 13936, 13951, 13967, 13982, - 13990, 13995, 14002, 14008, 14012, 14017, 14022, 14027, 14032, 14037, - 14042, 14047, 14052, 14057, 1567, 388, 14062, 14070, 14077, 14083, 14088, - 14093, 10576, 14095, 14099, 14104, 14108, 14118, 14123, 14127, 14130, - 14139, 14143, 14146, 14153, 10585, 14158, 14161, 14169, 14176, 14184, - 14188, 14194, 14202, 14206, 14213, 14222, 14229, 14225, 14236, 14240, - 14246, 14250, 14254, 14258, 14264, 14270, 14280, 14288, 14295, 14299, - 14307, 14312, 14316, 14323, 14328, 14335, 14339, 14344, 14349, 14353, - 14360, 14366, 14374, 14380, 14385, 14395, 14402, 14407, 14412, 14416, - 14420, 14428, 4461, 14436, 14441, 10590, 14445, 14452, 14456, 14459, - 14467, 14474, 14478, 14481, 6832, 14485, 14490, 14495, 14499, 14510, - 14520, 14525, 14531, 14536, 14545, 14549, 14552, 14560, 14565, 14570, - 14577, 14582, 4851, 10595, 14587, 14591, 14598, 14603, 14608, 14613, - 1664, 7007, 14618, 14623, 14628, 14633, 14639, 14644, 14650, 14655, - 14660, 14665, 14670, 14675, 14680, 14685, 14690, 14695, 14700, 14705, - 14710, 14715, 14720, 14725, 14730, 14736, 14741, 14746, 14751, 14756, - 14761, 14767, 14772, 14777, 14783, 14788, 14794, 14799, 14805, 14810, - 14815, 14820, 14825, 14831, 14836, 14841, 14846, 14854, 1008, 112, 14860, - 14864, 14869, 14874, 14878, 14882, 14886, 14891, 14895, 14900, 14904, - 14907, 14911, 14915, 14921, 14926, 14936, 14942, 14950, 14956, 14960, - 14964, 14971, 14979, 14988, 14999, 15009, 15016, 15023, 15027, 15036, - 15045, 15053, 15060, 15069, 15078, 15087, 15096, 15106, 15116, 15126, - 15136, 15146, 15155, 15165, 15175, 15185, 15195, 15205, 15215, 15225, - 15234, 15244, 15254, 15264, 15274, 15284, 15294, 15303, 15313, 15323, - 15333, 15343, 15353, 15363, 15373, 15383, 15393, 15402, 15412, 15422, - 15432, 15442, 15452, 15462, 15472, 15482, 15492, 15502, 15511, 15517, - 1138, 15521, 15524, 15528, 15533, 15540, 15546, 15551, 15555, 15560, - 15569, 15578, 15586, 15591, 15595, 15599, 15605, 15610, 15616, 10604, - 15621, 15626, 15635, 15640, 10614, 15645, 11424, 11434, 11444, 15648, - 15654, 15662, 10619, 15669, 15673, 15677, 15682, 15686, 15696, 15702, - 15708, 15713, 15722, 15730, 15737, 15744, 15749, 15756, 15761, 15765, - 15768, 15779, 15789, 15802, 15811, 15819, 15830, 15842, 15852, 15862, - 15867, 15871, 15876, 15881, 15885, 15891, 15899, 15906, 15917, 15922, - 15932, 15941, 15945, 15948, 15955, 15965, 15974, 15981, 15985, 15992, - 15998, 16003, 16008, 16012, 15564, 16021, 16025, 16031, 16035, 16040, - 16044, 16051, 16058, 16062, 16071, 16079, 16087, 16094, 16102, 16114, - 16125, 16135, 16142, 16148, 16157, 16168, 16177, 16189, 16201, 16213, - 16223, 16232, 16242, 16251, 16259, 16266, 16276, 16285, 16293, 16297, - 16302, 16308, 16314, 16319, 16324, 16328, 16333, 16338, 16343, 16348, - 16353, 16358, 16363, 8718, 16368, 16370, 16374, 16379, 16385, 16392, - 16398, 16404, 16413, 16417, 16423, 16431, 16438, 16447, 16456, 16465, - 16474, 16483, 16492, 16501, 16510, 16520, 16530, 16539, 16545, 16552, - 16559, 16565, 16579, 16585, 16592, 16600, 16609, 16617, 16623, 16632, - 16638, 16647, 16658, 16664, 16674, 16682, 16689, 16697, 16705, 16712, - 16721, 16734, 16743, 16751, 16758, 16771, 16777, 16783, 16793, 16802, - 16811, 16820, 16828, 16833, 16837, 16843, 16849, 16854, 16861, 16868, - 10222, 16873, 16878, 16885, 16893, 16898, 16910, 16917, 16922, 16934, - 14917, 16939, 16945, 16953, 16959, 16964, 16972, 16980, 16987, 16995, - 17002, 17008, 17014, 17022, 17030, 17036, 17044, 17050, 17055, 17061, - 17068, 17074, 17079, 17083, 17094, 17102, 17110, 17116, 17121, 17128, - 17137, 17143, 17148, 17156, 17163, 17172, 17186, 4405, 17190, 17195, - 17200, 17206, 17211, 17216, 17220, 17225, 17230, 17235, 8717, 17240, - 17245, 17250, 17255, 17260, 17264, 17269, 17274, 17279, 17284, 17290, - 17296, 14190, 17301, 17307, 17312, 17317, 17322, 10623, 17327, 17332, - 17337, 17342, 17347, 17361, 17378, 17396, 17408, 17421, 17438, 17454, - 17471, 17481, 17500, 17511, 17522, 17533, 2809, 17544, 17555, 17566, - 17583, 17594, 17605, 17610, 10628, 17615, 17619, 2489, 17623, 17629, - 17632, 17638, 17646, 17654, 17660, 17669, 17676, 17681, 17689, 17697, - 17704, 17708, 17713, 17719, 17726, 17734, 17741, 17753, 17760, 17766, - 17774, 17779, 17785, 17791, 17796, 13945, 17803, 17807, 17816, 17822, - 17827, 17835, 17844, 17852, 17859, 17865, 17873, 17880, 17886, 17892, - 17899, 17906, 17912, 17918, 17922, 17931, 17939, 17944, 17954, 17961, - 17967, 17975, 17981, 17989, 17997, 18004, 18017, 18021, 18028, 18037, - 18046, 18055, 18063, 18073, 18080, 18085, 3975, 18092, 18097, 1254, - 18101, 18108, 17241, 18112, 18118, 18122, 18130, 18142, 18147, 18154, - 18160, 18165, 18172, 17246, 18176, 18180, 18188, 18193, 18197, 17251, - 18201, 17256, 18205, 18212, 18217, 18221, 18228, 18232, 18235, 18243, - 18250, 18255, 18263, 18267, 18274, 18291, 18300, 18309, 18313, 18316, - 18322, 18330, 18336, 18341, 18345, 18350, 18355, 18360, 18365, 18370, - 18375, 4053, 18380, 18382, 18390, 18397, 18407, 18419, 18424, 18428, - 18434, 18439, 18447, 18451, 18457, 18462, 18468, 18471, 18478, 18486, - 18493, 18499, 18504, 18510, 18515, 18522, 18528, 18533, 18543, 18552, - 18559, 18564, 18568, 18574, 18580, 18584, 18591, 18597, 18602, 18608, - 18616, 18624, 18631, 18637, 18643, 18648, 18654, 18660, 18668, 18673, - 18678, 18686, 18692, 18698, 18703, 18710, 18715, 18719, 18725, 18731, - 18736, 18742, 18749, 18754, 18760, 18763, 18769, 18780, 18786, 18795, - 18798, 18802, 18806, 18820, 18833, 18845, 18851, 18856, 18863, 18869, - 18875, 18886, 18898, 18910, 18920, 18929, 18937, 18944, 18955, 18965, - 18975, 18983, 18986, 17270, 18991, 18996, 19003, 17275, 17426, 19011, - 19024, 19039, 19050, 17443, 19068, 19081, 19094, 19105, 12520, 19116, - 19129, 19148, 19159, 19170, 19181, 2830, 19194, 19198, 19206, 19217, - 19228, 19236, 19251, 19266, 19277, 19284, 19290, 19298, 19302, 19308, - 19312, 19315, 19328, 19340, 19350, 19358, 19365, 19373, 19383, 19388, - 19395, 19400, 19407, 19418, 19428, 19434, 19439, 19444, 17280, 19448, - 19454, 19461, 19467, 19472, 19477, 19482, 19486, 17285, 17291, 19490, - 17297, 19495, 19503, 19508, 19512, 19519, 19527, 19534, 19543, 19550, - 19554, 19558, 19563, 19568, 19573, 19578, 19583, 10467, 19588, 19590, - 19595, 19600, 19606, 19611, 19616, 19621, 19626, 19630, 19636, 19642, - 19647, 19653, 19658, 19663, 19667, 19673, 19678, 19682, 19687, 19692, - 19704, 19709, 19715, 19720, 19725, 19731, 19737, 19742, 19747, 19752, - 19759, 19765, 19776, 19783, 19792, 19797, 19801, 279, 19805, 19813, - 19818, 19824, 19830, 19835, 19842, 19849, 19855, 19860, 19866, 19871, - 19876, 19881, 19888, 19898, 19906, 19911, 19916, 19923, 19929, 19938, - 19948, 19958, 19972, 19986, 20000, 20014, 20029, 20044, 20061, 20079, - 20092, 20098, 20103, 20108, 20112, 20120, 20125, 20133, 20139, 20145, - 20150, 20155, 20159, 20165, 20170, 20174, 20181, 20186, 20190, 20201, - 20207, 20212, 20217, 20224, 20229, 20233, 3933, 20238, 20244, 20251, - 17302, 20257, 20261, 20267, 20272, 20277, 20281, 20287, 20292, 20297, - 20304, 20309, 15698, 20313, 20318, 20322, 20327, 20333, 20339, 20346, - 20356, 20364, 20371, 20376, 20380, 20389, 20397, 20404, 20411, 20417, - 20422, 20428, 20433, 20438, 20444, 20449, 20455, 20460, 20466, 20472, - 20479, 20485, 20490, 20495, 10693, 20504, 20507, 20515, 20521, 20526, - 20531, 20541, 20548, 20554, 20559, 20564, 20570, 20575, 20581, 20586, - 20592, 20599, 20605, 20611, 20616, 20624, 20631, 20636, 20641, 20647, - 20652, 20656, 20665, 20676, 20683, 20690, 20698, 20705, 20712, 20717, - 20722, 20728, 20733, 20741, 20747, 20753, 20758, 20765, 20771, 20776, - 20780, 20786, 20791, 20796, 20800, 20805, 1327, 8742, 3118, 20809, 20813, - 20817, 20821, 20825, 20829, 20832, 20837, 20844, 20852, 20862, 20873, - 20883, 20894, 20906, 20917, 20927, 20938, 20950, 20961, 20973, 20986, - 20998, 21009, 21019, 21030, 21042, 21053, 21066, 21078, 21089, 21101, - 21114, 21126, 21139, 21153, 21166, 21178, 21189, 21199, 21210, 21222, - 21233, 21245, 21258, 21270, 21281, 21293, 21306, 21319, 21333, 21346, - 21358, 21369, 21381, 21394, 21406, 21419, 21433, 21446, 21458, 21471, - 21485, 21498, 21512, 21526, 21539, 21551, 21562, 21572, 17313, 21579, - 21585, 21595, 21603, 21610, 21618, 21628, 21637, 21650, 21655, 21660, - 21668, 21675, 15807, 15816, 21682, 21692, 21707, 21713, 21720, 21727, - 21734, 21740, 21746, 21757, 21765, 21773, 21783, 21793, 21802, 17318, - 21811, 21817, 21823, 21832, 21840, 21848, 21853, 21862, 21870, 21882, - 21892, 21902, 21912, 21921, 21933, 21943, 21953, 21964, 21971, 21976, - 21983, 21995, 22007, 22019, 22031, 22043, 22055, 22067, 22079, 22091, - 22103, 22114, 22126, 22138, 22150, 22162, 22174, 22186, 22198, 22210, - 22222, 22234, 22245, 22257, 22269, 22281, 22293, 22305, 22317, 22329, - 22341, 22353, 22365, 22376, 22388, 22400, 22412, 22424, 22436, 22448, - 22460, 22472, 22484, 22496, 22507, 22519, 22531, 22543, 22555, 22567, - 22579, 22591, 22603, 22615, 22627, 22638, 22650, 22662, 22674, 22686, - 22698, 22710, 22722, 22734, 22746, 22758, 22769, 22781, 22793, 22805, - 22817, 22829, 22841, 22853, 22865, 22877, 22889, 22900, 22912, 22924, - 22936, 22948, 22961, 22974, 22987, 23000, 23013, 23026, 23039, 23051, - 23064, 23077, 23090, 23103, 23116, 23129, 23142, 23155, 23168, 23181, - 23193, 23206, 23219, 23232, 23245, 23258, 23271, 23284, 23297, 23310, - 23323, 23335, 23348, 23361, 23374, 23387, 23400, 23413, 23426, 23439, - 23452, 23465, 23477, 23490, 23503, 23516, 23529, 23542, 23555, 23568, - 23581, 23594, 23607, 23619, 23632, 23645, 23658, 23671, 23684, 23697, - 23710, 23723, 23736, 23749, 23761, 23772, 23785, 23798, 23811, 23824, - 23837, 23850, 23863, 23876, 23889, 23902, 23914, 23927, 23940, 23953, - 23966, 23979, 23992, 24005, 24018, 24031, 24044, 24056, 24069, 24082, - 24095, 24108, 24121, 24134, 24147, 24160, 24173, 24186, 24198, 24211, - 24224, 24237, 24250, 24263, 24276, 24289, 24302, 24315, 24328, 24340, - 24353, 24366, 24379, 24392, 24405, 24418, 24431, 24444, 24457, 24470, - 24482, 24495, 24508, 24521, 24534, 24547, 24560, 24573, 24586, 24599, - 24612, 24624, 24637, 24650, 24663, 24676, 24689, 24702, 24715, 24728, - 24741, 24754, 24766, 24779, 24792, 24805, 24818, 24831, 24844, 24857, - 24870, 24883, 24896, 24908, 24921, 24934, 24947, 24960, 24973, 24986, - 24999, 25012, 25025, 25038, 25050, 25063, 25076, 25089, 25102, 25115, - 25128, 25141, 25154, 25167, 25180, 25192, 25203, 25212, 25220, 25228, - 25235, 25241, 25245, 25251, 25257, 25266, 25274, 25279, 25285, 25290, - 25294, 25303, 10472, 25314, 25320, 25327, 25335, 25342, 13119, 13133, - 25349, 25356, 25365, 25370, 25375, 25382, 25387, 25392, 8758, 8764, 8770, - 25397, 25402, 25405, 25410, 25418, 25425, 25432, 25444, 25451, 25457, - 25466, 25471, 25480, 25489, 25495, 25503, 25512, 25516, 25522, 25527, - 25537, 25544, 25550, 25558, 25564, 25571, 25577, 25587, 25596, 25600, - 25607, 25611, 25616, 25622, 25630, 25634, 25644, 17328, 25653, 25659, - 25663, 25672, 25681, 25691, 25697, 17333, 25704, 25711, 25722, 25730, - 25740, 25749, 25757, 10187, 25765, 25770, 25776, 25781, 25785, 25789, - 25793, 11281, 25798, 25806, 25813, 25822, 25830, 25837, 25844, 25853, - 25859, 1059, 25866, 25872, 25876, 25882, 25889, 25895, 25903, 25909, - 25916, 25922, 25928, 25937, 25941, 25949, 25957, 25964, 25973, 25980, - 25985, 25989, 25999, 26010, 26021, 26026, 26031, 26037, 26046, 26051, - 26064, 8980, 26068, 26074, 26080, 26086, 26091, 26099, 26103, 26110, - 26119, 26124, 17606, 26132, 26136, 26148, 26153, 26157, 26160, 26166, - 26172, 26178, 26183, 26188, 26192, 26195, 26206, 26211, 10749, 26218, - 26223, 26228, 26233, 26238, 26243, 26248, 26253, 26258, 10754, 26263, - 26268, 26273, 26278, 26283, 26288, 26293, 26298, 26303, 26308, 26313, - 26318, 26324, 26329, 26334, 26339, 26344, 26349, 26354, 26359, 26364, - 26369, 26375, 26381, 26386, 26391, 26396, 26401, 26406, 26411, 26416, - 26421, 26426, 26432, 26437, 26442, 26447, 26453, 26459, 26464, 26469, - 26474, 26479, 26484, 26489, 26494, 26499, 26505, 26510, 26515, 26520, - 26525, 26531, 26536, 26541, 26545, 1250, 145, 26553, 26557, 26561, 26565, - 26570, 26574, 15704, 2415, 26578, 26583, 26587, 26592, 26596, 26601, - 26605, 26611, 26616, 26620, 26624, 26632, 26636, 26640, 26647, 26652, - 26657, 26661, 26667, 26672, 26676, 26681, 26686, 26690, 26697, 26704, - 26711, 26716, 26720, 26724, 26729, 26733, 26736, 26742, 26755, 26760, - 26766, 26775, 26780, 11029, 26785, 26794, 26799, 26802, 26806, 26811, - 26816, 26821, 26826, 26831, 2926, 2931, 26836, 26842, 26846, 26852, 3894, - 26857, 26862, 26867, 26873, 26878, 16654, 26883, 26888, 26893, 26898, - 26904, 26909, 26914, 26920, 26925, 26929, 26934, 26939, 26944, 26949, - 26954, 26958, 26963, 26967, 26972, 26977, 26982, 26987, 26991, 26996, - 27000, 27005, 27010, 27015, 26930, 3127, 26935, 27020, 27028, 27035, - 11375, 27047, 27055, 27065, 27083, 27102, 27111, 27119, 26940, 27126, - 27131, 27139, 26945, 27144, 27149, 27157, 27162, 27167, 27171, 19826, - 27176, 27184, 27189, 27193, 27200, 27206, 27215, 27219, 27227, 27233, - 27237, 27240, 20660, 27247, 27251, 27255, 27260, 27266, 27273, 27278, - 10214, 27282, 27287, 27292, 27297, 27302, 27307, 1669, 1674, 27312, - 27318, 27324, 27329, 27333, 27337, 27341, 27345, 27349, 27353, 27357, - 27361, 25438, 27364, 27371, 27379, 27385, 27391, 27396, 27401, 27407, - 27411, 27416, 27423, 16554, 16561, 27429, 27441, 27444, 27451, 27455, - 19851, 27462, 27470, 27481, 27490, 27503, 27513, 27527, 27539, 27553, - 27566, 27578, 27588, 27600, 27606, 27621, 27645, 27663, 27682, 27695, - 27709, 27727, 27743, 27760, 27778, 27789, 27808, 27825, 27845, 27863, - 27875, 27889, 27903, 27915, 27932, 27951, 27969, 27981, 27999, 28018, - 17486, 28031, 28051, 28063, 12551, 28075, 28080, 28085, 28090, 28099, - 28105, 28110, 28114, 28121, 28127, 28131, 28136, 28141, 28146, 28151, - 28156, 28161, 2512, 28166, 28172, 28176, 28179, 28190, 28194, 28197, - 28205, 28211, 14856, 28215, 28224, 28235, 28241, 28247, 28262, 28271, - 28279, 28286, 28291, 28295, 28302, 28308, 28317, 28325, 28332, 28342, - 28351, 28361, 28366, 28375, 28384, 28395, 28406, 28416, 28433, 4549, - 28443, 28447, 28457, 28465, 28475, 28486, 28492, 28497, 28507, 28515, - 28522, 28528, 28535, 28540, 26978, 28544, 28553, 28557, 28560, 28565, - 28573, 28580, 28589, 28597, 28605, 28613, 28623, 28632, 28638, 28644, - 28650, 28654, 26983, 26988, 28658, 28668, 28678, 28688, 28696, 28703, - 28713, 28721, 28729, 28735, 28743, 802, 28752, 17693, 649, 28766, 28775, - 28783, 28794, 28805, 28815, 28824, 28836, 28845, 28854, 28861, 28867, - 28877, 28886, 28895, 28903, 28911, 28921, 28929, 28937, 28944, 28950, - 28955, 28960, 28965, 8142, 28970, 28973, 28977, 28982, 28990, 28996, - 29001, 29005, 3757, 27001, 29013, 27006, 29019, 29025, 29031, 29036, - 29041, 29045, 29053, 29059, 29065, 29069, 3918, 29077, 29082, 29087, - 29091, 29095, 11661, 29102, 29110, 29124, 29131, 29138, 29144, 11670, - 11676, 29152, 29160, 29167, 29172, 29177, 27011, 29183, 29194, 29203, - 18999, 29211, 29216, 2761, 29221, 29232, 29238, 29243, 29247, 29251, - 29254, 29261, 29268, 29274, 29282, 29289, 29295, 29299, 8182, 29304, - 29308, 29312, 29320, 29325, 29330, 29335, 1702, 29340, 29345, 29350, - 29355, 29360, 29365, 29370, 29375, 29380, 29385, 29390, 29395, 29400, - 29405, 29411, 29416, 29421, 29426, 29431, 29436, 29441, 29447, 29452, - 29457, 29462, 29467, 29472, 29477, 29482, 29488, 29494, 29499, 29505, - 29510, 29515, 5, 29521, 29525, 29529, 29533, 29538, 29542, 29546, 29550, - 29554, 29559, 29563, 29568, 29572, 29575, 29579, 29584, 29588, 29593, - 29597, 29601, 29605, 29610, 29614, 29618, 29628, 29633, 29637, 29641, - 29646, 29651, 29660, 29665, 29670, 29674, 29678, 29687, 29700, 29712, - 29721, 29730, 29735, 29741, 29746, 29750, 29754, 29764, 29773, 29781, - 29787, 29792, 29796, 29803, 29810, 29820, 29829, 29837, 12908, 29845, - 29853, 29862, 29871, 29879, 29889, 29894, 29898, 29902, 29905, 29907, - 29911, 29915, 29920, 29925, 29929, 29933, 29936, 29940, 29943, 29947, - 29950, 29953, 29957, 29963, 29967, 29971, 29975, 29979, 29984, 29989, - 29994, 29998, 30001, 30006, 30012, 30017, 30023, 30028, 30032, 30038, - 30042, 30046, 30051, 30055, 30060, 30065, 30069, 30073, 30080, 30084, - 30087, 30091, 30095, 30101, 30107, 30111, 30115, 30120, 30127, 30133, - 30137, 30146, 30150, 30154, 30157, 30163, 30168, 30174, 1391, 1754, - 30179, 30184, 30189, 30194, 30199, 30204, 30209, 2219, 824, 30214, 30217, - 30221, 30225, 30230, 30234, 17705, 30238, 30243, 30248, 30252, 30255, - 30260, 30264, 30269, 30273, 17709, 30278, 30281, 30284, 30290, 30294, - 30299, 30303, 30316, 30324, 30328, 30331, 30339, 30348, 30355, 30360, - 30366, 30372, 30380, 30387, 30394, 30398, 30402, 30406, 30411, 30416, - 30420, 30428, 30433, 30440, 30452, 30463, 30468, 30472, 30479, 30483, - 30488, 30494, 30497, 30502, 30507, 30514, 30518, 30522, 30525, 30531, - 8880, 2419, 30535, 30540, 30556, 11080, 30576, 30585, 30601, 30605, - 30612, 30615, 30621, 30631, 30637, 30646, 30655, 30670, 30681, 30693, - 30704, 30712, 30721, 30727, 30736, 30746, 30756, 30767, 30778, 30788, - 30797, 30804, 30813, 30821, 30828, 30835, 30842, 30850, 30857, 30864, - 30877, 30884, 30892, 30899, 30905, 30910, 30919, 30926, 30932, 30937, - 30945, 30953, 30960, 30967, 28467, 30979, 30991, 31005, 31013, 31021, - 31029, 31036, 31048, 31057, 31066, 31074, 31082, 31090, 31097, 31103, - 31112, 31120, 31130, 31139, 31149, 31158, 31167, 31175, 31180, 31184, - 31187, 31191, 31195, 31199, 31203, 31207, 31213, 31219, 31224, 31232, - 31239, 31247, 31254, 10786, 17767, 31262, 31269, 31274, 31281, 31287, - 31293, 31300, 13998, 31307, 31310, 31322, 31330, 31336, 31341, 31345, - 31356, 31366, 31376, 11600, 31385, 31394, 31402, 31412, 31421, 31428, - 31435, 31443, 31447, 17786, 31450, 31457, 31461, 4493, 31467, 31470, - 31477, 31483, 31497, 31502, 31510, 31516, 31527, 31534, 31540, 31546, - 31550, 31555, 31559, 31568, 31575, 31581, 8933, 31588, 31596, 31603, - 31609, 31614, 31620, 31626, 31636, 31648, 31659, 31669, 31677, 31683, - 17804, 31687, 31689, 31192, 11613, 31698, 31703, 31709, 31719, 31724, - 31731, 31739, 31745, 31750, 31755, 31760, 31764, 31769, 31776, 31782, - 31791, 31799, 31803, 31810, 31820, 31826, 31835, 31841, 31848, 4763, - 31854, 31860, 31865, 31872, 31884, 31895, 31900, 31908, 31912, 31922, - 31928, 31932, 31937, 31947, 31956, 31960, 31967, 31975, 31982, 31988, - 31993, 32001, 32008, 32013, 32020, 32032, 32041, 32045, 15630, 32053, - 32063, 32067, 32075, 32082, 32089, 30335, 32100, 32105, 32109, 32116, - 32123, 26663, 31117, 32128, 32132, 32135, 27795, 32140, 32154, 32170, - 32188, 32207, 32224, 32242, 27814, 32259, 32279, 27831, 32291, 32303, - 19055, 32315, 27851, 32329, 32341, 12564, 32355, 32360, 32365, 32370, - 32376, 32382, 32388, 32392, 32400, 32406, 32413, 32418, 32428, 32435, - 32441, 12102, 32447, 32449, 32454, 32462, 32466, 31772, 32472, 32479, - 13840, 13850, 32486, 32493, 32503, 32508, 32512, 32515, 32521, 32529, - 32541, 32551, 32567, 32580, 32594, 19073, 32608, 32615, 32619, 32622, - 32627, 32631, 32638, 32645, 32652, 32659, 32669, 32674, 32679, 32684, - 32692, 32700, 32705, 32714, 28488, 3567, 32719, 32722, 32725, 32730, - 32737, 32742, 32747, 32763, 32771, 32779, 10844, 32787, 32792, 32796, - 32802, 32807, 32813, 32816, 32822, 32834, 32842, 32849, 32855, 32862, - 32873, 32887, 32900, 32906, 32915, 32921, 32930, 32942, 32953, 32963, - 32972, 32981, 32989, 32999, 33008, 33019, 673, 33026, 33033, 33039, - 33044, 33050, 33057, 33063, 33074, 33084, 33094, 33103, 33109, 33116, - 33121, 33129, 33136, 33144, 33152, 33164, 7128, 33171, 33174, 33183, - 33191, 33197, 33203, 33208, 33212, 33215, 33221, 33228, 33233, 33238, - 33245, 33250, 33254, 33266, 33277, 33286, 33294, 17976, 33299, 33307, - 33312, 33320, 33326, 33332, 13833, 9782, 33337, 33341, 33345, 33348, - 33351, 33357, 33365, 33373, 33377, 33381, 33386, 33390, 33393, 33402, - 33407, 33412, 33416, 33419, 33424, 33432, 33443, 33452, 33456, 33462, - 33468, 33472, 33478, 33486, 33508, 33532, 33543, 33552, 33558, 33565, - 33572, 33578, 33586, 33592, 33597, 33608, 33626, 33633, 33641, 33645, - 33652, 33657, 33666, 33679, 33687, 33699, 33710, 33721, 33731, 33745, - 33754, 33762, 33774, 33785, 11097, 33794, 33805, 33816, 33828, 33838, - 33847, 33857, 33862, 33866, 33874, 33885, 33895, 33901, 33906, 33910, - 33913, 33916, 33924, 33932, 33941, 33951, 33960, 33966, 33971, 33985, - 2844, 34007, 34018, 34027, 34037, 34049, 34058, 34067, 34077, 34085, - 34093, 34102, 34107, 34118, 34123, 34132, 34138, 34149, 34153, 34156, - 34166, 34175, 34183, 34193, 34203, 34211, 34220, 34227, 34233, 34241, - 34248, 34257, 34266, 34271, 34276, 34280, 34288, 34295, 34301, 34305, - 34313, 34320, 34331, 34346, 34353, 34359, 34369, 34378, 34384, 34395, - 34399, 34406, 34410, 34417, 34423, 16806, 34429, 34433, 34438, 34444, - 34451, 34455, 34459, 34467, 34475, 34481, 34490, 34497, 34504, 34509, - 34514, 34524, 28542, 34528, 34531, 34536, 34541, 34546, 34551, 34556, - 34561, 34566, 34571, 34577, 34582, 34587, 34593, 1100, 766, 34598, 34601, - 34608, 34617, 1783, 34624, 34629, 34633, 34639, 1149, 643, 34644, 334, - 34648, 34658, 34667, 34675, 34684, 34692, 34699, 34710, 34718, 34727, - 34735, 34745, 34753, 34758, 11768, 34762, 34770, 34778, 34783, 17722, - 4107, 34789, 34795, 34801, 6655, 34806, 34810, 34817, 34823, 34829, - 34833, 34842, 34848, 34853, 34860, 1342, 34866, 34872, 34877, 34884, - 34888, 1249, 6663, 34893, 34903, 34911, 34917, 34927, 34936, 34944, - 34950, 34955, 34963, 34970, 13350, 34976, 34983, 34988, 34995, 35005, - 1410, 245, 2218, 35011, 35017, 35024, 35035, 35046, 35054, 35061, 35071, - 35080, 35088, 35097, 35104, 35111, 35124, 35131, 35137, 35148, 35167, - 35172, 1154, 35176, 35181, 35189, 3990, 35193, 35198, 35202, 35206, 1346, - 29934, 35216, 35220, 35225, 35229, 35235, 3852, 35241, 35249, 35256, - 35267, 35276, 35284, 35309, 35317, 35322, 3991, 399, 35328, 35336, 35344, - 35351, 35356, 35362, 35367, 2287, 12766, 35374, 35380, 31551, 31890, - 35386, 656, 106, 35390, 35394, 35400, 622, 10659, 35405, 35412, 35418, - 35422, 35426, 1555, 35429, 35433, 18264, 35436, 35441, 35448, 35454, - 8946, 35459, 35467, 35474, 35480, 27173, 35484, 35488, 35492, 35496, - 1840, 20172, 35500, 35505, 35509, 35512, 35520, 35528, 35533, 35542, - 35550, 35553, 35560, 35567, 27252, 35577, 35589, 35597, 35602, 35606, - 35614, 35621, 35628, 35637, 35643, 35650, 35657, 35660, 35664, 35668, - 1357, 35678, 35680, 35685, 35691, 35697, 35702, 35707, 35712, 35717, - 35722, 35727, 35732, 35737, 35742, 35747, 35752, 35757, 35762, 35767, - 35773, 35779, 35785, 35791, 35796, 35801, 35806, 35812, 35817, 35822, - 35827, 35833, 35838, 35844, 35849, 35854, 35859, 35864, 35870, 35875, - 35881, 35886, 35891, 35896, 35901, 35907, 35912, 35918, 35923, 35928, - 35933, 35938, 35943, 35948, 35953, 35958, 35963, 35969, 35975, 35981, - 35986, 35991, 35996, 36001, 36007, 36013, 36019, 36025, 36031, 36037, - 36042, 36048, 36053, 36058, 36063, 36068, 36074, 2558, 36079, 2565, 2572, - 2968, 36084, 2578, 2588, 36090, 2620, 2625, 2630, 36094, 36099, 36104, - 36110, 36115, 36120, 36124, 36129, 36135, 36140, 36145, 36150, 36156, - 36161, 36165, 36169, 36174, 36179, 36184, 36189, 36194, 36200, 36206, - 36211, 36215, 36220, 36226, 36230, 36235, 36240, 36245, 36250, 36254, - 36257, 36262, 36267, 36272, 36277, 36282, 36288, 36294, 36299, 36304, - 36309, 36313, 36318, 36323, 36328, 36333, 36338, 36343, 36347, 36352, - 36357, 36362, 36366, 36370, 36374, 36379, 36387, 36392, 36397, 36403, - 36409, 36415, 36420, 36428, 36432, 36435, 36440, 36445, 36449, 36454, - 36459, 36463, 36468, 36472, 36475, 36480, 4203, 21663, 36485, 36490, - 36495, 36500, 36508, 25833, 34881, 10298, 36513, 36518, 36522, 36527, - 36531, 36535, 36540, 36544, 36547, 36550, 36554, 36559, 36563, 36571, - 36575, 36578, 36583, 36587, 36591, 36596, 36601, 36605, 36611, 36616, - 36621, 36628, 36635, 36639, 36642, 36648, 36657, 36664, 36672, 36679, - 36683, 36688, 36692, 36696, 36702, 36707, 36713, 36717, 36723, 36728, - 36733, 36737, 36744, 36750, 36756, 36762, 36768, 36775, 36781, 36787, - 36793, 36799, 36805, 36811, 36817, 36824, 36830, 36837, 36843, 36849, - 36855, 36861, 36867, 36873, 36879, 36885, 36891, 36897, 36902, 36907, - 13705, 36912, 36918, 36923, 36928, 36933, 36938, 36941, 36947, 36952, - 36960, 36965, 36969, 36974, 36980, 36989, 36995, 37000, 37005, 37010, - 37014, 37019, 37023, 37028, 37033, 37038, 37043, 37050, 37057, 37063, - 37069, 37074, 19769, 37081, 37087, 37094, 37100, 37106, 37111, 37119, - 37124, 11268, 37128, 37133, 37138, 37144, 37149, 37154, 37158, 37163, - 37168, 37174, 37179, 37184, 37189, 37193, 37198, 37203, 37207, 37212, - 37217, 37221, 37226, 37230, 37235, 37240, 37245, 37249, 37254, 37258, - 37263, 37267, 37274, 37278, 37282, 18420, 37287, 37294, 37303, 37309, - 37315, 37324, 37332, 37341, 37349, 37354, 37358, 37365, 37371, 37379, - 37383, 37386, 37391, 37395, 37404, 37412, 37430, 37436, 1409, 37442, - 37445, 37449, 27319, 27325, 37455, 37459, 37470, 37481, 37492, 37504, - 37508, 37515, 37522, 37529, 37534, 37538, 37546, 37551, 37556, 37561, - 37566, 6720, 16710, 25832, 37571, 37576, 37580, 16701, 37585, 37591, - 37596, 37602, 37607, 37613, 37618, 37624, 37629, 37635, 37641, 37647, - 37652, 37608, 37614, 37656, 37661, 37667, 37672, 37678, 37683, 37689, - 37694, 37619, 12396, 37698, 37630, 37636, 37642, 3060, 3766, 37704, - 37707, 37712, 37718, 37724, 37730, 37737, 37743, 37749, 37755, 37761, - 37767, 37773, 37779, 37785, 37791, 37797, 37803, 37809, 37816, 37822, - 37828, 37834, 37840, 37846, 37849, 37854, 37857, 37864, 37869, 37877, - 37881, 37886, 37891, 37897, 37902, 37907, 37911, 37916, 37922, 37927, - 37933, 37938, 37944, 37949, 37955, 37961, 37965, 37970, 37975, 37980, - 37985, 37989, 37994, 37999, 38004, 38010, 38016, 38022, 38028, 38033, - 38037, 38040, 38046, 38052, 38061, 38069, 38076, 38081, 38085, 38089, - 38094, 18207, 38099, 38107, 38113, 4149, 1259, 38118, 38123, 38127, 8996, - 38133, 38139, 38146, 9005, 38150, 38156, 38162, 38169, 38175, 38184, - 38192, 38204, 38208, 38215, 38221, 38226, 38230, 38234, 38237, 38247, - 38256, 38264, 37609, 38269, 38279, 38289, 38299, 38305, 38310, 38320, - 38325, 38338, 38352, 38363, 38375, 38387, 38401, 38414, 38426, 38438, - 17527, 38452, 38457, 38462, 38466, 38470, 38474, 38478, 38484, 38489, - 38494, 38499, 38504, 38509, 38514, 1743, 32951, 38519, 38524, 38529, - 37657, 38534, 38537, 38542, 38547, 38552, 38558, 38564, 19379, 11968, - 38569, 38575, 38582, 19007, 38588, 38593, 38598, 38602, 38607, 38612, - 37662, 38617, 38622, 38627, 38633, 37668, 38638, 38641, 38648, 38656, - 38662, 38668, 38674, 38685, 38690, 38697, 38704, 38711, 38719, 38728, - 38737, 38743, 38749, 38757, 37673, 38762, 38768, 38774, 37679, 38779, - 38784, 38792, 38800, 38806, 38813, 38819, 38826, 38833, 38839, 38847, - 38857, 38864, 38870, 38875, 38881, 38886, 38891, 38898, 38907, 38915, - 38920, 38926, 38933, 38941, 38947, 38952, 38958, 38967, 38974, 33946, - 38980, 38984, 38989, 38998, 39003, 39008, 39013, 14946, 39021, 39026, - 39031, 39036, 39040, 39045, 39050, 39057, 39062, 39067, 39072, 37684, - 25761, 39078, 2661, 155, 39081, 39084, 39088, 39092, 39102, 39110, 39117, - 39121, 39125, 39128, 39136, 39143, 39150, 31844, 39159, 39162, 39169, - 39175, 39180, 39184, 39191, 39195, 39203, 39211, 39218, 39233, 39237, - 39241, 39244, 39250, 39257, 39261, 39267, 39271, 39278, 39286, 39294, - 39301, 37620, 39308, 39316, 39321, 39333, 12049, 12056, 12063, 12070, - 12077, 12084, 630, 434, 39339, 39344, 39349, 39355, 39360, 39365, 4170, - 39370, 39373, 39378, 39383, 39388, 39393, 39398, 39405, 27437, 39410, - 39415, 39420, 39425, 39430, 39436, 39441, 39447, 37860, 39453, 39458, - 39464, 39470, 39480, 39485, 39490, 39494, 39499, 39504, 39509, 39514, - 39527, 39532, 27051, 20254, 1061, 39536, 39542, 39546, 39551, 39556, - 39562, 39567, 39572, 39576, 39581, 39586, 39592, 39597, 39602, 1264, - 39606, 39611, 39616, 39621, 39625, 39630, 39635, 39640, 39646, 39652, - 39657, 39661, 39665, 39670, 39675, 39680, 39684, 39689, 39697, 39701, - 39707, 39711, 39718, 39727, 20025, 37631, 39733, 39740, 39748, 39756, - 39763, 39769, 39778, 39791, 39803, 39808, 39814, 39818, 2987, 39822, - 39826, 39252, 39835, 39846, 39857, 39862, 34014, 39867, 39872, 39876, - 34134, 27330, 39881, 39888, 39892, 39897, 37637, 25868, 39901, 39906, - 39912, 39917, 39921, 39925, 39928, 39932, 39938, 39947, 39958, 39970, - 37643, 39975, 39978, 39982, 39986, 39991, 39996, 40001, 40006, 40011, - 40016, 40021, 40026, 373, 40031, 40036, 40041, 40046, 40051, 40056, - 40062, 40067, 40072, 40078, 40083, 40089, 40094, 40100, 40105, 40110, - 40115, 40120, 40125, 40130, 40135, 40140, 40146, 40151, 40156, 40161, - 40166, 40171, 40176, 40181, 40187, 40193, 40198, 40203, 40208, 40213, - 40218, 40223, 40228, 40233, 40238, 40243, 40248, 40253, 40258, 40263, - 40268, 40273, 40278, 40283, 40293, 40303, 40309, 346, 14, 40314, 40317, - 40321, 40325, 40333, 40337, 40341, 31524, 16943, 1824, 40344, 40349, - 40353, 40358, 40362, 40367, 40371, 40376, 40380, 40383, 40385, 40389, - 40394, 40398, 40409, 40412, 40414, 40418, 40430, 40442, 40451, 40455, - 40465, 40469, 40475, 40480, 40489, 40495, 40500, 40505, 40509, 40513, - 40518, 40525, 40530, 40536, 40541, 40545, 40552, 31125, 31135, 40556, - 40561, 40566, 40571, 40578, 40582, 40589, 40595, 9151, 40599, 40608, - 40616, 40631, 40645, 40654, 40662, 40673, 40682, 40687, 40694, 40704, - 8151, 40714, 40719, 40724, 40728, 40731, 40736, 40740, 40745, 40749, - 40756, 40761, 40766, 40771, 40781, 40786, 40791, 40796, 10168, 40801, - 40803, 40811, 40814, 40817, 40825, 40840, 40848, 40858, 40860, 40863, - 40867, 40873, 40877, 40882, 40887, 40905, 40919, 40938, 40955, 40964, - 40972, 40977, 40982, 1402, 40988, 40994, 40999, 41009, 41018, 41026, - 41031, 41037, 41042, 41051, 41060, 41071, 41076, 41083, 41089, 41093, - 41102, 41109, 41117, 41124, 41137, 41145, 41149, 41159, 41164, 41168, - 41176, 41184, 41189, 41193, 41197, 41206, 41212, 41217, 41225, 41235, - 41244, 41253, 41262, 41273, 41281, 41292, 41301, 41309, 41316, 41322, - 41327, 41338, 41349, 41354, 41358, 41361, 41365, 41375, 41383, 41389, - 41400, 41411, 41422, 41433, 41444, 41455, 41466, 41477, 41489, 41501, - 41513, 41525, 41537, 41549, 41561, 41570, 41574, 41582, 41588, 41594, - 41601, 41607, 41612, 41618, 41622, 41627, 41632, 41637, 40288, 40298, - 2532, 41642, 41644, 41649, 41654, 41659, 41662, 41664, 41668, 41671, - 41678, 41682, 11624, 41686, 41692, 41699, 41705, 41715, 41720, 41726, - 41730, 41735, 41748, 31714, 41754, 41760, 41769, 41778, 21886, 41785, - 41794, 38285, 41802, 41807, 41811, 41820, 41828, 41835, 41840, 41844, - 41849, 41854, 41862, 41866, 41874, 41880, 41886, 41891, 41896, 41900, - 41903, 41908, 41921, 41937, 27921, 41954, 41966, 41983, 41995, 42009, - 27938, 27957, 42021, 42033, 2861, 42047, 42052, 42057, 42062, 42066, - 42073, 42085, 42092, 42101, 42104, 42115, 42126, 42134, 42139, 42143, - 42148, 42153, 42158, 42163, 42168, 42173, 1774, 947, 42178, 42182, 42186, - 42189, 42194, 42199, 42205, 42210, 42215, 42221, 42227, 42232, 42236, - 42241, 42246, 42251, 42255, 42258, 42264, 42269, 42274, 42279, 42283, - 42288, 42294, 42302, 32025, 42307, 42312, 42319, 42325, 42331, 42336, - 42344, 27446, 42351, 42356, 42361, 42366, 42370, 42373, 42378, 42382, - 42386, 42393, 42399, 42405, 42411, 42418, 42423, 42429, 41179, 42433, - 42437, 42442, 42455, 42460, 42466, 42474, 42481, 42489, 42499, 42505, - 42511, 42517, 42521, 42530, 42538, 42545, 42550, 42555, 12419, 42560, - 42570, 42577, 42583, 42593, 42598, 42604, 42612, 4023, 42619, 42626, - 42632, 42639, 4029, 42643, 42648, 42659, 42666, 42672, 42681, 42685, - 42688, 4601, 42695, 42702, 42708, 42714, 42722, 42732, 35357, 42739, - 42747, 42753, 42758, 42764, 42769, 42773, 31473, 42779, 42786, 42792, - 42800, 42809, 42816, 42822, 42833, 28740, 42839, 42846, 42852, 42862, - 42867, 42871, 42879, 42887, 42894, 42900, 42905, 11226, 941, 42910, - 42914, 42916, 42920, 42925, 42928, 42930, 42935, 42941, 42946, 42951, - 42958, 39401, 42964, 42969, 42973, 42978, 42982, 42991, 42995, 43001, - 43008, 43014, 43021, 43026, 43035, 43040, 43044, 43049, 43056, 43064, - 43072, 43077, 25924, 43081, 43084, 43088, 43092, 12863, 993, 43096, - 43101, 43109, 43114, 43118, 43127, 43134, 43138, 43142, 43150, 43157, - 16228, 43167, 43171, 43175, 43183, 43191, 43197, 43202, 43206, 43215, - 15976, 43221, 43230, 43237, 43242, 43249, 43256, 43264, 43271, 43279, - 43287, 43296, 43301, 43308, 43315, 43322, 43329, 43336, 43341, 43348, - 43354, 43371, 43379, 43389, 43397, 43404, 459, 43408, 43414, 43418, - 43423, 40678, 43429, 43432, 43436, 43442, 43453, 43461, 4034, 43469, - 43475, 43481, 43491, 43497, 43506, 43515, 43525, 43532, 43538, 43543, - 4040, 4046, 43552, 43560, 43567, 43571, 14330, 43579, 43583, 43590, - 43598, 43605, 43612, 43618, 43627, 43637, 43643, 43651, 43660, 43667, - 43675, 43682, 26726, 43686, 43693, 43699, 43709, 43718, 43726, 43737, - 43741, 43751, 43758, 43763, 43768, 43774, 43781, 43789, 43798, 43807, - 43817, 43828, 43835, 43840, 43847, 3275, 43855, 43861, 43866, 43873, - 43879, 43885, 43890, 43903, 43916, 43929, 43936, 43942, 43950, 43958, - 43963, 43967, 43971, 43976, 43981, 43986, 43991, 43996, 44001, 1371, - 44006, 44010, 44014, 44018, 44022, 44026, 44030, 44034, 44038, 44042, - 44046, 44050, 44054, 44058, 44062, 44066, 44070, 44074, 44078, 44082, - 44086, 44090, 44094, 44098, 44102, 44106, 44110, 44114, 44118, 44122, - 44126, 44130, 44134, 44138, 44142, 44146, 44150, 44154, 44158, 44162, - 44166, 44170, 44174, 44178, 44182, 44186, 44190, 44194, 44198, 44202, - 44206, 44210, 44214, 44218, 44222, 44226, 44230, 44234, 44238, 44242, - 44246, 44250, 44254, 44258, 44262, 44266, 44270, 44274, 44278, 44282, - 44286, 44290, 44294, 44298, 44302, 44306, 44310, 44314, 44318, 44322, - 44326, 44330, 44334, 44338, 44342, 44346, 44350, 44354, 44358, 44362, - 44366, 44370, 44374, 44378, 44382, 44386, 44390, 44394, 44398, 44402, - 44406, 44410, 44414, 44418, 44422, 44426, 44430, 44434, 44438, 44442, - 44446, 44450, 44454, 44458, 44462, 44466, 44470, 44474, 44478, 44482, - 44486, 44490, 44494, 44498, 44502, 44506, 44510, 44514, 44518, 44522, - 44526, 44530, 44534, 44538, 44542, 44546, 44550, 44554, 44558, 44562, - 44566, 44570, 44574, 44578, 44582, 44586, 44590, 44594, 44598, 44602, - 44606, 44610, 44614, 44618, 44623, 44627, 44632, 44636, 44641, 44645, - 44650, 44654, 44660, 44665, 44669, 44674, 44678, 44683, 44687, 44692, - 44696, 44701, 44705, 44710, 44714, 44719, 44723, 44729, 44735, 44740, - 44744, 44749, 44753, 44759, 44764, 44768, 44773, 44777, 44782, 44786, - 44792, 44797, 44801, 44806, 44810, 44815, 44819, 44824, 44828, 44834, - 44839, 44843, 44848, 44852, 44858, 44863, 44867, 44872, 44876, 44881, - 44885, 44890, 44894, 44899, 44903, 44909, 44914, 44918, 44924, 44929, - 44933, 44939, 44944, 44948, 44953, 44957, 44962, 44966, 44972, 44978, - 44984, 44990, 44996, 45002, 45008, 45014, 45019, 45023, 45028, 45032, - 45038, 45043, 45047, 45052, 45056, 45061, 45065, 45070, 45074, 45079, - 45083, 45088, 45092, 45097, 45101, 45107, 45112, 45116, 45121, 45125, - 45131, 45137, 45142, 127, 63, 45146, 45148, 45152, 45156, 45160, 45165, - 45169, 45173, 45178, 11133, 45183, 45189, 1683, 7167, 45195, 45198, - 45203, 45207, 45212, 45216, 45220, 45225, 12207, 45229, 45233, 45237, - 626, 45241, 18529, 45246, 45250, 45255, 45260, 45265, 45269, 45276, - 45282, 31746, 45288, 45291, 45295, 45300, 45306, 45310, 45313, 45321, - 45327, 45332, 45336, 45339, 45343, 45349, 45353, 45357, 3817, 3822, - 15058, 45360, 45364, 45368, 45372, 45376, 45384, 45391, 45395, 15926, - 45402, 45416, 45423, 45434, 361, 45439, 45443, 45449, 45461, 45467, - 45473, 45478, 45484, 45488, 35653, 45497, 45503, 45512, 45516, 45520, - 45525, 45531, 45536, 45540, 45545, 45549, 45553, 45560, 45566, 45571, - 45582, 45597, 45612, 45627, 45643, 45661, 12114, 45675, 45682, 45688, - 45692, 45695, 45704, 45709, 45713, 45721, 19210, 45729, 45733, 45743, - 45754, 35555, 1031, 45767, 45776, 45794, 45813, 45822, 45830, 45838, - 1696, 12316, 45842, 27342, 45845, 31512, 45850, 11458, 45855, 45861, - 45866, 45872, 45877, 45883, 45888, 45894, 45899, 45905, 45911, 45917, - 45922, 45878, 45884, 45926, 45889, 45895, 45900, 45931, 45906, 45912, - 9164, 4426, 45937, 45945, 45949, 45952, 45959, 45963, 45968, 45973, - 45980, 45986, 45992, 45997, 17818, 46001, 31529, 46005, 46009, 46013, - 46020, 46026, 46030, 33880, 46039, 10331, 46043, 10760, 46046, 46053, - 46059, 46063, 14355, 46070, 46076, 46081, 46088, 46095, 46102, 34679, - 9061, 46109, 46116, 46123, 46129, 46134, 46141, 46152, 46158, 46163, - 46168, 46173, 46177, 46182, 46189, 45879, 46193, 46203, 46212, 46223, - 46229, 46237, 46244, 46249, 46254, 46259, 46264, 46269, 46273, 46277, - 46284, 46290, 46298, 2422, 30538, 12219, 12231, 12236, 12242, 46307, - 12247, 12252, 12258, 46312, 46322, 46326, 12263, 46331, 20452, 46334, - 46339, 46343, 46347, 46358, 46366, 42096, 46374, 46379, 46386, 46393, - 46397, 46400, 46408, 12127, 46415, 46418, 46424, 46434, 6753, 46443, - 46448, 46454, 46458, 46466, 46470, 46480, 46486, 46491, 46502, 46511, - 46520, 46529, 46538, 46547, 46556, 46565, 46571, 46577, 46582, 46588, - 46594, 46600, 46605, 46608, 46615, 46621, 46625, 46630, 46637, 46644, - 46648, 46651, 46661, 46674, 46683, 46692, 46703, 46716, 46728, 46739, - 46748, 46759, 46764, 46773, 46778, 12268, 46784, 46791, 46799, 46806, - 46811, 46816, 31792, 46820, 46827, 4366, 25, 46831, 46836, 20301, 46840, - 46843, 46846, 34071, 46850, 34688, 46858, 46862, 46866, 46869, 46875, - 46881, 46886, 37708, 46895, 46903, 46909, 46916, 34054, 46920, 34291, - 46924, 46933, 46937, 46945, 46951, 46957, 46962, 46966, 34714, 46972, - 46975, 46983, 46991, 46999, 4764, 47005, 47009, 47013, 47018, 47025, - 47031, 47036, 47041, 47045, 47051, 47056, 47062, 4654, 817, 47069, 47073, - 47076, 47088, 47095, 47100, 18402, 47104, 47112, 47120, 47128, 47136, - 47143, 47151, 47159, 47166, 47174, 47182, 47190, 47198, 47206, 47214, - 47222, 47230, 47238, 47246, 47254, 47261, 47269, 47277, 47285, 47293, - 47301, 47309, 47317, 47325, 47333, 47341, 47349, 47357, 47365, 47373, - 47381, 47389, 47397, 47405, 47413, 47420, 47428, 47435, 47443, 47451, - 47459, 47467, 47475, 47483, 47491, 47499, 47510, 26762, 47515, 47518, - 47525, 47529, 47535, 47539, 47545, 47550, 47556, 47561, 47566, 47570, - 47574, 47581, 47589, 47594, 47599, 47609, 47615, 47628, 47634, 47640, - 47646, 47649, 47656, 47661, 4692, 47667, 4855, 962, 47672, 47675, 47678, - 47681, 37792, 37798, 47684, 37804, 37817, 37823, 37829, 47690, 37835, - 37841, 47696, 47702, 10, 47710, 47717, 47721, 47725, 47733, 38643, 47737, - 47741, 47748, 47753, 47757, 47762, 47768, 47773, 47779, 47784, 47788, - 47792, 47796, 47801, 47805, 47810, 47814, 47818, 47825, 47830, 47834, - 47838, 47843, 47847, 47852, 47856, 47860, 47865, 47871, 18711, 18716, - 47876, 47880, 47883, 47889, 47893, 47897, 25718, 47902, 47906, 47912, - 47919, 47925, 47930, 40707, 47940, 47945, 47953, 47957, 47960, 47964, - 38658, 47972, 4730, 47977, 47982, 47986, 47991, 47995, 48000, 15994, - 48011, 48015, 48018, 48022, 48030, 48035, 48039, 48044, 48049, 48053, - 48057, 48061, 48064, 48068, 48071, 48076, 48081, 48086, 48091, 48096, - 48101, 8644, 16010, 48106, 48109, 48115, 48120, 48126, 48131, 48137, - 48142, 48148, 48153, 48159, 48165, 48171, 48176, 48180, 48184, 48195, - 48203, 48210, 48216, 48221, 48232, 48242, 48248, 48253, 48260, 48269, - 48285, 48301, 48311, 33956, 48318, 48322, 48327, 48332, 48336, 48340, - 43802, 48346, 48351, 48355, 48362, 48367, 48372, 48376, 48379, 48383, - 48389, 32754, 48393, 26076, 48398, 48405, 48413, 48419, 48425, 48432, - 48440, 48446, 48450, 48455, 48461, 48469, 48474, 48478, 48487, 11114, - 48495, 48499, 48507, 48514, 48519, 48524, 48529, 48533, 48536, 48542, - 48546, 48549, 48553, 48560, 48565, 48572, 48576, 48582, 48586, 48592, - 48597, 48602, 5093, 5100, 48607, 48616, 48624, 48629, 48635, 48647, - 48660, 48674, 48681, 48687, 48693, 48698, 48706, 48709, 48711, 48722, - 48734, 48745, 48760, 48777, 48797, 48819, 48826, 48833, 48840, 48846, - 48850, 8643, 48853, 48857, 48861, 48866, 48870, 48874, 48877, 48881, - 48895, 27987, 48914, 48927, 48940, 48953, 28005, 48968, 2814, 48983, - 48989, 48993, 49003, 49007, 49011, 49016, 49020, 49027, 49032, 49036, - 49043, 49049, 49054, 49060, 49070, 49082, 49093, 49098, 49105, 49109, - 49113, 49116, 49124, 19231, 4138, 49129, 18750, 49142, 49149, 49156, - 49162, 49166, 49170, 49175, 49181, 49186, 49192, 49196, 49200, 49203, - 49208, 49212, 49217, 49222, 49227, 49232, 49237, 49242, 49247, 49252, - 49257, 8707, 18761, 49262, 49266, 49272, 49281, 49286, 49295, 49302, - 43633, 49308, 49313, 49317, 49324, 49329, 49336, 49344, 49350, 49354, - 49357, 49361, 49366, 2892, 49373, 49380, 49384, 49387, 49392, 49397, - 49403, 49408, 49413, 49417, 49422, 49432, 49437, 49443, 49448, 47090, - 49454, 49460, 49468, 49478, 49483, 49488, 49492, 49497, 49502, 8153, - 8165, 49507, 49510, 49517, 49523, 49532, 10248, 41319, 49540, 49544, - 49548, 38706, 49556, 49567, 49575, 43850, 49582, 49587, 49592, 49603, - 49610, 49621, 38730, 26093, 49629, 4644, 49634, 16427, 49640, 34045, - 49646, 49651, 49661, 49670, 49677, 49683, 49687, 49690, 49697, 49703, - 49710, 49716, 49726, 49734, 49740, 49746, 49751, 49755, 49762, 49767, - 49773, 49780, 49786, 48862, 49791, 49795, 16469, 16478, 16487, 16496, - 16505, 16534, 617, 16543, 49801, 49806, 49809, 49815, 49823, 1281, 49828, - 49832, 49837, 49842, 49847, 49854, 49860, 49864, 49869, 49875, 49879, - 37865, 49884, 49889, 49898, 49905, 49915, 49921, 34089, 49938, 49947, - 49955, 49961, 49966, 49973, 49979, 49987, 49996, 50004, 50012, 50018, - 50022, 50027, 50035, 35231, 38739, 50041, 50060, 19134, 50074, 50090, - 50104, 50110, 50115, 50120, 50125, 50131, 38745, 50136, 50139, 50146, - 50153, 50162, 50167, 50171, 423, 3182, 50178, 50183, 50188, 33148, 49976, - 50192, 50197, 50205, 50209, 50212, 50217, 50223, 50229, 50234, 50238, - 34162, 50241, 50246, 50250, 50253, 50258, 50262, 50267, 50272, 50276, - 50281, 50285, 50292, 50296, 50300, 25714, 25725, 50305, 50310, 50316, - 50321, 50327, 50333, 32710, 50338, 50342, 50345, 50351, 50356, 50361, - 50366, 50371, 50376, 50381, 50386, 50391, 50397, 50403, 14543, 19441, - 50408, 50413, 50418, 50423, 50428, 50433, 50438, 50443, 452, 68, 37882, - 37887, 37892, 37898, 37903, 37908, 50448, 37912, 50452, 50456, 50460, - 37917, 37923, 50474, 37934, 37939, 50482, 50487, 37945, 50492, 50497, - 50506, 50511, 50516, 50525, 50531, 50537, 50543, 37962, 50556, 50565, - 50571, 37966, 50575, 37971, 50580, 37976, 37981, 50583, 50588, 50592, - 50598, 16235, 50605, 16245, 50612, 50617, 37986, 50621, 50626, 50631, - 50636, 50641, 50645, 50650, 50655, 50661, 50666, 50671, 50677, 50683, - 50688, 50692, 50697, 50702, 50707, 50711, 50716, 50721, 50726, 50732, - 50738, 50744, 50749, 50753, 50758, 50762, 37990, 37995, 38000, 50766, - 50770, 50775, 50779, 50791, 38005, 38011, 38017, 38029, 50797, 31572, - 50801, 50806, 50810, 50815, 50822, 50827, 50832, 50837, 50841, 50845, - 50855, 50860, 50865, 50869, 50873, 50876, 50884, 50889, 38077, 50893, - 1381, 50899, 50904, 50910, 50918, 50922, 50931, 50939, 50943, 50947, - 50955, 50961, 50969, 50985, 50990, 50994, 50998, 51002, 51007, 51013, - 51028, 38114, 1691, 14575, 51032, 1260, 1275, 51044, 51052, 51059, 51064, - 9210, 51071, 51076, 10745, 987, 2647, 12295, 51083, 10638, 51088, 51091, - 51100, 1168, 51105, 49033, 51112, 51121, 51126, 51130, 51138, 51145, - 27392, 2703, 51153, 12816, 51163, 51169, 2440, 2450, 51178, 51187, 51197, - 51208, 3590, 41716, 51213, 4333, 4344, 9238, 1173, 51217, 51225, 51232, - 51237, 51241, 51245, 51250, 29022, 49368, 12386, 51258, 51267, 51276, - 51284, 51297, 51304, 51315, 51320, 51333, 51346, 51358, 51370, 51382, - 51393, 51406, 51417, 51428, 51438, 51446, 51454, 51466, 51478, 51489, - 51498, 51506, 51513, 51525, 51532, 51538, 51547, 51553, 51560, 51573, - 51578, 51588, 51593, 51599, 51604, 46060, 51608, 48538, 51615, 51622, - 51630, 51637, 2660, 51644, 51655, 51665, 51674, 51682, 51692, 51700, - 51709, 51719, 51728, 51733, 51739, 51745, 4182, 51756, 51766, 51775, - 51784, 51792, 51802, 51810, 51819, 51824, 51829, 51834, 1610, 47, 51842, - 51850, 51861, 51872, 19845, 51882, 51886, 51893, 51899, 51904, 51908, - 51919, 51929, 51938, 51949, 51954, 20274, 20279, 51961, 51970, 51975, - 51985, 51990, 51998, 52006, 52013, 52019, 1572, 271, 52023, 52029, 45941, - 52034, 52037, 2188, 2669, 52045, 52049, 52052, 1426, 52058, 16755, 1178, - 52063, 52076, 2803, 2824, 52090, 52102, 52114, 2838, 2855, 2870, 2886, - 2903, 52128, 52140, 2918, 52154, 1184, 1190, 1196, 12687, 52159, 52164, - 52169, 52173, 52188, 52203, 52218, 52233, 52248, 52263, 52278, 52293, - 52308, 52323, 52338, 52353, 52368, 52383, 52398, 52413, 52428, 52443, - 52458, 52473, 52488, 52503, 52518, 52533, 52548, 52563, 52578, 52593, - 52608, 52623, 52638, 52653, 52668, 52683, 52698, 52713, 52728, 52743, - 52758, 52773, 52788, 52803, 52818, 52833, 52848, 52863, 52878, 52893, - 52908, 52923, 52938, 52953, 52968, 52983, 52998, 53013, 53028, 53043, - 53058, 53073, 53088, 53103, 53118, 53133, 53148, 53163, 53178, 53193, - 53208, 53223, 53238, 53253, 53268, 53283, 53298, 53313, 53328, 53343, - 53358, 53373, 53388, 53403, 53418, 53433, 53448, 53463, 53478, 53493, - 53508, 53523, 53538, 53553, 53568, 53583, 53598, 53613, 53628, 53643, - 53658, 53673, 53688, 53703, 53718, 53733, 53748, 53763, 53778, 53793, - 53808, 53823, 53838, 53853, 53868, 53883, 53898, 53913, 53928, 53943, - 53958, 53973, 53988, 54003, 54018, 54033, 54048, 54063, 54078, 54093, - 54108, 54123, 54138, 54153, 54168, 54183, 54198, 54213, 54228, 54243, - 54258, 54273, 54288, 54303, 54318, 54333, 54348, 54363, 54378, 54393, - 54408, 54423, 54438, 54453, 54468, 54483, 54498, 54513, 54528, 54543, - 54558, 54573, 54588, 54603, 54618, 54633, 54648, 54663, 54678, 54693, - 54708, 54723, 54738, 54753, 54768, 54783, 54798, 54813, 54828, 54843, - 54858, 54873, 54888, 54903, 54918, 54933, 54948, 54963, 54978, 54993, - 55008, 55023, 55038, 55053, 55068, 55083, 55098, 55113, 55128, 55143, - 55158, 55173, 55188, 55203, 55218, 55233, 55248, 55263, 55278, 55293, - 55308, 55323, 55338, 55353, 55368, 55383, 55398, 55413, 55428, 55443, - 55458, 55473, 55488, 55503, 55518, 55533, 55548, 55563, 55578, 55593, - 55608, 55623, 55638, 55653, 55668, 55683, 55698, 55713, 55728, 55743, - 55758, 55773, 55788, 55803, 55818, 55833, 55848, 55863, 55878, 55893, - 55908, 55923, 55938, 55953, 55968, 55983, 55998, 56013, 56028, 56043, - 56058, 56073, 56088, 56103, 56118, 56133, 56148, 56163, 56178, 56193, - 56208, 56223, 56238, 56253, 56268, 56283, 56298, 56313, 56328, 56343, - 56358, 56373, 56388, 56403, 56418, 56433, 56448, 56463, 56478, 56493, - 56508, 56523, 56538, 56553, 56568, 56583, 56598, 56613, 56628, 56643, - 56658, 56673, 56688, 56703, 56718, 56733, 56748, 56763, 56778, 56793, - 56808, 56823, 56838, 56853, 56868, 56883, 56898, 56913, 56928, 56943, - 56958, 56973, 56988, 57003, 57018, 57033, 57048, 57063, 57078, 57093, - 57108, 57123, 57138, 57153, 57168, 57183, 57198, 57213, 57228, 57243, - 57258, 57273, 57288, 57303, 57318, 57333, 57348, 57363, 57378, 57393, - 57408, 57423, 57438, 57453, 57468, 57483, 57498, 57513, 57528, 57543, - 57558, 57573, 57588, 57603, 57618, 57633, 57648, 57663, 57678, 57693, - 57708, 57723, 57738, 57753, 57768, 57783, 57798, 57813, 57828, 57843, - 57858, 57873, 57888, 57903, 57918, 57933, 57948, 57963, 57978, 57993, - 58008, 58023, 58038, 58053, 58068, 58083, 58098, 58113, 58128, 58143, - 58158, 58173, 58188, 58203, 58218, 58233, 58248, 58263, 58278, 58293, - 58308, 58323, 58338, 58353, 58368, 58383, 58398, 58413, 58428, 58443, - 58458, 58473, 58488, 58503, 58518, 58533, 58548, 58563, 58578, 58593, - 58608, 58623, 58638, 58653, 58668, 58683, 58698, 58713, 58728, 58743, - 58758, 58773, 58788, 58803, 58818, 58833, 58848, 58863, 58878, 58893, - 58908, 58923, 58938, 58953, 58968, 58983, 58998, 59013, 59028, 59043, - 59058, 59073, 59088, 59103, 59118, 59133, 59148, 59163, 59178, 59193, - 59208, 59223, 59238, 59253, 59268, 59283, 59298, 59313, 59328, 59343, - 59358, 59373, 59388, 59403, 59418, 59433, 59448, 59463, 59478, 59493, - 59508, 59523, 59538, 59553, 59568, 59583, 59598, 59613, 59628, 59643, - 59658, 59673, 59688, 59703, 59718, 59733, 59748, 59763, 59778, 59793, - 59808, 59823, 59838, 59853, 59868, 59883, 59898, 59913, 59928, 59943, - 59958, 59973, 59988, 60004, 60020, 60036, 60052, 60068, 60084, 60100, - 60116, 60132, 60148, 60164, 60180, 60196, 60212, 60228, 60244, 60260, - 60276, 60292, 60308, 60324, 60340, 60356, 60372, 60388, 60404, 60420, - 60436, 60452, 60468, 60484, 60500, 60516, 60532, 60548, 60564, 60580, - 60596, 60612, 60628, 60644, 60660, 60676, 60692, 60708, 60724, 60740, - 60756, 60772, 60788, 60804, 60820, 60836, 60852, 60868, 60884, 60900, - 60916, 60932, 60948, 60964, 60980, 60996, 61012, 61028, 61044, 61060, - 61076, 61092, 61108, 61124, 61140, 61156, 61172, 61188, 61204, 61220, - 61236, 61252, 61268, 61284, 61300, 61316, 61332, 61348, 61364, 61380, - 61396, 61412, 61428, 61444, 61460, 61476, 61492, 61508, 61524, 61540, - 61556, 61572, 61588, 61604, 61620, 61636, 61652, 61668, 61684, 61700, - 61716, 61732, 61748, 61764, 61780, 61796, 61812, 61828, 61844, 61860, - 61876, 61892, 61908, 61924, 61940, 61956, 61972, 61988, 62004, 62020, - 62036, 62052, 62068, 62084, 62100, 62116, 62132, 62148, 62164, 62180, - 62196, 62212, 62228, 62244, 62260, 62276, 62292, 62308, 62324, 62340, - 62356, 62372, 62388, 62404, 62420, 62436, 62452, 62468, 62484, 62500, - 62516, 62532, 62548, 62564, 62580, 62596, 62612, 62628, 62644, 62660, - 62676, 62692, 62708, 62724, 62740, 62756, 62772, 62788, 62804, 62820, - 62836, 62852, 62868, 62884, 62900, 62916, 62932, 62948, 62964, 62980, - 62996, 63012, 63028, 63044, 63060, 63076, 63092, 63108, 63124, 63140, - 63156, 63172, 63188, 63204, 63220, 63236, 63252, 63268, 63284, 63300, - 63316, 63332, 63348, 63364, 63380, 63396, 63412, 63428, 63444, 63460, - 63476, 63492, 63508, 63524, 63540, 63556, 63572, 63588, 63604, 63620, - 63636, 63652, 63668, 63684, 63700, 63716, 63732, 63748, 63764, 63780, - 63796, 63812, 63828, 63844, 63860, 63876, 63892, 63908, 63924, 63940, - 63956, 63972, 63988, 64004, 64020, 64036, 64052, 64068, 64084, 64100, - 64116, 64132, 64148, 64164, 64180, 64196, 64212, 64228, 64244, 64260, - 64276, 64292, 64308, 64324, 64340, 64356, 64372, 64388, 64404, 64420, - 64436, 64452, 64468, 64484, 64500, 64516, 64532, 64548, 64564, 64580, - 64596, 64612, 64628, 64644, 64660, 64676, 64692, 64708, 64724, 64740, - 64756, 64772, 64788, 64804, 64820, 64836, 64852, 64868, 64884, 64900, - 64916, 64932, 64948, 64964, 64980, 64996, 65012, 65028, 65044, 65060, - 65076, 65092, 65108, 65124, 65140, 65156, 65172, 65188, 65204, 65220, - 65236, 65252, 65268, 65284, 65300, 65316, 65332, 65348, 65364, 65380, - 65396, 65412, 65428, 65444, 65460, 65476, 65492, 65508, 65524, 65540, - 65556, 65572, 65588, 65604, 65620, 65636, 65652, 65668, 65684, 65700, - 65716, 65732, 65748, 65764, 65780, 65796, 65812, 65828, 65844, 65860, - 65876, 65892, 65908, 65924, 65940, 65956, 65972, 65988, 66004, 66020, - 66036, 66052, 66068, 66084, 66100, 66116, 66132, 66148, 66164, 66180, - 66196, 66212, 66228, 66244, 66260, 66276, 66292, 66308, 66324, 66340, - 66356, 66372, 66388, 66404, 66420, 66436, 66452, 66468, 66484, 66500, - 66516, 66532, 66548, 66564, 66580, 66596, 66612, 66628, 66644, 66660, - 66676, 66692, 66708, 66724, 66740, 66756, 66772, 66788, 66804, 66820, - 66836, 66852, 66868, 66884, 66900, 66916, 66932, 66948, 66964, 66980, - 66996, 67012, 67028, 67044, 67060, 67076, 67092, 67108, 67124, 67140, - 67156, 67172, 67188, 67204, 67220, 67236, 67252, 67268, 67284, 67300, - 67316, 67332, 67348, 67364, 67380, 67396, 67412, 67428, 67444, 67460, - 67476, 67492, 67508, 67524, 67540, 67556, 67572, 67588, 67604, 67620, - 67636, 67652, 67668, 67684, 67700, 67716, 67732, 67748, 67764, 67780, - 67796, 67812, 67828, 67844, 67860, 67876, 67892, 67908, 67924, 67940, - 67956, 67972, 67988, 68004, 68020, 68036, 68052, 68068, 68084, 68100, - 68116, 68132, 68148, 68164, 68180, 68196, 68212, 68228, 68244, 68260, - 68276, 68292, 68308, 68324, 68340, 68356, 68372, 68388, 68404, 68420, - 68436, 68452, 68468, 68484, 68500, 68516, 68532, 68548, 68564, 68580, - 68596, 68612, 68628, 68644, 68660, 68669, 68684, 68698, 17657, 68707, - 68712, 68718, 68724, 68734, 68742, 17914, 18645, 9257, 68755, 1434, 1438, - 68763, 4262, 33273, 8090, 68769, 68774, 68779, 68784, 68789, 68795, - 68800, 68806, 68811, 68817, 68822, 68827, 68832, 68837, 68843, 68848, - 68853, 68858, 68863, 68868, 68873, 68878, 68884, 68889, 68895, 68902, - 2707, 68907, 68913, 9632, 68917, 68922, 68929, 68937, 4273, 4278, 4283, - 4288, 65, 68941, 68947, 68952, 68957, 68961, 68966, 68970, 68974, 12759, - 68978, 68988, 69001, 69012, 69025, 69032, 69038, 69046, 12220, 69053, - 69058, 69064, 69070, 69076, 69081, 69086, 69091, 69096, 69100, 69105, - 69110, 69115, 69121, 69127, 69133, 69138, 69142, 69147, 69152, 69156, - 69161, 69166, 69171, 69175, 12775, 12786, 12791, 1477, 69179, 69185, - 1482, 19679, 69190, 19688, 1492, 69195, 69201, 69206, 1513, 69212, 1519, - 1525, 12821, 69217, 69226, 69234, 69242, 69249, 69253, 69257, 69263, - 69268, 37525, 69273, 69280, 69288, 69295, 69300, 69304, 69308, 69317, - 69322, 69327, 69332, 1530, 280, 69337, 69342, 69346, 19814, 1007, 69350, - 69357, 69362, 69366, 19872, 1534, 46217, 69369, 69374, 69384, 69393, - 69398, 69402, 69408, 1539, 49314, 69413, 69422, 69428, 69433, 69438, - 13060, 13066, 69444, 69456, 69473, 69490, 69507, 69524, 69541, 69558, - 69575, 69592, 69609, 69626, 69643, 69660, 69677, 69694, 69711, 69728, - 69745, 69762, 69779, 69796, 69813, 69830, 69847, 69864, 69881, 69898, - 69915, 69932, 69949, 69966, 69983, 70000, 70017, 70034, 70051, 70068, - 70085, 70102, 70119, 70136, 70153, 70170, 70187, 70204, 70221, 70238, - 70255, 70272, 70289, 70300, 70310, 70315, 1544, 70319, 70324, 70330, - 70335, 70340, 70347, 10657, 1549, 70353, 70362, 33662, 70367, 70378, - 13082, 70388, 70393, 70399, 70404, 70411, 70417, 70422, 1554, 20166, - 70427, 70433, 13092, 70439, 70444, 70449, 70454, 70459, 70464, 70469, - 70474, 1559, 4753, 70479, 70484, 70490, 70495, 70500, 70505, 70510, - 70515, 70520, 70525, 70530, 70536, 70542, 70548, 70553, 70557, 70562, - 70567, 70571, 70576, 70581, 70586, 70591, 70595, 70600, 70606, 70611, - 70616, 70620, 70625, 70630, 70636, 70641, 70646, 70652, 70658, 70663, - 70667, 70672, 70677, 70682, 70686, 70691, 70696, 70701, 70707, 70713, - 70718, 70722, 70726, 70731, 70736, 70741, 35430, 70745, 70750, 70755, - 70761, 70766, 70771, 70775, 70780, 70785, 70791, 70796, 70801, 70807, - 70813, 70818, 70822, 70827, 70832, 70836, 70841, 70846, 70851, 70857, - 70863, 70868, 70872, 70877, 70882, 70886, 70891, 70896, 70901, 70906, - 70910, 70913, 70916, 70921, 70926, 38252, 70933, 70941, 49930, 70947, - 3934, 33605, 70960, 70967, 70973, 70979, 4113, 70984, 13234, 70990, - 71000, 71015, 71023, 13239, 71034, 71039, 71050, 71062, 71074, 71086, - 2909, 71098, 71103, 31655, 71115, 71121, 71127, 71132, 71141, 71148, - 71153, 71158, 71163, 71168, 71173, 71178, 1576, 19306, 71183, 71188, - 71193, 71198, 71204, 71209, 71215, 71220, 71225, 71231, 71236, 71241, - 49388, 71245, 71249, 71254, 71258, 20314, 71263, 71266, 71271, 71279, - 71287, 1580, 13275, 13281, 1585, 71295, 71302, 71307, 71316, 71326, - 71333, 71338, 71343, 1590, 71350, 71355, 20434, 71359, 71364, 71371, - 71377, 71381, 71394, 71400, 71411, 71421, 71428, 20456, 10551, 10558, - 4347, 4353, 71435, 1595, 71440, 71449, 71455, 71463, 71470, 71476, 71483, - 71495, 71501, 71506, 71513, 71525, 71536, 71546, 71555, 71565, 71575, - 4241, 71583, 37319, 37328, 20496, 71596, 71601, 71606, 71611, 71616, - 71621, 71626, 1600, 1604, 71631, 71635, 71638, 71649, 71654, 20522, 1614, - 71662, 71667, 71672, 20555, 71684, 71687, 71693, 71699, 71704, 71712, - 1619, 71717, 71722, 71730, 71738, 71745, 71754, 71762, 71771, 71775, - 1624, 71784, 1629, 25899, 71789, 71796, 71802, 20642, 71810, 71820, - 71826, 71831, 71839, 71846, 71855, 71863, 71873, 71882, 71892, 71901, - 71912, 71922, 71932, 71941, 71951, 71965, 71978, 71987, 71995, 72005, - 72014, 72026, 72037, 72048, 72058, 19934, 72063, 13427, 72072, 72078, - 72083, 72090, 72096, 72103, 72109, 19523, 72119, 72125, 72130, 72141, - 72148, 72155, 72160, 72168, 13444, 13449, 72176, 72182, 72186, 4331, - 4342, 20718, 49484, 72194, 72200, 72205, 72213, 72220, 14556, 72225, - 72231, 72237, 1640, 72242, 72245, 72251, 72256, 72261, 72266, 72271, - 72276, 72281, 72286, 72291, 72297, 72303, 1339, 72308, 72313, 72318, - 72324, 72329, 72334, 72339, 72344, 72349, 72354, 1649, 18, 72360, 72364, - 72369, 72373, 72377, 72381, 38538, 72386, 28206, 72391, 72396, 72400, - 72403, 72407, 72411, 72416, 72420, 72425, 72429, 72432, 72438, 42190, - 42195, 42200, 72441, 72448, 72454, 72462, 49086, 72472, 72478, 42206, - 38802, 38553, 38559, 42222, 38565, 72483, 72488, 72492, 38835, 72499, - 72502, 72506, 72514, 72521, 72526, 72529, 72534, 72539, 72543, 72547, - 72550, 72560, 72572, 72579, 72585, 38570, 72592, 40521, 72595, 9649, - 13789, 72598, 72602, 72607, 4156, 72611, 72614, 16288, 72621, 72628, - 72641, 72656, 72670, 72686, 72701, 72710, 72718, 72726, 72735, 72744, - 72750, 72755, 72765, 72778, 72790, 72797, 72802, 72811, 72824, 43897, - 72842, 72847, 72854, 72860, 72865, 895, 72870, 72878, 72885, 72892, - 33089, 911, 72898, 72904, 72909, 72919, 72927, 72933, 72938, 38589, 6844, - 38603, 72942, 72952, 72957, 72965, 72975, 72990, 72996, 73002, 73009, - 38613, 73014, 37663, 73018, 73023, 73032, 73039, 73044, 73048, 73053, - 73061, 20499, 73068, 73073, 73077, 6885, 38639, 73081, 73087, 345, 73097, - 73104, 73111, 73117, 73124, 73129, 73138, 15909, 69378, 69388, 73144, - 73152, 73156, 73160, 73164, 73168, 73173, 73177, 73183, 73191, 73196, - 73201, 73208, 73213, 73217, 73222, 73226, 73230, 73236, 73247, 73253, - 73258, 73262, 73267, 73271, 38763, 73275, 38769, 38775, 73280, 73286, - 73293, 73298, 73302, 37680, 20153, 73305, 73309, 73314, 73321, 73327, - 73331, 73336, 48555, 73342, 73346, 73353, 73357, 73362, 73368, 73374, - 73380, 73392, 73401, 73411, 73417, 73424, 73429, 73434, 73438, 73441, - 73447, 73454, 73459, 73464, 73471, 73478, 73485, 73491, 73496, 73501, - 73509, 38780, 2537, 73514, 73519, 73525, 73530, 73536, 73541, 73546, - 73551, 73557, 38801, 73562, 73568, 73574, 73580, 38871, 73585, 73590, - 73595, 38882, 73600, 73605, 73610, 73616, 73622, 38887, 73627, 73632, - 73637, 38942, 38948, 73642, 73647, 38953, 38975, 33947, 38981, 38985, - 73652, 14232, 73656, 73664, 73670, 73678, 73685, 73691, 73701, 73707, - 73714, 12659, 38999, 73720, 73733, 73742, 73748, 73757, 73763, 73769, - 73776, 28549, 73784, 73791, 73801, 73809, 73812, 38943, 73817, 73824, - 73829, 73833, 73837, 73842, 73846, 4470, 73851, 73856, 73861, 42284, - 42289, 73865, 42303, 73870, 42308, 73875, 73881, 42320, 42326, 42332, - 73886, 73892, 27447, 73903, 73906, 73918, 73926, 39022, 73930, 73939, - 73949, 73958, 39032, 73963, 73970, 73979, 73985, 73993, 74000, 74007, - 6936, 5160, 74012, 38954, 74018, 74021, 74027, 74034, 74039, 74044, - 28453, 74048, 74054, 74060, 74065, 74070, 74074, 74080, 74086, 40405, - 74091, 43500, 45323, 45329, 39063, 39068, 74095, 74099, 74103, 74106, - 74119, 74125, 74129, 74132, 74137, 40774, 74141, 37685, 25840, 74147, - 6865, 6873, 10357, 74150, 74155, 74160, 74165, 74170, 74175, 74180, - 74185, 74190, 74195, 74201, 74206, 74211, 74217, 74222, 74227, 74232, - 74237, 74242, 74247, 74253, 74258, 74264, 74269, 74274, 74279, 74284, - 74289, 74294, 74299, 74304, 74309, 74314, 74320, 74325, 74330, 74335, - 74340, 74345, 74350, 74356, 74361, 74366, 74371, 74376, 74381, 74386, - 74391, 74396, 74401, 74407, 74412, 74417, 74422, 74427, 74433, 74439, - 74444, 74450, 74455, 74460, 74465, 74470, 74475, 1427, 156, 74480, 74484, - 74488, 74492, 30391, 74496, 74500, 74505, 74509, 74514, 74518, 74523, - 74528, 74533, 74538, 74542, 74546, 74551, 74555, 15988, 74560, 74564, - 74571, 74581, 18283, 74590, 74599, 74603, 74608, 74613, 74617, 74621, - 30171, 3265, 74625, 74631, 21731, 74635, 74644, 74652, 74658, 74663, - 74675, 74687, 74692, 74696, 74701, 74705, 74711, 74717, 74722, 74732, - 74742, 74748, 74756, 74761, 74765, 74771, 74776, 74783, 74789, 74794, - 74801, 74810, 74819, 74827, 74831, 18839, 74834, 74843, 74851, 74863, - 74874, 74885, 74894, 74898, 74907, 74915, 74925, 74933, 74940, 74950, - 74956, 74961, 74968, 74977, 74983, 74988, 74995, 75001, 75012, 60, 37462, - 75018, 31942, 31952, 75024, 75032, 75039, 75045, 75049, 75059, 75070, - 75078, 75087, 75092, 75097, 75102, 75106, 75110, 75118, 21678, 75125, - 75129, 75135, 75145, 75152, 75158, 75164, 42383, 75168, 75170, 75173, - 75179, 75183, 75194, 75204, 75210, 75217, 75224, 15925, 75232, 75238, - 75247, 75256, 75262, 11559, 75268, 75274, 75279, 75284, 75291, 75296, - 75303, 75309, 75314, 75322, 75335, 75344, 75353, 71927, 71937, 75363, - 75369, 75378, 75384, 75390, 75397, 75404, 75411, 75418, 75425, 75430, - 75434, 75438, 75441, 75451, 75455, 75467, 10018, 75476, 75487, 75492, - 75496, 71946, 75502, 75509, 75518, 75526, 75534, 75539, 75543, 75548, - 75553, 75563, 75571, 75583, 75588, 75592, 75596, 75602, 75610, 75617, - 75629, 75637, 75648, 75655, 75661, 75671, 75677, 75681, 75690, 75699, - 75706, 75712, 75717, 75721, 75725, 75729, 75738, 75747, 75756, 75763, - 75769, 75775, 75781, 75786, 75793, 75799, 75807, 75814, 75820, 15020, - 75825, 75831, 75835, 17140, 75839, 75844, 75854, 75859, 75868, 75874, - 75880, 75888, 75895, 75899, 75903, 75910, 75916, 75924, 75931, 75937, - 75948, 75952, 75956, 75960, 75963, 75969, 75974, 75979, 75983, 75987, - 75996, 76004, 76011, 76017, 76024, 29213, 48696, 76029, 76037, 76041, - 76045, 76048, 76056, 76063, 76069, 76078, 76086, 76092, 76097, 76101, - 76106, 76111, 76115, 76119, 76123, 76128, 76137, 76141, 76148, 45427, - 76152, 76158, 76166, 76170, 76176, 76184, 76190, 76195, 76206, 76214, - 76220, 76229, 27594, 76237, 76244, 76251, 76258, 76265, 76272, 52348, - 15740, 76279, 76286, 76291, 42419, 4713, 76297, 76302, 76307, 76313, - 76319, 76325, 76330, 76335, 76340, 76345, 76351, 76356, 76362, 76367, - 76373, 76378, 76383, 76388, 76393, 76398, 76403, 76408, 76414, 76419, - 76425, 76430, 76435, 76440, 76445, 76450, 76455, 76461, 76466, 76471, - 76476, 76481, 76486, 76491, 76496, 76501, 76506, 76511, 76517, 76522, - 76527, 76532, 76537, 76542, 76547, 76552, 76557, 76563, 76568, 76573, - 76578, 76583, 76588, 76593, 76598, 76603, 76608, 76613, 76618, 76623, - 76629, 1889, 305, 76634, 46335, 46340, 76638, 76643, 9273, 76647, 3634, - 76652, 76657, 76661, 76670, 76681, 76698, 76716, 76724, 75530, 76731, - 76734, 76744, 76751, 76760, 76776, 76785, 76795, 76800, 76813, 76823, - 76832, 76840, 76854, 76862, 76871, 76875, 76878, 76885, 76891, 76902, - 76909, 76921, 76932, 76943, 76952, 76959, 1179, 809, 76969, 2750, 76973, - 76978, 76987, 1025, 9039, 25276, 76995, 77003, 77017, 77030, 77034, - 77039, 77044, 77049, 77055, 77061, 77066, 9641, 18326, 77071, 77075, - 77083, 10078, 77088, 77094, 77103, 77111, 1663, 13288, 1185, 4385, 77115, - 77119, 77128, 77138, 2488, 32788, 77147, 77153, 20406, 32803, 77159, - 4550, 13670, 77165, 77172, 71644, 77176, 77180, 77186, 77191, 77196, - 3867, 163, 3893, 77201, 77213, 77217, 77221, 77227, 77232, 33682, 77236, - 13658, 2944, 4, 77241, 77251, 77262, 77273, 77283, 77289, 77300, 77307, - 77313, 77319, 2312, 77324, 77332, 77339, 77345, 77355, 77365, 77375, - 77384, 28536, 1191, 77389, 77393, 77397, 77403, 77407, 2967, 2973, 9638, - 2343, 77411, 77415, 77424, 77432, 77443, 77451, 77459, 77465, 77470, - 77481, 77492, 77500, 77506, 77511, 11336, 77521, 77529, 77533, 77537, - 77542, 77546, 77558, 34145, 18225, 77565, 77575, 77581, 77587, 7963, - 11470, 77597, 77608, 77619, 77629, 77638, 77642, 77649, 1027, 2737, - 77659, 77664, 77672, 71360, 77680, 77685, 77696, 77703, 77717, 16936, - 529, 77727, 77734, 77738, 77742, 77750, 77759, 77767, 77773, 20451, - 77778, 77792, 77799, 77805, 77813, 77822, 77831, 77838, 77850, 77860, - 77868, 77875, 77883, 77890, 4349, 116, 77898, 77909, 77913, 77925, 77931, - 1810, 227, 77936, 10689, 77941, 3012, 77945, 77952, 77958, 77969, 77979, - 77987, 77994, 10029, 78001, 78010, 78018, 4430, 78031, 4447, 78035, - 78040, 78046, 78051, 78056, 78061, 3017, 573, 78067, 78080, 78084, 78089, - 78094, 3022, 1888, 760, 78098, 4451, 78106, 78112, 78116, 803, 78126, - 78135, 78140, 3884, 78144, 17957, 17964, 9297, 78148, 4482, 4359, 15618, - 78156, 78163, 78168, 28600, 78172, 78179, 78185, 13926, 78190, 13991, - 204, 78195, 78207, 78213, 78221, 3034, 1705, 78229, 78231, 78236, 78241, - 78246, 78252, 78257, 78262, 78267, 78272, 78277, 78282, 78288, 78293, - 78298, 78303, 78308, 78313, 78318, 78323, 78328, 78334, 78339, 78344, - 78349, 78355, 78360, 78366, 78371, 78376, 78381, 78386, 78391, 78396, - 78401, 78407, 78412, 78418, 78423, 78428, 78433, 78438, 78443, 78448, - 78453, 78458, 9710, 9723, 4498, 4503, 4508, 4513, 26, 78464, 78470, - 78475, 78480, 78485, 78491, 78496, 78500, 78504, 78509, 78515, 78519, - 78525, 78530, 78535, 78541, 78546, 78550, 78555, 78560, 78564, 78567, - 78569, 78573, 78576, 78583, 78588, 78592, 78597, 78601, 78605, 78609, - 78615, 78626, 78646, 78665, 78686, 78699, 78711, 78720, 78724, 78727, - 39340, 78730, 39345, 78737, 78742, 39350, 78751, 78760, 39356, 78765, - 39361, 78774, 78779, 13915, 78783, 78788, 78793, 39366, 78797, 78806, - 50533, 78810, 78813, 78817, 9305, 78823, 78826, 78831, 78836, 78841, - 78845, 4171, 39371, 78848, 78852, 78855, 78866, 78871, 78875, 78881, - 78889, 78902, 78906, 78914, 78923, 78929, 78934, 78940, 78944, 78950, - 78956, 78964, 78969, 78973, 78980, 78986, 78994, 79003, 79011, 39374, - 79018, 79028, 79037, 79045, 79056, 79069, 79074, 79079, 79083, 79092, - 79098, 79105, 79118, 79130, 79141, 79153, 79160, 79169, 79178, 79187, - 79194, 79200, 79207, 79215, 79222, 79230, 79239, 79247, 79254, 79262, - 79271, 79279, 79288, 79298, 79307, 79315, 79322, 79330, 79339, 79347, - 79356, 79366, 79375, 79383, 79392, 79402, 79411, 79421, 79432, 79442, - 79451, 79459, 79466, 79474, 79483, 79491, 79500, 79510, 79519, 79527, - 79536, 79546, 79555, 79565, 79576, 79586, 79595, 79603, 79612, 79622, - 79631, 79641, 79652, 79662, 79671, 79681, 79692, 79702, 79713, 79725, - 79736, 79746, 79755, 79763, 79770, 79778, 79787, 79795, 79804, 79814, - 79823, 79831, 79840, 79850, 79859, 79869, 79880, 79890, 79899, 79907, - 79916, 79926, 79935, 79945, 79956, 79966, 79975, 79985, 79996, 80006, - 80017, 80029, 80040, 80050, 80059, 80067, 80076, 80086, 80095, 80105, - 80116, 80126, 80135, 80145, 80156, 80166, 80177, 80189, 80200, 80210, - 80219, 80229, 80240, 80250, 80261, 80273, 80284, 80294, 80305, 80317, - 80328, 80340, 80353, 80365, 80376, 80386, 80395, 80403, 80410, 80418, - 80427, 80435, 80444, 80454, 80463, 80471, 80480, 80490, 80499, 80509, - 80520, 80530, 80539, 80547, 80556, 80566, 80575, 80585, 80596, 80606, - 80615, 80625, 80636, 80646, 80657, 80669, 80680, 80690, 80699, 80707, - 80716, 80726, 80735, 80745, 80756, 80766, 80775, 80785, 80796, 80806, - 80817, 80829, 80840, 80850, 80859, 80869, 80880, 80890, 80901, 80913, - 80924, 80934, 80945, 80957, 80968, 80980, 80993, 81005, 81016, 81026, - 81035, 81043, 81052, 81062, 81071, 81081, 81092, 81102, 81111, 81121, - 81132, 81142, 81153, 81165, 81176, 81186, 81195, 81205, 81216, 81226, - 81237, 81249, 81260, 81270, 81281, 81293, 81304, 81316, 81329, 81341, - 81352, 81362, 81371, 81381, 81392, 81402, 81413, 81425, 81436, 81446, - 81457, 81469, 81480, 81492, 81505, 81517, 81528, 81538, 81549, 81561, - 81572, 81584, 81597, 81609, 81620, 81632, 81645, 81657, 81670, 81684, - 81697, 81709, 81720, 81730, 81739, 81747, 81754, 81759, 9070, 81766, - 81771, 39384, 81777, 81782, 39389, 81788, 25398, 31390, 81793, 81799, - 81805, 81813, 81819, 81825, 81832, 81839, 81844, 81849, 81853, 81858, - 81862, 81865, 81869, 81874, 81883, 81892, 81900, 81906, 81918, 81929, - 81933, 3327, 9045, 81938, 81941, 81944, 81946, 81950, 81954, 81958, - 81964, 81969, 31453, 81974, 81978, 81981, 81986, 81990, 81997, 82003, - 82007, 7046, 82011, 82016, 39411, 82020, 82027, 82036, 82044, 82050, - 82061, 82069, 82078, 82086, 82093, 82100, 82106, 82111, 82122, 39416, - 82127, 82138, 82150, 82158, 82169, 82178, 82186, 82197, 82202, 82210, - 2702, 82215, 82224, 41789, 82237, 82241, 82253, 82261, 82266, 82274, - 82285, 21896, 82294, 82300, 82307, 82315, 82321, 39426, 82326, 4476, - 68738, 82333, 82336, 82344, 82357, 82370, 82383, 82396, 82403, 82414, - 82423, 82428, 52165, 52170, 82432, 82436, 82444, 82451, 82460, 82468, - 82474, 82483, 82491, 82498, 82506, 82510, 82519, 82528, 82538, 82551, - 82564, 82574, 39431, 82580, 82587, 82593, 82599, 39437, 82604, 82607, - 82611, 82619, 82628, 51941, 82636, 82645, 82653, 82660, 82668, 82678, - 82687, 82696, 40947, 82705, 82716, 82731, 82741, 10727, 26214, 82750, - 82755, 82760, 82764, 19515, 82769, 82774, 82780, 82785, 82790, 82796, - 82801, 82806, 26174, 82811, 82818, 82826, 82834, 82842, 82847, 82854, - 82861, 82866, 1723, 82870, 82874, 82882, 82890, 39454, 82896, 82902, - 82914, 82920, 82927, 82931, 82938, 82943, 82950, 82956, 82963, 82974, - 82984, 82994, 83006, 83012, 83020, 83029, 83035, 83045, 83055, 39481, - 83064, 83073, 83079, 83091, 83102, 83109, 83114, 83118, 83126, 83137, - 83143, 83148, 83153, 83160, 83168, 83180, 83190, 83199, 83208, 83216, - 83223, 41603, 28974, 83229, 83234, 83238, 83242, 83247, 83255, 83261, - 83272, 83285, 83290, 83297, 39486, 83302, 83314, 83323, 83331, 83341, - 83352, 83365, 83372, 83381, 83390, 83398, 83403, 83409, 83413, 1416, - 83418, 83423, 83428, 83433, 83439, 83444, 83449, 83455, 83461, 83466, - 83470, 83475, 83480, 83485, 69313, 83490, 83495, 83500, 83505, 83511, - 83517, 83522, 83526, 83531, 19514, 83536, 83542, 83547, 83553, 83558, - 83563, 83568, 83573, 83577, 83583, 83588, 83597, 83602, 83607, 83612, - 83617, 83621, 83628, 83634, 4822, 20768, 3292, 83639, 83643, 83648, - 83652, 83656, 83660, 55965, 83664, 83589, 83666, 83676, 39495, 83679, - 83684, 83693, 83699, 7005, 39500, 83703, 83709, 83714, 83720, 83725, - 83729, 83736, 83741, 83751, 83760, 83764, 83770, 83776, 83782, 83786, - 83794, 83801, 83809, 83817, 39505, 83824, 83827, 83838, 83845, 83851, - 83856, 83860, 83866, 83874, 83881, 83886, 83890, 83899, 83907, 83913, - 83918, 39510, 83925, 28426, 83937, 83943, 83948, 83954, 83961, 83967, - 25862, 33296, 83973, 83978, 83984, 83988, 84000, 83622, 83629, 26106, - 84010, 84015, 84022, 84028, 84035, 84041, 84052, 84057, 84065, 10427, - 84070, 84073, 84079, 84083, 84087, 84090, 84096, 84102, 39199, 4823, - 1431, 16037, 84109, 84115, 84121, 84127, 84133, 84139, 84145, 84151, - 84157, 84162, 84167, 84172, 84177, 84182, 84187, 84192, 84197, 84202, - 84207, 84212, 84217, 84222, 84228, 84233, 84238, 84244, 84249, 84254, - 84260, 84266, 84272, 84278, 84284, 84290, 84296, 84302, 84308, 84313, - 84318, 84324, 84329, 84334, 84340, 84345, 84350, 84355, 84360, 84365, - 84370, 84375, 84380, 84385, 84390, 84395, 84400, 84406, 84411, 84416, - 84421, 84427, 84432, 84437, 84442, 84447, 84453, 84458, 84463, 84468, - 84473, 84478, 84483, 84488, 84493, 84498, 84503, 84508, 84513, 84518, - 84523, 84528, 84533, 84538, 84543, 84548, 84554, 84559, 84564, 84569, - 84574, 84579, 84584, 84589, 1062, 159, 84594, 84598, 84602, 84607, 84615, - 84619, 84631, 84638, 84646, 84650, 84663, 84671, 84676, 84681, 32005, - 84685, 84690, 84694, 84699, 84703, 84711, 84715, 25406, 84720, 84724, - 72190, 84728, 84731, 84739, 84747, 84755, 84760, 84765, 84772, 84779, - 84785, 84791, 84796, 84803, 84808, 84816, 77022, 84823, 84828, 71956, - 84835, 84841, 84846, 84850, 84857, 84863, 84870, 71983, 14005, 84878, - 84883, 84888, 84892, 84895, 84906, 84915, 84921, 84926, 84930, 84940, - 84949, 50324, 84953, 84957, 84964, 84977, 84983, 84991, 84998, 85007, - 85018, 85029, 85040, 85051, 85060, 85066, 85075, 85083, 85093, 85106, - 85114, 85121, 85132, 85141, 85147, 85152, 85157, 85163, 85173, 85179, - 85189, 85197, 85204, 85214, 85223, 83304, 85231, 85237, 85245, 85251, - 75575, 85258, 85263, 85266, 85270, 85276, 85280, 85283, 85291, 85297, - 85303, 85311, 85323, 85335, 85342, 85347, 85351, 85362, 85370, 85377, - 85389, 85397, 85404, 85412, 85419, 85425, 85430, 85436, 85446, 85455, - 85463, 85468, 85478, 85487, 51202, 85494, 85498, 85503, 85511, 85518, - 85524, 85528, 85538, 85549, 85557, 85564, 85576, 85588, 85597, 82227, - 85604, 85614, 85626, 85637, 85651, 85659, 85669, 85676, 85684, 85697, - 85709, 85718, 85726, 85736, 85747, 85759, 85768, 85778, 85788, 85797, - 85804, 85813, 85828, 85836, 85846, 85855, 85863, 85876, 68708, 85891, - 85901, 85910, 85922, 85932, 85944, 85955, 85969, 85983, 85997, 86011, - 86025, 86039, 86053, 86067, 86081, 86095, 86109, 86123, 86137, 86151, - 86165, 86179, 86193, 86207, 86221, 86235, 86249, 86263, 86277, 86291, - 86305, 86319, 86333, 86347, 86361, 86375, 86389, 86403, 86417, 86431, - 86445, 86459, 86473, 86487, 86501, 86515, 86529, 86543, 86557, 86571, - 86585, 86599, 86613, 86627, 86641, 86655, 86669, 86683, 86697, 86711, - 86725, 86739, 86753, 86767, 86781, 86795, 86809, 86823, 86837, 86851, - 86865, 86879, 86893, 86907, 86921, 86935, 86949, 86963, 86977, 86991, - 87005, 87019, 87033, 87047, 87061, 87075, 87089, 87103, 87117, 87131, - 87145, 87159, 87173, 87187, 87201, 87215, 87229, 87243, 87257, 87271, - 87285, 87299, 87313, 87327, 87341, 87355, 87369, 87383, 87397, 87411, - 87425, 87439, 87453, 87467, 87481, 87495, 87509, 87523, 87537, 87551, - 87565, 87579, 87593, 87607, 87621, 87635, 87649, 87663, 87677, 87691, - 87705, 87719, 87733, 87747, 87761, 87775, 87789, 87803, 87817, 87831, - 87845, 87859, 87873, 87887, 87901, 87915, 87929, 87943, 87957, 87971, - 87985, 87999, 88013, 88027, 88041, 88055, 88069, 88083, 88097, 88111, - 88125, 88139, 88153, 88167, 88181, 88195, 88209, 88223, 88237, 88251, - 88265, 88279, 88293, 88307, 88321, 88335, 88349, 88363, 88377, 88391, - 88405, 88419, 88433, 88447, 88461, 88475, 88489, 88503, 88517, 88531, - 88545, 88559, 88573, 88587, 88601, 88615, 88629, 88643, 88657, 88671, - 88685, 88699, 88713, 88727, 88741, 88755, 88769, 88783, 88797, 88811, - 88825, 88839, 88853, 88867, 88881, 88895, 88909, 88923, 88937, 88951, - 88965, 88979, 88993, 89007, 89021, 89035, 89049, 89063, 89077, 89091, - 89105, 89119, 89133, 89147, 89161, 89175, 89189, 89203, 89217, 89231, - 89245, 89259, 89273, 89287, 89301, 89315, 89329, 89343, 89357, 89371, - 89385, 89399, 89413, 89427, 89441, 89455, 89469, 89483, 89497, 89511, - 89525, 89539, 89553, 89567, 89581, 89595, 89609, 89623, 89637, 89651, - 89665, 89679, 89693, 89707, 89721, 89735, 89749, 89763, 89777, 89791, - 89805, 89819, 89833, 89847, 89861, 89875, 89889, 89903, 89917, 89931, - 89945, 89959, 89973, 89987, 90001, 90015, 90029, 90043, 90057, 90071, - 90085, 90099, 90113, 90127, 90141, 90155, 90169, 90183, 90197, 90211, - 90225, 90239, 90253, 90267, 90281, 90295, 90309, 90323, 90337, 90351, - 90365, 90379, 90393, 90407, 90421, 90435, 90449, 90463, 90477, 90491, - 90505, 90519, 90533, 90547, 90561, 90575, 90589, 90603, 90617, 90631, - 90645, 90659, 90673, 90687, 90701, 90715, 90729, 90743, 90757, 90771, - 90785, 90799, 90813, 90827, 90841, 90855, 90869, 90883, 90897, 90911, - 90925, 90939, 90953, 90967, 90981, 90995, 91009, 91023, 91037, 91051, - 91065, 91079, 91093, 91107, 91121, 91135, 91149, 91163, 91177, 91191, - 91205, 91219, 91233, 91247, 91261, 91275, 91289, 91303, 91317, 91331, - 91345, 91359, 91373, 91387, 91401, 91415, 91429, 91443, 91457, 91471, - 91485, 91499, 91513, 91527, 91541, 91555, 91569, 91583, 91597, 91611, - 91625, 91639, 91653, 91667, 91681, 91695, 91709, 91723, 91737, 91751, - 91765, 91779, 91793, 91807, 91821, 91835, 91849, 91863, 91877, 91891, - 91905, 91919, 91933, 91947, 91961, 91975, 91989, 92003, 92017, 92031, - 92045, 92059, 92073, 92087, 92101, 92115, 92129, 92143, 92157, 92171, - 92185, 92199, 92213, 92227, 92241, 92255, 92269, 92283, 92297, 92311, - 92325, 92339, 92353, 92367, 92381, 92395, 92409, 92423, 92437, 92451, - 92465, 92479, 92493, 92507, 92521, 92535, 92549, 92563, 92577, 92591, - 92605, 92619, 92633, 92647, 92661, 92675, 92689, 92703, 92717, 92731, - 92745, 92759, 92773, 92787, 92801, 92815, 92829, 92843, 92857, 92871, - 92885, 92899, 92913, 92927, 92941, 92955, 92969, 92983, 92997, 93011, - 93025, 93039, 93053, 93067, 93081, 93095, 93109, 93123, 93137, 93151, - 93165, 93179, 93193, 93207, 93221, 93235, 93249, 93263, 93277, 93291, - 93305, 93319, 93333, 93347, 93361, 93375, 93389, 93403, 93417, 93431, - 93445, 93459, 93473, 93487, 93501, 93515, 93529, 93543, 93557, 93571, - 93585, 93599, 93613, 93627, 93641, 93655, 93669, 93683, 93697, 93711, - 93725, 93739, 93753, 93767, 93781, 93795, 93809, 93823, 93837, 93851, - 93865, 93879, 93893, 93907, 93921, 93935, 93949, 93963, 93977, 93991, - 94005, 94019, 94033, 94047, 94061, 94075, 94089, 94103, 94117, 94131, - 94145, 94159, 94173, 94187, 94201, 94215, 94229, 94243, 94257, 94271, - 94285, 94299, 94313, 94327, 94341, 94355, 94369, 94383, 94397, 94411, - 94425, 94439, 94453, 94467, 94481, 94495, 94509, 94523, 94537, 94551, - 94565, 94579, 94593, 94607, 94621, 94635, 94649, 94663, 94677, 94691, - 94705, 94719, 94733, 94747, 94761, 94775, 94789, 94803, 94817, 94831, - 94845, 94859, 94873, 94887, 94901, 94915, 94929, 94943, 94957, 94971, - 94985, 94999, 95013, 95027, 95041, 95055, 95069, 95083, 95097, 95111, - 95125, 95139, 95153, 95167, 95181, 95195, 95209, 95223, 95237, 95251, - 95265, 95279, 95293, 95307, 95321, 95335, 95349, 95363, 95377, 95391, - 95405, 95419, 95433, 95447, 95461, 95475, 95489, 95503, 95517, 95531, - 95545, 95559, 95573, 95587, 95601, 95615, 95629, 95643, 95657, 95671, - 95685, 95699, 95713, 95727, 95741, 95755, 95769, 95783, 95797, 95811, - 95825, 95839, 95853, 95867, 95881, 95895, 95909, 95923, 95937, 95951, - 95965, 95979, 95993, 96007, 96021, 96035, 96049, 96063, 96077, 96091, - 96105, 96119, 96133, 96147, 96161, 96175, 96189, 96203, 96217, 96231, - 96245, 96259, 96273, 96287, 96301, 96315, 96329, 96343, 96357, 96371, - 96385, 96399, 96413, 96427, 96441, 96455, 96469, 96483, 96497, 96511, - 96525, 96539, 96553, 96567, 96581, 96595, 96609, 96623, 96637, 96651, - 96665, 96679, 96693, 96707, 96716, 96727, 96738, 96748, 96759, 96767, - 96775, 96781, 96791, 96799, 96805, 35311, 96810, 96816, 96825, 96837, - 96842, 96849, 11350, 21916, 96855, 96864, 96869, 96873, 96878, 96885, - 96891, 96896, 96901, 96909, 96917, 96927, 96932, 96940, 14487, 96944, - 96950, 96956, 96962, 96968, 96974, 96980, 96986, 96992, 96998, 97004, - 97010, 97016, 97022, 97028, 97034, 97040, 97046, 97052, 97058, 97064, - 97070, 97076, 97082, 97088, 97094, 97100, 97106, 97112, 97118, 97124, - 97130, 97136, 97142, 97148, 97154, 97160, 97167, 97173, 97179, 97185, - 97191, 97197, 97203, 97209, 97215, 97221, 97227, 97233, 97239, 97245, - 97251, 97257, 97263, 97269, 97275, 97281, 97287, 97293, 97299, 97305, - 97311, 97317, 97323, 97329, 97335, 97341, 97347, 97353, 97359, 97365, - 97371, 97377, 97383, 97389, 97395, 97401, 97407, 97413, 97419, 97425, - 97431, 97437, 97443, 97449, 97455, 97461, 97467, 97474, 97480, 97486, - 97492, 97498, 97504, 97510, 97516, 97522, 97528, 97534, 97540, 97543, - 97545, 97560, 97573, 97580, 97586, 97597, 97602, 97606, 97611, 97618, - 97624, 97629, 97637, 77621, 77631, 97643, 97650, 97660, 12646, 97667, - 97672, 35554, 97681, 97686, 97693, 97703, 97711, 97719, 97728, 97737, - 97743, 97749, 97754, 97761, 97768, 97773, 97777, 97785, 72000, 97790, - 97799, 97807, 97814, 97819, 97823, 97832, 97838, 97841, 97845, 97854, - 97864, 84658, 97873, 97877, 97885, 97889, 97895, 97906, 97916, 21925, - 97927, 97936, 97944, 97952, 97959, 72019, 9875, 97967, 97971, 97980, - 97987, 97990, 97994, 33167, 97997, 98001, 98006, 98023, 98035, 12604, - 98047, 98052, 98057, 98062, 25513, 98066, 98071, 98076, 98082, 98087, - 6626, 98092, 25517, 98097, 98102, 98108, 98115, 98120, 98125, 98131, - 98137, 98143, 98148, 98154, 98158, 98172, 98180, 98188, 98194, 98199, - 98206, 98216, 98225, 98230, 98235, 98240, 98248, 98258, 98269, 98274, - 98280, 98285, 98294, 70435, 4752, 98299, 98317, 98336, 98349, 98363, - 98379, 98386, 98393, 98402, 98409, 98415, 98422, 98427, 98433, 98438, - 98444, 98452, 98458, 98463, 98468, 98484, 12617, 98498, 98505, 98513, - 98519, 98523, 98526, 98532, 98537, 98542, 98550, 98557, 98562, 98571, - 98577, 98582, 98588, 98594, 98603, 98612, 43344, 98617, 98628, 98635, - 98643, 98652, 14078, 98661, 98667, 98675, 98681, 98687, 98693, 98698, - 98705, 98711, 14089, 98716, 98719, 98724, 39537, 98734, 98743, 98748, - 98756, 98763, 98769, 98774, 98782, 98789, 98800, 98816, 98832, 98848, - 98864, 98880, 98896, 98912, 98928, 98944, 98960, 98976, 98992, 99008, - 99024, 99040, 99056, 99072, 99088, 99104, 99120, 99136, 99152, 99168, - 99184, 99200, 99216, 99232, 99248, 99264, 99280, 99296, 99312, 99328, - 99344, 99360, 99376, 99392, 99408, 99424, 99440, 99456, 99472, 99488, - 99504, 99520, 99536, 99552, 99568, 99584, 99600, 99616, 99632, 99648, - 99664, 99680, 99696, 99712, 99728, 99744, 99760, 99776, 99792, 99808, - 99824, 99840, 99856, 99872, 99888, 99904, 99920, 99936, 99952, 99968, - 99984, 100000, 100016, 100032, 100048, 100064, 100080, 100096, 100112, - 100128, 100144, 100160, 100176, 100192, 100208, 100224, 100240, 100256, - 100272, 100288, 100304, 100320, 100336, 100352, 100368, 100384, 100400, - 100416, 100432, 100448, 100464, 100480, 100496, 100512, 100528, 100544, - 100560, 100576, 100592, 100608, 100624, 100640, 100656, 100672, 100688, - 100704, 100720, 100736, 100752, 100768, 100784, 100800, 100816, 100832, - 100848, 100864, 100880, 100896, 100912, 100928, 100944, 100960, 100976, - 100992, 101008, 101024, 101040, 101056, 101072, 101088, 101104, 101120, - 101136, 101152, 101168, 101184, 101200, 101216, 101232, 101248, 101264, - 101280, 101296, 101312, 101328, 101344, 101360, 101376, 101392, 101408, - 101424, 101440, 101456, 101472, 101488, 101504, 101520, 101536, 101552, - 101568, 101584, 101600, 101616, 101632, 101648, 101664, 101680, 101696, - 101712, 101728, 101744, 101760, 101776, 101792, 101808, 101824, 101840, - 101856, 101872, 101888, 101904, 101920, 101936, 101952, 101968, 101984, - 102000, 102016, 102032, 102048, 102064, 102080, 102096, 102112, 102128, - 102144, 102160, 102176, 102192, 102208, 102224, 102240, 102256, 102272, - 102288, 102304, 102320, 102336, 102352, 102368, 102384, 102400, 102416, - 102432, 102448, 102464, 102480, 102496, 102512, 102528, 102544, 102560, - 102576, 102592, 102608, 102624, 102640, 102656, 102672, 102688, 102704, - 102720, 102736, 102752, 102768, 102784, 102800, 102816, 102832, 102848, - 102864, 102880, 102896, 102912, 102928, 102944, 102960, 102976, 102992, - 103008, 103024, 103040, 103056, 103072, 103088, 103104, 103120, 103136, - 103152, 103168, 103184, 103200, 103216, 103232, 103248, 103264, 103280, - 103296, 103312, 103328, 103344, 103360, 103376, 103392, 103408, 103424, - 103440, 103456, 103472, 103488, 103504, 103520, 103536, 103552, 103568, - 103584, 103600, 103616, 103632, 103648, 103664, 103680, 103696, 103712, - 103728, 103744, 103760, 103776, 103792, 103808, 103824, 103840, 103856, - 103872, 103888, 103904, 103920, 103936, 103952, 103968, 103984, 104000, - 104016, 104032, 104048, 104064, 104080, 104096, 104112, 104128, 104144, - 104160, 104176, 104192, 104208, 104224, 104240, 104256, 104272, 104288, - 104304, 104320, 104336, 104352, 104368, 104384, 104400, 104416, 104432, - 104448, 104464, 104480, 104496, 104512, 104528, 104544, 104560, 104576, - 104592, 104608, 104624, 104640, 104656, 104672, 104688, 104704, 104720, - 104736, 104752, 104768, 104784, 104800, 104816, 104832, 104848, 104864, - 104880, 104896, 104912, 104928, 104944, 104960, 104976, 104992, 105008, - 105024, 105040, 105056, 105072, 105088, 105104, 105120, 105136, 105152, - 105168, 105184, 105200, 105216, 105232, 105248, 105264, 105280, 105296, - 105312, 105328, 105344, 105360, 105376, 105392, 105408, 105424, 105440, - 105456, 105472, 105488, 105504, 105520, 105536, 105552, 105568, 105584, - 105600, 105616, 105632, 105648, 105664, 105680, 105696, 105712, 105728, - 105744, 105760, 105776, 105792, 105808, 105824, 105840, 105856, 105872, - 105888, 105904, 105920, 105936, 105952, 105968, 105984, 106000, 106016, - 106032, 106048, 106064, 106080, 106096, 106112, 106128, 106144, 106160, - 106176, 106192, 106208, 106224, 106240, 106256, 106272, 106288, 106304, - 106320, 106336, 106352, 106368, 106384, 106400, 106416, 106432, 106448, - 106464, 106480, 106496, 106512, 106528, 106544, 106560, 106576, 106592, - 106608, 106624, 106640, 106656, 106672, 106688, 106704, 106720, 106736, - 106752, 106768, 106784, 106800, 106816, 106832, 106848, 106864, 106880, - 106896, 106912, 106928, 106944, 106960, 106976, 106992, 107008, 107024, - 107040, 107056, 107072, 107088, 107104, 107120, 107136, 107152, 107168, - 107184, 107200, 107216, 107232, 107248, 107264, 107280, 107296, 107312, - 107328, 107344, 107360, 107376, 107392, 107408, 107424, 107440, 107456, - 107472, 107488, 107504, 107520, 107536, 107552, 107568, 107584, 107600, - 107616, 107632, 107648, 107664, 107680, 107696, 107712, 107728, 107744, - 107760, 107776, 107792, 107808, 107824, 107840, 107856, 107872, 107888, - 107904, 107920, 107936, 107952, 107968, 107984, 108000, 108016, 108032, - 108048, 108064, 108080, 108096, 108112, 108128, 108144, 108160, 108176, - 108192, 108208, 108224, 108240, 108256, 108272, 108288, 108304, 108320, - 108336, 108352, 108368, 108384, 108400, 108416, 108432, 108448, 108464, - 108480, 108496, 108512, 108528, 108544, 108560, 108576, 108592, 108608, - 108624, 108640, 108656, 108672, 108688, 108704, 108720, 108736, 108752, - 108768, 108784, 108800, 108816, 108832, 108848, 108864, 108880, 108896, - 108912, 108928, 108944, 108960, 108976, 108992, 109008, 109024, 109040, - 109056, 109072, 109088, 109104, 109120, 109136, 109152, 109168, 109184, - 109200, 109216, 109232, 109248, 109264, 109280, 109296, 109312, 109328, - 109344, 109360, 109376, 109392, 109408, 109424, 109440, 109456, 109472, - 109488, 109504, 109520, 109536, 109552, 109568, 109584, 109600, 109616, - 109632, 109648, 109664, 109680, 109696, 109712, 109728, 109744, 109760, - 109776, 109792, 109808, 109824, 109840, 109856, 109872, 109888, 109904, - 109920, 109936, 109952, 109968, 109984, 110000, 110016, 110032, 110048, - 110064, 110080, 110096, 110112, 110128, 110144, 110160, 110176, 110192, - 110208, 110224, 110240, 110256, 110272, 110288, 110304, 110320, 110336, - 110352, 110368, 110384, 110400, 110416, 110432, 110448, 110464, 110480, - 110496, 110512, 110528, 110544, 110560, 110576, 110592, 110608, 110624, - 110640, 110656, 110672, 110688, 110704, 110720, 110736, 110752, 110768, - 110784, 110800, 110816, 110832, 110848, 110864, 110880, 110896, 110912, - 110928, 110944, 110960, 110976, 110992, 111008, 111024, 111040, 111056, - 111072, 111088, 111104, 111120, 111136, 111152, 111168, 111184, 111200, - 111216, 111232, 111248, 111264, 111280, 111296, 111312, 111328, 111344, - 111360, 111376, 111392, 111408, 111424, 111440, 111456, 111472, 111488, - 111504, 111520, 111536, 111552, 111568, 111584, 111600, 111616, 111632, - 111648, 111664, 111680, 111696, 111712, 111728, 111744, 111760, 111776, - 111792, 111808, 111824, 111840, 111856, 111872, 111888, 111904, 111920, - 111936, 111952, 111968, 111984, 112000, 112016, 112032, 112048, 112064, - 112080, 112096, 112112, 112128, 112144, 112160, 112176, 112192, 112208, - 112224, 112240, 112256, 112272, 112288, 112304, 112320, 112336, 112352, - 112368, 112384, 112400, 112416, 112432, 112448, 112464, 112480, 112496, - 112512, 112528, 112544, 112560, 112576, 112592, 112608, 112624, 112640, - 112656, 112666, 112675, 112680, 112688, 76945, 112693, 112699, 112704, - 112711, 112720, 112728, 112732, 4330, 112738, 112745, 112751, 112755, - 20517, 46451, 3301, 112760, 112764, 112768, 112775, 112781, 112790, - 112796, 112803, 112807, 112828, 112850, 112866, 112883, 112902, 112911, - 112921, 112929, 112936, 112943, 112949, 33022, 112963, 112967, 112973, - 112981, 112993, 112999, 113007, 113014, 113019, 113024, 113028, 113036, - 113043, 113047, 113053, 113059, 113064, 3978, 52365, 113070, 113074, - 113078, 113082, 113087, 113092, 113097, 113103, 113109, 113115, 113122, - 113128, 113135, 113141, 113147, 113152, 113158, 113163, 113167, 105260, - 113172, 105324, 52380, 113177, 113182, 113190, 113194, 113199, 113206, - 113215, 113222, 113228, 113237, 113241, 113248, 113252, 113255, 113262, - 113268, 113277, 113287, 113297, 113302, 113306, 113313, 113321, 113330, - 113334, 113342, 113348, 113353, 113358, 113364, 113370, 113375, 113379, - 31903, 113385, 113389, 113393, 113396, 113401, 113409, 113419, 113425, - 113430, 113440, 49513, 113448, 113460, 113466, 113473, 113479, 113483, - 113488, 113494, 113506, 113517, 113524, 113530, 113537, 113544, 113556, - 113563, 113569, 25597, 113573, 113581, 113587, 113594, 113600, 113606, - 113612, 113617, 113622, 113627, 113631, 113640, 113648, 113659, 7920, - 113664, 19953, 113670, 113674, 113678, 113682, 113690, 113699, 113703, - 113710, 113719, 113727, 113740, 113746, 105836, 36477, 113751, 113753, - 113758, 113763, 113768, 113773, 113778, 113783, 113788, 113793, 113798, - 113803, 113808, 113813, 113818, 113823, 113829, 113834, 113839, 113844, - 113849, 113854, 113859, 113864, 113869, 113875, 113881, 113887, 113892, - 113897, 113909, 113914, 1941, 54, 113919, 113924, 39547, 113928, 39552, - 39557, 39563, 39568, 113932, 39573, 26783, 113954, 113958, 113962, - 113967, 113971, 39577, 113975, 113983, 113990, 113996, 114006, 39582, - 114013, 114016, 114021, 114025, 114034, 11148, 114042, 39587, 26627, - 114045, 114049, 114057, 1313, 114062, 39598, 114065, 114070, 114075, - 31144, 31154, 42942, 114080, 114085, 114090, 114095, 114101, 114106, - 114115, 114120, 114129, 114137, 114144, 114150, 114155, 114160, 114165, - 114175, 114184, 114192, 114197, 114205, 114209, 114217, 114221, 114228, - 114235, 114243, 114250, 39402, 46166, 114256, 114262, 114267, 114272, - 14522, 11935, 114277, 114282, 114287, 114293, 114300, 114306, 114315, - 114320, 114328, 114338, 114345, 114355, 114361, 114366, 114372, 114376, - 21947, 114383, 43910, 114396, 114401, 114408, 114414, 114429, 37541, - 75357, 114442, 114446, 114455, 114464, 114471, 114477, 114485, 114491, - 114499, 114508, 114516, 114523, 46286, 114529, 114532, 114536, 114540, - 114544, 11956, 114550, 114557, 114563, 114571, 114576, 114580, 29148, - 114586, 114589, 114597, 114604, 114612, 114625, 114639, 114646, 114652, - 114659, 114665, 39612, 114669, 114675, 114683, 114690, 114698, 114706, - 114712, 39617, 114720, 114726, 114731, 114741, 114747, 114756, 37336, - 42290, 114764, 114769, 114774, 114778, 114783, 114787, 114795, 114800, - 17949, 18774, 49535, 114804, 114809, 39622, 18106, 114813, 114825, - 114830, 114834, 114841, 114850, 114854, 114862, 114868, 114873, 114881, - 114889, 114897, 114905, 114913, 114921, 114932, 114938, 9112, 114943, - 114949, 114954, 114959, 114970, 114979, 114991, 115006, 39934, 115012, - 20072, 39626, 115016, 115023, 115029, 115033, 29285, 115040, 115046, - 115053, 48667, 115062, 115068, 115077, 115083, 115088, 115096, 115102, - 115107, 39636, 115112, 115121, 115130, 113512, 115139, 115146, 115152, - 115158, 115167, 115177, 115183, 115191, 115198, 115202, 39641, 115205, - 39647, 1352, 115210, 115218, 115226, 115236, 115245, 115253, 115260, - 115270, 39658, 115274, 115276, 115280, 115285, 115289, 115293, 115299, - 115304, 115308, 115319, 115324, 115333, 115338, 3306, 115342, 115349, - 115353, 115362, 115370, 115378, 115385, 115390, 115395, 73882, 115399, - 115402, 115408, 115416, 115422, 115426, 115431, 115438, 115443, 115448, - 115452, 115459, 115465, 115470, 42321, 115474, 115477, 115482, 115486, - 115491, 115498, 115503, 115507, 47636, 115515, 31163, 31172, 115521, - 115527, 115533, 115538, 115542, 115545, 115555, 115564, 115569, 115575, - 115582, 115588, 115592, 115600, 115605, 42327, 84917, 115609, 115617, - 115624, 115630, 115637, 115642, 115649, 115654, 115658, 115664, 115669, - 68924, 115675, 115681, 10366, 115686, 115691, 115695, 115700, 115705, - 115710, 115714, 115719, 115724, 115730, 115735, 115740, 115746, 115752, - 115757, 115761, 115766, 115771, 115776, 115780, 29284, 115785, 115790, - 115796, 115802, 115808, 115813, 115817, 115822, 115827, 109612, 115832, - 115837, 115842, 115847, 109676, 52635, 115852, 39666, 115860, 115864, - 115872, 115880, 115891, 115896, 115900, 27262, 82330, 115905, 115911, - 115916, 4641, 115926, 115933, 115938, 115946, 115955, 115960, 115964, - 115969, 115973, 115981, 115989, 115996, 77207, 116002, 116010, 116017, - 116028, 116034, 116040, 39676, 116043, 116050, 116058, 116063, 116067, - 33538, 71588, 116073, 116078, 116085, 116090, 10255, 116094, 116102, - 116109, 116116, 116125, 116132, 116138, 116152, 116160, 6710, 115922, - 116166, 116171, 116177, 116181, 116184, 116192, 116199, 116204, 116217, - 116224, 116230, 116234, 116242, 116247, 116254, 116260, 116265, 71859, - 116270, 116273, 116282, 116289, 109884, 116295, 116298, 116306, 116312, - 116321, 116331, 116341, 116350, 116361, 116369, 116380, 116385, 116389, - 116394, 116398, 43073, 116406, 18739, 43082, 116411, 101403, 101419, - 101435, 101451, 101467, 116416, 101499, 101515, 101531, 101547, 101659, - 101675, 116420, 101707, 101723, 116424, 116428, 116432, 116436, 101963, - 101995, 116440, 102027, 116444, 116448, 102171, 102187, 102203, 102219, - 116452, 102283, 102299, 116456, 102427, 102443, 102459, 102475, 102491, - 102507, 102523, 102539, 102555, 102571, 102683, 102699, 102715, 102731, - 102747, 102763, 102779, 102795, 102811, 102827, 116460, 104619, 104731, - 104795, 104811, 104827, 104843, 104859, 104875, 104987, 105003, 105019, - 116464, 105067, 116468, 105099, 105115, 105131, 116472, 116477, 116482, - 116487, 116492, 116497, 116502, 116506, 116510, 116515, 116520, 116524, - 116529, 116534, 116538, 116543, 116548, 116553, 116558, 116562, 116567, - 116572, 116576, 116581, 116585, 116589, 116593, 116597, 116602, 116606, - 116610, 116614, 116618, 116622, 116626, 116630, 116634, 116638, 116643, - 116648, 116653, 116658, 116663, 116668, 116673, 116678, 116683, 116688, - 116692, 116696, 116700, 116704, 116708, 116712, 116717, 116721, 116726, - 116730, 116735, 116740, 116744, 116748, 116753, 116757, 116761, 116765, - 116769, 116773, 116777, 116781, 116785, 116789, 116793, 116797, 116801, - 116805, 116809, 116814, 116819, 116823, 116827, 116831, 116835, 116839, - 116843, 116848, 116852, 116856, 116860, 116864, 116868, 116872, 116877, - 116881, 116886, 116890, 116894, 116898, 116902, 116906, 116910, 116914, - 116918, 116922, 116926, 116930, 116935, 116939, 116943, 116947, 116951, - 116955, 116959, 116963, 116967, 116971, 116975, 116979, 116984, 116988, - 116992, 116997, 117002, 117006, 117010, 117014, 117018, 117022, 117026, - 117030, 117034, 117039, 117043, 117048, 117052, 117057, 117061, 117066, - 117070, 117076, 117081, 117085, 117090, 117094, 117099, 117103, 117108, - 117112, 117117, 1435, 117121, 117125, 3048, 1711, 28421, 1608, 31099, - 117129, 3057, 117133, 1282, 117138, 1224, 117142, 117146, 117150, 117154, - 117158, 117162, 3081, 117166, 117174, 117181, 117188, 117202, 3085, 8030, - 117211, 117219, 117226, 117237, 117246, 117250, 117257, 117269, 117282, - 117295, 117306, 117311, 117318, 117330, 117334, 3089, 14159, 117344, - 117349, 117358, 117368, 117373, 117382, 3093, 117390, 117394, 117399, - 117406, 117412, 117417, 117426, 117434, 117446, 117456, 1229, 15619, - 117469, 117473, 117479, 117493, 117505, 117517, 117525, 117535, 117544, - 117553, 117562, 117570, 117581, 117589, 4649, 117599, 117610, 117619, - 117625, 117640, 117647, 117653, 117658, 43216, 117663, 3117, 15623, - 117667, 117672, 117679, 10186, 117688, 117694, 4687, 117704, 3122, 39038, - 117713, 71478, 117720, 117724, 117730, 117741, 117747, 117752, 117759, - 117765, 117773, 117780, 117786, 117797, 117813, 117823, 117832, 117843, - 117852, 117859, 117865, 117875, 117883, 117889, 117904, 117910, 117915, - 117919, 117926, 117934, 117938, 117941, 117947, 117954, 117960, 117968, - 117977, 117985, 117991, 118000, 51943, 118014, 118019, 118025, 17700, - 118030, 118043, 118055, 118064, 118072, 118079, 118083, 118087, 118090, - 118097, 118104, 118112, 118120, 118129, 118137, 17599, 118145, 118150, - 118154, 118166, 118173, 118180, 118189, 954, 118199, 118208, 118219, - 3143, 118223, 118227, 118233, 118246, 118258, 118268, 118277, 118289, - 32057, 118300, 118308, 118317, 118328, 118339, 118349, 118359, 118367, - 118376, 118384, 13578, 118391, 118395, 118398, 118403, 118408, 118412, - 118418, 1234, 118425, 118429, 14255, 118433, 118444, 118453, 118461, - 118470, 118478, 118494, 118505, 118514, 118522, 118534, 118545, 118561, - 118571, 118592, 118606, 118619, 118627, 118634, 8076, 118647, 118652, - 118658, 6719, 118664, 118667, 118674, 118684, 9246, 118691, 118696, - 118701, 118708, 118716, 118724, 118730, 118735, 118741, 118745, 118753, - 118762, 118770, 118775, 118784, 118791, 11398, 11407, 118797, 118808, - 118814, 118819, 118825, 3159, 3164, 118831, 1060, 118837, 118844, 118851, - 118864, 118874, 118879, 2330, 87, 118887, 118894, 118899, 118907, 118917, - 118926, 118932, 118941, 118949, 118959, 118963, 118967, 118972, 118976, - 118988, 3187, 118996, 119004, 119009, 119020, 119031, 119043, 119054, - 119064, 119073, 25981, 119078, 119084, 119089, 119099, 119109, 119114, - 34272, 119120, 119125, 119134, 26003, 119138, 26014, 119143, 4769, 8, - 119150, 119159, 119166, 119173, 119179, 119184, 119188, 119194, 34302, - 119199, 119204, 72156, 119209, 119214, 119220, 119226, 119234, 119239, - 119247, 119255, 119264, 119271, 119277, 119284, 119290, 119297, 119302, - 47505, 51837, 119308, 119318, 1828, 32, 119325, 119330, 119343, 119348, - 119356, 119361, 119367, 3213, 30840, 119372, 119380, 119387, 119392, - 119397, 119406, 4332, 4343, 73480, 119414, 119418, 1635, 1868, 119423, - 119428, 119435, 34723, 1872, 323, 119442, 119448, 119453, 3235, 119457, - 119462, 119469, 1876, 119474, 119480, 119485, 119497, 6964, 119507, - 119514, 1883, 119520, 119525, 119532, 119539, 119554, 119561, 119572, - 119577, 119585, 2778, 119589, 119601, 119606, 119610, 119616, 34144, - 2335, 119620, 119631, 119635, 119639, 119645, 119649, 119658, 119662, - 119673, 119677, 2381, 38855, 119681, 119691, 119699, 3326, 119705, - 119714, 119722, 10732, 119727, 119735, 119740, 119744, 119753, 119760, - 119766, 3296, 17764, 119770, 119783, 43923, 119801, 119806, 119814, - 119822, 119832, 11739, 15741, 119844, 119857, 119864, 119874, 119888, - 119895, 119911, 119918, 119924, 26061, 14954, 119931, 119938, 119948, - 119957, 52634, 119969, 119977, 52769, 119984, 119987, 119993, 119999, - 120005, 120011, 120017, 120024, 120031, 120037, 120043, 120049, 120055, - 120061, 120067, 120073, 120079, 120085, 120091, 120097, 120103, 120109, - 120115, 120121, 120127, 120133, 120139, 120145, 120151, 120157, 120163, - 120169, 120175, 120181, 120187, 120193, 120199, 120205, 120211, 120217, - 120223, 120229, 120235, 120241, 120247, 120253, 120259, 120265, 120271, - 120277, 120283, 120289, 120295, 120301, 120307, 120313, 120319, 120325, - 120331, 120337, 120344, 120350, 120357, 120364, 120370, 120377, 120384, - 120390, 120396, 120402, 120408, 120414, 120420, 120426, 120432, 120438, - 120444, 120450, 120456, 120462, 120468, 120474, 3310, 10700, 120480, - 120490, 120496, 120504, 120508, 117402, 3314, 120512, 113741, 25726, - 4693, 4257, 120516, 3320, 120520, 120530, 120536, 120542, 120548, 120554, - 120560, 120566, 120572, 120578, 120584, 120590, 120596, 120602, 120608, - 120614, 120620, 120626, 120632, 120638, 120644, 120650, 120656, 120662, - 120668, 120674, 120680, 120687, 120694, 120700, 120706, 120712, 120718, - 120724, 120730, 1239, 120736, 120741, 120746, 120751, 120756, 120761, - 120766, 120771, 120776, 120780, 120784, 120788, 120792, 120796, 120800, - 120804, 120808, 120812, 120818, 120824, 120830, 120836, 120840, 120844, - 120848, 120852, 120856, 120860, 120864, 120868, 120872, 120877, 120882, - 120887, 120892, 120897, 120902, 120907, 120912, 120917, 120922, 120927, - 120932, 120937, 120942, 120947, 120952, 120957, 120962, 120967, 120972, - 120977, 120982, 120987, 120992, 120997, 121002, 121007, 121012, 121017, - 121022, 121027, 121032, 121037, 121042, 121047, 121052, 121057, 121062, - 121067, 121072, 121077, 121082, 121087, 121092, 121097, 121102, 121107, - 121112, 121117, 121122, 121127, 121132, 121137, 121142, 121147, 121152, - 121157, 121162, 121167, 121172, 121177, 121182, 121187, 121192, 121197, - 121202, 121207, 121212, 121217, 121222, 121227, 121232, 121237, 121242, - 121247, 121252, 121257, 121262, 121267, 121272, 121277, 121282, 121287, - 121292, 121297, 121302, 121307, 121312, 121317, 121322, 121327, 121332, - 121337, 121342, 121347, 121352, 121357, 121362, 121367, 121372, 121377, - 121382, 121387, 121392, 121397, 121402, 121407, 121412, 121417, 121422, - 121427, 121432, 121437, 121442, 121447, 121452, 121457, 121462, 121467, - 121472, 121477, 121482, 121487, 121492, 121497, 121502, 121507, 121512, - 121517, 121522, 121527, 121532, 121537, 121542, 121547, 121552, 121557, - 121562, 121567, 121572, 121577, 121582, 121587, 121592, 121597, 121602, - 121607, 121612, 121617, 121622, 121627, 121632, 121637, 121642, 121647, - 121652, 121657, 121662, 121667, 121672, 121677, 121682, 121687, 121692, - 121697, 121702, 121707, 121712, 121717, 121722, 121727, 121732, 121737, - 121742, 121747, 121752, 121757, 121762, 121768, 121773, 121778, 121783, - 121788, 121793, 121798, 121803, 121809, 121814, 121819, 121824, 121829, - 121834, 121839, 121844, 121849, 121854, 121859, 121864, 121869, 121874, - 121879, 121884, 121889, 121894, 121899, 121904, 121909, 121914, 121919, - 121924, 121929, 121934, 121939, 121944, 121949, 121954, 121959, 121964, - 121969, 121978, 121983, 121992, 121997, 122006, 122011, 122020, 122025, - 122034, 122039, 122048, 122053, 122062, 122067, 122076, 122081, 122086, - 122095, 122099, 122108, 122113, 122122, 122127, 122136, 122141, 122150, - 122155, 122164, 122169, 122178, 122183, 122192, 122197, 122206, 122211, - 122220, 122225, 122234, 122239, 122244, 122249, 122254, 122259, 122264, - 122269, 122273, 122278, 122283, 122288, 122293, 122298, 122303, 122309, - 122314, 122319, 122324, 122330, 122334, 122339, 122345, 122350, 122355, - 122360, 122365, 122370, 122375, 122380, 122385, 122390, 122395, 122401, - 122406, 122411, 122416, 122422, 122427, 122432, 122437, 122442, 122448, - 122453, 122458, 122463, 122468, 122473, 122479, 122484, 122489, 122494, - 122499, 122504, 122509, 122514, 122519, 122524, 122529, 122534, 122539, - 122544, 122549, 122554, 122559, 122564, 122569, 122574, 122579, 122584, - 122589, 122594, 122600, 122606, 122612, 122617, 122622, 122627, 122632, - 122638, 122644, 122650, 122655, 122660, 122665, 122671, 122676, 122681, - 122686, 122691, 122696, 122701, 122706, 122711, 122716, 122721, 122726, - 122731, 122736, 122741, 122746, 122751, 122757, 122763, 122769, 122774, - 122779, 122784, 122789, 122795, 122801, 122807, 122812, 122817, 122822, - 122827, 122832, 122837, 122842, 122847, 122852, 19431, 122857, 122863, - 122868, 122873, 122878, 122883, 122888, 122894, 122899, 122904, 122909, - 122914, 122919, 122925, 122930, 122935, 122940, 122945, 122950, 122955, - 122960, 122965, 122970, 122975, 122980, 122985, 122990, 122995, 123000, - 123005, 123010, 123015, 123020, 123025, 123030, 123035, 123041, 123046, - 123051, 123056, 123061, 123066, 123071, 123076, 123081, 123086, 123091, - 123096, 123101, 123106, 123111, 123116, 123121, 123126, 123131, 123136, - 123141, 123146, 123151, 123156, 123161, 123166, 123171, 123176, 123181, - 123186, 123191, 123196, 123201, 123206, 123211, 123216, 123221, 123226, - 123231, 123236, 123241, 123247, 123252, 123257, 123262, 123267, 123272, - 123277, 123282, 123287, 123292, 123297, 123302, 123308, 123313, 123319, - 123324, 123329, 123334, 123339, 123344, 123349, 123355, 123360, 123365, - 123371, 123376, 123381, 123386, 123391, 123396, 123402, 123408, 123413, - 123418, 14588, 123423, 123428, 123433, 123438, 123443, 123448, 123453, - 123458, 123463, 123468, 123473, 123478, 123483, 123488, 123493, 123498, - 123503, 123508, 123513, 123518, 123523, 123528, 123533, 123538, 123543, - 123548, 123553, 123558, 123563, 123568, 123573, 123578, 123583, 123588, - 123593, 123598, 123603, 123608, 123613, 123618, 123623, 123628, 123633, - 123638, 123643, 123648, 123653, 123658, 123663, 123668, 123673, 123678, - 123683, 123688, 123693, 123698, 123703, 123708, 123713, 123718, 123723, - 123728, 123733, 123738, 123743, 123749, 123754, 123759, 123764, 123769, - 123775, 123780, 123785, 123790, 123795, 123800, 123805, 123811, 123816, - 123821, 123826, 123831, 123836, 123842, 123847, 123852, 123857, 123862, - 123867, 123873, 123878, 123883, 123888, 123893, 123898, 123904, 123910, - 123915, 123920, 123925, 123931, 123937, 123943, 123948, 123953, 123959, - 123965, 123970, 123976, 123982, 123988, 123993, 123998, 124004, 124009, - 124015, 124020, 124026, 124035, 124040, 124045, 124051, 124056, 124062, - 124067, 124072, 124077, 124082, 124087, 124092, 124097, 124102, 124107, - 124112, 124117, 124122, 124127, 124132, 124137, 124142, 124147, 124152, - 124157, 124162, 124167, 124172, 124177, 124182, 124187, 124192, 124197, - 124202, 124207, 124212, 124217, 124223, 124229, 124235, 124240, 124245, - 124250, 124255, 124260, 124265, 124270, 124275, 124280, 124285, 124290, - 124295, 124300, 124305, 124310, 124315, 124320, 124325, 124330, 124335, - 124341, 124347, 124352, 124358, 124363, 124368, 124374, 124379, 124385, - 124390, 124396, 124401, 124407, 124412, 124418, 124423, 124428, 124433, - 124438, 124443, 124448, 124453, 120531, 120537, 120543, 120549, 124459, - 120555, 120561, 124465, 120567, 120573, 120579, 120585, 120591, 120597, - 120603, 120609, 120615, 124471, 120621, 120627, 120633, 124477, 120639, - 120645, 120651, 120657, 124483, 120663, 120669, 120675, 120695, 124489, - 124495, 120701, 124501, 120707, 120713, 120719, 120725, 120731, 124507, - 3337, 3342, 124512, 3357, 3362, 3367, 124517, 124520, 124526, 124532, - 124539, 124544, 124549, 2386, + 113, 118, 124, 129, 137, 146, 149, 160, 165, 170, 176, 180, 189, 195, + 201, 207, 216, 224, 229, 237, 244, 177, 252, 255, 261, 262, 268, 273, + 277, 282, 289, 296, 306, 311, 317, 325, 330, 333, 339, 344, 350, 356, + 359, 365, 375, 380, 385, 390, 392, 394, 403, 405, 412, 354, 419, 427, + 436, 438, 441, 449, 454, 455, 457, 464, 472, 478, 484, 491, 496, 503, + 507, 512, 519, 524, 527, 531, 536, 542, 547, 557, 565, 572, 575, 585, + 593, 598, 606, 615, 618, 625, 629, 633, 637, 642, 645, 652, 659, 666, + 671, 676, 683, 692, 694, 703, 707, 715, 719, 727, 281, 736, 749, 753, + 758, 761, 765, 769, 771, 776, 786, 792, 796, 802, 806, 809, 814, 823, + 828, 832, 774, 838, 846, 854, 859, 868, 877, 885, 891, 902, 905, 910, + 918, 925, 928, 938, 943, 949, 953, 957, 960, 967, 974, 977, 981, 984, + 657, 990, 993, 996, 1002, 1007, 1016, 1021, 1025, 1028, 1032, 1035, 1041, + 1046, 1050, 617, 1055, 1058, 1067, 1070, 1075, 1080, 1086, 1091, 1096, + 1101, 1105, 1110, 1116, 1121, 1126, 1130, 1136, 1141, 1146, 1151, 1155, + 1160, 1165, 1170, 1176, 1182, 1188, 1193, 1197, 1202, 1207, 1212, 1216, + 1221, 1226, 1231, 1236, 1071, 1076, 1081, 1087, 1092, 1240, 1102, 1246, + 1251, 1256, 1263, 1267, 1270, 1279, 1106, 1283, 1111, 1117, 1122, 1287, + 1292, 1297, 1301, 1305, 1311, 1315, 1127, 1318, 1320, 1137, 1325, 1329, + 1142, 1335, 1147, 1339, 1343, 1350, 1152, 1354, 1362, 1367, 1371, 1374, + 1378, 1156, 1161, 1383, 1389, 1166, 1401, 1407, 1413, 1419, 1171, 1183, + 1189, 1423, 1427, 1431, 1434, 1194, 1438, 1440, 1445, 1450, 1456, 1461, + 1466, 1470, 1475, 1480, 1485, 1490, 1496, 1501, 1506, 1512, 1518, 1523, + 1527, 1532, 1537, 1542, 1547, 1552, 1556, 1564, 1569, 1573, 1578, 1583, + 1588, 1593, 1597, 1600, 1607, 1612, 1617, 1622, 1627, 1633, 1638, 1642, + 1198, 1645, 1651, 1656, 1661, 1666, 1203, 1670, 1674, 1681, 1688, 1208, + 1693, 1698, 1213, 1702, 1704, 1709, 1720, 1726, 1217, 1731, 1740, 1222, + 1745, 1751, 1756, 1761, 1771, 1780, 1788, 1227, 1798, 1807, 1816, 1821, + 1825, 1828, 1837, 1847, 1856, 1861, 1865, 1869, 1873, 1876, 1880, 1885, + 1232, 1895, 1237, 1899, 1901, 1907, 1913, 1919, 1925, 1931, 1937, 1943, + 1949, 1954, 1960, 1966, 1972, 1978, 1984, 1990, 1996, 2002, 2008, 2013, + 2018, 2023, 2028, 2033, 2038, 2043, 2048, 2053, 2058, 2064, 2069, 2075, + 2080, 2086, 2092, 2097, 2103, 2109, 2115, 2121, 2126, 2131, 2133, 2134, + 2138, 2142, 2147, 2151, 2155, 2159, 2164, 2168, 2171, 2176, 2180, 2185, + 2189, 2193, 2198, 2202, 2205, 2209, 2215, 2229, 2233, 2237, 2241, 2244, + 2249, 2253, 2257, 2260, 2264, 2269, 2274, 2279, 2284, 2288, 2292, 2296, + 2300, 2304, 2309, 2313, 2318, 2322, 2327, 2333, 2340, 2346, 2351, 2356, + 2361, 2367, 2372, 2378, 2383, 2388, 2393, 2398, 2403, 2406, 2408, 1088, + 2412, 2419, 2427, 2437, 2446, 2460, 2464, 2468, 2473, 2486, 2494, 2497, + 2501, 2504, 2509, 2513, 2516, 2520, 2524, 2529, 1715, 2534, 2538, 2541, + 2545, 2551, 2558, 2565, 2571, 2576, 2581, 2587, 2593, 2598, 2603, 2608, + 2613, 2618, 2623, 2548, 2628, 1706, 2630, 2636, 2640, 2645, 2649, 2653, + 1603, 1728, 2658, 2662, 2666, 2669, 2674, 2679, 2684, 2689, 2693, 2700, + 2705, 2708, 2712, 2716, 2723, 2729, 2733, 2739, 2743, 2747, 2752, 2759, + 2764, 2769, 2776, 2782, 2788, 2794, 2815, 2829, 2846, 2861, 2877, 2894, + 2909, 2918, 2923, 2927, 2932, 2937, 2941, 2953, 2960, 2966, 2336, 2972, + 2979, 2985, 2989, 2992, 2999, 3005, 3010, 3014, 3019, 3023, 3027, 2156, + 3031, 3036, 3041, 3045, 3050, 3058, 3062, 3069, 3074, 3078, 3082, 3086, + 3091, 3096, 3101, 3105, 3110, 3115, 3119, 3124, 3129, 3133, 3136, 3140, + 3144, 3152, 3157, 3161, 3165, 3171, 3180, 3184, 3188, 3194, 3199, 3206, + 3210, 3220, 3224, 3228, 3233, 3237, 3242, 3248, 3253, 3257, 3261, 3265, + 2561, 3273, 3278, 3284, 3289, 3293, 3298, 3303, 3307, 3313, 3318, 2160, + 3324, 3330, 3335, 3340, 3345, 3350, 3355, 3360, 3365, 3370, 3375, 3380, + 3385, 3390, 3395, 3400, 3406, 3411, 1103, 101, 3417, 3421, 3425, 3429, + 3434, 3438, 3442, 3448, 3453, 3457, 3461, 3466, 3471, 3475, 3480, 3484, + 3487, 3491, 3496, 3500, 3505, 3509, 3512, 3514, 3518, 3522, 3527, 3531, + 3534, 3547, 3551, 3555, 3559, 3564, 3568, 3572, 3575, 3579, 3583, 3588, + 3592, 3597, 3602, 3607, 3611, 3618, 3623, 3626, 3632, 3635, 3640, 3646, + 3650, 3654, 3657, 3662, 3666, 3671, 3675, 3679, 3682, 3688, 3693, 3698, + 3704, 3709, 3714, 3720, 3726, 3731, 3736, 3741, 3746, 3749, 979, 644, + 3755, 3758, 3763, 3767, 3771, 3775, 3779, 3782, 3786, 3791, 3796, 3800, + 3805, 3809, 3814, 3818, 3822, 3826, 3832, 3838, 3841, 3844, 153, 3850, + 3855, 3864, 3872, 3881, 3891, 3898, 3904, 3911, 3916, 3920, 3924, 3932, + 3939, 3944, 3949, 3956, 3961, 3965, 3975, 3979, 3983, 3988, 3993, 4003, + 2172, 4008, 4012, 4015, 4021, 4026, 4032, 4038, 4043, 4050, 4054, 4058, + 4062, 4067, 4072, 4077, 4082, 4087, 4092, 634, 616, 1264, 4097, 4104, + 4111, 4117, 4126, 4131, 4138, 4145, 4150, 4156, 4162, 4167, 4172, 4176, + 4182, 4189, 4194, 4198, 4202, 2181, 4208, 4216, 4222, 4230, 863, 4236, + 4244, 4255, 4259, 4269, 4275, 4280, 4285, 4290, 4295, 2186, 4300, 4305, + 4320, 4326, 4333, 4344, 4354, 4360, 4365, 4371, 4377, 4380, 4383, 4387, + 4392, 4395, 4402, 4411, 4416, 4420, 4424, 4428, 4432, 4437, 4443, 4454, + 4458, 3492, 4463, 4475, 4481, 4489, 4493, 4498, 4505, 4510, 4515, 4520, + 1472, 4525, 4528, 4531, 4535, 4538, 4544, 4548, 4562, 4566, 4569, 4573, + 4579, 4585, 4590, 4594, 4598, 4604, 4615, 4621, 4626, 4632, 4636, 4644, + 4656, 4666, 4672, 4677, 4686, 4694, 4705, 4712, 4718, 4724, 4728, 4734, + 4743, 4752, 4757, 4763, 4767, 4776, 4782, 4787, 4791, 4796, 4800, 4808, + 4814, 4818, 4825, 4830, 4834, 4840, 4846, 4853, 2194, 4862, 4873, 4883, + 4892, 4897, 4902, 4907, 4912, 1280, 4917, 4919, 4924, 4930, 4935, 4940, + 4945, 4950, 4955, 4960, 4966, 4971, 4977, 4982, 4987, 4992, 4998, 5003, + 5008, 5013, 5018, 5024, 5029, 5035, 5040, 5045, 5050, 5055, 5060, 5065, + 5071, 5076, 5081, 348, 389, 5086, 5092, 5095, 5099, 5103, 5110, 5116, + 5121, 5125, 5129, 5132, 5135, 5139, 5143, 5146, 5150, 5154, 5158, 5163, + 5167, 5171, 5177, 5186, 4843, 5191, 5195, 5198, 5203, 5208, 5213, 5218, + 5223, 5228, 5233, 5238, 5243, 5248, 5252, 5257, 5262, 5267, 5272, 5277, + 5282, 5287, 5292, 5297, 5302, 5306, 5311, 5316, 5321, 5326, 5331, 5336, + 5341, 5346, 5351, 5356, 5360, 5365, 5370, 5375, 5380, 5385, 5390, 5395, + 5400, 5405, 5410, 5414, 5419, 5424, 5429, 5434, 5439, 5444, 5449, 5454, + 5459, 5464, 5468, 5473, 5478, 5483, 5488, 5493, 5498, 5503, 5508, 5513, + 5518, 5522, 5527, 5532, 5537, 5542, 5547, 5552, 5557, 5562, 5567, 5572, + 5576, 5581, 5586, 5591, 5596, 5602, 5608, 5614, 5620, 5626, 5632, 5638, + 5643, 5649, 5655, 5661, 5667, 5673, 5679, 5685, 5691, 5697, 5703, 5708, + 5714, 5720, 5726, 5732, 5738, 5744, 5750, 5756, 5762, 5768, 5773, 5779, + 5785, 5791, 5797, 5803, 5809, 5815, 5821, 5827, 5833, 5838, 5844, 5850, + 5856, 5862, 5868, 5874, 5880, 5886, 5892, 5898, 5903, 5909, 5915, 5921, + 5927, 5933, 5939, 5945, 5951, 5957, 5963, 5968, 5972, 5978, 5984, 5990, + 5996, 6002, 6008, 6014, 6020, 6026, 6032, 6037, 6043, 6049, 6055, 6061, + 6067, 6073, 6079, 6085, 6091, 6097, 6102, 6108, 6114, 6120, 6126, 6132, + 6138, 6144, 6150, 6156, 6162, 6167, 6173, 6179, 6185, 6191, 6197, 6203, + 6209, 6215, 6221, 6227, 6232, 6238, 6244, 6250, 6256, 6262, 6268, 6274, + 6280, 6286, 6292, 6297, 6303, 6309, 6315, 6321, 6327, 6333, 6339, 6345, + 6351, 6357, 6362, 6368, 6374, 6380, 6386, 6392, 6398, 6404, 6410, 6416, + 6422, 6427, 6433, 6439, 6445, 6451, 6457, 6463, 6469, 6475, 6481, 6487, + 6492, 6498, 6504, 6510, 6516, 6522, 6528, 6534, 6540, 6546, 6552, 6557, + 6563, 6569, 6575, 6581, 6587, 6593, 6599, 6605, 6611, 6617, 6622, 6626, + 6629, 6637, 6644, 6647, 6651, 6664, 6668, 6672, 6676, 6679, 6683, 6688, + 6692, 6701, 6705, 6711, 6718, 6729, 6737, 6744, 6750, 6754, 6762, 6771, + 6777, 6781, 6793, 6798, 6801, 6806, 6810, 6820, 6828, 6836, 6844, 6850, + 6854, 6864, 6874, 6882, 6889, 6896, 6902, 6908, 6915, 6919, 6926, 6936, + 6946, 6954, 6961, 6966, 6970, 6974, 6982, 6986, 6996, 7001, 7008, 7015, + 7023, 7033, 7038, 7042, 7047, 7051, 7058, 7063, 7077, 7082, 7087, 7094, + 3768, 7103, 7107, 7111, 7116, 7120, 7124, 7127, 7132, 7137, 7146, 7152, + 7158, 7163, 7169, 7173, 7184, 7194, 7209, 7224, 7239, 7254, 7269, 7284, + 7299, 7314, 7329, 7344, 7359, 7374, 7389, 7404, 7419, 7434, 7449, 7464, + 7479, 7494, 7509, 7524, 7539, 7554, 7569, 7584, 7599, 7614, 7629, 7644, + 7659, 7674, 7689, 7704, 7719, 7734, 7749, 7764, 7779, 7794, 7809, 7824, + 7839, 7854, 7869, 7884, 7899, 7914, 7929, 7938, 7947, 7952, 7958, 7968, + 7972, 7976, 7981, 7986, 7991, 7999, 8003, 8006, 8010, 3215, 8013, 8018, + 353, 534, 8024, 8027, 8035, 8039, 8043, 8046, 8050, 8056, 8060, 8068, + 8074, 8079, 8086, 8094, 8101, 8107, 8112, 8119, 8125, 8134, 8142, 8146, + 8151, 8159, 8171, 8182, 8189, 8200, 8204, 8208, 8212, 8215, 8221, 3519, + 8225, 8227, 8233, 8238, 8243, 8248, 8254, 8259, 8264, 8269, 8274, 8280, + 8285, 8290, 8296, 8301, 8307, 8312, 8318, 8323, 8329, 8334, 8339, 8344, + 8349, 8354, 8360, 8365, 8370, 8375, 8381, 8387, 8393, 8399, 8405, 8411, + 8417, 8423, 8429, 8435, 8441, 8447, 8452, 8457, 8462, 8467, 8472, 8477, + 8482, 8487, 8493, 8499, 8504, 8510, 8516, 8522, 8528, 8533, 8538, 8543, + 8548, 8554, 8560, 8565, 8570, 8575, 8580, 8585, 8591, 8596, 8602, 8608, + 8614, 8620, 8626, 8632, 8638, 8644, 8650, 2203, 8045, 8655, 8659, 8667, + 8671, 8674, 8677, 8683, 8690, 1107, 8693, 8697, 8705, 8710, 8715, 8706, + 8720, 2230, 8724, 8730, 8736, 8741, 8746, 8753, 8761, 8766, 8770, 8773, + 8777, 8783, 8789, 8793, 1653, 631, 8796, 8800, 8805, 8811, 8816, 8820, + 8823, 8827, 8833, 8838, 8842, 8849, 8853, 8857, 8861, 773, 8681, 2254, + 8864, 8872, 8879, 8886, 8892, 8899, 8907, 8914, 8925, 8932, 8938, 8950, + 1123, 1288, 1293, 8961, 8965, 1298, 8969, 8973, 8982, 8990, 8994, 9003, + 9009, 9015, 9020, 9024, 9030, 9035, 9043, 9050, 2914, 9057, 9063, 9067, + 9076, 9085, 9094, 9103, 9109, 9114, 9119, 9130, 9139, 9151, 9156, 9164, + 2289, 9168, 9170, 9175, 9179, 9188, 9196, 1302, 168, 3810, 3815, 9202, + 9206, 9215, 9221, 9226, 9229, 9233, 9237, 9242, 9247, 9252, 9257, 9261, + 9270, 9276, 2301, 9280, 2906, 9284, 9292, 9296, 9300, 2305, 9304, 9308, + 9312, 9316, 9320, 2310, 9324, 9329, 9336, 9342, 9349, 9355, 9358, 9254, + 9360, 9368, 9376, 9384, 9387, 9392, 2323, 9397, 8717, 9400, 9402, 9407, + 9412, 9417, 9422, 9427, 9432, 9437, 9442, 9447, 9452, 9458, 9463, 9468, + 9473, 9479, 9484, 9489, 9494, 9499, 9504, 9509, 9515, 9520, 9525, 9530, + 9535, 9540, 9545, 9550, 9555, 9560, 9565, 9570, 9575, 9580, 9585, 9590, + 9595, 9600, 9606, 9612, 9617, 9622, 9627, 9632, 9637, 2334, 2341, 2347, + 9642, 9650, 9656, 9664, 2373, 2379, 9672, 2384, 2389, 2394, 2399, 9676, + 9680, 9685, 9689, 9693, 9697, 9702, 9706, 9711, 9715, 9718, 9721, 9727, + 9734, 9740, 9747, 9753, 9760, 9766, 9773, 9779, 9785, 9794, 9800, 9804, + 9808, 9812, 9816, 9821, 9825, 9830, 9834, 9840, 9844, 9849, 9856, 9867, + 9875, 9885, 9891, 9901, 9910, 9917, 9922, 9926, 9937, 9947, 9960, 9971, + 9984, 9995, 10007, 10019, 10031, 10042, 10055, 10068, 10075, 10081, + 10092, 10102, 10116, 10123, 10129, 10138, 10146, 10150, 10155, 10159, + 10166, 10174, 10181, 10185, 10191, 10195, 10201, 10211, 10215, 10220, + 10225, 10232, 10238, 8894, 10248, 10252, 10259, 10265, 10272, 10279, + 10283, 10286, 10292, 10296, 10301, 10306, 10311, 10315, 10321, 10329, + 10336, 10342, 10346, 10349, 10355, 10365, 10369, 10375, 10380, 10384, + 10389, 10393, 10399, 10405, 10410, 10416, 10421, 10426, 10431, 2226, + 10436, 10438, 10443, 10451, 10460, 10464, 10470, 10475, 10480, 10485, + 10490, 10496, 10501, 10506, 4600, 10511, 10516, 10520, 10526, 10531, + 10537, 10542, 10547, 10553, 10558, 10465, 10564, 10568, 10575, 10581, + 10586, 10590, 7073, 10595, 10604, 10609, 10614, 9332, 9339, 10619, 3088, + 10623, 10628, 10633, 10638, 10476, 10642, 10647, 10652, 10481, 10656, + 10486, 10661, 10668, 10675, 10681, 10688, 10694, 10700, 10705, 10712, + 10717, 10722, 10727, 10733, 10491, 10497, 10739, 10744, 10750, 10755, + 10760, 10768, 1358, 10773, 1048, 10776, 10784, 10800, 10816, 10831, + 10839, 10845, 10851, 10860, 10868, 10876, 10884, 10892, 10900, 10908, + 10916, 10924, 10933, 10942, 10950, 10959, 10968, 10977, 10986, 10995, + 11004, 11013, 11022, 11031, 11040, 11048, 11053, 11057, 11063, 11071, + 11078, 11093, 11110, 11129, 11138, 11146, 11161, 11172, 11180, 11186, + 11196, 11206, 11214, 11220, 11232, 11241, 11249, 11256, 11263, 11270, + 11276, 11281, 11291, 11297, 11305, 11315, 11322, 11332, 11342, 11352, + 11360, 11367, 11376, 11386, 11400, 11415, 11424, 11432, 11437, 11441, + 11451, 11461, 11473, 11482, 11488, 11493, 11503, 11513, 11523, 11528, + 11532, 11542, 11551, 11556, 11572, 11589, 11599, 11604, 11615, 11628, + 11639, 11647, 11660, 11672, 11680, 11685, 11689, 11695, 11700, 11708, + 11716, 11723, 11734, 11739, 11747, 11757, 11763, 11767, 11770, 11776, + 11780, 11786, 11793, 11797, 11805, 11814, 11822, 11829, 11834, 11838, + 11843, 11847, 11851, 11859, 11874, 11890, 11896, 11904, 11913, 11921, + 11927, 11931, 11938, 11949, 11953, 11956, 11967, 11973, 11978, 10507, + 11986, 11992, 11999, 12005, 12010, 12017, 12024, 12031, 12038, 12045, + 12052, 12059, 12066, 12073, 12080, 12087, 12094, 12101, 12108, 12115, + 12120, 11106, 12125, 12131, 12138, 12145, 12150, 12157, 12166, 12170, + 12177, 12189, 12193, 12199, 12204, 12209, 12214, 12219, 12224, 12229, + 12232, 12236, 11457, 12240, 12244, 12250, 12256, 12261, 12267, 12272, + 12277, 12283, 12288, 12293, 10228, 12298, 12302, 12306, 12310, 12315, + 12320, 12325, 12333, 12339, 12344, 12348, 12352, 12359, 12364, 12372, + 12379, 12384, 12388, 12391, 12397, 12404, 12408, 12411, 12416, 12420, + 4639, 12426, 12435, 46, 12443, 12449, 12454, 12459, 12467, 12474, 12479, + 6991, 12485, 12491, 12496, 12500, 12503, 12509, 12517, 12524, 12539, + 12558, 12570, 12583, 12596, 12609, 12623, 12636, 12651, 12658, 10512, + 12664, 12678, 12683, 12689, 12694, 12702, 12707, 9072, 12712, 12715, + 12723, 12730, 12735, 12739, 12745, 12749, 12754, 12759, 12764, 12769, + 12774, 12779, 3093, 11194, 12784, 12788, 12794, 12800, 12805, 12811, + 12816, 10521, 12822, 12828, 12833, 12838, 12846, 12852, 12865, 12873, + 12880, 12886, 10527, 12892, 12900, 12908, 12915, 12928, 12941, 12953, + 12963, 12975, 13003, 13011, 13020, 13027, 13039, 13046, 13056, 13065, + 13073, 13080, 13085, 13091, 10532, 13096, 13102, 13107, 13112, 13117, + 10538, 13122, 13125, 13132, 13138, 13152, 13165, 13176, 9860, 13187, + 13193, 13202, 13210, 13217, 13223, 13234, 13240, 13245, 13253, 4113, + 13259, 13264, 12531, 13270, 13277, 13282, 10543, 13288, 13293, 13300, + 13306, 13312, 13317, 13325, 13333, 13340, 13344, 13356, 13370, 13380, + 13385, 13389, 13400, 13406, 13411, 13416, 10548, 13420, 10554, 13425, + 13428, 13433, 13445, 13452, 13457, 13461, 13469, 13474, 13478, 13483, + 13487, 13494, 13500, 10559, 10466, 13507, 3098, 17, 13514, 13519, 13523, + 13527, 13533, 13541, 13551, 13556, 13561, 13568, 13575, 13579, 13590, + 13600, 13609, 13618, 13630, 13635, 13639, 13647, 13661, 13665, 13668, + 13672, 13680, 13687, 13695, 13699, 13710, 13718, 13722, 13729, 13734, + 13738, 13744, 13749, 13755, 13760, 13765, 13769, 13775, 13780, 13791, + 13795, 13798, 13804, 13811, 13817, 13822, 13828, 13834, 13841, 13852, + 13862, 13872, 13881, 13888, 13897, 13901, 10569, 10576, 10582, 10587, + 13907, 13913, 13919, 13924, 13930, 10591, 13936, 13939, 13946, 13951, + 13957, 13962, 13977, 13993, 14008, 14016, 14021, 14028, 14034, 14038, + 14043, 14048, 14053, 14058, 14063, 14068, 14073, 14078, 14083, 1561, 383, + 14088, 14096, 14103, 14109, 14114, 14119, 10596, 14121, 14125, 14130, + 14134, 14144, 14149, 14153, 14156, 14165, 14169, 14172, 14179, 10605, + 14184, 14187, 14195, 14202, 14210, 14214, 14220, 14228, 14232, 14239, + 14248, 14255, 14251, 14262, 14266, 14272, 14276, 14280, 14284, 14290, + 14296, 14306, 14314, 14321, 14325, 14333, 14338, 14342, 14349, 14354, + 14361, 14365, 14370, 14375, 14379, 14386, 14392, 14400, 14406, 14411, + 14421, 14428, 14433, 14438, 14442, 14446, 14454, 4469, 14462, 14467, + 10610, 14471, 14478, 14482, 14485, 14493, 14500, 14504, 14507, 6846, + 14511, 14516, 14521, 14525, 14536, 14546, 14551, 14557, 14562, 14571, + 14575, 14578, 14586, 14591, 14596, 14603, 14608, 4865, 10615, 14613, + 14617, 14624, 14629, 14634, 14639, 7021, 14644, 14649, 14654, 14659, + 14665, 14670, 14676, 14681, 14686, 14691, 14696, 14701, 14706, 14711, + 14716, 14721, 14726, 14731, 14736, 14741, 14746, 14751, 14756, 14762, + 14767, 14772, 14777, 14782, 14787, 14793, 14798, 14803, 14809, 14814, + 14820, 14825, 14831, 14836, 14841, 14846, 14851, 14857, 14862, 14867, + 14872, 14880, 988, 112, 14886, 14890, 14895, 14900, 14904, 14908, 14912, + 14917, 14921, 14926, 14930, 14933, 14937, 14941, 14947, 14952, 14962, + 14968, 14976, 14982, 14986, 14990, 14997, 15005, 15014, 15025, 15035, + 15042, 15049, 15053, 15062, 15071, 15079, 15086, 15095, 15104, 15113, + 15122, 15132, 15142, 15152, 15162, 15172, 15181, 15191, 15201, 15211, + 15221, 15231, 15241, 15251, 15260, 15270, 15280, 15290, 15300, 15310, + 15320, 15329, 15339, 15349, 15359, 15369, 15379, 15389, 15399, 15409, + 15419, 15428, 15438, 15448, 15458, 15468, 15478, 15488, 15498, 15508, + 15518, 15528, 15537, 15543, 1132, 15547, 15550, 15554, 15559, 15566, + 15572, 15577, 15581, 15586, 15595, 15604, 15612, 15617, 15621, 15625, + 15631, 15636, 15642, 10624, 15647, 15652, 15661, 15666, 10634, 15671, + 11444, 11454, 11464, 15674, 15680, 15688, 10639, 15695, 15699, 15703, + 15709, 15714, 15718, 15728, 15734, 15740, 15745, 15754, 15762, 15769, + 15776, 15781, 15788, 15793, 15797, 15800, 15811, 15821, 15834, 15843, + 15851, 15862, 15874, 15884, 15894, 15899, 15903, 15908, 15913, 15917, + 15923, 15931, 15938, 15949, 15954, 15964, 15973, 15977, 15980, 15987, + 15997, 16006, 16013, 16017, 16024, 16030, 16035, 16040, 16044, 15590, + 16053, 16057, 16063, 16067, 16072, 16076, 16083, 16090, 16094, 16103, + 16111, 16119, 16126, 16134, 16146, 16157, 16167, 16174, 16180, 16189, + 16200, 16209, 16221, 16233, 16245, 16255, 16264, 16274, 16283, 16291, + 16298, 16308, 16317, 16325, 16329, 16334, 16340, 16346, 16351, 16356, + 16360, 16365, 16370, 16375, 16380, 16385, 16390, 16395, 8738, 16400, + 16402, 16406, 16411, 16417, 16424, 16430, 16436, 16445, 16449, 16455, + 16463, 16470, 16479, 16488, 16497, 16506, 16515, 16524, 16533, 16542, + 16552, 16562, 16571, 16577, 16584, 16591, 16597, 16611, 16617, 16624, + 16632, 16641, 16649, 16655, 16664, 16670, 16679, 16690, 16696, 16706, + 16714, 16721, 16729, 16737, 16744, 16753, 16766, 16775, 16783, 16790, + 16803, 16809, 16815, 16825, 16834, 16843, 16852, 16860, 16865, 16869, + 16875, 16881, 16886, 16893, 16900, 10242, 16905, 16910, 16917, 16925, + 16930, 16942, 16949, 16954, 16966, 14943, 16971, 16977, 16985, 16991, + 16996, 17004, 17012, 17019, 17027, 17034, 17040, 17046, 17054, 17062, + 17068, 17076, 17082, 17087, 17093, 17100, 17106, 17111, 17115, 17126, + 17134, 17142, 17148, 17153, 17160, 17169, 17175, 17180, 17188, 17195, + 17204, 17218, 4413, 17222, 17227, 17232, 17238, 17243, 17248, 17252, + 17257, 17262, 17267, 8737, 17272, 17277, 17282, 17287, 17292, 17296, + 17301, 17306, 17311, 17316, 17322, 17328, 14216, 17333, 17339, 17344, + 17349, 17354, 10643, 17359, 17364, 17369, 17374, 17379, 17393, 17410, + 17428, 17440, 17453, 17470, 17486, 17503, 17513, 17532, 17543, 17554, + 17565, 2803, 17576, 17587, 17598, 17615, 17626, 17637, 17642, 10648, + 17647, 17651, 2483, 17655, 17661, 17664, 17670, 17678, 17686, 17692, + 17701, 17708, 17713, 17721, 17729, 17736, 17740, 17745, 17751, 17758, + 17766, 17773, 17785, 17792, 17798, 17806, 17811, 17817, 17823, 17828, + 13971, 17835, 17839, 17848, 17854, 17859, 17867, 17876, 17884, 17891, + 17897, 17905, 17912, 17918, 17924, 17931, 17938, 17944, 17950, 17954, + 17963, 17971, 17976, 17986, 17993, 17999, 18007, 18013, 18021, 18029, + 18036, 18049, 18053, 18060, 18069, 18078, 18087, 18095, 18105, 18112, + 18117, 3969, 18124, 18129, 1248, 18133, 18140, 17273, 18144, 18150, + 18154, 18162, 18174, 18179, 18186, 18192, 18197, 18204, 17278, 18208, + 18212, 18220, 18225, 18229, 17283, 18233, 17288, 18237, 18244, 18249, + 18253, 18260, 18264, 18267, 18275, 18282, 18287, 18295, 18299, 18306, + 18323, 18332, 18341, 18345, 18348, 18354, 18362, 18368, 18373, 18377, + 18382, 18387, 18392, 18397, 18402, 18407, 4047, 18412, 18414, 18422, + 18429, 18439, 18451, 18456, 18460, 18466, 18471, 18479, 18483, 18489, + 18494, 18500, 18503, 18510, 18518, 18525, 18531, 18536, 18542, 18547, + 18554, 18560, 18565, 18575, 18584, 18591, 18596, 18600, 18606, 18612, + 18616, 18623, 18629, 18634, 18640, 18648, 18656, 18663, 18669, 18675, + 18680, 18686, 18692, 18700, 18705, 18710, 18718, 18724, 18730, 18735, + 18742, 18747, 18751, 18757, 18763, 18768, 18774, 18781, 18786, 18792, + 18795, 18801, 18812, 18818, 18827, 18830, 18834, 18838, 18852, 18865, + 18877, 18883, 18888, 18895, 18901, 18907, 18918, 18930, 18942, 18952, + 18961, 18969, 18976, 18987, 18997, 19007, 19015, 19018, 17302, 19023, + 19028, 19035, 17307, 17458, 19043, 19056, 19071, 19082, 17475, 19100, + 19113, 19126, 19137, 12546, 19148, 19161, 19180, 19191, 19202, 19213, + 2824, 19226, 19230, 19238, 19249, 19260, 19268, 19283, 19298, 19309, + 19316, 19322, 19330, 19334, 19340, 19344, 19347, 19360, 19372, 19382, + 19390, 19397, 19405, 19415, 19420, 19427, 19432, 19439, 19450, 19460, + 19466, 19471, 19476, 17312, 19480, 19486, 19493, 19499, 19504, 19509, + 19514, 19518, 17317, 17323, 19522, 17329, 19527, 19535, 19540, 19544, + 19551, 19559, 19566, 19575, 19582, 19586, 19590, 19595, 19600, 19605, + 19610, 19615, 10487, 19620, 19622, 19627, 19632, 19638, 19643, 19648, + 19653, 19658, 19662, 19668, 19674, 19679, 19685, 19690, 19695, 19699, + 19705, 19710, 19714, 19719, 19724, 19736, 19741, 19747, 19752, 19757, + 19763, 19769, 19774, 19779, 19784, 19791, 19797, 19808, 19815, 19824, + 19829, 19833, 279, 19837, 19845, 19850, 19856, 19862, 19867, 19874, + 19881, 19887, 19892, 19898, 19903, 19908, 19913, 19920, 19930, 19938, + 19943, 19948, 19955, 19961, 19970, 19980, 19990, 20004, 20018, 20032, + 20046, 20061, 20076, 20093, 20111, 20124, 20130, 20135, 20140, 20144, + 20152, 20157, 20165, 20171, 20177, 20182, 20187, 20191, 20197, 20202, + 20206, 20213, 20218, 20222, 20233, 20239, 20244, 20249, 20256, 20261, + 20265, 3927, 20270, 20276, 20283, 17334, 20289, 20293, 20299, 20304, + 20309, 20313, 20319, 20324, 20329, 20336, 20341, 15730, 20345, 20350, + 20354, 20359, 20365, 20371, 20378, 20388, 20396, 20403, 20408, 20412, + 20421, 20429, 20436, 20443, 20449, 20454, 20460, 20465, 20470, 20476, + 20481, 20487, 20492, 20498, 20504, 20511, 20517, 20522, 20527, 10713, + 20536, 20539, 20547, 20553, 20558, 20563, 20573, 20580, 20586, 20591, + 20596, 20602, 20607, 20613, 20618, 20624, 20631, 20637, 20643, 20648, + 20656, 20663, 20668, 20673, 20679, 20684, 20688, 20697, 20708, 20715, + 20722, 20730, 20737, 20744, 20749, 20754, 20760, 20765, 20773, 20779, + 20785, 20790, 20797, 20803, 20808, 20812, 20818, 20823, 20828, 20832, + 20837, 1321, 8762, 3112, 20841, 20845, 20849, 20853, 20857, 20861, 20864, + 20869, 20876, 20884, 20894, 20905, 20915, 20926, 20938, 20949, 20959, + 20970, 20982, 20993, 21005, 21018, 21030, 21041, 21051, 21062, 21074, + 21085, 21098, 21110, 21121, 21133, 21146, 21158, 21171, 21185, 21198, + 21210, 21221, 21231, 21242, 21254, 21265, 21277, 21290, 21302, 21313, + 21325, 21338, 21351, 21365, 21378, 21390, 21401, 21413, 21426, 21438, + 21451, 21465, 21478, 21490, 21503, 21517, 21530, 21544, 21558, 21571, + 21583, 21594, 21604, 17345, 21611, 21617, 21627, 21635, 21642, 21650, + 21660, 21669, 21682, 21687, 21692, 21700, 21707, 15839, 15848, 21714, + 21724, 21739, 21745, 21752, 21759, 21766, 21772, 21778, 21789, 21797, + 21805, 21815, 21825, 21834, 17350, 21843, 21849, 21855, 21864, 21872, + 21880, 21885, 21894, 21902, 21914, 21924, 21934, 21944, 21953, 21965, + 21975, 21985, 21996, 22003, 22008, 22015, 22027, 22039, 22051, 22063, + 22075, 22087, 22099, 22111, 22123, 22135, 22146, 22158, 22170, 22182, + 22194, 22206, 22218, 22230, 22242, 22254, 22266, 22277, 22289, 22301, + 22313, 22325, 22337, 22349, 22361, 22373, 22385, 22397, 22408, 22420, + 22432, 22444, 22456, 22468, 22480, 22492, 22504, 22516, 22528, 22539, + 22551, 22563, 22575, 22587, 22599, 22611, 22623, 22635, 22647, 22659, + 22670, 22682, 22694, 22706, 22718, 22730, 22742, 22754, 22766, 22778, + 22790, 22801, 22813, 22825, 22837, 22849, 22861, 22873, 22885, 22897, + 22909, 22921, 22932, 22944, 22956, 22968, 22980, 22993, 23006, 23019, + 23032, 23045, 23058, 23071, 23083, 23096, 23109, 23122, 23135, 23148, + 23161, 23174, 23187, 23200, 23213, 23225, 23238, 23251, 23264, 23277, + 23290, 23303, 23316, 23329, 23342, 23355, 23367, 23380, 23393, 23406, + 23419, 23432, 23445, 23458, 23471, 23484, 23497, 23509, 23522, 23535, + 23548, 23561, 23574, 23587, 23600, 23613, 23626, 23639, 23651, 23664, + 23677, 23690, 23703, 23716, 23729, 23742, 23755, 23768, 23781, 23793, + 23804, 23817, 23830, 23843, 23856, 23869, 23882, 23895, 23908, 23921, + 23934, 23946, 23959, 23972, 23985, 23998, 24011, 24024, 24037, 24050, + 24063, 24076, 24088, 24101, 24114, 24127, 24140, 24153, 24166, 24179, + 24192, 24205, 24218, 24230, 24243, 24256, 24269, 24282, 24295, 24308, + 24321, 24334, 24347, 24360, 24372, 24385, 24398, 24411, 24424, 24437, + 24450, 24463, 24476, 24489, 24502, 24514, 24527, 24540, 24553, 24566, + 24579, 24592, 24605, 24618, 24631, 24644, 24656, 24669, 24682, 24695, + 24708, 24721, 24734, 24747, 24760, 24773, 24786, 24798, 24811, 24824, + 24837, 24850, 24863, 24876, 24889, 24902, 24915, 24928, 24940, 24953, + 24966, 24979, 24992, 25005, 25018, 25031, 25044, 25057, 25070, 25082, + 25095, 25108, 25121, 25134, 25147, 25160, 25173, 25186, 25199, 25212, + 25224, 25235, 25244, 25252, 25260, 25267, 25273, 25277, 25283, 25289, + 25298, 25306, 25311, 25317, 25322, 25326, 25335, 10492, 25346, 25352, + 25359, 25367, 25374, 13145, 13159, 25381, 25388, 25397, 25402, 25407, + 25414, 25419, 25424, 8778, 8784, 8790, 25429, 25434, 25437, 25442, 25450, + 25457, 25464, 25476, 25483, 25489, 25498, 25503, 25512, 25521, 25527, + 25535, 25544, 25548, 25554, 25559, 25569, 25576, 25582, 25590, 25596, + 25603, 25609, 25619, 25628, 25632, 25639, 25643, 25648, 25654, 25662, + 25666, 25676, 17360, 25685, 25691, 25695, 25704, 25713, 25723, 25729, + 17365, 25736, 25743, 25754, 25762, 25772, 25781, 25789, 10207, 25797, + 25802, 25808, 25813, 25817, 25821, 25825, 11301, 25830, 25838, 25845, + 25854, 25862, 25869, 25876, 25885, 25891, 1062, 25898, 25904, 25908, + 25914, 25921, 25927, 25935, 25941, 25948, 25954, 25960, 25969, 25973, + 25981, 25989, 25996, 26005, 26012, 26017, 26021, 26031, 26042, 26053, + 26058, 26063, 26069, 26078, 26083, 26096, 9000, 26100, 26106, 26112, + 26118, 26123, 26131, 26135, 26142, 26151, 26156, 17638, 26164, 26168, + 26180, 26185, 26189, 26192, 26198, 26204, 26210, 26215, 26220, 26224, + 26227, 26238, 26243, 10769, 26250, 26255, 26260, 26265, 26270, 26275, + 26280, 26285, 26290, 10774, 26295, 26300, 26305, 26310, 26315, 26320, + 26325, 26330, 26335, 26340, 26345, 26350, 26356, 26361, 26366, 26371, + 26376, 26381, 26386, 26391, 26396, 26401, 26407, 26413, 26418, 26423, + 26428, 26433, 26438, 26443, 26448, 26453, 26458, 26464, 26469, 26474, + 26479, 26485, 26491, 26496, 26501, 26506, 26511, 26516, 26521, 26526, + 26531, 26537, 26542, 26547, 26552, 26557, 26563, 26568, 26573, 26577, + 1244, 145, 26585, 26589, 26593, 26597, 26602, 26606, 15736, 2409, 26610, + 26615, 26619, 26624, 26628, 26633, 26637, 26643, 26648, 26652, 26656, + 26664, 26668, 26672, 26679, 26684, 26689, 26693, 26699, 26704, 26708, + 26713, 26718, 26722, 26729, 26736, 26743, 26748, 26752, 26756, 26761, + 26765, 26768, 26774, 26787, 26792, 26798, 26807, 26812, 11049, 26817, + 26826, 26831, 26834, 26838, 26843, 26848, 26853, 26858, 26863, 2920, + 2925, 26868, 26874, 26878, 26884, 3888, 26889, 26894, 26899, 26905, + 26910, 16686, 26915, 26920, 26925, 26930, 26936, 26941, 26946, 26952, + 26957, 26961, 26966, 26971, 26976, 26981, 26986, 26990, 26995, 26999, + 27004, 27009, 27014, 27019, 27023, 27028, 27032, 27037, 27042, 27047, + 26962, 3121, 26967, 27052, 27060, 27067, 11395, 27079, 27087, 27097, + 27115, 27134, 27143, 27151, 26972, 27158, 27163, 27171, 26977, 27176, + 27181, 27189, 27194, 27199, 27203, 19858, 27208, 27216, 27221, 27225, + 27232, 27238, 27247, 27251, 27259, 27265, 27269, 27272, 20692, 27279, + 27283, 27287, 27292, 27298, 27305, 27310, 10234, 27314, 27319, 27324, + 27329, 27334, 27339, 1663, 1668, 27344, 27350, 27356, 27361, 27365, + 27369, 27373, 27377, 27381, 27385, 27389, 27393, 25470, 27396, 27403, + 27411, 27417, 27423, 27428, 27433, 27439, 27443, 27448, 27455, 16586, + 16593, 27461, 27473, 27476, 27483, 27487, 19883, 27494, 27502, 27513, + 27522, 27535, 27545, 27559, 27571, 27585, 27598, 27610, 27620, 27632, + 27638, 27653, 27677, 27695, 27714, 27727, 27741, 27759, 27775, 27792, + 27810, 27821, 27840, 27857, 27877, 27895, 27907, 27921, 27935, 27947, + 27964, 27983, 28001, 28013, 28031, 28050, 17518, 28063, 28083, 28095, + 12577, 28107, 28112, 28117, 28122, 28131, 28137, 28142, 28146, 28153, + 28159, 28163, 28168, 28173, 28178, 28183, 28188, 28193, 2506, 28198, + 28204, 28208, 28211, 28222, 28226, 28229, 28237, 28243, 14882, 28247, + 28256, 28267, 28273, 28279, 28294, 28303, 28311, 28318, 28323, 28327, + 28334, 28340, 28349, 28357, 28364, 28374, 28383, 28393, 28398, 28407, + 28416, 28427, 28438, 28448, 28465, 4557, 28475, 28479, 28489, 28497, + 28507, 28518, 28524, 28529, 28539, 28547, 28554, 28560, 28567, 28572, + 27010, 28576, 28585, 28589, 28592, 28597, 28605, 28612, 28621, 28629, + 28637, 28645, 28655, 28664, 28670, 28676, 28682, 28686, 27015, 27020, + 28690, 28700, 28710, 28720, 28728, 28735, 28745, 28753, 28761, 28767, + 28775, 798, 28784, 17725, 649, 28798, 28807, 28815, 28826, 28837, 28847, + 28856, 28868, 28877, 28886, 28893, 28899, 28909, 28918, 28927, 28935, + 28943, 28953, 28961, 28969, 28976, 28982, 28987, 28992, 28997, 8156, + 29002, 29005, 29009, 29014, 29022, 29028, 29033, 29037, 3751, 27033, + 29045, 27038, 29051, 29057, 29063, 29068, 29073, 29077, 29085, 29091, + 29097, 29101, 3912, 29109, 29114, 29119, 29123, 29127, 11681, 29134, + 29142, 29156, 29163, 29170, 29176, 11690, 11696, 29184, 29192, 29199, + 29204, 29209, 27043, 29215, 29226, 29235, 19031, 29243, 29248, 2755, + 29253, 29264, 29270, 29275, 29279, 29283, 29286, 29293, 29300, 29306, + 29314, 29321, 29327, 29331, 8196, 29336, 29340, 29344, 29352, 29357, + 29362, 29367, 1696, 29372, 29377, 29382, 29387, 29392, 29397, 29402, + 29407, 29412, 29417, 29422, 29427, 29432, 29437, 29443, 29448, 29453, + 29458, 29463, 29468, 29473, 29479, 29484, 29489, 29494, 29499, 29504, + 29509, 29514, 29520, 29526, 29531, 29537, 29542, 29547, 5, 29553, 29557, + 29561, 29565, 29570, 29574, 29578, 29582, 29586, 29591, 29595, 29600, + 29604, 29607, 29611, 29616, 29620, 29625, 29629, 29633, 29637, 29642, + 29646, 29650, 29660, 29665, 29669, 29673, 29678, 29683, 29692, 29697, + 29702, 29706, 29710, 29719, 29732, 29744, 29753, 29762, 29767, 29773, + 29778, 29782, 29786, 29796, 29805, 29813, 29819, 29824, 29828, 29835, + 29842, 29852, 29861, 29869, 12934, 29877, 29884, 29892, 29901, 29910, + 29918, 29928, 29933, 29937, 29941, 29944, 29946, 29950, 29954, 29959, + 29964, 29968, 29972, 29975, 29979, 29982, 29986, 29989, 29992, 29996, + 30002, 30006, 30010, 30014, 30018, 30023, 30028, 30033, 30037, 30040, + 30045, 30051, 30056, 30062, 30067, 30071, 30077, 30081, 30085, 30090, + 30094, 30099, 30104, 30108, 30112, 30119, 30123, 30126, 30130, 30134, + 30140, 30145, 30151, 30155, 30159, 30164, 30171, 30177, 30181, 30190, + 30194, 30198, 30201, 30207, 30212, 30218, 1385, 1748, 30223, 30228, + 30233, 30238, 30243, 30248, 30253, 2213, 827, 30258, 30261, 30265, 30269, + 30274, 30278, 17737, 30282, 30287, 30292, 30296, 30299, 30304, 30308, + 30313, 30317, 17741, 30322, 30325, 30328, 30334, 30338, 30343, 30347, + 30360, 30368, 30372, 30375, 30383, 30392, 30399, 30404, 30410, 30416, + 30424, 30431, 30438, 30442, 30446, 30450, 30455, 30460, 30464, 30472, + 30477, 30484, 30496, 30507, 30512, 30516, 30523, 30527, 30532, 30538, + 30541, 30546, 30551, 30558, 30562, 30566, 30569, 30575, 8900, 2413, + 30579, 30584, 30600, 11100, 30620, 30629, 30645, 30649, 30656, 30659, + 30665, 30675, 30681, 30690, 30699, 30714, 30725, 30737, 30748, 30756, + 30765, 30771, 30780, 30790, 30800, 30811, 30822, 30832, 30841, 30848, + 30857, 30865, 30872, 30879, 30886, 30894, 30901, 30908, 30921, 30928, + 30936, 30943, 30949, 30954, 30963, 30970, 30976, 30981, 30989, 30997, + 31004, 31011, 28499, 31023, 31035, 31049, 31057, 31065, 31073, 31080, + 31092, 31101, 31110, 31118, 31126, 31134, 31141, 31147, 31156, 31164, + 31174, 31183, 31193, 31202, 31211, 31219, 31224, 31228, 31231, 31235, + 31239, 31243, 31247, 31251, 31257, 31263, 31268, 31276, 31283, 31291, + 31298, 10806, 17799, 31306, 31313, 31318, 31325, 31331, 31337, 31344, + 14024, 31351, 31354, 31366, 31374, 31380, 31385, 31389, 31400, 31410, + 31420, 11620, 31429, 31438, 31446, 31456, 31465, 31472, 31479, 31487, + 31491, 17818, 31494, 31501, 31505, 4501, 31511, 31514, 31521, 31527, + 31541, 31546, 31554, 31560, 31571, 31578, 31584, 31590, 31594, 31599, + 31603, 31612, 31619, 31625, 8953, 31632, 31640, 31647, 31653, 31658, + 31664, 31670, 31680, 31692, 31703, 31713, 11252, 31721, 31727, 17836, + 31731, 31733, 31236, 11633, 31742, 31747, 31753, 31763, 31768, 31775, + 31783, 31789, 31794, 31799, 31804, 31808, 31813, 31820, 31826, 31835, + 31843, 31847, 31854, 31864, 31870, 31879, 31885, 31892, 4771, 31898, + 31904, 31909, 31916, 31928, 31939, 31944, 31952, 31956, 31966, 31972, + 31976, 31981, 31991, 32000, 32004, 32011, 32019, 32026, 32032, 32037, + 32045, 32052, 32057, 32064, 32076, 32085, 32089, 32097, 15656, 32101, + 32111, 32115, 32123, 32130, 32137, 30379, 32148, 32153, 32157, 32164, + 32171, 26695, 31161, 32176, 32180, 32183, 27827, 32188, 32202, 32218, + 32236, 32255, 32272, 32290, 27846, 32307, 32327, 27863, 32339, 32351, + 19087, 32363, 27883, 32377, 32389, 12590, 32403, 32408, 32413, 32418, + 32424, 32430, 32436, 32440, 32448, 32454, 32461, 32466, 32476, 32483, + 32489, 12128, 32495, 32497, 32502, 32510, 32514, 31816, 32520, 32527, + 13866, 13876, 32534, 32541, 32551, 32556, 32560, 32563, 32569, 32577, + 32589, 32599, 32615, 32628, 32642, 19105, 32656, 32663, 32667, 32670, + 32675, 32679, 32686, 32693, 32700, 32707, 32717, 32722, 32727, 32732, + 32740, 32748, 32753, 32762, 28520, 3561, 32767, 32770, 32773, 32778, + 32785, 32790, 32795, 32811, 32819, 32827, 10864, 32835, 32840, 32844, + 32850, 32855, 32861, 32864, 32870, 32882, 32890, 32897, 32903, 32910, + 32921, 32935, 32948, 32954, 32963, 32969, 32978, 32990, 33001, 33011, + 33020, 33029, 33037, 33047, 33056, 33067, 673, 33074, 33081, 33087, + 33092, 33098, 33105, 33111, 33122, 33132, 33142, 33151, 33157, 33164, + 33169, 33177, 33184, 33192, 33200, 33212, 7142, 33219, 33222, 33231, + 33239, 33245, 33251, 33256, 33260, 33263, 33269, 33276, 33281, 33286, + 33293, 33298, 33302, 33314, 33325, 33334, 33342, 18008, 33347, 33355, + 33360, 33368, 33374, 33380, 33385, 13859, 9802, 33388, 33392, 33396, + 33399, 33402, 33408, 33416, 33424, 33428, 33432, 33437, 33441, 33444, + 33453, 33458, 33463, 33467, 33470, 33475, 33483, 33494, 33503, 33507, + 33513, 33519, 33523, 33529, 33537, 33559, 33583, 33594, 33603, 33609, + 33616, 33623, 33629, 33637, 33643, 33648, 33659, 33677, 33684, 33692, + 33696, 33703, 33708, 33717, 33730, 33738, 33750, 33761, 33772, 33782, + 33796, 33805, 33813, 33825, 33836, 11117, 33845, 33856, 33867, 33879, + 33889, 33898, 33908, 33913, 33917, 33925, 33936, 33946, 33952, 33957, + 33961, 33964, 33967, 33975, 33983, 33992, 34002, 34011, 34017, 34022, + 34036, 2838, 34058, 34069, 34078, 34088, 34100, 34109, 34118, 34128, + 34136, 34144, 34153, 34158, 34169, 34174, 34183, 34189, 34200, 34204, + 34207, 34217, 34226, 34234, 34244, 34254, 34262, 34271, 34278, 34284, + 34292, 34299, 34308, 34317, 34322, 34327, 34331, 34339, 34346, 34352, + 34356, 34364, 34371, 34382, 34397, 34404, 34410, 34420, 34429, 34435, + 34446, 34450, 34457, 34461, 34468, 34474, 16838, 34480, 34484, 34489, + 34495, 34502, 34506, 34510, 34518, 34526, 34532, 34541, 34548, 34555, + 34560, 34565, 34575, 28574, 34579, 34582, 34587, 34592, 34597, 34602, + 34607, 34612, 34617, 34622, 34628, 34633, 34638, 34644, 1094, 770, 34649, + 34652, 34659, 34668, 1777, 34675, 34680, 34684, 34690, 1143, 643, 34695, + 347, 34699, 34709, 34718, 34726, 34735, 34743, 34750, 34761, 34769, + 34778, 34786, 34796, 34804, 34809, 11794, 34813, 34821, 34829, 34834, + 17754, 4101, 34840, 34846, 34852, 6669, 34857, 34861, 34868, 34874, + 34880, 34884, 34893, 34899, 34904, 34911, 1336, 34917, 34923, 34928, + 34935, 34939, 1243, 6677, 34944, 34954, 34962, 34968, 34978, 34987, + 34995, 35001, 35006, 35014, 35021, 13376, 35027, 35034, 35039, 35045, + 35052, 35062, 1404, 253, 2212, 35068, 35074, 35081, 35092, 35103, 35111, + 35118, 35128, 35137, 35145, 35154, 35161, 35168, 35181, 35188, 35194, + 35205, 35224, 35229, 1148, 35233, 35238, 35246, 3984, 35250, 35255, + 35259, 35263, 1340, 29973, 35273, 35277, 35282, 35286, 35292, 3846, + 35298, 35306, 35313, 35324, 35333, 35341, 35366, 35374, 35379, 3985, 401, + 35385, 35393, 35401, 35408, 35413, 35419, 35424, 2281, 12792, 35431, + 35437, 31595, 31934, 35443, 656, 106, 35447, 35451, 35457, 595, 10679, + 35462, 35467, 35474, 35480, 35484, 35488, 1549, 35491, 35495, 18296, + 35498, 35503, 35510, 35516, 8966, 35521, 35529, 35536, 35542, 27205, + 35546, 35550, 35554, 35558, 1834, 20204, 35562, 35567, 35571, 35574, + 35582, 35590, 35595, 35604, 35612, 35615, 35622, 35629, 35641, 27284, + 35651, 35663, 35671, 35676, 35680, 35688, 35695, 35702, 35711, 35717, + 35724, 35731, 35734, 35738, 35742, 1351, 35752, 35754, 35759, 35765, + 35771, 35776, 35781, 35786, 35791, 35796, 35801, 35806, 35811, 35816, + 35821, 35826, 35831, 35836, 35841, 35847, 35853, 35859, 35865, 35870, + 35875, 35880, 35886, 35891, 35896, 35901, 35907, 35912, 35918, 35923, + 35928, 35933, 35938, 35944, 35949, 35955, 35960, 35965, 35970, 35975, + 35981, 35986, 35992, 35997, 36002, 36007, 36012, 36017, 36022, 36027, + 36032, 36037, 36043, 36049, 36055, 36060, 36065, 36070, 36075, 36081, + 36087, 36093, 36099, 36105, 36111, 36116, 36122, 36127, 36132, 36137, + 36142, 36148, 2552, 36153, 2559, 2566, 2962, 36158, 2572, 2582, 36164, + 2614, 2619, 2624, 36168, 36173, 36178, 36184, 36189, 36194, 36198, 36203, + 36209, 36214, 36219, 36224, 36230, 36235, 36239, 36243, 36248, 36253, + 36258, 36263, 36268, 36274, 36280, 36285, 36289, 36294, 36300, 36304, + 36309, 36314, 36319, 36324, 36328, 36331, 36336, 36341, 36346, 36351, + 36356, 36362, 36368, 36373, 36378, 36383, 36387, 36392, 36397, 36402, + 36407, 36412, 36417, 36421, 36426, 36431, 36436, 36440, 36444, 36448, + 36453, 36461, 36466, 36471, 36477, 36483, 36489, 36494, 36502, 36506, + 36509, 36514, 36519, 36523, 36528, 36533, 36537, 36542, 36546, 36549, + 36554, 4211, 21695, 36559, 36564, 36569, 36574, 36582, 25865, 34932, + 10318, 36587, 36592, 36596, 36601, 36605, 36609, 36614, 36618, 36621, + 36624, 36628, 36633, 36637, 36645, 36649, 36652, 36657, 36661, 36665, + 36670, 36675, 36679, 36685, 36690, 36695, 36702, 36709, 36713, 36716, + 36722, 36731, 36738, 36746, 36753, 36757, 36762, 36766, 36770, 36776, + 36781, 36787, 36791, 36797, 36802, 36807, 36811, 36818, 36824, 36830, + 36836, 36842, 36849, 36855, 36861, 36867, 36873, 36879, 36885, 36891, + 36898, 36904, 36911, 36917, 36923, 36929, 36935, 36941, 36947, 36953, + 36959, 36965, 36971, 36976, 36981, 13731, 36986, 36992, 36997, 37002, + 37007, 37012, 37015, 37021, 37026, 37034, 37039, 37043, 37048, 37054, + 37063, 37069, 37074, 37079, 37084, 37088, 37093, 37097, 37102, 37107, + 37112, 37117, 37124, 37131, 37137, 37143, 37148, 19801, 37155, 37161, + 37168, 37174, 37180, 37185, 37193, 37198, 11288, 37202, 37207, 37212, + 37218, 37223, 37228, 37232, 37237, 37242, 37248, 37253, 37258, 37263, + 37267, 37272, 37277, 37281, 37286, 37291, 37295, 37300, 37304, 37309, + 37314, 37319, 37323, 37328, 37332, 37337, 37341, 37348, 37352, 37356, + 18452, 37361, 37368, 37377, 37383, 37389, 37398, 37406, 37415, 37423, + 37428, 37432, 37439, 37445, 37453, 37457, 37460, 37465, 37469, 37478, + 37486, 37504, 37510, 1403, 37516, 37519, 37523, 27351, 27357, 37529, + 37533, 37544, 37555, 37566, 37578, 37582, 37589, 37596, 37603, 37608, + 37612, 37620, 37625, 37630, 37635, 37640, 6734, 16742, 25864, 37645, + 37650, 37654, 16733, 37659, 37665, 37670, 37676, 37681, 37687, 37692, + 37698, 37703, 37709, 37715, 37721, 37726, 37682, 37688, 37730, 37735, + 37741, 37746, 37752, 37757, 37763, 37768, 37693, 12422, 37772, 37704, + 37710, 37716, 3054, 3760, 37778, 37781, 37786, 37792, 37798, 37804, + 37811, 37817, 37823, 37829, 37835, 37841, 37847, 37853, 37859, 37865, + 37871, 37877, 37883, 37890, 37896, 37902, 37908, 37914, 37920, 37923, + 37928, 37931, 37938, 37943, 37951, 37955, 37960, 37965, 37971, 37976, + 37981, 37985, 37990, 37996, 38001, 38007, 38012, 38018, 38023, 38029, + 38035, 38039, 38044, 38049, 38054, 38059, 38063, 38068, 38073, 38078, + 38084, 38090, 38096, 38102, 38107, 38111, 38114, 38120, 38126, 38135, + 38143, 38150, 38155, 38159, 38163, 38168, 18239, 38173, 38181, 38187, + 4152, 1253, 38192, 38197, 38201, 9016, 38207, 38213, 38220, 9025, 38224, + 38230, 38236, 38243, 38249, 38258, 38266, 38278, 38287, 38291, 38298, + 38304, 38309, 38313, 38317, 38320, 38330, 38339, 38347, 37683, 38352, + 38362, 38372, 38382, 38388, 38393, 38403, 38408, 38421, 38435, 38446, + 38458, 38470, 38484, 38497, 38509, 38521, 17559, 38535, 38540, 38545, + 38549, 38553, 38557, 38561, 38567, 38572, 38577, 38582, 38587, 38592, + 38597, 1737, 32999, 38602, 38607, 38612, 37731, 38617, 38620, 38625, + 38630, 38635, 38641, 38647, 19411, 11994, 38652, 38658, 38665, 19039, + 38671, 38676, 38681, 38685, 38690, 38695, 37736, 38700, 38705, 38710, + 38716, 37742, 38721, 38724, 38731, 38739, 38745, 38751, 38757, 38768, + 38773, 38780, 38787, 38794, 38802, 38811, 38820, 38826, 38832, 38840, + 37747, 38845, 38851, 38857, 37753, 38862, 38867, 38875, 38883, 38889, + 38896, 38902, 38909, 38916, 38922, 38930, 38940, 38947, 38953, 38958, + 38964, 38969, 38974, 38981, 38990, 38998, 39003, 39009, 39016, 39024, + 39030, 39035, 39041, 39050, 39057, 33997, 39063, 39067, 39072, 39081, + 39086, 39091, 39096, 14972, 39104, 39109, 39114, 39119, 39123, 39128, + 39133, 39140, 39145, 39150, 39155, 37758, 25793, 39161, 2655, 158, 39164, + 39167, 39171, 39175, 39185, 39193, 39200, 39204, 39208, 39211, 39219, + 39226, 39233, 31888, 39242, 39245, 39252, 39258, 39263, 39267, 39274, + 39278, 39286, 39294, 39301, 39316, 39320, 39324, 39327, 39333, 39340, + 39344, 39350, 39354, 39361, 39369, 39377, 39384, 37694, 39391, 39399, + 39404, 39416, 12075, 12082, 12089, 12096, 12103, 12110, 626, 434, 39422, + 39427, 39432, 39438, 39443, 39448, 4178, 39453, 39456, 39461, 39466, + 39471, 39476, 39481, 39488, 27469, 39493, 39498, 39503, 39508, 39513, + 39519, 39524, 39530, 37934, 39536, 39541, 39547, 39553, 39563, 39568, + 39573, 39577, 39582, 39587, 39592, 39597, 39610, 39615, 27083, 20286, + 1064, 39619, 39625, 39629, 39634, 39639, 39645, 39650, 39655, 39659, + 39664, 39669, 39675, 39680, 39685, 1258, 39689, 39694, 39699, 39704, + 39708, 39713, 39718, 39723, 39729, 39735, 39740, 39744, 39748, 39753, + 39758, 39763, 39767, 39772, 39780, 39784, 39790, 39794, 39801, 39810, + 20057, 37705, 39816, 39823, 39831, 39839, 39846, 39852, 39861, 39874, + 39886, 39891, 39897, 39901, 2981, 39905, 39909, 39335, 39918, 39929, + 39940, 39945, 34065, 39950, 39955, 39959, 34185, 27362, 39964, 39971, + 39975, 39980, 37711, 25900, 39984, 39989, 39995, 40000, 40004, 40008, + 40011, 40015, 40021, 40030, 40041, 40053, 37717, 40058, 40061, 40065, + 40069, 40074, 40079, 40084, 40089, 40094, 40099, 40104, 40109, 373, + 40114, 40119, 40124, 40129, 40134, 40139, 40145, 40150, 40155, 40161, + 40166, 40172, 40177, 40183, 40188, 40193, 40198, 40203, 40208, 40213, + 40218, 40223, 40229, 40234, 40239, 40244, 40249, 40254, 40259, 40264, + 40270, 40276, 40281, 40286, 40291, 40296, 40301, 40306, 40311, 40316, + 40321, 40326, 40331, 40336, 40341, 40346, 40351, 40356, 40361, 40366, + 40376, 40386, 40392, 342, 14, 40397, 40400, 40404, 40408, 40416, 40420, + 40424, 31568, 16975, 1818, 40427, 40432, 40436, 40441, 40445, 40450, + 40454, 40459, 40463, 40466, 40468, 40472, 40477, 40481, 40492, 40495, + 40497, 40501, 40513, 40525, 40534, 40538, 40548, 40552, 40558, 40563, + 40572, 40578, 40583, 40588, 40592, 40596, 40601, 40608, 40613, 40619, + 40624, 40628, 40635, 31169, 31179, 40639, 40644, 40649, 40654, 40661, + 40665, 40672, 40679, 40685, 9171, 40689, 40698, 40706, 40721, 40735, + 40744, 40752, 40763, 40772, 40777, 40784, 40794, 8165, 40804, 40809, + 40815, 40820, 40824, 40827, 40832, 40836, 40841, 40845, 40852, 40857, + 40862, 40867, 40877, 40882, 40887, 40892, 10188, 40897, 40899, 40907, + 40910, 40913, 40921, 40936, 40944, 40954, 40956, 40959, 40963, 40969, + 40973, 40978, 40983, 41001, 41015, 41034, 41051, 41060, 41068, 41073, + 41078, 1396, 41084, 41090, 41095, 41105, 41114, 41122, 41127, 41133, + 41138, 41147, 41156, 41167, 41172, 41179, 41185, 41189, 41198, 41205, + 41213, 41220, 41233, 41241, 41245, 41255, 41261, 41266, 41270, 41278, + 41286, 41291, 41295, 41299, 41308, 41314, 41319, 41327, 41337, 41346, + 41355, 41364, 41375, 41383, 41394, 41403, 41411, 41418, 41424, 41429, + 41440, 41451, 41456, 41460, 41463, 41467, 41477, 41485, 41491, 41502, + 41513, 41524, 41535, 41546, 41557, 41568, 41579, 41591, 41603, 41615, + 41627, 41639, 41651, 41663, 41672, 41676, 41684, 41690, 41696, 41703, + 41709, 41714, 41720, 41724, 41729, 41734, 41739, 40371, 40381, 2526, + 41744, 41746, 41751, 41756, 41761, 41764, 41766, 41770, 41773, 41780, + 41784, 11644, 41788, 41794, 41801, 41807, 41817, 41822, 41828, 41832, + 41837, 41850, 31758, 41856, 41862, 41871, 41880, 21918, 41887, 41896, + 41904, 38368, 41910, 41915, 41919, 41928, 41936, 41943, 41948, 41952, + 41957, 41962, 41970, 41974, 41982, 41988, 41994, 41999, 42004, 42008, + 42011, 42016, 42029, 42045, 27953, 42062, 42074, 42091, 42103, 42117, + 27970, 27989, 42129, 42141, 2855, 42155, 42160, 42165, 42170, 42174, + 42181, 42193, 42200, 42209, 42219, 42222, 42233, 42244, 42252, 42257, + 42261, 42266, 42271, 42276, 42281, 42286, 42291, 1768, 947, 42296, 42300, + 42304, 42307, 42312, 42317, 42323, 42328, 42333, 42339, 42345, 42350, + 42354, 42359, 42364, 42369, 42373, 42376, 42382, 42387, 42392, 42397, + 42401, 42406, 42412, 42420, 32069, 42425, 42430, 42437, 42443, 42449, + 42454, 42462, 27478, 42469, 42474, 42479, 42484, 42488, 42491, 42496, + 42500, 42504, 42511, 42517, 42523, 42529, 42536, 42541, 42547, 41281, + 42551, 42555, 42560, 42573, 42578, 42584, 42592, 42599, 42607, 42617, + 42623, 42629, 42635, 42639, 42648, 42656, 42663, 42668, 42673, 12445, + 42678, 42688, 42695, 42701, 42711, 42716, 42722, 42730, 4017, 42737, + 42744, 42750, 42757, 4023, 42761, 42766, 42777, 42784, 42790, 42799, + 42803, 42806, 4609, 42813, 42820, 42826, 42832, 42840, 42850, 35414, + 42857, 42865, 42871, 42876, 42882, 42887, 42891, 31517, 42897, 42904, + 42910, 42918, 42927, 42934, 42940, 42951, 28772, 42957, 42964, 42970, + 42980, 42985, 42989, 42997, 43005, 43012, 43018, 43023, 11246, 941, + 43028, 43032, 43034, 43038, 43043, 43046, 43048, 43053, 43059, 43064, + 43069, 43076, 39484, 43082, 43087, 43091, 43096, 43100, 43109, 43113, + 43119, 43126, 43132, 43139, 43144, 43153, 43158, 43162, 43167, 43174, + 43182, 43190, 43195, 25956, 43199, 43202, 43206, 43210, 12889, 1005, + 43214, 43219, 43227, 43232, 43236, 43245, 43252, 43256, 43260, 43268, + 43275, 16260, 43285, 43289, 43293, 43301, 43309, 43315, 43320, 43324, + 43333, 16008, 43339, 43348, 43355, 43360, 43367, 43374, 43382, 43389, + 43397, 43405, 43414, 43419, 43426, 43433, 43440, 43447, 43454, 43459, + 43466, 43472, 43489, 43497, 43507, 43515, 43522, 43530, 461, 43534, + 43540, 43544, 43549, 40768, 43555, 43558, 43562, 43568, 43579, 43587, + 4028, 43595, 43601, 43607, 43617, 43623, 43632, 43641, 43651, 43658, + 43664, 43669, 4034, 4040, 43678, 43686, 43693, 43697, 14356, 43705, + 43709, 43716, 43724, 43731, 43740, 43747, 43753, 43762, 43772, 43778, + 43786, 43795, 43802, 43810, 43817, 26758, 43821, 43828, 43834, 43844, + 43853, 43861, 43872, 43876, 43886, 43893, 43898, 43903, 43909, 43916, + 43924, 43933, 43942, 43952, 43963, 43970, 43975, 43982, 3269, 43990, + 43996, 44001, 44008, 44014, 44020, 44025, 44038, 44051, 44064, 44071, + 44077, 44085, 44093, 44098, 44102, 44106, 44111, 44116, 44121, 44126, + 44131, 44136, 1365, 44141, 44145, 44149, 44153, 44157, 44161, 44165, + 44169, 44173, 44177, 44181, 44185, 44189, 44193, 44197, 44201, 44205, + 44209, 44213, 44217, 44221, 44225, 44229, 44233, 44237, 44241, 44245, + 44249, 44253, 44257, 44261, 44265, 44269, 44273, 44277, 44281, 44285, + 44289, 44293, 44297, 44301, 44305, 44309, 44313, 44317, 44321, 44325, + 44329, 44333, 44337, 44341, 44345, 44349, 44353, 44357, 44361, 44365, + 44369, 44373, 44377, 44381, 44385, 44389, 44393, 44397, 44401, 44405, + 44409, 44413, 44417, 44421, 44425, 44429, 44433, 44437, 44441, 44445, + 44449, 44453, 44457, 44461, 44465, 44469, 44473, 44477, 44481, 44485, + 44489, 44493, 44497, 44501, 44505, 44509, 44513, 44517, 44521, 44525, + 44529, 44533, 44537, 44541, 44545, 44549, 44553, 44557, 44561, 44565, + 44569, 44573, 44577, 44581, 44585, 44589, 44593, 44597, 44601, 44605, + 44609, 44613, 44617, 44621, 44625, 44629, 44633, 44637, 44641, 44645, + 44649, 44653, 44657, 44661, 44665, 44669, 44673, 44677, 44681, 44685, + 44689, 44693, 44697, 44701, 44705, 44709, 44713, 44717, 44721, 44725, + 44729, 44733, 44737, 44741, 44745, 44749, 44753, 44758, 44762, 44767, + 44771, 44776, 44780, 44785, 44789, 44795, 44800, 44804, 44809, 44813, + 44818, 44822, 44827, 44831, 44836, 44840, 44845, 44849, 44854, 44858, + 44864, 44870, 44875, 44879, 44884, 44888, 44894, 44899, 44903, 44908, + 44912, 44917, 44921, 44927, 44932, 44936, 44941, 44945, 44950, 44954, + 44959, 44963, 44969, 44974, 44978, 44983, 44987, 44993, 44998, 45002, + 45007, 45011, 45016, 45020, 45025, 45029, 45034, 45038, 45044, 45049, + 45053, 45059, 45064, 45068, 45074, 45079, 45083, 45088, 45092, 45097, + 45101, 45107, 45113, 45119, 45125, 45131, 45137, 45143, 45149, 45154, + 45158, 45163, 45167, 45173, 45178, 45182, 45187, 45191, 45196, 45200, + 45205, 45209, 45214, 45218, 45223, 45227, 45232, 45236, 45242, 45247, + 45251, 45256, 45260, 45266, 45272, 45277, 127, 63, 45281, 45283, 45287, + 45291, 45295, 45300, 45304, 45308, 45313, 11153, 45318, 45324, 1677, + 7181, 45330, 45333, 45338, 45342, 45347, 45351, 45355, 45360, 12233, + 45364, 45368, 45372, 630, 45376, 18561, 45381, 45385, 45390, 45395, + 45400, 45404, 45411, 45417, 45423, 31790, 45428, 45431, 45435, 45440, + 45446, 45450, 45453, 45461, 45467, 45472, 45476, 45479, 45483, 45489, + 45493, 45497, 3811, 3816, 15084, 45500, 45504, 45508, 45512, 45516, + 45524, 45531, 45535, 15958, 45542, 45556, 45563, 45574, 361, 45579, + 45583, 45589, 45601, 45607, 45613, 45618, 45624, 18613, 45628, 45632, + 35727, 45641, 45647, 45656, 45660, 45664, 45669, 45675, 45680, 45684, + 45689, 45693, 45697, 45704, 45710, 45715, 45726, 45741, 45756, 45771, + 45787, 45805, 12140, 45819, 45826, 45832, 45836, 45839, 45848, 45853, + 45857, 45865, 19242, 45873, 45877, 45887, 45898, 35617, 1042, 45911, + 45920, 45938, 45957, 45966, 45974, 45982, 1690, 12342, 45986, 27374, + 45989, 31556, 45994, 11478, 45999, 46005, 46010, 46016, 46021, 46027, + 46032, 46038, 46043, 46049, 46055, 46061, 46066, 46022, 46028, 46070, + 46033, 46039, 46044, 46075, 46050, 46056, 9184, 4434, 46081, 46089, + 46093, 46096, 46103, 46107, 46112, 46117, 46124, 46130, 46136, 46141, + 17850, 46145, 31573, 46149, 46153, 46157, 46164, 46170, 46174, 33931, + 46183, 10351, 46187, 10780, 46190, 46197, 46203, 46207, 14381, 46214, + 46220, 46225, 46232, 46239, 46246, 34730, 9081, 46253, 46260, 46267, + 46273, 46278, 46285, 46296, 46302, 46307, 46312, 46317, 46321, 46326, + 46333, 46023, 46337, 46347, 46356, 46367, 46373, 46381, 46388, 46393, + 46398, 46403, 46408, 46413, 46417, 46421, 46428, 46434, 46442, 2416, + 30582, 12245, 12257, 12262, 12268, 46451, 12273, 12278, 12284, 46456, + 46466, 46470, 12289, 46475, 20484, 46478, 46483, 46487, 46491, 46502, + 46510, 42204, 46518, 46523, 46530, 46537, 46541, 46544, 46552, 12153, + 46559, 46562, 46568, 46578, 6767, 46587, 46592, 46598, 46602, 46610, + 46614, 46624, 46630, 46635, 46646, 46655, 46664, 46673, 46682, 46691, + 46700, 46709, 46715, 46721, 46726, 46732, 46738, 46744, 46749, 46752, + 46759, 46765, 46769, 46774, 46781, 46788, 46792, 46795, 46805, 46818, + 46827, 46836, 46847, 46860, 46872, 46883, 46892, 46903, 46908, 46917, + 46922, 12294, 46928, 46935, 46943, 46950, 46955, 46960, 31836, 46964, + 46971, 4374, 25, 46975, 46980, 20333, 46984, 46987, 46990, 34122, 46994, + 34739, 47002, 47006, 47010, 47013, 47019, 47025, 47030, 37782, 47039, + 47047, 47053, 47060, 34105, 47064, 34342, 47068, 47077, 47081, 47089, + 47095, 47101, 47106, 47110, 34765, 47116, 47119, 47127, 47135, 47143, + 4772, 47149, 47153, 47157, 47162, 47169, 47175, 47180, 47185, 47189, + 47195, 47200, 47206, 4662, 820, 47213, 47217, 47220, 47232, 47239, 47244, + 18434, 47248, 47256, 47264, 47272, 47280, 47287, 47295, 47303, 47310, + 47318, 47326, 47334, 47342, 47350, 47358, 47366, 47374, 47382, 47390, + 47398, 47405, 47413, 47421, 47429, 47437, 47445, 47453, 47461, 47469, + 47477, 47485, 47493, 47501, 47509, 47517, 47525, 47533, 47541, 47549, + 47557, 47564, 47572, 47579, 47587, 47595, 47603, 47611, 47619, 47627, + 47635, 47643, 47654, 26794, 47659, 47662, 47669, 47673, 47679, 47683, + 47689, 47694, 47700, 47705, 47710, 47714, 47718, 47725, 47733, 47738, + 47743, 47753, 47759, 47772, 47778, 47784, 47790, 47793, 47800, 47805, + 4700, 47811, 4869, 965, 47816, 47819, 47822, 47825, 37866, 37872, 47828, + 37878, 37891, 37897, 37903, 47834, 37909, 37915, 47840, 47846, 10, 47854, + 47861, 47865, 47869, 47877, 38726, 47881, 47885, 47892, 47897, 47901, + 47906, 47912, 47917, 47923, 47928, 47932, 47936, 47940, 47945, 47949, + 47954, 47958, 47962, 47969, 47974, 47978, 47982, 47987, 47991, 47996, + 48000, 48004, 48009, 48015, 18743, 18748, 48020, 48024, 48027, 48033, + 48037, 48041, 25750, 48046, 48050, 48056, 48063, 48069, 48074, 40797, + 48084, 48089, 48097, 48101, 48104, 48108, 38741, 48116, 4738, 48121, + 48126, 48130, 48135, 48139, 48144, 16026, 48155, 48159, 48162, 48166, + 48174, 48179, 48183, 48188, 48193, 48197, 48201, 48205, 48208, 48212, + 48215, 48220, 48225, 48230, 48235, 48240, 48245, 8664, 16042, 48250, + 48253, 48259, 48264, 48270, 48275, 48281, 48286, 48292, 48297, 48303, + 48309, 48315, 48320, 48324, 48328, 48339, 48347, 48354, 48360, 48365, + 48376, 48386, 48392, 48397, 48404, 48413, 48429, 48445, 48455, 34007, + 48462, 48466, 48471, 48476, 48480, 48484, 43937, 48490, 48495, 48499, + 48506, 48511, 48516, 48520, 48523, 48527, 48533, 32802, 48537, 26108, + 48542, 48549, 48557, 48563, 48569, 48576, 48584, 48590, 48594, 48599, + 48605, 48613, 48618, 48622, 48631, 11134, 48639, 48643, 48651, 48658, + 48663, 48668, 48673, 48677, 48680, 48686, 48690, 48693, 48697, 48704, + 48709, 48716, 48720, 48726, 48730, 48736, 48741, 48746, 5107, 5114, + 48751, 48760, 48768, 48773, 48779, 48791, 48804, 48818, 48825, 48831, + 48837, 48842, 48850, 48853, 48855, 48866, 48878, 48889, 48904, 48921, + 48941, 48963, 48970, 48977, 48984, 48990, 48994, 8663, 48997, 49001, + 49005, 49010, 49014, 49018, 49021, 49025, 49039, 28019, 49058, 49071, + 49084, 49097, 28037, 49112, 2808, 49127, 49133, 49137, 49147, 49151, + 49155, 49160, 49164, 49171, 49176, 49180, 49187, 49193, 49198, 49204, + 49214, 49226, 49237, 49242, 49249, 49253, 49257, 49260, 49268, 19263, + 4141, 49273, 18782, 49286, 49293, 49300, 49306, 49310, 49314, 49319, + 49325, 49330, 49336, 49340, 49344, 49347, 49352, 49356, 49361, 49366, + 49371, 49376, 49381, 49386, 49391, 49396, 49401, 8727, 18793, 49406, + 49410, 49416, 49425, 49430, 49439, 49446, 43768, 49452, 49457, 49461, + 49468, 49473, 49480, 49488, 49494, 49498, 49501, 49505, 49510, 2886, + 49517, 49524, 49528, 49531, 49536, 49541, 49547, 49552, 49557, 49561, + 49566, 49576, 49581, 49587, 49592, 49599, 47234, 49605, 49611, 49619, + 49629, 49634, 49639, 49643, 49648, 49653, 8167, 8179, 49658, 49661, + 49668, 49674, 49683, 10268, 41421, 49691, 49695, 49699, 38789, 49707, + 49718, 49726, 43985, 49733, 49738, 49743, 49754, 49761, 49772, 38813, + 26125, 49780, 4652, 49785, 16459, 49791, 34096, 49797, 49802, 49812, + 49821, 49828, 49834, 49838, 49841, 49848, 49854, 49861, 49867, 49877, + 49885, 49891, 49897, 49902, 49906, 49913, 49918, 49924, 49931, 49937, + 49006, 49942, 49946, 16501, 16510, 16519, 16528, 16537, 16566, 622, + 16575, 49952, 49957, 49960, 49966, 49974, 1275, 49979, 49983, 49988, + 49993, 49997, 50002, 50009, 50015, 50019, 50024, 50030, 50034, 37939, + 50039, 50044, 50053, 50060, 50070, 50076, 34140, 50093, 50102, 50110, + 50116, 50121, 50128, 50134, 50142, 50151, 50159, 50167, 50173, 50177, + 50182, 50190, 35288, 38822, 50196, 50215, 19166, 50229, 50245, 50259, + 50265, 50270, 50275, 50280, 50286, 38828, 50291, 50294, 50301, 50308, + 50317, 50322, 50326, 423, 3176, 50333, 50338, 50343, 33196, 50131, 50347, + 50355, 50360, 50368, 50372, 50375, 50380, 50386, 50392, 50397, 50401, + 34213, 50404, 50409, 50413, 50416, 50421, 50425, 50430, 50435, 50439, + 50444, 50448, 50455, 50459, 50463, 25746, 25757, 50468, 50473, 50479, + 50484, 50490, 50496, 32758, 50501, 50505, 50508, 50514, 50519, 50524, + 50529, 50534, 50539, 50544, 50549, 50554, 50560, 50566, 14569, 19473, + 50571, 50576, 50581, 50586, 50591, 50596, 50601, 50606, 452, 68, 37956, + 37961, 37966, 37972, 37977, 37982, 50611, 37986, 50615, 50619, 50623, + 37991, 37997, 50637, 38008, 38013, 50645, 50650, 38019, 50655, 50660, + 50669, 50674, 50679, 50688, 50694, 50700, 50706, 38036, 50719, 50728, + 50734, 38040, 50738, 38045, 50743, 38050, 38055, 50746, 50751, 50755, + 50761, 16267, 50768, 16277, 50775, 50780, 38060, 50784, 50789, 50794, + 50799, 50804, 50808, 50813, 50818, 50824, 50829, 50834, 50840, 50846, + 50851, 50855, 50860, 50865, 50870, 50874, 50879, 50884, 50889, 50895, + 50901, 50907, 50912, 50916, 50921, 50925, 38064, 38069, 38074, 50929, + 50933, 50938, 50942, 50954, 38079, 38085, 38091, 38103, 50960, 31616, + 50964, 50969, 50973, 50978, 50985, 50990, 50995, 51000, 51004, 51008, + 51018, 51023, 51028, 51032, 51042, 51046, 51049, 51057, 51062, 38151, + 51066, 1375, 51072, 51077, 51083, 51091, 51095, 51104, 51112, 51116, + 51120, 51128, 51134, 51142, 51158, 51163, 51167, 51171, 51175, 51180, + 51186, 51201, 38188, 1685, 14601, 51205, 1254, 1269, 51217, 51225, 51232, + 51237, 9230, 51244, 51249, 10765, 978, 2641, 12321, 51256, 10658, 51261, + 51264, 51273, 1162, 51278, 49177, 51285, 51294, 51299, 51303, 51311, + 51318, 27424, 2697, 51326, 12842, 51336, 51342, 2434, 2444, 51351, 51360, + 51370, 51381, 3584, 41818, 51386, 4341, 4352, 9258, 1167, 51390, 51398, + 51405, 51410, 51414, 51418, 51423, 29054, 49512, 12412, 51431, 51440, + 51449, 51457, 51470, 51477, 51488, 51493, 51506, 51519, 51531, 51543, + 51555, 51566, 51579, 51590, 51601, 51611, 51619, 51627, 51639, 51651, + 51662, 51671, 51679, 51686, 51698, 51705, 51711, 51720, 51726, 51733, + 51746, 51751, 51761, 51766, 51772, 51777, 32098, 51781, 48682, 51788, + 51795, 51803, 51810, 2654, 51817, 51828, 51838, 51847, 51855, 51865, + 51873, 51882, 51892, 51901, 51906, 51912, 51918, 4190, 51929, 51939, + 51948, 51957, 51965, 51975, 51983, 51992, 51997, 52002, 52007, 1604, 47, + 52015, 52023, 52034, 52045, 19877, 52055, 52059, 52066, 52072, 52077, + 52081, 52092, 52102, 52111, 52122, 52127, 20306, 20311, 52134, 52143, + 52148, 52158, 52163, 52171, 52179, 52186, 52192, 1566, 271, 52196, 52201, + 52207, 46085, 52212, 52215, 2182, 2663, 52223, 52227, 52230, 1420, 52236, + 16787, 1172, 52241, 52254, 2797, 2818, 52268, 52280, 52292, 2832, 2849, + 2864, 2880, 2897, 52306, 52318, 2912, 52332, 1178, 1184, 1190, 12713, + 52337, 52342, 52347, 52351, 52366, 52381, 52396, 52411, 52426, 52441, + 52456, 52471, 52486, 52501, 52516, 52531, 52546, 52561, 52576, 52591, + 52606, 52621, 52636, 52651, 52666, 52681, 52696, 52711, 52726, 52741, + 52756, 52771, 52786, 52801, 52816, 52831, 52846, 52861, 52876, 52891, + 52906, 52921, 52936, 52951, 52966, 52981, 52996, 53011, 53026, 53041, + 53056, 53071, 53086, 53101, 53116, 53131, 53146, 53161, 53176, 53191, + 53206, 53221, 53236, 53251, 53266, 53281, 53296, 53311, 53326, 53341, + 53356, 53371, 53386, 53401, 53416, 53431, 53446, 53461, 53476, 53491, + 53506, 53521, 53536, 53551, 53566, 53581, 53596, 53611, 53626, 53641, + 53656, 53671, 53686, 53701, 53716, 53731, 53746, 53761, 53776, 53791, + 53806, 53821, 53836, 53851, 53866, 53881, 53896, 53911, 53926, 53941, + 53956, 53971, 53986, 54001, 54016, 54031, 54046, 54061, 54076, 54091, + 54106, 54121, 54136, 54151, 54166, 54181, 54196, 54211, 54226, 54241, + 54256, 54271, 54286, 54301, 54316, 54331, 54346, 54361, 54376, 54391, + 54406, 54421, 54436, 54451, 54466, 54481, 54496, 54511, 54526, 54541, + 54556, 54571, 54586, 54601, 54616, 54631, 54646, 54661, 54676, 54691, + 54706, 54721, 54736, 54751, 54766, 54781, 54796, 54811, 54826, 54841, + 54856, 54871, 54886, 54901, 54916, 54931, 54946, 54961, 54976, 54991, + 55006, 55021, 55036, 55051, 55066, 55081, 55096, 55111, 55126, 55141, + 55156, 55171, 55186, 55201, 55216, 55231, 55246, 55261, 55276, 55291, + 55306, 55321, 55336, 55351, 55366, 55381, 55396, 55411, 55426, 55441, + 55456, 55471, 55486, 55501, 55516, 55531, 55546, 55561, 55576, 55591, + 55606, 55621, 55636, 55651, 55666, 55681, 55696, 55711, 55726, 55741, + 55756, 55771, 55786, 55801, 55816, 55831, 55846, 55861, 55876, 55891, + 55906, 55921, 55936, 55951, 55966, 55981, 55996, 56011, 56026, 56041, + 56056, 56071, 56086, 56101, 56116, 56131, 56146, 56161, 56176, 56191, + 56206, 56221, 56236, 56251, 56266, 56281, 56296, 56311, 56326, 56341, + 56356, 56371, 56386, 56401, 56416, 56431, 56446, 56461, 56476, 56491, + 56506, 56521, 56536, 56551, 56566, 56581, 56596, 56611, 56626, 56641, + 56656, 56671, 56686, 56701, 56716, 56731, 56746, 56761, 56776, 56791, + 56806, 56821, 56836, 56851, 56866, 56881, 56896, 56911, 56926, 56941, + 56956, 56971, 56986, 57001, 57016, 57031, 57046, 57061, 57076, 57091, + 57106, 57121, 57136, 57151, 57166, 57181, 57196, 57211, 57226, 57241, + 57256, 57271, 57286, 57301, 57316, 57331, 57346, 57361, 57376, 57391, + 57406, 57421, 57436, 57451, 57466, 57481, 57496, 57511, 57526, 57541, + 57556, 57571, 57586, 57601, 57616, 57631, 57646, 57661, 57676, 57691, + 57706, 57721, 57736, 57751, 57766, 57781, 57796, 57811, 57826, 57841, + 57856, 57871, 57886, 57901, 57916, 57931, 57946, 57961, 57976, 57991, + 58006, 58021, 58036, 58051, 58066, 58081, 58096, 58111, 58126, 58141, + 58156, 58171, 58186, 58201, 58216, 58231, 58246, 58261, 58276, 58291, + 58306, 58321, 58336, 58351, 58366, 58381, 58396, 58411, 58426, 58441, + 58456, 58471, 58486, 58501, 58516, 58531, 58546, 58561, 58576, 58591, + 58606, 58621, 58636, 58651, 58666, 58681, 58696, 58711, 58726, 58741, + 58756, 58771, 58786, 58801, 58816, 58831, 58846, 58861, 58876, 58891, + 58906, 58921, 58936, 58951, 58966, 58981, 58996, 59011, 59026, 59041, + 59056, 59071, 59086, 59101, 59116, 59131, 59146, 59161, 59176, 59191, + 59206, 59221, 59236, 59251, 59266, 59281, 59296, 59311, 59326, 59341, + 59356, 59371, 59386, 59401, 59416, 59431, 59446, 59461, 59476, 59491, + 59506, 59521, 59536, 59551, 59566, 59581, 59596, 59611, 59626, 59641, + 59656, 59671, 59686, 59701, 59716, 59731, 59746, 59761, 59776, 59791, + 59806, 59821, 59836, 59851, 59866, 59881, 59896, 59911, 59926, 59941, + 59956, 59971, 59986, 60001, 60016, 60031, 60046, 60061, 60076, 60091, + 60106, 60121, 60136, 60151, 60166, 60182, 60198, 60214, 60230, 60246, + 60262, 60278, 60294, 60310, 60326, 60342, 60358, 60374, 60390, 60406, + 60422, 60438, 60454, 60470, 60486, 60502, 60518, 60534, 60550, 60566, + 60582, 60598, 60614, 60630, 60646, 60662, 60678, 60694, 60710, 60726, + 60742, 60758, 60774, 60790, 60806, 60822, 60838, 60854, 60870, 60886, + 60902, 60918, 60934, 60950, 60966, 60982, 60998, 61014, 61030, 61046, + 61062, 61078, 61094, 61110, 61126, 61142, 61158, 61174, 61190, 61206, + 61222, 61238, 61254, 61270, 61286, 61302, 61318, 61334, 61350, 61366, + 61382, 61398, 61414, 61430, 61446, 61462, 61478, 61494, 61510, 61526, + 61542, 61558, 61574, 61590, 61606, 61622, 61638, 61654, 61670, 61686, + 61702, 61718, 61734, 61750, 61766, 61782, 61798, 61814, 61830, 61846, + 61862, 61878, 61894, 61910, 61926, 61942, 61958, 61974, 61990, 62006, + 62022, 62038, 62054, 62070, 62086, 62102, 62118, 62134, 62150, 62166, + 62182, 62198, 62214, 62230, 62246, 62262, 62278, 62294, 62310, 62326, + 62342, 62358, 62374, 62390, 62406, 62422, 62438, 62454, 62470, 62486, + 62502, 62518, 62534, 62550, 62566, 62582, 62598, 62614, 62630, 62646, + 62662, 62678, 62694, 62710, 62726, 62742, 62758, 62774, 62790, 62806, + 62822, 62838, 62854, 62870, 62886, 62902, 62918, 62934, 62950, 62966, + 62982, 62998, 63014, 63030, 63046, 63062, 63078, 63094, 63110, 63126, + 63142, 63158, 63174, 63190, 63206, 63222, 63238, 63254, 63270, 63286, + 63302, 63318, 63334, 63350, 63366, 63382, 63398, 63414, 63430, 63446, + 63462, 63478, 63494, 63510, 63526, 63542, 63558, 63574, 63590, 63606, + 63622, 63638, 63654, 63670, 63686, 63702, 63718, 63734, 63750, 63766, + 63782, 63798, 63814, 63830, 63846, 63862, 63878, 63894, 63910, 63926, + 63942, 63958, 63974, 63990, 64006, 64022, 64038, 64054, 64070, 64086, + 64102, 64118, 64134, 64150, 64166, 64182, 64198, 64214, 64230, 64246, + 64262, 64278, 64294, 64310, 64326, 64342, 64358, 64374, 64390, 64406, + 64422, 64438, 64454, 64470, 64486, 64502, 64518, 64534, 64550, 64566, + 64582, 64598, 64614, 64630, 64646, 64662, 64678, 64694, 64710, 64726, + 64742, 64758, 64774, 64790, 64806, 64822, 64838, 64854, 64870, 64886, + 64902, 64918, 64934, 64950, 64966, 64982, 64998, 65014, 65030, 65046, + 65062, 65078, 65094, 65110, 65126, 65142, 65158, 65174, 65190, 65206, + 65222, 65238, 65254, 65270, 65286, 65302, 65318, 65334, 65350, 65366, + 65382, 65398, 65414, 65430, 65446, 65462, 65478, 65494, 65510, 65526, + 65542, 65558, 65574, 65590, 65606, 65622, 65638, 65654, 65670, 65686, + 65702, 65718, 65734, 65750, 65766, 65782, 65798, 65814, 65830, 65846, + 65862, 65878, 65894, 65910, 65926, 65942, 65958, 65974, 65990, 66006, + 66022, 66038, 66054, 66070, 66086, 66102, 66118, 66134, 66150, 66166, + 66182, 66198, 66214, 66230, 66246, 66262, 66278, 66294, 66310, 66326, + 66342, 66358, 66374, 66390, 66406, 66422, 66438, 66454, 66470, 66486, + 66502, 66518, 66534, 66550, 66566, 66582, 66598, 66614, 66630, 66646, + 66662, 66678, 66694, 66710, 66726, 66742, 66758, 66774, 66790, 66806, + 66822, 66838, 66854, 66870, 66886, 66902, 66918, 66934, 66950, 66966, + 66982, 66998, 67014, 67030, 67046, 67062, 67078, 67094, 67110, 67126, + 67142, 67158, 67174, 67190, 67206, 67222, 67238, 67254, 67270, 67286, + 67302, 67318, 67334, 67350, 67366, 67382, 67398, 67414, 67430, 67446, + 67462, 67478, 67494, 67510, 67526, 67542, 67558, 67574, 67590, 67606, + 67622, 67638, 67654, 67670, 67686, 67702, 67718, 67734, 67750, 67766, + 67782, 67798, 67814, 67830, 67846, 67862, 67878, 67894, 67910, 67926, + 67942, 67958, 67974, 67990, 68006, 68022, 68038, 68054, 68070, 68086, + 68102, 68118, 68134, 68150, 68166, 68182, 68198, 68214, 68230, 68246, + 68262, 68278, 68294, 68310, 68326, 68342, 68358, 68374, 68390, 68406, + 68422, 68438, 68454, 68470, 68486, 68502, 68518, 68534, 68550, 68566, + 68582, 68598, 68614, 68630, 68646, 68662, 68678, 68694, 68710, 68726, + 68742, 68758, 68774, 68790, 68806, 68822, 68838, 68847, 68862, 68876, + 68885, 17689, 68889, 68894, 68900, 68906, 68916, 68924, 17946, 18677, + 9277, 68937, 1428, 1432, 68945, 4270, 33321, 8104, 68951, 68956, 68961, + 68966, 68971, 68977, 68982, 68988, 68993, 68999, 69004, 69009, 69014, + 69019, 69025, 69030, 69035, 69040, 69045, 69050, 69055, 69060, 69066, + 69071, 69077, 69084, 2701, 69089, 69095, 9652, 69099, 69104, 69111, + 69119, 4281, 4286, 4291, 4296, 65, 69123, 69129, 69134, 69139, 69143, + 69148, 69152, 69156, 12785, 69160, 69170, 69183, 69194, 69207, 69214, + 69220, 69228, 69235, 12246, 69244, 69249, 69255, 69261, 69267, 69272, + 69277, 69282, 69287, 69291, 69296, 69301, 69306, 69312, 69318, 69324, + 69329, 69333, 69338, 69343, 69347, 69352, 69357, 69362, 69366, 12801, + 12812, 12817, 1471, 69370, 69376, 1476, 19711, 69381, 19720, 1486, 69386, + 69392, 69397, 1507, 69403, 1513, 1519, 12847, 69408, 69417, 69425, 69433, + 69440, 69444, 69448, 69454, 69459, 37599, 69464, 69471, 69479, 69486, + 69491, 69495, 69499, 69508, 69513, 69518, 69523, 1524, 280, 69528, 69533, + 69537, 19846, 987, 69541, 69548, 69553, 69557, 19904, 1528, 46361, 69560, + 69565, 69575, 69584, 69589, 69593, 69599, 1533, 49458, 69604, 69613, + 69619, 69624, 69629, 13086, 13092, 69635, 69648, 69660, 69677, 69694, + 69711, 69728, 69745, 69762, 69779, 69796, 69813, 69830, 69847, 69864, + 69881, 69898, 69915, 69932, 69949, 69966, 69983, 70000, 70017, 70034, + 70051, 70068, 70085, 70102, 70119, 70136, 70153, 70170, 70187, 70204, + 70221, 70238, 70255, 70272, 70289, 70306, 70323, 70340, 70357, 70374, + 70391, 70408, 70425, 70442, 70459, 70476, 70493, 70504, 70514, 70519, + 1538, 70523, 70528, 70534, 70539, 70544, 70551, 10677, 1543, 70557, + 70566, 33713, 70571, 70582, 13108, 70592, 70597, 70603, 70608, 70615, + 70621, 70626, 1548, 20198, 70631, 70637, 13118, 70643, 70648, 70653, + 70658, 70663, 70668, 70673, 70678, 1553, 4761, 70683, 70688, 70694, + 70699, 70704, 70709, 70714, 70719, 70724, 70729, 70734, 70740, 70746, + 70752, 70757, 70761, 70766, 70771, 70775, 70780, 70785, 70790, 70795, + 70799, 70804, 70810, 70815, 70820, 70824, 70829, 70834, 70840, 70845, + 70850, 70856, 70862, 70867, 70871, 70876, 70881, 70886, 70890, 70895, + 70900, 70905, 70911, 70917, 70922, 70926, 70930, 70935, 70940, 70945, + 35492, 70949, 70954, 70959, 70965, 70970, 70975, 70979, 70984, 70989, + 70995, 71000, 71005, 71011, 71017, 71022, 71026, 71031, 71036, 71040, + 71045, 71050, 71055, 71061, 71067, 71072, 71076, 71081, 71086, 71090, + 71095, 71100, 71105, 71110, 71114, 71117, 71120, 71125, 71130, 38335, + 71137, 71145, 50085, 71151, 3928, 33656, 71164, 71171, 71177, 71183, + 4107, 71188, 13260, 71194, 71204, 71219, 71227, 13265, 71238, 71243, + 71254, 71266, 71278, 71290, 2903, 71302, 71307, 31699, 71319, 71325, + 71331, 71336, 71345, 71352, 71357, 71362, 71367, 71372, 71377, 71382, + 1570, 19338, 71387, 71392, 71397, 71402, 71408, 71413, 71419, 71424, + 71429, 71435, 71440, 71445, 49532, 71449, 71453, 71458, 71462, 20346, + 71467, 71470, 71475, 71483, 71491, 1574, 13301, 13307, 1579, 71499, + 71506, 71511, 71520, 71530, 71537, 71542, 71547, 1584, 71554, 71559, + 20466, 71563, 71568, 71575, 71581, 71585, 71598, 71604, 71615, 71625, + 71632, 20488, 10571, 10578, 4355, 4361, 71639, 1589, 71644, 71653, 71659, + 71667, 71674, 71680, 71687, 71699, 71705, 71710, 71717, 71729, 71740, + 71750, 71759, 71769, 71779, 4249, 71787, 37393, 37402, 20528, 71800, + 71805, 71810, 71815, 71820, 71825, 71830, 1594, 1598, 71835, 71839, + 71842, 71853, 71858, 20554, 1608, 71866, 71871, 71876, 71888, 20587, + 71895, 71898, 71904, 71910, 71915, 71923, 1613, 71928, 71933, 71941, + 71949, 71956, 71965, 71973, 71982, 71986, 1618, 71995, 1623, 25931, + 72000, 72007, 72013, 20674, 72021, 72031, 72037, 72042, 72050, 72057, + 72066, 72074, 72084, 72093, 72103, 72112, 72123, 72133, 72143, 72152, + 72162, 72176, 72189, 72198, 72206, 72216, 72225, 72237, 72248, 72259, + 72269, 19966, 72274, 13453, 72283, 72289, 72294, 72301, 72307, 72314, + 72320, 19555, 72330, 72336, 72341, 72352, 72359, 72366, 72371, 72379, + 13470, 13475, 72387, 72393, 72397, 4339, 4350, 20750, 49635, 72405, + 72411, 72416, 72424, 72431, 14582, 72436, 72442, 72448, 1634, 72453, + 72456, 72462, 72467, 72472, 72477, 72482, 72487, 72492, 72497, 72502, + 72508, 72514, 1333, 72519, 72524, 72529, 72535, 72540, 72545, 72550, + 72555, 72560, 72565, 1643, 18, 72571, 72575, 72580, 72584, 72588, 72592, + 38621, 72597, 28238, 72602, 72607, 72611, 72614, 72618, 72622, 72627, + 72631, 72636, 72640, 72643, 72649, 42308, 42313, 42318, 72652, 72659, + 72665, 72673, 49230, 72683, 72689, 42324, 38885, 38636, 38642, 42340, + 38648, 72694, 72699, 72703, 38918, 72710, 72713, 72717, 72725, 72732, + 72737, 72740, 72745, 72750, 72754, 72758, 72761, 72771, 72783, 72790, + 72796, 38653, 72803, 40604, 72806, 9669, 13815, 72809, 72813, 72818, + 4159, 72822, 72825, 16320, 72832, 72839, 72852, 72867, 72881, 72897, + 72912, 72921, 72929, 72937, 72946, 72950, 72959, 72965, 72970, 72980, + 72993, 73005, 73012, 73017, 73026, 73039, 44032, 73057, 73062, 73069, + 73075, 73080, 895, 73085, 73093, 73100, 73107, 33137, 914, 73113, 73119, + 73124, 73134, 73142, 73148, 73153, 38672, 6858, 38686, 73157, 73167, + 73172, 73180, 73190, 73205, 73211, 73217, 73224, 38696, 73229, 73235, + 37737, 73239, 73243, 73248, 73257, 73264, 73269, 73273, 73278, 73286, + 20531, 73293, 73298, 73302, 6899, 38722, 73306, 73312, 341, 73322, 73329, + 73336, 73342, 73349, 73354, 73363, 15941, 69569, 69579, 73369, 73377, + 73381, 73385, 73389, 73393, 73398, 73402, 73408, 73416, 73421, 73426, + 73433, 73438, 73442, 73447, 73451, 73455, 73461, 73467, 73478, 73484, + 73489, 73493, 73498, 73502, 38846, 73506, 38852, 38858, 73511, 73517, + 73524, 73529, 73533, 37754, 20185, 73536, 73540, 73545, 73552, 73558, + 73562, 73567, 48699, 73573, 73577, 73584, 73588, 73593, 73599, 73605, + 73611, 73623, 73632, 73642, 73648, 73655, 73660, 73665, 73669, 73672, + 73678, 73685, 73690, 73695, 73702, 73709, 73716, 73722, 73727, 73732, + 73740, 38863, 2531, 73745, 73750, 73756, 73761, 73767, 73772, 73777, + 73782, 73788, 38884, 73793, 73799, 73805, 73811, 38954, 73816, 73821, + 73826, 38965, 73831, 73836, 73841, 73847, 73853, 38970, 73858, 73863, + 73868, 39025, 39031, 73873, 73878, 39036, 39058, 33998, 39064, 39068, + 73883, 14258, 73887, 73895, 73901, 73909, 73916, 73922, 73932, 73938, + 73945, 12685, 39082, 73951, 73964, 73973, 73979, 73988, 73994, 74000, + 74007, 28581, 74015, 74022, 74032, 74040, 74043, 39026, 74048, 74055, + 74060, 74064, 74068, 74073, 74077, 4478, 74082, 74087, 74092, 42402, + 42407, 74096, 42421, 74101, 42426, 74106, 74112, 42438, 42444, 42450, + 74117, 74123, 27479, 74134, 74137, 74149, 74157, 39105, 74161, 74170, + 74180, 74189, 39115, 74194, 74201, 74210, 74216, 74224, 74231, 74238, + 6950, 5174, 74243, 39037, 74249, 74252, 74258, 74265, 74270, 74275, + 28485, 74279, 74285, 74291, 74296, 74301, 74305, 74311, 74317, 40488, + 74322, 43626, 45463, 45469, 39146, 39151, 74326, 74330, 74334, 74337, + 74350, 74356, 74360, 74363, 74368, 40870, 74372, 37759, 25872, 74378, + 6879, 6887, 10377, 74381, 74386, 74391, 74396, 74401, 74406, 74411, + 74416, 74421, 74426, 74432, 74437, 74442, 74448, 74453, 74458, 74463, + 74468, 74473, 74478, 74484, 74489, 74495, 74500, 74505, 74510, 74515, + 74520, 74525, 74530, 74535, 74540, 74545, 74551, 74556, 74561, 74566, + 74571, 74576, 74581, 74587, 74592, 74597, 74602, 74607, 74612, 74617, + 74622, 74627, 74632, 74638, 74643, 74648, 74653, 74658, 74664, 74670, + 74675, 74681, 74686, 74691, 74696, 74701, 74706, 1421, 159, 74711, 74715, + 74719, 74723, 30435, 74727, 74731, 74736, 74740, 74745, 74749, 74754, + 74759, 74764, 74769, 74773, 74777, 74782, 74786, 16020, 74791, 74795, + 74802, 74812, 18315, 74821, 74830, 74839, 74843, 74848, 74853, 74857, + 74861, 30215, 3259, 74865, 74871, 21763, 74875, 74884, 74892, 74898, + 74903, 74915, 74927, 74932, 74936, 74941, 74945, 74951, 74957, 74962, + 74972, 74982, 74988, 74996, 75001, 75005, 75011, 75016, 75023, 75029, + 75034, 75041, 75050, 75059, 75067, 75071, 18871, 75074, 75083, 75091, + 75103, 75114, 75125, 75134, 75138, 75147, 75155, 75165, 75173, 75180, + 75190, 75196, 75201, 75209, 75216, 75225, 75231, 75236, 75243, 75249, + 75260, 60, 37536, 75266, 31986, 31996, 75272, 75280, 75287, 75293, 75297, + 75307, 75318, 75326, 75335, 75340, 75345, 75350, 75354, 75358, 75366, + 21710, 75373, 75377, 75383, 75393, 75400, 75407, 75413, 75419, 42501, + 75423, 75425, 75428, 75434, 75438, 75449, 75459, 75465, 75472, 75479, + 15957, 75487, 75493, 75502, 75511, 75517, 11579, 75523, 75529, 75534, + 75539, 75546, 75551, 75558, 75564, 75569, 75577, 75590, 75599, 75608, + 72138, 72148, 75618, 75624, 75633, 75639, 75645, 75652, 75659, 75666, + 75673, 75680, 75685, 75689, 75693, 75696, 75706, 75710, 75722, 75731, + 10038, 75740, 75751, 75756, 75760, 72157, 75766, 75773, 75782, 75790, + 51037, 75798, 75802, 75807, 75812, 75822, 75830, 75842, 75847, 75851, + 75855, 75861, 75869, 75876, 75888, 75896, 75907, 75914, 75920, 75930, + 75936, 75940, 75949, 75958, 75965, 75971, 75976, 75980, 75984, 75988, + 75997, 76006, 76015, 76022, 76028, 76034, 76040, 76045, 76052, 76058, + 76066, 76073, 76079, 15046, 76084, 76090, 76094, 17172, 76098, 76103, + 76113, 76118, 76127, 76133, 76139, 76147, 76154, 76158, 76162, 76169, + 76175, 76183, 76190, 76196, 76207, 76211, 76215, 76219, 76222, 76228, + 76233, 76238, 76242, 76246, 76255, 76263, 76270, 76276, 76283, 29245, + 48840, 76288, 76296, 76300, 76304, 76307, 76315, 76322, 76328, 76337, + 76345, 76351, 76356, 76360, 76365, 76370, 76374, 76378, 76382, 76387, + 76396, 76400, 76407, 45567, 76411, 76417, 76425, 76429, 76435, 76443, + 76449, 76454, 76465, 76473, 76479, 76488, 27626, 76496, 76503, 76510, + 76517, 76524, 76531, 52526, 15772, 76538, 76545, 76550, 42537, 4721, + 76556, 76561, 76566, 76572, 76578, 76584, 76589, 76594, 76599, 76604, + 76610, 76615, 76621, 76626, 76632, 76637, 76642, 76647, 76652, 76657, + 76662, 76667, 76673, 76678, 76684, 76689, 76694, 76699, 76704, 76709, + 76714, 76720, 76725, 76730, 76735, 76740, 76745, 76750, 76755, 76760, + 76765, 76770, 76776, 76781, 76786, 76791, 76796, 76801, 76806, 76811, + 76816, 76822, 76827, 76832, 76837, 76842, 76847, 76852, 76857, 76862, + 76867, 76872, 76877, 76882, 76888, 1883, 305, 76893, 46479, 46484, 76897, + 76902, 9293, 76906, 3628, 76911, 76916, 76920, 76929, 76940, 76957, + 76975, 76983, 75794, 76990, 76993, 77003, 77010, 77019, 77035, 77044, + 77054, 77059, 77072, 77082, 77091, 77099, 77113, 77121, 77130, 77134, + 77137, 77144, 77150, 77161, 77168, 77180, 77191, 77202, 77211, 77218, + 1173, 812, 77228, 2744, 77232, 77237, 77246, 997, 9059, 25308, 77254, + 77262, 77276, 77289, 77293, 77298, 77303, 77308, 77314, 77320, 77325, + 9661, 18358, 77330, 77334, 77338, 77346, 10098, 77351, 77357, 77366, + 77374, 1657, 13314, 1179, 4393, 77378, 77382, 77391, 77401, 2482, 32836, + 77410, 77416, 20438, 32851, 77422, 4558, 13696, 77428, 77435, 71848, + 77439, 77443, 77449, 77454, 77459, 3861, 163, 3887, 77464, 77476, 77480, + 77484, 77490, 77495, 33733, 77499, 13684, 2938, 4, 77504, 77514, 77525, + 77536, 77546, 77552, 77563, 77570, 77576, 77582, 2306, 77587, 77595, + 77602, 77608, 77618, 77628, 77638, 77647, 28568, 1185, 77652, 77656, + 77660, 77666, 77670, 2961, 2967, 9658, 2337, 77674, 77678, 77687, 77695, + 77706, 77714, 77722, 77728, 77733, 77744, 77755, 77763, 77769, 77774, + 11356, 77784, 77792, 77796, 77800, 77805, 77809, 77821, 34196, 18257, + 77828, 77838, 77844, 77850, 7977, 11490, 77860, 77871, 77882, 77892, + 77901, 77905, 77912, 999, 2731, 77922, 77927, 77935, 71564, 77943, 77948, + 77959, 77966, 77980, 16968, 529, 77990, 77997, 78001, 78005, 78013, + 78022, 4433, 78030, 78036, 20483, 78041, 78055, 78062, 78068, 78076, + 78085, 78094, 78101, 78113, 78123, 78131, 78138, 78146, 78153, 4357, 116, + 78161, 78172, 78176, 78188, 78194, 1804, 227, 78199, 10709, 78204, 3006, + 78208, 78215, 78221, 78232, 78242, 78250, 78257, 10049, 78264, 78273, + 78281, 4438, 78294, 4455, 78298, 78303, 78309, 78314, 78319, 78324, 3011, + 573, 78330, 78343, 78347, 78352, 78357, 3016, 1882, 763, 78361, 4459, + 78369, 78375, 78379, 799, 78389, 78398, 78403, 3878, 78407, 78411, 17989, + 17996, 9317, 78419, 4490, 4367, 15644, 78427, 78434, 78439, 28632, 78443, + 78450, 78456, 13952, 78461, 14017, 204, 78466, 78478, 78484, 78492, 3028, + 1699, 78500, 78502, 78507, 78512, 78517, 78523, 78528, 78533, 78538, + 78543, 78548, 78553, 78559, 78564, 78569, 78574, 78579, 78584, 78589, + 78594, 78599, 78605, 78610, 78615, 78620, 78626, 78631, 78637, 78642, + 78647, 78652, 78657, 78662, 78667, 78672, 78678, 78683, 78689, 78694, + 78699, 78704, 78709, 78714, 78719, 78724, 78729, 9730, 9743, 4506, 4511, + 4516, 4521, 26, 78735, 78741, 78746, 78751, 78756, 78762, 78767, 78771, + 78775, 78780, 78786, 78790, 78796, 78801, 78806, 78812, 78817, 78821, + 78826, 78831, 78835, 78838, 78840, 78844, 78847, 78854, 78859, 78863, + 78868, 78872, 78876, 78880, 78886, 78897, 78917, 78936, 78957, 78970, + 78982, 78991, 78995, 78998, 39423, 79001, 39428, 79008, 79013, 39433, + 79022, 79031, 39439, 79036, 39444, 79045, 79050, 13941, 79054, 79059, + 79064, 39449, 79068, 79077, 50696, 79081, 79084, 79088, 9325, 79094, + 79097, 79102, 79107, 79112, 79116, 4179, 39454, 79119, 79123, 79126, + 79137, 79142, 79146, 79152, 79160, 79173, 79177, 79185, 79194, 79200, + 79205, 79211, 79215, 79221, 79227, 79235, 79240, 79244, 79251, 79257, + 79265, 79274, 79282, 39457, 79289, 79299, 79308, 79316, 79327, 79340, + 79345, 79350, 79354, 79363, 79369, 79376, 79389, 79401, 79412, 79424, + 79431, 79440, 79449, 79458, 79465, 79471, 79478, 79486, 79493, 79501, + 79510, 79518, 79525, 79533, 79542, 79550, 79559, 79569, 79578, 79586, + 79593, 79601, 79610, 79618, 79627, 79637, 79646, 79654, 79663, 79673, + 79682, 79692, 79703, 79713, 79722, 79730, 79737, 79745, 79754, 79762, + 79771, 79781, 79790, 79798, 79807, 79817, 79826, 79836, 79847, 79857, + 79866, 79874, 79883, 79893, 79902, 79912, 79923, 79933, 79942, 79952, + 79963, 79973, 79984, 79996, 80007, 80017, 80026, 80034, 80041, 80049, + 80058, 80066, 80075, 80085, 80094, 80102, 80111, 80121, 80130, 80140, + 80151, 80161, 80170, 80178, 80187, 80197, 80206, 80216, 80227, 80237, + 80246, 80256, 80267, 80277, 80288, 80300, 80311, 80321, 80330, 80338, + 80347, 80357, 80366, 80376, 80387, 80397, 80406, 80416, 80427, 80437, + 80448, 80460, 80471, 80481, 80490, 80500, 80511, 80521, 80532, 80544, + 80555, 80565, 80576, 80588, 80599, 80611, 80624, 80636, 80647, 80657, + 80666, 80674, 80681, 80689, 80698, 80706, 80715, 80725, 80734, 80742, + 80751, 80761, 80770, 80780, 80791, 80801, 80810, 80818, 80827, 80837, + 80846, 80856, 80867, 80877, 80886, 80896, 80907, 80917, 80928, 80940, + 80951, 80961, 80970, 80978, 80987, 80997, 81006, 81016, 81027, 81037, + 81046, 81056, 81067, 81077, 81088, 81100, 81111, 81121, 81130, 81140, + 81151, 81161, 81172, 81184, 81195, 81205, 81216, 81228, 81239, 81251, + 81264, 81276, 81287, 81297, 81306, 81314, 81323, 81333, 81342, 81352, + 81363, 81373, 81382, 81392, 81403, 81413, 81424, 81436, 81447, 81457, + 81466, 81476, 81487, 81497, 81508, 81520, 81531, 81541, 81552, 81564, + 81575, 81587, 81600, 81612, 81623, 81633, 81642, 81652, 81663, 81673, + 81684, 81696, 81707, 81717, 81728, 81740, 81751, 81763, 81776, 81788, + 81799, 81809, 81820, 81832, 81843, 81855, 81868, 81880, 81891, 81903, + 81916, 81928, 81941, 81955, 81968, 81980, 81991, 82001, 82010, 82018, + 82025, 82030, 9090, 82037, 82042, 39467, 82048, 82053, 39472, 82059, + 82066, 25430, 31434, 82071, 82077, 82083, 82091, 82097, 82103, 82110, + 82117, 82122, 82127, 82131, 82136, 82140, 82143, 82147, 82152, 82161, + 82170, 82178, 82184, 82196, 82207, 82211, 3321, 9065, 82216, 82219, + 82222, 82224, 82228, 82232, 82236, 82242, 82247, 31497, 82252, 82256, + 82259, 82264, 82268, 82275, 82281, 82285, 7060, 82289, 82294, 39494, + 82298, 82305, 82314, 82322, 82328, 82339, 82347, 82356, 82364, 82371, + 82378, 82384, 82389, 82400, 39499, 82405, 82416, 82428, 82436, 82447, + 82456, 82464, 82475, 82480, 82488, 2696, 82493, 82502, 41891, 82515, + 82519, 82531, 82539, 82544, 82552, 82563, 21928, 82572, 82578, 82585, + 82593, 82599, 39509, 82604, 4484, 68920, 82611, 82614, 82622, 82635, + 82648, 82661, 82674, 82681, 82692, 82701, 82706, 52343, 52348, 82710, + 82714, 82722, 82729, 82738, 82746, 82752, 82761, 82769, 82776, 82784, + 82788, 82797, 82806, 82816, 82829, 82842, 82852, 39514, 82858, 82865, + 82871, 82877, 39520, 82882, 82885, 82889, 82897, 82906, 52114, 82914, + 82923, 82931, 82938, 82946, 82956, 82965, 82974, 41043, 82983, 82994, + 83009, 83019, 10747, 26246, 83028, 83033, 83038, 83042, 19547, 83047, + 83052, 83058, 83063, 83068, 83074, 83079, 83084, 26206, 83089, 83096, + 83104, 83112, 83120, 83125, 83132, 83139, 83144, 1717, 83148, 83152, + 83160, 83168, 39537, 83174, 83180, 83192, 83198, 83205, 83209, 83216, + 83221, 83228, 83234, 83241, 83252, 83262, 83272, 83284, 83290, 83298, + 83307, 83313, 83323, 83333, 39564, 83342, 83351, 83357, 83369, 83380, + 83387, 83392, 83396, 83404, 83415, 83421, 83426, 83431, 83438, 83446, + 83458, 83468, 83477, 83486, 83494, 83501, 41705, 29006, 83507, 83512, + 83516, 83520, 83525, 83533, 83539, 83550, 83563, 83568, 83575, 39569, + 83580, 83592, 83601, 83609, 83619, 83630, 83643, 83650, 83659, 83668, + 83676, 83681, 83687, 83691, 1410, 83696, 83701, 83706, 83711, 83717, + 83722, 83727, 83733, 83739, 83744, 83748, 83753, 83758, 83763, 69504, + 83768, 83773, 83778, 83783, 83789, 83795, 83800, 83804, 83809, 19546, + 83814, 83820, 83825, 83831, 83836, 83841, 83846, 83851, 83855, 83861, + 83866, 83875, 83880, 83885, 83890, 83895, 83899, 83906, 83912, 4836, + 20800, 3286, 83917, 83921, 83926, 83930, 83934, 83938, 56143, 83942, + 83867, 83944, 83954, 39578, 83957, 83962, 83971, 83977, 7019, 39583, + 83981, 83987, 83992, 83998, 84003, 84007, 84014, 84019, 84029, 84038, + 84042, 84048, 84054, 84060, 84064, 84072, 84079, 84087, 84095, 39588, + 84102, 84105, 84116, 84123, 84129, 84134, 84138, 84144, 84152, 84159, + 84164, 84168, 84177, 84185, 84191, 84196, 84203, 84211, 39593, 84218, + 28458, 84230, 84236, 84241, 84247, 84254, 84260, 25894, 33344, 84266, + 84271, 84277, 84281, 84293, 83900, 83907, 26138, 84303, 84308, 84315, + 84321, 84328, 84334, 84345, 84350, 84358, 10447, 84363, 84366, 84372, + 84376, 84380, 84383, 84389, 84395, 39282, 4837, 1425, 16069, 84402, + 84408, 84414, 84420, 84426, 84432, 84438, 84444, 84450, 84455, 84460, + 84465, 84470, 84475, 84480, 84485, 84490, 84495, 84500, 84505, 84510, + 84515, 84521, 84526, 84531, 84537, 84542, 84547, 84553, 84559, 84565, + 84571, 84577, 84583, 84589, 84595, 84601, 84606, 84611, 84617, 84622, + 84627, 84633, 84638, 84643, 84648, 84653, 84658, 84663, 84668, 84673, + 84678, 84683, 84688, 84693, 84699, 84704, 84709, 84714, 84720, 84725, + 84730, 84735, 84740, 84746, 84751, 84756, 84761, 84766, 84771, 84776, + 84781, 84786, 84791, 84796, 84801, 84806, 84811, 84816, 84821, 84826, + 84831, 84836, 84841, 84847, 84852, 84857, 84862, 84867, 84872, 84877, + 84882, 1065, 148, 84887, 84891, 84895, 84900, 84908, 84912, 84924, 84931, + 84939, 84943, 84956, 84964, 84969, 84974, 32049, 84978, 84983, 84987, + 84992, 84996, 85004, 85008, 25438, 85013, 85017, 72401, 85021, 85024, + 85032, 85040, 85048, 85053, 85058, 85065, 85072, 85078, 85084, 85089, + 85096, 85101, 85109, 77281, 85116, 85121, 72167, 85128, 85134, 85139, + 85143, 85150, 85156, 85163, 72194, 14031, 85171, 85176, 85181, 85185, + 85188, 85199, 85208, 85214, 85219, 85223, 85233, 85242, 50487, 85246, + 85250, 85257, 85270, 85276, 85284, 85291, 85300, 85311, 85322, 85333, + 85344, 85353, 85359, 85368, 85376, 85386, 85399, 85407, 85414, 85425, + 85434, 85440, 85445, 85450, 85456, 85466, 85472, 85482, 85490, 85497, + 85507, 85516, 83582, 85524, 85530, 85538, 85544, 75834, 85551, 85556, + 85559, 85563, 85569, 85573, 85576, 85584, 85590, 85596, 85604, 85616, + 85628, 85635, 85640, 85644, 85655, 85663, 85670, 85682, 85690, 85697, + 85705, 85712, 85718, 85723, 85729, 85739, 85748, 85756, 85761, 85771, + 85780, 51375, 85787, 85791, 85796, 85804, 85811, 85817, 85821, 85831, + 85842, 85850, 85857, 85869, 85881, 85890, 82505, 85897, 85907, 85919, + 85930, 85944, 85952, 85962, 85969, 85977, 85990, 86002, 86011, 86019, + 86029, 86040, 86052, 86061, 86071, 86081, 86091, 86100, 86107, 86116, + 86131, 86139, 86149, 86158, 86166, 86179, 68890, 86194, 86204, 86213, + 86225, 86235, 86247, 86258, 86272, 86286, 86300, 86314, 86328, 86342, + 86356, 86370, 86384, 86398, 86412, 86426, 86440, 86454, 86468, 86482, + 86496, 86510, 86524, 86538, 86552, 86566, 86580, 86594, 86608, 86622, + 86636, 86650, 86664, 86678, 86692, 86706, 86720, 86734, 86748, 86762, + 86776, 86790, 86804, 86818, 86832, 86846, 86860, 86874, 86888, 86902, + 86916, 86930, 86944, 86958, 86972, 86986, 87000, 87014, 87028, 87042, + 87056, 87070, 87084, 87098, 87112, 87126, 87140, 87154, 87168, 87182, + 87196, 87210, 87224, 87238, 87252, 87266, 87280, 87294, 87308, 87322, + 87336, 87350, 87364, 87378, 87392, 87406, 87420, 87434, 87448, 87462, + 87476, 87490, 87504, 87518, 87532, 87546, 87560, 87574, 87588, 87602, + 87616, 87630, 87644, 87658, 87672, 87686, 87700, 87714, 87728, 87742, + 87756, 87770, 87784, 87798, 87812, 87826, 87840, 87854, 87868, 87882, + 87896, 87910, 87924, 87938, 87952, 87966, 87980, 87994, 88008, 88022, + 88036, 88050, 88064, 88078, 88092, 88106, 88120, 88134, 88148, 88162, + 88176, 88190, 88204, 88218, 88232, 88246, 88260, 88274, 88288, 88302, + 88316, 88330, 88344, 88358, 88372, 88386, 88400, 88414, 88428, 88442, + 88456, 88470, 88484, 88498, 88512, 88526, 88540, 88554, 88568, 88582, + 88596, 88610, 88624, 88638, 88652, 88666, 88680, 88694, 88708, 88722, + 88736, 88750, 88764, 88778, 88792, 88806, 88820, 88834, 88848, 88862, + 88876, 88890, 88904, 88918, 88932, 88946, 88960, 88974, 88988, 89002, + 89016, 89030, 89044, 89058, 89072, 89086, 89100, 89114, 89128, 89142, + 89156, 89170, 89184, 89198, 89212, 89226, 89240, 89254, 89268, 89282, + 89296, 89310, 89324, 89338, 89352, 89366, 89380, 89394, 89408, 89422, + 89436, 89450, 89464, 89478, 89492, 89506, 89520, 89534, 89548, 89562, + 89576, 89590, 89604, 89618, 89632, 89646, 89660, 89674, 89688, 89702, + 89716, 89730, 89744, 89758, 89772, 89786, 89800, 89814, 89828, 89842, + 89856, 89870, 89884, 89898, 89912, 89926, 89940, 89954, 89968, 89982, + 89996, 90010, 90024, 90038, 90052, 90066, 90080, 90094, 90108, 90122, + 90136, 90150, 90164, 90178, 90192, 90206, 90220, 90234, 90248, 90262, + 90276, 90290, 90304, 90318, 90332, 90346, 90360, 90374, 90388, 90402, + 90416, 90430, 90444, 90458, 90472, 90486, 90500, 90514, 90528, 90542, + 90556, 90570, 90584, 90598, 90612, 90626, 90640, 90654, 90668, 90682, + 90696, 90710, 90724, 90738, 90752, 90766, 90780, 90794, 90808, 90822, + 90836, 90850, 90864, 90878, 90892, 90906, 90920, 90934, 90948, 90962, + 90976, 90990, 91004, 91018, 91032, 91046, 91060, 91074, 91088, 91102, + 91116, 91130, 91144, 91158, 91172, 91186, 91200, 91214, 91228, 91242, + 91256, 91270, 91284, 91298, 91312, 91326, 91340, 91354, 91368, 91382, + 91396, 91410, 91424, 91438, 91452, 91466, 91480, 91494, 91508, 91522, + 91536, 91550, 91564, 91578, 91592, 91606, 91620, 91634, 91648, 91662, + 91676, 91690, 91704, 91718, 91732, 91746, 91760, 91774, 91788, 91802, + 91816, 91830, 91844, 91858, 91872, 91886, 91900, 91914, 91928, 91942, + 91956, 91970, 91984, 91998, 92012, 92026, 92040, 92054, 92068, 92082, + 92096, 92110, 92124, 92138, 92152, 92166, 92180, 92194, 92208, 92222, + 92236, 92250, 92264, 92278, 92292, 92306, 92320, 92334, 92348, 92362, + 92376, 92390, 92404, 92418, 92432, 92446, 92460, 92474, 92488, 92502, + 92516, 92530, 92544, 92558, 92572, 92586, 92600, 92614, 92628, 92642, + 92656, 92670, 92684, 92698, 92712, 92726, 92740, 92754, 92768, 92782, + 92796, 92810, 92824, 92838, 92852, 92866, 92880, 92894, 92908, 92922, + 92936, 92950, 92964, 92978, 92992, 93006, 93020, 93034, 93048, 93062, + 93076, 93090, 93104, 93118, 93132, 93146, 93160, 93174, 93188, 93202, + 93216, 93230, 93244, 93258, 93272, 93286, 93300, 93314, 93328, 93342, + 93356, 93370, 93384, 93398, 93412, 93426, 93440, 93454, 93468, 93482, + 93496, 93510, 93524, 93538, 93552, 93566, 93580, 93594, 93608, 93622, + 93636, 93650, 93664, 93678, 93692, 93706, 93720, 93734, 93748, 93762, + 93776, 93790, 93804, 93818, 93832, 93846, 93860, 93874, 93888, 93902, + 93916, 93930, 93944, 93958, 93972, 93986, 94000, 94014, 94028, 94042, + 94056, 94070, 94084, 94098, 94112, 94126, 94140, 94154, 94168, 94182, + 94196, 94210, 94224, 94238, 94252, 94266, 94280, 94294, 94308, 94322, + 94336, 94350, 94364, 94378, 94392, 94406, 94420, 94434, 94448, 94462, + 94476, 94490, 94504, 94518, 94532, 94546, 94560, 94574, 94588, 94602, + 94616, 94630, 94644, 94658, 94672, 94686, 94700, 94714, 94728, 94742, + 94756, 94770, 94784, 94798, 94812, 94826, 94840, 94854, 94868, 94882, + 94896, 94910, 94924, 94938, 94952, 94966, 94980, 94994, 95008, 95022, + 95036, 95050, 95064, 95078, 95092, 95106, 95120, 95134, 95148, 95162, + 95176, 95190, 95204, 95218, 95232, 95246, 95260, 95274, 95288, 95302, + 95316, 95330, 95344, 95358, 95372, 95386, 95400, 95414, 95428, 95442, + 95456, 95470, 95484, 95498, 95512, 95526, 95540, 95554, 95568, 95582, + 95596, 95610, 95624, 95638, 95652, 95666, 95680, 95694, 95708, 95722, + 95736, 95750, 95764, 95778, 95792, 95806, 95820, 95834, 95848, 95862, + 95876, 95890, 95904, 95918, 95932, 95946, 95960, 95974, 95988, 96002, + 96016, 96030, 96044, 96058, 96072, 96086, 96100, 96114, 96128, 96142, + 96156, 96170, 96184, 96198, 96212, 96226, 96240, 96254, 96268, 96282, + 96296, 96310, 96324, 96338, 96352, 96366, 96380, 96394, 96408, 96422, + 96436, 96450, 96464, 96478, 96492, 96506, 96520, 96534, 96548, 96562, + 96576, 96590, 96604, 96618, 96632, 96646, 96660, 96674, 96688, 96702, + 96716, 96730, 96744, 96758, 96772, 96786, 96800, 96814, 96828, 96842, + 96856, 96870, 96884, 96898, 96912, 96926, 96940, 96954, 96968, 96982, + 96996, 97010, 97019, 97030, 97041, 97051, 97062, 97070, 97078, 97084, + 97094, 97102, 97108, 35368, 97113, 97119, 97128, 97140, 97145, 97152, + 11370, 21948, 97158, 97167, 97172, 97176, 97181, 97188, 97194, 97199, + 97204, 97212, 97220, 97230, 97235, 97243, 14513, 97247, 97253, 97259, + 97265, 97271, 97277, 97283, 97289, 97295, 97301, 97307, 97313, 97319, + 97325, 97331, 97337, 97343, 97349, 97355, 97361, 97367, 97373, 97379, + 97385, 97391, 97397, 97403, 97409, 97415, 97421, 97427, 97433, 97439, + 97445, 97451, 97457, 97463, 97470, 97476, 97482, 97488, 97494, 97500, + 97506, 97512, 97518, 97524, 97530, 97536, 97542, 97548, 97554, 97560, + 97566, 97572, 97578, 97584, 97590, 97596, 97602, 97608, 97614, 97620, + 97626, 97632, 97638, 97644, 97650, 97656, 97662, 97668, 97674, 97680, + 97686, 97692, 97698, 97704, 97710, 97716, 97722, 97728, 97734, 97740, + 97746, 97752, 97758, 97764, 97770, 97777, 97783, 97789, 97795, 97801, + 97807, 97813, 97819, 97825, 97831, 97837, 97843, 97846, 97848, 97863, + 97876, 97883, 97889, 97900, 97905, 97909, 97914, 97921, 97927, 97932, + 97940, 77884, 77894, 97946, 97953, 97963, 12672, 97970, 97975, 35616, + 97984, 97989, 97996, 98006, 98014, 98022, 98031, 98040, 98046, 98052, + 98057, 98064, 98071, 98076, 98080, 98088, 72211, 98093, 98102, 98110, + 98117, 98122, 98126, 98135, 98141, 98144, 98148, 98157, 98167, 84951, + 98176, 98180, 98188, 98192, 98198, 98209, 98219, 21957, 98230, 98239, + 98247, 98255, 98262, 72230, 9895, 98270, 98274, 98283, 98290, 98293, + 98297, 33215, 98300, 98304, 98309, 98326, 98338, 12630, 98350, 98355, + 98360, 98365, 25545, 98369, 98374, 98379, 98385, 98390, 6640, 98395, + 25549, 98400, 98405, 98411, 98418, 98423, 98428, 98434, 98440, 98446, + 98451, 98457, 98461, 98475, 98483, 98491, 98497, 98502, 98509, 98519, + 98528, 98533, 98538, 98543, 98551, 98561, 98572, 98577, 98583, 98588, + 98597, 70639, 4760, 98602, 98620, 98639, 98652, 98666, 98682, 98689, + 98696, 98705, 98712, 98718, 98725, 98730, 98736, 98741, 98747, 98755, + 98761, 98766, 98771, 98787, 12643, 98801, 98808, 98816, 98822, 98826, + 98829, 98835, 98840, 98845, 98853, 98860, 98865, 98874, 98880, 98885, + 98891, 98897, 98906, 98915, 43462, 98920, 98931, 98938, 98946, 98955, + 14104, 98964, 98970, 98978, 98984, 98990, 98996, 99001, 99008, 99014, + 14115, 99019, 99022, 99027, 39620, 99037, 99046, 99051, 99059, 99066, + 99072, 99077, 99085, 99092, 99103, 99119, 99135, 99151, 99167, 99183, + 99199, 99215, 99231, 99247, 99263, 99279, 99295, 99311, 99327, 99343, + 99359, 99375, 99391, 99407, 99423, 99439, 99455, 99471, 99487, 99503, + 99519, 99535, 99551, 99567, 99583, 99599, 99615, 99631, 99647, 99663, + 99679, 99695, 99711, 99727, 99743, 99759, 99775, 99791, 99807, 99823, + 99839, 99855, 99871, 99887, 99903, 99919, 99935, 99951, 99967, 99983, + 99999, 100015, 100031, 100047, 100063, 100079, 100095, 100111, 100127, + 100143, 100159, 100175, 100191, 100207, 100223, 100239, 100255, 100271, + 100287, 100303, 100319, 100335, 100351, 100367, 100383, 100399, 100415, + 100431, 100447, 100463, 100479, 100495, 100511, 100527, 100543, 100559, + 100575, 100591, 100607, 100623, 100639, 100655, 100671, 100687, 100703, + 100719, 100735, 100751, 100767, 100783, 100799, 100815, 100831, 100847, + 100863, 100879, 100895, 100911, 100927, 100943, 100959, 100975, 100991, + 101007, 101023, 101039, 101055, 101071, 101087, 101103, 101119, 101135, + 101151, 101167, 101183, 101199, 101215, 101231, 101247, 101263, 101279, + 101295, 101311, 101327, 101343, 101359, 101375, 101391, 101407, 101423, + 101439, 101455, 101471, 101487, 101503, 101519, 101535, 101551, 101567, + 101583, 101599, 101615, 101631, 101647, 101663, 101679, 101695, 101711, + 101727, 101743, 101759, 101775, 101791, 101807, 101823, 101839, 101855, + 101871, 101887, 101903, 101919, 101935, 101951, 101967, 101983, 101999, + 102015, 102031, 102047, 102063, 102079, 102095, 102111, 102127, 102143, + 102159, 102175, 102191, 102207, 102223, 102239, 102255, 102271, 102287, + 102303, 102319, 102335, 102351, 102367, 102383, 102399, 102415, 102431, + 102447, 102463, 102479, 102495, 102511, 102527, 102543, 102559, 102575, + 102591, 102607, 102623, 102639, 102655, 102671, 102687, 102703, 102719, + 102735, 102751, 102767, 102783, 102799, 102815, 102831, 102847, 102863, + 102879, 102895, 102911, 102927, 102943, 102959, 102975, 102991, 103007, + 103023, 103039, 103055, 103071, 103087, 103103, 103119, 103135, 103151, + 103167, 103183, 103199, 103215, 103231, 103247, 103263, 103279, 103295, + 103311, 103327, 103343, 103359, 103375, 103391, 103407, 103423, 103439, + 103455, 103471, 103487, 103503, 103519, 103535, 103551, 103567, 103583, + 103599, 103615, 103631, 103647, 103663, 103679, 103695, 103711, 103727, + 103743, 103759, 103775, 103791, 103807, 103823, 103839, 103855, 103871, + 103887, 103903, 103919, 103935, 103951, 103967, 103983, 103999, 104015, + 104031, 104047, 104063, 104079, 104095, 104111, 104127, 104143, 104159, + 104175, 104191, 104207, 104223, 104239, 104255, 104271, 104287, 104303, + 104319, 104335, 104351, 104367, 104383, 104399, 104415, 104431, 104447, + 104463, 104479, 104495, 104511, 104527, 104543, 104559, 104575, 104591, + 104607, 104623, 104639, 104655, 104671, 104687, 104703, 104719, 104735, + 104751, 104767, 104783, 104799, 104815, 104831, 104847, 104863, 104879, + 104895, 104911, 104927, 104943, 104959, 104975, 104991, 105007, 105023, + 105039, 105055, 105071, 105087, 105103, 105119, 105135, 105151, 105167, + 105183, 105199, 105215, 105231, 105247, 105263, 105279, 105295, 105311, + 105327, 105343, 105359, 105375, 105391, 105407, 105423, 105439, 105455, + 105471, 105487, 105503, 105519, 105535, 105551, 105567, 105583, 105599, + 105615, 105631, 105647, 105663, 105679, 105695, 105711, 105727, 105743, + 105759, 105775, 105791, 105807, 105823, 105839, 105855, 105871, 105887, + 105903, 105919, 105935, 105951, 105967, 105983, 105999, 106015, 106031, + 106047, 106063, 106079, 106095, 106111, 106127, 106143, 106159, 106175, + 106191, 106207, 106223, 106239, 106255, 106271, 106287, 106303, 106319, + 106335, 106351, 106367, 106383, 106399, 106415, 106431, 106447, 106463, + 106479, 106495, 106511, 106527, 106543, 106559, 106575, 106591, 106607, + 106623, 106639, 106655, 106671, 106687, 106703, 106719, 106735, 106751, + 106767, 106783, 106799, 106815, 106831, 106847, 106863, 106879, 106895, + 106911, 106927, 106943, 106959, 106975, 106991, 107007, 107023, 107039, + 107055, 107071, 107087, 107103, 107119, 107135, 107151, 107167, 107183, + 107199, 107215, 107231, 107247, 107263, 107279, 107295, 107311, 107327, + 107343, 107359, 107375, 107391, 107407, 107423, 107439, 107455, 107471, + 107487, 107503, 107519, 107535, 107551, 107567, 107583, 107599, 107615, + 107631, 107647, 107663, 107679, 107695, 107711, 107727, 107743, 107759, + 107775, 107791, 107807, 107823, 107839, 107855, 107871, 107887, 107903, + 107919, 107935, 107951, 107967, 107983, 107999, 108015, 108031, 108047, + 108063, 108079, 108095, 108111, 108127, 108143, 108159, 108175, 108191, + 108207, 108223, 108239, 108255, 108271, 108287, 108303, 108319, 108335, + 108351, 108367, 108383, 108399, 108415, 108431, 108447, 108463, 108479, + 108495, 108511, 108527, 108543, 108559, 108575, 108591, 108607, 108623, + 108639, 108655, 108671, 108687, 108703, 108719, 108735, 108751, 108767, + 108783, 108799, 108815, 108831, 108847, 108863, 108879, 108895, 108911, + 108927, 108943, 108959, 108975, 108991, 109007, 109023, 109039, 109055, + 109071, 109087, 109103, 109119, 109135, 109151, 109167, 109183, 109199, + 109215, 109231, 109247, 109263, 109279, 109295, 109311, 109327, 109343, + 109359, 109375, 109391, 109407, 109423, 109439, 109455, 109471, 109487, + 109503, 109519, 109535, 109551, 109567, 109583, 109599, 109615, 109631, + 109647, 109663, 109679, 109695, 109711, 109727, 109743, 109759, 109775, + 109791, 109807, 109823, 109839, 109855, 109871, 109887, 109903, 109919, + 109935, 109951, 109967, 109983, 109999, 110015, 110031, 110047, 110063, + 110079, 110095, 110111, 110127, 110143, 110159, 110175, 110191, 110207, + 110223, 110239, 110255, 110271, 110287, 110303, 110319, 110335, 110351, + 110367, 110383, 110399, 110415, 110431, 110447, 110463, 110479, 110495, + 110511, 110527, 110543, 110559, 110575, 110591, 110607, 110623, 110639, + 110655, 110671, 110687, 110703, 110719, 110735, 110751, 110767, 110783, + 110799, 110815, 110831, 110847, 110863, 110879, 110895, 110911, 110927, + 110943, 110959, 110975, 110991, 111007, 111023, 111039, 111055, 111071, + 111087, 111103, 111119, 111135, 111151, 111167, 111183, 111199, 111215, + 111231, 111247, 111263, 111279, 111295, 111311, 111327, 111343, 111359, + 111375, 111391, 111407, 111423, 111439, 111455, 111471, 111487, 111503, + 111519, 111535, 111551, 111567, 111583, 111599, 111615, 111631, 111647, + 111663, 111679, 111695, 111711, 111727, 111743, 111759, 111775, 111791, + 111807, 111823, 111839, 111855, 111871, 111887, 111903, 111919, 111935, + 111951, 111967, 111983, 111999, 112015, 112031, 112047, 112063, 112079, + 112095, 112111, 112127, 112143, 112159, 112175, 112191, 112207, 112223, + 112239, 112255, 112271, 112287, 112303, 112319, 112335, 112351, 112367, + 112383, 112399, 112415, 112431, 112447, 112463, 112479, 112495, 112511, + 112527, 112543, 112559, 112575, 112591, 112607, 112623, 112639, 112655, + 112671, 112687, 112703, 112719, 112735, 112751, 112767, 112783, 112799, + 112815, 112831, 112847, 112863, 112879, 112895, 112911, 112927, 112943, + 112959, 112969, 112978, 112983, 112991, 77204, 112996, 113002, 113007, + 113014, 113023, 113031, 113035, 4338, 113041, 113048, 113054, 113058, + 20549, 46595, 3295, 113063, 113067, 113071, 113078, 113084, 113093, + 113099, 113106, 113110, 113131, 113153, 113169, 113186, 113205, 113214, + 113224, 113232, 113239, 113246, 113252, 33070, 113266, 113270, 113276, + 113284, 113296, 113302, 113310, 113317, 113322, 113327, 113331, 113339, + 113346, 113350, 113356, 113362, 113367, 3972, 52543, 113373, 113377, + 113381, 113385, 113390, 113395, 113400, 113406, 113412, 113418, 113425, + 113431, 113438, 113444, 113450, 113455, 113461, 113466, 113470, 105563, + 113475, 105627, 52558, 113480, 113485, 113493, 113497, 113502, 113509, + 113518, 113525, 113531, 113540, 113544, 113551, 113555, 113558, 113565, + 113571, 113580, 113590, 113600, 113605, 113609, 113616, 113624, 113633, + 113637, 113645, 113651, 113656, 113661, 113667, 113673, 113678, 113682, + 31947, 113688, 113692, 113696, 113699, 113704, 113712, 113722, 113728, + 113733, 113743, 49664, 113751, 113763, 113769, 113776, 113782, 113786, + 113791, 113797, 113809, 113820, 113827, 113833, 113840, 113847, 113859, + 113866, 113872, 25629, 113876, 113884, 113890, 113897, 113903, 113909, + 113915, 113920, 113925, 113930, 113934, 113943, 113951, 113962, 7934, + 113967, 19985, 113973, 113977, 113981, 113985, 113993, 114002, 114006, + 114013, 114022, 114030, 114043, 114049, 106139, 36551, 114054, 114056, + 114061, 114066, 114071, 114076, 114081, 114086, 114091, 114096, 114101, + 114106, 114111, 114116, 114121, 114126, 114132, 114137, 114142, 114147, + 114152, 114157, 114162, 114167, 114172, 114178, 114184, 114190, 114195, + 114200, 114212, 114217, 1935, 54, 114222, 114227, 39630, 114231, 39635, + 39640, 39646, 39651, 114235, 39656, 26815, 114257, 114261, 114265, + 114270, 114274, 39660, 114278, 114286, 114293, 114299, 114309, 39665, + 114316, 114319, 114324, 114328, 114337, 11168, 114345, 39670, 26659, + 114348, 114352, 114360, 1307, 114365, 39681, 114368, 114373, 114378, + 31188, 31198, 43060, 114383, 114388, 114393, 114398, 114404, 114409, + 114418, 114423, 114432, 114440, 114447, 114453, 114458, 114463, 114468, + 114478, 114487, 114495, 114500, 114508, 114512, 114520, 114524, 114531, + 114538, 114546, 114553, 39485, 46310, 114559, 114565, 114570, 114575, + 14548, 11961, 114580, 114585, 114590, 114596, 114603, 114609, 114618, + 114623, 114631, 114641, 114648, 114658, 114664, 114669, 114675, 114679, + 21979, 114686, 44045, 114699, 114704, 114711, 114717, 114732, 37615, + 75612, 114745, 114749, 114758, 114767, 114774, 114780, 114788, 114794, + 114802, 114811, 114819, 114826, 46430, 114832, 114835, 114839, 114843, + 114847, 11982, 114853, 114860, 114866, 114874, 114879, 114883, 29180, + 114889, 114892, 114900, 114907, 114915, 114928, 114942, 114949, 114955, + 114962, 114968, 39695, 114972, 114978, 114986, 114993, 115001, 115009, + 115015, 39700, 115023, 115029, 115034, 115044, 115050, 115059, 37410, + 42408, 115067, 115072, 115077, 115081, 115086, 115090, 115098, 115103, + 17981, 18806, 49686, 115107, 115112, 39705, 18138, 115116, 115128, + 115133, 115137, 115144, 115153, 115157, 115165, 115171, 115176, 115184, + 115192, 115200, 115208, 115216, 115224, 115235, 115241, 9132, 115246, + 115252, 115257, 115262, 115273, 115282, 115294, 115309, 40017, 115315, + 20104, 39709, 115319, 115326, 115332, 115336, 29317, 115343, 115349, + 115356, 48811, 115365, 115371, 115380, 115386, 115391, 115399, 115405, + 115410, 39719, 115415, 115424, 115433, 113815, 115442, 115449, 115455, + 115461, 115470, 115480, 115486, 115494, 115501, 115505, 39724, 115508, + 39730, 1346, 115513, 115521, 115529, 115539, 115548, 115556, 115563, + 115573, 39741, 115577, 115579, 115583, 115588, 115592, 115596, 115602, + 115607, 115611, 115622, 115627, 115633, 115638, 115647, 115652, 3300, + 115656, 115663, 115667, 115676, 115684, 115692, 115699, 115704, 115709, + 74113, 115713, 115716, 115722, 115730, 115736, 115740, 115745, 115752, + 115757, 115762, 115766, 115773, 115779, 115784, 42439, 115788, 115791, + 115796, 115800, 115805, 115812, 115817, 115821, 47780, 115829, 31207, + 31216, 115835, 115841, 115847, 115852, 115856, 115859, 115869, 115878, + 115883, 115889, 115896, 115902, 115906, 115914, 115919, 42445, 85210, + 115923, 115931, 115938, 115944, 115951, 115956, 115963, 115968, 115972, + 115978, 115983, 69106, 115989, 115995, 10386, 116000, 116005, 116009, + 116014, 116019, 116024, 116028, 116033, 116038, 116044, 116049, 116054, + 116060, 116066, 116071, 116075, 116080, 116085, 116090, 116094, 29316, + 116099, 116104, 116110, 116116, 116122, 116127, 116131, 116136, 116141, + 109915, 116146, 116151, 116156, 116161, 109979, 52813, 116166, 39749, + 116174, 116178, 116186, 116194, 116205, 116210, 116214, 27294, 82608, + 116219, 116225, 116230, 4649, 116240, 116247, 116252, 116260, 116269, + 116274, 116278, 116283, 116287, 116295, 116303, 116310, 77470, 116316, + 116324, 116331, 116342, 116348, 116354, 39759, 116357, 116364, 116372, + 116377, 116381, 33589, 71792, 116387, 116392, 116399, 116404, 10275, + 116408, 116416, 116423, 116430, 116439, 116446, 116452, 116466, 116474, + 6724, 116236, 116480, 116485, 116491, 116495, 116498, 116506, 116513, + 116518, 116531, 116538, 116544, 116548, 116556, 116561, 116568, 116574, + 116579, 72070, 116584, 116587, 116596, 116603, 110187, 116609, 116612, + 116620, 116626, 116635, 116645, 116655, 116664, 116675, 116683, 116694, + 116699, 116703, 116708, 116712, 43191, 116720, 18771, 43200, 116725, + 101706, 101722, 101738, 101754, 101770, 116730, 101802, 101818, 101834, + 101850, 101962, 101978, 116734, 102010, 102026, 116738, 116742, 116746, + 116750, 102266, 102298, 116754, 102330, 116758, 116762, 102474, 102490, + 102506, 102522, 116766, 102586, 102602, 116770, 102730, 102746, 102762, + 102778, 102794, 102810, 102826, 102842, 102858, 102874, 102986, 103002, + 103018, 103034, 103050, 103066, 103082, 103098, 103114, 103130, 116774, + 104922, 105034, 105098, 105114, 105130, 105146, 105162, 105178, 105290, + 105306, 105322, 116778, 105370, 116782, 105402, 105418, 105434, 116786, + 116791, 116796, 116801, 116806, 116811, 116816, 116820, 116824, 116829, + 116834, 116838, 116843, 116848, 116852, 116857, 116862, 116867, 116872, + 116876, 116881, 116886, 116890, 116895, 116899, 116903, 116907, 116911, + 116916, 116920, 116924, 116928, 116932, 116936, 116940, 116944, 116948, + 116952, 116957, 116962, 116967, 116972, 116977, 116982, 116987, 116992, + 116997, 117002, 117006, 117010, 117014, 117018, 117022, 117026, 117031, + 117035, 117040, 117044, 117049, 117054, 117058, 117062, 117067, 117071, + 117075, 117079, 117083, 117087, 117091, 117095, 117099, 117103, 117107, + 117111, 117115, 117119, 117123, 117128, 117133, 117137, 117141, 117145, + 117149, 117153, 117157, 117162, 117166, 117170, 117174, 117178, 117182, + 117186, 117191, 117195, 117200, 117204, 117208, 117212, 117216, 117220, + 117224, 117228, 117232, 117236, 117240, 117244, 117249, 117253, 117257, + 117261, 117265, 117269, 117273, 117277, 117281, 117285, 117289, 117293, + 117298, 117302, 117306, 117311, 117316, 117320, 117324, 117328, 117332, + 117336, 117340, 117344, 117348, 117353, 117357, 117362, 117366, 117371, + 117375, 117380, 117384, 117390, 117395, 117399, 117404, 117408, 117413, + 117417, 117422, 117426, 117431, 1429, 117435, 117439, 3042, 1705, 28453, + 1602, 31143, 117443, 3051, 117447, 1276, 117452, 1218, 117456, 117460, + 117464, 117468, 117472, 117476, 3075, 117480, 117488, 117495, 117502, + 117516, 3079, 8044, 117525, 117533, 117540, 117551, 117560, 117564, + 117571, 117583, 117596, 117609, 117620, 117625, 117632, 117644, 117648, + 3083, 14185, 117658, 117663, 117672, 117682, 117687, 117696, 3087, + 117704, 117708, 117713, 117720, 117726, 117731, 117740, 117748, 117760, + 117770, 1223, 15645, 117783, 117787, 117793, 117807, 117819, 117831, + 117839, 117849, 117858, 117867, 117876, 117884, 117895, 117903, 4657, + 117913, 117924, 117933, 117939, 117954, 117961, 117967, 117972, 43334, + 117977, 3111, 15649, 117981, 117986, 117993, 10206, 118002, 118008, 4695, + 118018, 3116, 39121, 118027, 71682, 118034, 118038, 118044, 118055, + 118061, 118066, 118073, 118079, 118087, 118094, 118100, 118111, 118127, + 118137, 118146, 118157, 118166, 118173, 118179, 118189, 118197, 118203, + 118218, 118224, 118229, 118233, 118240, 118248, 118252, 118255, 118261, + 118268, 118274, 118282, 118291, 118299, 118305, 118314, 52116, 118328, + 118333, 118339, 17732, 118344, 118357, 118369, 118378, 118386, 118393, + 118397, 118401, 118404, 118411, 118418, 118426, 118434, 118443, 118451, + 17631, 118459, 118464, 118468, 118480, 118487, 118494, 118503, 954, + 118513, 118522, 118533, 3137, 118537, 118541, 118547, 118560, 118572, + 118582, 118591, 118603, 32105, 118614, 118622, 118631, 118642, 118653, + 118663, 118673, 118681, 118690, 118698, 13604, 118705, 118709, 118712, + 118717, 118722, 118726, 118732, 1228, 118739, 118743, 14281, 118747, + 118751, 118762, 118771, 118779, 118788, 118796, 118812, 118823, 118832, + 118840, 118852, 118863, 118879, 118889, 118910, 118924, 118937, 118945, + 118952, 8090, 118965, 118970, 118976, 6733, 118982, 118985, 118992, + 119002, 9266, 119009, 119014, 119019, 119026, 119034, 119042, 119048, + 119053, 119059, 119063, 119071, 119080, 119088, 119093, 119102, 119109, + 11418, 11427, 119115, 119126, 119132, 119137, 119143, 3153, 3158, 119149, + 1063, 119155, 119162, 119169, 119182, 119192, 119197, 2324, 87, 119205, + 119212, 119217, 119225, 119235, 119244, 119250, 119259, 119267, 119277, + 119281, 119285, 119290, 119294, 119306, 3181, 119314, 119322, 119327, + 119338, 119349, 119361, 119372, 119382, 119391, 26013, 119396, 119402, + 119407, 119417, 119427, 119432, 34323, 119438, 119443, 119452, 26035, + 119456, 26046, 119461, 4783, 8, 119468, 119477, 119484, 119491, 119497, + 119502, 119506, 119512, 34353, 119517, 119522, 72367, 119527, 119532, + 119538, 119544, 119552, 119557, 119565, 119573, 119582, 119589, 119595, + 119602, 119608, 119615, 119620, 47649, 52010, 119626, 119636, 1822, 32, + 119643, 119648, 119661, 119666, 119674, 119679, 119685, 3207, 30884, + 3221, 119690, 119698, 119705, 119710, 119715, 119724, 4340, 4351, 73711, + 119732, 119736, 1629, 1862, 119741, 119746, 119753, 34774, 1866, 331, + 119760, 119766, 119771, 3229, 119775, 119780, 119787, 1870, 119792, + 119798, 119803, 119815, 6978, 119825, 119832, 1877, 119838, 119843, + 119850, 119857, 119872, 119879, 119890, 119895, 119903, 2772, 119907, + 119919, 119924, 119928, 119934, 34195, 2329, 119938, 119949, 119953, + 119957, 119963, 119967, 119976, 119980, 119991, 119995, 2375, 38938, + 119999, 120009, 120017, 3320, 120023, 120032, 120040, 10752, 120045, + 120053, 120058, 120062, 120071, 120078, 120084, 3290, 17796, 120088, + 120101, 44058, 120119, 120124, 120132, 120140, 120150, 11759, 15773, + 120162, 120175, 120182, 120192, 120206, 120213, 120229, 120236, 120242, + 26093, 14980, 120249, 120256, 120266, 120275, 52812, 120287, 120295, + 52947, 120302, 120305, 120311, 120317, 120323, 120329, 120335, 120342, + 120349, 120355, 120361, 120367, 120373, 120379, 120385, 120391, 120397, + 120403, 120409, 120415, 120421, 120427, 120433, 120439, 120445, 120451, + 120457, 120463, 120469, 120475, 120481, 120487, 120493, 120499, 120505, + 120511, 120517, 120523, 120529, 120535, 120541, 120547, 120553, 120559, + 120565, 120571, 120577, 120583, 120589, 120595, 120601, 120607, 120613, + 120619, 120625, 120631, 120637, 120643, 120649, 120655, 120662, 120668, + 120675, 120682, 120688, 120695, 120702, 120708, 120714, 120720, 120726, + 120732, 120738, 120744, 120750, 120756, 120762, 120768, 120774, 120780, + 120786, 120792, 3304, 10720, 120798, 120808, 120814, 120822, 120826, + 117716, 3308, 120830, 114044, 25758, 4701, 4265, 120834, 3314, 120838, + 120848, 120854, 120860, 120866, 120872, 120878, 120884, 120890, 120896, + 120902, 120908, 120914, 120920, 120926, 120932, 120938, 120944, 120950, + 120956, 120962, 120968, 120974, 120980, 120986, 120992, 120998, 121005, + 121012, 121018, 121024, 121030, 121036, 121042, 121048, 1233, 121054, + 121059, 121064, 121069, 121074, 121079, 121084, 121089, 121094, 121098, + 121102, 121106, 121110, 121114, 121118, 121122, 121126, 121130, 121136, + 121142, 121148, 121154, 121158, 121162, 121166, 121170, 121174, 121178, + 121182, 121186, 121190, 121195, 121200, 121205, 121210, 121215, 121220, + 121225, 121230, 121235, 121240, 121245, 121250, 121255, 121260, 121265, + 121270, 121275, 121280, 121285, 121290, 121295, 121300, 121305, 121310, + 121315, 121320, 121325, 121330, 121335, 121340, 121345, 121350, 121355, + 121360, 121365, 121370, 121375, 121380, 121385, 121390, 121395, 121400, + 121405, 121410, 121415, 121420, 121425, 121430, 121435, 121440, 121445, + 121450, 121455, 121460, 121465, 121470, 121475, 121480, 121485, 121490, + 121495, 121500, 121505, 121510, 121515, 121520, 121525, 121530, 121535, + 121540, 121545, 121550, 121555, 121560, 121565, 121570, 121575, 121580, + 121585, 121590, 121595, 121600, 121605, 121610, 121615, 121620, 121625, + 121630, 121635, 121640, 121645, 121650, 121655, 121660, 121665, 121670, + 121675, 121680, 121685, 121690, 121695, 121700, 121705, 121710, 121715, + 121720, 121725, 121730, 121735, 121740, 121745, 121750, 121755, 121760, + 121765, 121770, 121775, 121780, 121785, 121790, 121795, 121800, 121805, + 121810, 121815, 121820, 121825, 121830, 121835, 121840, 121845, 121850, + 121855, 121860, 121865, 121870, 121875, 121880, 121885, 121890, 121895, + 121900, 121905, 121910, 121915, 121920, 121925, 121930, 121935, 121940, + 121945, 121950, 121955, 121960, 121965, 121970, 121975, 121980, 121985, + 121990, 121995, 122000, 122005, 122010, 122015, 122020, 122025, 122030, + 122035, 122040, 122045, 122050, 122055, 122060, 122065, 122070, 122075, + 122080, 122086, 122091, 122096, 122101, 122106, 122111, 122116, 122121, + 122127, 122132, 122137, 122142, 122147, 122152, 122157, 122162, 122167, + 122172, 122177, 122182, 122187, 122192, 122197, 122202, 122207, 122212, + 122217, 122222, 122227, 122232, 122237, 122242, 122247, 122252, 122257, + 122262, 122267, 122272, 122277, 122282, 122287, 122296, 122301, 122310, + 122315, 122324, 122329, 122338, 122343, 122352, 122357, 122366, 122371, + 122380, 122385, 122394, 122399, 122404, 122413, 122417, 122426, 122431, + 122440, 122445, 122454, 122459, 122468, 122473, 122482, 122487, 122496, + 122501, 122510, 122515, 122524, 122529, 122538, 122543, 122552, 122557, + 122562, 122567, 122572, 122577, 122582, 122587, 122591, 122596, 122601, + 122606, 122611, 122616, 122621, 122627, 122632, 122637, 122642, 122648, + 122652, 122657, 122663, 122668, 122673, 122678, 122683, 122688, 122693, + 122698, 122703, 122708, 122713, 122719, 122724, 122729, 122734, 122740, + 122745, 122750, 122755, 122760, 122766, 122771, 122776, 122781, 122786, + 122791, 122797, 122802, 122807, 122812, 122817, 122822, 122827, 122832, + 122837, 122842, 122847, 122852, 122857, 122862, 122867, 122872, 122877, + 122882, 122887, 122892, 122897, 122902, 122907, 122912, 122918, 122924, + 122930, 122935, 122940, 122945, 122950, 122956, 122962, 122968, 122973, + 122978, 122983, 122989, 122994, 122999, 123004, 123009, 123014, 123019, + 123024, 123029, 123034, 123039, 123044, 123049, 123054, 123059, 123064, + 123069, 123075, 123081, 123087, 123092, 123097, 123102, 123107, 123113, + 123119, 123125, 123130, 123135, 123140, 123145, 123150, 123155, 123160, + 123165, 123170, 19463, 123175, 123181, 123186, 123191, 123196, 123201, + 123206, 123212, 123217, 123222, 123227, 123232, 123237, 123243, 123248, + 123253, 123258, 123263, 123268, 123273, 123278, 123283, 123288, 123293, + 123298, 123303, 123308, 123313, 123318, 123323, 123328, 123333, 123338, + 123343, 123348, 123353, 123359, 123364, 123369, 123374, 123379, 123384, + 123389, 123394, 123399, 123404, 123409, 123414, 123419, 123424, 123429, + 123434, 123439, 123444, 123449, 123454, 123459, 123464, 123469, 123474, + 123479, 123484, 123489, 123494, 123499, 123504, 123509, 123514, 123519, + 123524, 123529, 123534, 123539, 123544, 123549, 123554, 123559, 123565, + 123570, 123575, 123580, 123585, 123590, 123595, 123600, 123605, 123610, + 123615, 123620, 123626, 123631, 123637, 123642, 123647, 123652, 123657, + 123662, 123667, 123673, 123678, 123683, 123689, 123694, 123699, 123704, + 123709, 123714, 123720, 123726, 123731, 123736, 14614, 123741, 123746, + 123751, 123756, 123761, 123766, 123771, 123776, 123781, 123786, 123791, + 123796, 123801, 123806, 123811, 123816, 123821, 123826, 123831, 123836, + 123841, 123846, 123851, 123856, 123861, 123866, 123871, 123876, 123881, + 123886, 123891, 123896, 123901, 123906, 123911, 123916, 123921, 123926, + 123931, 123936, 123941, 123946, 123951, 123956, 123961, 123966, 123971, + 123976, 123981, 123986, 123991, 123996, 124001, 124006, 124011, 124016, + 124021, 124026, 124031, 124036, 124041, 124046, 124051, 124056, 124061, + 124067, 124072, 124077, 124082, 124087, 124093, 124098, 124103, 124108, + 124113, 124118, 124123, 124129, 124134, 124139, 124144, 124149, 124154, + 124160, 124165, 124170, 124175, 124180, 124185, 124191, 124196, 124201, + 124206, 124211, 124216, 124222, 124228, 124233, 124238, 124243, 124249, + 124255, 124261, 124266, 124271, 124277, 124283, 124288, 124294, 124300, + 124306, 124311, 124316, 124322, 124327, 124333, 124338, 124344, 124353, + 124358, 124363, 124369, 124374, 124380, 124385, 124390, 124395, 124400, + 124405, 124410, 124415, 124420, 124425, 124430, 124435, 124440, 124445, + 124450, 124455, 124460, 124465, 124470, 124475, 124480, 124485, 124490, + 124495, 124500, 124505, 124510, 124515, 124520, 124525, 124530, 124535, + 124541, 124547, 124553, 124558, 124563, 124568, 124573, 124578, 124583, + 124588, 124593, 124598, 124603, 124608, 124613, 124618, 124623, 124628, + 124633, 124638, 124643, 124648, 124653, 124659, 124665, 124670, 124676, + 124681, 124686, 124692, 124697, 124703, 124708, 124714, 124719, 124725, + 124730, 124736, 124741, 124746, 124751, 124756, 124761, 124766, 124771, + 120849, 120855, 120861, 120867, 124777, 120873, 120879, 124783, 120885, + 120891, 120897, 120903, 120909, 120915, 120921, 120927, 120933, 124789, + 120939, 120945, 120951, 124795, 120957, 120963, 120969, 120975, 124801, + 120981, 120987, 120993, 121013, 124807, 124813, 121019, 124819, 121025, + 121031, 121037, 121043, 121049, 124825, 3331, 3336, 124830, 3351, 3356, + 3361, 124835, 124838, 124844, 124850, 124857, 124862, 124867, 2380, }; /* code->name phrasebook */ #define phrasebook_shift 7 #define phrasebook_short 190 static const unsigned char phrasebook[] = { - 0, 201, 242, 233, 175, 77, 207, 247, 77, 31, 57, 236, 110, 57, 210, 4, - 57, 251, 86, 250, 255, 45, 210, 103, 50, 210, 103, 250, 143, 107, 57, - 242, 26, 228, 57, 232, 42, 201, 58, 202, 18, 17, 191, 77, 17, 108, 17, - 109, 17, 139, 17, 137, 17, 153, 17, 173, 17, 181, 17, 176, 17, 184, 242, - 35, 204, 20, 219, 156, 57, 234, 1, 57, 230, 170, 57, 208, 8, 77, 242, 24, - 250, 132, 8, 6, 1, 65, 8, 6, 1, 250, 70, 8, 6, 1, 247, 145, 8, 6, 1, 238, - 80, 8, 6, 1, 73, 8, 6, 1, 233, 134, 8, 6, 1, 232, 14, 8, 6, 1, 230, 83, - 8, 6, 1, 70, 8, 6, 1, 223, 7, 8, 6, 1, 222, 125, 8, 6, 1, 170, 8, 6, 1, - 218, 147, 8, 6, 1, 215, 47, 8, 6, 1, 74, 8, 6, 1, 210, 226, 8, 6, 1, 208, - 97, 8, 6, 1, 148, 8, 6, 1, 206, 3, 8, 6, 1, 200, 39, 8, 6, 1, 69, 8, 6, - 1, 196, 8, 8, 6, 1, 193, 221, 8, 6, 1, 192, 235, 8, 6, 1, 192, 159, 8, 6, - 1, 191, 166, 45, 51, 248, 5, 207, 14, 202, 18, 50, 51, 248, 5, 242, 210, - 252, 8, 131, 219, 88, 230, 177, 252, 8, 8, 2, 1, 65, 8, 2, 1, 250, 70, 8, - 2, 1, 247, 145, 8, 2, 1, 238, 80, 8, 2, 1, 73, 8, 2, 1, 233, 134, 8, 2, - 1, 232, 14, 8, 2, 1, 230, 83, 8, 2, 1, 70, 8, 2, 1, 223, 7, 8, 2, 1, 222, - 125, 8, 2, 1, 170, 8, 2, 1, 218, 147, 8, 2, 1, 215, 47, 8, 2, 1, 74, 8, - 2, 1, 210, 226, 8, 2, 1, 208, 97, 8, 2, 1, 148, 8, 2, 1, 206, 3, 8, 2, 1, - 200, 39, 8, 2, 1, 69, 8, 2, 1, 196, 8, 8, 2, 1, 193, 221, 8, 2, 1, 192, - 235, 8, 2, 1, 192, 159, 8, 2, 1, 191, 166, 45, 238, 124, 248, 5, 81, 219, - 88, 50, 238, 124, 248, 5, 198, 147, 213, 24, 201, 242, 223, 65, 233, 175, - 77, 246, 232, 57, 209, 1, 57, 238, 123, 57, 192, 71, 57, 247, 230, 164, - 205, 49, 57, 236, 253, 238, 215, 57, 232, 255, 211, 40, 223, 116, 219, - 195, 54, 251, 65, 207, 247, 77, 212, 255, 57, 202, 27, 228, 58, 207, 73, - 57, 217, 125, 237, 80, 57, 209, 72, 57, 200, 177, 109, 200, 177, 139, - 251, 251, 252, 8, 216, 72, 57, 209, 133, 57, 82, 236, 96, 246, 243, 200, - 177, 108, 217, 21, 211, 40, 223, 116, 206, 198, 54, 251, 65, 207, 247, - 77, 193, 243, 232, 80, 91, 208, 17, 193, 243, 232, 80, 91, 230, 37, 193, - 243, 232, 80, 115, 208, 15, 223, 65, 208, 8, 77, 8, 6, 1, 41, 4, 230, - 176, 8, 6, 1, 41, 4, 251, 250, 8, 6, 1, 41, 4, 242, 209, 8, 6, 1, 41, 4, - 198, 147, 8, 6, 1, 41, 4, 236, 253, 8, 6, 1, 41, 4, 206, 184, 56, 8, 6, - 1, 251, 229, 8, 6, 1, 247, 146, 4, 246, 243, 8, 6, 1, 234, 227, 4, 230, - 176, 8, 6, 1, 234, 227, 4, 251, 250, 8, 6, 1, 234, 227, 4, 242, 209, 8, - 6, 1, 234, 227, 4, 236, 253, 8, 6, 1, 228, 44, 4, 230, 176, 8, 6, 1, 228, - 44, 4, 251, 250, 8, 6, 1, 228, 44, 4, 242, 209, 8, 6, 1, 228, 44, 4, 236, - 253, 8, 6, 1, 233, 206, 8, 6, 1, 215, 48, 4, 198, 147, 8, 6, 1, 186, 4, - 230, 176, 8, 6, 1, 186, 4, 251, 250, 8, 6, 1, 186, 4, 242, 209, 8, 6, 1, - 186, 4, 198, 147, 8, 6, 1, 186, 4, 236, 253, 215, 112, 57, 8, 6, 1, 186, - 4, 105, 8, 6, 1, 126, 4, 230, 176, 8, 6, 1, 126, 4, 251, 250, 8, 6, 1, - 126, 4, 242, 209, 8, 6, 1, 126, 4, 236, 253, 8, 6, 1, 192, 160, 4, 251, - 250, 8, 6, 1, 198, 228, 8, 2, 1, 203, 122, 206, 3, 8, 2, 1, 41, 4, 230, - 176, 8, 2, 1, 41, 4, 251, 250, 8, 2, 1, 41, 4, 242, 209, 8, 2, 1, 41, 4, - 198, 147, 8, 2, 1, 41, 4, 236, 253, 8, 2, 1, 41, 4, 206, 184, 56, 8, 2, - 1, 251, 229, 8, 2, 1, 247, 146, 4, 246, 243, 8, 2, 1, 234, 227, 4, 230, - 176, 8, 2, 1, 234, 227, 4, 251, 250, 8, 2, 1, 234, 227, 4, 242, 209, 8, - 2, 1, 234, 227, 4, 236, 253, 8, 2, 1, 228, 44, 4, 230, 176, 8, 2, 1, 228, - 44, 4, 251, 250, 8, 2, 1, 228, 44, 4, 242, 209, 8, 2, 1, 228, 44, 4, 236, - 253, 8, 2, 1, 233, 206, 8, 2, 1, 215, 48, 4, 198, 147, 8, 2, 1, 186, 4, - 230, 176, 8, 2, 1, 186, 4, 251, 250, 8, 2, 1, 186, 4, 242, 209, 8, 2, 1, - 186, 4, 198, 147, 8, 2, 1, 186, 4, 236, 253, 236, 155, 57, 8, 2, 1, 186, - 4, 105, 8, 2, 1, 126, 4, 230, 176, 8, 2, 1, 126, 4, 251, 250, 8, 2, 1, - 126, 4, 242, 209, 8, 2, 1, 126, 4, 236, 253, 8, 2, 1, 192, 160, 4, 251, - 250, 8, 2, 1, 198, 228, 8, 2, 1, 192, 160, 4, 236, 253, 8, 6, 1, 41, 4, - 217, 125, 8, 2, 1, 41, 4, 217, 125, 8, 6, 1, 41, 4, 247, 244, 8, 2, 1, - 41, 4, 247, 244, 8, 6, 1, 41, 4, 211, 126, 8, 2, 1, 41, 4, 211, 126, 8, - 6, 1, 247, 146, 4, 251, 250, 8, 2, 1, 247, 146, 4, 251, 250, 8, 6, 1, - 247, 146, 4, 242, 209, 8, 2, 1, 247, 146, 4, 242, 209, 8, 6, 1, 247, 146, - 4, 75, 56, 8, 2, 1, 247, 146, 4, 75, 56, 8, 6, 1, 247, 146, 4, 247, 44, - 8, 2, 1, 247, 146, 4, 247, 44, 8, 6, 1, 238, 81, 4, 247, 44, 8, 2, 1, - 238, 81, 4, 247, 44, 8, 6, 1, 238, 81, 4, 105, 8, 2, 1, 238, 81, 4, 105, - 8, 6, 1, 234, 227, 4, 217, 125, 8, 2, 1, 234, 227, 4, 217, 125, 8, 6, 1, - 234, 227, 4, 247, 244, 8, 2, 1, 234, 227, 4, 247, 244, 8, 6, 1, 234, 227, - 4, 75, 56, 8, 2, 1, 234, 227, 4, 75, 56, 8, 6, 1, 234, 227, 4, 211, 126, - 8, 2, 1, 234, 227, 4, 211, 126, 8, 6, 1, 234, 227, 4, 247, 44, 8, 2, 1, - 234, 227, 4, 247, 44, 8, 6, 1, 232, 15, 4, 242, 209, 8, 2, 1, 232, 15, 4, - 242, 209, 8, 6, 1, 232, 15, 4, 247, 244, 8, 2, 1, 232, 15, 4, 247, 244, - 8, 6, 1, 232, 15, 4, 75, 56, 8, 2, 1, 232, 15, 4, 75, 56, 8, 6, 1, 232, - 15, 4, 246, 243, 8, 2, 1, 232, 15, 4, 246, 243, 8, 6, 1, 230, 84, 4, 242, - 209, 8, 2, 1, 230, 84, 4, 242, 209, 8, 6, 1, 230, 84, 4, 105, 8, 2, 1, - 230, 84, 4, 105, 8, 6, 1, 228, 44, 4, 198, 147, 8, 2, 1, 228, 44, 4, 198, - 147, 8, 6, 1, 228, 44, 4, 217, 125, 8, 2, 1, 228, 44, 4, 217, 125, 8, 6, - 1, 228, 44, 4, 247, 244, 8, 2, 1, 228, 44, 4, 247, 244, 8, 6, 1, 228, 44, - 4, 211, 126, 8, 2, 1, 228, 44, 4, 211, 126, 8, 6, 1, 228, 44, 4, 75, 56, - 8, 2, 1, 236, 95, 70, 8, 6, 34, 223, 168, 8, 2, 34, 223, 168, 8, 6, 1, - 223, 8, 4, 242, 209, 8, 2, 1, 223, 8, 4, 242, 209, 8, 6, 1, 222, 126, 4, - 246, 243, 8, 2, 1, 222, 126, 4, 246, 243, 8, 2, 1, 220, 240, 8, 6, 1, - 220, 119, 4, 251, 250, 8, 2, 1, 220, 119, 4, 251, 250, 8, 6, 1, 220, 119, - 4, 246, 243, 8, 2, 1, 220, 119, 4, 246, 243, 8, 6, 1, 220, 119, 4, 247, - 44, 8, 2, 1, 220, 119, 4, 247, 44, 8, 6, 1, 220, 119, 4, 82, 236, 96, 8, - 2, 1, 220, 119, 4, 82, 236, 96, 8, 6, 1, 220, 119, 4, 105, 8, 2, 1, 220, - 119, 4, 105, 8, 6, 1, 215, 48, 4, 251, 250, 8, 2, 1, 215, 48, 4, 251, - 250, 8, 6, 1, 215, 48, 4, 246, 243, 8, 2, 1, 215, 48, 4, 246, 243, 8, 6, - 1, 215, 48, 4, 247, 44, 8, 2, 1, 215, 48, 4, 247, 44, 8, 2, 1, 215, 48, - 208, 226, 247, 157, 250, 255, 8, 6, 1, 234, 46, 8, 2, 1, 234, 46, 8, 6, - 1, 186, 4, 217, 125, 8, 2, 1, 186, 4, 217, 125, 8, 6, 1, 186, 4, 247, - 244, 8, 2, 1, 186, 4, 247, 244, 8, 6, 1, 186, 4, 54, 251, 250, 8, 2, 1, - 186, 4, 54, 251, 250, 8, 6, 34, 211, 139, 8, 2, 34, 211, 139, 8, 6, 1, - 207, 217, 4, 251, 250, 8, 2, 1, 207, 217, 4, 251, 250, 8, 6, 1, 207, 217, - 4, 246, 243, 8, 2, 1, 207, 217, 4, 246, 243, 8, 6, 1, 207, 217, 4, 247, - 44, 8, 2, 1, 207, 217, 4, 247, 44, 8, 6, 1, 206, 4, 4, 251, 250, 8, 2, 1, - 206, 4, 4, 251, 250, 8, 6, 1, 206, 4, 4, 242, 209, 8, 2, 1, 206, 4, 4, - 242, 209, 8, 6, 1, 206, 4, 4, 246, 243, 8, 2, 1, 206, 4, 4, 246, 243, 8, - 6, 1, 206, 4, 4, 247, 44, 8, 2, 1, 206, 4, 4, 247, 44, 8, 6, 1, 200, 40, - 4, 246, 243, 8, 2, 1, 200, 40, 4, 246, 243, 8, 6, 1, 200, 40, 4, 247, 44, - 8, 2, 1, 200, 40, 4, 247, 44, 8, 6, 1, 200, 40, 4, 105, 8, 2, 1, 200, 40, - 4, 105, 8, 6, 1, 126, 4, 198, 147, 8, 2, 1, 126, 4, 198, 147, 8, 6, 1, - 126, 4, 217, 125, 8, 2, 1, 126, 4, 217, 125, 8, 6, 1, 126, 4, 247, 244, - 8, 2, 1, 126, 4, 247, 244, 8, 6, 1, 126, 4, 206, 184, 56, 8, 2, 1, 126, - 4, 206, 184, 56, 8, 6, 1, 126, 4, 54, 251, 250, 8, 2, 1, 126, 4, 54, 251, - 250, 8, 6, 1, 126, 4, 211, 126, 8, 2, 1, 126, 4, 211, 126, 8, 6, 1, 193, - 222, 4, 242, 209, 8, 2, 1, 193, 222, 4, 242, 209, 8, 6, 1, 192, 160, 4, - 242, 209, 8, 2, 1, 192, 160, 4, 242, 209, 8, 6, 1, 192, 160, 4, 236, 253, - 8, 6, 1, 191, 167, 4, 251, 250, 8, 2, 1, 191, 167, 4, 251, 250, 8, 6, 1, - 191, 167, 4, 75, 56, 8, 2, 1, 191, 167, 4, 75, 56, 8, 6, 1, 191, 167, 4, - 247, 44, 8, 2, 1, 191, 167, 4, 247, 44, 8, 2, 1, 177, 206, 3, 8, 2, 1, - 78, 4, 105, 8, 6, 1, 78, 4, 106, 8, 6, 1, 78, 4, 198, 46, 8, 2, 1, 78, 4, - 198, 46, 8, 6, 1, 163, 173, 8, 2, 1, 163, 173, 8, 6, 1, 211, 66, 74, 8, - 6, 1, 247, 146, 4, 106, 8, 2, 1, 247, 146, 4, 106, 8, 6, 1, 251, 204, - 238, 80, 8, 6, 1, 238, 81, 4, 106, 8, 6, 1, 238, 81, 4, 198, 46, 8, 2, 1, - 238, 81, 4, 198, 46, 8, 2, 1, 152, 237, 61, 8, 6, 1, 207, 13, 73, 8, 6, - 1, 205, 81, 8, 6, 1, 211, 66, 73, 8, 6, 1, 233, 135, 4, 106, 8, 2, 1, - 233, 135, 4, 106, 8, 6, 1, 232, 15, 4, 106, 8, 6, 1, 231, 174, 8, 2, 1, - 228, 95, 8, 6, 1, 223, 55, 8, 6, 1, 228, 44, 4, 105, 8, 6, 1, 222, 126, - 4, 106, 8, 2, 1, 222, 126, 4, 106, 8, 2, 1, 220, 119, 4, 164, 8, 2, 1, - 220, 9, 4, 105, 8, 6, 1, 152, 218, 147, 8, 6, 1, 215, 48, 4, 45, 106, 8, - 2, 1, 215, 48, 4, 177, 50, 219, 188, 8, 6, 1, 186, 4, 82, 198, 147, 8, 6, - 1, 186, 4, 228, 156, 8, 2, 1, 186, 4, 228, 156, 8, 6, 1, 211, 121, 8, 2, - 1, 211, 121, 8, 6, 1, 210, 227, 4, 106, 8, 2, 1, 210, 227, 4, 106, 8, 1, - 191, 228, 8, 6, 1, 163, 109, 8, 2, 1, 163, 109, 8, 6, 1, 233, 226, 8, 1, - 207, 13, 233, 227, 218, 236, 8, 2, 1, 200, 40, 4, 210, 182, 106, 8, 6, 1, - 200, 40, 4, 106, 8, 2, 1, 200, 40, 4, 106, 8, 6, 1, 200, 40, 4, 207, 19, - 106, 8, 6, 1, 126, 4, 228, 156, 8, 2, 1, 126, 4, 228, 156, 8, 6, 1, 196, - 66, 8, 6, 1, 196, 9, 4, 106, 8, 6, 1, 192, 160, 4, 106, 8, 2, 1, 192, - 160, 4, 106, 8, 6, 1, 191, 167, 4, 105, 8, 2, 1, 191, 167, 4, 105, 8, 6, - 1, 233, 137, 8, 6, 1, 233, 138, 207, 12, 8, 2, 1, 233, 138, 207, 12, 8, - 2, 1, 233, 138, 4, 199, 210, 8, 1, 103, 4, 105, 8, 6, 1, 163, 153, 8, 2, - 1, 163, 153, 8, 1, 223, 65, 230, 231, 201, 59, 4, 105, 8, 1, 192, 238, 8, - 1, 237, 53, 242, 183, 8, 1, 219, 235, 242, 183, 8, 1, 251, 99, 242, 183, - 8, 1, 207, 19, 242, 183, 8, 6, 1, 234, 249, 4, 247, 44, 8, 6, 1, 238, 81, - 4, 2, 1, 191, 167, 4, 247, 44, 8, 2, 1, 234, 249, 4, 247, 44, 8, 6, 1, - 219, 53, 8, 6, 1, 220, 119, 4, 2, 1, 223, 7, 8, 2, 1, 219, 53, 8, 6, 1, - 213, 145, 8, 6, 1, 215, 48, 4, 2, 1, 223, 7, 8, 2, 1, 213, 145, 8, 6, 1, - 41, 4, 247, 44, 8, 2, 1, 41, 4, 247, 44, 8, 6, 1, 228, 44, 4, 247, 44, 8, - 2, 1, 228, 44, 4, 247, 44, 8, 6, 1, 186, 4, 247, 44, 8, 2, 1, 186, 4, - 247, 44, 8, 6, 1, 126, 4, 247, 44, 8, 2, 1, 126, 4, 247, 44, 8, 6, 1, - 126, 4, 236, 254, 24, 217, 125, 8, 2, 1, 126, 4, 236, 254, 24, 217, 125, - 8, 6, 1, 126, 4, 236, 254, 24, 251, 250, 8, 2, 1, 126, 4, 236, 254, 24, - 251, 250, 8, 6, 1, 126, 4, 236, 254, 24, 247, 44, 8, 2, 1, 126, 4, 236, - 254, 24, 247, 44, 8, 6, 1, 126, 4, 236, 254, 24, 230, 176, 8, 2, 1, 126, - 4, 236, 254, 24, 230, 176, 8, 2, 1, 152, 73, 8, 6, 1, 41, 4, 236, 254, - 24, 217, 125, 8, 2, 1, 41, 4, 236, 254, 24, 217, 125, 8, 6, 1, 41, 4, 75, - 95, 24, 217, 125, 8, 2, 1, 41, 4, 75, 95, 24, 217, 125, 8, 6, 1, 251, - 230, 4, 217, 125, 8, 2, 1, 251, 230, 4, 217, 125, 8, 6, 1, 232, 15, 4, - 105, 8, 2, 1, 232, 15, 4, 105, 8, 6, 1, 232, 15, 4, 247, 44, 8, 2, 1, - 232, 15, 4, 247, 44, 8, 6, 1, 222, 126, 4, 247, 44, 8, 2, 1, 222, 126, 4, - 247, 44, 8, 6, 1, 186, 4, 211, 126, 8, 2, 1, 186, 4, 211, 126, 8, 6, 1, - 186, 4, 211, 127, 24, 217, 125, 8, 2, 1, 186, 4, 211, 127, 24, 217, 125, - 8, 6, 1, 233, 138, 4, 247, 44, 8, 2, 1, 233, 138, 4, 247, 44, 8, 2, 1, - 223, 8, 4, 247, 44, 8, 6, 1, 234, 248, 8, 6, 1, 238, 81, 4, 2, 1, 191, - 166, 8, 2, 1, 234, 248, 8, 6, 1, 232, 15, 4, 251, 250, 8, 2, 1, 232, 15, - 4, 251, 250, 8, 6, 1, 228, 92, 8, 6, 1, 192, 238, 8, 6, 1, 215, 48, 4, - 230, 176, 8, 2, 1, 215, 48, 4, 230, 176, 8, 6, 1, 41, 4, 206, 184, 95, - 24, 251, 250, 8, 2, 1, 41, 4, 206, 184, 95, 24, 251, 250, 8, 6, 1, 251, - 230, 4, 251, 250, 8, 2, 1, 251, 230, 4, 251, 250, 8, 6, 1, 186, 4, 201, - 23, 24, 251, 250, 8, 2, 1, 186, 4, 201, 23, 24, 251, 250, 8, 6, 1, 41, 4, - 54, 230, 176, 8, 2, 1, 41, 4, 54, 230, 176, 8, 6, 1, 41, 4, 223, 65, 247, - 244, 8, 2, 1, 41, 4, 223, 65, 247, 244, 8, 6, 1, 234, 227, 4, 54, 230, - 176, 8, 2, 1, 234, 227, 4, 54, 230, 176, 8, 6, 1, 234, 227, 4, 223, 65, - 247, 244, 8, 2, 1, 234, 227, 4, 223, 65, 247, 244, 8, 6, 1, 228, 44, 4, - 54, 230, 176, 8, 2, 1, 228, 44, 4, 54, 230, 176, 8, 6, 1, 228, 44, 4, - 223, 65, 247, 244, 8, 2, 1, 228, 44, 4, 223, 65, 247, 244, 8, 6, 1, 186, - 4, 54, 230, 176, 8, 2, 1, 186, 4, 54, 230, 176, 8, 6, 1, 186, 4, 223, 65, - 247, 244, 8, 2, 1, 186, 4, 223, 65, 247, 244, 8, 6, 1, 207, 217, 4, 54, - 230, 176, 8, 2, 1, 207, 217, 4, 54, 230, 176, 8, 6, 1, 207, 217, 4, 223, - 65, 247, 244, 8, 2, 1, 207, 217, 4, 223, 65, 247, 244, 8, 6, 1, 126, 4, - 54, 230, 176, 8, 2, 1, 126, 4, 54, 230, 176, 8, 6, 1, 126, 4, 223, 65, - 247, 244, 8, 2, 1, 126, 4, 223, 65, 247, 244, 8, 6, 1, 206, 4, 4, 242, - 27, 60, 8, 2, 1, 206, 4, 4, 242, 27, 60, 8, 6, 1, 200, 40, 4, 242, 27, - 60, 8, 2, 1, 200, 40, 4, 242, 27, 60, 8, 6, 1, 191, 248, 8, 2, 1, 191, - 248, 8, 6, 1, 230, 84, 4, 247, 44, 8, 2, 1, 230, 84, 4, 247, 44, 8, 6, 1, - 215, 48, 4, 177, 50, 219, 188, 8, 2, 1, 238, 81, 4, 238, 128, 8, 6, 1, - 211, 9, 8, 2, 1, 211, 9, 8, 6, 1, 191, 167, 4, 106, 8, 2, 1, 191, 167, 4, - 106, 8, 6, 1, 41, 4, 75, 56, 8, 2, 1, 41, 4, 75, 56, 8, 6, 1, 234, 227, - 4, 246, 243, 8, 2, 1, 234, 227, 4, 246, 243, 8, 6, 1, 186, 4, 236, 254, - 24, 217, 125, 8, 2, 1, 186, 4, 236, 254, 24, 217, 125, 8, 6, 1, 186, 4, - 198, 148, 24, 217, 125, 8, 2, 1, 186, 4, 198, 148, 24, 217, 125, 8, 6, 1, - 186, 4, 75, 56, 8, 2, 1, 186, 4, 75, 56, 8, 6, 1, 186, 4, 75, 95, 24, - 217, 125, 8, 2, 1, 186, 4, 75, 95, 24, 217, 125, 8, 6, 1, 192, 160, 4, - 217, 125, 8, 2, 1, 192, 160, 4, 217, 125, 8, 2, 1, 220, 119, 4, 238, 128, - 8, 2, 1, 215, 48, 4, 238, 128, 8, 2, 1, 200, 40, 4, 238, 128, 8, 2, 1, - 236, 95, 223, 7, 8, 2, 1, 237, 156, 236, 213, 8, 2, 1, 208, 28, 236, 213, - 8, 6, 1, 41, 4, 105, 8, 6, 1, 247, 146, 4, 105, 8, 2, 1, 247, 146, 4, - 105, 8, 6, 1, 220, 119, 4, 164, 8, 6, 1, 200, 40, 4, 236, 250, 105, 8, 2, - 1, 206, 4, 4, 200, 142, 199, 210, 8, 2, 1, 191, 167, 4, 200, 142, 199, - 210, 8, 6, 1, 230, 231, 201, 58, 8, 2, 1, 230, 231, 201, 58, 8, 6, 1, 78, - 4, 105, 8, 6, 1, 126, 164, 8, 6, 1, 152, 196, 8, 8, 6, 1, 234, 227, 4, - 105, 8, 2, 1, 234, 227, 4, 105, 8, 6, 1, 223, 8, 4, 105, 8, 2, 1, 223, 8, - 4, 105, 8, 6, 1, 2, 208, 98, 4, 228, 219, 199, 210, 8, 2, 1, 208, 98, 4, - 228, 219, 199, 210, 8, 6, 1, 207, 217, 4, 105, 8, 2, 1, 207, 217, 4, 105, - 8, 6, 1, 192, 160, 4, 105, 8, 2, 1, 192, 160, 4, 105, 8, 2, 1, 152, 65, - 8, 2, 1, 251, 109, 8, 2, 1, 152, 251, 109, 8, 2, 1, 78, 4, 106, 8, 2, 1, - 211, 66, 74, 8, 2, 1, 247, 146, 4, 238, 128, 8, 2, 1, 238, 81, 4, 199, - 210, 8, 2, 1, 238, 81, 4, 106, 8, 2, 1, 207, 13, 73, 8, 2, 1, 205, 81, 8, - 2, 1, 205, 82, 4, 106, 8, 2, 1, 211, 66, 73, 8, 2, 1, 207, 13, 211, 66, - 73, 8, 2, 1, 207, 13, 211, 66, 234, 227, 4, 106, 8, 2, 1, 242, 171, 207, - 13, 211, 66, 73, 8, 2, 1, 236, 95, 223, 8, 4, 105, 8, 2, 1, 232, 15, 4, - 106, 8, 2, 1, 27, 232, 14, 8, 1, 2, 6, 232, 14, 8, 2, 1, 231, 174, 8, 2, - 1, 207, 135, 228, 156, 8, 2, 1, 152, 230, 83, 8, 2, 1, 230, 84, 4, 106, - 8, 2, 1, 229, 165, 4, 106, 8, 2, 1, 228, 44, 4, 105, 8, 2, 1, 223, 55, 8, - 1, 2, 6, 70, 8, 2, 1, 220, 119, 4, 82, 198, 147, 8, 2, 1, 220, 119, 4, - 248, 181, 8, 2, 1, 220, 119, 4, 207, 19, 106, 8, 2, 1, 219, 138, 8, 2, 1, - 152, 218, 147, 8, 2, 1, 152, 218, 148, 4, 177, 219, 188, 8, 2, 1, 218, - 148, 4, 106, 8, 2, 1, 215, 48, 4, 45, 106, 8, 2, 1, 215, 48, 4, 207, 19, - 106, 8, 1, 2, 6, 215, 47, 8, 2, 1, 249, 32, 74, 8, 1, 2, 6, 211, 139, 8, - 2, 1, 242, 171, 211, 99, 8, 2, 1, 209, 202, 8, 2, 1, 152, 148, 8, 2, 1, - 152, 207, 217, 4, 177, 219, 188, 8, 2, 1, 152, 207, 217, 4, 106, 8, 2, 1, - 207, 217, 4, 177, 219, 188, 8, 2, 1, 207, 217, 4, 199, 210, 8, 2, 1, 207, - 217, 4, 232, 192, 8, 2, 1, 207, 13, 207, 217, 4, 232, 192, 8, 1, 2, 6, - 148, 8, 1, 2, 6, 223, 65, 148, 8, 2, 1, 206, 4, 4, 106, 8, 2, 1, 233, - 226, 8, 2, 1, 236, 95, 223, 8, 4, 201, 23, 24, 106, 8, 2, 1, 201, 182, - 207, 13, 233, 226, 8, 2, 1, 233, 227, 4, 238, 128, 8, 2, 1, 152, 200, 39, - 8, 2, 1, 200, 40, 4, 207, 19, 106, 8, 2, 1, 126, 164, 8, 2, 1, 196, 66, - 8, 2, 1, 196, 9, 4, 106, 8, 2, 1, 152, 196, 8, 8, 2, 1, 152, 193, 221, 8, - 2, 1, 152, 192, 159, 8, 1, 2, 6, 192, 159, 8, 2, 1, 191, 167, 4, 207, 19, - 106, 8, 2, 1, 191, 167, 4, 238, 128, 8, 2, 1, 233, 137, 8, 2, 1, 233, - 138, 4, 238, 128, 8, 1, 230, 231, 201, 58, 8, 1, 209, 210, 195, 17, 232, - 66, 8, 1, 223, 65, 230, 231, 201, 58, 8, 1, 201, 31, 247, 145, 8, 1, 248, - 124, 242, 183, 8, 1, 2, 6, 250, 70, 8, 2, 1, 242, 171, 211, 66, 73, 8, 1, - 2, 6, 232, 15, 4, 106, 8, 1, 2, 6, 230, 83, 8, 2, 1, 223, 8, 4, 238, 165, - 8, 2, 1, 152, 222, 125, 8, 1, 2, 6, 170, 8, 2, 1, 208, 98, 4, 106, 8, 1, - 230, 231, 201, 59, 4, 105, 8, 1, 207, 13, 230, 231, 201, 59, 4, 105, 8, - 2, 1, 234, 249, 236, 213, 8, 2, 1, 237, 25, 236, 213, 8, 2, 1, 234, 249, - 236, 214, 4, 238, 128, 8, 2, 1, 197, 166, 236, 213, 8, 2, 1, 199, 74, - 236, 213, 8, 2, 1, 199, 147, 236, 214, 4, 238, 128, 8, 2, 1, 232, 252, - 236, 213, 8, 2, 1, 218, 205, 236, 213, 8, 2, 1, 218, 149, 236, 213, 8, 1, - 248, 124, 210, 3, 8, 1, 248, 132, 210, 3, 8, 2, 1, 152, 230, 84, 4, 232, - 192, 8, 2, 1, 152, 230, 84, 4, 232, 193, 24, 199, 210, 59, 1, 2, 230, 83, - 59, 1, 2, 230, 84, 4, 106, 59, 1, 2, 223, 7, 59, 1, 2, 148, 59, 1, 2, - 152, 148, 59, 1, 2, 152, 207, 217, 4, 106, 59, 1, 2, 6, 223, 65, 148, 59, - 1, 2, 193, 221, 59, 1, 2, 192, 159, 59, 1, 208, 208, 59, 1, 54, 208, 208, - 59, 1, 152, 242, 26, 59, 1, 250, 255, 59, 1, 207, 13, 242, 26, 59, 1, 50, - 134, 206, 183, 59, 1, 45, 134, 206, 183, 59, 1, 230, 231, 201, 58, 59, 1, - 207, 13, 230, 231, 201, 58, 59, 1, 45, 250, 185, 59, 1, 50, 250, 185, 59, - 1, 132, 250, 185, 59, 1, 143, 250, 185, 59, 1, 242, 210, 252, 8, 247, 44, - 59, 1, 81, 219, 88, 59, 1, 217, 125, 59, 1, 251, 251, 252, 8, 59, 1, 230, - 177, 252, 8, 59, 1, 131, 81, 219, 88, 59, 1, 131, 217, 125, 59, 1, 131, - 230, 177, 252, 8, 59, 1, 131, 251, 251, 252, 8, 59, 1, 197, 234, 242, 35, - 59, 1, 134, 197, 234, 242, 35, 59, 1, 246, 228, 50, 134, 206, 183, 59, 1, - 246, 228, 45, 134, 206, 183, 59, 1, 132, 199, 223, 59, 1, 143, 199, 223, - 59, 1, 107, 57, 59, 1, 216, 18, 57, 247, 244, 75, 56, 206, 184, 56, 211, - 126, 2, 198, 147, 54, 251, 251, 252, 8, 59, 1, 206, 253, 106, 59, 1, 238, - 171, 252, 8, 59, 1, 2, 231, 174, 59, 1, 2, 170, 59, 1, 2, 206, 3, 59, 1, - 2, 192, 235, 59, 1, 2, 207, 13, 230, 231, 201, 58, 59, 1, 233, 159, 163, - 164, 59, 1, 136, 163, 164, 59, 1, 216, 68, 163, 164, 59, 1, 131, 163, - 164, 59, 1, 233, 158, 163, 164, 59, 1, 192, 22, 237, 50, 163, 77, 59, 1, - 192, 107, 237, 50, 163, 77, 59, 1, 195, 15, 59, 1, 196, 105, 59, 1, 54, - 250, 255, 59, 1, 131, 143, 250, 185, 59, 1, 131, 132, 250, 185, 59, 1, - 131, 45, 250, 185, 59, 1, 131, 50, 250, 185, 59, 1, 131, 206, 183, 59, 1, - 82, 230, 177, 252, 8, 59, 1, 82, 54, 230, 177, 252, 8, 59, 1, 82, 54, - 251, 251, 252, 8, 59, 1, 131, 198, 147, 59, 1, 207, 142, 242, 35, 59, 1, - 248, 199, 136, 198, 74, 59, 1, 234, 53, 136, 198, 74, 59, 1, 248, 199, - 131, 198, 74, 59, 1, 234, 53, 131, 198, 74, 59, 1, 203, 99, 59, 1, 211, - 66, 203, 99, 59, 1, 131, 45, 55, 33, 230, 177, 252, 8, 33, 251, 251, 252, - 8, 33, 242, 210, 252, 8, 33, 198, 147, 33, 217, 125, 33, 210, 244, 33, - 247, 244, 33, 75, 56, 33, 236, 253, 33, 228, 219, 56, 33, 206, 184, 56, - 33, 54, 251, 251, 252, 8, 33, 247, 44, 33, 81, 219, 89, 56, 33, 54, 81, - 219, 89, 56, 33, 54, 230, 177, 252, 8, 33, 247, 71, 33, 223, 65, 247, - 244, 33, 152, 242, 27, 56, 33, 242, 27, 56, 33, 207, 13, 242, 27, 56, 33, - 242, 27, 95, 187, 33, 230, 177, 252, 9, 60, 33, 251, 251, 252, 9, 60, 33, - 45, 199, 224, 60, 33, 50, 199, 224, 60, 33, 45, 251, 65, 56, 33, 228, - 156, 33, 45, 134, 206, 184, 60, 33, 132, 199, 224, 60, 33, 143, 199, 224, - 60, 33, 107, 3, 60, 33, 216, 18, 3, 60, 33, 210, 180, 228, 219, 60, 33, - 207, 19, 228, 219, 60, 33, 75, 60, 33, 236, 254, 60, 33, 206, 184, 60, - 33, 242, 27, 60, 33, 246, 243, 33, 211, 126, 33, 81, 219, 89, 60, 33, - 247, 237, 60, 33, 223, 65, 54, 250, 221, 60, 33, 247, 45, 60, 33, 242, - 210, 252, 9, 60, 33, 247, 245, 60, 33, 223, 65, 247, 245, 60, 33, 198, - 148, 60, 33, 217, 126, 60, 33, 131, 219, 88, 33, 54, 131, 219, 88, 33, - 198, 148, 210, 245, 33, 203, 35, 201, 23, 210, 245, 33, 177, 201, 23, - 210, 245, 33, 203, 35, 202, 19, 210, 245, 33, 177, 202, 19, 210, 245, 33, - 50, 134, 206, 184, 60, 33, 223, 65, 247, 237, 60, 33, 51, 60, 33, 205, - 57, 60, 33, 192, 236, 56, 33, 81, 198, 147, 33, 54, 210, 244, 33, 230, - 177, 163, 77, 33, 251, 251, 163, 77, 33, 35, 209, 251, 33, 35, 221, 6, - 33, 35, 236, 247, 198, 55, 33, 35, 191, 233, 33, 247, 237, 56, 33, 234, - 1, 3, 60, 33, 54, 81, 219, 89, 60, 33, 45, 251, 65, 60, 33, 212, 255, - 198, 148, 56, 33, 228, 225, 56, 33, 251, 114, 234, 3, 118, 56, 33, 45, - 50, 63, 60, 33, 196, 62, 63, 60, 33, 230, 183, 222, 169, 33, 50, 250, - 186, 56, 33, 45, 134, 206, 184, 56, 33, 232, 249, 33, 192, 236, 60, 33, - 45, 250, 186, 60, 33, 50, 250, 186, 60, 33, 50, 250, 186, 24, 132, 250, - 186, 60, 33, 50, 134, 206, 184, 56, 33, 75, 95, 187, 33, 250, 144, 60, - 33, 54, 206, 184, 60, 33, 191, 21, 56, 33, 54, 247, 245, 60, 33, 54, 247, - 244, 33, 54, 217, 125, 33, 54, 217, 126, 60, 33, 54, 198, 147, 33, 54, - 223, 65, 247, 244, 33, 54, 96, 63, 60, 33, 8, 2, 1, 65, 33, 8, 2, 1, 73, - 33, 8, 2, 1, 70, 33, 8, 2, 1, 74, 33, 8, 2, 1, 69, 33, 8, 2, 1, 247, 145, - 33, 8, 2, 1, 238, 80, 33, 8, 2, 1, 230, 83, 33, 8, 2, 1, 218, 147, 33, 8, - 2, 1, 148, 33, 8, 2, 1, 200, 39, 33, 8, 2, 1, 196, 8, 33, 8, 2, 1, 192, - 235, 35, 6, 1, 229, 153, 35, 2, 1, 229, 153, 35, 6, 1, 250, 220, 205, - 140, 35, 2, 1, 250, 220, 205, 140, 35, 212, 121, 57, 35, 110, 212, 121, - 57, 35, 6, 1, 210, 161, 236, 221, 35, 2, 1, 210, 161, 236, 221, 35, 191, - 233, 35, 2, 207, 13, 218, 185, 202, 192, 113, 35, 2, 235, 94, 218, 185, - 202, 192, 113, 35, 2, 207, 13, 235, 94, 218, 185, 202, 192, 113, 35, 208, - 8, 77, 35, 6, 1, 191, 240, 35, 198, 55, 35, 236, 247, 198, 55, 35, 6, 1, - 251, 110, 4, 198, 55, 35, 251, 43, 199, 103, 35, 6, 1, 234, 6, 4, 198, - 55, 35, 6, 1, 233, 212, 4, 198, 55, 35, 6, 1, 223, 56, 4, 198, 55, 35, 6, - 1, 211, 97, 4, 198, 55, 35, 6, 1, 196, 67, 4, 198, 55, 35, 6, 1, 211, - 100, 4, 198, 55, 35, 2, 1, 223, 56, 4, 236, 247, 24, 198, 55, 35, 6, 1, - 251, 109, 35, 6, 1, 248, 162, 35, 6, 1, 231, 174, 35, 6, 1, 237, 61, 35, - 6, 1, 234, 5, 35, 6, 1, 191, 76, 35, 6, 1, 233, 211, 35, 6, 1, 199, 10, - 35, 6, 1, 223, 55, 35, 6, 1, 222, 46, 35, 6, 1, 220, 7, 35, 6, 1, 215, - 139, 35, 6, 1, 212, 165, 35, 6, 1, 192, 207, 35, 6, 1, 211, 96, 35, 6, 1, - 209, 176, 35, 6, 1, 206, 254, 35, 6, 1, 202, 191, 35, 6, 1, 199, 161, 35, - 6, 1, 196, 66, 35, 6, 1, 209, 202, 35, 6, 1, 243, 47, 35, 6, 1, 208, 169, - 35, 6, 1, 211, 99, 35, 6, 1, 223, 56, 4, 236, 246, 35, 6, 1, 196, 67, 4, - 236, 246, 35, 2, 1, 251, 110, 4, 198, 55, 35, 2, 1, 234, 6, 4, 198, 55, - 35, 2, 1, 233, 212, 4, 198, 55, 35, 2, 1, 223, 56, 4, 198, 55, 35, 2, 1, - 196, 67, 4, 236, 247, 24, 198, 55, 35, 2, 1, 251, 109, 35, 2, 1, 248, - 162, 35, 2, 1, 231, 174, 35, 2, 1, 237, 61, 35, 2, 1, 234, 5, 35, 2, 1, - 191, 76, 35, 2, 1, 233, 211, 35, 2, 1, 199, 10, 35, 2, 1, 223, 55, 35, 2, - 1, 222, 46, 35, 2, 1, 220, 7, 35, 2, 1, 215, 139, 35, 2, 1, 212, 165, 35, - 2, 1, 192, 207, 35, 2, 1, 211, 96, 35, 2, 1, 209, 176, 35, 2, 1, 206, - 254, 35, 2, 1, 52, 202, 191, 35, 2, 1, 202, 191, 35, 2, 1, 199, 161, 35, - 2, 1, 196, 66, 35, 2, 1, 209, 202, 35, 2, 1, 243, 47, 35, 2, 1, 208, 169, - 35, 2, 1, 211, 99, 35, 2, 1, 223, 56, 4, 236, 246, 35, 2, 1, 196, 67, 4, - 236, 246, 35, 2, 1, 211, 97, 4, 198, 55, 35, 2, 1, 196, 67, 4, 198, 55, - 35, 2, 1, 211, 100, 4, 198, 55, 35, 6, 222, 76, 113, 35, 248, 163, 113, - 35, 199, 11, 113, 35, 196, 67, 4, 228, 219, 113, 35, 196, 67, 4, 251, - 251, 24, 228, 219, 113, 35, 196, 67, 4, 236, 254, 24, 228, 219, 113, 35, - 209, 203, 113, 35, 209, 177, 113, 35, 222, 76, 113, 35, 1, 250, 220, 221, - 11, 35, 2, 1, 250, 220, 221, 11, 35, 1, 201, 68, 35, 2, 1, 201, 68, 35, - 1, 236, 221, 35, 2, 1, 236, 221, 35, 1, 221, 11, 35, 2, 1, 221, 11, 35, - 1, 205, 140, 35, 2, 1, 205, 140, 93, 6, 1, 203, 100, 93, 2, 1, 203, 100, - 93, 6, 1, 233, 3, 93, 2, 1, 233, 3, 93, 6, 1, 221, 171, 93, 2, 1, 221, - 171, 93, 6, 1, 228, 210, 93, 2, 1, 228, 210, 93, 6, 1, 231, 169, 93, 2, - 1, 231, 169, 93, 6, 1, 203, 66, 93, 2, 1, 203, 66, 93, 6, 1, 237, 77, 93, - 2, 1, 237, 77, 35, 222, 47, 113, 35, 206, 255, 113, 35, 218, 185, 202, - 192, 113, 35, 1, 191, 240, 35, 6, 199, 11, 113, 35, 218, 185, 234, 6, - 113, 35, 207, 13, 218, 185, 234, 6, 113, 35, 6, 1, 203, 51, 35, 2, 1, - 203, 51, 35, 6, 218, 185, 202, 192, 113, 35, 6, 1, 205, 137, 35, 2, 1, - 205, 137, 35, 206, 255, 4, 201, 23, 113, 35, 6, 207, 13, 218, 185, 202, - 192, 113, 35, 6, 235, 94, 218, 185, 202, 192, 113, 35, 6, 207, 13, 235, - 94, 218, 185, 202, 192, 113, 42, 6, 1, 223, 198, 4, 230, 176, 42, 6, 1, - 223, 60, 42, 6, 1, 236, 147, 42, 6, 1, 230, 240, 42, 6, 1, 196, 121, 223, - 197, 42, 6, 1, 234, 244, 42, 6, 1, 247, 155, 70, 42, 6, 1, 192, 33, 42, - 6, 1, 222, 238, 42, 6, 1, 219, 52, 42, 6, 1, 213, 137, 42, 6, 1, 197, - 151, 42, 6, 1, 221, 79, 42, 6, 1, 228, 44, 4, 230, 176, 42, 6, 1, 203, - 35, 69, 42, 6, 1, 234, 240, 42, 6, 1, 65, 42, 6, 1, 248, 223, 42, 6, 1, - 195, 150, 42, 6, 1, 231, 40, 42, 6, 1, 237, 101, 42, 6, 1, 223, 197, 42, - 6, 1, 191, 62, 42, 6, 1, 191, 87, 42, 6, 1, 70, 42, 6, 1, 203, 35, 70, - 42, 6, 1, 157, 42, 6, 1, 234, 97, 42, 6, 1, 234, 72, 42, 6, 1, 234, 61, - 42, 6, 1, 74, 42, 6, 1, 210, 53, 42, 6, 1, 233, 248, 42, 6, 1, 233, 236, - 42, 6, 1, 199, 140, 42, 6, 1, 69, 42, 6, 1, 234, 138, 42, 6, 1, 144, 42, - 6, 1, 197, 157, 42, 6, 1, 243, 79, 42, 6, 1, 203, 160, 42, 6, 1, 203, - 111, 42, 6, 1, 229, 240, 57, 42, 6, 1, 192, 58, 42, 6, 1, 202, 27, 57, - 42, 6, 1, 73, 42, 6, 1, 191, 225, 42, 6, 1, 169, 42, 2, 1, 65, 42, 2, 1, - 248, 223, 42, 2, 1, 195, 150, 42, 2, 1, 231, 40, 42, 2, 1, 237, 101, 42, - 2, 1, 223, 197, 42, 2, 1, 191, 62, 42, 2, 1, 191, 87, 42, 2, 1, 70, 42, - 2, 1, 203, 35, 70, 42, 2, 1, 157, 42, 2, 1, 234, 97, 42, 2, 1, 234, 72, - 42, 2, 1, 234, 61, 42, 2, 1, 74, 42, 2, 1, 210, 53, 42, 2, 1, 233, 248, - 42, 2, 1, 233, 236, 42, 2, 1, 199, 140, 42, 2, 1, 69, 42, 2, 1, 234, 138, - 42, 2, 1, 144, 42, 2, 1, 197, 157, 42, 2, 1, 243, 79, 42, 2, 1, 203, 160, - 42, 2, 1, 203, 111, 42, 2, 1, 229, 240, 57, 42, 2, 1, 192, 58, 42, 2, 1, - 202, 27, 57, 42, 2, 1, 73, 42, 2, 1, 191, 225, 42, 2, 1, 169, 42, 2, 1, - 223, 198, 4, 230, 176, 42, 2, 1, 223, 60, 42, 2, 1, 236, 147, 42, 2, 1, - 230, 240, 42, 2, 1, 196, 121, 223, 197, 42, 2, 1, 234, 244, 42, 2, 1, - 247, 155, 70, 42, 2, 1, 192, 33, 42, 2, 1, 222, 238, 42, 2, 1, 219, 52, - 42, 2, 1, 213, 137, 42, 2, 1, 197, 151, 42, 2, 1, 221, 79, 42, 2, 1, 228, - 44, 4, 230, 176, 42, 2, 1, 203, 35, 69, 42, 2, 1, 234, 240, 42, 6, 1, - 211, 99, 42, 2, 1, 211, 99, 42, 6, 1, 192, 95, 42, 2, 1, 192, 95, 42, 6, - 1, 223, 53, 73, 42, 2, 1, 223, 53, 73, 42, 6, 1, 219, 59, 191, 190, 42, - 2, 1, 219, 59, 191, 190, 42, 6, 1, 223, 53, 219, 59, 191, 190, 42, 2, 1, - 223, 53, 219, 59, 191, 190, 42, 6, 1, 248, 127, 191, 190, 42, 2, 1, 248, - 127, 191, 190, 42, 6, 1, 223, 53, 248, 127, 191, 190, 42, 2, 1, 223, 53, - 248, 127, 191, 190, 42, 6, 1, 220, 224, 42, 2, 1, 220, 224, 42, 6, 1, - 208, 169, 42, 2, 1, 208, 169, 42, 6, 1, 232, 187, 42, 2, 1, 232, 187, 42, - 6, 1, 223, 9, 42, 2, 1, 223, 9, 42, 6, 1, 223, 10, 4, 54, 230, 177, 252, - 8, 42, 2, 1, 223, 10, 4, 54, 230, 177, 252, 8, 42, 6, 1, 196, 124, 42, 2, - 1, 196, 124, 42, 6, 1, 206, 110, 211, 99, 42, 2, 1, 206, 110, 211, 99, - 42, 6, 1, 211, 100, 4, 198, 117, 42, 2, 1, 211, 100, 4, 198, 117, 42, 6, - 1, 211, 20, 42, 2, 1, 211, 20, 42, 6, 1, 221, 11, 42, 2, 1, 221, 11, 42, - 198, 224, 57, 33, 42, 198, 117, 33, 42, 210, 181, 33, 42, 237, 168, 209, - 67, 33, 42, 208, 163, 209, 67, 33, 42, 209, 47, 33, 42, 228, 110, 198, - 224, 57, 33, 42, 216, 30, 57, 42, 6, 1, 203, 35, 228, 44, 4, 199, 210, - 42, 2, 1, 203, 35, 228, 44, 4, 199, 210, 42, 6, 1, 204, 16, 57, 42, 2, 1, - 204, 16, 57, 42, 6, 1, 233, 249, 4, 198, 177, 42, 2, 1, 233, 249, 4, 198, - 177, 42, 6, 1, 231, 41, 4, 196, 65, 42, 2, 1, 231, 41, 4, 196, 65, 42, 6, - 1, 231, 41, 4, 105, 42, 2, 1, 231, 41, 4, 105, 42, 6, 1, 231, 41, 4, 82, - 106, 42, 2, 1, 231, 41, 4, 82, 106, 42, 6, 1, 191, 63, 4, 237, 42, 42, 2, - 1, 191, 63, 4, 237, 42, 42, 6, 1, 191, 88, 4, 237, 42, 42, 2, 1, 191, 88, - 4, 237, 42, 42, 6, 1, 222, 115, 4, 237, 42, 42, 2, 1, 222, 115, 4, 237, - 42, 42, 6, 1, 222, 115, 4, 81, 105, 42, 2, 1, 222, 115, 4, 81, 105, 42, - 6, 1, 222, 115, 4, 105, 42, 2, 1, 222, 115, 4, 105, 42, 6, 1, 249, 20, - 157, 42, 2, 1, 249, 20, 157, 42, 6, 1, 234, 62, 4, 237, 42, 42, 2, 1, - 234, 62, 4, 237, 42, 42, 6, 34, 234, 62, 231, 40, 42, 2, 34, 234, 62, - 231, 40, 42, 6, 1, 210, 54, 4, 82, 106, 42, 2, 1, 210, 54, 4, 82, 106, - 42, 6, 1, 252, 15, 144, 42, 2, 1, 252, 15, 144, 42, 6, 1, 233, 237, 4, - 237, 42, 42, 2, 1, 233, 237, 4, 237, 42, 42, 6, 1, 199, 141, 4, 237, 42, - 42, 2, 1, 199, 141, 4, 237, 42, 42, 6, 1, 201, 48, 69, 42, 2, 1, 201, 48, - 69, 42, 6, 1, 201, 48, 126, 4, 105, 42, 2, 1, 201, 48, 126, 4, 105, 42, - 6, 1, 230, 72, 4, 237, 42, 42, 2, 1, 230, 72, 4, 237, 42, 42, 6, 34, 199, - 141, 197, 157, 42, 2, 34, 199, 141, 197, 157, 42, 6, 1, 243, 80, 4, 237, - 42, 42, 2, 1, 243, 80, 4, 237, 42, 42, 6, 1, 243, 80, 4, 81, 105, 42, 2, - 1, 243, 80, 4, 81, 105, 42, 6, 1, 203, 77, 42, 2, 1, 203, 77, 42, 6, 1, - 252, 15, 243, 79, 42, 2, 1, 252, 15, 243, 79, 42, 6, 1, 252, 15, 243, 80, - 4, 237, 42, 42, 2, 1, 252, 15, 243, 80, 4, 237, 42, 42, 1, 210, 169, 42, - 6, 1, 191, 63, 4, 247, 244, 42, 2, 1, 191, 63, 4, 247, 244, 42, 6, 1, - 222, 115, 4, 106, 42, 2, 1, 222, 115, 4, 106, 42, 6, 1, 234, 98, 4, 199, - 210, 42, 2, 1, 234, 98, 4, 199, 210, 42, 6, 1, 234, 62, 4, 106, 42, 2, 1, - 234, 62, 4, 106, 42, 6, 1, 234, 62, 4, 199, 210, 42, 2, 1, 234, 62, 4, - 199, 210, 42, 6, 1, 221, 183, 243, 79, 42, 2, 1, 221, 183, 243, 79, 42, - 6, 1, 234, 73, 4, 199, 210, 42, 2, 1, 234, 73, 4, 199, 210, 42, 2, 1, - 210, 169, 42, 6, 1, 41, 4, 247, 244, 42, 2, 1, 41, 4, 247, 244, 42, 6, 1, - 41, 4, 236, 253, 42, 2, 1, 41, 4, 236, 253, 42, 6, 34, 41, 223, 197, 42, - 2, 34, 41, 223, 197, 42, 6, 1, 223, 198, 4, 247, 244, 42, 2, 1, 223, 198, - 4, 247, 244, 42, 6, 1, 205, 81, 42, 2, 1, 205, 81, 42, 6, 1, 205, 82, 4, - 236, 253, 42, 2, 1, 205, 82, 4, 236, 253, 42, 6, 1, 191, 63, 4, 236, 253, - 42, 2, 1, 191, 63, 4, 236, 253, 42, 6, 1, 191, 88, 4, 236, 253, 42, 2, 1, - 191, 88, 4, 236, 253, 42, 6, 1, 252, 15, 234, 244, 42, 2, 1, 252, 15, - 234, 244, 42, 6, 1, 228, 44, 4, 217, 125, 42, 2, 1, 228, 44, 4, 217, 125, - 42, 6, 1, 228, 44, 4, 236, 253, 42, 2, 1, 228, 44, 4, 236, 253, 42, 6, 1, - 186, 4, 236, 253, 42, 2, 1, 186, 4, 236, 253, 42, 6, 1, 249, 32, 74, 42, - 2, 1, 249, 32, 74, 42, 6, 1, 249, 32, 186, 4, 236, 253, 42, 2, 1, 249, - 32, 186, 4, 236, 253, 42, 6, 1, 234, 227, 4, 236, 253, 42, 2, 1, 234, - 227, 4, 236, 253, 42, 6, 1, 126, 4, 217, 125, 42, 2, 1, 126, 4, 217, 125, - 42, 6, 1, 126, 4, 236, 253, 42, 2, 1, 126, 4, 236, 253, 42, 6, 1, 126, 4, - 54, 251, 250, 42, 2, 1, 126, 4, 54, 251, 250, 42, 6, 1, 243, 80, 4, 236, - 253, 42, 2, 1, 243, 80, 4, 236, 253, 42, 6, 1, 231, 41, 4, 237, 42, 42, - 2, 1, 231, 41, 4, 237, 42, 42, 6, 1, 192, 59, 4, 236, 253, 42, 2, 1, 192, - 59, 4, 236, 253, 42, 6, 1, 231, 41, 4, 201, 23, 24, 106, 42, 2, 1, 231, - 41, 4, 201, 23, 24, 106, 42, 6, 1, 230, 72, 4, 106, 42, 2, 1, 230, 72, 4, - 106, 42, 6, 1, 230, 72, 4, 105, 42, 2, 1, 230, 72, 4, 105, 42, 6, 1, 221, - 21, 237, 101, 42, 2, 1, 221, 21, 237, 101, 42, 6, 1, 221, 21, 236, 147, - 42, 2, 1, 221, 21, 236, 147, 42, 6, 1, 221, 21, 191, 12, 42, 2, 1, 221, - 21, 191, 12, 42, 6, 1, 221, 21, 234, 236, 42, 2, 1, 221, 21, 234, 236, - 42, 6, 1, 221, 21, 219, 52, 42, 2, 1, 221, 21, 219, 52, 42, 6, 1, 221, - 21, 213, 137, 42, 2, 1, 221, 21, 213, 137, 42, 6, 1, 221, 21, 202, 110, - 42, 2, 1, 221, 21, 202, 110, 42, 6, 1, 221, 21, 198, 111, 42, 2, 1, 221, - 21, 198, 111, 42, 6, 1, 207, 13, 191, 87, 42, 2, 1, 207, 13, 191, 87, 42, - 6, 1, 234, 98, 4, 106, 42, 2, 1, 234, 98, 4, 106, 42, 6, 1, 219, 135, 42, - 2, 1, 219, 135, 42, 6, 1, 207, 1, 42, 2, 1, 207, 1, 42, 6, 1, 192, 129, - 42, 2, 1, 192, 129, 42, 6, 1, 208, 89, 42, 2, 1, 208, 89, 42, 6, 1, 193, - 123, 42, 2, 1, 193, 123, 42, 6, 1, 251, 137, 157, 42, 2, 1, 251, 137, - 157, 42, 6, 1, 234, 98, 4, 82, 106, 42, 2, 1, 234, 98, 4, 82, 106, 42, 6, - 1, 234, 62, 4, 82, 106, 42, 2, 1, 234, 62, 4, 82, 106, 42, 6, 1, 210, 54, - 4, 237, 42, 42, 2, 1, 210, 54, 4, 237, 42, 42, 6, 1, 203, 78, 4, 237, 42, - 42, 2, 1, 203, 78, 4, 237, 42, 42, 6, 1, 234, 62, 4, 45, 106, 42, 2, 1, - 234, 62, 4, 45, 106, 42, 6, 1, 234, 228, 42, 2, 1, 234, 228, 42, 6, 1, - 237, 150, 42, 2, 1, 237, 150, 42, 6, 1, 234, 98, 4, 237, 42, 42, 2, 1, - 234, 98, 4, 237, 42, 250, 199, 6, 1, 250, 78, 250, 199, 6, 1, 248, 179, - 250, 199, 6, 1, 231, 3, 250, 199, 6, 1, 237, 241, 250, 199, 6, 1, 234, - 151, 250, 199, 6, 1, 191, 123, 250, 199, 6, 1, 234, 130, 250, 199, 6, 1, - 233, 213, 250, 199, 6, 1, 159, 250, 199, 6, 1, 191, 62, 250, 199, 6, 1, - 223, 103, 250, 199, 6, 1, 219, 56, 250, 199, 6, 1, 192, 212, 250, 199, 6, - 1, 247, 112, 250, 199, 6, 1, 221, 226, 250, 199, 6, 1, 228, 247, 250, - 199, 6, 1, 223, 4, 250, 199, 6, 1, 231, 51, 250, 199, 6, 1, 243, 69, 250, - 199, 6, 1, 216, 167, 250, 199, 6, 1, 192, 33, 250, 199, 6, 1, 212, 240, - 250, 199, 6, 1, 203, 160, 250, 199, 6, 1, 195, 21, 250, 199, 6, 1, 246, - 209, 250, 199, 6, 1, 210, 32, 250, 199, 6, 1, 222, 220, 250, 199, 6, 1, - 166, 250, 199, 6, 1, 205, 34, 250, 199, 6, 1, 195, 71, 250, 199, 6, 1, - 198, 114, 250, 199, 6, 1, 207, 66, 250, 199, 6, 1, 242, 51, 250, 199, 6, - 1, 192, 17, 250, 199, 6, 1, 209, 106, 250, 199, 6, 1, 221, 237, 250, 199, - 6, 1, 211, 124, 250, 199, 6, 1, 233, 5, 250, 199, 59, 1, 45, 134, 206, - 183, 250, 199, 250, 255, 250, 199, 234, 65, 77, 250, 199, 233, 175, 77, - 250, 199, 242, 26, 250, 199, 208, 8, 77, 250, 199, 252, 16, 77, 250, 199, - 2, 1, 152, 250, 78, 250, 199, 2, 1, 250, 78, 250, 199, 2, 1, 248, 179, - 250, 199, 2, 1, 231, 3, 250, 199, 2, 1, 237, 241, 250, 199, 2, 1, 234, - 151, 250, 199, 2, 1, 191, 123, 250, 199, 2, 1, 234, 130, 250, 199, 2, 1, - 233, 213, 250, 199, 2, 1, 159, 250, 199, 2, 1, 191, 62, 250, 199, 2, 1, - 223, 103, 250, 199, 2, 1, 219, 56, 250, 199, 2, 1, 192, 212, 250, 199, 2, - 1, 247, 112, 250, 199, 2, 1, 221, 226, 250, 199, 2, 1, 228, 247, 250, - 199, 2, 1, 223, 4, 250, 199, 2, 1, 231, 51, 250, 199, 2, 1, 243, 69, 250, - 199, 2, 1, 216, 167, 250, 199, 2, 1, 192, 33, 250, 199, 2, 1, 212, 240, - 250, 199, 2, 1, 203, 160, 250, 199, 2, 1, 195, 21, 250, 199, 2, 1, 246, - 209, 250, 199, 2, 1, 210, 32, 250, 199, 2, 1, 222, 220, 250, 199, 2, 1, - 166, 250, 199, 2, 1, 205, 34, 250, 199, 2, 1, 195, 71, 250, 199, 2, 1, - 198, 114, 250, 199, 2, 1, 207, 66, 250, 199, 2, 1, 242, 51, 250, 199, 2, - 1, 192, 17, 250, 199, 2, 1, 209, 106, 250, 199, 2, 1, 221, 237, 250, 199, - 2, 1, 211, 124, 250, 199, 2, 1, 233, 5, 250, 199, 2, 34, 234, 152, 192, - 17, 250, 199, 2, 1, 11, 4, 105, 250, 199, 232, 42, 201, 58, 250, 199, - 228, 58, 206, 202, 250, 199, 233, 209, 57, 219, 199, 250, 199, 233, 209, - 57, 250, 199, 235, 66, 57, 135, 252, 9, 233, 204, 135, 252, 9, 205, 35, - 135, 252, 9, 203, 136, 135, 252, 9, 191, 99, 208, 72, 135, 252, 9, 191, - 99, 231, 193, 135, 252, 9, 198, 129, 135, 252, 9, 207, 10, 135, 252, 9, - 191, 97, 135, 252, 9, 210, 87, 135, 252, 9, 192, 48, 135, 252, 9, 199, - 51, 135, 252, 9, 231, 102, 135, 252, 9, 231, 103, 215, 96, 135, 252, 9, - 231, 100, 135, 252, 9, 208, 73, 210, 120, 135, 252, 9, 199, 98, 231, 121, - 135, 252, 9, 210, 59, 135, 252, 9, 250, 123, 230, 52, 135, 252, 9, 215, - 106, 135, 252, 9, 217, 96, 135, 252, 9, 216, 156, 135, 252, 9, 216, 157, - 221, 238, 135, 252, 9, 237, 177, 135, 252, 9, 208, 84, 135, 252, 9, 199, - 98, 208, 67, 135, 252, 9, 192, 61, 248, 180, 191, 247, 135, 252, 9, 211, - 106, 135, 252, 9, 223, 155, 135, 252, 9, 237, 78, 135, 252, 9, 191, 19, - 135, 87, 217, 15, 242, 218, 135, 209, 55, 203, 80, 135, 209, 55, 229, - 231, 205, 35, 135, 209, 55, 229, 231, 210, 78, 135, 209, 55, 229, 231, - 208, 77, 135, 209, 55, 229, 87, 135, 209, 55, 197, 154, 135, 209, 55, - 205, 35, 135, 209, 55, 210, 78, 135, 209, 55, 208, 77, 135, 209, 55, 228, - 231, 135, 209, 55, 228, 232, 229, 233, 39, 195, 155, 135, 209, 55, 208, - 13, 135, 209, 55, 237, 226, 211, 46, 217, 50, 135, 209, 55, 216, 145, - 135, 208, 145, 217, 47, 135, 209, 55, 207, 156, 135, 208, 145, 210, 89, - 135, 209, 55, 203, 65, 236, 96, 135, 209, 55, 202, 170, 236, 96, 135, - 208, 145, 202, 28, 210, 80, 135, 87, 116, 236, 96, 135, 87, 110, 236, 96, - 135, 208, 145, 212, 118, 230, 51, 135, 209, 55, 208, 78, 208, 72, 135, 1, - 251, 141, 135, 1, 248, 164, 135, 1, 231, 1, 135, 1, 237, 206, 135, 1, - 229, 213, 135, 1, 195, 155, 135, 1, 191, 91, 135, 1, 229, 154, 135, 1, - 199, 68, 135, 1, 191, 250, 135, 1, 52, 222, 79, 135, 1, 222, 79, 135, 1, - 220, 3, 135, 1, 52, 216, 174, 135, 1, 216, 174, 135, 1, 52, 212, 117, - 135, 1, 212, 117, 135, 1, 205, 143, 135, 1, 250, 76, 135, 1, 52, 210, 53, - 135, 1, 210, 53, 135, 1, 52, 197, 159, 135, 1, 197, 159, 135, 1, 208, 36, - 135, 1, 207, 33, 135, 1, 203, 64, 135, 1, 199, 157, 135, 191, 251, 197, - 237, 135, 34, 192, 31, 54, 195, 155, 135, 34, 192, 31, 195, 156, 191, - 250, 135, 34, 192, 31, 54, 191, 250, 135, 208, 145, 231, 102, 135, 208, - 145, 231, 100, 9, 31, 57, 9, 3, 205, 136, 9, 232, 118, 217, 32, 9, 3, - 205, 182, 9, 3, 205, 139, 9, 31, 87, 56, 250, 234, 238, 144, 206, 123, - 250, 234, 232, 83, 206, 123, 9, 207, 117, 250, 234, 210, 5, 216, 32, 57, - 250, 234, 210, 5, 199, 91, 198, 225, 57, 251, 206, 57, 9, 242, 26, 9, - 237, 164, 204, 5, 9, 209, 57, 195, 134, 57, 9, 3, 216, 8, 9, 3, 205, 156, - 251, 148, 193, 147, 9, 3, 251, 148, 250, 148, 9, 3, 207, 152, 251, 147, - 9, 3, 207, 162, 251, 119, 251, 54, 9, 3, 199, 201, 9, 2, 136, 199, 214, - 9, 2, 136, 34, 130, 4, 220, 12, 4, 192, 75, 9, 2, 136, 191, 113, 9, 2, - 233, 29, 9, 2, 237, 200, 9, 2, 222, 26, 9, 204, 20, 9, 1, 77, 9, 234, 53, - 80, 199, 49, 77, 9, 197, 221, 75, 208, 145, 77, 9, 208, 8, 77, 9, 1, 222, - 30, 192, 75, 9, 1, 230, 24, 9, 1, 130, 4, 217, 121, 56, 9, 1, 130, 4, - 230, 25, 56, 9, 1, 193, 132, 4, 230, 25, 56, 9, 1, 130, 4, 230, 25, 60, - 9, 1, 99, 4, 230, 25, 56, 9, 1, 251, 141, 9, 1, 248, 195, 9, 1, 199, 110, - 217, 43, 9, 1, 199, 109, 9, 1, 199, 24, 9, 1, 222, 234, 9, 1, 230, 48, 9, - 1, 221, 185, 9, 1, 237, 212, 9, 1, 199, 36, 9, 1, 207, 66, 9, 1, 191, - 113, 9, 1, 205, 41, 9, 1, 203, 104, 9, 1, 205, 187, 9, 1, 237, 235, 9, 1, - 199, 214, 9, 1, 191, 116, 9, 1, 251, 178, 9, 1, 231, 49, 9, 1, 221, 236, - 4, 103, 183, 56, 9, 1, 221, 236, 4, 115, 183, 60, 9, 1, 233, 33, 99, 4, - 223, 65, 196, 8, 9, 1, 233, 33, 99, 4, 103, 183, 56, 9, 1, 233, 33, 99, - 4, 115, 183, 56, 9, 199, 163, 9, 1, 233, 5, 9, 1, 208, 82, 9, 1, 222, 79, - 9, 1, 220, 11, 9, 1, 216, 189, 9, 1, 213, 11, 9, 1, 229, 178, 9, 1, 193, - 131, 9, 1, 130, 217, 79, 9, 1, 192, 75, 9, 233, 27, 9, 237, 198, 9, 222, - 24, 9, 233, 29, 9, 237, 200, 9, 222, 26, 9, 203, 150, 9, 200, 201, 9, - 217, 119, 56, 9, 230, 25, 56, 9, 230, 25, 60, 9, 200, 225, 251, 141, 9, - 223, 65, 237, 200, 9, 87, 213, 12, 231, 20, 9, 190, 237, 9, 18, 3, 2, - 196, 9, 56, 9, 18, 3, 223, 65, 2, 196, 9, 56, 9, 18, 3, 75, 60, 9, 207, - 13, 237, 200, 9, 233, 30, 4, 103, 236, 94, 9, 193, 133, 230, 25, 60, 250, - 234, 17, 191, 77, 250, 234, 17, 108, 250, 234, 17, 109, 250, 234, 17, - 139, 250, 234, 17, 137, 250, 234, 17, 153, 250, 234, 17, 173, 250, 234, - 17, 181, 250, 234, 17, 176, 250, 234, 17, 184, 9, 210, 4, 57, 9, 237, 93, - 204, 5, 9, 198, 224, 204, 5, 9, 232, 185, 209, 53, 201, 97, 9, 1, 236, - 95, 248, 195, 9, 1, 236, 95, 208, 82, 9, 1, 200, 177, 251, 141, 9, 1, - 130, 193, 148, 9, 1, 130, 4, 193, 133, 230, 25, 56, 9, 1, 130, 4, 193, - 133, 230, 25, 60, 9, 1, 136, 230, 24, 9, 1, 136, 230, 25, 251, 141, 9, 1, - 136, 230, 25, 193, 131, 9, 1, 126, 4, 230, 25, 56, 9, 1, 136, 230, 25, - 192, 75, 9, 1, 197, 120, 9, 1, 197, 118, 9, 1, 248, 205, 9, 1, 199, 110, - 4, 206, 183, 9, 1, 199, 110, 4, 115, 183, 95, 235, 74, 9, 1, 210, 32, 9, - 1, 199, 107, 9, 1, 248, 193, 9, 1, 179, 4, 230, 25, 56, 9, 1, 179, 4, - 103, 183, 81, 56, 9, 1, 212, 74, 9, 1, 234, 253, 9, 1, 179, 4, 115, 183, - 56, 9, 1, 199, 144, 9, 1, 199, 142, 9, 1, 237, 141, 9, 1, 237, 213, 4, - 206, 183, 9, 1, 237, 213, 4, 75, 60, 9, 1, 237, 213, 4, 75, 248, 183, 24, - 2, 199, 214, 9, 1, 237, 219, 9, 1, 237, 143, 9, 1, 235, 34, 9, 1, 237, - 213, 4, 115, 183, 95, 235, 74, 9, 1, 237, 213, 4, 232, 90, 183, 56, 9, 1, - 206, 96, 9, 1, 207, 67, 4, 2, 196, 8, 9, 1, 207, 67, 4, 206, 183, 9, 1, - 207, 67, 4, 75, 60, 9, 1, 207, 67, 4, 2, 196, 9, 60, 9, 1, 207, 67, 4, - 75, 248, 183, 24, 75, 56, 9, 1, 207, 67, 4, 103, 183, 56, 9, 1, 222, 231, - 9, 1, 207, 67, 4, 232, 90, 183, 56, 9, 1, 205, 42, 4, 75, 248, 183, 24, - 75, 56, 9, 1, 205, 42, 4, 115, 183, 60, 9, 1, 205, 42, 4, 115, 183, 248, - 183, 24, 115, 183, 56, 9, 1, 205, 188, 4, 103, 183, 60, 9, 1, 205, 188, - 4, 115, 183, 56, 9, 1, 199, 215, 4, 115, 183, 56, 9, 1, 251, 179, 4, 115, - 183, 56, 9, 1, 236, 95, 233, 5, 9, 1, 233, 6, 4, 75, 215, 161, 60, 9, 1, - 233, 6, 4, 75, 60, 9, 1, 195, 143, 9, 1, 233, 6, 4, 115, 183, 60, 9, 1, - 210, 30, 9, 1, 208, 83, 4, 75, 56, 9, 1, 208, 83, 4, 115, 183, 56, 9, 1, - 221, 235, 9, 1, 200, 142, 222, 79, 9, 1, 222, 80, 4, 206, 183, 9, 1, 222, - 80, 4, 75, 56, 9, 1, 214, 56, 9, 1, 222, 80, 4, 115, 183, 60, 9, 1, 231, - 190, 9, 1, 231, 191, 4, 206, 183, 9, 1, 213, 233, 9, 1, 231, 191, 4, 103, - 183, 60, 9, 1, 230, 133, 9, 1, 231, 191, 4, 115, 183, 56, 9, 1, 220, 12, - 4, 2, 196, 8, 9, 1, 220, 12, 4, 75, 56, 9, 1, 220, 12, 4, 115, 183, 56, - 9, 1, 220, 12, 4, 115, 183, 60, 9, 1, 213, 12, 4, 75, 60, 9, 1, 213, 12, - 231, 20, 9, 1, 206, 160, 9, 1, 213, 12, 4, 206, 183, 9, 1, 213, 12, 4, - 115, 183, 56, 9, 1, 229, 179, 236, 125, 9, 1, 199, 145, 4, 75, 56, 9, 1, - 229, 179, 4, 99, 56, 9, 1, 229, 179, 230, 220, 9, 1, 229, 179, 230, 221, - 4, 230, 25, 56, 9, 1, 199, 110, 217, 44, 230, 220, 9, 1, 193, 132, 4, - 206, 183, 9, 1, 221, 108, 211, 139, 9, 1, 211, 139, 9, 1, 69, 9, 1, 191, - 225, 9, 1, 221, 108, 191, 225, 9, 1, 193, 132, 4, 103, 183, 56, 9, 1, - 195, 150, 9, 1, 233, 33, 192, 75, 9, 1, 99, 4, 199, 210, 9, 1, 99, 4, 2, - 196, 8, 9, 1, 193, 132, 4, 75, 56, 9, 1, 73, 9, 1, 99, 4, 115, 183, 60, - 9, 1, 99, 249, 30, 9, 1, 99, 249, 31, 4, 230, 25, 56, 9, 232, 42, 201, - 58, 9, 1, 251, 229, 9, 2, 136, 34, 205, 188, 4, 220, 12, 4, 130, 217, 79, - 9, 2, 136, 34, 208, 83, 4, 220, 12, 4, 130, 217, 79, 9, 2, 136, 92, 89, - 20, 9, 2, 136, 220, 12, 251, 141, 9, 2, 136, 222, 234, 9, 2, 136, 115, - 236, 94, 9, 2, 136, 205, 41, 9, 234, 53, 80, 250, 80, 9, 201, 93, 80, - 206, 55, 234, 98, 229, 82, 9, 2, 136, 206, 108, 191, 77, 9, 2, 136, 196, - 69, 207, 86, 191, 77, 9, 2, 136, 236, 95, 229, 204, 80, 221, 185, 9, 2, - 136, 92, 76, 20, 9, 2, 131, 205, 41, 9, 2, 136, 217, 120, 9, 2, 193, 131, - 9, 2, 192, 75, 9, 2, 136, 192, 75, 9, 2, 136, 213, 11, 9, 209, 100, 80, - 205, 172, 9, 234, 63, 246, 230, 131, 201, 58, 9, 234, 63, 246, 230, 136, - 201, 58, 9, 206, 108, 136, 201, 59, 4, 232, 219, 246, 229, 9, 2, 131, - 216, 189, 9, 1, 237, 213, 4, 223, 65, 196, 8, 9, 1, 207, 67, 4, 223, 65, - 196, 8, 233, 164, 250, 234, 17, 191, 77, 233, 164, 250, 234, 17, 108, - 233, 164, 250, 234, 17, 109, 233, 164, 250, 234, 17, 139, 233, 164, 250, - 234, 17, 137, 233, 164, 250, 234, 17, 153, 233, 164, 250, 234, 17, 173, - 233, 164, 250, 234, 17, 181, 233, 164, 250, 234, 17, 176, 233, 164, 250, - 234, 17, 184, 9, 1, 203, 105, 4, 75, 60, 9, 1, 237, 236, 4, 75, 60, 9, 1, - 231, 50, 4, 75, 60, 9, 3, 202, 168, 251, 86, 9, 3, 202, 168, 209, 9, 216, - 167, 9, 1, 229, 179, 4, 223, 65, 196, 8, 200, 59, 234, 53, 80, 210, 117, - 200, 59, 200, 172, 232, 42, 201, 58, 200, 59, 200, 227, 232, 42, 201, 58, - 200, 59, 200, 172, 242, 35, 200, 59, 200, 227, 242, 35, 200, 59, 228, - 209, 242, 35, 200, 59, 242, 36, 202, 105, 219, 200, 200, 59, 242, 36, - 202, 105, 187, 200, 59, 200, 172, 242, 36, 202, 105, 219, 200, 200, 59, - 200, 227, 242, 36, 202, 105, 187, 200, 59, 238, 233, 200, 59, 229, 238, - 211, 163, 200, 59, 229, 238, 216, 143, 200, 59, 229, 238, 250, 145, 200, - 59, 252, 16, 77, 200, 59, 1, 251, 151, 200, 59, 1, 200, 177, 251, 151, - 200, 59, 1, 248, 161, 200, 59, 1, 231, 180, 200, 59, 1, 231, 181, 231, - 157, 200, 59, 1, 237, 209, 200, 59, 1, 236, 95, 237, 210, 206, 176, 200, - 59, 1, 229, 213, 200, 59, 1, 193, 131, 200, 59, 1, 191, 113, 200, 59, 1, - 229, 152, 200, 59, 1, 199, 64, 200, 59, 1, 199, 65, 231, 157, 200, 59, 1, - 191, 208, 200, 59, 1, 191, 209, 229, 213, 200, 59, 1, 222, 49, 200, 59, - 1, 220, 10, 200, 59, 1, 216, 28, 200, 59, 1, 212, 117, 200, 59, 1, 204, - 13, 200, 59, 1, 52, 204, 13, 200, 59, 1, 73, 200, 59, 1, 210, 53, 200, - 59, 1, 207, 13, 210, 53, 200, 59, 1, 205, 184, 200, 59, 1, 208, 76, 200, - 59, 1, 206, 176, 200, 59, 1, 203, 64, 200, 59, 1, 199, 154, 200, 59, 1, - 209, 243, 248, 146, 200, 59, 1, 209, 243, 231, 47, 200, 59, 1, 209, 243, - 237, 18, 200, 59, 208, 159, 56, 200, 59, 208, 159, 60, 200, 59, 208, 159, - 235, 93, 200, 59, 191, 0, 56, 200, 59, 191, 0, 60, 200, 59, 191, 0, 235, - 93, 200, 59, 207, 111, 56, 200, 59, 207, 111, 60, 200, 59, 235, 94, 191, - 9, 228, 208, 200, 59, 235, 94, 191, 9, 251, 57, 200, 59, 229, 218, 56, - 200, 59, 229, 218, 60, 200, 59, 229, 217, 235, 93, 200, 59, 233, 230, 56, - 200, 59, 233, 230, 60, 200, 59, 206, 19, 200, 59, 232, 255, 236, 96, 200, - 59, 207, 241, 200, 59, 206, 49, 200, 59, 103, 81, 183, 56, 200, 59, 103, - 81, 183, 60, 200, 59, 115, 183, 56, 200, 59, 115, 183, 60, 200, 59, 211, - 159, 219, 89, 56, 200, 59, 211, 159, 219, 89, 60, 200, 59, 215, 82, 200, - 59, 249, 29, 200, 59, 1, 202, 23, 191, 69, 200, 59, 1, 202, 23, 221, 177, - 200, 59, 1, 202, 23, 233, 18, 9, 1, 248, 196, 4, 115, 183, 228, 158, 60, - 9, 1, 248, 196, 4, 75, 248, 183, 24, 115, 183, 56, 9, 1, 248, 196, 4, - 115, 183, 209, 51, 196, 62, 60, 9, 1, 248, 196, 4, 115, 183, 209, 51, - 196, 62, 248, 183, 24, 103, 183, 56, 9, 1, 248, 196, 4, 103, 183, 248, - 183, 24, 75, 56, 9, 1, 248, 196, 4, 223, 65, 2, 196, 9, 60, 9, 1, 248, - 196, 4, 2, 196, 8, 9, 1, 179, 4, 103, 183, 56, 9, 1, 179, 4, 115, 183, - 209, 51, 196, 62, 60, 9, 1, 237, 213, 4, 103, 183, 195, 82, 248, 183, 24, - 2, 199, 214, 9, 1, 237, 213, 4, 223, 65, 2, 196, 9, 60, 9, 1, 207, 67, 4, - 105, 9, 1, 205, 42, 4, 232, 90, 183, 56, 9, 1, 251, 179, 4, 103, 183, 56, - 9, 1, 251, 179, 4, 115, 183, 209, 51, 235, 75, 56, 9, 1, 251, 179, 4, - 103, 183, 195, 82, 56, 9, 1, 233, 6, 4, 103, 183, 60, 9, 1, 233, 6, 4, - 115, 183, 209, 51, 196, 62, 60, 9, 1, 221, 236, 4, 75, 56, 9, 1, 221, - 236, 4, 115, 183, 56, 9, 1, 221, 236, 4, 115, 183, 209, 51, 196, 62, 60, - 9, 1, 92, 4, 75, 56, 9, 1, 92, 4, 75, 60, 9, 1, 213, 12, 4, 103, 183, 60, - 9, 1, 213, 12, 4, 2, 199, 214, 9, 1, 213, 12, 4, 2, 196, 8, 9, 1, 220, - 12, 4, 164, 9, 1, 207, 67, 4, 103, 183, 195, 82, 56, 9, 1, 207, 67, 4, - 230, 25, 56, 9, 1, 205, 42, 4, 103, 183, 195, 82, 56, 9, 1, 179, 4, 2, 9, - 1, 199, 215, 60, 9, 1, 179, 4, 2, 9, 1, 199, 215, 24, 103, 236, 94, 9, 1, - 205, 42, 4, 2, 9, 1, 199, 215, 24, 103, 236, 94, 9, 1, 207, 67, 4, 2, 9, - 1, 199, 215, 24, 103, 236, 94, 9, 1, 179, 4, 2, 9, 1, 199, 215, 56, 9, 1, - 130, 4, 233, 164, 250, 234, 17, 103, 56, 9, 1, 130, 4, 233, 164, 250, - 234, 17, 115, 56, 9, 1, 233, 33, 99, 4, 233, 164, 250, 234, 17, 103, 56, - 9, 1, 233, 33, 99, 4, 233, 164, 250, 234, 17, 115, 56, 9, 1, 233, 33, 99, - 4, 233, 164, 250, 234, 17, 232, 90, 60, 9, 1, 193, 132, 4, 233, 164, 250, - 234, 17, 103, 56, 9, 1, 193, 132, 4, 233, 164, 250, 234, 17, 115, 56, 9, - 1, 99, 249, 31, 4, 233, 164, 250, 234, 17, 103, 56, 9, 1, 99, 249, 31, 4, - 233, 164, 250, 234, 17, 115, 56, 9, 1, 179, 4, 233, 164, 250, 234, 17, - 232, 90, 60, 9, 1, 205, 42, 4, 233, 164, 250, 234, 17, 232, 90, 56, 9, 1, - 205, 42, 4, 223, 65, 196, 8, 9, 1, 222, 80, 4, 103, 183, 56, 199, 41, 1, - 230, 58, 199, 41, 1, 203, 114, 199, 41, 1, 213, 10, 199, 41, 1, 207, 173, - 199, 41, 1, 249, 101, 199, 41, 1, 219, 132, 199, 41, 1, 222, 95, 199, 41, - 1, 251, 128, 199, 41, 1, 195, 183, 199, 41, 1, 216, 188, 199, 41, 1, 233, - 66, 199, 41, 1, 237, 21, 199, 41, 1, 199, 43, 199, 41, 1, 220, 98, 199, - 41, 1, 231, 199, 199, 41, 1, 230, 226, 199, 41, 1, 205, 40, 199, 41, 1, - 237, 162, 199, 41, 1, 191, 94, 199, 41, 1, 199, 156, 199, 41, 1, 192, - 140, 199, 41, 1, 210, 67, 199, 41, 1, 222, 243, 199, 41, 1, 243, 82, 199, - 41, 1, 197, 127, 199, 41, 1, 229, 144, 199, 41, 1, 221, 189, 199, 41, 1, - 199, 42, 199, 41, 1, 191, 121, 199, 41, 1, 203, 103, 199, 41, 1, 205, - 191, 199, 41, 1, 237, 239, 199, 41, 1, 159, 199, 41, 1, 191, 7, 199, 41, - 1, 251, 175, 199, 41, 1, 231, 48, 199, 41, 1, 208, 86, 199, 41, 1, 193, - 175, 199, 41, 252, 18, 199, 41, 252, 119, 199, 41, 227, 255, 199, 41, - 234, 144, 199, 41, 196, 157, 199, 41, 211, 75, 199, 41, 234, 154, 199, - 41, 233, 154, 199, 41, 211, 158, 199, 41, 211, 168, 199, 41, 200, 201, - 199, 41, 1, 214, 236, 213, 94, 17, 191, 77, 213, 94, 17, 108, 213, 94, - 17, 109, 213, 94, 17, 139, 213, 94, 17, 137, 213, 94, 17, 153, 213, 94, - 17, 173, 213, 94, 17, 181, 213, 94, 17, 176, 213, 94, 17, 184, 213, 94, - 1, 65, 213, 94, 1, 234, 145, 213, 94, 1, 70, 213, 94, 1, 73, 213, 94, 1, - 69, 213, 94, 1, 211, 76, 213, 94, 1, 74, 213, 94, 1, 237, 227, 213, 94, - 1, 215, 47, 213, 94, 1, 249, 103, 213, 94, 1, 168, 213, 94, 1, 199, 247, - 213, 94, 1, 223, 4, 213, 94, 1, 246, 209, 213, 94, 1, 237, 241, 213, 94, - 1, 166, 213, 94, 1, 206, 104, 213, 94, 1, 189, 213, 94, 1, 231, 145, 213, - 94, 1, 233, 68, 213, 94, 1, 157, 213, 94, 1, 171, 213, 94, 1, 214, 249, - 193, 37, 213, 94, 1, 172, 213, 94, 1, 212, 88, 213, 94, 1, 180, 213, 94, - 1, 144, 213, 94, 1, 193, 187, 213, 94, 1, 169, 213, 94, 1, 212, 89, 193, - 37, 213, 94, 1, 222, 166, 223, 4, 213, 94, 1, 222, 166, 246, 209, 213, - 94, 1, 222, 166, 166, 213, 94, 33, 203, 35, 136, 198, 74, 213, 94, 33, - 203, 35, 131, 198, 74, 213, 94, 33, 203, 35, 206, 175, 198, 74, 213, 94, - 33, 177, 237, 41, 198, 74, 213, 94, 33, 177, 136, 198, 74, 213, 94, 33, - 177, 131, 198, 74, 213, 94, 33, 177, 206, 175, 198, 74, 213, 94, 33, 214, - 199, 77, 213, 94, 33, 54, 75, 56, 213, 94, 136, 163, 250, 255, 213, 94, - 131, 163, 250, 255, 213, 94, 16, 211, 77, 237, 56, 213, 94, 16, 231, 144, - 213, 94, 242, 26, 213, 94, 233, 175, 77, 213, 94, 220, 70, 213, 94, 237, - 188, 213, 94, 236, 98, 57, 213, 94, 199, 190, 57, 205, 146, 1, 251, 153, - 205, 146, 1, 248, 100, 205, 146, 1, 231, 179, 205, 146, 1, 237, 211, 205, - 146, 1, 223, 16, 205, 146, 1, 249, 101, 205, 146, 1, 191, 80, 205, 146, - 1, 223, 25, 205, 146, 1, 198, 120, 205, 146, 1, 191, 189, 205, 146, 1, - 222, 96, 205, 146, 1, 220, 94, 205, 146, 1, 216, 28, 205, 146, 1, 212, - 117, 205, 146, 1, 202, 166, 205, 146, 1, 223, 134, 205, 146, 1, 232, 238, - 205, 146, 1, 197, 162, 205, 146, 1, 208, 5, 205, 146, 1, 206, 176, 205, - 146, 1, 203, 133, 205, 146, 1, 199, 238, 205, 146, 87, 223, 134, 205, - 146, 87, 223, 133, 205, 146, 87, 211, 152, 205, 146, 87, 237, 225, 205, - 146, 59, 1, 234, 10, 191, 189, 205, 146, 87, 234, 10, 191, 189, 205, 146, - 18, 3, 177, 73, 205, 146, 18, 3, 73, 205, 146, 18, 3, 210, 243, 252, 154, - 205, 146, 18, 3, 177, 252, 154, 205, 146, 18, 3, 252, 154, 205, 146, 18, - 3, 210, 243, 65, 205, 146, 18, 3, 177, 65, 205, 146, 18, 3, 65, 205, 146, - 59, 1, 203, 35, 65, 205, 146, 18, 3, 203, 35, 65, 205, 146, 18, 3, 177, - 69, 205, 146, 18, 3, 69, 205, 146, 59, 1, 70, 205, 146, 18, 3, 177, 70, - 205, 146, 18, 3, 70, 205, 146, 18, 3, 74, 205, 146, 18, 3, 200, 201, 205, - 146, 87, 214, 79, 205, 146, 208, 145, 214, 79, 205, 146, 208, 145, 251, - 203, 205, 146, 208, 145, 251, 70, 205, 146, 208, 145, 249, 7, 205, 146, - 208, 145, 250, 124, 205, 146, 208, 145, 203, 52, 205, 146, 252, 16, 77, - 205, 146, 208, 145, 216, 178, 208, 42, 205, 146, 208, 145, 191, 16, 205, - 146, 208, 145, 208, 42, 205, 146, 208, 145, 191, 119, 205, 146, 208, 145, - 197, 50, 205, 146, 208, 145, 250, 205, 205, 146, 208, 145, 202, 28, 217, - 18, 205, 146, 208, 145, 251, 46, 217, 66, 1, 230, 32, 217, 66, 1, 252, - 103, 217, 66, 1, 251, 201, 217, 66, 1, 251, 246, 217, 66, 1, 251, 193, - 217, 66, 1, 196, 32, 217, 66, 1, 250, 73, 217, 66, 1, 223, 25, 217, 66, - 1, 250, 121, 217, 66, 1, 251, 160, 217, 66, 1, 251, 165, 217, 66, 1, 251, - 156, 217, 66, 1, 251, 98, 217, 66, 1, 251, 81, 217, 66, 1, 250, 169, 217, - 66, 1, 223, 134, 217, 66, 1, 251, 15, 217, 66, 1, 250, 134, 217, 66, 1, - 250, 243, 217, 66, 1, 250, 239, 217, 66, 1, 250, 159, 217, 66, 1, 250, - 132, 217, 66, 1, 235, 18, 217, 66, 1, 222, 87, 217, 66, 1, 251, 178, 217, - 66, 251, 207, 77, 217, 66, 195, 19, 77, 217, 66, 231, 116, 77, 217, 66, - 208, 144, 200, 59, 1, 141, 214, 54, 200, 59, 1, 141, 223, 4, 200, 59, 1, - 141, 212, 88, 200, 59, 1, 141, 197, 128, 200, 59, 1, 141, 213, 66, 200, - 59, 1, 141, 213, 48, 200, 59, 1, 141, 248, 153, 200, 59, 1, 141, 166, - 200, 59, 1, 141, 219, 49, 200, 59, 1, 141, 219, 38, 200, 59, 1, 141, 201, - 170, 9, 1, 130, 4, 250, 120, 233, 29, 9, 1, 130, 4, 250, 120, 198, 49, - 50, 233, 29, 9, 1, 130, 4, 50, 82, 105, 9, 1, 130, 4, 45, 82, 105, 9, 1, - 130, 4, 250, 120, 222, 26, 9, 1, 130, 4, 250, 120, 248, 29, 50, 222, 26, - 9, 1, 130, 4, 250, 120, 206, 110, 75, 56, 9, 1, 130, 4, 250, 120, 50, - 206, 110, 236, 96, 9, 1, 130, 4, 250, 120, 45, 206, 110, 236, 96, 9, 1, - 130, 4, 250, 120, 206, 110, 75, 60, 9, 1, 130, 4, 75, 56, 9, 1, 130, 4, - 250, 120, 198, 49, 50, 233, 30, 24, 75, 56, 9, 1, 130, 4, 50, 82, 201, - 23, 24, 75, 56, 9, 1, 130, 4, 250, 120, 248, 29, 50, 222, 27, 24, 75, 56, - 9, 1, 130, 4, 250, 120, 198, 49, 50, 233, 30, 24, 45, 206, 183, 9, 1, - 130, 4, 50, 82, 201, 23, 24, 45, 206, 183, 9, 1, 130, 4, 250, 120, 248, - 29, 50, 222, 27, 24, 45, 206, 183, 9, 1, 130, 4, 250, 120, 50, 230, 24, - 9, 1, 130, 4, 250, 120, 45, 230, 24, 9, 199, 164, 4, 210, 241, 230, 24, - 9, 199, 164, 4, 210, 241, 193, 131, 9, 199, 164, 4, 103, 183, 60, 9, 1, - 198, 255, 192, 75, 9, 249, 22, 206, 110, 236, 96, 9, 207, 142, 206, 110, - 236, 96, 9, 1, 213, 12, 4, 223, 65, 2, 196, 8, 9, 1, 179, 4, 223, 65, 2, - 196, 9, 60, 9, 1, 199, 215, 4, 75, 60, 9, 1, 199, 215, 4, 115, 183, 60, - 9, 1, 221, 236, 4, 103, 183, 195, 82, 60, 9, 81, 199, 210, 9, 209, 1, 87, - 56, 9, 209, 173, 87, 56, 9, 2, 136, 193, 23, 251, 155, 9, 2, 131, 193, - 23, 223, 33, 9, 2, 131, 193, 23, 223, 151, 9, 2, 131, 193, 23, 199, 168, - 9, 217, 121, 193, 176, 9, 200, 177, 130, 215, 217, 9, 235, 84, 217, 120, - 9, 134, 217, 121, 138, 217, 120, 9, 1, 248, 196, 4, 2, 196, 9, 60, 9, 1, - 248, 196, 4, 230, 25, 56, 9, 1, 222, 235, 4, 103, 183, 56, 9, 1, 199, - 215, 4, 103, 183, 56, 9, 1, 233, 6, 4, 75, 248, 183, 24, 115, 183, 56, 9, - 1, 208, 83, 4, 75, 60, 9, 1, 220, 12, 4, 54, 164, 9, 1, 92, 4, 115, 183, - 56, 9, 1, 99, 4, 103, 183, 248, 183, 24, 230, 25, 56, 9, 1, 99, 4, 103, - 183, 248, 183, 24, 75, 56, 9, 1, 207, 67, 4, 218, 236, 9, 1, 193, 132, 4, - 75, 193, 52, 9, 1, 206, 137, 192, 75, 9, 1, 131, 251, 141, 9, 1, 237, - 213, 4, 115, 183, 60, 9, 1, 205, 188, 4, 115, 183, 60, 9, 1, 231, 191, 4, - 223, 65, 105, 9, 1, 201, 48, 193, 131, 9, 1, 191, 114, 4, 223, 65, 196, - 9, 56, 9, 1, 251, 179, 4, 115, 183, 60, 9, 1, 222, 80, 4, 75, 60, 9, 1, - 208, 83, 4, 75, 248, 183, 24, 213, 31, 183, 56, 9, 1, 248, 196, 4, 2, 92, - 56, 9, 1, 210, 33, 4, 2, 92, 56, 9, 1, 199, 110, 4, 2, 199, 110, 56, 9, - 1, 207, 67, 4, 2, 213, 12, 56, 9, 1, 99, 4, 103, 183, 248, 183, 24, 2, - 213, 12, 56, 9, 1, 251, 204, 233, 5, 9, 1, 251, 204, 208, 82, 9, 1, 251, - 204, 213, 11, 9, 1, 210, 33, 4, 2, 196, 8, 9, 1, 199, 110, 4, 2, 196, 8, - 9, 1, 197, 121, 4, 2, 196, 8, 9, 1, 199, 145, 4, 2, 196, 8, 9, 1, 221, - 236, 4, 2, 196, 8, 9, 1, 231, 50, 4, 115, 183, 56, 9, 1, 251, 204, 208, - 83, 4, 115, 183, 56, 9, 1, 222, 235, 4, 115, 183, 56, 9, 1, 222, 235, 4, - 115, 183, 60, 9, 1, 220, 12, 4, 2, 9, 1, 199, 215, 56, 9, 1, 230, 190, 9, - 2, 233, 33, 192, 75, 9, 2, 136, 233, 33, 192, 75, 9, 2, 136, 99, 249, 31, - 4, 103, 183, 60, 9, 2, 136, 193, 23, 205, 177, 9, 2, 136, 191, 116, 9, - 219, 245, 206, 110, 75, 56, 9, 219, 245, 206, 110, 75, 60, 9, 200, 202, - 60, 9, 219, 245, 242, 219, 60, 9, 219, 245, 206, 110, 75, 223, 90, 242, - 219, 60, 9, 2, 131, 193, 131, 9, 2, 136, 193, 23, 250, 236, 9, 2, 136, - 205, 187, 9, 2, 136, 251, 178, 9, 2, 136, 208, 82, 9, 2, 136, 213, 12, 4, - 222, 26, 9, 2, 131, 213, 12, 4, 222, 26, 9, 2, 136, 193, 23, 250, 131, 9, - 2, 136, 193, 23, 250, 168, 9, 2, 136, 193, 23, 251, 80, 9, 2, 136, 193, - 23, 205, 166, 9, 2, 136, 193, 23, 208, 46, 9, 2, 136, 193, 23, 193, 155, - 9, 2, 136, 232, 118, 217, 32, 9, 2, 136, 3, 205, 182, 9, 236, 173, 234, - 53, 80, 250, 80, 9, 152, 237, 201, 60, 9, 238, 124, 233, 29, 9, 238, 124, - 237, 200, 9, 238, 124, 222, 26, 9, 238, 124, 233, 27, 9, 238, 124, 237, - 198, 9, 238, 124, 222, 24, 9, 163, 91, 75, 56, 9, 163, 103, 183, 56, 9, - 163, 218, 237, 56, 9, 163, 91, 75, 60, 9, 163, 103, 183, 60, 9, 163, 218, - 237, 60, 9, 211, 66, 233, 27, 9, 211, 66, 237, 198, 9, 211, 66, 222, 24, - 9, 2, 136, 193, 131, 9, 233, 30, 4, 206, 183, 9, 233, 30, 4, 75, 56, 9, - 222, 27, 4, 75, 60, 9, 45, 250, 186, 56, 9, 50, 250, 186, 56, 9, 45, 250, - 186, 60, 9, 50, 250, 186, 60, 9, 54, 50, 250, 186, 56, 9, 54, 50, 250, - 186, 95, 4, 236, 96, 9, 50, 250, 186, 95, 4, 236, 96, 9, 237, 201, 4, - 236, 96, 9, 87, 202, 201, 213, 12, 231, 20, 104, 3, 223, 65, 247, 71, - 104, 3, 247, 71, 104, 3, 251, 20, 104, 3, 195, 32, 104, 1, 203, 35, 65, - 104, 1, 65, 104, 1, 252, 154, 104, 1, 70, 104, 1, 223, 170, 104, 1, 69, - 104, 1, 196, 26, 104, 1, 121, 148, 104, 1, 121, 170, 104, 1, 247, 74, 73, - 104, 1, 203, 35, 73, 104, 1, 73, 104, 1, 251, 184, 104, 1, 247, 74, 74, - 104, 1, 203, 35, 74, 104, 1, 74, 104, 1, 250, 113, 104, 1, 157, 104, 1, - 221, 190, 104, 1, 231, 203, 104, 1, 231, 54, 104, 1, 214, 54, 104, 1, - 247, 112, 104, 1, 246, 209, 104, 1, 223, 4, 104, 1, 222, 225, 104, 1, - 212, 88, 104, 1, 197, 128, 104, 1, 197, 116, 104, 1, 237, 146, 104, 1, - 237, 130, 104, 1, 213, 66, 104, 1, 199, 247, 104, 1, 199, 44, 104, 1, - 237, 241, 104, 1, 237, 23, 104, 1, 180, 104, 1, 213, 48, 104, 1, 168, - 104, 1, 209, 219, 104, 1, 249, 103, 104, 1, 248, 153, 104, 1, 172, 104, - 1, 169, 104, 1, 166, 104, 1, 206, 104, 104, 1, 171, 104, 1, 219, 49, 104, - 1, 219, 38, 104, 1, 195, 185, 104, 1, 203, 160, 104, 1, 201, 170, 104, 1, - 189, 104, 1, 144, 104, 18, 3, 211, 139, 104, 18, 3, 211, 74, 104, 3, 212, - 128, 104, 3, 250, 95, 104, 18, 3, 252, 154, 104, 18, 3, 70, 104, 18, 3, - 223, 170, 104, 18, 3, 69, 104, 18, 3, 196, 26, 104, 18, 3, 121, 148, 104, - 18, 3, 121, 206, 105, 104, 18, 3, 247, 74, 73, 104, 18, 3, 203, 35, 73, - 104, 18, 3, 73, 104, 18, 3, 251, 184, 104, 18, 3, 247, 74, 74, 104, 18, - 3, 203, 35, 74, 104, 18, 3, 74, 104, 18, 3, 250, 113, 104, 3, 195, 37, - 104, 18, 3, 208, 200, 73, 104, 18, 3, 250, 90, 104, 211, 102, 104, 201, - 33, 3, 196, 150, 104, 201, 33, 3, 251, 22, 104, 230, 177, 252, 8, 104, - 251, 251, 252, 8, 104, 18, 3, 247, 74, 177, 73, 104, 18, 3, 196, 148, - 104, 18, 3, 196, 25, 104, 1, 208, 89, 104, 1, 221, 169, 104, 1, 231, 29, - 104, 1, 191, 123, 104, 1, 237, 135, 104, 1, 207, 1, 104, 1, 233, 68, 104, - 1, 191, 175, 104, 1, 121, 206, 105, 104, 1, 121, 219, 50, 104, 18, 3, - 121, 170, 104, 18, 3, 121, 219, 50, 104, 237, 193, 104, 54, 237, 193, - 104, 17, 191, 77, 104, 17, 108, 104, 17, 109, 104, 17, 139, 104, 17, 137, - 104, 17, 153, 104, 17, 173, 104, 17, 181, 104, 17, 176, 104, 17, 184, - 104, 252, 16, 57, 104, 3, 136, 201, 241, 236, 96, 104, 1, 247, 74, 65, - 104, 1, 211, 139, 104, 1, 211, 74, 104, 1, 250, 90, 104, 1, 196, 148, - 104, 1, 196, 25, 104, 1, 217, 24, 237, 146, 104, 1, 191, 71, 104, 1, 88, - 169, 104, 1, 231, 90, 104, 1, 222, 203, 104, 1, 230, 231, 201, 58, 104, - 1, 237, 136, 104, 1, 249, 3, 248, 175, 251, 49, 248, 175, 3, 247, 71, - 248, 175, 3, 251, 20, 248, 175, 3, 195, 32, 248, 175, 1, 65, 248, 175, 1, - 252, 154, 248, 175, 1, 70, 248, 175, 1, 223, 170, 248, 175, 1, 69, 248, - 175, 1, 196, 26, 248, 175, 1, 121, 148, 248, 175, 1, 121, 170, 248, 175, - 1, 73, 248, 175, 1, 251, 184, 248, 175, 1, 74, 248, 175, 1, 250, 113, - 248, 175, 1, 157, 248, 175, 1, 221, 190, 248, 175, 1, 231, 203, 248, 175, - 1, 231, 54, 248, 175, 1, 214, 54, 248, 175, 1, 247, 112, 248, 175, 1, - 246, 209, 248, 175, 1, 223, 4, 248, 175, 1, 222, 225, 248, 175, 1, 212, - 88, 248, 175, 1, 197, 128, 248, 175, 1, 197, 116, 248, 175, 1, 237, 146, - 248, 175, 1, 237, 130, 248, 175, 1, 213, 66, 248, 175, 1, 199, 247, 248, - 175, 1, 199, 44, 248, 175, 1, 237, 241, 248, 175, 1, 237, 23, 248, 175, - 1, 180, 248, 175, 1, 168, 248, 175, 1, 209, 219, 248, 175, 1, 249, 103, - 248, 175, 1, 248, 153, 248, 175, 1, 172, 248, 175, 1, 169, 248, 175, 1, - 166, 248, 175, 1, 171, 248, 175, 1, 203, 160, 248, 175, 1, 201, 170, 248, - 175, 1, 189, 248, 175, 1, 144, 248, 175, 3, 212, 128, 248, 175, 3, 250, - 95, 248, 175, 18, 3, 252, 154, 248, 175, 18, 3, 70, 248, 175, 18, 3, 223, - 170, 248, 175, 18, 3, 69, 248, 175, 18, 3, 196, 26, 248, 175, 18, 3, 121, - 148, 248, 175, 18, 3, 121, 206, 105, 248, 175, 18, 3, 73, 248, 175, 18, - 3, 251, 184, 248, 175, 18, 3, 74, 248, 175, 18, 3, 250, 113, 248, 175, 3, - 195, 37, 248, 175, 1, 221, 179, 199, 247, 248, 175, 250, 114, 219, 174, - 77, 248, 175, 1, 206, 104, 248, 175, 1, 207, 1, 248, 175, 1, 191, 175, - 248, 175, 1, 121, 206, 105, 248, 175, 1, 121, 219, 50, 248, 175, 18, 3, - 121, 170, 248, 175, 18, 3, 121, 219, 50, 248, 175, 17, 191, 77, 248, 175, - 17, 108, 248, 175, 17, 109, 248, 175, 17, 139, 248, 175, 17, 137, 248, - 175, 17, 153, 248, 175, 17, 173, 248, 175, 17, 181, 248, 175, 17, 176, - 248, 175, 17, 184, 248, 175, 1, 207, 181, 4, 82, 236, 249, 248, 175, 1, - 207, 181, 4, 110, 236, 249, 248, 175, 206, 31, 77, 248, 175, 206, 31, 57, - 248, 175, 238, 123, 212, 120, 108, 248, 175, 238, 123, 212, 120, 109, - 248, 175, 238, 123, 212, 120, 139, 248, 175, 238, 123, 212, 120, 137, - 248, 175, 238, 123, 212, 120, 91, 219, 157, 199, 34, 199, 29, 237, 54, - 248, 175, 238, 123, 237, 55, 202, 125, 248, 175, 223, 26, 248, 175, 231, - 170, 77, 248, 175, 1, 195, 147, 251, 20, 248, 175, 252, 16, 57, 248, 175, - 205, 133, 77, 230, 111, 3, 251, 245, 248, 119, 230, 111, 3, 248, 119, - 230, 111, 3, 195, 32, 230, 111, 1, 65, 230, 111, 1, 252, 154, 230, 111, - 1, 70, 230, 111, 1, 223, 170, 230, 111, 1, 69, 230, 111, 1, 196, 26, 230, - 111, 1, 234, 145, 230, 111, 1, 251, 184, 230, 111, 1, 211, 76, 230, 111, - 1, 250, 113, 230, 111, 1, 157, 230, 111, 1, 221, 190, 230, 111, 1, 231, - 203, 230, 111, 1, 231, 54, 230, 111, 1, 214, 54, 230, 111, 1, 247, 112, - 230, 111, 1, 246, 209, 230, 111, 1, 223, 4, 230, 111, 1, 222, 225, 230, - 111, 1, 212, 88, 230, 111, 1, 197, 128, 230, 111, 1, 197, 116, 230, 111, - 1, 237, 146, 230, 111, 1, 237, 130, 230, 111, 1, 213, 66, 230, 111, 1, - 199, 247, 230, 111, 1, 199, 44, 230, 111, 1, 237, 241, 230, 111, 1, 237, - 23, 230, 111, 1, 180, 230, 111, 1, 168, 230, 111, 1, 209, 219, 230, 111, - 1, 249, 103, 230, 111, 1, 248, 153, 230, 111, 1, 172, 230, 111, 1, 169, - 230, 111, 1, 166, 230, 111, 1, 171, 230, 111, 1, 219, 49, 230, 111, 1, - 195, 185, 230, 111, 1, 203, 160, 230, 111, 1, 189, 230, 111, 1, 144, 230, - 111, 3, 212, 128, 230, 111, 18, 3, 252, 154, 230, 111, 18, 3, 70, 230, - 111, 18, 3, 223, 170, 230, 111, 18, 3, 69, 230, 111, 18, 3, 196, 26, 230, - 111, 18, 3, 234, 145, 230, 111, 18, 3, 251, 184, 230, 111, 18, 3, 211, - 76, 230, 111, 18, 3, 250, 113, 230, 111, 3, 195, 37, 230, 111, 3, 196, - 153, 230, 111, 1, 221, 169, 230, 111, 1, 231, 29, 230, 111, 1, 191, 123, - 230, 111, 1, 206, 104, 230, 111, 1, 233, 68, 230, 111, 17, 191, 77, 230, - 111, 17, 108, 230, 111, 17, 109, 230, 111, 17, 139, 230, 111, 17, 137, - 230, 111, 17, 153, 230, 111, 17, 173, 230, 111, 17, 181, 230, 111, 17, - 176, 230, 111, 17, 184, 230, 111, 198, 128, 230, 111, 251, 244, 230, 111, - 223, 47, 230, 111, 196, 54, 230, 111, 234, 105, 211, 81, 230, 111, 3, - 192, 115, 230, 111, 252, 16, 57, 230, 128, 3, 247, 71, 230, 128, 3, 251, - 20, 230, 128, 3, 195, 32, 230, 128, 1, 65, 230, 128, 1, 252, 154, 230, - 128, 1, 70, 230, 128, 1, 223, 170, 230, 128, 1, 69, 230, 128, 1, 196, 26, - 230, 128, 1, 121, 148, 230, 128, 1, 121, 170, 230, 128, 18, 247, 74, 73, - 230, 128, 1, 73, 230, 128, 1, 251, 184, 230, 128, 18, 247, 74, 74, 230, - 128, 1, 74, 230, 128, 1, 250, 113, 230, 128, 1, 157, 230, 128, 1, 221, - 190, 230, 128, 1, 231, 203, 230, 128, 1, 231, 54, 230, 128, 1, 214, 54, - 230, 128, 1, 247, 112, 230, 128, 1, 246, 209, 230, 128, 1, 223, 4, 230, - 128, 1, 222, 225, 230, 128, 1, 212, 88, 230, 128, 1, 197, 128, 230, 128, - 1, 197, 116, 230, 128, 1, 237, 146, 230, 128, 1, 237, 130, 230, 128, 1, - 213, 66, 230, 128, 1, 199, 247, 230, 128, 1, 199, 44, 230, 128, 1, 237, - 241, 230, 128, 1, 237, 23, 230, 128, 1, 180, 230, 128, 1, 168, 230, 128, - 1, 209, 219, 230, 128, 1, 249, 103, 230, 128, 1, 248, 153, 230, 128, 1, - 172, 230, 128, 1, 169, 230, 128, 1, 166, 230, 128, 1, 171, 230, 128, 1, - 219, 49, 230, 128, 1, 195, 185, 230, 128, 1, 203, 160, 230, 128, 1, 201, - 170, 230, 128, 1, 189, 230, 128, 1, 144, 230, 128, 3, 212, 128, 230, 128, - 3, 250, 95, 230, 128, 18, 3, 252, 154, 230, 128, 18, 3, 70, 230, 128, 18, - 3, 223, 170, 230, 128, 18, 3, 69, 230, 128, 18, 3, 196, 26, 230, 128, 18, - 3, 121, 148, 230, 128, 18, 3, 121, 206, 105, 230, 128, 18, 3, 247, 74, - 73, 230, 128, 18, 3, 73, 230, 128, 18, 3, 251, 184, 230, 128, 18, 3, 247, - 74, 74, 230, 128, 18, 3, 74, 230, 128, 18, 3, 250, 113, 230, 128, 3, 195, - 37, 230, 128, 211, 102, 230, 128, 1, 121, 206, 105, 230, 128, 1, 121, - 219, 50, 230, 128, 18, 3, 121, 170, 230, 128, 18, 3, 121, 219, 50, 230, - 128, 17, 191, 77, 230, 128, 17, 108, 230, 128, 17, 109, 230, 128, 17, - 139, 230, 128, 17, 137, 230, 128, 17, 153, 230, 128, 17, 173, 230, 128, - 17, 181, 230, 128, 17, 176, 230, 128, 17, 184, 230, 128, 252, 16, 57, - 230, 128, 206, 31, 57, 230, 128, 1, 191, 71, 230, 128, 3, 200, 201, 230, - 128, 3, 203, 150, 230, 128, 3, 217, 118, 230, 128, 3, 198, 219, 212, 129, - 56, 230, 128, 3, 242, 219, 212, 129, 56, 230, 128, 3, 197, 11, 212, 129, - 56, 211, 35, 3, 247, 71, 211, 35, 3, 251, 20, 211, 35, 3, 195, 32, 211, - 35, 1, 65, 211, 35, 1, 252, 154, 211, 35, 1, 70, 211, 35, 1, 223, 170, - 211, 35, 1, 69, 211, 35, 1, 196, 26, 211, 35, 1, 121, 148, 211, 35, 1, - 121, 170, 211, 35, 1, 73, 211, 35, 1, 251, 184, 211, 35, 1, 74, 211, 35, - 1, 250, 113, 211, 35, 1, 157, 211, 35, 1, 221, 190, 211, 35, 1, 231, 203, - 211, 35, 1, 231, 54, 211, 35, 1, 214, 54, 211, 35, 1, 247, 112, 211, 35, - 1, 246, 209, 211, 35, 1, 223, 4, 211, 35, 1, 222, 225, 211, 35, 1, 212, - 88, 211, 35, 1, 197, 128, 211, 35, 1, 197, 116, 211, 35, 1, 237, 146, - 211, 35, 1, 237, 130, 211, 35, 1, 213, 66, 211, 35, 1, 199, 247, 211, 35, - 1, 199, 44, 211, 35, 1, 237, 241, 211, 35, 1, 237, 23, 211, 35, 1, 180, - 211, 35, 1, 168, 211, 35, 1, 209, 219, 211, 35, 1, 249, 103, 211, 35, 1, - 248, 153, 211, 35, 1, 172, 211, 35, 1, 169, 211, 35, 1, 166, 211, 35, 1, - 171, 211, 35, 1, 219, 49, 211, 35, 1, 195, 185, 211, 35, 1, 203, 160, - 211, 35, 1, 201, 170, 211, 35, 1, 189, 211, 35, 1, 144, 211, 35, 3, 212, - 128, 211, 35, 3, 250, 95, 211, 35, 18, 3, 252, 154, 211, 35, 18, 3, 70, - 211, 35, 18, 3, 223, 170, 211, 35, 18, 3, 69, 211, 35, 18, 3, 196, 26, - 211, 35, 18, 3, 121, 148, 211, 35, 18, 3, 121, 206, 105, 211, 35, 18, 3, - 73, 211, 35, 18, 3, 251, 184, 211, 35, 18, 3, 74, 211, 35, 18, 3, 250, - 113, 211, 35, 3, 195, 37, 211, 35, 3, 210, 244, 211, 35, 251, 185, 219, - 174, 77, 211, 35, 250, 114, 219, 174, 77, 211, 35, 1, 206, 104, 211, 35, - 1, 207, 1, 211, 35, 1, 191, 175, 211, 35, 1, 121, 206, 105, 211, 35, 1, - 121, 219, 50, 211, 35, 18, 3, 121, 170, 211, 35, 18, 3, 121, 219, 50, - 211, 35, 17, 191, 77, 211, 35, 17, 108, 211, 35, 17, 109, 211, 35, 17, - 139, 211, 35, 17, 137, 211, 35, 17, 153, 211, 35, 17, 173, 211, 35, 17, - 181, 211, 35, 17, 176, 211, 35, 17, 184, 211, 35, 223, 26, 211, 35, 1, - 193, 187, 211, 35, 232, 80, 91, 208, 17, 211, 35, 232, 80, 91, 230, 37, - 211, 35, 232, 80, 115, 208, 15, 211, 35, 232, 80, 91, 202, 123, 211, 35, - 232, 80, 91, 234, 116, 211, 35, 232, 80, 115, 202, 120, 44, 3, 251, 20, - 44, 3, 195, 32, 44, 1, 65, 44, 1, 252, 154, 44, 1, 70, 44, 1, 223, 170, - 44, 1, 69, 44, 1, 196, 26, 44, 1, 73, 44, 1, 234, 145, 44, 1, 251, 184, - 44, 1, 74, 44, 1, 211, 76, 44, 1, 250, 113, 44, 1, 157, 44, 1, 214, 54, - 44, 1, 247, 112, 44, 1, 223, 4, 44, 1, 212, 88, 44, 1, 197, 128, 44, 1, - 213, 66, 44, 1, 199, 247, 44, 1, 180, 44, 1, 213, 48, 44, 1, 168, 44, 1, - 172, 44, 1, 169, 44, 1, 166, 44, 1, 206, 104, 44, 1, 171, 44, 1, 219, 49, - 44, 1, 219, 38, 44, 1, 195, 185, 44, 1, 203, 160, 44, 1, 201, 170, 44, 1, - 189, 44, 1, 144, 44, 18, 3, 252, 154, 44, 18, 3, 70, 44, 18, 3, 223, 170, - 44, 18, 3, 69, 44, 18, 3, 196, 26, 44, 18, 3, 73, 44, 18, 3, 234, 145, - 44, 18, 3, 251, 184, 44, 18, 3, 74, 44, 18, 3, 211, 76, 44, 18, 3, 250, - 113, 44, 3, 195, 37, 44, 211, 102, 44, 250, 114, 219, 174, 77, 44, 17, - 191, 77, 44, 17, 108, 44, 17, 109, 44, 17, 139, 44, 17, 137, 44, 17, 153, - 44, 17, 173, 44, 17, 181, 44, 17, 176, 44, 17, 184, 44, 31, 199, 90, 44, - 31, 91, 228, 109, 44, 31, 91, 188, 44, 237, 159, 57, 44, 215, 197, 57, - 44, 192, 78, 57, 44, 237, 97, 57, 44, 238, 183, 57, 44, 250, 170, 95, 57, - 44, 206, 31, 57, 44, 31, 57, 199, 94, 3, 33, 247, 72, 56, 199, 94, 3, - 247, 71, 199, 94, 3, 251, 20, 199, 94, 3, 195, 32, 199, 94, 3, 33, 251, - 21, 56, 199, 94, 1, 65, 199, 94, 1, 252, 154, 199, 94, 1, 70, 199, 94, 1, - 223, 170, 199, 94, 1, 69, 199, 94, 1, 196, 26, 199, 94, 1, 121, 148, 199, - 94, 1, 121, 170, 199, 94, 1, 73, 199, 94, 1, 234, 145, 199, 94, 1, 251, - 184, 199, 94, 1, 74, 199, 94, 1, 211, 76, 199, 94, 1, 250, 113, 199, 94, - 1, 157, 199, 94, 1, 221, 190, 199, 94, 1, 231, 203, 199, 94, 1, 231, 54, - 199, 94, 1, 214, 54, 199, 94, 1, 247, 112, 199, 94, 1, 246, 209, 199, 94, - 1, 223, 4, 199, 94, 1, 222, 225, 199, 94, 1, 212, 88, 199, 94, 1, 197, - 128, 199, 94, 1, 197, 116, 199, 94, 1, 237, 146, 199, 94, 1, 237, 130, - 199, 94, 1, 213, 66, 199, 94, 1, 199, 247, 199, 94, 1, 199, 44, 199, 94, - 1, 237, 241, 199, 94, 1, 237, 23, 199, 94, 1, 180, 199, 94, 1, 168, 199, - 94, 1, 209, 219, 199, 94, 1, 249, 103, 199, 94, 1, 248, 153, 199, 94, 1, - 172, 199, 94, 1, 169, 199, 94, 1, 166, 199, 94, 1, 206, 104, 199, 94, 1, - 171, 199, 94, 1, 219, 49, 199, 94, 1, 219, 38, 199, 94, 1, 195, 185, 199, - 94, 1, 203, 160, 199, 94, 1, 201, 170, 199, 94, 1, 189, 199, 94, 1, 144, - 199, 94, 3, 212, 128, 199, 94, 3, 250, 95, 199, 94, 18, 3, 252, 154, 199, - 94, 18, 3, 70, 199, 94, 18, 3, 223, 170, 199, 94, 18, 3, 69, 199, 94, 18, - 3, 196, 26, 199, 94, 18, 3, 121, 148, 199, 94, 18, 3, 121, 206, 105, 199, - 94, 18, 3, 73, 199, 94, 18, 3, 234, 145, 199, 94, 18, 3, 251, 184, 199, - 94, 18, 3, 74, 199, 94, 18, 3, 211, 76, 199, 94, 18, 3, 250, 113, 199, - 94, 3, 195, 37, 199, 94, 219, 174, 77, 199, 94, 251, 185, 219, 174, 77, - 199, 94, 1, 197, 164, 199, 94, 1, 234, 247, 199, 94, 1, 206, 85, 199, 94, - 1, 214, 218, 209, 39, 199, 94, 1, 121, 206, 105, 199, 94, 1, 121, 219, - 50, 199, 94, 18, 3, 121, 170, 199, 94, 18, 3, 121, 219, 50, 199, 94, 17, - 191, 77, 199, 94, 17, 108, 199, 94, 17, 109, 199, 94, 17, 139, 199, 94, - 17, 137, 199, 94, 17, 153, 199, 94, 17, 173, 199, 94, 17, 181, 199, 94, - 17, 176, 199, 94, 17, 184, 199, 94, 3, 202, 205, 199, 94, 232, 80, 17, - 191, 78, 39, 211, 143, 208, 246, 80, 137, 199, 94, 232, 80, 17, 91, 39, - 211, 143, 208, 246, 80, 137, 199, 94, 232, 80, 17, 103, 39, 211, 143, - 208, 246, 80, 137, 199, 94, 232, 80, 17, 115, 39, 211, 143, 208, 246, 80, - 137, 199, 94, 232, 80, 17, 91, 39, 233, 188, 208, 246, 80, 137, 199, 94, - 232, 80, 17, 103, 39, 233, 188, 208, 246, 80, 137, 199, 94, 232, 80, 17, - 115, 39, 233, 188, 208, 246, 80, 137, 199, 94, 3, 197, 44, 222, 55, 3, - 201, 241, 247, 71, 222, 55, 3, 247, 71, 222, 55, 3, 251, 20, 222, 55, 3, - 195, 32, 222, 55, 3, 202, 205, 222, 55, 1, 65, 222, 55, 1, 252, 154, 222, - 55, 1, 70, 222, 55, 1, 223, 170, 222, 55, 1, 69, 222, 55, 1, 196, 26, - 222, 55, 1, 121, 148, 222, 55, 1, 121, 170, 222, 55, 1, 73, 222, 55, 1, - 234, 145, 222, 55, 1, 251, 184, 222, 55, 1, 74, 222, 55, 1, 211, 76, 222, - 55, 1, 250, 113, 222, 55, 1, 157, 222, 55, 1, 221, 190, 222, 55, 1, 231, - 203, 222, 55, 1, 231, 54, 222, 55, 1, 214, 54, 222, 55, 1, 247, 112, 222, - 55, 1, 246, 209, 222, 55, 1, 223, 4, 222, 55, 1, 222, 225, 222, 55, 1, - 212, 88, 222, 55, 1, 197, 128, 222, 55, 1, 197, 116, 222, 55, 1, 237, - 146, 222, 55, 1, 237, 130, 222, 55, 1, 213, 66, 222, 55, 1, 199, 247, - 222, 55, 1, 199, 44, 222, 55, 1, 237, 241, 222, 55, 1, 237, 23, 222, 55, - 1, 180, 222, 55, 1, 168, 222, 55, 1, 209, 219, 222, 55, 1, 249, 103, 222, - 55, 1, 248, 153, 222, 55, 1, 172, 222, 55, 1, 169, 222, 55, 1, 166, 222, - 55, 1, 206, 104, 222, 55, 1, 171, 222, 55, 1, 219, 49, 222, 55, 1, 195, - 185, 222, 55, 1, 203, 160, 222, 55, 1, 201, 170, 222, 55, 1, 189, 222, - 55, 1, 144, 222, 55, 3, 212, 128, 222, 55, 3, 250, 95, 222, 55, 18, 3, - 252, 154, 222, 55, 18, 3, 70, 222, 55, 18, 3, 223, 170, 222, 55, 18, 3, - 69, 222, 55, 18, 3, 196, 26, 222, 55, 18, 3, 121, 148, 222, 55, 18, 3, - 121, 206, 105, 222, 55, 18, 3, 73, 222, 55, 18, 3, 234, 145, 222, 55, 18, - 3, 251, 184, 222, 55, 18, 3, 74, 222, 55, 18, 3, 211, 76, 222, 55, 18, 3, - 250, 113, 222, 55, 3, 195, 37, 222, 55, 219, 174, 77, 222, 55, 251, 185, - 219, 174, 77, 222, 55, 1, 214, 218, 209, 39, 222, 55, 1, 233, 68, 222, - 55, 1, 121, 206, 105, 222, 55, 1, 121, 219, 50, 222, 55, 18, 3, 121, 170, - 222, 55, 18, 3, 121, 219, 50, 222, 55, 17, 191, 77, 222, 55, 17, 108, - 222, 55, 17, 109, 222, 55, 17, 139, 222, 55, 17, 137, 222, 55, 17, 153, - 222, 55, 17, 173, 222, 55, 17, 181, 222, 55, 17, 176, 222, 55, 17, 184, - 222, 55, 3, 222, 210, 222, 55, 3, 196, 71, 141, 3, 33, 251, 21, 56, 141, - 3, 247, 71, 141, 3, 251, 20, 141, 3, 195, 32, 141, 1, 195, 147, 251, 20, - 141, 1, 65, 141, 1, 252, 154, 141, 1, 70, 141, 1, 223, 170, 141, 1, 69, - 141, 1, 196, 26, 141, 1, 121, 148, 141, 1, 121, 170, 141, 1, 73, 141, 1, - 234, 145, 141, 1, 251, 184, 141, 1, 74, 141, 1, 211, 76, 141, 1, 250, - 113, 141, 1, 157, 141, 1, 221, 190, 141, 1, 231, 203, 141, 1, 231, 54, - 141, 1, 214, 54, 141, 1, 247, 112, 141, 1, 246, 209, 141, 1, 223, 4, 141, - 1, 222, 225, 141, 1, 212, 88, 141, 1, 197, 128, 141, 1, 197, 116, 141, 1, - 237, 146, 141, 1, 237, 130, 141, 1, 213, 66, 141, 1, 199, 247, 141, 1, - 199, 44, 141, 1, 237, 241, 141, 1, 237, 23, 141, 1, 180, 141, 1, 213, 48, - 141, 1, 168, 141, 1, 209, 219, 141, 1, 249, 103, 141, 1, 248, 153, 141, - 1, 172, 141, 1, 169, 141, 1, 166, 141, 1, 206, 104, 141, 1, 171, 141, 1, - 219, 49, 141, 1, 219, 38, 141, 1, 195, 185, 141, 1, 203, 160, 141, 1, - 201, 170, 141, 1, 189, 141, 1, 144, 141, 1, 197, 97, 141, 3, 81, 249, 38, - 195, 37, 141, 3, 242, 212, 195, 37, 141, 3, 250, 95, 141, 18, 3, 252, - 154, 141, 18, 3, 70, 141, 18, 3, 223, 170, 141, 18, 3, 69, 141, 18, 3, - 196, 26, 141, 18, 3, 121, 148, 141, 18, 3, 121, 206, 105, 141, 18, 3, 73, - 141, 18, 3, 234, 145, 141, 18, 3, 251, 184, 141, 18, 3, 74, 141, 18, 3, - 211, 76, 141, 18, 3, 250, 113, 141, 3, 195, 37, 141, 1, 75, 207, 40, 141, - 3, 210, 120, 141, 1, 243, 36, 218, 147, 141, 1, 243, 36, 192, 159, 141, - 1, 243, 36, 219, 39, 141, 250, 114, 219, 174, 77, 141, 232, 80, 91, 211, - 89, 141, 232, 80, 91, 232, 100, 141, 232, 80, 115, 234, 112, 141, 232, - 80, 91, 197, 31, 141, 232, 80, 91, 199, 81, 141, 232, 80, 115, 197, 30, - 141, 232, 80, 91, 232, 233, 141, 1, 250, 220, 223, 170, 141, 1, 121, 206, - 105, 141, 1, 121, 219, 50, 141, 18, 3, 121, 170, 141, 18, 3, 121, 219, - 50, 141, 17, 191, 77, 141, 17, 108, 141, 17, 109, 141, 17, 139, 141, 17, - 137, 141, 17, 153, 141, 17, 173, 141, 17, 181, 141, 17, 176, 141, 17, - 184, 141, 31, 199, 90, 141, 31, 91, 228, 109, 141, 31, 91, 188, 141, 232, - 80, 91, 208, 17, 141, 232, 80, 91, 230, 37, 141, 232, 80, 115, 208, 15, - 141, 232, 80, 91, 202, 123, 141, 232, 80, 91, 234, 116, 141, 232, 80, - 115, 202, 120, 141, 237, 164, 77, 141, 1, 243, 36, 213, 67, 141, 1, 243, - 36, 215, 47, 141, 1, 243, 36, 206, 105, 141, 1, 243, 36, 170, 141, 1, - 243, 36, 219, 50, 141, 1, 243, 36, 222, 125, 165, 3, 247, 71, 165, 3, - 251, 19, 165, 3, 195, 31, 165, 1, 250, 79, 165, 1, 252, 107, 165, 1, 251, - 209, 165, 1, 251, 224, 165, 1, 223, 15, 165, 1, 223, 169, 165, 1, 196, - 16, 165, 1, 196, 20, 165, 1, 223, 42, 165, 1, 223, 43, 165, 1, 223, 154, - 165, 1, 223, 156, 165, 1, 233, 155, 165, 1, 234, 140, 165, 1, 251, 167, - 165, 1, 210, 231, 165, 1, 211, 69, 165, 1, 250, 98, 165, 1, 251, 112, - 222, 2, 165, 1, 217, 98, 222, 2, 165, 1, 251, 112, 231, 148, 165, 1, 217, - 98, 231, 148, 165, 1, 222, 54, 214, 233, 165, 1, 205, 127, 231, 148, 165, - 1, 251, 112, 247, 20, 165, 1, 217, 98, 247, 20, 165, 1, 251, 112, 222, - 241, 165, 1, 217, 98, 222, 241, 165, 1, 199, 236, 214, 233, 165, 1, 199, - 236, 205, 126, 214, 234, 165, 1, 205, 127, 222, 241, 165, 1, 251, 112, - 197, 124, 165, 1, 217, 98, 197, 124, 165, 1, 251, 112, 237, 137, 165, 1, - 217, 98, 237, 137, 165, 1, 215, 78, 214, 183, 165, 1, 205, 127, 237, 137, - 165, 1, 251, 112, 199, 148, 165, 1, 217, 98, 199, 148, 165, 1, 251, 112, - 237, 157, 165, 1, 217, 98, 237, 157, 165, 1, 237, 189, 214, 183, 165, 1, - 205, 127, 237, 157, 165, 1, 251, 112, 210, 61, 165, 1, 217, 98, 210, 61, - 165, 1, 251, 112, 249, 5, 165, 1, 217, 98, 249, 5, 165, 1, 217, 0, 165, - 1, 251, 92, 249, 5, 165, 1, 192, 85, 165, 1, 207, 116, 165, 1, 237, 189, - 219, 223, 165, 1, 195, 153, 165, 1, 199, 236, 205, 97, 165, 1, 215, 78, - 205, 97, 165, 1, 237, 189, 205, 97, 165, 1, 229, 219, 165, 1, 215, 78, - 219, 223, 165, 1, 233, 20, 165, 3, 251, 154, 165, 18, 3, 251, 219, 165, - 18, 3, 221, 215, 251, 226, 165, 18, 3, 236, 222, 251, 226, 165, 18, 3, - 221, 215, 223, 39, 165, 18, 3, 236, 222, 223, 39, 165, 18, 3, 221, 215, - 210, 209, 165, 18, 3, 236, 222, 210, 209, 165, 18, 3, 231, 192, 165, 18, - 3, 221, 22, 165, 18, 3, 236, 222, 221, 22, 165, 18, 3, 221, 24, 237, 75, - 165, 18, 3, 221, 23, 230, 59, 251, 219, 165, 18, 3, 221, 23, 230, 59, - 236, 222, 251, 219, 165, 18, 3, 221, 23, 230, 59, 231, 147, 165, 18, 3, - 231, 147, 165, 219, 62, 17, 191, 77, 165, 219, 62, 17, 108, 165, 219, 62, - 17, 109, 165, 219, 62, 17, 139, 165, 219, 62, 17, 137, 165, 219, 62, 17, - 153, 165, 219, 62, 17, 173, 165, 219, 62, 17, 181, 165, 219, 62, 17, 176, - 165, 219, 62, 17, 184, 165, 18, 3, 236, 222, 231, 192, 165, 18, 3, 236, - 222, 231, 147, 165, 208, 145, 220, 185, 199, 39, 246, 192, 221, 44, 222, - 75, 199, 39, 246, 192, 221, 160, 221, 184, 199, 39, 246, 192, 221, 160, - 221, 150, 199, 39, 246, 192, 221, 160, 221, 145, 199, 39, 246, 192, 221, - 160, 221, 155, 199, 39, 246, 192, 221, 160, 207, 138, 199, 39, 246, 192, - 213, 236, 213, 223, 199, 39, 246, 192, 243, 21, 246, 198, 199, 39, 246, - 192, 243, 21, 243, 31, 199, 39, 246, 192, 243, 21, 246, 197, 199, 39, - 246, 192, 202, 42, 202, 41, 199, 39, 246, 192, 243, 21, 243, 17, 199, 39, - 246, 192, 192, 13, 192, 20, 199, 39, 246, 192, 236, 130, 246, 206, 199, - 39, 246, 192, 118, 210, 77, 199, 39, 246, 192, 198, 237, 199, 33, 199, - 39, 246, 192, 198, 237, 214, 208, 199, 39, 246, 192, 198, 237, 209, 179, - 199, 39, 246, 192, 213, 31, 214, 88, 199, 39, 246, 192, 236, 130, 237, - 76, 199, 39, 246, 192, 118, 199, 179, 199, 39, 246, 192, 198, 237, 198, - 202, 199, 39, 246, 192, 198, 237, 199, 40, 199, 39, 246, 192, 198, 237, - 198, 231, 199, 39, 246, 192, 213, 31, 212, 165, 199, 39, 246, 192, 248, - 64, 249, 68, 199, 39, 246, 192, 209, 66, 209, 102, 199, 39, 246, 192, - 209, 191, 209, 181, 199, 39, 246, 192, 232, 136, 233, 68, 199, 39, 246, - 192, 209, 191, 209, 212, 199, 39, 246, 192, 232, 136, 233, 39, 199, 39, - 246, 192, 209, 191, 205, 141, 199, 39, 246, 192, 215, 252, 172, 199, 39, - 246, 192, 192, 13, 192, 116, 199, 39, 246, 192, 206, 158, 206, 56, 199, - 39, 246, 192, 206, 63, 199, 39, 246, 192, 219, 20, 219, 81, 199, 39, 246, - 192, 218, 203, 199, 39, 246, 192, 193, 49, 193, 172, 199, 39, 246, 192, - 202, 42, 205, 162, 199, 39, 246, 192, 202, 42, 206, 27, 199, 39, 246, - 192, 202, 42, 200, 246, 199, 39, 246, 192, 228, 248, 229, 90, 199, 39, - 246, 192, 219, 20, 242, 255, 199, 39, 246, 192, 186, 251, 71, 199, 39, - 246, 192, 228, 248, 213, 21, 199, 39, 246, 192, 210, 184, 199, 39, 246, - 192, 205, 121, 65, 199, 39, 246, 192, 217, 92, 230, 22, 199, 39, 246, - 192, 205, 121, 252, 154, 199, 39, 246, 192, 205, 121, 251, 98, 199, 39, - 246, 192, 205, 121, 70, 199, 39, 246, 192, 205, 121, 223, 170, 199, 39, - 246, 192, 205, 121, 196, 148, 199, 39, 246, 192, 205, 121, 196, 145, 199, - 39, 246, 192, 205, 121, 69, 199, 39, 246, 192, 205, 121, 196, 26, 199, - 39, 246, 192, 209, 193, 199, 39, 238, 123, 16, 249, 69, 199, 39, 246, - 192, 205, 121, 73, 199, 39, 246, 192, 205, 121, 251, 229, 199, 39, 246, - 192, 205, 121, 74, 199, 39, 246, 192, 205, 121, 251, 185, 217, 86, 199, - 39, 246, 192, 205, 121, 251, 185, 217, 87, 199, 39, 246, 192, 220, 15, - 199, 39, 246, 192, 217, 83, 199, 39, 246, 192, 217, 84, 199, 39, 246, - 192, 217, 92, 234, 104, 199, 39, 246, 192, 217, 92, 198, 236, 199, 39, - 246, 192, 217, 92, 197, 240, 199, 39, 246, 192, 217, 92, 243, 84, 199, - 39, 246, 192, 199, 31, 199, 39, 246, 192, 213, 169, 199, 39, 246, 192, - 192, 110, 199, 39, 246, 192, 232, 125, 199, 39, 17, 191, 77, 199, 39, 17, - 108, 199, 39, 17, 109, 199, 39, 17, 139, 199, 39, 17, 137, 199, 39, 17, - 153, 199, 39, 17, 173, 199, 39, 17, 181, 199, 39, 17, 176, 199, 39, 17, - 184, 199, 39, 246, 192, 251, 66, 199, 39, 246, 192, 221, 156, 219, 249, - 1, 221, 43, 219, 249, 1, 221, 160, 200, 190, 219, 249, 1, 221, 160, 199, - 192, 219, 249, 1, 210, 177, 231, 54, 219, 249, 1, 213, 235, 219, 249, 1, - 242, 51, 219, 249, 1, 210, 177, 246, 209, 219, 249, 1, 202, 42, 199, 192, - 219, 249, 1, 210, 177, 222, 225, 219, 249, 1, 212, 52, 219, 249, 1, 210, - 177, 212, 88, 219, 249, 1, 210, 177, 197, 128, 219, 249, 1, 210, 177, - 197, 116, 219, 249, 1, 210, 177, 237, 146, 219, 249, 1, 210, 177, 237, - 130, 219, 249, 1, 210, 177, 213, 66, 219, 249, 1, 236, 129, 219, 249, 1, - 159, 219, 249, 1, 198, 237, 200, 190, 219, 249, 1, 198, 237, 199, 192, - 219, 249, 1, 210, 177, 237, 23, 219, 249, 1, 213, 30, 219, 249, 1, 248, - 63, 219, 249, 1, 209, 65, 219, 249, 1, 209, 191, 200, 190, 219, 249, 1, - 232, 136, 199, 192, 219, 249, 1, 209, 191, 199, 192, 219, 249, 1, 232, - 136, 200, 190, 219, 249, 1, 210, 177, 248, 153, 219, 249, 1, 215, 251, - 219, 249, 1, 192, 12, 219, 249, 1, 219, 20, 219, 81, 219, 249, 1, 219, - 20, 218, 234, 219, 249, 1, 193, 48, 219, 249, 1, 205, 129, 203, 160, 219, - 249, 1, 205, 129, 201, 170, 219, 249, 1, 202, 42, 200, 190, 219, 249, 1, - 228, 248, 200, 190, 219, 249, 1, 210, 177, 219, 49, 219, 249, 1, 74, 219, - 249, 1, 228, 248, 199, 192, 219, 249, 234, 78, 219, 249, 18, 3, 65, 219, - 249, 18, 3, 217, 92, 222, 61, 219, 249, 18, 3, 252, 154, 219, 249, 18, 3, - 251, 98, 219, 249, 18, 3, 70, 219, 249, 18, 3, 223, 170, 219, 249, 18, 3, - 192, 159, 219, 249, 18, 3, 191, 176, 219, 249, 18, 3, 69, 219, 249, 18, - 3, 196, 26, 219, 249, 3, 210, 177, 195, 37, 219, 249, 18, 3, 217, 92, - 221, 20, 219, 249, 204, 15, 3, 219, 19, 219, 249, 204, 15, 3, 212, 52, - 219, 249, 18, 3, 73, 219, 249, 18, 3, 234, 123, 219, 249, 18, 3, 74, 219, - 249, 18, 3, 250, 81, 219, 249, 18, 3, 251, 184, 219, 249, 221, 44, 171, - 219, 249, 163, 217, 92, 234, 104, 219, 249, 163, 217, 92, 198, 236, 219, - 249, 163, 217, 92, 198, 188, 219, 249, 163, 217, 92, 247, 29, 219, 249, - 247, 77, 77, 219, 249, 213, 178, 219, 249, 17, 191, 77, 219, 249, 17, - 108, 219, 249, 17, 109, 219, 249, 17, 139, 219, 249, 17, 137, 219, 249, - 17, 153, 219, 249, 17, 173, 219, 249, 17, 181, 219, 249, 17, 176, 219, - 249, 17, 184, 219, 249, 228, 248, 213, 30, 219, 249, 228, 248, 215, 251, - 219, 249, 1, 221, 161, 230, 223, 219, 249, 1, 221, 161, 212, 52, 86, 5, - 211, 102, 86, 87, 230, 148, 192, 25, 216, 99, 197, 174, 65, 86, 87, 230, - 148, 192, 25, 216, 99, 255, 155, 206, 162, 248, 225, 172, 86, 87, 230, - 148, 192, 25, 216, 99, 255, 155, 230, 148, 197, 149, 172, 86, 87, 89, - 192, 25, 216, 99, 216, 215, 172, 86, 87, 242, 167, 192, 25, 216, 99, 203, - 167, 172, 86, 87, 247, 49, 192, 25, 216, 99, 209, 180, 203, 153, 172, 86, - 87, 192, 25, 216, 99, 197, 149, 203, 153, 172, 86, 87, 205, 95, 203, 152, - 86, 87, 247, 221, 192, 25, 216, 98, 86, 87, 248, 93, 203, 45, 192, 25, - 216, 98, 86, 87, 223, 70, 197, 148, 86, 87, 237, 68, 197, 149, 247, 220, - 86, 87, 203, 152, 86, 87, 212, 57, 203, 152, 86, 87, 197, 149, 203, 152, - 86, 87, 212, 57, 197, 149, 203, 152, 86, 87, 206, 186, 243, 63, 201, 188, - 203, 152, 86, 87, 207, 5, 230, 188, 203, 152, 86, 87, 247, 49, 255, 159, - 206, 68, 216, 214, 177, 247, 80, 86, 87, 230, 148, 197, 148, 86, 219, 3, - 3, 246, 207, 206, 67, 86, 219, 3, 3, 219, 133, 206, 67, 86, 250, 138, 3, - 203, 163, 231, 131, 255, 160, 206, 67, 86, 250, 138, 3, 255, 157, 168, - 86, 250, 138, 3, 205, 64, 197, 143, 86, 3, 207, 110, 236, 144, 231, 130, - 86, 3, 207, 110, 236, 144, 230, 225, 86, 3, 207, 110, 236, 144, 230, 149, - 86, 3, 207, 110, 214, 229, 231, 130, 86, 3, 207, 110, 214, 229, 230, 225, - 86, 3, 207, 110, 236, 144, 207, 110, 214, 228, 86, 17, 191, 77, 86, 17, - 108, 86, 17, 109, 86, 17, 139, 86, 17, 137, 86, 17, 153, 86, 17, 173, 86, - 17, 181, 86, 17, 176, 86, 17, 184, 86, 17, 134, 108, 86, 17, 134, 109, - 86, 17, 134, 139, 86, 17, 134, 137, 86, 17, 134, 153, 86, 17, 134, 173, - 86, 17, 134, 181, 86, 17, 134, 176, 86, 17, 134, 184, 86, 17, 134, 191, - 77, 86, 87, 247, 223, 206, 67, 86, 87, 214, 45, 247, 147, 212, 69, 191, - 10, 86, 87, 247, 49, 255, 159, 206, 68, 247, 148, 216, 44, 247, 80, 86, - 87, 214, 45, 247, 147, 203, 164, 206, 67, 86, 87, 243, 80, 216, 98, 86, - 87, 197, 165, 255, 156, 86, 87, 230, 131, 206, 68, 230, 86, 86, 87, 230, - 131, 206, 68, 230, 92, 86, 87, 251, 72, 221, 178, 230, 86, 86, 87, 251, - 72, 221, 178, 230, 92, 86, 3, 192, 102, 197, 147, 86, 3, 217, 46, 197, - 147, 86, 1, 157, 86, 1, 221, 190, 86, 1, 231, 203, 86, 1, 231, 54, 86, 1, - 214, 54, 86, 1, 247, 112, 86, 1, 246, 209, 86, 1, 223, 4, 86, 1, 212, 88, - 86, 1, 197, 128, 86, 1, 197, 116, 86, 1, 237, 146, 86, 1, 237, 130, 86, - 1, 213, 66, 86, 1, 199, 247, 86, 1, 199, 44, 86, 1, 237, 241, 86, 1, 237, - 23, 86, 1, 180, 86, 1, 168, 86, 1, 209, 219, 86, 1, 249, 103, 86, 1, 248, - 153, 86, 1, 172, 86, 1, 197, 164, 86, 1, 197, 153, 86, 1, 234, 247, 86, - 1, 234, 241, 86, 1, 193, 187, 86, 1, 191, 71, 86, 1, 191, 123, 86, 1, - 255, 162, 86, 1, 169, 86, 1, 166, 86, 1, 171, 86, 1, 203, 160, 86, 1, - 201, 170, 86, 1, 189, 86, 1, 144, 86, 1, 65, 86, 1, 220, 222, 86, 1, 232, - 181, 166, 86, 1, 221, 77, 86, 1, 206, 104, 86, 18, 3, 252, 154, 86, 18, - 3, 70, 86, 18, 3, 223, 170, 86, 18, 3, 69, 86, 18, 3, 196, 26, 86, 18, 3, - 121, 148, 86, 18, 3, 121, 206, 105, 86, 18, 3, 121, 170, 86, 18, 3, 121, - 219, 50, 86, 18, 3, 73, 86, 18, 3, 234, 145, 86, 18, 3, 74, 86, 18, 3, - 211, 76, 86, 3, 206, 168, 201, 0, 214, 55, 206, 157, 86, 3, 206, 162, - 248, 224, 86, 18, 3, 207, 13, 70, 86, 18, 3, 207, 13, 223, 170, 86, 3, - 212, 69, 191, 11, 214, 237, 237, 241, 86, 3, 202, 56, 219, 216, 86, 87, - 230, 39, 86, 87, 210, 168, 86, 3, 219, 219, 206, 67, 86, 3, 192, 107, - 206, 67, 86, 3, 219, 220, 197, 165, 247, 80, 86, 3, 216, 217, 247, 80, - 86, 3, 230, 152, 247, 81, 207, 3, 86, 3, 230, 152, 216, 201, 207, 3, 86, - 3, 223, 65, 216, 217, 247, 80, 86, 200, 234, 3, 219, 220, 197, 165, 247, - 80, 86, 200, 234, 3, 216, 217, 247, 80, 86, 200, 234, 3, 223, 65, 216, - 217, 247, 80, 86, 200, 234, 1, 157, 86, 200, 234, 1, 221, 190, 86, 200, - 234, 1, 231, 203, 86, 200, 234, 1, 231, 54, 86, 200, 234, 1, 214, 54, 86, - 200, 234, 1, 247, 112, 86, 200, 234, 1, 246, 209, 86, 200, 234, 1, 223, - 4, 86, 200, 234, 1, 212, 88, 86, 200, 234, 1, 197, 128, 86, 200, 234, 1, - 197, 116, 86, 200, 234, 1, 237, 146, 86, 200, 234, 1, 237, 130, 86, 200, - 234, 1, 213, 66, 86, 200, 234, 1, 199, 247, 86, 200, 234, 1, 199, 44, 86, - 200, 234, 1, 237, 241, 86, 200, 234, 1, 237, 23, 86, 200, 234, 1, 180, - 86, 200, 234, 1, 168, 86, 200, 234, 1, 209, 219, 86, 200, 234, 1, 249, - 103, 86, 200, 234, 1, 248, 153, 86, 200, 234, 1, 172, 86, 200, 234, 1, - 197, 164, 86, 200, 234, 1, 197, 153, 86, 200, 234, 1, 234, 247, 86, 200, - 234, 1, 234, 241, 86, 200, 234, 1, 193, 187, 86, 200, 234, 1, 191, 71, - 86, 200, 234, 1, 191, 123, 86, 200, 234, 1, 255, 162, 86, 200, 234, 1, - 169, 86, 200, 234, 1, 166, 86, 200, 234, 1, 171, 86, 200, 234, 1, 203, - 160, 86, 200, 234, 1, 201, 170, 86, 200, 234, 1, 189, 86, 200, 234, 1, - 144, 86, 200, 234, 1, 65, 86, 200, 234, 1, 220, 222, 86, 200, 234, 1, - 232, 181, 193, 187, 86, 200, 234, 1, 232, 181, 169, 86, 200, 234, 1, 232, - 181, 166, 86, 220, 209, 206, 64, 221, 190, 86, 220, 209, 206, 64, 221, - 191, 247, 148, 216, 44, 247, 80, 86, 247, 64, 3, 88, 248, 213, 86, 247, - 64, 3, 155, 248, 213, 86, 247, 64, 3, 247, 68, 199, 130, 86, 247, 64, 3, - 205, 94, 255, 161, 86, 16, 235, 61, 247, 218, 86, 16, 207, 109, 206, 169, - 86, 16, 210, 196, 231, 129, 86, 16, 207, 109, 206, 170, 207, 5, 230, 187, - 86, 16, 209, 180, 168, 86, 16, 213, 8, 247, 218, 86, 16, 213, 8, 247, - 219, 212, 57, 255, 158, 86, 16, 213, 8, 247, 219, 230, 150, 255, 158, 86, - 16, 213, 8, 247, 219, 247, 148, 255, 158, 86, 3, 207, 110, 214, 229, 207, - 110, 236, 143, 86, 3, 207, 110, 214, 229, 230, 149, 86, 87, 247, 222, - 203, 45, 231, 17, 216, 99, 207, 4, 86, 87, 215, 253, 192, 25, 231, 17, - 216, 99, 207, 4, 86, 87, 212, 57, 197, 148, 86, 87, 89, 247, 252, 206, - 159, 192, 25, 216, 99, 216, 215, 172, 86, 87, 242, 167, 247, 252, 206, - 159, 192, 25, 216, 99, 203, 167, 172, 206, 202, 200, 151, 57, 219, 199, - 200, 151, 57, 206, 202, 200, 151, 3, 4, 236, 94, 219, 199, 200, 151, 3, - 4, 236, 94, 86, 87, 219, 211, 216, 218, 206, 67, 86, 87, 198, 14, 216, - 218, 206, 67, 79, 1, 157, 79, 1, 221, 190, 79, 1, 231, 203, 79, 1, 231, - 54, 79, 1, 214, 54, 79, 1, 247, 112, 79, 1, 246, 209, 79, 1, 223, 4, 79, - 1, 222, 225, 79, 1, 212, 88, 79, 1, 213, 32, 79, 1, 197, 128, 79, 1, 197, - 116, 79, 1, 237, 146, 79, 1, 237, 130, 79, 1, 213, 66, 79, 1, 199, 247, - 79, 1, 199, 44, 79, 1, 237, 241, 79, 1, 237, 23, 79, 1, 180, 79, 1, 168, - 79, 1, 209, 219, 79, 1, 249, 103, 79, 1, 248, 153, 79, 1, 172, 79, 1, - 169, 79, 1, 166, 79, 1, 171, 79, 1, 193, 187, 79, 1, 189, 79, 1, 144, 79, - 1, 219, 49, 79, 1, 65, 79, 1, 203, 134, 65, 79, 1, 70, 79, 1, 223, 170, - 79, 1, 69, 79, 1, 196, 26, 79, 1, 73, 79, 1, 215, 215, 73, 79, 1, 74, 79, - 1, 250, 113, 79, 18, 3, 199, 195, 252, 154, 79, 18, 3, 252, 154, 79, 18, - 3, 70, 79, 18, 3, 223, 170, 79, 18, 3, 69, 79, 18, 3, 196, 26, 79, 18, 3, - 73, 79, 18, 3, 251, 184, 79, 18, 3, 215, 215, 223, 170, 79, 18, 3, 215, - 215, 74, 79, 18, 3, 234, 227, 56, 79, 3, 251, 20, 79, 3, 75, 60, 79, 3, - 195, 32, 79, 3, 195, 37, 79, 3, 250, 164, 79, 119, 3, 216, 198, 169, 79, - 119, 3, 216, 198, 166, 79, 119, 3, 216, 198, 193, 187, 79, 119, 3, 216, - 198, 144, 79, 1, 230, 172, 189, 79, 17, 191, 77, 79, 17, 108, 79, 17, - 109, 79, 17, 139, 79, 17, 137, 79, 17, 153, 79, 17, 173, 79, 17, 181, 79, - 17, 176, 79, 17, 184, 79, 3, 219, 59, 205, 48, 79, 3, 205, 48, 79, 16, - 219, 12, 79, 16, 242, 19, 79, 16, 251, 205, 79, 16, 231, 109, 79, 1, 203, - 160, 79, 1, 201, 170, 79, 1, 121, 148, 79, 1, 121, 206, 105, 79, 1, 121, - 170, 79, 1, 121, 219, 50, 79, 18, 3, 121, 148, 79, 18, 3, 121, 206, 105, - 79, 18, 3, 121, 170, 79, 18, 3, 121, 219, 50, 79, 1, 215, 215, 214, 54, - 79, 1, 215, 215, 222, 225, 79, 1, 215, 215, 249, 3, 79, 1, 215, 215, 248, - 254, 79, 119, 3, 215, 215, 216, 198, 180, 79, 119, 3, 215, 215, 216, 198, - 172, 79, 119, 3, 215, 215, 216, 198, 171, 79, 1, 203, 166, 222, 36, 203, - 160, 79, 18, 3, 203, 166, 222, 36, 233, 201, 79, 163, 87, 203, 166, 222, - 36, 229, 228, 79, 163, 87, 203, 166, 222, 36, 221, 254, 209, 190, 79, 1, - 193, 100, 208, 109, 222, 36, 199, 44, 79, 1, 193, 100, 208, 109, 222, 36, - 208, 115, 79, 18, 3, 193, 100, 208, 109, 222, 36, 233, 201, 79, 18, 3, - 193, 100, 208, 109, 222, 36, 196, 148, 79, 3, 193, 100, 208, 109, 222, - 36, 198, 73, 79, 3, 193, 100, 208, 109, 222, 36, 198, 72, 79, 3, 193, - 100, 208, 109, 222, 36, 198, 71, 79, 3, 193, 100, 208, 109, 222, 36, 198, - 70, 79, 3, 193, 100, 208, 109, 222, 36, 198, 69, 79, 1, 234, 158, 208, - 109, 222, 36, 213, 66, 79, 1, 234, 158, 208, 109, 222, 36, 191, 183, 79, - 1, 234, 158, 208, 109, 222, 36, 231, 19, 79, 18, 3, 231, 124, 222, 36, - 70, 79, 18, 3, 222, 3, 211, 139, 79, 18, 3, 222, 3, 69, 79, 18, 3, 222, - 3, 234, 145, 79, 1, 203, 134, 157, 79, 1, 203, 134, 221, 190, 79, 1, 203, - 134, 231, 203, 79, 1, 203, 134, 247, 112, 79, 1, 203, 134, 191, 123, 79, - 1, 203, 134, 212, 88, 79, 1, 203, 134, 237, 241, 79, 1, 203, 134, 180, - 79, 1, 203, 134, 209, 219, 79, 1, 203, 134, 233, 68, 79, 1, 203, 134, - 249, 103, 79, 1, 203, 134, 199, 44, 79, 1, 203, 134, 144, 79, 119, 3, - 203, 134, 216, 198, 193, 187, 79, 18, 3, 203, 134, 252, 154, 79, 18, 3, - 203, 134, 73, 79, 18, 3, 203, 134, 234, 227, 56, 79, 18, 3, 203, 134, 52, - 192, 159, 79, 3, 203, 134, 198, 72, 79, 3, 203, 134, 198, 71, 79, 3, 203, - 134, 198, 69, 79, 3, 203, 134, 198, 68, 79, 3, 203, 134, 238, 200, 198, - 72, 79, 3, 203, 134, 238, 200, 198, 71, 79, 3, 203, 134, 238, 200, 234, - 64, 198, 74, 79, 1, 206, 42, 210, 179, 233, 68, 79, 3, 206, 42, 210, 179, - 198, 69, 79, 203, 134, 17, 191, 77, 79, 203, 134, 17, 108, 79, 203, 134, - 17, 109, 79, 203, 134, 17, 139, 79, 203, 134, 17, 137, 79, 203, 134, 17, - 153, 79, 203, 134, 17, 173, 79, 203, 134, 17, 181, 79, 203, 134, 17, 176, - 79, 203, 134, 17, 184, 79, 3, 221, 181, 198, 73, 79, 3, 221, 181, 198, - 71, 79, 18, 3, 251, 170, 65, 79, 18, 3, 251, 170, 251, 184, 79, 16, 203, - 134, 108, 79, 16, 203, 134, 233, 174, 100, 6, 1, 251, 81, 100, 6, 1, 249, - 51, 100, 6, 1, 231, 173, 100, 6, 1, 236, 105, 100, 6, 1, 234, 61, 100, 6, - 1, 195, 46, 100, 6, 1, 191, 80, 100, 6, 1, 199, 188, 100, 6, 1, 223, 134, - 100, 6, 1, 222, 61, 100, 6, 1, 219, 239, 100, 6, 1, 217, 70, 100, 6, 1, - 214, 202, 100, 6, 1, 211, 93, 100, 6, 1, 210, 121, 100, 6, 1, 191, 67, - 100, 6, 1, 207, 158, 100, 6, 1, 205, 137, 100, 6, 1, 199, 174, 100, 6, 1, - 196, 109, 100, 6, 1, 209, 211, 100, 6, 1, 221, 176, 100, 6, 1, 231, 45, - 100, 6, 1, 208, 74, 100, 6, 1, 203, 64, 100, 6, 1, 243, 33, 100, 6, 1, - 247, 80, 100, 6, 1, 222, 207, 100, 6, 1, 242, 226, 100, 6, 1, 246, 193, - 100, 6, 1, 192, 218, 100, 6, 1, 222, 222, 100, 6, 1, 230, 54, 100, 6, 1, - 229, 213, 100, 6, 1, 229, 113, 100, 6, 1, 193, 123, 100, 6, 1, 229, 242, - 100, 6, 1, 228, 235, 100, 6, 1, 192, 14, 100, 6, 1, 251, 218, 100, 1, - 251, 81, 100, 1, 249, 51, 100, 1, 231, 173, 100, 1, 236, 105, 100, 1, - 234, 61, 100, 1, 195, 46, 100, 1, 191, 80, 100, 1, 199, 188, 100, 1, 223, - 134, 100, 1, 222, 61, 100, 1, 219, 239, 100, 1, 217, 70, 100, 1, 214, - 202, 100, 1, 211, 93, 100, 1, 210, 121, 100, 1, 191, 67, 100, 1, 207, - 158, 100, 1, 205, 137, 100, 1, 199, 174, 100, 1, 196, 109, 100, 1, 209, - 211, 100, 1, 221, 176, 100, 1, 231, 45, 100, 1, 208, 74, 100, 1, 203, 64, - 100, 1, 243, 33, 100, 1, 247, 80, 100, 1, 222, 207, 100, 1, 242, 226, - 100, 1, 246, 193, 100, 1, 192, 218, 100, 1, 222, 222, 100, 1, 230, 54, - 100, 1, 229, 213, 100, 1, 229, 113, 100, 1, 193, 123, 100, 1, 229, 242, - 100, 1, 228, 235, 100, 1, 232, 238, 100, 1, 192, 14, 100, 1, 234, 80, - 100, 1, 152, 231, 173, 100, 1, 251, 178, 100, 210, 118, 204, 5, 59, 1, - 100, 214, 202, 100, 1, 251, 218, 100, 1, 229, 240, 57, 100, 1, 220, 92, - 57, 30, 146, 221, 89, 30, 146, 201, 162, 30, 146, 213, 190, 30, 146, 198, - 163, 30, 146, 201, 151, 30, 146, 206, 234, 30, 146, 216, 59, 30, 146, - 209, 160, 30, 146, 201, 159, 30, 146, 202, 155, 30, 146, 201, 156, 30, - 146, 223, 193, 30, 146, 242, 232, 30, 146, 201, 166, 30, 146, 243, 43, - 30, 146, 221, 164, 30, 146, 199, 2, 30, 146, 209, 200, 30, 146, 229, 110, - 30, 146, 213, 186, 30, 146, 201, 160, 30, 146, 213, 180, 30, 146, 213, - 184, 30, 146, 198, 160, 30, 146, 206, 222, 30, 146, 201, 158, 30, 146, - 206, 232, 30, 146, 222, 42, 30, 146, 216, 52, 30, 146, 222, 45, 30, 146, - 209, 155, 30, 146, 209, 153, 30, 146, 209, 141, 30, 146, 209, 149, 30, - 146, 209, 147, 30, 146, 209, 144, 30, 146, 209, 146, 30, 146, 209, 143, - 30, 146, 209, 148, 30, 146, 209, 158, 30, 146, 209, 159, 30, 146, 209, - 142, 30, 146, 209, 152, 30, 146, 222, 43, 30, 146, 222, 41, 30, 146, 202, - 148, 30, 146, 202, 146, 30, 146, 202, 138, 30, 146, 202, 141, 30, 146, - 202, 147, 30, 146, 202, 143, 30, 146, 202, 142, 30, 146, 202, 140, 30, - 146, 202, 151, 30, 146, 202, 153, 30, 146, 202, 154, 30, 146, 202, 149, - 30, 146, 202, 139, 30, 146, 202, 144, 30, 146, 202, 152, 30, 146, 243, - 24, 30, 146, 243, 22, 30, 146, 246, 222, 30, 146, 246, 220, 30, 146, 210, - 139, 30, 146, 223, 188, 30, 146, 223, 179, 30, 146, 223, 187, 30, 146, - 223, 184, 30, 146, 223, 182, 30, 146, 223, 186, 30, 146, 201, 163, 30, - 146, 223, 191, 30, 146, 223, 192, 30, 146, 223, 180, 30, 146, 223, 185, - 30, 146, 192, 57, 30, 146, 242, 231, 30, 146, 243, 25, 30, 146, 243, 23, - 30, 146, 246, 223, 30, 146, 246, 221, 30, 146, 243, 41, 30, 146, 243, 42, - 30, 146, 243, 26, 30, 146, 246, 224, 30, 146, 209, 198, 30, 146, 222, 44, - 30, 146, 201, 164, 30, 146, 192, 63, 30, 146, 221, 80, 30, 146, 213, 182, - 30, 146, 213, 188, 30, 146, 213, 187, 30, 146, 198, 157, 30, 146, 232, - 218, 30, 222, 147, 232, 218, 30, 222, 147, 65, 30, 222, 147, 251, 229, - 30, 222, 147, 169, 30, 222, 147, 192, 129, 30, 222, 147, 234, 23, 30, - 222, 147, 73, 30, 222, 147, 192, 67, 30, 222, 147, 192, 80, 30, 222, 147, - 74, 30, 222, 147, 193, 187, 30, 222, 147, 193, 173, 30, 222, 147, 211, - 139, 30, 222, 147, 192, 12, 30, 222, 147, 69, 30, 222, 147, 193, 105, 30, - 222, 147, 193, 123, 30, 222, 147, 193, 84, 30, 222, 147, 191, 225, 30, - 222, 147, 233, 201, 30, 222, 147, 192, 33, 30, 222, 147, 70, 30, 222, - 147, 255, 150, 30, 222, 147, 255, 149, 30, 222, 147, 192, 143, 30, 222, - 147, 192, 141, 30, 222, 147, 234, 21, 30, 222, 147, 234, 20, 30, 222, - 147, 234, 22, 30, 222, 147, 192, 66, 30, 222, 147, 192, 65, 30, 222, 147, - 211, 253, 30, 222, 147, 211, 254, 30, 222, 147, 211, 247, 30, 222, 147, - 211, 252, 30, 222, 147, 211, 250, 30, 222, 147, 192, 0, 30, 222, 147, - 191, 255, 30, 222, 147, 191, 254, 30, 222, 147, 192, 1, 30, 222, 147, - 192, 2, 30, 222, 147, 196, 222, 30, 222, 147, 196, 221, 30, 222, 147, - 196, 219, 30, 222, 147, 196, 215, 30, 222, 147, 196, 216, 30, 222, 147, - 191, 220, 30, 222, 147, 191, 217, 30, 222, 147, 191, 218, 30, 222, 147, - 191, 212, 30, 222, 147, 191, 213, 30, 222, 147, 191, 214, 30, 222, 147, - 191, 216, 30, 222, 147, 233, 195, 30, 222, 147, 233, 197, 30, 222, 147, - 192, 32, 30, 222, 147, 228, 39, 30, 222, 147, 228, 31, 30, 222, 147, 228, - 34, 30, 222, 147, 228, 32, 30, 222, 147, 228, 36, 30, 222, 147, 228, 38, - 30, 222, 147, 250, 231, 30, 222, 147, 250, 228, 30, 222, 147, 250, 226, - 30, 222, 147, 250, 227, 30, 222, 147, 201, 167, 30, 222, 147, 255, 151, - 30, 222, 147, 192, 142, 30, 222, 147, 192, 64, 30, 222, 147, 211, 249, - 30, 222, 147, 211, 248, 30, 125, 221, 89, 30, 125, 201, 162, 30, 125, - 221, 82, 30, 125, 213, 190, 30, 125, 213, 188, 30, 125, 213, 187, 30, - 125, 198, 163, 30, 125, 206, 234, 30, 125, 206, 229, 30, 125, 206, 226, - 30, 125, 206, 219, 30, 125, 206, 214, 30, 125, 206, 209, 30, 125, 206, - 220, 30, 125, 206, 232, 30, 125, 216, 59, 30, 125, 209, 160, 30, 125, - 209, 149, 30, 125, 202, 155, 30, 125, 201, 156, 30, 125, 223, 193, 30, - 125, 242, 232, 30, 125, 243, 43, 30, 125, 221, 164, 30, 125, 199, 2, 30, - 125, 209, 200, 30, 125, 229, 110, 30, 125, 221, 83, 30, 125, 221, 81, 30, - 125, 213, 186, 30, 125, 213, 180, 30, 125, 213, 182, 30, 125, 213, 185, - 30, 125, 213, 181, 30, 125, 198, 160, 30, 125, 198, 157, 30, 125, 206, - 227, 30, 125, 206, 222, 30, 125, 206, 208, 30, 125, 206, 207, 30, 125, - 201, 158, 30, 125, 206, 224, 30, 125, 206, 223, 30, 125, 206, 216, 30, - 125, 206, 218, 30, 125, 206, 231, 30, 125, 206, 211, 30, 125, 206, 221, - 30, 125, 206, 230, 30, 125, 206, 206, 30, 125, 216, 55, 30, 125, 216, 50, - 30, 125, 216, 52, 30, 125, 216, 49, 30, 125, 216, 47, 30, 125, 216, 53, - 30, 125, 216, 58, 30, 125, 216, 56, 30, 125, 222, 45, 30, 125, 209, 151, - 30, 125, 209, 152, 30, 125, 209, 157, 30, 125, 222, 43, 30, 125, 202, - 148, 30, 125, 202, 138, 30, 125, 202, 141, 30, 125, 202, 143, 30, 125, - 210, 139, 30, 125, 223, 188, 30, 125, 223, 181, 30, 125, 201, 163, 30, - 125, 223, 189, 30, 125, 192, 57, 30, 125, 192, 51, 30, 125, 192, 52, 30, - 125, 209, 198, 30, 125, 222, 44, 30, 125, 229, 108, 30, 125, 229, 106, - 30, 125, 229, 109, 30, 125, 229, 107, 30, 125, 192, 63, 30, 125, 221, 85, - 30, 125, 221, 84, 30, 125, 221, 88, 30, 125, 221, 86, 30, 125, 221, 87, - 30, 125, 201, 160, 36, 5, 144, 36, 5, 228, 128, 36, 5, 229, 126, 36, 5, - 230, 58, 36, 5, 229, 183, 36, 5, 229, 213, 36, 5, 228, 247, 36, 5, 228, - 238, 36, 5, 171, 36, 5, 218, 203, 36, 5, 219, 122, 36, 5, 220, 101, 36, - 5, 219, 204, 36, 5, 219, 214, 36, 5, 219, 19, 36, 5, 218, 170, 36, 5, - 229, 145, 36, 5, 229, 139, 36, 5, 229, 141, 36, 5, 229, 144, 36, 5, 229, - 142, 36, 5, 229, 143, 36, 5, 229, 140, 36, 5, 229, 138, 36, 5, 172, 36, - 5, 215, 139, 36, 5, 216, 81, 36, 5, 217, 130, 36, 5, 216, 192, 36, 5, - 216, 213, 36, 5, 215, 251, 36, 5, 215, 66, 36, 5, 200, 50, 36, 5, 200, - 44, 36, 5, 200, 46, 36, 5, 200, 49, 36, 5, 200, 47, 36, 5, 200, 48, 36, - 5, 200, 45, 36, 5, 200, 43, 36, 5, 166, 36, 5, 206, 63, 36, 5, 206, 252, - 36, 5, 207, 173, 36, 5, 207, 79, 36, 5, 207, 108, 36, 5, 206, 157, 36, 5, - 206, 21, 36, 5, 189, 36, 5, 200, 255, 36, 5, 202, 217, 36, 5, 205, 192, - 36, 5, 205, 45, 36, 5, 205, 63, 36, 5, 202, 41, 36, 5, 200, 146, 36, 5, - 203, 160, 36, 5, 203, 0, 36, 5, 203, 76, 36, 5, 203, 155, 36, 5, 203, - 106, 36, 5, 203, 108, 36, 5, 203, 51, 36, 5, 202, 235, 36, 5, 208, 89, - 36, 5, 208, 27, 36, 5, 208, 51, 36, 5, 208, 88, 36, 5, 208, 68, 36, 5, - 208, 69, 36, 5, 208, 39, 36, 5, 208, 38, 36, 5, 207, 235, 36, 5, 207, - 231, 36, 5, 207, 234, 36, 5, 207, 232, 36, 5, 207, 233, 36, 5, 208, 65, - 36, 5, 208, 57, 36, 5, 208, 60, 36, 5, 208, 64, 36, 5, 208, 61, 36, 5, - 208, 62, 36, 5, 208, 59, 36, 5, 208, 56, 36, 5, 208, 52, 36, 5, 208, 55, - 36, 5, 208, 53, 36, 5, 208, 54, 36, 5, 249, 103, 36, 5, 247, 218, 36, 5, - 248, 140, 36, 5, 249, 101, 36, 5, 248, 207, 36, 5, 248, 223, 36, 5, 248, - 63, 36, 5, 247, 162, 36, 5, 195, 185, 36, 5, 193, 246, 36, 5, 195, 66, - 36, 5, 195, 184, 36, 5, 195, 145, 36, 5, 195, 150, 36, 5, 195, 21, 36, 5, - 193, 235, 36, 5, 199, 247, 36, 5, 197, 90, 36, 5, 198, 188, 36, 5, 199, - 240, 36, 5, 199, 116, 36, 5, 199, 140, 36, 5, 159, 36, 5, 197, 39, 36, 5, - 247, 112, 36, 5, 238, 148, 36, 5, 242, 237, 36, 5, 247, 111, 36, 5, 246, - 242, 36, 5, 246, 250, 36, 5, 242, 51, 36, 5, 238, 104, 36, 5, 192, 220, - 36, 5, 192, 188, 36, 5, 192, 207, 36, 5, 192, 219, 36, 5, 192, 213, 36, - 5, 192, 214, 36, 5, 192, 196, 36, 5, 192, 195, 36, 5, 192, 181, 36, 5, - 192, 177, 36, 5, 192, 180, 36, 5, 192, 178, 36, 5, 192, 179, 36, 5, 180, - 36, 5, 212, 165, 36, 5, 213, 205, 36, 5, 214, 236, 36, 5, 214, 96, 36, 5, - 214, 107, 36, 5, 213, 30, 36, 5, 212, 97, 36, 5, 212, 88, 36, 5, 212, 45, - 36, 5, 212, 68, 36, 5, 212, 87, 36, 5, 212, 76, 36, 5, 212, 77, 36, 5, - 212, 52, 36, 5, 212, 35, 36, 5, 230, 231, 65, 36, 5, 230, 231, 69, 36, 5, - 230, 231, 70, 36, 5, 230, 231, 252, 154, 36, 5, 230, 231, 234, 145, 36, - 5, 230, 231, 73, 36, 5, 230, 231, 74, 36, 5, 230, 231, 193, 187, 36, 5, - 157, 36, 5, 220, 208, 36, 5, 221, 142, 36, 5, 222, 100, 36, 5, 221, 244, - 36, 5, 221, 253, 36, 5, 221, 43, 36, 5, 221, 38, 36, 5, 220, 155, 36, 5, - 220, 148, 36, 5, 220, 154, 36, 5, 220, 149, 36, 5, 220, 150, 36, 5, 220, - 141, 36, 5, 220, 135, 36, 5, 220, 137, 36, 5, 220, 140, 36, 5, 220, 138, - 36, 5, 220, 139, 36, 5, 220, 136, 36, 5, 220, 134, 36, 5, 220, 130, 36, - 5, 220, 133, 36, 5, 220, 131, 36, 5, 220, 132, 36, 5, 193, 187, 36, 5, - 193, 0, 36, 5, 193, 84, 36, 5, 193, 178, 36, 5, 193, 112, 36, 5, 193, - 123, 36, 5, 193, 48, 36, 5, 193, 40, 36, 5, 209, 210, 65, 36, 5, 209, - 210, 69, 36, 5, 209, 210, 70, 36, 5, 209, 210, 252, 154, 36, 5, 209, 210, - 234, 145, 36, 5, 209, 210, 73, 36, 5, 209, 210, 74, 36, 5, 191, 123, 36, - 5, 190, 251, 36, 5, 191, 30, 36, 5, 191, 121, 36, 5, 191, 84, 36, 5, 191, - 87, 36, 5, 191, 7, 36, 5, 190, 238, 36, 5, 191, 71, 36, 5, 191, 48, 36, - 5, 191, 57, 36, 5, 191, 70, 36, 5, 191, 61, 36, 5, 191, 62, 36, 5, 191, - 54, 36, 5, 191, 39, 36, 5, 169, 36, 5, 191, 225, 36, 5, 192, 33, 36, 5, - 192, 140, 36, 5, 192, 77, 36, 5, 192, 80, 36, 5, 192, 12, 36, 5, 191, - 252, 36, 5, 237, 241, 36, 5, 235, 45, 36, 5, 236, 255, 36, 5, 237, 240, - 36, 5, 237, 86, 36, 5, 237, 101, 36, 5, 236, 129, 36, 5, 235, 2, 36, 5, - 237, 146, 36, 5, 237, 111, 36, 5, 237, 123, 36, 5, 237, 145, 36, 5, 237, - 133, 36, 5, 237, 134, 36, 5, 237, 116, 36, 5, 237, 102, 36, 5, 223, 4, - 36, 5, 222, 155, 36, 5, 222, 217, 36, 5, 223, 3, 36, 5, 222, 236, 36, 5, - 222, 238, 36, 5, 222, 174, 36, 5, 222, 133, 36, 5, 231, 203, 36, 5, 230, - 146, 36, 5, 231, 16, 36, 5, 231, 200, 36, 5, 231, 120, 36, 5, 231, 128, - 36, 5, 230, 223, 36, 5, 230, 222, 36, 5, 230, 102, 36, 5, 230, 98, 36, 5, - 230, 101, 36, 5, 230, 99, 36, 5, 230, 100, 36, 5, 231, 90, 36, 5, 231, - 70, 36, 5, 231, 80, 36, 5, 231, 89, 36, 5, 231, 84, 36, 5, 231, 85, 36, - 5, 231, 74, 36, 5, 231, 59, 36, 5, 199, 44, 36, 5, 198, 208, 36, 5, 199, - 6, 36, 5, 199, 43, 36, 5, 199, 26, 36, 5, 199, 28, 36, 5, 198, 236, 36, - 5, 198, 199, 36, 5, 246, 209, 36, 5, 243, 0, 36, 5, 243, 47, 36, 5, 246, - 208, 36, 5, 243, 75, 36, 5, 243, 79, 36, 5, 243, 20, 36, 5, 242, 245, 36, - 5, 209, 219, 36, 5, 209, 182, 36, 5, 209, 202, 36, 5, 209, 218, 36, 5, - 209, 204, 36, 5, 209, 205, 36, 5, 209, 190, 36, 5, 209, 178, 36, 5, 197, - 164, 36, 5, 197, 136, 36, 5, 197, 142, 36, 5, 197, 163, 36, 5, 197, 156, - 36, 5, 197, 157, 36, 5, 197, 140, 36, 5, 197, 134, 36, 5, 196, 236, 36, - 5, 196, 228, 36, 5, 196, 232, 36, 5, 196, 235, 36, 5, 196, 233, 36, 5, - 196, 234, 36, 5, 196, 230, 36, 5, 196, 229, 36, 5, 233, 68, 36, 5, 232, - 48, 36, 5, 232, 238, 36, 5, 233, 67, 36, 5, 233, 11, 36, 5, 233, 18, 36, - 5, 232, 135, 36, 5, 232, 25, 36, 5, 168, 36, 5, 208, 158, 36, 5, 209, - 176, 36, 5, 210, 210, 36, 5, 210, 40, 36, 5, 210, 53, 36, 5, 209, 65, 36, - 5, 208, 115, 36, 5, 206, 11, 36, 5, 215, 54, 36, 5, 232, 19, 36, 33, 231, - 116, 24, 18, 219, 174, 77, 36, 33, 18, 219, 174, 77, 36, 33, 231, 116, - 77, 36, 205, 49, 77, 36, 193, 22, 36, 232, 42, 201, 58, 36, 242, 26, 36, - 204, 20, 36, 242, 35, 36, 208, 221, 242, 35, 36, 208, 8, 77, 36, 210, - 118, 204, 5, 36, 17, 108, 36, 17, 109, 36, 17, 139, 36, 17, 137, 36, 17, - 153, 36, 17, 173, 36, 17, 181, 36, 17, 176, 36, 17, 184, 36, 31, 199, 90, - 36, 31, 197, 28, 36, 31, 198, 244, 36, 31, 232, 97, 36, 31, 232, 230, 36, - 31, 202, 115, 36, 31, 203, 236, 36, 31, 234, 110, 36, 31, 213, 156, 36, - 31, 228, 109, 36, 31, 199, 91, 188, 36, 5, 205, 54, 215, 66, 36, 5, 215, - 62, 36, 5, 215, 63, 36, 5, 215, 64, 36, 5, 205, 54, 247, 162, 36, 5, 247, - 159, 36, 5, 247, 160, 36, 5, 247, 161, 36, 5, 205, 54, 232, 25, 36, 5, - 232, 21, 36, 5, 232, 22, 36, 5, 232, 23, 36, 5, 205, 54, 208, 115, 36, 5, - 208, 111, 36, 5, 208, 112, 36, 5, 208, 113, 36, 198, 75, 87, 192, 15, 36, - 198, 75, 87, 237, 44, 36, 198, 75, 87, 206, 189, 36, 198, 75, 87, 203, - 35, 206, 189, 36, 198, 75, 87, 236, 229, 36, 198, 75, 87, 221, 225, 36, - 198, 75, 87, 243, 28, 36, 198, 75, 87, 229, 115, 36, 198, 75, 87, 237, - 43, 36, 198, 75, 87, 220, 171, 101, 1, 65, 101, 1, 73, 101, 1, 70, 101, - 1, 74, 101, 1, 69, 101, 1, 196, 8, 101, 1, 231, 203, 101, 1, 157, 101, 1, - 231, 128, 101, 1, 231, 16, 101, 1, 230, 223, 101, 1, 230, 146, 101, 1, - 230, 105, 101, 1, 144, 101, 1, 229, 213, 101, 1, 229, 126, 101, 1, 228, - 247, 101, 1, 228, 128, 101, 1, 228, 95, 101, 1, 171, 101, 1, 219, 214, - 101, 1, 219, 122, 101, 1, 219, 19, 101, 1, 218, 203, 101, 1, 218, 171, - 101, 1, 172, 101, 1, 216, 213, 101, 1, 216, 81, 101, 1, 215, 251, 101, 1, - 215, 139, 101, 1, 180, 101, 1, 229, 15, 101, 1, 214, 223, 101, 1, 214, - 107, 101, 1, 213, 205, 101, 1, 213, 30, 101, 1, 212, 165, 101, 1, 212, - 99, 101, 1, 208, 26, 101, 1, 208, 11, 101, 1, 208, 4, 101, 1, 207, 250, - 101, 1, 207, 239, 101, 1, 207, 237, 101, 1, 189, 101, 1, 206, 3, 101, 1, - 205, 63, 101, 1, 202, 217, 101, 1, 202, 41, 101, 1, 200, 255, 101, 1, - 200, 154, 101, 1, 237, 241, 101, 1, 199, 247, 101, 1, 237, 101, 101, 1, - 199, 140, 101, 1, 236, 255, 101, 1, 198, 188, 101, 1, 236, 129, 101, 1, - 235, 45, 101, 1, 235, 13, 101, 1, 236, 141, 101, 1, 198, 110, 101, 1, - 198, 109, 101, 1, 198, 98, 101, 1, 198, 97, 101, 1, 198, 96, 101, 1, 198, - 95, 101, 1, 197, 164, 101, 1, 197, 157, 101, 1, 197, 142, 101, 1, 197, - 140, 101, 1, 197, 136, 101, 1, 197, 135, 101, 1, 193, 187, 101, 1, 193, - 123, 101, 1, 193, 84, 101, 1, 193, 48, 101, 1, 193, 0, 101, 1, 192, 243, - 101, 1, 169, 101, 1, 192, 80, 101, 1, 192, 33, 101, 1, 192, 12, 101, 1, - 191, 225, 101, 1, 191, 184, 101, 1, 215, 73, 101, 2, 1, 192, 80, 101, 2, - 1, 192, 33, 101, 2, 1, 192, 12, 101, 2, 1, 191, 225, 101, 2, 1, 191, 184, - 101, 2, 1, 215, 73, 21, 22, 228, 58, 21, 22, 73, 21, 22, 252, 118, 21, - 22, 70, 21, 22, 223, 170, 21, 22, 74, 21, 22, 211, 76, 21, 22, 192, 158, - 211, 76, 21, 22, 98, 234, 145, 21, 22, 98, 70, 21, 22, 65, 21, 22, 252, - 154, 21, 22, 193, 123, 21, 22, 193, 101, 193, 123, 21, 22, 193, 84, 21, - 22, 193, 101, 193, 84, 21, 22, 193, 68, 21, 22, 193, 101, 193, 68, 21, - 22, 193, 48, 21, 22, 193, 101, 193, 48, 21, 22, 193, 29, 21, 22, 193, - 101, 193, 29, 21, 22, 214, 195, 193, 29, 21, 22, 193, 187, 21, 22, 193, - 101, 193, 187, 21, 22, 193, 178, 21, 22, 193, 101, 193, 178, 21, 22, 214, - 195, 193, 178, 21, 22, 251, 184, 21, 22, 192, 158, 193, 221, 21, 22, 230, - 231, 201, 58, 21, 22, 52, 251, 250, 21, 22, 52, 230, 176, 21, 22, 52, - 248, 29, 134, 206, 183, 21, 22, 52, 198, 49, 134, 206, 183, 21, 22, 52, - 50, 134, 206, 183, 21, 22, 52, 206, 183, 21, 22, 52, 54, 251, 250, 21, - 22, 52, 54, 203, 35, 81, 201, 10, 21, 22, 52, 82, 236, 96, 21, 22, 52, - 203, 35, 228, 209, 105, 21, 22, 52, 209, 73, 21, 22, 52, 143, 199, 223, - 21, 22, 234, 61, 21, 22, 223, 134, 21, 22, 211, 93, 21, 22, 251, 81, 21, - 22, 210, 53, 21, 22, 210, 208, 21, 22, 209, 176, 21, 22, 209, 136, 21, - 22, 209, 65, 21, 22, 209, 30, 21, 22, 192, 158, 209, 30, 21, 22, 98, 229, - 183, 21, 22, 98, 229, 126, 21, 22, 168, 21, 22, 210, 210, 21, 22, 208, - 113, 21, 22, 193, 101, 208, 113, 21, 22, 208, 111, 21, 22, 193, 101, 208, - 111, 21, 22, 208, 110, 21, 22, 193, 101, 208, 110, 21, 22, 208, 108, 21, - 22, 193, 101, 208, 108, 21, 22, 208, 107, 21, 22, 193, 101, 208, 107, 21, - 22, 208, 115, 21, 22, 193, 101, 208, 115, 21, 22, 208, 114, 21, 22, 193, - 101, 208, 114, 21, 22, 192, 158, 208, 114, 21, 22, 210, 226, 21, 22, 193, - 101, 210, 226, 21, 22, 98, 230, 83, 21, 22, 199, 140, 21, 22, 199, 237, - 21, 22, 198, 188, 21, 22, 198, 165, 21, 22, 159, 21, 22, 198, 54, 21, 22, - 192, 158, 198, 54, 21, 22, 98, 237, 86, 21, 22, 98, 236, 255, 21, 22, - 199, 247, 21, 22, 199, 240, 21, 22, 197, 37, 21, 22, 193, 101, 197, 37, - 21, 22, 197, 15, 21, 22, 193, 101, 197, 15, 21, 22, 197, 14, 21, 22, 193, - 101, 197, 14, 21, 22, 109, 21, 22, 193, 101, 109, 21, 22, 197, 5, 21, 22, - 193, 101, 197, 5, 21, 22, 197, 39, 21, 22, 193, 101, 197, 39, 21, 22, - 197, 38, 21, 22, 193, 101, 197, 38, 21, 22, 214, 195, 197, 38, 21, 22, - 200, 39, 21, 22, 197, 123, 21, 22, 197, 107, 21, 22, 197, 105, 21, 22, - 197, 128, 21, 22, 221, 253, 21, 22, 222, 94, 21, 22, 221, 142, 21, 22, - 221, 121, 21, 22, 221, 43, 21, 22, 221, 17, 21, 22, 192, 158, 221, 17, - 21, 22, 157, 21, 22, 222, 100, 21, 22, 220, 150, 21, 22, 193, 101, 220, - 150, 21, 22, 220, 148, 21, 22, 193, 101, 220, 148, 21, 22, 220, 147, 21, - 22, 193, 101, 220, 147, 21, 22, 220, 145, 21, 22, 193, 101, 220, 145, 21, - 22, 220, 144, 21, 22, 193, 101, 220, 144, 21, 22, 220, 155, 21, 22, 193, - 101, 220, 155, 21, 22, 220, 154, 21, 22, 193, 101, 220, 154, 21, 22, 214, - 195, 220, 154, 21, 22, 222, 125, 21, 22, 220, 156, 21, 22, 201, 252, 221, - 237, 21, 22, 201, 252, 221, 122, 21, 22, 201, 252, 221, 32, 21, 22, 201, - 252, 222, 77, 21, 22, 246, 250, 21, 22, 247, 110, 21, 22, 242, 237, 21, - 22, 242, 227, 21, 22, 242, 51, 21, 22, 238, 227, 21, 22, 192, 158, 238, - 227, 21, 22, 247, 112, 21, 22, 247, 111, 21, 22, 238, 102, 21, 22, 193, - 101, 238, 102, 21, 22, 238, 100, 21, 22, 193, 101, 238, 100, 21, 22, 238, - 99, 21, 22, 193, 101, 238, 99, 21, 22, 238, 98, 21, 22, 193, 101, 238, - 98, 21, 22, 238, 97, 21, 22, 193, 101, 238, 97, 21, 22, 238, 104, 21, 22, - 193, 101, 238, 104, 21, 22, 238, 103, 21, 22, 193, 101, 238, 103, 21, 22, - 214, 195, 238, 103, 21, 22, 247, 145, 21, 22, 205, 96, 199, 46, 21, 22, - 216, 213, 21, 22, 217, 129, 21, 22, 216, 81, 21, 22, 216, 43, 21, 22, - 215, 251, 21, 22, 215, 194, 21, 22, 192, 158, 215, 194, 21, 22, 172, 21, - 22, 217, 130, 21, 22, 215, 64, 21, 22, 193, 101, 215, 64, 21, 22, 215, - 62, 21, 22, 193, 101, 215, 62, 21, 22, 215, 61, 21, 22, 193, 101, 215, - 61, 21, 22, 215, 60, 21, 22, 193, 101, 215, 60, 21, 22, 215, 59, 21, 22, - 193, 101, 215, 59, 21, 22, 215, 66, 21, 22, 193, 101, 215, 66, 21, 22, - 215, 65, 21, 22, 193, 101, 215, 65, 21, 22, 214, 195, 215, 65, 21, 22, - 218, 147, 21, 22, 193, 101, 218, 147, 21, 22, 216, 85, 21, 22, 250, 130, - 218, 147, 21, 22, 205, 96, 218, 147, 21, 22, 214, 107, 21, 22, 214, 235, - 21, 22, 213, 205, 21, 22, 213, 172, 21, 22, 213, 30, 21, 22, 213, 13, 21, - 22, 192, 158, 213, 13, 21, 22, 180, 21, 22, 214, 236, 21, 22, 212, 95, - 21, 22, 193, 101, 212, 95, 21, 22, 212, 97, 21, 22, 193, 101, 212, 97, - 21, 22, 212, 96, 21, 22, 193, 101, 212, 96, 21, 22, 214, 195, 212, 96, - 21, 22, 215, 47, 21, 22, 98, 214, 56, 21, 22, 213, 211, 21, 22, 219, 214, - 21, 22, 220, 100, 21, 22, 219, 122, 21, 22, 219, 104, 21, 22, 219, 19, - 21, 22, 218, 240, 21, 22, 192, 158, 218, 240, 21, 22, 171, 21, 22, 220, - 101, 21, 22, 218, 168, 21, 22, 193, 101, 218, 168, 21, 22, 218, 167, 21, - 22, 193, 101, 218, 167, 21, 22, 218, 166, 21, 22, 193, 101, 218, 166, 21, - 22, 218, 165, 21, 22, 193, 101, 218, 165, 21, 22, 218, 164, 21, 22, 193, - 101, 218, 164, 21, 22, 218, 170, 21, 22, 193, 101, 218, 170, 21, 22, 218, - 169, 21, 22, 193, 101, 218, 169, 21, 22, 170, 21, 22, 193, 101, 170, 21, - 22, 216, 198, 170, 21, 22, 205, 63, 21, 22, 205, 190, 21, 22, 202, 217, - 21, 22, 202, 188, 21, 22, 202, 41, 21, 22, 202, 11, 21, 22, 192, 158, - 202, 11, 21, 22, 189, 21, 22, 205, 192, 21, 22, 200, 141, 21, 22, 193, - 101, 200, 141, 21, 22, 200, 135, 21, 22, 193, 101, 200, 135, 21, 22, 200, - 134, 21, 22, 193, 101, 200, 134, 21, 22, 200, 129, 21, 22, 193, 101, 200, - 129, 21, 22, 200, 128, 21, 22, 193, 101, 200, 128, 21, 22, 200, 146, 21, - 22, 193, 101, 200, 146, 21, 22, 200, 145, 21, 22, 193, 101, 200, 145, 21, - 22, 214, 195, 200, 145, 21, 22, 206, 3, 21, 22, 250, 130, 206, 3, 21, 22, - 200, 147, 21, 22, 248, 88, 206, 3, 21, 22, 215, 187, 202, 109, 21, 22, - 214, 195, 202, 96, 21, 22, 214, 195, 206, 1, 21, 22, 214, 195, 201, 187, - 21, 22, 214, 195, 201, 2, 21, 22, 214, 195, 202, 95, 21, 22, 214, 195, - 205, 66, 21, 22, 203, 108, 21, 22, 203, 76, 21, 22, 203, 71, 21, 22, 203, - 51, 21, 22, 203, 43, 21, 22, 203, 160, 21, 22, 203, 155, 21, 22, 202, - 232, 21, 22, 193, 101, 202, 232, 21, 22, 202, 231, 21, 22, 193, 101, 202, - 231, 21, 22, 202, 230, 21, 22, 193, 101, 202, 230, 21, 22, 202, 229, 21, - 22, 193, 101, 202, 229, 21, 22, 202, 228, 21, 22, 193, 101, 202, 228, 21, - 22, 202, 235, 21, 22, 193, 101, 202, 235, 21, 22, 202, 234, 21, 22, 193, - 101, 202, 234, 21, 22, 203, 162, 21, 22, 192, 80, 21, 22, 192, 138, 21, - 22, 192, 33, 21, 22, 192, 23, 21, 22, 192, 12, 21, 22, 191, 246, 21, 22, - 192, 158, 191, 246, 21, 22, 169, 21, 22, 192, 140, 21, 22, 191, 181, 21, - 22, 193, 101, 191, 181, 21, 22, 191, 180, 21, 22, 193, 101, 191, 180, 21, - 22, 191, 179, 21, 22, 193, 101, 191, 179, 21, 22, 191, 178, 21, 22, 193, - 101, 191, 178, 21, 22, 191, 177, 21, 22, 193, 101, 191, 177, 21, 22, 191, - 183, 21, 22, 193, 101, 191, 183, 21, 22, 191, 182, 21, 22, 193, 101, 191, - 182, 21, 22, 214, 195, 191, 182, 21, 22, 192, 159, 21, 22, 248, 138, 192, - 159, 21, 22, 193, 101, 192, 159, 21, 22, 205, 96, 192, 33, 21, 22, 207, - 108, 21, 22, 207, 216, 207, 108, 21, 22, 193, 101, 219, 214, 21, 22, 207, - 172, 21, 22, 206, 252, 21, 22, 206, 190, 21, 22, 206, 157, 21, 22, 206, - 129, 21, 22, 193, 101, 219, 19, 21, 22, 166, 21, 22, 207, 173, 21, 22, - 193, 101, 171, 21, 22, 206, 20, 21, 22, 193, 101, 206, 20, 21, 22, 148, - 21, 22, 193, 101, 148, 21, 22, 216, 198, 148, 21, 22, 233, 18, 21, 22, - 233, 65, 21, 22, 232, 238, 21, 22, 232, 223, 21, 22, 232, 135, 21, 22, - 232, 123, 21, 22, 233, 68, 21, 22, 233, 67, 21, 22, 232, 24, 21, 22, 193, - 101, 232, 24, 21, 22, 233, 134, 21, 22, 199, 28, 21, 22, 215, 45, 199, - 28, 21, 22, 199, 6, 21, 22, 215, 45, 199, 6, 21, 22, 199, 0, 21, 22, 215, - 45, 199, 0, 21, 22, 198, 236, 21, 22, 198, 230, 21, 22, 199, 44, 21, 22, - 199, 43, 21, 22, 198, 198, 21, 22, 193, 101, 198, 198, 21, 22, 199, 46, - 21, 22, 197, 114, 21, 22, 197, 112, 21, 22, 197, 111, 21, 22, 197, 116, - 21, 22, 197, 117, 21, 22, 196, 254, 21, 22, 196, 253, 21, 22, 196, 252, - 21, 22, 197, 0, 21, 22, 212, 116, 229, 213, 21, 22, 212, 116, 229, 126, - 21, 22, 212, 116, 229, 98, 21, 22, 212, 116, 228, 247, 21, 22, 212, 116, - 228, 220, 21, 22, 212, 116, 144, 21, 22, 212, 116, 230, 58, 21, 22, 212, - 116, 230, 83, 21, 22, 212, 115, 230, 83, 21, 22, 229, 81, 21, 22, 208, - 85, 21, 22, 208, 51, 21, 22, 208, 45, 21, 22, 208, 39, 21, 22, 208, 34, - 21, 22, 208, 89, 21, 22, 208, 88, 21, 22, 208, 97, 21, 22, 198, 106, 21, - 22, 198, 104, 21, 22, 198, 103, 21, 22, 198, 107, 21, 22, 193, 101, 207, - 108, 21, 22, 193, 101, 206, 252, 21, 22, 193, 101, 206, 157, 21, 22, 193, - 101, 166, 21, 22, 214, 52, 21, 22, 214, 2, 21, 22, 213, 254, 21, 22, 213, - 235, 21, 22, 213, 230, 21, 22, 214, 54, 21, 22, 214, 53, 21, 22, 214, 56, - 21, 22, 213, 59, 21, 22, 205, 96, 203, 108, 21, 22, 205, 96, 203, 76, 21, - 22, 205, 96, 203, 51, 21, 22, 205, 96, 203, 160, 21, 22, 193, 27, 199, - 28, 21, 22, 193, 27, 199, 6, 21, 22, 193, 27, 198, 236, 21, 22, 193, 27, - 199, 44, 21, 22, 193, 27, 199, 46, 21, 22, 219, 129, 21, 22, 219, 128, - 21, 22, 219, 127, 21, 22, 219, 126, 21, 22, 219, 135, 21, 22, 219, 134, - 21, 22, 219, 136, 21, 22, 199, 45, 199, 28, 21, 22, 199, 45, 199, 6, 21, - 22, 199, 45, 199, 0, 21, 22, 199, 45, 198, 236, 21, 22, 199, 45, 198, - 230, 21, 22, 199, 45, 199, 44, 21, 22, 199, 45, 199, 43, 21, 22, 199, 45, - 199, 46, 21, 22, 251, 168, 250, 70, 21, 22, 248, 88, 73, 21, 22, 248, 88, - 70, 21, 22, 248, 88, 74, 21, 22, 248, 88, 65, 21, 22, 248, 88, 193, 123, - 21, 22, 248, 88, 193, 84, 21, 22, 248, 88, 193, 48, 21, 22, 248, 88, 193, - 187, 21, 22, 248, 88, 214, 107, 21, 22, 248, 88, 213, 205, 21, 22, 248, - 88, 213, 30, 21, 22, 248, 88, 180, 21, 22, 248, 88, 221, 253, 21, 22, - 248, 88, 221, 142, 21, 22, 248, 88, 221, 43, 21, 22, 248, 88, 157, 21, - 22, 205, 96, 229, 213, 21, 22, 205, 96, 229, 126, 21, 22, 205, 96, 228, - 247, 21, 22, 205, 96, 144, 21, 22, 98, 231, 22, 21, 22, 98, 231, 26, 21, - 22, 98, 231, 40, 21, 22, 98, 231, 39, 21, 22, 98, 231, 28, 21, 22, 98, - 231, 54, 21, 22, 98, 206, 63, 21, 22, 98, 206, 157, 21, 22, 98, 207, 108, - 21, 22, 98, 207, 79, 21, 22, 98, 206, 252, 21, 22, 98, 166, 21, 22, 98, - 193, 0, 21, 22, 98, 193, 48, 21, 22, 98, 193, 123, 21, 22, 98, 193, 112, - 21, 22, 98, 193, 84, 21, 22, 98, 193, 187, 21, 22, 98, 228, 87, 21, 22, - 98, 228, 88, 21, 22, 98, 228, 91, 21, 22, 98, 228, 90, 21, 22, 98, 228, - 89, 21, 22, 98, 228, 94, 21, 22, 98, 198, 208, 21, 22, 98, 198, 236, 21, - 22, 98, 199, 28, 21, 22, 98, 199, 26, 21, 22, 98, 199, 6, 21, 22, 98, - 199, 44, 21, 22, 98, 197, 95, 21, 22, 98, 197, 105, 21, 22, 98, 197, 123, - 21, 22, 98, 197, 122, 21, 22, 98, 197, 107, 21, 22, 98, 197, 128, 21, 22, - 98, 208, 158, 21, 22, 98, 209, 65, 21, 22, 98, 210, 53, 21, 22, 98, 210, - 40, 21, 22, 98, 209, 176, 21, 22, 98, 168, 21, 22, 98, 210, 226, 21, 22, - 98, 230, 146, 21, 22, 98, 230, 223, 21, 22, 98, 231, 128, 21, 22, 98, - 231, 120, 21, 22, 98, 231, 16, 21, 22, 98, 231, 203, 21, 22, 98, 221, - 151, 21, 22, 98, 221, 159, 21, 22, 98, 221, 173, 21, 22, 98, 221, 172, - 21, 22, 98, 221, 166, 21, 22, 98, 221, 190, 21, 22, 98, 221, 72, 21, 22, - 98, 221, 73, 21, 22, 98, 221, 76, 21, 22, 98, 221, 75, 21, 22, 98, 221, - 74, 21, 22, 98, 221, 77, 21, 22, 98, 221, 78, 21, 22, 98, 212, 165, 21, - 22, 98, 213, 30, 21, 22, 98, 214, 107, 21, 22, 98, 214, 96, 21, 22, 98, - 213, 205, 21, 22, 98, 180, 21, 22, 98, 215, 139, 21, 22, 98, 215, 251, - 21, 22, 98, 216, 213, 21, 22, 98, 216, 192, 21, 22, 98, 216, 81, 21, 22, - 98, 172, 21, 22, 98, 191, 225, 21, 22, 98, 192, 12, 21, 22, 98, 192, 80, - 21, 22, 98, 192, 77, 21, 22, 98, 192, 33, 21, 22, 98, 169, 21, 22, 98, - 222, 155, 21, 22, 205, 96, 222, 155, 21, 22, 98, 222, 174, 21, 22, 98, - 222, 238, 21, 22, 98, 222, 236, 21, 22, 98, 222, 217, 21, 22, 205, 96, - 222, 217, 21, 22, 98, 223, 4, 21, 22, 98, 222, 188, 21, 22, 98, 222, 192, - 21, 22, 98, 222, 202, 21, 22, 98, 222, 201, 21, 22, 98, 222, 200, 21, 22, - 98, 222, 203, 21, 22, 98, 218, 203, 21, 22, 98, 219, 19, 21, 22, 98, 219, - 214, 21, 22, 98, 219, 204, 21, 22, 98, 219, 122, 21, 22, 98, 171, 21, 22, - 98, 236, 134, 21, 22, 98, 236, 135, 21, 22, 98, 236, 140, 21, 22, 98, - 236, 139, 21, 22, 98, 236, 136, 21, 22, 98, 236, 141, 21, 22, 98, 219, - 125, 21, 22, 98, 219, 127, 21, 22, 98, 219, 131, 21, 22, 98, 219, 130, - 21, 22, 98, 219, 129, 21, 22, 98, 219, 135, 21, 22, 98, 198, 101, 21, 22, - 98, 198, 103, 21, 22, 98, 198, 106, 21, 22, 98, 198, 105, 21, 22, 98, - 198, 104, 21, 22, 98, 198, 107, 21, 22, 98, 198, 96, 21, 22, 98, 198, 97, - 21, 22, 98, 198, 109, 21, 22, 98, 198, 108, 21, 22, 98, 198, 98, 21, 22, - 98, 198, 110, 21, 22, 98, 190, 251, 21, 22, 98, 191, 7, 21, 22, 98, 191, - 87, 21, 22, 98, 191, 84, 21, 22, 98, 191, 30, 21, 22, 98, 191, 123, 21, - 22, 98, 191, 166, 21, 22, 98, 89, 191, 166, 21, 22, 98, 234, 234, 21, 22, - 98, 234, 235, 21, 22, 98, 234, 244, 21, 22, 98, 234, 243, 21, 22, 98, - 234, 238, 21, 22, 98, 234, 247, 21, 22, 98, 200, 255, 21, 22, 98, 202, - 41, 21, 22, 98, 205, 63, 21, 22, 98, 205, 45, 21, 22, 98, 202, 217, 21, - 22, 98, 189, 21, 22, 98, 203, 0, 21, 22, 98, 203, 51, 21, 22, 98, 203, - 108, 21, 22, 98, 203, 106, 21, 22, 98, 203, 76, 21, 22, 98, 203, 160, 21, - 22, 98, 203, 162, 21, 22, 98, 197, 136, 21, 22, 98, 197, 140, 21, 22, 98, - 197, 157, 21, 22, 98, 197, 156, 21, 22, 98, 197, 142, 21, 22, 98, 197, - 164, 21, 22, 98, 243, 0, 21, 22, 98, 243, 20, 21, 22, 98, 243, 79, 21, - 22, 98, 243, 75, 21, 22, 98, 243, 47, 21, 22, 98, 246, 209, 21, 22, 98, - 197, 98, 21, 22, 98, 197, 99, 21, 22, 98, 197, 102, 21, 22, 98, 197, 101, - 21, 22, 98, 197, 100, 21, 22, 98, 197, 103, 21, 22, 243, 48, 57, 21, 22, - 232, 42, 201, 58, 21, 22, 208, 81, 21, 22, 214, 50, 21, 22, 213, 56, 21, - 22, 213, 55, 21, 22, 213, 54, 21, 22, 213, 53, 21, 22, 213, 58, 21, 22, - 213, 57, 21, 22, 193, 27, 198, 196, 21, 22, 193, 27, 198, 195, 21, 22, - 193, 27, 198, 194, 21, 22, 193, 27, 198, 193, 21, 22, 193, 27, 198, 192, - 21, 22, 193, 27, 198, 199, 21, 22, 193, 27, 198, 198, 21, 22, 193, 27, - 52, 199, 46, 21, 22, 248, 88, 193, 221, 211, 128, 201, 243, 77, 211, 128, - 1, 248, 189, 211, 128, 1, 218, 189, 211, 128, 1, 233, 15, 211, 128, 1, - 205, 174, 211, 128, 1, 213, 153, 211, 128, 1, 196, 161, 211, 128, 1, 237, - 214, 211, 128, 1, 198, 134, 211, 128, 1, 242, 38, 211, 128, 1, 246, 237, - 211, 128, 1, 215, 122, 211, 128, 1, 230, 200, 211, 128, 1, 214, 40, 211, - 128, 1, 201, 49, 211, 128, 1, 206, 50, 211, 128, 1, 251, 180, 211, 128, - 1, 211, 80, 211, 128, 1, 196, 58, 211, 128, 1, 234, 171, 211, 128, 1, - 223, 59, 211, 128, 1, 234, 172, 211, 128, 1, 211, 45, 211, 128, 1, 196, - 132, 211, 128, 1, 223, 176, 211, 128, 1, 234, 169, 211, 128, 1, 210, 29, - 211, 128, 233, 14, 77, 211, 128, 207, 13, 233, 14, 77, 206, 39, 1, 233, - 4, 232, 251, 233, 19, 233, 134, 206, 39, 1, 196, 8, 206, 39, 1, 196, 43, - 196, 59, 69, 206, 39, 1, 191, 228, 206, 39, 1, 192, 159, 206, 39, 1, 193, - 221, 206, 39, 1, 198, 201, 198, 200, 198, 228, 206, 39, 1, 233, 206, 206, - 39, 1, 251, 39, 65, 206, 39, 1, 211, 27, 74, 206, 39, 1, 252, 12, 65, - 206, 39, 1, 251, 213, 206, 39, 1, 218, 247, 74, 206, 39, 1, 203, 28, 74, - 206, 39, 1, 74, 206, 39, 1, 211, 139, 206, 39, 1, 211, 93, 206, 39, 1, - 207, 149, 207, 164, 207, 64, 148, 206, 39, 1, 222, 13, 206, 39, 1, 246, - 233, 206, 39, 1, 222, 14, 222, 125, 206, 39, 1, 232, 14, 206, 39, 1, 234, - 46, 206, 39, 1, 231, 123, 230, 89, 232, 14, 206, 39, 1, 231, 163, 206, - 39, 1, 192, 248, 192, 239, 193, 221, 206, 39, 1, 230, 49, 230, 83, 206, - 39, 1, 230, 53, 230, 83, 206, 39, 1, 218, 249, 230, 83, 206, 39, 1, 203, - 31, 230, 83, 206, 39, 1, 214, 189, 212, 78, 214, 190, 215, 47, 206, 39, - 1, 203, 29, 215, 47, 206, 39, 1, 235, 91, 206, 39, 1, 223, 37, 223, 41, - 223, 27, 70, 206, 39, 1, 73, 206, 39, 1, 222, 228, 223, 7, 206, 39, 1, - 231, 104, 206, 39, 1, 218, 250, 251, 229, 206, 39, 1, 203, 33, 65, 206, - 39, 1, 223, 19, 234, 19, 206, 39, 1, 209, 238, 210, 9, 210, 226, 206, 39, - 1, 251, 134, 234, 17, 206, 39, 1, 201, 249, 206, 3, 206, 39, 1, 202, 193, - 218, 246, 206, 3, 206, 39, 1, 203, 27, 206, 3, 206, 39, 1, 247, 145, 206, - 39, 1, 191, 166, 206, 39, 1, 198, 115, 198, 127, 196, 238, 200, 39, 206, - 39, 1, 203, 26, 200, 39, 206, 39, 1, 238, 80, 206, 39, 1, 248, 167, 248, - 170, 248, 94, 250, 70, 206, 39, 1, 203, 32, 250, 70, 206, 39, 1, 235, 90, - 206, 39, 1, 211, 59, 206, 39, 1, 234, 124, 234, 131, 73, 206, 39, 1, 217, - 59, 217, 71, 218, 147, 206, 39, 1, 218, 248, 218, 147, 206, 39, 1, 203, - 30, 218, 147, 206, 39, 1, 219, 229, 220, 77, 219, 2, 170, 206, 39, 1, - 235, 92, 206, 39, 1, 223, 107, 206, 39, 1, 223, 108, 206, 39, 1, 237, - 228, 237, 234, 238, 80, 206, 39, 1, 211, 18, 233, 205, 74, 206, 39, 1, - 234, 167, 206, 39, 1, 223, 57, 206, 39, 1, 238, 101, 206, 39, 1, 247, 95, - 206, 39, 1, 246, 249, 206, 39, 1, 201, 103, 206, 39, 1, 218, 245, 206, - 39, 1, 203, 25, 206, 39, 1, 227, 251, 206, 39, 1, 208, 97, 206, 39, 1, - 192, 235, 206, 39, 202, 165, 208, 144, 206, 39, 215, 114, 208, 144, 206, - 39, 238, 171, 208, 144, 206, 39, 250, 202, 113, 206, 39, 197, 41, 113, - 206, 39, 248, 187, 113, 206, 39, 1, 222, 125, 206, 39, 1, 203, 162, 206, - 39, 1, 211, 76, 206, 39, 1, 232, 72, 247, 33, 211, 26, 206, 39, 1, 232, - 72, 247, 33, 223, 40, 206, 39, 1, 232, 72, 247, 33, 234, 130, 206, 39, 1, - 232, 72, 247, 33, 252, 11, 206, 39, 1, 232, 72, 247, 33, 251, 213, 199, - 217, 1, 65, 199, 217, 1, 70, 199, 217, 1, 69, 199, 217, 1, 157, 199, 217, - 1, 231, 203, 199, 217, 1, 214, 54, 199, 217, 1, 199, 247, 199, 217, 1, - 237, 241, 199, 217, 1, 180, 199, 217, 1, 168, 199, 217, 1, 249, 103, 199, - 217, 1, 172, 199, 217, 1, 169, 199, 217, 1, 166, 199, 217, 1, 171, 199, - 217, 1, 193, 187, 199, 217, 1, 189, 199, 217, 1, 144, 199, 217, 18, 3, - 70, 199, 217, 18, 3, 69, 199, 217, 3, 195, 37, 199, 217, 3, 210, 159, - 199, 217, 1, 250, 220, 166, 229, 246, 1, 65, 229, 246, 1, 70, 229, 246, - 1, 69, 229, 246, 1, 157, 229, 246, 1, 231, 203, 229, 246, 1, 214, 54, - 229, 246, 1, 199, 247, 229, 246, 1, 237, 241, 229, 246, 1, 180, 229, 246, - 1, 168, 229, 246, 1, 249, 103, 229, 246, 1, 172, 229, 246, 1, 169, 229, - 246, 1, 166, 229, 246, 1, 171, 229, 246, 1, 193, 187, 229, 246, 1, 189, - 229, 246, 1, 144, 229, 246, 18, 3, 70, 229, 246, 18, 3, 69, 229, 246, 3, - 210, 159, 209, 195, 202, 165, 208, 144, 209, 195, 54, 208, 144, 247, 208, - 1, 65, 247, 208, 1, 70, 247, 208, 1, 69, 247, 208, 1, 157, 247, 208, 1, - 231, 203, 247, 208, 1, 214, 54, 247, 208, 1, 199, 247, 247, 208, 1, 237, - 241, 247, 208, 1, 180, 247, 208, 1, 168, 247, 208, 1, 249, 103, 247, 208, - 1, 172, 247, 208, 1, 169, 247, 208, 1, 166, 247, 208, 1, 171, 247, 208, - 1, 193, 187, 247, 208, 1, 189, 247, 208, 1, 144, 247, 208, 18, 3, 70, - 247, 208, 18, 3, 69, 199, 216, 1, 65, 199, 216, 1, 70, 199, 216, 1, 69, - 199, 216, 1, 157, 199, 216, 1, 231, 203, 199, 216, 1, 214, 54, 199, 216, - 1, 199, 247, 199, 216, 1, 237, 241, 199, 216, 1, 180, 199, 216, 1, 168, - 199, 216, 1, 249, 103, 199, 216, 1, 172, 199, 216, 1, 169, 199, 216, 1, - 171, 199, 216, 1, 193, 187, 199, 216, 1, 189, 199, 216, 18, 3, 70, 199, - 216, 18, 3, 69, 94, 1, 157, 94, 1, 221, 190, 94, 1, 221, 43, 94, 1, 221, - 159, 94, 1, 213, 235, 94, 1, 247, 112, 94, 1, 246, 209, 94, 1, 242, 51, - 94, 1, 243, 20, 94, 1, 212, 52, 94, 1, 237, 241, 94, 1, 197, 116, 94, 1, - 236, 129, 94, 1, 197, 111, 94, 1, 213, 36, 94, 1, 199, 247, 94, 1, 199, - 44, 94, 1, 159, 94, 1, 198, 236, 94, 1, 213, 30, 94, 1, 249, 103, 94, 1, - 209, 219, 94, 1, 209, 65, 94, 1, 209, 190, 94, 1, 215, 251, 94, 1, 192, - 12, 94, 1, 206, 157, 94, 1, 219, 19, 94, 1, 195, 21, 94, 1, 203, 160, 94, - 1, 201, 129, 94, 1, 189, 94, 1, 144, 94, 1, 171, 94, 1, 208, 89, 94, 223, - 121, 18, 208, 75, 94, 223, 121, 18, 208, 88, 94, 223, 121, 18, 208, 51, - 94, 223, 121, 18, 208, 45, 94, 223, 121, 18, 208, 27, 94, 223, 121, 18, - 207, 251, 94, 223, 121, 18, 207, 239, 94, 223, 121, 18, 207, 238, 94, - 223, 121, 18, 206, 12, 94, 223, 121, 18, 206, 5, 94, 223, 121, 18, 218, - 162, 94, 223, 121, 18, 218, 150, 94, 223, 121, 18, 208, 69, 94, 223, 121, - 18, 208, 81, 94, 223, 121, 18, 208, 35, 196, 251, 108, 94, 223, 121, 18, - 208, 35, 196, 251, 109, 94, 223, 121, 18, 208, 71, 94, 18, 223, 105, 250, - 243, 94, 18, 223, 105, 252, 154, 94, 18, 3, 252, 154, 94, 18, 3, 70, 94, - 18, 3, 223, 170, 94, 18, 3, 192, 159, 94, 18, 3, 191, 176, 94, 18, 3, 69, - 94, 18, 3, 196, 26, 94, 18, 3, 196, 164, 94, 18, 3, 211, 139, 94, 18, 3, - 169, 94, 18, 3, 223, 197, 94, 18, 3, 73, 94, 18, 3, 251, 229, 94, 18, 3, - 251, 184, 94, 18, 3, 211, 76, 94, 18, 3, 250, 113, 94, 3, 213, 170, 94, - 3, 207, 101, 94, 3, 191, 187, 94, 3, 215, 77, 94, 3, 197, 225, 94, 3, - 249, 40, 94, 3, 206, 146, 94, 3, 198, 85, 94, 3, 222, 68, 94, 3, 251, - 186, 94, 3, 205, 138, 205, 130, 94, 3, 195, 34, 94, 3, 242, 42, 94, 3, - 249, 10, 94, 3, 221, 180, 94, 3, 249, 35, 94, 3, 247, 83, 209, 137, 220, - 162, 94, 3, 219, 181, 198, 54, 94, 3, 248, 155, 94, 3, 209, 192, 215, - 132, 94, 3, 221, 15, 94, 238, 123, 16, 206, 236, 94, 3, 250, 94, 94, 3, - 250, 116, 94, 17, 191, 77, 94, 17, 108, 94, 17, 109, 94, 17, 139, 94, 17, - 137, 94, 17, 153, 94, 17, 173, 94, 17, 181, 94, 17, 176, 94, 17, 184, 94, - 16, 219, 181, 250, 118, 202, 14, 94, 16, 219, 181, 250, 118, 215, 98, 94, - 16, 219, 181, 250, 118, 209, 136, 94, 16, 219, 181, 250, 118, 248, 190, - 94, 16, 219, 181, 250, 118, 247, 188, 94, 16, 219, 181, 250, 118, 208, - 238, 94, 16, 219, 181, 250, 118, 208, 232, 94, 16, 219, 181, 250, 118, - 208, 230, 94, 16, 219, 181, 250, 118, 208, 236, 94, 16, 219, 181, 250, - 118, 208, 234, 102, 248, 110, 102, 234, 78, 102, 242, 26, 102, 232, 42, - 201, 58, 102, 242, 35, 102, 232, 90, 236, 94, 102, 198, 83, 202, 27, 228, - 58, 102, 202, 209, 5, 248, 25, 217, 32, 102, 217, 67, 242, 26, 102, 217, - 67, 232, 42, 201, 58, 102, 213, 151, 102, 232, 71, 66, 205, 30, 108, 102, - 232, 71, 66, 205, 30, 109, 102, 232, 71, 66, 205, 30, 139, 102, 18, 204, - 5, 102, 232, 71, 66, 205, 30, 137, 102, 17, 191, 77, 102, 17, 108, 102, - 17, 109, 102, 17, 139, 102, 17, 137, 102, 17, 153, 102, 17, 173, 102, 17, - 181, 102, 17, 176, 102, 17, 184, 102, 1, 65, 102, 1, 73, 102, 1, 70, 102, - 1, 74, 102, 1, 69, 102, 1, 211, 139, 102, 1, 196, 148, 102, 1, 234, 145, - 102, 1, 180, 102, 1, 251, 71, 102, 1, 249, 103, 102, 1, 168, 102, 1, 208, - 89, 102, 1, 231, 203, 102, 1, 172, 102, 1, 171, 102, 1, 189, 102, 1, 203, - 160, 102, 1, 199, 247, 102, 1, 237, 241, 102, 1, 246, 209, 102, 1, 223, - 4, 102, 1, 169, 102, 1, 166, 102, 1, 193, 187, 102, 1, 233, 68, 102, 1, - 157, 102, 1, 221, 190, 102, 1, 197, 164, 102, 1, 191, 123, 102, 1, 230, - 58, 102, 1, 190, 255, 102, 1, 219, 135, 102, 1, 191, 57, 102, 1, 243, 47, - 102, 1, 198, 83, 177, 18, 57, 102, 1, 198, 83, 73, 102, 1, 198, 83, 70, - 102, 1, 198, 83, 74, 102, 1, 198, 83, 69, 102, 1, 198, 83, 211, 139, 102, - 1, 198, 83, 196, 148, 102, 1, 198, 83, 251, 71, 102, 1, 198, 83, 249, - 103, 102, 1, 198, 83, 168, 102, 1, 198, 83, 208, 89, 102, 1, 198, 83, - 231, 203, 102, 1, 198, 83, 172, 102, 1, 198, 83, 199, 247, 102, 1, 198, - 83, 237, 241, 102, 1, 198, 83, 246, 209, 102, 1, 198, 83, 223, 4, 102, 1, - 198, 83, 197, 164, 102, 1, 198, 83, 169, 102, 1, 198, 83, 193, 187, 102, - 1, 198, 83, 157, 102, 1, 198, 83, 231, 200, 102, 1, 198, 83, 230, 58, - 102, 1, 198, 83, 222, 216, 102, 1, 198, 83, 213, 195, 102, 1, 198, 83, - 234, 247, 102, 1, 202, 209, 73, 102, 1, 202, 209, 70, 102, 1, 202, 209, - 223, 16, 102, 1, 202, 209, 196, 148, 102, 1, 202, 209, 69, 102, 1, 202, - 209, 251, 71, 102, 1, 202, 209, 157, 102, 1, 202, 209, 231, 203, 102, 1, - 202, 209, 144, 102, 1, 202, 209, 168, 102, 1, 202, 209, 203, 160, 102, 1, - 202, 209, 199, 247, 102, 1, 202, 209, 237, 241, 102, 1, 202, 209, 223, 4, - 102, 1, 202, 209, 233, 68, 102, 1, 202, 209, 231, 200, 102, 1, 202, 209, - 230, 58, 102, 1, 202, 209, 197, 164, 102, 1, 202, 209, 191, 123, 102, 1, - 202, 209, 207, 173, 102, 1, 202, 209, 246, 209, 102, 1, 202, 209, 191, - 71, 102, 1, 217, 67, 70, 102, 1, 217, 67, 157, 102, 1, 217, 67, 166, 102, - 1, 217, 67, 233, 68, 102, 1, 217, 67, 191, 71, 102, 1, 246, 210, 4, 103, - 236, 94, 102, 1, 251, 133, 231, 183, 251, 21, 108, 102, 1, 251, 133, 231, - 183, 195, 33, 108, 102, 1, 251, 133, 231, 183, 237, 202, 102, 1, 251, - 133, 231, 183, 196, 159, 102, 1, 251, 133, 231, 183, 223, 65, 196, 159, - 102, 1, 251, 133, 231, 183, 249, 54, 102, 1, 251, 133, 231, 183, 115, - 249, 54, 102, 1, 251, 133, 231, 183, 65, 102, 1, 251, 133, 231, 183, 70, - 102, 1, 251, 133, 231, 183, 157, 102, 1, 251, 133, 231, 183, 214, 54, - 102, 1, 251, 133, 231, 183, 247, 112, 102, 1, 251, 133, 231, 183, 197, - 128, 102, 1, 251, 133, 231, 183, 197, 116, 102, 1, 251, 133, 231, 183, - 237, 146, 102, 1, 251, 133, 231, 183, 213, 66, 102, 1, 251, 133, 231, - 183, 199, 247, 102, 1, 251, 133, 231, 183, 237, 241, 102, 1, 251, 133, - 231, 183, 168, 102, 1, 251, 133, 231, 183, 209, 219, 102, 1, 251, 133, - 231, 183, 201, 170, 102, 1, 251, 133, 231, 183, 191, 71, 102, 1, 251, - 133, 231, 183, 191, 123, 102, 1, 251, 133, 231, 183, 251, 193, 102, 1, - 198, 83, 251, 133, 231, 183, 199, 247, 102, 1, 198, 83, 251, 133, 231, - 183, 191, 71, 102, 1, 217, 67, 251, 133, 231, 183, 231, 54, 102, 1, 217, - 67, 251, 133, 231, 183, 214, 54, 102, 1, 217, 67, 251, 133, 231, 183, - 247, 112, 102, 1, 217, 67, 251, 133, 231, 183, 222, 225, 102, 1, 217, 67, - 251, 133, 231, 183, 197, 128, 102, 1, 217, 67, 251, 133, 231, 183, 237, - 130, 102, 1, 217, 67, 251, 133, 231, 183, 199, 247, 102, 1, 217, 67, 251, - 133, 231, 183, 237, 23, 102, 1, 217, 67, 251, 133, 231, 183, 201, 170, - 102, 1, 217, 67, 251, 133, 231, 183, 238, 95, 102, 1, 217, 67, 251, 133, - 231, 183, 191, 71, 102, 1, 217, 67, 251, 133, 231, 183, 191, 123, 102, 1, - 251, 133, 231, 183, 134, 69, 102, 1, 251, 133, 231, 183, 134, 169, 102, - 1, 217, 67, 251, 133, 231, 183, 248, 153, 102, 1, 251, 133, 231, 183, - 237, 229, 102, 1, 217, 67, 251, 133, 231, 183, 219, 135, 21, 22, 210, - 232, 21, 22, 250, 81, 21, 22, 252, 108, 21, 22, 193, 126, 21, 22, 208, - 244, 21, 22, 210, 62, 21, 22, 208, 106, 21, 22, 199, 149, 21, 22, 222, 4, - 21, 22, 220, 152, 21, 22, 217, 2, 21, 22, 212, 237, 21, 22, 214, 184, 21, - 22, 219, 224, 21, 22, 201, 247, 21, 22, 205, 98, 21, 22, 203, 13, 21, 22, - 203, 112, 21, 22, 202, 227, 21, 22, 191, 234, 21, 22, 192, 86, 21, 22, - 207, 117, 21, 22, 212, 94, 21, 22, 211, 116, 212, 94, 21, 22, 212, 93, - 21, 22, 211, 116, 212, 93, 21, 22, 212, 92, 21, 22, 211, 116, 212, 92, - 21, 22, 212, 91, 21, 22, 211, 116, 212, 91, 21, 22, 206, 17, 21, 22, 206, - 16, 21, 22, 206, 15, 21, 22, 206, 14, 21, 22, 206, 13, 21, 22, 206, 21, - 21, 22, 211, 116, 210, 226, 21, 22, 211, 116, 200, 39, 21, 22, 211, 116, - 222, 125, 21, 22, 211, 116, 247, 145, 21, 22, 211, 116, 218, 147, 21, 22, - 211, 116, 215, 47, 21, 22, 211, 116, 206, 3, 21, 22, 211, 116, 203, 162, - 21, 22, 234, 158, 193, 221, 21, 22, 193, 100, 193, 221, 21, 22, 52, 2, - 206, 183, 21, 22, 52, 207, 142, 236, 96, 21, 22, 207, 216, 206, 18, 21, - 22, 193, 101, 218, 240, 21, 22, 193, 101, 220, 101, 21, 22, 198, 197, 21, - 22, 198, 199, 21, 22, 197, 108, 21, 22, 197, 110, 21, 22, 197, 115, 21, - 22, 198, 100, 21, 22, 198, 102, 21, 22, 205, 96, 202, 232, 21, 22, 205, - 96, 203, 43, 21, 22, 205, 96, 228, 220, 21, 22, 98, 230, 97, 21, 22, 98, - 237, 58, 231, 120, 21, 22, 98, 231, 200, 21, 22, 98, 230, 102, 21, 22, - 205, 96, 222, 135, 21, 22, 98, 222, 133, 21, 22, 248, 211, 237, 58, 170, - 21, 22, 248, 211, 237, 58, 148, 21, 22, 98, 237, 53, 206, 3, 219, 98, - 194, 254, 219, 151, 219, 98, 1, 157, 219, 98, 1, 221, 190, 219, 98, 1, - 231, 203, 219, 98, 1, 231, 54, 219, 98, 1, 214, 54, 219, 98, 1, 247, 112, - 219, 98, 1, 246, 209, 219, 98, 1, 223, 4, 219, 98, 1, 222, 225, 219, 98, - 1, 192, 108, 219, 98, 1, 199, 247, 219, 98, 1, 199, 44, 219, 98, 1, 237, - 241, 219, 98, 1, 237, 23, 219, 98, 1, 180, 219, 98, 1, 168, 219, 98, 1, - 209, 219, 219, 98, 1, 249, 103, 219, 98, 1, 248, 153, 219, 98, 1, 172, - 219, 98, 1, 169, 219, 98, 1, 166, 219, 98, 1, 171, 219, 98, 1, 193, 187, - 219, 98, 1, 203, 160, 219, 98, 1, 201, 170, 219, 98, 1, 189, 219, 98, 1, - 144, 219, 98, 1, 230, 93, 219, 98, 1, 198, 22, 219, 98, 18, 3, 65, 219, - 98, 18, 3, 70, 219, 98, 18, 3, 69, 219, 98, 18, 3, 234, 145, 219, 98, 18, - 3, 251, 184, 219, 98, 18, 3, 211, 76, 219, 98, 18, 3, 250, 113, 219, 98, - 18, 3, 73, 219, 98, 18, 3, 74, 219, 98, 200, 234, 1, 169, 219, 98, 200, - 234, 1, 166, 219, 98, 200, 234, 1, 193, 187, 219, 98, 2, 1, 157, 219, 98, - 2, 1, 214, 54, 219, 98, 2, 1, 251, 20, 219, 98, 2, 1, 199, 247, 219, 98, - 2, 1, 180, 219, 98, 2, 1, 168, 219, 98, 2, 1, 172, 219, 98, 2, 1, 166, - 219, 98, 2, 1, 171, 219, 98, 3, 215, 119, 219, 98, 3, 221, 232, 219, 98, - 3, 205, 193, 219, 98, 3, 218, 240, 219, 98, 233, 175, 77, 219, 98, 208, - 8, 77, 219, 98, 17, 191, 77, 219, 98, 17, 108, 219, 98, 17, 109, 219, 98, - 17, 139, 219, 98, 17, 137, 219, 98, 17, 153, 219, 98, 17, 173, 219, 98, - 17, 181, 219, 98, 17, 176, 219, 98, 17, 184, 53, 219, 215, 1, 157, 53, - 219, 215, 1, 192, 220, 53, 219, 215, 1, 214, 54, 53, 219, 215, 1, 197, - 164, 53, 219, 215, 1, 189, 53, 219, 215, 1, 169, 53, 219, 215, 1, 199, - 247, 53, 219, 215, 1, 199, 44, 53, 219, 215, 1, 171, 53, 219, 215, 1, - 168, 53, 219, 215, 1, 209, 219, 53, 219, 215, 1, 172, 53, 219, 215, 1, - 233, 68, 53, 219, 215, 1, 195, 185, 53, 219, 215, 1, 144, 53, 219, 215, - 1, 208, 89, 53, 219, 215, 1, 221, 190, 53, 219, 215, 1, 197, 153, 53, - 219, 215, 1, 180, 53, 219, 215, 1, 65, 53, 219, 215, 1, 70, 53, 219, 215, - 1, 234, 145, 53, 219, 215, 1, 234, 130, 53, 219, 215, 1, 69, 53, 219, - 215, 1, 211, 76, 53, 219, 215, 1, 74, 53, 219, 215, 1, 196, 148, 53, 219, - 215, 1, 73, 53, 219, 215, 1, 250, 111, 53, 219, 215, 1, 251, 184, 53, - 219, 215, 1, 198, 72, 53, 219, 215, 1, 198, 71, 53, 219, 215, 1, 198, 70, - 53, 219, 215, 1, 198, 69, 53, 219, 215, 1, 198, 68, 214, 66, 53, 218, - 197, 1, 136, 208, 89, 214, 66, 53, 218, 197, 1, 131, 208, 89, 214, 66, - 53, 218, 197, 1, 136, 157, 214, 66, 53, 218, 197, 1, 136, 192, 220, 214, - 66, 53, 218, 197, 1, 136, 214, 54, 214, 66, 53, 218, 197, 1, 131, 157, - 214, 66, 53, 218, 197, 1, 131, 192, 220, 214, 66, 53, 218, 197, 1, 131, - 214, 54, 214, 66, 53, 218, 197, 1, 136, 197, 164, 214, 66, 53, 218, 197, - 1, 136, 189, 214, 66, 53, 218, 197, 1, 136, 169, 214, 66, 53, 218, 197, - 1, 131, 197, 164, 214, 66, 53, 218, 197, 1, 131, 189, 214, 66, 53, 218, - 197, 1, 131, 169, 214, 66, 53, 218, 197, 1, 136, 199, 247, 214, 66, 53, - 218, 197, 1, 136, 199, 44, 214, 66, 53, 218, 197, 1, 136, 180, 214, 66, - 53, 218, 197, 1, 131, 199, 247, 214, 66, 53, 218, 197, 1, 131, 199, 44, - 214, 66, 53, 218, 197, 1, 131, 180, 214, 66, 53, 218, 197, 1, 136, 168, - 214, 66, 53, 218, 197, 1, 136, 209, 219, 214, 66, 53, 218, 197, 1, 136, - 172, 214, 66, 53, 218, 197, 1, 131, 168, 214, 66, 53, 218, 197, 1, 131, - 209, 219, 214, 66, 53, 218, 197, 1, 131, 172, 214, 66, 53, 218, 197, 1, - 136, 233, 68, 214, 66, 53, 218, 197, 1, 136, 195, 185, 214, 66, 53, 218, - 197, 1, 136, 171, 214, 66, 53, 218, 197, 1, 131, 233, 68, 214, 66, 53, - 218, 197, 1, 131, 195, 185, 214, 66, 53, 218, 197, 1, 131, 171, 214, 66, - 53, 218, 197, 1, 136, 144, 214, 66, 53, 218, 197, 1, 136, 237, 241, 214, - 66, 53, 218, 197, 1, 136, 249, 103, 214, 66, 53, 218, 197, 1, 131, 144, - 214, 66, 53, 218, 197, 1, 131, 237, 241, 214, 66, 53, 218, 197, 1, 131, - 249, 103, 214, 66, 53, 218, 197, 1, 136, 220, 157, 214, 66, 53, 218, 197, - 1, 136, 192, 185, 214, 66, 53, 218, 197, 1, 131, 220, 157, 214, 66, 53, - 218, 197, 1, 131, 192, 185, 214, 66, 53, 218, 197, 1, 136, 200, 246, 214, - 66, 53, 218, 197, 1, 131, 200, 246, 214, 66, 53, 218, 197, 18, 3, 18, - 203, 23, 214, 66, 53, 218, 197, 18, 3, 252, 154, 214, 66, 53, 218, 197, - 18, 3, 223, 170, 214, 66, 53, 218, 197, 18, 3, 69, 214, 66, 53, 218, 197, - 18, 3, 196, 26, 214, 66, 53, 218, 197, 18, 3, 73, 214, 66, 53, 218, 197, - 18, 3, 251, 229, 214, 66, 53, 218, 197, 18, 3, 74, 214, 66, 53, 218, 197, - 18, 3, 211, 169, 214, 66, 53, 218, 197, 18, 3, 196, 148, 214, 66, 53, - 218, 197, 18, 3, 250, 81, 214, 66, 53, 218, 197, 18, 3, 252, 108, 214, - 66, 53, 218, 197, 18, 3, 196, 17, 214, 66, 53, 218, 197, 18, 3, 210, 232, - 214, 66, 53, 218, 197, 18, 3, 211, 166, 214, 66, 53, 218, 197, 18, 3, - 196, 140, 214, 66, 53, 218, 197, 18, 3, 223, 16, 214, 66, 53, 218, 197, - 1, 52, 196, 8, 214, 66, 53, 218, 197, 1, 52, 214, 56, 214, 66, 53, 218, - 197, 1, 52, 215, 47, 214, 66, 53, 218, 197, 1, 52, 218, 147, 214, 66, 53, - 218, 197, 1, 52, 222, 125, 214, 66, 53, 218, 197, 1, 52, 238, 80, 214, - 66, 53, 218, 197, 1, 52, 250, 70, 214, 66, 53, 218, 197, 163, 217, 36, - 214, 66, 53, 218, 197, 163, 217, 35, 214, 66, 53, 218, 197, 17, 191, 77, - 214, 66, 53, 218, 197, 17, 108, 214, 66, 53, 218, 197, 17, 109, 214, 66, - 53, 218, 197, 17, 139, 214, 66, 53, 218, 197, 17, 137, 214, 66, 53, 218, - 197, 17, 153, 214, 66, 53, 218, 197, 17, 173, 214, 66, 53, 218, 197, 17, - 181, 214, 66, 53, 218, 197, 17, 176, 214, 66, 53, 218, 197, 17, 184, 214, - 66, 53, 218, 197, 128, 17, 108, 214, 66, 53, 218, 197, 3, 220, 83, 214, - 66, 53, 218, 197, 3, 220, 82, 94, 16, 210, 74, 94, 16, 215, 99, 221, 34, - 94, 16, 209, 137, 221, 34, 94, 16, 248, 191, 221, 34, 94, 16, 247, 189, - 221, 34, 94, 16, 208, 239, 221, 34, 94, 16, 208, 233, 221, 34, 94, 16, - 208, 231, 221, 34, 94, 16, 208, 237, 221, 34, 94, 16, 208, 235, 221, 34, - 94, 16, 237, 187, 221, 34, 94, 16, 237, 183, 221, 34, 94, 16, 237, 182, - 221, 34, 94, 16, 237, 185, 221, 34, 94, 16, 237, 184, 221, 34, 94, 16, - 237, 181, 221, 34, 94, 16, 197, 47, 94, 16, 215, 99, 206, 144, 94, 16, - 209, 137, 206, 144, 94, 16, 248, 191, 206, 144, 94, 16, 247, 189, 206, - 144, 94, 16, 208, 239, 206, 144, 94, 16, 208, 233, 206, 144, 94, 16, 208, - 231, 206, 144, 94, 16, 208, 237, 206, 144, 94, 16, 208, 235, 206, 144, - 94, 16, 237, 187, 206, 144, 94, 16, 237, 183, 206, 144, 94, 16, 237, 182, - 206, 144, 94, 16, 237, 185, 206, 144, 94, 16, 237, 184, 206, 144, 94, 16, - 237, 181, 206, 144, 247, 209, 1, 157, 247, 209, 1, 231, 203, 247, 209, 1, - 214, 54, 247, 209, 1, 213, 253, 247, 209, 1, 168, 247, 209, 1, 249, 103, - 247, 209, 1, 172, 247, 209, 1, 215, 150, 247, 209, 1, 199, 247, 247, 209, - 1, 237, 241, 247, 209, 1, 180, 247, 209, 1, 212, 231, 247, 209, 1, 247, - 112, 247, 209, 1, 223, 4, 247, 209, 1, 212, 88, 247, 209, 1, 212, 79, - 247, 209, 1, 169, 247, 209, 1, 166, 247, 209, 1, 171, 247, 209, 1, 195, - 185, 247, 209, 1, 189, 247, 209, 1, 65, 247, 209, 1, 144, 247, 209, 18, - 3, 70, 247, 209, 18, 3, 69, 247, 209, 18, 3, 73, 247, 209, 18, 3, 74, - 247, 209, 18, 3, 251, 229, 247, 209, 210, 174, 247, 209, 234, 53, 80, - 205, 48, 53, 128, 1, 136, 157, 53, 128, 1, 136, 221, 190, 53, 128, 1, - 136, 220, 141, 53, 128, 1, 131, 157, 53, 128, 1, 131, 220, 141, 53, 128, - 1, 131, 221, 190, 53, 128, 1, 214, 54, 53, 128, 1, 136, 247, 112, 53, - 128, 1, 136, 246, 209, 53, 128, 1, 131, 247, 112, 53, 128, 1, 131, 189, - 53, 128, 1, 131, 246, 209, 53, 128, 1, 212, 88, 53, 128, 1, 207, 124, 53, - 128, 1, 136, 207, 122, 53, 128, 1, 237, 241, 53, 128, 1, 131, 207, 122, - 53, 128, 1, 207, 133, 53, 128, 1, 136, 199, 247, 53, 128, 1, 136, 199, - 44, 53, 128, 1, 131, 199, 247, 53, 128, 1, 131, 199, 44, 53, 128, 1, 180, - 53, 128, 1, 249, 103, 53, 128, 1, 136, 168, 53, 128, 1, 136, 209, 219, - 53, 128, 1, 136, 233, 68, 53, 128, 1, 131, 168, 53, 128, 1, 131, 233, 68, - 53, 128, 1, 131, 209, 219, 53, 128, 1, 172, 53, 128, 1, 131, 169, 53, - 128, 1, 136, 169, 53, 128, 1, 166, 53, 128, 1, 206, 52, 53, 128, 1, 171, - 53, 128, 1, 218, 196, 53, 128, 1, 193, 187, 53, 128, 1, 136, 203, 160, - 53, 128, 1, 136, 201, 170, 53, 128, 1, 136, 189, 53, 128, 1, 136, 144, - 53, 128, 1, 219, 49, 53, 128, 1, 65, 53, 128, 1, 131, 144, 53, 128, 1, - 70, 53, 128, 1, 223, 170, 53, 128, 1, 69, 53, 128, 1, 196, 26, 53, 128, - 1, 234, 145, 53, 128, 1, 211, 76, 53, 128, 1, 220, 83, 53, 128, 1, 230, - 172, 189, 53, 128, 119, 3, 216, 198, 166, 53, 128, 119, 3, 216, 198, 171, - 53, 128, 119, 3, 220, 102, 199, 185, 220, 72, 53, 128, 3, 217, 92, 222, - 58, 220, 72, 53, 128, 119, 3, 52, 214, 54, 53, 128, 119, 3, 131, 168, 53, - 128, 119, 3, 136, 207, 123, 211, 46, 131, 168, 53, 128, 119, 3, 172, 53, - 128, 119, 3, 249, 103, 53, 128, 119, 3, 189, 53, 128, 3, 205, 167, 53, - 128, 18, 3, 65, 53, 128, 18, 3, 217, 92, 205, 117, 53, 128, 18, 3, 252, - 154, 53, 128, 18, 3, 199, 195, 252, 154, 53, 128, 18, 3, 70, 53, 128, 18, - 3, 223, 170, 53, 128, 18, 3, 196, 148, 53, 128, 18, 3, 196, 25, 53, 128, - 18, 3, 69, 53, 128, 18, 3, 196, 26, 53, 128, 18, 3, 74, 53, 128, 18, 3, - 211, 170, 60, 53, 128, 18, 3, 210, 232, 53, 128, 18, 3, 73, 53, 128, 18, - 3, 251, 229, 53, 128, 18, 3, 211, 76, 53, 128, 18, 3, 251, 184, 53, 128, - 18, 3, 128, 251, 184, 53, 128, 18, 3, 211, 170, 56, 53, 128, 3, 217, 92, - 222, 57, 53, 128, 3, 198, 73, 53, 128, 3, 198, 72, 53, 128, 3, 221, 147, - 198, 71, 53, 128, 3, 221, 147, 198, 70, 53, 128, 3, 221, 147, 198, 69, - 53, 128, 3, 207, 181, 230, 57, 53, 128, 3, 217, 92, 205, 147, 53, 128, 3, - 221, 146, 222, 38, 53, 128, 33, 238, 151, 236, 96, 53, 128, 228, 211, 17, - 191, 77, 53, 128, 228, 211, 17, 108, 53, 128, 228, 211, 17, 109, 53, 128, - 228, 211, 17, 139, 53, 128, 228, 211, 17, 137, 53, 128, 228, 211, 17, - 153, 53, 128, 228, 211, 17, 173, 53, 128, 228, 211, 17, 181, 53, 128, - 228, 211, 17, 176, 53, 128, 228, 211, 17, 184, 53, 128, 128, 17, 191, 77, - 53, 128, 128, 17, 108, 53, 128, 128, 17, 109, 53, 128, 128, 17, 139, 53, - 128, 128, 17, 137, 53, 128, 128, 17, 153, 53, 128, 128, 17, 173, 53, 128, - 128, 17, 181, 53, 128, 128, 17, 176, 53, 128, 128, 17, 184, 53, 128, 3, - 193, 78, 53, 128, 3, 193, 77, 53, 128, 3, 205, 102, 53, 128, 3, 221, 221, - 53, 128, 3, 228, 139, 53, 128, 3, 236, 112, 53, 128, 3, 207, 13, 206, - 117, 207, 133, 53, 128, 3, 217, 92, 192, 109, 53, 128, 3, 222, 93, 53, - 128, 3, 222, 92, 53, 128, 3, 205, 112, 53, 128, 3, 205, 111, 53, 128, 3, - 229, 249, 53, 128, 3, 247, 109, 33, 235, 84, 242, 210, 252, 8, 33, 236, - 252, 33, 223, 111, 33, 235, 75, 55, 33, 197, 221, 236, 96, 33, 192, 233, - 60, 33, 193, 70, 219, 89, 60, 33, 211, 66, 87, 60, 33, 54, 211, 66, 87, - 60, 33, 155, 246, 231, 201, 23, 60, 33, 201, 9, 246, 231, 201, 23, 60, - 33, 210, 105, 56, 33, 54, 210, 105, 56, 33, 210, 105, 60, 33, 210, 105, - 210, 245, 33, 8, 2, 1, 193, 222, 60, 33, 8, 2, 1, 152, 193, 222, 60, 33, - 45, 210, 104, 95, 219, 200, 33, 50, 210, 104, 95, 187, 33, 45, 210, 104, - 248, 183, 219, 200, 33, 50, 210, 104, 248, 183, 187, 33, 51, 248, 3, 56, - 33, 31, 3, 56, 33, 223, 65, 54, 250, 221, 56, 33, 107, 3, 56, 33, 54, - 107, 3, 56, 33, 54, 107, 3, 60, 33, 197, 221, 251, 251, 252, 8, 33, 8, 2, - 1, 223, 87, 232, 14, 33, 8, 2, 1, 223, 87, 148, 33, 8, 2, 1, 223, 87, - 200, 39, 147, 3, 196, 119, 206, 239, 147, 3, 196, 119, 247, 73, 147, 3, - 246, 246, 147, 3, 200, 168, 147, 3, 248, 107, 147, 1, 251, 163, 147, 1, - 251, 164, 199, 118, 147, 1, 223, 165, 147, 1, 223, 166, 199, 118, 147, 1, - 196, 122, 147, 1, 196, 123, 199, 118, 147, 1, 207, 181, 207, 46, 147, 1, - 207, 181, 207, 47, 199, 118, 147, 1, 220, 102, 219, 175, 147, 1, 220, - 102, 219, 176, 199, 118, 147, 1, 234, 102, 147, 1, 251, 181, 147, 1, 211, - 112, 147, 1, 211, 113, 199, 118, 147, 1, 157, 147, 1, 222, 115, 217, 95, - 147, 1, 231, 203, 147, 1, 231, 204, 230, 207, 147, 1, 214, 54, 147, 1, - 247, 112, 147, 1, 247, 113, 220, 88, 147, 1, 223, 4, 147, 1, 223, 5, 222, - 229, 147, 1, 212, 88, 147, 1, 199, 248, 219, 234, 147, 1, 199, 248, 215, - 94, 217, 95, 147, 1, 237, 242, 215, 94, 251, 111, 147, 1, 237, 242, 215, - 94, 217, 95, 147, 1, 214, 249, 207, 136, 147, 1, 199, 247, 147, 1, 199, - 248, 199, 153, 147, 1, 237, 241, 147, 1, 237, 242, 217, 117, 147, 1, 180, - 147, 1, 168, 147, 1, 210, 211, 222, 50, 147, 1, 249, 103, 147, 1, 249, - 104, 221, 233, 147, 1, 172, 147, 1, 169, 147, 1, 166, 147, 1, 171, 147, - 1, 193, 187, 147, 1, 205, 202, 205, 179, 147, 1, 205, 202, 205, 124, 147, - 1, 189, 147, 1, 144, 147, 3, 207, 36, 147, 18, 3, 199, 118, 147, 18, 3, - 196, 118, 147, 18, 3, 196, 119, 205, 120, 147, 18, 3, 200, 203, 147, 18, - 3, 200, 204, 223, 157, 147, 18, 3, 207, 181, 207, 46, 147, 18, 3, 207, - 181, 207, 47, 199, 118, 147, 18, 3, 220, 102, 219, 175, 147, 18, 3, 220, - 102, 219, 176, 199, 118, 147, 18, 3, 199, 196, 147, 18, 3, 199, 197, 207, - 46, 147, 18, 3, 199, 197, 199, 118, 147, 18, 3, 199, 197, 207, 47, 199, - 118, 147, 18, 3, 210, 7, 147, 18, 3, 210, 8, 199, 118, 147, 251, 241, - 251, 240, 147, 1, 222, 80, 205, 119, 147, 1, 221, 153, 205, 119, 147, 1, - 196, 231, 205, 119, 147, 1, 234, 139, 205, 119, 147, 1, 195, 151, 205, - 119, 147, 1, 191, 109, 205, 119, 147, 1, 250, 135, 205, 119, 147, 1, 250, - 220, 222, 175, 147, 17, 191, 77, 147, 17, 108, 147, 17, 109, 147, 17, - 139, 147, 17, 137, 147, 17, 153, 147, 17, 173, 147, 17, 181, 147, 17, - 176, 147, 17, 184, 147, 210, 135, 147, 210, 165, 147, 193, 62, 147, 247, - 46, 210, 158, 147, 247, 46, 202, 185, 147, 247, 46, 210, 102, 147, 210, - 164, 147, 37, 16, 236, 103, 147, 37, 16, 237, 57, 147, 37, 16, 235, 27, - 147, 37, 16, 237, 191, 147, 37, 16, 237, 192, 200, 168, 147, 37, 16, 236, - 197, 147, 37, 16, 237, 233, 147, 37, 16, 237, 32, 147, 37, 16, 237, 215, - 147, 37, 16, 237, 192, 231, 122, 147, 37, 16, 33, 199, 111, 147, 37, 16, - 33, 234, 50, 147, 37, 16, 33, 221, 228, 147, 37, 16, 33, 221, 230, 147, - 37, 16, 33, 222, 233, 147, 37, 16, 33, 221, 229, 4, 222, 233, 147, 37, - 16, 33, 221, 231, 4, 222, 233, 147, 37, 16, 33, 248, 176, 147, 37, 16, - 33, 230, 211, 147, 37, 16, 206, 201, 211, 66, 235, 38, 147, 37, 16, 206, - 201, 211, 66, 237, 231, 147, 37, 16, 206, 201, 242, 171, 197, 76, 147, - 37, 16, 206, 201, 242, 171, 199, 206, 147, 37, 16, 219, 198, 211, 66, - 210, 150, 147, 37, 16, 219, 198, 211, 66, 208, 142, 147, 37, 16, 219, - 198, 242, 171, 209, 96, 147, 37, 16, 219, 198, 242, 171, 209, 78, 147, - 37, 16, 219, 198, 211, 66, 209, 123, 147, 210, 136, 219, 251, 147, 210, - 166, 219, 251, 200, 192, 3, 210, 132, 200, 192, 3, 210, 146, 200, 192, 3, - 210, 142, 200, 192, 1, 65, 200, 192, 1, 70, 200, 192, 1, 69, 200, 192, 1, - 251, 229, 200, 192, 1, 74, 200, 192, 1, 73, 200, 192, 1, 233, 201, 200, - 192, 1, 157, 200, 192, 1, 208, 89, 200, 192, 1, 231, 203, 200, 192, 1, - 214, 54, 200, 192, 1, 247, 112, 200, 192, 1, 223, 4, 200, 192, 1, 191, - 123, 200, 192, 1, 212, 88, 200, 192, 1, 199, 247, 200, 192, 1, 237, 241, - 200, 192, 1, 180, 200, 192, 1, 168, 200, 192, 1, 233, 68, 200, 192, 1, - 195, 185, 200, 192, 1, 249, 103, 200, 192, 1, 172, 200, 192, 1, 169, 200, - 192, 1, 166, 200, 192, 1, 171, 200, 192, 1, 193, 187, 200, 192, 1, 189, - 200, 192, 1, 192, 220, 200, 192, 1, 144, 200, 192, 119, 3, 210, 162, 200, - 192, 119, 3, 210, 134, 200, 192, 119, 3, 210, 131, 200, 192, 18, 3, 210, - 149, 200, 192, 18, 3, 210, 130, 200, 192, 18, 3, 210, 155, 200, 192, 18, - 3, 210, 141, 200, 192, 18, 3, 210, 163, 200, 192, 18, 3, 210, 151, 200, - 192, 3, 210, 167, 200, 192, 3, 195, 37, 200, 192, 119, 3, 210, 90, 172, - 200, 192, 119, 3, 210, 90, 193, 187, 200, 192, 1, 221, 190, 200, 192, 1, - 200, 122, 200, 192, 17, 191, 77, 200, 192, 17, 108, 200, 192, 17, 109, - 200, 192, 17, 139, 200, 192, 17, 137, 200, 192, 17, 153, 200, 192, 17, - 173, 200, 192, 17, 181, 200, 192, 17, 176, 200, 192, 17, 184, 200, 192, - 250, 95, 200, 192, 1, 207, 16, 200, 192, 1, 219, 148, 200, 192, 1, 248, - 153, 200, 192, 1, 52, 222, 125, 200, 192, 1, 52, 218, 147, 249, 13, 1, - 65, 249, 13, 1, 202, 177, 65, 249, 13, 1, 144, 249, 13, 1, 202, 177, 144, - 249, 13, 1, 217, 65, 144, 249, 13, 1, 249, 103, 249, 13, 1, 222, 35, 249, - 103, 249, 13, 1, 168, 249, 13, 1, 202, 177, 168, 249, 13, 1, 180, 249, - 13, 1, 217, 65, 180, 249, 13, 1, 193, 187, 249, 13, 1, 202, 177, 193, - 187, 249, 13, 1, 210, 183, 193, 187, 249, 13, 1, 231, 203, 249, 13, 1, - 202, 177, 231, 203, 249, 13, 1, 223, 4, 249, 13, 1, 237, 241, 249, 13, 1, - 166, 249, 13, 1, 202, 177, 166, 249, 13, 1, 172, 249, 13, 1, 202, 177, - 172, 249, 13, 1, 201, 251, 199, 247, 249, 13, 1, 213, 3, 199, 247, 249, - 13, 1, 189, 249, 13, 1, 202, 177, 189, 249, 13, 1, 217, 65, 189, 249, 13, - 1, 169, 249, 13, 1, 202, 177, 169, 249, 13, 1, 214, 54, 249, 13, 1, 171, - 249, 13, 1, 202, 177, 171, 249, 13, 1, 212, 88, 249, 13, 1, 247, 112, - 249, 13, 1, 214, 148, 249, 13, 1, 216, 248, 249, 13, 1, 70, 249, 13, 1, - 69, 249, 13, 3, 198, 77, 249, 13, 18, 3, 73, 249, 13, 18, 3, 210, 183, - 73, 249, 13, 18, 3, 234, 145, 249, 13, 18, 3, 70, 249, 13, 18, 3, 222, - 35, 70, 249, 13, 18, 3, 74, 249, 13, 18, 3, 222, 35, 74, 249, 13, 18, 3, - 69, 249, 13, 18, 3, 126, 39, 202, 177, 189, 249, 13, 119, 3, 214, 56, - 249, 13, 119, 3, 230, 83, 249, 13, 210, 144, 249, 13, 210, 140, 249, 13, - 16, 248, 117, 214, 249, 216, 144, 249, 13, 16, 248, 117, 209, 129, 249, - 13, 16, 248, 117, 222, 152, 249, 13, 16, 248, 117, 210, 144, 219, 159, 1, - 157, 219, 159, 1, 221, 70, 219, 159, 1, 221, 190, 219, 159, 1, 231, 203, - 219, 159, 1, 230, 239, 219, 159, 1, 214, 54, 219, 159, 1, 247, 112, 219, - 159, 1, 246, 209, 219, 159, 1, 223, 4, 219, 159, 1, 212, 88, 219, 159, 1, - 199, 247, 219, 159, 1, 199, 44, 219, 159, 1, 237, 241, 219, 159, 1, 180, - 219, 159, 1, 168, 219, 159, 1, 209, 102, 219, 159, 1, 209, 219, 219, 159, - 1, 233, 68, 219, 159, 1, 232, 179, 219, 159, 1, 249, 103, 219, 159, 1, - 248, 92, 219, 159, 1, 172, 219, 159, 1, 216, 2, 219, 159, 1, 197, 164, - 219, 159, 1, 197, 153, 219, 159, 1, 234, 247, 219, 159, 1, 169, 219, 159, - 1, 166, 219, 159, 1, 171, 219, 159, 1, 144, 219, 159, 1, 229, 79, 219, - 159, 1, 195, 185, 219, 159, 1, 189, 219, 159, 1, 203, 160, 219, 159, 1, - 193, 187, 219, 159, 1, 65, 219, 159, 200, 234, 1, 169, 219, 159, 200, - 234, 1, 166, 219, 159, 18, 3, 252, 154, 219, 159, 18, 3, 70, 219, 159, - 18, 3, 74, 219, 159, 18, 3, 211, 76, 219, 159, 18, 3, 69, 219, 159, 18, - 3, 196, 26, 219, 159, 18, 3, 73, 219, 159, 119, 3, 222, 125, 219, 159, - 119, 3, 218, 147, 219, 159, 119, 3, 170, 219, 159, 119, 3, 215, 47, 219, - 159, 119, 3, 210, 226, 219, 159, 119, 3, 148, 219, 159, 119, 3, 200, 39, - 219, 159, 119, 3, 212, 60, 219, 159, 119, 3, 222, 57, 219, 159, 3, 207, - 134, 219, 159, 3, 212, 128, 219, 159, 208, 145, 199, 242, 219, 159, 208, - 145, 212, 72, 198, 191, 199, 242, 219, 159, 208, 145, 246, 218, 219, 159, - 208, 145, 197, 145, 246, 218, 219, 159, 208, 145, 197, 144, 219, 159, 17, - 191, 77, 219, 159, 17, 108, 219, 159, 17, 109, 219, 159, 17, 139, 219, - 159, 17, 137, 219, 159, 17, 153, 219, 159, 17, 173, 219, 159, 17, 181, - 219, 159, 17, 176, 219, 159, 17, 184, 219, 159, 1, 197, 128, 219, 159, 1, - 197, 116, 219, 159, 1, 237, 146, 211, 110, 243, 40, 17, 191, 77, 211, - 110, 243, 40, 17, 108, 211, 110, 243, 40, 17, 109, 211, 110, 243, 40, 17, - 139, 211, 110, 243, 40, 17, 137, 211, 110, 243, 40, 17, 153, 211, 110, - 243, 40, 17, 173, 211, 110, 243, 40, 17, 181, 211, 110, 243, 40, 17, 176, - 211, 110, 243, 40, 17, 184, 211, 110, 243, 40, 1, 171, 211, 110, 243, 40, - 1, 250, 132, 211, 110, 243, 40, 1, 251, 201, 211, 110, 243, 40, 1, 251, - 71, 211, 110, 243, 40, 1, 251, 156, 211, 110, 243, 40, 1, 220, 101, 211, - 110, 243, 40, 1, 252, 116, 211, 110, 243, 40, 1, 252, 117, 211, 110, 243, - 40, 1, 252, 115, 211, 110, 243, 40, 1, 252, 109, 211, 110, 243, 40, 1, - 219, 122, 211, 110, 243, 40, 1, 223, 40, 211, 110, 243, 40, 1, 223, 171, - 211, 110, 243, 40, 1, 223, 62, 211, 110, 243, 40, 1, 223, 49, 211, 110, - 243, 40, 1, 218, 203, 211, 110, 243, 40, 1, 196, 156, 211, 110, 243, 40, - 1, 196, 154, 211, 110, 243, 40, 1, 196, 79, 211, 110, 243, 40, 1, 196, - 17, 211, 110, 243, 40, 1, 219, 214, 211, 110, 243, 40, 1, 234, 14, 211, - 110, 243, 40, 1, 234, 148, 211, 110, 243, 40, 1, 234, 61, 211, 110, 243, - 40, 1, 233, 240, 211, 110, 243, 40, 1, 219, 19, 211, 110, 243, 40, 1, - 211, 14, 211, 110, 243, 40, 1, 211, 165, 211, 110, 243, 40, 1, 210, 255, - 211, 110, 243, 40, 1, 211, 124, 211, 110, 243, 40, 215, 140, 197, 93, - 211, 110, 243, 40, 231, 198, 197, 94, 211, 110, 243, 40, 215, 134, 197, - 94, 211, 110, 243, 40, 207, 61, 211, 110, 243, 40, 209, 217, 211, 110, - 243, 40, 251, 192, 211, 110, 243, 40, 208, 145, 215, 130, 211, 110, 243, - 40, 208, 145, 54, 215, 130, 42, 2, 1, 206, 108, 195, 150, 42, 2, 1, 218, - 244, 237, 101, 42, 2, 1, 214, 201, 74, 42, 2, 1, 193, 76, 233, 236, 42, - 2, 1, 199, 195, 199, 140, 42, 2, 1, 198, 216, 199, 140, 42, 2, 1, 199, - 195, 229, 240, 57, 42, 2, 1, 199, 195, 192, 95, 42, 2, 1, 196, 104, 196, - 124, 100, 215, 141, 6, 1, 251, 81, 100, 215, 141, 6, 1, 249, 51, 100, - 215, 141, 6, 1, 231, 173, 100, 215, 141, 6, 1, 236, 105, 100, 215, 141, - 6, 1, 234, 61, 100, 215, 141, 6, 1, 195, 46, 100, 215, 141, 6, 1, 191, - 80, 100, 215, 141, 6, 1, 199, 188, 100, 215, 141, 6, 1, 223, 134, 100, - 215, 141, 6, 1, 222, 61, 100, 215, 141, 6, 1, 219, 239, 100, 215, 141, 6, - 1, 217, 70, 100, 215, 141, 6, 1, 214, 202, 100, 215, 141, 6, 1, 211, 93, - 100, 215, 141, 6, 1, 210, 121, 100, 215, 141, 6, 1, 191, 67, 100, 215, - 141, 6, 1, 207, 158, 100, 215, 141, 6, 1, 205, 137, 100, 215, 141, 6, 1, - 199, 174, 100, 215, 141, 6, 1, 196, 109, 100, 215, 141, 6, 1, 209, 211, - 100, 215, 141, 6, 1, 221, 176, 100, 215, 141, 6, 1, 231, 45, 100, 215, - 141, 6, 1, 208, 74, 100, 215, 141, 6, 1, 203, 64, 100, 215, 141, 6, 1, - 243, 33, 100, 215, 141, 6, 1, 247, 80, 100, 215, 141, 6, 1, 222, 207, - 100, 215, 141, 6, 1, 242, 226, 100, 215, 141, 6, 1, 246, 193, 100, 215, - 141, 6, 1, 192, 218, 100, 215, 141, 6, 1, 222, 222, 100, 215, 141, 6, 1, - 230, 54, 100, 215, 141, 6, 1, 229, 213, 100, 215, 141, 6, 1, 229, 113, - 100, 215, 141, 6, 1, 193, 123, 100, 215, 141, 6, 1, 229, 242, 100, 215, - 141, 6, 1, 228, 235, 100, 215, 141, 6, 1, 232, 238, 100, 215, 141, 6, 1, - 192, 14, 100, 215, 141, 6, 1, 234, 80, 100, 215, 141, 6, 1, 152, 231, - 173, 100, 215, 141, 6, 1, 251, 178, 100, 215, 141, 6, 1, 251, 218, 100, - 215, 141, 6, 1, 229, 240, 57, 100, 215, 141, 6, 1, 220, 92, 57, 200, 192, - 208, 145, 248, 117, 200, 161, 200, 192, 208, 145, 248, 117, 210, 145, - 200, 192, 208, 145, 248, 117, 208, 132, 200, 192, 208, 145, 248, 117, - 247, 97, 200, 192, 208, 145, 248, 117, 219, 149, 205, 116, 200, 192, 208, - 145, 248, 117, 222, 115, 205, 116, 200, 192, 208, 145, 248, 117, 237, - 242, 205, 116, 200, 192, 208, 145, 248, 117, 249, 104, 205, 116, 195, - 147, 163, 222, 31, 195, 147, 163, 203, 125, 195, 147, 163, 208, 218, 195, - 147, 3, 213, 173, 195, 147, 3, 192, 117, 216, 64, 200, 152, 195, 147, - 163, 192, 117, 251, 197, 223, 121, 200, 152, 195, 147, 163, 192, 117, - 223, 121, 200, 152, 195, 147, 163, 192, 117, 222, 19, 223, 121, 200, 152, - 195, 147, 163, 247, 74, 60, 195, 147, 163, 192, 117, 222, 19, 223, 121, - 200, 153, 205, 83, 195, 147, 163, 54, 200, 152, 195, 147, 163, 197, 221, - 200, 152, 195, 147, 163, 222, 19, 251, 22, 195, 147, 163, 75, 60, 195, - 147, 163, 103, 183, 60, 195, 147, 163, 115, 183, 60, 195, 147, 163, 206, - 191, 222, 30, 223, 121, 200, 152, 195, 147, 163, 250, 129, 223, 121, 200, - 152, 195, 147, 3, 195, 33, 200, 152, 195, 147, 3, 195, 33, 196, 150, 195, - 147, 3, 207, 13, 195, 33, 196, 150, 195, 147, 3, 195, 33, 251, 22, 195, - 147, 3, 207, 13, 195, 33, 251, 22, 195, 147, 3, 195, 33, 196, 151, 4, - 199, 210, 195, 147, 3, 195, 33, 251, 23, 4, 199, 210, 195, 147, 3, 251, - 21, 251, 37, 195, 147, 3, 251, 21, 249, 70, 195, 147, 3, 251, 21, 195, - 175, 195, 147, 3, 251, 21, 195, 176, 4, 199, 210, 195, 147, 3, 198, 121, - 195, 147, 3, 229, 148, 177, 251, 20, 195, 147, 3, 177, 251, 20, 195, 147, - 3, 206, 65, 177, 251, 20, 195, 147, 3, 251, 21, 196, 158, 215, 121, 195, - 147, 3, 250, 216, 195, 147, 3, 206, 117, 250, 216, 195, 147, 163, 247, - 74, 56, 195, 147, 3, 222, 210, 195, 147, 3, 196, 71, 195, 147, 3, 250, - 127, 195, 147, 163, 206, 184, 56, 195, 147, 163, 54, 206, 184, 56, 195, - 147, 3, 54, 251, 21, 251, 37, 8, 1, 2, 6, 65, 8, 1, 2, 6, 251, 229, 8, 2, - 1, 152, 251, 229, 8, 1, 2, 6, 249, 32, 250, 70, 8, 1, 2, 6, 247, 145, 8, - 1, 2, 6, 238, 80, 8, 1, 2, 6, 233, 206, 8, 1, 2, 6, 73, 8, 2, 1, 152, - 211, 66, 73, 8, 2, 1, 152, 70, 8, 1, 2, 6, 223, 7, 8, 1, 2, 6, 222, 125, - 8, 1, 2, 6, 220, 119, 4, 105, 8, 1, 2, 6, 218, 147, 8, 1, 2, 6, 207, 13, - 215, 47, 8, 1, 2, 6, 74, 8, 1, 2, 6, 211, 66, 74, 8, 2, 1, 202, 201, 74, - 8, 2, 1, 202, 201, 211, 66, 74, 8, 2, 1, 202, 201, 186, 4, 105, 8, 2, 1, - 152, 211, 139, 8, 1, 2, 6, 211, 9, 8, 2, 1, 198, 49, 134, 74, 8, 2, 1, - 248, 29, 134, 74, 8, 1, 2, 6, 210, 226, 8, 1, 2, 6, 207, 13, 148, 8, 1, - 2, 6, 152, 148, 8, 1, 2, 6, 200, 39, 8, 1, 2, 6, 69, 8, 2, 1, 202, 201, - 69, 8, 2, 1, 202, 201, 236, 251, 69, 8, 2, 1, 202, 201, 152, 218, 147, 8, - 1, 2, 6, 196, 8, 8, 1, 2, 6, 193, 221, 8, 1, 2, 6, 191, 166, 8, 1, 2, 6, - 233, 137, 8, 1, 195, 17, 219, 240, 201, 211, 8, 1, 251, 178, 35, 1, 2, 6, - 231, 174, 35, 1, 2, 6, 220, 7, 35, 1, 2, 6, 209, 176, 35, 1, 2, 6, 206, - 254, 35, 1, 2, 6, 208, 169, 42, 1, 2, 6, 234, 97, 59, 1, 6, 65, 59, 1, 6, - 251, 229, 59, 1, 6, 250, 70, 59, 1, 6, 249, 32, 250, 70, 59, 1, 6, 238, - 80, 59, 1, 6, 73, 59, 1, 6, 207, 13, 73, 59, 1, 6, 232, 14, 59, 1, 6, - 230, 83, 59, 1, 6, 70, 59, 1, 6, 223, 7, 59, 1, 6, 222, 125, 59, 1, 6, - 170, 59, 1, 6, 218, 147, 59, 1, 6, 215, 47, 59, 1, 6, 207, 13, 215, 47, - 59, 1, 6, 74, 59, 1, 6, 211, 9, 59, 1, 6, 210, 226, 59, 1, 6, 148, 59, 1, - 6, 200, 39, 59, 1, 6, 69, 59, 1, 6, 193, 221, 59, 1, 2, 65, 59, 1, 2, - 152, 65, 59, 1, 2, 251, 109, 59, 1, 2, 152, 251, 229, 59, 1, 2, 250, 70, - 59, 1, 2, 238, 80, 59, 1, 2, 73, 59, 1, 2, 205, 81, 59, 1, 2, 211, 66, - 73, 59, 1, 2, 152, 211, 66, 73, 59, 1, 2, 232, 14, 59, 1, 2, 152, 70, 59, - 1, 2, 222, 125, 59, 1, 2, 218, 147, 59, 1, 2, 234, 46, 59, 1, 2, 74, 59, - 1, 2, 211, 66, 74, 59, 1, 2, 198, 49, 134, 74, 59, 1, 2, 248, 29, 134, - 74, 59, 1, 2, 210, 226, 59, 1, 2, 200, 39, 59, 1, 2, 69, 59, 1, 2, 202, - 201, 69, 59, 1, 2, 152, 218, 147, 59, 1, 2, 196, 8, 59, 1, 2, 251, 178, - 59, 1, 2, 248, 162, 59, 1, 2, 35, 231, 174, 59, 1, 2, 237, 61, 59, 1, 2, - 35, 209, 202, 59, 1, 2, 243, 47, 8, 200, 225, 2, 1, 70, 8, 200, 225, 2, - 1, 148, 8, 200, 225, 2, 1, 69, 8, 200, 225, 2, 1, 196, 8, 35, 200, 225, - 2, 1, 248, 162, 35, 200, 225, 2, 1, 231, 174, 35, 200, 225, 2, 1, 206, - 254, 35, 200, 225, 2, 1, 209, 202, 35, 200, 225, 2, 1, 243, 47, 8, 2, 1, - 196, 148, 8, 2, 1, 78, 4, 82, 198, 147, 8, 2, 1, 238, 81, 4, 82, 198, - 147, 8, 2, 1, 233, 135, 4, 82, 198, 147, 8, 2, 1, 218, 148, 4, 82, 198, - 147, 8, 2, 1, 215, 48, 4, 82, 198, 147, 8, 2, 1, 210, 227, 4, 82, 198, - 147, 8, 2, 1, 207, 217, 4, 82, 198, 147, 8, 2, 1, 207, 217, 4, 232, 193, - 24, 82, 198, 147, 8, 2, 1, 206, 4, 4, 82, 198, 147, 8, 2, 1, 200, 40, 4, - 82, 198, 147, 8, 2, 1, 191, 167, 4, 82, 198, 147, 8, 2, 1, 152, 232, 14, - 59, 1, 42, 234, 61, 8, 2, 1, 223, 87, 232, 14, 8, 2, 1, 199, 47, 4, 201, - 27, 8, 2, 6, 1, 228, 44, 4, 105, 8, 2, 1, 223, 56, 4, 105, 8, 2, 1, 210, - 227, 4, 105, 8, 2, 6, 1, 126, 4, 105, 8, 2, 1, 196, 67, 4, 105, 8, 2, 1, - 78, 4, 210, 182, 106, 8, 2, 1, 238, 81, 4, 210, 182, 106, 8, 2, 1, 233, - 135, 4, 210, 182, 106, 8, 2, 1, 232, 15, 4, 210, 182, 106, 8, 2, 1, 222, - 126, 4, 210, 182, 106, 8, 2, 1, 220, 119, 4, 210, 182, 106, 8, 2, 1, 218, - 148, 4, 210, 182, 106, 8, 2, 1, 215, 48, 4, 210, 182, 106, 8, 2, 1, 210, - 227, 4, 210, 182, 106, 8, 2, 1, 207, 217, 4, 210, 182, 106, 8, 2, 1, 206, - 4, 4, 210, 182, 106, 8, 2, 1, 233, 227, 4, 210, 182, 106, 8, 2, 1, 196, - 9, 4, 210, 182, 106, 8, 2, 1, 192, 236, 4, 210, 182, 106, 8, 2, 1, 191, - 167, 4, 210, 182, 106, 8, 2, 1, 41, 4, 207, 19, 106, 8, 2, 1, 251, 110, - 4, 207, 19, 106, 8, 2, 1, 238, 81, 4, 228, 219, 24, 199, 210, 8, 2, 1, - 234, 227, 4, 207, 19, 106, 8, 2, 1, 211, 66, 234, 227, 4, 207, 19, 106, - 8, 2, 1, 207, 13, 211, 66, 234, 227, 4, 207, 19, 106, 8, 2, 1, 205, 82, - 4, 207, 19, 106, 8, 2, 1, 228, 44, 4, 207, 19, 106, 8, 2, 1, 211, 66, - 186, 4, 207, 19, 106, 8, 2, 1, 233, 227, 4, 207, 19, 106, 8, 2, 1, 126, - 4, 207, 19, 106, 8, 2, 1, 233, 138, 4, 207, 19, 106, 59, 1, 2, 152, 251, - 109, 59, 1, 2, 247, 145, 59, 1, 2, 247, 146, 4, 238, 128, 59, 1, 2, 233, - 206, 59, 1, 2, 207, 13, 211, 66, 73, 59, 1, 2, 233, 134, 59, 1, 2, 236, - 95, 223, 8, 4, 105, 59, 1, 2, 27, 232, 14, 59, 1, 2, 152, 230, 83, 59, 1, - 2, 228, 44, 4, 105, 59, 1, 2, 223, 55, 59, 1, 2, 6, 70, 59, 1, 2, 6, 228, - 44, 4, 105, 59, 1, 2, 223, 8, 4, 238, 165, 59, 1, 2, 220, 119, 4, 207, - 19, 106, 59, 1, 2, 220, 119, 4, 210, 182, 106, 59, 1, 2, 6, 170, 59, 1, - 2, 218, 148, 4, 106, 59, 1, 2, 152, 218, 148, 4, 177, 219, 188, 59, 1, 2, - 215, 48, 4, 45, 106, 59, 1, 2, 215, 48, 4, 207, 19, 106, 59, 1, 2, 6, - 215, 47, 59, 1, 2, 249, 32, 74, 59, 1, 2, 209, 202, 59, 1, 2, 206, 4, 4, - 106, 59, 1, 2, 233, 226, 59, 1, 2, 200, 40, 4, 210, 182, 106, 59, 1, 2, - 126, 164, 59, 1, 2, 196, 66, 59, 1, 2, 6, 69, 59, 1, 2, 196, 9, 4, 106, - 59, 1, 2, 152, 196, 8, 59, 1, 2, 191, 166, 59, 1, 2, 191, 167, 4, 207, - 19, 106, 59, 1, 2, 191, 167, 4, 238, 128, 59, 1, 2, 233, 137, 59, 1, 2, - 199, 10, 33, 235, 94, 230, 177, 252, 8, 33, 235, 94, 251, 251, 252, 8, - 33, 202, 54, 60, 33, 200, 159, 77, 33, 217, 124, 33, 230, 174, 33, 217, - 122, 33, 251, 248, 33, 230, 175, 33, 251, 249, 33, 8, 2, 1, 207, 217, 60, - 33, 247, 243, 33, 217, 123, 33, 54, 242, 210, 56, 33, 211, 127, 56, 33, - 191, 21, 60, 33, 223, 41, 60, 33, 196, 59, 56, 33, 196, 42, 56, 33, 8, 2, - 1, 232, 163, 211, 66, 41, 56, 33, 8, 2, 1, 251, 229, 33, 8, 2, 1, 251, - 18, 33, 8, 2, 1, 250, 96, 33, 8, 2, 1, 247, 146, 246, 243, 33, 8, 2, 1, - 223, 87, 238, 80, 33, 8, 2, 1, 233, 206, 33, 8, 2, 1, 232, 14, 33, 8, 1, - 2, 6, 232, 14, 33, 8, 2, 1, 222, 125, 33, 8, 2, 1, 170, 33, 8, 1, 2, 6, - 170, 33, 8, 1, 2, 6, 218, 147, 33, 8, 2, 1, 215, 47, 33, 8, 1, 2, 6, 215, - 47, 33, 8, 1, 2, 6, 148, 33, 8, 2, 1, 207, 217, 206, 111, 33, 8, 2, 1, - 206, 3, 33, 8, 2, 1, 177, 206, 3, 33, 8, 2, 1, 191, 166, 33, 8, 2, 1, - 251, 109, 33, 8, 2, 1, 250, 70, 33, 8, 2, 1, 248, 162, 33, 8, 2, 1, 205, - 81, 33, 8, 2, 1, 233, 134, 33, 8, 2, 1, 220, 119, 4, 54, 82, 198, 147, - 33, 8, 2, 1, 186, 4, 155, 246, 231, 105, 33, 8, 2, 1, 210, 226, 33, 8, 2, - 1, 233, 226, 33, 8, 2, 1, 126, 4, 155, 246, 231, 105, 33, 8, 2, 1, 193, - 221, 33, 8, 2, 1, 41, 4, 236, 253, 33, 8, 2, 1, 186, 4, 236, 253, 33, 8, - 2, 1, 126, 4, 236, 253, 33, 132, 199, 224, 56, 33, 222, 10, 95, 187, 33, - 222, 10, 95, 219, 200, 33, 75, 95, 219, 200, 33, 193, 76, 223, 65, 247, - 237, 60, 33, 75, 248, 183, 219, 200, 33, 237, 70, 77, 33, 54, 223, 65, - 247, 245, 60, 33, 251, 114, 234, 3, 118, 60, 33, 45, 250, 186, 56, 33, - 50, 250, 186, 24, 143, 250, 186, 60, 8, 6, 1, 41, 4, 206, 184, 60, 8, 2, - 1, 41, 4, 206, 184, 60, 8, 6, 1, 78, 4, 75, 56, 8, 2, 1, 78, 4, 75, 56, - 8, 6, 1, 78, 4, 75, 60, 8, 2, 1, 78, 4, 75, 60, 8, 6, 1, 78, 4, 219, 89, - 60, 8, 2, 1, 78, 4, 219, 89, 60, 8, 6, 1, 247, 146, 4, 246, 244, 24, 251, - 250, 8, 2, 1, 247, 146, 4, 246, 244, 24, 251, 250, 8, 6, 1, 238, 81, 4, - 75, 56, 8, 2, 1, 238, 81, 4, 75, 56, 8, 6, 1, 238, 81, 4, 75, 60, 8, 2, - 1, 238, 81, 4, 75, 60, 8, 6, 1, 238, 81, 4, 219, 89, 60, 8, 2, 1, 238, - 81, 4, 219, 89, 60, 8, 6, 1, 238, 81, 4, 246, 243, 8, 2, 1, 238, 81, 4, - 246, 243, 8, 6, 1, 238, 81, 4, 242, 210, 60, 8, 2, 1, 238, 81, 4, 242, - 210, 60, 8, 6, 1, 234, 227, 4, 217, 126, 24, 230, 176, 8, 2, 1, 234, 227, - 4, 217, 126, 24, 230, 176, 8, 6, 1, 234, 227, 4, 217, 126, 24, 251, 250, - 8, 2, 1, 234, 227, 4, 217, 126, 24, 251, 250, 8, 6, 1, 234, 227, 4, 242, - 210, 60, 8, 2, 1, 234, 227, 4, 242, 210, 60, 8, 6, 1, 234, 227, 4, 198, - 148, 60, 8, 2, 1, 234, 227, 4, 198, 148, 60, 8, 6, 1, 234, 227, 4, 246, - 244, 24, 247, 244, 8, 2, 1, 234, 227, 4, 246, 244, 24, 247, 244, 8, 6, 1, - 233, 135, 4, 75, 56, 8, 2, 1, 233, 135, 4, 75, 56, 8, 6, 1, 232, 15, 4, - 217, 125, 8, 2, 1, 232, 15, 4, 217, 125, 8, 6, 1, 230, 84, 4, 75, 56, 8, - 2, 1, 230, 84, 4, 75, 56, 8, 6, 1, 230, 84, 4, 75, 60, 8, 2, 1, 230, 84, - 4, 75, 60, 8, 6, 1, 230, 84, 4, 236, 253, 8, 2, 1, 230, 84, 4, 236, 253, - 8, 6, 1, 230, 84, 4, 246, 243, 8, 2, 1, 230, 84, 4, 246, 243, 8, 6, 1, - 230, 84, 4, 247, 245, 60, 8, 2, 1, 230, 84, 4, 247, 245, 60, 8, 6, 1, - 228, 44, 4, 198, 148, 60, 8, 2, 1, 228, 44, 4, 198, 148, 60, 8, 6, 1, - 228, 44, 4, 236, 254, 24, 251, 250, 8, 2, 1, 228, 44, 4, 236, 254, 24, - 251, 250, 8, 6, 1, 222, 126, 4, 251, 250, 8, 2, 1, 222, 126, 4, 251, 250, - 8, 6, 1, 222, 126, 4, 75, 60, 8, 2, 1, 222, 126, 4, 75, 60, 8, 6, 1, 222, - 126, 4, 219, 89, 60, 8, 2, 1, 222, 126, 4, 219, 89, 60, 8, 6, 1, 220, - 119, 4, 75, 60, 8, 2, 1, 220, 119, 4, 75, 60, 8, 6, 1, 220, 119, 4, 75, - 248, 183, 24, 217, 125, 8, 2, 1, 220, 119, 4, 75, 248, 183, 24, 217, 125, - 8, 6, 1, 220, 119, 4, 219, 89, 60, 8, 2, 1, 220, 119, 4, 219, 89, 60, 8, - 6, 1, 220, 119, 4, 242, 210, 60, 8, 2, 1, 220, 119, 4, 242, 210, 60, 8, - 6, 1, 218, 148, 4, 251, 250, 8, 2, 1, 218, 148, 4, 251, 250, 8, 6, 1, - 218, 148, 4, 75, 56, 8, 2, 1, 218, 148, 4, 75, 56, 8, 6, 1, 218, 148, 4, - 75, 60, 8, 2, 1, 218, 148, 4, 75, 60, 8, 6, 1, 215, 48, 4, 75, 56, 8, 2, - 1, 215, 48, 4, 75, 56, 8, 6, 1, 215, 48, 4, 75, 60, 8, 2, 1, 215, 48, 4, - 75, 60, 8, 6, 1, 215, 48, 4, 219, 89, 60, 8, 2, 1, 215, 48, 4, 219, 89, - 60, 8, 6, 1, 215, 48, 4, 242, 210, 60, 8, 2, 1, 215, 48, 4, 242, 210, 60, - 8, 6, 1, 186, 4, 198, 148, 24, 251, 250, 8, 2, 1, 186, 4, 198, 148, 24, - 251, 250, 8, 6, 1, 186, 4, 198, 148, 24, 236, 253, 8, 2, 1, 186, 4, 198, - 148, 24, 236, 253, 8, 6, 1, 186, 4, 217, 126, 24, 230, 176, 8, 2, 1, 186, - 4, 217, 126, 24, 230, 176, 8, 6, 1, 186, 4, 217, 126, 24, 251, 250, 8, 2, - 1, 186, 4, 217, 126, 24, 251, 250, 8, 6, 1, 210, 227, 4, 251, 250, 8, 2, - 1, 210, 227, 4, 251, 250, 8, 6, 1, 210, 227, 4, 75, 56, 8, 2, 1, 210, - 227, 4, 75, 56, 8, 6, 1, 207, 217, 4, 75, 56, 8, 2, 1, 207, 217, 4, 75, - 56, 8, 6, 1, 207, 217, 4, 75, 60, 8, 2, 1, 207, 217, 4, 75, 60, 8, 6, 1, - 207, 217, 4, 75, 248, 183, 24, 217, 125, 8, 2, 1, 207, 217, 4, 75, 248, - 183, 24, 217, 125, 8, 6, 1, 207, 217, 4, 219, 89, 60, 8, 2, 1, 207, 217, - 4, 219, 89, 60, 8, 6, 1, 206, 4, 4, 75, 56, 8, 2, 1, 206, 4, 4, 75, 56, - 8, 6, 1, 206, 4, 4, 75, 60, 8, 2, 1, 206, 4, 4, 75, 60, 8, 6, 1, 206, 4, - 4, 251, 251, 24, 75, 56, 8, 2, 1, 206, 4, 4, 251, 251, 24, 75, 56, 8, 6, - 1, 206, 4, 4, 247, 45, 24, 75, 56, 8, 2, 1, 206, 4, 4, 247, 45, 24, 75, - 56, 8, 6, 1, 206, 4, 4, 75, 248, 183, 24, 75, 56, 8, 2, 1, 206, 4, 4, 75, - 248, 183, 24, 75, 56, 8, 6, 1, 200, 40, 4, 75, 56, 8, 2, 1, 200, 40, 4, - 75, 56, 8, 6, 1, 200, 40, 4, 75, 60, 8, 2, 1, 200, 40, 4, 75, 60, 8, 6, - 1, 200, 40, 4, 219, 89, 60, 8, 2, 1, 200, 40, 4, 219, 89, 60, 8, 6, 1, - 200, 40, 4, 242, 210, 60, 8, 2, 1, 200, 40, 4, 242, 210, 60, 8, 6, 1, - 126, 4, 236, 254, 60, 8, 2, 1, 126, 4, 236, 254, 60, 8, 6, 1, 126, 4, - 198, 148, 60, 8, 2, 1, 126, 4, 198, 148, 60, 8, 6, 1, 126, 4, 242, 210, - 60, 8, 2, 1, 126, 4, 242, 210, 60, 8, 6, 1, 126, 4, 198, 148, 24, 251, - 250, 8, 2, 1, 126, 4, 198, 148, 24, 251, 250, 8, 6, 1, 126, 4, 217, 126, - 24, 236, 253, 8, 2, 1, 126, 4, 217, 126, 24, 236, 253, 8, 6, 1, 196, 9, - 4, 198, 147, 8, 2, 1, 196, 9, 4, 198, 147, 8, 6, 1, 196, 9, 4, 75, 60, 8, - 2, 1, 196, 9, 4, 75, 60, 8, 6, 1, 193, 222, 4, 230, 176, 8, 2, 1, 193, - 222, 4, 230, 176, 8, 6, 1, 193, 222, 4, 251, 250, 8, 2, 1, 193, 222, 4, - 251, 250, 8, 6, 1, 193, 222, 4, 236, 253, 8, 2, 1, 193, 222, 4, 236, 253, - 8, 6, 1, 193, 222, 4, 75, 56, 8, 2, 1, 193, 222, 4, 75, 56, 8, 6, 1, 193, - 222, 4, 75, 60, 8, 2, 1, 193, 222, 4, 75, 60, 8, 6, 1, 192, 236, 4, 75, - 56, 8, 2, 1, 192, 236, 4, 75, 56, 8, 6, 1, 192, 236, 4, 236, 253, 8, 2, - 1, 192, 236, 4, 236, 253, 8, 6, 1, 192, 160, 4, 75, 56, 8, 2, 1, 192, - 160, 4, 75, 56, 8, 6, 1, 191, 167, 4, 242, 209, 8, 2, 1, 191, 167, 4, - 242, 209, 8, 6, 1, 191, 167, 4, 75, 60, 8, 2, 1, 191, 167, 4, 75, 60, 8, - 6, 1, 191, 167, 4, 219, 89, 60, 8, 2, 1, 191, 167, 4, 219, 89, 60, 8, 2, - 1, 230, 84, 4, 219, 89, 60, 8, 2, 1, 200, 40, 4, 236, 253, 8, 2, 1, 193, - 222, 4, 206, 184, 56, 8, 2, 1, 192, 160, 4, 206, 184, 56, 8, 2, 1, 41, 4, - 50, 134, 206, 183, 8, 2, 1, 177, 206, 4, 4, 75, 56, 8, 2, 1, 177, 206, 4, - 4, 236, 250, 105, 8, 2, 1, 177, 206, 4, 4, 136, 105, 8, 6, 1, 203, 122, - 206, 3, 8, 2, 1, 237, 61, 8, 6, 1, 41, 4, 75, 60, 8, 2, 1, 41, 4, 75, 60, - 8, 6, 1, 41, 4, 228, 219, 56, 8, 2, 1, 41, 4, 228, 219, 56, 8, 6, 1, 41, - 4, 242, 210, 24, 251, 250, 8, 2, 1, 41, 4, 242, 210, 24, 251, 250, 8, 6, - 1, 41, 4, 242, 210, 24, 230, 176, 8, 2, 1, 41, 4, 242, 210, 24, 230, 176, - 8, 6, 1, 41, 4, 242, 210, 24, 228, 219, 56, 8, 2, 1, 41, 4, 242, 210, 24, - 228, 219, 56, 8, 6, 1, 41, 4, 242, 210, 24, 198, 147, 8, 2, 1, 41, 4, - 242, 210, 24, 198, 147, 8, 6, 1, 41, 4, 242, 210, 24, 75, 60, 8, 2, 1, - 41, 4, 242, 210, 24, 75, 60, 8, 6, 1, 41, 4, 247, 245, 24, 251, 250, 8, - 2, 1, 41, 4, 247, 245, 24, 251, 250, 8, 6, 1, 41, 4, 247, 245, 24, 230, - 176, 8, 2, 1, 41, 4, 247, 245, 24, 230, 176, 8, 6, 1, 41, 4, 247, 245, - 24, 228, 219, 56, 8, 2, 1, 41, 4, 247, 245, 24, 228, 219, 56, 8, 6, 1, - 41, 4, 247, 245, 24, 198, 147, 8, 2, 1, 41, 4, 247, 245, 24, 198, 147, 8, - 6, 1, 41, 4, 247, 245, 24, 75, 60, 8, 2, 1, 41, 4, 247, 245, 24, 75, 60, - 8, 6, 1, 234, 227, 4, 75, 60, 8, 2, 1, 234, 227, 4, 75, 60, 8, 6, 1, 234, - 227, 4, 228, 219, 56, 8, 2, 1, 234, 227, 4, 228, 219, 56, 8, 6, 1, 234, - 227, 4, 198, 147, 8, 2, 1, 234, 227, 4, 198, 147, 8, 6, 1, 234, 227, 4, - 242, 210, 24, 251, 250, 8, 2, 1, 234, 227, 4, 242, 210, 24, 251, 250, 8, - 6, 1, 234, 227, 4, 242, 210, 24, 230, 176, 8, 2, 1, 234, 227, 4, 242, - 210, 24, 230, 176, 8, 6, 1, 234, 227, 4, 242, 210, 24, 228, 219, 56, 8, - 2, 1, 234, 227, 4, 242, 210, 24, 228, 219, 56, 8, 6, 1, 234, 227, 4, 242, - 210, 24, 198, 147, 8, 2, 1, 234, 227, 4, 242, 210, 24, 198, 147, 8, 6, 1, - 234, 227, 4, 242, 210, 24, 75, 60, 8, 2, 1, 234, 227, 4, 242, 210, 24, - 75, 60, 8, 6, 1, 228, 44, 4, 228, 219, 56, 8, 2, 1, 228, 44, 4, 228, 219, - 56, 8, 6, 1, 228, 44, 4, 75, 60, 8, 2, 1, 228, 44, 4, 75, 60, 8, 6, 1, - 186, 4, 75, 60, 8, 2, 1, 186, 4, 75, 60, 8, 6, 1, 186, 4, 228, 219, 56, - 8, 2, 1, 186, 4, 228, 219, 56, 8, 6, 1, 186, 4, 242, 210, 24, 251, 250, - 8, 2, 1, 186, 4, 242, 210, 24, 251, 250, 8, 6, 1, 186, 4, 242, 210, 24, - 230, 176, 8, 2, 1, 186, 4, 242, 210, 24, 230, 176, 8, 6, 1, 186, 4, 242, - 210, 24, 228, 219, 56, 8, 2, 1, 186, 4, 242, 210, 24, 228, 219, 56, 8, 6, - 1, 186, 4, 242, 210, 24, 198, 147, 8, 2, 1, 186, 4, 242, 210, 24, 198, - 147, 8, 6, 1, 186, 4, 242, 210, 24, 75, 60, 8, 2, 1, 186, 4, 242, 210, - 24, 75, 60, 8, 6, 1, 186, 4, 228, 157, 24, 251, 250, 8, 2, 1, 186, 4, - 228, 157, 24, 251, 250, 8, 6, 1, 186, 4, 228, 157, 24, 230, 176, 8, 2, 1, - 186, 4, 228, 157, 24, 230, 176, 8, 6, 1, 186, 4, 228, 157, 24, 228, 219, - 56, 8, 2, 1, 186, 4, 228, 157, 24, 228, 219, 56, 8, 6, 1, 186, 4, 228, - 157, 24, 198, 147, 8, 2, 1, 186, 4, 228, 157, 24, 198, 147, 8, 6, 1, 186, - 4, 228, 157, 24, 75, 60, 8, 2, 1, 186, 4, 228, 157, 24, 75, 60, 8, 6, 1, - 126, 4, 75, 60, 8, 2, 1, 126, 4, 75, 60, 8, 6, 1, 126, 4, 228, 219, 56, - 8, 2, 1, 126, 4, 228, 219, 56, 8, 6, 1, 126, 4, 228, 157, 24, 251, 250, - 8, 2, 1, 126, 4, 228, 157, 24, 251, 250, 8, 6, 1, 126, 4, 228, 157, 24, - 230, 176, 8, 2, 1, 126, 4, 228, 157, 24, 230, 176, 8, 6, 1, 126, 4, 228, - 157, 24, 228, 219, 56, 8, 2, 1, 126, 4, 228, 157, 24, 228, 219, 56, 8, 6, - 1, 126, 4, 228, 157, 24, 198, 147, 8, 2, 1, 126, 4, 228, 157, 24, 198, - 147, 8, 6, 1, 126, 4, 228, 157, 24, 75, 60, 8, 2, 1, 126, 4, 228, 157, - 24, 75, 60, 8, 6, 1, 192, 160, 4, 230, 176, 8, 2, 1, 192, 160, 4, 230, - 176, 8, 6, 1, 192, 160, 4, 75, 60, 8, 2, 1, 192, 160, 4, 75, 60, 8, 6, 1, - 192, 160, 4, 228, 219, 56, 8, 2, 1, 192, 160, 4, 228, 219, 56, 8, 6, 1, - 192, 160, 4, 198, 147, 8, 2, 1, 192, 160, 4, 198, 147, 8, 6, 1, 216, 65, - 219, 50, 8, 2, 1, 216, 65, 219, 50, 8, 6, 1, 216, 65, 196, 8, 8, 2, 1, - 216, 65, 196, 8, 8, 6, 1, 192, 160, 4, 218, 236, 8, 2, 1, 192, 160, 4, - 218, 236, 35, 2, 1, 251, 110, 4, 208, 162, 35, 2, 1, 251, 110, 4, 237, - 167, 35, 2, 1, 251, 110, 4, 208, 163, 24, 195, 166, 35, 2, 1, 251, 110, - 4, 237, 168, 24, 195, 166, 35, 2, 1, 251, 110, 4, 208, 163, 24, 210, 233, - 35, 2, 1, 251, 110, 4, 237, 168, 24, 210, 233, 35, 2, 1, 251, 110, 4, - 208, 163, 24, 209, 251, 35, 2, 1, 251, 110, 4, 237, 168, 24, 209, 251, - 35, 6, 1, 251, 110, 4, 208, 162, 35, 6, 1, 251, 110, 4, 237, 167, 35, 6, - 1, 251, 110, 4, 208, 163, 24, 195, 166, 35, 6, 1, 251, 110, 4, 237, 168, - 24, 195, 166, 35, 6, 1, 251, 110, 4, 208, 163, 24, 210, 233, 35, 6, 1, - 251, 110, 4, 237, 168, 24, 210, 233, 35, 6, 1, 251, 110, 4, 208, 163, 24, - 209, 251, 35, 6, 1, 251, 110, 4, 237, 168, 24, 209, 251, 35, 2, 1, 234, - 6, 4, 208, 162, 35, 2, 1, 234, 6, 4, 237, 167, 35, 2, 1, 234, 6, 4, 208, - 163, 24, 195, 166, 35, 2, 1, 234, 6, 4, 237, 168, 24, 195, 166, 35, 2, 1, - 234, 6, 4, 208, 163, 24, 210, 233, 35, 2, 1, 234, 6, 4, 237, 168, 24, - 210, 233, 35, 6, 1, 234, 6, 4, 208, 162, 35, 6, 1, 234, 6, 4, 237, 167, - 35, 6, 1, 234, 6, 4, 208, 163, 24, 195, 166, 35, 6, 1, 234, 6, 4, 237, - 168, 24, 195, 166, 35, 6, 1, 234, 6, 4, 208, 163, 24, 210, 233, 35, 6, 1, - 234, 6, 4, 237, 168, 24, 210, 233, 35, 2, 1, 233, 212, 4, 208, 162, 35, - 2, 1, 233, 212, 4, 237, 167, 35, 2, 1, 233, 212, 4, 208, 163, 24, 195, - 166, 35, 2, 1, 233, 212, 4, 237, 168, 24, 195, 166, 35, 2, 1, 233, 212, - 4, 208, 163, 24, 210, 233, 35, 2, 1, 233, 212, 4, 237, 168, 24, 210, 233, - 35, 2, 1, 233, 212, 4, 208, 163, 24, 209, 251, 35, 2, 1, 233, 212, 4, - 237, 168, 24, 209, 251, 35, 6, 1, 233, 212, 4, 208, 162, 35, 6, 1, 233, - 212, 4, 237, 167, 35, 6, 1, 233, 212, 4, 208, 163, 24, 195, 166, 35, 6, - 1, 233, 212, 4, 237, 168, 24, 195, 166, 35, 6, 1, 233, 212, 4, 208, 163, - 24, 210, 233, 35, 6, 1, 233, 212, 4, 237, 168, 24, 210, 233, 35, 6, 1, - 233, 212, 4, 208, 163, 24, 209, 251, 35, 6, 1, 233, 212, 4, 237, 168, 24, - 209, 251, 35, 2, 1, 223, 56, 4, 208, 162, 35, 2, 1, 223, 56, 4, 237, 167, - 35, 2, 1, 223, 56, 4, 208, 163, 24, 195, 166, 35, 2, 1, 223, 56, 4, 237, - 168, 24, 195, 166, 35, 2, 1, 223, 56, 4, 208, 163, 24, 210, 233, 35, 2, - 1, 223, 56, 4, 237, 168, 24, 210, 233, 35, 2, 1, 223, 56, 4, 208, 163, - 24, 209, 251, 35, 2, 1, 223, 56, 4, 237, 168, 24, 209, 251, 35, 6, 1, - 223, 56, 4, 208, 162, 35, 6, 1, 223, 56, 4, 237, 167, 35, 6, 1, 223, 56, - 4, 208, 163, 24, 195, 166, 35, 6, 1, 223, 56, 4, 237, 168, 24, 195, 166, - 35, 6, 1, 223, 56, 4, 208, 163, 24, 210, 233, 35, 6, 1, 223, 56, 4, 237, - 168, 24, 210, 233, 35, 6, 1, 223, 56, 4, 208, 163, 24, 209, 251, 35, 6, - 1, 223, 56, 4, 237, 168, 24, 209, 251, 35, 2, 1, 211, 97, 4, 208, 162, - 35, 2, 1, 211, 97, 4, 237, 167, 35, 2, 1, 211, 97, 4, 208, 163, 24, 195, - 166, 35, 2, 1, 211, 97, 4, 237, 168, 24, 195, 166, 35, 2, 1, 211, 97, 4, - 208, 163, 24, 210, 233, 35, 2, 1, 211, 97, 4, 237, 168, 24, 210, 233, 35, - 6, 1, 211, 97, 4, 208, 162, 35, 6, 1, 211, 97, 4, 237, 167, 35, 6, 1, - 211, 97, 4, 208, 163, 24, 195, 166, 35, 6, 1, 211, 97, 4, 237, 168, 24, - 195, 166, 35, 6, 1, 211, 97, 4, 208, 163, 24, 210, 233, 35, 6, 1, 211, - 97, 4, 237, 168, 24, 210, 233, 35, 2, 1, 196, 67, 4, 208, 162, 35, 2, 1, - 196, 67, 4, 237, 167, 35, 2, 1, 196, 67, 4, 208, 163, 24, 195, 166, 35, - 2, 1, 196, 67, 4, 237, 168, 24, 195, 166, 35, 2, 1, 196, 67, 4, 208, 163, - 24, 210, 233, 35, 2, 1, 196, 67, 4, 237, 168, 24, 210, 233, 35, 2, 1, - 196, 67, 4, 208, 163, 24, 209, 251, 35, 2, 1, 196, 67, 4, 237, 168, 24, - 209, 251, 35, 6, 1, 196, 67, 4, 237, 167, 35, 6, 1, 196, 67, 4, 237, 168, - 24, 195, 166, 35, 6, 1, 196, 67, 4, 237, 168, 24, 210, 233, 35, 6, 1, - 196, 67, 4, 237, 168, 24, 209, 251, 35, 2, 1, 211, 100, 4, 208, 162, 35, - 2, 1, 211, 100, 4, 237, 167, 35, 2, 1, 211, 100, 4, 208, 163, 24, 195, - 166, 35, 2, 1, 211, 100, 4, 237, 168, 24, 195, 166, 35, 2, 1, 211, 100, - 4, 208, 163, 24, 210, 233, 35, 2, 1, 211, 100, 4, 237, 168, 24, 210, 233, - 35, 2, 1, 211, 100, 4, 208, 163, 24, 209, 251, 35, 2, 1, 211, 100, 4, - 237, 168, 24, 209, 251, 35, 6, 1, 211, 100, 4, 208, 162, 35, 6, 1, 211, - 100, 4, 237, 167, 35, 6, 1, 211, 100, 4, 208, 163, 24, 195, 166, 35, 6, - 1, 211, 100, 4, 237, 168, 24, 195, 166, 35, 6, 1, 211, 100, 4, 208, 163, - 24, 210, 233, 35, 6, 1, 211, 100, 4, 237, 168, 24, 210, 233, 35, 6, 1, - 211, 100, 4, 208, 163, 24, 209, 251, 35, 6, 1, 211, 100, 4, 237, 168, 24, - 209, 251, 35, 2, 1, 251, 110, 4, 195, 166, 35, 2, 1, 251, 110, 4, 210, - 233, 35, 2, 1, 234, 6, 4, 195, 166, 35, 2, 1, 234, 6, 4, 210, 233, 35, 2, - 1, 233, 212, 4, 195, 166, 35, 2, 1, 233, 212, 4, 210, 233, 35, 2, 1, 223, - 56, 4, 195, 166, 35, 2, 1, 223, 56, 4, 210, 233, 35, 2, 1, 211, 97, 4, - 195, 166, 35, 2, 1, 211, 97, 4, 210, 233, 35, 2, 1, 196, 67, 4, 195, 166, - 35, 2, 1, 196, 67, 4, 210, 233, 35, 2, 1, 211, 100, 4, 195, 166, 35, 2, - 1, 211, 100, 4, 210, 233, 35, 2, 1, 251, 110, 4, 208, 163, 24, 191, 233, - 35, 2, 1, 251, 110, 4, 237, 168, 24, 191, 233, 35, 2, 1, 251, 110, 4, - 208, 163, 24, 195, 167, 24, 191, 233, 35, 2, 1, 251, 110, 4, 237, 168, - 24, 195, 167, 24, 191, 233, 35, 2, 1, 251, 110, 4, 208, 163, 24, 210, - 234, 24, 191, 233, 35, 2, 1, 251, 110, 4, 237, 168, 24, 210, 234, 24, - 191, 233, 35, 2, 1, 251, 110, 4, 208, 163, 24, 209, 252, 24, 191, 233, - 35, 2, 1, 251, 110, 4, 237, 168, 24, 209, 252, 24, 191, 233, 35, 6, 1, - 251, 110, 4, 208, 163, 24, 208, 177, 35, 6, 1, 251, 110, 4, 237, 168, 24, - 208, 177, 35, 6, 1, 251, 110, 4, 208, 163, 24, 195, 167, 24, 208, 177, - 35, 6, 1, 251, 110, 4, 237, 168, 24, 195, 167, 24, 208, 177, 35, 6, 1, - 251, 110, 4, 208, 163, 24, 210, 234, 24, 208, 177, 35, 6, 1, 251, 110, 4, - 237, 168, 24, 210, 234, 24, 208, 177, 35, 6, 1, 251, 110, 4, 208, 163, - 24, 209, 252, 24, 208, 177, 35, 6, 1, 251, 110, 4, 237, 168, 24, 209, - 252, 24, 208, 177, 35, 2, 1, 233, 212, 4, 208, 163, 24, 191, 233, 35, 2, - 1, 233, 212, 4, 237, 168, 24, 191, 233, 35, 2, 1, 233, 212, 4, 208, 163, - 24, 195, 167, 24, 191, 233, 35, 2, 1, 233, 212, 4, 237, 168, 24, 195, - 167, 24, 191, 233, 35, 2, 1, 233, 212, 4, 208, 163, 24, 210, 234, 24, - 191, 233, 35, 2, 1, 233, 212, 4, 237, 168, 24, 210, 234, 24, 191, 233, - 35, 2, 1, 233, 212, 4, 208, 163, 24, 209, 252, 24, 191, 233, 35, 2, 1, - 233, 212, 4, 237, 168, 24, 209, 252, 24, 191, 233, 35, 6, 1, 233, 212, 4, - 208, 163, 24, 208, 177, 35, 6, 1, 233, 212, 4, 237, 168, 24, 208, 177, - 35, 6, 1, 233, 212, 4, 208, 163, 24, 195, 167, 24, 208, 177, 35, 6, 1, - 233, 212, 4, 237, 168, 24, 195, 167, 24, 208, 177, 35, 6, 1, 233, 212, 4, - 208, 163, 24, 210, 234, 24, 208, 177, 35, 6, 1, 233, 212, 4, 237, 168, - 24, 210, 234, 24, 208, 177, 35, 6, 1, 233, 212, 4, 208, 163, 24, 209, - 252, 24, 208, 177, 35, 6, 1, 233, 212, 4, 237, 168, 24, 209, 252, 24, - 208, 177, 35, 2, 1, 211, 100, 4, 208, 163, 24, 191, 233, 35, 2, 1, 211, - 100, 4, 237, 168, 24, 191, 233, 35, 2, 1, 211, 100, 4, 208, 163, 24, 195, - 167, 24, 191, 233, 35, 2, 1, 211, 100, 4, 237, 168, 24, 195, 167, 24, - 191, 233, 35, 2, 1, 211, 100, 4, 208, 163, 24, 210, 234, 24, 191, 233, - 35, 2, 1, 211, 100, 4, 237, 168, 24, 210, 234, 24, 191, 233, 35, 2, 1, - 211, 100, 4, 208, 163, 24, 209, 252, 24, 191, 233, 35, 2, 1, 211, 100, 4, - 237, 168, 24, 209, 252, 24, 191, 233, 35, 6, 1, 211, 100, 4, 208, 163, - 24, 208, 177, 35, 6, 1, 211, 100, 4, 237, 168, 24, 208, 177, 35, 6, 1, - 211, 100, 4, 208, 163, 24, 195, 167, 24, 208, 177, 35, 6, 1, 211, 100, 4, - 237, 168, 24, 195, 167, 24, 208, 177, 35, 6, 1, 211, 100, 4, 208, 163, - 24, 210, 234, 24, 208, 177, 35, 6, 1, 211, 100, 4, 237, 168, 24, 210, - 234, 24, 208, 177, 35, 6, 1, 211, 100, 4, 208, 163, 24, 209, 252, 24, - 208, 177, 35, 6, 1, 211, 100, 4, 237, 168, 24, 209, 252, 24, 208, 177, - 35, 2, 1, 251, 110, 4, 194, 251, 35, 2, 1, 251, 110, 4, 217, 125, 35, 2, - 1, 251, 110, 4, 195, 167, 24, 191, 233, 35, 2, 1, 251, 110, 4, 191, 233, - 35, 2, 1, 251, 110, 4, 210, 234, 24, 191, 233, 35, 2, 1, 251, 110, 4, - 209, 251, 35, 2, 1, 251, 110, 4, 209, 252, 24, 191, 233, 35, 6, 1, 251, - 110, 4, 194, 251, 35, 6, 1, 251, 110, 4, 217, 125, 35, 6, 1, 251, 110, 4, - 195, 166, 35, 6, 1, 251, 110, 4, 210, 233, 35, 6, 1, 251, 110, 4, 208, - 177, 35, 221, 6, 35, 208, 177, 35, 208, 162, 35, 209, 251, 35, 236, 247, - 24, 209, 251, 35, 2, 1, 233, 212, 4, 195, 167, 24, 191, 233, 35, 2, 1, - 233, 212, 4, 191, 233, 35, 2, 1, 233, 212, 4, 210, 234, 24, 191, 233, 35, - 2, 1, 233, 212, 4, 209, 251, 35, 2, 1, 233, 212, 4, 209, 252, 24, 191, - 233, 35, 6, 1, 234, 6, 4, 195, 166, 35, 6, 1, 234, 6, 4, 210, 233, 35, 6, - 1, 233, 212, 4, 195, 166, 35, 6, 1, 233, 212, 4, 210, 233, 35, 6, 1, 233, - 212, 4, 208, 177, 35, 208, 163, 24, 195, 166, 35, 208, 163, 24, 210, 233, - 35, 208, 163, 24, 209, 251, 35, 2, 1, 223, 56, 4, 194, 251, 35, 2, 1, - 223, 56, 4, 217, 125, 35, 2, 1, 223, 56, 4, 236, 247, 24, 195, 166, 35, - 2, 1, 223, 56, 4, 236, 247, 24, 210, 233, 35, 2, 1, 223, 56, 4, 209, 251, - 35, 2, 1, 223, 56, 4, 236, 247, 24, 209, 251, 35, 6, 1, 223, 56, 4, 194, - 251, 35, 6, 1, 223, 56, 4, 217, 125, 35, 6, 1, 223, 56, 4, 195, 166, 35, - 6, 1, 223, 56, 4, 210, 233, 35, 237, 168, 24, 195, 166, 35, 237, 168, 24, - 210, 233, 35, 237, 168, 24, 209, 251, 35, 2, 1, 196, 67, 4, 194, 251, 35, - 2, 1, 196, 67, 4, 217, 125, 35, 2, 1, 196, 67, 4, 236, 247, 24, 195, 166, - 35, 2, 1, 196, 67, 4, 236, 247, 24, 210, 233, 35, 2, 1, 206, 255, 4, 208, - 162, 35, 2, 1, 206, 255, 4, 237, 167, 35, 2, 1, 196, 67, 4, 209, 251, 35, - 2, 1, 196, 67, 4, 236, 247, 24, 209, 251, 35, 6, 1, 196, 67, 4, 194, 251, - 35, 6, 1, 196, 67, 4, 217, 125, 35, 6, 1, 196, 67, 4, 195, 166, 35, 6, 1, - 196, 67, 4, 210, 233, 35, 6, 1, 206, 255, 4, 237, 167, 35, 236, 247, 24, - 195, 166, 35, 236, 247, 24, 210, 233, 35, 195, 166, 35, 2, 1, 211, 100, - 4, 195, 167, 24, 191, 233, 35, 2, 1, 211, 100, 4, 191, 233, 35, 2, 1, - 211, 100, 4, 210, 234, 24, 191, 233, 35, 2, 1, 211, 100, 4, 209, 251, 35, - 2, 1, 211, 100, 4, 209, 252, 24, 191, 233, 35, 6, 1, 211, 97, 4, 195, - 166, 35, 6, 1, 211, 97, 4, 210, 233, 35, 6, 1, 211, 100, 4, 195, 166, 35, - 6, 1, 211, 100, 4, 210, 233, 35, 6, 1, 211, 100, 4, 208, 177, 35, 210, - 233, 35, 237, 167, 234, 62, 208, 24, 234, 73, 208, 24, 234, 62, 201, 242, - 234, 73, 201, 242, 198, 214, 201, 242, 232, 88, 201, 242, 202, 129, 201, - 242, 232, 228, 201, 242, 208, 145, 201, 242, 198, 255, 201, 242, 230, 46, - 201, 242, 191, 78, 193, 73, 201, 242, 191, 78, 193, 73, 213, 16, 191, 78, - 193, 73, 222, 169, 219, 191, 77, 206, 194, 77, 228, 58, 213, 17, 228, 58, - 232, 228, 237, 170, 234, 62, 237, 170, 234, 73, 237, 170, 228, 209, 164, - 54, 81, 219, 88, 54, 131, 219, 88, 45, 202, 165, 207, 247, 77, 50, 202, - 165, 207, 247, 77, 202, 165, 218, 218, 207, 247, 77, 202, 165, 229, 100, - 207, 247, 77, 45, 54, 207, 247, 77, 50, 54, 207, 247, 77, 54, 218, 218, - 207, 247, 77, 54, 229, 100, 207, 247, 77, 237, 223, 54, 237, 223, 247, - 200, 197, 234, 247, 200, 91, 75, 219, 212, 103, 75, 219, 212, 228, 209, - 234, 78, 228, 56, 209, 54, 219, 89, 204, 5, 210, 118, 204, 5, 219, 191, - 234, 71, 206, 194, 234, 71, 209, 27, 236, 187, 232, 105, 219, 191, 210, - 242, 206, 194, 210, 242, 214, 201, 213, 24, 201, 242, 210, 5, 216, 32, - 57, 210, 5, 199, 91, 198, 225, 57, 208, 208, 54, 208, 208, 197, 221, 208, - 208, 207, 13, 208, 208, 207, 13, 54, 208, 208, 207, 13, 197, 221, 208, - 208, 247, 48, 202, 165, 219, 195, 251, 65, 207, 247, 77, 202, 165, 206, - 198, 251, 65, 207, 247, 77, 207, 78, 77, 54, 233, 175, 77, 223, 74, 210, - 244, 196, 96, 246, 192, 198, 173, 247, 49, 223, 91, 209, 54, 250, 141, - 228, 59, 247, 200, 232, 80, 202, 92, 45, 51, 248, 6, 4, 208, 2, 50, 51, - 248, 6, 4, 208, 2, 54, 208, 8, 77, 208, 8, 233, 175, 77, 233, 175, 208, - 8, 77, 198, 123, 3, 233, 213, 207, 13, 209, 133, 57, 62, 117, 247, 200, - 62, 96, 247, 200, 131, 250, 143, 207, 13, 204, 20, 242, 172, 196, 73, - 103, 250, 142, 251, 127, 195, 81, 242, 24, 216, 18, 57, 200, 125, 237, - 170, 223, 65, 196, 96, 232, 147, 208, 145, 77, 115, 75, 208, 144, 208, - 20, 208, 208, 232, 90, 75, 208, 144, 232, 185, 75, 208, 144, 103, 75, - 208, 144, 232, 90, 75, 77, 235, 94, 238, 170, 197, 233, 81, 232, 90, 236, - 94, 216, 194, 13, 201, 242, 193, 23, 222, 169, 232, 40, 250, 250, 223, - 63, 198, 139, 223, 63, 204, 5, 223, 63, 209, 73, 219, 191, 223, 31, 206, - 194, 223, 31, 232, 197, 201, 9, 223, 31, 209, 27, 236, 187, 223, 31, 223, - 104, 200, 71, 200, 143, 251, 253, 200, 71, 200, 143, 223, 104, 9, 232, - 107, 203, 128, 251, 253, 9, 232, 107, 203, 128, 214, 194, 17, 203, 129, - 213, 20, 17, 203, 129, 200, 177, 191, 77, 200, 177, 8, 2, 1, 70, 200, - 177, 137, 200, 177, 153, 200, 177, 173, 200, 177, 181, 200, 177, 176, - 200, 177, 184, 200, 177, 107, 57, 200, 177, 216, 17, 200, 177, 234, 1, - 57, 200, 177, 45, 210, 103, 200, 177, 50, 210, 103, 200, 177, 8, 2, 1, - 215, 47, 200, 225, 191, 77, 200, 225, 108, 200, 225, 109, 200, 225, 139, - 200, 225, 137, 200, 225, 153, 200, 225, 173, 200, 225, 181, 200, 225, - 176, 200, 225, 184, 200, 225, 107, 57, 200, 225, 216, 17, 200, 225, 234, - 1, 57, 200, 225, 45, 210, 103, 200, 225, 50, 210, 103, 8, 200, 225, 2, 1, - 65, 8, 200, 225, 2, 1, 73, 8, 200, 225, 2, 1, 74, 8, 200, 225, 2, 1, 192, - 235, 8, 200, 225, 2, 1, 205, 81, 8, 200, 225, 2, 1, 230, 83, 8, 200, 225, - 2, 1, 222, 125, 8, 200, 225, 2, 1, 170, 8, 200, 225, 2, 1, 218, 147, 8, - 200, 225, 2, 1, 215, 47, 8, 200, 225, 2, 1, 210, 226, 8, 200, 225, 2, 1, - 206, 3, 8, 200, 225, 2, 1, 200, 39, 233, 192, 57, 242, 36, 57, 238, 153, - 57, 232, 68, 232, 73, 57, 219, 67, 57, 216, 33, 57, 214, 220, 57, 209, - 236, 57, 206, 31, 57, 193, 31, 57, 214, 66, 203, 94, 57, 236, 104, 57, - 233, 193, 57, 221, 111, 57, 197, 77, 57, 235, 72, 57, 231, 101, 210, 18, - 57, 209, 233, 57, 230, 141, 57, 250, 103, 57, 228, 135, 57, 246, 245, 57, - 219, 57, 198, 28, 57, 201, 221, 57, 199, 88, 57, 223, 119, 206, 31, 57, - 197, 56, 219, 67, 57, 213, 6, 87, 57, 217, 68, 57, 206, 54, 57, 219, 241, - 57, 248, 99, 57, 202, 17, 57, 33, 45, 229, 236, 56, 33, 50, 229, 236, 56, - 33, 177, 81, 219, 89, 210, 245, 33, 203, 35, 81, 219, 89, 210, 245, 33, - 251, 34, 63, 56, 33, 242, 173, 63, 56, 33, 45, 63, 56, 33, 50, 63, 56, - 33, 206, 184, 210, 245, 33, 242, 173, 206, 184, 210, 245, 33, 251, 34, - 206, 184, 210, 245, 33, 115, 183, 56, 33, 232, 90, 183, 56, 33, 234, 57, - 242, 218, 33, 234, 57, 201, 185, 33, 234, 57, 236, 243, 33, 234, 57, 242, - 219, 249, 91, 33, 45, 50, 63, 56, 33, 234, 57, 205, 71, 33, 234, 57, 221, - 193, 33, 234, 57, 196, 64, 209, 51, 197, 237, 33, 207, 14, 202, 19, 210, - 245, 33, 54, 81, 201, 23, 210, 245, 33, 251, 44, 113, 33, 197, 221, 196, - 98, 33, 193, 76, 247, 237, 56, 33, 117, 63, 210, 245, 33, 177, 54, 202, - 19, 210, 245, 33, 96, 229, 236, 4, 178, 235, 74, 33, 117, 229, 236, 4, - 178, 235, 74, 33, 45, 63, 60, 33, 50, 63, 60, 33, 250, 144, 56, 252, 3, - 211, 134, 251, 242, 118, 199, 29, 200, 235, 235, 85, 6, 247, 145, 237, - 80, 246, 235, 246, 230, 219, 89, 113, 247, 50, 211, 134, 247, 104, 196, - 108, 233, 194, 238, 247, 205, 67, 237, 80, 233, 50, 27, 2, 232, 14, 27, - 6, 230, 83, 248, 89, 6, 230, 83, 235, 85, 6, 230, 83, 209, 95, 238, 247, - 209, 95, 238, 248, 138, 103, 209, 176, 27, 6, 70, 248, 89, 6, 70, 27, 6, - 170, 27, 2, 170, 220, 119, 78, 249, 38, 113, 235, 85, 6, 215, 47, 212, - 119, 57, 202, 0, 207, 90, 238, 214, 27, 6, 210, 226, 235, 85, 6, 210, - 226, 235, 85, 6, 208, 97, 27, 6, 148, 248, 89, 6, 148, 235, 85, 6, 148, - 208, 216, 199, 203, 207, 26, 203, 252, 77, 199, 102, 57, 198, 18, 87, 57, - 195, 133, 235, 85, 6, 191, 166, 211, 8, 57, 211, 123, 57, 223, 65, 211, - 123, 57, 248, 89, 6, 191, 166, 152, 35, 2, 1, 223, 55, 221, 234, 57, 251, - 59, 57, 27, 6, 250, 70, 248, 89, 6, 247, 145, 233, 218, 113, 27, 2, 73, - 27, 6, 73, 27, 6, 233, 134, 152, 6, 233, 134, 27, 6, 218, 147, 27, 2, 74, - 130, 113, 248, 165, 113, 231, 2, 113, 237, 207, 113, 223, 109, 201, 254, - 206, 117, 6, 208, 97, 233, 53, 57, 235, 85, 2, 209, 176, 235, 85, 2, 231, - 174, 235, 85, 6, 231, 174, 235, 85, 6, 209, 176, 235, 85, 215, 46, 200, - 196, 152, 49, 6, 232, 14, 152, 49, 6, 170, 207, 13, 49, 6, 170, 152, 49, - 6, 192, 159, 235, 85, 43, 6, 238, 80, 235, 85, 43, 2, 238, 80, 235, 85, - 43, 2, 73, 235, 85, 43, 2, 70, 235, 85, 43, 2, 223, 7, 208, 181, 219, 88, - 152, 251, 86, 210, 5, 57, 251, 159, 152, 2, 233, 134, 16, 39, 205, 146, - 201, 254, 193, 243, 232, 80, 91, 203, 238, 193, 243, 232, 80, 91, 213, - 154, 193, 243, 232, 80, 91, 199, 81, 193, 243, 232, 80, 91, 198, 251, - 193, 243, 232, 80, 103, 198, 248, 193, 243, 232, 80, 91, 232, 233, 193, - 243, 232, 80, 103, 232, 232, 193, 243, 232, 80, 115, 232, 232, 193, 243, - 232, 80, 232, 90, 232, 232, 193, 243, 232, 80, 91, 202, 119, 193, 243, - 232, 80, 232, 185, 202, 117, 193, 243, 232, 80, 91, 234, 116, 193, 243, - 232, 80, 115, 234, 114, 193, 243, 232, 80, 232, 185, 234, 114, 193, 243, - 232, 80, 203, 242, 234, 114, 232, 80, 212, 120, 108, 206, 131, 212, 121, - 108, 206, 131, 212, 121, 109, 206, 131, 212, 121, 139, 206, 131, 212, - 121, 137, 206, 131, 212, 121, 153, 206, 131, 212, 121, 173, 206, 131, - 212, 121, 181, 206, 131, 212, 121, 176, 206, 131, 212, 121, 184, 206, - 131, 212, 121, 199, 90, 206, 131, 212, 121, 234, 84, 206, 131, 212, 121, - 197, 33, 206, 131, 212, 121, 232, 230, 206, 131, 212, 121, 91, 228, 109, - 206, 131, 212, 121, 232, 185, 228, 109, 206, 131, 212, 121, 91, 188, 2, - 206, 131, 212, 121, 108, 2, 206, 131, 212, 121, 109, 2, 206, 131, 212, - 121, 139, 2, 206, 131, 212, 121, 137, 2, 206, 131, 212, 121, 153, 2, 206, - 131, 212, 121, 173, 2, 206, 131, 212, 121, 181, 2, 206, 131, 212, 121, - 176, 2, 206, 131, 212, 121, 184, 2, 206, 131, 212, 121, 199, 90, 2, 206, - 131, 212, 121, 234, 84, 2, 206, 131, 212, 121, 197, 33, 2, 206, 131, 212, - 121, 232, 230, 2, 206, 131, 212, 121, 91, 228, 109, 2, 206, 131, 212, - 121, 232, 185, 228, 109, 2, 206, 131, 212, 121, 91, 188, 206, 131, 212, - 121, 91, 198, 225, 247, 146, 238, 80, 206, 131, 212, 121, 232, 185, 188, - 206, 131, 212, 121, 199, 91, 188, 206, 131, 212, 121, 207, 13, 91, 228, - 109, 8, 2, 1, 207, 13, 247, 145, 206, 131, 212, 121, 202, 131, 219, 236, - 20, 206, 131, 212, 121, 232, 231, 234, 166, 20, 206, 131, 212, 121, 232, - 231, 188, 206, 131, 212, 121, 91, 228, 110, 188, 193, 243, 232, 80, 191, - 78, 198, 248, 152, 17, 109, 152, 17, 139, 117, 55, 196, 62, 55, 96, 55, - 235, 75, 55, 45, 50, 55, 132, 143, 55, 185, 193, 103, 55, 185, 234, 160, - 55, 201, 253, 234, 160, 55, 201, 253, 193, 103, 55, 117, 63, 4, 105, 96, - 63, 4, 105, 117, 193, 137, 55, 96, 193, 137, 55, 117, 103, 229, 201, 55, - 196, 62, 103, 229, 201, 55, 96, 103, 229, 201, 55, 235, 75, 103, 229, - 201, 55, 117, 63, 4, 199, 210, 96, 63, 4, 199, 210, 117, 63, 232, 60, - 164, 196, 62, 63, 232, 60, 164, 96, 63, 232, 60, 164, 235, 75, 63, 232, - 60, 164, 132, 143, 63, 4, 249, 24, 117, 63, 4, 106, 96, 63, 4, 106, 117, - 63, 4, 218, 236, 96, 63, 4, 218, 236, 45, 50, 193, 137, 55, 45, 50, 63, - 4, 105, 235, 75, 191, 21, 55, 196, 62, 63, 4, 198, 131, 219, 190, 196, - 62, 63, 4, 198, 131, 206, 192, 235, 75, 63, 4, 198, 131, 219, 190, 235, - 75, 63, 4, 198, 131, 206, 192, 96, 63, 4, 238, 211, 235, 74, 235, 75, 63, - 4, 238, 211, 219, 190, 251, 34, 198, 49, 204, 23, 55, 242, 173, 198, 49, - 204, 23, 55, 185, 193, 103, 63, 118, 177, 164, 117, 63, 118, 249, 38, - 138, 96, 63, 118, 164, 251, 34, 211, 66, 242, 219, 55, 242, 173, 211, 66, - 242, 219, 55, 117, 229, 236, 4, 178, 196, 61, 117, 229, 236, 4, 178, 235, - 74, 196, 62, 229, 236, 4, 178, 206, 192, 196, 62, 229, 236, 4, 178, 219, - 190, 96, 229, 236, 4, 178, 196, 61, 96, 229, 236, 4, 178, 235, 74, 235, - 75, 229, 236, 4, 178, 206, 192, 235, 75, 229, 236, 4, 178, 219, 190, 96, - 63, 138, 117, 55, 196, 62, 63, 117, 80, 235, 75, 55, 117, 63, 138, 96, - 55, 117, 210, 186, 250, 181, 196, 62, 210, 186, 250, 181, 96, 210, 186, - 250, 181, 235, 75, 210, 186, 250, 181, 117, 229, 236, 138, 96, 229, 235, - 96, 229, 236, 138, 117, 229, 235, 117, 54, 63, 4, 105, 45, 50, 54, 63, 4, - 105, 96, 54, 63, 4, 105, 117, 54, 55, 196, 62, 54, 55, 96, 54, 55, 235, - 75, 54, 55, 45, 50, 54, 55, 132, 143, 54, 55, 185, 193, 103, 54, 55, 185, - 234, 160, 54, 55, 201, 253, 234, 160, 54, 55, 201, 253, 193, 103, 54, 55, - 117, 197, 221, 55, 96, 197, 221, 55, 117, 201, 178, 55, 96, 201, 178, 55, - 196, 62, 63, 4, 54, 105, 235, 75, 63, 4, 54, 105, 117, 237, 169, 55, 196, - 62, 237, 169, 55, 96, 237, 169, 55, 235, 75, 237, 169, 55, 117, 63, 118, - 164, 96, 63, 118, 164, 117, 64, 55, 196, 62, 64, 55, 96, 64, 55, 235, 75, - 64, 55, 196, 62, 64, 63, 232, 60, 164, 196, 62, 64, 63, 211, 94, 210, 43, - 196, 62, 64, 63, 211, 94, 210, 44, 4, 228, 209, 164, 196, 62, 64, 63, - 211, 94, 210, 44, 4, 81, 164, 196, 62, 64, 54, 55, 196, 62, 64, 54, 63, - 211, 94, 210, 43, 96, 64, 63, 232, 60, 193, 164, 185, 193, 103, 63, 118, - 238, 210, 201, 253, 234, 160, 63, 118, 238, 210, 132, 143, 64, 55, 50, - 63, 4, 2, 242, 218, 235, 75, 63, 117, 80, 196, 62, 55, 115, 96, 250, 181, - 117, 63, 4, 81, 105, 96, 63, 4, 81, 105, 45, 50, 63, 4, 81, 105, 117, 63, - 4, 54, 81, 105, 96, 63, 4, 54, 81, 105, 45, 50, 63, 4, 54, 81, 105, 117, - 211, 63, 55, 96, 211, 63, 55, 45, 50, 211, 63, 55, 39, 251, 123, 242, 20, - 210, 95, 236, 227, 199, 19, 233, 170, 199, 19, 236, 119, 212, 255, 233, - 171, 234, 63, 203, 247, 223, 123, 214, 231, 234, 89, 211, 134, 212, 255, - 251, 82, 234, 89, 211, 134, 2, 234, 89, 211, 134, 238, 241, 250, 170, - 216, 171, 236, 119, 212, 255, 238, 243, 250, 170, 216, 171, 2, 238, 241, - 250, 170, 216, 171, 234, 53, 80, 208, 183, 215, 46, 208, 193, 215, 46, - 238, 218, 215, 46, 200, 196, 216, 18, 57, 216, 16, 57, 75, 209, 73, 236, - 155, 202, 92, 203, 248, 216, 17, 250, 144, 211, 55, 206, 184, 211, 55, - 247, 201, 211, 55, 51, 206, 123, 238, 144, 206, 123, 232, 83, 206, 123, - 208, 179, 159, 223, 111, 50, 251, 64, 251, 64, 216, 207, 251, 64, 201, - 220, 251, 64, 236, 158, 236, 119, 212, 255, 236, 162, 210, 109, 159, 212, - 255, 210, 109, 159, 219, 5, 251, 74, 219, 5, 211, 45, 223, 71, 196, 88, - 223, 85, 54, 223, 85, 197, 221, 223, 85, 238, 235, 223, 85, 200, 166, - 223, 85, 195, 8, 223, 85, 242, 173, 223, 85, 242, 173, 238, 235, 223, 85, - 251, 34, 238, 235, 223, 85, 199, 18, 248, 209, 207, 121, 208, 180, 75, - 216, 17, 233, 178, 231, 107, 208, 180, 228, 224, 198, 148, 211, 55, 207, - 13, 198, 147, 223, 65, 219, 221, 206, 3, 202, 167, 193, 136, 193, 10, - 208, 193, 212, 255, 198, 147, 216, 18, 198, 147, 250, 136, 234, 3, 159, - 212, 255, 250, 136, 234, 3, 159, 250, 246, 234, 3, 159, 250, 246, 247, - 170, 212, 255, 251, 252, 234, 3, 159, 214, 91, 250, 246, 213, 8, 251, - 252, 234, 3, 159, 251, 114, 234, 3, 159, 212, 255, 251, 114, 234, 3, 159, - 251, 114, 234, 3, 211, 46, 234, 3, 159, 197, 221, 198, 147, 251, 124, - 234, 3, 159, 233, 250, 159, 231, 106, 233, 250, 159, 236, 228, 248, 159, - 250, 248, 199, 29, 219, 96, 231, 106, 234, 3, 159, 250, 246, 234, 3, 118, - 211, 46, 199, 29, 223, 150, 211, 134, 223, 150, 80, 211, 46, 250, 246, - 234, 3, 159, 242, 36, 234, 0, 234, 1, 242, 35, 206, 184, 223, 135, 234, - 3, 159, 206, 184, 234, 3, 159, 238, 203, 159, 233, 217, 233, 255, 159, - 201, 98, 234, 0, 237, 62, 234, 3, 159, 234, 3, 118, 247, 157, 237, 81, - 216, 207, 247, 156, 208, 6, 234, 3, 159, 212, 255, 234, 3, 159, 227, 244, - 159, 212, 255, 227, 244, 159, 201, 30, 233, 250, 159, 219, 156, 211, 46, - 234, 3, 159, 230, 170, 211, 46, 234, 3, 159, 219, 156, 138, 234, 3, 159, - 230, 170, 138, 234, 3, 159, 219, 156, 247, 170, 212, 255, 234, 3, 159, - 230, 170, 247, 170, 212, 255, 234, 3, 159, 215, 129, 219, 155, 215, 129, - 230, 169, 248, 159, 212, 255, 233, 250, 159, 212, 255, 219, 155, 212, - 255, 230, 169, 214, 91, 219, 156, 213, 8, 234, 3, 159, 214, 91, 230, 170, - 213, 8, 234, 3, 159, 219, 156, 211, 46, 233, 250, 159, 230, 170, 211, 46, - 233, 250, 159, 214, 91, 219, 156, 213, 8, 233, 250, 159, 214, 91, 230, - 170, 213, 8, 233, 250, 159, 219, 156, 211, 46, 230, 169, 230, 170, 211, - 46, 219, 155, 214, 91, 219, 156, 213, 8, 230, 169, 214, 91, 230, 170, - 213, 8, 219, 155, 208, 224, 200, 215, 208, 225, 211, 46, 234, 3, 159, - 200, 216, 211, 46, 234, 3, 159, 208, 225, 211, 46, 233, 250, 159, 200, - 216, 211, 46, 233, 250, 159, 236, 119, 212, 255, 208, 227, 236, 119, 212, - 255, 200, 217, 200, 224, 211, 134, 200, 176, 211, 134, 212, 255, 41, 200, - 224, 211, 134, 212, 255, 41, 200, 176, 211, 134, 200, 224, 80, 211, 46, - 234, 3, 159, 200, 176, 80, 211, 46, 234, 3, 159, 214, 91, 41, 200, 224, - 80, 213, 8, 234, 3, 159, 214, 91, 41, 200, 176, 80, 213, 8, 234, 3, 159, - 200, 224, 80, 4, 212, 255, 234, 3, 159, 200, 176, 80, 4, 212, 255, 234, - 3, 159, 215, 109, 215, 110, 215, 111, 215, 110, 196, 88, 51, 223, 150, - 211, 134, 51, 211, 36, 211, 134, 51, 223, 150, 80, 211, 46, 234, 3, 159, - 51, 211, 36, 80, 211, 46, 234, 3, 159, 51, 247, 63, 51, 238, 134, 47, - 209, 73, 47, 216, 17, 47, 198, 139, 47, 236, 155, 202, 92, 47, 75, 211, - 55, 47, 206, 184, 211, 55, 47, 250, 144, 211, 55, 47, 234, 0, 47, 237, - 170, 112, 209, 73, 112, 216, 17, 112, 198, 139, 112, 75, 211, 55, 50, - 199, 223, 45, 199, 223, 143, 199, 223, 132, 199, 223, 250, 147, 215, 240, - 197, 197, 232, 113, 197, 221, 81, 249, 38, 50, 197, 53, 54, 81, 249, 38, - 54, 50, 197, 53, 236, 119, 212, 255, 208, 172, 212, 255, 197, 197, 236, - 119, 212, 255, 232, 114, 214, 94, 54, 81, 249, 38, 54, 50, 197, 53, 208, - 225, 196, 101, 207, 60, 200, 216, 196, 101, 207, 60, 213, 5, 200, 239, - 211, 134, 238, 241, 250, 170, 213, 5, 200, 238, 213, 5, 200, 239, 80, - 211, 46, 234, 3, 159, 238, 241, 250, 170, 213, 5, 200, 239, 211, 46, 234, - 3, 159, 211, 36, 211, 134, 223, 150, 211, 134, 215, 116, 229, 157, 238, - 252, 217, 8, 223, 82, 192, 192, 214, 210, 213, 7, 50, 251, 65, 4, 250, - 222, 50, 197, 237, 215, 46, 219, 5, 251, 74, 215, 46, 219, 5, 211, 45, - 215, 46, 223, 71, 215, 46, 196, 88, 236, 244, 211, 55, 75, 211, 55, 201, - 98, 211, 55, 236, 155, 198, 139, 248, 15, 45, 213, 5, 233, 52, 204, 19, - 208, 193, 50, 213, 5, 233, 52, 204, 19, 208, 193, 45, 204, 19, 208, 193, - 50, 204, 19, 208, 193, 207, 13, 198, 148, 234, 0, 238, 124, 219, 5, 211, - 45, 238, 124, 219, 5, 251, 74, 54, 200, 223, 54, 200, 175, 54, 223, 71, - 54, 196, 88, 209, 107, 234, 3, 24, 210, 109, 159, 219, 156, 4, 236, 96, - 230, 170, 4, 236, 96, 195, 80, 215, 129, 219, 155, 195, 80, 215, 129, - 230, 169, 219, 156, 234, 3, 118, 211, 46, 230, 169, 230, 170, 234, 3, - 118, 211, 46, 219, 155, 234, 3, 118, 211, 46, 219, 155, 234, 3, 118, 211, - 46, 230, 169, 234, 3, 118, 211, 46, 208, 224, 234, 3, 118, 211, 46, 200, - 215, 236, 119, 212, 255, 208, 228, 211, 46, 234, 2, 236, 119, 212, 255, - 200, 218, 211, 46, 234, 2, 212, 255, 51, 223, 150, 80, 211, 46, 234, 3, - 159, 212, 255, 51, 211, 36, 80, 211, 46, 234, 3, 159, 51, 223, 150, 80, - 211, 46, 212, 255, 234, 3, 159, 51, 211, 36, 80, 211, 46, 212, 255, 234, - 3, 159, 219, 156, 247, 170, 212, 255, 233, 250, 159, 230, 170, 247, 170, - 212, 255, 233, 250, 159, 208, 225, 247, 170, 212, 255, 233, 250, 159, - 200, 216, 247, 170, 212, 255, 233, 250, 159, 212, 255, 213, 5, 200, 239, - 211, 134, 236, 119, 212, 255, 238, 243, 250, 170, 213, 5, 200, 238, 212, - 255, 213, 5, 200, 239, 80, 211, 46, 234, 3, 159, 236, 119, 212, 255, 238, - 243, 250, 170, 213, 5, 200, 239, 211, 46, 234, 2, 81, 234, 78, 216, 64, - 228, 209, 234, 78, 132, 50, 236, 250, 234, 78, 143, 50, 236, 250, 234, - 78, 234, 89, 80, 4, 177, 228, 209, 105, 234, 89, 80, 4, 81, 249, 38, 250, - 133, 234, 53, 80, 228, 209, 105, 2, 234, 89, 80, 4, 81, 249, 38, 250, - 133, 234, 53, 80, 228, 209, 105, 234, 89, 80, 4, 75, 56, 234, 89, 80, 4, - 210, 252, 2, 234, 89, 80, 4, 210, 252, 234, 89, 80, 4, 196, 99, 234, 89, - 80, 4, 103, 228, 209, 201, 10, 238, 241, 4, 177, 228, 209, 105, 238, 241, - 4, 81, 249, 38, 250, 133, 234, 53, 80, 228, 209, 105, 2, 238, 241, 4, 81, - 249, 38, 250, 133, 234, 53, 80, 228, 209, 105, 238, 241, 4, 210, 252, 2, - 238, 241, 4, 210, 252, 191, 167, 212, 253, 249, 81, 216, 170, 236, 245, - 57, 234, 92, 55, 228, 141, 132, 250, 185, 143, 250, 185, 208, 187, 209, - 239, 193, 133, 219, 88, 45, 246, 238, 50, 246, 238, 45, 232, 153, 50, - 232, 153, 248, 29, 50, 238, 172, 248, 29, 45, 238, 172, 198, 49, 50, 238, - 172, 198, 49, 45, 238, 172, 207, 13, 212, 255, 57, 51, 218, 210, 250, - 222, 205, 38, 205, 47, 199, 102, 207, 91, 209, 18, 223, 116, 195, 53, - 201, 185, 209, 100, 80, 223, 81, 57, 152, 212, 255, 57, 193, 143, 228, - 143, 198, 49, 45, 238, 210, 198, 49, 50, 238, 210, 248, 29, 45, 238, 210, - 248, 29, 50, 238, 210, 198, 49, 134, 223, 85, 248, 29, 134, 223, 85, 232, - 55, 202, 60, 132, 250, 186, 248, 160, 103, 228, 209, 249, 26, 211, 48, - 221, 197, 233, 246, 118, 199, 29, 187, 192, 236, 223, 135, 41, 207, 88, - 248, 14, 221, 195, 219, 195, 251, 65, 248, 5, 206, 198, 251, 65, 248, 5, - 233, 246, 118, 199, 29, 219, 200, 248, 171, 206, 183, 238, 91, 251, 124, - 250, 194, 200, 70, 198, 34, 206, 36, 236, 207, 211, 37, 239, 0, 199, 176, - 202, 76, 238, 199, 238, 198, 251, 9, 232, 38, 16, 228, 37, 251, 9, 232, - 38, 16, 201, 176, 208, 24, 251, 9, 232, 38, 16, 208, 25, 234, 2, 251, 9, - 232, 38, 16, 208, 25, 236, 162, 251, 9, 232, 38, 16, 208, 25, 236, 243, - 251, 9, 232, 38, 16, 208, 25, 222, 161, 251, 9, 232, 38, 16, 208, 25, - 242, 218, 251, 9, 232, 38, 16, 242, 219, 201, 66, 251, 9, 232, 38, 16, - 242, 219, 222, 161, 251, 9, 232, 38, 16, 202, 93, 164, 251, 9, 232, 38, - 16, 249, 92, 164, 251, 9, 232, 38, 16, 208, 25, 202, 92, 251, 9, 232, 38, - 16, 208, 25, 249, 91, 251, 9, 232, 38, 16, 208, 25, 219, 155, 251, 9, - 232, 38, 16, 208, 25, 230, 169, 251, 9, 232, 38, 16, 117, 195, 173, 251, - 9, 232, 38, 16, 96, 195, 173, 251, 9, 232, 38, 16, 208, 25, 117, 55, 251, - 9, 232, 38, 16, 208, 25, 96, 55, 251, 9, 232, 38, 16, 242, 219, 249, 91, - 251, 9, 232, 38, 16, 143, 199, 224, 196, 99, 251, 9, 232, 38, 16, 237, - 62, 201, 66, 251, 9, 232, 38, 16, 208, 25, 143, 247, 48, 251, 9, 232, 38, - 16, 208, 25, 237, 61, 251, 9, 232, 38, 16, 143, 199, 224, 222, 161, 251, - 9, 232, 38, 16, 196, 62, 195, 173, 251, 9, 232, 38, 16, 208, 25, 196, 62, - 55, 251, 9, 232, 38, 16, 132, 199, 224, 210, 252, 251, 9, 232, 38, 16, - 237, 74, 201, 66, 251, 9, 232, 38, 16, 208, 25, 132, 247, 48, 251, 9, - 232, 38, 16, 208, 25, 237, 73, 251, 9, 232, 38, 16, 132, 199, 224, 222, - 161, 251, 9, 232, 38, 16, 235, 75, 195, 173, 251, 9, 232, 38, 16, 208, - 25, 235, 75, 55, 251, 9, 232, 38, 16, 207, 246, 196, 99, 251, 9, 232, 38, - 16, 237, 62, 196, 99, 251, 9, 232, 38, 16, 236, 244, 196, 99, 251, 9, - 232, 38, 16, 222, 162, 196, 99, 251, 9, 232, 38, 16, 242, 219, 196, 99, - 251, 9, 232, 38, 16, 132, 203, 48, 222, 161, 251, 9, 232, 38, 16, 207, - 246, 208, 24, 251, 9, 232, 38, 16, 242, 219, 201, 97, 251, 9, 232, 38, - 16, 208, 25, 242, 35, 251, 9, 232, 38, 16, 132, 199, 224, 236, 253, 251, - 9, 232, 38, 16, 237, 74, 236, 253, 251, 9, 232, 38, 16, 201, 98, 236, - 253, 251, 9, 232, 38, 16, 222, 162, 236, 253, 251, 9, 232, 38, 16, 242, - 219, 236, 253, 251, 9, 232, 38, 16, 143, 203, 48, 201, 66, 251, 9, 232, - 38, 16, 45, 203, 48, 201, 66, 251, 9, 232, 38, 16, 198, 148, 236, 253, - 251, 9, 232, 38, 16, 230, 170, 236, 253, 251, 9, 232, 38, 16, 242, 27, - 164, 251, 9, 232, 38, 16, 237, 74, 198, 147, 251, 9, 232, 38, 16, 191, - 20, 251, 9, 232, 38, 16, 201, 67, 198, 147, 251, 9, 232, 38, 16, 204, 21, - 196, 99, 251, 9, 232, 38, 16, 208, 25, 212, 255, 234, 2, 251, 9, 232, 38, - 16, 208, 25, 208, 7, 251, 9, 232, 38, 16, 143, 247, 49, 198, 147, 251, 9, - 232, 38, 16, 132, 247, 49, 198, 147, 251, 9, 232, 38, 16, 223, 55, 251, - 9, 232, 38, 16, 206, 254, 251, 9, 232, 38, 16, 211, 99, 251, 9, 232, 38, - 16, 251, 110, 196, 99, 251, 9, 232, 38, 16, 234, 6, 196, 99, 251, 9, 232, - 38, 16, 223, 56, 196, 99, 251, 9, 232, 38, 16, 211, 100, 196, 99, 251, 9, - 232, 38, 16, 251, 109, 212, 255, 243, 78, 77, 50, 251, 65, 4, 235, 75, - 191, 21, 55, 203, 16, 211, 66, 248, 14, 248, 186, 113, 81, 219, 89, 4, - 82, 236, 96, 223, 91, 113, 238, 236, 196, 97, 113, 236, 180, 196, 97, - 113, 234, 65, 113, 239, 15, 113, 64, 51, 4, 246, 230, 81, 219, 88, 234, - 36, 113, 251, 101, 221, 198, 113, 229, 170, 113, 47, 228, 209, 249, 38, - 4, 212, 252, 47, 197, 238, 235, 79, 247, 230, 242, 219, 4, 213, 2, 55, - 196, 95, 113, 215, 199, 113, 228, 54, 113, 211, 64, 230, 82, 113, 211, - 64, 220, 117, 113, 210, 83, 113, 210, 82, 113, 236, 189, 238, 122, 16, - 232, 107, 109, 202, 24, 113, 251, 9, 232, 38, 16, 208, 24, 237, 93, 204, - 6, 221, 198, 113, 208, 210, 210, 194, 214, 59, 210, 194, 208, 205, 205, - 72, 113, 242, 190, 205, 72, 113, 45, 210, 104, 116, 106, 45, 210, 104, - 233, 162, 45, 210, 104, 110, 106, 50, 210, 104, 116, 106, 50, 210, 104, - 233, 162, 50, 210, 104, 110, 106, 45, 51, 248, 6, 116, 238, 210, 45, 51, - 248, 6, 233, 162, 45, 51, 248, 6, 110, 238, 210, 50, 51, 248, 6, 116, - 238, 210, 50, 51, 248, 6, 233, 162, 50, 51, 248, 6, 110, 238, 210, 45, - 238, 124, 248, 6, 116, 106, 45, 238, 124, 248, 6, 82, 209, 166, 45, 238, - 124, 248, 6, 110, 106, 238, 124, 248, 6, 233, 162, 50, 238, 124, 248, 6, - 116, 106, 50, 238, 124, 248, 6, 82, 209, 166, 50, 238, 124, 248, 6, 110, - 106, 223, 86, 233, 162, 228, 209, 219, 89, 233, 162, 116, 45, 211, 46, - 110, 50, 238, 124, 248, 6, 205, 48, 116, 50, 211, 46, 110, 45, 238, 124, - 248, 6, 205, 48, 200, 197, 198, 48, 200, 197, 248, 28, 198, 49, 51, 248, - 5, 248, 29, 51, 248, 5, 248, 29, 51, 248, 6, 138, 198, 49, 51, 248, 5, - 48, 16, 248, 28, 45, 81, 111, 219, 88, 50, 81, 111, 219, 88, 228, 209, - 205, 92, 219, 87, 228, 209, 205, 92, 219, 86, 228, 209, 205, 92, 219, 85, - 228, 209, 205, 92, 219, 84, 237, 52, 16, 155, 81, 24, 198, 49, 187, 237, - 52, 16, 155, 81, 24, 248, 29, 187, 237, 52, 16, 155, 81, 4, 242, 218, - 237, 52, 16, 155, 143, 24, 228, 209, 4, 242, 218, 237, 52, 16, 155, 132, - 24, 228, 209, 4, 242, 218, 237, 52, 16, 155, 81, 4, 197, 237, 237, 52, - 16, 155, 143, 24, 228, 209, 4, 197, 237, 237, 52, 16, 155, 132, 24, 228, - 209, 4, 197, 237, 237, 52, 16, 155, 81, 24, 193, 136, 237, 52, 16, 155, - 143, 24, 228, 209, 4, 193, 136, 237, 52, 16, 155, 132, 24, 228, 209, 4, - 193, 136, 237, 52, 16, 155, 143, 24, 228, 208, 237, 52, 16, 155, 132, 24, - 228, 208, 237, 52, 16, 155, 81, 24, 198, 49, 219, 200, 237, 52, 16, 155, - 81, 24, 248, 29, 219, 200, 51, 232, 120, 207, 18, 113, 234, 106, 113, 81, - 219, 89, 233, 162, 216, 140, 247, 244, 216, 140, 177, 138, 203, 34, 216, - 140, 203, 35, 138, 218, 251, 216, 140, 177, 138, 103, 203, 20, 216, 140, - 103, 203, 21, 138, 218, 251, 216, 140, 103, 203, 21, 222, 170, 216, 140, - 197, 217, 216, 140, 199, 60, 216, 140, 210, 13, 234, 164, 230, 155, 232, - 32, 198, 49, 210, 103, 248, 29, 210, 103, 198, 49, 238, 124, 248, 5, 248, - 29, 238, 124, 248, 5, 198, 49, 198, 37, 203, 98, 248, 5, 248, 29, 198, - 37, 203, 98, 248, 5, 64, 198, 1, 248, 171, 206, 184, 4, 242, 218, 201, - 46, 232, 164, 252, 12, 238, 121, 234, 91, 223, 71, 237, 93, 233, 166, - 113, 62, 206, 198, 54, 197, 237, 62, 219, 195, 54, 197, 237, 62, 196, 72, - 54, 197, 237, 62, 235, 78, 54, 197, 237, 62, 206, 198, 54, 197, 238, 4, - 81, 164, 62, 219, 195, 54, 197, 238, 4, 81, 164, 62, 206, 198, 197, 238, - 4, 54, 81, 164, 251, 150, 242, 174, 201, 53, 198, 140, 242, 174, 228, - 144, 4, 232, 144, 205, 135, 62, 216, 194, 219, 195, 197, 237, 62, 216, - 194, 206, 198, 197, 237, 62, 216, 194, 196, 72, 197, 237, 62, 216, 194, - 235, 78, 197, 237, 54, 81, 164, 62, 51, 39, 201, 58, 62, 242, 219, 39, - 207, 92, 208, 248, 113, 208, 248, 211, 92, 113, 208, 248, 211, 94, 113, - 208, 248, 202, 88, 113, 211, 155, 233, 153, 113, 16, 39, 212, 125, 16, - 39, 201, 93, 80, 229, 200, 16, 39, 201, 93, 80, 199, 48, 16, 39, 234, 53, - 80, 199, 48, 16, 39, 234, 53, 80, 198, 7, 16, 39, 234, 39, 16, 39, 251, - 255, 16, 39, 248, 185, 16, 39, 249, 90, 16, 39, 228, 209, 199, 225, 16, - 39, 219, 89, 233, 9, 16, 39, 81, 199, 225, 16, 39, 232, 107, 233, 9, 16, - 39, 247, 40, 207, 17, 16, 39, 203, 72, 211, 4, 16, 39, 203, 72, 223, 134, - 16, 39, 237, 165, 219, 79, 233, 228, 16, 39, 237, 30, 238, 231, 108, 16, - 39, 237, 30, 238, 231, 109, 16, 39, 237, 30, 238, 231, 139, 16, 39, 237, - 30, 238, 231, 137, 16, 39, 214, 92, 251, 255, 16, 39, 200, 65, 223, 199, - 16, 39, 234, 53, 80, 198, 8, 248, 81, 16, 39, 247, 78, 16, 39, 234, 53, - 80, 216, 193, 16, 39, 200, 221, 16, 39, 233, 228, 16, 39, 232, 222, 204, - 5, 16, 39, 230, 154, 204, 5, 16, 39, 207, 93, 204, 5, 16, 39, 196, 87, - 204, 5, 16, 39, 201, 242, 16, 39, 237, 71, 248, 85, 113, 211, 66, 248, - 14, 16, 39, 214, 62, 16, 39, 237, 72, 232, 107, 109, 16, 39, 200, 222, - 232, 107, 109, 211, 149, 106, 211, 149, 246, 204, 211, 149, 232, 110, - 211, 149, 223, 65, 232, 110, 211, 149, 248, 182, 247, 213, 211, 149, 248, - 22, 198, 173, 211, 149, 248, 0, 249, 43, 227, 242, 211, 149, 251, 88, 80, - 243, 77, 211, 149, 237, 170, 211, 149, 238, 110, 252, 3, 212, 123, 211, - 149, 54, 249, 91, 47, 17, 108, 47, 17, 109, 47, 17, 139, 47, 17, 137, 47, - 17, 153, 47, 17, 173, 47, 17, 181, 47, 17, 176, 47, 17, 184, 47, 31, 199, - 90, 47, 31, 234, 84, 47, 31, 197, 33, 47, 31, 198, 246, 47, 31, 232, 84, - 47, 31, 232, 234, 47, 31, 202, 125, 47, 31, 203, 239, 47, 31, 234, 118, - 47, 31, 213, 158, 47, 31, 197, 28, 127, 17, 108, 127, 17, 109, 127, 17, - 139, 127, 17, 137, 127, 17, 153, 127, 17, 173, 127, 17, 181, 127, 17, - 176, 127, 17, 184, 127, 31, 199, 90, 127, 31, 234, 84, 127, 31, 197, 33, - 127, 31, 198, 246, 127, 31, 232, 84, 127, 31, 232, 234, 127, 31, 202, - 125, 127, 31, 203, 239, 127, 31, 234, 118, 127, 31, 213, 158, 127, 31, - 197, 28, 17, 91, 232, 42, 201, 58, 17, 103, 232, 42, 201, 58, 17, 115, - 232, 42, 201, 58, 17, 232, 90, 232, 42, 201, 58, 17, 232, 185, 232, 42, - 201, 58, 17, 202, 131, 232, 42, 201, 58, 17, 203, 242, 232, 42, 201, 58, - 17, 234, 121, 232, 42, 201, 58, 17, 213, 161, 232, 42, 201, 58, 31, 199, - 91, 232, 42, 201, 58, 31, 234, 85, 232, 42, 201, 58, 31, 197, 34, 232, - 42, 201, 58, 31, 198, 247, 232, 42, 201, 58, 31, 232, 85, 232, 42, 201, - 58, 31, 232, 235, 232, 42, 201, 58, 31, 202, 126, 232, 42, 201, 58, 31, - 203, 240, 232, 42, 201, 58, 31, 234, 119, 232, 42, 201, 58, 31, 213, 159, - 232, 42, 201, 58, 31, 197, 29, 232, 42, 201, 58, 127, 8, 2, 1, 65, 127, - 8, 2, 1, 250, 70, 127, 8, 2, 1, 247, 145, 127, 8, 2, 1, 238, 80, 127, 8, - 2, 1, 73, 127, 8, 2, 1, 233, 134, 127, 8, 2, 1, 232, 14, 127, 8, 2, 1, - 230, 83, 127, 8, 2, 1, 70, 127, 8, 2, 1, 223, 7, 127, 8, 2, 1, 222, 125, - 127, 8, 2, 1, 170, 127, 8, 2, 1, 218, 147, 127, 8, 2, 1, 215, 47, 127, 8, - 2, 1, 74, 127, 8, 2, 1, 210, 226, 127, 8, 2, 1, 208, 97, 127, 8, 2, 1, - 148, 127, 8, 2, 1, 206, 3, 127, 8, 2, 1, 200, 39, 127, 8, 2, 1, 69, 127, - 8, 2, 1, 196, 8, 127, 8, 2, 1, 193, 221, 127, 8, 2, 1, 192, 235, 127, 8, - 2, 1, 192, 159, 127, 8, 2, 1, 191, 166, 47, 8, 6, 1, 65, 47, 8, 6, 1, - 250, 70, 47, 8, 6, 1, 247, 145, 47, 8, 6, 1, 238, 80, 47, 8, 6, 1, 73, - 47, 8, 6, 1, 233, 134, 47, 8, 6, 1, 232, 14, 47, 8, 6, 1, 230, 83, 47, 8, - 6, 1, 70, 47, 8, 6, 1, 223, 7, 47, 8, 6, 1, 222, 125, 47, 8, 6, 1, 170, - 47, 8, 6, 1, 218, 147, 47, 8, 6, 1, 215, 47, 47, 8, 6, 1, 74, 47, 8, 6, - 1, 210, 226, 47, 8, 6, 1, 208, 97, 47, 8, 6, 1, 148, 47, 8, 6, 1, 206, 3, - 47, 8, 6, 1, 200, 39, 47, 8, 6, 1, 69, 47, 8, 6, 1, 196, 8, 47, 8, 6, 1, - 193, 221, 47, 8, 6, 1, 192, 235, 47, 8, 6, 1, 192, 159, 47, 8, 6, 1, 191, - 166, 47, 8, 2, 1, 65, 47, 8, 2, 1, 250, 70, 47, 8, 2, 1, 247, 145, 47, 8, - 2, 1, 238, 80, 47, 8, 2, 1, 73, 47, 8, 2, 1, 233, 134, 47, 8, 2, 1, 232, - 14, 47, 8, 2, 1, 230, 83, 47, 8, 2, 1, 70, 47, 8, 2, 1, 223, 7, 47, 8, 2, - 1, 222, 125, 47, 8, 2, 1, 170, 47, 8, 2, 1, 218, 147, 47, 8, 2, 1, 215, - 47, 47, 8, 2, 1, 74, 47, 8, 2, 1, 210, 226, 47, 8, 2, 1, 208, 97, 47, 8, - 2, 1, 148, 47, 8, 2, 1, 206, 3, 47, 8, 2, 1, 200, 39, 47, 8, 2, 1, 69, - 47, 8, 2, 1, 196, 8, 47, 8, 2, 1, 193, 221, 47, 8, 2, 1, 192, 235, 47, 8, - 2, 1, 192, 159, 47, 8, 2, 1, 191, 166, 47, 17, 191, 77, 214, 92, 47, 31, - 234, 84, 214, 92, 47, 31, 197, 33, 214, 92, 47, 31, 198, 246, 214, 92, - 47, 31, 232, 84, 214, 92, 47, 31, 232, 234, 214, 92, 47, 31, 202, 125, - 214, 92, 47, 31, 203, 239, 214, 92, 47, 31, 234, 118, 214, 92, 47, 31, - 213, 158, 214, 92, 47, 31, 197, 28, 54, 47, 17, 108, 54, 47, 17, 109, 54, - 47, 17, 139, 54, 47, 17, 137, 54, 47, 17, 153, 54, 47, 17, 173, 54, 47, - 17, 181, 54, 47, 17, 176, 54, 47, 17, 184, 54, 47, 31, 199, 90, 214, 92, - 47, 17, 191, 77, 111, 122, 155, 228, 208, 111, 122, 88, 228, 208, 111, - 122, 155, 195, 132, 111, 122, 88, 195, 132, 111, 122, 155, 197, 221, 237, - 171, 228, 208, 111, 122, 88, 197, 221, 237, 171, 228, 208, 111, 122, 155, - 197, 221, 237, 171, 195, 132, 111, 122, 88, 197, 221, 237, 171, 195, 132, - 111, 122, 155, 208, 20, 237, 171, 228, 208, 111, 122, 88, 208, 20, 237, - 171, 228, 208, 111, 122, 155, 208, 20, 237, 171, 195, 132, 111, 122, 88, - 208, 20, 237, 171, 195, 132, 111, 122, 155, 143, 24, 187, 111, 122, 143, - 155, 24, 50, 229, 185, 111, 122, 143, 88, 24, 50, 219, 108, 111, 122, 88, - 143, 24, 187, 111, 122, 155, 143, 24, 219, 200, 111, 122, 143, 155, 24, - 45, 229, 185, 111, 122, 143, 88, 24, 45, 219, 108, 111, 122, 88, 143, 24, - 219, 200, 111, 122, 155, 132, 24, 187, 111, 122, 132, 155, 24, 50, 229, - 185, 111, 122, 132, 88, 24, 50, 219, 108, 111, 122, 88, 132, 24, 187, - 111, 122, 155, 132, 24, 219, 200, 111, 122, 132, 155, 24, 45, 229, 185, - 111, 122, 132, 88, 24, 45, 219, 108, 111, 122, 88, 132, 24, 219, 200, - 111, 122, 155, 81, 24, 187, 111, 122, 81, 155, 24, 50, 229, 185, 111, - 122, 132, 88, 24, 50, 143, 219, 108, 111, 122, 143, 88, 24, 50, 132, 219, - 108, 111, 122, 81, 88, 24, 50, 219, 108, 111, 122, 143, 155, 24, 50, 132, - 229, 185, 111, 122, 132, 155, 24, 50, 143, 229, 185, 111, 122, 88, 81, - 24, 187, 111, 122, 155, 81, 24, 219, 200, 111, 122, 81, 155, 24, 45, 229, - 185, 111, 122, 132, 88, 24, 45, 143, 219, 108, 111, 122, 143, 88, 24, 45, - 132, 219, 108, 111, 122, 81, 88, 24, 45, 219, 108, 111, 122, 143, 155, - 24, 45, 132, 229, 185, 111, 122, 132, 155, 24, 45, 143, 229, 185, 111, - 122, 88, 81, 24, 219, 200, 111, 122, 155, 143, 24, 228, 208, 111, 122, - 45, 88, 24, 50, 143, 219, 108, 111, 122, 50, 88, 24, 45, 143, 219, 108, - 111, 122, 143, 155, 24, 228, 209, 229, 185, 111, 122, 143, 88, 24, 228, - 209, 219, 108, 111, 122, 50, 155, 24, 45, 143, 229, 185, 111, 122, 45, - 155, 24, 50, 143, 229, 185, 111, 122, 88, 143, 24, 228, 208, 111, 122, - 155, 132, 24, 228, 208, 111, 122, 45, 88, 24, 50, 132, 219, 108, 111, - 122, 50, 88, 24, 45, 132, 219, 108, 111, 122, 132, 155, 24, 228, 209, - 229, 185, 111, 122, 132, 88, 24, 228, 209, 219, 108, 111, 122, 50, 155, - 24, 45, 132, 229, 185, 111, 122, 45, 155, 24, 50, 132, 229, 185, 111, - 122, 88, 132, 24, 228, 208, 111, 122, 155, 81, 24, 228, 208, 111, 122, - 45, 88, 24, 50, 81, 219, 108, 111, 122, 50, 88, 24, 45, 81, 219, 108, - 111, 122, 81, 155, 24, 228, 209, 229, 185, 111, 122, 132, 88, 24, 143, - 228, 209, 219, 108, 111, 122, 143, 88, 24, 132, 228, 209, 219, 108, 111, - 122, 81, 88, 24, 228, 209, 219, 108, 111, 122, 45, 132, 88, 24, 50, 143, - 219, 108, 111, 122, 50, 132, 88, 24, 45, 143, 219, 108, 111, 122, 45, - 143, 88, 24, 50, 132, 219, 108, 111, 122, 50, 143, 88, 24, 45, 132, 219, - 108, 111, 122, 143, 155, 24, 132, 228, 209, 229, 185, 111, 122, 132, 155, - 24, 143, 228, 209, 229, 185, 111, 122, 50, 155, 24, 45, 81, 229, 185, - 111, 122, 45, 155, 24, 50, 81, 229, 185, 111, 122, 88, 81, 24, 228, 208, - 111, 122, 155, 54, 237, 171, 228, 208, 111, 122, 88, 54, 237, 171, 228, - 208, 111, 122, 155, 54, 237, 171, 195, 132, 111, 122, 88, 54, 237, 171, - 195, 132, 111, 122, 54, 228, 208, 111, 122, 54, 195, 132, 111, 122, 143, - 202, 165, 24, 50, 235, 89, 111, 122, 143, 54, 24, 50, 202, 164, 111, 122, - 54, 143, 24, 187, 111, 122, 143, 202, 165, 24, 45, 235, 89, 111, 122, - 143, 54, 24, 45, 202, 164, 111, 122, 54, 143, 24, 219, 200, 111, 122, - 132, 202, 165, 24, 50, 235, 89, 111, 122, 132, 54, 24, 50, 202, 164, 111, - 122, 54, 132, 24, 187, 111, 122, 132, 202, 165, 24, 45, 235, 89, 111, - 122, 132, 54, 24, 45, 202, 164, 111, 122, 54, 132, 24, 219, 200, 111, - 122, 81, 202, 165, 24, 50, 235, 89, 111, 122, 81, 54, 24, 50, 202, 164, - 111, 122, 54, 81, 24, 187, 111, 122, 81, 202, 165, 24, 45, 235, 89, 111, - 122, 81, 54, 24, 45, 202, 164, 111, 122, 54, 81, 24, 219, 200, 111, 122, - 143, 202, 165, 24, 228, 209, 235, 89, 111, 122, 143, 54, 24, 228, 209, - 202, 164, 111, 122, 54, 143, 24, 228, 208, 111, 122, 132, 202, 165, 24, - 228, 209, 235, 89, 111, 122, 132, 54, 24, 228, 209, 202, 164, 111, 122, - 54, 132, 24, 228, 208, 111, 122, 81, 202, 165, 24, 228, 209, 235, 89, - 111, 122, 81, 54, 24, 228, 209, 202, 164, 111, 122, 54, 81, 24, 228, 208, - 111, 122, 155, 250, 223, 143, 24, 187, 111, 122, 155, 250, 223, 143, 24, - 219, 200, 111, 122, 155, 250, 223, 132, 24, 219, 200, 111, 122, 155, 250, - 223, 132, 24, 187, 111, 122, 155, 236, 250, 116, 50, 118, 110, 219, 200, - 111, 122, 155, 236, 250, 116, 45, 118, 110, 187, 111, 122, 155, 236, 250, - 238, 170, 111, 122, 155, 219, 200, 111, 122, 155, 196, 73, 111, 122, 155, - 187, 111, 122, 155, 235, 79, 111, 122, 88, 219, 200, 111, 122, 88, 196, - 73, 111, 122, 88, 187, 111, 122, 88, 235, 79, 111, 122, 155, 45, 24, 88, - 187, 111, 122, 155, 132, 24, 88, 235, 79, 111, 122, 88, 45, 24, 155, 187, - 111, 122, 88, 132, 24, 155, 235, 79, 116, 134, 248, 81, 110, 91, 234, - 117, 248, 81, 110, 91, 208, 18, 248, 81, 110, 115, 234, 115, 248, 81, - 110, 134, 248, 81, 110, 232, 185, 234, 115, 248, 81, 110, 115, 208, 16, - 248, 81, 110, 203, 242, 234, 115, 248, 81, 232, 42, 248, 81, 45, 203, - 242, 234, 115, 248, 81, 45, 115, 208, 16, 248, 81, 45, 232, 185, 234, - 115, 248, 81, 45, 134, 248, 81, 45, 115, 234, 115, 248, 81, 45, 91, 208, - 18, 248, 81, 45, 91, 234, 117, 248, 81, 50, 134, 248, 81, 155, 203, 148, - 216, 194, 203, 148, 237, 176, 203, 148, 116, 91, 234, 117, 248, 81, 50, - 91, 234, 117, 248, 81, 208, 22, 110, 219, 200, 208, 22, 110, 187, 208, - 22, 116, 219, 200, 208, 22, 116, 45, 24, 110, 45, 24, 110, 187, 208, 22, - 116, 45, 24, 110, 187, 208, 22, 116, 45, 24, 116, 50, 24, 110, 219, 200, - 208, 22, 116, 45, 24, 116, 50, 24, 110, 187, 208, 22, 116, 187, 208, 22, - 116, 50, 24, 110, 219, 200, 208, 22, 116, 50, 24, 110, 45, 24, 110, 187, - 62, 201, 185, 64, 201, 185, 64, 51, 4, 206, 108, 238, 209, 64, 51, 238, - 242, 62, 2, 201, 185, 51, 4, 228, 209, 232, 220, 51, 4, 81, 232, 220, 51, - 4, 211, 28, 238, 164, 232, 220, 51, 4, 116, 45, 118, 110, 50, 232, 220, - 51, 4, 116, 50, 118, 110, 45, 232, 220, 51, 4, 236, 250, 238, 164, 232, - 220, 62, 2, 201, 185, 64, 2, 201, 185, 62, 207, 87, 64, 207, 87, 62, 81, - 207, 87, 64, 81, 207, 87, 62, 210, 107, 64, 210, 107, 62, 196, 72, 197, - 237, 64, 196, 72, 197, 237, 62, 196, 72, 2, 197, 237, 64, 196, 72, 2, - 197, 237, 62, 206, 198, 197, 237, 64, 206, 198, 197, 237, 62, 206, 198, - 2, 197, 237, 64, 206, 198, 2, 197, 237, 62, 206, 198, 209, 52, 64, 206, - 198, 209, 52, 62, 235, 78, 197, 237, 64, 235, 78, 197, 237, 62, 235, 78, - 2, 197, 237, 64, 235, 78, 2, 197, 237, 62, 219, 195, 197, 237, 64, 219, - 195, 197, 237, 62, 219, 195, 2, 197, 237, 64, 219, 195, 2, 197, 237, 62, - 219, 195, 209, 52, 64, 219, 195, 209, 52, 62, 236, 243, 64, 236, 243, 64, - 236, 244, 238, 242, 62, 2, 236, 243, 232, 194, 218, 210, 64, 242, 218, - 235, 94, 242, 218, 242, 219, 4, 81, 232, 220, 247, 196, 62, 242, 218, - 242, 219, 4, 45, 134, 248, 91, 242, 219, 4, 50, 134, 248, 91, 242, 219, - 4, 110, 134, 248, 91, 242, 219, 4, 116, 134, 248, 91, 242, 219, 4, 116, - 50, 208, 22, 248, 91, 242, 219, 4, 251, 124, 247, 170, 116, 45, 208, 22, - 248, 91, 45, 134, 62, 242, 218, 50, 134, 62, 242, 218, 223, 67, 247, 200, - 223, 67, 64, 242, 218, 116, 134, 223, 67, 64, 242, 218, 110, 134, 223, - 67, 64, 242, 218, 116, 45, 208, 22, 242, 212, 250, 222, 116, 50, 208, 22, - 242, 212, 250, 222, 110, 50, 208, 22, 242, 212, 250, 222, 110, 45, 208, - 22, 242, 212, 250, 222, 116, 134, 242, 218, 110, 134, 242, 218, 62, 110, - 50, 197, 237, 62, 110, 45, 197, 237, 62, 116, 45, 197, 237, 62, 116, 50, - 197, 237, 64, 247, 200, 51, 4, 45, 134, 248, 91, 51, 4, 50, 134, 248, 91, - 51, 4, 116, 45, 236, 250, 134, 248, 91, 51, 4, 110, 50, 236, 250, 134, - 248, 91, 64, 51, 4, 81, 248, 106, 219, 88, 64, 196, 72, 197, 238, 4, 236, - 96, 196, 72, 197, 238, 4, 45, 134, 248, 91, 196, 72, 197, 238, 4, 50, - 134, 248, 91, 219, 245, 242, 218, 64, 51, 4, 116, 45, 208, 21, 64, 51, 4, - 110, 45, 208, 21, 64, 51, 4, 110, 50, 208, 21, 64, 51, 4, 116, 50, 208, - 21, 64, 242, 219, 4, 116, 45, 208, 21, 64, 242, 219, 4, 110, 45, 208, 21, - 64, 242, 219, 4, 110, 50, 208, 21, 64, 242, 219, 4, 116, 50, 208, 21, - 116, 45, 197, 237, 116, 50, 197, 237, 110, 45, 197, 237, 64, 216, 194, - 201, 185, 62, 216, 194, 201, 185, 64, 216, 194, 2, 201, 185, 62, 216, - 194, 2, 201, 185, 110, 50, 197, 237, 62, 200, 194, 4, 207, 114, 242, 162, - 196, 113, 202, 43, 242, 29, 62, 201, 97, 64, 201, 97, 219, 105, 198, 203, - 200, 193, 250, 163, 213, 22, 237, 41, 213, 22, 238, 251, 211, 51, 62, - 199, 101, 64, 199, 101, 249, 57, 248, 14, 249, 57, 111, 4, 243, 77, 249, - 57, 111, 4, 192, 235, 205, 149, 196, 114, 4, 207, 145, 235, 52, 228, 150, - 248, 157, 64, 203, 44, 209, 166, 62, 203, 44, 209, 166, 203, 135, 207, - 13, 206, 117, 232, 150, 229, 192, 247, 200, 62, 45, 209, 51, 223, 120, - 62, 50, 209, 51, 223, 120, 64, 45, 209, 51, 223, 120, 64, 132, 209, 51, - 223, 120, 64, 50, 209, 51, 223, 120, 64, 143, 209, 51, 223, 120, 202, 99, - 24, 238, 168, 247, 23, 57, 207, 159, 57, 248, 114, 57, 247, 103, 251, 48, - 211, 29, 238, 170, 243, 48, 206, 254, 238, 171, 80, 218, 231, 238, 171, - 80, 222, 227, 201, 98, 24, 238, 180, 233, 33, 113, 251, 238, 203, 138, - 230, 29, 24, 202, 208, 210, 52, 113, 192, 22, 192, 106, 197, 227, 39, - 229, 187, 197, 227, 39, 220, 19, 197, 227, 39, 232, 202, 197, 227, 39, - 198, 204, 197, 227, 39, 193, 64, 197, 227, 39, 193, 141, 197, 227, 39, - 215, 168, 197, 227, 39, 234, 163, 193, 92, 80, 237, 15, 64, 232, 54, 233, - 62, 64, 202, 59, 233, 62, 62, 202, 59, 233, 62, 64, 200, 194, 4, 207, - 114, 232, 197, 208, 18, 215, 188, 219, 238, 208, 18, 215, 188, 216, 161, - 233, 1, 57, 234, 163, 217, 77, 57, 222, 140, 205, 110, 196, 53, 214, 80, - 209, 69, 250, 208, 199, 159, 231, 115, 247, 76, 219, 162, 195, 35, 219, - 119, 205, 75, 205, 178, 247, 58, 250, 240, 209, 112, 64, 243, 57, 221, - 114, 64, 243, 57, 208, 9, 64, 243, 57, 206, 126, 64, 243, 57, 248, 104, - 64, 243, 57, 221, 52, 64, 243, 57, 210, 64, 62, 243, 57, 221, 114, 62, - 243, 57, 208, 9, 62, 243, 57, 206, 126, 62, 243, 57, 248, 104, 62, 243, - 57, 221, 52, 62, 243, 57, 210, 64, 62, 201, 240, 200, 206, 64, 229, 192, - 200, 206, 64, 236, 244, 200, 206, 62, 242, 159, 200, 206, 64, 201, 240, - 200, 206, 62, 229, 192, 200, 206, 62, 236, 244, 200, 206, 64, 242, 159, - 200, 206, 228, 150, 201, 190, 208, 18, 212, 249, 234, 117, 212, 249, 248, - 219, 234, 117, 212, 244, 248, 219, 202, 124, 212, 244, 215, 83, 232, 167, - 57, 215, 83, 214, 192, 57, 215, 83, 203, 122, 57, 193, 103, 200, 59, 238, - 170, 234, 160, 200, 59, 238, 170, 196, 83, 207, 83, 113, 207, 83, 16, 39, - 196, 250, 209, 90, 207, 83, 16, 39, 196, 248, 209, 90, 207, 83, 16, 39, - 196, 247, 209, 90, 207, 83, 16, 39, 196, 245, 209, 90, 207, 83, 16, 39, - 196, 243, 209, 90, 207, 83, 16, 39, 196, 241, 209, 90, 207, 83, 16, 39, - 196, 239, 209, 90, 207, 83, 16, 39, 231, 112, 217, 9, 62, 196, 83, 207, - 83, 113, 207, 84, 210, 126, 113, 210, 94, 210, 126, 113, 209, 250, 210, - 126, 57, 193, 90, 113, 236, 236, 233, 61, 236, 236, 233, 60, 236, 236, - 233, 59, 236, 236, 233, 58, 236, 236, 233, 57, 236, 236, 233, 56, 64, - 242, 219, 4, 75, 187, 64, 242, 219, 4, 103, 236, 94, 62, 242, 219, 4, 64, - 75, 187, 62, 242, 219, 4, 103, 64, 236, 94, 215, 204, 39, 192, 106, 215, - 204, 39, 192, 21, 236, 217, 39, 230, 171, 192, 106, 236, 217, 39, 219, - 154, 192, 21, 236, 217, 39, 219, 154, 192, 106, 236, 217, 39, 230, 171, - 192, 21, 64, 232, 177, 62, 232, 177, 230, 29, 24, 209, 171, 251, 76, 238, - 167, 200, 126, 201, 107, 80, 251, 212, 205, 93, 251, 140, 232, 146, 231, - 125, 201, 107, 80, 229, 159, 250, 122, 113, 232, 162, 211, 0, 64, 201, - 97, 115, 219, 83, 238, 228, 187, 115, 219, 83, 238, 228, 219, 200, 193, - 153, 57, 136, 195, 9, 57, 235, 84, 233, 1, 57, 235, 84, 217, 77, 57, 223, - 77, 233, 1, 24, 217, 77, 57, 217, 77, 24, 233, 1, 57, 217, 77, 4, 201, - 23, 57, 217, 77, 4, 201, 23, 24, 217, 77, 24, 233, 1, 57, 81, 217, 77, 4, - 201, 23, 57, 228, 209, 217, 77, 4, 201, 23, 57, 216, 194, 64, 242, 218, - 216, 194, 62, 242, 218, 216, 194, 2, 64, 242, 218, 217, 29, 113, 236, - 153, 113, 196, 80, 210, 93, 113, 242, 41, 232, 37, 196, 49, 214, 69, 246, - 215, 210, 175, 222, 146, 195, 77, 243, 27, 62, 215, 189, 219, 102, 203, - 171, 204, 17, 207, 255, 203, 250, 202, 31, 249, 61, 249, 23, 112, 221, - 197, 64, 235, 64, 217, 70, 64, 235, 64, 221, 114, 62, 235, 64, 217, 70, - 62, 235, 64, 221, 114, 202, 44, 193, 51, 202, 47, 200, 194, 248, 192, - 242, 162, 207, 144, 62, 202, 43, 198, 205, 242, 163, 24, 207, 144, 152, - 64, 203, 44, 209, 166, 152, 62, 203, 44, 209, 166, 64, 236, 244, 223, - 135, 201, 185, 238, 163, 219, 253, 236, 184, 247, 54, 211, 54, 209, 171, - 247, 55, 202, 80, 229, 169, 4, 64, 238, 170, 47, 238, 163, 219, 253, 246, - 205, 213, 31, 234, 30, 251, 106, 211, 85, 45, 193, 127, 198, 15, 62, 197, - 6, 45, 193, 127, 198, 15, 64, 197, 6, 45, 193, 127, 198, 15, 62, 45, 219, - 254, 216, 160, 64, 45, 219, 254, 216, 160, 235, 59, 202, 71, 57, 88, 64, - 235, 78, 197, 237, 45, 242, 171, 234, 30, 112, 205, 149, 233, 42, 236, - 250, 223, 135, 64, 242, 219, 223, 135, 62, 201, 185, 62, 197, 199, 207, - 24, 45, 234, 29, 207, 24, 45, 234, 28, 250, 137, 16, 39, 196, 53, 88, - 242, 219, 4, 201, 23, 24, 103, 183, 56, 210, 14, 206, 200, 223, 79, 210, - 14, 219, 197, 223, 79, 210, 14, 223, 65, 210, 14, 62, 238, 171, 211, 94, - 203, 73, 203, 61, 203, 7, 242, 248, 247, 32, 229, 86, 202, 132, 231, 126, - 193, 51, 228, 122, 231, 126, 4, 229, 253, 217, 52, 16, 39, 219, 107, 215, - 168, 196, 114, 211, 94, 230, 155, 232, 91, 232, 178, 223, 135, 228, 229, - 232, 247, 205, 173, 51, 232, 90, 238, 209, 202, 103, 227, 253, 202, 107, - 209, 242, 4, 249, 61, 199, 82, 222, 247, 249, 43, 113, 229, 197, 230, - 173, 113, 232, 45, 208, 146, 238, 135, 211, 94, 62, 201, 185, 64, 232, - 178, 4, 228, 209, 82, 62, 201, 24, 62, 205, 183, 205, 79, 116, 248, 86, - 205, 79, 62, 205, 79, 110, 248, 86, 205, 79, 64, 205, 79, 64, 88, 243, - 78, 77, 199, 102, 219, 16, 57, 199, 177, 235, 58, 251, 171, 234, 25, 207, - 142, 232, 190, 207, 142, 230, 20, 195, 64, 230, 20, 193, 3, 230, 20, 110, - 50, 210, 24, 210, 24, 116, 50, 210, 24, 64, 213, 194, 62, 213, 194, 243, - 78, 77, 88, 243, 78, 77, 215, 112, 192, 235, 88, 215, 112, 192, 235, 249, - 57, 192, 235, 88, 249, 57, 192, 235, 211, 0, 35, 238, 170, 88, 35, 238, - 170, 211, 66, 246, 230, 238, 170, 88, 211, 66, 246, 230, 238, 170, 8, - 238, 170, 203, 146, 64, 8, 238, 170, 211, 0, 8, 238, 170, 217, 73, 238, - 170, 201, 98, 80, 237, 163, 232, 90, 199, 122, 250, 143, 232, 90, 249, - 58, 250, 143, 88, 232, 90, 249, 58, 250, 143, 232, 90, 242, 157, 250, - 143, 62, 232, 90, 209, 53, 201, 97, 64, 232, 90, 209, 53, 201, 97, 201, - 235, 201, 33, 211, 0, 64, 201, 97, 47, 64, 201, 97, 211, 66, 246, 230, - 62, 201, 97, 62, 246, 230, 64, 201, 97, 211, 0, 62, 201, 97, 88, 211, 0, - 62, 201, 97, 209, 122, 201, 97, 203, 146, 64, 201, 97, 88, 250, 143, 211, - 66, 246, 230, 250, 143, 234, 121, 201, 201, 250, 143, 234, 121, 209, 53, - 62, 201, 97, 234, 121, 209, 53, 209, 122, 201, 97, 202, 131, 209, 53, 62, - 201, 97, 234, 121, 209, 53, 207, 85, 62, 201, 97, 88, 234, 121, 209, 53, - 207, 85, 62, 201, 97, 197, 34, 209, 53, 62, 201, 97, 202, 126, 209, 53, - 250, 143, 199, 122, 250, 143, 211, 66, 246, 230, 199, 122, 250, 143, 88, - 199, 122, 250, 143, 202, 131, 209, 230, 62, 24, 64, 232, 149, 62, 232, - 149, 64, 232, 149, 234, 121, 209, 230, 211, 0, 62, 232, 149, 47, 211, 66, - 246, 230, 234, 121, 209, 53, 201, 97, 88, 199, 122, 209, 122, 250, 143, - 202, 45, 198, 167, 197, 230, 202, 45, 88, 243, 53, 202, 45, 201, 237, 88, - 201, 237, 249, 58, 250, 143, 234, 121, 199, 122, 208, 182, 250, 143, 88, - 234, 121, 199, 122, 208, 182, 250, 143, 238, 171, 77, 203, 146, 64, 242, - 218, 214, 92, 112, 238, 171, 77, 110, 50, 235, 54, 64, 201, 185, 116, 50, - 235, 54, 64, 201, 185, 110, 50, 203, 146, 64, 201, 185, 116, 50, 203, - 146, 64, 201, 185, 62, 208, 8, 87, 211, 32, 64, 208, 8, 87, 211, 32, 64, - 233, 175, 87, 211, 32, 62, 236, 244, 216, 18, 64, 192, 235, 88, 233, 175, - 87, 113, 155, 81, 164, 216, 194, 81, 164, 88, 81, 164, 88, 202, 165, 152, - 242, 27, 207, 247, 87, 211, 32, 88, 202, 165, 242, 27, 207, 247, 87, 211, - 32, 88, 54, 152, 242, 27, 207, 247, 87, 211, 32, 88, 54, 242, 27, 207, - 247, 87, 211, 32, 88, 131, 202, 165, 242, 27, 207, 247, 87, 211, 32, 88, - 131, 54, 242, 27, 207, 247, 87, 211, 32, 238, 116, 201, 76, 210, 118, 3, - 211, 32, 88, 233, 175, 87, 211, 32, 88, 229, 192, 233, 175, 87, 211, 32, - 88, 62, 229, 191, 206, 117, 88, 62, 229, 192, 247, 200, 232, 150, 229, - 191, 206, 117, 232, 150, 229, 192, 247, 200, 216, 194, 45, 210, 104, 211, - 32, 216, 194, 50, 210, 104, 211, 32, 216, 194, 232, 163, 45, 210, 104, - 211, 32, 216, 194, 232, 163, 50, 210, 104, 211, 32, 216, 194, 219, 195, - 251, 65, 248, 6, 211, 32, 216, 194, 206, 198, 251, 65, 248, 6, 211, 32, - 88, 219, 195, 251, 65, 207, 247, 87, 211, 32, 88, 206, 198, 251, 65, 207, - 247, 87, 211, 32, 88, 219, 195, 251, 65, 248, 6, 211, 32, 88, 206, 198, - 251, 65, 248, 6, 211, 32, 155, 45, 198, 37, 203, 98, 248, 6, 211, 32, - 155, 50, 198, 37, 203, 98, 248, 6, 211, 32, 216, 194, 45, 238, 124, 248, - 6, 211, 32, 216, 194, 50, 238, 124, 248, 6, 211, 32, 236, 196, 214, 92, - 47, 17, 108, 236, 196, 214, 92, 47, 17, 109, 236, 196, 214, 92, 47, 17, - 139, 236, 196, 214, 92, 47, 17, 137, 236, 196, 214, 92, 47, 17, 153, 236, - 196, 214, 92, 47, 17, 173, 236, 196, 214, 92, 47, 17, 181, 236, 196, 214, - 92, 47, 17, 176, 236, 196, 214, 92, 47, 17, 184, 236, 196, 214, 92, 47, - 31, 199, 90, 236, 196, 47, 49, 17, 108, 236, 196, 47, 49, 17, 109, 236, - 196, 47, 49, 17, 139, 236, 196, 47, 49, 17, 137, 236, 196, 47, 49, 17, - 153, 236, 196, 47, 49, 17, 173, 236, 196, 47, 49, 17, 181, 236, 196, 47, - 49, 17, 176, 236, 196, 47, 49, 17, 184, 236, 196, 47, 49, 31, 199, 90, - 236, 196, 214, 92, 47, 49, 17, 108, 236, 196, 214, 92, 47, 49, 17, 109, - 236, 196, 214, 92, 47, 49, 17, 139, 236, 196, 214, 92, 47, 49, 17, 137, - 236, 196, 214, 92, 47, 49, 17, 153, 236, 196, 214, 92, 47, 49, 17, 173, - 236, 196, 214, 92, 47, 49, 17, 181, 236, 196, 214, 92, 47, 49, 17, 176, - 236, 196, 214, 92, 47, 49, 17, 184, 236, 196, 214, 92, 47, 49, 31, 199, - 90, 88, 193, 75, 96, 55, 88, 107, 57, 88, 216, 18, 57, 88, 236, 155, 57, - 88, 201, 253, 234, 160, 55, 88, 96, 55, 88, 185, 234, 160, 55, 235, 69, - 209, 55, 96, 55, 88, 206, 109, 96, 55, 197, 236, 96, 55, 88, 197, 236, - 96, 55, 237, 169, 197, 236, 96, 55, 88, 237, 169, 197, 236, 96, 55, 62, - 96, 55, 198, 220, 198, 47, 96, 250, 185, 198, 220, 248, 27, 96, 250, 185, - 62, 96, 250, 185, 88, 62, 238, 116, 235, 75, 24, 96, 55, 88, 62, 238, - 116, 196, 62, 24, 96, 55, 201, 182, 62, 96, 55, 88, 239, 8, 62, 96, 55, - 206, 197, 64, 96, 55, 219, 194, 64, 96, 55, 249, 95, 203, 146, 64, 96, - 55, 232, 57, 203, 146, 64, 96, 55, 88, 110, 206, 196, 64, 96, 55, 88, - 116, 206, 196, 64, 96, 55, 212, 251, 110, 206, 196, 64, 96, 55, 238, 124, - 218, 236, 212, 251, 116, 206, 196, 64, 96, 55, 47, 88, 64, 96, 55, 193, - 86, 96, 55, 248, 90, 201, 253, 234, 160, 55, 248, 90, 96, 55, 248, 90, - 185, 234, 160, 55, 88, 248, 90, 201, 253, 234, 160, 55, 88, 248, 90, 96, - 55, 88, 248, 90, 185, 234, 160, 55, 199, 124, 96, 55, 88, 199, 123, 96, - 55, 193, 113, 96, 55, 88, 193, 113, 96, 55, 211, 60, 96, 55, 54, 238, - 124, 218, 236, 115, 236, 206, 251, 64, 64, 197, 238, 238, 242, 2, 64, - 197, 237, 209, 245, 211, 66, 200, 223, 211, 66, 200, 175, 45, 206, 2, - 249, 81, 237, 67, 50, 206, 2, 249, 81, 237, 67, 211, 46, 4, 75, 223, 89, - 207, 14, 202, 19, 208, 223, 200, 223, 200, 176, 208, 223, 202, 18, 81, - 249, 38, 4, 228, 209, 105, 13, 206, 175, 236, 249, 177, 236, 154, 13, - 233, 42, 236, 249, 112, 219, 5, 251, 74, 112, 219, 5, 211, 45, 64, 236, - 244, 4, 246, 228, 236, 96, 24, 4, 236, 96, 234, 89, 80, 211, 58, 196, 61, - 110, 50, 238, 211, 4, 236, 96, 116, 45, 238, 211, 4, 236, 96, 45, 211, 2, - 222, 172, 50, 211, 2, 222, 172, 232, 42, 211, 2, 222, 172, 219, 245, 132, - 199, 223, 219, 245, 143, 199, 223, 45, 24, 50, 54, 197, 53, 45, 24, 50, - 199, 223, 45, 215, 116, 177, 50, 199, 223, 177, 45, 199, 223, 132, 199, - 224, 4, 242, 219, 56, 218, 211, 236, 161, 247, 157, 228, 209, 206, 47, - 64, 239, 7, 236, 243, 64, 239, 7, 236, 244, 4, 117, 198, 177, 64, 239, 7, - 236, 244, 4, 96, 198, 177, 64, 51, 4, 117, 198, 177, 64, 51, 4, 96, 198, - 177, 13, 45, 64, 51, 248, 5, 13, 50, 64, 51, 248, 5, 13, 45, 251, 65, - 248, 5, 13, 50, 251, 65, 248, 5, 13, 45, 54, 251, 65, 248, 5, 13, 50, 54, - 251, 65, 248, 5, 13, 45, 64, 198, 37, 203, 98, 248, 5, 13, 50, 64, 198, - 37, 203, 98, 248, 5, 13, 45, 232, 163, 210, 103, 13, 50, 232, 163, 210, - 103, 196, 62, 208, 20, 55, 235, 75, 208, 20, 55, 251, 34, 231, 165, 242, - 219, 55, 242, 173, 231, 165, 242, 219, 55, 50, 63, 4, 47, 209, 73, 177, - 117, 55, 177, 96, 55, 177, 45, 50, 55, 177, 117, 54, 55, 177, 96, 54, 55, - 177, 45, 50, 54, 55, 177, 117, 63, 232, 60, 164, 177, 96, 63, 232, 60, - 164, 177, 117, 54, 63, 232, 60, 164, 177, 96, 54, 63, 232, 60, 164, 177, - 96, 201, 178, 55, 67, 68, 248, 84, 67, 68, 236, 93, 67, 68, 235, 221, 67, - 68, 236, 92, 67, 68, 235, 157, 67, 68, 236, 28, 67, 68, 235, 220, 67, 68, - 236, 91, 67, 68, 235, 125, 67, 68, 235, 252, 67, 68, 235, 188, 67, 68, - 236, 59, 67, 68, 235, 156, 67, 68, 236, 27, 67, 68, 235, 219, 67, 68, - 236, 90, 67, 68, 235, 109, 67, 68, 235, 236, 67, 68, 235, 172, 67, 68, - 236, 43, 67, 68, 235, 140, 67, 68, 236, 11, 67, 68, 235, 203, 67, 68, - 236, 74, 67, 68, 235, 124, 67, 68, 235, 251, 67, 68, 235, 187, 67, 68, - 236, 58, 67, 68, 235, 155, 67, 68, 236, 26, 67, 68, 235, 218, 67, 68, - 236, 89, 67, 68, 235, 101, 67, 68, 235, 228, 67, 68, 235, 164, 67, 68, - 236, 35, 67, 68, 235, 132, 67, 68, 236, 3, 67, 68, 235, 195, 67, 68, 236, - 66, 67, 68, 235, 116, 67, 68, 235, 243, 67, 68, 235, 179, 67, 68, 236, - 50, 67, 68, 235, 147, 67, 68, 236, 18, 67, 68, 235, 210, 67, 68, 236, 81, - 67, 68, 235, 108, 67, 68, 235, 235, 67, 68, 235, 171, 67, 68, 236, 42, - 67, 68, 235, 139, 67, 68, 236, 10, 67, 68, 235, 202, 67, 68, 236, 73, 67, - 68, 235, 123, 67, 68, 235, 250, 67, 68, 235, 186, 67, 68, 236, 57, 67, - 68, 235, 154, 67, 68, 236, 25, 67, 68, 235, 217, 67, 68, 236, 88, 67, 68, - 235, 97, 67, 68, 235, 224, 67, 68, 235, 160, 67, 68, 236, 31, 67, 68, - 235, 128, 67, 68, 235, 255, 67, 68, 235, 191, 67, 68, 236, 62, 67, 68, - 235, 112, 67, 68, 235, 239, 67, 68, 235, 175, 67, 68, 236, 46, 67, 68, - 235, 143, 67, 68, 236, 14, 67, 68, 235, 206, 67, 68, 236, 77, 67, 68, - 235, 104, 67, 68, 235, 231, 67, 68, 235, 167, 67, 68, 236, 38, 67, 68, - 235, 135, 67, 68, 236, 6, 67, 68, 235, 198, 67, 68, 236, 69, 67, 68, 235, - 119, 67, 68, 235, 246, 67, 68, 235, 182, 67, 68, 236, 53, 67, 68, 235, - 150, 67, 68, 236, 21, 67, 68, 235, 213, 67, 68, 236, 84, 67, 68, 235, - 100, 67, 68, 235, 227, 67, 68, 235, 163, 67, 68, 236, 34, 67, 68, 235, - 131, 67, 68, 236, 2, 67, 68, 235, 194, 67, 68, 236, 65, 67, 68, 235, 115, - 67, 68, 235, 242, 67, 68, 235, 178, 67, 68, 236, 49, 67, 68, 235, 146, - 67, 68, 236, 17, 67, 68, 235, 209, 67, 68, 236, 80, 67, 68, 235, 107, 67, - 68, 235, 234, 67, 68, 235, 170, 67, 68, 236, 41, 67, 68, 235, 138, 67, - 68, 236, 9, 67, 68, 235, 201, 67, 68, 236, 72, 67, 68, 235, 122, 67, 68, - 235, 249, 67, 68, 235, 185, 67, 68, 236, 56, 67, 68, 235, 153, 67, 68, - 236, 24, 67, 68, 235, 216, 67, 68, 236, 87, 67, 68, 235, 95, 67, 68, 235, - 222, 67, 68, 235, 158, 67, 68, 236, 29, 67, 68, 235, 126, 67, 68, 235, - 253, 67, 68, 235, 189, 67, 68, 236, 60, 67, 68, 235, 110, 67, 68, 235, - 237, 67, 68, 235, 173, 67, 68, 236, 44, 67, 68, 235, 141, 67, 68, 236, - 12, 67, 68, 235, 204, 67, 68, 236, 75, 67, 68, 235, 102, 67, 68, 235, - 229, 67, 68, 235, 165, 67, 68, 236, 36, 67, 68, 235, 133, 67, 68, 236, 4, - 67, 68, 235, 196, 67, 68, 236, 67, 67, 68, 235, 117, 67, 68, 235, 244, - 67, 68, 235, 180, 67, 68, 236, 51, 67, 68, 235, 148, 67, 68, 236, 19, 67, - 68, 235, 211, 67, 68, 236, 82, 67, 68, 235, 98, 67, 68, 235, 225, 67, 68, - 235, 161, 67, 68, 236, 32, 67, 68, 235, 129, 67, 68, 236, 0, 67, 68, 235, - 192, 67, 68, 236, 63, 67, 68, 235, 113, 67, 68, 235, 240, 67, 68, 235, - 176, 67, 68, 236, 47, 67, 68, 235, 144, 67, 68, 236, 15, 67, 68, 235, - 207, 67, 68, 236, 78, 67, 68, 235, 105, 67, 68, 235, 232, 67, 68, 235, - 168, 67, 68, 236, 39, 67, 68, 235, 136, 67, 68, 236, 7, 67, 68, 235, 199, - 67, 68, 236, 70, 67, 68, 235, 120, 67, 68, 235, 247, 67, 68, 235, 183, - 67, 68, 236, 54, 67, 68, 235, 151, 67, 68, 236, 22, 67, 68, 235, 214, 67, - 68, 236, 85, 67, 68, 235, 96, 67, 68, 235, 223, 67, 68, 235, 159, 67, 68, - 236, 30, 67, 68, 235, 127, 67, 68, 235, 254, 67, 68, 235, 190, 67, 68, - 236, 61, 67, 68, 235, 111, 67, 68, 235, 238, 67, 68, 235, 174, 67, 68, - 236, 45, 67, 68, 235, 142, 67, 68, 236, 13, 67, 68, 235, 205, 67, 68, - 236, 76, 67, 68, 235, 103, 67, 68, 235, 230, 67, 68, 235, 166, 67, 68, - 236, 37, 67, 68, 235, 134, 67, 68, 236, 5, 67, 68, 235, 197, 67, 68, 236, - 68, 67, 68, 235, 118, 67, 68, 235, 245, 67, 68, 235, 181, 67, 68, 236, - 52, 67, 68, 235, 149, 67, 68, 236, 20, 67, 68, 235, 212, 67, 68, 236, 83, - 67, 68, 235, 99, 67, 68, 235, 226, 67, 68, 235, 162, 67, 68, 236, 33, 67, - 68, 235, 130, 67, 68, 236, 1, 67, 68, 235, 193, 67, 68, 236, 64, 67, 68, - 235, 114, 67, 68, 235, 241, 67, 68, 235, 177, 67, 68, 236, 48, 67, 68, - 235, 145, 67, 68, 236, 16, 67, 68, 235, 208, 67, 68, 236, 79, 67, 68, - 235, 106, 67, 68, 235, 233, 67, 68, 235, 169, 67, 68, 236, 40, 67, 68, - 235, 137, 67, 68, 236, 8, 67, 68, 235, 200, 67, 68, 236, 71, 67, 68, 235, - 121, 67, 68, 235, 248, 67, 68, 235, 184, 67, 68, 236, 55, 67, 68, 235, - 152, 67, 68, 236, 23, 67, 68, 235, 215, 67, 68, 236, 86, 96, 197, 9, 63, - 4, 81, 105, 96, 197, 9, 63, 4, 54, 81, 105, 117, 54, 63, 4, 81, 105, 96, - 54, 63, 4, 81, 105, 45, 50, 54, 63, 4, 81, 105, 96, 197, 9, 63, 232, 60, - 164, 117, 54, 63, 232, 60, 164, 96, 54, 63, 232, 60, 164, 235, 75, 63, 4, - 228, 209, 105, 196, 62, 63, 4, 228, 209, 105, 196, 62, 197, 221, 55, 235, - 75, 197, 221, 55, 117, 54, 237, 171, 55, 96, 54, 237, 171, 55, 117, 197, - 221, 237, 171, 55, 96, 197, 221, 237, 171, 55, 96, 197, 9, 197, 221, 237, - 171, 55, 96, 63, 4, 235, 94, 201, 75, 196, 62, 63, 118, 164, 235, 75, 63, - 118, 164, 96, 63, 4, 199, 211, 4, 81, 105, 96, 63, 4, 199, 211, 4, 54, - 81, 105, 96, 197, 9, 63, 4, 199, 210, 96, 197, 9, 63, 4, 199, 211, 4, 81, - 105, 96, 197, 9, 63, 4, 199, 211, 4, 54, 81, 105, 117, 250, 187, 96, 250, - 187, 117, 54, 250, 187, 96, 54, 250, 187, 117, 63, 118, 62, 236, 243, 96, - 63, 118, 62, 236, 243, 117, 63, 232, 60, 249, 38, 118, 62, 236, 243, 96, - 63, 232, 60, 249, 38, 118, 62, 236, 243, 185, 193, 103, 24, 201, 253, - 234, 160, 55, 185, 234, 160, 24, 201, 253, 193, 103, 55, 185, 193, 103, - 63, 4, 106, 185, 234, 160, 63, 4, 106, 201, 253, 234, 160, 63, 4, 106, - 201, 253, 193, 103, 63, 4, 106, 185, 193, 103, 63, 24, 185, 234, 160, 55, - 185, 234, 160, 63, 24, 201, 253, 234, 160, 55, 201, 253, 234, 160, 63, - 24, 201, 253, 193, 103, 55, 201, 253, 193, 103, 63, 24, 185, 193, 103, - 55, 206, 175, 236, 250, 238, 163, 233, 42, 236, 249, 233, 42, 236, 250, - 238, 163, 206, 175, 236, 249, 201, 253, 234, 160, 63, 238, 163, 185, 234, - 160, 55, 185, 234, 160, 63, 238, 163, 201, 253, 234, 160, 55, 233, 42, - 236, 250, 238, 163, 185, 234, 160, 55, 206, 175, 236, 250, 238, 163, 201, - 253, 234, 160, 55, 185, 234, 160, 63, 238, 163, 185, 193, 103, 55, 185, - 193, 103, 63, 238, 163, 185, 234, 160, 55, 193, 137, 63, 209, 51, 236, - 186, 187, 63, 209, 51, 96, 199, 20, 238, 114, 196, 61, 63, 209, 51, 96, - 199, 20, 238, 114, 235, 74, 63, 209, 51, 235, 75, 199, 20, 238, 114, 219, - 190, 63, 209, 51, 235, 75, 199, 20, 238, 114, 206, 192, 206, 195, 250, - 223, 242, 173, 55, 219, 193, 250, 223, 251, 34, 55, 198, 49, 250, 223, - 251, 34, 55, 248, 29, 250, 223, 251, 34, 55, 198, 49, 250, 223, 242, 173, - 63, 4, 216, 17, 198, 49, 250, 223, 251, 34, 63, 4, 209, 73, 110, 50, 204, - 22, 242, 173, 55, 110, 45, 204, 22, 251, 34, 55, 251, 34, 242, 171, 242, - 219, 55, 242, 173, 242, 171, 242, 219, 55, 96, 63, 95, 203, 35, 117, 55, - 117, 63, 95, 203, 35, 96, 55, 203, 35, 96, 63, 95, 117, 55, 96, 63, 4, - 107, 60, 117, 63, 4, 107, 60, 96, 63, 198, 211, 192, 235, 45, 50, 63, - 198, 211, 2, 242, 218, 196, 62, 197, 9, 63, 232, 60, 2, 242, 218, 45, - 178, 132, 50, 178, 143, 229, 235, 45, 178, 143, 50, 178, 132, 229, 235, - 132, 178, 50, 143, 178, 45, 229, 235, 132, 178, 45, 143, 178, 50, 229, - 235, 45, 178, 132, 50, 178, 132, 229, 235, 132, 178, 50, 143, 178, 50, - 229, 235, 45, 178, 143, 50, 178, 143, 229, 235, 132, 178, 45, 143, 178, - 45, 229, 235, 117, 229, 236, 4, 178, 132, 118, 164, 96, 229, 236, 4, 178, - 132, 118, 164, 196, 62, 229, 236, 4, 178, 50, 118, 164, 235, 75, 229, - 236, 4, 178, 50, 118, 164, 117, 229, 236, 4, 178, 143, 118, 164, 96, 229, - 236, 4, 178, 143, 118, 164, 196, 62, 229, 236, 4, 178, 45, 118, 164, 235, - 75, 229, 236, 4, 178, 45, 118, 164, 117, 229, 236, 4, 178, 132, 232, 60, - 164, 96, 229, 236, 4, 178, 132, 232, 60, 164, 196, 62, 229, 236, 4, 178, - 50, 232, 60, 164, 235, 75, 229, 236, 4, 178, 50, 232, 60, 164, 117, 229, - 236, 4, 178, 143, 232, 60, 164, 96, 229, 236, 4, 178, 143, 232, 60, 164, - 196, 62, 229, 236, 4, 178, 45, 232, 60, 164, 235, 75, 229, 236, 4, 178, - 45, 232, 60, 164, 117, 229, 236, 4, 178, 132, 95, 117, 229, 236, 4, 178, - 235, 79, 196, 62, 229, 236, 4, 178, 45, 248, 166, 196, 62, 229, 236, 4, - 178, 187, 96, 229, 236, 4, 178, 132, 95, 96, 229, 236, 4, 178, 235, 79, - 235, 75, 229, 236, 4, 178, 45, 248, 166, 235, 75, 229, 236, 4, 178, 187, - 117, 229, 236, 4, 178, 132, 95, 96, 229, 236, 4, 178, 196, 73, 117, 229, - 236, 4, 178, 143, 95, 96, 229, 236, 4, 178, 235, 79, 96, 229, 236, 4, - 178, 132, 95, 117, 229, 236, 4, 178, 196, 73, 96, 229, 236, 4, 178, 143, - 95, 117, 229, 236, 4, 178, 235, 79, 117, 229, 236, 4, 178, 132, 95, 177, - 237, 170, 117, 229, 236, 4, 178, 143, 248, 183, 177, 237, 170, 96, 229, - 236, 4, 178, 132, 95, 177, 237, 170, 96, 229, 236, 4, 178, 143, 248, 183, - 177, 237, 170, 196, 62, 229, 236, 4, 178, 45, 248, 166, 235, 75, 229, - 236, 4, 178, 187, 235, 75, 229, 236, 4, 178, 45, 248, 166, 196, 62, 229, - 236, 4, 178, 187, 50, 54, 63, 4, 206, 108, 229, 203, 234, 1, 3, 95, 96, - 55, 198, 148, 211, 56, 95, 96, 55, 117, 63, 95, 198, 148, 211, 55, 96, - 63, 95, 198, 148, 211, 55, 96, 63, 95, 251, 114, 234, 3, 159, 219, 156, - 95, 117, 55, 117, 63, 198, 211, 219, 155, 230, 170, 95, 96, 55, 200, 224, - 95, 96, 55, 117, 63, 198, 211, 200, 223, 200, 176, 95, 117, 55, 45, 232, - 196, 199, 210, 50, 232, 196, 199, 210, 132, 232, 196, 199, 210, 143, 232, - 196, 199, 210, 197, 221, 81, 249, 38, 237, 67, 191, 167, 212, 253, 201, - 196, 191, 167, 212, 253, 196, 251, 242, 35, 45, 64, 238, 124, 248, 5, 50, - 64, 238, 124, 248, 5, 45, 64, 210, 103, 50, 64, 210, 103, 191, 167, 212, - 253, 45, 223, 150, 248, 5, 191, 167, 212, 253, 50, 223, 150, 248, 5, 191, - 167, 212, 253, 45, 248, 118, 248, 5, 191, 167, 212, 253, 50, 248, 118, - 248, 5, 45, 51, 248, 6, 4, 196, 99, 50, 51, 248, 6, 4, 196, 99, 45, 51, - 248, 6, 4, 198, 178, 223, 135, 198, 49, 238, 210, 50, 51, 248, 6, 4, 198, - 178, 223, 135, 248, 29, 238, 210, 45, 51, 248, 6, 4, 198, 178, 223, 135, - 248, 29, 238, 210, 50, 51, 248, 6, 4, 198, 178, 223, 135, 198, 49, 238, - 210, 45, 251, 65, 248, 6, 4, 236, 96, 50, 251, 65, 248, 6, 4, 236, 96, - 45, 250, 223, 219, 156, 248, 5, 50, 250, 223, 230, 170, 248, 5, 54, 45, - 250, 223, 230, 170, 248, 5, 54, 50, 250, 223, 219, 156, 248, 5, 45, 62, - 198, 37, 203, 98, 248, 5, 50, 62, 198, 37, 203, 98, 248, 5, 235, 94, 232, - 254, 81, 191, 21, 219, 88, 216, 207, 251, 65, 211, 58, 219, 200, 50, 251, - 65, 195, 165, 4, 201, 185, 216, 207, 50, 251, 65, 4, 236, 96, 251, 65, 4, - 206, 4, 223, 89, 251, 251, 251, 64, 201, 220, 251, 65, 211, 58, 219, 200, - 201, 220, 251, 65, 211, 58, 196, 73, 152, 251, 64, 207, 13, 251, 64, 251, - 65, 4, 196, 99, 207, 13, 251, 65, 4, 196, 99, 211, 159, 251, 65, 211, 58, - 196, 73, 211, 159, 251, 65, 211, 58, 235, 79, 216, 207, 251, 65, 4, 211, - 66, 250, 201, 234, 49, 223, 135, 63, 209, 51, 132, 24, 187, 216, 207, - 251, 65, 4, 211, 66, 250, 201, 234, 49, 223, 135, 63, 209, 51, 132, 24, - 219, 200, 216, 207, 251, 65, 4, 211, 66, 250, 201, 234, 49, 223, 135, 63, - 209, 51, 143, 24, 187, 216, 207, 251, 65, 4, 211, 66, 250, 201, 234, 49, - 223, 135, 63, 209, 51, 143, 24, 219, 200, 216, 207, 251, 65, 4, 211, 66, - 250, 201, 234, 49, 223, 135, 63, 209, 51, 50, 24, 196, 73, 216, 207, 251, - 65, 4, 211, 66, 250, 201, 234, 49, 223, 135, 63, 209, 51, 45, 24, 196, - 73, 216, 207, 251, 65, 4, 211, 66, 250, 201, 234, 49, 223, 135, 63, 209, - 51, 50, 24, 235, 79, 216, 207, 251, 65, 4, 211, 66, 250, 201, 234, 49, - 223, 135, 63, 209, 51, 45, 24, 235, 79, 207, 13, 234, 63, 203, 247, 234, - 63, 203, 248, 4, 210, 252, 234, 63, 203, 248, 4, 2, 242, 219, 56, 234, - 63, 203, 248, 4, 50, 63, 56, 234, 63, 203, 248, 4, 45, 63, 56, 242, 219, - 4, 228, 209, 164, 47, 81, 164, 47, 210, 108, 47, 207, 14, 202, 18, 47, - 209, 245, 242, 219, 236, 161, 247, 157, 228, 209, 249, 38, 24, 198, 49, - 134, 236, 161, 247, 157, 81, 164, 242, 219, 4, 200, 178, 192, 235, 47, - 251, 32, 236, 155, 57, 132, 63, 198, 211, 242, 218, 47, 64, 247, 200, 47, - 247, 200, 47, 219, 155, 47, 230, 169, 242, 219, 4, 2, 242, 219, 118, 199, - 29, 187, 242, 219, 4, 103, 228, 209, 201, 11, 118, 199, 29, 187, 112, - 206, 175, 236, 250, 202, 92, 112, 233, 42, 236, 250, 202, 92, 112, 250, - 143, 112, 2, 242, 218, 112, 201, 185, 103, 222, 171, 201, 183, 197, 238, - 4, 75, 56, 197, 238, 4, 196, 99, 206, 4, 223, 135, 197, 237, 197, 238, 4, - 203, 255, 250, 133, 248, 28, 50, 197, 238, 95, 45, 197, 237, 45, 197, - 238, 248, 166, 81, 164, 81, 249, 38, 248, 166, 50, 197, 237, 248, 16, 4, - 45, 134, 248, 91, 248, 16, 4, 50, 134, 248, 91, 62, 248, 15, 25, 4, 45, - 134, 248, 91, 25, 4, 50, 134, 248, 91, 64, 228, 143, 62, 228, 143, 45, - 193, 70, 232, 254, 50, 193, 70, 232, 254, 45, 54, 193, 70, 232, 254, 50, - 54, 193, 70, 232, 254, 223, 127, 223, 111, 198, 174, 138, 223, 111, 223, - 112, 214, 94, 4, 81, 164, 235, 88, 215, 116, 51, 4, 238, 234, 211, 1, - 223, 124, 250, 169, 202, 249, 208, 193, 234, 1, 3, 24, 202, 94, 210, 108, - 234, 1, 3, 24, 202, 94, 210, 109, 4, 198, 148, 56, 227, 244, 118, 24, - 202, 94, 210, 108, 230, 234, 201, 96, 199, 17, 235, 78, 197, 238, 4, 45, - 134, 248, 91, 235, 78, 197, 238, 4, 50, 134, 248, 91, 62, 236, 244, 4, - 143, 55, 62, 218, 210, 64, 242, 219, 4, 143, 55, 62, 242, 219, 4, 143, - 55, 233, 239, 64, 201, 185, 233, 239, 62, 201, 185, 233, 239, 64, 236, - 243, 233, 239, 62, 236, 243, 233, 239, 64, 242, 218, 233, 239, 62, 242, - 218, 206, 46, 207, 14, 202, 19, 211, 55, 202, 19, 4, 210, 252, 207, 14, - 202, 19, 4, 228, 209, 105, 248, 127, 202, 18, 248, 127, 207, 14, 202, 18, - 54, 209, 73, 197, 221, 209, 73, 219, 195, 238, 116, 251, 65, 248, 5, 206, - 198, 238, 116, 251, 65, 248, 5, 198, 132, 216, 15, 215, 46, 47, 75, 211, - 55, 215, 46, 47, 107, 211, 55, 215, 46, 47, 25, 211, 55, 215, 46, 196, - 89, 211, 56, 4, 236, 96, 215, 46, 196, 89, 211, 56, 4, 209, 73, 215, 46, - 51, 223, 72, 211, 55, 215, 46, 51, 196, 89, 211, 55, 103, 219, 5, 24, - 211, 55, 103, 219, 5, 211, 46, 211, 55, 215, 46, 25, 211, 55, 215, 219, - 103, 200, 199, 200, 197, 4, 223, 85, 208, 20, 223, 86, 211, 55, 232, 205, - 210, 97, 223, 85, 223, 86, 4, 54, 105, 223, 86, 250, 93, 4, 202, 92, 242, - 211, 232, 39, 251, 34, 223, 83, 219, 89, 223, 84, 4, 207, 86, 210, 76, - 250, 195, 209, 45, 219, 89, 223, 84, 4, 204, 22, 210, 76, 250, 195, 209, - 45, 219, 89, 223, 84, 212, 255, 223, 129, 199, 29, 209, 45, 223, 86, 250, - 195, 41, 209, 55, 211, 55, 208, 14, 223, 86, 211, 55, 223, 86, 4, 117, - 63, 4, 106, 223, 86, 4, 25, 57, 223, 86, 4, 223, 71, 223, 86, 4, 196, 88, - 223, 86, 4, 210, 252, 223, 86, 4, 196, 99, 222, 172, 219, 245, 45, 197, - 238, 211, 55, 191, 167, 212, 253, 205, 87, 239, 14, 191, 167, 212, 253, - 205, 87, 209, 118, 191, 167, 212, 253, 205, 87, 208, 188, 107, 3, 4, 2, - 242, 219, 56, 107, 3, 4, 242, 210, 252, 9, 56, 107, 3, 4, 198, 148, 56, - 107, 3, 4, 75, 60, 107, 3, 4, 198, 148, 60, 107, 3, 4, 200, 225, 109, - 107, 3, 4, 62, 197, 237, 216, 18, 3, 4, 242, 27, 56, 216, 18, 3, 4, 75, - 60, 216, 18, 3, 4, 233, 42, 236, 94, 216, 18, 3, 4, 206, 175, 236, 94, - 107, 3, 223, 135, 45, 134, 242, 218, 107, 3, 223, 135, 50, 134, 242, 218, - 195, 149, 211, 46, 238, 171, 208, 193, 215, 112, 3, 4, 75, 56, 215, 112, - 3, 4, 196, 99, 204, 19, 208, 194, 4, 248, 29, 242, 170, 202, 63, 208, - 193, 215, 112, 3, 223, 135, 45, 134, 242, 218, 215, 112, 3, 223, 135, 50, - 134, 242, 218, 47, 215, 112, 3, 4, 242, 210, 252, 8, 215, 112, 3, 223, - 135, 54, 242, 218, 47, 236, 155, 57, 107, 3, 223, 135, 197, 237, 216, 18, - 3, 223, 135, 197, 237, 215, 112, 3, 223, 135, 197, 237, 223, 80, 208, - 193, 206, 193, 223, 80, 208, 193, 191, 167, 212, 253, 207, 59, 239, 14, - 251, 96, 211, 46, 238, 218, 223, 72, 4, 236, 96, 196, 89, 4, 216, 18, 57, - 196, 89, 4, 210, 252, 223, 72, 4, 210, 252, 223, 72, 4, 219, 5, 251, 74, - 196, 89, 4, 219, 5, 211, 45, 196, 89, 95, 223, 71, 223, 72, 95, 196, 88, - 196, 89, 95, 249, 38, 95, 223, 71, 223, 72, 95, 249, 38, 95, 196, 88, - 196, 89, 248, 166, 24, 222, 171, 4, 196, 88, 223, 72, 248, 166, 24, 222, - 171, 4, 223, 71, 242, 171, 196, 89, 4, 203, 254, 242, 171, 223, 72, 4, - 203, 254, 54, 51, 223, 71, 54, 51, 196, 88, 242, 171, 196, 89, 4, 203, - 255, 24, 202, 63, 208, 193, 219, 5, 24, 4, 75, 56, 219, 5, 211, 46, 4, - 75, 56, 54, 219, 5, 251, 74, 54, 219, 5, 211, 45, 103, 223, 73, 219, 5, - 251, 74, 103, 223, 73, 219, 5, 211, 45, 202, 75, 219, 245, 211, 45, 202, - 75, 219, 245, 251, 74, 219, 5, 211, 46, 210, 247, 219, 5, 251, 74, 219, - 5, 24, 4, 82, 201, 75, 219, 5, 211, 46, 4, 82, 201, 75, 219, 5, 24, 4, - 228, 209, 237, 170, 219, 5, 211, 46, 4, 228, 209, 237, 170, 219, 5, 24, - 4, 54, 210, 252, 219, 5, 24, 4, 196, 99, 219, 5, 24, 4, 54, 196, 99, 2, - 195, 146, 4, 196, 99, 219, 5, 211, 46, 4, 54, 210, 252, 219, 5, 211, 46, - 4, 54, 196, 99, 191, 167, 212, 253, 236, 107, 251, 24, 191, 167, 212, - 253, 207, 132, 251, 24, 234, 1, 3, 4, 75, 60, 227, 244, 4, 75, 56, 197, - 221, 228, 209, 249, 38, 4, 54, 81, 105, 197, 221, 228, 209, 249, 38, 4, - 197, 221, 81, 105, 198, 148, 211, 56, 4, 75, 56, 198, 148, 211, 56, 4, - 206, 175, 236, 94, 202, 175, 216, 18, 202, 174, 239, 1, 4, 75, 56, 234, - 1, 4, 250, 143, 251, 114, 234, 3, 118, 4, 242, 210, 252, 8, 250, 246, - 234, 3, 211, 46, 234, 3, 159, 234, 1, 3, 95, 107, 57, 107, 3, 95, 234, 1, - 57, 234, 1, 3, 95, 198, 148, 211, 55, 54, 242, 36, 234, 2, 103, 238, 250, - 234, 1, 202, 189, 115, 238, 250, 234, 1, 202, 189, 234, 1, 3, 4, 103, - 183, 95, 24, 103, 183, 60, 233, 250, 4, 232, 90, 183, 56, 219, 156, 4, - 242, 219, 223, 89, 230, 170, 4, 242, 219, 223, 89, 219, 156, 4, 208, 8, - 87, 56, 230, 170, 4, 208, 8, 87, 56, 219, 156, 211, 46, 202, 94, 234, 3, - 159, 230, 170, 211, 46, 202, 94, 234, 3, 159, 219, 156, 211, 46, 202, 94, - 234, 3, 118, 4, 75, 223, 89, 230, 170, 211, 46, 202, 94, 234, 3, 118, 4, - 75, 223, 89, 219, 156, 211, 46, 202, 94, 234, 3, 118, 4, 75, 56, 230, - 170, 211, 46, 202, 94, 234, 3, 118, 4, 75, 56, 219, 156, 211, 46, 202, - 94, 234, 3, 118, 4, 75, 95, 187, 230, 170, 211, 46, 202, 94, 234, 3, 118, - 4, 75, 95, 219, 200, 219, 156, 211, 46, 250, 247, 230, 170, 211, 46, 250, - 247, 219, 156, 24, 202, 163, 212, 255, 234, 3, 159, 230, 170, 24, 202, - 163, 212, 255, 234, 3, 159, 219, 156, 24, 212, 255, 250, 247, 230, 170, - 24, 212, 255, 250, 247, 219, 156, 95, 235, 87, 234, 3, 95, 230, 169, 230, - 170, 95, 235, 87, 234, 3, 95, 219, 155, 219, 156, 95, 202, 175, 211, 46, - 234, 2, 230, 170, 95, 202, 175, 211, 46, 234, 2, 219, 156, 95, 202, 175, - 95, 230, 169, 230, 170, 95, 202, 175, 95, 219, 155, 219, 156, 95, 230, - 170, 95, 235, 87, 234, 2, 230, 170, 95, 219, 156, 95, 235, 87, 234, 2, - 219, 156, 95, 202, 94, 234, 3, 95, 230, 170, 95, 202, 94, 234, 2, 230, - 170, 95, 202, 94, 234, 3, 95, 219, 156, 95, 202, 94, 234, 2, 202, 94, - 234, 3, 118, 211, 46, 219, 155, 202, 94, 234, 3, 118, 211, 46, 230, 169, - 202, 94, 234, 3, 118, 211, 46, 219, 156, 4, 75, 223, 89, 202, 94, 234, 3, - 118, 211, 46, 230, 170, 4, 75, 223, 89, 235, 87, 234, 3, 118, 211, 46, - 219, 155, 235, 87, 234, 3, 118, 211, 46, 230, 169, 235, 87, 202, 94, 234, - 3, 118, 211, 46, 219, 155, 235, 87, 202, 94, 234, 3, 118, 211, 46, 230, - 169, 202, 175, 211, 46, 219, 155, 202, 175, 211, 46, 230, 169, 202, 175, - 95, 219, 156, 95, 234, 1, 57, 202, 175, 95, 230, 170, 95, 234, 1, 57, 54, - 214, 74, 219, 155, 54, 214, 74, 230, 169, 54, 214, 74, 219, 156, 4, 196, - 99, 230, 170, 210, 247, 219, 155, 230, 170, 248, 166, 219, 155, 219, 156, - 242, 171, 247, 157, 238, 117, 230, 170, 242, 171, 247, 157, 238, 117, - 219, 156, 242, 171, 247, 157, 238, 118, 95, 202, 94, 234, 2, 230, 170, - 242, 171, 247, 157, 238, 118, 95, 202, 94, 234, 2, 202, 64, 199, 33, 219, - 243, 199, 33, 202, 64, 199, 34, 211, 46, 234, 3, 159, 219, 243, 199, 34, - 211, 46, 234, 3, 159, 234, 1, 3, 4, 247, 193, 56, 208, 225, 95, 202, 163, - 234, 1, 57, 200, 216, 95, 202, 163, 234, 1, 57, 208, 225, 95, 202, 163, - 212, 255, 234, 3, 159, 200, 216, 95, 202, 163, 212, 255, 234, 3, 159, - 208, 225, 95, 234, 1, 57, 200, 216, 95, 234, 1, 57, 208, 225, 95, 212, - 255, 234, 3, 159, 200, 216, 95, 212, 255, 234, 3, 159, 208, 225, 95, 251, - 114, 234, 3, 159, 200, 216, 95, 251, 114, 234, 3, 159, 208, 225, 95, 212, - 255, 251, 114, 234, 3, 159, 200, 216, 95, 212, 255, 251, 114, 234, 3, - 159, 54, 208, 224, 54, 200, 215, 200, 224, 4, 236, 96, 200, 176, 4, 236, - 96, 200, 224, 4, 107, 3, 60, 200, 176, 4, 107, 3, 60, 200, 224, 4, 215, - 112, 3, 60, 200, 176, 4, 215, 112, 3, 60, 200, 224, 80, 211, 46, 234, 3, - 118, 4, 75, 56, 200, 176, 80, 211, 46, 234, 3, 118, 4, 75, 56, 200, 224, - 80, 95, 234, 1, 57, 200, 176, 80, 95, 234, 1, 57, 200, 224, 80, 95, 198, - 148, 211, 55, 200, 176, 80, 95, 198, 148, 211, 55, 200, 224, 80, 95, 251, - 114, 234, 3, 159, 200, 176, 80, 95, 251, 114, 234, 3, 159, 200, 224, 80, - 95, 212, 255, 234, 3, 159, 200, 176, 80, 95, 212, 255, 234, 3, 159, 51, - 45, 211, 66, 111, 211, 55, 51, 50, 211, 66, 111, 211, 55, 242, 171, 200, - 223, 242, 171, 200, 175, 242, 171, 200, 224, 211, 46, 234, 3, 159, 242, - 171, 200, 176, 211, 46, 234, 3, 159, 200, 224, 95, 200, 175, 200, 176, - 95, 200, 223, 200, 224, 95, 200, 223, 200, 176, 95, 200, 175, 200, 176, - 248, 166, 200, 223, 200, 176, 248, 166, 24, 222, 171, 247, 157, 237, 171, - 4, 200, 223, 234, 89, 80, 211, 58, 235, 74, 209, 108, 4, 199, 117, 198, - 48, 198, 3, 223, 71, 232, 108, 213, 14, 203, 35, 45, 199, 223, 203, 35, - 143, 199, 223, 203, 35, 132, 199, 223, 209, 246, 4, 206, 3, 81, 249, 38, - 197, 221, 50, 197, 53, 54, 81, 249, 38, 45, 197, 53, 81, 249, 38, 54, 45, - 197, 53, 54, 81, 249, 38, 54, 45, 197, 53, 177, 237, 171, 232, 60, 45, - 216, 172, 80, 54, 195, 132, 203, 35, 143, 199, 224, 4, 210, 252, 203, 35, - 132, 199, 224, 4, 196, 99, 203, 35, 132, 199, 224, 95, 203, 35, 143, 199, - 223, 54, 143, 199, 223, 54, 132, 199, 223, 54, 201, 23, 212, 255, 57, - 207, 13, 54, 201, 23, 212, 255, 57, 236, 119, 212, 255, 236, 163, 4, 207, - 13, 214, 93, 202, 92, 81, 219, 89, 4, 242, 219, 56, 81, 219, 89, 4, 242, - 219, 60, 143, 199, 224, 4, 242, 219, 60, 210, 109, 4, 228, 209, 105, 210, - 109, 4, 198, 148, 211, 55, 197, 221, 81, 249, 38, 248, 120, 207, 60, 197, - 221, 81, 249, 38, 4, 228, 209, 105, 197, 221, 242, 36, 211, 55, 197, 221, - 214, 74, 219, 155, 197, 221, 214, 74, 230, 169, 235, 87, 202, 94, 219, - 156, 211, 46, 234, 3, 159, 235, 87, 202, 94, 230, 170, 211, 46, 234, 3, - 159, 197, 221, 202, 19, 248, 120, 207, 60, 219, 245, 197, 221, 81, 249, - 38, 211, 55, 54, 202, 19, 211, 55, 64, 81, 164, 215, 46, 64, 81, 164, - 185, 234, 160, 64, 55, 185, 193, 103, 64, 55, 201, 253, 234, 160, 64, 55, - 201, 253, 193, 103, 64, 55, 45, 50, 64, 55, 117, 62, 55, 196, 62, 62, 55, - 235, 75, 62, 55, 185, 234, 160, 62, 55, 185, 193, 103, 62, 55, 201, 253, - 234, 160, 62, 55, 201, 253, 193, 103, 62, 55, 45, 50, 62, 55, 132, 143, - 62, 55, 96, 63, 4, 198, 131, 235, 74, 96, 63, 4, 198, 131, 196, 61, 117, - 63, 4, 198, 131, 235, 74, 117, 63, 4, 198, 131, 196, 61, 51, 4, 198, 49, - 134, 248, 91, 51, 4, 248, 29, 134, 248, 91, 51, 4, 116, 50, 236, 250, - 134, 248, 91, 51, 4, 110, 45, 236, 250, 134, 248, 91, 236, 244, 4, 45, - 134, 248, 91, 236, 244, 4, 50, 134, 248, 91, 236, 244, 4, 198, 49, 134, - 248, 91, 236, 244, 4, 248, 29, 134, 248, 91, 235, 94, 201, 185, 62, 219, - 245, 201, 185, 64, 219, 245, 201, 185, 62, 195, 80, 2, 201, 185, 64, 195, - 80, 2, 201, 185, 62, 210, 15, 64, 210, 15, 64, 229, 150, 62, 229, 150, - 228, 209, 62, 229, 150, 62, 219, 245, 242, 218, 62, 216, 194, 236, 243, - 64, 216, 194, 236, 243, 62, 216, 194, 218, 210, 64, 216, 194, 218, 210, - 62, 2, 236, 243, 62, 2, 218, 210, 64, 2, 218, 210, 62, 228, 209, 234, 79, - 64, 228, 209, 234, 79, 62, 81, 234, 79, 64, 81, 234, 79, 45, 63, 4, 2, - 242, 218, 115, 117, 250, 181, 45, 63, 4, 47, 209, 73, 177, 117, 201, 178, - 55, 117, 197, 9, 63, 4, 81, 105, 117, 197, 9, 63, 4, 54, 81, 105, 117, - 197, 9, 63, 232, 60, 164, 117, 197, 9, 197, 221, 237, 171, 55, 117, 63, - 4, 235, 94, 201, 75, 117, 63, 4, 199, 211, 4, 81, 105, 117, 63, 4, 199, - 211, 4, 54, 81, 105, 117, 197, 9, 63, 4, 199, 210, 117, 197, 9, 63, 4, - 199, 211, 4, 81, 105, 117, 197, 9, 63, 4, 199, 211, 4, 54, 81, 105, 117, - 63, 198, 211, 192, 235, 193, 137, 63, 209, 51, 236, 186, 219, 200, 234, - 1, 3, 95, 117, 55, 207, 14, 198, 148, 211, 56, 95, 117, 55, 117, 63, 95, - 207, 14, 251, 114, 234, 3, 159, 96, 63, 198, 211, 230, 169, 96, 63, 198, - 211, 200, 175, 117, 208, 20, 55, 96, 208, 20, 55, 207, 14, 198, 148, 211, - 56, 95, 96, 55, 96, 63, 95, 207, 14, 251, 114, 234, 3, 159, 198, 148, - 211, 56, 95, 117, 55, 117, 63, 95, 251, 114, 234, 3, 159, 117, 63, 95, - 207, 14, 198, 148, 211, 55, 96, 63, 95, 207, 14, 198, 148, 211, 55, 235, - 75, 197, 236, 191, 21, 55, 203, 35, 202, 94, 185, 55, 203, 35, 249, 93, - 201, 253, 55, 64, 216, 194, 201, 97, 62, 2, 201, 97, 64, 2, 201, 97, 62, - 206, 198, 210, 15, 64, 206, 198, 210, 15, 88, 219, 245, 242, 218, 88, - 210, 254, 4, 210, 254, 223, 89, 88, 242, 219, 4, 242, 219, 223, 89, 88, - 242, 218, 88, 47, 205, 149, 202, 94, 185, 63, 4, 228, 218, 229, 203, 249, - 93, 201, 253, 63, 4, 228, 218, 199, 210, 202, 94, 185, 63, 4, 228, 209, - 199, 210, 249, 93, 201, 253, 63, 4, 228, 209, 199, 210, 248, 174, 63, - 209, 51, 235, 75, 199, 20, 185, 234, 159, 203, 35, 248, 174, 63, 209, 51, - 235, 75, 199, 20, 185, 234, 159, 117, 197, 236, 55, 196, 62, 197, 236, - 55, 96, 197, 236, 55, 235, 75, 197, 236, 55, 45, 50, 197, 236, 55, 132, - 143, 197, 236, 55, 185, 193, 103, 197, 236, 55, 185, 234, 160, 197, 236, - 55, 201, 253, 234, 160, 197, 236, 55, 201, 253, 193, 103, 197, 236, 55, - 117, 197, 236, 237, 169, 55, 196, 62, 197, 236, 237, 169, 55, 96, 197, - 236, 237, 169, 55, 235, 75, 197, 236, 237, 169, 55, 242, 173, 197, 236, - 211, 66, 242, 219, 55, 251, 34, 197, 236, 211, 66, 242, 219, 55, 117, - 197, 236, 63, 118, 164, 196, 62, 197, 236, 63, 118, 164, 96, 197, 236, - 63, 118, 164, 235, 75, 197, 236, 63, 118, 164, 185, 193, 103, 197, 236, - 63, 118, 164, 185, 234, 160, 197, 236, 63, 118, 164, 201, 253, 234, 160, - 197, 236, 63, 118, 164, 201, 253, 193, 103, 197, 236, 63, 118, 164, 117, - 197, 236, 63, 4, 54, 228, 209, 105, 196, 62, 197, 236, 63, 4, 54, 228, - 209, 105, 96, 197, 236, 63, 4, 54, 228, 209, 105, 235, 75, 197, 236, 63, - 4, 54, 228, 209, 105, 228, 209, 199, 232, 221, 197, 81, 199, 232, 221, - 197, 117, 197, 236, 63, 138, 96, 197, 236, 55, 196, 62, 197, 236, 63, - 117, 80, 235, 75, 197, 236, 55, 96, 197, 236, 63, 138, 117, 197, 236, 55, - 235, 75, 197, 236, 63, 117, 80, 196, 62, 197, 236, 55, 117, 197, 236, - 210, 186, 250, 181, 196, 62, 197, 236, 210, 186, 250, 181, 96, 197, 236, - 210, 186, 250, 181, 235, 75, 197, 236, 210, 186, 250, 181, 117, 62, 47, - 64, 55, 196, 62, 62, 47, 64, 55, 96, 62, 47, 64, 55, 235, 75, 62, 47, 64, - 55, 251, 34, 197, 236, 50, 196, 217, 55, 251, 34, 197, 236, 248, 29, 196, - 217, 55, 251, 34, 197, 236, 45, 196, 217, 55, 251, 34, 197, 236, 198, 49, - 196, 217, 55, 207, 18, 219, 200, 207, 18, 187, 214, 63, 219, 200, 214, - 63, 187, 232, 90, 238, 211, 250, 182, 242, 214, 251, 33, 96, 62, 55, 16, - 39, 196, 251, 41, 234, 90, 198, 220, 198, 47, 117, 233, 251, 250, 185, - 198, 220, 206, 199, 196, 62, 233, 251, 250, 185, 198, 220, 198, 47, 96, - 233, 251, 250, 185, 198, 220, 219, 196, 235, 75, 233, 251, 250, 185, 62, - 117, 233, 251, 250, 185, 62, 196, 62, 233, 251, 250, 185, 62, 96, 233, - 251, 250, 185, 62, 235, 75, 233, 251, 250, 185, 235, 75, 197, 236, 63, 4, - 177, 198, 131, 219, 190, 235, 75, 197, 236, 63, 4, 177, 198, 131, 206, - 192, 196, 62, 197, 236, 63, 4, 177, 198, 131, 219, 190, 196, 62, 197, - 236, 63, 4, 177, 198, 131, 206, 192, 117, 197, 236, 63, 4, 177, 198, 131, - 196, 61, 96, 197, 236, 63, 4, 177, 198, 131, 196, 61, 117, 197, 236, 63, - 4, 177, 198, 131, 235, 74, 96, 197, 236, 63, 4, 177, 198, 131, 235, 74, - 62, 238, 116, 235, 75, 24, 117, 55, 62, 238, 116, 235, 75, 24, 96, 55, - 62, 238, 116, 196, 62, 24, 117, 55, 62, 238, 116, 196, 62, 24, 96, 55, - 62, 238, 116, 117, 24, 196, 62, 55, 62, 238, 116, 96, 24, 196, 62, 55, - 62, 238, 116, 117, 24, 235, 75, 55, 62, 238, 116, 96, 24, 235, 75, 55, - 206, 243, 63, 143, 219, 200, 206, 243, 63, 143, 187, 206, 243, 63, 132, - 219, 200, 206, 243, 63, 132, 187, 206, 243, 63, 45, 196, 73, 206, 243, - 63, 50, 196, 73, 206, 243, 63, 45, 235, 79, 206, 243, 63, 50, 235, 79, - 196, 62, 64, 63, 232, 60, 249, 38, 4, 228, 209, 164, 132, 250, 186, 223, - 135, 41, 207, 88, 248, 14, 210, 247, 64, 201, 183, 210, 247, 64, 24, 62, - 201, 183, 210, 247, 62, 201, 183, 249, 57, 111, 4, 155, 192, 235, 47, - 192, 235, 47, 28, 192, 235, 62, 51, 246, 227, 62, 236, 244, 246, 227, - 152, 62, 210, 15, 228, 209, 62, 211, 148, 62, 211, 148, 62, 216, 194, - 196, 72, 197, 238, 246, 227, 62, 216, 194, 235, 78, 197, 238, 246, 227, - 62, 216, 194, 219, 195, 197, 238, 246, 227, 62, 216, 194, 206, 198, 197, - 238, 246, 227, 214, 81, 232, 107, 109, 198, 49, 134, 62, 242, 218, 248, - 29, 134, 62, 242, 218, 155, 232, 90, 209, 53, 62, 238, 112, 206, 117, - 155, 232, 90, 209, 53, 62, 238, 112, 64, 232, 90, 209, 53, 238, 112, 206, - 117, 64, 232, 90, 209, 53, 238, 112, 51, 209, 18, 223, 116, 196, 103, 57, - 230, 154, 77, 209, 70, 232, 107, 109, 209, 70, 232, 107, 139, 209, 70, - 232, 107, 137, 209, 70, 232, 107, 153, 198, 5, 208, 178, 250, 139, 228, - 61, 209, 187, 214, 77, 64, 215, 189, 204, 28, 62, 236, 244, 211, 94, 238, - 170, 197, 198, 155, 215, 189, 250, 177, 238, 132, 230, 55, 191, 75, 220, - 234, 251, 3, 251, 236, 193, 244, 209, 19, 45, 134, 62, 201, 97, 50, 134, - 62, 201, 97, 201, 98, 4, 45, 134, 248, 91, 201, 98, 4, 50, 134, 248, 91, - 117, 197, 9, 63, 4, 197, 238, 250, 183, 196, 62, 197, 9, 63, 4, 197, 238, - 250, 183, 96, 197, 9, 63, 4, 197, 238, 250, 183, 235, 75, 197, 9, 63, 4, - 197, 238, 250, 183, 233, 241, 232, 107, 108, 233, 241, 232, 107, 109, - 205, 46, 206, 26, 250, 138, 16, 195, 49, 206, 26, 250, 138, 16, 212, 241, - 206, 26, 250, 138, 16, 207, 252, 206, 26, 250, 138, 16, 248, 115, 206, - 26, 250, 138, 16, 204, 11, 206, 26, 250, 138, 16, 197, 252, 234, 1, 3, 4, - 223, 112, 60, 196, 85, 113, 204, 7, 113, 235, 84, 113, 210, 86, 113, 207, - 13, 50, 251, 64, 229, 171, 210, 68, 113, 133, 6, 1, 250, 72, 133, 6, 1, - 247, 204, 133, 6, 1, 195, 148, 133, 6, 1, 230, 238, 133, 6, 1, 236, 124, - 133, 6, 1, 192, 49, 133, 6, 1, 191, 55, 133, 6, 1, 234, 242, 133, 6, 1, - 191, 82, 133, 6, 1, 223, 11, 133, 6, 1, 89, 223, 11, 133, 6, 1, 70, 133, - 6, 1, 236, 145, 133, 6, 1, 222, 67, 133, 6, 1, 219, 51, 133, 6, 1, 215, - 52, 133, 6, 1, 214, 196, 133, 6, 1, 211, 78, 133, 6, 1, 209, 48, 133, 6, - 1, 206, 174, 133, 6, 1, 202, 72, 133, 6, 1, 197, 40, 133, 6, 1, 196, 120, - 133, 6, 1, 232, 63, 133, 6, 1, 229, 156, 133, 6, 1, 211, 10, 133, 6, 1, - 210, 53, 133, 6, 1, 203, 3, 133, 6, 1, 197, 142, 133, 6, 1, 243, 6, 133, - 6, 1, 203, 160, 133, 6, 1, 192, 58, 133, 6, 1, 192, 60, 133, 6, 1, 192, - 93, 133, 6, 1, 201, 215, 144, 133, 6, 1, 191, 225, 133, 6, 1, 2, 191, - 190, 133, 6, 1, 2, 191, 191, 4, 199, 210, 133, 6, 1, 192, 12, 133, 6, 1, - 223, 54, 2, 191, 190, 133, 6, 1, 248, 127, 191, 190, 133, 6, 1, 223, 54, - 248, 127, 191, 190, 133, 6, 1, 232, 187, 133, 6, 1, 223, 9, 133, 6, 1, - 203, 2, 133, 6, 1, 197, 211, 65, 133, 6, 1, 219, 233, 215, 52, 133, 6, 1, - 247, 25, 243, 6, 133, 2, 1, 250, 72, 133, 2, 1, 247, 204, 133, 2, 1, 195, - 148, 133, 2, 1, 230, 238, 133, 2, 1, 236, 124, 133, 2, 1, 192, 49, 133, - 2, 1, 191, 55, 133, 2, 1, 234, 242, 133, 2, 1, 191, 82, 133, 2, 1, 223, - 11, 133, 2, 1, 89, 223, 11, 133, 2, 1, 70, 133, 2, 1, 236, 145, 133, 2, - 1, 222, 67, 133, 2, 1, 219, 51, 133, 2, 1, 215, 52, 133, 2, 1, 214, 196, - 133, 2, 1, 211, 78, 133, 2, 1, 209, 48, 133, 2, 1, 206, 174, 133, 2, 1, - 202, 72, 133, 2, 1, 197, 40, 133, 2, 1, 196, 120, 133, 2, 1, 232, 63, - 133, 2, 1, 229, 156, 133, 2, 1, 211, 10, 133, 2, 1, 210, 53, 133, 2, 1, - 203, 3, 133, 2, 1, 197, 142, 133, 2, 1, 243, 6, 133, 2, 1, 203, 160, 133, - 2, 1, 192, 58, 133, 2, 1, 192, 60, 133, 2, 1, 192, 93, 133, 2, 1, 201, - 215, 144, 133, 2, 1, 191, 225, 133, 2, 1, 2, 191, 190, 133, 2, 1, 2, 191, - 191, 4, 199, 210, 133, 2, 1, 192, 12, 133, 2, 1, 223, 54, 2, 191, 190, - 133, 2, 1, 248, 127, 191, 190, 133, 2, 1, 223, 54, 248, 127, 191, 190, - 133, 2, 1, 232, 187, 133, 2, 1, 223, 9, 133, 2, 1, 203, 2, 133, 2, 1, - 197, 211, 65, 133, 2, 1, 219, 233, 215, 52, 133, 2, 1, 247, 25, 243, 6, - 8, 6, 1, 220, 119, 4, 54, 164, 8, 2, 1, 220, 119, 4, 54, 164, 8, 6, 1, - 220, 119, 4, 82, 198, 147, 8, 6, 1, 210, 227, 4, 105, 8, 6, 1, 207, 217, - 4, 199, 210, 8, 2, 1, 41, 4, 105, 8, 2, 1, 200, 40, 4, 236, 250, 105, 8, - 6, 1, 230, 84, 4, 237, 42, 8, 2, 1, 230, 84, 4, 237, 42, 8, 6, 1, 222, - 126, 4, 237, 42, 8, 2, 1, 222, 126, 4, 237, 42, 8, 6, 1, 191, 167, 4, - 237, 42, 8, 2, 1, 191, 167, 4, 237, 42, 8, 6, 1, 251, 109, 8, 6, 1, 218, - 148, 4, 106, 8, 6, 1, 152, 65, 8, 6, 1, 152, 251, 109, 8, 2, 1, 196, 9, - 4, 50, 106, 8, 6, 1, 193, 222, 4, 106, 8, 2, 1, 193, 222, 4, 106, 8, 2, - 1, 196, 9, 4, 238, 128, 8, 6, 1, 134, 230, 83, 8, 2, 1, 134, 230, 83, 8, - 2, 1, 199, 208, 209, 202, 8, 2, 1, 234, 227, 4, 212, 252, 8, 2, 1, 152, - 207, 217, 4, 199, 210, 8, 2, 1, 186, 4, 131, 206, 184, 223, 89, 8, 1, 2, - 6, 152, 73, 8, 200, 225, 2, 1, 223, 7, 59, 1, 6, 196, 8, 8, 6, 1, 206, 4, - 4, 200, 142, 199, 210, 8, 6, 1, 191, 167, 4, 200, 142, 199, 210, 93, 6, - 1, 251, 135, 93, 2, 1, 251, 135, 93, 6, 1, 195, 63, 93, 2, 1, 195, 63, - 93, 6, 1, 231, 174, 93, 2, 1, 231, 174, 93, 6, 1, 237, 208, 93, 2, 1, - 237, 208, 93, 6, 1, 234, 122, 93, 2, 1, 234, 122, 93, 6, 1, 202, 2, 93, - 2, 1, 202, 2, 93, 6, 1, 191, 95, 93, 2, 1, 191, 95, 93, 6, 1, 229, 229, - 93, 2, 1, 229, 229, 93, 6, 1, 199, 8, 93, 2, 1, 199, 8, 93, 6, 1, 228, 2, - 93, 2, 1, 228, 2, 93, 6, 1, 222, 51, 93, 2, 1, 222, 51, 93, 6, 1, 219, - 228, 93, 2, 1, 219, 228, 93, 6, 1, 216, 81, 93, 2, 1, 216, 81, 93, 6, 1, - 213, 205, 93, 2, 1, 213, 205, 93, 6, 1, 220, 224, 93, 2, 1, 220, 224, 93, - 6, 1, 74, 93, 2, 1, 74, 93, 6, 1, 209, 176, 93, 2, 1, 209, 176, 93, 6, 1, - 206, 157, 93, 2, 1, 206, 157, 93, 6, 1, 202, 178, 93, 2, 1, 202, 178, 93, - 6, 1, 199, 161, 93, 2, 1, 199, 161, 93, 6, 1, 196, 164, 93, 2, 1, 196, - 164, 93, 6, 1, 232, 238, 93, 2, 1, 232, 238, 93, 6, 1, 221, 166, 93, 2, - 1, 221, 166, 93, 6, 1, 208, 169, 93, 2, 1, 208, 169, 93, 6, 1, 211, 70, - 93, 2, 1, 211, 70, 93, 6, 1, 236, 248, 251, 141, 93, 2, 1, 236, 248, 251, - 141, 93, 6, 1, 38, 93, 251, 178, 93, 2, 1, 38, 93, 251, 178, 93, 6, 1, - 238, 151, 234, 122, 93, 2, 1, 238, 151, 234, 122, 93, 6, 1, 236, 248, - 222, 51, 93, 2, 1, 236, 248, 222, 51, 93, 6, 1, 236, 248, 213, 205, 93, - 2, 1, 236, 248, 213, 205, 93, 6, 1, 238, 151, 213, 205, 93, 2, 1, 238, - 151, 213, 205, 93, 6, 1, 38, 93, 211, 70, 93, 2, 1, 38, 93, 211, 70, 93, - 6, 1, 205, 140, 93, 2, 1, 205, 140, 93, 6, 1, 238, 167, 203, 100, 93, 2, - 1, 238, 167, 203, 100, 93, 6, 1, 38, 93, 203, 100, 93, 2, 1, 38, 93, 203, - 100, 93, 6, 1, 38, 93, 233, 226, 93, 2, 1, 38, 93, 233, 226, 93, 6, 1, - 251, 161, 221, 171, 93, 2, 1, 251, 161, 221, 171, 93, 6, 1, 236, 248, - 228, 210, 93, 2, 1, 236, 248, 228, 210, 93, 6, 1, 38, 93, 228, 210, 93, - 2, 1, 38, 93, 228, 210, 93, 6, 1, 38, 93, 144, 93, 2, 1, 38, 93, 144, 93, - 6, 1, 220, 118, 144, 93, 2, 1, 220, 118, 144, 93, 6, 1, 38, 93, 229, 177, - 93, 2, 1, 38, 93, 229, 177, 93, 6, 1, 38, 93, 229, 232, 93, 2, 1, 38, 93, - 229, 232, 93, 6, 1, 38, 93, 231, 169, 93, 2, 1, 38, 93, 231, 169, 93, 6, - 1, 38, 93, 236, 148, 93, 2, 1, 38, 93, 236, 148, 93, 6, 1, 38, 93, 203, - 66, 93, 2, 1, 38, 93, 203, 66, 93, 6, 1, 38, 212, 132, 203, 66, 93, 2, 1, - 38, 212, 132, 203, 66, 93, 6, 1, 38, 212, 132, 214, 2, 93, 2, 1, 38, 212, - 132, 214, 2, 93, 6, 1, 38, 212, 132, 212, 68, 93, 2, 1, 38, 212, 132, - 212, 68, 93, 6, 1, 38, 212, 132, 193, 138, 93, 2, 1, 38, 212, 132, 193, - 138, 93, 16, 222, 75, 93, 16, 216, 82, 206, 157, 93, 16, 209, 177, 206, - 157, 93, 16, 201, 84, 93, 16, 199, 162, 206, 157, 93, 16, 221, 167, 206, - 157, 93, 16, 203, 67, 202, 178, 93, 6, 1, 238, 151, 203, 100, 93, 2, 1, - 238, 151, 203, 100, 93, 6, 1, 238, 151, 231, 169, 93, 2, 1, 238, 151, - 231, 169, 93, 33, 213, 206, 56, 93, 33, 201, 208, 250, 151, 93, 33, 201, - 208, 219, 164, 93, 6, 1, 248, 55, 221, 171, 93, 2, 1, 248, 55, 221, 171, - 93, 38, 212, 132, 232, 42, 201, 58, 93, 38, 212, 132, 236, 189, 208, 8, - 77, 93, 38, 212, 132, 223, 114, 208, 8, 77, 93, 38, 212, 132, 195, 134, - 236, 160, 93, 232, 80, 91, 230, 37, 93, 232, 42, 201, 58, 93, 215, 184, - 236, 160, 100, 2, 1, 251, 81, 100, 2, 1, 249, 51, 100, 2, 1, 231, 173, - 100, 2, 1, 236, 105, 100, 2, 1, 234, 61, 100, 2, 1, 195, 46, 100, 2, 1, - 191, 80, 100, 2, 1, 199, 188, 100, 2, 1, 223, 134, 100, 2, 1, 222, 61, - 100, 2, 1, 219, 239, 100, 2, 1, 217, 70, 100, 2, 1, 214, 202, 100, 2, 1, - 211, 93, 100, 2, 1, 210, 121, 100, 2, 1, 191, 67, 100, 2, 1, 207, 158, - 100, 2, 1, 205, 137, 100, 2, 1, 199, 174, 100, 2, 1, 196, 109, 100, 2, 1, - 209, 211, 100, 2, 1, 221, 176, 100, 2, 1, 231, 45, 100, 2, 1, 208, 74, - 100, 2, 1, 203, 64, 100, 2, 1, 243, 33, 100, 2, 1, 247, 80, 100, 2, 1, - 222, 207, 100, 2, 1, 242, 226, 100, 2, 1, 246, 193, 100, 2, 1, 192, 218, - 100, 2, 1, 222, 222, 100, 2, 1, 230, 54, 100, 2, 1, 229, 213, 100, 2, 1, - 229, 113, 100, 2, 1, 193, 123, 100, 2, 1, 229, 242, 100, 2, 1, 228, 235, - 100, 2, 1, 192, 14, 100, 2, 1, 251, 218, 198, 170, 1, 169, 198, 170, 1, - 192, 136, 198, 170, 1, 192, 135, 198, 170, 1, 192, 125, 198, 170, 1, 192, - 123, 198, 170, 1, 248, 168, 252, 10, 192, 118, 198, 170, 1, 192, 118, - 198, 170, 1, 192, 133, 198, 170, 1, 192, 130, 198, 170, 1, 192, 132, 198, - 170, 1, 192, 131, 198, 170, 1, 192, 40, 198, 170, 1, 192, 127, 198, 170, - 1, 192, 116, 198, 170, 1, 197, 82, 192, 116, 198, 170, 1, 192, 113, 198, - 170, 1, 192, 121, 198, 170, 1, 248, 168, 252, 10, 192, 121, 198, 170, 1, - 197, 82, 192, 121, 198, 170, 1, 192, 120, 198, 170, 1, 192, 140, 198, - 170, 1, 192, 114, 198, 170, 1, 197, 82, 192, 114, 198, 170, 1, 192, 103, - 198, 170, 1, 197, 82, 192, 103, 198, 170, 1, 192, 33, 198, 170, 1, 192, - 82, 198, 170, 1, 251, 191, 192, 82, 198, 170, 1, 197, 82, 192, 82, 198, - 170, 1, 192, 112, 198, 170, 1, 192, 111, 198, 170, 1, 192, 108, 198, 170, - 1, 197, 82, 192, 122, 198, 170, 1, 197, 82, 192, 106, 198, 170, 1, 192, - 104, 198, 170, 1, 191, 225, 198, 170, 1, 192, 101, 198, 170, 1, 192, 99, - 198, 170, 1, 192, 124, 198, 170, 1, 197, 82, 192, 124, 198, 170, 1, 250, - 77, 192, 124, 198, 170, 1, 192, 98, 198, 170, 1, 192, 96, 198, 170, 1, - 192, 97, 198, 170, 1, 192, 95, 198, 170, 1, 192, 94, 198, 170, 1, 192, - 134, 198, 170, 1, 192, 92, 198, 170, 1, 192, 90, 198, 170, 1, 192, 89, - 198, 170, 1, 192, 86, 198, 170, 1, 192, 83, 198, 170, 1, 199, 152, 192, - 83, 198, 170, 1, 192, 81, 198, 170, 1, 192, 80, 198, 170, 1, 192, 12, - 198, 170, 59, 1, 220, 91, 77, 198, 170, 204, 6, 77, 198, 170, 119, 222, - 169, 36, 5, 219, 18, 36, 5, 215, 244, 36, 5, 206, 149, 36, 5, 202, 33, - 36, 5, 203, 50, 36, 5, 248, 62, 36, 5, 198, 86, 36, 5, 242, 50, 36, 5, - 213, 23, 36, 5, 212, 51, 36, 5, 230, 231, 211, 169, 36, 5, 191, 6, 36, 5, - 236, 127, 36, 5, 237, 115, 36, 5, 222, 173, 36, 5, 198, 235, 36, 5, 243, - 19, 36, 5, 209, 189, 36, 5, 209, 64, 36, 5, 231, 60, 36, 5, 231, 56, 36, - 5, 231, 57, 36, 5, 231, 58, 36, 5, 201, 170, 36, 5, 201, 124, 36, 5, 201, - 137, 36, 5, 201, 169, 36, 5, 201, 142, 36, 5, 201, 143, 36, 5, 201, 129, - 36, 5, 247, 17, 36, 5, 246, 252, 36, 5, 246, 254, 36, 5, 247, 16, 36, 5, - 247, 14, 36, 5, 247, 15, 36, 5, 246, 253, 36, 5, 190, 224, 36, 5, 190, - 202, 36, 5, 190, 215, 36, 5, 190, 223, 36, 5, 190, 218, 36, 5, 190, 219, - 36, 5, 190, 207, 36, 5, 247, 12, 36, 5, 246, 255, 36, 5, 247, 1, 36, 5, - 247, 11, 36, 5, 247, 9, 36, 5, 247, 10, 36, 5, 247, 0, 36, 5, 207, 229, - 36, 5, 207, 219, 36, 5, 207, 225, 36, 5, 207, 228, 36, 5, 207, 226, 36, - 5, 207, 227, 36, 5, 207, 224, 36, 5, 220, 129, 36, 5, 220, 121, 36, 5, - 220, 124, 36, 5, 220, 128, 36, 5, 220, 125, 36, 5, 220, 126, 36, 5, 220, - 122, 36, 5, 192, 175, 36, 5, 192, 162, 36, 5, 192, 170, 36, 5, 192, 174, - 36, 5, 192, 172, 36, 5, 192, 173, 36, 5, 192, 169, 36, 5, 230, 95, 36, 5, - 230, 85, 36, 5, 230, 88, 36, 5, 230, 94, 36, 5, 230, 90, 36, 5, 230, 91, - 36, 5, 230, 87, 33, 42, 1, 248, 223, 33, 42, 1, 195, 150, 33, 42, 1, 231, - 40, 33, 42, 1, 237, 101, 33, 42, 1, 191, 62, 33, 42, 1, 191, 87, 33, 42, - 1, 157, 33, 42, 1, 234, 97, 33, 42, 1, 234, 72, 33, 42, 1, 234, 61, 33, - 42, 1, 74, 33, 42, 1, 210, 53, 33, 42, 1, 233, 248, 33, 42, 1, 233, 236, - 33, 42, 1, 199, 140, 33, 42, 1, 144, 33, 42, 1, 197, 157, 33, 42, 1, 243, - 79, 33, 42, 1, 203, 160, 33, 42, 1, 203, 111, 33, 42, 1, 232, 187, 33, - 42, 1, 233, 232, 33, 42, 1, 65, 33, 42, 1, 223, 197, 33, 42, 1, 236, 146, - 33, 42, 1, 215, 202, 196, 124, 33, 42, 1, 192, 95, 33, 42, 1, 191, 225, - 33, 42, 1, 223, 53, 65, 33, 42, 1, 219, 59, 191, 190, 33, 42, 1, 248, - 127, 191, 190, 33, 42, 1, 223, 53, 248, 127, 191, 190, 50, 251, 65, 200, - 220, 217, 32, 50, 251, 65, 235, 94, 200, 220, 217, 32, 45, 200, 220, 248, - 5, 50, 200, 220, 248, 5, 45, 235, 94, 200, 220, 248, 5, 50, 235, 94, 200, - 220, 248, 5, 207, 142, 223, 76, 217, 32, 207, 142, 235, 94, 223, 76, 217, - 32, 235, 94, 198, 4, 217, 32, 45, 198, 4, 248, 5, 50, 198, 4, 248, 5, - 207, 142, 201, 185, 45, 207, 142, 211, 95, 248, 5, 50, 207, 142, 211, 95, - 248, 5, 234, 146, 238, 207, 210, 116, 232, 109, 210, 116, 207, 13, 232, - 109, 210, 116, 228, 55, 235, 94, 211, 164, 235, 75, 251, 75, 196, 62, - 251, 75, 235, 94, 206, 198, 251, 64, 54, 211, 159, 228, 58, 223, 65, 223, - 74, 210, 173, 247, 255, 228, 59, 4, 236, 253, 198, 148, 4, 206, 184, 56, - 45, 131, 210, 106, 248, 5, 50, 131, 210, 106, 248, 5, 198, 148, 4, 75, - 56, 198, 148, 4, 75, 60, 45, 81, 249, 38, 4, 208, 2, 50, 81, 249, 38, 4, - 208, 2, 198, 49, 45, 134, 248, 5, 198, 49, 50, 134, 248, 5, 248, 29, 45, - 134, 248, 5, 248, 29, 50, 134, 248, 5, 45, 202, 201, 126, 248, 5, 50, - 202, 201, 126, 248, 5, 45, 54, 210, 103, 50, 54, 210, 103, 103, 183, 138, - 91, 75, 208, 144, 91, 75, 138, 103, 183, 208, 144, 112, 232, 90, 75, 208, - 144, 232, 185, 75, 77, 207, 13, 208, 8, 77, 81, 198, 147, 206, 184, 209, - 54, 193, 23, 204, 6, 82, 236, 96, 152, 242, 26, 207, 142, 236, 96, 207, - 142, 242, 26, 152, 204, 20, 237, 224, 4, 45, 230, 140, 237, 224, 4, 50, - 230, 140, 152, 237, 223, 198, 49, 134, 205, 49, 57, 197, 10, 237, 170, - 198, 218, 237, 170, 201, 74, 232, 42, 201, 58, 81, 202, 131, 236, 94, - 193, 70, 81, 219, 88, 247, 61, 54, 228, 58, 207, 13, 242, 26, 54, 218, - 215, 207, 247, 77, 237, 171, 4, 45, 196, 65, 54, 200, 159, 77, 223, 65, - 131, 222, 9, 223, 65, 131, 222, 10, 4, 222, 10, 56, 131, 222, 9, 131, - 222, 10, 4, 236, 96, 54, 201, 109, 242, 26, 235, 94, 202, 18, 197, 221, - 237, 223, 216, 195, 242, 26, 210, 115, 77, 208, 143, 234, 86, 77, 238, - 208, 195, 134, 236, 160, 238, 171, 210, 72, 4, 50, 238, 169, 238, 171, - 210, 72, 4, 45, 238, 169, 198, 123, 3, 6, 233, 213, 216, 195, 233, 175, - 77, 216, 195, 208, 8, 77, 45, 51, 248, 6, 4, 105, 50, 51, 248, 6, 4, 105, - 45, 51, 248, 6, 4, 54, 105, 50, 51, 248, 6, 4, 54, 105, 198, 49, 134, 45, - 210, 103, 198, 49, 134, 50, 210, 103, 248, 29, 134, 45, 210, 103, 248, - 29, 134, 50, 210, 103, 211, 159, 228, 58, 12, 48, 207, 43, 12, 48, 242, - 182, 12, 48, 205, 52, 108, 12, 48, 205, 52, 109, 12, 48, 205, 52, 139, - 12, 48, 209, 241, 12, 48, 248, 14, 12, 48, 199, 228, 12, 48, 221, 55, - 108, 12, 48, 221, 55, 109, 12, 48, 236, 157, 12, 48, 205, 56, 12, 48, 2, - 108, 12, 48, 2, 109, 12, 48, 220, 6, 108, 12, 48, 220, 6, 109, 12, 48, - 220, 6, 139, 12, 48, 220, 6, 137, 12, 48, 202, 53, 12, 48, 198, 222, 12, - 48, 202, 50, 108, 12, 48, 202, 50, 109, 12, 48, 229, 192, 108, 12, 48, - 229, 192, 109, 12, 48, 230, 20, 12, 48, 207, 131, 12, 48, 243, 16, 12, - 48, 200, 193, 12, 48, 215, 188, 12, 48, 237, 98, 12, 48, 215, 177, 12, - 48, 242, 201, 12, 48, 193, 142, 108, 12, 48, 193, 142, 109, 12, 48, 232, - 202, 12, 48, 210, 66, 108, 12, 48, 210, 66, 109, 12, 48, 202, 173, 134, - 197, 251, 197, 173, 12, 48, 238, 192, 12, 48, 236, 117, 12, 48, 222, 255, - 12, 48, 248, 54, 80, 242, 165, 12, 48, 233, 152, 12, 48, 201, 210, 108, - 12, 48, 201, 210, 109, 12, 48, 249, 53, 12, 48, 202, 180, 12, 48, 247, - 142, 202, 180, 12, 48, 214, 72, 108, 12, 48, 214, 72, 109, 12, 48, 214, - 72, 139, 12, 48, 214, 72, 137, 12, 48, 216, 153, 12, 48, 203, 102, 12, - 48, 207, 137, 12, 48, 233, 182, 12, 48, 211, 108, 12, 48, 247, 226, 108, - 12, 48, 247, 226, 109, 12, 48, 216, 205, 12, 48, 215, 183, 12, 48, 230, - 180, 108, 12, 48, 230, 180, 109, 12, 48, 230, 180, 139, 12, 48, 198, 168, - 12, 48, 242, 164, 12, 48, 193, 103, 108, 12, 48, 193, 103, 109, 12, 48, - 247, 142, 205, 45, 12, 48, 202, 173, 228, 156, 12, 48, 228, 156, 12, 48, - 247, 142, 201, 224, 12, 48, 247, 142, 203, 97, 12, 48, 232, 120, 12, 48, - 247, 142, 247, 37, 12, 48, 202, 173, 193, 166, 12, 48, 193, 167, 108, 12, - 48, 193, 167, 109, 12, 48, 242, 204, 12, 48, 247, 142, 230, 214, 12, 48, - 177, 108, 12, 48, 177, 109, 12, 48, 247, 142, 218, 251, 12, 48, 247, 142, - 231, 154, 12, 48, 215, 172, 108, 12, 48, 215, 172, 109, 12, 48, 207, 144, - 12, 48, 248, 66, 12, 48, 247, 142, 199, 180, 219, 206, 12, 48, 247, 142, - 219, 209, 12, 48, 247, 142, 193, 64, 12, 48, 247, 142, 232, 139, 12, 48, - 234, 157, 108, 12, 48, 234, 157, 109, 12, 48, 234, 157, 139, 12, 48, 247, - 142, 234, 156, 12, 48, 229, 203, 12, 48, 247, 142, 228, 152, 12, 48, 248, - 50, 12, 48, 231, 24, 12, 48, 247, 142, 232, 195, 12, 48, 247, 142, 248, - 112, 12, 48, 247, 142, 205, 153, 12, 48, 202, 173, 193, 93, 12, 48, 202, - 173, 192, 72, 12, 48, 247, 142, 232, 61, 12, 48, 223, 6, 233, 187, 12, - 48, 247, 142, 233, 187, 12, 48, 223, 6, 198, 51, 12, 48, 247, 142, 198, - 51, 12, 48, 223, 6, 235, 67, 12, 48, 247, 142, 235, 67, 12, 48, 197, 51, - 12, 48, 223, 6, 197, 51, 12, 48, 247, 142, 197, 51, 83, 48, 108, 83, 48, - 219, 88, 83, 48, 236, 96, 83, 48, 202, 92, 83, 48, 205, 51, 83, 48, 106, - 83, 48, 109, 83, 48, 219, 117, 83, 48, 217, 70, 83, 48, 219, 185, 83, 48, - 234, 35, 83, 48, 176, 83, 48, 143, 248, 14, 83, 48, 238, 195, 83, 48, - 227, 252, 83, 48, 199, 228, 83, 48, 211, 66, 248, 14, 83, 48, 221, 54, - 83, 48, 208, 247, 83, 48, 193, 12, 83, 48, 201, 198, 83, 48, 50, 211, 66, - 248, 14, 83, 48, 229, 114, 234, 56, 83, 48, 199, 90, 83, 48, 236, 157, - 83, 48, 205, 56, 83, 48, 242, 182, 83, 48, 208, 197, 83, 48, 251, 200, - 83, 48, 215, 163, 83, 48, 234, 56, 83, 48, 234, 163, 83, 48, 205, 86, 83, - 48, 230, 223, 83, 48, 230, 224, 202, 69, 83, 48, 233, 186, 83, 48, 248, - 126, 83, 48, 193, 35, 83, 48, 243, 38, 83, 48, 206, 128, 83, 48, 223, - 130, 83, 48, 202, 65, 83, 48, 220, 5, 83, 48, 238, 205, 83, 48, 201, 189, - 83, 48, 215, 168, 83, 48, 206, 171, 83, 48, 193, 20, 83, 48, 211, 84, 83, - 48, 197, 59, 83, 48, 235, 47, 83, 48, 203, 35, 198, 222, 83, 48, 235, 94, - 242, 182, 83, 48, 177, 201, 29, 83, 48, 103, 229, 251, 83, 48, 203, 41, - 83, 48, 248, 21, 83, 48, 202, 49, 83, 48, 247, 233, 83, 48, 201, 73, 83, - 48, 229, 191, 83, 48, 230, 38, 83, 48, 236, 100, 83, 48, 230, 20, 83, 48, - 247, 255, 83, 48, 207, 131, 83, 48, 205, 69, 83, 48, 236, 191, 83, 48, - 250, 82, 83, 48, 201, 185, 83, 48, 212, 254, 83, 48, 200, 193, 83, 48, - 205, 98, 83, 48, 215, 188, 83, 48, 197, 250, 83, 48, 220, 87, 83, 48, - 201, 58, 83, 48, 237, 98, 83, 48, 193, 118, 83, 48, 236, 130, 212, 254, - 83, 48, 242, 22, 83, 48, 232, 35, 83, 48, 242, 195, 83, 48, 201, 79, 83, - 48, 193, 141, 83, 48, 232, 202, 83, 48, 242, 191, 83, 48, 233, 25, 83, - 48, 54, 192, 235, 83, 48, 134, 197, 251, 197, 173, 83, 48, 202, 83, 83, - 48, 233, 37, 83, 48, 238, 192, 83, 48, 236, 117, 83, 48, 208, 192, 83, - 48, 222, 255, 83, 48, 216, 177, 83, 48, 198, 146, 83, 48, 200, 137, 83, - 48, 219, 111, 83, 48, 196, 39, 83, 48, 232, 236, 83, 48, 248, 54, 80, - 242, 165, 83, 48, 202, 207, 83, 48, 235, 94, 199, 82, 83, 48, 193, 87, - 83, 48, 202, 102, 83, 48, 236, 177, 83, 48, 233, 152, 83, 48, 201, 227, - 83, 48, 55, 83, 48, 201, 60, 83, 48, 201, 209, 83, 48, 198, 21, 83, 48, - 230, 189, 83, 48, 247, 22, 83, 48, 201, 102, 83, 48, 249, 53, 83, 48, - 206, 240, 83, 48, 202, 180, 83, 48, 222, 246, 83, 48, 214, 71, 83, 48, - 203, 102, 83, 48, 233, 13, 83, 48, 211, 108, 83, 48, 251, 74, 83, 48, - 209, 81, 83, 48, 234, 167, 83, 48, 247, 225, 83, 48, 216, 205, 83, 48, - 216, 20, 83, 48, 204, 27, 83, 48, 250, 189, 83, 48, 215, 183, 83, 48, - 198, 56, 83, 48, 211, 53, 83, 48, 248, 58, 83, 48, 201, 54, 83, 48, 242, - 34, 83, 48, 230, 179, 83, 48, 198, 168, 83, 48, 223, 93, 83, 48, 248, 72, - 83, 48, 193, 167, 234, 56, 83, 48, 242, 164, 83, 48, 193, 102, 83, 48, - 205, 45, 83, 48, 228, 156, 83, 48, 201, 224, 83, 48, 195, 177, 83, 48, - 248, 218, 83, 48, 209, 138, 83, 48, 249, 83, 83, 48, 203, 97, 83, 48, - 207, 81, 83, 48, 206, 40, 83, 48, 232, 120, 83, 48, 248, 56, 83, 48, 247, - 37, 83, 48, 248, 96, 83, 48, 215, 185, 83, 48, 193, 166, 83, 48, 242, - 204, 83, 48, 193, 60, 83, 48, 236, 169, 83, 48, 195, 47, 83, 48, 230, - 214, 83, 48, 218, 251, 83, 48, 231, 154, 83, 48, 215, 171, 83, 48, 202, - 91, 83, 48, 203, 35, 199, 209, 248, 112, 83, 48, 207, 144, 83, 48, 248, - 66, 83, 48, 193, 2, 83, 48, 233, 62, 83, 48, 219, 206, 83, 48, 199, 180, - 219, 206, 83, 48, 219, 202, 83, 48, 201, 255, 83, 48, 219, 209, 83, 48, - 193, 64, 83, 48, 232, 139, 83, 48, 234, 156, 83, 48, 229, 203, 83, 48, - 232, 78, 83, 48, 228, 152, 83, 48, 248, 50, 83, 48, 199, 194, 83, 48, - 230, 45, 83, 48, 232, 229, 83, 48, 205, 189, 193, 60, 83, 48, 247, 24, - 83, 48, 231, 24, 83, 48, 232, 195, 83, 48, 248, 112, 83, 48, 205, 153, - 83, 48, 237, 83, 83, 48, 193, 93, 83, 48, 229, 167, 83, 48, 192, 72, 83, - 48, 216, 31, 83, 48, 248, 91, 83, 48, 234, 68, 83, 48, 232, 61, 83, 48, - 197, 218, 83, 48, 235, 50, 83, 48, 207, 125, 83, 48, 213, 0, 83, 48, 233, - 187, 83, 48, 198, 51, 83, 48, 235, 67, 83, 48, 197, 51, 83, 48, 232, 142, - 154, 237, 40, 246, 192, 45, 118, 187, 154, 237, 40, 246, 192, 95, 118, - 60, 154, 237, 40, 246, 192, 45, 118, 82, 24, 187, 154, 237, 40, 246, 192, - 95, 118, 82, 24, 60, 154, 237, 40, 246, 192, 232, 42, 200, 163, 154, 237, - 40, 246, 192, 200, 164, 232, 60, 56, 154, 237, 40, 246, 192, 200, 164, - 232, 60, 60, 154, 237, 40, 246, 192, 200, 164, 232, 60, 219, 200, 154, - 237, 40, 246, 192, 200, 164, 232, 60, 116, 219, 200, 154, 237, 40, 246, - 192, 200, 164, 232, 60, 116, 187, 154, 237, 40, 246, 192, 200, 164, 232, - 60, 110, 219, 200, 154, 237, 40, 246, 192, 210, 249, 154, 201, 242, 154, - 242, 26, 154, 232, 42, 201, 58, 236, 166, 77, 222, 247, 223, 113, 201, - 101, 113, 154, 223, 23, 77, 154, 242, 167, 77, 154, 31, 191, 77, 45, 251, - 65, 248, 5, 50, 251, 65, 248, 5, 45, 54, 251, 65, 248, 5, 50, 54, 251, - 65, 248, 5, 45, 238, 211, 248, 5, 50, 238, 211, 248, 5, 45, 64, 238, 211, - 248, 5, 50, 64, 238, 211, 248, 5, 45, 62, 219, 163, 248, 5, 50, 62, 219, - 163, 248, 5, 209, 11, 77, 231, 93, 77, 45, 198, 37, 203, 98, 248, 5, 50, - 198, 37, 203, 98, 248, 5, 45, 64, 219, 163, 248, 5, 50, 64, 219, 163, - 248, 5, 45, 64, 198, 37, 203, 98, 248, 5, 50, 64, 198, 37, 203, 98, 248, - 5, 45, 64, 51, 248, 5, 50, 64, 51, 248, 5, 193, 137, 237, 170, 207, 13, - 54, 208, 209, 207, 247, 77, 54, 208, 209, 207, 247, 77, 131, 54, 208, - 209, 207, 247, 77, 209, 11, 87, 233, 62, 229, 248, 212, 121, 108, 229, - 248, 212, 121, 109, 229, 248, 212, 121, 139, 229, 248, 212, 121, 137, - 229, 248, 212, 121, 153, 229, 248, 212, 121, 173, 229, 248, 212, 121, - 181, 229, 248, 212, 121, 176, 229, 248, 212, 121, 184, 154, 219, 144, - 163, 77, 154, 206, 175, 163, 77, 154, 237, 50, 163, 77, 154, 234, 34, - 163, 77, 30, 202, 165, 75, 163, 77, 30, 54, 75, 163, 77, 193, 133, 237, - 170, 81, 222, 60, 207, 44, 77, 81, 222, 60, 207, 44, 4, 195, 17, 202, 0, - 77, 81, 222, 60, 207, 44, 87, 116, 230, 37, 81, 222, 60, 207, 44, 4, 195, - 17, 202, 0, 87, 116, 230, 37, 81, 222, 60, 207, 44, 87, 110, 230, 37, 47, - 209, 11, 77, 154, 199, 104, 219, 89, 233, 10, 204, 6, 113, 229, 248, 212, - 121, 199, 90, 229, 248, 212, 121, 197, 28, 229, 248, 212, 121, 198, 244, - 81, 154, 223, 23, 77, 217, 12, 77, 210, 97, 251, 102, 77, 154, 66, 223, - 116, 154, 134, 232, 221, 201, 242, 229, 88, 1, 2, 65, 229, 88, 1, 65, - 229, 88, 1, 2, 70, 229, 88, 1, 70, 229, 88, 1, 2, 69, 229, 88, 1, 69, - 229, 88, 1, 2, 73, 229, 88, 1, 73, 229, 88, 1, 2, 74, 229, 88, 1, 74, - 229, 88, 1, 157, 229, 88, 1, 231, 203, 229, 88, 1, 221, 142, 229, 88, 1, - 231, 16, 229, 88, 1, 220, 208, 229, 88, 1, 230, 146, 229, 88, 1, 221, - 253, 229, 88, 1, 231, 128, 229, 88, 1, 221, 43, 229, 88, 1, 230, 223, - 229, 88, 1, 189, 229, 88, 1, 191, 123, 229, 88, 1, 202, 217, 229, 88, 1, - 191, 30, 229, 88, 1, 200, 255, 229, 88, 1, 190, 251, 229, 88, 1, 205, 63, - 229, 88, 1, 191, 87, 229, 88, 1, 202, 41, 229, 88, 1, 191, 7, 229, 88, 1, - 199, 247, 229, 88, 1, 237, 241, 229, 88, 1, 198, 188, 229, 88, 1, 236, - 255, 229, 88, 1, 2, 197, 90, 229, 88, 1, 197, 90, 229, 88, 1, 235, 45, - 229, 88, 1, 199, 140, 229, 88, 1, 237, 101, 229, 88, 1, 159, 229, 88, 1, - 236, 129, 229, 88, 1, 180, 229, 88, 1, 213, 205, 229, 88, 1, 212, 165, - 229, 88, 1, 214, 107, 229, 88, 1, 213, 30, 229, 88, 1, 144, 229, 88, 1, - 249, 103, 229, 88, 1, 168, 229, 88, 1, 229, 126, 229, 88, 1, 248, 140, - 229, 88, 1, 209, 176, 229, 88, 1, 228, 128, 229, 88, 1, 247, 218, 229, - 88, 1, 208, 158, 229, 88, 1, 229, 213, 229, 88, 1, 248, 223, 229, 88, 1, - 210, 53, 229, 88, 1, 228, 247, 229, 88, 1, 248, 63, 229, 88, 1, 209, 65, - 229, 88, 1, 172, 229, 88, 1, 216, 81, 229, 88, 1, 215, 139, 229, 88, 1, - 216, 213, 229, 88, 1, 215, 251, 229, 88, 1, 2, 169, 229, 88, 1, 169, 229, - 88, 1, 2, 191, 225, 229, 88, 1, 191, 225, 229, 88, 1, 2, 192, 12, 229, - 88, 1, 192, 12, 229, 88, 1, 166, 229, 88, 1, 206, 252, 229, 88, 1, 206, - 63, 229, 88, 1, 207, 108, 229, 88, 1, 206, 157, 229, 88, 1, 2, 193, 187, - 229, 88, 1, 193, 187, 229, 88, 1, 193, 84, 229, 88, 1, 193, 123, 229, 88, - 1, 193, 48, 229, 88, 1, 215, 47, 229, 88, 1, 193, 246, 229, 88, 1, 2, - 157, 229, 88, 1, 2, 221, 253, 33, 222, 22, 195, 17, 202, 0, 77, 33, 222, - 22, 204, 25, 202, 0, 77, 222, 22, 195, 17, 202, 0, 77, 222, 22, 204, 25, - 202, 0, 77, 229, 88, 223, 23, 77, 229, 88, 195, 17, 223, 23, 77, 229, 88, - 236, 214, 191, 242, 222, 22, 54, 228, 58, 71, 1, 2, 65, 71, 1, 65, 71, 1, - 2, 70, 71, 1, 70, 71, 1, 2, 69, 71, 1, 69, 71, 1, 2, 73, 71, 1, 73, 71, - 1, 2, 74, 71, 1, 74, 71, 1, 157, 71, 1, 231, 203, 71, 1, 221, 142, 71, 1, - 231, 16, 71, 1, 220, 208, 71, 1, 230, 146, 71, 1, 221, 253, 71, 1, 231, - 128, 71, 1, 221, 43, 71, 1, 230, 223, 71, 1, 189, 71, 1, 191, 123, 71, 1, - 202, 217, 71, 1, 191, 30, 71, 1, 200, 255, 71, 1, 190, 251, 71, 1, 205, - 63, 71, 1, 191, 87, 71, 1, 202, 41, 71, 1, 191, 7, 71, 1, 199, 247, 71, - 1, 237, 241, 71, 1, 198, 188, 71, 1, 236, 255, 71, 1, 2, 197, 90, 71, 1, - 197, 90, 71, 1, 235, 45, 71, 1, 199, 140, 71, 1, 237, 101, 71, 1, 159, - 71, 1, 236, 129, 71, 1, 180, 71, 1, 213, 205, 71, 1, 212, 165, 71, 1, - 214, 107, 71, 1, 213, 30, 71, 1, 144, 71, 1, 249, 103, 71, 1, 168, 71, 1, - 229, 126, 71, 1, 248, 140, 71, 1, 209, 176, 71, 1, 228, 128, 71, 1, 247, - 218, 71, 1, 208, 158, 71, 1, 229, 213, 71, 1, 248, 223, 71, 1, 210, 53, - 71, 1, 228, 247, 71, 1, 248, 63, 71, 1, 209, 65, 71, 1, 172, 71, 1, 216, - 81, 71, 1, 215, 139, 71, 1, 216, 213, 71, 1, 215, 251, 71, 1, 2, 169, 71, - 1, 169, 71, 1, 2, 191, 225, 71, 1, 191, 225, 71, 1, 2, 192, 12, 71, 1, - 192, 12, 71, 1, 166, 71, 1, 206, 252, 71, 1, 206, 63, 71, 1, 207, 108, - 71, 1, 206, 157, 71, 1, 2, 193, 187, 71, 1, 193, 187, 71, 1, 193, 84, 71, - 1, 193, 123, 71, 1, 193, 48, 71, 1, 215, 47, 71, 1, 193, 246, 71, 1, 2, - 157, 71, 1, 2, 221, 253, 71, 1, 195, 185, 71, 1, 195, 66, 71, 1, 195, - 150, 71, 1, 195, 21, 71, 82, 236, 96, 222, 22, 208, 184, 202, 0, 77, 71, - 223, 23, 77, 71, 195, 17, 223, 23, 77, 71, 236, 214, 221, 3, 248, 40, 1, - 250, 70, 248, 40, 1, 210, 226, 248, 40, 1, 218, 147, 248, 40, 1, 233, - 134, 248, 40, 1, 238, 80, 248, 40, 1, 200, 39, 248, 40, 1, 215, 47, 248, - 40, 1, 170, 248, 40, 1, 232, 14, 248, 40, 1, 222, 125, 248, 40, 1, 230, - 83, 248, 40, 1, 223, 7, 248, 40, 1, 208, 97, 248, 40, 1, 192, 235, 248, - 40, 1, 191, 72, 248, 40, 1, 246, 211, 248, 40, 1, 203, 162, 248, 40, 1, - 148, 248, 40, 1, 191, 166, 248, 40, 1, 247, 145, 248, 40, 1, 206, 3, 248, - 40, 1, 65, 248, 40, 1, 74, 248, 40, 1, 73, 248, 40, 1, 234, 130, 248, 40, - 1, 251, 184, 248, 40, 1, 234, 123, 248, 40, 1, 250, 113, 248, 40, 1, 211, - 9, 248, 40, 1, 251, 81, 248, 40, 1, 234, 61, 248, 40, 1, 251, 71, 248, - 40, 1, 234, 46, 248, 40, 1, 233, 248, 248, 40, 1, 70, 248, 40, 1, 69, - 248, 40, 1, 223, 21, 248, 40, 1, 196, 8, 248, 40, 1, 214, 56, 248, 40, 1, - 230, 227, 248, 40, 1, 223, 171, 248, 40, 1, 186, 4, 75, 56, 248, 40, 1, - 213, 67, 30, 1, 221, 89, 30, 1, 201, 162, 30, 1, 221, 82, 30, 1, 213, - 190, 30, 1, 213, 188, 30, 1, 213, 187, 30, 1, 198, 163, 30, 1, 201, 151, - 30, 1, 206, 234, 30, 1, 206, 229, 30, 1, 206, 226, 30, 1, 206, 219, 30, - 1, 206, 214, 30, 1, 206, 209, 30, 1, 206, 220, 30, 1, 206, 232, 30, 1, - 216, 59, 30, 1, 209, 160, 30, 1, 201, 159, 30, 1, 209, 149, 30, 1, 202, - 155, 30, 1, 201, 156, 30, 1, 223, 193, 30, 1, 242, 232, 30, 1, 201, 166, - 30, 1, 243, 43, 30, 1, 221, 164, 30, 1, 199, 2, 30, 1, 209, 200, 30, 1, - 229, 110, 30, 1, 65, 30, 1, 251, 229, 30, 1, 169, 30, 1, 192, 129, 30, 1, - 234, 23, 30, 1, 73, 30, 1, 192, 67, 30, 1, 192, 80, 30, 1, 74, 30, 1, - 193, 187, 30, 1, 193, 173, 30, 1, 211, 139, 30, 1, 192, 12, 30, 1, 69, - 30, 1, 193, 105, 30, 1, 193, 123, 30, 1, 193, 84, 30, 1, 191, 225, 30, 1, - 233, 201, 30, 1, 192, 33, 30, 1, 70, 30, 232, 218, 30, 1, 201, 160, 30, - 1, 213, 180, 30, 1, 213, 182, 30, 1, 213, 185, 30, 1, 206, 227, 30, 1, - 206, 208, 30, 1, 206, 216, 30, 1, 206, 221, 30, 1, 206, 206, 30, 1, 216, - 52, 30, 1, 216, 49, 30, 1, 216, 53, 30, 1, 222, 45, 30, 1, 209, 155, 30, - 1, 209, 141, 30, 1, 209, 147, 30, 1, 209, 144, 30, 1, 209, 158, 30, 1, - 209, 142, 30, 1, 222, 43, 30, 1, 222, 41, 30, 1, 202, 148, 30, 1, 202, - 146, 30, 1, 202, 138, 30, 1, 202, 143, 30, 1, 202, 153, 30, 1, 210, 139, - 30, 1, 201, 163, 30, 1, 192, 57, 30, 1, 192, 51, 30, 1, 192, 52, 30, 1, - 222, 44, 30, 1, 201, 164, 30, 1, 192, 63, 30, 1, 192, 0, 30, 1, 191, 255, - 30, 1, 192, 2, 30, 1, 191, 212, 30, 1, 191, 213, 30, 1, 191, 216, 30, 1, - 250, 231, 30, 1, 250, 225, 154, 251, 45, 219, 77, 77, 154, 251, 45, 207, - 14, 77, 154, 251, 45, 91, 77, 154, 251, 45, 103, 77, 154, 251, 45, 115, - 77, 154, 251, 45, 232, 90, 77, 154, 251, 45, 198, 49, 77, 154, 251, 45, - 82, 77, 154, 251, 45, 248, 29, 77, 154, 251, 45, 232, 197, 77, 154, 251, - 45, 205, 52, 77, 154, 251, 45, 198, 252, 77, 154, 251, 45, 232, 83, 77, - 154, 251, 45, 229, 188, 77, 154, 251, 45, 234, 164, 77, 154, 251, 45, - 217, 71, 77, 248, 40, 1, 247, 218, 248, 40, 1, 191, 30, 248, 40, 1, 222, - 217, 248, 40, 1, 230, 146, 248, 40, 1, 234, 145, 248, 40, 1, 234, 43, - 248, 40, 1, 211, 76, 248, 40, 1, 211, 80, 248, 40, 1, 223, 49, 248, 40, - 1, 251, 47, 248, 40, 1, 223, 100, 248, 40, 1, 196, 79, 248, 40, 1, 223, - 152, 248, 40, 1, 214, 34, 248, 40, 1, 251, 177, 248, 40, 1, 250, 108, - 248, 40, 1, 251, 98, 248, 40, 1, 211, 102, 248, 40, 1, 211, 83, 248, 40, - 1, 223, 97, 248, 40, 52, 1, 210, 226, 248, 40, 52, 1, 200, 39, 248, 40, - 52, 1, 222, 125, 248, 40, 52, 1, 230, 83, 248, 40, 1, 231, 55, 248, 40, - 1, 219, 136, 248, 40, 1, 190, 231, 248, 40, 52, 1, 232, 14, 248, 40, 1, - 230, 103, 248, 40, 1, 220, 156, 248, 40, 1, 211, 139, 248, 40, 1, 251, - 193, 12, 201, 23, 200, 39, 12, 201, 23, 193, 96, 12, 201, 23, 192, 209, - 12, 201, 23, 247, 158, 12, 201, 23, 200, 147, 12, 201, 23, 228, 48, 12, - 201, 23, 228, 52, 12, 201, 23, 228, 138, 12, 201, 23, 228, 49, 12, 201, - 23, 200, 42, 12, 201, 23, 228, 51, 12, 201, 23, 228, 47, 12, 201, 23, - 228, 136, 12, 201, 23, 228, 50, 12, 201, 23, 228, 46, 12, 201, 23, 215, - 47, 12, 201, 23, 230, 83, 12, 201, 23, 206, 3, 12, 201, 23, 210, 226, 12, - 201, 23, 201, 245, 12, 201, 23, 238, 80, 12, 201, 23, 228, 53, 12, 201, - 23, 229, 146, 12, 201, 23, 200, 51, 12, 201, 23, 200, 124, 12, 201, 23, - 201, 113, 12, 201, 23, 203, 168, 12, 201, 23, 210, 57, 12, 201, 23, 208, - 99, 12, 201, 23, 198, 94, 12, 201, 23, 200, 41, 12, 201, 23, 200, 136, - 12, 201, 23, 228, 63, 12, 201, 23, 228, 45, 12, 201, 23, 209, 221, 12, - 201, 23, 208, 97, 71, 1, 2, 220, 208, 71, 1, 2, 202, 217, 71, 1, 2, 200, - 255, 71, 1, 2, 159, 71, 1, 2, 212, 165, 71, 1, 2, 144, 71, 1, 2, 229, - 126, 71, 1, 2, 228, 128, 71, 1, 2, 229, 213, 71, 1, 2, 228, 247, 71, 1, - 2, 215, 139, 71, 1, 2, 166, 71, 1, 2, 206, 252, 71, 1, 2, 206, 63, 71, 1, - 2, 207, 108, 71, 1, 2, 206, 157, 127, 30, 221, 89, 127, 30, 213, 190, - 127, 30, 198, 163, 127, 30, 206, 234, 127, 30, 216, 59, 127, 30, 209, - 160, 127, 30, 202, 155, 127, 30, 223, 193, 127, 30, 242, 232, 127, 30, - 243, 43, 127, 30, 221, 164, 127, 30, 199, 2, 127, 30, 209, 200, 127, 30, - 229, 110, 127, 30, 221, 90, 65, 127, 30, 213, 191, 65, 127, 30, 198, 164, - 65, 127, 30, 206, 235, 65, 127, 30, 216, 60, 65, 127, 30, 209, 161, 65, - 127, 30, 202, 156, 65, 127, 30, 223, 194, 65, 127, 30, 242, 233, 65, 127, - 30, 243, 44, 65, 127, 30, 221, 165, 65, 127, 30, 199, 3, 65, 127, 30, - 209, 201, 65, 127, 30, 229, 111, 65, 127, 30, 242, 233, 69, 127, 221, 8, - 246, 192, 211, 117, 127, 221, 8, 246, 192, 186, 228, 128, 127, 227, 241, - 108, 127, 227, 241, 109, 127, 227, 241, 139, 127, 227, 241, 137, 127, - 227, 241, 153, 127, 227, 241, 173, 127, 227, 241, 181, 127, 227, 241, - 176, 127, 227, 241, 184, 127, 227, 241, 199, 90, 127, 227, 241, 215, 188, - 127, 227, 241, 232, 202, 127, 227, 241, 193, 141, 127, 227, 241, 193, 28, - 127, 227, 241, 216, 146, 127, 227, 241, 234, 163, 127, 227, 241, 200, - 193, 127, 227, 241, 201, 61, 127, 227, 241, 229, 223, 127, 227, 241, 202, - 30, 127, 227, 241, 214, 213, 127, 227, 241, 201, 226, 127, 227, 241, 232, - 213, 127, 227, 241, 239, 2, 127, 227, 241, 220, 90, 127, 227, 241, 207, - 37, 127, 227, 241, 247, 90, 127, 227, 241, 201, 5, 127, 227, 241, 200, - 173, 127, 227, 241, 234, 33, 127, 227, 241, 207, 27, 127, 227, 241, 251, - 117, 127, 227, 241, 232, 246, 127, 227, 241, 207, 25, 127, 227, 241, 204, - 27, 127, 227, 241, 207, 103, 47, 227, 241, 208, 7, 47, 227, 241, 221, - 116, 47, 227, 241, 205, 84, 47, 227, 241, 221, 3, 47, 31, 199, 91, 211, - 94, 62, 201, 185, 47, 31, 197, 29, 211, 94, 62, 201, 185, 47, 31, 198, - 245, 211, 94, 62, 201, 185, 47, 31, 232, 98, 211, 94, 62, 201, 185, 47, - 31, 232, 231, 211, 94, 62, 201, 185, 47, 31, 202, 116, 211, 94, 62, 201, - 185, 47, 31, 203, 237, 211, 94, 62, 201, 185, 47, 31, 234, 111, 211, 94, - 62, 201, 185, 210, 93, 57, 47, 31, 197, 29, 108, 47, 31, 197, 29, 109, - 47, 31, 197, 29, 139, 47, 31, 197, 29, 137, 47, 31, 197, 29, 153, 47, 31, - 197, 29, 173, 47, 31, 197, 29, 181, 47, 31, 197, 29, 176, 47, 31, 197, - 29, 184, 47, 31, 198, 244, 47, 31, 198, 245, 108, 47, 31, 198, 245, 109, - 47, 31, 198, 245, 139, 47, 31, 198, 245, 137, 47, 31, 198, 245, 153, 47, - 30, 221, 89, 47, 30, 213, 190, 47, 30, 198, 163, 47, 30, 206, 234, 47, - 30, 216, 59, 47, 30, 209, 160, 47, 30, 202, 155, 47, 30, 223, 193, 47, - 30, 242, 232, 47, 30, 243, 43, 47, 30, 221, 164, 47, 30, 199, 2, 47, 30, - 209, 200, 47, 30, 229, 110, 47, 30, 221, 90, 65, 47, 30, 213, 191, 65, - 47, 30, 198, 164, 65, 47, 30, 206, 235, 65, 47, 30, 216, 60, 65, 47, 30, - 209, 161, 65, 47, 30, 202, 156, 65, 47, 30, 223, 194, 65, 47, 30, 242, - 233, 65, 47, 30, 243, 44, 65, 47, 30, 221, 165, 65, 47, 30, 199, 3, 65, - 47, 30, 209, 201, 65, 47, 30, 229, 111, 65, 47, 221, 8, 246, 192, 246, - 199, 47, 221, 8, 246, 192, 222, 151, 47, 30, 223, 194, 69, 221, 8, 201, - 101, 113, 47, 227, 241, 108, 47, 227, 241, 109, 47, 227, 241, 139, 47, - 227, 241, 137, 47, 227, 241, 153, 47, 227, 241, 173, 47, 227, 241, 181, - 47, 227, 241, 176, 47, 227, 241, 184, 47, 227, 241, 199, 90, 47, 227, - 241, 215, 188, 47, 227, 241, 232, 202, 47, 227, 241, 193, 141, 47, 227, - 241, 193, 28, 47, 227, 241, 216, 146, 47, 227, 241, 234, 163, 47, 227, - 241, 200, 193, 47, 227, 241, 201, 61, 47, 227, 241, 229, 223, 47, 227, - 241, 202, 30, 47, 227, 241, 214, 213, 47, 227, 241, 201, 226, 47, 227, - 241, 232, 213, 47, 227, 241, 239, 2, 47, 227, 241, 220, 90, 47, 227, 241, - 205, 50, 47, 227, 241, 217, 76, 47, 227, 241, 233, 0, 47, 227, 241, 200, - 205, 47, 227, 241, 233, 179, 47, 227, 241, 208, 204, 47, 227, 241, 250, - 117, 47, 227, 241, 223, 24, 47, 227, 241, 207, 25, 47, 227, 241, 238, - 217, 47, 227, 241, 238, 204, 47, 227, 241, 229, 103, 47, 227, 241, 246, - 229, 47, 227, 241, 218, 219, 47, 227, 241, 219, 200, 47, 227, 241, 187, - 47, 227, 241, 216, 196, 47, 227, 241, 207, 55, 47, 227, 241, 201, 5, 47, - 227, 241, 200, 173, 47, 227, 241, 234, 33, 47, 227, 241, 207, 27, 47, - 227, 241, 251, 117, 47, 227, 241, 213, 176, 47, 31, 198, 245, 173, 47, - 31, 198, 245, 181, 47, 31, 198, 245, 176, 47, 31, 198, 245, 184, 47, 31, - 232, 97, 47, 31, 232, 98, 108, 47, 31, 232, 98, 109, 47, 31, 232, 98, - 139, 47, 31, 232, 98, 137, 47, 31, 232, 98, 153, 47, 31, 232, 98, 173, - 47, 31, 232, 98, 181, 47, 31, 232, 98, 176, 47, 31, 232, 98, 184, 47, 31, - 232, 230, 154, 199, 104, 16, 39, 222, 249, 154, 199, 104, 16, 39, 233, - 12, 154, 199, 104, 16, 39, 217, 39, 154, 199, 104, 16, 39, 250, 245, 154, - 199, 104, 16, 39, 217, 2, 154, 199, 104, 16, 39, 222, 148, 154, 199, 104, - 16, 39, 222, 149, 154, 199, 104, 16, 39, 250, 109, 154, 199, 104, 16, 39, - 204, 4, 154, 199, 104, 16, 39, 211, 145, 154, 199, 104, 16, 39, 212, 242, - 154, 199, 104, 16, 39, 237, 95, 51, 229, 146, 51, 233, 244, 51, 233, 189, - 219, 94, 219, 121, 57, 47, 71, 65, 47, 71, 70, 47, 71, 69, 47, 71, 73, - 47, 71, 74, 47, 71, 157, 47, 71, 221, 142, 47, 71, 220, 208, 47, 71, 221, - 253, 47, 71, 221, 43, 47, 71, 189, 47, 71, 202, 217, 47, 71, 200, 255, - 47, 71, 205, 63, 47, 71, 202, 41, 47, 71, 199, 247, 47, 71, 198, 188, 47, - 71, 197, 90, 47, 71, 199, 140, 47, 71, 159, 47, 71, 180, 47, 71, 213, - 205, 47, 71, 212, 165, 47, 71, 214, 107, 47, 71, 213, 30, 47, 71, 144, - 47, 71, 229, 126, 47, 71, 228, 128, 47, 71, 229, 213, 47, 71, 228, 247, - 47, 71, 172, 47, 71, 216, 81, 47, 71, 215, 139, 47, 71, 216, 213, 47, 71, - 215, 251, 47, 71, 169, 47, 71, 191, 225, 47, 71, 192, 12, 47, 71, 166, - 47, 71, 206, 252, 47, 71, 206, 63, 47, 71, 207, 108, 47, 71, 206, 157, - 47, 71, 193, 187, 47, 71, 193, 84, 47, 71, 193, 123, 47, 71, 193, 48, 51, - 233, 247, 214, 214, 207, 63, 51, 251, 14, 51, 250, 171, 51, 251, 41, 51, - 252, 111, 51, 223, 102, 51, 223, 69, 51, 196, 76, 51, 233, 216, 51, 234, - 142, 51, 211, 79, 51, 211, 72, 51, 222, 73, 51, 222, 37, 51, 222, 32, 51, - 231, 158, 51, 231, 168, 51, 231, 4, 51, 230, 255, 51, 220, 120, 51, 230, - 246, 51, 221, 107, 51, 221, 106, 51, 221, 105, 51, 221, 104, 51, 230, - 113, 51, 230, 112, 51, 220, 169, 51, 220, 172, 51, 221, 240, 51, 221, 5, - 51, 221, 14, 51, 205, 175, 51, 205, 128, 51, 202, 136, 51, 204, 10, 51, - 204, 9, 51, 237, 237, 51, 237, 36, 51, 236, 97, 51, 198, 76, 51, 214, - 207, 51, 212, 243, 51, 230, 42, 51, 210, 204, 51, 210, 203, 51, 249, 100, - 51, 209, 172, 51, 209, 134, 51, 209, 135, 51, 248, 108, 51, 228, 123, 51, - 228, 117, 51, 247, 173, 51, 228, 101, 51, 229, 174, 51, 209, 232, 51, - 210, 20, 51, 229, 155, 51, 210, 16, 51, 210, 34, 51, 248, 202, 51, 209, - 50, 51, 248, 36, 51, 228, 223, 51, 209, 31, 51, 228, 214, 51, 228, 216, - 51, 217, 89, 51, 217, 85, 51, 217, 94, 51, 217, 25, 51, 217, 56, 51, 216, - 38, 51, 216, 12, 51, 216, 11, 51, 216, 184, 51, 216, 181, 51, 216, 185, - 51, 192, 139, 51, 192, 137, 51, 191, 210, 51, 206, 173, 51, 206, 177, 51, - 206, 30, 51, 206, 23, 51, 207, 52, 51, 207, 49, 51, 193, 139, 154, 199, - 104, 16, 39, 228, 146, 191, 77, 154, 199, 104, 16, 39, 228, 146, 108, - 154, 199, 104, 16, 39, 228, 146, 109, 154, 199, 104, 16, 39, 228, 146, - 139, 154, 199, 104, 16, 39, 228, 146, 137, 154, 199, 104, 16, 39, 228, - 146, 153, 154, 199, 104, 16, 39, 228, 146, 173, 154, 199, 104, 16, 39, - 228, 146, 181, 154, 199, 104, 16, 39, 228, 146, 176, 154, 199, 104, 16, - 39, 228, 146, 184, 154, 199, 104, 16, 39, 228, 146, 199, 90, 154, 199, - 104, 16, 39, 228, 146, 234, 84, 154, 199, 104, 16, 39, 228, 146, 197, 33, - 154, 199, 104, 16, 39, 228, 146, 198, 246, 154, 199, 104, 16, 39, 228, - 146, 232, 84, 154, 199, 104, 16, 39, 228, 146, 232, 234, 154, 199, 104, - 16, 39, 228, 146, 202, 125, 154, 199, 104, 16, 39, 228, 146, 203, 239, - 154, 199, 104, 16, 39, 228, 146, 234, 118, 154, 199, 104, 16, 39, 228, - 146, 213, 158, 154, 199, 104, 16, 39, 228, 146, 197, 28, 154, 199, 104, - 16, 39, 228, 146, 197, 21, 154, 199, 104, 16, 39, 228, 146, 197, 16, 154, - 199, 104, 16, 39, 228, 146, 197, 18, 154, 199, 104, 16, 39, 228, 146, - 197, 23, 51, 228, 137, 51, 237, 241, 51, 250, 113, 51, 164, 51, 210, 255, - 51, 210, 58, 51, 236, 132, 51, 236, 133, 201, 184, 51, 236, 133, 238, - 142, 51, 223, 21, 51, 233, 247, 214, 214, 229, 175, 51, 233, 247, 214, - 214, 200, 62, 51, 233, 247, 214, 214, 199, 207, 51, 233, 247, 214, 214, - 216, 180, 51, 238, 206, 51, 210, 211, 251, 84, 51, 180, 51, 215, 140, 65, - 51, 172, 51, 157, 51, 222, 0, 51, 216, 253, 51, 231, 146, 51, 247, 96, - 51, 221, 255, 51, 209, 222, 51, 214, 58, 51, 215, 140, 233, 134, 51, 215, - 140, 232, 14, 51, 216, 122, 51, 221, 192, 51, 228, 53, 51, 221, 144, 51, - 216, 83, 51, 231, 18, 51, 198, 190, 51, 215, 140, 170, 51, 216, 3, 51, - 236, 142, 51, 221, 71, 51, 232, 137, 51, 213, 68, 51, 215, 140, 218, 147, - 51, 216, 0, 51, 242, 151, 51, 221, 57, 51, 216, 1, 201, 184, 51, 242, - 152, 201, 184, 51, 218, 148, 201, 184, 51, 221, 58, 201, 184, 51, 216, 1, - 238, 142, 51, 242, 152, 238, 142, 51, 218, 148, 238, 142, 51, 221, 58, - 238, 142, 51, 218, 148, 138, 206, 3, 51, 218, 148, 138, 206, 4, 201, 184, - 51, 168, 51, 220, 253, 51, 215, 150, 51, 230, 195, 51, 207, 163, 51, 207, - 164, 138, 206, 3, 51, 207, 164, 138, 206, 4, 201, 184, 51, 208, 171, 51, - 212, 206, 51, 215, 140, 206, 3, 51, 215, 142, 51, 208, 117, 51, 212, 99, - 51, 215, 140, 196, 8, 51, 215, 73, 51, 220, 158, 51, 215, 74, 216, 184, - 51, 208, 116, 51, 212, 98, 51, 215, 140, 193, 221, 51, 215, 67, 51, 220, - 156, 51, 215, 68, 216, 184, 51, 222, 126, 211, 122, 51, 218, 148, 211, - 122, 51, 251, 98, 51, 248, 9, 51, 247, 18, 51, 246, 251, 51, 247, 146, - 138, 221, 192, 51, 242, 51, 51, 237, 155, 51, 230, 96, 51, 144, 51, 228, - 138, 51, 223, 134, 51, 221, 78, 51, 221, 58, 247, 62, 51, 220, 210, 51, - 219, 22, 51, 219, 21, 51, 219, 6, 51, 218, 163, 51, 216, 254, 202, 65, - 51, 216, 37, 51, 215, 216, 51, 209, 220, 51, 209, 68, 51, 208, 242, 51, - 208, 240, 51, 201, 175, 51, 200, 154, 51, 193, 125, 51, 196, 9, 138, 218, - 147, 51, 41, 138, 218, 147, 154, 199, 104, 16, 39, 237, 159, 108, 154, - 199, 104, 16, 39, 237, 159, 109, 154, 199, 104, 16, 39, 237, 159, 139, - 154, 199, 104, 16, 39, 237, 159, 137, 154, 199, 104, 16, 39, 237, 159, - 153, 154, 199, 104, 16, 39, 237, 159, 173, 154, 199, 104, 16, 39, 237, - 159, 181, 154, 199, 104, 16, 39, 237, 159, 176, 154, 199, 104, 16, 39, - 237, 159, 184, 154, 199, 104, 16, 39, 237, 159, 199, 90, 154, 199, 104, - 16, 39, 237, 159, 234, 84, 154, 199, 104, 16, 39, 237, 159, 197, 33, 154, - 199, 104, 16, 39, 237, 159, 198, 246, 154, 199, 104, 16, 39, 237, 159, - 232, 84, 154, 199, 104, 16, 39, 237, 159, 232, 234, 154, 199, 104, 16, - 39, 237, 159, 202, 125, 154, 199, 104, 16, 39, 237, 159, 203, 239, 154, - 199, 104, 16, 39, 237, 159, 234, 118, 154, 199, 104, 16, 39, 237, 159, - 213, 158, 154, 199, 104, 16, 39, 237, 159, 197, 28, 154, 199, 104, 16, - 39, 237, 159, 197, 21, 154, 199, 104, 16, 39, 237, 159, 197, 16, 154, - 199, 104, 16, 39, 237, 159, 197, 18, 154, 199, 104, 16, 39, 237, 159, - 197, 23, 154, 199, 104, 16, 39, 237, 159, 197, 24, 154, 199, 104, 16, 39, - 237, 159, 197, 19, 154, 199, 104, 16, 39, 237, 159, 197, 20, 154, 199, - 104, 16, 39, 237, 159, 197, 27, 154, 199, 104, 16, 39, 237, 159, 197, 22, - 154, 199, 104, 16, 39, 237, 159, 198, 244, 154, 199, 104, 16, 39, 237, - 159, 198, 242, 51, 231, 185, 229, 149, 39, 199, 29, 238, 184, 229, 187, - 229, 149, 39, 199, 29, 207, 95, 234, 163, 229, 149, 39, 236, 225, 250, - 133, 199, 29, 248, 197, 229, 149, 39, 191, 238, 232, 129, 229, 149, 39, - 193, 168, 229, 149, 39, 239, 5, 229, 149, 39, 199, 29, 250, 196, 229, - 149, 39, 228, 230, 198, 82, 229, 149, 39, 2, 199, 189, 229, 149, 39, 197, - 253, 229, 149, 39, 210, 51, 229, 149, 39, 201, 99, 229, 149, 39, 233, 2, - 229, 149, 39, 230, 172, 209, 14, 229, 149, 39, 215, 237, 229, 149, 39, - 234, 32, 229, 149, 39, 232, 130, 229, 149, 39, 193, 21, 211, 94, 199, 29, - 237, 96, 229, 149, 39, 250, 249, 229, 149, 39, 238, 240, 229, 149, 39, - 248, 97, 198, 210, 229, 149, 39, 230, 193, 229, 149, 39, 201, 203, 251, - 13, 229, 149, 39, 207, 17, 229, 149, 39, 223, 96, 229, 149, 39, 230, 172, - 199, 189, 229, 149, 39, 215, 164, 238, 209, 229, 149, 39, 230, 172, 208, - 217, 229, 149, 39, 199, 29, 252, 13, 193, 141, 229, 149, 39, 199, 29, - 242, 179, 232, 202, 229, 149, 39, 223, 110, 229, 149, 39, 235, 20, 229, - 149, 39, 207, 20, 229, 149, 39, 230, 172, 208, 247, 229, 149, 39, 208, - 190, 229, 149, 39, 237, 175, 80, 199, 29, 219, 108, 229, 149, 39, 199, - 29, 233, 40, 229, 149, 39, 211, 51, 229, 149, 39, 211, 154, 229, 149, 39, - 237, 66, 229, 149, 39, 237, 88, 229, 149, 39, 223, 125, 229, 149, 39, - 247, 249, 229, 149, 39, 242, 28, 118, 216, 187, 229, 149, 39, 231, 153, - 198, 82, 229, 149, 39, 208, 128, 196, 63, 229, 149, 39, 211, 50, 229, - 149, 39, 199, 29, 193, 107, 229, 149, 39, 207, 8, 229, 149, 39, 199, 29, - 247, 24, 229, 149, 39, 199, 29, 250, 192, 198, 204, 229, 149, 39, 199, - 29, 221, 241, 201, 65, 215, 168, 229, 149, 39, 237, 31, 229, 149, 39, - 199, 29, 217, 28, 217, 90, 229, 149, 39, 252, 14, 229, 149, 39, 199, 29, - 193, 159, 229, 149, 39, 199, 29, 231, 108, 193, 64, 229, 149, 39, 199, - 29, 222, 157, 220, 19, 229, 149, 39, 236, 174, 229, 149, 39, 219, 95, - 229, 149, 39, 223, 99, 197, 172, 229, 149, 39, 2, 208, 217, 229, 149, 39, - 251, 202, 242, 18, 229, 149, 39, 248, 200, 242, 18, 11, 5, 223, 25, 11, - 5, 223, 17, 11, 5, 70, 11, 5, 223, 52, 11, 5, 223, 195, 11, 5, 223, 178, - 11, 5, 223, 197, 11, 5, 223, 196, 11, 5, 250, 132, 11, 5, 250, 83, 11, 5, - 65, 11, 5, 251, 15, 11, 5, 196, 74, 11, 5, 196, 78, 11, 5, 196, 75, 11, - 5, 211, 20, 11, 5, 210, 237, 11, 5, 74, 11, 5, 211, 67, 11, 5, 233, 180, - 11, 5, 73, 11, 5, 193, 0, 11, 5, 248, 100, 11, 5, 248, 95, 11, 5, 248, - 140, 11, 5, 248, 113, 11, 5, 248, 129, 11, 5, 248, 128, 11, 5, 248, 131, - 11, 5, 248, 130, 11, 5, 249, 14, 11, 5, 249, 6, 11, 5, 249, 103, 11, 5, - 249, 39, 11, 5, 247, 186, 11, 5, 247, 190, 11, 5, 247, 187, 11, 5, 248, - 33, 11, 5, 248, 14, 11, 5, 248, 63, 11, 5, 248, 41, 11, 5, 248, 156, 11, - 5, 248, 223, 11, 5, 248, 169, 11, 5, 247, 169, 11, 5, 247, 163, 11, 5, - 247, 218, 11, 5, 247, 184, 11, 5, 247, 177, 11, 5, 247, 182, 11, 5, 247, - 151, 11, 5, 247, 149, 11, 5, 247, 156, 11, 5, 247, 154, 11, 5, 247, 152, - 11, 5, 247, 153, 11, 5, 209, 109, 11, 5, 209, 105, 11, 5, 209, 176, 11, - 5, 209, 121, 11, 5, 209, 140, 11, 5, 209, 167, 11, 5, 209, 163, 11, 5, - 210, 79, 11, 5, 210, 63, 11, 5, 168, 11, 5, 210, 127, 11, 5, 208, 138, - 11, 5, 208, 140, 11, 5, 208, 139, 11, 5, 209, 7, 11, 5, 208, 245, 11, 5, - 209, 65, 11, 5, 209, 26, 11, 5, 208, 124, 11, 5, 208, 119, 11, 5, 208, - 158, 11, 5, 208, 137, 11, 5, 208, 129, 11, 5, 208, 135, 11, 5, 208, 101, - 11, 5, 208, 100, 11, 5, 208, 105, 11, 5, 208, 104, 11, 5, 208, 102, 11, - 5, 208, 103, 11, 5, 248, 244, 11, 5, 248, 243, 11, 5, 248, 250, 11, 5, - 248, 245, 11, 5, 248, 247, 11, 5, 248, 246, 11, 5, 248, 249, 11, 5, 248, - 248, 11, 5, 249, 0, 11, 5, 248, 255, 11, 5, 249, 3, 11, 5, 249, 1, 11, 5, - 248, 235, 11, 5, 248, 237, 11, 5, 248, 236, 11, 5, 248, 240, 11, 5, 248, - 239, 11, 5, 248, 242, 11, 5, 248, 241, 11, 5, 248, 251, 11, 5, 248, 254, - 11, 5, 248, 252, 11, 5, 248, 231, 11, 5, 248, 230, 11, 5, 248, 238, 11, - 5, 248, 234, 11, 5, 248, 232, 11, 5, 248, 233, 11, 5, 248, 227, 11, 5, - 248, 226, 11, 5, 248, 229, 11, 5, 248, 228, 11, 5, 214, 171, 11, 5, 214, - 170, 11, 5, 214, 176, 11, 5, 214, 172, 11, 5, 214, 173, 11, 5, 214, 175, - 11, 5, 214, 174, 11, 5, 214, 179, 11, 5, 214, 178, 11, 5, 214, 181, 11, - 5, 214, 180, 11, 5, 214, 167, 11, 5, 214, 166, 11, 5, 214, 169, 11, 5, - 214, 168, 11, 5, 214, 160, 11, 5, 214, 159, 11, 5, 214, 164, 11, 5, 214, - 163, 11, 5, 214, 161, 11, 5, 214, 162, 11, 5, 214, 154, 11, 5, 214, 153, - 11, 5, 214, 158, 11, 5, 214, 157, 11, 5, 214, 155, 11, 5, 214, 156, 11, - 5, 229, 35, 11, 5, 229, 34, 11, 5, 229, 40, 11, 5, 229, 36, 11, 5, 229, - 37, 11, 5, 229, 39, 11, 5, 229, 38, 11, 5, 229, 43, 11, 5, 229, 42, 11, - 5, 229, 45, 11, 5, 229, 44, 11, 5, 229, 26, 11, 5, 229, 28, 11, 5, 229, - 27, 11, 5, 229, 31, 11, 5, 229, 30, 11, 5, 229, 33, 11, 5, 229, 32, 11, - 5, 229, 22, 11, 5, 229, 21, 11, 5, 229, 29, 11, 5, 229, 25, 11, 5, 229, - 23, 11, 5, 229, 24, 11, 5, 229, 16, 11, 5, 229, 20, 11, 5, 229, 19, 11, - 5, 229, 17, 11, 5, 229, 18, 11, 5, 216, 6, 11, 5, 216, 5, 11, 5, 216, 81, - 11, 5, 216, 14, 11, 5, 216, 45, 11, 5, 216, 63, 11, 5, 216, 61, 11, 5, - 217, 11, 11, 5, 217, 5, 11, 5, 172, 11, 5, 217, 51, 11, 5, 215, 101, 11, - 5, 215, 100, 11, 5, 215, 104, 11, 5, 215, 102, 11, 5, 215, 179, 11, 5, - 215, 152, 11, 5, 215, 251, 11, 5, 215, 186, 11, 5, 216, 133, 11, 5, 216, - 213, 11, 5, 215, 81, 11, 5, 215, 75, 11, 5, 215, 139, 11, 5, 215, 97, 11, - 5, 215, 90, 11, 5, 215, 95, 11, 5, 215, 51, 11, 5, 215, 50, 11, 5, 215, - 56, 11, 5, 215, 53, 11, 5, 232, 188, 11, 5, 232, 182, 11, 5, 232, 238, - 11, 5, 232, 204, 11, 5, 233, 31, 11, 5, 233, 22, 11, 5, 233, 68, 11, 5, - 233, 36, 11, 5, 232, 81, 11, 5, 232, 135, 11, 5, 232, 115, 11, 5, 232, - 31, 11, 5, 232, 30, 11, 5, 232, 48, 11, 5, 232, 36, 11, 5, 232, 34, 11, - 5, 232, 35, 11, 5, 232, 17, 11, 5, 232, 16, 11, 5, 232, 20, 11, 5, 232, - 18, 11, 5, 195, 29, 11, 5, 195, 23, 11, 5, 195, 66, 11, 5, 195, 38, 11, - 5, 195, 55, 11, 5, 195, 50, 11, 5, 195, 58, 11, 5, 195, 57, 11, 5, 195, - 159, 11, 5, 195, 154, 11, 5, 195, 185, 11, 5, 195, 172, 11, 5, 195, 1, - 11, 5, 194, 253, 11, 5, 195, 21, 11, 5, 195, 3, 11, 5, 195, 70, 11, 5, - 195, 138, 11, 5, 193, 239, 11, 5, 193, 237, 11, 5, 193, 246, 11, 5, 193, - 242, 11, 5, 193, 240, 11, 5, 193, 241, 11, 5, 193, 226, 11, 5, 193, 225, - 11, 5, 193, 232, 11, 5, 193, 231, 11, 5, 193, 229, 11, 5, 193, 230, 11, - 5, 236, 167, 11, 5, 236, 152, 11, 5, 236, 255, 11, 5, 236, 195, 11, 5, - 236, 230, 11, 5, 236, 235, 11, 5, 236, 234, 11, 5, 237, 166, 11, 5, 237, - 160, 11, 5, 237, 241, 11, 5, 237, 186, 11, 5, 235, 25, 11, 5, 235, 26, - 11, 5, 236, 96, 11, 5, 235, 73, 11, 5, 236, 129, 11, 5, 236, 99, 11, 5, - 237, 29, 11, 5, 237, 101, 11, 5, 237, 51, 11, 5, 235, 16, 11, 5, 235, 14, - 11, 5, 235, 45, 11, 5, 235, 24, 11, 5, 235, 19, 11, 5, 235, 22, 11, 5, - 198, 120, 11, 5, 198, 112, 11, 5, 198, 188, 11, 5, 198, 130, 11, 5, 198, - 171, 11, 5, 198, 173, 11, 5, 198, 172, 11, 5, 199, 166, 11, 5, 199, 151, - 11, 5, 199, 247, 11, 5, 199, 178, 11, 5, 197, 65, 11, 5, 197, 64, 11, 5, - 197, 67, 11, 5, 197, 66, 11, 5, 198, 35, 11, 5, 198, 24, 11, 5, 159, 11, - 5, 198, 48, 11, 5, 199, 50, 11, 5, 199, 140, 11, 5, 199, 77, 11, 5, 197, - 48, 11, 5, 197, 43, 11, 5, 197, 90, 11, 5, 197, 63, 11, 5, 197, 49, 11, - 5, 197, 60, 11, 5, 237, 118, 11, 5, 237, 117, 11, 5, 237, 123, 11, 5, - 237, 119, 11, 5, 237, 120, 11, 5, 237, 122, 11, 5, 237, 121, 11, 5, 237, - 139, 11, 5, 237, 138, 11, 5, 237, 146, 11, 5, 237, 140, 11, 5, 237, 108, - 11, 5, 237, 110, 11, 5, 237, 109, 11, 5, 237, 113, 11, 5, 237, 112, 11, - 5, 237, 116, 11, 5, 237, 114, 11, 5, 237, 131, 11, 5, 237, 134, 11, 5, - 237, 132, 11, 5, 237, 104, 11, 5, 237, 103, 11, 5, 237, 111, 11, 5, 237, - 107, 11, 5, 237, 105, 11, 5, 237, 106, 11, 5, 214, 126, 11, 5, 214, 125, - 11, 5, 214, 133, 11, 5, 214, 128, 11, 5, 214, 129, 11, 5, 214, 130, 11, - 5, 214, 142, 11, 5, 214, 141, 11, 5, 214, 148, 11, 5, 214, 143, 11, 5, - 214, 118, 11, 5, 214, 117, 11, 5, 214, 124, 11, 5, 214, 119, 11, 5, 214, - 134, 11, 5, 214, 140, 11, 5, 214, 138, 11, 5, 214, 110, 11, 5, 214, 109, - 11, 5, 214, 115, 11, 5, 214, 113, 11, 5, 214, 111, 11, 5, 214, 112, 11, - 5, 229, 1, 11, 5, 229, 0, 11, 5, 229, 7, 11, 5, 229, 2, 11, 5, 229, 4, - 11, 5, 229, 3, 11, 5, 229, 6, 11, 5, 229, 5, 11, 5, 229, 13, 11, 5, 229, - 11, 11, 5, 229, 15, 11, 5, 229, 14, 11, 5, 228, 250, 11, 5, 228, 251, 11, - 5, 228, 254, 11, 5, 228, 253, 11, 5, 228, 255, 11, 5, 229, 8, 11, 5, 229, - 10, 11, 5, 229, 9, 11, 5, 228, 249, 11, 5, 213, 149, 11, 5, 213, 147, 11, - 5, 213, 205, 11, 5, 213, 152, 11, 5, 213, 179, 11, 5, 213, 193, 11, 5, - 213, 192, 11, 5, 214, 186, 11, 5, 180, 11, 5, 214, 204, 11, 5, 212, 109, - 11, 5, 212, 111, 11, 5, 212, 110, 11, 5, 212, 254, 11, 5, 212, 238, 11, - 5, 213, 30, 11, 5, 213, 9, 11, 5, 214, 60, 11, 5, 214, 107, 11, 5, 214, - 83, 11, 5, 212, 104, 11, 5, 212, 100, 11, 5, 212, 165, 11, 5, 212, 108, - 11, 5, 212, 106, 11, 5, 212, 107, 11, 5, 229, 66, 11, 5, 229, 65, 11, 5, - 229, 71, 11, 5, 229, 67, 11, 5, 229, 68, 11, 5, 229, 70, 11, 5, 229, 69, - 11, 5, 229, 77, 11, 5, 229, 75, 11, 5, 229, 79, 11, 5, 229, 78, 11, 5, - 229, 58, 11, 5, 229, 60, 11, 5, 229, 59, 11, 5, 229, 62, 11, 5, 229, 64, - 11, 5, 229, 63, 11, 5, 229, 72, 11, 5, 229, 74, 11, 5, 229, 73, 11, 5, - 229, 54, 11, 5, 229, 53, 11, 5, 229, 61, 11, 5, 229, 57, 11, 5, 229, 55, - 11, 5, 229, 56, 11, 5, 229, 48, 11, 5, 229, 47, 11, 5, 229, 52, 11, 5, - 229, 51, 11, 5, 229, 49, 11, 5, 229, 50, 11, 5, 219, 63, 11, 5, 219, 55, - 11, 5, 219, 122, 11, 5, 219, 74, 11, 5, 219, 113, 11, 5, 219, 112, 11, 5, - 219, 116, 11, 5, 219, 114, 11, 5, 219, 237, 11, 5, 219, 225, 11, 5, 171, - 11, 5, 219, 248, 11, 5, 218, 180, 11, 5, 218, 179, 11, 5, 218, 182, 11, - 5, 218, 181, 11, 5, 218, 227, 11, 5, 218, 212, 11, 5, 219, 19, 11, 5, - 218, 233, 11, 5, 219, 140, 11, 5, 219, 214, 11, 5, 219, 160, 11, 5, 218, - 174, 11, 5, 218, 172, 11, 5, 218, 203, 11, 5, 218, 178, 11, 5, 218, 176, - 11, 5, 218, 177, 11, 5, 218, 152, 11, 5, 218, 151, 11, 5, 218, 162, 11, - 5, 218, 155, 11, 5, 218, 153, 11, 5, 218, 154, 11, 5, 230, 242, 11, 5, - 230, 241, 11, 5, 231, 16, 11, 5, 230, 254, 11, 5, 231, 8, 11, 5, 231, 7, - 11, 5, 231, 10, 11, 5, 231, 9, 11, 5, 231, 155, 11, 5, 231, 150, 11, 5, - 231, 203, 11, 5, 231, 166, 11, 5, 230, 119, 11, 5, 230, 118, 11, 5, 230, - 121, 11, 5, 230, 120, 11, 5, 230, 198, 11, 5, 230, 196, 11, 5, 230, 223, - 11, 5, 230, 208, 11, 5, 231, 94, 11, 5, 231, 92, 11, 5, 231, 128, 11, 5, - 231, 105, 11, 5, 230, 107, 11, 5, 230, 106, 11, 5, 230, 146, 11, 5, 230, - 117, 11, 5, 230, 108, 11, 5, 230, 116, 11, 5, 221, 96, 11, 5, 221, 91, - 11, 5, 221, 142, 11, 5, 221, 110, 11, 5, 221, 123, 11, 5, 221, 127, 11, - 5, 221, 125, 11, 5, 222, 23, 11, 5, 222, 5, 11, 5, 157, 11, 5, 222, 52, - 11, 5, 220, 178, 11, 5, 220, 183, 11, 5, 220, 180, 11, 5, 221, 4, 11, 5, - 220, 255, 11, 5, 221, 43, 11, 5, 221, 12, 11, 5, 221, 216, 11, 5, 221, - 199, 11, 5, 221, 253, 11, 5, 221, 220, 11, 5, 220, 164, 11, 5, 220, 160, - 11, 5, 220, 208, 11, 5, 220, 177, 11, 5, 220, 168, 11, 5, 220, 173, 11, - 5, 231, 76, 11, 5, 231, 75, 11, 5, 231, 80, 11, 5, 231, 77, 11, 5, 231, - 79, 11, 5, 231, 78, 11, 5, 231, 87, 11, 5, 231, 86, 11, 5, 231, 90, 11, - 5, 231, 88, 11, 5, 231, 67, 11, 5, 231, 66, 11, 5, 231, 69, 11, 5, 231, - 68, 11, 5, 231, 72, 11, 5, 231, 71, 11, 5, 231, 74, 11, 5, 231, 73, 11, - 5, 231, 82, 11, 5, 231, 81, 11, 5, 231, 85, 11, 5, 231, 83, 11, 5, 231, - 62, 11, 5, 231, 61, 11, 5, 231, 70, 11, 5, 231, 65, 11, 5, 231, 63, 11, - 5, 231, 64, 11, 5, 216, 100, 11, 5, 216, 101, 11, 5, 216, 119, 11, 5, - 216, 118, 11, 5, 216, 121, 11, 5, 216, 120, 11, 5, 216, 91, 11, 5, 216, - 93, 11, 5, 216, 92, 11, 5, 216, 96, 11, 5, 216, 95, 11, 5, 216, 98, 11, - 5, 216, 97, 11, 5, 216, 102, 11, 5, 216, 104, 11, 5, 216, 103, 11, 5, - 216, 87, 11, 5, 216, 86, 11, 5, 216, 94, 11, 5, 216, 90, 11, 5, 216, 88, - 11, 5, 216, 89, 11, 5, 228, 73, 11, 5, 228, 72, 11, 5, 228, 79, 11, 5, - 228, 74, 11, 5, 228, 76, 11, 5, 228, 75, 11, 5, 228, 78, 11, 5, 228, 77, - 11, 5, 228, 84, 11, 5, 228, 83, 11, 5, 228, 86, 11, 5, 228, 85, 11, 5, - 228, 65, 11, 5, 228, 64, 11, 5, 228, 67, 11, 5, 228, 66, 11, 5, 228, 69, - 11, 5, 228, 68, 11, 5, 228, 71, 11, 5, 228, 70, 11, 5, 228, 80, 11, 5, - 228, 82, 11, 5, 228, 81, 11, 5, 213, 255, 11, 5, 214, 1, 11, 5, 214, 0, - 11, 5, 214, 44, 11, 5, 214, 42, 11, 5, 214, 54, 11, 5, 214, 47, 11, 5, - 213, 216, 11, 5, 213, 215, 11, 5, 213, 217, 11, 5, 213, 227, 11, 5, 213, - 224, 11, 5, 213, 235, 11, 5, 213, 229, 11, 5, 214, 35, 11, 5, 214, 41, - 11, 5, 214, 37, 11, 5, 229, 85, 11, 5, 229, 104, 11, 5, 229, 113, 11, 5, - 229, 232, 11, 5, 229, 221, 11, 5, 144, 11, 5, 229, 244, 11, 5, 228, 103, - 11, 5, 228, 102, 11, 5, 228, 105, 11, 5, 228, 104, 11, 5, 228, 149, 11, - 5, 228, 140, 11, 5, 228, 247, 11, 5, 228, 212, 11, 5, 229, 151, 11, 5, - 229, 213, 11, 5, 229, 163, 11, 5, 193, 144, 11, 5, 193, 129, 11, 5, 193, - 187, 11, 5, 193, 156, 11, 5, 192, 245, 11, 5, 192, 247, 11, 5, 192, 246, - 11, 5, 193, 13, 11, 5, 193, 48, 11, 5, 193, 24, 11, 5, 193, 97, 11, 5, - 193, 123, 11, 5, 193, 104, 11, 5, 191, 15, 11, 5, 191, 14, 11, 5, 191, - 30, 11, 5, 191, 18, 11, 5, 191, 23, 11, 5, 191, 25, 11, 5, 191, 24, 11, - 5, 191, 96, 11, 5, 191, 93, 11, 5, 191, 123, 11, 5, 191, 104, 11, 5, 190, - 244, 11, 5, 190, 246, 11, 5, 190, 245, 11, 5, 191, 2, 11, 5, 191, 1, 11, - 5, 191, 7, 11, 5, 191, 3, 11, 5, 191, 73, 11, 5, 191, 87, 11, 5, 191, 79, - 11, 5, 190, 240, 11, 5, 190, 239, 11, 5, 190, 251, 11, 5, 190, 243, 11, - 5, 190, 241, 11, 5, 190, 242, 11, 5, 190, 226, 11, 5, 190, 225, 11, 5, - 190, 231, 11, 5, 190, 229, 11, 5, 190, 227, 11, 5, 190, 228, 11, 5, 242, - 207, 11, 5, 242, 200, 11, 5, 242, 237, 11, 5, 242, 220, 11, 5, 242, 234, - 11, 5, 242, 228, 11, 5, 242, 236, 11, 5, 242, 235, 11, 5, 247, 30, 11, 5, - 247, 21, 11, 5, 247, 112, 11, 5, 247, 63, 11, 5, 238, 136, 11, 5, 238, - 138, 11, 5, 238, 137, 11, 5, 238, 202, 11, 5, 238, 190, 11, 5, 242, 51, - 11, 5, 238, 222, 11, 5, 246, 213, 11, 5, 246, 250, 11, 5, 246, 219, 11, - 5, 238, 107, 11, 5, 238, 105, 11, 5, 238, 148, 11, 5, 238, 134, 11, 5, - 238, 113, 11, 5, 238, 129, 11, 5, 238, 83, 11, 5, 238, 82, 11, 5, 238, - 96, 11, 5, 238, 90, 11, 5, 238, 84, 11, 5, 238, 86, 11, 5, 190, 209, 11, - 5, 190, 208, 11, 5, 190, 215, 11, 5, 190, 210, 11, 5, 190, 212, 11, 5, - 190, 211, 11, 5, 190, 214, 11, 5, 190, 213, 11, 5, 190, 221, 11, 5, 190, - 220, 11, 5, 190, 224, 11, 5, 190, 222, 11, 5, 190, 205, 11, 5, 190, 207, - 11, 5, 190, 206, 11, 5, 190, 216, 11, 5, 190, 219, 11, 5, 190, 217, 11, - 5, 190, 198, 11, 5, 190, 202, 11, 5, 190, 201, 11, 5, 190, 199, 11, 5, - 190, 200, 11, 5, 190, 192, 11, 5, 190, 191, 11, 5, 190, 197, 11, 5, 190, - 195, 11, 5, 190, 193, 11, 5, 190, 194, 11, 5, 212, 20, 11, 5, 212, 19, - 11, 5, 212, 25, 11, 5, 212, 21, 11, 5, 212, 22, 11, 5, 212, 24, 11, 5, - 212, 23, 11, 5, 212, 30, 11, 5, 212, 29, 11, 5, 212, 33, 11, 5, 212, 32, - 11, 5, 212, 13, 11, 5, 212, 14, 11, 5, 212, 17, 11, 5, 212, 18, 11, 5, - 212, 26, 11, 5, 212, 28, 11, 5, 212, 8, 11, 5, 212, 16, 11, 5, 212, 12, - 11, 5, 212, 9, 11, 5, 212, 10, 11, 5, 212, 3, 11, 5, 212, 2, 11, 5, 212, - 7, 11, 5, 212, 6, 11, 5, 212, 4, 11, 5, 212, 5, 11, 5, 202, 133, 11, 5, - 173, 11, 5, 202, 217, 11, 5, 202, 137, 11, 5, 202, 197, 11, 5, 202, 200, - 11, 5, 202, 198, 11, 5, 205, 117, 11, 5, 205, 101, 11, 5, 189, 11, 5, - 205, 125, 11, 5, 200, 183, 11, 5, 200, 185, 11, 5, 200, 184, 11, 5, 202, - 3, 11, 5, 201, 248, 11, 5, 202, 41, 11, 5, 202, 9, 11, 5, 203, 233, 11, - 5, 205, 63, 11, 5, 204, 8, 11, 5, 200, 158, 11, 5, 200, 155, 11, 5, 200, - 255, 11, 5, 200, 182, 11, 5, 200, 162, 11, 5, 200, 170, 11, 5, 200, 53, - 11, 5, 200, 52, 11, 5, 200, 123, 11, 5, 200, 61, 11, 5, 200, 55, 11, 5, - 200, 60, 11, 5, 201, 131, 11, 5, 201, 130, 11, 5, 201, 137, 11, 5, 201, - 132, 11, 5, 201, 134, 11, 5, 201, 136, 11, 5, 201, 135, 11, 5, 201, 146, - 11, 5, 201, 144, 11, 5, 201, 170, 11, 5, 201, 147, 11, 5, 201, 126, 11, - 5, 201, 125, 11, 5, 201, 129, 11, 5, 201, 127, 11, 5, 201, 140, 11, 5, - 201, 143, 11, 5, 201, 141, 11, 5, 201, 122, 11, 5, 201, 120, 11, 5, 201, - 124, 11, 5, 201, 123, 11, 5, 201, 115, 11, 5, 201, 114, 11, 5, 201, 119, - 11, 5, 201, 118, 11, 5, 201, 116, 11, 5, 201, 117, 11, 5, 191, 66, 11, 5, - 191, 65, 11, 5, 191, 71, 11, 5, 191, 68, 11, 5, 191, 45, 11, 5, 191, 47, - 11, 5, 191, 46, 11, 5, 191, 50, 11, 5, 191, 49, 11, 5, 191, 54, 11, 5, - 191, 51, 11, 5, 191, 59, 11, 5, 191, 58, 11, 5, 191, 62, 11, 5, 191, 60, - 11, 5, 191, 41, 11, 5, 191, 40, 11, 5, 191, 48, 11, 5, 191, 44, 11, 5, - 191, 42, 11, 5, 191, 43, 11, 5, 191, 33, 11, 5, 191, 32, 11, 5, 191, 37, - 11, 5, 191, 36, 11, 5, 191, 34, 11, 5, 191, 35, 11, 5, 243, 85, 11, 5, - 243, 81, 11, 5, 246, 209, 11, 5, 246, 195, 11, 5, 242, 252, 11, 5, 242, - 251, 11, 5, 242, 254, 11, 5, 242, 253, 11, 5, 243, 11, 11, 5, 243, 10, - 11, 5, 243, 20, 11, 5, 243, 15, 11, 5, 243, 54, 11, 5, 243, 51, 11, 5, - 243, 79, 11, 5, 243, 62, 11, 5, 242, 246, 11, 5, 243, 0, 11, 5, 242, 250, - 11, 5, 242, 247, 11, 5, 242, 249, 11, 5, 242, 239, 11, 5, 242, 238, 11, - 5, 242, 243, 11, 5, 242, 242, 11, 5, 242, 240, 11, 5, 242, 241, 11, 5, - 206, 100, 11, 5, 206, 104, 11, 5, 206, 82, 11, 5, 206, 83, 11, 5, 206, - 87, 11, 5, 206, 86, 11, 5, 206, 90, 11, 5, 206, 88, 11, 5, 206, 94, 11, - 5, 206, 93, 11, 5, 206, 99, 11, 5, 206, 95, 11, 5, 206, 78, 11, 5, 206, - 76, 11, 5, 206, 84, 11, 5, 206, 81, 11, 5, 206, 79, 11, 5, 206, 80, 11, - 5, 206, 71, 11, 5, 206, 70, 11, 5, 206, 75, 11, 5, 206, 74, 11, 5, 206, - 72, 11, 5, 206, 73, 11, 5, 212, 229, 11, 5, 212, 228, 11, 5, 212, 231, - 11, 5, 212, 230, 11, 5, 212, 220, 11, 5, 212, 222, 11, 5, 212, 221, 11, - 5, 212, 224, 11, 5, 212, 223, 11, 5, 212, 227, 11, 5, 212, 226, 11, 5, - 212, 214, 11, 5, 212, 213, 11, 5, 212, 219, 11, 5, 212, 217, 11, 5, 212, - 215, 11, 5, 212, 216, 11, 5, 212, 208, 11, 5, 212, 207, 11, 5, 212, 212, - 11, 5, 212, 211, 11, 5, 212, 209, 11, 5, 212, 210, 11, 5, 203, 118, 11, - 5, 203, 113, 11, 5, 203, 160, 11, 5, 203, 131, 11, 5, 202, 244, 11, 5, - 202, 246, 11, 5, 202, 245, 11, 5, 203, 19, 11, 5, 203, 14, 11, 5, 203, - 51, 11, 5, 203, 39, 11, 5, 203, 86, 11, 5, 203, 79, 11, 5, 203, 108, 11, - 5, 203, 95, 11, 5, 202, 240, 11, 5, 202, 237, 11, 5, 203, 0, 11, 5, 202, - 243, 11, 5, 202, 241, 11, 5, 202, 242, 11, 5, 202, 220, 11, 5, 202, 219, - 11, 5, 202, 226, 11, 5, 202, 223, 11, 5, 202, 221, 11, 5, 202, 222, 11, - 5, 207, 125, 11, 5, 207, 118, 11, 5, 166, 11, 5, 207, 131, 11, 5, 206, - 33, 11, 5, 206, 35, 11, 5, 206, 34, 11, 5, 206, 118, 11, 5, 206, 106, 11, - 5, 206, 157, 11, 5, 206, 122, 11, 5, 207, 6, 11, 5, 207, 108, 11, 5, 207, - 48, 11, 5, 206, 25, 11, 5, 206, 22, 11, 5, 206, 63, 11, 5, 206, 32, 11, - 5, 206, 28, 11, 5, 206, 29, 11, 5, 206, 7, 11, 5, 206, 6, 11, 5, 206, 12, - 11, 5, 206, 10, 11, 5, 206, 8, 11, 5, 206, 9, 11, 5, 222, 205, 11, 5, - 222, 204, 11, 5, 222, 217, 11, 5, 222, 206, 11, 5, 222, 213, 11, 5, 222, - 212, 11, 5, 222, 215, 11, 5, 222, 214, 11, 5, 222, 143, 11, 5, 222, 142, - 11, 5, 222, 145, 11, 5, 222, 144, 11, 5, 222, 161, 11, 5, 222, 159, 11, - 5, 222, 174, 11, 5, 222, 163, 11, 5, 222, 136, 11, 5, 222, 134, 11, 5, - 222, 155, 11, 5, 222, 141, 11, 5, 222, 138, 11, 5, 222, 139, 11, 5, 222, - 128, 11, 5, 222, 127, 11, 5, 222, 132, 11, 5, 222, 131, 11, 5, 222, 129, - 11, 5, 222, 130, 11, 5, 208, 43, 11, 5, 208, 41, 11, 5, 208, 51, 11, 5, - 208, 44, 11, 5, 208, 48, 11, 5, 208, 47, 11, 5, 208, 50, 11, 5, 208, 49, - 11, 5, 207, 248, 11, 5, 207, 245, 11, 5, 207, 250, 11, 5, 207, 249, 11, - 5, 208, 30, 11, 5, 208, 29, 11, 5, 208, 39, 11, 5, 208, 33, 11, 5, 207, - 240, 11, 5, 207, 236, 11, 5, 208, 27, 11, 5, 207, 244, 11, 5, 207, 242, - 11, 5, 207, 243, 11, 5, 207, 220, 11, 5, 207, 218, 11, 5, 207, 230, 11, - 5, 207, 223, 11, 5, 207, 221, 11, 5, 207, 222, 11, 5, 222, 194, 11, 5, - 222, 193, 11, 5, 222, 200, 11, 5, 222, 195, 11, 5, 222, 197, 11, 5, 222, - 196, 11, 5, 222, 199, 11, 5, 222, 198, 11, 5, 222, 185, 11, 5, 222, 187, - 11, 5, 222, 186, 11, 5, 222, 190, 11, 5, 222, 189, 11, 5, 222, 192, 11, - 5, 222, 191, 11, 5, 222, 181, 11, 5, 222, 180, 11, 5, 222, 188, 11, 5, - 222, 184, 11, 5, 222, 182, 11, 5, 222, 183, 11, 5, 222, 177, 11, 5, 222, - 176, 11, 5, 222, 179, 11, 5, 222, 178, 11, 5, 213, 121, 11, 5, 213, 120, - 11, 5, 213, 128, 11, 5, 213, 122, 11, 5, 213, 124, 11, 5, 213, 123, 11, - 5, 213, 127, 11, 5, 213, 125, 11, 5, 213, 110, 11, 5, 213, 111, 11, 5, - 213, 116, 11, 5, 213, 115, 11, 5, 213, 119, 11, 5, 213, 117, 11, 5, 213, - 105, 11, 5, 213, 114, 11, 5, 213, 109, 11, 5, 213, 106, 11, 5, 213, 107, - 11, 5, 213, 100, 11, 5, 213, 99, 11, 5, 213, 104, 11, 5, 213, 103, 11, 5, - 213, 101, 11, 5, 213, 102, 11, 5, 212, 55, 11, 5, 212, 54, 11, 5, 212, - 68, 11, 5, 212, 59, 11, 5, 212, 64, 11, 5, 212, 63, 11, 5, 212, 66, 11, - 5, 212, 65, 11, 5, 212, 40, 11, 5, 212, 42, 11, 5, 212, 41, 11, 5, 212, - 47, 11, 5, 212, 46, 11, 5, 212, 52, 11, 5, 212, 48, 11, 5, 212, 38, 11, - 5, 212, 36, 11, 5, 212, 45, 11, 5, 212, 39, 11, 5, 192, 198, 11, 5, 192, - 197, 11, 5, 192, 207, 11, 5, 192, 200, 11, 5, 192, 202, 11, 5, 192, 201, - 11, 5, 192, 204, 11, 5, 192, 203, 11, 5, 192, 186, 11, 5, 192, 187, 11, - 5, 192, 191, 11, 5, 192, 190, 11, 5, 192, 196, 11, 5, 192, 194, 11, 5, - 192, 163, 11, 5, 192, 161, 11, 5, 192, 176, 11, 5, 192, 166, 11, 5, 192, - 164, 11, 5, 192, 165, 11, 5, 192, 18, 11, 5, 192, 16, 11, 5, 192, 33, 11, - 5, 192, 19, 11, 5, 192, 27, 11, 5, 192, 26, 11, 5, 192, 30, 11, 5, 192, - 28, 11, 5, 191, 198, 11, 5, 191, 197, 11, 5, 191, 201, 11, 5, 191, 199, - 11, 5, 191, 240, 11, 5, 191, 235, 11, 5, 192, 12, 11, 5, 191, 245, 11, 5, - 191, 189, 11, 5, 191, 185, 11, 5, 191, 225, 11, 5, 191, 196, 11, 5, 191, - 192, 11, 5, 191, 193, 11, 5, 191, 169, 11, 5, 191, 168, 11, 5, 191, 176, - 11, 5, 191, 172, 11, 5, 191, 170, 11, 5, 191, 171, 11, 48, 208, 30, 11, - 48, 219, 122, 11, 48, 221, 96, 11, 48, 212, 59, 11, 48, 238, 90, 11, 48, - 201, 137, 11, 48, 231, 73, 11, 48, 231, 105, 11, 48, 216, 81, 11, 48, - 228, 73, 11, 48, 218, 154, 11, 48, 248, 231, 11, 48, 215, 186, 11, 48, - 192, 12, 11, 48, 208, 124, 11, 48, 228, 67, 11, 48, 199, 166, 11, 48, - 231, 203, 11, 48, 190, 243, 11, 48, 238, 83, 11, 48, 237, 106, 11, 48, - 247, 182, 11, 48, 231, 69, 11, 48, 212, 48, 11, 48, 197, 90, 11, 48, 211, - 67, 11, 48, 222, 181, 11, 48, 191, 2, 11, 48, 208, 101, 11, 48, 229, 33, - 11, 48, 192, 18, 11, 48, 193, 241, 11, 48, 202, 226, 11, 48, 195, 138, - 11, 48, 191, 123, 11, 48, 222, 174, 11, 48, 212, 12, 11, 48, 222, 179, - 11, 48, 230, 198, 11, 48, 222, 199, 11, 48, 193, 48, 11, 48, 235, 45, 11, - 48, 202, 242, 11, 48, 219, 116, 11, 48, 238, 96, 11, 48, 238, 137, 11, - 48, 242, 220, 11, 48, 228, 70, 11, 48, 203, 118, 11, 48, 190, 242, 11, - 48, 203, 39, 11, 48, 243, 79, 11, 48, 190, 212, 11, 48, 214, 175, 11, 48, - 221, 253, 219, 64, 1, 249, 103, 219, 64, 1, 168, 219, 64, 1, 209, 219, - 219, 64, 1, 237, 241, 219, 64, 1, 199, 247, 219, 64, 1, 199, 44, 219, 64, - 1, 231, 203, 219, 64, 1, 157, 219, 64, 1, 221, 190, 219, 64, 1, 223, 4, - 219, 64, 1, 247, 112, 219, 64, 1, 246, 209, 219, 64, 1, 234, 247, 219, - 64, 1, 197, 164, 219, 64, 1, 197, 153, 219, 64, 1, 172, 219, 64, 1, 180, - 219, 64, 1, 171, 219, 64, 1, 189, 219, 64, 1, 191, 71, 219, 64, 1, 191, - 123, 219, 64, 1, 214, 54, 219, 64, 1, 144, 219, 64, 1, 192, 220, 219, 64, - 1, 229, 145, 219, 64, 1, 233, 68, 219, 64, 1, 193, 187, 219, 64, 1, 203, - 160, 219, 64, 1, 169, 219, 64, 1, 231, 54, 219, 64, 1, 65, 219, 64, 1, - 251, 229, 219, 64, 1, 73, 219, 64, 1, 233, 201, 219, 64, 1, 70, 219, 64, - 1, 74, 219, 64, 1, 69, 219, 64, 1, 196, 148, 219, 64, 1, 196, 137, 219, - 64, 1, 211, 139, 219, 64, 1, 163, 215, 55, 198, 188, 219, 64, 1, 163, - 214, 249, 209, 65, 219, 64, 1, 163, 215, 55, 238, 95, 219, 64, 1, 163, - 215, 55, 248, 63, 219, 64, 1, 163, 215, 55, 180, 219, 64, 1, 163, 215, - 55, 222, 226, 219, 64, 208, 145, 242, 26, 219, 64, 208, 145, 232, 42, - 201, 58, 58, 5, 234, 145, 58, 5, 234, 141, 58, 5, 229, 183, 58, 5, 193, - 112, 58, 5, 193, 111, 58, 5, 210, 40, 58, 5, 248, 147, 58, 5, 248, 207, - 58, 5, 216, 240, 58, 5, 220, 248, 58, 5, 216, 113, 58, 5, 231, 141, 58, - 5, 233, 11, 58, 5, 195, 145, 58, 5, 199, 116, 58, 5, 199, 26, 58, 5, 237, - 13, 58, 5, 237, 10, 58, 5, 219, 204, 58, 5, 207, 79, 58, 5, 237, 86, 58, - 5, 214, 139, 58, 5, 205, 45, 58, 5, 203, 106, 58, 5, 191, 84, 58, 5, 191, - 61, 58, 5, 246, 242, 58, 5, 222, 236, 58, 5, 213, 135, 58, 5, 192, 77, - 58, 5, 221, 244, 58, 5, 214, 27, 58, 5, 231, 120, 58, 5, 216, 192, 58, 5, - 214, 96, 58, 5, 212, 76, 58, 5, 70, 58, 5, 223, 134, 58, 5, 229, 126, 58, - 5, 229, 96, 58, 5, 193, 84, 58, 5, 193, 66, 58, 5, 209, 176, 58, 5, 248, - 145, 58, 5, 248, 140, 58, 5, 216, 233, 58, 5, 220, 245, 58, 5, 216, 110, - 58, 5, 231, 137, 58, 5, 232, 238, 58, 5, 195, 66, 58, 5, 198, 188, 58, 5, - 199, 6, 58, 5, 237, 5, 58, 5, 237, 9, 58, 5, 219, 122, 58, 5, 206, 252, - 58, 5, 236, 255, 58, 5, 214, 133, 58, 5, 202, 217, 58, 5, 203, 76, 58, 5, - 191, 30, 58, 5, 191, 57, 58, 5, 242, 237, 58, 5, 222, 217, 58, 5, 213, - 128, 58, 5, 192, 33, 58, 5, 221, 142, 58, 5, 214, 19, 58, 5, 231, 16, 58, - 5, 216, 81, 58, 5, 213, 205, 58, 5, 212, 68, 58, 5, 65, 58, 5, 251, 81, - 58, 5, 214, 49, 58, 5, 144, 58, 5, 230, 23, 58, 5, 193, 187, 58, 5, 193, - 162, 58, 5, 168, 58, 5, 248, 153, 58, 5, 249, 103, 58, 5, 216, 248, 58, - 5, 220, 253, 58, 5, 220, 251, 58, 5, 216, 117, 58, 5, 231, 145, 58, 5, - 233, 68, 58, 5, 195, 185, 58, 5, 199, 247, 58, 5, 199, 44, 58, 5, 237, - 23, 58, 5, 237, 12, 58, 5, 171, 58, 5, 166, 58, 5, 237, 241, 58, 5, 214, - 148, 58, 5, 189, 58, 5, 203, 160, 58, 5, 191, 123, 58, 5, 191, 71, 58, 5, - 247, 112, 58, 5, 223, 4, 58, 5, 213, 144, 58, 5, 169, 58, 5, 157, 58, 5, - 222, 61, 58, 5, 214, 33, 58, 5, 231, 203, 58, 5, 172, 58, 5, 180, 58, 5, - 212, 88, 58, 5, 211, 76, 58, 5, 211, 71, 58, 5, 228, 220, 58, 5, 193, 29, - 58, 5, 193, 25, 58, 5, 209, 30, 58, 5, 248, 143, 58, 5, 248, 49, 58, 5, - 216, 228, 58, 5, 220, 243, 58, 5, 216, 106, 58, 5, 231, 133, 58, 5, 232, - 123, 58, 5, 195, 5, 58, 5, 198, 54, 58, 5, 198, 230, 58, 5, 237, 2, 58, - 5, 237, 7, 58, 5, 218, 240, 58, 5, 206, 129, 58, 5, 236, 102, 58, 5, 214, - 120, 58, 5, 202, 11, 58, 5, 203, 43, 58, 5, 191, 4, 58, 5, 191, 52, 58, - 5, 238, 227, 58, 5, 222, 164, 58, 5, 213, 118, 58, 5, 191, 246, 58, 5, - 221, 17, 58, 5, 214, 17, 58, 5, 230, 210, 58, 5, 215, 194, 58, 5, 213, - 13, 58, 5, 212, 49, 58, 5, 69, 58, 5, 196, 109, 58, 5, 228, 128, 58, 5, - 228, 111, 58, 5, 193, 0, 58, 5, 192, 249, 58, 5, 208, 158, 58, 5, 248, - 142, 58, 5, 247, 218, 58, 5, 216, 227, 58, 5, 220, 241, 58, 5, 216, 105, - 58, 5, 231, 132, 58, 5, 232, 48, 58, 5, 193, 246, 58, 5, 197, 90, 58, 5, - 198, 208, 58, 5, 237, 0, 58, 5, 237, 6, 58, 5, 218, 203, 58, 5, 206, 63, - 58, 5, 235, 45, 58, 5, 214, 115, 58, 5, 200, 255, 58, 5, 203, 0, 58, 5, - 190, 251, 58, 5, 191, 48, 58, 5, 238, 148, 58, 5, 222, 155, 58, 5, 213, - 114, 58, 5, 191, 225, 58, 5, 220, 208, 58, 5, 214, 16, 58, 5, 230, 146, - 58, 5, 215, 139, 58, 5, 212, 165, 58, 5, 212, 45, 58, 5, 74, 58, 5, 211, - 93, 58, 5, 213, 231, 58, 5, 228, 247, 58, 5, 228, 223, 58, 5, 193, 48, - 58, 5, 193, 30, 58, 5, 209, 65, 58, 5, 248, 144, 58, 5, 248, 63, 58, 5, - 216, 229, 58, 5, 220, 244, 58, 5, 216, 108, 58, 5, 231, 135, 58, 5, 231, - 134, 58, 5, 232, 135, 58, 5, 195, 21, 58, 5, 159, 58, 5, 198, 236, 58, 5, - 237, 3, 58, 5, 237, 8, 58, 5, 219, 19, 58, 5, 206, 157, 58, 5, 236, 129, - 58, 5, 214, 124, 58, 5, 202, 41, 58, 5, 203, 51, 58, 5, 191, 7, 58, 5, - 191, 54, 58, 5, 242, 51, 58, 5, 222, 174, 58, 5, 213, 119, 58, 5, 192, - 12, 58, 5, 221, 43, 58, 5, 214, 18, 58, 5, 230, 223, 58, 5, 215, 251, 58, - 5, 213, 30, 58, 5, 212, 52, 58, 5, 73, 58, 5, 234, 61, 58, 5, 214, 38, - 58, 5, 229, 213, 58, 5, 229, 166, 58, 5, 193, 123, 58, 5, 193, 106, 58, - 5, 210, 53, 58, 5, 248, 148, 58, 5, 248, 223, 58, 5, 216, 241, 58, 5, - 220, 249, 58, 5, 220, 247, 58, 5, 216, 114, 58, 5, 231, 142, 58, 5, 231, - 140, 58, 5, 233, 18, 58, 5, 195, 150, 58, 5, 199, 140, 58, 5, 199, 28, - 58, 5, 237, 14, 58, 5, 237, 11, 58, 5, 219, 214, 58, 5, 207, 108, 58, 5, - 237, 101, 58, 5, 214, 140, 58, 5, 205, 63, 58, 5, 203, 108, 58, 5, 191, - 87, 58, 5, 191, 62, 58, 5, 246, 250, 58, 5, 222, 238, 58, 5, 213, 137, - 58, 5, 192, 80, 58, 5, 221, 253, 58, 5, 214, 28, 58, 5, 214, 24, 58, 5, - 231, 128, 58, 5, 231, 114, 58, 5, 216, 213, 58, 5, 214, 107, 58, 5, 212, - 77, 58, 5, 214, 56, 58, 5, 219, 166, 58, 242, 26, 58, 232, 42, 201, 58, - 58, 208, 8, 77, 58, 5, 214, 123, 233, 68, 58, 5, 214, 123, 157, 58, 5, - 214, 123, 202, 11, 58, 16, 233, 7, 58, 16, 221, 242, 58, 16, 198, 135, - 58, 16, 213, 172, 58, 16, 249, 45, 58, 16, 233, 67, 58, 16, 199, 240, 58, - 16, 237, 191, 58, 16, 236, 101, 58, 16, 220, 184, 58, 16, 198, 58, 58, - 16, 236, 128, 58, 16, 222, 165, 58, 17, 191, 77, 58, 17, 108, 58, 17, - 109, 58, 17, 139, 58, 17, 137, 58, 17, 153, 58, 17, 173, 58, 17, 181, 58, - 17, 176, 58, 17, 184, 58, 5, 214, 123, 172, 58, 5, 214, 123, 236, 129, - 42, 6, 1, 191, 81, 42, 2, 1, 191, 81, 42, 6, 1, 234, 242, 42, 2, 1, 234, - 242, 42, 6, 1, 207, 13, 234, 244, 42, 2, 1, 207, 13, 234, 244, 42, 6, 1, - 223, 55, 42, 2, 1, 223, 55, 42, 6, 1, 236, 146, 42, 2, 1, 236, 146, 42, - 6, 1, 215, 202, 196, 124, 42, 2, 1, 215, 202, 196, 124, 42, 6, 1, 247, - 232, 211, 99, 42, 2, 1, 247, 232, 211, 99, 42, 6, 1, 214, 68, 192, 62, - 42, 2, 1, 214, 68, 192, 62, 42, 6, 1, 192, 59, 4, 249, 97, 192, 62, 42, - 2, 1, 192, 59, 4, 249, 97, 192, 62, 42, 6, 1, 223, 53, 192, 95, 42, 2, 1, - 223, 53, 192, 95, 42, 6, 1, 207, 13, 191, 225, 42, 2, 1, 207, 13, 191, - 225, 42, 6, 1, 223, 53, 65, 42, 2, 1, 223, 53, 65, 42, 6, 1, 242, 171, - 219, 59, 191, 190, 42, 2, 1, 242, 171, 219, 59, 191, 190, 42, 6, 1, 248, - 83, 191, 190, 42, 2, 1, 248, 83, 191, 190, 42, 6, 1, 223, 53, 242, 171, - 219, 59, 191, 190, 42, 2, 1, 223, 53, 242, 171, 219, 59, 191, 190, 42, 6, - 1, 192, 14, 42, 2, 1, 192, 14, 42, 6, 1, 207, 13, 197, 157, 42, 2, 1, - 207, 13, 197, 157, 42, 6, 1, 202, 27, 237, 101, 42, 2, 1, 202, 27, 237, - 101, 42, 6, 1, 202, 27, 234, 97, 42, 2, 1, 202, 27, 234, 97, 42, 6, 1, - 202, 27, 234, 72, 42, 2, 1, 202, 27, 234, 72, 42, 6, 1, 215, 206, 74, 42, - 2, 1, 215, 206, 74, 42, 6, 1, 248, 116, 74, 42, 2, 1, 248, 116, 74, 42, - 6, 1, 54, 215, 206, 74, 42, 2, 1, 54, 215, 206, 74, 42, 1, 215, 115, 74, - 33, 42, 193, 223, 33, 42, 199, 91, 216, 30, 57, 33, 42, 228, 110, 216, - 30, 57, 33, 42, 198, 225, 216, 30, 57, 202, 90, 250, 143, 33, 42, 1, 196, - 121, 223, 197, 33, 42, 1, 70, 33, 42, 1, 192, 33, 33, 42, 1, 69, 33, 42, - 1, 229, 240, 57, 33, 42, 1, 192, 58, 33, 42, 1, 202, 27, 57, 33, 42, 1, - 211, 99, 33, 42, 222, 9, 33, 42, 210, 60, 42, 222, 9, 42, 210, 60, 42, 6, - 1, 235, 1, 42, 2, 1, 235, 1, 42, 6, 1, 234, 233, 42, 2, 1, 234, 233, 42, - 6, 1, 191, 38, 42, 2, 1, 191, 38, 42, 6, 1, 247, 10, 42, 2, 1, 247, 10, - 42, 6, 1, 234, 229, 42, 2, 1, 234, 229, 42, 6, 1, 199, 141, 4, 82, 106, - 42, 2, 1, 199, 141, 4, 82, 106, 42, 6, 1, 197, 37, 42, 2, 1, 197, 37, 42, - 6, 1, 197, 132, 42, 2, 1, 197, 132, 42, 6, 1, 197, 137, 42, 2, 1, 197, - 137, 42, 6, 1, 199, 146, 42, 2, 1, 199, 146, 42, 6, 1, 228, 91, 42, 2, 1, - 228, 91, 42, 6, 1, 202, 232, 42, 2, 1, 202, 232, 42, 6, 1, 54, 74, 42, 2, - 1, 54, 74, 42, 6, 1, 238, 167, 74, 42, 2, 1, 238, 167, 74, 59, 1, 42, - 229, 240, 57, 59, 1, 42, 202, 27, 57, 33, 42, 1, 234, 138, 33, 42, 1, - 223, 53, 73, 26, 1, 65, 26, 1, 157, 26, 1, 69, 26, 1, 220, 208, 26, 1, - 234, 145, 26, 1, 207, 79, 26, 1, 199, 221, 26, 1, 74, 26, 1, 212, 68, 26, - 1, 70, 26, 1, 171, 26, 1, 168, 26, 1, 206, 190, 26, 1, 206, 237, 26, 1, - 219, 203, 26, 1, 216, 191, 26, 1, 199, 240, 26, 1, 214, 146, 26, 1, 213, - 142, 26, 1, 218, 147, 26, 1, 200, 156, 26, 1, 215, 139, 26, 1, 203, 71, - 26, 1, 202, 217, 26, 1, 203, 81, 26, 1, 203, 243, 26, 1, 220, 125, 26, 1, - 221, 216, 26, 1, 212, 133, 26, 1, 212, 165, 26, 1, 213, 113, 26, 1, 191, - 243, 26, 1, 203, 0, 26, 1, 191, 194, 26, 1, 169, 26, 1, 212, 202, 26, 1, - 221, 202, 26, 1, 209, 223, 26, 1, 213, 135, 26, 1, 212, 182, 26, 1, 208, - 149, 26, 1, 192, 253, 26, 1, 210, 40, 26, 1, 233, 11, 26, 1, 206, 63, 26, - 1, 218, 203, 26, 1, 216, 81, 26, 1, 213, 205, 26, 1, 207, 15, 26, 1, 207, - 158, 26, 1, 221, 226, 26, 1, 213, 238, 26, 1, 214, 33, 26, 1, 214, 54, - 26, 1, 203, 51, 26, 1, 208, 154, 26, 1, 232, 48, 26, 1, 232, 128, 26, 1, - 193, 187, 26, 1, 180, 26, 1, 219, 122, 26, 1, 209, 176, 26, 1, 218, 232, - 26, 1, 221, 43, 26, 1, 216, 238, 26, 1, 207, 50, 26, 1, 216, 167, 26, 1, - 172, 26, 1, 198, 188, 26, 1, 221, 142, 26, 1, 215, 251, 26, 1, 216, 246, - 26, 1, 199, 68, 26, 1, 220, 253, 26, 1, 199, 90, 26, 1, 212, 168, 26, 1, - 205, 145, 26, 1, 233, 64, 26, 1, 221, 0, 26, 1, 221, 33, 26, 33, 87, 221, - 10, 26, 33, 87, 197, 75, 26, 213, 141, 26, 232, 42, 201, 58, 26, 242, 35, - 26, 242, 26, 26, 204, 20, 26, 208, 8, 77, 59, 1, 243, 32, 163, 192, 22, - 209, 123, 59, 1, 243, 32, 163, 192, 107, 209, 123, 59, 1, 243, 32, 163, - 192, 22, 203, 132, 59, 1, 243, 32, 163, 192, 107, 203, 132, 59, 1, 243, - 32, 163, 192, 22, 208, 27, 59, 1, 243, 32, 163, 192, 107, 208, 27, 59, 1, - 243, 32, 163, 192, 22, 206, 63, 59, 1, 243, 32, 163, 192, 107, 206, 63, - 59, 1, 233, 159, 235, 94, 163, 164, 59, 1, 136, 235, 94, 163, 164, 59, 1, - 216, 68, 235, 94, 163, 164, 59, 1, 131, 235, 94, 163, 164, 59, 1, 233, - 158, 235, 94, 163, 164, 59, 1, 233, 159, 235, 94, 219, 192, 163, 164, 59, - 1, 136, 235, 94, 219, 192, 163, 164, 59, 1, 216, 68, 235, 94, 219, 192, - 163, 164, 59, 1, 131, 235, 94, 219, 192, 163, 164, 59, 1, 233, 158, 235, - 94, 219, 192, 163, 164, 59, 1, 233, 159, 219, 192, 163, 164, 59, 1, 136, - 219, 192, 163, 164, 59, 1, 216, 68, 219, 192, 163, 164, 59, 1, 131, 219, - 192, 163, 164, 59, 1, 233, 158, 219, 192, 163, 164, 59, 1, 75, 81, 164, - 59, 1, 75, 202, 92, 59, 1, 75, 228, 209, 164, 59, 1, 110, 50, 238, 211, - 251, 64, 59, 1, 207, 142, 132, 55, 59, 1, 207, 142, 143, 55, 59, 1, 207, - 142, 233, 175, 77, 59, 1, 207, 142, 223, 65, 233, 175, 77, 59, 1, 131, - 223, 65, 233, 175, 77, 59, 1, 201, 33, 24, 136, 198, 74, 59, 1, 201, 33, - 24, 131, 198, 74, 8, 6, 1, 234, 132, 251, 141, 8, 2, 1, 234, 132, 251, - 141, 8, 6, 1, 234, 132, 251, 178, 8, 2, 1, 234, 132, 251, 178, 8, 6, 1, - 229, 164, 8, 2, 1, 229, 164, 8, 6, 1, 196, 237, 8, 2, 1, 196, 237, 8, 6, - 1, 197, 244, 8, 2, 1, 197, 244, 8, 6, 1, 238, 145, 8, 2, 1, 238, 145, 8, - 6, 1, 238, 146, 4, 242, 26, 8, 2, 1, 238, 146, 4, 242, 26, 8, 1, 2, 6, - 233, 134, 8, 1, 2, 6, 206, 3, 8, 6, 1, 252, 154, 8, 2, 1, 252, 154, 8, 6, - 1, 251, 18, 8, 2, 1, 251, 18, 8, 6, 1, 250, 113, 8, 2, 1, 250, 113, 8, 6, - 1, 250, 96, 8, 2, 1, 250, 96, 8, 6, 1, 250, 97, 4, 228, 209, 164, 8, 2, - 1, 250, 97, 4, 228, 209, 164, 8, 6, 1, 250, 81, 8, 2, 1, 250, 81, 8, 6, - 1, 207, 13, 247, 146, 4, 236, 96, 8, 2, 1, 207, 13, 247, 146, 4, 236, 96, - 8, 6, 1, 222, 126, 4, 105, 8, 2, 1, 222, 126, 4, 105, 8, 6, 1, 222, 126, - 4, 236, 250, 105, 8, 2, 1, 222, 126, 4, 236, 250, 105, 8, 6, 1, 222, 126, - 4, 201, 23, 24, 236, 250, 105, 8, 2, 1, 222, 126, 4, 201, 23, 24, 236, - 250, 105, 8, 6, 1, 247, 230, 170, 8, 2, 1, 247, 230, 170, 8, 6, 1, 220, - 119, 4, 136, 105, 8, 2, 1, 220, 119, 4, 136, 105, 8, 6, 1, 186, 4, 177, - 201, 23, 210, 245, 8, 2, 1, 186, 4, 177, 201, 23, 210, 245, 8, 6, 1, 186, - 4, 218, 236, 8, 2, 1, 186, 4, 218, 236, 8, 6, 1, 211, 76, 8, 2, 1, 211, - 76, 8, 6, 1, 210, 227, 4, 201, 23, 198, 211, 237, 42, 8, 2, 1, 210, 227, - 4, 201, 23, 198, 211, 237, 42, 8, 6, 1, 210, 227, 4, 232, 148, 8, 2, 1, - 210, 227, 4, 232, 148, 8, 6, 1, 210, 227, 4, 201, 177, 199, 210, 8, 2, 1, - 210, 227, 4, 201, 177, 199, 210, 8, 6, 1, 208, 98, 4, 201, 23, 198, 211, - 237, 42, 8, 2, 1, 208, 98, 4, 201, 23, 198, 211, 237, 42, 8, 6, 1, 208, - 98, 4, 236, 250, 105, 8, 2, 1, 208, 98, 4, 236, 250, 105, 8, 6, 1, 207, - 217, 206, 111, 8, 2, 1, 207, 217, 206, 111, 8, 6, 1, 206, 44, 206, 111, - 8, 2, 1, 206, 44, 206, 111, 8, 6, 1, 196, 9, 4, 236, 250, 105, 8, 2, 1, - 196, 9, 4, 236, 250, 105, 8, 6, 1, 193, 232, 8, 2, 1, 193, 232, 8, 6, 1, - 195, 30, 191, 166, 8, 2, 1, 195, 30, 191, 166, 8, 6, 1, 198, 229, 4, 105, - 8, 2, 1, 198, 229, 4, 105, 8, 6, 1, 198, 229, 4, 201, 23, 198, 211, 237, - 42, 8, 2, 1, 198, 229, 4, 201, 23, 198, 211, 237, 42, 8, 6, 1, 195, 139, - 8, 2, 1, 195, 139, 8, 6, 1, 233, 213, 8, 2, 1, 233, 213, 8, 6, 1, 223, - 40, 8, 2, 1, 223, 40, 8, 6, 1, 239, 9, 8, 2, 1, 239, 9, 59, 1, 196, 41, - 8, 2, 1, 235, 33, 8, 2, 1, 218, 186, 8, 2, 1, 215, 108, 8, 2, 1, 212, - 124, 8, 2, 1, 206, 43, 8, 1, 2, 6, 206, 43, 8, 2, 1, 197, 72, 8, 2, 1, - 196, 116, 8, 6, 1, 223, 87, 238, 80, 8, 2, 1, 223, 87, 238, 80, 8, 6, 1, - 223, 87, 233, 134, 8, 2, 1, 223, 87, 233, 134, 8, 6, 1, 223, 87, 232, 14, - 8, 6, 1, 152, 223, 87, 232, 14, 8, 2, 1, 152, 223, 87, 232, 14, 8, 6, 1, - 152, 170, 8, 2, 1, 152, 170, 8, 6, 1, 223, 87, 148, 8, 2, 1, 223, 87, - 148, 8, 6, 1, 223, 87, 206, 3, 8, 2, 1, 223, 87, 206, 3, 8, 6, 1, 223, - 87, 200, 39, 8, 2, 1, 223, 87, 200, 39, 59, 1, 131, 242, 210, 252, 8, 59, - 1, 242, 35, 59, 1, 203, 35, 234, 1, 57, 8, 6, 1, 205, 151, 8, 2, 1, 205, - 151, 8, 6, 1, 152, 230, 83, 8, 2, 1, 220, 119, 4, 207, 19, 228, 219, 24, - 248, 181, 8, 1, 202, 158, 236, 96, 8, 6, 1, 215, 48, 4, 237, 42, 8, 2, 1, - 215, 48, 4, 237, 42, 8, 6, 1, 247, 146, 4, 164, 8, 2, 1, 247, 146, 4, - 164, 8, 2, 1, 247, 146, 4, 210, 182, 106, 8, 2, 1, 230, 84, 4, 210, 182, - 106, 8, 6, 1, 78, 4, 232, 148, 8, 2, 1, 78, 4, 232, 148, 8, 6, 1, 233, - 135, 4, 105, 8, 2, 1, 233, 135, 4, 105, 8, 6, 1, 195, 12, 251, 229, 8, 2, - 1, 195, 12, 251, 229, 8, 6, 1, 195, 12, 211, 139, 8, 2, 1, 195, 12, 211, - 139, 8, 6, 1, 195, 12, 196, 148, 8, 2, 1, 195, 12, 196, 148, 8, 6, 1, - 232, 15, 4, 211, 159, 105, 8, 2, 1, 232, 15, 4, 211, 159, 105, 8, 6, 1, - 222, 126, 4, 211, 159, 105, 8, 2, 1, 222, 126, 4, 211, 159, 105, 8, 6, 1, - 215, 48, 4, 211, 159, 105, 8, 2, 1, 215, 48, 4, 211, 159, 105, 8, 6, 1, - 207, 217, 4, 211, 159, 105, 8, 2, 1, 207, 217, 4, 211, 159, 105, 8, 6, 1, - 206, 4, 4, 211, 159, 105, 8, 2, 1, 206, 4, 4, 211, 159, 105, 8, 6, 1, - 230, 84, 4, 106, 8, 6, 1, 207, 13, 211, 66, 73, 8, 6, 1, 27, 232, 14, 8, - 6, 1, 220, 119, 4, 248, 181, 8, 6, 1, 2, 6, 70, 8, 1, 2, 6, 208, 97, 8, - 6, 1, 152, 222, 125, 8, 6, 1, 152, 200, 39, 8, 6, 1, 223, 8, 4, 238, 165, - 8, 6, 1, 243, 47, 8, 6, 1, 248, 162, 8, 2, 1, 248, 162, 8, 6, 1, 211, 99, - 8, 2, 1, 211, 99, 8, 6, 1, 126, 4, 105, 8, 2, 1, 126, 4, 105, 8, 6, 1, - 230, 231, 65, 8, 2, 1, 230, 231, 65, 8, 6, 1, 230, 231, 70, 8, 2, 1, 230, - 231, 70, 8, 6, 1, 230, 231, 69, 8, 2, 1, 230, 231, 69, 8, 6, 1, 38, 209, - 42, 74, 8, 2, 1, 38, 209, 42, 74, 8, 6, 1, 251, 61, 193, 221, 8, 2, 1, - 251, 61, 193, 221, 8, 6, 1, 247, 146, 4, 210, 182, 106, 8, 6, 1, 206, 4, - 4, 106, 8, 6, 1, 191, 167, 4, 210, 182, 106, 8, 6, 1, 238, 81, 4, 203, - 35, 201, 23, 210, 245, 8, 2, 1, 238, 81, 4, 203, 35, 201, 23, 210, 245, - 8, 6, 1, 206, 4, 4, 203, 35, 201, 23, 210, 245, 8, 2, 1, 206, 4, 4, 203, - 35, 201, 23, 210, 245, 8, 6, 1, 242, 171, 223, 87, 232, 14, 8, 2, 1, 242, - 171, 223, 87, 232, 14, 8, 2, 1, 54, 198, 228, 8, 2, 1, 54, 192, 238, 8, - 6, 1, 82, 205, 74, 206, 3, 8, 2, 1, 82, 205, 74, 206, 3, 8, 6, 1, 202, - 190, 206, 3, 8, 2, 1, 202, 190, 206, 3, 59, 1, 6, 247, 145, 59, 1, 6, - 233, 134, 59, 1, 6, 208, 97, 8, 6, 1, 207, 13, 134, 230, 83, 8, 2, 1, - 207, 13, 134, 230, 83, 8, 234, 8, 1, 202, 201, 70, 59, 1, 6, 230, 84, 4, - 105, 59, 1, 2, 34, 211, 139, 8, 1, 2, 6, 152, 218, 147, 8, 234, 8, 1, - 207, 13, 233, 134, 8, 234, 8, 1, 207, 13, 210, 226, 8, 234, 8, 1, 223, - 65, 218, 147, 8, 234, 8, 1, 228, 44, 218, 242, 8, 234, 8, 1, 250, 220, - 218, 147, 200, 120, 214, 224, 1, 65, 200, 120, 214, 224, 1, 70, 200, 120, - 214, 224, 3, 235, 10, 200, 120, 214, 224, 1, 69, 200, 120, 214, 224, 1, - 73, 200, 120, 214, 224, 1, 74, 200, 120, 214, 224, 3, 229, 234, 200, 120, - 214, 224, 1, 221, 43, 200, 120, 214, 224, 1, 221, 159, 200, 120, 214, - 224, 1, 230, 223, 200, 120, 214, 224, 1, 231, 26, 200, 120, 214, 224, 3, - 251, 20, 200, 120, 214, 224, 1, 242, 51, 200, 120, 214, 224, 1, 243, 20, - 200, 120, 214, 224, 1, 222, 174, 200, 120, 214, 224, 1, 222, 219, 200, - 120, 214, 224, 1, 197, 105, 200, 120, 214, 224, 1, 197, 111, 200, 120, - 214, 224, 1, 237, 116, 200, 120, 214, 224, 1, 237, 125, 200, 120, 214, - 224, 1, 159, 200, 120, 214, 224, 1, 198, 236, 200, 120, 214, 224, 1, 236, - 129, 200, 120, 214, 224, 1, 237, 3, 200, 120, 214, 224, 1, 213, 30, 200, - 120, 214, 224, 1, 209, 65, 200, 120, 214, 224, 1, 209, 190, 200, 120, - 214, 224, 1, 248, 63, 200, 120, 214, 224, 1, 248, 144, 200, 120, 214, - 224, 1, 215, 251, 200, 120, 214, 224, 1, 206, 157, 200, 120, 214, 224, 1, - 219, 19, 200, 120, 214, 224, 1, 206, 90, 200, 120, 214, 224, 1, 202, 41, - 200, 120, 214, 224, 1, 228, 247, 200, 120, 214, 224, 18, 3, 65, 200, 120, - 214, 224, 18, 3, 70, 200, 120, 214, 224, 18, 3, 69, 200, 120, 214, 224, - 18, 3, 73, 200, 120, 214, 224, 18, 3, 211, 76, 200, 120, 214, 224, 209, - 56, 217, 36, 200, 120, 214, 224, 209, 56, 217, 35, 200, 120, 214, 224, - 209, 56, 217, 34, 200, 120, 214, 224, 209, 56, 217, 33, 200, 120, 214, - 224, 3, 251, 106, 229, 234, 185, 223, 118, 232, 80, 91, 208, 17, 185, - 223, 118, 232, 80, 91, 230, 37, 185, 223, 118, 232, 80, 115, 208, 15, - 185, 223, 118, 232, 80, 91, 202, 123, 185, 223, 118, 232, 80, 91, 234, - 116, 185, 223, 118, 232, 80, 115, 202, 120, 185, 223, 118, 208, 18, 77, - 185, 223, 118, 209, 99, 77, 185, 223, 118, 206, 31, 77, 185, 223, 118, - 208, 19, 77, 209, 215, 1, 157, 209, 215, 1, 221, 190, 209, 215, 1, 231, - 203, 209, 215, 1, 214, 54, 209, 215, 1, 247, 112, 209, 215, 1, 246, 209, - 209, 215, 1, 223, 4, 209, 215, 1, 212, 88, 209, 215, 1, 199, 247, 209, - 215, 1, 199, 44, 209, 215, 1, 237, 241, 209, 215, 1, 180, 209, 215, 1, - 168, 209, 215, 1, 209, 219, 209, 215, 1, 249, 103, 209, 215, 1, 172, 209, - 215, 1, 197, 164, 209, 215, 1, 197, 153, 209, 215, 1, 234, 247, 209, 215, - 1, 193, 187, 209, 215, 1, 191, 71, 209, 215, 1, 191, 123, 209, 215, 1, 2, - 65, 209, 215, 1, 169, 209, 215, 1, 166, 209, 215, 1, 171, 209, 215, 1, - 203, 160, 209, 215, 1, 189, 209, 215, 1, 144, 209, 215, 1, 65, 209, 215, - 1, 70, 209, 215, 1, 69, 209, 215, 1, 73, 209, 215, 1, 74, 209, 215, 1, - 208, 89, 209, 215, 1, 192, 220, 209, 215, 1, 233, 68, 209, 215, 1, 231, - 90, 209, 215, 1, 234, 145, 209, 215, 200, 234, 1, 193, 187, 209, 215, - 200, 234, 1, 169, 209, 215, 1, 197, 128, 209, 215, 1, 197, 116, 209, 215, - 1, 237, 146, 209, 215, 1, 213, 66, 209, 215, 1, 251, 106, 169, 209, 215, - 1, 195, 16, 203, 160, 209, 215, 1, 195, 17, 144, 209, 215, 1, 250, 150, - 233, 68, 209, 215, 200, 234, 1, 166, 209, 215, 200, 180, 1, 166, 209, - 215, 1, 247, 71, 209, 215, 202, 165, 229, 204, 77, 209, 215, 54, 229, - 204, 77, 209, 215, 87, 203, 152, 209, 215, 87, 54, 203, 152, 205, 106, 3, - 251, 20, 205, 106, 3, 195, 32, 205, 106, 1, 65, 205, 106, 1, 252, 154, - 205, 106, 1, 70, 205, 106, 1, 223, 170, 205, 106, 1, 69, 205, 106, 1, - 196, 26, 205, 106, 1, 121, 148, 205, 106, 1, 121, 206, 105, 205, 106, 1, - 121, 170, 205, 106, 1, 121, 219, 50, 205, 106, 1, 73, 205, 106, 1, 234, - 145, 205, 106, 1, 251, 184, 205, 106, 1, 74, 205, 106, 1, 211, 76, 205, - 106, 1, 250, 113, 205, 106, 1, 157, 205, 106, 1, 221, 190, 205, 106, 1, - 231, 203, 205, 106, 1, 231, 54, 205, 106, 1, 214, 54, 205, 106, 1, 247, - 112, 205, 106, 1, 246, 209, 205, 106, 1, 223, 4, 205, 106, 1, 222, 225, - 205, 106, 1, 212, 88, 205, 106, 1, 197, 128, 205, 106, 1, 197, 116, 205, - 106, 1, 237, 146, 205, 106, 1, 237, 130, 205, 106, 1, 213, 66, 205, 106, - 1, 199, 247, 205, 106, 1, 199, 44, 205, 106, 1, 237, 241, 205, 106, 1, - 237, 23, 205, 106, 1, 180, 205, 106, 1, 168, 205, 106, 1, 209, 219, 205, - 106, 1, 249, 103, 205, 106, 1, 248, 153, 205, 106, 1, 172, 205, 106, 1, - 169, 205, 106, 1, 166, 205, 106, 1, 171, 205, 106, 1, 195, 185, 205, 106, - 1, 203, 160, 205, 106, 1, 201, 170, 205, 106, 1, 189, 205, 106, 1, 144, - 205, 106, 1, 219, 49, 205, 106, 119, 3, 230, 56, 205, 106, 18, 3, 252, - 154, 205, 106, 18, 3, 70, 205, 106, 18, 3, 223, 170, 205, 106, 18, 3, 69, - 205, 106, 18, 3, 196, 26, 205, 106, 18, 3, 121, 148, 205, 106, 18, 3, - 121, 206, 105, 205, 106, 18, 3, 121, 170, 205, 106, 18, 3, 121, 219, 50, - 205, 106, 18, 3, 73, 205, 106, 18, 3, 234, 145, 205, 106, 18, 3, 251, - 184, 205, 106, 18, 3, 74, 205, 106, 18, 3, 211, 76, 205, 106, 18, 3, 250, - 113, 205, 106, 3, 195, 37, 205, 106, 3, 247, 71, 205, 106, 237, 193, 205, - 106, 54, 237, 193, 205, 106, 17, 191, 77, 205, 106, 17, 108, 205, 106, - 17, 109, 205, 106, 17, 139, 205, 106, 17, 137, 205, 106, 17, 153, 205, - 106, 17, 173, 205, 106, 17, 181, 205, 106, 17, 176, 205, 106, 17, 184, - 33, 104, 17, 191, 77, 33, 104, 17, 108, 33, 104, 17, 109, 33, 104, 17, - 139, 33, 104, 17, 137, 33, 104, 17, 153, 33, 104, 17, 173, 33, 104, 17, - 181, 33, 104, 17, 176, 33, 104, 17, 184, 33, 104, 1, 65, 33, 104, 1, 69, - 33, 104, 1, 157, 33, 104, 1, 180, 33, 104, 1, 168, 33, 104, 1, 166, 33, - 104, 1, 195, 66, 33, 104, 3, 250, 95, 104, 3, 201, 241, 247, 71, 104, 3, - 247, 72, 195, 37, 104, 3, 54, 247, 72, 195, 37, 104, 3, 247, 72, 109, - 104, 3, 247, 72, 139, 104, 3, 247, 72, 250, 95, 104, 3, 208, 127, 104, - 231, 167, 232, 218, 104, 247, 48, 104, 229, 195, 104, 3, 202, 205, 104, - 222, 252, 211, 102, 104, 1, 250, 81, 104, 18, 3, 250, 81, 222, 3, 219, - 123, 17, 191, 77, 222, 3, 219, 123, 17, 108, 222, 3, 219, 123, 17, 109, - 222, 3, 219, 123, 17, 139, 222, 3, 219, 123, 17, 137, 222, 3, 219, 123, - 17, 153, 222, 3, 219, 123, 17, 173, 222, 3, 219, 123, 17, 181, 222, 3, - 219, 123, 17, 176, 222, 3, 219, 123, 17, 184, 222, 3, 219, 123, 1, 157, - 222, 3, 219, 123, 1, 221, 190, 222, 3, 219, 123, 1, 231, 203, 222, 3, - 219, 123, 1, 214, 54, 222, 3, 219, 123, 1, 189, 222, 3, 219, 123, 1, 203, - 160, 222, 3, 219, 123, 1, 191, 123, 222, 3, 219, 123, 1, 212, 88, 222, 3, - 219, 123, 1, 199, 247, 222, 3, 219, 123, 1, 228, 133, 222, 3, 219, 123, - 1, 180, 222, 3, 219, 123, 1, 168, 222, 3, 219, 123, 1, 209, 219, 222, 3, - 219, 123, 1, 172, 222, 3, 219, 123, 1, 237, 241, 222, 3, 219, 123, 1, - 249, 103, 222, 3, 219, 123, 1, 166, 222, 3, 219, 123, 1, 169, 222, 3, - 219, 123, 1, 171, 222, 3, 219, 123, 1, 193, 187, 222, 3, 219, 123, 1, - 199, 44, 222, 3, 219, 123, 1, 144, 222, 3, 219, 123, 1, 195, 185, 222, 3, - 219, 123, 1, 247, 112, 222, 3, 219, 123, 1, 65, 222, 3, 219, 123, 1, 211, - 139, 222, 3, 219, 123, 1, 70, 222, 3, 219, 123, 1, 211, 76, 222, 3, 219, - 123, 18, 196, 148, 222, 3, 219, 123, 18, 73, 222, 3, 219, 123, 18, 69, - 222, 3, 219, 123, 18, 234, 145, 222, 3, 219, 123, 18, 74, 222, 3, 219, - 123, 163, 209, 82, 222, 3, 219, 123, 163, 247, 87, 222, 3, 219, 123, 163, - 247, 88, 209, 82, 222, 3, 219, 123, 3, 238, 100, 222, 3, 219, 123, 3, - 202, 225, 207, 62, 1, 157, 207, 62, 1, 231, 203, 207, 62, 1, 214, 54, - 207, 62, 1, 199, 247, 207, 62, 1, 237, 241, 207, 62, 1, 180, 207, 62, 1, - 168, 207, 62, 1, 249, 103, 207, 62, 1, 172, 207, 62, 1, 247, 112, 207, - 62, 1, 223, 4, 207, 62, 1, 212, 88, 207, 62, 1, 189, 207, 62, 1, 166, - 207, 62, 1, 171, 207, 62, 1, 169, 207, 62, 1, 193, 187, 207, 62, 1, 144, - 207, 62, 1, 216, 248, 207, 62, 1, 214, 33, 207, 62, 1, 214, 148, 207, 62, - 1, 212, 53, 207, 62, 1, 65, 207, 62, 18, 3, 70, 207, 62, 18, 3, 69, 207, - 62, 18, 3, 73, 207, 62, 18, 3, 251, 184, 207, 62, 18, 3, 74, 207, 62, 18, - 3, 250, 113, 207, 62, 18, 3, 233, 201, 207, 62, 18, 3, 234, 173, 207, 62, - 119, 3, 214, 56, 207, 62, 119, 3, 215, 47, 207, 62, 119, 3, 148, 207, 62, - 119, 3, 230, 83, 207, 62, 195, 37, 207, 62, 205, 49, 77, 30, 146, 198, - 159, 30, 146, 198, 158, 30, 146, 198, 156, 30, 146, 198, 161, 30, 146, - 206, 229, 30, 146, 206, 213, 30, 146, 206, 208, 30, 146, 206, 210, 30, - 146, 206, 226, 30, 146, 206, 219, 30, 146, 206, 212, 30, 146, 206, 231, - 30, 146, 206, 214, 30, 146, 206, 233, 30, 146, 206, 230, 30, 146, 216, - 55, 30, 146, 216, 46, 30, 146, 216, 49, 30, 146, 209, 145, 30, 146, 209, - 156, 30, 146, 209, 157, 30, 146, 201, 154, 30, 146, 223, 183, 30, 146, - 223, 190, 30, 146, 201, 165, 30, 146, 201, 152, 30, 146, 209, 199, 30, - 146, 229, 105, 30, 146, 201, 149, 222, 244, 3, 210, 133, 222, 244, 3, - 246, 247, 222, 244, 3, 219, 222, 222, 244, 3, 193, 69, 222, 244, 1, 65, - 222, 244, 1, 228, 44, 222, 7, 222, 244, 1, 70, 222, 244, 1, 223, 170, - 222, 244, 1, 69, 222, 244, 1, 210, 211, 246, 217, 222, 244, 1, 214, 55, - 219, 179, 222, 244, 1, 214, 55, 219, 180, 207, 126, 222, 244, 1, 73, 222, - 244, 1, 251, 184, 222, 244, 1, 74, 222, 244, 1, 157, 222, 244, 1, 222, - 115, 205, 119, 222, 244, 1, 222, 115, 215, 93, 222, 244, 1, 231, 203, - 222, 244, 1, 231, 204, 215, 93, 222, 244, 1, 214, 54, 222, 244, 1, 247, - 112, 222, 244, 1, 247, 113, 215, 93, 222, 244, 1, 223, 4, 222, 244, 1, - 212, 89, 215, 93, 222, 244, 1, 223, 5, 217, 95, 222, 244, 1, 212, 88, - 222, 244, 1, 197, 128, 222, 244, 1, 197, 129, 217, 95, 222, 244, 1, 237, - 146, 222, 244, 1, 237, 147, 217, 95, 222, 244, 1, 214, 249, 215, 93, 222, - 244, 1, 199, 247, 222, 244, 1, 199, 248, 215, 93, 222, 244, 1, 237, 241, - 222, 244, 1, 237, 242, 217, 95, 222, 244, 1, 180, 222, 244, 1, 168, 222, - 244, 1, 210, 211, 215, 93, 222, 244, 1, 249, 103, 222, 244, 1, 249, 104, - 215, 93, 222, 244, 1, 172, 222, 244, 1, 169, 222, 244, 1, 166, 222, 244, - 1, 207, 181, 251, 194, 222, 244, 1, 171, 222, 244, 1, 193, 187, 222, 244, - 1, 205, 202, 215, 93, 222, 244, 1, 205, 202, 217, 95, 222, 244, 1, 189, - 222, 244, 1, 144, 222, 244, 3, 246, 248, 199, 95, 222, 244, 18, 3, 199, - 170, 222, 244, 18, 3, 198, 79, 222, 244, 18, 3, 192, 250, 222, 244, 18, - 3, 192, 251, 216, 179, 222, 244, 18, 3, 200, 203, 222, 244, 18, 3, 200, - 204, 216, 166, 222, 244, 18, 3, 199, 196, 222, 244, 18, 3, 236, 185, 215, - 92, 222, 244, 18, 3, 210, 7, 222, 244, 119, 3, 221, 219, 222, 244, 119, - 3, 210, 22, 222, 244, 119, 3, 247, 97, 222, 244, 210, 147, 222, 244, 45, - 207, 35, 222, 244, 50, 207, 35, 222, 244, 210, 199, 251, 73, 222, 244, - 210, 199, 217, 116, 222, 244, 210, 199, 218, 190, 222, 244, 210, 199, - 193, 62, 222, 244, 210, 199, 210, 148, 222, 244, 210, 199, 219, 80, 222, - 244, 210, 199, 218, 183, 222, 244, 210, 199, 251, 240, 222, 244, 210, - 199, 251, 241, 251, 240, 222, 244, 210, 199, 209, 111, 222, 244, 152, - 210, 199, 209, 111, 222, 244, 210, 143, 222, 244, 17, 191, 77, 222, 244, - 17, 108, 222, 244, 17, 109, 222, 244, 17, 139, 222, 244, 17, 137, 222, - 244, 17, 153, 222, 244, 17, 173, 222, 244, 17, 181, 222, 244, 17, 176, - 222, 244, 17, 184, 222, 244, 210, 199, 198, 122, 197, 69, 222, 244, 210, - 199, 223, 36, 79, 1, 203, 134, 231, 54, 79, 1, 203, 134, 246, 209, 79, 1, - 203, 134, 222, 225, 79, 1, 203, 134, 213, 66, 79, 1, 203, 134, 248, 153, - 79, 3, 203, 134, 205, 103, 79, 59, 1, 203, 134, 207, 80, 79, 1, 53, 220, - 71, 212, 88, 79, 1, 53, 220, 71, 233, 68, 79, 1, 53, 220, 71, 231, 203, - 79, 1, 53, 220, 71, 231, 54, 79, 1, 53, 220, 71, 223, 4, 79, 1, 53, 220, - 71, 222, 225, 79, 1, 53, 220, 71, 237, 146, 79, 1, 53, 220, 71, 237, 130, - 79, 1, 53, 220, 71, 213, 66, 79, 53, 220, 71, 17, 191, 77, 79, 53, 220, - 71, 17, 108, 79, 53, 220, 71, 17, 109, 79, 53, 220, 71, 17, 139, 79, 53, - 220, 71, 17, 137, 79, 53, 220, 71, 17, 153, 79, 53, 220, 71, 17, 173, 79, - 53, 220, 71, 17, 181, 79, 53, 220, 71, 17, 176, 79, 53, 220, 71, 17, 184, - 79, 1, 53, 220, 71, 219, 49, 79, 1, 53, 220, 71, 237, 241, 79, 1, 53, - 220, 71, 237, 23, 79, 1, 53, 220, 71, 249, 103, 79, 1, 53, 220, 71, 248, - 153, 246, 202, 1, 65, 246, 202, 1, 70, 246, 202, 1, 69, 246, 202, 1, 73, - 246, 202, 1, 251, 184, 246, 202, 1, 74, 246, 202, 1, 157, 246, 202, 1, - 221, 190, 246, 202, 1, 231, 203, 246, 202, 1, 231, 54, 246, 202, 1, 213, - 219, 246, 202, 1, 214, 54, 246, 202, 1, 246, 209, 246, 202, 1, 243, 50, - 246, 202, 1, 223, 4, 246, 202, 1, 222, 225, 246, 202, 1, 213, 207, 246, - 202, 1, 213, 210, 246, 202, 1, 213, 208, 246, 202, 1, 199, 247, 246, 202, - 1, 199, 44, 246, 202, 1, 237, 241, 246, 202, 1, 237, 23, 246, 202, 1, - 212, 131, 246, 202, 1, 180, 246, 202, 1, 237, 146, 246, 202, 1, 168, 246, - 202, 1, 208, 243, 246, 202, 1, 209, 219, 246, 202, 1, 249, 103, 246, 202, - 1, 248, 153, 246, 202, 1, 215, 127, 246, 202, 1, 172, 246, 202, 1, 249, - 3, 246, 202, 1, 169, 246, 202, 1, 166, 246, 202, 1, 171, 246, 202, 1, - 195, 185, 246, 202, 1, 201, 170, 246, 202, 1, 189, 246, 202, 1, 144, 246, - 202, 18, 3, 252, 154, 246, 202, 18, 3, 70, 246, 202, 18, 3, 223, 170, - 246, 202, 18, 3, 234, 123, 246, 202, 18, 3, 69, 246, 202, 18, 3, 211, - 139, 246, 202, 18, 3, 74, 246, 202, 18, 3, 251, 184, 246, 202, 18, 3, - 250, 113, 246, 202, 18, 3, 196, 148, 246, 202, 119, 3, 169, 246, 202, - 119, 3, 166, 246, 202, 119, 3, 171, 246, 202, 119, 3, 193, 187, 246, 202, - 1, 52, 222, 125, 246, 202, 1, 52, 232, 14, 246, 202, 1, 52, 214, 56, 246, - 202, 119, 3, 52, 214, 56, 246, 202, 1, 52, 246, 211, 246, 202, 1, 52, - 200, 39, 246, 202, 1, 52, 215, 47, 246, 202, 1, 52, 210, 226, 246, 202, - 1, 52, 192, 159, 246, 202, 1, 52, 148, 246, 202, 1, 52, 170, 246, 202, 1, - 52, 201, 173, 246, 202, 119, 3, 52, 218, 147, 246, 202, 119, 3, 52, 230, - 83, 246, 202, 17, 191, 77, 246, 202, 17, 108, 246, 202, 17, 109, 246, - 202, 17, 139, 246, 202, 17, 137, 246, 202, 17, 153, 246, 202, 17, 173, - 246, 202, 17, 181, 246, 202, 17, 176, 246, 202, 17, 184, 246, 202, 208, - 145, 201, 212, 246, 202, 208, 145, 237, 193, 246, 202, 208, 145, 54, 237, - 193, 246, 202, 208, 145, 197, 221, 237, 193, 79, 1, 221, 181, 231, 203, - 79, 1, 221, 181, 247, 112, 79, 1, 221, 181, 246, 209, 79, 1, 221, 181, - 223, 4, 79, 1, 221, 181, 222, 225, 79, 1, 221, 181, 212, 88, 79, 1, 221, - 181, 197, 128, 79, 1, 221, 181, 197, 116, 79, 1, 221, 181, 237, 146, 79, - 1, 221, 181, 237, 130, 79, 1, 221, 181, 237, 23, 79, 1, 221, 181, 180, - 79, 1, 221, 181, 189, 79, 1, 221, 181, 144, 79, 1, 221, 181, 229, 145, - 79, 1, 221, 181, 233, 68, 79, 59, 1, 221, 181, 207, 80, 79, 1, 221, 181, - 192, 220, 79, 1, 221, 181, 191, 123, 79, 1, 221, 181, 166, 79, 219, 4, - 221, 181, 211, 166, 79, 219, 4, 221, 181, 208, 40, 79, 219, 4, 221, 181, - 229, 46, 79, 16, 251, 170, 233, 174, 79, 16, 251, 170, 108, 79, 16, 251, - 170, 109, 79, 1, 251, 170, 166, 79, 3, 210, 129, 222, 36, 198, 74, 79, 3, - 53, 220, 71, 198, 72, 79, 3, 53, 220, 71, 198, 69, 79, 1, 202, 233, 210, - 179, 246, 209, 79, 1, 202, 233, 210, 179, 203, 160, 53, 195, 56, 1, 131, - 221, 43, 53, 195, 56, 1, 136, 221, 43, 53, 195, 56, 1, 131, 221, 159, 53, - 195, 56, 1, 136, 221, 159, 53, 195, 56, 1, 131, 221, 168, 53, 195, 56, 1, - 136, 221, 168, 53, 195, 56, 1, 131, 230, 223, 53, 195, 56, 1, 136, 230, - 223, 53, 195, 56, 1, 131, 213, 235, 53, 195, 56, 1, 136, 213, 235, 53, - 195, 56, 1, 131, 242, 51, 53, 195, 56, 1, 136, 242, 51, 53, 195, 56, 1, - 131, 243, 20, 53, 195, 56, 1, 136, 243, 20, 53, 195, 56, 1, 131, 202, 41, - 53, 195, 56, 1, 136, 202, 41, 53, 195, 56, 1, 131, 212, 52, 53, 195, 56, - 1, 136, 212, 52, 53, 195, 56, 1, 131, 236, 129, 53, 195, 56, 1, 136, 236, - 129, 53, 195, 56, 1, 131, 159, 53, 195, 56, 1, 136, 159, 53, 195, 56, 1, - 131, 198, 236, 53, 195, 56, 1, 136, 198, 236, 53, 195, 56, 1, 131, 213, - 30, 53, 195, 56, 1, 136, 213, 30, 53, 195, 56, 1, 131, 248, 63, 53, 195, - 56, 1, 136, 248, 63, 53, 195, 56, 1, 131, 209, 65, 53, 195, 56, 1, 136, - 209, 65, 53, 195, 56, 1, 131, 209, 190, 53, 195, 56, 1, 136, 209, 190, - 53, 195, 56, 1, 131, 232, 135, 53, 195, 56, 1, 136, 232, 135, 53, 195, - 56, 1, 131, 215, 251, 53, 195, 56, 1, 136, 215, 251, 53, 195, 56, 1, 131, - 192, 12, 53, 195, 56, 1, 136, 192, 12, 53, 195, 56, 1, 131, 206, 157, 53, - 195, 56, 1, 136, 206, 157, 53, 195, 56, 1, 131, 219, 19, 53, 195, 56, 1, - 136, 219, 19, 53, 195, 56, 1, 131, 195, 21, 53, 195, 56, 1, 136, 195, 21, - 53, 195, 56, 1, 131, 228, 247, 53, 195, 56, 1, 136, 228, 247, 53, 195, - 56, 1, 131, 74, 53, 195, 56, 1, 136, 74, 53, 195, 56, 217, 92, 222, 57, - 53, 195, 56, 18, 252, 154, 53, 195, 56, 18, 70, 53, 195, 56, 18, 196, - 148, 53, 195, 56, 18, 69, 53, 195, 56, 18, 73, 53, 195, 56, 18, 74, 53, - 195, 56, 217, 92, 221, 162, 53, 195, 56, 18, 228, 5, 53, 195, 56, 18, - 196, 147, 53, 195, 56, 18, 196, 164, 53, 195, 56, 18, 250, 111, 53, 195, - 56, 18, 250, 81, 53, 195, 56, 18, 251, 81, 53, 195, 56, 18, 251, 98, 53, - 195, 56, 163, 217, 92, 234, 104, 53, 195, 56, 163, 217, 92, 212, 130, 53, - 195, 56, 163, 217, 92, 198, 236, 53, 195, 56, 163, 217, 92, 202, 13, 53, - 195, 56, 16, 221, 20, 53, 195, 56, 16, 212, 130, 53, 195, 56, 16, 205, - 147, 53, 195, 56, 16, 228, 248, 228, 234, 53, 195, 56, 16, 221, 31, 221, - 30, 216, 186, 216, 255, 1, 73, 216, 186, 216, 255, 1, 74, 216, 186, 216, - 255, 1, 246, 209, 216, 186, 216, 255, 1, 212, 88, 216, 186, 216, 255, 1, - 197, 128, 216, 186, 216, 255, 1, 197, 116, 216, 186, 216, 255, 1, 237, - 146, 216, 186, 216, 255, 1, 237, 130, 216, 186, 216, 255, 1, 213, 66, - 216, 186, 216, 255, 1, 203, 160, 216, 186, 216, 255, 1, 201, 170, 216, - 186, 216, 255, 18, 3, 223, 170, 216, 186, 216, 255, 18, 3, 196, 26, 216, - 186, 216, 255, 18, 3, 252, 118, 216, 186, 216, 255, 18, 3, 250, 113, 216, - 186, 216, 255, 18, 3, 252, 110, 216, 186, 216, 255, 243, 68, 216, 186, - 216, 255, 251, 190, 221, 149, 216, 186, 216, 255, 251, 49, 216, 186, 216, - 255, 5, 207, 41, 77, 216, 186, 216, 255, 193, 23, 207, 41, 77, 216, 186, - 216, 255, 18, 3, 195, 32, 216, 186, 216, 255, 195, 37, 36, 5, 197, 109, - 36, 5, 197, 112, 36, 5, 197, 115, 36, 5, 197, 113, 36, 5, 197, 114, 36, - 5, 197, 111, 36, 5, 237, 124, 36, 5, 237, 126, 36, 5, 237, 129, 36, 5, - 237, 127, 36, 5, 237, 128, 36, 5, 237, 125, 36, 5, 234, 234, 36, 5, 234, - 238, 36, 5, 234, 246, 36, 5, 234, 243, 36, 5, 234, 244, 36, 5, 234, 235, - 36, 5, 247, 8, 36, 5, 247, 2, 36, 5, 247, 4, 36, 5, 247, 7, 36, 5, 247, - 5, 36, 5, 247, 6, 36, 5, 247, 3, 36, 5, 249, 3, 36, 5, 248, 238, 36, 5, - 248, 250, 36, 5, 249, 2, 36, 5, 248, 253, 36, 5, 248, 254, 36, 5, 248, - 242, 8, 2, 1, 249, 32, 251, 109, 8, 2, 1, 41, 207, 11, 8, 2, 1, 248, 87, - 73, 8, 2, 1, 249, 32, 73, 8, 2, 1, 234, 227, 4, 232, 148, 8, 2, 1, 219, - 165, 233, 134, 8, 2, 1, 27, 232, 15, 4, 238, 165, 8, 2, 1, 220, 119, 4, - 223, 65, 219, 221, 206, 3, 8, 2, 1, 220, 119, 4, 54, 82, 198, 147, 8, 2, - 1, 220, 119, 4, 82, 206, 183, 8, 2, 1, 218, 148, 4, 238, 165, 8, 2, 1, - 215, 48, 4, 238, 165, 8, 2, 1, 234, 47, 4, 238, 165, 8, 2, 1, 248, 87, - 74, 8, 2, 1, 248, 87, 186, 4, 105, 8, 2, 1, 211, 66, 186, 4, 105, 8, 2, - 1, 223, 65, 211, 139, 8, 2, 1, 152, 211, 140, 4, 105, 8, 2, 1, 152, 211, - 140, 4, 228, 209, 105, 8, 2, 1, 152, 186, 211, 61, 8, 2, 1, 152, 186, - 211, 62, 4, 105, 8, 2, 1, 201, 63, 148, 8, 1, 2, 6, 207, 217, 4, 50, 219, - 188, 8, 2, 1, 207, 217, 193, 51, 229, 254, 8, 2, 1, 54, 148, 8, 2, 1, - 207, 217, 4, 238, 165, 8, 2, 1, 54, 207, 217, 4, 238, 165, 8, 2, 1, 27, - 148, 8, 2, 1, 27, 207, 217, 4, 206, 183, 8, 2, 1, 249, 22, 233, 226, 8, - 2, 1, 126, 4, 203, 35, 50, 219, 188, 8, 2, 1, 126, 249, 38, 4, 203, 35, - 50, 219, 188, 8, 2, 1, 196, 135, 8, 2, 1, 152, 196, 135, 8, 2, 1, 126, 4, - 45, 106, 8, 2, 1, 243, 47, 8, 2, 1, 243, 48, 4, 131, 50, 206, 183, 8, 2, - 1, 243, 48, 4, 131, 45, 204, 0, 8, 2, 1, 192, 236, 4, 131, 50, 206, 183, - 8, 2, 1, 192, 236, 4, 177, 45, 219, 188, 8, 2, 1, 192, 236, 4, 177, 45, - 219, 189, 24, 131, 50, 206, 183, 8, 2, 1, 192, 236, 4, 177, 45, 219, 189, - 4, 204, 0, 8, 2, 1, 192, 160, 4, 203, 35, 50, 219, 188, 59, 247, 245, 4, - 223, 65, 247, 244, 59, 1, 2, 229, 164, 59, 1, 2, 220, 119, 4, 223, 65, - 219, 221, 206, 3, 59, 1, 2, 220, 119, 4, 82, 198, 147, 59, 1, 2, 126, 4, - 45, 106, 8, 2, 1, 205, 169, 192, 95, 8, 2, 1, 223, 53, 73, 8, 2, 1, 211, - 66, 211, 139, 8, 2, 1, 196, 78, 8, 2, 1, 223, 65, 251, 109, 35, 1, 2, 6, - 211, 99, 8, 2, 1, 234, 249, 236, 214, 4, 207, 19, 106, 8, 2, 1, 197, 166, - 236, 214, 4, 207, 19, 106, 8, 2, 1, 152, 207, 217, 4, 82, 198, 147, 59, - 1, 2, 152, 193, 221, 59, 1, 45, 199, 223, 59, 1, 50, 199, 223, 101, 2, 1, - 65, 101, 2, 1, 73, 101, 2, 1, 70, 101, 2, 1, 74, 101, 2, 1, 69, 101, 2, - 1, 196, 8, 101, 2, 1, 231, 203, 101, 2, 1, 157, 101, 2, 1, 231, 128, 101, - 2, 1, 231, 16, 101, 2, 1, 230, 223, 101, 2, 1, 230, 146, 101, 2, 1, 230, - 105, 101, 2, 1, 144, 101, 2, 1, 229, 213, 101, 2, 1, 229, 126, 101, 2, 1, - 228, 247, 101, 2, 1, 228, 128, 101, 2, 1, 228, 95, 101, 2, 1, 171, 101, - 2, 1, 219, 214, 101, 2, 1, 219, 122, 101, 2, 1, 219, 19, 101, 2, 1, 218, - 203, 101, 2, 1, 218, 171, 101, 2, 1, 172, 101, 2, 1, 216, 213, 101, 2, 1, - 216, 81, 101, 2, 1, 215, 251, 101, 2, 1, 215, 139, 101, 2, 1, 180, 101, - 2, 1, 229, 15, 101, 2, 1, 214, 223, 101, 2, 1, 214, 107, 101, 2, 1, 213, - 205, 101, 2, 1, 213, 30, 101, 2, 1, 212, 165, 101, 2, 1, 212, 99, 101, 2, - 1, 208, 26, 101, 2, 1, 208, 11, 101, 2, 1, 208, 4, 101, 2, 1, 207, 250, - 101, 2, 1, 207, 239, 101, 2, 1, 207, 237, 101, 2, 1, 189, 101, 2, 1, 206, - 3, 101, 2, 1, 205, 63, 101, 2, 1, 202, 217, 101, 2, 1, 202, 41, 101, 2, - 1, 200, 255, 101, 2, 1, 200, 154, 101, 2, 1, 237, 241, 101, 2, 1, 199, - 247, 101, 2, 1, 237, 101, 101, 2, 1, 199, 140, 101, 2, 1, 236, 255, 101, - 2, 1, 198, 188, 101, 2, 1, 236, 129, 101, 2, 1, 235, 45, 101, 2, 1, 235, - 13, 101, 2, 1, 236, 141, 101, 2, 1, 198, 110, 101, 2, 1, 198, 109, 101, - 2, 1, 198, 98, 101, 2, 1, 198, 97, 101, 2, 1, 198, 96, 101, 2, 1, 198, - 95, 101, 2, 1, 197, 164, 101, 2, 1, 197, 157, 101, 2, 1, 197, 142, 101, - 2, 1, 197, 140, 101, 2, 1, 197, 136, 101, 2, 1, 197, 135, 101, 2, 1, 193, - 187, 101, 2, 1, 193, 123, 101, 2, 1, 193, 84, 101, 2, 1, 193, 48, 101, 2, - 1, 193, 0, 101, 2, 1, 192, 243, 101, 2, 1, 169, 216, 186, 216, 255, 1, - 221, 27, 216, 186, 216, 255, 1, 205, 147, 216, 186, 216, 255, 1, 220, 72, - 216, 186, 216, 255, 1, 216, 6, 216, 186, 216, 255, 1, 168, 216, 186, 216, - 255, 1, 180, 216, 186, 216, 255, 1, 243, 39, 216, 186, 216, 255, 1, 198, - 149, 216, 186, 216, 255, 1, 221, 152, 216, 186, 216, 255, 1, 213, 225, - 216, 186, 216, 255, 1, 198, 227, 216, 186, 216, 255, 1, 193, 170, 216, - 186, 216, 255, 1, 192, 106, 216, 186, 216, 255, 1, 228, 116, 216, 186, - 216, 255, 1, 196, 109, 216, 186, 216, 255, 1, 70, 216, 186, 216, 255, 1, - 209, 213, 216, 186, 216, 255, 1, 250, 125, 216, 186, 216, 255, 1, 230, - 215, 216, 186, 216, 255, 1, 222, 223, 216, 186, 216, 255, 1, 207, 151, - 216, 186, 216, 255, 1, 249, 103, 216, 186, 216, 255, 1, 222, 207, 216, - 186, 216, 255, 1, 236, 212, 216, 186, 216, 255, 1, 231, 23, 216, 186, - 216, 255, 1, 237, 1, 216, 186, 216, 255, 1, 248, 150, 216, 186, 216, 255, - 1, 221, 28, 218, 241, 216, 186, 216, 255, 1, 220, 73, 218, 241, 216, 186, - 216, 255, 1, 216, 7, 218, 241, 216, 186, 216, 255, 1, 210, 211, 218, 241, - 216, 186, 216, 255, 1, 214, 249, 218, 241, 216, 186, 216, 255, 1, 198, - 150, 218, 241, 216, 186, 216, 255, 1, 213, 226, 218, 241, 216, 186, 216, - 255, 1, 228, 44, 218, 241, 216, 186, 216, 255, 18, 3, 211, 91, 216, 186, - 216, 255, 18, 3, 223, 132, 216, 186, 216, 255, 18, 3, 251, 79, 216, 186, - 216, 255, 18, 3, 192, 69, 216, 186, 216, 255, 18, 3, 202, 1, 216, 186, - 216, 255, 18, 3, 196, 106, 216, 186, 216, 255, 18, 3, 243, 66, 216, 186, - 216, 255, 18, 3, 212, 114, 216, 186, 216, 255, 243, 67, 216, 186, 216, - 255, 218, 187, 223, 14, 216, 186, 216, 255, 250, 244, 223, 14, 216, 186, - 216, 255, 17, 191, 77, 216, 186, 216, 255, 17, 108, 216, 186, 216, 255, - 17, 109, 216, 186, 216, 255, 17, 139, 216, 186, 216, 255, 17, 137, 216, - 186, 216, 255, 17, 153, 216, 186, 216, 255, 17, 173, 216, 186, 216, 255, - 17, 181, 216, 186, 216, 255, 17, 176, 216, 186, 216, 255, 17, 184, 30, - 222, 147, 211, 246, 30, 222, 147, 211, 251, 30, 222, 147, 192, 5, 30, - 222, 147, 192, 4, 30, 222, 147, 192, 3, 30, 222, 147, 196, 214, 30, 222, - 147, 196, 218, 30, 222, 147, 191, 219, 30, 222, 147, 191, 215, 30, 222, - 147, 233, 200, 30, 222, 147, 233, 198, 30, 222, 147, 233, 199, 30, 222, - 147, 233, 196, 30, 222, 147, 228, 30, 30, 222, 147, 228, 29, 30, 222, - 147, 228, 27, 30, 222, 147, 228, 28, 30, 222, 147, 228, 33, 30, 222, 147, - 228, 26, 30, 222, 147, 228, 25, 30, 222, 147, 228, 35, 30, 222, 147, 250, - 230, 30, 222, 147, 250, 229, 30, 125, 213, 183, 30, 125, 213, 189, 30, - 125, 201, 151, 30, 125, 201, 150, 30, 125, 198, 158, 30, 125, 198, 156, - 30, 125, 198, 155, 30, 125, 198, 161, 30, 125, 198, 162, 30, 125, 198, - 154, 30, 125, 206, 213, 30, 125, 206, 228, 30, 125, 201, 157, 30, 125, - 206, 225, 30, 125, 206, 215, 30, 125, 206, 217, 30, 125, 206, 204, 30, - 125, 206, 205, 30, 125, 222, 42, 30, 125, 216, 54, 30, 125, 216, 48, 30, - 125, 201, 161, 30, 125, 216, 51, 30, 125, 216, 57, 30, 125, 209, 141, 30, - 125, 209, 150, 30, 125, 209, 154, 30, 125, 201, 159, 30, 125, 209, 144, - 30, 125, 209, 158, 30, 125, 209, 159, 30, 125, 202, 147, 30, 125, 202, - 150, 30, 125, 201, 155, 30, 125, 201, 153, 30, 125, 202, 145, 30, 125, - 202, 153, 30, 125, 202, 154, 30, 125, 202, 139, 30, 125, 202, 152, 30, - 125, 210, 137, 30, 125, 210, 138, 30, 125, 192, 53, 30, 125, 192, 56, 30, - 125, 242, 230, 30, 125, 242, 229, 30, 125, 201, 166, 30, 125, 209, 197, - 30, 125, 209, 196, 12, 15, 225, 161, 12, 15, 225, 160, 12, 15, 225, 159, - 12, 15, 225, 158, 12, 15, 225, 157, 12, 15, 225, 156, 12, 15, 225, 155, - 12, 15, 225, 154, 12, 15, 225, 153, 12, 15, 225, 152, 12, 15, 225, 151, - 12, 15, 225, 150, 12, 15, 225, 149, 12, 15, 225, 148, 12, 15, 225, 147, - 12, 15, 225, 146, 12, 15, 225, 145, 12, 15, 225, 144, 12, 15, 225, 143, - 12, 15, 225, 142, 12, 15, 225, 141, 12, 15, 225, 140, 12, 15, 225, 139, - 12, 15, 225, 138, 12, 15, 225, 137, 12, 15, 225, 136, 12, 15, 225, 135, - 12, 15, 225, 134, 12, 15, 225, 133, 12, 15, 225, 132, 12, 15, 225, 131, - 12, 15, 225, 130, 12, 15, 225, 129, 12, 15, 225, 128, 12, 15, 225, 127, - 12, 15, 225, 126, 12, 15, 225, 125, 12, 15, 225, 124, 12, 15, 225, 123, - 12, 15, 225, 122, 12, 15, 225, 121, 12, 15, 225, 120, 12, 15, 225, 119, - 12, 15, 225, 118, 12, 15, 225, 117, 12, 15, 225, 116, 12, 15, 225, 115, - 12, 15, 225, 114, 12, 15, 225, 113, 12, 15, 225, 112, 12, 15, 225, 111, - 12, 15, 225, 110, 12, 15, 225, 109, 12, 15, 225, 108, 12, 15, 225, 107, - 12, 15, 225, 106, 12, 15, 225, 105, 12, 15, 225, 104, 12, 15, 225, 103, - 12, 15, 225, 102, 12, 15, 225, 101, 12, 15, 225, 100, 12, 15, 225, 99, - 12, 15, 225, 98, 12, 15, 225, 97, 12, 15, 225, 96, 12, 15, 225, 95, 12, - 15, 225, 94, 12, 15, 225, 93, 12, 15, 225, 92, 12, 15, 225, 91, 12, 15, - 225, 90, 12, 15, 225, 89, 12, 15, 225, 88, 12, 15, 225, 87, 12, 15, 225, - 86, 12, 15, 225, 85, 12, 15, 225, 84, 12, 15, 225, 83, 12, 15, 225, 82, - 12, 15, 225, 81, 12, 15, 225, 80, 12, 15, 225, 79, 12, 15, 225, 78, 12, - 15, 225, 77, 12, 15, 225, 76, 12, 15, 225, 75, 12, 15, 225, 74, 12, 15, - 225, 73, 12, 15, 225, 72, 12, 15, 225, 71, 12, 15, 225, 70, 12, 15, 225, - 69, 12, 15, 225, 68, 12, 15, 225, 67, 12, 15, 225, 66, 12, 15, 225, 65, - 12, 15, 225, 64, 12, 15, 225, 63, 12, 15, 225, 62, 12, 15, 225, 61, 12, - 15, 225, 60, 12, 15, 225, 59, 12, 15, 225, 58, 12, 15, 225, 57, 12, 15, - 225, 56, 12, 15, 225, 55, 12, 15, 225, 54, 12, 15, 225, 53, 12, 15, 225, - 52, 12, 15, 225, 51, 12, 15, 225, 50, 12, 15, 225, 49, 12, 15, 225, 48, - 12, 15, 225, 47, 12, 15, 225, 46, 12, 15, 225, 45, 12, 15, 225, 44, 12, - 15, 225, 43, 12, 15, 225, 42, 12, 15, 225, 41, 12, 15, 225, 40, 12, 15, - 225, 39, 12, 15, 225, 38, 12, 15, 225, 37, 12, 15, 225, 36, 12, 15, 225, - 35, 12, 15, 225, 34, 12, 15, 225, 33, 12, 15, 225, 32, 12, 15, 225, 31, - 12, 15, 225, 30, 12, 15, 225, 29, 12, 15, 225, 28, 12, 15, 225, 27, 12, - 15, 225, 26, 12, 15, 225, 25, 12, 15, 225, 24, 12, 15, 225, 23, 12, 15, - 225, 22, 12, 15, 225, 21, 12, 15, 225, 20, 12, 15, 225, 19, 12, 15, 225, - 18, 12, 15, 225, 17, 12, 15, 225, 16, 12, 15, 225, 15, 12, 15, 225, 14, - 12, 15, 225, 13, 12, 15, 225, 12, 12, 15, 225, 11, 12, 15, 225, 10, 12, - 15, 225, 9, 12, 15, 225, 8, 12, 15, 225, 7, 12, 15, 225, 6, 12, 15, 225, - 5, 12, 15, 225, 4, 12, 15, 225, 3, 12, 15, 225, 2, 12, 15, 225, 1, 12, - 15, 225, 0, 12, 15, 224, 255, 12, 15, 224, 254, 12, 15, 224, 253, 12, 15, - 224, 252, 12, 15, 224, 251, 12, 15, 224, 250, 12, 15, 224, 249, 12, 15, - 224, 248, 12, 15, 224, 247, 12, 15, 224, 246, 12, 15, 224, 245, 12, 15, - 224, 244, 12, 15, 224, 243, 12, 15, 224, 242, 12, 15, 224, 241, 12, 15, - 224, 240, 12, 15, 224, 239, 12, 15, 224, 238, 12, 15, 224, 237, 12, 15, - 224, 236, 12, 15, 224, 235, 12, 15, 224, 234, 12, 15, 224, 233, 12, 15, - 224, 232, 12, 15, 224, 231, 12, 15, 224, 230, 12, 15, 224, 229, 12, 15, - 224, 228, 12, 15, 224, 227, 12, 15, 224, 226, 12, 15, 224, 225, 12, 15, - 224, 224, 12, 15, 224, 223, 12, 15, 224, 222, 12, 15, 224, 221, 12, 15, - 224, 220, 12, 15, 224, 219, 12, 15, 224, 218, 12, 15, 224, 217, 12, 15, - 224, 216, 12, 15, 224, 215, 12, 15, 224, 214, 12, 15, 224, 213, 12, 15, - 224, 212, 12, 15, 224, 211, 12, 15, 224, 210, 12, 15, 224, 209, 12, 15, - 224, 208, 12, 15, 224, 207, 12, 15, 224, 206, 12, 15, 224, 205, 12, 15, - 224, 204, 12, 15, 224, 203, 12, 15, 224, 202, 12, 15, 224, 201, 12, 15, - 224, 200, 12, 15, 224, 199, 12, 15, 224, 198, 12, 15, 224, 197, 12, 15, - 224, 196, 12, 15, 224, 195, 12, 15, 224, 194, 12, 15, 224, 193, 12, 15, - 224, 192, 12, 15, 224, 191, 12, 15, 224, 190, 12, 15, 224, 189, 12, 15, - 224, 188, 12, 15, 224, 187, 12, 15, 224, 186, 12, 15, 224, 185, 12, 15, - 224, 184, 12, 15, 224, 183, 12, 15, 224, 182, 12, 15, 224, 181, 12, 15, - 224, 180, 12, 15, 224, 179, 12, 15, 224, 178, 12, 15, 224, 177, 12, 15, - 224, 176, 12, 15, 224, 175, 12, 15, 224, 174, 12, 15, 224, 173, 12, 15, - 224, 172, 12, 15, 224, 171, 12, 15, 224, 170, 12, 15, 224, 169, 12, 15, - 224, 168, 12, 15, 224, 167, 12, 15, 224, 166, 12, 15, 224, 165, 12, 15, - 224, 164, 12, 15, 224, 163, 12, 15, 224, 162, 12, 15, 224, 161, 12, 15, - 224, 160, 12, 15, 224, 159, 12, 15, 224, 158, 12, 15, 224, 157, 12, 15, - 224, 156, 12, 15, 224, 155, 12, 15, 224, 154, 12, 15, 224, 153, 12, 15, - 224, 152, 12, 15, 224, 151, 12, 15, 224, 150, 12, 15, 224, 149, 12, 15, - 224, 148, 12, 15, 224, 147, 12, 15, 224, 146, 12, 15, 224, 145, 12, 15, - 224, 144, 12, 15, 224, 143, 12, 15, 224, 142, 12, 15, 224, 141, 12, 15, - 224, 140, 12, 15, 224, 139, 12, 15, 224, 138, 12, 15, 224, 137, 12, 15, - 224, 136, 12, 15, 224, 135, 12, 15, 224, 134, 12, 15, 224, 133, 12, 15, - 224, 132, 12, 15, 224, 131, 12, 15, 224, 130, 12, 15, 224, 129, 12, 15, - 224, 128, 12, 15, 224, 127, 12, 15, 224, 126, 12, 15, 224, 125, 12, 15, - 224, 124, 12, 15, 224, 123, 12, 15, 224, 122, 12, 15, 224, 121, 12, 15, - 224, 120, 12, 15, 224, 119, 12, 15, 224, 118, 12, 15, 224, 117, 12, 15, - 224, 116, 12, 15, 224, 115, 12, 15, 224, 114, 12, 15, 224, 113, 12, 15, - 224, 112, 12, 15, 224, 111, 12, 15, 224, 110, 12, 15, 224, 109, 12, 15, - 224, 108, 12, 15, 224, 107, 12, 15, 224, 106, 12, 15, 224, 105, 12, 15, - 224, 104, 12, 15, 224, 103, 12, 15, 224, 102, 12, 15, 224, 101, 12, 15, - 224, 100, 12, 15, 224, 99, 12, 15, 224, 98, 12, 15, 224, 97, 12, 15, 224, - 96, 12, 15, 224, 95, 12, 15, 224, 94, 12, 15, 224, 93, 12, 15, 224, 92, - 12, 15, 224, 91, 12, 15, 224, 90, 12, 15, 224, 89, 12, 15, 224, 88, 12, - 15, 224, 87, 12, 15, 224, 86, 12, 15, 224, 85, 12, 15, 224, 84, 12, 15, - 224, 83, 12, 15, 224, 82, 12, 15, 224, 81, 12, 15, 224, 80, 12, 15, 224, - 79, 12, 15, 224, 78, 12, 15, 224, 77, 12, 15, 224, 76, 12, 15, 224, 75, - 12, 15, 224, 74, 12, 15, 224, 73, 12, 15, 224, 72, 12, 15, 224, 71, 12, - 15, 224, 70, 12, 15, 224, 69, 12, 15, 224, 68, 12, 15, 224, 67, 12, 15, - 224, 66, 12, 15, 224, 65, 12, 15, 224, 64, 12, 15, 224, 63, 12, 15, 224, - 62, 12, 15, 224, 61, 12, 15, 224, 60, 12, 15, 224, 59, 12, 15, 224, 58, - 12, 15, 224, 57, 12, 15, 224, 56, 12, 15, 224, 55, 12, 15, 224, 54, 12, - 15, 224, 53, 12, 15, 224, 52, 12, 15, 224, 51, 12, 15, 224, 50, 12, 15, - 224, 49, 12, 15, 224, 48, 12, 15, 224, 47, 12, 15, 224, 46, 12, 15, 224, - 45, 12, 15, 224, 44, 12, 15, 224, 43, 12, 15, 224, 42, 12, 15, 224, 41, - 12, 15, 224, 40, 12, 15, 224, 39, 12, 15, 224, 38, 12, 15, 224, 37, 12, - 15, 224, 36, 12, 15, 224, 35, 12, 15, 224, 34, 12, 15, 224, 33, 12, 15, - 224, 32, 12, 15, 224, 31, 12, 15, 224, 30, 12, 15, 224, 29, 12, 15, 224, - 28, 12, 15, 224, 27, 12, 15, 224, 26, 12, 15, 224, 25, 12, 15, 224, 24, - 12, 15, 224, 23, 12, 15, 224, 22, 12, 15, 224, 21, 12, 15, 224, 20, 12, - 15, 224, 19, 12, 15, 224, 18, 12, 15, 224, 17, 12, 15, 224, 16, 12, 15, - 224, 15, 12, 15, 224, 14, 12, 15, 224, 13, 12, 15, 224, 12, 12, 15, 224, - 11, 12, 15, 224, 10, 12, 15, 224, 9, 12, 15, 224, 8, 12, 15, 224, 7, 12, - 15, 224, 6, 12, 15, 224, 5, 12, 15, 224, 4, 12, 15, 224, 3, 12, 15, 224, - 2, 12, 15, 224, 1, 12, 15, 224, 0, 12, 15, 223, 255, 12, 15, 223, 254, - 12, 15, 223, 253, 12, 15, 223, 252, 12, 15, 223, 251, 12, 15, 223, 250, - 12, 15, 223, 249, 12, 15, 223, 248, 12, 15, 223, 247, 12, 15, 223, 246, - 12, 15, 223, 245, 12, 15, 223, 244, 12, 15, 223, 243, 12, 15, 223, 242, - 12, 15, 223, 241, 12, 15, 223, 240, 12, 15, 223, 239, 12, 15, 223, 238, - 12, 15, 223, 237, 12, 15, 223, 236, 12, 15, 223, 235, 12, 15, 223, 234, - 12, 15, 223, 233, 12, 15, 223, 232, 12, 15, 223, 231, 12, 15, 223, 230, - 12, 15, 223, 229, 12, 15, 223, 228, 12, 15, 223, 227, 12, 15, 223, 226, - 12, 15, 223, 225, 12, 15, 223, 224, 12, 15, 223, 223, 12, 15, 223, 222, - 12, 15, 223, 221, 12, 15, 223, 220, 12, 15, 223, 219, 12, 15, 223, 218, - 12, 15, 223, 217, 12, 15, 223, 216, 12, 15, 223, 215, 12, 15, 223, 214, - 12, 15, 223, 213, 12, 15, 223, 212, 12, 15, 223, 211, 12, 15, 223, 210, - 12, 15, 223, 209, 12, 15, 223, 208, 12, 15, 223, 207, 12, 15, 223, 206, - 12, 15, 223, 205, 12, 15, 223, 204, 12, 15, 223, 203, 12, 15, 223, 202, - 8, 2, 34, 232, 242, 8, 2, 34, 232, 238, 8, 2, 34, 232, 180, 8, 2, 34, - 232, 241, 8, 2, 34, 232, 240, 8, 2, 34, 177, 206, 4, 200, 39, 8, 2, 34, - 201, 113, 250, 199, 2, 34, 216, 168, 212, 240, 250, 199, 2, 34, 216, 168, - 234, 151, 250, 199, 2, 34, 216, 168, 223, 103, 250, 199, 2, 34, 195, 72, - 212, 240, 250, 199, 2, 34, 216, 168, 192, 212, 135, 1, 191, 251, 4, 229, - 87, 135, 209, 55, 222, 154, 195, 163, 135, 34, 192, 31, 191, 251, 191, - 251, 210, 78, 135, 1, 251, 101, 250, 76, 135, 1, 193, 76, 251, 141, 135, - 1, 193, 76, 237, 206, 135, 1, 193, 76, 229, 213, 135, 1, 193, 76, 222, - 79, 135, 1, 193, 76, 220, 3, 135, 1, 193, 76, 52, 216, 174, 135, 1, 193, - 76, 207, 33, 135, 1, 193, 76, 199, 157, 135, 1, 251, 101, 107, 57, 135, - 1, 203, 65, 4, 203, 65, 236, 96, 135, 1, 203, 65, 4, 202, 170, 236, 96, - 135, 1, 203, 65, 4, 237, 226, 24, 203, 65, 236, 96, 135, 1, 203, 65, 4, - 237, 226, 24, 202, 170, 236, 96, 135, 1, 130, 4, 210, 78, 135, 1, 130, 4, - 208, 77, 135, 1, 130, 4, 217, 50, 135, 1, 248, 165, 4, 237, 225, 135, 1, - 231, 2, 4, 237, 225, 135, 1, 237, 207, 4, 237, 225, 135, 1, 229, 214, 4, - 217, 50, 135, 1, 195, 156, 4, 237, 225, 135, 1, 191, 92, 4, 237, 225, - 135, 1, 199, 69, 4, 237, 225, 135, 1, 191, 251, 4, 237, 225, 135, 1, 52, - 222, 80, 4, 237, 225, 135, 1, 222, 80, 4, 237, 225, 135, 1, 220, 4, 4, - 237, 225, 135, 1, 216, 175, 4, 237, 225, 135, 1, 212, 118, 4, 237, 225, - 135, 1, 205, 144, 4, 237, 225, 135, 1, 52, 210, 54, 4, 237, 225, 135, 1, - 210, 54, 4, 237, 225, 135, 1, 197, 160, 4, 237, 225, 135, 1, 208, 37, 4, - 237, 225, 135, 1, 207, 34, 4, 237, 225, 135, 1, 203, 65, 4, 237, 225, - 135, 1, 199, 158, 4, 237, 225, 135, 1, 195, 156, 4, 228, 231, 135, 1, - 248, 165, 4, 207, 156, 135, 1, 222, 80, 4, 207, 156, 135, 1, 210, 54, 4, - 207, 156, 135, 34, 130, 220, 3, 9, 1, 130, 193, 149, 76, 20, 9, 1, 130, - 193, 149, 52, 20, 9, 1, 248, 206, 76, 20, 9, 1, 248, 206, 52, 20, 9, 1, - 248, 206, 89, 20, 9, 1, 248, 206, 216, 198, 20, 9, 1, 210, 33, 76, 20, 9, - 1, 210, 33, 52, 20, 9, 1, 210, 33, 89, 20, 9, 1, 210, 33, 216, 198, 20, - 9, 1, 248, 194, 76, 20, 9, 1, 248, 194, 52, 20, 9, 1, 248, 194, 89, 20, - 9, 1, 248, 194, 216, 198, 20, 9, 1, 197, 119, 76, 20, 9, 1, 197, 119, 52, - 20, 9, 1, 197, 119, 89, 20, 9, 1, 197, 119, 216, 198, 20, 9, 1, 199, 108, - 76, 20, 9, 1, 199, 108, 52, 20, 9, 1, 199, 108, 89, 20, 9, 1, 199, 108, - 216, 198, 20, 9, 1, 197, 121, 76, 20, 9, 1, 197, 121, 52, 20, 9, 1, 197, - 121, 89, 20, 9, 1, 197, 121, 216, 198, 20, 9, 1, 195, 144, 76, 20, 9, 1, - 195, 144, 52, 20, 9, 1, 195, 144, 89, 20, 9, 1, 195, 144, 216, 198, 20, - 9, 1, 210, 31, 76, 20, 9, 1, 210, 31, 52, 20, 9, 1, 210, 31, 89, 20, 9, - 1, 210, 31, 216, 198, 20, 9, 1, 234, 254, 76, 20, 9, 1, 234, 254, 52, 20, - 9, 1, 234, 254, 89, 20, 9, 1, 234, 254, 216, 198, 20, 9, 1, 212, 75, 76, - 20, 9, 1, 212, 75, 52, 20, 9, 1, 212, 75, 89, 20, 9, 1, 212, 75, 216, - 198, 20, 9, 1, 199, 145, 76, 20, 9, 1, 199, 145, 52, 20, 9, 1, 199, 145, - 89, 20, 9, 1, 199, 145, 216, 198, 20, 9, 1, 199, 143, 76, 20, 9, 1, 199, - 143, 52, 20, 9, 1, 199, 143, 89, 20, 9, 1, 199, 143, 216, 198, 20, 9, 1, - 237, 144, 76, 20, 9, 1, 237, 144, 52, 20, 9, 1, 237, 220, 76, 20, 9, 1, - 237, 220, 52, 20, 9, 1, 235, 35, 76, 20, 9, 1, 235, 35, 52, 20, 9, 1, - 237, 142, 76, 20, 9, 1, 237, 142, 52, 20, 9, 1, 222, 232, 76, 20, 9, 1, - 222, 232, 52, 20, 9, 1, 206, 97, 76, 20, 9, 1, 206, 97, 52, 20, 9, 1, - 221, 236, 76, 20, 9, 1, 221, 236, 52, 20, 9, 1, 221, 236, 89, 20, 9, 1, - 221, 236, 216, 198, 20, 9, 1, 231, 191, 76, 20, 9, 1, 231, 191, 52, 20, - 9, 1, 231, 191, 89, 20, 9, 1, 231, 191, 216, 198, 20, 9, 1, 230, 134, 76, - 20, 9, 1, 230, 134, 52, 20, 9, 1, 230, 134, 89, 20, 9, 1, 230, 134, 216, - 198, 20, 9, 1, 213, 234, 76, 20, 9, 1, 213, 234, 52, 20, 9, 1, 213, 234, - 89, 20, 9, 1, 213, 234, 216, 198, 20, 9, 1, 213, 12, 231, 21, 76, 20, 9, - 1, 213, 12, 231, 21, 52, 20, 9, 1, 206, 161, 76, 20, 9, 1, 206, 161, 52, - 20, 9, 1, 206, 161, 89, 20, 9, 1, 206, 161, 216, 198, 20, 9, 1, 229, 179, - 4, 99, 95, 76, 20, 9, 1, 229, 179, 4, 99, 95, 52, 20, 9, 1, 229, 179, - 230, 221, 76, 20, 9, 1, 229, 179, 230, 221, 52, 20, 9, 1, 229, 179, 230, - 221, 89, 20, 9, 1, 229, 179, 230, 221, 216, 198, 20, 9, 1, 229, 179, 236, - 126, 76, 20, 9, 1, 229, 179, 236, 126, 52, 20, 9, 1, 229, 179, 236, 126, - 89, 20, 9, 1, 229, 179, 236, 126, 216, 198, 20, 9, 1, 99, 249, 31, 76, - 20, 9, 1, 99, 249, 31, 52, 20, 9, 1, 99, 249, 31, 4, 230, 25, 95, 76, 20, - 9, 1, 99, 249, 31, 4, 230, 25, 95, 52, 20, 9, 16, 75, 56, 9, 16, 75, 60, - 9, 16, 103, 183, 56, 9, 16, 103, 183, 60, 9, 16, 115, 183, 56, 9, 16, - 115, 183, 60, 9, 16, 115, 183, 209, 51, 235, 75, 56, 9, 16, 115, 183, - 209, 51, 235, 75, 60, 9, 16, 232, 90, 183, 56, 9, 16, 232, 90, 183, 60, - 9, 16, 54, 81, 249, 38, 60, 9, 16, 103, 183, 195, 82, 56, 9, 16, 103, - 183, 195, 82, 60, 9, 16, 206, 183, 9, 16, 2, 199, 215, 56, 9, 16, 2, 199, - 215, 60, 9, 16, 193, 149, 56, 9, 1, 214, 57, 76, 20, 9, 1, 214, 57, 52, - 20, 9, 1, 214, 57, 89, 20, 9, 1, 214, 57, 216, 198, 20, 9, 1, 126, 76, - 20, 9, 1, 126, 52, 20, 9, 1, 211, 140, 76, 20, 9, 1, 211, 140, 52, 20, 9, - 1, 191, 226, 76, 20, 9, 1, 191, 226, 52, 20, 9, 1, 126, 4, 230, 25, 95, - 76, 20, 9, 1, 195, 151, 76, 20, 9, 1, 195, 151, 52, 20, 9, 1, 221, 108, - 211, 140, 76, 20, 9, 1, 221, 108, 211, 140, 52, 20, 9, 1, 221, 108, 191, - 226, 76, 20, 9, 1, 221, 108, 191, 226, 52, 20, 9, 1, 234, 227, 76, 20, 9, - 1, 234, 227, 52, 20, 9, 1, 234, 227, 89, 20, 9, 1, 234, 227, 216, 198, - 20, 9, 1, 196, 133, 222, 1, 221, 108, 130, 217, 80, 89, 20, 9, 1, 196, - 133, 222, 1, 221, 108, 130, 217, 80, 216, 198, 20, 9, 34, 99, 4, 230, 25, - 95, 4, 130, 76, 20, 9, 34, 99, 4, 230, 25, 95, 4, 130, 52, 20, 9, 34, 99, - 4, 230, 25, 95, 4, 251, 230, 76, 20, 9, 34, 99, 4, 230, 25, 95, 4, 251, - 230, 52, 20, 9, 34, 99, 4, 230, 25, 95, 4, 193, 132, 76, 20, 9, 34, 99, - 4, 230, 25, 95, 4, 193, 132, 52, 20, 9, 34, 99, 4, 230, 25, 95, 4, 126, - 76, 20, 9, 34, 99, 4, 230, 25, 95, 4, 126, 52, 20, 9, 34, 99, 4, 230, 25, - 95, 4, 211, 140, 76, 20, 9, 34, 99, 4, 230, 25, 95, 4, 211, 140, 52, 20, - 9, 34, 99, 4, 230, 25, 95, 4, 191, 226, 76, 20, 9, 34, 99, 4, 230, 25, - 95, 4, 191, 226, 52, 20, 9, 34, 99, 4, 230, 25, 95, 4, 234, 227, 76, 20, - 9, 34, 99, 4, 230, 25, 95, 4, 234, 227, 52, 20, 9, 34, 99, 4, 230, 25, - 95, 4, 234, 227, 89, 20, 9, 34, 196, 133, 221, 108, 99, 4, 230, 25, 95, - 4, 130, 217, 80, 76, 20, 9, 34, 196, 133, 221, 108, 99, 4, 230, 25, 95, - 4, 130, 217, 80, 52, 20, 9, 34, 196, 133, 221, 108, 99, 4, 230, 25, 95, - 4, 130, 217, 80, 89, 20, 9, 1, 233, 33, 99, 76, 20, 9, 1, 233, 33, 99, - 52, 20, 9, 1, 233, 33, 99, 89, 20, 9, 1, 233, 33, 99, 216, 198, 20, 9, - 34, 99, 4, 230, 25, 95, 4, 222, 235, 76, 20, 9, 34, 99, 4, 230, 25, 95, - 4, 179, 76, 20, 9, 34, 99, 4, 230, 25, 95, 4, 92, 76, 20, 9, 34, 99, 4, - 230, 25, 95, 4, 130, 217, 80, 76, 20, 9, 34, 99, 4, 230, 25, 95, 4, 99, - 76, 20, 9, 34, 248, 196, 4, 222, 235, 76, 20, 9, 34, 248, 196, 4, 179, - 76, 20, 9, 34, 248, 196, 4, 221, 186, 76, 20, 9, 34, 248, 196, 4, 92, 76, - 20, 9, 34, 248, 196, 4, 130, 217, 80, 76, 20, 9, 34, 248, 196, 4, 99, 76, - 20, 9, 34, 199, 110, 4, 222, 235, 76, 20, 9, 34, 199, 110, 4, 179, 76, - 20, 9, 34, 199, 110, 4, 221, 186, 76, 20, 9, 34, 199, 110, 4, 92, 76, 20, - 9, 34, 199, 110, 4, 130, 217, 80, 76, 20, 9, 34, 199, 110, 4, 99, 76, 20, - 9, 34, 199, 25, 4, 222, 235, 76, 20, 9, 34, 199, 25, 4, 92, 76, 20, 9, - 34, 199, 25, 4, 130, 217, 80, 76, 20, 9, 34, 199, 25, 4, 99, 76, 20, 9, - 34, 222, 235, 4, 179, 76, 20, 9, 34, 222, 235, 4, 92, 76, 20, 9, 34, 179, - 4, 222, 235, 76, 20, 9, 34, 179, 4, 92, 76, 20, 9, 34, 221, 186, 4, 222, - 235, 76, 20, 9, 34, 221, 186, 4, 179, 76, 20, 9, 34, 221, 186, 4, 92, 76, - 20, 9, 34, 205, 42, 4, 222, 235, 76, 20, 9, 34, 205, 42, 4, 179, 76, 20, - 9, 34, 205, 42, 4, 221, 186, 76, 20, 9, 34, 205, 42, 4, 92, 76, 20, 9, - 34, 205, 188, 4, 179, 76, 20, 9, 34, 205, 188, 4, 92, 76, 20, 9, 34, 237, - 236, 4, 222, 235, 76, 20, 9, 34, 237, 236, 4, 179, 76, 20, 9, 34, 237, - 236, 4, 221, 186, 76, 20, 9, 34, 237, 236, 4, 92, 76, 20, 9, 34, 199, - 215, 4, 179, 76, 20, 9, 34, 199, 215, 4, 92, 76, 20, 9, 34, 191, 117, 4, - 92, 76, 20, 9, 34, 251, 179, 4, 222, 235, 76, 20, 9, 34, 251, 179, 4, 92, - 76, 20, 9, 34, 231, 50, 4, 222, 235, 76, 20, 9, 34, 231, 50, 4, 92, 76, - 20, 9, 34, 233, 6, 4, 222, 235, 76, 20, 9, 34, 233, 6, 4, 179, 76, 20, 9, - 34, 233, 6, 4, 221, 186, 76, 20, 9, 34, 233, 6, 4, 92, 76, 20, 9, 34, - 233, 6, 4, 130, 217, 80, 76, 20, 9, 34, 233, 6, 4, 99, 76, 20, 9, 34, - 208, 83, 4, 179, 76, 20, 9, 34, 208, 83, 4, 92, 76, 20, 9, 34, 208, 83, - 4, 130, 217, 80, 76, 20, 9, 34, 208, 83, 4, 99, 76, 20, 9, 34, 222, 80, - 4, 130, 76, 20, 9, 34, 222, 80, 4, 222, 235, 76, 20, 9, 34, 222, 80, 4, - 179, 76, 20, 9, 34, 222, 80, 4, 221, 186, 76, 20, 9, 34, 222, 80, 4, 220, - 12, 76, 20, 9, 34, 222, 80, 4, 92, 76, 20, 9, 34, 222, 80, 4, 130, 217, - 80, 76, 20, 9, 34, 222, 80, 4, 99, 76, 20, 9, 34, 220, 12, 4, 222, 235, - 76, 20, 9, 34, 220, 12, 4, 179, 76, 20, 9, 34, 220, 12, 4, 221, 186, 76, - 20, 9, 34, 220, 12, 4, 92, 76, 20, 9, 34, 220, 12, 4, 130, 217, 80, 76, - 20, 9, 34, 220, 12, 4, 99, 76, 20, 9, 34, 92, 4, 222, 235, 76, 20, 9, 34, - 92, 4, 179, 76, 20, 9, 34, 92, 4, 221, 186, 76, 20, 9, 34, 92, 4, 92, 76, - 20, 9, 34, 92, 4, 130, 217, 80, 76, 20, 9, 34, 92, 4, 99, 76, 20, 9, 34, - 213, 12, 4, 222, 235, 76, 20, 9, 34, 213, 12, 4, 179, 76, 20, 9, 34, 213, - 12, 4, 221, 186, 76, 20, 9, 34, 213, 12, 4, 92, 76, 20, 9, 34, 213, 12, - 4, 130, 217, 80, 76, 20, 9, 34, 213, 12, 4, 99, 76, 20, 9, 34, 229, 179, - 4, 222, 235, 76, 20, 9, 34, 229, 179, 4, 92, 76, 20, 9, 34, 229, 179, 4, - 130, 217, 80, 76, 20, 9, 34, 229, 179, 4, 99, 76, 20, 9, 34, 99, 4, 222, - 235, 76, 20, 9, 34, 99, 4, 179, 76, 20, 9, 34, 99, 4, 221, 186, 76, 20, - 9, 34, 99, 4, 92, 76, 20, 9, 34, 99, 4, 130, 217, 80, 76, 20, 9, 34, 99, - 4, 99, 76, 20, 9, 34, 199, 37, 4, 200, 177, 130, 76, 20, 9, 34, 207, 67, - 4, 200, 177, 130, 76, 20, 9, 34, 130, 217, 80, 4, 200, 177, 130, 76, 20, - 9, 34, 203, 151, 4, 237, 199, 76, 20, 9, 34, 203, 151, 4, 222, 25, 76, - 20, 9, 34, 203, 151, 4, 233, 30, 76, 20, 9, 34, 203, 151, 4, 237, 201, - 76, 20, 9, 34, 203, 151, 4, 222, 27, 76, 20, 9, 34, 203, 151, 4, 200, - 177, 130, 76, 20, 9, 34, 99, 4, 230, 25, 95, 4, 207, 67, 52, 20, 9, 34, - 99, 4, 230, 25, 95, 4, 191, 114, 52, 20, 9, 34, 99, 4, 230, 25, 95, 4, - 92, 52, 20, 9, 34, 99, 4, 230, 25, 95, 4, 213, 12, 52, 20, 9, 34, 99, 4, - 230, 25, 95, 4, 130, 217, 80, 52, 20, 9, 34, 99, 4, 230, 25, 95, 4, 99, - 52, 20, 9, 34, 248, 196, 4, 207, 67, 52, 20, 9, 34, 248, 196, 4, 191, - 114, 52, 20, 9, 34, 248, 196, 4, 92, 52, 20, 9, 34, 248, 196, 4, 213, 12, - 52, 20, 9, 34, 248, 196, 4, 130, 217, 80, 52, 20, 9, 34, 248, 196, 4, 99, - 52, 20, 9, 34, 199, 110, 4, 207, 67, 52, 20, 9, 34, 199, 110, 4, 191, - 114, 52, 20, 9, 34, 199, 110, 4, 92, 52, 20, 9, 34, 199, 110, 4, 213, 12, - 52, 20, 9, 34, 199, 110, 4, 130, 217, 80, 52, 20, 9, 34, 199, 110, 4, 99, - 52, 20, 9, 34, 199, 25, 4, 207, 67, 52, 20, 9, 34, 199, 25, 4, 191, 114, - 52, 20, 9, 34, 199, 25, 4, 92, 52, 20, 9, 34, 199, 25, 4, 213, 12, 52, - 20, 9, 34, 199, 25, 4, 130, 217, 80, 52, 20, 9, 34, 199, 25, 4, 99, 52, - 20, 9, 34, 233, 6, 4, 130, 217, 80, 52, 20, 9, 34, 233, 6, 4, 99, 52, 20, - 9, 34, 208, 83, 4, 130, 217, 80, 52, 20, 9, 34, 208, 83, 4, 99, 52, 20, - 9, 34, 222, 80, 4, 130, 52, 20, 9, 34, 222, 80, 4, 220, 12, 52, 20, 9, - 34, 222, 80, 4, 92, 52, 20, 9, 34, 222, 80, 4, 130, 217, 80, 52, 20, 9, - 34, 222, 80, 4, 99, 52, 20, 9, 34, 220, 12, 4, 92, 52, 20, 9, 34, 220, - 12, 4, 130, 217, 80, 52, 20, 9, 34, 220, 12, 4, 99, 52, 20, 9, 34, 92, 4, - 130, 52, 20, 9, 34, 92, 4, 92, 52, 20, 9, 34, 213, 12, 4, 207, 67, 52, - 20, 9, 34, 213, 12, 4, 191, 114, 52, 20, 9, 34, 213, 12, 4, 92, 52, 20, - 9, 34, 213, 12, 4, 213, 12, 52, 20, 9, 34, 213, 12, 4, 130, 217, 80, 52, - 20, 9, 34, 213, 12, 4, 99, 52, 20, 9, 34, 130, 217, 80, 4, 200, 177, 130, - 52, 20, 9, 34, 99, 4, 207, 67, 52, 20, 9, 34, 99, 4, 191, 114, 52, 20, 9, - 34, 99, 4, 92, 52, 20, 9, 34, 99, 4, 213, 12, 52, 20, 9, 34, 99, 4, 130, - 217, 80, 52, 20, 9, 34, 99, 4, 99, 52, 20, 9, 34, 99, 4, 230, 25, 95, 4, - 222, 235, 89, 20, 9, 34, 99, 4, 230, 25, 95, 4, 179, 89, 20, 9, 34, 99, - 4, 230, 25, 95, 4, 221, 186, 89, 20, 9, 34, 99, 4, 230, 25, 95, 4, 92, - 89, 20, 9, 34, 99, 4, 230, 25, 95, 4, 229, 179, 89, 20, 9, 34, 248, 196, - 4, 222, 235, 89, 20, 9, 34, 248, 196, 4, 179, 89, 20, 9, 34, 248, 196, 4, - 221, 186, 89, 20, 9, 34, 248, 196, 4, 92, 89, 20, 9, 34, 248, 196, 4, - 229, 179, 89, 20, 9, 34, 199, 110, 4, 222, 235, 89, 20, 9, 34, 199, 110, - 4, 179, 89, 20, 9, 34, 199, 110, 4, 221, 186, 89, 20, 9, 34, 199, 110, 4, - 92, 89, 20, 9, 34, 199, 110, 4, 229, 179, 89, 20, 9, 34, 199, 25, 4, 92, - 89, 20, 9, 34, 222, 235, 4, 179, 89, 20, 9, 34, 222, 235, 4, 92, 89, 20, - 9, 34, 179, 4, 222, 235, 89, 20, 9, 34, 179, 4, 92, 89, 20, 9, 34, 221, - 186, 4, 222, 235, 89, 20, 9, 34, 221, 186, 4, 92, 89, 20, 9, 34, 205, 42, - 4, 222, 235, 89, 20, 9, 34, 205, 42, 4, 179, 89, 20, 9, 34, 205, 42, 4, - 221, 186, 89, 20, 9, 34, 205, 42, 4, 92, 89, 20, 9, 34, 205, 188, 4, 179, - 89, 20, 9, 34, 205, 188, 4, 221, 186, 89, 20, 9, 34, 205, 188, 4, 92, 89, - 20, 9, 34, 237, 236, 4, 222, 235, 89, 20, 9, 34, 237, 236, 4, 179, 89, - 20, 9, 34, 237, 236, 4, 221, 186, 89, 20, 9, 34, 237, 236, 4, 92, 89, 20, - 9, 34, 199, 215, 4, 179, 89, 20, 9, 34, 191, 117, 4, 92, 89, 20, 9, 34, - 251, 179, 4, 222, 235, 89, 20, 9, 34, 251, 179, 4, 92, 89, 20, 9, 34, - 231, 50, 4, 222, 235, 89, 20, 9, 34, 231, 50, 4, 92, 89, 20, 9, 34, 233, - 6, 4, 222, 235, 89, 20, 9, 34, 233, 6, 4, 179, 89, 20, 9, 34, 233, 6, 4, - 221, 186, 89, 20, 9, 34, 233, 6, 4, 92, 89, 20, 9, 34, 208, 83, 4, 179, - 89, 20, 9, 34, 208, 83, 4, 92, 89, 20, 9, 34, 222, 80, 4, 222, 235, 89, - 20, 9, 34, 222, 80, 4, 179, 89, 20, 9, 34, 222, 80, 4, 221, 186, 89, 20, - 9, 34, 222, 80, 4, 220, 12, 89, 20, 9, 34, 222, 80, 4, 92, 89, 20, 9, 34, - 220, 12, 4, 222, 235, 89, 20, 9, 34, 220, 12, 4, 179, 89, 20, 9, 34, 220, - 12, 4, 221, 186, 89, 20, 9, 34, 220, 12, 4, 92, 89, 20, 9, 34, 220, 12, - 4, 229, 179, 89, 20, 9, 34, 92, 4, 222, 235, 89, 20, 9, 34, 92, 4, 179, - 89, 20, 9, 34, 92, 4, 221, 186, 89, 20, 9, 34, 92, 4, 92, 89, 20, 9, 34, - 213, 12, 4, 222, 235, 89, 20, 9, 34, 213, 12, 4, 179, 89, 20, 9, 34, 213, - 12, 4, 221, 186, 89, 20, 9, 34, 213, 12, 4, 92, 89, 20, 9, 34, 213, 12, - 4, 229, 179, 89, 20, 9, 34, 229, 179, 4, 222, 235, 89, 20, 9, 34, 229, - 179, 4, 92, 89, 20, 9, 34, 229, 179, 4, 200, 177, 130, 89, 20, 9, 34, 99, - 4, 222, 235, 89, 20, 9, 34, 99, 4, 179, 89, 20, 9, 34, 99, 4, 221, 186, - 89, 20, 9, 34, 99, 4, 92, 89, 20, 9, 34, 99, 4, 229, 179, 89, 20, 9, 34, - 99, 4, 230, 25, 95, 4, 92, 216, 198, 20, 9, 34, 99, 4, 230, 25, 95, 4, - 229, 179, 216, 198, 20, 9, 34, 248, 196, 4, 92, 216, 198, 20, 9, 34, 248, - 196, 4, 229, 179, 216, 198, 20, 9, 34, 199, 110, 4, 92, 216, 198, 20, 9, - 34, 199, 110, 4, 229, 179, 216, 198, 20, 9, 34, 199, 25, 4, 92, 216, 198, - 20, 9, 34, 199, 25, 4, 229, 179, 216, 198, 20, 9, 34, 205, 42, 4, 92, - 216, 198, 20, 9, 34, 205, 42, 4, 229, 179, 216, 198, 20, 9, 34, 203, 105, - 4, 92, 216, 198, 20, 9, 34, 203, 105, 4, 229, 179, 216, 198, 20, 9, 34, - 222, 80, 4, 220, 12, 216, 198, 20, 9, 34, 222, 80, 4, 92, 216, 198, 20, - 9, 34, 220, 12, 4, 92, 216, 198, 20, 9, 34, 213, 12, 4, 92, 216, 198, 20, - 9, 34, 213, 12, 4, 229, 179, 216, 198, 20, 9, 34, 99, 4, 92, 216, 198, - 20, 9, 34, 99, 4, 229, 179, 216, 198, 20, 9, 34, 203, 151, 4, 233, 30, - 216, 198, 20, 9, 34, 203, 151, 4, 237, 201, 216, 198, 20, 9, 34, 203, - 151, 4, 222, 27, 216, 198, 20, 9, 34, 199, 215, 4, 130, 217, 80, 76, 20, - 9, 34, 199, 215, 4, 99, 76, 20, 9, 34, 251, 179, 4, 130, 217, 80, 76, 20, - 9, 34, 251, 179, 4, 99, 76, 20, 9, 34, 231, 50, 4, 130, 217, 80, 76, 20, - 9, 34, 231, 50, 4, 99, 76, 20, 9, 34, 205, 42, 4, 130, 217, 80, 76, 20, - 9, 34, 205, 42, 4, 99, 76, 20, 9, 34, 203, 105, 4, 130, 217, 80, 76, 20, - 9, 34, 203, 105, 4, 99, 76, 20, 9, 34, 179, 4, 130, 217, 80, 76, 20, 9, - 34, 179, 4, 99, 76, 20, 9, 34, 222, 235, 4, 130, 217, 80, 76, 20, 9, 34, - 222, 235, 4, 99, 76, 20, 9, 34, 221, 186, 4, 130, 217, 80, 76, 20, 9, 34, - 221, 186, 4, 99, 76, 20, 9, 34, 205, 188, 4, 130, 217, 80, 76, 20, 9, 34, - 205, 188, 4, 99, 76, 20, 9, 34, 237, 236, 4, 130, 217, 80, 76, 20, 9, 34, - 237, 236, 4, 99, 76, 20, 9, 34, 203, 105, 4, 222, 235, 76, 20, 9, 34, - 203, 105, 4, 179, 76, 20, 9, 34, 203, 105, 4, 221, 186, 76, 20, 9, 34, - 203, 105, 4, 92, 76, 20, 9, 34, 203, 105, 4, 207, 67, 76, 20, 9, 34, 205, - 42, 4, 207, 67, 76, 20, 9, 34, 205, 188, 4, 207, 67, 76, 20, 9, 34, 237, - 236, 4, 207, 67, 76, 20, 9, 34, 199, 215, 4, 130, 217, 80, 52, 20, 9, 34, - 199, 215, 4, 99, 52, 20, 9, 34, 251, 179, 4, 130, 217, 80, 52, 20, 9, 34, - 251, 179, 4, 99, 52, 20, 9, 34, 231, 50, 4, 130, 217, 80, 52, 20, 9, 34, - 231, 50, 4, 99, 52, 20, 9, 34, 205, 42, 4, 130, 217, 80, 52, 20, 9, 34, - 205, 42, 4, 99, 52, 20, 9, 34, 203, 105, 4, 130, 217, 80, 52, 20, 9, 34, - 203, 105, 4, 99, 52, 20, 9, 34, 179, 4, 130, 217, 80, 52, 20, 9, 34, 179, - 4, 99, 52, 20, 9, 34, 222, 235, 4, 130, 217, 80, 52, 20, 9, 34, 222, 235, - 4, 99, 52, 20, 9, 34, 221, 186, 4, 130, 217, 80, 52, 20, 9, 34, 221, 186, - 4, 99, 52, 20, 9, 34, 205, 188, 4, 130, 217, 80, 52, 20, 9, 34, 205, 188, - 4, 99, 52, 20, 9, 34, 237, 236, 4, 130, 217, 80, 52, 20, 9, 34, 237, 236, - 4, 99, 52, 20, 9, 34, 203, 105, 4, 222, 235, 52, 20, 9, 34, 203, 105, 4, - 179, 52, 20, 9, 34, 203, 105, 4, 221, 186, 52, 20, 9, 34, 203, 105, 4, - 92, 52, 20, 9, 34, 203, 105, 4, 207, 67, 52, 20, 9, 34, 205, 42, 4, 207, - 67, 52, 20, 9, 34, 205, 188, 4, 207, 67, 52, 20, 9, 34, 237, 236, 4, 207, - 67, 52, 20, 9, 34, 203, 105, 4, 222, 235, 89, 20, 9, 34, 203, 105, 4, - 179, 89, 20, 9, 34, 203, 105, 4, 221, 186, 89, 20, 9, 34, 203, 105, 4, - 92, 89, 20, 9, 34, 205, 42, 4, 229, 179, 89, 20, 9, 34, 203, 105, 4, 229, - 179, 89, 20, 9, 34, 199, 215, 4, 92, 89, 20, 9, 34, 205, 42, 4, 222, 235, - 216, 198, 20, 9, 34, 205, 42, 4, 179, 216, 198, 20, 9, 34, 205, 42, 4, - 221, 186, 216, 198, 20, 9, 34, 203, 105, 4, 222, 235, 216, 198, 20, 9, - 34, 203, 105, 4, 179, 216, 198, 20, 9, 34, 203, 105, 4, 221, 186, 216, - 198, 20, 9, 34, 199, 215, 4, 92, 216, 198, 20, 9, 34, 191, 117, 4, 92, - 216, 198, 20, 9, 34, 130, 4, 233, 28, 52, 20, 9, 34, 130, 4, 233, 28, 76, - 20, 211, 30, 45, 210, 103, 211, 30, 50, 210, 103, 9, 34, 207, 154, 251, - 122, 9, 34, 207, 162, 251, 121, 251, 56, 9, 34, 207, 162, 251, 121, 251, - 55, 9, 34, 207, 162, 251, 121, 251, 53, 9, 34, 207, 162, 251, 121, 251, - 52, 9, 34, 207, 162, 251, 121, 251, 51, 9, 34, 205, 157, 251, 146, 193, - 181, 9, 34, 251, 146, 250, 167, 9, 34, 251, 145, 250, 167, 9, 34, 251, - 144, 250, 167, 9, 34, 251, 146, 250, 166, 193, 152, 9, 34, 208, 12, 202, - 135, 9, 34, 205, 155, 251, 146, 193, 177, 193, 180, 9, 34, 251, 149, 250, - 167, 9, 34, 199, 230, 193, 179, 9, 34, 207, 153, 251, 122, 9, 34, 199, - 110, 4, 222, 235, 4, 92, 89, 20, 9, 34, 199, 110, 4, 179, 4, 222, 235, - 52, 20, 9, 34, 199, 110, 4, 179, 4, 222, 235, 89, 20, 9, 34, 199, 110, 4, - 179, 4, 92, 89, 20, 9, 34, 199, 110, 4, 221, 186, 4, 92, 89, 20, 9, 34, - 199, 110, 4, 92, 4, 222, 235, 89, 20, 9, 34, 199, 110, 4, 92, 4, 179, 89, - 20, 9, 34, 199, 110, 4, 92, 4, 221, 186, 89, 20, 9, 34, 222, 235, 4, 92, - 4, 179, 52, 20, 9, 34, 222, 235, 4, 92, 4, 179, 89, 20, 9, 34, 179, 4, - 92, 4, 99, 52, 20, 9, 34, 179, 4, 92, 4, 130, 217, 80, 52, 20, 9, 34, - 205, 42, 4, 179, 4, 222, 235, 89, 20, 9, 34, 205, 42, 4, 222, 235, 4, - 179, 89, 20, 9, 34, 205, 42, 4, 222, 235, 4, 130, 217, 80, 52, 20, 9, 34, - 205, 42, 4, 92, 4, 179, 52, 20, 9, 34, 205, 42, 4, 92, 4, 179, 89, 20, 9, - 34, 205, 42, 4, 92, 4, 222, 235, 89, 20, 9, 34, 205, 42, 4, 92, 4, 92, - 52, 20, 9, 34, 205, 42, 4, 92, 4, 92, 89, 20, 9, 34, 205, 188, 4, 179, 4, - 179, 52, 20, 9, 34, 205, 188, 4, 179, 4, 179, 89, 20, 9, 34, 205, 188, 4, - 92, 4, 92, 52, 20, 9, 34, 203, 105, 4, 179, 4, 92, 52, 20, 9, 34, 203, - 105, 4, 179, 4, 92, 89, 20, 9, 34, 203, 105, 4, 222, 235, 4, 99, 52, 20, - 9, 34, 203, 105, 4, 92, 4, 221, 186, 52, 20, 9, 34, 203, 105, 4, 92, 4, - 221, 186, 89, 20, 9, 34, 203, 105, 4, 92, 4, 92, 52, 20, 9, 34, 203, 105, - 4, 92, 4, 92, 89, 20, 9, 34, 237, 236, 4, 179, 4, 130, 217, 80, 52, 20, - 9, 34, 237, 236, 4, 221, 186, 4, 92, 52, 20, 9, 34, 237, 236, 4, 221, - 186, 4, 92, 89, 20, 9, 34, 199, 215, 4, 92, 4, 179, 52, 20, 9, 34, 199, - 215, 4, 92, 4, 179, 89, 20, 9, 34, 199, 215, 4, 92, 4, 92, 89, 20, 9, 34, - 199, 215, 4, 92, 4, 99, 52, 20, 9, 34, 251, 179, 4, 222, 235, 4, 92, 52, - 20, 9, 34, 251, 179, 4, 92, 4, 92, 52, 20, 9, 34, 251, 179, 4, 92, 4, 92, - 89, 20, 9, 34, 251, 179, 4, 92, 4, 130, 217, 80, 52, 20, 9, 34, 231, 50, - 4, 92, 4, 92, 52, 20, 9, 34, 231, 50, 4, 92, 4, 99, 52, 20, 9, 34, 231, - 50, 4, 92, 4, 130, 217, 80, 52, 20, 9, 34, 233, 6, 4, 221, 186, 4, 92, - 52, 20, 9, 34, 233, 6, 4, 221, 186, 4, 92, 89, 20, 9, 34, 208, 83, 4, 92, - 4, 179, 52, 20, 9, 34, 208, 83, 4, 92, 4, 92, 52, 20, 9, 34, 220, 12, 4, - 179, 4, 92, 52, 20, 9, 34, 220, 12, 4, 179, 4, 99, 52, 20, 9, 34, 220, - 12, 4, 179, 4, 130, 217, 80, 52, 20, 9, 34, 220, 12, 4, 222, 235, 4, 222, - 235, 89, 20, 9, 34, 220, 12, 4, 222, 235, 4, 222, 235, 52, 20, 9, 34, - 220, 12, 4, 221, 186, 4, 92, 52, 20, 9, 34, 220, 12, 4, 221, 186, 4, 92, - 89, 20, 9, 34, 220, 12, 4, 92, 4, 179, 52, 20, 9, 34, 220, 12, 4, 92, 4, - 179, 89, 20, 9, 34, 92, 4, 179, 4, 222, 235, 89, 20, 9, 34, 92, 4, 179, - 4, 92, 89, 20, 9, 34, 92, 4, 179, 4, 99, 52, 20, 9, 34, 92, 4, 222, 235, - 4, 179, 89, 20, 9, 34, 92, 4, 222, 235, 4, 92, 89, 20, 9, 34, 92, 4, 221, - 186, 4, 222, 235, 89, 20, 9, 34, 92, 4, 221, 186, 4, 92, 89, 20, 9, 34, - 92, 4, 222, 235, 4, 221, 186, 89, 20, 9, 34, 229, 179, 4, 92, 4, 222, - 235, 89, 20, 9, 34, 229, 179, 4, 92, 4, 92, 89, 20, 9, 34, 213, 12, 4, - 179, 4, 92, 89, 20, 9, 34, 213, 12, 4, 179, 4, 130, 217, 80, 52, 20, 9, - 34, 213, 12, 4, 222, 235, 4, 92, 52, 20, 9, 34, 213, 12, 4, 222, 235, 4, - 92, 89, 20, 9, 34, 213, 12, 4, 222, 235, 4, 130, 217, 80, 52, 20, 9, 34, - 213, 12, 4, 92, 4, 99, 52, 20, 9, 34, 213, 12, 4, 92, 4, 130, 217, 80, - 52, 20, 9, 34, 99, 4, 92, 4, 92, 52, 20, 9, 34, 99, 4, 92, 4, 92, 89, 20, - 9, 34, 248, 196, 4, 221, 186, 4, 99, 52, 20, 9, 34, 199, 110, 4, 222, - 235, 4, 99, 52, 20, 9, 34, 199, 110, 4, 222, 235, 4, 130, 217, 80, 52, - 20, 9, 34, 199, 110, 4, 221, 186, 4, 99, 52, 20, 9, 34, 199, 110, 4, 221, - 186, 4, 130, 217, 80, 52, 20, 9, 34, 199, 110, 4, 92, 4, 99, 52, 20, 9, - 34, 199, 110, 4, 92, 4, 130, 217, 80, 52, 20, 9, 34, 222, 235, 4, 92, 4, - 99, 52, 20, 9, 34, 222, 235, 4, 179, 4, 130, 217, 80, 52, 20, 9, 34, 222, - 235, 4, 92, 4, 130, 217, 80, 52, 20, 9, 34, 205, 42, 4, 221, 186, 4, 130, - 217, 80, 52, 20, 9, 34, 205, 188, 4, 179, 4, 99, 52, 20, 9, 34, 203, 105, - 4, 179, 4, 99, 52, 20, 9, 34, 237, 236, 4, 179, 4, 99, 52, 20, 9, 34, - 220, 12, 4, 222, 235, 4, 99, 52, 20, 9, 34, 220, 12, 4, 92, 4, 99, 52, - 20, 9, 34, 99, 4, 179, 4, 99, 52, 20, 9, 34, 99, 4, 222, 235, 4, 99, 52, - 20, 9, 34, 99, 4, 92, 4, 99, 52, 20, 9, 34, 92, 4, 92, 4, 99, 52, 20, 9, - 34, 208, 83, 4, 92, 4, 99, 52, 20, 9, 34, 213, 12, 4, 179, 4, 99, 52, 20, - 9, 34, 208, 83, 4, 92, 4, 179, 89, 20, 9, 34, 220, 12, 4, 179, 4, 92, 89, - 20, 9, 34, 251, 179, 4, 92, 4, 99, 52, 20, 9, 34, 222, 80, 4, 92, 4, 99, - 52, 20, 9, 34, 213, 12, 4, 222, 235, 4, 179, 89, 20, 9, 34, 92, 4, 221, - 186, 4, 99, 52, 20, 9, 34, 220, 12, 4, 222, 235, 4, 92, 89, 20, 9, 34, - 222, 80, 4, 92, 4, 92, 52, 20, 9, 34, 220, 12, 4, 222, 235, 4, 92, 52, - 20, 9, 34, 213, 12, 4, 222, 235, 4, 179, 52, 20, 9, 34, 222, 235, 4, 179, - 4, 99, 52, 20, 9, 34, 179, 4, 222, 235, 4, 99, 52, 20, 9, 34, 92, 4, 222, - 235, 4, 99, 52, 20, 9, 34, 233, 6, 4, 92, 4, 99, 52, 20, 9, 34, 248, 196, - 4, 179, 4, 99, 52, 20, 9, 34, 222, 80, 4, 92, 4, 92, 89, 20, 9, 34, 251, - 179, 4, 222, 235, 4, 92, 89, 20, 9, 34, 205, 188, 4, 92, 4, 92, 89, 20, - 9, 34, 205, 42, 4, 221, 186, 4, 99, 52, 20, 9, 34, 213, 12, 4, 222, 235, - 4, 99, 52, 20, 9, 34, 205, 161, 251, 143, 9, 34, 205, 158, 196, 36, 250, - 170, 221, 9, 201, 59, 3, 76, 20, 9, 34, 208, 79, 196, 36, 250, 170, 221, - 9, 201, 59, 3, 76, 20, 9, 34, 251, 120, 76, 20, 9, 34, 251, 162, 76, 20, - 9, 34, 215, 218, 76, 20, 9, 34, 205, 159, 76, 20, 9, 34, 207, 127, 76, - 20, 9, 34, 251, 148, 76, 20, 9, 34, 193, 151, 76, 20, 9, 34, 205, 158, - 76, 20, 9, 34, 205, 156, 251, 148, 193, 150, 9, 34, 222, 250, 206, 244, - 57, 9, 34, 248, 103, 250, 237, 250, 238, 9, 34, 200, 237, 193, 188, 199, - 239, 9, 34, 250, 71, 193, 188, 222, 251, 66, 205, 28, 66, 204, 173, 66, - 204, 105, 66, 204, 94, 66, 204, 83, 66, 204, 72, 66, 204, 61, 66, 204, - 50, 66, 204, 39, 66, 205, 27, 66, 205, 16, 66, 205, 5, 66, 204, 250, 66, - 204, 239, 66, 204, 228, 66, 204, 217, 208, 214, 232, 107, 39, 81, 242, - 26, 208, 214, 232, 107, 39, 81, 154, 242, 26, 208, 214, 232, 107, 39, 81, - 154, 232, 42, 201, 58, 208, 214, 232, 107, 39, 81, 242, 35, 208, 214, - 232, 107, 39, 81, 204, 20, 208, 214, 232, 107, 39, 81, 233, 175, 77, 208, - 214, 232, 107, 39, 81, 208, 8, 77, 208, 214, 232, 107, 39, 81, 45, 64, - 219, 163, 248, 5, 208, 214, 232, 107, 39, 81, 50, 64, 219, 163, 248, 1, - 208, 214, 232, 107, 39, 81, 228, 209, 234, 78, 33, 34, 45, 230, 37, 33, - 34, 50, 230, 37, 33, 54, 198, 148, 45, 230, 37, 33, 54, 198, 148, 50, - 230, 37, 33, 217, 126, 45, 230, 37, 33, 217, 126, 50, 230, 37, 33, 238, - 253, 217, 125, 33, 34, 45, 134, 60, 33, 34, 50, 134, 60, 33, 198, 148, - 45, 134, 60, 33, 198, 148, 50, 134, 60, 33, 217, 126, 45, 134, 60, 33, - 217, 126, 50, 134, 60, 33, 238, 253, 217, 126, 60, 33, 42, 198, 118, 45, - 230, 37, 33, 42, 198, 118, 50, 230, 37, 208, 214, 232, 107, 39, 81, 103, - 75, 219, 212, 208, 214, 232, 107, 39, 81, 234, 73, 237, 170, 208, 214, - 232, 107, 39, 81, 234, 62, 237, 170, 208, 214, 232, 107, 39, 81, 131, - 219, 88, 208, 214, 232, 107, 39, 81, 193, 133, 131, 219, 88, 208, 214, - 232, 107, 39, 81, 45, 210, 103, 208, 214, 232, 107, 39, 81, 50, 210, 103, - 208, 214, 232, 107, 39, 81, 45, 238, 124, 248, 5, 208, 214, 232, 107, 39, - 81, 50, 238, 124, 248, 5, 208, 214, 232, 107, 39, 81, 45, 198, 37, 203, - 98, 248, 5, 208, 214, 232, 107, 39, 81, 50, 198, 37, 203, 98, 248, 5, - 208, 214, 232, 107, 39, 81, 45, 62, 219, 163, 248, 5, 208, 214, 232, 107, - 39, 81, 50, 62, 219, 163, 248, 5, 208, 214, 232, 107, 39, 81, 45, 54, - 251, 65, 248, 5, 208, 214, 232, 107, 39, 81, 50, 54, 251, 65, 248, 5, - 208, 214, 232, 107, 39, 81, 45, 251, 65, 248, 5, 208, 214, 232, 107, 39, - 81, 50, 251, 65, 248, 5, 208, 214, 232, 107, 39, 81, 45, 238, 211, 248, - 5, 208, 214, 232, 107, 39, 81, 50, 238, 211, 248, 5, 208, 214, 232, 107, - 39, 81, 45, 64, 238, 211, 248, 5, 208, 214, 232, 107, 39, 81, 50, 64, - 238, 211, 248, 5, 203, 251, 236, 96, 64, 203, 251, 236, 96, 208, 214, - 232, 107, 39, 81, 45, 51, 248, 5, 208, 214, 232, 107, 39, 81, 50, 51, - 248, 5, 237, 169, 210, 244, 246, 226, 210, 244, 193, 133, 210, 244, 54, - 193, 133, 210, 244, 237, 169, 131, 219, 88, 246, 226, 131, 219, 88, 193, - 133, 131, 219, 88, 2, 242, 26, 2, 154, 242, 26, 2, 232, 42, 201, 58, 2, - 204, 20, 2, 242, 35, 2, 208, 8, 77, 2, 233, 175, 77, 2, 234, 73, 237, - 170, 2, 45, 210, 103, 2, 50, 210, 103, 2, 45, 238, 124, 248, 5, 2, 50, - 238, 124, 248, 5, 2, 45, 198, 37, 203, 98, 248, 5, 2, 50, 198, 37, 203, - 98, 248, 5, 2, 31, 57, 2, 251, 86, 2, 250, 143, 2, 107, 57, 2, 228, 57, - 2, 219, 156, 57, 2, 230, 170, 57, 2, 234, 1, 57, 2, 207, 14, 202, 18, 2, - 236, 110, 57, 2, 210, 4, 57, 2, 242, 24, 250, 132, 9, 233, 28, 76, 20, 9, - 199, 164, 4, 233, 28, 56, 9, 237, 199, 76, 20, 9, 199, 211, 232, 79, 9, - 222, 25, 76, 20, 9, 233, 30, 76, 20, 9, 233, 30, 216, 198, 20, 9, 237, - 201, 76, 20, 9, 237, 201, 216, 198, 20, 9, 222, 27, 76, 20, 9, 222, 27, - 216, 198, 20, 9, 203, 151, 76, 20, 9, 203, 151, 216, 198, 20, 9, 200, - 202, 76, 20, 9, 200, 202, 216, 198, 20, 9, 1, 230, 25, 76, 20, 9, 1, 130, - 4, 217, 121, 95, 76, 20, 9, 1, 130, 4, 217, 121, 95, 52, 20, 9, 1, 130, - 4, 230, 25, 95, 76, 20, 9, 1, 130, 4, 230, 25, 95, 52, 20, 9, 1, 193, - 132, 4, 230, 25, 95, 76, 20, 9, 1, 193, 132, 4, 230, 25, 95, 52, 20, 9, - 1, 130, 4, 230, 25, 248, 183, 76, 20, 9, 1, 130, 4, 230, 25, 248, 183, - 52, 20, 9, 1, 99, 4, 230, 25, 95, 76, 20, 9, 1, 99, 4, 230, 25, 95, 52, - 20, 9, 1, 99, 4, 230, 25, 95, 89, 20, 9, 1, 99, 4, 230, 25, 95, 216, 198, - 20, 9, 1, 130, 76, 20, 9, 1, 130, 52, 20, 9, 1, 248, 196, 76, 20, 9, 1, - 248, 196, 52, 20, 9, 1, 248, 196, 89, 20, 9, 1, 248, 196, 216, 198, 20, - 9, 1, 199, 110, 217, 44, 76, 20, 9, 1, 199, 110, 217, 44, 52, 20, 9, 1, - 199, 110, 76, 20, 9, 1, 199, 110, 52, 20, 9, 1, 199, 110, 89, 20, 9, 1, - 199, 110, 216, 198, 20, 9, 1, 199, 25, 76, 20, 9, 1, 199, 25, 52, 20, 9, - 1, 199, 25, 89, 20, 9, 1, 199, 25, 216, 198, 20, 9, 1, 222, 235, 76, 20, - 9, 1, 222, 235, 52, 20, 9, 1, 222, 235, 89, 20, 9, 1, 222, 235, 216, 198, - 20, 9, 1, 179, 76, 20, 9, 1, 179, 52, 20, 9, 1, 179, 89, 20, 9, 1, 179, - 216, 198, 20, 9, 1, 221, 186, 76, 20, 9, 1, 221, 186, 52, 20, 9, 1, 221, - 186, 89, 20, 9, 1, 221, 186, 216, 198, 20, 9, 1, 237, 213, 76, 20, 9, 1, - 237, 213, 52, 20, 9, 1, 199, 37, 76, 20, 9, 1, 199, 37, 52, 20, 9, 1, - 207, 67, 76, 20, 9, 1, 207, 67, 52, 20, 9, 1, 191, 114, 76, 20, 9, 1, - 191, 114, 52, 20, 9, 1, 205, 42, 76, 20, 9, 1, 205, 42, 52, 20, 9, 1, - 205, 42, 89, 20, 9, 1, 205, 42, 216, 198, 20, 9, 1, 203, 105, 76, 20, 9, - 1, 203, 105, 52, 20, 9, 1, 203, 105, 89, 20, 9, 1, 203, 105, 216, 198, - 20, 9, 1, 205, 188, 76, 20, 9, 1, 205, 188, 52, 20, 9, 1, 205, 188, 89, - 20, 9, 1, 205, 188, 216, 198, 20, 9, 1, 237, 236, 76, 20, 9, 1, 237, 236, - 52, 20, 9, 1, 237, 236, 89, 20, 9, 1, 237, 236, 216, 198, 20, 9, 1, 199, - 215, 76, 20, 9, 1, 199, 215, 52, 20, 9, 1, 199, 215, 89, 20, 9, 1, 199, - 215, 216, 198, 20, 9, 1, 191, 117, 76, 20, 9, 1, 191, 117, 52, 20, 9, 1, - 191, 117, 89, 20, 9, 1, 191, 117, 216, 198, 20, 9, 1, 251, 179, 76, 20, - 9, 1, 251, 179, 52, 20, 9, 1, 251, 179, 89, 20, 9, 1, 251, 179, 216, 198, - 20, 9, 1, 231, 50, 76, 20, 9, 1, 231, 50, 52, 20, 9, 1, 231, 50, 89, 20, - 9, 1, 231, 50, 216, 198, 20, 9, 1, 233, 6, 76, 20, 9, 1, 233, 6, 52, 20, - 9, 1, 233, 6, 89, 20, 9, 1, 233, 6, 216, 198, 20, 9, 1, 208, 83, 76, 20, - 9, 1, 208, 83, 52, 20, 9, 1, 208, 83, 89, 20, 9, 1, 208, 83, 216, 198, - 20, 9, 1, 222, 80, 76, 20, 9, 1, 222, 80, 52, 20, 9, 1, 222, 80, 89, 20, - 9, 1, 222, 80, 216, 198, 20, 9, 1, 220, 12, 76, 20, 9, 1, 220, 12, 52, - 20, 9, 1, 220, 12, 89, 20, 9, 1, 220, 12, 216, 198, 20, 9, 1, 92, 76, 20, - 9, 1, 92, 52, 20, 9, 1, 92, 89, 20, 9, 1, 92, 216, 198, 20, 9, 1, 213, - 12, 76, 20, 9, 1, 213, 12, 52, 20, 9, 1, 213, 12, 89, 20, 9, 1, 213, 12, - 216, 198, 20, 9, 1, 229, 179, 76, 20, 9, 1, 229, 179, 52, 20, 9, 1, 229, - 179, 89, 20, 9, 1, 229, 179, 216, 198, 20, 9, 1, 193, 132, 76, 20, 9, 1, - 193, 132, 52, 20, 9, 1, 130, 217, 80, 76, 20, 9, 1, 130, 217, 80, 52, 20, - 9, 1, 99, 76, 20, 9, 1, 99, 52, 20, 9, 1, 99, 89, 20, 9, 1, 99, 216, 198, - 20, 9, 34, 220, 12, 4, 130, 4, 217, 121, 95, 76, 20, 9, 34, 220, 12, 4, - 130, 4, 217, 121, 95, 52, 20, 9, 34, 220, 12, 4, 130, 4, 230, 25, 95, 76, - 20, 9, 34, 220, 12, 4, 130, 4, 230, 25, 95, 52, 20, 9, 34, 220, 12, 4, - 130, 4, 230, 25, 248, 183, 76, 20, 9, 34, 220, 12, 4, 130, 4, 230, 25, - 248, 183, 52, 20, 9, 34, 220, 12, 4, 130, 76, 20, 9, 34, 220, 12, 4, 130, - 52, 20, 191, 78, 193, 73, 213, 24, 201, 242, 190, 190, 233, 175, 77, 190, - 190, 207, 247, 77, 190, 190, 31, 57, 190, 190, 236, 110, 57, 190, 190, - 210, 4, 57, 190, 190, 251, 86, 190, 190, 250, 255, 190, 190, 45, 210, - 103, 190, 190, 50, 210, 103, 190, 190, 250, 143, 190, 190, 107, 57, 190, - 190, 242, 26, 190, 190, 228, 57, 190, 190, 232, 42, 201, 58, 190, 190, - 202, 18, 190, 190, 17, 191, 77, 190, 190, 17, 108, 190, 190, 17, 109, - 190, 190, 17, 139, 190, 190, 17, 137, 190, 190, 17, 153, 190, 190, 17, - 173, 190, 190, 17, 181, 190, 190, 17, 176, 190, 190, 17, 184, 190, 190, - 242, 35, 190, 190, 204, 20, 190, 190, 219, 156, 57, 190, 190, 234, 1, 57, - 190, 190, 230, 170, 57, 190, 190, 208, 8, 77, 190, 190, 242, 24, 250, - 132, 190, 190, 8, 6, 1, 65, 190, 190, 8, 6, 1, 250, 70, 190, 190, 8, 6, - 1, 247, 145, 190, 190, 8, 6, 1, 238, 80, 190, 190, 8, 6, 1, 73, 190, 190, - 8, 6, 1, 233, 134, 190, 190, 8, 6, 1, 232, 14, 190, 190, 8, 6, 1, 230, - 83, 190, 190, 8, 6, 1, 70, 190, 190, 8, 6, 1, 223, 7, 190, 190, 8, 6, 1, - 222, 125, 190, 190, 8, 6, 1, 170, 190, 190, 8, 6, 1, 218, 147, 190, 190, - 8, 6, 1, 215, 47, 190, 190, 8, 6, 1, 74, 190, 190, 8, 6, 1, 210, 226, - 190, 190, 8, 6, 1, 208, 97, 190, 190, 8, 6, 1, 148, 190, 190, 8, 6, 1, - 206, 3, 190, 190, 8, 6, 1, 200, 39, 190, 190, 8, 6, 1, 69, 190, 190, 8, - 6, 1, 196, 8, 190, 190, 8, 6, 1, 193, 221, 190, 190, 8, 6, 1, 192, 235, - 190, 190, 8, 6, 1, 192, 159, 190, 190, 8, 6, 1, 191, 166, 190, 190, 45, - 51, 248, 5, 190, 190, 207, 14, 202, 18, 190, 190, 50, 51, 248, 5, 190, - 190, 242, 210, 252, 8, 190, 190, 131, 219, 88, 190, 190, 230, 177, 252, - 8, 190, 190, 8, 2, 1, 65, 190, 190, 8, 2, 1, 250, 70, 190, 190, 8, 2, 1, - 247, 145, 190, 190, 8, 2, 1, 238, 80, 190, 190, 8, 2, 1, 73, 190, 190, 8, - 2, 1, 233, 134, 190, 190, 8, 2, 1, 232, 14, 190, 190, 8, 2, 1, 230, 83, - 190, 190, 8, 2, 1, 70, 190, 190, 8, 2, 1, 223, 7, 190, 190, 8, 2, 1, 222, - 125, 190, 190, 8, 2, 1, 170, 190, 190, 8, 2, 1, 218, 147, 190, 190, 8, 2, - 1, 215, 47, 190, 190, 8, 2, 1, 74, 190, 190, 8, 2, 1, 210, 226, 190, 190, - 8, 2, 1, 208, 97, 190, 190, 8, 2, 1, 148, 190, 190, 8, 2, 1, 206, 3, 190, - 190, 8, 2, 1, 200, 39, 190, 190, 8, 2, 1, 69, 190, 190, 8, 2, 1, 196, 8, - 190, 190, 8, 2, 1, 193, 221, 190, 190, 8, 2, 1, 192, 235, 190, 190, 8, 2, - 1, 192, 159, 190, 190, 8, 2, 1, 191, 166, 190, 190, 45, 238, 124, 248, 5, - 190, 190, 81, 219, 88, 190, 190, 50, 238, 124, 248, 5, 190, 190, 198, - 147, 190, 190, 45, 64, 210, 103, 190, 190, 50, 64, 210, 103, 149, 154, - 232, 42, 201, 58, 149, 45, 238, 211, 248, 5, 149, 50, 238, 211, 248, 5, - 149, 154, 242, 26, 149, 71, 82, 236, 96, 149, 71, 1, 193, 48, 149, 71, 1, - 2, 65, 149, 71, 1, 2, 70, 149, 71, 1, 2, 69, 149, 71, 1, 2, 73, 149, 71, - 1, 2, 74, 149, 71, 1, 2, 169, 149, 71, 1, 2, 191, 225, 149, 71, 1, 2, - 192, 12, 149, 71, 1, 2, 197, 90, 149, 222, 22, 208, 184, 202, 0, 77, 149, - 71, 1, 65, 149, 71, 1, 70, 149, 71, 1, 69, 149, 71, 1, 73, 149, 71, 1, - 74, 149, 71, 1, 157, 149, 71, 1, 221, 142, 149, 71, 1, 220, 208, 149, 71, - 1, 221, 253, 149, 71, 1, 221, 43, 149, 71, 1, 189, 149, 71, 1, 202, 217, - 149, 71, 1, 200, 255, 149, 71, 1, 205, 63, 149, 71, 1, 202, 41, 149, 71, - 1, 199, 247, 149, 71, 1, 198, 188, 149, 71, 1, 197, 90, 149, 71, 1, 199, - 140, 149, 71, 1, 159, 149, 71, 1, 180, 149, 71, 1, 213, 205, 149, 71, 1, - 212, 165, 149, 71, 1, 214, 107, 149, 71, 1, 213, 30, 149, 71, 1, 144, - 149, 71, 1, 229, 126, 149, 71, 1, 228, 128, 149, 71, 1, 229, 213, 149, - 71, 1, 228, 247, 149, 71, 1, 172, 149, 71, 1, 216, 81, 149, 71, 1, 215, - 139, 149, 71, 1, 216, 213, 149, 71, 1, 215, 251, 149, 71, 1, 169, 149, - 71, 1, 191, 225, 149, 71, 1, 192, 12, 149, 71, 1, 166, 149, 71, 1, 206, - 252, 149, 71, 1, 206, 63, 149, 71, 1, 207, 108, 149, 71, 1, 206, 157, - 149, 71, 1, 193, 187, 149, 71, 1, 215, 47, 149, 71, 195, 17, 202, 0, 77, - 149, 71, 204, 25, 202, 0, 77, 149, 30, 232, 218, 149, 30, 1, 221, 89, - 149, 30, 1, 201, 162, 149, 30, 1, 221, 82, 149, 30, 1, 213, 190, 149, 30, - 1, 213, 188, 149, 30, 1, 213, 187, 149, 30, 1, 198, 163, 149, 30, 1, 201, - 151, 149, 30, 1, 206, 234, 149, 30, 1, 206, 229, 149, 30, 1, 206, 226, - 149, 30, 1, 206, 219, 149, 30, 1, 206, 214, 149, 30, 1, 206, 209, 149, - 30, 1, 206, 220, 149, 30, 1, 206, 232, 149, 30, 1, 216, 59, 149, 30, 1, - 209, 160, 149, 30, 1, 201, 159, 149, 30, 1, 209, 149, 149, 30, 1, 202, - 155, 149, 30, 1, 201, 156, 149, 30, 1, 223, 193, 149, 30, 1, 242, 232, - 149, 30, 1, 201, 166, 149, 30, 1, 243, 43, 149, 30, 1, 221, 164, 149, 30, - 1, 199, 2, 149, 30, 1, 209, 200, 149, 30, 1, 229, 110, 149, 30, 1, 65, - 149, 30, 1, 251, 229, 149, 30, 1, 169, 149, 30, 1, 192, 129, 149, 30, 1, - 234, 23, 149, 30, 1, 73, 149, 30, 1, 192, 67, 149, 30, 1, 192, 80, 149, - 30, 1, 74, 149, 30, 1, 193, 187, 149, 30, 1, 193, 173, 149, 30, 1, 211, - 139, 149, 30, 1, 192, 12, 149, 30, 1, 69, 149, 30, 1, 193, 105, 149, 30, - 1, 193, 123, 149, 30, 1, 193, 84, 149, 30, 1, 191, 225, 149, 30, 1, 233, - 201, 149, 30, 1, 192, 33, 149, 30, 1, 70, 190, 190, 246, 232, 57, 190, - 190, 209, 1, 57, 190, 190, 212, 255, 57, 190, 190, 217, 125, 190, 190, - 247, 230, 164, 190, 190, 192, 71, 57, 190, 190, 193, 31, 57, 149, 232, - 102, 155, 195, 132, 149, 117, 55, 149, 196, 62, 55, 149, 96, 55, 149, - 235, 75, 55, 149, 62, 201, 185, 149, 64, 242, 218, 223, 78, 251, 45, 251, - 76, 223, 78, 251, 45, 204, 5, 223, 78, 251, 45, 199, 75, 211, 162, 207, - 38, 246, 191, 207, 38, 246, 191, 32, 78, 5, 250, 54, 65, 32, 78, 5, 250, - 23, 73, 32, 78, 5, 250, 32, 70, 32, 78, 5, 250, 0, 74, 32, 78, 5, 250, - 50, 69, 32, 78, 5, 250, 69, 237, 241, 32, 78, 5, 250, 16, 237, 101, 32, - 78, 5, 250, 56, 236, 255, 32, 78, 5, 250, 46, 236, 129, 32, 78, 5, 250, - 10, 235, 45, 32, 78, 5, 250, 4, 223, 4, 32, 78, 5, 250, 15, 222, 238, 32, - 78, 5, 250, 25, 222, 174, 32, 78, 5, 249, 252, 222, 155, 32, 78, 5, 249, - 240, 157, 32, 78, 5, 250, 17, 221, 253, 32, 78, 5, 249, 250, 221, 142, - 32, 78, 5, 249, 247, 221, 43, 32, 78, 5, 249, 236, 220, 208, 32, 78, 5, - 249, 237, 172, 32, 78, 5, 250, 47, 216, 213, 32, 78, 5, 249, 244, 216, - 81, 32, 78, 5, 250, 45, 215, 251, 32, 78, 5, 250, 37, 215, 139, 32, 78, - 5, 250, 58, 180, 32, 78, 5, 250, 36, 214, 107, 32, 78, 5, 250, 30, 213, - 205, 32, 78, 5, 250, 9, 213, 30, 32, 78, 5, 250, 6, 212, 165, 32, 78, 5, - 250, 65, 168, 32, 78, 5, 249, 245, 210, 53, 32, 78, 5, 250, 22, 209, 176, - 32, 78, 5, 250, 49, 209, 65, 32, 78, 5, 250, 11, 208, 158, 32, 78, 5, - 250, 44, 208, 89, 32, 78, 5, 249, 239, 208, 69, 32, 78, 5, 250, 39, 208, - 51, 32, 78, 5, 250, 28, 208, 39, 32, 78, 5, 250, 1, 166, 32, 78, 5, 250, - 33, 207, 108, 32, 78, 5, 250, 8, 206, 252, 32, 78, 5, 250, 67, 206, 157, - 32, 78, 5, 250, 34, 206, 63, 32, 78, 5, 250, 29, 189, 32, 78, 5, 250, 52, - 205, 63, 32, 78, 5, 250, 20, 202, 217, 32, 78, 5, 250, 48, 202, 41, 32, - 78, 5, 250, 3, 200, 255, 32, 78, 5, 250, 2, 199, 247, 32, 78, 5, 250, 63, - 199, 140, 32, 78, 5, 250, 24, 198, 188, 32, 78, 5, 250, 61, 159, 32, 78, - 5, 249, 248, 197, 90, 32, 78, 5, 250, 7, 193, 187, 32, 78, 5, 249, 242, - 193, 123, 32, 78, 5, 250, 21, 193, 84, 32, 78, 5, 250, 19, 193, 48, 32, - 78, 5, 250, 43, 191, 123, 32, 78, 5, 249, 243, 191, 87, 32, 78, 5, 250, - 40, 191, 7, 32, 78, 5, 250, 35, 254, 163, 32, 78, 5, 250, 18, 254, 51, - 32, 78, 5, 249, 233, 250, 113, 32, 78, 5, 249, 246, 235, 1, 32, 78, 5, - 249, 229, 235, 0, 32, 78, 5, 250, 13, 212, 97, 32, 78, 5, 250, 31, 208, - 156, 32, 78, 5, 249, 255, 208, 160, 32, 78, 5, 249, 241, 207, 175, 32, - 78, 5, 250, 27, 207, 174, 32, 78, 5, 249, 249, 206, 150, 32, 78, 5, 249, - 251, 199, 241, 32, 78, 5, 249, 231, 197, 37, 32, 78, 5, 249, 228, 109, - 32, 78, 16, 250, 42, 32, 78, 16, 250, 41, 32, 78, 16, 250, 38, 32, 78, - 16, 250, 26, 32, 78, 16, 250, 14, 32, 78, 16, 250, 12, 32, 78, 16, 250, - 5, 32, 78, 16, 249, 254, 32, 78, 16, 249, 253, 32, 78, 16, 249, 238, 32, - 78, 16, 249, 235, 32, 78, 16, 249, 234, 32, 78, 16, 249, 232, 32, 78, 16, - 249, 230, 32, 78, 156, 249, 227, 217, 70, 32, 78, 156, 249, 226, 193, 35, - 32, 78, 156, 249, 225, 237, 83, 32, 78, 156, 249, 224, 233, 254, 32, 78, - 156, 249, 223, 217, 37, 32, 78, 156, 249, 222, 201, 105, 32, 78, 156, - 249, 221, 233, 182, 32, 78, 156, 249, 220, 207, 137, 32, 78, 156, 249, - 219, 203, 107, 32, 78, 156, 249, 218, 229, 205, 32, 78, 156, 249, 217, - 201, 250, 32, 78, 156, 249, 216, 248, 61, 32, 78, 156, 249, 215, 238, - 192, 32, 78, 156, 249, 214, 247, 202, 32, 78, 156, 249, 213, 193, 93, 32, - 78, 156, 249, 212, 249, 34, 32, 78, 156, 249, 211, 211, 104, 32, 78, 156, - 249, 210, 201, 218, 32, 78, 156, 249, 209, 238, 89, 32, 78, 215, 204, - 249, 208, 222, 48, 32, 78, 215, 204, 249, 207, 222, 59, 32, 78, 156, 249, - 206, 211, 119, 32, 78, 156, 249, 205, 193, 60, 32, 78, 156, 249, 204, 32, - 78, 215, 204, 249, 203, 250, 213, 32, 78, 215, 204, 249, 202, 216, 159, - 32, 78, 156, 249, 201, 247, 229, 32, 78, 156, 249, 200, 230, 214, 32, 78, - 156, 249, 199, 32, 78, 156, 249, 198, 193, 26, 32, 78, 156, 249, 197, 32, - 78, 156, 249, 196, 32, 78, 156, 249, 195, 228, 156, 32, 78, 156, 249, - 194, 32, 78, 156, 249, 193, 32, 78, 156, 249, 192, 32, 78, 215, 204, 249, - 190, 197, 52, 32, 78, 156, 249, 189, 32, 78, 156, 249, 188, 32, 78, 156, - 249, 187, 242, 165, 32, 78, 156, 249, 186, 32, 78, 156, 249, 185, 32, 78, - 156, 249, 184, 231, 159, 32, 78, 156, 249, 183, 250, 198, 32, 78, 156, - 249, 182, 32, 78, 156, 249, 181, 32, 78, 156, 249, 180, 32, 78, 156, 249, - 179, 32, 78, 156, 249, 178, 32, 78, 156, 249, 177, 32, 78, 156, 249, 176, - 32, 78, 156, 249, 175, 32, 78, 156, 249, 174, 32, 78, 156, 249, 173, 215, - 196, 32, 78, 156, 249, 172, 32, 78, 156, 249, 171, 197, 250, 32, 78, 156, - 249, 170, 32, 78, 156, 249, 169, 32, 78, 156, 249, 168, 32, 78, 156, 249, - 167, 32, 78, 156, 249, 166, 32, 78, 156, 249, 165, 32, 78, 156, 249, 164, - 32, 78, 156, 249, 163, 32, 78, 156, 249, 162, 32, 78, 156, 249, 161, 32, - 78, 156, 249, 160, 32, 78, 156, 249, 159, 229, 168, 32, 78, 156, 249, - 138, 232, 116, 32, 78, 156, 249, 135, 249, 9, 32, 78, 156, 249, 130, 201, - 227, 32, 78, 156, 249, 129, 55, 32, 78, 156, 249, 128, 32, 78, 156, 249, - 127, 200, 127, 32, 78, 156, 249, 126, 32, 78, 156, 249, 125, 32, 78, 156, - 249, 124, 193, 88, 243, 90, 32, 78, 156, 249, 123, 243, 90, 32, 78, 156, - 249, 122, 243, 91, 232, 75, 32, 78, 156, 249, 121, 193, 91, 32, 78, 156, - 249, 120, 32, 78, 156, 249, 119, 32, 78, 215, 204, 249, 118, 236, 190, - 32, 78, 156, 249, 117, 32, 78, 156, 249, 116, 32, 78, 156, 249, 114, 32, - 78, 156, 249, 113, 32, 78, 156, 249, 112, 32, 78, 156, 249, 111, 237, - 173, 32, 78, 156, 249, 110, 32, 78, 156, 249, 109, 32, 78, 156, 249, 108, - 32, 78, 156, 249, 107, 32, 78, 156, 249, 106, 32, 78, 156, 195, 79, 249, - 191, 32, 78, 156, 195, 79, 249, 158, 32, 78, 156, 195, 79, 249, 157, 32, - 78, 156, 195, 79, 249, 156, 32, 78, 156, 195, 79, 249, 155, 32, 78, 156, - 195, 79, 249, 154, 32, 78, 156, 195, 79, 249, 153, 32, 78, 156, 195, 79, - 249, 152, 32, 78, 156, 195, 79, 249, 151, 32, 78, 156, 195, 79, 249, 150, - 32, 78, 156, 195, 79, 249, 149, 32, 78, 156, 195, 79, 249, 148, 32, 78, - 156, 195, 79, 249, 147, 32, 78, 156, 195, 79, 249, 146, 32, 78, 156, 195, - 79, 249, 145, 32, 78, 156, 195, 79, 249, 144, 32, 78, 156, 195, 79, 249, - 143, 32, 78, 156, 195, 79, 249, 142, 32, 78, 156, 195, 79, 249, 141, 32, - 78, 156, 195, 79, 249, 140, 32, 78, 156, 195, 79, 249, 139, 32, 78, 156, - 195, 79, 249, 137, 32, 78, 156, 195, 79, 249, 136, 32, 78, 156, 195, 79, - 249, 134, 32, 78, 156, 195, 79, 249, 133, 32, 78, 156, 195, 79, 249, 132, - 32, 78, 156, 195, 79, 249, 131, 32, 78, 156, 195, 79, 249, 115, 32, 78, - 156, 195, 79, 249, 105, 251, 222, 193, 23, 204, 6, 219, 88, 251, 222, - 193, 23, 204, 6, 236, 96, 251, 222, 243, 78, 77, 251, 222, 31, 108, 251, - 222, 31, 109, 251, 222, 31, 139, 251, 222, 31, 137, 251, 222, 31, 153, - 251, 222, 31, 173, 251, 222, 31, 181, 251, 222, 31, 176, 251, 222, 31, - 184, 251, 222, 31, 199, 90, 251, 222, 31, 197, 28, 251, 222, 31, 198, - 244, 251, 222, 31, 232, 97, 251, 222, 31, 232, 230, 251, 222, 31, 202, - 115, 251, 222, 31, 203, 236, 251, 222, 31, 234, 110, 251, 222, 31, 213, - 156, 251, 222, 31, 91, 228, 109, 251, 222, 31, 103, 228, 109, 251, 222, - 31, 115, 228, 109, 251, 222, 31, 232, 90, 228, 109, 251, 222, 31, 232, - 185, 228, 109, 251, 222, 31, 202, 131, 228, 109, 251, 222, 31, 203, 242, - 228, 109, 251, 222, 31, 234, 121, 228, 109, 251, 222, 31, 213, 161, 228, - 109, 251, 222, 31, 91, 188, 251, 222, 31, 103, 188, 251, 222, 31, 115, - 188, 251, 222, 31, 232, 90, 188, 251, 222, 31, 232, 185, 188, 251, 222, - 31, 202, 131, 188, 251, 222, 31, 203, 242, 188, 251, 222, 31, 234, 121, - 188, 251, 222, 31, 213, 161, 188, 251, 222, 31, 199, 91, 188, 251, 222, - 31, 197, 29, 188, 251, 222, 31, 198, 245, 188, 251, 222, 31, 232, 98, - 188, 251, 222, 31, 232, 231, 188, 251, 222, 31, 202, 116, 188, 251, 222, - 31, 203, 237, 188, 251, 222, 31, 234, 111, 188, 251, 222, 31, 213, 157, - 188, 251, 222, 193, 108, 249, 25, 196, 86, 251, 222, 193, 108, 232, 197, - 200, 219, 251, 222, 193, 108, 205, 52, 200, 219, 251, 222, 193, 108, 198, - 252, 200, 219, 251, 222, 193, 108, 232, 83, 200, 219, 251, 222, 235, 48, - 216, 209, 232, 197, 200, 219, 251, 222, 219, 69, 216, 209, 232, 197, 200, - 219, 251, 222, 216, 209, 205, 52, 200, 219, 251, 222, 216, 209, 198, 252, - 200, 219, 35, 251, 254, 250, 115, 91, 208, 17, 35, 251, 254, 250, 115, - 91, 230, 37, 35, 251, 254, 250, 115, 91, 235, 71, 35, 251, 254, 250, 115, - 153, 35, 251, 254, 250, 115, 232, 230, 35, 251, 254, 250, 115, 232, 185, - 228, 109, 35, 251, 254, 250, 115, 232, 185, 188, 35, 251, 254, 250, 115, - 232, 231, 188, 35, 251, 254, 250, 115, 232, 185, 199, 198, 35, 251, 254, - 250, 115, 199, 91, 199, 198, 35, 251, 254, 250, 115, 232, 231, 199, 198, - 35, 251, 254, 250, 115, 91, 228, 110, 199, 198, 35, 251, 254, 250, 115, - 232, 185, 228, 110, 199, 198, 35, 251, 254, 250, 115, 91, 198, 225, 199, - 198, 35, 251, 254, 250, 115, 232, 185, 198, 225, 199, 198, 35, 251, 254, - 250, 115, 232, 185, 201, 89, 35, 251, 254, 250, 115, 199, 91, 201, 89, - 35, 251, 254, 250, 115, 232, 231, 201, 89, 35, 251, 254, 250, 115, 91, - 228, 110, 201, 89, 35, 251, 254, 250, 115, 232, 185, 228, 110, 201, 89, - 35, 251, 254, 250, 115, 91, 198, 225, 201, 89, 35, 251, 254, 250, 115, - 199, 91, 198, 225, 201, 89, 35, 251, 254, 250, 115, 232, 231, 198, 225, - 201, 89, 35, 251, 254, 250, 115, 199, 91, 215, 254, 35, 251, 254, 229, - 162, 91, 209, 84, 35, 251, 254, 199, 12, 108, 35, 251, 254, 229, 158, - 108, 35, 251, 254, 234, 9, 109, 35, 251, 254, 199, 12, 109, 35, 251, 254, - 238, 85, 103, 235, 70, 35, 251, 254, 234, 9, 103, 235, 70, 35, 251, 254, - 197, 212, 153, 35, 251, 254, 197, 212, 199, 90, 35, 251, 254, 197, 212, - 199, 91, 251, 106, 20, 35, 251, 254, 229, 158, 199, 90, 35, 251, 254, - 216, 148, 199, 90, 35, 251, 254, 199, 12, 199, 90, 35, 251, 254, 199, 12, - 198, 244, 35, 251, 254, 197, 212, 232, 230, 35, 251, 254, 197, 212, 232, - 231, 251, 106, 20, 35, 251, 254, 229, 158, 232, 230, 35, 251, 254, 199, - 12, 232, 230, 35, 251, 254, 199, 12, 91, 228, 109, 35, 251, 254, 199, 12, - 115, 228, 109, 35, 251, 254, 234, 9, 232, 185, 228, 109, 35, 251, 254, - 197, 212, 232, 185, 228, 109, 35, 251, 254, 199, 12, 232, 185, 228, 109, - 35, 251, 254, 247, 34, 232, 185, 228, 109, 35, 251, 254, 214, 185, 232, - 185, 228, 109, 35, 251, 254, 199, 12, 91, 188, 35, 251, 254, 199, 12, - 232, 185, 188, 35, 251, 254, 237, 64, 232, 185, 215, 254, 35, 251, 254, - 201, 42, 232, 231, 215, 254, 35, 91, 134, 57, 35, 91, 134, 3, 251, 106, - 20, 35, 103, 198, 249, 57, 35, 115, 208, 16, 57, 35, 192, 78, 57, 35, - 199, 199, 57, 35, 235, 72, 57, 35, 211, 157, 57, 35, 103, 211, 156, 57, - 35, 115, 211, 156, 57, 35, 232, 90, 211, 156, 57, 35, 232, 185, 211, 156, - 57, 35, 216, 142, 57, 35, 220, 127, 249, 25, 57, 35, 219, 61, 57, 35, - 211, 6, 57, 35, 192, 211, 57, 35, 250, 176, 57, 35, 250, 193, 57, 35, - 230, 186, 57, 35, 197, 167, 249, 25, 57, 35, 191, 78, 57, 35, 91, 208, - 18, 57, 35, 202, 157, 57, 35, 223, 115, 57, 213, 19, 57, 206, 131, 203, - 232, 57, 206, 131, 196, 102, 57, 206, 131, 204, 12, 57, 206, 131, 203, - 170, 57, 206, 131, 236, 205, 203, 170, 57, 206, 131, 202, 181, 57, 206, - 131, 237, 59, 57, 206, 131, 208, 0, 57, 206, 131, 203, 249, 57, 206, 131, - 235, 23, 57, 206, 131, 250, 170, 57, 206, 131, 246, 225, 57, 250, 161, - 113, 35, 16, 199, 162, 206, 254, 209, 214, 236, 182, 3, 210, 42, 209, - 214, 236, 182, 3, 209, 76, 229, 203, 209, 214, 236, 182, 3, 199, 165, - 229, 203, 209, 214, 236, 182, 3, 247, 57, 209, 214, 236, 182, 3, 243, 38, - 209, 214, 236, 182, 3, 193, 35, 209, 214, 236, 182, 3, 229, 168, 209, - 214, 236, 182, 3, 231, 151, 209, 214, 236, 182, 3, 198, 179, 209, 214, - 236, 182, 3, 55, 209, 214, 236, 182, 3, 248, 21, 209, 214, 236, 182, 3, - 203, 73, 209, 214, 236, 182, 3, 242, 158, 209, 214, 236, 182, 3, 217, 69, - 209, 214, 236, 182, 3, 217, 7, 209, 214, 236, 182, 3, 205, 103, 209, 214, - 236, 182, 3, 219, 117, 209, 214, 236, 182, 3, 248, 44, 209, 214, 236, - 182, 3, 247, 41, 209, 93, 209, 214, 236, 182, 3, 236, 111, 209, 214, 236, - 182, 3, 242, 32, 209, 214, 236, 182, 3, 202, 78, 209, 214, 236, 182, 3, - 242, 33, 209, 214, 236, 182, 3, 248, 204, 209, 214, 236, 182, 3, 203, 60, - 209, 214, 236, 182, 3, 228, 156, 209, 214, 236, 182, 3, 229, 116, 209, - 214, 236, 182, 3, 247, 197, 219, 188, 209, 214, 236, 182, 3, 247, 30, - 209, 214, 236, 182, 3, 207, 137, 209, 214, 236, 182, 3, 234, 170, 209, - 214, 236, 182, 3, 235, 80, 209, 214, 236, 182, 3, 197, 68, 209, 214, 236, - 182, 3, 248, 207, 209, 214, 236, 182, 3, 209, 94, 197, 250, 209, 214, - 236, 182, 3, 195, 44, 209, 214, 236, 182, 3, 210, 122, 209, 214, 236, - 182, 3, 206, 120, 209, 214, 236, 182, 3, 219, 101, 209, 214, 236, 182, 3, - 210, 238, 249, 96, 209, 214, 236, 182, 3, 232, 142, 209, 214, 236, 182, - 3, 230, 178, 209, 214, 236, 182, 3, 201, 45, 209, 214, 236, 182, 3, 2, - 250, 82, 209, 214, 236, 182, 3, 193, 133, 249, 47, 209, 214, 236, 182, 3, - 33, 211, 159, 105, 218, 160, 1, 65, 218, 160, 1, 73, 218, 160, 1, 250, - 70, 218, 160, 1, 248, 154, 218, 160, 1, 232, 14, 218, 160, 1, 238, 80, - 218, 160, 1, 70, 218, 160, 1, 193, 221, 218, 160, 1, 191, 166, 218, 160, - 1, 199, 46, 218, 160, 1, 223, 7, 218, 160, 1, 222, 125, 218, 160, 1, 208, - 97, 218, 160, 1, 170, 218, 160, 1, 218, 147, 218, 160, 1, 215, 47, 218, - 160, 1, 216, 0, 218, 160, 1, 213, 67, 218, 160, 1, 69, 218, 160, 1, 210, - 226, 218, 160, 1, 221, 78, 218, 160, 1, 148, 218, 160, 1, 206, 3, 218, - 160, 1, 200, 39, 218, 160, 1, 197, 131, 218, 160, 1, 251, 81, 218, 160, - 1, 234, 61, 218, 160, 1, 230, 83, 218, 160, 1, 192, 235, 247, 47, 1, 65, - 247, 47, 1, 210, 212, 247, 47, 1, 238, 80, 247, 47, 1, 170, 247, 47, 1, - 196, 24, 247, 47, 1, 148, 247, 47, 1, 219, 218, 247, 47, 1, 254, 163, - 247, 47, 1, 208, 97, 247, 47, 1, 250, 70, 247, 47, 1, 218, 147, 247, 47, - 1, 74, 247, 47, 1, 237, 243, 247, 47, 1, 200, 39, 247, 47, 1, 203, 162, - 247, 47, 1, 203, 161, 247, 47, 1, 206, 3, 247, 47, 1, 247, 144, 247, 47, - 1, 69, 247, 47, 1, 213, 67, 247, 47, 1, 192, 235, 247, 47, 1, 215, 47, - 247, 47, 1, 197, 130, 247, 47, 1, 210, 226, 247, 47, 1, 201, 173, 247, - 47, 1, 70, 247, 47, 1, 73, 247, 47, 1, 196, 21, 247, 47, 1, 222, 125, - 247, 47, 1, 222, 116, 247, 47, 1, 214, 150, 247, 47, 1, 196, 26, 247, 47, - 1, 232, 14, 247, 47, 1, 231, 205, 247, 47, 1, 201, 113, 247, 47, 1, 201, - 112, 247, 47, 1, 214, 56, 247, 47, 1, 223, 170, 247, 47, 1, 247, 143, - 247, 47, 1, 197, 131, 247, 47, 1, 196, 23, 247, 47, 1, 206, 105, 247, 47, - 1, 216, 253, 247, 47, 1, 216, 252, 247, 47, 1, 216, 251, 247, 47, 1, 216, - 250, 247, 47, 1, 219, 217, 247, 47, 1, 234, 174, 247, 47, 1, 196, 22, 93, - 234, 12, 198, 224, 77, 93, 234, 12, 17, 108, 93, 234, 12, 17, 109, 93, - 234, 12, 17, 139, 93, 234, 12, 17, 137, 93, 234, 12, 17, 153, 93, 234, - 12, 17, 173, 93, 234, 12, 17, 181, 93, 234, 12, 17, 176, 93, 234, 12, 17, - 184, 93, 234, 12, 31, 199, 90, 93, 234, 12, 31, 197, 28, 93, 234, 12, 31, - 198, 244, 93, 234, 12, 31, 232, 97, 93, 234, 12, 31, 232, 230, 93, 234, - 12, 31, 202, 115, 93, 234, 12, 31, 203, 236, 93, 234, 12, 31, 234, 110, - 93, 234, 12, 31, 213, 156, 93, 234, 12, 31, 91, 228, 109, 93, 234, 12, - 31, 103, 228, 109, 93, 234, 12, 31, 115, 228, 109, 93, 234, 12, 31, 232, - 90, 228, 109, 93, 234, 12, 31, 232, 185, 228, 109, 93, 234, 12, 31, 202, - 131, 228, 109, 93, 234, 12, 31, 203, 242, 228, 109, 93, 234, 12, 31, 234, - 121, 228, 109, 93, 234, 12, 31, 213, 161, 228, 109, 38, 43, 1, 65, 38, - 43, 1, 248, 223, 38, 43, 1, 221, 253, 38, 43, 1, 237, 101, 38, 43, 1, 73, - 38, 43, 1, 195, 150, 38, 43, 1, 191, 87, 38, 43, 1, 229, 213, 38, 43, 1, - 199, 28, 38, 43, 1, 70, 38, 43, 1, 157, 38, 43, 1, 234, 97, 38, 43, 1, - 234, 72, 38, 43, 1, 234, 61, 38, 43, 1, 233, 226, 38, 43, 1, 74, 38, 43, - 1, 210, 53, 38, 43, 1, 203, 108, 38, 43, 1, 220, 208, 38, 43, 1, 233, - 248, 38, 43, 1, 233, 236, 38, 43, 1, 199, 140, 38, 43, 1, 69, 38, 43, 1, - 234, 100, 38, 43, 1, 209, 205, 38, 43, 1, 221, 173, 38, 43, 1, 234, 138, - 38, 43, 1, 233, 238, 38, 43, 1, 243, 79, 38, 43, 1, 223, 170, 38, 43, 1, - 196, 26, 38, 43, 1, 233, 219, 38, 43, 212, 121, 108, 38, 43, 212, 121, - 153, 38, 43, 212, 121, 199, 90, 38, 43, 212, 121, 232, 230, 38, 43, 1, - 192, 80, 38, 43, 1, 213, 3, 197, 157, 38, 43, 1, 201, 251, 197, 157, 230, - 197, 1, 251, 187, 230, 197, 1, 249, 67, 230, 197, 1, 231, 13, 230, 197, - 1, 237, 222, 230, 197, 1, 251, 182, 230, 197, 1, 208, 80, 230, 197, 1, - 223, 20, 230, 197, 1, 230, 50, 230, 197, 1, 198, 238, 230, 197, 1, 234, - 108, 230, 197, 1, 220, 165, 230, 197, 1, 220, 76, 230, 197, 1, 217, 60, - 230, 197, 1, 214, 187, 230, 197, 1, 222, 230, 230, 197, 1, 196, 44, 230, - 197, 1, 210, 185, 230, 197, 1, 213, 156, 230, 197, 1, 207, 150, 230, 197, - 1, 205, 107, 230, 197, 1, 199, 106, 230, 197, 1, 193, 58, 230, 197, 1, - 233, 48, 230, 197, 1, 223, 174, 230, 197, 1, 228, 92, 230, 197, 1, 211, - 19, 230, 197, 1, 213, 161, 228, 109, 38, 209, 249, 1, 251, 81, 38, 209, - 249, 1, 247, 182, 38, 209, 249, 1, 231, 187, 38, 209, 249, 1, 236, 115, - 38, 209, 249, 1, 73, 38, 209, 249, 1, 191, 53, 38, 209, 249, 1, 234, 239, - 38, 209, 249, 1, 191, 95, 38, 209, 249, 1, 234, 237, 38, 209, 249, 1, 70, - 38, 209, 249, 1, 221, 26, 38, 209, 249, 1, 219, 184, 38, 209, 249, 1, - 216, 165, 38, 209, 249, 1, 214, 86, 38, 209, 249, 1, 195, 4, 38, 209, - 249, 1, 210, 39, 38, 209, 249, 1, 207, 65, 38, 209, 249, 1, 202, 188, 38, - 209, 249, 1, 199, 212, 38, 209, 249, 1, 69, 38, 209, 249, 1, 243, 58, 38, - 209, 249, 1, 203, 42, 38, 209, 249, 1, 203, 110, 38, 209, 249, 1, 191, - 227, 38, 209, 249, 1, 192, 58, 38, 209, 249, 1, 74, 38, 209, 249, 1, 211, - 76, 38, 209, 249, 1, 234, 138, 38, 209, 249, 1, 144, 38, 209, 249, 1, - 197, 141, 38, 209, 249, 1, 195, 137, 38, 209, 249, 1, 192, 62, 38, 209, - 249, 1, 192, 60, 38, 209, 249, 1, 192, 95, 38, 209, 249, 1, 223, 197, 38, - 209, 249, 1, 191, 225, 38, 209, 249, 1, 169, 38, 209, 249, 1, 228, 5, 33, - 38, 209, 249, 1, 251, 81, 33, 38, 209, 249, 1, 236, 115, 33, 38, 209, - 249, 1, 191, 95, 33, 38, 209, 249, 1, 214, 86, 33, 38, 209, 249, 1, 202, - 188, 196, 138, 1, 251, 113, 196, 138, 1, 248, 162, 196, 138, 1, 231, 175, - 196, 138, 1, 221, 190, 196, 138, 1, 237, 61, 196, 138, 1, 228, 247, 196, - 138, 1, 193, 48, 196, 138, 1, 191, 76, 196, 138, 1, 228, 148, 196, 138, - 1, 199, 68, 196, 138, 1, 191, 250, 196, 138, 1, 222, 79, 196, 138, 1, - 203, 64, 196, 138, 1, 220, 7, 196, 138, 1, 216, 174, 196, 138, 1, 237, - 19, 196, 138, 1, 212, 117, 196, 138, 1, 190, 251, 196, 138, 1, 205, 142, - 196, 138, 1, 251, 178, 196, 138, 1, 208, 158, 196, 138, 1, 205, 186, 196, - 138, 1, 208, 32, 196, 138, 1, 207, 128, 196, 138, 1, 199, 32, 196, 138, - 1, 231, 49, 196, 138, 1, 159, 196, 138, 1, 70, 196, 138, 1, 69, 196, 138, - 1, 201, 124, 196, 138, 193, 23, 236, 160, 38, 209, 243, 3, 65, 38, 209, - 243, 3, 70, 38, 209, 243, 3, 69, 38, 209, 243, 3, 157, 38, 209, 243, 3, - 220, 208, 38, 209, 243, 3, 231, 203, 38, 209, 243, 3, 230, 146, 38, 209, - 243, 3, 192, 220, 38, 209, 243, 3, 247, 112, 38, 209, 243, 3, 223, 4, 38, - 209, 243, 3, 222, 217, 38, 209, 243, 3, 199, 247, 38, 209, 243, 3, 197, - 90, 38, 209, 243, 3, 237, 241, 38, 209, 243, 3, 236, 255, 38, 209, 243, - 3, 235, 45, 38, 209, 243, 3, 199, 44, 38, 209, 243, 3, 168, 38, 209, 243, - 3, 249, 103, 38, 209, 243, 3, 233, 68, 38, 209, 243, 3, 180, 38, 209, - 243, 3, 212, 165, 38, 209, 243, 3, 172, 38, 209, 243, 3, 216, 81, 38, - 209, 243, 3, 215, 139, 38, 209, 243, 3, 169, 38, 209, 243, 3, 195, 185, - 38, 209, 243, 3, 195, 66, 38, 209, 243, 3, 166, 38, 209, 243, 3, 206, 63, - 38, 209, 243, 3, 171, 38, 209, 243, 3, 189, 38, 209, 243, 3, 191, 123, - 38, 209, 243, 3, 203, 160, 38, 209, 243, 3, 201, 170, 38, 209, 243, 3, - 144, 38, 209, 243, 3, 250, 107, 38, 209, 243, 3, 250, 106, 38, 209, 243, - 3, 250, 105, 38, 209, 243, 3, 192, 189, 38, 209, 243, 3, 237, 218, 38, - 209, 243, 3, 237, 217, 38, 209, 243, 3, 249, 78, 38, 209, 243, 3, 247, - 164, 38, 209, 243, 193, 23, 236, 160, 38, 209, 243, 31, 108, 38, 209, - 243, 31, 109, 38, 209, 243, 31, 199, 90, 38, 209, 243, 31, 197, 28, 38, - 209, 243, 31, 228, 109, 237, 39, 6, 1, 177, 70, 237, 39, 6, 1, 177, 73, - 237, 39, 6, 1, 177, 65, 237, 39, 6, 1, 177, 251, 193, 237, 39, 6, 1, 177, - 74, 237, 39, 6, 1, 177, 211, 76, 237, 39, 6, 1, 203, 35, 70, 237, 39, 6, - 1, 203, 35, 73, 237, 39, 6, 1, 203, 35, 65, 237, 39, 6, 1, 203, 35, 251, - 193, 237, 39, 6, 1, 203, 35, 74, 237, 39, 6, 1, 203, 35, 211, 76, 237, - 39, 6, 1, 250, 81, 237, 39, 6, 1, 210, 240, 237, 39, 6, 1, 193, 0, 237, - 39, 6, 1, 192, 77, 237, 39, 6, 1, 230, 83, 237, 39, 6, 1, 210, 40, 237, - 39, 6, 1, 248, 207, 237, 39, 6, 1, 199, 116, 237, 39, 6, 1, 237, 86, 237, - 39, 6, 1, 243, 75, 237, 39, 6, 1, 222, 236, 237, 39, 6, 1, 222, 4, 237, - 39, 6, 1, 231, 149, 237, 39, 6, 1, 234, 138, 237, 39, 6, 1, 195, 145, - 237, 39, 6, 1, 233, 206, 237, 39, 6, 1, 199, 26, 237, 39, 6, 1, 233, 236, - 237, 39, 6, 1, 191, 84, 237, 39, 6, 1, 233, 226, 237, 39, 6, 1, 191, 61, - 237, 39, 6, 1, 233, 248, 237, 39, 6, 1, 234, 97, 237, 39, 6, 1, 234, 72, - 237, 39, 6, 1, 234, 61, 237, 39, 6, 1, 234, 46, 237, 39, 6, 1, 211, 121, - 237, 39, 6, 1, 233, 183, 237, 39, 2, 1, 177, 70, 237, 39, 2, 1, 177, 73, - 237, 39, 2, 1, 177, 65, 237, 39, 2, 1, 177, 251, 193, 237, 39, 2, 1, 177, - 74, 237, 39, 2, 1, 177, 211, 76, 237, 39, 2, 1, 203, 35, 70, 237, 39, 2, - 1, 203, 35, 73, 237, 39, 2, 1, 203, 35, 65, 237, 39, 2, 1, 203, 35, 251, - 193, 237, 39, 2, 1, 203, 35, 74, 237, 39, 2, 1, 203, 35, 211, 76, 237, - 39, 2, 1, 250, 81, 237, 39, 2, 1, 210, 240, 237, 39, 2, 1, 193, 0, 237, - 39, 2, 1, 192, 77, 237, 39, 2, 1, 230, 83, 237, 39, 2, 1, 210, 40, 237, - 39, 2, 1, 248, 207, 237, 39, 2, 1, 199, 116, 237, 39, 2, 1, 237, 86, 237, - 39, 2, 1, 243, 75, 237, 39, 2, 1, 222, 236, 237, 39, 2, 1, 222, 4, 237, - 39, 2, 1, 231, 149, 237, 39, 2, 1, 234, 138, 237, 39, 2, 1, 195, 145, - 237, 39, 2, 1, 233, 206, 237, 39, 2, 1, 199, 26, 237, 39, 2, 1, 233, 236, - 237, 39, 2, 1, 191, 84, 237, 39, 2, 1, 233, 226, 237, 39, 2, 1, 191, 61, - 237, 39, 2, 1, 233, 248, 237, 39, 2, 1, 234, 97, 237, 39, 2, 1, 234, 72, - 237, 39, 2, 1, 234, 61, 237, 39, 2, 1, 234, 46, 237, 39, 2, 1, 211, 121, - 237, 39, 2, 1, 233, 183, 203, 115, 1, 210, 36, 203, 115, 1, 198, 35, 203, - 115, 1, 221, 130, 203, 115, 1, 233, 11, 203, 115, 1, 199, 1, 203, 115, 1, - 202, 41, 203, 115, 1, 200, 167, 203, 115, 1, 242, 248, 203, 115, 1, 192, - 79, 203, 115, 1, 228, 106, 203, 115, 1, 248, 139, 203, 115, 1, 237, 100, - 203, 115, 1, 231, 189, 203, 115, 1, 194, 255, 203, 115, 1, 199, 7, 203, - 115, 1, 191, 4, 203, 115, 1, 216, 208, 203, 115, 1, 222, 153, 203, 115, - 1, 193, 39, 203, 115, 1, 230, 60, 203, 115, 1, 219, 1, 203, 115, 1, 216, - 27, 203, 115, 1, 223, 177, 203, 115, 1, 234, 136, 203, 115, 1, 250, 159, - 203, 115, 1, 251, 234, 203, 115, 1, 211, 93, 203, 115, 1, 193, 26, 203, - 115, 1, 211, 4, 203, 115, 1, 251, 193, 203, 115, 1, 206, 148, 203, 115, - 1, 212, 117, 203, 115, 1, 234, 156, 203, 115, 1, 251, 198, 203, 115, 1, - 227, 252, 203, 115, 1, 196, 73, 203, 115, 1, 211, 167, 203, 115, 1, 211, - 68, 203, 115, 1, 211, 119, 203, 115, 1, 250, 87, 203, 115, 1, 250, 215, - 203, 115, 1, 211, 45, 203, 115, 1, 251, 173, 203, 115, 1, 233, 240, 203, - 115, 1, 250, 190, 203, 115, 1, 234, 167, 203, 115, 1, 228, 4, 203, 115, - 1, 192, 41, 211, 23, 1, 251, 141, 211, 23, 1, 249, 103, 211, 23, 1, 199, - 247, 211, 23, 1, 223, 4, 211, 23, 1, 192, 220, 211, 23, 1, 221, 190, 211, - 23, 1, 237, 85, 211, 23, 1, 166, 211, 23, 1, 189, 211, 23, 1, 203, 70, - 211, 23, 1, 237, 23, 211, 23, 1, 247, 19, 211, 23, 1, 231, 203, 211, 23, - 1, 233, 68, 211, 23, 1, 208, 87, 211, 23, 1, 222, 96, 211, 23, 1, 220, - 97, 211, 23, 1, 216, 41, 211, 23, 1, 212, 101, 211, 23, 1, 193, 131, 211, - 23, 1, 144, 211, 23, 1, 169, 211, 23, 1, 65, 211, 23, 1, 73, 211, 23, 1, - 70, 211, 23, 1, 74, 211, 23, 1, 69, 211, 23, 1, 252, 154, 211, 23, 1, - 234, 145, 211, 23, 1, 211, 76, 211, 23, 17, 191, 77, 211, 23, 17, 108, - 211, 23, 17, 109, 211, 23, 17, 139, 211, 23, 17, 137, 211, 23, 17, 153, - 211, 23, 17, 173, 211, 23, 17, 181, 211, 23, 17, 176, 211, 23, 17, 184, - 211, 25, 6, 1, 65, 211, 25, 6, 1, 251, 184, 211, 25, 6, 1, 251, 178, 211, - 25, 6, 1, 251, 193, 211, 25, 6, 1, 248, 8, 211, 25, 6, 1, 246, 209, 211, - 25, 6, 1, 234, 129, 211, 25, 6, 1, 73, 211, 25, 6, 1, 234, 109, 211, 25, - 6, 1, 144, 211, 25, 6, 1, 228, 62, 211, 25, 6, 1, 70, 211, 25, 6, 1, 157, - 211, 25, 6, 1, 234, 128, 211, 25, 6, 1, 220, 129, 211, 25, 6, 1, 171, - 211, 25, 6, 1, 172, 211, 25, 6, 1, 180, 211, 25, 6, 1, 74, 211, 25, 6, 1, - 211, 118, 211, 25, 6, 1, 168, 211, 25, 6, 1, 234, 127, 211, 25, 6, 1, - 189, 211, 25, 6, 1, 203, 160, 211, 25, 6, 1, 199, 247, 211, 25, 6, 1, - 234, 126, 211, 25, 6, 1, 197, 164, 211, 25, 6, 1, 234, 125, 211, 25, 6, - 1, 197, 153, 211, 25, 6, 1, 237, 23, 211, 25, 6, 1, 69, 211, 25, 6, 1, - 193, 187, 211, 25, 6, 1, 221, 190, 211, 25, 6, 1, 231, 54, 211, 25, 6, 1, - 191, 123, 211, 25, 6, 1, 191, 71, 211, 25, 2, 1, 65, 211, 25, 2, 1, 251, - 184, 211, 25, 2, 1, 251, 178, 211, 25, 2, 1, 251, 193, 211, 25, 2, 1, - 248, 8, 211, 25, 2, 1, 246, 209, 211, 25, 2, 1, 234, 129, 211, 25, 2, 1, - 73, 211, 25, 2, 1, 234, 109, 211, 25, 2, 1, 144, 211, 25, 2, 1, 228, 62, - 211, 25, 2, 1, 70, 211, 25, 2, 1, 157, 211, 25, 2, 1, 234, 128, 211, 25, - 2, 1, 220, 129, 211, 25, 2, 1, 171, 211, 25, 2, 1, 172, 211, 25, 2, 1, - 180, 211, 25, 2, 1, 74, 211, 25, 2, 1, 211, 118, 211, 25, 2, 1, 168, 211, - 25, 2, 1, 234, 127, 211, 25, 2, 1, 189, 211, 25, 2, 1, 203, 160, 211, 25, - 2, 1, 199, 247, 211, 25, 2, 1, 234, 126, 211, 25, 2, 1, 197, 164, 211, - 25, 2, 1, 234, 125, 211, 25, 2, 1, 197, 153, 211, 25, 2, 1, 237, 23, 211, - 25, 2, 1, 69, 211, 25, 2, 1, 193, 187, 211, 25, 2, 1, 221, 190, 211, 25, - 2, 1, 231, 54, 211, 25, 2, 1, 191, 123, 211, 25, 2, 1, 191, 71, 234, 93, - 1, 65, 234, 93, 1, 248, 223, 234, 93, 1, 246, 250, 234, 93, 1, 243, 79, - 234, 93, 1, 237, 101, 234, 93, 1, 214, 140, 234, 93, 1, 237, 14, 234, 93, - 1, 234, 123, 234, 93, 1, 73, 234, 93, 1, 233, 18, 234, 93, 1, 231, 128, - 234, 93, 1, 230, 240, 234, 93, 1, 229, 213, 234, 93, 1, 70, 234, 93, 1, - 222, 238, 234, 93, 1, 221, 253, 234, 93, 1, 219, 214, 234, 93, 1, 219, - 44, 234, 93, 1, 216, 213, 234, 93, 1, 214, 107, 234, 93, 1, 180, 234, 93, - 1, 213, 137, 234, 93, 1, 74, 234, 93, 1, 210, 53, 234, 93, 1, 208, 69, - 234, 93, 1, 207, 108, 234, 93, 1, 206, 99, 234, 93, 1, 205, 63, 234, 93, - 1, 203, 108, 234, 93, 1, 199, 140, 234, 93, 1, 199, 28, 234, 93, 1, 69, - 234, 93, 1, 195, 150, 234, 93, 1, 192, 214, 234, 93, 1, 192, 159, 234, - 93, 1, 191, 87, 234, 93, 1, 191, 62, 234, 93, 1, 231, 40, 234, 93, 1, - 231, 46, 234, 93, 1, 221, 173, 247, 27, 251, 142, 1, 251, 108, 247, 27, - 251, 142, 1, 248, 164, 247, 27, 251, 142, 1, 231, 3, 247, 27, 251, 142, - 1, 237, 166, 247, 27, 251, 142, 1, 234, 155, 247, 27, 251, 142, 1, 191, - 98, 247, 27, 251, 142, 1, 233, 143, 247, 27, 251, 142, 1, 191, 56, 247, - 27, 251, 142, 1, 199, 169, 247, 27, 251, 142, 1, 246, 209, 247, 27, 251, - 142, 1, 191, 236, 247, 27, 251, 142, 1, 191, 71, 247, 27, 251, 142, 1, - 223, 48, 247, 27, 251, 142, 1, 203, 160, 247, 27, 251, 142, 1, 220, 0, - 247, 27, 251, 142, 1, 223, 61, 247, 27, 251, 142, 1, 192, 210, 247, 27, - 251, 142, 1, 234, 255, 247, 27, 251, 142, 1, 247, 54, 247, 27, 251, 142, - 1, 222, 218, 247, 27, 251, 142, 1, 222, 39, 247, 27, 251, 142, 1, 218, - 156, 247, 27, 251, 142, 1, 229, 147, 247, 27, 251, 142, 1, 208, 70, 247, - 27, 251, 142, 1, 251, 17, 247, 27, 251, 142, 1, 243, 9, 247, 27, 251, - 142, 1, 243, 47, 247, 27, 251, 142, 1, 238, 93, 247, 27, 251, 142, 1, - 217, 48, 247, 27, 251, 142, 1, 208, 74, 247, 27, 251, 142, 1, 212, 239, - 247, 27, 251, 142, 1, 234, 232, 247, 27, 251, 142, 1, 203, 142, 247, 27, - 251, 142, 1, 222, 239, 247, 27, 251, 142, 1, 211, 93, 247, 27, 251, 142, - 1, 196, 255, 247, 27, 251, 142, 1, 233, 41, 247, 27, 251, 142, 1, 234, - 245, 247, 27, 251, 142, 1, 243, 85, 247, 27, 251, 142, 1, 210, 25, 247, - 27, 251, 142, 1, 231, 30, 247, 27, 251, 142, 1, 207, 125, 247, 27, 251, - 142, 1, 203, 169, 247, 27, 251, 142, 1, 195, 69, 247, 27, 251, 142, 1, - 198, 113, 247, 27, 251, 142, 1, 203, 13, 247, 27, 251, 142, 1, 223, 18, - 247, 27, 251, 142, 1, 238, 94, 247, 27, 251, 142, 1, 247, 19, 247, 27, - 251, 142, 1, 192, 84, 247, 27, 251, 142, 1, 209, 106, 247, 27, 251, 142, - 1, 221, 93, 247, 27, 251, 142, 242, 206, 77, 195, 26, 6, 1, 65, 195, 26, - 6, 1, 248, 254, 195, 26, 6, 1, 248, 223, 195, 26, 6, 1, 246, 250, 195, - 26, 6, 1, 243, 79, 195, 26, 6, 1, 237, 101, 195, 26, 6, 1, 237, 14, 195, - 26, 6, 1, 234, 123, 195, 26, 6, 1, 73, 195, 26, 6, 1, 233, 18, 195, 26, - 6, 1, 231, 203, 195, 26, 6, 1, 144, 195, 26, 6, 1, 229, 145, 195, 26, 6, - 1, 70, 195, 26, 6, 1, 223, 167, 195, 26, 6, 1, 222, 238, 195, 26, 6, 1, - 157, 195, 26, 6, 1, 171, 195, 26, 6, 1, 219, 49, 195, 26, 6, 1, 216, 213, - 195, 26, 6, 1, 214, 107, 195, 26, 6, 1, 213, 137, 195, 26, 6, 1, 74, 195, - 26, 6, 1, 210, 53, 195, 26, 6, 1, 208, 89, 195, 26, 6, 1, 207, 108, 195, - 26, 6, 1, 205, 63, 195, 26, 6, 1, 203, 108, 195, 26, 6, 1, 199, 140, 195, - 26, 6, 1, 199, 28, 195, 26, 6, 1, 69, 195, 26, 6, 1, 195, 150, 195, 26, - 6, 1, 192, 214, 195, 26, 6, 1, 192, 159, 195, 26, 6, 1, 191, 87, 195, 26, - 2, 1, 65, 195, 26, 2, 1, 248, 254, 195, 26, 2, 1, 248, 223, 195, 26, 2, - 1, 246, 250, 195, 26, 2, 1, 243, 79, 195, 26, 2, 1, 237, 101, 195, 26, 2, - 1, 237, 14, 195, 26, 2, 1, 234, 123, 195, 26, 2, 1, 73, 195, 26, 2, 1, - 233, 18, 195, 26, 2, 1, 231, 203, 195, 26, 2, 1, 144, 195, 26, 2, 1, 229, - 145, 195, 26, 2, 1, 70, 195, 26, 2, 1, 223, 167, 195, 26, 2, 1, 222, 238, - 195, 26, 2, 1, 157, 195, 26, 2, 1, 171, 195, 26, 2, 1, 219, 49, 195, 26, - 2, 1, 216, 213, 195, 26, 2, 1, 214, 107, 195, 26, 2, 1, 213, 137, 195, - 26, 2, 1, 74, 195, 26, 2, 1, 210, 53, 195, 26, 2, 1, 208, 89, 195, 26, 2, - 1, 207, 108, 195, 26, 2, 1, 205, 63, 195, 26, 2, 1, 203, 108, 195, 26, 2, - 1, 199, 140, 195, 26, 2, 1, 199, 28, 195, 26, 2, 1, 69, 195, 26, 2, 1, - 195, 150, 195, 26, 2, 1, 192, 214, 195, 26, 2, 1, 192, 159, 195, 26, 2, - 1, 191, 87, 32, 41, 3, 252, 102, 32, 41, 3, 252, 101, 32, 41, 3, 252, - 100, 32, 41, 3, 252, 99, 32, 41, 3, 252, 98, 32, 41, 3, 252, 97, 32, 41, - 3, 252, 96, 32, 41, 3, 252, 95, 32, 41, 3, 252, 94, 32, 41, 3, 252, 93, - 32, 41, 3, 252, 92, 32, 41, 3, 252, 91, 32, 41, 3, 252, 90, 32, 41, 3, - 252, 89, 32, 41, 3, 252, 88, 32, 41, 3, 252, 87, 32, 41, 3, 252, 86, 32, - 41, 3, 252, 85, 32, 41, 3, 252, 84, 32, 41, 3, 252, 83, 32, 41, 3, 252, - 82, 32, 41, 3, 252, 81, 32, 41, 3, 252, 80, 32, 41, 3, 252, 79, 32, 41, - 3, 252, 78, 32, 41, 3, 252, 77, 32, 41, 3, 252, 76, 32, 41, 3, 255, 112, - 32, 41, 3, 252, 75, 32, 41, 3, 252, 74, 32, 41, 3, 252, 73, 32, 41, 3, - 252, 72, 32, 41, 3, 252, 71, 32, 41, 3, 252, 70, 32, 41, 3, 252, 69, 32, - 41, 3, 252, 68, 32, 41, 3, 252, 67, 32, 41, 3, 252, 66, 32, 41, 3, 252, - 65, 32, 41, 3, 252, 64, 32, 41, 3, 252, 63, 32, 41, 3, 252, 62, 32, 41, - 3, 252, 61, 32, 41, 3, 252, 60, 32, 41, 3, 252, 59, 32, 41, 3, 252, 58, - 32, 41, 3, 252, 57, 32, 41, 3, 252, 56, 32, 41, 3, 252, 55, 32, 41, 3, - 252, 54, 32, 41, 3, 252, 53, 32, 41, 3, 252, 52, 32, 41, 3, 252, 51, 32, - 41, 3, 252, 50, 32, 41, 3, 252, 49, 32, 41, 3, 252, 48, 32, 41, 3, 252, - 47, 32, 41, 3, 252, 46, 32, 41, 3, 252, 45, 32, 41, 3, 252, 44, 32, 41, - 3, 252, 43, 32, 41, 3, 252, 42, 32, 41, 3, 252, 41, 32, 41, 3, 252, 40, - 32, 41, 3, 252, 39, 32, 41, 3, 252, 38, 32, 41, 3, 252, 37, 32, 41, 3, - 252, 36, 32, 41, 3, 252, 35, 32, 41, 3, 252, 34, 32, 41, 3, 252, 33, 32, - 41, 3, 255, 25, 32, 41, 3, 252, 32, 32, 41, 3, 252, 31, 32, 41, 3, 254, - 246, 32, 41, 3, 252, 30, 32, 41, 3, 252, 29, 32, 41, 3, 252, 28, 32, 41, - 3, 252, 27, 32, 41, 3, 254, 233, 32, 41, 3, 252, 26, 32, 41, 3, 252, 25, - 32, 41, 3, 252, 24, 32, 41, 3, 252, 23, 32, 41, 3, 252, 22, 32, 41, 3, - 254, 49, 32, 41, 3, 254, 48, 32, 41, 3, 254, 47, 32, 41, 3, 254, 46, 32, - 41, 3, 254, 45, 32, 41, 3, 254, 44, 32, 41, 3, 254, 43, 32, 41, 3, 254, - 42, 32, 41, 3, 254, 40, 32, 41, 3, 254, 39, 32, 41, 3, 254, 38, 32, 41, - 3, 254, 37, 32, 41, 3, 254, 36, 32, 41, 3, 254, 35, 32, 41, 3, 254, 33, - 32, 41, 3, 254, 32, 32, 41, 3, 254, 31, 32, 41, 3, 254, 30, 32, 41, 3, - 254, 29, 32, 41, 3, 254, 28, 32, 41, 3, 254, 27, 32, 41, 3, 254, 26, 32, - 41, 3, 254, 25, 32, 41, 3, 254, 24, 32, 41, 3, 254, 23, 32, 41, 3, 254, - 22, 32, 41, 3, 254, 21, 32, 41, 3, 254, 20, 32, 41, 3, 254, 19, 32, 41, - 3, 254, 18, 32, 41, 3, 254, 17, 32, 41, 3, 254, 16, 32, 41, 3, 254, 15, - 32, 41, 3, 254, 13, 32, 41, 3, 254, 12, 32, 41, 3, 254, 11, 32, 41, 3, - 254, 7, 32, 41, 3, 254, 6, 32, 41, 3, 254, 5, 32, 41, 3, 254, 4, 32, 41, - 3, 254, 0, 32, 41, 3, 253, 255, 32, 41, 3, 253, 254, 32, 41, 3, 253, 253, - 32, 41, 3, 253, 252, 32, 41, 3, 253, 251, 32, 41, 3, 253, 250, 32, 41, 3, - 253, 249, 32, 41, 3, 253, 248, 32, 41, 3, 253, 247, 32, 41, 3, 253, 246, - 32, 41, 3, 253, 245, 32, 41, 3, 253, 244, 32, 41, 3, 253, 243, 32, 41, 3, - 253, 242, 32, 41, 3, 253, 241, 32, 41, 3, 253, 240, 32, 41, 3, 253, 239, - 32, 41, 3, 253, 238, 32, 41, 3, 253, 237, 32, 41, 3, 253, 236, 32, 41, 3, - 253, 235, 32, 41, 3, 253, 234, 32, 41, 3, 253, 232, 32, 41, 3, 253, 231, - 32, 41, 3, 253, 230, 32, 41, 3, 253, 229, 32, 41, 3, 253, 228, 32, 41, 3, - 253, 226, 32, 41, 3, 253, 225, 32, 41, 3, 253, 224, 32, 41, 3, 253, 223, - 32, 41, 3, 253, 221, 32, 41, 3, 253, 220, 32, 41, 3, 253, 219, 32, 41, 3, - 253, 185, 32, 41, 3, 253, 183, 32, 41, 3, 253, 181, 32, 41, 3, 253, 179, - 32, 41, 3, 253, 177, 32, 41, 3, 253, 175, 32, 41, 3, 253, 173, 32, 41, 3, - 253, 171, 32, 41, 3, 253, 169, 32, 41, 3, 253, 167, 32, 41, 3, 253, 165, - 32, 41, 3, 253, 162, 32, 41, 3, 253, 160, 32, 41, 3, 253, 158, 32, 41, 3, - 253, 156, 32, 41, 3, 253, 154, 32, 41, 3, 253, 152, 32, 41, 3, 253, 150, - 32, 41, 3, 253, 148, 32, 41, 3, 253, 66, 32, 41, 3, 253, 65, 32, 41, 3, - 253, 64, 32, 41, 3, 253, 63, 32, 41, 3, 253, 62, 32, 41, 3, 253, 61, 32, - 41, 3, 253, 59, 32, 41, 3, 253, 58, 32, 41, 3, 253, 57, 32, 41, 3, 253, - 56, 32, 41, 3, 253, 55, 32, 41, 3, 253, 54, 32, 41, 3, 253, 52, 32, 41, - 3, 253, 51, 32, 41, 3, 253, 47, 32, 41, 3, 253, 46, 32, 41, 3, 253, 44, - 32, 41, 3, 253, 43, 32, 41, 3, 253, 42, 32, 41, 3, 253, 41, 32, 41, 3, - 253, 40, 32, 41, 3, 253, 39, 32, 41, 3, 253, 38, 32, 41, 3, 253, 37, 32, - 41, 3, 253, 36, 32, 41, 3, 253, 35, 32, 41, 3, 253, 34, 32, 41, 3, 253, - 33, 32, 41, 3, 253, 32, 32, 41, 3, 253, 31, 32, 41, 3, 253, 30, 32, 41, - 3, 253, 29, 32, 41, 3, 253, 28, 32, 41, 3, 253, 27, 32, 41, 3, 253, 26, - 32, 41, 3, 253, 25, 32, 41, 3, 253, 24, 32, 41, 3, 253, 23, 32, 41, 3, - 253, 22, 32, 41, 3, 253, 21, 32, 41, 3, 253, 20, 32, 41, 3, 253, 19, 32, - 41, 3, 253, 18, 32, 41, 3, 253, 17, 32, 41, 3, 253, 16, 32, 41, 3, 253, - 15, 32, 41, 3, 253, 14, 32, 41, 3, 253, 13, 32, 41, 3, 253, 12, 32, 41, - 3, 253, 11, 32, 41, 3, 253, 10, 32, 41, 3, 253, 9, 32, 41, 3, 253, 8, 32, - 41, 3, 253, 7, 32, 41, 3, 253, 6, 32, 41, 3, 253, 5, 32, 41, 3, 253, 4, - 32, 41, 3, 253, 3, 32, 41, 3, 253, 2, 32, 41, 3, 253, 1, 32, 41, 3, 253, - 0, 32, 41, 3, 252, 255, 32, 41, 3, 252, 254, 32, 41, 3, 252, 253, 32, 41, - 3, 252, 252, 32, 41, 3, 252, 251, 32, 41, 3, 252, 250, 32, 41, 3, 252, - 249, 32, 41, 3, 252, 248, 32, 41, 3, 252, 247, 32, 41, 3, 252, 246, 32, - 41, 3, 252, 245, 32, 41, 3, 252, 244, 32, 41, 3, 252, 243, 32, 41, 3, - 252, 242, 32, 41, 3, 252, 241, 32, 41, 3, 252, 240, 32, 41, 3, 252, 239, - 32, 41, 3, 252, 238, 32, 41, 3, 252, 237, 32, 41, 3, 252, 236, 32, 41, 3, - 252, 235, 32, 41, 3, 252, 234, 32, 41, 3, 252, 233, 32, 41, 3, 252, 232, - 32, 41, 3, 252, 231, 32, 41, 3, 252, 230, 32, 41, 3, 252, 229, 32, 41, 3, - 252, 228, 32, 41, 3, 252, 227, 32, 41, 3, 252, 226, 32, 41, 3, 252, 225, - 32, 41, 3, 252, 224, 32, 41, 3, 252, 223, 32, 41, 3, 252, 222, 32, 41, 3, - 252, 221, 32, 41, 3, 252, 220, 32, 41, 3, 252, 219, 32, 41, 3, 252, 218, - 32, 41, 3, 252, 217, 32, 41, 3, 252, 216, 32, 41, 3, 252, 215, 32, 41, 3, - 252, 214, 32, 41, 3, 252, 213, 32, 41, 3, 252, 212, 32, 41, 3, 252, 211, - 32, 41, 3, 252, 210, 32, 41, 3, 252, 209, 32, 41, 3, 252, 208, 32, 41, 3, - 252, 207, 32, 41, 3, 252, 206, 32, 41, 3, 252, 205, 32, 41, 3, 252, 204, - 32, 41, 3, 252, 203, 32, 41, 3, 252, 202, 32, 41, 3, 252, 201, 32, 41, 3, - 252, 200, 32, 41, 3, 252, 199, 32, 41, 3, 252, 198, 32, 41, 3, 252, 197, - 32, 41, 3, 252, 196, 32, 41, 3, 252, 195, 32, 41, 3, 252, 194, 32, 41, 3, - 252, 193, 32, 41, 3, 252, 192, 32, 41, 3, 252, 191, 32, 41, 3, 252, 190, - 32, 41, 3, 252, 189, 32, 41, 3, 252, 188, 32, 41, 3, 252, 187, 32, 41, 3, - 252, 186, 32, 41, 3, 252, 185, 32, 41, 3, 252, 184, 65, 32, 41, 3, 252, - 183, 250, 70, 32, 41, 3, 252, 182, 238, 80, 32, 41, 3, 252, 181, 73, 32, - 41, 3, 252, 180, 233, 134, 32, 41, 3, 252, 179, 230, 83, 32, 41, 3, 252, - 178, 223, 7, 32, 41, 3, 252, 177, 222, 125, 32, 41, 3, 252, 176, 170, 32, - 41, 3, 252, 175, 220, 106, 32, 41, 3, 252, 174, 220, 105, 32, 41, 3, 252, - 173, 220, 104, 32, 41, 3, 252, 172, 220, 103, 32, 41, 3, 252, 171, 193, - 221, 32, 41, 3, 252, 170, 192, 235, 32, 41, 3, 252, 169, 192, 159, 32, - 41, 3, 252, 168, 211, 99, 32, 41, 3, 252, 167, 252, 17, 32, 41, 3, 252, - 166, 249, 4, 32, 41, 3, 252, 165, 237, 148, 32, 41, 3, 252, 164, 233, - 142, 32, 41, 3, 252, 163, 222, 238, 32, 41, 3, 252, 162, 32, 41, 3, 252, - 161, 32, 41, 3, 252, 160, 32, 41, 3, 252, 159, 32, 41, 3, 252, 158, 32, - 41, 3, 252, 157, 32, 41, 3, 252, 156, 32, 41, 3, 252, 155, 59, 1, 2, 6, - 252, 154, 59, 1, 200, 177, 197, 234, 242, 35, 59, 1, 200, 177, 134, 197, - 234, 242, 35, 59, 1, 2, 251, 229, 59, 1, 2, 6, 250, 70, 59, 1, 2, 78, 4, - 106, 59, 1, 2, 234, 249, 236, 213, 59, 1, 2, 234, 249, 236, 214, 4, 207, - 19, 106, 59, 1, 2, 234, 249, 236, 214, 4, 238, 128, 59, 1, 2, 237, 25, - 236, 213, 59, 1, 2, 238, 81, 4, 199, 210, 59, 1, 2, 238, 81, 4, 106, 59, - 1, 2, 238, 81, 4, 228, 219, 24, 199, 210, 59, 1, 2, 207, 13, 73, 59, 1, - 2, 242, 171, 207, 13, 211, 66, 73, 59, 1, 2, 232, 252, 236, 213, 59, 1, - 2, 207, 135, 228, 156, 59, 1, 2, 6, 232, 14, 59, 1, 2, 232, 15, 4, 106, - 59, 1, 2, 6, 232, 15, 4, 106, 59, 1, 2, 230, 84, 4, 105, 59, 1, 2, 6, - 230, 83, 59, 1, 2, 229, 165, 4, 106, 59, 1, 2, 236, 95, 223, 8, 4, 201, - 23, 24, 106, 59, 1, 2, 218, 205, 236, 213, 59, 1, 2, 218, 149, 236, 213, - 59, 1, 2, 220, 119, 4, 248, 181, 59, 1, 2, 6, 220, 119, 4, 248, 181, 59, - 1, 2, 220, 119, 4, 207, 19, 228, 219, 24, 248, 181, 59, 1, 2, 219, 138, - 59, 1, 2, 219, 139, 4, 207, 19, 106, 59, 1, 2, 152, 192, 159, 59, 1, 2, - 152, 192, 160, 4, 248, 181, 59, 1, 2, 186, 4, 105, 59, 1, 2, 6, 211, 139, - 59, 1, 2, 242, 171, 211, 99, 59, 1, 2, 208, 97, 59, 1, 2, 152, 207, 217, - 4, 177, 219, 188, 59, 1, 2, 152, 207, 217, 4, 177, 219, 189, 24, 207, 19, - 106, 59, 1, 2, 207, 217, 4, 199, 210, 59, 1, 2, 207, 217, 4, 232, 192, - 59, 1, 2, 6, 148, 59, 1, 2, 199, 147, 236, 214, 4, 238, 128, 59, 1, 2, - 197, 166, 236, 213, 59, 1, 2, 197, 166, 236, 214, 4, 207, 19, 106, 59, 1, - 2, 199, 74, 236, 213, 59, 1, 2, 200, 40, 4, 207, 19, 106, 59, 1, 2, 196, - 9, 4, 50, 106, 59, 1, 2, 6, 192, 159, 59, 1, 230, 231, 201, 59, 4, 105, - 59, 1, 207, 13, 230, 231, 201, 59, 4, 105, 59, 1, 248, 124, 242, 183, 59, - 1, 237, 53, 242, 183, 59, 1, 219, 235, 242, 183, 59, 1, 251, 99, 242, - 183, 59, 1, 207, 19, 242, 184, 4, 207, 19, 106, 59, 1, 2, 206, 4, 4, 238, - 128, 238, 88, 5, 65, 238, 88, 5, 73, 238, 88, 5, 70, 238, 88, 5, 74, 238, - 88, 5, 69, 238, 88, 5, 223, 4, 238, 88, 5, 222, 174, 238, 88, 5, 157, - 238, 88, 5, 221, 253, 238, 88, 5, 221, 142, 238, 88, 5, 221, 43, 238, 88, - 5, 220, 208, 238, 88, 5, 171, 238, 88, 5, 219, 214, 238, 88, 5, 219, 122, - 238, 88, 5, 219, 19, 238, 88, 5, 218, 203, 238, 88, 5, 172, 238, 88, 5, - 216, 213, 238, 88, 5, 216, 81, 238, 88, 5, 215, 251, 238, 88, 5, 215, - 139, 238, 88, 5, 180, 238, 88, 5, 214, 107, 238, 88, 5, 213, 205, 238, - 88, 5, 213, 30, 238, 88, 5, 212, 165, 238, 88, 5, 168, 238, 88, 5, 210, - 53, 238, 88, 5, 209, 176, 238, 88, 5, 209, 65, 238, 88, 5, 208, 158, 238, - 88, 5, 166, 238, 88, 5, 207, 108, 238, 88, 5, 206, 252, 238, 88, 5, 206, - 157, 238, 88, 5, 206, 63, 238, 88, 5, 189, 238, 88, 5, 205, 63, 238, 88, - 5, 202, 217, 238, 88, 5, 202, 41, 238, 88, 5, 200, 255, 238, 88, 5, 199, - 247, 238, 88, 5, 199, 140, 238, 88, 5, 198, 188, 238, 88, 5, 159, 238, - 88, 5, 197, 90, 238, 88, 5, 193, 187, 238, 88, 5, 193, 123, 238, 88, 5, - 193, 84, 238, 88, 5, 193, 48, 238, 88, 5, 192, 220, 238, 88, 5, 192, 214, - 238, 88, 5, 191, 123, 238, 88, 5, 191, 7, 223, 136, 250, 224, 1, 251, - 139, 223, 136, 250, 224, 1, 248, 161, 223, 136, 250, 224, 1, 231, 1, 223, - 136, 250, 224, 1, 237, 205, 223, 136, 250, 224, 1, 229, 213, 223, 136, - 250, 224, 1, 193, 131, 223, 136, 250, 224, 1, 191, 91, 223, 136, 250, - 224, 1, 229, 152, 223, 136, 250, 224, 1, 199, 64, 223, 136, 250, 224, 1, - 191, 249, 223, 136, 250, 224, 1, 222, 49, 223, 136, 250, 224, 1, 220, 2, - 223, 136, 250, 224, 1, 216, 174, 223, 136, 250, 224, 1, 212, 117, 223, - 136, 250, 224, 1, 205, 143, 223, 136, 250, 224, 1, 250, 76, 223, 136, - 250, 224, 1, 210, 53, 223, 136, 250, 224, 1, 205, 184, 223, 136, 250, - 224, 1, 208, 31, 223, 136, 250, 224, 1, 207, 33, 223, 136, 250, 224, 1, - 203, 64, 223, 136, 250, 224, 1, 199, 154, 223, 136, 250, 224, 205, 49, - 57, 223, 136, 250, 224, 31, 108, 223, 136, 250, 224, 31, 109, 223, 136, - 250, 224, 31, 139, 223, 136, 250, 224, 31, 199, 90, 223, 136, 250, 224, - 31, 197, 28, 223, 136, 250, 224, 31, 91, 228, 109, 223, 136, 250, 224, - 31, 91, 188, 223, 136, 250, 224, 31, 199, 91, 188, 210, 170, 1, 251, 139, - 210, 170, 1, 248, 161, 210, 170, 1, 231, 1, 210, 170, 1, 237, 205, 210, - 170, 1, 229, 213, 210, 170, 1, 193, 131, 210, 170, 1, 191, 91, 210, 170, - 1, 229, 152, 210, 170, 1, 199, 64, 210, 170, 1, 191, 249, 210, 170, 1, - 222, 49, 210, 170, 1, 220, 2, 210, 170, 1, 216, 174, 210, 170, 1, 52, - 212, 117, 210, 170, 1, 212, 117, 210, 170, 1, 205, 143, 210, 170, 1, 250, - 76, 210, 170, 1, 210, 53, 210, 170, 1, 205, 184, 210, 170, 1, 208, 31, - 210, 170, 1, 207, 33, 210, 170, 1, 203, 64, 210, 170, 1, 199, 154, 210, - 170, 219, 195, 232, 161, 210, 170, 206, 198, 232, 161, 210, 170, 31, 108, - 210, 170, 31, 109, 210, 170, 31, 139, 210, 170, 31, 137, 210, 170, 31, - 153, 210, 170, 31, 199, 90, 210, 170, 31, 197, 28, 214, 232, 1, 52, 251, - 139, 214, 232, 1, 251, 139, 214, 232, 1, 52, 248, 161, 214, 232, 1, 248, - 161, 214, 232, 1, 231, 1, 214, 232, 1, 237, 205, 214, 232, 1, 52, 229, - 213, 214, 232, 1, 229, 213, 214, 232, 1, 193, 131, 214, 232, 1, 191, 91, - 214, 232, 1, 229, 152, 214, 232, 1, 199, 64, 214, 232, 1, 52, 191, 249, - 214, 232, 1, 191, 249, 214, 232, 1, 52, 222, 49, 214, 232, 1, 222, 49, - 214, 232, 1, 52, 220, 2, 214, 232, 1, 220, 2, 214, 232, 1, 52, 216, 174, - 214, 232, 1, 216, 174, 214, 232, 1, 52, 212, 117, 214, 232, 1, 212, 117, - 214, 232, 1, 205, 143, 214, 232, 1, 250, 76, 214, 232, 1, 210, 53, 214, - 232, 1, 205, 184, 214, 232, 1, 208, 31, 214, 232, 1, 207, 33, 214, 232, - 1, 52, 203, 64, 214, 232, 1, 203, 64, 214, 232, 1, 199, 154, 214, 232, - 31, 108, 214, 232, 31, 109, 214, 232, 31, 139, 214, 232, 31, 137, 214, - 232, 238, 155, 31, 137, 214, 232, 31, 153, 214, 232, 31, 199, 90, 214, - 232, 31, 197, 28, 214, 232, 31, 91, 228, 109, 229, 227, 1, 251, 139, 229, - 227, 1, 248, 161, 229, 227, 1, 231, 1, 229, 227, 1, 237, 204, 229, 227, - 1, 229, 213, 229, 227, 1, 193, 131, 229, 227, 1, 191, 89, 229, 227, 1, - 229, 152, 229, 227, 1, 199, 64, 229, 227, 1, 191, 249, 229, 227, 1, 222, - 49, 229, 227, 1, 220, 2, 229, 227, 1, 216, 174, 229, 227, 1, 212, 117, - 229, 227, 1, 205, 143, 229, 227, 1, 250, 74, 229, 227, 1, 210, 53, 229, - 227, 1, 205, 184, 229, 227, 1, 208, 31, 229, 227, 1, 203, 64, 229, 227, - 1, 199, 154, 229, 227, 31, 108, 229, 227, 31, 153, 229, 227, 31, 199, 90, - 229, 227, 31, 197, 28, 229, 227, 31, 91, 228, 109, 209, 188, 1, 251, 136, - 209, 188, 1, 248, 164, 209, 188, 1, 231, 176, 209, 188, 1, 237, 63, 209, - 188, 1, 229, 213, 209, 188, 1, 193, 138, 209, 188, 1, 191, 115, 209, 188, - 1, 229, 154, 209, 188, 1, 199, 68, 209, 188, 1, 191, 250, 209, 188, 1, - 222, 79, 209, 188, 1, 220, 8, 209, 188, 1, 216, 174, 209, 188, 1, 212, - 117, 209, 188, 1, 204, 14, 209, 188, 1, 251, 178, 209, 188, 1, 210, 53, - 209, 188, 1, 205, 186, 209, 188, 1, 208, 36, 209, 188, 1, 206, 119, 209, - 188, 1, 203, 64, 209, 188, 1, 199, 161, 209, 188, 31, 108, 209, 188, 31, - 199, 90, 209, 188, 31, 197, 28, 209, 188, 31, 91, 228, 109, 209, 188, 31, - 109, 209, 188, 31, 139, 209, 188, 193, 23, 204, 5, 218, 159, 1, 65, 218, - 159, 1, 250, 70, 218, 159, 1, 232, 14, 218, 159, 1, 238, 80, 218, 159, 1, - 73, 218, 159, 1, 196, 8, 218, 159, 1, 70, 218, 159, 1, 192, 159, 218, - 159, 1, 222, 125, 218, 159, 1, 170, 218, 159, 1, 218, 147, 218, 159, 1, - 215, 47, 218, 159, 1, 74, 218, 159, 1, 148, 218, 159, 1, 201, 173, 218, - 159, 1, 200, 39, 218, 159, 1, 69, 218, 159, 1, 233, 134, 218, 159, 1, - 208, 97, 218, 159, 1, 206, 3, 218, 159, 1, 197, 131, 218, 159, 1, 251, - 81, 218, 159, 1, 234, 61, 218, 159, 1, 218, 162, 218, 159, 1, 213, 67, - 218, 159, 1, 247, 145, 218, 159, 197, 234, 77, 151, 229, 112, 1, 65, 151, - 229, 112, 1, 73, 151, 229, 112, 1, 70, 151, 229, 112, 1, 74, 151, 229, - 112, 1, 169, 151, 229, 112, 1, 193, 187, 151, 229, 112, 1, 249, 103, 151, - 229, 112, 1, 249, 102, 151, 229, 112, 1, 168, 151, 229, 112, 1, 172, 151, - 229, 112, 1, 180, 151, 229, 112, 1, 214, 247, 151, 229, 112, 1, 214, 107, - 151, 229, 112, 1, 214, 105, 151, 229, 112, 1, 166, 151, 229, 112, 1, 207, - 179, 151, 229, 112, 1, 171, 151, 229, 112, 1, 221, 190, 151, 229, 112, 1, - 229, 145, 151, 229, 112, 1, 189, 151, 229, 112, 1, 205, 200, 151, 229, - 112, 1, 205, 63, 151, 229, 112, 1, 157, 151, 229, 112, 1, 208, 89, 151, - 229, 112, 1, 199, 247, 151, 229, 112, 1, 199, 245, 151, 229, 112, 1, 199, - 140, 151, 229, 112, 1, 199, 138, 151, 229, 112, 1, 159, 151, 229, 112, 1, - 237, 241, 151, 229, 112, 16, 195, 60, 151, 229, 112, 16, 195, 59, 151, - 238, 119, 1, 65, 151, 238, 119, 1, 73, 151, 238, 119, 1, 70, 151, 238, - 119, 1, 74, 151, 238, 119, 1, 169, 151, 238, 119, 1, 193, 187, 151, 238, - 119, 1, 249, 103, 151, 238, 119, 1, 168, 151, 238, 119, 1, 172, 151, 238, - 119, 1, 180, 151, 238, 119, 1, 214, 107, 151, 238, 119, 1, 166, 151, 238, - 119, 1, 171, 151, 238, 119, 1, 221, 190, 151, 238, 119, 1, 229, 145, 151, - 238, 119, 1, 189, 151, 238, 119, 1, 250, 220, 189, 151, 238, 119, 1, 205, - 63, 151, 238, 119, 1, 157, 151, 238, 119, 1, 208, 89, 151, 238, 119, 1, - 199, 247, 151, 238, 119, 1, 199, 140, 151, 238, 119, 1, 159, 151, 238, - 119, 1, 237, 241, 151, 238, 119, 232, 80, 234, 85, 197, 35, 151, 238, - 119, 232, 80, 91, 230, 37, 151, 238, 119, 219, 4, 206, 163, 151, 238, - 119, 219, 4, 223, 141, 151, 238, 119, 31, 108, 151, 238, 119, 31, 109, - 151, 238, 119, 31, 139, 151, 238, 119, 31, 137, 151, 238, 119, 31, 153, - 151, 238, 119, 31, 173, 151, 238, 119, 31, 181, 151, 238, 119, 31, 176, - 151, 238, 119, 31, 184, 151, 238, 119, 31, 199, 90, 151, 238, 119, 31, - 197, 28, 151, 238, 119, 31, 198, 244, 151, 238, 119, 31, 232, 97, 151, - 238, 119, 31, 232, 230, 151, 238, 119, 31, 202, 115, 151, 238, 119, 31, - 203, 236, 151, 238, 119, 31, 91, 228, 109, 151, 238, 119, 31, 103, 228, - 109, 151, 238, 119, 31, 115, 228, 109, 151, 238, 119, 31, 232, 90, 228, - 109, 151, 238, 119, 31, 232, 185, 228, 109, 151, 238, 119, 31, 202, 131, - 228, 109, 151, 238, 119, 31, 203, 242, 228, 109, 151, 238, 119, 31, 234, - 121, 228, 109, 151, 238, 119, 31, 213, 161, 228, 109, 151, 238, 119, 31, - 91, 188, 151, 238, 119, 31, 103, 188, 151, 238, 119, 31, 115, 188, 151, - 238, 119, 31, 232, 90, 188, 151, 238, 119, 31, 232, 185, 188, 151, 238, - 119, 31, 202, 131, 188, 151, 238, 119, 31, 203, 242, 188, 151, 238, 119, - 31, 234, 121, 188, 151, 238, 119, 31, 213, 161, 188, 151, 238, 119, 31, - 199, 91, 188, 151, 238, 119, 31, 197, 29, 188, 151, 238, 119, 31, 198, - 245, 188, 151, 238, 119, 31, 232, 98, 188, 151, 238, 119, 31, 232, 231, - 188, 151, 238, 119, 31, 202, 116, 188, 151, 238, 119, 31, 203, 237, 188, - 151, 238, 119, 31, 234, 111, 188, 151, 238, 119, 31, 213, 157, 188, 151, - 238, 119, 31, 91, 228, 110, 188, 151, 238, 119, 31, 103, 228, 110, 188, - 151, 238, 119, 31, 115, 228, 110, 188, 151, 238, 119, 31, 232, 90, 228, - 110, 188, 151, 238, 119, 31, 232, 185, 228, 110, 188, 151, 238, 119, 31, - 202, 131, 228, 110, 188, 151, 238, 119, 31, 203, 242, 228, 110, 188, 151, - 238, 119, 31, 234, 121, 228, 110, 188, 151, 238, 119, 31, 213, 161, 228, - 110, 188, 151, 238, 119, 232, 80, 91, 197, 36, 151, 238, 119, 232, 80, - 103, 197, 35, 151, 238, 119, 232, 80, 115, 197, 35, 151, 238, 119, 232, - 80, 232, 90, 197, 35, 151, 238, 119, 232, 80, 232, 185, 197, 35, 151, - 238, 119, 232, 80, 202, 131, 197, 35, 151, 238, 119, 232, 80, 203, 242, - 197, 35, 151, 238, 119, 232, 80, 234, 121, 197, 35, 151, 238, 119, 232, - 80, 213, 161, 197, 35, 151, 238, 119, 232, 80, 199, 91, 197, 35, 221, - 175, 1, 65, 221, 175, 18, 3, 70, 221, 175, 18, 3, 69, 221, 175, 18, 3, - 121, 148, 221, 175, 18, 3, 73, 221, 175, 18, 3, 74, 221, 175, 18, 219, - 174, 77, 221, 175, 3, 54, 206, 184, 60, 221, 175, 3, 251, 20, 221, 175, - 3, 195, 32, 221, 175, 1, 157, 221, 175, 1, 221, 190, 221, 175, 1, 231, - 203, 221, 175, 1, 231, 54, 221, 175, 1, 247, 112, 221, 175, 1, 246, 209, - 221, 175, 1, 223, 4, 221, 175, 1, 212, 88, 221, 175, 1, 197, 128, 221, - 175, 1, 197, 116, 221, 175, 1, 237, 146, 221, 175, 1, 237, 130, 221, 175, - 1, 213, 66, 221, 175, 1, 199, 247, 221, 175, 1, 199, 44, 221, 175, 1, - 237, 241, 221, 175, 1, 237, 23, 221, 175, 1, 180, 221, 175, 1, 168, 221, - 175, 1, 209, 219, 221, 175, 1, 249, 103, 221, 175, 1, 248, 153, 221, 175, - 1, 172, 221, 175, 1, 169, 221, 175, 1, 166, 221, 175, 1, 171, 221, 175, - 1, 195, 185, 221, 175, 1, 203, 160, 221, 175, 1, 201, 170, 221, 175, 1, - 189, 221, 175, 1, 191, 123, 221, 175, 1, 144, 221, 175, 1, 221, 77, 221, - 175, 1, 197, 96, 221, 175, 1, 197, 97, 221, 175, 1, 195, 67, 221, 175, 3, - 249, 38, 56, 221, 175, 3, 247, 26, 221, 175, 3, 75, 60, 221, 175, 195, - 37, 221, 175, 17, 108, 221, 175, 17, 109, 221, 175, 17, 139, 221, 175, - 17, 137, 221, 175, 31, 199, 90, 221, 175, 31, 197, 28, 221, 175, 31, 91, - 228, 109, 221, 175, 31, 91, 188, 221, 175, 232, 80, 91, 230, 37, 221, - 175, 208, 145, 236, 96, 221, 175, 208, 145, 2, 242, 218, 221, 175, 208, - 145, 242, 218, 221, 175, 208, 145, 238, 181, 164, 221, 175, 208, 145, - 217, 63, 221, 175, 208, 145, 218, 224, 221, 175, 208, 145, 237, 193, 221, - 175, 208, 145, 54, 237, 193, 221, 175, 208, 145, 219, 82, 38, 201, 253, - 250, 235, 1, 229, 213, 38, 201, 253, 250, 235, 1, 220, 2, 38, 201, 253, - 250, 235, 1, 229, 152, 38, 201, 253, 250, 235, 1, 216, 174, 38, 201, 253, - 250, 235, 1, 208, 31, 38, 201, 253, 250, 235, 1, 193, 131, 38, 201, 253, - 250, 235, 1, 203, 64, 38, 201, 253, 250, 235, 1, 207, 33, 38, 201, 253, - 250, 235, 1, 248, 161, 38, 201, 253, 250, 235, 1, 199, 154, 38, 201, 253, - 250, 235, 1, 205, 117, 38, 201, 253, 250, 235, 1, 222, 49, 38, 201, 253, - 250, 235, 1, 212, 117, 38, 201, 253, 250, 235, 1, 221, 170, 38, 201, 253, - 250, 235, 1, 205, 184, 38, 201, 253, 250, 235, 1, 205, 143, 38, 201, 253, - 250, 235, 1, 233, 18, 38, 201, 253, 250, 235, 1, 251, 141, 38, 201, 253, - 250, 235, 1, 250, 74, 38, 201, 253, 250, 235, 1, 237, 20, 38, 201, 253, - 250, 235, 1, 231, 1, 38, 201, 253, 250, 235, 1, 237, 205, 38, 201, 253, - 250, 235, 1, 231, 42, 38, 201, 253, 250, 235, 1, 199, 64, 38, 201, 253, - 250, 235, 1, 191, 89, 38, 201, 253, 250, 235, 1, 237, 17, 38, 201, 253, - 250, 235, 1, 191, 249, 38, 201, 253, 250, 235, 1, 199, 30, 38, 201, 253, - 250, 235, 1, 199, 9, 38, 201, 253, 250, 235, 31, 108, 38, 201, 253, 250, - 235, 31, 232, 230, 38, 201, 253, 250, 235, 167, 223, 116, 38, 185, 250, - 235, 1, 229, 178, 38, 185, 250, 235, 1, 220, 11, 38, 185, 250, 235, 1, - 230, 48, 38, 185, 250, 235, 1, 216, 189, 38, 185, 250, 235, 1, 208, 82, - 38, 185, 250, 235, 1, 193, 131, 38, 185, 250, 235, 1, 233, 234, 38, 185, - 250, 235, 1, 207, 66, 38, 185, 250, 235, 1, 248, 195, 38, 185, 250, 235, - 1, 199, 109, 38, 185, 250, 235, 1, 233, 235, 38, 185, 250, 235, 1, 222, - 79, 38, 185, 250, 235, 1, 213, 11, 38, 185, 250, 235, 1, 221, 185, 38, - 185, 250, 235, 1, 205, 187, 38, 185, 250, 235, 1, 233, 233, 38, 185, 250, - 235, 1, 233, 5, 38, 185, 250, 235, 1, 251, 141, 38, 185, 250, 235, 1, - 251, 178, 38, 185, 250, 235, 1, 237, 235, 38, 185, 250, 235, 1, 231, 119, - 38, 185, 250, 235, 1, 237, 212, 38, 185, 250, 235, 1, 231, 49, 38, 185, - 250, 235, 1, 199, 214, 38, 185, 250, 235, 1, 191, 113, 38, 185, 250, 235, - 1, 199, 36, 38, 185, 250, 235, 1, 192, 75, 38, 185, 250, 235, 1, 199, 24, - 38, 185, 250, 235, 1, 191, 116, 38, 185, 250, 235, 31, 108, 38, 185, 250, - 235, 31, 199, 90, 38, 185, 250, 235, 31, 197, 28, 217, 61, 1, 251, 139, - 217, 61, 1, 248, 161, 217, 61, 1, 248, 146, 217, 61, 1, 231, 1, 217, 61, - 1, 231, 27, 217, 61, 1, 237, 205, 217, 61, 1, 229, 213, 217, 61, 1, 193, - 131, 217, 61, 3, 196, 154, 217, 61, 1, 191, 91, 217, 61, 1, 191, 64, 217, - 61, 1, 222, 240, 217, 61, 1, 222, 221, 217, 61, 1, 229, 152, 217, 61, 1, - 199, 64, 217, 61, 1, 191, 249, 217, 61, 1, 222, 49, 217, 61, 1, 192, 217, - 217, 61, 1, 221, 177, 217, 61, 1, 220, 2, 217, 61, 1, 237, 16, 217, 61, - 1, 199, 35, 217, 61, 1, 216, 174, 217, 61, 1, 212, 117, 217, 61, 1, 205, - 143, 217, 61, 1, 250, 76, 217, 61, 1, 252, 106, 217, 61, 1, 210, 53, 217, - 61, 1, 233, 18, 217, 61, 1, 205, 184, 217, 61, 1, 208, 31, 217, 61, 1, - 192, 193, 217, 61, 1, 208, 58, 217, 61, 1, 207, 33, 217, 61, 1, 203, 64, - 217, 61, 1, 201, 138, 217, 61, 1, 199, 154, 217, 61, 252, 16, 87, 56, - 217, 61, 252, 16, 87, 60, 217, 61, 31, 108, 217, 61, 31, 153, 217, 61, - 31, 199, 90, 217, 61, 31, 197, 28, 217, 61, 31, 91, 228, 109, 217, 61, - 208, 145, 201, 97, 217, 61, 208, 145, 232, 161, 217, 61, 208, 145, 54, - 75, 193, 53, 236, 96, 217, 61, 208, 145, 75, 193, 53, 236, 96, 217, 61, - 208, 145, 236, 96, 217, 61, 208, 145, 103, 236, 94, 217, 61, 208, 145, - 219, 89, 232, 218, 250, 92, 1, 65, 250, 92, 1, 252, 154, 250, 92, 1, 251, - 18, 250, 92, 1, 252, 112, 250, 92, 1, 251, 81, 250, 92, 1, 252, 114, 250, - 92, 1, 251, 229, 250, 92, 1, 251, 225, 250, 92, 1, 73, 250, 92, 1, 234, - 145, 250, 92, 1, 74, 250, 92, 1, 211, 76, 250, 92, 1, 70, 250, 92, 1, - 223, 170, 250, 92, 1, 69, 250, 92, 1, 196, 26, 250, 92, 1, 221, 253, 250, - 92, 1, 192, 214, 250, 92, 1, 192, 173, 250, 92, 1, 192, 184, 250, 92, 1, - 231, 128, 250, 92, 1, 231, 85, 250, 92, 1, 231, 40, 250, 92, 1, 246, 250, - 250, 92, 1, 222, 238, 250, 92, 1, 199, 140, 250, 92, 1, 199, 28, 250, 92, - 1, 237, 101, 250, 92, 1, 237, 14, 250, 92, 1, 197, 123, 250, 92, 1, 210, - 53, 250, 92, 1, 233, 18, 250, 92, 1, 248, 223, 250, 92, 1, 248, 148, 250, - 92, 1, 214, 41, 250, 92, 1, 213, 212, 250, 92, 1, 213, 213, 250, 92, 1, - 214, 107, 250, 92, 1, 212, 77, 250, 92, 1, 213, 61, 250, 92, 1, 216, 213, - 250, 92, 1, 229, 41, 250, 92, 1, 191, 173, 250, 92, 1, 192, 80, 250, 92, - 1, 195, 150, 250, 92, 1, 207, 108, 250, 92, 1, 219, 214, 250, 92, 1, 205, - 63, 250, 92, 1, 191, 87, 250, 92, 1, 203, 108, 250, 92, 1, 191, 62, 250, - 92, 1, 202, 224, 250, 92, 1, 201, 139, 250, 92, 1, 229, 213, 250, 92, - 252, 16, 77, 198, 133, 103, 183, 138, 91, 75, 208, 144, 2, 103, 183, 138, - 91, 75, 208, 144, 219, 245, 103, 183, 138, 91, 75, 208, 144, 219, 245, - 91, 75, 138, 103, 183, 208, 144, 219, 245, 103, 206, 180, 138, 91, 206, - 184, 208, 144, 219, 245, 91, 206, 184, 138, 103, 206, 180, 208, 144, 223, - 94, 210, 96, 1, 251, 139, 223, 94, 210, 96, 1, 248, 161, 223, 94, 210, - 96, 1, 231, 1, 223, 94, 210, 96, 1, 237, 205, 223, 94, 210, 96, 1, 229, - 213, 223, 94, 210, 96, 1, 193, 131, 223, 94, 210, 96, 1, 191, 91, 223, - 94, 210, 96, 1, 229, 152, 223, 94, 210, 96, 1, 199, 64, 223, 94, 210, 96, - 1, 191, 249, 223, 94, 210, 96, 1, 222, 49, 223, 94, 210, 96, 1, 220, 2, - 223, 94, 210, 96, 1, 216, 174, 223, 94, 210, 96, 1, 212, 117, 223, 94, - 210, 96, 1, 205, 143, 223, 94, 210, 96, 1, 250, 76, 223, 94, 210, 96, 1, - 210, 53, 223, 94, 210, 96, 1, 205, 184, 223, 94, 210, 96, 1, 208, 31, - 223, 94, 210, 96, 1, 207, 33, 223, 94, 210, 96, 1, 203, 64, 223, 94, 210, - 96, 1, 199, 154, 223, 94, 210, 96, 31, 108, 223, 94, 210, 96, 31, 109, - 223, 94, 210, 96, 31, 139, 223, 94, 210, 96, 31, 137, 223, 94, 210, 96, - 31, 199, 90, 223, 94, 210, 96, 31, 197, 28, 223, 94, 210, 96, 31, 91, - 228, 109, 223, 94, 210, 96, 31, 91, 188, 223, 94, 210, 189, 1, 251, 139, - 223, 94, 210, 189, 1, 248, 161, 223, 94, 210, 189, 1, 231, 1, 223, 94, - 210, 189, 1, 237, 205, 223, 94, 210, 189, 1, 229, 213, 223, 94, 210, 189, - 1, 193, 130, 223, 94, 210, 189, 1, 191, 91, 223, 94, 210, 189, 1, 229, - 152, 223, 94, 210, 189, 1, 199, 64, 223, 94, 210, 189, 1, 191, 249, 223, - 94, 210, 189, 1, 222, 49, 223, 94, 210, 189, 1, 220, 2, 223, 94, 210, - 189, 1, 216, 173, 223, 94, 210, 189, 1, 212, 117, 223, 94, 210, 189, 1, - 205, 143, 223, 94, 210, 189, 1, 210, 53, 223, 94, 210, 189, 1, 205, 184, - 223, 94, 210, 189, 1, 203, 64, 223, 94, 210, 189, 1, 199, 154, 223, 94, - 210, 189, 31, 108, 223, 94, 210, 189, 31, 109, 223, 94, 210, 189, 31, - 139, 223, 94, 210, 189, 31, 137, 223, 94, 210, 189, 31, 199, 90, 223, 94, - 210, 189, 31, 197, 28, 223, 94, 210, 189, 31, 91, 228, 109, 223, 94, 210, - 189, 31, 91, 188, 208, 170, 210, 189, 1, 251, 139, 208, 170, 210, 189, 1, - 248, 161, 208, 170, 210, 189, 1, 231, 1, 208, 170, 210, 189, 1, 237, 205, - 208, 170, 210, 189, 1, 229, 213, 208, 170, 210, 189, 1, 193, 130, 208, - 170, 210, 189, 1, 191, 91, 208, 170, 210, 189, 1, 229, 152, 208, 170, - 210, 189, 1, 191, 249, 208, 170, 210, 189, 1, 222, 49, 208, 170, 210, - 189, 1, 220, 2, 208, 170, 210, 189, 1, 216, 173, 208, 170, 210, 189, 1, - 212, 117, 208, 170, 210, 189, 1, 205, 143, 208, 170, 210, 189, 1, 210, - 53, 208, 170, 210, 189, 1, 205, 184, 208, 170, 210, 189, 1, 203, 64, 208, - 170, 210, 189, 1, 199, 154, 208, 170, 210, 189, 205, 49, 77, 208, 170, - 210, 189, 152, 205, 49, 77, 208, 170, 210, 189, 232, 90, 183, 4, 238, - 170, 208, 170, 210, 189, 232, 90, 183, 4, 236, 96, 208, 170, 210, 189, - 31, 108, 208, 170, 210, 189, 31, 109, 208, 170, 210, 189, 31, 139, 208, - 170, 210, 189, 31, 137, 208, 170, 210, 189, 31, 199, 90, 208, 170, 210, - 189, 31, 197, 28, 208, 170, 210, 189, 31, 91, 228, 109, 38, 197, 57, 1, - 211, 34, 65, 38, 197, 57, 1, 192, 68, 65, 38, 197, 57, 1, 192, 68, 251, - 229, 38, 197, 57, 1, 211, 34, 70, 38, 197, 57, 1, 192, 68, 70, 38, 197, - 57, 1, 192, 68, 73, 38, 197, 57, 1, 211, 34, 74, 38, 197, 57, 1, 211, 34, - 211, 139, 38, 197, 57, 1, 192, 68, 211, 139, 38, 197, 57, 1, 211, 34, - 252, 103, 38, 197, 57, 1, 192, 68, 252, 103, 38, 197, 57, 1, 211, 34, - 251, 228, 38, 197, 57, 1, 192, 68, 251, 228, 38, 197, 57, 1, 211, 34, - 251, 201, 38, 197, 57, 1, 192, 68, 251, 201, 38, 197, 57, 1, 211, 34, - 251, 223, 38, 197, 57, 1, 192, 68, 251, 223, 38, 197, 57, 1, 211, 34, - 251, 246, 38, 197, 57, 1, 192, 68, 251, 246, 38, 197, 57, 1, 211, 34, - 251, 227, 38, 197, 57, 1, 211, 34, 233, 141, 38, 197, 57, 1, 192, 68, - 233, 141, 38, 197, 57, 1, 211, 34, 250, 81, 38, 197, 57, 1, 192, 68, 250, - 81, 38, 197, 57, 1, 211, 34, 251, 210, 38, 197, 57, 1, 192, 68, 251, 210, - 38, 197, 57, 1, 211, 34, 251, 221, 38, 197, 57, 1, 192, 68, 251, 221, 38, - 197, 57, 1, 211, 34, 211, 137, 38, 197, 57, 1, 192, 68, 211, 137, 38, - 197, 57, 1, 211, 34, 251, 156, 38, 197, 57, 1, 192, 68, 251, 156, 38, - 197, 57, 1, 211, 34, 251, 220, 38, 197, 57, 1, 211, 34, 234, 76, 38, 197, - 57, 1, 211, 34, 234, 72, 38, 197, 57, 1, 211, 34, 251, 81, 38, 197, 57, - 1, 211, 34, 251, 218, 38, 197, 57, 1, 192, 68, 251, 218, 38, 197, 57, 1, - 211, 34, 234, 38, 38, 197, 57, 1, 192, 68, 234, 38, 38, 197, 57, 1, 211, - 34, 234, 58, 38, 197, 57, 1, 192, 68, 234, 58, 38, 197, 57, 1, 211, 34, - 234, 24, 38, 197, 57, 1, 192, 68, 234, 24, 38, 197, 57, 1, 192, 68, 251, - 71, 38, 197, 57, 1, 211, 34, 234, 46, 38, 197, 57, 1, 192, 68, 251, 217, - 38, 197, 57, 1, 211, 34, 234, 14, 38, 197, 57, 1, 211, 34, 211, 67, 38, - 197, 57, 1, 211, 34, 227, 254, 38, 197, 57, 1, 211, 34, 234, 153, 38, - 197, 57, 1, 192, 68, 234, 153, 38, 197, 57, 1, 211, 34, 250, 243, 38, - 197, 57, 1, 192, 68, 250, 243, 38, 197, 57, 1, 211, 34, 223, 51, 38, 197, - 57, 1, 192, 68, 223, 51, 38, 197, 57, 1, 211, 34, 211, 47, 38, 197, 57, - 1, 192, 68, 211, 47, 38, 197, 57, 1, 211, 34, 250, 239, 38, 197, 57, 1, - 192, 68, 250, 239, 38, 197, 57, 1, 211, 34, 251, 216, 38, 197, 57, 1, - 211, 34, 250, 169, 38, 197, 57, 1, 211, 34, 251, 214, 38, 197, 57, 1, - 211, 34, 250, 159, 38, 197, 57, 1, 192, 68, 250, 159, 38, 197, 57, 1, - 211, 34, 233, 226, 38, 197, 57, 1, 192, 68, 233, 226, 38, 197, 57, 1, - 211, 34, 250, 132, 38, 197, 57, 1, 192, 68, 250, 132, 38, 197, 57, 1, - 211, 34, 251, 211, 38, 197, 57, 1, 192, 68, 251, 211, 38, 197, 57, 1, - 211, 34, 211, 20, 38, 197, 57, 1, 211, 34, 249, 21, 38, 175, 6, 1, 65, - 38, 175, 6, 1, 252, 154, 38, 175, 6, 1, 234, 155, 38, 175, 6, 1, 251, 93, - 38, 175, 6, 1, 234, 153, 38, 175, 6, 1, 234, 58, 38, 175, 6, 1, 234, 150, - 38, 175, 6, 1, 234, 149, 38, 175, 6, 1, 251, 74, 38, 175, 6, 1, 73, 38, - 175, 6, 1, 242, 172, 73, 38, 175, 6, 1, 234, 145, 38, 175, 6, 1, 234, - 138, 38, 175, 6, 1, 234, 137, 38, 175, 6, 1, 234, 133, 38, 175, 6, 1, - 234, 130, 38, 175, 6, 1, 70, 38, 175, 6, 1, 223, 170, 38, 175, 6, 1, 234, - 107, 38, 175, 6, 1, 234, 104, 38, 175, 6, 1, 251, 165, 38, 175, 6, 1, - 196, 82, 38, 175, 6, 1, 234, 97, 38, 175, 6, 1, 234, 75, 38, 175, 6, 1, - 234, 72, 38, 175, 6, 1, 234, 61, 38, 175, 6, 1, 234, 24, 38, 175, 6, 1, - 74, 38, 175, 6, 1, 211, 76, 38, 175, 6, 1, 213, 168, 211, 139, 38, 175, - 6, 1, 206, 53, 211, 139, 38, 175, 6, 1, 211, 138, 38, 175, 6, 1, 234, 14, - 38, 175, 6, 1, 234, 66, 38, 175, 6, 1, 233, 248, 38, 175, 6, 1, 203, 35, - 233, 248, 38, 175, 6, 1, 233, 236, 38, 175, 6, 1, 233, 215, 38, 175, 6, - 1, 233, 213, 38, 175, 6, 1, 234, 38, 38, 175, 6, 1, 233, 202, 38, 175, 6, - 1, 234, 151, 38, 175, 6, 1, 69, 38, 175, 6, 1, 196, 26, 38, 175, 6, 1, - 213, 168, 196, 148, 38, 175, 6, 1, 206, 53, 196, 148, 38, 175, 6, 1, 233, - 189, 38, 175, 6, 1, 233, 141, 38, 175, 6, 1, 233, 136, 38, 175, 6, 1, - 234, 37, 57, 38, 175, 6, 1, 196, 41, 38, 175, 2, 1, 65, 38, 175, 2, 1, - 252, 154, 38, 175, 2, 1, 234, 155, 38, 175, 2, 1, 251, 93, 38, 175, 2, 1, - 234, 153, 38, 175, 2, 1, 234, 58, 38, 175, 2, 1, 234, 150, 38, 175, 2, 1, - 234, 149, 38, 175, 2, 1, 251, 74, 38, 175, 2, 1, 73, 38, 175, 2, 1, 242, - 172, 73, 38, 175, 2, 1, 234, 145, 38, 175, 2, 1, 234, 138, 38, 175, 2, 1, - 234, 137, 38, 175, 2, 1, 234, 133, 38, 175, 2, 1, 234, 130, 38, 175, 2, - 1, 70, 38, 175, 2, 1, 223, 170, 38, 175, 2, 1, 234, 107, 38, 175, 2, 1, - 234, 104, 38, 175, 2, 1, 251, 165, 38, 175, 2, 1, 196, 82, 38, 175, 2, 1, - 234, 97, 38, 175, 2, 1, 234, 75, 38, 175, 2, 1, 234, 72, 38, 175, 2, 1, - 234, 61, 38, 175, 2, 1, 234, 24, 38, 175, 2, 1, 74, 38, 175, 2, 1, 211, - 76, 38, 175, 2, 1, 213, 168, 211, 139, 38, 175, 2, 1, 206, 53, 211, 139, - 38, 175, 2, 1, 211, 138, 38, 175, 2, 1, 234, 14, 38, 175, 2, 1, 234, 66, - 38, 175, 2, 1, 233, 248, 38, 175, 2, 1, 203, 35, 233, 248, 38, 175, 2, 1, - 233, 236, 38, 175, 2, 1, 233, 215, 38, 175, 2, 1, 233, 213, 38, 175, 2, - 1, 234, 38, 38, 175, 2, 1, 233, 202, 38, 175, 2, 1, 234, 151, 38, 175, 2, - 1, 69, 38, 175, 2, 1, 196, 26, 38, 175, 2, 1, 213, 168, 196, 148, 38, - 175, 2, 1, 206, 53, 196, 148, 38, 175, 2, 1, 233, 189, 38, 175, 2, 1, - 233, 141, 38, 175, 2, 1, 233, 136, 38, 175, 2, 1, 234, 37, 57, 38, 175, - 2, 1, 196, 41, 38, 175, 31, 108, 38, 175, 31, 153, 38, 175, 31, 199, 90, - 38, 175, 31, 232, 230, 38, 175, 31, 91, 228, 109, 38, 175, 31, 91, 188, - 229, 247, 206, 137, 1, 65, 229, 247, 206, 137, 1, 249, 103, 229, 247, - 206, 137, 1, 168, 229, 247, 206, 137, 1, 199, 247, 229, 247, 206, 137, 1, - 197, 128, 229, 247, 206, 137, 1, 223, 4, 229, 247, 206, 137, 1, 247, 112, - 229, 247, 206, 137, 1, 144, 229, 247, 206, 137, 1, 221, 190, 229, 247, - 206, 137, 1, 233, 68, 229, 247, 206, 137, 1, 237, 241, 229, 247, 206, - 137, 1, 237, 146, 229, 247, 206, 137, 1, 166, 229, 247, 206, 137, 1, 206, - 104, 229, 247, 206, 137, 1, 191, 123, 229, 247, 206, 137, 1, 189, 229, - 247, 206, 137, 1, 203, 160, 229, 247, 206, 137, 1, 157, 229, 247, 206, - 137, 1, 231, 203, 229, 247, 206, 137, 1, 171, 229, 247, 206, 137, 1, 172, - 229, 247, 206, 137, 1, 180, 229, 247, 206, 137, 1, 193, 187, 229, 247, - 206, 137, 1, 221, 113, 193, 187, 229, 247, 206, 137, 1, 169, 229, 247, - 206, 137, 1, 221, 113, 169, 229, 247, 206, 137, 1, 214, 54, 229, 247, - 206, 137, 1, 212, 88, 229, 247, 206, 137, 1, 195, 185, 229, 247, 206, - 137, 18, 65, 229, 247, 206, 137, 18, 70, 229, 247, 206, 137, 18, 69, 229, - 247, 206, 137, 18, 73, 229, 247, 206, 137, 18, 74, 229, 247, 206, 137, - 87, 205, 168, 229, 247, 206, 137, 87, 214, 249, 221, 154, 229, 247, 206, - 137, 3, 229, 241, 229, 247, 206, 137, 3, 199, 213, 229, 247, 206, 137, 3, - 199, 187, 229, 247, 206, 137, 3, 199, 167, 229, 247, 206, 137, 17, 191, - 77, 229, 247, 206, 137, 17, 108, 229, 247, 206, 137, 17, 109, 229, 247, - 206, 137, 17, 139, 229, 247, 206, 137, 17, 137, 229, 247, 206, 137, 17, - 153, 229, 247, 206, 137, 17, 173, 229, 247, 206, 137, 17, 181, 229, 247, - 206, 137, 17, 176, 229, 247, 206, 137, 17, 184, 206, 41, 17, 108, 206, - 41, 17, 109, 206, 41, 17, 139, 206, 41, 17, 137, 206, 41, 17, 153, 206, - 41, 17, 173, 206, 41, 17, 181, 206, 41, 17, 176, 206, 41, 17, 184, 206, - 41, 31, 199, 90, 206, 41, 31, 197, 28, 206, 41, 31, 198, 244, 206, 41, - 31, 232, 97, 206, 41, 31, 232, 230, 206, 41, 31, 202, 115, 206, 41, 31, - 203, 236, 206, 41, 31, 234, 110, 206, 41, 31, 213, 156, 206, 41, 31, 91, - 228, 109, 206, 41, 31, 103, 228, 109, 206, 41, 31, 115, 228, 109, 206, - 41, 31, 232, 90, 228, 109, 206, 41, 31, 232, 185, 228, 109, 206, 41, 31, - 202, 131, 228, 109, 206, 41, 31, 203, 242, 228, 109, 206, 41, 31, 234, - 121, 228, 109, 206, 41, 31, 213, 161, 228, 109, 206, 41, 232, 80, 91, - 230, 37, 206, 41, 232, 80, 91, 208, 17, 206, 41, 232, 80, 91, 198, 251, - 206, 41, 232, 80, 103, 198, 248, 192, 39, 1, 234, 81, 192, 39, 1, 248, - 223, 192, 39, 1, 210, 53, 192, 39, 1, 209, 205, 192, 39, 1, 199, 28, 192, - 39, 1, 205, 63, 192, 39, 1, 242, 224, 192, 39, 1, 243, 35, 192, 39, 1, - 243, 49, 192, 39, 1, 229, 145, 192, 39, 1, 192, 220, 192, 39, 1, 237, - 212, 192, 39, 1, 191, 108, 192, 39, 1, 166, 192, 39, 1, 207, 1, 192, 39, - 1, 191, 123, 192, 39, 1, 223, 4, 192, 39, 1, 202, 169, 192, 39, 1, 203, - 64, 192, 39, 1, 205, 187, 192, 39, 1, 237, 235, 192, 39, 1, 199, 247, - 192, 39, 1, 191, 87, 192, 39, 1, 233, 143, 192, 39, 1, 192, 208, 192, 39, - 1, 233, 68, 192, 39, 1, 195, 185, 192, 39, 1, 195, 186, 251, 106, 20, - 192, 39, 1, 208, 82, 192, 39, 1, 222, 79, 192, 39, 1, 221, 187, 192, 39, - 1, 231, 190, 192, 39, 1, 220, 11, 192, 39, 1, 216, 28, 192, 39, 1, 212, - 117, 192, 39, 1, 196, 116, 192, 39, 1, 193, 131, 192, 39, 1, 210, 240, - 192, 39, 1, 233, 183, 192, 39, 1, 229, 220, 192, 39, 1, 191, 240, 192, - 39, 1, 233, 213, 192, 39, 33, 230, 25, 77, 192, 39, 33, 217, 121, 77, - 192, 39, 228, 56, 77, 192, 39, 1, 220, 12, 4, 75, 56, 192, 39, 1, 191, - 241, 4, 242, 210, 56, 38, 202, 23, 1, 251, 139, 38, 202, 23, 1, 52, 251, - 139, 38, 202, 23, 1, 248, 161, 38, 202, 23, 1, 52, 248, 161, 38, 202, 23, - 1, 231, 1, 38, 202, 23, 1, 229, 213, 38, 202, 23, 1, 52, 229, 213, 38, - 202, 23, 1, 193, 131, 38, 202, 23, 1, 191, 91, 38, 202, 23, 1, 229, 152, - 38, 202, 23, 1, 191, 249, 38, 202, 23, 1, 222, 49, 38, 202, 23, 1, 220, - 2, 38, 202, 23, 1, 216, 174, 38, 202, 23, 1, 212, 117, 38, 202, 23, 1, - 52, 212, 117, 38, 202, 23, 1, 52, 212, 118, 4, 81, 199, 210, 38, 202, 23, - 1, 205, 143, 38, 202, 23, 1, 250, 76, 38, 202, 23, 1, 251, 106, 250, 76, - 38, 202, 23, 1, 210, 53, 38, 202, 23, 1, 205, 184, 38, 202, 23, 1, 52, - 205, 184, 38, 202, 23, 1, 52, 205, 185, 4, 81, 199, 210, 38, 202, 23, 1, - 207, 31, 38, 202, 23, 1, 203, 64, 38, 202, 23, 1, 199, 154, 38, 202, 23, - 1, 52, 199, 154, 38, 202, 23, 1, 52, 199, 155, 4, 81, 199, 210, 38, 202, - 23, 31, 108, 38, 202, 23, 31, 109, 38, 202, 23, 31, 139, 38, 202, 23, 31, - 137, 38, 202, 23, 31, 153, 38, 202, 23, 31, 199, 90, 38, 202, 23, 31, - 197, 28, 38, 202, 23, 31, 198, 244, 38, 202, 23, 31, 91, 228, 109, 38, - 202, 23, 232, 80, 91, 230, 37, 38, 202, 23, 34, 250, 75, 202, 23, 1, 251, - 139, 202, 23, 1, 248, 161, 202, 23, 1, 231, 1, 202, 23, 1, 229, 213, 202, - 23, 1, 193, 131, 202, 23, 1, 191, 91, 202, 23, 1, 229, 152, 202, 23, 1, - 191, 249, 202, 23, 1, 222, 49, 202, 23, 1, 220, 2, 202, 23, 1, 216, 174, - 202, 23, 1, 212, 117, 202, 23, 1, 205, 143, 202, 23, 1, 250, 76, 202, 23, - 1, 210, 53, 202, 23, 1, 205, 184, 202, 23, 1, 207, 32, 202, 23, 1, 203, - 64, 202, 23, 1, 199, 154, 202, 23, 1, 232, 245, 202, 23, 1, 219, 158, - 202, 23, 223, 121, 203, 64, 202, 23, 33, 75, 60, 202, 23, 33, 103, 183, - 60, 202, 23, 33, 75, 56, 202, 23, 33, 103, 183, 56, 202, 23, 33, 238, - 118, 56, 202, 23, 33, 238, 118, 60, 202, 23, 33, 228, 219, 56, 202, 23, - 33, 228, 219, 60, 202, 23, 33, 177, 228, 219, 60, 202, 23, 33, 207, 34, - 60, 202, 23, 33, 201, 23, 60, 202, 23, 31, 108, 202, 23, 31, 199, 90, - 202, 23, 31, 197, 28, 202, 23, 31, 91, 228, 109, 202, 23, 208, 145, 103, - 81, 249, 26, 202, 23, 208, 145, 103, 81, 249, 27, 4, 236, 94, 202, 23, - 208, 145, 242, 219, 4, 236, 96, 202, 23, 208, 145, 103, 242, 216, 4, 236, - 94, 202, 23, 208, 145, 134, 242, 219, 4, 236, 96, 38, 196, 15, 1, 251, - 139, 38, 196, 15, 1, 248, 161, 38, 196, 15, 1, 231, 0, 38, 196, 15, 1, - 193, 131, 38, 196, 15, 1, 191, 91, 38, 196, 15, 1, 52, 229, 152, 38, 196, - 15, 1, 191, 249, 38, 196, 15, 1, 222, 49, 38, 196, 15, 1, 220, 2, 38, - 196, 15, 1, 216, 174, 38, 196, 15, 1, 212, 117, 38, 196, 15, 1, 205, 143, - 38, 196, 15, 1, 210, 53, 38, 196, 15, 1, 205, 184, 38, 196, 15, 1, 207, - 33, 38, 196, 15, 1, 203, 64, 38, 196, 15, 1, 199, 154, 38, 196, 15, 1, - 219, 158, 38, 196, 15, 33, 75, 56, 38, 196, 15, 33, 75, 60, 38, 196, 15, - 33, 103, 183, 56, 38, 196, 15, 33, 103, 183, 60, 38, 196, 15, 208, 145, - 164, 38, 196, 15, 208, 145, 103, 249, 26, 38, 196, 15, 208, 145, 103, - 236, 94, 38, 196, 15, 208, 145, 232, 90, 236, 94, 243, 13, 1, 251, 139, - 243, 13, 1, 2, 251, 139, 243, 13, 1, 248, 161, 243, 13, 1, 231, 1, 243, - 13, 1, 237, 205, 243, 13, 1, 229, 213, 243, 13, 1, 193, 131, 243, 13, 1, - 238, 127, 193, 131, 243, 13, 1, 191, 91, 243, 13, 1, 229, 152, 243, 13, - 1, 191, 249, 243, 13, 1, 222, 49, 243, 13, 1, 220, 2, 243, 13, 1, 216, - 174, 243, 13, 1, 212, 117, 243, 13, 1, 205, 143, 243, 13, 1, 250, 76, - 243, 13, 1, 210, 53, 243, 13, 1, 207, 33, 243, 13, 1, 203, 64, 243, 13, - 1, 199, 154, 243, 13, 31, 108, 243, 13, 31, 109, 243, 13, 31, 139, 243, - 13, 31, 137, 243, 13, 31, 199, 90, 243, 13, 31, 197, 28, 243, 13, 31, 91, - 228, 109, 234, 74, 1, 251, 139, 234, 74, 1, 248, 161, 234, 74, 1, 231, 1, - 234, 74, 1, 237, 205, 234, 74, 1, 229, 213, 234, 74, 1, 193, 131, 234, - 74, 1, 191, 91, 234, 74, 1, 229, 152, 234, 74, 1, 199, 64, 234, 74, 1, - 191, 249, 234, 74, 1, 222, 49, 234, 74, 1, 220, 2, 234, 74, 1, 216, 174, - 234, 74, 1, 212, 117, 234, 74, 1, 205, 143, 234, 74, 1, 250, 76, 234, 74, - 1, 210, 53, 234, 74, 1, 205, 184, 234, 74, 1, 208, 31, 234, 74, 1, 207, - 33, 234, 74, 1, 203, 64, 234, 74, 1, 199, 154, 234, 74, 34, 191, 90, 162, - 3, 247, 71, 162, 3, 251, 20, 162, 3, 195, 32, 162, 3, 222, 210, 162, 3, - 196, 71, 162, 1, 65, 162, 1, 252, 154, 162, 1, 70, 162, 1, 223, 170, 162, - 1, 69, 162, 1, 196, 26, 162, 1, 121, 148, 162, 1, 121, 206, 105, 162, 1, - 121, 170, 162, 1, 121, 219, 50, 162, 1, 73, 162, 1, 251, 184, 162, 1, 74, - 162, 1, 250, 113, 162, 1, 157, 162, 1, 221, 190, 162, 1, 231, 203, 162, - 1, 231, 54, 162, 1, 214, 54, 162, 1, 247, 112, 162, 1, 246, 209, 162, 1, - 223, 4, 162, 1, 222, 225, 162, 1, 212, 88, 162, 1, 197, 128, 162, 1, 197, - 116, 162, 1, 237, 146, 162, 1, 237, 130, 162, 1, 213, 66, 162, 1, 199, - 247, 162, 1, 199, 44, 162, 1, 237, 241, 162, 1, 237, 23, 162, 1, 180, - 162, 1, 168, 162, 1, 209, 219, 162, 1, 249, 103, 162, 1, 248, 153, 162, - 1, 172, 162, 1, 169, 162, 1, 166, 162, 1, 171, 162, 1, 195, 185, 162, 1, - 203, 160, 162, 1, 201, 170, 162, 1, 189, 162, 1, 144, 162, 1, 219, 49, - 162, 1, 38, 44, 219, 38, 162, 1, 38, 44, 206, 104, 162, 1, 38, 44, 213, - 48, 162, 18, 3, 252, 154, 162, 18, 3, 248, 149, 252, 154, 162, 18, 3, 70, - 162, 18, 3, 223, 170, 162, 18, 3, 69, 162, 18, 3, 196, 26, 162, 18, 3, - 121, 148, 162, 18, 3, 121, 206, 105, 162, 18, 3, 121, 170, 162, 18, 3, - 121, 219, 50, 162, 18, 3, 73, 162, 18, 3, 251, 184, 162, 18, 3, 74, 162, - 18, 3, 250, 113, 162, 195, 37, 162, 237, 193, 162, 54, 237, 193, 162, - 208, 145, 236, 96, 162, 208, 145, 54, 236, 96, 162, 208, 145, 219, 88, - 162, 208, 145, 238, 181, 164, 162, 208, 145, 218, 224, 162, 31, 108, 162, - 31, 109, 162, 31, 139, 162, 31, 137, 162, 31, 153, 162, 31, 173, 162, 31, - 181, 162, 31, 176, 162, 31, 184, 162, 31, 199, 90, 162, 31, 197, 28, 162, - 31, 198, 244, 162, 31, 232, 97, 162, 31, 232, 230, 162, 31, 202, 115, - 162, 31, 203, 236, 162, 31, 234, 110, 162, 31, 213, 156, 162, 31, 91, - 228, 109, 162, 31, 91, 188, 162, 17, 191, 77, 162, 17, 108, 162, 17, 109, - 162, 17, 139, 162, 17, 137, 162, 17, 153, 162, 17, 173, 162, 17, 181, - 162, 17, 176, 162, 17, 184, 162, 3, 38, 44, 195, 37, 162, 1, 38, 44, 203, - 35, 73, 162, 1, 38, 44, 203, 35, 74, 162, 18, 3, 38, 44, 203, 35, 73, - 162, 18, 3, 38, 44, 203, 35, 74, 162, 1, 38, 44, 219, 49, 162, 31, 222, - 169, 222, 72, 3, 247, 71, 222, 72, 3, 251, 20, 222, 72, 3, 195, 32, 222, - 72, 1, 65, 222, 72, 1, 252, 154, 222, 72, 1, 70, 222, 72, 1, 223, 170, - 222, 72, 1, 69, 222, 72, 1, 196, 26, 222, 72, 1, 73, 222, 72, 1, 251, - 184, 222, 72, 1, 74, 222, 72, 1, 250, 113, 222, 72, 1, 157, 222, 72, 1, - 221, 190, 222, 72, 1, 231, 203, 222, 72, 1, 231, 54, 222, 72, 1, 214, 54, - 222, 72, 1, 247, 112, 222, 72, 1, 246, 209, 222, 72, 1, 223, 4, 222, 72, - 1, 222, 225, 222, 72, 1, 212, 88, 222, 72, 1, 197, 128, 222, 72, 1, 197, - 116, 222, 72, 1, 237, 146, 222, 72, 1, 237, 135, 222, 72, 1, 237, 130, - 222, 72, 1, 207, 1, 222, 72, 1, 213, 66, 222, 72, 1, 199, 247, 222, 72, - 1, 199, 44, 222, 72, 1, 237, 241, 222, 72, 1, 237, 23, 222, 72, 1, 180, - 222, 72, 1, 168, 222, 72, 1, 209, 219, 222, 72, 1, 249, 103, 222, 72, 1, - 248, 153, 222, 72, 1, 172, 222, 72, 1, 169, 222, 72, 1, 166, 222, 72, 1, - 171, 222, 72, 1, 195, 185, 222, 72, 1, 203, 160, 222, 72, 1, 201, 170, - 222, 72, 1, 189, 222, 72, 1, 144, 222, 72, 18, 3, 252, 154, 222, 72, 18, - 3, 70, 222, 72, 18, 3, 223, 170, 222, 72, 18, 3, 69, 222, 72, 18, 3, 196, - 26, 222, 72, 18, 3, 73, 222, 72, 18, 3, 251, 184, 222, 72, 18, 3, 74, - 222, 72, 18, 3, 250, 113, 222, 72, 3, 195, 37, 222, 72, 3, 212, 128, 222, - 72, 252, 16, 57, 222, 72, 234, 27, 57, 222, 72, 31, 57, 222, 72, 205, 49, - 77, 222, 72, 54, 205, 49, 77, 222, 72, 237, 193, 222, 72, 54, 237, 193, - 222, 72, 18, 3, 121, 148, 222, 72, 31, 3, 56, 202, 7, 202, 15, 1, 205, - 177, 202, 7, 202, 15, 1, 199, 214, 202, 7, 202, 15, 1, 249, 73, 202, 7, - 202, 15, 1, 247, 101, 202, 7, 202, 15, 1, 237, 221, 202, 7, 202, 15, 1, - 231, 188, 202, 7, 202, 15, 1, 217, 99, 202, 7, 202, 15, 1, 214, 51, 202, - 7, 202, 15, 1, 220, 75, 202, 7, 202, 15, 1, 214, 223, 202, 7, 202, 15, 1, - 195, 181, 202, 7, 202, 15, 1, 210, 190, 202, 7, 202, 15, 1, 192, 121, - 202, 7, 202, 15, 1, 207, 155, 202, 7, 202, 15, 1, 230, 48, 202, 7, 202, - 15, 1, 222, 77, 202, 7, 202, 15, 1, 222, 254, 202, 7, 202, 15, 1, 212, - 85, 202, 7, 202, 15, 1, 251, 193, 202, 7, 202, 15, 1, 234, 143, 202, 7, - 202, 15, 1, 223, 171, 202, 7, 202, 15, 1, 196, 137, 202, 7, 202, 15, 1, - 211, 124, 202, 7, 202, 15, 1, 234, 130, 202, 7, 202, 15, 1, 217, 115, - 202, 7, 202, 15, 17, 191, 77, 202, 7, 202, 15, 17, 108, 202, 7, 202, 15, - 17, 109, 202, 7, 202, 15, 17, 139, 202, 7, 202, 15, 17, 137, 202, 7, 202, - 15, 17, 153, 202, 7, 202, 15, 17, 173, 202, 7, 202, 15, 17, 181, 202, 7, - 202, 15, 17, 176, 202, 7, 202, 15, 17, 184, 246, 203, 3, 247, 71, 246, - 203, 3, 251, 20, 246, 203, 3, 195, 32, 246, 203, 1, 252, 154, 246, 203, - 1, 70, 246, 203, 1, 69, 246, 203, 1, 73, 246, 203, 1, 222, 100, 246, 203, - 1, 221, 189, 246, 203, 1, 231, 200, 246, 203, 1, 231, 53, 246, 203, 1, - 214, 53, 246, 203, 1, 247, 111, 246, 203, 1, 246, 208, 246, 203, 1, 223, - 3, 246, 203, 1, 222, 224, 246, 203, 1, 212, 87, 246, 203, 1, 197, 127, - 246, 203, 1, 197, 115, 246, 203, 1, 237, 145, 246, 203, 1, 237, 129, 246, - 203, 1, 213, 65, 246, 203, 1, 199, 240, 246, 203, 1, 199, 43, 246, 203, - 1, 237, 240, 246, 203, 1, 237, 22, 246, 203, 1, 214, 236, 246, 203, 1, - 210, 210, 246, 203, 1, 209, 218, 246, 203, 1, 249, 101, 246, 203, 1, 248, - 152, 246, 203, 1, 217, 130, 246, 203, 1, 191, 174, 246, 203, 1, 192, 140, - 246, 203, 1, 207, 173, 246, 203, 1, 220, 101, 246, 203, 1, 193, 178, 246, - 203, 1, 205, 192, 246, 203, 1, 230, 58, 246, 203, 18, 3, 65, 246, 203, - 18, 3, 70, 246, 203, 18, 3, 223, 170, 246, 203, 18, 3, 69, 246, 203, 18, - 3, 196, 26, 246, 203, 18, 3, 73, 246, 203, 18, 3, 251, 184, 246, 203, 18, - 3, 74, 246, 203, 18, 3, 250, 113, 246, 203, 18, 3, 211, 121, 246, 203, - 186, 77, 246, 203, 250, 114, 77, 246, 203, 195, 37, 246, 203, 217, 128, - 246, 203, 17, 191, 77, 246, 203, 17, 108, 246, 203, 17, 109, 246, 203, - 17, 139, 246, 203, 17, 137, 246, 203, 17, 153, 246, 203, 17, 173, 246, - 203, 17, 181, 246, 203, 17, 176, 246, 203, 17, 184, 246, 203, 205, 49, - 77, 246, 203, 237, 193, 246, 203, 54, 237, 193, 246, 203, 208, 8, 77, - 246, 203, 1, 219, 134, 246, 203, 18, 3, 252, 154, 246, 203, 18, 3, 234, - 123, 246, 203, 1, 195, 184, 217, 97, 1, 65, 217, 97, 1, 70, 217, 97, 1, - 69, 217, 97, 1, 73, 217, 97, 1, 74, 217, 97, 1, 157, 217, 97, 1, 221, - 190, 217, 97, 1, 231, 203, 217, 97, 1, 231, 54, 217, 97, 1, 247, 112, - 217, 97, 1, 246, 209, 217, 97, 1, 223, 4, 217, 97, 1, 222, 225, 217, 97, - 1, 212, 88, 217, 97, 1, 197, 128, 217, 97, 1, 197, 116, 217, 97, 1, 237, - 146, 217, 97, 1, 237, 130, 217, 97, 1, 213, 66, 217, 97, 1, 199, 247, - 217, 97, 1, 199, 44, 217, 97, 1, 237, 241, 217, 97, 1, 237, 23, 217, 97, - 1, 180, 217, 97, 1, 168, 217, 97, 1, 209, 219, 217, 97, 1, 249, 103, 217, - 97, 1, 248, 153, 217, 97, 1, 172, 217, 97, 1, 166, 217, 97, 1, 171, 217, - 97, 1, 195, 185, 217, 97, 1, 189, 217, 97, 1, 144, 217, 97, 1, 206, 104, - 217, 97, 3, 212, 128, 217, 97, 252, 16, 57, 217, 97, 205, 49, 77, 217, - 97, 34, 203, 10, 203, 124, 3, 247, 71, 203, 124, 3, 251, 20, 203, 124, 3, - 195, 32, 203, 124, 1, 65, 203, 124, 1, 252, 154, 203, 124, 1, 70, 203, - 124, 1, 223, 170, 203, 124, 1, 69, 203, 124, 1, 196, 26, 203, 124, 1, - 121, 148, 203, 124, 1, 121, 206, 105, 203, 124, 1, 121, 170, 203, 124, 1, - 121, 219, 50, 203, 124, 1, 73, 203, 124, 1, 251, 184, 203, 124, 1, 74, - 203, 124, 1, 250, 113, 203, 124, 1, 157, 203, 124, 1, 221, 190, 203, 124, - 1, 231, 203, 203, 124, 1, 231, 54, 203, 124, 1, 214, 54, 203, 124, 1, - 247, 112, 203, 124, 1, 246, 209, 203, 124, 1, 223, 4, 203, 124, 1, 222, - 225, 203, 124, 1, 212, 88, 203, 124, 1, 197, 128, 203, 124, 1, 197, 116, - 203, 124, 1, 237, 146, 203, 124, 1, 237, 130, 203, 124, 1, 213, 66, 203, - 124, 1, 199, 247, 203, 124, 1, 199, 44, 203, 124, 1, 237, 241, 203, 124, - 1, 237, 23, 203, 124, 1, 180, 203, 124, 1, 168, 203, 124, 1, 209, 219, - 203, 124, 1, 249, 103, 203, 124, 1, 248, 153, 203, 124, 1, 172, 203, 124, - 1, 169, 203, 124, 1, 166, 203, 124, 1, 171, 203, 124, 1, 219, 49, 203, - 124, 1, 195, 185, 203, 124, 1, 203, 160, 203, 124, 1, 201, 170, 203, 124, - 1, 189, 203, 124, 1, 144, 203, 124, 18, 3, 252, 154, 203, 124, 18, 3, 70, - 203, 124, 18, 3, 223, 170, 203, 124, 18, 3, 69, 203, 124, 18, 3, 196, 26, - 203, 124, 18, 3, 121, 148, 203, 124, 18, 3, 121, 206, 105, 203, 124, 18, - 3, 121, 170, 203, 124, 18, 3, 121, 219, 50, 203, 124, 18, 3, 73, 203, - 124, 18, 3, 251, 184, 203, 124, 18, 3, 74, 203, 124, 18, 3, 250, 113, - 203, 124, 3, 195, 37, 203, 124, 3, 250, 95, 203, 124, 3, 222, 210, 203, - 124, 3, 196, 71, 203, 124, 211, 102, 203, 124, 237, 193, 203, 124, 54, - 237, 193, 203, 124, 252, 16, 57, 203, 124, 204, 5, 203, 124, 205, 133, - 77, 203, 124, 3, 212, 128, 203, 124, 18, 59, 77, 203, 124, 233, 160, 203, - 35, 18, 77, 203, 124, 200, 157, 77, 203, 124, 18, 3, 208, 200, 73, 203, - 124, 3, 223, 65, 247, 71, 203, 124, 17, 191, 77, 203, 124, 17, 108, 203, - 124, 17, 109, 203, 124, 17, 139, 203, 124, 17, 137, 203, 124, 17, 153, - 203, 124, 17, 173, 203, 124, 17, 181, 203, 124, 17, 176, 203, 124, 17, - 184, 203, 124, 234, 103, 203, 124, 3, 202, 205, 203, 124, 229, 195, 203, - 124, 238, 238, 57, 203, 124, 205, 49, 217, 36, 203, 124, 205, 49, 217, - 35, 165, 250, 220, 17, 108, 165, 250, 220, 17, 109, 165, 250, 220, 17, - 139, 165, 250, 220, 17, 137, 165, 250, 220, 17, 153, 165, 250, 220, 17, - 173, 165, 250, 220, 17, 181, 165, 250, 220, 17, 176, 165, 250, 220, 17, - 184, 165, 250, 220, 31, 199, 90, 165, 250, 220, 31, 197, 28, 165, 250, - 220, 31, 198, 244, 165, 250, 220, 31, 232, 97, 165, 250, 220, 31, 232, - 230, 165, 250, 220, 31, 202, 115, 165, 250, 220, 31, 203, 236, 165, 250, - 220, 31, 234, 110, 165, 250, 220, 31, 213, 156, 165, 250, 220, 31, 91, - 228, 109, 165, 250, 220, 31, 91, 188, 221, 158, 1, 65, 221, 158, 1, 252, - 154, 221, 158, 1, 70, 221, 158, 1, 69, 221, 158, 1, 73, 221, 158, 1, 251, - 184, 221, 158, 1, 74, 221, 158, 1, 250, 113, 221, 158, 1, 157, 221, 158, - 1, 221, 190, 221, 158, 1, 231, 203, 221, 158, 1, 231, 90, 221, 158, 1, - 231, 54, 221, 158, 1, 214, 54, 221, 158, 1, 247, 112, 221, 158, 1, 246, - 209, 221, 158, 1, 223, 4, 221, 158, 1, 222, 203, 221, 158, 1, 212, 88, - 221, 158, 1, 197, 128, 221, 158, 1, 197, 116, 221, 158, 1, 237, 146, 221, - 158, 1, 237, 130, 221, 158, 1, 213, 66, 221, 158, 1, 199, 247, 221, 158, - 1, 199, 44, 221, 158, 1, 237, 241, 221, 158, 1, 237, 136, 221, 158, 1, - 237, 23, 221, 158, 1, 180, 221, 158, 1, 168, 221, 158, 1, 209, 219, 221, - 158, 1, 249, 103, 221, 158, 1, 249, 3, 221, 158, 1, 248, 153, 221, 158, - 1, 172, 221, 158, 1, 169, 221, 158, 1, 166, 221, 158, 1, 171, 221, 158, - 1, 195, 185, 221, 158, 1, 189, 221, 158, 1, 144, 221, 158, 1, 219, 49, - 221, 158, 18, 3, 252, 154, 221, 158, 18, 3, 70, 221, 158, 18, 3, 223, - 170, 221, 158, 18, 3, 69, 221, 158, 18, 3, 73, 221, 158, 18, 3, 251, 184, - 221, 158, 18, 3, 74, 221, 158, 18, 3, 250, 113, 221, 158, 3, 251, 20, - 221, 158, 3, 195, 37, 221, 158, 3, 212, 128, 221, 158, 3, 203, 150, 221, - 158, 237, 193, 221, 158, 54, 237, 193, 221, 158, 193, 23, 204, 5, 221, - 158, 205, 49, 77, 221, 158, 54, 205, 49, 77, 221, 158, 252, 16, 57, 221, - 158, 3, 200, 201, 215, 118, 1, 65, 215, 118, 1, 70, 215, 118, 1, 69, 215, - 118, 1, 73, 215, 118, 1, 157, 215, 118, 1, 221, 190, 215, 118, 1, 231, - 203, 215, 118, 1, 231, 54, 215, 118, 1, 247, 112, 215, 118, 1, 246, 209, - 215, 118, 1, 223, 4, 215, 118, 1, 222, 203, 215, 118, 1, 212, 88, 215, - 118, 1, 197, 128, 215, 118, 1, 197, 116, 215, 118, 1, 237, 146, 215, 118, - 1, 237, 136, 215, 118, 1, 237, 130, 215, 118, 1, 213, 66, 215, 118, 1, - 199, 247, 215, 118, 1, 199, 44, 215, 118, 1, 237, 241, 215, 118, 1, 237, - 23, 215, 118, 1, 180, 215, 118, 1, 168, 215, 118, 1, 209, 219, 215, 118, - 1, 249, 103, 215, 118, 1, 248, 153, 215, 118, 1, 172, 215, 118, 1, 169, - 215, 118, 1, 166, 215, 118, 1, 171, 215, 118, 1, 195, 185, 215, 118, 1, - 189, 215, 118, 1, 144, 215, 118, 1, 206, 104, 215, 118, 1, 207, 1, 215, - 118, 205, 49, 77, 221, 148, 1, 65, 221, 148, 1, 252, 154, 221, 148, 1, - 70, 221, 148, 1, 223, 170, 221, 148, 1, 69, 221, 148, 1, 196, 26, 221, - 148, 1, 73, 221, 148, 1, 251, 184, 221, 148, 1, 74, 221, 148, 1, 250, - 113, 221, 148, 1, 157, 221, 148, 1, 221, 190, 221, 148, 1, 231, 203, 221, - 148, 1, 231, 90, 221, 148, 1, 231, 54, 221, 148, 1, 214, 54, 221, 148, 1, - 247, 112, 221, 148, 1, 246, 209, 221, 148, 1, 223, 4, 221, 148, 1, 222, - 203, 221, 148, 1, 222, 225, 221, 148, 1, 212, 88, 221, 148, 1, 197, 128, - 221, 148, 1, 197, 116, 221, 148, 1, 237, 146, 221, 148, 1, 237, 136, 221, - 148, 1, 206, 104, 221, 148, 1, 237, 130, 221, 148, 1, 213, 66, 221, 148, - 1, 199, 247, 221, 148, 1, 199, 44, 221, 148, 1, 237, 241, 221, 148, 1, - 237, 23, 221, 148, 1, 180, 221, 148, 1, 168, 221, 148, 1, 209, 219, 221, - 148, 1, 249, 103, 221, 148, 1, 249, 3, 221, 148, 1, 248, 153, 221, 148, - 1, 172, 221, 148, 1, 169, 221, 148, 1, 166, 221, 148, 1, 171, 221, 148, - 1, 195, 185, 221, 148, 1, 203, 160, 221, 148, 1, 189, 221, 148, 1, 144, - 221, 148, 3, 251, 20, 221, 148, 18, 3, 252, 154, 221, 148, 18, 3, 70, - 221, 148, 18, 3, 223, 170, 221, 148, 18, 3, 69, 221, 148, 18, 3, 196, 26, - 221, 148, 18, 3, 73, 221, 148, 18, 3, 251, 184, 221, 148, 18, 3, 74, 221, - 148, 18, 3, 250, 113, 221, 148, 3, 212, 128, 221, 148, 3, 195, 37, 221, - 148, 17, 191, 77, 221, 148, 17, 108, 221, 148, 17, 109, 221, 148, 17, - 139, 221, 148, 17, 137, 221, 148, 17, 153, 221, 148, 17, 173, 221, 148, - 17, 181, 221, 148, 17, 176, 221, 148, 17, 184, 230, 185, 3, 33, 251, 21, - 56, 230, 185, 3, 247, 71, 230, 185, 3, 251, 20, 230, 185, 3, 195, 32, - 230, 185, 1, 65, 230, 185, 1, 252, 154, 230, 185, 1, 70, 230, 185, 1, - 223, 170, 230, 185, 1, 69, 230, 185, 1, 196, 26, 230, 185, 1, 121, 148, - 230, 185, 1, 121, 170, 230, 185, 1, 234, 145, 230, 185, 1, 251, 184, 230, - 185, 1, 211, 76, 230, 185, 1, 250, 113, 230, 185, 1, 157, 230, 185, 1, - 221, 190, 230, 185, 1, 231, 203, 230, 185, 1, 231, 54, 230, 185, 1, 214, - 54, 230, 185, 1, 247, 112, 230, 185, 1, 246, 209, 230, 185, 1, 223, 4, - 230, 185, 1, 222, 225, 230, 185, 1, 212, 88, 230, 185, 1, 197, 128, 230, - 185, 1, 197, 116, 230, 185, 1, 237, 146, 230, 185, 1, 237, 130, 230, 185, - 1, 213, 66, 230, 185, 1, 199, 247, 230, 185, 1, 199, 44, 230, 185, 1, - 237, 241, 230, 185, 1, 237, 23, 230, 185, 1, 180, 230, 185, 1, 168, 230, - 185, 1, 209, 219, 230, 185, 1, 249, 103, 230, 185, 1, 248, 153, 230, 185, - 1, 172, 230, 185, 1, 169, 230, 185, 1, 166, 230, 185, 1, 171, 230, 185, - 1, 219, 49, 230, 185, 1, 195, 185, 230, 185, 1, 203, 160, 230, 185, 1, - 201, 170, 230, 185, 1, 189, 230, 185, 1, 144, 33, 248, 117, 60, 230, 185, - 3, 212, 128, 230, 185, 3, 250, 95, 230, 185, 18, 3, 252, 154, 230, 185, - 18, 3, 70, 230, 185, 18, 3, 223, 170, 230, 185, 18, 3, 69, 230, 185, 18, - 3, 196, 26, 230, 185, 18, 3, 121, 148, 230, 185, 18, 3, 121, 206, 105, - 230, 185, 18, 3, 234, 145, 230, 185, 18, 3, 251, 184, 230, 185, 18, 3, - 211, 76, 230, 185, 18, 3, 250, 113, 230, 185, 3, 195, 37, 230, 185, 211, - 102, 230, 185, 250, 114, 219, 174, 77, 230, 185, 3, 209, 71, 230, 185, 1, - 195, 147, 251, 20, 230, 185, 1, 195, 147, 54, 251, 20, 230, 185, 1, 121, - 206, 105, 230, 185, 1, 121, 219, 50, 230, 185, 18, 3, 121, 170, 230, 185, - 18, 3, 121, 219, 50, 33, 230, 185, 17, 191, 77, 33, 230, 185, 17, 108, - 33, 230, 185, 17, 109, 33, 230, 185, 17, 139, 33, 230, 185, 17, 137, 33, - 230, 185, 17, 153, 33, 230, 185, 17, 173, 33, 230, 185, 1, 65, 33, 230, - 185, 1, 157, 33, 230, 185, 1, 180, 33, 230, 185, 1, 195, 66, 33, 230, - 185, 1, 168, 214, 64, 1, 65, 214, 64, 1, 252, 154, 214, 64, 1, 70, 214, - 64, 1, 223, 170, 214, 64, 1, 69, 214, 64, 1, 196, 26, 214, 64, 1, 121, - 148, 214, 64, 1, 121, 206, 105, 214, 64, 1, 121, 170, 214, 64, 1, 121, - 219, 50, 214, 64, 1, 73, 214, 64, 1, 251, 184, 214, 64, 1, 74, 214, 64, - 1, 250, 113, 214, 64, 1, 157, 214, 64, 1, 221, 190, 214, 64, 1, 231, 203, - 214, 64, 1, 231, 54, 214, 64, 1, 214, 54, 214, 64, 1, 214, 3, 214, 64, 1, - 247, 112, 214, 64, 1, 246, 209, 214, 64, 1, 223, 4, 214, 64, 1, 222, 225, - 214, 64, 1, 212, 88, 214, 64, 1, 212, 70, 214, 64, 1, 197, 128, 214, 64, - 1, 197, 116, 214, 64, 1, 237, 146, 214, 64, 1, 237, 130, 214, 64, 1, 213, - 66, 214, 64, 1, 199, 247, 214, 64, 1, 199, 44, 214, 64, 1, 237, 241, 214, - 64, 1, 237, 23, 214, 64, 1, 180, 214, 64, 1, 213, 210, 214, 64, 1, 168, - 214, 64, 1, 209, 219, 214, 64, 1, 249, 103, 214, 64, 1, 248, 153, 214, - 64, 1, 172, 214, 64, 1, 216, 84, 214, 64, 1, 169, 214, 64, 1, 166, 214, - 64, 1, 207, 1, 214, 64, 1, 171, 214, 64, 1, 219, 135, 214, 64, 1, 193, - 187, 214, 64, 1, 203, 160, 214, 64, 1, 201, 170, 214, 64, 1, 189, 214, - 64, 1, 144, 214, 64, 18, 3, 252, 154, 214, 64, 18, 3, 70, 214, 64, 18, 3, - 223, 170, 214, 64, 18, 3, 69, 214, 64, 18, 3, 196, 26, 214, 64, 18, 3, - 121, 148, 214, 64, 18, 3, 121, 206, 105, 214, 64, 18, 3, 121, 170, 214, - 64, 18, 3, 121, 219, 50, 214, 64, 18, 3, 73, 214, 64, 18, 3, 251, 184, - 214, 64, 18, 3, 74, 214, 64, 18, 3, 250, 113, 214, 64, 3, 195, 37, 214, - 64, 3, 247, 71, 214, 64, 3, 251, 20, 214, 64, 3, 195, 32, 214, 64, 3, - 212, 128, 214, 64, 3, 250, 95, 214, 64, 3, 52, 251, 20, 214, 64, 211, - 102, 214, 64, 202, 204, 214, 64, 237, 193, 214, 64, 54, 237, 193, 214, - 64, 242, 26, 214, 64, 231, 167, 232, 218, 214, 64, 252, 16, 57, 214, 64, - 17, 191, 77, 214, 64, 17, 108, 214, 64, 17, 109, 214, 64, 17, 139, 214, - 64, 17, 137, 214, 64, 17, 153, 214, 64, 17, 173, 214, 64, 17, 181, 214, - 64, 17, 176, 214, 64, 17, 184, 214, 64, 54, 242, 26, 214, 64, 209, 99, - 77, 214, 64, 223, 91, 57, 214, 64, 205, 133, 77, 214, 64, 1, 195, 147, - 251, 20, 214, 64, 3, 222, 210, 214, 64, 3, 196, 71, 198, 124, 251, 49, - 198, 124, 1, 65, 198, 124, 1, 252, 154, 198, 124, 1, 70, 198, 124, 1, - 223, 170, 198, 124, 1, 69, 198, 124, 1, 196, 26, 198, 124, 1, 121, 148, - 198, 124, 1, 121, 206, 105, 198, 124, 1, 121, 170, 198, 124, 1, 121, 219, - 50, 198, 124, 1, 73, 198, 124, 1, 251, 184, 198, 124, 1, 74, 198, 124, 1, - 250, 113, 198, 124, 1, 157, 198, 124, 1, 221, 190, 198, 124, 1, 231, 203, - 198, 124, 1, 231, 54, 198, 124, 1, 214, 54, 198, 124, 1, 247, 112, 198, - 124, 1, 246, 209, 198, 124, 1, 223, 4, 198, 124, 1, 222, 225, 198, 124, - 1, 212, 88, 198, 124, 1, 197, 128, 198, 124, 1, 197, 116, 198, 124, 1, - 237, 146, 198, 124, 1, 237, 130, 198, 124, 1, 213, 66, 198, 124, 1, 199, - 247, 198, 124, 1, 199, 44, 198, 124, 1, 237, 241, 198, 124, 1, 237, 23, - 198, 124, 1, 180, 198, 124, 1, 168, 198, 124, 1, 209, 219, 198, 124, 1, - 249, 103, 198, 124, 1, 248, 153, 198, 124, 1, 172, 198, 124, 1, 169, 198, - 124, 1, 166, 198, 124, 1, 171, 198, 124, 1, 195, 185, 198, 124, 1, 203, - 160, 198, 124, 1, 201, 170, 198, 124, 1, 189, 198, 124, 1, 144, 198, 124, - 18, 3, 252, 154, 198, 124, 18, 3, 70, 198, 124, 18, 3, 223, 170, 198, - 124, 18, 3, 69, 198, 124, 18, 3, 196, 26, 198, 124, 18, 3, 121, 148, 198, - 124, 18, 3, 121, 206, 105, 198, 124, 18, 3, 121, 170, 198, 124, 18, 3, - 121, 219, 50, 198, 124, 18, 3, 73, 198, 124, 18, 3, 203, 35, 73, 198, - 124, 18, 3, 251, 184, 198, 124, 18, 3, 74, 198, 124, 18, 3, 203, 35, 74, - 198, 124, 18, 3, 250, 113, 198, 124, 3, 247, 71, 198, 124, 3, 251, 20, - 198, 124, 3, 195, 32, 198, 124, 3, 195, 37, 198, 124, 3, 212, 128, 198, - 124, 3, 250, 95, 198, 124, 230, 104, 198, 124, 252, 16, 57, 198, 124, - 211, 102, 198, 124, 17, 191, 77, 198, 124, 17, 108, 198, 124, 17, 109, - 198, 124, 17, 139, 198, 124, 17, 137, 198, 124, 17, 153, 198, 124, 17, - 173, 198, 124, 17, 181, 198, 124, 17, 176, 198, 124, 17, 184, 202, 206, - 1, 65, 202, 206, 1, 252, 154, 202, 206, 1, 70, 202, 206, 1, 223, 170, - 202, 206, 1, 69, 202, 206, 1, 196, 26, 202, 206, 1, 121, 148, 202, 206, - 1, 121, 206, 105, 202, 206, 1, 121, 170, 202, 206, 1, 121, 219, 50, 202, - 206, 1, 73, 202, 206, 1, 251, 184, 202, 206, 1, 74, 202, 206, 1, 250, - 113, 202, 206, 1, 157, 202, 206, 1, 221, 190, 202, 206, 1, 231, 203, 202, - 206, 1, 231, 54, 202, 206, 1, 214, 54, 202, 206, 1, 247, 112, 202, 206, - 1, 246, 209, 202, 206, 1, 223, 4, 202, 206, 1, 222, 225, 202, 206, 1, - 212, 88, 202, 206, 1, 197, 128, 202, 206, 1, 197, 116, 202, 206, 1, 237, - 146, 202, 206, 1, 237, 130, 202, 206, 1, 213, 66, 202, 206, 1, 199, 247, - 202, 206, 1, 199, 44, 202, 206, 1, 237, 241, 202, 206, 1, 237, 23, 202, - 206, 1, 180, 202, 206, 1, 168, 202, 206, 1, 209, 219, 202, 206, 1, 249, - 103, 202, 206, 1, 248, 153, 202, 206, 1, 172, 202, 206, 1, 169, 202, 206, - 1, 166, 202, 206, 1, 171, 202, 206, 1, 195, 185, 202, 206, 1, 203, 160, - 202, 206, 1, 201, 170, 202, 206, 1, 189, 202, 206, 1, 144, 202, 206, 18, - 3, 252, 154, 202, 206, 18, 3, 70, 202, 206, 18, 3, 223, 170, 202, 206, - 18, 3, 69, 202, 206, 18, 3, 196, 26, 202, 206, 18, 3, 121, 148, 202, 206, - 18, 3, 121, 206, 105, 202, 206, 18, 3, 73, 202, 206, 18, 3, 251, 184, - 202, 206, 18, 3, 74, 202, 206, 18, 3, 250, 113, 202, 206, 3, 247, 71, - 202, 206, 3, 251, 20, 202, 206, 3, 195, 32, 202, 206, 3, 195, 37, 202, - 206, 3, 212, 128, 202, 206, 3, 202, 205, 202, 206, 237, 193, 202, 206, - 54, 237, 193, 202, 206, 204, 6, 236, 96, 202, 206, 204, 6, 164, 202, 206, - 207, 41, 217, 36, 202, 206, 207, 41, 217, 35, 202, 206, 207, 41, 217, 34, - 202, 206, 234, 53, 80, 199, 49, 77, 202, 206, 205, 49, 87, 4, 197, 232, - 24, 196, 217, 211, 31, 202, 206, 205, 49, 87, 4, 197, 232, 24, 235, 94, - 238, 179, 202, 206, 205, 49, 87, 4, 207, 115, 24, 235, 94, 238, 179, 202, - 206, 205, 49, 87, 4, 207, 115, 24, 235, 94, 54, 238, 179, 202, 206, 205, - 49, 87, 4, 207, 115, 24, 235, 94, 197, 221, 238, 179, 202, 206, 205, 49, - 87, 54, 206, 183, 202, 206, 205, 49, 87, 54, 206, 184, 4, 207, 114, 202, - 206, 205, 49, 87, 4, 54, 238, 179, 202, 206, 205, 49, 87, 4, 197, 221, - 238, 179, 202, 206, 205, 49, 87, 4, 208, 20, 238, 179, 202, 206, 205, 49, - 87, 4, 204, 3, 238, 179, 202, 206, 205, 49, 87, 4, 242, 216, 24, 207, - 114, 202, 206, 205, 49, 87, 4, 242, 216, 24, 103, 234, 55, 202, 206, 205, - 49, 87, 4, 242, 216, 24, 232, 90, 234, 55, 202, 206, 1, 198, 221, 251, - 106, 70, 202, 206, 1, 197, 11, 251, 106, 70, 202, 206, 1, 197, 11, 251, - 106, 223, 170, 202, 206, 1, 251, 106, 69, 202, 206, 18, 3, 251, 106, 69, - 202, 206, 18, 3, 251, 106, 196, 26, 215, 236, 1, 65, 215, 236, 1, 252, - 154, 215, 236, 1, 70, 215, 236, 1, 223, 170, 215, 236, 1, 69, 215, 236, - 1, 196, 26, 215, 236, 1, 121, 148, 215, 236, 1, 121, 206, 105, 215, 236, - 1, 121, 170, 215, 236, 1, 121, 219, 50, 215, 236, 1, 73, 215, 236, 1, - 251, 184, 215, 236, 1, 74, 215, 236, 1, 250, 113, 215, 236, 1, 157, 215, - 236, 1, 221, 190, 215, 236, 1, 231, 203, 215, 236, 1, 231, 54, 215, 236, - 1, 214, 54, 215, 236, 1, 247, 112, 215, 236, 1, 246, 209, 215, 236, 1, - 223, 4, 215, 236, 1, 222, 225, 215, 236, 1, 212, 88, 215, 236, 1, 197, - 128, 215, 236, 1, 197, 116, 215, 236, 1, 237, 146, 215, 236, 1, 237, 130, - 215, 236, 1, 213, 66, 215, 236, 1, 199, 247, 215, 236, 1, 199, 44, 215, - 236, 1, 237, 241, 215, 236, 1, 237, 23, 215, 236, 1, 180, 215, 236, 1, - 168, 215, 236, 1, 209, 219, 215, 236, 1, 249, 103, 215, 236, 1, 248, 153, - 215, 236, 1, 172, 215, 236, 1, 169, 215, 236, 1, 166, 215, 236, 1, 171, - 215, 236, 1, 195, 185, 215, 236, 1, 203, 160, 215, 236, 1, 201, 170, 215, - 236, 1, 189, 215, 236, 1, 144, 215, 236, 1, 219, 49, 215, 236, 18, 3, - 252, 154, 215, 236, 18, 3, 70, 215, 236, 18, 3, 223, 170, 215, 236, 18, - 3, 69, 215, 236, 18, 3, 196, 26, 215, 236, 18, 3, 121, 148, 215, 236, 18, - 3, 121, 206, 105, 215, 236, 18, 3, 121, 170, 215, 236, 18, 3, 121, 219, - 50, 215, 236, 18, 3, 73, 215, 236, 18, 3, 251, 184, 215, 236, 18, 3, 74, - 215, 236, 18, 3, 250, 113, 215, 236, 3, 251, 20, 215, 236, 3, 195, 32, - 215, 236, 3, 195, 37, 215, 236, 3, 250, 217, 215, 236, 237, 193, 215, - 236, 54, 237, 193, 215, 236, 252, 16, 57, 215, 236, 3, 228, 96, 215, 236, - 17, 191, 77, 215, 236, 17, 108, 215, 236, 17, 109, 215, 236, 17, 139, - 215, 236, 17, 137, 215, 236, 17, 153, 215, 236, 17, 173, 215, 236, 17, - 181, 215, 236, 17, 176, 215, 236, 17, 184, 102, 248, 111, 4, 211, 32, - 102, 206, 117, 248, 110, 102, 54, 248, 111, 4, 211, 32, 102, 197, 221, - 248, 111, 4, 211, 32, 102, 248, 111, 4, 54, 211, 32, 102, 206, 117, 248, - 111, 4, 211, 32, 102, 206, 117, 248, 111, 4, 54, 211, 32, 102, 223, 65, - 248, 110, 102, 223, 65, 248, 111, 4, 54, 211, 32, 102, 200, 130, 248, - 110, 102, 200, 130, 248, 111, 4, 211, 32, 102, 200, 130, 248, 111, 4, 54, - 211, 32, 102, 152, 200, 130, 248, 111, 4, 54, 211, 32, 199, 200, 1, 65, - 199, 200, 1, 252, 154, 199, 200, 1, 70, 199, 200, 1, 223, 170, 199, 200, - 1, 69, 199, 200, 1, 196, 26, 199, 200, 1, 73, 199, 200, 1, 251, 184, 199, - 200, 1, 74, 199, 200, 1, 250, 113, 199, 200, 1, 157, 199, 200, 1, 221, - 190, 199, 200, 1, 231, 203, 199, 200, 1, 231, 54, 199, 200, 1, 214, 54, - 199, 200, 1, 247, 112, 199, 200, 1, 246, 209, 199, 200, 1, 223, 4, 199, - 200, 1, 222, 225, 199, 200, 1, 212, 88, 199, 200, 1, 197, 128, 199, 200, - 1, 197, 116, 199, 200, 1, 237, 146, 199, 200, 1, 237, 130, 199, 200, 1, - 213, 66, 199, 200, 1, 199, 247, 199, 200, 1, 199, 44, 199, 200, 1, 237, - 241, 199, 200, 1, 237, 23, 199, 200, 1, 180, 199, 200, 1, 168, 199, 200, - 1, 209, 219, 199, 200, 1, 249, 103, 199, 200, 1, 248, 153, 199, 200, 1, - 172, 199, 200, 1, 169, 199, 200, 1, 166, 199, 200, 1, 171, 199, 200, 1, - 195, 185, 199, 200, 1, 203, 160, 199, 200, 1, 189, 199, 200, 1, 144, 199, - 200, 1, 206, 104, 199, 200, 3, 251, 20, 199, 200, 3, 195, 32, 199, 200, - 18, 3, 252, 154, 199, 200, 18, 3, 70, 199, 200, 18, 3, 223, 170, 199, - 200, 18, 3, 69, 199, 200, 18, 3, 196, 26, 199, 200, 18, 3, 73, 199, 200, - 18, 3, 251, 184, 199, 200, 18, 3, 74, 199, 200, 18, 3, 250, 113, 199, - 200, 3, 195, 37, 199, 200, 3, 212, 128, 199, 200, 1, 250, 220, 221, 190, - 199, 200, 252, 16, 57, 199, 200, 17, 191, 77, 199, 200, 17, 108, 199, - 200, 17, 109, 199, 200, 17, 139, 199, 200, 17, 137, 199, 200, 17, 153, - 199, 200, 17, 173, 199, 200, 17, 181, 199, 200, 17, 176, 199, 200, 17, - 184, 251, 188, 1, 157, 251, 188, 1, 221, 190, 251, 188, 1, 214, 54, 251, - 188, 1, 180, 251, 188, 1, 199, 247, 251, 188, 1, 251, 106, 199, 247, 251, - 188, 1, 168, 251, 188, 1, 209, 219, 251, 188, 1, 249, 103, 251, 188, 1, - 172, 251, 188, 1, 223, 4, 251, 188, 1, 246, 209, 251, 188, 1, 199, 44, - 251, 188, 1, 166, 251, 188, 1, 171, 251, 188, 1, 189, 251, 188, 1, 212, - 88, 251, 188, 1, 144, 251, 188, 1, 65, 251, 188, 1, 237, 241, 251, 188, - 1, 237, 23, 251, 188, 1, 231, 203, 251, 188, 1, 251, 106, 231, 203, 251, - 188, 1, 231, 54, 251, 188, 1, 248, 153, 251, 188, 1, 222, 225, 251, 188, - 1, 251, 106, 249, 103, 251, 188, 119, 3, 216, 198, 171, 251, 188, 119, 3, - 216, 198, 166, 251, 188, 119, 3, 216, 198, 219, 109, 166, 251, 188, 18, - 3, 65, 251, 188, 18, 3, 252, 154, 251, 188, 18, 3, 70, 251, 188, 18, 3, - 223, 170, 251, 188, 18, 3, 69, 251, 188, 18, 3, 196, 26, 251, 188, 18, 3, - 73, 251, 188, 18, 3, 250, 90, 251, 188, 18, 3, 74, 251, 188, 18, 3, 251, - 184, 251, 188, 18, 3, 251, 98, 251, 188, 3, 221, 119, 251, 188, 17, 191, - 77, 251, 188, 17, 108, 251, 188, 17, 109, 251, 188, 17, 139, 251, 188, - 17, 137, 251, 188, 17, 153, 251, 188, 17, 173, 251, 188, 17, 181, 251, - 188, 17, 176, 251, 188, 17, 184, 251, 188, 31, 199, 90, 251, 188, 31, - 197, 28, 251, 188, 3, 2, 205, 48, 251, 188, 3, 205, 48, 251, 188, 3, 206, - 48, 251, 188, 16, 195, 66, 251, 188, 1, 247, 112, 251, 188, 1, 197, 128, - 251, 188, 1, 197, 116, 251, 188, 1, 237, 146, 251, 188, 1, 237, 130, 251, - 188, 1, 213, 66, 251, 188, 1, 219, 49, 236, 116, 1, 65, 236, 116, 1, 252, - 154, 236, 116, 1, 70, 236, 116, 1, 223, 170, 236, 116, 1, 69, 236, 116, - 1, 196, 26, 236, 116, 1, 73, 236, 116, 1, 251, 184, 236, 116, 1, 74, 236, - 116, 1, 250, 113, 236, 116, 1, 157, 236, 116, 1, 221, 190, 236, 116, 1, - 231, 203, 236, 116, 1, 231, 54, 236, 116, 1, 214, 54, 236, 116, 1, 247, - 112, 236, 116, 1, 246, 209, 236, 116, 1, 223, 4, 236, 116, 1, 222, 225, - 236, 116, 1, 212, 88, 236, 116, 1, 197, 128, 236, 116, 1, 197, 116, 236, - 116, 1, 237, 146, 236, 116, 1, 237, 130, 236, 116, 1, 213, 66, 236, 116, - 1, 199, 247, 236, 116, 1, 199, 44, 236, 116, 1, 237, 241, 236, 116, 1, - 237, 23, 236, 116, 1, 180, 236, 116, 1, 168, 236, 116, 1, 209, 219, 236, - 116, 1, 249, 103, 236, 116, 1, 248, 153, 236, 116, 1, 172, 236, 116, 1, - 169, 236, 116, 1, 166, 236, 116, 1, 171, 236, 116, 1, 195, 185, 236, 116, - 1, 203, 160, 236, 116, 1, 201, 170, 236, 116, 1, 189, 236, 116, 1, 144, - 236, 116, 1, 206, 104, 236, 116, 18, 3, 252, 154, 236, 116, 18, 3, 70, - 236, 116, 18, 3, 223, 170, 236, 116, 18, 3, 69, 236, 116, 18, 3, 196, 26, - 236, 116, 18, 3, 121, 148, 236, 116, 18, 3, 121, 206, 105, 236, 116, 18, - 3, 73, 236, 116, 18, 3, 251, 184, 236, 116, 18, 3, 74, 236, 116, 18, 3, - 250, 113, 236, 116, 3, 251, 20, 236, 116, 3, 195, 32, 236, 116, 3, 195, - 37, 236, 116, 3, 212, 128, 236, 116, 252, 16, 57, 193, 154, 242, 205, 6, - 1, 214, 53, 193, 154, 242, 205, 6, 1, 65, 193, 154, 242, 205, 6, 1, 193, - 84, 193, 154, 242, 205, 6, 1, 191, 225, 193, 154, 242, 205, 6, 1, 169, - 193, 154, 242, 205, 6, 1, 192, 12, 193, 154, 242, 205, 6, 1, 223, 170, - 193, 154, 242, 205, 6, 1, 196, 26, 193, 154, 242, 205, 6, 1, 73, 193, - 154, 242, 205, 6, 1, 74, 193, 154, 242, 205, 6, 1, 251, 71, 193, 154, - 242, 205, 6, 1, 231, 203, 193, 154, 242, 205, 6, 1, 221, 43, 193, 154, - 242, 205, 6, 1, 234, 24, 193, 154, 242, 205, 6, 1, 191, 204, 193, 154, - 242, 205, 6, 1, 196, 156, 193, 154, 242, 205, 6, 1, 234, 43, 193, 154, - 242, 205, 6, 1, 211, 142, 193, 154, 242, 205, 6, 1, 197, 123, 193, 154, - 242, 205, 6, 1, 212, 114, 193, 154, 242, 205, 6, 1, 237, 241, 193, 154, - 242, 205, 6, 1, 250, 132, 193, 154, 242, 205, 6, 1, 251, 98, 193, 154, - 242, 205, 6, 1, 247, 218, 193, 154, 242, 205, 6, 1, 208, 158, 193, 154, - 242, 205, 6, 1, 229, 83, 193, 154, 242, 205, 6, 1, 228, 227, 193, 154, - 242, 205, 6, 1, 228, 154, 193, 154, 242, 205, 6, 1, 229, 242, 193, 154, - 242, 205, 6, 1, 201, 121, 193, 154, 242, 205, 6, 1, 202, 188, 193, 154, - 242, 205, 6, 1, 195, 22, 193, 154, 242, 205, 2, 1, 214, 53, 193, 154, - 242, 205, 2, 1, 65, 193, 154, 242, 205, 2, 1, 193, 84, 193, 154, 242, - 205, 2, 1, 191, 225, 193, 154, 242, 205, 2, 1, 169, 193, 154, 242, 205, - 2, 1, 192, 12, 193, 154, 242, 205, 2, 1, 223, 170, 193, 154, 242, 205, 2, - 1, 196, 26, 193, 154, 242, 205, 2, 1, 73, 193, 154, 242, 205, 2, 1, 74, - 193, 154, 242, 205, 2, 1, 251, 71, 193, 154, 242, 205, 2, 1, 231, 203, - 193, 154, 242, 205, 2, 1, 221, 43, 193, 154, 242, 205, 2, 1, 234, 24, - 193, 154, 242, 205, 2, 1, 191, 204, 193, 154, 242, 205, 2, 1, 196, 156, - 193, 154, 242, 205, 2, 1, 234, 43, 193, 154, 242, 205, 2, 1, 211, 142, - 193, 154, 242, 205, 2, 1, 197, 123, 193, 154, 242, 205, 2, 1, 212, 114, - 193, 154, 242, 205, 2, 1, 237, 241, 193, 154, 242, 205, 2, 1, 250, 132, - 193, 154, 242, 205, 2, 1, 251, 98, 193, 154, 242, 205, 2, 1, 247, 218, - 193, 154, 242, 205, 2, 1, 208, 158, 193, 154, 242, 205, 2, 1, 229, 83, - 193, 154, 242, 205, 2, 1, 228, 227, 193, 154, 242, 205, 2, 1, 228, 154, - 193, 154, 242, 205, 2, 1, 229, 242, 193, 154, 242, 205, 2, 1, 201, 121, - 193, 154, 242, 205, 2, 1, 202, 188, 193, 154, 242, 205, 2, 1, 195, 22, - 193, 154, 242, 205, 17, 191, 77, 193, 154, 242, 205, 17, 108, 193, 154, - 242, 205, 17, 109, 193, 154, 242, 205, 17, 139, 193, 154, 242, 205, 17, - 137, 193, 154, 242, 205, 17, 153, 193, 154, 242, 205, 17, 173, 193, 154, - 242, 205, 17, 181, 193, 154, 242, 205, 17, 176, 193, 154, 242, 205, 17, - 184, 193, 154, 242, 205, 31, 199, 90, 193, 154, 242, 205, 31, 197, 28, - 193, 154, 242, 205, 31, 198, 244, 193, 154, 242, 205, 31, 232, 97, 193, - 154, 242, 205, 31, 232, 230, 193, 154, 242, 205, 31, 202, 115, 193, 154, - 242, 205, 31, 203, 236, 193, 154, 242, 205, 31, 234, 110, 193, 154, 242, - 205, 31, 213, 156, 193, 154, 242, 205, 211, 102, 236, 164, 251, 158, 1, - 65, 236, 164, 251, 158, 1, 252, 154, 236, 164, 251, 158, 1, 70, 236, 164, - 251, 158, 1, 223, 170, 236, 164, 251, 158, 1, 69, 236, 164, 251, 158, 1, - 196, 26, 236, 164, 251, 158, 1, 73, 236, 164, 251, 158, 1, 74, 236, 164, - 251, 158, 1, 157, 236, 164, 251, 158, 1, 221, 190, 236, 164, 251, 158, 1, - 231, 203, 236, 164, 251, 158, 1, 231, 54, 236, 164, 251, 158, 1, 214, 54, - 236, 164, 251, 158, 1, 247, 112, 236, 164, 251, 158, 1, 246, 209, 236, - 164, 251, 158, 1, 223, 4, 236, 164, 251, 158, 1, 212, 88, 236, 164, 251, - 158, 1, 197, 128, 236, 164, 251, 158, 1, 237, 146, 236, 164, 251, 158, 1, - 237, 130, 236, 164, 251, 158, 1, 213, 66, 236, 164, 251, 158, 1, 199, - 247, 236, 164, 251, 158, 1, 199, 44, 236, 164, 251, 158, 1, 237, 241, - 236, 164, 251, 158, 1, 237, 23, 236, 164, 251, 158, 1, 180, 236, 164, - 251, 158, 1, 168, 236, 164, 251, 158, 1, 209, 219, 236, 164, 251, 158, 1, - 249, 103, 236, 164, 251, 158, 1, 248, 153, 236, 164, 251, 158, 1, 172, - 236, 164, 251, 158, 1, 169, 236, 164, 251, 158, 1, 191, 175, 236, 164, - 251, 158, 1, 166, 236, 164, 251, 158, 1, 171, 236, 164, 251, 158, 1, 195, - 185, 236, 164, 251, 158, 1, 203, 160, 236, 164, 251, 158, 1, 201, 170, - 236, 164, 251, 158, 1, 189, 236, 164, 251, 158, 1, 144, 236, 164, 251, - 158, 1, 219, 49, 236, 164, 251, 158, 1, 191, 123, 236, 164, 251, 158, 18, - 3, 252, 154, 236, 164, 251, 158, 18, 3, 70, 236, 164, 251, 158, 18, 3, - 223, 170, 236, 164, 251, 158, 18, 3, 69, 236, 164, 251, 158, 18, 3, 196, - 26, 236, 164, 251, 158, 18, 3, 73, 236, 164, 251, 158, 18, 3, 251, 184, - 236, 164, 251, 158, 18, 3, 74, 236, 164, 251, 158, 3, 251, 20, 236, 164, - 251, 158, 3, 247, 71, 236, 164, 251, 158, 3, 230, 39, 236, 164, 251, 158, - 195, 37, 236, 164, 251, 158, 208, 220, 214, 200, 57, 236, 164, 251, 158, - 216, 198, 169, 236, 164, 251, 158, 89, 166, 236, 164, 251, 158, 216, 198, - 166, 236, 164, 251, 158, 3, 212, 128, 236, 164, 251, 158, 54, 237, 193, - 236, 164, 251, 158, 231, 167, 232, 218, 236, 164, 251, 158, 234, 53, 80, - 199, 49, 77, 236, 164, 251, 158, 17, 191, 77, 236, 164, 251, 158, 17, - 108, 236, 164, 251, 158, 17, 109, 236, 164, 251, 158, 17, 139, 236, 164, - 251, 158, 17, 137, 236, 164, 251, 158, 17, 153, 236, 164, 251, 158, 17, - 173, 236, 164, 251, 158, 17, 181, 236, 164, 251, 158, 17, 176, 236, 164, - 251, 158, 17, 184, 214, 209, 1, 65, 214, 209, 1, 252, 154, 214, 209, 1, - 70, 214, 209, 1, 223, 170, 214, 209, 1, 69, 214, 209, 1, 196, 26, 214, - 209, 1, 121, 148, 214, 209, 1, 121, 206, 105, 214, 209, 1, 73, 214, 209, - 1, 251, 184, 214, 209, 1, 74, 214, 209, 1, 250, 113, 214, 209, 1, 157, - 214, 209, 1, 221, 190, 214, 209, 1, 231, 203, 214, 209, 1, 231, 54, 214, - 209, 1, 214, 54, 214, 209, 1, 247, 112, 214, 209, 1, 246, 209, 214, 209, - 1, 223, 4, 214, 209, 1, 222, 225, 214, 209, 1, 212, 88, 214, 209, 1, 197, - 128, 214, 209, 1, 197, 116, 214, 209, 1, 237, 146, 214, 209, 1, 237, 130, - 214, 209, 1, 213, 66, 214, 209, 1, 199, 247, 214, 209, 1, 199, 44, 214, - 209, 1, 237, 241, 214, 209, 1, 237, 23, 214, 209, 1, 180, 214, 209, 1, - 168, 214, 209, 1, 209, 219, 214, 209, 1, 249, 103, 214, 209, 1, 248, 153, - 214, 209, 1, 172, 214, 209, 1, 169, 214, 209, 1, 166, 214, 209, 1, 171, - 214, 209, 1, 195, 185, 214, 209, 1, 203, 160, 214, 209, 1, 201, 170, 214, - 209, 1, 189, 214, 209, 1, 144, 214, 209, 1, 219, 49, 214, 209, 1, 206, - 104, 214, 209, 18, 3, 252, 154, 214, 209, 18, 3, 70, 214, 209, 18, 3, - 223, 170, 214, 209, 18, 3, 69, 214, 209, 18, 3, 196, 26, 214, 209, 18, 3, - 121, 148, 214, 209, 18, 3, 121, 206, 105, 214, 209, 18, 3, 73, 214, 209, - 18, 3, 251, 184, 214, 209, 18, 3, 74, 214, 209, 18, 3, 250, 113, 214, - 209, 3, 251, 20, 214, 209, 3, 195, 32, 214, 209, 3, 195, 37, 214, 209, 3, - 250, 95, 214, 209, 3, 202, 205, 214, 209, 229, 195, 214, 209, 18, 3, 208, - 200, 73, 191, 106, 51, 1, 65, 191, 106, 51, 18, 3, 70, 191, 106, 51, 18, - 3, 196, 148, 191, 106, 51, 18, 3, 69, 191, 106, 51, 18, 3, 73, 191, 106, - 51, 18, 3, 211, 139, 191, 106, 51, 18, 3, 74, 191, 106, 51, 18, 3, 251, - 184, 191, 106, 51, 18, 3, 250, 113, 191, 106, 51, 18, 3, 207, 13, 70, - 191, 106, 51, 18, 219, 174, 77, 191, 106, 51, 1, 157, 191, 106, 51, 1, - 221, 190, 191, 106, 51, 1, 231, 203, 191, 106, 51, 1, 231, 54, 191, 106, - 51, 1, 214, 54, 191, 106, 51, 1, 247, 112, 191, 106, 51, 1, 246, 209, - 191, 106, 51, 1, 223, 4, 191, 106, 51, 1, 212, 88, 191, 106, 51, 1, 197, - 128, 191, 106, 51, 1, 197, 116, 191, 106, 51, 1, 237, 146, 191, 106, 51, - 1, 237, 130, 191, 106, 51, 1, 213, 66, 191, 106, 51, 1, 199, 247, 191, - 106, 51, 1, 199, 44, 191, 106, 51, 1, 237, 241, 191, 106, 51, 1, 237, 23, - 191, 106, 51, 1, 180, 191, 106, 51, 1, 168, 191, 106, 51, 1, 209, 219, - 191, 106, 51, 1, 249, 103, 191, 106, 51, 1, 248, 153, 191, 106, 51, 1, - 172, 191, 106, 51, 1, 197, 164, 191, 106, 51, 1, 197, 153, 191, 106, 51, - 1, 234, 247, 191, 106, 51, 1, 234, 241, 191, 106, 51, 1, 191, 71, 191, - 106, 51, 1, 191, 123, 191, 106, 51, 1, 255, 162, 191, 106, 51, 1, 169, - 191, 106, 51, 1, 166, 191, 106, 51, 1, 171, 191, 106, 51, 1, 195, 185, - 191, 106, 51, 1, 203, 160, 191, 106, 51, 1, 201, 170, 191, 106, 51, 1, - 189, 191, 106, 51, 1, 144, 191, 106, 51, 1, 220, 222, 191, 106, 51, 52, - 119, 77, 191, 106, 51, 3, 195, 37, 191, 106, 51, 3, 247, 71, 191, 106, - 51, 3, 247, 72, 4, 211, 32, 191, 106, 51, 3, 247, 74, 4, 211, 32, 191, - 106, 51, 3, 251, 20, 191, 106, 51, 3, 195, 32, 191, 106, 51, 242, 153, 1, - 166, 191, 106, 51, 242, 154, 1, 169, 191, 106, 51, 242, 154, 1, 166, 191, - 106, 51, 242, 154, 1, 171, 191, 106, 51, 242, 154, 1, 195, 185, 191, 106, - 51, 89, 229, 204, 77, 191, 106, 51, 242, 167, 229, 204, 77, 191, 106, 51, - 87, 197, 148, 191, 106, 51, 87, 203, 152, 191, 106, 51, 87, 54, 203, 152, - 191, 106, 51, 87, 177, 197, 148, 191, 106, 51, 89, 235, 86, 229, 204, 77, - 191, 106, 51, 242, 167, 235, 86, 229, 204, 77, 191, 106, 51, 200, 233, - 201, 246, 1, 65, 201, 246, 18, 3, 70, 201, 246, 18, 3, 196, 148, 201, - 246, 18, 3, 69, 201, 246, 18, 3, 73, 201, 246, 18, 3, 74, 201, 246, 18, - 3, 211, 139, 201, 246, 18, 3, 251, 184, 201, 246, 18, 3, 250, 113, 201, - 246, 18, 3, 121, 148, 201, 246, 18, 3, 121, 170, 201, 246, 18, 219, 174, - 77, 201, 246, 1, 157, 201, 246, 1, 221, 190, 201, 246, 1, 231, 203, 201, - 246, 1, 231, 54, 201, 246, 1, 214, 54, 201, 246, 1, 247, 112, 201, 246, - 1, 246, 209, 201, 246, 1, 223, 4, 201, 246, 1, 222, 225, 201, 246, 1, - 212, 88, 201, 246, 1, 197, 128, 201, 246, 1, 197, 116, 201, 246, 1, 237, - 146, 201, 246, 1, 237, 130, 201, 246, 1, 213, 66, 201, 246, 1, 199, 247, - 201, 246, 1, 199, 44, 201, 246, 1, 237, 241, 201, 246, 1, 237, 23, 201, - 246, 1, 180, 201, 246, 1, 168, 201, 246, 1, 209, 219, 201, 246, 1, 249, - 103, 201, 246, 1, 248, 153, 201, 246, 1, 172, 201, 246, 1, 197, 164, 201, - 246, 1, 197, 153, 201, 246, 1, 234, 247, 201, 246, 1, 191, 71, 201, 246, - 1, 191, 123, 201, 246, 1, 255, 162, 201, 246, 1, 169, 201, 246, 1, 166, - 201, 246, 1, 171, 201, 246, 1, 195, 185, 201, 246, 1, 203, 160, 201, 246, - 1, 201, 170, 201, 246, 1, 189, 201, 246, 1, 144, 201, 246, 1, 220, 222, - 201, 246, 3, 222, 210, 201, 246, 3, 196, 71, 201, 246, 242, 153, 1, 166, - 201, 246, 242, 153, 1, 171, 201, 246, 242, 153, 1, 203, 160, 201, 246, - 242, 153, 1, 189, 201, 246, 52, 119, 3, 232, 14, 201, 246, 52, 119, 3, - 222, 125, 201, 246, 52, 119, 3, 214, 56, 201, 246, 52, 119, 3, 238, 80, - 201, 246, 52, 119, 3, 215, 47, 201, 246, 52, 119, 3, 250, 70, 201, 246, - 52, 119, 3, 218, 147, 201, 246, 52, 119, 3, 148, 201, 246, 52, 119, 3, - 170, 201, 246, 52, 119, 3, 203, 162, 201, 246, 52, 119, 3, 206, 3, 201, - 246, 52, 119, 3, 255, 162, 201, 246, 3, 251, 20, 201, 246, 3, 195, 32, - 201, 246, 231, 116, 77, 201, 246, 200, 233, 201, 246, 87, 197, 148, 201, - 246, 87, 203, 152, 201, 246, 87, 54, 203, 152, 201, 246, 87, 209, 71, - 201, 246, 229, 204, 87, 4, 215, 189, 24, 200, 194, 24, 197, 221, 232, - 170, 201, 246, 229, 204, 87, 4, 215, 189, 24, 200, 194, 24, 232, 170, - 201, 246, 229, 204, 87, 4, 215, 189, 24, 200, 193, 201, 246, 199, 76, - 217, 36, 201, 246, 199, 76, 217, 35, 21, 22, 214, 193, 229, 126, 21, 22, - 214, 193, 229, 98, 21, 22, 214, 193, 228, 247, 21, 22, 214, 193, 228, - 220, 21, 22, 214, 193, 144, 21, 22, 214, 193, 230, 58, 21, 22, 214, 193, - 203, 10, 21, 22, 214, 193, 203, 9, 21, 22, 214, 193, 203, 6, 21, 22, 214, - 193, 203, 5, 21, 22, 214, 193, 203, 12, 21, 22, 214, 193, 203, 11, 21, - 22, 201, 232, 21, 22, 201, 219, 21, 22, 201, 202, 21, 22, 201, 244, 210, - 71, 242, 223, 229, 226, 1, 168, 210, 71, 242, 223, 229, 226, 1, 157, 210, - 71, 242, 223, 229, 226, 1, 171, 210, 71, 242, 223, 229, 226, 1, 172, 210, - 71, 242, 223, 229, 226, 1, 237, 241, 210, 71, 242, 223, 229, 226, 1, 191, - 123, 210, 71, 242, 223, 229, 226, 1, 195, 185, 210, 71, 242, 223, 229, - 226, 1, 214, 54, 210, 71, 242, 223, 229, 226, 1, 144, 210, 71, 242, 223, - 229, 226, 1, 231, 203, 210, 71, 242, 223, 229, 226, 1, 221, 190, 210, 71, - 242, 223, 229, 226, 1, 189, 210, 71, 242, 223, 229, 226, 1, 249, 103, - 210, 71, 242, 223, 229, 226, 1, 247, 112, 210, 71, 242, 223, 229, 226, 1, - 199, 247, 210, 71, 242, 223, 229, 226, 1, 199, 44, 210, 71, 242, 223, - 229, 226, 1, 180, 210, 71, 242, 223, 229, 226, 1, 209, 219, 210, 71, 242, - 223, 229, 226, 1, 166, 210, 71, 242, 223, 229, 226, 1, 233, 68, 210, 71, - 242, 223, 229, 226, 1, 246, 209, 210, 71, 242, 223, 229, 226, 1, 65, 210, - 71, 242, 223, 229, 226, 1, 73, 210, 71, 242, 223, 229, 226, 1, 70, 210, - 71, 242, 223, 229, 226, 1, 74, 210, 71, 242, 223, 229, 226, 1, 69, 210, - 71, 242, 223, 229, 226, 1, 196, 164, 210, 71, 242, 223, 229, 226, 1, 228, - 5, 210, 71, 242, 223, 229, 226, 1, 52, 210, 226, 210, 71, 242, 223, 229, - 226, 1, 52, 222, 125, 210, 71, 242, 223, 229, 226, 1, 52, 200, 39, 210, - 71, 242, 223, 229, 226, 1, 52, 218, 147, 210, 71, 242, 223, 229, 226, 1, - 52, 215, 47, 210, 71, 242, 223, 229, 226, 1, 52, 170, 210, 71, 242, 223, - 229, 226, 1, 52, 193, 221, 210, 71, 242, 223, 229, 226, 1, 52, 214, 56, - 210, 71, 242, 223, 229, 226, 1, 52, 192, 159, 210, 71, 242, 223, 229, - 226, 206, 175, 163, 218, 251, 210, 71, 242, 223, 229, 226, 206, 175, 198, - 74, 210, 71, 242, 223, 229, 226, 205, 133, 230, 231, 201, 58, 210, 71, - 242, 223, 229, 226, 206, 175, 163, 177, 232, 214, 210, 71, 242, 223, 229, - 226, 206, 175, 163, 232, 214, 210, 71, 242, 223, 229, 226, 205, 133, 230, - 231, 201, 59, 232, 214, 210, 71, 242, 223, 229, 226, 205, 133, 163, 218, - 251, 210, 71, 242, 223, 229, 226, 205, 133, 198, 74, 210, 71, 242, 223, - 229, 226, 205, 133, 163, 177, 232, 214, 210, 71, 242, 223, 229, 226, 205, - 133, 163, 232, 214, 210, 71, 242, 223, 229, 226, 216, 67, 198, 74, 210, - 71, 242, 223, 229, 226, 230, 231, 201, 59, 195, 164, 210, 71, 242, 223, - 229, 226, 216, 67, 163, 177, 232, 214, 210, 71, 242, 223, 229, 226, 216, - 67, 163, 232, 214, 210, 71, 242, 223, 229, 226, 218, 217, 163, 218, 251, - 210, 71, 242, 223, 229, 226, 218, 217, 198, 74, 210, 71, 242, 223, 229, - 226, 230, 231, 201, 58, 210, 71, 242, 223, 229, 226, 218, 217, 163, 177, - 232, 214, 210, 71, 242, 223, 229, 226, 218, 217, 163, 232, 214, 210, 71, - 242, 223, 229, 226, 230, 231, 201, 59, 232, 214, 248, 151, 1, 65, 248, - 151, 1, 252, 154, 248, 151, 1, 70, 248, 151, 1, 223, 170, 248, 151, 1, - 69, 248, 151, 1, 196, 26, 248, 151, 1, 121, 148, 248, 151, 1, 121, 206, - 105, 248, 151, 1, 121, 170, 248, 151, 1, 73, 248, 151, 1, 251, 184, 248, - 151, 1, 74, 248, 151, 1, 250, 113, 248, 151, 1, 157, 248, 151, 1, 221, - 190, 248, 151, 1, 231, 203, 248, 151, 1, 231, 54, 248, 151, 1, 214, 54, - 248, 151, 1, 247, 112, 248, 151, 1, 246, 209, 248, 151, 1, 223, 4, 248, - 151, 1, 222, 225, 248, 151, 1, 212, 88, 248, 151, 1, 197, 128, 248, 151, - 1, 197, 116, 248, 151, 1, 237, 146, 248, 151, 1, 237, 130, 248, 151, 1, - 213, 66, 248, 151, 1, 199, 247, 248, 151, 1, 199, 44, 248, 151, 1, 237, - 241, 248, 151, 1, 237, 23, 248, 151, 1, 180, 248, 151, 1, 168, 248, 151, - 1, 209, 219, 248, 151, 1, 249, 103, 248, 151, 1, 248, 153, 248, 151, 1, - 172, 248, 151, 1, 169, 248, 151, 1, 166, 248, 151, 1, 171, 248, 151, 1, - 195, 185, 248, 151, 1, 203, 160, 248, 151, 1, 201, 170, 248, 151, 1, 189, - 248, 151, 1, 144, 248, 151, 18, 3, 252, 154, 248, 151, 18, 3, 70, 248, - 151, 18, 3, 223, 170, 248, 151, 18, 3, 69, 248, 151, 18, 3, 196, 26, 248, - 151, 18, 3, 121, 148, 248, 151, 18, 3, 121, 206, 105, 248, 151, 18, 3, - 121, 170, 248, 151, 18, 3, 73, 248, 151, 18, 3, 251, 184, 248, 151, 18, - 3, 74, 248, 151, 18, 3, 250, 113, 248, 151, 3, 247, 71, 248, 151, 3, 251, - 20, 248, 151, 3, 195, 32, 248, 151, 3, 195, 37, 248, 151, 3, 250, 95, - 248, 151, 237, 193, 248, 151, 54, 237, 193, 248, 151, 193, 23, 204, 5, - 248, 151, 231, 167, 232, 217, 248, 151, 231, 167, 232, 216, 248, 151, 17, - 191, 77, 248, 151, 17, 108, 248, 151, 17, 109, 248, 151, 17, 139, 248, - 151, 17, 137, 248, 151, 17, 153, 248, 151, 17, 173, 248, 151, 17, 181, - 248, 151, 17, 176, 248, 151, 17, 184, 248, 151, 31, 108, 248, 151, 31, - 109, 248, 151, 31, 139, 248, 151, 31, 137, 248, 151, 31, 153, 248, 151, - 31, 173, 248, 151, 31, 181, 248, 151, 31, 176, 248, 151, 31, 184, 248, - 151, 31, 199, 90, 248, 151, 31, 197, 28, 248, 151, 31, 198, 244, 248, - 151, 31, 232, 97, 248, 151, 31, 232, 230, 248, 151, 31, 202, 115, 248, - 151, 31, 203, 236, 248, 151, 31, 234, 110, 248, 151, 31, 213, 156, 248, - 151, 228, 108, 196, 87, 77, 217, 38, 229, 204, 77, 217, 38, 87, 203, 152, - 217, 38, 1, 157, 217, 38, 1, 221, 190, 217, 38, 1, 231, 203, 217, 38, 1, - 214, 54, 217, 38, 1, 247, 112, 217, 38, 1, 246, 209, 217, 38, 1, 223, 4, - 217, 38, 1, 212, 88, 217, 38, 1, 199, 247, 217, 38, 1, 199, 44, 217, 38, - 1, 237, 241, 217, 38, 1, 180, 217, 38, 1, 168, 217, 38, 1, 209, 219, 217, - 38, 1, 249, 103, 217, 38, 1, 172, 217, 38, 1, 197, 164, 217, 38, 1, 197, - 153, 217, 38, 1, 234, 247, 217, 38, 1, 193, 187, 217, 38, 1, 191, 71, - 217, 38, 1, 191, 123, 217, 38, 1, 255, 162, 217, 38, 1, 169, 217, 38, 1, - 166, 217, 38, 1, 171, 217, 38, 1, 203, 160, 217, 38, 1, 189, 217, 38, 1, - 144, 217, 38, 1, 65, 217, 38, 200, 234, 1, 157, 217, 38, 200, 234, 1, - 221, 190, 217, 38, 200, 234, 1, 231, 203, 217, 38, 200, 234, 1, 214, 54, - 217, 38, 200, 234, 1, 247, 112, 217, 38, 200, 234, 1, 246, 209, 217, 38, - 200, 234, 1, 223, 4, 217, 38, 200, 234, 1, 212, 88, 217, 38, 200, 234, 1, - 199, 247, 217, 38, 200, 234, 1, 199, 44, 217, 38, 200, 234, 1, 237, 241, - 217, 38, 200, 234, 1, 180, 217, 38, 200, 234, 1, 168, 217, 38, 200, 234, - 1, 209, 219, 217, 38, 200, 234, 1, 249, 103, 217, 38, 200, 234, 1, 172, - 217, 38, 200, 234, 1, 197, 164, 217, 38, 200, 234, 1, 197, 153, 217, 38, - 200, 234, 1, 234, 247, 217, 38, 200, 234, 1, 193, 187, 217, 38, 200, 234, - 1, 191, 71, 217, 38, 200, 234, 1, 191, 123, 217, 38, 200, 234, 1, 169, - 217, 38, 200, 234, 1, 166, 217, 38, 200, 234, 1, 171, 217, 38, 200, 234, - 1, 203, 160, 217, 38, 200, 234, 1, 189, 217, 38, 200, 234, 1, 144, 217, - 38, 200, 234, 1, 65, 217, 38, 18, 3, 252, 154, 217, 38, 18, 3, 70, 217, - 38, 18, 3, 69, 217, 38, 18, 3, 73, 217, 38, 18, 3, 74, 217, 38, 3, 251, - 20, 217, 38, 3, 247, 71, 217, 22, 129, 1, 65, 217, 22, 129, 1, 252, 154, - 217, 22, 129, 1, 70, 217, 22, 129, 1, 223, 170, 217, 22, 129, 1, 69, 217, - 22, 129, 1, 196, 26, 217, 22, 129, 1, 73, 217, 22, 129, 1, 251, 184, 217, - 22, 129, 1, 74, 217, 22, 129, 1, 250, 113, 217, 22, 129, 1, 157, 217, 22, - 129, 1, 221, 190, 217, 22, 129, 1, 231, 203, 217, 22, 129, 1, 231, 54, - 217, 22, 129, 1, 214, 54, 217, 22, 129, 1, 247, 112, 217, 22, 129, 1, - 246, 209, 217, 22, 129, 1, 223, 4, 217, 22, 129, 1, 222, 225, 217, 22, - 129, 1, 212, 88, 217, 22, 129, 1, 197, 128, 217, 22, 129, 1, 197, 116, - 217, 22, 129, 1, 237, 146, 217, 22, 129, 1, 237, 130, 217, 22, 129, 1, - 213, 66, 217, 22, 129, 1, 199, 247, 217, 22, 129, 1, 199, 44, 217, 22, - 129, 1, 237, 241, 217, 22, 129, 1, 237, 23, 217, 22, 129, 1, 180, 217, - 22, 129, 1, 168, 217, 22, 129, 1, 209, 219, 217, 22, 129, 1, 249, 103, - 217, 22, 129, 1, 248, 153, 217, 22, 129, 1, 172, 217, 22, 129, 1, 169, - 217, 22, 129, 1, 166, 217, 22, 129, 1, 171, 217, 22, 129, 1, 195, 185, - 217, 22, 129, 1, 203, 160, 217, 22, 129, 1, 201, 170, 217, 22, 129, 1, - 189, 217, 22, 129, 1, 144, 217, 22, 129, 1, 219, 49, 217, 22, 129, 1, - 220, 222, 217, 22, 129, 1, 222, 175, 217, 22, 129, 1, 198, 22, 217, 22, - 129, 18, 3, 252, 154, 217, 22, 129, 18, 3, 70, 217, 22, 129, 18, 3, 223, - 170, 217, 22, 129, 18, 3, 69, 217, 22, 129, 18, 3, 196, 26, 217, 22, 129, - 18, 3, 121, 148, 217, 22, 129, 18, 3, 73, 217, 22, 129, 18, 3, 251, 184, - 217, 22, 129, 18, 3, 74, 217, 22, 129, 18, 3, 250, 113, 217, 22, 129, 3, - 251, 20, 217, 22, 129, 3, 195, 32, 217, 22, 129, 3, 212, 128, 217, 22, - 129, 3, 247, 73, 217, 22, 129, 3, 230, 39, 217, 22, 129, 195, 37, 217, - 22, 129, 207, 39, 217, 22, 129, 207, 176, 217, 22, 129, 17, 191, 77, 217, - 22, 129, 17, 108, 217, 22, 129, 17, 109, 217, 22, 129, 17, 139, 217, 22, - 129, 17, 137, 217, 22, 129, 17, 153, 217, 22, 129, 17, 173, 217, 22, 129, - 17, 181, 217, 22, 129, 17, 176, 217, 22, 129, 17, 184, 230, 124, 129, 1, - 65, 230, 124, 129, 1, 252, 154, 230, 124, 129, 1, 70, 230, 124, 129, 1, - 223, 170, 230, 124, 129, 1, 69, 230, 124, 129, 1, 196, 26, 230, 124, 129, - 1, 234, 145, 230, 124, 129, 1, 251, 184, 230, 124, 129, 1, 211, 76, 230, - 124, 129, 1, 250, 113, 230, 124, 129, 1, 169, 230, 124, 129, 1, 195, 185, - 230, 124, 129, 1, 249, 103, 230, 124, 129, 1, 248, 153, 230, 124, 129, 1, - 172, 230, 124, 129, 1, 157, 230, 124, 129, 1, 221, 190, 230, 124, 129, 1, - 199, 247, 230, 124, 129, 1, 199, 44, 230, 124, 129, 1, 171, 230, 124, - 129, 1, 231, 203, 230, 124, 129, 1, 231, 54, 230, 124, 129, 1, 237, 241, - 230, 124, 129, 1, 237, 23, 230, 124, 129, 1, 180, 230, 124, 129, 1, 247, - 112, 230, 124, 129, 1, 246, 209, 230, 124, 129, 1, 197, 128, 230, 124, - 129, 1, 197, 116, 230, 124, 129, 1, 219, 49, 230, 124, 129, 1, 223, 4, - 230, 124, 129, 1, 222, 225, 230, 124, 129, 1, 237, 146, 230, 124, 129, 1, - 237, 130, 230, 124, 129, 1, 214, 54, 230, 124, 129, 1, 168, 230, 124, - 129, 1, 209, 219, 230, 124, 129, 1, 144, 230, 124, 129, 1, 166, 230, 124, - 129, 1, 189, 230, 124, 129, 18, 3, 252, 154, 230, 124, 129, 18, 3, 70, - 230, 124, 129, 18, 3, 223, 170, 230, 124, 129, 18, 3, 69, 230, 124, 129, - 18, 3, 196, 26, 230, 124, 129, 18, 3, 234, 145, 230, 124, 129, 18, 3, - 251, 184, 230, 124, 129, 18, 3, 211, 76, 230, 124, 129, 18, 3, 250, 113, - 230, 124, 129, 3, 251, 20, 230, 124, 129, 3, 195, 32, 230, 124, 129, 195, - 37, 230, 124, 129, 211, 102, 230, 124, 129, 17, 191, 77, 230, 124, 129, - 17, 108, 230, 124, 129, 17, 109, 230, 124, 129, 17, 139, 230, 124, 129, - 17, 137, 230, 124, 129, 17, 153, 230, 124, 129, 17, 173, 230, 124, 129, - 17, 181, 230, 124, 129, 17, 176, 230, 124, 129, 17, 184, 217, 81, 1, 157, - 217, 81, 1, 231, 203, 217, 81, 1, 214, 54, 217, 81, 1, 168, 217, 81, 1, - 249, 103, 217, 81, 1, 172, 217, 81, 1, 199, 247, 217, 81, 1, 237, 241, - 217, 81, 1, 180, 217, 81, 1, 247, 112, 217, 81, 1, 223, 4, 217, 81, 1, - 212, 88, 217, 81, 1, 169, 217, 81, 1, 166, 217, 81, 1, 171, 217, 81, 1, - 195, 185, 217, 81, 1, 189, 217, 81, 1, 65, 217, 81, 251, 67, 217, 81, 18, - 3, 70, 217, 81, 18, 3, 69, 217, 81, 18, 3, 73, 217, 81, 18, 3, 74, 217, - 81, 210, 84, 217, 81, 234, 53, 80, 205, 48, 219, 64, 1, 192, 35, 44, 232, - 80, 91, 198, 217, 44, 232, 80, 91, 211, 89, 44, 232, 80, 91, 234, 113, - 44, 232, 80, 91, 202, 113, 44, 232, 80, 91, 232, 100, 44, 232, 80, 91, - 198, 240, 44, 232, 80, 115, 234, 112, 44, 232, 80, 115, 202, 112, 44, - 232, 80, 91, 197, 31, 44, 232, 80, 91, 202, 122, 44, 232, 80, 91, 202, - 121, 44, 232, 80, 91, 199, 81, 44, 232, 80, 91, 234, 116, 44, 232, 80, - 115, 197, 30, 44, 232, 80, 115, 202, 120, 44, 232, 80, 91, 232, 233, 44, - 232, 80, 91, 208, 17, 44, 232, 80, 91, 230, 36, 44, 232, 80, 91, 230, 35, - 44, 232, 80, 115, 208, 15, 44, 232, 80, 235, 77, 233, 52, 221, 120, 44, - 3, 214, 90, 44, 3, 246, 214, 44, 3, 252, 105, 44, 3, 196, 11, 44, 3, 215, - 76, 44, 3, 220, 170, 44, 3, 210, 75, 44, 3, 215, 120, 44, 3, 222, 97, 44, - 3, 210, 154, 44, 3, 209, 32, 44, 3, 195, 170, 44, 3, 210, 205, 44, 3, - 220, 159, 44, 3, 195, 140, 44, 193, 99, 238, 140, 57, 44, 235, 48, 238, - 140, 57, 44, 219, 255, 57, 44, 205, 154, 210, 157, 57, 44, 198, 17, 238, - 183, 57, 44, 198, 17, 31, 57, 44, 238, 122, 57, 44, 24, 211, 143, 57, 44, - 201, 222, 57, 44, 198, 34, 57, 44, 223, 135, 209, 15, 57, 44, 201, 91, - 232, 60, 57, 44, 3, 215, 80, 44, 3, 195, 178, 44, 208, 145, 234, 53, 80, - 199, 48, 10, 3, 65, 10, 3, 41, 25, 65, 10, 3, 41, 25, 249, 85, 10, 3, 41, - 25, 231, 172, 199, 79, 10, 3, 41, 25, 144, 10, 3, 41, 25, 223, 172, 10, - 3, 41, 25, 220, 79, 230, 122, 10, 3, 41, 25, 215, 87, 10, 3, 41, 25, 205, - 180, 10, 3, 254, 163, 10, 3, 252, 103, 10, 3, 252, 104, 25, 250, 157, 10, - 3, 252, 104, 25, 235, 30, 230, 122, 10, 3, 252, 104, 25, 231, 185, 10, 3, - 252, 104, 25, 231, 172, 199, 79, 10, 3, 252, 104, 25, 144, 10, 3, 252, - 104, 25, 223, 173, 230, 122, 10, 3, 252, 104, 25, 223, 144, 10, 3, 252, - 104, 25, 220, 80, 10, 3, 252, 104, 25, 203, 92, 10, 3, 252, 104, 25, 126, - 107, 126, 107, 69, 10, 3, 252, 104, 230, 122, 10, 3, 252, 20, 10, 3, 252, - 21, 25, 249, 64, 10, 3, 252, 21, 25, 231, 172, 199, 79, 10, 3, 252, 21, - 25, 216, 214, 107, 234, 61, 10, 3, 252, 21, 25, 203, 158, 10, 3, 252, 21, - 25, 199, 204, 10, 3, 251, 246, 10, 3, 251, 165, 10, 3, 251, 166, 25, 233, - 242, 10, 3, 251, 166, 25, 203, 54, 107, 230, 243, 10, 3, 251, 156, 10, 3, - 251, 157, 25, 251, 156, 10, 3, 251, 157, 25, 236, 208, 10, 3, 251, 157, - 25, 230, 243, 10, 3, 251, 157, 25, 144, 10, 3, 251, 157, 25, 222, 84, 10, - 3, 251, 157, 25, 221, 142, 10, 3, 251, 157, 25, 203, 108, 10, 3, 251, - 157, 25, 196, 34, 10, 3, 251, 152, 10, 3, 251, 139, 10, 3, 251, 94, 10, - 3, 251, 95, 25, 203, 108, 10, 3, 251, 81, 10, 3, 251, 82, 138, 251, 81, - 10, 3, 251, 82, 115, 198, 139, 10, 3, 251, 82, 107, 214, 227, 211, 52, - 251, 82, 107, 214, 226, 10, 3, 251, 82, 107, 214, 227, 201, 184, 10, 3, - 251, 40, 10, 3, 251, 10, 10, 3, 250, 232, 10, 3, 250, 233, 25, 220, 173, - 10, 3, 250, 204, 10, 3, 250, 165, 10, 3, 250, 159, 10, 3, 250, 160, 191, - 26, 199, 79, 10, 3, 250, 160, 222, 89, 199, 79, 10, 3, 250, 160, 138, - 250, 160, 197, 79, 138, 197, 79, 197, 79, 138, 197, 79, 210, 127, 10, 3, - 250, 160, 138, 250, 160, 138, 250, 159, 10, 3, 250, 160, 138, 250, 160, - 138, 250, 160, 238, 163, 250, 160, 138, 250, 160, 138, 250, 159, 10, 3, - 250, 157, 10, 3, 250, 153, 10, 3, 249, 103, 10, 3, 249, 85, 10, 3, 249, - 79, 10, 3, 249, 71, 10, 3, 249, 65, 10, 3, 249, 66, 138, 249, 65, 10, 3, - 249, 64, 10, 3, 164, 10, 3, 249, 37, 10, 3, 248, 140, 10, 3, 248, 141, - 25, 65, 10, 3, 248, 141, 25, 231, 163, 10, 3, 248, 141, 25, 223, 173, - 230, 122, 10, 3, 247, 218, 10, 3, 247, 219, 138, 247, 219, 252, 103, 10, - 3, 247, 219, 138, 247, 219, 196, 109, 10, 3, 247, 219, 238, 163, 247, - 218, 10, 3, 247, 194, 10, 3, 247, 195, 138, 247, 194, 10, 3, 247, 182, - 10, 3, 247, 181, 10, 3, 237, 241, 10, 3, 237, 231, 10, 3, 237, 232, 221, - 101, 25, 41, 107, 217, 20, 10, 3, 237, 232, 221, 101, 25, 251, 94, 10, 3, - 237, 232, 221, 101, 25, 249, 64, 10, 3, 237, 232, 221, 101, 25, 248, 140, - 10, 3, 237, 232, 221, 101, 25, 231, 203, 10, 3, 237, 232, 221, 101, 25, - 231, 204, 107, 217, 20, 10, 3, 237, 232, 221, 101, 25, 231, 16, 10, 3, - 237, 232, 221, 101, 25, 230, 252, 10, 3, 237, 232, 221, 101, 25, 230, - 135, 10, 3, 237, 232, 221, 101, 25, 144, 10, 3, 237, 232, 221, 101, 25, - 223, 49, 10, 3, 237, 232, 221, 101, 25, 223, 50, 107, 218, 203, 10, 3, - 237, 232, 221, 101, 25, 222, 69, 10, 3, 237, 232, 221, 101, 25, 171, 10, - 3, 237, 232, 221, 101, 25, 218, 203, 10, 3, 237, 232, 221, 101, 25, 218, - 204, 107, 217, 19, 10, 3, 237, 232, 221, 101, 25, 218, 186, 10, 3, 237, - 232, 221, 101, 25, 214, 107, 10, 3, 237, 232, 221, 101, 25, 210, 128, - 107, 210, 127, 10, 3, 237, 232, 221, 101, 25, 202, 217, 10, 3, 237, 232, - 221, 101, 25, 199, 204, 10, 3, 237, 232, 221, 101, 25, 196, 166, 107, - 230, 252, 10, 3, 237, 232, 221, 101, 25, 196, 34, 10, 3, 237, 203, 10, 3, - 237, 180, 10, 3, 237, 179, 10, 3, 237, 178, 10, 3, 236, 255, 10, 3, 236, - 237, 10, 3, 236, 210, 10, 3, 236, 211, 25, 203, 108, 10, 3, 236, 208, 10, - 3, 236, 198, 10, 3, 236, 199, 222, 29, 126, 230, 123, 236, 177, 10, 3, - 236, 177, 10, 3, 235, 45, 10, 3, 235, 46, 138, 235, 45, 10, 3, 235, 46, - 230, 122, 10, 3, 235, 46, 203, 89, 10, 3, 235, 43, 10, 3, 235, 44, 25, - 233, 223, 10, 3, 235, 42, 10, 3, 235, 38, 10, 3, 235, 37, 10, 3, 235, 36, - 10, 3, 235, 31, 10, 3, 235, 29, 10, 3, 235, 30, 230, 122, 10, 3, 235, 30, - 230, 123, 230, 122, 10, 3, 235, 28, 10, 3, 235, 21, 10, 3, 73, 10, 3, - 234, 227, 25, 210, 127, 10, 3, 234, 227, 138, 234, 227, 212, 118, 138, - 212, 117, 10, 3, 234, 174, 10, 3, 234, 175, 25, 41, 107, 230, 72, 107, - 237, 241, 10, 3, 234, 175, 25, 231, 163, 10, 3, 234, 175, 25, 216, 81, - 10, 3, 234, 175, 25, 205, 164, 10, 3, 234, 175, 25, 203, 108, 10, 3, 234, - 175, 25, 69, 10, 3, 234, 147, 10, 3, 234, 134, 10, 3, 234, 97, 10, 3, - 234, 61, 10, 3, 234, 62, 25, 231, 171, 10, 3, 234, 62, 25, 231, 172, 199, - 79, 10, 3, 234, 62, 25, 216, 213, 10, 3, 234, 62, 238, 163, 234, 61, 10, - 3, 234, 62, 211, 52, 234, 61, 10, 3, 234, 62, 201, 184, 10, 3, 233, 245, - 10, 3, 233, 242, 10, 3, 233, 223, 10, 3, 233, 139, 10, 3, 233, 140, 25, - 65, 10, 3, 233, 140, 25, 41, 107, 220, 13, 10, 3, 233, 140, 25, 41, 107, - 220, 14, 25, 220, 13, 10, 3, 233, 140, 25, 251, 81, 10, 3, 233, 140, 25, - 249, 85, 10, 3, 233, 140, 25, 235, 30, 230, 122, 10, 3, 233, 140, 25, - 235, 30, 230, 123, 230, 122, 10, 3, 233, 140, 25, 144, 10, 3, 233, 140, - 25, 230, 72, 230, 122, 10, 3, 233, 140, 25, 223, 173, 230, 122, 10, 3, - 233, 140, 25, 222, 28, 10, 3, 233, 140, 25, 222, 29, 201, 184, 10, 3, - 233, 140, 25, 220, 199, 10, 3, 233, 140, 25, 171, 10, 3, 233, 140, 25, - 220, 14, 25, 220, 13, 10, 3, 233, 140, 25, 219, 122, 10, 3, 233, 140, 25, - 218, 203, 10, 3, 233, 140, 25, 196, 165, 10, 3, 233, 140, 25, 196, 154, - 10, 3, 231, 203, 10, 3, 231, 204, 230, 122, 10, 3, 231, 201, 10, 3, 231, - 202, 25, 41, 107, 237, 242, 107, 144, 10, 3, 231, 202, 25, 41, 107, 144, - 10, 3, 231, 202, 25, 41, 107, 223, 172, 10, 3, 231, 202, 25, 252, 21, - 199, 80, 107, 199, 231, 10, 3, 231, 202, 25, 251, 81, 10, 3, 231, 202, - 25, 250, 159, 10, 3, 231, 202, 25, 250, 158, 107, 231, 185, 10, 3, 231, - 202, 25, 249, 85, 10, 3, 231, 202, 25, 249, 38, 107, 166, 10, 3, 231, - 202, 25, 247, 182, 10, 3, 231, 202, 25, 247, 183, 107, 166, 10, 3, 231, - 202, 25, 237, 241, 10, 3, 231, 202, 25, 236, 255, 10, 3, 231, 202, 25, - 236, 211, 25, 203, 108, 10, 3, 231, 202, 25, 235, 43, 10, 3, 231, 202, - 25, 234, 97, 10, 3, 231, 202, 25, 234, 98, 107, 171, 10, 3, 231, 202, 25, - 234, 61, 10, 3, 231, 202, 25, 234, 62, 25, 231, 172, 199, 79, 10, 3, 231, - 202, 25, 231, 172, 199, 79, 10, 3, 231, 202, 25, 231, 163, 10, 3, 231, - 202, 25, 231, 16, 10, 3, 231, 202, 25, 231, 14, 10, 3, 231, 202, 25, 231, - 15, 107, 65, 10, 3, 231, 202, 25, 230, 253, 107, 200, 255, 10, 3, 231, - 202, 25, 230, 72, 107, 218, 204, 107, 233, 223, 10, 3, 231, 202, 25, 230, - 40, 10, 3, 231, 202, 25, 230, 41, 107, 171, 10, 3, 231, 202, 25, 229, - 127, 107, 219, 122, 10, 3, 231, 202, 25, 228, 120, 10, 3, 231, 202, 25, - 223, 173, 230, 122, 10, 3, 231, 202, 25, 223, 35, 107, 228, 129, 107, - 250, 159, 10, 3, 231, 202, 25, 222, 69, 10, 3, 231, 202, 25, 222, 28, 10, - 3, 231, 202, 25, 221, 128, 10, 3, 231, 202, 25, 221, 129, 107, 220, 13, - 10, 3, 231, 202, 25, 220, 200, 107, 251, 81, 10, 3, 231, 202, 25, 171, - 10, 3, 231, 202, 25, 216, 214, 107, 234, 61, 10, 3, 231, 202, 25, 216, - 81, 10, 3, 231, 202, 25, 212, 117, 10, 3, 231, 202, 25, 212, 118, 138, - 212, 117, 10, 3, 231, 202, 25, 168, 10, 3, 231, 202, 25, 205, 164, 10, 3, - 231, 202, 25, 205, 122, 10, 3, 231, 202, 25, 203, 108, 10, 3, 231, 202, - 25, 203, 109, 107, 197, 60, 10, 3, 231, 202, 25, 203, 74, 10, 3, 231, - 202, 25, 200, 199, 10, 3, 231, 202, 25, 199, 204, 10, 3, 231, 202, 25, - 69, 10, 3, 231, 202, 25, 196, 154, 10, 3, 231, 202, 25, 196, 155, 107, - 235, 45, 10, 3, 231, 202, 138, 231, 201, 10, 3, 231, 196, 10, 3, 231, - 197, 238, 163, 231, 196, 10, 3, 231, 194, 10, 3, 231, 195, 138, 231, 195, - 231, 164, 138, 231, 163, 10, 3, 231, 185, 10, 3, 231, 186, 231, 195, 138, - 231, 195, 231, 164, 138, 231, 163, 10, 3, 231, 184, 10, 3, 231, 182, 10, - 3, 231, 173, 10, 3, 231, 171, 10, 3, 231, 172, 199, 79, 10, 3, 231, 172, - 138, 231, 171, 10, 3, 231, 172, 238, 163, 231, 171, 10, 3, 231, 163, 10, - 3, 231, 162, 10, 3, 231, 156, 10, 3, 231, 97, 10, 3, 231, 98, 25, 220, - 173, 10, 3, 231, 16, 10, 3, 231, 17, 25, 73, 10, 3, 231, 17, 25, 69, 10, - 3, 231, 17, 238, 163, 231, 16, 10, 3, 231, 14, 10, 3, 231, 15, 138, 231, - 14, 10, 3, 231, 15, 238, 163, 231, 14, 10, 3, 231, 11, 10, 3, 230, 252, - 10, 3, 230, 253, 230, 122, 10, 3, 230, 250, 10, 3, 230, 251, 25, 41, 107, - 223, 172, 10, 3, 230, 251, 25, 231, 172, 199, 79, 10, 3, 230, 251, 25, - 223, 172, 10, 3, 230, 251, 25, 218, 204, 107, 223, 172, 10, 3, 230, 251, - 25, 168, 10, 3, 230, 245, 10, 3, 230, 243, 10, 3, 230, 244, 238, 163, - 230, 243, 10, 3, 230, 244, 25, 249, 85, 10, 3, 230, 244, 25, 199, 204, - 10, 3, 230, 244, 199, 79, 10, 3, 230, 146, 10, 3, 230, 147, 238, 163, - 230, 146, 10, 3, 230, 144, 10, 3, 230, 145, 25, 222, 69, 10, 3, 230, 145, - 25, 222, 70, 25, 223, 173, 230, 122, 10, 3, 230, 145, 25, 212, 117, 10, - 3, 230, 145, 25, 205, 165, 107, 197, 78, 10, 3, 230, 145, 230, 122, 10, - 3, 230, 135, 10, 3, 230, 136, 25, 41, 107, 220, 173, 10, 3, 230, 136, 25, - 220, 173, 10, 3, 230, 136, 138, 230, 136, 218, 194, 10, 3, 230, 127, 10, - 3, 230, 125, 10, 3, 230, 126, 25, 203, 108, 10, 3, 230, 116, 10, 3, 230, - 115, 10, 3, 230, 110, 10, 3, 230, 109, 10, 3, 144, 10, 3, 230, 72, 199, - 79, 10, 3, 230, 72, 230, 122, 10, 3, 230, 40, 10, 3, 229, 126, 10, 3, - 229, 127, 25, 250, 159, 10, 3, 229, 127, 25, 250, 157, 10, 3, 229, 127, - 25, 249, 85, 10, 3, 229, 127, 25, 236, 177, 10, 3, 229, 127, 25, 231, - 194, 10, 3, 229, 127, 25, 221, 117, 10, 3, 229, 127, 25, 212, 117, 10, 3, - 229, 127, 25, 203, 108, 10, 3, 229, 127, 25, 69, 10, 3, 228, 128, 10, 3, - 228, 120, 10, 3, 228, 121, 25, 251, 81, 10, 3, 228, 121, 25, 230, 40, 10, - 3, 228, 121, 25, 222, 28, 10, 3, 228, 121, 25, 219, 65, 10, 3, 228, 121, - 25, 196, 154, 10, 3, 228, 115, 10, 3, 70, 10, 3, 228, 44, 65, 10, 3, 228, - 0, 10, 3, 223, 200, 10, 3, 223, 201, 138, 223, 201, 247, 182, 10, 3, 223, - 201, 138, 223, 201, 201, 184, 10, 3, 223, 175, 10, 3, 223, 172, 10, 3, - 223, 173, 236, 237, 10, 3, 223, 173, 206, 252, 10, 3, 223, 173, 138, 223, - 173, 203, 58, 138, 203, 58, 196, 155, 138, 196, 154, 10, 3, 223, 173, - 230, 122, 10, 3, 223, 163, 10, 3, 223, 164, 25, 231, 172, 199, 79, 10, 3, - 223, 162, 10, 3, 223, 152, 10, 3, 223, 153, 25, 199, 204, 10, 3, 223, - 153, 238, 163, 223, 152, 10, 3, 223, 153, 211, 52, 223, 152, 10, 3, 223, - 153, 201, 184, 10, 3, 223, 144, 10, 3, 223, 134, 10, 3, 223, 49, 10, 3, - 223, 34, 10, 3, 157, 10, 3, 222, 115, 25, 65, 10, 3, 222, 115, 25, 251, - 246, 10, 3, 222, 115, 25, 251, 247, 107, 220, 199, 10, 3, 222, 115, 25, - 250, 157, 10, 3, 222, 115, 25, 249, 85, 10, 3, 222, 115, 25, 249, 64, 10, - 3, 222, 115, 25, 164, 10, 3, 222, 115, 25, 248, 140, 10, 3, 222, 115, 25, - 233, 242, 10, 3, 222, 115, 25, 233, 223, 10, 3, 222, 115, 25, 231, 203, - 10, 3, 222, 115, 25, 231, 185, 10, 3, 222, 115, 25, 231, 172, 199, 79, - 10, 3, 222, 115, 25, 231, 163, 10, 3, 222, 115, 25, 231, 164, 107, 203, - 159, 107, 65, 10, 3, 222, 115, 25, 231, 16, 10, 3, 222, 115, 25, 230, - 252, 10, 3, 222, 115, 25, 230, 244, 107, 205, 122, 10, 3, 222, 115, 25, - 230, 244, 238, 163, 230, 243, 10, 3, 222, 115, 25, 230, 146, 10, 3, 222, - 115, 25, 230, 115, 10, 3, 222, 115, 25, 223, 172, 10, 3, 222, 115, 25, - 223, 152, 10, 3, 222, 115, 25, 222, 69, 10, 3, 222, 115, 25, 221, 142, - 10, 3, 222, 115, 25, 221, 128, 10, 3, 222, 115, 25, 219, 122, 10, 3, 222, - 115, 25, 218, 203, 10, 3, 222, 115, 25, 216, 213, 10, 3, 222, 115, 25, - 216, 214, 107, 235, 45, 10, 3, 222, 115, 25, 216, 214, 107, 231, 16, 10, - 3, 222, 115, 25, 216, 214, 107, 199, 140, 10, 3, 222, 115, 25, 216, 81, - 10, 3, 222, 115, 25, 216, 82, 107, 212, 112, 10, 3, 222, 115, 25, 214, - 107, 10, 3, 222, 115, 25, 212, 117, 10, 3, 222, 115, 25, 209, 176, 10, 3, - 222, 115, 25, 206, 63, 10, 3, 222, 115, 25, 189, 10, 3, 222, 115, 25, - 205, 122, 10, 3, 222, 115, 25, 203, 160, 10, 3, 222, 115, 25, 203, 108, - 10, 3, 222, 115, 25, 203, 74, 10, 3, 222, 115, 25, 203, 0, 10, 3, 222, - 115, 25, 202, 196, 10, 3, 222, 115, 25, 200, 208, 10, 3, 222, 115, 25, - 199, 174, 10, 3, 222, 115, 25, 69, 10, 3, 222, 115, 25, 196, 165, 10, 3, - 222, 115, 25, 196, 154, 10, 3, 222, 115, 25, 196, 112, 25, 168, 10, 3, - 222, 115, 25, 196, 34, 10, 3, 222, 115, 25, 191, 30, 10, 3, 222, 101, 10, - 3, 222, 102, 238, 163, 222, 101, 10, 3, 222, 90, 10, 3, 222, 86, 10, 3, - 222, 84, 10, 3, 222, 83, 10, 3, 222, 81, 10, 3, 222, 82, 138, 222, 81, - 10, 3, 222, 69, 10, 3, 222, 70, 25, 223, 173, 230, 122, 10, 3, 222, 65, - 10, 3, 222, 66, 25, 249, 85, 10, 3, 222, 66, 238, 163, 222, 65, 10, 3, - 222, 63, 10, 3, 222, 62, 10, 3, 222, 28, 10, 3, 222, 29, 220, 81, 25, - 126, 138, 220, 81, 25, 69, 10, 3, 222, 29, 138, 222, 29, 220, 81, 25, - 126, 138, 220, 81, 25, 69, 10, 3, 221, 217, 10, 3, 221, 142, 10, 3, 221, - 143, 25, 249, 85, 10, 3, 221, 143, 25, 69, 10, 3, 221, 143, 25, 196, 154, - 10, 3, 221, 128, 10, 3, 221, 117, 10, 3, 221, 103, 10, 3, 221, 102, 10, - 3, 221, 100, 10, 3, 221, 101, 138, 221, 100, 10, 3, 220, 208, 10, 3, 220, - 209, 138, 229, 127, 25, 250, 158, 220, 209, 138, 229, 127, 25, 250, 157, - 10, 3, 220, 199, 10, 3, 220, 197, 10, 3, 220, 198, 195, 165, 20, 10, 3, - 220, 196, 10, 3, 220, 187, 10, 3, 220, 188, 230, 122, 10, 3, 220, 186, - 10, 3, 220, 173, 10, 3, 220, 174, 211, 52, 220, 173, 10, 3, 220, 166, 10, - 3, 220, 143, 10, 3, 171, 10, 3, 220, 80, 10, 3, 220, 81, 25, 65, 10, 3, - 220, 81, 25, 41, 107, 237, 242, 107, 144, 10, 3, 220, 81, 25, 41, 107, - 231, 163, 10, 3, 220, 81, 25, 41, 107, 220, 13, 10, 3, 220, 81, 25, 251, - 156, 10, 3, 220, 81, 25, 251, 81, 10, 3, 220, 81, 25, 250, 160, 191, 26, - 199, 79, 10, 3, 220, 81, 25, 249, 85, 10, 3, 220, 81, 25, 248, 140, 10, - 3, 220, 81, 25, 237, 180, 10, 3, 220, 81, 25, 234, 61, 10, 3, 220, 81, - 25, 231, 203, 10, 3, 220, 81, 25, 231, 163, 10, 3, 220, 81, 25, 230, 135, - 10, 3, 220, 81, 25, 230, 136, 107, 230, 135, 10, 3, 220, 81, 25, 144, 10, - 3, 220, 81, 25, 230, 40, 10, 3, 220, 81, 25, 229, 127, 25, 212, 117, 10, - 3, 220, 81, 25, 223, 173, 230, 122, 10, 3, 220, 81, 25, 223, 152, 10, 3, - 220, 81, 25, 223, 153, 107, 144, 10, 3, 220, 81, 25, 223, 153, 107, 218, - 203, 10, 3, 220, 81, 25, 221, 142, 10, 3, 220, 81, 25, 221, 117, 10, 3, - 220, 81, 25, 220, 199, 10, 3, 220, 81, 25, 220, 187, 10, 3, 220, 81, 25, - 220, 188, 107, 229, 127, 107, 65, 10, 3, 220, 81, 25, 220, 80, 10, 3, - 220, 81, 25, 219, 65, 10, 3, 220, 81, 25, 218, 203, 10, 3, 220, 81, 25, - 218, 188, 10, 3, 220, 81, 25, 216, 213, 10, 3, 220, 81, 25, 216, 214, - 107, 234, 61, 10, 3, 220, 81, 25, 215, 87, 10, 3, 220, 81, 25, 214, 107, - 10, 3, 220, 81, 25, 203, 109, 107, 200, 199, 10, 3, 220, 81, 25, 203, 54, - 107, 230, 244, 107, 233, 242, 10, 3, 220, 81, 25, 203, 54, 107, 230, 244, - 199, 79, 10, 3, 220, 81, 25, 202, 254, 10, 3, 220, 81, 25, 202, 255, 107, - 202, 254, 10, 3, 220, 81, 25, 200, 199, 10, 3, 220, 81, 25, 199, 218, 10, - 3, 220, 81, 25, 199, 204, 10, 3, 220, 81, 25, 199, 141, 107, 41, 107, - 201, 0, 107, 180, 10, 3, 220, 81, 25, 69, 10, 3, 220, 81, 25, 126, 107, - 65, 10, 3, 220, 81, 25, 126, 107, 126, 107, 69, 10, 3, 220, 81, 25, 196, - 166, 107, 250, 159, 10, 3, 220, 81, 25, 196, 154, 10, 3, 220, 81, 25, - 196, 34, 10, 3, 220, 81, 201, 184, 10, 3, 220, 78, 10, 3, 220, 79, 25, - 203, 108, 10, 3, 220, 79, 25, 203, 109, 107, 200, 199, 10, 3, 220, 79, - 230, 122, 10, 3, 220, 79, 230, 123, 138, 220, 79, 230, 123, 203, 108, 10, - 3, 220, 74, 10, 3, 220, 13, 10, 3, 220, 14, 25, 220, 13, 10, 3, 220, 11, - 10, 3, 220, 12, 25, 220, 173, 10, 3, 220, 12, 25, 220, 174, 107, 206, 63, - 10, 3, 219, 122, 10, 3, 219, 103, 10, 3, 219, 91, 10, 3, 219, 65, 10, 3, - 218, 203, 10, 3, 218, 204, 25, 249, 85, 10, 3, 218, 201, 10, 3, 218, 202, - 25, 251, 156, 10, 3, 218, 202, 25, 249, 85, 10, 3, 218, 202, 25, 233, - 223, 10, 3, 218, 202, 25, 233, 224, 199, 79, 10, 3, 218, 202, 25, 231, - 172, 199, 79, 10, 3, 218, 202, 25, 229, 127, 25, 249, 85, 10, 3, 218, - 202, 25, 223, 152, 10, 3, 218, 202, 25, 222, 86, 10, 3, 218, 202, 25, - 222, 84, 10, 3, 218, 202, 25, 222, 85, 107, 250, 159, 10, 3, 218, 202, - 25, 221, 142, 10, 3, 218, 202, 25, 220, 102, 107, 250, 159, 10, 3, 218, - 202, 25, 220, 80, 10, 3, 218, 202, 25, 216, 214, 107, 234, 61, 10, 3, - 218, 202, 25, 214, 107, 10, 3, 218, 202, 25, 212, 165, 10, 3, 218, 202, - 25, 202, 218, 107, 250, 159, 10, 3, 218, 202, 25, 202, 187, 107, 247, - 218, 10, 3, 218, 202, 25, 197, 78, 10, 3, 218, 202, 199, 79, 10, 3, 218, - 202, 238, 163, 218, 201, 10, 3, 218, 202, 211, 52, 218, 201, 10, 3, 218, - 202, 201, 184, 10, 3, 218, 202, 203, 89, 10, 3, 218, 200, 10, 3, 218, - 194, 10, 3, 218, 195, 138, 218, 194, 10, 3, 218, 195, 211, 52, 218, 194, - 10, 3, 218, 195, 203, 89, 10, 3, 218, 191, 10, 3, 218, 188, 10, 3, 218, - 186, 10, 3, 218, 187, 138, 218, 186, 10, 3, 218, 187, 138, 218, 187, 231, - 164, 138, 231, 163, 10, 3, 172, 10, 3, 217, 139, 25, 199, 204, 10, 3, - 217, 139, 230, 122, 10, 3, 217, 131, 10, 3, 217, 99, 10, 3, 217, 45, 10, - 3, 217, 20, 10, 3, 217, 19, 10, 3, 216, 213, 10, 3, 216, 154, 10, 3, 216, - 81, 10, 3, 216, 26, 10, 3, 215, 139, 10, 3, 215, 140, 138, 215, 139, 10, - 3, 215, 124, 10, 3, 215, 125, 230, 122, 10, 3, 215, 105, 10, 3, 215, 91, - 10, 3, 215, 87, 10, 3, 215, 88, 25, 65, 10, 3, 215, 88, 25, 220, 173, 10, - 3, 215, 88, 25, 191, 123, 10, 3, 215, 88, 138, 215, 87, 10, 3, 215, 88, - 138, 215, 88, 25, 41, 107, 180, 10, 3, 215, 88, 238, 163, 215, 87, 10, 3, - 215, 85, 10, 3, 215, 86, 25, 65, 10, 3, 215, 86, 25, 41, 107, 236, 255, - 10, 3, 215, 86, 25, 236, 255, 10, 3, 215, 86, 230, 122, 10, 3, 180, 10, - 3, 214, 239, 10, 3, 214, 226, 10, 3, 214, 227, 223, 64, 10, 3, 214, 227, - 25, 203, 1, 199, 79, 10, 3, 214, 227, 211, 52, 214, 226, 10, 3, 214, 225, - 10, 3, 214, 217, 212, 103, 10, 3, 214, 216, 10, 3, 214, 215, 10, 3, 214, - 107, 10, 3, 214, 108, 25, 65, 10, 3, 214, 108, 25, 196, 154, 10, 3, 214, - 108, 203, 89, 10, 3, 213, 205, 10, 3, 213, 206, 25, 73, 10, 3, 213, 196, - 10, 3, 213, 166, 10, 3, 213, 167, 25, 231, 172, 199, 79, 10, 3, 213, 167, - 25, 231, 164, 107, 231, 172, 199, 79, 10, 3, 213, 162, 10, 3, 213, 163, - 25, 251, 81, 10, 3, 213, 163, 25, 250, 159, 10, 3, 213, 163, 25, 250, - 160, 107, 250, 159, 10, 3, 213, 163, 25, 230, 135, 10, 3, 213, 163, 25, - 216, 214, 107, 231, 172, 199, 79, 10, 3, 213, 163, 25, 214, 107, 10, 3, - 213, 163, 25, 212, 117, 10, 3, 213, 163, 25, 203, 108, 10, 3, 213, 163, - 25, 203, 109, 107, 41, 251, 81, 10, 3, 213, 163, 25, 203, 109, 107, 250, - 159, 10, 3, 213, 163, 25, 203, 109, 107, 250, 160, 107, 250, 159, 10, 3, - 213, 163, 25, 196, 166, 107, 250, 159, 10, 3, 213, 163, 25, 196, 34, 10, - 3, 213, 150, 10, 3, 212, 165, 10, 3, 212, 134, 10, 3, 212, 117, 10, 3, - 212, 118, 220, 79, 25, 231, 163, 10, 3, 212, 118, 220, 79, 25, 217, 20, - 10, 3, 212, 118, 220, 79, 25, 205, 164, 10, 3, 212, 118, 220, 79, 25, - 205, 165, 138, 212, 118, 220, 79, 25, 205, 164, 10, 3, 212, 118, 220, 79, - 25, 196, 34, 10, 3, 212, 118, 199, 79, 10, 3, 212, 118, 138, 212, 117, - 10, 3, 212, 118, 238, 163, 212, 117, 10, 3, 212, 118, 238, 163, 212, 118, - 220, 79, 138, 220, 78, 10, 3, 212, 112, 10, 3, 212, 113, 252, 21, 25, - 250, 153, 10, 3, 212, 113, 252, 21, 25, 248, 140, 10, 3, 212, 113, 252, - 21, 25, 235, 38, 10, 3, 212, 113, 252, 21, 25, 230, 135, 10, 3, 212, 113, - 252, 21, 25, 223, 173, 230, 122, 10, 3, 212, 113, 252, 21, 25, 222, 84, - 10, 3, 212, 113, 252, 21, 25, 171, 10, 3, 212, 113, 252, 21, 25, 214, - 107, 10, 3, 212, 113, 252, 21, 25, 202, 184, 10, 3, 212, 113, 252, 21, - 25, 196, 165, 10, 3, 212, 113, 221, 101, 25, 248, 140, 10, 3, 212, 113, - 221, 101, 25, 248, 141, 69, 10, 3, 168, 10, 3, 210, 200, 10, 3, 210, 156, - 10, 3, 210, 127, 10, 3, 209, 234, 10, 3, 209, 176, 10, 3, 209, 177, 25, - 65, 10, 3, 209, 177, 25, 252, 103, 10, 3, 209, 177, 25, 248, 140, 10, 3, - 209, 177, 25, 247, 218, 10, 3, 209, 177, 25, 73, 10, 3, 209, 177, 25, 70, - 10, 3, 209, 177, 25, 228, 0, 10, 3, 209, 177, 25, 69, 10, 3, 209, 177, - 25, 196, 165, 10, 3, 209, 177, 238, 163, 209, 176, 10, 3, 209, 113, 10, - 3, 209, 114, 25, 222, 65, 10, 3, 209, 114, 25, 196, 154, 10, 3, 209, 114, - 25, 191, 123, 10, 3, 209, 114, 211, 52, 209, 113, 10, 3, 166, 10, 3, 207, - 171, 10, 3, 206, 252, 10, 3, 206, 63, 10, 3, 189, 10, 3, 205, 181, 212, - 103, 10, 3, 205, 180, 10, 3, 205, 181, 25, 65, 10, 3, 205, 181, 25, 235, - 45, 10, 3, 205, 181, 25, 235, 43, 10, 3, 205, 181, 25, 144, 10, 3, 205, - 181, 25, 222, 69, 10, 3, 205, 181, 25, 220, 173, 10, 3, 205, 181, 25, - 218, 186, 10, 3, 205, 181, 25, 216, 81, 10, 3, 205, 181, 25, 212, 117, - 10, 3, 205, 181, 25, 205, 164, 10, 3, 205, 181, 25, 203, 74, 10, 3, 205, - 181, 25, 199, 231, 10, 3, 205, 181, 25, 196, 165, 10, 3, 205, 181, 25, - 196, 160, 10, 3, 205, 181, 25, 196, 116, 10, 3, 205, 181, 25, 196, 58, - 10, 3, 205, 181, 25, 196, 34, 10, 3, 205, 181, 138, 205, 180, 10, 3, 205, - 181, 230, 122, 10, 3, 205, 164, 10, 3, 205, 165, 220, 81, 25, 250, 157, - 10, 3, 205, 131, 10, 3, 205, 122, 10, 3, 203, 160, 10, 3, 203, 158, 10, - 3, 203, 159, 25, 65, 10, 3, 203, 159, 25, 249, 85, 10, 3, 203, 159, 25, - 230, 243, 10, 3, 203, 159, 25, 214, 107, 10, 3, 203, 159, 25, 202, 254, - 10, 3, 203, 159, 25, 197, 60, 10, 3, 203, 159, 25, 69, 10, 3, 203, 159, - 25, 126, 107, 65, 10, 3, 203, 156, 10, 3, 203, 154, 10, 3, 203, 126, 10, - 3, 203, 108, 10, 3, 203, 109, 228, 128, 10, 3, 203, 109, 138, 203, 109, - 231, 195, 138, 231, 195, 231, 164, 138, 231, 163, 10, 3, 203, 109, 138, - 203, 109, 199, 232, 138, 199, 232, 231, 164, 138, 231, 163, 10, 3, 203, - 101, 10, 3, 203, 96, 10, 3, 203, 92, 10, 3, 203, 91, 10, 3, 203, 88, 10, - 3, 203, 74, 10, 3, 203, 75, 25, 65, 10, 3, 203, 75, 25, 223, 152, 10, 3, - 203, 68, 10, 3, 203, 69, 25, 65, 10, 3, 203, 69, 25, 249, 65, 10, 3, 203, - 69, 25, 247, 194, 10, 3, 203, 69, 25, 236, 198, 10, 3, 203, 69, 25, 231, - 163, 10, 3, 203, 69, 25, 223, 172, 10, 3, 203, 69, 25, 223, 173, 230, - 122, 10, 3, 203, 69, 25, 220, 166, 10, 3, 203, 69, 25, 218, 188, 10, 3, - 203, 69, 25, 215, 124, 10, 3, 203, 69, 25, 205, 164, 10, 3, 203, 62, 10, - 3, 203, 57, 10, 3, 203, 58, 199, 79, 10, 3, 203, 58, 138, 203, 58, 247, - 183, 138, 247, 182, 10, 3, 203, 53, 10, 3, 203, 0, 10, 3, 203, 1, 138, - 223, 65, 203, 0, 10, 3, 202, 254, 10, 3, 202, 252, 10, 3, 202, 217, 10, - 3, 202, 218, 230, 122, 10, 3, 202, 196, 10, 3, 202, 194, 10, 3, 202, 195, - 138, 202, 195, 202, 254, 10, 3, 202, 186, 10, 3, 202, 184, 10, 3, 200, - 255, 10, 3, 201, 0, 138, 200, 255, 10, 3, 200, 211, 10, 3, 200, 210, 10, - 3, 200, 208, 10, 3, 200, 199, 10, 3, 200, 198, 10, 3, 200, 170, 10, 3, - 200, 169, 10, 3, 199, 247, 10, 3, 199, 248, 250, 143, 10, 3, 199, 248, - 25, 229, 126, 10, 3, 199, 248, 25, 216, 81, 10, 3, 199, 248, 230, 122, - 10, 3, 199, 231, 10, 3, 199, 232, 138, 199, 232, 213, 206, 138, 213, 206, - 236, 178, 138, 236, 177, 10, 3, 199, 232, 201, 184, 10, 3, 199, 218, 10, - 3, 199, 219, 25, 248, 140, 10, 3, 199, 219, 25, 230, 135, 10, 3, 199, - 219, 25, 203, 108, 10, 3, 199, 219, 25, 203, 0, 10, 3, 199, 219, 25, 197, - 78, 10, 3, 199, 219, 25, 196, 154, 10, 3, 199, 204, 10, 3, 199, 174, 10, - 3, 199, 140, 10, 3, 199, 141, 230, 122, 10, 3, 198, 188, 10, 3, 198, 189, - 199, 79, 10, 3, 198, 149, 10, 3, 198, 126, 10, 3, 198, 127, 25, 199, 204, - 10, 3, 198, 127, 138, 198, 126, 10, 3, 198, 127, 138, 198, 127, 231, 195, - 138, 231, 195, 231, 164, 138, 231, 163, 10, 3, 197, 90, 10, 3, 197, 78, - 10, 3, 197, 76, 10, 3, 197, 72, 10, 3, 197, 60, 10, 3, 197, 61, 138, 197, - 61, 191, 124, 138, 191, 123, 10, 3, 69, 10, 3, 126, 230, 135, 10, 3, 126, - 126, 69, 10, 3, 126, 138, 126, 210, 211, 138, 210, 211, 231, 164, 138, - 231, 163, 10, 3, 126, 138, 126, 200, 171, 138, 200, 170, 10, 3, 126, 138, - 126, 126, 207, 13, 138, 126, 207, 12, 10, 3, 196, 165, 10, 3, 196, 160, - 10, 3, 196, 154, 10, 3, 196, 155, 220, 166, 10, 3, 196, 155, 25, 249, 85, - 10, 3, 196, 155, 25, 216, 81, 10, 3, 196, 155, 25, 126, 107, 126, 107, - 69, 10, 3, 196, 155, 25, 126, 107, 126, 107, 126, 230, 122, 10, 3, 196, - 155, 230, 122, 10, 3, 196, 155, 203, 89, 10, 3, 196, 155, 203, 90, 25, - 249, 85, 10, 3, 196, 149, 10, 3, 196, 116, 10, 3, 196, 117, 25, 220, 80, - 10, 3, 196, 117, 25, 216, 214, 107, 237, 241, 10, 3, 196, 117, 25, 203, - 158, 10, 3, 196, 117, 25, 69, 10, 3, 196, 115, 10, 3, 196, 111, 10, 3, - 196, 112, 25, 222, 28, 10, 3, 196, 112, 25, 168, 10, 3, 196, 109, 10, 3, - 196, 110, 230, 122, 10, 3, 196, 58, 10, 3, 196, 59, 238, 163, 196, 58, - 10, 3, 196, 59, 203, 89, 10, 3, 196, 56, 10, 3, 196, 57, 25, 41, 107, - 144, 10, 3, 196, 57, 25, 41, 107, 180, 10, 3, 196, 57, 25, 251, 156, 10, - 3, 196, 57, 25, 144, 10, 3, 196, 57, 25, 212, 117, 10, 3, 196, 57, 25, - 196, 165, 10, 3, 196, 57, 25, 196, 166, 107, 250, 159, 10, 3, 196, 57, - 25, 196, 166, 107, 248, 140, 10, 3, 196, 55, 10, 3, 196, 52, 10, 3, 196, - 51, 10, 3, 196, 47, 10, 3, 196, 48, 25, 65, 10, 3, 196, 48, 25, 250, 153, - 10, 3, 196, 48, 25, 164, 10, 3, 196, 48, 25, 235, 31, 10, 3, 196, 48, 25, - 231, 203, 10, 3, 196, 48, 25, 231, 185, 10, 3, 196, 48, 25, 231, 172, - 199, 79, 10, 3, 196, 48, 25, 231, 163, 10, 3, 196, 48, 25, 230, 146, 10, - 3, 196, 48, 25, 144, 10, 3, 196, 48, 25, 223, 172, 10, 3, 196, 48, 25, - 223, 152, 10, 3, 196, 48, 25, 223, 34, 10, 3, 196, 48, 25, 221, 142, 10, - 3, 196, 48, 25, 218, 186, 10, 3, 196, 48, 25, 216, 26, 10, 3, 196, 48, - 25, 168, 10, 3, 196, 48, 25, 203, 108, 10, 3, 196, 48, 25, 202, 194, 10, - 3, 196, 48, 25, 197, 90, 10, 3, 196, 48, 25, 126, 107, 230, 135, 10, 3, - 196, 48, 25, 196, 154, 10, 3, 196, 48, 25, 196, 45, 10, 3, 196, 45, 10, - 3, 196, 46, 25, 69, 10, 3, 196, 34, 10, 3, 196, 35, 25, 65, 10, 3, 196, - 35, 25, 220, 208, 10, 3, 196, 35, 25, 220, 173, 10, 3, 196, 35, 25, 199, - 204, 10, 3, 196, 30, 10, 3, 196, 33, 10, 3, 196, 31, 10, 3, 196, 27, 10, - 3, 196, 12, 10, 3, 196, 13, 25, 222, 28, 10, 3, 196, 10, 10, 3, 191, 123, - 10, 3, 191, 124, 199, 79, 10, 3, 191, 124, 112, 25, 220, 173, 10, 3, 191, - 118, 10, 3, 191, 107, 10, 3, 191, 86, 10, 3, 191, 30, 10, 3, 191, 31, - 138, 191, 30, 10, 3, 191, 29, 10, 3, 191, 27, 10, 3, 191, 28, 222, 89, - 199, 79, 10, 3, 191, 22, 10, 3, 191, 13, 10, 3, 190, 251, 10, 3, 190, - 249, 10, 3, 190, 250, 25, 65, 10, 3, 190, 248, 10, 3, 190, 247, 10, 3, - 222, 53, 234, 94, 10, 3, 252, 104, 25, 212, 117, 10, 3, 252, 21, 25, 65, - 10, 3, 251, 95, 25, 220, 189, 10, 3, 237, 232, 221, 101, 25, 196, 166, - 107, 217, 20, 10, 3, 237, 230, 10, 3, 236, 178, 107, 203, 0, 10, 3, 235, - 44, 25, 203, 108, 10, 3, 233, 140, 25, 230, 135, 10, 3, 233, 140, 25, - 203, 108, 10, 3, 231, 202, 25, 251, 82, 107, 222, 70, 107, 65, 10, 3, - 231, 202, 25, 250, 157, 10, 3, 231, 127, 10, 3, 231, 5, 10, 3, 228, 100, - 10, 3, 222, 115, 25, 251, 40, 10, 3, 222, 115, 25, 250, 156, 10, 3, 222, - 115, 25, 230, 243, 10, 3, 222, 115, 25, 230, 135, 10, 3, 222, 115, 25, - 229, 127, 25, 250, 157, 10, 3, 222, 115, 25, 218, 186, 10, 3, 222, 115, - 25, 168, 10, 3, 222, 115, 25, 202, 248, 10, 3, 222, 115, 25, 197, 90, 10, - 3, 222, 115, 25, 196, 56, 10, 3, 220, 81, 25, 231, 16, 10, 3, 218, 202, - 203, 90, 25, 249, 85, 10, 3, 218, 202, 25, 233, 224, 107, 220, 13, 10, 3, - 218, 202, 25, 203, 0, 10, 3, 216, 153, 10, 3, 215, 86, 25, 191, 123, 10, - 3, 214, 238, 10, 3, 213, 165, 10, 3, 213, 164, 10, 3, 213, 163, 25, 249, - 65, 10, 3, 213, 163, 25, 231, 16, 10, 3, 212, 135, 206, 117, 213, 157, - 237, 79, 10, 3, 209, 235, 250, 143, 10, 3, 209, 117, 10, 3, 205, 181, 25, - 223, 173, 230, 122, 10, 3, 198, 180, 10, 3, 196, 117, 25, 216, 213, 10, - 3, 126, 69, 10, 167, 3, 103, 250, 159, 10, 167, 3, 115, 250, 159, 10, - 167, 3, 232, 90, 250, 159, 10, 167, 3, 232, 185, 250, 159, 10, 167, 3, - 202, 131, 250, 159, 10, 167, 3, 203, 242, 250, 159, 10, 167, 3, 234, 121, - 250, 159, 10, 167, 3, 213, 161, 250, 159, 10, 167, 3, 115, 236, 177, 10, - 167, 3, 232, 90, 236, 177, 10, 167, 3, 232, 185, 236, 177, 10, 167, 3, - 202, 131, 236, 177, 10, 167, 3, 203, 242, 236, 177, 10, 167, 3, 234, 121, - 236, 177, 10, 167, 3, 213, 161, 236, 177, 10, 167, 3, 232, 90, 69, 10, - 167, 3, 232, 185, 69, 10, 167, 3, 202, 131, 69, 10, 167, 3, 203, 242, 69, - 10, 167, 3, 234, 121, 69, 10, 167, 3, 213, 161, 69, 10, 167, 3, 91, 231, - 99, 10, 167, 3, 103, 231, 99, 10, 167, 3, 115, 231, 99, 10, 167, 3, 232, - 90, 231, 99, 10, 167, 3, 232, 185, 231, 99, 10, 167, 3, 202, 131, 231, - 99, 10, 167, 3, 203, 242, 231, 99, 10, 167, 3, 234, 121, 231, 99, 10, - 167, 3, 213, 161, 231, 99, 10, 167, 3, 91, 231, 96, 10, 167, 3, 103, 231, - 96, 10, 167, 3, 115, 231, 96, 10, 167, 3, 232, 90, 231, 96, 10, 167, 3, - 232, 185, 231, 96, 10, 167, 3, 103, 203, 126, 10, 167, 3, 115, 203, 126, - 10, 167, 3, 115, 203, 127, 195, 165, 20, 10, 167, 3, 232, 90, 203, 126, - 10, 167, 3, 232, 185, 203, 126, 10, 167, 3, 202, 131, 203, 126, 10, 167, - 3, 203, 242, 203, 126, 10, 167, 3, 234, 121, 203, 126, 10, 167, 3, 213, - 161, 203, 126, 10, 167, 3, 91, 203, 119, 10, 167, 3, 103, 203, 119, 10, - 167, 3, 115, 203, 119, 10, 167, 3, 115, 203, 120, 195, 165, 20, 10, 167, - 3, 232, 90, 203, 119, 10, 167, 3, 232, 185, 203, 119, 10, 167, 3, 203, - 127, 25, 231, 186, 107, 236, 177, 10, 167, 3, 203, 127, 25, 231, 186, - 107, 216, 26, 10, 167, 3, 91, 247, 178, 10, 167, 3, 103, 247, 178, 10, - 167, 3, 115, 247, 178, 10, 167, 3, 115, 247, 179, 195, 165, 20, 10, 167, - 3, 232, 90, 247, 178, 10, 167, 3, 232, 185, 247, 178, 10, 167, 3, 115, - 195, 165, 232, 107, 233, 225, 10, 167, 3, 115, 195, 165, 232, 107, 233, - 222, 10, 167, 3, 232, 90, 195, 165, 232, 107, 219, 92, 10, 167, 3, 232, - 90, 195, 165, 232, 107, 219, 90, 10, 167, 3, 232, 90, 195, 165, 232, 107, - 219, 93, 65, 10, 167, 3, 232, 90, 195, 165, 232, 107, 219, 93, 250, 70, - 10, 167, 3, 202, 131, 195, 165, 232, 107, 250, 155, 10, 167, 3, 203, 242, - 195, 165, 232, 107, 223, 143, 10, 167, 3, 203, 242, 195, 165, 232, 107, - 223, 145, 65, 10, 167, 3, 203, 242, 195, 165, 232, 107, 223, 145, 250, - 70, 10, 167, 3, 234, 121, 195, 165, 232, 107, 196, 29, 10, 167, 3, 234, - 121, 195, 165, 232, 107, 196, 28, 10, 167, 3, 213, 161, 195, 165, 232, - 107, 223, 160, 10, 167, 3, 213, 161, 195, 165, 232, 107, 223, 159, 10, - 167, 3, 213, 161, 195, 165, 232, 107, 223, 158, 10, 167, 3, 213, 161, - 195, 165, 232, 107, 223, 161, 65, 10, 167, 3, 103, 250, 160, 199, 79, 10, - 167, 3, 115, 250, 160, 199, 79, 10, 167, 3, 232, 90, 250, 160, 199, 79, - 10, 167, 3, 232, 185, 250, 160, 199, 79, 10, 167, 3, 202, 131, 250, 160, - 199, 79, 10, 167, 3, 91, 249, 49, 10, 167, 3, 103, 249, 49, 10, 167, 3, - 115, 249, 49, 10, 167, 3, 232, 90, 249, 49, 10, 167, 3, 232, 90, 249, 50, - 195, 165, 20, 10, 167, 3, 232, 185, 249, 49, 10, 167, 3, 232, 185, 249, - 50, 195, 165, 20, 10, 167, 3, 213, 174, 10, 167, 3, 213, 175, 10, 167, 3, - 91, 233, 221, 10, 167, 3, 103, 233, 221, 10, 167, 3, 91, 198, 252, 236, - 177, 10, 167, 3, 103, 198, 249, 236, 177, 10, 167, 3, 232, 185, 202, 118, - 236, 177, 10, 167, 3, 91, 198, 252, 195, 165, 232, 107, 65, 10, 167, 3, - 103, 198, 249, 195, 165, 232, 107, 65, 10, 167, 3, 91, 234, 117, 250, - 159, 10, 167, 3, 91, 208, 18, 250, 159, 10, 167, 3, 38, 250, 146, 91, - 202, 119, 10, 167, 3, 38, 250, 146, 91, 208, 17, 10, 167, 3, 91, 208, 18, - 230, 116, 10, 167, 3, 91, 134, 230, 116, 10, 167, 3, 234, 95, 91, 198, - 251, 10, 167, 3, 234, 95, 103, 198, 248, 10, 167, 3, 234, 95, 232, 97, - 10, 167, 3, 234, 95, 232, 230, 10, 167, 3, 232, 90, 126, 195, 165, 20, - 10, 167, 3, 232, 185, 126, 195, 165, 20, 10, 167, 3, 202, 131, 126, 195, - 165, 20, 10, 167, 3, 203, 242, 126, 195, 165, 20, 10, 167, 3, 234, 121, - 126, 195, 165, 20, 10, 167, 3, 213, 161, 126, 195, 165, 20, 10, 208, 145, - 3, 38, 250, 146, 193, 23, 236, 160, 10, 208, 145, 3, 81, 242, 35, 10, - 208, 145, 3, 236, 250, 242, 35, 10, 208, 145, 3, 236, 250, 197, 233, 10, - 208, 145, 3, 236, 250, 208, 23, 10, 3, 252, 104, 25, 212, 118, 199, 79, - 10, 3, 252, 104, 25, 202, 254, 10, 3, 251, 247, 25, 233, 223, 10, 3, 249, - 86, 25, 236, 178, 199, 79, 10, 3, 249, 72, 25, 252, 20, 10, 3, 249, 72, - 25, 213, 205, 10, 3, 249, 72, 25, 191, 123, 10, 3, 247, 219, 138, 247, - 219, 25, 214, 239, 10, 3, 237, 242, 25, 199, 204, 10, 3, 237, 232, 25, - 220, 173, 10, 3, 236, 211, 25, 223, 172, 10, 3, 236, 211, 25, 126, 126, - 69, 10, 3, 236, 209, 25, 196, 154, 10, 3, 235, 39, 25, 251, 40, 10, 3, - 235, 39, 25, 250, 159, 10, 3, 235, 39, 25, 250, 160, 250, 133, 219, 200, - 10, 3, 235, 39, 25, 236, 198, 10, 3, 235, 39, 25, 235, 31, 10, 3, 235, - 39, 25, 233, 242, 10, 3, 235, 39, 25, 231, 203, 10, 3, 235, 39, 25, 231, - 16, 10, 3, 235, 39, 25, 230, 253, 230, 122, 10, 3, 235, 39, 25, 230, 243, - 10, 3, 235, 39, 25, 144, 10, 3, 235, 39, 25, 229, 126, 10, 3, 235, 39, - 25, 223, 173, 230, 122, 10, 3, 235, 39, 25, 222, 28, 10, 3, 235, 39, 25, - 220, 173, 10, 3, 235, 39, 25, 220, 166, 10, 3, 235, 39, 25, 220, 167, - 107, 222, 28, 10, 3, 235, 39, 25, 220, 68, 10, 3, 235, 39, 25, 220, 11, - 10, 3, 235, 39, 25, 220, 12, 25, 220, 173, 10, 3, 235, 39, 25, 218, 192, - 107, 230, 243, 10, 3, 235, 39, 25, 217, 20, 10, 3, 235, 39, 25, 216, 154, - 10, 3, 235, 39, 25, 216, 81, 10, 3, 235, 39, 25, 213, 205, 10, 3, 235, - 39, 25, 209, 176, 10, 3, 235, 39, 25, 203, 108, 10, 3, 235, 39, 25, 202, - 218, 230, 122, 10, 3, 234, 175, 25, 220, 173, 10, 3, 234, 175, 25, 210, - 127, 10, 3, 233, 243, 192, 235, 10, 3, 233, 224, 238, 163, 233, 223, 10, - 3, 233, 140, 203, 90, 25, 250, 159, 10, 3, 233, 140, 203, 90, 25, 229, - 126, 10, 3, 233, 140, 203, 90, 25, 223, 173, 230, 122, 10, 3, 233, 140, - 203, 90, 25, 171, 10, 3, 233, 140, 203, 90, 25, 220, 13, 10, 3, 233, 140, - 203, 90, 25, 216, 213, 10, 3, 233, 140, 203, 90, 25, 216, 154, 10, 3, - 233, 140, 203, 90, 25, 200, 255, 10, 3, 233, 140, 25, 200, 255, 10, 3, - 231, 202, 25, 249, 71, 10, 3, 231, 202, 25, 236, 211, 230, 122, 10, 3, - 231, 202, 25, 235, 39, 25, 223, 173, 230, 122, 10, 3, 231, 202, 25, 235, - 39, 25, 222, 28, 10, 3, 231, 202, 25, 233, 245, 10, 3, 231, 202, 25, 231, - 203, 10, 3, 231, 202, 25, 231, 164, 107, 236, 255, 10, 3, 231, 202, 25, - 231, 164, 107, 214, 107, 10, 3, 231, 202, 25, 230, 72, 107, 65, 10, 3, - 231, 202, 25, 220, 167, 107, 222, 28, 10, 3, 231, 202, 25, 220, 11, 10, - 3, 231, 202, 25, 220, 12, 25, 220, 173, 10, 3, 231, 202, 25, 218, 191, - 10, 3, 231, 202, 25, 215, 87, 10, 3, 231, 202, 25, 214, 107, 10, 3, 231, - 202, 25, 214, 108, 107, 234, 174, 10, 3, 231, 202, 25, 214, 108, 107, - 231, 16, 10, 3, 231, 202, 25, 203, 68, 10, 3, 231, 202, 25, 191, 13, 10, - 3, 231, 197, 206, 117, 213, 157, 237, 79, 10, 3, 231, 98, 25, 69, 10, 3, - 230, 244, 25, 230, 244, 238, 163, 230, 243, 10, 3, 230, 145, 25, 223, - 173, 230, 122, 10, 3, 230, 136, 107, 230, 244, 25, 199, 204, 10, 3, 230, - 72, 199, 80, 230, 122, 10, 3, 229, 127, 25, 250, 160, 138, 229, 127, 25, - 250, 159, 10, 3, 222, 115, 25, 247, 218, 10, 3, 222, 115, 25, 157, 10, 3, - 222, 115, 25, 126, 126, 69, 10, 3, 222, 115, 25, 196, 58, 10, 3, 220, 81, - 25, 190, 252, 138, 190, 251, 10, 3, 220, 69, 10, 3, 220, 67, 10, 3, 220, - 66, 10, 3, 220, 65, 10, 3, 220, 64, 10, 3, 220, 63, 10, 3, 220, 62, 10, - 3, 220, 61, 138, 220, 61, 230, 122, 10, 3, 220, 60, 10, 3, 220, 59, 138, + 0, 201, 247, 233, 216, 77, 207, 252, 77, 31, 56, 236, 155, 56, 210, 13, + 56, 251, 137, 251, 49, 45, 210, 113, 50, 210, 113, 250, 193, 108, 56, + 242, 74, 228, 87, 232, 80, 201, 63, 202, 23, 17, 191, 77, 17, 107, 17, + 109, 17, 138, 17, 134, 17, 149, 17, 169, 17, 175, 17, 171, 17, 178, 242, + 83, 204, 25, 219, 180, 56, 234, 43, 56, 230, 204, 56, 208, 13, 77, 242, + 72, 250, 182, 8, 6, 1, 65, 8, 6, 1, 250, 120, 8, 6, 1, 247, 193, 8, 6, 1, + 238, 127, 8, 6, 1, 71, 8, 6, 1, 233, 175, 8, 6, 1, 232, 51, 8, 6, 1, 230, + 116, 8, 6, 1, 68, 8, 6, 1, 223, 35, 8, 6, 1, 222, 152, 8, 6, 1, 172, 8, + 6, 1, 218, 168, 8, 6, 1, 215, 61, 8, 6, 1, 74, 8, 6, 1, 210, 236, 8, 6, + 1, 208, 104, 8, 6, 1, 146, 8, 6, 1, 206, 8, 8, 6, 1, 200, 43, 8, 6, 1, + 66, 8, 6, 1, 196, 12, 8, 6, 1, 193, 224, 8, 6, 1, 192, 235, 8, 6, 1, 192, + 159, 8, 6, 1, 191, 166, 45, 51, 248, 53, 207, 19, 202, 23, 50, 51, 248, + 53, 243, 2, 252, 60, 130, 219, 112, 230, 211, 252, 60, 8, 2, 1, 65, 8, 2, + 1, 250, 120, 8, 2, 1, 247, 193, 8, 2, 1, 238, 127, 8, 2, 1, 71, 8, 2, 1, + 233, 175, 8, 2, 1, 232, 51, 8, 2, 1, 230, 116, 8, 2, 1, 68, 8, 2, 1, 223, + 35, 8, 2, 1, 222, 152, 8, 2, 1, 172, 8, 2, 1, 218, 168, 8, 2, 1, 215, 61, + 8, 2, 1, 74, 8, 2, 1, 210, 236, 8, 2, 1, 208, 104, 8, 2, 1, 146, 8, 2, 1, + 206, 8, 8, 2, 1, 200, 43, 8, 2, 1, 66, 8, 2, 1, 196, 12, 8, 2, 1, 193, + 224, 8, 2, 1, 192, 235, 8, 2, 1, 192, 159, 8, 2, 1, 191, 166, 45, 238, + 171, 248, 53, 81, 219, 112, 50, 238, 171, 248, 53, 198, 152, 213, 37, + 201, 247, 223, 93, 233, 216, 77, 247, 24, 56, 209, 8, 56, 238, 170, 56, + 192, 71, 56, 248, 22, 164, 205, 54, 56, 237, 42, 239, 6, 56, 233, 40, + 211, 50, 223, 144, 219, 219, 55, 251, 116, 207, 252, 77, 213, 12, 56, + 202, 32, 228, 88, 207, 78, 56, 217, 146, 237, 125, 56, 209, 80, 56, 200, + 182, 109, 200, 182, 138, 252, 47, 252, 60, 216, 91, 56, 209, 142, 56, 82, + 236, 140, 247, 35, 200, 182, 107, 217, 40, 211, 50, 223, 144, 206, 203, + 55, 251, 116, 207, 252, 77, 193, 246, 232, 118, 91, 208, 22, 193, 246, + 232, 118, 91, 230, 70, 193, 246, 232, 118, 115, 208, 20, 223, 93, 208, + 13, 77, 8, 6, 1, 42, 4, 230, 210, 8, 6, 1, 42, 4, 252, 46, 8, 6, 1, 42, + 4, 243, 1, 8, 6, 1, 42, 4, 198, 152, 8, 6, 1, 42, 4, 237, 42, 8, 6, 1, + 42, 4, 206, 189, 58, 8, 6, 1, 252, 25, 8, 6, 1, 247, 194, 4, 247, 35, 8, + 6, 1, 235, 15, 4, 230, 210, 8, 6, 1, 235, 15, 4, 252, 46, 8, 6, 1, 235, + 15, 4, 243, 1, 8, 6, 1, 235, 15, 4, 237, 42, 8, 6, 1, 228, 74, 4, 230, + 210, 8, 6, 1, 228, 74, 4, 252, 46, 8, 6, 1, 228, 74, 4, 243, 1, 8, 6, 1, + 228, 74, 4, 237, 42, 8, 6, 1, 233, 248, 8, 6, 1, 215, 62, 4, 198, 152, 8, + 6, 1, 187, 4, 230, 210, 8, 6, 1, 187, 4, 252, 46, 8, 6, 1, 187, 4, 243, + 1, 8, 6, 1, 187, 4, 198, 152, 8, 6, 1, 187, 4, 237, 42, 215, 127, 56, 8, + 6, 1, 187, 4, 106, 8, 6, 1, 126, 4, 230, 210, 8, 6, 1, 126, 4, 252, 46, + 8, 6, 1, 126, 4, 243, 1, 8, 6, 1, 126, 4, 237, 42, 8, 6, 1, 192, 160, 4, + 252, 46, 8, 6, 1, 198, 233, 8, 2, 1, 203, 127, 206, 8, 8, 2, 1, 42, 4, + 230, 210, 8, 2, 1, 42, 4, 252, 46, 8, 2, 1, 42, 4, 243, 1, 8, 2, 1, 42, + 4, 198, 152, 8, 2, 1, 42, 4, 237, 42, 8, 2, 1, 42, 4, 206, 189, 58, 8, 2, + 1, 252, 25, 8, 2, 1, 247, 194, 4, 247, 35, 8, 2, 1, 235, 15, 4, 230, 210, + 8, 2, 1, 235, 15, 4, 252, 46, 8, 2, 1, 235, 15, 4, 243, 1, 8, 2, 1, 235, + 15, 4, 237, 42, 8, 2, 1, 228, 74, 4, 230, 210, 8, 2, 1, 228, 74, 4, 252, + 46, 8, 2, 1, 228, 74, 4, 243, 1, 8, 2, 1, 228, 74, 4, 237, 42, 8, 2, 1, + 233, 248, 8, 2, 1, 215, 62, 4, 198, 152, 8, 2, 1, 187, 4, 230, 210, 8, 2, + 1, 187, 4, 252, 46, 8, 2, 1, 187, 4, 243, 1, 8, 2, 1, 187, 4, 198, 152, + 8, 2, 1, 187, 4, 237, 42, 236, 200, 56, 8, 2, 1, 187, 4, 106, 8, 2, 1, + 126, 4, 230, 210, 8, 2, 1, 126, 4, 252, 46, 8, 2, 1, 126, 4, 243, 1, 8, + 2, 1, 126, 4, 237, 42, 8, 2, 1, 192, 160, 4, 252, 46, 8, 2, 1, 198, 233, + 8, 2, 1, 192, 160, 4, 237, 42, 8, 6, 1, 42, 4, 217, 146, 8, 2, 1, 42, 4, + 217, 146, 8, 6, 1, 42, 4, 248, 36, 8, 2, 1, 42, 4, 248, 36, 8, 6, 1, 42, + 4, 211, 138, 8, 2, 1, 42, 4, 211, 138, 8, 6, 1, 247, 194, 4, 252, 46, 8, + 2, 1, 247, 194, 4, 252, 46, 8, 6, 1, 247, 194, 4, 243, 1, 8, 2, 1, 247, + 194, 4, 243, 1, 8, 6, 1, 247, 194, 4, 75, 58, 8, 2, 1, 247, 194, 4, 75, + 58, 8, 6, 1, 247, 194, 4, 247, 92, 8, 2, 1, 247, 194, 4, 247, 92, 8, 6, + 1, 238, 128, 4, 247, 92, 8, 2, 1, 238, 128, 4, 247, 92, 8, 6, 1, 238, + 128, 4, 106, 8, 2, 1, 238, 128, 4, 106, 8, 6, 1, 235, 15, 4, 217, 146, 8, + 2, 1, 235, 15, 4, 217, 146, 8, 6, 1, 235, 15, 4, 248, 36, 8, 2, 1, 235, + 15, 4, 248, 36, 8, 6, 1, 235, 15, 4, 75, 58, 8, 2, 1, 235, 15, 4, 75, 58, + 8, 6, 1, 235, 15, 4, 211, 138, 8, 2, 1, 235, 15, 4, 211, 138, 8, 6, 1, + 235, 15, 4, 247, 92, 8, 2, 1, 235, 15, 4, 247, 92, 8, 6, 1, 232, 52, 4, + 243, 1, 8, 2, 1, 232, 52, 4, 243, 1, 8, 6, 1, 232, 52, 4, 248, 36, 8, 2, + 1, 232, 52, 4, 248, 36, 8, 6, 1, 232, 52, 4, 75, 58, 8, 2, 1, 232, 52, 4, + 75, 58, 8, 6, 1, 232, 52, 4, 247, 35, 8, 2, 1, 232, 52, 4, 247, 35, 8, 6, + 1, 230, 117, 4, 243, 1, 8, 2, 1, 230, 117, 4, 243, 1, 8, 6, 1, 230, 117, + 4, 106, 8, 2, 1, 230, 117, 4, 106, 8, 6, 1, 228, 74, 4, 198, 152, 8, 2, + 1, 228, 74, 4, 198, 152, 8, 6, 1, 228, 74, 4, 217, 146, 8, 2, 1, 228, 74, + 4, 217, 146, 8, 6, 1, 228, 74, 4, 248, 36, 8, 2, 1, 228, 74, 4, 248, 36, + 8, 6, 1, 228, 74, 4, 211, 138, 8, 2, 1, 228, 74, 4, 211, 138, 8, 6, 1, + 228, 74, 4, 75, 58, 8, 2, 1, 236, 139, 68, 8, 6, 34, 223, 197, 8, 2, 34, + 223, 197, 8, 6, 1, 223, 36, 4, 243, 1, 8, 2, 1, 223, 36, 4, 243, 1, 8, 6, + 1, 222, 153, 4, 247, 35, 8, 2, 1, 222, 153, 4, 247, 35, 8, 2, 1, 221, 8, + 8, 6, 1, 220, 143, 4, 252, 46, 8, 2, 1, 220, 143, 4, 252, 46, 8, 6, 1, + 220, 143, 4, 247, 35, 8, 2, 1, 220, 143, 4, 247, 35, 8, 6, 1, 220, 143, + 4, 247, 92, 8, 2, 1, 220, 143, 4, 247, 92, 8, 6, 1, 220, 143, 4, 82, 236, + 140, 8, 2, 1, 220, 143, 4, 82, 236, 140, 8, 6, 1, 220, 143, 4, 106, 8, 2, + 1, 220, 143, 4, 106, 8, 6, 1, 215, 62, 4, 252, 46, 8, 2, 1, 215, 62, 4, + 252, 46, 8, 6, 1, 215, 62, 4, 247, 35, 8, 2, 1, 215, 62, 4, 247, 35, 8, + 6, 1, 215, 62, 4, 247, 92, 8, 2, 1, 215, 62, 4, 247, 92, 8, 2, 1, 215, + 62, 208, 233, 247, 205, 251, 49, 8, 6, 1, 234, 88, 8, 2, 1, 234, 88, 8, + 6, 1, 187, 4, 217, 146, 8, 2, 1, 187, 4, 217, 146, 8, 6, 1, 187, 4, 248, + 36, 8, 2, 1, 187, 4, 248, 36, 8, 6, 1, 187, 4, 55, 252, 46, 8, 2, 1, 187, + 4, 55, 252, 46, 8, 6, 34, 211, 151, 8, 2, 34, 211, 151, 8, 6, 1, 207, + 222, 4, 252, 46, 8, 2, 1, 207, 222, 4, 252, 46, 8, 6, 1, 207, 222, 4, + 247, 35, 8, 2, 1, 207, 222, 4, 247, 35, 8, 6, 1, 207, 222, 4, 247, 92, 8, + 2, 1, 207, 222, 4, 247, 92, 8, 6, 1, 206, 9, 4, 252, 46, 8, 2, 1, 206, 9, + 4, 252, 46, 8, 6, 1, 206, 9, 4, 243, 1, 8, 2, 1, 206, 9, 4, 243, 1, 8, 6, + 1, 206, 9, 4, 247, 35, 8, 2, 1, 206, 9, 4, 247, 35, 8, 6, 1, 206, 9, 4, + 247, 92, 8, 2, 1, 206, 9, 4, 247, 92, 8, 6, 1, 200, 44, 4, 247, 35, 8, 2, + 1, 200, 44, 4, 247, 35, 8, 6, 1, 200, 44, 4, 247, 92, 8, 2, 1, 200, 44, + 4, 247, 92, 8, 6, 1, 200, 44, 4, 106, 8, 2, 1, 200, 44, 4, 106, 8, 6, 1, + 126, 4, 198, 152, 8, 2, 1, 126, 4, 198, 152, 8, 6, 1, 126, 4, 217, 146, + 8, 2, 1, 126, 4, 217, 146, 8, 6, 1, 126, 4, 248, 36, 8, 2, 1, 126, 4, + 248, 36, 8, 6, 1, 126, 4, 206, 189, 58, 8, 2, 1, 126, 4, 206, 189, 58, 8, + 6, 1, 126, 4, 55, 252, 46, 8, 2, 1, 126, 4, 55, 252, 46, 8, 6, 1, 126, 4, + 211, 138, 8, 2, 1, 126, 4, 211, 138, 8, 6, 1, 193, 225, 4, 243, 1, 8, 2, + 1, 193, 225, 4, 243, 1, 8, 6, 1, 192, 160, 4, 243, 1, 8, 2, 1, 192, 160, + 4, 243, 1, 8, 6, 1, 192, 160, 4, 237, 42, 8, 6, 1, 191, 167, 4, 252, 46, + 8, 2, 1, 191, 167, 4, 252, 46, 8, 6, 1, 191, 167, 4, 75, 58, 8, 2, 1, + 191, 167, 4, 75, 58, 8, 6, 1, 191, 167, 4, 247, 92, 8, 2, 1, 191, 167, 4, + 247, 92, 8, 2, 1, 179, 206, 8, 8, 2, 1, 78, 4, 106, 8, 6, 1, 78, 4, 102, + 8, 6, 1, 78, 4, 198, 51, 8, 2, 1, 78, 4, 198, 51, 8, 6, 1, 163, 169, 8, + 2, 1, 163, 169, 8, 6, 1, 211, 77, 74, 8, 6, 1, 247, 194, 4, 102, 8, 2, 1, + 247, 194, 4, 102, 8, 6, 1, 252, 0, 238, 127, 8, 6, 1, 238, 128, 4, 102, + 8, 6, 1, 238, 128, 4, 198, 51, 8, 2, 1, 238, 128, 4, 198, 51, 8, 2, 1, + 153, 237, 106, 8, 6, 1, 207, 18, 71, 8, 6, 1, 205, 86, 8, 6, 1, 211, 77, + 71, 8, 6, 1, 233, 176, 4, 102, 8, 2, 1, 233, 176, 4, 102, 8, 6, 1, 232, + 52, 4, 102, 8, 6, 1, 231, 211, 8, 2, 1, 228, 126, 8, 6, 1, 223, 83, 8, 6, + 1, 228, 74, 4, 106, 8, 6, 1, 222, 153, 4, 102, 8, 2, 1, 222, 153, 4, 102, + 8, 2, 1, 220, 143, 4, 164, 8, 2, 1, 220, 33, 4, 106, 8, 6, 1, 153, 218, + 168, 8, 6, 1, 215, 62, 4, 45, 102, 8, 2, 1, 215, 62, 4, 179, 50, 219, + 212, 8, 6, 1, 187, 4, 82, 198, 152, 8, 6, 1, 187, 4, 228, 187, 8, 2, 1, + 187, 4, 228, 187, 8, 6, 1, 211, 133, 8, 2, 1, 211, 133, 8, 6, 1, 210, + 237, 4, 102, 8, 2, 1, 210, 237, 4, 102, 8, 1, 191, 228, 8, 6, 1, 163, + 109, 8, 2, 1, 163, 109, 8, 6, 1, 234, 12, 8, 1, 207, 18, 234, 13, 219, 4, + 8, 2, 1, 200, 44, 4, 210, 192, 102, 8, 6, 1, 200, 44, 4, 102, 8, 2, 1, + 200, 44, 4, 102, 8, 6, 1, 200, 44, 4, 207, 24, 102, 8, 6, 1, 126, 4, 228, + 187, 8, 2, 1, 126, 4, 228, 187, 8, 6, 1, 196, 70, 8, 6, 1, 196, 13, 4, + 102, 8, 6, 1, 192, 160, 4, 102, 8, 2, 1, 192, 160, 4, 102, 8, 6, 1, 191, + 167, 4, 106, 8, 2, 1, 191, 167, 4, 106, 8, 6, 1, 233, 178, 8, 6, 1, 233, + 179, 207, 17, 8, 2, 1, 233, 179, 207, 17, 8, 2, 1, 233, 179, 4, 199, 215, + 8, 1, 105, 4, 106, 8, 6, 1, 163, 149, 8, 2, 1, 163, 149, 8, 1, 223, 93, + 231, 11, 201, 64, 4, 106, 8, 1, 192, 238, 8, 1, 237, 98, 242, 231, 8, 1, + 220, 3, 242, 231, 8, 1, 251, 150, 242, 231, 8, 1, 207, 24, 242, 231, 8, + 6, 1, 235, 37, 4, 247, 92, 8, 6, 1, 238, 128, 4, 2, 1, 191, 167, 4, 247, + 92, 8, 2, 1, 235, 37, 4, 247, 92, 8, 6, 1, 219, 77, 8, 6, 1, 220, 143, 4, + 2, 1, 223, 35, 8, 2, 1, 219, 77, 8, 6, 1, 213, 158, 8, 6, 1, 215, 62, 4, + 2, 1, 223, 35, 8, 2, 1, 213, 158, 8, 6, 1, 42, 4, 247, 92, 8, 2, 1, 42, + 4, 247, 92, 8, 6, 1, 228, 74, 4, 247, 92, 8, 2, 1, 228, 74, 4, 247, 92, + 8, 6, 1, 187, 4, 247, 92, 8, 2, 1, 187, 4, 247, 92, 8, 6, 1, 126, 4, 247, + 92, 8, 2, 1, 126, 4, 247, 92, 8, 6, 1, 126, 4, 237, 43, 23, 217, 146, 8, + 2, 1, 126, 4, 237, 43, 23, 217, 146, 8, 6, 1, 126, 4, 237, 43, 23, 252, + 46, 8, 2, 1, 126, 4, 237, 43, 23, 252, 46, 8, 6, 1, 126, 4, 237, 43, 23, + 247, 92, 8, 2, 1, 126, 4, 237, 43, 23, 247, 92, 8, 6, 1, 126, 4, 237, 43, + 23, 230, 210, 8, 2, 1, 126, 4, 237, 43, 23, 230, 210, 8, 2, 1, 153, 71, + 8, 6, 1, 42, 4, 237, 43, 23, 217, 146, 8, 2, 1, 42, 4, 237, 43, 23, 217, + 146, 8, 6, 1, 42, 4, 75, 93, 23, 217, 146, 8, 2, 1, 42, 4, 75, 93, 23, + 217, 146, 8, 6, 1, 252, 26, 4, 217, 146, 8, 2, 1, 252, 26, 4, 217, 146, + 8, 6, 1, 232, 52, 4, 106, 8, 2, 1, 232, 52, 4, 106, 8, 6, 1, 232, 52, 4, + 247, 92, 8, 2, 1, 232, 52, 4, 247, 92, 8, 6, 1, 222, 153, 4, 247, 92, 8, + 2, 1, 222, 153, 4, 247, 92, 8, 6, 1, 187, 4, 211, 138, 8, 2, 1, 187, 4, + 211, 138, 8, 6, 1, 187, 4, 211, 139, 23, 217, 146, 8, 2, 1, 187, 4, 211, + 139, 23, 217, 146, 8, 6, 1, 233, 179, 4, 247, 92, 8, 2, 1, 233, 179, 4, + 247, 92, 8, 2, 1, 223, 36, 4, 247, 92, 8, 6, 1, 235, 36, 8, 6, 1, 238, + 128, 4, 2, 1, 191, 166, 8, 2, 1, 235, 36, 8, 6, 1, 232, 52, 4, 252, 46, + 8, 2, 1, 232, 52, 4, 252, 46, 8, 6, 1, 228, 123, 8, 6, 1, 192, 238, 8, 6, + 1, 215, 62, 4, 230, 210, 8, 2, 1, 215, 62, 4, 230, 210, 8, 6, 1, 42, 4, + 206, 189, 93, 23, 252, 46, 8, 2, 1, 42, 4, 206, 189, 93, 23, 252, 46, 8, + 6, 1, 252, 26, 4, 252, 46, 8, 2, 1, 252, 26, 4, 252, 46, 8, 6, 1, 187, 4, + 201, 28, 23, 252, 46, 8, 2, 1, 187, 4, 201, 28, 23, 252, 46, 8, 6, 1, 42, + 4, 55, 230, 210, 8, 2, 1, 42, 4, 55, 230, 210, 8, 6, 1, 42, 4, 223, 93, + 248, 36, 8, 2, 1, 42, 4, 223, 93, 248, 36, 8, 6, 1, 235, 15, 4, 55, 230, + 210, 8, 2, 1, 235, 15, 4, 55, 230, 210, 8, 6, 1, 235, 15, 4, 223, 93, + 248, 36, 8, 2, 1, 235, 15, 4, 223, 93, 248, 36, 8, 6, 1, 228, 74, 4, 55, + 230, 210, 8, 2, 1, 228, 74, 4, 55, 230, 210, 8, 6, 1, 228, 74, 4, 223, + 93, 248, 36, 8, 2, 1, 228, 74, 4, 223, 93, 248, 36, 8, 6, 1, 187, 4, 55, + 230, 210, 8, 2, 1, 187, 4, 55, 230, 210, 8, 6, 1, 187, 4, 223, 93, 248, + 36, 8, 2, 1, 187, 4, 223, 93, 248, 36, 8, 6, 1, 207, 222, 4, 55, 230, + 210, 8, 2, 1, 207, 222, 4, 55, 230, 210, 8, 6, 1, 207, 222, 4, 223, 93, + 248, 36, 8, 2, 1, 207, 222, 4, 223, 93, 248, 36, 8, 6, 1, 126, 4, 55, + 230, 210, 8, 2, 1, 126, 4, 55, 230, 210, 8, 6, 1, 126, 4, 223, 93, 248, + 36, 8, 2, 1, 126, 4, 223, 93, 248, 36, 8, 6, 1, 206, 9, 4, 242, 75, 60, + 8, 2, 1, 206, 9, 4, 242, 75, 60, 8, 6, 1, 200, 44, 4, 242, 75, 60, 8, 2, + 1, 200, 44, 4, 242, 75, 60, 8, 6, 1, 191, 248, 8, 2, 1, 191, 248, 8, 6, + 1, 230, 117, 4, 247, 92, 8, 2, 1, 230, 117, 4, 247, 92, 8, 6, 1, 215, 62, + 4, 179, 50, 219, 212, 8, 2, 1, 238, 128, 4, 238, 175, 8, 6, 1, 211, 19, + 8, 2, 1, 211, 19, 8, 6, 1, 191, 167, 4, 102, 8, 2, 1, 191, 167, 4, 102, + 8, 6, 1, 42, 4, 75, 58, 8, 2, 1, 42, 4, 75, 58, 8, 6, 1, 235, 15, 4, 247, + 35, 8, 2, 1, 235, 15, 4, 247, 35, 8, 6, 1, 187, 4, 237, 43, 23, 217, 146, + 8, 2, 1, 187, 4, 237, 43, 23, 217, 146, 8, 6, 1, 187, 4, 198, 153, 23, + 217, 146, 8, 2, 1, 187, 4, 198, 153, 23, 217, 146, 8, 6, 1, 187, 4, 75, + 58, 8, 2, 1, 187, 4, 75, 58, 8, 6, 1, 187, 4, 75, 93, 23, 217, 146, 8, 2, + 1, 187, 4, 75, 93, 23, 217, 146, 8, 6, 1, 192, 160, 4, 217, 146, 8, 2, 1, + 192, 160, 4, 217, 146, 8, 2, 1, 220, 143, 4, 238, 175, 8, 2, 1, 215, 62, + 4, 238, 175, 8, 2, 1, 200, 44, 4, 238, 175, 8, 2, 1, 236, 139, 223, 35, + 8, 2, 1, 237, 201, 237, 2, 8, 2, 1, 208, 34, 237, 2, 8, 6, 1, 42, 4, 106, + 8, 6, 1, 247, 194, 4, 106, 8, 2, 1, 247, 194, 4, 106, 8, 6, 1, 220, 143, + 4, 164, 8, 6, 1, 200, 44, 4, 237, 39, 106, 8, 2, 1, 206, 9, 4, 200, 146, + 199, 215, 8, 2, 1, 191, 167, 4, 200, 146, 199, 215, 8, 6, 1, 231, 11, + 201, 63, 8, 2, 1, 231, 11, 201, 63, 8, 6, 1, 78, 4, 106, 8, 6, 1, 126, + 164, 8, 6, 1, 153, 196, 12, 8, 6, 1, 235, 15, 4, 106, 8, 2, 1, 235, 15, + 4, 106, 8, 6, 1, 223, 36, 4, 106, 8, 2, 1, 223, 36, 4, 106, 8, 6, 1, 2, + 208, 105, 4, 228, 251, 199, 215, 8, 2, 1, 208, 105, 4, 228, 251, 199, + 215, 8, 6, 1, 207, 222, 4, 106, 8, 2, 1, 207, 222, 4, 106, 8, 6, 1, 192, + 160, 4, 106, 8, 2, 1, 192, 160, 4, 106, 8, 2, 1, 153, 65, 8, 2, 1, 251, + 160, 8, 2, 1, 153, 251, 160, 8, 2, 1, 78, 4, 102, 8, 2, 1, 211, 77, 74, + 8, 2, 1, 247, 194, 4, 238, 175, 8, 2, 1, 238, 128, 4, 199, 215, 8, 2, 1, + 238, 128, 4, 102, 8, 2, 1, 207, 18, 71, 8, 2, 1, 205, 86, 8, 2, 1, 205, + 87, 4, 102, 8, 2, 1, 211, 77, 71, 8, 2, 1, 207, 18, 211, 77, 71, 8, 2, 1, + 207, 18, 211, 77, 235, 15, 4, 102, 8, 2, 1, 242, 219, 207, 18, 211, 77, + 71, 8, 2, 1, 236, 139, 223, 36, 4, 106, 8, 2, 1, 232, 52, 4, 102, 8, 2, + 1, 27, 232, 51, 8, 1, 2, 6, 232, 51, 8, 2, 1, 231, 211, 8, 2, 1, 207, + 140, 228, 187, 8, 2, 1, 153, 230, 116, 8, 2, 1, 230, 117, 4, 102, 8, 2, + 1, 229, 197, 4, 102, 8, 2, 1, 228, 74, 4, 106, 8, 2, 1, 223, 83, 8, 1, 2, + 6, 68, 8, 2, 1, 220, 143, 4, 82, 198, 152, 8, 2, 1, 220, 143, 4, 248, + 231, 8, 2, 1, 220, 143, 4, 207, 24, 102, 8, 2, 1, 219, 162, 8, 2, 1, 153, + 218, 168, 8, 2, 1, 153, 218, 169, 4, 179, 219, 212, 8, 2, 1, 218, 169, 4, + 102, 8, 2, 1, 215, 62, 4, 45, 102, 8, 2, 1, 215, 62, 4, 207, 24, 102, 8, + 1, 2, 6, 215, 61, 8, 2, 1, 249, 82, 74, 8, 1, 2, 6, 211, 151, 8, 2, 1, + 242, 219, 211, 110, 8, 2, 1, 209, 211, 8, 2, 1, 153, 146, 8, 2, 1, 153, + 207, 222, 4, 179, 219, 212, 8, 2, 1, 153, 207, 222, 4, 102, 8, 2, 1, 207, + 222, 4, 179, 219, 212, 8, 2, 1, 207, 222, 4, 199, 215, 8, 2, 1, 207, 222, + 4, 232, 233, 8, 2, 1, 207, 18, 207, 222, 4, 232, 233, 8, 1, 2, 6, 146, 8, + 1, 2, 6, 223, 93, 146, 8, 2, 1, 206, 9, 4, 102, 8, 2, 1, 234, 12, 8, 2, + 1, 236, 139, 223, 36, 4, 201, 28, 23, 102, 8, 2, 1, 201, 187, 207, 18, + 234, 12, 8, 2, 1, 234, 13, 4, 238, 175, 8, 2, 1, 153, 200, 43, 8, 2, 1, + 200, 44, 4, 207, 24, 102, 8, 2, 1, 126, 164, 8, 2, 1, 196, 70, 8, 2, 1, + 196, 13, 4, 102, 8, 2, 1, 153, 196, 12, 8, 2, 1, 153, 193, 224, 8, 2, 1, + 153, 192, 159, 8, 1, 2, 6, 192, 159, 8, 2, 1, 191, 167, 4, 207, 24, 102, + 8, 2, 1, 191, 167, 4, 238, 175, 8, 2, 1, 233, 178, 8, 2, 1, 233, 179, 4, + 238, 175, 8, 1, 231, 11, 201, 63, 8, 1, 209, 219, 195, 20, 232, 104, 8, + 1, 223, 93, 231, 11, 201, 63, 8, 1, 201, 36, 247, 193, 8, 1, 248, 172, + 242, 231, 8, 1, 2, 6, 250, 120, 8, 2, 1, 242, 219, 211, 77, 71, 8, 1, 2, + 6, 232, 52, 4, 102, 8, 1, 2, 6, 230, 116, 8, 2, 1, 223, 36, 4, 238, 212, + 8, 2, 1, 153, 222, 152, 8, 1, 2, 6, 172, 8, 2, 1, 208, 105, 4, 102, 8, 1, + 231, 11, 201, 64, 4, 106, 8, 1, 207, 18, 231, 11, 201, 64, 4, 106, 8, 2, + 1, 235, 37, 237, 2, 8, 2, 1, 237, 70, 237, 2, 8, 2, 1, 235, 37, 237, 3, + 4, 238, 175, 8, 2, 1, 197, 170, 237, 2, 8, 2, 1, 199, 79, 237, 2, 8, 2, + 1, 199, 152, 237, 3, 4, 238, 175, 8, 2, 1, 233, 37, 237, 2, 8, 2, 1, 218, + 227, 237, 2, 8, 2, 1, 218, 170, 237, 2, 8, 1, 248, 172, 210, 12, 8, 1, + 248, 180, 210, 12, 8, 2, 1, 153, 230, 117, 4, 232, 233, 8, 2, 1, 153, + 230, 117, 4, 232, 234, 23, 199, 215, 52, 1, 2, 230, 116, 52, 1, 2, 230, + 117, 4, 102, 52, 1, 2, 223, 35, 52, 1, 2, 146, 52, 1, 2, 153, 146, 52, 1, + 2, 153, 207, 222, 4, 102, 52, 1, 2, 6, 223, 93, 146, 52, 1, 2, 193, 224, + 52, 1, 2, 192, 159, 52, 1, 208, 215, 52, 1, 55, 208, 215, 52, 1, 153, + 242, 74, 52, 1, 251, 49, 52, 1, 207, 18, 242, 74, 52, 1, 50, 132, 206, + 188, 52, 1, 45, 132, 206, 188, 52, 1, 231, 11, 201, 63, 52, 1, 207, 18, + 231, 11, 201, 63, 52, 1, 45, 250, 235, 52, 1, 50, 250, 235, 52, 1, 133, + 250, 235, 52, 1, 144, 250, 235, 52, 1, 243, 2, 252, 60, 247, 92, 52, 1, + 81, 219, 112, 52, 1, 217, 146, 52, 1, 252, 47, 252, 60, 52, 1, 230, 211, + 252, 60, 52, 1, 130, 81, 219, 112, 52, 1, 130, 217, 146, 52, 1, 130, 230, + 211, 252, 60, 52, 1, 130, 252, 47, 252, 60, 52, 1, 197, 238, 242, 83, 52, + 1, 132, 197, 238, 242, 83, 52, 1, 247, 20, 50, 132, 206, 188, 52, 1, 247, + 20, 45, 132, 206, 188, 52, 1, 133, 199, 228, 52, 1, 144, 199, 228, 52, 1, + 108, 56, 52, 1, 216, 35, 56, 248, 36, 75, 58, 206, 189, 58, 211, 138, 2, + 198, 152, 55, 252, 47, 252, 60, 52, 1, 207, 2, 102, 52, 1, 238, 218, 252, + 60, 52, 1, 2, 231, 211, 52, 1, 2, 172, 52, 1, 2, 206, 8, 52, 1, 2, 192, + 235, 52, 1, 2, 207, 18, 231, 11, 201, 63, 52, 1, 233, 200, 163, 164, 52, + 1, 137, 163, 164, 52, 1, 216, 87, 163, 164, 52, 1, 130, 163, 164, 52, 1, + 233, 199, 163, 164, 52, 1, 192, 22, 237, 95, 163, 77, 52, 1, 192, 107, + 237, 95, 163, 77, 52, 1, 195, 18, 52, 1, 196, 109, 52, 1, 55, 251, 49, + 52, 1, 130, 144, 250, 235, 52, 1, 130, 133, 250, 235, 52, 1, 130, 45, + 250, 235, 52, 1, 130, 50, 250, 235, 52, 1, 130, 206, 188, 52, 1, 82, 230, + 211, 252, 60, 52, 1, 82, 55, 230, 211, 252, 60, 52, 1, 82, 55, 252, 47, + 252, 60, 52, 1, 130, 198, 152, 52, 1, 207, 147, 242, 83, 52, 1, 248, 249, + 137, 198, 79, 52, 1, 234, 95, 137, 198, 79, 52, 1, 248, 249, 130, 198, + 79, 52, 1, 234, 95, 130, 198, 79, 52, 1, 203, 104, 52, 1, 211, 77, 203, + 104, 52, 1, 130, 45, 57, 33, 230, 211, 252, 60, 33, 252, 47, 252, 60, 33, + 243, 2, 252, 60, 33, 198, 152, 33, 217, 146, 33, 210, 254, 33, 248, 36, + 33, 75, 58, 33, 237, 42, 33, 228, 251, 58, 33, 206, 189, 58, 33, 55, 252, + 47, 252, 60, 33, 247, 92, 33, 81, 219, 113, 58, 33, 55, 81, 219, 113, 58, + 33, 55, 230, 211, 252, 60, 33, 247, 119, 33, 223, 93, 248, 36, 33, 153, + 242, 75, 58, 33, 242, 75, 58, 33, 207, 18, 242, 75, 58, 33, 242, 75, 93, + 183, 33, 230, 211, 252, 61, 60, 33, 252, 47, 252, 61, 60, 33, 45, 199, + 229, 60, 33, 50, 199, 229, 60, 33, 45, 251, 116, 58, 33, 228, 187, 33, + 45, 132, 206, 189, 60, 33, 133, 199, 229, 60, 33, 144, 199, 229, 60, 33, + 108, 3, 60, 33, 216, 35, 3, 60, 33, 210, 190, 228, 251, 60, 33, 207, 24, + 228, 251, 60, 33, 75, 60, 33, 237, 43, 60, 33, 206, 189, 60, 33, 242, 75, + 60, 33, 247, 35, 33, 211, 138, 33, 81, 219, 113, 60, 33, 248, 29, 60, 33, + 223, 93, 55, 251, 15, 60, 33, 247, 93, 60, 33, 243, 2, 252, 61, 60, 33, + 248, 37, 60, 33, 223, 93, 248, 37, 60, 33, 198, 153, 60, 33, 217, 147, + 60, 33, 130, 219, 112, 33, 55, 130, 219, 112, 33, 198, 153, 210, 255, 33, + 203, 40, 201, 28, 210, 255, 33, 179, 201, 28, 210, 255, 33, 203, 40, 202, + 24, 210, 255, 33, 179, 202, 24, 210, 255, 33, 50, 132, 206, 189, 60, 33, + 223, 93, 248, 29, 60, 33, 51, 60, 33, 205, 62, 60, 33, 192, 236, 58, 33, + 81, 198, 152, 33, 55, 210, 254, 33, 230, 211, 163, 77, 33, 252, 47, 163, + 77, 33, 35, 210, 4, 33, 35, 221, 30, 33, 35, 237, 36, 198, 60, 33, 35, + 191, 233, 33, 248, 29, 58, 33, 234, 43, 3, 60, 33, 55, 81, 219, 113, 60, + 33, 45, 251, 116, 60, 33, 213, 12, 198, 153, 58, 33, 229, 1, 58, 33, 251, + 165, 234, 45, 119, 58, 33, 45, 50, 64, 60, 33, 196, 66, 64, 60, 33, 230, + 217, 222, 196, 33, 50, 250, 236, 58, 33, 45, 132, 206, 189, 58, 33, 233, + 34, 33, 192, 236, 60, 33, 45, 250, 236, 60, 33, 50, 250, 236, 60, 33, 50, + 250, 236, 23, 133, 250, 236, 60, 33, 50, 132, 206, 189, 58, 33, 75, 93, + 183, 33, 250, 194, 60, 33, 55, 206, 189, 60, 33, 191, 21, 58, 33, 55, + 248, 37, 60, 33, 55, 248, 36, 33, 55, 217, 146, 33, 55, 217, 147, 60, 33, + 55, 198, 152, 33, 55, 223, 93, 248, 36, 33, 55, 96, 64, 60, 33, 8, 2, 1, + 65, 33, 8, 2, 1, 71, 33, 8, 2, 1, 68, 33, 8, 2, 1, 74, 33, 8, 2, 1, 66, + 33, 8, 2, 1, 247, 193, 33, 8, 2, 1, 238, 127, 33, 8, 2, 1, 230, 116, 33, + 8, 2, 1, 218, 168, 33, 8, 2, 1, 146, 33, 8, 2, 1, 200, 43, 33, 8, 2, 1, + 196, 12, 33, 8, 2, 1, 192, 235, 35, 6, 1, 229, 185, 35, 2, 1, 229, 185, + 35, 6, 1, 251, 14, 205, 145, 35, 2, 1, 251, 14, 205, 145, 35, 212, 134, + 56, 35, 110, 212, 134, 56, 35, 6, 1, 210, 171, 237, 10, 35, 2, 1, 210, + 171, 237, 10, 35, 191, 233, 35, 2, 207, 18, 218, 206, 202, 197, 113, 35, + 2, 235, 138, 218, 206, 202, 197, 113, 35, 2, 207, 18, 235, 138, 218, 206, + 202, 197, 113, 35, 208, 13, 77, 35, 6, 1, 191, 240, 35, 198, 60, 35, 237, + 36, 198, 60, 35, 6, 1, 251, 161, 4, 198, 60, 35, 251, 94, 199, 108, 35, + 6, 1, 234, 48, 4, 198, 60, 35, 6, 1, 233, 254, 4, 198, 60, 35, 6, 1, 223, + 84, 4, 198, 60, 35, 6, 1, 211, 108, 4, 198, 60, 35, 6, 1, 196, 71, 4, + 198, 60, 35, 6, 1, 211, 111, 4, 198, 60, 35, 2, 1, 223, 84, 4, 237, 36, + 23, 198, 60, 35, 6, 1, 251, 160, 35, 6, 1, 248, 212, 35, 6, 1, 231, 211, + 35, 6, 1, 237, 106, 35, 6, 1, 234, 47, 35, 6, 1, 191, 76, 35, 6, 1, 233, + 253, 35, 6, 1, 199, 15, 35, 6, 1, 223, 83, 35, 6, 1, 222, 72, 35, 6, 1, + 220, 31, 35, 6, 1, 215, 155, 35, 6, 1, 212, 178, 35, 6, 1, 192, 207, 35, + 6, 1, 211, 107, 35, 6, 1, 209, 185, 35, 6, 1, 207, 3, 35, 6, 1, 202, 196, + 35, 6, 1, 199, 166, 35, 6, 1, 196, 70, 35, 6, 1, 209, 211, 35, 6, 1, 243, + 95, 35, 6, 1, 208, 176, 35, 6, 1, 211, 110, 35, 6, 1, 223, 84, 4, 237, + 35, 35, 6, 1, 196, 71, 4, 237, 35, 35, 2, 1, 251, 161, 4, 198, 60, 35, 2, + 1, 234, 48, 4, 198, 60, 35, 2, 1, 233, 254, 4, 198, 60, 35, 2, 1, 223, + 84, 4, 198, 60, 35, 2, 1, 196, 71, 4, 237, 36, 23, 198, 60, 35, 2, 1, + 251, 160, 35, 2, 1, 248, 212, 35, 2, 1, 231, 211, 35, 2, 1, 237, 106, 35, + 2, 1, 234, 47, 35, 2, 1, 191, 76, 35, 2, 1, 233, 253, 35, 2, 1, 199, 15, + 35, 2, 1, 223, 83, 35, 2, 1, 222, 72, 35, 2, 1, 220, 31, 35, 2, 1, 215, + 155, 35, 2, 1, 212, 178, 35, 2, 1, 192, 207, 35, 2, 1, 211, 107, 35, 2, + 1, 209, 185, 35, 2, 1, 207, 3, 35, 2, 1, 53, 202, 196, 35, 2, 1, 202, + 196, 35, 2, 1, 199, 166, 35, 2, 1, 196, 70, 35, 2, 1, 209, 211, 35, 2, 1, + 243, 95, 35, 2, 1, 208, 176, 35, 2, 1, 211, 110, 35, 2, 1, 223, 84, 4, + 237, 35, 35, 2, 1, 196, 71, 4, 237, 35, 35, 2, 1, 211, 108, 4, 198, 60, + 35, 2, 1, 196, 71, 4, 198, 60, 35, 2, 1, 211, 111, 4, 198, 60, 35, 6, + 222, 103, 113, 35, 248, 213, 113, 35, 199, 16, 113, 35, 196, 71, 4, 228, + 251, 113, 35, 196, 71, 4, 252, 47, 23, 228, 251, 113, 35, 196, 71, 4, + 237, 43, 23, 228, 251, 113, 35, 209, 212, 113, 35, 209, 186, 113, 35, + 222, 103, 113, 35, 1, 251, 14, 221, 35, 35, 2, 1, 251, 14, 221, 35, 35, + 1, 201, 73, 35, 2, 1, 201, 73, 35, 1, 237, 10, 35, 2, 1, 237, 10, 35, 1, + 221, 35, 35, 2, 1, 221, 35, 35, 1, 205, 145, 35, 2, 1, 205, 145, 94, 6, + 1, 203, 105, 94, 2, 1, 203, 105, 94, 6, 1, 233, 44, 94, 2, 1, 233, 44, + 94, 6, 1, 221, 195, 94, 2, 1, 221, 195, 94, 6, 1, 228, 242, 94, 2, 1, + 228, 242, 94, 6, 1, 231, 206, 94, 2, 1, 231, 206, 94, 6, 1, 203, 71, 94, + 2, 1, 203, 71, 94, 6, 1, 237, 122, 94, 2, 1, 237, 122, 35, 222, 73, 113, + 35, 207, 4, 113, 35, 218, 206, 202, 197, 113, 35, 1, 191, 240, 35, 6, + 199, 16, 113, 35, 218, 206, 234, 48, 113, 35, 207, 18, 218, 206, 234, 48, + 113, 35, 6, 1, 203, 56, 35, 2, 1, 203, 56, 35, 6, 218, 206, 202, 197, + 113, 35, 6, 1, 205, 142, 35, 2, 1, 205, 142, 35, 207, 4, 4, 201, 28, 113, + 35, 6, 207, 18, 218, 206, 202, 197, 113, 35, 6, 235, 138, 218, 206, 202, + 197, 113, 35, 6, 207, 18, 235, 138, 218, 206, 202, 197, 113, 38, 6, 1, + 223, 227, 4, 230, 210, 38, 6, 1, 223, 88, 38, 6, 1, 236, 192, 38, 6, 1, + 231, 20, 38, 6, 1, 196, 125, 223, 226, 38, 6, 1, 235, 32, 38, 6, 1, 247, + 203, 68, 38, 6, 1, 192, 33, 38, 6, 1, 223, 10, 38, 6, 1, 219, 76, 38, 6, + 1, 213, 150, 38, 6, 1, 197, 155, 38, 6, 1, 221, 103, 38, 6, 1, 228, 74, + 4, 230, 210, 38, 6, 1, 203, 40, 66, 38, 6, 1, 235, 28, 38, 6, 1, 65, 38, + 6, 1, 249, 17, 38, 6, 1, 195, 153, 38, 6, 1, 231, 77, 38, 6, 1, 237, 146, + 38, 6, 1, 223, 226, 38, 6, 1, 191, 62, 38, 6, 1, 191, 87, 38, 6, 1, 68, + 38, 6, 1, 203, 40, 68, 38, 6, 1, 155, 38, 6, 1, 234, 140, 38, 6, 1, 234, + 114, 38, 6, 1, 234, 103, 38, 6, 1, 74, 38, 6, 1, 210, 63, 38, 6, 1, 234, + 34, 38, 6, 1, 234, 22, 38, 6, 1, 199, 145, 38, 6, 1, 66, 38, 6, 1, 234, + 181, 38, 6, 1, 140, 38, 6, 1, 197, 161, 38, 6, 1, 243, 127, 38, 6, 1, + 203, 165, 38, 6, 1, 203, 116, 38, 6, 1, 230, 17, 56, 38, 6, 1, 192, 58, + 38, 6, 1, 202, 32, 56, 38, 6, 1, 71, 38, 6, 1, 191, 225, 38, 6, 1, 170, + 38, 2, 1, 65, 38, 2, 1, 249, 17, 38, 2, 1, 195, 153, 38, 2, 1, 231, 77, + 38, 2, 1, 237, 146, 38, 2, 1, 223, 226, 38, 2, 1, 191, 62, 38, 2, 1, 191, + 87, 38, 2, 1, 68, 38, 2, 1, 203, 40, 68, 38, 2, 1, 155, 38, 2, 1, 234, + 140, 38, 2, 1, 234, 114, 38, 2, 1, 234, 103, 38, 2, 1, 74, 38, 2, 1, 210, + 63, 38, 2, 1, 234, 34, 38, 2, 1, 234, 22, 38, 2, 1, 199, 145, 38, 2, 1, + 66, 38, 2, 1, 234, 181, 38, 2, 1, 140, 38, 2, 1, 197, 161, 38, 2, 1, 243, + 127, 38, 2, 1, 203, 165, 38, 2, 1, 203, 116, 38, 2, 1, 230, 17, 56, 38, + 2, 1, 192, 58, 38, 2, 1, 202, 32, 56, 38, 2, 1, 71, 38, 2, 1, 191, 225, + 38, 2, 1, 170, 38, 2, 1, 223, 227, 4, 230, 210, 38, 2, 1, 223, 88, 38, 2, + 1, 236, 192, 38, 2, 1, 231, 20, 38, 2, 1, 196, 125, 223, 226, 38, 2, 1, + 235, 32, 38, 2, 1, 247, 203, 68, 38, 2, 1, 192, 33, 38, 2, 1, 223, 10, + 38, 2, 1, 219, 76, 38, 2, 1, 213, 150, 38, 2, 1, 197, 155, 38, 2, 1, 221, + 103, 38, 2, 1, 228, 74, 4, 230, 210, 38, 2, 1, 203, 40, 66, 38, 2, 1, + 235, 28, 38, 6, 1, 211, 110, 38, 2, 1, 211, 110, 38, 6, 1, 192, 95, 38, + 2, 1, 192, 95, 38, 6, 1, 223, 81, 71, 38, 2, 1, 223, 81, 71, 38, 6, 1, + 219, 83, 191, 190, 38, 2, 1, 219, 83, 191, 190, 38, 6, 1, 223, 81, 219, + 83, 191, 190, 38, 2, 1, 223, 81, 219, 83, 191, 190, 38, 6, 1, 248, 175, + 191, 190, 38, 2, 1, 248, 175, 191, 190, 38, 6, 1, 223, 81, 248, 175, 191, + 190, 38, 2, 1, 223, 81, 248, 175, 191, 190, 38, 6, 1, 220, 248, 38, 2, 1, + 220, 248, 38, 6, 1, 208, 176, 38, 2, 1, 208, 176, 38, 6, 1, 232, 228, 38, + 2, 1, 232, 228, 38, 6, 1, 223, 37, 38, 2, 1, 223, 37, 38, 6, 1, 223, 38, + 4, 55, 230, 211, 252, 60, 38, 2, 1, 223, 38, 4, 55, 230, 211, 252, 60, + 38, 6, 1, 196, 128, 38, 2, 1, 196, 128, 38, 6, 1, 206, 115, 211, 110, 38, + 2, 1, 206, 115, 211, 110, 38, 6, 1, 211, 111, 4, 198, 122, 38, 2, 1, 211, + 111, 4, 198, 122, 38, 6, 1, 211, 30, 38, 2, 1, 211, 30, 38, 6, 1, 221, + 35, 38, 2, 1, 221, 35, 38, 198, 229, 56, 33, 38, 198, 122, 33, 38, 210, + 191, 33, 38, 237, 213, 209, 75, 33, 38, 208, 170, 209, 75, 33, 38, 209, + 54, 33, 38, 228, 141, 198, 229, 56, 33, 38, 216, 48, 56, 38, 6, 1, 203, + 40, 228, 74, 4, 199, 215, 38, 2, 1, 203, 40, 228, 74, 4, 199, 215, 38, 6, + 1, 204, 21, 56, 38, 2, 1, 204, 21, 56, 38, 6, 1, 234, 35, 4, 198, 182, + 38, 2, 1, 234, 35, 4, 198, 182, 38, 6, 1, 231, 78, 4, 196, 69, 38, 2, 1, + 231, 78, 4, 196, 69, 38, 6, 1, 231, 78, 4, 106, 38, 2, 1, 231, 78, 4, + 106, 38, 6, 1, 231, 78, 4, 82, 102, 38, 2, 1, 231, 78, 4, 82, 102, 38, 6, + 1, 191, 63, 4, 237, 87, 38, 2, 1, 191, 63, 4, 237, 87, 38, 6, 1, 191, 88, + 4, 237, 87, 38, 2, 1, 191, 88, 4, 237, 87, 38, 6, 1, 222, 142, 4, 237, + 87, 38, 2, 1, 222, 142, 4, 237, 87, 38, 6, 1, 222, 142, 4, 81, 106, 38, + 2, 1, 222, 142, 4, 81, 106, 38, 6, 1, 222, 142, 4, 106, 38, 2, 1, 222, + 142, 4, 106, 38, 6, 1, 249, 70, 155, 38, 2, 1, 249, 70, 155, 38, 6, 1, + 234, 104, 4, 237, 87, 38, 2, 1, 234, 104, 4, 237, 87, 38, 6, 34, 234, + 104, 231, 77, 38, 2, 34, 234, 104, 231, 77, 38, 6, 1, 210, 64, 4, 82, + 102, 38, 2, 1, 210, 64, 4, 82, 102, 38, 6, 1, 252, 67, 140, 38, 2, 1, + 252, 67, 140, 38, 6, 1, 234, 23, 4, 237, 87, 38, 2, 1, 234, 23, 4, 237, + 87, 38, 6, 1, 199, 146, 4, 237, 87, 38, 2, 1, 199, 146, 4, 237, 87, 38, + 6, 1, 201, 53, 66, 38, 2, 1, 201, 53, 66, 38, 6, 1, 201, 53, 126, 4, 106, + 38, 2, 1, 201, 53, 126, 4, 106, 38, 6, 1, 230, 105, 4, 237, 87, 38, 2, 1, + 230, 105, 4, 237, 87, 38, 6, 34, 199, 146, 197, 161, 38, 2, 34, 199, 146, + 197, 161, 38, 6, 1, 243, 128, 4, 237, 87, 38, 2, 1, 243, 128, 4, 237, 87, + 38, 6, 1, 243, 128, 4, 81, 106, 38, 2, 1, 243, 128, 4, 81, 106, 38, 6, 1, + 203, 82, 38, 2, 1, 203, 82, 38, 6, 1, 252, 67, 243, 127, 38, 2, 1, 252, + 67, 243, 127, 38, 6, 1, 252, 67, 243, 128, 4, 237, 87, 38, 2, 1, 252, 67, + 243, 128, 4, 237, 87, 38, 1, 210, 179, 38, 6, 1, 191, 63, 4, 248, 36, 38, + 2, 1, 191, 63, 4, 248, 36, 38, 6, 1, 222, 142, 4, 102, 38, 2, 1, 222, + 142, 4, 102, 38, 6, 1, 234, 141, 4, 199, 215, 38, 2, 1, 234, 141, 4, 199, + 215, 38, 6, 1, 234, 104, 4, 102, 38, 2, 1, 234, 104, 4, 102, 38, 6, 1, + 234, 104, 4, 199, 215, 38, 2, 1, 234, 104, 4, 199, 215, 38, 6, 1, 221, + 208, 243, 127, 38, 2, 1, 221, 208, 243, 127, 38, 6, 1, 234, 115, 4, 199, + 215, 38, 2, 1, 234, 115, 4, 199, 215, 38, 2, 1, 210, 179, 38, 6, 1, 42, + 4, 248, 36, 38, 2, 1, 42, 4, 248, 36, 38, 6, 1, 42, 4, 237, 42, 38, 2, 1, + 42, 4, 237, 42, 38, 6, 34, 42, 223, 226, 38, 2, 34, 42, 223, 226, 38, 6, + 1, 223, 227, 4, 248, 36, 38, 2, 1, 223, 227, 4, 248, 36, 38, 6, 1, 205, + 86, 38, 2, 1, 205, 86, 38, 6, 1, 205, 87, 4, 237, 42, 38, 2, 1, 205, 87, + 4, 237, 42, 38, 6, 1, 191, 63, 4, 237, 42, 38, 2, 1, 191, 63, 4, 237, 42, + 38, 6, 1, 191, 88, 4, 237, 42, 38, 2, 1, 191, 88, 4, 237, 42, 38, 6, 1, + 252, 67, 235, 32, 38, 2, 1, 252, 67, 235, 32, 38, 6, 1, 228, 74, 4, 217, + 146, 38, 2, 1, 228, 74, 4, 217, 146, 38, 6, 1, 228, 74, 4, 237, 42, 38, + 2, 1, 228, 74, 4, 237, 42, 38, 6, 1, 187, 4, 237, 42, 38, 2, 1, 187, 4, + 237, 42, 38, 6, 1, 249, 82, 74, 38, 2, 1, 249, 82, 74, 38, 6, 1, 249, 82, + 187, 4, 237, 42, 38, 2, 1, 249, 82, 187, 4, 237, 42, 38, 6, 1, 235, 15, + 4, 237, 42, 38, 2, 1, 235, 15, 4, 237, 42, 38, 6, 1, 126, 4, 217, 146, + 38, 2, 1, 126, 4, 217, 146, 38, 6, 1, 126, 4, 237, 42, 38, 2, 1, 126, 4, + 237, 42, 38, 6, 1, 126, 4, 55, 252, 46, 38, 2, 1, 126, 4, 55, 252, 46, + 38, 6, 1, 243, 128, 4, 237, 42, 38, 2, 1, 243, 128, 4, 237, 42, 38, 6, 1, + 231, 78, 4, 237, 87, 38, 2, 1, 231, 78, 4, 237, 87, 38, 6, 1, 192, 59, 4, + 237, 42, 38, 2, 1, 192, 59, 4, 237, 42, 38, 6, 1, 231, 78, 4, 201, 28, + 23, 102, 38, 2, 1, 231, 78, 4, 201, 28, 23, 102, 38, 6, 1, 230, 105, 4, + 102, 38, 2, 1, 230, 105, 4, 102, 38, 6, 1, 230, 105, 4, 106, 38, 2, 1, + 230, 105, 4, 106, 38, 6, 1, 221, 45, 237, 146, 38, 2, 1, 221, 45, 237, + 146, 38, 6, 1, 221, 45, 236, 192, 38, 2, 1, 221, 45, 236, 192, 38, 6, 1, + 221, 45, 191, 12, 38, 2, 1, 221, 45, 191, 12, 38, 6, 1, 221, 45, 235, 24, + 38, 2, 1, 221, 45, 235, 24, 38, 6, 1, 221, 45, 219, 76, 38, 2, 1, 221, + 45, 219, 76, 38, 6, 1, 221, 45, 213, 150, 38, 2, 1, 221, 45, 213, 150, + 38, 6, 1, 221, 45, 202, 115, 38, 2, 1, 221, 45, 202, 115, 38, 6, 1, 221, + 45, 198, 116, 38, 2, 1, 221, 45, 198, 116, 38, 6, 1, 207, 18, 191, 87, + 38, 2, 1, 207, 18, 191, 87, 38, 6, 1, 234, 141, 4, 102, 38, 2, 1, 234, + 141, 4, 102, 38, 6, 1, 219, 159, 38, 2, 1, 219, 159, 38, 6, 1, 207, 6, + 38, 2, 1, 207, 6, 38, 6, 1, 192, 129, 38, 2, 1, 192, 129, 38, 6, 1, 208, + 96, 38, 2, 1, 208, 96, 38, 6, 1, 193, 125, 38, 2, 1, 193, 125, 38, 6, 1, + 251, 188, 155, 38, 2, 1, 251, 188, 155, 38, 6, 1, 234, 141, 4, 82, 102, + 38, 2, 1, 234, 141, 4, 82, 102, 38, 6, 1, 234, 104, 4, 82, 102, 38, 2, 1, + 234, 104, 4, 82, 102, 38, 6, 1, 210, 64, 4, 237, 87, 38, 2, 1, 210, 64, + 4, 237, 87, 38, 6, 1, 203, 83, 4, 237, 87, 38, 2, 1, 203, 83, 4, 237, 87, + 38, 6, 1, 234, 104, 4, 45, 102, 38, 2, 1, 234, 104, 4, 45, 102, 38, 6, 1, + 235, 16, 38, 2, 1, 235, 16, 38, 6, 1, 237, 195, 38, 2, 1, 237, 195, 38, + 6, 1, 234, 141, 4, 237, 87, 38, 2, 1, 234, 141, 4, 237, 87, 250, 249, 6, + 1, 250, 128, 250, 249, 6, 1, 248, 229, 250, 249, 6, 1, 231, 40, 250, 249, + 6, 1, 238, 32, 250, 249, 6, 1, 234, 195, 250, 249, 6, 1, 191, 123, 250, + 249, 6, 1, 234, 173, 250, 249, 6, 1, 233, 255, 250, 249, 6, 1, 159, 250, + 249, 6, 1, 191, 62, 250, 249, 6, 1, 223, 131, 250, 249, 6, 1, 219, 80, + 250, 249, 6, 1, 192, 212, 250, 249, 6, 1, 247, 160, 250, 249, 6, 1, 221, + 251, 250, 249, 6, 1, 229, 23, 250, 249, 6, 1, 223, 32, 250, 249, 6, 1, + 231, 88, 250, 249, 6, 1, 243, 117, 250, 249, 6, 1, 216, 186, 250, 249, 6, + 1, 192, 33, 250, 249, 6, 1, 212, 253, 250, 249, 6, 1, 203, 165, 250, 249, + 6, 1, 195, 24, 250, 249, 6, 1, 247, 1, 250, 249, 6, 1, 210, 41, 250, 249, + 6, 1, 222, 247, 250, 249, 6, 1, 165, 250, 249, 6, 1, 205, 39, 250, 249, + 6, 1, 195, 74, 250, 249, 6, 1, 198, 119, 250, 249, 6, 1, 207, 71, 250, + 249, 6, 1, 242, 99, 250, 249, 6, 1, 192, 17, 250, 249, 6, 1, 209, 114, + 250, 249, 6, 1, 222, 6, 250, 249, 6, 1, 211, 136, 250, 249, 6, 1, 233, + 46, 250, 249, 52, 1, 45, 132, 206, 188, 250, 249, 251, 49, 250, 249, 234, + 107, 77, 250, 249, 233, 216, 77, 250, 249, 242, 74, 250, 249, 208, 13, + 77, 250, 249, 252, 68, 77, 250, 249, 2, 1, 153, 250, 128, 250, 249, 2, 1, + 250, 128, 250, 249, 2, 1, 248, 229, 250, 249, 2, 1, 231, 40, 250, 249, 2, + 1, 238, 32, 250, 249, 2, 1, 234, 195, 250, 249, 2, 1, 191, 123, 250, 249, + 2, 1, 234, 173, 250, 249, 2, 1, 233, 255, 250, 249, 2, 1, 159, 250, 249, + 2, 1, 191, 62, 250, 249, 2, 1, 223, 131, 250, 249, 2, 1, 219, 80, 250, + 249, 2, 1, 192, 212, 250, 249, 2, 1, 247, 160, 250, 249, 2, 1, 221, 251, + 250, 249, 2, 1, 229, 23, 250, 249, 2, 1, 223, 32, 250, 249, 2, 1, 231, + 88, 250, 249, 2, 1, 243, 117, 250, 249, 2, 1, 216, 186, 250, 249, 2, 1, + 192, 33, 250, 249, 2, 1, 212, 253, 250, 249, 2, 1, 203, 165, 250, 249, 2, + 1, 195, 24, 250, 249, 2, 1, 247, 1, 250, 249, 2, 1, 210, 41, 250, 249, 2, + 1, 222, 247, 250, 249, 2, 1, 165, 250, 249, 2, 1, 205, 39, 250, 249, 2, + 1, 195, 74, 250, 249, 2, 1, 198, 119, 250, 249, 2, 1, 207, 71, 250, 249, + 2, 1, 242, 99, 250, 249, 2, 1, 192, 17, 250, 249, 2, 1, 209, 114, 250, + 249, 2, 1, 222, 6, 250, 249, 2, 1, 211, 136, 250, 249, 2, 1, 233, 46, + 250, 249, 2, 34, 234, 196, 192, 17, 250, 249, 2, 1, 11, 4, 106, 250, 249, + 232, 80, 201, 63, 250, 249, 228, 88, 206, 207, 250, 249, 233, 251, 56, + 219, 223, 250, 249, 233, 251, 56, 250, 249, 235, 110, 56, 136, 252, 61, + 233, 246, 136, 252, 61, 205, 40, 136, 252, 61, 203, 141, 136, 252, 61, + 191, 99, 208, 78, 136, 252, 61, 191, 99, 231, 230, 136, 252, 61, 198, + 134, 136, 252, 61, 207, 15, 136, 252, 61, 191, 97, 136, 252, 61, 210, 97, + 136, 252, 61, 192, 48, 136, 252, 61, 199, 56, 136, 252, 61, 231, 139, + 136, 252, 61, 231, 140, 215, 110, 136, 252, 61, 231, 137, 136, 252, 61, + 208, 80, 210, 130, 136, 252, 61, 199, 103, 231, 158, 136, 252, 61, 210, + 69, 136, 252, 61, 250, 173, 230, 85, 136, 252, 61, 215, 121, 136, 252, + 61, 217, 117, 136, 252, 61, 216, 175, 136, 252, 61, 216, 176, 222, 7, + 136, 252, 61, 237, 222, 136, 252, 61, 208, 91, 136, 252, 61, 199, 103, + 208, 73, 136, 252, 61, 192, 61, 248, 230, 191, 247, 136, 252, 61, 211, + 117, 136, 252, 61, 223, 183, 136, 252, 61, 237, 123, 136, 252, 61, 191, + 19, 136, 87, 217, 34, 243, 10, 136, 209, 62, 203, 85, 136, 209, 62, 230, + 8, 205, 40, 136, 209, 62, 230, 8, 210, 88, 136, 209, 62, 230, 8, 208, 84, + 136, 209, 62, 229, 119, 136, 209, 62, 197, 158, 136, 209, 62, 205, 40, + 136, 209, 62, 210, 88, 136, 209, 62, 208, 84, 136, 209, 62, 229, 7, 136, + 209, 62, 229, 8, 230, 10, 40, 195, 158, 136, 209, 62, 208, 18, 136, 209, + 62, 238, 17, 211, 57, 217, 70, 136, 209, 62, 216, 164, 136, 208, 152, + 217, 67, 136, 209, 62, 207, 161, 136, 208, 152, 210, 99, 136, 209, 62, + 203, 70, 236, 140, 136, 209, 62, 202, 175, 236, 140, 136, 208, 152, 202, + 33, 210, 90, 136, 87, 116, 236, 140, 136, 87, 110, 236, 140, 136, 208, + 152, 212, 131, 230, 84, 136, 209, 62, 208, 85, 208, 78, 136, 1, 251, 192, + 136, 1, 248, 214, 136, 1, 231, 38, 136, 1, 237, 253, 136, 1, 229, 245, + 136, 1, 195, 158, 136, 1, 191, 91, 136, 1, 229, 186, 136, 1, 199, 73, + 136, 1, 191, 250, 136, 1, 53, 222, 106, 136, 1, 222, 106, 136, 1, 220, + 27, 136, 1, 53, 216, 193, 136, 1, 216, 193, 136, 1, 53, 212, 130, 136, 1, + 212, 130, 136, 1, 205, 148, 136, 1, 250, 126, 136, 1, 53, 210, 63, 136, + 1, 210, 63, 136, 1, 53, 197, 163, 136, 1, 197, 163, 136, 1, 208, 42, 136, + 1, 207, 38, 136, 1, 203, 69, 136, 1, 199, 162, 136, 191, 251, 197, 241, + 136, 34, 192, 31, 55, 195, 158, 136, 34, 192, 31, 195, 159, 191, 250, + 136, 34, 192, 31, 55, 191, 250, 136, 208, 152, 231, 139, 136, 208, 152, + 231, 137, 9, 31, 56, 9, 3, 205, 141, 9, 232, 157, 217, 51, 9, 3, 205, + 187, 9, 3, 205, 144, 9, 31, 87, 58, 251, 28, 238, 191, 206, 128, 251, 28, + 232, 121, 206, 128, 9, 207, 122, 251, 28, 210, 14, 216, 50, 56, 251, 28, + 210, 14, 199, 96, 198, 230, 56, 252, 2, 56, 9, 242, 74, 9, 237, 209, 204, + 10, 9, 209, 64, 195, 137, 56, 9, 3, 216, 25, 9, 3, 205, 161, 251, 199, + 193, 149, 9, 3, 251, 199, 250, 198, 9, 3, 207, 157, 251, 198, 9, 3, 207, + 167, 251, 170, 251, 105, 9, 3, 199, 206, 9, 2, 137, 199, 219, 9, 2, 137, + 34, 131, 4, 220, 36, 4, 192, 75, 9, 2, 137, 191, 113, 9, 2, 233, 70, 9, + 2, 237, 245, 9, 2, 222, 52, 9, 204, 25, 9, 1, 77, 9, 234, 95, 79, 199, + 54, 77, 9, 197, 225, 75, 208, 152, 77, 9, 208, 13, 77, 9, 1, 222, 56, + 192, 75, 9, 1, 230, 57, 9, 1, 131, 4, 217, 142, 58, 9, 1, 131, 4, 230, + 58, 58, 9, 1, 193, 134, 4, 230, 58, 58, 9, 1, 131, 4, 230, 58, 60, 9, 1, + 99, 4, 230, 58, 58, 9, 1, 251, 192, 9, 1, 248, 245, 9, 1, 199, 115, 217, + 62, 9, 1, 199, 114, 9, 1, 199, 29, 9, 1, 223, 6, 9, 1, 230, 81, 9, 1, + 221, 210, 9, 1, 238, 3, 9, 1, 199, 41, 9, 1, 207, 71, 9, 1, 191, 113, 9, + 1, 205, 46, 9, 1, 203, 109, 9, 1, 205, 192, 9, 1, 238, 26, 9, 1, 199, + 219, 9, 1, 191, 116, 9, 1, 251, 230, 9, 1, 231, 86, 9, 1, 222, 5, 4, 105, + 185, 58, 9, 1, 222, 5, 4, 115, 185, 60, 9, 1, 233, 74, 99, 4, 223, 93, + 196, 12, 9, 1, 233, 74, 99, 4, 105, 185, 58, 9, 1, 233, 74, 99, 4, 115, + 185, 58, 9, 199, 168, 9, 1, 233, 46, 9, 1, 208, 89, 9, 1, 222, 106, 9, 1, + 220, 35, 9, 1, 216, 208, 9, 1, 213, 24, 9, 1, 229, 210, 9, 1, 193, 133, + 9, 1, 131, 217, 99, 9, 1, 192, 75, 9, 233, 68, 9, 237, 243, 9, 222, 50, + 9, 233, 70, 9, 237, 245, 9, 222, 52, 9, 203, 155, 9, 200, 206, 9, 217, + 140, 58, 9, 230, 58, 58, 9, 230, 58, 60, 9, 200, 230, 251, 192, 9, 223, + 93, 237, 245, 9, 87, 213, 25, 231, 57, 9, 190, 237, 9, 18, 3, 2, 196, 13, + 58, 9, 18, 3, 223, 93, 2, 196, 13, 58, 9, 18, 3, 75, 60, 9, 207, 18, 237, + 245, 9, 233, 71, 4, 105, 236, 138, 9, 193, 135, 230, 58, 60, 251, 28, 17, + 191, 77, 251, 28, 17, 107, 251, 28, 17, 109, 251, 28, 17, 138, 251, 28, + 17, 134, 251, 28, 17, 149, 251, 28, 17, 169, 251, 28, 17, 175, 251, 28, + 17, 171, 251, 28, 17, 178, 9, 210, 13, 56, 9, 237, 138, 204, 10, 9, 198, + 229, 204, 10, 9, 232, 226, 209, 60, 201, 102, 9, 1, 236, 139, 248, 245, + 9, 1, 236, 139, 208, 89, 9, 1, 200, 182, 251, 192, 9, 1, 131, 193, 150, + 9, 1, 131, 4, 193, 135, 230, 58, 58, 9, 1, 131, 4, 193, 135, 230, 58, 60, + 9, 1, 137, 230, 57, 9, 1, 137, 230, 58, 251, 192, 9, 1, 137, 230, 58, + 193, 133, 9, 1, 126, 4, 230, 58, 58, 9, 1, 137, 230, 58, 192, 75, 9, 1, + 197, 124, 9, 1, 197, 122, 9, 1, 248, 255, 9, 1, 199, 115, 4, 206, 188, 9, + 1, 199, 115, 4, 115, 185, 93, 235, 118, 9, 1, 210, 41, 9, 1, 199, 112, 9, + 1, 248, 243, 9, 1, 182, 4, 230, 58, 58, 9, 1, 182, 4, 105, 185, 81, 58, + 9, 1, 212, 87, 9, 1, 235, 41, 9, 1, 182, 4, 115, 185, 58, 9, 1, 199, 149, + 9, 1, 199, 147, 9, 1, 237, 186, 9, 1, 238, 4, 4, 206, 188, 9, 1, 238, 4, + 4, 75, 60, 9, 1, 238, 4, 4, 75, 248, 233, 23, 2, 199, 219, 9, 1, 238, 10, + 9, 1, 237, 188, 9, 1, 235, 78, 9, 1, 238, 4, 4, 115, 185, 93, 235, 118, + 9, 1, 238, 4, 4, 232, 128, 185, 58, 9, 1, 206, 101, 9, 1, 207, 72, 4, 2, + 196, 12, 9, 1, 207, 72, 4, 206, 188, 9, 1, 207, 72, 4, 75, 60, 9, 1, 207, + 72, 4, 2, 196, 13, 60, 9, 1, 207, 72, 4, 75, 248, 233, 23, 75, 58, 9, 1, + 207, 72, 4, 105, 185, 58, 9, 1, 223, 3, 9, 1, 207, 72, 4, 232, 128, 185, + 58, 9, 1, 205, 47, 4, 75, 248, 233, 23, 75, 58, 9, 1, 205, 47, 4, 115, + 185, 60, 9, 1, 205, 47, 4, 115, 185, 248, 233, 23, 115, 185, 58, 9, 1, + 205, 193, 4, 105, 185, 60, 9, 1, 205, 193, 4, 115, 185, 58, 9, 1, 199, + 220, 4, 115, 185, 58, 9, 1, 251, 231, 4, 115, 185, 58, 9, 1, 236, 139, + 233, 46, 9, 1, 233, 47, 4, 75, 215, 177, 60, 9, 1, 233, 47, 4, 75, 60, 9, + 1, 195, 146, 9, 1, 233, 47, 4, 115, 185, 60, 9, 1, 210, 39, 9, 1, 208, + 90, 4, 75, 58, 9, 1, 208, 90, 4, 115, 185, 58, 9, 1, 222, 4, 9, 1, 200, + 146, 222, 106, 9, 1, 222, 107, 4, 206, 188, 9, 1, 222, 107, 4, 75, 58, 9, + 1, 214, 70, 9, 1, 222, 107, 4, 115, 185, 60, 9, 1, 231, 227, 9, 1, 231, + 228, 4, 206, 188, 9, 1, 213, 247, 9, 1, 231, 228, 4, 105, 185, 60, 9, 1, + 230, 166, 9, 1, 231, 228, 4, 115, 185, 58, 9, 1, 220, 36, 4, 2, 196, 12, + 9, 1, 220, 36, 4, 75, 58, 9, 1, 220, 36, 4, 115, 185, 58, 9, 1, 220, 36, + 4, 115, 185, 60, 9, 1, 213, 25, 4, 75, 60, 9, 1, 213, 25, 231, 57, 9, 1, + 206, 165, 9, 1, 213, 25, 4, 206, 188, 9, 1, 213, 25, 4, 115, 185, 58, 9, + 1, 229, 211, 236, 170, 9, 1, 199, 150, 4, 75, 58, 9, 1, 229, 211, 4, 99, + 58, 9, 1, 229, 211, 231, 0, 9, 1, 229, 211, 231, 1, 4, 230, 58, 58, 9, 1, + 199, 115, 217, 63, 231, 0, 9, 1, 193, 134, 4, 206, 188, 9, 1, 221, 132, + 211, 151, 9, 1, 211, 151, 9, 1, 66, 9, 1, 191, 225, 9, 1, 221, 132, 191, + 225, 9, 1, 193, 134, 4, 105, 185, 58, 9, 1, 195, 153, 9, 1, 233, 74, 192, + 75, 9, 1, 99, 4, 199, 215, 9, 1, 99, 4, 2, 196, 12, 9, 1, 193, 134, 4, + 75, 58, 9, 1, 71, 9, 1, 99, 4, 115, 185, 60, 9, 1, 99, 249, 80, 9, 1, 99, + 249, 81, 4, 230, 58, 58, 9, 232, 80, 201, 63, 9, 1, 252, 25, 9, 2, 137, + 34, 205, 193, 4, 220, 36, 4, 131, 217, 99, 9, 2, 137, 34, 208, 90, 4, + 220, 36, 4, 131, 217, 99, 9, 2, 137, 92, 89, 20, 9, 2, 137, 220, 36, 251, + 192, 9, 2, 137, 223, 6, 9, 2, 137, 115, 236, 138, 9, 2, 137, 205, 46, 9, + 234, 95, 79, 250, 130, 9, 201, 98, 79, 206, 60, 234, 141, 229, 114, 9, 2, + 137, 206, 113, 191, 77, 9, 2, 137, 196, 73, 207, 91, 191, 77, 9, 2, 137, + 236, 139, 229, 236, 79, 221, 210, 9, 2, 137, 92, 76, 20, 9, 2, 130, 205, + 46, 9, 2, 137, 217, 141, 9, 2, 193, 133, 9, 2, 192, 75, 9, 2, 137, 192, + 75, 9, 2, 137, 213, 24, 9, 209, 108, 79, 205, 177, 9, 234, 105, 247, 22, + 130, 201, 63, 9, 234, 105, 247, 22, 137, 201, 63, 9, 206, 113, 137, 201, + 64, 4, 233, 4, 247, 21, 9, 2, 130, 216, 208, 9, 1, 238, 4, 4, 223, 93, + 196, 12, 9, 1, 207, 72, 4, 223, 93, 196, 12, 233, 205, 251, 28, 17, 191, + 77, 233, 205, 251, 28, 17, 107, 233, 205, 251, 28, 17, 109, 233, 205, + 251, 28, 17, 138, 233, 205, 251, 28, 17, 134, 233, 205, 251, 28, 17, 149, + 233, 205, 251, 28, 17, 169, 233, 205, 251, 28, 17, 175, 233, 205, 251, + 28, 17, 171, 233, 205, 251, 28, 17, 178, 9, 1, 203, 110, 4, 75, 60, 9, 1, + 238, 27, 4, 75, 60, 9, 1, 231, 87, 4, 75, 60, 9, 3, 202, 173, 251, 137, + 9, 3, 202, 173, 209, 16, 216, 186, 9, 1, 229, 211, 4, 223, 93, 196, 12, + 200, 63, 234, 95, 79, 210, 127, 200, 63, 200, 177, 232, 80, 201, 63, 200, + 63, 200, 232, 232, 80, 201, 63, 200, 63, 200, 177, 242, 83, 200, 63, 200, + 232, 242, 83, 200, 63, 228, 241, 242, 83, 200, 63, 242, 84, 202, 110, + 219, 224, 200, 63, 242, 84, 202, 110, 183, 200, 63, 200, 177, 242, 84, + 202, 110, 219, 224, 200, 63, 200, 232, 242, 84, 202, 110, 183, 200, 63, + 239, 24, 200, 63, 230, 15, 211, 176, 200, 63, 230, 15, 216, 162, 200, 63, + 230, 15, 250, 195, 200, 63, 252, 68, 77, 200, 63, 1, 251, 202, 200, 63, + 1, 200, 182, 251, 202, 200, 63, 1, 248, 211, 200, 63, 1, 231, 217, 200, + 63, 1, 231, 218, 231, 194, 200, 63, 1, 238, 0, 200, 63, 1, 236, 139, 238, + 1, 206, 181, 200, 63, 1, 229, 245, 200, 63, 1, 193, 133, 200, 63, 1, 191, + 113, 200, 63, 1, 229, 184, 200, 63, 1, 199, 69, 200, 63, 1, 199, 70, 231, + 194, 200, 63, 1, 191, 208, 200, 63, 1, 191, 209, 229, 245, 200, 63, 1, + 222, 75, 200, 63, 1, 220, 34, 200, 63, 1, 216, 46, 200, 63, 1, 212, 130, + 200, 63, 1, 204, 18, 200, 63, 1, 53, 204, 18, 200, 63, 1, 71, 200, 63, 1, + 210, 63, 200, 63, 1, 207, 18, 210, 63, 200, 63, 1, 205, 189, 200, 63, 1, + 208, 83, 200, 63, 1, 206, 181, 200, 63, 1, 203, 69, 200, 63, 1, 199, 159, + 200, 63, 1, 209, 252, 248, 194, 200, 63, 1, 209, 252, 231, 84, 200, 63, + 1, 209, 252, 237, 63, 200, 63, 208, 166, 58, 200, 63, 208, 166, 60, 200, + 63, 208, 166, 235, 137, 200, 63, 191, 0, 58, 200, 63, 191, 0, 60, 200, + 63, 191, 0, 235, 137, 200, 63, 207, 116, 58, 200, 63, 207, 116, 60, 200, + 63, 235, 138, 191, 9, 228, 240, 200, 63, 235, 138, 191, 9, 251, 108, 200, + 63, 229, 250, 58, 200, 63, 229, 250, 60, 200, 63, 229, 249, 235, 137, + 200, 63, 234, 16, 58, 200, 63, 234, 16, 60, 200, 63, 206, 24, 200, 63, + 233, 40, 236, 140, 200, 63, 207, 246, 200, 63, 206, 54, 200, 63, 105, 81, + 185, 58, 200, 63, 105, 81, 185, 60, 200, 63, 115, 185, 58, 200, 63, 115, + 185, 60, 200, 63, 211, 172, 219, 113, 58, 200, 63, 211, 172, 219, 113, + 60, 200, 63, 215, 96, 200, 63, 249, 79, 200, 63, 1, 202, 28, 191, 69, + 200, 63, 1, 202, 28, 221, 201, 200, 63, 1, 202, 28, 233, 59, 9, 1, 248, + 246, 4, 115, 185, 228, 190, 60, 9, 1, 248, 246, 4, 75, 248, 233, 23, 115, + 185, 58, 9, 1, 248, 246, 4, 115, 185, 209, 58, 196, 66, 60, 9, 1, 248, + 246, 4, 115, 185, 209, 58, 196, 66, 248, 233, 23, 105, 185, 58, 9, 1, + 248, 246, 4, 105, 185, 248, 233, 23, 75, 58, 9, 1, 248, 246, 4, 223, 93, + 2, 196, 13, 60, 9, 1, 248, 246, 4, 2, 196, 12, 9, 1, 182, 4, 105, 185, + 58, 9, 1, 182, 4, 115, 185, 209, 58, 196, 66, 60, 9, 1, 238, 4, 4, 105, + 185, 195, 85, 248, 233, 23, 2, 199, 219, 9, 1, 238, 4, 4, 223, 93, 2, + 196, 13, 60, 9, 1, 207, 72, 4, 106, 9, 1, 205, 47, 4, 232, 128, 185, 58, + 9, 1, 251, 231, 4, 105, 185, 58, 9, 1, 251, 231, 4, 115, 185, 209, 58, + 235, 119, 58, 9, 1, 251, 231, 4, 105, 185, 195, 85, 58, 9, 1, 233, 47, 4, + 105, 185, 60, 9, 1, 233, 47, 4, 115, 185, 209, 58, 196, 66, 60, 9, 1, + 222, 5, 4, 75, 58, 9, 1, 222, 5, 4, 115, 185, 58, 9, 1, 222, 5, 4, 115, + 185, 209, 58, 196, 66, 60, 9, 1, 92, 4, 75, 58, 9, 1, 92, 4, 75, 60, 9, + 1, 213, 25, 4, 105, 185, 60, 9, 1, 213, 25, 4, 2, 199, 219, 9, 1, 213, + 25, 4, 2, 196, 12, 9, 1, 220, 36, 4, 164, 9, 1, 207, 72, 4, 105, 185, + 195, 85, 58, 9, 1, 207, 72, 4, 230, 58, 58, 9, 1, 205, 47, 4, 105, 185, + 195, 85, 58, 9, 1, 182, 4, 2, 9, 1, 199, 220, 60, 9, 1, 182, 4, 2, 9, 1, + 199, 220, 23, 105, 236, 138, 9, 1, 205, 47, 4, 2, 9, 1, 199, 220, 23, + 105, 236, 138, 9, 1, 207, 72, 4, 2, 9, 1, 199, 220, 23, 105, 236, 138, 9, + 1, 182, 4, 2, 9, 1, 199, 220, 58, 9, 1, 131, 4, 233, 205, 251, 28, 17, + 105, 58, 9, 1, 131, 4, 233, 205, 251, 28, 17, 115, 58, 9, 1, 233, 74, 99, + 4, 233, 205, 251, 28, 17, 105, 58, 9, 1, 233, 74, 99, 4, 233, 205, 251, + 28, 17, 115, 58, 9, 1, 233, 74, 99, 4, 233, 205, 251, 28, 17, 232, 128, + 60, 9, 1, 193, 134, 4, 233, 205, 251, 28, 17, 105, 58, 9, 1, 193, 134, 4, + 233, 205, 251, 28, 17, 115, 58, 9, 1, 99, 249, 81, 4, 233, 205, 251, 28, + 17, 105, 58, 9, 1, 99, 249, 81, 4, 233, 205, 251, 28, 17, 115, 58, 9, 1, + 182, 4, 233, 205, 251, 28, 17, 232, 128, 60, 9, 1, 205, 47, 4, 233, 205, + 251, 28, 17, 232, 128, 58, 9, 1, 205, 47, 4, 223, 93, 196, 12, 9, 1, 222, + 107, 4, 105, 185, 58, 199, 46, 1, 230, 91, 199, 46, 1, 203, 119, 199, 46, + 1, 213, 23, 199, 46, 1, 207, 178, 199, 46, 1, 249, 151, 199, 46, 1, 219, + 156, 199, 46, 1, 222, 122, 199, 46, 1, 251, 179, 199, 46, 1, 195, 186, + 199, 46, 1, 216, 207, 199, 46, 1, 233, 107, 199, 46, 1, 237, 66, 199, 46, + 1, 199, 48, 199, 46, 1, 220, 122, 199, 46, 1, 231, 236, 199, 46, 1, 231, + 6, 199, 46, 1, 205, 45, 199, 46, 1, 237, 207, 199, 46, 1, 191, 94, 199, + 46, 1, 199, 161, 199, 46, 1, 192, 140, 199, 46, 1, 210, 77, 199, 46, 1, + 223, 15, 199, 46, 1, 243, 130, 199, 46, 1, 197, 131, 199, 46, 1, 229, + 176, 199, 46, 1, 221, 214, 199, 46, 1, 199, 47, 199, 46, 1, 191, 121, + 199, 46, 1, 203, 108, 199, 46, 1, 205, 196, 199, 46, 1, 238, 30, 199, 46, + 1, 159, 199, 46, 1, 191, 7, 199, 46, 1, 251, 227, 199, 46, 1, 231, 85, + 199, 46, 1, 208, 93, 199, 46, 1, 193, 178, 199, 46, 252, 70, 199, 46, + 252, 171, 199, 46, 228, 29, 199, 46, 234, 187, 199, 46, 196, 161, 199, + 46, 211, 86, 199, 46, 234, 198, 199, 46, 233, 195, 199, 46, 211, 171, + 199, 46, 211, 181, 199, 46, 200, 206, 199, 46, 1, 214, 250, 213, 107, 17, + 191, 77, 213, 107, 17, 107, 213, 107, 17, 109, 213, 107, 17, 138, 213, + 107, 17, 134, 213, 107, 17, 149, 213, 107, 17, 169, 213, 107, 17, 175, + 213, 107, 17, 171, 213, 107, 17, 178, 213, 107, 1, 65, 213, 107, 1, 234, + 188, 213, 107, 1, 68, 213, 107, 1, 71, 213, 107, 1, 66, 213, 107, 1, 211, + 87, 213, 107, 1, 74, 213, 107, 1, 238, 18, 213, 107, 1, 215, 61, 213, + 107, 1, 249, 153, 213, 107, 1, 168, 213, 107, 1, 190, 190, 213, 107, 1, + 223, 32, 213, 107, 1, 247, 1, 213, 107, 1, 238, 32, 213, 107, 1, 165, + 213, 107, 1, 206, 109, 213, 107, 1, 188, 213, 107, 1, 231, 182, 213, 107, + 1, 233, 109, 213, 107, 1, 155, 213, 107, 1, 173, 213, 107, 1, 215, 7, + 193, 37, 213, 107, 1, 174, 213, 107, 1, 212, 101, 213, 107, 1, 180, 213, + 107, 1, 140, 213, 107, 1, 193, 190, 213, 107, 1, 170, 213, 107, 1, 212, + 102, 193, 37, 213, 107, 1, 222, 193, 223, 32, 213, 107, 1, 222, 193, 247, + 1, 213, 107, 1, 222, 193, 165, 213, 107, 33, 203, 40, 137, 198, 79, 213, + 107, 33, 203, 40, 130, 198, 79, 213, 107, 33, 203, 40, 206, 180, 198, 79, + 213, 107, 33, 179, 237, 86, 198, 79, 213, 107, 33, 179, 137, 198, 79, + 213, 107, 33, 179, 130, 198, 79, 213, 107, 33, 179, 206, 180, 198, 79, + 213, 107, 33, 214, 213, 77, 213, 107, 33, 55, 75, 58, 213, 107, 137, 163, + 251, 49, 213, 107, 130, 163, 251, 49, 213, 107, 16, 211, 88, 237, 101, + 213, 107, 16, 231, 181, 213, 107, 242, 74, 213, 107, 233, 216, 77, 213, + 107, 220, 94, 213, 107, 237, 233, 213, 107, 236, 142, 56, 213, 107, 199, + 195, 56, 205, 151, 1, 251, 204, 205, 151, 1, 248, 148, 205, 151, 1, 231, + 216, 205, 151, 1, 238, 2, 205, 151, 1, 223, 44, 205, 151, 1, 249, 151, + 205, 151, 1, 191, 80, 205, 151, 1, 223, 53, 205, 151, 1, 198, 125, 205, + 151, 1, 191, 189, 205, 151, 1, 222, 123, 205, 151, 1, 220, 118, 205, 151, + 1, 216, 46, 205, 151, 1, 212, 130, 205, 151, 1, 202, 171, 205, 151, 1, + 223, 162, 205, 151, 1, 233, 23, 205, 151, 1, 197, 166, 205, 151, 1, 208, + 10, 205, 151, 1, 206, 181, 205, 151, 1, 203, 138, 205, 151, 1, 199, 243, + 205, 151, 87, 223, 162, 205, 151, 87, 223, 161, 205, 151, 87, 211, 165, + 205, 151, 87, 238, 16, 205, 151, 52, 1, 234, 52, 191, 189, 205, 151, 87, + 234, 52, 191, 189, 205, 151, 18, 3, 179, 71, 205, 151, 18, 3, 71, 205, + 151, 18, 3, 210, 253, 252, 206, 205, 151, 18, 3, 179, 252, 206, 205, 151, + 18, 3, 252, 206, 205, 151, 18, 3, 210, 253, 65, 205, 151, 18, 3, 179, 65, + 205, 151, 18, 3, 65, 205, 151, 52, 1, 203, 40, 65, 205, 151, 18, 3, 203, + 40, 65, 205, 151, 18, 3, 179, 66, 205, 151, 18, 3, 66, 205, 151, 52, 1, + 68, 205, 151, 18, 3, 179, 68, 205, 151, 18, 3, 68, 205, 151, 18, 3, 74, + 205, 151, 18, 3, 200, 206, 205, 151, 87, 214, 93, 205, 151, 208, 152, + 214, 93, 205, 151, 208, 152, 251, 255, 205, 151, 208, 152, 251, 121, 205, + 151, 208, 152, 249, 57, 205, 151, 208, 152, 250, 174, 205, 151, 208, 152, + 203, 57, 205, 151, 252, 68, 77, 205, 151, 208, 152, 216, 197, 208, 48, + 205, 151, 208, 152, 191, 16, 205, 151, 208, 152, 208, 48, 205, 151, 208, + 152, 191, 119, 205, 151, 208, 152, 197, 54, 205, 151, 208, 152, 250, 255, + 205, 151, 208, 152, 202, 33, 217, 37, 205, 151, 208, 152, 251, 97, 217, + 86, 1, 230, 65, 217, 86, 1, 252, 155, 217, 86, 1, 251, 253, 217, 86, 1, + 252, 42, 217, 86, 1, 251, 245, 217, 86, 1, 196, 36, 217, 86, 1, 250, 123, + 217, 86, 1, 223, 53, 217, 86, 1, 250, 171, 217, 86, 1, 251, 211, 217, 86, + 1, 251, 216, 217, 86, 1, 251, 207, 217, 86, 1, 251, 149, 217, 86, 1, 251, + 132, 217, 86, 1, 250, 219, 217, 86, 1, 223, 162, 217, 86, 1, 251, 65, + 217, 86, 1, 250, 184, 217, 86, 1, 251, 37, 217, 86, 1, 251, 33, 217, 86, + 1, 250, 209, 217, 86, 1, 250, 182, 217, 86, 1, 235, 62, 217, 86, 1, 222, + 114, 217, 86, 1, 251, 230, 217, 86, 252, 3, 77, 217, 86, 195, 22, 77, + 217, 86, 231, 153, 77, 217, 86, 208, 151, 200, 63, 1, 142, 214, 68, 200, + 63, 1, 142, 223, 32, 200, 63, 1, 142, 212, 101, 200, 63, 1, 142, 197, + 132, 200, 63, 1, 142, 213, 79, 200, 63, 1, 142, 213, 61, 200, 63, 1, 142, + 248, 203, 200, 63, 1, 142, 165, 200, 63, 1, 142, 219, 73, 200, 63, 1, + 142, 219, 62, 200, 63, 1, 142, 201, 175, 9, 1, 131, 4, 250, 170, 233, 70, + 9, 1, 131, 4, 250, 170, 198, 54, 50, 233, 70, 9, 1, 131, 4, 50, 82, 106, + 9, 1, 131, 4, 45, 82, 106, 9, 1, 131, 4, 250, 170, 222, 52, 9, 1, 131, 4, + 250, 170, 248, 77, 50, 222, 52, 9, 1, 131, 4, 250, 170, 206, 115, 75, 58, + 9, 1, 131, 4, 250, 170, 50, 206, 115, 236, 140, 9, 1, 131, 4, 250, 170, + 45, 206, 115, 236, 140, 9, 1, 131, 4, 250, 170, 206, 115, 75, 60, 9, 1, + 131, 4, 75, 58, 9, 1, 131, 4, 250, 170, 198, 54, 50, 233, 71, 23, 75, 58, + 9, 1, 131, 4, 50, 82, 201, 28, 23, 75, 58, 9, 1, 131, 4, 250, 170, 248, + 77, 50, 222, 53, 23, 75, 58, 9, 1, 131, 4, 250, 170, 198, 54, 50, 233, + 71, 23, 45, 206, 188, 9, 1, 131, 4, 50, 82, 201, 28, 23, 45, 206, 188, 9, + 1, 131, 4, 250, 170, 248, 77, 50, 222, 53, 23, 45, 206, 188, 9, 1, 131, + 4, 250, 170, 50, 230, 57, 9, 1, 131, 4, 250, 170, 45, 230, 57, 9, 199, + 169, 4, 210, 251, 230, 57, 9, 199, 169, 4, 210, 251, 193, 133, 9, 199, + 169, 4, 105, 185, 60, 9, 1, 199, 4, 192, 75, 9, 249, 72, 206, 115, 236, + 140, 9, 207, 147, 206, 115, 236, 140, 9, 1, 213, 25, 4, 223, 93, 2, 196, + 12, 9, 1, 182, 4, 223, 93, 2, 196, 13, 60, 9, 1, 199, 220, 4, 75, 60, 9, + 1, 199, 220, 4, 115, 185, 60, 9, 1, 222, 5, 4, 105, 185, 195, 85, 60, 9, + 81, 199, 215, 9, 209, 8, 87, 58, 9, 209, 182, 87, 58, 9, 2, 137, 193, 23, + 251, 206, 9, 2, 130, 193, 23, 223, 61, 9, 2, 130, 193, 23, 223, 179, 9, + 2, 130, 193, 23, 199, 173, 9, 217, 142, 193, 179, 9, 200, 182, 131, 215, + 234, 9, 235, 128, 217, 141, 9, 132, 217, 142, 139, 217, 141, 9, 1, 248, + 246, 4, 2, 196, 13, 60, 9, 1, 248, 246, 4, 230, 58, 58, 9, 1, 223, 7, 4, + 105, 185, 58, 9, 1, 199, 220, 4, 105, 185, 58, 9, 1, 233, 47, 4, 75, 248, + 233, 23, 115, 185, 58, 9, 1, 208, 90, 4, 75, 60, 9, 1, 220, 36, 4, 55, + 164, 9, 1, 92, 4, 115, 185, 58, 9, 1, 99, 4, 105, 185, 248, 233, 23, 230, + 58, 58, 9, 1, 99, 4, 105, 185, 248, 233, 23, 75, 58, 9, 1, 207, 72, 4, + 219, 4, 9, 1, 193, 134, 4, 75, 193, 52, 9, 1, 206, 142, 192, 75, 9, 1, + 130, 251, 192, 9, 1, 238, 4, 4, 115, 185, 60, 9, 1, 205, 193, 4, 115, + 185, 60, 9, 1, 231, 228, 4, 223, 93, 106, 9, 1, 201, 53, 193, 133, 9, 1, + 191, 114, 4, 223, 93, 196, 13, 58, 9, 1, 251, 231, 4, 115, 185, 60, 9, 1, + 222, 107, 4, 75, 60, 9, 1, 208, 90, 4, 75, 248, 233, 23, 213, 44, 185, + 58, 9, 1, 248, 246, 4, 2, 92, 58, 9, 1, 210, 42, 4, 2, 92, 58, 9, 1, 199, + 115, 4, 2, 199, 115, 58, 9, 1, 207, 72, 4, 2, 213, 25, 58, 9, 1, 99, 4, + 105, 185, 248, 233, 23, 2, 213, 25, 58, 9, 1, 252, 0, 233, 46, 9, 1, 252, + 0, 208, 89, 9, 1, 252, 0, 213, 24, 9, 1, 210, 42, 4, 2, 196, 12, 9, 1, + 199, 115, 4, 2, 196, 12, 9, 1, 197, 125, 4, 2, 196, 12, 9, 1, 199, 150, + 4, 2, 196, 12, 9, 1, 222, 5, 4, 2, 196, 12, 9, 1, 231, 87, 4, 115, 185, + 58, 9, 1, 252, 0, 208, 90, 4, 115, 185, 58, 9, 1, 223, 7, 4, 115, 185, + 58, 9, 1, 223, 7, 4, 115, 185, 60, 9, 1, 220, 36, 4, 2, 9, 1, 199, 220, + 58, 9, 1, 230, 224, 9, 2, 233, 74, 192, 75, 9, 2, 137, 233, 74, 192, 75, + 9, 2, 137, 99, 249, 81, 4, 105, 185, 60, 9, 2, 137, 193, 23, 205, 182, 9, + 2, 137, 191, 116, 9, 220, 13, 206, 115, 75, 58, 9, 220, 13, 206, 115, 75, + 60, 9, 200, 207, 60, 9, 220, 13, 243, 11, 60, 9, 220, 13, 206, 115, 75, + 223, 118, 243, 11, 60, 9, 2, 130, 193, 133, 9, 2, 137, 193, 23, 251, 30, + 9, 2, 137, 205, 192, 9, 2, 137, 251, 230, 9, 2, 137, 208, 89, 9, 2, 137, + 213, 25, 4, 222, 52, 9, 2, 130, 213, 25, 4, 222, 52, 9, 2, 137, 193, 23, + 250, 181, 9, 2, 137, 193, 23, 250, 218, 9, 2, 137, 193, 23, 251, 131, 9, + 2, 137, 193, 23, 205, 171, 9, 2, 137, 193, 23, 208, 52, 9, 2, 137, 193, + 23, 193, 157, 9, 2, 137, 232, 157, 217, 51, 9, 2, 137, 3, 205, 187, 9, + 236, 218, 234, 95, 79, 250, 130, 9, 153, 237, 246, 60, 9, 238, 171, 233, + 70, 9, 238, 171, 237, 245, 9, 238, 171, 222, 52, 9, 238, 171, 233, 68, 9, + 238, 171, 237, 243, 9, 238, 171, 222, 50, 9, 163, 91, 75, 58, 9, 163, + 105, 185, 58, 9, 163, 219, 5, 58, 9, 163, 91, 75, 60, 9, 163, 105, 185, + 60, 9, 163, 219, 5, 60, 9, 211, 77, 233, 68, 9, 211, 77, 237, 243, 9, + 211, 77, 222, 50, 9, 2, 137, 193, 133, 9, 233, 71, 4, 206, 188, 9, 233, + 71, 4, 75, 58, 9, 222, 53, 4, 75, 60, 9, 45, 250, 236, 58, 9, 50, 250, + 236, 58, 9, 45, 250, 236, 60, 9, 50, 250, 236, 60, 9, 55, 50, 250, 236, + 58, 9, 55, 50, 250, 236, 93, 4, 236, 140, 9, 50, 250, 236, 93, 4, 236, + 140, 9, 237, 246, 4, 236, 140, 9, 87, 202, 206, 213, 25, 231, 57, 100, 3, + 223, 93, 247, 119, 100, 3, 247, 119, 100, 3, 251, 71, 100, 3, 195, 35, + 100, 1, 203, 40, 65, 100, 1, 65, 100, 1, 252, 206, 100, 1, 68, 100, 1, + 223, 199, 100, 1, 66, 100, 1, 196, 30, 100, 1, 117, 146, 100, 1, 117, + 172, 100, 1, 247, 122, 71, 100, 1, 203, 40, 71, 100, 1, 71, 100, 1, 251, + 236, 100, 1, 247, 122, 74, 100, 1, 203, 40, 74, 100, 1, 74, 100, 1, 250, + 163, 100, 1, 155, 100, 1, 221, 215, 100, 1, 231, 240, 100, 1, 231, 91, + 100, 1, 214, 68, 100, 1, 247, 160, 100, 1, 247, 1, 100, 1, 223, 32, 100, + 1, 222, 252, 100, 1, 212, 101, 100, 1, 197, 132, 100, 1, 197, 120, 100, + 1, 237, 191, 100, 1, 237, 175, 100, 1, 213, 79, 100, 1, 190, 190, 100, 1, + 199, 49, 100, 1, 238, 32, 100, 1, 237, 68, 100, 1, 180, 100, 1, 213, 61, + 100, 1, 168, 100, 1, 209, 228, 100, 1, 249, 153, 100, 1, 248, 203, 100, + 1, 174, 100, 1, 170, 100, 1, 165, 100, 1, 206, 109, 100, 1, 173, 100, 1, + 219, 73, 100, 1, 219, 62, 100, 1, 195, 188, 100, 1, 203, 165, 100, 1, + 201, 175, 100, 1, 188, 100, 1, 140, 100, 18, 3, 211, 151, 100, 18, 3, + 211, 85, 100, 3, 212, 141, 100, 3, 250, 145, 100, 18, 3, 252, 206, 100, + 18, 3, 68, 100, 18, 3, 223, 199, 100, 18, 3, 66, 100, 18, 3, 196, 30, + 100, 18, 3, 117, 146, 100, 18, 3, 117, 206, 110, 100, 18, 3, 247, 122, + 71, 100, 18, 3, 203, 40, 71, 100, 18, 3, 71, 100, 18, 3, 251, 236, 100, + 18, 3, 247, 122, 74, 100, 18, 3, 203, 40, 74, 100, 18, 3, 74, 100, 18, 3, + 250, 163, 100, 3, 195, 40, 100, 18, 3, 208, 207, 71, 100, 18, 3, 250, + 140, 100, 211, 113, 100, 201, 38, 3, 196, 154, 100, 201, 38, 3, 251, 73, + 100, 230, 211, 252, 60, 100, 252, 47, 252, 60, 100, 18, 3, 247, 122, 179, + 71, 100, 18, 3, 196, 152, 100, 18, 3, 196, 29, 100, 1, 208, 96, 100, 1, + 221, 193, 100, 1, 231, 66, 100, 1, 191, 123, 100, 1, 237, 180, 100, 1, + 207, 6, 100, 1, 233, 109, 100, 1, 191, 175, 100, 1, 117, 206, 110, 100, + 1, 117, 219, 74, 100, 18, 3, 117, 172, 100, 18, 3, 117, 219, 74, 100, + 237, 238, 100, 55, 237, 238, 100, 17, 191, 77, 100, 17, 107, 100, 17, + 109, 100, 17, 138, 100, 17, 134, 100, 17, 149, 100, 17, 169, 100, 17, + 175, 100, 17, 171, 100, 17, 178, 100, 252, 68, 56, 100, 3, 137, 201, 246, + 236, 140, 100, 1, 247, 122, 65, 100, 1, 211, 151, 100, 1, 211, 85, 100, + 1, 250, 140, 100, 1, 196, 152, 100, 1, 196, 29, 100, 1, 217, 43, 237, + 191, 100, 1, 191, 71, 100, 1, 88, 170, 100, 1, 231, 127, 100, 1, 222, + 230, 100, 1, 231, 11, 201, 63, 100, 1, 237, 181, 100, 1, 249, 53, 248, + 225, 251, 100, 248, 225, 3, 247, 119, 248, 225, 3, 251, 71, 248, 225, 3, + 195, 35, 248, 225, 1, 65, 248, 225, 1, 252, 206, 248, 225, 1, 68, 248, + 225, 1, 223, 199, 248, 225, 1, 66, 248, 225, 1, 196, 30, 248, 225, 1, + 117, 146, 248, 225, 1, 117, 172, 248, 225, 1, 71, 248, 225, 1, 251, 236, + 248, 225, 1, 74, 248, 225, 1, 250, 163, 248, 225, 1, 155, 248, 225, 1, + 221, 215, 248, 225, 1, 231, 240, 248, 225, 1, 231, 91, 248, 225, 1, 214, + 68, 248, 225, 1, 247, 160, 248, 225, 1, 247, 1, 248, 225, 1, 223, 32, + 248, 225, 1, 222, 252, 248, 225, 1, 212, 101, 248, 225, 1, 197, 132, 248, + 225, 1, 197, 120, 248, 225, 1, 237, 191, 248, 225, 1, 237, 175, 248, 225, + 1, 213, 79, 248, 225, 1, 190, 190, 248, 225, 1, 199, 49, 248, 225, 1, + 238, 32, 248, 225, 1, 237, 68, 248, 225, 1, 180, 248, 225, 1, 168, 248, + 225, 1, 209, 228, 248, 225, 1, 249, 153, 248, 225, 1, 248, 203, 248, 225, + 1, 174, 248, 225, 1, 170, 248, 225, 1, 165, 248, 225, 1, 173, 248, 225, + 1, 203, 165, 248, 225, 1, 201, 175, 248, 225, 1, 188, 248, 225, 1, 140, + 248, 225, 3, 212, 141, 248, 225, 3, 250, 145, 248, 225, 18, 3, 252, 206, + 248, 225, 18, 3, 68, 248, 225, 18, 3, 223, 199, 248, 225, 18, 3, 66, 248, + 225, 18, 3, 196, 30, 248, 225, 18, 3, 117, 146, 248, 225, 18, 3, 117, + 206, 110, 248, 225, 18, 3, 71, 248, 225, 18, 3, 251, 236, 248, 225, 18, + 3, 74, 248, 225, 18, 3, 250, 163, 248, 225, 3, 195, 40, 248, 225, 1, 221, + 204, 190, 190, 248, 225, 250, 164, 219, 198, 77, 248, 225, 1, 206, 109, + 248, 225, 1, 207, 6, 248, 225, 1, 191, 175, 248, 225, 1, 117, 206, 110, + 248, 225, 1, 117, 219, 74, 248, 225, 18, 3, 117, 172, 248, 225, 18, 3, + 117, 219, 74, 248, 225, 17, 191, 77, 248, 225, 17, 107, 248, 225, 17, + 109, 248, 225, 17, 138, 248, 225, 17, 134, 248, 225, 17, 149, 248, 225, + 17, 169, 248, 225, 17, 175, 248, 225, 17, 171, 248, 225, 17, 178, 248, + 225, 1, 207, 186, 4, 82, 237, 38, 248, 225, 1, 207, 186, 4, 110, 237, 38, + 248, 225, 206, 36, 77, 248, 225, 206, 36, 56, 248, 225, 238, 170, 212, + 133, 107, 248, 225, 238, 170, 212, 133, 109, 248, 225, 238, 170, 212, + 133, 138, 248, 225, 238, 170, 212, 133, 134, 248, 225, 238, 170, 212, + 133, 91, 219, 181, 199, 39, 199, 34, 237, 99, 248, 225, 238, 170, 237, + 100, 202, 130, 248, 225, 223, 54, 248, 225, 231, 207, 77, 248, 225, 1, + 195, 150, 251, 71, 248, 225, 252, 68, 56, 248, 225, 205, 138, 77, 230, + 144, 3, 252, 41, 248, 167, 230, 144, 3, 248, 167, 230, 144, 3, 195, 35, + 230, 144, 1, 65, 230, 144, 1, 252, 206, 230, 144, 1, 68, 230, 144, 1, + 223, 199, 230, 144, 1, 66, 230, 144, 1, 196, 30, 230, 144, 1, 234, 188, + 230, 144, 1, 251, 236, 230, 144, 1, 211, 87, 230, 144, 1, 250, 163, 230, + 144, 1, 155, 230, 144, 1, 221, 215, 230, 144, 1, 231, 240, 230, 144, 1, + 231, 91, 230, 144, 1, 214, 68, 230, 144, 1, 247, 160, 230, 144, 1, 247, + 1, 230, 144, 1, 223, 32, 230, 144, 1, 222, 252, 230, 144, 1, 212, 101, + 230, 144, 1, 197, 132, 230, 144, 1, 197, 120, 230, 144, 1, 237, 191, 230, + 144, 1, 237, 175, 230, 144, 1, 213, 79, 230, 144, 1, 190, 190, 230, 144, + 1, 199, 49, 230, 144, 1, 238, 32, 230, 144, 1, 237, 68, 230, 144, 1, 180, + 230, 144, 1, 168, 230, 144, 1, 209, 228, 230, 144, 1, 249, 153, 230, 144, + 1, 248, 203, 230, 144, 1, 174, 230, 144, 1, 170, 230, 144, 1, 165, 230, + 144, 1, 173, 230, 144, 1, 219, 73, 230, 144, 1, 195, 188, 230, 144, 1, + 203, 165, 230, 144, 1, 188, 230, 144, 1, 140, 230, 144, 3, 212, 141, 230, + 144, 18, 3, 252, 206, 230, 144, 18, 3, 68, 230, 144, 18, 3, 223, 199, + 230, 144, 18, 3, 66, 230, 144, 18, 3, 196, 30, 230, 144, 18, 3, 234, 188, + 230, 144, 18, 3, 251, 236, 230, 144, 18, 3, 211, 87, 230, 144, 18, 3, + 250, 163, 230, 144, 3, 195, 40, 230, 144, 3, 196, 157, 230, 144, 1, 221, + 193, 230, 144, 1, 231, 66, 230, 144, 1, 191, 123, 230, 144, 1, 206, 109, + 230, 144, 1, 233, 109, 230, 144, 17, 191, 77, 230, 144, 17, 107, 230, + 144, 17, 109, 230, 144, 17, 138, 230, 144, 17, 134, 230, 144, 17, 149, + 230, 144, 17, 169, 230, 144, 17, 175, 230, 144, 17, 171, 230, 144, 17, + 178, 230, 144, 198, 133, 230, 144, 252, 40, 230, 144, 223, 75, 230, 144, + 196, 58, 230, 144, 234, 148, 211, 92, 230, 144, 3, 192, 115, 230, 144, + 252, 68, 56, 230, 161, 3, 247, 119, 230, 161, 3, 251, 71, 230, 161, 3, + 195, 35, 230, 161, 1, 65, 230, 161, 1, 252, 206, 230, 161, 1, 68, 230, + 161, 1, 223, 199, 230, 161, 1, 66, 230, 161, 1, 196, 30, 230, 161, 1, + 117, 146, 230, 161, 1, 117, 172, 230, 161, 18, 247, 122, 71, 230, 161, 1, + 71, 230, 161, 1, 251, 236, 230, 161, 18, 247, 122, 74, 230, 161, 1, 74, + 230, 161, 1, 250, 163, 230, 161, 1, 155, 230, 161, 1, 221, 215, 230, 161, + 1, 231, 240, 230, 161, 1, 231, 91, 230, 161, 1, 214, 68, 230, 161, 1, + 247, 160, 230, 161, 1, 247, 1, 230, 161, 1, 223, 32, 230, 161, 1, 222, + 252, 230, 161, 1, 212, 101, 230, 161, 1, 197, 132, 230, 161, 1, 197, 120, + 230, 161, 1, 237, 191, 230, 161, 1, 237, 175, 230, 161, 1, 213, 79, 230, + 161, 1, 190, 190, 230, 161, 1, 199, 49, 230, 161, 1, 238, 32, 230, 161, + 1, 237, 68, 230, 161, 1, 180, 230, 161, 1, 168, 230, 161, 1, 209, 228, + 230, 161, 1, 249, 153, 230, 161, 1, 248, 203, 230, 161, 1, 174, 230, 161, + 1, 170, 230, 161, 1, 165, 230, 161, 1, 173, 230, 161, 1, 219, 73, 230, + 161, 1, 195, 188, 230, 161, 1, 203, 165, 230, 161, 1, 201, 175, 230, 161, + 1, 188, 230, 161, 1, 140, 230, 161, 3, 212, 141, 230, 161, 3, 250, 145, + 230, 161, 18, 3, 252, 206, 230, 161, 18, 3, 68, 230, 161, 18, 3, 223, + 199, 230, 161, 18, 3, 66, 230, 161, 18, 3, 196, 30, 230, 161, 18, 3, 117, + 146, 230, 161, 18, 3, 117, 206, 110, 230, 161, 18, 3, 247, 122, 71, 230, + 161, 18, 3, 71, 230, 161, 18, 3, 251, 236, 230, 161, 18, 3, 247, 122, 74, + 230, 161, 18, 3, 74, 230, 161, 18, 3, 250, 163, 230, 161, 3, 195, 40, + 230, 161, 211, 113, 230, 161, 1, 117, 206, 110, 230, 161, 1, 117, 219, + 74, 230, 161, 18, 3, 117, 172, 230, 161, 18, 3, 117, 219, 74, 230, 161, + 17, 191, 77, 230, 161, 17, 107, 230, 161, 17, 109, 230, 161, 17, 138, + 230, 161, 17, 134, 230, 161, 17, 149, 230, 161, 17, 169, 230, 161, 17, + 175, 230, 161, 17, 171, 230, 161, 17, 178, 230, 161, 252, 68, 56, 230, + 161, 206, 36, 56, 230, 161, 1, 191, 71, 230, 161, 3, 200, 206, 230, 161, + 3, 203, 155, 230, 161, 3, 217, 139, 230, 161, 3, 198, 224, 212, 142, 58, + 230, 161, 3, 243, 11, 212, 142, 58, 230, 161, 3, 197, 15, 212, 142, 58, + 211, 45, 3, 247, 119, 211, 45, 3, 251, 71, 211, 45, 3, 195, 35, 211, 45, + 1, 65, 211, 45, 1, 252, 206, 211, 45, 1, 68, 211, 45, 1, 223, 199, 211, + 45, 1, 66, 211, 45, 1, 196, 30, 211, 45, 1, 117, 146, 211, 45, 1, 117, + 172, 211, 45, 1, 71, 211, 45, 1, 251, 236, 211, 45, 1, 74, 211, 45, 1, + 250, 163, 211, 45, 1, 155, 211, 45, 1, 221, 215, 211, 45, 1, 231, 240, + 211, 45, 1, 231, 91, 211, 45, 1, 214, 68, 211, 45, 1, 247, 160, 211, 45, + 1, 247, 1, 211, 45, 1, 223, 32, 211, 45, 1, 222, 252, 211, 45, 1, 212, + 101, 211, 45, 1, 197, 132, 211, 45, 1, 197, 120, 211, 45, 1, 237, 191, + 211, 45, 1, 237, 175, 211, 45, 1, 213, 79, 211, 45, 1, 190, 190, 211, 45, + 1, 199, 49, 211, 45, 1, 238, 32, 211, 45, 1, 237, 68, 211, 45, 1, 180, + 211, 45, 1, 168, 211, 45, 1, 209, 228, 211, 45, 1, 249, 153, 211, 45, 1, + 248, 203, 211, 45, 1, 174, 211, 45, 1, 170, 211, 45, 1, 165, 211, 45, 1, + 173, 211, 45, 1, 219, 73, 211, 45, 1, 195, 188, 211, 45, 1, 203, 165, + 211, 45, 1, 201, 175, 211, 45, 1, 188, 211, 45, 1, 140, 211, 45, 3, 212, + 141, 211, 45, 3, 250, 145, 211, 45, 18, 3, 252, 206, 211, 45, 18, 3, 68, + 211, 45, 18, 3, 223, 199, 211, 45, 18, 3, 66, 211, 45, 18, 3, 196, 30, + 211, 45, 18, 3, 117, 146, 211, 45, 18, 3, 117, 206, 110, 211, 45, 18, 3, + 71, 211, 45, 18, 3, 251, 236, 211, 45, 18, 3, 74, 211, 45, 18, 3, 250, + 163, 211, 45, 3, 195, 40, 211, 45, 3, 210, 254, 211, 45, 251, 237, 219, + 198, 77, 211, 45, 250, 164, 219, 198, 77, 211, 45, 1, 206, 109, 211, 45, + 1, 207, 6, 211, 45, 1, 191, 175, 211, 45, 1, 117, 206, 110, 211, 45, 1, + 117, 219, 74, 211, 45, 18, 3, 117, 172, 211, 45, 18, 3, 117, 219, 74, + 211, 45, 17, 191, 77, 211, 45, 17, 107, 211, 45, 17, 109, 211, 45, 17, + 138, 211, 45, 17, 134, 211, 45, 17, 149, 211, 45, 17, 169, 211, 45, 17, + 175, 211, 45, 17, 171, 211, 45, 17, 178, 211, 45, 223, 54, 211, 45, 1, + 193, 190, 211, 45, 232, 118, 91, 208, 22, 211, 45, 232, 118, 91, 230, 70, + 211, 45, 232, 118, 115, 208, 20, 211, 45, 232, 118, 91, 202, 128, 211, + 45, 232, 118, 91, 234, 159, 211, 45, 232, 118, 115, 202, 125, 44, 3, 251, + 71, 44, 3, 195, 35, 44, 1, 65, 44, 1, 252, 206, 44, 1, 68, 44, 1, 223, + 199, 44, 1, 66, 44, 1, 196, 30, 44, 1, 71, 44, 1, 234, 188, 44, 1, 251, + 236, 44, 1, 74, 44, 1, 211, 87, 44, 1, 250, 163, 44, 1, 155, 44, 1, 214, + 68, 44, 1, 247, 160, 44, 1, 223, 32, 44, 1, 212, 101, 44, 1, 197, 132, + 44, 1, 213, 79, 44, 1, 190, 190, 44, 1, 180, 44, 1, 213, 61, 44, 1, 168, + 44, 1, 174, 44, 1, 170, 44, 1, 165, 44, 1, 206, 109, 44, 1, 173, 44, 1, + 219, 73, 44, 1, 219, 62, 44, 1, 195, 188, 44, 1, 203, 165, 44, 1, 201, + 175, 44, 1, 188, 44, 1, 140, 44, 18, 3, 252, 206, 44, 18, 3, 68, 44, 18, + 3, 223, 199, 44, 18, 3, 66, 44, 18, 3, 196, 30, 44, 18, 3, 71, 44, 18, 3, + 234, 188, 44, 18, 3, 251, 236, 44, 18, 3, 74, 44, 18, 3, 211, 87, 44, 18, + 3, 250, 163, 44, 3, 195, 40, 44, 211, 113, 44, 250, 164, 219, 198, 77, + 44, 17, 191, 77, 44, 17, 107, 44, 17, 109, 44, 17, 138, 44, 17, 134, 44, + 17, 149, 44, 17, 169, 44, 17, 175, 44, 17, 171, 44, 17, 178, 44, 31, 199, + 95, 44, 31, 91, 228, 140, 44, 31, 91, 189, 44, 237, 204, 56, 44, 215, + 214, 56, 44, 192, 78, 56, 44, 237, 142, 56, 44, 238, 230, 56, 44, 250, + 220, 93, 56, 44, 206, 36, 56, 44, 31, 56, 199, 99, 3, 33, 247, 120, 58, + 199, 99, 3, 247, 119, 199, 99, 3, 251, 71, 199, 99, 3, 195, 35, 199, 99, + 3, 33, 251, 72, 58, 199, 99, 1, 65, 199, 99, 1, 252, 206, 199, 99, 1, 68, + 199, 99, 1, 223, 199, 199, 99, 1, 66, 199, 99, 1, 196, 30, 199, 99, 1, + 117, 146, 199, 99, 1, 117, 172, 199, 99, 1, 71, 199, 99, 1, 234, 188, + 199, 99, 1, 251, 236, 199, 99, 1, 74, 199, 99, 1, 211, 87, 199, 99, 1, + 250, 163, 199, 99, 1, 155, 199, 99, 1, 221, 215, 199, 99, 1, 231, 240, + 199, 99, 1, 231, 91, 199, 99, 1, 214, 68, 199, 99, 1, 247, 160, 199, 99, + 1, 247, 1, 199, 99, 1, 223, 32, 199, 99, 1, 222, 252, 199, 99, 1, 212, + 101, 199, 99, 1, 197, 132, 199, 99, 1, 197, 120, 199, 99, 1, 237, 191, + 199, 99, 1, 237, 175, 199, 99, 1, 213, 79, 199, 99, 1, 190, 190, 199, 99, + 1, 199, 49, 199, 99, 1, 238, 32, 199, 99, 1, 237, 68, 199, 99, 1, 180, + 199, 99, 1, 168, 199, 99, 1, 209, 228, 199, 99, 1, 249, 153, 199, 99, 1, + 248, 203, 199, 99, 1, 174, 199, 99, 1, 170, 199, 99, 1, 165, 199, 99, 1, + 206, 109, 199, 99, 1, 173, 199, 99, 1, 219, 73, 199, 99, 1, 219, 62, 199, + 99, 1, 195, 188, 199, 99, 1, 203, 165, 199, 99, 1, 201, 175, 199, 99, 1, + 188, 199, 99, 1, 140, 199, 99, 3, 212, 141, 199, 99, 3, 250, 145, 199, + 99, 18, 3, 252, 206, 199, 99, 18, 3, 68, 199, 99, 18, 3, 223, 199, 199, + 99, 18, 3, 66, 199, 99, 18, 3, 196, 30, 199, 99, 18, 3, 117, 146, 199, + 99, 18, 3, 117, 206, 110, 199, 99, 18, 3, 71, 199, 99, 18, 3, 234, 188, + 199, 99, 18, 3, 251, 236, 199, 99, 18, 3, 74, 199, 99, 18, 3, 211, 87, + 199, 99, 18, 3, 250, 163, 199, 99, 3, 195, 40, 199, 99, 219, 198, 77, + 199, 99, 251, 237, 219, 198, 77, 199, 99, 1, 197, 168, 199, 99, 1, 235, + 35, 199, 99, 1, 206, 90, 199, 99, 1, 214, 232, 209, 46, 199, 99, 1, 117, + 206, 110, 199, 99, 1, 117, 219, 74, 199, 99, 18, 3, 117, 172, 199, 99, + 18, 3, 117, 219, 74, 199, 99, 17, 191, 77, 199, 99, 17, 107, 199, 99, 17, + 109, 199, 99, 17, 138, 199, 99, 17, 134, 199, 99, 17, 149, 199, 99, 17, + 169, 199, 99, 17, 175, 199, 99, 17, 171, 199, 99, 17, 178, 199, 99, 3, + 202, 210, 199, 99, 232, 118, 17, 191, 78, 40, 211, 155, 208, 253, 79, + 134, 199, 99, 232, 118, 17, 91, 40, 211, 155, 208, 253, 79, 134, 199, 99, + 232, 118, 17, 105, 40, 211, 155, 208, 253, 79, 134, 199, 99, 232, 118, + 17, 115, 40, 211, 155, 208, 253, 79, 134, 199, 99, 232, 118, 17, 91, 40, + 233, 229, 208, 253, 79, 134, 199, 99, 232, 118, 17, 105, 40, 233, 229, + 208, 253, 79, 134, 199, 99, 232, 118, 17, 115, 40, 233, 229, 208, 253, + 79, 134, 199, 99, 3, 197, 48, 222, 81, 3, 201, 246, 247, 119, 222, 81, 3, + 247, 119, 222, 81, 3, 251, 71, 222, 81, 3, 195, 35, 222, 81, 3, 202, 210, + 222, 81, 1, 65, 222, 81, 1, 252, 206, 222, 81, 1, 68, 222, 81, 1, 223, + 199, 222, 81, 1, 66, 222, 81, 1, 196, 30, 222, 81, 1, 117, 146, 222, 81, + 1, 117, 172, 222, 81, 1, 71, 222, 81, 1, 234, 188, 222, 81, 1, 251, 236, + 222, 81, 1, 74, 222, 81, 1, 211, 87, 222, 81, 1, 250, 163, 222, 81, 1, + 155, 222, 81, 1, 221, 215, 222, 81, 1, 231, 240, 222, 81, 1, 231, 91, + 222, 81, 1, 214, 68, 222, 81, 1, 247, 160, 222, 81, 1, 247, 1, 222, 81, + 1, 223, 32, 222, 81, 1, 222, 252, 222, 81, 1, 212, 101, 222, 81, 1, 197, + 132, 222, 81, 1, 197, 120, 222, 81, 1, 237, 191, 222, 81, 1, 237, 175, + 222, 81, 1, 213, 79, 222, 81, 1, 190, 190, 222, 81, 1, 199, 49, 222, 81, + 1, 238, 32, 222, 81, 1, 237, 68, 222, 81, 1, 180, 222, 81, 1, 168, 222, + 81, 1, 209, 228, 222, 81, 1, 249, 153, 222, 81, 1, 248, 203, 222, 81, 1, + 174, 222, 81, 1, 170, 222, 81, 1, 165, 222, 81, 1, 206, 109, 222, 81, 1, + 173, 222, 81, 1, 219, 73, 222, 81, 1, 195, 188, 222, 81, 1, 203, 165, + 222, 81, 1, 201, 175, 222, 81, 1, 188, 222, 81, 1, 140, 222, 81, 3, 212, + 141, 222, 81, 3, 250, 145, 222, 81, 18, 3, 252, 206, 222, 81, 18, 3, 68, + 222, 81, 18, 3, 223, 199, 222, 81, 18, 3, 66, 222, 81, 18, 3, 196, 30, + 222, 81, 18, 3, 117, 146, 222, 81, 18, 3, 117, 206, 110, 222, 81, 18, 3, + 71, 222, 81, 18, 3, 234, 188, 222, 81, 18, 3, 251, 236, 222, 81, 18, 3, + 74, 222, 81, 18, 3, 211, 87, 222, 81, 18, 3, 250, 163, 222, 81, 3, 195, + 40, 222, 81, 219, 198, 77, 222, 81, 251, 237, 219, 198, 77, 222, 81, 1, + 214, 232, 209, 46, 222, 81, 1, 233, 109, 222, 81, 1, 117, 206, 110, 222, + 81, 1, 117, 219, 74, 222, 81, 18, 3, 117, 172, 222, 81, 18, 3, 117, 219, + 74, 222, 81, 17, 191, 77, 222, 81, 17, 107, 222, 81, 17, 109, 222, 81, + 17, 138, 222, 81, 17, 134, 222, 81, 17, 149, 222, 81, 17, 169, 222, 81, + 17, 175, 222, 81, 17, 171, 222, 81, 17, 178, 222, 81, 3, 222, 237, 222, + 81, 3, 196, 75, 222, 81, 3, 33, 251, 72, 93, 183, 142, 3, 33, 251, 72, + 58, 142, 3, 247, 119, 142, 3, 251, 71, 142, 3, 195, 35, 142, 1, 195, 150, + 251, 71, 142, 1, 65, 142, 1, 252, 206, 142, 1, 68, 142, 1, 223, 199, 142, + 1, 66, 142, 1, 196, 30, 142, 1, 117, 146, 142, 1, 117, 172, 142, 1, 71, + 142, 1, 234, 188, 142, 1, 251, 236, 142, 1, 74, 142, 1, 211, 87, 142, 1, + 250, 163, 142, 1, 155, 142, 1, 221, 215, 142, 1, 231, 240, 142, 1, 231, + 91, 142, 1, 214, 68, 142, 1, 247, 160, 142, 1, 247, 1, 142, 1, 223, 32, + 142, 1, 222, 252, 142, 1, 212, 101, 142, 1, 197, 132, 142, 1, 197, 120, + 142, 1, 237, 191, 142, 1, 237, 175, 142, 1, 213, 79, 142, 1, 190, 190, + 142, 1, 199, 49, 142, 1, 238, 32, 142, 1, 237, 68, 142, 1, 180, 142, 1, + 213, 61, 142, 1, 168, 142, 1, 209, 228, 142, 1, 249, 153, 142, 1, 248, + 203, 142, 1, 174, 142, 1, 170, 142, 1, 165, 142, 1, 206, 109, 142, 1, + 173, 142, 1, 219, 73, 142, 1, 219, 62, 142, 1, 195, 188, 142, 1, 203, + 165, 142, 1, 201, 175, 142, 1, 188, 142, 1, 140, 142, 1, 197, 101, 142, + 3, 81, 249, 88, 195, 40, 142, 3, 243, 4, 195, 40, 142, 3, 250, 145, 142, + 18, 3, 252, 206, 142, 18, 3, 68, 142, 18, 3, 223, 199, 142, 18, 3, 66, + 142, 18, 3, 196, 30, 142, 18, 3, 117, 146, 142, 18, 3, 117, 206, 110, + 142, 18, 3, 71, 142, 18, 3, 234, 188, 142, 18, 3, 251, 236, 142, 18, 3, + 74, 142, 18, 3, 211, 87, 142, 18, 3, 250, 163, 142, 3, 195, 40, 142, 1, + 75, 207, 45, 142, 3, 210, 130, 142, 1, 243, 84, 218, 168, 142, 1, 243, + 84, 192, 159, 142, 1, 243, 84, 219, 63, 142, 250, 164, 219, 198, 77, 142, + 232, 118, 91, 211, 100, 142, 232, 118, 91, 232, 139, 142, 232, 118, 115, + 234, 155, 142, 232, 118, 91, 197, 35, 142, 232, 118, 91, 199, 86, 142, + 232, 118, 115, 197, 34, 142, 232, 118, 91, 233, 18, 142, 1, 251, 14, 223, + 199, 142, 1, 117, 206, 110, 142, 1, 117, 219, 74, 142, 18, 3, 117, 172, + 142, 18, 3, 117, 219, 74, 142, 17, 191, 77, 142, 17, 107, 142, 17, 109, + 142, 17, 138, 142, 17, 134, 142, 17, 149, 142, 17, 169, 142, 17, 175, + 142, 17, 171, 142, 17, 178, 142, 31, 199, 95, 142, 31, 91, 228, 140, 142, + 31, 91, 189, 142, 232, 118, 91, 208, 22, 142, 232, 118, 91, 230, 70, 142, + 232, 118, 115, 208, 20, 142, 232, 118, 91, 202, 128, 142, 232, 118, 91, + 234, 159, 142, 232, 118, 115, 202, 125, 142, 237, 209, 77, 142, 1, 243, + 84, 213, 80, 142, 1, 243, 84, 215, 61, 142, 1, 243, 84, 206, 110, 142, 1, + 243, 84, 172, 142, 1, 243, 84, 219, 74, 142, 1, 243, 84, 222, 152, 166, + 3, 247, 119, 166, 3, 251, 70, 166, 3, 195, 34, 166, 1, 250, 129, 166, 1, + 252, 159, 166, 1, 252, 5, 166, 1, 252, 20, 166, 1, 223, 43, 166, 1, 223, + 198, 166, 1, 196, 20, 166, 1, 196, 24, 166, 1, 223, 70, 166, 1, 223, 71, + 166, 1, 223, 182, 166, 1, 223, 184, 166, 1, 233, 196, 166, 1, 234, 183, + 166, 1, 251, 219, 166, 1, 210, 241, 166, 1, 211, 80, 166, 1, 250, 148, + 166, 1, 251, 163, 222, 27, 166, 1, 217, 119, 222, 27, 166, 1, 251, 163, + 231, 185, 166, 1, 217, 119, 231, 185, 166, 1, 222, 80, 214, 247, 166, 1, + 205, 132, 231, 185, 166, 1, 251, 163, 247, 68, 166, 1, 217, 119, 247, 68, + 166, 1, 251, 163, 223, 13, 166, 1, 217, 119, 223, 13, 166, 1, 199, 241, + 214, 247, 166, 1, 199, 241, 205, 131, 214, 248, 166, 1, 205, 132, 223, + 13, 166, 1, 251, 163, 197, 128, 166, 1, 217, 119, 197, 128, 166, 1, 251, + 163, 237, 182, 166, 1, 217, 119, 237, 182, 166, 1, 215, 92, 214, 197, + 166, 1, 205, 132, 237, 182, 166, 1, 251, 163, 199, 153, 166, 1, 217, 119, + 199, 153, 166, 1, 251, 163, 237, 202, 166, 1, 217, 119, 237, 202, 166, 1, + 237, 234, 214, 197, 166, 1, 205, 132, 237, 202, 166, 1, 251, 163, 210, + 71, 166, 1, 217, 119, 210, 71, 166, 1, 251, 163, 249, 55, 166, 1, 217, + 119, 249, 55, 166, 1, 217, 19, 166, 1, 251, 143, 249, 55, 166, 1, 192, + 85, 166, 1, 207, 121, 166, 1, 237, 234, 219, 247, 166, 1, 195, 156, 166, + 1, 199, 241, 205, 102, 166, 1, 215, 92, 205, 102, 166, 1, 237, 234, 205, + 102, 166, 1, 229, 251, 166, 1, 215, 92, 219, 247, 166, 1, 233, 61, 166, + 3, 251, 205, 166, 18, 3, 252, 15, 166, 18, 3, 221, 240, 252, 22, 166, 18, + 3, 237, 11, 252, 22, 166, 18, 3, 221, 240, 223, 67, 166, 18, 3, 237, 11, + 223, 67, 166, 18, 3, 221, 240, 210, 219, 166, 18, 3, 237, 11, 210, 219, + 166, 18, 3, 231, 229, 166, 18, 3, 221, 46, 166, 18, 3, 237, 11, 221, 46, + 166, 18, 3, 221, 48, 237, 120, 166, 18, 3, 221, 47, 230, 92, 252, 15, + 166, 18, 3, 221, 47, 230, 92, 237, 11, 252, 15, 166, 18, 3, 221, 47, 230, + 92, 231, 184, 166, 18, 3, 231, 184, 166, 219, 86, 17, 191, 77, 166, 219, + 86, 17, 107, 166, 219, 86, 17, 109, 166, 219, 86, 17, 138, 166, 219, 86, + 17, 134, 166, 219, 86, 17, 149, 166, 219, 86, 17, 169, 166, 219, 86, 17, + 175, 166, 219, 86, 17, 171, 166, 219, 86, 17, 178, 166, 18, 3, 237, 11, + 231, 229, 166, 18, 3, 237, 11, 231, 184, 166, 208, 152, 220, 209, 199, + 44, 246, 240, 221, 68, 222, 102, 199, 44, 246, 240, 221, 184, 221, 209, + 199, 44, 246, 240, 221, 184, 221, 174, 199, 44, 246, 240, 221, 184, 221, + 169, 199, 44, 246, 240, 221, 184, 221, 179, 199, 44, 246, 240, 221, 184, + 207, 143, 199, 44, 246, 240, 213, 250, 213, 237, 199, 44, 246, 240, 243, + 69, 246, 246, 199, 44, 246, 240, 243, 69, 243, 79, 199, 44, 246, 240, + 243, 69, 246, 245, 199, 44, 246, 240, 202, 47, 202, 46, 199, 44, 246, + 240, 243, 69, 243, 65, 199, 44, 246, 240, 192, 13, 192, 20, 199, 44, 246, + 240, 236, 175, 246, 254, 199, 44, 246, 240, 119, 210, 87, 199, 44, 246, + 240, 198, 242, 199, 38, 199, 44, 246, 240, 198, 242, 214, 222, 199, 44, + 246, 240, 198, 242, 209, 188, 199, 44, 246, 240, 213, 44, 214, 102, 199, + 44, 246, 240, 236, 175, 237, 121, 199, 44, 246, 240, 119, 199, 184, 199, + 44, 246, 240, 198, 242, 198, 207, 199, 44, 246, 240, 198, 242, 199, 45, + 199, 44, 246, 240, 198, 242, 198, 236, 199, 44, 246, 240, 213, 44, 212, + 178, 199, 44, 246, 240, 248, 112, 249, 118, 199, 44, 246, 240, 209, 74, + 209, 110, 199, 44, 246, 240, 209, 200, 209, 190, 199, 44, 246, 240, 232, + 176, 233, 109, 199, 44, 246, 240, 209, 200, 209, 221, 199, 44, 246, 240, + 232, 176, 233, 80, 199, 44, 246, 240, 209, 200, 205, 146, 199, 44, 246, + 240, 216, 13, 174, 199, 44, 246, 240, 192, 13, 192, 116, 199, 44, 246, + 240, 206, 163, 206, 61, 199, 44, 246, 240, 206, 68, 199, 44, 246, 240, + 219, 44, 219, 105, 199, 44, 246, 240, 218, 225, 199, 44, 246, 240, 193, + 49, 193, 175, 199, 44, 246, 240, 202, 47, 205, 167, 199, 44, 246, 240, + 202, 47, 206, 32, 199, 44, 246, 240, 202, 47, 200, 251, 199, 44, 246, + 240, 229, 24, 229, 122, 199, 44, 246, 240, 219, 44, 243, 47, 199, 44, + 246, 240, 187, 251, 122, 199, 44, 246, 240, 229, 24, 213, 34, 199, 44, + 246, 240, 210, 194, 199, 44, 246, 240, 205, 126, 65, 199, 44, 246, 240, + 217, 113, 230, 55, 199, 44, 246, 240, 205, 126, 252, 206, 199, 44, 246, + 240, 205, 126, 251, 149, 199, 44, 246, 240, 205, 126, 68, 199, 44, 246, + 240, 205, 126, 223, 199, 199, 44, 246, 240, 205, 126, 196, 152, 199, 44, + 246, 240, 205, 126, 196, 149, 199, 44, 246, 240, 205, 126, 66, 199, 44, + 246, 240, 205, 126, 196, 30, 199, 44, 246, 240, 209, 202, 199, 44, 238, + 170, 16, 249, 119, 199, 44, 246, 240, 205, 126, 71, 199, 44, 246, 240, + 205, 126, 252, 25, 199, 44, 246, 240, 205, 126, 74, 199, 44, 246, 240, + 205, 126, 251, 237, 217, 107, 199, 44, 246, 240, 205, 126, 251, 237, 217, + 108, 199, 44, 246, 240, 220, 39, 199, 44, 246, 240, 217, 104, 199, 44, + 246, 240, 217, 105, 199, 44, 246, 240, 217, 113, 234, 147, 199, 44, 246, + 240, 217, 113, 198, 241, 199, 44, 246, 240, 217, 113, 197, 244, 199, 44, + 246, 240, 217, 113, 243, 132, 199, 44, 246, 240, 199, 36, 199, 44, 246, + 240, 213, 183, 199, 44, 246, 240, 192, 110, 199, 44, 246, 240, 232, 164, + 199, 44, 17, 191, 77, 199, 44, 17, 107, 199, 44, 17, 109, 199, 44, 17, + 138, 199, 44, 17, 134, 199, 44, 17, 149, 199, 44, 17, 169, 199, 44, 17, + 175, 199, 44, 17, 171, 199, 44, 17, 178, 199, 44, 246, 240, 251, 117, + 199, 44, 246, 240, 221, 180, 220, 17, 1, 221, 67, 220, 17, 1, 221, 184, + 200, 195, 220, 17, 1, 221, 184, 199, 197, 220, 17, 1, 210, 187, 231, 91, + 220, 17, 1, 213, 249, 220, 17, 1, 242, 99, 220, 17, 1, 210, 187, 247, 1, + 220, 17, 1, 202, 47, 199, 197, 220, 17, 1, 210, 187, 222, 252, 220, 17, + 1, 212, 65, 220, 17, 1, 210, 187, 212, 101, 220, 17, 1, 210, 187, 197, + 132, 220, 17, 1, 210, 187, 197, 120, 220, 17, 1, 210, 187, 237, 191, 220, + 17, 1, 210, 187, 237, 175, 220, 17, 1, 210, 187, 213, 79, 220, 17, 1, + 236, 174, 220, 17, 1, 159, 220, 17, 1, 198, 242, 200, 195, 220, 17, 1, + 198, 242, 199, 197, 220, 17, 1, 210, 187, 237, 68, 220, 17, 1, 213, 43, + 220, 17, 1, 248, 111, 220, 17, 1, 209, 73, 220, 17, 1, 209, 200, 200, + 195, 220, 17, 1, 232, 176, 199, 197, 220, 17, 1, 209, 200, 199, 197, 220, + 17, 1, 232, 176, 200, 195, 220, 17, 1, 210, 187, 248, 203, 220, 17, 1, + 216, 12, 220, 17, 1, 192, 12, 220, 17, 1, 219, 44, 219, 105, 220, 17, 1, + 219, 44, 219, 2, 220, 17, 1, 193, 48, 220, 17, 1, 205, 134, 203, 165, + 220, 17, 1, 205, 134, 201, 175, 220, 17, 1, 202, 47, 200, 195, 220, 17, + 1, 229, 24, 200, 195, 220, 17, 1, 210, 187, 219, 73, 220, 17, 1, 74, 220, + 17, 1, 229, 24, 199, 197, 220, 17, 234, 120, 220, 17, 18, 3, 65, 220, 17, + 18, 3, 217, 113, 222, 87, 220, 17, 18, 3, 252, 206, 220, 17, 18, 3, 251, + 149, 220, 17, 18, 3, 68, 220, 17, 18, 3, 223, 199, 220, 17, 18, 3, 192, + 159, 220, 17, 18, 3, 191, 176, 220, 17, 18, 3, 66, 220, 17, 18, 3, 196, + 30, 220, 17, 3, 210, 187, 195, 40, 220, 17, 18, 3, 217, 113, 221, 44, + 220, 17, 204, 20, 3, 219, 43, 220, 17, 204, 20, 3, 212, 65, 220, 17, 18, + 3, 71, 220, 17, 18, 3, 234, 166, 220, 17, 18, 3, 74, 220, 17, 18, 3, 250, + 131, 220, 17, 18, 3, 251, 236, 220, 17, 221, 68, 173, 220, 17, 163, 217, + 113, 234, 147, 220, 17, 163, 217, 113, 198, 241, 220, 17, 163, 217, 113, + 198, 193, 220, 17, 163, 217, 113, 247, 77, 220, 17, 247, 125, 77, 220, + 17, 213, 192, 220, 17, 192, 110, 220, 17, 17, 191, 77, 220, 17, 17, 107, + 220, 17, 17, 109, 220, 17, 17, 138, 220, 17, 17, 134, 220, 17, 17, 149, + 220, 17, 17, 169, 220, 17, 17, 175, 220, 17, 17, 171, 220, 17, 17, 178, + 220, 17, 229, 24, 213, 43, 220, 17, 229, 24, 216, 12, 220, 17, 1, 221, + 185, 231, 3, 220, 17, 1, 221, 185, 212, 65, 86, 5, 211, 113, 86, 87, 230, + 181, 192, 25, 216, 118, 197, 178, 65, 86, 87, 230, 181, 192, 25, 216, + 118, 255, 207, 206, 167, 249, 19, 174, 86, 87, 230, 181, 192, 25, 216, + 118, 255, 207, 230, 181, 197, 153, 174, 86, 87, 89, 192, 25, 216, 118, + 216, 234, 174, 86, 87, 242, 215, 192, 25, 216, 118, 203, 172, 174, 86, + 87, 247, 97, 192, 25, 216, 118, 209, 189, 203, 158, 174, 86, 87, 192, 25, + 216, 118, 197, 153, 203, 158, 174, 86, 87, 205, 100, 203, 157, 86, 87, + 248, 13, 192, 25, 216, 117, 86, 87, 248, 141, 203, 50, 192, 25, 216, 117, + 86, 87, 223, 98, 197, 152, 86, 87, 237, 113, 197, 153, 248, 12, 86, 87, + 203, 157, 86, 87, 212, 70, 203, 157, 86, 87, 197, 153, 203, 157, 86, 87, + 212, 70, 197, 153, 203, 157, 86, 87, 206, 191, 243, 111, 201, 193, 203, + 157, 86, 87, 207, 10, 230, 222, 203, 157, 86, 87, 247, 97, 255, 211, 206, + 73, 216, 233, 179, 247, 128, 86, 87, 230, 181, 197, 152, 86, 219, 27, 3, + 246, 255, 206, 72, 86, 219, 27, 3, 219, 157, 206, 72, 86, 250, 188, 3, + 203, 168, 231, 168, 255, 212, 206, 72, 86, 250, 188, 3, 255, 209, 168, + 86, 250, 188, 3, 205, 69, 197, 147, 86, 3, 207, 115, 236, 189, 231, 167, + 86, 3, 207, 115, 236, 189, 231, 5, 86, 3, 207, 115, 236, 189, 230, 182, + 86, 3, 207, 115, 214, 243, 231, 167, 86, 3, 207, 115, 214, 243, 231, 5, + 86, 3, 207, 115, 236, 189, 207, 115, 214, 242, 86, 17, 191, 77, 86, 17, + 107, 86, 17, 109, 86, 17, 138, 86, 17, 134, 86, 17, 149, 86, 17, 169, 86, + 17, 175, 86, 17, 171, 86, 17, 178, 86, 17, 132, 107, 86, 17, 132, 109, + 86, 17, 132, 138, 86, 17, 132, 134, 86, 17, 132, 149, 86, 17, 132, 169, + 86, 17, 132, 175, 86, 17, 132, 171, 86, 17, 132, 178, 86, 17, 132, 191, + 77, 86, 87, 248, 15, 206, 72, 86, 87, 214, 59, 247, 195, 212, 82, 191, + 10, 86, 87, 247, 97, 255, 211, 206, 73, 247, 196, 216, 62, 247, 128, 86, + 87, 214, 59, 247, 195, 203, 169, 206, 72, 86, 87, 243, 128, 216, 117, 86, + 87, 197, 169, 255, 208, 86, 87, 230, 164, 206, 73, 230, 119, 86, 87, 230, + 164, 206, 73, 230, 125, 86, 87, 251, 123, 221, 202, 230, 119, 86, 87, + 251, 123, 221, 202, 230, 125, 86, 3, 192, 102, 197, 151, 86, 3, 217, 66, + 197, 151, 86, 1, 155, 86, 1, 221, 215, 86, 1, 231, 240, 86, 1, 231, 91, + 86, 1, 214, 68, 86, 1, 247, 160, 86, 1, 247, 1, 86, 1, 223, 32, 86, 1, + 212, 101, 86, 1, 197, 132, 86, 1, 197, 120, 86, 1, 237, 191, 86, 1, 237, + 175, 86, 1, 213, 79, 86, 1, 190, 190, 86, 1, 199, 49, 86, 1, 238, 32, 86, + 1, 237, 68, 86, 1, 180, 86, 1, 168, 86, 1, 209, 228, 86, 1, 249, 153, 86, + 1, 248, 203, 86, 1, 174, 86, 1, 197, 168, 86, 1, 197, 157, 86, 1, 235, + 35, 86, 1, 235, 29, 86, 1, 193, 190, 86, 1, 191, 71, 86, 1, 191, 123, 86, + 1, 255, 214, 86, 1, 170, 86, 1, 165, 86, 1, 173, 86, 1, 203, 165, 86, 1, + 201, 175, 86, 1, 188, 86, 1, 140, 86, 1, 65, 86, 1, 220, 246, 86, 1, 232, + 221, 165, 86, 1, 221, 101, 86, 1, 206, 109, 86, 18, 3, 252, 206, 86, 18, + 3, 68, 86, 18, 3, 223, 199, 86, 18, 3, 66, 86, 18, 3, 196, 30, 86, 18, 3, + 117, 146, 86, 18, 3, 117, 206, 110, 86, 18, 3, 117, 172, 86, 18, 3, 117, + 219, 74, 86, 18, 3, 71, 86, 18, 3, 234, 188, 86, 18, 3, 74, 86, 18, 3, + 211, 87, 86, 3, 206, 173, 201, 5, 214, 69, 206, 162, 86, 3, 206, 167, + 249, 18, 86, 18, 3, 207, 18, 68, 86, 18, 3, 207, 18, 223, 199, 86, 3, + 212, 82, 191, 11, 214, 251, 238, 32, 86, 3, 202, 61, 219, 240, 86, 87, + 230, 72, 86, 87, 210, 178, 86, 3, 219, 243, 206, 72, 86, 3, 192, 107, + 206, 72, 86, 3, 219, 244, 197, 169, 247, 128, 86, 3, 216, 236, 247, 128, + 86, 3, 230, 185, 247, 129, 207, 8, 86, 3, 230, 185, 216, 220, 207, 8, 86, + 3, 223, 93, 216, 236, 247, 128, 86, 200, 239, 3, 219, 244, 197, 169, 247, + 128, 86, 200, 239, 3, 216, 236, 247, 128, 86, 200, 239, 3, 223, 93, 216, + 236, 247, 128, 86, 200, 239, 1, 155, 86, 200, 239, 1, 221, 215, 86, 200, + 239, 1, 231, 240, 86, 200, 239, 1, 231, 91, 86, 200, 239, 1, 214, 68, 86, + 200, 239, 1, 247, 160, 86, 200, 239, 1, 247, 1, 86, 200, 239, 1, 223, 32, + 86, 200, 239, 1, 212, 101, 86, 200, 239, 1, 197, 132, 86, 200, 239, 1, + 197, 120, 86, 200, 239, 1, 237, 191, 86, 200, 239, 1, 237, 175, 86, 200, + 239, 1, 213, 79, 86, 200, 239, 1, 190, 190, 86, 200, 239, 1, 199, 49, 86, + 200, 239, 1, 238, 32, 86, 200, 239, 1, 237, 68, 86, 200, 239, 1, 180, 86, + 200, 239, 1, 168, 86, 200, 239, 1, 209, 228, 86, 200, 239, 1, 249, 153, + 86, 200, 239, 1, 248, 203, 86, 200, 239, 1, 174, 86, 200, 239, 1, 197, + 168, 86, 200, 239, 1, 197, 157, 86, 200, 239, 1, 235, 35, 86, 200, 239, + 1, 235, 29, 86, 200, 239, 1, 193, 190, 86, 200, 239, 1, 191, 71, 86, 200, + 239, 1, 191, 123, 86, 200, 239, 1, 255, 214, 86, 200, 239, 1, 170, 86, + 200, 239, 1, 165, 86, 200, 239, 1, 173, 86, 200, 239, 1, 203, 165, 86, + 200, 239, 1, 201, 175, 86, 200, 239, 1, 188, 86, 200, 239, 1, 140, 86, + 200, 239, 1, 65, 86, 200, 239, 1, 220, 246, 86, 200, 239, 1, 232, 221, + 193, 190, 86, 200, 239, 1, 232, 221, 170, 86, 200, 239, 1, 232, 221, 165, + 86, 220, 233, 206, 69, 221, 215, 86, 220, 233, 206, 69, 221, 216, 247, + 196, 216, 62, 247, 128, 86, 247, 112, 3, 88, 249, 7, 86, 247, 112, 3, + 156, 249, 7, 86, 247, 112, 3, 247, 116, 199, 135, 86, 247, 112, 3, 205, + 99, 255, 213, 86, 16, 235, 105, 248, 10, 86, 16, 207, 114, 206, 174, 86, + 16, 210, 206, 231, 166, 86, 16, 207, 114, 206, 175, 207, 10, 230, 221, + 86, 16, 209, 189, 168, 86, 16, 213, 21, 248, 10, 86, 16, 213, 21, 248, + 11, 212, 70, 255, 210, 86, 16, 213, 21, 248, 11, 230, 183, 255, 210, 86, + 16, 213, 21, 248, 11, 247, 196, 255, 210, 86, 3, 207, 115, 214, 243, 207, + 115, 236, 188, 86, 3, 207, 115, 214, 243, 230, 182, 86, 87, 248, 14, 203, + 50, 231, 54, 216, 118, 207, 9, 86, 87, 216, 14, 192, 25, 231, 54, 216, + 118, 207, 9, 86, 87, 212, 70, 197, 152, 86, 87, 89, 248, 44, 206, 164, + 192, 25, 216, 118, 216, 234, 174, 86, 87, 242, 215, 248, 44, 206, 164, + 192, 25, 216, 118, 203, 172, 174, 206, 207, 200, 155, 56, 219, 223, 200, + 155, 56, 206, 207, 200, 155, 3, 4, 236, 138, 219, 223, 200, 155, 3, 4, + 236, 138, 86, 87, 219, 235, 216, 237, 206, 72, 86, 87, 198, 18, 216, 237, + 206, 72, 80, 1, 155, 80, 1, 221, 215, 80, 1, 231, 240, 80, 1, 231, 91, + 80, 1, 214, 68, 80, 1, 247, 160, 80, 1, 247, 1, 80, 1, 223, 32, 80, 1, + 222, 252, 80, 1, 212, 101, 80, 1, 213, 45, 80, 1, 197, 132, 80, 1, 197, + 120, 80, 1, 237, 191, 80, 1, 237, 175, 80, 1, 213, 79, 80, 1, 190, 190, + 80, 1, 199, 49, 80, 1, 238, 32, 80, 1, 237, 68, 80, 1, 180, 80, 1, 168, + 80, 1, 209, 228, 80, 1, 249, 153, 80, 1, 248, 203, 80, 1, 174, 80, 1, + 170, 80, 1, 165, 80, 1, 173, 80, 1, 193, 190, 80, 1, 188, 80, 1, 140, 80, + 1, 219, 73, 80, 1, 65, 80, 1, 203, 139, 65, 80, 1, 68, 80, 1, 223, 199, + 80, 1, 66, 80, 1, 196, 30, 80, 1, 71, 80, 1, 215, 232, 71, 80, 1, 74, 80, + 1, 250, 163, 80, 18, 3, 199, 200, 252, 206, 80, 18, 3, 252, 206, 80, 18, + 3, 68, 80, 18, 3, 223, 199, 80, 18, 3, 66, 80, 18, 3, 196, 30, 80, 18, 3, + 71, 80, 18, 3, 251, 236, 80, 18, 3, 215, 232, 223, 199, 80, 18, 3, 215, + 232, 74, 80, 18, 3, 235, 15, 58, 80, 3, 251, 71, 80, 3, 75, 60, 80, 3, + 195, 35, 80, 3, 195, 40, 80, 3, 250, 214, 80, 120, 3, 216, 217, 170, 80, + 120, 3, 216, 217, 165, 80, 120, 3, 216, 217, 193, 190, 80, 120, 3, 216, + 217, 140, 80, 1, 230, 206, 188, 80, 17, 191, 77, 80, 17, 107, 80, 17, + 109, 80, 17, 138, 80, 17, 134, 80, 17, 149, 80, 17, 169, 80, 17, 175, 80, + 17, 171, 80, 17, 178, 80, 3, 219, 83, 205, 53, 80, 3, 205, 53, 80, 16, + 219, 36, 80, 16, 242, 67, 80, 16, 252, 1, 80, 16, 231, 146, 80, 1, 203, + 165, 80, 1, 201, 175, 80, 1, 117, 146, 80, 1, 117, 206, 110, 80, 1, 117, + 172, 80, 1, 117, 219, 74, 80, 18, 3, 117, 146, 80, 18, 3, 117, 206, 110, + 80, 18, 3, 117, 172, 80, 18, 3, 117, 219, 74, 80, 1, 215, 232, 214, 68, + 80, 1, 215, 232, 222, 252, 80, 1, 215, 232, 249, 53, 80, 1, 215, 232, + 249, 48, 80, 120, 3, 215, 232, 216, 217, 180, 80, 120, 3, 215, 232, 216, + 217, 174, 80, 120, 3, 215, 232, 216, 217, 173, 80, 1, 203, 171, 222, 62, + 203, 165, 80, 18, 3, 203, 171, 222, 62, 233, 242, 80, 163, 87, 203, 171, + 222, 62, 230, 5, 80, 163, 87, 203, 171, 222, 62, 222, 23, 209, 199, 80, + 1, 193, 102, 208, 116, 222, 62, 199, 49, 80, 1, 193, 102, 208, 116, 222, + 62, 208, 122, 80, 18, 3, 193, 102, 208, 116, 222, 62, 233, 242, 80, 18, + 3, 193, 102, 208, 116, 222, 62, 196, 152, 80, 3, 193, 102, 208, 116, 222, + 62, 198, 78, 80, 3, 193, 102, 208, 116, 222, 62, 198, 77, 80, 3, 193, + 102, 208, 116, 222, 62, 198, 76, 80, 3, 193, 102, 208, 116, 222, 62, 198, + 75, 80, 3, 193, 102, 208, 116, 222, 62, 198, 74, 80, 1, 234, 202, 208, + 116, 222, 62, 213, 79, 80, 1, 234, 202, 208, 116, 222, 62, 191, 183, 80, + 1, 234, 202, 208, 116, 222, 62, 231, 56, 80, 18, 3, 231, 161, 222, 62, + 68, 80, 18, 3, 222, 28, 211, 151, 80, 18, 3, 222, 28, 66, 80, 18, 3, 222, + 28, 234, 188, 80, 1, 203, 139, 155, 80, 1, 203, 139, 221, 215, 80, 1, + 203, 139, 231, 240, 80, 1, 203, 139, 247, 160, 80, 1, 203, 139, 191, 123, + 80, 1, 203, 139, 212, 101, 80, 1, 203, 139, 238, 32, 80, 1, 203, 139, + 180, 80, 1, 203, 139, 209, 228, 80, 1, 203, 139, 233, 109, 80, 1, 203, + 139, 249, 153, 80, 1, 203, 139, 199, 49, 80, 1, 203, 139, 140, 80, 120, + 3, 203, 139, 216, 217, 193, 190, 80, 18, 3, 203, 139, 252, 206, 80, 18, + 3, 203, 139, 71, 80, 18, 3, 203, 139, 235, 15, 58, 80, 18, 3, 203, 139, + 53, 192, 159, 80, 3, 203, 139, 198, 77, 80, 3, 203, 139, 198, 76, 80, 3, + 203, 139, 198, 74, 80, 3, 203, 139, 198, 73, 80, 3, 203, 139, 238, 247, + 198, 77, 80, 3, 203, 139, 238, 247, 198, 76, 80, 3, 203, 139, 238, 247, + 234, 106, 198, 79, 80, 1, 206, 47, 210, 189, 233, 109, 80, 3, 206, 47, + 210, 189, 198, 74, 80, 203, 139, 17, 191, 77, 80, 203, 139, 17, 107, 80, + 203, 139, 17, 109, 80, 203, 139, 17, 138, 80, 203, 139, 17, 134, 80, 203, + 139, 17, 149, 80, 203, 139, 17, 169, 80, 203, 139, 17, 175, 80, 203, 139, + 17, 171, 80, 203, 139, 17, 178, 80, 3, 221, 206, 198, 78, 80, 3, 221, + 206, 198, 76, 80, 18, 3, 251, 222, 65, 80, 18, 3, 251, 222, 251, 236, 80, + 16, 203, 139, 107, 80, 16, 203, 139, 233, 215, 101, 6, 1, 251, 132, 101, + 6, 1, 249, 101, 101, 6, 1, 231, 210, 101, 6, 1, 236, 150, 101, 6, 1, 234, + 103, 101, 6, 1, 195, 49, 101, 6, 1, 191, 80, 101, 6, 1, 199, 193, 101, 6, + 1, 223, 162, 101, 6, 1, 222, 87, 101, 6, 1, 220, 7, 101, 6, 1, 217, 90, + 101, 6, 1, 214, 216, 101, 6, 1, 211, 104, 101, 6, 1, 210, 131, 101, 6, 1, + 191, 67, 101, 6, 1, 207, 163, 101, 6, 1, 205, 142, 101, 6, 1, 199, 179, + 101, 6, 1, 196, 113, 101, 6, 1, 209, 220, 101, 6, 1, 221, 200, 101, 6, 1, + 231, 82, 101, 6, 1, 208, 81, 101, 6, 1, 203, 69, 101, 6, 1, 243, 81, 101, + 6, 1, 247, 128, 101, 6, 1, 222, 234, 101, 6, 1, 243, 18, 101, 6, 1, 246, + 241, 101, 6, 1, 192, 218, 101, 6, 1, 222, 249, 101, 6, 1, 230, 87, 101, + 6, 1, 229, 245, 101, 6, 1, 229, 145, 101, 6, 1, 193, 125, 101, 6, 1, 230, + 19, 101, 6, 1, 229, 11, 101, 6, 1, 192, 14, 101, 6, 1, 252, 14, 101, 1, + 251, 132, 101, 1, 249, 101, 101, 1, 231, 210, 101, 1, 236, 150, 101, 1, + 234, 103, 101, 1, 195, 49, 101, 1, 191, 80, 101, 1, 199, 193, 101, 1, + 223, 162, 101, 1, 222, 87, 101, 1, 220, 7, 101, 1, 217, 90, 101, 1, 214, + 216, 101, 1, 211, 104, 101, 1, 210, 131, 101, 1, 191, 67, 101, 1, 207, + 163, 101, 1, 205, 142, 101, 1, 199, 179, 101, 1, 196, 113, 101, 1, 209, + 220, 101, 1, 221, 200, 101, 1, 231, 82, 101, 1, 208, 81, 101, 1, 203, 69, + 101, 1, 243, 81, 101, 1, 247, 128, 101, 1, 222, 234, 101, 1, 243, 18, + 101, 1, 246, 241, 101, 1, 192, 218, 101, 1, 222, 249, 101, 1, 230, 87, + 101, 1, 229, 245, 101, 1, 229, 145, 101, 1, 193, 125, 101, 1, 230, 19, + 101, 1, 229, 11, 101, 1, 233, 23, 101, 1, 192, 14, 101, 1, 234, 123, 101, + 1, 153, 231, 210, 101, 1, 251, 230, 101, 210, 128, 204, 10, 52, 1, 101, + 214, 216, 101, 1, 252, 14, 101, 1, 230, 17, 56, 101, 1, 220, 116, 56, 30, + 147, 221, 113, 30, 147, 201, 167, 30, 147, 213, 204, 30, 147, 198, 168, + 30, 147, 201, 156, 30, 147, 206, 239, 30, 147, 216, 77, 30, 147, 209, + 169, 30, 147, 201, 164, 30, 147, 202, 160, 30, 147, 201, 161, 30, 147, + 223, 222, 30, 147, 243, 24, 30, 147, 201, 171, 30, 147, 243, 91, 30, 147, + 221, 188, 30, 147, 199, 7, 30, 147, 209, 209, 30, 147, 229, 142, 30, 147, + 213, 200, 30, 147, 201, 165, 30, 147, 213, 194, 30, 147, 213, 198, 30, + 147, 198, 165, 30, 147, 206, 227, 30, 147, 201, 163, 30, 147, 206, 237, + 30, 147, 222, 68, 30, 147, 216, 70, 30, 147, 222, 71, 30, 147, 209, 164, + 30, 147, 209, 162, 30, 147, 209, 150, 30, 147, 209, 158, 30, 147, 209, + 156, 30, 147, 209, 153, 30, 147, 209, 155, 30, 147, 209, 152, 30, 147, + 209, 157, 30, 147, 209, 167, 30, 147, 209, 168, 30, 147, 209, 151, 30, + 147, 209, 161, 30, 147, 222, 69, 30, 147, 222, 67, 30, 147, 202, 153, 30, + 147, 202, 151, 30, 147, 202, 143, 30, 147, 202, 146, 30, 147, 202, 152, + 30, 147, 202, 148, 30, 147, 202, 147, 30, 147, 202, 145, 30, 147, 202, + 156, 30, 147, 202, 158, 30, 147, 202, 159, 30, 147, 202, 154, 30, 147, + 202, 144, 30, 147, 202, 149, 30, 147, 202, 157, 30, 147, 243, 72, 30, + 147, 243, 70, 30, 147, 247, 14, 30, 147, 247, 12, 30, 147, 210, 149, 30, + 147, 223, 217, 30, 147, 223, 208, 30, 147, 223, 216, 30, 147, 223, 213, + 30, 147, 223, 211, 30, 147, 223, 215, 30, 147, 201, 168, 30, 147, 223, + 220, 30, 147, 223, 221, 30, 147, 223, 209, 30, 147, 223, 214, 30, 147, + 192, 57, 30, 147, 243, 23, 30, 147, 243, 73, 30, 147, 243, 71, 30, 147, + 247, 15, 30, 147, 247, 13, 30, 147, 243, 89, 30, 147, 243, 90, 30, 147, + 243, 74, 30, 147, 247, 16, 30, 147, 209, 207, 30, 147, 222, 70, 30, 147, + 201, 169, 30, 147, 192, 63, 30, 147, 221, 104, 30, 147, 213, 196, 30, + 147, 213, 202, 30, 147, 213, 201, 30, 147, 198, 162, 30, 147, 233, 3, 30, + 222, 174, 233, 3, 30, 222, 174, 65, 30, 222, 174, 252, 25, 30, 222, 174, + 170, 30, 222, 174, 192, 129, 30, 222, 174, 234, 65, 30, 222, 174, 71, 30, + 222, 174, 192, 67, 30, 222, 174, 192, 80, 30, 222, 174, 74, 30, 222, 174, + 193, 190, 30, 222, 174, 193, 176, 30, 222, 174, 211, 151, 30, 222, 174, + 192, 12, 30, 222, 174, 66, 30, 222, 174, 193, 107, 30, 222, 174, 193, + 125, 30, 222, 174, 193, 86, 30, 222, 174, 191, 225, 30, 222, 174, 233, + 242, 30, 222, 174, 192, 33, 30, 222, 174, 68, 30, 222, 174, 255, 202, 30, + 222, 174, 255, 201, 30, 222, 174, 192, 143, 30, 222, 174, 192, 141, 30, + 222, 174, 234, 63, 30, 222, 174, 234, 62, 30, 222, 174, 234, 64, 30, 222, + 174, 192, 66, 30, 222, 174, 192, 65, 30, 222, 174, 212, 10, 30, 222, 174, + 212, 11, 30, 222, 174, 212, 4, 30, 222, 174, 212, 9, 30, 222, 174, 212, + 7, 30, 222, 174, 192, 0, 30, 222, 174, 191, 255, 30, 222, 174, 191, 254, + 30, 222, 174, 192, 1, 30, 222, 174, 192, 2, 30, 222, 174, 196, 226, 30, + 222, 174, 196, 225, 30, 222, 174, 196, 223, 30, 222, 174, 196, 219, 30, + 222, 174, 196, 220, 30, 222, 174, 191, 220, 30, 222, 174, 191, 217, 30, + 222, 174, 191, 218, 30, 222, 174, 191, 212, 30, 222, 174, 191, 213, 30, + 222, 174, 191, 214, 30, 222, 174, 191, 216, 30, 222, 174, 233, 236, 30, + 222, 174, 233, 238, 30, 222, 174, 192, 32, 30, 222, 174, 228, 69, 30, + 222, 174, 228, 61, 30, 222, 174, 228, 64, 30, 222, 174, 228, 62, 30, 222, + 174, 228, 66, 30, 222, 174, 228, 68, 30, 222, 174, 251, 25, 30, 222, 174, + 251, 22, 30, 222, 174, 251, 20, 30, 222, 174, 251, 21, 30, 222, 174, 201, + 172, 30, 222, 174, 255, 203, 30, 222, 174, 192, 142, 30, 222, 174, 192, + 64, 30, 222, 174, 212, 6, 30, 222, 174, 212, 5, 30, 125, 221, 113, 30, + 125, 201, 167, 30, 125, 221, 106, 30, 125, 213, 204, 30, 125, 213, 202, + 30, 125, 213, 201, 30, 125, 198, 168, 30, 125, 206, 239, 30, 125, 206, + 234, 30, 125, 206, 231, 30, 125, 206, 224, 30, 125, 206, 219, 30, 125, + 206, 214, 30, 125, 206, 225, 30, 125, 206, 237, 30, 125, 216, 77, 30, + 125, 209, 169, 30, 125, 209, 158, 30, 125, 202, 160, 30, 125, 201, 161, + 30, 125, 223, 222, 30, 125, 243, 24, 30, 125, 243, 91, 30, 125, 221, 188, + 30, 125, 199, 7, 30, 125, 209, 209, 30, 125, 229, 142, 30, 125, 221, 107, + 30, 125, 221, 105, 30, 125, 213, 200, 30, 125, 213, 194, 30, 125, 213, + 196, 30, 125, 213, 199, 30, 125, 213, 195, 30, 125, 198, 165, 30, 125, + 198, 162, 30, 125, 206, 232, 30, 125, 206, 227, 30, 125, 206, 213, 30, + 125, 206, 212, 30, 125, 201, 163, 30, 125, 206, 229, 30, 125, 206, 228, + 30, 125, 206, 221, 30, 125, 206, 223, 30, 125, 206, 236, 30, 125, 206, + 216, 30, 125, 206, 226, 30, 125, 206, 235, 30, 125, 206, 211, 30, 125, + 216, 73, 30, 125, 216, 68, 30, 125, 216, 70, 30, 125, 216, 67, 30, 125, + 216, 65, 30, 125, 216, 71, 30, 125, 216, 76, 30, 125, 216, 74, 30, 125, + 222, 71, 30, 125, 209, 160, 30, 125, 209, 161, 30, 125, 209, 166, 30, + 125, 222, 69, 30, 125, 202, 153, 30, 125, 202, 143, 30, 125, 202, 146, + 30, 125, 202, 148, 30, 125, 210, 149, 30, 125, 223, 217, 30, 125, 223, + 210, 30, 125, 201, 168, 30, 125, 223, 218, 30, 125, 192, 57, 30, 125, + 192, 51, 30, 125, 192, 52, 30, 125, 209, 207, 30, 125, 222, 70, 30, 125, + 229, 140, 30, 125, 229, 138, 30, 125, 229, 141, 30, 125, 229, 139, 30, + 125, 192, 63, 30, 125, 221, 109, 30, 125, 221, 108, 30, 125, 221, 112, + 30, 125, 221, 110, 30, 125, 221, 111, 30, 125, 201, 165, 36, 5, 140, 36, + 5, 228, 159, 36, 5, 229, 158, 36, 5, 230, 91, 36, 5, 229, 215, 36, 5, + 229, 245, 36, 5, 229, 23, 36, 5, 229, 14, 36, 5, 173, 36, 5, 218, 225, + 36, 5, 219, 146, 36, 5, 220, 125, 36, 5, 219, 228, 36, 5, 219, 238, 36, + 5, 219, 43, 36, 5, 218, 191, 36, 5, 229, 177, 36, 5, 229, 171, 36, 5, + 229, 173, 36, 5, 229, 176, 36, 5, 229, 174, 36, 5, 229, 175, 36, 5, 229, + 172, 36, 5, 229, 170, 36, 5, 174, 36, 5, 215, 155, 36, 5, 216, 100, 36, + 5, 217, 151, 36, 5, 216, 211, 36, 5, 216, 232, 36, 5, 216, 12, 36, 5, + 215, 80, 36, 5, 200, 54, 36, 5, 200, 48, 36, 5, 200, 50, 36, 5, 200, 53, + 36, 5, 200, 51, 36, 5, 200, 52, 36, 5, 200, 49, 36, 5, 200, 47, 36, 5, + 165, 36, 5, 206, 68, 36, 5, 207, 1, 36, 5, 207, 178, 36, 5, 207, 84, 36, + 5, 207, 113, 36, 5, 206, 162, 36, 5, 206, 26, 36, 5, 188, 36, 5, 201, 4, + 36, 5, 202, 222, 36, 5, 205, 197, 36, 5, 205, 50, 36, 5, 205, 68, 36, 5, + 202, 46, 36, 5, 200, 150, 36, 5, 203, 165, 36, 5, 203, 5, 36, 5, 203, 81, + 36, 5, 203, 160, 36, 5, 203, 111, 36, 5, 203, 113, 36, 5, 203, 56, 36, 5, + 202, 240, 36, 5, 208, 96, 36, 5, 208, 33, 36, 5, 208, 57, 36, 5, 208, 95, + 36, 5, 208, 74, 36, 5, 208, 75, 36, 5, 208, 45, 36, 5, 208, 44, 36, 5, + 207, 240, 36, 5, 207, 236, 36, 5, 207, 239, 36, 5, 207, 237, 36, 5, 207, + 238, 36, 5, 208, 71, 36, 5, 208, 63, 36, 5, 208, 66, 36, 5, 208, 70, 36, + 5, 208, 67, 36, 5, 208, 68, 36, 5, 208, 65, 36, 5, 208, 62, 36, 5, 208, + 58, 36, 5, 208, 61, 36, 5, 208, 59, 36, 5, 208, 60, 36, 5, 249, 153, 36, + 5, 248, 10, 36, 5, 248, 188, 36, 5, 249, 151, 36, 5, 249, 1, 36, 5, 249, + 17, 36, 5, 248, 111, 36, 5, 247, 210, 36, 5, 195, 188, 36, 5, 193, 249, + 36, 5, 195, 69, 36, 5, 195, 187, 36, 5, 195, 148, 36, 5, 195, 153, 36, 5, + 195, 24, 36, 5, 193, 238, 36, 5, 190, 190, 36, 5, 197, 94, 36, 5, 198, + 193, 36, 5, 199, 245, 36, 5, 199, 121, 36, 5, 199, 145, 36, 5, 159, 36, + 5, 197, 43, 36, 5, 247, 160, 36, 5, 238, 195, 36, 5, 243, 29, 36, 5, 247, + 159, 36, 5, 247, 34, 36, 5, 247, 42, 36, 5, 242, 99, 36, 5, 238, 151, 36, + 5, 192, 220, 36, 5, 192, 188, 36, 5, 192, 207, 36, 5, 192, 219, 36, 5, + 192, 213, 36, 5, 192, 214, 36, 5, 192, 196, 36, 5, 192, 195, 36, 5, 192, + 181, 36, 5, 192, 177, 36, 5, 192, 180, 36, 5, 192, 178, 36, 5, 192, 179, + 36, 5, 180, 36, 5, 212, 178, 36, 5, 213, 219, 36, 5, 214, 250, 36, 5, + 214, 110, 36, 5, 214, 121, 36, 5, 213, 43, 36, 5, 212, 110, 36, 5, 212, + 101, 36, 5, 212, 58, 36, 5, 212, 81, 36, 5, 212, 100, 36, 5, 212, 89, 36, + 5, 212, 90, 36, 5, 212, 65, 36, 5, 212, 48, 36, 5, 231, 11, 65, 36, 5, + 231, 11, 66, 36, 5, 231, 11, 68, 36, 5, 231, 11, 252, 206, 36, 5, 231, + 11, 234, 188, 36, 5, 231, 11, 71, 36, 5, 231, 11, 74, 36, 5, 231, 11, + 193, 190, 36, 5, 155, 36, 5, 220, 232, 36, 5, 221, 166, 36, 5, 222, 127, + 36, 5, 222, 13, 36, 5, 222, 22, 36, 5, 221, 67, 36, 5, 221, 62, 36, 5, + 220, 179, 36, 5, 220, 172, 36, 5, 220, 178, 36, 5, 220, 173, 36, 5, 220, + 174, 36, 5, 220, 165, 36, 5, 220, 159, 36, 5, 220, 161, 36, 5, 220, 164, + 36, 5, 220, 162, 36, 5, 220, 163, 36, 5, 220, 160, 36, 5, 220, 158, 36, + 5, 220, 154, 36, 5, 220, 157, 36, 5, 220, 155, 36, 5, 220, 156, 36, 5, + 193, 190, 36, 5, 193, 0, 36, 5, 193, 86, 36, 5, 193, 181, 36, 5, 193, + 114, 36, 5, 193, 125, 36, 5, 193, 48, 36, 5, 193, 40, 36, 5, 209, 219, + 65, 36, 5, 209, 219, 66, 36, 5, 209, 219, 68, 36, 5, 209, 219, 252, 206, + 36, 5, 209, 219, 234, 188, 36, 5, 209, 219, 71, 36, 5, 209, 219, 74, 36, + 5, 191, 123, 36, 5, 190, 251, 36, 5, 191, 30, 36, 5, 191, 121, 36, 5, + 191, 84, 36, 5, 191, 87, 36, 5, 191, 7, 36, 5, 190, 238, 36, 5, 191, 71, + 36, 5, 191, 48, 36, 5, 191, 57, 36, 5, 191, 70, 36, 5, 191, 61, 36, 5, + 191, 62, 36, 5, 191, 54, 36, 5, 191, 39, 36, 5, 170, 36, 5, 191, 225, 36, + 5, 192, 33, 36, 5, 192, 140, 36, 5, 192, 77, 36, 5, 192, 80, 36, 5, 192, + 12, 36, 5, 191, 252, 36, 5, 238, 32, 36, 5, 235, 89, 36, 5, 237, 44, 36, + 5, 238, 31, 36, 5, 237, 131, 36, 5, 237, 146, 36, 5, 236, 174, 36, 5, + 235, 46, 36, 5, 237, 191, 36, 5, 237, 156, 36, 5, 237, 168, 36, 5, 237, + 190, 36, 5, 237, 178, 36, 5, 237, 179, 36, 5, 237, 161, 36, 5, 237, 147, + 36, 5, 223, 32, 36, 5, 222, 182, 36, 5, 222, 244, 36, 5, 223, 31, 36, 5, + 223, 8, 36, 5, 223, 10, 36, 5, 222, 201, 36, 5, 222, 160, 36, 5, 231, + 240, 36, 5, 230, 179, 36, 5, 231, 53, 36, 5, 231, 237, 36, 5, 231, 157, + 36, 5, 231, 165, 36, 5, 231, 3, 36, 5, 231, 2, 36, 5, 230, 135, 36, 5, + 230, 131, 36, 5, 230, 134, 36, 5, 230, 132, 36, 5, 230, 133, 36, 5, 231, + 127, 36, 5, 231, 107, 36, 5, 231, 117, 36, 5, 231, 126, 36, 5, 231, 121, + 36, 5, 231, 122, 36, 5, 231, 111, 36, 5, 231, 96, 36, 5, 199, 49, 36, 5, + 198, 213, 36, 5, 199, 11, 36, 5, 199, 48, 36, 5, 199, 31, 36, 5, 199, 33, + 36, 5, 198, 241, 36, 5, 198, 204, 36, 5, 247, 1, 36, 5, 243, 48, 36, 5, + 243, 95, 36, 5, 247, 0, 36, 5, 243, 123, 36, 5, 243, 127, 36, 5, 243, 68, + 36, 5, 243, 37, 36, 5, 209, 228, 36, 5, 209, 191, 36, 5, 209, 211, 36, 5, + 209, 227, 36, 5, 209, 213, 36, 5, 209, 214, 36, 5, 209, 199, 36, 5, 209, + 187, 36, 5, 197, 168, 36, 5, 197, 140, 36, 5, 197, 146, 36, 5, 197, 167, + 36, 5, 197, 160, 36, 5, 197, 161, 36, 5, 197, 144, 36, 5, 197, 138, 36, + 5, 196, 240, 36, 5, 196, 232, 36, 5, 196, 236, 36, 5, 196, 239, 36, 5, + 196, 237, 36, 5, 196, 238, 36, 5, 196, 234, 36, 5, 196, 233, 36, 5, 233, + 109, 36, 5, 232, 86, 36, 5, 233, 23, 36, 5, 233, 108, 36, 5, 233, 52, 36, + 5, 233, 59, 36, 5, 232, 175, 36, 5, 232, 62, 36, 5, 168, 36, 5, 208, 165, + 36, 5, 209, 185, 36, 5, 210, 220, 36, 5, 210, 49, 36, 5, 210, 63, 36, 5, + 209, 73, 36, 5, 208, 122, 36, 5, 206, 16, 36, 5, 215, 68, 36, 5, 232, 56, + 36, 33, 231, 153, 23, 18, 219, 198, 77, 36, 33, 18, 219, 198, 77, 36, 33, + 231, 153, 77, 36, 205, 54, 77, 36, 193, 22, 36, 232, 80, 201, 63, 36, + 242, 74, 36, 204, 25, 36, 242, 83, 36, 208, 228, 242, 83, 36, 208, 13, + 77, 36, 210, 128, 204, 10, 36, 17, 107, 36, 17, 109, 36, 17, 138, 36, 17, + 134, 36, 17, 149, 36, 17, 169, 36, 17, 175, 36, 17, 171, 36, 17, 178, 36, + 31, 199, 95, 36, 31, 197, 32, 36, 31, 198, 249, 36, 31, 232, 135, 36, 31, + 233, 15, 36, 31, 202, 120, 36, 31, 203, 241, 36, 31, 234, 153, 36, 31, + 213, 169, 36, 31, 228, 140, 36, 31, 199, 96, 189, 36, 5, 205, 59, 215, + 80, 36, 5, 215, 76, 36, 5, 215, 77, 36, 5, 215, 78, 36, 5, 205, 59, 247, + 210, 36, 5, 247, 207, 36, 5, 247, 208, 36, 5, 247, 209, 36, 5, 205, 59, + 232, 62, 36, 5, 232, 58, 36, 5, 232, 59, 36, 5, 232, 60, 36, 5, 205, 59, + 208, 122, 36, 5, 208, 118, 36, 5, 208, 119, 36, 5, 208, 120, 36, 198, 80, + 87, 192, 15, 36, 198, 80, 87, 237, 89, 36, 198, 80, 87, 206, 194, 36, + 198, 80, 87, 203, 40, 206, 194, 36, 198, 80, 87, 237, 18, 36, 198, 80, + 87, 221, 250, 36, 198, 80, 87, 243, 76, 36, 198, 80, 87, 229, 147, 36, + 198, 80, 87, 237, 88, 36, 198, 80, 87, 220, 195, 103, 1, 65, 103, 1, 71, + 103, 1, 68, 103, 1, 74, 103, 1, 66, 103, 1, 196, 12, 103, 1, 231, 240, + 103, 1, 155, 103, 1, 231, 165, 103, 1, 231, 53, 103, 1, 231, 3, 103, 1, + 230, 179, 103, 1, 230, 138, 103, 1, 140, 103, 1, 229, 245, 103, 1, 229, + 158, 103, 1, 229, 23, 103, 1, 228, 159, 103, 1, 228, 126, 103, 1, 173, + 103, 1, 219, 238, 103, 1, 219, 146, 103, 1, 219, 43, 103, 1, 218, 225, + 103, 1, 218, 192, 103, 1, 174, 103, 1, 216, 232, 103, 1, 216, 100, 103, + 1, 216, 12, 103, 1, 215, 155, 103, 1, 180, 103, 1, 229, 47, 103, 1, 214, + 237, 103, 1, 214, 121, 103, 1, 213, 219, 103, 1, 213, 43, 103, 1, 212, + 178, 103, 1, 212, 112, 103, 1, 208, 32, 103, 1, 208, 16, 103, 1, 208, 9, + 103, 1, 207, 255, 103, 1, 207, 244, 103, 1, 207, 242, 103, 1, 188, 103, + 1, 206, 8, 103, 1, 205, 68, 103, 1, 202, 222, 103, 1, 202, 46, 103, 1, + 201, 4, 103, 1, 200, 158, 103, 1, 238, 32, 103, 1, 190, 190, 103, 1, 237, + 146, 103, 1, 199, 145, 103, 1, 237, 44, 103, 1, 198, 193, 103, 1, 236, + 174, 103, 1, 235, 89, 103, 1, 235, 57, 103, 1, 236, 186, 103, 1, 198, + 115, 103, 1, 198, 114, 103, 1, 198, 103, 103, 1, 198, 102, 103, 1, 198, + 101, 103, 1, 198, 100, 103, 1, 197, 168, 103, 1, 197, 161, 103, 1, 197, + 146, 103, 1, 197, 144, 103, 1, 197, 140, 103, 1, 197, 139, 103, 1, 193, + 190, 103, 1, 193, 125, 103, 1, 193, 86, 103, 1, 193, 48, 103, 1, 193, 0, + 103, 1, 192, 243, 103, 1, 170, 103, 1, 192, 80, 103, 1, 192, 33, 103, 1, + 192, 12, 103, 1, 191, 225, 103, 1, 191, 184, 103, 1, 215, 87, 103, 2, 1, + 192, 80, 103, 2, 1, 192, 33, 103, 2, 1, 192, 12, 103, 2, 1, 191, 225, + 103, 2, 1, 191, 184, 103, 2, 1, 215, 87, 21, 22, 228, 88, 21, 22, 71, 21, + 22, 252, 170, 21, 22, 68, 21, 22, 223, 199, 21, 22, 74, 21, 22, 211, 87, + 21, 22, 192, 158, 211, 87, 21, 22, 98, 234, 188, 21, 22, 98, 68, 21, 22, + 65, 21, 22, 252, 206, 21, 22, 193, 125, 21, 22, 193, 103, 193, 125, 21, + 22, 193, 86, 21, 22, 193, 103, 193, 86, 21, 22, 193, 70, 21, 22, 193, + 103, 193, 70, 21, 22, 193, 48, 21, 22, 193, 103, 193, 48, 21, 22, 193, + 29, 21, 22, 193, 103, 193, 29, 21, 22, 214, 209, 193, 29, 21, 22, 193, + 190, 21, 22, 193, 103, 193, 190, 21, 22, 193, 181, 21, 22, 193, 103, 193, + 181, 21, 22, 214, 209, 193, 181, 21, 22, 251, 236, 21, 22, 192, 158, 193, + 224, 21, 22, 231, 11, 201, 63, 21, 22, 53, 252, 46, 21, 22, 53, 230, 210, + 21, 22, 53, 248, 77, 132, 206, 188, 21, 22, 53, 198, 54, 132, 206, 188, + 21, 22, 53, 50, 132, 206, 188, 21, 22, 53, 206, 188, 21, 22, 53, 55, 252, + 46, 21, 22, 53, 55, 203, 40, 81, 201, 15, 21, 22, 53, 82, 236, 140, 21, + 22, 53, 203, 40, 228, 241, 106, 21, 22, 53, 209, 81, 21, 22, 53, 144, + 199, 228, 21, 22, 234, 103, 21, 22, 223, 162, 21, 22, 211, 104, 21, 22, + 251, 132, 21, 22, 210, 63, 21, 22, 210, 218, 21, 22, 209, 185, 21, 22, + 209, 145, 21, 22, 209, 73, 21, 22, 209, 37, 21, 22, 192, 158, 209, 37, + 21, 22, 98, 229, 215, 21, 22, 98, 229, 158, 21, 22, 168, 21, 22, 210, + 220, 21, 22, 208, 120, 21, 22, 193, 103, 208, 120, 21, 22, 208, 118, 21, + 22, 193, 103, 208, 118, 21, 22, 208, 117, 21, 22, 193, 103, 208, 117, 21, + 22, 208, 115, 21, 22, 193, 103, 208, 115, 21, 22, 208, 114, 21, 22, 193, + 103, 208, 114, 21, 22, 208, 122, 21, 22, 193, 103, 208, 122, 21, 22, 208, + 121, 21, 22, 193, 103, 208, 121, 21, 22, 192, 158, 208, 121, 21, 22, 210, + 236, 21, 22, 193, 103, 210, 236, 21, 22, 98, 230, 116, 21, 22, 199, 145, + 21, 22, 199, 242, 21, 22, 198, 193, 21, 22, 198, 170, 21, 22, 159, 21, + 22, 198, 59, 21, 22, 192, 158, 198, 59, 21, 22, 98, 237, 131, 21, 22, 98, + 237, 44, 21, 22, 190, 190, 21, 22, 199, 245, 21, 22, 197, 41, 21, 22, + 193, 103, 197, 41, 21, 22, 197, 19, 21, 22, 193, 103, 197, 19, 21, 22, + 197, 18, 21, 22, 193, 103, 197, 18, 21, 22, 109, 21, 22, 193, 103, 109, + 21, 22, 197, 9, 21, 22, 193, 103, 197, 9, 21, 22, 197, 43, 21, 22, 193, + 103, 197, 43, 21, 22, 197, 42, 21, 22, 193, 103, 197, 42, 21, 22, 214, + 209, 197, 42, 21, 22, 200, 43, 21, 22, 197, 127, 21, 22, 197, 111, 21, + 22, 197, 109, 21, 22, 197, 132, 21, 22, 222, 22, 21, 22, 222, 121, 21, + 22, 221, 166, 21, 22, 221, 145, 21, 22, 221, 67, 21, 22, 221, 41, 21, 22, + 192, 158, 221, 41, 21, 22, 155, 21, 22, 222, 127, 21, 22, 220, 174, 21, + 22, 193, 103, 220, 174, 21, 22, 220, 172, 21, 22, 193, 103, 220, 172, 21, + 22, 220, 171, 21, 22, 193, 103, 220, 171, 21, 22, 220, 169, 21, 22, 193, + 103, 220, 169, 21, 22, 220, 168, 21, 22, 193, 103, 220, 168, 21, 22, 220, + 179, 21, 22, 193, 103, 220, 179, 21, 22, 220, 178, 21, 22, 193, 103, 220, + 178, 21, 22, 214, 209, 220, 178, 21, 22, 222, 152, 21, 22, 220, 180, 21, + 22, 202, 1, 222, 6, 21, 22, 202, 1, 221, 146, 21, 22, 202, 1, 221, 56, + 21, 22, 202, 1, 222, 104, 21, 22, 247, 42, 21, 22, 247, 158, 21, 22, 243, + 29, 21, 22, 243, 19, 21, 22, 242, 99, 21, 22, 239, 18, 21, 22, 192, 158, + 239, 18, 21, 22, 247, 160, 21, 22, 247, 159, 21, 22, 238, 149, 21, 22, + 193, 103, 238, 149, 21, 22, 238, 147, 21, 22, 193, 103, 238, 147, 21, 22, + 238, 146, 21, 22, 193, 103, 238, 146, 21, 22, 238, 145, 21, 22, 193, 103, + 238, 145, 21, 22, 238, 144, 21, 22, 193, 103, 238, 144, 21, 22, 238, 151, + 21, 22, 193, 103, 238, 151, 21, 22, 238, 150, 21, 22, 193, 103, 238, 150, + 21, 22, 214, 209, 238, 150, 21, 22, 247, 193, 21, 22, 205, 101, 199, 51, + 21, 22, 216, 232, 21, 22, 217, 150, 21, 22, 216, 100, 21, 22, 216, 61, + 21, 22, 216, 12, 21, 22, 215, 211, 21, 22, 192, 158, 215, 211, 21, 22, + 174, 21, 22, 217, 151, 21, 22, 215, 78, 21, 22, 193, 103, 215, 78, 21, + 22, 215, 76, 21, 22, 193, 103, 215, 76, 21, 22, 215, 75, 21, 22, 193, + 103, 215, 75, 21, 22, 215, 74, 21, 22, 193, 103, 215, 74, 21, 22, 215, + 73, 21, 22, 193, 103, 215, 73, 21, 22, 215, 80, 21, 22, 193, 103, 215, + 80, 21, 22, 215, 79, 21, 22, 193, 103, 215, 79, 21, 22, 214, 209, 215, + 79, 21, 22, 218, 168, 21, 22, 193, 103, 218, 168, 21, 22, 216, 104, 21, + 22, 250, 180, 218, 168, 21, 22, 205, 101, 218, 168, 21, 22, 214, 121, 21, + 22, 214, 249, 21, 22, 213, 219, 21, 22, 213, 186, 21, 22, 213, 43, 21, + 22, 213, 26, 21, 22, 192, 158, 213, 26, 21, 22, 180, 21, 22, 214, 250, + 21, 22, 212, 108, 21, 22, 193, 103, 212, 108, 21, 22, 212, 110, 21, 22, + 193, 103, 212, 110, 21, 22, 212, 109, 21, 22, 193, 103, 212, 109, 21, 22, + 214, 209, 212, 109, 21, 22, 215, 61, 21, 22, 98, 214, 70, 21, 22, 213, + 225, 21, 22, 219, 238, 21, 22, 220, 124, 21, 22, 219, 146, 21, 22, 219, + 128, 21, 22, 219, 43, 21, 22, 219, 8, 21, 22, 192, 158, 219, 8, 21, 22, + 173, 21, 22, 220, 125, 21, 22, 218, 189, 21, 22, 193, 103, 218, 189, 21, + 22, 218, 188, 21, 22, 193, 103, 218, 188, 21, 22, 218, 187, 21, 22, 193, + 103, 218, 187, 21, 22, 218, 186, 21, 22, 193, 103, 218, 186, 21, 22, 218, + 185, 21, 22, 193, 103, 218, 185, 21, 22, 218, 191, 21, 22, 193, 103, 218, + 191, 21, 22, 218, 190, 21, 22, 193, 103, 218, 190, 21, 22, 172, 21, 22, + 193, 103, 172, 21, 22, 216, 217, 172, 21, 22, 205, 68, 21, 22, 205, 195, + 21, 22, 202, 222, 21, 22, 202, 193, 21, 22, 202, 46, 21, 22, 202, 16, 21, + 22, 192, 158, 202, 16, 21, 22, 188, 21, 22, 205, 197, 21, 22, 200, 145, + 21, 22, 193, 103, 200, 145, 21, 22, 200, 139, 21, 22, 193, 103, 200, 139, + 21, 22, 200, 138, 21, 22, 193, 103, 200, 138, 21, 22, 200, 133, 21, 22, + 193, 103, 200, 133, 21, 22, 200, 132, 21, 22, 193, 103, 200, 132, 21, 22, + 200, 150, 21, 22, 193, 103, 200, 150, 21, 22, 200, 149, 21, 22, 193, 103, + 200, 149, 21, 22, 214, 209, 200, 149, 21, 22, 206, 8, 21, 22, 250, 180, + 206, 8, 21, 22, 200, 151, 21, 22, 248, 136, 206, 8, 21, 22, 215, 203, + 202, 114, 21, 22, 214, 209, 202, 101, 21, 22, 214, 209, 206, 6, 21, 22, + 214, 209, 201, 192, 21, 22, 214, 209, 201, 7, 21, 22, 214, 209, 202, 100, + 21, 22, 214, 209, 205, 71, 21, 22, 203, 113, 21, 22, 203, 81, 21, 22, + 203, 76, 21, 22, 203, 56, 21, 22, 203, 48, 21, 22, 203, 165, 21, 22, 203, + 160, 21, 22, 202, 237, 21, 22, 193, 103, 202, 237, 21, 22, 202, 236, 21, + 22, 193, 103, 202, 236, 21, 22, 202, 235, 21, 22, 193, 103, 202, 235, 21, + 22, 202, 234, 21, 22, 193, 103, 202, 234, 21, 22, 202, 233, 21, 22, 193, + 103, 202, 233, 21, 22, 202, 240, 21, 22, 193, 103, 202, 240, 21, 22, 202, + 239, 21, 22, 193, 103, 202, 239, 21, 22, 203, 167, 21, 22, 192, 80, 21, + 22, 192, 138, 21, 22, 192, 33, 21, 22, 192, 23, 21, 22, 192, 12, 21, 22, + 191, 246, 21, 22, 192, 158, 191, 246, 21, 22, 170, 21, 22, 192, 140, 21, + 22, 191, 181, 21, 22, 193, 103, 191, 181, 21, 22, 191, 180, 21, 22, 193, + 103, 191, 180, 21, 22, 191, 179, 21, 22, 193, 103, 191, 179, 21, 22, 191, + 178, 21, 22, 193, 103, 191, 178, 21, 22, 191, 177, 21, 22, 193, 103, 191, + 177, 21, 22, 191, 183, 21, 22, 193, 103, 191, 183, 21, 22, 191, 182, 21, + 22, 193, 103, 191, 182, 21, 22, 214, 209, 191, 182, 21, 22, 192, 159, 21, + 22, 248, 186, 192, 159, 21, 22, 193, 103, 192, 159, 21, 22, 205, 101, + 192, 33, 21, 22, 207, 113, 21, 22, 207, 221, 207, 113, 21, 22, 193, 103, + 219, 238, 21, 22, 207, 177, 21, 22, 207, 1, 21, 22, 206, 195, 21, 22, + 206, 162, 21, 22, 206, 134, 21, 22, 193, 103, 219, 43, 21, 22, 165, 21, + 22, 207, 178, 21, 22, 193, 103, 173, 21, 22, 206, 25, 21, 22, 193, 103, + 206, 25, 21, 22, 146, 21, 22, 193, 103, 146, 21, 22, 216, 217, 146, 21, + 22, 233, 59, 21, 22, 233, 106, 21, 22, 233, 23, 21, 22, 233, 8, 21, 22, + 232, 175, 21, 22, 232, 162, 21, 22, 233, 109, 21, 22, 233, 108, 21, 22, + 232, 61, 21, 22, 193, 103, 232, 61, 21, 22, 233, 175, 21, 22, 199, 33, + 21, 22, 215, 59, 199, 33, 21, 22, 199, 11, 21, 22, 215, 59, 199, 11, 21, + 22, 199, 5, 21, 22, 215, 59, 199, 5, 21, 22, 198, 241, 21, 22, 198, 235, + 21, 22, 199, 49, 21, 22, 199, 48, 21, 22, 198, 203, 21, 22, 193, 103, + 198, 203, 21, 22, 199, 51, 21, 22, 197, 118, 21, 22, 197, 116, 21, 22, + 197, 115, 21, 22, 197, 120, 21, 22, 197, 121, 21, 22, 197, 2, 21, 22, + 197, 1, 21, 22, 197, 0, 21, 22, 197, 4, 21, 22, 212, 129, 229, 245, 21, + 22, 212, 129, 229, 158, 21, 22, 212, 129, 229, 130, 21, 22, 212, 129, + 229, 23, 21, 22, 212, 129, 228, 252, 21, 22, 212, 129, 140, 21, 22, 212, + 129, 230, 91, 21, 22, 212, 129, 230, 116, 21, 22, 212, 128, 230, 116, 21, + 22, 229, 113, 21, 22, 208, 92, 21, 22, 208, 57, 21, 22, 208, 51, 21, 22, + 208, 45, 21, 22, 208, 40, 21, 22, 208, 96, 21, 22, 208, 95, 21, 22, 208, + 104, 21, 22, 198, 111, 21, 22, 198, 109, 21, 22, 198, 108, 21, 22, 198, + 112, 21, 22, 193, 103, 207, 113, 21, 22, 193, 103, 207, 1, 21, 22, 193, + 103, 206, 162, 21, 22, 193, 103, 165, 21, 22, 214, 66, 21, 22, 214, 16, + 21, 22, 214, 12, 21, 22, 213, 249, 21, 22, 213, 244, 21, 22, 214, 68, 21, + 22, 214, 67, 21, 22, 214, 70, 21, 22, 213, 72, 21, 22, 205, 101, 203, + 113, 21, 22, 205, 101, 203, 81, 21, 22, 205, 101, 203, 56, 21, 22, 205, + 101, 203, 165, 21, 22, 193, 27, 199, 33, 21, 22, 193, 27, 199, 11, 21, + 22, 193, 27, 198, 241, 21, 22, 193, 27, 199, 49, 21, 22, 193, 27, 199, + 51, 21, 22, 219, 153, 21, 22, 219, 152, 21, 22, 219, 151, 21, 22, 219, + 150, 21, 22, 219, 159, 21, 22, 219, 158, 21, 22, 219, 160, 21, 22, 199, + 50, 199, 33, 21, 22, 199, 50, 199, 11, 21, 22, 199, 50, 199, 5, 21, 22, + 199, 50, 198, 241, 21, 22, 199, 50, 198, 235, 21, 22, 199, 50, 199, 49, + 21, 22, 199, 50, 199, 48, 21, 22, 199, 50, 199, 51, 21, 22, 251, 220, + 250, 120, 21, 22, 248, 136, 71, 21, 22, 248, 136, 68, 21, 22, 248, 136, + 74, 21, 22, 248, 136, 65, 21, 22, 248, 136, 193, 125, 21, 22, 248, 136, + 193, 86, 21, 22, 248, 136, 193, 48, 21, 22, 248, 136, 193, 190, 21, 22, + 248, 136, 214, 121, 21, 22, 248, 136, 213, 219, 21, 22, 248, 136, 213, + 43, 21, 22, 248, 136, 180, 21, 22, 248, 136, 222, 22, 21, 22, 248, 136, + 221, 166, 21, 22, 248, 136, 221, 67, 21, 22, 248, 136, 155, 21, 22, 205, + 101, 229, 245, 21, 22, 205, 101, 229, 158, 21, 22, 205, 101, 229, 23, 21, + 22, 205, 101, 140, 21, 22, 98, 231, 59, 21, 22, 98, 231, 63, 21, 22, 98, + 231, 77, 21, 22, 98, 231, 76, 21, 22, 98, 231, 65, 21, 22, 98, 231, 91, + 21, 22, 98, 206, 68, 21, 22, 98, 206, 162, 21, 22, 98, 207, 113, 21, 22, + 98, 207, 84, 21, 22, 98, 207, 1, 21, 22, 98, 165, 21, 22, 98, 193, 0, 21, + 22, 98, 193, 48, 21, 22, 98, 193, 125, 21, 22, 98, 193, 114, 21, 22, 98, + 193, 86, 21, 22, 98, 193, 190, 21, 22, 98, 228, 118, 21, 22, 98, 228, + 119, 21, 22, 98, 228, 122, 21, 22, 98, 228, 121, 21, 22, 98, 228, 120, + 21, 22, 98, 228, 125, 21, 22, 98, 198, 213, 21, 22, 98, 198, 241, 21, 22, + 98, 199, 33, 21, 22, 98, 199, 31, 21, 22, 98, 199, 11, 21, 22, 98, 199, + 49, 21, 22, 98, 197, 99, 21, 22, 98, 197, 109, 21, 22, 98, 197, 127, 21, + 22, 98, 197, 126, 21, 22, 98, 197, 111, 21, 22, 98, 197, 132, 21, 22, 98, + 208, 165, 21, 22, 98, 209, 73, 21, 22, 98, 210, 63, 21, 22, 98, 210, 49, + 21, 22, 98, 209, 185, 21, 22, 98, 168, 21, 22, 98, 210, 236, 21, 22, 98, + 230, 179, 21, 22, 98, 231, 3, 21, 22, 98, 231, 165, 21, 22, 98, 231, 157, + 21, 22, 98, 231, 53, 21, 22, 98, 231, 240, 21, 22, 98, 221, 175, 21, 22, + 98, 221, 183, 21, 22, 98, 221, 197, 21, 22, 98, 221, 196, 21, 22, 98, + 221, 190, 21, 22, 98, 221, 215, 21, 22, 98, 221, 96, 21, 22, 98, 221, 97, + 21, 22, 98, 221, 100, 21, 22, 98, 221, 99, 21, 22, 98, 221, 98, 21, 22, + 98, 221, 101, 21, 22, 98, 221, 102, 21, 22, 98, 212, 178, 21, 22, 98, + 213, 43, 21, 22, 98, 214, 121, 21, 22, 98, 214, 110, 21, 22, 98, 213, + 219, 21, 22, 98, 180, 21, 22, 98, 215, 155, 21, 22, 98, 216, 12, 21, 22, + 98, 216, 232, 21, 22, 98, 216, 211, 21, 22, 98, 216, 100, 21, 22, 98, + 174, 21, 22, 98, 191, 225, 21, 22, 98, 192, 12, 21, 22, 98, 192, 80, 21, + 22, 98, 192, 77, 21, 22, 98, 192, 33, 21, 22, 98, 170, 21, 22, 98, 222, + 182, 21, 22, 205, 101, 222, 182, 21, 22, 98, 222, 201, 21, 22, 98, 223, + 10, 21, 22, 98, 223, 8, 21, 22, 98, 222, 244, 21, 22, 205, 101, 222, 244, + 21, 22, 98, 223, 32, 21, 22, 98, 222, 215, 21, 22, 98, 222, 219, 21, 22, + 98, 222, 229, 21, 22, 98, 222, 228, 21, 22, 98, 222, 227, 21, 22, 98, + 222, 230, 21, 22, 98, 218, 225, 21, 22, 98, 219, 43, 21, 22, 98, 219, + 238, 21, 22, 98, 219, 228, 21, 22, 98, 219, 146, 21, 22, 98, 173, 21, 22, + 98, 236, 179, 21, 22, 98, 236, 180, 21, 22, 98, 236, 185, 21, 22, 98, + 236, 184, 21, 22, 98, 236, 181, 21, 22, 98, 236, 186, 21, 22, 98, 219, + 149, 21, 22, 98, 219, 151, 21, 22, 98, 219, 155, 21, 22, 98, 219, 154, + 21, 22, 98, 219, 153, 21, 22, 98, 219, 159, 21, 22, 98, 198, 106, 21, 22, + 98, 198, 108, 21, 22, 98, 198, 111, 21, 22, 98, 198, 110, 21, 22, 98, + 198, 109, 21, 22, 98, 198, 112, 21, 22, 98, 198, 101, 21, 22, 98, 198, + 102, 21, 22, 98, 198, 114, 21, 22, 98, 198, 113, 21, 22, 98, 198, 103, + 21, 22, 98, 198, 115, 21, 22, 98, 190, 251, 21, 22, 98, 191, 7, 21, 22, + 98, 191, 87, 21, 22, 98, 191, 84, 21, 22, 98, 191, 30, 21, 22, 98, 191, + 123, 21, 22, 98, 191, 166, 21, 22, 98, 89, 191, 166, 21, 22, 98, 235, 22, + 21, 22, 98, 235, 23, 21, 22, 98, 235, 32, 21, 22, 98, 235, 31, 21, 22, + 98, 235, 26, 21, 22, 98, 235, 35, 21, 22, 98, 201, 4, 21, 22, 98, 202, + 46, 21, 22, 98, 205, 68, 21, 22, 98, 205, 50, 21, 22, 98, 202, 222, 21, + 22, 98, 188, 21, 22, 98, 203, 5, 21, 22, 98, 203, 56, 21, 22, 98, 203, + 113, 21, 22, 98, 203, 111, 21, 22, 98, 203, 81, 21, 22, 98, 203, 165, 21, + 22, 98, 203, 167, 21, 22, 98, 197, 140, 21, 22, 98, 197, 144, 21, 22, 98, + 197, 161, 21, 22, 98, 197, 160, 21, 22, 98, 197, 146, 21, 22, 98, 197, + 168, 21, 22, 98, 243, 48, 21, 22, 98, 243, 68, 21, 22, 98, 243, 127, 21, + 22, 98, 243, 123, 21, 22, 98, 243, 95, 21, 22, 98, 247, 1, 21, 22, 98, + 197, 102, 21, 22, 98, 197, 103, 21, 22, 98, 197, 106, 21, 22, 98, 197, + 105, 21, 22, 98, 197, 104, 21, 22, 98, 197, 107, 21, 22, 243, 96, 56, 21, + 22, 232, 80, 201, 63, 21, 22, 208, 88, 21, 22, 214, 64, 21, 22, 213, 69, + 21, 22, 213, 68, 21, 22, 213, 67, 21, 22, 213, 66, 21, 22, 213, 71, 21, + 22, 213, 70, 21, 22, 193, 27, 198, 201, 21, 22, 193, 27, 198, 200, 21, + 22, 193, 27, 198, 199, 21, 22, 193, 27, 198, 198, 21, 22, 193, 27, 198, + 197, 21, 22, 193, 27, 198, 204, 21, 22, 193, 27, 198, 203, 21, 22, 193, + 27, 53, 199, 51, 21, 22, 248, 136, 193, 224, 211, 140, 201, 248, 77, 211, + 140, 1, 248, 239, 211, 140, 1, 218, 211, 211, 140, 1, 233, 56, 211, 140, + 1, 205, 179, 211, 140, 1, 213, 166, 211, 140, 1, 196, 165, 211, 140, 1, + 238, 5, 211, 140, 1, 198, 139, 211, 140, 1, 242, 86, 211, 140, 1, 247, + 29, 211, 140, 1, 215, 137, 211, 140, 1, 230, 234, 211, 140, 1, 214, 54, + 211, 140, 1, 201, 54, 211, 140, 1, 206, 55, 211, 140, 1, 251, 232, 211, + 140, 1, 211, 91, 211, 140, 1, 196, 62, 211, 140, 1, 234, 215, 211, 140, + 1, 223, 87, 211, 140, 1, 234, 216, 211, 140, 1, 211, 56, 211, 140, 1, + 196, 136, 211, 140, 1, 223, 205, 211, 140, 1, 234, 213, 211, 140, 1, 210, + 38, 211, 140, 233, 55, 77, 211, 140, 207, 18, 233, 55, 77, 206, 44, 1, + 233, 45, 233, 36, 233, 60, 233, 175, 206, 44, 1, 196, 12, 206, 44, 1, + 196, 47, 196, 63, 66, 206, 44, 1, 191, 228, 206, 44, 1, 192, 159, 206, + 44, 1, 193, 224, 206, 44, 1, 198, 206, 198, 205, 198, 233, 206, 44, 1, + 233, 248, 206, 44, 1, 251, 90, 65, 206, 44, 1, 211, 37, 74, 206, 44, 1, + 252, 64, 65, 206, 44, 1, 252, 9, 206, 44, 1, 219, 15, 74, 206, 44, 1, + 203, 33, 74, 206, 44, 1, 74, 206, 44, 1, 211, 151, 206, 44, 1, 211, 104, + 206, 44, 1, 207, 154, 207, 169, 207, 69, 146, 206, 44, 1, 222, 39, 206, + 44, 1, 247, 25, 206, 44, 1, 222, 40, 222, 152, 206, 44, 1, 232, 51, 206, + 44, 1, 234, 88, 206, 44, 1, 231, 160, 230, 122, 232, 51, 206, 44, 1, 231, + 200, 206, 44, 1, 192, 248, 192, 239, 193, 224, 206, 44, 1, 230, 82, 230, + 116, 206, 44, 1, 230, 86, 230, 116, 206, 44, 1, 219, 17, 230, 116, 206, + 44, 1, 203, 36, 230, 116, 206, 44, 1, 214, 203, 212, 91, 214, 204, 215, + 61, 206, 44, 1, 203, 34, 215, 61, 206, 44, 1, 235, 135, 206, 44, 1, 223, + 65, 223, 69, 223, 55, 68, 206, 44, 1, 71, 206, 44, 1, 222, 255, 223, 35, + 206, 44, 1, 231, 141, 206, 44, 1, 219, 18, 252, 25, 206, 44, 1, 203, 38, + 65, 206, 44, 1, 223, 47, 234, 61, 206, 44, 1, 209, 247, 210, 18, 210, + 236, 206, 44, 1, 251, 185, 234, 59, 206, 44, 1, 201, 254, 206, 8, 206, + 44, 1, 202, 198, 219, 14, 206, 8, 206, 44, 1, 203, 32, 206, 8, 206, 44, + 1, 247, 193, 206, 44, 1, 191, 166, 206, 44, 1, 198, 120, 198, 132, 196, + 242, 200, 43, 206, 44, 1, 203, 31, 200, 43, 206, 44, 1, 238, 127, 206, + 44, 1, 248, 217, 248, 220, 248, 142, 250, 120, 206, 44, 1, 203, 37, 250, + 120, 206, 44, 1, 235, 134, 206, 44, 1, 211, 70, 206, 44, 1, 234, 167, + 234, 174, 71, 206, 44, 1, 217, 79, 217, 91, 218, 168, 206, 44, 1, 219, + 16, 218, 168, 206, 44, 1, 203, 35, 218, 168, 206, 44, 1, 219, 253, 220, + 101, 219, 26, 172, 206, 44, 1, 235, 136, 206, 44, 1, 223, 135, 206, 44, + 1, 223, 136, 206, 44, 1, 238, 19, 238, 25, 238, 127, 206, 44, 1, 211, 28, + 233, 247, 74, 206, 44, 1, 234, 211, 206, 44, 1, 223, 85, 206, 44, 1, 238, + 148, 206, 44, 1, 247, 143, 206, 44, 1, 247, 41, 206, 44, 1, 201, 108, + 206, 44, 1, 219, 13, 206, 44, 1, 203, 30, 206, 44, 1, 228, 25, 206, 44, + 1, 208, 104, 206, 44, 1, 192, 235, 206, 44, 202, 170, 208, 151, 206, 44, + 215, 129, 208, 151, 206, 44, 238, 218, 208, 151, 206, 44, 250, 252, 113, + 206, 44, 197, 45, 113, 206, 44, 248, 237, 113, 206, 44, 1, 222, 152, 206, + 44, 1, 203, 167, 206, 44, 1, 211, 87, 206, 44, 1, 232, 110, 247, 81, 211, + 36, 206, 44, 1, 232, 110, 247, 81, 223, 68, 206, 44, 1, 232, 110, 247, + 81, 234, 173, 206, 44, 1, 232, 110, 247, 81, 252, 63, 206, 44, 1, 232, + 110, 247, 81, 252, 9, 199, 222, 1, 65, 199, 222, 1, 68, 199, 222, 1, 66, + 199, 222, 1, 155, 199, 222, 1, 231, 240, 199, 222, 1, 214, 68, 199, 222, + 1, 190, 190, 199, 222, 1, 238, 32, 199, 222, 1, 180, 199, 222, 1, 168, + 199, 222, 1, 249, 153, 199, 222, 1, 174, 199, 222, 1, 170, 199, 222, 1, + 165, 199, 222, 1, 173, 199, 222, 1, 193, 190, 199, 222, 1, 188, 199, 222, + 1, 140, 199, 222, 18, 3, 68, 199, 222, 18, 3, 66, 199, 222, 3, 195, 40, + 199, 222, 3, 210, 169, 199, 222, 1, 251, 14, 165, 230, 23, 1, 65, 230, + 23, 1, 68, 230, 23, 1, 66, 230, 23, 1, 155, 230, 23, 1, 231, 240, 230, + 23, 1, 214, 68, 230, 23, 1, 190, 190, 230, 23, 1, 238, 32, 230, 23, 1, + 180, 230, 23, 1, 168, 230, 23, 1, 249, 153, 230, 23, 1, 174, 230, 23, 1, + 170, 230, 23, 1, 165, 230, 23, 1, 173, 230, 23, 1, 193, 190, 230, 23, 1, + 188, 230, 23, 1, 140, 230, 23, 18, 3, 68, 230, 23, 18, 3, 66, 230, 23, 3, + 210, 169, 209, 204, 202, 170, 208, 151, 209, 204, 55, 208, 151, 248, 0, + 1, 65, 248, 0, 1, 68, 248, 0, 1, 66, 248, 0, 1, 155, 248, 0, 1, 231, 240, + 248, 0, 1, 214, 68, 248, 0, 1, 190, 190, 248, 0, 1, 238, 32, 248, 0, 1, + 180, 248, 0, 1, 168, 248, 0, 1, 249, 153, 248, 0, 1, 174, 248, 0, 1, 170, + 248, 0, 1, 165, 248, 0, 1, 173, 248, 0, 1, 193, 190, 248, 0, 1, 188, 248, + 0, 1, 140, 248, 0, 18, 3, 68, 248, 0, 18, 3, 66, 199, 221, 1, 65, 199, + 221, 1, 68, 199, 221, 1, 66, 199, 221, 1, 155, 199, 221, 1, 231, 240, + 199, 221, 1, 214, 68, 199, 221, 1, 190, 190, 199, 221, 1, 238, 32, 199, + 221, 1, 180, 199, 221, 1, 168, 199, 221, 1, 249, 153, 199, 221, 1, 174, + 199, 221, 1, 170, 199, 221, 1, 173, 199, 221, 1, 193, 190, 199, 221, 1, + 188, 199, 221, 18, 3, 68, 199, 221, 18, 3, 66, 95, 1, 155, 95, 1, 221, + 215, 95, 1, 221, 67, 95, 1, 221, 183, 95, 1, 213, 249, 95, 1, 247, 160, + 95, 1, 247, 1, 95, 1, 242, 99, 95, 1, 243, 68, 95, 1, 212, 65, 95, 1, + 238, 32, 95, 1, 197, 120, 95, 1, 236, 174, 95, 1, 197, 115, 95, 1, 213, + 49, 95, 1, 190, 190, 95, 1, 199, 49, 95, 1, 159, 95, 1, 198, 241, 95, 1, + 213, 43, 95, 1, 249, 153, 95, 1, 209, 228, 95, 1, 209, 73, 95, 1, 209, + 199, 95, 1, 216, 12, 95, 1, 192, 12, 95, 1, 206, 162, 95, 1, 219, 43, 95, + 1, 195, 24, 95, 1, 203, 165, 95, 1, 201, 134, 95, 1, 188, 95, 1, 140, 95, + 1, 173, 95, 1, 208, 96, 95, 223, 149, 18, 208, 82, 95, 223, 149, 18, 208, + 95, 95, 223, 149, 18, 208, 57, 95, 223, 149, 18, 208, 51, 95, 223, 149, + 18, 208, 33, 95, 223, 149, 18, 208, 0, 95, 223, 149, 18, 207, 244, 95, + 223, 149, 18, 207, 243, 95, 223, 149, 18, 206, 17, 95, 223, 149, 18, 206, + 10, 95, 223, 149, 18, 218, 183, 95, 223, 149, 18, 218, 171, 95, 223, 149, + 18, 208, 75, 95, 223, 149, 18, 208, 88, 95, 223, 149, 18, 208, 41, 196, + 255, 107, 95, 223, 149, 18, 208, 41, 196, 255, 109, 95, 223, 149, 18, + 208, 77, 95, 18, 223, 133, 251, 37, 95, 18, 223, 133, 252, 206, 95, 18, + 3, 252, 206, 95, 18, 3, 68, 95, 18, 3, 223, 199, 95, 18, 3, 192, 159, 95, + 18, 3, 191, 176, 95, 18, 3, 66, 95, 18, 3, 196, 30, 95, 18, 3, 196, 168, + 95, 18, 3, 211, 151, 95, 18, 3, 170, 95, 18, 3, 223, 226, 95, 18, 3, 71, + 95, 18, 3, 252, 25, 95, 18, 3, 251, 236, 95, 18, 3, 211, 87, 95, 18, 3, + 250, 163, 95, 3, 213, 184, 95, 3, 207, 106, 95, 3, 191, 187, 95, 3, 215, + 91, 95, 3, 197, 229, 95, 3, 249, 90, 95, 3, 206, 151, 95, 3, 198, 90, 95, + 3, 222, 95, 95, 3, 251, 238, 95, 3, 205, 143, 205, 135, 95, 3, 195, 37, + 95, 3, 242, 90, 95, 3, 249, 60, 95, 3, 221, 205, 95, 3, 249, 85, 95, 3, + 247, 131, 209, 146, 220, 186, 95, 3, 219, 205, 198, 59, 95, 3, 248, 205, + 95, 3, 209, 201, 215, 148, 95, 3, 221, 39, 95, 238, 170, 16, 206, 241, + 95, 3, 250, 144, 95, 3, 250, 166, 95, 17, 191, 77, 95, 17, 107, 95, 17, + 109, 95, 17, 138, 95, 17, 134, 95, 17, 149, 95, 17, 169, 95, 17, 175, 95, + 17, 171, 95, 17, 178, 95, 16, 219, 205, 250, 168, 202, 19, 95, 16, 219, + 205, 250, 168, 215, 112, 95, 16, 219, 205, 250, 168, 209, 145, 95, 16, + 219, 205, 250, 168, 248, 240, 95, 16, 219, 205, 250, 168, 247, 236, 95, + 16, 219, 205, 250, 168, 208, 245, 95, 16, 219, 205, 250, 168, 208, 239, + 95, 16, 219, 205, 250, 168, 208, 237, 95, 16, 219, 205, 250, 168, 208, + 243, 95, 16, 219, 205, 250, 168, 208, 241, 104, 248, 158, 104, 234, 120, + 104, 242, 74, 104, 232, 80, 201, 63, 104, 242, 83, 104, 232, 128, 236, + 138, 104, 198, 88, 202, 32, 228, 88, 104, 202, 214, 5, 248, 73, 217, 51, + 104, 217, 87, 242, 74, 104, 217, 87, 232, 80, 201, 63, 104, 213, 164, + 104, 232, 109, 67, 205, 35, 107, 104, 232, 109, 67, 205, 35, 109, 104, + 232, 109, 67, 205, 35, 138, 104, 18, 204, 10, 104, 232, 109, 67, 205, 35, + 134, 104, 17, 191, 77, 104, 17, 107, 104, 17, 109, 104, 17, 138, 104, 17, + 134, 104, 17, 149, 104, 17, 169, 104, 17, 175, 104, 17, 171, 104, 17, + 178, 104, 1, 65, 104, 1, 71, 104, 1, 68, 104, 1, 74, 104, 1, 66, 104, 1, + 211, 151, 104, 1, 196, 152, 104, 1, 234, 188, 104, 1, 180, 104, 1, 251, + 122, 104, 1, 249, 153, 104, 1, 168, 104, 1, 208, 96, 104, 1, 231, 240, + 104, 1, 174, 104, 1, 173, 104, 1, 188, 104, 1, 203, 165, 104, 1, 190, + 190, 104, 1, 238, 32, 104, 1, 247, 1, 104, 1, 223, 32, 104, 1, 170, 104, + 1, 165, 104, 1, 193, 190, 104, 1, 233, 109, 104, 1, 155, 104, 1, 221, + 215, 104, 1, 197, 168, 104, 1, 191, 123, 104, 1, 230, 91, 104, 1, 190, + 255, 104, 1, 219, 159, 104, 1, 191, 57, 104, 1, 243, 95, 104, 1, 198, 88, + 179, 18, 56, 104, 1, 198, 88, 71, 104, 1, 198, 88, 68, 104, 1, 198, 88, + 74, 104, 1, 198, 88, 66, 104, 1, 198, 88, 211, 151, 104, 1, 198, 88, 196, + 152, 104, 1, 198, 88, 251, 122, 104, 1, 198, 88, 249, 153, 104, 1, 198, + 88, 168, 104, 1, 198, 88, 208, 96, 104, 1, 198, 88, 231, 240, 104, 1, + 198, 88, 174, 104, 1, 198, 88, 190, 190, 104, 1, 198, 88, 238, 32, 104, + 1, 198, 88, 247, 1, 104, 1, 198, 88, 223, 32, 104, 1, 198, 88, 197, 168, + 104, 1, 198, 88, 170, 104, 1, 198, 88, 193, 190, 104, 1, 198, 88, 155, + 104, 1, 198, 88, 231, 237, 104, 1, 198, 88, 230, 91, 104, 1, 198, 88, + 222, 243, 104, 1, 198, 88, 213, 209, 104, 1, 198, 88, 235, 35, 104, 1, + 202, 214, 71, 104, 1, 202, 214, 68, 104, 1, 202, 214, 223, 44, 104, 1, + 202, 214, 196, 152, 104, 1, 202, 214, 66, 104, 1, 202, 214, 251, 122, + 104, 1, 202, 214, 155, 104, 1, 202, 214, 231, 240, 104, 1, 202, 214, 140, + 104, 1, 202, 214, 168, 104, 1, 202, 214, 203, 165, 104, 1, 202, 214, 190, + 190, 104, 1, 202, 214, 238, 32, 104, 1, 202, 214, 223, 32, 104, 1, 202, + 214, 233, 109, 104, 1, 202, 214, 231, 237, 104, 1, 202, 214, 230, 91, + 104, 1, 202, 214, 197, 168, 104, 1, 202, 214, 191, 123, 104, 1, 202, 214, + 207, 178, 104, 1, 202, 214, 247, 1, 104, 1, 202, 214, 191, 71, 104, 1, + 217, 87, 68, 104, 1, 217, 87, 155, 104, 1, 217, 87, 165, 104, 1, 217, 87, + 233, 109, 104, 1, 217, 87, 191, 71, 104, 1, 247, 2, 4, 105, 236, 138, + 104, 1, 251, 184, 231, 220, 251, 72, 107, 104, 1, 251, 184, 231, 220, + 195, 36, 107, 104, 1, 251, 184, 231, 220, 237, 247, 104, 1, 251, 184, + 231, 220, 196, 163, 104, 1, 251, 184, 231, 220, 223, 93, 196, 163, 104, + 1, 251, 184, 231, 220, 249, 104, 104, 1, 251, 184, 231, 220, 115, 249, + 104, 104, 1, 251, 184, 231, 220, 65, 104, 1, 251, 184, 231, 220, 68, 104, + 1, 251, 184, 231, 220, 155, 104, 1, 251, 184, 231, 220, 214, 68, 104, 1, + 251, 184, 231, 220, 247, 160, 104, 1, 251, 184, 231, 220, 197, 132, 104, + 1, 251, 184, 231, 220, 197, 120, 104, 1, 251, 184, 231, 220, 237, 191, + 104, 1, 251, 184, 231, 220, 213, 79, 104, 1, 251, 184, 231, 220, 190, + 190, 104, 1, 251, 184, 231, 220, 238, 32, 104, 1, 251, 184, 231, 220, + 168, 104, 1, 251, 184, 231, 220, 209, 228, 104, 1, 251, 184, 231, 220, + 201, 175, 104, 1, 251, 184, 231, 220, 191, 71, 104, 1, 251, 184, 231, + 220, 191, 123, 104, 1, 251, 184, 231, 220, 251, 245, 104, 1, 198, 88, + 251, 184, 231, 220, 190, 190, 104, 1, 198, 88, 251, 184, 231, 220, 191, + 71, 104, 1, 217, 87, 251, 184, 231, 220, 231, 91, 104, 1, 217, 87, 251, + 184, 231, 220, 214, 68, 104, 1, 217, 87, 251, 184, 231, 220, 247, 160, + 104, 1, 217, 87, 251, 184, 231, 220, 222, 252, 104, 1, 217, 87, 251, 184, + 231, 220, 197, 132, 104, 1, 217, 87, 251, 184, 231, 220, 237, 175, 104, + 1, 217, 87, 251, 184, 231, 220, 190, 190, 104, 1, 217, 87, 251, 184, 231, + 220, 237, 68, 104, 1, 217, 87, 251, 184, 231, 220, 201, 175, 104, 1, 217, + 87, 251, 184, 231, 220, 238, 142, 104, 1, 217, 87, 251, 184, 231, 220, + 191, 71, 104, 1, 217, 87, 251, 184, 231, 220, 191, 123, 104, 1, 251, 184, + 231, 220, 132, 66, 104, 1, 251, 184, 231, 220, 132, 170, 104, 1, 217, 87, + 251, 184, 231, 220, 248, 203, 104, 1, 251, 184, 231, 220, 238, 20, 104, + 1, 217, 87, 251, 184, 231, 220, 219, 159, 21, 22, 210, 242, 21, 22, 250, + 131, 21, 22, 252, 160, 21, 22, 193, 128, 21, 22, 208, 251, 21, 22, 210, + 72, 21, 22, 208, 113, 21, 22, 199, 154, 21, 22, 222, 29, 21, 22, 220, + 176, 21, 22, 217, 21, 21, 22, 212, 250, 21, 22, 214, 198, 21, 22, 219, + 248, 21, 22, 201, 252, 21, 22, 205, 103, 21, 22, 203, 18, 21, 22, 203, + 117, 21, 22, 202, 232, 21, 22, 191, 234, 21, 22, 192, 86, 21, 22, 207, + 122, 21, 22, 212, 107, 21, 22, 211, 128, 212, 107, 21, 22, 212, 106, 21, + 22, 211, 128, 212, 106, 21, 22, 212, 105, 21, 22, 211, 128, 212, 105, 21, + 22, 212, 104, 21, 22, 211, 128, 212, 104, 21, 22, 206, 22, 21, 22, 206, + 21, 21, 22, 206, 20, 21, 22, 206, 19, 21, 22, 206, 18, 21, 22, 206, 26, + 21, 22, 211, 128, 210, 236, 21, 22, 211, 128, 200, 43, 21, 22, 211, 128, + 222, 152, 21, 22, 211, 128, 247, 193, 21, 22, 211, 128, 218, 168, 21, 22, + 211, 128, 215, 61, 21, 22, 211, 128, 206, 8, 21, 22, 211, 128, 203, 167, + 21, 22, 234, 202, 193, 224, 21, 22, 193, 102, 193, 224, 21, 22, 53, 2, + 206, 188, 21, 22, 53, 207, 147, 236, 140, 21, 22, 207, 221, 206, 23, 21, + 22, 193, 103, 219, 8, 21, 22, 193, 103, 220, 125, 21, 22, 198, 202, 21, + 22, 198, 204, 21, 22, 197, 112, 21, 22, 197, 114, 21, 22, 197, 119, 21, + 22, 198, 105, 21, 22, 198, 107, 21, 22, 205, 101, 202, 237, 21, 22, 205, + 101, 203, 48, 21, 22, 205, 101, 228, 252, 21, 22, 98, 230, 130, 21, 22, + 98, 237, 103, 231, 157, 21, 22, 98, 231, 237, 21, 22, 98, 230, 135, 21, + 22, 205, 101, 222, 162, 21, 22, 98, 222, 160, 21, 22, 249, 5, 237, 103, + 172, 21, 22, 249, 5, 237, 103, 146, 21, 22, 98, 237, 98, 206, 8, 219, + 122, 195, 1, 219, 175, 219, 122, 1, 155, 219, 122, 1, 221, 215, 219, 122, + 1, 231, 240, 219, 122, 1, 231, 91, 219, 122, 1, 214, 68, 219, 122, 1, + 247, 160, 219, 122, 1, 247, 1, 219, 122, 1, 223, 32, 219, 122, 1, 222, + 252, 219, 122, 1, 192, 108, 219, 122, 1, 190, 190, 219, 122, 1, 199, 49, + 219, 122, 1, 238, 32, 219, 122, 1, 237, 68, 219, 122, 1, 180, 219, 122, + 1, 168, 219, 122, 1, 209, 228, 219, 122, 1, 249, 153, 219, 122, 1, 248, + 203, 219, 122, 1, 174, 219, 122, 1, 170, 219, 122, 1, 165, 219, 122, 1, + 173, 219, 122, 1, 193, 190, 219, 122, 1, 203, 165, 219, 122, 1, 201, 175, + 219, 122, 1, 188, 219, 122, 1, 140, 219, 122, 1, 230, 126, 219, 122, 1, + 198, 26, 219, 122, 18, 3, 65, 219, 122, 18, 3, 68, 219, 122, 18, 3, 66, + 219, 122, 18, 3, 234, 188, 219, 122, 18, 3, 251, 236, 219, 122, 18, 3, + 211, 87, 219, 122, 18, 3, 250, 163, 219, 122, 18, 3, 71, 219, 122, 18, 3, + 74, 219, 122, 200, 239, 1, 170, 219, 122, 200, 239, 1, 165, 219, 122, + 200, 239, 1, 193, 190, 219, 122, 2, 1, 155, 219, 122, 2, 1, 214, 68, 219, + 122, 2, 1, 251, 71, 219, 122, 2, 1, 190, 190, 219, 122, 2, 1, 180, 219, + 122, 2, 1, 168, 219, 122, 2, 1, 174, 219, 122, 2, 1, 165, 219, 122, 2, 1, + 173, 219, 122, 3, 215, 134, 219, 122, 3, 222, 1, 219, 122, 3, 205, 198, + 219, 122, 3, 219, 8, 219, 122, 233, 216, 77, 219, 122, 208, 13, 77, 219, + 122, 17, 191, 77, 219, 122, 17, 107, 219, 122, 17, 109, 219, 122, 17, + 138, 219, 122, 17, 134, 219, 122, 17, 149, 219, 122, 17, 169, 219, 122, + 17, 175, 219, 122, 17, 171, 219, 122, 17, 178, 54, 219, 239, 1, 155, 54, + 219, 239, 1, 192, 220, 54, 219, 239, 1, 214, 68, 54, 219, 239, 1, 197, + 168, 54, 219, 239, 1, 188, 54, 219, 239, 1, 170, 54, 219, 239, 1, 190, + 190, 54, 219, 239, 1, 199, 49, 54, 219, 239, 1, 173, 54, 219, 239, 1, + 168, 54, 219, 239, 1, 209, 228, 54, 219, 239, 1, 174, 54, 219, 239, 1, + 233, 109, 54, 219, 239, 1, 195, 188, 54, 219, 239, 1, 140, 54, 219, 239, + 1, 208, 96, 54, 219, 239, 1, 221, 215, 54, 219, 239, 1, 197, 157, 54, + 219, 239, 1, 180, 54, 219, 239, 1, 65, 54, 219, 239, 1, 68, 54, 219, 239, + 1, 234, 188, 54, 219, 239, 1, 234, 173, 54, 219, 239, 1, 66, 54, 219, + 239, 1, 211, 87, 54, 219, 239, 1, 74, 54, 219, 239, 1, 196, 152, 54, 219, + 239, 1, 71, 54, 219, 239, 1, 250, 161, 54, 219, 239, 1, 251, 236, 54, + 219, 239, 1, 198, 77, 54, 219, 239, 1, 198, 76, 54, 219, 239, 1, 198, 75, + 54, 219, 239, 1, 198, 74, 54, 219, 239, 1, 198, 73, 214, 80, 54, 218, + 219, 1, 137, 208, 96, 214, 80, 54, 218, 219, 1, 130, 208, 96, 214, 80, + 54, 218, 219, 1, 137, 155, 214, 80, 54, 218, 219, 1, 137, 192, 220, 214, + 80, 54, 218, 219, 1, 137, 214, 68, 214, 80, 54, 218, 219, 1, 130, 155, + 214, 80, 54, 218, 219, 1, 130, 192, 220, 214, 80, 54, 218, 219, 1, 130, + 214, 68, 214, 80, 54, 218, 219, 1, 137, 197, 168, 214, 80, 54, 218, 219, + 1, 137, 188, 214, 80, 54, 218, 219, 1, 137, 170, 214, 80, 54, 218, 219, + 1, 130, 197, 168, 214, 80, 54, 218, 219, 1, 130, 188, 214, 80, 54, 218, + 219, 1, 130, 170, 214, 80, 54, 218, 219, 1, 137, 190, 190, 214, 80, 54, + 218, 219, 1, 137, 199, 49, 214, 80, 54, 218, 219, 1, 137, 180, 214, 80, + 54, 218, 219, 1, 130, 190, 190, 214, 80, 54, 218, 219, 1, 130, 199, 49, + 214, 80, 54, 218, 219, 1, 130, 180, 214, 80, 54, 218, 219, 1, 137, 168, + 214, 80, 54, 218, 219, 1, 137, 209, 228, 214, 80, 54, 218, 219, 1, 137, + 174, 214, 80, 54, 218, 219, 1, 130, 168, 214, 80, 54, 218, 219, 1, 130, + 209, 228, 214, 80, 54, 218, 219, 1, 130, 174, 214, 80, 54, 218, 219, 1, + 137, 233, 109, 214, 80, 54, 218, 219, 1, 137, 195, 188, 214, 80, 54, 218, + 219, 1, 137, 173, 214, 80, 54, 218, 219, 1, 130, 233, 109, 214, 80, 54, + 218, 219, 1, 130, 195, 188, 214, 80, 54, 218, 219, 1, 130, 173, 214, 80, + 54, 218, 219, 1, 137, 140, 214, 80, 54, 218, 219, 1, 137, 238, 32, 214, + 80, 54, 218, 219, 1, 137, 249, 153, 214, 80, 54, 218, 219, 1, 130, 140, + 214, 80, 54, 218, 219, 1, 130, 238, 32, 214, 80, 54, 218, 219, 1, 130, + 249, 153, 214, 80, 54, 218, 219, 1, 137, 220, 181, 214, 80, 54, 218, 219, + 1, 137, 192, 185, 214, 80, 54, 218, 219, 1, 130, 220, 181, 214, 80, 54, + 218, 219, 1, 130, 192, 185, 214, 80, 54, 218, 219, 1, 137, 200, 251, 214, + 80, 54, 218, 219, 1, 130, 200, 251, 214, 80, 54, 218, 219, 18, 3, 18, + 203, 28, 214, 80, 54, 218, 219, 18, 3, 252, 206, 214, 80, 54, 218, 219, + 18, 3, 223, 199, 214, 80, 54, 218, 219, 18, 3, 66, 214, 80, 54, 218, 219, + 18, 3, 196, 30, 214, 80, 54, 218, 219, 18, 3, 71, 214, 80, 54, 218, 219, + 18, 3, 252, 25, 214, 80, 54, 218, 219, 18, 3, 74, 214, 80, 54, 218, 219, + 18, 3, 211, 182, 214, 80, 54, 218, 219, 18, 3, 196, 152, 214, 80, 54, + 218, 219, 18, 3, 250, 131, 214, 80, 54, 218, 219, 18, 3, 252, 160, 214, + 80, 54, 218, 219, 18, 3, 196, 21, 214, 80, 54, 218, 219, 18, 3, 210, 242, + 214, 80, 54, 218, 219, 18, 3, 211, 179, 214, 80, 54, 218, 219, 18, 3, + 196, 144, 214, 80, 54, 218, 219, 18, 3, 223, 44, 214, 80, 54, 218, 219, + 1, 53, 196, 12, 214, 80, 54, 218, 219, 1, 53, 214, 70, 214, 80, 54, 218, + 219, 1, 53, 215, 61, 214, 80, 54, 218, 219, 1, 53, 218, 168, 214, 80, 54, + 218, 219, 1, 53, 222, 152, 214, 80, 54, 218, 219, 1, 53, 238, 127, 214, + 80, 54, 218, 219, 1, 53, 250, 120, 214, 80, 54, 218, 219, 163, 217, 55, + 214, 80, 54, 218, 219, 163, 217, 54, 214, 80, 54, 218, 219, 17, 191, 77, + 214, 80, 54, 218, 219, 17, 107, 214, 80, 54, 218, 219, 17, 109, 214, 80, + 54, 218, 219, 17, 138, 214, 80, 54, 218, 219, 17, 134, 214, 80, 54, 218, + 219, 17, 149, 214, 80, 54, 218, 219, 17, 169, 214, 80, 54, 218, 219, 17, + 175, 214, 80, 54, 218, 219, 17, 171, 214, 80, 54, 218, 219, 17, 178, 214, + 80, 54, 218, 219, 128, 17, 107, 214, 80, 54, 218, 219, 3, 220, 107, 214, + 80, 54, 218, 219, 3, 220, 106, 95, 16, 210, 84, 95, 16, 215, 113, 221, + 58, 95, 16, 209, 146, 221, 58, 95, 16, 248, 241, 221, 58, 95, 16, 247, + 237, 221, 58, 95, 16, 208, 246, 221, 58, 95, 16, 208, 240, 221, 58, 95, + 16, 208, 238, 221, 58, 95, 16, 208, 244, 221, 58, 95, 16, 208, 242, 221, + 58, 95, 16, 237, 232, 221, 58, 95, 16, 237, 228, 221, 58, 95, 16, 237, + 227, 221, 58, 95, 16, 237, 230, 221, 58, 95, 16, 237, 229, 221, 58, 95, + 16, 237, 226, 221, 58, 95, 16, 197, 51, 95, 16, 215, 113, 206, 149, 95, + 16, 209, 146, 206, 149, 95, 16, 248, 241, 206, 149, 95, 16, 247, 237, + 206, 149, 95, 16, 208, 246, 206, 149, 95, 16, 208, 240, 206, 149, 95, 16, + 208, 238, 206, 149, 95, 16, 208, 244, 206, 149, 95, 16, 208, 242, 206, + 149, 95, 16, 237, 232, 206, 149, 95, 16, 237, 228, 206, 149, 95, 16, 237, + 227, 206, 149, 95, 16, 237, 230, 206, 149, 95, 16, 237, 229, 206, 149, + 95, 16, 237, 226, 206, 149, 248, 1, 1, 155, 248, 1, 1, 231, 240, 248, 1, + 1, 214, 68, 248, 1, 1, 214, 11, 248, 1, 1, 168, 248, 1, 1, 249, 153, 248, + 1, 1, 174, 248, 1, 1, 215, 166, 248, 1, 1, 190, 190, 248, 1, 1, 238, 32, + 248, 1, 1, 180, 248, 1, 1, 212, 244, 248, 1, 1, 247, 160, 248, 1, 1, 223, + 32, 248, 1, 1, 212, 101, 248, 1, 1, 212, 92, 248, 1, 1, 170, 248, 1, 1, + 165, 248, 1, 1, 173, 248, 1, 1, 195, 188, 248, 1, 1, 188, 248, 1, 1, 65, + 248, 1, 1, 140, 248, 1, 18, 3, 68, 248, 1, 18, 3, 66, 248, 1, 18, 3, 71, + 248, 1, 18, 3, 74, 248, 1, 18, 3, 252, 25, 248, 1, 210, 184, 248, 1, 234, + 95, 79, 205, 53, 54, 128, 1, 137, 155, 54, 128, 1, 137, 221, 215, 54, + 128, 1, 137, 220, 165, 54, 128, 1, 130, 155, 54, 128, 1, 130, 220, 165, + 54, 128, 1, 130, 221, 215, 54, 128, 1, 214, 68, 54, 128, 1, 137, 247, + 160, 54, 128, 1, 137, 247, 1, 54, 128, 1, 130, 247, 160, 54, 128, 1, 130, + 188, 54, 128, 1, 130, 247, 1, 54, 128, 1, 212, 101, 54, 128, 1, 207, 129, + 54, 128, 1, 137, 207, 127, 54, 128, 1, 238, 32, 54, 128, 1, 130, 207, + 127, 54, 128, 1, 207, 138, 54, 128, 1, 137, 190, 190, 54, 128, 1, 137, + 199, 49, 54, 128, 1, 130, 190, 190, 54, 128, 1, 130, 199, 49, 54, 128, 1, + 180, 54, 128, 1, 249, 153, 54, 128, 1, 137, 168, 54, 128, 1, 137, 209, + 228, 54, 128, 1, 137, 233, 109, 54, 128, 1, 130, 168, 54, 128, 1, 130, + 233, 109, 54, 128, 1, 130, 209, 228, 54, 128, 1, 174, 54, 128, 1, 130, + 170, 54, 128, 1, 137, 170, 54, 128, 1, 165, 54, 128, 1, 206, 57, 54, 128, + 1, 173, 54, 128, 1, 218, 218, 54, 128, 1, 193, 190, 54, 128, 1, 137, 203, + 165, 54, 128, 1, 137, 201, 175, 54, 128, 1, 137, 188, 54, 128, 1, 137, + 140, 54, 128, 1, 219, 73, 54, 128, 1, 65, 54, 128, 1, 130, 140, 54, 128, + 1, 68, 54, 128, 1, 223, 199, 54, 128, 1, 66, 54, 128, 1, 196, 30, 54, + 128, 1, 234, 188, 54, 128, 1, 211, 87, 54, 128, 1, 220, 107, 54, 128, 1, + 230, 206, 188, 54, 128, 120, 3, 216, 217, 165, 54, 128, 120, 3, 216, 217, + 173, 54, 128, 120, 3, 220, 126, 199, 190, 220, 96, 54, 128, 3, 217, 113, + 222, 84, 220, 96, 54, 128, 120, 3, 53, 214, 68, 54, 128, 120, 3, 130, + 168, 54, 128, 120, 3, 137, 207, 128, 211, 57, 130, 168, 54, 128, 120, 3, + 174, 54, 128, 120, 3, 249, 153, 54, 128, 120, 3, 188, 54, 128, 3, 205, + 172, 54, 128, 18, 3, 65, 54, 128, 18, 3, 217, 113, 205, 122, 54, 128, 18, + 3, 252, 206, 54, 128, 18, 3, 199, 200, 252, 206, 54, 128, 18, 3, 68, 54, + 128, 18, 3, 223, 199, 54, 128, 18, 3, 196, 152, 54, 128, 18, 3, 196, 29, + 54, 128, 18, 3, 66, 54, 128, 18, 3, 196, 30, 54, 128, 18, 3, 74, 54, 128, + 18, 3, 211, 183, 60, 54, 128, 18, 3, 210, 242, 54, 128, 18, 3, 71, 54, + 128, 18, 3, 252, 25, 54, 128, 18, 3, 211, 87, 54, 128, 18, 3, 251, 236, + 54, 128, 18, 3, 128, 251, 236, 54, 128, 18, 3, 211, 183, 58, 54, 128, 3, + 217, 113, 222, 83, 54, 128, 3, 198, 78, 54, 128, 3, 198, 77, 54, 128, 3, + 221, 171, 198, 76, 54, 128, 3, 221, 171, 198, 75, 54, 128, 3, 221, 171, + 198, 74, 54, 128, 3, 207, 186, 230, 90, 54, 128, 3, 217, 113, 205, 152, + 54, 128, 3, 221, 170, 222, 64, 54, 128, 33, 238, 198, 236, 140, 54, 128, + 228, 243, 17, 191, 77, 54, 128, 228, 243, 17, 107, 54, 128, 228, 243, 17, + 109, 54, 128, 228, 243, 17, 138, 54, 128, 228, 243, 17, 134, 54, 128, + 228, 243, 17, 149, 54, 128, 228, 243, 17, 169, 54, 128, 228, 243, 17, + 175, 54, 128, 228, 243, 17, 171, 54, 128, 228, 243, 17, 178, 54, 128, + 128, 17, 191, 77, 54, 128, 128, 17, 107, 54, 128, 128, 17, 109, 54, 128, + 128, 17, 138, 54, 128, 128, 17, 134, 54, 128, 128, 17, 149, 54, 128, 128, + 17, 169, 54, 128, 128, 17, 175, 54, 128, 128, 17, 171, 54, 128, 128, 17, + 178, 54, 128, 3, 193, 80, 54, 128, 3, 193, 79, 54, 128, 3, 205, 107, 54, + 128, 3, 221, 246, 54, 128, 3, 228, 170, 54, 128, 3, 236, 157, 54, 128, 3, + 207, 18, 206, 122, 207, 138, 54, 128, 3, 217, 113, 192, 109, 54, 128, 3, + 222, 120, 54, 128, 3, 222, 119, 54, 128, 3, 205, 117, 54, 128, 3, 205, + 116, 54, 128, 3, 230, 26, 54, 128, 3, 247, 157, 33, 235, 128, 243, 2, + 252, 60, 33, 237, 41, 33, 223, 139, 33, 235, 119, 57, 33, 197, 225, 236, + 140, 33, 192, 233, 60, 33, 193, 72, 219, 113, 60, 33, 211, 77, 87, 60, + 33, 55, 211, 77, 87, 60, 33, 156, 247, 23, 201, 28, 60, 33, 201, 14, 247, + 23, 201, 28, 60, 33, 210, 115, 58, 33, 55, 210, 115, 58, 33, 210, 115, + 60, 33, 210, 115, 210, 255, 33, 8, 2, 1, 193, 225, 60, 33, 8, 2, 1, 153, + 193, 225, 60, 33, 45, 210, 114, 93, 219, 224, 33, 50, 210, 114, 93, 183, + 33, 45, 210, 114, 248, 233, 219, 224, 33, 50, 210, 114, 248, 233, 183, + 33, 51, 248, 51, 58, 33, 31, 3, 58, 33, 223, 93, 55, 251, 15, 58, 33, + 108, 3, 58, 33, 55, 108, 3, 58, 33, 55, 108, 3, 60, 33, 197, 225, 252, + 47, 252, 60, 33, 8, 2, 1, 223, 115, 232, 51, 33, 8, 2, 1, 223, 115, 146, + 33, 8, 2, 1, 223, 115, 200, 43, 148, 3, 196, 123, 206, 244, 148, 3, 196, + 123, 247, 121, 148, 3, 247, 38, 148, 3, 200, 173, 148, 3, 248, 155, 148, + 1, 251, 214, 148, 1, 251, 215, 199, 123, 148, 1, 223, 194, 148, 1, 223, + 195, 199, 123, 148, 1, 196, 126, 148, 1, 196, 127, 199, 123, 148, 1, 207, + 186, 207, 51, 148, 1, 207, 186, 207, 52, 199, 123, 148, 1, 220, 126, 219, + 199, 148, 1, 220, 126, 219, 200, 199, 123, 148, 1, 234, 145, 148, 1, 251, + 233, 148, 1, 211, 123, 148, 1, 211, 124, 199, 123, 148, 1, 155, 148, 1, + 222, 142, 217, 116, 148, 1, 231, 240, 148, 1, 231, 241, 230, 241, 148, 1, + 214, 68, 148, 1, 247, 160, 148, 1, 247, 161, 220, 112, 148, 1, 223, 32, + 148, 1, 223, 33, 223, 0, 148, 1, 212, 101, 148, 1, 199, 252, 220, 2, 148, + 1, 199, 252, 215, 108, 217, 116, 148, 1, 238, 33, 215, 108, 251, 162, + 148, 1, 238, 33, 215, 108, 217, 116, 148, 1, 215, 7, 207, 141, 148, 1, + 190, 190, 148, 1, 199, 252, 199, 158, 148, 1, 238, 32, 148, 1, 238, 33, + 217, 138, 148, 1, 180, 148, 1, 168, 148, 1, 210, 221, 222, 76, 148, 1, + 249, 153, 148, 1, 249, 154, 222, 2, 148, 1, 174, 148, 1, 170, 148, 1, + 165, 148, 1, 173, 148, 1, 193, 190, 148, 1, 205, 207, 205, 184, 148, 1, + 205, 207, 205, 129, 148, 1, 188, 148, 1, 140, 148, 3, 207, 41, 148, 18, + 3, 199, 123, 148, 18, 3, 196, 122, 148, 18, 3, 196, 123, 205, 125, 148, + 18, 3, 200, 208, 148, 18, 3, 200, 209, 223, 185, 148, 18, 3, 207, 186, + 207, 51, 148, 18, 3, 207, 186, 207, 52, 199, 123, 148, 18, 3, 220, 126, + 219, 199, 148, 18, 3, 220, 126, 219, 200, 199, 123, 148, 18, 3, 199, 201, + 148, 18, 3, 199, 202, 207, 51, 148, 18, 3, 199, 202, 199, 123, 148, 18, + 3, 199, 202, 207, 52, 199, 123, 148, 18, 3, 210, 16, 148, 18, 3, 210, 17, + 199, 123, 148, 252, 37, 252, 36, 148, 1, 222, 107, 205, 124, 148, 1, 221, + 177, 205, 124, 148, 1, 196, 235, 205, 124, 148, 1, 234, 182, 205, 124, + 148, 1, 195, 154, 205, 124, 148, 1, 191, 109, 205, 124, 148, 1, 250, 185, + 205, 124, 148, 1, 251, 14, 222, 202, 148, 17, 191, 77, 148, 17, 107, 148, + 17, 109, 148, 17, 138, 148, 17, 134, 148, 17, 149, 148, 17, 169, 148, 17, + 175, 148, 17, 171, 148, 17, 178, 148, 210, 145, 148, 210, 175, 148, 193, + 64, 148, 247, 94, 210, 168, 148, 247, 94, 202, 190, 148, 247, 94, 210, + 112, 148, 210, 174, 148, 37, 16, 236, 148, 148, 37, 16, 237, 102, 148, + 37, 16, 235, 71, 148, 37, 16, 237, 236, 148, 37, 16, 237, 237, 200, 173, + 148, 37, 16, 236, 242, 148, 37, 16, 238, 24, 148, 37, 16, 237, 77, 148, + 37, 16, 238, 6, 148, 37, 16, 237, 237, 231, 159, 148, 37, 16, 33, 199, + 116, 148, 37, 16, 33, 234, 92, 148, 37, 16, 33, 221, 253, 148, 37, 16, + 33, 221, 255, 148, 37, 16, 33, 223, 5, 148, 37, 16, 33, 221, 254, 4, 223, + 5, 148, 37, 16, 33, 222, 0, 4, 223, 5, 148, 37, 16, 33, 248, 226, 148, + 37, 16, 33, 230, 247, 148, 37, 16, 206, 206, 211, 77, 235, 82, 148, 37, + 16, 206, 206, 211, 77, 238, 22, 148, 37, 16, 206, 206, 242, 219, 197, 80, + 148, 37, 16, 206, 206, 242, 219, 199, 211, 148, 37, 16, 219, 222, 211, + 77, 210, 160, 148, 37, 16, 219, 222, 211, 77, 208, 149, 148, 37, 16, 219, + 222, 242, 219, 209, 104, 148, 37, 16, 219, 222, 242, 219, 209, 86, 148, + 37, 16, 219, 222, 211, 77, 209, 132, 148, 210, 146, 220, 19, 148, 210, + 176, 220, 19, 200, 197, 3, 210, 142, 200, 197, 3, 210, 156, 200, 197, 3, + 210, 152, 200, 197, 1, 65, 200, 197, 1, 68, 200, 197, 1, 66, 200, 197, 1, + 252, 25, 200, 197, 1, 74, 200, 197, 1, 71, 200, 197, 1, 233, 242, 200, + 197, 1, 155, 200, 197, 1, 208, 96, 200, 197, 1, 231, 240, 200, 197, 1, + 214, 68, 200, 197, 1, 247, 160, 200, 197, 1, 223, 32, 200, 197, 1, 191, + 123, 200, 197, 1, 212, 101, 200, 197, 1, 190, 190, 200, 197, 1, 238, 32, + 200, 197, 1, 180, 200, 197, 1, 168, 200, 197, 1, 233, 109, 200, 197, 1, + 195, 188, 200, 197, 1, 249, 153, 200, 197, 1, 174, 200, 197, 1, 170, 200, + 197, 1, 165, 200, 197, 1, 173, 200, 197, 1, 193, 190, 200, 197, 1, 188, + 200, 197, 1, 192, 220, 200, 197, 1, 140, 200, 197, 120, 3, 210, 172, 200, + 197, 120, 3, 210, 144, 200, 197, 120, 3, 210, 141, 200, 197, 18, 3, 210, + 159, 200, 197, 18, 3, 210, 140, 200, 197, 18, 3, 210, 165, 200, 197, 18, + 3, 210, 151, 200, 197, 18, 3, 210, 173, 200, 197, 18, 3, 210, 161, 200, + 197, 3, 210, 177, 200, 197, 3, 195, 40, 200, 197, 120, 3, 210, 100, 174, + 200, 197, 120, 3, 210, 100, 193, 190, 200, 197, 1, 221, 215, 200, 197, 1, + 200, 126, 200, 197, 17, 191, 77, 200, 197, 17, 107, 200, 197, 17, 109, + 200, 197, 17, 138, 200, 197, 17, 134, 200, 197, 17, 149, 200, 197, 17, + 169, 200, 197, 17, 175, 200, 197, 17, 171, 200, 197, 17, 178, 200, 197, + 250, 145, 200, 197, 1, 207, 21, 200, 197, 1, 219, 172, 200, 197, 1, 248, + 203, 200, 197, 1, 53, 222, 152, 200, 197, 1, 53, 218, 168, 249, 63, 1, + 65, 249, 63, 1, 202, 182, 65, 249, 63, 1, 140, 249, 63, 1, 202, 182, 140, + 249, 63, 1, 217, 85, 140, 249, 63, 1, 249, 153, 249, 63, 1, 222, 61, 249, + 153, 249, 63, 1, 168, 249, 63, 1, 202, 182, 168, 249, 63, 1, 180, 249, + 63, 1, 217, 85, 180, 249, 63, 1, 193, 190, 249, 63, 1, 202, 182, 193, + 190, 249, 63, 1, 210, 193, 193, 190, 249, 63, 1, 231, 240, 249, 63, 1, + 202, 182, 231, 240, 249, 63, 1, 223, 32, 249, 63, 1, 238, 32, 249, 63, 1, + 165, 249, 63, 1, 202, 182, 165, 249, 63, 1, 174, 249, 63, 1, 202, 182, + 174, 249, 63, 1, 202, 0, 190, 190, 249, 63, 1, 213, 16, 190, 190, 249, + 63, 1, 188, 249, 63, 1, 202, 182, 188, 249, 63, 1, 217, 85, 188, 249, 63, + 1, 170, 249, 63, 1, 202, 182, 170, 249, 63, 1, 214, 68, 249, 63, 1, 173, + 249, 63, 1, 202, 182, 173, 249, 63, 1, 212, 101, 249, 63, 1, 247, 160, + 249, 63, 1, 214, 162, 249, 63, 1, 217, 11, 249, 63, 1, 68, 249, 63, 1, + 66, 249, 63, 3, 198, 82, 249, 63, 18, 3, 71, 249, 63, 18, 3, 210, 193, + 71, 249, 63, 18, 3, 234, 188, 249, 63, 18, 3, 68, 249, 63, 18, 3, 222, + 61, 68, 249, 63, 18, 3, 74, 249, 63, 18, 3, 222, 61, 74, 249, 63, 18, 3, + 66, 249, 63, 18, 3, 126, 40, 202, 182, 188, 249, 63, 120, 3, 214, 70, + 249, 63, 120, 3, 230, 116, 249, 63, 210, 154, 249, 63, 210, 150, 249, 63, + 16, 248, 165, 215, 7, 216, 163, 249, 63, 16, 248, 165, 209, 138, 249, 63, + 16, 248, 165, 222, 179, 249, 63, 16, 248, 165, 210, 154, 219, 183, 1, + 155, 219, 183, 1, 221, 94, 219, 183, 1, 221, 215, 219, 183, 1, 231, 240, + 219, 183, 1, 231, 19, 219, 183, 1, 214, 68, 219, 183, 1, 247, 160, 219, + 183, 1, 247, 1, 219, 183, 1, 223, 32, 219, 183, 1, 212, 101, 219, 183, 1, + 190, 190, 219, 183, 1, 199, 49, 219, 183, 1, 238, 32, 219, 183, 1, 180, + 219, 183, 1, 168, 219, 183, 1, 209, 110, 219, 183, 1, 209, 228, 219, 183, + 1, 233, 109, 219, 183, 1, 232, 219, 219, 183, 1, 249, 153, 219, 183, 1, + 248, 140, 219, 183, 1, 174, 219, 183, 1, 216, 19, 219, 183, 1, 197, 168, + 219, 183, 1, 197, 157, 219, 183, 1, 235, 35, 219, 183, 1, 170, 219, 183, + 1, 165, 219, 183, 1, 173, 219, 183, 1, 140, 219, 183, 1, 229, 111, 219, + 183, 1, 195, 188, 219, 183, 1, 188, 219, 183, 1, 203, 165, 219, 183, 1, + 193, 190, 219, 183, 1, 65, 219, 183, 200, 239, 1, 170, 219, 183, 200, + 239, 1, 165, 219, 183, 18, 3, 252, 206, 219, 183, 18, 3, 68, 219, 183, + 18, 3, 74, 219, 183, 18, 3, 211, 87, 219, 183, 18, 3, 66, 219, 183, 18, + 3, 196, 30, 219, 183, 18, 3, 71, 219, 183, 120, 3, 222, 152, 219, 183, + 120, 3, 218, 168, 219, 183, 120, 3, 172, 219, 183, 120, 3, 215, 61, 219, + 183, 120, 3, 210, 236, 219, 183, 120, 3, 146, 219, 183, 120, 3, 200, 43, + 219, 183, 120, 3, 212, 73, 219, 183, 120, 3, 222, 83, 219, 183, 3, 207, + 139, 219, 183, 3, 212, 141, 219, 183, 208, 152, 199, 247, 219, 183, 208, + 152, 212, 85, 198, 196, 199, 247, 219, 183, 208, 152, 247, 10, 219, 183, + 208, 152, 197, 149, 247, 10, 219, 183, 208, 152, 197, 148, 219, 183, 17, + 191, 77, 219, 183, 17, 107, 219, 183, 17, 109, 219, 183, 17, 138, 219, + 183, 17, 134, 219, 183, 17, 149, 219, 183, 17, 169, 219, 183, 17, 175, + 219, 183, 17, 171, 219, 183, 17, 178, 219, 183, 1, 197, 132, 219, 183, 1, + 197, 120, 219, 183, 1, 237, 191, 211, 121, 243, 88, 17, 191, 77, 211, + 121, 243, 88, 17, 107, 211, 121, 243, 88, 17, 109, 211, 121, 243, 88, 17, + 138, 211, 121, 243, 88, 17, 134, 211, 121, 243, 88, 17, 149, 211, 121, + 243, 88, 17, 169, 211, 121, 243, 88, 17, 175, 211, 121, 243, 88, 17, 171, + 211, 121, 243, 88, 17, 178, 211, 121, 243, 88, 1, 173, 211, 121, 243, 88, + 1, 250, 182, 211, 121, 243, 88, 1, 251, 253, 211, 121, 243, 88, 1, 251, + 122, 211, 121, 243, 88, 1, 251, 207, 211, 121, 243, 88, 1, 220, 125, 211, + 121, 243, 88, 1, 252, 168, 211, 121, 243, 88, 1, 252, 169, 211, 121, 243, + 88, 1, 252, 167, 211, 121, 243, 88, 1, 252, 161, 211, 121, 243, 88, 1, + 219, 146, 211, 121, 243, 88, 1, 223, 68, 211, 121, 243, 88, 1, 223, 200, + 211, 121, 243, 88, 1, 223, 90, 211, 121, 243, 88, 1, 223, 77, 211, 121, + 243, 88, 1, 218, 225, 211, 121, 243, 88, 1, 196, 160, 211, 121, 243, 88, + 1, 196, 158, 211, 121, 243, 88, 1, 196, 83, 211, 121, 243, 88, 1, 196, + 21, 211, 121, 243, 88, 1, 219, 238, 211, 121, 243, 88, 1, 234, 56, 211, + 121, 243, 88, 1, 234, 191, 211, 121, 243, 88, 1, 234, 103, 211, 121, 243, + 88, 1, 234, 26, 211, 121, 243, 88, 1, 219, 43, 211, 121, 243, 88, 1, 211, + 24, 211, 121, 243, 88, 1, 211, 178, 211, 121, 243, 88, 1, 211, 9, 211, + 121, 243, 88, 1, 211, 136, 211, 121, 243, 88, 215, 156, 197, 97, 211, + 121, 243, 88, 231, 235, 197, 98, 211, 121, 243, 88, 215, 150, 197, 98, + 211, 121, 243, 88, 207, 66, 211, 121, 243, 88, 209, 226, 211, 121, 243, + 88, 251, 244, 211, 121, 243, 88, 208, 152, 215, 146, 211, 121, 243, 88, + 208, 152, 55, 215, 146, 38, 2, 1, 206, 113, 195, 153, 38, 2, 1, 219, 12, + 237, 146, 38, 2, 1, 214, 215, 74, 38, 2, 1, 193, 78, 234, 22, 38, 2, 1, + 199, 200, 199, 145, 38, 2, 1, 198, 221, 199, 145, 38, 2, 1, 199, 200, + 230, 17, 56, 38, 2, 1, 199, 200, 192, 95, 38, 2, 1, 196, 108, 196, 128, + 101, 215, 157, 6, 1, 251, 132, 101, 215, 157, 6, 1, 249, 101, 101, 215, + 157, 6, 1, 231, 210, 101, 215, 157, 6, 1, 236, 150, 101, 215, 157, 6, 1, + 234, 103, 101, 215, 157, 6, 1, 195, 49, 101, 215, 157, 6, 1, 191, 80, + 101, 215, 157, 6, 1, 199, 193, 101, 215, 157, 6, 1, 223, 162, 101, 215, + 157, 6, 1, 222, 87, 101, 215, 157, 6, 1, 220, 7, 101, 215, 157, 6, 1, + 217, 90, 101, 215, 157, 6, 1, 214, 216, 101, 215, 157, 6, 1, 211, 104, + 101, 215, 157, 6, 1, 210, 131, 101, 215, 157, 6, 1, 191, 67, 101, 215, + 157, 6, 1, 207, 163, 101, 215, 157, 6, 1, 205, 142, 101, 215, 157, 6, 1, + 199, 179, 101, 215, 157, 6, 1, 196, 113, 101, 215, 157, 6, 1, 209, 220, + 101, 215, 157, 6, 1, 221, 200, 101, 215, 157, 6, 1, 231, 82, 101, 215, + 157, 6, 1, 208, 81, 101, 215, 157, 6, 1, 203, 69, 101, 215, 157, 6, 1, + 243, 81, 101, 215, 157, 6, 1, 247, 128, 101, 215, 157, 6, 1, 222, 234, + 101, 215, 157, 6, 1, 243, 18, 101, 215, 157, 6, 1, 246, 241, 101, 215, + 157, 6, 1, 192, 218, 101, 215, 157, 6, 1, 222, 249, 101, 215, 157, 6, 1, + 230, 87, 101, 215, 157, 6, 1, 229, 245, 101, 215, 157, 6, 1, 229, 145, + 101, 215, 157, 6, 1, 193, 125, 101, 215, 157, 6, 1, 230, 19, 101, 215, + 157, 6, 1, 229, 11, 101, 215, 157, 6, 1, 233, 23, 101, 215, 157, 6, 1, + 192, 14, 101, 215, 157, 6, 1, 234, 123, 101, 215, 157, 6, 1, 153, 231, + 210, 101, 215, 157, 6, 1, 251, 230, 101, 215, 157, 6, 1, 252, 14, 101, + 215, 157, 6, 1, 230, 17, 56, 101, 215, 157, 6, 1, 220, 116, 56, 200, 197, + 208, 152, 248, 165, 200, 166, 200, 197, 208, 152, 248, 165, 210, 155, + 200, 197, 208, 152, 248, 165, 208, 139, 200, 197, 208, 152, 248, 165, + 247, 145, 200, 197, 208, 152, 248, 165, 219, 173, 205, 121, 200, 197, + 208, 152, 248, 165, 222, 142, 205, 121, 200, 197, 208, 152, 248, 165, + 238, 33, 205, 121, 200, 197, 208, 152, 248, 165, 249, 154, 205, 121, 195, + 150, 163, 222, 57, 195, 150, 163, 203, 130, 195, 150, 163, 208, 225, 195, + 150, 3, 213, 187, 195, 150, 3, 192, 117, 216, 82, 200, 156, 195, 150, + 163, 192, 117, 251, 249, 223, 149, 200, 156, 195, 150, 163, 192, 117, + 223, 149, 200, 156, 195, 150, 163, 192, 117, 222, 45, 223, 149, 200, 156, + 195, 150, 163, 247, 122, 60, 195, 150, 163, 192, 117, 222, 45, 223, 149, + 200, 157, 205, 88, 195, 150, 163, 55, 200, 156, 195, 150, 163, 197, 225, + 200, 156, 195, 150, 163, 222, 45, 251, 73, 195, 150, 163, 75, 60, 195, + 150, 163, 105, 185, 60, 195, 150, 163, 115, 185, 60, 195, 150, 163, 206, + 196, 222, 56, 223, 149, 200, 156, 195, 150, 163, 250, 179, 223, 149, 200, + 156, 195, 150, 3, 195, 36, 200, 156, 195, 150, 3, 195, 36, 196, 154, 195, + 150, 3, 207, 18, 195, 36, 196, 154, 195, 150, 3, 195, 36, 251, 73, 195, + 150, 3, 207, 18, 195, 36, 251, 73, 195, 150, 3, 195, 36, 196, 155, 4, + 199, 215, 195, 150, 3, 195, 36, 251, 74, 4, 199, 215, 195, 150, 3, 251, + 72, 251, 88, 195, 150, 3, 251, 72, 249, 120, 195, 150, 3, 251, 72, 195, + 178, 195, 150, 3, 251, 72, 195, 179, 4, 199, 215, 195, 150, 3, 198, 126, + 195, 150, 3, 229, 180, 179, 251, 71, 195, 150, 3, 179, 251, 71, 195, 150, + 3, 206, 70, 179, 251, 71, 195, 150, 3, 251, 72, 196, 162, 215, 136, 195, + 150, 3, 251, 10, 195, 150, 3, 206, 122, 251, 10, 195, 150, 163, 247, 122, + 58, 195, 150, 3, 222, 237, 195, 150, 3, 196, 75, 195, 150, 3, 250, 177, + 195, 150, 163, 206, 189, 58, 195, 150, 163, 55, 206, 189, 58, 195, 150, + 3, 55, 251, 72, 251, 88, 8, 1, 2, 6, 65, 8, 1, 2, 6, 252, 25, 8, 2, 1, + 153, 252, 25, 8, 1, 2, 6, 249, 82, 250, 120, 8, 1, 2, 6, 247, 193, 8, 1, + 2, 6, 238, 127, 8, 1, 2, 6, 233, 248, 8, 1, 2, 6, 71, 8, 2, 1, 153, 211, + 77, 71, 8, 2, 1, 153, 68, 8, 1, 2, 6, 223, 35, 8, 1, 2, 6, 222, 152, 8, + 1, 2, 6, 220, 143, 4, 106, 8, 1, 2, 6, 218, 168, 8, 1, 2, 6, 207, 18, + 215, 61, 8, 1, 2, 6, 74, 8, 1, 2, 6, 211, 77, 74, 8, 2, 1, 202, 206, 74, + 8, 2, 1, 202, 206, 211, 77, 74, 8, 2, 1, 202, 206, 187, 4, 106, 8, 2, 1, + 153, 211, 151, 8, 1, 2, 6, 211, 19, 8, 2, 1, 198, 54, 132, 74, 8, 2, 1, + 248, 77, 132, 74, 8, 1, 2, 6, 210, 236, 8, 1, 2, 6, 207, 18, 146, 8, 1, + 2, 6, 153, 146, 8, 1, 2, 6, 200, 43, 8, 1, 2, 6, 66, 8, 2, 1, 202, 206, + 66, 8, 2, 1, 202, 206, 237, 40, 66, 8, 2, 1, 202, 206, 153, 218, 168, 8, + 1, 2, 6, 196, 12, 8, 1, 2, 6, 193, 224, 8, 1, 2, 6, 191, 166, 8, 1, 2, 6, + 233, 178, 8, 1, 195, 20, 220, 8, 201, 216, 8, 1, 251, 230, 35, 1, 2, 6, + 231, 211, 35, 1, 2, 6, 220, 31, 35, 1, 2, 6, 209, 185, 35, 1, 2, 6, 207, + 3, 35, 1, 2, 6, 208, 176, 38, 1, 2, 6, 234, 140, 52, 1, 6, 65, 52, 1, 6, + 252, 25, 52, 1, 6, 250, 120, 52, 1, 6, 249, 82, 250, 120, 52, 1, 6, 238, + 127, 52, 1, 6, 71, 52, 1, 6, 207, 18, 71, 52, 1, 6, 232, 51, 52, 1, 6, + 230, 116, 52, 1, 6, 68, 52, 1, 6, 223, 35, 52, 1, 6, 222, 152, 52, 1, 6, + 172, 52, 1, 6, 218, 168, 52, 1, 6, 215, 61, 52, 1, 6, 207, 18, 215, 61, + 52, 1, 6, 74, 52, 1, 6, 211, 19, 52, 1, 6, 210, 236, 52, 1, 6, 146, 52, + 1, 6, 200, 43, 52, 1, 6, 66, 52, 1, 6, 193, 224, 52, 1, 2, 65, 52, 1, 2, + 153, 65, 52, 1, 2, 251, 160, 52, 1, 2, 153, 252, 25, 52, 1, 2, 250, 120, + 52, 1, 2, 238, 127, 52, 1, 2, 71, 52, 1, 2, 205, 86, 52, 1, 2, 211, 77, + 71, 52, 1, 2, 153, 211, 77, 71, 52, 1, 2, 232, 51, 52, 1, 2, 153, 68, 52, + 1, 2, 222, 152, 52, 1, 2, 218, 168, 52, 1, 2, 234, 88, 52, 1, 2, 74, 52, + 1, 2, 211, 77, 74, 52, 1, 2, 198, 54, 132, 74, 52, 1, 2, 248, 77, 132, + 74, 52, 1, 2, 210, 236, 52, 1, 2, 200, 43, 52, 1, 2, 66, 52, 1, 2, 202, + 206, 66, 52, 1, 2, 153, 218, 168, 52, 1, 2, 196, 12, 52, 1, 2, 251, 230, + 52, 1, 2, 248, 212, 52, 1, 2, 35, 231, 211, 52, 1, 2, 237, 106, 52, 1, 2, + 35, 209, 211, 52, 1, 2, 243, 95, 8, 200, 230, 2, 1, 68, 8, 200, 230, 2, + 1, 146, 8, 200, 230, 2, 1, 66, 8, 200, 230, 2, 1, 196, 12, 35, 200, 230, + 2, 1, 248, 212, 35, 200, 230, 2, 1, 231, 211, 35, 200, 230, 2, 1, 207, 3, + 35, 200, 230, 2, 1, 209, 211, 35, 200, 230, 2, 1, 243, 95, 8, 2, 1, 196, + 152, 8, 2, 1, 78, 4, 82, 198, 152, 8, 2, 1, 238, 128, 4, 82, 198, 152, 8, + 2, 1, 233, 176, 4, 82, 198, 152, 8, 2, 1, 218, 169, 4, 82, 198, 152, 8, + 2, 1, 215, 62, 4, 82, 198, 152, 8, 2, 1, 210, 237, 4, 82, 198, 152, 8, 2, + 1, 207, 222, 4, 82, 198, 152, 8, 2, 1, 207, 222, 4, 232, 234, 23, 82, + 198, 152, 8, 2, 1, 206, 9, 4, 82, 198, 152, 8, 2, 1, 200, 44, 4, 82, 198, + 152, 8, 2, 1, 191, 167, 4, 82, 198, 152, 8, 2, 1, 153, 232, 51, 52, 1, + 38, 234, 103, 8, 2, 1, 223, 115, 232, 51, 8, 2, 1, 199, 52, 4, 201, 32, + 8, 2, 6, 1, 228, 74, 4, 106, 8, 2, 1, 223, 84, 4, 106, 8, 2, 1, 210, 237, + 4, 106, 8, 2, 6, 1, 126, 4, 106, 8, 2, 1, 196, 71, 4, 106, 8, 2, 1, 78, + 4, 210, 192, 102, 8, 2, 1, 238, 128, 4, 210, 192, 102, 8, 2, 1, 233, 176, + 4, 210, 192, 102, 8, 2, 1, 232, 52, 4, 210, 192, 102, 8, 2, 1, 222, 153, + 4, 210, 192, 102, 8, 2, 1, 220, 143, 4, 210, 192, 102, 8, 2, 1, 218, 169, + 4, 210, 192, 102, 8, 2, 1, 215, 62, 4, 210, 192, 102, 8, 2, 1, 210, 237, + 4, 210, 192, 102, 8, 2, 1, 207, 222, 4, 210, 192, 102, 8, 2, 1, 206, 9, + 4, 210, 192, 102, 8, 2, 1, 234, 13, 4, 210, 192, 102, 8, 2, 1, 196, 13, + 4, 210, 192, 102, 8, 2, 1, 192, 236, 4, 210, 192, 102, 8, 2, 1, 191, 167, + 4, 210, 192, 102, 8, 2, 1, 42, 4, 207, 24, 102, 8, 2, 1, 251, 161, 4, + 207, 24, 102, 8, 2, 1, 238, 128, 4, 228, 251, 23, 199, 215, 8, 2, 1, 235, + 15, 4, 207, 24, 102, 8, 2, 1, 211, 77, 235, 15, 4, 207, 24, 102, 8, 2, 1, + 207, 18, 211, 77, 235, 15, 4, 207, 24, 102, 8, 2, 1, 205, 87, 4, 207, 24, + 102, 8, 2, 1, 228, 74, 4, 207, 24, 102, 8, 2, 1, 211, 77, 187, 4, 207, + 24, 102, 8, 2, 1, 234, 13, 4, 207, 24, 102, 8, 2, 1, 126, 4, 207, 24, + 102, 8, 2, 1, 233, 179, 4, 207, 24, 102, 52, 1, 2, 153, 251, 160, 52, 1, + 2, 247, 193, 52, 1, 2, 247, 194, 4, 238, 175, 52, 1, 2, 233, 248, 52, 1, + 2, 207, 18, 211, 77, 71, 52, 1, 2, 233, 175, 52, 1, 2, 236, 139, 223, 36, + 4, 106, 52, 1, 2, 27, 232, 51, 52, 1, 2, 153, 230, 116, 52, 1, 2, 228, + 74, 4, 106, 52, 1, 2, 223, 83, 52, 1, 2, 6, 68, 52, 1, 2, 6, 228, 74, 4, + 106, 52, 1, 2, 223, 36, 4, 238, 212, 52, 1, 2, 220, 143, 4, 207, 24, 102, + 52, 1, 2, 220, 143, 4, 210, 192, 102, 52, 1, 2, 6, 172, 52, 1, 2, 218, + 169, 4, 102, 52, 1, 2, 153, 218, 169, 4, 179, 219, 212, 52, 1, 2, 215, + 62, 4, 45, 102, 52, 1, 2, 215, 62, 4, 207, 24, 102, 52, 1, 2, 6, 215, 61, + 52, 1, 2, 249, 82, 74, 52, 1, 2, 209, 211, 52, 1, 2, 206, 9, 4, 102, 52, + 1, 2, 234, 12, 52, 1, 2, 200, 44, 4, 210, 192, 102, 52, 1, 2, 126, 164, + 52, 1, 2, 196, 70, 52, 1, 2, 6, 66, 52, 1, 2, 196, 13, 4, 102, 52, 1, 2, + 153, 196, 12, 52, 1, 2, 191, 166, 52, 1, 2, 191, 167, 4, 207, 24, 102, + 52, 1, 2, 191, 167, 4, 238, 175, 52, 1, 2, 233, 178, 52, 1, 2, 199, 15, + 33, 235, 138, 230, 211, 252, 60, 33, 235, 138, 252, 47, 252, 60, 33, 202, + 59, 60, 33, 200, 164, 77, 33, 217, 145, 33, 230, 208, 33, 217, 143, 33, + 252, 44, 33, 230, 209, 33, 252, 45, 33, 8, 2, 1, 207, 222, 60, 33, 248, + 35, 33, 217, 144, 33, 55, 243, 2, 58, 33, 211, 139, 58, 33, 191, 21, 60, + 33, 223, 69, 60, 33, 196, 63, 58, 33, 196, 46, 58, 33, 8, 2, 1, 232, 203, + 211, 77, 42, 58, 33, 8, 2, 1, 252, 25, 33, 8, 2, 1, 251, 68, 33, 8, 2, 1, + 250, 146, 33, 8, 2, 1, 247, 194, 247, 35, 33, 8, 2, 1, 223, 115, 238, + 127, 33, 8, 2, 1, 233, 248, 33, 8, 2, 1, 232, 51, 33, 8, 1, 2, 6, 232, + 51, 33, 8, 2, 1, 222, 152, 33, 8, 2, 1, 172, 33, 8, 1, 2, 6, 172, 33, 8, + 1, 2, 6, 218, 168, 33, 8, 2, 1, 215, 61, 33, 8, 1, 2, 6, 215, 61, 33, 8, + 1, 2, 6, 146, 33, 8, 2, 1, 207, 222, 206, 116, 33, 8, 2, 1, 206, 8, 33, + 8, 2, 1, 179, 206, 8, 33, 8, 2, 1, 191, 166, 33, 8, 2, 1, 251, 160, 33, + 8, 2, 1, 250, 120, 33, 8, 2, 1, 248, 212, 33, 8, 2, 1, 205, 86, 33, 8, 2, + 1, 233, 175, 33, 8, 2, 1, 220, 143, 4, 55, 82, 198, 152, 33, 8, 2, 1, + 187, 4, 156, 247, 23, 106, 33, 8, 2, 1, 210, 236, 33, 8, 2, 1, 234, 12, + 33, 8, 2, 1, 126, 4, 156, 247, 23, 106, 33, 8, 2, 1, 193, 224, 33, 8, 2, + 1, 42, 4, 237, 42, 33, 8, 2, 1, 187, 4, 237, 42, 33, 8, 2, 1, 126, 4, + 237, 42, 33, 133, 199, 229, 58, 33, 222, 36, 93, 183, 33, 222, 36, 93, + 219, 224, 33, 75, 93, 219, 224, 33, 193, 78, 223, 93, 248, 29, 60, 33, + 75, 248, 233, 219, 224, 33, 237, 115, 77, 33, 55, 223, 93, 248, 37, 60, + 33, 251, 165, 234, 45, 119, 60, 33, 45, 250, 236, 58, 33, 50, 250, 236, + 23, 144, 250, 236, 60, 8, 6, 1, 42, 4, 206, 189, 60, 8, 2, 1, 42, 4, 206, + 189, 60, 8, 6, 1, 78, 4, 75, 58, 8, 2, 1, 78, 4, 75, 58, 8, 6, 1, 78, 4, + 75, 60, 8, 2, 1, 78, 4, 75, 60, 8, 6, 1, 78, 4, 219, 113, 60, 8, 2, 1, + 78, 4, 219, 113, 60, 8, 6, 1, 247, 194, 4, 247, 36, 23, 252, 46, 8, 2, 1, + 247, 194, 4, 247, 36, 23, 252, 46, 8, 6, 1, 238, 128, 4, 75, 58, 8, 2, 1, + 238, 128, 4, 75, 58, 8, 6, 1, 238, 128, 4, 75, 60, 8, 2, 1, 238, 128, 4, + 75, 60, 8, 6, 1, 238, 128, 4, 219, 113, 60, 8, 2, 1, 238, 128, 4, 219, + 113, 60, 8, 6, 1, 238, 128, 4, 247, 35, 8, 2, 1, 238, 128, 4, 247, 35, 8, + 6, 1, 238, 128, 4, 243, 2, 60, 8, 2, 1, 238, 128, 4, 243, 2, 60, 8, 6, 1, + 235, 15, 4, 217, 147, 23, 230, 210, 8, 2, 1, 235, 15, 4, 217, 147, 23, + 230, 210, 8, 6, 1, 235, 15, 4, 217, 147, 23, 252, 46, 8, 2, 1, 235, 15, + 4, 217, 147, 23, 252, 46, 8, 6, 1, 235, 15, 4, 243, 2, 60, 8, 2, 1, 235, + 15, 4, 243, 2, 60, 8, 6, 1, 235, 15, 4, 198, 153, 60, 8, 2, 1, 235, 15, + 4, 198, 153, 60, 8, 6, 1, 235, 15, 4, 247, 36, 23, 248, 36, 8, 2, 1, 235, + 15, 4, 247, 36, 23, 248, 36, 8, 6, 1, 233, 176, 4, 75, 58, 8, 2, 1, 233, + 176, 4, 75, 58, 8, 6, 1, 232, 52, 4, 217, 146, 8, 2, 1, 232, 52, 4, 217, + 146, 8, 6, 1, 230, 117, 4, 75, 58, 8, 2, 1, 230, 117, 4, 75, 58, 8, 6, 1, + 230, 117, 4, 75, 60, 8, 2, 1, 230, 117, 4, 75, 60, 8, 6, 1, 230, 117, 4, + 237, 42, 8, 2, 1, 230, 117, 4, 237, 42, 8, 6, 1, 230, 117, 4, 247, 35, 8, + 2, 1, 230, 117, 4, 247, 35, 8, 6, 1, 230, 117, 4, 248, 37, 60, 8, 2, 1, + 230, 117, 4, 248, 37, 60, 8, 6, 1, 228, 74, 4, 198, 153, 60, 8, 2, 1, + 228, 74, 4, 198, 153, 60, 8, 6, 1, 228, 74, 4, 237, 43, 23, 252, 46, 8, + 2, 1, 228, 74, 4, 237, 43, 23, 252, 46, 8, 6, 1, 222, 153, 4, 252, 46, 8, + 2, 1, 222, 153, 4, 252, 46, 8, 6, 1, 222, 153, 4, 75, 60, 8, 2, 1, 222, + 153, 4, 75, 60, 8, 6, 1, 222, 153, 4, 219, 113, 60, 8, 2, 1, 222, 153, 4, + 219, 113, 60, 8, 6, 1, 220, 143, 4, 75, 60, 8, 2, 1, 220, 143, 4, 75, 60, + 8, 6, 1, 220, 143, 4, 75, 248, 233, 23, 217, 146, 8, 2, 1, 220, 143, 4, + 75, 248, 233, 23, 217, 146, 8, 6, 1, 220, 143, 4, 219, 113, 60, 8, 2, 1, + 220, 143, 4, 219, 113, 60, 8, 6, 1, 220, 143, 4, 243, 2, 60, 8, 2, 1, + 220, 143, 4, 243, 2, 60, 8, 6, 1, 218, 169, 4, 252, 46, 8, 2, 1, 218, + 169, 4, 252, 46, 8, 6, 1, 218, 169, 4, 75, 58, 8, 2, 1, 218, 169, 4, 75, + 58, 8, 6, 1, 218, 169, 4, 75, 60, 8, 2, 1, 218, 169, 4, 75, 60, 8, 6, 1, + 215, 62, 4, 75, 58, 8, 2, 1, 215, 62, 4, 75, 58, 8, 6, 1, 215, 62, 4, 75, + 60, 8, 2, 1, 215, 62, 4, 75, 60, 8, 6, 1, 215, 62, 4, 219, 113, 60, 8, 2, + 1, 215, 62, 4, 219, 113, 60, 8, 6, 1, 215, 62, 4, 243, 2, 60, 8, 2, 1, + 215, 62, 4, 243, 2, 60, 8, 6, 1, 187, 4, 198, 153, 23, 252, 46, 8, 2, 1, + 187, 4, 198, 153, 23, 252, 46, 8, 6, 1, 187, 4, 198, 153, 23, 237, 42, 8, + 2, 1, 187, 4, 198, 153, 23, 237, 42, 8, 6, 1, 187, 4, 217, 147, 23, 230, + 210, 8, 2, 1, 187, 4, 217, 147, 23, 230, 210, 8, 6, 1, 187, 4, 217, 147, + 23, 252, 46, 8, 2, 1, 187, 4, 217, 147, 23, 252, 46, 8, 6, 1, 210, 237, + 4, 252, 46, 8, 2, 1, 210, 237, 4, 252, 46, 8, 6, 1, 210, 237, 4, 75, 58, + 8, 2, 1, 210, 237, 4, 75, 58, 8, 6, 1, 207, 222, 4, 75, 58, 8, 2, 1, 207, + 222, 4, 75, 58, 8, 6, 1, 207, 222, 4, 75, 60, 8, 2, 1, 207, 222, 4, 75, + 60, 8, 6, 1, 207, 222, 4, 75, 248, 233, 23, 217, 146, 8, 2, 1, 207, 222, + 4, 75, 248, 233, 23, 217, 146, 8, 6, 1, 207, 222, 4, 219, 113, 60, 8, 2, + 1, 207, 222, 4, 219, 113, 60, 8, 6, 1, 206, 9, 4, 75, 58, 8, 2, 1, 206, + 9, 4, 75, 58, 8, 6, 1, 206, 9, 4, 75, 60, 8, 2, 1, 206, 9, 4, 75, 60, 8, + 6, 1, 206, 9, 4, 252, 47, 23, 75, 58, 8, 2, 1, 206, 9, 4, 252, 47, 23, + 75, 58, 8, 6, 1, 206, 9, 4, 247, 93, 23, 75, 58, 8, 2, 1, 206, 9, 4, 247, + 93, 23, 75, 58, 8, 6, 1, 206, 9, 4, 75, 248, 233, 23, 75, 58, 8, 2, 1, + 206, 9, 4, 75, 248, 233, 23, 75, 58, 8, 6, 1, 200, 44, 4, 75, 58, 8, 2, + 1, 200, 44, 4, 75, 58, 8, 6, 1, 200, 44, 4, 75, 60, 8, 2, 1, 200, 44, 4, + 75, 60, 8, 6, 1, 200, 44, 4, 219, 113, 60, 8, 2, 1, 200, 44, 4, 219, 113, + 60, 8, 6, 1, 200, 44, 4, 243, 2, 60, 8, 2, 1, 200, 44, 4, 243, 2, 60, 8, + 6, 1, 126, 4, 237, 43, 60, 8, 2, 1, 126, 4, 237, 43, 60, 8, 6, 1, 126, 4, + 198, 153, 60, 8, 2, 1, 126, 4, 198, 153, 60, 8, 6, 1, 126, 4, 243, 2, 60, + 8, 2, 1, 126, 4, 243, 2, 60, 8, 6, 1, 126, 4, 198, 153, 23, 252, 46, 8, + 2, 1, 126, 4, 198, 153, 23, 252, 46, 8, 6, 1, 126, 4, 217, 147, 23, 237, + 42, 8, 2, 1, 126, 4, 217, 147, 23, 237, 42, 8, 6, 1, 196, 13, 4, 198, + 152, 8, 2, 1, 196, 13, 4, 198, 152, 8, 6, 1, 196, 13, 4, 75, 60, 8, 2, 1, + 196, 13, 4, 75, 60, 8, 6, 1, 193, 225, 4, 230, 210, 8, 2, 1, 193, 225, 4, + 230, 210, 8, 6, 1, 193, 225, 4, 252, 46, 8, 2, 1, 193, 225, 4, 252, 46, + 8, 6, 1, 193, 225, 4, 237, 42, 8, 2, 1, 193, 225, 4, 237, 42, 8, 6, 1, + 193, 225, 4, 75, 58, 8, 2, 1, 193, 225, 4, 75, 58, 8, 6, 1, 193, 225, 4, + 75, 60, 8, 2, 1, 193, 225, 4, 75, 60, 8, 6, 1, 192, 236, 4, 75, 58, 8, 2, + 1, 192, 236, 4, 75, 58, 8, 6, 1, 192, 236, 4, 237, 42, 8, 2, 1, 192, 236, + 4, 237, 42, 8, 6, 1, 192, 160, 4, 75, 58, 8, 2, 1, 192, 160, 4, 75, 58, + 8, 6, 1, 191, 167, 4, 243, 1, 8, 2, 1, 191, 167, 4, 243, 1, 8, 6, 1, 191, + 167, 4, 75, 60, 8, 2, 1, 191, 167, 4, 75, 60, 8, 6, 1, 191, 167, 4, 219, + 113, 60, 8, 2, 1, 191, 167, 4, 219, 113, 60, 8, 2, 1, 230, 117, 4, 219, + 113, 60, 8, 2, 1, 200, 44, 4, 237, 42, 8, 2, 1, 193, 225, 4, 206, 189, + 58, 8, 2, 1, 192, 160, 4, 206, 189, 58, 8, 2, 1, 42, 4, 50, 132, 206, + 188, 8, 2, 1, 179, 206, 9, 4, 75, 58, 8, 2, 1, 179, 206, 9, 4, 237, 39, + 106, 8, 2, 1, 179, 206, 9, 4, 137, 106, 8, 6, 1, 203, 127, 206, 8, 8, 2, + 1, 237, 106, 8, 6, 1, 42, 4, 75, 60, 8, 2, 1, 42, 4, 75, 60, 8, 6, 1, 42, + 4, 228, 251, 58, 8, 2, 1, 42, 4, 228, 251, 58, 8, 6, 1, 42, 4, 243, 2, + 23, 252, 46, 8, 2, 1, 42, 4, 243, 2, 23, 252, 46, 8, 6, 1, 42, 4, 243, 2, + 23, 230, 210, 8, 2, 1, 42, 4, 243, 2, 23, 230, 210, 8, 6, 1, 42, 4, 243, + 2, 23, 228, 251, 58, 8, 2, 1, 42, 4, 243, 2, 23, 228, 251, 58, 8, 6, 1, + 42, 4, 243, 2, 23, 198, 152, 8, 2, 1, 42, 4, 243, 2, 23, 198, 152, 8, 6, + 1, 42, 4, 243, 2, 23, 75, 60, 8, 2, 1, 42, 4, 243, 2, 23, 75, 60, 8, 6, + 1, 42, 4, 248, 37, 23, 252, 46, 8, 2, 1, 42, 4, 248, 37, 23, 252, 46, 8, + 6, 1, 42, 4, 248, 37, 23, 230, 210, 8, 2, 1, 42, 4, 248, 37, 23, 230, + 210, 8, 6, 1, 42, 4, 248, 37, 23, 228, 251, 58, 8, 2, 1, 42, 4, 248, 37, + 23, 228, 251, 58, 8, 6, 1, 42, 4, 248, 37, 23, 198, 152, 8, 2, 1, 42, 4, + 248, 37, 23, 198, 152, 8, 6, 1, 42, 4, 248, 37, 23, 75, 60, 8, 2, 1, 42, + 4, 248, 37, 23, 75, 60, 8, 6, 1, 235, 15, 4, 75, 60, 8, 2, 1, 235, 15, 4, + 75, 60, 8, 6, 1, 235, 15, 4, 228, 251, 58, 8, 2, 1, 235, 15, 4, 228, 251, + 58, 8, 6, 1, 235, 15, 4, 198, 152, 8, 2, 1, 235, 15, 4, 198, 152, 8, 6, + 1, 235, 15, 4, 243, 2, 23, 252, 46, 8, 2, 1, 235, 15, 4, 243, 2, 23, 252, + 46, 8, 6, 1, 235, 15, 4, 243, 2, 23, 230, 210, 8, 2, 1, 235, 15, 4, 243, + 2, 23, 230, 210, 8, 6, 1, 235, 15, 4, 243, 2, 23, 228, 251, 58, 8, 2, 1, + 235, 15, 4, 243, 2, 23, 228, 251, 58, 8, 6, 1, 235, 15, 4, 243, 2, 23, + 198, 152, 8, 2, 1, 235, 15, 4, 243, 2, 23, 198, 152, 8, 6, 1, 235, 15, 4, + 243, 2, 23, 75, 60, 8, 2, 1, 235, 15, 4, 243, 2, 23, 75, 60, 8, 6, 1, + 228, 74, 4, 228, 251, 58, 8, 2, 1, 228, 74, 4, 228, 251, 58, 8, 6, 1, + 228, 74, 4, 75, 60, 8, 2, 1, 228, 74, 4, 75, 60, 8, 6, 1, 187, 4, 75, 60, + 8, 2, 1, 187, 4, 75, 60, 8, 6, 1, 187, 4, 228, 251, 58, 8, 2, 1, 187, 4, + 228, 251, 58, 8, 6, 1, 187, 4, 243, 2, 23, 252, 46, 8, 2, 1, 187, 4, 243, + 2, 23, 252, 46, 8, 6, 1, 187, 4, 243, 2, 23, 230, 210, 8, 2, 1, 187, 4, + 243, 2, 23, 230, 210, 8, 6, 1, 187, 4, 243, 2, 23, 228, 251, 58, 8, 2, 1, + 187, 4, 243, 2, 23, 228, 251, 58, 8, 6, 1, 187, 4, 243, 2, 23, 198, 152, + 8, 2, 1, 187, 4, 243, 2, 23, 198, 152, 8, 6, 1, 187, 4, 243, 2, 23, 75, + 60, 8, 2, 1, 187, 4, 243, 2, 23, 75, 60, 8, 6, 1, 187, 4, 228, 188, 23, + 252, 46, 8, 2, 1, 187, 4, 228, 188, 23, 252, 46, 8, 6, 1, 187, 4, 228, + 188, 23, 230, 210, 8, 2, 1, 187, 4, 228, 188, 23, 230, 210, 8, 6, 1, 187, + 4, 228, 188, 23, 228, 251, 58, 8, 2, 1, 187, 4, 228, 188, 23, 228, 251, + 58, 8, 6, 1, 187, 4, 228, 188, 23, 198, 152, 8, 2, 1, 187, 4, 228, 188, + 23, 198, 152, 8, 6, 1, 187, 4, 228, 188, 23, 75, 60, 8, 2, 1, 187, 4, + 228, 188, 23, 75, 60, 8, 6, 1, 126, 4, 75, 60, 8, 2, 1, 126, 4, 75, 60, + 8, 6, 1, 126, 4, 228, 251, 58, 8, 2, 1, 126, 4, 228, 251, 58, 8, 6, 1, + 126, 4, 228, 188, 23, 252, 46, 8, 2, 1, 126, 4, 228, 188, 23, 252, 46, 8, + 6, 1, 126, 4, 228, 188, 23, 230, 210, 8, 2, 1, 126, 4, 228, 188, 23, 230, + 210, 8, 6, 1, 126, 4, 228, 188, 23, 228, 251, 58, 8, 2, 1, 126, 4, 228, + 188, 23, 228, 251, 58, 8, 6, 1, 126, 4, 228, 188, 23, 198, 152, 8, 2, 1, + 126, 4, 228, 188, 23, 198, 152, 8, 6, 1, 126, 4, 228, 188, 23, 75, 60, 8, + 2, 1, 126, 4, 228, 188, 23, 75, 60, 8, 6, 1, 192, 160, 4, 230, 210, 8, 2, + 1, 192, 160, 4, 230, 210, 8, 6, 1, 192, 160, 4, 75, 60, 8, 2, 1, 192, + 160, 4, 75, 60, 8, 6, 1, 192, 160, 4, 228, 251, 58, 8, 2, 1, 192, 160, 4, + 228, 251, 58, 8, 6, 1, 192, 160, 4, 198, 152, 8, 2, 1, 192, 160, 4, 198, + 152, 8, 6, 1, 216, 83, 219, 74, 8, 2, 1, 216, 83, 219, 74, 8, 6, 1, 216, + 83, 196, 12, 8, 2, 1, 216, 83, 196, 12, 8, 6, 1, 192, 160, 4, 219, 4, 8, + 2, 1, 192, 160, 4, 219, 4, 35, 2, 1, 251, 161, 4, 208, 169, 35, 2, 1, + 251, 161, 4, 237, 212, 35, 2, 1, 251, 161, 4, 208, 170, 23, 195, 169, 35, + 2, 1, 251, 161, 4, 237, 213, 23, 195, 169, 35, 2, 1, 251, 161, 4, 208, + 170, 23, 210, 243, 35, 2, 1, 251, 161, 4, 237, 213, 23, 210, 243, 35, 2, + 1, 251, 161, 4, 208, 170, 23, 210, 4, 35, 2, 1, 251, 161, 4, 237, 213, + 23, 210, 4, 35, 6, 1, 251, 161, 4, 208, 169, 35, 6, 1, 251, 161, 4, 237, + 212, 35, 6, 1, 251, 161, 4, 208, 170, 23, 195, 169, 35, 6, 1, 251, 161, + 4, 237, 213, 23, 195, 169, 35, 6, 1, 251, 161, 4, 208, 170, 23, 210, 243, + 35, 6, 1, 251, 161, 4, 237, 213, 23, 210, 243, 35, 6, 1, 251, 161, 4, + 208, 170, 23, 210, 4, 35, 6, 1, 251, 161, 4, 237, 213, 23, 210, 4, 35, 2, + 1, 234, 48, 4, 208, 169, 35, 2, 1, 234, 48, 4, 237, 212, 35, 2, 1, 234, + 48, 4, 208, 170, 23, 195, 169, 35, 2, 1, 234, 48, 4, 237, 213, 23, 195, + 169, 35, 2, 1, 234, 48, 4, 208, 170, 23, 210, 243, 35, 2, 1, 234, 48, 4, + 237, 213, 23, 210, 243, 35, 6, 1, 234, 48, 4, 208, 169, 35, 6, 1, 234, + 48, 4, 237, 212, 35, 6, 1, 234, 48, 4, 208, 170, 23, 195, 169, 35, 6, 1, + 234, 48, 4, 237, 213, 23, 195, 169, 35, 6, 1, 234, 48, 4, 208, 170, 23, + 210, 243, 35, 6, 1, 234, 48, 4, 237, 213, 23, 210, 243, 35, 2, 1, 233, + 254, 4, 208, 169, 35, 2, 1, 233, 254, 4, 237, 212, 35, 2, 1, 233, 254, 4, + 208, 170, 23, 195, 169, 35, 2, 1, 233, 254, 4, 237, 213, 23, 195, 169, + 35, 2, 1, 233, 254, 4, 208, 170, 23, 210, 243, 35, 2, 1, 233, 254, 4, + 237, 213, 23, 210, 243, 35, 2, 1, 233, 254, 4, 208, 170, 23, 210, 4, 35, + 2, 1, 233, 254, 4, 237, 213, 23, 210, 4, 35, 6, 1, 233, 254, 4, 208, 169, + 35, 6, 1, 233, 254, 4, 237, 212, 35, 6, 1, 233, 254, 4, 208, 170, 23, + 195, 169, 35, 6, 1, 233, 254, 4, 237, 213, 23, 195, 169, 35, 6, 1, 233, + 254, 4, 208, 170, 23, 210, 243, 35, 6, 1, 233, 254, 4, 237, 213, 23, 210, + 243, 35, 6, 1, 233, 254, 4, 208, 170, 23, 210, 4, 35, 6, 1, 233, 254, 4, + 237, 213, 23, 210, 4, 35, 2, 1, 223, 84, 4, 208, 169, 35, 2, 1, 223, 84, + 4, 237, 212, 35, 2, 1, 223, 84, 4, 208, 170, 23, 195, 169, 35, 2, 1, 223, + 84, 4, 237, 213, 23, 195, 169, 35, 2, 1, 223, 84, 4, 208, 170, 23, 210, + 243, 35, 2, 1, 223, 84, 4, 237, 213, 23, 210, 243, 35, 2, 1, 223, 84, 4, + 208, 170, 23, 210, 4, 35, 2, 1, 223, 84, 4, 237, 213, 23, 210, 4, 35, 6, + 1, 223, 84, 4, 208, 169, 35, 6, 1, 223, 84, 4, 237, 212, 35, 6, 1, 223, + 84, 4, 208, 170, 23, 195, 169, 35, 6, 1, 223, 84, 4, 237, 213, 23, 195, + 169, 35, 6, 1, 223, 84, 4, 208, 170, 23, 210, 243, 35, 6, 1, 223, 84, 4, + 237, 213, 23, 210, 243, 35, 6, 1, 223, 84, 4, 208, 170, 23, 210, 4, 35, + 6, 1, 223, 84, 4, 237, 213, 23, 210, 4, 35, 2, 1, 211, 108, 4, 208, 169, + 35, 2, 1, 211, 108, 4, 237, 212, 35, 2, 1, 211, 108, 4, 208, 170, 23, + 195, 169, 35, 2, 1, 211, 108, 4, 237, 213, 23, 195, 169, 35, 2, 1, 211, + 108, 4, 208, 170, 23, 210, 243, 35, 2, 1, 211, 108, 4, 237, 213, 23, 210, + 243, 35, 6, 1, 211, 108, 4, 208, 169, 35, 6, 1, 211, 108, 4, 237, 212, + 35, 6, 1, 211, 108, 4, 208, 170, 23, 195, 169, 35, 6, 1, 211, 108, 4, + 237, 213, 23, 195, 169, 35, 6, 1, 211, 108, 4, 208, 170, 23, 210, 243, + 35, 6, 1, 211, 108, 4, 237, 213, 23, 210, 243, 35, 2, 1, 196, 71, 4, 208, + 169, 35, 2, 1, 196, 71, 4, 237, 212, 35, 2, 1, 196, 71, 4, 208, 170, 23, + 195, 169, 35, 2, 1, 196, 71, 4, 237, 213, 23, 195, 169, 35, 2, 1, 196, + 71, 4, 208, 170, 23, 210, 243, 35, 2, 1, 196, 71, 4, 237, 213, 23, 210, + 243, 35, 2, 1, 196, 71, 4, 208, 170, 23, 210, 4, 35, 2, 1, 196, 71, 4, + 237, 213, 23, 210, 4, 35, 6, 1, 196, 71, 4, 237, 212, 35, 6, 1, 196, 71, + 4, 237, 213, 23, 195, 169, 35, 6, 1, 196, 71, 4, 237, 213, 23, 210, 243, + 35, 6, 1, 196, 71, 4, 237, 213, 23, 210, 4, 35, 2, 1, 211, 111, 4, 208, + 169, 35, 2, 1, 211, 111, 4, 237, 212, 35, 2, 1, 211, 111, 4, 208, 170, + 23, 195, 169, 35, 2, 1, 211, 111, 4, 237, 213, 23, 195, 169, 35, 2, 1, + 211, 111, 4, 208, 170, 23, 210, 243, 35, 2, 1, 211, 111, 4, 237, 213, 23, + 210, 243, 35, 2, 1, 211, 111, 4, 208, 170, 23, 210, 4, 35, 2, 1, 211, + 111, 4, 237, 213, 23, 210, 4, 35, 6, 1, 211, 111, 4, 208, 169, 35, 6, 1, + 211, 111, 4, 237, 212, 35, 6, 1, 211, 111, 4, 208, 170, 23, 195, 169, 35, + 6, 1, 211, 111, 4, 237, 213, 23, 195, 169, 35, 6, 1, 211, 111, 4, 208, + 170, 23, 210, 243, 35, 6, 1, 211, 111, 4, 237, 213, 23, 210, 243, 35, 6, + 1, 211, 111, 4, 208, 170, 23, 210, 4, 35, 6, 1, 211, 111, 4, 237, 213, + 23, 210, 4, 35, 2, 1, 251, 161, 4, 195, 169, 35, 2, 1, 251, 161, 4, 210, + 243, 35, 2, 1, 234, 48, 4, 195, 169, 35, 2, 1, 234, 48, 4, 210, 243, 35, + 2, 1, 233, 254, 4, 195, 169, 35, 2, 1, 233, 254, 4, 210, 243, 35, 2, 1, + 223, 84, 4, 195, 169, 35, 2, 1, 223, 84, 4, 210, 243, 35, 2, 1, 211, 108, + 4, 195, 169, 35, 2, 1, 211, 108, 4, 210, 243, 35, 2, 1, 196, 71, 4, 195, + 169, 35, 2, 1, 196, 71, 4, 210, 243, 35, 2, 1, 211, 111, 4, 195, 169, 35, + 2, 1, 211, 111, 4, 210, 243, 35, 2, 1, 251, 161, 4, 208, 170, 23, 191, + 233, 35, 2, 1, 251, 161, 4, 237, 213, 23, 191, 233, 35, 2, 1, 251, 161, + 4, 208, 170, 23, 195, 170, 23, 191, 233, 35, 2, 1, 251, 161, 4, 237, 213, + 23, 195, 170, 23, 191, 233, 35, 2, 1, 251, 161, 4, 208, 170, 23, 210, + 244, 23, 191, 233, 35, 2, 1, 251, 161, 4, 237, 213, 23, 210, 244, 23, + 191, 233, 35, 2, 1, 251, 161, 4, 208, 170, 23, 210, 5, 23, 191, 233, 35, + 2, 1, 251, 161, 4, 237, 213, 23, 210, 5, 23, 191, 233, 35, 6, 1, 251, + 161, 4, 208, 170, 23, 208, 184, 35, 6, 1, 251, 161, 4, 237, 213, 23, 208, + 184, 35, 6, 1, 251, 161, 4, 208, 170, 23, 195, 170, 23, 208, 184, 35, 6, + 1, 251, 161, 4, 237, 213, 23, 195, 170, 23, 208, 184, 35, 6, 1, 251, 161, + 4, 208, 170, 23, 210, 244, 23, 208, 184, 35, 6, 1, 251, 161, 4, 237, 213, + 23, 210, 244, 23, 208, 184, 35, 6, 1, 251, 161, 4, 208, 170, 23, 210, 5, + 23, 208, 184, 35, 6, 1, 251, 161, 4, 237, 213, 23, 210, 5, 23, 208, 184, + 35, 2, 1, 233, 254, 4, 208, 170, 23, 191, 233, 35, 2, 1, 233, 254, 4, + 237, 213, 23, 191, 233, 35, 2, 1, 233, 254, 4, 208, 170, 23, 195, 170, + 23, 191, 233, 35, 2, 1, 233, 254, 4, 237, 213, 23, 195, 170, 23, 191, + 233, 35, 2, 1, 233, 254, 4, 208, 170, 23, 210, 244, 23, 191, 233, 35, 2, + 1, 233, 254, 4, 237, 213, 23, 210, 244, 23, 191, 233, 35, 2, 1, 233, 254, + 4, 208, 170, 23, 210, 5, 23, 191, 233, 35, 2, 1, 233, 254, 4, 237, 213, + 23, 210, 5, 23, 191, 233, 35, 6, 1, 233, 254, 4, 208, 170, 23, 208, 184, + 35, 6, 1, 233, 254, 4, 237, 213, 23, 208, 184, 35, 6, 1, 233, 254, 4, + 208, 170, 23, 195, 170, 23, 208, 184, 35, 6, 1, 233, 254, 4, 237, 213, + 23, 195, 170, 23, 208, 184, 35, 6, 1, 233, 254, 4, 208, 170, 23, 210, + 244, 23, 208, 184, 35, 6, 1, 233, 254, 4, 237, 213, 23, 210, 244, 23, + 208, 184, 35, 6, 1, 233, 254, 4, 208, 170, 23, 210, 5, 23, 208, 184, 35, + 6, 1, 233, 254, 4, 237, 213, 23, 210, 5, 23, 208, 184, 35, 2, 1, 211, + 111, 4, 208, 170, 23, 191, 233, 35, 2, 1, 211, 111, 4, 237, 213, 23, 191, + 233, 35, 2, 1, 211, 111, 4, 208, 170, 23, 195, 170, 23, 191, 233, 35, 2, + 1, 211, 111, 4, 237, 213, 23, 195, 170, 23, 191, 233, 35, 2, 1, 211, 111, + 4, 208, 170, 23, 210, 244, 23, 191, 233, 35, 2, 1, 211, 111, 4, 237, 213, + 23, 210, 244, 23, 191, 233, 35, 2, 1, 211, 111, 4, 208, 170, 23, 210, 5, + 23, 191, 233, 35, 2, 1, 211, 111, 4, 237, 213, 23, 210, 5, 23, 191, 233, + 35, 6, 1, 211, 111, 4, 208, 170, 23, 208, 184, 35, 6, 1, 211, 111, 4, + 237, 213, 23, 208, 184, 35, 6, 1, 211, 111, 4, 208, 170, 23, 195, 170, + 23, 208, 184, 35, 6, 1, 211, 111, 4, 237, 213, 23, 195, 170, 23, 208, + 184, 35, 6, 1, 211, 111, 4, 208, 170, 23, 210, 244, 23, 208, 184, 35, 6, + 1, 211, 111, 4, 237, 213, 23, 210, 244, 23, 208, 184, 35, 6, 1, 211, 111, + 4, 208, 170, 23, 210, 5, 23, 208, 184, 35, 6, 1, 211, 111, 4, 237, 213, + 23, 210, 5, 23, 208, 184, 35, 2, 1, 251, 161, 4, 194, 254, 35, 2, 1, 251, + 161, 4, 217, 146, 35, 2, 1, 251, 161, 4, 195, 170, 23, 191, 233, 35, 2, + 1, 251, 161, 4, 191, 233, 35, 2, 1, 251, 161, 4, 210, 244, 23, 191, 233, + 35, 2, 1, 251, 161, 4, 210, 4, 35, 2, 1, 251, 161, 4, 210, 5, 23, 191, + 233, 35, 6, 1, 251, 161, 4, 194, 254, 35, 6, 1, 251, 161, 4, 217, 146, + 35, 6, 1, 251, 161, 4, 195, 169, 35, 6, 1, 251, 161, 4, 210, 243, 35, 6, + 1, 251, 161, 4, 208, 184, 35, 221, 30, 35, 208, 184, 35, 208, 169, 35, + 210, 4, 35, 237, 36, 23, 210, 4, 35, 2, 1, 233, 254, 4, 195, 170, 23, + 191, 233, 35, 2, 1, 233, 254, 4, 191, 233, 35, 2, 1, 233, 254, 4, 210, + 244, 23, 191, 233, 35, 2, 1, 233, 254, 4, 210, 4, 35, 2, 1, 233, 254, 4, + 210, 5, 23, 191, 233, 35, 6, 1, 234, 48, 4, 195, 169, 35, 6, 1, 234, 48, + 4, 210, 243, 35, 6, 1, 233, 254, 4, 195, 169, 35, 6, 1, 233, 254, 4, 210, + 243, 35, 6, 1, 233, 254, 4, 208, 184, 35, 208, 170, 23, 195, 169, 35, + 208, 170, 23, 210, 243, 35, 208, 170, 23, 210, 4, 35, 2, 1, 223, 84, 4, + 194, 254, 35, 2, 1, 223, 84, 4, 217, 146, 35, 2, 1, 223, 84, 4, 237, 36, + 23, 195, 169, 35, 2, 1, 223, 84, 4, 237, 36, 23, 210, 243, 35, 2, 1, 223, + 84, 4, 210, 4, 35, 2, 1, 223, 84, 4, 237, 36, 23, 210, 4, 35, 6, 1, 223, + 84, 4, 194, 254, 35, 6, 1, 223, 84, 4, 217, 146, 35, 6, 1, 223, 84, 4, + 195, 169, 35, 6, 1, 223, 84, 4, 210, 243, 35, 237, 213, 23, 195, 169, 35, + 237, 213, 23, 210, 243, 35, 237, 213, 23, 210, 4, 35, 2, 1, 196, 71, 4, + 194, 254, 35, 2, 1, 196, 71, 4, 217, 146, 35, 2, 1, 196, 71, 4, 237, 36, + 23, 195, 169, 35, 2, 1, 196, 71, 4, 237, 36, 23, 210, 243, 35, 2, 1, 207, + 4, 4, 208, 169, 35, 2, 1, 207, 4, 4, 237, 212, 35, 2, 1, 196, 71, 4, 210, + 4, 35, 2, 1, 196, 71, 4, 237, 36, 23, 210, 4, 35, 6, 1, 196, 71, 4, 194, + 254, 35, 6, 1, 196, 71, 4, 217, 146, 35, 6, 1, 196, 71, 4, 195, 169, 35, + 6, 1, 196, 71, 4, 210, 243, 35, 6, 1, 207, 4, 4, 237, 212, 35, 237, 36, + 23, 195, 169, 35, 237, 36, 23, 210, 243, 35, 195, 169, 35, 2, 1, 211, + 111, 4, 195, 170, 23, 191, 233, 35, 2, 1, 211, 111, 4, 191, 233, 35, 2, + 1, 211, 111, 4, 210, 244, 23, 191, 233, 35, 2, 1, 211, 111, 4, 210, 4, + 35, 2, 1, 211, 111, 4, 210, 5, 23, 191, 233, 35, 6, 1, 211, 108, 4, 195, + 169, 35, 6, 1, 211, 108, 4, 210, 243, 35, 6, 1, 211, 111, 4, 195, 169, + 35, 6, 1, 211, 111, 4, 210, 243, 35, 6, 1, 211, 111, 4, 208, 184, 35, + 210, 243, 35, 237, 212, 234, 104, 208, 30, 234, 115, 208, 30, 234, 104, + 201, 247, 234, 115, 201, 247, 198, 219, 201, 247, 232, 126, 201, 247, + 202, 134, 201, 247, 233, 13, 201, 247, 208, 152, 201, 247, 199, 4, 201, + 247, 230, 79, 201, 247, 191, 78, 193, 75, 201, 247, 191, 78, 193, 75, + 213, 29, 191, 78, 193, 75, 222, 196, 219, 215, 77, 206, 199, 77, 228, 88, + 213, 30, 228, 88, 233, 13, 237, 215, 234, 104, 237, 215, 234, 115, 237, + 215, 228, 241, 164, 55, 81, 219, 112, 55, 130, 219, 112, 45, 202, 170, + 207, 252, 77, 50, 202, 170, 207, 252, 77, 202, 170, 218, 240, 207, 252, + 77, 202, 170, 229, 132, 207, 252, 77, 45, 55, 207, 252, 77, 50, 55, 207, + 252, 77, 55, 218, 240, 207, 252, 77, 55, 229, 132, 207, 252, 77, 238, 14, + 55, 238, 14, 247, 248, 197, 238, 247, 248, 91, 75, 219, 236, 105, 75, + 219, 236, 228, 241, 234, 120, 228, 86, 209, 61, 219, 113, 204, 10, 210, + 128, 204, 10, 219, 215, 234, 113, 206, 199, 234, 113, 209, 34, 236, 232, + 232, 144, 219, 215, 210, 252, 206, 199, 210, 252, 214, 215, 213, 37, 201, + 247, 210, 14, 216, 50, 56, 210, 14, 199, 96, 198, 230, 56, 208, 215, 55, + 208, 215, 197, 225, 208, 215, 207, 18, 208, 215, 207, 18, 55, 208, 215, + 207, 18, 197, 225, 208, 215, 247, 96, 202, 170, 219, 219, 251, 116, 207, + 252, 77, 202, 170, 206, 203, 251, 116, 207, 252, 77, 207, 83, 77, 55, + 233, 216, 77, 223, 102, 210, 254, 196, 100, 246, 240, 198, 178, 247, 97, + 223, 119, 209, 61, 250, 191, 228, 89, 247, 248, 232, 118, 202, 97, 45, + 51, 248, 54, 4, 208, 7, 50, 51, 248, 54, 4, 208, 7, 55, 208, 13, 77, 208, + 13, 233, 216, 77, 233, 216, 208, 13, 77, 198, 128, 3, 233, 255, 207, 18, + 209, 142, 56, 62, 118, 247, 248, 62, 96, 247, 248, 130, 250, 193, 207, + 18, 204, 25, 242, 220, 196, 77, 105, 250, 192, 251, 178, 195, 84, 242, + 72, 216, 35, 56, 200, 129, 237, 215, 223, 93, 196, 100, 232, 187, 208, + 152, 77, 115, 75, 208, 151, 208, 26, 208, 215, 232, 128, 75, 208, 151, + 232, 226, 75, 208, 151, 105, 75, 208, 151, 232, 128, 75, 77, 235, 138, + 238, 217, 197, 237, 81, 232, 128, 236, 138, 216, 213, 13, 201, 247, 193, + 23, 222, 196, 232, 77, 251, 44, 223, 91, 198, 144, 223, 91, 204, 10, 223, + 91, 209, 81, 219, 215, 223, 59, 206, 199, 223, 59, 232, 238, 201, 14, + 223, 59, 209, 34, 236, 232, 223, 59, 223, 132, 200, 75, 200, 147, 252, + 49, 200, 75, 200, 147, 223, 132, 9, 232, 146, 203, 133, 252, 49, 9, 232, + 146, 203, 133, 214, 208, 17, 203, 134, 213, 33, 17, 203, 134, 200, 182, + 191, 77, 200, 182, 8, 2, 1, 68, 200, 182, 134, 200, 182, 149, 200, 182, + 169, 200, 182, 175, 200, 182, 171, 200, 182, 178, 200, 182, 108, 56, 200, + 182, 216, 34, 200, 182, 234, 43, 56, 200, 182, 45, 210, 113, 200, 182, + 50, 210, 113, 200, 182, 8, 2, 1, 215, 61, 200, 230, 191, 77, 200, 230, + 107, 200, 230, 109, 200, 230, 138, 200, 230, 134, 200, 230, 149, 200, + 230, 169, 200, 230, 175, 200, 230, 171, 200, 230, 178, 200, 230, 108, 56, + 200, 230, 216, 34, 200, 230, 234, 43, 56, 200, 230, 45, 210, 113, 200, + 230, 50, 210, 113, 8, 200, 230, 2, 1, 65, 8, 200, 230, 2, 1, 71, 8, 200, + 230, 2, 1, 74, 8, 200, 230, 2, 1, 192, 235, 8, 200, 230, 2, 1, 205, 86, + 8, 200, 230, 2, 1, 230, 116, 8, 200, 230, 2, 1, 222, 152, 8, 200, 230, 2, + 1, 172, 8, 200, 230, 2, 1, 218, 168, 8, 200, 230, 2, 1, 215, 61, 8, 200, + 230, 2, 1, 210, 236, 8, 200, 230, 2, 1, 206, 8, 8, 200, 230, 2, 1, 200, + 43, 233, 233, 56, 242, 84, 56, 238, 200, 56, 232, 106, 232, 111, 56, 219, + 91, 56, 216, 51, 56, 214, 234, 56, 209, 245, 56, 206, 36, 56, 193, 31, + 56, 214, 80, 203, 99, 56, 236, 149, 56, 233, 234, 56, 221, 135, 56, 197, + 81, 56, 235, 116, 56, 231, 138, 210, 27, 56, 209, 242, 56, 230, 174, 56, + 250, 153, 56, 228, 166, 56, 247, 37, 56, 219, 81, 198, 33, 56, 201, 226, + 56, 199, 93, 56, 223, 147, 206, 36, 56, 197, 60, 219, 91, 56, 213, 19, + 87, 56, 217, 88, 56, 206, 59, 56, 220, 9, 56, 248, 147, 56, 202, 22, 56, + 33, 45, 230, 13, 58, 33, 50, 230, 13, 58, 33, 179, 81, 219, 113, 210, + 255, 33, 203, 40, 81, 219, 113, 210, 255, 33, 251, 85, 64, 58, 33, 242, + 221, 64, 58, 33, 45, 64, 58, 33, 50, 64, 58, 33, 206, 189, 210, 255, 33, + 242, 221, 206, 189, 210, 255, 33, 251, 85, 206, 189, 210, 255, 33, 115, + 185, 58, 33, 232, 128, 185, 58, 33, 234, 99, 243, 10, 33, 234, 99, 201, + 190, 33, 234, 99, 237, 32, 33, 234, 99, 243, 11, 249, 141, 33, 45, 50, + 64, 58, 33, 234, 99, 205, 76, 33, 234, 99, 221, 218, 33, 234, 99, 196, + 68, 209, 58, 197, 241, 33, 207, 19, 202, 24, 210, 255, 33, 55, 81, 201, + 28, 210, 255, 33, 251, 95, 113, 33, 197, 225, 196, 102, 33, 193, 78, 248, + 29, 58, 33, 118, 64, 210, 255, 33, 179, 55, 202, 24, 210, 255, 33, 96, + 230, 13, 4, 181, 235, 118, 33, 118, 230, 13, 4, 181, 235, 118, 33, 45, + 64, 60, 33, 50, 64, 60, 33, 250, 194, 58, 252, 55, 211, 146, 252, 38, + 119, 199, 34, 200, 240, 235, 129, 6, 247, 193, 237, 125, 247, 27, 247, + 22, 219, 113, 113, 247, 98, 211, 146, 247, 152, 196, 112, 233, 235, 239, + 38, 205, 72, 237, 125, 233, 91, 27, 2, 232, 51, 27, 6, 230, 116, 248, + 137, 6, 230, 116, 235, 129, 6, 230, 116, 209, 103, 239, 38, 209, 103, + 239, 39, 139, 105, 209, 185, 27, 6, 68, 248, 137, 6, 68, 27, 6, 172, 27, + 2, 172, 220, 143, 78, 249, 88, 113, 235, 129, 6, 215, 61, 212, 132, 56, + 202, 5, 207, 95, 239, 5, 27, 6, 210, 236, 235, 129, 6, 210, 236, 235, + 129, 6, 208, 104, 27, 6, 146, 248, 137, 6, 146, 235, 129, 6, 146, 208, + 223, 199, 208, 207, 31, 204, 1, 77, 199, 107, 56, 198, 22, 87, 56, 195, + 136, 235, 129, 6, 191, 166, 211, 18, 56, 211, 135, 56, 223, 93, 211, 135, + 56, 248, 137, 6, 191, 166, 153, 35, 2, 1, 223, 83, 222, 3, 56, 251, 110, + 56, 27, 6, 250, 120, 248, 137, 6, 247, 193, 234, 4, 113, 27, 2, 71, 27, + 6, 71, 27, 6, 233, 175, 153, 6, 233, 175, 27, 6, 218, 168, 27, 2, 74, + 131, 113, 248, 215, 113, 231, 39, 113, 237, 254, 113, 223, 137, 202, 3, + 206, 122, 6, 208, 104, 233, 94, 56, 235, 129, 2, 209, 185, 235, 129, 2, + 231, 211, 235, 129, 6, 231, 211, 235, 129, 6, 209, 185, 235, 129, 215, + 60, 200, 201, 153, 49, 6, 232, 51, 153, 49, 6, 172, 207, 18, 49, 6, 172, + 153, 49, 6, 192, 159, 235, 129, 43, 6, 238, 127, 235, 129, 43, 2, 238, + 127, 235, 129, 43, 2, 71, 235, 129, 43, 2, 68, 235, 129, 43, 2, 223, 35, + 208, 188, 219, 112, 153, 251, 137, 210, 14, 56, 251, 210, 153, 2, 233, + 175, 16, 40, 205, 151, 202, 3, 193, 246, 232, 118, 91, 203, 243, 193, + 246, 232, 118, 91, 213, 167, 193, 246, 232, 118, 91, 199, 86, 193, 246, + 232, 118, 91, 199, 0, 193, 246, 232, 118, 105, 198, 253, 193, 246, 232, + 118, 91, 233, 18, 193, 246, 232, 118, 105, 233, 17, 193, 246, 232, 118, + 115, 233, 17, 193, 246, 232, 118, 232, 128, 233, 17, 193, 246, 232, 118, + 91, 202, 124, 193, 246, 232, 118, 232, 226, 202, 122, 193, 246, 232, 118, + 91, 234, 159, 193, 246, 232, 118, 115, 234, 157, 193, 246, 232, 118, 232, + 226, 234, 157, 193, 246, 232, 118, 203, 247, 234, 157, 232, 118, 212, + 133, 107, 206, 136, 212, 134, 107, 206, 136, 212, 134, 109, 206, 136, + 212, 134, 138, 206, 136, 212, 134, 134, 206, 136, 212, 134, 149, 206, + 136, 212, 134, 169, 206, 136, 212, 134, 175, 206, 136, 212, 134, 171, + 206, 136, 212, 134, 178, 206, 136, 212, 134, 199, 95, 206, 136, 212, 134, + 234, 127, 206, 136, 212, 134, 197, 37, 206, 136, 212, 134, 233, 15, 206, + 136, 212, 134, 91, 228, 140, 206, 136, 212, 134, 232, 226, 228, 140, 206, + 136, 212, 134, 91, 189, 2, 206, 136, 212, 134, 107, 2, 206, 136, 212, + 134, 109, 2, 206, 136, 212, 134, 138, 2, 206, 136, 212, 134, 134, 2, 206, + 136, 212, 134, 149, 2, 206, 136, 212, 134, 169, 2, 206, 136, 212, 134, + 175, 2, 206, 136, 212, 134, 171, 2, 206, 136, 212, 134, 178, 2, 206, 136, + 212, 134, 199, 95, 2, 206, 136, 212, 134, 234, 127, 2, 206, 136, 212, + 134, 197, 37, 2, 206, 136, 212, 134, 233, 15, 2, 206, 136, 212, 134, 91, + 228, 140, 2, 206, 136, 212, 134, 232, 226, 228, 140, 2, 206, 136, 212, + 134, 91, 189, 206, 136, 212, 134, 91, 198, 230, 247, 194, 238, 127, 206, + 136, 212, 134, 232, 226, 189, 206, 136, 212, 134, 199, 96, 189, 206, 136, + 212, 134, 207, 18, 91, 228, 140, 8, 2, 1, 207, 18, 247, 193, 206, 136, + 212, 134, 202, 136, 220, 4, 20, 206, 136, 212, 134, 233, 16, 234, 210, + 20, 206, 136, 212, 134, 233, 16, 189, 206, 136, 212, 134, 91, 228, 141, + 189, 193, 246, 232, 118, 191, 78, 198, 253, 153, 17, 109, 153, 17, 138, + 118, 57, 196, 66, 57, 96, 57, 235, 119, 57, 45, 50, 57, 133, 144, 57, + 186, 193, 105, 57, 186, 234, 204, 57, 202, 2, 234, 204, 57, 202, 2, 193, + 105, 57, 118, 64, 4, 106, 96, 64, 4, 106, 118, 193, 139, 57, 96, 193, + 139, 57, 118, 105, 229, 233, 57, 196, 66, 105, 229, 233, 57, 96, 105, + 229, 233, 57, 235, 119, 105, 229, 233, 57, 118, 64, 4, 199, 215, 96, 64, + 4, 199, 215, 118, 64, 232, 98, 164, 196, 66, 64, 232, 98, 164, 96, 64, + 232, 98, 164, 235, 119, 64, 232, 98, 164, 133, 144, 64, 4, 249, 74, 118, + 64, 4, 102, 96, 64, 4, 102, 118, 64, 4, 219, 4, 96, 64, 4, 219, 4, 45, + 50, 193, 139, 57, 45, 50, 64, 4, 106, 235, 119, 191, 21, 57, 196, 66, 64, + 4, 198, 136, 219, 214, 196, 66, 64, 4, 198, 136, 206, 197, 235, 119, 64, + 4, 198, 136, 219, 214, 235, 119, 64, 4, 198, 136, 206, 197, 96, 64, 4, + 239, 2, 235, 118, 235, 119, 64, 4, 239, 2, 219, 214, 251, 85, 198, 54, + 204, 28, 57, 242, 221, 198, 54, 204, 28, 57, 186, 193, 105, 64, 119, 179, + 164, 118, 64, 119, 249, 88, 139, 96, 64, 119, 164, 251, 85, 211, 77, 243, + 11, 57, 242, 221, 211, 77, 243, 11, 57, 118, 230, 13, 4, 181, 196, 65, + 118, 230, 13, 4, 181, 235, 118, 196, 66, 230, 13, 4, 181, 206, 197, 196, + 66, 230, 13, 4, 181, 219, 214, 96, 230, 13, 4, 181, 196, 65, 96, 230, 13, + 4, 181, 235, 118, 235, 119, 230, 13, 4, 181, 206, 197, 235, 119, 230, 13, + 4, 181, 219, 214, 96, 64, 139, 118, 57, 196, 66, 64, 118, 79, 235, 119, + 57, 118, 64, 139, 96, 57, 118, 210, 196, 250, 231, 196, 66, 210, 196, + 250, 231, 96, 210, 196, 250, 231, 235, 119, 210, 196, 250, 231, 118, 230, + 13, 139, 96, 230, 12, 96, 230, 13, 139, 118, 230, 12, 118, 55, 64, 4, + 106, 45, 50, 55, 64, 4, 106, 96, 55, 64, 4, 106, 118, 55, 57, 196, 66, + 55, 57, 96, 55, 57, 235, 119, 55, 57, 45, 50, 55, 57, 133, 144, 55, 57, + 186, 193, 105, 55, 57, 186, 234, 204, 55, 57, 202, 2, 234, 204, 55, 57, + 202, 2, 193, 105, 55, 57, 118, 197, 225, 57, 96, 197, 225, 57, 118, 201, + 183, 57, 96, 201, 183, 57, 196, 66, 64, 4, 55, 106, 235, 119, 64, 4, 55, + 106, 118, 237, 214, 57, 196, 66, 237, 214, 57, 96, 237, 214, 57, 235, + 119, 237, 214, 57, 118, 64, 119, 164, 96, 64, 119, 164, 118, 63, 57, 196, + 66, 63, 57, 96, 63, 57, 235, 119, 63, 57, 196, 66, 63, 64, 232, 98, 164, + 196, 66, 63, 64, 211, 105, 210, 52, 196, 66, 63, 64, 211, 105, 210, 53, + 4, 228, 241, 164, 196, 66, 63, 64, 211, 105, 210, 53, 4, 81, 164, 196, + 66, 63, 55, 57, 196, 66, 63, 55, 64, 211, 105, 210, 52, 96, 63, 64, 232, + 98, 193, 167, 186, 193, 105, 64, 119, 239, 1, 202, 2, 234, 204, 64, 119, + 239, 1, 133, 144, 63, 57, 50, 64, 4, 2, 243, 10, 235, 119, 64, 118, 79, + 196, 66, 57, 115, 96, 250, 231, 118, 64, 4, 81, 106, 96, 64, 4, 81, 106, + 45, 50, 64, 4, 81, 106, 118, 64, 4, 55, 81, 106, 96, 64, 4, 55, 81, 106, + 45, 50, 64, 4, 55, 81, 106, 118, 211, 74, 57, 96, 211, 74, 57, 45, 50, + 211, 74, 57, 40, 251, 174, 242, 68, 210, 105, 237, 16, 199, 24, 233, 211, + 199, 24, 236, 164, 213, 12, 233, 212, 234, 105, 203, 252, 223, 151, 214, + 245, 234, 132, 211, 146, 213, 12, 251, 133, 234, 132, 211, 146, 2, 234, + 132, 211, 146, 239, 32, 250, 220, 216, 190, 236, 164, 213, 12, 239, 34, + 250, 220, 216, 190, 2, 239, 32, 250, 220, 216, 190, 234, 95, 79, 208, + 190, 215, 60, 208, 200, 215, 60, 239, 9, 215, 60, 200, 201, 216, 35, 56, + 216, 33, 56, 75, 209, 81, 236, 200, 202, 97, 203, 253, 216, 34, 250, 194, + 211, 66, 206, 189, 211, 66, 247, 249, 211, 66, 51, 206, 128, 238, 191, + 206, 128, 232, 121, 206, 128, 208, 186, 159, 223, 139, 50, 251, 115, 251, + 115, 216, 226, 251, 115, 201, 225, 251, 115, 236, 203, 236, 164, 213, 12, + 236, 207, 210, 119, 159, 213, 12, 210, 119, 159, 219, 29, 251, 125, 219, + 29, 211, 56, 223, 99, 196, 92, 223, 113, 55, 223, 113, 197, 225, 223, + 113, 239, 26, 223, 113, 200, 171, 223, 113, 195, 11, 223, 113, 242, 221, + 223, 113, 242, 221, 239, 26, 223, 113, 251, 85, 239, 26, 223, 113, 199, + 23, 249, 3, 207, 126, 208, 187, 75, 216, 34, 233, 219, 231, 144, 208, + 187, 229, 0, 198, 153, 211, 66, 207, 18, 198, 152, 223, 93, 219, 245, + 206, 8, 202, 172, 193, 138, 193, 10, 208, 200, 213, 12, 198, 152, 216, + 35, 198, 152, 250, 186, 234, 45, 159, 213, 12, 250, 186, 234, 45, 159, + 251, 40, 234, 45, 159, 251, 40, 247, 218, 213, 12, 252, 48, 234, 45, 159, + 214, 105, 251, 40, 213, 21, 252, 48, 234, 45, 159, 251, 165, 234, 45, + 159, 213, 12, 251, 165, 234, 45, 159, 251, 165, 234, 45, 211, 57, 234, + 45, 159, 197, 225, 198, 152, 251, 175, 234, 45, 159, 234, 36, 159, 231, + 143, 234, 36, 159, 237, 17, 248, 209, 251, 42, 199, 34, 219, 120, 231, + 143, 234, 45, 159, 251, 40, 234, 45, 119, 211, 57, 199, 34, 223, 178, + 211, 146, 223, 178, 79, 211, 57, 251, 40, 234, 45, 159, 242, 84, 234, 42, + 234, 43, 242, 83, 206, 189, 223, 163, 234, 45, 159, 206, 189, 234, 45, + 159, 238, 250, 159, 234, 3, 234, 41, 159, 201, 103, 234, 42, 237, 107, + 234, 45, 159, 234, 45, 119, 247, 205, 237, 126, 216, 226, 247, 204, 208, + 11, 234, 45, 159, 213, 12, 234, 45, 159, 228, 17, 159, 213, 12, 228, 17, + 159, 201, 35, 234, 36, 159, 219, 180, 211, 57, 234, 45, 159, 230, 204, + 211, 57, 234, 45, 159, 219, 180, 139, 234, 45, 159, 230, 204, 139, 234, + 45, 159, 219, 180, 247, 218, 213, 12, 234, 45, 159, 230, 204, 247, 218, + 213, 12, 234, 45, 159, 215, 145, 219, 179, 215, 145, 230, 203, 248, 209, + 213, 12, 234, 36, 159, 213, 12, 219, 179, 213, 12, 230, 203, 214, 105, + 219, 180, 213, 21, 234, 45, 159, 214, 105, 230, 204, 213, 21, 234, 45, + 159, 219, 180, 211, 57, 234, 36, 159, 230, 204, 211, 57, 234, 36, 159, + 214, 105, 219, 180, 213, 21, 234, 36, 159, 214, 105, 230, 204, 213, 21, + 234, 36, 159, 219, 180, 211, 57, 230, 203, 230, 204, 211, 57, 219, 179, + 214, 105, 219, 180, 213, 21, 230, 203, 214, 105, 230, 204, 213, 21, 219, + 179, 208, 231, 200, 220, 208, 232, 211, 57, 234, 45, 159, 200, 221, 211, + 57, 234, 45, 159, 208, 232, 211, 57, 234, 36, 159, 200, 221, 211, 57, + 234, 36, 159, 236, 164, 213, 12, 208, 234, 236, 164, 213, 12, 200, 222, + 200, 229, 211, 146, 200, 181, 211, 146, 213, 12, 42, 200, 229, 211, 146, + 213, 12, 42, 200, 181, 211, 146, 200, 229, 79, 211, 57, 234, 45, 159, + 200, 181, 79, 211, 57, 234, 45, 159, 214, 105, 42, 200, 229, 79, 213, 21, + 234, 45, 159, 214, 105, 42, 200, 181, 79, 213, 21, 234, 45, 159, 200, + 229, 79, 4, 213, 12, 234, 45, 159, 200, 181, 79, 4, 213, 12, 234, 45, + 159, 215, 124, 215, 125, 215, 126, 215, 125, 196, 92, 51, 223, 178, 211, + 146, 51, 211, 46, 211, 146, 51, 223, 178, 79, 211, 57, 234, 45, 159, 51, + 211, 46, 79, 211, 57, 234, 45, 159, 51, 247, 111, 51, 238, 181, 47, 209, + 81, 47, 216, 34, 47, 198, 144, 47, 236, 200, 202, 97, 47, 75, 211, 66, + 47, 206, 189, 211, 66, 47, 250, 194, 211, 66, 47, 234, 42, 47, 237, 215, + 112, 209, 81, 112, 216, 34, 112, 198, 144, 112, 75, 211, 66, 50, 199, + 228, 45, 199, 228, 144, 199, 228, 133, 199, 228, 250, 197, 216, 1, 197, + 201, 232, 152, 197, 225, 81, 249, 88, 50, 197, 57, 55, 81, 249, 88, 55, + 50, 197, 57, 236, 164, 213, 12, 208, 179, 213, 12, 197, 201, 236, 164, + 213, 12, 232, 153, 214, 108, 55, 81, 249, 88, 55, 50, 197, 57, 208, 232, + 196, 105, 207, 65, 200, 221, 196, 105, 207, 65, 213, 18, 200, 244, 211, + 146, 239, 32, 250, 220, 213, 18, 200, 243, 213, 18, 200, 244, 79, 211, + 57, 234, 45, 159, 239, 32, 250, 220, 213, 18, 200, 244, 211, 57, 234, 45, + 159, 211, 46, 211, 146, 223, 178, 211, 146, 215, 131, 229, 189, 239, 43, + 217, 27, 223, 110, 192, 192, 214, 224, 213, 20, 50, 251, 116, 4, 251, 16, + 50, 197, 241, 215, 60, 219, 29, 251, 125, 215, 60, 219, 29, 211, 56, 215, + 60, 223, 99, 215, 60, 196, 92, 237, 33, 211, 66, 75, 211, 66, 201, 103, + 211, 66, 236, 200, 198, 144, 248, 63, 45, 213, 18, 233, 93, 204, 24, 208, + 200, 50, 213, 18, 233, 93, 204, 24, 208, 200, 45, 204, 24, 208, 200, 50, + 204, 24, 208, 200, 207, 18, 198, 153, 234, 42, 238, 171, 219, 29, 211, + 56, 238, 171, 219, 29, 251, 125, 55, 200, 228, 55, 200, 180, 55, 223, 99, + 55, 196, 92, 209, 115, 234, 45, 23, 210, 119, 159, 219, 180, 4, 236, 140, + 230, 204, 4, 236, 140, 195, 83, 215, 145, 219, 179, 195, 83, 215, 145, + 230, 203, 219, 180, 234, 45, 119, 211, 57, 230, 203, 230, 204, 234, 45, + 119, 211, 57, 219, 179, 234, 45, 119, 211, 57, 219, 179, 234, 45, 119, + 211, 57, 230, 203, 234, 45, 119, 211, 57, 208, 231, 234, 45, 119, 211, + 57, 200, 220, 236, 164, 213, 12, 208, 235, 211, 57, 234, 44, 236, 164, + 213, 12, 200, 223, 211, 57, 234, 44, 213, 12, 51, 223, 178, 79, 211, 57, + 234, 45, 159, 213, 12, 51, 211, 46, 79, 211, 57, 234, 45, 159, 51, 223, + 178, 79, 211, 57, 213, 12, 234, 45, 159, 51, 211, 46, 79, 211, 57, 213, + 12, 234, 45, 159, 219, 180, 247, 218, 213, 12, 234, 36, 159, 230, 204, + 247, 218, 213, 12, 234, 36, 159, 208, 232, 247, 218, 213, 12, 234, 36, + 159, 200, 221, 247, 218, 213, 12, 234, 36, 159, 213, 12, 213, 18, 200, + 244, 211, 146, 236, 164, 213, 12, 239, 34, 250, 220, 213, 18, 200, 243, + 213, 12, 213, 18, 200, 244, 79, 211, 57, 234, 45, 159, 236, 164, 213, 12, + 239, 34, 250, 220, 213, 18, 200, 244, 211, 57, 234, 44, 81, 234, 120, + 216, 82, 228, 241, 234, 120, 133, 50, 237, 39, 234, 120, 144, 50, 237, + 39, 234, 120, 234, 132, 79, 4, 179, 228, 241, 106, 234, 132, 79, 4, 81, + 249, 88, 250, 183, 234, 95, 79, 228, 241, 106, 2, 234, 132, 79, 4, 81, + 249, 88, 250, 183, 234, 95, 79, 228, 241, 106, 234, 132, 79, 4, 75, 58, + 234, 132, 79, 4, 211, 6, 2, 234, 132, 79, 4, 211, 6, 234, 132, 79, 4, + 196, 103, 234, 132, 79, 4, 105, 228, 241, 201, 15, 239, 32, 4, 179, 228, + 241, 106, 239, 32, 4, 81, 249, 88, 250, 183, 234, 95, 79, 228, 241, 106, + 2, 239, 32, 4, 81, 249, 88, 250, 183, 234, 95, 79, 228, 241, 106, 239, + 32, 4, 211, 6, 2, 239, 32, 4, 211, 6, 191, 167, 213, 10, 249, 131, 216, + 189, 237, 34, 56, 234, 135, 57, 228, 172, 133, 250, 235, 144, 250, 235, + 208, 194, 209, 248, 193, 135, 219, 112, 45, 247, 30, 50, 247, 30, 45, + 232, 193, 50, 232, 193, 248, 77, 50, 238, 219, 248, 77, 45, 238, 219, + 198, 54, 50, 238, 219, 198, 54, 45, 238, 219, 207, 18, 213, 12, 56, 51, + 218, 232, 251, 16, 205, 43, 205, 52, 199, 107, 207, 96, 209, 25, 223, + 144, 195, 56, 201, 190, 209, 108, 79, 223, 109, 56, 153, 213, 12, 56, + 193, 145, 228, 174, 198, 54, 45, 239, 1, 198, 54, 50, 239, 1, 248, 77, + 45, 239, 1, 248, 77, 50, 239, 1, 198, 54, 132, 223, 113, 248, 77, 132, + 223, 113, 232, 93, 202, 65, 133, 250, 236, 248, 210, 105, 228, 241, 249, + 76, 211, 59, 221, 222, 234, 32, 119, 199, 34, 183, 192, 236, 223, 163, + 42, 207, 93, 248, 62, 221, 220, 219, 219, 251, 116, 248, 53, 206, 203, + 251, 116, 248, 53, 234, 32, 119, 199, 34, 219, 224, 248, 221, 206, 188, + 238, 138, 251, 175, 250, 244, 200, 74, 198, 39, 206, 41, 236, 252, 211, + 47, 239, 48, 199, 181, 202, 81, 238, 246, 238, 245, 251, 59, 232, 75, 16, + 228, 67, 251, 59, 232, 75, 16, 201, 181, 208, 30, 251, 59, 232, 75, 16, + 208, 31, 234, 44, 251, 59, 232, 75, 16, 208, 31, 236, 207, 251, 59, 232, + 75, 16, 208, 31, 237, 32, 251, 59, 232, 75, 16, 208, 31, 222, 188, 251, + 59, 232, 75, 16, 208, 31, 243, 10, 251, 59, 232, 75, 16, 243, 11, 201, + 71, 251, 59, 232, 75, 16, 243, 11, 222, 188, 251, 59, 232, 75, 16, 202, + 98, 164, 251, 59, 232, 75, 16, 249, 142, 164, 251, 59, 232, 75, 16, 208, + 31, 202, 97, 251, 59, 232, 75, 16, 208, 31, 249, 141, 251, 59, 232, 75, + 16, 208, 31, 219, 179, 251, 59, 232, 75, 16, 208, 31, 230, 203, 251, 59, + 232, 75, 16, 118, 195, 176, 251, 59, 232, 75, 16, 96, 195, 176, 251, 59, + 232, 75, 16, 208, 31, 118, 57, 251, 59, 232, 75, 16, 208, 31, 96, 57, + 251, 59, 232, 75, 16, 243, 11, 249, 141, 251, 59, 232, 75, 16, 144, 199, + 229, 196, 103, 251, 59, 232, 75, 16, 237, 107, 201, 71, 251, 59, 232, 75, + 16, 208, 31, 144, 247, 96, 251, 59, 232, 75, 16, 208, 31, 237, 106, 251, + 59, 232, 75, 16, 144, 199, 229, 222, 188, 251, 59, 232, 75, 16, 196, 66, + 195, 176, 251, 59, 232, 75, 16, 208, 31, 196, 66, 57, 251, 59, 232, 75, + 16, 133, 199, 229, 211, 6, 251, 59, 232, 75, 16, 237, 119, 201, 71, 251, + 59, 232, 75, 16, 208, 31, 133, 247, 96, 251, 59, 232, 75, 16, 208, 31, + 237, 118, 251, 59, 232, 75, 16, 133, 199, 229, 222, 188, 251, 59, 232, + 75, 16, 235, 119, 195, 176, 251, 59, 232, 75, 16, 208, 31, 235, 119, 57, + 251, 59, 232, 75, 16, 207, 251, 196, 103, 251, 59, 232, 75, 16, 237, 107, + 196, 103, 251, 59, 232, 75, 16, 237, 33, 196, 103, 251, 59, 232, 75, 16, + 222, 189, 196, 103, 251, 59, 232, 75, 16, 243, 11, 196, 103, 251, 59, + 232, 75, 16, 133, 203, 53, 222, 188, 251, 59, 232, 75, 16, 207, 251, 208, + 30, 251, 59, 232, 75, 16, 243, 11, 201, 102, 251, 59, 232, 75, 16, 208, + 31, 242, 83, 251, 59, 232, 75, 16, 133, 199, 229, 237, 42, 251, 59, 232, + 75, 16, 237, 119, 237, 42, 251, 59, 232, 75, 16, 201, 103, 237, 42, 251, + 59, 232, 75, 16, 222, 189, 237, 42, 251, 59, 232, 75, 16, 243, 11, 237, + 42, 251, 59, 232, 75, 16, 144, 203, 53, 201, 71, 251, 59, 232, 75, 16, + 45, 203, 53, 201, 71, 251, 59, 232, 75, 16, 198, 153, 237, 42, 251, 59, + 232, 75, 16, 230, 204, 237, 42, 251, 59, 232, 75, 16, 242, 75, 164, 251, + 59, 232, 75, 16, 237, 119, 198, 152, 251, 59, 232, 75, 16, 191, 20, 251, + 59, 232, 75, 16, 201, 72, 198, 152, 251, 59, 232, 75, 16, 204, 26, 196, + 103, 251, 59, 232, 75, 16, 208, 31, 213, 12, 234, 44, 251, 59, 232, 75, + 16, 208, 31, 208, 12, 251, 59, 232, 75, 16, 144, 247, 97, 198, 152, 251, + 59, 232, 75, 16, 133, 247, 97, 198, 152, 251, 59, 232, 75, 16, 223, 83, + 251, 59, 232, 75, 16, 207, 3, 251, 59, 232, 75, 16, 211, 110, 251, 59, + 232, 75, 16, 251, 161, 196, 103, 251, 59, 232, 75, 16, 234, 48, 196, 103, + 251, 59, 232, 75, 16, 223, 84, 196, 103, 251, 59, 232, 75, 16, 211, 111, + 196, 103, 251, 59, 232, 75, 16, 251, 160, 213, 12, 243, 126, 77, 50, 251, + 116, 4, 235, 119, 191, 21, 57, 203, 21, 211, 77, 248, 62, 248, 236, 113, + 81, 219, 113, 4, 82, 236, 140, 223, 119, 113, 239, 27, 196, 101, 113, + 236, 225, 196, 101, 113, 234, 107, 113, 239, 63, 113, 63, 51, 4, 247, 22, + 81, 219, 112, 234, 78, 113, 251, 152, 221, 223, 113, 229, 202, 113, 47, + 228, 241, 249, 88, 4, 213, 9, 47, 197, 242, 235, 123, 248, 22, 243, 11, + 4, 213, 15, 57, 196, 99, 113, 215, 216, 113, 228, 84, 113, 211, 75, 230, + 115, 113, 211, 75, 220, 141, 113, 210, 93, 113, 210, 92, 113, 236, 234, + 238, 169, 16, 232, 146, 109, 202, 29, 113, 251, 59, 232, 75, 16, 208, 30, + 237, 138, 204, 11, 221, 223, 113, 208, 217, 210, 204, 214, 73, 210, 204, + 208, 212, 205, 77, 113, 242, 238, 205, 77, 113, 45, 210, 114, 116, 102, + 45, 210, 114, 233, 203, 45, 210, 114, 110, 102, 50, 210, 114, 116, 102, + 50, 210, 114, 233, 203, 50, 210, 114, 110, 102, 45, 51, 248, 54, 116, + 239, 1, 45, 51, 248, 54, 233, 203, 45, 51, 248, 54, 110, 239, 1, 50, 51, + 248, 54, 116, 239, 1, 50, 51, 248, 54, 233, 203, 50, 51, 248, 54, 110, + 239, 1, 45, 238, 171, 248, 54, 116, 102, 45, 238, 171, 248, 54, 82, 209, + 175, 45, 238, 171, 248, 54, 110, 102, 238, 171, 248, 54, 233, 203, 50, + 238, 171, 248, 54, 116, 102, 50, 238, 171, 248, 54, 82, 209, 175, 50, + 238, 171, 248, 54, 110, 102, 223, 114, 233, 203, 228, 241, 219, 113, 233, + 203, 116, 45, 211, 57, 110, 50, 238, 171, 248, 54, 205, 53, 116, 50, 211, + 57, 110, 45, 238, 171, 248, 54, 205, 53, 200, 202, 198, 53, 200, 202, + 248, 76, 198, 54, 51, 248, 53, 248, 77, 51, 248, 53, 248, 77, 51, 248, + 54, 139, 198, 54, 51, 248, 53, 48, 16, 248, 76, 45, 81, 111, 219, 112, + 50, 81, 111, 219, 112, 228, 241, 205, 97, 219, 111, 228, 241, 205, 97, + 219, 110, 228, 241, 205, 97, 219, 109, 228, 241, 205, 97, 219, 108, 237, + 97, 16, 156, 81, 23, 198, 54, 183, 237, 97, 16, 156, 81, 23, 248, 77, + 183, 237, 97, 16, 156, 81, 4, 243, 10, 237, 97, 16, 156, 144, 23, 228, + 241, 4, 243, 10, 237, 97, 16, 156, 133, 23, 228, 241, 4, 243, 10, 237, + 97, 16, 156, 81, 4, 197, 241, 237, 97, 16, 156, 144, 23, 228, 241, 4, + 197, 241, 237, 97, 16, 156, 133, 23, 228, 241, 4, 197, 241, 237, 97, 16, + 156, 81, 23, 193, 138, 237, 97, 16, 156, 144, 23, 228, 241, 4, 193, 138, + 237, 97, 16, 156, 133, 23, 228, 241, 4, 193, 138, 237, 97, 16, 156, 144, + 23, 228, 240, 237, 97, 16, 156, 133, 23, 228, 240, 237, 97, 16, 156, 81, + 23, 198, 54, 219, 224, 237, 97, 16, 156, 81, 23, 248, 77, 219, 224, 51, + 232, 159, 207, 23, 113, 234, 149, 113, 81, 219, 113, 233, 203, 216, 159, + 248, 36, 216, 159, 179, 139, 203, 39, 216, 159, 203, 40, 139, 219, 19, + 216, 159, 179, 139, 105, 203, 25, 216, 159, 105, 203, 26, 139, 219, 19, + 216, 159, 105, 203, 26, 222, 197, 216, 159, 197, 221, 216, 159, 199, 65, + 216, 159, 210, 22, 234, 208, 230, 188, 232, 69, 198, 54, 210, 113, 248, + 77, 210, 113, 198, 54, 238, 171, 248, 53, 248, 77, 238, 171, 248, 53, + 198, 54, 198, 42, 203, 103, 248, 53, 248, 77, 198, 42, 203, 103, 248, 53, + 63, 198, 5, 248, 221, 206, 189, 4, 243, 10, 201, 51, 232, 204, 252, 64, + 238, 168, 234, 134, 223, 99, 237, 138, 233, 207, 113, 62, 206, 203, 55, + 197, 241, 62, 219, 219, 55, 197, 241, 62, 196, 76, 55, 197, 241, 62, 235, + 122, 55, 197, 241, 62, 206, 203, 55, 197, 242, 4, 81, 164, 62, 219, 219, + 55, 197, 242, 4, 81, 164, 62, 206, 203, 197, 242, 4, 55, 81, 164, 251, + 201, 242, 222, 201, 58, 198, 145, 242, 222, 228, 175, 4, 232, 184, 205, + 140, 62, 216, 213, 219, 219, 197, 241, 62, 216, 213, 206, 203, 197, 241, + 62, 216, 213, 196, 76, 197, 241, 62, 216, 213, 235, 122, 197, 241, 55, + 81, 164, 62, 51, 40, 201, 63, 62, 243, 11, 40, 207, 97, 208, 255, 113, + 208, 255, 211, 103, 113, 208, 255, 211, 105, 113, 208, 255, 202, 93, 113, + 211, 168, 233, 194, 113, 16, 40, 212, 138, 16, 40, 201, 98, 79, 229, 232, + 16, 40, 201, 98, 79, 199, 53, 16, 40, 234, 95, 79, 199, 53, 16, 40, 234, + 95, 79, 198, 11, 16, 40, 234, 81, 16, 40, 252, 51, 16, 40, 248, 235, 16, + 40, 249, 140, 16, 40, 228, 241, 199, 230, 16, 40, 219, 113, 233, 50, 16, + 40, 81, 199, 230, 16, 40, 232, 146, 233, 50, 16, 40, 247, 88, 207, 22, + 16, 40, 203, 77, 211, 14, 16, 40, 203, 77, 223, 162, 16, 40, 237, 210, + 219, 103, 234, 14, 16, 40, 237, 75, 239, 22, 107, 16, 40, 237, 75, 239, + 22, 109, 16, 40, 237, 75, 239, 22, 138, 16, 40, 237, 75, 239, 22, 134, + 16, 40, 214, 106, 252, 51, 16, 40, 200, 69, 223, 228, 16, 40, 234, 95, + 79, 198, 12, 248, 129, 16, 40, 247, 126, 16, 40, 234, 95, 79, 216, 212, + 16, 40, 200, 226, 16, 40, 234, 14, 16, 40, 233, 7, 204, 10, 16, 40, 230, + 187, 204, 10, 16, 40, 207, 98, 204, 10, 16, 40, 196, 91, 204, 10, 16, 40, + 201, 247, 16, 40, 237, 116, 248, 133, 113, 211, 77, 248, 62, 16, 40, 214, + 76, 16, 40, 237, 117, 232, 146, 109, 16, 40, 200, 227, 232, 146, 109, + 211, 161, 102, 211, 161, 246, 252, 211, 161, 232, 149, 211, 161, 223, 93, + 232, 149, 211, 161, 248, 232, 248, 5, 211, 161, 248, 70, 198, 178, 211, + 161, 248, 48, 249, 93, 228, 15, 211, 161, 251, 139, 79, 243, 125, 211, + 161, 237, 215, 211, 161, 238, 157, 252, 55, 212, 136, 211, 161, 55, 249, + 141, 47, 17, 107, 47, 17, 109, 47, 17, 138, 47, 17, 134, 47, 17, 149, 47, + 17, 169, 47, 17, 175, 47, 17, 171, 47, 17, 178, 47, 31, 199, 95, 47, 31, + 234, 127, 47, 31, 197, 37, 47, 31, 198, 251, 47, 31, 232, 122, 47, 31, + 233, 19, 47, 31, 202, 130, 47, 31, 203, 244, 47, 31, 234, 161, 47, 31, + 213, 171, 47, 31, 197, 32, 127, 17, 107, 127, 17, 109, 127, 17, 138, 127, + 17, 134, 127, 17, 149, 127, 17, 169, 127, 17, 175, 127, 17, 171, 127, 17, + 178, 127, 31, 199, 95, 127, 31, 234, 127, 127, 31, 197, 37, 127, 31, 198, + 251, 127, 31, 232, 122, 127, 31, 233, 19, 127, 31, 202, 130, 127, 31, + 203, 244, 127, 31, 234, 161, 127, 31, 213, 171, 127, 31, 197, 32, 17, 91, + 232, 80, 201, 63, 17, 105, 232, 80, 201, 63, 17, 115, 232, 80, 201, 63, + 17, 232, 128, 232, 80, 201, 63, 17, 232, 226, 232, 80, 201, 63, 17, 202, + 136, 232, 80, 201, 63, 17, 203, 247, 232, 80, 201, 63, 17, 234, 164, 232, + 80, 201, 63, 17, 213, 175, 232, 80, 201, 63, 31, 199, 96, 232, 80, 201, + 63, 31, 234, 128, 232, 80, 201, 63, 31, 197, 38, 232, 80, 201, 63, 31, + 198, 252, 232, 80, 201, 63, 31, 232, 123, 232, 80, 201, 63, 31, 233, 20, + 232, 80, 201, 63, 31, 202, 131, 232, 80, 201, 63, 31, 203, 245, 232, 80, + 201, 63, 31, 234, 162, 232, 80, 201, 63, 31, 213, 172, 232, 80, 201, 63, + 31, 197, 33, 232, 80, 201, 63, 127, 8, 2, 1, 65, 127, 8, 2, 1, 250, 120, + 127, 8, 2, 1, 247, 193, 127, 8, 2, 1, 238, 127, 127, 8, 2, 1, 71, 127, 8, + 2, 1, 233, 175, 127, 8, 2, 1, 232, 51, 127, 8, 2, 1, 230, 116, 127, 8, 2, + 1, 68, 127, 8, 2, 1, 223, 35, 127, 8, 2, 1, 222, 152, 127, 8, 2, 1, 172, + 127, 8, 2, 1, 218, 168, 127, 8, 2, 1, 215, 61, 127, 8, 2, 1, 74, 127, 8, + 2, 1, 210, 236, 127, 8, 2, 1, 208, 104, 127, 8, 2, 1, 146, 127, 8, 2, 1, + 206, 8, 127, 8, 2, 1, 200, 43, 127, 8, 2, 1, 66, 127, 8, 2, 1, 196, 12, + 127, 8, 2, 1, 193, 224, 127, 8, 2, 1, 192, 235, 127, 8, 2, 1, 192, 159, + 127, 8, 2, 1, 191, 166, 47, 8, 6, 1, 65, 47, 8, 6, 1, 250, 120, 47, 8, 6, + 1, 247, 193, 47, 8, 6, 1, 238, 127, 47, 8, 6, 1, 71, 47, 8, 6, 1, 233, + 175, 47, 8, 6, 1, 232, 51, 47, 8, 6, 1, 230, 116, 47, 8, 6, 1, 68, 47, 8, + 6, 1, 223, 35, 47, 8, 6, 1, 222, 152, 47, 8, 6, 1, 172, 47, 8, 6, 1, 218, + 168, 47, 8, 6, 1, 215, 61, 47, 8, 6, 1, 74, 47, 8, 6, 1, 210, 236, 47, 8, + 6, 1, 208, 104, 47, 8, 6, 1, 146, 47, 8, 6, 1, 206, 8, 47, 8, 6, 1, 200, + 43, 47, 8, 6, 1, 66, 47, 8, 6, 1, 196, 12, 47, 8, 6, 1, 193, 224, 47, 8, + 6, 1, 192, 235, 47, 8, 6, 1, 192, 159, 47, 8, 6, 1, 191, 166, 47, 8, 2, + 1, 65, 47, 8, 2, 1, 250, 120, 47, 8, 2, 1, 247, 193, 47, 8, 2, 1, 238, + 127, 47, 8, 2, 1, 71, 47, 8, 2, 1, 233, 175, 47, 8, 2, 1, 232, 51, 47, 8, + 2, 1, 230, 116, 47, 8, 2, 1, 68, 47, 8, 2, 1, 223, 35, 47, 8, 2, 1, 222, + 152, 47, 8, 2, 1, 172, 47, 8, 2, 1, 218, 168, 47, 8, 2, 1, 215, 61, 47, + 8, 2, 1, 74, 47, 8, 2, 1, 210, 236, 47, 8, 2, 1, 208, 104, 47, 8, 2, 1, + 146, 47, 8, 2, 1, 206, 8, 47, 8, 2, 1, 200, 43, 47, 8, 2, 1, 66, 47, 8, + 2, 1, 196, 12, 47, 8, 2, 1, 193, 224, 47, 8, 2, 1, 192, 235, 47, 8, 2, 1, + 192, 159, 47, 8, 2, 1, 191, 166, 47, 17, 191, 77, 214, 106, 47, 31, 234, + 127, 214, 106, 47, 31, 197, 37, 214, 106, 47, 31, 198, 251, 214, 106, 47, + 31, 232, 122, 214, 106, 47, 31, 233, 19, 214, 106, 47, 31, 202, 130, 214, + 106, 47, 31, 203, 244, 214, 106, 47, 31, 234, 161, 214, 106, 47, 31, 213, + 171, 214, 106, 47, 31, 197, 32, 55, 47, 17, 107, 55, 47, 17, 109, 55, 47, + 17, 138, 55, 47, 17, 134, 55, 47, 17, 149, 55, 47, 17, 169, 55, 47, 17, + 175, 55, 47, 17, 171, 55, 47, 17, 178, 55, 47, 31, 199, 95, 214, 106, 47, + 17, 191, 77, 111, 122, 156, 228, 240, 111, 122, 88, 228, 240, 111, 122, + 156, 195, 135, 111, 122, 88, 195, 135, 111, 122, 156, 197, 225, 237, 216, + 228, 240, 111, 122, 88, 197, 225, 237, 216, 228, 240, 111, 122, 156, 197, + 225, 237, 216, 195, 135, 111, 122, 88, 197, 225, 237, 216, 195, 135, 111, + 122, 156, 208, 26, 237, 216, 228, 240, 111, 122, 88, 208, 26, 237, 216, + 228, 240, 111, 122, 156, 208, 26, 237, 216, 195, 135, 111, 122, 88, 208, + 26, 237, 216, 195, 135, 111, 122, 156, 144, 23, 183, 111, 122, 144, 156, + 23, 50, 229, 217, 111, 122, 144, 88, 23, 50, 219, 132, 111, 122, 88, 144, + 23, 183, 111, 122, 156, 144, 23, 219, 224, 111, 122, 144, 156, 23, 45, + 229, 217, 111, 122, 144, 88, 23, 45, 219, 132, 111, 122, 88, 144, 23, + 219, 224, 111, 122, 156, 133, 23, 183, 111, 122, 133, 156, 23, 50, 229, + 217, 111, 122, 133, 88, 23, 50, 219, 132, 111, 122, 88, 133, 23, 183, + 111, 122, 156, 133, 23, 219, 224, 111, 122, 133, 156, 23, 45, 229, 217, + 111, 122, 133, 88, 23, 45, 219, 132, 111, 122, 88, 133, 23, 219, 224, + 111, 122, 156, 81, 23, 183, 111, 122, 81, 156, 23, 50, 229, 217, 111, + 122, 133, 88, 23, 50, 144, 219, 132, 111, 122, 144, 88, 23, 50, 133, 219, + 132, 111, 122, 81, 88, 23, 50, 219, 132, 111, 122, 144, 156, 23, 50, 133, + 229, 217, 111, 122, 133, 156, 23, 50, 144, 229, 217, 111, 122, 88, 81, + 23, 183, 111, 122, 156, 81, 23, 219, 224, 111, 122, 81, 156, 23, 45, 229, + 217, 111, 122, 133, 88, 23, 45, 144, 219, 132, 111, 122, 144, 88, 23, 45, + 133, 219, 132, 111, 122, 81, 88, 23, 45, 219, 132, 111, 122, 144, 156, + 23, 45, 133, 229, 217, 111, 122, 133, 156, 23, 45, 144, 229, 217, 111, + 122, 88, 81, 23, 219, 224, 111, 122, 156, 144, 23, 228, 240, 111, 122, + 45, 88, 23, 50, 144, 219, 132, 111, 122, 50, 88, 23, 45, 144, 219, 132, + 111, 122, 144, 156, 23, 228, 241, 229, 217, 111, 122, 144, 88, 23, 228, + 241, 219, 132, 111, 122, 50, 156, 23, 45, 144, 229, 217, 111, 122, 45, + 156, 23, 50, 144, 229, 217, 111, 122, 88, 144, 23, 228, 240, 111, 122, + 156, 133, 23, 228, 240, 111, 122, 45, 88, 23, 50, 133, 219, 132, 111, + 122, 50, 88, 23, 45, 133, 219, 132, 111, 122, 133, 156, 23, 228, 241, + 229, 217, 111, 122, 133, 88, 23, 228, 241, 219, 132, 111, 122, 50, 156, + 23, 45, 133, 229, 217, 111, 122, 45, 156, 23, 50, 133, 229, 217, 111, + 122, 88, 133, 23, 228, 240, 111, 122, 156, 81, 23, 228, 240, 111, 122, + 45, 88, 23, 50, 81, 219, 132, 111, 122, 50, 88, 23, 45, 81, 219, 132, + 111, 122, 81, 156, 23, 228, 241, 229, 217, 111, 122, 133, 88, 23, 144, + 228, 241, 219, 132, 111, 122, 144, 88, 23, 133, 228, 241, 219, 132, 111, + 122, 81, 88, 23, 228, 241, 219, 132, 111, 122, 45, 133, 88, 23, 50, 144, + 219, 132, 111, 122, 50, 133, 88, 23, 45, 144, 219, 132, 111, 122, 45, + 144, 88, 23, 50, 133, 219, 132, 111, 122, 50, 144, 88, 23, 45, 133, 219, + 132, 111, 122, 144, 156, 23, 133, 228, 241, 229, 217, 111, 122, 133, 156, + 23, 144, 228, 241, 229, 217, 111, 122, 50, 156, 23, 45, 81, 229, 217, + 111, 122, 45, 156, 23, 50, 81, 229, 217, 111, 122, 88, 81, 23, 228, 240, + 111, 122, 156, 55, 237, 216, 228, 240, 111, 122, 88, 55, 237, 216, 228, + 240, 111, 122, 156, 55, 237, 216, 195, 135, 111, 122, 88, 55, 237, 216, + 195, 135, 111, 122, 55, 228, 240, 111, 122, 55, 195, 135, 111, 122, 144, + 202, 170, 23, 50, 235, 133, 111, 122, 144, 55, 23, 50, 202, 169, 111, + 122, 55, 144, 23, 183, 111, 122, 144, 202, 170, 23, 45, 235, 133, 111, + 122, 144, 55, 23, 45, 202, 169, 111, 122, 55, 144, 23, 219, 224, 111, + 122, 133, 202, 170, 23, 50, 235, 133, 111, 122, 133, 55, 23, 50, 202, + 169, 111, 122, 55, 133, 23, 183, 111, 122, 133, 202, 170, 23, 45, 235, + 133, 111, 122, 133, 55, 23, 45, 202, 169, 111, 122, 55, 133, 23, 219, + 224, 111, 122, 81, 202, 170, 23, 50, 235, 133, 111, 122, 81, 55, 23, 50, + 202, 169, 111, 122, 55, 81, 23, 183, 111, 122, 81, 202, 170, 23, 45, 235, + 133, 111, 122, 81, 55, 23, 45, 202, 169, 111, 122, 55, 81, 23, 219, 224, + 111, 122, 144, 202, 170, 23, 228, 241, 235, 133, 111, 122, 144, 55, 23, + 228, 241, 202, 169, 111, 122, 55, 144, 23, 228, 240, 111, 122, 133, 202, + 170, 23, 228, 241, 235, 133, 111, 122, 133, 55, 23, 228, 241, 202, 169, + 111, 122, 55, 133, 23, 228, 240, 111, 122, 81, 202, 170, 23, 228, 241, + 235, 133, 111, 122, 81, 55, 23, 228, 241, 202, 169, 111, 122, 55, 81, 23, + 228, 240, 111, 122, 156, 251, 17, 144, 23, 183, 111, 122, 156, 251, 17, + 144, 23, 219, 224, 111, 122, 156, 251, 17, 133, 23, 219, 224, 111, 122, + 156, 251, 17, 133, 23, 183, 111, 122, 156, 237, 39, 116, 50, 119, 110, + 219, 224, 111, 122, 156, 237, 39, 116, 45, 119, 110, 183, 111, 122, 156, + 237, 39, 238, 217, 111, 122, 156, 219, 224, 111, 122, 156, 196, 77, 111, + 122, 156, 183, 111, 122, 156, 235, 123, 111, 122, 88, 219, 224, 111, 122, + 88, 196, 77, 111, 122, 88, 183, 111, 122, 88, 235, 123, 111, 122, 156, + 45, 23, 88, 183, 111, 122, 156, 133, 23, 88, 235, 123, 111, 122, 88, 45, + 23, 156, 183, 111, 122, 88, 133, 23, 156, 235, 123, 116, 132, 248, 129, + 110, 91, 234, 160, 248, 129, 110, 91, 208, 23, 248, 129, 110, 115, 234, + 158, 248, 129, 110, 132, 248, 129, 110, 232, 226, 234, 158, 248, 129, + 110, 115, 208, 21, 248, 129, 110, 203, 247, 234, 158, 248, 129, 232, 80, + 248, 129, 45, 203, 247, 234, 158, 248, 129, 45, 115, 208, 21, 248, 129, + 45, 232, 226, 234, 158, 248, 129, 45, 132, 248, 129, 45, 115, 234, 158, + 248, 129, 45, 91, 208, 23, 248, 129, 45, 91, 234, 160, 248, 129, 50, 132, + 248, 129, 156, 203, 153, 216, 213, 203, 153, 237, 221, 203, 153, 116, 91, + 234, 160, 248, 129, 50, 91, 234, 160, 248, 129, 208, 28, 110, 219, 224, + 208, 28, 110, 183, 208, 28, 116, 219, 224, 208, 28, 116, 45, 23, 110, 45, + 23, 110, 183, 208, 28, 116, 45, 23, 110, 183, 208, 28, 116, 45, 23, 116, + 50, 23, 110, 219, 224, 208, 28, 116, 45, 23, 116, 50, 23, 110, 183, 208, + 28, 116, 183, 208, 28, 116, 50, 23, 110, 219, 224, 208, 28, 116, 50, 23, + 110, 45, 23, 110, 183, 62, 201, 190, 63, 201, 190, 63, 51, 4, 206, 113, + 239, 0, 63, 51, 239, 33, 62, 2, 201, 190, 51, 4, 228, 241, 233, 5, 51, 4, + 81, 233, 5, 51, 4, 211, 38, 238, 211, 233, 5, 51, 4, 116, 45, 119, 110, + 50, 233, 5, 51, 4, 116, 50, 119, 110, 45, 233, 5, 51, 4, 237, 39, 238, + 211, 233, 5, 62, 2, 201, 190, 63, 2, 201, 190, 62, 207, 92, 63, 207, 92, + 62, 81, 207, 92, 63, 81, 207, 92, 62, 210, 117, 63, 210, 117, 62, 196, + 76, 197, 241, 63, 196, 76, 197, 241, 62, 196, 76, 2, 197, 241, 63, 196, + 76, 2, 197, 241, 62, 206, 203, 197, 241, 63, 206, 203, 197, 241, 62, 206, + 203, 2, 197, 241, 63, 206, 203, 2, 197, 241, 62, 206, 203, 209, 59, 63, + 206, 203, 209, 59, 62, 235, 122, 197, 241, 63, 235, 122, 197, 241, 62, + 235, 122, 2, 197, 241, 63, 235, 122, 2, 197, 241, 62, 219, 219, 197, 241, + 63, 219, 219, 197, 241, 62, 219, 219, 2, 197, 241, 63, 219, 219, 2, 197, + 241, 62, 219, 219, 209, 59, 63, 219, 219, 209, 59, 62, 237, 32, 63, 237, + 32, 63, 237, 33, 239, 33, 62, 2, 237, 32, 232, 235, 218, 232, 63, 243, + 10, 235, 138, 243, 10, 243, 11, 4, 81, 233, 5, 247, 244, 62, 243, 10, + 243, 11, 4, 45, 132, 248, 139, 243, 11, 4, 50, 132, 248, 139, 243, 11, 4, + 110, 132, 248, 139, 243, 11, 4, 116, 132, 248, 139, 243, 11, 4, 116, 50, + 208, 28, 248, 139, 243, 11, 4, 251, 175, 247, 218, 116, 45, 208, 28, 248, + 139, 45, 132, 62, 243, 10, 50, 132, 62, 243, 10, 223, 95, 247, 248, 223, + 95, 63, 243, 10, 116, 132, 223, 95, 63, 243, 10, 110, 132, 223, 95, 63, + 243, 10, 116, 45, 208, 28, 243, 4, 251, 16, 116, 50, 208, 28, 243, 4, + 251, 16, 110, 50, 208, 28, 243, 4, 251, 16, 110, 45, 208, 28, 243, 4, + 251, 16, 116, 132, 243, 10, 110, 132, 243, 10, 62, 110, 50, 197, 241, 62, + 110, 45, 197, 241, 62, 116, 45, 197, 241, 62, 116, 50, 197, 241, 63, 247, + 248, 51, 4, 45, 132, 248, 139, 51, 4, 50, 132, 248, 139, 51, 4, 116, 45, + 237, 39, 132, 248, 139, 51, 4, 110, 50, 237, 39, 132, 248, 139, 63, 51, + 4, 81, 248, 154, 219, 112, 63, 196, 76, 197, 242, 4, 236, 140, 196, 76, + 197, 242, 4, 45, 132, 248, 139, 196, 76, 197, 242, 4, 50, 132, 248, 139, + 220, 13, 243, 10, 63, 51, 4, 116, 45, 208, 27, 63, 51, 4, 110, 45, 208, + 27, 63, 51, 4, 110, 50, 208, 27, 63, 51, 4, 116, 50, 208, 27, 63, 243, + 11, 4, 116, 45, 208, 27, 63, 243, 11, 4, 110, 45, 208, 27, 63, 243, 11, + 4, 110, 50, 208, 27, 63, 243, 11, 4, 116, 50, 208, 27, 116, 45, 197, 241, + 116, 50, 197, 241, 110, 45, 197, 241, 63, 216, 213, 201, 190, 62, 216, + 213, 201, 190, 63, 216, 213, 2, 201, 190, 62, 216, 213, 2, 201, 190, 110, + 50, 197, 241, 62, 200, 199, 4, 207, 119, 242, 210, 196, 117, 202, 48, + 242, 77, 62, 201, 102, 63, 201, 102, 219, 129, 198, 208, 200, 198, 250, + 213, 213, 35, 237, 86, 213, 35, 239, 42, 211, 62, 62, 199, 106, 63, 199, + 106, 249, 107, 248, 62, 249, 107, 111, 4, 243, 125, 249, 107, 111, 4, + 192, 235, 205, 154, 196, 118, 4, 207, 150, 235, 96, 228, 181, 248, 207, + 63, 203, 49, 209, 175, 62, 203, 49, 209, 175, 203, 140, 207, 18, 206, + 122, 232, 190, 229, 224, 247, 248, 62, 45, 209, 58, 223, 148, 62, 50, + 209, 58, 223, 148, 63, 45, 209, 58, 223, 148, 63, 133, 209, 58, 223, 148, + 63, 50, 209, 58, 223, 148, 63, 144, 209, 58, 223, 148, 202, 104, 23, 238, + 215, 247, 71, 56, 207, 164, 56, 248, 162, 56, 247, 151, 251, 99, 211, 39, + 238, 217, 243, 96, 207, 3, 238, 218, 79, 218, 255, 238, 218, 79, 222, + 254, 201, 103, 23, 238, 227, 233, 74, 113, 252, 34, 203, 143, 230, 62, + 23, 202, 213, 210, 61, 113, 192, 22, 192, 106, 197, 231, 40, 229, 219, + 197, 231, 40, 220, 43, 197, 231, 40, 232, 243, 197, 231, 40, 198, 209, + 197, 231, 40, 193, 66, 197, 231, 40, 193, 143, 197, 231, 40, 215, 184, + 197, 231, 40, 234, 207, 193, 94, 79, 237, 60, 63, 232, 92, 233, 103, 63, + 202, 64, 233, 103, 62, 202, 64, 233, 103, 63, 200, 199, 4, 207, 119, 232, + 238, 208, 23, 215, 205, 220, 6, 208, 23, 215, 205, 216, 180, 233, 42, 56, + 234, 207, 217, 97, 56, 222, 167, 205, 115, 196, 57, 214, 94, 209, 77, + 251, 2, 199, 164, 231, 152, 247, 124, 219, 186, 195, 38, 219, 143, 205, + 80, 205, 183, 247, 106, 251, 34, 209, 120, 63, 243, 105, 221, 138, 63, + 243, 105, 208, 14, 63, 243, 105, 206, 131, 63, 243, 105, 248, 152, 63, + 243, 105, 221, 76, 63, 243, 105, 210, 74, 62, 243, 105, 221, 138, 62, + 243, 105, 208, 14, 62, 243, 105, 206, 131, 62, 243, 105, 248, 152, 62, + 243, 105, 221, 76, 62, 243, 105, 210, 74, 62, 201, 245, 200, 211, 63, + 229, 224, 200, 211, 63, 237, 33, 200, 211, 62, 242, 207, 200, 211, 63, + 201, 245, 200, 211, 62, 229, 224, 200, 211, 62, 237, 33, 200, 211, 63, + 242, 207, 200, 211, 228, 181, 201, 195, 208, 23, 213, 6, 234, 160, 213, + 6, 249, 13, 234, 160, 213, 1, 249, 13, 202, 129, 213, 1, 215, 97, 232, + 207, 56, 215, 97, 214, 206, 56, 215, 97, 203, 127, 56, 193, 105, 200, 63, + 238, 217, 234, 204, 200, 63, 238, 217, 196, 87, 207, 88, 113, 207, 88, + 16, 40, 196, 254, 209, 98, 207, 88, 16, 40, 196, 252, 209, 98, 207, 88, + 16, 40, 196, 251, 209, 98, 207, 88, 16, 40, 196, 249, 209, 98, 207, 88, + 16, 40, 196, 247, 209, 98, 207, 88, 16, 40, 196, 245, 209, 98, 207, 88, + 16, 40, 196, 243, 209, 98, 207, 88, 16, 40, 231, 149, 217, 28, 62, 196, + 87, 207, 88, 113, 207, 89, 210, 136, 113, 210, 104, 210, 136, 113, 210, + 3, 210, 136, 56, 193, 92, 113, 237, 25, 233, 102, 237, 25, 233, 101, 237, + 25, 233, 100, 237, 25, 233, 99, 237, 25, 233, 98, 237, 25, 233, 97, 63, + 243, 11, 4, 75, 183, 63, 243, 11, 4, 105, 236, 138, 62, 243, 11, 4, 63, + 75, 183, 62, 243, 11, 4, 105, 63, 236, 138, 215, 221, 40, 192, 106, 215, + 221, 40, 192, 21, 237, 6, 40, 230, 205, 192, 106, 237, 6, 40, 219, 178, + 192, 21, 237, 6, 40, 219, 178, 192, 106, 237, 6, 40, 230, 205, 192, 21, + 63, 232, 217, 62, 232, 217, 230, 62, 23, 209, 180, 251, 127, 238, 214, + 200, 130, 201, 112, 79, 252, 8, 205, 98, 251, 191, 232, 186, 231, 162, + 201, 112, 79, 229, 191, 250, 172, 113, 232, 202, 211, 10, 63, 201, 102, + 115, 219, 107, 239, 19, 183, 115, 219, 107, 239, 19, 219, 224, 193, 155, + 56, 137, 195, 12, 56, 235, 128, 233, 42, 56, 235, 128, 217, 97, 56, 223, + 105, 233, 42, 23, 217, 97, 56, 217, 97, 23, 233, 42, 56, 217, 97, 4, 201, + 28, 56, 217, 97, 4, 201, 28, 23, 217, 97, 23, 233, 42, 56, 81, 217, 97, + 4, 201, 28, 56, 228, 241, 217, 97, 4, 201, 28, 56, 216, 213, 63, 243, 10, + 216, 213, 62, 243, 10, 216, 213, 2, 63, 243, 10, 217, 48, 113, 236, 198, + 113, 196, 84, 210, 103, 113, 242, 89, 232, 74, 196, 53, 214, 83, 247, 7, + 210, 185, 222, 173, 195, 80, 243, 75, 62, 215, 206, 219, 126, 203, 176, + 204, 22, 208, 4, 203, 255, 202, 36, 249, 111, 249, 73, 112, 221, 222, 63, + 235, 108, 217, 90, 63, 235, 108, 221, 138, 62, 235, 108, 217, 90, 62, + 235, 108, 221, 138, 202, 49, 193, 51, 202, 52, 200, 199, 248, 242, 242, + 210, 207, 149, 62, 202, 48, 198, 210, 242, 211, 23, 207, 149, 153, 63, + 203, 49, 209, 175, 153, 62, 203, 49, 209, 175, 63, 237, 33, 223, 163, + 201, 190, 238, 210, 220, 21, 236, 229, 247, 102, 211, 65, 209, 180, 247, + 103, 202, 85, 229, 201, 4, 63, 238, 217, 47, 238, 210, 220, 21, 246, 253, + 213, 44, 234, 72, 251, 157, 211, 96, 45, 193, 129, 198, 19, 62, 197, 10, + 45, 193, 129, 198, 19, 63, 197, 10, 45, 193, 129, 198, 19, 62, 45, 220, + 22, 216, 179, 63, 45, 220, 22, 216, 179, 235, 103, 202, 76, 56, 88, 63, + 235, 122, 197, 241, 45, 242, 219, 234, 72, 112, 205, 154, 233, 83, 237, + 39, 223, 163, 63, 243, 11, 223, 163, 62, 201, 190, 62, 197, 203, 207, 29, + 45, 234, 71, 207, 29, 45, 234, 70, 250, 187, 16, 40, 196, 57, 88, 243, + 11, 4, 201, 28, 23, 105, 185, 58, 210, 23, 206, 205, 223, 107, 210, 23, + 219, 221, 223, 107, 210, 23, 223, 93, 210, 23, 62, 238, 218, 211, 105, + 203, 78, 203, 66, 203, 12, 243, 40, 247, 80, 229, 118, 202, 137, 231, + 163, 193, 51, 228, 153, 231, 163, 4, 230, 30, 217, 72, 16, 40, 219, 131, + 215, 184, 196, 118, 211, 105, 230, 188, 232, 129, 232, 218, 223, 163, + 229, 5, 233, 32, 205, 178, 51, 232, 128, 239, 0, 202, 108, 228, 27, 202, + 112, 209, 251, 4, 249, 111, 199, 87, 223, 19, 249, 93, 113, 229, 229, + 230, 207, 113, 232, 83, 208, 153, 238, 182, 211, 105, 62, 201, 190, 63, + 232, 218, 4, 228, 241, 82, 62, 201, 29, 62, 205, 188, 205, 84, 116, 248, + 134, 205, 84, 62, 205, 84, 110, 248, 134, 205, 84, 63, 205, 84, 63, 88, + 243, 126, 77, 199, 107, 219, 40, 56, 199, 182, 235, 102, 251, 223, 234, + 67, 207, 147, 232, 231, 207, 147, 230, 53, 195, 67, 230, 53, 193, 3, 230, + 53, 110, 50, 210, 33, 210, 33, 116, 50, 210, 33, 63, 213, 208, 62, 213, + 208, 243, 126, 77, 88, 243, 126, 77, 215, 127, 192, 235, 88, 215, 127, + 192, 235, 249, 107, 192, 235, 88, 249, 107, 192, 235, 211, 10, 35, 238, + 217, 88, 35, 238, 217, 211, 77, 247, 22, 238, 217, 88, 211, 77, 247, 22, + 238, 217, 8, 238, 217, 203, 151, 63, 8, 238, 217, 211, 10, 8, 238, 217, + 217, 93, 238, 217, 201, 103, 79, 237, 208, 232, 128, 199, 127, 250, 193, + 232, 128, 249, 108, 250, 193, 88, 232, 128, 249, 108, 250, 193, 232, 128, + 242, 205, 250, 193, 62, 232, 128, 209, 60, 201, 102, 63, 232, 128, 209, + 60, 201, 102, 201, 240, 201, 38, 211, 10, 63, 201, 102, 47, 63, 201, 102, + 211, 77, 247, 22, 62, 201, 102, 62, 247, 22, 63, 201, 102, 211, 10, 62, + 201, 102, 88, 211, 10, 62, 201, 102, 209, 130, 201, 102, 203, 151, 63, + 201, 102, 88, 250, 193, 211, 77, 247, 22, 250, 193, 234, 164, 201, 206, + 250, 193, 234, 164, 209, 60, 62, 201, 102, 234, 164, 209, 60, 209, 130, + 201, 102, 202, 136, 209, 60, 62, 201, 102, 234, 164, 209, 60, 207, 90, + 62, 201, 102, 88, 234, 164, 209, 60, 207, 90, 62, 201, 102, 197, 38, 209, + 60, 62, 201, 102, 202, 131, 209, 60, 250, 193, 199, 127, 250, 193, 211, + 77, 247, 22, 199, 127, 250, 193, 88, 199, 127, 250, 193, 202, 136, 209, + 239, 62, 23, 63, 232, 189, 62, 232, 189, 63, 232, 189, 234, 164, 209, + 239, 211, 10, 62, 232, 189, 47, 211, 77, 247, 22, 234, 164, 209, 60, 201, + 102, 88, 199, 127, 209, 130, 250, 193, 202, 50, 198, 172, 197, 234, 202, + 50, 88, 243, 101, 202, 50, 201, 242, 88, 201, 242, 249, 108, 250, 193, + 234, 164, 199, 127, 208, 189, 250, 193, 88, 234, 164, 199, 127, 208, 189, + 250, 193, 238, 218, 77, 203, 151, 63, 243, 10, 214, 106, 112, 238, 218, + 77, 110, 50, 235, 98, 63, 201, 190, 116, 50, 235, 98, 63, 201, 190, 110, + 50, 203, 151, 63, 201, 190, 116, 50, 203, 151, 63, 201, 190, 62, 208, 13, + 87, 211, 42, 63, 208, 13, 87, 211, 42, 63, 233, 216, 87, 211, 42, 62, + 237, 33, 216, 35, 63, 192, 235, 88, 233, 216, 87, 113, 156, 81, 164, 216, + 213, 81, 164, 88, 81, 164, 88, 202, 170, 153, 242, 75, 207, 252, 87, 211, + 42, 88, 202, 170, 242, 75, 207, 252, 87, 211, 42, 88, 55, 153, 242, 75, + 207, 252, 87, 211, 42, 88, 55, 242, 75, 207, 252, 87, 211, 42, 88, 130, + 202, 170, 242, 75, 207, 252, 87, 211, 42, 88, 130, 55, 242, 75, 207, 252, + 87, 211, 42, 238, 163, 201, 81, 210, 128, 3, 211, 42, 88, 233, 216, 87, + 211, 42, 88, 229, 224, 233, 216, 87, 211, 42, 88, 62, 229, 223, 206, 122, + 88, 62, 229, 224, 247, 248, 232, 190, 229, 223, 206, 122, 232, 190, 229, + 224, 247, 248, 216, 213, 45, 210, 114, 211, 42, 216, 213, 50, 210, 114, + 211, 42, 216, 213, 232, 203, 45, 210, 114, 211, 42, 216, 213, 232, 203, + 50, 210, 114, 211, 42, 216, 213, 219, 219, 251, 116, 248, 54, 211, 42, + 216, 213, 206, 203, 251, 116, 248, 54, 211, 42, 88, 219, 219, 251, 116, + 207, 252, 87, 211, 42, 88, 206, 203, 251, 116, 207, 252, 87, 211, 42, 88, + 219, 219, 251, 116, 248, 54, 211, 42, 88, 206, 203, 251, 116, 248, 54, + 211, 42, 156, 45, 198, 42, 203, 103, 248, 54, 211, 42, 156, 50, 198, 42, + 203, 103, 248, 54, 211, 42, 216, 213, 45, 238, 171, 248, 54, 211, 42, + 216, 213, 50, 238, 171, 248, 54, 211, 42, 236, 241, 214, 106, 47, 17, + 107, 236, 241, 214, 106, 47, 17, 109, 236, 241, 214, 106, 47, 17, 138, + 236, 241, 214, 106, 47, 17, 134, 236, 241, 214, 106, 47, 17, 149, 236, + 241, 214, 106, 47, 17, 169, 236, 241, 214, 106, 47, 17, 175, 236, 241, + 214, 106, 47, 17, 171, 236, 241, 214, 106, 47, 17, 178, 236, 241, 214, + 106, 47, 31, 199, 95, 236, 241, 47, 49, 17, 107, 236, 241, 47, 49, 17, + 109, 236, 241, 47, 49, 17, 138, 236, 241, 47, 49, 17, 134, 236, 241, 47, + 49, 17, 149, 236, 241, 47, 49, 17, 169, 236, 241, 47, 49, 17, 175, 236, + 241, 47, 49, 17, 171, 236, 241, 47, 49, 17, 178, 236, 241, 47, 49, 31, + 199, 95, 236, 241, 214, 106, 47, 49, 17, 107, 236, 241, 214, 106, 47, 49, + 17, 109, 236, 241, 214, 106, 47, 49, 17, 138, 236, 241, 214, 106, 47, 49, + 17, 134, 236, 241, 214, 106, 47, 49, 17, 149, 236, 241, 214, 106, 47, 49, + 17, 169, 236, 241, 214, 106, 47, 49, 17, 175, 236, 241, 214, 106, 47, 49, + 17, 171, 236, 241, 214, 106, 47, 49, 17, 178, 236, 241, 214, 106, 47, 49, + 31, 199, 95, 88, 193, 77, 96, 57, 88, 108, 56, 88, 216, 35, 56, 88, 236, + 200, 56, 88, 202, 2, 234, 204, 57, 88, 96, 57, 88, 186, 234, 204, 57, + 235, 113, 209, 62, 96, 57, 88, 206, 114, 96, 57, 197, 240, 96, 57, 88, + 197, 240, 96, 57, 237, 214, 197, 240, 96, 57, 88, 237, 214, 197, 240, 96, + 57, 62, 96, 57, 198, 225, 198, 52, 96, 250, 235, 198, 225, 248, 75, 96, + 250, 235, 62, 96, 250, 235, 88, 62, 238, 163, 235, 119, 23, 96, 57, 88, + 62, 238, 163, 196, 66, 23, 96, 57, 201, 187, 62, 96, 57, 88, 239, 56, 62, + 96, 57, 206, 202, 63, 96, 57, 219, 218, 63, 96, 57, 249, 145, 203, 151, + 63, 96, 57, 232, 95, 203, 151, 63, 96, 57, 88, 110, 206, 201, 63, 96, 57, + 88, 116, 206, 201, 63, 96, 57, 213, 8, 110, 206, 201, 63, 96, 57, 238, + 171, 219, 4, 213, 8, 116, 206, 201, 63, 96, 57, 47, 88, 63, 96, 57, 193, + 88, 96, 57, 248, 138, 202, 2, 234, 204, 57, 248, 138, 96, 57, 248, 138, + 186, 234, 204, 57, 88, 248, 138, 202, 2, 234, 204, 57, 88, 248, 138, 96, + 57, 88, 248, 138, 186, 234, 204, 57, 199, 129, 96, 57, 88, 199, 128, 96, + 57, 193, 115, 96, 57, 88, 193, 115, 96, 57, 211, 71, 96, 57, 55, 238, + 171, 219, 4, 115, 236, 251, 251, 115, 63, 197, 242, 239, 33, 2, 63, 197, + 241, 209, 254, 211, 77, 200, 228, 211, 77, 200, 180, 45, 206, 7, 249, + 131, 237, 112, 50, 206, 7, 249, 131, 237, 112, 211, 57, 4, 75, 223, 117, + 207, 19, 202, 24, 208, 230, 200, 228, 200, 181, 208, 230, 202, 23, 81, + 249, 88, 4, 228, 241, 106, 13, 206, 180, 237, 38, 179, 236, 199, 13, 233, + 83, 237, 38, 112, 219, 29, 251, 125, 112, 219, 29, 211, 56, 63, 237, 33, + 4, 247, 20, 236, 140, 23, 4, 236, 140, 234, 132, 79, 211, 69, 196, 65, + 110, 50, 239, 2, 4, 236, 140, 116, 45, 239, 2, 4, 236, 140, 45, 211, 12, + 222, 199, 50, 211, 12, 222, 199, 232, 80, 211, 12, 222, 199, 220, 13, + 133, 199, 228, 220, 13, 144, 199, 228, 45, 23, 50, 55, 197, 57, 45, 23, + 50, 199, 228, 45, 215, 131, 179, 50, 199, 228, 179, 45, 199, 228, 133, + 199, 229, 4, 243, 11, 58, 218, 233, 236, 206, 247, 205, 228, 241, 206, + 52, 63, 239, 55, 237, 32, 63, 239, 55, 237, 33, 4, 118, 198, 182, 63, + 239, 55, 237, 33, 4, 96, 198, 182, 63, 51, 4, 118, 198, 182, 63, 51, 4, + 96, 198, 182, 13, 45, 63, 51, 248, 53, 13, 50, 63, 51, 248, 53, 13, 45, + 251, 116, 248, 53, 13, 50, 251, 116, 248, 53, 13, 45, 55, 251, 116, 248, + 53, 13, 50, 55, 251, 116, 248, 53, 13, 45, 63, 198, 42, 203, 103, 248, + 53, 13, 50, 63, 198, 42, 203, 103, 248, 53, 13, 45, 232, 203, 210, 113, + 13, 50, 232, 203, 210, 113, 196, 66, 208, 26, 57, 235, 119, 208, 26, 57, + 251, 85, 231, 202, 243, 11, 57, 242, 221, 231, 202, 243, 11, 57, 50, 64, + 4, 47, 209, 81, 179, 118, 57, 179, 96, 57, 179, 45, 50, 57, 179, 118, 55, + 57, 179, 96, 55, 57, 179, 45, 50, 55, 57, 179, 118, 64, 232, 98, 164, + 179, 96, 64, 232, 98, 164, 179, 118, 55, 64, 232, 98, 164, 179, 96, 55, + 64, 232, 98, 164, 179, 96, 201, 183, 57, 69, 70, 248, 132, 69, 70, 236, + 137, 69, 70, 236, 9, 69, 70, 236, 136, 69, 70, 235, 201, 69, 70, 236, 72, + 69, 70, 236, 8, 69, 70, 236, 135, 69, 70, 235, 169, 69, 70, 236, 40, 69, + 70, 235, 232, 69, 70, 236, 103, 69, 70, 235, 200, 69, 70, 236, 71, 69, + 70, 236, 7, 69, 70, 236, 134, 69, 70, 235, 153, 69, 70, 236, 24, 69, 70, + 235, 216, 69, 70, 236, 87, 69, 70, 235, 184, 69, 70, 236, 55, 69, 70, + 235, 247, 69, 70, 236, 118, 69, 70, 235, 168, 69, 70, 236, 39, 69, 70, + 235, 231, 69, 70, 236, 102, 69, 70, 235, 199, 69, 70, 236, 70, 69, 70, + 236, 6, 69, 70, 236, 133, 69, 70, 235, 145, 69, 70, 236, 16, 69, 70, 235, + 208, 69, 70, 236, 79, 69, 70, 235, 176, 69, 70, 236, 47, 69, 70, 235, + 239, 69, 70, 236, 110, 69, 70, 235, 160, 69, 70, 236, 31, 69, 70, 235, + 223, 69, 70, 236, 94, 69, 70, 235, 191, 69, 70, 236, 62, 69, 70, 235, + 254, 69, 70, 236, 125, 69, 70, 235, 152, 69, 70, 236, 23, 69, 70, 235, + 215, 69, 70, 236, 86, 69, 70, 235, 183, 69, 70, 236, 54, 69, 70, 235, + 246, 69, 70, 236, 117, 69, 70, 235, 167, 69, 70, 236, 38, 69, 70, 235, + 230, 69, 70, 236, 101, 69, 70, 235, 198, 69, 70, 236, 69, 69, 70, 236, 5, + 69, 70, 236, 132, 69, 70, 235, 141, 69, 70, 236, 12, 69, 70, 235, 204, + 69, 70, 236, 75, 69, 70, 235, 172, 69, 70, 236, 43, 69, 70, 235, 235, 69, + 70, 236, 106, 69, 70, 235, 156, 69, 70, 236, 27, 69, 70, 235, 219, 69, + 70, 236, 90, 69, 70, 235, 187, 69, 70, 236, 58, 69, 70, 235, 250, 69, 70, + 236, 121, 69, 70, 235, 148, 69, 70, 236, 19, 69, 70, 235, 211, 69, 70, + 236, 82, 69, 70, 235, 179, 69, 70, 236, 50, 69, 70, 235, 242, 69, 70, + 236, 113, 69, 70, 235, 163, 69, 70, 236, 34, 69, 70, 235, 226, 69, 70, + 236, 97, 69, 70, 235, 194, 69, 70, 236, 65, 69, 70, 236, 1, 69, 70, 236, + 128, 69, 70, 235, 144, 69, 70, 236, 15, 69, 70, 235, 207, 69, 70, 236, + 78, 69, 70, 235, 175, 69, 70, 236, 46, 69, 70, 235, 238, 69, 70, 236, + 109, 69, 70, 235, 159, 69, 70, 236, 30, 69, 70, 235, 222, 69, 70, 236, + 93, 69, 70, 235, 190, 69, 70, 236, 61, 69, 70, 235, 253, 69, 70, 236, + 124, 69, 70, 235, 151, 69, 70, 236, 22, 69, 70, 235, 214, 69, 70, 236, + 85, 69, 70, 235, 182, 69, 70, 236, 53, 69, 70, 235, 245, 69, 70, 236, + 116, 69, 70, 235, 166, 69, 70, 236, 37, 69, 70, 235, 229, 69, 70, 236, + 100, 69, 70, 235, 197, 69, 70, 236, 68, 69, 70, 236, 4, 69, 70, 236, 131, + 69, 70, 235, 139, 69, 70, 236, 10, 69, 70, 235, 202, 69, 70, 236, 73, 69, + 70, 235, 170, 69, 70, 236, 41, 69, 70, 235, 233, 69, 70, 236, 104, 69, + 70, 235, 154, 69, 70, 236, 25, 69, 70, 235, 217, 69, 70, 236, 88, 69, 70, + 235, 185, 69, 70, 236, 56, 69, 70, 235, 248, 69, 70, 236, 119, 69, 70, + 235, 146, 69, 70, 236, 17, 69, 70, 235, 209, 69, 70, 236, 80, 69, 70, + 235, 177, 69, 70, 236, 48, 69, 70, 235, 240, 69, 70, 236, 111, 69, 70, + 235, 161, 69, 70, 236, 32, 69, 70, 235, 224, 69, 70, 236, 95, 69, 70, + 235, 192, 69, 70, 236, 63, 69, 70, 235, 255, 69, 70, 236, 126, 69, 70, + 235, 142, 69, 70, 236, 13, 69, 70, 235, 205, 69, 70, 236, 76, 69, 70, + 235, 173, 69, 70, 236, 44, 69, 70, 235, 236, 69, 70, 236, 107, 69, 70, + 235, 157, 69, 70, 236, 28, 69, 70, 235, 220, 69, 70, 236, 91, 69, 70, + 235, 188, 69, 70, 236, 59, 69, 70, 235, 251, 69, 70, 236, 122, 69, 70, + 235, 149, 69, 70, 236, 20, 69, 70, 235, 212, 69, 70, 236, 83, 69, 70, + 235, 180, 69, 70, 236, 51, 69, 70, 235, 243, 69, 70, 236, 114, 69, 70, + 235, 164, 69, 70, 236, 35, 69, 70, 235, 227, 69, 70, 236, 98, 69, 70, + 235, 195, 69, 70, 236, 66, 69, 70, 236, 2, 69, 70, 236, 129, 69, 70, 235, + 140, 69, 70, 236, 11, 69, 70, 235, 203, 69, 70, 236, 74, 69, 70, 235, + 171, 69, 70, 236, 42, 69, 70, 235, 234, 69, 70, 236, 105, 69, 70, 235, + 155, 69, 70, 236, 26, 69, 70, 235, 218, 69, 70, 236, 89, 69, 70, 235, + 186, 69, 70, 236, 57, 69, 70, 235, 249, 69, 70, 236, 120, 69, 70, 235, + 147, 69, 70, 236, 18, 69, 70, 235, 210, 69, 70, 236, 81, 69, 70, 235, + 178, 69, 70, 236, 49, 69, 70, 235, 241, 69, 70, 236, 112, 69, 70, 235, + 162, 69, 70, 236, 33, 69, 70, 235, 225, 69, 70, 236, 96, 69, 70, 235, + 193, 69, 70, 236, 64, 69, 70, 236, 0, 69, 70, 236, 127, 69, 70, 235, 143, + 69, 70, 236, 14, 69, 70, 235, 206, 69, 70, 236, 77, 69, 70, 235, 174, 69, + 70, 236, 45, 69, 70, 235, 237, 69, 70, 236, 108, 69, 70, 235, 158, 69, + 70, 236, 29, 69, 70, 235, 221, 69, 70, 236, 92, 69, 70, 235, 189, 69, 70, + 236, 60, 69, 70, 235, 252, 69, 70, 236, 123, 69, 70, 235, 150, 69, 70, + 236, 21, 69, 70, 235, 213, 69, 70, 236, 84, 69, 70, 235, 181, 69, 70, + 236, 52, 69, 70, 235, 244, 69, 70, 236, 115, 69, 70, 235, 165, 69, 70, + 236, 36, 69, 70, 235, 228, 69, 70, 236, 99, 69, 70, 235, 196, 69, 70, + 236, 67, 69, 70, 236, 3, 69, 70, 236, 130, 96, 197, 13, 64, 4, 81, 106, + 96, 197, 13, 64, 4, 55, 81, 106, 118, 55, 64, 4, 81, 106, 96, 55, 64, 4, + 81, 106, 45, 50, 55, 64, 4, 81, 106, 96, 197, 13, 64, 232, 98, 164, 118, + 55, 64, 232, 98, 164, 96, 55, 64, 232, 98, 164, 235, 119, 64, 4, 228, + 241, 106, 196, 66, 64, 4, 228, 241, 106, 196, 66, 197, 225, 57, 235, 119, + 197, 225, 57, 118, 55, 237, 216, 57, 96, 55, 237, 216, 57, 118, 197, 225, + 237, 216, 57, 96, 197, 225, 237, 216, 57, 96, 197, 13, 197, 225, 237, + 216, 57, 96, 64, 4, 235, 138, 201, 80, 196, 66, 64, 119, 164, 235, 119, + 64, 119, 164, 96, 64, 4, 199, 216, 4, 81, 106, 96, 64, 4, 199, 216, 4, + 55, 81, 106, 96, 197, 13, 64, 4, 199, 215, 96, 197, 13, 64, 4, 199, 216, + 4, 81, 106, 96, 197, 13, 64, 4, 199, 216, 4, 55, 81, 106, 118, 250, 237, + 96, 250, 237, 118, 55, 250, 237, 96, 55, 250, 237, 118, 64, 119, 62, 237, + 32, 96, 64, 119, 62, 237, 32, 118, 64, 232, 98, 249, 88, 119, 62, 237, + 32, 96, 64, 232, 98, 249, 88, 119, 62, 237, 32, 186, 193, 105, 23, 202, + 2, 234, 204, 57, 186, 234, 204, 23, 202, 2, 193, 105, 57, 186, 193, 105, + 64, 4, 102, 186, 234, 204, 64, 4, 102, 202, 2, 234, 204, 64, 4, 102, 202, + 2, 193, 105, 64, 4, 102, 186, 193, 105, 64, 23, 186, 234, 204, 57, 186, + 234, 204, 64, 23, 202, 2, 234, 204, 57, 202, 2, 234, 204, 64, 23, 202, 2, + 193, 105, 57, 202, 2, 193, 105, 64, 23, 186, 193, 105, 57, 206, 180, 237, + 39, 238, 210, 233, 83, 237, 38, 233, 83, 237, 39, 238, 210, 206, 180, + 237, 38, 202, 2, 234, 204, 64, 238, 210, 186, 234, 204, 57, 186, 234, + 204, 64, 238, 210, 202, 2, 234, 204, 57, 233, 83, 237, 39, 238, 210, 186, + 234, 204, 57, 206, 180, 237, 39, 238, 210, 202, 2, 234, 204, 57, 186, + 234, 204, 64, 238, 210, 186, 193, 105, 57, 186, 193, 105, 64, 238, 210, + 186, 234, 204, 57, 193, 139, 64, 209, 58, 236, 231, 183, 64, 209, 58, 96, + 199, 25, 238, 161, 196, 65, 64, 209, 58, 96, 199, 25, 238, 161, 235, 118, + 64, 209, 58, 235, 119, 199, 25, 238, 161, 219, 214, 64, 209, 58, 235, + 119, 199, 25, 238, 161, 206, 197, 206, 200, 251, 17, 242, 221, 57, 219, + 217, 251, 17, 251, 85, 57, 198, 54, 251, 17, 251, 85, 57, 248, 77, 251, + 17, 251, 85, 57, 198, 54, 251, 17, 242, 221, 64, 4, 216, 34, 198, 54, + 251, 17, 251, 85, 64, 4, 209, 81, 110, 50, 204, 27, 242, 221, 57, 110, + 45, 204, 27, 251, 85, 57, 251, 85, 242, 219, 243, 11, 57, 242, 221, 242, + 219, 243, 11, 57, 96, 64, 93, 203, 40, 118, 57, 118, 64, 93, 203, 40, 96, + 57, 203, 40, 96, 64, 93, 118, 57, 96, 64, 4, 108, 60, 118, 64, 4, 108, + 60, 96, 64, 198, 216, 192, 235, 45, 50, 64, 198, 216, 2, 243, 10, 196, + 66, 197, 13, 64, 232, 98, 2, 243, 10, 45, 181, 133, 50, 181, 144, 230, + 12, 45, 181, 144, 50, 181, 133, 230, 12, 133, 181, 50, 144, 181, 45, 230, + 12, 133, 181, 45, 144, 181, 50, 230, 12, 45, 181, 133, 50, 181, 133, 230, + 12, 133, 181, 50, 144, 181, 50, 230, 12, 45, 181, 144, 50, 181, 144, 230, + 12, 133, 181, 45, 144, 181, 45, 230, 12, 118, 230, 13, 4, 181, 133, 119, + 164, 96, 230, 13, 4, 181, 133, 119, 164, 196, 66, 230, 13, 4, 181, 50, + 119, 164, 235, 119, 230, 13, 4, 181, 50, 119, 164, 118, 230, 13, 4, 181, + 144, 119, 164, 96, 230, 13, 4, 181, 144, 119, 164, 196, 66, 230, 13, 4, + 181, 45, 119, 164, 235, 119, 230, 13, 4, 181, 45, 119, 164, 118, 230, 13, + 4, 181, 133, 232, 98, 164, 96, 230, 13, 4, 181, 133, 232, 98, 164, 196, + 66, 230, 13, 4, 181, 50, 232, 98, 164, 235, 119, 230, 13, 4, 181, 50, + 232, 98, 164, 118, 230, 13, 4, 181, 144, 232, 98, 164, 96, 230, 13, 4, + 181, 144, 232, 98, 164, 196, 66, 230, 13, 4, 181, 45, 232, 98, 164, 235, + 119, 230, 13, 4, 181, 45, 232, 98, 164, 118, 230, 13, 4, 181, 133, 93, + 118, 230, 13, 4, 181, 235, 123, 196, 66, 230, 13, 4, 181, 45, 248, 216, + 196, 66, 230, 13, 4, 181, 183, 96, 230, 13, 4, 181, 133, 93, 96, 230, 13, + 4, 181, 235, 123, 235, 119, 230, 13, 4, 181, 45, 248, 216, 235, 119, 230, + 13, 4, 181, 183, 118, 230, 13, 4, 181, 133, 93, 96, 230, 13, 4, 181, 196, + 77, 118, 230, 13, 4, 181, 144, 93, 96, 230, 13, 4, 181, 235, 123, 96, + 230, 13, 4, 181, 133, 93, 118, 230, 13, 4, 181, 196, 77, 96, 230, 13, 4, + 181, 144, 93, 118, 230, 13, 4, 181, 235, 123, 118, 230, 13, 4, 181, 133, + 93, 179, 237, 215, 118, 230, 13, 4, 181, 144, 248, 233, 179, 237, 215, + 96, 230, 13, 4, 181, 133, 93, 179, 237, 215, 96, 230, 13, 4, 181, 144, + 248, 233, 179, 237, 215, 196, 66, 230, 13, 4, 181, 45, 248, 216, 235, + 119, 230, 13, 4, 181, 183, 235, 119, 230, 13, 4, 181, 45, 248, 216, 196, + 66, 230, 13, 4, 181, 183, 50, 55, 64, 4, 206, 113, 229, 235, 234, 43, 3, + 93, 96, 57, 198, 153, 211, 67, 93, 96, 57, 118, 64, 93, 198, 153, 211, + 66, 96, 64, 93, 198, 153, 211, 66, 96, 64, 93, 251, 165, 234, 45, 159, + 219, 180, 93, 118, 57, 118, 64, 198, 216, 219, 179, 230, 204, 93, 96, 57, + 200, 229, 93, 96, 57, 118, 64, 198, 216, 200, 228, 200, 181, 93, 118, 57, + 45, 232, 237, 199, 215, 50, 232, 237, 199, 215, 133, 232, 237, 199, 215, + 144, 232, 237, 199, 215, 197, 225, 81, 249, 88, 237, 112, 191, 167, 213, + 10, 201, 201, 191, 167, 213, 10, 196, 255, 242, 83, 45, 63, 238, 171, + 248, 53, 50, 63, 238, 171, 248, 53, 45, 63, 210, 113, 50, 63, 210, 113, + 191, 167, 213, 10, 45, 223, 178, 248, 53, 191, 167, 213, 10, 50, 223, + 178, 248, 53, 191, 167, 213, 10, 45, 248, 166, 248, 53, 191, 167, 213, + 10, 50, 248, 166, 248, 53, 45, 51, 248, 54, 4, 196, 103, 50, 51, 248, 54, + 4, 196, 103, 45, 51, 248, 54, 4, 198, 183, 223, 163, 198, 54, 239, 1, 50, + 51, 248, 54, 4, 198, 183, 223, 163, 248, 77, 239, 1, 45, 51, 248, 54, 4, + 198, 183, 223, 163, 248, 77, 239, 1, 50, 51, 248, 54, 4, 198, 183, 223, + 163, 198, 54, 239, 1, 45, 251, 116, 248, 54, 4, 236, 140, 50, 251, 116, + 248, 54, 4, 236, 140, 45, 251, 17, 219, 180, 248, 53, 50, 251, 17, 230, + 204, 248, 53, 55, 45, 251, 17, 230, 204, 248, 53, 55, 50, 251, 17, 219, + 180, 248, 53, 45, 62, 198, 42, 203, 103, 248, 53, 50, 62, 198, 42, 203, + 103, 248, 53, 235, 138, 233, 39, 81, 191, 21, 219, 112, 216, 226, 251, + 116, 211, 69, 219, 224, 50, 251, 116, 195, 168, 4, 201, 190, 216, 226, + 50, 251, 116, 4, 236, 140, 251, 116, 4, 206, 9, 223, 117, 252, 47, 251, + 115, 201, 225, 251, 116, 211, 69, 219, 224, 201, 225, 251, 116, 211, 69, + 196, 77, 153, 251, 115, 207, 18, 251, 115, 251, 116, 4, 196, 103, 207, + 18, 251, 116, 4, 196, 103, 211, 172, 251, 116, 211, 69, 196, 77, 211, + 172, 251, 116, 211, 69, 235, 123, 216, 226, 251, 116, 4, 211, 77, 250, + 251, 234, 91, 223, 163, 64, 209, 58, 133, 23, 183, 216, 226, 251, 116, 4, + 211, 77, 250, 251, 234, 91, 223, 163, 64, 209, 58, 133, 23, 219, 224, + 216, 226, 251, 116, 4, 211, 77, 250, 251, 234, 91, 223, 163, 64, 209, 58, + 144, 23, 183, 216, 226, 251, 116, 4, 211, 77, 250, 251, 234, 91, 223, + 163, 64, 209, 58, 144, 23, 219, 224, 216, 226, 251, 116, 4, 211, 77, 250, + 251, 234, 91, 223, 163, 64, 209, 58, 50, 23, 196, 77, 216, 226, 251, 116, + 4, 211, 77, 250, 251, 234, 91, 223, 163, 64, 209, 58, 45, 23, 196, 77, + 216, 226, 251, 116, 4, 211, 77, 250, 251, 234, 91, 223, 163, 64, 209, 58, + 50, 23, 235, 123, 216, 226, 251, 116, 4, 211, 77, 250, 251, 234, 91, 223, + 163, 64, 209, 58, 45, 23, 235, 123, 207, 18, 234, 105, 203, 252, 234, + 105, 203, 253, 4, 211, 6, 234, 105, 203, 253, 4, 2, 243, 11, 58, 234, + 105, 203, 253, 4, 50, 64, 58, 234, 105, 203, 253, 4, 45, 64, 58, 243, 11, + 4, 228, 241, 164, 47, 81, 164, 47, 210, 118, 47, 207, 19, 202, 23, 47, + 209, 254, 243, 11, 236, 206, 247, 205, 228, 241, 249, 88, 23, 198, 54, + 132, 236, 206, 247, 205, 81, 164, 243, 11, 4, 200, 183, 192, 235, 47, + 251, 83, 236, 200, 56, 133, 64, 198, 216, 243, 10, 47, 63, 247, 248, 47, + 247, 248, 47, 219, 179, 47, 230, 203, 243, 11, 4, 2, 243, 11, 119, 199, + 34, 183, 243, 11, 4, 105, 228, 241, 201, 16, 119, 199, 34, 183, 112, 206, + 180, 237, 39, 202, 97, 112, 233, 83, 237, 39, 202, 97, 112, 250, 193, + 112, 2, 243, 10, 112, 201, 190, 105, 222, 198, 201, 188, 197, 242, 4, 75, + 58, 197, 242, 4, 196, 103, 206, 9, 223, 163, 197, 241, 197, 242, 4, 204, + 4, 250, 183, 248, 76, 50, 197, 242, 93, 45, 197, 241, 45, 197, 242, 248, + 216, 81, 164, 81, 249, 88, 248, 216, 50, 197, 241, 248, 64, 4, 45, 132, + 248, 139, 248, 64, 4, 50, 132, 248, 139, 62, 248, 63, 25, 4, 45, 132, + 248, 139, 25, 4, 50, 132, 248, 139, 63, 228, 174, 62, 228, 174, 45, 193, + 72, 233, 39, 50, 193, 72, 233, 39, 45, 55, 193, 72, 233, 39, 50, 55, 193, + 72, 233, 39, 223, 155, 223, 139, 198, 179, 139, 223, 139, 223, 140, 214, + 108, 4, 81, 164, 235, 132, 215, 131, 51, 4, 239, 25, 211, 11, 223, 152, + 250, 219, 202, 254, 208, 200, 234, 43, 3, 23, 202, 99, 210, 118, 234, 43, + 3, 23, 202, 99, 210, 119, 4, 198, 153, 58, 228, 17, 119, 23, 202, 99, + 210, 118, 231, 14, 201, 101, 199, 22, 235, 122, 197, 242, 4, 45, 132, + 248, 139, 235, 122, 197, 242, 4, 50, 132, 248, 139, 62, 237, 33, 4, 144, + 57, 62, 218, 232, 63, 243, 11, 4, 144, 57, 62, 243, 11, 4, 144, 57, 234, + 25, 63, 201, 190, 234, 25, 62, 201, 190, 234, 25, 63, 237, 32, 234, 25, + 62, 237, 32, 234, 25, 63, 243, 10, 234, 25, 62, 243, 10, 206, 51, 207, + 19, 202, 24, 211, 66, 202, 24, 4, 211, 6, 207, 19, 202, 24, 4, 228, 241, + 106, 248, 175, 202, 23, 248, 175, 207, 19, 202, 23, 55, 209, 81, 197, + 225, 209, 81, 219, 219, 238, 163, 251, 116, 248, 53, 206, 203, 238, 163, + 251, 116, 248, 53, 198, 137, 216, 32, 215, 60, 47, 75, 211, 66, 215, 60, + 47, 108, 211, 66, 215, 60, 47, 25, 211, 66, 215, 60, 196, 93, 211, 67, 4, + 236, 140, 215, 60, 196, 93, 211, 67, 4, 209, 81, 215, 60, 51, 223, 100, + 211, 66, 215, 60, 51, 196, 93, 211, 66, 105, 219, 29, 23, 211, 66, 105, + 219, 29, 211, 57, 211, 66, 215, 60, 25, 211, 66, 215, 236, 105, 200, 204, + 200, 202, 4, 223, 113, 208, 26, 223, 114, 211, 66, 232, 246, 210, 107, + 223, 113, 223, 114, 4, 55, 106, 223, 114, 250, 143, 4, 202, 97, 243, 3, + 232, 76, 251, 85, 223, 111, 219, 113, 223, 112, 4, 207, 91, 210, 86, 250, + 245, 209, 52, 219, 113, 223, 112, 4, 204, 27, 210, 86, 250, 245, 209, 52, + 219, 113, 223, 112, 213, 12, 223, 157, 199, 34, 209, 52, 223, 114, 250, + 245, 42, 209, 62, 211, 66, 208, 19, 223, 114, 211, 66, 223, 114, 4, 118, + 64, 4, 102, 223, 114, 4, 25, 56, 223, 114, 4, 223, 99, 223, 114, 4, 196, + 92, 223, 114, 4, 211, 6, 223, 114, 4, 196, 103, 222, 199, 220, 13, 45, + 197, 242, 211, 66, 191, 167, 213, 10, 205, 92, 239, 62, 191, 167, 213, + 10, 205, 92, 209, 126, 191, 167, 213, 10, 205, 92, 208, 195, 108, 3, 4, + 2, 243, 11, 58, 108, 3, 4, 243, 2, 252, 61, 58, 108, 3, 4, 198, 153, 58, + 108, 3, 4, 75, 60, 108, 3, 4, 198, 153, 60, 108, 3, 4, 200, 230, 109, + 108, 3, 4, 62, 197, 241, 216, 35, 3, 4, 242, 75, 58, 216, 35, 3, 4, 75, + 60, 216, 35, 3, 4, 233, 83, 236, 138, 216, 35, 3, 4, 206, 180, 236, 138, + 108, 3, 223, 163, 45, 132, 243, 10, 108, 3, 223, 163, 50, 132, 243, 10, + 195, 152, 211, 57, 238, 218, 208, 200, 215, 127, 3, 4, 75, 58, 215, 127, + 3, 4, 196, 103, 204, 24, 208, 201, 4, 248, 77, 242, 218, 202, 68, 208, + 200, 215, 127, 3, 223, 163, 45, 132, 243, 10, 215, 127, 3, 223, 163, 50, + 132, 243, 10, 47, 215, 127, 3, 4, 243, 2, 252, 60, 215, 127, 3, 223, 163, + 55, 243, 10, 47, 236, 200, 56, 108, 3, 223, 163, 197, 241, 216, 35, 3, + 223, 163, 197, 241, 215, 127, 3, 223, 163, 197, 241, 223, 108, 208, 200, + 206, 198, 223, 108, 208, 200, 191, 167, 213, 10, 207, 64, 239, 62, 251, + 147, 211, 57, 239, 9, 223, 100, 4, 236, 140, 196, 93, 4, 216, 35, 56, + 196, 93, 4, 211, 6, 223, 100, 4, 211, 6, 223, 100, 4, 219, 29, 251, 125, + 196, 93, 4, 219, 29, 211, 56, 196, 93, 93, 223, 99, 223, 100, 93, 196, + 92, 196, 93, 93, 249, 88, 93, 223, 99, 223, 100, 93, 249, 88, 93, 196, + 92, 196, 93, 248, 216, 23, 222, 198, 4, 196, 92, 223, 100, 248, 216, 23, + 222, 198, 4, 223, 99, 242, 219, 196, 93, 4, 204, 3, 242, 219, 223, 100, + 4, 204, 3, 55, 51, 223, 99, 55, 51, 196, 92, 242, 219, 196, 93, 4, 204, + 4, 23, 202, 68, 208, 200, 219, 29, 23, 4, 75, 58, 219, 29, 211, 57, 4, + 75, 58, 55, 219, 29, 251, 125, 55, 219, 29, 211, 56, 105, 223, 101, 219, + 29, 251, 125, 105, 223, 101, 219, 29, 211, 56, 202, 80, 220, 13, 211, 56, + 202, 80, 220, 13, 251, 125, 219, 29, 211, 57, 211, 1, 219, 29, 251, 125, + 219, 29, 23, 4, 82, 201, 80, 219, 29, 211, 57, 4, 82, 201, 80, 219, 29, + 23, 4, 228, 241, 237, 215, 219, 29, 211, 57, 4, 228, 241, 237, 215, 219, + 29, 23, 4, 55, 211, 6, 219, 29, 23, 4, 196, 103, 219, 29, 23, 4, 55, 196, + 103, 2, 195, 149, 4, 196, 103, 219, 29, 211, 57, 4, 55, 211, 6, 219, 29, + 211, 57, 4, 55, 196, 103, 191, 167, 213, 10, 236, 152, 251, 75, 191, 167, + 213, 10, 207, 137, 251, 75, 234, 43, 3, 4, 75, 60, 228, 17, 4, 75, 58, + 197, 225, 228, 241, 249, 88, 4, 55, 81, 106, 197, 225, 228, 241, 249, 88, + 4, 197, 225, 81, 106, 198, 153, 211, 67, 4, 75, 58, 198, 153, 211, 67, 4, + 206, 180, 236, 138, 202, 180, 216, 35, 202, 179, 239, 49, 4, 75, 58, 234, + 43, 4, 250, 193, 251, 165, 234, 45, 119, 4, 243, 2, 252, 60, 251, 40, + 234, 45, 211, 57, 234, 45, 159, 234, 43, 3, 93, 108, 56, 108, 3, 93, 234, + 43, 56, 234, 43, 3, 93, 198, 153, 211, 66, 55, 242, 84, 234, 44, 105, + 239, 41, 234, 43, 202, 194, 115, 239, 41, 234, 43, 202, 194, 234, 43, 3, + 4, 105, 185, 93, 23, 105, 185, 60, 234, 36, 4, 232, 128, 185, 58, 219, + 180, 4, 243, 11, 223, 117, 230, 204, 4, 243, 11, 223, 117, 219, 180, 4, + 208, 13, 87, 58, 230, 204, 4, 208, 13, 87, 58, 219, 180, 211, 57, 202, + 99, 234, 45, 159, 230, 204, 211, 57, 202, 99, 234, 45, 159, 219, 180, + 211, 57, 202, 99, 234, 45, 119, 4, 75, 223, 117, 230, 204, 211, 57, 202, + 99, 234, 45, 119, 4, 75, 223, 117, 219, 180, 211, 57, 202, 99, 234, 45, + 119, 4, 75, 58, 230, 204, 211, 57, 202, 99, 234, 45, 119, 4, 75, 58, 219, + 180, 211, 57, 202, 99, 234, 45, 119, 4, 75, 93, 183, 230, 204, 211, 57, + 202, 99, 234, 45, 119, 4, 75, 93, 219, 224, 219, 180, 211, 57, 251, 41, + 230, 204, 211, 57, 251, 41, 219, 180, 23, 202, 168, 213, 12, 234, 45, + 159, 230, 204, 23, 202, 168, 213, 12, 234, 45, 159, 219, 180, 23, 213, + 12, 251, 41, 230, 204, 23, 213, 12, 251, 41, 219, 180, 93, 235, 131, 234, + 45, 93, 230, 203, 230, 204, 93, 235, 131, 234, 45, 93, 219, 179, 219, + 180, 93, 202, 180, 211, 57, 234, 44, 230, 204, 93, 202, 180, 211, 57, + 234, 44, 219, 180, 93, 202, 180, 93, 230, 203, 230, 204, 93, 202, 180, + 93, 219, 179, 219, 180, 93, 230, 204, 93, 235, 131, 234, 44, 230, 204, + 93, 219, 180, 93, 235, 131, 234, 44, 219, 180, 93, 202, 99, 234, 45, 93, + 230, 204, 93, 202, 99, 234, 44, 230, 204, 93, 202, 99, 234, 45, 93, 219, + 180, 93, 202, 99, 234, 44, 202, 99, 234, 45, 119, 211, 57, 219, 179, 202, + 99, 234, 45, 119, 211, 57, 230, 203, 202, 99, 234, 45, 119, 211, 57, 219, + 180, 4, 75, 223, 117, 202, 99, 234, 45, 119, 211, 57, 230, 204, 4, 75, + 223, 117, 235, 131, 234, 45, 119, 211, 57, 219, 179, 235, 131, 234, 45, + 119, 211, 57, 230, 203, 235, 131, 202, 99, 234, 45, 119, 211, 57, 219, + 179, 235, 131, 202, 99, 234, 45, 119, 211, 57, 230, 203, 202, 180, 211, + 57, 219, 179, 202, 180, 211, 57, 230, 203, 202, 180, 93, 219, 180, 93, + 234, 43, 56, 202, 180, 93, 230, 204, 93, 234, 43, 56, 55, 214, 88, 219, + 179, 55, 214, 88, 230, 203, 55, 214, 88, 219, 180, 4, 196, 103, 230, 204, + 211, 1, 219, 179, 230, 204, 248, 216, 219, 179, 219, 180, 242, 219, 247, + 205, 238, 164, 230, 204, 242, 219, 247, 205, 238, 164, 219, 180, 242, + 219, 247, 205, 238, 165, 93, 202, 99, 234, 44, 230, 204, 242, 219, 247, + 205, 238, 165, 93, 202, 99, 234, 44, 202, 69, 199, 38, 220, 11, 199, 38, + 202, 69, 199, 39, 211, 57, 234, 45, 159, 220, 11, 199, 39, 211, 57, 234, + 45, 159, 234, 43, 3, 4, 247, 241, 58, 208, 232, 93, 202, 168, 234, 43, + 56, 200, 221, 93, 202, 168, 234, 43, 56, 208, 232, 93, 202, 168, 213, 12, + 234, 45, 159, 200, 221, 93, 202, 168, 213, 12, 234, 45, 159, 208, 232, + 93, 234, 43, 56, 200, 221, 93, 234, 43, 56, 208, 232, 93, 213, 12, 234, + 45, 159, 200, 221, 93, 213, 12, 234, 45, 159, 208, 232, 93, 251, 165, + 234, 45, 159, 200, 221, 93, 251, 165, 234, 45, 159, 208, 232, 93, 213, + 12, 251, 165, 234, 45, 159, 200, 221, 93, 213, 12, 251, 165, 234, 45, + 159, 55, 208, 231, 55, 200, 220, 200, 229, 4, 236, 140, 200, 181, 4, 236, + 140, 200, 229, 4, 108, 3, 60, 200, 181, 4, 108, 3, 60, 200, 229, 4, 215, + 127, 3, 60, 200, 181, 4, 215, 127, 3, 60, 200, 229, 79, 211, 57, 234, 45, + 119, 4, 75, 58, 200, 181, 79, 211, 57, 234, 45, 119, 4, 75, 58, 200, 229, + 79, 93, 234, 43, 56, 200, 181, 79, 93, 234, 43, 56, 200, 229, 79, 93, + 198, 153, 211, 66, 200, 181, 79, 93, 198, 153, 211, 66, 200, 229, 79, 93, + 251, 165, 234, 45, 159, 200, 181, 79, 93, 251, 165, 234, 45, 159, 200, + 229, 79, 93, 213, 12, 234, 45, 159, 200, 181, 79, 93, 213, 12, 234, 45, + 159, 51, 45, 211, 77, 111, 211, 66, 51, 50, 211, 77, 111, 211, 66, 242, + 219, 200, 228, 242, 219, 200, 180, 242, 219, 200, 229, 211, 57, 234, 45, + 159, 242, 219, 200, 181, 211, 57, 234, 45, 159, 200, 229, 93, 200, 180, + 200, 181, 93, 200, 228, 200, 229, 93, 200, 228, 200, 181, 93, 200, 180, + 200, 181, 248, 216, 200, 228, 200, 181, 248, 216, 23, 222, 198, 247, 205, + 237, 216, 4, 200, 228, 234, 132, 79, 211, 69, 235, 118, 209, 116, 4, 199, + 122, 198, 53, 198, 7, 223, 99, 232, 147, 213, 27, 203, 40, 45, 199, 228, + 203, 40, 144, 199, 228, 203, 40, 133, 199, 228, 209, 255, 4, 206, 8, 81, + 249, 88, 197, 225, 50, 197, 57, 55, 81, 249, 88, 45, 197, 57, 81, 249, + 88, 55, 45, 197, 57, 55, 81, 249, 88, 55, 45, 197, 57, 179, 237, 216, + 232, 98, 45, 216, 191, 79, 55, 195, 135, 203, 40, 144, 199, 229, 4, 211, + 6, 203, 40, 133, 199, 229, 4, 196, 103, 203, 40, 133, 199, 229, 93, 203, + 40, 144, 199, 228, 55, 144, 199, 228, 55, 133, 199, 228, 55, 201, 28, + 213, 12, 56, 207, 18, 55, 201, 28, 213, 12, 56, 236, 164, 213, 12, 236, + 208, 4, 207, 18, 214, 107, 202, 97, 81, 219, 113, 4, 243, 11, 58, 81, + 219, 113, 4, 243, 11, 60, 144, 199, 229, 4, 243, 11, 60, 210, 119, 4, + 228, 241, 106, 210, 119, 4, 198, 153, 211, 66, 197, 225, 81, 249, 88, + 248, 168, 207, 65, 197, 225, 81, 249, 88, 4, 228, 241, 106, 197, 225, + 242, 84, 211, 66, 197, 225, 214, 88, 219, 179, 197, 225, 214, 88, 230, + 203, 235, 131, 202, 99, 219, 180, 211, 57, 234, 45, 159, 235, 131, 202, + 99, 230, 204, 211, 57, 234, 45, 159, 197, 225, 202, 24, 248, 168, 207, + 65, 220, 13, 197, 225, 81, 249, 88, 211, 66, 55, 202, 24, 211, 66, 63, + 81, 164, 215, 60, 63, 81, 164, 186, 234, 204, 63, 57, 186, 193, 105, 63, + 57, 202, 2, 234, 204, 63, 57, 202, 2, 193, 105, 63, 57, 45, 50, 63, 57, + 118, 62, 57, 196, 66, 62, 57, 235, 119, 62, 57, 186, 234, 204, 62, 57, + 186, 193, 105, 62, 57, 202, 2, 234, 204, 62, 57, 202, 2, 193, 105, 62, + 57, 45, 50, 62, 57, 133, 144, 62, 57, 96, 64, 4, 198, 136, 235, 118, 96, + 64, 4, 198, 136, 196, 65, 118, 64, 4, 198, 136, 235, 118, 118, 64, 4, + 198, 136, 196, 65, 51, 4, 198, 54, 132, 248, 139, 51, 4, 248, 77, 132, + 248, 139, 51, 4, 116, 50, 237, 39, 132, 248, 139, 51, 4, 110, 45, 237, + 39, 132, 248, 139, 237, 33, 4, 45, 132, 248, 139, 237, 33, 4, 50, 132, + 248, 139, 237, 33, 4, 198, 54, 132, 248, 139, 237, 33, 4, 248, 77, 132, + 248, 139, 235, 138, 201, 190, 62, 220, 13, 201, 190, 63, 220, 13, 201, + 190, 62, 195, 83, 2, 201, 190, 63, 195, 83, 2, 201, 190, 62, 210, 24, 63, + 210, 24, 63, 229, 182, 62, 229, 182, 228, 241, 62, 229, 182, 62, 220, 13, + 243, 10, 62, 216, 213, 237, 32, 63, 216, 213, 237, 32, 62, 216, 213, 218, + 232, 63, 216, 213, 218, 232, 62, 2, 237, 32, 62, 2, 218, 232, 63, 2, 218, + 232, 62, 228, 241, 234, 121, 63, 228, 241, 234, 121, 62, 81, 234, 121, + 63, 81, 234, 121, 45, 64, 4, 2, 243, 10, 115, 118, 250, 231, 45, 64, 4, + 47, 209, 81, 179, 118, 201, 183, 57, 118, 197, 13, 64, 4, 81, 106, 118, + 197, 13, 64, 4, 55, 81, 106, 118, 197, 13, 64, 232, 98, 164, 118, 197, + 13, 197, 225, 237, 216, 57, 118, 64, 4, 235, 138, 201, 80, 118, 64, 4, + 199, 216, 4, 81, 106, 118, 64, 4, 199, 216, 4, 55, 81, 106, 118, 197, 13, + 64, 4, 199, 215, 118, 197, 13, 64, 4, 199, 216, 4, 81, 106, 118, 197, 13, + 64, 4, 199, 216, 4, 55, 81, 106, 118, 64, 198, 216, 192, 235, 193, 139, + 64, 209, 58, 236, 231, 219, 224, 234, 43, 3, 93, 118, 57, 207, 19, 198, + 153, 211, 67, 93, 118, 57, 118, 64, 93, 207, 19, 251, 165, 234, 45, 159, + 96, 64, 198, 216, 230, 203, 96, 64, 198, 216, 200, 180, 118, 208, 26, 57, + 96, 208, 26, 57, 207, 19, 198, 153, 211, 67, 93, 96, 57, 96, 64, 93, 207, + 19, 251, 165, 234, 45, 159, 198, 153, 211, 67, 93, 118, 57, 118, 64, 93, + 251, 165, 234, 45, 159, 118, 64, 93, 207, 19, 198, 153, 211, 66, 96, 64, + 93, 207, 19, 198, 153, 211, 66, 235, 119, 197, 240, 191, 21, 57, 203, 40, + 202, 99, 186, 57, 203, 40, 249, 143, 202, 2, 57, 63, 216, 213, 201, 102, + 62, 2, 201, 102, 63, 2, 201, 102, 62, 206, 203, 210, 24, 63, 206, 203, + 210, 24, 88, 220, 13, 243, 10, 88, 211, 8, 4, 211, 8, 223, 117, 88, 243, + 11, 4, 243, 11, 223, 117, 88, 243, 10, 88, 47, 205, 154, 202, 99, 186, + 64, 4, 228, 250, 229, 235, 249, 143, 202, 2, 64, 4, 228, 250, 199, 215, + 202, 99, 186, 64, 4, 228, 241, 199, 215, 249, 143, 202, 2, 64, 4, 228, + 241, 199, 215, 248, 224, 64, 209, 58, 235, 119, 199, 25, 186, 234, 203, + 203, 40, 248, 224, 64, 209, 58, 235, 119, 199, 25, 186, 234, 203, 118, + 197, 240, 57, 196, 66, 197, 240, 57, 96, 197, 240, 57, 235, 119, 197, + 240, 57, 45, 50, 197, 240, 57, 133, 144, 197, 240, 57, 186, 193, 105, + 197, 240, 57, 186, 234, 204, 197, 240, 57, 202, 2, 234, 204, 197, 240, + 57, 202, 2, 193, 105, 197, 240, 57, 118, 197, 240, 237, 214, 57, 196, 66, + 197, 240, 237, 214, 57, 96, 197, 240, 237, 214, 57, 235, 119, 197, 240, + 237, 214, 57, 242, 221, 197, 240, 211, 77, 243, 11, 57, 251, 85, 197, + 240, 211, 77, 243, 11, 57, 118, 197, 240, 64, 119, 164, 196, 66, 197, + 240, 64, 119, 164, 96, 197, 240, 64, 119, 164, 235, 119, 197, 240, 64, + 119, 164, 186, 193, 105, 197, 240, 64, 119, 164, 186, 234, 204, 197, 240, + 64, 119, 164, 202, 2, 234, 204, 197, 240, 64, 119, 164, 202, 2, 193, 105, + 197, 240, 64, 119, 164, 118, 197, 240, 64, 4, 55, 228, 241, 106, 196, 66, + 197, 240, 64, 4, 55, 228, 241, 106, 96, 197, 240, 64, 4, 55, 228, 241, + 106, 235, 119, 197, 240, 64, 4, 55, 228, 241, 106, 228, 241, 199, 237, + 221, 222, 81, 199, 237, 221, 222, 118, 197, 240, 64, 139, 96, 197, 240, + 57, 196, 66, 197, 240, 64, 118, 79, 235, 119, 197, 240, 57, 96, 197, 240, + 64, 139, 118, 197, 240, 57, 235, 119, 197, 240, 64, 118, 79, 196, 66, + 197, 240, 57, 118, 197, 240, 210, 196, 250, 231, 196, 66, 197, 240, 210, + 196, 250, 231, 96, 197, 240, 210, 196, 250, 231, 235, 119, 197, 240, 210, + 196, 250, 231, 118, 62, 47, 63, 57, 196, 66, 62, 47, 63, 57, 96, 62, 47, + 63, 57, 235, 119, 62, 47, 63, 57, 251, 85, 197, 240, 50, 196, 221, 57, + 251, 85, 197, 240, 248, 77, 196, 221, 57, 251, 85, 197, 240, 45, 196, + 221, 57, 251, 85, 197, 240, 198, 54, 196, 221, 57, 207, 23, 219, 224, + 207, 23, 183, 214, 77, 219, 224, 214, 77, 183, 232, 128, 239, 2, 250, + 232, 243, 6, 251, 84, 96, 62, 57, 16, 40, 196, 255, 42, 234, 133, 198, + 225, 198, 52, 118, 234, 37, 250, 235, 198, 225, 206, 204, 196, 66, 234, + 37, 250, 235, 198, 225, 198, 52, 96, 234, 37, 250, 235, 198, 225, 219, + 220, 235, 119, 234, 37, 250, 235, 62, 118, 234, 37, 250, 235, 62, 196, + 66, 234, 37, 250, 235, 62, 96, 234, 37, 250, 235, 62, 235, 119, 234, 37, + 250, 235, 235, 119, 197, 240, 64, 4, 179, 198, 136, 219, 214, 235, 119, + 197, 240, 64, 4, 179, 198, 136, 206, 197, 196, 66, 197, 240, 64, 4, 179, + 198, 136, 219, 214, 196, 66, 197, 240, 64, 4, 179, 198, 136, 206, 197, + 118, 197, 240, 64, 4, 179, 198, 136, 196, 65, 96, 197, 240, 64, 4, 179, + 198, 136, 196, 65, 118, 197, 240, 64, 4, 179, 198, 136, 235, 118, 96, + 197, 240, 64, 4, 179, 198, 136, 235, 118, 62, 238, 163, 235, 119, 23, + 118, 57, 62, 238, 163, 235, 119, 23, 96, 57, 62, 238, 163, 196, 66, 23, + 118, 57, 62, 238, 163, 196, 66, 23, 96, 57, 62, 238, 163, 118, 23, 196, + 66, 57, 62, 238, 163, 96, 23, 196, 66, 57, 62, 238, 163, 118, 23, 235, + 119, 57, 62, 238, 163, 96, 23, 235, 119, 57, 206, 248, 64, 144, 219, 224, + 206, 248, 64, 144, 183, 206, 248, 64, 133, 219, 224, 206, 248, 64, 133, + 183, 206, 248, 64, 45, 196, 77, 206, 248, 64, 50, 196, 77, 206, 248, 64, + 45, 235, 123, 206, 248, 64, 50, 235, 123, 196, 66, 63, 64, 232, 98, 249, + 88, 4, 228, 241, 164, 133, 250, 236, 223, 163, 42, 207, 93, 248, 62, 211, + 1, 63, 201, 188, 211, 1, 63, 23, 62, 201, 188, 211, 1, 62, 201, 188, 249, + 107, 111, 4, 156, 192, 235, 47, 192, 235, 47, 28, 192, 235, 62, 51, 247, + 19, 62, 237, 33, 247, 19, 153, 62, 210, 24, 228, 241, 62, 211, 160, 62, + 211, 160, 62, 216, 213, 196, 76, 197, 242, 247, 19, 62, 216, 213, 235, + 122, 197, 242, 247, 19, 62, 216, 213, 219, 219, 197, 242, 247, 19, 62, + 216, 213, 206, 203, 197, 242, 247, 19, 214, 95, 232, 146, 109, 198, 54, + 132, 62, 243, 10, 248, 77, 132, 62, 243, 10, 156, 232, 128, 209, 60, 62, + 238, 159, 206, 122, 156, 232, 128, 209, 60, 62, 238, 159, 63, 232, 128, + 209, 60, 238, 159, 206, 122, 63, 232, 128, 209, 60, 238, 159, 51, 209, + 25, 223, 144, 196, 107, 56, 230, 187, 77, 209, 78, 232, 146, 109, 209, + 78, 232, 146, 138, 209, 78, 232, 146, 134, 209, 78, 232, 146, 149, 198, + 9, 208, 185, 250, 189, 228, 91, 209, 196, 214, 91, 63, 215, 206, 204, 33, + 62, 237, 33, 211, 105, 238, 217, 197, 202, 156, 215, 206, 250, 227, 238, + 179, 230, 88, 191, 75, 221, 2, 251, 53, 252, 32, 193, 247, 209, 26, 45, + 132, 62, 201, 102, 50, 132, 62, 201, 102, 201, 103, 4, 45, 132, 248, 139, + 201, 103, 4, 50, 132, 248, 139, 118, 197, 13, 64, 4, 197, 242, 250, 233, + 196, 66, 197, 13, 64, 4, 197, 242, 250, 233, 96, 197, 13, 64, 4, 197, + 242, 250, 233, 235, 119, 197, 13, 64, 4, 197, 242, 250, 233, 234, 27, + 232, 146, 107, 234, 27, 232, 146, 109, 205, 51, 206, 31, 250, 188, 16, + 195, 52, 206, 31, 250, 188, 16, 212, 254, 206, 31, 250, 188, 16, 208, 1, + 206, 31, 250, 188, 16, 248, 163, 206, 31, 250, 188, 16, 204, 16, 206, 31, + 250, 188, 16, 198, 0, 234, 43, 3, 4, 223, 140, 60, 196, 89, 113, 204, 12, + 113, 235, 128, 113, 210, 96, 113, 207, 18, 50, 251, 115, 229, 203, 210, + 78, 113, 135, 6, 1, 250, 122, 135, 6, 1, 247, 252, 135, 6, 1, 195, 151, + 135, 6, 1, 231, 18, 135, 6, 1, 236, 169, 135, 6, 1, 192, 49, 135, 6, 1, + 191, 55, 135, 6, 1, 235, 30, 135, 6, 1, 191, 82, 135, 6, 1, 223, 39, 135, + 6, 1, 89, 223, 39, 135, 6, 1, 68, 135, 6, 1, 236, 190, 135, 6, 1, 222, + 94, 135, 6, 1, 219, 75, 135, 6, 1, 215, 66, 135, 6, 1, 214, 210, 135, 6, + 1, 211, 89, 135, 6, 1, 209, 55, 135, 6, 1, 206, 179, 135, 6, 1, 202, 77, + 135, 6, 1, 197, 44, 135, 6, 1, 196, 124, 135, 6, 1, 232, 101, 135, 6, 1, + 229, 188, 135, 6, 1, 211, 20, 135, 6, 1, 210, 63, 135, 6, 1, 203, 8, 135, + 6, 1, 197, 146, 135, 6, 1, 243, 54, 135, 6, 1, 203, 165, 135, 6, 1, 192, + 58, 135, 6, 1, 192, 60, 135, 6, 1, 192, 93, 135, 6, 1, 201, 220, 140, + 135, 6, 1, 191, 225, 135, 6, 1, 2, 191, 190, 135, 6, 1, 2, 191, 191, 4, + 199, 215, 135, 6, 1, 192, 12, 135, 6, 1, 223, 82, 2, 191, 190, 135, 6, 1, + 248, 175, 191, 190, 135, 6, 1, 223, 82, 248, 175, 191, 190, 135, 6, 1, + 232, 228, 135, 6, 1, 223, 37, 135, 6, 1, 203, 7, 135, 6, 1, 197, 215, 65, + 135, 6, 1, 220, 1, 215, 66, 135, 6, 1, 247, 73, 243, 54, 135, 2, 1, 250, + 122, 135, 2, 1, 247, 252, 135, 2, 1, 195, 151, 135, 2, 1, 231, 18, 135, + 2, 1, 236, 169, 135, 2, 1, 192, 49, 135, 2, 1, 191, 55, 135, 2, 1, 235, + 30, 135, 2, 1, 191, 82, 135, 2, 1, 223, 39, 135, 2, 1, 89, 223, 39, 135, + 2, 1, 68, 135, 2, 1, 236, 190, 135, 2, 1, 222, 94, 135, 2, 1, 219, 75, + 135, 2, 1, 215, 66, 135, 2, 1, 214, 210, 135, 2, 1, 211, 89, 135, 2, 1, + 209, 55, 135, 2, 1, 206, 179, 135, 2, 1, 202, 77, 135, 2, 1, 197, 44, + 135, 2, 1, 196, 124, 135, 2, 1, 232, 101, 135, 2, 1, 229, 188, 135, 2, 1, + 211, 20, 135, 2, 1, 210, 63, 135, 2, 1, 203, 8, 135, 2, 1, 197, 146, 135, + 2, 1, 243, 54, 135, 2, 1, 203, 165, 135, 2, 1, 192, 58, 135, 2, 1, 192, + 60, 135, 2, 1, 192, 93, 135, 2, 1, 201, 220, 140, 135, 2, 1, 191, 225, + 135, 2, 1, 2, 191, 190, 135, 2, 1, 2, 191, 191, 4, 199, 215, 135, 2, 1, + 192, 12, 135, 2, 1, 223, 82, 2, 191, 190, 135, 2, 1, 248, 175, 191, 190, + 135, 2, 1, 223, 82, 248, 175, 191, 190, 135, 2, 1, 232, 228, 135, 2, 1, + 223, 37, 135, 2, 1, 203, 7, 135, 2, 1, 197, 215, 65, 135, 2, 1, 220, 1, + 215, 66, 135, 2, 1, 247, 73, 243, 54, 8, 6, 1, 220, 143, 4, 55, 164, 8, + 2, 1, 220, 143, 4, 55, 164, 8, 6, 1, 220, 143, 4, 82, 198, 152, 8, 6, 1, + 210, 237, 4, 106, 8, 6, 1, 207, 222, 4, 199, 215, 8, 2, 1, 42, 4, 106, 8, + 2, 1, 200, 44, 4, 237, 39, 106, 8, 6, 1, 230, 117, 4, 237, 87, 8, 2, 1, + 230, 117, 4, 237, 87, 8, 6, 1, 222, 153, 4, 237, 87, 8, 2, 1, 222, 153, + 4, 237, 87, 8, 6, 1, 191, 167, 4, 237, 87, 8, 2, 1, 191, 167, 4, 237, 87, + 8, 6, 1, 251, 160, 8, 6, 1, 218, 169, 4, 102, 8, 6, 1, 153, 65, 8, 6, 1, + 153, 251, 160, 8, 2, 1, 196, 13, 4, 50, 102, 8, 6, 1, 193, 225, 4, 102, + 8, 2, 1, 193, 225, 4, 102, 8, 2, 1, 196, 13, 4, 238, 175, 8, 6, 1, 132, + 230, 116, 8, 2, 1, 132, 230, 116, 8, 2, 1, 199, 213, 209, 211, 8, 2, 1, + 235, 15, 4, 213, 9, 8, 2, 1, 153, 207, 222, 4, 199, 215, 8, 2, 1, 187, 4, + 130, 206, 189, 223, 117, 8, 1, 2, 6, 153, 71, 8, 200, 230, 2, 1, 223, 35, + 52, 1, 6, 196, 12, 8, 6, 1, 206, 9, 4, 200, 146, 199, 215, 8, 6, 1, 191, + 167, 4, 200, 146, 199, 215, 94, 6, 1, 251, 186, 94, 2, 1, 251, 186, 94, + 6, 1, 195, 66, 94, 2, 1, 195, 66, 94, 6, 1, 231, 211, 94, 2, 1, 231, 211, + 94, 6, 1, 237, 255, 94, 2, 1, 237, 255, 94, 6, 1, 234, 165, 94, 2, 1, + 234, 165, 94, 6, 1, 202, 7, 94, 2, 1, 202, 7, 94, 6, 1, 191, 95, 94, 2, + 1, 191, 95, 94, 6, 1, 230, 6, 94, 2, 1, 230, 6, 94, 6, 1, 199, 13, 94, 2, + 1, 199, 13, 94, 6, 1, 228, 32, 94, 2, 1, 228, 32, 94, 6, 1, 222, 77, 94, + 2, 1, 222, 77, 94, 6, 1, 219, 252, 94, 2, 1, 219, 252, 94, 6, 1, 216, + 100, 94, 2, 1, 216, 100, 94, 6, 1, 213, 219, 94, 2, 1, 213, 219, 94, 6, + 1, 220, 248, 94, 2, 1, 220, 248, 94, 6, 1, 74, 94, 2, 1, 74, 94, 6, 1, + 209, 185, 94, 2, 1, 209, 185, 94, 6, 1, 206, 162, 94, 2, 1, 206, 162, 94, + 6, 1, 202, 183, 94, 2, 1, 202, 183, 94, 6, 1, 199, 166, 94, 2, 1, 199, + 166, 94, 6, 1, 196, 168, 94, 2, 1, 196, 168, 94, 6, 1, 233, 23, 94, 2, 1, + 233, 23, 94, 6, 1, 221, 190, 94, 2, 1, 221, 190, 94, 6, 1, 208, 176, 94, + 2, 1, 208, 176, 94, 6, 1, 211, 81, 94, 2, 1, 211, 81, 94, 6, 1, 237, 37, + 251, 192, 94, 2, 1, 237, 37, 251, 192, 94, 6, 1, 39, 94, 251, 230, 94, 2, + 1, 39, 94, 251, 230, 94, 6, 1, 238, 198, 234, 165, 94, 2, 1, 238, 198, + 234, 165, 94, 6, 1, 237, 37, 222, 77, 94, 2, 1, 237, 37, 222, 77, 94, 6, + 1, 237, 37, 213, 219, 94, 2, 1, 237, 37, 213, 219, 94, 6, 1, 238, 198, + 213, 219, 94, 2, 1, 238, 198, 213, 219, 94, 6, 1, 39, 94, 211, 81, 94, 2, + 1, 39, 94, 211, 81, 94, 6, 1, 205, 145, 94, 2, 1, 205, 145, 94, 6, 1, + 238, 214, 203, 105, 94, 2, 1, 238, 214, 203, 105, 94, 6, 1, 39, 94, 203, + 105, 94, 2, 1, 39, 94, 203, 105, 94, 6, 1, 39, 94, 234, 12, 94, 2, 1, 39, + 94, 234, 12, 94, 6, 1, 251, 212, 221, 195, 94, 2, 1, 251, 212, 221, 195, + 94, 6, 1, 237, 37, 228, 242, 94, 2, 1, 237, 37, 228, 242, 94, 6, 1, 39, + 94, 228, 242, 94, 2, 1, 39, 94, 228, 242, 94, 6, 1, 39, 94, 140, 94, 2, + 1, 39, 94, 140, 94, 6, 1, 220, 142, 140, 94, 2, 1, 220, 142, 140, 94, 6, + 1, 39, 94, 229, 209, 94, 2, 1, 39, 94, 229, 209, 94, 6, 1, 39, 94, 230, + 9, 94, 2, 1, 39, 94, 230, 9, 94, 6, 1, 39, 94, 231, 206, 94, 2, 1, 39, + 94, 231, 206, 94, 6, 1, 39, 94, 236, 193, 94, 2, 1, 39, 94, 236, 193, 94, + 6, 1, 39, 94, 203, 71, 94, 2, 1, 39, 94, 203, 71, 94, 6, 1, 39, 212, 145, + 203, 71, 94, 2, 1, 39, 212, 145, 203, 71, 94, 6, 1, 39, 212, 145, 214, + 16, 94, 2, 1, 39, 212, 145, 214, 16, 94, 6, 1, 39, 212, 145, 212, 81, 94, + 2, 1, 39, 212, 145, 212, 81, 94, 6, 1, 39, 212, 145, 193, 140, 94, 2, 1, + 39, 212, 145, 193, 140, 94, 16, 222, 102, 94, 16, 216, 101, 206, 162, 94, + 16, 209, 186, 206, 162, 94, 16, 201, 89, 94, 16, 199, 167, 206, 162, 94, + 16, 221, 191, 206, 162, 94, 16, 203, 72, 202, 183, 94, 6, 1, 238, 198, + 203, 105, 94, 2, 1, 238, 198, 203, 105, 94, 6, 1, 238, 198, 231, 206, 94, + 2, 1, 238, 198, 231, 206, 94, 33, 213, 220, 58, 94, 33, 201, 213, 250, + 201, 94, 33, 201, 213, 219, 188, 94, 6, 1, 248, 103, 221, 195, 94, 2, 1, + 248, 103, 221, 195, 94, 39, 212, 145, 232, 80, 201, 63, 94, 39, 212, 145, + 236, 234, 208, 13, 77, 94, 39, 212, 145, 223, 142, 208, 13, 77, 94, 39, + 212, 145, 195, 137, 236, 205, 94, 232, 118, 91, 230, 70, 94, 232, 80, + 201, 63, 94, 215, 200, 236, 205, 101, 2, 1, 251, 132, 101, 2, 1, 249, + 101, 101, 2, 1, 231, 210, 101, 2, 1, 236, 150, 101, 2, 1, 234, 103, 101, + 2, 1, 195, 49, 101, 2, 1, 191, 80, 101, 2, 1, 199, 193, 101, 2, 1, 223, + 162, 101, 2, 1, 222, 87, 101, 2, 1, 220, 7, 101, 2, 1, 217, 90, 101, 2, + 1, 214, 216, 101, 2, 1, 211, 104, 101, 2, 1, 210, 131, 101, 2, 1, 191, + 67, 101, 2, 1, 207, 163, 101, 2, 1, 205, 142, 101, 2, 1, 199, 179, 101, + 2, 1, 196, 113, 101, 2, 1, 209, 220, 101, 2, 1, 221, 200, 101, 2, 1, 231, + 82, 101, 2, 1, 208, 81, 101, 2, 1, 203, 69, 101, 2, 1, 243, 81, 101, 2, + 1, 247, 128, 101, 2, 1, 222, 234, 101, 2, 1, 243, 18, 101, 2, 1, 246, + 241, 101, 2, 1, 192, 218, 101, 2, 1, 222, 249, 101, 2, 1, 230, 87, 101, + 2, 1, 229, 245, 101, 2, 1, 229, 145, 101, 2, 1, 193, 125, 101, 2, 1, 230, + 19, 101, 2, 1, 229, 11, 101, 2, 1, 192, 14, 101, 2, 1, 252, 14, 198, 175, + 1, 170, 198, 175, 1, 192, 136, 198, 175, 1, 192, 135, 198, 175, 1, 192, + 125, 198, 175, 1, 192, 123, 198, 175, 1, 248, 218, 252, 62, 192, 118, + 198, 175, 1, 192, 118, 198, 175, 1, 192, 133, 198, 175, 1, 192, 130, 198, + 175, 1, 192, 132, 198, 175, 1, 192, 131, 198, 175, 1, 192, 40, 198, 175, + 1, 192, 127, 198, 175, 1, 192, 116, 198, 175, 1, 197, 86, 192, 116, 198, + 175, 1, 192, 113, 198, 175, 1, 192, 121, 198, 175, 1, 248, 218, 252, 62, + 192, 121, 198, 175, 1, 197, 86, 192, 121, 198, 175, 1, 192, 120, 198, + 175, 1, 192, 140, 198, 175, 1, 192, 114, 198, 175, 1, 197, 86, 192, 114, + 198, 175, 1, 192, 103, 198, 175, 1, 197, 86, 192, 103, 198, 175, 1, 192, + 33, 198, 175, 1, 192, 82, 198, 175, 1, 251, 243, 192, 82, 198, 175, 1, + 197, 86, 192, 82, 198, 175, 1, 192, 112, 198, 175, 1, 192, 111, 198, 175, + 1, 192, 108, 198, 175, 1, 197, 86, 192, 122, 198, 175, 1, 197, 86, 192, + 106, 198, 175, 1, 192, 104, 198, 175, 1, 191, 225, 198, 175, 1, 192, 101, + 198, 175, 1, 192, 99, 198, 175, 1, 192, 124, 198, 175, 1, 197, 86, 192, + 124, 198, 175, 1, 250, 127, 192, 124, 198, 175, 1, 192, 98, 198, 175, 1, + 192, 96, 198, 175, 1, 192, 97, 198, 175, 1, 192, 95, 198, 175, 1, 192, + 94, 198, 175, 1, 192, 134, 198, 175, 1, 192, 92, 198, 175, 1, 192, 90, + 198, 175, 1, 192, 89, 198, 175, 1, 192, 86, 198, 175, 1, 192, 83, 198, + 175, 1, 199, 157, 192, 83, 198, 175, 1, 192, 81, 198, 175, 1, 192, 80, + 198, 175, 1, 192, 12, 198, 175, 52, 1, 220, 115, 77, 198, 175, 204, 11, + 77, 198, 175, 120, 222, 196, 36, 5, 219, 42, 36, 5, 216, 5, 36, 5, 206, + 154, 36, 5, 202, 38, 36, 5, 203, 55, 36, 5, 248, 110, 36, 5, 198, 91, 36, + 5, 242, 98, 36, 5, 213, 36, 36, 5, 212, 64, 36, 5, 231, 11, 211, 182, 36, + 5, 191, 6, 36, 5, 236, 172, 36, 5, 237, 160, 36, 5, 222, 200, 36, 5, 198, + 240, 36, 5, 243, 67, 36, 5, 209, 198, 36, 5, 209, 72, 36, 5, 231, 97, 36, + 5, 231, 93, 36, 5, 231, 94, 36, 5, 231, 95, 36, 5, 201, 175, 36, 5, 201, + 129, 36, 5, 201, 142, 36, 5, 201, 174, 36, 5, 201, 147, 36, 5, 201, 148, + 36, 5, 201, 134, 36, 5, 247, 65, 36, 5, 247, 44, 36, 5, 247, 46, 36, 5, + 247, 64, 36, 5, 247, 62, 36, 5, 247, 63, 36, 5, 247, 45, 36, 5, 190, 224, + 36, 5, 190, 202, 36, 5, 190, 215, 36, 5, 190, 223, 36, 5, 190, 218, 36, + 5, 190, 219, 36, 5, 190, 207, 36, 5, 247, 60, 36, 5, 247, 47, 36, 5, 247, + 49, 36, 5, 247, 59, 36, 5, 247, 57, 36, 5, 247, 58, 36, 5, 247, 48, 36, + 5, 207, 234, 36, 5, 207, 224, 36, 5, 207, 230, 36, 5, 207, 233, 36, 5, + 207, 231, 36, 5, 207, 232, 36, 5, 207, 229, 36, 5, 220, 153, 36, 5, 220, + 145, 36, 5, 220, 148, 36, 5, 220, 152, 36, 5, 220, 149, 36, 5, 220, 150, + 36, 5, 220, 146, 36, 5, 192, 175, 36, 5, 192, 162, 36, 5, 192, 170, 36, + 5, 192, 174, 36, 5, 192, 172, 36, 5, 192, 173, 36, 5, 192, 169, 36, 5, + 230, 128, 36, 5, 230, 118, 36, 5, 230, 121, 36, 5, 230, 127, 36, 5, 230, + 123, 36, 5, 230, 124, 36, 5, 230, 120, 33, 38, 1, 249, 17, 33, 38, 1, + 195, 153, 33, 38, 1, 231, 77, 33, 38, 1, 237, 146, 33, 38, 1, 191, 62, + 33, 38, 1, 191, 87, 33, 38, 1, 155, 33, 38, 1, 234, 140, 33, 38, 1, 234, + 114, 33, 38, 1, 234, 103, 33, 38, 1, 74, 33, 38, 1, 210, 63, 33, 38, 1, + 234, 34, 33, 38, 1, 234, 22, 33, 38, 1, 199, 145, 33, 38, 1, 140, 33, 38, + 1, 197, 161, 33, 38, 1, 243, 127, 33, 38, 1, 203, 165, 33, 38, 1, 203, + 116, 33, 38, 1, 232, 228, 33, 38, 1, 234, 18, 33, 38, 1, 65, 33, 38, 1, + 223, 226, 33, 38, 1, 236, 191, 33, 38, 1, 215, 219, 196, 128, 33, 38, 1, + 192, 95, 33, 38, 1, 191, 225, 33, 38, 1, 223, 81, 65, 33, 38, 1, 219, 83, + 191, 190, 33, 38, 1, 248, 175, 191, 190, 33, 38, 1, 223, 81, 248, 175, + 191, 190, 50, 251, 116, 200, 225, 217, 51, 50, 251, 116, 235, 138, 200, + 225, 217, 51, 45, 200, 225, 248, 53, 50, 200, 225, 248, 53, 45, 235, 138, + 200, 225, 248, 53, 50, 235, 138, 200, 225, 248, 53, 207, 147, 223, 104, + 217, 51, 207, 147, 235, 138, 223, 104, 217, 51, 235, 138, 198, 8, 217, + 51, 45, 198, 8, 248, 53, 50, 198, 8, 248, 53, 207, 147, 201, 190, 45, + 207, 147, 211, 106, 248, 53, 50, 207, 147, 211, 106, 248, 53, 234, 189, + 238, 254, 210, 126, 232, 148, 210, 126, 207, 18, 232, 148, 210, 126, 228, + 85, 235, 138, 211, 177, 235, 119, 251, 126, 196, 66, 251, 126, 235, 138, + 206, 203, 251, 115, 55, 211, 172, 228, 88, 223, 93, 223, 102, 210, 183, + 248, 47, 228, 89, 4, 237, 42, 198, 153, 4, 206, 189, 58, 45, 130, 210, + 116, 248, 53, 50, 130, 210, 116, 248, 53, 198, 153, 4, 75, 58, 198, 153, + 4, 75, 60, 45, 81, 249, 88, 4, 208, 7, 50, 81, 249, 88, 4, 208, 7, 198, + 54, 45, 132, 248, 53, 198, 54, 50, 132, 248, 53, 248, 77, 45, 132, 248, + 53, 248, 77, 50, 132, 248, 53, 45, 202, 206, 126, 248, 53, 50, 202, 206, + 126, 248, 53, 45, 55, 210, 113, 50, 55, 210, 113, 105, 185, 139, 91, 75, + 208, 151, 91, 75, 139, 105, 185, 208, 151, 112, 232, 128, 75, 208, 151, + 232, 226, 75, 77, 207, 18, 208, 13, 77, 81, 198, 152, 206, 189, 209, 61, + 193, 23, 204, 11, 82, 236, 140, 153, 242, 74, 207, 147, 236, 140, 207, + 147, 242, 74, 153, 204, 25, 238, 15, 4, 45, 230, 173, 238, 15, 4, 50, + 230, 173, 153, 238, 14, 198, 54, 132, 205, 54, 56, 197, 14, 237, 215, + 198, 223, 237, 215, 201, 79, 232, 80, 201, 63, 81, 202, 136, 236, 138, + 193, 72, 81, 219, 112, 247, 109, 55, 228, 88, 207, 18, 242, 74, 55, 218, + 237, 207, 252, 77, 237, 216, 4, 45, 196, 69, 55, 200, 164, 77, 223, 93, + 130, 222, 35, 223, 93, 130, 222, 36, 4, 222, 36, 58, 130, 222, 35, 130, + 222, 36, 4, 236, 140, 55, 201, 114, 242, 74, 235, 138, 202, 23, 197, 225, + 238, 14, 216, 214, 242, 74, 210, 125, 77, 208, 150, 234, 129, 77, 238, + 255, 195, 137, 236, 205, 238, 218, 210, 82, 4, 50, 238, 216, 238, 218, + 210, 82, 4, 45, 238, 216, 198, 128, 3, 6, 233, 255, 216, 214, 233, 216, + 77, 216, 214, 208, 13, 77, 45, 51, 248, 54, 4, 106, 50, 51, 248, 54, 4, + 106, 45, 51, 248, 54, 4, 55, 106, 50, 51, 248, 54, 4, 55, 106, 198, 54, + 132, 45, 210, 113, 198, 54, 132, 50, 210, 113, 248, 77, 132, 45, 210, + 113, 248, 77, 132, 50, 210, 113, 211, 172, 228, 88, 12, 48, 207, 48, 12, + 48, 242, 230, 12, 48, 205, 57, 107, 12, 48, 205, 57, 109, 12, 48, 205, + 57, 138, 12, 48, 209, 250, 12, 48, 248, 62, 12, 48, 199, 233, 12, 48, + 221, 79, 107, 12, 48, 221, 79, 109, 12, 48, 236, 202, 12, 48, 205, 61, + 12, 48, 2, 107, 12, 48, 2, 109, 12, 48, 220, 30, 107, 12, 48, 220, 30, + 109, 12, 48, 220, 30, 138, 12, 48, 220, 30, 134, 12, 48, 202, 58, 12, 48, + 198, 227, 12, 48, 202, 55, 107, 12, 48, 202, 55, 109, 12, 48, 229, 224, + 107, 12, 48, 229, 224, 109, 12, 48, 230, 53, 12, 48, 207, 136, 12, 48, + 243, 64, 12, 48, 200, 198, 12, 48, 215, 205, 12, 48, 237, 143, 12, 48, + 215, 193, 12, 48, 242, 249, 12, 48, 193, 144, 107, 12, 48, 193, 144, 109, + 12, 48, 232, 243, 12, 48, 210, 76, 107, 12, 48, 210, 76, 109, 12, 48, + 202, 178, 132, 197, 255, 197, 177, 12, 48, 238, 239, 12, 48, 236, 162, + 12, 48, 223, 27, 12, 48, 248, 102, 79, 242, 213, 12, 48, 233, 193, 12, + 48, 201, 215, 107, 12, 48, 201, 215, 109, 12, 48, 249, 103, 12, 48, 202, + 185, 12, 48, 247, 190, 202, 185, 12, 48, 214, 86, 107, 12, 48, 214, 86, + 109, 12, 48, 214, 86, 138, 12, 48, 214, 86, 134, 12, 48, 216, 172, 12, + 48, 203, 107, 12, 48, 207, 142, 12, 48, 233, 223, 12, 48, 211, 119, 12, + 48, 248, 18, 107, 12, 48, 248, 18, 109, 12, 48, 216, 224, 12, 48, 215, + 199, 12, 48, 230, 214, 107, 12, 48, 230, 214, 109, 12, 48, 230, 214, 138, + 12, 48, 198, 173, 12, 48, 242, 212, 12, 48, 193, 105, 107, 12, 48, 193, + 105, 109, 12, 48, 247, 190, 205, 50, 12, 48, 202, 178, 228, 187, 12, 48, + 228, 187, 12, 48, 247, 190, 201, 229, 12, 48, 247, 190, 203, 102, 12, 48, + 232, 159, 12, 48, 247, 190, 247, 85, 12, 48, 202, 178, 193, 169, 12, 48, + 193, 170, 107, 12, 48, 193, 170, 109, 12, 48, 242, 252, 12, 48, 247, 190, + 230, 250, 12, 48, 179, 107, 12, 48, 179, 109, 12, 48, 247, 190, 219, 19, + 12, 48, 247, 190, 231, 191, 12, 48, 215, 188, 107, 12, 48, 215, 188, 109, + 12, 48, 207, 149, 12, 48, 248, 114, 12, 48, 247, 190, 199, 185, 219, 230, + 12, 48, 247, 190, 219, 233, 12, 48, 247, 190, 193, 66, 12, 48, 247, 190, + 232, 179, 12, 48, 234, 201, 107, 12, 48, 234, 201, 109, 12, 48, 234, 201, + 138, 12, 48, 247, 190, 234, 200, 12, 48, 229, 235, 12, 48, 247, 190, 228, + 183, 12, 48, 248, 98, 12, 48, 231, 61, 12, 48, 247, 190, 232, 236, 12, + 48, 247, 190, 248, 160, 12, 48, 247, 190, 205, 158, 12, 48, 202, 178, + 193, 95, 12, 48, 202, 178, 192, 72, 12, 48, 247, 190, 232, 99, 12, 48, + 223, 34, 233, 228, 12, 48, 247, 190, 233, 228, 12, 48, 223, 34, 198, 56, + 12, 48, 247, 190, 198, 56, 12, 48, 223, 34, 235, 111, 12, 48, 247, 190, + 235, 111, 12, 48, 197, 55, 12, 48, 223, 34, 197, 55, 12, 48, 247, 190, + 197, 55, 83, 48, 107, 83, 48, 219, 112, 83, 48, 236, 140, 83, 48, 202, + 97, 83, 48, 205, 56, 83, 48, 102, 83, 48, 109, 83, 48, 219, 141, 83, 48, + 217, 90, 83, 48, 219, 209, 83, 48, 234, 77, 83, 48, 171, 83, 48, 144, + 248, 62, 83, 48, 238, 242, 83, 48, 228, 26, 83, 48, 199, 233, 83, 48, + 211, 77, 248, 62, 83, 48, 221, 78, 83, 48, 208, 254, 83, 48, 193, 12, 83, + 48, 201, 203, 83, 48, 50, 211, 77, 248, 62, 83, 48, 229, 146, 234, 98, + 83, 48, 199, 95, 83, 48, 236, 202, 83, 48, 205, 61, 83, 48, 242, 230, 83, + 48, 208, 204, 83, 48, 251, 252, 83, 48, 215, 179, 83, 48, 234, 98, 83, + 48, 234, 207, 83, 48, 205, 91, 83, 48, 231, 3, 83, 48, 231, 4, 202, 74, + 83, 48, 233, 227, 83, 48, 248, 174, 83, 48, 193, 35, 83, 48, 243, 86, 83, + 48, 206, 133, 83, 48, 223, 158, 83, 48, 202, 70, 83, 48, 220, 29, 83, 48, + 238, 252, 83, 48, 201, 194, 83, 48, 215, 184, 83, 48, 206, 176, 83, 48, + 193, 20, 83, 48, 211, 95, 83, 48, 197, 63, 83, 48, 235, 91, 83, 48, 203, + 40, 198, 227, 83, 48, 235, 138, 242, 230, 83, 48, 179, 201, 34, 83, 48, + 105, 230, 28, 83, 48, 203, 46, 83, 48, 248, 69, 83, 48, 202, 54, 83, 48, + 248, 25, 83, 48, 201, 78, 83, 48, 229, 223, 83, 48, 230, 71, 83, 48, 236, + 144, 83, 48, 230, 53, 83, 48, 248, 47, 83, 48, 207, 136, 83, 48, 205, 74, + 83, 48, 236, 236, 83, 48, 250, 132, 83, 48, 201, 190, 83, 48, 213, 11, + 83, 48, 200, 198, 83, 48, 205, 103, 83, 48, 215, 205, 83, 48, 197, 254, + 83, 48, 220, 111, 83, 48, 201, 63, 83, 48, 237, 143, 83, 48, 193, 120, + 83, 48, 236, 175, 213, 11, 83, 48, 242, 70, 83, 48, 232, 72, 83, 48, 242, + 243, 83, 48, 201, 84, 83, 48, 193, 143, 83, 48, 232, 243, 83, 48, 242, + 239, 83, 48, 233, 66, 83, 48, 55, 192, 235, 83, 48, 132, 197, 255, 197, + 177, 83, 48, 202, 88, 83, 48, 233, 78, 83, 48, 238, 239, 83, 48, 236, + 162, 83, 48, 208, 199, 83, 48, 223, 27, 83, 48, 216, 196, 83, 48, 198, + 151, 83, 48, 200, 141, 83, 48, 219, 135, 83, 48, 196, 43, 83, 48, 233, + 21, 83, 48, 248, 102, 79, 242, 213, 83, 48, 202, 212, 83, 48, 235, 138, + 199, 87, 83, 48, 193, 89, 83, 48, 202, 107, 83, 48, 236, 222, 83, 48, + 233, 193, 83, 48, 201, 232, 83, 48, 57, 83, 48, 201, 65, 83, 48, 201, + 214, 83, 48, 198, 25, 83, 48, 230, 223, 83, 48, 247, 70, 83, 48, 201, + 107, 83, 48, 249, 103, 83, 48, 206, 245, 83, 48, 202, 185, 83, 48, 223, + 18, 83, 48, 214, 85, 83, 48, 203, 107, 83, 48, 233, 54, 83, 48, 211, 119, + 83, 48, 251, 125, 83, 48, 209, 89, 83, 48, 234, 211, 83, 48, 248, 17, 83, + 48, 216, 224, 83, 48, 216, 37, 83, 48, 204, 32, 83, 48, 250, 239, 83, 48, + 215, 199, 83, 48, 198, 61, 83, 48, 211, 64, 83, 48, 248, 106, 83, 48, + 201, 59, 83, 48, 242, 82, 83, 48, 230, 213, 83, 48, 198, 173, 83, 48, + 223, 121, 83, 48, 248, 120, 83, 48, 193, 170, 234, 98, 83, 48, 242, 212, + 83, 48, 193, 104, 83, 48, 205, 50, 83, 48, 228, 187, 83, 48, 201, 229, + 83, 48, 195, 180, 83, 48, 249, 12, 83, 48, 209, 147, 83, 48, 249, 133, + 83, 48, 203, 102, 83, 48, 207, 86, 83, 48, 206, 45, 83, 48, 232, 159, 83, + 48, 248, 104, 83, 48, 247, 85, 83, 48, 248, 144, 83, 48, 215, 201, 83, + 48, 193, 169, 83, 48, 242, 252, 83, 48, 193, 62, 83, 48, 236, 214, 83, + 48, 195, 50, 83, 48, 230, 250, 83, 48, 219, 19, 83, 48, 231, 191, 83, 48, + 215, 187, 83, 48, 202, 96, 83, 48, 203, 40, 199, 214, 248, 160, 83, 48, + 207, 149, 83, 48, 248, 114, 83, 48, 193, 2, 83, 48, 233, 103, 83, 48, + 219, 230, 83, 48, 199, 185, 219, 230, 83, 48, 219, 226, 83, 48, 202, 4, + 83, 48, 219, 233, 83, 48, 193, 66, 83, 48, 232, 179, 83, 48, 234, 200, + 83, 48, 229, 235, 83, 48, 232, 116, 83, 48, 228, 183, 83, 48, 248, 98, + 83, 48, 199, 199, 83, 48, 230, 78, 83, 48, 233, 14, 83, 48, 205, 194, + 193, 62, 83, 48, 247, 72, 83, 48, 231, 61, 83, 48, 232, 236, 83, 48, 248, + 160, 83, 48, 205, 158, 83, 48, 237, 128, 83, 48, 193, 95, 83, 48, 229, + 199, 83, 48, 192, 72, 83, 48, 216, 49, 83, 48, 248, 139, 83, 48, 234, + 110, 83, 48, 232, 99, 83, 48, 197, 222, 83, 48, 235, 94, 83, 48, 207, + 130, 83, 48, 213, 13, 83, 48, 233, 228, 83, 48, 198, 56, 83, 48, 235, + 111, 83, 48, 197, 55, 83, 48, 232, 182, 154, 237, 85, 246, 240, 45, 119, + 183, 154, 237, 85, 246, 240, 93, 119, 60, 154, 237, 85, 246, 240, 45, + 119, 82, 23, 183, 154, 237, 85, 246, 240, 93, 119, 82, 23, 60, 154, 237, + 85, 246, 240, 232, 80, 200, 168, 154, 237, 85, 246, 240, 200, 169, 232, + 98, 58, 154, 237, 85, 246, 240, 200, 169, 232, 98, 60, 154, 237, 85, 246, + 240, 200, 169, 232, 98, 219, 224, 154, 237, 85, 246, 240, 200, 169, 232, + 98, 116, 219, 224, 154, 237, 85, 246, 240, 200, 169, 232, 98, 116, 183, + 154, 237, 85, 246, 240, 200, 169, 232, 98, 110, 219, 224, 154, 237, 85, + 246, 240, 211, 3, 154, 201, 247, 154, 242, 74, 154, 232, 80, 201, 63, + 236, 211, 77, 223, 19, 223, 141, 201, 106, 113, 154, 223, 51, 77, 154, + 242, 215, 77, 154, 31, 191, 77, 45, 251, 116, 248, 53, 50, 251, 116, 248, + 53, 45, 55, 251, 116, 248, 53, 50, 55, 251, 116, 248, 53, 45, 239, 2, + 248, 53, 50, 239, 2, 248, 53, 45, 63, 239, 2, 248, 53, 50, 63, 239, 2, + 248, 53, 45, 62, 219, 187, 248, 53, 50, 62, 219, 187, 248, 53, 209, 18, + 77, 231, 130, 77, 45, 198, 42, 203, 103, 248, 53, 50, 198, 42, 203, 103, + 248, 53, 45, 63, 219, 187, 248, 53, 50, 63, 219, 187, 248, 53, 45, 63, + 198, 42, 203, 103, 248, 53, 50, 63, 198, 42, 203, 103, 248, 53, 45, 63, + 51, 248, 53, 50, 63, 51, 248, 53, 193, 139, 237, 215, 207, 18, 55, 208, + 216, 207, 252, 77, 55, 208, 216, 207, 252, 77, 130, 55, 208, 216, 207, + 252, 77, 209, 18, 87, 233, 103, 230, 25, 212, 134, 107, 230, 25, 212, + 134, 109, 230, 25, 212, 134, 138, 230, 25, 212, 134, 134, 230, 25, 212, + 134, 149, 230, 25, 212, 134, 169, 230, 25, 212, 134, 175, 230, 25, 212, + 134, 171, 230, 25, 212, 134, 178, 154, 219, 168, 163, 77, 154, 206, 180, + 163, 77, 154, 237, 95, 163, 77, 154, 234, 76, 163, 77, 30, 202, 170, 75, + 163, 77, 30, 55, 75, 163, 77, 193, 135, 237, 215, 81, 222, 86, 207, 49, + 77, 81, 222, 86, 207, 49, 4, 195, 20, 202, 5, 77, 81, 222, 86, 207, 49, + 87, 116, 230, 70, 81, 222, 86, 207, 49, 4, 195, 20, 202, 5, 87, 116, 230, + 70, 81, 222, 86, 207, 49, 87, 110, 230, 70, 47, 209, 18, 77, 154, 199, + 109, 219, 113, 233, 51, 204, 11, 113, 230, 25, 212, 134, 199, 95, 230, + 25, 212, 134, 197, 32, 230, 25, 212, 134, 198, 249, 81, 154, 223, 51, 77, + 217, 31, 77, 210, 107, 251, 153, 77, 154, 67, 223, 144, 154, 132, 233, 6, + 201, 247, 229, 120, 1, 2, 65, 229, 120, 1, 65, 229, 120, 1, 2, 68, 229, + 120, 1, 68, 229, 120, 1, 2, 66, 229, 120, 1, 66, 229, 120, 1, 2, 71, 229, + 120, 1, 71, 229, 120, 1, 2, 74, 229, 120, 1, 74, 229, 120, 1, 155, 229, + 120, 1, 231, 240, 229, 120, 1, 221, 166, 229, 120, 1, 231, 53, 229, 120, + 1, 220, 232, 229, 120, 1, 230, 179, 229, 120, 1, 222, 22, 229, 120, 1, + 231, 165, 229, 120, 1, 221, 67, 229, 120, 1, 231, 3, 229, 120, 1, 188, + 229, 120, 1, 191, 123, 229, 120, 1, 202, 222, 229, 120, 1, 191, 30, 229, + 120, 1, 201, 4, 229, 120, 1, 190, 251, 229, 120, 1, 205, 68, 229, 120, 1, + 191, 87, 229, 120, 1, 202, 46, 229, 120, 1, 191, 7, 229, 120, 1, 190, + 190, 229, 120, 1, 238, 32, 229, 120, 1, 198, 193, 229, 120, 1, 237, 44, + 229, 120, 1, 2, 197, 94, 229, 120, 1, 197, 94, 229, 120, 1, 235, 89, 229, + 120, 1, 199, 145, 229, 120, 1, 237, 146, 229, 120, 1, 159, 229, 120, 1, + 236, 174, 229, 120, 1, 180, 229, 120, 1, 213, 219, 229, 120, 1, 212, 178, + 229, 120, 1, 214, 121, 229, 120, 1, 213, 43, 229, 120, 1, 140, 229, 120, + 1, 249, 153, 229, 120, 1, 168, 229, 120, 1, 229, 158, 229, 120, 1, 248, + 188, 229, 120, 1, 209, 185, 229, 120, 1, 228, 159, 229, 120, 1, 248, 10, + 229, 120, 1, 208, 165, 229, 120, 1, 229, 245, 229, 120, 1, 249, 17, 229, + 120, 1, 210, 63, 229, 120, 1, 229, 23, 229, 120, 1, 248, 111, 229, 120, + 1, 209, 73, 229, 120, 1, 174, 229, 120, 1, 216, 100, 229, 120, 1, 215, + 155, 229, 120, 1, 216, 232, 229, 120, 1, 216, 12, 229, 120, 1, 2, 170, + 229, 120, 1, 170, 229, 120, 1, 2, 191, 225, 229, 120, 1, 191, 225, 229, + 120, 1, 2, 192, 12, 229, 120, 1, 192, 12, 229, 120, 1, 165, 229, 120, 1, + 207, 1, 229, 120, 1, 206, 68, 229, 120, 1, 207, 113, 229, 120, 1, 206, + 162, 229, 120, 1, 2, 193, 190, 229, 120, 1, 193, 190, 229, 120, 1, 193, + 86, 229, 120, 1, 193, 125, 229, 120, 1, 193, 48, 229, 120, 1, 215, 61, + 229, 120, 1, 193, 249, 229, 120, 1, 2, 155, 229, 120, 1, 2, 222, 22, 33, + 222, 48, 195, 20, 202, 5, 77, 33, 222, 48, 204, 30, 202, 5, 77, 222, 48, + 195, 20, 202, 5, 77, 222, 48, 204, 30, 202, 5, 77, 229, 120, 223, 51, 77, + 229, 120, 195, 20, 223, 51, 77, 229, 120, 237, 3, 191, 242, 222, 48, 55, + 228, 88, 72, 1, 2, 65, 72, 1, 65, 72, 1, 2, 68, 72, 1, 68, 72, 1, 2, 66, + 72, 1, 66, 72, 1, 2, 71, 72, 1, 71, 72, 1, 2, 74, 72, 1, 74, 72, 1, 155, + 72, 1, 231, 240, 72, 1, 221, 166, 72, 1, 231, 53, 72, 1, 220, 232, 72, 1, + 230, 179, 72, 1, 222, 22, 72, 1, 231, 165, 72, 1, 221, 67, 72, 1, 231, 3, + 72, 1, 188, 72, 1, 191, 123, 72, 1, 202, 222, 72, 1, 191, 30, 72, 1, 201, + 4, 72, 1, 190, 251, 72, 1, 205, 68, 72, 1, 191, 87, 72, 1, 202, 46, 72, + 1, 191, 7, 72, 1, 190, 190, 72, 1, 238, 32, 72, 1, 198, 193, 72, 1, 237, + 44, 72, 1, 2, 197, 94, 72, 1, 197, 94, 72, 1, 235, 89, 72, 1, 199, 145, + 72, 1, 237, 146, 72, 1, 159, 72, 1, 236, 174, 72, 1, 180, 72, 1, 213, + 219, 72, 1, 212, 178, 72, 1, 214, 121, 72, 1, 213, 43, 72, 1, 140, 72, 1, + 249, 153, 72, 1, 168, 72, 1, 229, 158, 72, 1, 248, 188, 72, 1, 209, 185, + 72, 1, 228, 159, 72, 1, 248, 10, 72, 1, 208, 165, 72, 1, 229, 245, 72, 1, + 249, 17, 72, 1, 210, 63, 72, 1, 229, 23, 72, 1, 248, 111, 72, 1, 209, 73, + 72, 1, 174, 72, 1, 216, 100, 72, 1, 215, 155, 72, 1, 216, 232, 72, 1, + 216, 12, 72, 1, 2, 170, 72, 1, 170, 72, 1, 2, 191, 225, 72, 1, 191, 225, + 72, 1, 2, 192, 12, 72, 1, 192, 12, 72, 1, 165, 72, 1, 207, 1, 72, 1, 206, + 68, 72, 1, 207, 113, 72, 1, 206, 162, 72, 1, 2, 193, 190, 72, 1, 193, + 190, 72, 1, 193, 86, 72, 1, 193, 125, 72, 1, 193, 48, 72, 1, 215, 61, 72, + 1, 193, 249, 72, 1, 2, 155, 72, 1, 2, 222, 22, 72, 1, 195, 188, 72, 1, + 195, 69, 72, 1, 195, 153, 72, 1, 195, 24, 72, 82, 236, 140, 222, 48, 208, + 191, 202, 5, 77, 72, 223, 51, 77, 72, 195, 20, 223, 51, 77, 72, 237, 3, + 221, 27, 248, 88, 1, 250, 120, 248, 88, 1, 210, 236, 248, 88, 1, 218, + 168, 248, 88, 1, 233, 175, 248, 88, 1, 238, 127, 248, 88, 1, 200, 43, + 248, 88, 1, 215, 61, 248, 88, 1, 172, 248, 88, 1, 232, 51, 248, 88, 1, + 222, 152, 248, 88, 1, 230, 116, 248, 88, 1, 223, 35, 248, 88, 1, 208, + 104, 248, 88, 1, 192, 235, 248, 88, 1, 191, 72, 248, 88, 1, 247, 3, 248, + 88, 1, 203, 167, 248, 88, 1, 146, 248, 88, 1, 191, 166, 248, 88, 1, 247, + 193, 248, 88, 1, 206, 8, 248, 88, 1, 65, 248, 88, 1, 74, 248, 88, 1, 71, + 248, 88, 1, 234, 173, 248, 88, 1, 251, 236, 248, 88, 1, 234, 166, 248, + 88, 1, 250, 163, 248, 88, 1, 211, 19, 248, 88, 1, 251, 132, 248, 88, 1, + 234, 103, 248, 88, 1, 251, 122, 248, 88, 1, 234, 88, 248, 88, 1, 234, 34, + 248, 88, 1, 68, 248, 88, 1, 66, 248, 88, 1, 223, 49, 248, 88, 1, 196, 12, + 248, 88, 1, 214, 70, 248, 88, 1, 231, 7, 248, 88, 1, 223, 200, 248, 88, + 1, 187, 4, 75, 58, 248, 88, 1, 213, 80, 30, 1, 221, 113, 30, 1, 201, 167, + 30, 1, 221, 106, 30, 1, 213, 204, 30, 1, 213, 202, 30, 1, 213, 201, 30, + 1, 198, 168, 30, 1, 201, 156, 30, 1, 206, 239, 30, 1, 206, 234, 30, 1, + 206, 231, 30, 1, 206, 224, 30, 1, 206, 219, 30, 1, 206, 214, 30, 1, 206, + 225, 30, 1, 206, 237, 30, 1, 216, 77, 30, 1, 209, 169, 30, 1, 201, 164, + 30, 1, 209, 158, 30, 1, 202, 160, 30, 1, 201, 161, 30, 1, 223, 222, 30, + 1, 243, 24, 30, 1, 201, 171, 30, 1, 243, 91, 30, 1, 221, 188, 30, 1, 199, + 7, 30, 1, 209, 209, 30, 1, 229, 142, 30, 1, 65, 30, 1, 252, 25, 30, 1, + 170, 30, 1, 192, 129, 30, 1, 234, 65, 30, 1, 71, 30, 1, 192, 67, 30, 1, + 192, 80, 30, 1, 74, 30, 1, 193, 190, 30, 1, 193, 176, 30, 1, 211, 151, + 30, 1, 192, 12, 30, 1, 66, 30, 1, 193, 107, 30, 1, 193, 125, 30, 1, 193, + 86, 30, 1, 191, 225, 30, 1, 233, 242, 30, 1, 192, 33, 30, 1, 68, 30, 233, + 3, 30, 1, 201, 165, 30, 1, 213, 194, 30, 1, 213, 196, 30, 1, 213, 199, + 30, 1, 206, 232, 30, 1, 206, 213, 30, 1, 206, 221, 30, 1, 206, 226, 30, + 1, 206, 211, 30, 1, 216, 70, 30, 1, 216, 67, 30, 1, 216, 71, 30, 1, 222, + 71, 30, 1, 209, 164, 30, 1, 209, 150, 30, 1, 209, 156, 30, 1, 209, 153, + 30, 1, 209, 167, 30, 1, 209, 151, 30, 1, 222, 69, 30, 1, 222, 67, 30, 1, + 202, 153, 30, 1, 202, 151, 30, 1, 202, 143, 30, 1, 202, 148, 30, 1, 202, + 158, 30, 1, 210, 149, 30, 1, 201, 168, 30, 1, 192, 57, 30, 1, 192, 51, + 30, 1, 192, 52, 30, 1, 222, 70, 30, 1, 201, 169, 30, 1, 192, 63, 30, 1, + 192, 0, 30, 1, 191, 255, 30, 1, 192, 2, 30, 1, 191, 212, 30, 1, 191, 213, + 30, 1, 191, 216, 30, 1, 251, 25, 30, 1, 251, 19, 154, 251, 96, 219, 101, + 77, 154, 251, 96, 207, 19, 77, 154, 251, 96, 91, 77, 154, 251, 96, 105, + 77, 154, 251, 96, 115, 77, 154, 251, 96, 232, 128, 77, 154, 251, 96, 198, + 54, 77, 154, 251, 96, 82, 77, 154, 251, 96, 248, 77, 77, 154, 251, 96, + 232, 238, 77, 154, 251, 96, 205, 57, 77, 154, 251, 96, 199, 1, 77, 154, + 251, 96, 232, 121, 77, 154, 251, 96, 229, 220, 77, 154, 251, 96, 234, + 208, 77, 154, 251, 96, 217, 91, 77, 248, 88, 1, 248, 10, 248, 88, 1, 191, + 30, 248, 88, 1, 222, 244, 248, 88, 1, 230, 179, 248, 88, 1, 234, 188, + 248, 88, 1, 234, 85, 248, 88, 1, 211, 87, 248, 88, 1, 211, 91, 248, 88, + 1, 223, 77, 248, 88, 1, 251, 98, 248, 88, 1, 223, 128, 248, 88, 1, 196, + 83, 248, 88, 1, 223, 180, 248, 88, 1, 214, 48, 248, 88, 1, 251, 229, 248, + 88, 1, 250, 158, 248, 88, 1, 251, 149, 248, 88, 1, 211, 113, 248, 88, 1, + 211, 94, 248, 88, 1, 223, 125, 248, 88, 53, 1, 210, 236, 248, 88, 53, 1, + 200, 43, 248, 88, 53, 1, 222, 152, 248, 88, 53, 1, 230, 116, 248, 88, 1, + 231, 92, 248, 88, 1, 219, 160, 248, 88, 1, 190, 231, 248, 88, 53, 1, 232, + 51, 248, 88, 1, 230, 136, 248, 88, 1, 220, 180, 248, 88, 1, 211, 151, + 248, 88, 1, 251, 245, 12, 201, 28, 200, 43, 12, 201, 28, 193, 98, 12, + 201, 28, 192, 209, 12, 201, 28, 247, 206, 12, 201, 28, 200, 151, 12, 201, + 28, 228, 78, 12, 201, 28, 228, 82, 12, 201, 28, 228, 169, 12, 201, 28, + 228, 79, 12, 201, 28, 200, 46, 12, 201, 28, 228, 81, 12, 201, 28, 228, + 77, 12, 201, 28, 228, 167, 12, 201, 28, 228, 80, 12, 201, 28, 228, 76, + 12, 201, 28, 215, 61, 12, 201, 28, 230, 116, 12, 201, 28, 206, 8, 12, + 201, 28, 210, 236, 12, 201, 28, 201, 250, 12, 201, 28, 238, 127, 12, 201, + 28, 228, 83, 12, 201, 28, 229, 178, 12, 201, 28, 200, 55, 12, 201, 28, + 200, 128, 12, 201, 28, 201, 118, 12, 201, 28, 203, 173, 12, 201, 28, 210, + 67, 12, 201, 28, 208, 106, 12, 201, 28, 198, 99, 12, 201, 28, 200, 45, + 12, 201, 28, 200, 140, 12, 201, 28, 228, 94, 12, 201, 28, 228, 75, 12, + 201, 28, 209, 230, 12, 201, 28, 208, 104, 72, 1, 2, 220, 232, 72, 1, 2, + 202, 222, 72, 1, 2, 201, 4, 72, 1, 2, 159, 72, 1, 2, 212, 178, 72, 1, 2, + 140, 72, 1, 2, 229, 158, 72, 1, 2, 228, 159, 72, 1, 2, 229, 245, 72, 1, + 2, 229, 23, 72, 1, 2, 215, 155, 72, 1, 2, 165, 72, 1, 2, 207, 1, 72, 1, + 2, 206, 68, 72, 1, 2, 207, 113, 72, 1, 2, 206, 162, 127, 30, 221, 113, + 127, 30, 213, 204, 127, 30, 198, 168, 127, 30, 206, 239, 127, 30, 216, + 77, 127, 30, 209, 169, 127, 30, 202, 160, 127, 30, 223, 222, 127, 30, + 243, 24, 127, 30, 243, 91, 127, 30, 221, 188, 127, 30, 199, 7, 127, 30, + 209, 209, 127, 30, 229, 142, 127, 30, 221, 114, 65, 127, 30, 213, 205, + 65, 127, 30, 198, 169, 65, 127, 30, 206, 240, 65, 127, 30, 216, 78, 65, + 127, 30, 209, 170, 65, 127, 30, 202, 161, 65, 127, 30, 223, 223, 65, 127, + 30, 243, 25, 65, 127, 30, 243, 92, 65, 127, 30, 221, 189, 65, 127, 30, + 199, 8, 65, 127, 30, 209, 210, 65, 127, 30, 229, 143, 65, 127, 30, 243, + 25, 66, 127, 221, 32, 246, 240, 211, 129, 127, 221, 32, 246, 240, 187, + 228, 159, 127, 228, 14, 107, 127, 228, 14, 109, 127, 228, 14, 138, 127, + 228, 14, 134, 127, 228, 14, 149, 127, 228, 14, 169, 127, 228, 14, 175, + 127, 228, 14, 171, 127, 228, 14, 178, 127, 228, 14, 199, 95, 127, 228, + 14, 215, 205, 127, 228, 14, 232, 243, 127, 228, 14, 193, 143, 127, 228, + 14, 193, 28, 127, 228, 14, 216, 165, 127, 228, 14, 234, 207, 127, 228, + 14, 200, 198, 127, 228, 14, 201, 66, 127, 228, 14, 229, 255, 127, 228, + 14, 202, 35, 127, 228, 14, 214, 227, 127, 228, 14, 201, 231, 127, 228, + 14, 232, 254, 127, 228, 14, 239, 50, 127, 228, 14, 220, 114, 127, 228, + 14, 207, 42, 127, 228, 14, 247, 138, 127, 228, 14, 201, 10, 127, 228, 14, + 200, 178, 127, 228, 14, 234, 75, 127, 228, 14, 207, 32, 127, 228, 14, + 251, 168, 127, 228, 14, 233, 31, 127, 228, 14, 207, 30, 127, 228, 14, + 204, 32, 127, 228, 14, 207, 108, 47, 228, 14, 208, 12, 47, 228, 14, 221, + 140, 47, 228, 14, 205, 89, 47, 228, 14, 221, 27, 47, 31, 199, 96, 211, + 105, 62, 201, 190, 47, 31, 197, 33, 211, 105, 62, 201, 190, 47, 31, 198, + 250, 211, 105, 62, 201, 190, 47, 31, 232, 136, 211, 105, 62, 201, 190, + 47, 31, 233, 16, 211, 105, 62, 201, 190, 47, 31, 202, 121, 211, 105, 62, + 201, 190, 47, 31, 203, 242, 211, 105, 62, 201, 190, 47, 31, 234, 154, + 211, 105, 62, 201, 190, 210, 103, 56, 47, 31, 197, 33, 107, 47, 31, 197, + 33, 109, 47, 31, 197, 33, 138, 47, 31, 197, 33, 134, 47, 31, 197, 33, + 149, 47, 31, 197, 33, 169, 47, 31, 197, 33, 175, 47, 31, 197, 33, 171, + 47, 31, 197, 33, 178, 47, 31, 198, 249, 47, 31, 198, 250, 107, 47, 31, + 198, 250, 109, 47, 31, 198, 250, 138, 47, 31, 198, 250, 134, 47, 31, 198, + 250, 149, 47, 30, 221, 113, 47, 30, 213, 204, 47, 30, 198, 168, 47, 30, + 206, 239, 47, 30, 216, 77, 47, 30, 209, 169, 47, 30, 202, 160, 47, 30, + 223, 222, 47, 30, 243, 24, 47, 30, 243, 91, 47, 30, 221, 188, 47, 30, + 199, 7, 47, 30, 209, 209, 47, 30, 229, 142, 47, 30, 221, 114, 65, 47, 30, + 213, 205, 65, 47, 30, 198, 169, 65, 47, 30, 206, 240, 65, 47, 30, 216, + 78, 65, 47, 30, 209, 170, 65, 47, 30, 202, 161, 65, 47, 30, 223, 223, 65, + 47, 30, 243, 25, 65, 47, 30, 243, 92, 65, 47, 30, 221, 189, 65, 47, 30, + 199, 8, 65, 47, 30, 209, 210, 65, 47, 30, 229, 143, 65, 47, 221, 32, 246, + 240, 246, 247, 47, 221, 32, 246, 240, 222, 178, 47, 30, 223, 223, 66, + 221, 32, 201, 106, 113, 47, 228, 14, 107, 47, 228, 14, 109, 47, 228, 14, + 138, 47, 228, 14, 134, 47, 228, 14, 149, 47, 228, 14, 169, 47, 228, 14, + 175, 47, 228, 14, 171, 47, 228, 14, 178, 47, 228, 14, 199, 95, 47, 228, + 14, 215, 205, 47, 228, 14, 232, 243, 47, 228, 14, 193, 143, 47, 228, 14, + 193, 28, 47, 228, 14, 216, 165, 47, 228, 14, 234, 207, 47, 228, 14, 200, + 198, 47, 228, 14, 201, 66, 47, 228, 14, 229, 255, 47, 228, 14, 202, 35, + 47, 228, 14, 214, 227, 47, 228, 14, 201, 231, 47, 228, 14, 232, 254, 47, + 228, 14, 239, 50, 47, 228, 14, 220, 114, 47, 228, 14, 205, 55, 47, 228, + 14, 217, 96, 47, 228, 14, 233, 41, 47, 228, 14, 200, 210, 47, 228, 14, + 233, 220, 47, 228, 14, 208, 211, 47, 228, 14, 250, 167, 47, 228, 14, 223, + 52, 47, 228, 14, 207, 30, 47, 228, 14, 239, 8, 47, 228, 14, 238, 251, 47, + 228, 14, 229, 135, 47, 228, 14, 247, 21, 47, 228, 14, 218, 241, 47, 228, + 14, 219, 224, 47, 228, 14, 183, 47, 228, 14, 216, 215, 47, 228, 14, 207, + 60, 47, 228, 14, 201, 10, 47, 228, 14, 200, 178, 47, 228, 14, 234, 75, + 47, 228, 14, 207, 32, 47, 228, 14, 251, 168, 47, 228, 14, 213, 190, 47, + 31, 198, 250, 169, 47, 31, 198, 250, 175, 47, 31, 198, 250, 171, 47, 31, + 198, 250, 178, 47, 31, 232, 135, 47, 31, 232, 136, 107, 47, 31, 232, 136, + 109, 47, 31, 232, 136, 138, 47, 31, 232, 136, 134, 47, 31, 232, 136, 149, + 47, 31, 232, 136, 169, 47, 31, 232, 136, 175, 47, 31, 232, 136, 171, 47, + 31, 232, 136, 178, 47, 31, 233, 15, 154, 199, 109, 16, 40, 223, 21, 154, + 199, 109, 16, 40, 233, 53, 154, 199, 109, 16, 40, 217, 58, 154, 199, 109, + 16, 40, 251, 39, 154, 199, 109, 16, 40, 217, 21, 154, 199, 109, 16, 40, + 222, 175, 154, 199, 109, 16, 40, 222, 176, 154, 199, 109, 16, 40, 250, + 159, 154, 199, 109, 16, 40, 204, 9, 154, 199, 109, 16, 40, 211, 157, 154, + 199, 109, 16, 40, 212, 255, 154, 199, 109, 16, 40, 237, 140, 51, 229, + 178, 51, 234, 30, 51, 233, 230, 219, 118, 219, 145, 56, 47, 72, 65, 47, + 72, 68, 47, 72, 66, 47, 72, 71, 47, 72, 74, 47, 72, 155, 47, 72, 221, + 166, 47, 72, 220, 232, 47, 72, 222, 22, 47, 72, 221, 67, 47, 72, 188, 47, + 72, 202, 222, 47, 72, 201, 4, 47, 72, 205, 68, 47, 72, 202, 46, 47, 72, + 190, 190, 47, 72, 198, 193, 47, 72, 197, 94, 47, 72, 199, 145, 47, 72, + 159, 47, 72, 180, 47, 72, 213, 219, 47, 72, 212, 178, 47, 72, 214, 121, + 47, 72, 213, 43, 47, 72, 140, 47, 72, 229, 158, 47, 72, 228, 159, 47, 72, + 229, 245, 47, 72, 229, 23, 47, 72, 174, 47, 72, 216, 100, 47, 72, 215, + 155, 47, 72, 216, 232, 47, 72, 216, 12, 47, 72, 170, 47, 72, 191, 225, + 47, 72, 192, 12, 47, 72, 165, 47, 72, 207, 1, 47, 72, 206, 68, 47, 72, + 207, 113, 47, 72, 206, 162, 47, 72, 193, 190, 47, 72, 193, 86, 47, 72, + 193, 125, 47, 72, 193, 48, 51, 234, 33, 214, 228, 207, 68, 51, 251, 64, + 51, 250, 221, 51, 251, 92, 51, 252, 163, 51, 223, 130, 51, 223, 97, 51, + 196, 80, 51, 234, 2, 51, 234, 185, 51, 211, 90, 51, 211, 83, 51, 222, + 100, 51, 222, 63, 51, 222, 58, 51, 231, 195, 51, 231, 205, 51, 231, 41, + 51, 231, 35, 51, 220, 144, 51, 231, 26, 51, 221, 131, 51, 221, 130, 51, + 221, 129, 51, 221, 128, 51, 230, 146, 51, 230, 145, 51, 220, 193, 51, + 220, 196, 51, 222, 9, 51, 221, 29, 51, 221, 38, 51, 205, 180, 51, 205, + 133, 51, 202, 141, 51, 204, 15, 51, 204, 14, 51, 238, 28, 51, 237, 81, + 51, 236, 141, 51, 198, 81, 51, 214, 221, 51, 213, 0, 51, 230, 75, 51, + 210, 214, 51, 210, 213, 51, 249, 150, 51, 209, 181, 51, 209, 143, 51, + 209, 144, 51, 248, 156, 51, 228, 154, 51, 228, 148, 51, 247, 221, 51, + 228, 132, 51, 229, 206, 51, 209, 241, 51, 210, 29, 51, 229, 187, 51, 210, + 25, 51, 210, 43, 51, 248, 252, 51, 209, 57, 51, 248, 84, 51, 228, 255, + 51, 209, 38, 51, 228, 246, 51, 228, 248, 51, 217, 110, 51, 217, 106, 51, + 217, 115, 51, 217, 44, 51, 217, 76, 51, 216, 56, 51, 216, 29, 51, 216, + 28, 51, 216, 203, 51, 216, 200, 51, 216, 204, 51, 192, 139, 51, 192, 137, + 51, 191, 210, 51, 206, 178, 51, 206, 182, 51, 206, 35, 51, 206, 28, 51, + 207, 57, 51, 207, 54, 51, 193, 141, 154, 199, 109, 16, 40, 228, 177, 191, + 77, 154, 199, 109, 16, 40, 228, 177, 107, 154, 199, 109, 16, 40, 228, + 177, 109, 154, 199, 109, 16, 40, 228, 177, 138, 154, 199, 109, 16, 40, + 228, 177, 134, 154, 199, 109, 16, 40, 228, 177, 149, 154, 199, 109, 16, + 40, 228, 177, 169, 154, 199, 109, 16, 40, 228, 177, 175, 154, 199, 109, + 16, 40, 228, 177, 171, 154, 199, 109, 16, 40, 228, 177, 178, 154, 199, + 109, 16, 40, 228, 177, 199, 95, 154, 199, 109, 16, 40, 228, 177, 234, + 127, 154, 199, 109, 16, 40, 228, 177, 197, 37, 154, 199, 109, 16, 40, + 228, 177, 198, 251, 154, 199, 109, 16, 40, 228, 177, 232, 122, 154, 199, + 109, 16, 40, 228, 177, 233, 19, 154, 199, 109, 16, 40, 228, 177, 202, + 130, 154, 199, 109, 16, 40, 228, 177, 203, 244, 154, 199, 109, 16, 40, + 228, 177, 234, 161, 154, 199, 109, 16, 40, 228, 177, 213, 171, 154, 199, + 109, 16, 40, 228, 177, 197, 32, 154, 199, 109, 16, 40, 228, 177, 197, 25, + 154, 199, 109, 16, 40, 228, 177, 197, 20, 154, 199, 109, 16, 40, 228, + 177, 197, 22, 154, 199, 109, 16, 40, 228, 177, 197, 27, 51, 228, 168, 51, + 238, 32, 51, 250, 163, 51, 164, 51, 211, 9, 51, 210, 68, 51, 236, 177, + 51, 236, 178, 201, 189, 51, 236, 178, 238, 189, 51, 223, 49, 51, 234, 33, + 214, 228, 229, 207, 51, 234, 33, 214, 228, 200, 66, 51, 234, 33, 214, + 228, 199, 212, 51, 234, 33, 214, 228, 216, 199, 51, 238, 253, 51, 210, + 221, 251, 135, 51, 180, 51, 215, 156, 65, 51, 174, 51, 155, 51, 222, 25, + 51, 217, 16, 51, 231, 183, 51, 247, 144, 51, 222, 24, 51, 209, 231, 51, + 214, 72, 51, 215, 156, 233, 175, 51, 215, 156, 232, 51, 51, 216, 141, 51, + 221, 217, 51, 228, 83, 51, 221, 168, 51, 216, 102, 51, 231, 55, 51, 198, + 195, 51, 215, 156, 172, 51, 216, 20, 51, 236, 187, 51, 221, 95, 51, 232, + 177, 51, 213, 81, 51, 215, 156, 218, 168, 51, 216, 17, 51, 242, 199, 51, + 221, 81, 51, 216, 18, 201, 189, 51, 242, 200, 201, 189, 51, 218, 169, + 201, 189, 51, 221, 82, 201, 189, 51, 216, 18, 238, 189, 51, 242, 200, + 238, 189, 51, 218, 169, 238, 189, 51, 221, 82, 238, 189, 51, 218, 169, + 139, 206, 8, 51, 218, 169, 139, 206, 9, 201, 189, 51, 168, 51, 221, 21, + 51, 215, 166, 51, 230, 229, 51, 207, 168, 51, 207, 169, 139, 206, 8, 51, + 207, 169, 139, 206, 9, 201, 189, 51, 208, 178, 51, 212, 219, 51, 215, + 156, 206, 8, 51, 215, 158, 51, 208, 124, 51, 212, 112, 51, 215, 156, 196, + 12, 51, 215, 87, 51, 220, 182, 51, 215, 88, 216, 203, 51, 208, 123, 51, + 212, 111, 51, 215, 156, 193, 224, 51, 215, 81, 51, 220, 180, 51, 215, 82, + 216, 203, 51, 222, 153, 211, 134, 51, 218, 169, 211, 134, 51, 251, 149, + 51, 248, 57, 51, 247, 66, 51, 247, 43, 51, 247, 194, 139, 221, 217, 51, + 242, 99, 51, 237, 200, 51, 230, 129, 51, 140, 51, 228, 169, 51, 223, 162, + 51, 221, 102, 51, 221, 82, 247, 110, 51, 220, 234, 51, 219, 46, 51, 219, + 45, 51, 219, 30, 51, 218, 184, 51, 217, 17, 202, 70, 51, 216, 55, 51, + 215, 233, 51, 209, 229, 51, 209, 76, 51, 208, 249, 51, 208, 247, 51, 201, + 180, 51, 200, 158, 51, 193, 127, 51, 196, 13, 139, 218, 168, 51, 42, 139, + 218, 168, 154, 199, 109, 16, 40, 237, 204, 107, 154, 199, 109, 16, 40, + 237, 204, 109, 154, 199, 109, 16, 40, 237, 204, 138, 154, 199, 109, 16, + 40, 237, 204, 134, 154, 199, 109, 16, 40, 237, 204, 149, 154, 199, 109, + 16, 40, 237, 204, 169, 154, 199, 109, 16, 40, 237, 204, 175, 154, 199, + 109, 16, 40, 237, 204, 171, 154, 199, 109, 16, 40, 237, 204, 178, 154, + 199, 109, 16, 40, 237, 204, 199, 95, 154, 199, 109, 16, 40, 237, 204, + 234, 127, 154, 199, 109, 16, 40, 237, 204, 197, 37, 154, 199, 109, 16, + 40, 237, 204, 198, 251, 154, 199, 109, 16, 40, 237, 204, 232, 122, 154, + 199, 109, 16, 40, 237, 204, 233, 19, 154, 199, 109, 16, 40, 237, 204, + 202, 130, 154, 199, 109, 16, 40, 237, 204, 203, 244, 154, 199, 109, 16, + 40, 237, 204, 234, 161, 154, 199, 109, 16, 40, 237, 204, 213, 171, 154, + 199, 109, 16, 40, 237, 204, 197, 32, 154, 199, 109, 16, 40, 237, 204, + 197, 25, 154, 199, 109, 16, 40, 237, 204, 197, 20, 154, 199, 109, 16, 40, + 237, 204, 197, 22, 154, 199, 109, 16, 40, 237, 204, 197, 27, 154, 199, + 109, 16, 40, 237, 204, 197, 28, 154, 199, 109, 16, 40, 237, 204, 197, 23, + 154, 199, 109, 16, 40, 237, 204, 197, 24, 154, 199, 109, 16, 40, 237, + 204, 197, 31, 154, 199, 109, 16, 40, 237, 204, 197, 26, 154, 199, 109, + 16, 40, 237, 204, 198, 249, 154, 199, 109, 16, 40, 237, 204, 198, 247, + 51, 231, 222, 229, 181, 40, 199, 34, 238, 231, 229, 219, 229, 181, 40, + 199, 34, 207, 100, 234, 207, 229, 181, 40, 237, 14, 250, 183, 199, 34, + 248, 247, 229, 181, 40, 191, 238, 232, 168, 229, 181, 40, 193, 171, 229, + 181, 40, 239, 53, 229, 181, 40, 199, 34, 250, 246, 229, 181, 40, 229, 6, + 198, 87, 229, 181, 40, 2, 199, 194, 229, 181, 40, 198, 1, 229, 181, 40, + 210, 60, 229, 181, 40, 201, 104, 229, 181, 40, 233, 43, 229, 181, 40, + 230, 206, 209, 21, 229, 181, 40, 215, 254, 229, 181, 40, 234, 74, 229, + 181, 40, 232, 169, 229, 181, 40, 193, 21, 211, 105, 199, 34, 237, 141, + 229, 181, 40, 251, 43, 229, 181, 40, 239, 31, 229, 181, 40, 248, 145, + 198, 215, 229, 181, 40, 230, 227, 229, 181, 40, 201, 208, 251, 63, 229, + 181, 40, 207, 22, 229, 181, 40, 223, 124, 229, 181, 40, 230, 206, 199, + 194, 229, 181, 40, 215, 180, 239, 0, 229, 181, 40, 230, 206, 208, 224, + 229, 181, 40, 199, 34, 252, 65, 193, 143, 229, 181, 40, 199, 34, 242, + 227, 232, 243, 229, 181, 40, 223, 138, 229, 181, 40, 235, 64, 229, 181, + 40, 207, 25, 229, 181, 40, 230, 206, 208, 254, 229, 181, 40, 208, 197, + 229, 181, 40, 237, 220, 79, 199, 34, 219, 132, 229, 181, 40, 199, 34, + 233, 81, 229, 181, 40, 211, 62, 229, 181, 40, 211, 167, 229, 181, 40, + 237, 111, 229, 181, 40, 237, 133, 229, 181, 40, 223, 153, 229, 181, 40, + 248, 41, 229, 181, 40, 242, 76, 119, 216, 206, 229, 181, 40, 231, 190, + 198, 87, 229, 181, 40, 208, 135, 196, 67, 229, 181, 40, 211, 61, 229, + 181, 40, 199, 34, 193, 109, 229, 181, 40, 207, 13, 229, 181, 40, 199, 34, + 247, 72, 229, 181, 40, 199, 34, 250, 242, 198, 209, 229, 181, 40, 199, + 34, 222, 10, 201, 70, 215, 184, 229, 181, 40, 237, 76, 229, 181, 40, 199, + 34, 217, 47, 217, 111, 229, 181, 40, 252, 66, 229, 181, 40, 199, 34, 193, + 161, 229, 181, 40, 199, 34, 231, 145, 193, 66, 229, 181, 40, 199, 34, + 222, 184, 220, 43, 229, 181, 40, 236, 219, 229, 181, 40, 219, 119, 229, + 181, 40, 223, 127, 197, 176, 229, 181, 40, 2, 208, 224, 229, 181, 40, + 251, 254, 242, 66, 229, 181, 40, 248, 250, 242, 66, 11, 5, 223, 53, 11, + 5, 223, 45, 11, 5, 68, 11, 5, 223, 80, 11, 5, 223, 224, 11, 5, 223, 207, + 11, 5, 223, 226, 11, 5, 223, 225, 11, 5, 250, 182, 11, 5, 250, 133, 11, + 5, 65, 11, 5, 251, 65, 11, 5, 196, 78, 11, 5, 196, 82, 11, 5, 196, 79, + 11, 5, 211, 30, 11, 5, 210, 247, 11, 5, 74, 11, 5, 211, 78, 11, 5, 233, + 221, 11, 5, 71, 11, 5, 193, 0, 11, 5, 248, 148, 11, 5, 248, 143, 11, 5, + 248, 188, 11, 5, 248, 161, 11, 5, 248, 177, 11, 5, 248, 176, 11, 5, 248, + 179, 11, 5, 248, 178, 11, 5, 249, 64, 11, 5, 249, 56, 11, 5, 249, 153, + 11, 5, 249, 89, 11, 5, 247, 234, 11, 5, 247, 238, 11, 5, 247, 235, 11, 5, + 248, 81, 11, 5, 248, 62, 11, 5, 248, 111, 11, 5, 248, 89, 11, 5, 248, + 206, 11, 5, 249, 17, 11, 5, 248, 219, 11, 5, 247, 217, 11, 5, 247, 211, + 11, 5, 248, 10, 11, 5, 247, 232, 11, 5, 247, 225, 11, 5, 247, 230, 11, 5, + 247, 199, 11, 5, 247, 197, 11, 5, 247, 204, 11, 5, 247, 202, 11, 5, 247, + 200, 11, 5, 247, 201, 11, 5, 209, 117, 11, 5, 209, 113, 11, 5, 209, 185, + 11, 5, 209, 129, 11, 5, 209, 149, 11, 5, 209, 176, 11, 5, 209, 172, 11, + 5, 210, 89, 11, 5, 210, 73, 11, 5, 168, 11, 5, 210, 137, 11, 5, 208, 145, + 11, 5, 208, 147, 11, 5, 208, 146, 11, 5, 209, 14, 11, 5, 208, 252, 11, 5, + 209, 73, 11, 5, 209, 33, 11, 5, 208, 131, 11, 5, 208, 126, 11, 5, 208, + 165, 11, 5, 208, 144, 11, 5, 208, 136, 11, 5, 208, 142, 11, 5, 208, 108, + 11, 5, 208, 107, 11, 5, 208, 112, 11, 5, 208, 111, 11, 5, 208, 109, 11, + 5, 208, 110, 11, 5, 249, 38, 11, 5, 249, 37, 11, 5, 249, 44, 11, 5, 249, + 39, 11, 5, 249, 41, 11, 5, 249, 40, 11, 5, 249, 43, 11, 5, 249, 42, 11, + 5, 249, 50, 11, 5, 249, 49, 11, 5, 249, 53, 11, 5, 249, 51, 11, 5, 249, + 29, 11, 5, 249, 31, 11, 5, 249, 30, 11, 5, 249, 34, 11, 5, 249, 33, 11, + 5, 249, 36, 11, 5, 249, 35, 11, 5, 249, 45, 11, 5, 249, 48, 11, 5, 249, + 46, 11, 5, 249, 25, 11, 5, 249, 24, 11, 5, 249, 32, 11, 5, 249, 28, 11, + 5, 249, 26, 11, 5, 249, 27, 11, 5, 249, 21, 11, 5, 249, 20, 11, 5, 249, + 23, 11, 5, 249, 22, 11, 5, 214, 185, 11, 5, 214, 184, 11, 5, 214, 190, + 11, 5, 214, 186, 11, 5, 214, 187, 11, 5, 214, 189, 11, 5, 214, 188, 11, + 5, 214, 193, 11, 5, 214, 192, 11, 5, 214, 195, 11, 5, 214, 194, 11, 5, + 214, 181, 11, 5, 214, 180, 11, 5, 214, 183, 11, 5, 214, 182, 11, 5, 214, + 174, 11, 5, 214, 173, 11, 5, 214, 178, 11, 5, 214, 177, 11, 5, 214, 175, + 11, 5, 214, 176, 11, 5, 214, 168, 11, 5, 214, 167, 11, 5, 214, 172, 11, + 5, 214, 171, 11, 5, 214, 169, 11, 5, 214, 170, 11, 5, 229, 67, 11, 5, + 229, 66, 11, 5, 229, 72, 11, 5, 229, 68, 11, 5, 229, 69, 11, 5, 229, 71, + 11, 5, 229, 70, 11, 5, 229, 75, 11, 5, 229, 74, 11, 5, 229, 77, 11, 5, + 229, 76, 11, 5, 229, 58, 11, 5, 229, 60, 11, 5, 229, 59, 11, 5, 229, 63, + 11, 5, 229, 62, 11, 5, 229, 65, 11, 5, 229, 64, 11, 5, 229, 54, 11, 5, + 229, 53, 11, 5, 229, 61, 11, 5, 229, 57, 11, 5, 229, 55, 11, 5, 229, 56, + 11, 5, 229, 48, 11, 5, 229, 52, 11, 5, 229, 51, 11, 5, 229, 49, 11, 5, + 229, 50, 11, 5, 216, 23, 11, 5, 216, 22, 11, 5, 216, 100, 11, 5, 216, 31, + 11, 5, 216, 63, 11, 5, 216, 81, 11, 5, 216, 79, 11, 5, 217, 30, 11, 5, + 217, 24, 11, 5, 174, 11, 5, 217, 71, 11, 5, 215, 115, 11, 5, 215, 114, + 11, 5, 215, 118, 11, 5, 215, 116, 11, 5, 215, 195, 11, 5, 215, 168, 11, + 5, 216, 12, 11, 5, 215, 202, 11, 5, 216, 152, 11, 5, 216, 232, 11, 5, + 215, 95, 11, 5, 215, 89, 11, 5, 215, 155, 11, 5, 215, 111, 11, 5, 215, + 104, 11, 5, 215, 109, 11, 5, 215, 65, 11, 5, 215, 64, 11, 5, 215, 70, 11, + 5, 215, 67, 11, 5, 232, 229, 11, 5, 232, 222, 11, 5, 233, 23, 11, 5, 232, + 245, 11, 5, 233, 72, 11, 5, 233, 63, 11, 5, 233, 109, 11, 5, 233, 77, 11, + 5, 232, 119, 11, 5, 232, 175, 11, 5, 232, 154, 11, 5, 232, 68, 11, 5, + 232, 67, 11, 5, 232, 86, 11, 5, 232, 73, 11, 5, 232, 71, 11, 5, 232, 72, + 11, 5, 232, 54, 11, 5, 232, 53, 11, 5, 232, 57, 11, 5, 232, 55, 11, 5, + 195, 32, 11, 5, 195, 26, 11, 5, 195, 69, 11, 5, 195, 41, 11, 5, 195, 58, + 11, 5, 195, 53, 11, 5, 195, 61, 11, 5, 195, 60, 11, 5, 195, 162, 11, 5, + 195, 157, 11, 5, 195, 188, 11, 5, 195, 175, 11, 5, 195, 4, 11, 5, 195, 0, + 11, 5, 195, 24, 11, 5, 195, 6, 11, 5, 195, 73, 11, 5, 195, 141, 11, 5, + 193, 242, 11, 5, 193, 240, 11, 5, 193, 249, 11, 5, 193, 245, 11, 5, 193, + 243, 11, 5, 193, 244, 11, 5, 193, 229, 11, 5, 193, 228, 11, 5, 193, 235, + 11, 5, 193, 234, 11, 5, 193, 232, 11, 5, 193, 233, 11, 5, 236, 212, 11, + 5, 236, 197, 11, 5, 237, 44, 11, 5, 236, 240, 11, 5, 237, 19, 11, 5, 237, + 24, 11, 5, 237, 23, 11, 5, 237, 211, 11, 5, 237, 205, 11, 5, 238, 32, 11, + 5, 237, 231, 11, 5, 235, 69, 11, 5, 235, 70, 11, 5, 236, 140, 11, 5, 235, + 117, 11, 5, 236, 174, 11, 5, 236, 143, 11, 5, 237, 74, 11, 5, 237, 146, + 11, 5, 237, 96, 11, 5, 235, 60, 11, 5, 235, 58, 11, 5, 235, 89, 11, 5, + 235, 68, 11, 5, 235, 63, 11, 5, 235, 66, 11, 5, 198, 125, 11, 5, 198, + 117, 11, 5, 198, 193, 11, 5, 198, 135, 11, 5, 198, 176, 11, 5, 198, 178, + 11, 5, 198, 177, 11, 5, 199, 171, 11, 5, 199, 156, 11, 5, 190, 190, 11, + 5, 199, 183, 11, 5, 197, 69, 11, 5, 197, 68, 11, 5, 197, 71, 11, 5, 197, + 70, 11, 5, 198, 40, 11, 5, 198, 29, 11, 5, 159, 11, 5, 198, 53, 11, 5, + 199, 55, 11, 5, 199, 145, 11, 5, 199, 82, 11, 5, 197, 52, 11, 5, 197, 47, + 11, 5, 197, 94, 11, 5, 197, 67, 11, 5, 197, 53, 11, 5, 197, 64, 11, 5, + 237, 163, 11, 5, 237, 162, 11, 5, 237, 168, 11, 5, 237, 164, 11, 5, 237, + 165, 11, 5, 237, 167, 11, 5, 237, 166, 11, 5, 237, 184, 11, 5, 237, 183, + 11, 5, 237, 191, 11, 5, 237, 185, 11, 5, 237, 153, 11, 5, 237, 155, 11, + 5, 237, 154, 11, 5, 237, 158, 11, 5, 237, 157, 11, 5, 237, 161, 11, 5, + 237, 159, 11, 5, 237, 176, 11, 5, 237, 179, 11, 5, 237, 177, 11, 5, 237, + 149, 11, 5, 237, 148, 11, 5, 237, 156, 11, 5, 237, 152, 11, 5, 237, 150, + 11, 5, 237, 151, 11, 5, 214, 140, 11, 5, 214, 139, 11, 5, 214, 147, 11, + 5, 214, 142, 11, 5, 214, 143, 11, 5, 214, 144, 11, 5, 214, 156, 11, 5, + 214, 155, 11, 5, 214, 162, 11, 5, 214, 157, 11, 5, 214, 132, 11, 5, 214, + 131, 11, 5, 214, 138, 11, 5, 214, 133, 11, 5, 214, 148, 11, 5, 214, 154, + 11, 5, 214, 152, 11, 5, 214, 124, 11, 5, 214, 123, 11, 5, 214, 129, 11, + 5, 214, 127, 11, 5, 214, 125, 11, 5, 214, 126, 11, 5, 229, 33, 11, 5, + 229, 32, 11, 5, 229, 39, 11, 5, 229, 34, 11, 5, 229, 36, 11, 5, 229, 35, + 11, 5, 229, 38, 11, 5, 229, 37, 11, 5, 229, 45, 11, 5, 229, 43, 11, 5, + 229, 47, 11, 5, 229, 46, 11, 5, 229, 26, 11, 5, 229, 27, 11, 5, 229, 30, + 11, 5, 229, 29, 11, 5, 229, 31, 11, 5, 229, 40, 11, 5, 229, 42, 11, 5, + 229, 41, 11, 5, 229, 25, 11, 5, 213, 162, 11, 5, 213, 160, 11, 5, 213, + 219, 11, 5, 213, 165, 11, 5, 213, 193, 11, 5, 213, 207, 11, 5, 213, 206, + 11, 5, 214, 200, 11, 5, 180, 11, 5, 214, 218, 11, 5, 212, 122, 11, 5, + 212, 124, 11, 5, 212, 123, 11, 5, 213, 11, 11, 5, 212, 251, 11, 5, 213, + 43, 11, 5, 213, 22, 11, 5, 214, 74, 11, 5, 214, 121, 11, 5, 214, 97, 11, + 5, 212, 117, 11, 5, 212, 113, 11, 5, 212, 178, 11, 5, 212, 121, 11, 5, + 212, 119, 11, 5, 212, 120, 11, 5, 229, 98, 11, 5, 229, 97, 11, 5, 229, + 103, 11, 5, 229, 99, 11, 5, 229, 100, 11, 5, 229, 102, 11, 5, 229, 101, + 11, 5, 229, 109, 11, 5, 229, 107, 11, 5, 229, 111, 11, 5, 229, 110, 11, + 5, 229, 90, 11, 5, 229, 92, 11, 5, 229, 91, 11, 5, 229, 94, 11, 5, 229, + 96, 11, 5, 229, 95, 11, 5, 229, 104, 11, 5, 229, 106, 11, 5, 229, 105, + 11, 5, 229, 86, 11, 5, 229, 85, 11, 5, 229, 93, 11, 5, 229, 89, 11, 5, + 229, 87, 11, 5, 229, 88, 11, 5, 229, 80, 11, 5, 229, 79, 11, 5, 229, 84, + 11, 5, 229, 83, 11, 5, 229, 81, 11, 5, 229, 82, 11, 5, 219, 87, 11, 5, + 219, 79, 11, 5, 219, 146, 11, 5, 219, 98, 11, 5, 219, 137, 11, 5, 219, + 136, 11, 5, 219, 140, 11, 5, 219, 138, 11, 5, 220, 5, 11, 5, 219, 249, + 11, 5, 173, 11, 5, 220, 16, 11, 5, 218, 201, 11, 5, 218, 200, 11, 5, 218, + 203, 11, 5, 218, 202, 11, 5, 218, 249, 11, 5, 218, 234, 11, 5, 219, 43, + 11, 5, 219, 1, 11, 5, 219, 164, 11, 5, 219, 238, 11, 5, 219, 184, 11, 5, + 218, 195, 11, 5, 218, 193, 11, 5, 218, 225, 11, 5, 218, 199, 11, 5, 218, + 197, 11, 5, 218, 198, 11, 5, 218, 173, 11, 5, 218, 172, 11, 5, 218, 183, + 11, 5, 218, 176, 11, 5, 218, 174, 11, 5, 218, 175, 11, 5, 231, 22, 11, 5, + 231, 21, 11, 5, 231, 53, 11, 5, 231, 34, 11, 5, 231, 45, 11, 5, 231, 44, + 11, 5, 231, 47, 11, 5, 231, 46, 11, 5, 231, 192, 11, 5, 231, 187, 11, 5, + 231, 240, 11, 5, 231, 203, 11, 5, 230, 152, 11, 5, 230, 151, 11, 5, 230, + 154, 11, 5, 230, 153, 11, 5, 230, 232, 11, 5, 230, 230, 11, 5, 231, 3, + 11, 5, 230, 242, 11, 5, 231, 131, 11, 5, 231, 129, 11, 5, 231, 165, 11, + 5, 231, 142, 11, 5, 230, 140, 11, 5, 230, 139, 11, 5, 230, 179, 11, 5, + 230, 150, 11, 5, 230, 141, 11, 5, 230, 149, 11, 5, 221, 120, 11, 5, 221, + 115, 11, 5, 221, 166, 11, 5, 221, 134, 11, 5, 221, 147, 11, 5, 221, 151, + 11, 5, 221, 149, 11, 5, 222, 49, 11, 5, 222, 30, 11, 5, 155, 11, 5, 222, + 78, 11, 5, 220, 202, 11, 5, 220, 207, 11, 5, 220, 204, 11, 5, 221, 28, + 11, 5, 221, 23, 11, 5, 221, 67, 11, 5, 221, 36, 11, 5, 221, 241, 11, 5, + 221, 224, 11, 5, 222, 22, 11, 5, 221, 245, 11, 5, 220, 188, 11, 5, 220, + 184, 11, 5, 220, 232, 11, 5, 220, 201, 11, 5, 220, 192, 11, 5, 220, 197, + 11, 5, 231, 113, 11, 5, 231, 112, 11, 5, 231, 117, 11, 5, 231, 114, 11, + 5, 231, 116, 11, 5, 231, 115, 11, 5, 231, 124, 11, 5, 231, 123, 11, 5, + 231, 127, 11, 5, 231, 125, 11, 5, 231, 104, 11, 5, 231, 103, 11, 5, 231, + 106, 11, 5, 231, 105, 11, 5, 231, 109, 11, 5, 231, 108, 11, 5, 231, 111, + 11, 5, 231, 110, 11, 5, 231, 119, 11, 5, 231, 118, 11, 5, 231, 122, 11, + 5, 231, 120, 11, 5, 231, 99, 11, 5, 231, 98, 11, 5, 231, 107, 11, 5, 231, + 102, 11, 5, 231, 100, 11, 5, 231, 101, 11, 5, 216, 119, 11, 5, 216, 120, + 11, 5, 216, 138, 11, 5, 216, 137, 11, 5, 216, 140, 11, 5, 216, 139, 11, + 5, 216, 110, 11, 5, 216, 112, 11, 5, 216, 111, 11, 5, 216, 115, 11, 5, + 216, 114, 11, 5, 216, 117, 11, 5, 216, 116, 11, 5, 216, 121, 11, 5, 216, + 123, 11, 5, 216, 122, 11, 5, 216, 106, 11, 5, 216, 105, 11, 5, 216, 113, + 11, 5, 216, 109, 11, 5, 216, 107, 11, 5, 216, 108, 11, 5, 228, 104, 11, + 5, 228, 103, 11, 5, 228, 110, 11, 5, 228, 105, 11, 5, 228, 107, 11, 5, + 228, 106, 11, 5, 228, 109, 11, 5, 228, 108, 11, 5, 228, 115, 11, 5, 228, + 114, 11, 5, 228, 117, 11, 5, 228, 116, 11, 5, 228, 96, 11, 5, 228, 95, + 11, 5, 228, 98, 11, 5, 228, 97, 11, 5, 228, 100, 11, 5, 228, 99, 11, 5, + 228, 102, 11, 5, 228, 101, 11, 5, 228, 111, 11, 5, 228, 113, 11, 5, 228, + 112, 11, 5, 214, 13, 11, 5, 214, 15, 11, 5, 214, 14, 11, 5, 214, 58, 11, + 5, 214, 56, 11, 5, 214, 68, 11, 5, 214, 61, 11, 5, 213, 230, 11, 5, 213, + 229, 11, 5, 213, 231, 11, 5, 213, 241, 11, 5, 213, 238, 11, 5, 213, 249, + 11, 5, 213, 243, 11, 5, 214, 49, 11, 5, 214, 55, 11, 5, 214, 51, 11, 5, + 229, 117, 11, 5, 229, 136, 11, 5, 229, 145, 11, 5, 230, 9, 11, 5, 229, + 253, 11, 5, 140, 11, 5, 230, 21, 11, 5, 228, 134, 11, 5, 228, 133, 11, 5, + 228, 136, 11, 5, 228, 135, 11, 5, 228, 180, 11, 5, 228, 171, 11, 5, 229, + 23, 11, 5, 228, 244, 11, 5, 229, 183, 11, 5, 229, 245, 11, 5, 229, 195, + 11, 5, 193, 146, 11, 5, 193, 131, 11, 5, 193, 190, 11, 5, 193, 158, 11, + 5, 192, 245, 11, 5, 192, 247, 11, 5, 192, 246, 11, 5, 193, 13, 11, 5, + 193, 48, 11, 5, 193, 24, 11, 5, 193, 99, 11, 5, 193, 125, 11, 5, 193, + 106, 11, 5, 191, 15, 11, 5, 191, 14, 11, 5, 191, 30, 11, 5, 191, 18, 11, + 5, 191, 23, 11, 5, 191, 25, 11, 5, 191, 24, 11, 5, 191, 96, 11, 5, 191, + 93, 11, 5, 191, 123, 11, 5, 191, 104, 11, 5, 190, 244, 11, 5, 190, 246, + 11, 5, 190, 245, 11, 5, 191, 2, 11, 5, 191, 1, 11, 5, 191, 7, 11, 5, 191, + 3, 11, 5, 191, 73, 11, 5, 191, 87, 11, 5, 191, 79, 11, 5, 190, 240, 11, + 5, 190, 239, 11, 5, 190, 251, 11, 5, 190, 243, 11, 5, 190, 241, 11, 5, + 190, 242, 11, 5, 190, 226, 11, 5, 190, 225, 11, 5, 190, 231, 11, 5, 190, + 229, 11, 5, 190, 227, 11, 5, 190, 228, 11, 5, 242, 255, 11, 5, 242, 248, + 11, 5, 243, 29, 11, 5, 243, 12, 11, 5, 243, 26, 11, 5, 243, 20, 11, 5, + 243, 28, 11, 5, 243, 27, 11, 5, 247, 78, 11, 5, 247, 69, 11, 5, 247, 160, + 11, 5, 247, 111, 11, 5, 238, 183, 11, 5, 238, 185, 11, 5, 238, 184, 11, + 5, 238, 249, 11, 5, 238, 237, 11, 5, 242, 99, 11, 5, 239, 13, 11, 5, 247, + 5, 11, 5, 247, 42, 11, 5, 247, 11, 11, 5, 238, 154, 11, 5, 238, 152, 11, + 5, 238, 195, 11, 5, 238, 181, 11, 5, 238, 160, 11, 5, 238, 176, 11, 5, + 238, 130, 11, 5, 238, 129, 11, 5, 238, 143, 11, 5, 238, 137, 11, 5, 238, + 131, 11, 5, 238, 133, 11, 5, 190, 209, 11, 5, 190, 208, 11, 5, 190, 215, + 11, 5, 190, 210, 11, 5, 190, 212, 11, 5, 190, 211, 11, 5, 190, 214, 11, + 5, 190, 213, 11, 5, 190, 221, 11, 5, 190, 220, 11, 5, 190, 224, 11, 5, + 190, 222, 11, 5, 190, 205, 11, 5, 190, 207, 11, 5, 190, 206, 11, 5, 190, + 216, 11, 5, 190, 219, 11, 5, 190, 217, 11, 5, 190, 198, 11, 5, 190, 202, + 11, 5, 190, 201, 11, 5, 190, 199, 11, 5, 190, 200, 11, 5, 190, 192, 11, + 5, 190, 191, 11, 5, 190, 197, 11, 5, 190, 195, 11, 5, 190, 193, 11, 5, + 190, 194, 11, 5, 212, 33, 11, 5, 212, 32, 11, 5, 212, 38, 11, 5, 212, 34, + 11, 5, 212, 35, 11, 5, 212, 37, 11, 5, 212, 36, 11, 5, 212, 43, 11, 5, + 212, 42, 11, 5, 212, 46, 11, 5, 212, 45, 11, 5, 212, 26, 11, 5, 212, 27, + 11, 5, 212, 30, 11, 5, 212, 31, 11, 5, 212, 39, 11, 5, 212, 41, 11, 5, + 212, 21, 11, 5, 212, 29, 11, 5, 212, 25, 11, 5, 212, 22, 11, 5, 212, 23, + 11, 5, 212, 16, 11, 5, 212, 15, 11, 5, 212, 20, 11, 5, 212, 19, 11, 5, + 212, 17, 11, 5, 212, 18, 11, 5, 202, 138, 11, 5, 169, 11, 5, 202, 222, + 11, 5, 202, 142, 11, 5, 202, 202, 11, 5, 202, 205, 11, 5, 202, 203, 11, + 5, 205, 122, 11, 5, 205, 106, 11, 5, 188, 11, 5, 205, 130, 11, 5, 200, + 188, 11, 5, 200, 190, 11, 5, 200, 189, 11, 5, 202, 8, 11, 5, 201, 253, + 11, 5, 202, 46, 11, 5, 202, 14, 11, 5, 203, 238, 11, 5, 205, 68, 11, 5, + 204, 13, 11, 5, 200, 163, 11, 5, 200, 159, 11, 5, 201, 4, 11, 5, 200, + 187, 11, 5, 200, 167, 11, 5, 200, 175, 11, 5, 200, 57, 11, 5, 200, 56, + 11, 5, 200, 127, 11, 5, 200, 65, 11, 5, 200, 59, 11, 5, 200, 64, 11, 5, + 201, 136, 11, 5, 201, 135, 11, 5, 201, 142, 11, 5, 201, 137, 11, 5, 201, + 139, 11, 5, 201, 141, 11, 5, 201, 140, 11, 5, 201, 151, 11, 5, 201, 149, + 11, 5, 201, 175, 11, 5, 201, 152, 11, 5, 201, 131, 11, 5, 201, 130, 11, + 5, 201, 134, 11, 5, 201, 132, 11, 5, 201, 145, 11, 5, 201, 148, 11, 5, + 201, 146, 11, 5, 201, 127, 11, 5, 201, 125, 11, 5, 201, 129, 11, 5, 201, + 128, 11, 5, 201, 120, 11, 5, 201, 119, 11, 5, 201, 124, 11, 5, 201, 123, + 11, 5, 201, 121, 11, 5, 201, 122, 11, 5, 191, 66, 11, 5, 191, 65, 11, 5, + 191, 71, 11, 5, 191, 68, 11, 5, 191, 45, 11, 5, 191, 47, 11, 5, 191, 46, + 11, 5, 191, 50, 11, 5, 191, 49, 11, 5, 191, 54, 11, 5, 191, 51, 11, 5, + 191, 59, 11, 5, 191, 58, 11, 5, 191, 62, 11, 5, 191, 60, 11, 5, 191, 41, + 11, 5, 191, 40, 11, 5, 191, 48, 11, 5, 191, 44, 11, 5, 191, 42, 11, 5, + 191, 43, 11, 5, 191, 33, 11, 5, 191, 32, 11, 5, 191, 37, 11, 5, 191, 36, + 11, 5, 191, 34, 11, 5, 191, 35, 11, 5, 243, 133, 11, 5, 243, 129, 11, 5, + 247, 1, 11, 5, 246, 243, 11, 5, 243, 44, 11, 5, 243, 43, 11, 5, 243, 46, + 11, 5, 243, 45, 11, 5, 243, 59, 11, 5, 243, 58, 11, 5, 243, 68, 11, 5, + 243, 63, 11, 5, 243, 102, 11, 5, 243, 99, 11, 5, 243, 127, 11, 5, 243, + 110, 11, 5, 243, 38, 11, 5, 243, 48, 11, 5, 243, 42, 11, 5, 243, 39, 11, + 5, 243, 41, 11, 5, 243, 31, 11, 5, 243, 30, 11, 5, 243, 35, 11, 5, 243, + 34, 11, 5, 243, 32, 11, 5, 243, 33, 11, 5, 206, 105, 11, 5, 206, 109, 11, + 5, 206, 87, 11, 5, 206, 88, 11, 5, 206, 92, 11, 5, 206, 91, 11, 5, 206, + 95, 11, 5, 206, 93, 11, 5, 206, 99, 11, 5, 206, 98, 11, 5, 206, 104, 11, + 5, 206, 100, 11, 5, 206, 83, 11, 5, 206, 81, 11, 5, 206, 89, 11, 5, 206, + 86, 11, 5, 206, 84, 11, 5, 206, 85, 11, 5, 206, 76, 11, 5, 206, 75, 11, + 5, 206, 80, 11, 5, 206, 79, 11, 5, 206, 77, 11, 5, 206, 78, 11, 5, 212, + 242, 11, 5, 212, 241, 11, 5, 212, 244, 11, 5, 212, 243, 11, 5, 212, 233, + 11, 5, 212, 235, 11, 5, 212, 234, 11, 5, 212, 237, 11, 5, 212, 236, 11, + 5, 212, 240, 11, 5, 212, 239, 11, 5, 212, 227, 11, 5, 212, 226, 11, 5, + 212, 232, 11, 5, 212, 230, 11, 5, 212, 228, 11, 5, 212, 229, 11, 5, 212, + 221, 11, 5, 212, 220, 11, 5, 212, 225, 11, 5, 212, 224, 11, 5, 212, 222, + 11, 5, 212, 223, 11, 5, 203, 123, 11, 5, 203, 118, 11, 5, 203, 165, 11, + 5, 203, 136, 11, 5, 202, 249, 11, 5, 202, 251, 11, 5, 202, 250, 11, 5, + 203, 24, 11, 5, 203, 19, 11, 5, 203, 56, 11, 5, 203, 44, 11, 5, 203, 91, + 11, 5, 203, 84, 11, 5, 203, 113, 11, 5, 203, 100, 11, 5, 202, 245, 11, 5, + 202, 242, 11, 5, 203, 5, 11, 5, 202, 248, 11, 5, 202, 246, 11, 5, 202, + 247, 11, 5, 202, 225, 11, 5, 202, 224, 11, 5, 202, 231, 11, 5, 202, 228, + 11, 5, 202, 226, 11, 5, 202, 227, 11, 5, 207, 130, 11, 5, 207, 123, 11, + 5, 165, 11, 5, 207, 136, 11, 5, 206, 38, 11, 5, 206, 40, 11, 5, 206, 39, + 11, 5, 206, 123, 11, 5, 206, 111, 11, 5, 206, 162, 11, 5, 206, 127, 11, + 5, 207, 11, 11, 5, 207, 113, 11, 5, 207, 53, 11, 5, 206, 30, 11, 5, 206, + 27, 11, 5, 206, 68, 11, 5, 206, 37, 11, 5, 206, 33, 11, 5, 206, 34, 11, + 5, 206, 12, 11, 5, 206, 11, 11, 5, 206, 17, 11, 5, 206, 15, 11, 5, 206, + 13, 11, 5, 206, 14, 11, 5, 222, 232, 11, 5, 222, 231, 11, 5, 222, 244, + 11, 5, 222, 233, 11, 5, 222, 240, 11, 5, 222, 239, 11, 5, 222, 242, 11, + 5, 222, 241, 11, 5, 222, 170, 11, 5, 222, 169, 11, 5, 222, 172, 11, 5, + 222, 171, 11, 5, 222, 188, 11, 5, 222, 186, 11, 5, 222, 201, 11, 5, 222, + 190, 11, 5, 222, 163, 11, 5, 222, 161, 11, 5, 222, 182, 11, 5, 222, 168, + 11, 5, 222, 165, 11, 5, 222, 166, 11, 5, 222, 155, 11, 5, 222, 154, 11, + 5, 222, 159, 11, 5, 222, 158, 11, 5, 222, 156, 11, 5, 222, 157, 11, 5, + 208, 49, 11, 5, 208, 47, 11, 5, 208, 57, 11, 5, 208, 50, 11, 5, 208, 54, + 11, 5, 208, 53, 11, 5, 208, 56, 11, 5, 208, 55, 11, 5, 207, 253, 11, 5, + 207, 250, 11, 5, 207, 255, 11, 5, 207, 254, 11, 5, 208, 36, 11, 5, 208, + 35, 11, 5, 208, 45, 11, 5, 208, 39, 11, 5, 207, 245, 11, 5, 207, 241, 11, + 5, 208, 33, 11, 5, 207, 249, 11, 5, 207, 247, 11, 5, 207, 248, 11, 5, + 207, 225, 11, 5, 207, 223, 11, 5, 207, 235, 11, 5, 207, 228, 11, 5, 207, + 226, 11, 5, 207, 227, 11, 5, 222, 221, 11, 5, 222, 220, 11, 5, 222, 227, + 11, 5, 222, 222, 11, 5, 222, 224, 11, 5, 222, 223, 11, 5, 222, 226, 11, + 5, 222, 225, 11, 5, 222, 212, 11, 5, 222, 214, 11, 5, 222, 213, 11, 5, + 222, 217, 11, 5, 222, 216, 11, 5, 222, 219, 11, 5, 222, 218, 11, 5, 222, + 208, 11, 5, 222, 207, 11, 5, 222, 215, 11, 5, 222, 211, 11, 5, 222, 209, + 11, 5, 222, 210, 11, 5, 222, 204, 11, 5, 222, 203, 11, 5, 222, 206, 11, + 5, 222, 205, 11, 5, 213, 134, 11, 5, 213, 133, 11, 5, 213, 141, 11, 5, + 213, 135, 11, 5, 213, 137, 11, 5, 213, 136, 11, 5, 213, 140, 11, 5, 213, + 138, 11, 5, 213, 123, 11, 5, 213, 124, 11, 5, 213, 129, 11, 5, 213, 128, + 11, 5, 213, 132, 11, 5, 213, 130, 11, 5, 213, 118, 11, 5, 213, 127, 11, + 5, 213, 122, 11, 5, 213, 119, 11, 5, 213, 120, 11, 5, 213, 113, 11, 5, + 213, 112, 11, 5, 213, 117, 11, 5, 213, 116, 11, 5, 213, 114, 11, 5, 213, + 115, 11, 5, 212, 68, 11, 5, 212, 67, 11, 5, 212, 81, 11, 5, 212, 72, 11, + 5, 212, 77, 11, 5, 212, 76, 11, 5, 212, 79, 11, 5, 212, 78, 11, 5, 212, + 53, 11, 5, 212, 55, 11, 5, 212, 54, 11, 5, 212, 60, 11, 5, 212, 59, 11, + 5, 212, 65, 11, 5, 212, 61, 11, 5, 212, 51, 11, 5, 212, 49, 11, 5, 212, + 58, 11, 5, 212, 52, 11, 5, 192, 198, 11, 5, 192, 197, 11, 5, 192, 207, + 11, 5, 192, 200, 11, 5, 192, 202, 11, 5, 192, 201, 11, 5, 192, 204, 11, + 5, 192, 203, 11, 5, 192, 186, 11, 5, 192, 187, 11, 5, 192, 191, 11, 5, + 192, 190, 11, 5, 192, 196, 11, 5, 192, 194, 11, 5, 192, 163, 11, 5, 192, + 161, 11, 5, 192, 176, 11, 5, 192, 166, 11, 5, 192, 164, 11, 5, 192, 165, + 11, 5, 192, 18, 11, 5, 192, 16, 11, 5, 192, 33, 11, 5, 192, 19, 11, 5, + 192, 27, 11, 5, 192, 26, 11, 5, 192, 30, 11, 5, 192, 28, 11, 5, 191, 198, + 11, 5, 191, 197, 11, 5, 191, 201, 11, 5, 191, 199, 11, 5, 191, 240, 11, + 5, 191, 235, 11, 5, 192, 12, 11, 5, 191, 245, 11, 5, 191, 189, 11, 5, + 191, 185, 11, 5, 191, 225, 11, 5, 191, 196, 11, 5, 191, 192, 11, 5, 191, + 193, 11, 5, 191, 169, 11, 5, 191, 168, 11, 5, 191, 176, 11, 5, 191, 172, + 11, 5, 191, 170, 11, 5, 191, 171, 11, 48, 208, 36, 11, 48, 219, 146, 11, + 48, 221, 120, 11, 48, 212, 72, 11, 48, 238, 137, 11, 48, 201, 142, 11, + 48, 231, 110, 11, 48, 231, 142, 11, 48, 216, 100, 11, 48, 228, 104, 11, + 48, 218, 175, 11, 48, 249, 25, 11, 48, 215, 202, 11, 48, 192, 12, 11, 48, + 208, 131, 11, 48, 228, 98, 11, 48, 199, 171, 11, 48, 231, 240, 11, 48, + 190, 243, 11, 48, 238, 130, 11, 48, 237, 151, 11, 48, 247, 230, 11, 48, + 231, 106, 11, 48, 212, 61, 11, 48, 197, 94, 11, 48, 211, 78, 11, 48, 222, + 208, 11, 48, 191, 2, 11, 48, 208, 108, 11, 48, 229, 65, 11, 48, 192, 18, + 11, 48, 193, 244, 11, 48, 202, 231, 11, 48, 195, 141, 11, 48, 191, 123, + 11, 48, 222, 201, 11, 48, 212, 25, 11, 48, 222, 206, 11, 48, 230, 232, + 11, 48, 222, 226, 11, 48, 193, 48, 11, 48, 235, 89, 11, 48, 202, 247, 11, + 48, 219, 140, 11, 48, 238, 143, 11, 48, 238, 184, 11, 48, 243, 12, 11, + 48, 228, 101, 11, 48, 203, 123, 11, 48, 190, 242, 11, 48, 203, 44, 11, + 48, 243, 127, 11, 48, 190, 212, 11, 48, 214, 189, 11, 48, 222, 22, 219, + 88, 1, 249, 153, 219, 88, 1, 168, 219, 88, 1, 209, 228, 219, 88, 1, 238, + 32, 219, 88, 1, 190, 190, 219, 88, 1, 199, 49, 219, 88, 1, 231, 240, 219, + 88, 1, 155, 219, 88, 1, 221, 215, 219, 88, 1, 223, 32, 219, 88, 1, 247, + 160, 219, 88, 1, 247, 1, 219, 88, 1, 235, 35, 219, 88, 1, 197, 168, 219, + 88, 1, 197, 157, 219, 88, 1, 174, 219, 88, 1, 180, 219, 88, 1, 173, 219, + 88, 1, 188, 219, 88, 1, 191, 71, 219, 88, 1, 191, 123, 219, 88, 1, 214, + 68, 219, 88, 1, 140, 219, 88, 1, 192, 220, 219, 88, 1, 229, 177, 219, 88, + 1, 233, 109, 219, 88, 1, 193, 190, 219, 88, 1, 203, 165, 219, 88, 1, 170, + 219, 88, 1, 231, 91, 219, 88, 1, 65, 219, 88, 1, 252, 25, 219, 88, 1, 71, + 219, 88, 1, 233, 242, 219, 88, 1, 68, 219, 88, 1, 74, 219, 88, 1, 66, + 219, 88, 1, 196, 152, 219, 88, 1, 196, 141, 219, 88, 1, 211, 151, 219, + 88, 1, 163, 215, 69, 198, 193, 219, 88, 1, 163, 215, 7, 209, 73, 219, 88, + 1, 163, 215, 69, 238, 142, 219, 88, 1, 163, 215, 69, 248, 111, 219, 88, + 1, 163, 215, 69, 180, 219, 88, 1, 163, 215, 69, 222, 253, 219, 88, 208, + 152, 242, 74, 219, 88, 208, 152, 232, 80, 201, 63, 59, 5, 234, 188, 59, + 5, 234, 184, 59, 5, 229, 215, 59, 5, 193, 114, 59, 5, 193, 113, 59, 5, + 210, 49, 59, 5, 248, 195, 59, 5, 249, 1, 59, 5, 217, 3, 59, 5, 221, 16, + 59, 5, 216, 132, 59, 5, 231, 178, 59, 5, 233, 52, 59, 5, 195, 148, 59, 5, + 199, 121, 59, 5, 199, 31, 59, 5, 237, 58, 59, 5, 237, 55, 59, 5, 219, + 228, 59, 5, 207, 84, 59, 5, 237, 131, 59, 5, 214, 153, 59, 5, 205, 50, + 59, 5, 203, 111, 59, 5, 191, 84, 59, 5, 191, 61, 59, 5, 247, 34, 59, 5, + 223, 8, 59, 5, 213, 148, 59, 5, 192, 77, 59, 5, 222, 13, 59, 5, 214, 41, + 59, 5, 231, 157, 59, 5, 216, 211, 59, 5, 214, 110, 59, 5, 212, 89, 59, 5, + 68, 59, 5, 223, 162, 59, 5, 229, 158, 59, 5, 229, 128, 59, 5, 193, 86, + 59, 5, 193, 68, 59, 5, 209, 185, 59, 5, 248, 193, 59, 5, 248, 188, 59, 5, + 216, 252, 59, 5, 221, 13, 59, 5, 216, 129, 59, 5, 231, 174, 59, 5, 233, + 23, 59, 5, 195, 69, 59, 5, 198, 193, 59, 5, 199, 11, 59, 5, 237, 50, 59, + 5, 237, 54, 59, 5, 219, 146, 59, 5, 207, 1, 59, 5, 237, 44, 59, 5, 214, + 147, 59, 5, 202, 222, 59, 5, 203, 81, 59, 5, 191, 30, 59, 5, 191, 57, 59, + 5, 243, 29, 59, 5, 222, 244, 59, 5, 213, 141, 59, 5, 192, 33, 59, 5, 221, + 166, 59, 5, 214, 33, 59, 5, 231, 53, 59, 5, 216, 100, 59, 5, 213, 219, + 59, 5, 212, 81, 59, 5, 65, 59, 5, 251, 132, 59, 5, 214, 63, 59, 5, 140, + 59, 5, 230, 56, 59, 5, 193, 190, 59, 5, 193, 164, 59, 5, 168, 59, 5, 248, + 203, 59, 5, 249, 153, 59, 5, 217, 11, 59, 5, 221, 21, 59, 5, 221, 19, 59, + 5, 216, 136, 59, 5, 231, 182, 59, 5, 233, 109, 59, 5, 195, 188, 59, 5, + 190, 190, 59, 5, 199, 49, 59, 5, 237, 68, 59, 5, 237, 57, 59, 5, 173, 59, + 5, 165, 59, 5, 238, 32, 59, 5, 214, 162, 59, 5, 188, 59, 5, 203, 165, 59, + 5, 191, 123, 59, 5, 191, 71, 59, 5, 247, 160, 59, 5, 223, 32, 59, 5, 213, + 157, 59, 5, 170, 59, 5, 155, 59, 5, 222, 87, 59, 5, 214, 47, 59, 5, 231, + 240, 59, 5, 174, 59, 5, 180, 59, 5, 212, 101, 59, 5, 211, 87, 59, 5, 211, + 82, 59, 5, 228, 252, 59, 5, 193, 29, 59, 5, 193, 25, 59, 5, 209, 37, 59, + 5, 248, 191, 59, 5, 248, 97, 59, 5, 216, 247, 59, 5, 221, 11, 59, 5, 216, + 125, 59, 5, 231, 170, 59, 5, 232, 162, 59, 5, 195, 8, 59, 5, 198, 59, 59, + 5, 198, 235, 59, 5, 237, 47, 59, 5, 237, 52, 59, 5, 219, 8, 59, 5, 206, + 134, 59, 5, 236, 146, 59, 5, 214, 134, 59, 5, 202, 16, 59, 5, 203, 48, + 59, 5, 191, 4, 59, 5, 191, 52, 59, 5, 239, 18, 59, 5, 222, 191, 59, 5, + 213, 131, 59, 5, 191, 246, 59, 5, 221, 41, 59, 5, 214, 31, 59, 5, 230, + 245, 59, 5, 215, 211, 59, 5, 213, 26, 59, 5, 212, 62, 59, 5, 66, 59, 5, + 196, 113, 59, 5, 228, 159, 59, 5, 228, 142, 59, 5, 193, 0, 59, 5, 192, + 249, 59, 5, 208, 165, 59, 5, 248, 190, 59, 5, 248, 10, 59, 5, 216, 246, + 59, 5, 221, 9, 59, 5, 216, 124, 59, 5, 231, 169, 59, 5, 232, 86, 59, 5, + 193, 249, 59, 5, 197, 94, 59, 5, 198, 213, 59, 5, 237, 45, 59, 5, 237, + 51, 59, 5, 218, 225, 59, 5, 206, 68, 59, 5, 235, 89, 59, 5, 214, 129, 59, + 5, 201, 4, 59, 5, 203, 5, 59, 5, 190, 251, 59, 5, 191, 48, 59, 5, 238, + 195, 59, 5, 222, 182, 59, 5, 213, 127, 59, 5, 191, 225, 59, 5, 220, 232, + 59, 5, 214, 30, 59, 5, 230, 179, 59, 5, 215, 155, 59, 5, 212, 178, 59, 5, + 212, 58, 59, 5, 74, 59, 5, 211, 104, 59, 5, 213, 245, 59, 5, 229, 23, 59, + 5, 228, 255, 59, 5, 193, 48, 59, 5, 193, 30, 59, 5, 209, 73, 59, 5, 248, + 192, 59, 5, 248, 111, 59, 5, 216, 248, 59, 5, 221, 12, 59, 5, 216, 127, + 59, 5, 231, 172, 59, 5, 231, 171, 59, 5, 232, 175, 59, 5, 195, 24, 59, 5, + 159, 59, 5, 198, 241, 59, 5, 237, 48, 59, 5, 237, 53, 59, 5, 219, 43, 59, + 5, 206, 162, 59, 5, 236, 174, 59, 5, 214, 138, 59, 5, 202, 46, 59, 5, + 203, 56, 59, 5, 191, 7, 59, 5, 191, 54, 59, 5, 242, 99, 59, 5, 222, 201, + 59, 5, 213, 132, 59, 5, 192, 12, 59, 5, 221, 67, 59, 5, 214, 32, 59, 5, + 231, 3, 59, 5, 216, 12, 59, 5, 213, 43, 59, 5, 212, 65, 59, 5, 71, 59, 5, + 234, 103, 59, 5, 214, 52, 59, 5, 229, 245, 59, 5, 229, 198, 59, 5, 193, + 125, 59, 5, 193, 108, 59, 5, 210, 63, 59, 5, 248, 196, 59, 5, 249, 17, + 59, 5, 217, 4, 59, 5, 221, 17, 59, 5, 221, 15, 59, 5, 216, 133, 59, 5, + 231, 179, 59, 5, 231, 177, 59, 5, 233, 59, 59, 5, 195, 153, 59, 5, 199, + 145, 59, 5, 199, 33, 59, 5, 237, 59, 59, 5, 237, 56, 59, 5, 219, 238, 59, + 5, 207, 113, 59, 5, 237, 146, 59, 5, 214, 154, 59, 5, 205, 68, 59, 5, + 203, 113, 59, 5, 191, 87, 59, 5, 191, 62, 59, 5, 247, 42, 59, 5, 223, 10, + 59, 5, 213, 150, 59, 5, 192, 80, 59, 5, 222, 22, 59, 5, 214, 42, 59, 5, + 214, 38, 59, 5, 231, 165, 59, 5, 231, 151, 59, 5, 216, 232, 59, 5, 214, + 121, 59, 5, 212, 90, 59, 5, 214, 70, 59, 5, 219, 190, 59, 242, 74, 59, + 232, 80, 201, 63, 59, 208, 13, 77, 59, 5, 214, 137, 233, 109, 59, 5, 214, + 137, 155, 59, 5, 214, 137, 202, 16, 59, 16, 233, 48, 59, 16, 222, 11, 59, + 16, 198, 140, 59, 16, 213, 186, 59, 16, 249, 95, 59, 16, 233, 108, 59, + 16, 199, 245, 59, 16, 237, 236, 59, 16, 236, 145, 59, 16, 220, 208, 59, + 16, 198, 63, 59, 16, 236, 173, 59, 16, 222, 192, 59, 17, 191, 77, 59, 17, + 107, 59, 17, 109, 59, 17, 138, 59, 17, 134, 59, 17, 149, 59, 17, 169, 59, + 17, 175, 59, 17, 171, 59, 17, 178, 59, 5, 214, 137, 174, 59, 5, 214, 137, + 236, 174, 38, 6, 1, 191, 81, 38, 2, 1, 191, 81, 38, 6, 1, 235, 30, 38, 2, + 1, 235, 30, 38, 6, 1, 207, 18, 235, 32, 38, 2, 1, 207, 18, 235, 32, 38, + 6, 1, 223, 83, 38, 2, 1, 223, 83, 38, 6, 1, 236, 191, 38, 2, 1, 236, 191, + 38, 6, 1, 215, 219, 196, 128, 38, 2, 1, 215, 219, 196, 128, 38, 6, 1, + 248, 24, 211, 110, 38, 2, 1, 248, 24, 211, 110, 38, 6, 1, 214, 82, 192, + 62, 38, 2, 1, 214, 82, 192, 62, 38, 6, 1, 192, 59, 4, 249, 147, 192, 62, + 38, 2, 1, 192, 59, 4, 249, 147, 192, 62, 38, 6, 1, 223, 81, 192, 95, 38, + 2, 1, 223, 81, 192, 95, 38, 6, 1, 207, 18, 191, 225, 38, 2, 1, 207, 18, + 191, 225, 38, 6, 1, 223, 81, 65, 38, 2, 1, 223, 81, 65, 38, 6, 1, 242, + 219, 219, 83, 191, 190, 38, 2, 1, 242, 219, 219, 83, 191, 190, 38, 6, 1, + 248, 131, 191, 190, 38, 2, 1, 248, 131, 191, 190, 38, 6, 1, 223, 81, 242, + 219, 219, 83, 191, 190, 38, 2, 1, 223, 81, 242, 219, 219, 83, 191, 190, + 38, 6, 1, 192, 14, 38, 2, 1, 192, 14, 38, 6, 1, 207, 18, 197, 161, 38, 2, + 1, 207, 18, 197, 161, 38, 6, 1, 202, 32, 237, 146, 38, 2, 1, 202, 32, + 237, 146, 38, 6, 1, 202, 32, 234, 140, 38, 2, 1, 202, 32, 234, 140, 38, + 6, 1, 202, 32, 234, 114, 38, 2, 1, 202, 32, 234, 114, 38, 6, 1, 215, 223, + 74, 38, 2, 1, 215, 223, 74, 38, 6, 1, 248, 164, 74, 38, 2, 1, 248, 164, + 74, 38, 6, 1, 55, 215, 223, 74, 38, 2, 1, 55, 215, 223, 74, 38, 1, 215, + 130, 74, 33, 38, 193, 226, 33, 38, 199, 96, 216, 48, 56, 33, 38, 228, + 141, 216, 48, 56, 33, 38, 198, 230, 216, 48, 56, 202, 95, 250, 193, 33, + 38, 1, 196, 125, 223, 226, 33, 38, 1, 68, 33, 38, 1, 192, 33, 33, 38, 1, + 66, 33, 38, 1, 230, 17, 56, 33, 38, 1, 192, 58, 33, 38, 1, 202, 32, 56, + 33, 38, 1, 211, 110, 33, 38, 222, 35, 33, 38, 210, 70, 38, 222, 35, 38, + 210, 70, 38, 6, 1, 235, 45, 38, 2, 1, 235, 45, 38, 6, 1, 235, 21, 38, 2, + 1, 235, 21, 38, 6, 1, 191, 38, 38, 2, 1, 191, 38, 38, 6, 1, 247, 58, 38, + 2, 1, 247, 58, 38, 6, 1, 235, 17, 38, 2, 1, 235, 17, 38, 6, 1, 199, 146, + 4, 82, 102, 38, 2, 1, 199, 146, 4, 82, 102, 38, 6, 1, 197, 41, 38, 2, 1, + 197, 41, 38, 6, 1, 197, 136, 38, 2, 1, 197, 136, 38, 6, 1, 197, 141, 38, + 2, 1, 197, 141, 38, 6, 1, 199, 151, 38, 2, 1, 199, 151, 38, 6, 1, 228, + 122, 38, 2, 1, 228, 122, 38, 6, 1, 202, 237, 38, 2, 1, 202, 237, 38, 6, + 1, 55, 74, 38, 2, 1, 55, 74, 38, 6, 1, 238, 214, 74, 38, 2, 1, 238, 214, + 74, 52, 1, 38, 230, 17, 56, 52, 1, 38, 202, 32, 56, 33, 38, 1, 234, 181, + 33, 38, 1, 223, 81, 71, 26, 1, 65, 26, 1, 155, 26, 1, 66, 26, 1, 220, + 232, 26, 1, 234, 188, 26, 1, 207, 84, 26, 1, 199, 226, 26, 1, 74, 26, 1, + 212, 81, 26, 1, 68, 26, 1, 173, 26, 1, 168, 26, 1, 206, 195, 26, 1, 206, + 242, 26, 1, 219, 227, 26, 1, 216, 210, 26, 1, 199, 245, 26, 1, 214, 160, + 26, 1, 213, 155, 26, 1, 218, 168, 26, 1, 200, 160, 26, 1, 215, 155, 26, + 1, 203, 76, 26, 1, 202, 222, 26, 1, 203, 86, 26, 1, 203, 248, 26, 1, 220, + 149, 26, 1, 221, 241, 26, 1, 212, 146, 26, 1, 212, 178, 26, 1, 213, 126, + 26, 1, 191, 243, 26, 1, 203, 5, 26, 1, 191, 194, 26, 1, 170, 26, 1, 212, + 215, 26, 1, 221, 227, 26, 1, 209, 232, 26, 1, 213, 148, 26, 1, 212, 195, + 26, 1, 208, 156, 26, 1, 192, 253, 26, 1, 210, 49, 26, 1, 233, 52, 26, 1, + 206, 68, 26, 1, 218, 225, 26, 1, 216, 100, 26, 1, 213, 219, 26, 1, 207, + 20, 26, 1, 207, 163, 26, 1, 221, 251, 26, 1, 213, 252, 26, 1, 214, 47, + 26, 1, 214, 68, 26, 1, 203, 56, 26, 1, 208, 161, 26, 1, 232, 86, 26, 1, + 232, 167, 26, 1, 193, 190, 26, 1, 180, 26, 1, 219, 146, 26, 1, 209, 185, + 26, 1, 219, 0, 26, 1, 221, 67, 26, 1, 217, 1, 26, 1, 207, 55, 26, 1, 216, + 186, 26, 1, 174, 26, 1, 198, 193, 26, 1, 221, 166, 26, 1, 216, 12, 26, 1, + 217, 9, 26, 1, 199, 73, 26, 1, 221, 21, 26, 1, 199, 95, 26, 1, 212, 181, + 26, 1, 205, 150, 26, 1, 233, 105, 26, 1, 221, 24, 26, 1, 221, 57, 26, 33, + 87, 221, 34, 26, 33, 87, 197, 79, 26, 213, 154, 26, 232, 80, 201, 63, 26, + 242, 83, 26, 242, 74, 26, 204, 25, 26, 208, 13, 77, 52, 1, 243, 80, 163, + 192, 22, 209, 132, 52, 1, 243, 80, 163, 192, 107, 209, 132, 52, 1, 243, + 80, 163, 192, 22, 203, 137, 52, 1, 243, 80, 163, 192, 107, 203, 137, 52, + 1, 243, 80, 163, 192, 22, 208, 33, 52, 1, 243, 80, 163, 192, 107, 208, + 33, 52, 1, 243, 80, 163, 192, 22, 206, 68, 52, 1, 243, 80, 163, 192, 107, + 206, 68, 52, 1, 233, 200, 235, 138, 163, 164, 52, 1, 137, 235, 138, 163, + 164, 52, 1, 216, 87, 235, 138, 163, 164, 52, 1, 130, 235, 138, 163, 164, + 52, 1, 233, 199, 235, 138, 163, 164, 52, 1, 233, 200, 235, 138, 219, 216, + 163, 164, 52, 1, 137, 235, 138, 219, 216, 163, 164, 52, 1, 216, 87, 235, + 138, 219, 216, 163, 164, 52, 1, 130, 235, 138, 219, 216, 163, 164, 52, 1, + 233, 199, 235, 138, 219, 216, 163, 164, 52, 1, 233, 200, 219, 216, 163, + 164, 52, 1, 137, 219, 216, 163, 164, 52, 1, 216, 87, 219, 216, 163, 164, + 52, 1, 130, 219, 216, 163, 164, 52, 1, 233, 199, 219, 216, 163, 164, 52, + 1, 75, 81, 164, 52, 1, 75, 202, 97, 52, 1, 75, 228, 241, 164, 52, 1, 110, + 50, 239, 2, 251, 115, 52, 1, 207, 147, 133, 57, 52, 1, 207, 147, 144, 57, + 52, 1, 207, 147, 233, 216, 77, 52, 1, 207, 147, 223, 93, 233, 216, 77, + 52, 1, 130, 223, 93, 233, 216, 77, 52, 1, 201, 38, 23, 137, 198, 79, 52, + 1, 201, 38, 23, 130, 198, 79, 8, 6, 1, 234, 175, 251, 192, 8, 2, 1, 234, + 175, 251, 192, 8, 6, 1, 234, 175, 251, 230, 8, 2, 1, 234, 175, 251, 230, + 8, 6, 1, 229, 196, 8, 2, 1, 229, 196, 8, 6, 1, 196, 241, 8, 2, 1, 196, + 241, 8, 6, 1, 197, 248, 8, 2, 1, 197, 248, 8, 6, 1, 238, 192, 8, 2, 1, + 238, 192, 8, 6, 1, 238, 193, 4, 242, 74, 8, 2, 1, 238, 193, 4, 242, 74, + 8, 1, 2, 6, 233, 175, 8, 1, 2, 6, 206, 8, 8, 6, 1, 252, 206, 8, 2, 1, + 252, 206, 8, 6, 1, 251, 68, 8, 2, 1, 251, 68, 8, 6, 1, 250, 163, 8, 2, 1, + 250, 163, 8, 6, 1, 250, 146, 8, 2, 1, 250, 146, 8, 6, 1, 250, 147, 4, + 228, 241, 164, 8, 2, 1, 250, 147, 4, 228, 241, 164, 8, 6, 1, 250, 131, 8, + 2, 1, 250, 131, 8, 6, 1, 207, 18, 247, 194, 4, 236, 140, 8, 2, 1, 207, + 18, 247, 194, 4, 236, 140, 8, 6, 1, 222, 153, 4, 106, 8, 2, 1, 222, 153, + 4, 106, 8, 6, 1, 222, 153, 4, 237, 39, 106, 8, 2, 1, 222, 153, 4, 237, + 39, 106, 8, 6, 1, 222, 153, 4, 201, 28, 23, 237, 39, 106, 8, 2, 1, 222, + 153, 4, 201, 28, 23, 237, 39, 106, 8, 6, 1, 248, 22, 172, 8, 2, 1, 248, + 22, 172, 8, 6, 1, 220, 143, 4, 137, 106, 8, 2, 1, 220, 143, 4, 137, 106, + 8, 6, 1, 187, 4, 179, 201, 28, 210, 255, 8, 2, 1, 187, 4, 179, 201, 28, + 210, 255, 8, 6, 1, 187, 4, 219, 4, 8, 2, 1, 187, 4, 219, 4, 8, 6, 1, 211, + 87, 8, 2, 1, 211, 87, 8, 6, 1, 210, 237, 4, 201, 28, 198, 216, 237, 87, + 8, 2, 1, 210, 237, 4, 201, 28, 198, 216, 237, 87, 8, 6, 1, 210, 237, 4, + 232, 188, 8, 2, 1, 210, 237, 4, 232, 188, 8, 6, 1, 210, 237, 4, 201, 182, + 199, 215, 8, 2, 1, 210, 237, 4, 201, 182, 199, 215, 8, 6, 1, 208, 105, 4, + 201, 28, 198, 216, 237, 87, 8, 2, 1, 208, 105, 4, 201, 28, 198, 216, 237, + 87, 8, 6, 1, 208, 105, 4, 237, 39, 106, 8, 2, 1, 208, 105, 4, 237, 39, + 106, 8, 6, 1, 207, 222, 206, 116, 8, 2, 1, 207, 222, 206, 116, 8, 6, 1, + 206, 49, 206, 116, 8, 2, 1, 206, 49, 206, 116, 8, 6, 1, 196, 13, 4, 237, + 39, 106, 8, 2, 1, 196, 13, 4, 237, 39, 106, 8, 6, 1, 193, 235, 8, 2, 1, + 193, 235, 8, 6, 1, 195, 33, 191, 166, 8, 2, 1, 195, 33, 191, 166, 8, 6, + 1, 198, 234, 4, 106, 8, 2, 1, 198, 234, 4, 106, 8, 6, 1, 198, 234, 4, + 201, 28, 198, 216, 237, 87, 8, 2, 1, 198, 234, 4, 201, 28, 198, 216, 237, + 87, 8, 6, 1, 195, 142, 8, 2, 1, 195, 142, 8, 6, 1, 233, 255, 8, 2, 1, + 233, 255, 8, 6, 1, 223, 68, 8, 2, 1, 223, 68, 8, 6, 1, 239, 57, 8, 2, 1, + 239, 57, 52, 1, 196, 45, 8, 2, 1, 235, 77, 8, 2, 1, 218, 208, 8, 2, 1, + 215, 123, 8, 2, 1, 212, 137, 8, 2, 1, 206, 48, 8, 1, 2, 6, 206, 48, 8, 2, + 1, 197, 76, 8, 2, 1, 196, 120, 8, 6, 1, 223, 115, 238, 127, 8, 2, 1, 223, + 115, 238, 127, 8, 6, 1, 223, 115, 233, 175, 8, 2, 1, 223, 115, 233, 175, + 8, 6, 1, 223, 115, 232, 51, 8, 6, 1, 153, 223, 115, 232, 51, 8, 2, 1, + 153, 223, 115, 232, 51, 8, 6, 1, 153, 172, 8, 2, 1, 153, 172, 8, 6, 1, + 223, 115, 146, 8, 2, 1, 223, 115, 146, 8, 6, 1, 223, 115, 206, 8, 8, 2, + 1, 223, 115, 206, 8, 8, 6, 1, 223, 115, 200, 43, 8, 2, 1, 223, 115, 200, + 43, 52, 1, 130, 243, 2, 252, 60, 52, 1, 242, 83, 52, 1, 203, 40, 234, 43, + 56, 8, 6, 1, 205, 156, 8, 2, 1, 205, 156, 8, 6, 1, 153, 230, 116, 8, 2, + 1, 220, 143, 4, 207, 24, 228, 251, 23, 248, 231, 8, 1, 202, 163, 236, + 140, 8, 6, 1, 215, 62, 4, 237, 87, 8, 2, 1, 215, 62, 4, 237, 87, 8, 6, 1, + 247, 194, 4, 164, 8, 2, 1, 247, 194, 4, 164, 8, 2, 1, 247, 194, 4, 210, + 192, 102, 8, 2, 1, 230, 117, 4, 210, 192, 102, 8, 6, 1, 78, 4, 232, 188, + 8, 2, 1, 78, 4, 232, 188, 8, 6, 1, 233, 176, 4, 106, 8, 2, 1, 233, 176, + 4, 106, 8, 6, 1, 195, 15, 252, 25, 8, 2, 1, 195, 15, 252, 25, 8, 6, 1, + 195, 15, 211, 151, 8, 2, 1, 195, 15, 211, 151, 8, 6, 1, 195, 15, 196, + 152, 8, 2, 1, 195, 15, 196, 152, 8, 6, 1, 232, 52, 4, 211, 172, 106, 8, + 2, 1, 232, 52, 4, 211, 172, 106, 8, 6, 1, 222, 153, 4, 211, 172, 106, 8, + 2, 1, 222, 153, 4, 211, 172, 106, 8, 6, 1, 215, 62, 4, 211, 172, 106, 8, + 2, 1, 215, 62, 4, 211, 172, 106, 8, 6, 1, 207, 222, 4, 211, 172, 106, 8, + 2, 1, 207, 222, 4, 211, 172, 106, 8, 6, 1, 206, 9, 4, 211, 172, 106, 8, + 2, 1, 206, 9, 4, 211, 172, 106, 8, 6, 1, 230, 117, 4, 102, 8, 6, 1, 207, + 18, 211, 77, 71, 8, 6, 1, 27, 232, 51, 8, 6, 1, 220, 143, 4, 248, 231, 8, + 6, 1, 2, 6, 68, 8, 1, 2, 6, 208, 104, 8, 6, 1, 153, 222, 152, 8, 6, 1, + 153, 200, 43, 8, 6, 1, 223, 36, 4, 238, 212, 8, 6, 1, 243, 95, 8, 6, 1, + 248, 212, 8, 2, 1, 248, 212, 8, 6, 1, 211, 110, 8, 2, 1, 211, 110, 8, 6, + 1, 126, 4, 106, 8, 2, 1, 126, 4, 106, 8, 6, 1, 231, 11, 65, 8, 2, 1, 231, + 11, 65, 8, 6, 1, 231, 11, 68, 8, 2, 1, 231, 11, 68, 8, 6, 1, 231, 11, 66, + 8, 2, 1, 231, 11, 66, 8, 6, 1, 39, 209, 49, 74, 8, 2, 1, 39, 209, 49, 74, + 8, 6, 1, 251, 112, 193, 224, 8, 2, 1, 251, 112, 193, 224, 8, 6, 1, 247, + 194, 4, 210, 192, 102, 8, 6, 1, 206, 9, 4, 102, 8, 6, 1, 191, 167, 4, + 210, 192, 102, 8, 6, 1, 238, 128, 4, 203, 40, 201, 28, 210, 255, 8, 2, 1, + 238, 128, 4, 203, 40, 201, 28, 210, 255, 8, 6, 1, 206, 9, 4, 203, 40, + 201, 28, 210, 255, 8, 2, 1, 206, 9, 4, 203, 40, 201, 28, 210, 255, 8, 6, + 1, 242, 219, 223, 115, 232, 51, 8, 2, 1, 242, 219, 223, 115, 232, 51, 8, + 2, 1, 55, 198, 233, 8, 2, 1, 55, 192, 238, 8, 6, 1, 82, 205, 79, 206, 8, + 8, 2, 1, 82, 205, 79, 206, 8, 8, 6, 1, 202, 195, 206, 8, 8, 2, 1, 202, + 195, 206, 8, 52, 1, 6, 247, 193, 52, 1, 6, 233, 175, 52, 1, 6, 208, 104, + 8, 6, 1, 207, 18, 132, 230, 116, 8, 2, 1, 207, 18, 132, 230, 116, 8, 234, + 50, 1, 202, 206, 68, 52, 1, 6, 230, 117, 4, 106, 52, 1, 2, 34, 211, 151, + 8, 1, 2, 6, 153, 218, 168, 8, 234, 50, 1, 207, 18, 233, 175, 8, 234, 50, + 1, 207, 18, 210, 236, 8, 234, 50, 1, 223, 93, 218, 168, 8, 234, 50, 1, + 228, 74, 219, 10, 8, 234, 50, 1, 251, 14, 218, 168, 200, 124, 214, 238, + 1, 65, 200, 124, 214, 238, 1, 68, 200, 124, 214, 238, 3, 235, 54, 200, + 124, 214, 238, 1, 66, 200, 124, 214, 238, 1, 71, 200, 124, 214, 238, 1, + 74, 200, 124, 214, 238, 3, 230, 11, 200, 124, 214, 238, 1, 221, 67, 200, + 124, 214, 238, 1, 221, 183, 200, 124, 214, 238, 1, 231, 3, 200, 124, 214, + 238, 1, 231, 63, 200, 124, 214, 238, 3, 251, 71, 200, 124, 214, 238, 1, + 242, 99, 200, 124, 214, 238, 1, 243, 68, 200, 124, 214, 238, 1, 222, 201, + 200, 124, 214, 238, 1, 222, 246, 200, 124, 214, 238, 1, 197, 109, 200, + 124, 214, 238, 1, 197, 115, 200, 124, 214, 238, 1, 237, 161, 200, 124, + 214, 238, 1, 237, 170, 200, 124, 214, 238, 1, 159, 200, 124, 214, 238, 1, + 198, 241, 200, 124, 214, 238, 1, 236, 174, 200, 124, 214, 238, 1, 237, + 48, 200, 124, 214, 238, 1, 213, 43, 200, 124, 214, 238, 1, 209, 73, 200, + 124, 214, 238, 1, 209, 199, 200, 124, 214, 238, 1, 248, 111, 200, 124, + 214, 238, 1, 248, 192, 200, 124, 214, 238, 1, 216, 12, 200, 124, 214, + 238, 1, 206, 162, 200, 124, 214, 238, 1, 219, 43, 200, 124, 214, 238, 1, + 206, 95, 200, 124, 214, 238, 1, 202, 46, 200, 124, 214, 238, 1, 229, 23, + 200, 124, 214, 238, 18, 3, 65, 200, 124, 214, 238, 18, 3, 68, 200, 124, + 214, 238, 18, 3, 66, 200, 124, 214, 238, 18, 3, 71, 200, 124, 214, 238, + 18, 3, 211, 87, 200, 124, 214, 238, 209, 63, 217, 55, 200, 124, 214, 238, + 209, 63, 217, 54, 200, 124, 214, 238, 209, 63, 217, 53, 200, 124, 214, + 238, 209, 63, 217, 52, 200, 124, 214, 238, 3, 251, 157, 230, 11, 186, + 223, 146, 232, 118, 91, 208, 22, 186, 223, 146, 232, 118, 91, 230, 70, + 186, 223, 146, 232, 118, 115, 208, 20, 186, 223, 146, 232, 118, 91, 202, + 128, 186, 223, 146, 232, 118, 91, 234, 159, 186, 223, 146, 232, 118, 115, + 202, 125, 186, 223, 146, 208, 23, 77, 186, 223, 146, 209, 107, 77, 186, + 223, 146, 206, 36, 77, 186, 223, 146, 208, 25, 77, 209, 224, 1, 155, 209, + 224, 1, 221, 215, 209, 224, 1, 231, 240, 209, 224, 1, 214, 68, 209, 224, + 1, 247, 160, 209, 224, 1, 247, 1, 209, 224, 1, 223, 32, 209, 224, 1, 212, + 101, 209, 224, 1, 190, 190, 209, 224, 1, 199, 49, 209, 224, 1, 238, 32, + 209, 224, 1, 180, 209, 224, 1, 168, 209, 224, 1, 209, 228, 209, 224, 1, + 249, 153, 209, 224, 1, 174, 209, 224, 1, 197, 168, 209, 224, 1, 197, 157, + 209, 224, 1, 235, 35, 209, 224, 1, 193, 190, 209, 224, 1, 191, 71, 209, + 224, 1, 191, 123, 209, 224, 1, 2, 65, 209, 224, 1, 170, 209, 224, 1, 165, + 209, 224, 1, 173, 209, 224, 1, 203, 165, 209, 224, 1, 188, 209, 224, 1, + 140, 209, 224, 1, 65, 209, 224, 1, 68, 209, 224, 1, 66, 209, 224, 1, 71, + 209, 224, 1, 74, 209, 224, 1, 208, 96, 209, 224, 1, 192, 220, 209, 224, + 1, 233, 109, 209, 224, 1, 231, 127, 209, 224, 1, 234, 188, 209, 224, 200, + 239, 1, 193, 190, 209, 224, 200, 239, 1, 170, 209, 224, 1, 197, 132, 209, + 224, 1, 197, 120, 209, 224, 1, 237, 191, 209, 224, 1, 213, 79, 209, 224, + 1, 251, 157, 170, 209, 224, 1, 195, 19, 203, 165, 209, 224, 1, 195, 20, + 140, 209, 224, 1, 250, 200, 233, 109, 209, 224, 200, 239, 1, 165, 209, + 224, 200, 185, 1, 165, 209, 224, 1, 247, 119, 209, 224, 202, 170, 229, + 236, 77, 209, 224, 55, 229, 236, 77, 209, 224, 87, 203, 157, 209, 224, + 87, 55, 203, 157, 205, 111, 3, 251, 71, 205, 111, 3, 195, 35, 205, 111, + 1, 65, 205, 111, 1, 252, 206, 205, 111, 1, 68, 205, 111, 1, 223, 199, + 205, 111, 1, 66, 205, 111, 1, 196, 30, 205, 111, 1, 117, 146, 205, 111, + 1, 117, 206, 110, 205, 111, 1, 117, 172, 205, 111, 1, 117, 219, 74, 205, + 111, 1, 71, 205, 111, 1, 234, 188, 205, 111, 1, 251, 236, 205, 111, 1, + 74, 205, 111, 1, 211, 87, 205, 111, 1, 250, 163, 205, 111, 1, 155, 205, + 111, 1, 221, 215, 205, 111, 1, 231, 240, 205, 111, 1, 231, 91, 205, 111, + 1, 214, 68, 205, 111, 1, 247, 160, 205, 111, 1, 247, 1, 205, 111, 1, 223, + 32, 205, 111, 1, 222, 252, 205, 111, 1, 212, 101, 205, 111, 1, 197, 132, + 205, 111, 1, 197, 120, 205, 111, 1, 237, 191, 205, 111, 1, 237, 175, 205, + 111, 1, 213, 79, 205, 111, 1, 190, 190, 205, 111, 1, 199, 49, 205, 111, + 1, 238, 32, 205, 111, 1, 237, 68, 205, 111, 1, 180, 205, 111, 1, 168, + 205, 111, 1, 209, 228, 205, 111, 1, 249, 153, 205, 111, 1, 248, 203, 205, + 111, 1, 174, 205, 111, 1, 170, 205, 111, 1, 165, 205, 111, 1, 173, 205, + 111, 1, 195, 188, 205, 111, 1, 203, 165, 205, 111, 1, 201, 175, 205, 111, + 1, 188, 205, 111, 1, 140, 205, 111, 1, 219, 73, 205, 111, 120, 3, 230, + 89, 205, 111, 18, 3, 252, 206, 205, 111, 18, 3, 68, 205, 111, 18, 3, 223, + 199, 205, 111, 18, 3, 66, 205, 111, 18, 3, 196, 30, 205, 111, 18, 3, 117, + 146, 205, 111, 18, 3, 117, 206, 110, 205, 111, 18, 3, 117, 172, 205, 111, + 18, 3, 117, 219, 74, 205, 111, 18, 3, 71, 205, 111, 18, 3, 234, 188, 205, + 111, 18, 3, 251, 236, 205, 111, 18, 3, 74, 205, 111, 18, 3, 211, 87, 205, + 111, 18, 3, 250, 163, 205, 111, 3, 195, 40, 205, 111, 3, 247, 119, 205, + 111, 237, 238, 205, 111, 55, 237, 238, 205, 111, 17, 191, 77, 205, 111, + 17, 107, 205, 111, 17, 109, 205, 111, 17, 138, 205, 111, 17, 134, 205, + 111, 17, 149, 205, 111, 17, 169, 205, 111, 17, 175, 205, 111, 17, 171, + 205, 111, 17, 178, 33, 100, 17, 191, 77, 33, 100, 17, 107, 33, 100, 17, + 109, 33, 100, 17, 138, 33, 100, 17, 134, 33, 100, 17, 149, 33, 100, 17, + 169, 33, 100, 17, 175, 33, 100, 17, 171, 33, 100, 17, 178, 33, 100, 1, + 65, 33, 100, 1, 66, 33, 100, 1, 155, 33, 100, 1, 180, 33, 100, 1, 168, + 33, 100, 1, 165, 33, 100, 1, 195, 69, 33, 100, 3, 250, 145, 100, 3, 201, + 246, 247, 119, 100, 3, 247, 120, 195, 40, 100, 3, 55, 247, 120, 195, 40, + 100, 3, 247, 120, 109, 100, 3, 247, 120, 138, 100, 3, 247, 120, 250, 145, + 100, 3, 208, 134, 100, 231, 204, 233, 3, 100, 247, 96, 100, 229, 227, + 100, 3, 202, 210, 100, 223, 24, 211, 113, 100, 1, 250, 131, 100, 18, 3, + 250, 131, 222, 28, 219, 147, 17, 191, 77, 222, 28, 219, 147, 17, 107, + 222, 28, 219, 147, 17, 109, 222, 28, 219, 147, 17, 138, 222, 28, 219, + 147, 17, 134, 222, 28, 219, 147, 17, 149, 222, 28, 219, 147, 17, 169, + 222, 28, 219, 147, 17, 175, 222, 28, 219, 147, 17, 171, 222, 28, 219, + 147, 17, 178, 222, 28, 219, 147, 1, 155, 222, 28, 219, 147, 1, 221, 215, + 222, 28, 219, 147, 1, 231, 240, 222, 28, 219, 147, 1, 214, 68, 222, 28, + 219, 147, 1, 188, 222, 28, 219, 147, 1, 203, 165, 222, 28, 219, 147, 1, + 191, 123, 222, 28, 219, 147, 1, 212, 101, 222, 28, 219, 147, 1, 190, 190, + 222, 28, 219, 147, 1, 228, 164, 222, 28, 219, 147, 1, 180, 222, 28, 219, + 147, 1, 168, 222, 28, 219, 147, 1, 209, 228, 222, 28, 219, 147, 1, 174, + 222, 28, 219, 147, 1, 238, 32, 222, 28, 219, 147, 1, 249, 153, 222, 28, + 219, 147, 1, 165, 222, 28, 219, 147, 1, 170, 222, 28, 219, 147, 1, 173, + 222, 28, 219, 147, 1, 193, 190, 222, 28, 219, 147, 1, 199, 49, 222, 28, + 219, 147, 1, 140, 222, 28, 219, 147, 1, 195, 188, 222, 28, 219, 147, 1, + 247, 160, 222, 28, 219, 147, 1, 65, 222, 28, 219, 147, 1, 211, 151, 222, + 28, 219, 147, 1, 68, 222, 28, 219, 147, 1, 211, 87, 222, 28, 219, 147, + 18, 196, 152, 222, 28, 219, 147, 18, 71, 222, 28, 219, 147, 18, 66, 222, + 28, 219, 147, 18, 234, 188, 222, 28, 219, 147, 18, 74, 222, 28, 219, 147, + 163, 209, 90, 222, 28, 219, 147, 163, 247, 135, 222, 28, 219, 147, 163, + 247, 136, 209, 90, 222, 28, 219, 147, 3, 238, 147, 222, 28, 219, 147, 3, + 202, 230, 207, 67, 1, 155, 207, 67, 1, 231, 240, 207, 67, 1, 214, 68, + 207, 67, 1, 190, 190, 207, 67, 1, 238, 32, 207, 67, 1, 180, 207, 67, 1, + 168, 207, 67, 1, 249, 153, 207, 67, 1, 174, 207, 67, 1, 247, 160, 207, + 67, 1, 223, 32, 207, 67, 1, 212, 101, 207, 67, 1, 188, 207, 67, 1, 165, + 207, 67, 1, 173, 207, 67, 1, 170, 207, 67, 1, 193, 190, 207, 67, 1, 140, + 207, 67, 1, 217, 11, 207, 67, 1, 214, 47, 207, 67, 1, 214, 162, 207, 67, + 1, 212, 66, 207, 67, 1, 65, 207, 67, 18, 3, 68, 207, 67, 18, 3, 66, 207, + 67, 18, 3, 71, 207, 67, 18, 3, 251, 236, 207, 67, 18, 3, 74, 207, 67, 18, + 3, 250, 163, 207, 67, 18, 3, 233, 242, 207, 67, 18, 3, 234, 217, 207, 67, + 120, 3, 214, 70, 207, 67, 120, 3, 215, 61, 207, 67, 120, 3, 146, 207, 67, + 120, 3, 230, 116, 207, 67, 195, 40, 207, 67, 205, 54, 77, 30, 147, 198, + 164, 30, 147, 198, 163, 30, 147, 198, 161, 30, 147, 198, 166, 30, 147, + 206, 234, 30, 147, 206, 218, 30, 147, 206, 213, 30, 147, 206, 215, 30, + 147, 206, 231, 30, 147, 206, 224, 30, 147, 206, 217, 30, 147, 206, 236, + 30, 147, 206, 219, 30, 147, 206, 238, 30, 147, 206, 235, 30, 147, 216, + 73, 30, 147, 216, 64, 30, 147, 216, 67, 30, 147, 209, 154, 30, 147, 209, + 165, 30, 147, 209, 166, 30, 147, 201, 159, 30, 147, 223, 212, 30, 147, + 223, 219, 30, 147, 201, 170, 30, 147, 201, 157, 30, 147, 209, 208, 30, + 147, 229, 137, 30, 147, 201, 154, 223, 16, 3, 210, 143, 223, 16, 3, 247, + 39, 223, 16, 3, 219, 246, 223, 16, 3, 193, 71, 223, 16, 1, 65, 223, 16, + 1, 228, 74, 222, 32, 223, 16, 1, 68, 223, 16, 1, 223, 199, 223, 16, 1, + 66, 223, 16, 1, 210, 221, 247, 9, 223, 16, 1, 214, 69, 219, 203, 223, 16, + 1, 214, 69, 219, 204, 207, 131, 223, 16, 1, 71, 223, 16, 1, 251, 236, + 223, 16, 1, 74, 223, 16, 1, 155, 223, 16, 1, 222, 142, 205, 124, 223, 16, + 1, 222, 142, 215, 107, 223, 16, 1, 231, 240, 223, 16, 1, 231, 241, 215, + 107, 223, 16, 1, 214, 68, 223, 16, 1, 247, 160, 223, 16, 1, 247, 161, + 215, 107, 223, 16, 1, 223, 32, 223, 16, 1, 212, 102, 215, 107, 223, 16, + 1, 223, 33, 217, 116, 223, 16, 1, 212, 101, 223, 16, 1, 197, 132, 223, + 16, 1, 197, 133, 217, 116, 223, 16, 1, 237, 191, 223, 16, 1, 237, 192, + 217, 116, 223, 16, 1, 215, 7, 215, 107, 223, 16, 1, 190, 190, 223, 16, 1, + 199, 252, 215, 107, 223, 16, 1, 238, 32, 223, 16, 1, 238, 33, 217, 116, + 223, 16, 1, 180, 223, 16, 1, 168, 223, 16, 1, 210, 221, 215, 107, 223, + 16, 1, 249, 153, 223, 16, 1, 249, 154, 215, 107, 223, 16, 1, 174, 223, + 16, 1, 170, 223, 16, 1, 165, 223, 16, 1, 207, 186, 251, 246, 223, 16, 1, + 173, 223, 16, 1, 193, 190, 223, 16, 1, 205, 207, 215, 107, 223, 16, 1, + 205, 207, 217, 116, 223, 16, 1, 188, 223, 16, 1, 140, 223, 16, 3, 247, + 40, 199, 100, 223, 16, 18, 3, 199, 175, 223, 16, 18, 3, 198, 84, 223, 16, + 18, 3, 192, 250, 223, 16, 18, 3, 192, 251, 216, 198, 223, 16, 18, 3, 200, + 208, 223, 16, 18, 3, 200, 209, 216, 185, 223, 16, 18, 3, 199, 201, 223, + 16, 18, 3, 236, 230, 215, 106, 223, 16, 18, 3, 210, 16, 223, 16, 120, 3, + 221, 244, 223, 16, 120, 3, 210, 31, 223, 16, 120, 3, 247, 145, 223, 16, + 210, 157, 223, 16, 45, 207, 40, 223, 16, 50, 207, 40, 223, 16, 210, 209, + 251, 124, 223, 16, 210, 209, 217, 137, 223, 16, 210, 209, 218, 212, 223, + 16, 210, 209, 193, 64, 223, 16, 210, 209, 210, 158, 223, 16, 210, 209, + 219, 104, 223, 16, 210, 209, 218, 204, 223, 16, 210, 209, 252, 36, 223, + 16, 210, 209, 252, 37, 252, 36, 223, 16, 210, 209, 209, 119, 223, 16, + 153, 210, 209, 209, 119, 223, 16, 210, 153, 223, 16, 17, 191, 77, 223, + 16, 17, 107, 223, 16, 17, 109, 223, 16, 17, 138, 223, 16, 17, 134, 223, + 16, 17, 149, 223, 16, 17, 169, 223, 16, 17, 175, 223, 16, 17, 171, 223, + 16, 17, 178, 223, 16, 210, 209, 198, 127, 197, 73, 223, 16, 210, 209, + 223, 64, 80, 1, 203, 139, 231, 91, 80, 1, 203, 139, 247, 1, 80, 1, 203, + 139, 222, 252, 80, 1, 203, 139, 213, 79, 80, 1, 203, 139, 248, 203, 80, + 3, 203, 139, 205, 108, 80, 52, 1, 203, 139, 207, 85, 80, 1, 54, 220, 95, + 212, 101, 80, 1, 54, 220, 95, 233, 109, 80, 1, 54, 220, 95, 231, 240, 80, + 1, 54, 220, 95, 231, 91, 80, 1, 54, 220, 95, 223, 32, 80, 1, 54, 220, 95, + 222, 252, 80, 1, 54, 220, 95, 237, 191, 80, 1, 54, 220, 95, 237, 175, 80, + 1, 54, 220, 95, 213, 79, 80, 54, 220, 95, 17, 191, 77, 80, 54, 220, 95, + 17, 107, 80, 54, 220, 95, 17, 109, 80, 54, 220, 95, 17, 138, 80, 54, 220, + 95, 17, 134, 80, 54, 220, 95, 17, 149, 80, 54, 220, 95, 17, 169, 80, 54, + 220, 95, 17, 175, 80, 54, 220, 95, 17, 171, 80, 54, 220, 95, 17, 178, 80, + 1, 54, 220, 95, 219, 73, 80, 1, 54, 220, 95, 238, 32, 80, 1, 54, 220, 95, + 237, 68, 80, 1, 54, 220, 95, 249, 153, 80, 1, 54, 220, 95, 248, 203, 246, + 250, 1, 65, 246, 250, 1, 68, 246, 250, 1, 66, 246, 250, 1, 71, 246, 250, + 1, 251, 236, 246, 250, 1, 74, 246, 250, 1, 155, 246, 250, 1, 221, 215, + 246, 250, 1, 231, 240, 246, 250, 1, 231, 91, 246, 250, 1, 213, 233, 246, + 250, 1, 214, 68, 246, 250, 1, 247, 1, 246, 250, 1, 243, 98, 246, 250, 1, + 223, 32, 246, 250, 1, 222, 252, 246, 250, 1, 213, 221, 246, 250, 1, 213, + 224, 246, 250, 1, 213, 222, 246, 250, 1, 190, 190, 246, 250, 1, 199, 49, + 246, 250, 1, 238, 32, 246, 250, 1, 237, 68, 246, 250, 1, 212, 144, 246, + 250, 1, 180, 246, 250, 1, 237, 191, 246, 250, 1, 168, 246, 250, 1, 208, + 250, 246, 250, 1, 209, 228, 246, 250, 1, 249, 153, 246, 250, 1, 248, 203, + 246, 250, 1, 215, 143, 246, 250, 1, 174, 246, 250, 1, 249, 53, 246, 250, + 1, 170, 246, 250, 1, 165, 246, 250, 1, 173, 246, 250, 1, 195, 188, 246, + 250, 1, 201, 175, 246, 250, 1, 188, 246, 250, 1, 140, 246, 250, 18, 3, + 252, 206, 246, 250, 18, 3, 68, 246, 250, 18, 3, 223, 199, 246, 250, 18, + 3, 234, 166, 246, 250, 18, 3, 66, 246, 250, 18, 3, 211, 151, 246, 250, + 18, 3, 74, 246, 250, 18, 3, 251, 236, 246, 250, 18, 3, 250, 163, 246, + 250, 18, 3, 196, 152, 246, 250, 120, 3, 170, 246, 250, 120, 3, 165, 246, + 250, 120, 3, 173, 246, 250, 120, 3, 193, 190, 246, 250, 1, 53, 222, 152, + 246, 250, 1, 53, 232, 51, 246, 250, 1, 53, 214, 70, 246, 250, 120, 3, 53, + 214, 70, 246, 250, 1, 53, 247, 3, 246, 250, 1, 53, 200, 43, 246, 250, 1, + 53, 215, 61, 246, 250, 1, 53, 210, 236, 246, 250, 1, 53, 192, 159, 246, + 250, 1, 53, 146, 246, 250, 1, 53, 172, 246, 250, 1, 53, 201, 178, 246, + 250, 120, 3, 53, 218, 168, 246, 250, 120, 3, 53, 230, 116, 246, 250, 17, + 191, 77, 246, 250, 17, 107, 246, 250, 17, 109, 246, 250, 17, 138, 246, + 250, 17, 134, 246, 250, 17, 149, 246, 250, 17, 169, 246, 250, 17, 175, + 246, 250, 17, 171, 246, 250, 17, 178, 246, 250, 208, 152, 201, 217, 246, + 250, 208, 152, 237, 238, 246, 250, 208, 152, 55, 237, 238, 246, 250, 208, + 152, 197, 225, 237, 238, 80, 1, 221, 206, 231, 240, 80, 1, 221, 206, 247, + 160, 80, 1, 221, 206, 247, 1, 80, 1, 221, 206, 223, 32, 80, 1, 221, 206, + 222, 252, 80, 1, 221, 206, 212, 101, 80, 1, 221, 206, 197, 132, 80, 1, + 221, 206, 197, 120, 80, 1, 221, 206, 237, 191, 80, 1, 221, 206, 237, 175, + 80, 1, 221, 206, 237, 68, 80, 1, 221, 206, 180, 80, 1, 221, 206, 188, 80, + 1, 221, 206, 140, 80, 1, 221, 206, 229, 177, 80, 1, 221, 206, 233, 109, + 80, 52, 1, 221, 206, 207, 85, 80, 1, 221, 206, 192, 220, 80, 1, 221, 206, + 191, 123, 80, 1, 221, 206, 165, 80, 219, 28, 221, 206, 211, 179, 80, 219, + 28, 221, 206, 208, 46, 80, 219, 28, 221, 206, 229, 78, 80, 16, 251, 222, + 233, 215, 80, 16, 251, 222, 107, 80, 16, 251, 222, 109, 80, 1, 251, 222, + 165, 80, 3, 210, 139, 222, 62, 198, 79, 80, 3, 54, 220, 95, 198, 77, 80, + 3, 54, 220, 95, 198, 74, 80, 1, 202, 238, 210, 189, 247, 1, 80, 1, 202, + 238, 210, 189, 203, 165, 54, 195, 59, 1, 130, 221, 67, 54, 195, 59, 1, + 137, 221, 67, 54, 195, 59, 1, 130, 221, 183, 54, 195, 59, 1, 137, 221, + 183, 54, 195, 59, 1, 130, 221, 192, 54, 195, 59, 1, 137, 221, 192, 54, + 195, 59, 1, 130, 231, 3, 54, 195, 59, 1, 137, 231, 3, 54, 195, 59, 1, + 130, 213, 249, 54, 195, 59, 1, 137, 213, 249, 54, 195, 59, 1, 130, 242, + 99, 54, 195, 59, 1, 137, 242, 99, 54, 195, 59, 1, 130, 243, 68, 54, 195, + 59, 1, 137, 243, 68, 54, 195, 59, 1, 130, 202, 46, 54, 195, 59, 1, 137, + 202, 46, 54, 195, 59, 1, 130, 212, 65, 54, 195, 59, 1, 137, 212, 65, 54, + 195, 59, 1, 130, 236, 174, 54, 195, 59, 1, 137, 236, 174, 54, 195, 59, 1, + 130, 159, 54, 195, 59, 1, 137, 159, 54, 195, 59, 1, 130, 198, 241, 54, + 195, 59, 1, 137, 198, 241, 54, 195, 59, 1, 130, 213, 43, 54, 195, 59, 1, + 137, 213, 43, 54, 195, 59, 1, 130, 248, 111, 54, 195, 59, 1, 137, 248, + 111, 54, 195, 59, 1, 130, 209, 73, 54, 195, 59, 1, 137, 209, 73, 54, 195, + 59, 1, 130, 209, 199, 54, 195, 59, 1, 137, 209, 199, 54, 195, 59, 1, 130, + 232, 175, 54, 195, 59, 1, 137, 232, 175, 54, 195, 59, 1, 130, 216, 12, + 54, 195, 59, 1, 137, 216, 12, 54, 195, 59, 1, 130, 192, 12, 54, 195, 59, + 1, 137, 192, 12, 54, 195, 59, 1, 130, 206, 162, 54, 195, 59, 1, 137, 206, + 162, 54, 195, 59, 1, 130, 219, 43, 54, 195, 59, 1, 137, 219, 43, 54, 195, + 59, 1, 130, 195, 24, 54, 195, 59, 1, 137, 195, 24, 54, 195, 59, 1, 130, + 229, 23, 54, 195, 59, 1, 137, 229, 23, 54, 195, 59, 1, 130, 74, 54, 195, + 59, 1, 137, 74, 54, 195, 59, 217, 113, 222, 83, 54, 195, 59, 18, 252, + 206, 54, 195, 59, 18, 68, 54, 195, 59, 18, 196, 152, 54, 195, 59, 18, 66, + 54, 195, 59, 18, 71, 54, 195, 59, 18, 74, 54, 195, 59, 217, 113, 221, + 186, 54, 195, 59, 18, 228, 35, 54, 195, 59, 18, 196, 151, 54, 195, 59, + 18, 196, 168, 54, 195, 59, 18, 250, 161, 54, 195, 59, 18, 250, 131, 54, + 195, 59, 18, 251, 132, 54, 195, 59, 18, 251, 149, 54, 195, 59, 163, 217, + 113, 234, 147, 54, 195, 59, 163, 217, 113, 212, 143, 54, 195, 59, 163, + 217, 113, 198, 241, 54, 195, 59, 163, 217, 113, 202, 18, 54, 195, 59, 16, + 221, 44, 54, 195, 59, 16, 212, 143, 54, 195, 59, 16, 205, 152, 54, 195, + 59, 16, 229, 24, 229, 10, 54, 195, 59, 16, 221, 55, 221, 54, 216, 205, + 217, 18, 1, 71, 216, 205, 217, 18, 1, 74, 216, 205, 217, 18, 1, 247, 1, + 216, 205, 217, 18, 1, 212, 101, 216, 205, 217, 18, 1, 197, 132, 216, 205, + 217, 18, 1, 197, 120, 216, 205, 217, 18, 1, 237, 191, 216, 205, 217, 18, + 1, 237, 175, 216, 205, 217, 18, 1, 213, 79, 216, 205, 217, 18, 1, 203, + 165, 216, 205, 217, 18, 1, 201, 175, 216, 205, 217, 18, 18, 3, 223, 199, + 216, 205, 217, 18, 18, 3, 196, 30, 216, 205, 217, 18, 18, 3, 252, 170, + 216, 205, 217, 18, 18, 3, 250, 163, 216, 205, 217, 18, 18, 3, 252, 162, + 216, 205, 217, 18, 243, 116, 216, 205, 217, 18, 251, 242, 221, 173, 216, + 205, 217, 18, 251, 100, 216, 205, 217, 18, 5, 207, 46, 77, 216, 205, 217, + 18, 193, 23, 207, 46, 77, 216, 205, 217, 18, 18, 3, 195, 35, 216, 205, + 217, 18, 195, 40, 36, 5, 197, 113, 36, 5, 197, 116, 36, 5, 197, 119, 36, + 5, 197, 117, 36, 5, 197, 118, 36, 5, 197, 115, 36, 5, 237, 169, 36, 5, + 237, 171, 36, 5, 237, 174, 36, 5, 237, 172, 36, 5, 237, 173, 36, 5, 237, + 170, 36, 5, 235, 22, 36, 5, 235, 26, 36, 5, 235, 34, 36, 5, 235, 31, 36, + 5, 235, 32, 36, 5, 235, 23, 36, 5, 247, 56, 36, 5, 247, 50, 36, 5, 247, + 52, 36, 5, 247, 55, 36, 5, 247, 53, 36, 5, 247, 54, 36, 5, 247, 51, 36, + 5, 249, 53, 36, 5, 249, 32, 36, 5, 249, 44, 36, 5, 249, 52, 36, 5, 249, + 47, 36, 5, 249, 48, 36, 5, 249, 36, 8, 2, 1, 249, 82, 251, 160, 8, 2, 1, + 42, 207, 16, 8, 2, 1, 248, 135, 71, 8, 2, 1, 249, 82, 71, 8, 2, 1, 235, + 15, 4, 232, 188, 8, 2, 1, 219, 189, 233, 175, 8, 2, 1, 27, 232, 52, 4, + 238, 212, 8, 2, 1, 220, 143, 4, 223, 93, 219, 245, 206, 8, 8, 2, 1, 220, + 143, 4, 55, 82, 198, 152, 8, 2, 1, 220, 143, 4, 82, 206, 188, 8, 2, 1, + 218, 169, 4, 238, 212, 8, 2, 1, 215, 62, 4, 238, 212, 8, 2, 1, 234, 89, + 4, 238, 212, 8, 2, 1, 248, 135, 74, 8, 2, 1, 248, 135, 187, 4, 106, 8, 2, + 1, 211, 77, 187, 4, 106, 8, 2, 1, 223, 93, 211, 151, 8, 2, 1, 153, 211, + 152, 4, 106, 8, 2, 1, 153, 211, 152, 4, 228, 241, 106, 8, 2, 1, 153, 187, + 211, 72, 8, 2, 1, 153, 187, 211, 73, 4, 106, 8, 2, 1, 201, 68, 146, 8, 1, + 2, 6, 207, 222, 4, 50, 219, 212, 8, 2, 1, 207, 222, 193, 51, 230, 31, 8, + 2, 1, 55, 146, 8, 2, 1, 207, 222, 4, 238, 212, 8, 2, 1, 55, 207, 222, 4, + 238, 212, 8, 2, 1, 27, 146, 8, 2, 1, 27, 207, 222, 4, 206, 188, 8, 2, 1, + 249, 72, 234, 12, 8, 2, 1, 126, 4, 203, 40, 50, 219, 212, 8, 2, 1, 126, + 249, 88, 4, 203, 40, 50, 219, 212, 8, 2, 1, 196, 139, 8, 2, 1, 153, 196, + 139, 8, 2, 1, 126, 4, 45, 102, 8, 2, 1, 243, 95, 8, 2, 1, 243, 96, 4, + 130, 50, 206, 188, 8, 2, 1, 243, 96, 4, 130, 45, 204, 5, 8, 2, 1, 192, + 236, 4, 130, 50, 206, 188, 8, 2, 1, 192, 236, 4, 179, 45, 219, 212, 8, 2, + 1, 192, 236, 4, 179, 45, 219, 213, 23, 130, 50, 206, 188, 8, 2, 1, 192, + 236, 4, 179, 45, 219, 213, 4, 204, 5, 8, 2, 1, 192, 160, 4, 203, 40, 50, + 219, 212, 52, 248, 37, 4, 223, 93, 248, 36, 52, 1, 2, 229, 196, 52, 1, 2, + 220, 143, 4, 223, 93, 219, 245, 206, 8, 52, 1, 2, 220, 143, 4, 82, 198, + 152, 52, 1, 2, 126, 4, 45, 102, 8, 2, 1, 205, 174, 192, 95, 8, 2, 1, 223, + 81, 71, 8, 2, 1, 211, 77, 211, 151, 8, 2, 1, 196, 82, 8, 2, 1, 223, 93, + 251, 160, 35, 1, 2, 6, 211, 110, 8, 2, 1, 235, 37, 237, 3, 4, 207, 24, + 102, 8, 2, 1, 197, 170, 237, 3, 4, 207, 24, 102, 8, 2, 1, 153, 207, 222, + 4, 82, 198, 152, 52, 1, 2, 153, 193, 224, 52, 1, 45, 199, 228, 52, 1, 50, + 199, 228, 103, 2, 1, 65, 103, 2, 1, 71, 103, 2, 1, 68, 103, 2, 1, 74, + 103, 2, 1, 66, 103, 2, 1, 196, 12, 103, 2, 1, 231, 240, 103, 2, 1, 155, + 103, 2, 1, 231, 165, 103, 2, 1, 231, 53, 103, 2, 1, 231, 3, 103, 2, 1, + 230, 179, 103, 2, 1, 230, 138, 103, 2, 1, 140, 103, 2, 1, 229, 245, 103, + 2, 1, 229, 158, 103, 2, 1, 229, 23, 103, 2, 1, 228, 159, 103, 2, 1, 228, + 126, 103, 2, 1, 173, 103, 2, 1, 219, 238, 103, 2, 1, 219, 146, 103, 2, 1, + 219, 43, 103, 2, 1, 218, 225, 103, 2, 1, 218, 192, 103, 2, 1, 174, 103, + 2, 1, 216, 232, 103, 2, 1, 216, 100, 103, 2, 1, 216, 12, 103, 2, 1, 215, + 155, 103, 2, 1, 180, 103, 2, 1, 229, 47, 103, 2, 1, 214, 237, 103, 2, 1, + 214, 121, 103, 2, 1, 213, 219, 103, 2, 1, 213, 43, 103, 2, 1, 212, 178, + 103, 2, 1, 212, 112, 103, 2, 1, 208, 32, 103, 2, 1, 208, 16, 103, 2, 1, + 208, 9, 103, 2, 1, 207, 255, 103, 2, 1, 207, 244, 103, 2, 1, 207, 242, + 103, 2, 1, 188, 103, 2, 1, 206, 8, 103, 2, 1, 205, 68, 103, 2, 1, 202, + 222, 103, 2, 1, 202, 46, 103, 2, 1, 201, 4, 103, 2, 1, 200, 158, 103, 2, + 1, 238, 32, 103, 2, 1, 190, 190, 103, 2, 1, 237, 146, 103, 2, 1, 199, + 145, 103, 2, 1, 237, 44, 103, 2, 1, 198, 193, 103, 2, 1, 236, 174, 103, + 2, 1, 235, 89, 103, 2, 1, 235, 57, 103, 2, 1, 236, 186, 103, 2, 1, 198, + 115, 103, 2, 1, 198, 114, 103, 2, 1, 198, 103, 103, 2, 1, 198, 102, 103, + 2, 1, 198, 101, 103, 2, 1, 198, 100, 103, 2, 1, 197, 168, 103, 2, 1, 197, + 161, 103, 2, 1, 197, 146, 103, 2, 1, 197, 144, 103, 2, 1, 197, 140, 103, + 2, 1, 197, 139, 103, 2, 1, 193, 190, 103, 2, 1, 193, 125, 103, 2, 1, 193, + 86, 103, 2, 1, 193, 48, 103, 2, 1, 193, 0, 103, 2, 1, 192, 243, 103, 2, + 1, 170, 216, 205, 217, 18, 1, 221, 51, 216, 205, 217, 18, 1, 205, 152, + 216, 205, 217, 18, 1, 220, 96, 216, 205, 217, 18, 1, 216, 23, 216, 205, + 217, 18, 1, 168, 216, 205, 217, 18, 1, 180, 216, 205, 217, 18, 1, 243, + 87, 216, 205, 217, 18, 1, 198, 154, 216, 205, 217, 18, 1, 221, 176, 216, + 205, 217, 18, 1, 213, 239, 216, 205, 217, 18, 1, 198, 232, 216, 205, 217, + 18, 1, 193, 173, 216, 205, 217, 18, 1, 192, 106, 216, 205, 217, 18, 1, + 228, 147, 216, 205, 217, 18, 1, 196, 113, 216, 205, 217, 18, 1, 68, 216, + 205, 217, 18, 1, 209, 222, 216, 205, 217, 18, 1, 250, 175, 216, 205, 217, + 18, 1, 230, 251, 216, 205, 217, 18, 1, 222, 250, 216, 205, 217, 18, 1, + 207, 156, 216, 205, 217, 18, 1, 249, 153, 216, 205, 217, 18, 1, 222, 234, + 216, 205, 217, 18, 1, 237, 1, 216, 205, 217, 18, 1, 231, 60, 216, 205, + 217, 18, 1, 237, 46, 216, 205, 217, 18, 1, 248, 198, 216, 205, 217, 18, + 1, 221, 52, 219, 9, 216, 205, 217, 18, 1, 220, 97, 219, 9, 216, 205, 217, + 18, 1, 216, 24, 219, 9, 216, 205, 217, 18, 1, 210, 221, 219, 9, 216, 205, + 217, 18, 1, 215, 7, 219, 9, 216, 205, 217, 18, 1, 198, 155, 219, 9, 216, + 205, 217, 18, 1, 213, 240, 219, 9, 216, 205, 217, 18, 1, 228, 74, 219, 9, + 216, 205, 217, 18, 18, 3, 211, 102, 216, 205, 217, 18, 18, 3, 223, 160, + 216, 205, 217, 18, 18, 3, 251, 130, 216, 205, 217, 18, 18, 3, 192, 69, + 216, 205, 217, 18, 18, 3, 202, 6, 216, 205, 217, 18, 18, 3, 196, 110, + 216, 205, 217, 18, 18, 3, 243, 114, 216, 205, 217, 18, 18, 3, 212, 127, + 216, 205, 217, 18, 243, 115, 216, 205, 217, 18, 218, 209, 223, 42, 216, + 205, 217, 18, 251, 38, 223, 42, 216, 205, 217, 18, 17, 191, 77, 216, 205, + 217, 18, 17, 107, 216, 205, 217, 18, 17, 109, 216, 205, 217, 18, 17, 138, + 216, 205, 217, 18, 17, 134, 216, 205, 217, 18, 17, 149, 216, 205, 217, + 18, 17, 169, 216, 205, 217, 18, 17, 175, 216, 205, 217, 18, 17, 171, 216, + 205, 217, 18, 17, 178, 30, 222, 174, 212, 3, 30, 222, 174, 212, 8, 30, + 222, 174, 192, 5, 30, 222, 174, 192, 4, 30, 222, 174, 192, 3, 30, 222, + 174, 196, 218, 30, 222, 174, 196, 222, 30, 222, 174, 191, 219, 30, 222, + 174, 191, 215, 30, 222, 174, 233, 241, 30, 222, 174, 233, 239, 30, 222, + 174, 233, 240, 30, 222, 174, 233, 237, 30, 222, 174, 228, 60, 30, 222, + 174, 228, 59, 30, 222, 174, 228, 57, 30, 222, 174, 228, 58, 30, 222, 174, + 228, 63, 30, 222, 174, 228, 56, 30, 222, 174, 228, 55, 30, 222, 174, 228, + 65, 30, 222, 174, 251, 24, 30, 222, 174, 251, 23, 30, 125, 213, 197, 30, + 125, 213, 203, 30, 125, 201, 156, 30, 125, 201, 155, 30, 125, 198, 163, + 30, 125, 198, 161, 30, 125, 198, 160, 30, 125, 198, 166, 30, 125, 198, + 167, 30, 125, 198, 159, 30, 125, 206, 218, 30, 125, 206, 233, 30, 125, + 201, 162, 30, 125, 206, 230, 30, 125, 206, 220, 30, 125, 206, 222, 30, + 125, 206, 209, 30, 125, 206, 210, 30, 125, 222, 68, 30, 125, 216, 72, 30, + 125, 216, 66, 30, 125, 201, 166, 30, 125, 216, 69, 30, 125, 216, 75, 30, + 125, 209, 150, 30, 125, 209, 159, 30, 125, 209, 163, 30, 125, 201, 164, + 30, 125, 209, 153, 30, 125, 209, 167, 30, 125, 209, 168, 30, 125, 202, + 152, 30, 125, 202, 155, 30, 125, 201, 160, 30, 125, 201, 158, 30, 125, + 202, 150, 30, 125, 202, 158, 30, 125, 202, 159, 30, 125, 202, 144, 30, + 125, 202, 157, 30, 125, 210, 147, 30, 125, 210, 148, 30, 125, 192, 53, + 30, 125, 192, 56, 30, 125, 243, 22, 30, 125, 243, 21, 30, 125, 201, 171, + 30, 125, 209, 206, 30, 125, 209, 205, 12, 15, 225, 190, 12, 15, 225, 189, + 12, 15, 225, 188, 12, 15, 225, 187, 12, 15, 225, 186, 12, 15, 225, 185, + 12, 15, 225, 184, 12, 15, 225, 183, 12, 15, 225, 182, 12, 15, 225, 181, + 12, 15, 225, 180, 12, 15, 225, 179, 12, 15, 225, 178, 12, 15, 225, 177, + 12, 15, 225, 176, 12, 15, 225, 175, 12, 15, 225, 174, 12, 15, 225, 173, + 12, 15, 225, 172, 12, 15, 225, 171, 12, 15, 225, 170, 12, 15, 225, 169, + 12, 15, 225, 168, 12, 15, 225, 167, 12, 15, 225, 166, 12, 15, 225, 165, + 12, 15, 225, 164, 12, 15, 225, 163, 12, 15, 225, 162, 12, 15, 225, 161, + 12, 15, 225, 160, 12, 15, 225, 159, 12, 15, 225, 158, 12, 15, 225, 157, + 12, 15, 225, 156, 12, 15, 225, 155, 12, 15, 225, 154, 12, 15, 225, 153, + 12, 15, 225, 152, 12, 15, 225, 151, 12, 15, 225, 150, 12, 15, 225, 149, + 12, 15, 225, 148, 12, 15, 225, 147, 12, 15, 225, 146, 12, 15, 225, 145, + 12, 15, 225, 144, 12, 15, 225, 143, 12, 15, 225, 142, 12, 15, 225, 141, + 12, 15, 225, 140, 12, 15, 225, 139, 12, 15, 225, 138, 12, 15, 225, 137, + 12, 15, 225, 136, 12, 15, 225, 135, 12, 15, 225, 134, 12, 15, 225, 133, + 12, 15, 225, 132, 12, 15, 225, 131, 12, 15, 225, 130, 12, 15, 225, 129, + 12, 15, 225, 128, 12, 15, 225, 127, 12, 15, 225, 126, 12, 15, 225, 125, + 12, 15, 225, 124, 12, 15, 225, 123, 12, 15, 225, 122, 12, 15, 225, 121, + 12, 15, 225, 120, 12, 15, 225, 119, 12, 15, 225, 118, 12, 15, 225, 117, + 12, 15, 225, 116, 12, 15, 225, 115, 12, 15, 225, 114, 12, 15, 225, 113, + 12, 15, 225, 112, 12, 15, 225, 111, 12, 15, 225, 110, 12, 15, 225, 109, + 12, 15, 225, 108, 12, 15, 225, 107, 12, 15, 225, 106, 12, 15, 225, 105, + 12, 15, 225, 104, 12, 15, 225, 103, 12, 15, 225, 102, 12, 15, 225, 101, + 12, 15, 225, 100, 12, 15, 225, 99, 12, 15, 225, 98, 12, 15, 225, 97, 12, + 15, 225, 96, 12, 15, 225, 95, 12, 15, 225, 94, 12, 15, 225, 93, 12, 15, + 225, 92, 12, 15, 225, 91, 12, 15, 225, 90, 12, 15, 225, 89, 12, 15, 225, + 88, 12, 15, 225, 87, 12, 15, 225, 86, 12, 15, 225, 85, 12, 15, 225, 84, + 12, 15, 225, 83, 12, 15, 225, 82, 12, 15, 225, 81, 12, 15, 225, 80, 12, + 15, 225, 79, 12, 15, 225, 78, 12, 15, 225, 77, 12, 15, 225, 76, 12, 15, + 225, 75, 12, 15, 225, 74, 12, 15, 225, 73, 12, 15, 225, 72, 12, 15, 225, + 71, 12, 15, 225, 70, 12, 15, 225, 69, 12, 15, 225, 68, 12, 15, 225, 67, + 12, 15, 225, 66, 12, 15, 225, 65, 12, 15, 225, 64, 12, 15, 225, 63, 12, + 15, 225, 62, 12, 15, 225, 61, 12, 15, 225, 60, 12, 15, 225, 59, 12, 15, + 225, 58, 12, 15, 225, 57, 12, 15, 225, 56, 12, 15, 225, 55, 12, 15, 225, + 54, 12, 15, 225, 53, 12, 15, 225, 52, 12, 15, 225, 51, 12, 15, 225, 50, + 12, 15, 225, 49, 12, 15, 225, 48, 12, 15, 225, 47, 12, 15, 225, 46, 12, + 15, 225, 45, 12, 15, 225, 44, 12, 15, 225, 43, 12, 15, 225, 42, 12, 15, + 225, 41, 12, 15, 225, 40, 12, 15, 225, 39, 12, 15, 225, 38, 12, 15, 225, + 37, 12, 15, 225, 36, 12, 15, 225, 35, 12, 15, 225, 34, 12, 15, 225, 33, + 12, 15, 225, 32, 12, 15, 225, 31, 12, 15, 225, 30, 12, 15, 225, 29, 12, + 15, 225, 28, 12, 15, 225, 27, 12, 15, 225, 26, 12, 15, 225, 25, 12, 15, + 225, 24, 12, 15, 225, 23, 12, 15, 225, 22, 12, 15, 225, 21, 12, 15, 225, + 20, 12, 15, 225, 19, 12, 15, 225, 18, 12, 15, 225, 17, 12, 15, 225, 16, + 12, 15, 225, 15, 12, 15, 225, 14, 12, 15, 225, 13, 12, 15, 225, 12, 12, + 15, 225, 11, 12, 15, 225, 10, 12, 15, 225, 9, 12, 15, 225, 8, 12, 15, + 225, 7, 12, 15, 225, 6, 12, 15, 225, 5, 12, 15, 225, 4, 12, 15, 225, 3, + 12, 15, 225, 2, 12, 15, 225, 1, 12, 15, 225, 0, 12, 15, 224, 255, 12, 15, + 224, 254, 12, 15, 224, 253, 12, 15, 224, 252, 12, 15, 224, 251, 12, 15, + 224, 250, 12, 15, 224, 249, 12, 15, 224, 248, 12, 15, 224, 247, 12, 15, + 224, 246, 12, 15, 224, 245, 12, 15, 224, 244, 12, 15, 224, 243, 12, 15, + 224, 242, 12, 15, 224, 241, 12, 15, 224, 240, 12, 15, 224, 239, 12, 15, + 224, 238, 12, 15, 224, 237, 12, 15, 224, 236, 12, 15, 224, 235, 12, 15, + 224, 234, 12, 15, 224, 233, 12, 15, 224, 232, 12, 15, 224, 231, 12, 15, + 224, 230, 12, 15, 224, 229, 12, 15, 224, 228, 12, 15, 224, 227, 12, 15, + 224, 226, 12, 15, 224, 225, 12, 15, 224, 224, 12, 15, 224, 223, 12, 15, + 224, 222, 12, 15, 224, 221, 12, 15, 224, 220, 12, 15, 224, 219, 12, 15, + 224, 218, 12, 15, 224, 217, 12, 15, 224, 216, 12, 15, 224, 215, 12, 15, + 224, 214, 12, 15, 224, 213, 12, 15, 224, 212, 12, 15, 224, 211, 12, 15, + 224, 210, 12, 15, 224, 209, 12, 15, 224, 208, 12, 15, 224, 207, 12, 15, + 224, 206, 12, 15, 224, 205, 12, 15, 224, 204, 12, 15, 224, 203, 12, 15, + 224, 202, 12, 15, 224, 201, 12, 15, 224, 200, 12, 15, 224, 199, 12, 15, + 224, 198, 12, 15, 224, 197, 12, 15, 224, 196, 12, 15, 224, 195, 12, 15, + 224, 194, 12, 15, 224, 193, 12, 15, 224, 192, 12, 15, 224, 191, 12, 15, + 224, 190, 12, 15, 224, 189, 12, 15, 224, 188, 12, 15, 224, 187, 12, 15, + 224, 186, 12, 15, 224, 185, 12, 15, 224, 184, 12, 15, 224, 183, 12, 15, + 224, 182, 12, 15, 224, 181, 12, 15, 224, 180, 12, 15, 224, 179, 12, 15, + 224, 178, 12, 15, 224, 177, 12, 15, 224, 176, 12, 15, 224, 175, 12, 15, + 224, 174, 12, 15, 224, 173, 12, 15, 224, 172, 12, 15, 224, 171, 12, 15, + 224, 170, 12, 15, 224, 169, 12, 15, 224, 168, 12, 15, 224, 167, 12, 15, + 224, 166, 12, 15, 224, 165, 12, 15, 224, 164, 12, 15, 224, 163, 12, 15, + 224, 162, 12, 15, 224, 161, 12, 15, 224, 160, 12, 15, 224, 159, 12, 15, + 224, 158, 12, 15, 224, 157, 12, 15, 224, 156, 12, 15, 224, 155, 12, 15, + 224, 154, 12, 15, 224, 153, 12, 15, 224, 152, 12, 15, 224, 151, 12, 15, + 224, 150, 12, 15, 224, 149, 12, 15, 224, 148, 12, 15, 224, 147, 12, 15, + 224, 146, 12, 15, 224, 145, 12, 15, 224, 144, 12, 15, 224, 143, 12, 15, + 224, 142, 12, 15, 224, 141, 12, 15, 224, 140, 12, 15, 224, 139, 12, 15, + 224, 138, 12, 15, 224, 137, 12, 15, 224, 136, 12, 15, 224, 135, 12, 15, + 224, 134, 12, 15, 224, 133, 12, 15, 224, 132, 12, 15, 224, 131, 12, 15, + 224, 130, 12, 15, 224, 129, 12, 15, 224, 128, 12, 15, 224, 127, 12, 15, + 224, 126, 12, 15, 224, 125, 12, 15, 224, 124, 12, 15, 224, 123, 12, 15, + 224, 122, 12, 15, 224, 121, 12, 15, 224, 120, 12, 15, 224, 119, 12, 15, + 224, 118, 12, 15, 224, 117, 12, 15, 224, 116, 12, 15, 224, 115, 12, 15, + 224, 114, 12, 15, 224, 113, 12, 15, 224, 112, 12, 15, 224, 111, 12, 15, + 224, 110, 12, 15, 224, 109, 12, 15, 224, 108, 12, 15, 224, 107, 12, 15, + 224, 106, 12, 15, 224, 105, 12, 15, 224, 104, 12, 15, 224, 103, 12, 15, + 224, 102, 12, 15, 224, 101, 12, 15, 224, 100, 12, 15, 224, 99, 12, 15, + 224, 98, 12, 15, 224, 97, 12, 15, 224, 96, 12, 15, 224, 95, 12, 15, 224, + 94, 12, 15, 224, 93, 12, 15, 224, 92, 12, 15, 224, 91, 12, 15, 224, 90, + 12, 15, 224, 89, 12, 15, 224, 88, 12, 15, 224, 87, 12, 15, 224, 86, 12, + 15, 224, 85, 12, 15, 224, 84, 12, 15, 224, 83, 12, 15, 224, 82, 12, 15, + 224, 81, 12, 15, 224, 80, 12, 15, 224, 79, 12, 15, 224, 78, 12, 15, 224, + 77, 12, 15, 224, 76, 12, 15, 224, 75, 12, 15, 224, 74, 12, 15, 224, 73, + 12, 15, 224, 72, 12, 15, 224, 71, 12, 15, 224, 70, 12, 15, 224, 69, 12, + 15, 224, 68, 12, 15, 224, 67, 12, 15, 224, 66, 12, 15, 224, 65, 12, 15, + 224, 64, 12, 15, 224, 63, 12, 15, 224, 62, 12, 15, 224, 61, 12, 15, 224, + 60, 12, 15, 224, 59, 12, 15, 224, 58, 12, 15, 224, 57, 12, 15, 224, 56, + 12, 15, 224, 55, 12, 15, 224, 54, 12, 15, 224, 53, 12, 15, 224, 52, 12, + 15, 224, 51, 12, 15, 224, 50, 12, 15, 224, 49, 12, 15, 224, 48, 12, 15, + 224, 47, 12, 15, 224, 46, 12, 15, 224, 45, 12, 15, 224, 44, 12, 15, 224, + 43, 12, 15, 224, 42, 12, 15, 224, 41, 12, 15, 224, 40, 12, 15, 224, 39, + 12, 15, 224, 38, 12, 15, 224, 37, 12, 15, 224, 36, 12, 15, 224, 35, 12, + 15, 224, 34, 12, 15, 224, 33, 12, 15, 224, 32, 12, 15, 224, 31, 12, 15, + 224, 30, 12, 15, 224, 29, 12, 15, 224, 28, 12, 15, 224, 27, 12, 15, 224, + 26, 12, 15, 224, 25, 12, 15, 224, 24, 12, 15, 224, 23, 12, 15, 224, 22, + 12, 15, 224, 21, 12, 15, 224, 20, 12, 15, 224, 19, 12, 15, 224, 18, 12, + 15, 224, 17, 12, 15, 224, 16, 12, 15, 224, 15, 12, 15, 224, 14, 12, 15, + 224, 13, 12, 15, 224, 12, 12, 15, 224, 11, 12, 15, 224, 10, 12, 15, 224, + 9, 12, 15, 224, 8, 12, 15, 224, 7, 12, 15, 224, 6, 12, 15, 224, 5, 12, + 15, 224, 4, 12, 15, 224, 3, 12, 15, 224, 2, 12, 15, 224, 1, 12, 15, 224, + 0, 12, 15, 223, 255, 12, 15, 223, 254, 12, 15, 223, 253, 12, 15, 223, + 252, 12, 15, 223, 251, 12, 15, 223, 250, 12, 15, 223, 249, 12, 15, 223, + 248, 12, 15, 223, 247, 12, 15, 223, 246, 12, 15, 223, 245, 12, 15, 223, + 244, 12, 15, 223, 243, 12, 15, 223, 242, 12, 15, 223, 241, 12, 15, 223, + 240, 12, 15, 223, 239, 12, 15, 223, 238, 12, 15, 223, 237, 12, 15, 223, + 236, 12, 15, 223, 235, 12, 15, 223, 234, 12, 15, 223, 233, 12, 15, 223, + 232, 12, 15, 223, 231, 8, 2, 34, 233, 27, 8, 2, 34, 233, 23, 8, 2, 34, + 232, 220, 8, 2, 34, 233, 26, 8, 2, 34, 233, 25, 8, 2, 34, 179, 206, 9, + 200, 43, 8, 2, 34, 201, 118, 250, 249, 2, 34, 216, 187, 212, 253, 250, + 249, 2, 34, 216, 187, 234, 195, 250, 249, 2, 34, 216, 187, 223, 131, 250, + 249, 2, 34, 195, 75, 212, 253, 250, 249, 2, 34, 216, 187, 192, 212, 136, + 1, 191, 251, 4, 229, 119, 136, 209, 62, 222, 181, 195, 166, 136, 34, 192, + 31, 191, 251, 191, 251, 210, 88, 136, 1, 251, 152, 250, 126, 136, 1, 193, + 78, 251, 192, 136, 1, 193, 78, 237, 253, 136, 1, 193, 78, 229, 245, 136, + 1, 193, 78, 222, 106, 136, 1, 193, 78, 220, 27, 136, 1, 193, 78, 53, 216, + 193, 136, 1, 193, 78, 207, 38, 136, 1, 193, 78, 199, 162, 136, 1, 251, + 152, 108, 56, 136, 1, 203, 70, 4, 203, 70, 236, 140, 136, 1, 203, 70, 4, + 202, 175, 236, 140, 136, 1, 203, 70, 4, 238, 17, 23, 203, 70, 236, 140, + 136, 1, 203, 70, 4, 238, 17, 23, 202, 175, 236, 140, 136, 1, 131, 4, 210, + 88, 136, 1, 131, 4, 208, 84, 136, 1, 131, 4, 217, 70, 136, 1, 248, 215, + 4, 238, 16, 136, 1, 231, 39, 4, 238, 16, 136, 1, 237, 254, 4, 238, 16, + 136, 1, 229, 246, 4, 217, 70, 136, 1, 195, 159, 4, 238, 16, 136, 1, 191, + 92, 4, 238, 16, 136, 1, 199, 74, 4, 238, 16, 136, 1, 191, 251, 4, 238, + 16, 136, 1, 53, 222, 107, 4, 238, 16, 136, 1, 222, 107, 4, 238, 16, 136, + 1, 220, 28, 4, 238, 16, 136, 1, 216, 194, 4, 238, 16, 136, 1, 212, 131, + 4, 238, 16, 136, 1, 205, 149, 4, 238, 16, 136, 1, 53, 210, 64, 4, 238, + 16, 136, 1, 210, 64, 4, 238, 16, 136, 1, 197, 164, 4, 238, 16, 136, 1, + 208, 43, 4, 238, 16, 136, 1, 207, 39, 4, 238, 16, 136, 1, 203, 70, 4, + 238, 16, 136, 1, 199, 163, 4, 238, 16, 136, 1, 195, 159, 4, 229, 7, 136, + 1, 248, 215, 4, 207, 161, 136, 1, 222, 107, 4, 207, 161, 136, 1, 210, 64, + 4, 207, 161, 136, 34, 131, 220, 27, 9, 1, 131, 193, 151, 76, 20, 9, 1, + 131, 193, 151, 53, 20, 9, 1, 249, 0, 76, 20, 9, 1, 249, 0, 53, 20, 9, 1, + 249, 0, 89, 20, 9, 1, 249, 0, 216, 217, 20, 9, 1, 210, 42, 76, 20, 9, 1, + 210, 42, 53, 20, 9, 1, 210, 42, 89, 20, 9, 1, 210, 42, 216, 217, 20, 9, + 1, 248, 244, 76, 20, 9, 1, 248, 244, 53, 20, 9, 1, 248, 244, 89, 20, 9, + 1, 248, 244, 216, 217, 20, 9, 1, 197, 123, 76, 20, 9, 1, 197, 123, 53, + 20, 9, 1, 197, 123, 89, 20, 9, 1, 197, 123, 216, 217, 20, 9, 1, 199, 113, + 76, 20, 9, 1, 199, 113, 53, 20, 9, 1, 199, 113, 89, 20, 9, 1, 199, 113, + 216, 217, 20, 9, 1, 197, 125, 76, 20, 9, 1, 197, 125, 53, 20, 9, 1, 197, + 125, 89, 20, 9, 1, 197, 125, 216, 217, 20, 9, 1, 195, 147, 76, 20, 9, 1, + 195, 147, 53, 20, 9, 1, 195, 147, 89, 20, 9, 1, 195, 147, 216, 217, 20, + 9, 1, 210, 40, 76, 20, 9, 1, 210, 40, 53, 20, 9, 1, 210, 40, 89, 20, 9, + 1, 210, 40, 216, 217, 20, 9, 1, 235, 42, 76, 20, 9, 1, 235, 42, 53, 20, + 9, 1, 235, 42, 89, 20, 9, 1, 235, 42, 216, 217, 20, 9, 1, 212, 88, 76, + 20, 9, 1, 212, 88, 53, 20, 9, 1, 212, 88, 89, 20, 9, 1, 212, 88, 216, + 217, 20, 9, 1, 199, 150, 76, 20, 9, 1, 199, 150, 53, 20, 9, 1, 199, 150, + 89, 20, 9, 1, 199, 150, 216, 217, 20, 9, 1, 199, 148, 76, 20, 9, 1, 199, + 148, 53, 20, 9, 1, 199, 148, 89, 20, 9, 1, 199, 148, 216, 217, 20, 9, 1, + 237, 189, 76, 20, 9, 1, 237, 189, 53, 20, 9, 1, 238, 11, 76, 20, 9, 1, + 238, 11, 53, 20, 9, 1, 235, 79, 76, 20, 9, 1, 235, 79, 53, 20, 9, 1, 237, + 187, 76, 20, 9, 1, 237, 187, 53, 20, 9, 1, 223, 4, 76, 20, 9, 1, 223, 4, + 53, 20, 9, 1, 206, 102, 76, 20, 9, 1, 206, 102, 53, 20, 9, 1, 222, 5, 76, + 20, 9, 1, 222, 5, 53, 20, 9, 1, 222, 5, 89, 20, 9, 1, 222, 5, 216, 217, + 20, 9, 1, 231, 228, 76, 20, 9, 1, 231, 228, 53, 20, 9, 1, 231, 228, 89, + 20, 9, 1, 231, 228, 216, 217, 20, 9, 1, 230, 167, 76, 20, 9, 1, 230, 167, + 53, 20, 9, 1, 230, 167, 89, 20, 9, 1, 230, 167, 216, 217, 20, 9, 1, 213, + 248, 76, 20, 9, 1, 213, 248, 53, 20, 9, 1, 213, 248, 89, 20, 9, 1, 213, + 248, 216, 217, 20, 9, 1, 213, 25, 231, 58, 76, 20, 9, 1, 213, 25, 231, + 58, 53, 20, 9, 1, 206, 166, 76, 20, 9, 1, 206, 166, 53, 20, 9, 1, 206, + 166, 89, 20, 9, 1, 206, 166, 216, 217, 20, 9, 1, 229, 211, 4, 99, 93, 76, + 20, 9, 1, 229, 211, 4, 99, 93, 53, 20, 9, 1, 229, 211, 231, 1, 76, 20, 9, + 1, 229, 211, 231, 1, 53, 20, 9, 1, 229, 211, 231, 1, 89, 20, 9, 1, 229, + 211, 231, 1, 216, 217, 20, 9, 1, 229, 211, 236, 171, 76, 20, 9, 1, 229, + 211, 236, 171, 53, 20, 9, 1, 229, 211, 236, 171, 89, 20, 9, 1, 229, 211, + 236, 171, 216, 217, 20, 9, 1, 99, 249, 81, 76, 20, 9, 1, 99, 249, 81, 53, + 20, 9, 1, 99, 249, 81, 4, 230, 58, 93, 76, 20, 9, 1, 99, 249, 81, 4, 230, + 58, 93, 53, 20, 9, 16, 75, 58, 9, 16, 75, 60, 9, 16, 105, 185, 58, 9, 16, + 105, 185, 60, 9, 16, 115, 185, 58, 9, 16, 115, 185, 60, 9, 16, 115, 185, + 209, 58, 235, 119, 58, 9, 16, 115, 185, 209, 58, 235, 119, 60, 9, 16, + 232, 128, 185, 58, 9, 16, 232, 128, 185, 60, 9, 16, 55, 81, 249, 88, 60, + 9, 16, 105, 185, 195, 85, 58, 9, 16, 105, 185, 195, 85, 60, 9, 16, 206, + 188, 9, 16, 2, 199, 220, 58, 9, 16, 2, 199, 220, 60, 9, 16, 193, 151, 58, + 9, 1, 214, 71, 76, 20, 9, 1, 214, 71, 53, 20, 9, 1, 214, 71, 89, 20, 9, + 1, 214, 71, 216, 217, 20, 9, 1, 126, 76, 20, 9, 1, 126, 53, 20, 9, 1, + 211, 152, 76, 20, 9, 1, 211, 152, 53, 20, 9, 1, 191, 226, 76, 20, 9, 1, + 191, 226, 53, 20, 9, 1, 126, 4, 230, 58, 93, 76, 20, 9, 1, 195, 154, 76, + 20, 9, 1, 195, 154, 53, 20, 9, 1, 221, 132, 211, 152, 76, 20, 9, 1, 221, + 132, 211, 152, 53, 20, 9, 1, 221, 132, 191, 226, 76, 20, 9, 1, 221, 132, + 191, 226, 53, 20, 9, 1, 235, 15, 76, 20, 9, 1, 235, 15, 53, 20, 9, 1, + 235, 15, 89, 20, 9, 1, 235, 15, 216, 217, 20, 9, 1, 196, 137, 222, 26, + 221, 132, 131, 217, 100, 89, 20, 9, 1, 196, 137, 222, 26, 221, 132, 131, + 217, 100, 216, 217, 20, 9, 34, 99, 4, 230, 58, 93, 4, 131, 76, 20, 9, 34, + 99, 4, 230, 58, 93, 4, 131, 53, 20, 9, 34, 99, 4, 230, 58, 93, 4, 252, + 26, 76, 20, 9, 34, 99, 4, 230, 58, 93, 4, 252, 26, 53, 20, 9, 34, 99, 4, + 230, 58, 93, 4, 193, 134, 76, 20, 9, 34, 99, 4, 230, 58, 93, 4, 193, 134, + 53, 20, 9, 34, 99, 4, 230, 58, 93, 4, 126, 76, 20, 9, 34, 99, 4, 230, 58, + 93, 4, 126, 53, 20, 9, 34, 99, 4, 230, 58, 93, 4, 211, 152, 76, 20, 9, + 34, 99, 4, 230, 58, 93, 4, 211, 152, 53, 20, 9, 34, 99, 4, 230, 58, 93, + 4, 191, 226, 76, 20, 9, 34, 99, 4, 230, 58, 93, 4, 191, 226, 53, 20, 9, + 34, 99, 4, 230, 58, 93, 4, 235, 15, 76, 20, 9, 34, 99, 4, 230, 58, 93, 4, + 235, 15, 53, 20, 9, 34, 99, 4, 230, 58, 93, 4, 235, 15, 89, 20, 9, 34, + 196, 137, 221, 132, 99, 4, 230, 58, 93, 4, 131, 217, 100, 76, 20, 9, 34, + 196, 137, 221, 132, 99, 4, 230, 58, 93, 4, 131, 217, 100, 53, 20, 9, 34, + 196, 137, 221, 132, 99, 4, 230, 58, 93, 4, 131, 217, 100, 89, 20, 9, 1, + 233, 74, 99, 76, 20, 9, 1, 233, 74, 99, 53, 20, 9, 1, 233, 74, 99, 89, + 20, 9, 1, 233, 74, 99, 216, 217, 20, 9, 34, 99, 4, 230, 58, 93, 4, 223, + 7, 76, 20, 9, 34, 99, 4, 230, 58, 93, 4, 182, 76, 20, 9, 34, 99, 4, 230, + 58, 93, 4, 92, 76, 20, 9, 34, 99, 4, 230, 58, 93, 4, 131, 217, 100, 76, + 20, 9, 34, 99, 4, 230, 58, 93, 4, 99, 76, 20, 9, 34, 248, 246, 4, 223, 7, + 76, 20, 9, 34, 248, 246, 4, 182, 76, 20, 9, 34, 248, 246, 4, 221, 211, + 76, 20, 9, 34, 248, 246, 4, 92, 76, 20, 9, 34, 248, 246, 4, 131, 217, + 100, 76, 20, 9, 34, 248, 246, 4, 99, 76, 20, 9, 34, 199, 115, 4, 223, 7, + 76, 20, 9, 34, 199, 115, 4, 182, 76, 20, 9, 34, 199, 115, 4, 221, 211, + 76, 20, 9, 34, 199, 115, 4, 92, 76, 20, 9, 34, 199, 115, 4, 131, 217, + 100, 76, 20, 9, 34, 199, 115, 4, 99, 76, 20, 9, 34, 199, 30, 4, 223, 7, + 76, 20, 9, 34, 199, 30, 4, 92, 76, 20, 9, 34, 199, 30, 4, 131, 217, 100, + 76, 20, 9, 34, 199, 30, 4, 99, 76, 20, 9, 34, 223, 7, 4, 182, 76, 20, 9, + 34, 223, 7, 4, 92, 76, 20, 9, 34, 182, 4, 223, 7, 76, 20, 9, 34, 182, 4, + 92, 76, 20, 9, 34, 221, 211, 4, 223, 7, 76, 20, 9, 34, 221, 211, 4, 182, + 76, 20, 9, 34, 221, 211, 4, 92, 76, 20, 9, 34, 205, 47, 4, 223, 7, 76, + 20, 9, 34, 205, 47, 4, 182, 76, 20, 9, 34, 205, 47, 4, 221, 211, 76, 20, + 9, 34, 205, 47, 4, 92, 76, 20, 9, 34, 205, 193, 4, 182, 76, 20, 9, 34, + 205, 193, 4, 92, 76, 20, 9, 34, 238, 27, 4, 223, 7, 76, 20, 9, 34, 238, + 27, 4, 182, 76, 20, 9, 34, 238, 27, 4, 221, 211, 76, 20, 9, 34, 238, 27, + 4, 92, 76, 20, 9, 34, 199, 220, 4, 182, 76, 20, 9, 34, 199, 220, 4, 92, + 76, 20, 9, 34, 191, 117, 4, 92, 76, 20, 9, 34, 251, 231, 4, 223, 7, 76, + 20, 9, 34, 251, 231, 4, 92, 76, 20, 9, 34, 231, 87, 4, 223, 7, 76, 20, 9, + 34, 231, 87, 4, 92, 76, 20, 9, 34, 233, 47, 4, 223, 7, 76, 20, 9, 34, + 233, 47, 4, 182, 76, 20, 9, 34, 233, 47, 4, 221, 211, 76, 20, 9, 34, 233, + 47, 4, 92, 76, 20, 9, 34, 233, 47, 4, 131, 217, 100, 76, 20, 9, 34, 233, + 47, 4, 99, 76, 20, 9, 34, 208, 90, 4, 182, 76, 20, 9, 34, 208, 90, 4, 92, + 76, 20, 9, 34, 208, 90, 4, 131, 217, 100, 76, 20, 9, 34, 208, 90, 4, 99, + 76, 20, 9, 34, 222, 107, 4, 131, 76, 20, 9, 34, 222, 107, 4, 223, 7, 76, + 20, 9, 34, 222, 107, 4, 182, 76, 20, 9, 34, 222, 107, 4, 221, 211, 76, + 20, 9, 34, 222, 107, 4, 220, 36, 76, 20, 9, 34, 222, 107, 4, 92, 76, 20, + 9, 34, 222, 107, 4, 131, 217, 100, 76, 20, 9, 34, 222, 107, 4, 99, 76, + 20, 9, 34, 220, 36, 4, 223, 7, 76, 20, 9, 34, 220, 36, 4, 182, 76, 20, 9, + 34, 220, 36, 4, 221, 211, 76, 20, 9, 34, 220, 36, 4, 92, 76, 20, 9, 34, + 220, 36, 4, 131, 217, 100, 76, 20, 9, 34, 220, 36, 4, 99, 76, 20, 9, 34, + 92, 4, 223, 7, 76, 20, 9, 34, 92, 4, 182, 76, 20, 9, 34, 92, 4, 221, 211, + 76, 20, 9, 34, 92, 4, 92, 76, 20, 9, 34, 92, 4, 131, 217, 100, 76, 20, 9, + 34, 92, 4, 99, 76, 20, 9, 34, 213, 25, 4, 223, 7, 76, 20, 9, 34, 213, 25, + 4, 182, 76, 20, 9, 34, 213, 25, 4, 221, 211, 76, 20, 9, 34, 213, 25, 4, + 92, 76, 20, 9, 34, 213, 25, 4, 131, 217, 100, 76, 20, 9, 34, 213, 25, 4, + 99, 76, 20, 9, 34, 229, 211, 4, 223, 7, 76, 20, 9, 34, 229, 211, 4, 92, + 76, 20, 9, 34, 229, 211, 4, 131, 217, 100, 76, 20, 9, 34, 229, 211, 4, + 99, 76, 20, 9, 34, 99, 4, 223, 7, 76, 20, 9, 34, 99, 4, 182, 76, 20, 9, + 34, 99, 4, 221, 211, 76, 20, 9, 34, 99, 4, 92, 76, 20, 9, 34, 99, 4, 131, + 217, 100, 76, 20, 9, 34, 99, 4, 99, 76, 20, 9, 34, 199, 42, 4, 200, 182, + 131, 76, 20, 9, 34, 207, 72, 4, 200, 182, 131, 76, 20, 9, 34, 131, 217, + 100, 4, 200, 182, 131, 76, 20, 9, 34, 203, 156, 4, 237, 244, 76, 20, 9, + 34, 203, 156, 4, 222, 51, 76, 20, 9, 34, 203, 156, 4, 233, 71, 76, 20, 9, + 34, 203, 156, 4, 237, 246, 76, 20, 9, 34, 203, 156, 4, 222, 53, 76, 20, + 9, 34, 203, 156, 4, 200, 182, 131, 76, 20, 9, 34, 99, 4, 230, 58, 93, 4, + 207, 72, 53, 20, 9, 34, 99, 4, 230, 58, 93, 4, 191, 114, 53, 20, 9, 34, + 99, 4, 230, 58, 93, 4, 92, 53, 20, 9, 34, 99, 4, 230, 58, 93, 4, 213, 25, + 53, 20, 9, 34, 99, 4, 230, 58, 93, 4, 131, 217, 100, 53, 20, 9, 34, 99, + 4, 230, 58, 93, 4, 99, 53, 20, 9, 34, 248, 246, 4, 207, 72, 53, 20, 9, + 34, 248, 246, 4, 191, 114, 53, 20, 9, 34, 248, 246, 4, 92, 53, 20, 9, 34, + 248, 246, 4, 213, 25, 53, 20, 9, 34, 248, 246, 4, 131, 217, 100, 53, 20, + 9, 34, 248, 246, 4, 99, 53, 20, 9, 34, 199, 115, 4, 207, 72, 53, 20, 9, + 34, 199, 115, 4, 191, 114, 53, 20, 9, 34, 199, 115, 4, 92, 53, 20, 9, 34, + 199, 115, 4, 213, 25, 53, 20, 9, 34, 199, 115, 4, 131, 217, 100, 53, 20, + 9, 34, 199, 115, 4, 99, 53, 20, 9, 34, 199, 30, 4, 207, 72, 53, 20, 9, + 34, 199, 30, 4, 191, 114, 53, 20, 9, 34, 199, 30, 4, 92, 53, 20, 9, 34, + 199, 30, 4, 213, 25, 53, 20, 9, 34, 199, 30, 4, 131, 217, 100, 53, 20, 9, + 34, 199, 30, 4, 99, 53, 20, 9, 34, 233, 47, 4, 131, 217, 100, 53, 20, 9, + 34, 233, 47, 4, 99, 53, 20, 9, 34, 208, 90, 4, 131, 217, 100, 53, 20, 9, + 34, 208, 90, 4, 99, 53, 20, 9, 34, 222, 107, 4, 131, 53, 20, 9, 34, 222, + 107, 4, 220, 36, 53, 20, 9, 34, 222, 107, 4, 92, 53, 20, 9, 34, 222, 107, + 4, 131, 217, 100, 53, 20, 9, 34, 222, 107, 4, 99, 53, 20, 9, 34, 220, 36, + 4, 92, 53, 20, 9, 34, 220, 36, 4, 131, 217, 100, 53, 20, 9, 34, 220, 36, + 4, 99, 53, 20, 9, 34, 92, 4, 131, 53, 20, 9, 34, 92, 4, 92, 53, 20, 9, + 34, 213, 25, 4, 207, 72, 53, 20, 9, 34, 213, 25, 4, 191, 114, 53, 20, 9, + 34, 213, 25, 4, 92, 53, 20, 9, 34, 213, 25, 4, 213, 25, 53, 20, 9, 34, + 213, 25, 4, 131, 217, 100, 53, 20, 9, 34, 213, 25, 4, 99, 53, 20, 9, 34, + 131, 217, 100, 4, 200, 182, 131, 53, 20, 9, 34, 99, 4, 207, 72, 53, 20, + 9, 34, 99, 4, 191, 114, 53, 20, 9, 34, 99, 4, 92, 53, 20, 9, 34, 99, 4, + 213, 25, 53, 20, 9, 34, 99, 4, 131, 217, 100, 53, 20, 9, 34, 99, 4, 99, + 53, 20, 9, 34, 99, 4, 230, 58, 93, 4, 223, 7, 89, 20, 9, 34, 99, 4, 230, + 58, 93, 4, 182, 89, 20, 9, 34, 99, 4, 230, 58, 93, 4, 221, 211, 89, 20, + 9, 34, 99, 4, 230, 58, 93, 4, 92, 89, 20, 9, 34, 99, 4, 230, 58, 93, 4, + 229, 211, 89, 20, 9, 34, 248, 246, 4, 223, 7, 89, 20, 9, 34, 248, 246, 4, + 182, 89, 20, 9, 34, 248, 246, 4, 221, 211, 89, 20, 9, 34, 248, 246, 4, + 92, 89, 20, 9, 34, 248, 246, 4, 229, 211, 89, 20, 9, 34, 199, 115, 4, + 223, 7, 89, 20, 9, 34, 199, 115, 4, 182, 89, 20, 9, 34, 199, 115, 4, 221, + 211, 89, 20, 9, 34, 199, 115, 4, 92, 89, 20, 9, 34, 199, 115, 4, 229, + 211, 89, 20, 9, 34, 199, 30, 4, 92, 89, 20, 9, 34, 223, 7, 4, 182, 89, + 20, 9, 34, 223, 7, 4, 92, 89, 20, 9, 34, 182, 4, 223, 7, 89, 20, 9, 34, + 182, 4, 92, 89, 20, 9, 34, 221, 211, 4, 223, 7, 89, 20, 9, 34, 221, 211, + 4, 92, 89, 20, 9, 34, 205, 47, 4, 223, 7, 89, 20, 9, 34, 205, 47, 4, 182, + 89, 20, 9, 34, 205, 47, 4, 221, 211, 89, 20, 9, 34, 205, 47, 4, 92, 89, + 20, 9, 34, 205, 193, 4, 182, 89, 20, 9, 34, 205, 193, 4, 221, 211, 89, + 20, 9, 34, 205, 193, 4, 92, 89, 20, 9, 34, 238, 27, 4, 223, 7, 89, 20, 9, + 34, 238, 27, 4, 182, 89, 20, 9, 34, 238, 27, 4, 221, 211, 89, 20, 9, 34, + 238, 27, 4, 92, 89, 20, 9, 34, 199, 220, 4, 182, 89, 20, 9, 34, 191, 117, + 4, 92, 89, 20, 9, 34, 251, 231, 4, 223, 7, 89, 20, 9, 34, 251, 231, 4, + 92, 89, 20, 9, 34, 231, 87, 4, 223, 7, 89, 20, 9, 34, 231, 87, 4, 92, 89, + 20, 9, 34, 233, 47, 4, 223, 7, 89, 20, 9, 34, 233, 47, 4, 182, 89, 20, 9, + 34, 233, 47, 4, 221, 211, 89, 20, 9, 34, 233, 47, 4, 92, 89, 20, 9, 34, + 208, 90, 4, 182, 89, 20, 9, 34, 208, 90, 4, 92, 89, 20, 9, 34, 222, 107, + 4, 223, 7, 89, 20, 9, 34, 222, 107, 4, 182, 89, 20, 9, 34, 222, 107, 4, + 221, 211, 89, 20, 9, 34, 222, 107, 4, 220, 36, 89, 20, 9, 34, 222, 107, + 4, 92, 89, 20, 9, 34, 220, 36, 4, 223, 7, 89, 20, 9, 34, 220, 36, 4, 182, + 89, 20, 9, 34, 220, 36, 4, 221, 211, 89, 20, 9, 34, 220, 36, 4, 92, 89, + 20, 9, 34, 220, 36, 4, 229, 211, 89, 20, 9, 34, 92, 4, 223, 7, 89, 20, 9, + 34, 92, 4, 182, 89, 20, 9, 34, 92, 4, 221, 211, 89, 20, 9, 34, 92, 4, 92, + 89, 20, 9, 34, 213, 25, 4, 223, 7, 89, 20, 9, 34, 213, 25, 4, 182, 89, + 20, 9, 34, 213, 25, 4, 221, 211, 89, 20, 9, 34, 213, 25, 4, 92, 89, 20, + 9, 34, 213, 25, 4, 229, 211, 89, 20, 9, 34, 229, 211, 4, 223, 7, 89, 20, + 9, 34, 229, 211, 4, 92, 89, 20, 9, 34, 229, 211, 4, 200, 182, 131, 89, + 20, 9, 34, 99, 4, 223, 7, 89, 20, 9, 34, 99, 4, 182, 89, 20, 9, 34, 99, + 4, 221, 211, 89, 20, 9, 34, 99, 4, 92, 89, 20, 9, 34, 99, 4, 229, 211, + 89, 20, 9, 34, 99, 4, 230, 58, 93, 4, 92, 216, 217, 20, 9, 34, 99, 4, + 230, 58, 93, 4, 229, 211, 216, 217, 20, 9, 34, 248, 246, 4, 92, 216, 217, + 20, 9, 34, 248, 246, 4, 229, 211, 216, 217, 20, 9, 34, 199, 115, 4, 92, + 216, 217, 20, 9, 34, 199, 115, 4, 229, 211, 216, 217, 20, 9, 34, 199, 30, + 4, 92, 216, 217, 20, 9, 34, 199, 30, 4, 229, 211, 216, 217, 20, 9, 34, + 205, 47, 4, 92, 216, 217, 20, 9, 34, 205, 47, 4, 229, 211, 216, 217, 20, + 9, 34, 203, 110, 4, 92, 216, 217, 20, 9, 34, 203, 110, 4, 229, 211, 216, + 217, 20, 9, 34, 222, 107, 4, 220, 36, 216, 217, 20, 9, 34, 222, 107, 4, + 92, 216, 217, 20, 9, 34, 220, 36, 4, 92, 216, 217, 20, 9, 34, 213, 25, 4, + 92, 216, 217, 20, 9, 34, 213, 25, 4, 229, 211, 216, 217, 20, 9, 34, 99, + 4, 92, 216, 217, 20, 9, 34, 99, 4, 229, 211, 216, 217, 20, 9, 34, 203, + 156, 4, 233, 71, 216, 217, 20, 9, 34, 203, 156, 4, 237, 246, 216, 217, + 20, 9, 34, 203, 156, 4, 222, 53, 216, 217, 20, 9, 34, 199, 220, 4, 131, + 217, 100, 76, 20, 9, 34, 199, 220, 4, 99, 76, 20, 9, 34, 251, 231, 4, + 131, 217, 100, 76, 20, 9, 34, 251, 231, 4, 99, 76, 20, 9, 34, 231, 87, 4, + 131, 217, 100, 76, 20, 9, 34, 231, 87, 4, 99, 76, 20, 9, 34, 205, 47, 4, + 131, 217, 100, 76, 20, 9, 34, 205, 47, 4, 99, 76, 20, 9, 34, 203, 110, 4, + 131, 217, 100, 76, 20, 9, 34, 203, 110, 4, 99, 76, 20, 9, 34, 182, 4, + 131, 217, 100, 76, 20, 9, 34, 182, 4, 99, 76, 20, 9, 34, 223, 7, 4, 131, + 217, 100, 76, 20, 9, 34, 223, 7, 4, 99, 76, 20, 9, 34, 221, 211, 4, 131, + 217, 100, 76, 20, 9, 34, 221, 211, 4, 99, 76, 20, 9, 34, 205, 193, 4, + 131, 217, 100, 76, 20, 9, 34, 205, 193, 4, 99, 76, 20, 9, 34, 238, 27, 4, + 131, 217, 100, 76, 20, 9, 34, 238, 27, 4, 99, 76, 20, 9, 34, 203, 110, 4, + 223, 7, 76, 20, 9, 34, 203, 110, 4, 182, 76, 20, 9, 34, 203, 110, 4, 221, + 211, 76, 20, 9, 34, 203, 110, 4, 92, 76, 20, 9, 34, 203, 110, 4, 207, 72, + 76, 20, 9, 34, 205, 47, 4, 207, 72, 76, 20, 9, 34, 205, 193, 4, 207, 72, + 76, 20, 9, 34, 238, 27, 4, 207, 72, 76, 20, 9, 34, 199, 220, 4, 131, 217, + 100, 53, 20, 9, 34, 199, 220, 4, 99, 53, 20, 9, 34, 251, 231, 4, 131, + 217, 100, 53, 20, 9, 34, 251, 231, 4, 99, 53, 20, 9, 34, 231, 87, 4, 131, + 217, 100, 53, 20, 9, 34, 231, 87, 4, 99, 53, 20, 9, 34, 205, 47, 4, 131, + 217, 100, 53, 20, 9, 34, 205, 47, 4, 99, 53, 20, 9, 34, 203, 110, 4, 131, + 217, 100, 53, 20, 9, 34, 203, 110, 4, 99, 53, 20, 9, 34, 182, 4, 131, + 217, 100, 53, 20, 9, 34, 182, 4, 99, 53, 20, 9, 34, 223, 7, 4, 131, 217, + 100, 53, 20, 9, 34, 223, 7, 4, 99, 53, 20, 9, 34, 221, 211, 4, 131, 217, + 100, 53, 20, 9, 34, 221, 211, 4, 99, 53, 20, 9, 34, 205, 193, 4, 131, + 217, 100, 53, 20, 9, 34, 205, 193, 4, 99, 53, 20, 9, 34, 238, 27, 4, 131, + 217, 100, 53, 20, 9, 34, 238, 27, 4, 99, 53, 20, 9, 34, 203, 110, 4, 223, + 7, 53, 20, 9, 34, 203, 110, 4, 182, 53, 20, 9, 34, 203, 110, 4, 221, 211, + 53, 20, 9, 34, 203, 110, 4, 92, 53, 20, 9, 34, 203, 110, 4, 207, 72, 53, + 20, 9, 34, 205, 47, 4, 207, 72, 53, 20, 9, 34, 205, 193, 4, 207, 72, 53, + 20, 9, 34, 238, 27, 4, 207, 72, 53, 20, 9, 34, 203, 110, 4, 223, 7, 89, + 20, 9, 34, 203, 110, 4, 182, 89, 20, 9, 34, 203, 110, 4, 221, 211, 89, + 20, 9, 34, 203, 110, 4, 92, 89, 20, 9, 34, 205, 47, 4, 229, 211, 89, 20, + 9, 34, 203, 110, 4, 229, 211, 89, 20, 9, 34, 199, 220, 4, 92, 89, 20, 9, + 34, 205, 47, 4, 223, 7, 216, 217, 20, 9, 34, 205, 47, 4, 182, 216, 217, + 20, 9, 34, 205, 47, 4, 221, 211, 216, 217, 20, 9, 34, 203, 110, 4, 223, + 7, 216, 217, 20, 9, 34, 203, 110, 4, 182, 216, 217, 20, 9, 34, 203, 110, + 4, 221, 211, 216, 217, 20, 9, 34, 199, 220, 4, 92, 216, 217, 20, 9, 34, + 191, 117, 4, 92, 216, 217, 20, 9, 34, 131, 4, 233, 69, 53, 20, 9, 34, + 131, 4, 233, 69, 76, 20, 211, 40, 45, 210, 113, 211, 40, 50, 210, 113, 9, + 34, 207, 159, 251, 173, 9, 34, 207, 167, 251, 172, 251, 107, 9, 34, 207, + 167, 251, 172, 251, 106, 9, 34, 207, 167, 251, 172, 251, 104, 9, 34, 207, + 167, 251, 172, 251, 103, 9, 34, 207, 167, 251, 172, 251, 102, 9, 34, 205, + 162, 251, 197, 193, 184, 9, 34, 251, 197, 250, 217, 9, 34, 251, 196, 250, + 217, 9, 34, 251, 195, 250, 217, 9, 34, 251, 197, 250, 216, 193, 154, 9, + 34, 208, 17, 202, 140, 9, 34, 205, 160, 251, 197, 193, 180, 193, 183, 9, + 34, 251, 200, 250, 217, 9, 34, 199, 235, 193, 182, 9, 34, 207, 158, 251, + 173, 9, 34, 199, 115, 4, 223, 7, 4, 92, 89, 20, 9, 34, 199, 115, 4, 182, + 4, 223, 7, 53, 20, 9, 34, 199, 115, 4, 182, 4, 223, 7, 89, 20, 9, 34, + 199, 115, 4, 182, 4, 92, 89, 20, 9, 34, 199, 115, 4, 221, 211, 4, 92, 89, + 20, 9, 34, 199, 115, 4, 92, 4, 223, 7, 89, 20, 9, 34, 199, 115, 4, 92, 4, + 182, 89, 20, 9, 34, 199, 115, 4, 92, 4, 221, 211, 89, 20, 9, 34, 223, 7, + 4, 92, 4, 182, 53, 20, 9, 34, 223, 7, 4, 92, 4, 182, 89, 20, 9, 34, 182, + 4, 92, 4, 99, 53, 20, 9, 34, 182, 4, 92, 4, 131, 217, 100, 53, 20, 9, 34, + 205, 47, 4, 182, 4, 223, 7, 89, 20, 9, 34, 205, 47, 4, 223, 7, 4, 182, + 89, 20, 9, 34, 205, 47, 4, 223, 7, 4, 131, 217, 100, 53, 20, 9, 34, 205, + 47, 4, 92, 4, 182, 53, 20, 9, 34, 205, 47, 4, 92, 4, 182, 89, 20, 9, 34, + 205, 47, 4, 92, 4, 223, 7, 89, 20, 9, 34, 205, 47, 4, 92, 4, 92, 53, 20, + 9, 34, 205, 47, 4, 92, 4, 92, 89, 20, 9, 34, 205, 193, 4, 182, 4, 182, + 53, 20, 9, 34, 205, 193, 4, 182, 4, 182, 89, 20, 9, 34, 205, 193, 4, 92, + 4, 92, 53, 20, 9, 34, 203, 110, 4, 182, 4, 92, 53, 20, 9, 34, 203, 110, + 4, 182, 4, 92, 89, 20, 9, 34, 203, 110, 4, 223, 7, 4, 99, 53, 20, 9, 34, + 203, 110, 4, 92, 4, 221, 211, 53, 20, 9, 34, 203, 110, 4, 92, 4, 221, + 211, 89, 20, 9, 34, 203, 110, 4, 92, 4, 92, 53, 20, 9, 34, 203, 110, 4, + 92, 4, 92, 89, 20, 9, 34, 238, 27, 4, 182, 4, 131, 217, 100, 53, 20, 9, + 34, 238, 27, 4, 221, 211, 4, 92, 53, 20, 9, 34, 238, 27, 4, 221, 211, 4, + 92, 89, 20, 9, 34, 199, 220, 4, 92, 4, 182, 53, 20, 9, 34, 199, 220, 4, + 92, 4, 182, 89, 20, 9, 34, 199, 220, 4, 92, 4, 92, 89, 20, 9, 34, 199, + 220, 4, 92, 4, 99, 53, 20, 9, 34, 251, 231, 4, 223, 7, 4, 92, 53, 20, 9, + 34, 251, 231, 4, 92, 4, 92, 53, 20, 9, 34, 251, 231, 4, 92, 4, 92, 89, + 20, 9, 34, 251, 231, 4, 92, 4, 131, 217, 100, 53, 20, 9, 34, 231, 87, 4, + 92, 4, 92, 53, 20, 9, 34, 231, 87, 4, 92, 4, 99, 53, 20, 9, 34, 231, 87, + 4, 92, 4, 131, 217, 100, 53, 20, 9, 34, 233, 47, 4, 221, 211, 4, 92, 53, + 20, 9, 34, 233, 47, 4, 221, 211, 4, 92, 89, 20, 9, 34, 208, 90, 4, 92, 4, + 182, 53, 20, 9, 34, 208, 90, 4, 92, 4, 92, 53, 20, 9, 34, 220, 36, 4, + 182, 4, 92, 53, 20, 9, 34, 220, 36, 4, 182, 4, 99, 53, 20, 9, 34, 220, + 36, 4, 182, 4, 131, 217, 100, 53, 20, 9, 34, 220, 36, 4, 223, 7, 4, 223, + 7, 89, 20, 9, 34, 220, 36, 4, 223, 7, 4, 223, 7, 53, 20, 9, 34, 220, 36, + 4, 221, 211, 4, 92, 53, 20, 9, 34, 220, 36, 4, 221, 211, 4, 92, 89, 20, + 9, 34, 220, 36, 4, 92, 4, 182, 53, 20, 9, 34, 220, 36, 4, 92, 4, 182, 89, + 20, 9, 34, 92, 4, 182, 4, 223, 7, 89, 20, 9, 34, 92, 4, 182, 4, 92, 89, + 20, 9, 34, 92, 4, 182, 4, 99, 53, 20, 9, 34, 92, 4, 223, 7, 4, 182, 89, + 20, 9, 34, 92, 4, 223, 7, 4, 92, 89, 20, 9, 34, 92, 4, 221, 211, 4, 223, + 7, 89, 20, 9, 34, 92, 4, 221, 211, 4, 92, 89, 20, 9, 34, 92, 4, 223, 7, + 4, 221, 211, 89, 20, 9, 34, 229, 211, 4, 92, 4, 223, 7, 89, 20, 9, 34, + 229, 211, 4, 92, 4, 92, 89, 20, 9, 34, 213, 25, 4, 182, 4, 92, 89, 20, 9, + 34, 213, 25, 4, 182, 4, 131, 217, 100, 53, 20, 9, 34, 213, 25, 4, 223, 7, + 4, 92, 53, 20, 9, 34, 213, 25, 4, 223, 7, 4, 92, 89, 20, 9, 34, 213, 25, + 4, 223, 7, 4, 131, 217, 100, 53, 20, 9, 34, 213, 25, 4, 92, 4, 99, 53, + 20, 9, 34, 213, 25, 4, 92, 4, 131, 217, 100, 53, 20, 9, 34, 99, 4, 92, 4, + 92, 53, 20, 9, 34, 99, 4, 92, 4, 92, 89, 20, 9, 34, 248, 246, 4, 221, + 211, 4, 99, 53, 20, 9, 34, 199, 115, 4, 223, 7, 4, 99, 53, 20, 9, 34, + 199, 115, 4, 223, 7, 4, 131, 217, 100, 53, 20, 9, 34, 199, 115, 4, 221, + 211, 4, 99, 53, 20, 9, 34, 199, 115, 4, 221, 211, 4, 131, 217, 100, 53, + 20, 9, 34, 199, 115, 4, 92, 4, 99, 53, 20, 9, 34, 199, 115, 4, 92, 4, + 131, 217, 100, 53, 20, 9, 34, 223, 7, 4, 92, 4, 99, 53, 20, 9, 34, 223, + 7, 4, 182, 4, 131, 217, 100, 53, 20, 9, 34, 223, 7, 4, 92, 4, 131, 217, + 100, 53, 20, 9, 34, 205, 47, 4, 221, 211, 4, 131, 217, 100, 53, 20, 9, + 34, 205, 193, 4, 182, 4, 99, 53, 20, 9, 34, 203, 110, 4, 182, 4, 99, 53, + 20, 9, 34, 238, 27, 4, 182, 4, 99, 53, 20, 9, 34, 220, 36, 4, 223, 7, 4, + 99, 53, 20, 9, 34, 220, 36, 4, 92, 4, 99, 53, 20, 9, 34, 99, 4, 182, 4, + 99, 53, 20, 9, 34, 99, 4, 223, 7, 4, 99, 53, 20, 9, 34, 99, 4, 92, 4, 99, + 53, 20, 9, 34, 92, 4, 92, 4, 99, 53, 20, 9, 34, 208, 90, 4, 92, 4, 99, + 53, 20, 9, 34, 213, 25, 4, 182, 4, 99, 53, 20, 9, 34, 208, 90, 4, 92, 4, + 182, 89, 20, 9, 34, 220, 36, 4, 182, 4, 92, 89, 20, 9, 34, 251, 231, 4, + 92, 4, 99, 53, 20, 9, 34, 222, 107, 4, 92, 4, 99, 53, 20, 9, 34, 213, 25, + 4, 223, 7, 4, 182, 89, 20, 9, 34, 92, 4, 221, 211, 4, 99, 53, 20, 9, 34, + 220, 36, 4, 223, 7, 4, 92, 89, 20, 9, 34, 222, 107, 4, 92, 4, 92, 53, 20, + 9, 34, 220, 36, 4, 223, 7, 4, 92, 53, 20, 9, 34, 213, 25, 4, 223, 7, 4, + 182, 53, 20, 9, 34, 223, 7, 4, 182, 4, 99, 53, 20, 9, 34, 182, 4, 223, 7, + 4, 99, 53, 20, 9, 34, 92, 4, 223, 7, 4, 99, 53, 20, 9, 34, 233, 47, 4, + 92, 4, 99, 53, 20, 9, 34, 248, 246, 4, 182, 4, 99, 53, 20, 9, 34, 222, + 107, 4, 92, 4, 92, 89, 20, 9, 34, 251, 231, 4, 223, 7, 4, 92, 89, 20, 9, + 34, 205, 193, 4, 92, 4, 92, 89, 20, 9, 34, 205, 47, 4, 221, 211, 4, 99, + 53, 20, 9, 34, 213, 25, 4, 223, 7, 4, 99, 53, 20, 9, 34, 205, 166, 251, + 194, 9, 34, 205, 163, 196, 40, 250, 220, 221, 33, 201, 64, 3, 76, 20, 9, + 34, 208, 86, 196, 40, 250, 220, 221, 33, 201, 64, 3, 76, 20, 9, 34, 251, + 171, 76, 20, 9, 34, 251, 213, 76, 20, 9, 34, 215, 235, 76, 20, 9, 34, + 205, 164, 76, 20, 9, 34, 207, 132, 76, 20, 9, 34, 251, 199, 76, 20, 9, + 34, 193, 153, 76, 20, 9, 34, 205, 163, 76, 20, 9, 34, 205, 161, 251, 199, + 193, 152, 9, 34, 223, 22, 206, 249, 56, 9, 34, 248, 151, 251, 31, 251, + 32, 9, 34, 200, 242, 193, 191, 199, 244, 9, 34, 250, 121, 193, 191, 223, + 23, 67, 205, 33, 67, 204, 178, 67, 204, 110, 67, 204, 99, 67, 204, 88, + 67, 204, 77, 67, 204, 66, 67, 204, 55, 67, 204, 44, 67, 205, 32, 67, 205, + 21, 67, 205, 10, 67, 204, 255, 67, 204, 244, 67, 204, 233, 67, 204, 222, + 208, 221, 232, 146, 40, 81, 242, 74, 208, 221, 232, 146, 40, 81, 154, + 242, 74, 208, 221, 232, 146, 40, 81, 154, 232, 80, 201, 63, 208, 221, + 232, 146, 40, 81, 242, 83, 208, 221, 232, 146, 40, 81, 204, 25, 208, 221, + 232, 146, 40, 81, 233, 216, 77, 208, 221, 232, 146, 40, 81, 208, 13, 77, + 208, 221, 232, 146, 40, 81, 45, 63, 219, 187, 248, 53, 208, 221, 232, + 146, 40, 81, 50, 63, 219, 187, 248, 49, 208, 221, 232, 146, 40, 81, 228, + 241, 234, 120, 33, 34, 45, 230, 70, 33, 34, 50, 230, 70, 33, 55, 198, + 153, 45, 230, 70, 33, 55, 198, 153, 50, 230, 70, 33, 217, 147, 45, 230, + 70, 33, 217, 147, 50, 230, 70, 33, 239, 44, 217, 146, 33, 34, 45, 132, + 60, 33, 34, 50, 132, 60, 33, 198, 153, 45, 132, 60, 33, 198, 153, 50, + 132, 60, 33, 217, 147, 45, 132, 60, 33, 217, 147, 50, 132, 60, 33, 239, + 44, 217, 147, 60, 33, 38, 198, 123, 45, 230, 70, 33, 38, 198, 123, 50, + 230, 70, 208, 221, 232, 146, 40, 81, 105, 75, 219, 236, 208, 221, 232, + 146, 40, 81, 234, 115, 237, 215, 208, 221, 232, 146, 40, 81, 234, 104, + 237, 215, 208, 221, 232, 146, 40, 81, 130, 219, 112, 208, 221, 232, 146, + 40, 81, 193, 135, 130, 219, 112, 208, 221, 232, 146, 40, 81, 45, 210, + 113, 208, 221, 232, 146, 40, 81, 50, 210, 113, 208, 221, 232, 146, 40, + 81, 45, 238, 171, 248, 53, 208, 221, 232, 146, 40, 81, 50, 238, 171, 248, + 53, 208, 221, 232, 146, 40, 81, 45, 198, 42, 203, 103, 248, 53, 208, 221, + 232, 146, 40, 81, 50, 198, 42, 203, 103, 248, 53, 208, 221, 232, 146, 40, + 81, 45, 62, 219, 187, 248, 53, 208, 221, 232, 146, 40, 81, 50, 62, 219, + 187, 248, 53, 208, 221, 232, 146, 40, 81, 45, 55, 251, 116, 248, 53, 208, + 221, 232, 146, 40, 81, 50, 55, 251, 116, 248, 53, 208, 221, 232, 146, 40, + 81, 45, 251, 116, 248, 53, 208, 221, 232, 146, 40, 81, 50, 251, 116, 248, + 53, 208, 221, 232, 146, 40, 81, 45, 239, 2, 248, 53, 208, 221, 232, 146, + 40, 81, 50, 239, 2, 248, 53, 208, 221, 232, 146, 40, 81, 45, 63, 239, 2, + 248, 53, 208, 221, 232, 146, 40, 81, 50, 63, 239, 2, 248, 53, 204, 0, + 236, 140, 63, 204, 0, 236, 140, 208, 221, 232, 146, 40, 81, 45, 51, 248, + 53, 208, 221, 232, 146, 40, 81, 50, 51, 248, 53, 237, 214, 210, 254, 247, + 18, 210, 254, 193, 135, 210, 254, 55, 193, 135, 210, 254, 237, 214, 130, + 219, 112, 247, 18, 130, 219, 112, 193, 135, 130, 219, 112, 2, 242, 74, 2, + 154, 242, 74, 2, 232, 80, 201, 63, 2, 204, 25, 2, 242, 83, 2, 208, 13, + 77, 2, 233, 216, 77, 2, 234, 115, 237, 215, 2, 45, 210, 113, 2, 50, 210, + 113, 2, 45, 238, 171, 248, 53, 2, 50, 238, 171, 248, 53, 2, 45, 198, 42, + 203, 103, 248, 53, 2, 50, 198, 42, 203, 103, 248, 53, 2, 31, 56, 2, 251, + 137, 2, 250, 193, 2, 108, 56, 2, 228, 87, 2, 219, 180, 56, 2, 230, 204, + 56, 2, 234, 43, 56, 2, 207, 19, 202, 23, 2, 236, 155, 56, 2, 210, 13, 56, + 2, 242, 72, 250, 182, 9, 233, 69, 76, 20, 9, 199, 169, 4, 233, 69, 58, 9, + 237, 244, 76, 20, 9, 199, 216, 232, 117, 9, 222, 51, 76, 20, 9, 233, 71, + 76, 20, 9, 233, 71, 216, 217, 20, 9, 237, 246, 76, 20, 9, 237, 246, 216, + 217, 20, 9, 222, 53, 76, 20, 9, 222, 53, 216, 217, 20, 9, 203, 156, 76, + 20, 9, 203, 156, 216, 217, 20, 9, 200, 207, 76, 20, 9, 200, 207, 216, + 217, 20, 9, 1, 230, 58, 76, 20, 9, 1, 131, 4, 217, 142, 93, 76, 20, 9, 1, + 131, 4, 217, 142, 93, 53, 20, 9, 1, 131, 4, 230, 58, 93, 76, 20, 9, 1, + 131, 4, 230, 58, 93, 53, 20, 9, 1, 193, 134, 4, 230, 58, 93, 76, 20, 9, + 1, 193, 134, 4, 230, 58, 93, 53, 20, 9, 1, 131, 4, 230, 58, 248, 233, 76, + 20, 9, 1, 131, 4, 230, 58, 248, 233, 53, 20, 9, 1, 99, 4, 230, 58, 93, + 76, 20, 9, 1, 99, 4, 230, 58, 93, 53, 20, 9, 1, 99, 4, 230, 58, 93, 89, + 20, 9, 1, 99, 4, 230, 58, 93, 216, 217, 20, 9, 1, 131, 76, 20, 9, 1, 131, + 53, 20, 9, 1, 248, 246, 76, 20, 9, 1, 248, 246, 53, 20, 9, 1, 248, 246, + 89, 20, 9, 1, 248, 246, 216, 217, 20, 9, 1, 199, 115, 217, 63, 76, 20, 9, + 1, 199, 115, 217, 63, 53, 20, 9, 1, 199, 115, 76, 20, 9, 1, 199, 115, 53, + 20, 9, 1, 199, 115, 89, 20, 9, 1, 199, 115, 216, 217, 20, 9, 1, 199, 30, + 76, 20, 9, 1, 199, 30, 53, 20, 9, 1, 199, 30, 89, 20, 9, 1, 199, 30, 216, + 217, 20, 9, 1, 223, 7, 76, 20, 9, 1, 223, 7, 53, 20, 9, 1, 223, 7, 89, + 20, 9, 1, 223, 7, 216, 217, 20, 9, 1, 182, 76, 20, 9, 1, 182, 53, 20, 9, + 1, 182, 89, 20, 9, 1, 182, 216, 217, 20, 9, 1, 221, 211, 76, 20, 9, 1, + 221, 211, 53, 20, 9, 1, 221, 211, 89, 20, 9, 1, 221, 211, 216, 217, 20, + 9, 1, 238, 4, 76, 20, 9, 1, 238, 4, 53, 20, 9, 1, 199, 42, 76, 20, 9, 1, + 199, 42, 53, 20, 9, 1, 207, 72, 76, 20, 9, 1, 207, 72, 53, 20, 9, 1, 191, + 114, 76, 20, 9, 1, 191, 114, 53, 20, 9, 1, 205, 47, 76, 20, 9, 1, 205, + 47, 53, 20, 9, 1, 205, 47, 89, 20, 9, 1, 205, 47, 216, 217, 20, 9, 1, + 203, 110, 76, 20, 9, 1, 203, 110, 53, 20, 9, 1, 203, 110, 89, 20, 9, 1, + 203, 110, 216, 217, 20, 9, 1, 205, 193, 76, 20, 9, 1, 205, 193, 53, 20, + 9, 1, 205, 193, 89, 20, 9, 1, 205, 193, 216, 217, 20, 9, 1, 238, 27, 76, + 20, 9, 1, 238, 27, 53, 20, 9, 1, 238, 27, 89, 20, 9, 1, 238, 27, 216, + 217, 20, 9, 1, 199, 220, 76, 20, 9, 1, 199, 220, 53, 20, 9, 1, 199, 220, + 89, 20, 9, 1, 199, 220, 216, 217, 20, 9, 1, 191, 117, 76, 20, 9, 1, 191, + 117, 53, 20, 9, 1, 191, 117, 89, 20, 9, 1, 191, 117, 216, 217, 20, 9, 1, + 251, 231, 76, 20, 9, 1, 251, 231, 53, 20, 9, 1, 251, 231, 89, 20, 9, 1, + 251, 231, 216, 217, 20, 9, 1, 231, 87, 76, 20, 9, 1, 231, 87, 53, 20, 9, + 1, 231, 87, 89, 20, 9, 1, 231, 87, 216, 217, 20, 9, 1, 233, 47, 76, 20, + 9, 1, 233, 47, 53, 20, 9, 1, 233, 47, 89, 20, 9, 1, 233, 47, 216, 217, + 20, 9, 1, 208, 90, 76, 20, 9, 1, 208, 90, 53, 20, 9, 1, 208, 90, 89, 20, + 9, 1, 208, 90, 216, 217, 20, 9, 1, 222, 107, 76, 20, 9, 1, 222, 107, 53, + 20, 9, 1, 222, 107, 89, 20, 9, 1, 222, 107, 216, 217, 20, 9, 1, 220, 36, + 76, 20, 9, 1, 220, 36, 53, 20, 9, 1, 220, 36, 89, 20, 9, 1, 220, 36, 216, + 217, 20, 9, 1, 92, 76, 20, 9, 1, 92, 53, 20, 9, 1, 92, 89, 20, 9, 1, 92, + 216, 217, 20, 9, 1, 213, 25, 76, 20, 9, 1, 213, 25, 53, 20, 9, 1, 213, + 25, 89, 20, 9, 1, 213, 25, 216, 217, 20, 9, 1, 229, 211, 76, 20, 9, 1, + 229, 211, 53, 20, 9, 1, 229, 211, 89, 20, 9, 1, 229, 211, 216, 217, 20, + 9, 1, 193, 134, 76, 20, 9, 1, 193, 134, 53, 20, 9, 1, 131, 217, 100, 76, + 20, 9, 1, 131, 217, 100, 53, 20, 9, 1, 99, 76, 20, 9, 1, 99, 53, 20, 9, + 1, 99, 89, 20, 9, 1, 99, 216, 217, 20, 9, 34, 220, 36, 4, 131, 4, 217, + 142, 93, 76, 20, 9, 34, 220, 36, 4, 131, 4, 217, 142, 93, 53, 20, 9, 34, + 220, 36, 4, 131, 4, 230, 58, 93, 76, 20, 9, 34, 220, 36, 4, 131, 4, 230, + 58, 93, 53, 20, 9, 34, 220, 36, 4, 131, 4, 230, 58, 248, 233, 76, 20, 9, + 34, 220, 36, 4, 131, 4, 230, 58, 248, 233, 53, 20, 9, 34, 220, 36, 4, + 131, 76, 20, 9, 34, 220, 36, 4, 131, 53, 20, 191, 78, 193, 75, 213, 37, + 201, 247, 232, 78, 233, 216, 77, 232, 78, 207, 252, 77, 232, 78, 31, 56, + 232, 78, 236, 155, 56, 232, 78, 210, 13, 56, 232, 78, 251, 137, 232, 78, + 251, 49, 232, 78, 45, 210, 113, 232, 78, 50, 210, 113, 232, 78, 250, 193, + 232, 78, 108, 56, 232, 78, 242, 74, 232, 78, 228, 87, 232, 78, 232, 80, + 201, 63, 232, 78, 202, 23, 232, 78, 17, 191, 77, 232, 78, 17, 107, 232, + 78, 17, 109, 232, 78, 17, 138, 232, 78, 17, 134, 232, 78, 17, 149, 232, + 78, 17, 169, 232, 78, 17, 175, 232, 78, 17, 171, 232, 78, 17, 178, 232, + 78, 242, 83, 232, 78, 204, 25, 232, 78, 219, 180, 56, 232, 78, 234, 43, + 56, 232, 78, 230, 204, 56, 232, 78, 208, 13, 77, 232, 78, 242, 72, 250, + 182, 232, 78, 8, 6, 1, 65, 232, 78, 8, 6, 1, 250, 120, 232, 78, 8, 6, 1, + 247, 193, 232, 78, 8, 6, 1, 238, 127, 232, 78, 8, 6, 1, 71, 232, 78, 8, + 6, 1, 233, 175, 232, 78, 8, 6, 1, 232, 51, 232, 78, 8, 6, 1, 230, 116, + 232, 78, 8, 6, 1, 68, 232, 78, 8, 6, 1, 223, 35, 232, 78, 8, 6, 1, 222, + 152, 232, 78, 8, 6, 1, 172, 232, 78, 8, 6, 1, 218, 168, 232, 78, 8, 6, 1, + 215, 61, 232, 78, 8, 6, 1, 74, 232, 78, 8, 6, 1, 210, 236, 232, 78, 8, 6, + 1, 208, 104, 232, 78, 8, 6, 1, 146, 232, 78, 8, 6, 1, 206, 8, 232, 78, 8, + 6, 1, 200, 43, 232, 78, 8, 6, 1, 66, 232, 78, 8, 6, 1, 196, 12, 232, 78, + 8, 6, 1, 193, 224, 232, 78, 8, 6, 1, 192, 235, 232, 78, 8, 6, 1, 192, + 159, 232, 78, 8, 6, 1, 191, 166, 232, 78, 45, 51, 248, 53, 232, 78, 207, + 19, 202, 23, 232, 78, 50, 51, 248, 53, 232, 78, 243, 2, 252, 60, 232, 78, + 130, 219, 112, 232, 78, 230, 211, 252, 60, 232, 78, 8, 2, 1, 65, 232, 78, + 8, 2, 1, 250, 120, 232, 78, 8, 2, 1, 247, 193, 232, 78, 8, 2, 1, 238, + 127, 232, 78, 8, 2, 1, 71, 232, 78, 8, 2, 1, 233, 175, 232, 78, 8, 2, 1, + 232, 51, 232, 78, 8, 2, 1, 230, 116, 232, 78, 8, 2, 1, 68, 232, 78, 8, 2, + 1, 223, 35, 232, 78, 8, 2, 1, 222, 152, 232, 78, 8, 2, 1, 172, 232, 78, + 8, 2, 1, 218, 168, 232, 78, 8, 2, 1, 215, 61, 232, 78, 8, 2, 1, 74, 232, + 78, 8, 2, 1, 210, 236, 232, 78, 8, 2, 1, 208, 104, 232, 78, 8, 2, 1, 146, + 232, 78, 8, 2, 1, 206, 8, 232, 78, 8, 2, 1, 200, 43, 232, 78, 8, 2, 1, + 66, 232, 78, 8, 2, 1, 196, 12, 232, 78, 8, 2, 1, 193, 224, 232, 78, 8, 2, + 1, 192, 235, 232, 78, 8, 2, 1, 192, 159, 232, 78, 8, 2, 1, 191, 166, 232, + 78, 45, 238, 171, 248, 53, 232, 78, 81, 219, 112, 232, 78, 50, 238, 171, + 248, 53, 232, 78, 198, 152, 232, 78, 45, 63, 210, 113, 232, 78, 50, 63, + 210, 113, 150, 154, 232, 80, 201, 63, 150, 45, 239, 2, 248, 53, 150, 50, + 239, 2, 248, 53, 150, 154, 242, 74, 150, 72, 82, 236, 140, 150, 72, 1, + 193, 48, 150, 72, 1, 2, 65, 150, 72, 1, 2, 68, 150, 72, 1, 2, 66, 150, + 72, 1, 2, 71, 150, 72, 1, 2, 74, 150, 72, 1, 2, 170, 150, 72, 1, 2, 191, + 225, 150, 72, 1, 2, 192, 12, 150, 72, 1, 2, 197, 94, 150, 222, 48, 208, + 191, 202, 5, 77, 150, 72, 1, 65, 150, 72, 1, 68, 150, 72, 1, 66, 150, 72, + 1, 71, 150, 72, 1, 74, 150, 72, 1, 155, 150, 72, 1, 221, 166, 150, 72, 1, + 220, 232, 150, 72, 1, 222, 22, 150, 72, 1, 221, 67, 150, 72, 1, 188, 150, + 72, 1, 202, 222, 150, 72, 1, 201, 4, 150, 72, 1, 205, 68, 150, 72, 1, + 202, 46, 150, 72, 1, 190, 190, 150, 72, 1, 198, 193, 150, 72, 1, 197, 94, + 150, 72, 1, 199, 145, 150, 72, 1, 159, 150, 72, 1, 180, 150, 72, 1, 213, + 219, 150, 72, 1, 212, 178, 150, 72, 1, 214, 121, 150, 72, 1, 213, 43, + 150, 72, 1, 140, 150, 72, 1, 229, 158, 150, 72, 1, 228, 159, 150, 72, 1, + 229, 245, 150, 72, 1, 229, 23, 150, 72, 1, 174, 150, 72, 1, 216, 100, + 150, 72, 1, 215, 155, 150, 72, 1, 216, 232, 150, 72, 1, 216, 12, 150, 72, + 1, 170, 150, 72, 1, 191, 225, 150, 72, 1, 192, 12, 150, 72, 1, 165, 150, + 72, 1, 207, 1, 150, 72, 1, 206, 68, 150, 72, 1, 207, 113, 150, 72, 1, + 206, 162, 150, 72, 1, 193, 190, 150, 72, 1, 215, 61, 150, 72, 195, 20, + 202, 5, 77, 150, 72, 204, 30, 202, 5, 77, 150, 30, 233, 3, 150, 30, 1, + 221, 113, 150, 30, 1, 201, 167, 150, 30, 1, 221, 106, 150, 30, 1, 213, + 204, 150, 30, 1, 213, 202, 150, 30, 1, 213, 201, 150, 30, 1, 198, 168, + 150, 30, 1, 201, 156, 150, 30, 1, 206, 239, 150, 30, 1, 206, 234, 150, + 30, 1, 206, 231, 150, 30, 1, 206, 224, 150, 30, 1, 206, 219, 150, 30, 1, + 206, 214, 150, 30, 1, 206, 225, 150, 30, 1, 206, 237, 150, 30, 1, 216, + 77, 150, 30, 1, 209, 169, 150, 30, 1, 201, 164, 150, 30, 1, 209, 158, + 150, 30, 1, 202, 160, 150, 30, 1, 201, 161, 150, 30, 1, 223, 222, 150, + 30, 1, 243, 24, 150, 30, 1, 201, 171, 150, 30, 1, 243, 91, 150, 30, 1, + 221, 188, 150, 30, 1, 199, 7, 150, 30, 1, 209, 209, 150, 30, 1, 229, 142, + 150, 30, 1, 65, 150, 30, 1, 252, 25, 150, 30, 1, 170, 150, 30, 1, 192, + 129, 150, 30, 1, 234, 65, 150, 30, 1, 71, 150, 30, 1, 192, 67, 150, 30, + 1, 192, 80, 150, 30, 1, 74, 150, 30, 1, 193, 190, 150, 30, 1, 193, 176, + 150, 30, 1, 211, 151, 150, 30, 1, 192, 12, 150, 30, 1, 66, 150, 30, 1, + 193, 107, 150, 30, 1, 193, 125, 150, 30, 1, 193, 86, 150, 30, 1, 191, + 225, 150, 30, 1, 233, 242, 150, 30, 1, 192, 33, 150, 30, 1, 68, 232, 78, + 247, 24, 56, 232, 78, 209, 8, 56, 232, 78, 213, 12, 56, 232, 78, 217, + 146, 232, 78, 248, 22, 164, 232, 78, 192, 71, 56, 232, 78, 193, 31, 56, + 150, 232, 141, 156, 195, 135, 150, 118, 57, 150, 196, 66, 57, 150, 96, + 57, 150, 235, 119, 57, 150, 62, 201, 190, 150, 63, 243, 10, 223, 106, + 251, 96, 251, 127, 223, 106, 251, 96, 204, 10, 223, 106, 251, 96, 199, + 80, 211, 175, 207, 43, 246, 239, 207, 43, 246, 239, 32, 78, 5, 250, 104, + 65, 32, 78, 5, 250, 73, 71, 32, 78, 5, 250, 82, 68, 32, 78, 5, 250, 50, + 74, 32, 78, 5, 250, 100, 66, 32, 78, 5, 250, 119, 238, 32, 32, 78, 5, + 250, 66, 237, 146, 32, 78, 5, 250, 106, 237, 44, 32, 78, 5, 250, 96, 236, + 174, 32, 78, 5, 250, 60, 235, 89, 32, 78, 5, 250, 54, 223, 32, 32, 78, 5, + 250, 65, 223, 10, 32, 78, 5, 250, 75, 222, 201, 32, 78, 5, 250, 46, 222, + 182, 32, 78, 5, 250, 34, 155, 32, 78, 5, 250, 67, 222, 22, 32, 78, 5, + 250, 44, 221, 166, 32, 78, 5, 250, 41, 221, 67, 32, 78, 5, 250, 30, 220, + 232, 32, 78, 5, 250, 31, 174, 32, 78, 5, 250, 97, 216, 232, 32, 78, 5, + 250, 38, 216, 100, 32, 78, 5, 250, 95, 216, 12, 32, 78, 5, 250, 87, 215, + 155, 32, 78, 5, 250, 108, 180, 32, 78, 5, 250, 86, 214, 121, 32, 78, 5, + 250, 80, 213, 219, 32, 78, 5, 250, 59, 213, 43, 32, 78, 5, 250, 56, 212, + 178, 32, 78, 5, 250, 115, 168, 32, 78, 5, 250, 39, 210, 63, 32, 78, 5, + 250, 72, 209, 185, 32, 78, 5, 250, 99, 209, 73, 32, 78, 5, 250, 61, 208, + 165, 32, 78, 5, 250, 94, 208, 96, 32, 78, 5, 250, 33, 208, 75, 32, 78, 5, + 250, 89, 208, 57, 32, 78, 5, 250, 78, 208, 45, 32, 78, 5, 250, 51, 165, + 32, 78, 5, 250, 83, 207, 113, 32, 78, 5, 250, 58, 207, 1, 32, 78, 5, 250, + 117, 206, 162, 32, 78, 5, 250, 84, 206, 68, 32, 78, 5, 250, 79, 188, 32, + 78, 5, 250, 102, 205, 68, 32, 78, 5, 250, 70, 202, 222, 32, 78, 5, 250, + 98, 202, 46, 32, 78, 5, 250, 53, 201, 4, 32, 78, 5, 250, 52, 190, 190, + 32, 78, 5, 250, 113, 199, 145, 32, 78, 5, 250, 74, 198, 193, 32, 78, 5, + 250, 111, 159, 32, 78, 5, 250, 42, 197, 94, 32, 78, 5, 250, 57, 193, 190, + 32, 78, 5, 250, 36, 193, 125, 32, 78, 5, 250, 71, 193, 86, 32, 78, 5, + 250, 69, 193, 48, 32, 78, 5, 250, 93, 191, 123, 32, 78, 5, 250, 37, 191, + 87, 32, 78, 5, 250, 90, 191, 7, 32, 78, 5, 250, 85, 254, 215, 32, 78, 5, + 250, 68, 254, 103, 32, 78, 5, 250, 27, 250, 163, 32, 78, 5, 250, 40, 235, + 45, 32, 78, 5, 250, 23, 235, 44, 32, 78, 5, 250, 63, 212, 110, 32, 78, 5, + 250, 81, 208, 163, 32, 78, 5, 250, 49, 208, 167, 32, 78, 5, 250, 35, 207, + 180, 32, 78, 5, 250, 77, 207, 179, 32, 78, 5, 250, 43, 206, 155, 32, 78, + 5, 250, 45, 199, 246, 32, 78, 5, 250, 25, 197, 41, 32, 78, 5, 250, 22, + 109, 32, 78, 16, 250, 92, 32, 78, 16, 250, 91, 32, 78, 16, 250, 88, 32, + 78, 16, 250, 76, 32, 78, 16, 250, 64, 32, 78, 16, 250, 62, 32, 78, 16, + 250, 55, 32, 78, 16, 250, 48, 32, 78, 16, 250, 47, 32, 78, 16, 250, 32, + 32, 78, 16, 250, 29, 32, 78, 16, 250, 28, 32, 78, 16, 250, 26, 32, 78, + 16, 250, 24, 32, 78, 157, 250, 21, 217, 90, 32, 78, 157, 250, 20, 193, + 35, 32, 78, 157, 250, 19, 237, 128, 32, 78, 157, 250, 18, 234, 40, 32, + 78, 157, 250, 17, 217, 56, 32, 78, 157, 250, 16, 201, 110, 32, 78, 157, + 250, 15, 233, 223, 32, 78, 157, 250, 14, 207, 142, 32, 78, 157, 250, 13, + 203, 112, 32, 78, 157, 250, 12, 229, 237, 32, 78, 157, 250, 11, 201, 255, + 32, 78, 157, 250, 10, 248, 109, 32, 78, 157, 250, 9, 238, 239, 32, 78, + 157, 250, 8, 247, 250, 32, 78, 157, 250, 7, 193, 95, 32, 78, 157, 250, 6, + 249, 84, 32, 78, 157, 250, 5, 211, 115, 32, 78, 157, 250, 4, 201, 223, + 32, 78, 157, 250, 3, 238, 136, 32, 78, 215, 221, 250, 2, 222, 74, 32, 78, + 215, 221, 250, 1, 222, 85, 32, 78, 157, 250, 0, 211, 131, 32, 78, 157, + 249, 255, 193, 62, 32, 78, 157, 249, 254, 32, 78, 215, 221, 249, 253, + 251, 7, 32, 78, 215, 221, 249, 252, 216, 178, 32, 78, 157, 249, 251, 248, + 21, 32, 78, 157, 249, 250, 230, 250, 32, 78, 157, 249, 249, 32, 78, 157, + 249, 248, 193, 26, 32, 78, 157, 249, 247, 32, 78, 157, 249, 246, 32, 78, + 157, 249, 245, 228, 187, 32, 78, 157, 249, 244, 32, 78, 157, 249, 243, + 32, 78, 157, 249, 242, 32, 78, 215, 221, 249, 240, 197, 56, 32, 78, 157, + 249, 239, 32, 78, 157, 249, 238, 32, 78, 157, 249, 237, 242, 213, 32, 78, + 157, 249, 236, 32, 78, 157, 249, 235, 32, 78, 157, 249, 234, 231, 196, + 32, 78, 157, 249, 233, 250, 248, 32, 78, 157, 249, 232, 32, 78, 157, 249, + 231, 32, 78, 157, 249, 230, 32, 78, 157, 249, 229, 32, 78, 157, 249, 228, + 32, 78, 157, 249, 227, 32, 78, 157, 249, 226, 32, 78, 157, 249, 225, 32, + 78, 157, 249, 224, 32, 78, 157, 249, 223, 215, 213, 32, 78, 157, 249, + 222, 32, 78, 157, 249, 221, 197, 254, 32, 78, 157, 249, 220, 32, 78, 157, + 249, 219, 32, 78, 157, 249, 218, 32, 78, 157, 249, 217, 32, 78, 157, 249, + 216, 32, 78, 157, 249, 215, 32, 78, 157, 249, 214, 32, 78, 157, 249, 213, + 32, 78, 157, 249, 212, 32, 78, 157, 249, 211, 32, 78, 157, 249, 210, 32, + 78, 157, 249, 209, 229, 200, 32, 78, 157, 249, 188, 232, 155, 32, 78, + 157, 249, 185, 249, 59, 32, 78, 157, 249, 180, 201, 232, 32, 78, 157, + 249, 179, 57, 32, 78, 157, 249, 178, 32, 78, 157, 249, 177, 200, 131, 32, + 78, 157, 249, 176, 32, 78, 157, 249, 175, 32, 78, 157, 249, 174, 193, 90, + 243, 138, 32, 78, 157, 249, 173, 243, 138, 32, 78, 157, 249, 172, 243, + 139, 232, 113, 32, 78, 157, 249, 171, 193, 93, 32, 78, 157, 249, 170, 32, + 78, 157, 249, 169, 32, 78, 215, 221, 249, 168, 236, 235, 32, 78, 157, + 249, 167, 32, 78, 157, 249, 166, 32, 78, 157, 249, 164, 32, 78, 157, 249, + 163, 32, 78, 157, 249, 162, 32, 78, 157, 249, 161, 237, 218, 32, 78, 157, + 249, 160, 32, 78, 157, 249, 159, 32, 78, 157, 249, 158, 32, 78, 157, 249, + 157, 32, 78, 157, 249, 156, 32, 78, 157, 195, 82, 249, 241, 32, 78, 157, + 195, 82, 249, 208, 32, 78, 157, 195, 82, 249, 207, 32, 78, 157, 195, 82, + 249, 206, 32, 78, 157, 195, 82, 249, 205, 32, 78, 157, 195, 82, 249, 204, + 32, 78, 157, 195, 82, 249, 203, 32, 78, 157, 195, 82, 249, 202, 32, 78, + 157, 195, 82, 249, 201, 32, 78, 157, 195, 82, 249, 200, 32, 78, 157, 195, + 82, 249, 199, 32, 78, 157, 195, 82, 249, 198, 32, 78, 157, 195, 82, 249, + 197, 32, 78, 157, 195, 82, 249, 196, 32, 78, 157, 195, 82, 249, 195, 32, + 78, 157, 195, 82, 249, 194, 32, 78, 157, 195, 82, 249, 193, 32, 78, 157, + 195, 82, 249, 192, 32, 78, 157, 195, 82, 249, 191, 32, 78, 157, 195, 82, + 249, 190, 32, 78, 157, 195, 82, 249, 189, 32, 78, 157, 195, 82, 249, 187, + 32, 78, 157, 195, 82, 249, 186, 32, 78, 157, 195, 82, 249, 184, 32, 78, + 157, 195, 82, 249, 183, 32, 78, 157, 195, 82, 249, 182, 32, 78, 157, 195, + 82, 249, 181, 32, 78, 157, 195, 82, 249, 165, 32, 78, 157, 195, 82, 249, + 155, 252, 18, 193, 23, 204, 11, 219, 112, 252, 18, 193, 23, 204, 11, 236, + 140, 252, 18, 243, 126, 77, 252, 18, 31, 107, 252, 18, 31, 109, 252, 18, + 31, 138, 252, 18, 31, 134, 252, 18, 31, 149, 252, 18, 31, 169, 252, 18, + 31, 175, 252, 18, 31, 171, 252, 18, 31, 178, 252, 18, 31, 199, 95, 252, + 18, 31, 197, 32, 252, 18, 31, 198, 249, 252, 18, 31, 232, 135, 252, 18, + 31, 233, 15, 252, 18, 31, 202, 120, 252, 18, 31, 203, 241, 252, 18, 31, + 234, 153, 252, 18, 31, 213, 169, 252, 18, 31, 91, 228, 140, 252, 18, 31, + 105, 228, 140, 252, 18, 31, 115, 228, 140, 252, 18, 31, 232, 128, 228, + 140, 252, 18, 31, 232, 226, 228, 140, 252, 18, 31, 202, 136, 228, 140, + 252, 18, 31, 203, 247, 228, 140, 252, 18, 31, 234, 164, 228, 140, 252, + 18, 31, 213, 175, 228, 140, 252, 18, 31, 91, 189, 252, 18, 31, 105, 189, + 252, 18, 31, 115, 189, 252, 18, 31, 232, 128, 189, 252, 18, 31, 232, 226, + 189, 252, 18, 31, 202, 136, 189, 252, 18, 31, 203, 247, 189, 252, 18, 31, + 234, 164, 189, 252, 18, 31, 213, 175, 189, 252, 18, 31, 199, 96, 189, + 252, 18, 31, 197, 33, 189, 252, 18, 31, 198, 250, 189, 252, 18, 31, 232, + 136, 189, 252, 18, 31, 233, 16, 189, 252, 18, 31, 202, 121, 189, 252, 18, + 31, 203, 242, 189, 252, 18, 31, 234, 154, 189, 252, 18, 31, 213, 170, + 189, 252, 18, 193, 110, 249, 75, 196, 90, 252, 18, 193, 110, 232, 238, + 200, 224, 252, 18, 193, 110, 205, 57, 200, 224, 252, 18, 193, 110, 199, + 1, 200, 224, 252, 18, 193, 110, 232, 121, 200, 224, 252, 18, 235, 92, + 216, 228, 232, 238, 200, 224, 252, 18, 219, 93, 216, 228, 232, 238, 200, + 224, 252, 18, 216, 228, 205, 57, 200, 224, 252, 18, 216, 228, 199, 1, + 200, 224, 35, 252, 50, 250, 165, 91, 208, 22, 35, 252, 50, 250, 165, 91, + 230, 70, 35, 252, 50, 250, 165, 91, 235, 115, 35, 252, 50, 250, 165, 149, + 35, 252, 50, 250, 165, 233, 15, 35, 252, 50, 250, 165, 232, 226, 228, + 140, 35, 252, 50, 250, 165, 232, 226, 189, 35, 252, 50, 250, 165, 233, + 16, 189, 35, 252, 50, 250, 165, 232, 226, 199, 203, 35, 252, 50, 250, + 165, 199, 96, 199, 203, 35, 252, 50, 250, 165, 233, 16, 199, 203, 35, + 252, 50, 250, 165, 91, 228, 141, 199, 203, 35, 252, 50, 250, 165, 232, + 226, 228, 141, 199, 203, 35, 252, 50, 250, 165, 91, 198, 230, 199, 203, + 35, 252, 50, 250, 165, 232, 226, 198, 230, 199, 203, 35, 252, 50, 250, + 165, 232, 226, 201, 94, 35, 252, 50, 250, 165, 199, 96, 201, 94, 35, 252, + 50, 250, 165, 233, 16, 201, 94, 35, 252, 50, 250, 165, 91, 228, 141, 201, + 94, 35, 252, 50, 250, 165, 232, 226, 228, 141, 201, 94, 35, 252, 50, 250, + 165, 91, 198, 230, 201, 94, 35, 252, 50, 250, 165, 199, 96, 198, 230, + 201, 94, 35, 252, 50, 250, 165, 233, 16, 198, 230, 201, 94, 35, 252, 50, + 250, 165, 199, 96, 216, 15, 35, 252, 50, 229, 194, 91, 209, 92, 35, 252, + 50, 199, 17, 107, 35, 252, 50, 229, 190, 107, 35, 252, 50, 234, 51, 109, + 35, 252, 50, 199, 17, 109, 35, 252, 50, 238, 132, 105, 235, 114, 35, 252, + 50, 234, 51, 105, 235, 114, 35, 252, 50, 197, 216, 149, 35, 252, 50, 197, + 216, 199, 95, 35, 252, 50, 197, 216, 199, 96, 251, 157, 20, 35, 252, 50, + 229, 190, 199, 95, 35, 252, 50, 216, 167, 199, 95, 35, 252, 50, 199, 17, + 199, 95, 35, 252, 50, 199, 17, 198, 249, 35, 252, 50, 197, 216, 233, 15, + 35, 252, 50, 197, 216, 233, 16, 251, 157, 20, 35, 252, 50, 229, 190, 233, + 15, 35, 252, 50, 199, 17, 233, 15, 35, 252, 50, 199, 17, 91, 228, 140, + 35, 252, 50, 199, 17, 115, 228, 140, 35, 252, 50, 234, 51, 232, 226, 228, + 140, 35, 252, 50, 197, 216, 232, 226, 228, 140, 35, 252, 50, 199, 17, + 232, 226, 228, 140, 35, 252, 50, 247, 82, 232, 226, 228, 140, 35, 252, + 50, 214, 199, 232, 226, 228, 140, 35, 252, 50, 199, 17, 91, 189, 35, 252, + 50, 199, 17, 232, 226, 189, 35, 252, 50, 237, 109, 232, 226, 216, 15, 35, + 252, 50, 201, 47, 233, 16, 216, 15, 35, 91, 132, 56, 35, 91, 132, 3, 251, + 157, 20, 35, 105, 198, 254, 56, 35, 115, 208, 21, 56, 35, 192, 78, 56, + 35, 199, 204, 56, 35, 235, 116, 56, 35, 211, 170, 56, 35, 105, 211, 169, + 56, 35, 115, 211, 169, 56, 35, 232, 128, 211, 169, 56, 35, 232, 226, 211, + 169, 56, 35, 216, 161, 56, 35, 220, 151, 249, 75, 56, 35, 219, 85, 56, + 35, 211, 16, 56, 35, 192, 211, 56, 35, 250, 226, 56, 35, 250, 243, 56, + 35, 230, 220, 56, 35, 197, 171, 249, 75, 56, 35, 191, 78, 56, 35, 91, + 208, 23, 56, 35, 202, 162, 56, 35, 223, 143, 56, 213, 32, 56, 206, 136, + 203, 237, 56, 206, 136, 196, 106, 56, 206, 136, 204, 17, 56, 206, 136, + 203, 175, 56, 206, 136, 236, 250, 203, 175, 56, 206, 136, 202, 186, 56, + 206, 136, 237, 104, 56, 206, 136, 208, 5, 56, 206, 136, 203, 254, 56, + 206, 136, 235, 67, 56, 206, 136, 250, 220, 56, 206, 136, 247, 17, 56, + 250, 211, 113, 35, 16, 199, 167, 207, 3, 209, 223, 236, 227, 3, 210, 51, + 209, 223, 236, 227, 3, 209, 84, 229, 235, 209, 223, 236, 227, 3, 199, + 170, 229, 235, 209, 223, 236, 227, 3, 247, 105, 209, 223, 236, 227, 3, + 243, 86, 209, 223, 236, 227, 3, 193, 35, 209, 223, 236, 227, 3, 229, 200, + 209, 223, 236, 227, 3, 231, 188, 209, 223, 236, 227, 3, 198, 184, 209, + 223, 236, 227, 3, 57, 209, 223, 236, 227, 3, 248, 69, 209, 223, 236, 227, + 3, 203, 78, 209, 223, 236, 227, 3, 242, 206, 209, 223, 236, 227, 3, 217, + 89, 209, 223, 236, 227, 3, 217, 26, 209, 223, 236, 227, 3, 205, 108, 209, + 223, 236, 227, 3, 219, 141, 209, 223, 236, 227, 3, 248, 92, 209, 223, + 236, 227, 3, 247, 89, 209, 101, 209, 223, 236, 227, 3, 236, 156, 209, + 223, 236, 227, 3, 242, 80, 209, 223, 236, 227, 3, 202, 83, 209, 223, 236, + 227, 3, 242, 81, 209, 223, 236, 227, 3, 248, 254, 209, 223, 236, 227, 3, + 203, 65, 209, 223, 236, 227, 3, 228, 187, 209, 223, 236, 227, 3, 229, + 148, 209, 223, 236, 227, 3, 247, 245, 219, 212, 209, 223, 236, 227, 3, + 247, 78, 209, 223, 236, 227, 3, 207, 142, 209, 223, 236, 227, 3, 234, + 214, 209, 223, 236, 227, 3, 235, 124, 209, 223, 236, 227, 3, 197, 72, + 209, 223, 236, 227, 3, 249, 1, 209, 223, 236, 227, 3, 209, 102, 197, 254, + 209, 223, 236, 227, 3, 195, 47, 209, 223, 236, 227, 3, 210, 132, 209, + 223, 236, 227, 3, 206, 125, 209, 223, 236, 227, 3, 219, 125, 209, 223, + 236, 227, 3, 210, 248, 249, 146, 209, 223, 236, 227, 3, 232, 182, 209, + 223, 236, 227, 3, 230, 212, 209, 223, 236, 227, 3, 201, 50, 209, 223, + 236, 227, 3, 2, 250, 132, 209, 223, 236, 227, 3, 193, 135, 249, 97, 209, + 223, 236, 227, 3, 33, 211, 172, 106, 218, 181, 1, 65, 218, 181, 1, 71, + 218, 181, 1, 250, 120, 218, 181, 1, 248, 204, 218, 181, 1, 232, 51, 218, + 181, 1, 238, 127, 218, 181, 1, 68, 218, 181, 1, 193, 224, 218, 181, 1, + 191, 166, 218, 181, 1, 199, 51, 218, 181, 1, 223, 35, 218, 181, 1, 222, + 152, 218, 181, 1, 208, 104, 218, 181, 1, 172, 218, 181, 1, 218, 168, 218, + 181, 1, 215, 61, 218, 181, 1, 216, 17, 218, 181, 1, 213, 80, 218, 181, 1, + 66, 218, 181, 1, 210, 236, 218, 181, 1, 221, 102, 218, 181, 1, 146, 218, + 181, 1, 206, 8, 218, 181, 1, 200, 43, 218, 181, 1, 197, 135, 218, 181, 1, + 251, 132, 218, 181, 1, 234, 103, 218, 181, 1, 230, 116, 218, 181, 1, 192, + 235, 247, 95, 1, 65, 247, 95, 1, 210, 222, 247, 95, 1, 238, 127, 247, 95, + 1, 172, 247, 95, 1, 196, 28, 247, 95, 1, 146, 247, 95, 1, 219, 242, 247, + 95, 1, 254, 215, 247, 95, 1, 208, 104, 247, 95, 1, 250, 120, 247, 95, 1, + 218, 168, 247, 95, 1, 74, 247, 95, 1, 238, 34, 247, 95, 1, 200, 43, 247, + 95, 1, 203, 167, 247, 95, 1, 203, 166, 247, 95, 1, 206, 8, 247, 95, 1, + 247, 192, 247, 95, 1, 66, 247, 95, 1, 213, 80, 247, 95, 1, 192, 235, 247, + 95, 1, 215, 61, 247, 95, 1, 197, 134, 247, 95, 1, 210, 236, 247, 95, 1, + 201, 178, 247, 95, 1, 68, 247, 95, 1, 71, 247, 95, 1, 196, 25, 247, 95, + 1, 222, 152, 247, 95, 1, 222, 143, 247, 95, 1, 214, 164, 247, 95, 1, 196, + 30, 247, 95, 1, 232, 51, 247, 95, 1, 231, 242, 247, 95, 1, 201, 118, 247, + 95, 1, 201, 117, 247, 95, 1, 214, 70, 247, 95, 1, 223, 199, 247, 95, 1, + 247, 191, 247, 95, 1, 197, 135, 247, 95, 1, 196, 27, 247, 95, 1, 206, + 110, 247, 95, 1, 217, 16, 247, 95, 1, 217, 15, 247, 95, 1, 217, 14, 247, + 95, 1, 217, 13, 247, 95, 1, 219, 241, 247, 95, 1, 234, 218, 247, 95, 1, + 196, 26, 94, 234, 54, 198, 229, 77, 94, 234, 54, 17, 107, 94, 234, 54, + 17, 109, 94, 234, 54, 17, 138, 94, 234, 54, 17, 134, 94, 234, 54, 17, + 149, 94, 234, 54, 17, 169, 94, 234, 54, 17, 175, 94, 234, 54, 17, 171, + 94, 234, 54, 17, 178, 94, 234, 54, 31, 199, 95, 94, 234, 54, 31, 197, 32, + 94, 234, 54, 31, 198, 249, 94, 234, 54, 31, 232, 135, 94, 234, 54, 31, + 233, 15, 94, 234, 54, 31, 202, 120, 94, 234, 54, 31, 203, 241, 94, 234, + 54, 31, 234, 153, 94, 234, 54, 31, 213, 169, 94, 234, 54, 31, 91, 228, + 140, 94, 234, 54, 31, 105, 228, 140, 94, 234, 54, 31, 115, 228, 140, 94, + 234, 54, 31, 232, 128, 228, 140, 94, 234, 54, 31, 232, 226, 228, 140, 94, + 234, 54, 31, 202, 136, 228, 140, 94, 234, 54, 31, 203, 247, 228, 140, 94, + 234, 54, 31, 234, 164, 228, 140, 94, 234, 54, 31, 213, 175, 228, 140, 39, + 43, 1, 65, 39, 43, 1, 249, 17, 39, 43, 1, 222, 22, 39, 43, 1, 237, 146, + 39, 43, 1, 71, 39, 43, 1, 195, 153, 39, 43, 1, 191, 87, 39, 43, 1, 229, + 245, 39, 43, 1, 199, 33, 39, 43, 1, 68, 39, 43, 1, 155, 39, 43, 1, 234, + 140, 39, 43, 1, 234, 114, 39, 43, 1, 234, 103, 39, 43, 1, 234, 12, 39, + 43, 1, 74, 39, 43, 1, 210, 63, 39, 43, 1, 203, 113, 39, 43, 1, 220, 232, + 39, 43, 1, 234, 34, 39, 43, 1, 234, 22, 39, 43, 1, 199, 145, 39, 43, 1, + 66, 39, 43, 1, 234, 143, 39, 43, 1, 209, 214, 39, 43, 1, 221, 197, 39, + 43, 1, 234, 181, 39, 43, 1, 234, 24, 39, 43, 1, 243, 127, 39, 43, 1, 223, + 199, 39, 43, 1, 196, 30, 39, 43, 1, 234, 5, 39, 43, 212, 134, 107, 39, + 43, 212, 134, 149, 39, 43, 212, 134, 199, 95, 39, 43, 212, 134, 233, 15, + 39, 43, 1, 192, 80, 39, 43, 1, 213, 16, 197, 161, 39, 43, 1, 202, 0, 197, + 161, 230, 231, 1, 251, 239, 230, 231, 1, 249, 117, 230, 231, 1, 231, 50, + 230, 231, 1, 238, 13, 230, 231, 1, 251, 234, 230, 231, 1, 208, 87, 230, + 231, 1, 223, 48, 230, 231, 1, 230, 83, 230, 231, 1, 198, 243, 230, 231, + 1, 234, 151, 230, 231, 1, 220, 189, 230, 231, 1, 220, 100, 230, 231, 1, + 217, 80, 230, 231, 1, 214, 201, 230, 231, 1, 223, 1, 230, 231, 1, 196, + 48, 230, 231, 1, 210, 195, 230, 231, 1, 213, 169, 230, 231, 1, 207, 155, + 230, 231, 1, 205, 112, 230, 231, 1, 199, 111, 230, 231, 1, 193, 59, 230, + 231, 1, 233, 89, 230, 231, 1, 223, 203, 230, 231, 1, 228, 123, 230, 231, + 1, 211, 29, 230, 231, 1, 213, 175, 228, 140, 39, 210, 2, 1, 251, 132, 39, + 210, 2, 1, 247, 230, 39, 210, 2, 1, 231, 224, 39, 210, 2, 1, 236, 160, + 39, 210, 2, 1, 71, 39, 210, 2, 1, 191, 53, 39, 210, 2, 1, 235, 27, 39, + 210, 2, 1, 191, 95, 39, 210, 2, 1, 235, 25, 39, 210, 2, 1, 68, 39, 210, + 2, 1, 221, 50, 39, 210, 2, 1, 219, 208, 39, 210, 2, 1, 216, 184, 39, 210, + 2, 1, 214, 100, 39, 210, 2, 1, 195, 7, 39, 210, 2, 1, 210, 48, 39, 210, + 2, 1, 207, 70, 39, 210, 2, 1, 202, 193, 39, 210, 2, 1, 199, 217, 39, 210, + 2, 1, 66, 39, 210, 2, 1, 243, 106, 39, 210, 2, 1, 203, 47, 39, 210, 2, 1, + 203, 115, 39, 210, 2, 1, 191, 227, 39, 210, 2, 1, 192, 58, 39, 210, 2, 1, + 74, 39, 210, 2, 1, 211, 87, 39, 210, 2, 1, 234, 181, 39, 210, 2, 1, 140, + 39, 210, 2, 1, 197, 145, 39, 210, 2, 1, 195, 140, 39, 210, 2, 1, 192, 62, + 39, 210, 2, 1, 192, 60, 39, 210, 2, 1, 192, 95, 39, 210, 2, 1, 223, 226, + 39, 210, 2, 1, 191, 225, 39, 210, 2, 1, 170, 39, 210, 2, 1, 228, 35, 33, + 39, 210, 2, 1, 251, 132, 33, 39, 210, 2, 1, 236, 160, 33, 39, 210, 2, 1, + 191, 95, 33, 39, 210, 2, 1, 214, 100, 33, 39, 210, 2, 1, 202, 193, 196, + 142, 1, 251, 164, 196, 142, 1, 248, 212, 196, 142, 1, 231, 212, 196, 142, + 1, 221, 215, 196, 142, 1, 237, 106, 196, 142, 1, 229, 23, 196, 142, 1, + 193, 48, 196, 142, 1, 191, 76, 196, 142, 1, 228, 179, 196, 142, 1, 199, + 73, 196, 142, 1, 191, 250, 196, 142, 1, 222, 106, 196, 142, 1, 203, 69, + 196, 142, 1, 220, 31, 196, 142, 1, 216, 193, 196, 142, 1, 237, 64, 196, + 142, 1, 212, 130, 196, 142, 1, 190, 251, 196, 142, 1, 205, 147, 196, 142, + 1, 251, 230, 196, 142, 1, 208, 165, 196, 142, 1, 205, 191, 196, 142, 1, + 208, 38, 196, 142, 1, 207, 133, 196, 142, 1, 199, 37, 196, 142, 1, 231, + 86, 196, 142, 1, 159, 196, 142, 1, 68, 196, 142, 1, 66, 196, 142, 1, 201, + 129, 196, 142, 193, 23, 236, 205, 39, 209, 252, 3, 65, 39, 209, 252, 3, + 68, 39, 209, 252, 3, 66, 39, 209, 252, 3, 155, 39, 209, 252, 3, 220, 232, + 39, 209, 252, 3, 231, 240, 39, 209, 252, 3, 230, 179, 39, 209, 252, 3, + 192, 220, 39, 209, 252, 3, 247, 160, 39, 209, 252, 3, 223, 32, 39, 209, + 252, 3, 222, 244, 39, 209, 252, 3, 190, 190, 39, 209, 252, 3, 197, 94, + 39, 209, 252, 3, 238, 32, 39, 209, 252, 3, 237, 44, 39, 209, 252, 3, 235, + 89, 39, 209, 252, 3, 199, 49, 39, 209, 252, 3, 168, 39, 209, 252, 3, 249, + 153, 39, 209, 252, 3, 233, 109, 39, 209, 252, 3, 180, 39, 209, 252, 3, + 212, 178, 39, 209, 252, 3, 174, 39, 209, 252, 3, 216, 100, 39, 209, 252, + 3, 215, 155, 39, 209, 252, 3, 170, 39, 209, 252, 3, 195, 188, 39, 209, + 252, 3, 195, 69, 39, 209, 252, 3, 165, 39, 209, 252, 3, 206, 68, 39, 209, + 252, 3, 173, 39, 209, 252, 3, 188, 39, 209, 252, 3, 191, 123, 39, 209, + 252, 3, 203, 165, 39, 209, 252, 3, 201, 175, 39, 209, 252, 3, 140, 39, + 209, 252, 3, 250, 157, 39, 209, 252, 3, 250, 156, 39, 209, 252, 3, 250, + 155, 39, 209, 252, 3, 192, 189, 39, 209, 252, 3, 238, 9, 39, 209, 252, 3, + 238, 8, 39, 209, 252, 3, 249, 128, 39, 209, 252, 3, 247, 212, 39, 209, + 252, 193, 23, 236, 205, 39, 209, 252, 31, 107, 39, 209, 252, 31, 109, 39, + 209, 252, 31, 199, 95, 39, 209, 252, 31, 197, 32, 39, 209, 252, 31, 228, + 140, 237, 84, 6, 1, 179, 68, 237, 84, 6, 1, 179, 71, 237, 84, 6, 1, 179, + 65, 237, 84, 6, 1, 179, 251, 245, 237, 84, 6, 1, 179, 74, 237, 84, 6, 1, + 179, 211, 87, 237, 84, 6, 1, 203, 40, 68, 237, 84, 6, 1, 203, 40, 71, + 237, 84, 6, 1, 203, 40, 65, 237, 84, 6, 1, 203, 40, 251, 245, 237, 84, 6, + 1, 203, 40, 74, 237, 84, 6, 1, 203, 40, 211, 87, 237, 84, 6, 1, 250, 131, + 237, 84, 6, 1, 210, 250, 237, 84, 6, 1, 193, 0, 237, 84, 6, 1, 192, 77, + 237, 84, 6, 1, 230, 116, 237, 84, 6, 1, 210, 49, 237, 84, 6, 1, 249, 1, + 237, 84, 6, 1, 199, 121, 237, 84, 6, 1, 237, 131, 237, 84, 6, 1, 243, + 123, 237, 84, 6, 1, 223, 8, 237, 84, 6, 1, 222, 29, 237, 84, 6, 1, 231, + 186, 237, 84, 6, 1, 234, 181, 237, 84, 6, 1, 195, 148, 237, 84, 6, 1, + 233, 248, 237, 84, 6, 1, 199, 31, 237, 84, 6, 1, 234, 22, 237, 84, 6, 1, + 191, 84, 237, 84, 6, 1, 234, 12, 237, 84, 6, 1, 191, 61, 237, 84, 6, 1, + 234, 34, 237, 84, 6, 1, 234, 140, 237, 84, 6, 1, 234, 114, 237, 84, 6, 1, + 234, 103, 237, 84, 6, 1, 234, 88, 237, 84, 6, 1, 211, 133, 237, 84, 6, 1, + 233, 224, 237, 84, 2, 1, 179, 68, 237, 84, 2, 1, 179, 71, 237, 84, 2, 1, + 179, 65, 237, 84, 2, 1, 179, 251, 245, 237, 84, 2, 1, 179, 74, 237, 84, + 2, 1, 179, 211, 87, 237, 84, 2, 1, 203, 40, 68, 237, 84, 2, 1, 203, 40, + 71, 237, 84, 2, 1, 203, 40, 65, 237, 84, 2, 1, 203, 40, 251, 245, 237, + 84, 2, 1, 203, 40, 74, 237, 84, 2, 1, 203, 40, 211, 87, 237, 84, 2, 1, + 250, 131, 237, 84, 2, 1, 210, 250, 237, 84, 2, 1, 193, 0, 237, 84, 2, 1, + 192, 77, 237, 84, 2, 1, 230, 116, 237, 84, 2, 1, 210, 49, 237, 84, 2, 1, + 249, 1, 237, 84, 2, 1, 199, 121, 237, 84, 2, 1, 237, 131, 237, 84, 2, 1, + 243, 123, 237, 84, 2, 1, 223, 8, 237, 84, 2, 1, 222, 29, 237, 84, 2, 1, + 231, 186, 237, 84, 2, 1, 234, 181, 237, 84, 2, 1, 195, 148, 237, 84, 2, + 1, 233, 248, 237, 84, 2, 1, 199, 31, 237, 84, 2, 1, 234, 22, 237, 84, 2, + 1, 191, 84, 237, 84, 2, 1, 234, 12, 237, 84, 2, 1, 191, 61, 237, 84, 2, + 1, 234, 34, 237, 84, 2, 1, 234, 140, 237, 84, 2, 1, 234, 114, 237, 84, 2, + 1, 234, 103, 237, 84, 2, 1, 234, 88, 237, 84, 2, 1, 211, 133, 237, 84, 2, + 1, 233, 224, 203, 120, 1, 210, 45, 203, 120, 1, 198, 40, 203, 120, 1, + 221, 154, 203, 120, 1, 233, 52, 203, 120, 1, 199, 6, 203, 120, 1, 202, + 46, 203, 120, 1, 200, 172, 203, 120, 1, 243, 40, 203, 120, 1, 192, 79, + 203, 120, 1, 228, 137, 203, 120, 1, 248, 187, 203, 120, 1, 237, 145, 203, + 120, 1, 231, 226, 203, 120, 1, 195, 2, 203, 120, 1, 199, 12, 203, 120, 1, + 191, 4, 203, 120, 1, 216, 227, 203, 120, 1, 222, 180, 203, 120, 1, 193, + 39, 203, 120, 1, 230, 93, 203, 120, 1, 219, 25, 203, 120, 1, 216, 45, + 203, 120, 1, 223, 206, 203, 120, 1, 234, 179, 203, 120, 1, 250, 209, 203, + 120, 1, 252, 30, 203, 120, 1, 211, 104, 203, 120, 1, 193, 26, 203, 120, + 1, 211, 14, 203, 120, 1, 251, 245, 203, 120, 1, 206, 153, 203, 120, 1, + 212, 130, 203, 120, 1, 234, 200, 203, 120, 1, 251, 250, 203, 120, 1, 228, + 26, 203, 120, 1, 196, 77, 203, 120, 1, 211, 180, 203, 120, 1, 211, 79, + 203, 120, 1, 211, 131, 203, 120, 1, 250, 137, 203, 120, 1, 251, 9, 203, + 120, 1, 211, 56, 203, 120, 1, 251, 225, 203, 120, 1, 234, 26, 203, 120, + 1, 250, 240, 203, 120, 1, 234, 211, 203, 120, 1, 228, 34, 203, 120, 1, + 192, 41, 211, 33, 1, 251, 192, 211, 33, 1, 249, 153, 211, 33, 1, 190, + 190, 211, 33, 1, 223, 32, 211, 33, 1, 192, 220, 211, 33, 1, 221, 215, + 211, 33, 1, 237, 130, 211, 33, 1, 165, 211, 33, 1, 188, 211, 33, 1, 203, + 75, 211, 33, 1, 237, 68, 211, 33, 1, 247, 67, 211, 33, 1, 231, 240, 211, + 33, 1, 233, 109, 211, 33, 1, 208, 94, 211, 33, 1, 222, 123, 211, 33, 1, + 220, 121, 211, 33, 1, 216, 59, 211, 33, 1, 212, 114, 211, 33, 1, 193, + 133, 211, 33, 1, 140, 211, 33, 1, 170, 211, 33, 1, 65, 211, 33, 1, 71, + 211, 33, 1, 68, 211, 33, 1, 74, 211, 33, 1, 66, 211, 33, 1, 252, 206, + 211, 33, 1, 234, 188, 211, 33, 1, 211, 87, 211, 33, 17, 191, 77, 211, 33, + 17, 107, 211, 33, 17, 109, 211, 33, 17, 138, 211, 33, 17, 134, 211, 33, + 17, 149, 211, 33, 17, 169, 211, 33, 17, 175, 211, 33, 17, 171, 211, 33, + 17, 178, 211, 35, 6, 1, 65, 211, 35, 6, 1, 251, 236, 211, 35, 6, 1, 251, + 230, 211, 35, 6, 1, 251, 245, 211, 35, 6, 1, 248, 56, 211, 35, 6, 1, 247, + 1, 211, 35, 6, 1, 234, 172, 211, 35, 6, 1, 71, 211, 35, 6, 1, 234, 152, + 211, 35, 6, 1, 140, 211, 35, 6, 1, 228, 93, 211, 35, 6, 1, 68, 211, 35, + 6, 1, 155, 211, 35, 6, 1, 234, 171, 211, 35, 6, 1, 220, 153, 211, 35, 6, + 1, 173, 211, 35, 6, 1, 174, 211, 35, 6, 1, 180, 211, 35, 6, 1, 74, 211, + 35, 6, 1, 211, 130, 211, 35, 6, 1, 168, 211, 35, 6, 1, 234, 170, 211, 35, + 6, 1, 188, 211, 35, 6, 1, 203, 165, 211, 35, 6, 1, 190, 190, 211, 35, 6, + 1, 234, 169, 211, 35, 6, 1, 197, 168, 211, 35, 6, 1, 234, 168, 211, 35, + 6, 1, 197, 157, 211, 35, 6, 1, 237, 68, 211, 35, 6, 1, 66, 211, 35, 6, 1, + 193, 190, 211, 35, 6, 1, 221, 215, 211, 35, 6, 1, 231, 91, 211, 35, 6, 1, + 191, 123, 211, 35, 6, 1, 191, 71, 211, 35, 2, 1, 65, 211, 35, 2, 1, 251, + 236, 211, 35, 2, 1, 251, 230, 211, 35, 2, 1, 251, 245, 211, 35, 2, 1, + 248, 56, 211, 35, 2, 1, 247, 1, 211, 35, 2, 1, 234, 172, 211, 35, 2, 1, + 71, 211, 35, 2, 1, 234, 152, 211, 35, 2, 1, 140, 211, 35, 2, 1, 228, 93, + 211, 35, 2, 1, 68, 211, 35, 2, 1, 155, 211, 35, 2, 1, 234, 171, 211, 35, + 2, 1, 220, 153, 211, 35, 2, 1, 173, 211, 35, 2, 1, 174, 211, 35, 2, 1, + 180, 211, 35, 2, 1, 74, 211, 35, 2, 1, 211, 130, 211, 35, 2, 1, 168, 211, + 35, 2, 1, 234, 170, 211, 35, 2, 1, 188, 211, 35, 2, 1, 203, 165, 211, 35, + 2, 1, 190, 190, 211, 35, 2, 1, 234, 169, 211, 35, 2, 1, 197, 168, 211, + 35, 2, 1, 234, 168, 211, 35, 2, 1, 197, 157, 211, 35, 2, 1, 237, 68, 211, + 35, 2, 1, 66, 211, 35, 2, 1, 193, 190, 211, 35, 2, 1, 221, 215, 211, 35, + 2, 1, 231, 91, 211, 35, 2, 1, 191, 123, 211, 35, 2, 1, 191, 71, 234, 136, + 1, 65, 234, 136, 1, 249, 17, 234, 136, 1, 247, 42, 234, 136, 1, 243, 127, + 234, 136, 1, 237, 146, 234, 136, 1, 214, 154, 234, 136, 1, 237, 59, 234, + 136, 1, 234, 166, 234, 136, 1, 71, 234, 136, 1, 233, 59, 234, 136, 1, + 231, 165, 234, 136, 1, 231, 20, 234, 136, 1, 229, 245, 234, 136, 1, 68, + 234, 136, 1, 223, 10, 234, 136, 1, 222, 22, 234, 136, 1, 219, 238, 234, + 136, 1, 219, 68, 234, 136, 1, 216, 232, 234, 136, 1, 214, 121, 234, 136, + 1, 180, 234, 136, 1, 213, 150, 234, 136, 1, 74, 234, 136, 1, 210, 63, + 234, 136, 1, 208, 75, 234, 136, 1, 207, 113, 234, 136, 1, 206, 104, 234, + 136, 1, 205, 68, 234, 136, 1, 203, 113, 234, 136, 1, 199, 145, 234, 136, + 1, 199, 33, 234, 136, 1, 66, 234, 136, 1, 195, 153, 234, 136, 1, 192, + 214, 234, 136, 1, 192, 159, 234, 136, 1, 191, 87, 234, 136, 1, 191, 62, + 234, 136, 1, 231, 77, 234, 136, 1, 231, 83, 234, 136, 1, 221, 197, 247, + 75, 251, 193, 1, 251, 159, 247, 75, 251, 193, 1, 248, 214, 247, 75, 251, + 193, 1, 231, 40, 247, 75, 251, 193, 1, 237, 211, 247, 75, 251, 193, 1, + 234, 199, 247, 75, 251, 193, 1, 191, 98, 247, 75, 251, 193, 1, 233, 184, + 247, 75, 251, 193, 1, 191, 56, 247, 75, 251, 193, 1, 199, 174, 247, 75, + 251, 193, 1, 247, 1, 247, 75, 251, 193, 1, 191, 236, 247, 75, 251, 193, + 1, 191, 71, 247, 75, 251, 193, 1, 223, 76, 247, 75, 251, 193, 1, 203, + 165, 247, 75, 251, 193, 1, 220, 24, 247, 75, 251, 193, 1, 223, 89, 247, + 75, 251, 193, 1, 192, 210, 247, 75, 251, 193, 1, 235, 43, 247, 75, 251, + 193, 1, 247, 102, 247, 75, 251, 193, 1, 222, 245, 247, 75, 251, 193, 1, + 222, 65, 247, 75, 251, 193, 1, 218, 177, 247, 75, 251, 193, 1, 229, 179, + 247, 75, 251, 193, 1, 208, 76, 247, 75, 251, 193, 1, 251, 67, 247, 75, + 251, 193, 1, 243, 57, 247, 75, 251, 193, 1, 243, 95, 247, 75, 251, 193, + 1, 238, 140, 247, 75, 251, 193, 1, 217, 68, 247, 75, 251, 193, 1, 208, + 81, 247, 75, 251, 193, 1, 212, 252, 247, 75, 251, 193, 1, 235, 20, 247, + 75, 251, 193, 1, 203, 147, 247, 75, 251, 193, 1, 223, 11, 247, 75, 251, + 193, 1, 211, 104, 247, 75, 251, 193, 1, 197, 3, 247, 75, 251, 193, 1, + 233, 82, 247, 75, 251, 193, 1, 235, 33, 247, 75, 251, 193, 1, 243, 133, + 247, 75, 251, 193, 1, 210, 34, 247, 75, 251, 193, 1, 231, 67, 247, 75, + 251, 193, 1, 207, 130, 247, 75, 251, 193, 1, 203, 174, 247, 75, 251, 193, + 1, 195, 72, 247, 75, 251, 193, 1, 198, 118, 247, 75, 251, 193, 1, 203, + 18, 247, 75, 251, 193, 1, 223, 46, 247, 75, 251, 193, 1, 238, 141, 247, + 75, 251, 193, 1, 247, 67, 247, 75, 251, 193, 1, 192, 84, 247, 75, 251, + 193, 1, 209, 114, 247, 75, 251, 193, 1, 221, 117, 247, 75, 251, 193, 242, + 254, 77, 195, 29, 6, 1, 65, 195, 29, 6, 1, 249, 48, 195, 29, 6, 1, 249, + 17, 195, 29, 6, 1, 247, 42, 195, 29, 6, 1, 243, 127, 195, 29, 6, 1, 237, + 146, 195, 29, 6, 1, 237, 59, 195, 29, 6, 1, 234, 166, 195, 29, 6, 1, 71, + 195, 29, 6, 1, 233, 59, 195, 29, 6, 1, 231, 240, 195, 29, 6, 1, 140, 195, + 29, 6, 1, 229, 177, 195, 29, 6, 1, 68, 195, 29, 6, 1, 223, 196, 195, 29, + 6, 1, 223, 10, 195, 29, 6, 1, 155, 195, 29, 6, 1, 173, 195, 29, 6, 1, + 219, 73, 195, 29, 6, 1, 216, 232, 195, 29, 6, 1, 214, 121, 195, 29, 6, 1, + 213, 150, 195, 29, 6, 1, 74, 195, 29, 6, 1, 210, 63, 195, 29, 6, 1, 208, + 96, 195, 29, 6, 1, 207, 113, 195, 29, 6, 1, 205, 68, 195, 29, 6, 1, 203, + 113, 195, 29, 6, 1, 199, 145, 195, 29, 6, 1, 199, 33, 195, 29, 6, 1, 66, + 195, 29, 6, 1, 195, 153, 195, 29, 6, 1, 192, 214, 195, 29, 6, 1, 192, + 159, 195, 29, 6, 1, 191, 87, 195, 29, 2, 1, 65, 195, 29, 2, 1, 249, 48, + 195, 29, 2, 1, 249, 17, 195, 29, 2, 1, 247, 42, 195, 29, 2, 1, 243, 127, + 195, 29, 2, 1, 237, 146, 195, 29, 2, 1, 237, 59, 195, 29, 2, 1, 234, 166, + 195, 29, 2, 1, 71, 195, 29, 2, 1, 233, 59, 195, 29, 2, 1, 231, 240, 195, + 29, 2, 1, 140, 195, 29, 2, 1, 229, 177, 195, 29, 2, 1, 68, 195, 29, 2, 1, + 223, 196, 195, 29, 2, 1, 223, 10, 195, 29, 2, 1, 155, 195, 29, 2, 1, 173, + 195, 29, 2, 1, 219, 73, 195, 29, 2, 1, 216, 232, 195, 29, 2, 1, 214, 121, + 195, 29, 2, 1, 213, 150, 195, 29, 2, 1, 74, 195, 29, 2, 1, 210, 63, 195, + 29, 2, 1, 208, 96, 195, 29, 2, 1, 207, 113, 195, 29, 2, 1, 205, 68, 195, + 29, 2, 1, 203, 113, 195, 29, 2, 1, 199, 145, 195, 29, 2, 1, 199, 33, 195, + 29, 2, 1, 66, 195, 29, 2, 1, 195, 153, 195, 29, 2, 1, 192, 214, 195, 29, + 2, 1, 192, 159, 195, 29, 2, 1, 191, 87, 32, 42, 3, 252, 154, 32, 42, 3, + 252, 153, 32, 42, 3, 252, 152, 32, 42, 3, 252, 151, 32, 42, 3, 252, 150, + 32, 42, 3, 252, 149, 32, 42, 3, 252, 148, 32, 42, 3, 252, 147, 32, 42, 3, + 252, 146, 32, 42, 3, 252, 145, 32, 42, 3, 252, 144, 32, 42, 3, 252, 143, + 32, 42, 3, 252, 142, 32, 42, 3, 252, 141, 32, 42, 3, 252, 140, 32, 42, 3, + 252, 139, 32, 42, 3, 252, 138, 32, 42, 3, 252, 137, 32, 42, 3, 252, 136, + 32, 42, 3, 252, 135, 32, 42, 3, 252, 134, 32, 42, 3, 252, 133, 32, 42, 3, + 252, 132, 32, 42, 3, 252, 131, 32, 42, 3, 252, 130, 32, 42, 3, 252, 129, + 32, 42, 3, 252, 128, 32, 42, 3, 255, 164, 32, 42, 3, 252, 127, 32, 42, 3, + 252, 126, 32, 42, 3, 252, 125, 32, 42, 3, 252, 124, 32, 42, 3, 252, 123, + 32, 42, 3, 252, 122, 32, 42, 3, 252, 121, 32, 42, 3, 252, 120, 32, 42, 3, + 252, 119, 32, 42, 3, 252, 118, 32, 42, 3, 252, 117, 32, 42, 3, 252, 116, + 32, 42, 3, 252, 115, 32, 42, 3, 252, 114, 32, 42, 3, 252, 113, 32, 42, 3, + 252, 112, 32, 42, 3, 252, 111, 32, 42, 3, 252, 110, 32, 42, 3, 252, 109, + 32, 42, 3, 252, 108, 32, 42, 3, 252, 107, 32, 42, 3, 252, 106, 32, 42, 3, + 252, 105, 32, 42, 3, 252, 104, 32, 42, 3, 252, 103, 32, 42, 3, 252, 102, + 32, 42, 3, 252, 101, 32, 42, 3, 252, 100, 32, 42, 3, 252, 99, 32, 42, 3, + 252, 98, 32, 42, 3, 252, 97, 32, 42, 3, 252, 96, 32, 42, 3, 252, 95, 32, + 42, 3, 252, 94, 32, 42, 3, 252, 93, 32, 42, 3, 252, 92, 32, 42, 3, 252, + 91, 32, 42, 3, 252, 90, 32, 42, 3, 252, 89, 32, 42, 3, 252, 88, 32, 42, + 3, 252, 87, 32, 42, 3, 252, 86, 32, 42, 3, 252, 85, 32, 42, 3, 255, 77, + 32, 42, 3, 252, 84, 32, 42, 3, 252, 83, 32, 42, 3, 255, 42, 32, 42, 3, + 252, 82, 32, 42, 3, 252, 81, 32, 42, 3, 252, 80, 32, 42, 3, 252, 79, 32, + 42, 3, 255, 29, 32, 42, 3, 252, 78, 32, 42, 3, 252, 77, 32, 42, 3, 252, + 76, 32, 42, 3, 252, 75, 32, 42, 3, 252, 74, 32, 42, 3, 254, 101, 32, 42, + 3, 254, 100, 32, 42, 3, 254, 99, 32, 42, 3, 254, 98, 32, 42, 3, 254, 97, + 32, 42, 3, 254, 96, 32, 42, 3, 254, 95, 32, 42, 3, 254, 94, 32, 42, 3, + 254, 92, 32, 42, 3, 254, 91, 32, 42, 3, 254, 90, 32, 42, 3, 254, 89, 32, + 42, 3, 254, 88, 32, 42, 3, 254, 87, 32, 42, 3, 254, 85, 32, 42, 3, 254, + 84, 32, 42, 3, 254, 83, 32, 42, 3, 254, 82, 32, 42, 3, 254, 81, 32, 42, + 3, 254, 80, 32, 42, 3, 254, 79, 32, 42, 3, 254, 78, 32, 42, 3, 254, 77, + 32, 42, 3, 254, 76, 32, 42, 3, 254, 75, 32, 42, 3, 254, 74, 32, 42, 3, + 254, 73, 32, 42, 3, 254, 72, 32, 42, 3, 254, 71, 32, 42, 3, 254, 70, 32, + 42, 3, 254, 69, 32, 42, 3, 254, 68, 32, 42, 3, 254, 67, 32, 42, 3, 254, + 65, 32, 42, 3, 254, 64, 32, 42, 3, 254, 63, 32, 42, 3, 254, 59, 32, 42, + 3, 254, 58, 32, 42, 3, 254, 57, 32, 42, 3, 254, 56, 32, 42, 3, 254, 52, + 32, 42, 3, 254, 51, 32, 42, 3, 254, 50, 32, 42, 3, 254, 49, 32, 42, 3, + 254, 48, 32, 42, 3, 254, 47, 32, 42, 3, 254, 46, 32, 42, 3, 254, 45, 32, + 42, 3, 254, 44, 32, 42, 3, 254, 43, 32, 42, 3, 254, 42, 32, 42, 3, 254, + 41, 32, 42, 3, 254, 40, 32, 42, 3, 254, 39, 32, 42, 3, 254, 38, 32, 42, + 3, 254, 37, 32, 42, 3, 254, 36, 32, 42, 3, 254, 35, 32, 42, 3, 254, 34, + 32, 42, 3, 254, 33, 32, 42, 3, 254, 32, 32, 42, 3, 254, 31, 32, 42, 3, + 254, 30, 32, 42, 3, 254, 28, 32, 42, 3, 254, 27, 32, 42, 3, 254, 26, 32, + 42, 3, 254, 25, 32, 42, 3, 254, 24, 32, 42, 3, 254, 22, 32, 42, 3, 254, + 21, 32, 42, 3, 254, 20, 32, 42, 3, 254, 19, 32, 42, 3, 254, 17, 32, 42, + 3, 254, 16, 32, 42, 3, 254, 15, 32, 42, 3, 253, 237, 32, 42, 3, 253, 235, + 32, 42, 3, 253, 233, 32, 42, 3, 253, 231, 32, 42, 3, 253, 229, 32, 42, 3, + 253, 227, 32, 42, 3, 253, 225, 32, 42, 3, 253, 223, 32, 42, 3, 253, 221, + 32, 42, 3, 253, 219, 32, 42, 3, 253, 217, 32, 42, 3, 253, 214, 32, 42, 3, + 253, 212, 32, 42, 3, 253, 210, 32, 42, 3, 253, 208, 32, 42, 3, 253, 206, + 32, 42, 3, 253, 204, 32, 42, 3, 253, 202, 32, 42, 3, 253, 200, 32, 42, 3, + 253, 118, 32, 42, 3, 253, 117, 32, 42, 3, 253, 116, 32, 42, 3, 253, 115, + 32, 42, 3, 253, 114, 32, 42, 3, 253, 113, 32, 42, 3, 253, 111, 32, 42, 3, + 253, 110, 32, 42, 3, 253, 109, 32, 42, 3, 253, 108, 32, 42, 3, 253, 107, + 32, 42, 3, 253, 106, 32, 42, 3, 253, 104, 32, 42, 3, 253, 103, 32, 42, 3, + 253, 99, 32, 42, 3, 253, 98, 32, 42, 3, 253, 96, 32, 42, 3, 253, 95, 32, + 42, 3, 253, 94, 32, 42, 3, 253, 93, 32, 42, 3, 253, 92, 32, 42, 3, 253, + 91, 32, 42, 3, 253, 90, 32, 42, 3, 253, 89, 32, 42, 3, 253, 88, 32, 42, + 3, 253, 87, 32, 42, 3, 253, 86, 32, 42, 3, 253, 85, 32, 42, 3, 253, 84, + 32, 42, 3, 253, 83, 32, 42, 3, 253, 82, 32, 42, 3, 253, 81, 32, 42, 3, + 253, 80, 32, 42, 3, 253, 79, 32, 42, 3, 253, 78, 32, 42, 3, 253, 77, 32, + 42, 3, 253, 76, 32, 42, 3, 253, 75, 32, 42, 3, 253, 74, 32, 42, 3, 253, + 73, 32, 42, 3, 253, 72, 32, 42, 3, 253, 71, 32, 42, 3, 253, 70, 32, 42, + 3, 253, 69, 32, 42, 3, 253, 68, 32, 42, 3, 253, 67, 32, 42, 3, 253, 66, + 32, 42, 3, 253, 65, 32, 42, 3, 253, 64, 32, 42, 3, 253, 63, 32, 42, 3, + 253, 62, 32, 42, 3, 253, 61, 32, 42, 3, 253, 60, 32, 42, 3, 253, 59, 32, + 42, 3, 253, 58, 32, 42, 3, 253, 57, 32, 42, 3, 253, 56, 32, 42, 3, 253, + 55, 32, 42, 3, 253, 54, 32, 42, 3, 253, 53, 32, 42, 3, 253, 52, 32, 42, + 3, 253, 51, 32, 42, 3, 253, 50, 32, 42, 3, 253, 49, 32, 42, 3, 253, 48, + 32, 42, 3, 253, 47, 32, 42, 3, 253, 46, 32, 42, 3, 253, 45, 32, 42, 3, + 253, 44, 32, 42, 3, 253, 43, 32, 42, 3, 253, 42, 32, 42, 3, 253, 41, 32, + 42, 3, 253, 40, 32, 42, 3, 253, 39, 32, 42, 3, 253, 38, 32, 42, 3, 253, + 37, 32, 42, 3, 253, 36, 32, 42, 3, 253, 35, 32, 42, 3, 253, 34, 32, 42, + 3, 253, 33, 32, 42, 3, 253, 32, 32, 42, 3, 253, 31, 32, 42, 3, 253, 30, + 32, 42, 3, 253, 29, 32, 42, 3, 253, 28, 32, 42, 3, 253, 27, 32, 42, 3, + 253, 26, 32, 42, 3, 253, 25, 32, 42, 3, 253, 24, 32, 42, 3, 253, 23, 32, + 42, 3, 253, 22, 32, 42, 3, 253, 21, 32, 42, 3, 253, 20, 32, 42, 3, 253, + 19, 32, 42, 3, 253, 18, 32, 42, 3, 253, 17, 32, 42, 3, 253, 16, 32, 42, + 3, 253, 15, 32, 42, 3, 253, 14, 32, 42, 3, 253, 13, 32, 42, 3, 253, 12, + 32, 42, 3, 253, 11, 32, 42, 3, 253, 10, 32, 42, 3, 253, 9, 32, 42, 3, + 253, 8, 32, 42, 3, 253, 7, 32, 42, 3, 253, 6, 32, 42, 3, 253, 5, 32, 42, + 3, 253, 4, 32, 42, 3, 253, 3, 32, 42, 3, 253, 2, 32, 42, 3, 253, 1, 32, + 42, 3, 253, 0, 32, 42, 3, 252, 255, 32, 42, 3, 252, 254, 32, 42, 3, 252, + 253, 32, 42, 3, 252, 252, 32, 42, 3, 252, 251, 32, 42, 3, 252, 250, 32, + 42, 3, 252, 249, 32, 42, 3, 252, 248, 32, 42, 3, 252, 247, 32, 42, 3, + 252, 246, 32, 42, 3, 252, 245, 32, 42, 3, 252, 244, 32, 42, 3, 252, 243, + 32, 42, 3, 252, 242, 32, 42, 3, 252, 241, 32, 42, 3, 252, 240, 32, 42, 3, + 252, 239, 32, 42, 3, 252, 238, 32, 42, 3, 252, 237, 32, 42, 3, 252, 236, + 65, 32, 42, 3, 252, 235, 250, 120, 32, 42, 3, 252, 234, 238, 127, 32, 42, + 3, 252, 233, 71, 32, 42, 3, 252, 232, 233, 175, 32, 42, 3, 252, 231, 230, + 116, 32, 42, 3, 252, 230, 223, 35, 32, 42, 3, 252, 229, 222, 152, 32, 42, + 3, 252, 228, 172, 32, 42, 3, 252, 227, 220, 130, 32, 42, 3, 252, 226, + 220, 129, 32, 42, 3, 252, 225, 220, 128, 32, 42, 3, 252, 224, 220, 127, + 32, 42, 3, 252, 223, 193, 224, 32, 42, 3, 252, 222, 192, 235, 32, 42, 3, + 252, 221, 192, 159, 32, 42, 3, 252, 220, 211, 110, 32, 42, 3, 252, 219, + 252, 69, 32, 42, 3, 252, 218, 249, 54, 32, 42, 3, 252, 217, 237, 193, 32, + 42, 3, 252, 216, 233, 183, 32, 42, 3, 252, 215, 223, 10, 32, 42, 3, 252, + 214, 32, 42, 3, 252, 213, 32, 42, 3, 252, 212, 32, 42, 3, 252, 211, 32, + 42, 3, 252, 210, 32, 42, 3, 252, 209, 32, 42, 3, 252, 208, 32, 42, 3, + 252, 207, 52, 1, 2, 6, 252, 206, 52, 1, 200, 182, 197, 238, 242, 83, 52, + 1, 200, 182, 132, 197, 238, 242, 83, 52, 1, 2, 252, 25, 52, 1, 2, 6, 250, + 120, 52, 1, 2, 78, 4, 102, 52, 1, 2, 235, 37, 237, 2, 52, 1, 2, 235, 37, + 237, 3, 4, 207, 24, 102, 52, 1, 2, 235, 37, 237, 3, 4, 238, 175, 52, 1, + 2, 237, 70, 237, 2, 52, 1, 2, 238, 128, 4, 199, 215, 52, 1, 2, 238, 128, + 4, 102, 52, 1, 2, 238, 128, 4, 228, 251, 23, 199, 215, 52, 1, 2, 207, 18, + 71, 52, 1, 2, 242, 219, 207, 18, 211, 77, 71, 52, 1, 2, 233, 37, 237, 2, + 52, 1, 2, 207, 140, 228, 187, 52, 1, 2, 6, 232, 51, 52, 1, 2, 232, 52, 4, + 102, 52, 1, 2, 6, 232, 52, 4, 102, 52, 1, 2, 230, 117, 4, 106, 52, 1, 2, + 6, 230, 116, 52, 1, 2, 229, 197, 4, 102, 52, 1, 2, 236, 139, 223, 36, 4, + 201, 28, 23, 102, 52, 1, 2, 218, 227, 237, 2, 52, 1, 2, 218, 170, 237, 2, + 52, 1, 2, 220, 143, 4, 248, 231, 52, 1, 2, 6, 220, 143, 4, 248, 231, 52, + 1, 2, 220, 143, 4, 207, 24, 228, 251, 23, 248, 231, 52, 1, 2, 219, 162, + 52, 1, 2, 219, 163, 4, 207, 24, 102, 52, 1, 2, 153, 192, 159, 52, 1, 2, + 153, 192, 160, 4, 248, 231, 52, 1, 2, 187, 4, 106, 52, 1, 2, 6, 211, 151, + 52, 1, 2, 242, 219, 211, 110, 52, 1, 2, 208, 104, 52, 1, 2, 153, 207, + 222, 4, 179, 219, 212, 52, 1, 2, 153, 207, 222, 4, 179, 219, 213, 23, + 207, 24, 102, 52, 1, 2, 207, 222, 4, 199, 215, 52, 1, 2, 207, 222, 4, + 232, 233, 52, 1, 2, 6, 146, 52, 1, 2, 199, 152, 237, 3, 4, 238, 175, 52, + 1, 2, 197, 170, 237, 2, 52, 1, 2, 197, 170, 237, 3, 4, 207, 24, 102, 52, + 1, 2, 199, 79, 237, 2, 52, 1, 2, 200, 44, 4, 207, 24, 102, 52, 1, 2, 196, + 13, 4, 50, 102, 52, 1, 2, 6, 192, 159, 52, 1, 231, 11, 201, 64, 4, 106, + 52, 1, 207, 18, 231, 11, 201, 64, 4, 106, 52, 1, 248, 172, 242, 231, 52, + 1, 237, 98, 242, 231, 52, 1, 220, 3, 242, 231, 52, 1, 251, 150, 242, 231, + 52, 1, 207, 24, 242, 232, 4, 207, 24, 102, 52, 1, 2, 206, 9, 4, 238, 175, + 238, 135, 5, 65, 238, 135, 5, 71, 238, 135, 5, 68, 238, 135, 5, 74, 238, + 135, 5, 66, 238, 135, 5, 223, 32, 238, 135, 5, 222, 201, 238, 135, 5, + 155, 238, 135, 5, 222, 22, 238, 135, 5, 221, 166, 238, 135, 5, 221, 67, + 238, 135, 5, 220, 232, 238, 135, 5, 173, 238, 135, 5, 219, 238, 238, 135, + 5, 219, 146, 238, 135, 5, 219, 43, 238, 135, 5, 218, 225, 238, 135, 5, + 174, 238, 135, 5, 216, 232, 238, 135, 5, 216, 100, 238, 135, 5, 216, 12, + 238, 135, 5, 215, 155, 238, 135, 5, 180, 238, 135, 5, 214, 121, 238, 135, + 5, 213, 219, 238, 135, 5, 213, 43, 238, 135, 5, 212, 178, 238, 135, 5, + 168, 238, 135, 5, 210, 63, 238, 135, 5, 209, 185, 238, 135, 5, 209, 73, + 238, 135, 5, 208, 165, 238, 135, 5, 165, 238, 135, 5, 207, 113, 238, 135, + 5, 207, 1, 238, 135, 5, 206, 162, 238, 135, 5, 206, 68, 238, 135, 5, 188, + 238, 135, 5, 205, 68, 238, 135, 5, 202, 222, 238, 135, 5, 202, 46, 238, + 135, 5, 201, 4, 238, 135, 5, 190, 190, 238, 135, 5, 199, 145, 238, 135, + 5, 198, 193, 238, 135, 5, 159, 238, 135, 5, 197, 94, 238, 135, 5, 193, + 190, 238, 135, 5, 193, 125, 238, 135, 5, 193, 86, 238, 135, 5, 193, 48, + 238, 135, 5, 192, 220, 238, 135, 5, 192, 214, 238, 135, 5, 191, 123, 238, + 135, 5, 191, 7, 223, 164, 251, 18, 1, 251, 190, 223, 164, 251, 18, 1, + 248, 211, 223, 164, 251, 18, 1, 231, 38, 223, 164, 251, 18, 1, 237, 252, + 223, 164, 251, 18, 1, 229, 245, 223, 164, 251, 18, 1, 193, 133, 223, 164, + 251, 18, 1, 191, 91, 223, 164, 251, 18, 1, 229, 184, 223, 164, 251, 18, + 1, 199, 69, 223, 164, 251, 18, 1, 191, 249, 223, 164, 251, 18, 1, 222, + 75, 223, 164, 251, 18, 1, 220, 26, 223, 164, 251, 18, 1, 216, 193, 223, + 164, 251, 18, 1, 212, 130, 223, 164, 251, 18, 1, 205, 148, 223, 164, 251, + 18, 1, 250, 126, 223, 164, 251, 18, 1, 210, 63, 223, 164, 251, 18, 1, + 205, 189, 223, 164, 251, 18, 1, 208, 37, 223, 164, 251, 18, 1, 207, 38, + 223, 164, 251, 18, 1, 203, 69, 223, 164, 251, 18, 1, 199, 159, 223, 164, + 251, 18, 205, 54, 56, 223, 164, 251, 18, 31, 107, 223, 164, 251, 18, 31, + 109, 223, 164, 251, 18, 31, 138, 223, 164, 251, 18, 31, 199, 95, 223, + 164, 251, 18, 31, 197, 32, 223, 164, 251, 18, 31, 91, 228, 140, 223, 164, + 251, 18, 31, 91, 189, 223, 164, 251, 18, 31, 199, 96, 189, 210, 180, 1, + 251, 190, 210, 180, 1, 248, 211, 210, 180, 1, 231, 38, 210, 180, 1, 237, + 252, 210, 180, 1, 229, 245, 210, 180, 1, 193, 133, 210, 180, 1, 191, 91, + 210, 180, 1, 229, 184, 210, 180, 1, 199, 69, 210, 180, 1, 191, 249, 210, + 180, 1, 222, 75, 210, 180, 1, 220, 26, 210, 180, 1, 216, 193, 210, 180, + 1, 53, 212, 130, 210, 180, 1, 212, 130, 210, 180, 1, 205, 148, 210, 180, + 1, 250, 126, 210, 180, 1, 210, 63, 210, 180, 1, 205, 189, 210, 180, 1, + 208, 37, 210, 180, 1, 207, 38, 210, 180, 1, 203, 69, 210, 180, 1, 199, + 159, 210, 180, 219, 219, 232, 201, 210, 180, 206, 203, 232, 201, 210, + 180, 31, 107, 210, 180, 31, 109, 210, 180, 31, 138, 210, 180, 31, 134, + 210, 180, 31, 149, 210, 180, 31, 199, 95, 210, 180, 31, 197, 32, 214, + 246, 1, 53, 251, 190, 214, 246, 1, 251, 190, 214, 246, 1, 53, 248, 211, + 214, 246, 1, 248, 211, 214, 246, 1, 231, 38, 214, 246, 1, 237, 252, 214, + 246, 1, 53, 229, 245, 214, 246, 1, 229, 245, 214, 246, 1, 193, 133, 214, + 246, 1, 191, 91, 214, 246, 1, 229, 184, 214, 246, 1, 199, 69, 214, 246, + 1, 53, 191, 249, 214, 246, 1, 191, 249, 214, 246, 1, 53, 222, 75, 214, + 246, 1, 222, 75, 214, 246, 1, 53, 220, 26, 214, 246, 1, 220, 26, 214, + 246, 1, 53, 216, 193, 214, 246, 1, 216, 193, 214, 246, 1, 53, 212, 130, + 214, 246, 1, 212, 130, 214, 246, 1, 205, 148, 214, 246, 1, 250, 126, 214, + 246, 1, 210, 63, 214, 246, 1, 205, 189, 214, 246, 1, 208, 37, 214, 246, + 1, 207, 38, 214, 246, 1, 53, 203, 69, 214, 246, 1, 203, 69, 214, 246, 1, + 199, 159, 214, 246, 31, 107, 214, 246, 31, 109, 214, 246, 31, 138, 214, + 246, 31, 134, 214, 246, 238, 202, 31, 134, 214, 246, 31, 149, 214, 246, + 31, 199, 95, 214, 246, 31, 197, 32, 214, 246, 31, 91, 228, 140, 230, 4, + 1, 251, 190, 230, 4, 1, 248, 211, 230, 4, 1, 231, 38, 230, 4, 1, 237, + 251, 230, 4, 1, 229, 245, 230, 4, 1, 193, 133, 230, 4, 1, 191, 89, 230, + 4, 1, 229, 184, 230, 4, 1, 199, 69, 230, 4, 1, 191, 249, 230, 4, 1, 222, + 75, 230, 4, 1, 220, 26, 230, 4, 1, 216, 193, 230, 4, 1, 212, 130, 230, 4, + 1, 205, 148, 230, 4, 1, 250, 124, 230, 4, 1, 210, 63, 230, 4, 1, 205, + 189, 230, 4, 1, 208, 37, 230, 4, 1, 203, 69, 230, 4, 1, 199, 159, 230, 4, + 31, 107, 230, 4, 31, 149, 230, 4, 31, 199, 95, 230, 4, 31, 197, 32, 230, + 4, 31, 91, 228, 140, 209, 197, 1, 251, 187, 209, 197, 1, 248, 214, 209, + 197, 1, 231, 213, 209, 197, 1, 237, 108, 209, 197, 1, 229, 245, 209, 197, + 1, 193, 140, 209, 197, 1, 191, 115, 209, 197, 1, 229, 186, 209, 197, 1, + 199, 73, 209, 197, 1, 191, 250, 209, 197, 1, 222, 106, 209, 197, 1, 220, + 32, 209, 197, 1, 216, 193, 209, 197, 1, 212, 130, 209, 197, 1, 204, 19, + 209, 197, 1, 251, 230, 209, 197, 1, 210, 63, 209, 197, 1, 205, 191, 209, + 197, 1, 208, 42, 209, 197, 1, 206, 124, 209, 197, 1, 203, 69, 209, 197, + 1, 199, 166, 209, 197, 31, 107, 209, 197, 31, 199, 95, 209, 197, 31, 197, + 32, 209, 197, 31, 91, 228, 140, 209, 197, 31, 109, 209, 197, 31, 138, + 209, 197, 193, 23, 204, 10, 218, 180, 1, 65, 218, 180, 1, 250, 120, 218, + 180, 1, 232, 51, 218, 180, 1, 238, 127, 218, 180, 1, 71, 218, 180, 1, + 196, 12, 218, 180, 1, 68, 218, 180, 1, 192, 159, 218, 180, 1, 222, 152, + 218, 180, 1, 172, 218, 180, 1, 218, 168, 218, 180, 1, 215, 61, 218, 180, + 1, 74, 218, 180, 1, 146, 218, 180, 1, 201, 178, 218, 180, 1, 200, 43, + 218, 180, 1, 66, 218, 180, 1, 233, 175, 218, 180, 1, 208, 104, 218, 180, + 1, 206, 8, 218, 180, 1, 197, 135, 218, 180, 1, 251, 132, 218, 180, 1, + 234, 103, 218, 180, 1, 218, 183, 218, 180, 1, 213, 80, 218, 180, 1, 247, + 193, 218, 180, 197, 238, 77, 152, 229, 144, 1, 65, 152, 229, 144, 1, 71, + 152, 229, 144, 1, 68, 152, 229, 144, 1, 74, 152, 229, 144, 1, 170, 152, + 229, 144, 1, 193, 190, 152, 229, 144, 1, 249, 153, 152, 229, 144, 1, 249, + 152, 152, 229, 144, 1, 168, 152, 229, 144, 1, 174, 152, 229, 144, 1, 180, + 152, 229, 144, 1, 215, 5, 152, 229, 144, 1, 214, 121, 152, 229, 144, 1, + 214, 119, 152, 229, 144, 1, 165, 152, 229, 144, 1, 207, 184, 152, 229, + 144, 1, 173, 152, 229, 144, 1, 221, 215, 152, 229, 144, 1, 229, 177, 152, + 229, 144, 1, 188, 152, 229, 144, 1, 205, 205, 152, 229, 144, 1, 205, 68, + 152, 229, 144, 1, 155, 152, 229, 144, 1, 208, 96, 152, 229, 144, 1, 190, + 190, 152, 229, 144, 1, 199, 250, 152, 229, 144, 1, 199, 145, 152, 229, + 144, 1, 199, 143, 152, 229, 144, 1, 159, 152, 229, 144, 1, 238, 32, 152, + 229, 144, 16, 195, 63, 152, 229, 144, 16, 195, 62, 152, 238, 166, 1, 65, + 152, 238, 166, 1, 71, 152, 238, 166, 1, 68, 152, 238, 166, 1, 74, 152, + 238, 166, 1, 170, 152, 238, 166, 1, 193, 190, 152, 238, 166, 1, 249, 153, + 152, 238, 166, 1, 168, 152, 238, 166, 1, 174, 152, 238, 166, 1, 180, 152, + 238, 166, 1, 214, 121, 152, 238, 166, 1, 165, 152, 238, 166, 1, 173, 152, + 238, 166, 1, 221, 215, 152, 238, 166, 1, 229, 177, 152, 238, 166, 1, 188, + 152, 238, 166, 1, 251, 14, 188, 152, 238, 166, 1, 205, 68, 152, 238, 166, + 1, 155, 152, 238, 166, 1, 208, 96, 152, 238, 166, 1, 190, 190, 152, 238, + 166, 1, 199, 145, 152, 238, 166, 1, 159, 152, 238, 166, 1, 238, 32, 152, + 238, 166, 232, 118, 234, 128, 197, 39, 152, 238, 166, 232, 118, 91, 230, + 70, 152, 238, 166, 219, 28, 206, 168, 152, 238, 166, 219, 28, 223, 169, + 152, 238, 166, 31, 107, 152, 238, 166, 31, 109, 152, 238, 166, 31, 138, + 152, 238, 166, 31, 134, 152, 238, 166, 31, 149, 152, 238, 166, 31, 169, + 152, 238, 166, 31, 175, 152, 238, 166, 31, 171, 152, 238, 166, 31, 178, + 152, 238, 166, 31, 199, 95, 152, 238, 166, 31, 197, 32, 152, 238, 166, + 31, 198, 249, 152, 238, 166, 31, 232, 135, 152, 238, 166, 31, 233, 15, + 152, 238, 166, 31, 202, 120, 152, 238, 166, 31, 203, 241, 152, 238, 166, + 31, 91, 228, 140, 152, 238, 166, 31, 105, 228, 140, 152, 238, 166, 31, + 115, 228, 140, 152, 238, 166, 31, 232, 128, 228, 140, 152, 238, 166, 31, + 232, 226, 228, 140, 152, 238, 166, 31, 202, 136, 228, 140, 152, 238, 166, + 31, 203, 247, 228, 140, 152, 238, 166, 31, 234, 164, 228, 140, 152, 238, + 166, 31, 213, 175, 228, 140, 152, 238, 166, 31, 91, 189, 152, 238, 166, + 31, 105, 189, 152, 238, 166, 31, 115, 189, 152, 238, 166, 31, 232, 128, + 189, 152, 238, 166, 31, 232, 226, 189, 152, 238, 166, 31, 202, 136, 189, + 152, 238, 166, 31, 203, 247, 189, 152, 238, 166, 31, 234, 164, 189, 152, + 238, 166, 31, 213, 175, 189, 152, 238, 166, 31, 199, 96, 189, 152, 238, + 166, 31, 197, 33, 189, 152, 238, 166, 31, 198, 250, 189, 152, 238, 166, + 31, 232, 136, 189, 152, 238, 166, 31, 233, 16, 189, 152, 238, 166, 31, + 202, 121, 189, 152, 238, 166, 31, 203, 242, 189, 152, 238, 166, 31, 234, + 154, 189, 152, 238, 166, 31, 213, 170, 189, 152, 238, 166, 31, 91, 228, + 141, 189, 152, 238, 166, 31, 105, 228, 141, 189, 152, 238, 166, 31, 115, + 228, 141, 189, 152, 238, 166, 31, 232, 128, 228, 141, 189, 152, 238, 166, + 31, 232, 226, 228, 141, 189, 152, 238, 166, 31, 202, 136, 228, 141, 189, + 152, 238, 166, 31, 203, 247, 228, 141, 189, 152, 238, 166, 31, 234, 164, + 228, 141, 189, 152, 238, 166, 31, 213, 175, 228, 141, 189, 152, 238, 166, + 232, 118, 91, 197, 40, 152, 238, 166, 232, 118, 105, 197, 39, 152, 238, + 166, 232, 118, 115, 197, 39, 152, 238, 166, 232, 118, 232, 128, 197, 39, + 152, 238, 166, 232, 118, 232, 226, 197, 39, 152, 238, 166, 232, 118, 202, + 136, 197, 39, 152, 238, 166, 232, 118, 203, 247, 197, 39, 152, 238, 166, + 232, 118, 234, 164, 197, 39, 152, 238, 166, 232, 118, 213, 175, 197, 39, + 152, 238, 166, 232, 118, 199, 96, 197, 39, 221, 199, 1, 65, 221, 199, 18, + 3, 68, 221, 199, 18, 3, 66, 221, 199, 18, 3, 117, 146, 221, 199, 18, 3, + 71, 221, 199, 18, 3, 74, 221, 199, 18, 219, 198, 77, 221, 199, 3, 55, + 206, 189, 60, 221, 199, 3, 251, 71, 221, 199, 3, 195, 35, 221, 199, 1, + 155, 221, 199, 1, 221, 215, 221, 199, 1, 231, 240, 221, 199, 1, 231, 91, + 221, 199, 1, 247, 160, 221, 199, 1, 247, 1, 221, 199, 1, 223, 32, 221, + 199, 1, 212, 101, 221, 199, 1, 197, 132, 221, 199, 1, 197, 120, 221, 199, + 1, 237, 191, 221, 199, 1, 237, 175, 221, 199, 1, 213, 79, 221, 199, 1, + 190, 190, 221, 199, 1, 199, 49, 221, 199, 1, 238, 32, 221, 199, 1, 237, + 68, 221, 199, 1, 180, 221, 199, 1, 168, 221, 199, 1, 209, 228, 221, 199, + 1, 249, 153, 221, 199, 1, 248, 203, 221, 199, 1, 174, 221, 199, 1, 170, + 221, 199, 1, 165, 221, 199, 1, 173, 221, 199, 1, 195, 188, 221, 199, 1, + 203, 165, 221, 199, 1, 201, 175, 221, 199, 1, 188, 221, 199, 1, 191, 123, + 221, 199, 1, 140, 221, 199, 1, 221, 101, 221, 199, 1, 197, 100, 221, 199, + 1, 197, 101, 221, 199, 1, 195, 70, 221, 199, 3, 249, 88, 58, 221, 199, 3, + 247, 74, 221, 199, 3, 75, 60, 221, 199, 195, 40, 221, 199, 17, 107, 221, + 199, 17, 109, 221, 199, 17, 138, 221, 199, 17, 134, 221, 199, 31, 199, + 95, 221, 199, 31, 197, 32, 221, 199, 31, 91, 228, 140, 221, 199, 31, 91, + 189, 221, 199, 232, 118, 91, 230, 70, 221, 199, 208, 152, 236, 140, 221, + 199, 208, 152, 2, 243, 10, 221, 199, 208, 152, 243, 10, 221, 199, 208, + 152, 238, 228, 164, 221, 199, 208, 152, 217, 83, 221, 199, 208, 152, 218, + 246, 221, 199, 208, 152, 237, 238, 221, 199, 208, 152, 55, 237, 238, 221, + 199, 208, 152, 219, 106, 39, 202, 2, 251, 29, 1, 229, 245, 39, 202, 2, + 251, 29, 1, 220, 26, 39, 202, 2, 251, 29, 1, 229, 184, 39, 202, 2, 251, + 29, 1, 216, 193, 39, 202, 2, 251, 29, 1, 208, 37, 39, 202, 2, 251, 29, 1, + 193, 133, 39, 202, 2, 251, 29, 1, 203, 69, 39, 202, 2, 251, 29, 1, 207, + 38, 39, 202, 2, 251, 29, 1, 248, 211, 39, 202, 2, 251, 29, 1, 199, 159, + 39, 202, 2, 251, 29, 1, 205, 122, 39, 202, 2, 251, 29, 1, 222, 75, 39, + 202, 2, 251, 29, 1, 212, 130, 39, 202, 2, 251, 29, 1, 221, 194, 39, 202, + 2, 251, 29, 1, 205, 189, 39, 202, 2, 251, 29, 1, 205, 148, 39, 202, 2, + 251, 29, 1, 233, 59, 39, 202, 2, 251, 29, 1, 251, 192, 39, 202, 2, 251, + 29, 1, 250, 124, 39, 202, 2, 251, 29, 1, 237, 65, 39, 202, 2, 251, 29, 1, + 231, 38, 39, 202, 2, 251, 29, 1, 237, 252, 39, 202, 2, 251, 29, 1, 231, + 79, 39, 202, 2, 251, 29, 1, 199, 69, 39, 202, 2, 251, 29, 1, 191, 89, 39, + 202, 2, 251, 29, 1, 237, 62, 39, 202, 2, 251, 29, 1, 191, 249, 39, 202, + 2, 251, 29, 1, 199, 35, 39, 202, 2, 251, 29, 1, 199, 14, 39, 202, 2, 251, + 29, 31, 107, 39, 202, 2, 251, 29, 31, 233, 15, 39, 202, 2, 251, 29, 167, + 223, 144, 39, 186, 251, 29, 1, 229, 210, 39, 186, 251, 29, 1, 220, 35, + 39, 186, 251, 29, 1, 230, 81, 39, 186, 251, 29, 1, 216, 208, 39, 186, + 251, 29, 1, 208, 89, 39, 186, 251, 29, 1, 193, 133, 39, 186, 251, 29, 1, + 234, 20, 39, 186, 251, 29, 1, 207, 71, 39, 186, 251, 29, 1, 248, 245, 39, + 186, 251, 29, 1, 199, 114, 39, 186, 251, 29, 1, 234, 21, 39, 186, 251, + 29, 1, 222, 106, 39, 186, 251, 29, 1, 213, 24, 39, 186, 251, 29, 1, 221, + 210, 39, 186, 251, 29, 1, 205, 192, 39, 186, 251, 29, 1, 234, 19, 39, + 186, 251, 29, 1, 233, 46, 39, 186, 251, 29, 1, 251, 192, 39, 186, 251, + 29, 1, 251, 230, 39, 186, 251, 29, 1, 238, 26, 39, 186, 251, 29, 1, 231, + 156, 39, 186, 251, 29, 1, 238, 3, 39, 186, 251, 29, 1, 231, 86, 39, 186, + 251, 29, 1, 199, 219, 39, 186, 251, 29, 1, 191, 113, 39, 186, 251, 29, 1, + 199, 41, 39, 186, 251, 29, 1, 192, 75, 39, 186, 251, 29, 1, 199, 29, 39, + 186, 251, 29, 1, 191, 116, 39, 186, 251, 29, 31, 107, 39, 186, 251, 29, + 31, 199, 95, 39, 186, 251, 29, 31, 197, 32, 217, 81, 1, 251, 190, 217, + 81, 1, 248, 211, 217, 81, 1, 248, 194, 217, 81, 1, 231, 38, 217, 81, 1, + 231, 64, 217, 81, 1, 237, 252, 217, 81, 1, 229, 245, 217, 81, 1, 193, + 133, 217, 81, 3, 196, 158, 217, 81, 1, 191, 91, 217, 81, 1, 191, 64, 217, + 81, 1, 223, 12, 217, 81, 1, 222, 248, 217, 81, 1, 229, 184, 217, 81, 1, + 199, 69, 217, 81, 1, 191, 249, 217, 81, 1, 222, 75, 217, 81, 1, 192, 217, + 217, 81, 1, 221, 201, 217, 81, 1, 220, 26, 217, 81, 1, 237, 61, 217, 81, + 1, 199, 40, 217, 81, 1, 216, 193, 217, 81, 1, 212, 130, 217, 81, 1, 205, + 148, 217, 81, 1, 250, 126, 217, 81, 1, 252, 158, 217, 81, 1, 210, 63, + 217, 81, 1, 233, 59, 217, 81, 1, 205, 189, 217, 81, 1, 208, 37, 217, 81, + 1, 192, 193, 217, 81, 1, 208, 64, 217, 81, 1, 207, 38, 217, 81, 1, 203, + 69, 217, 81, 1, 201, 143, 217, 81, 1, 199, 159, 217, 81, 252, 68, 87, 58, + 217, 81, 252, 68, 87, 60, 217, 81, 31, 107, 217, 81, 31, 149, 217, 81, + 31, 199, 95, 217, 81, 31, 197, 32, 217, 81, 31, 91, 228, 140, 217, 81, + 208, 152, 201, 102, 217, 81, 208, 152, 232, 201, 217, 81, 208, 152, 55, + 75, 193, 53, 236, 140, 217, 81, 208, 152, 75, 193, 53, 236, 140, 217, 81, + 208, 152, 236, 140, 217, 81, 208, 152, 105, 236, 138, 217, 81, 208, 152, + 219, 113, 233, 3, 250, 142, 1, 65, 250, 142, 1, 252, 206, 250, 142, 1, + 251, 68, 250, 142, 1, 252, 164, 250, 142, 1, 251, 132, 250, 142, 1, 252, + 166, 250, 142, 1, 252, 25, 250, 142, 1, 252, 21, 250, 142, 1, 71, 250, + 142, 1, 234, 188, 250, 142, 1, 74, 250, 142, 1, 211, 87, 250, 142, 1, 68, + 250, 142, 1, 223, 199, 250, 142, 1, 66, 250, 142, 1, 196, 30, 250, 142, + 1, 222, 22, 250, 142, 1, 192, 214, 250, 142, 1, 192, 173, 250, 142, 1, + 192, 184, 250, 142, 1, 231, 165, 250, 142, 1, 231, 122, 250, 142, 1, 231, + 77, 250, 142, 1, 247, 42, 250, 142, 1, 223, 10, 250, 142, 1, 199, 145, + 250, 142, 1, 199, 33, 250, 142, 1, 237, 146, 250, 142, 1, 237, 59, 250, + 142, 1, 197, 127, 250, 142, 1, 210, 63, 250, 142, 1, 233, 59, 250, 142, + 1, 249, 17, 250, 142, 1, 248, 196, 250, 142, 1, 214, 55, 250, 142, 1, + 213, 226, 250, 142, 1, 213, 227, 250, 142, 1, 214, 121, 250, 142, 1, 212, + 90, 250, 142, 1, 213, 74, 250, 142, 1, 216, 232, 250, 142, 1, 229, 73, + 250, 142, 1, 191, 173, 250, 142, 1, 192, 80, 250, 142, 1, 195, 153, 250, + 142, 1, 207, 113, 250, 142, 1, 219, 238, 250, 142, 1, 205, 68, 250, 142, + 1, 191, 87, 250, 142, 1, 203, 113, 250, 142, 1, 191, 62, 250, 142, 1, + 202, 229, 250, 142, 1, 201, 144, 250, 142, 1, 229, 245, 250, 142, 252, + 68, 77, 198, 138, 105, 185, 139, 91, 75, 208, 151, 2, 105, 185, 139, 91, + 75, 208, 151, 220, 13, 105, 185, 139, 91, 75, 208, 151, 220, 13, 91, 75, + 139, 105, 185, 208, 151, 220, 13, 105, 206, 185, 139, 91, 206, 189, 208, + 151, 220, 13, 91, 206, 189, 139, 105, 206, 185, 208, 151, 223, 122, 210, + 106, 1, 251, 190, 223, 122, 210, 106, 1, 248, 211, 223, 122, 210, 106, 1, + 231, 38, 223, 122, 210, 106, 1, 237, 252, 223, 122, 210, 106, 1, 229, + 245, 223, 122, 210, 106, 1, 193, 133, 223, 122, 210, 106, 1, 191, 91, + 223, 122, 210, 106, 1, 229, 184, 223, 122, 210, 106, 1, 199, 69, 223, + 122, 210, 106, 1, 191, 249, 223, 122, 210, 106, 1, 222, 75, 223, 122, + 210, 106, 1, 220, 26, 223, 122, 210, 106, 1, 216, 193, 223, 122, 210, + 106, 1, 212, 130, 223, 122, 210, 106, 1, 205, 148, 223, 122, 210, 106, 1, + 250, 126, 223, 122, 210, 106, 1, 210, 63, 223, 122, 210, 106, 1, 205, + 189, 223, 122, 210, 106, 1, 208, 37, 223, 122, 210, 106, 1, 207, 38, 223, + 122, 210, 106, 1, 203, 69, 223, 122, 210, 106, 1, 199, 159, 223, 122, + 210, 106, 31, 107, 223, 122, 210, 106, 31, 109, 223, 122, 210, 106, 31, + 138, 223, 122, 210, 106, 31, 134, 223, 122, 210, 106, 31, 199, 95, 223, + 122, 210, 106, 31, 197, 32, 223, 122, 210, 106, 31, 91, 228, 140, 223, + 122, 210, 106, 31, 91, 189, 223, 122, 210, 199, 1, 251, 190, 223, 122, + 210, 199, 1, 248, 211, 223, 122, 210, 199, 1, 231, 38, 223, 122, 210, + 199, 1, 237, 252, 223, 122, 210, 199, 1, 229, 245, 223, 122, 210, 199, 1, + 193, 132, 223, 122, 210, 199, 1, 191, 91, 223, 122, 210, 199, 1, 229, + 184, 223, 122, 210, 199, 1, 199, 69, 223, 122, 210, 199, 1, 191, 249, + 223, 122, 210, 199, 1, 222, 75, 223, 122, 210, 199, 1, 220, 26, 223, 122, + 210, 199, 1, 216, 192, 223, 122, 210, 199, 1, 212, 130, 223, 122, 210, + 199, 1, 205, 148, 223, 122, 210, 199, 1, 210, 63, 223, 122, 210, 199, 1, + 205, 189, 223, 122, 210, 199, 1, 203, 69, 223, 122, 210, 199, 1, 199, + 159, 223, 122, 210, 199, 31, 107, 223, 122, 210, 199, 31, 109, 223, 122, + 210, 199, 31, 138, 223, 122, 210, 199, 31, 134, 223, 122, 210, 199, 31, + 199, 95, 223, 122, 210, 199, 31, 197, 32, 223, 122, 210, 199, 31, 91, + 228, 140, 223, 122, 210, 199, 31, 91, 189, 208, 177, 210, 199, 1, 251, + 190, 208, 177, 210, 199, 1, 248, 211, 208, 177, 210, 199, 1, 231, 38, + 208, 177, 210, 199, 1, 237, 252, 208, 177, 210, 199, 1, 229, 245, 208, + 177, 210, 199, 1, 193, 132, 208, 177, 210, 199, 1, 191, 91, 208, 177, + 210, 199, 1, 229, 184, 208, 177, 210, 199, 1, 191, 249, 208, 177, 210, + 199, 1, 222, 75, 208, 177, 210, 199, 1, 220, 26, 208, 177, 210, 199, 1, + 216, 192, 208, 177, 210, 199, 1, 212, 130, 208, 177, 210, 199, 1, 205, + 148, 208, 177, 210, 199, 1, 210, 63, 208, 177, 210, 199, 1, 205, 189, + 208, 177, 210, 199, 1, 203, 69, 208, 177, 210, 199, 1, 199, 159, 208, + 177, 210, 199, 205, 54, 77, 208, 177, 210, 199, 153, 205, 54, 77, 208, + 177, 210, 199, 232, 128, 185, 4, 238, 217, 208, 177, 210, 199, 232, 128, + 185, 4, 236, 140, 208, 177, 210, 199, 31, 107, 208, 177, 210, 199, 31, + 109, 208, 177, 210, 199, 31, 138, 208, 177, 210, 199, 31, 134, 208, 177, + 210, 199, 31, 199, 95, 208, 177, 210, 199, 31, 197, 32, 208, 177, 210, + 199, 31, 91, 228, 140, 39, 197, 61, 1, 211, 44, 65, 39, 197, 61, 1, 192, + 68, 65, 39, 197, 61, 1, 192, 68, 252, 25, 39, 197, 61, 1, 211, 44, 68, + 39, 197, 61, 1, 192, 68, 68, 39, 197, 61, 1, 192, 68, 71, 39, 197, 61, 1, + 211, 44, 74, 39, 197, 61, 1, 211, 44, 211, 151, 39, 197, 61, 1, 192, 68, + 211, 151, 39, 197, 61, 1, 211, 44, 252, 155, 39, 197, 61, 1, 192, 68, + 252, 155, 39, 197, 61, 1, 211, 44, 252, 24, 39, 197, 61, 1, 192, 68, 252, + 24, 39, 197, 61, 1, 211, 44, 251, 253, 39, 197, 61, 1, 192, 68, 251, 253, + 39, 197, 61, 1, 211, 44, 252, 19, 39, 197, 61, 1, 192, 68, 252, 19, 39, + 197, 61, 1, 211, 44, 252, 42, 39, 197, 61, 1, 192, 68, 252, 42, 39, 197, + 61, 1, 211, 44, 252, 23, 39, 197, 61, 1, 211, 44, 233, 182, 39, 197, 61, + 1, 192, 68, 233, 182, 39, 197, 61, 1, 211, 44, 250, 131, 39, 197, 61, 1, + 192, 68, 250, 131, 39, 197, 61, 1, 211, 44, 252, 6, 39, 197, 61, 1, 192, + 68, 252, 6, 39, 197, 61, 1, 211, 44, 252, 17, 39, 197, 61, 1, 192, 68, + 252, 17, 39, 197, 61, 1, 211, 44, 211, 149, 39, 197, 61, 1, 192, 68, 211, + 149, 39, 197, 61, 1, 211, 44, 251, 207, 39, 197, 61, 1, 192, 68, 251, + 207, 39, 197, 61, 1, 211, 44, 252, 16, 39, 197, 61, 1, 211, 44, 234, 118, + 39, 197, 61, 1, 211, 44, 234, 114, 39, 197, 61, 1, 211, 44, 251, 132, 39, + 197, 61, 1, 211, 44, 252, 14, 39, 197, 61, 1, 192, 68, 252, 14, 39, 197, + 61, 1, 211, 44, 234, 80, 39, 197, 61, 1, 192, 68, 234, 80, 39, 197, 61, + 1, 211, 44, 234, 100, 39, 197, 61, 1, 192, 68, 234, 100, 39, 197, 61, 1, + 211, 44, 234, 66, 39, 197, 61, 1, 192, 68, 234, 66, 39, 197, 61, 1, 192, + 68, 251, 122, 39, 197, 61, 1, 211, 44, 234, 88, 39, 197, 61, 1, 192, 68, + 252, 13, 39, 197, 61, 1, 211, 44, 234, 56, 39, 197, 61, 1, 211, 44, 211, + 78, 39, 197, 61, 1, 211, 44, 228, 28, 39, 197, 61, 1, 211, 44, 234, 197, + 39, 197, 61, 1, 192, 68, 234, 197, 39, 197, 61, 1, 211, 44, 251, 37, 39, + 197, 61, 1, 192, 68, 251, 37, 39, 197, 61, 1, 211, 44, 223, 79, 39, 197, + 61, 1, 192, 68, 223, 79, 39, 197, 61, 1, 211, 44, 211, 58, 39, 197, 61, + 1, 192, 68, 211, 58, 39, 197, 61, 1, 211, 44, 251, 33, 39, 197, 61, 1, + 192, 68, 251, 33, 39, 197, 61, 1, 211, 44, 252, 12, 39, 197, 61, 1, 211, + 44, 250, 219, 39, 197, 61, 1, 211, 44, 252, 10, 39, 197, 61, 1, 211, 44, + 250, 209, 39, 197, 61, 1, 192, 68, 250, 209, 39, 197, 61, 1, 211, 44, + 234, 12, 39, 197, 61, 1, 192, 68, 234, 12, 39, 197, 61, 1, 211, 44, 250, + 182, 39, 197, 61, 1, 192, 68, 250, 182, 39, 197, 61, 1, 211, 44, 252, 7, + 39, 197, 61, 1, 192, 68, 252, 7, 39, 197, 61, 1, 211, 44, 211, 30, 39, + 197, 61, 1, 211, 44, 249, 71, 39, 177, 6, 1, 65, 39, 177, 6, 1, 252, 206, + 39, 177, 6, 1, 234, 199, 39, 177, 6, 1, 251, 144, 39, 177, 6, 1, 234, + 197, 39, 177, 6, 1, 234, 100, 39, 177, 6, 1, 234, 193, 39, 177, 6, 1, + 234, 192, 39, 177, 6, 1, 251, 125, 39, 177, 6, 1, 71, 39, 177, 6, 1, 242, + 220, 71, 39, 177, 6, 1, 234, 188, 39, 177, 6, 1, 234, 181, 39, 177, 6, 1, + 234, 180, 39, 177, 6, 1, 234, 176, 39, 177, 6, 1, 234, 173, 39, 177, 6, + 1, 68, 39, 177, 6, 1, 223, 199, 39, 177, 6, 1, 234, 150, 39, 177, 6, 1, + 234, 147, 39, 177, 6, 1, 251, 216, 39, 177, 6, 1, 196, 86, 39, 177, 6, 1, + 234, 140, 39, 177, 6, 1, 234, 117, 39, 177, 6, 1, 234, 114, 39, 177, 6, + 1, 234, 103, 39, 177, 6, 1, 234, 66, 39, 177, 6, 1, 74, 39, 177, 6, 1, + 211, 87, 39, 177, 6, 1, 213, 182, 211, 151, 39, 177, 6, 1, 206, 58, 211, + 151, 39, 177, 6, 1, 211, 150, 39, 177, 6, 1, 234, 56, 39, 177, 6, 1, 234, + 108, 39, 177, 6, 1, 234, 34, 39, 177, 6, 1, 203, 40, 234, 34, 39, 177, 6, + 1, 234, 22, 39, 177, 6, 1, 234, 1, 39, 177, 6, 1, 233, 255, 39, 177, 6, + 1, 234, 80, 39, 177, 6, 1, 233, 243, 39, 177, 6, 1, 234, 195, 39, 177, 6, + 1, 66, 39, 177, 6, 1, 196, 30, 39, 177, 6, 1, 213, 182, 196, 152, 39, + 177, 6, 1, 206, 58, 196, 152, 39, 177, 6, 1, 233, 230, 39, 177, 6, 1, + 233, 182, 39, 177, 6, 1, 233, 177, 39, 177, 6, 1, 234, 79, 56, 39, 177, + 6, 1, 196, 45, 39, 177, 2, 1, 65, 39, 177, 2, 1, 252, 206, 39, 177, 2, 1, + 234, 199, 39, 177, 2, 1, 251, 144, 39, 177, 2, 1, 234, 197, 39, 177, 2, + 1, 234, 100, 39, 177, 2, 1, 234, 193, 39, 177, 2, 1, 234, 192, 39, 177, + 2, 1, 251, 125, 39, 177, 2, 1, 71, 39, 177, 2, 1, 242, 220, 71, 39, 177, + 2, 1, 234, 188, 39, 177, 2, 1, 234, 181, 39, 177, 2, 1, 234, 180, 39, + 177, 2, 1, 234, 176, 39, 177, 2, 1, 234, 173, 39, 177, 2, 1, 68, 39, 177, + 2, 1, 223, 199, 39, 177, 2, 1, 234, 150, 39, 177, 2, 1, 234, 147, 39, + 177, 2, 1, 251, 216, 39, 177, 2, 1, 196, 86, 39, 177, 2, 1, 234, 140, 39, + 177, 2, 1, 234, 117, 39, 177, 2, 1, 234, 114, 39, 177, 2, 1, 234, 103, + 39, 177, 2, 1, 234, 66, 39, 177, 2, 1, 74, 39, 177, 2, 1, 211, 87, 39, + 177, 2, 1, 213, 182, 211, 151, 39, 177, 2, 1, 206, 58, 211, 151, 39, 177, + 2, 1, 211, 150, 39, 177, 2, 1, 234, 56, 39, 177, 2, 1, 234, 108, 39, 177, + 2, 1, 234, 34, 39, 177, 2, 1, 203, 40, 234, 34, 39, 177, 2, 1, 234, 22, + 39, 177, 2, 1, 234, 1, 39, 177, 2, 1, 233, 255, 39, 177, 2, 1, 234, 80, + 39, 177, 2, 1, 233, 243, 39, 177, 2, 1, 234, 195, 39, 177, 2, 1, 66, 39, + 177, 2, 1, 196, 30, 39, 177, 2, 1, 213, 182, 196, 152, 39, 177, 2, 1, + 206, 58, 196, 152, 39, 177, 2, 1, 233, 230, 39, 177, 2, 1, 233, 182, 39, + 177, 2, 1, 233, 177, 39, 177, 2, 1, 234, 79, 56, 39, 177, 2, 1, 196, 45, + 39, 177, 31, 107, 39, 177, 31, 149, 39, 177, 31, 199, 95, 39, 177, 31, + 233, 15, 39, 177, 31, 91, 228, 140, 39, 177, 31, 91, 189, 230, 24, 206, + 142, 1, 65, 230, 24, 206, 142, 1, 249, 153, 230, 24, 206, 142, 1, 168, + 230, 24, 206, 142, 1, 190, 190, 230, 24, 206, 142, 1, 197, 132, 230, 24, + 206, 142, 1, 223, 32, 230, 24, 206, 142, 1, 247, 160, 230, 24, 206, 142, + 1, 140, 230, 24, 206, 142, 1, 221, 215, 230, 24, 206, 142, 1, 233, 109, + 230, 24, 206, 142, 1, 238, 32, 230, 24, 206, 142, 1, 237, 191, 230, 24, + 206, 142, 1, 165, 230, 24, 206, 142, 1, 206, 109, 230, 24, 206, 142, 1, + 191, 123, 230, 24, 206, 142, 1, 188, 230, 24, 206, 142, 1, 203, 165, 230, + 24, 206, 142, 1, 155, 230, 24, 206, 142, 1, 231, 240, 230, 24, 206, 142, + 1, 173, 230, 24, 206, 142, 1, 174, 230, 24, 206, 142, 1, 180, 230, 24, + 206, 142, 1, 193, 190, 230, 24, 206, 142, 1, 221, 137, 193, 190, 230, 24, + 206, 142, 1, 170, 230, 24, 206, 142, 1, 221, 137, 170, 230, 24, 206, 142, + 1, 214, 68, 230, 24, 206, 142, 1, 212, 101, 230, 24, 206, 142, 1, 195, + 188, 230, 24, 206, 142, 18, 65, 230, 24, 206, 142, 18, 68, 230, 24, 206, + 142, 18, 66, 230, 24, 206, 142, 18, 71, 230, 24, 206, 142, 18, 74, 230, + 24, 206, 142, 87, 205, 173, 230, 24, 206, 142, 87, 215, 7, 221, 178, 230, + 24, 206, 142, 3, 230, 18, 230, 24, 206, 142, 3, 199, 218, 230, 24, 206, + 142, 3, 199, 192, 230, 24, 206, 142, 3, 199, 172, 230, 24, 206, 142, 17, + 191, 77, 230, 24, 206, 142, 17, 107, 230, 24, 206, 142, 17, 109, 230, 24, + 206, 142, 17, 138, 230, 24, 206, 142, 17, 134, 230, 24, 206, 142, 17, + 149, 230, 24, 206, 142, 17, 169, 230, 24, 206, 142, 17, 175, 230, 24, + 206, 142, 17, 171, 230, 24, 206, 142, 17, 178, 206, 46, 17, 107, 206, 46, + 17, 109, 206, 46, 17, 138, 206, 46, 17, 134, 206, 46, 17, 149, 206, 46, + 17, 169, 206, 46, 17, 175, 206, 46, 17, 171, 206, 46, 17, 178, 206, 46, + 31, 199, 95, 206, 46, 31, 197, 32, 206, 46, 31, 198, 249, 206, 46, 31, + 232, 135, 206, 46, 31, 233, 15, 206, 46, 31, 202, 120, 206, 46, 31, 203, + 241, 206, 46, 31, 234, 153, 206, 46, 31, 213, 169, 206, 46, 31, 91, 228, + 140, 206, 46, 31, 105, 228, 140, 206, 46, 31, 115, 228, 140, 206, 46, 31, + 232, 128, 228, 140, 206, 46, 31, 232, 226, 228, 140, 206, 46, 31, 202, + 136, 228, 140, 206, 46, 31, 203, 247, 228, 140, 206, 46, 31, 234, 164, + 228, 140, 206, 46, 31, 213, 175, 228, 140, 206, 46, 232, 118, 91, 230, + 70, 206, 46, 232, 118, 91, 208, 22, 206, 46, 232, 118, 91, 199, 0, 206, + 46, 232, 118, 105, 198, 253, 192, 39, 1, 234, 124, 192, 39, 1, 249, 17, + 192, 39, 1, 210, 63, 192, 39, 1, 209, 214, 192, 39, 1, 199, 33, 192, 39, + 1, 205, 68, 192, 39, 1, 243, 16, 192, 39, 1, 243, 83, 192, 39, 1, 243, + 97, 192, 39, 1, 229, 177, 192, 39, 1, 192, 220, 192, 39, 1, 238, 3, 192, + 39, 1, 191, 108, 192, 39, 1, 165, 192, 39, 1, 207, 6, 192, 39, 1, 191, + 123, 192, 39, 1, 223, 32, 192, 39, 1, 202, 174, 192, 39, 1, 203, 69, 192, + 39, 1, 205, 192, 192, 39, 1, 238, 26, 192, 39, 1, 190, 190, 192, 39, 1, + 191, 87, 192, 39, 1, 233, 184, 192, 39, 1, 192, 208, 192, 39, 1, 233, + 109, 192, 39, 1, 195, 188, 192, 39, 1, 195, 189, 251, 157, 20, 192, 39, + 1, 208, 89, 192, 39, 1, 222, 106, 192, 39, 1, 221, 212, 192, 39, 1, 231, + 227, 192, 39, 1, 220, 35, 192, 39, 1, 216, 46, 192, 39, 1, 212, 130, 192, + 39, 1, 196, 120, 192, 39, 1, 193, 133, 192, 39, 1, 210, 250, 192, 39, 1, + 233, 224, 192, 39, 1, 229, 252, 192, 39, 1, 191, 240, 192, 39, 1, 233, + 255, 192, 39, 33, 230, 58, 77, 192, 39, 33, 217, 142, 77, 192, 39, 228, + 86, 77, 192, 39, 1, 220, 36, 4, 75, 58, 192, 39, 1, 191, 241, 4, 243, 2, + 58, 9, 2, 130, 193, 23, 205, 171, 9, 2, 130, 193, 23, 208, 79, 9, 2, 130, + 193, 23, 217, 141, 39, 202, 28, 1, 251, 190, 39, 202, 28, 1, 53, 251, + 190, 39, 202, 28, 1, 248, 211, 39, 202, 28, 1, 53, 248, 211, 39, 202, 28, + 1, 231, 38, 39, 202, 28, 1, 229, 245, 39, 202, 28, 1, 53, 229, 245, 39, + 202, 28, 1, 193, 133, 39, 202, 28, 1, 191, 91, 39, 202, 28, 1, 229, 184, + 39, 202, 28, 1, 191, 249, 39, 202, 28, 1, 222, 75, 39, 202, 28, 1, 220, + 26, 39, 202, 28, 1, 216, 193, 39, 202, 28, 1, 212, 130, 39, 202, 28, 1, + 53, 212, 130, 39, 202, 28, 1, 53, 212, 131, 4, 81, 199, 215, 39, 202, 28, + 1, 205, 148, 39, 202, 28, 1, 250, 126, 39, 202, 28, 1, 251, 157, 250, + 126, 39, 202, 28, 1, 210, 63, 39, 202, 28, 1, 205, 189, 39, 202, 28, 1, + 53, 205, 189, 39, 202, 28, 1, 53, 205, 190, 4, 81, 199, 215, 39, 202, 28, + 1, 207, 36, 39, 202, 28, 1, 203, 69, 39, 202, 28, 1, 199, 159, 39, 202, + 28, 1, 53, 199, 159, 39, 202, 28, 1, 53, 199, 160, 4, 81, 199, 215, 39, + 202, 28, 31, 107, 39, 202, 28, 31, 109, 39, 202, 28, 31, 138, 39, 202, + 28, 31, 134, 39, 202, 28, 31, 149, 39, 202, 28, 31, 199, 95, 39, 202, 28, + 31, 197, 32, 39, 202, 28, 31, 198, 249, 39, 202, 28, 31, 91, 228, 140, + 39, 202, 28, 232, 118, 91, 230, 70, 39, 202, 28, 34, 250, 125, 202, 28, + 1, 251, 190, 202, 28, 1, 248, 211, 202, 28, 1, 231, 38, 202, 28, 1, 229, + 245, 202, 28, 1, 193, 133, 202, 28, 1, 191, 91, 202, 28, 1, 229, 184, + 202, 28, 1, 191, 249, 202, 28, 1, 222, 75, 202, 28, 1, 220, 26, 202, 28, + 1, 216, 193, 202, 28, 1, 212, 130, 202, 28, 1, 205, 148, 202, 28, 1, 250, + 126, 202, 28, 1, 210, 63, 202, 28, 1, 205, 189, 202, 28, 1, 207, 37, 202, + 28, 1, 203, 69, 202, 28, 1, 199, 159, 202, 28, 1, 233, 30, 202, 28, 1, + 219, 182, 202, 28, 223, 149, 203, 69, 202, 28, 33, 75, 60, 202, 28, 33, + 105, 185, 60, 202, 28, 33, 75, 58, 202, 28, 33, 105, 185, 58, 202, 28, + 33, 238, 165, 58, 202, 28, 33, 238, 165, 60, 202, 28, 33, 228, 251, 58, + 202, 28, 33, 228, 251, 60, 202, 28, 33, 179, 228, 251, 60, 202, 28, 33, + 207, 39, 60, 202, 28, 33, 201, 28, 60, 202, 28, 31, 107, 202, 28, 31, + 199, 95, 202, 28, 31, 197, 32, 202, 28, 31, 91, 228, 140, 202, 28, 208, + 152, 105, 81, 249, 76, 202, 28, 208, 152, 105, 81, 249, 77, 4, 236, 138, + 202, 28, 208, 152, 243, 11, 4, 236, 140, 202, 28, 208, 152, 105, 243, 8, + 4, 236, 138, 202, 28, 208, 152, 132, 243, 11, 4, 236, 140, 39, 196, 19, + 1, 251, 190, 39, 196, 19, 1, 248, 211, 39, 196, 19, 1, 231, 37, 39, 196, + 19, 1, 193, 133, 39, 196, 19, 1, 191, 91, 39, 196, 19, 1, 53, 229, 184, + 39, 196, 19, 1, 191, 249, 39, 196, 19, 1, 222, 75, 39, 196, 19, 1, 220, + 26, 39, 196, 19, 1, 216, 193, 39, 196, 19, 1, 212, 130, 39, 196, 19, 1, + 205, 148, 39, 196, 19, 1, 210, 63, 39, 196, 19, 1, 205, 189, 39, 196, 19, + 1, 207, 38, 39, 196, 19, 1, 203, 69, 39, 196, 19, 1, 199, 159, 39, 196, + 19, 1, 219, 182, 39, 196, 19, 33, 75, 58, 39, 196, 19, 33, 75, 60, 39, + 196, 19, 33, 105, 185, 58, 39, 196, 19, 33, 105, 185, 60, 39, 196, 19, + 208, 152, 164, 39, 196, 19, 208, 152, 105, 249, 76, 39, 196, 19, 208, + 152, 105, 236, 138, 39, 196, 19, 208, 152, 232, 128, 236, 138, 243, 61, + 1, 251, 190, 243, 61, 1, 2, 251, 190, 243, 61, 1, 248, 211, 243, 61, 1, + 231, 38, 243, 61, 1, 237, 252, 243, 61, 1, 229, 245, 243, 61, 1, 193, + 133, 243, 61, 1, 238, 174, 193, 133, 243, 61, 1, 191, 91, 243, 61, 1, + 229, 184, 243, 61, 1, 191, 249, 243, 61, 1, 222, 75, 243, 61, 1, 220, 26, + 243, 61, 1, 216, 193, 243, 61, 1, 212, 130, 243, 61, 1, 205, 148, 243, + 61, 1, 250, 126, 243, 61, 1, 210, 63, 243, 61, 1, 207, 38, 243, 61, 1, + 203, 69, 243, 61, 1, 199, 159, 243, 61, 31, 107, 243, 61, 31, 109, 243, + 61, 31, 138, 243, 61, 31, 134, 243, 61, 31, 199, 95, 243, 61, 31, 197, + 32, 243, 61, 31, 91, 228, 140, 234, 116, 1, 251, 190, 234, 116, 1, 248, + 211, 234, 116, 1, 231, 38, 234, 116, 1, 237, 252, 234, 116, 1, 229, 245, + 234, 116, 1, 193, 133, 234, 116, 1, 191, 91, 234, 116, 1, 229, 184, 234, + 116, 1, 199, 69, 234, 116, 1, 191, 249, 234, 116, 1, 222, 75, 234, 116, + 1, 220, 26, 234, 116, 1, 216, 193, 234, 116, 1, 212, 130, 234, 116, 1, + 205, 148, 234, 116, 1, 250, 126, 234, 116, 1, 210, 63, 234, 116, 1, 205, + 189, 234, 116, 1, 208, 37, 234, 116, 1, 207, 38, 234, 116, 1, 203, 69, + 234, 116, 1, 199, 159, 234, 116, 34, 191, 90, 162, 3, 247, 119, 162, 3, + 251, 71, 162, 3, 195, 35, 162, 3, 222, 237, 162, 3, 196, 75, 162, 1, 65, + 162, 1, 252, 206, 162, 1, 68, 162, 1, 223, 199, 162, 1, 66, 162, 1, 196, + 30, 162, 1, 117, 146, 162, 1, 117, 206, 110, 162, 1, 117, 172, 162, 1, + 117, 219, 74, 162, 1, 71, 162, 1, 251, 236, 162, 1, 74, 162, 1, 250, 163, + 162, 1, 155, 162, 1, 221, 215, 162, 1, 231, 240, 162, 1, 231, 91, 162, 1, + 214, 68, 162, 1, 247, 160, 162, 1, 247, 1, 162, 1, 223, 32, 162, 1, 222, + 252, 162, 1, 212, 101, 162, 1, 197, 132, 162, 1, 197, 120, 162, 1, 237, + 191, 162, 1, 237, 175, 162, 1, 213, 79, 162, 1, 190, 190, 162, 1, 199, + 49, 162, 1, 238, 32, 162, 1, 237, 68, 162, 1, 180, 162, 1, 168, 162, 1, + 209, 228, 162, 1, 249, 153, 162, 1, 248, 203, 162, 1, 174, 162, 1, 170, + 162, 1, 165, 162, 1, 173, 162, 1, 195, 188, 162, 1, 203, 165, 162, 1, + 201, 175, 162, 1, 188, 162, 1, 140, 162, 1, 219, 73, 162, 1, 39, 44, 219, + 62, 162, 1, 39, 44, 206, 109, 162, 1, 39, 44, 213, 61, 162, 18, 3, 252, + 206, 162, 18, 3, 248, 197, 252, 206, 162, 18, 3, 68, 162, 18, 3, 223, + 199, 162, 18, 3, 66, 162, 18, 3, 196, 30, 162, 18, 3, 117, 146, 162, 18, + 3, 117, 206, 110, 162, 18, 3, 117, 172, 162, 18, 3, 117, 219, 74, 162, + 18, 3, 71, 162, 18, 3, 251, 236, 162, 18, 3, 74, 162, 18, 3, 250, 163, + 162, 195, 40, 162, 237, 238, 162, 55, 237, 238, 162, 208, 152, 236, 140, + 162, 208, 152, 55, 236, 140, 162, 208, 152, 219, 112, 162, 208, 152, 238, + 228, 164, 162, 208, 152, 218, 246, 162, 31, 107, 162, 31, 109, 162, 31, + 138, 162, 31, 134, 162, 31, 149, 162, 31, 169, 162, 31, 175, 162, 31, + 171, 162, 31, 178, 162, 31, 199, 95, 162, 31, 197, 32, 162, 31, 198, 249, + 162, 31, 232, 135, 162, 31, 233, 15, 162, 31, 202, 120, 162, 31, 203, + 241, 162, 31, 234, 153, 162, 31, 213, 169, 162, 31, 91, 228, 140, 162, + 31, 91, 189, 162, 17, 191, 77, 162, 17, 107, 162, 17, 109, 162, 17, 138, + 162, 17, 134, 162, 17, 149, 162, 17, 169, 162, 17, 175, 162, 17, 171, + 162, 17, 178, 162, 3, 39, 44, 195, 40, 162, 1, 39, 44, 203, 40, 71, 162, + 1, 39, 44, 203, 40, 74, 162, 18, 3, 39, 44, 203, 40, 71, 162, 18, 3, 39, + 44, 203, 40, 74, 162, 1, 39, 44, 219, 73, 162, 31, 222, 196, 222, 99, 3, + 247, 119, 222, 99, 3, 251, 71, 222, 99, 3, 195, 35, 222, 99, 1, 65, 222, + 99, 1, 252, 206, 222, 99, 1, 68, 222, 99, 1, 223, 199, 222, 99, 1, 66, + 222, 99, 1, 196, 30, 222, 99, 1, 71, 222, 99, 1, 251, 236, 222, 99, 1, + 74, 222, 99, 1, 250, 163, 222, 99, 1, 155, 222, 99, 1, 221, 215, 222, 99, + 1, 231, 240, 222, 99, 1, 231, 91, 222, 99, 1, 214, 68, 222, 99, 1, 247, + 160, 222, 99, 1, 247, 1, 222, 99, 1, 223, 32, 222, 99, 1, 222, 252, 222, + 99, 1, 212, 101, 222, 99, 1, 197, 132, 222, 99, 1, 197, 120, 222, 99, 1, + 237, 191, 222, 99, 1, 237, 180, 222, 99, 1, 237, 175, 222, 99, 1, 207, 6, + 222, 99, 1, 213, 79, 222, 99, 1, 190, 190, 222, 99, 1, 199, 49, 222, 99, + 1, 238, 32, 222, 99, 1, 237, 68, 222, 99, 1, 180, 222, 99, 1, 168, 222, + 99, 1, 209, 228, 222, 99, 1, 249, 153, 222, 99, 1, 248, 203, 222, 99, 1, + 174, 222, 99, 1, 170, 222, 99, 1, 165, 222, 99, 1, 173, 222, 99, 1, 195, + 188, 222, 99, 1, 203, 165, 222, 99, 1, 201, 175, 222, 99, 1, 188, 222, + 99, 1, 140, 222, 99, 18, 3, 252, 206, 222, 99, 18, 3, 68, 222, 99, 18, 3, + 223, 199, 222, 99, 18, 3, 66, 222, 99, 18, 3, 196, 30, 222, 99, 18, 3, + 71, 222, 99, 18, 3, 251, 236, 222, 99, 18, 3, 74, 222, 99, 18, 3, 250, + 163, 222, 99, 3, 195, 40, 222, 99, 3, 212, 141, 222, 99, 252, 68, 56, + 222, 99, 234, 69, 56, 222, 99, 31, 56, 222, 99, 205, 54, 77, 222, 99, 55, + 205, 54, 77, 222, 99, 237, 238, 222, 99, 55, 237, 238, 222, 99, 18, 3, + 117, 146, 222, 99, 31, 3, 58, 202, 12, 202, 20, 1, 205, 182, 202, 12, + 202, 20, 1, 199, 219, 202, 12, 202, 20, 1, 249, 123, 202, 12, 202, 20, 1, + 247, 149, 202, 12, 202, 20, 1, 238, 12, 202, 12, 202, 20, 1, 231, 225, + 202, 12, 202, 20, 1, 217, 120, 202, 12, 202, 20, 1, 214, 65, 202, 12, + 202, 20, 1, 220, 99, 202, 12, 202, 20, 1, 214, 237, 202, 12, 202, 20, 1, + 195, 184, 202, 12, 202, 20, 1, 210, 200, 202, 12, 202, 20, 1, 192, 121, + 202, 12, 202, 20, 1, 207, 160, 202, 12, 202, 20, 1, 230, 81, 202, 12, + 202, 20, 1, 222, 104, 202, 12, 202, 20, 1, 223, 26, 202, 12, 202, 20, 1, + 212, 98, 202, 12, 202, 20, 1, 251, 245, 202, 12, 202, 20, 1, 234, 186, + 202, 12, 202, 20, 1, 223, 200, 202, 12, 202, 20, 1, 196, 141, 202, 12, + 202, 20, 1, 211, 136, 202, 12, 202, 20, 1, 234, 173, 202, 12, 202, 20, 1, + 217, 136, 202, 12, 202, 20, 17, 191, 77, 202, 12, 202, 20, 17, 107, 202, + 12, 202, 20, 17, 109, 202, 12, 202, 20, 17, 138, 202, 12, 202, 20, 17, + 134, 202, 12, 202, 20, 17, 149, 202, 12, 202, 20, 17, 169, 202, 12, 202, + 20, 17, 175, 202, 12, 202, 20, 17, 171, 202, 12, 202, 20, 17, 178, 246, + 251, 3, 247, 119, 246, 251, 3, 251, 71, 246, 251, 3, 195, 35, 246, 251, + 1, 252, 206, 246, 251, 1, 68, 246, 251, 1, 66, 246, 251, 1, 71, 246, 251, + 1, 222, 127, 246, 251, 1, 221, 214, 246, 251, 1, 231, 237, 246, 251, 1, + 231, 90, 246, 251, 1, 214, 67, 246, 251, 1, 247, 159, 246, 251, 1, 247, + 0, 246, 251, 1, 223, 31, 246, 251, 1, 222, 251, 246, 251, 1, 212, 100, + 246, 251, 1, 197, 131, 246, 251, 1, 197, 119, 246, 251, 1, 237, 190, 246, + 251, 1, 237, 174, 246, 251, 1, 213, 78, 246, 251, 1, 199, 245, 246, 251, + 1, 199, 48, 246, 251, 1, 238, 31, 246, 251, 1, 237, 67, 246, 251, 1, 214, + 250, 246, 251, 1, 210, 220, 246, 251, 1, 209, 227, 246, 251, 1, 249, 151, + 246, 251, 1, 248, 202, 246, 251, 1, 217, 151, 246, 251, 1, 191, 174, 246, + 251, 1, 192, 140, 246, 251, 1, 207, 178, 246, 251, 1, 220, 125, 246, 251, + 1, 193, 181, 246, 251, 1, 205, 197, 246, 251, 1, 230, 91, 246, 251, 18, + 3, 65, 246, 251, 18, 3, 68, 246, 251, 18, 3, 223, 199, 246, 251, 18, 3, + 66, 246, 251, 18, 3, 196, 30, 246, 251, 18, 3, 71, 246, 251, 18, 3, 251, + 236, 246, 251, 18, 3, 74, 246, 251, 18, 3, 250, 163, 246, 251, 18, 3, + 211, 133, 246, 251, 187, 77, 246, 251, 250, 164, 77, 246, 251, 195, 40, + 246, 251, 217, 149, 246, 251, 17, 191, 77, 246, 251, 17, 107, 246, 251, + 17, 109, 246, 251, 17, 138, 246, 251, 17, 134, 246, 251, 17, 149, 246, + 251, 17, 169, 246, 251, 17, 175, 246, 251, 17, 171, 246, 251, 17, 178, + 246, 251, 205, 54, 77, 246, 251, 237, 238, 246, 251, 55, 237, 238, 246, + 251, 208, 13, 77, 246, 251, 1, 219, 158, 246, 251, 18, 3, 252, 206, 246, + 251, 18, 3, 234, 166, 246, 251, 1, 195, 187, 217, 118, 1, 65, 217, 118, + 1, 68, 217, 118, 1, 66, 217, 118, 1, 71, 217, 118, 1, 74, 217, 118, 1, + 155, 217, 118, 1, 221, 215, 217, 118, 1, 231, 240, 217, 118, 1, 231, 91, + 217, 118, 1, 247, 160, 217, 118, 1, 247, 1, 217, 118, 1, 223, 32, 217, + 118, 1, 222, 252, 217, 118, 1, 212, 101, 217, 118, 1, 197, 132, 217, 118, + 1, 197, 120, 217, 118, 1, 237, 191, 217, 118, 1, 237, 175, 217, 118, 1, + 213, 79, 217, 118, 1, 190, 190, 217, 118, 1, 199, 49, 217, 118, 1, 238, + 32, 217, 118, 1, 237, 68, 217, 118, 1, 180, 217, 118, 1, 168, 217, 118, + 1, 209, 228, 217, 118, 1, 249, 153, 217, 118, 1, 248, 203, 217, 118, 1, + 174, 217, 118, 1, 165, 217, 118, 1, 173, 217, 118, 1, 195, 188, 217, 118, + 1, 188, 217, 118, 1, 140, 217, 118, 1, 206, 109, 217, 118, 3, 212, 141, + 217, 118, 252, 68, 56, 217, 118, 205, 54, 77, 217, 118, 34, 203, 15, 203, + 129, 3, 247, 119, 203, 129, 3, 251, 71, 203, 129, 3, 195, 35, 203, 129, + 1, 65, 203, 129, 1, 252, 206, 203, 129, 1, 68, 203, 129, 1, 223, 199, + 203, 129, 1, 66, 203, 129, 1, 196, 30, 203, 129, 1, 117, 146, 203, 129, + 1, 117, 206, 110, 203, 129, 1, 117, 172, 203, 129, 1, 117, 219, 74, 203, + 129, 1, 71, 203, 129, 1, 251, 236, 203, 129, 1, 74, 203, 129, 1, 250, + 163, 203, 129, 1, 155, 203, 129, 1, 221, 215, 203, 129, 1, 231, 240, 203, + 129, 1, 231, 91, 203, 129, 1, 214, 68, 203, 129, 1, 247, 160, 203, 129, + 1, 247, 1, 203, 129, 1, 223, 32, 203, 129, 1, 222, 252, 203, 129, 1, 212, + 101, 203, 129, 1, 197, 132, 203, 129, 1, 197, 120, 203, 129, 1, 237, 191, + 203, 129, 1, 237, 175, 203, 129, 1, 213, 79, 203, 129, 1, 190, 190, 203, + 129, 1, 199, 49, 203, 129, 1, 238, 32, 203, 129, 1, 237, 68, 203, 129, 1, + 180, 203, 129, 1, 168, 203, 129, 1, 209, 228, 203, 129, 1, 249, 153, 203, + 129, 1, 248, 203, 203, 129, 1, 174, 203, 129, 1, 170, 203, 129, 1, 165, + 203, 129, 1, 173, 203, 129, 1, 219, 73, 203, 129, 1, 195, 188, 203, 129, + 1, 203, 165, 203, 129, 1, 201, 175, 203, 129, 1, 188, 203, 129, 1, 140, + 203, 129, 18, 3, 252, 206, 203, 129, 18, 3, 68, 203, 129, 18, 3, 223, + 199, 203, 129, 18, 3, 66, 203, 129, 18, 3, 196, 30, 203, 129, 18, 3, 117, + 146, 203, 129, 18, 3, 117, 206, 110, 203, 129, 18, 3, 117, 172, 203, 129, + 18, 3, 117, 219, 74, 203, 129, 18, 3, 71, 203, 129, 18, 3, 251, 236, 203, + 129, 18, 3, 74, 203, 129, 18, 3, 250, 163, 203, 129, 3, 195, 40, 203, + 129, 3, 250, 145, 203, 129, 3, 222, 237, 203, 129, 3, 196, 75, 203, 129, + 211, 113, 203, 129, 237, 238, 203, 129, 55, 237, 238, 203, 129, 252, 68, + 56, 203, 129, 204, 10, 203, 129, 205, 138, 77, 203, 129, 3, 212, 141, + 203, 129, 18, 52, 77, 203, 129, 233, 201, 203, 40, 18, 77, 203, 129, 200, + 162, 77, 203, 129, 18, 3, 208, 207, 71, 203, 129, 3, 223, 93, 247, 119, + 203, 129, 17, 191, 77, 203, 129, 17, 107, 203, 129, 17, 109, 203, 129, + 17, 138, 203, 129, 17, 134, 203, 129, 17, 149, 203, 129, 17, 169, 203, + 129, 17, 175, 203, 129, 17, 171, 203, 129, 17, 178, 203, 129, 234, 146, + 203, 129, 3, 202, 210, 203, 129, 229, 227, 203, 129, 239, 29, 56, 203, + 129, 205, 54, 217, 55, 203, 129, 205, 54, 217, 54, 166, 251, 14, 17, 107, + 166, 251, 14, 17, 109, 166, 251, 14, 17, 138, 166, 251, 14, 17, 134, 166, + 251, 14, 17, 149, 166, 251, 14, 17, 169, 166, 251, 14, 17, 175, 166, 251, + 14, 17, 171, 166, 251, 14, 17, 178, 166, 251, 14, 31, 199, 95, 166, 251, + 14, 31, 197, 32, 166, 251, 14, 31, 198, 249, 166, 251, 14, 31, 232, 135, + 166, 251, 14, 31, 233, 15, 166, 251, 14, 31, 202, 120, 166, 251, 14, 31, + 203, 241, 166, 251, 14, 31, 234, 153, 166, 251, 14, 31, 213, 169, 166, + 251, 14, 31, 91, 228, 140, 166, 251, 14, 31, 91, 189, 221, 182, 1, 65, + 221, 182, 1, 252, 206, 221, 182, 1, 68, 221, 182, 1, 66, 221, 182, 1, 71, + 221, 182, 1, 251, 236, 221, 182, 1, 74, 221, 182, 1, 250, 163, 221, 182, + 1, 155, 221, 182, 1, 221, 215, 221, 182, 1, 231, 240, 221, 182, 1, 231, + 127, 221, 182, 1, 231, 91, 221, 182, 1, 214, 68, 221, 182, 1, 247, 160, + 221, 182, 1, 247, 1, 221, 182, 1, 223, 32, 221, 182, 1, 222, 230, 221, + 182, 1, 212, 101, 221, 182, 1, 197, 132, 221, 182, 1, 197, 120, 221, 182, + 1, 237, 191, 221, 182, 1, 237, 175, 221, 182, 1, 213, 79, 221, 182, 1, + 190, 190, 221, 182, 1, 199, 49, 221, 182, 1, 238, 32, 221, 182, 1, 237, + 181, 221, 182, 1, 237, 68, 221, 182, 1, 180, 221, 182, 1, 168, 221, 182, + 1, 209, 228, 221, 182, 1, 249, 153, 221, 182, 1, 249, 53, 221, 182, 1, + 248, 203, 221, 182, 1, 174, 221, 182, 1, 170, 221, 182, 1, 165, 221, 182, + 1, 173, 221, 182, 1, 195, 188, 221, 182, 1, 188, 221, 182, 1, 140, 221, + 182, 1, 219, 73, 221, 182, 18, 3, 252, 206, 221, 182, 18, 3, 68, 221, + 182, 18, 3, 223, 199, 221, 182, 18, 3, 66, 221, 182, 18, 3, 71, 221, 182, + 18, 3, 251, 236, 221, 182, 18, 3, 74, 221, 182, 18, 3, 250, 163, 221, + 182, 3, 251, 71, 221, 182, 3, 195, 40, 221, 182, 3, 212, 141, 221, 182, + 3, 203, 155, 221, 182, 237, 238, 221, 182, 55, 237, 238, 221, 182, 193, + 23, 204, 10, 221, 182, 205, 54, 77, 221, 182, 55, 205, 54, 77, 221, 182, + 252, 68, 56, 221, 182, 3, 200, 206, 221, 182, 1, 208, 96, 221, 182, 1, + 203, 40, 68, 221, 182, 18, 3, 117, 146, 215, 133, 1, 65, 215, 133, 1, 68, + 215, 133, 1, 66, 215, 133, 1, 71, 215, 133, 1, 155, 215, 133, 1, 221, + 215, 215, 133, 1, 231, 240, 215, 133, 1, 231, 91, 215, 133, 1, 247, 160, + 215, 133, 1, 247, 1, 215, 133, 1, 223, 32, 215, 133, 1, 222, 230, 215, + 133, 1, 212, 101, 215, 133, 1, 197, 132, 215, 133, 1, 197, 120, 215, 133, + 1, 237, 191, 215, 133, 1, 237, 181, 215, 133, 1, 237, 175, 215, 133, 1, + 213, 79, 215, 133, 1, 190, 190, 215, 133, 1, 199, 49, 215, 133, 1, 238, + 32, 215, 133, 1, 237, 68, 215, 133, 1, 180, 215, 133, 1, 168, 215, 133, + 1, 209, 228, 215, 133, 1, 249, 153, 215, 133, 1, 248, 203, 215, 133, 1, + 174, 215, 133, 1, 170, 215, 133, 1, 165, 215, 133, 1, 173, 215, 133, 1, + 195, 188, 215, 133, 1, 188, 215, 133, 1, 140, 215, 133, 1, 206, 109, 215, + 133, 1, 207, 6, 215, 133, 205, 54, 77, 221, 172, 1, 65, 221, 172, 1, 252, + 206, 221, 172, 1, 68, 221, 172, 1, 223, 199, 221, 172, 1, 66, 221, 172, + 1, 196, 30, 221, 172, 1, 71, 221, 172, 1, 251, 236, 221, 172, 1, 74, 221, + 172, 1, 250, 163, 221, 172, 1, 155, 221, 172, 1, 221, 215, 221, 172, 1, + 231, 240, 221, 172, 1, 231, 127, 221, 172, 1, 231, 91, 221, 172, 1, 214, + 68, 221, 172, 1, 247, 160, 221, 172, 1, 247, 1, 221, 172, 1, 223, 32, + 221, 172, 1, 222, 230, 221, 172, 1, 222, 252, 221, 172, 1, 212, 101, 221, + 172, 1, 197, 132, 221, 172, 1, 197, 120, 221, 172, 1, 237, 191, 221, 172, + 1, 237, 181, 221, 172, 1, 206, 109, 221, 172, 1, 237, 175, 221, 172, 1, + 213, 79, 221, 172, 1, 190, 190, 221, 172, 1, 199, 49, 221, 172, 1, 238, + 32, 221, 172, 1, 237, 68, 221, 172, 1, 180, 221, 172, 1, 168, 221, 172, + 1, 209, 228, 221, 172, 1, 249, 153, 221, 172, 1, 249, 53, 221, 172, 1, + 248, 203, 221, 172, 1, 174, 221, 172, 1, 170, 221, 172, 1, 165, 221, 172, + 1, 173, 221, 172, 1, 195, 188, 221, 172, 1, 203, 165, 221, 172, 1, 188, + 221, 172, 1, 140, 221, 172, 3, 251, 71, 221, 172, 18, 3, 252, 206, 221, + 172, 18, 3, 68, 221, 172, 18, 3, 223, 199, 221, 172, 18, 3, 66, 221, 172, + 18, 3, 196, 30, 221, 172, 18, 3, 71, 221, 172, 18, 3, 251, 236, 221, 172, + 18, 3, 74, 221, 172, 18, 3, 250, 163, 221, 172, 3, 212, 141, 221, 172, 3, + 195, 40, 221, 172, 17, 191, 77, 221, 172, 17, 107, 221, 172, 17, 109, + 221, 172, 17, 138, 221, 172, 17, 134, 221, 172, 17, 149, 221, 172, 17, + 169, 221, 172, 17, 175, 221, 172, 17, 171, 221, 172, 17, 178, 230, 219, + 3, 33, 251, 72, 58, 230, 219, 3, 247, 119, 230, 219, 3, 251, 71, 230, + 219, 3, 195, 35, 230, 219, 1, 65, 230, 219, 1, 252, 206, 230, 219, 1, 68, + 230, 219, 1, 223, 199, 230, 219, 1, 66, 230, 219, 1, 196, 30, 230, 219, + 1, 117, 146, 230, 219, 1, 117, 172, 230, 219, 1, 234, 188, 230, 219, 1, + 251, 236, 230, 219, 1, 211, 87, 230, 219, 1, 250, 163, 230, 219, 1, 155, + 230, 219, 1, 221, 215, 230, 219, 1, 231, 240, 230, 219, 1, 231, 91, 230, + 219, 1, 214, 68, 230, 219, 1, 247, 160, 230, 219, 1, 247, 1, 230, 219, 1, + 223, 32, 230, 219, 1, 222, 252, 230, 219, 1, 212, 101, 230, 219, 1, 197, + 132, 230, 219, 1, 197, 120, 230, 219, 1, 237, 191, 230, 219, 1, 237, 175, + 230, 219, 1, 213, 79, 230, 219, 1, 190, 190, 230, 219, 1, 199, 49, 230, + 219, 1, 238, 32, 230, 219, 1, 237, 68, 230, 219, 1, 180, 230, 219, 1, + 168, 230, 219, 1, 209, 228, 230, 219, 1, 249, 153, 230, 219, 1, 248, 203, + 230, 219, 1, 174, 230, 219, 1, 170, 230, 219, 1, 165, 230, 219, 1, 173, + 230, 219, 1, 219, 73, 230, 219, 1, 195, 188, 230, 219, 1, 203, 165, 230, + 219, 1, 201, 175, 230, 219, 1, 188, 230, 219, 1, 140, 33, 248, 165, 60, + 230, 219, 3, 212, 141, 230, 219, 3, 250, 145, 230, 219, 18, 3, 252, 206, + 230, 219, 18, 3, 68, 230, 219, 18, 3, 223, 199, 230, 219, 18, 3, 66, 230, + 219, 18, 3, 196, 30, 230, 219, 18, 3, 117, 146, 230, 219, 18, 3, 117, + 206, 110, 230, 219, 18, 3, 234, 188, 230, 219, 18, 3, 251, 236, 230, 219, + 18, 3, 211, 87, 230, 219, 18, 3, 250, 163, 230, 219, 3, 195, 40, 230, + 219, 211, 113, 230, 219, 250, 164, 219, 198, 77, 230, 219, 3, 209, 79, + 230, 219, 1, 195, 150, 251, 71, 230, 219, 1, 195, 150, 55, 251, 71, 230, + 219, 1, 117, 206, 110, 230, 219, 1, 117, 219, 74, 230, 219, 18, 3, 117, + 172, 230, 219, 18, 3, 117, 219, 74, 33, 230, 219, 17, 191, 77, 33, 230, + 219, 17, 107, 33, 230, 219, 17, 109, 33, 230, 219, 17, 138, 33, 230, 219, + 17, 134, 33, 230, 219, 17, 149, 33, 230, 219, 17, 169, 33, 230, 219, 1, + 65, 33, 230, 219, 1, 155, 33, 230, 219, 1, 180, 33, 230, 219, 1, 195, 69, + 33, 230, 219, 1, 168, 214, 78, 1, 65, 214, 78, 1, 252, 206, 214, 78, 1, + 68, 214, 78, 1, 223, 199, 214, 78, 1, 66, 214, 78, 1, 196, 30, 214, 78, + 1, 117, 146, 214, 78, 1, 117, 206, 110, 214, 78, 1, 117, 172, 214, 78, 1, + 117, 219, 74, 214, 78, 1, 71, 214, 78, 1, 251, 236, 214, 78, 1, 74, 214, + 78, 1, 250, 163, 214, 78, 1, 155, 214, 78, 1, 221, 215, 214, 78, 1, 231, + 240, 214, 78, 1, 231, 91, 214, 78, 1, 214, 68, 214, 78, 1, 214, 17, 214, + 78, 1, 247, 160, 214, 78, 1, 247, 1, 214, 78, 1, 223, 32, 214, 78, 1, + 222, 252, 214, 78, 1, 212, 101, 214, 78, 1, 212, 83, 214, 78, 1, 197, + 132, 214, 78, 1, 197, 120, 214, 78, 1, 237, 191, 214, 78, 1, 237, 175, + 214, 78, 1, 213, 79, 214, 78, 1, 190, 190, 214, 78, 1, 199, 49, 214, 78, + 1, 238, 32, 214, 78, 1, 237, 68, 214, 78, 1, 180, 214, 78, 1, 213, 224, + 214, 78, 1, 168, 214, 78, 1, 209, 228, 214, 78, 1, 249, 153, 214, 78, 1, + 248, 203, 214, 78, 1, 174, 214, 78, 1, 216, 103, 214, 78, 1, 170, 214, + 78, 1, 165, 214, 78, 1, 207, 6, 214, 78, 1, 173, 214, 78, 1, 219, 159, + 214, 78, 1, 193, 190, 214, 78, 1, 203, 165, 214, 78, 1, 201, 175, 214, + 78, 1, 188, 214, 78, 1, 140, 214, 78, 18, 3, 252, 206, 214, 78, 18, 3, + 68, 214, 78, 18, 3, 223, 199, 214, 78, 18, 3, 66, 214, 78, 18, 3, 196, + 30, 214, 78, 18, 3, 117, 146, 214, 78, 18, 3, 117, 206, 110, 214, 78, 18, + 3, 117, 172, 214, 78, 18, 3, 117, 219, 74, 214, 78, 18, 3, 71, 214, 78, + 18, 3, 251, 236, 214, 78, 18, 3, 74, 214, 78, 18, 3, 250, 163, 214, 78, + 3, 195, 40, 214, 78, 3, 247, 119, 214, 78, 3, 251, 71, 214, 78, 3, 195, + 35, 214, 78, 3, 212, 141, 214, 78, 3, 250, 145, 214, 78, 3, 53, 251, 71, + 214, 78, 211, 113, 214, 78, 202, 209, 214, 78, 237, 238, 214, 78, 55, + 237, 238, 214, 78, 242, 74, 214, 78, 231, 204, 233, 3, 214, 78, 252, 68, + 56, 214, 78, 17, 191, 77, 214, 78, 17, 107, 214, 78, 17, 109, 214, 78, + 17, 138, 214, 78, 17, 134, 214, 78, 17, 149, 214, 78, 17, 169, 214, 78, + 17, 175, 214, 78, 17, 171, 214, 78, 17, 178, 214, 78, 55, 242, 74, 214, + 78, 209, 107, 77, 214, 78, 223, 119, 56, 214, 78, 205, 138, 77, 214, 78, + 1, 195, 150, 251, 71, 214, 78, 3, 222, 237, 214, 78, 3, 196, 75, 198, + 129, 251, 100, 198, 129, 1, 65, 198, 129, 1, 252, 206, 198, 129, 1, 68, + 198, 129, 1, 223, 199, 198, 129, 1, 66, 198, 129, 1, 196, 30, 198, 129, + 1, 117, 146, 198, 129, 1, 117, 206, 110, 198, 129, 1, 117, 172, 198, 129, + 1, 117, 219, 74, 198, 129, 1, 71, 198, 129, 1, 251, 236, 198, 129, 1, 74, + 198, 129, 1, 250, 163, 198, 129, 1, 155, 198, 129, 1, 221, 215, 198, 129, + 1, 231, 240, 198, 129, 1, 231, 91, 198, 129, 1, 214, 68, 198, 129, 1, + 247, 160, 198, 129, 1, 247, 1, 198, 129, 1, 223, 32, 198, 129, 1, 222, + 252, 198, 129, 1, 212, 101, 198, 129, 1, 197, 132, 198, 129, 1, 197, 120, + 198, 129, 1, 237, 191, 198, 129, 1, 237, 175, 198, 129, 1, 213, 79, 198, + 129, 1, 190, 190, 198, 129, 1, 199, 49, 198, 129, 1, 238, 32, 198, 129, + 1, 237, 68, 198, 129, 1, 180, 198, 129, 1, 168, 198, 129, 1, 209, 228, + 198, 129, 1, 249, 153, 198, 129, 1, 248, 203, 198, 129, 1, 174, 198, 129, + 1, 170, 198, 129, 1, 165, 198, 129, 1, 173, 198, 129, 1, 195, 188, 198, + 129, 1, 203, 165, 198, 129, 1, 201, 175, 198, 129, 1, 188, 198, 129, 1, + 140, 198, 129, 18, 3, 252, 206, 198, 129, 18, 3, 68, 198, 129, 18, 3, + 223, 199, 198, 129, 18, 3, 66, 198, 129, 18, 3, 196, 30, 198, 129, 18, 3, + 117, 146, 198, 129, 18, 3, 117, 206, 110, 198, 129, 18, 3, 117, 172, 198, + 129, 18, 3, 117, 219, 74, 198, 129, 18, 3, 71, 198, 129, 18, 3, 203, 40, + 71, 198, 129, 18, 3, 251, 236, 198, 129, 18, 3, 74, 198, 129, 18, 3, 203, + 40, 74, 198, 129, 18, 3, 250, 163, 198, 129, 3, 247, 119, 198, 129, 3, + 251, 71, 198, 129, 3, 195, 35, 198, 129, 3, 195, 40, 198, 129, 3, 212, + 141, 198, 129, 3, 250, 145, 198, 129, 230, 137, 198, 129, 252, 68, 56, + 198, 129, 211, 113, 198, 129, 17, 191, 77, 198, 129, 17, 107, 198, 129, + 17, 109, 198, 129, 17, 138, 198, 129, 17, 134, 198, 129, 17, 149, 198, + 129, 17, 169, 198, 129, 17, 175, 198, 129, 17, 171, 198, 129, 17, 178, + 202, 211, 1, 65, 202, 211, 1, 252, 206, 202, 211, 1, 68, 202, 211, 1, + 223, 199, 202, 211, 1, 66, 202, 211, 1, 196, 30, 202, 211, 1, 117, 146, + 202, 211, 1, 117, 206, 110, 202, 211, 1, 117, 172, 202, 211, 1, 117, 219, + 74, 202, 211, 1, 71, 202, 211, 1, 251, 236, 202, 211, 1, 74, 202, 211, 1, + 250, 163, 202, 211, 1, 155, 202, 211, 1, 221, 215, 202, 211, 1, 231, 240, + 202, 211, 1, 231, 91, 202, 211, 1, 214, 68, 202, 211, 1, 247, 160, 202, + 211, 1, 247, 1, 202, 211, 1, 223, 32, 202, 211, 1, 222, 252, 202, 211, 1, + 212, 101, 202, 211, 1, 197, 132, 202, 211, 1, 197, 120, 202, 211, 1, 237, + 191, 202, 211, 1, 237, 175, 202, 211, 1, 213, 79, 202, 211, 1, 190, 190, + 202, 211, 1, 199, 49, 202, 211, 1, 238, 32, 202, 211, 1, 237, 68, 202, + 211, 1, 180, 202, 211, 1, 168, 202, 211, 1, 209, 228, 202, 211, 1, 249, + 153, 202, 211, 1, 248, 203, 202, 211, 1, 174, 202, 211, 1, 170, 202, 211, + 1, 165, 202, 211, 1, 173, 202, 211, 1, 195, 188, 202, 211, 1, 203, 165, + 202, 211, 1, 201, 175, 202, 211, 1, 188, 202, 211, 1, 140, 202, 211, 18, + 3, 252, 206, 202, 211, 18, 3, 68, 202, 211, 18, 3, 223, 199, 202, 211, + 18, 3, 66, 202, 211, 18, 3, 196, 30, 202, 211, 18, 3, 117, 146, 202, 211, + 18, 3, 117, 206, 110, 202, 211, 18, 3, 71, 202, 211, 18, 3, 251, 236, + 202, 211, 18, 3, 74, 202, 211, 18, 3, 250, 163, 202, 211, 3, 247, 119, + 202, 211, 3, 251, 71, 202, 211, 3, 195, 35, 202, 211, 3, 195, 40, 202, + 211, 3, 212, 141, 202, 211, 3, 202, 210, 202, 211, 237, 238, 202, 211, + 55, 237, 238, 202, 211, 204, 11, 236, 140, 202, 211, 204, 11, 164, 202, + 211, 207, 46, 217, 55, 202, 211, 207, 46, 217, 54, 202, 211, 207, 46, + 217, 53, 202, 211, 234, 95, 79, 199, 54, 77, 202, 211, 205, 54, 87, 4, + 197, 236, 23, 196, 221, 211, 41, 202, 211, 205, 54, 87, 4, 197, 236, 23, + 235, 138, 238, 226, 202, 211, 205, 54, 87, 4, 207, 120, 23, 235, 138, + 238, 226, 202, 211, 205, 54, 87, 4, 207, 120, 23, 235, 138, 55, 238, 226, + 202, 211, 205, 54, 87, 4, 207, 120, 23, 235, 138, 197, 225, 238, 226, + 202, 211, 205, 54, 87, 55, 206, 188, 202, 211, 205, 54, 87, 55, 206, 189, + 4, 207, 119, 202, 211, 205, 54, 87, 4, 55, 238, 226, 202, 211, 205, 54, + 87, 4, 197, 225, 238, 226, 202, 211, 205, 54, 87, 4, 208, 26, 238, 226, + 202, 211, 205, 54, 87, 4, 204, 8, 238, 226, 202, 211, 205, 54, 87, 4, + 243, 8, 23, 207, 119, 202, 211, 205, 54, 87, 4, 243, 8, 23, 105, 234, 97, + 202, 211, 205, 54, 87, 4, 243, 8, 23, 232, 128, 234, 97, 202, 211, 1, + 198, 226, 251, 157, 68, 202, 211, 1, 197, 15, 251, 157, 68, 202, 211, 1, + 197, 15, 251, 157, 223, 199, 202, 211, 1, 251, 157, 66, 202, 211, 18, 3, + 251, 157, 66, 202, 211, 18, 3, 251, 157, 196, 30, 215, 253, 1, 65, 215, + 253, 1, 252, 206, 215, 253, 1, 68, 215, 253, 1, 223, 199, 215, 253, 1, + 66, 215, 253, 1, 196, 30, 215, 253, 1, 117, 146, 215, 253, 1, 117, 206, + 110, 215, 253, 1, 117, 172, 215, 253, 1, 117, 219, 74, 215, 253, 1, 71, + 215, 253, 1, 251, 236, 215, 253, 1, 74, 215, 253, 1, 250, 163, 215, 253, + 1, 155, 215, 253, 1, 221, 215, 215, 253, 1, 231, 240, 215, 253, 1, 231, + 91, 215, 253, 1, 214, 68, 215, 253, 1, 247, 160, 215, 253, 1, 247, 1, + 215, 253, 1, 223, 32, 215, 253, 1, 222, 252, 215, 253, 1, 212, 101, 215, + 253, 1, 197, 132, 215, 253, 1, 197, 120, 215, 253, 1, 237, 191, 215, 253, + 1, 237, 175, 215, 253, 1, 213, 79, 215, 253, 1, 190, 190, 215, 253, 1, + 199, 49, 215, 253, 1, 238, 32, 215, 253, 1, 237, 68, 215, 253, 1, 180, + 215, 253, 1, 168, 215, 253, 1, 209, 228, 215, 253, 1, 249, 153, 215, 253, + 1, 248, 203, 215, 253, 1, 174, 215, 253, 1, 170, 215, 253, 1, 165, 215, + 253, 1, 173, 215, 253, 1, 195, 188, 215, 253, 1, 203, 165, 215, 253, 1, + 201, 175, 215, 253, 1, 188, 215, 253, 1, 140, 215, 253, 1, 219, 73, 215, + 253, 18, 3, 252, 206, 215, 253, 18, 3, 68, 215, 253, 18, 3, 223, 199, + 215, 253, 18, 3, 66, 215, 253, 18, 3, 196, 30, 215, 253, 18, 3, 117, 146, + 215, 253, 18, 3, 117, 206, 110, 215, 253, 18, 3, 117, 172, 215, 253, 18, + 3, 117, 219, 74, 215, 253, 18, 3, 71, 215, 253, 18, 3, 251, 236, 215, + 253, 18, 3, 74, 215, 253, 18, 3, 250, 163, 215, 253, 3, 251, 71, 215, + 253, 3, 195, 35, 215, 253, 3, 195, 40, 215, 253, 3, 251, 11, 215, 253, + 237, 238, 215, 253, 55, 237, 238, 215, 253, 252, 68, 56, 215, 253, 3, + 228, 127, 215, 253, 17, 191, 77, 215, 253, 17, 107, 215, 253, 17, 109, + 215, 253, 17, 138, 215, 253, 17, 134, 215, 253, 17, 149, 215, 253, 17, + 169, 215, 253, 17, 175, 215, 253, 17, 171, 215, 253, 17, 178, 104, 248, + 159, 4, 211, 42, 104, 206, 122, 248, 158, 104, 55, 248, 159, 4, 211, 42, + 104, 197, 225, 248, 159, 4, 211, 42, 104, 248, 159, 4, 55, 211, 42, 104, + 206, 122, 248, 159, 4, 211, 42, 104, 206, 122, 248, 159, 4, 55, 211, 42, + 104, 223, 93, 248, 158, 104, 223, 93, 248, 159, 4, 55, 211, 42, 104, 200, + 134, 248, 158, 104, 200, 134, 248, 159, 4, 211, 42, 104, 200, 134, 248, + 159, 4, 55, 211, 42, 104, 153, 200, 134, 248, 159, 4, 55, 211, 42, 199, + 205, 1, 65, 199, 205, 1, 252, 206, 199, 205, 1, 68, 199, 205, 1, 223, + 199, 199, 205, 1, 66, 199, 205, 1, 196, 30, 199, 205, 1, 71, 199, 205, 1, + 251, 236, 199, 205, 1, 74, 199, 205, 1, 250, 163, 199, 205, 1, 155, 199, + 205, 1, 221, 215, 199, 205, 1, 231, 240, 199, 205, 1, 231, 91, 199, 205, + 1, 214, 68, 199, 205, 1, 247, 160, 199, 205, 1, 247, 1, 199, 205, 1, 223, + 32, 199, 205, 1, 222, 252, 199, 205, 1, 212, 101, 199, 205, 1, 197, 132, + 199, 205, 1, 197, 120, 199, 205, 1, 237, 191, 199, 205, 1, 237, 175, 199, + 205, 1, 213, 79, 199, 205, 1, 190, 190, 199, 205, 1, 199, 49, 199, 205, + 1, 238, 32, 199, 205, 1, 237, 68, 199, 205, 1, 180, 199, 205, 1, 168, + 199, 205, 1, 209, 228, 199, 205, 1, 249, 153, 199, 205, 1, 248, 203, 199, + 205, 1, 174, 199, 205, 1, 170, 199, 205, 1, 165, 199, 205, 1, 173, 199, + 205, 1, 195, 188, 199, 205, 1, 203, 165, 199, 205, 1, 188, 199, 205, 1, + 140, 199, 205, 1, 206, 109, 199, 205, 3, 251, 71, 199, 205, 3, 195, 35, + 199, 205, 18, 3, 252, 206, 199, 205, 18, 3, 68, 199, 205, 18, 3, 223, + 199, 199, 205, 18, 3, 66, 199, 205, 18, 3, 196, 30, 199, 205, 18, 3, 71, + 199, 205, 18, 3, 251, 236, 199, 205, 18, 3, 74, 199, 205, 18, 3, 250, + 163, 199, 205, 3, 195, 40, 199, 205, 3, 212, 141, 199, 205, 1, 251, 14, + 221, 215, 199, 205, 252, 68, 56, 199, 205, 17, 191, 77, 199, 205, 17, + 107, 199, 205, 17, 109, 199, 205, 17, 138, 199, 205, 17, 134, 199, 205, + 17, 149, 199, 205, 17, 169, 199, 205, 17, 175, 199, 205, 17, 171, 199, + 205, 17, 178, 251, 240, 1, 155, 251, 240, 1, 221, 215, 251, 240, 1, 214, + 68, 251, 240, 1, 180, 251, 240, 1, 190, 190, 251, 240, 1, 251, 157, 190, + 190, 251, 240, 1, 168, 251, 240, 1, 209, 228, 251, 240, 1, 249, 153, 251, + 240, 1, 174, 251, 240, 1, 223, 32, 251, 240, 1, 247, 1, 251, 240, 1, 199, + 49, 251, 240, 1, 165, 251, 240, 1, 173, 251, 240, 1, 188, 251, 240, 1, + 212, 101, 251, 240, 1, 140, 251, 240, 1, 65, 251, 240, 1, 238, 32, 251, + 240, 1, 237, 68, 251, 240, 1, 231, 240, 251, 240, 1, 251, 157, 231, 240, + 251, 240, 1, 231, 91, 251, 240, 1, 248, 203, 251, 240, 1, 222, 252, 251, + 240, 1, 251, 157, 249, 153, 251, 240, 120, 3, 216, 217, 173, 251, 240, + 120, 3, 216, 217, 165, 251, 240, 120, 3, 216, 217, 219, 133, 165, 251, + 240, 18, 3, 65, 251, 240, 18, 3, 252, 206, 251, 240, 18, 3, 68, 251, 240, + 18, 3, 223, 199, 251, 240, 18, 3, 66, 251, 240, 18, 3, 196, 30, 251, 240, + 18, 3, 71, 251, 240, 18, 3, 250, 140, 251, 240, 18, 3, 74, 251, 240, 18, + 3, 251, 236, 251, 240, 18, 3, 251, 149, 251, 240, 3, 221, 143, 251, 240, + 17, 191, 77, 251, 240, 17, 107, 251, 240, 17, 109, 251, 240, 17, 138, + 251, 240, 17, 134, 251, 240, 17, 149, 251, 240, 17, 169, 251, 240, 17, + 175, 251, 240, 17, 171, 251, 240, 17, 178, 251, 240, 31, 199, 95, 251, + 240, 31, 197, 32, 251, 240, 3, 2, 205, 53, 251, 240, 3, 205, 53, 251, + 240, 3, 206, 53, 251, 240, 16, 195, 69, 251, 240, 1, 247, 160, 251, 240, + 1, 197, 132, 251, 240, 1, 197, 120, 251, 240, 1, 237, 191, 251, 240, 1, + 237, 175, 251, 240, 1, 213, 79, 251, 240, 1, 219, 73, 236, 161, 1, 65, + 236, 161, 1, 252, 206, 236, 161, 1, 68, 236, 161, 1, 223, 199, 236, 161, + 1, 66, 236, 161, 1, 196, 30, 236, 161, 1, 71, 236, 161, 1, 251, 236, 236, + 161, 1, 74, 236, 161, 1, 250, 163, 236, 161, 1, 155, 236, 161, 1, 221, + 215, 236, 161, 1, 231, 240, 236, 161, 1, 231, 91, 236, 161, 1, 214, 68, + 236, 161, 1, 247, 160, 236, 161, 1, 247, 1, 236, 161, 1, 223, 32, 236, + 161, 1, 222, 252, 236, 161, 1, 212, 101, 236, 161, 1, 197, 132, 236, 161, + 1, 197, 120, 236, 161, 1, 237, 191, 236, 161, 1, 237, 175, 236, 161, 1, + 213, 79, 236, 161, 1, 190, 190, 236, 161, 1, 199, 49, 236, 161, 1, 238, + 32, 236, 161, 1, 237, 68, 236, 161, 1, 180, 236, 161, 1, 168, 236, 161, + 1, 209, 228, 236, 161, 1, 249, 153, 236, 161, 1, 248, 203, 236, 161, 1, + 174, 236, 161, 1, 170, 236, 161, 1, 165, 236, 161, 1, 173, 236, 161, 1, + 195, 188, 236, 161, 1, 203, 165, 236, 161, 1, 201, 175, 236, 161, 1, 188, + 236, 161, 1, 140, 236, 161, 1, 206, 109, 236, 161, 18, 3, 252, 206, 236, + 161, 18, 3, 68, 236, 161, 18, 3, 223, 199, 236, 161, 18, 3, 66, 236, 161, + 18, 3, 196, 30, 236, 161, 18, 3, 117, 146, 236, 161, 18, 3, 117, 206, + 110, 236, 161, 18, 3, 71, 236, 161, 18, 3, 251, 236, 236, 161, 18, 3, 74, + 236, 161, 18, 3, 250, 163, 236, 161, 3, 251, 71, 236, 161, 3, 195, 35, + 236, 161, 3, 195, 40, 236, 161, 3, 212, 141, 236, 161, 252, 68, 56, 193, + 156, 242, 253, 6, 1, 214, 67, 193, 156, 242, 253, 6, 1, 65, 193, 156, + 242, 253, 6, 1, 193, 86, 193, 156, 242, 253, 6, 1, 191, 225, 193, 156, + 242, 253, 6, 1, 170, 193, 156, 242, 253, 6, 1, 192, 12, 193, 156, 242, + 253, 6, 1, 223, 199, 193, 156, 242, 253, 6, 1, 196, 30, 193, 156, 242, + 253, 6, 1, 71, 193, 156, 242, 253, 6, 1, 74, 193, 156, 242, 253, 6, 1, + 251, 122, 193, 156, 242, 253, 6, 1, 231, 240, 193, 156, 242, 253, 6, 1, + 221, 67, 193, 156, 242, 253, 6, 1, 234, 66, 193, 156, 242, 253, 6, 1, + 191, 204, 193, 156, 242, 253, 6, 1, 196, 160, 193, 156, 242, 253, 6, 1, + 234, 85, 193, 156, 242, 253, 6, 1, 211, 154, 193, 156, 242, 253, 6, 1, + 197, 127, 193, 156, 242, 253, 6, 1, 212, 127, 193, 156, 242, 253, 6, 1, + 238, 32, 193, 156, 242, 253, 6, 1, 250, 182, 193, 156, 242, 253, 6, 1, + 251, 149, 193, 156, 242, 253, 6, 1, 248, 10, 193, 156, 242, 253, 6, 1, + 208, 165, 193, 156, 242, 253, 6, 1, 229, 115, 193, 156, 242, 253, 6, 1, + 229, 3, 193, 156, 242, 253, 6, 1, 228, 185, 193, 156, 242, 253, 6, 1, + 230, 19, 193, 156, 242, 253, 6, 1, 201, 126, 193, 156, 242, 253, 6, 1, + 202, 193, 193, 156, 242, 253, 6, 1, 195, 25, 193, 156, 242, 253, 2, 1, + 214, 67, 193, 156, 242, 253, 2, 1, 65, 193, 156, 242, 253, 2, 1, 193, 86, + 193, 156, 242, 253, 2, 1, 191, 225, 193, 156, 242, 253, 2, 1, 170, 193, + 156, 242, 253, 2, 1, 192, 12, 193, 156, 242, 253, 2, 1, 223, 199, 193, + 156, 242, 253, 2, 1, 196, 30, 193, 156, 242, 253, 2, 1, 71, 193, 156, + 242, 253, 2, 1, 74, 193, 156, 242, 253, 2, 1, 251, 122, 193, 156, 242, + 253, 2, 1, 231, 240, 193, 156, 242, 253, 2, 1, 221, 67, 193, 156, 242, + 253, 2, 1, 234, 66, 193, 156, 242, 253, 2, 1, 191, 204, 193, 156, 242, + 253, 2, 1, 196, 160, 193, 156, 242, 253, 2, 1, 234, 85, 193, 156, 242, + 253, 2, 1, 211, 154, 193, 156, 242, 253, 2, 1, 197, 127, 193, 156, 242, + 253, 2, 1, 212, 127, 193, 156, 242, 253, 2, 1, 238, 32, 193, 156, 242, + 253, 2, 1, 250, 182, 193, 156, 242, 253, 2, 1, 251, 149, 193, 156, 242, + 253, 2, 1, 248, 10, 193, 156, 242, 253, 2, 1, 208, 165, 193, 156, 242, + 253, 2, 1, 229, 115, 193, 156, 242, 253, 2, 1, 229, 3, 193, 156, 242, + 253, 2, 1, 228, 185, 193, 156, 242, 253, 2, 1, 230, 19, 193, 156, 242, + 253, 2, 1, 201, 126, 193, 156, 242, 253, 2, 1, 202, 193, 193, 156, 242, + 253, 2, 1, 195, 25, 193, 156, 242, 253, 17, 191, 77, 193, 156, 242, 253, + 17, 107, 193, 156, 242, 253, 17, 109, 193, 156, 242, 253, 17, 138, 193, + 156, 242, 253, 17, 134, 193, 156, 242, 253, 17, 149, 193, 156, 242, 253, + 17, 169, 193, 156, 242, 253, 17, 175, 193, 156, 242, 253, 17, 171, 193, + 156, 242, 253, 17, 178, 193, 156, 242, 253, 31, 199, 95, 193, 156, 242, + 253, 31, 197, 32, 193, 156, 242, 253, 31, 198, 249, 193, 156, 242, 253, + 31, 232, 135, 193, 156, 242, 253, 31, 233, 15, 193, 156, 242, 253, 31, + 202, 120, 193, 156, 242, 253, 31, 203, 241, 193, 156, 242, 253, 31, 234, + 153, 193, 156, 242, 253, 31, 213, 169, 193, 156, 242, 253, 211, 113, 236, + 209, 251, 209, 1, 65, 236, 209, 251, 209, 1, 252, 206, 236, 209, 251, + 209, 1, 68, 236, 209, 251, 209, 1, 223, 199, 236, 209, 251, 209, 1, 66, + 236, 209, 251, 209, 1, 196, 30, 236, 209, 251, 209, 1, 71, 236, 209, 251, + 209, 1, 74, 236, 209, 251, 209, 1, 155, 236, 209, 251, 209, 1, 221, 215, + 236, 209, 251, 209, 1, 231, 240, 236, 209, 251, 209, 1, 231, 91, 236, + 209, 251, 209, 1, 214, 68, 236, 209, 251, 209, 1, 247, 160, 236, 209, + 251, 209, 1, 247, 1, 236, 209, 251, 209, 1, 223, 32, 236, 209, 251, 209, + 1, 212, 101, 236, 209, 251, 209, 1, 197, 132, 236, 209, 251, 209, 1, 237, + 191, 236, 209, 251, 209, 1, 237, 175, 236, 209, 251, 209, 1, 213, 79, + 236, 209, 251, 209, 1, 190, 190, 236, 209, 251, 209, 1, 199, 49, 236, + 209, 251, 209, 1, 238, 32, 236, 209, 251, 209, 1, 237, 68, 236, 209, 251, + 209, 1, 180, 236, 209, 251, 209, 1, 168, 236, 209, 251, 209, 1, 209, 228, + 236, 209, 251, 209, 1, 249, 153, 236, 209, 251, 209, 1, 248, 203, 236, + 209, 251, 209, 1, 174, 236, 209, 251, 209, 1, 170, 236, 209, 251, 209, 1, + 191, 175, 236, 209, 251, 209, 1, 165, 236, 209, 251, 209, 1, 173, 236, + 209, 251, 209, 1, 195, 188, 236, 209, 251, 209, 1, 203, 165, 236, 209, + 251, 209, 1, 201, 175, 236, 209, 251, 209, 1, 188, 236, 209, 251, 209, 1, + 140, 236, 209, 251, 209, 1, 219, 73, 236, 209, 251, 209, 1, 191, 123, + 236, 209, 251, 209, 18, 3, 252, 206, 236, 209, 251, 209, 18, 3, 68, 236, + 209, 251, 209, 18, 3, 223, 199, 236, 209, 251, 209, 18, 3, 66, 236, 209, + 251, 209, 18, 3, 196, 30, 236, 209, 251, 209, 18, 3, 71, 236, 209, 251, + 209, 18, 3, 251, 236, 236, 209, 251, 209, 18, 3, 74, 236, 209, 251, 209, + 3, 251, 71, 236, 209, 251, 209, 3, 247, 119, 236, 209, 251, 209, 3, 230, + 72, 236, 209, 251, 209, 195, 40, 236, 209, 251, 209, 208, 227, 214, 214, + 56, 236, 209, 251, 209, 216, 217, 170, 236, 209, 251, 209, 89, 165, 236, + 209, 251, 209, 216, 217, 165, 236, 209, 251, 209, 3, 212, 141, 236, 209, + 251, 209, 55, 237, 238, 236, 209, 251, 209, 231, 204, 233, 3, 236, 209, + 251, 209, 234, 95, 79, 199, 54, 77, 236, 209, 251, 209, 17, 191, 77, 236, + 209, 251, 209, 17, 107, 236, 209, 251, 209, 17, 109, 236, 209, 251, 209, + 17, 138, 236, 209, 251, 209, 17, 134, 236, 209, 251, 209, 17, 149, 236, + 209, 251, 209, 17, 169, 236, 209, 251, 209, 17, 175, 236, 209, 251, 209, + 17, 171, 236, 209, 251, 209, 17, 178, 214, 223, 1, 65, 214, 223, 1, 252, + 206, 214, 223, 1, 68, 214, 223, 1, 223, 199, 214, 223, 1, 66, 214, 223, + 1, 196, 30, 214, 223, 1, 117, 146, 214, 223, 1, 117, 206, 110, 214, 223, + 1, 71, 214, 223, 1, 251, 236, 214, 223, 1, 74, 214, 223, 1, 250, 163, + 214, 223, 1, 155, 214, 223, 1, 221, 215, 214, 223, 1, 231, 240, 214, 223, + 1, 231, 91, 214, 223, 1, 214, 68, 214, 223, 1, 247, 160, 214, 223, 1, + 247, 1, 214, 223, 1, 223, 32, 214, 223, 1, 222, 252, 214, 223, 1, 212, + 101, 214, 223, 1, 197, 132, 214, 223, 1, 197, 120, 214, 223, 1, 237, 191, + 214, 223, 1, 237, 175, 214, 223, 1, 213, 79, 214, 223, 1, 190, 190, 214, + 223, 1, 199, 49, 214, 223, 1, 238, 32, 214, 223, 1, 237, 68, 214, 223, 1, + 180, 214, 223, 1, 168, 214, 223, 1, 209, 228, 214, 223, 1, 249, 153, 214, + 223, 1, 248, 203, 214, 223, 1, 174, 214, 223, 1, 170, 214, 223, 1, 165, + 214, 223, 1, 173, 214, 223, 1, 195, 188, 214, 223, 1, 203, 165, 214, 223, + 1, 201, 175, 214, 223, 1, 188, 214, 223, 1, 140, 214, 223, 1, 219, 73, + 214, 223, 1, 206, 109, 214, 223, 18, 3, 252, 206, 214, 223, 18, 3, 68, + 214, 223, 18, 3, 223, 199, 214, 223, 18, 3, 66, 214, 223, 18, 3, 196, 30, + 214, 223, 18, 3, 117, 146, 214, 223, 18, 3, 117, 206, 110, 214, 223, 18, + 3, 71, 214, 223, 18, 3, 251, 236, 214, 223, 18, 3, 74, 214, 223, 18, 3, + 250, 163, 214, 223, 3, 251, 71, 214, 223, 3, 195, 35, 214, 223, 3, 195, + 40, 214, 223, 3, 250, 145, 214, 223, 3, 202, 210, 214, 223, 229, 227, + 214, 223, 18, 3, 208, 207, 71, 191, 106, 51, 1, 65, 191, 106, 51, 18, 3, + 68, 191, 106, 51, 18, 3, 196, 152, 191, 106, 51, 18, 3, 66, 191, 106, 51, + 18, 3, 71, 191, 106, 51, 18, 3, 211, 151, 191, 106, 51, 18, 3, 74, 191, + 106, 51, 18, 3, 251, 236, 191, 106, 51, 18, 3, 250, 163, 191, 106, 51, + 18, 3, 207, 18, 68, 191, 106, 51, 18, 219, 198, 77, 191, 106, 51, 1, 155, + 191, 106, 51, 1, 221, 215, 191, 106, 51, 1, 231, 240, 191, 106, 51, 1, + 231, 91, 191, 106, 51, 1, 214, 68, 191, 106, 51, 1, 247, 160, 191, 106, + 51, 1, 247, 1, 191, 106, 51, 1, 223, 32, 191, 106, 51, 1, 212, 101, 191, + 106, 51, 1, 197, 132, 191, 106, 51, 1, 197, 120, 191, 106, 51, 1, 237, + 191, 191, 106, 51, 1, 237, 175, 191, 106, 51, 1, 213, 79, 191, 106, 51, + 1, 190, 190, 191, 106, 51, 1, 199, 49, 191, 106, 51, 1, 238, 32, 191, + 106, 51, 1, 237, 68, 191, 106, 51, 1, 180, 191, 106, 51, 1, 168, 191, + 106, 51, 1, 209, 228, 191, 106, 51, 1, 249, 153, 191, 106, 51, 1, 248, + 203, 191, 106, 51, 1, 174, 191, 106, 51, 1, 197, 168, 191, 106, 51, 1, + 197, 157, 191, 106, 51, 1, 235, 35, 191, 106, 51, 1, 235, 29, 191, 106, + 51, 1, 191, 71, 191, 106, 51, 1, 191, 123, 191, 106, 51, 1, 255, 214, + 191, 106, 51, 1, 170, 191, 106, 51, 1, 165, 191, 106, 51, 1, 173, 191, + 106, 51, 1, 195, 188, 191, 106, 51, 1, 203, 165, 191, 106, 51, 1, 201, + 175, 191, 106, 51, 1, 188, 191, 106, 51, 1, 140, 191, 106, 51, 1, 220, + 246, 191, 106, 51, 53, 120, 77, 191, 106, 51, 3, 195, 40, 191, 106, 51, + 3, 247, 119, 191, 106, 51, 3, 247, 120, 4, 211, 42, 191, 106, 51, 3, 247, + 122, 4, 211, 42, 191, 106, 51, 3, 251, 71, 191, 106, 51, 3, 195, 35, 191, + 106, 51, 242, 201, 1, 165, 191, 106, 51, 242, 202, 1, 170, 191, 106, 51, + 242, 202, 1, 165, 191, 106, 51, 242, 202, 1, 173, 191, 106, 51, 242, 202, + 1, 195, 188, 191, 106, 51, 89, 229, 236, 77, 191, 106, 51, 242, 215, 229, + 236, 77, 191, 106, 51, 87, 197, 152, 191, 106, 51, 87, 203, 157, 191, + 106, 51, 87, 55, 203, 157, 191, 106, 51, 87, 179, 197, 152, 191, 106, 51, + 89, 235, 130, 229, 236, 77, 191, 106, 51, 242, 215, 235, 130, 229, 236, + 77, 191, 106, 51, 200, 238, 201, 251, 1, 65, 201, 251, 18, 3, 68, 201, + 251, 18, 3, 196, 152, 201, 251, 18, 3, 66, 201, 251, 18, 3, 71, 201, 251, + 18, 3, 74, 201, 251, 18, 3, 211, 151, 201, 251, 18, 3, 251, 236, 201, + 251, 18, 3, 250, 163, 201, 251, 18, 3, 117, 146, 201, 251, 18, 3, 117, + 172, 201, 251, 18, 219, 198, 77, 201, 251, 1, 155, 201, 251, 1, 221, 215, + 201, 251, 1, 231, 240, 201, 251, 1, 231, 91, 201, 251, 1, 214, 68, 201, + 251, 1, 247, 160, 201, 251, 1, 247, 1, 201, 251, 1, 223, 32, 201, 251, 1, + 222, 252, 201, 251, 1, 212, 101, 201, 251, 1, 197, 132, 201, 251, 1, 197, + 120, 201, 251, 1, 237, 191, 201, 251, 1, 237, 175, 201, 251, 1, 213, 79, + 201, 251, 1, 190, 190, 201, 251, 1, 199, 49, 201, 251, 1, 238, 32, 201, + 251, 1, 237, 68, 201, 251, 1, 180, 201, 251, 1, 168, 201, 251, 1, 209, + 228, 201, 251, 1, 249, 153, 201, 251, 1, 248, 203, 201, 251, 1, 174, 201, + 251, 1, 197, 168, 201, 251, 1, 197, 157, 201, 251, 1, 235, 35, 201, 251, + 1, 191, 71, 201, 251, 1, 191, 123, 201, 251, 1, 255, 214, 201, 251, 1, + 170, 201, 251, 1, 165, 201, 251, 1, 173, 201, 251, 1, 195, 188, 201, 251, + 1, 203, 165, 201, 251, 1, 201, 175, 201, 251, 1, 188, 201, 251, 1, 140, + 201, 251, 1, 220, 246, 201, 251, 3, 222, 237, 201, 251, 3, 196, 75, 201, + 251, 242, 201, 1, 165, 201, 251, 242, 201, 1, 173, 201, 251, 242, 201, 1, + 203, 165, 201, 251, 242, 201, 1, 188, 201, 251, 53, 120, 3, 232, 51, 201, + 251, 53, 120, 3, 222, 152, 201, 251, 53, 120, 3, 214, 70, 201, 251, 53, + 120, 3, 238, 127, 201, 251, 53, 120, 3, 215, 61, 201, 251, 53, 120, 3, + 250, 120, 201, 251, 53, 120, 3, 218, 168, 201, 251, 53, 120, 3, 146, 201, + 251, 53, 120, 3, 172, 201, 251, 53, 120, 3, 203, 167, 201, 251, 53, 120, + 3, 206, 8, 201, 251, 53, 120, 3, 255, 214, 201, 251, 3, 251, 71, 201, + 251, 3, 195, 35, 201, 251, 231, 153, 77, 201, 251, 200, 238, 201, 251, + 87, 197, 152, 201, 251, 87, 203, 157, 201, 251, 87, 55, 203, 157, 201, + 251, 87, 209, 79, 201, 251, 229, 236, 87, 4, 215, 206, 23, 200, 199, 23, + 197, 225, 232, 210, 201, 251, 229, 236, 87, 4, 215, 206, 23, 200, 199, + 23, 232, 210, 201, 251, 229, 236, 87, 4, 215, 206, 23, 200, 198, 201, + 251, 199, 81, 217, 55, 201, 251, 199, 81, 217, 54, 21, 22, 214, 207, 229, + 158, 21, 22, 214, 207, 229, 130, 21, 22, 214, 207, 229, 23, 21, 22, 214, + 207, 228, 252, 21, 22, 214, 207, 140, 21, 22, 214, 207, 230, 91, 21, 22, + 214, 207, 203, 15, 21, 22, 214, 207, 203, 14, 21, 22, 214, 207, 203, 11, + 21, 22, 214, 207, 203, 10, 21, 22, 214, 207, 203, 17, 21, 22, 214, 207, + 203, 16, 21, 22, 201, 237, 21, 22, 201, 224, 21, 22, 201, 207, 21, 22, + 201, 249, 210, 81, 243, 15, 230, 3, 1, 168, 210, 81, 243, 15, 230, 3, 1, + 155, 210, 81, 243, 15, 230, 3, 1, 173, 210, 81, 243, 15, 230, 3, 1, 174, + 210, 81, 243, 15, 230, 3, 1, 238, 32, 210, 81, 243, 15, 230, 3, 1, 191, + 123, 210, 81, 243, 15, 230, 3, 1, 195, 188, 210, 81, 243, 15, 230, 3, 1, + 214, 68, 210, 81, 243, 15, 230, 3, 1, 140, 210, 81, 243, 15, 230, 3, 1, + 231, 240, 210, 81, 243, 15, 230, 3, 1, 221, 215, 210, 81, 243, 15, 230, + 3, 1, 188, 210, 81, 243, 15, 230, 3, 1, 249, 153, 210, 81, 243, 15, 230, + 3, 1, 247, 160, 210, 81, 243, 15, 230, 3, 1, 190, 190, 210, 81, 243, 15, + 230, 3, 1, 199, 49, 210, 81, 243, 15, 230, 3, 1, 180, 210, 81, 243, 15, + 230, 3, 1, 209, 228, 210, 81, 243, 15, 230, 3, 1, 165, 210, 81, 243, 15, + 230, 3, 1, 233, 109, 210, 81, 243, 15, 230, 3, 1, 247, 1, 210, 81, 243, + 15, 230, 3, 1, 65, 210, 81, 243, 15, 230, 3, 1, 71, 210, 81, 243, 15, + 230, 3, 1, 68, 210, 81, 243, 15, 230, 3, 1, 74, 210, 81, 243, 15, 230, 3, + 1, 66, 210, 81, 243, 15, 230, 3, 1, 196, 168, 210, 81, 243, 15, 230, 3, + 1, 228, 35, 210, 81, 243, 15, 230, 3, 1, 53, 210, 236, 210, 81, 243, 15, + 230, 3, 1, 53, 222, 152, 210, 81, 243, 15, 230, 3, 1, 53, 200, 43, 210, + 81, 243, 15, 230, 3, 1, 53, 218, 168, 210, 81, 243, 15, 230, 3, 1, 53, + 215, 61, 210, 81, 243, 15, 230, 3, 1, 53, 172, 210, 81, 243, 15, 230, 3, + 1, 53, 193, 224, 210, 81, 243, 15, 230, 3, 1, 53, 214, 70, 210, 81, 243, + 15, 230, 3, 1, 53, 192, 159, 210, 81, 243, 15, 230, 3, 206, 180, 163, + 219, 19, 210, 81, 243, 15, 230, 3, 206, 180, 198, 79, 210, 81, 243, 15, + 230, 3, 205, 138, 231, 11, 201, 63, 210, 81, 243, 15, 230, 3, 206, 180, + 163, 179, 232, 255, 210, 81, 243, 15, 230, 3, 206, 180, 163, 232, 255, + 210, 81, 243, 15, 230, 3, 205, 138, 231, 11, 201, 64, 232, 255, 210, 81, + 243, 15, 230, 3, 205, 138, 163, 219, 19, 210, 81, 243, 15, 230, 3, 205, + 138, 198, 79, 210, 81, 243, 15, 230, 3, 205, 138, 163, 179, 232, 255, + 210, 81, 243, 15, 230, 3, 205, 138, 163, 232, 255, 210, 81, 243, 15, 230, + 3, 216, 85, 198, 79, 210, 81, 243, 15, 230, 3, 231, 11, 201, 64, 195, + 167, 210, 81, 243, 15, 230, 3, 216, 85, 163, 179, 232, 255, 210, 81, 243, + 15, 230, 3, 216, 85, 163, 232, 255, 210, 81, 243, 15, 230, 3, 218, 239, + 163, 219, 19, 210, 81, 243, 15, 230, 3, 218, 239, 198, 79, 210, 81, 243, + 15, 230, 3, 231, 11, 201, 63, 210, 81, 243, 15, 230, 3, 218, 239, 163, + 179, 232, 255, 210, 81, 243, 15, 230, 3, 218, 239, 163, 232, 255, 210, + 81, 243, 15, 230, 3, 231, 11, 201, 64, 232, 255, 100, 229, 236, 77, 100, + 229, 236, 87, 4, 229, 227, 100, 3, 248, 199, 100, 3, 248, 200, 4, 102, + 100, 3, 233, 205, 248, 199, 100, 3, 233, 205, 248, 200, 4, 102, 100, 3, + 193, 102, 232, 225, 248, 199, 100, 3, 193, 102, 213, 174, 248, 199, 100, + 3, 207, 18, 213, 174, 248, 199, 100, 3, 216, 43, 248, 201, 1, 65, 248, + 201, 1, 252, 206, 248, 201, 1, 68, 248, 201, 1, 223, 199, 248, 201, 1, + 66, 248, 201, 1, 196, 30, 248, 201, 1, 117, 146, 248, 201, 1, 117, 206, + 110, 248, 201, 1, 117, 172, 248, 201, 1, 71, 248, 201, 1, 251, 236, 248, + 201, 1, 74, 248, 201, 1, 250, 163, 248, 201, 1, 155, 248, 201, 1, 221, + 215, 248, 201, 1, 231, 240, 248, 201, 1, 231, 91, 248, 201, 1, 214, 68, + 248, 201, 1, 247, 160, 248, 201, 1, 247, 1, 248, 201, 1, 223, 32, 248, + 201, 1, 222, 252, 248, 201, 1, 212, 101, 248, 201, 1, 197, 132, 248, 201, + 1, 197, 120, 248, 201, 1, 237, 191, 248, 201, 1, 237, 175, 248, 201, 1, + 213, 79, 248, 201, 1, 190, 190, 248, 201, 1, 199, 49, 248, 201, 1, 238, + 32, 248, 201, 1, 237, 68, 248, 201, 1, 180, 248, 201, 1, 168, 248, 201, + 1, 209, 228, 248, 201, 1, 249, 153, 248, 201, 1, 248, 203, 248, 201, 1, + 174, 248, 201, 1, 170, 248, 201, 1, 165, 248, 201, 1, 173, 248, 201, 1, + 195, 188, 248, 201, 1, 203, 165, 248, 201, 1, 201, 175, 248, 201, 1, 188, + 248, 201, 1, 140, 248, 201, 18, 3, 252, 206, 248, 201, 18, 3, 68, 248, + 201, 18, 3, 223, 199, 248, 201, 18, 3, 66, 248, 201, 18, 3, 196, 30, 248, + 201, 18, 3, 117, 146, 248, 201, 18, 3, 117, 206, 110, 248, 201, 18, 3, + 117, 172, 248, 201, 18, 3, 71, 248, 201, 18, 3, 251, 236, 248, 201, 18, + 3, 74, 248, 201, 18, 3, 250, 163, 248, 201, 3, 247, 119, 248, 201, 3, + 251, 71, 248, 201, 3, 195, 35, 248, 201, 3, 195, 40, 248, 201, 3, 250, + 145, 248, 201, 237, 238, 248, 201, 55, 237, 238, 248, 201, 193, 23, 204, + 10, 248, 201, 231, 204, 233, 2, 248, 201, 231, 204, 233, 1, 248, 201, 17, + 191, 77, 248, 201, 17, 107, 248, 201, 17, 109, 248, 201, 17, 138, 248, + 201, 17, 134, 248, 201, 17, 149, 248, 201, 17, 169, 248, 201, 17, 175, + 248, 201, 17, 171, 248, 201, 17, 178, 248, 201, 31, 107, 248, 201, 31, + 109, 248, 201, 31, 138, 248, 201, 31, 134, 248, 201, 31, 149, 248, 201, + 31, 169, 248, 201, 31, 175, 248, 201, 31, 171, 248, 201, 31, 178, 248, + 201, 31, 199, 95, 248, 201, 31, 197, 32, 248, 201, 31, 198, 249, 248, + 201, 31, 232, 135, 248, 201, 31, 233, 15, 248, 201, 31, 202, 120, 248, + 201, 31, 203, 241, 248, 201, 31, 234, 153, 248, 201, 31, 213, 169, 248, + 201, 228, 139, 196, 91, 77, 217, 57, 229, 236, 77, 217, 57, 87, 203, 157, + 217, 57, 1, 155, 217, 57, 1, 221, 215, 217, 57, 1, 231, 240, 217, 57, 1, + 214, 68, 217, 57, 1, 247, 160, 217, 57, 1, 247, 1, 217, 57, 1, 223, 32, + 217, 57, 1, 212, 101, 217, 57, 1, 190, 190, 217, 57, 1, 199, 49, 217, 57, + 1, 238, 32, 217, 57, 1, 180, 217, 57, 1, 168, 217, 57, 1, 209, 228, 217, + 57, 1, 249, 153, 217, 57, 1, 174, 217, 57, 1, 197, 168, 217, 57, 1, 197, + 157, 217, 57, 1, 235, 35, 217, 57, 1, 193, 190, 217, 57, 1, 191, 71, 217, + 57, 1, 191, 123, 217, 57, 1, 255, 214, 217, 57, 1, 170, 217, 57, 1, 165, + 217, 57, 1, 173, 217, 57, 1, 203, 165, 217, 57, 1, 188, 217, 57, 1, 140, + 217, 57, 1, 65, 217, 57, 200, 239, 1, 155, 217, 57, 200, 239, 1, 221, + 215, 217, 57, 200, 239, 1, 231, 240, 217, 57, 200, 239, 1, 214, 68, 217, + 57, 200, 239, 1, 247, 160, 217, 57, 200, 239, 1, 247, 1, 217, 57, 200, + 239, 1, 223, 32, 217, 57, 200, 239, 1, 212, 101, 217, 57, 200, 239, 1, + 190, 190, 217, 57, 200, 239, 1, 199, 49, 217, 57, 200, 239, 1, 238, 32, + 217, 57, 200, 239, 1, 180, 217, 57, 200, 239, 1, 168, 217, 57, 200, 239, + 1, 209, 228, 217, 57, 200, 239, 1, 249, 153, 217, 57, 200, 239, 1, 174, + 217, 57, 200, 239, 1, 197, 168, 217, 57, 200, 239, 1, 197, 157, 217, 57, + 200, 239, 1, 235, 35, 217, 57, 200, 239, 1, 193, 190, 217, 57, 200, 239, + 1, 191, 71, 217, 57, 200, 239, 1, 191, 123, 217, 57, 200, 239, 1, 170, + 217, 57, 200, 239, 1, 165, 217, 57, 200, 239, 1, 173, 217, 57, 200, 239, + 1, 203, 165, 217, 57, 200, 239, 1, 188, 217, 57, 200, 239, 1, 140, 217, + 57, 200, 239, 1, 65, 217, 57, 18, 3, 252, 206, 217, 57, 18, 3, 68, 217, + 57, 18, 3, 66, 217, 57, 18, 3, 71, 217, 57, 18, 3, 74, 217, 57, 3, 251, + 71, 217, 57, 3, 247, 119, 217, 41, 129, 1, 65, 217, 41, 129, 1, 252, 206, + 217, 41, 129, 1, 68, 217, 41, 129, 1, 223, 199, 217, 41, 129, 1, 66, 217, + 41, 129, 1, 196, 30, 217, 41, 129, 1, 71, 217, 41, 129, 1, 251, 236, 217, + 41, 129, 1, 74, 217, 41, 129, 1, 250, 163, 217, 41, 129, 1, 155, 217, 41, + 129, 1, 221, 215, 217, 41, 129, 1, 231, 240, 217, 41, 129, 1, 231, 91, + 217, 41, 129, 1, 214, 68, 217, 41, 129, 1, 247, 160, 217, 41, 129, 1, + 247, 1, 217, 41, 129, 1, 223, 32, 217, 41, 129, 1, 222, 252, 217, 41, + 129, 1, 212, 101, 217, 41, 129, 1, 197, 132, 217, 41, 129, 1, 197, 120, + 217, 41, 129, 1, 237, 191, 217, 41, 129, 1, 237, 175, 217, 41, 129, 1, + 213, 79, 217, 41, 129, 1, 190, 190, 217, 41, 129, 1, 199, 49, 217, 41, + 129, 1, 238, 32, 217, 41, 129, 1, 237, 68, 217, 41, 129, 1, 180, 217, 41, + 129, 1, 168, 217, 41, 129, 1, 209, 228, 217, 41, 129, 1, 249, 153, 217, + 41, 129, 1, 248, 203, 217, 41, 129, 1, 174, 217, 41, 129, 1, 170, 217, + 41, 129, 1, 165, 217, 41, 129, 1, 173, 217, 41, 129, 1, 195, 188, 217, + 41, 129, 1, 203, 165, 217, 41, 129, 1, 201, 175, 217, 41, 129, 1, 188, + 217, 41, 129, 1, 140, 217, 41, 129, 1, 219, 73, 217, 41, 129, 1, 220, + 246, 217, 41, 129, 1, 222, 202, 217, 41, 129, 1, 198, 26, 217, 41, 129, + 18, 3, 252, 206, 217, 41, 129, 18, 3, 68, 217, 41, 129, 18, 3, 223, 199, + 217, 41, 129, 18, 3, 66, 217, 41, 129, 18, 3, 196, 30, 217, 41, 129, 18, + 3, 117, 146, 217, 41, 129, 18, 3, 71, 217, 41, 129, 18, 3, 251, 236, 217, + 41, 129, 18, 3, 74, 217, 41, 129, 18, 3, 250, 163, 217, 41, 129, 3, 251, + 71, 217, 41, 129, 3, 195, 35, 217, 41, 129, 3, 212, 141, 217, 41, 129, 3, + 247, 121, 217, 41, 129, 3, 230, 72, 217, 41, 129, 195, 40, 217, 41, 129, + 207, 44, 217, 41, 129, 207, 181, 217, 41, 129, 17, 191, 77, 217, 41, 129, + 17, 107, 217, 41, 129, 17, 109, 217, 41, 129, 17, 138, 217, 41, 129, 17, + 134, 217, 41, 129, 17, 149, 217, 41, 129, 17, 169, 217, 41, 129, 17, 175, + 217, 41, 129, 17, 171, 217, 41, 129, 17, 178, 230, 157, 129, 1, 65, 230, + 157, 129, 1, 252, 206, 230, 157, 129, 1, 68, 230, 157, 129, 1, 223, 199, + 230, 157, 129, 1, 66, 230, 157, 129, 1, 196, 30, 230, 157, 129, 1, 234, + 188, 230, 157, 129, 1, 251, 236, 230, 157, 129, 1, 211, 87, 230, 157, + 129, 1, 250, 163, 230, 157, 129, 1, 170, 230, 157, 129, 1, 195, 188, 230, + 157, 129, 1, 249, 153, 230, 157, 129, 1, 248, 203, 230, 157, 129, 1, 174, + 230, 157, 129, 1, 155, 230, 157, 129, 1, 221, 215, 230, 157, 129, 1, 190, + 190, 230, 157, 129, 1, 199, 49, 230, 157, 129, 1, 173, 230, 157, 129, 1, + 231, 240, 230, 157, 129, 1, 231, 91, 230, 157, 129, 1, 238, 32, 230, 157, + 129, 1, 237, 68, 230, 157, 129, 1, 180, 230, 157, 129, 1, 247, 160, 230, + 157, 129, 1, 247, 1, 230, 157, 129, 1, 197, 132, 230, 157, 129, 1, 197, + 120, 230, 157, 129, 1, 219, 73, 230, 157, 129, 1, 223, 32, 230, 157, 129, + 1, 222, 252, 230, 157, 129, 1, 237, 191, 230, 157, 129, 1, 237, 175, 230, + 157, 129, 1, 214, 68, 230, 157, 129, 1, 168, 230, 157, 129, 1, 209, 228, + 230, 157, 129, 1, 140, 230, 157, 129, 1, 165, 230, 157, 129, 1, 188, 230, + 157, 129, 18, 3, 252, 206, 230, 157, 129, 18, 3, 68, 230, 157, 129, 18, + 3, 223, 199, 230, 157, 129, 18, 3, 66, 230, 157, 129, 18, 3, 196, 30, + 230, 157, 129, 18, 3, 234, 188, 230, 157, 129, 18, 3, 251, 236, 230, 157, + 129, 18, 3, 211, 87, 230, 157, 129, 18, 3, 250, 163, 230, 157, 129, 3, + 251, 71, 230, 157, 129, 3, 195, 35, 230, 157, 129, 195, 40, 230, 157, + 129, 211, 113, 230, 157, 129, 17, 191, 77, 230, 157, 129, 17, 107, 230, + 157, 129, 17, 109, 230, 157, 129, 17, 138, 230, 157, 129, 17, 134, 230, + 157, 129, 17, 149, 230, 157, 129, 17, 169, 230, 157, 129, 17, 175, 230, + 157, 129, 17, 171, 230, 157, 129, 17, 178, 217, 102, 1, 155, 217, 102, 1, + 231, 240, 217, 102, 1, 214, 68, 217, 102, 1, 168, 217, 102, 1, 249, 153, + 217, 102, 1, 174, 217, 102, 1, 190, 190, 217, 102, 1, 238, 32, 217, 102, + 1, 180, 217, 102, 1, 247, 160, 217, 102, 1, 223, 32, 217, 102, 1, 212, + 101, 217, 102, 1, 170, 217, 102, 1, 165, 217, 102, 1, 173, 217, 102, 1, + 195, 188, 217, 102, 1, 188, 217, 102, 1, 65, 217, 102, 251, 118, 217, + 102, 18, 3, 68, 217, 102, 18, 3, 66, 217, 102, 18, 3, 71, 217, 102, 18, + 3, 74, 217, 102, 210, 94, 217, 102, 234, 95, 79, 205, 53, 222, 33, 3, + 247, 119, 222, 33, 3, 251, 71, 222, 33, 3, 207, 44, 222, 33, 3, 195, 35, + 222, 33, 1, 65, 222, 33, 1, 252, 206, 222, 33, 1, 68, 222, 33, 1, 223, + 199, 222, 33, 1, 66, 222, 33, 1, 196, 30, 222, 33, 1, 117, 146, 222, 33, + 1, 117, 206, 110, 222, 33, 1, 117, 172, 222, 33, 1, 117, 219, 74, 222, + 33, 1, 71, 222, 33, 1, 251, 236, 222, 33, 1, 74, 222, 33, 1, 155, 222, + 33, 1, 221, 215, 222, 33, 1, 231, 240, 222, 33, 1, 231, 91, 222, 33, 1, + 214, 68, 222, 33, 1, 247, 160, 222, 33, 1, 247, 1, 222, 33, 1, 223, 32, + 222, 33, 1, 222, 252, 222, 33, 1, 212, 101, 222, 33, 1, 197, 132, 222, + 33, 1, 197, 120, 222, 33, 1, 237, 191, 222, 33, 1, 237, 175, 222, 33, 1, + 213, 79, 222, 33, 1, 190, 190, 222, 33, 1, 199, 49, 222, 33, 1, 238, 32, + 222, 33, 1, 237, 68, 222, 33, 1, 180, 222, 33, 1, 168, 222, 33, 1, 209, + 228, 222, 33, 1, 249, 153, 222, 33, 1, 248, 203, 222, 33, 1, 174, 222, + 33, 1, 170, 222, 33, 1, 165, 222, 33, 1, 173, 222, 33, 1, 193, 190, 222, + 33, 1, 203, 165, 222, 33, 1, 201, 175, 222, 33, 1, 188, 222, 33, 1, 140, + 222, 33, 1, 222, 202, 222, 33, 18, 3, 252, 206, 222, 33, 18, 3, 251, 157, + 252, 206, 222, 33, 18, 3, 68, 222, 33, 18, 3, 223, 199, 222, 33, 18, 3, + 66, 222, 33, 18, 3, 196, 30, 222, 33, 18, 3, 117, 146, 222, 33, 18, 3, + 71, 222, 33, 18, 3, 251, 236, 222, 33, 18, 3, 233, 242, 222, 33, 3, 221, + 143, 222, 33, 239, 45, 222, 33, 237, 238, 222, 33, 55, 237, 238, 222, 33, + 208, 152, 205, 54, 217, 51, 222, 33, 208, 152, 251, 157, 205, 54, 217, + 51, 222, 33, 208, 152, 232, 186, 222, 33, 208, 152, 201, 248, 233, 3, + 222, 33, 208, 152, 236, 140, 222, 33, 208, 152, 55, 236, 140, 222, 33, + 208, 152, 197, 225, 236, 140, 222, 33, 208, 152, 243, 10, 222, 33, 208, + 152, 233, 4, 243, 10, 222, 33, 208, 152, 201, 217, 222, 33, 208, 152, + 242, 215, 201, 217, 222, 33, 17, 191, 77, 222, 33, 17, 107, 222, 33, 17, + 109, 222, 33, 17, 138, 222, 33, 17, 134, 222, 33, 17, 149, 222, 33, 17, + 169, 222, 33, 17, 175, 222, 33, 17, 171, 222, 33, 17, 178, 219, 88, 1, + 192, 35, 44, 232, 118, 91, 198, 222, 44, 232, 118, 91, 211, 100, 44, 232, + 118, 91, 234, 156, 44, 232, 118, 91, 202, 118, 44, 232, 118, 91, 232, + 139, 44, 232, 118, 91, 198, 245, 44, 232, 118, 115, 234, 155, 44, 232, + 118, 115, 202, 117, 44, 232, 118, 91, 197, 35, 44, 232, 118, 91, 202, + 127, 44, 232, 118, 91, 202, 126, 44, 232, 118, 91, 199, 86, 44, 232, 118, + 91, 234, 159, 44, 232, 118, 115, 197, 34, 44, 232, 118, 115, 202, 125, + 44, 232, 118, 91, 233, 18, 44, 232, 118, 91, 208, 22, 44, 232, 118, 91, + 230, 69, 44, 232, 118, 91, 230, 68, 44, 232, 118, 115, 208, 20, 44, 232, + 118, 235, 121, 233, 93, 221, 144, 44, 3, 214, 104, 44, 3, 247, 6, 44, 3, + 252, 157, 44, 3, 196, 15, 44, 3, 215, 90, 44, 3, 220, 194, 44, 3, 210, + 85, 44, 3, 215, 135, 44, 3, 222, 124, 44, 3, 210, 164, 44, 3, 209, 39, + 44, 3, 195, 173, 44, 3, 210, 215, 44, 3, 220, 183, 44, 3, 195, 143, 44, + 193, 101, 238, 187, 56, 44, 235, 92, 238, 187, 56, 44, 220, 23, 56, 44, + 205, 159, 210, 167, 56, 44, 198, 21, 238, 230, 56, 44, 198, 21, 31, 56, + 44, 238, 169, 56, 44, 23, 211, 155, 56, 44, 201, 227, 56, 44, 198, 39, + 56, 44, 223, 163, 209, 22, 56, 44, 201, 96, 232, 98, 56, 44, 3, 215, 94, + 44, 3, 195, 181, 44, 208, 152, 234, 95, 79, 199, 53, 10, 3, 65, 10, 3, + 42, 25, 65, 10, 3, 42, 25, 249, 135, 10, 3, 42, 25, 231, 209, 199, 84, + 10, 3, 42, 25, 140, 10, 3, 42, 25, 223, 201, 10, 3, 42, 25, 220, 103, + 230, 155, 10, 3, 42, 25, 215, 101, 10, 3, 42, 25, 205, 185, 10, 3, 254, + 215, 10, 3, 252, 155, 10, 3, 252, 156, 25, 250, 207, 10, 3, 252, 156, 25, + 235, 74, 230, 155, 10, 3, 252, 156, 25, 231, 222, 10, 3, 252, 156, 25, + 231, 209, 199, 84, 10, 3, 252, 156, 25, 140, 10, 3, 252, 156, 25, 223, + 202, 230, 155, 10, 3, 252, 156, 25, 223, 172, 10, 3, 252, 156, 25, 220, + 104, 10, 3, 252, 156, 25, 203, 97, 10, 3, 252, 156, 25, 126, 108, 126, + 108, 66, 10, 3, 252, 156, 230, 155, 10, 3, 252, 72, 10, 3, 252, 73, 25, + 249, 114, 10, 3, 252, 73, 25, 231, 209, 199, 84, 10, 3, 252, 73, 25, 216, + 233, 108, 234, 103, 10, 3, 252, 73, 25, 203, 163, 10, 3, 252, 73, 25, + 199, 209, 10, 3, 252, 42, 10, 3, 251, 216, 10, 3, 251, 217, 25, 234, 28, + 10, 3, 251, 217, 25, 203, 59, 108, 231, 23, 10, 3, 251, 207, 10, 3, 251, + 208, 25, 251, 207, 10, 3, 251, 208, 25, 236, 253, 10, 3, 251, 208, 25, + 231, 23, 10, 3, 251, 208, 25, 140, 10, 3, 251, 208, 25, 222, 111, 10, 3, + 251, 208, 25, 221, 166, 10, 3, 251, 208, 25, 203, 113, 10, 3, 251, 208, + 25, 196, 38, 10, 3, 251, 203, 10, 3, 251, 190, 10, 3, 251, 145, 10, 3, + 251, 146, 25, 203, 113, 10, 3, 251, 132, 10, 3, 251, 133, 139, 251, 132, + 10, 3, 251, 133, 115, 198, 144, 10, 3, 251, 133, 108, 214, 241, 211, 63, + 251, 133, 108, 214, 240, 10, 3, 251, 133, 108, 214, 241, 201, 189, 10, 3, + 251, 91, 10, 3, 251, 60, 10, 3, 251, 26, 10, 3, 251, 27, 25, 220, 197, + 10, 3, 250, 254, 10, 3, 250, 215, 10, 3, 250, 209, 10, 3, 250, 210, 191, + 26, 199, 84, 10, 3, 250, 210, 222, 116, 199, 84, 10, 3, 250, 210, 139, + 250, 210, 197, 83, 139, 197, 83, 197, 83, 139, 197, 83, 210, 137, 10, 3, + 250, 210, 139, 250, 210, 139, 250, 209, 10, 3, 250, 210, 139, 250, 210, + 139, 250, 210, 238, 210, 250, 210, 139, 250, 210, 139, 250, 209, 10, 3, + 250, 207, 10, 3, 250, 203, 10, 3, 249, 153, 10, 3, 249, 135, 10, 3, 249, + 129, 10, 3, 249, 121, 10, 3, 249, 115, 10, 3, 249, 116, 139, 249, 115, + 10, 3, 249, 114, 10, 3, 164, 10, 3, 249, 87, 10, 3, 248, 188, 10, 3, 248, + 189, 25, 65, 10, 3, 248, 189, 25, 231, 200, 10, 3, 248, 189, 25, 223, + 202, 230, 155, 10, 3, 248, 10, 10, 3, 248, 11, 139, 248, 11, 252, 155, + 10, 3, 248, 11, 139, 248, 11, 196, 113, 10, 3, 248, 11, 238, 210, 248, + 10, 10, 3, 247, 242, 10, 3, 247, 243, 139, 247, 242, 10, 3, 247, 230, 10, + 3, 247, 229, 10, 3, 238, 32, 10, 3, 238, 22, 10, 3, 238, 23, 221, 125, + 25, 42, 108, 217, 39, 10, 3, 238, 23, 221, 125, 25, 251, 145, 10, 3, 238, + 23, 221, 125, 25, 249, 114, 10, 3, 238, 23, 221, 125, 25, 248, 188, 10, + 3, 238, 23, 221, 125, 25, 231, 240, 10, 3, 238, 23, 221, 125, 25, 231, + 241, 108, 217, 39, 10, 3, 238, 23, 221, 125, 25, 231, 53, 10, 3, 238, 23, + 221, 125, 25, 231, 32, 10, 3, 238, 23, 221, 125, 25, 230, 168, 10, 3, + 238, 23, 221, 125, 25, 140, 10, 3, 238, 23, 221, 125, 25, 223, 77, 10, 3, + 238, 23, 221, 125, 25, 223, 78, 108, 218, 225, 10, 3, 238, 23, 221, 125, + 25, 222, 96, 10, 3, 238, 23, 221, 125, 25, 173, 10, 3, 238, 23, 221, 125, + 25, 218, 225, 10, 3, 238, 23, 221, 125, 25, 218, 226, 108, 217, 38, 10, + 3, 238, 23, 221, 125, 25, 218, 208, 10, 3, 238, 23, 221, 125, 25, 214, + 121, 10, 3, 238, 23, 221, 125, 25, 210, 138, 108, 210, 137, 10, 3, 238, + 23, 221, 125, 25, 202, 222, 10, 3, 238, 23, 221, 125, 25, 199, 209, 10, + 3, 238, 23, 221, 125, 25, 196, 170, 108, 231, 32, 10, 3, 238, 23, 221, + 125, 25, 196, 38, 10, 3, 237, 250, 10, 3, 237, 225, 10, 3, 237, 224, 10, + 3, 237, 223, 10, 3, 237, 44, 10, 3, 237, 26, 10, 3, 236, 255, 10, 3, 237, + 0, 25, 203, 113, 10, 3, 236, 253, 10, 3, 236, 243, 10, 3, 236, 244, 222, + 55, 126, 230, 156, 236, 222, 10, 3, 236, 222, 10, 3, 235, 89, 10, 3, 235, + 90, 139, 235, 89, 10, 3, 235, 90, 230, 155, 10, 3, 235, 90, 203, 94, 10, + 3, 235, 87, 10, 3, 235, 88, 25, 234, 9, 10, 3, 235, 86, 10, 3, 235, 82, + 10, 3, 235, 81, 10, 3, 235, 80, 10, 3, 235, 75, 10, 3, 235, 73, 10, 3, + 235, 74, 230, 155, 10, 3, 235, 74, 230, 156, 230, 155, 10, 3, 235, 72, + 10, 3, 235, 65, 10, 3, 71, 10, 3, 235, 15, 25, 210, 137, 10, 3, 235, 15, + 139, 235, 15, 212, 131, 139, 212, 130, 10, 3, 234, 218, 10, 3, 234, 219, + 25, 42, 108, 230, 105, 108, 238, 32, 10, 3, 234, 219, 25, 231, 200, 10, + 3, 234, 219, 25, 216, 100, 10, 3, 234, 219, 25, 205, 169, 10, 3, 234, + 219, 25, 203, 113, 10, 3, 234, 219, 25, 66, 10, 3, 234, 190, 10, 3, 234, + 177, 10, 3, 234, 140, 10, 3, 234, 103, 10, 3, 234, 104, 25, 231, 208, 10, + 3, 234, 104, 25, 231, 209, 199, 84, 10, 3, 234, 104, 25, 216, 232, 10, 3, + 234, 104, 238, 210, 234, 103, 10, 3, 234, 104, 211, 63, 234, 103, 10, 3, + 234, 104, 201, 189, 10, 3, 234, 31, 10, 3, 234, 28, 10, 3, 234, 9, 10, 3, + 233, 180, 10, 3, 233, 181, 25, 65, 10, 3, 233, 181, 25, 42, 108, 220, 37, + 10, 3, 233, 181, 25, 42, 108, 220, 38, 25, 220, 37, 10, 3, 233, 181, 25, + 251, 132, 10, 3, 233, 181, 25, 249, 135, 10, 3, 233, 181, 25, 235, 74, + 230, 155, 10, 3, 233, 181, 25, 235, 74, 230, 156, 230, 155, 10, 3, 233, + 181, 25, 140, 10, 3, 233, 181, 25, 230, 105, 230, 155, 10, 3, 233, 181, + 25, 223, 202, 230, 155, 10, 3, 233, 181, 25, 222, 54, 10, 3, 233, 181, + 25, 222, 55, 201, 189, 10, 3, 233, 181, 25, 220, 223, 10, 3, 233, 181, + 25, 173, 10, 3, 233, 181, 25, 220, 38, 25, 220, 37, 10, 3, 233, 181, 25, + 219, 146, 10, 3, 233, 181, 25, 218, 225, 10, 3, 233, 181, 25, 196, 169, + 10, 3, 233, 181, 25, 196, 158, 10, 3, 231, 240, 10, 3, 231, 241, 230, + 155, 10, 3, 231, 238, 10, 3, 231, 239, 25, 42, 108, 238, 33, 108, 140, + 10, 3, 231, 239, 25, 42, 108, 140, 10, 3, 231, 239, 25, 42, 108, 223, + 201, 10, 3, 231, 239, 25, 252, 73, 199, 85, 108, 199, 236, 10, 3, 231, + 239, 25, 251, 132, 10, 3, 231, 239, 25, 250, 209, 10, 3, 231, 239, 25, + 250, 208, 108, 231, 222, 10, 3, 231, 239, 25, 249, 135, 10, 3, 231, 239, + 25, 249, 88, 108, 165, 10, 3, 231, 239, 25, 247, 230, 10, 3, 231, 239, + 25, 247, 231, 108, 165, 10, 3, 231, 239, 25, 238, 32, 10, 3, 231, 239, + 25, 237, 44, 10, 3, 231, 239, 25, 237, 0, 25, 203, 113, 10, 3, 231, 239, + 25, 235, 87, 10, 3, 231, 239, 25, 234, 140, 10, 3, 231, 239, 25, 234, + 141, 108, 173, 10, 3, 231, 239, 25, 234, 103, 10, 3, 231, 239, 25, 234, + 104, 25, 231, 209, 199, 84, 10, 3, 231, 239, 25, 231, 209, 199, 84, 10, + 3, 231, 239, 25, 231, 200, 10, 3, 231, 239, 25, 231, 53, 10, 3, 231, 239, + 25, 231, 51, 10, 3, 231, 239, 25, 231, 52, 108, 65, 10, 3, 231, 239, 25, + 231, 33, 108, 201, 4, 10, 3, 231, 239, 25, 230, 105, 108, 218, 226, 108, + 234, 9, 10, 3, 231, 239, 25, 230, 73, 10, 3, 231, 239, 25, 230, 74, 108, + 173, 10, 3, 231, 239, 25, 229, 159, 108, 219, 146, 10, 3, 231, 239, 25, + 228, 151, 10, 3, 231, 239, 25, 223, 202, 230, 155, 10, 3, 231, 239, 25, + 223, 63, 108, 228, 160, 108, 250, 209, 10, 3, 231, 239, 25, 222, 96, 10, + 3, 231, 239, 25, 222, 54, 10, 3, 231, 239, 25, 221, 152, 10, 3, 231, 239, + 25, 221, 153, 108, 220, 37, 10, 3, 231, 239, 25, 220, 224, 108, 251, 132, + 10, 3, 231, 239, 25, 173, 10, 3, 231, 239, 25, 216, 233, 108, 234, 103, + 10, 3, 231, 239, 25, 216, 100, 10, 3, 231, 239, 25, 212, 130, 10, 3, 231, + 239, 25, 212, 131, 139, 212, 130, 10, 3, 231, 239, 25, 168, 10, 3, 231, + 239, 25, 205, 169, 10, 3, 231, 239, 25, 205, 127, 10, 3, 231, 239, 25, + 203, 113, 10, 3, 231, 239, 25, 203, 114, 108, 197, 64, 10, 3, 231, 239, + 25, 203, 79, 10, 3, 231, 239, 25, 200, 204, 10, 3, 231, 239, 25, 199, + 209, 10, 3, 231, 239, 25, 66, 10, 3, 231, 239, 25, 196, 158, 10, 3, 231, + 239, 25, 196, 159, 108, 235, 89, 10, 3, 231, 239, 139, 231, 238, 10, 3, + 231, 233, 10, 3, 231, 234, 238, 210, 231, 233, 10, 3, 231, 231, 10, 3, + 231, 232, 139, 231, 232, 231, 201, 139, 231, 200, 10, 3, 231, 222, 10, 3, + 231, 223, 231, 232, 139, 231, 232, 231, 201, 139, 231, 200, 10, 3, 231, + 221, 10, 3, 231, 219, 10, 3, 231, 210, 10, 3, 231, 208, 10, 3, 231, 209, + 199, 84, 10, 3, 231, 209, 139, 231, 208, 10, 3, 231, 209, 238, 210, 231, + 208, 10, 3, 231, 200, 10, 3, 231, 199, 10, 3, 231, 193, 10, 3, 231, 134, + 10, 3, 231, 135, 25, 220, 197, 10, 3, 231, 53, 10, 3, 231, 54, 25, 71, + 10, 3, 231, 54, 25, 66, 10, 3, 231, 54, 238, 210, 231, 53, 10, 3, 231, + 51, 10, 3, 231, 52, 139, 231, 51, 10, 3, 231, 52, 238, 210, 231, 51, 10, + 3, 231, 48, 10, 3, 231, 32, 10, 3, 231, 33, 230, 155, 10, 3, 231, 30, 10, + 3, 231, 31, 25, 42, 108, 223, 201, 10, 3, 231, 31, 25, 231, 209, 199, 84, + 10, 3, 231, 31, 25, 223, 201, 10, 3, 231, 31, 25, 218, 226, 108, 223, + 201, 10, 3, 231, 31, 25, 168, 10, 3, 231, 25, 10, 3, 231, 23, 10, 3, 231, + 24, 238, 210, 231, 23, 10, 3, 231, 24, 25, 249, 135, 10, 3, 231, 24, 25, + 199, 209, 10, 3, 231, 24, 199, 84, 10, 3, 230, 179, 10, 3, 230, 180, 238, + 210, 230, 179, 10, 3, 230, 177, 10, 3, 230, 178, 25, 222, 96, 10, 3, 230, + 178, 25, 222, 97, 25, 223, 202, 230, 155, 10, 3, 230, 178, 25, 212, 130, + 10, 3, 230, 178, 25, 205, 170, 108, 197, 82, 10, 3, 230, 178, 230, 155, + 10, 3, 230, 168, 10, 3, 230, 169, 25, 42, 108, 220, 197, 10, 3, 230, 169, + 25, 220, 197, 10, 3, 230, 169, 139, 230, 169, 218, 216, 10, 3, 230, 160, + 10, 3, 230, 158, 10, 3, 230, 159, 25, 203, 113, 10, 3, 230, 149, 10, 3, + 230, 148, 10, 3, 230, 143, 10, 3, 230, 142, 10, 3, 140, 10, 3, 230, 105, + 199, 84, 10, 3, 230, 105, 230, 155, 10, 3, 230, 73, 10, 3, 229, 158, 10, + 3, 229, 159, 25, 250, 209, 10, 3, 229, 159, 25, 250, 207, 10, 3, 229, + 159, 25, 249, 135, 10, 3, 229, 159, 25, 236, 222, 10, 3, 229, 159, 25, + 231, 231, 10, 3, 229, 159, 25, 221, 141, 10, 3, 229, 159, 25, 212, 130, + 10, 3, 229, 159, 25, 203, 113, 10, 3, 229, 159, 25, 66, 10, 3, 228, 159, + 10, 3, 228, 151, 10, 3, 228, 152, 25, 251, 132, 10, 3, 228, 152, 25, 230, + 73, 10, 3, 228, 152, 25, 222, 54, 10, 3, 228, 152, 25, 219, 89, 10, 3, + 228, 152, 25, 196, 158, 10, 3, 228, 146, 10, 3, 68, 10, 3, 228, 74, 65, + 10, 3, 228, 30, 10, 3, 223, 229, 10, 3, 223, 230, 139, 223, 230, 247, + 230, 10, 3, 223, 230, 139, 223, 230, 201, 189, 10, 3, 223, 204, 10, 3, + 223, 201, 10, 3, 223, 202, 237, 26, 10, 3, 223, 202, 207, 1, 10, 3, 223, + 202, 139, 223, 202, 203, 63, 139, 203, 63, 196, 159, 139, 196, 158, 10, + 3, 223, 202, 230, 155, 10, 3, 223, 191, 10, 3, 223, 192, 25, 231, 209, + 199, 84, 10, 3, 223, 190, 10, 3, 223, 180, 10, 3, 223, 181, 25, 199, 209, + 10, 3, 223, 181, 238, 210, 223, 180, 10, 3, 223, 181, 211, 63, 223, 180, + 10, 3, 223, 181, 201, 189, 10, 3, 223, 172, 10, 3, 223, 162, 10, 3, 223, + 77, 10, 3, 223, 62, 10, 3, 155, 10, 3, 222, 142, 25, 65, 10, 3, 222, 142, + 25, 252, 42, 10, 3, 222, 142, 25, 252, 43, 108, 220, 223, 10, 3, 222, + 142, 25, 250, 207, 10, 3, 222, 142, 25, 249, 135, 10, 3, 222, 142, 25, + 249, 114, 10, 3, 222, 142, 25, 164, 10, 3, 222, 142, 25, 248, 188, 10, 3, + 222, 142, 25, 234, 28, 10, 3, 222, 142, 25, 234, 9, 10, 3, 222, 142, 25, + 231, 240, 10, 3, 222, 142, 25, 231, 222, 10, 3, 222, 142, 25, 231, 209, + 199, 84, 10, 3, 222, 142, 25, 231, 200, 10, 3, 222, 142, 25, 231, 201, + 108, 203, 164, 108, 65, 10, 3, 222, 142, 25, 231, 53, 10, 3, 222, 142, + 25, 231, 32, 10, 3, 222, 142, 25, 231, 24, 108, 205, 127, 10, 3, 222, + 142, 25, 231, 24, 238, 210, 231, 23, 10, 3, 222, 142, 25, 230, 179, 10, + 3, 222, 142, 25, 230, 148, 10, 3, 222, 142, 25, 223, 201, 10, 3, 222, + 142, 25, 223, 180, 10, 3, 222, 142, 25, 222, 96, 10, 3, 222, 142, 25, + 221, 166, 10, 3, 222, 142, 25, 221, 152, 10, 3, 222, 142, 25, 219, 146, + 10, 3, 222, 142, 25, 218, 225, 10, 3, 222, 142, 25, 216, 232, 10, 3, 222, + 142, 25, 216, 233, 108, 235, 89, 10, 3, 222, 142, 25, 216, 233, 108, 231, + 53, 10, 3, 222, 142, 25, 216, 233, 108, 199, 145, 10, 3, 222, 142, 25, + 216, 100, 10, 3, 222, 142, 25, 216, 101, 108, 212, 125, 10, 3, 222, 142, + 25, 214, 121, 10, 3, 222, 142, 25, 212, 130, 10, 3, 222, 142, 25, 209, + 185, 10, 3, 222, 142, 25, 206, 68, 10, 3, 222, 142, 25, 188, 10, 3, 222, + 142, 25, 205, 127, 10, 3, 222, 142, 25, 203, 165, 10, 3, 222, 142, 25, + 203, 113, 10, 3, 222, 142, 25, 203, 79, 10, 3, 222, 142, 25, 203, 5, 10, + 3, 222, 142, 25, 202, 201, 10, 3, 222, 142, 25, 200, 213, 10, 3, 222, + 142, 25, 199, 179, 10, 3, 222, 142, 25, 66, 10, 3, 222, 142, 25, 196, + 169, 10, 3, 222, 142, 25, 196, 158, 10, 3, 222, 142, 25, 196, 116, 25, + 168, 10, 3, 222, 142, 25, 196, 38, 10, 3, 222, 142, 25, 191, 30, 10, 3, + 222, 128, 10, 3, 222, 129, 238, 210, 222, 128, 10, 3, 222, 117, 10, 3, + 222, 113, 10, 3, 222, 111, 10, 3, 222, 110, 10, 3, 222, 108, 10, 3, 222, + 109, 139, 222, 108, 10, 3, 222, 96, 10, 3, 222, 97, 25, 223, 202, 230, + 155, 10, 3, 222, 91, 10, 3, 222, 92, 25, 249, 135, 10, 3, 222, 92, 238, + 210, 222, 91, 10, 3, 222, 89, 10, 3, 222, 88, 10, 3, 222, 54, 10, 3, 222, + 55, 220, 105, 25, 126, 139, 220, 105, 25, 66, 10, 3, 222, 55, 139, 222, + 55, 220, 105, 25, 126, 139, 220, 105, 25, 66, 10, 3, 221, 242, 10, 3, + 221, 166, 10, 3, 221, 167, 25, 249, 135, 10, 3, 221, 167, 25, 66, 10, 3, + 221, 167, 25, 196, 158, 10, 3, 221, 152, 10, 3, 221, 141, 10, 3, 221, + 127, 10, 3, 221, 126, 10, 3, 221, 124, 10, 3, 221, 125, 139, 221, 124, + 10, 3, 220, 232, 10, 3, 220, 233, 139, 229, 159, 25, 250, 208, 220, 233, + 139, 229, 159, 25, 250, 207, 10, 3, 220, 223, 10, 3, 220, 221, 10, 3, + 220, 222, 195, 168, 20, 10, 3, 220, 220, 10, 3, 220, 211, 10, 3, 220, + 212, 230, 155, 10, 3, 220, 210, 10, 3, 220, 197, 10, 3, 220, 198, 211, + 63, 220, 197, 10, 3, 220, 190, 10, 3, 220, 167, 10, 3, 173, 10, 3, 220, + 104, 10, 3, 220, 105, 25, 65, 10, 3, 220, 105, 25, 42, 108, 238, 33, 108, + 140, 10, 3, 220, 105, 25, 42, 108, 231, 200, 10, 3, 220, 105, 25, 42, + 108, 220, 37, 10, 3, 220, 105, 25, 251, 207, 10, 3, 220, 105, 25, 251, + 132, 10, 3, 220, 105, 25, 250, 210, 191, 26, 199, 84, 10, 3, 220, 105, + 25, 249, 135, 10, 3, 220, 105, 25, 248, 188, 10, 3, 220, 105, 25, 237, + 225, 10, 3, 220, 105, 25, 234, 103, 10, 3, 220, 105, 25, 231, 240, 10, 3, + 220, 105, 25, 231, 200, 10, 3, 220, 105, 25, 230, 168, 10, 3, 220, 105, + 25, 230, 169, 108, 230, 168, 10, 3, 220, 105, 25, 140, 10, 3, 220, 105, + 25, 230, 73, 10, 3, 220, 105, 25, 229, 159, 25, 212, 130, 10, 3, 220, + 105, 25, 223, 202, 230, 155, 10, 3, 220, 105, 25, 223, 180, 10, 3, 220, + 105, 25, 223, 181, 108, 140, 10, 3, 220, 105, 25, 223, 181, 108, 218, + 225, 10, 3, 220, 105, 25, 221, 166, 10, 3, 220, 105, 25, 221, 141, 10, 3, + 220, 105, 25, 220, 223, 10, 3, 220, 105, 25, 220, 211, 10, 3, 220, 105, + 25, 220, 212, 108, 229, 159, 108, 65, 10, 3, 220, 105, 25, 220, 104, 10, + 3, 220, 105, 25, 219, 89, 10, 3, 220, 105, 25, 218, 225, 10, 3, 220, 105, + 25, 218, 210, 10, 3, 220, 105, 25, 216, 232, 10, 3, 220, 105, 25, 216, + 233, 108, 234, 103, 10, 3, 220, 105, 25, 215, 101, 10, 3, 220, 105, 25, + 214, 121, 10, 3, 220, 105, 25, 203, 114, 108, 200, 204, 10, 3, 220, 105, + 25, 203, 59, 108, 231, 24, 108, 234, 28, 10, 3, 220, 105, 25, 203, 59, + 108, 231, 24, 199, 84, 10, 3, 220, 105, 25, 203, 3, 10, 3, 220, 105, 25, + 203, 4, 108, 203, 3, 10, 3, 220, 105, 25, 200, 204, 10, 3, 220, 105, 25, + 199, 223, 10, 3, 220, 105, 25, 199, 209, 10, 3, 220, 105, 25, 199, 146, + 108, 42, 108, 201, 5, 108, 180, 10, 3, 220, 105, 25, 66, 10, 3, 220, 105, + 25, 126, 108, 65, 10, 3, 220, 105, 25, 126, 108, 126, 108, 66, 10, 3, + 220, 105, 25, 196, 170, 108, 250, 209, 10, 3, 220, 105, 25, 196, 158, 10, + 3, 220, 105, 25, 196, 38, 10, 3, 220, 105, 201, 189, 10, 3, 220, 102, 10, + 3, 220, 103, 25, 203, 113, 10, 3, 220, 103, 25, 203, 114, 108, 200, 204, + 10, 3, 220, 103, 230, 155, 10, 3, 220, 103, 230, 156, 139, 220, 103, 230, + 156, 203, 113, 10, 3, 220, 98, 10, 3, 220, 37, 10, 3, 220, 38, 25, 220, + 37, 10, 3, 220, 35, 10, 3, 220, 36, 25, 220, 197, 10, 3, 220, 36, 25, + 220, 198, 108, 206, 68, 10, 3, 219, 146, 10, 3, 219, 127, 10, 3, 219, + 115, 10, 3, 219, 89, 10, 3, 218, 225, 10, 3, 218, 226, 25, 249, 135, 10, + 3, 218, 223, 10, 3, 218, 224, 25, 251, 207, 10, 3, 218, 224, 25, 249, + 135, 10, 3, 218, 224, 25, 234, 9, 10, 3, 218, 224, 25, 234, 10, 199, 84, + 10, 3, 218, 224, 25, 231, 209, 199, 84, 10, 3, 218, 224, 25, 229, 159, + 25, 249, 135, 10, 3, 218, 224, 25, 223, 180, 10, 3, 218, 224, 25, 222, + 113, 10, 3, 218, 224, 25, 222, 111, 10, 3, 218, 224, 25, 222, 112, 108, + 250, 209, 10, 3, 218, 224, 25, 221, 166, 10, 3, 218, 224, 25, 220, 126, + 108, 250, 209, 10, 3, 218, 224, 25, 220, 104, 10, 3, 218, 224, 25, 216, + 233, 108, 234, 103, 10, 3, 218, 224, 25, 214, 121, 10, 3, 218, 224, 25, + 212, 178, 10, 3, 218, 224, 25, 202, 223, 108, 250, 209, 10, 3, 218, 224, + 25, 202, 192, 108, 248, 10, 10, 3, 218, 224, 25, 197, 82, 10, 3, 218, + 224, 199, 84, 10, 3, 218, 224, 238, 210, 218, 223, 10, 3, 218, 224, 211, + 63, 218, 223, 10, 3, 218, 224, 201, 189, 10, 3, 218, 224, 203, 94, 10, 3, + 218, 222, 10, 3, 218, 216, 10, 3, 218, 217, 139, 218, 216, 10, 3, 218, + 217, 211, 63, 218, 216, 10, 3, 218, 217, 203, 94, 10, 3, 218, 213, 10, 3, + 218, 210, 10, 3, 218, 208, 10, 3, 218, 209, 139, 218, 208, 10, 3, 218, + 209, 139, 218, 209, 231, 201, 139, 231, 200, 10, 3, 174, 10, 3, 217, 160, + 25, 199, 209, 10, 3, 217, 160, 230, 155, 10, 3, 217, 152, 10, 3, 217, + 120, 10, 3, 217, 65, 10, 3, 217, 39, 10, 3, 217, 38, 10, 3, 216, 232, 10, + 3, 216, 173, 10, 3, 216, 100, 10, 3, 216, 44, 10, 3, 215, 155, 10, 3, + 215, 156, 139, 215, 155, 10, 3, 215, 140, 10, 3, 215, 141, 230, 155, 10, + 3, 215, 119, 10, 3, 215, 105, 10, 3, 215, 101, 10, 3, 215, 102, 25, 65, + 10, 3, 215, 102, 25, 220, 197, 10, 3, 215, 102, 25, 191, 123, 10, 3, 215, + 102, 139, 215, 101, 10, 3, 215, 102, 139, 215, 102, 25, 42, 108, 180, 10, + 3, 215, 102, 238, 210, 215, 101, 10, 3, 215, 99, 10, 3, 215, 100, 25, 65, + 10, 3, 215, 100, 25, 42, 108, 237, 44, 10, 3, 215, 100, 25, 237, 44, 10, + 3, 215, 100, 230, 155, 10, 3, 180, 10, 3, 214, 253, 10, 3, 214, 240, 10, + 3, 214, 241, 223, 92, 10, 3, 214, 241, 25, 203, 6, 199, 84, 10, 3, 214, + 241, 211, 63, 214, 240, 10, 3, 214, 239, 10, 3, 214, 231, 212, 116, 10, + 3, 214, 230, 10, 3, 214, 229, 10, 3, 214, 121, 10, 3, 214, 122, 25, 65, + 10, 3, 214, 122, 25, 196, 158, 10, 3, 214, 122, 203, 94, 10, 3, 213, 219, + 10, 3, 213, 220, 25, 71, 10, 3, 213, 210, 10, 3, 213, 180, 10, 3, 213, + 181, 25, 231, 209, 199, 84, 10, 3, 213, 181, 25, 231, 201, 108, 231, 209, + 199, 84, 10, 3, 213, 176, 10, 3, 213, 177, 25, 251, 132, 10, 3, 213, 177, + 25, 250, 209, 10, 3, 213, 177, 25, 250, 210, 108, 250, 209, 10, 3, 213, + 177, 25, 230, 168, 10, 3, 213, 177, 25, 216, 233, 108, 231, 209, 199, 84, + 10, 3, 213, 177, 25, 214, 121, 10, 3, 213, 177, 25, 212, 130, 10, 3, 213, + 177, 25, 203, 113, 10, 3, 213, 177, 25, 203, 114, 108, 42, 251, 132, 10, + 3, 213, 177, 25, 203, 114, 108, 250, 209, 10, 3, 213, 177, 25, 203, 114, + 108, 250, 210, 108, 250, 209, 10, 3, 213, 177, 25, 196, 170, 108, 250, + 209, 10, 3, 213, 177, 25, 196, 38, 10, 3, 213, 163, 10, 3, 212, 178, 10, + 3, 212, 147, 10, 3, 212, 130, 10, 3, 212, 131, 220, 103, 25, 231, 200, + 10, 3, 212, 131, 220, 103, 25, 217, 39, 10, 3, 212, 131, 220, 103, 25, + 205, 169, 10, 3, 212, 131, 220, 103, 25, 205, 170, 139, 212, 131, 220, + 103, 25, 205, 169, 10, 3, 212, 131, 220, 103, 25, 196, 38, 10, 3, 212, + 131, 199, 84, 10, 3, 212, 131, 139, 212, 130, 10, 3, 212, 131, 238, 210, + 212, 130, 10, 3, 212, 131, 238, 210, 212, 131, 220, 103, 139, 220, 102, + 10, 3, 212, 125, 10, 3, 212, 126, 252, 73, 25, 250, 203, 10, 3, 212, 126, + 252, 73, 25, 248, 188, 10, 3, 212, 126, 252, 73, 25, 235, 82, 10, 3, 212, + 126, 252, 73, 25, 230, 168, 10, 3, 212, 126, 252, 73, 25, 223, 202, 230, + 155, 10, 3, 212, 126, 252, 73, 25, 222, 111, 10, 3, 212, 126, 252, 73, + 25, 173, 10, 3, 212, 126, 252, 73, 25, 214, 121, 10, 3, 212, 126, 252, + 73, 25, 202, 189, 10, 3, 212, 126, 252, 73, 25, 196, 169, 10, 3, 212, + 126, 221, 125, 25, 248, 188, 10, 3, 212, 126, 221, 125, 25, 248, 189, 66, + 10, 3, 168, 10, 3, 210, 210, 10, 3, 210, 166, 10, 3, 210, 137, 10, 3, + 209, 243, 10, 3, 209, 185, 10, 3, 209, 186, 25, 65, 10, 3, 209, 186, 25, + 252, 155, 10, 3, 209, 186, 25, 248, 188, 10, 3, 209, 186, 25, 248, 10, + 10, 3, 209, 186, 25, 71, 10, 3, 209, 186, 25, 68, 10, 3, 209, 186, 25, + 228, 30, 10, 3, 209, 186, 25, 66, 10, 3, 209, 186, 25, 196, 169, 10, 3, + 209, 186, 238, 210, 209, 185, 10, 3, 209, 121, 10, 3, 209, 122, 25, 222, + 91, 10, 3, 209, 122, 25, 196, 158, 10, 3, 209, 122, 25, 191, 123, 10, 3, + 209, 122, 211, 63, 209, 121, 10, 3, 165, 10, 3, 207, 176, 10, 3, 207, 1, + 10, 3, 206, 68, 10, 3, 188, 10, 3, 205, 186, 212, 116, 10, 3, 205, 185, + 10, 3, 205, 186, 25, 65, 10, 3, 205, 186, 25, 235, 89, 10, 3, 205, 186, + 25, 235, 87, 10, 3, 205, 186, 25, 140, 10, 3, 205, 186, 25, 222, 96, 10, + 3, 205, 186, 25, 220, 197, 10, 3, 205, 186, 25, 218, 208, 10, 3, 205, + 186, 25, 216, 100, 10, 3, 205, 186, 25, 212, 130, 10, 3, 205, 186, 25, + 205, 169, 10, 3, 205, 186, 25, 203, 79, 10, 3, 205, 186, 25, 199, 236, + 10, 3, 205, 186, 25, 196, 169, 10, 3, 205, 186, 25, 196, 164, 10, 3, 205, + 186, 25, 196, 120, 10, 3, 205, 186, 25, 196, 62, 10, 3, 205, 186, 25, + 196, 38, 10, 3, 205, 186, 139, 205, 185, 10, 3, 205, 186, 230, 155, 10, + 3, 205, 169, 10, 3, 205, 170, 220, 105, 25, 250, 207, 10, 3, 205, 136, + 10, 3, 205, 127, 10, 3, 203, 165, 10, 3, 203, 163, 10, 3, 203, 164, 25, + 65, 10, 3, 203, 164, 25, 249, 135, 10, 3, 203, 164, 25, 231, 23, 10, 3, + 203, 164, 25, 214, 121, 10, 3, 203, 164, 25, 203, 3, 10, 3, 203, 164, 25, + 197, 64, 10, 3, 203, 164, 25, 66, 10, 3, 203, 164, 25, 126, 108, 65, 10, + 3, 203, 161, 10, 3, 203, 159, 10, 3, 203, 131, 10, 3, 203, 113, 10, 3, + 203, 114, 228, 159, 10, 3, 203, 114, 139, 203, 114, 231, 232, 139, 231, + 232, 231, 201, 139, 231, 200, 10, 3, 203, 114, 139, 203, 114, 199, 237, + 139, 199, 237, 231, 201, 139, 231, 200, 10, 3, 203, 106, 10, 3, 203, 101, + 10, 3, 203, 97, 10, 3, 203, 96, 10, 3, 203, 93, 10, 3, 203, 79, 10, 3, + 203, 80, 25, 65, 10, 3, 203, 80, 25, 223, 180, 10, 3, 203, 73, 10, 3, + 203, 74, 25, 65, 10, 3, 203, 74, 25, 249, 115, 10, 3, 203, 74, 25, 247, + 242, 10, 3, 203, 74, 25, 236, 243, 10, 3, 203, 74, 25, 231, 200, 10, 3, + 203, 74, 25, 223, 201, 10, 3, 203, 74, 25, 223, 202, 230, 155, 10, 3, + 203, 74, 25, 220, 190, 10, 3, 203, 74, 25, 218, 210, 10, 3, 203, 74, 25, + 215, 140, 10, 3, 203, 74, 25, 205, 169, 10, 3, 203, 67, 10, 3, 203, 62, + 10, 3, 203, 63, 199, 84, 10, 3, 203, 63, 139, 203, 63, 247, 231, 139, + 247, 230, 10, 3, 203, 58, 10, 3, 203, 5, 10, 3, 203, 6, 139, 223, 93, + 203, 5, 10, 3, 203, 3, 10, 3, 203, 1, 10, 3, 202, 222, 10, 3, 202, 223, + 230, 155, 10, 3, 202, 201, 10, 3, 202, 199, 10, 3, 202, 200, 139, 202, + 200, 203, 3, 10, 3, 202, 191, 10, 3, 202, 189, 10, 3, 201, 4, 10, 3, 201, + 5, 139, 201, 4, 10, 3, 200, 216, 10, 3, 200, 215, 10, 3, 200, 213, 10, 3, + 200, 204, 10, 3, 200, 203, 10, 3, 200, 175, 10, 3, 200, 174, 10, 3, 190, + 190, 10, 3, 199, 252, 250, 193, 10, 3, 199, 252, 25, 229, 158, 10, 3, + 199, 252, 25, 216, 100, 10, 3, 199, 252, 230, 155, 10, 3, 199, 236, 10, + 3, 199, 237, 139, 199, 237, 213, 220, 139, 213, 220, 236, 223, 139, 236, + 222, 10, 3, 199, 237, 201, 189, 10, 3, 199, 223, 10, 3, 199, 224, 25, + 248, 188, 10, 3, 199, 224, 25, 230, 168, 10, 3, 199, 224, 25, 203, 113, + 10, 3, 199, 224, 25, 203, 5, 10, 3, 199, 224, 25, 197, 82, 10, 3, 199, + 224, 25, 196, 158, 10, 3, 199, 209, 10, 3, 199, 179, 10, 3, 199, 145, 10, + 3, 199, 146, 230, 155, 10, 3, 198, 193, 10, 3, 198, 194, 199, 84, 10, 3, + 198, 154, 10, 3, 198, 131, 10, 3, 198, 132, 25, 199, 209, 10, 3, 198, + 132, 139, 198, 131, 10, 3, 198, 132, 139, 198, 132, 231, 232, 139, 231, + 232, 231, 201, 139, 231, 200, 10, 3, 197, 94, 10, 3, 197, 82, 10, 3, 197, + 80, 10, 3, 197, 76, 10, 3, 197, 64, 10, 3, 197, 65, 139, 197, 65, 191, + 124, 139, 191, 123, 10, 3, 66, 10, 3, 126, 230, 168, 10, 3, 126, 126, 66, + 10, 3, 126, 139, 126, 210, 221, 139, 210, 221, 231, 201, 139, 231, 200, + 10, 3, 126, 139, 126, 200, 176, 139, 200, 175, 10, 3, 126, 139, 126, 126, + 207, 18, 139, 126, 207, 17, 10, 3, 196, 169, 10, 3, 196, 164, 10, 3, 196, + 158, 10, 3, 196, 159, 220, 190, 10, 3, 196, 159, 25, 249, 135, 10, 3, + 196, 159, 25, 216, 100, 10, 3, 196, 159, 25, 126, 108, 126, 108, 66, 10, + 3, 196, 159, 25, 126, 108, 126, 108, 126, 230, 155, 10, 3, 196, 159, 230, + 155, 10, 3, 196, 159, 203, 94, 10, 3, 196, 159, 203, 95, 25, 249, 135, + 10, 3, 196, 153, 10, 3, 196, 120, 10, 3, 196, 121, 25, 220, 104, 10, 3, + 196, 121, 25, 216, 233, 108, 238, 32, 10, 3, 196, 121, 25, 203, 163, 10, + 3, 196, 121, 25, 66, 10, 3, 196, 119, 10, 3, 196, 115, 10, 3, 196, 116, + 25, 222, 54, 10, 3, 196, 116, 25, 168, 10, 3, 196, 113, 10, 3, 196, 114, + 230, 155, 10, 3, 196, 62, 10, 3, 196, 63, 238, 210, 196, 62, 10, 3, 196, + 63, 203, 94, 10, 3, 196, 60, 10, 3, 196, 61, 25, 42, 108, 140, 10, 3, + 196, 61, 25, 42, 108, 180, 10, 3, 196, 61, 25, 251, 207, 10, 3, 196, 61, + 25, 140, 10, 3, 196, 61, 25, 212, 130, 10, 3, 196, 61, 25, 196, 169, 10, + 3, 196, 61, 25, 196, 170, 108, 250, 209, 10, 3, 196, 61, 25, 196, 170, + 108, 248, 188, 10, 3, 196, 59, 10, 3, 196, 56, 10, 3, 196, 55, 10, 3, + 196, 51, 10, 3, 196, 52, 25, 65, 10, 3, 196, 52, 25, 250, 203, 10, 3, + 196, 52, 25, 164, 10, 3, 196, 52, 25, 235, 75, 10, 3, 196, 52, 25, 231, + 240, 10, 3, 196, 52, 25, 231, 222, 10, 3, 196, 52, 25, 231, 209, 199, 84, + 10, 3, 196, 52, 25, 231, 200, 10, 3, 196, 52, 25, 230, 179, 10, 3, 196, + 52, 25, 140, 10, 3, 196, 52, 25, 223, 201, 10, 3, 196, 52, 25, 223, 180, + 10, 3, 196, 52, 25, 223, 62, 10, 3, 196, 52, 25, 221, 166, 10, 3, 196, + 52, 25, 218, 208, 10, 3, 196, 52, 25, 216, 44, 10, 3, 196, 52, 25, 168, + 10, 3, 196, 52, 25, 203, 113, 10, 3, 196, 52, 25, 202, 199, 10, 3, 196, + 52, 25, 197, 94, 10, 3, 196, 52, 25, 126, 108, 230, 168, 10, 3, 196, 52, + 25, 196, 158, 10, 3, 196, 52, 25, 196, 49, 10, 3, 196, 49, 10, 3, 196, + 50, 25, 66, 10, 3, 196, 38, 10, 3, 196, 39, 25, 65, 10, 3, 196, 39, 25, + 220, 232, 10, 3, 196, 39, 25, 220, 197, 10, 3, 196, 39, 25, 199, 209, 10, + 3, 196, 34, 10, 3, 196, 37, 10, 3, 196, 35, 10, 3, 196, 31, 10, 3, 196, + 16, 10, 3, 196, 17, 25, 222, 54, 10, 3, 196, 14, 10, 3, 191, 123, 10, 3, + 191, 124, 199, 84, 10, 3, 191, 124, 112, 25, 220, 197, 10, 3, 191, 118, + 10, 3, 191, 107, 10, 3, 191, 86, 10, 3, 191, 30, 10, 3, 191, 31, 139, + 191, 30, 10, 3, 191, 29, 10, 3, 191, 27, 10, 3, 191, 28, 222, 116, 199, + 84, 10, 3, 191, 22, 10, 3, 191, 13, 10, 3, 190, 251, 10, 3, 190, 249, 10, + 3, 190, 250, 25, 65, 10, 3, 190, 248, 10, 3, 190, 247, 10, 3, 222, 79, + 234, 137, 10, 3, 252, 156, 25, 212, 130, 10, 3, 252, 73, 25, 65, 10, 3, + 251, 146, 25, 220, 213, 10, 3, 238, 23, 221, 125, 25, 196, 170, 108, 217, + 39, 10, 3, 238, 21, 10, 3, 236, 223, 108, 203, 5, 10, 3, 235, 88, 25, + 203, 113, 10, 3, 233, 181, 25, 230, 168, 10, 3, 233, 181, 25, 203, 113, + 10, 3, 231, 239, 25, 251, 133, 108, 222, 97, 108, 65, 10, 3, 231, 239, + 25, 250, 207, 10, 3, 231, 164, 10, 3, 231, 42, 10, 3, 228, 131, 10, 3, + 222, 142, 25, 251, 91, 10, 3, 222, 142, 25, 250, 206, 10, 3, 222, 142, + 25, 231, 23, 10, 3, 222, 142, 25, 230, 168, 10, 3, 222, 142, 25, 229, + 159, 25, 250, 207, 10, 3, 222, 142, 25, 218, 208, 10, 3, 222, 142, 25, + 168, 10, 3, 222, 142, 25, 202, 253, 10, 3, 222, 142, 25, 197, 94, 10, 3, + 222, 142, 25, 196, 60, 10, 3, 220, 105, 25, 231, 53, 10, 3, 218, 224, + 203, 95, 25, 249, 135, 10, 3, 218, 224, 25, 234, 10, 108, 220, 37, 10, 3, + 218, 224, 25, 203, 5, 10, 3, 216, 172, 10, 3, 215, 100, 25, 191, 123, 10, + 3, 214, 252, 10, 3, 213, 179, 10, 3, 213, 178, 10, 3, 213, 177, 25, 249, + 115, 10, 3, 213, 177, 25, 231, 53, 10, 3, 212, 148, 206, 122, 213, 170, + 237, 124, 10, 3, 209, 244, 250, 193, 10, 3, 209, 125, 10, 3, 205, 186, + 25, 223, 202, 230, 155, 10, 3, 198, 185, 10, 3, 196, 121, 25, 216, 232, + 10, 3, 126, 66, 10, 167, 3, 105, 250, 209, 10, 167, 3, 115, 250, 209, 10, + 167, 3, 232, 128, 250, 209, 10, 167, 3, 232, 226, 250, 209, 10, 167, 3, + 202, 136, 250, 209, 10, 167, 3, 203, 247, 250, 209, 10, 167, 3, 234, 164, + 250, 209, 10, 167, 3, 213, 175, 250, 209, 10, 167, 3, 115, 236, 222, 10, + 167, 3, 232, 128, 236, 222, 10, 167, 3, 232, 226, 236, 222, 10, 167, 3, + 202, 136, 236, 222, 10, 167, 3, 203, 247, 236, 222, 10, 167, 3, 234, 164, + 236, 222, 10, 167, 3, 213, 175, 236, 222, 10, 167, 3, 232, 128, 66, 10, + 167, 3, 232, 226, 66, 10, 167, 3, 202, 136, 66, 10, 167, 3, 203, 247, 66, + 10, 167, 3, 234, 164, 66, 10, 167, 3, 213, 175, 66, 10, 167, 3, 91, 231, + 136, 10, 167, 3, 105, 231, 136, 10, 167, 3, 115, 231, 136, 10, 167, 3, + 232, 128, 231, 136, 10, 167, 3, 232, 226, 231, 136, 10, 167, 3, 202, 136, + 231, 136, 10, 167, 3, 203, 247, 231, 136, 10, 167, 3, 234, 164, 231, 136, + 10, 167, 3, 213, 175, 231, 136, 10, 167, 3, 91, 231, 133, 10, 167, 3, + 105, 231, 133, 10, 167, 3, 115, 231, 133, 10, 167, 3, 232, 128, 231, 133, + 10, 167, 3, 232, 226, 231, 133, 10, 167, 3, 105, 203, 131, 10, 167, 3, + 115, 203, 131, 10, 167, 3, 115, 203, 132, 195, 168, 20, 10, 167, 3, 232, + 128, 203, 131, 10, 167, 3, 232, 226, 203, 131, 10, 167, 3, 202, 136, 203, + 131, 10, 167, 3, 203, 247, 203, 131, 10, 167, 3, 234, 164, 203, 131, 10, + 167, 3, 213, 175, 203, 131, 10, 167, 3, 91, 203, 124, 10, 167, 3, 105, + 203, 124, 10, 167, 3, 115, 203, 124, 10, 167, 3, 115, 203, 125, 195, 168, + 20, 10, 167, 3, 232, 128, 203, 124, 10, 167, 3, 232, 226, 203, 124, 10, + 167, 3, 203, 132, 25, 231, 223, 108, 236, 222, 10, 167, 3, 203, 132, 25, + 231, 223, 108, 216, 44, 10, 167, 3, 91, 247, 226, 10, 167, 3, 105, 247, + 226, 10, 167, 3, 115, 247, 226, 10, 167, 3, 115, 247, 227, 195, 168, 20, + 10, 167, 3, 232, 128, 247, 226, 10, 167, 3, 232, 226, 247, 226, 10, 167, + 3, 115, 195, 168, 232, 146, 234, 11, 10, 167, 3, 115, 195, 168, 232, 146, + 234, 8, 10, 167, 3, 232, 128, 195, 168, 232, 146, 219, 116, 10, 167, 3, + 232, 128, 195, 168, 232, 146, 219, 114, 10, 167, 3, 232, 128, 195, 168, + 232, 146, 219, 117, 65, 10, 167, 3, 232, 128, 195, 168, 232, 146, 219, + 117, 250, 120, 10, 167, 3, 202, 136, 195, 168, 232, 146, 250, 205, 10, + 167, 3, 203, 247, 195, 168, 232, 146, 223, 171, 10, 167, 3, 203, 247, + 195, 168, 232, 146, 223, 173, 65, 10, 167, 3, 203, 247, 195, 168, 232, + 146, 223, 173, 250, 120, 10, 167, 3, 234, 164, 195, 168, 232, 146, 196, + 33, 10, 167, 3, 234, 164, 195, 168, 232, 146, 196, 32, 10, 167, 3, 213, + 175, 195, 168, 232, 146, 223, 188, 10, 167, 3, 213, 175, 195, 168, 232, + 146, 223, 187, 10, 167, 3, 213, 175, 195, 168, 232, 146, 223, 186, 10, + 167, 3, 213, 175, 195, 168, 232, 146, 223, 189, 65, 10, 167, 3, 105, 250, + 210, 199, 84, 10, 167, 3, 115, 250, 210, 199, 84, 10, 167, 3, 232, 128, + 250, 210, 199, 84, 10, 167, 3, 232, 226, 250, 210, 199, 84, 10, 167, 3, + 202, 136, 250, 210, 199, 84, 10, 167, 3, 91, 249, 99, 10, 167, 3, 105, + 249, 99, 10, 167, 3, 115, 249, 99, 10, 167, 3, 232, 128, 249, 99, 10, + 167, 3, 232, 128, 249, 100, 195, 168, 20, 10, 167, 3, 232, 226, 249, 99, + 10, 167, 3, 232, 226, 249, 100, 195, 168, 20, 10, 167, 3, 213, 188, 10, + 167, 3, 213, 189, 10, 167, 3, 91, 234, 7, 10, 167, 3, 105, 234, 7, 10, + 167, 3, 91, 199, 1, 236, 222, 10, 167, 3, 105, 198, 254, 236, 222, 10, + 167, 3, 232, 226, 202, 123, 236, 222, 10, 167, 3, 91, 199, 1, 195, 168, + 232, 146, 65, 10, 167, 3, 105, 198, 254, 195, 168, 232, 146, 65, 10, 167, + 3, 91, 234, 160, 250, 209, 10, 167, 3, 91, 208, 23, 250, 209, 10, 167, 3, + 39, 250, 196, 91, 202, 124, 10, 167, 3, 39, 250, 196, 91, 208, 22, 10, + 167, 3, 91, 208, 23, 230, 149, 10, 167, 3, 91, 132, 230, 149, 10, 167, 3, + 234, 138, 91, 199, 0, 10, 167, 3, 234, 138, 105, 198, 253, 10, 167, 3, + 234, 138, 232, 135, 10, 167, 3, 234, 138, 233, 15, 10, 167, 3, 232, 128, + 126, 195, 168, 20, 10, 167, 3, 232, 226, 126, 195, 168, 20, 10, 167, 3, + 202, 136, 126, 195, 168, 20, 10, 167, 3, 203, 247, 126, 195, 168, 20, 10, + 167, 3, 234, 164, 126, 195, 168, 20, 10, 167, 3, 213, 175, 126, 195, 168, + 20, 10, 208, 152, 3, 39, 250, 196, 193, 23, 236, 205, 10, 208, 152, 3, + 81, 242, 83, 10, 208, 152, 3, 237, 39, 242, 83, 10, 208, 152, 3, 237, 39, + 197, 237, 10, 208, 152, 3, 237, 39, 208, 29, 10, 3, 252, 156, 25, 212, + 131, 199, 84, 10, 3, 252, 156, 25, 203, 3, 10, 3, 252, 43, 25, 234, 9, + 10, 3, 249, 136, 25, 236, 223, 199, 84, 10, 3, 249, 122, 25, 252, 72, 10, + 3, 249, 122, 25, 213, 219, 10, 3, 249, 122, 25, 191, 123, 10, 3, 248, 11, + 139, 248, 11, 25, 214, 253, 10, 3, 238, 33, 25, 199, 209, 10, 3, 238, 23, + 25, 220, 197, 10, 3, 237, 0, 25, 223, 201, 10, 3, 237, 0, 25, 126, 126, + 66, 10, 3, 236, 254, 25, 196, 158, 10, 3, 235, 83, 25, 251, 91, 10, 3, + 235, 83, 25, 250, 209, 10, 3, 235, 83, 25, 250, 210, 250, 183, 219, 224, + 10, 3, 235, 83, 25, 236, 243, 10, 3, 235, 83, 25, 235, 75, 10, 3, 235, + 83, 25, 234, 28, 10, 3, 235, 83, 25, 231, 240, 10, 3, 235, 83, 25, 231, + 53, 10, 3, 235, 83, 25, 231, 33, 230, 155, 10, 3, 235, 83, 25, 231, 23, + 10, 3, 235, 83, 25, 140, 10, 3, 235, 83, 25, 229, 158, 10, 3, 235, 83, + 25, 223, 202, 230, 155, 10, 3, 235, 83, 25, 222, 54, 10, 3, 235, 83, 25, + 220, 197, 10, 3, 235, 83, 25, 220, 190, 10, 3, 235, 83, 25, 220, 191, + 108, 222, 54, 10, 3, 235, 83, 25, 220, 92, 10, 3, 235, 83, 25, 220, 35, + 10, 3, 235, 83, 25, 220, 36, 25, 220, 197, 10, 3, 235, 83, 25, 218, 214, + 108, 231, 23, 10, 3, 235, 83, 25, 217, 39, 10, 3, 235, 83, 25, 216, 173, + 10, 3, 235, 83, 25, 216, 100, 10, 3, 235, 83, 25, 213, 219, 10, 3, 235, + 83, 25, 209, 185, 10, 3, 235, 83, 25, 203, 113, 10, 3, 235, 83, 25, 202, + 223, 230, 155, 10, 3, 234, 219, 25, 220, 197, 10, 3, 234, 219, 25, 210, + 137, 10, 3, 234, 29, 192, 235, 10, 3, 234, 10, 238, 210, 234, 9, 10, 3, + 233, 181, 203, 95, 25, 250, 209, 10, 3, 233, 181, 203, 95, 25, 229, 158, + 10, 3, 233, 181, 203, 95, 25, 223, 202, 230, 155, 10, 3, 233, 181, 203, + 95, 25, 173, 10, 3, 233, 181, 203, 95, 25, 220, 37, 10, 3, 233, 181, 203, + 95, 25, 216, 232, 10, 3, 233, 181, 203, 95, 25, 216, 173, 10, 3, 233, + 181, 203, 95, 25, 201, 4, 10, 3, 233, 181, 25, 201, 4, 10, 3, 231, 239, + 25, 249, 121, 10, 3, 231, 239, 25, 237, 0, 230, 155, 10, 3, 231, 239, 25, + 235, 83, 25, 223, 202, 230, 155, 10, 3, 231, 239, 25, 235, 83, 25, 222, + 54, 10, 3, 231, 239, 25, 234, 31, 10, 3, 231, 239, 25, 231, 240, 10, 3, + 231, 239, 25, 231, 201, 108, 237, 44, 10, 3, 231, 239, 25, 231, 201, 108, + 214, 121, 10, 3, 231, 239, 25, 230, 105, 108, 65, 10, 3, 231, 239, 25, + 220, 191, 108, 222, 54, 10, 3, 231, 239, 25, 220, 35, 10, 3, 231, 239, + 25, 220, 36, 25, 220, 197, 10, 3, 231, 239, 25, 218, 213, 10, 3, 231, + 239, 25, 215, 101, 10, 3, 231, 239, 25, 214, 121, 10, 3, 231, 239, 25, + 214, 122, 108, 234, 218, 10, 3, 231, 239, 25, 214, 122, 108, 231, 53, 10, + 3, 231, 239, 25, 203, 73, 10, 3, 231, 239, 25, 191, 13, 10, 3, 231, 234, + 206, 122, 213, 170, 237, 124, 10, 3, 231, 135, 25, 66, 10, 3, 231, 24, + 25, 231, 24, 238, 210, 231, 23, 10, 3, 230, 178, 25, 223, 202, 230, 155, + 10, 3, 230, 169, 108, 231, 24, 25, 199, 209, 10, 3, 230, 105, 199, 85, + 230, 155, 10, 3, 229, 159, 25, 250, 210, 139, 229, 159, 25, 250, 209, 10, + 3, 222, 142, 25, 248, 10, 10, 3, 222, 142, 25, 155, 10, 3, 222, 142, 25, + 126, 126, 66, 10, 3, 222, 142, 25, 196, 62, 10, 3, 220, 105, 25, 190, + 252, 139, 190, 251, 10, 3, 220, 93, 10, 3, 220, 91, 10, 3, 220, 90, 10, + 3, 220, 89, 10, 3, 220, 88, 10, 3, 220, 87, 10, 3, 220, 86, 10, 3, 220, + 85, 139, 220, 85, 230, 155, 10, 3, 220, 84, 10, 3, 220, 83, 139, 220, 82, + 10, 3, 220, 81, 10, 3, 220, 80, 10, 3, 220, 79, 10, 3, 220, 78, 10, 3, + 220, 77, 10, 3, 220, 76, 10, 3, 220, 75, 10, 3, 220, 74, 10, 3, 220, 73, + 10, 3, 220, 72, 10, 3, 220, 71, 10, 3, 220, 70, 10, 3, 220, 69, 10, 3, + 220, 68, 10, 3, 220, 67, 10, 3, 220, 66, 10, 3, 220, 65, 10, 3, 220, 64, + 10, 3, 220, 62, 10, 3, 220, 63, 25, 230, 179, 10, 3, 220, 63, 25, 223, + 201, 10, 3, 220, 63, 25, 210, 138, 108, 218, 222, 10, 3, 220, 63, 25, + 210, 138, 108, 210, 138, 108, 218, 222, 10, 3, 220, 63, 25, 196, 170, + 108, 249, 153, 10, 3, 220, 61, 10, 3, 220, 60, 10, 3, 220, 59, 10, 3, 220, 58, 10, 3, 220, 57, 10, 3, 220, 56, 10, 3, 220, 55, 10, 3, 220, 54, - 10, 3, 220, 53, 10, 3, 220, 52, 10, 3, 220, 51, 10, 3, 220, 50, 10, 3, - 220, 49, 10, 3, 220, 48, 10, 3, 220, 47, 10, 3, 220, 46, 10, 3, 220, 45, - 10, 3, 220, 44, 10, 3, 220, 43, 10, 3, 220, 42, 10, 3, 220, 41, 10, 3, - 220, 40, 10, 3, 220, 38, 10, 3, 220, 39, 25, 230, 146, 10, 3, 220, 39, - 25, 223, 172, 10, 3, 220, 39, 25, 210, 128, 107, 218, 200, 10, 3, 220, - 39, 25, 210, 128, 107, 210, 128, 107, 218, 200, 10, 3, 220, 39, 25, 196, - 166, 107, 249, 103, 10, 3, 220, 37, 10, 3, 220, 36, 10, 3, 220, 35, 10, - 3, 220, 34, 10, 3, 220, 33, 10, 3, 220, 32, 10, 3, 220, 31, 10, 3, 220, - 30, 10, 3, 220, 29, 10, 3, 220, 28, 10, 3, 220, 26, 10, 3, 220, 27, 25, - 250, 159, 10, 3, 220, 27, 25, 249, 85, 10, 3, 220, 27, 25, 235, 30, 230, - 123, 230, 122, 10, 3, 220, 27, 25, 220, 199, 10, 3, 220, 27, 25, 171, 10, - 3, 220, 27, 25, 199, 174, 10, 3, 220, 27, 25, 199, 140, 10, 3, 220, 27, - 25, 196, 165, 10, 3, 220, 27, 25, 196, 154, 10, 3, 220, 27, 25, 196, 45, - 10, 3, 220, 25, 10, 3, 220, 23, 10, 3, 220, 24, 25, 235, 43, 10, 3, 220, - 24, 25, 231, 203, 10, 3, 220, 24, 25, 223, 172, 10, 3, 220, 24, 25, 223, - 173, 230, 122, 10, 3, 220, 24, 25, 213, 205, 10, 3, 220, 24, 25, 210, - 128, 107, 210, 128, 107, 218, 200, 10, 3, 220, 24, 25, 203, 93, 107, 221, - 142, 10, 3, 220, 24, 25, 196, 154, 10, 3, 220, 24, 25, 196, 45, 10, 3, - 220, 21, 10, 3, 220, 20, 10, 3, 218, 202, 230, 123, 25, 250, 159, 10, 3, - 218, 202, 25, 236, 177, 10, 3, 218, 202, 25, 230, 40, 10, 3, 218, 202, - 25, 210, 127, 10, 3, 218, 202, 25, 210, 128, 107, 210, 128, 107, 218, - 200, 10, 3, 218, 202, 25, 199, 204, 10, 3, 216, 82, 107, 191, 122, 10, 3, - 215, 88, 138, 215, 88, 25, 231, 203, 10, 3, 215, 88, 138, 215, 88, 25, - 222, 69, 10, 3, 213, 163, 25, 236, 211, 230, 122, 10, 3, 213, 163, 25, - 230, 243, 10, 3, 213, 163, 25, 230, 127, 10, 3, 213, 163, 25, 229, 126, - 10, 3, 213, 163, 25, 221, 217, 10, 3, 213, 163, 25, 220, 64, 10, 3, 213, - 163, 25, 217, 20, 10, 3, 213, 163, 25, 210, 128, 107, 210, 127, 10, 3, - 213, 163, 25, 69, 10, 3, 213, 163, 25, 126, 107, 69, 10, 3, 213, 163, 25, - 196, 45, 10, 3, 205, 181, 230, 123, 25, 144, 10, 3, 205, 181, 25, 234, - 61, 10, 3, 205, 181, 25, 203, 109, 250, 133, 219, 200, 10, 3, 205, 181, - 25, 199, 204, 10, 3, 203, 157, 199, 79, 10, 3, 203, 109, 138, 203, 108, - 10, 3, 203, 109, 107, 228, 120, 10, 3, 203, 109, 107, 214, 215, 10, 3, - 203, 109, 107, 205, 122, 10, 3, 202, 255, 107, 235, 39, 25, 213, 205, 10, - 3, 202, 255, 107, 234, 175, 25, 251, 81, 10, 3, 202, 218, 25, 199, 204, - 10, 3, 199, 205, 107, 205, 180, 10, 3, 197, 73, 25, 231, 172, 199, 79, - 10, 3, 197, 73, 25, 115, 236, 177, 10, 3, 196, 57, 223, 64, 10, 3, 196, - 57, 25, 196, 154, 10, 3, 196, 48, 25, 237, 179, 10, 3, 196, 48, 25, 220, - 22, 10, 3, 196, 48, 25, 218, 200, 10, 3, 191, 122, 10, 3, 190, 252, 138, - 190, 252, 107, 205, 122, 10, 3, 190, 250, 25, 115, 236, 178, 199, 79, - 238, 87, 3, 242, 150, 238, 87, 3, 242, 149, 238, 87, 3, 242, 148, 238, - 87, 3, 242, 147, 238, 87, 3, 242, 146, 238, 87, 3, 242, 145, 238, 87, 3, - 242, 144, 238, 87, 3, 242, 143, 238, 87, 3, 242, 142, 238, 87, 3, 242, - 141, 238, 87, 3, 242, 140, 238, 87, 3, 242, 139, 238, 87, 3, 242, 138, - 238, 87, 3, 242, 137, 238, 87, 3, 242, 136, 238, 87, 3, 242, 135, 238, - 87, 3, 242, 134, 238, 87, 3, 242, 133, 238, 87, 3, 242, 132, 238, 87, 3, - 242, 131, 238, 87, 3, 242, 130, 238, 87, 3, 242, 129, 238, 87, 3, 242, - 128, 238, 87, 3, 242, 127, 238, 87, 3, 242, 126, 238, 87, 3, 242, 125, - 238, 87, 3, 242, 124, 238, 87, 3, 242, 123, 238, 87, 3, 242, 122, 238, - 87, 3, 242, 121, 238, 87, 3, 242, 120, 238, 87, 3, 242, 119, 238, 87, 3, - 242, 118, 238, 87, 3, 242, 117, 238, 87, 3, 242, 116, 238, 87, 3, 242, - 115, 238, 87, 3, 242, 114, 238, 87, 3, 242, 113, 238, 87, 3, 242, 112, - 238, 87, 3, 242, 111, 238, 87, 3, 242, 110, 238, 87, 3, 242, 109, 238, - 87, 3, 242, 108, 238, 87, 3, 242, 107, 238, 87, 3, 242, 106, 238, 87, 3, - 242, 105, 238, 87, 3, 242, 104, 238, 87, 3, 242, 103, 238, 87, 3, 242, - 102, 238, 87, 3, 242, 101, 238, 87, 3, 242, 100, 238, 87, 3, 242, 99, - 238, 87, 3, 242, 98, 238, 87, 3, 242, 97, 238, 87, 3, 242, 96, 238, 87, - 3, 242, 95, 238, 87, 3, 242, 94, 238, 87, 3, 242, 93, 238, 87, 3, 242, - 92, 238, 87, 3, 242, 91, 238, 87, 3, 242, 90, 238, 87, 3, 242, 89, 238, - 87, 3, 242, 88, 238, 87, 3, 242, 87, 238, 87, 3, 242, 86, 238, 87, 3, - 242, 85, 238, 87, 3, 242, 84, 238, 87, 3, 242, 83, 238, 87, 3, 242, 82, - 238, 87, 3, 242, 81, 238, 87, 3, 242, 80, 238, 87, 3, 242, 79, 238, 87, - 3, 242, 78, 238, 87, 3, 242, 77, 238, 87, 3, 242, 76, 238, 87, 3, 242, - 75, 238, 87, 3, 242, 74, 238, 87, 3, 242, 73, 238, 87, 3, 242, 72, 238, - 87, 3, 242, 71, 238, 87, 3, 242, 70, 238, 87, 3, 242, 69, 238, 87, 3, - 242, 68, 238, 87, 3, 242, 67, 238, 87, 3, 242, 66, 238, 87, 3, 242, 65, - 238, 87, 3, 242, 64, 238, 87, 3, 242, 63, 238, 87, 3, 242, 62, 238, 87, - 3, 242, 61, 238, 87, 3, 242, 60, 238, 87, 3, 242, 59, 238, 87, 3, 242, - 58, 238, 87, 3, 242, 57, 238, 87, 3, 242, 56, 238, 87, 3, 242, 55, 238, - 87, 3, 242, 54, 238, 87, 3, 242, 53, 238, 87, 3, 242, 52, 14, 7, 255, - 147, 14, 7, 255, 146, 14, 7, 255, 145, 14, 7, 255, 144, 14, 7, 255, 143, - 14, 7, 255, 142, 14, 7, 255, 141, 14, 7, 255, 140, 14, 7, 255, 139, 14, - 7, 255, 138, 14, 7, 255, 137, 14, 7, 255, 136, 14, 7, 255, 135, 14, 7, - 255, 133, 14, 7, 255, 132, 14, 7, 255, 131, 14, 7, 255, 130, 14, 7, 255, - 129, 14, 7, 255, 128, 14, 7, 255, 127, 14, 7, 255, 126, 14, 7, 255, 125, - 14, 7, 255, 124, 14, 7, 255, 123, 14, 7, 255, 122, 14, 7, 255, 121, 14, - 7, 255, 120, 14, 7, 255, 119, 14, 7, 255, 118, 14, 7, 255, 117, 14, 7, - 255, 116, 14, 7, 255, 114, 14, 7, 255, 113, 14, 7, 255, 111, 14, 7, 255, - 110, 14, 7, 255, 109, 14, 7, 255, 108, 14, 7, 255, 107, 14, 7, 255, 106, - 14, 7, 255, 105, 14, 7, 255, 104, 14, 7, 255, 103, 14, 7, 255, 102, 14, - 7, 255, 101, 14, 7, 255, 100, 14, 7, 255, 98, 14, 7, 255, 97, 14, 7, 255, - 96, 14, 7, 255, 94, 14, 7, 255, 93, 14, 7, 255, 92, 14, 7, 255, 91, 14, - 7, 255, 90, 14, 7, 255, 89, 14, 7, 255, 88, 14, 7, 255, 87, 14, 7, 255, - 84, 14, 7, 255, 83, 14, 7, 255, 82, 14, 7, 255, 81, 14, 7, 255, 80, 14, - 7, 255, 79, 14, 7, 255, 78, 14, 7, 255, 77, 14, 7, 255, 76, 14, 7, 255, - 75, 14, 7, 255, 74, 14, 7, 255, 73, 14, 7, 255, 72, 14, 7, 255, 71, 14, - 7, 255, 70, 14, 7, 255, 69, 14, 7, 255, 68, 14, 7, 255, 67, 14, 7, 255, - 66, 14, 7, 255, 65, 14, 7, 255, 61, 14, 7, 255, 60, 14, 7, 255, 59, 14, - 7, 255, 58, 14, 7, 250, 68, 14, 7, 250, 66, 14, 7, 250, 64, 14, 7, 250, - 62, 14, 7, 250, 60, 14, 7, 250, 59, 14, 7, 250, 57, 14, 7, 250, 55, 14, - 7, 250, 53, 14, 7, 250, 51, 14, 7, 247, 141, 14, 7, 247, 140, 14, 7, 247, - 139, 14, 7, 247, 138, 14, 7, 247, 137, 14, 7, 247, 136, 14, 7, 247, 135, - 14, 7, 247, 134, 14, 7, 247, 133, 14, 7, 247, 132, 14, 7, 247, 131, 14, - 7, 247, 130, 14, 7, 247, 129, 14, 7, 247, 128, 14, 7, 247, 127, 14, 7, - 247, 126, 14, 7, 247, 125, 14, 7, 247, 124, 14, 7, 247, 123, 14, 7, 247, - 122, 14, 7, 247, 121, 14, 7, 247, 120, 14, 7, 247, 119, 14, 7, 247, 118, - 14, 7, 247, 117, 14, 7, 247, 116, 14, 7, 247, 115, 14, 7, 247, 114, 14, - 7, 238, 79, 14, 7, 238, 78, 14, 7, 238, 77, 14, 7, 238, 76, 14, 7, 238, - 75, 14, 7, 238, 74, 14, 7, 238, 73, 14, 7, 238, 72, 14, 7, 238, 71, 14, - 7, 238, 70, 14, 7, 238, 69, 14, 7, 238, 68, 14, 7, 238, 67, 14, 7, 238, - 66, 14, 7, 238, 65, 14, 7, 238, 64, 14, 7, 238, 63, 14, 7, 238, 62, 14, - 7, 238, 61, 14, 7, 238, 60, 14, 7, 238, 59, 14, 7, 238, 58, 14, 7, 238, - 57, 14, 7, 238, 56, 14, 7, 238, 55, 14, 7, 238, 54, 14, 7, 238, 53, 14, - 7, 238, 52, 14, 7, 238, 51, 14, 7, 238, 50, 14, 7, 238, 49, 14, 7, 238, - 48, 14, 7, 238, 47, 14, 7, 238, 46, 14, 7, 238, 45, 14, 7, 238, 44, 14, - 7, 238, 43, 14, 7, 238, 42, 14, 7, 238, 41, 14, 7, 238, 40, 14, 7, 238, - 39, 14, 7, 238, 38, 14, 7, 238, 37, 14, 7, 238, 36, 14, 7, 238, 35, 14, - 7, 238, 34, 14, 7, 238, 33, 14, 7, 238, 32, 14, 7, 238, 31, 14, 7, 238, - 30, 14, 7, 238, 29, 14, 7, 238, 28, 14, 7, 238, 27, 14, 7, 238, 26, 14, - 7, 238, 25, 14, 7, 238, 24, 14, 7, 238, 23, 14, 7, 238, 22, 14, 7, 238, - 21, 14, 7, 238, 20, 14, 7, 238, 19, 14, 7, 238, 18, 14, 7, 238, 17, 14, - 7, 238, 16, 14, 7, 238, 15, 14, 7, 238, 14, 14, 7, 238, 13, 14, 7, 238, - 12, 14, 7, 238, 11, 14, 7, 238, 10, 14, 7, 238, 9, 14, 7, 238, 8, 14, 7, - 238, 7, 14, 7, 238, 6, 14, 7, 238, 5, 14, 7, 238, 4, 14, 7, 238, 3, 14, - 7, 238, 2, 14, 7, 238, 1, 14, 7, 238, 0, 14, 7, 237, 255, 14, 7, 237, - 254, 14, 7, 237, 253, 14, 7, 237, 252, 14, 7, 237, 251, 14, 7, 237, 250, - 14, 7, 237, 249, 14, 7, 237, 248, 14, 7, 237, 247, 14, 7, 237, 246, 14, - 7, 237, 245, 14, 7, 237, 244, 14, 7, 234, 219, 14, 7, 234, 218, 14, 7, - 234, 217, 14, 7, 234, 216, 14, 7, 234, 215, 14, 7, 234, 214, 14, 7, 234, - 213, 14, 7, 234, 212, 14, 7, 234, 211, 14, 7, 234, 210, 14, 7, 234, 209, - 14, 7, 234, 208, 14, 7, 234, 207, 14, 7, 234, 206, 14, 7, 234, 205, 14, - 7, 234, 204, 14, 7, 234, 203, 14, 7, 234, 202, 14, 7, 234, 201, 14, 7, - 234, 200, 14, 7, 234, 199, 14, 7, 234, 198, 14, 7, 234, 197, 14, 7, 234, - 196, 14, 7, 234, 195, 14, 7, 234, 194, 14, 7, 234, 193, 14, 7, 234, 192, - 14, 7, 234, 191, 14, 7, 234, 190, 14, 7, 234, 189, 14, 7, 234, 188, 14, - 7, 234, 187, 14, 7, 234, 186, 14, 7, 234, 185, 14, 7, 234, 184, 14, 7, - 234, 183, 14, 7, 234, 182, 14, 7, 234, 181, 14, 7, 234, 180, 14, 7, 234, - 179, 14, 7, 234, 178, 14, 7, 234, 177, 14, 7, 234, 176, 14, 7, 233, 133, - 14, 7, 233, 132, 14, 7, 233, 131, 14, 7, 233, 130, 14, 7, 233, 129, 14, - 7, 233, 128, 14, 7, 233, 127, 14, 7, 233, 126, 14, 7, 233, 125, 14, 7, - 233, 124, 14, 7, 233, 123, 14, 7, 233, 122, 14, 7, 233, 121, 14, 7, 233, - 120, 14, 7, 233, 119, 14, 7, 233, 118, 14, 7, 233, 117, 14, 7, 233, 116, - 14, 7, 233, 115, 14, 7, 233, 114, 14, 7, 233, 113, 14, 7, 233, 112, 14, - 7, 233, 111, 14, 7, 233, 110, 14, 7, 233, 109, 14, 7, 233, 108, 14, 7, - 233, 107, 14, 7, 233, 106, 14, 7, 233, 105, 14, 7, 233, 104, 14, 7, 233, - 103, 14, 7, 233, 102, 14, 7, 233, 101, 14, 7, 233, 100, 14, 7, 233, 99, - 14, 7, 233, 98, 14, 7, 233, 97, 14, 7, 233, 96, 14, 7, 233, 95, 14, 7, - 233, 94, 14, 7, 233, 93, 14, 7, 233, 92, 14, 7, 233, 91, 14, 7, 233, 90, - 14, 7, 233, 89, 14, 7, 233, 88, 14, 7, 233, 87, 14, 7, 233, 86, 14, 7, - 233, 85, 14, 7, 233, 84, 14, 7, 233, 83, 14, 7, 233, 82, 14, 7, 233, 81, - 14, 7, 233, 80, 14, 7, 233, 79, 14, 7, 233, 78, 14, 7, 233, 77, 14, 7, - 233, 76, 14, 7, 233, 75, 14, 7, 233, 74, 14, 7, 233, 73, 14, 7, 233, 72, - 14, 7, 233, 71, 14, 7, 233, 70, 14, 7, 233, 69, 14, 7, 232, 13, 14, 7, - 232, 12, 14, 7, 232, 11, 14, 7, 232, 10, 14, 7, 232, 9, 14, 7, 232, 8, - 14, 7, 232, 7, 14, 7, 232, 6, 14, 7, 232, 5, 14, 7, 232, 4, 14, 7, 232, - 3, 14, 7, 232, 2, 14, 7, 232, 1, 14, 7, 232, 0, 14, 7, 231, 255, 14, 7, - 231, 254, 14, 7, 231, 253, 14, 7, 231, 252, 14, 7, 231, 251, 14, 7, 231, - 250, 14, 7, 231, 249, 14, 7, 231, 248, 14, 7, 231, 247, 14, 7, 231, 246, - 14, 7, 231, 245, 14, 7, 231, 244, 14, 7, 231, 243, 14, 7, 231, 242, 14, - 7, 231, 241, 14, 7, 231, 240, 14, 7, 231, 239, 14, 7, 231, 238, 14, 7, - 231, 237, 14, 7, 231, 236, 14, 7, 231, 235, 14, 7, 231, 234, 14, 7, 231, - 233, 14, 7, 231, 232, 14, 7, 231, 231, 14, 7, 231, 230, 14, 7, 231, 229, - 14, 7, 231, 228, 14, 7, 231, 227, 14, 7, 231, 226, 14, 7, 231, 225, 14, - 7, 231, 224, 14, 7, 231, 223, 14, 7, 231, 222, 14, 7, 231, 221, 14, 7, - 231, 220, 14, 7, 231, 219, 14, 7, 231, 218, 14, 7, 231, 217, 14, 7, 231, - 216, 14, 7, 231, 215, 14, 7, 231, 214, 14, 7, 231, 213, 14, 7, 231, 212, - 14, 7, 231, 211, 14, 7, 231, 210, 14, 7, 231, 209, 14, 7, 231, 208, 14, - 7, 231, 207, 14, 7, 231, 206, 14, 7, 230, 81, 14, 7, 230, 80, 14, 7, 230, - 79, 14, 7, 230, 78, 14, 7, 230, 77, 14, 7, 230, 76, 14, 7, 230, 75, 14, - 7, 230, 74, 14, 7, 230, 73, 14, 7, 228, 24, 14, 7, 228, 23, 14, 7, 228, - 22, 14, 7, 228, 21, 14, 7, 228, 20, 14, 7, 228, 19, 14, 7, 228, 18, 14, - 7, 228, 17, 14, 7, 228, 16, 14, 7, 228, 15, 14, 7, 228, 14, 14, 7, 228, - 13, 14, 7, 228, 12, 14, 7, 228, 11, 14, 7, 228, 10, 14, 7, 228, 9, 14, 7, - 228, 8, 14, 7, 228, 7, 14, 7, 228, 6, 14, 7, 222, 124, 14, 7, 222, 123, - 14, 7, 222, 122, 14, 7, 222, 121, 14, 7, 222, 120, 14, 7, 222, 119, 14, - 7, 222, 118, 14, 7, 222, 117, 14, 7, 220, 116, 14, 7, 220, 115, 14, 7, - 220, 114, 14, 7, 220, 113, 14, 7, 220, 112, 14, 7, 220, 111, 14, 7, 220, - 110, 14, 7, 220, 109, 14, 7, 220, 108, 14, 7, 220, 107, 14, 7, 218, 145, - 14, 7, 218, 144, 14, 7, 218, 143, 14, 7, 218, 141, 14, 7, 218, 139, 14, - 7, 218, 138, 14, 7, 218, 136, 14, 7, 218, 134, 14, 7, 218, 132, 14, 7, - 218, 130, 14, 7, 218, 128, 14, 7, 218, 126, 14, 7, 218, 124, 14, 7, 218, - 123, 14, 7, 218, 121, 14, 7, 218, 119, 14, 7, 218, 118, 14, 7, 218, 117, - 14, 7, 218, 116, 14, 7, 218, 115, 14, 7, 218, 114, 14, 7, 218, 113, 14, - 7, 218, 112, 14, 7, 218, 111, 14, 7, 218, 109, 14, 7, 218, 107, 14, 7, - 218, 105, 14, 7, 218, 104, 14, 7, 218, 102, 14, 7, 218, 101, 14, 7, 218, - 99, 14, 7, 218, 98, 14, 7, 218, 96, 14, 7, 218, 94, 14, 7, 218, 92, 14, - 7, 218, 90, 14, 7, 218, 88, 14, 7, 218, 87, 14, 7, 218, 85, 14, 7, 218, - 83, 14, 7, 218, 82, 14, 7, 218, 80, 14, 7, 218, 78, 14, 7, 218, 76, 14, - 7, 218, 74, 14, 7, 218, 73, 14, 7, 218, 71, 14, 7, 218, 69, 14, 7, 218, - 67, 14, 7, 218, 66, 14, 7, 218, 64, 14, 7, 218, 62, 14, 7, 218, 61, 14, - 7, 218, 60, 14, 7, 218, 58, 14, 7, 218, 56, 14, 7, 218, 54, 14, 7, 218, - 52, 14, 7, 218, 50, 14, 7, 218, 48, 14, 7, 218, 46, 14, 7, 218, 45, 14, - 7, 218, 43, 14, 7, 218, 41, 14, 7, 218, 39, 14, 7, 218, 37, 14, 7, 215, - 42, 14, 7, 215, 41, 14, 7, 215, 40, 14, 7, 215, 39, 14, 7, 215, 38, 14, - 7, 215, 37, 14, 7, 215, 36, 14, 7, 215, 35, 14, 7, 215, 34, 14, 7, 215, - 33, 14, 7, 215, 32, 14, 7, 215, 31, 14, 7, 215, 30, 14, 7, 215, 29, 14, - 7, 215, 28, 14, 7, 215, 27, 14, 7, 215, 26, 14, 7, 215, 25, 14, 7, 215, - 24, 14, 7, 215, 23, 14, 7, 215, 22, 14, 7, 215, 21, 14, 7, 215, 20, 14, - 7, 215, 19, 14, 7, 215, 18, 14, 7, 215, 17, 14, 7, 215, 16, 14, 7, 215, - 15, 14, 7, 215, 14, 14, 7, 215, 13, 14, 7, 215, 12, 14, 7, 215, 11, 14, - 7, 215, 10, 14, 7, 215, 9, 14, 7, 215, 8, 14, 7, 215, 7, 14, 7, 215, 6, - 14, 7, 215, 5, 14, 7, 215, 4, 14, 7, 215, 3, 14, 7, 215, 2, 14, 7, 215, - 1, 14, 7, 215, 0, 14, 7, 214, 255, 14, 7, 214, 254, 14, 7, 214, 253, 14, - 7, 214, 252, 14, 7, 214, 251, 14, 7, 214, 250, 14, 7, 213, 91, 14, 7, - 213, 90, 14, 7, 213, 89, 14, 7, 213, 88, 14, 7, 213, 87, 14, 7, 213, 86, - 14, 7, 213, 85, 14, 7, 213, 84, 14, 7, 213, 83, 14, 7, 213, 82, 14, 7, - 213, 81, 14, 7, 213, 80, 14, 7, 213, 79, 14, 7, 213, 78, 14, 7, 213, 77, - 14, 7, 213, 76, 14, 7, 213, 75, 14, 7, 213, 74, 14, 7, 213, 73, 14, 7, - 213, 72, 14, 7, 213, 71, 14, 7, 213, 70, 14, 7, 212, 161, 14, 7, 212, - 160, 14, 7, 212, 159, 14, 7, 212, 158, 14, 7, 212, 157, 14, 7, 212, 156, - 14, 7, 212, 155, 14, 7, 212, 154, 14, 7, 212, 153, 14, 7, 212, 152, 14, - 7, 212, 151, 14, 7, 212, 150, 14, 7, 212, 149, 14, 7, 212, 148, 14, 7, - 212, 147, 14, 7, 212, 146, 14, 7, 212, 145, 14, 7, 212, 144, 14, 7, 212, - 143, 14, 7, 212, 142, 14, 7, 212, 141, 14, 7, 212, 140, 14, 7, 212, 139, - 14, 7, 212, 138, 14, 7, 212, 137, 14, 7, 212, 136, 14, 7, 211, 245, 14, - 7, 211, 244, 14, 7, 211, 243, 14, 7, 211, 242, 14, 7, 211, 241, 14, 7, - 211, 240, 14, 7, 211, 239, 14, 7, 211, 238, 14, 7, 211, 237, 14, 7, 211, - 236, 14, 7, 211, 235, 14, 7, 211, 234, 14, 7, 211, 233, 14, 7, 211, 232, - 14, 7, 211, 231, 14, 7, 211, 230, 14, 7, 211, 229, 14, 7, 211, 228, 14, - 7, 211, 227, 14, 7, 211, 226, 14, 7, 211, 225, 14, 7, 211, 224, 14, 7, - 211, 223, 14, 7, 211, 222, 14, 7, 211, 221, 14, 7, 211, 220, 14, 7, 211, - 219, 14, 7, 211, 218, 14, 7, 211, 217, 14, 7, 211, 216, 14, 7, 211, 215, - 14, 7, 211, 214, 14, 7, 211, 213, 14, 7, 211, 212, 14, 7, 211, 211, 14, - 7, 211, 210, 14, 7, 211, 209, 14, 7, 211, 208, 14, 7, 211, 207, 14, 7, - 211, 206, 14, 7, 211, 205, 14, 7, 211, 204, 14, 7, 211, 203, 14, 7, 211, - 202, 14, 7, 211, 201, 14, 7, 211, 200, 14, 7, 211, 199, 14, 7, 211, 198, - 14, 7, 211, 197, 14, 7, 211, 196, 14, 7, 211, 195, 14, 7, 211, 194, 14, - 7, 211, 193, 14, 7, 211, 192, 14, 7, 211, 191, 14, 7, 211, 190, 14, 7, - 211, 189, 14, 7, 211, 188, 14, 7, 211, 187, 14, 7, 211, 186, 14, 7, 211, - 185, 14, 7, 211, 184, 14, 7, 211, 183, 14, 7, 211, 182, 14, 7, 211, 181, - 14, 7, 211, 180, 14, 7, 211, 179, 14, 7, 211, 178, 14, 7, 211, 177, 14, - 7, 211, 176, 14, 7, 211, 175, 14, 7, 211, 174, 14, 7, 211, 173, 14, 7, - 211, 172, 14, 7, 211, 171, 14, 7, 210, 225, 14, 7, 210, 224, 14, 7, 210, - 223, 14, 7, 210, 222, 14, 7, 210, 221, 14, 7, 210, 220, 14, 7, 210, 219, - 14, 7, 210, 218, 14, 7, 210, 217, 14, 7, 210, 216, 14, 7, 210, 215, 14, - 7, 210, 214, 14, 7, 210, 213, 14, 7, 208, 96, 14, 7, 208, 95, 14, 7, 208, - 94, 14, 7, 208, 93, 14, 7, 208, 92, 14, 7, 208, 91, 14, 7, 208, 90, 14, - 7, 207, 215, 14, 7, 207, 214, 14, 7, 207, 213, 14, 7, 207, 212, 14, 7, - 207, 211, 14, 7, 207, 210, 14, 7, 207, 209, 14, 7, 207, 208, 14, 7, 207, - 207, 14, 7, 207, 206, 14, 7, 207, 205, 14, 7, 207, 204, 14, 7, 207, 203, - 14, 7, 207, 202, 14, 7, 207, 201, 14, 7, 207, 200, 14, 7, 207, 199, 14, - 7, 207, 198, 14, 7, 207, 197, 14, 7, 207, 196, 14, 7, 207, 195, 14, 7, - 207, 194, 14, 7, 207, 193, 14, 7, 207, 192, 14, 7, 207, 191, 14, 7, 207, - 190, 14, 7, 207, 189, 14, 7, 207, 188, 14, 7, 207, 187, 14, 7, 207, 186, - 14, 7, 207, 185, 14, 7, 207, 184, 14, 7, 207, 183, 14, 7, 207, 182, 14, - 7, 206, 0, 14, 7, 205, 255, 14, 7, 205, 254, 14, 7, 205, 253, 14, 7, 205, - 252, 14, 7, 205, 251, 14, 7, 205, 250, 14, 7, 205, 249, 14, 7, 205, 248, - 14, 7, 205, 247, 14, 7, 205, 246, 14, 7, 205, 245, 14, 7, 205, 244, 14, - 7, 205, 243, 14, 7, 205, 242, 14, 7, 205, 241, 14, 7, 205, 240, 14, 7, - 205, 239, 14, 7, 205, 238, 14, 7, 205, 237, 14, 7, 205, 236, 14, 7, 205, - 235, 14, 7, 205, 234, 14, 7, 205, 233, 14, 7, 205, 232, 14, 7, 205, 231, - 14, 7, 205, 230, 14, 7, 205, 229, 14, 7, 205, 228, 14, 7, 205, 227, 14, - 7, 205, 226, 14, 7, 205, 225, 14, 7, 205, 224, 14, 7, 205, 223, 14, 7, - 205, 222, 14, 7, 205, 221, 14, 7, 205, 220, 14, 7, 205, 219, 14, 7, 205, - 218, 14, 7, 205, 217, 14, 7, 205, 216, 14, 7, 205, 215, 14, 7, 205, 214, - 14, 7, 205, 213, 14, 7, 205, 212, 14, 7, 205, 211, 14, 7, 205, 210, 14, - 7, 205, 209, 14, 7, 205, 208, 14, 7, 205, 207, 14, 7, 205, 206, 14, 7, - 205, 205, 14, 7, 205, 204, 14, 7, 205, 203, 14, 7, 200, 36, 14, 7, 200, - 35, 14, 7, 200, 34, 14, 7, 200, 33, 14, 7, 200, 32, 14, 7, 200, 31, 14, - 7, 200, 30, 14, 7, 200, 29, 14, 7, 200, 28, 14, 7, 200, 27, 14, 7, 200, - 26, 14, 7, 200, 25, 14, 7, 200, 24, 14, 7, 200, 23, 14, 7, 200, 22, 14, - 7, 200, 21, 14, 7, 200, 20, 14, 7, 200, 19, 14, 7, 200, 18, 14, 7, 200, - 17, 14, 7, 200, 16, 14, 7, 200, 15, 14, 7, 200, 14, 14, 7, 200, 13, 14, - 7, 200, 12, 14, 7, 200, 11, 14, 7, 200, 10, 14, 7, 200, 9, 14, 7, 200, 8, + 10, 3, 220, 53, 10, 3, 220, 52, 10, 3, 220, 50, 10, 3, 220, 51, 25, 250, + 209, 10, 3, 220, 51, 25, 249, 135, 10, 3, 220, 51, 25, 235, 74, 230, 156, + 230, 155, 10, 3, 220, 51, 25, 220, 223, 10, 3, 220, 51, 25, 173, 10, 3, + 220, 51, 25, 199, 179, 10, 3, 220, 51, 25, 199, 145, 10, 3, 220, 51, 25, + 196, 169, 10, 3, 220, 51, 25, 196, 158, 10, 3, 220, 51, 25, 196, 49, 10, + 3, 220, 49, 10, 3, 220, 47, 10, 3, 220, 48, 25, 235, 87, 10, 3, 220, 48, + 25, 231, 240, 10, 3, 220, 48, 25, 223, 201, 10, 3, 220, 48, 25, 223, 202, + 230, 155, 10, 3, 220, 48, 25, 213, 219, 10, 3, 220, 48, 25, 210, 138, + 108, 210, 138, 108, 218, 222, 10, 3, 220, 48, 25, 203, 98, 108, 221, 166, + 10, 3, 220, 48, 25, 196, 158, 10, 3, 220, 48, 25, 196, 49, 10, 3, 220, + 45, 10, 3, 220, 44, 10, 3, 218, 224, 230, 156, 25, 250, 209, 10, 3, 218, + 224, 25, 236, 222, 10, 3, 218, 224, 25, 230, 73, 10, 3, 218, 224, 25, + 210, 137, 10, 3, 218, 224, 25, 210, 138, 108, 210, 138, 108, 218, 222, + 10, 3, 218, 224, 25, 199, 209, 10, 3, 216, 101, 108, 191, 122, 10, 3, + 215, 102, 139, 215, 102, 25, 231, 240, 10, 3, 215, 102, 139, 215, 102, + 25, 222, 96, 10, 3, 213, 177, 25, 237, 0, 230, 155, 10, 3, 213, 177, 25, + 231, 23, 10, 3, 213, 177, 25, 230, 160, 10, 3, 213, 177, 25, 229, 158, + 10, 3, 213, 177, 25, 221, 242, 10, 3, 213, 177, 25, 220, 88, 10, 3, 213, + 177, 25, 217, 39, 10, 3, 213, 177, 25, 210, 138, 108, 210, 137, 10, 3, + 213, 177, 25, 66, 10, 3, 213, 177, 25, 126, 108, 66, 10, 3, 213, 177, 25, + 196, 49, 10, 3, 205, 186, 230, 156, 25, 140, 10, 3, 205, 186, 25, 234, + 103, 10, 3, 205, 186, 25, 203, 114, 250, 183, 219, 224, 10, 3, 205, 186, + 25, 199, 209, 10, 3, 203, 162, 199, 84, 10, 3, 203, 114, 139, 203, 113, + 10, 3, 203, 114, 108, 228, 151, 10, 3, 203, 114, 108, 214, 229, 10, 3, + 203, 114, 108, 205, 127, 10, 3, 203, 4, 108, 235, 83, 25, 213, 219, 10, + 3, 203, 4, 108, 234, 219, 25, 251, 132, 10, 3, 202, 223, 25, 199, 209, + 10, 3, 199, 210, 108, 205, 185, 10, 3, 197, 77, 25, 231, 209, 199, 84, + 10, 3, 197, 77, 25, 115, 236, 222, 10, 3, 196, 61, 223, 92, 10, 3, 196, + 61, 25, 196, 158, 10, 3, 196, 52, 25, 237, 224, 10, 3, 196, 52, 25, 220, + 46, 10, 3, 196, 52, 25, 218, 222, 10, 3, 191, 122, 10, 3, 190, 252, 139, + 190, 252, 108, 205, 127, 10, 3, 190, 250, 25, 115, 236, 223, 199, 84, + 238, 134, 3, 242, 198, 238, 134, 3, 242, 197, 238, 134, 3, 242, 196, 238, + 134, 3, 242, 195, 238, 134, 3, 242, 194, 238, 134, 3, 242, 193, 238, 134, + 3, 242, 192, 238, 134, 3, 242, 191, 238, 134, 3, 242, 190, 238, 134, 3, + 242, 189, 238, 134, 3, 242, 188, 238, 134, 3, 242, 187, 238, 134, 3, 242, + 186, 238, 134, 3, 242, 185, 238, 134, 3, 242, 184, 238, 134, 3, 242, 183, + 238, 134, 3, 242, 182, 238, 134, 3, 242, 181, 238, 134, 3, 242, 180, 238, + 134, 3, 242, 179, 238, 134, 3, 242, 178, 238, 134, 3, 242, 177, 238, 134, + 3, 242, 176, 238, 134, 3, 242, 175, 238, 134, 3, 242, 174, 238, 134, 3, + 242, 173, 238, 134, 3, 242, 172, 238, 134, 3, 242, 171, 238, 134, 3, 242, + 170, 238, 134, 3, 242, 169, 238, 134, 3, 242, 168, 238, 134, 3, 242, 167, + 238, 134, 3, 242, 166, 238, 134, 3, 242, 165, 238, 134, 3, 242, 164, 238, + 134, 3, 242, 163, 238, 134, 3, 242, 162, 238, 134, 3, 242, 161, 238, 134, + 3, 242, 160, 238, 134, 3, 242, 159, 238, 134, 3, 242, 158, 238, 134, 3, + 242, 157, 238, 134, 3, 242, 156, 238, 134, 3, 242, 155, 238, 134, 3, 242, + 154, 238, 134, 3, 242, 153, 238, 134, 3, 242, 152, 238, 134, 3, 242, 151, + 238, 134, 3, 242, 150, 238, 134, 3, 242, 149, 238, 134, 3, 242, 148, 238, + 134, 3, 242, 147, 238, 134, 3, 242, 146, 238, 134, 3, 242, 145, 238, 134, + 3, 242, 144, 238, 134, 3, 242, 143, 238, 134, 3, 242, 142, 238, 134, 3, + 242, 141, 238, 134, 3, 242, 140, 238, 134, 3, 242, 139, 238, 134, 3, 242, + 138, 238, 134, 3, 242, 137, 238, 134, 3, 242, 136, 238, 134, 3, 242, 135, + 238, 134, 3, 242, 134, 238, 134, 3, 242, 133, 238, 134, 3, 242, 132, 238, + 134, 3, 242, 131, 238, 134, 3, 242, 130, 238, 134, 3, 242, 129, 238, 134, + 3, 242, 128, 238, 134, 3, 242, 127, 238, 134, 3, 242, 126, 238, 134, 3, + 242, 125, 238, 134, 3, 242, 124, 238, 134, 3, 242, 123, 238, 134, 3, 242, + 122, 238, 134, 3, 242, 121, 238, 134, 3, 242, 120, 238, 134, 3, 242, 119, + 238, 134, 3, 242, 118, 238, 134, 3, 242, 117, 238, 134, 3, 242, 116, 238, + 134, 3, 242, 115, 238, 134, 3, 242, 114, 238, 134, 3, 242, 113, 238, 134, + 3, 242, 112, 238, 134, 3, 242, 111, 238, 134, 3, 242, 110, 238, 134, 3, + 242, 109, 238, 134, 3, 242, 108, 238, 134, 3, 242, 107, 238, 134, 3, 242, + 106, 238, 134, 3, 242, 105, 238, 134, 3, 242, 104, 238, 134, 3, 242, 103, + 238, 134, 3, 242, 102, 238, 134, 3, 242, 101, 238, 134, 3, 242, 100, 14, + 7, 255, 199, 14, 7, 255, 198, 14, 7, 255, 197, 14, 7, 255, 196, 14, 7, + 255, 195, 14, 7, 255, 194, 14, 7, 255, 193, 14, 7, 255, 192, 14, 7, 255, + 191, 14, 7, 255, 190, 14, 7, 255, 189, 14, 7, 255, 188, 14, 7, 255, 187, + 14, 7, 255, 185, 14, 7, 255, 184, 14, 7, 255, 183, 14, 7, 255, 182, 14, + 7, 255, 181, 14, 7, 255, 180, 14, 7, 255, 179, 14, 7, 255, 178, 14, 7, + 255, 177, 14, 7, 255, 176, 14, 7, 255, 175, 14, 7, 255, 174, 14, 7, 255, + 173, 14, 7, 255, 172, 14, 7, 255, 171, 14, 7, 255, 170, 14, 7, 255, 169, + 14, 7, 255, 168, 14, 7, 255, 166, 14, 7, 255, 165, 14, 7, 255, 163, 14, + 7, 255, 162, 14, 7, 255, 161, 14, 7, 255, 160, 14, 7, 255, 159, 14, 7, + 255, 158, 14, 7, 255, 157, 14, 7, 255, 156, 14, 7, 255, 155, 14, 7, 255, + 154, 14, 7, 255, 153, 14, 7, 255, 152, 14, 7, 255, 150, 14, 7, 255, 149, + 14, 7, 255, 148, 14, 7, 255, 146, 14, 7, 255, 145, 14, 7, 255, 144, 14, + 7, 255, 143, 14, 7, 255, 142, 14, 7, 255, 141, 14, 7, 255, 140, 14, 7, + 255, 139, 14, 7, 255, 136, 14, 7, 255, 135, 14, 7, 255, 134, 14, 7, 255, + 133, 14, 7, 255, 132, 14, 7, 255, 131, 14, 7, 255, 130, 14, 7, 255, 129, + 14, 7, 255, 128, 14, 7, 255, 127, 14, 7, 255, 126, 14, 7, 255, 125, 14, + 7, 255, 124, 14, 7, 255, 123, 14, 7, 255, 122, 14, 7, 255, 121, 14, 7, + 255, 120, 14, 7, 255, 119, 14, 7, 255, 118, 14, 7, 255, 117, 14, 7, 255, + 113, 14, 7, 255, 112, 14, 7, 255, 111, 14, 7, 255, 110, 14, 7, 250, 118, + 14, 7, 250, 116, 14, 7, 250, 114, 14, 7, 250, 112, 14, 7, 250, 110, 14, + 7, 250, 109, 14, 7, 250, 107, 14, 7, 250, 105, 14, 7, 250, 103, 14, 7, + 250, 101, 14, 7, 247, 189, 14, 7, 247, 188, 14, 7, 247, 187, 14, 7, 247, + 186, 14, 7, 247, 185, 14, 7, 247, 184, 14, 7, 247, 183, 14, 7, 247, 182, + 14, 7, 247, 181, 14, 7, 247, 180, 14, 7, 247, 179, 14, 7, 247, 178, 14, + 7, 247, 177, 14, 7, 247, 176, 14, 7, 247, 175, 14, 7, 247, 174, 14, 7, + 247, 173, 14, 7, 247, 172, 14, 7, 247, 171, 14, 7, 247, 170, 14, 7, 247, + 169, 14, 7, 247, 168, 14, 7, 247, 167, 14, 7, 247, 166, 14, 7, 247, 165, + 14, 7, 247, 164, 14, 7, 247, 163, 14, 7, 247, 162, 14, 7, 238, 126, 14, + 7, 238, 125, 14, 7, 238, 124, 14, 7, 238, 123, 14, 7, 238, 122, 14, 7, + 238, 121, 14, 7, 238, 120, 14, 7, 238, 119, 14, 7, 238, 118, 14, 7, 238, + 117, 14, 7, 238, 116, 14, 7, 238, 115, 14, 7, 238, 114, 14, 7, 238, 113, + 14, 7, 238, 112, 14, 7, 238, 111, 14, 7, 238, 110, 14, 7, 238, 109, 14, + 7, 238, 108, 14, 7, 238, 107, 14, 7, 238, 106, 14, 7, 238, 105, 14, 7, + 238, 104, 14, 7, 238, 103, 14, 7, 238, 102, 14, 7, 238, 101, 14, 7, 238, + 100, 14, 7, 238, 99, 14, 7, 238, 98, 14, 7, 238, 97, 14, 7, 238, 96, 14, + 7, 238, 95, 14, 7, 238, 94, 14, 7, 238, 93, 14, 7, 238, 92, 14, 7, 238, + 91, 14, 7, 238, 90, 14, 7, 238, 89, 14, 7, 238, 88, 14, 7, 238, 87, 14, + 7, 238, 86, 14, 7, 238, 85, 14, 7, 238, 84, 14, 7, 238, 83, 14, 7, 238, + 82, 14, 7, 238, 81, 14, 7, 238, 80, 14, 7, 238, 79, 14, 7, 238, 78, 14, + 7, 238, 77, 14, 7, 238, 76, 14, 7, 238, 75, 14, 7, 238, 74, 14, 7, 238, + 73, 14, 7, 238, 72, 14, 7, 238, 71, 14, 7, 238, 70, 14, 7, 238, 69, 14, + 7, 238, 68, 14, 7, 238, 67, 14, 7, 238, 66, 14, 7, 238, 65, 14, 7, 238, + 64, 14, 7, 238, 63, 14, 7, 238, 62, 14, 7, 238, 61, 14, 7, 238, 60, 14, + 7, 238, 59, 14, 7, 238, 58, 14, 7, 238, 57, 14, 7, 238, 56, 14, 7, 238, + 55, 14, 7, 238, 54, 14, 7, 238, 53, 14, 7, 238, 52, 14, 7, 238, 51, 14, + 7, 238, 50, 14, 7, 238, 49, 14, 7, 238, 48, 14, 7, 238, 47, 14, 7, 238, + 46, 14, 7, 238, 45, 14, 7, 238, 44, 14, 7, 238, 43, 14, 7, 238, 42, 14, + 7, 238, 41, 14, 7, 238, 40, 14, 7, 238, 39, 14, 7, 238, 38, 14, 7, 238, + 37, 14, 7, 238, 36, 14, 7, 238, 35, 14, 7, 235, 7, 14, 7, 235, 6, 14, 7, + 235, 5, 14, 7, 235, 4, 14, 7, 235, 3, 14, 7, 235, 2, 14, 7, 235, 1, 14, + 7, 235, 0, 14, 7, 234, 255, 14, 7, 234, 254, 14, 7, 234, 253, 14, 7, 234, + 252, 14, 7, 234, 251, 14, 7, 234, 250, 14, 7, 234, 249, 14, 7, 234, 248, + 14, 7, 234, 247, 14, 7, 234, 246, 14, 7, 234, 245, 14, 7, 234, 244, 14, + 7, 234, 243, 14, 7, 234, 242, 14, 7, 234, 241, 14, 7, 234, 240, 14, 7, + 234, 239, 14, 7, 234, 238, 14, 7, 234, 237, 14, 7, 234, 236, 14, 7, 234, + 235, 14, 7, 234, 234, 14, 7, 234, 233, 14, 7, 234, 232, 14, 7, 234, 231, + 14, 7, 234, 230, 14, 7, 234, 229, 14, 7, 234, 228, 14, 7, 234, 227, 14, + 7, 234, 226, 14, 7, 234, 225, 14, 7, 234, 224, 14, 7, 234, 223, 14, 7, + 234, 222, 14, 7, 234, 221, 14, 7, 234, 220, 14, 7, 233, 174, 14, 7, 233, + 173, 14, 7, 233, 172, 14, 7, 233, 171, 14, 7, 233, 170, 14, 7, 233, 169, + 14, 7, 233, 168, 14, 7, 233, 167, 14, 7, 233, 166, 14, 7, 233, 165, 14, + 7, 233, 164, 14, 7, 233, 163, 14, 7, 233, 162, 14, 7, 233, 161, 14, 7, + 233, 160, 14, 7, 233, 159, 14, 7, 233, 158, 14, 7, 233, 157, 14, 7, 233, + 156, 14, 7, 233, 155, 14, 7, 233, 154, 14, 7, 233, 153, 14, 7, 233, 152, + 14, 7, 233, 151, 14, 7, 233, 150, 14, 7, 233, 149, 14, 7, 233, 148, 14, + 7, 233, 147, 14, 7, 233, 146, 14, 7, 233, 145, 14, 7, 233, 144, 14, 7, + 233, 143, 14, 7, 233, 142, 14, 7, 233, 141, 14, 7, 233, 140, 14, 7, 233, + 139, 14, 7, 233, 138, 14, 7, 233, 137, 14, 7, 233, 136, 14, 7, 233, 135, + 14, 7, 233, 134, 14, 7, 233, 133, 14, 7, 233, 132, 14, 7, 233, 131, 14, + 7, 233, 130, 14, 7, 233, 129, 14, 7, 233, 128, 14, 7, 233, 127, 14, 7, + 233, 126, 14, 7, 233, 125, 14, 7, 233, 124, 14, 7, 233, 123, 14, 7, 233, + 122, 14, 7, 233, 121, 14, 7, 233, 120, 14, 7, 233, 119, 14, 7, 233, 118, + 14, 7, 233, 117, 14, 7, 233, 116, 14, 7, 233, 115, 14, 7, 233, 114, 14, + 7, 233, 113, 14, 7, 233, 112, 14, 7, 233, 111, 14, 7, 233, 110, 14, 7, + 232, 50, 14, 7, 232, 49, 14, 7, 232, 48, 14, 7, 232, 47, 14, 7, 232, 46, + 14, 7, 232, 45, 14, 7, 232, 44, 14, 7, 232, 43, 14, 7, 232, 42, 14, 7, + 232, 41, 14, 7, 232, 40, 14, 7, 232, 39, 14, 7, 232, 38, 14, 7, 232, 37, + 14, 7, 232, 36, 14, 7, 232, 35, 14, 7, 232, 34, 14, 7, 232, 33, 14, 7, + 232, 32, 14, 7, 232, 31, 14, 7, 232, 30, 14, 7, 232, 29, 14, 7, 232, 28, + 14, 7, 232, 27, 14, 7, 232, 26, 14, 7, 232, 25, 14, 7, 232, 24, 14, 7, + 232, 23, 14, 7, 232, 22, 14, 7, 232, 21, 14, 7, 232, 20, 14, 7, 232, 19, + 14, 7, 232, 18, 14, 7, 232, 17, 14, 7, 232, 16, 14, 7, 232, 15, 14, 7, + 232, 14, 14, 7, 232, 13, 14, 7, 232, 12, 14, 7, 232, 11, 14, 7, 232, 10, + 14, 7, 232, 9, 14, 7, 232, 8, 14, 7, 232, 7, 14, 7, 232, 6, 14, 7, 232, + 5, 14, 7, 232, 4, 14, 7, 232, 3, 14, 7, 232, 2, 14, 7, 232, 1, 14, 7, + 232, 0, 14, 7, 231, 255, 14, 7, 231, 254, 14, 7, 231, 253, 14, 7, 231, + 252, 14, 7, 231, 251, 14, 7, 231, 250, 14, 7, 231, 249, 14, 7, 231, 248, + 14, 7, 231, 247, 14, 7, 231, 246, 14, 7, 231, 245, 14, 7, 231, 244, 14, + 7, 231, 243, 14, 7, 230, 114, 14, 7, 230, 113, 14, 7, 230, 112, 14, 7, + 230, 111, 14, 7, 230, 110, 14, 7, 230, 109, 14, 7, 230, 108, 14, 7, 230, + 107, 14, 7, 230, 106, 14, 7, 228, 54, 14, 7, 228, 53, 14, 7, 228, 52, 14, + 7, 228, 51, 14, 7, 228, 50, 14, 7, 228, 49, 14, 7, 228, 48, 14, 7, 228, + 47, 14, 7, 228, 46, 14, 7, 228, 45, 14, 7, 228, 44, 14, 7, 228, 43, 14, + 7, 228, 42, 14, 7, 228, 41, 14, 7, 228, 40, 14, 7, 228, 39, 14, 7, 228, + 38, 14, 7, 228, 37, 14, 7, 228, 36, 14, 7, 222, 151, 14, 7, 222, 150, 14, + 7, 222, 149, 14, 7, 222, 148, 14, 7, 222, 147, 14, 7, 222, 146, 14, 7, + 222, 145, 14, 7, 222, 144, 14, 7, 220, 140, 14, 7, 220, 139, 14, 7, 220, + 138, 14, 7, 220, 137, 14, 7, 220, 136, 14, 7, 220, 135, 14, 7, 220, 134, + 14, 7, 220, 133, 14, 7, 220, 132, 14, 7, 220, 131, 14, 7, 218, 166, 14, + 7, 218, 165, 14, 7, 218, 164, 14, 7, 218, 162, 14, 7, 218, 160, 14, 7, + 218, 159, 14, 7, 218, 157, 14, 7, 218, 155, 14, 7, 218, 153, 14, 7, 218, + 151, 14, 7, 218, 149, 14, 7, 218, 147, 14, 7, 218, 145, 14, 7, 218, 144, + 14, 7, 218, 142, 14, 7, 218, 140, 14, 7, 218, 139, 14, 7, 218, 138, 14, + 7, 218, 137, 14, 7, 218, 136, 14, 7, 218, 135, 14, 7, 218, 134, 14, 7, + 218, 133, 14, 7, 218, 132, 14, 7, 218, 130, 14, 7, 218, 128, 14, 7, 218, + 126, 14, 7, 218, 125, 14, 7, 218, 123, 14, 7, 218, 122, 14, 7, 218, 120, + 14, 7, 218, 119, 14, 7, 218, 117, 14, 7, 218, 115, 14, 7, 218, 113, 14, + 7, 218, 111, 14, 7, 218, 109, 14, 7, 218, 108, 14, 7, 218, 106, 14, 7, + 218, 104, 14, 7, 218, 103, 14, 7, 218, 101, 14, 7, 218, 99, 14, 7, 218, + 97, 14, 7, 218, 95, 14, 7, 218, 94, 14, 7, 218, 92, 14, 7, 218, 90, 14, + 7, 218, 88, 14, 7, 218, 87, 14, 7, 218, 85, 14, 7, 218, 83, 14, 7, 218, + 82, 14, 7, 218, 81, 14, 7, 218, 79, 14, 7, 218, 77, 14, 7, 218, 75, 14, + 7, 218, 73, 14, 7, 218, 71, 14, 7, 218, 69, 14, 7, 218, 67, 14, 7, 218, + 66, 14, 7, 218, 64, 14, 7, 218, 62, 14, 7, 218, 60, 14, 7, 218, 58, 14, + 7, 215, 56, 14, 7, 215, 55, 14, 7, 215, 54, 14, 7, 215, 53, 14, 7, 215, + 52, 14, 7, 215, 51, 14, 7, 215, 50, 14, 7, 215, 49, 14, 7, 215, 48, 14, + 7, 215, 47, 14, 7, 215, 46, 14, 7, 215, 45, 14, 7, 215, 44, 14, 7, 215, + 43, 14, 7, 215, 42, 14, 7, 215, 41, 14, 7, 215, 40, 14, 7, 215, 39, 14, + 7, 215, 38, 14, 7, 215, 37, 14, 7, 215, 36, 14, 7, 215, 35, 14, 7, 215, + 34, 14, 7, 215, 33, 14, 7, 215, 32, 14, 7, 215, 31, 14, 7, 215, 30, 14, + 7, 215, 29, 14, 7, 215, 28, 14, 7, 215, 27, 14, 7, 215, 26, 14, 7, 215, + 25, 14, 7, 215, 24, 14, 7, 215, 23, 14, 7, 215, 22, 14, 7, 215, 21, 14, + 7, 215, 20, 14, 7, 215, 19, 14, 7, 215, 18, 14, 7, 215, 17, 14, 7, 215, + 16, 14, 7, 215, 15, 14, 7, 215, 14, 14, 7, 215, 13, 14, 7, 215, 12, 14, + 7, 215, 11, 14, 7, 215, 10, 14, 7, 215, 9, 14, 7, 215, 8, 14, 7, 213, + 104, 14, 7, 213, 103, 14, 7, 213, 102, 14, 7, 213, 101, 14, 7, 213, 100, + 14, 7, 213, 99, 14, 7, 213, 98, 14, 7, 213, 97, 14, 7, 213, 96, 14, 7, + 213, 95, 14, 7, 213, 94, 14, 7, 213, 93, 14, 7, 213, 92, 14, 7, 213, 91, + 14, 7, 213, 90, 14, 7, 213, 89, 14, 7, 213, 88, 14, 7, 213, 87, 14, 7, + 213, 86, 14, 7, 213, 85, 14, 7, 213, 84, 14, 7, 213, 83, 14, 7, 212, 174, + 14, 7, 212, 173, 14, 7, 212, 172, 14, 7, 212, 171, 14, 7, 212, 170, 14, + 7, 212, 169, 14, 7, 212, 168, 14, 7, 212, 167, 14, 7, 212, 166, 14, 7, + 212, 165, 14, 7, 212, 164, 14, 7, 212, 163, 14, 7, 212, 162, 14, 7, 212, + 161, 14, 7, 212, 160, 14, 7, 212, 159, 14, 7, 212, 158, 14, 7, 212, 157, + 14, 7, 212, 156, 14, 7, 212, 155, 14, 7, 212, 154, 14, 7, 212, 153, 14, + 7, 212, 152, 14, 7, 212, 151, 14, 7, 212, 150, 14, 7, 212, 149, 14, 7, + 212, 2, 14, 7, 212, 1, 14, 7, 212, 0, 14, 7, 211, 255, 14, 7, 211, 254, + 14, 7, 211, 253, 14, 7, 211, 252, 14, 7, 211, 251, 14, 7, 211, 250, 14, + 7, 211, 249, 14, 7, 211, 248, 14, 7, 211, 247, 14, 7, 211, 246, 14, 7, + 211, 245, 14, 7, 211, 244, 14, 7, 211, 243, 14, 7, 211, 242, 14, 7, 211, + 241, 14, 7, 211, 240, 14, 7, 211, 239, 14, 7, 211, 238, 14, 7, 211, 237, + 14, 7, 211, 236, 14, 7, 211, 235, 14, 7, 211, 234, 14, 7, 211, 233, 14, + 7, 211, 232, 14, 7, 211, 231, 14, 7, 211, 230, 14, 7, 211, 229, 14, 7, + 211, 228, 14, 7, 211, 227, 14, 7, 211, 226, 14, 7, 211, 225, 14, 7, 211, + 224, 14, 7, 211, 223, 14, 7, 211, 222, 14, 7, 211, 221, 14, 7, 211, 220, + 14, 7, 211, 219, 14, 7, 211, 218, 14, 7, 211, 217, 14, 7, 211, 216, 14, + 7, 211, 215, 14, 7, 211, 214, 14, 7, 211, 213, 14, 7, 211, 212, 14, 7, + 211, 211, 14, 7, 211, 210, 14, 7, 211, 209, 14, 7, 211, 208, 14, 7, 211, + 207, 14, 7, 211, 206, 14, 7, 211, 205, 14, 7, 211, 204, 14, 7, 211, 203, + 14, 7, 211, 202, 14, 7, 211, 201, 14, 7, 211, 200, 14, 7, 211, 199, 14, + 7, 211, 198, 14, 7, 211, 197, 14, 7, 211, 196, 14, 7, 211, 195, 14, 7, + 211, 194, 14, 7, 211, 193, 14, 7, 211, 192, 14, 7, 211, 191, 14, 7, 211, + 190, 14, 7, 211, 189, 14, 7, 211, 188, 14, 7, 211, 187, 14, 7, 211, 186, + 14, 7, 211, 185, 14, 7, 211, 184, 14, 7, 210, 235, 14, 7, 210, 234, 14, + 7, 210, 233, 14, 7, 210, 232, 14, 7, 210, 231, 14, 7, 210, 230, 14, 7, + 210, 229, 14, 7, 210, 228, 14, 7, 210, 227, 14, 7, 210, 226, 14, 7, 210, + 225, 14, 7, 210, 224, 14, 7, 210, 223, 14, 7, 208, 103, 14, 7, 208, 102, + 14, 7, 208, 101, 14, 7, 208, 100, 14, 7, 208, 99, 14, 7, 208, 98, 14, 7, + 208, 97, 14, 7, 207, 220, 14, 7, 207, 219, 14, 7, 207, 218, 14, 7, 207, + 217, 14, 7, 207, 216, 14, 7, 207, 215, 14, 7, 207, 214, 14, 7, 207, 213, + 14, 7, 207, 212, 14, 7, 207, 211, 14, 7, 207, 210, 14, 7, 207, 209, 14, + 7, 207, 208, 14, 7, 207, 207, 14, 7, 207, 206, 14, 7, 207, 205, 14, 7, + 207, 204, 14, 7, 207, 203, 14, 7, 207, 202, 14, 7, 207, 201, 14, 7, 207, + 200, 14, 7, 207, 199, 14, 7, 207, 198, 14, 7, 207, 197, 14, 7, 207, 196, + 14, 7, 207, 195, 14, 7, 207, 194, 14, 7, 207, 193, 14, 7, 207, 192, 14, + 7, 207, 191, 14, 7, 207, 190, 14, 7, 207, 189, 14, 7, 207, 188, 14, 7, + 207, 187, 14, 7, 206, 5, 14, 7, 206, 4, 14, 7, 206, 3, 14, 7, 206, 2, 14, + 7, 206, 1, 14, 7, 206, 0, 14, 7, 205, 255, 14, 7, 205, 254, 14, 7, 205, + 253, 14, 7, 205, 252, 14, 7, 205, 251, 14, 7, 205, 250, 14, 7, 205, 249, + 14, 7, 205, 248, 14, 7, 205, 247, 14, 7, 205, 246, 14, 7, 205, 245, 14, + 7, 205, 244, 14, 7, 205, 243, 14, 7, 205, 242, 14, 7, 205, 241, 14, 7, + 205, 240, 14, 7, 205, 239, 14, 7, 205, 238, 14, 7, 205, 237, 14, 7, 205, + 236, 14, 7, 205, 235, 14, 7, 205, 234, 14, 7, 205, 233, 14, 7, 205, 232, + 14, 7, 205, 231, 14, 7, 205, 230, 14, 7, 205, 229, 14, 7, 205, 228, 14, + 7, 205, 227, 14, 7, 205, 226, 14, 7, 205, 225, 14, 7, 205, 224, 14, 7, + 205, 223, 14, 7, 205, 222, 14, 7, 205, 221, 14, 7, 205, 220, 14, 7, 205, + 219, 14, 7, 205, 218, 14, 7, 205, 217, 14, 7, 205, 216, 14, 7, 205, 215, + 14, 7, 205, 214, 14, 7, 205, 213, 14, 7, 205, 212, 14, 7, 205, 211, 14, + 7, 205, 210, 14, 7, 205, 209, 14, 7, 205, 208, 14, 7, 200, 40, 14, 7, + 200, 39, 14, 7, 200, 38, 14, 7, 200, 37, 14, 7, 200, 36, 14, 7, 200, 35, + 14, 7, 200, 34, 14, 7, 200, 33, 14, 7, 200, 32, 14, 7, 200, 31, 14, 7, + 200, 30, 14, 7, 200, 29, 14, 7, 200, 28, 14, 7, 200, 27, 14, 7, 200, 26, + 14, 7, 200, 25, 14, 7, 200, 24, 14, 7, 200, 23, 14, 7, 200, 22, 14, 7, + 200, 21, 14, 7, 200, 20, 14, 7, 200, 19, 14, 7, 200, 18, 14, 7, 200, 17, + 14, 7, 200, 16, 14, 7, 200, 15, 14, 7, 200, 14, 14, 7, 200, 13, 14, 7, + 200, 12, 14, 7, 200, 11, 14, 7, 200, 10, 14, 7, 200, 9, 14, 7, 200, 8, 14, 7, 200, 7, 14, 7, 200, 6, 14, 7, 200, 5, 14, 7, 200, 4, 14, 7, 200, 3, 14, 7, 200, 2, 14, 7, 200, 1, 14, 7, 200, 0, 14, 7, 199, 255, 14, 7, - 199, 254, 14, 7, 199, 253, 14, 7, 199, 252, 14, 7, 199, 251, 14, 7, 199, - 250, 14, 7, 199, 249, 14, 7, 196, 213, 14, 7, 196, 212, 14, 7, 196, 211, + 199, 254, 14, 7, 199, 253, 14, 7, 196, 217, 14, 7, 196, 216, 14, 7, 196, + 215, 14, 7, 196, 214, 14, 7, 196, 213, 14, 7, 196, 212, 14, 7, 196, 211, 14, 7, 196, 210, 14, 7, 196, 209, 14, 7, 196, 208, 14, 7, 196, 207, 14, 7, 196, 206, 14, 7, 196, 205, 14, 7, 196, 204, 14, 7, 196, 203, 14, 7, 196, 202, 14, 7, 196, 201, 14, 7, 196, 200, 14, 7, 196, 199, 14, 7, 196, @@ -16815,74 +16874,101 @@ static const unsigned char phrasebook[] = { 196, 185, 14, 7, 196, 184, 14, 7, 196, 183, 14, 7, 196, 182, 14, 7, 196, 181, 14, 7, 196, 180, 14, 7, 196, 179, 14, 7, 196, 178, 14, 7, 196, 177, 14, 7, 196, 176, 14, 7, 196, 175, 14, 7, 196, 174, 14, 7, 196, 173, 14, - 7, 196, 172, 14, 7, 196, 171, 14, 7, 196, 170, 14, 7, 196, 169, 14, 7, - 196, 168, 14, 7, 196, 167, 14, 7, 196, 7, 14, 7, 196, 6, 14, 7, 196, 5, - 14, 7, 196, 4, 14, 7, 196, 3, 14, 7, 196, 2, 14, 7, 196, 1, 14, 7, 196, - 0, 14, 7, 195, 255, 14, 7, 195, 254, 14, 7, 195, 253, 14, 7, 195, 252, - 14, 7, 195, 251, 14, 7, 195, 250, 14, 7, 195, 249, 14, 7, 195, 248, 14, - 7, 195, 247, 14, 7, 195, 246, 14, 7, 195, 245, 14, 7, 195, 244, 14, 7, - 195, 243, 14, 7, 195, 242, 14, 7, 195, 241, 14, 7, 195, 240, 14, 7, 195, - 239, 14, 7, 195, 238, 14, 7, 195, 237, 14, 7, 195, 236, 14, 7, 195, 235, - 14, 7, 195, 234, 14, 7, 195, 233, 14, 7, 195, 232, 14, 7, 195, 231, 14, - 7, 195, 230, 14, 7, 195, 229, 14, 7, 195, 228, 14, 7, 195, 227, 14, 7, - 195, 226, 14, 7, 195, 225, 14, 7, 195, 224, 14, 7, 195, 223, 14, 7, 195, - 222, 14, 7, 195, 221, 14, 7, 195, 220, 14, 7, 195, 219, 14, 7, 195, 218, - 14, 7, 195, 217, 14, 7, 195, 216, 14, 7, 195, 215, 14, 7, 195, 214, 14, - 7, 195, 213, 14, 7, 195, 212, 14, 7, 195, 211, 14, 7, 195, 210, 14, 7, - 195, 209, 14, 7, 195, 208, 14, 7, 195, 207, 14, 7, 195, 206, 14, 7, 195, - 205, 14, 7, 195, 204, 14, 7, 195, 203, 14, 7, 195, 202, 14, 7, 195, 201, - 14, 7, 195, 200, 14, 7, 195, 199, 14, 7, 195, 198, 14, 7, 195, 197, 14, - 7, 195, 196, 14, 7, 195, 195, 14, 7, 195, 194, 14, 7, 195, 193, 14, 7, - 195, 192, 14, 7, 195, 191, 14, 7, 195, 190, 14, 7, 195, 189, 14, 7, 195, - 188, 14, 7, 195, 187, 14, 7, 193, 220, 14, 7, 193, 219, 14, 7, 193, 218, - 14, 7, 193, 217, 14, 7, 193, 216, 14, 7, 193, 215, 14, 7, 193, 214, 14, - 7, 193, 213, 14, 7, 193, 212, 14, 7, 193, 211, 14, 7, 193, 210, 14, 7, - 193, 209, 14, 7, 193, 208, 14, 7, 193, 207, 14, 7, 193, 206, 14, 7, 193, - 205, 14, 7, 193, 204, 14, 7, 193, 203, 14, 7, 193, 202, 14, 7, 193, 201, - 14, 7, 193, 200, 14, 7, 193, 199, 14, 7, 193, 198, 14, 7, 193, 197, 14, - 7, 193, 196, 14, 7, 193, 195, 14, 7, 193, 194, 14, 7, 193, 193, 14, 7, - 193, 192, 14, 7, 193, 191, 14, 7, 193, 190, 14, 7, 193, 189, 14, 7, 192, - 232, 14, 7, 192, 231, 14, 7, 192, 230, 14, 7, 192, 229, 14, 7, 192, 228, - 14, 7, 192, 227, 14, 7, 192, 226, 14, 7, 192, 225, 14, 7, 192, 224, 14, - 7, 192, 223, 14, 7, 192, 222, 14, 7, 192, 221, 14, 7, 192, 157, 14, 7, - 192, 156, 14, 7, 192, 155, 14, 7, 192, 154, 14, 7, 192, 153, 14, 7, 192, - 152, 14, 7, 192, 151, 14, 7, 192, 150, 14, 7, 192, 149, 14, 7, 191, 165, - 14, 7, 191, 164, 14, 7, 191, 163, 14, 7, 191, 162, 14, 7, 191, 161, 14, - 7, 191, 160, 14, 7, 191, 159, 14, 7, 191, 158, 14, 7, 191, 157, 14, 7, - 191, 156, 14, 7, 191, 155, 14, 7, 191, 154, 14, 7, 191, 153, 14, 7, 191, - 152, 14, 7, 191, 151, 14, 7, 191, 150, 14, 7, 191, 149, 14, 7, 191, 148, - 14, 7, 191, 147, 14, 7, 191, 146, 14, 7, 191, 145, 14, 7, 191, 144, 14, - 7, 191, 143, 14, 7, 191, 142, 14, 7, 191, 141, 14, 7, 191, 140, 14, 7, - 191, 139, 14, 7, 191, 138, 14, 7, 191, 137, 14, 7, 191, 136, 14, 7, 191, - 135, 14, 7, 191, 134, 14, 7, 191, 133, 14, 7, 191, 132, 14, 7, 191, 131, - 14, 7, 191, 130, 14, 7, 191, 129, 14, 7, 191, 128, 14, 7, 191, 127, 14, - 7, 191, 126, 14, 7, 191, 125, 14, 7, 252, 153, 14, 7, 252, 152, 14, 7, - 252, 151, 14, 7, 252, 150, 14, 7, 252, 149, 14, 7, 252, 148, 14, 7, 252, - 147, 14, 7, 252, 146, 14, 7, 252, 145, 14, 7, 252, 144, 14, 7, 252, 143, - 14, 7, 252, 142, 14, 7, 252, 141, 14, 7, 252, 140, 14, 7, 252, 139, 14, - 7, 252, 138, 14, 7, 252, 137, 14, 7, 252, 136, 14, 7, 252, 135, 14, 7, - 252, 134, 14, 7, 252, 133, 14, 7, 252, 132, 14, 7, 252, 131, 14, 7, 252, - 130, 14, 7, 252, 129, 14, 7, 252, 128, 14, 7, 252, 127, 14, 7, 252, 126, - 14, 7, 252, 125, 14, 7, 252, 124, 14, 7, 252, 123, 14, 7, 252, 122, 14, - 7, 252, 121, 14, 7, 252, 120, 14, 7, 81, 222, 169, 14, 7, 228, 209, 222, - 169, 14, 7, 223, 92, 250, 133, 198, 49, 201, 92, 14, 7, 223, 92, 250, - 133, 248, 29, 201, 92, 14, 7, 223, 92, 250, 133, 198, 49, 234, 52, 14, 7, - 223, 92, 250, 133, 248, 29, 234, 52, 14, 7, 210, 246, 216, 66, 14, 7, - 248, 199, 205, 38, 14, 7, 234, 53, 205, 38, 29, 7, 255, 147, 29, 7, 255, - 146, 29, 7, 255, 145, 29, 7, 255, 144, 29, 7, 255, 143, 29, 7, 255, 141, - 29, 7, 255, 138, 29, 7, 255, 137, 29, 7, 255, 136, 29, 7, 255, 135, 29, - 7, 255, 134, 29, 7, 255, 133, 29, 7, 255, 132, 29, 7, 255, 131, 29, 7, - 255, 130, 29, 7, 255, 128, 29, 7, 255, 127, 29, 7, 255, 126, 29, 7, 255, - 124, 29, 7, 255, 123, 29, 7, 255, 122, 29, 7, 255, 121, 29, 7, 255, 120, - 29, 7, 255, 119, 29, 7, 255, 118, 29, 7, 255, 117, 29, 7, 255, 116, 29, - 7, 255, 115, 29, 7, 255, 114, 29, 7, 255, 113, 29, 7, 255, 111, 29, 7, - 255, 110, 29, 7, 255, 109, 29, 7, 255, 108, 29, 7, 255, 106, 29, 7, 255, - 105, 29, 7, 255, 104, 29, 7, 255, 103, 29, 7, 255, 102, 29, 7, 255, 101, - 29, 7, 255, 100, 29, 7, 255, 99, 29, 7, 255, 98, 29, 7, 255, 96, 29, 7, - 255, 95, 29, 7, 255, 94, 29, 7, 255, 92, 29, 7, 255, 90, 29, 7, 255, 89, - 29, 7, 255, 88, 29, 7, 255, 87, 29, 7, 255, 86, 29, 7, 255, 85, 29, 7, - 255, 84, 29, 7, 255, 83, 29, 7, 255, 82, 29, 7, 255, 81, 29, 7, 255, 80, - 29, 7, 255, 79, 29, 7, 255, 78, 29, 7, 255, 77, 29, 7, 255, 76, 29, 7, + 7, 196, 172, 14, 7, 196, 171, 14, 7, 196, 11, 14, 7, 196, 10, 14, 7, 196, + 9, 14, 7, 196, 8, 14, 7, 196, 7, 14, 7, 196, 6, 14, 7, 196, 5, 14, 7, + 196, 4, 14, 7, 196, 3, 14, 7, 196, 2, 14, 7, 196, 1, 14, 7, 196, 0, 14, + 7, 195, 255, 14, 7, 195, 254, 14, 7, 195, 253, 14, 7, 195, 252, 14, 7, + 195, 251, 14, 7, 195, 250, 14, 7, 195, 249, 14, 7, 195, 248, 14, 7, 195, + 247, 14, 7, 195, 246, 14, 7, 195, 245, 14, 7, 195, 244, 14, 7, 195, 243, + 14, 7, 195, 242, 14, 7, 195, 240, 14, 7, 195, 239, 14, 7, 195, 238, 14, + 7, 195, 237, 14, 7, 195, 236, 14, 7, 195, 235, 14, 7, 195, 234, 14, 7, + 195, 233, 14, 7, 195, 232, 14, 7, 195, 231, 14, 7, 195, 230, 14, 7, 195, + 229, 14, 7, 195, 228, 14, 7, 195, 227, 14, 7, 195, 226, 14, 7, 195, 225, + 14, 7, 195, 224, 14, 7, 195, 223, 14, 7, 195, 222, 14, 7, 195, 221, 14, + 7, 195, 220, 14, 7, 195, 219, 14, 7, 195, 218, 14, 7, 195, 217, 14, 7, + 195, 216, 14, 7, 195, 215, 14, 7, 195, 214, 14, 7, 195, 213, 14, 7, 195, + 212, 14, 7, 195, 211, 14, 7, 195, 210, 14, 7, 195, 209, 14, 7, 195, 208, + 14, 7, 195, 207, 14, 7, 195, 206, 14, 7, 195, 205, 14, 7, 195, 204, 14, + 7, 195, 203, 14, 7, 195, 202, 14, 7, 195, 201, 14, 7, 195, 200, 14, 7, + 195, 199, 14, 7, 195, 198, 14, 7, 195, 197, 14, 7, 195, 196, 14, 7, 195, + 195, 14, 7, 195, 194, 14, 7, 195, 193, 14, 7, 195, 192, 14, 7, 195, 191, + 14, 7, 195, 190, 14, 7, 193, 223, 14, 7, 193, 222, 14, 7, 193, 221, 14, + 7, 193, 220, 14, 7, 193, 219, 14, 7, 193, 218, 14, 7, 193, 217, 14, 7, + 193, 216, 14, 7, 193, 215, 14, 7, 193, 214, 14, 7, 193, 213, 14, 7, 193, + 212, 14, 7, 193, 211, 14, 7, 193, 210, 14, 7, 193, 209, 14, 7, 193, 208, + 14, 7, 193, 207, 14, 7, 193, 206, 14, 7, 193, 205, 14, 7, 193, 204, 14, + 7, 193, 203, 14, 7, 193, 202, 14, 7, 193, 201, 14, 7, 193, 200, 14, 7, + 193, 199, 14, 7, 193, 198, 14, 7, 193, 197, 14, 7, 193, 196, 14, 7, 193, + 195, 14, 7, 193, 194, 14, 7, 193, 193, 14, 7, 193, 192, 14, 7, 192, 232, + 14, 7, 192, 231, 14, 7, 192, 230, 14, 7, 192, 229, 14, 7, 192, 228, 14, + 7, 192, 227, 14, 7, 192, 226, 14, 7, 192, 225, 14, 7, 192, 224, 14, 7, + 192, 223, 14, 7, 192, 222, 14, 7, 192, 221, 14, 7, 192, 157, 14, 7, 192, + 156, 14, 7, 192, 155, 14, 7, 192, 154, 14, 7, 192, 153, 14, 7, 192, 152, + 14, 7, 192, 151, 14, 7, 192, 150, 14, 7, 192, 149, 14, 7, 191, 165, 14, + 7, 191, 164, 14, 7, 191, 163, 14, 7, 191, 162, 14, 7, 191, 161, 14, 7, + 191, 160, 14, 7, 191, 159, 14, 7, 191, 158, 14, 7, 191, 157, 14, 7, 191, + 156, 14, 7, 191, 155, 14, 7, 191, 154, 14, 7, 191, 153, 14, 7, 191, 152, + 14, 7, 191, 151, 14, 7, 191, 150, 14, 7, 191, 149, 14, 7, 191, 148, 14, + 7, 191, 147, 14, 7, 191, 146, 14, 7, 191, 145, 14, 7, 191, 144, 14, 7, + 191, 143, 14, 7, 191, 142, 14, 7, 191, 141, 14, 7, 191, 140, 14, 7, 191, + 139, 14, 7, 191, 138, 14, 7, 191, 137, 14, 7, 191, 136, 14, 7, 191, 135, + 14, 7, 191, 134, 14, 7, 191, 133, 14, 7, 191, 132, 14, 7, 191, 131, 14, + 7, 191, 130, 14, 7, 191, 129, 14, 7, 191, 128, 14, 7, 191, 127, 14, 7, + 191, 126, 14, 7, 191, 125, 14, 7, 252, 205, 14, 7, 252, 204, 14, 7, 252, + 203, 14, 7, 252, 202, 14, 7, 252, 201, 14, 7, 252, 200, 14, 7, 252, 199, + 14, 7, 252, 198, 14, 7, 252, 197, 14, 7, 252, 196, 14, 7, 252, 195, 14, + 7, 252, 194, 14, 7, 252, 193, 14, 7, 252, 192, 14, 7, 252, 191, 14, 7, + 252, 190, 14, 7, 252, 189, 14, 7, 252, 188, 14, 7, 252, 187, 14, 7, 252, + 186, 14, 7, 252, 185, 14, 7, 252, 184, 14, 7, 252, 183, 14, 7, 252, 182, + 14, 7, 252, 181, 14, 7, 252, 180, 14, 7, 252, 179, 14, 7, 252, 178, 14, + 7, 252, 177, 14, 7, 252, 176, 14, 7, 252, 175, 14, 7, 252, 174, 14, 7, + 252, 173, 14, 7, 252, 172, 14, 7, 195, 241, 14, 7, 81, 222, 196, 14, 7, + 228, 241, 222, 196, 14, 7, 223, 120, 250, 183, 198, 54, 201, 97, 14, 7, + 223, 120, 250, 183, 248, 77, 201, 97, 14, 7, 223, 120, 250, 183, 198, 54, + 234, 94, 14, 7, 223, 120, 250, 183, 248, 77, 234, 94, 14, 7, 211, 0, 216, + 84, 14, 7, 248, 249, 205, 43, 14, 7, 234, 95, 205, 43, 14, 7, 223, 120, + 250, 183, 216, 84, 14, 7, 223, 120, 250, 183, 198, 53, 14, 7, 223, 120, + 250, 183, 248, 76, 14, 7, 248, 249, 234, 98, 14, 7, 234, 95, 234, 98, 14, + 7, 248, 249, 193, 166, 234, 98, 14, 7, 234, 95, 193, 166, 234, 98, 14, 7, + 216, 27, 228, 189, 14, 7, 232, 80, 248, 132, 14, 7, 132, 248, 132, 14, 7, + 218, 251, 56, 14, 7, 132, 218, 251, 56, 14, 7, 199, 200, 218, 251, 56, + 14, 7, 193, 78, 218, 251, 56, 14, 7, 52, 237, 249, 250, 183, 198, 54, + 201, 97, 14, 7, 52, 237, 249, 250, 183, 248, 77, 201, 97, 14, 7, 52, 237, + 249, 250, 183, 201, 97, 14, 7, 52, 237, 249, 250, 183, 198, 54, 234, 94, + 14, 7, 52, 237, 249, 250, 183, 198, 53, 14, 7, 52, 237, 249, 250, 183, + 248, 77, 201, 98, 23, 198, 54, 234, 94, 14, 7, 52, 237, 249, 250, 183, + 201, 98, 23, 198, 53, 14, 7, 52, 237, 249, 250, 183, 248, 77, 234, 94, + 14, 7, 52, 237, 249, 250, 183, 198, 54, 201, 98, 23, 248, 77, 234, 94, + 14, 7, 52, 237, 249, 250, 183, 248, 76, 14, 7, 52, 237, 249, 250, 183, + 201, 98, 23, 248, 76, 14, 7, 52, 237, 249, 250, 183, 234, 94, 14, 7, 52, + 237, 249, 250, 183, 198, 54, 23, 234, 94, 14, 7, 52, 237, 249, 250, 183, + 248, 77, 23, 234, 94, 14, 7, 52, 237, 248, 29, 7, 255, 199, 29, 7, 255, + 198, 29, 7, 255, 197, 29, 7, 255, 196, 29, 7, 255, 195, 29, 7, 255, 193, + 29, 7, 255, 190, 29, 7, 255, 189, 29, 7, 255, 188, 29, 7, 255, 187, 29, + 7, 255, 186, 29, 7, 255, 185, 29, 7, 255, 184, 29, 7, 255, 183, 29, 7, + 255, 182, 29, 7, 255, 180, 29, 7, 255, 179, 29, 7, 255, 178, 29, 7, 255, + 176, 29, 7, 255, 175, 29, 7, 255, 174, 29, 7, 255, 173, 29, 7, 255, 172, + 29, 7, 255, 171, 29, 7, 255, 170, 29, 7, 255, 169, 29, 7, 255, 168, 29, + 7, 255, 167, 29, 7, 255, 166, 29, 7, 255, 165, 29, 7, 255, 163, 29, 7, + 255, 162, 29, 7, 255, 161, 29, 7, 255, 160, 29, 7, 255, 158, 29, 7, 255, + 157, 29, 7, 255, 156, 29, 7, 255, 155, 29, 7, 255, 154, 29, 7, 255, 153, + 29, 7, 255, 152, 29, 7, 255, 151, 29, 7, 255, 150, 29, 7, 255, 148, 29, + 7, 255, 147, 29, 7, 255, 146, 29, 7, 255, 144, 29, 7, 255, 142, 29, 7, + 255, 141, 29, 7, 255, 140, 29, 7, 255, 139, 29, 7, 255, 138, 29, 7, 255, + 137, 29, 7, 255, 136, 29, 7, 255, 135, 29, 7, 255, 134, 29, 7, 255, 133, + 29, 7, 255, 132, 29, 7, 255, 131, 29, 7, 255, 130, 29, 7, 255, 129, 29, + 7, 255, 128, 29, 7, 255, 127, 29, 7, 255, 126, 29, 7, 255, 125, 29, 7, + 255, 124, 29, 7, 255, 123, 29, 7, 255, 122, 29, 7, 255, 121, 29, 7, 255, + 120, 29, 7, 255, 119, 29, 7, 255, 118, 29, 7, 255, 117, 29, 7, 255, 116, + 29, 7, 255, 115, 29, 7, 255, 114, 29, 7, 255, 113, 29, 7, 255, 112, 29, + 7, 255, 111, 29, 7, 255, 110, 29, 7, 255, 109, 29, 7, 255, 108, 29, 7, + 255, 107, 29, 7, 255, 106, 29, 7, 255, 105, 29, 7, 255, 104, 29, 7, 255, + 103, 29, 7, 255, 102, 29, 7, 255, 101, 29, 7, 255, 100, 29, 7, 255, 99, + 29, 7, 255, 98, 29, 7, 255, 97, 29, 7, 255, 96, 29, 7, 255, 95, 29, 7, + 255, 94, 29, 7, 255, 93, 29, 7, 255, 92, 29, 7, 255, 91, 29, 7, 255, 90, + 29, 7, 255, 89, 29, 7, 255, 88, 29, 7, 255, 87, 29, 7, 255, 86, 29, 7, + 255, 85, 29, 7, 255, 84, 29, 7, 255, 83, 29, 7, 255, 82, 29, 7, 255, 81, + 29, 7, 255, 80, 29, 7, 255, 79, 29, 7, 255, 78, 29, 7, 255, 76, 29, 7, 255, 75, 29, 7, 255, 74, 29, 7, 255, 73, 29, 7, 255, 72, 29, 7, 255, 71, 29, 7, 255, 70, 29, 7, 255, 69, 29, 7, 255, 68, 29, 7, 255, 67, 29, 7, 255, 66, 29, 7, 255, 65, 29, 7, 255, 64, 29, 7, 255, 63, 29, 7, 255, 62, @@ -16890,25 +16976,25 @@ static const unsigned char phrasebook[] = { 255, 57, 29, 7, 255, 56, 29, 7, 255, 55, 29, 7, 255, 54, 29, 7, 255, 53, 29, 7, 255, 52, 29, 7, 255, 51, 29, 7, 255, 50, 29, 7, 255, 49, 29, 7, 255, 48, 29, 7, 255, 47, 29, 7, 255, 46, 29, 7, 255, 45, 29, 7, 255, 44, - 29, 7, 255, 43, 29, 7, 255, 42, 29, 7, 255, 41, 29, 7, 255, 40, 29, 7, - 255, 39, 29, 7, 255, 38, 29, 7, 255, 37, 29, 7, 255, 36, 29, 7, 255, 35, - 29, 7, 255, 34, 29, 7, 255, 33, 29, 7, 255, 32, 29, 7, 255, 31, 29, 7, - 255, 30, 29, 7, 255, 29, 29, 7, 255, 28, 29, 7, 255, 27, 29, 7, 255, 26, - 29, 7, 255, 24, 29, 7, 255, 23, 29, 7, 255, 22, 29, 7, 255, 21, 29, 7, - 255, 20, 29, 7, 255, 19, 29, 7, 255, 18, 29, 7, 255, 17, 29, 7, 255, 16, - 29, 7, 255, 15, 29, 7, 255, 14, 29, 7, 255, 13, 29, 7, 255, 12, 29, 7, - 255, 11, 29, 7, 255, 10, 29, 7, 255, 9, 29, 7, 255, 8, 29, 7, 255, 7, 29, - 7, 255, 6, 29, 7, 255, 5, 29, 7, 255, 4, 29, 7, 255, 3, 29, 7, 255, 2, - 29, 7, 255, 1, 29, 7, 255, 0, 29, 7, 254, 255, 29, 7, 254, 254, 29, 7, - 254, 253, 29, 7, 254, 252, 29, 7, 254, 251, 29, 7, 254, 250, 29, 7, 254, - 249, 29, 7, 254, 248, 29, 7, 254, 247, 29, 7, 254, 245, 29, 7, 254, 244, + 29, 7, 255, 43, 29, 7, 255, 41, 29, 7, 255, 40, 29, 7, 255, 39, 29, 7, + 255, 38, 29, 7, 255, 37, 29, 7, 255, 36, 29, 7, 255, 35, 29, 7, 255, 34, + 29, 7, 255, 33, 29, 7, 255, 32, 29, 7, 255, 31, 29, 7, 255, 30, 29, 7, + 255, 28, 29, 7, 255, 27, 29, 7, 255, 26, 29, 7, 255, 25, 29, 7, 255, 24, + 29, 7, 255, 23, 29, 7, 255, 22, 29, 7, 255, 21, 29, 7, 255, 20, 29, 7, + 255, 19, 29, 7, 255, 18, 29, 7, 255, 17, 29, 7, 255, 16, 29, 7, 255, 15, + 29, 7, 255, 14, 29, 7, 255, 13, 29, 7, 255, 12, 29, 7, 255, 11, 29, 7, + 255, 10, 29, 7, 255, 9, 29, 7, 255, 8, 29, 7, 255, 7, 29, 7, 255, 6, 29, + 7, 255, 5, 29, 7, 255, 4, 29, 7, 255, 3, 29, 7, 255, 2, 29, 7, 255, 1, + 29, 7, 255, 0, 29, 7, 254, 255, 29, 7, 254, 254, 29, 7, 254, 253, 29, 7, + 254, 252, 29, 7, 254, 251, 29, 7, 254, 250, 29, 7, 254, 249, 29, 7, 254, + 248, 29, 7, 254, 247, 29, 7, 254, 246, 29, 7, 254, 245, 29, 7, 254, 244, 29, 7, 254, 243, 29, 7, 254, 242, 29, 7, 254, 241, 29, 7, 254, 240, 29, 7, 254, 239, 29, 7, 254, 238, 29, 7, 254, 237, 29, 7, 254, 236, 29, 7, - 254, 235, 29, 7, 254, 234, 29, 7, 254, 232, 29, 7, 254, 231, 29, 7, 254, - 230, 29, 7, 254, 229, 29, 7, 254, 228, 29, 7, 254, 227, 29, 7, 254, 226, - 29, 7, 254, 225, 29, 7, 254, 224, 29, 7, 254, 223, 29, 7, 254, 222, 29, - 7, 254, 221, 29, 7, 254, 220, 29, 7, 254, 219, 29, 7, 254, 218, 29, 7, - 254, 217, 29, 7, 254, 216, 29, 7, 254, 215, 29, 7, 254, 214, 29, 7, 254, + 254, 235, 29, 7, 254, 234, 29, 7, 254, 233, 29, 7, 254, 232, 29, 7, 254, + 231, 29, 7, 254, 230, 29, 7, 254, 229, 29, 7, 254, 228, 29, 7, 254, 227, + 29, 7, 254, 226, 29, 7, 254, 225, 29, 7, 254, 224, 29, 7, 254, 223, 29, + 7, 254, 222, 29, 7, 254, 221, 29, 7, 254, 220, 29, 7, 254, 219, 29, 7, + 254, 218, 29, 7, 254, 217, 29, 7, 254, 216, 29, 7, 254, 214, 29, 7, 254, 213, 29, 7, 254, 212, 29, 7, 254, 211, 29, 7, 254, 210, 29, 7, 254, 209, 29, 7, 254, 208, 29, 7, 254, 207, 29, 7, 254, 206, 29, 7, 254, 205, 29, 7, 254, 204, 29, 7, 254, 203, 29, 7, 254, 202, 29, 7, 254, 201, 29, 7, @@ -16920,472 +17006,469 @@ static const unsigned char phrasebook[] = { 179, 29, 7, 254, 178, 29, 7, 254, 177, 29, 7, 254, 176, 29, 7, 254, 175, 29, 7, 254, 174, 29, 7, 254, 173, 29, 7, 254, 172, 29, 7, 254, 171, 29, 7, 254, 170, 29, 7, 254, 169, 29, 7, 254, 168, 29, 7, 254, 167, 29, 7, - 254, 166, 29, 7, 254, 165, 29, 7, 254, 164, 29, 7, 254, 162, 29, 7, 254, - 161, 29, 7, 254, 160, 29, 7, 254, 159, 29, 7, 254, 158, 29, 7, 254, 157, - 29, 7, 254, 156, 29, 7, 254, 155, 29, 7, 254, 154, 29, 7, 254, 153, 29, - 7, 254, 152, 29, 7, 254, 151, 29, 7, 254, 150, 29, 7, 254, 149, 29, 7, - 254, 148, 29, 7, 254, 147, 29, 7, 254, 146, 29, 7, 254, 145, 29, 7, 254, - 144, 29, 7, 254, 143, 29, 7, 254, 142, 29, 7, 254, 141, 29, 7, 254, 140, - 29, 7, 254, 139, 29, 7, 254, 138, 29, 7, 254, 137, 29, 7, 254, 136, 29, - 7, 254, 135, 29, 7, 254, 134, 29, 7, 254, 133, 29, 7, 254, 132, 29, 7, - 254, 131, 29, 7, 254, 130, 29, 7, 254, 129, 29, 7, 254, 128, 29, 7, 254, - 127, 29, 7, 254, 126, 29, 7, 254, 125, 29, 7, 254, 124, 29, 7, 254, 123, - 29, 7, 254, 122, 29, 7, 254, 121, 29, 7, 254, 120, 29, 7, 254, 119, 29, - 7, 254, 118, 29, 7, 254, 117, 29, 7, 254, 116, 29, 7, 254, 115, 29, 7, - 254, 114, 29, 7, 254, 113, 29, 7, 254, 112, 29, 7, 254, 111, 29, 7, 254, - 110, 29, 7, 254, 109, 29, 7, 254, 108, 29, 7, 254, 107, 29, 7, 254, 106, - 29, 7, 254, 105, 29, 7, 254, 104, 29, 7, 254, 103, 29, 7, 254, 102, 29, + 254, 166, 29, 7, 254, 165, 29, 7, 254, 164, 29, 7, 254, 163, 29, 7, 254, + 162, 29, 7, 254, 161, 29, 7, 254, 160, 29, 7, 254, 159, 29, 7, 254, 158, + 29, 7, 254, 157, 29, 7, 254, 156, 29, 7, 254, 155, 29, 7, 254, 154, 29, + 7, 254, 153, 29, 7, 254, 152, 29, 7, 254, 151, 29, 7, 254, 150, 29, 7, + 254, 149, 29, 7, 254, 148, 29, 7, 254, 147, 29, 7, 254, 146, 29, 7, 254, + 145, 29, 7, 254, 144, 29, 7, 254, 143, 29, 7, 254, 142, 29, 7, 254, 141, + 29, 7, 254, 140, 29, 7, 254, 139, 29, 7, 254, 138, 29, 7, 254, 137, 29, + 7, 254, 136, 29, 7, 254, 135, 29, 7, 254, 134, 29, 7, 254, 133, 29, 7, + 254, 132, 29, 7, 254, 131, 29, 7, 254, 130, 29, 7, 254, 129, 29, 7, 254, + 128, 29, 7, 254, 127, 29, 7, 254, 126, 29, 7, 254, 125, 29, 7, 254, 124, + 29, 7, 254, 123, 29, 7, 254, 122, 29, 7, 254, 121, 29, 7, 254, 120, 29, + 7, 254, 119, 29, 7, 254, 118, 29, 7, 254, 117, 29, 7, 254, 116, 29, 7, + 254, 115, 29, 7, 254, 114, 29, 7, 254, 113, 29, 7, 254, 112, 29, 7, 254, + 111, 29, 7, 254, 110, 29, 7, 254, 109, 29, 7, 254, 108, 29, 7, 254, 107, + 29, 7, 254, 106, 29, 7, 254, 105, 29, 7, 254, 104, 29, 7, 254, 102, 29, 7, 254, 101, 29, 7, 254, 100, 29, 7, 254, 99, 29, 7, 254, 98, 29, 7, 254, 97, 29, 7, 254, 96, 29, 7, 254, 95, 29, 7, 254, 94, 29, 7, 254, 93, 29, - 7, 254, 92, 29, 7, 254, 91, 29, 7, 254, 90, 29, 7, 254, 89, 29, 7, 254, - 88, 29, 7, 254, 87, 29, 7, 254, 86, 29, 7, 254, 85, 29, 7, 254, 84, 29, - 7, 254, 83, 29, 7, 254, 82, 29, 7, 254, 81, 29, 7, 254, 80, 29, 7, 254, - 79, 29, 7, 254, 78, 29, 7, 254, 77, 29, 7, 254, 76, 29, 7, 254, 75, 29, - 7, 254, 74, 29, 7, 254, 73, 29, 7, 254, 72, 29, 7, 254, 71, 29, 7, 254, - 70, 29, 7, 254, 69, 29, 7, 254, 68, 29, 7, 254, 67, 29, 7, 254, 66, 29, - 7, 254, 65, 29, 7, 254, 64, 29, 7, 254, 63, 29, 7, 254, 62, 29, 7, 254, - 61, 29, 7, 254, 60, 29, 7, 254, 59, 29, 7, 254, 58, 29, 7, 254, 57, 29, - 7, 254, 56, 29, 7, 254, 55, 29, 7, 254, 54, 29, 7, 254, 53, 29, 7, 254, - 52, 29, 7, 254, 50, 29, 7, 254, 49, 29, 7, 254, 48, 29, 7, 254, 47, 29, - 7, 254, 46, 29, 7, 254, 45, 29, 7, 254, 44, 29, 7, 254, 43, 29, 7, 254, - 42, 29, 7, 254, 41, 29, 7, 254, 40, 29, 7, 254, 37, 29, 7, 254, 36, 29, - 7, 254, 35, 29, 7, 254, 34, 29, 7, 254, 30, 29, 7, 254, 29, 29, 7, 254, + 7, 254, 92, 29, 7, 254, 89, 29, 7, 254, 88, 29, 7, 254, 87, 29, 7, 254, + 86, 29, 7, 254, 82, 29, 7, 254, 81, 29, 7, 254, 80, 29, 7, 254, 79, 29, + 7, 254, 78, 29, 7, 254, 77, 29, 7, 254, 76, 29, 7, 254, 75, 29, 7, 254, + 74, 29, 7, 254, 73, 29, 7, 254, 72, 29, 7, 254, 71, 29, 7, 254, 70, 29, + 7, 254, 69, 29, 7, 254, 68, 29, 7, 254, 67, 29, 7, 254, 66, 29, 7, 254, + 65, 29, 7, 254, 64, 29, 7, 254, 62, 29, 7, 254, 61, 29, 7, 254, 60, 29, + 7, 254, 59, 29, 7, 254, 58, 29, 7, 254, 57, 29, 7, 254, 56, 29, 7, 254, + 55, 29, 7, 254, 54, 29, 7, 254, 53, 29, 7, 254, 52, 29, 7, 254, 51, 29, + 7, 254, 50, 29, 7, 254, 49, 29, 7, 254, 48, 29, 7, 254, 47, 29, 7, 254, + 46, 29, 7, 254, 45, 29, 7, 254, 44, 29, 7, 254, 43, 29, 7, 254, 42, 29, + 7, 254, 41, 29, 7, 254, 40, 29, 7, 254, 39, 29, 7, 254, 38, 29, 7, 254, + 37, 29, 7, 254, 36, 29, 7, 254, 35, 29, 7, 254, 34, 29, 7, 254, 33, 29, + 7, 254, 32, 29, 7, 254, 31, 29, 7, 254, 30, 29, 7, 254, 29, 29, 7, 254, 28, 29, 7, 254, 27, 29, 7, 254, 26, 29, 7, 254, 25, 29, 7, 254, 24, 29, 7, 254, 23, 29, 7, 254, 22, 29, 7, 254, 21, 29, 7, 254, 20, 29, 7, 254, 19, 29, 7, 254, 18, 29, 7, 254, 17, 29, 7, 254, 16, 29, 7, 254, 15, 29, - 7, 254, 14, 29, 7, 254, 13, 29, 7, 254, 12, 29, 7, 254, 10, 29, 7, 254, - 9, 29, 7, 254, 8, 29, 7, 254, 7, 29, 7, 254, 6, 29, 7, 254, 5, 29, 7, - 254, 4, 29, 7, 254, 3, 29, 7, 254, 2, 29, 7, 254, 1, 29, 7, 254, 0, 29, - 7, 253, 255, 29, 7, 253, 254, 29, 7, 253, 253, 29, 7, 253, 252, 29, 7, - 253, 251, 29, 7, 253, 250, 29, 7, 253, 249, 29, 7, 253, 248, 29, 7, 253, - 247, 29, 7, 253, 246, 29, 7, 253, 245, 29, 7, 253, 244, 29, 7, 253, 243, - 29, 7, 253, 242, 29, 7, 253, 241, 29, 7, 253, 240, 29, 7, 253, 239, 29, - 7, 253, 238, 29, 7, 253, 237, 29, 7, 253, 236, 29, 7, 253, 235, 29, 7, - 253, 234, 29, 7, 253, 233, 29, 7, 253, 232, 29, 7, 253, 231, 29, 7, 253, - 230, 29, 7, 253, 229, 29, 7, 253, 228, 29, 7, 253, 227, 29, 7, 253, 226, - 29, 7, 253, 225, 29, 7, 253, 224, 29, 7, 253, 223, 29, 7, 253, 222, 29, - 7, 253, 221, 29, 7, 253, 220, 29, 7, 253, 219, 29, 7, 253, 218, 29, 7, - 253, 217, 29, 7, 253, 216, 29, 7, 253, 215, 29, 7, 253, 214, 29, 7, 253, - 213, 29, 7, 253, 212, 29, 7, 253, 211, 29, 7, 253, 210, 29, 7, 253, 209, - 29, 7, 253, 208, 29, 7, 253, 207, 29, 7, 253, 206, 29, 7, 253, 205, 207, - 181, 211, 46, 206, 252, 29, 7, 253, 204, 29, 7, 253, 203, 29, 7, 253, - 202, 29, 7, 253, 201, 29, 7, 253, 200, 29, 7, 253, 199, 29, 7, 253, 198, - 29, 7, 253, 197, 29, 7, 253, 196, 29, 7, 253, 195, 29, 7, 253, 194, 29, - 7, 253, 193, 176, 29, 7, 253, 192, 29, 7, 253, 191, 29, 7, 253, 190, 29, - 7, 253, 189, 29, 7, 253, 188, 29, 7, 253, 187, 29, 7, 253, 186, 29, 7, - 253, 184, 29, 7, 253, 182, 29, 7, 253, 180, 29, 7, 253, 178, 29, 7, 253, - 176, 29, 7, 253, 174, 29, 7, 253, 172, 29, 7, 253, 170, 29, 7, 253, 168, - 29, 7, 253, 166, 248, 199, 219, 4, 77, 29, 7, 253, 164, 234, 53, 219, 4, - 77, 29, 7, 253, 163, 29, 7, 253, 161, 29, 7, 253, 159, 29, 7, 253, 157, - 29, 7, 253, 155, 29, 7, 253, 153, 29, 7, 253, 151, 29, 7, 253, 149, 29, - 7, 253, 147, 29, 7, 253, 146, 29, 7, 253, 145, 29, 7, 253, 144, 29, 7, - 253, 143, 29, 7, 253, 142, 29, 7, 253, 141, 29, 7, 253, 140, 29, 7, 253, - 139, 29, 7, 253, 138, 29, 7, 253, 137, 29, 7, 253, 136, 29, 7, 253, 135, - 29, 7, 253, 134, 29, 7, 253, 133, 29, 7, 253, 132, 29, 7, 253, 131, 29, - 7, 253, 130, 29, 7, 253, 129, 29, 7, 253, 128, 29, 7, 253, 127, 29, 7, - 253, 126, 29, 7, 253, 125, 29, 7, 253, 124, 29, 7, 253, 123, 29, 7, 253, - 122, 29, 7, 253, 121, 29, 7, 253, 120, 29, 7, 253, 119, 29, 7, 253, 118, - 29, 7, 253, 117, 29, 7, 253, 116, 29, 7, 253, 115, 29, 7, 253, 114, 29, - 7, 253, 113, 29, 7, 253, 112, 29, 7, 253, 111, 29, 7, 253, 110, 29, 7, - 253, 109, 29, 7, 253, 108, 29, 7, 253, 107, 29, 7, 253, 106, 29, 7, 253, - 105, 29, 7, 253, 104, 29, 7, 253, 103, 29, 7, 253, 102, 29, 7, 253, 101, - 29, 7, 253, 100, 29, 7, 253, 99, 29, 7, 253, 98, 29, 7, 253, 97, 29, 7, - 253, 96, 29, 7, 253, 95, 29, 7, 253, 94, 29, 7, 253, 93, 29, 7, 253, 92, - 29, 7, 253, 91, 29, 7, 253, 90, 29, 7, 253, 89, 29, 7, 253, 88, 29, 7, - 253, 87, 29, 7, 253, 86, 29, 7, 253, 85, 29, 7, 253, 84, 29, 7, 253, 83, - 29, 7, 253, 82, 29, 7, 253, 81, 29, 7, 253, 80, 29, 7, 253, 79, 29, 7, - 253, 78, 29, 7, 253, 77, 29, 7, 253, 76, 29, 7, 253, 75, 29, 7, 253, 74, - 29, 7, 253, 73, 29, 7, 253, 72, 29, 7, 253, 71, 29, 7, 253, 70, 29, 7, - 253, 69, 29, 7, 253, 68, 29, 7, 253, 67, 29, 7, 253, 66, 29, 7, 253, 65, - 29, 7, 253, 64, 29, 7, 253, 63, 29, 7, 253, 62, 29, 7, 253, 61, 29, 7, - 253, 60, 29, 7, 253, 59, 29, 7, 253, 58, 29, 7, 253, 57, 29, 7, 253, 56, - 29, 7, 253, 55, 29, 7, 253, 54, 29, 7, 253, 53, 29, 7, 253, 52, 29, 7, - 253, 51, 29, 7, 253, 50, 29, 7, 253, 49, 29, 7, 253, 48, 29, 7, 253, 47, - 29, 7, 253, 46, 29, 7, 253, 45, 29, 7, 253, 44, 29, 7, 253, 43, 29, 7, - 253, 42, 29, 7, 253, 41, 29, 7, 253, 40, 29, 7, 253, 39, 29, 7, 253, 38, - 29, 7, 253, 37, 26, 1, 209, 209, 213, 243, 216, 123, 26, 1, 209, 209, - 231, 136, 232, 127, 26, 1, 209, 209, 209, 33, 216, 124, 209, 119, 26, 1, - 209, 209, 209, 33, 216, 124, 209, 120, 26, 1, 209, 209, 214, 237, 216, - 123, 26, 1, 209, 209, 202, 251, 26, 1, 209, 209, 198, 119, 216, 123, 26, - 1, 209, 209, 212, 34, 216, 123, 26, 1, 209, 209, 203, 63, 210, 211, 213, - 128, 26, 1, 209, 209, 209, 33, 210, 211, 213, 129, 209, 119, 26, 1, 209, - 209, 209, 33, 210, 211, 213, 129, 209, 120, 26, 1, 209, 209, 217, 110, - 26, 1, 209, 209, 197, 91, 217, 111, 26, 1, 209, 209, 214, 48, 26, 1, 209, - 209, 217, 107, 26, 1, 209, 209, 217, 57, 26, 1, 209, 209, 215, 72, 26, 1, - 209, 209, 203, 244, 26, 1, 209, 209, 212, 174, 26, 1, 209, 209, 221, 209, - 26, 1, 209, 209, 213, 95, 26, 1, 209, 209, 200, 156, 26, 1, 209, 209, - 213, 242, 26, 1, 209, 209, 219, 247, 26, 1, 209, 209, 219, 153, 220, 164, - 26, 1, 209, 209, 212, 184, 216, 131, 26, 1, 209, 209, 217, 114, 26, 1, - 209, 209, 210, 88, 26, 1, 209, 209, 231, 35, 26, 1, 209, 209, 210, 160, - 26, 1, 209, 209, 215, 215, 214, 21, 26, 1, 209, 209, 212, 15, 216, 134, - 26, 1, 209, 209, 126, 191, 195, 214, 230, 26, 1, 209, 209, 231, 36, 26, - 1, 209, 209, 212, 184, 212, 185, 26, 1, 209, 209, 202, 134, 26, 1, 209, - 209, 216, 116, 26, 1, 209, 209, 216, 137, 26, 1, 209, 209, 215, 190, 26, - 1, 209, 209, 222, 78, 26, 1, 209, 209, 210, 211, 219, 201, 26, 1, 209, - 209, 214, 149, 219, 201, 26, 1, 209, 209, 209, 231, 26, 1, 209, 209, 217, - 108, 26, 1, 209, 209, 213, 171, 26, 1, 209, 209, 208, 137, 26, 1, 209, - 209, 197, 83, 26, 1, 209, 209, 218, 199, 26, 1, 209, 209, 202, 12, 26, 1, - 209, 209, 199, 53, 26, 1, 209, 209, 217, 105, 26, 1, 209, 209, 221, 216, - 26, 1, 209, 209, 214, 145, 26, 1, 209, 209, 220, 179, 26, 1, 209, 209, - 215, 191, 26, 1, 209, 209, 202, 247, 26, 1, 209, 209, 218, 252, 26, 1, - 209, 209, 232, 198, 26, 1, 209, 209, 206, 132, 26, 1, 209, 209, 220, 242, - 26, 1, 209, 209, 202, 8, 26, 1, 209, 209, 217, 52, 209, 164, 26, 1, 209, - 209, 203, 56, 26, 1, 209, 209, 212, 183, 26, 1, 209, 209, 203, 37, 212, - 195, 191, 203, 26, 1, 209, 209, 212, 56, 215, 211, 26, 1, 209, 209, 210, - 206, 26, 1, 209, 209, 213, 97, 26, 1, 209, 209, 196, 81, 26, 1, 209, 209, - 214, 24, 26, 1, 209, 209, 217, 104, 26, 1, 209, 209, 213, 140, 26, 1, - 209, 209, 216, 243, 26, 1, 209, 209, 212, 71, 26, 1, 209, 209, 199, 57, - 26, 1, 209, 209, 202, 3, 26, 1, 209, 209, 210, 207, 26, 1, 209, 209, 212, - 199, 26, 1, 209, 209, 217, 112, 26, 1, 209, 209, 212, 68, 26, 1, 209, - 209, 222, 40, 26, 1, 209, 209, 212, 202, 26, 1, 209, 209, 195, 145, 26, - 1, 209, 209, 218, 203, 26, 1, 209, 209, 214, 88, 26, 1, 209, 209, 214, - 203, 26, 1, 209, 209, 216, 242, 26, 1, 209, 208, 212, 197, 26, 1, 209, - 208, 197, 91, 217, 109, 26, 1, 209, 208, 202, 199, 26, 1, 209, 208, 203, - 248, 197, 90, 26, 1, 209, 208, 218, 255, 212, 180, 26, 1, 209, 208, 216, - 249, 217, 113, 26, 1, 209, 208, 221, 126, 26, 1, 209, 208, 192, 43, 26, - 1, 209, 208, 216, 244, 26, 1, 209, 208, 222, 64, 26, 1, 209, 208, 210, - 35, 26, 1, 209, 208, 192, 126, 219, 201, 26, 1, 209, 208, 220, 12, 212, - 195, 212, 82, 26, 1, 209, 208, 212, 177, 203, 82, 26, 1, 209, 208, 214, - 116, 213, 143, 26, 1, 209, 208, 231, 33, 26, 1, 209, 208, 209, 109, 26, - 1, 209, 208, 197, 91, 212, 193, 26, 1, 209, 208, 203, 87, 213, 138, 26, - 1, 209, 208, 203, 83, 26, 1, 209, 208, 216, 124, 199, 56, 26, 1, 209, - 208, 216, 231, 216, 245, 26, 1, 209, 208, 212, 69, 212, 180, 26, 1, 209, - 208, 221, 205, 26, 1, 209, 208, 231, 34, 26, 1, 209, 208, 221, 201, 26, - 1, 209, 208, 220, 96, 26, 1, 209, 208, 210, 91, 26, 1, 209, 208, 195, 74, - 26, 1, 209, 208, 213, 244, 215, 70, 26, 1, 209, 208, 214, 23, 216, 227, - 26, 1, 209, 208, 192, 254, 26, 1, 209, 208, 205, 170, 26, 1, 209, 208, - 199, 235, 26, 1, 209, 208, 216, 136, 26, 1, 209, 208, 214, 7, 26, 1, 209, - 208, 214, 8, 219, 244, 26, 1, 209, 208, 216, 126, 26, 1, 209, 208, 200, - 209, 26, 1, 209, 208, 216, 235, 26, 1, 209, 208, 215, 195, 26, 1, 209, - 208, 212, 86, 26, 1, 209, 208, 208, 141, 26, 1, 209, 208, 216, 135, 214, - 25, 26, 1, 209, 208, 232, 243, 26, 1, 209, 208, 216, 222, 26, 1, 209, - 208, 233, 11, 26, 1, 209, 208, 221, 213, 26, 1, 209, 208, 217, 139, 213, - 132, 26, 1, 209, 208, 217, 139, 213, 108, 26, 1, 209, 208, 219, 152, 26, - 1, 209, 208, 214, 31, 26, 1, 209, 208, 212, 204, 26, 1, 209, 208, 172, - 26, 1, 209, 208, 221, 109, 26, 1, 209, 208, 213, 232, 26, 1, 209, 207, - 213, 243, 217, 111, 26, 1, 209, 207, 212, 33, 26, 1, 209, 207, 191, 203, - 26, 1, 209, 207, 193, 158, 26, 1, 209, 207, 214, 24, 26, 1, 209, 207, - 214, 137, 26, 1, 209, 207, 213, 250, 26, 1, 209, 207, 231, 43, 26, 1, - 209, 207, 216, 239, 26, 1, 209, 207, 231, 143, 26, 1, 209, 207, 212, 58, - 216, 4, 216, 138, 26, 1, 209, 207, 212, 171, 216, 230, 26, 1, 209, 207, - 216, 236, 26, 1, 209, 207, 209, 115, 26, 1, 209, 207, 214, 122, 26, 1, - 209, 207, 216, 247, 247, 108, 26, 1, 209, 207, 221, 203, 26, 1, 209, 207, - 231, 44, 26, 1, 209, 207, 221, 210, 26, 1, 209, 207, 191, 226, 215, 103, - 26, 1, 209, 207, 212, 27, 26, 1, 209, 207, 216, 224, 26, 1, 209, 207, - 212, 203, 26, 1, 209, 207, 216, 230, 26, 1, 209, 207, 192, 44, 26, 1, - 209, 207, 220, 250, 26, 1, 209, 207, 222, 100, 26, 1, 209, 207, 203, 243, - 26, 1, 209, 207, 214, 131, 26, 1, 209, 207, 199, 233, 26, 1, 209, 207, - 213, 112, 26, 1, 209, 207, 198, 119, 191, 207, 26, 1, 209, 207, 200, 242, - 26, 1, 209, 207, 214, 14, 212, 82, 26, 1, 209, 207, 195, 73, 26, 1, 209, - 207, 214, 206, 26, 1, 209, 207, 217, 139, 221, 212, 26, 1, 209, 207, 212, - 185, 26, 1, 209, 207, 214, 9, 26, 1, 209, 207, 219, 248, 26, 1, 209, 207, - 216, 232, 26, 1, 209, 207, 216, 115, 26, 1, 209, 207, 212, 179, 26, 1, - 209, 207, 199, 52, 26, 1, 209, 207, 214, 11, 26, 1, 209, 207, 232, 46, - 26, 1, 209, 207, 214, 136, 26, 1, 209, 207, 212, 205, 26, 1, 209, 207, - 212, 201, 26, 1, 209, 207, 247, 192, 26, 1, 209, 207, 195, 75, 26, 1, - 209, 207, 216, 237, 26, 1, 209, 207, 206, 63, 26, 1, 209, 207, 213, 142, - 26, 1, 209, 207, 220, 11, 26, 1, 209, 207, 198, 116, 26, 1, 209, 207, - 212, 187, 213, 232, 26, 1, 209, 207, 213, 134, 26, 1, 209, 207, 221, 216, - 26, 1, 209, 207, 214, 16, 26, 1, 209, 207, 217, 104, 26, 1, 209, 207, - 216, 225, 26, 1, 209, 207, 218, 203, 26, 1, 209, 207, 220, 164, 26, 1, - 209, 207, 213, 140, 26, 1, 209, 207, 213, 232, 26, 1, 209, 207, 192, 244, - 26, 1, 209, 207, 214, 12, 26, 1, 209, 207, 212, 190, 26, 1, 209, 207, - 212, 181, 26, 1, 209, 207, 220, 181, 213, 97, 26, 1, 209, 207, 212, 188, - 26, 1, 209, 207, 214, 144, 26, 1, 209, 207, 217, 139, 212, 193, 26, 1, - 209, 207, 192, 140, 26, 1, 209, 207, 214, 143, 26, 1, 209, 207, 202, 250, - 26, 1, 209, 207, 203, 246, 26, 1, 209, 207, 216, 233, 26, 1, 209, 207, - 217, 111, 26, 1, 209, 207, 216, 243, 26, 1, 209, 207, 221, 204, 26, 1, - 209, 207, 216, 234, 26, 1, 209, 207, 221, 208, 26, 1, 209, 207, 216, 247, - 209, 170, 26, 1, 209, 207, 191, 186, 26, 1, 209, 207, 213, 130, 26, 1, - 209, 207, 216, 62, 26, 1, 209, 207, 215, 133, 26, 1, 209, 207, 203, 59, - 26, 1, 209, 207, 221, 227, 219, 226, 26, 1, 209, 207, 221, 227, 233, 24, - 26, 1, 209, 207, 214, 46, 26, 1, 209, 207, 214, 203, 26, 1, 209, 207, - 219, 70, 26, 1, 209, 207, 209, 130, 26, 1, 209, 207, 210, 25, 26, 1, 209, - 207, 199, 68, 26, 1, 158, 216, 223, 26, 1, 158, 193, 156, 26, 1, 158, - 213, 128, 26, 1, 158, 216, 123, 26, 1, 158, 213, 126, 26, 1, 158, 219, - 115, 26, 1, 158, 213, 131, 26, 1, 158, 212, 200, 26, 1, 158, 214, 30, 26, - 1, 158, 212, 82, 26, 1, 158, 192, 255, 26, 1, 158, 213, 240, 26, 1, 158, - 203, 106, 26, 1, 158, 213, 251, 26, 1, 158, 221, 211, 26, 1, 158, 199, - 54, 26, 1, 158, 203, 85, 26, 1, 158, 213, 139, 26, 1, 158, 200, 209, 26, - 1, 158, 221, 216, 26, 1, 158, 192, 128, 26, 1, 158, 220, 182, 26, 1, 158, - 205, 125, 26, 1, 158, 216, 128, 26, 1, 158, 214, 135, 26, 1, 158, 217, - 75, 26, 1, 158, 216, 134, 26, 1, 158, 203, 245, 26, 1, 158, 192, 70, 26, - 1, 158, 213, 133, 26, 1, 158, 221, 207, 216, 226, 26, 1, 158, 213, 247, - 26, 1, 158, 197, 90, 26, 1, 158, 231, 53, 26, 1, 158, 213, 237, 26, 1, - 158, 232, 244, 26, 1, 158, 214, 139, 26, 1, 158, 216, 107, 26, 1, 158, - 219, 146, 26, 1, 158, 214, 121, 26, 1, 158, 215, 210, 26, 1, 158, 216, - 111, 26, 1, 158, 208, 120, 26, 1, 158, 216, 109, 26, 1, 158, 216, 125, - 26, 1, 158, 218, 186, 26, 1, 158, 212, 192, 26, 1, 158, 216, 246, 26, 1, - 158, 220, 153, 26, 1, 158, 212, 71, 26, 1, 158, 199, 57, 26, 1, 158, 202, - 3, 26, 1, 158, 191, 186, 26, 1, 158, 221, 208, 26, 1, 158, 207, 157, 26, - 1, 158, 199, 115, 26, 1, 158, 213, 248, 26, 1, 158, 216, 130, 26, 1, 158, - 212, 191, 26, 1, 158, 221, 206, 26, 1, 158, 209, 121, 26, 1, 158, 209, - 224, 26, 1, 158, 212, 44, 26, 1, 158, 219, 152, 26, 1, 158, 214, 31, 26, - 1, 158, 216, 127, 26, 1, 158, 214, 4, 26, 1, 158, 191, 200, 26, 1, 158, - 210, 127, 26, 1, 158, 191, 199, 26, 1, 158, 214, 144, 26, 1, 158, 212, - 180, 26, 1, 158, 200, 244, 26, 1, 158, 220, 186, 26, 1, 158, 214, 20, 26, - 1, 158, 213, 245, 26, 1, 158, 197, 65, 26, 1, 158, 216, 138, 26, 1, 158, - 220, 175, 26, 1, 158, 212, 189, 26, 1, 158, 199, 55, 26, 1, 158, 217, - 106, 26, 1, 158, 214, 29, 26, 1, 158, 219, 145, 26, 1, 158, 214, 10, 26, - 1, 158, 212, 194, 26, 1, 158, 213, 112, 26, 1, 158, 231, 37, 26, 1, 158, - 220, 208, 26, 1, 158, 207, 51, 211, 108, 26, 1, 158, 199, 221, 26, 1, - 158, 198, 45, 26, 1, 158, 212, 68, 26, 1, 158, 206, 190, 26, 1, 158, 219, - 203, 26, 1, 158, 216, 191, 26, 1, 158, 218, 147, 26, 1, 158, 200, 156, - 26, 1, 158, 215, 139, 26, 1, 158, 203, 71, 26, 1, 158, 203, 81, 26, 1, - 158, 220, 125, 26, 1, 158, 212, 165, 26, 1, 158, 203, 0, 26, 1, 158, 212, - 182, 26, 1, 158, 210, 40, 26, 1, 158, 213, 205, 26, 1, 158, 203, 36, 26, - 1, 158, 208, 136, 26, 1, 158, 215, 70, 26, 1, 158, 218, 232, 26, 1, 158, - 207, 51, 215, 128, 26, 1, 158, 198, 188, 26, 1, 158, 212, 168, 26, 1, - 158, 216, 247, 181, 26, 1, 158, 205, 123, 26, 1, 158, 233, 67, 26, 1, - 114, 214, 143, 26, 1, 114, 198, 52, 26, 1, 114, 216, 236, 26, 1, 114, - 219, 248, 26, 1, 114, 195, 7, 26, 1, 114, 218, 238, 26, 1, 114, 210, 210, - 26, 1, 114, 202, 16, 26, 1, 114, 207, 129, 26, 1, 114, 212, 196, 26, 1, - 114, 214, 114, 26, 1, 114, 208, 154, 26, 1, 114, 199, 192, 26, 1, 114, - 213, 253, 26, 1, 114, 220, 246, 26, 1, 114, 192, 247, 26, 1, 114, 205, - 45, 26, 1, 114, 214, 21, 26, 1, 114, 210, 207, 26, 1, 114, 198, 54, 26, - 1, 114, 220, 180, 26, 1, 114, 218, 254, 26, 1, 114, 212, 199, 26, 1, 114, - 213, 229, 26, 1, 114, 217, 112, 26, 1, 114, 213, 246, 26, 1, 114, 213, - 228, 26, 1, 114, 212, 198, 26, 1, 114, 206, 187, 26, 1, 114, 213, 130, - 26, 1, 114, 210, 37, 26, 1, 114, 205, 192, 26, 1, 114, 214, 5, 26, 1, - 114, 216, 117, 26, 1, 114, 231, 31, 26, 1, 114, 213, 249, 26, 1, 114, - 213, 141, 26, 1, 114, 217, 51, 26, 1, 114, 218, 234, 26, 1, 114, 214, 26, - 26, 1, 114, 214, 127, 26, 1, 114, 199, 220, 212, 180, 26, 1, 114, 203, - 247, 26, 1, 114, 208, 147, 26, 1, 114, 214, 147, 202, 25, 26, 1, 114, - 214, 13, 212, 82, 26, 1, 114, 192, 29, 26, 1, 114, 231, 32, 26, 1, 114, - 197, 84, 26, 1, 114, 192, 47, 26, 1, 114, 209, 65, 26, 1, 114, 197, 71, - 26, 1, 114, 221, 214, 26, 1, 114, 200, 243, 26, 1, 114, 199, 56, 26, 1, - 114, 195, 76, 26, 1, 114, 193, 98, 26, 1, 114, 220, 99, 26, 1, 114, 208, - 158, 26, 1, 114, 199, 234, 26, 1, 114, 231, 52, 26, 1, 114, 214, 36, 26, - 1, 114, 203, 84, 26, 1, 114, 216, 112, 26, 1, 114, 216, 240, 26, 1, 114, - 212, 31, 26, 1, 114, 213, 93, 26, 1, 114, 231, 139, 26, 1, 114, 197, 72, - 26, 1, 114, 220, 191, 26, 1, 114, 192, 104, 26, 1, 114, 212, 69, 242, - 189, 26, 1, 114, 192, 18, 26, 1, 114, 216, 129, 26, 1, 114, 214, 132, 26, - 1, 114, 209, 165, 26, 1, 114, 191, 206, 26, 1, 114, 219, 147, 26, 1, 114, - 232, 46, 26, 1, 114, 231, 138, 26, 1, 114, 213, 239, 26, 1, 114, 221, - 216, 26, 1, 114, 217, 115, 26, 1, 114, 213, 252, 26, 1, 114, 231, 38, 26, - 1, 114, 233, 68, 26, 1, 114, 212, 169, 26, 1, 114, 209, 225, 26, 1, 114, - 192, 45, 26, 1, 114, 214, 22, 26, 1, 114, 212, 69, 248, 159, 26, 1, 114, - 212, 11, 26, 1, 114, 209, 28, 26, 1, 114, 216, 62, 26, 1, 114, 232, 44, - 26, 1, 114, 214, 230, 26, 1, 114, 215, 133, 26, 1, 114, 231, 37, 26, 1, - 114, 232, 49, 70, 26, 1, 114, 215, 71, 26, 1, 114, 208, 153, 26, 1, 114, - 213, 241, 26, 1, 114, 220, 164, 26, 1, 114, 209, 162, 26, 1, 114, 212, - 183, 26, 1, 114, 192, 46, 26, 1, 114, 214, 6, 26, 1, 114, 210, 211, 210, - 10, 26, 1, 114, 232, 49, 247, 90, 26, 1, 114, 232, 128, 26, 1, 114, 213, - 135, 26, 1, 114, 65, 26, 1, 114, 198, 45, 26, 1, 114, 74, 26, 1, 114, 70, - 26, 1, 114, 219, 246, 26, 1, 114, 210, 211, 209, 74, 26, 1, 114, 199, - 240, 26, 1, 114, 199, 175, 26, 1, 114, 214, 147, 215, 57, 228, 141, 26, - 1, 114, 203, 59, 26, 1, 114, 192, 42, 26, 1, 114, 213, 222, 26, 1, 114, - 191, 211, 26, 1, 114, 191, 244, 200, 132, 26, 1, 114, 191, 244, 238, 195, - 26, 1, 114, 191, 194, 26, 1, 114, 191, 202, 26, 1, 114, 221, 202, 26, 1, - 114, 209, 223, 26, 1, 114, 213, 136, 234, 7, 26, 1, 114, 208, 149, 26, 1, - 114, 192, 253, 26, 1, 114, 233, 11, 26, 1, 114, 195, 145, 26, 1, 114, - 218, 203, 26, 1, 114, 216, 81, 26, 1, 114, 207, 15, 26, 1, 114, 207, 158, - 26, 1, 114, 213, 221, 26, 1, 114, 214, 54, 26, 1, 114, 203, 51, 26, 1, - 114, 203, 36, 26, 1, 114, 232, 49, 207, 54, 26, 1, 114, 180, 26, 1, 114, - 209, 176, 26, 1, 114, 218, 232, 26, 1, 114, 221, 43, 26, 1, 114, 216, - 167, 26, 1, 114, 172, 26, 1, 114, 217, 48, 26, 1, 114, 199, 58, 26, 1, - 114, 221, 142, 26, 1, 114, 215, 214, 26, 1, 114, 199, 90, 26, 1, 114, - 233, 35, 26, 1, 114, 231, 25, 26, 1, 209, 206, 157, 26, 1, 209, 206, 69, - 26, 1, 209, 206, 220, 208, 26, 1, 209, 206, 234, 145, 26, 1, 209, 206, - 207, 79, 26, 1, 209, 206, 199, 221, 26, 1, 209, 206, 212, 68, 26, 1, 209, - 206, 171, 26, 1, 209, 206, 206, 190, 26, 1, 209, 206, 206, 237, 26, 1, - 209, 206, 216, 191, 26, 1, 209, 206, 199, 240, 26, 1, 209, 206, 214, 146, - 26, 1, 209, 206, 213, 142, 26, 1, 209, 206, 218, 147, 26, 1, 209, 206, - 200, 156, 26, 1, 209, 206, 203, 71, 26, 1, 209, 206, 202, 217, 26, 1, - 209, 206, 203, 243, 26, 1, 209, 206, 220, 125, 26, 1, 209, 206, 221, 216, - 26, 1, 209, 206, 212, 133, 26, 1, 209, 206, 212, 165, 26, 1, 209, 206, - 213, 113, 26, 1, 209, 206, 191, 243, 26, 1, 209, 206, 203, 0, 26, 1, 209, - 206, 169, 26, 1, 209, 206, 212, 202, 26, 1, 209, 206, 209, 223, 26, 1, - 209, 206, 212, 182, 26, 1, 209, 206, 192, 253, 26, 1, 209, 206, 210, 40, - 26, 1, 209, 206, 206, 63, 26, 1, 209, 206, 213, 205, 26, 1, 209, 206, - 207, 15, 26, 1, 209, 206, 221, 226, 26, 1, 209, 206, 213, 238, 26, 1, - 209, 206, 214, 33, 26, 1, 209, 206, 203, 51, 26, 1, 209, 206, 208, 154, - 26, 1, 209, 206, 232, 128, 26, 1, 209, 206, 193, 187, 26, 1, 209, 206, - 219, 122, 26, 1, 209, 206, 218, 232, 26, 1, 209, 206, 221, 43, 26, 1, - 209, 206, 216, 238, 26, 1, 209, 206, 207, 50, 26, 1, 209, 206, 172, 26, - 1, 209, 206, 215, 251, 26, 1, 209, 206, 216, 246, 26, 1, 209, 206, 199, - 68, 26, 1, 209, 206, 220, 253, 26, 1, 209, 206, 205, 145, 26, 1, 209, - 206, 193, 245, 215, 143, 1, 199, 247, 215, 143, 1, 214, 2, 215, 143, 1, - 192, 12, 215, 143, 1, 216, 28, 215, 143, 1, 249, 103, 215, 143, 1, 237, - 241, 215, 143, 1, 65, 215, 143, 1, 209, 202, 215, 143, 1, 221, 184, 215, - 143, 1, 229, 245, 215, 143, 1, 237, 216, 215, 143, 1, 243, 0, 215, 143, - 1, 221, 246, 215, 143, 1, 211, 109, 215, 143, 1, 217, 112, 215, 143, 1, - 213, 165, 215, 143, 1, 168, 215, 143, 1, 211, 76, 215, 143, 1, 74, 215, - 143, 1, 206, 157, 215, 143, 1, 203, 76, 215, 143, 1, 199, 27, 215, 143, - 1, 234, 173, 215, 143, 1, 193, 187, 215, 143, 1, 73, 215, 143, 1, 221, - 43, 215, 143, 1, 220, 0, 215, 143, 1, 171, 215, 143, 1, 230, 47, 215, - 143, 1, 206, 252, 215, 143, 1, 199, 105, 215, 143, 17, 191, 77, 215, 143, - 17, 108, 215, 143, 17, 109, 215, 143, 17, 139, 215, 143, 17, 137, 215, - 143, 17, 153, 215, 143, 17, 173, 215, 143, 17, 181, 215, 143, 17, 176, - 215, 143, 17, 184, 215, 143, 237, 193, 215, 143, 54, 237, 193, 199, 181, - 1, 210, 228, 199, 181, 1, 211, 153, 199, 181, 1, 211, 47, 199, 181, 1, - 210, 237, 199, 181, 1, 250, 73, 199, 181, 1, 252, 11, 199, 181, 1, 250, - 243, 199, 181, 1, 250, 83, 199, 181, 1, 193, 224, 199, 181, 1, 195, 152, - 199, 181, 1, 194, 252, 199, 181, 1, 193, 233, 199, 181, 1, 233, 141, 199, - 181, 1, 234, 153, 199, 181, 1, 234, 4, 199, 181, 1, 233, 180, 199, 181, - 1, 223, 13, 199, 181, 1, 227, 254, 199, 181, 1, 223, 51, 199, 181, 1, - 223, 17, 199, 181, 1, 196, 14, 199, 181, 1, 196, 156, 199, 181, 1, 196, - 60, 199, 181, 1, 196, 18, 199, 181, 1, 250, 84, 199, 181, 1, 250, 88, - 199, 181, 1, 250, 86, 199, 181, 1, 250, 85, 199, 181, 1, 196, 125, 199, - 181, 1, 196, 134, 199, 181, 1, 196, 131, 199, 181, 1, 196, 126, 199, 181, - 1, 52, 214, 56, 199, 181, 1, 177, 196, 141, 199, 181, 1, 203, 35, 196, - 139, 199, 181, 1, 203, 35, 250, 85, 199, 181, 1, 196, 146, 199, 181, 1, - 196, 139, 199, 181, 1, 196, 142, 199, 181, 1, 196, 141, 199, 181, 1, 196, - 127, 199, 181, 1, 196, 130, 199, 181, 1, 196, 129, 199, 181, 1, 196, 128, - 199, 181, 1, 215, 49, 199, 181, 1, 216, 219, 199, 181, 1, 215, 149, 199, - 181, 1, 215, 58, 199, 181, 1, 157, 199, 181, 1, 221, 190, 199, 181, 1, - 231, 203, 199, 181, 1, 214, 54, 199, 181, 1, 189, 199, 181, 1, 169, 199, - 181, 1, 193, 187, 199, 181, 1, 168, 199, 181, 1, 212, 88, 199, 181, 1, - 209, 219, 199, 181, 1, 249, 103, 199, 181, 1, 172, 199, 181, 1, 180, 199, - 181, 1, 144, 199, 181, 1, 171, 199, 181, 1, 228, 133, 199, 181, 1, 199, - 247, 199, 181, 1, 237, 241, 199, 181, 1, 166, 199, 181, 1, 213, 210, 199, - 181, 1, 203, 160, 199, 181, 1, 247, 112, 199, 181, 1, 197, 164, 199, 181, - 1, 231, 54, 199, 181, 1, 228, 130, 199, 181, 1, 199, 44, 199, 181, 1, - 192, 220, 199, 181, 1, 233, 68, 199, 181, 1, 237, 23, 199, 181, 1, 246, - 209, 199, 181, 1, 191, 123, 199, 181, 17, 191, 77, 199, 181, 17, 108, - 199, 181, 17, 109, 199, 181, 17, 139, 199, 181, 17, 137, 199, 181, 17, - 153, 199, 181, 17, 173, 199, 181, 17, 181, 199, 181, 17, 176, 199, 181, - 17, 184, 249, 17, 195, 182, 1, 234, 42, 249, 17, 195, 182, 1, 157, 249, - 17, 195, 182, 1, 205, 63, 249, 17, 195, 182, 1, 233, 68, 249, 17, 195, - 182, 1, 216, 241, 249, 17, 195, 182, 1, 192, 30, 249, 17, 195, 182, 1, - 231, 188, 249, 17, 195, 182, 1, 237, 4, 249, 17, 195, 182, 1, 220, 252, - 249, 17, 195, 182, 1, 222, 174, 249, 17, 195, 182, 1, 228, 93, 249, 17, - 195, 182, 1, 193, 187, 249, 17, 195, 182, 1, 191, 7, 249, 17, 195, 182, - 1, 231, 132, 249, 17, 195, 182, 1, 236, 129, 249, 17, 195, 182, 1, 246, - 250, 249, 17, 195, 182, 1, 196, 19, 249, 17, 195, 182, 1, 159, 249, 17, - 195, 182, 1, 249, 103, 249, 17, 195, 182, 1, 193, 246, 249, 17, 195, 182, - 1, 192, 74, 249, 17, 195, 182, 1, 168, 249, 17, 195, 182, 1, 193, 174, - 249, 17, 195, 182, 1, 65, 249, 17, 195, 182, 1, 74, 249, 17, 195, 182, 1, - 211, 76, 249, 17, 195, 182, 1, 69, 249, 17, 195, 182, 1, 234, 145, 249, - 17, 195, 182, 1, 73, 249, 17, 195, 182, 1, 70, 249, 17, 195, 182, 33, - 136, 198, 74, 249, 17, 195, 182, 33, 131, 198, 74, 249, 17, 195, 182, 33, - 216, 68, 198, 74, 249, 17, 195, 182, 33, 218, 216, 198, 74, 249, 17, 195, - 182, 33, 229, 101, 198, 74, 249, 17, 195, 182, 232, 42, 201, 58, 145, 90, - 18, 221, 243, 145, 90, 18, 221, 239, 145, 90, 18, 221, 131, 145, 90, 18, - 221, 94, 145, 90, 18, 222, 15, 145, 90, 18, 222, 12, 145, 90, 18, 220, - 192, 145, 90, 18, 220, 161, 145, 90, 18, 221, 245, 145, 90, 18, 221, 200, - 145, 90, 18, 222, 74, 145, 90, 18, 222, 71, 145, 90, 18, 221, 16, 145, - 90, 18, 221, 13, 145, 90, 18, 222, 8, 145, 90, 18, 222, 6, 145, 90, 18, - 220, 194, 145, 90, 18, 220, 193, 145, 90, 18, 221, 36, 145, 90, 18, 221, - 1, 145, 90, 18, 221, 133, 145, 90, 18, 221, 132, 145, 90, 18, 222, 90, - 145, 90, 18, 222, 11, 145, 90, 18, 220, 151, 145, 90, 18, 220, 142, 145, - 90, 18, 222, 99, 145, 90, 18, 222, 91, 145, 90, 119, 195, 157, 145, 90, - 119, 212, 172, 145, 90, 119, 219, 232, 145, 90, 119, 229, 225, 145, 90, - 119, 213, 69, 145, 90, 119, 207, 120, 145, 90, 119, 213, 96, 145, 90, - 119, 208, 63, 145, 90, 119, 192, 91, 145, 90, 119, 229, 76, 145, 90, 119, - 217, 6, 145, 90, 119, 243, 83, 145, 90, 119, 214, 151, 145, 90, 119, 229, - 12, 145, 90, 119, 209, 83, 145, 90, 119, 212, 178, 145, 90, 119, 214, - 191, 145, 90, 119, 250, 113, 145, 90, 119, 192, 216, 145, 90, 119, 247, - 28, 145, 90, 87, 242, 225, 197, 81, 145, 90, 87, 242, 225, 202, 41, 145, - 90, 87, 242, 225, 221, 218, 145, 90, 87, 242, 225, 221, 174, 145, 90, 87, - 242, 225, 200, 241, 145, 90, 87, 242, 225, 228, 226, 145, 90, 87, 242, - 225, 199, 160, 145, 90, 3, 195, 2, 198, 233, 145, 90, 3, 195, 2, 197, - 152, 246, 241, 145, 90, 3, 242, 225, 243, 72, 145, 90, 3, 195, 2, 199, 5, - 145, 90, 3, 195, 2, 233, 8, 145, 90, 3, 192, 171, 212, 166, 145, 90, 3, - 192, 171, 206, 254, 145, 90, 3, 192, 171, 198, 27, 145, 90, 3, 192, 171, - 233, 49, 145, 90, 3, 195, 2, 205, 39, 145, 90, 3, 216, 190, 200, 245, - 145, 90, 3, 195, 2, 212, 218, 145, 90, 3, 228, 1, 192, 111, 145, 90, 3, - 192, 215, 145, 90, 3, 242, 225, 197, 139, 206, 139, 145, 90, 17, 191, 77, - 145, 90, 17, 108, 145, 90, 17, 109, 145, 90, 17, 139, 145, 90, 17, 137, - 145, 90, 17, 153, 145, 90, 17, 173, 145, 90, 17, 181, 145, 90, 17, 176, - 145, 90, 17, 184, 145, 90, 31, 199, 85, 145, 90, 31, 228, 107, 145, 90, - 31, 199, 91, 198, 223, 145, 90, 31, 216, 29, 145, 90, 31, 228, 110, 216, - 29, 145, 90, 31, 199, 91, 248, 121, 145, 90, 31, 197, 223, 145, 90, 3, - 195, 2, 218, 198, 145, 90, 3, 192, 168, 145, 90, 3, 229, 71, 145, 90, 3, - 198, 250, 229, 71, 145, 90, 3, 190, 236, 199, 38, 145, 90, 3, 228, 252, - 145, 90, 3, 212, 232, 145, 90, 3, 192, 206, 145, 90, 3, 212, 170, 145, - 90, 3, 250, 96, 145, 90, 3, 197, 3, 246, 240, 145, 90, 3, 216, 190, 197, - 155, 145, 90, 3, 199, 161, 145, 90, 3, 218, 229, 145, 90, 3, 215, 89, - 145, 90, 3, 242, 225, 230, 43, 218, 175, 212, 176, 212, 175, 145, 90, 3, - 242, 225, 238, 147, 197, 146, 145, 90, 3, 242, 225, 197, 1, 145, 90, 3, - 242, 225, 197, 2, 242, 244, 145, 90, 3, 242, 225, 208, 152, 237, 161, - 145, 90, 3, 242, 225, 212, 225, 198, 36, 145, 90, 242, 196, 3, 197, 150, - 145, 90, 242, 196, 3, 192, 76, 145, 90, 242, 196, 3, 219, 66, 145, 90, - 242, 196, 3, 219, 230, 145, 90, 242, 196, 3, 192, 167, 145, 90, 242, 196, - 3, 221, 17, 145, 90, 242, 196, 3, 229, 222, 145, 90, 242, 196, 3, 215, - 131, 145, 90, 242, 196, 3, 198, 234, 145, 90, 242, 196, 3, 197, 161, 145, - 90, 242, 196, 3, 209, 216, 145, 90, 242, 196, 3, 221, 188, 145, 90, 242, - 196, 3, 230, 31, 145, 90, 242, 196, 3, 195, 179, 145, 90, 242, 196, 3, - 233, 45, 145, 90, 242, 196, 3, 192, 118, 145, 90, 242, 196, 3, 197, 133, - 145, 90, 242, 196, 3, 220, 146, 145, 90, 242, 196, 3, 193, 234, 216, 199, - 6, 1, 218, 147, 216, 199, 6, 1, 206, 3, 216, 199, 6, 1, 196, 8, 216, 199, - 6, 1, 193, 221, 216, 199, 6, 1, 250, 126, 216, 199, 6, 1, 191, 166, 216, - 199, 6, 1, 220, 254, 216, 199, 6, 1, 210, 226, 216, 199, 6, 1, 200, 39, - 216, 199, 6, 1, 232, 14, 216, 199, 6, 1, 233, 134, 216, 199, 6, 1, 70, - 216, 199, 6, 1, 222, 125, 216, 199, 6, 1, 65, 216, 199, 6, 1, 223, 7, - 216, 199, 6, 1, 73, 216, 199, 6, 1, 250, 70, 216, 199, 6, 1, 247, 145, - 216, 199, 6, 1, 69, 216, 199, 6, 1, 191, 225, 216, 199, 6, 1, 170, 216, - 199, 6, 1, 208, 97, 216, 199, 6, 1, 228, 138, 216, 199, 6, 1, 212, 90, - 216, 199, 6, 1, 192, 235, 216, 199, 6, 1, 238, 80, 216, 199, 6, 1, 211, - 139, 216, 199, 6, 1, 215, 47, 216, 199, 6, 1, 148, 216, 199, 6, 1, 74, - 216, 199, 6, 1, 251, 184, 216, 199, 6, 1, 192, 159, 216, 199, 2, 1, 218, - 147, 216, 199, 2, 1, 206, 3, 216, 199, 2, 1, 196, 8, 216, 199, 2, 1, 193, - 221, 216, 199, 2, 1, 250, 126, 216, 199, 2, 1, 191, 166, 216, 199, 2, 1, - 220, 254, 216, 199, 2, 1, 210, 226, 216, 199, 2, 1, 200, 39, 216, 199, 2, - 1, 232, 14, 216, 199, 2, 1, 233, 134, 216, 199, 2, 1, 70, 216, 199, 2, 1, - 222, 125, 216, 199, 2, 1, 65, 216, 199, 2, 1, 223, 7, 216, 199, 2, 1, 73, - 216, 199, 2, 1, 250, 70, 216, 199, 2, 1, 247, 145, 216, 199, 2, 1, 69, - 216, 199, 2, 1, 191, 225, 216, 199, 2, 1, 170, 216, 199, 2, 1, 208, 97, - 216, 199, 2, 1, 228, 138, 216, 199, 2, 1, 212, 90, 216, 199, 2, 1, 192, - 235, 216, 199, 2, 1, 238, 80, 216, 199, 2, 1, 211, 139, 216, 199, 2, 1, - 215, 47, 216, 199, 2, 1, 148, 216, 199, 2, 1, 74, 216, 199, 2, 1, 251, - 184, 216, 199, 2, 1, 192, 159, 216, 199, 17, 191, 77, 216, 199, 17, 108, - 216, 199, 17, 109, 216, 199, 17, 139, 216, 199, 17, 137, 216, 199, 17, - 153, 216, 199, 17, 173, 216, 199, 17, 181, 216, 199, 17, 176, 216, 199, - 17, 184, 216, 199, 31, 199, 90, 216, 199, 31, 234, 84, 216, 199, 31, 197, - 33, 216, 199, 31, 198, 246, 216, 199, 31, 232, 84, 216, 199, 31, 232, - 234, 216, 199, 31, 202, 125, 216, 199, 31, 203, 239, 216, 199, 31, 234, - 118, 216, 199, 31, 213, 158, 216, 199, 17, 91, 251, 106, 20, 216, 199, - 17, 103, 251, 106, 20, 216, 199, 17, 115, 251, 106, 20, 216, 199, 242, - 26, 216, 199, 232, 42, 201, 58, 216, 199, 16, 251, 169, 216, 199, 233, - 175, 211, 124, 120, 1, 168, 120, 1, 249, 103, 120, 1, 11, 168, 120, 1, - 209, 102, 120, 1, 172, 120, 1, 216, 84, 120, 1, 250, 220, 172, 120, 1, - 233, 68, 120, 1, 195, 185, 120, 1, 195, 68, 120, 1, 199, 247, 120, 1, - 237, 241, 120, 1, 11, 197, 128, 120, 1, 11, 199, 247, 120, 1, 197, 128, - 120, 1, 237, 146, 120, 1, 180, 120, 1, 213, 210, 120, 1, 11, 213, 66, - 120, 1, 250, 220, 180, 120, 1, 213, 66, 120, 1, 213, 52, 120, 1, 171, - 120, 1, 218, 161, 120, 1, 219, 135, 120, 1, 219, 124, 120, 1, 198, 107, - 120, 1, 236, 138, 120, 1, 198, 99, 120, 1, 236, 137, 120, 1, 157, 120, 1, - 231, 203, 120, 1, 11, 157, 120, 1, 208, 89, 120, 1, 208, 66, 120, 1, 214, - 54, 120, 1, 214, 3, 120, 1, 250, 220, 214, 54, 120, 1, 144, 120, 1, 192, - 220, 120, 1, 231, 54, 120, 1, 231, 29, 120, 1, 197, 138, 120, 1, 234, - 230, 120, 1, 212, 88, 120, 1, 212, 70, 120, 1, 197, 153, 120, 1, 234, - 241, 120, 1, 11, 197, 153, 120, 1, 11, 234, 241, 120, 1, 207, 77, 197, - 153, 120, 1, 203, 160, 120, 1, 201, 170, 120, 1, 191, 71, 120, 1, 190, - 253, 120, 1, 197, 164, 120, 1, 234, 247, 120, 1, 11, 197, 164, 120, 1, - 189, 120, 1, 191, 123, 120, 1, 190, 254, 120, 1, 190, 224, 120, 1, 190, - 204, 120, 1, 250, 220, 190, 224, 120, 1, 190, 196, 120, 1, 190, 203, 120, - 1, 193, 187, 120, 1, 251, 193, 120, 1, 229, 145, 120, 1, 247, 240, 120, - 1, 200, 121, 120, 1, 234, 231, 120, 1, 199, 140, 120, 1, 197, 157, 120, - 1, 206, 66, 120, 3, 119, 59, 164, 120, 1, 214, 198, 120, 3, 250, 149, - 120, 3, 207, 77, 195, 15, 120, 3, 207, 77, 250, 149, 120, 18, 3, 65, 120, - 18, 3, 252, 154, 120, 18, 3, 251, 189, 120, 18, 3, 251, 81, 120, 18, 3, - 251, 71, 120, 18, 3, 74, 120, 18, 3, 211, 76, 120, 18, 3, 193, 48, 120, - 18, 3, 193, 221, 120, 18, 3, 73, 120, 18, 3, 234, 61, 120, 18, 3, 234, - 46, 120, 18, 3, 211, 135, 120, 18, 3, 70, 120, 18, 3, 228, 5, 120, 18, 3, - 228, 4, 120, 18, 3, 228, 3, 120, 18, 3, 223, 60, 120, 18, 3, 223, 197, - 120, 18, 3, 223, 170, 120, 18, 3, 223, 21, 120, 18, 3, 223, 108, 120, 18, - 3, 69, 120, 18, 3, 196, 164, 120, 18, 3, 196, 163, 120, 18, 3, 196, 162, - 120, 18, 3, 196, 26, 120, 18, 3, 196, 144, 120, 18, 3, 196, 93, 120, 18, - 3, 192, 159, 120, 18, 3, 192, 33, 120, 18, 3, 251, 229, 120, 18, 3, 251, - 225, 120, 18, 3, 233, 240, 120, 18, 3, 206, 108, 233, 240, 120, 18, 3, - 233, 248, 120, 18, 3, 206, 108, 233, 248, 120, 18, 3, 251, 184, 120, 18, - 3, 234, 123, 120, 18, 3, 250, 113, 120, 18, 3, 211, 9, 120, 18, 3, 215, - 47, 120, 18, 3, 214, 56, 120, 18, 3, 196, 77, 120, 18, 3, 191, 205, 120, - 18, 3, 211, 129, 120, 18, 3, 211, 136, 120, 18, 3, 193, 236, 120, 18, 3, - 223, 175, 120, 18, 3, 234, 173, 120, 18, 3, 223, 58, 120, 18, 3, 196, - 135, 120, 163, 187, 120, 163, 198, 49, 187, 120, 163, 56, 120, 163, 60, - 120, 1, 198, 72, 120, 1, 198, 71, 120, 1, 198, 70, 120, 1, 198, 69, 120, - 1, 198, 68, 120, 1, 198, 67, 120, 1, 198, 66, 120, 1, 207, 77, 198, 73, - 120, 1, 207, 77, 198, 72, 120, 1, 207, 77, 198, 70, 120, 1, 207, 77, 198, - 69, 120, 1, 207, 77, 198, 68, 120, 1, 207, 77, 198, 66, 19, 223, 23, 77, - 46, 223, 23, 77, 38, 243, 32, 228, 219, 77, 38, 243, 32, 223, 23, 77, 40, - 2, 27, 232, 218, 195, 54, 251, 106, 207, 102, 87, 247, 112, 195, 54, 251, - 106, 207, 102, 87, 213, 209, 19, 242, 15, 19, 242, 14, 19, 242, 13, 19, - 242, 12, 19, 242, 11, 19, 242, 10, 19, 242, 9, 19, 242, 8, 19, 242, 7, - 19, 242, 6, 19, 242, 5, 19, 242, 4, 19, 242, 3, 19, 242, 2, 19, 242, 1, - 19, 242, 0, 19, 241, 255, 19, 241, 254, 19, 241, 253, 19, 241, 252, 19, - 241, 251, 19, 241, 250, 19, 241, 249, 19, 241, 248, 19, 241, 247, 19, + 7, 254, 14, 29, 7, 254, 13, 29, 7, 254, 12, 29, 7, 254, 11, 29, 7, 254, + 10, 29, 7, 254, 9, 29, 7, 254, 8, 29, 7, 254, 7, 29, 7, 254, 6, 29, 7, + 254, 5, 29, 7, 254, 4, 29, 7, 254, 3, 29, 7, 254, 2, 29, 7, 254, 1, 207, + 186, 211, 57, 207, 1, 29, 7, 254, 0, 29, 7, 253, 255, 29, 7, 253, 254, + 29, 7, 253, 253, 29, 7, 253, 252, 29, 7, 253, 251, 29, 7, 253, 250, 29, + 7, 253, 249, 29, 7, 253, 248, 29, 7, 253, 247, 29, 7, 253, 246, 29, 7, + 253, 245, 171, 29, 7, 253, 244, 29, 7, 253, 243, 29, 7, 253, 242, 29, 7, + 253, 241, 29, 7, 253, 240, 29, 7, 253, 239, 29, 7, 253, 238, 29, 7, 253, + 236, 29, 7, 253, 234, 29, 7, 253, 232, 29, 7, 253, 230, 29, 7, 253, 228, + 29, 7, 253, 226, 29, 7, 253, 224, 29, 7, 253, 222, 29, 7, 253, 220, 29, + 7, 253, 218, 248, 249, 219, 28, 77, 29, 7, 253, 216, 234, 95, 219, 28, + 77, 29, 7, 253, 215, 29, 7, 253, 213, 29, 7, 253, 211, 29, 7, 253, 209, + 29, 7, 253, 207, 29, 7, 253, 205, 29, 7, 253, 203, 29, 7, 253, 201, 29, + 7, 253, 199, 29, 7, 253, 198, 29, 7, 253, 197, 29, 7, 253, 196, 29, 7, + 253, 195, 29, 7, 253, 194, 29, 7, 253, 193, 29, 7, 253, 192, 29, 7, 253, + 191, 29, 7, 253, 190, 29, 7, 253, 189, 29, 7, 253, 188, 29, 7, 253, 187, + 29, 7, 253, 186, 29, 7, 253, 185, 29, 7, 253, 184, 29, 7, 253, 183, 29, + 7, 253, 182, 29, 7, 253, 181, 29, 7, 253, 180, 29, 7, 253, 179, 29, 7, + 253, 178, 29, 7, 253, 177, 29, 7, 253, 176, 29, 7, 253, 175, 29, 7, 253, + 174, 29, 7, 253, 173, 29, 7, 253, 172, 29, 7, 253, 171, 29, 7, 253, 170, + 29, 7, 253, 169, 29, 7, 253, 168, 29, 7, 253, 167, 29, 7, 253, 166, 29, + 7, 253, 165, 29, 7, 253, 164, 29, 7, 253, 163, 29, 7, 253, 162, 29, 7, + 253, 161, 29, 7, 253, 160, 29, 7, 253, 159, 29, 7, 253, 158, 29, 7, 253, + 157, 29, 7, 253, 156, 29, 7, 253, 155, 29, 7, 253, 154, 29, 7, 253, 153, + 29, 7, 253, 152, 29, 7, 253, 151, 29, 7, 253, 150, 29, 7, 253, 149, 29, + 7, 253, 148, 29, 7, 253, 147, 29, 7, 253, 146, 29, 7, 253, 145, 29, 7, + 253, 144, 29, 7, 253, 143, 29, 7, 253, 142, 29, 7, 253, 141, 29, 7, 253, + 140, 29, 7, 253, 139, 29, 7, 253, 138, 29, 7, 253, 137, 29, 7, 253, 136, + 29, 7, 253, 135, 29, 7, 253, 134, 29, 7, 253, 133, 29, 7, 253, 132, 29, + 7, 253, 131, 29, 7, 253, 130, 29, 7, 253, 129, 29, 7, 253, 128, 29, 7, + 253, 127, 29, 7, 253, 126, 29, 7, 253, 125, 29, 7, 253, 124, 29, 7, 253, + 123, 29, 7, 253, 122, 29, 7, 253, 121, 29, 7, 253, 120, 29, 7, 253, 119, + 29, 7, 253, 118, 29, 7, 253, 117, 29, 7, 253, 116, 29, 7, 253, 115, 29, + 7, 253, 114, 29, 7, 253, 113, 29, 7, 253, 112, 29, 7, 253, 111, 29, 7, + 253, 110, 29, 7, 253, 109, 29, 7, 253, 108, 29, 7, 253, 107, 29, 7, 253, + 106, 29, 7, 253, 105, 29, 7, 253, 104, 29, 7, 253, 103, 29, 7, 253, 102, + 29, 7, 253, 101, 29, 7, 253, 100, 29, 7, 253, 99, 29, 7, 253, 98, 29, 7, + 253, 97, 29, 7, 253, 96, 29, 7, 253, 95, 29, 7, 253, 94, 29, 7, 253, 93, + 29, 7, 253, 92, 29, 7, 253, 91, 29, 7, 253, 90, 29, 7, 253, 89, 26, 1, + 209, 218, 214, 1, 216, 142, 26, 1, 209, 218, 231, 173, 232, 166, 26, 1, + 209, 218, 209, 40, 216, 143, 209, 127, 26, 1, 209, 218, 209, 40, 216, + 143, 209, 128, 26, 1, 209, 218, 214, 251, 216, 142, 26, 1, 209, 218, 203, + 0, 26, 1, 209, 218, 198, 124, 216, 142, 26, 1, 209, 218, 212, 47, 216, + 142, 26, 1, 209, 218, 203, 68, 210, 221, 213, 141, 26, 1, 209, 218, 209, + 40, 210, 221, 213, 142, 209, 127, 26, 1, 209, 218, 209, 40, 210, 221, + 213, 142, 209, 128, 26, 1, 209, 218, 217, 131, 26, 1, 209, 218, 197, 95, + 217, 132, 26, 1, 209, 218, 214, 62, 26, 1, 209, 218, 217, 128, 26, 1, + 209, 218, 217, 77, 26, 1, 209, 218, 215, 86, 26, 1, 209, 218, 203, 249, + 26, 1, 209, 218, 212, 187, 26, 1, 209, 218, 221, 234, 26, 1, 209, 218, + 213, 108, 26, 1, 209, 218, 200, 160, 26, 1, 209, 218, 214, 0, 26, 1, 209, + 218, 220, 15, 26, 1, 209, 218, 219, 177, 220, 188, 26, 1, 209, 218, 212, + 197, 216, 150, 26, 1, 209, 218, 217, 135, 26, 1, 209, 218, 210, 98, 26, + 1, 209, 218, 231, 72, 26, 1, 209, 218, 210, 170, 26, 1, 209, 218, 215, + 232, 214, 35, 26, 1, 209, 218, 212, 28, 216, 153, 26, 1, 209, 218, 126, + 191, 195, 214, 244, 26, 1, 209, 218, 231, 73, 26, 1, 209, 218, 212, 197, + 212, 198, 26, 1, 209, 218, 202, 139, 26, 1, 209, 218, 216, 135, 26, 1, + 209, 218, 216, 156, 26, 1, 209, 218, 215, 207, 26, 1, 209, 218, 222, 105, + 26, 1, 209, 218, 210, 221, 219, 225, 26, 1, 209, 218, 214, 163, 219, 225, + 26, 1, 209, 218, 209, 240, 26, 1, 209, 218, 217, 129, 26, 1, 209, 218, + 213, 185, 26, 1, 209, 218, 208, 144, 26, 1, 209, 218, 197, 87, 26, 1, + 209, 218, 218, 221, 26, 1, 209, 218, 202, 17, 26, 1, 209, 218, 199, 58, + 26, 1, 209, 218, 217, 126, 26, 1, 209, 218, 221, 241, 26, 1, 209, 218, + 214, 159, 26, 1, 209, 218, 220, 203, 26, 1, 209, 218, 215, 208, 26, 1, + 209, 218, 202, 252, 26, 1, 209, 218, 219, 20, 26, 1, 209, 218, 232, 239, + 26, 1, 209, 218, 206, 137, 26, 1, 209, 218, 221, 10, 26, 1, 209, 218, + 202, 13, 26, 1, 209, 218, 217, 72, 209, 173, 26, 1, 209, 218, 203, 61, + 26, 1, 209, 218, 212, 196, 26, 1, 209, 218, 203, 42, 212, 208, 191, 203, + 26, 1, 209, 218, 212, 69, 215, 228, 26, 1, 209, 218, 210, 216, 26, 1, + 209, 218, 213, 110, 26, 1, 209, 218, 196, 85, 26, 1, 209, 218, 214, 38, + 26, 1, 209, 218, 217, 125, 26, 1, 209, 218, 213, 153, 26, 1, 209, 218, + 217, 6, 26, 1, 209, 218, 212, 84, 26, 1, 209, 218, 199, 62, 26, 1, 209, + 218, 202, 8, 26, 1, 209, 218, 210, 217, 26, 1, 209, 218, 212, 212, 26, 1, + 209, 218, 217, 133, 26, 1, 209, 218, 212, 81, 26, 1, 209, 218, 222, 66, + 26, 1, 209, 218, 212, 215, 26, 1, 209, 218, 195, 148, 26, 1, 209, 218, + 218, 225, 26, 1, 209, 218, 214, 102, 26, 1, 209, 218, 214, 217, 26, 1, + 209, 218, 217, 5, 26, 1, 209, 217, 212, 210, 26, 1, 209, 217, 197, 95, + 217, 130, 26, 1, 209, 217, 202, 204, 26, 1, 209, 217, 203, 253, 197, 94, + 26, 1, 209, 217, 219, 23, 212, 193, 26, 1, 209, 217, 217, 12, 217, 134, + 26, 1, 209, 217, 221, 150, 26, 1, 209, 217, 192, 43, 26, 1, 209, 217, + 217, 7, 26, 1, 209, 217, 222, 90, 26, 1, 209, 217, 210, 44, 26, 1, 209, + 217, 192, 126, 219, 225, 26, 1, 209, 217, 220, 36, 212, 208, 212, 95, 26, + 1, 209, 217, 212, 190, 203, 87, 26, 1, 209, 217, 214, 130, 213, 156, 26, + 1, 209, 217, 231, 70, 26, 1, 209, 217, 209, 117, 26, 1, 209, 217, 197, + 95, 212, 206, 26, 1, 209, 217, 203, 92, 213, 151, 26, 1, 209, 217, 203, + 88, 26, 1, 209, 217, 216, 143, 199, 61, 26, 1, 209, 217, 216, 250, 217, + 8, 26, 1, 209, 217, 212, 82, 212, 193, 26, 1, 209, 217, 221, 230, 26, 1, + 209, 217, 231, 71, 26, 1, 209, 217, 221, 226, 26, 1, 209, 217, 220, 120, + 26, 1, 209, 217, 210, 101, 26, 1, 209, 217, 195, 77, 26, 1, 209, 217, + 214, 2, 215, 84, 26, 1, 209, 217, 214, 37, 216, 246, 26, 1, 209, 217, + 192, 254, 26, 1, 209, 217, 205, 175, 26, 1, 209, 217, 199, 240, 26, 1, + 209, 217, 216, 155, 26, 1, 209, 217, 214, 21, 26, 1, 209, 217, 214, 22, + 220, 12, 26, 1, 209, 217, 216, 145, 26, 1, 209, 217, 200, 214, 26, 1, + 209, 217, 216, 254, 26, 1, 209, 217, 215, 212, 26, 1, 209, 217, 212, 99, + 26, 1, 209, 217, 208, 148, 26, 1, 209, 217, 216, 154, 214, 39, 26, 1, + 209, 217, 233, 28, 26, 1, 209, 217, 216, 241, 26, 1, 209, 217, 233, 52, + 26, 1, 209, 217, 221, 238, 26, 1, 209, 217, 217, 160, 213, 145, 26, 1, + 209, 217, 217, 160, 213, 121, 26, 1, 209, 217, 219, 176, 26, 1, 209, 217, + 214, 45, 26, 1, 209, 217, 212, 217, 26, 1, 209, 217, 174, 26, 1, 209, + 217, 221, 133, 26, 1, 209, 217, 213, 246, 26, 1, 209, 216, 214, 1, 217, + 132, 26, 1, 209, 216, 212, 46, 26, 1, 209, 216, 191, 203, 26, 1, 209, + 216, 193, 160, 26, 1, 209, 216, 214, 38, 26, 1, 209, 216, 214, 151, 26, + 1, 209, 216, 214, 8, 26, 1, 209, 216, 231, 80, 26, 1, 209, 216, 217, 2, + 26, 1, 209, 216, 231, 180, 26, 1, 209, 216, 212, 71, 216, 21, 216, 157, + 26, 1, 209, 216, 212, 184, 216, 249, 26, 1, 209, 216, 216, 255, 26, 1, + 209, 216, 209, 123, 26, 1, 209, 216, 214, 136, 26, 1, 209, 216, 217, 10, + 247, 156, 26, 1, 209, 216, 221, 228, 26, 1, 209, 216, 231, 81, 26, 1, + 209, 216, 221, 235, 26, 1, 209, 216, 191, 226, 215, 117, 26, 1, 209, 216, + 212, 40, 26, 1, 209, 216, 216, 243, 26, 1, 209, 216, 212, 216, 26, 1, + 209, 216, 216, 249, 26, 1, 209, 216, 192, 44, 26, 1, 209, 216, 221, 18, + 26, 1, 209, 216, 222, 127, 26, 1, 209, 216, 203, 248, 26, 1, 209, 216, + 214, 145, 26, 1, 209, 216, 199, 238, 26, 1, 209, 216, 213, 125, 26, 1, + 209, 216, 198, 124, 191, 207, 26, 1, 209, 216, 200, 247, 26, 1, 209, 216, + 214, 28, 212, 95, 26, 1, 209, 216, 195, 76, 26, 1, 209, 216, 214, 220, + 26, 1, 209, 216, 217, 160, 221, 237, 26, 1, 209, 216, 212, 198, 26, 1, + 209, 216, 214, 23, 26, 1, 209, 216, 220, 16, 26, 1, 209, 216, 216, 251, + 26, 1, 209, 216, 216, 134, 26, 1, 209, 216, 212, 192, 26, 1, 209, 216, + 199, 57, 26, 1, 209, 216, 214, 25, 26, 1, 209, 216, 232, 84, 26, 1, 209, + 216, 214, 150, 26, 1, 209, 216, 212, 218, 26, 1, 209, 216, 212, 214, 26, + 1, 209, 216, 247, 240, 26, 1, 209, 216, 195, 78, 26, 1, 209, 216, 217, 0, + 26, 1, 209, 216, 206, 68, 26, 1, 209, 216, 213, 155, 26, 1, 209, 216, + 220, 35, 26, 1, 209, 216, 198, 121, 26, 1, 209, 216, 212, 200, 213, 246, + 26, 1, 209, 216, 213, 147, 26, 1, 209, 216, 221, 241, 26, 1, 209, 216, + 214, 30, 26, 1, 209, 216, 217, 125, 26, 1, 209, 216, 216, 244, 26, 1, + 209, 216, 218, 225, 26, 1, 209, 216, 220, 188, 26, 1, 209, 216, 213, 153, + 26, 1, 209, 216, 213, 246, 26, 1, 209, 216, 192, 244, 26, 1, 209, 216, + 214, 26, 26, 1, 209, 216, 212, 203, 26, 1, 209, 216, 212, 194, 26, 1, + 209, 216, 220, 205, 213, 110, 26, 1, 209, 216, 212, 201, 26, 1, 209, 216, + 214, 158, 26, 1, 209, 216, 217, 160, 212, 206, 26, 1, 209, 216, 192, 140, + 26, 1, 209, 216, 214, 157, 26, 1, 209, 216, 202, 255, 26, 1, 209, 216, + 203, 251, 26, 1, 209, 216, 216, 252, 26, 1, 209, 216, 217, 132, 26, 1, + 209, 216, 217, 6, 26, 1, 209, 216, 221, 229, 26, 1, 209, 216, 216, 253, + 26, 1, 209, 216, 221, 233, 26, 1, 209, 216, 217, 10, 209, 179, 26, 1, + 209, 216, 191, 186, 26, 1, 209, 216, 213, 143, 26, 1, 209, 216, 216, 80, + 26, 1, 209, 216, 215, 149, 26, 1, 209, 216, 203, 64, 26, 1, 209, 216, + 221, 252, 219, 250, 26, 1, 209, 216, 221, 252, 233, 65, 26, 1, 209, 216, + 214, 60, 26, 1, 209, 216, 214, 217, 26, 1, 209, 216, 219, 94, 26, 1, 209, + 216, 209, 139, 26, 1, 209, 216, 210, 34, 26, 1, 209, 216, 199, 73, 26, 1, + 158, 216, 242, 26, 1, 158, 193, 158, 26, 1, 158, 213, 141, 26, 1, 158, + 216, 142, 26, 1, 158, 213, 139, 26, 1, 158, 219, 139, 26, 1, 158, 213, + 144, 26, 1, 158, 212, 213, 26, 1, 158, 214, 44, 26, 1, 158, 212, 95, 26, + 1, 158, 192, 255, 26, 1, 158, 213, 254, 26, 1, 158, 203, 111, 26, 1, 158, + 214, 9, 26, 1, 158, 221, 236, 26, 1, 158, 199, 59, 26, 1, 158, 203, 90, + 26, 1, 158, 213, 152, 26, 1, 158, 200, 214, 26, 1, 158, 221, 241, 26, 1, + 158, 192, 128, 26, 1, 158, 220, 206, 26, 1, 158, 205, 130, 26, 1, 158, + 216, 147, 26, 1, 158, 214, 149, 26, 1, 158, 217, 95, 26, 1, 158, 216, + 153, 26, 1, 158, 203, 250, 26, 1, 158, 192, 70, 26, 1, 158, 213, 146, 26, + 1, 158, 221, 232, 216, 245, 26, 1, 158, 214, 5, 26, 1, 158, 197, 94, 26, + 1, 158, 231, 90, 26, 1, 158, 213, 251, 26, 1, 158, 233, 29, 26, 1, 158, + 214, 153, 26, 1, 158, 216, 126, 26, 1, 158, 219, 170, 26, 1, 158, 214, + 135, 26, 1, 158, 215, 227, 26, 1, 158, 216, 130, 26, 1, 158, 208, 127, + 26, 1, 158, 216, 128, 26, 1, 158, 216, 144, 26, 1, 158, 218, 208, 26, 1, + 158, 212, 205, 26, 1, 158, 217, 9, 26, 1, 158, 220, 177, 26, 1, 158, 212, + 84, 26, 1, 158, 199, 62, 26, 1, 158, 202, 8, 26, 1, 158, 191, 186, 26, 1, + 158, 221, 233, 26, 1, 158, 207, 162, 26, 1, 158, 199, 120, 26, 1, 158, + 214, 6, 26, 1, 158, 216, 149, 26, 1, 158, 212, 204, 26, 1, 158, 221, 231, + 26, 1, 158, 209, 129, 26, 1, 158, 209, 233, 26, 1, 158, 212, 57, 26, 1, + 158, 219, 176, 26, 1, 158, 214, 45, 26, 1, 158, 216, 146, 26, 1, 158, + 214, 18, 26, 1, 158, 191, 200, 26, 1, 158, 210, 137, 26, 1, 158, 191, + 199, 26, 1, 158, 214, 158, 26, 1, 158, 212, 193, 26, 1, 158, 200, 249, + 26, 1, 158, 220, 210, 26, 1, 158, 214, 34, 26, 1, 158, 214, 3, 26, 1, + 158, 197, 69, 26, 1, 158, 216, 157, 26, 1, 158, 220, 199, 26, 1, 158, + 212, 202, 26, 1, 158, 199, 60, 26, 1, 158, 217, 127, 26, 1, 158, 214, 43, + 26, 1, 158, 219, 169, 26, 1, 158, 214, 24, 26, 1, 158, 212, 207, 26, 1, + 158, 213, 125, 26, 1, 158, 231, 74, 26, 1, 158, 220, 232, 26, 1, 158, + 207, 56, 211, 119, 26, 1, 158, 199, 226, 26, 1, 158, 198, 50, 26, 1, 158, + 212, 81, 26, 1, 158, 206, 195, 26, 1, 158, 219, 227, 26, 1, 158, 216, + 210, 26, 1, 158, 218, 168, 26, 1, 158, 200, 160, 26, 1, 158, 215, 155, + 26, 1, 158, 203, 76, 26, 1, 158, 203, 86, 26, 1, 158, 220, 149, 26, 1, + 158, 212, 178, 26, 1, 158, 203, 5, 26, 1, 158, 212, 195, 26, 1, 158, 210, + 49, 26, 1, 158, 213, 219, 26, 1, 158, 203, 41, 26, 1, 158, 208, 143, 26, + 1, 158, 215, 84, 26, 1, 158, 219, 0, 26, 1, 158, 207, 56, 215, 144, 26, + 1, 158, 198, 193, 26, 1, 158, 212, 181, 26, 1, 158, 217, 10, 175, 26, 1, + 158, 205, 128, 26, 1, 158, 233, 108, 26, 1, 114, 214, 157, 26, 1, 114, + 198, 57, 26, 1, 114, 216, 255, 26, 1, 114, 220, 16, 26, 1, 114, 195, 10, + 26, 1, 114, 219, 6, 26, 1, 114, 210, 220, 26, 1, 114, 202, 21, 26, 1, + 114, 207, 134, 26, 1, 114, 212, 209, 26, 1, 114, 214, 128, 26, 1, 114, + 208, 161, 26, 1, 114, 199, 197, 26, 1, 114, 214, 11, 26, 1, 114, 221, 14, + 26, 1, 114, 192, 247, 26, 1, 114, 205, 50, 26, 1, 114, 214, 35, 26, 1, + 114, 210, 217, 26, 1, 114, 198, 59, 26, 1, 114, 220, 204, 26, 1, 114, + 219, 22, 26, 1, 114, 212, 212, 26, 1, 114, 213, 243, 26, 1, 114, 217, + 133, 26, 1, 114, 214, 4, 26, 1, 114, 213, 242, 26, 1, 114, 212, 211, 26, + 1, 114, 206, 192, 26, 1, 114, 213, 143, 26, 1, 114, 210, 46, 26, 1, 114, + 205, 197, 26, 1, 114, 214, 19, 26, 1, 114, 216, 136, 26, 1, 114, 231, 68, + 26, 1, 114, 214, 7, 26, 1, 114, 213, 154, 26, 1, 114, 217, 71, 26, 1, + 114, 219, 2, 26, 1, 114, 214, 40, 26, 1, 114, 214, 141, 26, 1, 114, 199, + 225, 212, 193, 26, 1, 114, 203, 252, 26, 1, 114, 208, 154, 26, 1, 114, + 214, 161, 202, 30, 26, 1, 114, 214, 27, 212, 95, 26, 1, 114, 192, 29, 26, + 1, 114, 231, 69, 26, 1, 114, 197, 88, 26, 1, 114, 192, 47, 26, 1, 114, + 209, 73, 26, 1, 114, 197, 75, 26, 1, 114, 221, 239, 26, 1, 114, 200, 248, + 26, 1, 114, 199, 61, 26, 1, 114, 195, 79, 26, 1, 114, 193, 100, 26, 1, + 114, 220, 123, 26, 1, 114, 208, 165, 26, 1, 114, 199, 239, 26, 1, 114, + 231, 89, 26, 1, 114, 214, 50, 26, 1, 114, 203, 89, 26, 1, 114, 216, 131, + 26, 1, 114, 217, 3, 26, 1, 114, 212, 44, 26, 1, 114, 213, 106, 26, 1, + 114, 231, 176, 26, 1, 114, 197, 76, 26, 1, 114, 220, 215, 26, 1, 114, + 192, 104, 26, 1, 114, 212, 82, 242, 237, 26, 1, 114, 192, 18, 26, 1, 114, + 216, 148, 26, 1, 114, 214, 146, 26, 1, 114, 209, 174, 26, 1, 114, 191, + 206, 26, 1, 114, 219, 171, 26, 1, 114, 232, 84, 26, 1, 114, 231, 175, 26, + 1, 114, 213, 253, 26, 1, 114, 221, 241, 26, 1, 114, 217, 136, 26, 1, 114, + 214, 10, 26, 1, 114, 231, 75, 26, 1, 114, 233, 109, 26, 1, 114, 212, 182, + 26, 1, 114, 209, 234, 26, 1, 114, 192, 45, 26, 1, 114, 214, 36, 26, 1, + 114, 212, 82, 248, 209, 26, 1, 114, 212, 24, 26, 1, 114, 209, 35, 26, 1, + 114, 216, 80, 26, 1, 114, 232, 82, 26, 1, 114, 214, 244, 26, 1, 114, 215, + 149, 26, 1, 114, 231, 74, 26, 1, 114, 232, 87, 68, 26, 1, 114, 215, 85, + 26, 1, 114, 208, 160, 26, 1, 114, 213, 255, 26, 1, 114, 220, 188, 26, 1, + 114, 209, 171, 26, 1, 114, 212, 196, 26, 1, 114, 192, 46, 26, 1, 114, + 214, 20, 26, 1, 114, 210, 221, 210, 19, 26, 1, 114, 232, 87, 247, 138, + 26, 1, 114, 232, 167, 26, 1, 114, 213, 148, 26, 1, 114, 65, 26, 1, 114, + 198, 50, 26, 1, 114, 74, 26, 1, 114, 68, 26, 1, 114, 220, 14, 26, 1, 114, + 210, 221, 209, 82, 26, 1, 114, 199, 245, 26, 1, 114, 199, 180, 26, 1, + 114, 214, 161, 215, 71, 228, 172, 26, 1, 114, 203, 64, 26, 1, 114, 192, + 42, 26, 1, 114, 213, 236, 26, 1, 114, 191, 211, 26, 1, 114, 191, 244, + 200, 136, 26, 1, 114, 191, 244, 238, 242, 26, 1, 114, 191, 194, 26, 1, + 114, 191, 202, 26, 1, 114, 221, 227, 26, 1, 114, 209, 232, 26, 1, 114, + 213, 149, 234, 49, 26, 1, 114, 208, 156, 26, 1, 114, 192, 253, 26, 1, + 114, 233, 52, 26, 1, 114, 195, 148, 26, 1, 114, 218, 225, 26, 1, 114, + 216, 100, 26, 1, 114, 207, 20, 26, 1, 114, 207, 163, 26, 1, 114, 213, + 235, 26, 1, 114, 214, 68, 26, 1, 114, 203, 56, 26, 1, 114, 203, 41, 26, + 1, 114, 232, 87, 207, 59, 26, 1, 114, 180, 26, 1, 114, 209, 185, 26, 1, + 114, 219, 0, 26, 1, 114, 221, 67, 26, 1, 114, 216, 186, 26, 1, 114, 174, + 26, 1, 114, 217, 68, 26, 1, 114, 199, 63, 26, 1, 114, 221, 166, 26, 1, + 114, 215, 231, 26, 1, 114, 199, 95, 26, 1, 114, 233, 76, 26, 1, 114, 231, + 62, 26, 1, 209, 215, 155, 26, 1, 209, 215, 66, 26, 1, 209, 215, 220, 232, + 26, 1, 209, 215, 234, 188, 26, 1, 209, 215, 207, 84, 26, 1, 209, 215, + 199, 226, 26, 1, 209, 215, 212, 81, 26, 1, 209, 215, 173, 26, 1, 209, + 215, 206, 195, 26, 1, 209, 215, 206, 242, 26, 1, 209, 215, 216, 210, 26, + 1, 209, 215, 199, 245, 26, 1, 209, 215, 214, 160, 26, 1, 209, 215, 213, + 155, 26, 1, 209, 215, 218, 168, 26, 1, 209, 215, 200, 160, 26, 1, 209, + 215, 203, 76, 26, 1, 209, 215, 202, 222, 26, 1, 209, 215, 203, 248, 26, + 1, 209, 215, 220, 149, 26, 1, 209, 215, 221, 241, 26, 1, 209, 215, 212, + 146, 26, 1, 209, 215, 212, 178, 26, 1, 209, 215, 213, 126, 26, 1, 209, + 215, 191, 243, 26, 1, 209, 215, 203, 5, 26, 1, 209, 215, 170, 26, 1, 209, + 215, 212, 215, 26, 1, 209, 215, 209, 232, 26, 1, 209, 215, 212, 195, 26, + 1, 209, 215, 192, 253, 26, 1, 209, 215, 210, 49, 26, 1, 209, 215, 206, + 68, 26, 1, 209, 215, 213, 219, 26, 1, 209, 215, 207, 20, 26, 1, 209, 215, + 221, 251, 26, 1, 209, 215, 213, 252, 26, 1, 209, 215, 214, 47, 26, 1, + 209, 215, 203, 56, 26, 1, 209, 215, 208, 161, 26, 1, 209, 215, 232, 167, + 26, 1, 209, 215, 193, 190, 26, 1, 209, 215, 219, 146, 26, 1, 209, 215, + 219, 0, 26, 1, 209, 215, 221, 67, 26, 1, 209, 215, 217, 1, 26, 1, 209, + 215, 207, 55, 26, 1, 209, 215, 174, 26, 1, 209, 215, 216, 12, 26, 1, 209, + 215, 217, 9, 26, 1, 209, 215, 199, 73, 26, 1, 209, 215, 221, 21, 26, 1, + 209, 215, 205, 150, 26, 1, 209, 215, 193, 248, 215, 159, 1, 190, 190, + 215, 159, 1, 214, 16, 215, 159, 1, 192, 12, 215, 159, 1, 216, 46, 215, + 159, 1, 249, 153, 215, 159, 1, 238, 32, 215, 159, 1, 65, 215, 159, 1, + 209, 211, 215, 159, 1, 221, 209, 215, 159, 1, 230, 22, 215, 159, 1, 238, + 7, 215, 159, 1, 243, 48, 215, 159, 1, 222, 15, 215, 159, 1, 211, 120, + 215, 159, 1, 217, 133, 215, 159, 1, 213, 179, 215, 159, 1, 168, 215, 159, + 1, 211, 87, 215, 159, 1, 74, 215, 159, 1, 206, 162, 215, 159, 1, 203, 81, + 215, 159, 1, 199, 32, 215, 159, 1, 234, 217, 215, 159, 1, 193, 190, 215, + 159, 1, 71, 215, 159, 1, 221, 67, 215, 159, 1, 220, 24, 215, 159, 1, 173, + 215, 159, 1, 230, 80, 215, 159, 1, 207, 1, 215, 159, 1, 199, 110, 215, + 159, 17, 191, 77, 215, 159, 17, 107, 215, 159, 17, 109, 215, 159, 17, + 138, 215, 159, 17, 134, 215, 159, 17, 149, 215, 159, 17, 169, 215, 159, + 17, 175, 215, 159, 17, 171, 215, 159, 17, 178, 215, 159, 237, 238, 215, + 159, 55, 237, 238, 199, 186, 1, 210, 238, 199, 186, 1, 211, 166, 199, + 186, 1, 211, 58, 199, 186, 1, 210, 247, 199, 186, 1, 250, 123, 199, 186, + 1, 252, 63, 199, 186, 1, 251, 37, 199, 186, 1, 250, 133, 199, 186, 1, + 193, 227, 199, 186, 1, 195, 155, 199, 186, 1, 194, 255, 199, 186, 1, 193, + 236, 199, 186, 1, 233, 182, 199, 186, 1, 234, 197, 199, 186, 1, 234, 46, + 199, 186, 1, 233, 221, 199, 186, 1, 223, 41, 199, 186, 1, 228, 28, 199, + 186, 1, 223, 79, 199, 186, 1, 223, 45, 199, 186, 1, 196, 18, 199, 186, 1, + 196, 160, 199, 186, 1, 196, 64, 199, 186, 1, 196, 22, 199, 186, 1, 250, + 134, 199, 186, 1, 250, 138, 199, 186, 1, 250, 136, 199, 186, 1, 250, 135, + 199, 186, 1, 196, 129, 199, 186, 1, 196, 138, 199, 186, 1, 196, 135, 199, + 186, 1, 196, 130, 199, 186, 1, 53, 214, 70, 199, 186, 1, 179, 196, 145, + 199, 186, 1, 203, 40, 196, 143, 199, 186, 1, 203, 40, 250, 135, 199, 186, + 1, 196, 150, 199, 186, 1, 196, 143, 199, 186, 1, 196, 146, 199, 186, 1, + 196, 145, 199, 186, 1, 196, 131, 199, 186, 1, 196, 134, 199, 186, 1, 196, + 133, 199, 186, 1, 196, 132, 199, 186, 1, 215, 63, 199, 186, 1, 216, 238, + 199, 186, 1, 215, 165, 199, 186, 1, 215, 72, 199, 186, 1, 155, 199, 186, + 1, 221, 215, 199, 186, 1, 231, 240, 199, 186, 1, 214, 68, 199, 186, 1, + 188, 199, 186, 1, 170, 199, 186, 1, 193, 190, 199, 186, 1, 168, 199, 186, + 1, 212, 101, 199, 186, 1, 209, 228, 199, 186, 1, 249, 153, 199, 186, 1, + 174, 199, 186, 1, 180, 199, 186, 1, 140, 199, 186, 1, 173, 199, 186, 1, + 228, 164, 199, 186, 1, 190, 190, 199, 186, 1, 238, 32, 199, 186, 1, 165, + 199, 186, 1, 213, 224, 199, 186, 1, 203, 165, 199, 186, 1, 247, 160, 199, + 186, 1, 197, 168, 199, 186, 1, 231, 91, 199, 186, 1, 228, 161, 199, 186, + 1, 199, 49, 199, 186, 1, 192, 220, 199, 186, 1, 233, 109, 199, 186, 1, + 237, 68, 199, 186, 1, 247, 1, 199, 186, 1, 191, 123, 199, 186, 17, 191, + 77, 199, 186, 17, 107, 199, 186, 17, 109, 199, 186, 17, 138, 199, 186, + 17, 134, 199, 186, 17, 149, 199, 186, 17, 169, 199, 186, 17, 175, 199, + 186, 17, 171, 199, 186, 17, 178, 249, 67, 195, 185, 1, 234, 84, 249, 67, + 195, 185, 1, 155, 249, 67, 195, 185, 1, 205, 68, 249, 67, 195, 185, 1, + 233, 109, 249, 67, 195, 185, 1, 217, 4, 249, 67, 195, 185, 1, 192, 30, + 249, 67, 195, 185, 1, 231, 225, 249, 67, 195, 185, 1, 237, 49, 249, 67, + 195, 185, 1, 221, 20, 249, 67, 195, 185, 1, 222, 201, 249, 67, 195, 185, + 1, 228, 124, 249, 67, 195, 185, 1, 193, 190, 249, 67, 195, 185, 1, 191, + 7, 249, 67, 195, 185, 1, 231, 169, 249, 67, 195, 185, 1, 236, 174, 249, + 67, 195, 185, 1, 247, 42, 249, 67, 195, 185, 1, 196, 23, 249, 67, 195, + 185, 1, 159, 249, 67, 195, 185, 1, 249, 153, 249, 67, 195, 185, 1, 193, + 249, 249, 67, 195, 185, 1, 192, 74, 249, 67, 195, 185, 1, 168, 249, 67, + 195, 185, 1, 193, 177, 249, 67, 195, 185, 1, 65, 249, 67, 195, 185, 1, + 74, 249, 67, 195, 185, 1, 211, 87, 249, 67, 195, 185, 1, 66, 249, 67, + 195, 185, 1, 234, 188, 249, 67, 195, 185, 1, 71, 249, 67, 195, 185, 1, + 68, 249, 67, 195, 185, 33, 137, 198, 79, 249, 67, 195, 185, 33, 130, 198, + 79, 249, 67, 195, 185, 33, 216, 87, 198, 79, 249, 67, 195, 185, 33, 218, + 238, 198, 79, 249, 67, 195, 185, 33, 229, 133, 198, 79, 249, 67, 195, + 185, 232, 80, 201, 63, 145, 90, 18, 222, 12, 145, 90, 18, 222, 8, 145, + 90, 18, 221, 155, 145, 90, 18, 221, 118, 145, 90, 18, 222, 41, 145, 90, + 18, 222, 38, 145, 90, 18, 220, 216, 145, 90, 18, 220, 185, 145, 90, 18, + 222, 14, 145, 90, 18, 221, 225, 145, 90, 18, 222, 101, 145, 90, 18, 222, + 98, 145, 90, 18, 221, 40, 145, 90, 18, 221, 37, 145, 90, 18, 222, 34, + 145, 90, 18, 222, 31, 145, 90, 18, 220, 218, 145, 90, 18, 220, 217, 145, + 90, 18, 221, 60, 145, 90, 18, 221, 25, 145, 90, 18, 221, 157, 145, 90, + 18, 221, 156, 145, 90, 18, 222, 117, 145, 90, 18, 222, 37, 145, 90, 18, + 220, 175, 145, 90, 18, 220, 166, 145, 90, 18, 222, 126, 145, 90, 18, 222, + 118, 145, 90, 120, 195, 160, 145, 90, 120, 212, 185, 145, 90, 120, 220, + 0, 145, 90, 120, 230, 2, 145, 90, 120, 213, 82, 145, 90, 120, 207, 125, + 145, 90, 120, 213, 109, 145, 90, 120, 208, 69, 145, 90, 120, 192, 91, + 145, 90, 120, 229, 108, 145, 90, 120, 217, 25, 145, 90, 120, 243, 131, + 145, 90, 120, 214, 165, 145, 90, 120, 229, 44, 145, 90, 120, 209, 91, + 145, 90, 120, 212, 191, 145, 90, 120, 214, 205, 145, 90, 120, 250, 163, + 145, 90, 120, 192, 216, 145, 90, 120, 247, 76, 145, 90, 87, 243, 17, 197, + 85, 145, 90, 87, 243, 17, 202, 46, 145, 90, 87, 243, 17, 221, 243, 145, + 90, 87, 243, 17, 221, 198, 145, 90, 87, 243, 17, 200, 246, 145, 90, 87, + 243, 17, 229, 2, 145, 90, 87, 243, 17, 199, 165, 145, 90, 3, 195, 5, 198, + 238, 145, 90, 3, 195, 5, 197, 156, 247, 33, 145, 90, 3, 243, 17, 243, + 120, 145, 90, 3, 195, 5, 199, 10, 145, 90, 3, 195, 5, 233, 49, 145, 90, + 3, 192, 171, 212, 179, 145, 90, 3, 192, 171, 207, 3, 145, 90, 3, 192, + 171, 198, 32, 145, 90, 3, 192, 171, 233, 90, 145, 90, 3, 195, 5, 205, 44, + 145, 90, 3, 216, 209, 200, 250, 145, 90, 3, 195, 5, 212, 231, 145, 90, 3, + 228, 31, 192, 111, 145, 90, 3, 192, 215, 145, 90, 3, 243, 17, 197, 143, + 206, 144, 145, 90, 17, 191, 77, 145, 90, 17, 107, 145, 90, 17, 109, 145, + 90, 17, 138, 145, 90, 17, 134, 145, 90, 17, 149, 145, 90, 17, 169, 145, + 90, 17, 175, 145, 90, 17, 171, 145, 90, 17, 178, 145, 90, 31, 199, 90, + 145, 90, 31, 228, 138, 145, 90, 31, 199, 96, 198, 228, 145, 90, 31, 216, + 47, 145, 90, 31, 228, 141, 216, 47, 145, 90, 31, 199, 96, 248, 169, 145, + 90, 31, 197, 227, 145, 90, 3, 195, 5, 218, 220, 145, 90, 3, 192, 168, + 145, 90, 3, 229, 103, 145, 90, 3, 198, 255, 229, 103, 145, 90, 3, 190, + 236, 199, 43, 145, 90, 3, 229, 28, 145, 90, 3, 212, 245, 145, 90, 3, 192, + 206, 145, 90, 3, 212, 183, 145, 90, 3, 250, 146, 145, 90, 3, 197, 7, 247, + 32, 145, 90, 3, 216, 209, 197, 159, 145, 90, 3, 199, 166, 145, 90, 3, + 218, 253, 145, 90, 3, 215, 103, 145, 90, 3, 243, 17, 230, 76, 218, 196, + 212, 189, 212, 188, 145, 90, 3, 243, 17, 238, 194, 197, 150, 145, 90, 3, + 243, 17, 197, 5, 145, 90, 3, 243, 17, 197, 6, 243, 36, 145, 90, 3, 243, + 17, 208, 159, 237, 206, 145, 90, 3, 243, 17, 212, 238, 198, 41, 145, 90, + 242, 244, 3, 197, 154, 145, 90, 242, 244, 3, 192, 76, 145, 90, 242, 244, + 3, 219, 90, 145, 90, 242, 244, 3, 219, 254, 145, 90, 242, 244, 3, 192, + 167, 145, 90, 242, 244, 3, 221, 41, 145, 90, 242, 244, 3, 229, 254, 145, + 90, 242, 244, 3, 215, 147, 145, 90, 242, 244, 3, 198, 239, 145, 90, 242, + 244, 3, 197, 165, 145, 90, 242, 244, 3, 209, 225, 145, 90, 242, 244, 3, + 221, 213, 145, 90, 242, 244, 3, 230, 64, 145, 90, 242, 244, 3, 195, 182, + 145, 90, 242, 244, 3, 233, 86, 145, 90, 242, 244, 3, 192, 118, 145, 90, + 242, 244, 3, 197, 137, 145, 90, 242, 244, 3, 220, 170, 145, 90, 242, 244, + 3, 193, 237, 216, 218, 6, 1, 218, 168, 216, 218, 6, 1, 206, 8, 216, 218, + 6, 1, 196, 12, 216, 218, 6, 1, 193, 224, 216, 218, 6, 1, 250, 176, 216, + 218, 6, 1, 191, 166, 216, 218, 6, 1, 221, 22, 216, 218, 6, 1, 210, 236, + 216, 218, 6, 1, 200, 43, 216, 218, 6, 1, 232, 51, 216, 218, 6, 1, 233, + 175, 216, 218, 6, 1, 68, 216, 218, 6, 1, 222, 152, 216, 218, 6, 1, 65, + 216, 218, 6, 1, 223, 35, 216, 218, 6, 1, 71, 216, 218, 6, 1, 250, 120, + 216, 218, 6, 1, 247, 193, 216, 218, 6, 1, 66, 216, 218, 6, 1, 191, 225, + 216, 218, 6, 1, 172, 216, 218, 6, 1, 208, 104, 216, 218, 6, 1, 228, 169, + 216, 218, 6, 1, 212, 103, 216, 218, 6, 1, 192, 235, 216, 218, 6, 1, 238, + 127, 216, 218, 6, 1, 211, 151, 216, 218, 6, 1, 215, 61, 216, 218, 6, 1, + 146, 216, 218, 6, 1, 74, 216, 218, 6, 1, 251, 236, 216, 218, 6, 1, 192, + 159, 216, 218, 2, 1, 218, 168, 216, 218, 2, 1, 206, 8, 216, 218, 2, 1, + 196, 12, 216, 218, 2, 1, 193, 224, 216, 218, 2, 1, 250, 176, 216, 218, 2, + 1, 191, 166, 216, 218, 2, 1, 221, 22, 216, 218, 2, 1, 210, 236, 216, 218, + 2, 1, 200, 43, 216, 218, 2, 1, 232, 51, 216, 218, 2, 1, 233, 175, 216, + 218, 2, 1, 68, 216, 218, 2, 1, 222, 152, 216, 218, 2, 1, 65, 216, 218, 2, + 1, 223, 35, 216, 218, 2, 1, 71, 216, 218, 2, 1, 250, 120, 216, 218, 2, 1, + 247, 193, 216, 218, 2, 1, 66, 216, 218, 2, 1, 191, 225, 216, 218, 2, 1, + 172, 216, 218, 2, 1, 208, 104, 216, 218, 2, 1, 228, 169, 216, 218, 2, 1, + 212, 103, 216, 218, 2, 1, 192, 235, 216, 218, 2, 1, 238, 127, 216, 218, + 2, 1, 211, 151, 216, 218, 2, 1, 215, 61, 216, 218, 2, 1, 146, 216, 218, + 2, 1, 74, 216, 218, 2, 1, 251, 236, 216, 218, 2, 1, 192, 159, 216, 218, + 17, 191, 77, 216, 218, 17, 107, 216, 218, 17, 109, 216, 218, 17, 138, + 216, 218, 17, 134, 216, 218, 17, 149, 216, 218, 17, 169, 216, 218, 17, + 175, 216, 218, 17, 171, 216, 218, 17, 178, 216, 218, 31, 199, 95, 216, + 218, 31, 234, 127, 216, 218, 31, 197, 37, 216, 218, 31, 198, 251, 216, + 218, 31, 232, 122, 216, 218, 31, 233, 19, 216, 218, 31, 202, 130, 216, + 218, 31, 203, 244, 216, 218, 31, 234, 161, 216, 218, 31, 213, 171, 216, + 218, 17, 91, 251, 157, 20, 216, 218, 17, 105, 251, 157, 20, 216, 218, 17, + 115, 251, 157, 20, 216, 218, 242, 74, 216, 218, 232, 80, 201, 63, 216, + 218, 16, 251, 221, 216, 218, 233, 216, 211, 136, 121, 1, 168, 121, 1, + 249, 153, 121, 1, 11, 168, 121, 1, 209, 110, 121, 1, 174, 121, 1, 216, + 103, 121, 1, 251, 14, 174, 121, 1, 233, 109, 121, 1, 195, 188, 121, 1, + 195, 71, 121, 1, 190, 190, 121, 1, 238, 32, 121, 1, 11, 197, 132, 121, 1, + 11, 190, 190, 121, 1, 197, 132, 121, 1, 237, 191, 121, 1, 180, 121, 1, + 213, 224, 121, 1, 11, 213, 79, 121, 1, 251, 14, 180, 121, 1, 213, 79, + 121, 1, 213, 65, 121, 1, 173, 121, 1, 218, 182, 121, 1, 219, 159, 121, 1, + 219, 148, 121, 1, 198, 112, 121, 1, 236, 183, 121, 1, 198, 104, 121, 1, + 236, 182, 121, 1, 155, 121, 1, 231, 240, 121, 1, 11, 155, 121, 1, 208, + 96, 121, 1, 208, 72, 121, 1, 214, 68, 121, 1, 214, 17, 121, 1, 251, 14, + 214, 68, 121, 1, 140, 121, 1, 192, 220, 121, 1, 231, 91, 121, 1, 231, 66, + 121, 1, 197, 142, 121, 1, 235, 18, 121, 1, 212, 101, 121, 1, 212, 83, + 121, 1, 197, 157, 121, 1, 235, 29, 121, 1, 11, 197, 157, 121, 1, 11, 235, + 29, 121, 1, 207, 82, 197, 157, 121, 1, 203, 165, 121, 1, 201, 175, 121, + 1, 191, 71, 121, 1, 190, 253, 121, 1, 197, 168, 121, 1, 235, 35, 121, 1, + 11, 197, 168, 121, 1, 188, 121, 1, 191, 123, 121, 1, 190, 254, 121, 1, + 190, 224, 121, 1, 190, 204, 121, 1, 251, 14, 190, 224, 121, 1, 190, 196, + 121, 1, 190, 203, 121, 1, 193, 190, 121, 1, 251, 245, 121, 1, 229, 177, + 121, 1, 248, 32, 121, 1, 200, 125, 121, 1, 235, 19, 121, 1, 199, 145, + 121, 1, 197, 161, 121, 1, 206, 71, 121, 3, 120, 52, 164, 121, 1, 214, + 212, 121, 3, 250, 199, 121, 3, 207, 82, 195, 18, 121, 3, 207, 82, 250, + 199, 121, 18, 3, 65, 121, 18, 3, 252, 206, 121, 18, 3, 251, 241, 121, 18, + 3, 251, 132, 121, 18, 3, 251, 122, 121, 18, 3, 74, 121, 18, 3, 211, 87, + 121, 18, 3, 193, 48, 121, 18, 3, 193, 224, 121, 18, 3, 71, 121, 18, 3, + 234, 103, 121, 18, 3, 234, 88, 121, 18, 3, 211, 147, 121, 18, 3, 68, 121, + 18, 3, 228, 35, 121, 18, 3, 228, 34, 121, 18, 3, 228, 33, 121, 18, 3, + 223, 88, 121, 18, 3, 223, 226, 121, 18, 3, 223, 199, 121, 18, 3, 223, 49, + 121, 18, 3, 223, 136, 121, 18, 3, 66, 121, 18, 3, 196, 168, 121, 18, 3, + 196, 167, 121, 18, 3, 196, 166, 121, 18, 3, 196, 30, 121, 18, 3, 196, + 148, 121, 18, 3, 196, 97, 121, 18, 3, 192, 159, 121, 18, 3, 192, 33, 121, + 18, 3, 252, 25, 121, 18, 3, 252, 21, 121, 18, 3, 234, 26, 121, 18, 3, + 206, 113, 234, 26, 121, 18, 3, 234, 34, 121, 18, 3, 206, 113, 234, 34, + 121, 18, 3, 251, 236, 121, 18, 3, 234, 166, 121, 18, 3, 250, 163, 121, + 18, 3, 211, 19, 121, 18, 3, 215, 61, 121, 18, 3, 214, 70, 121, 18, 3, + 196, 81, 121, 18, 3, 191, 205, 121, 18, 3, 211, 141, 121, 18, 3, 211, + 148, 121, 18, 3, 193, 239, 121, 18, 3, 223, 204, 121, 18, 3, 234, 217, + 121, 18, 3, 223, 86, 121, 18, 3, 196, 139, 121, 163, 183, 121, 163, 198, + 54, 183, 121, 163, 58, 121, 163, 60, 121, 1, 198, 77, 121, 1, 198, 76, + 121, 1, 198, 75, 121, 1, 198, 74, 121, 1, 198, 73, 121, 1, 198, 72, 121, + 1, 198, 71, 121, 1, 207, 82, 198, 78, 121, 1, 207, 82, 198, 77, 121, 1, + 207, 82, 198, 75, 121, 1, 207, 82, 198, 74, 121, 1, 207, 82, 198, 73, + 121, 1, 207, 82, 198, 71, 19, 223, 51, 77, 46, 223, 51, 77, 39, 243, 80, + 228, 251, 77, 39, 243, 80, 223, 51, 77, 41, 2, 27, 233, 3, 195, 57, 251, + 157, 207, 107, 87, 247, 160, 195, 57, 251, 157, 207, 107, 87, 213, 223, + 19, 242, 63, 19, 242, 62, 19, 242, 61, 19, 242, 60, 19, 242, 59, 19, 242, + 58, 19, 242, 57, 19, 242, 56, 19, 242, 55, 19, 242, 54, 19, 242, 53, 19, + 242, 52, 19, 242, 51, 19, 242, 50, 19, 242, 49, 19, 242, 48, 19, 242, 47, + 19, 242, 46, 19, 242, 45, 19, 242, 44, 19, 242, 43, 19, 242, 42, 19, 242, + 41, 19, 242, 40, 19, 242, 39, 19, 242, 38, 19, 242, 37, 19, 242, 36, 19, + 242, 35, 19, 242, 34, 19, 242, 33, 19, 242, 32, 19, 242, 31, 19, 242, 30, + 19, 242, 29, 19, 242, 28, 19, 242, 27, 19, 242, 26, 19, 242, 25, 19, 242, + 24, 19, 242, 23, 19, 242, 22, 19, 242, 21, 19, 242, 20, 19, 242, 19, 19, + 242, 18, 19, 242, 17, 19, 242, 16, 19, 242, 15, 19, 242, 14, 19, 242, 13, + 19, 242, 12, 19, 242, 11, 19, 242, 10, 19, 242, 9, 19, 242, 8, 19, 242, + 7, 19, 242, 6, 19, 242, 5, 19, 242, 4, 19, 242, 3, 19, 242, 2, 19, 242, + 1, 19, 242, 0, 19, 241, 255, 19, 241, 254, 19, 241, 253, 19, 241, 252, + 19, 241, 251, 19, 241, 250, 19, 241, 249, 19, 241, 248, 19, 241, 247, 19, 241, 246, 19, 241, 245, 19, 241, 244, 19, 241, 243, 19, 241, 242, 19, 241, 241, 19, 241, 240, 19, 241, 239, 19, 241, 238, 19, 241, 237, 19, 241, 236, 19, 241, 235, 19, 241, 234, 19, 241, 233, 19, 241, 232, 19, @@ -17519,3030 +17602,3084 @@ static const unsigned char phrasebook[] = { 81, 19, 239, 80, 19, 239, 79, 19, 239, 78, 19, 239, 77, 19, 239, 76, 19, 239, 75, 19, 239, 74, 19, 239, 73, 19, 239, 72, 19, 239, 71, 19, 239, 70, 19, 239, 69, 19, 239, 68, 19, 239, 67, 19, 239, 66, 19, 239, 65, 19, 239, - 64, 19, 239, 63, 19, 239, 62, 19, 239, 61, 19, 239, 60, 19, 239, 59, 19, - 239, 58, 19, 239, 57, 19, 239, 56, 19, 239, 55, 19, 239, 54, 19, 239, 53, - 19, 239, 52, 19, 239, 51, 19, 239, 50, 19, 239, 49, 19, 239, 48, 19, 239, - 47, 19, 239, 46, 19, 239, 45, 19, 239, 44, 19, 239, 43, 19, 239, 42, 19, - 239, 41, 19, 239, 40, 19, 239, 39, 19, 239, 38, 19, 239, 37, 19, 239, 36, - 19, 239, 35, 19, 239, 34, 19, 239, 33, 19, 239, 32, 19, 239, 31, 19, 239, - 30, 19, 239, 29, 19, 239, 28, 19, 239, 27, 19, 239, 26, 19, 239, 25, 19, - 239, 24, 19, 239, 23, 19, 239, 22, 19, 239, 21, 19, 239, 20, 19, 239, 19, - 19, 239, 18, 19, 239, 17, 19, 239, 16, 40, 2, 27, 246, 190, 40, 2, 27, - 246, 189, 40, 2, 27, 246, 188, 40, 2, 27, 246, 187, 40, 2, 27, 246, 186, - 40, 2, 27, 246, 185, 40, 2, 27, 246, 184, 40, 2, 27, 246, 183, 40, 2, 27, - 246, 182, 40, 2, 27, 246, 181, 40, 2, 27, 246, 180, 40, 2, 27, 246, 179, - 40, 2, 27, 246, 178, 40, 2, 27, 246, 177, 40, 2, 27, 246, 176, 40, 2, 27, - 246, 175, 40, 2, 27, 246, 174, 40, 2, 27, 246, 173, 40, 2, 27, 246, 172, - 40, 2, 27, 246, 171, 40, 2, 27, 246, 170, 40, 2, 27, 246, 169, 40, 2, 27, - 246, 168, 40, 2, 27, 246, 167, 40, 2, 27, 246, 166, 40, 2, 27, 246, 165, - 40, 2, 27, 246, 164, 40, 2, 27, 246, 163, 40, 2, 27, 246, 162, 40, 2, 27, - 246, 161, 40, 2, 27, 246, 160, 40, 2, 27, 246, 159, 40, 2, 27, 246, 158, - 40, 2, 27, 246, 157, 40, 2, 27, 246, 156, 40, 2, 27, 246, 155, 40, 2, 27, - 246, 154, 40, 2, 27, 246, 153, 40, 2, 27, 246, 152, 40, 2, 27, 246, 151, - 40, 2, 27, 246, 150, 40, 2, 27, 246, 149, 40, 2, 27, 246, 148, 40, 2, 27, - 246, 147, 40, 2, 27, 246, 146, 40, 2, 27, 246, 145, 40, 2, 27, 246, 144, - 40, 2, 27, 246, 143, 40, 2, 27, 246, 142, 40, 2, 27, 246, 141, 40, 2, 27, - 246, 140, 40, 2, 27, 246, 139, 40, 2, 27, 246, 138, 40, 2, 27, 246, 137, - 40, 2, 27, 246, 136, 40, 2, 27, 246, 135, 40, 2, 27, 246, 134, 40, 2, 27, - 246, 133, 40, 2, 27, 246, 132, 40, 2, 27, 246, 131, 40, 2, 27, 246, 130, - 40, 2, 27, 246, 129, 40, 2, 27, 246, 128, 40, 2, 27, 246, 127, 40, 2, 27, - 246, 126, 40, 2, 27, 246, 125, 40, 2, 27, 246, 124, 40, 2, 27, 246, 123, - 40, 2, 27, 246, 122, 40, 2, 27, 246, 121, 40, 2, 27, 246, 120, 40, 2, 27, - 246, 119, 40, 2, 27, 246, 118, 40, 2, 27, 246, 117, 40, 2, 27, 246, 116, - 40, 2, 27, 246, 115, 40, 2, 27, 246, 114, 40, 2, 27, 246, 113, 40, 2, 27, - 246, 112, 40, 2, 27, 246, 111, 40, 2, 27, 246, 110, 40, 2, 27, 246, 109, - 40, 2, 27, 246, 108, 40, 2, 27, 246, 107, 40, 2, 27, 246, 106, 40, 2, 27, - 246, 105, 40, 2, 27, 246, 104, 40, 2, 27, 246, 103, 40, 2, 27, 246, 102, - 40, 2, 27, 246, 101, 40, 2, 27, 246, 100, 40, 2, 27, 246, 99, 40, 2, 27, - 246, 98, 40, 2, 27, 246, 97, 40, 2, 27, 246, 96, 40, 2, 27, 246, 95, 40, - 2, 27, 246, 94, 40, 2, 27, 246, 93, 40, 2, 27, 246, 92, 40, 2, 27, 246, - 91, 40, 2, 27, 246, 90, 40, 2, 27, 246, 89, 40, 2, 27, 246, 88, 40, 2, - 27, 246, 87, 40, 2, 27, 246, 86, 40, 2, 27, 246, 85, 40, 2, 27, 246, 84, - 40, 2, 27, 246, 83, 40, 2, 27, 246, 82, 40, 2, 27, 246, 81, 40, 2, 27, - 246, 80, 40, 2, 27, 246, 79, 40, 2, 27, 246, 78, 40, 2, 27, 246, 77, 40, - 2, 27, 246, 76, 40, 2, 27, 246, 75, 40, 2, 27, 246, 74, 40, 2, 27, 246, - 73, 40, 2, 27, 246, 72, 40, 2, 27, 246, 71, 40, 2, 27, 246, 70, 40, 2, - 27, 246, 69, 40, 2, 27, 246, 68, 40, 2, 27, 246, 67, 40, 2, 27, 246, 66, - 40, 2, 27, 246, 65, 40, 2, 27, 246, 64, 40, 2, 27, 246, 63, 40, 2, 27, - 246, 62, 40, 2, 27, 246, 61, 40, 2, 27, 246, 60, 40, 2, 27, 246, 59, 40, - 2, 27, 246, 58, 40, 2, 27, 246, 57, 40, 2, 27, 246, 56, 40, 2, 27, 246, - 55, 40, 2, 27, 246, 54, 40, 2, 27, 246, 53, 40, 2, 27, 246, 52, 40, 2, - 27, 246, 51, 40, 2, 27, 246, 50, 40, 2, 27, 246, 49, 40, 2, 27, 246, 48, - 40, 2, 27, 246, 47, 40, 2, 27, 246, 46, 40, 2, 27, 246, 45, 40, 2, 27, - 246, 44, 40, 2, 27, 246, 43, 40, 2, 27, 246, 42, 40, 2, 27, 246, 41, 40, - 2, 27, 246, 40, 40, 2, 27, 246, 39, 40, 2, 27, 246, 38, 40, 2, 27, 246, - 37, 40, 2, 27, 246, 36, 40, 2, 27, 246, 35, 40, 2, 27, 246, 34, 40, 2, - 27, 246, 33, 40, 2, 27, 246, 32, 40, 2, 27, 246, 31, 40, 2, 27, 246, 30, - 40, 2, 27, 246, 29, 40, 2, 27, 246, 28, 40, 2, 27, 246, 27, 40, 2, 27, - 246, 26, 40, 2, 27, 246, 25, 40, 2, 27, 246, 24, 40, 2, 27, 246, 23, 40, - 2, 27, 246, 22, 40, 2, 27, 246, 21, 40, 2, 27, 246, 20, 40, 2, 27, 246, - 19, 40, 2, 27, 246, 18, 40, 2, 27, 246, 17, 40, 2, 27, 246, 16, 40, 2, - 27, 246, 15, 40, 2, 27, 246, 14, 40, 2, 27, 246, 13, 40, 2, 27, 246, 12, - 40, 2, 27, 246, 11, 40, 2, 27, 246, 10, 40, 2, 27, 246, 9, 40, 2, 27, - 246, 8, 40, 2, 27, 246, 7, 40, 2, 27, 246, 6, 40, 2, 27, 246, 5, 40, 2, - 27, 246, 4, 40, 2, 27, 246, 3, 40, 2, 27, 246, 2, 40, 2, 27, 246, 1, 40, - 2, 27, 246, 0, 40, 2, 27, 245, 255, 40, 2, 27, 245, 254, 40, 2, 27, 245, - 253, 40, 2, 27, 245, 252, 40, 2, 27, 245, 251, 40, 2, 27, 245, 250, 40, - 2, 27, 245, 249, 40, 2, 27, 245, 248, 40, 2, 27, 245, 247, 40, 2, 27, - 245, 246, 40, 2, 27, 245, 245, 40, 2, 27, 245, 244, 40, 2, 27, 245, 243, - 40, 2, 27, 245, 242, 40, 2, 27, 245, 241, 40, 2, 27, 245, 240, 40, 2, 27, - 245, 239, 40, 2, 27, 245, 238, 40, 2, 27, 245, 237, 40, 2, 27, 245, 236, - 40, 2, 27, 245, 235, 40, 2, 27, 245, 234, 40, 2, 27, 245, 233, 40, 2, 27, - 245, 232, 40, 2, 27, 245, 231, 40, 2, 27, 245, 230, 40, 2, 27, 245, 229, - 40, 2, 27, 245, 228, 40, 2, 27, 245, 227, 40, 2, 27, 245, 226, 40, 2, 27, - 245, 225, 40, 2, 27, 245, 224, 40, 2, 27, 245, 223, 40, 2, 27, 245, 222, - 40, 2, 27, 245, 221, 40, 2, 27, 245, 220, 40, 2, 27, 245, 219, 40, 2, 27, - 245, 218, 40, 2, 27, 245, 217, 40, 2, 27, 245, 216, 40, 2, 27, 245, 215, - 40, 2, 27, 245, 214, 40, 2, 27, 245, 213, 40, 2, 27, 245, 212, 40, 2, 27, - 245, 211, 40, 2, 27, 245, 210, 40, 2, 27, 245, 209, 40, 2, 27, 245, 208, - 40, 2, 27, 245, 207, 40, 2, 27, 245, 206, 40, 2, 27, 245, 205, 40, 2, 27, - 245, 204, 40, 2, 27, 245, 203, 40, 2, 27, 245, 202, 40, 2, 27, 245, 201, - 40, 2, 27, 245, 200, 40, 2, 27, 245, 199, 40, 2, 27, 245, 198, 40, 2, 27, - 245, 197, 40, 2, 27, 245, 196, 40, 2, 27, 245, 195, 40, 2, 27, 245, 194, - 40, 2, 27, 245, 193, 40, 2, 27, 245, 192, 40, 2, 27, 245, 191, 40, 2, 27, - 245, 190, 40, 2, 27, 245, 189, 40, 2, 27, 245, 188, 40, 2, 27, 245, 187, - 40, 2, 27, 245, 186, 40, 2, 27, 245, 185, 40, 2, 27, 245, 184, 40, 2, 27, - 245, 183, 40, 2, 27, 245, 182, 40, 2, 27, 245, 181, 40, 2, 27, 245, 180, - 40, 2, 27, 245, 179, 40, 2, 27, 245, 178, 40, 2, 27, 245, 177, 40, 2, 27, - 245, 176, 40, 2, 27, 245, 175, 40, 2, 27, 245, 174, 40, 2, 27, 245, 173, - 40, 2, 27, 245, 172, 40, 2, 27, 245, 171, 40, 2, 27, 245, 170, 40, 2, 27, - 245, 169, 40, 2, 27, 245, 168, 40, 2, 27, 245, 167, 40, 2, 27, 245, 166, - 40, 2, 27, 245, 165, 40, 2, 27, 245, 164, 40, 2, 27, 245, 163, 40, 2, 27, - 245, 162, 40, 2, 27, 245, 161, 40, 2, 27, 245, 160, 40, 2, 27, 245, 159, - 40, 2, 27, 245, 158, 40, 2, 27, 245, 157, 40, 2, 27, 245, 156, 40, 2, 27, - 245, 155, 40, 2, 27, 245, 154, 40, 2, 27, 245, 153, 40, 2, 27, 245, 152, - 40, 2, 27, 245, 151, 40, 2, 27, 245, 150, 40, 2, 27, 245, 149, 40, 2, 27, - 245, 148, 40, 2, 27, 245, 147, 40, 2, 27, 245, 146, 40, 2, 27, 245, 145, - 40, 2, 27, 245, 144, 40, 2, 27, 245, 143, 40, 2, 27, 245, 142, 40, 2, 27, - 245, 141, 40, 2, 27, 245, 140, 40, 2, 27, 245, 139, 40, 2, 27, 245, 138, - 40, 2, 27, 245, 137, 40, 2, 27, 245, 136, 40, 2, 27, 245, 135, 40, 2, 27, - 245, 134, 40, 2, 27, 245, 133, 40, 2, 27, 245, 132, 40, 2, 27, 245, 131, - 40, 2, 27, 245, 130, 40, 2, 27, 245, 129, 40, 2, 27, 245, 128, 40, 2, 27, - 245, 127, 40, 2, 27, 245, 126, 40, 2, 27, 245, 125, 40, 2, 27, 245, 124, - 40, 2, 27, 245, 123, 40, 2, 27, 245, 122, 40, 2, 27, 245, 121, 40, 2, 27, - 245, 120, 40, 2, 27, 245, 119, 40, 2, 27, 245, 118, 40, 2, 27, 245, 117, - 40, 2, 27, 245, 116, 40, 2, 27, 245, 115, 40, 2, 27, 245, 114, 40, 2, 27, - 245, 113, 40, 2, 27, 245, 112, 40, 2, 27, 245, 111, 40, 2, 27, 245, 110, - 40, 2, 27, 245, 109, 40, 2, 27, 245, 108, 40, 2, 27, 245, 107, 40, 2, 27, - 245, 106, 40, 2, 27, 245, 105, 40, 2, 27, 245, 104, 40, 2, 27, 245, 103, - 40, 2, 27, 245, 102, 40, 2, 27, 245, 101, 40, 2, 27, 245, 100, 40, 2, 27, - 245, 99, 40, 2, 27, 245, 98, 40, 2, 27, 245, 97, 40, 2, 27, 245, 96, 40, - 2, 27, 245, 95, 40, 2, 27, 245, 94, 40, 2, 27, 245, 93, 40, 2, 27, 245, - 92, 40, 2, 27, 245, 91, 40, 2, 27, 245, 90, 40, 2, 27, 245, 89, 40, 2, - 27, 245, 88, 40, 2, 27, 245, 87, 40, 2, 27, 245, 86, 40, 2, 27, 245, 85, - 40, 2, 27, 245, 84, 40, 2, 27, 245, 83, 40, 2, 27, 245, 82, 40, 2, 27, - 245, 81, 40, 2, 27, 245, 80, 40, 2, 27, 245, 79, 40, 2, 27, 245, 78, 40, - 2, 27, 245, 77, 40, 2, 27, 245, 76, 40, 2, 27, 245, 75, 40, 2, 27, 245, - 74, 40, 2, 27, 245, 73, 40, 2, 27, 245, 72, 40, 2, 27, 245, 71, 40, 2, - 27, 245, 70, 40, 2, 27, 245, 69, 40, 2, 27, 245, 68, 40, 2, 27, 245, 67, - 40, 2, 27, 245, 66, 40, 2, 27, 245, 65, 40, 2, 27, 245, 64, 40, 2, 27, - 245, 63, 40, 2, 27, 245, 62, 40, 2, 27, 245, 61, 40, 2, 27, 245, 60, 40, - 2, 27, 245, 59, 40, 2, 27, 245, 58, 40, 2, 27, 245, 57, 40, 2, 27, 245, - 56, 40, 2, 27, 245, 55, 40, 2, 27, 245, 54, 40, 2, 27, 245, 53, 40, 2, - 27, 245, 52, 40, 2, 27, 245, 51, 40, 2, 27, 245, 50, 40, 2, 27, 245, 49, - 40, 2, 27, 245, 48, 40, 2, 27, 245, 47, 40, 2, 27, 245, 46, 40, 2, 27, - 245, 45, 40, 2, 27, 245, 44, 40, 2, 27, 245, 43, 40, 2, 27, 245, 42, 40, - 2, 27, 245, 41, 40, 2, 27, 245, 40, 40, 2, 27, 245, 39, 40, 2, 27, 245, - 38, 40, 2, 27, 245, 37, 40, 2, 27, 245, 36, 40, 2, 27, 245, 35, 40, 2, - 27, 245, 34, 40, 2, 27, 245, 33, 40, 2, 27, 245, 32, 40, 2, 27, 245, 31, - 40, 2, 27, 245, 30, 40, 2, 27, 245, 29, 40, 2, 27, 245, 28, 40, 2, 27, - 245, 27, 40, 2, 27, 245, 26, 40, 2, 27, 245, 25, 40, 2, 27, 245, 24, 40, - 2, 27, 245, 23, 40, 2, 27, 245, 22, 40, 2, 27, 245, 21, 40, 2, 27, 245, - 20, 40, 2, 27, 245, 19, 40, 2, 27, 245, 18, 40, 2, 27, 245, 17, 40, 2, - 27, 245, 16, 40, 2, 27, 245, 15, 40, 2, 27, 245, 14, 40, 2, 27, 245, 13, - 40, 2, 27, 245, 12, 40, 2, 27, 245, 11, 40, 2, 27, 245, 10, 40, 2, 27, - 245, 9, 40, 2, 27, 245, 8, 40, 2, 27, 245, 7, 40, 2, 27, 245, 6, 40, 2, - 27, 245, 5, 40, 2, 27, 245, 4, 40, 2, 27, 245, 3, 40, 2, 27, 245, 2, 40, - 2, 27, 245, 1, 40, 2, 27, 245, 0, 40, 2, 27, 244, 255, 40, 2, 27, 244, - 254, 40, 2, 27, 244, 253, 40, 2, 27, 244, 252, 40, 2, 27, 244, 251, 40, - 2, 27, 244, 250, 40, 2, 27, 244, 249, 40, 2, 27, 244, 248, 40, 2, 27, - 244, 247, 40, 2, 27, 244, 246, 40, 2, 27, 244, 245, 40, 2, 27, 244, 244, - 40, 2, 27, 244, 243, 40, 2, 27, 244, 242, 40, 2, 27, 244, 241, 40, 2, 27, - 244, 240, 40, 2, 27, 244, 239, 40, 2, 27, 244, 238, 40, 2, 27, 244, 237, - 40, 2, 27, 244, 236, 40, 2, 27, 244, 235, 40, 2, 27, 244, 234, 40, 2, 27, - 244, 233, 71, 1, 216, 19, 198, 72, 71, 1, 216, 19, 198, 71, 71, 1, 216, - 19, 198, 70, 71, 1, 216, 19, 198, 69, 71, 1, 216, 19, 198, 67, 71, 1, - 216, 19, 198, 66, 71, 1, 216, 19, 214, 197, 198, 73, 71, 1, 216, 19, 214, - 197, 198, 72, 71, 1, 216, 19, 214, 197, 198, 71, 71, 1, 216, 19, 214, - 197, 198, 70, 71, 1, 216, 19, 214, 197, 198, 69, 71, 1, 216, 19, 214, - 197, 198, 67, 71, 1, 216, 19, 214, 197, 198, 66, 71, 1, 250, 220, 73, - 229, 88, 1, 250, 220, 192, 80, 61, 1, 255, 154, 61, 1, 255, 153, 61, 1, - 255, 152, 61, 1, 255, 148, 61, 1, 228, 43, 61, 1, 228, 42, 61, 1, 228, - 41, 61, 1, 228, 40, 61, 1, 196, 227, 61, 1, 196, 226, 61, 1, 196, 225, - 61, 1, 196, 224, 61, 1, 196, 223, 61, 1, 234, 225, 61, 1, 234, 224, 61, - 1, 234, 223, 61, 1, 234, 222, 61, 1, 234, 221, 61, 1, 212, 1, 61, 1, 212, - 0, 61, 1, 211, 255, 61, 1, 222, 114, 61, 1, 222, 111, 61, 1, 222, 110, - 61, 1, 222, 109, 61, 1, 222, 108, 61, 1, 222, 107, 61, 1, 222, 106, 61, - 1, 222, 105, 61, 1, 222, 104, 61, 1, 222, 113, 61, 1, 222, 112, 61, 1, - 222, 103, 61, 1, 221, 141, 61, 1, 221, 140, 61, 1, 221, 139, 61, 1, 221, - 138, 61, 1, 221, 137, 61, 1, 221, 136, 61, 1, 221, 135, 61, 1, 221, 134, - 61, 1, 220, 207, 61, 1, 220, 206, 61, 1, 220, 205, 61, 1, 220, 204, 61, - 1, 220, 203, 61, 1, 220, 202, 61, 1, 220, 201, 61, 1, 221, 252, 61, 1, - 221, 251, 61, 1, 221, 250, 61, 1, 221, 249, 61, 1, 221, 248, 61, 1, 221, - 247, 61, 1, 221, 42, 61, 1, 221, 41, 61, 1, 221, 40, 61, 1, 221, 39, 61, - 1, 205, 201, 61, 1, 205, 200, 61, 1, 205, 199, 61, 1, 205, 198, 61, 1, - 205, 197, 61, 1, 205, 196, 61, 1, 205, 195, 61, 1, 205, 194, 61, 1, 202, - 216, 61, 1, 202, 215, 61, 1, 202, 214, 61, 1, 202, 213, 61, 1, 202, 212, - 61, 1, 202, 211, 61, 1, 200, 254, 61, 1, 200, 253, 61, 1, 200, 252, 61, - 1, 200, 251, 61, 1, 200, 250, 61, 1, 200, 249, 61, 1, 200, 248, 61, 1, - 200, 247, 61, 1, 205, 62, 61, 1, 205, 61, 61, 1, 205, 60, 61, 1, 205, 59, - 61, 1, 205, 58, 61, 1, 202, 40, 61, 1, 202, 39, 61, 1, 202, 38, 61, 1, - 202, 37, 61, 1, 202, 36, 61, 1, 202, 35, 61, 1, 202, 34, 61, 1, 199, 246, - 61, 1, 199, 245, 61, 1, 199, 244, 61, 1, 199, 243, 61, 1, 198, 187, 61, - 1, 198, 186, 61, 1, 198, 185, 61, 1, 198, 184, 61, 1, 198, 183, 61, 1, - 198, 182, 61, 1, 198, 181, 61, 1, 197, 89, 61, 1, 197, 88, 61, 1, 197, - 87, 61, 1, 197, 86, 61, 1, 197, 85, 61, 1, 199, 139, 61, 1, 199, 138, 61, - 1, 199, 137, 61, 1, 199, 136, 61, 1, 199, 135, 61, 1, 199, 134, 61, 1, - 199, 133, 61, 1, 199, 132, 61, 1, 199, 131, 61, 1, 198, 93, 61, 1, 198, - 92, 61, 1, 198, 91, 61, 1, 198, 90, 61, 1, 198, 89, 61, 1, 198, 88, 61, - 1, 198, 87, 61, 1, 214, 248, 61, 1, 214, 247, 61, 1, 214, 246, 61, 1, - 214, 245, 61, 1, 214, 244, 61, 1, 214, 243, 61, 1, 214, 242, 61, 1, 214, - 241, 61, 1, 214, 240, 61, 1, 213, 204, 61, 1, 213, 203, 61, 1, 213, 202, - 61, 1, 213, 201, 61, 1, 213, 200, 61, 1, 213, 199, 61, 1, 213, 198, 61, - 1, 213, 197, 61, 1, 212, 164, 61, 1, 212, 163, 61, 1, 212, 162, 61, 1, - 214, 106, 61, 1, 214, 105, 61, 1, 214, 104, 61, 1, 214, 103, 61, 1, 214, - 102, 61, 1, 214, 101, 61, 1, 214, 100, 61, 1, 213, 29, 61, 1, 213, 28, - 61, 1, 213, 27, 61, 1, 213, 26, 61, 1, 213, 25, 61, 1, 230, 71, 61, 1, - 230, 68, 61, 1, 230, 67, 61, 1, 230, 66, 61, 1, 230, 65, 61, 1, 230, 64, - 61, 1, 230, 63, 61, 1, 230, 62, 61, 1, 230, 61, 61, 1, 230, 70, 61, 1, - 230, 69, 61, 1, 229, 125, 61, 1, 229, 124, 61, 1, 229, 123, 61, 1, 229, - 122, 61, 1, 229, 121, 61, 1, 229, 120, 61, 1, 229, 119, 61, 1, 228, 127, - 61, 1, 228, 126, 61, 1, 228, 125, 61, 1, 229, 212, 61, 1, 229, 211, 61, - 1, 229, 210, 61, 1, 229, 209, 61, 1, 229, 208, 61, 1, 229, 207, 61, 1, - 229, 206, 61, 1, 228, 246, 61, 1, 228, 245, 61, 1, 228, 244, 61, 1, 228, - 243, 61, 1, 228, 242, 61, 1, 228, 241, 61, 1, 228, 240, 61, 1, 228, 239, - 61, 1, 217, 138, 61, 1, 217, 137, 61, 1, 217, 136, 61, 1, 217, 135, 61, - 1, 217, 134, 61, 1, 217, 133, 61, 1, 217, 132, 61, 1, 216, 80, 61, 1, - 216, 79, 61, 1, 216, 78, 61, 1, 216, 77, 61, 1, 216, 76, 61, 1, 216, 75, - 61, 1, 216, 74, 61, 1, 215, 138, 61, 1, 215, 137, 61, 1, 215, 136, 61, 1, - 215, 135, 61, 1, 216, 212, 61, 1, 216, 211, 61, 1, 216, 210, 61, 1, 215, - 250, 61, 1, 215, 249, 61, 1, 215, 248, 61, 1, 215, 247, 61, 1, 215, 246, - 61, 1, 215, 245, 61, 1, 192, 148, 61, 1, 192, 147, 61, 1, 192, 146, 61, - 1, 192, 145, 61, 1, 192, 144, 61, 1, 192, 141, 61, 1, 191, 224, 61, 1, - 191, 223, 61, 1, 191, 222, 61, 1, 191, 221, 61, 1, 192, 11, 61, 1, 192, - 10, 61, 1, 192, 9, 61, 1, 192, 8, 61, 1, 192, 7, 61, 1, 192, 6, 61, 1, - 207, 180, 61, 1, 207, 179, 61, 1, 207, 178, 61, 1, 207, 177, 61, 1, 206, - 251, 61, 1, 206, 250, 61, 1, 206, 249, 61, 1, 206, 248, 61, 1, 206, 247, - 61, 1, 206, 246, 61, 1, 206, 245, 61, 1, 206, 62, 61, 1, 206, 61, 61, 1, - 206, 60, 61, 1, 206, 59, 61, 1, 206, 58, 61, 1, 206, 57, 61, 1, 207, 107, - 61, 1, 207, 106, 61, 1, 207, 105, 61, 1, 207, 104, 61, 1, 206, 156, 61, - 1, 206, 155, 61, 1, 206, 154, 61, 1, 206, 153, 61, 1, 206, 152, 61, 1, - 206, 151, 61, 1, 193, 186, 61, 1, 193, 185, 61, 1, 193, 184, 61, 1, 193, - 183, 61, 1, 193, 182, 61, 1, 193, 83, 61, 1, 193, 82, 61, 1, 193, 81, 61, - 1, 193, 80, 61, 1, 193, 79, 61, 1, 193, 122, 61, 1, 193, 121, 61, 1, 193, - 120, 61, 1, 193, 119, 61, 1, 193, 47, 61, 1, 193, 46, 61, 1, 193, 45, 61, - 1, 193, 44, 61, 1, 193, 43, 61, 1, 193, 42, 61, 1, 193, 41, 61, 1, 215, - 44, 61, 1, 215, 43, 229, 88, 1, 250, 220, 193, 0, 71, 1, 250, 220, 192, - 33, 71, 1, 250, 220, 192, 80, 71, 1, 250, 220, 193, 0, 229, 88, 1, 2, - 193, 84, 229, 88, 1, 2, 193, 123, 229, 88, 1, 2, 193, 48, 71, 1, 2, 193, - 84, 71, 1, 2, 193, 123, 71, 1, 2, 193, 48, 71, 1, 2, 215, 47, 46, 244, - 232, 46, 244, 231, 46, 244, 230, 46, 244, 229, 46, 244, 228, 46, 244, - 227, 46, 244, 226, 46, 244, 225, 46, 244, 224, 46, 244, 223, 46, 244, - 222, 46, 244, 221, 46, 244, 220, 46, 244, 219, 46, 244, 218, 46, 244, - 217, 46, 244, 216, 46, 244, 215, 46, 244, 214, 46, 244, 213, 46, 244, - 212, 46, 244, 211, 46, 244, 210, 46, 244, 209, 46, 244, 208, 46, 244, - 207, 46, 244, 206, 46, 244, 205, 46, 244, 204, 46, 244, 203, 46, 244, - 202, 46, 244, 201, 46, 244, 200, 46, 244, 199, 46, 244, 198, 46, 244, - 197, 46, 244, 196, 46, 244, 195, 46, 244, 194, 46, 244, 193, 46, 244, - 192, 46, 244, 191, 46, 244, 190, 46, 244, 189, 46, 244, 188, 46, 244, - 187, 46, 244, 186, 46, 244, 185, 46, 244, 184, 46, 244, 183, 46, 244, - 182, 46, 244, 181, 46, 244, 180, 46, 244, 179, 46, 244, 178, 46, 244, - 177, 46, 244, 176, 46, 244, 175, 46, 244, 174, 46, 244, 173, 46, 244, - 172, 46, 244, 171, 46, 244, 170, 46, 244, 169, 46, 244, 168, 46, 244, - 167, 46, 244, 166, 46, 244, 165, 46, 244, 164, 46, 244, 163, 46, 244, - 162, 46, 244, 161, 46, 244, 160, 46, 244, 159, 46, 244, 158, 46, 244, - 157, 46, 244, 156, 46, 244, 155, 46, 244, 154, 46, 244, 153, 46, 244, - 152, 46, 244, 151, 46, 244, 150, 46, 244, 149, 46, 244, 148, 46, 244, - 147, 46, 244, 146, 46, 244, 145, 46, 244, 144, 46, 244, 143, 46, 244, - 142, 46, 244, 141, 46, 244, 140, 46, 244, 139, 46, 244, 138, 46, 244, - 137, 46, 244, 136, 46, 244, 135, 46, 244, 134, 46, 244, 133, 46, 244, - 132, 46, 244, 131, 46, 244, 130, 46, 244, 129, 46, 244, 128, 46, 244, - 127, 46, 244, 126, 46, 244, 125, 46, 244, 124, 46, 244, 123, 46, 244, - 122, 46, 244, 121, 46, 244, 120, 46, 244, 119, 46, 244, 118, 46, 244, - 117, 46, 244, 116, 46, 244, 115, 46, 244, 114, 46, 244, 113, 46, 244, - 112, 46, 244, 111, 46, 244, 110, 46, 244, 109, 46, 244, 108, 46, 244, - 107, 46, 244, 106, 46, 244, 105, 46, 244, 104, 46, 244, 103, 46, 244, - 102, 46, 244, 101, 46, 244, 100, 46, 244, 99, 46, 244, 98, 46, 244, 97, - 46, 244, 96, 46, 244, 95, 46, 244, 94, 46, 244, 93, 46, 244, 92, 46, 244, - 91, 46, 244, 90, 46, 244, 89, 46, 244, 88, 46, 244, 87, 46, 244, 86, 46, - 244, 85, 46, 244, 84, 46, 244, 83, 46, 244, 82, 46, 244, 81, 46, 244, 80, - 46, 244, 79, 46, 244, 78, 46, 244, 77, 46, 244, 76, 46, 244, 75, 46, 244, - 74, 46, 244, 73, 46, 244, 72, 46, 244, 71, 46, 244, 70, 46, 244, 69, 46, - 244, 68, 46, 244, 67, 46, 244, 66, 46, 244, 65, 46, 244, 64, 46, 244, 63, - 46, 244, 62, 46, 244, 61, 46, 244, 60, 46, 244, 59, 46, 244, 58, 46, 244, - 57, 46, 244, 56, 46, 244, 55, 46, 244, 54, 46, 244, 53, 46, 244, 52, 46, - 244, 51, 46, 244, 50, 46, 244, 49, 46, 244, 48, 46, 244, 47, 46, 244, 46, - 46, 244, 45, 46, 244, 44, 46, 244, 43, 46, 244, 42, 46, 244, 41, 46, 244, - 40, 46, 244, 39, 46, 244, 38, 46, 244, 37, 46, 244, 36, 46, 244, 35, 46, - 244, 34, 46, 244, 33, 46, 244, 32, 46, 244, 31, 46, 244, 30, 46, 244, 29, - 46, 244, 28, 46, 244, 27, 46, 244, 26, 46, 244, 25, 46, 244, 24, 46, 244, - 23, 46, 244, 22, 46, 244, 21, 46, 244, 20, 46, 244, 19, 46, 244, 18, 46, - 244, 17, 46, 244, 16, 46, 244, 15, 46, 244, 14, 46, 244, 13, 46, 244, 12, - 46, 244, 11, 46, 244, 10, 46, 244, 9, 46, 244, 8, 46, 244, 7, 46, 244, 6, - 46, 244, 5, 46, 244, 4, 46, 244, 3, 46, 244, 2, 46, 244, 1, 46, 244, 0, - 46, 243, 255, 46, 243, 254, 46, 243, 253, 46, 243, 252, 46, 243, 251, 46, - 243, 250, 46, 243, 249, 46, 243, 248, 46, 243, 247, 46, 243, 246, 46, - 243, 245, 46, 243, 244, 46, 243, 243, 46, 243, 242, 46, 243, 241, 46, - 243, 240, 46, 243, 239, 46, 243, 238, 46, 243, 237, 46, 243, 236, 46, - 243, 235, 46, 243, 234, 46, 243, 233, 46, 243, 232, 46, 243, 231, 46, - 243, 230, 46, 243, 229, 46, 243, 228, 46, 243, 227, 46, 243, 226, 46, - 243, 225, 46, 243, 224, 46, 243, 223, 46, 243, 222, 46, 243, 221, 46, - 243, 220, 46, 243, 219, 46, 243, 218, 46, 243, 217, 46, 243, 216, 46, - 243, 215, 46, 243, 214, 46, 243, 213, 46, 243, 212, 46, 243, 211, 46, - 243, 210, 46, 243, 209, 46, 243, 208, 46, 243, 207, 46, 243, 206, 46, - 243, 205, 46, 243, 204, 46, 243, 203, 46, 243, 202, 46, 243, 201, 46, - 243, 200, 46, 243, 199, 46, 243, 198, 46, 243, 197, 46, 243, 196, 46, - 243, 195, 46, 243, 194, 46, 243, 193, 46, 243, 192, 46, 243, 191, 46, - 243, 190, 46, 243, 189, 46, 243, 188, 46, 243, 187, 46, 243, 186, 46, - 243, 185, 46, 243, 184, 46, 243, 183, 46, 243, 182, 46, 243, 181, 46, - 243, 180, 46, 243, 179, 46, 243, 178, 46, 243, 177, 46, 243, 176, 46, - 243, 175, 46, 243, 174, 46, 243, 173, 46, 243, 172, 46, 243, 171, 46, - 243, 170, 46, 243, 169, 46, 243, 168, 46, 243, 167, 46, 243, 166, 46, - 243, 165, 46, 243, 164, 46, 243, 163, 46, 243, 162, 46, 243, 161, 46, - 243, 160, 46, 243, 159, 46, 243, 158, 46, 243, 157, 46, 243, 156, 46, - 243, 155, 46, 243, 154, 46, 243, 153, 46, 243, 152, 46, 243, 151, 46, - 243, 150, 46, 243, 149, 46, 243, 148, 46, 243, 147, 46, 243, 146, 46, - 243, 145, 46, 243, 144, 46, 243, 143, 46, 243, 142, 46, 243, 141, 46, - 243, 140, 46, 243, 139, 46, 243, 138, 46, 243, 137, 46, 243, 136, 46, - 243, 135, 46, 243, 134, 46, 243, 133, 46, 243, 132, 46, 243, 131, 46, - 243, 130, 46, 243, 129, 46, 243, 128, 46, 243, 127, 46, 243, 126, 46, - 243, 125, 46, 243, 124, 46, 243, 123, 46, 243, 122, 46, 243, 121, 46, - 243, 120, 46, 243, 119, 46, 243, 118, 46, 243, 117, 46, 243, 116, 46, - 243, 115, 46, 243, 114, 46, 243, 113, 46, 243, 112, 46, 243, 111, 46, - 243, 110, 46, 243, 109, 46, 243, 108, 46, 243, 107, 46, 243, 106, 46, - 243, 105, 46, 243, 104, 46, 243, 103, 46, 243, 102, 46, 243, 101, 46, - 243, 100, 46, 243, 99, 46, 243, 98, 46, 243, 97, 46, 243, 96, 46, 243, - 95, 46, 243, 94, 46, 243, 93, 124, 1, 230, 83, 124, 1, 192, 235, 124, 1, - 210, 226, 124, 1, 200, 39, 124, 1, 233, 134, 124, 1, 222, 125, 124, 1, - 170, 124, 1, 250, 70, 124, 1, 238, 80, 124, 1, 196, 8, 124, 1, 232, 14, - 124, 1, 148, 124, 1, 210, 227, 215, 47, 124, 1, 238, 81, 206, 3, 124, 1, - 233, 135, 215, 47, 124, 1, 222, 126, 218, 147, 124, 1, 207, 217, 206, 3, - 124, 1, 199, 46, 124, 1, 202, 77, 237, 24, 124, 1, 237, 24, 124, 1, 221, - 78, 124, 1, 202, 77, 223, 7, 124, 1, 229, 80, 124, 1, 219, 136, 124, 1, - 207, 2, 124, 1, 218, 147, 124, 1, 215, 47, 124, 1, 223, 7, 124, 1, 206, - 3, 124, 1, 218, 148, 215, 47, 124, 1, 215, 48, 218, 147, 124, 1, 223, 8, - 218, 147, 124, 1, 206, 4, 223, 7, 124, 1, 218, 148, 4, 236, 96, 124, 1, - 215, 48, 4, 236, 96, 124, 1, 223, 8, 4, 236, 96, 124, 1, 223, 8, 4, 183, - 223, 90, 24, 56, 124, 1, 206, 4, 4, 236, 96, 124, 1, 206, 4, 4, 75, 60, - 124, 1, 218, 148, 206, 3, 124, 1, 215, 48, 206, 3, 124, 1, 223, 8, 206, - 3, 124, 1, 206, 4, 206, 3, 124, 1, 218, 148, 215, 48, 206, 3, 124, 1, - 215, 48, 218, 148, 206, 3, 124, 1, 223, 8, 218, 148, 206, 3, 124, 1, 206, - 4, 223, 8, 206, 3, 124, 1, 223, 8, 206, 4, 4, 236, 96, 124, 1, 223, 8, - 215, 47, 124, 1, 223, 8, 215, 48, 206, 3, 124, 1, 206, 4, 200, 39, 124, - 1, 206, 4, 200, 40, 148, 124, 1, 206, 4, 210, 226, 124, 1, 206, 4, 210, - 227, 148, 124, 1, 200, 40, 206, 3, 124, 1, 200, 40, 207, 217, 206, 3, - 124, 1, 193, 221, 124, 1, 193, 95, 124, 1, 193, 222, 148, 124, 1, 206, 4, - 215, 47, 124, 1, 206, 4, 218, 147, 124, 1, 222, 126, 207, 217, 206, 3, - 124, 1, 232, 15, 207, 217, 206, 3, 124, 1, 206, 4, 222, 125, 124, 1, 206, - 4, 222, 126, 148, 124, 1, 65, 124, 1, 202, 77, 210, 240, 124, 1, 211, - 169, 124, 1, 74, 124, 1, 251, 16, 124, 1, 70, 124, 1, 73, 124, 1, 223, - 197, 124, 1, 203, 35, 70, 124, 1, 196, 135, 124, 1, 234, 145, 124, 1, - 202, 77, 234, 130, 124, 1, 206, 130, 70, 124, 1, 202, 77, 234, 145, 124, - 1, 177, 70, 124, 1, 192, 80, 124, 1, 69, 124, 1, 233, 201, 124, 1, 192, - 182, 124, 1, 126, 215, 47, 124, 1, 177, 69, 124, 1, 206, 130, 69, 124, 1, - 196, 137, 124, 1, 202, 77, 69, 124, 1, 211, 73, 124, 1, 210, 240, 124, 1, - 211, 9, 124, 1, 193, 187, 124, 1, 193, 48, 124, 1, 193, 84, 124, 1, 193, - 110, 124, 1, 193, 14, 124, 1, 214, 200, 69, 124, 1, 214, 200, 74, 124, 1, - 214, 200, 70, 124, 1, 214, 200, 65, 124, 1, 209, 247, 251, 81, 124, 1, - 209, 247, 251, 98, 124, 1, 202, 77, 234, 61, 124, 1, 202, 77, 251, 81, - 124, 1, 202, 77, 211, 93, 124, 1, 121, 218, 147, 124, 251, 208, 45, 228, - 209, 205, 53, 124, 251, 208, 216, 68, 228, 209, 205, 53, 124, 251, 208, - 50, 228, 209, 205, 53, 124, 251, 208, 131, 81, 205, 53, 124, 251, 208, - 216, 68, 81, 205, 53, 124, 251, 208, 136, 81, 205, 53, 124, 251, 208, - 250, 120, 205, 53, 124, 251, 208, 250, 120, 219, 191, 205, 53, 124, 251, - 208, 250, 120, 199, 183, 124, 251, 208, 250, 120, 199, 210, 124, 251, - 208, 250, 120, 234, 227, 106, 124, 251, 208, 250, 120, 228, 44, 106, 124, - 251, 208, 250, 120, 199, 184, 106, 124, 251, 208, 136, 251, 250, 124, - 251, 208, 136, 198, 167, 251, 250, 124, 251, 208, 136, 230, 176, 124, - 251, 208, 136, 177, 230, 176, 124, 251, 208, 136, 236, 96, 124, 251, 208, - 136, 242, 218, 124, 251, 208, 136, 219, 88, 124, 251, 208, 136, 193, 136, - 124, 251, 208, 136, 195, 132, 124, 251, 208, 131, 251, 250, 124, 251, - 208, 131, 198, 167, 251, 250, 124, 251, 208, 131, 230, 176, 124, 251, - 208, 131, 177, 230, 176, 124, 251, 208, 131, 236, 96, 124, 251, 208, 131, - 242, 218, 124, 251, 208, 131, 219, 88, 124, 251, 208, 131, 193, 136, 124, - 251, 208, 131, 195, 132, 124, 251, 208, 131, 55, 124, 3, 186, 4, 238, - 170, 124, 199, 4, 1, 205, 29, 124, 54, 77, 124, 208, 145, 243, 30, 232, - 42, 201, 58, 203, 22, 232, 106, 1, 210, 248, 203, 22, 232, 106, 238, 237, - 210, 248, 203, 22, 232, 106, 143, 201, 73, 203, 22, 232, 106, 132, 201, - 73, 97, 33, 87, 230, 206, 213, 146, 206, 4, 220, 227, 211, 94, 219, 200, - 97, 33, 87, 213, 146, 206, 4, 220, 227, 211, 94, 219, 200, 97, 33, 87, - 197, 158, 211, 94, 219, 200, 97, 33, 87, 230, 206, 213, 146, 211, 94, - 219, 200, 97, 33, 87, 213, 146, 211, 94, 219, 200, 97, 33, 87, 201, 174, - 211, 94, 219, 200, 97, 33, 87, 217, 74, 208, 252, 211, 94, 219, 200, 97, - 33, 87, 208, 252, 211, 94, 219, 200, 97, 33, 87, 193, 228, 211, 94, 219, - 200, 97, 33, 87, 217, 74, 208, 252, 206, 4, 221, 157, 211, 94, 219, 200, - 97, 33, 87, 208, 252, 206, 4, 221, 157, 211, 94, 219, 200, 97, 33, 87, - 193, 228, 206, 4, 221, 157, 211, 94, 219, 200, 97, 33, 87, 230, 206, 213, - 146, 206, 4, 220, 227, 211, 94, 187, 97, 33, 87, 213, 146, 206, 4, 220, - 227, 211, 94, 187, 97, 33, 87, 197, 158, 211, 94, 187, 97, 33, 87, 230, - 206, 213, 146, 211, 94, 187, 97, 33, 87, 213, 146, 211, 94, 187, 97, 33, - 87, 201, 174, 211, 94, 187, 97, 33, 87, 217, 74, 208, 252, 211, 94, 187, - 97, 33, 87, 208, 252, 211, 94, 187, 97, 33, 87, 193, 228, 211, 94, 187, - 97, 33, 87, 217, 74, 208, 252, 206, 4, 221, 157, 211, 94, 187, 97, 33, - 87, 208, 252, 206, 4, 221, 157, 211, 94, 187, 97, 33, 87, 193, 228, 206, - 4, 221, 157, 211, 94, 187, 97, 33, 87, 197, 158, 206, 4, 220, 226, 97, - 33, 87, 217, 74, 208, 252, 206, 4, 220, 226, 97, 33, 87, 201, 44, 217, - 74, 208, 251, 97, 33, 87, 208, 252, 206, 4, 220, 226, 97, 33, 87, 208, - 252, 201, 43, 97, 33, 87, 193, 228, 206, 4, 220, 226, 97, 33, 87, 217, - 74, 208, 252, 201, 43, 97, 33, 87, 230, 206, 193, 227, 97, 33, 87, 191, - 83, 97, 33, 87, 211, 93, 97, 33, 87, 207, 119, 97, 33, 87, 198, 152, 97, - 33, 87, 248, 35, 97, 33, 87, 196, 152, 97, 33, 87, 209, 58, 97, 33, 87, - 218, 253, 97, 33, 87, 220, 176, 97, 33, 87, 222, 88, 97, 33, 87, 191, 74, - 97, 33, 87, 202, 100, 97, 33, 87, 207, 112, 97, 33, 87, 220, 229, 211, - 94, 219, 200, 97, 33, 198, 75, 207, 132, 87, 215, 146, 97, 33, 198, 75, - 207, 132, 87, 200, 149, 97, 33, 198, 75, 207, 132, 87, 197, 242, 97, 33, - 87, 191, 120, 97, 33, 87, 237, 60, 191, 120, 97, 33, 87, 211, 15, 97, 33, - 87, 209, 60, 97, 33, 87, 209, 61, 4, 81, 105, 97, 33, 87, 243, 86, 97, - 33, 87, 243, 87, 209, 38, 97, 33, 87, 211, 161, 97, 33, 87, 202, 5, 212, - 236, 97, 33, 87, 198, 84, 97, 33, 87, 235, 4, 97, 33, 250, 119, 81, 211, - 98, 97, 33, 87, 238, 116, 211, 98, 97, 33, 87, 220, 228, 97, 33, 110, - 198, 75, 207, 132, 223, 116, 97, 208, 196, 59, 219, 143, 97, 208, 196, - 59, 219, 142, 97, 208, 196, 59, 236, 188, 232, 155, 97, 208, 196, 59, - 220, 228, 97, 208, 196, 59, 206, 139, 97, 161, 220, 232, 97, 161, 220, - 233, 198, 151, 97, 161, 210, 112, 97, 161, 235, 12, 196, 9, 243, 65, 97, - 161, 221, 66, 97, 161, 191, 105, 97, 161, 201, 56, 97, 161, 201, 57, 206, - 4, 211, 151, 97, 161, 210, 1, 97, 161, 210, 2, 214, 82, 97, 161, 201, 57, - 4, 202, 5, 212, 236, 97, 161, 243, 64, 97, 161, 210, 176, 97, 161, 191, - 103, 97, 161, 230, 212, 248, 34, 97, 161, 230, 212, 198, 151, 97, 161, - 230, 212, 215, 144, 97, 161, 230, 212, 200, 148, 97, 161, 230, 212, 197, - 241, 97, 161, 194, 250, 208, 176, 97, 161, 194, 250, 215, 147, 97, 161, - 194, 250, 200, 150, 97, 161, 194, 250, 197, 243, 97, 161, 194, 250, 221, - 61, 208, 176, 97, 161, 194, 250, 221, 61, 215, 147, 97, 161, 194, 250, - 221, 61, 200, 150, 97, 161, 194, 250, 221, 61, 197, 243, 97, 161, 54, - 191, 103, 97, 161, 207, 13, 243, 64, 97, 161, 237, 46, 97, 161, 221, 182, - 97, 161, 243, 86, 97, 161, 209, 60, 97, 161, 202, 108, 215, 147, 97, 161, - 202, 108, 200, 150, 97, 161, 202, 108, 197, 243, 97, 161, 202, 108, 198, - 152, 97, 161, 237, 60, 221, 66, 97, 161, 202, 108, 221, 61, 200, 150, 97, - 161, 202, 108, 221, 65, 97, 161, 202, 108, 221, 61, 198, 152, 97, 161, - 202, 108, 235, 9, 208, 176, 97, 161, 202, 108, 235, 9, 200, 150, 97, 161, - 202, 108, 235, 9, 214, 82, 97, 161, 202, 108, 235, 9, 221, 60, 97, 161, - 202, 67, 97, 161, 202, 68, 206, 4, 191, 101, 97, 161, 202, 68, 191, 110, - 97, 161, 202, 68, 206, 4, 220, 226, 97, 161, 220, 228, 97, 161, 206, 139, - 97, 161, 232, 187, 97, 161, 221, 35, 97, 161, 191, 8, 97, 161, 201, 85, - 97, 161, 201, 86, 206, 4, 191, 101, 97, 161, 201, 86, 206, 4, 220, 226, - 97, 161, 201, 86, 206, 4, 191, 102, 228, 44, 220, 226, 97, 161, 201, 86, - 206, 4, 220, 227, 228, 44, 191, 101, 97, 161, 201, 86, 191, 111, 97, 161, - 201, 86, 191, 112, 206, 4, 191, 101, 97, 161, 201, 86, 206, 4, 206, 138, - 97, 161, 201, 86, 206, 4, 235, 3, 191, 100, 97, 161, 201, 86, 206, 4, - 191, 102, 228, 44, 209, 59, 97, 161, 209, 40, 97, 161, 201, 86, 214, 82, - 97, 161, 201, 35, 208, 176, 97, 161, 201, 35, 215, 145, 97, 161, 201, 35, - 220, 225, 97, 161, 201, 35, 209, 36, 97, 161, 201, 35, 208, 254, 97, 161, - 201, 35, 214, 82, 97, 161, 201, 35, 221, 63, 97, 161, 201, 35, 221, 65, - 97, 161, 201, 35, 198, 153, 208, 123, 97, 161, 201, 35, 235, 8, 97, 161, - 201, 35, 235, 7, 97, 161, 201, 35, 235, 5, 97, 161, 201, 35, 235, 9, 221, - 60, 97, 161, 201, 35, 235, 6, 221, 60, 97, 161, 201, 35, 230, 162, 4, - 202, 165, 191, 103, 97, 161, 201, 35, 230, 158, 4, 202, 165, 191, 103, - 97, 161, 201, 35, 230, 161, 97, 161, 201, 35, 230, 157, 97, 161, 201, 35, - 230, 158, 4, 54, 191, 103, 97, 161, 201, 35, 230, 159, 97, 161, 201, 35, - 230, 160, 208, 254, 97, 161, 216, 202, 97, 161, 216, 203, 208, 253, 97, - 161, 216, 203, 221, 59, 97, 161, 216, 203, 221, 62, 97, 161, 216, 203, - 221, 64, 97, 161, 201, 35, 197, 170, 97, 161, 201, 35, 197, 169, 97, 161, - 201, 35, 197, 168, 97, 161, 211, 21, 97, 161, 211, 22, 200, 150, 97, 161, - 211, 22, 197, 243, 97, 161, 211, 22, 220, 231, 200, 150, 97, 161, 211, - 22, 221, 61, 200, 150, 97, 161, 211, 22, 221, 61, 214, 82, 97, 161, 201, - 35, 220, 230, 97, 161, 201, 35, 220, 231, 208, 254, 97, 161, 201, 35, - 220, 231, 230, 162, 4, 202, 165, 191, 103, 97, 161, 201, 35, 220, 231, - 230, 158, 4, 202, 165, 191, 103, 97, 161, 201, 35, 220, 231, 230, 161, - 97, 161, 201, 35, 220, 231, 230, 157, 97, 161, 201, 35, 220, 231, 230, - 158, 4, 54, 191, 103, 97, 161, 201, 35, 220, 231, 230, 159, 97, 161, 201, - 35, 220, 231, 230, 160, 208, 254, 97, 161, 201, 35, 220, 231, 197, 171, - 97, 161, 220, 190, 97, 161, 211, 160, 97, 161, 235, 40, 97, 161, 214, 89, - 97, 161, 210, 69, 72, 37, 16, 208, 162, 72, 37, 16, 237, 172, 72, 37, 16, - 209, 251, 72, 37, 16, 210, 236, 234, 101, 72, 37, 16, 210, 236, 236, 193, - 72, 37, 16, 195, 169, 234, 101, 72, 37, 16, 195, 169, 236, 193, 72, 37, - 16, 222, 18, 72, 37, 16, 200, 56, 72, 37, 16, 210, 110, 72, 37, 16, 191, - 231, 72, 37, 16, 191, 232, 236, 193, 72, 37, 16, 220, 235, 72, 37, 16, - 251, 11, 234, 101, 72, 37, 16, 233, 169, 234, 101, 72, 37, 16, 199, 103, - 72, 37, 16, 221, 222, 72, 37, 16, 251, 0, 72, 37, 16, 251, 1, 236, 193, - 72, 37, 16, 200, 63, 72, 37, 16, 198, 239, 72, 37, 16, 211, 105, 250, - 218, 72, 37, 16, 230, 204, 250, 218, 72, 37, 16, 208, 161, 72, 37, 16, - 246, 200, 72, 37, 16, 195, 158, 72, 37, 16, 223, 30, 250, 218, 72, 37, - 16, 221, 224, 250, 218, 72, 37, 16, 221, 223, 250, 218, 72, 37, 16, 205, - 100, 72, 37, 16, 210, 100, 72, 37, 16, 201, 83, 251, 4, 72, 37, 16, 210, - 235, 250, 218, 72, 37, 16, 195, 168, 250, 218, 72, 37, 16, 251, 5, 250, - 218, 72, 37, 16, 250, 254, 72, 37, 16, 221, 68, 72, 37, 16, 207, 9, 72, - 37, 16, 209, 174, 250, 218, 72, 37, 16, 198, 137, 72, 37, 16, 251, 77, - 72, 37, 16, 205, 32, 72, 37, 16, 200, 67, 250, 218, 72, 37, 16, 200, 67, - 216, 147, 201, 81, 72, 37, 16, 210, 230, 250, 218, 72, 37, 16, 199, 22, - 72, 37, 16, 219, 178, 72, 37, 16, 234, 250, 72, 37, 16, 197, 239, 72, 37, - 16, 199, 71, 72, 37, 16, 220, 238, 72, 37, 16, 251, 11, 233, 169, 214, - 84, 72, 37, 16, 232, 50, 250, 218, 72, 37, 16, 223, 147, 72, 37, 16, 197, - 206, 250, 218, 72, 37, 16, 222, 21, 197, 205, 72, 37, 16, 210, 27, 72, - 37, 16, 208, 166, 72, 37, 16, 221, 18, 72, 37, 16, 243, 12, 250, 218, 72, - 37, 16, 207, 130, 72, 37, 16, 210, 114, 250, 218, 72, 37, 16, 210, 111, - 250, 218, 72, 37, 16, 227, 250, 72, 37, 16, 214, 211, 72, 37, 16, 209, - 229, 72, 37, 16, 221, 19, 251, 116, 72, 37, 16, 197, 206, 251, 116, 72, - 37, 16, 201, 50, 72, 37, 16, 230, 156, 72, 37, 16, 223, 30, 214, 84, 72, - 37, 16, 211, 105, 214, 84, 72, 37, 16, 210, 236, 214, 84, 72, 37, 16, - 209, 228, 72, 37, 16, 221, 2, 72, 37, 16, 209, 227, 72, 37, 16, 220, 237, - 72, 37, 16, 210, 28, 214, 84, 72, 37, 16, 221, 223, 214, 85, 251, 42, 72, - 37, 16, 221, 224, 214, 85, 251, 42, 72, 37, 16, 191, 229, 72, 37, 16, - 251, 1, 214, 84, 72, 37, 16, 251, 2, 200, 64, 214, 84, 72, 37, 16, 191, - 230, 72, 37, 16, 220, 236, 72, 37, 16, 234, 96, 72, 37, 16, 246, 201, 72, - 37, 16, 216, 39, 223, 29, 72, 37, 16, 195, 169, 214, 84, 72, 37, 16, 209, - 174, 214, 84, 72, 37, 16, 208, 167, 214, 84, 72, 37, 16, 211, 101, 72, - 37, 16, 251, 29, 72, 37, 16, 218, 158, 72, 37, 16, 210, 111, 214, 84, 72, - 37, 16, 210, 114, 214, 84, 72, 37, 16, 233, 207, 210, 113, 72, 37, 16, - 220, 123, 72, 37, 16, 251, 30, 72, 37, 16, 197, 206, 214, 84, 72, 37, 16, - 234, 99, 72, 37, 16, 200, 67, 214, 84, 72, 37, 16, 200, 57, 72, 37, 16, - 243, 12, 214, 84, 72, 37, 16, 234, 11, 72, 37, 16, 205, 33, 214, 84, 72, - 37, 16, 192, 199, 221, 68, 72, 37, 16, 197, 203, 72, 37, 16, 208, 168, - 72, 37, 16, 197, 207, 72, 37, 16, 197, 204, 72, 37, 16, 208, 165, 72, 37, - 16, 197, 202, 72, 37, 16, 208, 164, 72, 37, 16, 230, 203, 72, 37, 16, - 250, 210, 72, 37, 16, 233, 207, 250, 210, 72, 37, 16, 210, 230, 214, 84, - 72, 37, 16, 199, 21, 233, 220, 72, 37, 16, 199, 21, 233, 168, 72, 37, 16, - 199, 23, 251, 6, 72, 37, 16, 199, 15, 222, 76, 250, 253, 72, 37, 16, 222, - 20, 72, 37, 16, 234, 48, 72, 37, 16, 192, 38, 222, 17, 72, 37, 16, 192, - 38, 251, 42, 72, 37, 16, 201, 82, 72, 37, 16, 221, 69, 251, 42, 72, 37, - 16, 236, 194, 250, 218, 72, 37, 16, 220, 239, 250, 218, 72, 37, 16, 220, - 239, 251, 116, 72, 37, 16, 220, 239, 214, 84, 72, 37, 16, 251, 5, 214, - 84, 72, 37, 16, 251, 7, 72, 37, 16, 236, 193, 72, 37, 16, 197, 219, 72, - 37, 16, 199, 61, 72, 37, 16, 221, 6, 72, 37, 16, 219, 183, 234, 41, 243, - 2, 72, 37, 16, 219, 183, 234, 251, 243, 3, 72, 37, 16, 219, 183, 197, - 222, 243, 3, 72, 37, 16, 219, 183, 199, 73, 243, 3, 72, 37, 16, 219, 183, - 223, 142, 243, 2, 72, 37, 16, 230, 204, 214, 85, 251, 42, 72, 37, 16, - 230, 204, 210, 101, 250, 206, 72, 37, 16, 230, 204, 210, 101, 237, 28, - 72, 37, 16, 236, 218, 72, 37, 16, 236, 219, 210, 101, 250, 207, 222, 17, - 72, 37, 16, 236, 219, 210, 101, 250, 207, 251, 42, 72, 37, 16, 236, 219, - 210, 101, 237, 28, 72, 37, 16, 197, 228, 72, 37, 16, 250, 211, 72, 37, - 16, 223, 149, 72, 37, 16, 236, 241, 72, 37, 16, 251, 195, 209, 44, 250, - 212, 72, 37, 16, 251, 195, 250, 209, 72, 37, 16, 251, 195, 250, 212, 72, - 37, 16, 251, 195, 216, 141, 72, 37, 16, 251, 195, 216, 152, 72, 37, 16, - 251, 195, 230, 205, 72, 37, 16, 251, 195, 230, 202, 72, 37, 16, 251, 195, - 209, 44, 230, 205, 72, 37, 16, 217, 26, 208, 174, 227, 248, 72, 37, 16, - 217, 26, 251, 118, 208, 174, 227, 248, 72, 37, 16, 217, 26, 237, 27, 227, - 248, 72, 37, 16, 217, 26, 251, 118, 237, 27, 227, 248, 72, 37, 16, 217, - 26, 197, 214, 227, 248, 72, 37, 16, 217, 26, 197, 229, 72, 37, 16, 217, - 26, 199, 66, 227, 248, 72, 37, 16, 217, 26, 199, 66, 219, 187, 227, 248, - 72, 37, 16, 217, 26, 219, 187, 227, 248, 72, 37, 16, 217, 26, 209, 97, - 227, 248, 72, 37, 16, 223, 38, 199, 96, 227, 249, 72, 37, 16, 251, 2, - 199, 96, 227, 249, 72, 37, 16, 233, 38, 199, 63, 72, 37, 16, 233, 38, - 215, 205, 72, 37, 16, 233, 38, 236, 224, 72, 37, 16, 217, 26, 195, 162, - 227, 248, 72, 37, 16, 217, 26, 208, 173, 227, 248, 72, 37, 16, 217, 26, - 209, 97, 199, 66, 227, 248, 72, 37, 16, 230, 199, 215, 48, 251, 6, 72, - 37, 16, 230, 199, 215, 48, 236, 192, 72, 37, 16, 234, 59, 222, 76, 232, - 50, 195, 0, 72, 37, 16, 223, 148, 72, 37, 16, 223, 146, 72, 37, 16, 232, - 50, 250, 219, 237, 26, 227, 247, 72, 37, 16, 232, 50, 236, 239, 168, 72, - 37, 16, 232, 50, 236, 239, 214, 211, 72, 37, 16, 232, 50, 214, 205, 227, - 248, 72, 37, 16, 232, 50, 236, 239, 236, 255, 72, 37, 16, 232, 50, 202, - 101, 236, 238, 236, 255, 72, 37, 16, 232, 50, 236, 239, 221, 253, 72, 37, - 16, 232, 50, 236, 239, 191, 7, 72, 37, 16, 232, 50, 236, 239, 213, 206, - 222, 17, 72, 37, 16, 232, 50, 236, 239, 213, 206, 251, 42, 72, 37, 16, - 232, 50, 217, 78, 243, 4, 236, 224, 72, 37, 16, 232, 50, 217, 78, 243, 4, - 215, 205, 72, 37, 16, 232, 239, 202, 101, 243, 4, 195, 161, 72, 37, 16, - 232, 50, 202, 101, 243, 4, 200, 68, 72, 37, 16, 232, 50, 214, 87, 72, 37, - 16, 243, 5, 190, 230, 72, 37, 16, 243, 5, 221, 67, 72, 37, 16, 243, 5, - 201, 233, 72, 37, 16, 232, 50, 228, 44, 192, 37, 199, 67, 72, 37, 16, - 232, 50, 234, 60, 251, 31, 72, 37, 16, 192, 37, 197, 215, 72, 37, 16, - 236, 232, 197, 215, 72, 37, 16, 236, 232, 199, 67, 72, 37, 16, 236, 232, - 251, 8, 234, 251, 236, 121, 72, 37, 16, 236, 232, 215, 203, 199, 72, 236, - 121, 72, 37, 16, 236, 232, 236, 215, 233, 181, 236, 121, 72, 37, 16, 236, - 232, 197, 226, 211, 111, 236, 121, 72, 37, 16, 192, 37, 251, 8, 234, 251, - 236, 121, 72, 37, 16, 192, 37, 215, 203, 199, 72, 236, 121, 72, 37, 16, - 192, 37, 236, 215, 233, 181, 236, 121, 72, 37, 16, 192, 37, 197, 226, - 211, 111, 236, 121, 72, 37, 16, 231, 110, 236, 231, 72, 37, 16, 231, 110, - 192, 36, 72, 37, 16, 236, 240, 251, 8, 216, 40, 72, 37, 16, 236, 240, - 251, 8, 216, 183, 72, 37, 16, 236, 240, 236, 193, 72, 37, 16, 236, 240, - 199, 13, 72, 37, 16, 202, 176, 199, 13, 72, 37, 16, 202, 176, 199, 14, - 236, 176, 72, 37, 16, 202, 176, 199, 14, 197, 216, 72, 37, 16, 202, 176, - 199, 14, 199, 59, 72, 37, 16, 202, 176, 250, 178, 72, 37, 16, 202, 176, - 250, 179, 236, 176, 72, 37, 16, 202, 176, 250, 179, 197, 216, 72, 37, 16, - 202, 176, 250, 179, 199, 59, 72, 37, 16, 236, 216, 231, 91, 72, 37, 16, - 236, 223, 211, 9, 72, 37, 16, 201, 68, 72, 37, 16, 250, 203, 168, 72, 37, - 16, 250, 203, 195, 0, 72, 37, 16, 250, 203, 231, 203, 72, 37, 16, 250, - 203, 236, 255, 72, 37, 16, 250, 203, 221, 253, 72, 37, 16, 250, 203, 191, - 7, 72, 37, 16, 250, 203, 213, 205, 72, 37, 16, 221, 223, 214, 85, 216, - 151, 72, 37, 16, 221, 224, 214, 85, 216, 151, 72, 37, 16, 221, 223, 214, - 85, 222, 17, 72, 37, 16, 221, 224, 214, 85, 222, 17, 72, 37, 16, 221, 69, - 222, 17, 72, 37, 16, 230, 204, 214, 85, 222, 17, 37, 16, 202, 165, 249, - 33, 37, 16, 54, 249, 33, 37, 16, 52, 249, 33, 37, 16, 207, 14, 52, 249, - 33, 37, 16, 237, 169, 249, 33, 37, 16, 203, 35, 249, 33, 37, 16, 45, 207, - 44, 57, 37, 16, 50, 207, 44, 57, 37, 16, 207, 44, 236, 94, 37, 16, 237, - 213, 205, 36, 37, 16, 237, 242, 247, 60, 37, 16, 205, 36, 37, 16, 242, - 44, 37, 16, 207, 42, 232, 226, 37, 16, 207, 42, 232, 225, 37, 16, 207, - 42, 232, 224, 37, 16, 232, 249, 37, 16, 232, 250, 60, 37, 16, 247, 247, - 77, 37, 16, 247, 102, 37, 16, 248, 7, 37, 16, 248, 5, 37, 16, 211, 88, - 201, 106, 37, 16, 197, 8, 201, 106, 37, 16, 198, 215, 201, 106, 37, 16, - 232, 89, 201, 106, 37, 16, 232, 184, 201, 106, 37, 16, 202, 130, 201, - 106, 37, 16, 202, 128, 232, 67, 37, 16, 232, 87, 232, 67, 37, 16, 232, - 15, 242, 187, 37, 16, 232, 15, 242, 188, 211, 13, 251, 107, 37, 16, 232, - 15, 242, 188, 211, 13, 249, 16, 37, 16, 247, 146, 242, 187, 37, 16, 233, - 135, 242, 187, 37, 16, 233, 135, 242, 188, 211, 13, 251, 107, 37, 16, - 233, 135, 242, 188, 211, 13, 249, 16, 37, 16, 235, 51, 242, 186, 37, 16, - 235, 51, 242, 185, 37, 16, 215, 114, 216, 209, 207, 25, 37, 16, 54, 203, - 121, 37, 16, 54, 232, 166, 37, 16, 232, 167, 196, 73, 37, 16, 232, 167, - 235, 79, 37, 16, 214, 192, 196, 73, 37, 16, 214, 192, 235, 79, 37, 16, - 203, 122, 196, 73, 37, 16, 203, 122, 235, 79, 37, 16, 208, 18, 163, 203, - 121, 37, 16, 208, 18, 163, 232, 166, 37, 16, 242, 23, 198, 141, 37, 16, - 238, 108, 198, 141, 37, 16, 211, 13, 251, 107, 37, 16, 211, 13, 249, 16, - 37, 16, 207, 254, 251, 107, 37, 16, 207, 254, 249, 16, 37, 16, 215, 117, - 207, 25, 37, 16, 193, 85, 207, 25, 37, 16, 134, 207, 25, 37, 16, 208, 18, - 207, 25, 37, 16, 234, 117, 207, 25, 37, 16, 202, 124, 207, 25, 37, 16, - 198, 241, 207, 25, 37, 16, 202, 114, 207, 25, 37, 16, 91, 228, 110, 197, - 26, 207, 25, 37, 16, 192, 236, 212, 245, 37, 16, 107, 212, 245, 37, 16, - 242, 219, 192, 236, 212, 245, 37, 16, 51, 212, 246, 193, 87, 37, 16, 51, - 212, 246, 248, 91, 37, 16, 197, 238, 212, 246, 132, 193, 87, 37, 16, 197, - 238, 212, 246, 132, 248, 91, 37, 16, 197, 238, 212, 246, 45, 193, 87, 37, - 16, 197, 238, 212, 246, 45, 248, 91, 37, 16, 197, 238, 212, 246, 50, 193, - 87, 37, 16, 197, 238, 212, 246, 50, 248, 91, 37, 16, 197, 238, 212, 246, - 143, 193, 87, 37, 16, 197, 238, 212, 246, 143, 248, 91, 37, 16, 197, 238, - 212, 246, 132, 50, 193, 87, 37, 16, 197, 238, 212, 246, 132, 50, 248, 91, - 37, 16, 215, 189, 212, 246, 193, 87, 37, 16, 215, 189, 212, 246, 248, 91, - 37, 16, 197, 235, 212, 246, 143, 193, 87, 37, 16, 197, 235, 212, 246, - 143, 248, 91, 37, 16, 210, 104, 212, 245, 37, 16, 195, 14, 212, 245, 37, - 16, 212, 246, 248, 91, 37, 16, 212, 126, 212, 245, 37, 16, 242, 155, 212, - 246, 193, 87, 37, 16, 242, 155, 212, 246, 248, 91, 37, 16, 247, 244, 37, - 16, 193, 85, 212, 249, 37, 16, 134, 212, 249, 37, 16, 208, 18, 212, 249, - 37, 16, 234, 117, 212, 249, 37, 16, 202, 124, 212, 249, 37, 16, 198, 241, - 212, 249, 37, 16, 202, 114, 212, 249, 37, 16, 91, 228, 110, 197, 26, 212, - 249, 37, 16, 33, 201, 75, 37, 16, 33, 201, 192, 201, 75, 37, 16, 33, 197, - 249, 37, 16, 33, 197, 248, 37, 16, 33, 197, 247, 37, 16, 232, 209, 197, - 249, 37, 16, 232, 209, 197, 248, 37, 16, 232, 209, 197, 247, 37, 16, 33, - 250, 110, 236, 96, 37, 16, 33, 232, 176, 37, 16, 33, 232, 175, 37, 16, - 33, 232, 174, 37, 16, 33, 232, 173, 37, 16, 33, 232, 172, 37, 16, 248, - 199, 248, 220, 37, 16, 234, 53, 248, 220, 37, 16, 248, 199, 198, 173, 37, - 16, 234, 53, 198, 173, 37, 16, 248, 199, 202, 66, 37, 16, 234, 53, 202, - 66, 37, 16, 248, 199, 209, 183, 37, 16, 234, 53, 209, 183, 37, 16, 33, - 252, 8, 37, 16, 33, 201, 110, 37, 16, 33, 199, 78, 37, 16, 33, 201, 111, - 37, 16, 33, 217, 41, 37, 16, 33, 217, 40, 37, 16, 33, 252, 7, 37, 16, 33, - 218, 221, 37, 16, 250, 191, 196, 73, 37, 16, 250, 191, 235, 79, 37, 16, - 33, 236, 113, 37, 16, 33, 206, 179, 37, 16, 33, 232, 155, 37, 16, 33, - 202, 62, 37, 16, 33, 248, 177, 37, 16, 33, 54, 198, 56, 37, 16, 33, 197, - 221, 198, 56, 37, 16, 206, 185, 37, 16, 200, 236, 37, 16, 191, 166, 37, - 16, 209, 175, 37, 16, 216, 132, 37, 16, 232, 101, 37, 16, 238, 182, 37, - 16, 237, 87, 37, 16, 230, 194, 212, 250, 202, 92, 37, 16, 230, 194, 212, - 250, 213, 31, 202, 92, 37, 16, 198, 23, 37, 16, 197, 54, 37, 16, 223, 65, - 197, 54, 37, 16, 197, 55, 202, 92, 37, 16, 197, 55, 196, 73, 37, 16, 211, - 33, 201, 22, 37, 16, 211, 33, 201, 19, 37, 16, 211, 33, 201, 18, 37, 16, - 211, 33, 201, 17, 37, 16, 211, 33, 201, 16, 37, 16, 211, 33, 201, 15, 37, - 16, 211, 33, 201, 14, 37, 16, 211, 33, 201, 13, 37, 16, 211, 33, 201, 12, - 37, 16, 211, 33, 201, 21, 37, 16, 211, 33, 201, 20, 37, 16, 229, 224, 37, - 16, 214, 99, 37, 16, 234, 53, 80, 201, 64, 37, 16, 237, 80, 202, 92, 37, - 16, 33, 143, 248, 21, 37, 16, 33, 132, 248, 21, 37, 16, 33, 229, 237, 37, - 16, 33, 202, 52, 209, 103, 37, 16, 210, 45, 77, 37, 16, 210, 45, 132, 77, - 37, 16, 134, 210, 45, 77, 37, 16, 230, 233, 196, 73, 37, 16, 230, 233, - 235, 79, 37, 16, 4, 232, 208, 37, 16, 237, 196, 37, 16, 237, 197, 251, - 123, 37, 16, 217, 4, 37, 16, 218, 242, 37, 16, 247, 241, 37, 16, 204, 24, - 193, 87, 37, 16, 204, 24, 248, 91, 37, 16, 216, 22, 37, 16, 216, 23, 248, - 91, 37, 16, 204, 18, 193, 87, 37, 16, 204, 18, 248, 91, 37, 16, 232, 33, - 193, 87, 37, 16, 232, 33, 248, 91, 37, 16, 218, 243, 210, 0, 207, 25, 37, - 16, 218, 243, 223, 139, 207, 25, 37, 16, 247, 242, 207, 25, 37, 16, 204, - 24, 207, 25, 37, 16, 216, 23, 207, 25, 37, 16, 204, 18, 207, 25, 37, 16, - 199, 92, 209, 254, 238, 139, 208, 185, 209, 255, 37, 16, 199, 92, 209, - 254, 238, 139, 208, 185, 223, 138, 37, 16, 199, 92, 209, 254, 238, 139, - 208, 185, 210, 0, 236, 203, 37, 16, 199, 92, 223, 137, 238, 139, 208, - 185, 209, 255, 37, 16, 199, 92, 223, 137, 238, 139, 208, 185, 223, 138, - 37, 16, 199, 92, 223, 137, 238, 139, 208, 185, 223, 139, 236, 203, 37, - 16, 199, 92, 223, 137, 238, 139, 208, 185, 223, 139, 236, 202, 37, 16, - 199, 92, 223, 137, 238, 139, 208, 185, 223, 139, 236, 201, 37, 16, 238, - 173, 37, 16, 230, 165, 247, 146, 242, 187, 37, 16, 230, 165, 233, 135, - 242, 187, 37, 16, 51, 250, 70, 37, 16, 195, 36, 37, 16, 209, 62, 37, 16, - 242, 176, 37, 16, 205, 90, 37, 16, 242, 181, 37, 16, 198, 42, 37, 16, - 209, 21, 37, 16, 209, 22, 232, 158, 37, 16, 205, 91, 232, 158, 37, 16, - 198, 43, 207, 22, 37, 16, 209, 237, 200, 226, 37, 16, 221, 124, 247, 146, - 242, 187, 37, 16, 221, 124, 234, 53, 80, 209, 166, 37, 16, 221, 124, 52, - 212, 249, 37, 16, 221, 124, 207, 94, 77, 37, 16, 221, 124, 193, 85, 212, - 249, 37, 16, 221, 124, 134, 212, 249, 37, 16, 221, 124, 208, 18, 212, - 250, 201, 76, 235, 79, 37, 16, 221, 124, 208, 18, 212, 250, 201, 76, 196, - 73, 37, 16, 221, 124, 234, 117, 212, 250, 201, 76, 235, 79, 37, 16, 221, - 124, 234, 117, 212, 250, 201, 76, 196, 73, 37, 16, 221, 124, 232, 167, - 57, 37, 16, 202, 6, 37, 16, 221, 7, 35, 195, 20, 212, 253, 200, 119, 35, - 195, 20, 212, 253, 200, 108, 35, 195, 20, 212, 253, 200, 98, 35, 195, 20, - 212, 253, 200, 91, 35, 195, 20, 212, 253, 200, 83, 35, 195, 20, 212, 253, - 200, 77, 35, 195, 20, 212, 253, 200, 76, 35, 195, 20, 212, 253, 200, 75, - 35, 195, 20, 212, 253, 200, 74, 35, 195, 20, 212, 253, 200, 118, 35, 195, - 20, 212, 253, 200, 117, 35, 195, 20, 212, 253, 200, 116, 35, 195, 20, - 212, 253, 200, 115, 35, 195, 20, 212, 253, 200, 114, 35, 195, 20, 212, - 253, 200, 113, 35, 195, 20, 212, 253, 200, 112, 35, 195, 20, 212, 253, - 200, 111, 35, 195, 20, 212, 253, 200, 110, 35, 195, 20, 212, 253, 200, - 109, 35, 195, 20, 212, 253, 200, 107, 35, 195, 20, 212, 253, 200, 106, - 35, 195, 20, 212, 253, 200, 105, 35, 195, 20, 212, 253, 200, 104, 35, - 195, 20, 212, 253, 200, 103, 35, 195, 20, 212, 253, 200, 82, 35, 195, 20, - 212, 253, 200, 81, 35, 195, 20, 212, 253, 200, 80, 35, 195, 20, 212, 253, - 200, 79, 35, 195, 20, 212, 253, 200, 78, 35, 223, 88, 212, 253, 200, 119, - 35, 223, 88, 212, 253, 200, 108, 35, 223, 88, 212, 253, 200, 91, 35, 223, - 88, 212, 253, 200, 83, 35, 223, 88, 212, 253, 200, 76, 35, 223, 88, 212, - 253, 200, 75, 35, 223, 88, 212, 253, 200, 117, 35, 223, 88, 212, 253, - 200, 116, 35, 223, 88, 212, 253, 200, 115, 35, 223, 88, 212, 253, 200, - 114, 35, 223, 88, 212, 253, 200, 111, 35, 223, 88, 212, 253, 200, 110, - 35, 223, 88, 212, 253, 200, 109, 35, 223, 88, 212, 253, 200, 104, 35, - 223, 88, 212, 253, 200, 103, 35, 223, 88, 212, 253, 200, 102, 35, 223, - 88, 212, 253, 200, 101, 35, 223, 88, 212, 253, 200, 100, 35, 223, 88, - 212, 253, 200, 99, 35, 223, 88, 212, 253, 200, 97, 35, 223, 88, 212, 253, - 200, 96, 35, 223, 88, 212, 253, 200, 95, 35, 223, 88, 212, 253, 200, 94, - 35, 223, 88, 212, 253, 200, 93, 35, 223, 88, 212, 253, 200, 92, 35, 223, - 88, 212, 253, 200, 90, 35, 223, 88, 212, 253, 200, 89, 35, 223, 88, 212, - 253, 200, 88, 35, 223, 88, 212, 253, 200, 87, 35, 223, 88, 212, 253, 200, - 86, 35, 223, 88, 212, 253, 200, 85, 35, 223, 88, 212, 253, 200, 84, 35, - 223, 88, 212, 253, 200, 82, 35, 223, 88, 212, 253, 200, 81, 35, 223, 88, - 212, 253, 200, 80, 35, 223, 88, 212, 253, 200, 79, 35, 223, 88, 212, 253, - 200, 78, 33, 35, 37, 197, 217, 33, 35, 37, 199, 60, 33, 35, 37, 210, 13, - 35, 37, 219, 182, 217, 1, 212, 121, 191, 77, 217, 1, 212, 121, 108, 217, - 1, 212, 121, 109, 217, 1, 212, 121, 139, 217, 1, 212, 121, 137, 217, 1, - 212, 121, 153, 217, 1, 212, 121, 173, 217, 1, 212, 121, 181, 217, 1, 212, - 121, 176, 217, 1, 212, 121, 184, 217, 1, 212, 121, 199, 90, 217, 1, 212, - 121, 234, 84, 217, 1, 212, 121, 197, 33, 217, 1, 212, 121, 198, 246, 217, - 1, 212, 121, 232, 84, 217, 1, 212, 121, 232, 234, 217, 1, 212, 121, 202, - 125, 217, 1, 212, 121, 203, 239, 217, 1, 212, 121, 234, 118, 217, 1, 212, - 121, 213, 158, 215, 204, 39, 234, 163, 236, 217, 39, 229, 186, 234, 163, - 236, 217, 39, 228, 114, 234, 163, 236, 217, 39, 234, 162, 229, 187, 236, - 217, 39, 234, 162, 228, 113, 236, 217, 39, 234, 163, 199, 62, 39, 246, - 229, 199, 62, 39, 232, 42, 242, 218, 199, 62, 39, 216, 13, 199, 62, 39, - 249, 28, 199, 62, 39, 221, 241, 202, 65, 199, 62, 39, 238, 232, 199, 62, - 39, 250, 162, 199, 62, 39, 211, 51, 199, 62, 39, 247, 253, 211, 4, 199, - 62, 39, 237, 82, 211, 46, 236, 168, 199, 62, 39, 236, 165, 199, 62, 39, - 191, 237, 199, 62, 39, 223, 125, 199, 62, 39, 210, 23, 199, 62, 39, 207, - 103, 199, 62, 39, 238, 244, 199, 62, 39, 228, 230, 249, 96, 199, 62, 39, - 193, 168, 199, 62, 39, 232, 130, 199, 62, 39, 251, 232, 199, 62, 39, 207, - 57, 199, 62, 39, 207, 29, 199, 62, 39, 234, 161, 199, 62, 39, 222, 158, - 199, 62, 39, 238, 239, 199, 62, 39, 234, 51, 199, 62, 39, 235, 15, 199, - 62, 39, 246, 196, 199, 62, 39, 237, 92, 199, 62, 39, 28, 207, 28, 199, - 62, 39, 210, 201, 199, 62, 39, 219, 186, 199, 62, 39, 242, 169, 199, 62, - 39, 221, 112, 199, 62, 39, 231, 152, 199, 62, 39, 201, 34, 199, 62, 39, - 208, 133, 199, 62, 39, 232, 41, 199, 62, 39, 207, 30, 199, 62, 39, 219, - 227, 211, 46, 215, 241, 199, 62, 39, 207, 26, 199, 62, 39, 230, 216, 118, - 216, 187, 199, 62, 39, 234, 54, 199, 62, 39, 201, 51, 199, 62, 39, 230, - 168, 199, 62, 39, 234, 44, 199, 62, 39, 210, 73, 199, 62, 39, 206, 172, - 199, 62, 39, 232, 156, 199, 62, 39, 195, 160, 211, 46, 193, 145, 199, 62, - 39, 238, 249, 199, 62, 39, 216, 208, 199, 62, 39, 233, 208, 199, 62, 39, - 196, 84, 199, 62, 39, 236, 204, 199, 62, 39, 242, 171, 215, 163, 199, 62, - 39, 230, 138, 199, 62, 39, 231, 153, 223, 134, 199, 62, 39, 217, 13, 199, - 62, 39, 252, 2, 199, 62, 39, 234, 70, 199, 62, 39, 235, 83, 199, 62, 39, - 193, 143, 199, 62, 39, 202, 160, 199, 62, 39, 223, 98, 199, 62, 39, 237, - 48, 199, 62, 39, 237, 174, 199, 62, 39, 236, 200, 199, 62, 39, 233, 172, - 199, 62, 39, 203, 235, 199, 62, 39, 201, 55, 199, 62, 39, 229, 239, 199, - 62, 39, 242, 18, 199, 62, 39, 242, 166, 199, 62, 39, 233, 47, 199, 62, - 39, 251, 196, 199, 62, 39, 242, 17, 199, 62, 39, 211, 94, 199, 29, 195, - 135, 199, 62, 39, 236, 226, 199, 62, 39, 220, 89, 199, 62, 39, 232, 93, - 238, 197, 206, 140, 196, 87, 17, 108, 238, 197, 206, 140, 196, 87, 17, - 109, 238, 197, 206, 140, 196, 87, 17, 139, 238, 197, 206, 140, 196, 87, - 17, 137, 238, 197, 206, 140, 196, 87, 17, 153, 238, 197, 206, 140, 196, - 87, 17, 173, 238, 197, 206, 140, 196, 87, 17, 181, 238, 197, 206, 140, - 196, 87, 17, 176, 238, 197, 206, 140, 196, 87, 17, 184, 238, 197, 206, - 140, 199, 86, 17, 108, 238, 197, 206, 140, 199, 86, 17, 109, 238, 197, - 206, 140, 199, 86, 17, 139, 238, 197, 206, 140, 199, 86, 17, 137, 238, - 197, 206, 140, 199, 86, 17, 153, 238, 197, 206, 140, 199, 86, 17, 173, - 238, 197, 206, 140, 199, 86, 17, 181, 238, 197, 206, 140, 199, 86, 17, - 176, 238, 197, 206, 140, 199, 86, 17, 184, 154, 199, 193, 87, 108, 154, - 199, 193, 87, 109, 154, 199, 193, 87, 139, 154, 199, 193, 87, 137, 154, - 199, 193, 87, 153, 199, 193, 87, 108, 199, 193, 87, 153, 13, 28, 6, 65, - 13, 28, 6, 250, 70, 13, 28, 6, 247, 145, 13, 28, 6, 238, 80, 13, 28, 6, - 73, 13, 28, 6, 233, 134, 13, 28, 6, 232, 14, 13, 28, 6, 230, 83, 13, 28, - 6, 70, 13, 28, 6, 223, 7, 13, 28, 6, 222, 125, 13, 28, 6, 170, 13, 28, 6, - 218, 147, 13, 28, 6, 215, 47, 13, 28, 6, 74, 13, 28, 6, 210, 226, 13, 28, - 6, 208, 97, 13, 28, 6, 148, 13, 28, 6, 206, 3, 13, 28, 6, 200, 39, 13, - 28, 6, 69, 13, 28, 6, 196, 8, 13, 28, 6, 193, 221, 13, 28, 6, 192, 235, - 13, 28, 6, 192, 159, 13, 28, 6, 191, 166, 13, 28, 2, 65, 13, 28, 2, 250, - 70, 13, 28, 2, 247, 145, 13, 28, 2, 238, 80, 13, 28, 2, 73, 13, 28, 2, - 233, 134, 13, 28, 2, 232, 14, 13, 28, 2, 230, 83, 13, 28, 2, 70, 13, 28, - 2, 223, 7, 13, 28, 2, 222, 125, 13, 28, 2, 170, 13, 28, 2, 218, 147, 13, - 28, 2, 215, 47, 13, 28, 2, 74, 13, 28, 2, 210, 226, 13, 28, 2, 208, 97, - 13, 28, 2, 148, 13, 28, 2, 206, 3, 13, 28, 2, 200, 39, 13, 28, 2, 69, 13, - 28, 2, 196, 8, 13, 28, 2, 193, 221, 13, 28, 2, 192, 235, 13, 28, 2, 192, - 159, 13, 28, 2, 191, 166, 13, 43, 6, 65, 13, 43, 6, 250, 70, 13, 43, 6, - 247, 145, 13, 43, 6, 238, 80, 13, 43, 6, 73, 13, 43, 6, 233, 134, 13, 43, - 6, 232, 14, 13, 43, 6, 230, 83, 13, 43, 6, 70, 13, 43, 6, 223, 7, 13, 43, - 6, 222, 125, 13, 43, 6, 170, 13, 43, 6, 218, 147, 13, 43, 6, 215, 47, 13, - 43, 6, 74, 13, 43, 6, 210, 226, 13, 43, 6, 208, 97, 13, 43, 6, 148, 13, - 43, 6, 206, 3, 13, 43, 6, 200, 39, 13, 43, 6, 69, 13, 43, 6, 196, 8, 13, - 43, 6, 193, 221, 13, 43, 6, 192, 235, 13, 43, 6, 192, 159, 13, 43, 6, - 191, 166, 13, 43, 2, 65, 13, 43, 2, 250, 70, 13, 43, 2, 247, 145, 13, 43, - 2, 238, 80, 13, 43, 2, 73, 13, 43, 2, 233, 134, 13, 43, 2, 232, 14, 13, - 43, 2, 70, 13, 43, 2, 223, 7, 13, 43, 2, 222, 125, 13, 43, 2, 170, 13, - 43, 2, 218, 147, 13, 43, 2, 215, 47, 13, 43, 2, 74, 13, 43, 2, 210, 226, - 13, 43, 2, 208, 97, 13, 43, 2, 148, 13, 43, 2, 206, 3, 13, 43, 2, 200, - 39, 13, 43, 2, 69, 13, 43, 2, 196, 8, 13, 43, 2, 193, 221, 13, 43, 2, - 192, 235, 13, 43, 2, 192, 159, 13, 43, 2, 191, 166, 13, 28, 43, 6, 65, - 13, 28, 43, 6, 250, 70, 13, 28, 43, 6, 247, 145, 13, 28, 43, 6, 238, 80, - 13, 28, 43, 6, 73, 13, 28, 43, 6, 233, 134, 13, 28, 43, 6, 232, 14, 13, - 28, 43, 6, 230, 83, 13, 28, 43, 6, 70, 13, 28, 43, 6, 223, 7, 13, 28, 43, - 6, 222, 125, 13, 28, 43, 6, 170, 13, 28, 43, 6, 218, 147, 13, 28, 43, 6, - 215, 47, 13, 28, 43, 6, 74, 13, 28, 43, 6, 210, 226, 13, 28, 43, 6, 208, - 97, 13, 28, 43, 6, 148, 13, 28, 43, 6, 206, 3, 13, 28, 43, 6, 200, 39, - 13, 28, 43, 6, 69, 13, 28, 43, 6, 196, 8, 13, 28, 43, 6, 193, 221, 13, + 64, 41, 2, 27, 246, 238, 41, 2, 27, 246, 237, 41, 2, 27, 246, 236, 41, 2, + 27, 246, 235, 41, 2, 27, 246, 234, 41, 2, 27, 246, 233, 41, 2, 27, 246, + 232, 41, 2, 27, 246, 231, 41, 2, 27, 246, 230, 41, 2, 27, 246, 229, 41, + 2, 27, 246, 228, 41, 2, 27, 246, 227, 41, 2, 27, 246, 226, 41, 2, 27, + 246, 225, 41, 2, 27, 246, 224, 41, 2, 27, 246, 223, 41, 2, 27, 246, 222, + 41, 2, 27, 246, 221, 41, 2, 27, 246, 220, 41, 2, 27, 246, 219, 41, 2, 27, + 246, 218, 41, 2, 27, 246, 217, 41, 2, 27, 246, 216, 41, 2, 27, 246, 215, + 41, 2, 27, 246, 214, 41, 2, 27, 246, 213, 41, 2, 27, 246, 212, 41, 2, 27, + 246, 211, 41, 2, 27, 246, 210, 41, 2, 27, 246, 209, 41, 2, 27, 246, 208, + 41, 2, 27, 246, 207, 41, 2, 27, 246, 206, 41, 2, 27, 246, 205, 41, 2, 27, + 246, 204, 41, 2, 27, 246, 203, 41, 2, 27, 246, 202, 41, 2, 27, 246, 201, + 41, 2, 27, 246, 200, 41, 2, 27, 246, 199, 41, 2, 27, 246, 198, 41, 2, 27, + 246, 197, 41, 2, 27, 246, 196, 41, 2, 27, 246, 195, 41, 2, 27, 246, 194, + 41, 2, 27, 246, 193, 41, 2, 27, 246, 192, 41, 2, 27, 246, 191, 41, 2, 27, + 246, 190, 41, 2, 27, 246, 189, 41, 2, 27, 246, 188, 41, 2, 27, 246, 187, + 41, 2, 27, 246, 186, 41, 2, 27, 246, 185, 41, 2, 27, 246, 184, 41, 2, 27, + 246, 183, 41, 2, 27, 246, 182, 41, 2, 27, 246, 181, 41, 2, 27, 246, 180, + 41, 2, 27, 246, 179, 41, 2, 27, 246, 178, 41, 2, 27, 246, 177, 41, 2, 27, + 246, 176, 41, 2, 27, 246, 175, 41, 2, 27, 246, 174, 41, 2, 27, 246, 173, + 41, 2, 27, 246, 172, 41, 2, 27, 246, 171, 41, 2, 27, 246, 170, 41, 2, 27, + 246, 169, 41, 2, 27, 246, 168, 41, 2, 27, 246, 167, 41, 2, 27, 246, 166, + 41, 2, 27, 246, 165, 41, 2, 27, 246, 164, 41, 2, 27, 246, 163, 41, 2, 27, + 246, 162, 41, 2, 27, 246, 161, 41, 2, 27, 246, 160, 41, 2, 27, 246, 159, + 41, 2, 27, 246, 158, 41, 2, 27, 246, 157, 41, 2, 27, 246, 156, 41, 2, 27, + 246, 155, 41, 2, 27, 246, 154, 41, 2, 27, 246, 153, 41, 2, 27, 246, 152, + 41, 2, 27, 246, 151, 41, 2, 27, 246, 150, 41, 2, 27, 246, 149, 41, 2, 27, + 246, 148, 41, 2, 27, 246, 147, 41, 2, 27, 246, 146, 41, 2, 27, 246, 145, + 41, 2, 27, 246, 144, 41, 2, 27, 246, 143, 41, 2, 27, 246, 142, 41, 2, 27, + 246, 141, 41, 2, 27, 246, 140, 41, 2, 27, 246, 139, 41, 2, 27, 246, 138, + 41, 2, 27, 246, 137, 41, 2, 27, 246, 136, 41, 2, 27, 246, 135, 41, 2, 27, + 246, 134, 41, 2, 27, 246, 133, 41, 2, 27, 246, 132, 41, 2, 27, 246, 131, + 41, 2, 27, 246, 130, 41, 2, 27, 246, 129, 41, 2, 27, 246, 128, 41, 2, 27, + 246, 127, 41, 2, 27, 246, 126, 41, 2, 27, 246, 125, 41, 2, 27, 246, 124, + 41, 2, 27, 246, 123, 41, 2, 27, 246, 122, 41, 2, 27, 246, 121, 41, 2, 27, + 246, 120, 41, 2, 27, 246, 119, 41, 2, 27, 246, 118, 41, 2, 27, 246, 117, + 41, 2, 27, 246, 116, 41, 2, 27, 246, 115, 41, 2, 27, 246, 114, 41, 2, 27, + 246, 113, 41, 2, 27, 246, 112, 41, 2, 27, 246, 111, 41, 2, 27, 246, 110, + 41, 2, 27, 246, 109, 41, 2, 27, 246, 108, 41, 2, 27, 246, 107, 41, 2, 27, + 246, 106, 41, 2, 27, 246, 105, 41, 2, 27, 246, 104, 41, 2, 27, 246, 103, + 41, 2, 27, 246, 102, 41, 2, 27, 246, 101, 41, 2, 27, 246, 100, 41, 2, 27, + 246, 99, 41, 2, 27, 246, 98, 41, 2, 27, 246, 97, 41, 2, 27, 246, 96, 41, + 2, 27, 246, 95, 41, 2, 27, 246, 94, 41, 2, 27, 246, 93, 41, 2, 27, 246, + 92, 41, 2, 27, 246, 91, 41, 2, 27, 246, 90, 41, 2, 27, 246, 89, 41, 2, + 27, 246, 88, 41, 2, 27, 246, 87, 41, 2, 27, 246, 86, 41, 2, 27, 246, 85, + 41, 2, 27, 246, 84, 41, 2, 27, 246, 83, 41, 2, 27, 246, 82, 41, 2, 27, + 246, 81, 41, 2, 27, 246, 80, 41, 2, 27, 246, 79, 41, 2, 27, 246, 78, 41, + 2, 27, 246, 77, 41, 2, 27, 246, 76, 41, 2, 27, 246, 75, 41, 2, 27, 246, + 74, 41, 2, 27, 246, 73, 41, 2, 27, 246, 72, 41, 2, 27, 246, 71, 41, 2, + 27, 246, 70, 41, 2, 27, 246, 69, 41, 2, 27, 246, 68, 41, 2, 27, 246, 67, + 41, 2, 27, 246, 66, 41, 2, 27, 246, 65, 41, 2, 27, 246, 64, 41, 2, 27, + 246, 63, 41, 2, 27, 246, 62, 41, 2, 27, 246, 61, 41, 2, 27, 246, 60, 41, + 2, 27, 246, 59, 41, 2, 27, 246, 58, 41, 2, 27, 246, 57, 41, 2, 27, 246, + 56, 41, 2, 27, 246, 55, 41, 2, 27, 246, 54, 41, 2, 27, 246, 53, 41, 2, + 27, 246, 52, 41, 2, 27, 246, 51, 41, 2, 27, 246, 50, 41, 2, 27, 246, 49, + 41, 2, 27, 246, 48, 41, 2, 27, 246, 47, 41, 2, 27, 246, 46, 41, 2, 27, + 246, 45, 41, 2, 27, 246, 44, 41, 2, 27, 246, 43, 41, 2, 27, 246, 42, 41, + 2, 27, 246, 41, 41, 2, 27, 246, 40, 41, 2, 27, 246, 39, 41, 2, 27, 246, + 38, 41, 2, 27, 246, 37, 41, 2, 27, 246, 36, 41, 2, 27, 246, 35, 41, 2, + 27, 246, 34, 41, 2, 27, 246, 33, 41, 2, 27, 246, 32, 41, 2, 27, 246, 31, + 41, 2, 27, 246, 30, 41, 2, 27, 246, 29, 41, 2, 27, 246, 28, 41, 2, 27, + 246, 27, 41, 2, 27, 246, 26, 41, 2, 27, 246, 25, 41, 2, 27, 246, 24, 41, + 2, 27, 246, 23, 41, 2, 27, 246, 22, 41, 2, 27, 246, 21, 41, 2, 27, 246, + 20, 41, 2, 27, 246, 19, 41, 2, 27, 246, 18, 41, 2, 27, 246, 17, 41, 2, + 27, 246, 16, 41, 2, 27, 246, 15, 41, 2, 27, 246, 14, 41, 2, 27, 246, 13, + 41, 2, 27, 246, 12, 41, 2, 27, 246, 11, 41, 2, 27, 246, 10, 41, 2, 27, + 246, 9, 41, 2, 27, 246, 8, 41, 2, 27, 246, 7, 41, 2, 27, 246, 6, 41, 2, + 27, 246, 5, 41, 2, 27, 246, 4, 41, 2, 27, 246, 3, 41, 2, 27, 246, 2, 41, + 2, 27, 246, 1, 41, 2, 27, 246, 0, 41, 2, 27, 245, 255, 41, 2, 27, 245, + 254, 41, 2, 27, 245, 253, 41, 2, 27, 245, 252, 41, 2, 27, 245, 251, 41, + 2, 27, 245, 250, 41, 2, 27, 245, 249, 41, 2, 27, 245, 248, 41, 2, 27, + 245, 247, 41, 2, 27, 245, 246, 41, 2, 27, 245, 245, 41, 2, 27, 245, 244, + 41, 2, 27, 245, 243, 41, 2, 27, 245, 242, 41, 2, 27, 245, 241, 41, 2, 27, + 245, 240, 41, 2, 27, 245, 239, 41, 2, 27, 245, 238, 41, 2, 27, 245, 237, + 41, 2, 27, 245, 236, 41, 2, 27, 245, 235, 41, 2, 27, 245, 234, 41, 2, 27, + 245, 233, 41, 2, 27, 245, 232, 41, 2, 27, 245, 231, 41, 2, 27, 245, 230, + 41, 2, 27, 245, 229, 41, 2, 27, 245, 228, 41, 2, 27, 245, 227, 41, 2, 27, + 245, 226, 41, 2, 27, 245, 225, 41, 2, 27, 245, 224, 41, 2, 27, 245, 223, + 41, 2, 27, 245, 222, 41, 2, 27, 245, 221, 41, 2, 27, 245, 220, 41, 2, 27, + 245, 219, 41, 2, 27, 245, 218, 41, 2, 27, 245, 217, 41, 2, 27, 245, 216, + 41, 2, 27, 245, 215, 41, 2, 27, 245, 214, 41, 2, 27, 245, 213, 41, 2, 27, + 245, 212, 41, 2, 27, 245, 211, 41, 2, 27, 245, 210, 41, 2, 27, 245, 209, + 41, 2, 27, 245, 208, 41, 2, 27, 245, 207, 41, 2, 27, 245, 206, 41, 2, 27, + 245, 205, 41, 2, 27, 245, 204, 41, 2, 27, 245, 203, 41, 2, 27, 245, 202, + 41, 2, 27, 245, 201, 41, 2, 27, 245, 200, 41, 2, 27, 245, 199, 41, 2, 27, + 245, 198, 41, 2, 27, 245, 197, 41, 2, 27, 245, 196, 41, 2, 27, 245, 195, + 41, 2, 27, 245, 194, 41, 2, 27, 245, 193, 41, 2, 27, 245, 192, 41, 2, 27, + 245, 191, 41, 2, 27, 245, 190, 41, 2, 27, 245, 189, 41, 2, 27, 245, 188, + 41, 2, 27, 245, 187, 41, 2, 27, 245, 186, 41, 2, 27, 245, 185, 41, 2, 27, + 245, 184, 41, 2, 27, 245, 183, 41, 2, 27, 245, 182, 41, 2, 27, 245, 181, + 41, 2, 27, 245, 180, 41, 2, 27, 245, 179, 41, 2, 27, 245, 178, 41, 2, 27, + 245, 177, 41, 2, 27, 245, 176, 41, 2, 27, 245, 175, 41, 2, 27, 245, 174, + 41, 2, 27, 245, 173, 41, 2, 27, 245, 172, 41, 2, 27, 245, 171, 41, 2, 27, + 245, 170, 41, 2, 27, 245, 169, 41, 2, 27, 245, 168, 41, 2, 27, 245, 167, + 41, 2, 27, 245, 166, 41, 2, 27, 245, 165, 41, 2, 27, 245, 164, 41, 2, 27, + 245, 163, 41, 2, 27, 245, 162, 41, 2, 27, 245, 161, 41, 2, 27, 245, 160, + 41, 2, 27, 245, 159, 41, 2, 27, 245, 158, 41, 2, 27, 245, 157, 41, 2, 27, + 245, 156, 41, 2, 27, 245, 155, 41, 2, 27, 245, 154, 41, 2, 27, 245, 153, + 41, 2, 27, 245, 152, 41, 2, 27, 245, 151, 41, 2, 27, 245, 150, 41, 2, 27, + 245, 149, 41, 2, 27, 245, 148, 41, 2, 27, 245, 147, 41, 2, 27, 245, 146, + 41, 2, 27, 245, 145, 41, 2, 27, 245, 144, 41, 2, 27, 245, 143, 41, 2, 27, + 245, 142, 41, 2, 27, 245, 141, 41, 2, 27, 245, 140, 41, 2, 27, 245, 139, + 41, 2, 27, 245, 138, 41, 2, 27, 245, 137, 41, 2, 27, 245, 136, 41, 2, 27, + 245, 135, 41, 2, 27, 245, 134, 41, 2, 27, 245, 133, 41, 2, 27, 245, 132, + 41, 2, 27, 245, 131, 41, 2, 27, 245, 130, 41, 2, 27, 245, 129, 41, 2, 27, + 245, 128, 41, 2, 27, 245, 127, 41, 2, 27, 245, 126, 41, 2, 27, 245, 125, + 41, 2, 27, 245, 124, 41, 2, 27, 245, 123, 41, 2, 27, 245, 122, 41, 2, 27, + 245, 121, 41, 2, 27, 245, 120, 41, 2, 27, 245, 119, 41, 2, 27, 245, 118, + 41, 2, 27, 245, 117, 41, 2, 27, 245, 116, 41, 2, 27, 245, 115, 41, 2, 27, + 245, 114, 41, 2, 27, 245, 113, 41, 2, 27, 245, 112, 41, 2, 27, 245, 111, + 41, 2, 27, 245, 110, 41, 2, 27, 245, 109, 41, 2, 27, 245, 108, 41, 2, 27, + 245, 107, 41, 2, 27, 245, 106, 41, 2, 27, 245, 105, 41, 2, 27, 245, 104, + 41, 2, 27, 245, 103, 41, 2, 27, 245, 102, 41, 2, 27, 245, 101, 41, 2, 27, + 245, 100, 41, 2, 27, 245, 99, 41, 2, 27, 245, 98, 41, 2, 27, 245, 97, 41, + 2, 27, 245, 96, 41, 2, 27, 245, 95, 41, 2, 27, 245, 94, 41, 2, 27, 245, + 93, 41, 2, 27, 245, 92, 41, 2, 27, 245, 91, 41, 2, 27, 245, 90, 41, 2, + 27, 245, 89, 41, 2, 27, 245, 88, 41, 2, 27, 245, 87, 41, 2, 27, 245, 86, + 41, 2, 27, 245, 85, 41, 2, 27, 245, 84, 41, 2, 27, 245, 83, 41, 2, 27, + 245, 82, 41, 2, 27, 245, 81, 41, 2, 27, 245, 80, 41, 2, 27, 245, 79, 41, + 2, 27, 245, 78, 41, 2, 27, 245, 77, 41, 2, 27, 245, 76, 41, 2, 27, 245, + 75, 41, 2, 27, 245, 74, 41, 2, 27, 245, 73, 41, 2, 27, 245, 72, 41, 2, + 27, 245, 71, 41, 2, 27, 245, 70, 41, 2, 27, 245, 69, 41, 2, 27, 245, 68, + 41, 2, 27, 245, 67, 41, 2, 27, 245, 66, 41, 2, 27, 245, 65, 41, 2, 27, + 245, 64, 41, 2, 27, 245, 63, 41, 2, 27, 245, 62, 41, 2, 27, 245, 61, 41, + 2, 27, 245, 60, 41, 2, 27, 245, 59, 41, 2, 27, 245, 58, 41, 2, 27, 245, + 57, 41, 2, 27, 245, 56, 41, 2, 27, 245, 55, 41, 2, 27, 245, 54, 41, 2, + 27, 245, 53, 41, 2, 27, 245, 52, 41, 2, 27, 245, 51, 41, 2, 27, 245, 50, + 41, 2, 27, 245, 49, 41, 2, 27, 245, 48, 41, 2, 27, 245, 47, 41, 2, 27, + 245, 46, 41, 2, 27, 245, 45, 41, 2, 27, 245, 44, 41, 2, 27, 245, 43, 41, + 2, 27, 245, 42, 41, 2, 27, 245, 41, 41, 2, 27, 245, 40, 41, 2, 27, 245, + 39, 41, 2, 27, 245, 38, 41, 2, 27, 245, 37, 41, 2, 27, 245, 36, 41, 2, + 27, 245, 35, 41, 2, 27, 245, 34, 41, 2, 27, 245, 33, 41, 2, 27, 245, 32, + 41, 2, 27, 245, 31, 41, 2, 27, 245, 30, 41, 2, 27, 245, 29, 41, 2, 27, + 245, 28, 41, 2, 27, 245, 27, 41, 2, 27, 245, 26, 41, 2, 27, 245, 25, 72, + 1, 216, 36, 198, 77, 72, 1, 216, 36, 198, 76, 72, 1, 216, 36, 198, 75, + 72, 1, 216, 36, 198, 74, 72, 1, 216, 36, 198, 72, 72, 1, 216, 36, 198, + 71, 72, 1, 216, 36, 214, 211, 198, 78, 72, 1, 216, 36, 214, 211, 198, 77, + 72, 1, 216, 36, 214, 211, 198, 76, 72, 1, 216, 36, 214, 211, 198, 75, 72, + 1, 216, 36, 214, 211, 198, 74, 72, 1, 216, 36, 214, 211, 198, 72, 72, 1, + 216, 36, 214, 211, 198, 71, 72, 1, 251, 14, 71, 229, 120, 1, 251, 14, + 192, 80, 61, 1, 255, 206, 61, 1, 255, 205, 61, 1, 255, 204, 61, 1, 255, + 200, 61, 1, 228, 73, 61, 1, 228, 72, 61, 1, 228, 71, 61, 1, 228, 70, 61, + 1, 196, 231, 61, 1, 196, 230, 61, 1, 196, 229, 61, 1, 196, 228, 61, 1, + 196, 227, 61, 1, 235, 13, 61, 1, 235, 12, 61, 1, 235, 11, 61, 1, 235, 10, + 61, 1, 235, 9, 61, 1, 212, 14, 61, 1, 212, 13, 61, 1, 212, 12, 61, 1, + 222, 141, 61, 1, 222, 138, 61, 1, 222, 137, 61, 1, 222, 136, 61, 1, 222, + 135, 61, 1, 222, 134, 61, 1, 222, 133, 61, 1, 222, 132, 61, 1, 222, 131, + 61, 1, 222, 140, 61, 1, 222, 139, 61, 1, 222, 130, 61, 1, 221, 165, 61, + 1, 221, 164, 61, 1, 221, 163, 61, 1, 221, 162, 61, 1, 221, 161, 61, 1, + 221, 160, 61, 1, 221, 159, 61, 1, 221, 158, 61, 1, 220, 231, 61, 1, 220, + 230, 61, 1, 220, 229, 61, 1, 220, 228, 61, 1, 220, 227, 61, 1, 220, 226, + 61, 1, 220, 225, 61, 1, 222, 21, 61, 1, 222, 20, 61, 1, 222, 19, 61, 1, + 222, 18, 61, 1, 222, 17, 61, 1, 222, 16, 61, 1, 221, 66, 61, 1, 221, 65, + 61, 1, 221, 64, 61, 1, 221, 63, 61, 1, 205, 206, 61, 1, 205, 205, 61, 1, + 205, 204, 61, 1, 205, 203, 61, 1, 205, 202, 61, 1, 205, 201, 61, 1, 205, + 200, 61, 1, 205, 199, 61, 1, 202, 221, 61, 1, 202, 220, 61, 1, 202, 219, + 61, 1, 202, 218, 61, 1, 202, 217, 61, 1, 202, 216, 61, 1, 201, 3, 61, 1, + 201, 2, 61, 1, 201, 1, 61, 1, 201, 0, 61, 1, 200, 255, 61, 1, 200, 254, + 61, 1, 200, 253, 61, 1, 200, 252, 61, 1, 205, 67, 61, 1, 205, 66, 61, 1, + 205, 65, 61, 1, 205, 64, 61, 1, 205, 63, 61, 1, 202, 45, 61, 1, 202, 44, + 61, 1, 202, 43, 61, 1, 202, 42, 61, 1, 202, 41, 61, 1, 202, 40, 61, 1, + 202, 39, 61, 1, 199, 251, 61, 1, 199, 250, 61, 1, 199, 249, 61, 1, 199, + 248, 61, 1, 198, 192, 61, 1, 198, 191, 61, 1, 198, 190, 61, 1, 198, 189, + 61, 1, 198, 188, 61, 1, 198, 187, 61, 1, 198, 186, 61, 1, 197, 93, 61, 1, + 197, 92, 61, 1, 197, 91, 61, 1, 197, 90, 61, 1, 197, 89, 61, 1, 199, 144, + 61, 1, 199, 143, 61, 1, 199, 142, 61, 1, 199, 141, 61, 1, 199, 140, 61, + 1, 199, 139, 61, 1, 199, 138, 61, 1, 199, 137, 61, 1, 199, 136, 61, 1, + 198, 98, 61, 1, 198, 97, 61, 1, 198, 96, 61, 1, 198, 95, 61, 1, 198, 94, + 61, 1, 198, 93, 61, 1, 198, 92, 61, 1, 215, 6, 61, 1, 215, 5, 61, 1, 215, + 4, 61, 1, 215, 3, 61, 1, 215, 2, 61, 1, 215, 1, 61, 1, 215, 0, 61, 1, + 214, 255, 61, 1, 214, 254, 61, 1, 213, 218, 61, 1, 213, 217, 61, 1, 213, + 216, 61, 1, 213, 215, 61, 1, 213, 214, 61, 1, 213, 213, 61, 1, 213, 212, + 61, 1, 213, 211, 61, 1, 212, 177, 61, 1, 212, 176, 61, 1, 212, 175, 61, + 1, 214, 120, 61, 1, 214, 119, 61, 1, 214, 118, 61, 1, 214, 117, 61, 1, + 214, 116, 61, 1, 214, 115, 61, 1, 214, 114, 61, 1, 213, 42, 61, 1, 213, + 41, 61, 1, 213, 40, 61, 1, 213, 39, 61, 1, 213, 38, 61, 1, 230, 104, 61, + 1, 230, 101, 61, 1, 230, 100, 61, 1, 230, 99, 61, 1, 230, 98, 61, 1, 230, + 97, 61, 1, 230, 96, 61, 1, 230, 95, 61, 1, 230, 94, 61, 1, 230, 103, 61, + 1, 230, 102, 61, 1, 229, 157, 61, 1, 229, 156, 61, 1, 229, 155, 61, 1, + 229, 154, 61, 1, 229, 153, 61, 1, 229, 152, 61, 1, 229, 151, 61, 1, 228, + 158, 61, 1, 228, 157, 61, 1, 228, 156, 61, 1, 229, 244, 61, 1, 229, 243, + 61, 1, 229, 242, 61, 1, 229, 241, 61, 1, 229, 240, 61, 1, 229, 239, 61, + 1, 229, 238, 61, 1, 229, 22, 61, 1, 229, 21, 61, 1, 229, 20, 61, 1, 229, + 19, 61, 1, 229, 18, 61, 1, 229, 17, 61, 1, 229, 16, 61, 1, 229, 15, 61, + 1, 217, 159, 61, 1, 217, 158, 61, 1, 217, 157, 61, 1, 217, 156, 61, 1, + 217, 155, 61, 1, 217, 154, 61, 1, 217, 153, 61, 1, 216, 99, 61, 1, 216, + 98, 61, 1, 216, 97, 61, 1, 216, 96, 61, 1, 216, 95, 61, 1, 216, 94, 61, + 1, 216, 93, 61, 1, 215, 154, 61, 1, 215, 153, 61, 1, 215, 152, 61, 1, + 215, 151, 61, 1, 216, 231, 61, 1, 216, 230, 61, 1, 216, 229, 61, 1, 216, + 11, 61, 1, 216, 10, 61, 1, 216, 9, 61, 1, 216, 8, 61, 1, 216, 7, 61, 1, + 216, 6, 61, 1, 192, 148, 61, 1, 192, 147, 61, 1, 192, 146, 61, 1, 192, + 145, 61, 1, 192, 144, 61, 1, 192, 141, 61, 1, 191, 224, 61, 1, 191, 223, + 61, 1, 191, 222, 61, 1, 191, 221, 61, 1, 192, 11, 61, 1, 192, 10, 61, 1, + 192, 9, 61, 1, 192, 8, 61, 1, 192, 7, 61, 1, 192, 6, 61, 1, 207, 185, 61, + 1, 207, 184, 61, 1, 207, 183, 61, 1, 207, 182, 61, 1, 207, 0, 61, 1, 206, + 255, 61, 1, 206, 254, 61, 1, 206, 253, 61, 1, 206, 252, 61, 1, 206, 251, + 61, 1, 206, 250, 61, 1, 206, 67, 61, 1, 206, 66, 61, 1, 206, 65, 61, 1, + 206, 64, 61, 1, 206, 63, 61, 1, 206, 62, 61, 1, 207, 112, 61, 1, 207, + 111, 61, 1, 207, 110, 61, 1, 207, 109, 61, 1, 206, 161, 61, 1, 206, 160, + 61, 1, 206, 159, 61, 1, 206, 158, 61, 1, 206, 157, 61, 1, 206, 156, 61, + 1, 193, 189, 61, 1, 193, 188, 61, 1, 193, 187, 61, 1, 193, 186, 61, 1, + 193, 185, 61, 1, 193, 85, 61, 1, 193, 84, 61, 1, 193, 83, 61, 1, 193, 82, + 61, 1, 193, 81, 61, 1, 193, 124, 61, 1, 193, 123, 61, 1, 193, 122, 61, 1, + 193, 121, 61, 1, 193, 47, 61, 1, 193, 46, 61, 1, 193, 45, 61, 1, 193, 44, + 61, 1, 193, 43, 61, 1, 193, 42, 61, 1, 193, 41, 61, 1, 215, 58, 61, 1, + 215, 57, 229, 120, 1, 251, 14, 193, 0, 72, 1, 251, 14, 192, 33, 72, 1, + 251, 14, 192, 80, 72, 1, 251, 14, 193, 0, 229, 120, 1, 2, 221, 67, 229, + 120, 1, 2, 193, 86, 229, 120, 1, 2, 193, 125, 229, 120, 1, 2, 193, 48, + 72, 1, 2, 221, 67, 72, 1, 2, 193, 86, 72, 1, 2, 193, 125, 72, 1, 2, 193, + 48, 72, 1, 2, 215, 61, 46, 245, 24, 46, 245, 23, 46, 245, 22, 46, 245, + 21, 46, 245, 20, 46, 245, 19, 46, 245, 18, 46, 245, 17, 46, 245, 16, 46, + 245, 15, 46, 245, 14, 46, 245, 13, 46, 245, 12, 46, 245, 11, 46, 245, 10, + 46, 245, 9, 46, 245, 8, 46, 245, 7, 46, 245, 6, 46, 245, 5, 46, 245, 4, + 46, 245, 3, 46, 245, 2, 46, 245, 1, 46, 245, 0, 46, 244, 255, 46, 244, + 254, 46, 244, 253, 46, 244, 252, 46, 244, 251, 46, 244, 250, 46, 244, + 249, 46, 244, 248, 46, 244, 247, 46, 244, 246, 46, 244, 245, 46, 244, + 244, 46, 244, 243, 46, 244, 242, 46, 244, 241, 46, 244, 240, 46, 244, + 239, 46, 244, 238, 46, 244, 237, 46, 244, 236, 46, 244, 235, 46, 244, + 234, 46, 244, 233, 46, 244, 232, 46, 244, 231, 46, 244, 230, 46, 244, + 229, 46, 244, 228, 46, 244, 227, 46, 244, 226, 46, 244, 225, 46, 244, + 224, 46, 244, 223, 46, 244, 222, 46, 244, 221, 46, 244, 220, 46, 244, + 219, 46, 244, 218, 46, 244, 217, 46, 244, 216, 46, 244, 215, 46, 244, + 214, 46, 244, 213, 46, 244, 212, 46, 244, 211, 46, 244, 210, 46, 244, + 209, 46, 244, 208, 46, 244, 207, 46, 244, 206, 46, 244, 205, 46, 244, + 204, 46, 244, 203, 46, 244, 202, 46, 244, 201, 46, 244, 200, 46, 244, + 199, 46, 244, 198, 46, 244, 197, 46, 244, 196, 46, 244, 195, 46, 244, + 194, 46, 244, 193, 46, 244, 192, 46, 244, 191, 46, 244, 190, 46, 244, + 189, 46, 244, 188, 46, 244, 187, 46, 244, 186, 46, 244, 185, 46, 244, + 184, 46, 244, 183, 46, 244, 182, 46, 244, 181, 46, 244, 180, 46, 244, + 179, 46, 244, 178, 46, 244, 177, 46, 244, 176, 46, 244, 175, 46, 244, + 174, 46, 244, 173, 46, 244, 172, 46, 244, 171, 46, 244, 170, 46, 244, + 169, 46, 244, 168, 46, 244, 167, 46, 244, 166, 46, 244, 165, 46, 244, + 164, 46, 244, 163, 46, 244, 162, 46, 244, 161, 46, 244, 160, 46, 244, + 159, 46, 244, 158, 46, 244, 157, 46, 244, 156, 46, 244, 155, 46, 244, + 154, 46, 244, 153, 46, 244, 152, 46, 244, 151, 46, 244, 150, 46, 244, + 149, 46, 244, 148, 46, 244, 147, 46, 244, 146, 46, 244, 145, 46, 244, + 144, 46, 244, 143, 46, 244, 142, 46, 244, 141, 46, 244, 140, 46, 244, + 139, 46, 244, 138, 46, 244, 137, 46, 244, 136, 46, 244, 135, 46, 244, + 134, 46, 244, 133, 46, 244, 132, 46, 244, 131, 46, 244, 130, 46, 244, + 129, 46, 244, 128, 46, 244, 127, 46, 244, 126, 46, 244, 125, 46, 244, + 124, 46, 244, 123, 46, 244, 122, 46, 244, 121, 46, 244, 120, 46, 244, + 119, 46, 244, 118, 46, 244, 117, 46, 244, 116, 46, 244, 115, 46, 244, + 114, 46, 244, 113, 46, 244, 112, 46, 244, 111, 46, 244, 110, 46, 244, + 109, 46, 244, 108, 46, 244, 107, 46, 244, 106, 46, 244, 105, 46, 244, + 104, 46, 244, 103, 46, 244, 102, 46, 244, 101, 46, 244, 100, 46, 244, 99, + 46, 244, 98, 46, 244, 97, 46, 244, 96, 46, 244, 95, 46, 244, 94, 46, 244, + 93, 46, 244, 92, 46, 244, 91, 46, 244, 90, 46, 244, 89, 46, 244, 88, 46, + 244, 87, 46, 244, 86, 46, 244, 85, 46, 244, 84, 46, 244, 83, 46, 244, 82, + 46, 244, 81, 46, 244, 80, 46, 244, 79, 46, 244, 78, 46, 244, 77, 46, 244, + 76, 46, 244, 75, 46, 244, 74, 46, 244, 73, 46, 244, 72, 46, 244, 71, 46, + 244, 70, 46, 244, 69, 46, 244, 68, 46, 244, 67, 46, 244, 66, 46, 244, 65, + 46, 244, 64, 46, 244, 63, 46, 244, 62, 46, 244, 61, 46, 244, 60, 46, 244, + 59, 46, 244, 58, 46, 244, 57, 46, 244, 56, 46, 244, 55, 46, 244, 54, 46, + 244, 53, 46, 244, 52, 46, 244, 51, 46, 244, 50, 46, 244, 49, 46, 244, 48, + 46, 244, 47, 46, 244, 46, 46, 244, 45, 46, 244, 44, 46, 244, 43, 46, 244, + 42, 46, 244, 41, 46, 244, 40, 46, 244, 39, 46, 244, 38, 46, 244, 37, 46, + 244, 36, 46, 244, 35, 46, 244, 34, 46, 244, 33, 46, 244, 32, 46, 244, 31, + 46, 244, 30, 46, 244, 29, 46, 244, 28, 46, 244, 27, 46, 244, 26, 46, 244, + 25, 46, 244, 24, 46, 244, 23, 46, 244, 22, 46, 244, 21, 46, 244, 20, 46, + 244, 19, 46, 244, 18, 46, 244, 17, 46, 244, 16, 46, 244, 15, 46, 244, 14, + 46, 244, 13, 46, 244, 12, 46, 244, 11, 46, 244, 10, 46, 244, 9, 46, 244, + 8, 46, 244, 7, 46, 244, 6, 46, 244, 5, 46, 244, 4, 46, 244, 3, 46, 244, + 2, 46, 244, 1, 46, 244, 0, 46, 243, 255, 46, 243, 254, 46, 243, 253, 46, + 243, 252, 46, 243, 251, 46, 243, 250, 46, 243, 249, 46, 243, 248, 46, + 243, 247, 46, 243, 246, 46, 243, 245, 46, 243, 244, 46, 243, 243, 46, + 243, 242, 46, 243, 241, 46, 243, 240, 46, 243, 239, 46, 243, 238, 46, + 243, 237, 46, 243, 236, 46, 243, 235, 46, 243, 234, 46, 243, 233, 46, + 243, 232, 46, 243, 231, 46, 243, 230, 46, 243, 229, 46, 243, 228, 46, + 243, 227, 46, 243, 226, 46, 243, 225, 46, 243, 224, 46, 243, 223, 46, + 243, 222, 46, 243, 221, 46, 243, 220, 46, 243, 219, 46, 243, 218, 46, + 243, 217, 46, 243, 216, 46, 243, 215, 46, 243, 214, 46, 243, 213, 46, + 243, 212, 46, 243, 211, 46, 243, 210, 46, 243, 209, 46, 243, 208, 46, + 243, 207, 46, 243, 206, 46, 243, 205, 46, 243, 204, 46, 243, 203, 46, + 243, 202, 46, 243, 201, 46, 243, 200, 46, 243, 199, 46, 243, 198, 46, + 243, 197, 46, 243, 196, 46, 243, 195, 46, 243, 194, 46, 243, 193, 46, + 243, 192, 46, 243, 191, 46, 243, 190, 46, 243, 189, 46, 243, 188, 46, + 243, 187, 46, 243, 186, 46, 243, 185, 46, 243, 184, 46, 243, 183, 46, + 243, 182, 46, 243, 181, 46, 243, 180, 46, 243, 179, 46, 243, 178, 46, + 243, 177, 46, 243, 176, 46, 243, 175, 46, 243, 174, 46, 243, 173, 46, + 243, 172, 46, 243, 171, 46, 243, 170, 46, 243, 169, 46, 243, 168, 46, + 243, 167, 46, 243, 166, 46, 243, 165, 46, 243, 164, 46, 243, 163, 46, + 243, 162, 46, 243, 161, 46, 243, 160, 46, 243, 159, 46, 243, 158, 46, + 243, 157, 46, 243, 156, 46, 243, 155, 46, 243, 154, 46, 243, 153, 46, + 243, 152, 46, 243, 151, 46, 243, 150, 46, 243, 149, 46, 243, 148, 46, + 243, 147, 46, 243, 146, 46, 243, 145, 46, 243, 144, 46, 243, 143, 46, + 243, 142, 46, 243, 141, 124, 1, 230, 116, 124, 1, 192, 235, 124, 1, 210, + 236, 124, 1, 200, 43, 124, 1, 233, 175, 124, 1, 222, 152, 124, 1, 172, + 124, 1, 250, 120, 124, 1, 238, 127, 124, 1, 196, 12, 124, 1, 232, 51, + 124, 1, 146, 124, 1, 210, 237, 215, 61, 124, 1, 238, 128, 206, 8, 124, 1, + 233, 176, 215, 61, 124, 1, 222, 153, 218, 168, 124, 1, 207, 222, 206, 8, + 124, 1, 199, 51, 124, 1, 202, 82, 237, 69, 124, 1, 237, 69, 124, 1, 221, + 102, 124, 1, 202, 82, 223, 35, 124, 1, 229, 112, 124, 1, 219, 160, 124, + 1, 207, 7, 124, 1, 218, 168, 124, 1, 215, 61, 124, 1, 223, 35, 124, 1, + 206, 8, 124, 1, 218, 169, 215, 61, 124, 1, 215, 62, 218, 168, 124, 1, + 223, 36, 218, 168, 124, 1, 206, 9, 223, 35, 124, 1, 218, 169, 4, 236, + 140, 124, 1, 215, 62, 4, 236, 140, 124, 1, 223, 36, 4, 236, 140, 124, 1, + 223, 36, 4, 185, 223, 118, 23, 58, 124, 1, 206, 9, 4, 236, 140, 124, 1, + 206, 9, 4, 75, 60, 124, 1, 218, 169, 206, 8, 124, 1, 215, 62, 206, 8, + 124, 1, 223, 36, 206, 8, 124, 1, 206, 9, 206, 8, 124, 1, 218, 169, 215, + 62, 206, 8, 124, 1, 215, 62, 218, 169, 206, 8, 124, 1, 223, 36, 218, 169, + 206, 8, 124, 1, 206, 9, 223, 36, 206, 8, 124, 1, 223, 36, 206, 9, 4, 236, + 140, 124, 1, 223, 36, 215, 61, 124, 1, 223, 36, 215, 62, 206, 8, 124, 1, + 206, 9, 200, 43, 124, 1, 206, 9, 200, 44, 146, 124, 1, 206, 9, 210, 236, + 124, 1, 206, 9, 210, 237, 146, 124, 1, 200, 44, 206, 8, 124, 1, 200, 44, + 207, 222, 206, 8, 124, 1, 193, 224, 124, 1, 193, 97, 124, 1, 193, 225, + 146, 124, 1, 206, 9, 215, 61, 124, 1, 206, 9, 218, 168, 124, 1, 222, 153, + 207, 222, 206, 8, 124, 1, 232, 52, 207, 222, 206, 8, 124, 1, 206, 9, 222, + 152, 124, 1, 206, 9, 222, 153, 146, 124, 1, 65, 124, 1, 202, 82, 210, + 250, 124, 1, 211, 182, 124, 1, 74, 124, 1, 251, 66, 124, 1, 68, 124, 1, + 71, 124, 1, 223, 226, 124, 1, 203, 40, 68, 124, 1, 196, 139, 124, 1, 234, + 188, 124, 1, 202, 82, 234, 173, 124, 1, 206, 135, 68, 124, 1, 202, 82, + 234, 188, 124, 1, 179, 68, 124, 1, 192, 80, 124, 1, 66, 124, 1, 233, 242, + 124, 1, 192, 182, 124, 1, 126, 215, 61, 124, 1, 179, 66, 124, 1, 206, + 135, 66, 124, 1, 196, 141, 124, 1, 202, 82, 66, 124, 1, 211, 84, 124, 1, + 210, 250, 124, 1, 211, 19, 124, 1, 193, 190, 124, 1, 193, 48, 124, 1, + 193, 86, 124, 1, 193, 112, 124, 1, 193, 14, 124, 1, 214, 214, 66, 124, 1, + 214, 214, 74, 124, 1, 214, 214, 68, 124, 1, 214, 214, 65, 124, 1, 210, 0, + 251, 132, 124, 1, 210, 0, 251, 149, 124, 1, 202, 82, 234, 103, 124, 1, + 202, 82, 251, 132, 124, 1, 202, 82, 211, 104, 124, 1, 117, 218, 168, 124, + 252, 4, 45, 228, 241, 205, 58, 124, 252, 4, 216, 87, 228, 241, 205, 58, + 124, 252, 4, 50, 228, 241, 205, 58, 124, 252, 4, 130, 81, 205, 58, 124, + 252, 4, 216, 87, 81, 205, 58, 124, 252, 4, 137, 81, 205, 58, 124, 252, 4, + 250, 170, 205, 58, 124, 252, 4, 250, 170, 219, 215, 205, 58, 124, 252, 4, + 250, 170, 199, 188, 124, 252, 4, 250, 170, 199, 215, 124, 252, 4, 250, + 170, 235, 15, 102, 124, 252, 4, 250, 170, 228, 74, 102, 124, 252, 4, 250, + 170, 199, 189, 102, 124, 252, 4, 137, 252, 46, 124, 252, 4, 137, 198, + 172, 252, 46, 124, 252, 4, 137, 230, 210, 124, 252, 4, 137, 179, 230, + 210, 124, 252, 4, 137, 236, 140, 124, 252, 4, 137, 243, 10, 124, 252, 4, + 137, 219, 112, 124, 252, 4, 137, 193, 138, 124, 252, 4, 137, 195, 135, + 124, 252, 4, 130, 252, 46, 124, 252, 4, 130, 198, 172, 252, 46, 124, 252, + 4, 130, 230, 210, 124, 252, 4, 130, 179, 230, 210, 124, 252, 4, 130, 236, + 140, 124, 252, 4, 130, 243, 10, 124, 252, 4, 130, 219, 112, 124, 252, 4, + 130, 193, 138, 124, 252, 4, 130, 195, 135, 124, 252, 4, 130, 57, 124, 3, + 187, 4, 238, 217, 124, 199, 9, 1, 205, 34, 124, 55, 77, 124, 208, 152, + 243, 78, 232, 80, 201, 63, 203, 27, 232, 145, 1, 211, 2, 203, 27, 232, + 145, 239, 28, 211, 2, 203, 27, 232, 145, 144, 201, 78, 203, 27, 232, 145, + 133, 201, 78, 97, 33, 87, 230, 240, 213, 159, 206, 9, 220, 251, 211, 105, + 219, 224, 97, 33, 87, 213, 159, 206, 9, 220, 251, 211, 105, 219, 224, 97, + 33, 87, 197, 162, 211, 105, 219, 224, 97, 33, 87, 230, 240, 213, 159, + 211, 105, 219, 224, 97, 33, 87, 213, 159, 211, 105, 219, 224, 97, 33, 87, + 201, 179, 211, 105, 219, 224, 97, 33, 87, 217, 94, 209, 3, 211, 105, 219, + 224, 97, 33, 87, 209, 3, 211, 105, 219, 224, 97, 33, 87, 193, 231, 211, + 105, 219, 224, 97, 33, 87, 217, 94, 209, 3, 206, 9, 221, 181, 211, 105, + 219, 224, 97, 33, 87, 209, 3, 206, 9, 221, 181, 211, 105, 219, 224, 97, + 33, 87, 193, 231, 206, 9, 221, 181, 211, 105, 219, 224, 97, 33, 87, 230, + 240, 213, 159, 206, 9, 220, 251, 211, 105, 183, 97, 33, 87, 213, 159, + 206, 9, 220, 251, 211, 105, 183, 97, 33, 87, 197, 162, 211, 105, 183, 97, + 33, 87, 230, 240, 213, 159, 211, 105, 183, 97, 33, 87, 213, 159, 211, + 105, 183, 97, 33, 87, 201, 179, 211, 105, 183, 97, 33, 87, 217, 94, 209, + 3, 211, 105, 183, 97, 33, 87, 209, 3, 211, 105, 183, 97, 33, 87, 193, + 231, 211, 105, 183, 97, 33, 87, 217, 94, 209, 3, 206, 9, 221, 181, 211, + 105, 183, 97, 33, 87, 209, 3, 206, 9, 221, 181, 211, 105, 183, 97, 33, + 87, 193, 231, 206, 9, 221, 181, 211, 105, 183, 97, 33, 87, 197, 162, 206, + 9, 220, 250, 97, 33, 87, 217, 94, 209, 3, 206, 9, 220, 250, 97, 33, 87, + 201, 49, 217, 94, 209, 2, 97, 33, 87, 209, 3, 206, 9, 220, 250, 97, 33, + 87, 209, 3, 201, 48, 97, 33, 87, 193, 231, 206, 9, 220, 250, 97, 33, 87, + 217, 94, 209, 3, 201, 48, 97, 33, 87, 230, 240, 193, 230, 97, 33, 87, + 191, 83, 97, 33, 87, 211, 104, 97, 33, 87, 207, 124, 97, 33, 87, 198, + 157, 97, 33, 87, 248, 83, 97, 33, 87, 196, 156, 97, 33, 87, 209, 65, 97, + 33, 87, 219, 21, 97, 33, 87, 220, 200, 97, 33, 87, 222, 115, 97, 33, 87, + 191, 74, 97, 33, 87, 202, 105, 97, 33, 87, 207, 117, 97, 33, 87, 220, + 253, 211, 105, 219, 224, 97, 33, 198, 80, 207, 137, 87, 215, 162, 97, 33, + 198, 80, 207, 137, 87, 200, 153, 97, 33, 198, 80, 207, 137, 87, 197, 246, + 97, 33, 87, 191, 120, 97, 33, 87, 237, 105, 191, 120, 97, 33, 87, 211, + 25, 97, 33, 87, 209, 67, 97, 33, 87, 209, 68, 4, 81, 106, 97, 33, 87, + 243, 134, 97, 33, 87, 243, 135, 209, 45, 97, 33, 87, 211, 174, 97, 33, + 87, 202, 10, 212, 249, 97, 33, 87, 198, 89, 97, 33, 87, 235, 48, 97, 33, + 250, 169, 81, 211, 109, 97, 33, 87, 238, 163, 211, 109, 97, 33, 87, 220, + 252, 97, 33, 110, 198, 80, 207, 137, 223, 144, 97, 208, 203, 52, 219, + 167, 97, 208, 203, 52, 219, 166, 97, 208, 203, 52, 236, 233, 232, 195, + 97, 208, 203, 52, 220, 252, 97, 208, 203, 52, 206, 144, 97, 161, 221, 0, + 97, 161, 221, 1, 198, 156, 97, 161, 210, 122, 97, 161, 235, 56, 196, 13, + 243, 113, 97, 161, 221, 90, 97, 161, 191, 105, 97, 161, 201, 61, 97, 161, + 201, 62, 206, 9, 211, 163, 97, 161, 210, 10, 97, 161, 210, 11, 214, 96, + 97, 161, 201, 62, 4, 202, 10, 212, 249, 97, 161, 243, 112, 97, 161, 210, + 186, 97, 161, 191, 103, 97, 161, 230, 248, 248, 82, 97, 161, 230, 248, + 198, 156, 97, 161, 230, 248, 215, 160, 97, 161, 230, 248, 200, 152, 97, + 161, 230, 248, 197, 245, 97, 161, 194, 253, 208, 183, 97, 161, 194, 253, + 215, 163, 97, 161, 194, 253, 200, 154, 97, 161, 194, 253, 197, 247, 97, + 161, 194, 253, 221, 85, 208, 183, 97, 161, 194, 253, 221, 85, 215, 163, + 97, 161, 194, 253, 221, 85, 200, 154, 97, 161, 194, 253, 221, 85, 197, + 247, 97, 161, 55, 191, 103, 97, 161, 207, 18, 243, 112, 97, 161, 237, 91, + 97, 161, 221, 207, 97, 161, 243, 134, 97, 161, 209, 67, 97, 161, 202, + 113, 215, 163, 97, 161, 202, 113, 200, 154, 97, 161, 202, 113, 197, 247, + 97, 161, 202, 113, 198, 157, 97, 161, 237, 105, 221, 90, 97, 161, 202, + 113, 221, 85, 200, 154, 97, 161, 202, 113, 221, 89, 97, 161, 202, 113, + 221, 85, 198, 157, 97, 161, 202, 113, 235, 53, 208, 183, 97, 161, 202, + 113, 235, 53, 200, 154, 97, 161, 202, 113, 235, 53, 214, 96, 97, 161, + 202, 113, 235, 53, 221, 84, 97, 161, 202, 72, 97, 161, 202, 73, 206, 9, + 191, 101, 97, 161, 202, 73, 191, 110, 97, 161, 202, 73, 206, 9, 220, 250, + 97, 161, 220, 252, 97, 161, 206, 144, 97, 161, 232, 228, 97, 161, 221, + 59, 97, 161, 191, 8, 97, 161, 201, 90, 97, 161, 201, 91, 206, 9, 191, + 101, 97, 161, 201, 91, 206, 9, 220, 250, 97, 161, 201, 91, 206, 9, 191, + 102, 228, 74, 220, 250, 97, 161, 201, 91, 206, 9, 220, 251, 228, 74, 191, + 101, 97, 161, 201, 91, 191, 111, 97, 161, 201, 91, 191, 112, 206, 9, 191, + 101, 97, 161, 201, 91, 206, 9, 206, 143, 97, 161, 201, 91, 206, 9, 235, + 47, 191, 100, 97, 161, 201, 91, 206, 9, 191, 102, 228, 74, 209, 66, 97, + 161, 209, 47, 97, 161, 201, 91, 214, 96, 97, 161, 201, 40, 208, 183, 97, + 161, 201, 40, 215, 161, 97, 161, 201, 40, 220, 249, 97, 161, 201, 40, + 209, 43, 97, 161, 201, 40, 209, 5, 97, 161, 201, 40, 214, 96, 97, 161, + 201, 40, 221, 87, 97, 161, 201, 40, 221, 89, 97, 161, 201, 40, 198, 158, + 208, 130, 97, 161, 201, 40, 235, 52, 97, 161, 201, 40, 235, 51, 97, 161, + 201, 40, 235, 49, 97, 161, 201, 40, 235, 53, 221, 84, 97, 161, 201, 40, + 235, 50, 221, 84, 97, 161, 201, 40, 230, 195, 4, 202, 170, 191, 103, 97, + 161, 201, 40, 230, 191, 4, 202, 170, 191, 103, 97, 161, 201, 40, 230, + 194, 97, 161, 201, 40, 230, 190, 97, 161, 201, 40, 230, 191, 4, 55, 191, + 103, 97, 161, 201, 40, 230, 192, 97, 161, 201, 40, 230, 193, 209, 5, 97, + 161, 216, 221, 97, 161, 216, 222, 209, 4, 97, 161, 216, 222, 221, 83, 97, + 161, 216, 222, 221, 86, 97, 161, 216, 222, 221, 88, 97, 161, 201, 40, + 197, 174, 97, 161, 201, 40, 197, 173, 97, 161, 201, 40, 197, 172, 97, + 161, 211, 31, 97, 161, 211, 32, 200, 154, 97, 161, 211, 32, 197, 247, 97, + 161, 211, 32, 220, 255, 200, 154, 97, 161, 211, 32, 221, 85, 200, 154, + 97, 161, 211, 32, 221, 85, 214, 96, 97, 161, 201, 40, 220, 254, 97, 161, + 201, 40, 220, 255, 209, 5, 97, 161, 201, 40, 220, 255, 230, 195, 4, 202, + 170, 191, 103, 97, 161, 201, 40, 220, 255, 230, 191, 4, 202, 170, 191, + 103, 97, 161, 201, 40, 220, 255, 230, 194, 97, 161, 201, 40, 220, 255, + 230, 190, 97, 161, 201, 40, 220, 255, 230, 191, 4, 55, 191, 103, 97, 161, + 201, 40, 220, 255, 230, 192, 97, 161, 201, 40, 220, 255, 230, 193, 209, + 5, 97, 161, 201, 40, 220, 255, 197, 175, 97, 161, 220, 214, 97, 161, 211, + 173, 97, 161, 235, 84, 97, 161, 214, 103, 97, 161, 210, 79, 73, 37, 16, + 208, 169, 73, 37, 16, 237, 217, 73, 37, 16, 210, 4, 73, 37, 16, 210, 246, + 234, 144, 73, 37, 16, 210, 246, 236, 238, 73, 37, 16, 195, 172, 234, 144, + 73, 37, 16, 195, 172, 236, 238, 73, 37, 16, 222, 44, 73, 37, 16, 200, 60, + 73, 37, 16, 210, 120, 73, 37, 16, 191, 231, 73, 37, 16, 191, 232, 236, + 238, 73, 37, 16, 221, 3, 73, 37, 16, 251, 61, 234, 144, 73, 37, 16, 233, + 210, 234, 144, 73, 37, 16, 199, 108, 73, 37, 16, 221, 247, 73, 37, 16, + 251, 50, 73, 37, 16, 251, 51, 236, 238, 73, 37, 16, 200, 67, 73, 37, 16, + 198, 244, 73, 37, 16, 211, 116, 251, 12, 73, 37, 16, 230, 238, 251, 12, + 73, 37, 16, 208, 168, 73, 37, 16, 246, 248, 73, 37, 16, 195, 161, 73, 37, + 16, 223, 58, 251, 12, 73, 37, 16, 221, 249, 251, 12, 73, 37, 16, 221, + 248, 251, 12, 73, 37, 16, 205, 105, 73, 37, 16, 210, 110, 73, 37, 16, + 201, 88, 251, 54, 73, 37, 16, 210, 245, 251, 12, 73, 37, 16, 195, 171, + 251, 12, 73, 37, 16, 251, 55, 251, 12, 73, 37, 16, 251, 48, 73, 37, 16, + 221, 92, 73, 37, 16, 207, 14, 73, 37, 16, 209, 183, 251, 12, 73, 37, 16, + 198, 142, 73, 37, 16, 251, 128, 73, 37, 16, 205, 37, 73, 37, 16, 200, 71, + 251, 12, 73, 37, 16, 200, 71, 216, 166, 201, 86, 73, 37, 16, 210, 240, + 251, 12, 73, 37, 16, 199, 27, 73, 37, 16, 219, 202, 73, 37, 16, 235, 38, + 73, 37, 16, 197, 243, 73, 37, 16, 199, 76, 73, 37, 16, 221, 6, 73, 37, + 16, 251, 61, 233, 210, 214, 98, 73, 37, 16, 232, 88, 251, 12, 73, 37, 16, + 223, 175, 73, 37, 16, 197, 210, 251, 12, 73, 37, 16, 222, 47, 197, 209, + 73, 37, 16, 210, 36, 73, 37, 16, 208, 173, 73, 37, 16, 221, 42, 73, 37, + 16, 243, 60, 251, 12, 73, 37, 16, 207, 135, 73, 37, 16, 210, 124, 251, + 12, 73, 37, 16, 210, 121, 251, 12, 73, 37, 16, 228, 24, 73, 37, 16, 214, + 225, 73, 37, 16, 209, 238, 73, 37, 16, 221, 43, 251, 167, 73, 37, 16, + 197, 210, 251, 167, 73, 37, 16, 201, 55, 73, 37, 16, 230, 189, 73, 37, + 16, 223, 58, 214, 98, 73, 37, 16, 211, 116, 214, 98, 73, 37, 16, 210, + 246, 214, 98, 73, 37, 16, 209, 237, 73, 37, 16, 221, 26, 73, 37, 16, 209, + 236, 73, 37, 16, 221, 5, 73, 37, 16, 210, 37, 214, 98, 73, 37, 16, 221, + 248, 214, 99, 251, 93, 73, 37, 16, 221, 249, 214, 99, 251, 93, 73, 37, + 16, 191, 229, 73, 37, 16, 251, 51, 214, 98, 73, 37, 16, 251, 52, 200, 68, + 214, 98, 73, 37, 16, 191, 230, 73, 37, 16, 221, 4, 73, 37, 16, 234, 139, + 73, 37, 16, 246, 249, 73, 37, 16, 216, 57, 223, 57, 73, 37, 16, 195, 172, + 214, 98, 73, 37, 16, 209, 183, 214, 98, 73, 37, 16, 208, 174, 214, 98, + 73, 37, 16, 211, 112, 73, 37, 16, 251, 80, 73, 37, 16, 218, 179, 73, 37, + 16, 210, 121, 214, 98, 73, 37, 16, 210, 124, 214, 98, 73, 37, 16, 233, + 249, 210, 123, 73, 37, 16, 220, 147, 73, 37, 16, 251, 81, 73, 37, 16, + 197, 210, 214, 98, 73, 37, 16, 234, 142, 73, 37, 16, 200, 71, 214, 98, + 73, 37, 16, 200, 61, 73, 37, 16, 243, 60, 214, 98, 73, 37, 16, 234, 53, + 73, 37, 16, 205, 38, 214, 98, 73, 37, 16, 192, 199, 221, 92, 73, 37, 16, + 197, 207, 73, 37, 16, 208, 175, 73, 37, 16, 197, 211, 73, 37, 16, 197, + 208, 73, 37, 16, 208, 172, 73, 37, 16, 197, 206, 73, 37, 16, 208, 171, + 73, 37, 16, 230, 237, 73, 37, 16, 251, 4, 73, 37, 16, 233, 249, 251, 4, + 73, 37, 16, 210, 240, 214, 98, 73, 37, 16, 199, 26, 234, 6, 73, 37, 16, + 199, 26, 233, 209, 73, 37, 16, 199, 28, 251, 56, 73, 37, 16, 199, 20, + 222, 103, 251, 47, 73, 37, 16, 222, 46, 73, 37, 16, 234, 90, 73, 37, 16, + 192, 38, 222, 43, 73, 37, 16, 192, 38, 251, 93, 73, 37, 16, 201, 87, 73, + 37, 16, 221, 93, 251, 93, 73, 37, 16, 236, 239, 251, 12, 73, 37, 16, 221, + 7, 251, 12, 73, 37, 16, 221, 7, 251, 167, 73, 37, 16, 221, 7, 214, 98, + 73, 37, 16, 251, 55, 214, 98, 73, 37, 16, 251, 57, 73, 37, 16, 236, 238, + 73, 37, 16, 197, 223, 73, 37, 16, 199, 66, 73, 37, 16, 221, 30, 73, 37, + 16, 219, 207, 234, 83, 243, 50, 73, 37, 16, 219, 207, 235, 39, 243, 51, + 73, 37, 16, 219, 207, 197, 226, 243, 51, 73, 37, 16, 219, 207, 199, 78, + 243, 51, 73, 37, 16, 219, 207, 223, 170, 243, 50, 73, 37, 16, 230, 238, + 214, 99, 251, 93, 73, 37, 16, 230, 238, 210, 111, 251, 0, 73, 37, 16, + 230, 238, 210, 111, 237, 73, 73, 37, 16, 237, 7, 73, 37, 16, 237, 8, 210, + 111, 251, 1, 222, 43, 73, 37, 16, 237, 8, 210, 111, 251, 1, 251, 93, 73, + 37, 16, 237, 8, 210, 111, 237, 73, 73, 37, 16, 197, 232, 73, 37, 16, 251, + 5, 73, 37, 16, 223, 177, 73, 37, 16, 237, 30, 73, 37, 16, 251, 247, 209, + 51, 251, 6, 73, 37, 16, 251, 247, 251, 3, 73, 37, 16, 251, 247, 251, 6, + 73, 37, 16, 251, 247, 216, 160, 73, 37, 16, 251, 247, 216, 171, 73, 37, + 16, 251, 247, 230, 239, 73, 37, 16, 251, 247, 230, 236, 73, 37, 16, 251, + 247, 209, 51, 230, 239, 73, 37, 16, 217, 45, 208, 181, 228, 22, 73, 37, + 16, 217, 45, 251, 169, 208, 181, 228, 22, 73, 37, 16, 217, 45, 237, 72, + 228, 22, 73, 37, 16, 217, 45, 251, 169, 237, 72, 228, 22, 73, 37, 16, + 217, 45, 197, 218, 228, 22, 73, 37, 16, 217, 45, 197, 233, 73, 37, 16, + 217, 45, 199, 71, 228, 22, 73, 37, 16, 217, 45, 199, 71, 219, 211, 228, + 22, 73, 37, 16, 217, 45, 219, 211, 228, 22, 73, 37, 16, 217, 45, 209, + 105, 228, 22, 73, 37, 16, 223, 66, 199, 101, 228, 23, 73, 37, 16, 251, + 52, 199, 101, 228, 23, 73, 37, 16, 233, 79, 199, 68, 73, 37, 16, 233, 79, + 215, 222, 73, 37, 16, 233, 79, 237, 13, 73, 37, 16, 217, 45, 195, 165, + 228, 22, 73, 37, 16, 217, 45, 208, 180, 228, 22, 73, 37, 16, 217, 45, + 209, 105, 199, 71, 228, 22, 73, 37, 16, 230, 233, 215, 62, 251, 56, 73, + 37, 16, 230, 233, 215, 62, 236, 237, 73, 37, 16, 234, 101, 222, 103, 232, + 88, 195, 3, 73, 37, 16, 223, 176, 73, 37, 16, 223, 174, 73, 37, 16, 232, + 88, 251, 13, 237, 71, 228, 21, 73, 37, 16, 232, 88, 237, 28, 168, 73, 37, + 16, 232, 88, 237, 28, 214, 225, 73, 37, 16, 232, 88, 214, 219, 228, 22, + 73, 37, 16, 232, 88, 237, 28, 237, 44, 73, 37, 16, 232, 88, 202, 106, + 237, 27, 237, 44, 73, 37, 16, 232, 88, 237, 28, 222, 22, 73, 37, 16, 232, + 88, 237, 28, 191, 7, 73, 37, 16, 232, 88, 237, 28, 213, 220, 222, 43, 73, + 37, 16, 232, 88, 237, 28, 213, 220, 251, 93, 73, 37, 16, 232, 88, 217, + 98, 243, 52, 237, 13, 73, 37, 16, 232, 88, 217, 98, 243, 52, 215, 222, + 73, 37, 16, 233, 24, 202, 106, 243, 52, 195, 164, 73, 37, 16, 232, 88, + 202, 106, 243, 52, 200, 72, 73, 37, 16, 232, 88, 214, 101, 73, 37, 16, + 243, 53, 190, 230, 73, 37, 16, 243, 53, 221, 91, 73, 37, 16, 243, 53, + 201, 238, 73, 37, 16, 232, 88, 228, 74, 192, 37, 199, 72, 73, 37, 16, + 232, 88, 234, 102, 251, 82, 73, 37, 16, 192, 37, 197, 219, 73, 37, 16, + 237, 21, 197, 219, 73, 37, 16, 237, 21, 199, 72, 73, 37, 16, 237, 21, + 251, 58, 235, 39, 236, 166, 73, 37, 16, 237, 21, 215, 220, 199, 77, 236, + 166, 73, 37, 16, 237, 21, 237, 4, 233, 222, 236, 166, 73, 37, 16, 237, + 21, 197, 230, 211, 122, 236, 166, 73, 37, 16, 192, 37, 251, 58, 235, 39, + 236, 166, 73, 37, 16, 192, 37, 215, 220, 199, 77, 236, 166, 73, 37, 16, + 192, 37, 237, 4, 233, 222, 236, 166, 73, 37, 16, 192, 37, 197, 230, 211, + 122, 236, 166, 73, 37, 16, 231, 147, 237, 20, 73, 37, 16, 231, 147, 192, + 36, 73, 37, 16, 237, 29, 251, 58, 216, 58, 73, 37, 16, 237, 29, 251, 58, + 216, 202, 73, 37, 16, 237, 29, 236, 238, 73, 37, 16, 237, 29, 199, 18, + 73, 37, 16, 202, 181, 199, 18, 73, 37, 16, 202, 181, 199, 19, 236, 221, + 73, 37, 16, 202, 181, 199, 19, 197, 220, 73, 37, 16, 202, 181, 199, 19, + 199, 64, 73, 37, 16, 202, 181, 250, 228, 73, 37, 16, 202, 181, 250, 229, + 236, 221, 73, 37, 16, 202, 181, 250, 229, 197, 220, 73, 37, 16, 202, 181, + 250, 229, 199, 64, 73, 37, 16, 237, 5, 231, 128, 73, 37, 16, 237, 12, + 211, 19, 73, 37, 16, 201, 73, 73, 37, 16, 250, 253, 168, 73, 37, 16, 250, + 253, 195, 3, 73, 37, 16, 250, 253, 231, 240, 73, 37, 16, 250, 253, 237, + 44, 73, 37, 16, 250, 253, 222, 22, 73, 37, 16, 250, 253, 191, 7, 73, 37, + 16, 250, 253, 213, 219, 73, 37, 16, 221, 248, 214, 99, 216, 170, 73, 37, + 16, 221, 249, 214, 99, 216, 170, 73, 37, 16, 221, 248, 214, 99, 222, 43, + 73, 37, 16, 221, 249, 214, 99, 222, 43, 73, 37, 16, 221, 93, 222, 43, 73, + 37, 16, 230, 238, 214, 99, 222, 43, 37, 16, 202, 170, 249, 83, 37, 16, + 55, 249, 83, 37, 16, 53, 249, 83, 37, 16, 207, 19, 53, 249, 83, 37, 16, + 237, 214, 249, 83, 37, 16, 203, 40, 249, 83, 37, 16, 45, 207, 49, 56, 37, + 16, 50, 207, 49, 56, 37, 16, 207, 49, 236, 138, 37, 16, 238, 4, 205, 41, + 37, 16, 238, 33, 247, 108, 37, 16, 205, 41, 37, 16, 242, 92, 37, 16, 207, + 47, 233, 11, 37, 16, 207, 47, 233, 10, 37, 16, 207, 47, 233, 9, 37, 16, + 233, 34, 37, 16, 233, 35, 60, 37, 16, 248, 39, 77, 37, 16, 247, 150, 37, + 16, 248, 55, 37, 16, 248, 53, 37, 16, 211, 99, 201, 111, 37, 16, 197, 12, + 201, 111, 37, 16, 198, 220, 201, 111, 37, 16, 232, 127, 201, 111, 37, 16, + 232, 224, 201, 111, 37, 16, 202, 135, 201, 111, 37, 16, 202, 133, 232, + 105, 37, 16, 232, 125, 232, 105, 37, 16, 232, 52, 242, 235, 37, 16, 232, + 52, 242, 236, 211, 23, 251, 158, 37, 16, 232, 52, 242, 236, 211, 23, 249, + 66, 37, 16, 247, 194, 242, 235, 37, 16, 233, 176, 242, 235, 37, 16, 233, + 176, 242, 236, 211, 23, 251, 158, 37, 16, 233, 176, 242, 236, 211, 23, + 249, 66, 37, 16, 235, 95, 242, 234, 37, 16, 235, 95, 242, 233, 37, 16, + 215, 129, 216, 228, 207, 30, 37, 16, 55, 203, 126, 37, 16, 55, 232, 206, + 37, 16, 232, 207, 196, 77, 37, 16, 232, 207, 235, 123, 37, 16, 214, 206, + 196, 77, 37, 16, 214, 206, 235, 123, 37, 16, 203, 127, 196, 77, 37, 16, + 203, 127, 235, 123, 37, 16, 208, 23, 163, 203, 126, 37, 16, 208, 23, 163, + 232, 206, 37, 16, 242, 71, 198, 146, 37, 16, 238, 155, 198, 146, 37, 16, + 211, 23, 251, 158, 37, 16, 211, 23, 249, 66, 37, 16, 208, 3, 251, 158, + 37, 16, 208, 3, 249, 66, 37, 16, 215, 132, 207, 30, 37, 16, 193, 87, 207, + 30, 37, 16, 132, 207, 30, 37, 16, 208, 23, 207, 30, 37, 16, 234, 160, + 207, 30, 37, 16, 202, 129, 207, 30, 37, 16, 198, 246, 207, 30, 37, 16, + 202, 119, 207, 30, 37, 16, 91, 228, 141, 197, 30, 207, 30, 37, 16, 192, + 236, 213, 2, 37, 16, 108, 213, 2, 37, 16, 243, 11, 192, 236, 213, 2, 37, + 16, 51, 213, 3, 193, 89, 37, 16, 51, 213, 3, 248, 139, 37, 16, 197, 242, + 213, 3, 133, 193, 89, 37, 16, 197, 242, 213, 3, 133, 248, 139, 37, 16, + 197, 242, 213, 3, 45, 193, 89, 37, 16, 197, 242, 213, 3, 45, 248, 139, + 37, 16, 197, 242, 213, 3, 50, 193, 89, 37, 16, 197, 242, 213, 3, 50, 248, + 139, 37, 16, 197, 242, 213, 3, 144, 193, 89, 37, 16, 197, 242, 213, 3, + 144, 248, 139, 37, 16, 197, 242, 213, 3, 133, 50, 193, 89, 37, 16, 197, + 242, 213, 3, 133, 50, 248, 139, 37, 16, 215, 206, 213, 3, 193, 89, 37, + 16, 215, 206, 213, 3, 248, 139, 37, 16, 197, 239, 213, 3, 144, 193, 89, + 37, 16, 197, 239, 213, 3, 144, 248, 139, 37, 16, 210, 114, 213, 2, 37, + 16, 195, 17, 213, 2, 37, 16, 213, 3, 248, 139, 37, 16, 212, 139, 213, 2, + 37, 16, 242, 203, 213, 3, 193, 89, 37, 16, 242, 203, 213, 3, 248, 139, + 37, 16, 248, 36, 37, 16, 193, 87, 213, 6, 37, 16, 132, 213, 6, 37, 16, + 208, 23, 213, 6, 37, 16, 234, 160, 213, 6, 37, 16, 202, 129, 213, 6, 37, + 16, 198, 246, 213, 6, 37, 16, 202, 119, 213, 6, 37, 16, 91, 228, 141, + 197, 30, 213, 6, 37, 16, 33, 201, 80, 37, 16, 33, 201, 197, 201, 80, 37, + 16, 33, 197, 253, 37, 16, 33, 197, 252, 37, 16, 33, 197, 251, 37, 16, + 232, 250, 197, 253, 37, 16, 232, 250, 197, 252, 37, 16, 232, 250, 197, + 251, 37, 16, 33, 250, 160, 236, 140, 37, 16, 33, 232, 216, 37, 16, 33, + 232, 215, 37, 16, 33, 232, 214, 37, 16, 33, 232, 213, 37, 16, 33, 232, + 212, 37, 16, 248, 249, 249, 14, 37, 16, 234, 95, 249, 14, 37, 16, 248, + 249, 198, 178, 37, 16, 234, 95, 198, 178, 37, 16, 248, 249, 202, 71, 37, + 16, 234, 95, 202, 71, 37, 16, 248, 249, 209, 192, 37, 16, 234, 95, 209, + 192, 37, 16, 33, 252, 60, 37, 16, 33, 201, 115, 37, 16, 33, 199, 83, 37, + 16, 33, 201, 116, 37, 16, 33, 217, 60, 37, 16, 33, 217, 59, 37, 16, 33, + 252, 59, 37, 16, 33, 218, 243, 37, 16, 250, 241, 196, 77, 37, 16, 250, + 241, 235, 123, 37, 16, 33, 236, 158, 37, 16, 33, 206, 184, 37, 16, 33, + 232, 195, 37, 16, 33, 202, 67, 37, 16, 33, 248, 227, 37, 16, 33, 55, 198, + 61, 37, 16, 33, 197, 225, 198, 61, 37, 16, 206, 190, 37, 16, 200, 241, + 37, 16, 191, 166, 37, 16, 209, 184, 37, 16, 216, 151, 37, 16, 232, 140, + 37, 16, 238, 229, 37, 16, 237, 132, 37, 16, 230, 228, 213, 7, 202, 97, + 37, 16, 230, 228, 213, 7, 213, 44, 202, 97, 37, 16, 198, 27, 37, 16, 197, + 58, 37, 16, 223, 93, 197, 58, 37, 16, 197, 59, 202, 97, 37, 16, 197, 59, + 196, 77, 37, 16, 211, 43, 201, 27, 37, 16, 211, 43, 201, 24, 37, 16, 211, + 43, 201, 23, 37, 16, 211, 43, 201, 22, 37, 16, 211, 43, 201, 21, 37, 16, + 211, 43, 201, 20, 37, 16, 211, 43, 201, 19, 37, 16, 211, 43, 201, 18, 37, + 16, 211, 43, 201, 17, 37, 16, 211, 43, 201, 26, 37, 16, 211, 43, 201, 25, + 37, 16, 230, 0, 37, 16, 214, 113, 37, 16, 234, 95, 79, 201, 69, 37, 16, + 237, 125, 202, 97, 37, 16, 33, 144, 248, 69, 37, 16, 33, 133, 248, 69, + 37, 16, 33, 230, 14, 37, 16, 33, 202, 57, 209, 111, 37, 16, 210, 54, 77, + 37, 16, 210, 54, 133, 77, 37, 16, 132, 210, 54, 77, 37, 16, 231, 13, 196, + 77, 37, 16, 231, 13, 235, 123, 37, 16, 4, 232, 249, 37, 16, 237, 241, 37, + 16, 237, 242, 251, 174, 37, 16, 217, 23, 37, 16, 219, 10, 37, 16, 248, + 33, 37, 16, 204, 29, 193, 89, 37, 16, 204, 29, 248, 139, 37, 16, 216, 39, + 37, 16, 216, 40, 248, 139, 37, 16, 204, 23, 193, 89, 37, 16, 204, 23, + 248, 139, 37, 16, 232, 70, 193, 89, 37, 16, 232, 70, 248, 139, 37, 16, + 219, 11, 210, 9, 207, 30, 37, 16, 219, 11, 223, 167, 207, 30, 37, 16, + 248, 34, 207, 30, 37, 16, 204, 29, 207, 30, 37, 16, 216, 40, 207, 30, 37, + 16, 204, 23, 207, 30, 37, 16, 199, 97, 210, 7, 238, 186, 208, 192, 210, + 8, 37, 16, 199, 97, 210, 7, 238, 186, 208, 192, 223, 166, 37, 16, 199, + 97, 210, 7, 238, 186, 208, 192, 210, 9, 236, 248, 37, 16, 199, 97, 223, + 165, 238, 186, 208, 192, 210, 8, 37, 16, 199, 97, 223, 165, 238, 186, + 208, 192, 223, 166, 37, 16, 199, 97, 223, 165, 238, 186, 208, 192, 223, + 167, 236, 248, 37, 16, 199, 97, 223, 165, 238, 186, 208, 192, 223, 167, + 236, 247, 37, 16, 199, 97, 223, 165, 238, 186, 208, 192, 223, 167, 236, + 246, 37, 16, 238, 220, 37, 16, 230, 199, 247, 194, 242, 235, 37, 16, 230, + 199, 233, 176, 242, 235, 37, 16, 51, 250, 120, 37, 16, 195, 39, 37, 16, + 209, 69, 37, 16, 242, 224, 37, 16, 205, 95, 37, 16, 242, 229, 37, 16, + 198, 47, 37, 16, 209, 28, 37, 16, 209, 29, 232, 198, 37, 16, 205, 96, + 232, 198, 37, 16, 198, 48, 207, 27, 37, 16, 209, 246, 200, 231, 37, 16, + 221, 148, 247, 194, 242, 235, 37, 16, 221, 148, 234, 95, 79, 209, 175, + 37, 16, 221, 148, 53, 213, 6, 37, 16, 221, 148, 207, 99, 77, 37, 16, 221, + 148, 193, 87, 213, 6, 37, 16, 221, 148, 132, 213, 6, 37, 16, 221, 148, + 208, 23, 213, 7, 201, 81, 235, 123, 37, 16, 221, 148, 208, 23, 213, 7, + 201, 81, 196, 77, 37, 16, 221, 148, 234, 160, 213, 7, 201, 81, 235, 123, + 37, 16, 221, 148, 234, 160, 213, 7, 201, 81, 196, 77, 37, 16, 221, 148, + 232, 207, 56, 37, 16, 202, 11, 37, 16, 221, 31, 35, 195, 23, 213, 10, + 200, 123, 35, 195, 23, 213, 10, 200, 112, 35, 195, 23, 213, 10, 200, 102, + 35, 195, 23, 213, 10, 200, 95, 35, 195, 23, 213, 10, 200, 87, 35, 195, + 23, 213, 10, 200, 81, 35, 195, 23, 213, 10, 200, 80, 35, 195, 23, 213, + 10, 200, 79, 35, 195, 23, 213, 10, 200, 78, 35, 195, 23, 213, 10, 200, + 122, 35, 195, 23, 213, 10, 200, 121, 35, 195, 23, 213, 10, 200, 120, 35, + 195, 23, 213, 10, 200, 119, 35, 195, 23, 213, 10, 200, 118, 35, 195, 23, + 213, 10, 200, 117, 35, 195, 23, 213, 10, 200, 116, 35, 195, 23, 213, 10, + 200, 115, 35, 195, 23, 213, 10, 200, 114, 35, 195, 23, 213, 10, 200, 113, + 35, 195, 23, 213, 10, 200, 111, 35, 195, 23, 213, 10, 200, 110, 35, 195, + 23, 213, 10, 200, 109, 35, 195, 23, 213, 10, 200, 108, 35, 195, 23, 213, + 10, 200, 107, 35, 195, 23, 213, 10, 200, 86, 35, 195, 23, 213, 10, 200, + 85, 35, 195, 23, 213, 10, 200, 84, 35, 195, 23, 213, 10, 200, 83, 35, + 195, 23, 213, 10, 200, 82, 35, 223, 116, 213, 10, 200, 123, 35, 223, 116, + 213, 10, 200, 112, 35, 223, 116, 213, 10, 200, 95, 35, 223, 116, 213, 10, + 200, 87, 35, 223, 116, 213, 10, 200, 80, 35, 223, 116, 213, 10, 200, 79, + 35, 223, 116, 213, 10, 200, 121, 35, 223, 116, 213, 10, 200, 120, 35, + 223, 116, 213, 10, 200, 119, 35, 223, 116, 213, 10, 200, 118, 35, 223, + 116, 213, 10, 200, 115, 35, 223, 116, 213, 10, 200, 114, 35, 223, 116, + 213, 10, 200, 113, 35, 223, 116, 213, 10, 200, 108, 35, 223, 116, 213, + 10, 200, 107, 35, 223, 116, 213, 10, 200, 106, 35, 223, 116, 213, 10, + 200, 105, 35, 223, 116, 213, 10, 200, 104, 35, 223, 116, 213, 10, 200, + 103, 35, 223, 116, 213, 10, 200, 101, 35, 223, 116, 213, 10, 200, 100, + 35, 223, 116, 213, 10, 200, 99, 35, 223, 116, 213, 10, 200, 98, 35, 223, + 116, 213, 10, 200, 97, 35, 223, 116, 213, 10, 200, 96, 35, 223, 116, 213, + 10, 200, 94, 35, 223, 116, 213, 10, 200, 93, 35, 223, 116, 213, 10, 200, + 92, 35, 223, 116, 213, 10, 200, 91, 35, 223, 116, 213, 10, 200, 90, 35, + 223, 116, 213, 10, 200, 89, 35, 223, 116, 213, 10, 200, 88, 35, 223, 116, + 213, 10, 200, 86, 35, 223, 116, 213, 10, 200, 85, 35, 223, 116, 213, 10, + 200, 84, 35, 223, 116, 213, 10, 200, 83, 35, 223, 116, 213, 10, 200, 82, + 33, 35, 37, 197, 221, 33, 35, 37, 199, 65, 33, 35, 37, 210, 22, 35, 37, + 219, 206, 222, 93, 212, 134, 191, 77, 222, 93, 212, 134, 107, 222, 93, + 212, 134, 109, 222, 93, 212, 134, 138, 222, 93, 212, 134, 134, 222, 93, + 212, 134, 149, 222, 93, 212, 134, 169, 222, 93, 212, 134, 175, 222, 93, + 212, 134, 171, 222, 93, 212, 134, 178, 222, 93, 212, 134, 199, 95, 222, + 93, 212, 134, 234, 127, 222, 93, 212, 134, 197, 37, 222, 93, 212, 134, + 198, 251, 222, 93, 212, 134, 232, 122, 222, 93, 212, 134, 233, 19, 222, + 93, 212, 134, 202, 130, 222, 93, 212, 134, 203, 244, 222, 93, 212, 134, + 234, 161, 222, 93, 212, 134, 213, 171, 217, 20, 212, 134, 191, 77, 217, + 20, 212, 134, 107, 217, 20, 212, 134, 109, 217, 20, 212, 134, 138, 217, + 20, 212, 134, 134, 217, 20, 212, 134, 149, 217, 20, 212, 134, 169, 217, + 20, 212, 134, 175, 217, 20, 212, 134, 171, 217, 20, 212, 134, 178, 217, + 20, 212, 134, 199, 95, 217, 20, 212, 134, 234, 127, 217, 20, 212, 134, + 197, 37, 217, 20, 212, 134, 198, 251, 217, 20, 212, 134, 232, 122, 217, + 20, 212, 134, 233, 19, 217, 20, 212, 134, 202, 130, 217, 20, 212, 134, + 203, 244, 217, 20, 212, 134, 234, 161, 217, 20, 212, 134, 213, 171, 215, + 221, 40, 234, 207, 237, 6, 40, 229, 218, 234, 207, 237, 6, 40, 228, 145, + 234, 207, 237, 6, 40, 234, 206, 229, 219, 237, 6, 40, 234, 206, 228, 144, + 237, 6, 40, 234, 207, 199, 67, 40, 247, 21, 199, 67, 40, 232, 80, 243, + 10, 199, 67, 40, 216, 30, 199, 67, 40, 249, 78, 199, 67, 40, 222, 10, + 202, 70, 199, 67, 40, 239, 23, 199, 67, 40, 250, 212, 199, 67, 40, 211, + 62, 199, 67, 40, 248, 45, 211, 14, 199, 67, 40, 237, 127, 211, 57, 236, + 213, 199, 67, 40, 236, 210, 199, 67, 40, 191, 237, 199, 67, 40, 223, 153, + 199, 67, 40, 210, 32, 199, 67, 40, 207, 108, 199, 67, 40, 239, 35, 199, + 67, 40, 229, 6, 249, 146, 199, 67, 40, 193, 171, 199, 67, 40, 232, 169, + 199, 67, 40, 252, 28, 199, 67, 40, 207, 62, 199, 67, 40, 207, 34, 199, + 67, 40, 234, 205, 199, 67, 40, 222, 185, 199, 67, 40, 239, 30, 199, 67, + 40, 234, 93, 199, 67, 40, 235, 59, 199, 67, 40, 246, 244, 199, 67, 40, + 237, 137, 199, 67, 40, 28, 207, 33, 199, 67, 40, 210, 211, 199, 67, 40, + 219, 210, 199, 67, 40, 242, 217, 199, 67, 40, 221, 136, 199, 67, 40, 231, + 189, 199, 67, 40, 201, 39, 199, 67, 40, 208, 140, 199, 67, 40, 232, 79, + 199, 67, 40, 207, 35, 199, 67, 40, 219, 251, 211, 57, 216, 2, 199, 67, + 40, 207, 31, 199, 67, 40, 230, 252, 119, 216, 206, 199, 67, 40, 234, 96, + 199, 67, 40, 201, 56, 199, 67, 40, 230, 202, 199, 67, 40, 234, 86, 199, + 67, 40, 210, 83, 199, 67, 40, 206, 177, 199, 67, 40, 232, 196, 199, 67, + 40, 195, 163, 211, 57, 193, 147, 199, 67, 40, 239, 40, 199, 67, 40, 216, + 227, 199, 67, 40, 233, 250, 199, 67, 40, 196, 88, 199, 67, 40, 236, 249, + 199, 67, 40, 242, 219, 215, 179, 199, 67, 40, 230, 171, 199, 67, 40, 231, + 190, 223, 162, 199, 67, 40, 217, 32, 199, 67, 40, 252, 54, 199, 67, 40, + 234, 112, 199, 67, 40, 235, 127, 199, 67, 40, 193, 145, 199, 67, 40, 202, + 165, 199, 67, 40, 223, 126, 199, 67, 40, 237, 93, 199, 67, 40, 237, 219, + 199, 67, 40, 236, 245, 199, 67, 40, 233, 213, 199, 67, 40, 203, 240, 199, + 67, 40, 201, 60, 199, 67, 40, 230, 16, 199, 67, 40, 242, 66, 199, 67, 40, + 242, 214, 199, 67, 40, 233, 88, 199, 67, 40, 251, 248, 199, 67, 40, 242, + 65, 199, 67, 40, 211, 105, 199, 34, 195, 138, 199, 67, 40, 237, 15, 199, + 67, 40, 220, 113, 199, 67, 40, 232, 131, 238, 244, 206, 145, 196, 91, 17, + 107, 238, 244, 206, 145, 196, 91, 17, 109, 238, 244, 206, 145, 196, 91, + 17, 138, 238, 244, 206, 145, 196, 91, 17, 134, 238, 244, 206, 145, 196, + 91, 17, 149, 238, 244, 206, 145, 196, 91, 17, 169, 238, 244, 206, 145, + 196, 91, 17, 175, 238, 244, 206, 145, 196, 91, 17, 171, 238, 244, 206, + 145, 196, 91, 17, 178, 238, 244, 206, 145, 199, 91, 17, 107, 238, 244, + 206, 145, 199, 91, 17, 109, 238, 244, 206, 145, 199, 91, 17, 138, 238, + 244, 206, 145, 199, 91, 17, 134, 238, 244, 206, 145, 199, 91, 17, 149, + 238, 244, 206, 145, 199, 91, 17, 169, 238, 244, 206, 145, 199, 91, 17, + 175, 238, 244, 206, 145, 199, 91, 17, 171, 238, 244, 206, 145, 199, 91, + 17, 178, 154, 199, 198, 87, 107, 154, 199, 198, 87, 109, 154, 199, 198, + 87, 138, 154, 199, 198, 87, 134, 154, 199, 198, 87, 149, 199, 198, 87, + 107, 199, 198, 87, 149, 13, 28, 6, 65, 13, 28, 6, 250, 120, 13, 28, 6, + 247, 193, 13, 28, 6, 238, 127, 13, 28, 6, 71, 13, 28, 6, 233, 175, 13, + 28, 6, 232, 51, 13, 28, 6, 230, 116, 13, 28, 6, 68, 13, 28, 6, 223, 35, + 13, 28, 6, 222, 152, 13, 28, 6, 172, 13, 28, 6, 218, 168, 13, 28, 6, 215, + 61, 13, 28, 6, 74, 13, 28, 6, 210, 236, 13, 28, 6, 208, 104, 13, 28, 6, + 146, 13, 28, 6, 206, 8, 13, 28, 6, 200, 43, 13, 28, 6, 66, 13, 28, 6, + 196, 12, 13, 28, 6, 193, 224, 13, 28, 6, 192, 235, 13, 28, 6, 192, 159, + 13, 28, 6, 191, 166, 13, 28, 2, 65, 13, 28, 2, 250, 120, 13, 28, 2, 247, + 193, 13, 28, 2, 238, 127, 13, 28, 2, 71, 13, 28, 2, 233, 175, 13, 28, 2, + 232, 51, 13, 28, 2, 230, 116, 13, 28, 2, 68, 13, 28, 2, 223, 35, 13, 28, + 2, 222, 152, 13, 28, 2, 172, 13, 28, 2, 218, 168, 13, 28, 2, 215, 61, 13, + 28, 2, 74, 13, 28, 2, 210, 236, 13, 28, 2, 208, 104, 13, 28, 2, 146, 13, + 28, 2, 206, 8, 13, 28, 2, 200, 43, 13, 28, 2, 66, 13, 28, 2, 196, 12, 13, + 28, 2, 193, 224, 13, 28, 2, 192, 235, 13, 28, 2, 192, 159, 13, 28, 2, + 191, 166, 13, 43, 6, 65, 13, 43, 6, 250, 120, 13, 43, 6, 247, 193, 13, + 43, 6, 238, 127, 13, 43, 6, 71, 13, 43, 6, 233, 175, 13, 43, 6, 232, 51, + 13, 43, 6, 230, 116, 13, 43, 6, 68, 13, 43, 6, 223, 35, 13, 43, 6, 222, + 152, 13, 43, 6, 172, 13, 43, 6, 218, 168, 13, 43, 6, 215, 61, 13, 43, 6, + 74, 13, 43, 6, 210, 236, 13, 43, 6, 208, 104, 13, 43, 6, 146, 13, 43, 6, + 206, 8, 13, 43, 6, 200, 43, 13, 43, 6, 66, 13, 43, 6, 196, 12, 13, 43, 6, + 193, 224, 13, 43, 6, 192, 235, 13, 43, 6, 192, 159, 13, 43, 6, 191, 166, + 13, 43, 2, 65, 13, 43, 2, 250, 120, 13, 43, 2, 247, 193, 13, 43, 2, 238, + 127, 13, 43, 2, 71, 13, 43, 2, 233, 175, 13, 43, 2, 232, 51, 13, 43, 2, + 68, 13, 43, 2, 223, 35, 13, 43, 2, 222, 152, 13, 43, 2, 172, 13, 43, 2, + 218, 168, 13, 43, 2, 215, 61, 13, 43, 2, 74, 13, 43, 2, 210, 236, 13, 43, + 2, 208, 104, 13, 43, 2, 146, 13, 43, 2, 206, 8, 13, 43, 2, 200, 43, 13, + 43, 2, 66, 13, 43, 2, 196, 12, 13, 43, 2, 193, 224, 13, 43, 2, 192, 235, + 13, 43, 2, 192, 159, 13, 43, 2, 191, 166, 13, 28, 43, 6, 65, 13, 28, 43, + 6, 250, 120, 13, 28, 43, 6, 247, 193, 13, 28, 43, 6, 238, 127, 13, 28, + 43, 6, 71, 13, 28, 43, 6, 233, 175, 13, 28, 43, 6, 232, 51, 13, 28, 43, + 6, 230, 116, 13, 28, 43, 6, 68, 13, 28, 43, 6, 223, 35, 13, 28, 43, 6, + 222, 152, 13, 28, 43, 6, 172, 13, 28, 43, 6, 218, 168, 13, 28, 43, 6, + 215, 61, 13, 28, 43, 6, 74, 13, 28, 43, 6, 210, 236, 13, 28, 43, 6, 208, + 104, 13, 28, 43, 6, 146, 13, 28, 43, 6, 206, 8, 13, 28, 43, 6, 200, 43, + 13, 28, 43, 6, 66, 13, 28, 43, 6, 196, 12, 13, 28, 43, 6, 193, 224, 13, 28, 43, 6, 192, 235, 13, 28, 43, 6, 192, 159, 13, 28, 43, 6, 191, 166, - 13, 28, 43, 2, 65, 13, 28, 43, 2, 250, 70, 13, 28, 43, 2, 247, 145, 13, - 28, 43, 2, 238, 80, 13, 28, 43, 2, 73, 13, 28, 43, 2, 233, 134, 13, 28, - 43, 2, 232, 14, 13, 28, 43, 2, 230, 83, 13, 28, 43, 2, 70, 13, 28, 43, 2, - 223, 7, 13, 28, 43, 2, 222, 125, 13, 28, 43, 2, 170, 13, 28, 43, 2, 218, - 147, 13, 28, 43, 2, 215, 47, 13, 28, 43, 2, 74, 13, 28, 43, 2, 210, 226, - 13, 28, 43, 2, 208, 97, 13, 28, 43, 2, 148, 13, 28, 43, 2, 206, 3, 13, - 28, 43, 2, 200, 39, 13, 28, 43, 2, 69, 13, 28, 43, 2, 196, 8, 13, 28, 43, - 2, 193, 221, 13, 28, 43, 2, 192, 235, 13, 28, 43, 2, 192, 159, 13, 28, - 43, 2, 191, 166, 13, 27, 6, 65, 13, 27, 6, 247, 145, 13, 27, 6, 238, 80, - 13, 27, 6, 232, 14, 13, 27, 6, 223, 7, 13, 27, 6, 222, 125, 13, 27, 6, - 215, 47, 13, 27, 6, 74, 13, 27, 6, 210, 226, 13, 27, 6, 208, 97, 13, 27, - 6, 206, 3, 13, 27, 6, 200, 39, 13, 27, 6, 69, 13, 27, 6, 196, 8, 13, 27, - 6, 193, 221, 13, 27, 6, 192, 235, 13, 27, 6, 192, 159, 13, 27, 6, 191, - 166, 13, 27, 2, 65, 13, 27, 2, 250, 70, 13, 27, 2, 247, 145, 13, 27, 2, - 238, 80, 13, 27, 2, 233, 134, 13, 27, 2, 230, 83, 13, 27, 2, 70, 13, 27, - 2, 223, 7, 13, 27, 2, 222, 125, 13, 27, 2, 170, 13, 27, 2, 218, 147, 13, - 27, 2, 215, 47, 13, 27, 2, 210, 226, 13, 27, 2, 208, 97, 13, 27, 2, 148, - 13, 27, 2, 206, 3, 13, 27, 2, 200, 39, 13, 27, 2, 69, 13, 27, 2, 196, 8, - 13, 27, 2, 193, 221, 13, 27, 2, 192, 235, 13, 27, 2, 192, 159, 13, 27, 2, - 191, 166, 13, 28, 27, 6, 65, 13, 28, 27, 6, 250, 70, 13, 28, 27, 6, 247, - 145, 13, 28, 27, 6, 238, 80, 13, 28, 27, 6, 73, 13, 28, 27, 6, 233, 134, - 13, 28, 27, 6, 232, 14, 13, 28, 27, 6, 230, 83, 13, 28, 27, 6, 70, 13, - 28, 27, 6, 223, 7, 13, 28, 27, 6, 222, 125, 13, 28, 27, 6, 170, 13, 28, - 27, 6, 218, 147, 13, 28, 27, 6, 215, 47, 13, 28, 27, 6, 74, 13, 28, 27, - 6, 210, 226, 13, 28, 27, 6, 208, 97, 13, 28, 27, 6, 148, 13, 28, 27, 6, - 206, 3, 13, 28, 27, 6, 200, 39, 13, 28, 27, 6, 69, 13, 28, 27, 6, 196, 8, - 13, 28, 27, 6, 193, 221, 13, 28, 27, 6, 192, 235, 13, 28, 27, 6, 192, - 159, 13, 28, 27, 6, 191, 166, 13, 28, 27, 2, 65, 13, 28, 27, 2, 250, 70, - 13, 28, 27, 2, 247, 145, 13, 28, 27, 2, 238, 80, 13, 28, 27, 2, 73, 13, - 28, 27, 2, 233, 134, 13, 28, 27, 2, 232, 14, 13, 28, 27, 2, 230, 83, 13, - 28, 27, 2, 70, 13, 28, 27, 2, 223, 7, 13, 28, 27, 2, 222, 125, 13, 28, - 27, 2, 170, 13, 28, 27, 2, 218, 147, 13, 28, 27, 2, 215, 47, 13, 28, 27, - 2, 74, 13, 28, 27, 2, 210, 226, 13, 28, 27, 2, 208, 97, 13, 28, 27, 2, - 148, 13, 28, 27, 2, 206, 3, 13, 28, 27, 2, 200, 39, 13, 28, 27, 2, 69, - 13, 28, 27, 2, 196, 8, 13, 28, 27, 2, 193, 221, 13, 28, 27, 2, 192, 235, - 13, 28, 27, 2, 192, 159, 13, 28, 27, 2, 191, 166, 13, 232, 77, 6, 65, 13, - 232, 77, 6, 250, 70, 13, 232, 77, 6, 238, 80, 13, 232, 77, 6, 73, 13, - 232, 77, 6, 233, 134, 13, 232, 77, 6, 232, 14, 13, 232, 77, 6, 223, 7, - 13, 232, 77, 6, 222, 125, 13, 232, 77, 6, 170, 13, 232, 77, 6, 218, 147, - 13, 232, 77, 6, 215, 47, 13, 232, 77, 6, 74, 13, 232, 77, 6, 210, 226, - 13, 232, 77, 6, 208, 97, 13, 232, 77, 6, 206, 3, 13, 232, 77, 6, 200, 39, - 13, 232, 77, 6, 69, 13, 232, 77, 6, 196, 8, 13, 232, 77, 6, 193, 221, 13, - 232, 77, 6, 192, 235, 13, 232, 77, 6, 192, 159, 13, 232, 77, 2, 65, 13, - 232, 77, 2, 250, 70, 13, 232, 77, 2, 247, 145, 13, 232, 77, 2, 238, 80, - 13, 232, 77, 2, 73, 13, 232, 77, 2, 233, 134, 13, 232, 77, 2, 232, 14, - 13, 232, 77, 2, 230, 83, 13, 232, 77, 2, 70, 13, 232, 77, 2, 223, 7, 13, - 232, 77, 2, 222, 125, 13, 232, 77, 2, 170, 13, 232, 77, 2, 218, 147, 13, - 232, 77, 2, 215, 47, 13, 232, 77, 2, 74, 13, 232, 77, 2, 210, 226, 13, - 232, 77, 2, 208, 97, 13, 232, 77, 2, 148, 13, 232, 77, 2, 206, 3, 13, - 232, 77, 2, 200, 39, 13, 232, 77, 2, 69, 13, 232, 77, 2, 196, 8, 13, 232, - 77, 2, 193, 221, 13, 232, 77, 2, 192, 235, 13, 232, 77, 2, 192, 159, 13, - 232, 77, 2, 191, 166, 13, 235, 85, 6, 65, 13, 235, 85, 6, 250, 70, 13, - 235, 85, 6, 238, 80, 13, 235, 85, 6, 73, 13, 235, 85, 6, 233, 134, 13, - 235, 85, 6, 232, 14, 13, 235, 85, 6, 70, 13, 235, 85, 6, 223, 7, 13, 235, - 85, 6, 222, 125, 13, 235, 85, 6, 170, 13, 235, 85, 6, 218, 147, 13, 235, - 85, 6, 74, 13, 235, 85, 6, 206, 3, 13, 235, 85, 6, 200, 39, 13, 235, 85, - 6, 69, 13, 235, 85, 6, 196, 8, 13, 235, 85, 6, 193, 221, 13, 235, 85, 6, - 192, 235, 13, 235, 85, 6, 192, 159, 13, 235, 85, 2, 65, 13, 235, 85, 2, - 250, 70, 13, 235, 85, 2, 247, 145, 13, 235, 85, 2, 238, 80, 13, 235, 85, - 2, 73, 13, 235, 85, 2, 233, 134, 13, 235, 85, 2, 232, 14, 13, 235, 85, 2, - 230, 83, 13, 235, 85, 2, 70, 13, 235, 85, 2, 223, 7, 13, 235, 85, 2, 222, - 125, 13, 235, 85, 2, 170, 13, 235, 85, 2, 218, 147, 13, 235, 85, 2, 215, - 47, 13, 235, 85, 2, 74, 13, 235, 85, 2, 210, 226, 13, 235, 85, 2, 208, - 97, 13, 235, 85, 2, 148, 13, 235, 85, 2, 206, 3, 13, 235, 85, 2, 200, 39, - 13, 235, 85, 2, 69, 13, 235, 85, 2, 196, 8, 13, 235, 85, 2, 193, 221, 13, - 235, 85, 2, 192, 235, 13, 235, 85, 2, 192, 159, 13, 235, 85, 2, 191, 166, - 13, 28, 232, 77, 6, 65, 13, 28, 232, 77, 6, 250, 70, 13, 28, 232, 77, 6, - 247, 145, 13, 28, 232, 77, 6, 238, 80, 13, 28, 232, 77, 6, 73, 13, 28, - 232, 77, 6, 233, 134, 13, 28, 232, 77, 6, 232, 14, 13, 28, 232, 77, 6, - 230, 83, 13, 28, 232, 77, 6, 70, 13, 28, 232, 77, 6, 223, 7, 13, 28, 232, - 77, 6, 222, 125, 13, 28, 232, 77, 6, 170, 13, 28, 232, 77, 6, 218, 147, - 13, 28, 232, 77, 6, 215, 47, 13, 28, 232, 77, 6, 74, 13, 28, 232, 77, 6, - 210, 226, 13, 28, 232, 77, 6, 208, 97, 13, 28, 232, 77, 6, 148, 13, 28, - 232, 77, 6, 206, 3, 13, 28, 232, 77, 6, 200, 39, 13, 28, 232, 77, 6, 69, - 13, 28, 232, 77, 6, 196, 8, 13, 28, 232, 77, 6, 193, 221, 13, 28, 232, - 77, 6, 192, 235, 13, 28, 232, 77, 6, 192, 159, 13, 28, 232, 77, 6, 191, - 166, 13, 28, 232, 77, 2, 65, 13, 28, 232, 77, 2, 250, 70, 13, 28, 232, - 77, 2, 247, 145, 13, 28, 232, 77, 2, 238, 80, 13, 28, 232, 77, 2, 73, 13, - 28, 232, 77, 2, 233, 134, 13, 28, 232, 77, 2, 232, 14, 13, 28, 232, 77, - 2, 230, 83, 13, 28, 232, 77, 2, 70, 13, 28, 232, 77, 2, 223, 7, 13, 28, - 232, 77, 2, 222, 125, 13, 28, 232, 77, 2, 170, 13, 28, 232, 77, 2, 218, - 147, 13, 28, 232, 77, 2, 215, 47, 13, 28, 232, 77, 2, 74, 13, 28, 232, - 77, 2, 210, 226, 13, 28, 232, 77, 2, 208, 97, 13, 28, 232, 77, 2, 148, - 13, 28, 232, 77, 2, 206, 3, 13, 28, 232, 77, 2, 200, 39, 13, 28, 232, 77, - 2, 69, 13, 28, 232, 77, 2, 196, 8, 13, 28, 232, 77, 2, 193, 221, 13, 28, - 232, 77, 2, 192, 235, 13, 28, 232, 77, 2, 192, 159, 13, 28, 232, 77, 2, - 191, 166, 13, 49, 6, 65, 13, 49, 6, 250, 70, 13, 49, 6, 247, 145, 13, 49, - 6, 238, 80, 13, 49, 6, 73, 13, 49, 6, 233, 134, 13, 49, 6, 232, 14, 13, - 49, 6, 230, 83, 13, 49, 6, 70, 13, 49, 6, 223, 7, 13, 49, 6, 222, 125, - 13, 49, 6, 170, 13, 49, 6, 218, 147, 13, 49, 6, 215, 47, 13, 49, 6, 74, - 13, 49, 6, 210, 226, 13, 49, 6, 208, 97, 13, 49, 6, 148, 13, 49, 6, 206, - 3, 13, 49, 6, 200, 39, 13, 49, 6, 69, 13, 49, 6, 196, 8, 13, 49, 6, 193, - 221, 13, 49, 6, 192, 235, 13, 49, 6, 192, 159, 13, 49, 6, 191, 166, 13, - 49, 2, 65, 13, 49, 2, 250, 70, 13, 49, 2, 247, 145, 13, 49, 2, 238, 80, - 13, 49, 2, 73, 13, 49, 2, 233, 134, 13, 49, 2, 232, 14, 13, 49, 2, 230, - 83, 13, 49, 2, 70, 13, 49, 2, 223, 7, 13, 49, 2, 222, 125, 13, 49, 2, - 170, 13, 49, 2, 218, 147, 13, 49, 2, 215, 47, 13, 49, 2, 74, 13, 49, 2, - 210, 226, 13, 49, 2, 208, 97, 13, 49, 2, 148, 13, 49, 2, 206, 3, 13, 49, - 2, 200, 39, 13, 49, 2, 69, 13, 49, 2, 196, 8, 13, 49, 2, 193, 221, 13, - 49, 2, 192, 235, 13, 49, 2, 192, 159, 13, 49, 2, 191, 166, 13, 49, 28, 6, - 65, 13, 49, 28, 6, 250, 70, 13, 49, 28, 6, 247, 145, 13, 49, 28, 6, 238, - 80, 13, 49, 28, 6, 73, 13, 49, 28, 6, 233, 134, 13, 49, 28, 6, 232, 14, - 13, 49, 28, 6, 230, 83, 13, 49, 28, 6, 70, 13, 49, 28, 6, 223, 7, 13, 49, - 28, 6, 222, 125, 13, 49, 28, 6, 170, 13, 49, 28, 6, 218, 147, 13, 49, 28, - 6, 215, 47, 13, 49, 28, 6, 74, 13, 49, 28, 6, 210, 226, 13, 49, 28, 6, - 208, 97, 13, 49, 28, 6, 148, 13, 49, 28, 6, 206, 3, 13, 49, 28, 6, 200, - 39, 13, 49, 28, 6, 69, 13, 49, 28, 6, 196, 8, 13, 49, 28, 6, 193, 221, - 13, 49, 28, 6, 192, 235, 13, 49, 28, 6, 192, 159, 13, 49, 28, 6, 191, - 166, 13, 49, 28, 2, 65, 13, 49, 28, 2, 250, 70, 13, 49, 28, 2, 247, 145, - 13, 49, 28, 2, 238, 80, 13, 49, 28, 2, 73, 13, 49, 28, 2, 233, 134, 13, - 49, 28, 2, 232, 14, 13, 49, 28, 2, 230, 83, 13, 49, 28, 2, 70, 13, 49, - 28, 2, 223, 7, 13, 49, 28, 2, 222, 125, 13, 49, 28, 2, 170, 13, 49, 28, - 2, 218, 147, 13, 49, 28, 2, 215, 47, 13, 49, 28, 2, 74, 13, 49, 28, 2, - 210, 226, 13, 49, 28, 2, 208, 97, 13, 49, 28, 2, 148, 13, 49, 28, 2, 206, - 3, 13, 49, 28, 2, 200, 39, 13, 49, 28, 2, 69, 13, 49, 28, 2, 196, 8, 13, - 49, 28, 2, 193, 221, 13, 49, 28, 2, 192, 235, 13, 49, 28, 2, 192, 159, - 13, 49, 28, 2, 191, 166, 13, 49, 43, 6, 65, 13, 49, 43, 6, 250, 70, 13, - 49, 43, 6, 247, 145, 13, 49, 43, 6, 238, 80, 13, 49, 43, 6, 73, 13, 49, - 43, 6, 233, 134, 13, 49, 43, 6, 232, 14, 13, 49, 43, 6, 230, 83, 13, 49, - 43, 6, 70, 13, 49, 43, 6, 223, 7, 13, 49, 43, 6, 222, 125, 13, 49, 43, 6, - 170, 13, 49, 43, 6, 218, 147, 13, 49, 43, 6, 215, 47, 13, 49, 43, 6, 74, - 13, 49, 43, 6, 210, 226, 13, 49, 43, 6, 208, 97, 13, 49, 43, 6, 148, 13, - 49, 43, 6, 206, 3, 13, 49, 43, 6, 200, 39, 13, 49, 43, 6, 69, 13, 49, 43, - 6, 196, 8, 13, 49, 43, 6, 193, 221, 13, 49, 43, 6, 192, 235, 13, 49, 43, - 6, 192, 159, 13, 49, 43, 6, 191, 166, 13, 49, 43, 2, 65, 13, 49, 43, 2, - 250, 70, 13, 49, 43, 2, 247, 145, 13, 49, 43, 2, 238, 80, 13, 49, 43, 2, - 73, 13, 49, 43, 2, 233, 134, 13, 49, 43, 2, 232, 14, 13, 49, 43, 2, 230, - 83, 13, 49, 43, 2, 70, 13, 49, 43, 2, 223, 7, 13, 49, 43, 2, 222, 125, - 13, 49, 43, 2, 170, 13, 49, 43, 2, 218, 147, 13, 49, 43, 2, 215, 47, 13, - 49, 43, 2, 74, 13, 49, 43, 2, 210, 226, 13, 49, 43, 2, 208, 97, 13, 49, - 43, 2, 148, 13, 49, 43, 2, 206, 3, 13, 49, 43, 2, 200, 39, 13, 49, 43, 2, - 69, 13, 49, 43, 2, 196, 8, 13, 49, 43, 2, 193, 221, 13, 49, 43, 2, 192, - 235, 13, 49, 43, 2, 192, 159, 13, 49, 43, 2, 191, 166, 13, 49, 28, 43, 6, - 65, 13, 49, 28, 43, 6, 250, 70, 13, 49, 28, 43, 6, 247, 145, 13, 49, 28, - 43, 6, 238, 80, 13, 49, 28, 43, 6, 73, 13, 49, 28, 43, 6, 233, 134, 13, - 49, 28, 43, 6, 232, 14, 13, 49, 28, 43, 6, 230, 83, 13, 49, 28, 43, 6, - 70, 13, 49, 28, 43, 6, 223, 7, 13, 49, 28, 43, 6, 222, 125, 13, 49, 28, - 43, 6, 170, 13, 49, 28, 43, 6, 218, 147, 13, 49, 28, 43, 6, 215, 47, 13, - 49, 28, 43, 6, 74, 13, 49, 28, 43, 6, 210, 226, 13, 49, 28, 43, 6, 208, - 97, 13, 49, 28, 43, 6, 148, 13, 49, 28, 43, 6, 206, 3, 13, 49, 28, 43, 6, - 200, 39, 13, 49, 28, 43, 6, 69, 13, 49, 28, 43, 6, 196, 8, 13, 49, 28, - 43, 6, 193, 221, 13, 49, 28, 43, 6, 192, 235, 13, 49, 28, 43, 6, 192, - 159, 13, 49, 28, 43, 6, 191, 166, 13, 49, 28, 43, 2, 65, 13, 49, 28, 43, - 2, 250, 70, 13, 49, 28, 43, 2, 247, 145, 13, 49, 28, 43, 2, 238, 80, 13, - 49, 28, 43, 2, 73, 13, 49, 28, 43, 2, 233, 134, 13, 49, 28, 43, 2, 232, - 14, 13, 49, 28, 43, 2, 230, 83, 13, 49, 28, 43, 2, 70, 13, 49, 28, 43, 2, - 223, 7, 13, 49, 28, 43, 2, 222, 125, 13, 49, 28, 43, 2, 170, 13, 49, 28, - 43, 2, 218, 147, 13, 49, 28, 43, 2, 215, 47, 13, 49, 28, 43, 2, 74, 13, - 49, 28, 43, 2, 210, 226, 13, 49, 28, 43, 2, 208, 97, 13, 49, 28, 43, 2, - 148, 13, 49, 28, 43, 2, 206, 3, 13, 49, 28, 43, 2, 200, 39, 13, 49, 28, - 43, 2, 69, 13, 49, 28, 43, 2, 196, 8, 13, 49, 28, 43, 2, 193, 221, 13, - 49, 28, 43, 2, 192, 235, 13, 49, 28, 43, 2, 192, 159, 13, 49, 28, 43, 2, - 191, 166, 13, 215, 200, 6, 65, 13, 215, 200, 6, 250, 70, 13, 215, 200, 6, - 247, 145, 13, 215, 200, 6, 238, 80, 13, 215, 200, 6, 73, 13, 215, 200, 6, - 233, 134, 13, 215, 200, 6, 232, 14, 13, 215, 200, 6, 230, 83, 13, 215, - 200, 6, 70, 13, 215, 200, 6, 223, 7, 13, 215, 200, 6, 222, 125, 13, 215, - 200, 6, 170, 13, 215, 200, 6, 218, 147, 13, 215, 200, 6, 215, 47, 13, - 215, 200, 6, 74, 13, 215, 200, 6, 210, 226, 13, 215, 200, 6, 208, 97, 13, - 215, 200, 6, 148, 13, 215, 200, 6, 206, 3, 13, 215, 200, 6, 200, 39, 13, - 215, 200, 6, 69, 13, 215, 200, 6, 196, 8, 13, 215, 200, 6, 193, 221, 13, - 215, 200, 6, 192, 235, 13, 215, 200, 6, 192, 159, 13, 215, 200, 6, 191, - 166, 13, 215, 200, 2, 65, 13, 215, 200, 2, 250, 70, 13, 215, 200, 2, 247, - 145, 13, 215, 200, 2, 238, 80, 13, 215, 200, 2, 73, 13, 215, 200, 2, 233, - 134, 13, 215, 200, 2, 232, 14, 13, 215, 200, 2, 230, 83, 13, 215, 200, 2, - 70, 13, 215, 200, 2, 223, 7, 13, 215, 200, 2, 222, 125, 13, 215, 200, 2, - 170, 13, 215, 200, 2, 218, 147, 13, 215, 200, 2, 215, 47, 13, 215, 200, - 2, 74, 13, 215, 200, 2, 210, 226, 13, 215, 200, 2, 208, 97, 13, 215, 200, - 2, 148, 13, 215, 200, 2, 206, 3, 13, 215, 200, 2, 200, 39, 13, 215, 200, - 2, 69, 13, 215, 200, 2, 196, 8, 13, 215, 200, 2, 193, 221, 13, 215, 200, - 2, 192, 235, 13, 215, 200, 2, 192, 159, 13, 215, 200, 2, 191, 166, 13, - 43, 2, 236, 95, 70, 13, 43, 2, 236, 95, 223, 7, 13, 28, 6, 251, 109, 13, - 28, 6, 248, 162, 13, 28, 6, 231, 174, 13, 28, 6, 237, 61, 13, 28, 6, 234, - 5, 13, 28, 6, 191, 76, 13, 28, 6, 233, 211, 13, 28, 6, 199, 10, 13, 28, - 6, 223, 55, 13, 28, 6, 222, 46, 13, 28, 6, 220, 7, 13, 28, 6, 215, 139, - 13, 28, 6, 212, 165, 13, 28, 6, 192, 207, 13, 28, 6, 211, 96, 13, 28, 6, - 209, 176, 13, 28, 6, 206, 254, 13, 28, 6, 199, 11, 113, 13, 28, 6, 202, - 191, 13, 28, 6, 199, 161, 13, 28, 6, 196, 66, 13, 28, 6, 209, 202, 13, - 28, 6, 243, 47, 13, 28, 6, 208, 169, 13, 28, 6, 211, 99, 13, 28, 214, - 231, 13, 28, 2, 251, 109, 13, 28, 2, 248, 162, 13, 28, 2, 231, 174, 13, - 28, 2, 237, 61, 13, 28, 2, 234, 5, 13, 28, 2, 191, 76, 13, 28, 2, 233, - 211, 13, 28, 2, 199, 10, 13, 28, 2, 223, 55, 13, 28, 2, 222, 46, 13, 28, - 2, 220, 7, 13, 28, 2, 215, 139, 13, 28, 2, 212, 165, 13, 28, 2, 192, 207, - 13, 28, 2, 211, 96, 13, 28, 2, 209, 176, 13, 28, 2, 206, 254, 13, 28, 2, - 52, 202, 191, 13, 28, 2, 202, 191, 13, 28, 2, 199, 161, 13, 28, 2, 196, - 66, 13, 28, 2, 209, 202, 13, 28, 2, 243, 47, 13, 28, 2, 208, 169, 13, 28, - 2, 211, 99, 13, 28, 210, 95, 236, 227, 13, 28, 234, 6, 113, 13, 28, 199, - 11, 113, 13, 28, 222, 47, 113, 13, 28, 209, 203, 113, 13, 28, 206, 255, - 113, 13, 28, 209, 177, 113, 13, 43, 6, 251, 109, 13, 43, 6, 248, 162, 13, - 43, 6, 231, 174, 13, 43, 6, 237, 61, 13, 43, 6, 234, 5, 13, 43, 6, 191, - 76, 13, 43, 6, 233, 211, 13, 43, 6, 199, 10, 13, 43, 6, 223, 55, 13, 43, - 6, 222, 46, 13, 43, 6, 220, 7, 13, 43, 6, 215, 139, 13, 43, 6, 212, 165, - 13, 43, 6, 192, 207, 13, 43, 6, 211, 96, 13, 43, 6, 209, 176, 13, 43, 6, - 206, 254, 13, 43, 6, 199, 11, 113, 13, 43, 6, 202, 191, 13, 43, 6, 199, - 161, 13, 43, 6, 196, 66, 13, 43, 6, 209, 202, 13, 43, 6, 243, 47, 13, 43, - 6, 208, 169, 13, 43, 6, 211, 99, 13, 43, 214, 231, 13, 43, 2, 251, 109, - 13, 43, 2, 248, 162, 13, 43, 2, 231, 174, 13, 43, 2, 237, 61, 13, 43, 2, - 234, 5, 13, 43, 2, 191, 76, 13, 43, 2, 233, 211, 13, 43, 2, 199, 10, 13, - 43, 2, 223, 55, 13, 43, 2, 222, 46, 13, 43, 2, 220, 7, 13, 43, 2, 215, - 139, 13, 43, 2, 212, 165, 13, 43, 2, 192, 207, 13, 43, 2, 211, 96, 13, - 43, 2, 209, 176, 13, 43, 2, 206, 254, 13, 43, 2, 52, 202, 191, 13, 43, 2, - 202, 191, 13, 43, 2, 199, 161, 13, 43, 2, 196, 66, 13, 43, 2, 209, 202, - 13, 43, 2, 243, 47, 13, 43, 2, 208, 169, 13, 43, 2, 211, 99, 13, 43, 210, - 95, 236, 227, 13, 43, 234, 6, 113, 13, 43, 199, 11, 113, 13, 43, 222, 47, - 113, 13, 43, 209, 203, 113, 13, 43, 206, 255, 113, 13, 43, 209, 177, 113, - 13, 28, 43, 6, 251, 109, 13, 28, 43, 6, 248, 162, 13, 28, 43, 6, 231, - 174, 13, 28, 43, 6, 237, 61, 13, 28, 43, 6, 234, 5, 13, 28, 43, 6, 191, - 76, 13, 28, 43, 6, 233, 211, 13, 28, 43, 6, 199, 10, 13, 28, 43, 6, 223, - 55, 13, 28, 43, 6, 222, 46, 13, 28, 43, 6, 220, 7, 13, 28, 43, 6, 215, - 139, 13, 28, 43, 6, 212, 165, 13, 28, 43, 6, 192, 207, 13, 28, 43, 6, - 211, 96, 13, 28, 43, 6, 209, 176, 13, 28, 43, 6, 206, 254, 13, 28, 43, 6, - 199, 11, 113, 13, 28, 43, 6, 202, 191, 13, 28, 43, 6, 199, 161, 13, 28, - 43, 6, 196, 66, 13, 28, 43, 6, 209, 202, 13, 28, 43, 6, 243, 47, 13, 28, - 43, 6, 208, 169, 13, 28, 43, 6, 211, 99, 13, 28, 43, 214, 231, 13, 28, - 43, 2, 251, 109, 13, 28, 43, 2, 248, 162, 13, 28, 43, 2, 231, 174, 13, - 28, 43, 2, 237, 61, 13, 28, 43, 2, 234, 5, 13, 28, 43, 2, 191, 76, 13, - 28, 43, 2, 233, 211, 13, 28, 43, 2, 199, 10, 13, 28, 43, 2, 223, 55, 13, - 28, 43, 2, 222, 46, 13, 28, 43, 2, 220, 7, 13, 28, 43, 2, 215, 139, 13, - 28, 43, 2, 212, 165, 13, 28, 43, 2, 192, 207, 13, 28, 43, 2, 211, 96, 13, - 28, 43, 2, 209, 176, 13, 28, 43, 2, 206, 254, 13, 28, 43, 2, 52, 202, - 191, 13, 28, 43, 2, 202, 191, 13, 28, 43, 2, 199, 161, 13, 28, 43, 2, - 196, 66, 13, 28, 43, 2, 209, 202, 13, 28, 43, 2, 243, 47, 13, 28, 43, 2, - 208, 169, 13, 28, 43, 2, 211, 99, 13, 28, 43, 210, 95, 236, 227, 13, 28, - 43, 234, 6, 113, 13, 28, 43, 199, 11, 113, 13, 28, 43, 222, 47, 113, 13, - 28, 43, 209, 203, 113, 13, 28, 43, 206, 255, 113, 13, 28, 43, 209, 177, - 113, 13, 49, 28, 6, 251, 109, 13, 49, 28, 6, 248, 162, 13, 49, 28, 6, - 231, 174, 13, 49, 28, 6, 237, 61, 13, 49, 28, 6, 234, 5, 13, 49, 28, 6, - 191, 76, 13, 49, 28, 6, 233, 211, 13, 49, 28, 6, 199, 10, 13, 49, 28, 6, - 223, 55, 13, 49, 28, 6, 222, 46, 13, 49, 28, 6, 220, 7, 13, 49, 28, 6, - 215, 139, 13, 49, 28, 6, 212, 165, 13, 49, 28, 6, 192, 207, 13, 49, 28, - 6, 211, 96, 13, 49, 28, 6, 209, 176, 13, 49, 28, 6, 206, 254, 13, 49, 28, - 6, 199, 11, 113, 13, 49, 28, 6, 202, 191, 13, 49, 28, 6, 199, 161, 13, - 49, 28, 6, 196, 66, 13, 49, 28, 6, 209, 202, 13, 49, 28, 6, 243, 47, 13, - 49, 28, 6, 208, 169, 13, 49, 28, 6, 211, 99, 13, 49, 28, 214, 231, 13, - 49, 28, 2, 251, 109, 13, 49, 28, 2, 248, 162, 13, 49, 28, 2, 231, 174, - 13, 49, 28, 2, 237, 61, 13, 49, 28, 2, 234, 5, 13, 49, 28, 2, 191, 76, - 13, 49, 28, 2, 233, 211, 13, 49, 28, 2, 199, 10, 13, 49, 28, 2, 223, 55, - 13, 49, 28, 2, 222, 46, 13, 49, 28, 2, 220, 7, 13, 49, 28, 2, 215, 139, - 13, 49, 28, 2, 212, 165, 13, 49, 28, 2, 192, 207, 13, 49, 28, 2, 211, 96, - 13, 49, 28, 2, 209, 176, 13, 49, 28, 2, 206, 254, 13, 49, 28, 2, 52, 202, - 191, 13, 49, 28, 2, 202, 191, 13, 49, 28, 2, 199, 161, 13, 49, 28, 2, - 196, 66, 13, 49, 28, 2, 209, 202, 13, 49, 28, 2, 243, 47, 13, 49, 28, 2, - 208, 169, 13, 49, 28, 2, 211, 99, 13, 49, 28, 210, 95, 236, 227, 13, 49, - 28, 234, 6, 113, 13, 49, 28, 199, 11, 113, 13, 49, 28, 222, 47, 113, 13, - 49, 28, 209, 203, 113, 13, 49, 28, 206, 255, 113, 13, 49, 28, 209, 177, - 113, 13, 49, 28, 43, 6, 251, 109, 13, 49, 28, 43, 6, 248, 162, 13, 49, - 28, 43, 6, 231, 174, 13, 49, 28, 43, 6, 237, 61, 13, 49, 28, 43, 6, 234, - 5, 13, 49, 28, 43, 6, 191, 76, 13, 49, 28, 43, 6, 233, 211, 13, 49, 28, - 43, 6, 199, 10, 13, 49, 28, 43, 6, 223, 55, 13, 49, 28, 43, 6, 222, 46, - 13, 49, 28, 43, 6, 220, 7, 13, 49, 28, 43, 6, 215, 139, 13, 49, 28, 43, - 6, 212, 165, 13, 49, 28, 43, 6, 192, 207, 13, 49, 28, 43, 6, 211, 96, 13, - 49, 28, 43, 6, 209, 176, 13, 49, 28, 43, 6, 206, 254, 13, 49, 28, 43, 6, - 199, 11, 113, 13, 49, 28, 43, 6, 202, 191, 13, 49, 28, 43, 6, 199, 161, - 13, 49, 28, 43, 6, 196, 66, 13, 49, 28, 43, 6, 209, 202, 13, 49, 28, 43, - 6, 243, 47, 13, 49, 28, 43, 6, 208, 169, 13, 49, 28, 43, 6, 211, 99, 13, - 49, 28, 43, 214, 231, 13, 49, 28, 43, 2, 251, 109, 13, 49, 28, 43, 2, - 248, 162, 13, 49, 28, 43, 2, 231, 174, 13, 49, 28, 43, 2, 237, 61, 13, - 49, 28, 43, 2, 234, 5, 13, 49, 28, 43, 2, 191, 76, 13, 49, 28, 43, 2, - 233, 211, 13, 49, 28, 43, 2, 199, 10, 13, 49, 28, 43, 2, 223, 55, 13, 49, - 28, 43, 2, 222, 46, 13, 49, 28, 43, 2, 220, 7, 13, 49, 28, 43, 2, 215, - 139, 13, 49, 28, 43, 2, 212, 165, 13, 49, 28, 43, 2, 192, 207, 13, 49, - 28, 43, 2, 211, 96, 13, 49, 28, 43, 2, 209, 176, 13, 49, 28, 43, 2, 206, - 254, 13, 49, 28, 43, 2, 52, 202, 191, 13, 49, 28, 43, 2, 202, 191, 13, - 49, 28, 43, 2, 199, 161, 13, 49, 28, 43, 2, 196, 66, 13, 49, 28, 43, 2, - 209, 202, 13, 49, 28, 43, 2, 243, 47, 13, 49, 28, 43, 2, 208, 169, 13, - 49, 28, 43, 2, 211, 99, 13, 49, 28, 43, 210, 95, 236, 227, 13, 49, 28, - 43, 234, 6, 113, 13, 49, 28, 43, 199, 11, 113, 13, 49, 28, 43, 222, 47, - 113, 13, 49, 28, 43, 209, 203, 113, 13, 49, 28, 43, 206, 255, 113, 13, - 49, 28, 43, 209, 177, 113, 13, 28, 6, 236, 221, 13, 28, 2, 236, 221, 13, - 28, 17, 191, 77, 13, 28, 17, 108, 13, 28, 17, 109, 13, 28, 17, 139, 13, - 28, 17, 137, 13, 28, 17, 153, 13, 28, 17, 173, 13, 28, 17, 181, 13, 28, - 17, 176, 13, 28, 17, 184, 13, 235, 85, 17, 191, 77, 13, 235, 85, 17, 108, - 13, 235, 85, 17, 109, 13, 235, 85, 17, 139, 13, 235, 85, 17, 137, 13, - 235, 85, 17, 153, 13, 235, 85, 17, 173, 13, 235, 85, 17, 181, 13, 235, - 85, 17, 176, 13, 235, 85, 17, 184, 13, 49, 17, 191, 77, 13, 49, 17, 108, - 13, 49, 17, 109, 13, 49, 17, 139, 13, 49, 17, 137, 13, 49, 17, 153, 13, - 49, 17, 173, 13, 49, 17, 181, 13, 49, 17, 176, 13, 49, 17, 184, 13, 49, - 28, 17, 191, 77, 13, 49, 28, 17, 108, 13, 49, 28, 17, 109, 13, 49, 28, - 17, 139, 13, 49, 28, 17, 137, 13, 49, 28, 17, 153, 13, 49, 28, 17, 173, - 13, 49, 28, 17, 181, 13, 49, 28, 17, 176, 13, 49, 28, 17, 184, 13, 215, - 200, 17, 191, 77, 13, 215, 200, 17, 108, 13, 215, 200, 17, 109, 13, 215, - 200, 17, 139, 13, 215, 200, 17, 137, 13, 215, 200, 17, 153, 13, 215, 200, - 17, 173, 13, 215, 200, 17, 181, 13, 215, 200, 17, 176, 13, 215, 200, 17, - 184, 23, 150, 223, 120, 23, 230, 17, 223, 120, 23, 230, 13, 223, 120, 23, - 230, 2, 223, 120, 23, 230, 6, 223, 120, 23, 230, 19, 223, 120, 23, 150, - 140, 248, 173, 23, 230, 17, 140, 248, 173, 23, 150, 174, 196, 101, 140, - 248, 173, 23, 150, 140, 207, 142, 221, 46, 23, 150, 140, 238, 130, 23, - 150, 140, 229, 92, 23, 150, 140, 229, 93, 218, 219, 23, 230, 17, 140, - 229, 94, 23, 150, 140, 216, 66, 23, 230, 17, 140, 216, 66, 23, 150, 140, - 82, 248, 173, 23, 150, 140, 82, 207, 142, 221, 45, 23, 150, 140, 82, 229, - 92, 23, 150, 140, 132, 82, 229, 92, 23, 150, 140, 229, 93, 82, 196, 73, - 23, 150, 140, 82, 238, 254, 23, 150, 140, 82, 238, 255, 140, 248, 173, - 23, 150, 140, 82, 238, 255, 82, 248, 173, 23, 150, 140, 82, 238, 255, - 238, 130, 23, 150, 140, 82, 238, 255, 229, 92, 23, 150, 140, 82, 238, - 166, 23, 230, 17, 140, 82, 238, 166, 23, 150, 82, 248, 174, 138, 223, - 120, 23, 150, 140, 248, 174, 138, 216, 66, 23, 150, 140, 82, 198, 207, - 23, 230, 17, 140, 82, 198, 207, 23, 150, 140, 82, 201, 48, 174, 248, 173, - 23, 150, 140, 82, 248, 174, 174, 201, 47, 23, 150, 140, 82, 174, 248, - 173, 23, 150, 140, 82, 229, 93, 201, 194, 174, 202, 202, 23, 150, 140, - 132, 82, 229, 93, 174, 202, 202, 23, 150, 140, 132, 82, 229, 93, 174, - 238, 254, 23, 150, 140, 229, 93, 82, 132, 174, 202, 202, 23, 150, 140, - 82, 132, 201, 194, 174, 232, 94, 23, 150, 140, 82, 174, 238, 130, 23, - 150, 140, 82, 174, 242, 217, 23, 150, 140, 82, 174, 228, 217, 23, 150, - 140, 82, 174, 229, 92, 23, 150, 174, 248, 160, 140, 82, 201, 47, 23, 150, - 140, 82, 238, 255, 174, 202, 202, 23, 150, 140, 82, 238, 255, 174, 202, - 203, 238, 254, 23, 150, 140, 82, 238, 255, 174, 202, 203, 248, 173, 23, - 150, 82, 174, 228, 218, 140, 196, 73, 23, 150, 140, 174, 228, 218, 82, - 196, 73, 23, 150, 140, 82, 238, 255, 229, 93, 174, 202, 202, 23, 150, - 140, 82, 238, 167, 174, 202, 202, 23, 150, 140, 82, 238, 255, 174, 232, - 94, 23, 150, 140, 82, 238, 255, 238, 131, 174, 232, 94, 23, 150, 82, 174, - 238, 131, 140, 196, 73, 23, 150, 140, 174, 238, 131, 82, 196, 73, 23, - 150, 82, 174, 47, 140, 196, 73, 23, 150, 82, 174, 47, 140, 229, 92, 23, - 150, 140, 174, 251, 63, 211, 5, 82, 196, 73, 23, 150, 140, 174, 251, 63, - 223, 135, 82, 196, 73, 23, 150, 140, 174, 47, 82, 196, 73, 23, 150, 140, - 82, 174, 238, 255, 229, 92, 23, 150, 140, 82, 174, 251, 63, 211, 4, 23, - 150, 140, 82, 174, 251, 62, 23, 150, 82, 174, 251, 63, 211, 5, 140, 196, - 73, 23, 150, 82, 174, 251, 63, 211, 5, 140, 238, 166, 23, 150, 82, 174, - 251, 63, 140, 196, 73, 23, 150, 140, 174, 228, 218, 82, 229, 92, 23, 230, - 8, 232, 90, 232, 206, 23, 230, 8, 232, 90, 232, 207, 248, 173, 23, 230, - 8, 232, 90, 232, 207, 229, 92, 23, 230, 8, 232, 90, 232, 207, 238, 254, - 23, 230, 8, 232, 90, 232, 207, 238, 255, 201, 204, 23, 230, 15, 232, 90, - 232, 207, 238, 254, 23, 150, 232, 90, 232, 207, 238, 255, 248, 173, 23, - 230, 6, 232, 90, 232, 207, 238, 254, 23, 230, 8, 232, 185, 232, 207, 201, - 193, 23, 230, 8, 229, 181, 232, 185, 232, 207, 201, 193, 23, 230, 8, 232, - 185, 232, 207, 201, 194, 232, 90, 248, 173, 23, 230, 8, 229, 181, 232, - 185, 232, 207, 201, 194, 232, 90, 248, 173, 23, 230, 8, 232, 185, 232, - 207, 201, 194, 248, 173, 23, 230, 8, 229, 181, 232, 185, 232, 207, 201, - 194, 248, 173, 23, 230, 8, 232, 185, 232, 207, 201, 194, 174, 232, 94, - 23, 230, 13, 232, 185, 232, 207, 201, 193, 23, 230, 13, 232, 185, 232, - 207, 201, 194, 211, 65, 23, 230, 6, 232, 185, 232, 207, 201, 194, 211, - 65, 23, 230, 2, 232, 185, 232, 207, 201, 193, 23, 230, 8, 232, 185, 232, - 207, 201, 194, 229, 92, 23, 230, 8, 232, 185, 232, 207, 201, 194, 229, - 93, 174, 202, 202, 23, 230, 8, 232, 185, 232, 207, 201, 194, 229, 93, - 213, 31, 198, 207, 23, 230, 7, 23, 230, 8, 248, 160, 210, 173, 233, 54, - 23, 230, 8, 229, 180, 23, 230, 8, 174, 202, 202, 23, 230, 8, 229, 181, - 174, 202, 202, 23, 230, 8, 174, 248, 173, 23, 230, 8, 174, 232, 94, 23, - 230, 8, 201, 205, 140, 174, 202, 202, 23, 230, 8, 201, 205, 246, 229, 23, - 230, 8, 201, 205, 246, 230, 174, 202, 202, 23, 230, 8, 201, 205, 246, - 230, 174, 202, 203, 248, 173, 23, 230, 8, 201, 205, 219, 58, 23, 230, 14, - 23, 230, 15, 174, 202, 202, 23, 230, 15, 213, 31, 198, 207, 23, 230, 15, - 174, 232, 94, 23, 230, 4, 238, 126, 23, 230, 3, 23, 230, 13, 211, 65, 23, - 230, 12, 23, 230, 13, 211, 66, 174, 202, 202, 23, 230, 13, 174, 202, 202, - 23, 230, 13, 211, 66, 213, 31, 198, 207, 23, 230, 13, 213, 31, 198, 207, - 23, 230, 13, 211, 66, 174, 232, 94, 23, 230, 13, 174, 232, 94, 23, 230, - 11, 211, 65, 23, 230, 10, 23, 230, 16, 23, 230, 1, 23, 230, 2, 174, 202, - 202, 23, 230, 2, 213, 31, 198, 207, 23, 230, 2, 174, 232, 94, 23, 230, 6, - 211, 65, 23, 230, 6, 211, 66, 174, 232, 94, 23, 230, 5, 23, 230, 6, 202, - 65, 23, 230, 6, 211, 66, 174, 202, 202, 23, 230, 6, 174, 202, 202, 23, - 230, 6, 211, 66, 213, 31, 198, 207, 23, 230, 6, 213, 31, 198, 207, 23, - 230, 6, 174, 202, 203, 198, 30, 223, 120, 23, 230, 6, 174, 248, 160, 82, - 206, 183, 23, 230, 18, 23, 150, 140, 82, 206, 183, 23, 230, 17, 140, 82, - 206, 183, 23, 230, 6, 140, 82, 206, 183, 23, 230, 19, 140, 82, 206, 183, - 23, 230, 6, 219, 58, 23, 150, 140, 82, 206, 184, 248, 173, 23, 150, 140, - 82, 206, 184, 238, 254, 23, 230, 6, 140, 82, 206, 184, 238, 254, 23, 150, - 219, 59, 235, 79, 23, 150, 219, 59, 143, 206, 178, 201, 47, 23, 150, 219, - 59, 143, 206, 178, 238, 115, 23, 150, 219, 59, 143, 211, 16, 242, 217, - 23, 150, 219, 59, 196, 73, 23, 150, 174, 196, 101, 219, 59, 196, 73, 23, - 230, 17, 219, 59, 196, 73, 23, 230, 2, 219, 59, 196, 73, 23, 230, 19, - 219, 59, 196, 73, 23, 150, 219, 59, 207, 142, 221, 46, 23, 150, 219, 59, - 248, 173, 23, 150, 219, 59, 198, 31, 198, 207, 23, 150, 219, 59, 198, - 207, 23, 230, 6, 219, 59, 198, 207, 23, 150, 219, 59, 140, 198, 207, 23, - 230, 6, 219, 59, 140, 198, 207, 23, 230, 19, 219, 59, 140, 174, 140, 174, - 211, 4, 23, 230, 19, 219, 59, 140, 174, 140, 198, 207, 23, 150, 219, 59, - 223, 120, 23, 230, 17, 219, 59, 223, 120, 23, 230, 6, 219, 59, 223, 120, - 23, 230, 19, 219, 59, 223, 120, 23, 150, 140, 82, 219, 58, 23, 230, 17, - 140, 82, 219, 58, 23, 230, 6, 140, 82, 219, 58, 23, 230, 6, 206, 183, 23, - 230, 19, 140, 82, 219, 58, 23, 150, 140, 82, 238, 171, 219, 58, 23, 230, - 17, 140, 82, 238, 171, 219, 58, 23, 150, 206, 184, 235, 79, 23, 230, 6, - 206, 184, 143, 140, 174, 228, 219, 216, 66, 23, 230, 19, 206, 184, 143, - 82, 174, 140, 238, 170, 23, 150, 206, 184, 196, 73, 23, 150, 206, 184, - 207, 142, 221, 46, 23, 150, 206, 184, 219, 58, 23, 230, 17, 206, 184, - 219, 58, 23, 230, 2, 206, 184, 219, 58, 23, 230, 19, 206, 184, 219, 58, - 23, 150, 206, 184, 216, 66, 23, 150, 206, 184, 82, 238, 254, 23, 150, - 206, 184, 82, 207, 142, 221, 45, 23, 150, 206, 184, 223, 120, 23, 150, - 206, 184, 198, 207, 23, 230, 4, 206, 184, 198, 207, 23, 150, 140, 206, - 184, 219, 58, 23, 230, 17, 140, 206, 184, 219, 58, 23, 230, 11, 140, 206, - 184, 219, 59, 211, 93, 23, 230, 4, 140, 206, 184, 219, 59, 211, 4, 23, - 230, 4, 140, 206, 184, 219, 59, 223, 134, 23, 230, 4, 140, 206, 184, 219, - 59, 196, 100, 23, 230, 13, 140, 206, 184, 219, 58, 23, 230, 6, 140, 206, - 184, 219, 58, 23, 230, 19, 140, 206, 184, 219, 59, 211, 4, 23, 230, 19, - 140, 206, 184, 219, 58, 23, 150, 82, 235, 79, 23, 230, 6, 216, 66, 23, - 150, 82, 196, 73, 23, 230, 17, 82, 196, 73, 23, 150, 82, 207, 142, 221, - 46, 23, 150, 82, 132, 174, 202, 202, 23, 230, 4, 82, 198, 207, 23, 150, - 82, 174, 219, 58, 23, 150, 82, 219, 58, 23, 150, 82, 206, 184, 219, 58, - 23, 230, 17, 82, 206, 184, 219, 58, 23, 230, 11, 82, 206, 184, 219, 59, - 211, 93, 23, 230, 13, 82, 206, 184, 219, 58, 23, 230, 6, 82, 206, 184, - 219, 58, 23, 230, 19, 82, 206, 184, 219, 59, 211, 4, 23, 230, 19, 82, - 206, 184, 219, 59, 223, 134, 23, 230, 19, 82, 206, 184, 219, 58, 23, 230, - 17, 82, 206, 184, 219, 59, 248, 173, 23, 230, 15, 82, 206, 184, 219, 59, - 238, 254, 23, 230, 15, 82, 206, 184, 219, 59, 238, 255, 202, 202, 23, - 230, 4, 82, 206, 184, 219, 59, 238, 255, 211, 4, 23, 230, 4, 82, 206, - 184, 219, 59, 238, 255, 223, 134, 23, 230, 4, 82, 206, 184, 219, 59, 238, - 254, 23, 230, 6, 140, 229, 92, 23, 150, 140, 174, 202, 202, 23, 230, 6, - 140, 174, 202, 202, 23, 150, 140, 174, 202, 203, 174, 236, 249, 23, 150, - 140, 174, 202, 203, 174, 238, 254, 23, 150, 140, 174, 202, 203, 174, 248, - 173, 23, 150, 140, 174, 202, 203, 140, 248, 173, 23, 150, 140, 174, 202, - 203, 248, 32, 248, 173, 23, 150, 140, 174, 202, 203, 140, 229, 94, 23, - 150, 140, 174, 232, 95, 140, 201, 47, 23, 150, 140, 174, 232, 95, 140, - 248, 173, 23, 150, 140, 174, 106, 23, 150, 140, 174, 238, 126, 23, 150, - 140, 174, 238, 118, 174, 223, 89, 23, 230, 15, 140, 174, 238, 118, 174, - 223, 89, 23, 150, 140, 174, 238, 118, 174, 196, 100, 23, 150, 140, 174, - 242, 218, 23, 230, 13, 140, 198, 207, 23, 230, 13, 140, 174, 211, 65, 23, - 230, 6, 140, 174, 211, 65, 23, 230, 6, 140, 174, 219, 244, 23, 230, 6, - 140, 198, 207, 23, 230, 6, 140, 174, 202, 65, 23, 230, 19, 140, 174, 211, - 4, 23, 230, 19, 140, 174, 223, 134, 23, 230, 19, 140, 198, 207, 23, 150, - 198, 207, 23, 150, 174, 229, 180, 23, 150, 174, 202, 203, 236, 249, 23, - 150, 174, 202, 203, 238, 254, 23, 150, 174, 202, 203, 248, 173, 23, 150, - 174, 232, 94, 23, 150, 174, 248, 160, 140, 216, 66, 23, 150, 174, 248, - 160, 82, 206, 183, 23, 150, 174, 248, 160, 206, 184, 219, 58, 23, 150, - 174, 196, 101, 103, 232, 206, 23, 150, 174, 138, 103, 232, 206, 23, 150, - 174, 196, 101, 115, 232, 206, 23, 150, 174, 196, 101, 232, 90, 232, 206, - 23, 150, 174, 138, 232, 90, 207, 142, 221, 45, 23, 230, 9, 23, 150, 229, - 180, 23, 198, 32, 202, 164, 23, 198, 32, 215, 113, 23, 198, 32, 248, 159, - 23, 230, 181, 202, 164, 23, 230, 181, 215, 113, 23, 230, 181, 248, 159, - 23, 201, 28, 202, 164, 23, 201, 28, 215, 113, 23, 201, 28, 248, 159, 23, - 247, 226, 202, 164, 23, 247, 226, 215, 113, 23, 247, 226, 248, 159, 23, - 206, 55, 202, 164, 23, 206, 55, 215, 113, 23, 206, 55, 248, 159, 23, 200, - 166, 200, 72, 23, 200, 166, 248, 159, 23, 201, 181, 219, 245, 202, 164, - 23, 201, 181, 2, 202, 164, 23, 201, 181, 219, 245, 215, 113, 23, 201, - 181, 2, 215, 113, 23, 201, 181, 204, 1, 23, 232, 157, 219, 245, 202, 164, - 23, 232, 157, 2, 202, 164, 23, 232, 157, 219, 245, 215, 113, 23, 232, - 157, 2, 215, 113, 23, 232, 157, 204, 1, 23, 201, 181, 232, 157, 251, 103, - 23, 215, 156, 132, 143, 219, 244, 23, 215, 156, 132, 143, 202, 65, 23, - 215, 156, 132, 204, 1, 23, 215, 156, 143, 204, 1, 23, 215, 156, 132, 143, - 251, 104, 219, 244, 23, 215, 156, 132, 143, 251, 104, 202, 65, 23, 215, - 156, 202, 203, 118, 202, 203, 205, 79, 23, 215, 155, 232, 212, 238, 244, - 23, 215, 157, 232, 212, 238, 244, 23, 215, 155, 202, 165, 201, 48, 202, - 65, 23, 215, 155, 202, 165, 201, 48, 216, 193, 23, 215, 155, 202, 165, - 201, 48, 219, 244, 23, 215, 155, 202, 165, 201, 48, 219, 242, 23, 215, - 155, 202, 165, 193, 4, 232, 160, 23, 215, 155, 54, 201, 47, 23, 215, 155, - 54, 193, 4, 232, 160, 23, 215, 155, 54, 251, 103, 23, 215, 155, 54, 251, - 104, 193, 4, 232, 160, 23, 215, 155, 238, 170, 23, 215, 155, 197, 221, - 201, 48, 215, 159, 23, 215, 155, 197, 221, 193, 4, 232, 160, 23, 215, - 155, 197, 221, 251, 103, 23, 215, 155, 197, 221, 251, 104, 193, 4, 232, - 160, 23, 215, 155, 248, 178, 202, 65, 23, 215, 155, 248, 178, 216, 193, - 23, 215, 155, 248, 178, 219, 244, 23, 215, 155, 238, 211, 202, 65, 23, - 215, 155, 238, 211, 216, 193, 23, 215, 155, 238, 211, 219, 244, 23, 215, - 155, 238, 211, 206, 115, 23, 215, 155, 243, 78, 202, 65, 23, 215, 155, - 243, 78, 216, 193, 23, 215, 155, 243, 78, 219, 244, 23, 215, 155, 111, - 202, 65, 23, 215, 155, 111, 216, 193, 23, 215, 155, 111, 219, 244, 23, - 215, 155, 191, 21, 202, 65, 23, 215, 155, 191, 21, 216, 193, 23, 215, - 155, 191, 21, 219, 244, 23, 215, 155, 210, 48, 202, 65, 23, 215, 155, - 210, 48, 216, 193, 23, 215, 155, 210, 48, 219, 244, 23, 197, 255, 206, - 113, 202, 164, 23, 197, 255, 206, 113, 235, 89, 23, 197, 255, 206, 113, - 251, 103, 23, 197, 255, 206, 114, 202, 164, 23, 197, 255, 206, 114, 235, - 89, 23, 197, 255, 206, 114, 251, 103, 23, 197, 255, 203, 139, 23, 197, - 255, 250, 201, 201, 213, 202, 164, 23, 197, 255, 250, 201, 201, 213, 235, - 89, 23, 197, 255, 250, 201, 201, 213, 197, 220, 23, 215, 158, 250, 89, - 202, 65, 23, 215, 158, 250, 89, 216, 193, 23, 215, 158, 250, 89, 219, - 244, 23, 215, 158, 250, 89, 219, 242, 23, 215, 158, 198, 26, 202, 65, 23, - 215, 158, 198, 26, 216, 193, 23, 215, 158, 198, 26, 219, 244, 23, 215, - 158, 198, 26, 219, 242, 23, 215, 158, 248, 160, 250, 89, 202, 65, 23, - 215, 158, 248, 160, 250, 89, 216, 193, 23, 215, 158, 248, 160, 250, 89, - 219, 244, 23, 215, 158, 248, 160, 250, 89, 219, 242, 23, 215, 158, 248, - 160, 198, 26, 202, 65, 23, 215, 158, 248, 160, 198, 26, 216, 193, 23, - 215, 158, 248, 160, 198, 26, 219, 244, 23, 215, 158, 248, 160, 198, 26, - 219, 242, 23, 215, 157, 202, 165, 201, 48, 202, 65, 23, 215, 157, 202, - 165, 201, 48, 216, 193, 23, 215, 157, 202, 165, 201, 48, 219, 244, 23, - 215, 157, 202, 165, 201, 48, 219, 242, 23, 215, 157, 202, 165, 193, 4, - 232, 160, 23, 215, 157, 54, 201, 47, 23, 215, 157, 54, 193, 4, 232, 160, - 23, 215, 157, 54, 251, 103, 23, 215, 157, 54, 251, 104, 193, 4, 232, 160, - 23, 215, 157, 238, 170, 23, 215, 157, 197, 221, 201, 48, 215, 159, 23, - 215, 157, 197, 221, 193, 4, 232, 160, 23, 215, 157, 197, 221, 251, 104, - 215, 159, 23, 215, 157, 197, 221, 251, 104, 193, 4, 232, 160, 23, 215, - 157, 248, 177, 23, 215, 157, 238, 211, 202, 65, 23, 215, 157, 238, 211, - 216, 193, 23, 215, 157, 238, 211, 219, 244, 23, 215, 157, 243, 77, 23, - 215, 157, 111, 202, 65, 23, 215, 157, 111, 216, 193, 23, 215, 157, 111, - 219, 244, 23, 215, 157, 191, 21, 202, 65, 23, 215, 157, 191, 21, 216, - 193, 23, 215, 157, 191, 21, 219, 244, 23, 215, 157, 210, 48, 202, 65, 23, - 215, 157, 210, 48, 216, 193, 23, 215, 157, 210, 48, 219, 244, 23, 198, 0, - 206, 114, 202, 164, 23, 198, 0, 206, 114, 235, 89, 23, 198, 0, 206, 114, - 251, 103, 23, 198, 0, 206, 113, 202, 164, 23, 198, 0, 206, 113, 235, 89, - 23, 198, 0, 206, 113, 251, 103, 23, 198, 0, 203, 139, 23, 215, 155, 238, - 118, 208, 18, 202, 65, 23, 215, 155, 238, 118, 208, 18, 216, 193, 23, - 215, 155, 238, 118, 208, 18, 219, 244, 23, 215, 155, 238, 118, 208, 18, - 219, 242, 23, 215, 155, 238, 118, 230, 34, 202, 65, 23, 215, 155, 238, - 118, 230, 34, 216, 193, 23, 215, 155, 238, 118, 230, 34, 219, 244, 23, - 215, 155, 238, 118, 230, 34, 219, 242, 23, 215, 155, 238, 118, 198, 213, - 242, 219, 202, 65, 23, 215, 155, 238, 118, 198, 213, 242, 219, 216, 193, - 23, 215, 155, 228, 112, 202, 65, 23, 215, 155, 228, 112, 216, 193, 23, - 215, 155, 228, 112, 219, 244, 23, 215, 155, 218, 237, 202, 65, 23, 215, - 155, 218, 237, 216, 193, 23, 215, 155, 218, 237, 219, 244, 23, 215, 155, - 218, 237, 2, 235, 89, 23, 215, 155, 193, 137, 238, 118, 54, 202, 65, 23, - 215, 155, 193, 137, 238, 118, 54, 216, 193, 23, 215, 155, 193, 137, 238, - 118, 54, 219, 244, 23, 215, 155, 193, 137, 238, 118, 197, 221, 202, 65, - 23, 215, 155, 193, 137, 238, 118, 197, 221, 216, 193, 23, 215, 155, 193, - 137, 238, 118, 197, 221, 219, 244, 23, 215, 155, 238, 118, 199, 20, 201, - 47, 23, 215, 155, 238, 116, 238, 171, 202, 65, 23, 215, 155, 238, 116, - 238, 171, 216, 193, 23, 206, 113, 202, 164, 23, 206, 113, 235, 89, 23, - 206, 113, 251, 105, 23, 215, 155, 203, 139, 23, 215, 155, 238, 118, 229, - 84, 232, 59, 193, 164, 23, 215, 155, 228, 112, 229, 84, 232, 59, 193, - 164, 23, 215, 155, 218, 237, 229, 84, 232, 59, 193, 164, 23, 215, 155, - 193, 137, 229, 84, 232, 59, 193, 164, 23, 206, 113, 202, 165, 229, 84, - 232, 59, 193, 164, 23, 206, 113, 54, 229, 84, 232, 59, 193, 164, 23, 206, - 113, 251, 104, 229, 84, 232, 59, 193, 164, 23, 215, 155, 238, 118, 229, - 84, 243, 56, 23, 215, 155, 228, 112, 229, 84, 243, 56, 23, 215, 155, 218, - 237, 229, 84, 243, 56, 23, 215, 155, 193, 137, 229, 84, 243, 56, 23, 206, - 113, 202, 165, 229, 84, 243, 56, 23, 206, 113, 54, 229, 84, 243, 56, 23, - 206, 113, 251, 104, 229, 84, 243, 56, 23, 215, 155, 193, 137, 236, 250, - 210, 76, 202, 65, 23, 215, 155, 193, 137, 236, 250, 210, 76, 216, 193, - 23, 215, 155, 193, 137, 236, 250, 210, 76, 219, 244, 23, 215, 157, 238, - 118, 229, 84, 246, 239, 202, 65, 23, 215, 157, 238, 118, 229, 84, 246, - 239, 219, 244, 23, 215, 157, 228, 112, 229, 84, 246, 239, 2, 235, 89, 23, - 215, 157, 228, 112, 229, 84, 246, 239, 219, 245, 235, 89, 23, 215, 157, - 228, 112, 229, 84, 246, 239, 2, 197, 220, 23, 215, 157, 228, 112, 229, - 84, 246, 239, 219, 245, 197, 220, 23, 215, 157, 218, 237, 229, 84, 246, - 239, 2, 202, 164, 23, 215, 157, 218, 237, 229, 84, 246, 239, 219, 245, - 202, 164, 23, 215, 157, 218, 237, 229, 84, 246, 239, 2, 235, 89, 23, 215, - 157, 218, 237, 229, 84, 246, 239, 219, 245, 235, 89, 23, 215, 157, 193, - 137, 229, 84, 246, 239, 202, 65, 23, 215, 157, 193, 137, 229, 84, 246, - 239, 219, 244, 23, 206, 114, 202, 165, 229, 84, 246, 238, 23, 206, 114, - 54, 229, 84, 246, 238, 23, 206, 114, 251, 104, 229, 84, 246, 238, 23, - 215, 157, 238, 118, 229, 84, 232, 154, 202, 65, 23, 215, 157, 238, 118, - 229, 84, 232, 154, 219, 244, 23, 215, 157, 228, 112, 229, 84, 232, 154, - 2, 235, 89, 23, 215, 157, 228, 112, 229, 84, 232, 154, 219, 245, 235, 89, - 23, 215, 157, 228, 112, 229, 84, 232, 154, 197, 221, 2, 197, 220, 23, - 215, 157, 228, 112, 229, 84, 232, 154, 197, 221, 219, 245, 197, 220, 23, - 215, 157, 218, 237, 229, 84, 232, 154, 2, 202, 164, 23, 215, 157, 218, - 237, 229, 84, 232, 154, 219, 245, 202, 164, 23, 215, 157, 218, 237, 229, - 84, 232, 154, 2, 235, 89, 23, 215, 157, 218, 237, 229, 84, 232, 154, 219, - 245, 235, 89, 23, 215, 157, 193, 137, 229, 84, 232, 154, 202, 65, 23, - 215, 157, 193, 137, 229, 84, 232, 154, 219, 244, 23, 206, 114, 202, 165, - 229, 84, 232, 153, 23, 206, 114, 54, 229, 84, 232, 153, 23, 206, 114, - 251, 104, 229, 84, 232, 153, 23, 215, 157, 238, 118, 202, 65, 23, 215, - 157, 238, 118, 216, 193, 23, 215, 157, 238, 118, 219, 244, 23, 215, 157, - 238, 118, 219, 242, 23, 215, 157, 238, 118, 242, 30, 23, 215, 157, 228, - 112, 202, 65, 23, 215, 157, 218, 237, 202, 65, 23, 215, 157, 193, 137, - 202, 53, 23, 215, 157, 193, 137, 202, 65, 23, 215, 157, 193, 137, 219, - 244, 23, 206, 114, 202, 164, 23, 206, 114, 235, 89, 23, 206, 114, 251, - 103, 23, 215, 157, 203, 140, 210, 108, 23, 215, 155, 250, 201, 242, 219, - 2, 202, 164, 23, 215, 155, 250, 201, 242, 219, 216, 194, 202, 164, 23, - 215, 155, 250, 201, 242, 219, 2, 235, 89, 23, 215, 155, 250, 201, 242, - 219, 216, 194, 235, 89, 23, 215, 157, 250, 201, 242, 219, 229, 84, 193, - 165, 2, 202, 164, 23, 215, 157, 250, 201, 242, 219, 229, 84, 193, 165, - 216, 194, 202, 164, 23, 215, 157, 250, 201, 242, 219, 229, 84, 193, 165, - 219, 245, 202, 164, 23, 215, 157, 250, 201, 242, 219, 229, 84, 193, 165, - 2, 235, 89, 23, 215, 157, 250, 201, 242, 219, 229, 84, 193, 165, 216, - 194, 235, 89, 23, 215, 157, 250, 201, 242, 219, 229, 84, 193, 165, 219, - 245, 235, 89, 23, 215, 155, 193, 4, 242, 219, 232, 59, 202, 164, 23, 215, - 155, 193, 4, 242, 219, 232, 59, 235, 89, 23, 215, 157, 193, 4, 242, 219, - 229, 84, 193, 165, 202, 164, 23, 215, 157, 193, 4, 242, 219, 229, 84, - 193, 165, 235, 89, 23, 215, 155, 232, 212, 242, 216, 202, 164, 23, 215, - 155, 232, 212, 242, 216, 235, 89, 23, 215, 157, 232, 212, 242, 216, 229, - 84, 193, 165, 202, 164, 23, 215, 157, 232, 212, 242, 216, 229, 84, 193, - 165, 235, 89, 23, 234, 252, 250, 186, 202, 65, 23, 234, 252, 250, 186, - 219, 244, 23, 234, 252, 233, 32, 23, 234, 252, 202, 70, 23, 234, 252, - 199, 83, 23, 234, 252, 207, 58, 23, 234, 252, 202, 171, 23, 234, 252, - 202, 172, 251, 103, 23, 234, 252, 233, 184, 211, 17, 198, 141, 23, 234, - 252, 230, 192, 23, 229, 203, 23, 229, 204, 206, 188, 23, 229, 204, 215, - 155, 201, 47, 23, 229, 204, 215, 155, 198, 144, 23, 229, 204, 215, 157, - 201, 47, 23, 229, 204, 215, 155, 238, 117, 23, 229, 204, 215, 157, 238, - 117, 23, 229, 204, 215, 160, 242, 218, 23, 233, 63, 236, 188, 209, 18, - 213, 1, 232, 95, 198, 142, 23, 233, 63, 236, 188, 209, 18, 213, 1, 132, - 211, 46, 235, 79, 23, 233, 63, 236, 188, 209, 18, 213, 1, 132, 211, 46, - 143, 198, 142, 23, 233, 150, 201, 48, 196, 73, 23, 233, 150, 201, 48, - 214, 67, 23, 233, 150, 201, 48, 235, 79, 23, 235, 63, 233, 150, 214, 68, - 235, 79, 23, 235, 63, 233, 150, 143, 214, 67, 23, 235, 63, 233, 150, 132, - 214, 67, 23, 235, 63, 233, 150, 214, 68, 196, 73, 23, 232, 112, 214, 67, - 23, 232, 112, 238, 244, 23, 232, 112, 193, 7, 23, 233, 145, 211, 65, 23, - 233, 145, 201, 180, 23, 233, 145, 242, 170, 23, 233, 153, 248, 82, 202, - 164, 23, 233, 153, 248, 82, 215, 113, 23, 233, 145, 134, 211, 65, 23, - 233, 145, 193, 76, 211, 65, 23, 233, 145, 134, 242, 170, 23, 233, 145, - 193, 74, 215, 159, 23, 233, 153, 193, 57, 23, 233, 146, 196, 73, 23, 233, - 146, 235, 79, 23, 233, 146, 232, 140, 23, 233, 148, 201, 47, 23, 233, - 148, 201, 48, 235, 89, 23, 233, 148, 201, 48, 251, 103, 23, 233, 149, - 201, 47, 23, 233, 149, 201, 48, 235, 89, 23, 233, 149, 201, 48, 251, 103, - 23, 233, 148, 238, 115, 23, 233, 149, 238, 115, 23, 233, 148, 242, 213, - 23, 243, 73, 208, 148, 23, 243, 73, 214, 67, 23, 243, 73, 200, 213, 23, - 199, 84, 243, 73, 229, 103, 23, 199, 84, 243, 73, 216, 66, 23, 199, 84, - 243, 73, 218, 219, 23, 234, 165, 23, 213, 1, 214, 67, 23, 213, 1, 238, - 244, 23, 213, 1, 193, 5, 23, 213, 1, 193, 71, 23, 251, 174, 248, 68, 211, - 4, 23, 251, 174, 200, 212, 223, 134, 23, 251, 174, 248, 70, 2, 206, 112, - 23, 251, 174, 200, 214, 2, 206, 112, 23, 247, 247, 223, 106, 23, 247, - 247, 233, 173, 23, 215, 164, 242, 171, 214, 67, 23, 215, 164, 242, 171, - 232, 94, 23, 215, 164, 242, 171, 238, 244, 23, 215, 164, 202, 60, 23, - 215, 164, 202, 61, 193, 7, 23, 215, 164, 202, 61, 211, 65, 23, 215, 164, - 232, 55, 23, 215, 164, 232, 56, 193, 7, 23, 215, 164, 232, 56, 211, 65, - 23, 215, 164, 211, 66, 242, 218, 23, 215, 164, 211, 66, 232, 94, 23, 215, - 164, 211, 66, 193, 7, 23, 215, 164, 211, 66, 210, 253, 23, 215, 164, 211, - 66, 210, 254, 193, 7, 23, 215, 164, 211, 66, 210, 254, 192, 88, 23, 215, - 164, 211, 66, 207, 87, 23, 215, 164, 211, 66, 207, 88, 193, 7, 23, 215, - 164, 211, 66, 207, 88, 192, 88, 23, 215, 164, 221, 98, 23, 215, 164, 221, - 99, 232, 94, 23, 215, 164, 221, 99, 193, 7, 23, 215, 164, 199, 83, 23, - 215, 164, 199, 84, 232, 94, 23, 215, 164, 199, 84, 200, 213, 23, 219, 73, - 208, 212, 198, 82, 23, 219, 75, 110, 138, 196, 70, 23, 219, 75, 116, 138, - 218, 214, 23, 215, 164, 238, 209, 23, 215, 164, 193, 6, 202, 164, 23, - 215, 164, 193, 6, 235, 89, 23, 198, 57, 201, 69, 211, 5, 233, 34, 23, - 198, 57, 219, 118, 219, 72, 23, 198, 57, 198, 131, 248, 160, 219, 72, 23, - 198, 57, 198, 131, 198, 30, 223, 90, 215, 163, 23, 198, 57, 223, 90, 215, - 164, 207, 58, 23, 198, 57, 215, 154, 251, 199, 243, 74, 23, 198, 57, 246, - 230, 201, 69, 211, 4, 23, 198, 57, 246, 230, 223, 90, 215, 163, 23, 199, - 112, 23, 199, 113, 215, 159, 23, 199, 113, 211, 94, 198, 56, 23, 199, - 113, 211, 94, 198, 57, 215, 159, 23, 199, 113, 211, 94, 219, 72, 23, 199, - 113, 211, 94, 219, 73, 215, 159, 23, 199, 113, 248, 98, 219, 72, 23, 215, - 155, 222, 242, 23, 215, 157, 222, 242, 23, 214, 98, 23, 230, 45, 23, 233, - 176, 23, 203, 17, 229, 91, 201, 214, 23, 203, 17, 229, 91, 209, 16, 23, - 193, 163, 203, 17, 229, 91, 215, 162, 23, 232, 152, 203, 17, 229, 91, - 215, 162, 23, 203, 17, 198, 143, 232, 60, 193, 169, 23, 198, 38, 201, 48, - 201, 32, 23, 198, 38, 238, 116, 248, 177, 23, 198, 39, 197, 12, 23, 116, - 248, 57, 198, 143, 232, 60, 229, 91, 222, 168, 23, 219, 100, 242, 31, 23, - 219, 100, 219, 173, 23, 219, 100, 219, 172, 23, 219, 100, 219, 171, 23, - 219, 100, 219, 170, 23, 219, 100, 219, 169, 23, 219, 100, 219, 168, 23, - 219, 100, 219, 167, 23, 232, 211, 23, 219, 13, 201, 242, 23, 219, 14, - 201, 242, 23, 219, 16, 229, 176, 23, 219, 16, 193, 72, 23, 219, 16, 237, - 47, 23, 219, 16, 229, 204, 214, 98, 23, 219, 16, 198, 40, 23, 219, 16, - 219, 99, 236, 220, 23, 242, 26, 23, 232, 42, 201, 58, 23, 204, 20, 23, - 242, 35, 23, 210, 103, 23, 232, 221, 215, 227, 23, 232, 221, 215, 226, - 23, 232, 221, 215, 225, 23, 232, 221, 215, 224, 23, 232, 221, 215, 223, - 23, 206, 116, 215, 227, 23, 206, 116, 215, 226, 23, 206, 116, 215, 225, - 23, 206, 116, 215, 224, 23, 206, 116, 215, 223, 23, 206, 116, 215, 222, - 23, 206, 116, 215, 221, 23, 206, 116, 215, 220, 23, 206, 116, 215, 234, - 23, 206, 116, 215, 233, 23, 206, 116, 215, 232, 23, 206, 116, 215, 231, - 23, 206, 116, 215, 230, 23, 206, 116, 215, 229, 23, 206, 116, 215, 228, - 8, 2, 1, 232, 252, 236, 214, 4, 197, 224, 8, 2, 1, 207, 13, 27, 232, 14, - 8, 1, 2, 6, 152, 232, 14, 8, 2, 1, 207, 13, 222, 125, 8, 1, 2, 6, 220, - 119, 4, 248, 181, 8, 2, 1, 219, 139, 4, 207, 19, 106, 8, 2, 1, 152, 192, - 160, 4, 248, 181, 8, 2, 1, 207, 13, 234, 46, 8, 2, 1, 152, 207, 217, 4, - 177, 219, 189, 24, 207, 19, 106, 8, 2, 1, 200, 40, 4, 228, 219, 24, 207, - 19, 106, 8, 1, 207, 19, 242, 184, 4, 207, 19, 106, 8, 2, 1, 233, 227, 4, - 54, 164, 8, 2, 1, 233, 227, 4, 54, 249, 38, 24, 238, 128, 8, 2, 1, 152, - 200, 40, 4, 238, 128, 8, 1, 223, 65, 230, 231, 201, 59, 4, 238, 128, 8, - 1, 201, 31, 247, 146, 4, 238, 128, 8, 1, 2, 6, 152, 222, 125, 8, 2, 1, - 220, 119, 4, 232, 192, 8, 2, 1, 237, 25, 236, 214, 4, 210, 182, 106, 8, - 2, 1, 220, 119, 4, 248, 182, 24, 210, 182, 106, 8, 2, 1, 234, 47, 4, 210, - 182, 106, 8, 2, 1, 152, 207, 217, 4, 210, 182, 106, 8, 2, 1, 207, 217, 4, - 232, 193, 24, 210, 182, 106, 8, 2, 1, 199, 74, 236, 214, 4, 210, 182, - 106, 8, 2, 1, 233, 138, 4, 210, 182, 106, 8, 2, 1, 237, 25, 236, 214, 4, - 207, 19, 106, 8, 2, 1, 228, 44, 4, 201, 23, 24, 207, 19, 106, 8, 2, 1, - 186, 4, 207, 19, 106, 8, 2, 1, 199, 74, 236, 214, 4, 207, 19, 106, 8, 2, - 1, 247, 146, 4, 207, 19, 106, 8, 2, 1, 206, 4, 4, 238, 128, 33, 133, 1, - 250, 72, 33, 133, 1, 247, 204, 33, 133, 1, 195, 148, 33, 133, 1, 230, - 238, 33, 133, 1, 236, 124, 33, 133, 1, 192, 49, 33, 133, 1, 191, 55, 33, - 133, 1, 191, 82, 33, 133, 1, 223, 11, 33, 133, 1, 89, 223, 11, 33, 133, - 1, 70, 33, 133, 1, 236, 145, 33, 133, 1, 222, 67, 33, 133, 1, 219, 51, - 33, 133, 1, 215, 52, 33, 133, 1, 214, 196, 33, 133, 1, 211, 78, 33, 133, - 1, 209, 48, 33, 133, 1, 206, 174, 33, 133, 1, 202, 72, 33, 133, 1, 197, - 40, 33, 133, 1, 196, 120, 33, 133, 1, 232, 63, 33, 133, 1, 229, 156, 33, - 133, 1, 203, 3, 33, 133, 1, 197, 142, 33, 133, 1, 243, 6, 33, 133, 1, - 203, 160, 33, 133, 1, 192, 58, 33, 133, 1, 192, 60, 33, 133, 1, 192, 93, - 33, 133, 1, 191, 225, 33, 133, 1, 2, 191, 190, 33, 133, 1, 192, 12, 33, - 133, 1, 223, 54, 2, 191, 190, 33, 133, 1, 248, 127, 191, 190, 33, 133, 1, - 223, 54, 248, 127, 191, 190, 33, 133, 1, 232, 187, 212, 67, 208, 155, 90, - 1, 172, 212, 67, 208, 155, 90, 1, 197, 164, 212, 67, 208, 155, 90, 1, - 212, 186, 212, 67, 208, 155, 90, 1, 199, 247, 212, 67, 208, 155, 90, 1, - 144, 212, 67, 208, 155, 90, 1, 180, 212, 67, 208, 155, 90, 1, 192, 220, - 212, 67, 208, 155, 90, 1, 213, 98, 212, 67, 208, 155, 90, 1, 247, 112, - 212, 67, 208, 155, 90, 1, 171, 212, 67, 208, 155, 90, 1, 189, 212, 67, - 208, 155, 90, 1, 191, 123, 212, 67, 208, 155, 90, 1, 214, 152, 212, 67, - 208, 155, 90, 1, 212, 173, 212, 67, 208, 155, 90, 1, 157, 212, 67, 208, - 155, 90, 1, 237, 241, 212, 67, 208, 155, 90, 1, 212, 88, 212, 67, 208, - 155, 90, 1, 212, 231, 212, 67, 208, 155, 90, 1, 195, 185, 212, 67, 208, - 155, 90, 1, 212, 167, 212, 67, 208, 155, 90, 1, 197, 4, 212, 67, 208, - 155, 90, 1, 233, 68, 212, 67, 208, 155, 90, 1, 166, 212, 67, 208, 155, - 90, 1, 208, 89, 212, 67, 208, 155, 90, 1, 169, 212, 67, 208, 155, 90, 1, - 212, 233, 212, 67, 208, 155, 90, 1, 168, 212, 67, 208, 155, 90, 1, 192, - 175, 212, 67, 208, 155, 90, 1, 212, 235, 212, 67, 208, 155, 90, 1, 236, - 141, 212, 67, 208, 155, 90, 1, 212, 234, 212, 67, 208, 155, 90, 1, 230, - 48, 212, 67, 208, 155, 90, 1, 216, 2, 212, 67, 208, 155, 90, 1, 209, 102, - 212, 67, 208, 155, 90, 1, 231, 203, 212, 67, 208, 155, 90, 1, 206, 104, - 212, 67, 208, 155, 90, 1, 65, 212, 67, 208, 155, 90, 1, 252, 154, 212, - 67, 208, 155, 90, 1, 70, 212, 67, 208, 155, 90, 1, 69, 212, 67, 208, 155, - 90, 1, 74, 212, 67, 208, 155, 90, 1, 211, 76, 212, 67, 208, 155, 90, 1, - 73, 212, 67, 208, 155, 90, 1, 234, 145, 212, 67, 208, 155, 90, 1, 193, - 221, 212, 67, 208, 155, 90, 198, 65, 212, 67, 208, 155, 90, 198, 61, 212, - 67, 208, 155, 90, 198, 62, 212, 67, 208, 155, 90, 198, 59, 212, 67, 208, - 155, 90, 198, 60, 212, 67, 208, 155, 90, 198, 63, 212, 67, 208, 155, 90, - 198, 64, 212, 67, 208, 155, 90, 3, 39, 209, 241, 212, 67, 208, 155, 90, - 3, 39, 198, 254, 212, 67, 208, 155, 90, 3, 39, 219, 15, 212, 67, 208, - 155, 90, 3, 39, 251, 50, 212, 67, 208, 155, 90, 3, 39, 223, 66, 212, 67, - 208, 155, 90, 3, 192, 183, 192, 182, 212, 67, 208, 155, 90, 5, 219, 166, - 212, 67, 208, 155, 90, 17, 191, 77, 212, 67, 208, 155, 90, 17, 108, 212, - 67, 208, 155, 90, 17, 109, 212, 67, 208, 155, 90, 17, 139, 212, 67, 208, - 155, 90, 17, 137, 212, 67, 208, 155, 90, 17, 153, 212, 67, 208, 155, 90, - 17, 173, 212, 67, 208, 155, 90, 17, 181, 212, 67, 208, 155, 90, 17, 176, - 212, 67, 208, 155, 90, 17, 184, 212, 67, 208, 155, 90, 219, 4, 212, 83, - 212, 67, 208, 155, 90, 47, 247, 112, 198, 33, 1, 168, 198, 33, 1, 249, - 103, 198, 33, 1, 199, 247, 198, 33, 1, 237, 241, 198, 33, 1, 157, 198, - 33, 1, 231, 203, 198, 33, 1, 172, 198, 33, 1, 180, 198, 33, 1, 214, 54, - 198, 33, 1, 189, 198, 33, 1, 246, 209, 198, 33, 1, 169, 198, 33, 1, 193, - 187, 198, 33, 1, 223, 4, 198, 33, 1, 144, 198, 33, 1, 166, 198, 33, 1, - 171, 198, 33, 1, 70, 198, 33, 1, 247, 246, 70, 198, 33, 1, 223, 21, 198, - 33, 1, 247, 246, 223, 21, 198, 33, 1, 69, 198, 33, 1, 73, 198, 33, 1, - 247, 246, 73, 198, 33, 1, 234, 23, 198, 33, 1, 247, 246, 234, 23, 198, - 33, 1, 74, 198, 33, 1, 251, 229, 198, 33, 1, 247, 246, 251, 229, 198, 33, - 1, 65, 198, 33, 3, 206, 175, 198, 74, 193, 161, 1, 252, 154, 193, 161, 1, - 65, 193, 161, 1, 249, 103, 193, 161, 1, 247, 112, 193, 161, 1, 237, 241, - 193, 161, 1, 231, 203, 193, 161, 1, 169, 193, 161, 1, 209, 219, 193, 161, - 1, 171, 193, 161, 1, 180, 193, 161, 1, 168, 193, 161, 1, 199, 247, 193, - 161, 1, 199, 44, 193, 161, 1, 233, 68, 193, 161, 1, 189, 193, 161, 1, - 203, 160, 193, 161, 1, 223, 4, 193, 161, 1, 191, 123, 193, 161, 1, 193, - 187, 193, 161, 1, 195, 185, 193, 161, 1, 157, 193, 161, 1, 74, 193, 161, - 1, 250, 113, 193, 161, 1, 166, 193, 161, 1, 172, 193, 161, 1, 221, 190, - 193, 161, 1, 144, 193, 161, 1, 73, 193, 161, 1, 70, 193, 161, 1, 214, 54, - 193, 161, 1, 69, 193, 161, 1, 219, 42, 193, 161, 1, 197, 164, 193, 161, - 1, 198, 22, 193, 161, 1, 211, 83, 193, 161, 1, 252, 113, 193, 161, 1, - 251, 71, 193, 161, 1, 223, 108, 193, 161, 1, 211, 93, 193, 161, 1, 234, - 61, 193, 161, 1, 252, 114, 193, 161, 1, 212, 88, 193, 161, 1, 196, 143, - 193, 161, 1, 192, 24, 193, 161, 163, 197, 63, 193, 161, 163, 197, 62, - 193, 161, 163, 221, 30, 193, 161, 163, 221, 29, 193, 161, 17, 191, 77, - 193, 161, 17, 108, 193, 161, 17, 109, 193, 161, 17, 139, 193, 161, 17, - 137, 193, 161, 17, 153, 193, 161, 17, 173, 193, 161, 17, 181, 193, 161, - 17, 176, 193, 161, 17, 184, 193, 161, 213, 218, 57, 36, 5, 229, 134, 36, - 5, 229, 128, 36, 5, 229, 130, 36, 5, 229, 133, 36, 5, 229, 131, 36, 5, - 229, 132, 36, 5, 229, 129, 36, 5, 230, 114, 229, 138, 36, 5, 229, 135, - 36, 5, 229, 136, 36, 5, 229, 137, 36, 5, 230, 114, 215, 62, 36, 5, 230, - 114, 215, 63, 36, 5, 230, 114, 207, 231, 36, 5, 230, 114, 207, 232, 36, - 5, 230, 114, 207, 233, 36, 5, 230, 114, 247, 159, 36, 5, 230, 114, 247, - 160, 36, 5, 230, 114, 220, 148, 36, 5, 230, 114, 220, 149, 36, 5, 230, - 114, 220, 150, 36, 5, 230, 114, 230, 98, 36, 5, 230, 114, 230, 99, 36, 5, - 230, 114, 230, 100, 36, 5, 230, 114, 232, 21, 36, 5, 230, 114, 232, 22, - 36, 5, 230, 114, 208, 111, 36, 5, 230, 114, 208, 112, 85, 84, 5, 218, - 146, 221, 142, 85, 84, 5, 218, 142, 157, 85, 84, 5, 218, 140, 220, 208, - 85, 84, 5, 218, 16, 221, 244, 85, 84, 5, 217, 242, 221, 253, 85, 84, 5, - 218, 5, 221, 17, 85, 84, 5, 218, 33, 221, 43, 85, 84, 5, 217, 158, 220, - 195, 85, 84, 5, 218, 137, 193, 84, 85, 84, 5, 218, 135, 193, 187, 85, 84, - 5, 218, 133, 193, 0, 85, 84, 5, 217, 211, 193, 112, 85, 84, 5, 217, 219, - 193, 123, 85, 84, 5, 217, 223, 193, 29, 85, 84, 5, 218, 36, 193, 48, 85, - 84, 5, 217, 143, 192, 252, 85, 84, 5, 217, 194, 193, 110, 85, 84, 5, 218, - 20, 192, 240, 85, 84, 5, 218, 32, 192, 242, 85, 84, 5, 217, 198, 192, - 241, 85, 84, 5, 218, 131, 216, 26, 85, 84, 5, 218, 129, 217, 70, 85, 84, - 5, 218, 127, 215, 107, 85, 84, 5, 218, 22, 216, 167, 85, 84, 5, 217, 243, - 215, 214, 85, 84, 5, 217, 183, 215, 132, 85, 84, 5, 217, 148, 215, 126, - 85, 84, 5, 218, 125, 248, 140, 85, 84, 5, 218, 122, 249, 103, 85, 84, 5, - 218, 120, 247, 218, 85, 84, 5, 217, 187, 248, 207, 85, 84, 5, 217, 240, - 248, 223, 85, 84, 5, 217, 234, 248, 49, 85, 84, 5, 217, 199, 248, 63, 85, - 84, 5, 218, 110, 70, 85, 84, 5, 218, 108, 65, 85, 84, 5, 218, 106, 69, - 85, 84, 5, 217, 174, 234, 145, 85, 84, 5, 217, 237, 73, 85, 84, 5, 217, - 172, 211, 76, 85, 84, 5, 217, 190, 74, 85, 84, 5, 217, 200, 234, 123, 85, - 84, 5, 217, 206, 223, 134, 85, 84, 5, 217, 202, 223, 134, 85, 84, 5, 217, - 142, 251, 81, 85, 84, 5, 217, 159, 234, 61, 85, 84, 5, 218, 95, 202, 217, - 85, 84, 5, 218, 93, 189, 85, 84, 5, 218, 91, 200, 255, 85, 84, 5, 217, - 175, 205, 45, 85, 84, 5, 217, 221, 205, 63, 85, 84, 5, 217, 201, 202, 11, - 85, 84, 5, 218, 2, 202, 41, 85, 84, 5, 217, 141, 202, 210, 85, 84, 5, - 218, 81, 219, 122, 85, 84, 5, 218, 79, 171, 85, 84, 5, 218, 77, 218, 203, - 85, 84, 5, 217, 253, 219, 204, 85, 84, 5, 218, 8, 219, 214, 85, 84, 5, - 218, 27, 218, 240, 85, 84, 5, 217, 184, 219, 19, 85, 84, 5, 217, 227, - 177, 219, 214, 85, 84, 5, 218, 103, 236, 255, 85, 84, 5, 218, 100, 237, - 241, 85, 84, 5, 218, 97, 235, 45, 85, 84, 5, 217, 248, 237, 86, 85, 84, - 5, 217, 157, 236, 102, 85, 84, 5, 217, 156, 236, 129, 85, 84, 5, 218, 89, - 198, 188, 85, 84, 5, 218, 86, 199, 247, 85, 84, 5, 218, 84, 197, 90, 85, - 84, 5, 217, 246, 199, 116, 85, 84, 5, 218, 26, 199, 140, 85, 84, 5, 217, - 233, 198, 54, 85, 84, 5, 218, 12, 159, 85, 84, 5, 218, 75, 222, 217, 85, - 84, 5, 218, 72, 223, 4, 85, 84, 5, 218, 70, 222, 155, 85, 84, 5, 217, - 180, 222, 236, 85, 84, 5, 217, 224, 222, 238, 85, 84, 5, 217, 177, 222, - 164, 85, 84, 5, 218, 18, 222, 174, 85, 84, 5, 217, 162, 177, 222, 174, - 85, 84, 5, 218, 68, 192, 33, 85, 84, 5, 218, 65, 169, 85, 84, 5, 218, 63, - 191, 225, 85, 84, 5, 217, 228, 192, 77, 85, 84, 5, 218, 1, 192, 80, 85, - 84, 5, 217, 196, 191, 246, 85, 84, 5, 217, 216, 192, 12, 85, 84, 5, 218, - 59, 232, 238, 85, 84, 5, 218, 57, 233, 68, 85, 84, 5, 218, 55, 232, 48, - 85, 84, 5, 218, 3, 233, 11, 85, 84, 5, 218, 6, 233, 18, 85, 84, 5, 217, - 204, 232, 123, 85, 84, 5, 217, 249, 232, 135, 85, 84, 5, 217, 140, 232, - 47, 85, 84, 5, 217, 236, 233, 39, 85, 84, 5, 218, 53, 213, 165, 85, 84, - 5, 218, 51, 214, 212, 85, 84, 5, 218, 49, 212, 117, 85, 84, 5, 217, 220, - 214, 88, 85, 84, 5, 217, 168, 213, 18, 85, 84, 5, 217, 161, 229, 126, 85, - 84, 5, 218, 44, 144, 85, 84, 5, 217, 151, 228, 128, 85, 84, 5, 218, 47, - 229, 183, 85, 84, 5, 217, 241, 229, 213, 85, 84, 5, 218, 42, 228, 220, - 85, 84, 5, 217, 197, 228, 247, 85, 84, 5, 217, 254, 229, 182, 85, 84, 5, - 217, 209, 228, 213, 85, 84, 5, 218, 28, 229, 96, 85, 84, 5, 217, 207, - 230, 23, 85, 84, 5, 217, 250, 228, 111, 85, 84, 5, 218, 29, 229, 166, 85, - 84, 5, 217, 144, 228, 223, 85, 84, 5, 218, 35, 228, 124, 85, 84, 5, 217, - 247, 214, 19, 85, 84, 5, 218, 40, 214, 33, 85, 84, 5, 217, 255, 214, 16, - 85, 84, 5, 217, 222, 214, 27, 85, 84, 5, 217, 191, 214, 28, 85, 84, 5, - 217, 181, 214, 17, 85, 84, 5, 217, 217, 214, 18, 85, 84, 5, 217, 178, - 214, 32, 85, 84, 5, 217, 210, 214, 15, 85, 84, 5, 217, 251, 177, 214, 28, - 85, 84, 5, 217, 231, 177, 214, 17, 85, 84, 5, 217, 154, 177, 214, 18, 85, - 84, 5, 217, 182, 231, 16, 85, 84, 5, 217, 226, 231, 203, 85, 84, 5, 217, - 169, 230, 146, 85, 84, 5, 217, 147, 231, 120, 85, 84, 5, 217, 171, 230, - 132, 85, 84, 5, 217, 170, 230, 142, 85, 84, 5, 217, 153, 214, 38, 85, 84, - 5, 218, 24, 213, 231, 85, 84, 5, 217, 160, 213, 220, 85, 84, 5, 218, 13, - 209, 176, 85, 84, 5, 217, 238, 168, 85, 84, 5, 218, 31, 208, 158, 85, 84, - 5, 218, 0, 210, 40, 85, 84, 5, 218, 30, 210, 53, 85, 84, 5, 217, 235, - 209, 30, 85, 84, 5, 218, 15, 209, 65, 85, 84, 5, 217, 192, 216, 233, 85, - 84, 5, 218, 19, 216, 248, 85, 84, 5, 217, 215, 216, 227, 85, 84, 5, 218, - 34, 216, 240, 85, 84, 5, 217, 149, 216, 240, 85, 84, 5, 218, 9, 216, 241, - 85, 84, 5, 217, 165, 216, 228, 85, 84, 5, 217, 163, 216, 229, 85, 84, 5, - 217, 150, 216, 221, 85, 84, 5, 217, 176, 177, 216, 241, 85, 84, 5, 217, - 232, 177, 216, 228, 85, 84, 5, 217, 195, 177, 216, 229, 85, 84, 5, 217, - 205, 220, 245, 85, 84, 5, 217, 245, 220, 253, 85, 84, 5, 218, 7, 220, - 241, 85, 84, 5, 218, 38, 220, 248, 85, 84, 5, 217, 229, 220, 249, 85, 84, - 5, 217, 225, 220, 243, 85, 84, 5, 217, 179, 220, 244, 85, 84, 5, 217, - 213, 231, 137, 85, 84, 5, 218, 25, 231, 145, 85, 84, 5, 217, 189, 231, - 132, 85, 84, 5, 217, 244, 231, 141, 85, 84, 5, 217, 230, 231, 142, 85, - 84, 5, 218, 10, 231, 133, 85, 84, 5, 218, 11, 231, 135, 85, 84, 5, 217, - 166, 166, 85, 84, 5, 217, 214, 214, 133, 85, 84, 5, 217, 208, 214, 148, - 85, 84, 5, 217, 212, 214, 115, 85, 84, 5, 217, 146, 214, 139, 85, 84, 5, - 217, 218, 214, 140, 85, 84, 5, 218, 14, 214, 120, 85, 84, 5, 218, 17, - 214, 124, 85, 84, 5, 217, 185, 213, 144, 85, 84, 5, 217, 145, 213, 114, - 85, 84, 5, 217, 188, 213, 135, 85, 84, 5, 217, 203, 213, 118, 85, 84, 5, - 217, 155, 195, 66, 85, 84, 5, 217, 152, 195, 185, 85, 84, 5, 217, 186, - 193, 246, 85, 84, 5, 217, 164, 195, 145, 85, 84, 5, 217, 252, 195, 150, - 85, 84, 5, 217, 193, 195, 5, 85, 84, 5, 218, 4, 195, 21, 85, 84, 5, 217, - 173, 212, 61, 85, 84, 5, 218, 23, 212, 81, 85, 84, 5, 217, 167, 212, 43, - 85, 84, 5, 217, 239, 212, 73, 85, 84, 5, 218, 21, 212, 50, 85, 84, 17, - 108, 85, 84, 17, 109, 85, 84, 17, 139, 85, 84, 17, 137, 85, 84, 17, 153, - 85, 84, 17, 173, 85, 84, 17, 181, 85, 84, 17, 176, 85, 84, 17, 184, 85, - 84, 33, 31, 199, 114, 85, 84, 33, 31, 199, 85, 85, 84, 33, 31, 228, 107, - 85, 84, 33, 31, 198, 223, 85, 84, 33, 31, 199, 91, 198, 223, 85, 84, 33, - 31, 228, 110, 198, 223, 85, 84, 33, 31, 216, 29, 251, 237, 6, 1, 251, - 129, 251, 237, 6, 1, 237, 238, 251, 237, 6, 1, 220, 99, 251, 237, 6, 1, - 216, 42, 251, 237, 6, 1, 249, 103, 251, 237, 6, 1, 202, 159, 251, 237, 6, - 1, 210, 53, 251, 237, 6, 1, 248, 148, 251, 237, 6, 1, 166, 251, 237, 6, - 1, 73, 251, 237, 6, 1, 233, 68, 251, 237, 6, 1, 70, 251, 237, 6, 1, 74, - 251, 237, 6, 1, 237, 23, 251, 237, 6, 1, 192, 34, 251, 237, 6, 1, 193, - 131, 251, 237, 6, 1, 212, 117, 251, 237, 6, 1, 222, 79, 251, 237, 6, 1, - 169, 251, 237, 6, 1, 69, 251, 237, 6, 1, 222, 208, 251, 237, 6, 1, 243, - 47, 251, 237, 6, 1, 144, 251, 237, 6, 1, 208, 87, 251, 237, 6, 1, 231, - 203, 251, 237, 6, 1, 212, 88, 251, 237, 6, 1, 197, 90, 251, 237, 6, 1, - 213, 210, 251, 237, 6, 1, 195, 185, 251, 237, 6, 1, 221, 190, 251, 237, - 6, 1, 231, 142, 251, 237, 6, 1, 191, 108, 251, 237, 6, 1, 220, 244, 251, - 237, 6, 1, 203, 160, 251, 237, 2, 1, 251, 129, 251, 237, 2, 1, 237, 238, - 251, 237, 2, 1, 220, 99, 251, 237, 2, 1, 216, 42, 251, 237, 2, 1, 249, - 103, 251, 237, 2, 1, 202, 159, 251, 237, 2, 1, 210, 53, 251, 237, 2, 1, - 248, 148, 251, 237, 2, 1, 166, 251, 237, 2, 1, 73, 251, 237, 2, 1, 233, - 68, 251, 237, 2, 1, 70, 251, 237, 2, 1, 74, 251, 237, 2, 1, 237, 23, 251, - 237, 2, 1, 192, 34, 251, 237, 2, 1, 193, 131, 251, 237, 2, 1, 212, 117, - 251, 237, 2, 1, 222, 79, 251, 237, 2, 1, 169, 251, 237, 2, 1, 69, 251, - 237, 2, 1, 222, 208, 251, 237, 2, 1, 243, 47, 251, 237, 2, 1, 144, 251, - 237, 2, 1, 208, 87, 251, 237, 2, 1, 231, 203, 251, 237, 2, 1, 212, 88, - 251, 237, 2, 1, 197, 90, 251, 237, 2, 1, 213, 210, 251, 237, 2, 1, 195, - 185, 251, 237, 2, 1, 221, 190, 251, 237, 2, 1, 231, 142, 251, 237, 2, 1, - 191, 108, 251, 237, 2, 1, 220, 244, 251, 237, 2, 1, 203, 160, 251, 237, - 251, 130, 219, 166, 251, 237, 18, 219, 166, 251, 237, 231, 116, 77, 251, - 237, 230, 24, 251, 237, 119, 215, 235, 251, 237, 231, 117, 119, 215, 235, - 251, 237, 212, 128, 251, 237, 214, 199, 77, 251, 237, 17, 191, 77, 251, - 237, 17, 108, 251, 237, 17, 109, 251, 237, 17, 139, 251, 237, 17, 137, - 251, 237, 17, 153, 251, 237, 17, 173, 251, 237, 17, 181, 251, 237, 17, - 176, 251, 237, 17, 184, 251, 237, 89, 233, 175, 77, 251, 237, 89, 208, 8, - 77, 223, 118, 142, 31, 108, 223, 118, 142, 31, 109, 223, 118, 142, 31, - 139, 223, 118, 142, 31, 137, 223, 118, 142, 31, 153, 223, 118, 142, 31, - 173, 223, 118, 142, 31, 181, 223, 118, 142, 31, 176, 223, 118, 142, 31, - 184, 223, 118, 142, 31, 199, 90, 223, 118, 142, 31, 197, 28, 223, 118, - 142, 31, 198, 244, 223, 118, 142, 31, 232, 97, 223, 118, 142, 31, 232, - 230, 223, 118, 142, 31, 202, 115, 223, 118, 142, 31, 203, 236, 223, 118, - 142, 31, 234, 110, 223, 118, 142, 31, 213, 156, 223, 118, 142, 31, 91, - 228, 109, 223, 118, 142, 31, 103, 228, 109, 223, 118, 142, 31, 115, 228, - 109, 223, 118, 142, 31, 232, 90, 228, 109, 223, 118, 142, 31, 232, 185, - 228, 109, 223, 118, 142, 31, 202, 131, 228, 109, 223, 118, 142, 31, 203, - 242, 228, 109, 223, 118, 142, 31, 234, 121, 228, 109, 223, 118, 142, 31, - 213, 161, 228, 109, 223, 118, 142, 31, 91, 188, 223, 118, 142, 31, 103, - 188, 223, 118, 142, 31, 115, 188, 223, 118, 142, 31, 232, 90, 188, 223, - 118, 142, 31, 232, 185, 188, 223, 118, 142, 31, 202, 131, 188, 223, 118, - 142, 31, 203, 242, 188, 223, 118, 142, 31, 234, 121, 188, 223, 118, 142, - 31, 213, 161, 188, 223, 118, 142, 31, 199, 91, 188, 223, 118, 142, 31, - 197, 29, 188, 223, 118, 142, 31, 198, 245, 188, 223, 118, 142, 31, 232, - 98, 188, 223, 118, 142, 31, 232, 231, 188, 223, 118, 142, 31, 202, 116, - 188, 223, 118, 142, 31, 203, 237, 188, 223, 118, 142, 31, 234, 111, 188, - 223, 118, 142, 31, 213, 157, 188, 223, 118, 142, 31, 220, 17, 223, 118, - 142, 31, 220, 16, 223, 118, 142, 220, 18, 77, 223, 118, 142, 31, 222, 34, - 223, 118, 142, 31, 222, 33, 223, 118, 142, 31, 208, 220, 108, 223, 118, - 142, 31, 208, 220, 109, 223, 118, 142, 31, 208, 220, 139, 223, 118, 142, - 31, 208, 220, 137, 223, 118, 142, 31, 208, 220, 153, 223, 118, 142, 31, - 208, 220, 173, 223, 118, 142, 31, 208, 220, 181, 223, 118, 142, 31, 208, - 220, 176, 223, 118, 142, 31, 208, 220, 184, 223, 118, 142, 209, 98, 223, - 118, 142, 232, 80, 91, 208, 17, 223, 118, 142, 232, 80, 91, 230, 37, 223, - 118, 142, 232, 80, 115, 208, 15, 223, 118, 142, 206, 31, 77, 223, 118, - 142, 31, 251, 106, 108, 223, 118, 142, 31, 251, 106, 109, 223, 118, 142, - 31, 251, 106, 199, 91, 188, 223, 118, 142, 251, 106, 220, 18, 77, 211, - 11, 142, 31, 108, 211, 11, 142, 31, 109, 211, 11, 142, 31, 139, 211, 11, - 142, 31, 137, 211, 11, 142, 31, 153, 211, 11, 142, 31, 173, 211, 11, 142, - 31, 181, 211, 11, 142, 31, 176, 211, 11, 142, 31, 184, 211, 11, 142, 31, - 199, 90, 211, 11, 142, 31, 197, 28, 211, 11, 142, 31, 198, 244, 211, 11, - 142, 31, 232, 97, 211, 11, 142, 31, 232, 230, 211, 11, 142, 31, 202, 115, - 211, 11, 142, 31, 203, 236, 211, 11, 142, 31, 234, 110, 211, 11, 142, 31, - 213, 156, 211, 11, 142, 31, 91, 228, 109, 211, 11, 142, 31, 103, 228, - 109, 211, 11, 142, 31, 115, 228, 109, 211, 11, 142, 31, 232, 90, 228, - 109, 211, 11, 142, 31, 232, 185, 228, 109, 211, 11, 142, 31, 202, 131, - 228, 109, 211, 11, 142, 31, 203, 242, 228, 109, 211, 11, 142, 31, 234, - 121, 228, 109, 211, 11, 142, 31, 213, 161, 228, 109, 211, 11, 142, 31, - 91, 188, 211, 11, 142, 31, 103, 188, 211, 11, 142, 31, 115, 188, 211, 11, - 142, 31, 232, 90, 188, 211, 11, 142, 31, 232, 185, 188, 211, 11, 142, 31, - 202, 131, 188, 211, 11, 142, 31, 203, 242, 188, 211, 11, 142, 31, 234, - 121, 188, 211, 11, 142, 31, 213, 161, 188, 211, 11, 142, 31, 199, 91, - 188, 211, 11, 142, 31, 197, 29, 188, 211, 11, 142, 31, 198, 245, 188, - 211, 11, 142, 31, 232, 98, 188, 211, 11, 142, 31, 232, 231, 188, 211, 11, - 142, 31, 202, 116, 188, 211, 11, 142, 31, 203, 237, 188, 211, 11, 142, - 31, 234, 111, 188, 211, 11, 142, 31, 213, 157, 188, 211, 11, 142, 217, - 30, 211, 11, 142, 251, 106, 31, 109, 211, 11, 142, 251, 106, 31, 139, - 211, 11, 142, 251, 106, 31, 137, 211, 11, 142, 251, 106, 31, 153, 211, - 11, 142, 251, 106, 31, 173, 211, 11, 142, 251, 106, 31, 181, 211, 11, - 142, 251, 106, 31, 176, 211, 11, 142, 251, 106, 31, 184, 211, 11, 142, - 251, 106, 31, 199, 90, 211, 11, 142, 251, 106, 31, 232, 90, 228, 109, - 211, 11, 142, 251, 106, 31, 202, 131, 228, 109, 211, 11, 142, 251, 106, - 31, 103, 188, 211, 11, 142, 251, 106, 31, 199, 91, 188, 211, 11, 142, - 232, 80, 91, 230, 37, 211, 11, 142, 232, 80, 91, 202, 119, 9, 13, 251, - 141, 9, 13, 248, 195, 9, 13, 222, 234, 9, 13, 237, 212, 9, 13, 193, 131, - 9, 13, 191, 113, 9, 13, 230, 48, 9, 13, 199, 214, 9, 13, 192, 75, 9, 13, - 222, 79, 9, 13, 220, 11, 9, 13, 216, 189, 9, 13, 213, 11, 9, 13, 205, 41, - 9, 13, 251, 178, 9, 13, 233, 5, 9, 13, 205, 187, 9, 13, 208, 82, 9, 13, - 207, 66, 9, 13, 203, 104, 9, 13, 199, 109, 9, 13, 199, 24, 9, 13, 221, - 185, 9, 13, 199, 36, 9, 13, 237, 235, 9, 13, 191, 116, 9, 13, 231, 49, 9, - 13, 236, 95, 248, 195, 9, 13, 236, 95, 213, 11, 9, 13, 236, 95, 233, 5, - 9, 13, 236, 95, 208, 82, 9, 13, 89, 248, 195, 9, 13, 89, 222, 234, 9, 13, - 89, 229, 178, 9, 13, 89, 230, 48, 9, 13, 89, 192, 75, 9, 13, 89, 222, 79, - 9, 13, 89, 220, 11, 9, 13, 89, 216, 189, 9, 13, 89, 213, 11, 9, 13, 89, - 205, 41, 9, 13, 89, 251, 178, 9, 13, 89, 233, 5, 9, 13, 89, 205, 187, 9, - 13, 89, 208, 82, 9, 13, 89, 203, 104, 9, 13, 89, 199, 109, 9, 13, 89, - 199, 24, 9, 13, 89, 221, 185, 9, 13, 89, 237, 235, 9, 13, 89, 231, 49, 9, - 13, 199, 209, 222, 234, 9, 13, 199, 209, 230, 48, 9, 13, 199, 209, 192, - 75, 9, 13, 199, 209, 220, 11, 9, 13, 199, 209, 213, 11, 9, 13, 199, 209, - 205, 41, 9, 13, 199, 209, 251, 178, 9, 13, 199, 209, 205, 187, 9, 13, - 199, 209, 208, 82, 9, 13, 199, 209, 203, 104, 9, 13, 199, 209, 221, 185, - 9, 13, 199, 209, 237, 235, 9, 13, 199, 209, 231, 49, 9, 13, 199, 209, - 236, 95, 213, 11, 9, 13, 199, 209, 236, 95, 208, 82, 9, 13, 201, 31, 248, - 195, 9, 13, 201, 31, 222, 234, 9, 13, 201, 31, 229, 178, 9, 13, 201, 31, - 230, 48, 9, 13, 201, 31, 199, 214, 9, 13, 201, 31, 192, 75, 9, 13, 201, - 31, 222, 79, 9, 13, 201, 31, 216, 189, 9, 13, 201, 31, 213, 11, 9, 13, - 201, 31, 205, 41, 9, 13, 201, 31, 251, 178, 9, 13, 201, 31, 233, 5, 9, - 13, 201, 31, 205, 187, 9, 13, 201, 31, 208, 82, 9, 13, 201, 31, 203, 104, - 9, 13, 201, 31, 199, 109, 9, 13, 201, 31, 199, 24, 9, 13, 201, 31, 221, - 185, 9, 13, 201, 31, 237, 235, 9, 13, 201, 31, 191, 116, 9, 13, 201, 31, - 231, 49, 9, 13, 201, 31, 236, 95, 248, 195, 9, 13, 201, 31, 236, 95, 233, - 5, 9, 13, 218, 235, 251, 141, 9, 13, 218, 235, 248, 195, 9, 13, 218, 235, - 222, 234, 9, 13, 218, 235, 237, 212, 9, 13, 218, 235, 229, 178, 9, 13, - 218, 235, 193, 131, 9, 13, 218, 235, 191, 113, 9, 13, 218, 235, 230, 48, - 9, 13, 218, 235, 199, 214, 9, 13, 218, 235, 192, 75, 9, 13, 218, 235, - 220, 11, 9, 13, 218, 235, 216, 189, 9, 13, 218, 235, 213, 11, 9, 13, 218, - 235, 205, 41, 9, 13, 218, 235, 251, 178, 9, 13, 218, 235, 233, 5, 9, 13, - 218, 235, 205, 187, 9, 13, 218, 235, 208, 82, 9, 13, 218, 235, 207, 66, - 9, 13, 218, 235, 203, 104, 9, 13, 218, 235, 199, 109, 9, 13, 218, 235, - 199, 24, 9, 13, 218, 235, 221, 185, 9, 13, 218, 235, 199, 36, 9, 13, 218, - 235, 237, 235, 9, 13, 218, 235, 191, 116, 9, 13, 218, 235, 231, 49, 9, - 13, 235, 85, 248, 195, 9, 13, 235, 85, 222, 234, 9, 13, 235, 85, 237, - 212, 9, 13, 235, 85, 193, 131, 9, 13, 235, 85, 191, 113, 9, 13, 235, 85, - 230, 48, 9, 13, 235, 85, 199, 214, 9, 13, 235, 85, 192, 75, 9, 13, 235, - 85, 220, 11, 9, 13, 235, 85, 216, 189, 9, 13, 235, 85, 213, 11, 9, 13, - 235, 85, 205, 41, 9, 13, 235, 85, 251, 178, 9, 13, 235, 85, 233, 5, 9, - 13, 235, 85, 205, 187, 9, 13, 235, 85, 208, 82, 9, 13, 235, 85, 207, 66, - 9, 13, 235, 85, 203, 104, 9, 13, 235, 85, 199, 109, 9, 13, 235, 85, 199, - 24, 9, 13, 235, 85, 221, 185, 9, 13, 235, 85, 199, 36, 9, 13, 235, 85, - 237, 235, 9, 13, 235, 85, 191, 116, 9, 13, 235, 85, 231, 49, 9, 13, 211, - 56, 92, 4, 179, 4, 199, 163, 9, 13, 211, 56, 179, 4, 237, 212, 217, 93, - 123, 234, 160, 193, 64, 217, 93, 123, 201, 253, 193, 64, 217, 93, 123, - 193, 103, 193, 64, 217, 93, 123, 185, 193, 64, 217, 93, 123, 207, 82, - 235, 67, 217, 93, 123, 230, 167, 235, 67, 217, 93, 123, 64, 235, 67, 217, - 93, 123, 91, 80, 243, 92, 217, 93, 123, 103, 80, 243, 92, 217, 93, 123, - 115, 80, 243, 92, 217, 93, 123, 232, 90, 80, 243, 92, 217, 93, 123, 232, - 185, 80, 243, 92, 217, 93, 123, 202, 131, 80, 243, 92, 217, 93, 123, 203, - 242, 80, 243, 92, 217, 93, 123, 234, 121, 80, 243, 92, 217, 93, 123, 213, - 161, 80, 243, 92, 217, 93, 123, 91, 80, 249, 52, 217, 93, 123, 103, 80, - 249, 52, 217, 93, 123, 115, 80, 249, 52, 217, 93, 123, 232, 90, 80, 249, - 52, 217, 93, 123, 232, 185, 80, 249, 52, 217, 93, 123, 202, 131, 80, 249, - 52, 217, 93, 123, 203, 242, 80, 249, 52, 217, 93, 123, 234, 121, 80, 249, - 52, 217, 93, 123, 213, 161, 80, 249, 52, 217, 93, 123, 91, 80, 242, 215, - 217, 93, 123, 103, 80, 242, 215, 217, 93, 123, 115, 80, 242, 215, 217, - 93, 123, 232, 90, 80, 242, 215, 217, 93, 123, 232, 185, 80, 242, 215, - 217, 93, 123, 202, 131, 80, 242, 215, 217, 93, 123, 203, 242, 80, 242, - 215, 217, 93, 123, 234, 121, 80, 242, 215, 217, 93, 123, 213, 161, 80, - 242, 215, 217, 93, 123, 209, 77, 217, 93, 123, 211, 42, 217, 93, 123, - 249, 53, 217, 93, 123, 243, 1, 217, 93, 123, 201, 191, 217, 93, 123, 200, - 195, 217, 93, 123, 250, 99, 217, 93, 123, 193, 55, 217, 93, 123, 222, - 167, 217, 93, 123, 249, 96, 236, 106, 123, 228, 209, 249, 96, 236, 106, - 123, 228, 207, 236, 106, 123, 228, 206, 236, 106, 123, 228, 205, 236, - 106, 123, 228, 204, 236, 106, 123, 228, 203, 236, 106, 123, 228, 202, - 236, 106, 123, 228, 201, 236, 106, 123, 228, 200, 236, 106, 123, 228, - 199, 236, 106, 123, 228, 198, 236, 106, 123, 228, 197, 236, 106, 123, - 228, 196, 236, 106, 123, 228, 195, 236, 106, 123, 228, 194, 236, 106, - 123, 228, 193, 236, 106, 123, 228, 192, 236, 106, 123, 228, 191, 236, - 106, 123, 228, 190, 236, 106, 123, 228, 189, 236, 106, 123, 228, 188, - 236, 106, 123, 228, 187, 236, 106, 123, 228, 186, 236, 106, 123, 228, - 185, 236, 106, 123, 228, 184, 236, 106, 123, 228, 183, 236, 106, 123, - 228, 182, 236, 106, 123, 228, 181, 236, 106, 123, 228, 180, 236, 106, - 123, 228, 179, 236, 106, 123, 228, 178, 236, 106, 123, 228, 177, 236, - 106, 123, 228, 176, 236, 106, 123, 228, 175, 236, 106, 123, 228, 174, - 236, 106, 123, 228, 173, 236, 106, 123, 228, 172, 236, 106, 123, 228, - 171, 236, 106, 123, 228, 170, 236, 106, 123, 228, 169, 236, 106, 123, - 228, 168, 236, 106, 123, 228, 167, 236, 106, 123, 228, 166, 236, 106, - 123, 228, 165, 236, 106, 123, 228, 164, 236, 106, 123, 228, 163, 236, - 106, 123, 228, 162, 236, 106, 123, 228, 161, 236, 106, 123, 228, 160, - 236, 106, 123, 228, 159, 236, 106, 123, 81, 249, 96, 236, 106, 123, 195, - 131, 236, 106, 123, 195, 130, 236, 106, 123, 195, 129, 236, 106, 123, - 195, 128, 236, 106, 123, 195, 127, 236, 106, 123, 195, 126, 236, 106, - 123, 195, 125, 236, 106, 123, 195, 124, 236, 106, 123, 195, 123, 236, - 106, 123, 195, 122, 236, 106, 123, 195, 121, 236, 106, 123, 195, 120, - 236, 106, 123, 195, 119, 236, 106, 123, 195, 118, 236, 106, 123, 195, - 117, 236, 106, 123, 195, 116, 236, 106, 123, 195, 115, 236, 106, 123, - 195, 114, 236, 106, 123, 195, 113, 236, 106, 123, 195, 112, 236, 106, - 123, 195, 111, 236, 106, 123, 195, 110, 236, 106, 123, 195, 109, 236, - 106, 123, 195, 108, 236, 106, 123, 195, 107, 236, 106, 123, 195, 106, - 236, 106, 123, 195, 105, 236, 106, 123, 195, 104, 236, 106, 123, 195, - 103, 236, 106, 123, 195, 102, 236, 106, 123, 195, 101, 236, 106, 123, - 195, 100, 236, 106, 123, 195, 99, 236, 106, 123, 195, 98, 236, 106, 123, - 195, 97, 236, 106, 123, 195, 96, 236, 106, 123, 195, 95, 236, 106, 123, - 195, 94, 236, 106, 123, 195, 93, 236, 106, 123, 195, 92, 236, 106, 123, - 195, 91, 236, 106, 123, 195, 90, 236, 106, 123, 195, 89, 236, 106, 123, - 195, 88, 236, 106, 123, 195, 87, 236, 106, 123, 195, 86, 236, 106, 123, - 195, 85, 236, 106, 123, 195, 84, 236, 106, 123, 195, 83, 209, 87, 247, - 53, 249, 96, 209, 87, 247, 53, 252, 1, 80, 201, 239, 209, 87, 247, 53, - 103, 80, 201, 239, 209, 87, 247, 53, 115, 80, 201, 239, 209, 87, 247, 53, - 232, 90, 80, 201, 239, 209, 87, 247, 53, 232, 185, 80, 201, 239, 209, 87, - 247, 53, 202, 131, 80, 201, 239, 209, 87, 247, 53, 203, 242, 80, 201, - 239, 209, 87, 247, 53, 234, 121, 80, 201, 239, 209, 87, 247, 53, 213, - 161, 80, 201, 239, 209, 87, 247, 53, 199, 91, 80, 201, 239, 209, 87, 247, - 53, 223, 2, 80, 201, 239, 209, 87, 247, 53, 221, 53, 80, 201, 239, 209, - 87, 247, 53, 208, 10, 80, 201, 239, 209, 87, 247, 53, 221, 115, 80, 201, - 239, 209, 87, 247, 53, 252, 1, 80, 229, 189, 209, 87, 247, 53, 103, 80, - 229, 189, 209, 87, 247, 53, 115, 80, 229, 189, 209, 87, 247, 53, 232, 90, - 80, 229, 189, 209, 87, 247, 53, 232, 185, 80, 229, 189, 209, 87, 247, 53, - 202, 131, 80, 229, 189, 209, 87, 247, 53, 203, 242, 80, 229, 189, 209, - 87, 247, 53, 234, 121, 80, 229, 189, 209, 87, 247, 53, 213, 161, 80, 229, - 189, 209, 87, 247, 53, 199, 91, 80, 229, 189, 209, 87, 247, 53, 223, 2, - 80, 229, 189, 209, 87, 247, 53, 221, 53, 80, 229, 189, 209, 87, 247, 53, - 208, 10, 80, 229, 189, 209, 87, 247, 53, 221, 115, 80, 229, 189, 209, 87, - 247, 53, 207, 82, 222, 167, 209, 87, 247, 53, 252, 1, 80, 236, 242, 209, - 87, 247, 53, 103, 80, 236, 242, 209, 87, 247, 53, 115, 80, 236, 242, 209, - 87, 247, 53, 232, 90, 80, 236, 242, 209, 87, 247, 53, 232, 185, 80, 236, - 242, 209, 87, 247, 53, 202, 131, 80, 236, 242, 209, 87, 247, 53, 203, - 242, 80, 236, 242, 209, 87, 247, 53, 234, 121, 80, 236, 242, 209, 87, - 247, 53, 213, 161, 80, 236, 242, 209, 87, 247, 53, 199, 91, 80, 236, 242, - 209, 87, 247, 53, 223, 2, 80, 236, 242, 209, 87, 247, 53, 221, 53, 80, - 236, 242, 209, 87, 247, 53, 208, 10, 80, 236, 242, 209, 87, 247, 53, 221, - 115, 80, 236, 242, 209, 87, 247, 53, 62, 222, 167, 209, 87, 247, 53, 252, - 1, 80, 242, 156, 209, 87, 247, 53, 103, 80, 242, 156, 209, 87, 247, 53, - 115, 80, 242, 156, 209, 87, 247, 53, 232, 90, 80, 242, 156, 209, 87, 247, - 53, 232, 185, 80, 242, 156, 209, 87, 247, 53, 202, 131, 80, 242, 156, - 209, 87, 247, 53, 203, 242, 80, 242, 156, 209, 87, 247, 53, 234, 121, 80, - 242, 156, 209, 87, 247, 53, 213, 161, 80, 242, 156, 209, 87, 247, 53, - 199, 91, 80, 242, 156, 209, 87, 247, 53, 223, 2, 80, 242, 156, 209, 87, - 247, 53, 221, 53, 80, 242, 156, 209, 87, 247, 53, 208, 10, 80, 242, 156, - 209, 87, 247, 53, 221, 115, 80, 242, 156, 209, 87, 247, 53, 64, 222, 167, - 209, 87, 247, 53, 232, 121, 209, 87, 247, 53, 197, 196, 209, 87, 247, 53, - 197, 185, 209, 87, 247, 53, 197, 182, 209, 87, 247, 53, 197, 181, 209, - 87, 247, 53, 197, 180, 209, 87, 247, 53, 197, 179, 209, 87, 247, 53, 197, - 178, 209, 87, 247, 53, 197, 177, 209, 87, 247, 53, 197, 176, 209, 87, - 247, 53, 197, 195, 209, 87, 247, 53, 197, 194, 209, 87, 247, 53, 197, - 193, 209, 87, 247, 53, 197, 192, 209, 87, 247, 53, 197, 191, 209, 87, - 247, 53, 197, 190, 209, 87, 247, 53, 197, 189, 209, 87, 247, 53, 197, - 188, 209, 87, 247, 53, 197, 187, 209, 87, 247, 53, 197, 186, 209, 87, - 247, 53, 197, 184, 209, 87, 247, 53, 197, 183, 17, 191, 78, 232, 42, 201, - 58, 17, 191, 78, 242, 26, 17, 91, 242, 26, 17, 103, 242, 26, 17, 115, - 242, 26, 17, 232, 90, 242, 26, 17, 232, 185, 242, 26, 17, 202, 131, 242, - 26, 17, 203, 242, 242, 26, 17, 234, 121, 242, 26, 17, 213, 161, 242, 26, - 236, 196, 47, 49, 17, 191, 77, 236, 196, 214, 92, 47, 49, 17, 191, 77, - 47, 191, 78, 4, 202, 92, 47, 251, 34, 55, 47, 236, 110, 3, 4, 210, 250, - 249, 91, 127, 8, 6, 1, 65, 127, 8, 6, 1, 250, 70, 127, 8, 6, 1, 247, 145, - 127, 8, 6, 1, 238, 80, 127, 8, 6, 1, 73, 127, 8, 6, 1, 233, 134, 127, 8, - 6, 1, 232, 14, 127, 8, 6, 1, 230, 83, 127, 8, 6, 1, 70, 127, 8, 6, 1, - 223, 7, 127, 8, 6, 1, 222, 125, 127, 8, 6, 1, 170, 127, 8, 6, 1, 218, - 147, 127, 8, 6, 1, 215, 47, 127, 8, 6, 1, 74, 127, 8, 6, 1, 210, 226, - 127, 8, 6, 1, 208, 97, 127, 8, 6, 1, 148, 127, 8, 6, 1, 206, 3, 127, 8, - 6, 1, 200, 39, 127, 8, 6, 1, 69, 127, 8, 6, 1, 196, 8, 127, 8, 6, 1, 193, - 221, 127, 8, 6, 1, 192, 235, 127, 8, 6, 1, 192, 159, 127, 8, 6, 1, 191, - 166, 198, 37, 203, 98, 248, 4, 8, 6, 1, 206, 3, 47, 43, 8, 6, 1, 247, - 145, 47, 43, 8, 6, 1, 148, 47, 246, 251, 47, 192, 237, 238, 216, 113, - 112, 8, 6, 1, 65, 112, 8, 6, 1, 250, 70, 112, 8, 6, 1, 247, 145, 112, 8, - 6, 1, 238, 80, 112, 8, 6, 1, 73, 112, 8, 6, 1, 233, 134, 112, 8, 6, 1, - 232, 14, 112, 8, 6, 1, 230, 83, 112, 8, 6, 1, 70, 112, 8, 6, 1, 223, 7, - 112, 8, 6, 1, 222, 125, 112, 8, 6, 1, 170, 112, 8, 6, 1, 218, 147, 112, - 8, 6, 1, 215, 47, 112, 8, 6, 1, 74, 112, 8, 6, 1, 210, 226, 112, 8, 6, 1, - 208, 97, 112, 8, 6, 1, 148, 112, 8, 6, 1, 206, 3, 112, 8, 6, 1, 200, 39, - 112, 8, 6, 1, 69, 112, 8, 6, 1, 196, 8, 112, 8, 6, 1, 193, 221, 112, 8, - 6, 1, 192, 235, 112, 8, 6, 1, 192, 159, 112, 8, 6, 1, 191, 166, 112, 228, - 95, 112, 215, 73, 112, 205, 65, 112, 201, 173, 112, 208, 241, 112, 193, - 124, 214, 92, 47, 8, 6, 1, 65, 214, 92, 47, 8, 6, 1, 250, 70, 214, 92, - 47, 8, 6, 1, 247, 145, 214, 92, 47, 8, 6, 1, 238, 80, 214, 92, 47, 8, 6, - 1, 73, 214, 92, 47, 8, 6, 1, 233, 134, 214, 92, 47, 8, 6, 1, 232, 14, - 214, 92, 47, 8, 6, 1, 230, 83, 214, 92, 47, 8, 6, 1, 70, 214, 92, 47, 8, - 6, 1, 223, 7, 214, 92, 47, 8, 6, 1, 222, 125, 214, 92, 47, 8, 6, 1, 170, - 214, 92, 47, 8, 6, 1, 218, 147, 214, 92, 47, 8, 6, 1, 215, 47, 214, 92, - 47, 8, 6, 1, 74, 214, 92, 47, 8, 6, 1, 210, 226, 214, 92, 47, 8, 6, 1, - 208, 97, 214, 92, 47, 8, 6, 1, 148, 214, 92, 47, 8, 6, 1, 206, 3, 214, - 92, 47, 8, 6, 1, 200, 39, 214, 92, 47, 8, 6, 1, 69, 214, 92, 47, 8, 6, 1, - 196, 8, 214, 92, 47, 8, 6, 1, 193, 221, 214, 92, 47, 8, 6, 1, 192, 235, - 214, 92, 47, 8, 6, 1, 192, 159, 214, 92, 47, 8, 6, 1, 191, 166, 207, 142, - 216, 220, 57, 207, 142, 216, 216, 57, 207, 142, 215, 148, 57, 47, 247, - 18, 47, 247, 146, 4, 210, 250, 249, 91, 47, 228, 114, 232, 227, 214, 92, - 112, 8, 6, 1, 65, 214, 92, 112, 8, 6, 1, 250, 70, 214, 92, 112, 8, 6, 1, - 247, 145, 214, 92, 112, 8, 6, 1, 238, 80, 214, 92, 112, 8, 6, 1, 73, 214, - 92, 112, 8, 6, 1, 233, 134, 214, 92, 112, 8, 6, 1, 232, 14, 214, 92, 112, - 8, 6, 1, 230, 83, 214, 92, 112, 8, 6, 1, 70, 214, 92, 112, 8, 6, 1, 223, - 7, 214, 92, 112, 8, 6, 1, 222, 125, 214, 92, 112, 8, 6, 1, 170, 214, 92, - 112, 8, 6, 1, 218, 147, 214, 92, 112, 8, 6, 1, 215, 47, 214, 92, 112, 8, - 6, 1, 74, 214, 92, 112, 8, 6, 1, 210, 226, 214, 92, 112, 8, 6, 1, 208, - 97, 214, 92, 112, 8, 6, 1, 148, 214, 92, 112, 8, 6, 1, 206, 3, 214, 92, - 112, 8, 6, 1, 200, 39, 214, 92, 112, 8, 6, 1, 69, 214, 92, 112, 8, 6, 1, - 196, 8, 214, 92, 112, 8, 6, 1, 193, 221, 214, 92, 112, 8, 6, 1, 192, 235, - 214, 92, 112, 8, 6, 1, 192, 159, 214, 92, 112, 8, 6, 1, 191, 166, 238, - 167, 214, 92, 112, 8, 6, 1, 210, 226, 214, 92, 112, 227, 254, 214, 92, - 112, 168, 214, 92, 112, 189, 214, 92, 112, 252, 103, 214, 92, 112, 193, - 124, 51, 236, 149, 112, 242, 199, 112, 238, 223, 112, 232, 70, 112, 227, - 245, 112, 214, 65, 112, 214, 56, 112, 211, 114, 112, 202, 4, 112, 132, 4, - 233, 175, 77, 112, 194, 249, 112, 115, 238, 80, 112, 205, 52, 205, 71, - 112, 103, 222, 125, 112, 232, 90, 222, 125, 112, 234, 121, 222, 125, 112, - 232, 185, 209, 55, 108, 112, 203, 242, 209, 55, 108, 112, 197, 17, 209, - 55, 109, 112, 202, 116, 210, 226, 112, 91, 228, 110, 197, 29, 210, 226, - 112, 8, 2, 1, 238, 80, 112, 229, 216, 112, 229, 215, 112, 229, 118, 112, - 218, 228, 112, 202, 236, 112, 196, 136, 112, 195, 18, 217, 17, 193, 21, - 113, 207, 74, 223, 117, 16, 1, 65, 207, 74, 223, 117, 16, 1, 250, 70, - 207, 74, 223, 117, 16, 1, 247, 145, 207, 74, 223, 117, 16, 1, 238, 80, - 207, 74, 223, 117, 16, 1, 73, 207, 74, 223, 117, 16, 1, 233, 134, 207, - 74, 223, 117, 16, 1, 232, 14, 207, 74, 223, 117, 16, 1, 230, 83, 207, 74, - 223, 117, 16, 1, 70, 207, 74, 223, 117, 16, 1, 223, 7, 207, 74, 223, 117, - 16, 1, 222, 125, 207, 74, 223, 117, 16, 1, 170, 207, 74, 223, 117, 16, 1, - 218, 147, 207, 74, 223, 117, 16, 1, 215, 47, 207, 74, 223, 117, 16, 1, - 74, 207, 74, 223, 117, 16, 1, 210, 226, 207, 74, 223, 117, 16, 1, 208, - 97, 207, 74, 223, 117, 16, 1, 148, 207, 74, 223, 117, 16, 1, 206, 3, 207, - 74, 223, 117, 16, 1, 200, 39, 207, 74, 223, 117, 16, 1, 69, 207, 74, 223, - 117, 16, 1, 196, 8, 207, 74, 223, 117, 16, 1, 193, 221, 207, 74, 223, - 117, 16, 1, 192, 235, 207, 74, 223, 117, 16, 1, 192, 159, 207, 74, 223, - 117, 16, 1, 191, 166, 51, 229, 88, 228, 233, 112, 71, 221, 25, 112, 71, - 189, 112, 12, 196, 91, 225, 188, 112, 12, 196, 91, 225, 192, 112, 12, - 196, 91, 225, 200, 112, 71, 237, 101, 112, 12, 196, 91, 225, 207, 112, - 12, 196, 91, 225, 194, 112, 12, 196, 91, 225, 166, 112, 12, 196, 91, 225, - 193, 112, 12, 196, 91, 225, 206, 112, 12, 196, 91, 225, 180, 112, 12, - 196, 91, 225, 173, 112, 12, 196, 91, 225, 182, 112, 12, 196, 91, 225, - 203, 112, 12, 196, 91, 225, 189, 112, 12, 196, 91, 225, 205, 112, 12, - 196, 91, 225, 181, 112, 12, 196, 91, 225, 204, 112, 12, 196, 91, 225, - 167, 112, 12, 196, 91, 225, 172, 112, 12, 196, 91, 225, 165, 112, 12, - 196, 91, 225, 195, 112, 12, 196, 91, 225, 197, 112, 12, 196, 91, 225, - 175, 112, 12, 196, 91, 225, 186, 112, 12, 196, 91, 225, 184, 112, 12, - 196, 91, 225, 210, 112, 12, 196, 91, 225, 209, 112, 12, 196, 91, 225, - 163, 112, 12, 196, 91, 225, 190, 112, 12, 196, 91, 225, 208, 112, 12, - 196, 91, 225, 199, 112, 12, 196, 91, 225, 185, 112, 12, 196, 91, 225, - 164, 112, 12, 196, 91, 225, 187, 112, 12, 196, 91, 225, 169, 112, 12, - 196, 91, 225, 168, 112, 12, 196, 91, 225, 198, 112, 12, 196, 91, 225, - 176, 112, 12, 196, 91, 225, 178, 112, 12, 196, 91, 225, 179, 112, 12, - 196, 91, 225, 171, 112, 12, 196, 91, 225, 202, 112, 12, 196, 91, 225, - 196, 112, 12, 196, 91, 225, 162, 198, 37, 203, 98, 248, 4, 12, 196, 91, - 225, 177, 198, 37, 203, 98, 248, 4, 12, 196, 91, 225, 209, 198, 37, 203, - 98, 248, 4, 12, 196, 91, 225, 207, 198, 37, 203, 98, 248, 4, 12, 196, 91, - 225, 191, 198, 37, 203, 98, 248, 4, 12, 196, 91, 225, 174, 198, 37, 203, - 98, 248, 4, 12, 196, 91, 225, 187, 198, 37, 203, 98, 248, 4, 12, 196, 91, - 225, 170, 198, 37, 203, 98, 248, 4, 12, 196, 91, 225, 201, 198, 37, 203, - 98, 248, 4, 12, 196, 91, 225, 183, 47, 227, 241, 251, 231, 47, 227, 241, - 252, 6, 206, 108, 16, 39, 232, 48, 206, 108, 16, 39, 218, 203, 206, 108, - 16, 39, 203, 18, 206, 108, 16, 39, 192, 207, 206, 108, 16, 39, 202, 253, - 206, 108, 16, 39, 247, 100, 238, 92, 232, 133, 242, 171, 196, 113, 213, - 177, 4, 201, 94, 200, 188, 138, 215, 167, 200, 187, 242, 203, 250, 133, - 235, 17, 200, 186, 138, 247, 205, 207, 143, 247, 237, 250, 133, 213, 176, - 193, 142, 193, 136, 195, 11, 216, 34, 193, 126, 234, 164, 230, 232, 233, - 191, 234, 164, 230, 232, 251, 89, 234, 164, 230, 232, 250, 152, 230, 232, - 4, 216, 158, 214, 66, 215, 189, 113, 193, 128, 238, 181, 215, 189, 113, - 232, 197, 208, 18, 215, 189, 113, 193, 128, 231, 12, 215, 189, 113, 232, - 42, 215, 189, 113, 193, 157, 231, 12, 215, 189, 113, 219, 238, 208, 18, - 215, 189, 113, 193, 157, 238, 181, 215, 189, 113, 238, 181, 215, 188, - 214, 66, 215, 189, 4, 233, 62, 232, 197, 208, 18, 215, 189, 4, 233, 62, - 219, 238, 208, 18, 215, 189, 4, 233, 62, 232, 42, 215, 189, 4, 233, 62, - 200, 194, 4, 233, 62, 230, 228, 201, 97, 203, 40, 201, 97, 199, 16, 62, - 235, 53, 64, 200, 193, 64, 200, 194, 4, 2, 242, 162, 64, 200, 194, 248, - 192, 242, 162, 64, 200, 194, 248, 192, 242, 163, 4, 207, 144, 242, 163, - 4, 207, 144, 242, 163, 4, 202, 47, 242, 163, 4, 219, 105, 242, 163, 4, - 198, 41, 232, 134, 193, 65, 248, 68, 233, 62, 228, 150, 236, 117, 199, - 222, 247, 180, 243, 55, 205, 43, 233, 185, 197, 250, 237, 94, 197, 250, - 210, 173, 197, 250, 247, 105, 228, 150, 210, 6, 197, 74, 243, 59, 248, - 71, 206, 121, 229, 117, 200, 191, 248, 71, 234, 168, 80, 217, 82, 234, - 168, 80, 206, 240, 229, 161, 232, 90, 219, 210, 242, 161, 217, 49, 219, - 209, 233, 43, 219, 209, 219, 210, 232, 141, 223, 135, 193, 64, 215, 84, - 198, 78, 250, 112, 230, 184, 216, 177, 193, 140, 199, 182, 219, 177, 249, - 48, 209, 124, 207, 82, 250, 252, 230, 167, 250, 252, 210, 46, 210, 50, - 243, 60, 201, 37, 230, 30, 202, 84, 80, 209, 104, 216, 206, 211, 94, 248, - 50, 209, 2, 219, 188, 206, 241, 238, 187, 206, 241, 249, 61, 238, 226, - 206, 240, 238, 120, 24, 206, 240, 201, 78, 248, 18, 201, 238, 247, 251, - 232, 68, 232, 64, 206, 147, 200, 138, 209, 5, 237, 190, 211, 141, 200, - 160, 232, 65, 203, 8, 232, 196, 247, 99, 4, 200, 130, 237, 35, 202, 27, - 227, 253, 238, 185, 203, 116, 227, 252, 227, 253, 238, 185, 235, 82, 238, - 225, 243, 18, 164, 247, 70, 219, 0, 238, 111, 228, 222, 209, 7, 203, 24, - 248, 172, 248, 14, 209, 8, 80, 232, 122, 238, 224, 232, 111, 24, 221, 54, - 199, 128, 193, 51, 229, 254, 205, 171, 248, 31, 24, 238, 134, 193, 61, - 230, 236, 242, 46, 230, 236, 197, 200, 235, 60, 248, 203, 215, 124, 242, - 178, 248, 203, 215, 123, 249, 99, 248, 30, 232, 111, 24, 221, 55, 4, 209, - 89, 248, 31, 4, 209, 23, 238, 212, 209, 25, 206, 242, 193, 11, 208, 215, - 248, 109, 247, 98, 223, 1, 243, 8, 197, 250, 233, 26, 243, 7, 232, 199, - 232, 200, 201, 236, 249, 59, 210, 92, 209, 24, 239, 6, 249, 61, 199, 186, - 197, 250, 238, 167, 232, 171, 209, 125, 237, 91, 222, 247, 236, 109, 247, - 42, 201, 36, 193, 65, 243, 34, 215, 189, 195, 51, 246, 216, 205, 85, 205, - 115, 230, 191, 247, 63, 229, 192, 4, 198, 131, 211, 94, 199, 29, 219, - 200, 248, 24, 80, 232, 145, 216, 36, 216, 200, 207, 53, 206, 242, 37, - 221, 196, 4, 223, 0, 201, 6, 216, 70, 219, 144, 202, 81, 238, 231, 221, - 48, 248, 219, 250, 163, 37, 212, 244, 248, 219, 237, 41, 37, 212, 244, - 232, 215, 232, 74, 251, 235, 198, 175, 247, 43, 228, 152, 232, 248, 193, - 91, 206, 134, 242, 49, 232, 191, 209, 46, 24, 232, 195, 216, 70, 215, - 153, 247, 84, 242, 222, 229, 199, 250, 174, 210, 178, 198, 49, 229, 232, - 242, 208, 199, 82, 198, 176, 242, 194, 248, 59, 209, 253, 250, 172, 195, - 62, 231, 177, 236, 189, 229, 85, 202, 74, 217, 127, 248, 122, 231, 178, - 236, 235, 248, 17, 232, 147, 209, 87, 247, 51, 37, 212, 249, 215, 114, - 37, 212, 244, 205, 99, 230, 129, 37, 221, 195, 197, 175, 195, 39, 37, - 205, 77, 206, 37, 203, 55, 4, 205, 118, 199, 87, 207, 165, 24, 249, 61, - 202, 104, 24, 202, 104, 248, 43, 249, 18, 24, 228, 215, 243, 61, 232, - 177, 202, 46, 206, 38, 200, 165, 201, 197, 216, 200, 197, 201, 228, 153, - 207, 166, 251, 90, 232, 119, 206, 51, 232, 119, 200, 133, 193, 108, 219, - 110, 230, 213, 207, 167, 215, 175, 207, 167, 247, 54, 238, 178, 249, 15, - 24, 249, 61, 195, 10, 232, 237, 228, 236, 201, 70, 24, 249, 61, 227, 253, - 228, 236, 201, 70, 24, 208, 150, 199, 229, 199, 87, 210, 197, 24, 249, - 61, 202, 48, 247, 59, 215, 168, 247, 82, 248, 222, 4, 196, 113, 247, 207, - 238, 245, 228, 142, 247, 205, 242, 202, 237, 45, 228, 142, 247, 206, 242, - 192, 247, 206, 237, 37, 237, 38, 223, 32, 214, 194, 210, 99, 201, 108, - 228, 142, 247, 206, 228, 142, 4, 231, 161, 211, 132, 247, 206, 222, 247, - 209, 13, 211, 131, 233, 190, 209, 13, 211, 131, 228, 151, 249, 42, 250, - 101, 199, 97, 217, 127, 228, 147, 218, 220, 228, 147, 238, 229, 201, 52, - 205, 84, 237, 49, 201, 52, 233, 51, 223, 12, 219, 250, 222, 247, 247, 32, - 233, 190, 247, 32, 64, 210, 19, 62, 210, 19, 193, 134, 64, 232, 177, 193, - 134, 62, 232, 177, 206, 120, 62, 206, 120, 220, 93, 249, 82, 207, 165, - 24, 202, 239, 248, 22, 24, 55, 251, 85, 234, 67, 59, 232, 186, 196, 249, - 234, 67, 59, 232, 186, 196, 246, 234, 67, 59, 232, 186, 196, 244, 234, - 67, 59, 232, 186, 196, 242, 234, 67, 59, 232, 186, 196, 240, 207, 125, - 215, 165, 210, 237, 193, 142, 247, 211, 238, 192, 198, 168, 219, 161, - 207, 169, 247, 30, 235, 67, 238, 176, 193, 94, 202, 55, 202, 53, 228, - 152, 207, 137, 230, 219, 203, 102, 215, 208, 206, 124, 243, 45, 236, 117, - 209, 138, 248, 61, 234, 88, 211, 144, 201, 213, 203, 97, 247, 210, 251, - 38, 228, 221, 220, 84, 248, 201, 232, 195, 197, 200, 232, 195, 248, 69, - 197, 51, 229, 230, 243, 46, 249, 99, 243, 46, 232, 58, 249, 99, 243, 46, - 248, 112, 210, 21, 221, 37, 209, 29, 235, 57, 247, 86, 249, 87, 247, 86, - 236, 108, 215, 166, 233, 62, 238, 193, 233, 62, 198, 169, 233, 62, 207, - 170, 233, 62, 247, 31, 233, 62, 235, 68, 233, 62, 201, 195, 193, 94, 228, - 153, 233, 62, 215, 209, 233, 62, 236, 118, 233, 62, 209, 139, 233, 62, - 232, 62, 233, 62, 230, 26, 233, 62, 193, 38, 233, 62, 248, 216, 233, 62, - 210, 152, 233, 62, 209, 139, 213, 0, 210, 66, 208, 201, 243, 29, 233, - 144, 233, 152, 234, 167, 213, 0, 215, 163, 198, 56, 64, 132, 209, 51, - 249, 94, 223, 120, 64, 143, 209, 51, 249, 94, 223, 120, 64, 45, 209, 51, - 249, 94, 223, 120, 64, 50, 209, 51, 249, 94, 223, 120, 232, 189, 230, 21, - 57, 193, 134, 230, 21, 57, 211, 115, 230, 21, 57, 198, 206, 132, 57, 198, - 206, 143, 57, 242, 193, 229, 252, 57, 211, 66, 229, 252, 57, 238, 161, - 193, 34, 229, 232, 233, 147, 214, 97, 200, 37, 222, 237, 235, 62, 221, - 118, 248, 125, 193, 34, 242, 164, 208, 130, 230, 0, 209, 3, 217, 58, 203, - 47, 250, 128, 203, 47, 229, 102, 203, 47, 193, 34, 205, 134, 193, 34, - 248, 42, 232, 117, 247, 172, 223, 135, 202, 182, 247, 171, 223, 135, 202, - 182, 248, 12, 230, 248, 217, 70, 193, 35, 233, 40, 217, 71, 24, 193, 36, - 228, 230, 229, 251, 103, 216, 168, 228, 230, 229, 251, 103, 193, 33, 228, - 230, 229, 251, 209, 43, 211, 130, 193, 36, 4, 247, 191, 234, 165, 247, - 238, 4, 195, 141, 209, 242, 4, 248, 73, 230, 45, 217, 71, 4, 230, 143, - 209, 177, 217, 53, 217, 71, 4, 197, 59, 211, 107, 217, 70, 211, 107, 193, - 35, 249, 98, 238, 246, 193, 19, 208, 206, 222, 247, 211, 125, 222, 247, - 230, 218, 231, 24, 249, 99, 251, 69, 233, 157, 251, 131, 251, 132, 215, - 198, 223, 140, 202, 98, 223, 109, 237, 34, 209, 241, 230, 137, 237, 195, - 219, 71, 214, 221, 209, 41, 233, 63, 217, 14, 230, 44, 249, 36, 209, 45, - 200, 58, 209, 131, 221, 99, 77, 218, 220, 219, 151, 206, 183, 231, 118, - 201, 60, 221, 98, 248, 23, 238, 196, 4, 229, 191, 193, 115, 248, 212, - 229, 191, 247, 230, 229, 191, 103, 229, 189, 201, 234, 229, 191, 230, - 153, 229, 191, 229, 192, 4, 55, 248, 67, 229, 191, 230, 167, 229, 191, - 192, 73, 229, 191, 208, 131, 229, 191, 229, 192, 4, 206, 242, 207, 7, - 229, 189, 229, 192, 237, 91, 236, 244, 203, 130, 4, 41, 75, 223, 89, 234, - 92, 155, 247, 203, 251, 68, 113, 248, 51, 202, 87, 113, 242, 37, 113, - 201, 207, 200, 140, 113, 235, 53, 237, 171, 113, 209, 132, 80, 209, 30, - 232, 159, 248, 137, 236, 150, 113, 201, 225, 249, 59, 198, 226, 249, 59, - 64, 232, 146, 228, 110, 209, 49, 113, 215, 213, 249, 80, 238, 123, 233, - 177, 88, 236, 110, 57, 238, 183, 247, 52, 249, 41, 4, 192, 71, 57, 249, - 41, 4, 236, 110, 57, 249, 41, 4, 233, 193, 57, 249, 41, 4, 209, 1, 57, - 215, 213, 4, 193, 59, 243, 89, 4, 196, 62, 197, 246, 24, 192, 71, 57, - 205, 55, 209, 240, 239, 11, 247, 236, 216, 24, 232, 151, 236, 175, 211, - 49, 236, 181, 235, 11, 232, 222, 232, 131, 211, 66, 232, 222, 232, 131, - 210, 195, 4, 238, 128, 210, 195, 233, 55, 196, 73, 247, 92, 199, 125, - 247, 92, 247, 53, 223, 120, 243, 89, 4, 196, 62, 197, 245, 243, 89, 4, - 235, 75, 197, 245, 249, 38, 243, 88, 242, 177, 208, 126, 206, 110, 208, - 126, 210, 124, 201, 48, 206, 45, 197, 234, 206, 45, 248, 47, 199, 227, - 219, 205, 212, 247, 212, 248, 4, 237, 90, 238, 195, 242, 171, 248, 48, - 211, 66, 248, 48, 230, 167, 248, 48, 248, 67, 248, 48, 211, 44, 248, 48, - 248, 45, 214, 214, 249, 84, 205, 68, 216, 169, 199, 102, 207, 96, 210, - 193, 233, 23, 217, 127, 205, 114, 251, 35, 208, 151, 251, 243, 218, 222, - 243, 71, 216, 182, 211, 3, 197, 254, 223, 131, 197, 254, 210, 202, 234, - 220, 113, 223, 128, 234, 25, 234, 26, 4, 235, 75, 63, 56, 242, 171, 217, - 88, 4, 218, 213, 232, 177, 242, 171, 217, 88, 4, 207, 142, 232, 177, 211, - 66, 217, 88, 4, 207, 142, 232, 177, 211, 66, 217, 88, 4, 218, 213, 232, - 177, 209, 10, 209, 11, 228, 156, 214, 61, 215, 243, 209, 185, 215, 243, - 209, 186, 4, 96, 63, 250, 133, 219, 200, 195, 65, 215, 242, 215, 243, - 209, 186, 211, 133, 213, 31, 215, 243, 209, 184, 251, 36, 4, 249, 26, - 247, 84, 247, 85, 4, 232, 168, 195, 62, 247, 84, 199, 99, 207, 160, 195, - 61, 232, 215, 208, 186, 209, 20, 201, 72, 208, 229, 248, 221, 197, 13, - 96, 250, 181, 242, 173, 96, 24, 117, 211, 66, 242, 219, 250, 181, 242, - 173, 96, 24, 117, 211, 66, 242, 219, 250, 182, 4, 47, 91, 210, 245, 242, - 173, 235, 75, 24, 196, 62, 211, 66, 242, 219, 250, 181, 251, 34, 235, 75, - 24, 196, 62, 211, 66, 242, 219, 250, 181, 131, 247, 234, 113, 136, 247, - 234, 113, 201, 230, 4, 247, 77, 105, 201, 229, 201, 230, 4, 91, 202, 0, - 193, 136, 201, 230, 4, 115, 202, 0, 193, 135, 249, 8, 234, 92, 209, 79, - 219, 195, 217, 100, 230, 236, 206, 198, 217, 100, 230, 236, 219, 11, 4, - 223, 101, 210, 25, 242, 171, 219, 11, 4, 221, 197, 221, 197, 219, 10, - 211, 66, 219, 10, 248, 185, 248, 186, 4, 247, 77, 105, 248, 46, 219, 79, - 113, 207, 161, 247, 165, 249, 97, 4, 117, 63, 56, 234, 53, 4, 117, 63, - 56, 211, 94, 4, 233, 175, 87, 4, 45, 50, 63, 56, 202, 10, 4, 96, 63, 56, - 198, 49, 4, 196, 62, 63, 56, 213, 31, 91, 196, 101, 234, 119, 113, 221, - 194, 199, 90, 223, 95, 16, 39, 8, 6, 219, 150, 223, 95, 16, 39, 8, 2, - 219, 150, 223, 95, 16, 39, 212, 122, 223, 95, 16, 39, 200, 72, 223, 95, - 16, 39, 8, 219, 150, 232, 202, 234, 92, 198, 44, 193, 9, 230, 28, 212, - 105, 24, 248, 53, 228, 237, 209, 110, 216, 69, 199, 100, 238, 150, 249, - 61, 202, 131, 209, 53, 201, 98, 4, 82, 236, 96, 222, 247, 16, 39, 248, - 198, 197, 232, 234, 69, 62, 51, 247, 165, 64, 51, 247, 165, 219, 245, - 207, 82, 242, 218, 219, 245, 248, 67, 242, 218, 219, 245, 211, 44, 236, - 243, 219, 245, 248, 67, 236, 243, 2, 211, 44, 236, 243, 2, 248, 67, 236, - 243, 196, 72, 207, 82, 197, 237, 235, 78, 207, 82, 197, 237, 196, 72, 2, - 207, 82, 197, 237, 235, 78, 2, 207, 82, 197, 237, 110, 50, 203, 146, 64, - 242, 218, 116, 50, 203, 146, 64, 242, 218, 47, 238, 171, 209, 34, 238, - 171, 209, 35, 4, 230, 34, 60, 238, 171, 209, 34, 212, 251, 45, 204, 23, - 4, 115, 236, 94, 212, 251, 50, 204, 23, 4, 115, 236, 94, 16, 39, 217, 31, - 246, 194, 64, 8, 238, 170, 88, 8, 238, 170, 246, 234, 238, 170, 211, 103, - 113, 235, 81, 80, 210, 51, 222, 98, 215, 181, 200, 66, 216, 164, 4, 213, - 161, 247, 254, 248, 19, 80, 228, 60, 242, 175, 233, 63, 91, 211, 150, - 242, 175, 233, 63, 103, 211, 150, 242, 175, 233, 63, 115, 211, 150, 242, - 175, 233, 63, 232, 90, 211, 150, 242, 175, 233, 63, 232, 185, 211, 150, - 242, 175, 233, 63, 202, 131, 211, 150, 242, 175, 233, 63, 203, 242, 211, - 150, 242, 175, 233, 63, 234, 121, 211, 150, 242, 175, 233, 63, 213, 161, - 211, 150, 242, 175, 233, 63, 199, 91, 211, 150, 242, 175, 233, 63, 234, - 85, 211, 150, 242, 175, 233, 63, 197, 34, 211, 150, 242, 175, 233, 63, - 211, 86, 242, 175, 233, 63, 197, 7, 242, 175, 233, 63, 198, 212, 242, - 175, 233, 63, 232, 86, 242, 175, 233, 63, 232, 183, 242, 175, 233, 63, - 202, 127, 242, 175, 233, 63, 203, 241, 242, 175, 233, 63, 234, 120, 242, - 175, 233, 63, 213, 160, 242, 175, 233, 63, 199, 89, 242, 175, 233, 63, - 234, 83, 242, 175, 233, 63, 197, 32, 50, 201, 229, 50, 201, 230, 4, 91, - 202, 0, 193, 136, 50, 201, 230, 4, 115, 202, 0, 193, 135, 247, 198, 247, - 199, 4, 202, 0, 193, 135, 206, 181, 248, 185, 248, 48, 247, 75, 217, 55, - 242, 174, 62, 202, 99, 24, 238, 168, 213, 31, 209, 116, 228, 229, 217, - 71, 223, 135, 247, 174, 200, 207, 219, 141, 202, 85, 211, 46, 201, 186, - 237, 176, 200, 189, 201, 216, 201, 217, 193, 116, 222, 156, 217, 71, 237, - 194, 45, 230, 21, 199, 102, 207, 96, 199, 102, 207, 97, 4, 210, 194, 50, - 230, 21, 199, 102, 207, 96, 64, 198, 29, 199, 101, 62, 198, 29, 199, 101, - 199, 102, 211, 94, 198, 49, 80, 215, 239, 242, 197, 215, 243, 209, 185, - 249, 97, 80, 234, 25, 201, 104, 234, 25, 234, 26, 4, 219, 105, 232, 138, - 234, 25, 210, 26, 138, 201, 104, 234, 25, 219, 78, 210, 123, 62, 208, - 126, 110, 45, 210, 24, 110, 45, 249, 55, 210, 25, 110, 45, 232, 92, 210, - 25, 110, 45, 210, 187, 110, 45, 238, 186, 45, 193, 3, 230, 20, 152, 211, - 115, 230, 21, 57, 207, 142, 230, 21, 4, 232, 207, 201, 206, 207, 13, 207, - 142, 230, 21, 4, 232, 207, 201, 206, 207, 13, 198, 206, 132, 57, 207, 13, - 198, 206, 143, 57, 207, 13, 195, 64, 230, 20, 207, 13, 230, 21, 4, 82, - 232, 212, 233, 163, 207, 142, 230, 21, 4, 210, 97, 248, 160, 82, 24, 206, - 184, 232, 206, 64, 143, 209, 51, 45, 230, 21, 223, 120, 202, 201, 64, 45, - 209, 51, 223, 120, 202, 201, 64, 50, 209, 51, 223, 120, 202, 201, 62, 45, - 209, 51, 223, 120, 202, 201, 62, 50, 209, 51, 223, 120, 62, 45, 209, 51, - 249, 94, 223, 120, 62, 50, 209, 51, 249, 94, 223, 120, 202, 201, 64, 132, - 209, 51, 223, 120, 202, 201, 64, 143, 209, 51, 223, 120, 202, 201, 62, - 132, 209, 51, 223, 120, 202, 201, 62, 143, 209, 51, 223, 120, 62, 132, - 209, 51, 249, 94, 223, 120, 62, 143, 209, 51, 249, 94, 223, 120, 62, 229, - 191, 237, 33, 239, 11, 221, 196, 24, 215, 165, 115, 214, 70, 239, 10, - 208, 202, 209, 63, 247, 94, 62, 229, 240, 203, 98, 232, 151, 236, 175, - 64, 229, 240, 203, 98, 232, 151, 236, 175, 202, 27, 203, 98, 232, 151, - 236, 175, 199, 177, 247, 36, 193, 54, 221, 195, 91, 247, 166, 215, 165, - 103, 247, 166, 215, 165, 115, 247, 166, 215, 165, 198, 20, 38, 209, 240, - 239, 11, 229, 240, 236, 175, 205, 71, 208, 203, 227, 246, 233, 23, 227, - 246, 211, 49, 236, 182, 227, 246, 236, 123, 4, 199, 48, 236, 123, 4, 199, - 49, 24, 209, 168, 236, 123, 4, 209, 168, 232, 76, 4, 209, 168, 232, 76, - 4, 198, 145, 232, 76, 4, 251, 82, 192, 235, 62, 232, 131, 232, 131, 211, - 66, 232, 131, 247, 53, 140, 236, 159, 247, 53, 232, 222, 248, 14, 232, - 222, 247, 107, 234, 63, 212, 249, 234, 63, 212, 250, 210, 194, 234, 63, - 212, 250, 210, 200, 212, 249, 212, 250, 210, 194, 212, 250, 210, 200, - 234, 63, 236, 122, 234, 63, 210, 194, 234, 63, 210, 192, 236, 122, 210, - 194, 210, 192, 193, 146, 201, 213, 212, 250, 210, 200, 201, 213, 247, 93, - 210, 200, 237, 33, 193, 63, 216, 21, 217, 3, 210, 248, 242, 173, 50, 24, - 45, 204, 23, 250, 181, 247, 77, 192, 235, 223, 126, 232, 124, 202, 111, - 113, 237, 89, 232, 124, 202, 111, 113, 239, 12, 38, 221, 197, 206, 135, - 214, 61, 210, 195, 4, 47, 199, 48, 201, 62, 243, 88, 237, 224, 221, 54, - 219, 72, 201, 228, 229, 204, 223, 135, 202, 182, 115, 207, 115, 56, 115, - 207, 115, 60, 115, 207, 115, 219, 200, 115, 207, 115, 187, 45, 201, 225, - 247, 216, 50, 201, 225, 247, 216, 103, 201, 225, 247, 215, 115, 201, 225, - 247, 215, 45, 198, 226, 247, 216, 50, 198, 226, 247, 216, 45, 251, 68, - 247, 216, 50, 251, 68, 247, 216, 215, 193, 247, 216, 219, 106, 215, 193, - 247, 216, 219, 106, 215, 192, 249, 57, 111, 4, 249, 56, 249, 57, 27, 192, - 235, 249, 57, 111, 4, 27, 192, 235, 249, 57, 28, 27, 192, 235, 249, 57, - 111, 4, 28, 27, 192, 235, 155, 243, 78, 77, 249, 57, 111, 4, 28, 243, 77, - 193, 18, 217, 51, 215, 170, 232, 43, 198, 80, 198, 25, 201, 87, 80, 219, - 120, 202, 183, 80, 222, 248, 215, 151, 230, 163, 233, 62, 230, 163, 233, - 63, 4, 202, 59, 233, 144, 233, 63, 4, 199, 121, 80, 222, 158, 202, 59, - 233, 63, 4, 211, 66, 215, 163, 202, 59, 233, 63, 4, 211, 66, 215, 164, - 24, 202, 59, 233, 144, 202, 59, 233, 63, 4, 211, 66, 215, 164, 24, 242, - 39, 200, 139, 202, 59, 233, 63, 4, 211, 66, 215, 164, 24, 198, 166, 233, - 144, 202, 59, 233, 63, 4, 230, 33, 202, 59, 233, 63, 4, 228, 155, 193, - 56, 233, 62, 202, 59, 233, 63, 4, 202, 59, 233, 144, 233, 63, 205, 104, - 237, 69, 232, 122, 207, 56, 233, 62, 202, 59, 233, 63, 4, 229, 190, 233, - 144, 202, 59, 233, 63, 4, 200, 189, 202, 58, 233, 62, 214, 68, 233, 62, - 233, 165, 233, 62, 196, 107, 233, 62, 233, 63, 4, 242, 39, 200, 139, 210, - 17, 233, 62, 239, 3, 233, 62, 239, 4, 233, 62, 221, 97, 233, 62, 233, 63, - 198, 209, 41, 221, 98, 221, 97, 233, 63, 4, 202, 59, 233, 144, 221, 97, - 233, 63, 4, 242, 171, 233, 144, 233, 63, 4, 201, 7, 198, 56, 233, 63, 4, - 201, 7, 198, 57, 24, 193, 56, 233, 152, 233, 63, 4, 201, 7, 198, 57, 24, - 198, 166, 233, 144, 236, 183, 233, 62, 193, 16, 233, 62, 251, 60, 233, - 62, 208, 255, 233, 62, 238, 152, 233, 62, 209, 244, 233, 62, 233, 63, 4, - 218, 239, 80, 197, 213, 236, 183, 247, 170, 207, 56, 233, 62, 232, 54, - 233, 63, 4, 211, 66, 215, 163, 251, 58, 233, 62, 233, 16, 233, 62, 193, - 117, 233, 62, 202, 86, 233, 62, 198, 125, 233, 62, 230, 164, 233, 62, - 218, 223, 238, 152, 233, 62, 233, 63, 4, 211, 66, 215, 163, 228, 99, 233, - 62, 233, 63, 4, 211, 66, 215, 164, 24, 242, 39, 200, 139, 233, 63, 205, - 73, 223, 135, 233, 17, 250, 140, 233, 62, 232, 143, 233, 62, 202, 87, - 233, 62, 236, 150, 233, 62, 233, 63, 193, 51, 215, 163, 233, 63, 4, 216, - 197, 217, 16, 230, 163, 247, 31, 233, 63, 4, 202, 59, 233, 144, 247, 31, - 233, 63, 4, 199, 121, 80, 222, 158, 202, 59, 247, 31, 233, 63, 4, 211, - 66, 215, 163, 202, 59, 247, 31, 233, 63, 4, 229, 190, 233, 144, 247, 31, - 233, 63, 4, 193, 1, 202, 60, 221, 97, 247, 31, 233, 63, 4, 242, 171, 233, - 144, 208, 255, 247, 31, 233, 62, 238, 152, 247, 31, 233, 62, 193, 117, - 247, 31, 233, 62, 202, 79, 232, 54, 233, 62, 202, 79, 202, 59, 233, 62, - 196, 68, 233, 62, 233, 63, 4, 206, 133, 233, 144, 233, 63, 4, 213, 31, - 230, 209, 231, 95, 233, 63, 4, 211, 115, 231, 95, 209, 242, 248, 20, 237, - 84, 205, 44, 215, 208, 229, 194, 215, 208, 201, 231, 215, 208, 229, 243, - 209, 242, 207, 140, 91, 230, 20, 209, 242, 207, 140, 248, 32, 229, 252, - 223, 135, 246, 236, 209, 242, 232, 53, 209, 242, 4, 208, 255, 233, 62, - 209, 242, 4, 232, 132, 229, 251, 185, 193, 103, 209, 51, 219, 209, 201, - 253, 193, 103, 209, 51, 219, 209, 185, 234, 160, 209, 51, 219, 209, 201, - 253, 234, 160, 209, 51, 219, 209, 152, 185, 193, 103, 209, 51, 219, 209, - 152, 201, 253, 193, 103, 209, 51, 219, 209, 152, 185, 234, 160, 209, 51, - 219, 209, 152, 201, 253, 234, 160, 209, 51, 219, 209, 185, 193, 103, 209, - 51, 195, 45, 219, 209, 201, 253, 193, 103, 209, 51, 195, 45, 219, 209, - 185, 234, 160, 209, 51, 195, 45, 219, 209, 201, 253, 234, 160, 209, 51, - 195, 45, 219, 209, 88, 185, 193, 103, 209, 51, 195, 45, 219, 209, 88, - 201, 253, 193, 103, 209, 51, 195, 45, 219, 209, 88, 185, 234, 160, 209, - 51, 195, 45, 219, 209, 88, 201, 253, 234, 160, 209, 51, 195, 45, 219, - 209, 185, 193, 103, 209, 51, 247, 212, 201, 253, 193, 103, 209, 51, 247, - 212, 185, 234, 160, 209, 51, 247, 212, 201, 253, 234, 160, 209, 51, 247, - 212, 88, 185, 193, 103, 209, 51, 247, 212, 88, 201, 253, 193, 103, 209, - 51, 247, 212, 88, 185, 234, 160, 209, 51, 247, 212, 88, 201, 253, 234, - 160, 209, 51, 247, 212, 228, 228, 208, 1, 51, 211, 32, 228, 228, 208, 1, - 51, 211, 33, 223, 135, 62, 201, 185, 202, 20, 208, 1, 51, 211, 32, 202, - 20, 208, 1, 51, 211, 33, 223, 135, 62, 201, 185, 117, 206, 141, 196, 62, - 206, 141, 96, 206, 141, 235, 75, 206, 141, 27, 34, 233, 214, 211, 32, 88, - 27, 34, 233, 214, 211, 32, 34, 211, 66, 233, 214, 211, 32, 88, 34, 211, - 66, 233, 214, 211, 32, 88, 251, 87, 211, 32, 200, 142, 251, 87, 211, 32, - 49, 88, 54, 152, 242, 27, 207, 247, 87, 211, 32, 49, 88, 54, 242, 27, - 207, 247, 87, 211, 32, 49, 88, 131, 54, 242, 27, 207, 247, 87, 211, 32, - 88, 223, 75, 211, 32, 49, 223, 75, 211, 32, 88, 49, 223, 75, 211, 32, - 195, 80, 88, 202, 18, 195, 80, 88, 207, 14, 202, 18, 243, 76, 248, 59, - 207, 14, 243, 76, 248, 59, 206, 141, 229, 173, 201, 80, 219, 8, 207, 147, - 247, 54, 229, 99, 198, 12, 229, 99, 198, 13, 4, 247, 201, 213, 0, 198, - 12, 216, 139, 155, 207, 148, 201, 88, 198, 10, 198, 11, 247, 54, 247, - 175, 211, 90, 247, 175, 197, 208, 247, 176, 201, 58, 216, 25, 251, 91, - 232, 203, 234, 45, 209, 43, 247, 54, 211, 90, 209, 43, 247, 54, 199, 150, - 211, 90, 199, 150, 250, 100, 211, 90, 250, 100, 207, 89, 195, 142, 237, - 65, 197, 199, 250, 175, 218, 230, 198, 19, 215, 201, 215, 169, 207, 146, - 200, 159, 207, 146, 215, 169, 247, 106, 251, 215, 198, 9, 203, 60, 206, - 107, 201, 223, 228, 209, 198, 16, 219, 108, 81, 198, 16, 219, 108, 238, - 246, 57, 209, 43, 247, 38, 207, 7, 219, 108, 197, 234, 232, 178, 211, 94, - 209, 12, 236, 100, 213, 31, 234, 31, 57, 202, 57, 113, 213, 31, 202, 57, - 113, 208, 125, 219, 60, 223, 135, 223, 22, 209, 100, 113, 236, 130, 212, - 255, 219, 60, 113, 209, 6, 193, 142, 113, 213, 15, 193, 142, 113, 248, - 136, 213, 31, 248, 135, 248, 134, 215, 169, 248, 134, 210, 42, 213, 31, - 210, 41, 243, 37, 238, 162, 216, 163, 113, 193, 32, 113, 207, 23, 249, - 99, 113, 198, 81, 193, 142, 242, 168, 203, 15, 249, 11, 249, 9, 210, 81, - 238, 230, 238, 109, 249, 76, 242, 198, 45, 218, 193, 197, 238, 4, 206, - 108, 238, 209, 208, 189, 57, 47, 223, 109, 201, 254, 248, 11, 113, 230, - 247, 113, 238, 201, 24, 220, 1, 202, 87, 252, 5, 203, 38, 249, 75, 248, - 184, 248, 185, 248, 208, 209, 100, 80, 193, 15, 211, 147, 57, 203, 38, - 197, 209, 201, 3, 210, 191, 229, 95, 199, 93, 228, 98, 234, 87, 209, 88, - 202, 82, 193, 91, 206, 184, 247, 185, 230, 29, 24, 193, 9, 203, 73, 211, - 120, 235, 50, 215, 173, 207, 147, 198, 21, 215, 176, 248, 58, 196, 72, - 216, 36, 251, 171, 196, 72, 251, 171, 196, 72, 2, 251, 171, 2, 251, 171, - 213, 4, 251, 171, 251, 172, 237, 48, 251, 172, 250, 188, 205, 113, 211, - 90, 232, 203, 234, 45, 236, 233, 219, 8, 210, 85, 203, 60, 205, 78, 215, - 176, 205, 78, 247, 65, 202, 89, 232, 138, 205, 108, 202, 106, 250, 102, - 206, 238, 209, 169, 197, 199, 206, 134, 202, 107, 160, 16, 39, 207, 253, - 160, 16, 39, 251, 173, 160, 16, 39, 232, 202, 160, 16, 39, 234, 163, 160, - 16, 39, 193, 141, 160, 16, 39, 250, 241, 160, 16, 39, 250, 242, 207, 76, - 160, 16, 39, 250, 242, 207, 75, 160, 16, 39, 250, 242, 195, 28, 160, 16, - 39, 250, 242, 195, 27, 160, 16, 39, 195, 42, 160, 16, 39, 195, 41, 160, - 16, 39, 195, 40, 160, 16, 39, 200, 200, 160, 16, 39, 209, 194, 200, 200, - 160, 16, 39, 62, 200, 200, 160, 16, 39, 216, 162, 200, 231, 160, 16, 39, - 216, 162, 200, 230, 160, 16, 39, 216, 162, 200, 229, 160, 16, 39, 242, - 221, 160, 16, 39, 205, 153, 160, 16, 39, 213, 148, 160, 16, 39, 195, 25, - 160, 16, 39, 195, 24, 160, 16, 39, 206, 143, 205, 153, 160, 16, 39, 206, - 143, 205, 152, 160, 16, 39, 230, 214, 160, 16, 39, 202, 179, 160, 16, 39, - 223, 46, 211, 39, 160, 16, 39, 223, 46, 211, 38, 160, 16, 39, 238, 175, - 80, 223, 45, 160, 16, 39, 207, 72, 80, 223, 45, 160, 16, 39, 238, 221, - 211, 39, 160, 16, 39, 223, 44, 211, 39, 160, 16, 39, 200, 232, 80, 238, - 220, 160, 16, 39, 238, 175, 80, 238, 220, 160, 16, 39, 238, 175, 80, 238, - 219, 160, 16, 39, 238, 221, 251, 28, 160, 16, 39, 205, 154, 80, 238, 221, - 251, 28, 160, 16, 39, 200, 232, 80, 205, 154, 80, 238, 220, 160, 16, 39, - 195, 136, 160, 16, 39, 198, 138, 211, 39, 160, 16, 39, 219, 213, 211, 39, - 160, 16, 39, 251, 27, 211, 39, 160, 16, 39, 200, 232, 80, 251, 26, 160, - 16, 39, 205, 154, 80, 251, 26, 160, 16, 39, 200, 232, 80, 205, 154, 80, - 251, 26, 160, 16, 39, 195, 43, 80, 251, 26, 160, 16, 39, 207, 72, 80, - 251, 26, 160, 16, 39, 207, 72, 80, 251, 25, 160, 16, 39, 207, 71, 160, - 16, 39, 207, 70, 160, 16, 39, 207, 69, 160, 16, 39, 207, 68, 160, 16, 39, - 251, 126, 160, 16, 39, 251, 125, 160, 16, 39, 217, 42, 160, 16, 39, 205, - 163, 160, 16, 39, 250, 180, 160, 16, 39, 207, 100, 160, 16, 39, 207, 99, - 160, 16, 39, 250, 104, 160, 16, 39, 248, 102, 211, 39, 160, 16, 39, 199, - 172, 160, 16, 39, 199, 171, 160, 16, 39, 208, 3, 219, 97, 160, 16, 39, - 248, 39, 160, 16, 39, 248, 38, 160, 16, 39, 248, 37, 160, 16, 39, 251, - 100, 160, 16, 39, 211, 119, 160, 16, 39, 201, 209, 160, 16, 39, 198, 136, - 160, 16, 39, 230, 125, 160, 16, 39, 193, 129, 160, 16, 39, 208, 250, 160, - 16, 39, 247, 89, 160, 16, 39, 197, 46, 160, 16, 39, 247, 56, 215, 182, - 160, 16, 39, 205, 88, 80, 222, 160, 160, 16, 39, 247, 103, 160, 16, 39, - 197, 231, 160, 16, 39, 201, 95, 197, 231, 160, 16, 39, 219, 7, 160, 16, - 39, 202, 32, 160, 16, 39, 196, 50, 160, 16, 39, 228, 153, 235, 27, 160, - 16, 39, 250, 154, 160, 16, 39, 209, 8, 250, 154, 160, 16, 39, 247, 239, - 160, 16, 39, 208, 249, 247, 239, 160, 16, 39, 251, 97, 160, 16, 39, 201, - 41, 200, 181, 201, 40, 160, 16, 39, 201, 41, 200, 181, 201, 39, 160, 16, - 39, 200, 228, 160, 16, 39, 208, 222, 160, 16, 39, 236, 170, 160, 16, 39, - 236, 172, 160, 16, 39, 236, 171, 160, 16, 39, 208, 134, 160, 16, 39, 208, - 122, 160, 16, 39, 238, 160, 160, 16, 39, 238, 159, 160, 16, 39, 238, 158, - 160, 16, 39, 238, 157, 160, 16, 39, 238, 156, 160, 16, 39, 251, 140, 160, - 16, 39, 249, 12, 80, 217, 23, 160, 16, 39, 249, 12, 80, 195, 171, 160, - 16, 39, 207, 21, 160, 16, 39, 228, 145, 160, 16, 39, 213, 176, 160, 16, - 39, 237, 158, 160, 16, 39, 215, 196, 160, 16, 39, 134, 235, 65, 160, 16, - 39, 134, 211, 7, 62, 219, 195, 223, 28, 50, 197, 237, 62, 196, 72, 223, - 28, 50, 197, 237, 62, 206, 198, 223, 28, 50, 197, 237, 62, 235, 78, 223, - 28, 50, 197, 237, 62, 202, 79, 2, 242, 218, 216, 194, 28, 64, 242, 218, - 28, 64, 242, 218, 88, 64, 242, 218, 195, 80, 88, 64, 242, 218, 233, 156, - 88, 64, 242, 218, 64, 242, 219, 238, 242, 62, 2, 242, 218, 206, 110, 199, - 173, 62, 198, 133, 201, 185, 62, 202, 79, 2, 201, 185, 155, 64, 201, 185, - 216, 194, 64, 201, 185, 28, 64, 201, 185, 88, 64, 201, 185, 195, 80, 88, - 64, 201, 185, 233, 156, 88, 64, 201, 185, 64, 51, 238, 242, 62, 195, 80, - 2, 201, 185, 64, 51, 238, 242, 62, 216, 194, 201, 185, 51, 199, 173, 62, - 198, 133, 236, 243, 62, 195, 80, 2, 236, 243, 62, 216, 194, 2, 236, 243, - 64, 236, 244, 238, 242, 62, 195, 80, 2, 236, 243, 64, 236, 244, 238, 242, - 62, 216, 194, 236, 243, 236, 244, 199, 173, 62, 198, 133, 218, 210, 62, - 195, 80, 2, 218, 210, 62, 216, 194, 2, 218, 210, 64, 218, 211, 238, 242, - 62, 2, 218, 210, 198, 255, 35, 238, 170, 155, 35, 238, 170, 216, 194, 35, - 238, 170, 28, 35, 238, 170, 195, 80, 28, 35, 238, 170, 195, 80, 88, 35, - 238, 170, 233, 156, 88, 35, 238, 170, 198, 255, 205, 149, 155, 205, 149, - 216, 194, 205, 149, 28, 205, 149, 88, 205, 149, 195, 80, 88, 205, 149, - 233, 156, 88, 205, 149, 155, 232, 185, 201, 201, 250, 143, 216, 194, 232, - 185, 201, 201, 250, 143, 28, 232, 185, 201, 201, 250, 143, 88, 232, 185, - 201, 201, 250, 143, 195, 80, 88, 232, 185, 201, 201, 250, 143, 233, 156, - 88, 232, 185, 201, 201, 250, 143, 155, 202, 131, 201, 201, 250, 143, 216, - 194, 202, 131, 201, 201, 250, 143, 28, 202, 131, 201, 201, 250, 143, 88, - 202, 131, 201, 201, 250, 143, 195, 80, 88, 202, 131, 201, 201, 250, 143, - 233, 156, 88, 202, 131, 201, 201, 250, 143, 155, 234, 121, 201, 201, 250, - 143, 216, 194, 234, 121, 201, 201, 250, 143, 28, 234, 121, 201, 201, 250, - 143, 88, 234, 121, 201, 201, 250, 143, 195, 80, 88, 234, 121, 201, 201, - 250, 143, 155, 115, 209, 53, 62, 201, 97, 216, 194, 115, 209, 53, 62, - 201, 97, 115, 209, 53, 62, 201, 97, 216, 194, 115, 209, 53, 209, 122, - 201, 97, 155, 232, 90, 209, 53, 62, 201, 97, 216, 194, 232, 90, 209, 53, - 62, 201, 97, 232, 90, 209, 53, 62, 201, 97, 216, 194, 232, 90, 209, 53, - 209, 122, 201, 97, 207, 14, 155, 232, 90, 209, 53, 209, 122, 201, 97, - 155, 232, 185, 209, 53, 62, 201, 97, 88, 232, 185, 209, 53, 62, 201, 97, - 216, 194, 202, 131, 209, 53, 62, 201, 97, 88, 202, 131, 209, 53, 62, 201, - 97, 202, 131, 209, 53, 209, 122, 201, 97, 216, 194, 234, 121, 209, 53, - 62, 201, 97, 88, 234, 121, 209, 53, 62, 201, 97, 195, 80, 88, 234, 121, - 209, 53, 62, 201, 97, 88, 234, 121, 209, 53, 209, 122, 201, 97, 155, 197, - 34, 209, 53, 62, 201, 97, 88, 197, 34, 209, 53, 62, 201, 97, 88, 197, 34, - 209, 53, 209, 122, 201, 97, 47, 197, 237, 214, 92, 47, 197, 237, 47, 201, - 185, 214, 92, 47, 201, 185, 219, 245, 211, 44, 242, 218, 219, 245, 192, - 73, 242, 218, 219, 245, 230, 167, 242, 218, 219, 245, 208, 131, 242, 218, - 219, 245, 247, 227, 242, 218, 219, 245, 207, 82, 201, 185, 219, 245, 248, - 67, 201, 185, 219, 245, 211, 44, 201, 185, 219, 245, 192, 73, 201, 185, - 219, 245, 230, 167, 201, 185, 219, 245, 208, 131, 201, 185, 219, 245, - 247, 227, 201, 185, 88, 234, 1, 57, 117, 63, 4, 2, 197, 238, 250, 185, - 196, 62, 63, 4, 2, 197, 238, 250, 185, 96, 63, 4, 2, 197, 238, 250, 185, - 235, 75, 63, 4, 2, 197, 238, 250, 185, 117, 63, 4, 216, 194, 197, 238, - 250, 185, 196, 62, 63, 4, 216, 194, 197, 238, 250, 185, 96, 63, 4, 216, - 194, 197, 238, 250, 185, 235, 75, 63, 4, 216, 194, 197, 238, 250, 185, - 117, 63, 4, 219, 245, 197, 238, 250, 185, 196, 62, 63, 4, 219, 245, 197, - 238, 250, 185, 96, 63, 4, 219, 245, 197, 238, 250, 185, 235, 75, 63, 4, - 219, 245, 197, 238, 250, 185, 117, 63, 4, 2, 233, 251, 250, 185, 196, 62, - 63, 4, 2, 233, 251, 250, 185, 96, 63, 4, 2, 233, 251, 250, 185, 235, 75, - 63, 4, 2, 233, 251, 250, 185, 117, 63, 4, 233, 251, 250, 185, 196, 62, - 63, 4, 233, 251, 250, 185, 96, 63, 4, 233, 251, 250, 185, 235, 75, 63, 4, - 233, 251, 250, 185, 88, 117, 63, 4, 233, 251, 250, 185, 88, 196, 62, 63, - 4, 233, 251, 250, 185, 88, 96, 63, 4, 233, 251, 250, 185, 88, 235, 75, - 63, 4, 233, 251, 250, 185, 88, 117, 63, 4, 219, 245, 233, 251, 250, 185, - 88, 196, 62, 63, 4, 219, 245, 233, 251, 250, 185, 88, 96, 63, 4, 219, - 245, 233, 251, 250, 185, 88, 235, 75, 63, 4, 219, 245, 233, 251, 250, - 185, 117, 197, 236, 63, 4, 214, 201, 203, 144, 196, 62, 197, 236, 63, 4, - 214, 201, 203, 144, 96, 197, 236, 63, 4, 214, 201, 203, 144, 235, 75, - 197, 236, 63, 4, 214, 201, 203, 144, 117, 197, 236, 63, 4, 216, 194, 203, - 144, 196, 62, 197, 236, 63, 4, 216, 194, 203, 144, 96, 197, 236, 63, 4, - 216, 194, 203, 144, 235, 75, 197, 236, 63, 4, 216, 194, 203, 144, 117, - 197, 236, 63, 4, 28, 203, 144, 196, 62, 197, 236, 63, 4, 28, 203, 144, - 96, 197, 236, 63, 4, 28, 203, 144, 235, 75, 197, 236, 63, 4, 28, 203, - 144, 117, 197, 236, 63, 4, 88, 203, 144, 196, 62, 197, 236, 63, 4, 88, - 203, 144, 96, 197, 236, 63, 4, 88, 203, 144, 235, 75, 197, 236, 63, 4, - 88, 203, 144, 117, 197, 236, 63, 4, 195, 80, 88, 203, 144, 196, 62, 197, - 236, 63, 4, 195, 80, 88, 203, 144, 96, 197, 236, 63, 4, 195, 80, 88, 203, - 144, 235, 75, 197, 236, 63, 4, 195, 80, 88, 203, 144, 117, 232, 210, 55, - 196, 62, 232, 210, 55, 96, 232, 210, 55, 235, 75, 232, 210, 55, 117, 112, - 55, 196, 62, 112, 55, 96, 112, 55, 235, 75, 112, 55, 117, 239, 13, 55, - 196, 62, 239, 13, 55, 96, 239, 13, 55, 235, 75, 239, 13, 55, 117, 88, - 239, 13, 55, 196, 62, 88, 239, 13, 55, 96, 88, 239, 13, 55, 235, 75, 88, - 239, 13, 55, 117, 88, 55, 196, 62, 88, 55, 96, 88, 55, 235, 75, 88, 55, - 117, 49, 55, 196, 62, 49, 55, 96, 49, 55, 235, 75, 49, 55, 185, 193, 103, - 49, 55, 185, 234, 160, 49, 55, 201, 253, 234, 160, 49, 55, 201, 253, 193, - 103, 49, 55, 45, 50, 49, 55, 132, 143, 49, 55, 193, 75, 117, 155, 178, - 55, 193, 75, 196, 62, 155, 178, 55, 193, 75, 96, 155, 178, 55, 193, 75, - 235, 75, 155, 178, 55, 193, 75, 185, 193, 103, 155, 178, 55, 193, 75, - 185, 234, 160, 155, 178, 55, 193, 75, 201, 253, 234, 160, 155, 178, 55, - 193, 75, 201, 253, 193, 103, 155, 178, 55, 193, 75, 117, 178, 55, 193, - 75, 196, 62, 178, 55, 193, 75, 96, 178, 55, 193, 75, 235, 75, 178, 55, - 193, 75, 185, 193, 103, 178, 55, 193, 75, 185, 234, 160, 178, 55, 193, - 75, 201, 253, 234, 160, 178, 55, 193, 75, 201, 253, 193, 103, 178, 55, - 193, 75, 117, 216, 194, 178, 55, 193, 75, 196, 62, 216, 194, 178, 55, - 193, 75, 96, 216, 194, 178, 55, 193, 75, 235, 75, 216, 194, 178, 55, 193, - 75, 185, 193, 103, 216, 194, 178, 55, 193, 75, 185, 234, 160, 216, 194, - 178, 55, 193, 75, 201, 253, 234, 160, 216, 194, 178, 55, 193, 75, 201, - 253, 193, 103, 216, 194, 178, 55, 193, 75, 117, 88, 178, 55, 193, 75, - 196, 62, 88, 178, 55, 193, 75, 96, 88, 178, 55, 193, 75, 235, 75, 88, - 178, 55, 193, 75, 185, 193, 103, 88, 178, 55, 193, 75, 185, 234, 160, 88, - 178, 55, 193, 75, 201, 253, 234, 160, 88, 178, 55, 193, 75, 201, 253, - 193, 103, 88, 178, 55, 193, 75, 117, 195, 80, 88, 178, 55, 193, 75, 196, - 62, 195, 80, 88, 178, 55, 193, 75, 96, 195, 80, 88, 178, 55, 193, 75, - 235, 75, 195, 80, 88, 178, 55, 193, 75, 185, 193, 103, 195, 80, 88, 178, - 55, 193, 75, 185, 234, 160, 195, 80, 88, 178, 55, 193, 75, 201, 253, 234, - 160, 195, 80, 88, 178, 55, 193, 75, 201, 253, 193, 103, 195, 80, 88, 178, - 55, 117, 197, 238, 250, 185, 196, 62, 197, 238, 250, 185, 96, 197, 238, - 250, 185, 235, 75, 197, 238, 250, 185, 117, 64, 63, 193, 53, 197, 238, - 250, 185, 196, 62, 64, 63, 193, 53, 197, 238, 250, 185, 96, 64, 63, 193, - 53, 197, 238, 250, 185, 235, 75, 64, 63, 193, 53, 197, 238, 250, 185, - 117, 63, 4, 212, 251, 199, 210, 196, 62, 63, 4, 212, 251, 199, 210, 96, - 63, 4, 212, 251, 199, 210, 235, 75, 63, 4, 212, 251, 199, 210, 88, 63, - 203, 145, 193, 73, 108, 88, 63, 203, 145, 193, 73, 103, 198, 248, 88, 63, - 203, 145, 193, 73, 91, 230, 37, 88, 63, 203, 145, 193, 73, 91, 198, 251, - 117, 248, 26, 64, 55, 96, 248, 29, 203, 147, 64, 55, 117, 198, 49, 203, - 147, 64, 55, 96, 198, 49, 203, 147, 64, 55, 117, 219, 194, 64, 55, 96, - 206, 197, 64, 55, 117, 206, 197, 64, 55, 96, 219, 194, 64, 55, 117, 249, - 95, 203, 146, 64, 55, 96, 249, 95, 203, 146, 64, 55, 117, 232, 57, 203, - 146, 64, 55, 96, 232, 57, 203, 146, 64, 55, 64, 63, 203, 145, 193, 73, - 108, 64, 63, 203, 145, 193, 73, 103, 198, 248, 63, 209, 51, 196, 62, 199, - 20, 185, 193, 102, 63, 209, 51, 96, 199, 20, 238, 114, 201, 253, 193, - 102, 47, 238, 171, 232, 104, 4, 232, 90, 236, 94, 47, 238, 171, 232, 104, - 4, 103, 236, 94, 47, 238, 171, 232, 103, 45, 134, 242, 219, 4, 232, 90, - 236, 94, 45, 134, 242, 219, 4, 115, 236, 94, 45, 134, 242, 219, 4, 103, - 236, 94, 45, 134, 242, 219, 4, 236, 96, 45, 134, 242, 218, 235, 76, 233, - 55, 106, 235, 76, 233, 55, 212, 251, 106, 235, 76, 233, 55, 228, 219, 4, - 236, 96, 235, 76, 233, 55, 212, 251, 228, 219, 4, 236, 96, 209, 127, 232, - 206, 64, 229, 191, 247, 227, 229, 191, 209, 126, 230, 20, 191, 17, 233, - 62, 215, 212, 233, 62, 233, 63, 4, 199, 16, 214, 78, 233, 62, 198, 253, - 233, 62, 233, 63, 4, 229, 202, 206, 145, 233, 62, 228, 119, 233, 62, 3, - 80, 199, 29, 228, 155, 247, 91, 216, 214, 230, 20, 207, 142, 249, 97, 80, - 230, 20, 219, 199, 232, 190, 206, 202, 232, 190, 229, 250, 230, 21, 4, - 140, 24, 82, 232, 207, 238, 166, 228, 44, 218, 220, 191, 239, 230, 21, - 57, 233, 63, 4, 238, 191, 229, 232, 242, 160, 233, 62, 214, 188, 233, 62, - 206, 133, 211, 94, 199, 29, 232, 154, 219, 231, 235, 56, 233, 62, 218, - 157, 233, 62, 233, 63, 210, 172, 202, 51, 233, 62, 233, 63, 4, 91, 233, - 151, 207, 141, 230, 163, 233, 63, 4, 201, 98, 233, 144, 230, 163, 233, - 63, 4, 91, 219, 245, 24, 91, 2, 233, 152, 233, 63, 4, 232, 212, 238, 194, - 242, 171, 219, 72, 203, 253, 233, 63, 4, 200, 73, 238, 194, 215, 163, - 202, 59, 233, 63, 4, 202, 59, 233, 145, 24, 230, 21, 238, 194, 215, 163, - 233, 63, 4, 211, 66, 215, 164, 195, 6, 203, 49, 233, 63, 4, 233, 167, - 229, 203, 208, 219, 193, 35, 247, 248, 210, 171, 132, 198, 82, 204, 26, - 208, 207, 217, 71, 223, 135, 197, 42, 215, 178, 243, 7, 203, 4, 209, 242, - 236, 114, 247, 35, 222, 150, 232, 253, 215, 238, 210, 12, 193, 8, 193, - 142, 209, 37, 229, 255, 236, 156, 217, 16, 193, 67, 232, 146, 235, 51, 4, - 235, 49, 242, 178, 230, 235, 197, 70, 230, 236, 201, 198, 230, 221, 214, - 71, 206, 203, 232, 197, 209, 100, 216, 200, 205, 52, 209, 100, 216, 200, - 198, 252, 209, 100, 216, 200, 248, 13, 230, 230, 217, 27, 250, 173, 196, - 90, 238, 125, 201, 60, 220, 86, 201, 70, 24, 249, 61, 202, 26, 232, 138, - 236, 181, 238, 174, 250, 91, 238, 141, 249, 88, 209, 5, 247, 39, 249, 74, - 247, 251, 230, 167, 205, 160, 203, 137, 210, 157, 80, 232, 122, 201, 4, - 232, 165, 234, 136, 230, 237, 80, 216, 35, 210, 47, 221, 92, 210, 153, - 235, 32, 232, 99, 238, 225, 199, 202, 248, 14, 243, 14, 248, 19, 4, 201, - 198, 238, 135, 4, 201, 38, 242, 45, 247, 231, 209, 167, 208, 211, 238, - 108, 80, 216, 205, 205, 132, 247, 67, 232, 122, 219, 208, 230, 166, 217, - 62, 215, 189, 247, 98, 249, 77, 202, 59, 233, 63, 4, 202, 59, 233, 145, - 24, 115, 229, 189, 192, 87, 233, 62, 202, 59, 233, 63, 4, 199, 126, 233, - 63, 4, 210, 92, 228, 157, 24, 210, 92, 229, 232, 233, 63, 4, 196, 94, - 233, 145, 24, 193, 133, 215, 163, 210, 251, 233, 62, 232, 69, 233, 62, - 213, 155, 236, 179, 233, 62, 233, 63, 228, 230, 249, 97, 199, 120, 233, - 63, 4, 209, 85, 233, 144, 205, 120, 220, 95, 242, 48, 230, 217, 229, 97, - 248, 43, 232, 167, 203, 47, 238, 188, 219, 76, 233, 62, 205, 76, 197, 58, - 196, 92, 233, 62, 234, 170, 235, 41, 249, 14, 203, 123, 210, 239, 232, - 82, 233, 62, 247, 167, 237, 83, 230, 201, 219, 54, 207, 0, 203, 8, 201, - 179, 230, 249, 233, 62, 191, 85, 233, 62, 229, 184, 205, 105, 200, 38, - 238, 177, 222, 56, 219, 46, 210, 49, 229, 89, 210, 98, 207, 168, 219, 17, - 215, 180, 216, 71, 249, 83, 200, 144, 217, 72, 236, 120, 202, 73, 211, - 12, 211, 43, 202, 97, 232, 169, 210, 229, 248, 210, 248, 101, 205, 56, - 230, 130, 236, 117, 208, 195, 247, 69, 234, 67, 242, 16, 207, 82, 230, - 45, 234, 67, 242, 16, 238, 124, 230, 45, 234, 67, 242, 16, 249, 63, 234, - 67, 242, 16, 64, 230, 45, 248, 50, 219, 188, 232, 120, 198, 51, 200, 179, - 200, 174, 205, 183, 195, 78, 234, 168, 4, 229, 193, 251, 183, 215, 174, - 193, 89, 217, 54, 193, 89, 216, 204, 250, 200, 216, 204, 219, 188, 243, - 70, 193, 114, 238, 133, 205, 154, 203, 141, 248, 158, 248, 14, 231, 160, - 211, 82, 233, 44, 193, 171, 247, 168, 217, 10, 235, 60, 227, 253, 238, - 143, 247, 217, 199, 129, 197, 210, 201, 100, 209, 241, 221, 56, 209, 241, - 237, 99, 209, 241, 233, 63, 4, 215, 207, 251, 233, 243, 38, 211, 107, - 251, 233, 248, 214, 209, 241, 209, 242, 4, 229, 198, 209, 242, 223, 135, - 201, 77, 206, 125, 209, 242, 242, 180, 209, 242, 223, 135, 218, 225, 209, - 17, 217, 103, 233, 46, 195, 174, 216, 155, 234, 82, 231, 111, 191, 5, - 248, 2, 211, 44, 229, 191, 248, 123, 247, 63, 205, 89, 230, 229, 242, 48, - 202, 29, 207, 82, 231, 6, 234, 25, 232, 201, 222, 211, 208, 118, 209, - 166, 199, 70, 197, 80, 209, 226, 236, 177, 236, 131, 54, 229, 172, 242, - 21, 252, 19, 232, 203, 233, 161, 198, 53, 247, 239, 217, 101, 218, 193, - 218, 226, 248, 30, 201, 199, 80, 198, 222, 249, 62, 80, 192, 100, 205, - 183, 209, 130, 199, 119, 248, 215, 247, 228, 249, 19, 206, 136, 80, 210, - 125, 249, 38, 80, 202, 32, 201, 200, 207, 98, 214, 182, 251, 83, 214, 68, - 243, 57, 221, 114, 214, 68, 243, 57, 208, 9, 214, 68, 243, 57, 206, 126, - 214, 68, 243, 57, 248, 104, 214, 68, 243, 57, 221, 52, 214, 68, 243, 57, - 210, 64, 64, 243, 57, 221, 53, 206, 117, 232, 96, 237, 79, 62, 243, 57, - 221, 53, 206, 117, 232, 96, 237, 79, 214, 68, 243, 57, 221, 53, 206, 117, - 232, 96, 237, 79, 64, 243, 57, 221, 115, 206, 117, 213, 157, 237, 79, 64, - 243, 57, 208, 10, 206, 117, 213, 157, 237, 79, 64, 243, 57, 206, 127, - 206, 117, 213, 157, 237, 79, 64, 243, 57, 248, 105, 206, 117, 213, 157, - 237, 79, 64, 243, 57, 221, 53, 206, 117, 213, 157, 237, 79, 64, 243, 57, - 210, 65, 206, 117, 213, 157, 237, 79, 62, 243, 57, 221, 115, 206, 117, - 213, 157, 237, 79, 62, 243, 57, 208, 10, 206, 117, 213, 157, 237, 79, 62, - 243, 57, 206, 127, 206, 117, 213, 157, 237, 79, 62, 243, 57, 248, 105, - 206, 117, 213, 157, 237, 79, 62, 243, 57, 221, 53, 206, 117, 213, 157, - 237, 79, 62, 243, 57, 210, 65, 206, 117, 213, 157, 237, 79, 214, 68, 243, - 57, 221, 115, 206, 117, 213, 157, 237, 79, 214, 68, 243, 57, 208, 10, - 206, 117, 213, 157, 237, 79, 214, 68, 243, 57, 206, 127, 206, 117, 213, - 157, 237, 79, 214, 68, 243, 57, 248, 105, 206, 117, 213, 157, 237, 79, - 214, 68, 243, 57, 221, 53, 206, 117, 213, 157, 237, 79, 214, 68, 243, 57, - 210, 65, 206, 117, 213, 157, 237, 79, 64, 243, 57, 221, 53, 206, 117, 91, - 228, 110, 198, 243, 237, 79, 62, 243, 57, 221, 53, 206, 117, 91, 228, - 110, 198, 243, 237, 79, 214, 68, 243, 57, 221, 53, 206, 117, 91, 228, - 110, 198, 243, 237, 79, 64, 243, 57, 152, 221, 114, 64, 243, 57, 152, - 208, 9, 64, 243, 57, 152, 206, 126, 64, 243, 57, 152, 248, 104, 64, 243, - 57, 152, 221, 52, 64, 243, 57, 152, 210, 64, 62, 243, 57, 152, 221, 114, - 62, 243, 57, 152, 208, 9, 62, 243, 57, 152, 206, 126, 62, 243, 57, 152, - 248, 104, 62, 243, 57, 152, 221, 52, 62, 243, 57, 152, 210, 64, 214, 68, - 243, 57, 152, 221, 114, 214, 68, 243, 57, 152, 208, 9, 214, 68, 243, 57, - 152, 206, 126, 214, 68, 243, 57, 152, 248, 104, 214, 68, 243, 57, 152, - 221, 52, 214, 68, 243, 57, 152, 210, 64, 64, 243, 57, 221, 53, 206, 117, - 103, 228, 110, 197, 25, 237, 79, 62, 243, 57, 221, 53, 206, 117, 103, - 228, 110, 197, 25, 237, 79, 214, 68, 243, 57, 221, 53, 206, 117, 103, - 228, 110, 197, 25, 237, 79, 64, 243, 57, 221, 115, 206, 117, 103, 228, - 110, 203, 237, 237, 79, 64, 243, 57, 208, 10, 206, 117, 103, 228, 110, - 203, 237, 237, 79, 64, 243, 57, 206, 127, 206, 117, 103, 228, 110, 203, - 237, 237, 79, 64, 243, 57, 248, 105, 206, 117, 103, 228, 110, 203, 237, - 237, 79, 64, 243, 57, 221, 53, 206, 117, 103, 228, 110, 203, 237, 237, - 79, 64, 243, 57, 210, 65, 206, 117, 103, 228, 110, 203, 237, 237, 79, 62, - 243, 57, 221, 115, 206, 117, 103, 228, 110, 203, 237, 237, 79, 62, 243, - 57, 208, 10, 206, 117, 103, 228, 110, 203, 237, 237, 79, 62, 243, 57, - 206, 127, 206, 117, 103, 228, 110, 203, 237, 237, 79, 62, 243, 57, 248, - 105, 206, 117, 103, 228, 110, 203, 237, 237, 79, 62, 243, 57, 221, 53, - 206, 117, 103, 228, 110, 203, 237, 237, 79, 62, 243, 57, 210, 65, 206, - 117, 103, 228, 110, 203, 237, 237, 79, 214, 68, 243, 57, 221, 115, 206, - 117, 103, 228, 110, 203, 237, 237, 79, 214, 68, 243, 57, 208, 10, 206, - 117, 103, 228, 110, 203, 237, 237, 79, 214, 68, 243, 57, 206, 127, 206, - 117, 103, 228, 110, 203, 237, 237, 79, 214, 68, 243, 57, 248, 105, 206, - 117, 103, 228, 110, 203, 237, 237, 79, 214, 68, 243, 57, 221, 53, 206, - 117, 103, 228, 110, 203, 237, 237, 79, 214, 68, 243, 57, 210, 65, 206, - 117, 103, 228, 110, 203, 237, 237, 79, 64, 243, 57, 221, 53, 206, 117, - 115, 228, 110, 232, 235, 237, 79, 62, 243, 57, 221, 53, 206, 117, 115, - 228, 110, 232, 235, 237, 79, 214, 68, 243, 57, 221, 53, 206, 117, 115, - 228, 110, 232, 235, 237, 79, 64, 243, 57, 233, 252, 62, 243, 57, 233, - 252, 214, 68, 243, 57, 233, 252, 64, 243, 57, 233, 253, 206, 117, 213, - 157, 237, 79, 62, 243, 57, 233, 253, 206, 117, 213, 157, 237, 79, 214, - 68, 243, 57, 233, 253, 206, 117, 213, 157, 237, 79, 64, 243, 57, 221, 50, - 64, 243, 57, 221, 49, 64, 243, 57, 221, 51, 62, 243, 57, 221, 50, 62, - 243, 57, 221, 49, 62, 243, 57, 221, 51, 192, 205, 207, 82, 231, 113, 192, - 205, 207, 82, 217, 64, 192, 205, 207, 82, 234, 88, 192, 205, 207, 82, - 228, 152, 192, 205, 207, 82, 243, 90, 192, 205, 207, 82, 247, 66, 192, - 205, 207, 82, 202, 21, 192, 205, 62, 231, 113, 192, 205, 62, 217, 64, - 192, 205, 62, 234, 88, 192, 205, 62, 228, 152, 192, 205, 62, 243, 90, - 192, 205, 62, 247, 66, 192, 205, 62, 202, 21, 249, 60, 203, 46, 211, 87, - 200, 131, 247, 235, 203, 20, 198, 232, 205, 134, 235, 55, 80, 248, 72, - 251, 239, 249, 46, 201, 71, 192, 234, 238, 154, 191, 253, 221, 95, 210, - 119, 248, 44, 217, 102, 193, 160, 209, 128, 214, 73, 236, 109, 206, 182, - 209, 92, 246, 204, 207, 113, 250, 82, 236, 151, 220, 1, 249, 44, 216, 36, - 229, 168, 252, 4, 177, 235, 50, 242, 40, 247, 41, 205, 103, 205, 70, 220, - 85, 106, 216, 9, 193, 63, 209, 75, 203, 234, 214, 95, 221, 47, 247, 214, - 215, 166, 198, 2, 198, 50, 229, 196, 209, 101, 206, 142, 216, 10, 249, - 61, 227, 243, 247, 52, 131, 249, 8, 230, 27, 232, 139, 193, 17, 248, 201, - 242, 47, 209, 4, 209, 91, 193, 28, 233, 13, 218, 224, 238, 213, 234, 63, - 214, 75, 214, 76, 4, 234, 135, 251, 78, 229, 191, 218, 184, 210, 11, 228, - 118, 208, 219, 217, 70, 208, 219, 209, 241, 209, 242, 4, 238, 161, 248, - 65, 248, 186, 210, 6, 211, 104, 232, 165, 199, 191, 232, 126, 199, 127, - 209, 0, 219, 68, 248, 217, 222, 246, 216, 176, 233, 62, 205, 148, 233, - 62, 233, 63, 4, 211, 66, 233, 145, 24, 230, 21, 138, 215, 163, 233, 63, - 4, 210, 38, 233, 152, 233, 63, 4, 236, 250, 215, 163, 235, 94, 219, 89, - 233, 62, 248, 97, 219, 74, 247, 215, 230, 21, 4, 140, 232, 212, 24, 174, - 238, 166, 96, 230, 20, 117, 230, 20, 210, 173, 143, 230, 20, 210, 173, - 132, 230, 20, 140, 209, 51, 250, 133, 199, 29, 195, 52, 229, 192, 229, - 251, 182, 203, 231, 182, 203, 201, 182, 203, 230, 182, 203, 186, 182, - 203, 215, 182, 203, 200, 182, 203, 229, 182, 203, 178, 182, 203, 208, - 182, 203, 192, 182, 203, 222, 182, 203, 185, 182, 203, 214, 182, 203, - 199, 182, 203, 228, 182, 203, 174, 182, 203, 204, 182, 203, 189, 182, - 203, 218, 182, 203, 181, 182, 203, 195, 182, 203, 225, 182, 203, 177, - 182, 203, 207, 182, 203, 191, 182, 203, 221, 182, 203, 184, 182, 203, - 213, 182, 203, 198, 182, 203, 227, 182, 203, 172, 182, 203, 202, 182, - 203, 187, 182, 203, 216, 182, 203, 179, 182, 203, 209, 182, 203, 193, - 182, 203, 223, 182, 203, 175, 182, 203, 205, 182, 203, 219, 182, 203, - 182, 182, 203, 211, 182, 203, 196, 182, 203, 226, 182, 203, 173, 182, - 203, 203, 182, 203, 188, 182, 203, 217, 182, 203, 180, 182, 203, 210, - 182, 203, 194, 182, 203, 224, 182, 203, 176, 182, 203, 206, 182, 203, - 190, 182, 203, 220, 182, 203, 183, 182, 203, 212, 182, 203, 197, 110, 45, - 182, 236, 250, 110, 82, 45, 118, 110, 246, 229, 110, 45, 182, 236, 250, - 110, 82, 45, 118, 110, 187, 110, 45, 182, 236, 250, 116, 82, 45, 118, - 110, 246, 229, 110, 45, 182, 236, 250, 116, 82, 45, 118, 110, 187, 110, - 45, 182, 236, 250, 116, 45, 118, 110, 246, 229, 110, 50, 182, 236, 250, - 116, 82, 45, 118, 116, 246, 229, 110, 50, 182, 236, 250, 116, 82, 45, - 118, 116, 187, 110, 50, 182, 236, 250, 110, 82, 45, 118, 116, 246, 229, - 110, 50, 182, 236, 250, 110, 82, 45, 118, 116, 187, 110, 50, 182, 236, - 250, 110, 45, 118, 116, 246, 229, 110, 50, 182, 236, 250, 110, 82, 45, - 118, 116, 82, 187, 110, 50, 182, 236, 250, 110, 246, 230, 118, 110, 82, - 187, 110, 50, 182, 236, 250, 110, 45, 118, 110, 82, 187, 110, 50, 182, - 236, 250, 110, 246, 230, 118, 116, 82, 187, 110, 50, 182, 236, 250, 110, - 45, 118, 116, 82, 187, 110, 50, 182, 236, 250, 110, 246, 230, 118, 116, - 187, 110, 45, 182, 236, 250, 116, 246, 230, 118, 116, 82, 187, 110, 45, - 182, 236, 250, 116, 45, 118, 116, 82, 187, 110, 45, 182, 236, 250, 116, - 246, 230, 118, 110, 82, 187, 110, 45, 182, 236, 250, 116, 45, 118, 110, - 82, 187, 110, 45, 182, 236, 250, 116, 246, 230, 118, 110, 187, 110, 45, - 182, 236, 250, 116, 82, 45, 118, 110, 82, 187, 116, 50, 182, 236, 250, - 110, 82, 45, 118, 110, 246, 229, 116, 50, 182, 236, 250, 110, 82, 45, - 118, 110, 187, 116, 50, 182, 236, 250, 116, 82, 45, 118, 110, 246, 229, - 116, 50, 182, 236, 250, 116, 82, 45, 118, 110, 187, 116, 50, 182, 236, - 250, 116, 45, 118, 110, 246, 229, 116, 45, 182, 236, 250, 116, 82, 45, - 118, 116, 246, 229, 116, 45, 182, 236, 250, 116, 82, 45, 118, 116, 187, - 116, 45, 182, 236, 250, 110, 82, 45, 118, 116, 246, 229, 116, 45, 182, - 236, 250, 110, 82, 45, 118, 116, 187, 116, 45, 182, 236, 250, 110, 45, - 118, 116, 246, 229, 116, 45, 182, 236, 250, 110, 82, 45, 118, 116, 82, - 187, 116, 45, 182, 236, 250, 110, 246, 230, 118, 110, 82, 187, 116, 45, - 182, 236, 250, 110, 45, 118, 110, 82, 187, 116, 45, 182, 236, 250, 110, - 246, 230, 118, 116, 82, 187, 116, 45, 182, 236, 250, 110, 45, 118, 116, - 82, 187, 116, 45, 182, 236, 250, 110, 246, 230, 118, 116, 187, 116, 50, - 182, 236, 250, 116, 246, 230, 118, 116, 82, 187, 116, 50, 182, 236, 250, - 116, 45, 118, 116, 82, 187, 116, 50, 182, 236, 250, 116, 246, 230, 118, - 110, 82, 187, 116, 50, 182, 236, 250, 116, 45, 118, 110, 82, 187, 116, - 50, 182, 236, 250, 116, 246, 230, 118, 110, 187, 116, 50, 182, 236, 250, - 116, 82, 45, 118, 110, 82, 187, 116, 24, 50, 24, 110, 197, 234, 115, 208, - 16, 248, 81, 45, 24, 110, 24, 50, 197, 234, 115, 208, 16, 248, 81, 116, - 24, 45, 24, 110, 197, 234, 115, 208, 16, 248, 81, 45, 24, 116, 24, 50, - 197, 234, 115, 208, 16, 248, 81, 45, 197, 234, 91, 208, 18, 248, 81, 116, - 197, 234, 91, 208, 18, 248, 81, 50, 197, 234, 91, 208, 18, 248, 81, 110, - 197, 234, 91, 208, 18, 248, 81, 81, 91, 234, 117, 248, 79, 81, 91, 234, - 117, 248, 78, 81, 91, 234, 117, 248, 77, 81, 91, 234, 117, 248, 76, 81, - 91, 234, 117, 248, 75, 81, 91, 234, 117, 248, 74, 228, 209, 91, 234, 117, - 248, 79, 228, 209, 91, 234, 117, 248, 78, 228, 209, 91, 234, 117, 248, - 77, 228, 209, 91, 234, 117, 248, 76, 228, 209, 91, 234, 117, 248, 75, - 228, 209, 91, 234, 117, 248, 74, 45, 24, 110, 91, 234, 117, 248, 81, 45, - 24, 116, 91, 234, 117, 248, 81, 50, 24, 116, 91, 234, 117, 248, 81, 50, - 24, 110, 91, 234, 117, 248, 81, 116, 24, 110, 91, 234, 117, 248, 81, 228, - 209, 91, 234, 117, 248, 80, 116, 91, 208, 18, 248, 81, 116, 115, 234, - 115, 248, 81, 116, 232, 185, 234, 115, 248, 81, 116, 115, 208, 16, 248, - 81, 116, 203, 242, 234, 115, 248, 81, 50, 91, 208, 18, 248, 81, 50, 115, - 234, 115, 248, 81, 50, 232, 185, 234, 115, 248, 81, 50, 115, 208, 16, - 248, 81, 50, 203, 242, 234, 115, 248, 81, 45, 134, 216, 194, 203, 148, - 50, 134, 216, 194, 203, 148, 116, 134, 216, 194, 203, 148, 110, 134, 216, - 194, 203, 148, 223, 67, 216, 194, 203, 148, 116, 134, 182, 24, 110, 134, - 223, 67, 216, 194, 203, 148, 116, 134, 223, 67, 216, 194, 203, 149, 24, - 110, 134, 248, 81, 45, 134, 223, 67, 216, 194, 203, 149, 24, 50, 134, - 248, 81, 243, 76, 248, 60, 232, 220, 223, 67, 243, 76, 248, 60, 232, 220, - 88, 228, 209, 232, 220, 116, 45, 118, 110, 50, 232, 220, 116, 50, 118, - 110, 45, 232, 220, 116, 24, 110, 197, 234, 134, 248, 81, 45, 24, 50, 197, - 234, 134, 248, 81, 116, 45, 197, 234, 216, 194, 203, 148, 116, 50, 197, - 234, 216, 194, 203, 148, 110, 50, 197, 234, 216, 194, 203, 148, 110, 45, - 197, 234, 216, 194, 203, 148, 111, 122, 155, 236, 250, 116, 246, 230, - 118, 82, 219, 200, 111, 122, 155, 236, 250, 116, 246, 230, 118, 82, 187, - 111, 122, 155, 236, 250, 82, 45, 118, 110, 246, 229, 111, 122, 155, 236, - 250, 82, 50, 118, 110, 246, 229, 111, 122, 155, 236, 250, 116, 246, 230, - 118, 82, 45, 118, 110, 246, 229, 111, 122, 155, 236, 250, 116, 246, 230, - 118, 82, 50, 118, 110, 246, 229, 111, 122, 155, 236, 250, 82, 45, 118, - 110, 246, 230, 118, 82, 187, 111, 122, 155, 236, 250, 82, 45, 118, 116, - 246, 230, 118, 82, 187, 111, 122, 155, 236, 250, 116, 246, 230, 118, 82, - 45, 24, 82, 50, 118, 110, 246, 229, 111, 122, 155, 236, 250, 116, 246, - 230, 118, 82, 50, 24, 82, 45, 118, 110, 246, 229, 111, 122, 155, 236, - 250, 116, 246, 230, 118, 82, 50, 118, 110, 246, 230, 118, 82, 219, 200, - 111, 122, 155, 236, 250, 116, 246, 230, 118, 82, 45, 118, 110, 246, 230, - 118, 82, 187, 111, 122, 155, 236, 250, 82, 45, 118, 116, 246, 230, 118, - 82, 50, 118, 110, 246, 229, 111, 122, 155, 236, 250, 82, 50, 118, 116, - 246, 230, 118, 82, 45, 118, 110, 246, 229, 111, 122, 155, 236, 250, 236, - 243, 111, 122, 155, 228, 209, 4, 81, 105, 250, 184, 209, 52, 223, 67, - 243, 78, 77, 45, 134, 206, 37, 217, 70, 50, 134, 206, 37, 217, 70, 223, - 67, 235, 75, 63, 4, 198, 131, 219, 190, 117, 63, 24, 116, 24, 110, 91, - 234, 117, 248, 81, 96, 63, 24, 116, 24, 110, 91, 234, 117, 248, 81, 235, - 75, 63, 24, 50, 91, 234, 117, 248, 81, 196, 62, 63, 24, 50, 91, 234, 117, - 248, 81, 45, 134, 232, 131, 50, 134, 232, 131, 195, 13, 35, 238, 170, 50, - 211, 66, 112, 236, 96, 214, 92, 236, 250, 238, 170, 214, 92, 236, 250, - 82, 50, 118, 110, 246, 229, 214, 92, 236, 250, 236, 243, 64, 88, 205, - 150, 4, 206, 108, 238, 209, 45, 198, 252, 64, 50, 209, 51, 223, 120, 82, - 198, 252, 64, 50, 209, 51, 223, 120, 50, 198, 252, 64, 50, 209, 51, 223, - 120, 214, 92, 112, 208, 8, 77, 201, 70, 232, 227, 201, 70, 232, 228, 4, - 250, 197, 207, 141, 201, 70, 232, 228, 219, 207, 219, 200, 201, 70, 232, - 228, 219, 207, 187, 201, 70, 232, 228, 4, 235, 62, 64, 196, 72, 243, 52, - 205, 37, 17, 191, 77, 205, 37, 17, 108, 205, 37, 17, 109, 205, 37, 17, - 139, 205, 37, 17, 137, 205, 37, 17, 153, 205, 37, 17, 173, 205, 37, 17, - 181, 205, 37, 17, 176, 205, 37, 17, 184, 12, 15, 227, 240, 12, 15, 227, - 239, 12, 15, 227, 238, 12, 15, 227, 237, 12, 15, 227, 236, 12, 15, 227, - 235, 12, 15, 227, 234, 12, 15, 227, 233, 12, 15, 227, 232, 12, 15, 227, - 231, 12, 15, 227, 230, 12, 15, 227, 229, 12, 15, 227, 228, 12, 15, 227, - 227, 12, 15, 227, 226, 12, 15, 227, 225, 12, 15, 227, 224, 12, 15, 227, - 223, 12, 15, 227, 222, 12, 15, 227, 221, 12, 15, 227, 220, 12, 15, 227, - 219, 12, 15, 227, 218, 12, 15, 227, 217, 12, 15, 227, 216, 12, 15, 227, - 215, 12, 15, 227, 214, 12, 15, 227, 213, 12, 15, 227, 212, 12, 15, 227, - 211, 12, 15, 227, 210, 12, 15, 227, 209, 12, 15, 227, 208, 12, 15, 227, - 207, 12, 15, 227, 206, 12, 15, 227, 205, 12, 15, 227, 204, 12, 15, 227, - 203, 12, 15, 227, 202, 12, 15, 227, 201, 12, 15, 227, 200, 12, 15, 227, - 199, 12, 15, 227, 198, 12, 15, 227, 197, 12, 15, 227, 196, 12, 15, 227, - 195, 12, 15, 227, 194, 12, 15, 227, 193, 12, 15, 227, 192, 12, 15, 227, - 191, 12, 15, 227, 190, 12, 15, 227, 189, 12, 15, 227, 188, 12, 15, 227, - 187, 12, 15, 227, 186, 12, 15, 227, 185, 12, 15, 227, 184, 12, 15, 227, - 183, 12, 15, 227, 182, 12, 15, 227, 181, 12, 15, 227, 180, 12, 15, 227, - 179, 12, 15, 227, 178, 12, 15, 227, 177, 12, 15, 227, 176, 12, 15, 227, - 175, 12, 15, 227, 174, 12, 15, 227, 173, 12, 15, 227, 172, 12, 15, 227, - 171, 12, 15, 227, 170, 12, 15, 227, 169, 12, 15, 227, 168, 12, 15, 227, - 167, 12, 15, 227, 166, 12, 15, 227, 165, 12, 15, 227, 164, 12, 15, 227, - 163, 12, 15, 227, 162, 12, 15, 227, 161, 12, 15, 227, 160, 12, 15, 227, - 159, 12, 15, 227, 158, 12, 15, 227, 157, 12, 15, 227, 156, 12, 15, 227, - 155, 12, 15, 227, 154, 12, 15, 227, 153, 12, 15, 227, 152, 12, 15, 227, - 151, 12, 15, 227, 150, 12, 15, 227, 149, 12, 15, 227, 148, 12, 15, 227, - 147, 12, 15, 227, 146, 12, 15, 227, 145, 12, 15, 227, 144, 12, 15, 227, - 143, 12, 15, 227, 142, 12, 15, 227, 141, 12, 15, 227, 140, 12, 15, 227, - 139, 12, 15, 227, 138, 12, 15, 227, 137, 12, 15, 227, 136, 12, 15, 227, - 135, 12, 15, 227, 134, 12, 15, 227, 133, 12, 15, 227, 132, 12, 15, 227, - 131, 12, 15, 227, 130, 12, 15, 227, 129, 12, 15, 227, 128, 12, 15, 227, - 127, 12, 15, 227, 126, 12, 15, 227, 125, 12, 15, 227, 124, 12, 15, 227, - 123, 12, 15, 227, 122, 12, 15, 227, 121, 12, 15, 227, 120, 12, 15, 227, - 119, 12, 15, 227, 118, 12, 15, 227, 117, 12, 15, 227, 116, 12, 15, 227, - 115, 12, 15, 227, 114, 12, 15, 227, 113, 12, 15, 227, 112, 12, 15, 227, - 111, 12, 15, 227, 110, 12, 15, 227, 109, 12, 15, 227, 108, 12, 15, 227, - 107, 12, 15, 227, 106, 12, 15, 227, 105, 12, 15, 227, 104, 12, 15, 227, - 103, 12, 15, 227, 102, 12, 15, 227, 101, 12, 15, 227, 100, 12, 15, 227, - 99, 12, 15, 227, 98, 12, 15, 227, 97, 12, 15, 227, 96, 12, 15, 227, 95, - 12, 15, 227, 94, 12, 15, 227, 93, 12, 15, 227, 92, 12, 15, 227, 91, 12, - 15, 227, 90, 12, 15, 227, 89, 12, 15, 227, 88, 12, 15, 227, 87, 12, 15, - 227, 86, 12, 15, 227, 85, 12, 15, 227, 84, 12, 15, 227, 83, 12, 15, 227, - 82, 12, 15, 227, 81, 12, 15, 227, 80, 12, 15, 227, 79, 12, 15, 227, 78, - 12, 15, 227, 77, 12, 15, 227, 76, 12, 15, 227, 75, 12, 15, 227, 74, 12, - 15, 227, 73, 12, 15, 227, 72, 12, 15, 227, 71, 12, 15, 227, 70, 12, 15, - 227, 69, 12, 15, 227, 68, 12, 15, 227, 67, 12, 15, 227, 66, 12, 15, 227, - 65, 12, 15, 227, 64, 12, 15, 227, 63, 12, 15, 227, 62, 12, 15, 227, 61, - 12, 15, 227, 60, 12, 15, 227, 59, 12, 15, 227, 58, 12, 15, 227, 57, 12, - 15, 227, 56, 12, 15, 227, 55, 12, 15, 227, 54, 12, 15, 227, 53, 12, 15, - 227, 52, 12, 15, 227, 51, 12, 15, 227, 50, 12, 15, 227, 49, 12, 15, 227, - 48, 12, 15, 227, 47, 12, 15, 227, 46, 12, 15, 227, 45, 12, 15, 227, 44, - 12, 15, 227, 43, 12, 15, 227, 42, 12, 15, 227, 41, 12, 15, 227, 40, 12, - 15, 227, 39, 12, 15, 227, 38, 12, 15, 227, 37, 12, 15, 227, 36, 12, 15, - 227, 35, 12, 15, 227, 34, 12, 15, 227, 33, 12, 15, 227, 32, 12, 15, 227, - 31, 12, 15, 227, 30, 12, 15, 227, 29, 12, 15, 227, 28, 12, 15, 227, 27, - 12, 15, 227, 26, 12, 15, 227, 25, 12, 15, 227, 24, 12, 15, 227, 23, 12, - 15, 227, 22, 12, 15, 227, 21, 12, 15, 227, 20, 12, 15, 227, 19, 12, 15, - 227, 18, 12, 15, 227, 17, 12, 15, 227, 16, 12, 15, 227, 15, 12, 15, 227, - 14, 12, 15, 227, 13, 12, 15, 227, 12, 12, 15, 227, 11, 12, 15, 227, 10, - 12, 15, 227, 9, 12, 15, 227, 8, 12, 15, 227, 7, 12, 15, 227, 6, 12, 15, - 227, 5, 12, 15, 227, 4, 12, 15, 227, 3, 12, 15, 227, 2, 12, 15, 227, 1, - 12, 15, 227, 0, 12, 15, 226, 255, 12, 15, 226, 254, 12, 15, 226, 253, 12, - 15, 226, 252, 12, 15, 226, 251, 12, 15, 226, 250, 12, 15, 226, 249, 12, - 15, 226, 248, 12, 15, 226, 247, 12, 15, 226, 246, 12, 15, 226, 245, 12, - 15, 226, 244, 12, 15, 226, 243, 12, 15, 226, 242, 12, 15, 226, 241, 12, - 15, 226, 240, 12, 15, 226, 239, 12, 15, 226, 238, 12, 15, 226, 237, 12, - 15, 226, 236, 12, 15, 226, 235, 12, 15, 226, 234, 12, 15, 226, 233, 12, - 15, 226, 232, 12, 15, 226, 231, 12, 15, 226, 230, 12, 15, 226, 229, 12, - 15, 226, 228, 12, 15, 226, 227, 12, 15, 226, 226, 12, 15, 226, 225, 12, - 15, 226, 224, 12, 15, 226, 223, 12, 15, 226, 222, 12, 15, 226, 221, 12, - 15, 226, 220, 12, 15, 226, 219, 12, 15, 226, 218, 12, 15, 226, 217, 12, - 15, 226, 216, 12, 15, 226, 215, 12, 15, 226, 214, 12, 15, 226, 213, 12, - 15, 226, 212, 12, 15, 226, 211, 12, 15, 226, 210, 12, 15, 226, 209, 12, - 15, 226, 208, 12, 15, 226, 207, 12, 15, 226, 206, 12, 15, 226, 205, 12, - 15, 226, 204, 12, 15, 226, 203, 12, 15, 226, 202, 12, 15, 226, 201, 12, - 15, 226, 200, 12, 15, 226, 199, 12, 15, 226, 198, 12, 15, 226, 197, 12, - 15, 226, 196, 12, 15, 226, 195, 12, 15, 226, 194, 12, 15, 226, 193, 12, - 15, 226, 192, 12, 15, 226, 191, 12, 15, 226, 190, 12, 15, 226, 189, 12, - 15, 226, 188, 12, 15, 226, 187, 12, 15, 226, 186, 12, 15, 226, 185, 12, - 15, 226, 184, 12, 15, 226, 183, 12, 15, 226, 182, 12, 15, 226, 181, 12, - 15, 226, 180, 12, 15, 226, 179, 12, 15, 226, 178, 12, 15, 226, 177, 12, - 15, 226, 176, 12, 15, 226, 175, 12, 15, 226, 174, 12, 15, 226, 173, 12, - 15, 226, 172, 12, 15, 226, 171, 12, 15, 226, 170, 12, 15, 226, 169, 12, - 15, 226, 168, 12, 15, 226, 167, 12, 15, 226, 166, 12, 15, 226, 165, 12, - 15, 226, 164, 12, 15, 226, 163, 12, 15, 226, 162, 12, 15, 226, 161, 12, - 15, 226, 160, 12, 15, 226, 159, 12, 15, 226, 158, 12, 15, 226, 157, 12, - 15, 226, 156, 12, 15, 226, 155, 12, 15, 226, 154, 12, 15, 226, 153, 12, - 15, 226, 152, 12, 15, 226, 151, 12, 15, 226, 150, 12, 15, 226, 149, 12, - 15, 226, 148, 12, 15, 226, 147, 12, 15, 226, 146, 12, 15, 226, 145, 12, - 15, 226, 144, 12, 15, 226, 143, 12, 15, 226, 142, 12, 15, 226, 141, 12, - 15, 226, 140, 12, 15, 226, 139, 12, 15, 226, 138, 12, 15, 226, 137, 12, - 15, 226, 136, 12, 15, 226, 135, 12, 15, 226, 134, 12, 15, 226, 133, 12, - 15, 226, 132, 12, 15, 226, 131, 12, 15, 226, 130, 12, 15, 226, 129, 12, - 15, 226, 128, 12, 15, 226, 127, 12, 15, 226, 126, 12, 15, 226, 125, 12, - 15, 226, 124, 12, 15, 226, 123, 12, 15, 226, 122, 12, 15, 226, 121, 12, - 15, 226, 120, 12, 15, 226, 119, 12, 15, 226, 118, 12, 15, 226, 117, 12, - 15, 226, 116, 12, 15, 226, 115, 12, 15, 226, 114, 12, 15, 226, 113, 12, - 15, 226, 112, 12, 15, 226, 111, 12, 15, 226, 110, 12, 15, 226, 109, 12, - 15, 226, 108, 12, 15, 226, 107, 12, 15, 226, 106, 12, 15, 226, 105, 12, - 15, 226, 104, 12, 15, 226, 103, 12, 15, 226, 102, 12, 15, 226, 101, 12, - 15, 226, 100, 12, 15, 226, 99, 12, 15, 226, 98, 12, 15, 226, 97, 12, 15, - 226, 96, 12, 15, 226, 95, 12, 15, 226, 94, 12, 15, 226, 93, 12, 15, 226, - 92, 12, 15, 226, 91, 12, 15, 226, 90, 12, 15, 226, 89, 12, 15, 226, 88, - 12, 15, 226, 87, 12, 15, 226, 86, 12, 15, 226, 85, 12, 15, 226, 84, 12, - 15, 226, 83, 12, 15, 226, 82, 12, 15, 226, 81, 12, 15, 226, 80, 12, 15, - 226, 79, 12, 15, 226, 78, 12, 15, 226, 77, 12, 15, 226, 76, 12, 15, 226, - 75, 12, 15, 226, 74, 12, 15, 226, 73, 12, 15, 226, 72, 12, 15, 226, 71, - 12, 15, 226, 70, 12, 15, 226, 69, 12, 15, 226, 68, 12, 15, 226, 67, 12, - 15, 226, 66, 12, 15, 226, 65, 12, 15, 226, 64, 12, 15, 226, 63, 12, 15, - 226, 62, 12, 15, 226, 61, 12, 15, 226, 60, 12, 15, 226, 59, 12, 15, 226, - 58, 12, 15, 226, 57, 12, 15, 226, 56, 12, 15, 226, 55, 12, 15, 226, 54, - 12, 15, 226, 53, 12, 15, 226, 52, 12, 15, 226, 51, 12, 15, 226, 50, 12, - 15, 226, 49, 12, 15, 226, 48, 12, 15, 226, 47, 12, 15, 226, 46, 12, 15, - 226, 45, 12, 15, 226, 44, 12, 15, 226, 43, 12, 15, 226, 42, 12, 15, 226, - 41, 12, 15, 226, 40, 12, 15, 226, 39, 12, 15, 226, 38, 12, 15, 226, 37, - 12, 15, 226, 36, 12, 15, 226, 35, 12, 15, 226, 34, 12, 15, 226, 33, 12, - 15, 226, 32, 12, 15, 226, 31, 12, 15, 226, 30, 12, 15, 226, 29, 12, 15, - 226, 28, 12, 15, 226, 27, 12, 15, 226, 26, 12, 15, 226, 25, 12, 15, 226, - 24, 12, 15, 226, 23, 12, 15, 226, 22, 12, 15, 226, 21, 12, 15, 226, 20, - 12, 15, 226, 19, 12, 15, 226, 18, 12, 15, 226, 17, 12, 15, 226, 16, 12, - 15, 226, 15, 12, 15, 226, 14, 12, 15, 226, 13, 12, 15, 226, 12, 12, 15, - 226, 11, 12, 15, 226, 10, 12, 15, 226, 9, 12, 15, 226, 8, 12, 15, 226, 7, - 12, 15, 226, 6, 12, 15, 226, 5, 12, 15, 226, 4, 12, 15, 226, 3, 12, 15, - 226, 2, 12, 15, 226, 1, 12, 15, 226, 0, 12, 15, 225, 255, 12, 15, 225, - 254, 12, 15, 225, 253, 12, 15, 225, 252, 12, 15, 225, 251, 12, 15, 225, - 250, 12, 15, 225, 249, 12, 15, 225, 248, 12, 15, 225, 247, 12, 15, 225, - 246, 12, 15, 225, 245, 12, 15, 225, 244, 12, 15, 225, 243, 12, 15, 225, - 242, 12, 15, 225, 241, 12, 15, 225, 240, 12, 15, 225, 239, 12, 15, 225, - 238, 12, 15, 225, 237, 12, 15, 225, 236, 12, 15, 225, 235, 12, 15, 225, - 234, 12, 15, 225, 233, 12, 15, 225, 232, 12, 15, 225, 231, 12, 15, 225, - 230, 12, 15, 225, 229, 12, 15, 225, 228, 12, 15, 225, 227, 12, 15, 225, - 226, 12, 15, 225, 225, 12, 15, 225, 224, 12, 15, 225, 223, 12, 15, 225, - 222, 12, 15, 225, 221, 12, 15, 225, 220, 12, 15, 225, 219, 12, 15, 225, - 218, 12, 15, 225, 217, 12, 15, 225, 216, 12, 15, 225, 215, 12, 15, 225, - 214, 12, 15, 225, 213, 12, 15, 225, 212, 12, 15, 225, 211, 219, 252, 199, - 218, 199, 219, 201, 242, 199, 219, 233, 175, 77, 199, 219, 207, 247, 77, - 199, 219, 31, 57, 199, 219, 236, 110, 57, 199, 219, 210, 4, 57, 199, 219, - 251, 86, 199, 219, 250, 255, 199, 219, 45, 210, 103, 199, 219, 50, 210, - 103, 199, 219, 250, 143, 199, 219, 107, 57, 199, 219, 242, 26, 199, 219, - 228, 57, 199, 219, 232, 42, 201, 58, 199, 219, 202, 18, 199, 219, 17, - 191, 77, 199, 219, 17, 108, 199, 219, 17, 109, 199, 219, 17, 139, 199, - 219, 17, 137, 199, 219, 17, 153, 199, 219, 17, 173, 199, 219, 17, 181, - 199, 219, 17, 176, 199, 219, 17, 184, 199, 219, 242, 35, 199, 219, 204, - 20, 199, 219, 219, 156, 57, 199, 219, 234, 1, 57, 199, 219, 230, 170, 57, - 199, 219, 208, 8, 77, 199, 219, 242, 24, 250, 132, 199, 219, 8, 6, 1, 65, - 199, 219, 8, 6, 1, 250, 70, 199, 219, 8, 6, 1, 247, 145, 199, 219, 8, 6, - 1, 238, 80, 199, 219, 8, 6, 1, 73, 199, 219, 8, 6, 1, 233, 134, 199, 219, - 8, 6, 1, 232, 14, 199, 219, 8, 6, 1, 230, 83, 199, 219, 8, 6, 1, 70, 199, - 219, 8, 6, 1, 223, 7, 199, 219, 8, 6, 1, 222, 125, 199, 219, 8, 6, 1, - 170, 199, 219, 8, 6, 1, 218, 147, 199, 219, 8, 6, 1, 215, 47, 199, 219, - 8, 6, 1, 74, 199, 219, 8, 6, 1, 210, 226, 199, 219, 8, 6, 1, 208, 97, - 199, 219, 8, 6, 1, 148, 199, 219, 8, 6, 1, 206, 3, 199, 219, 8, 6, 1, - 200, 39, 199, 219, 8, 6, 1, 69, 199, 219, 8, 6, 1, 196, 8, 199, 219, 8, - 6, 1, 193, 221, 199, 219, 8, 6, 1, 192, 235, 199, 219, 8, 6, 1, 192, 159, - 199, 219, 8, 6, 1, 191, 166, 199, 219, 45, 51, 248, 5, 199, 219, 207, 14, - 202, 18, 199, 219, 50, 51, 248, 5, 199, 219, 242, 210, 252, 8, 199, 219, - 131, 219, 88, 199, 219, 230, 177, 252, 8, 199, 219, 8, 2, 1, 65, 199, - 219, 8, 2, 1, 250, 70, 199, 219, 8, 2, 1, 247, 145, 199, 219, 8, 2, 1, - 238, 80, 199, 219, 8, 2, 1, 73, 199, 219, 8, 2, 1, 233, 134, 199, 219, 8, - 2, 1, 232, 14, 199, 219, 8, 2, 1, 230, 83, 199, 219, 8, 2, 1, 70, 199, - 219, 8, 2, 1, 223, 7, 199, 219, 8, 2, 1, 222, 125, 199, 219, 8, 2, 1, - 170, 199, 219, 8, 2, 1, 218, 147, 199, 219, 8, 2, 1, 215, 47, 199, 219, - 8, 2, 1, 74, 199, 219, 8, 2, 1, 210, 226, 199, 219, 8, 2, 1, 208, 97, - 199, 219, 8, 2, 1, 148, 199, 219, 8, 2, 1, 206, 3, 199, 219, 8, 2, 1, - 200, 39, 199, 219, 8, 2, 1, 69, 199, 219, 8, 2, 1, 196, 8, 199, 219, 8, - 2, 1, 193, 221, 199, 219, 8, 2, 1, 192, 235, 199, 219, 8, 2, 1, 192, 159, - 199, 219, 8, 2, 1, 191, 166, 199, 219, 45, 238, 124, 248, 5, 199, 219, - 81, 219, 88, 199, 219, 50, 238, 124, 248, 5, 199, 219, 198, 147, 247, 79, - 199, 218, 66, 204, 206, 66, 204, 195, 66, 204, 184, 66, 204, 172, 66, - 204, 161, 66, 204, 150, 66, 204, 139, 66, 204, 128, 66, 204, 117, 66, - 204, 109, 66, 204, 108, 66, 204, 107, 66, 204, 106, 66, 204, 104, 66, - 204, 103, 66, 204, 102, 66, 204, 101, 66, 204, 100, 66, 204, 99, 66, 204, - 98, 66, 204, 97, 66, 204, 96, 66, 204, 95, 66, 204, 93, 66, 204, 92, 66, - 204, 91, 66, 204, 90, 66, 204, 89, 66, 204, 88, 66, 204, 87, 66, 204, 86, - 66, 204, 85, 66, 204, 84, 66, 204, 82, 66, 204, 81, 66, 204, 80, 66, 204, - 79, 66, 204, 78, 66, 204, 77, 66, 204, 76, 66, 204, 75, 66, 204, 74, 66, - 204, 73, 66, 204, 71, 66, 204, 70, 66, 204, 69, 66, 204, 68, 66, 204, 67, - 66, 204, 66, 66, 204, 65, 66, 204, 64, 66, 204, 63, 66, 204, 62, 66, 204, - 60, 66, 204, 59, 66, 204, 58, 66, 204, 57, 66, 204, 56, 66, 204, 55, 66, - 204, 54, 66, 204, 53, 66, 204, 52, 66, 204, 51, 66, 204, 49, 66, 204, 48, - 66, 204, 47, 66, 204, 46, 66, 204, 45, 66, 204, 44, 66, 204, 43, 66, 204, - 42, 66, 204, 41, 66, 204, 40, 66, 204, 38, 66, 204, 37, 66, 204, 36, 66, - 204, 35, 66, 204, 34, 66, 204, 33, 66, 204, 32, 66, 204, 31, 66, 204, 30, - 66, 204, 29, 66, 205, 26, 66, 205, 25, 66, 205, 24, 66, 205, 23, 66, 205, - 22, 66, 205, 21, 66, 205, 20, 66, 205, 19, 66, 205, 18, 66, 205, 17, 66, - 205, 15, 66, 205, 14, 66, 205, 13, 66, 205, 12, 66, 205, 11, 66, 205, 10, - 66, 205, 9, 66, 205, 8, 66, 205, 7, 66, 205, 6, 66, 205, 4, 66, 205, 3, - 66, 205, 2, 66, 205, 1, 66, 205, 0, 66, 204, 255, 66, 204, 254, 66, 204, - 253, 66, 204, 252, 66, 204, 251, 66, 204, 249, 66, 204, 248, 66, 204, - 247, 66, 204, 246, 66, 204, 245, 66, 204, 244, 66, 204, 243, 66, 204, - 242, 66, 204, 241, 66, 204, 240, 66, 204, 238, 66, 204, 237, 66, 204, - 236, 66, 204, 235, 66, 204, 234, 66, 204, 233, 66, 204, 232, 66, 204, - 231, 66, 204, 230, 66, 204, 229, 66, 204, 227, 66, 204, 226, 66, 204, - 225, 66, 204, 224, 66, 204, 223, 66, 204, 222, 66, 204, 221, 66, 204, - 220, 66, 204, 219, 66, 204, 218, 66, 204, 216, 66, 204, 215, 66, 204, - 214, 66, 204, 213, 66, 204, 212, 66, 204, 211, 66, 204, 210, 66, 204, - 209, 66, 204, 208, 66, 204, 207, 66, 204, 205, 66, 204, 204, 66, 204, - 203, 66, 204, 202, 66, 204, 201, 66, 204, 200, 66, 204, 199, 66, 204, - 198, 66, 204, 197, 66, 204, 196, 66, 204, 194, 66, 204, 193, 66, 204, - 192, 66, 204, 191, 66, 204, 190, 66, 204, 189, 66, 204, 188, 66, 204, - 187, 66, 204, 186, 66, 204, 185, 66, 204, 183, 66, 204, 182, 66, 204, - 181, 66, 204, 180, 66, 204, 179, 66, 204, 178, 66, 204, 177, 66, 204, - 176, 66, 204, 175, 66, 204, 174, 66, 204, 171, 66, 204, 170, 66, 204, - 169, 66, 204, 168, 66, 204, 167, 66, 204, 166, 66, 204, 165, 66, 204, - 164, 66, 204, 163, 66, 204, 162, 66, 204, 160, 66, 204, 159, 66, 204, - 158, 66, 204, 157, 66, 204, 156, 66, 204, 155, 66, 204, 154, 66, 204, - 153, 66, 204, 152, 66, 204, 151, 66, 204, 149, 66, 204, 148, 66, 204, - 147, 66, 204, 146, 66, 204, 145, 66, 204, 144, 66, 204, 143, 66, 204, - 142, 66, 204, 141, 66, 204, 140, 66, 204, 138, 66, 204, 137, 66, 204, - 136, 66, 204, 135, 66, 204, 134, 66, 204, 133, 66, 204, 132, 66, 204, - 131, 66, 204, 130, 66, 204, 129, 66, 204, 127, 66, 204, 126, 66, 204, - 125, 66, 204, 124, 66, 204, 123, 66, 204, 122, 66, 204, 121, 66, 204, - 120, 66, 204, 119, 66, 204, 118, 66, 204, 116, 66, 204, 115, 66, 204, - 114, 66, 204, 113, 66, 204, 112, 66, 204, 111, 66, 204, 110, 212, 125, - 212, 127, 201, 93, 80, 229, 200, 202, 22, 201, 93, 80, 199, 48, 201, 1, - 234, 53, 80, 199, 48, 233, 203, 234, 53, 80, 198, 7, 234, 15, 234, 39, - 234, 40, 251, 255, 252, 0, 251, 138, 248, 188, 249, 90, 247, 224, 246, - 192, 199, 225, 228, 209, 199, 225, 228, 134, 199, 231, 219, 89, 233, 9, - 214, 66, 219, 88, 234, 53, 80, 219, 88, 219, 137, 213, 92, 234, 18, 219, - 89, 199, 225, 81, 199, 225, 193, 248, 232, 107, 233, 9, 232, 242, 247, - 40, 207, 17, 238, 189, 203, 72, 211, 4, 219, 9, 108, 202, 41, 203, 72, - 223, 134, 219, 9, 191, 77, 202, 217, 237, 165, 219, 79, 233, 228, 236, - 140, 237, 30, 238, 231, 108, 237, 154, 237, 30, 238, 231, 109, 237, 153, - 237, 30, 238, 231, 139, 237, 152, 237, 30, 238, 231, 137, 237, 151, 214, - 92, 251, 255, 214, 219, 200, 65, 223, 199, 200, 69, 234, 53, 80, 198, 8, - 248, 81, 233, 210, 247, 78, 247, 80, 234, 53, 80, 216, 193, 234, 16, 200, - 221, 200, 240, 233, 228, 233, 229, 223, 109, 204, 6, 137, 232, 222, 204, - 5, 232, 52, 223, 109, 204, 6, 139, 230, 154, 204, 5, 230, 151, 223, 109, - 204, 6, 109, 207, 93, 204, 5, 206, 69, 223, 109, 204, 6, 108, 196, 87, - 204, 5, 196, 41, 201, 245, 237, 71, 237, 73, 210, 198, 246, 191, 210, - 200, 136, 211, 146, 208, 213, 228, 212, 247, 250, 209, 248, 229, 160, - 248, 10, 213, 31, 247, 250, 229, 160, 214, 177, 223, 120, 223, 122, 214, - 59, 219, 88, 214, 90, 201, 93, 80, 205, 31, 250, 214, 201, 170, 234, 53, - 80, 205, 31, 250, 214, 233, 231, 246, 192, 199, 226, 203, 247, 228, 209, - 199, 226, 203, 247, 228, 131, 246, 192, 199, 226, 4, 222, 137, 228, 209, - 199, 226, 4, 222, 137, 228, 132, 219, 89, 199, 226, 203, 247, 81, 199, - 226, 203, 247, 193, 247, 210, 95, 219, 89, 232, 94, 210, 95, 219, 89, - 235, 79, 209, 86, 210, 95, 219, 89, 249, 89, 210, 95, 219, 89, 196, 73, - 209, 80, 207, 14, 219, 89, 233, 9, 207, 14, 223, 120, 206, 252, 202, 165, - 203, 72, 109, 202, 162, 201, 172, 202, 165, 203, 72, 139, 202, 161, 201, - 171, 237, 30, 238, 231, 201, 25, 237, 149, 208, 198, 196, 40, 108, 208, - 198, 196, 38, 208, 157, 208, 198, 196, 40, 109, 208, 198, 196, 37, 208, - 156, 203, 248, 198, 6, 201, 90, 201, 8, 247, 79, 246, 191, 247, 13, 216, - 150, 193, 168, 215, 67, 201, 93, 80, 230, 139, 250, 214, 201, 93, 80, - 208, 175, 250, 214, 201, 244, 234, 53, 80, 230, 139, 250, 214, 234, 53, - 80, 208, 175, 250, 214, 234, 13, 201, 93, 80, 201, 25, 202, 4, 202, 165, - 230, 182, 246, 192, 223, 68, 203, 165, 202, 165, 246, 192, 223, 68, 205, - 80, 238, 231, 204, 2, 223, 68, 238, 149, 201, 26, 199, 75, 201, 113, 211, - 57, 200, 54, 242, 25, 211, 24, 208, 199, 216, 149, 209, 68, 250, 251, - 208, 191, 242, 25, 251, 12, 214, 165, 202, 226, 8, 6, 1, 231, 54, 8, 2, - 1, 231, 54, 246, 212, 251, 115, 200, 59, 200, 227, 242, 36, 202, 105, - 219, 200, 222, 55, 1, 219, 38, 219, 249, 1, 232, 136, 232, 127, 219, 249, - 1, 232, 136, 233, 21, 219, 249, 1, 206, 157, 219, 249, 1, 219, 19, 86, - 87, 248, 93, 203, 45, 231, 17, 216, 99, 207, 4, 30, 125, 192, 54, 30, - 125, 192, 50, 30, 125, 201, 148, 30, 125, 192, 55, 232, 29, 232, 28, 232, - 27, 215, 69, 232, 26, 190, 232, 190, 233, 190, 235, 218, 207, 206, 165, - 218, 209, 206, 167, 210, 56, 218, 206, 206, 164, 213, 62, 215, 255, 193, - 50, 218, 208, 206, 166, 232, 51, 210, 55, 193, 109, 234, 77, 232, 39, - 216, 73, 211, 94, 196, 42, 113, 216, 73, 237, 171, 113, 117, 197, 236, - 63, 4, 54, 81, 105, 96, 197, 236, 63, 4, 54, 81, 105, 11, 5, 223, 23, 77, - 79, 1, 221, 181, 219, 49, 194, 248, 194, 137, 194, 69, 194, 58, 194, 47, - 194, 36, 194, 25, 194, 14, 194, 3, 194, 247, 194, 236, 194, 225, 194, - 214, 194, 203, 194, 192, 194, 181, 208, 214, 232, 107, 39, 81, 50, 64, - 219, 163, 248, 5, 247, 150, 211, 41, 77, 248, 52, 190, 234, 10, 3, 212, - 135, 199, 79, 10, 3, 212, 135, 138, 212, 135, 247, 183, 138, 247, 182, - 216, 199, 6, 1, 230, 83, 216, 199, 6, 1, 214, 56, 216, 199, 2, 1, 230, - 83, 216, 199, 2, 1, 214, 56, 61, 1, 234, 226, 72, 37, 16, 232, 50, 202, - 101, 243, 4, 195, 161, 194, 170, 194, 159, 194, 148, 194, 136, 194, 125, - 194, 114, 194, 103, 194, 92, 194, 81, 194, 73, 194, 72, 194, 71, 194, 70, - 194, 68, 194, 67, 194, 66, 194, 65, 194, 64, 194, 63, 194, 62, 194, 61, - 194, 60, 194, 59, 194, 57, 194, 56, 194, 55, 194, 54, 194, 53, 194, 52, - 194, 51, 194, 50, 194, 49, 194, 48, 194, 46, 194, 45, 194, 44, 194, 43, - 194, 42, 194, 41, 194, 40, 194, 39, 194, 38, 194, 37, 194, 35, 194, 34, - 194, 33, 194, 32, 194, 31, 194, 30, 194, 29, 194, 28, 194, 27, 194, 26, - 194, 24, 194, 23, 194, 22, 194, 21, 194, 20, 194, 19, 194, 18, 194, 17, - 194, 16, 194, 15, 194, 13, 194, 12, 194, 11, 194, 10, 194, 9, 194, 8, - 194, 7, 194, 6, 194, 5, 194, 4, 194, 2, 194, 1, 194, 0, 193, 255, 193, - 254, 193, 253, 193, 252, 193, 251, 193, 250, 193, 249, 194, 246, 194, - 245, 194, 244, 194, 243, 194, 242, 194, 241, 194, 240, 194, 239, 194, - 238, 194, 237, 194, 235, 194, 234, 194, 233, 194, 232, 194, 231, 194, - 230, 194, 229, 194, 228, 194, 227, 194, 226, 194, 224, 194, 223, 194, - 222, 194, 221, 194, 220, 194, 219, 194, 218, 194, 217, 194, 216, 194, - 215, 194, 213, 194, 212, 194, 211, 194, 210, 194, 209, 194, 208, 194, - 207, 194, 206, 194, 205, 194, 204, 194, 202, 194, 201, 194, 200, 194, - 199, 194, 198, 194, 197, 194, 196, 194, 195, 194, 194, 194, 193, 194, - 191, 194, 190, 194, 189, 194, 188, 194, 187, 194, 186, 194, 185, 194, - 184, 194, 183, 194, 182, 194, 180, 194, 179, 194, 178, 194, 177, 194, - 176, 194, 175, 194, 174, 194, 173, 194, 172, 194, 171, 194, 169, 194, - 168, 194, 167, 194, 166, 194, 165, 194, 164, 194, 163, 194, 162, 194, - 161, 194, 160, 194, 158, 194, 157, 194, 156, 194, 155, 194, 154, 194, - 153, 194, 152, 194, 151, 194, 150, 194, 149, 194, 147, 194, 146, 194, - 145, 194, 144, 194, 143, 194, 142, 194, 141, 194, 140, 194, 139, 194, - 138, 194, 135, 194, 134, 194, 133, 194, 132, 194, 131, 194, 130, 194, - 129, 194, 128, 194, 127, 194, 126, 194, 124, 194, 123, 194, 122, 194, - 121, 194, 120, 194, 119, 194, 118, 194, 117, 194, 116, 194, 115, 194, - 113, 194, 112, 194, 111, 194, 110, 194, 109, 194, 108, 194, 107, 194, - 106, 194, 105, 194, 104, 194, 102, 194, 101, 194, 100, 194, 99, 194, 98, - 194, 97, 194, 96, 194, 95, 194, 94, 194, 93, 194, 91, 194, 90, 194, 89, - 194, 88, 194, 87, 194, 86, 194, 85, 194, 84, 194, 83, 194, 82, 194, 80, - 194, 79, 194, 78, 194, 77, 194, 76, 194, 75, 194, 74, 221, 194, 31, 57, - 221, 194, 250, 143, 221, 194, 17, 191, 77, 221, 194, 17, 108, 221, 194, - 17, 109, 221, 194, 17, 139, 221, 194, 17, 137, 221, 194, 17, 153, 221, - 194, 17, 173, 221, 194, 17, 181, 221, 194, 17, 176, 221, 194, 17, 184, 8, - 6, 1, 41, 4, 217, 126, 24, 230, 176, 8, 2, 1, 41, 4, 217, 126, 24, 230, - 176, 8, 6, 1, 228, 44, 4, 217, 126, 24, 230, 176, 8, 2, 1, 228, 44, 4, - 217, 126, 24, 230, 176, 8, 6, 1, 126, 4, 217, 126, 24, 230, 176, 8, 2, 1, - 126, 4, 217, 126, 24, 230, 176, 8, 6, 1, 234, 227, 4, 81, 219, 89, 60, 8, - 2, 1, 234, 227, 4, 81, 219, 89, 60, 8, 6, 1, 234, 227, 4, 81, 219, 89, - 248, 183, 24, 230, 176, 8, 2, 1, 234, 227, 4, 81, 219, 89, 248, 183, 24, - 230, 176, 8, 6, 1, 234, 227, 4, 81, 219, 89, 248, 183, 24, 251, 250, 8, - 2, 1, 234, 227, 4, 81, 219, 89, 248, 183, 24, 251, 250, 8, 6, 1, 186, 4, - 81, 219, 89, 60, 8, 2, 1, 186, 4, 81, 219, 89, 60, 8, 6, 1, 186, 4, 81, - 219, 89, 248, 183, 24, 230, 176, 8, 2, 1, 186, 4, 81, 219, 89, 248, 183, - 24, 230, 176, 8, 6, 1, 186, 4, 81, 219, 89, 248, 183, 24, 251, 250, 8, 2, - 1, 186, 4, 81, 219, 89, 248, 183, 24, 251, 250, 8, 6, 1, 206, 4, 4, 81, - 219, 89, 60, 8, 2, 1, 206, 4, 4, 81, 219, 89, 60, 8, 6, 1, 234, 227, 4, - 242, 210, 24, 217, 125, 8, 2, 1, 234, 227, 4, 242, 210, 24, 217, 125, 8, - 6, 1, 234, 227, 4, 242, 210, 24, 247, 44, 8, 2, 1, 234, 227, 4, 242, 210, - 24, 247, 44, 8, 2, 1, 228, 44, 4, 75, 95, 24, 251, 250, 8, 2, 1, 214, 57, - 4, 198, 148, 56, 8, 6, 1, 41, 4, 211, 127, 24, 251, 250, 8, 2, 1, 41, 4, - 211, 127, 24, 251, 250, 8, 6, 1, 41, 4, 211, 127, 24, 198, 147, 8, 2, 1, - 41, 4, 211, 127, 24, 198, 147, 8, 6, 1, 234, 227, 4, 211, 127, 24, 251, - 250, 8, 2, 1, 234, 227, 4, 211, 127, 24, 251, 250, 8, 6, 1, 234, 227, 4, - 211, 127, 24, 198, 147, 8, 2, 1, 234, 227, 4, 211, 127, 24, 198, 147, 8, - 6, 1, 234, 227, 4, 75, 95, 24, 251, 250, 8, 2, 1, 234, 227, 4, 75, 95, - 24, 251, 250, 8, 6, 1, 234, 227, 4, 75, 95, 24, 198, 147, 8, 2, 1, 234, - 227, 4, 75, 95, 24, 198, 147, 8, 2, 1, 228, 44, 4, 75, 95, 24, 230, 176, - 8, 2, 1, 228, 44, 4, 75, 95, 24, 198, 147, 8, 6, 1, 228, 44, 4, 211, 127, - 24, 251, 250, 8, 2, 1, 228, 44, 4, 211, 127, 24, 75, 95, 24, 251, 250, 8, - 6, 1, 228, 44, 4, 211, 127, 24, 198, 147, 8, 2, 1, 228, 44, 4, 211, 127, - 24, 75, 95, 24, 198, 147, 8, 6, 1, 223, 8, 4, 198, 147, 8, 2, 1, 223, 8, - 4, 75, 95, 24, 198, 147, 8, 6, 1, 220, 119, 4, 198, 147, 8, 2, 1, 220, - 119, 4, 198, 147, 8, 6, 1, 218, 148, 4, 198, 147, 8, 2, 1, 218, 148, 4, - 198, 147, 8, 6, 1, 207, 217, 4, 198, 147, 8, 2, 1, 207, 217, 4, 198, 147, - 8, 6, 1, 126, 4, 211, 127, 24, 251, 250, 8, 2, 1, 126, 4, 211, 127, 24, - 251, 250, 8, 6, 1, 126, 4, 211, 127, 24, 198, 147, 8, 2, 1, 126, 4, 211, - 127, 24, 198, 147, 8, 6, 1, 126, 4, 217, 126, 24, 251, 250, 8, 2, 1, 126, - 4, 217, 126, 24, 251, 250, 8, 6, 1, 126, 4, 217, 126, 24, 198, 147, 8, 2, - 1, 126, 4, 217, 126, 24, 198, 147, 8, 2, 1, 251, 230, 4, 230, 176, 8, 2, - 1, 211, 66, 186, 4, 230, 176, 8, 2, 1, 211, 66, 186, 4, 251, 250, 8, 2, - 1, 152, 196, 9, 4, 230, 176, 8, 2, 1, 152, 196, 9, 4, 251, 250, 8, 2, 1, - 205, 82, 4, 230, 176, 8, 2, 1, 205, 82, 4, 251, 250, 8, 2, 1, 228, 218, - 205, 82, 4, 230, 176, 8, 2, 1, 228, 218, 205, 82, 4, 251, 250, 9, 204, 2, - 99, 4, 230, 25, 95, 4, 251, 141, 9, 204, 2, 99, 4, 230, 25, 95, 4, 193, - 131, 9, 204, 2, 99, 4, 230, 25, 95, 4, 130, 217, 79, 9, 204, 2, 99, 4, - 230, 25, 95, 4, 211, 139, 9, 204, 2, 99, 4, 230, 25, 95, 4, 69, 9, 204, - 2, 99, 4, 230, 25, 95, 4, 191, 225, 9, 204, 2, 99, 4, 230, 25, 95, 4, 73, - 9, 204, 2, 99, 4, 230, 25, 95, 4, 251, 229, 9, 204, 2, 213, 12, 4, 221, - 235, 104, 204, 2, 39, 1, 208, 89, 104, 204, 2, 39, 1, 221, 169, 104, 204, - 2, 39, 1, 231, 29, 104, 204, 2, 39, 1, 191, 123, 104, 204, 2, 39, 1, 237, - 135, 104, 204, 2, 39, 1, 207, 1, 104, 204, 2, 39, 1, 233, 68, 104, 204, - 2, 39, 1, 191, 175, 248, 175, 204, 2, 39, 1, 206, 104, 248, 175, 204, 2, - 39, 1, 207, 1, 248, 175, 204, 2, 39, 1, 191, 175, 230, 111, 204, 2, 39, - 1, 219, 49, 230, 111, 204, 2, 39, 1, 203, 160, 230, 111, 204, 2, 39, 1, - 221, 169, 230, 111, 204, 2, 39, 1, 231, 29, 230, 111, 204, 2, 39, 1, 191, - 123, 230, 111, 204, 2, 39, 1, 233, 68, 211, 35, 204, 2, 39, 1, 206, 104, - 211, 35, 204, 2, 39, 1, 207, 1, 248, 175, 1, 221, 163, 44, 119, 222, 125, - 44, 119, 214, 56, 44, 119, 247, 145, 44, 119, 212, 90, 44, 119, 197, 131, - 44, 119, 213, 67, 44, 119, 200, 39, 44, 119, 215, 47, 44, 119, 210, 226, - 44, 119, 218, 147, 44, 119, 192, 159, 44, 119, 148, 44, 119, 170, 44, - 119, 196, 8, 44, 119, 219, 39, 44, 119, 219, 50, 44, 119, 206, 105, 44, - 119, 213, 49, 44, 119, 223, 7, 44, 119, 203, 162, 44, 119, 201, 173, 44, - 119, 206, 3, 44, 119, 230, 83, 44, 119, 220, 223, 44, 5, 222, 100, 44, 5, - 221, 142, 44, 5, 221, 121, 44, 5, 220, 208, 44, 5, 220, 163, 44, 5, 221, - 253, 44, 5, 221, 244, 44, 5, 222, 75, 44, 5, 221, 43, 44, 5, 221, 17, 44, - 5, 222, 16, 44, 5, 214, 53, 44, 5, 214, 2, 44, 5, 213, 254, 44, 5, 213, - 223, 44, 5, 213, 214, 44, 5, 214, 41, 44, 5, 214, 39, 44, 5, 214, 50, 44, - 5, 213, 235, 44, 5, 213, 230, 44, 5, 214, 43, 44, 5, 247, 111, 44, 5, - 242, 237, 44, 5, 242, 227, 44, 5, 238, 148, 44, 5, 238, 106, 44, 5, 246, - 250, 44, 5, 246, 242, 44, 5, 247, 100, 44, 5, 242, 51, 44, 5, 238, 227, - 44, 5, 247, 28, 44, 5, 212, 87, 44, 5, 212, 68, 44, 5, 212, 62, 44, 5, - 212, 45, 44, 5, 212, 37, 44, 5, 212, 77, 44, 5, 212, 76, 44, 5, 212, 84, - 44, 5, 212, 52, 44, 5, 212, 49, 44, 5, 212, 80, 44, 5, 197, 127, 44, 5, - 197, 107, 44, 5, 197, 106, 44, 5, 197, 95, 44, 5, 197, 92, 44, 5, 197, - 123, 44, 5, 197, 122, 44, 5, 197, 126, 44, 5, 197, 105, 44, 5, 197, 104, - 44, 5, 197, 125, 44, 5, 213, 65, 44, 5, 213, 51, 44, 5, 213, 50, 44, 5, - 213, 34, 44, 5, 213, 33, 44, 5, 213, 61, 44, 5, 213, 60, 44, 5, 213, 64, - 44, 5, 213, 36, 44, 5, 213, 35, 44, 5, 213, 63, 44, 5, 199, 240, 44, 5, - 198, 188, 44, 5, 198, 165, 44, 5, 197, 90, 44, 5, 197, 45, 44, 5, 199, - 140, 44, 5, 199, 116, 44, 5, 199, 212, 44, 5, 159, 44, 5, 198, 54, 44, 5, - 199, 161, 44, 5, 214, 236, 44, 5, 213, 205, 44, 5, 213, 172, 44, 5, 212, - 165, 44, 5, 212, 102, 44, 5, 214, 107, 44, 5, 214, 96, 44, 5, 214, 222, - 44, 5, 213, 30, 44, 5, 213, 13, 44, 5, 214, 191, 44, 5, 210, 210, 44, 5, - 209, 176, 44, 5, 209, 136, 44, 5, 208, 158, 44, 5, 208, 121, 44, 5, 210, - 53, 44, 5, 210, 40, 44, 5, 210, 188, 44, 5, 209, 65, 44, 5, 209, 30, 44, - 5, 210, 70, 44, 5, 217, 130, 44, 5, 216, 81, 44, 5, 216, 43, 44, 5, 215, - 139, 44, 5, 215, 79, 44, 5, 216, 213, 44, 5, 216, 192, 44, 5, 217, 91, - 44, 5, 215, 251, 44, 5, 215, 194, 44, 5, 217, 6, 44, 5, 192, 140, 44, 5, - 192, 33, 44, 5, 192, 23, 44, 5, 191, 225, 44, 5, 191, 188, 44, 5, 192, - 80, 44, 5, 192, 77, 44, 5, 192, 119, 44, 5, 192, 12, 44, 5, 191, 246, 44, - 5, 192, 91, 44, 5, 207, 173, 44, 5, 206, 252, 44, 5, 206, 190, 44, 5, - 206, 63, 44, 5, 206, 24, 44, 5, 207, 108, 44, 5, 207, 79, 44, 5, 207, - 151, 44, 5, 206, 157, 44, 5, 206, 129, 44, 5, 207, 120, 44, 5, 220, 101, - 44, 5, 219, 122, 44, 5, 219, 104, 44, 5, 218, 203, 44, 5, 218, 173, 44, - 5, 219, 214, 44, 5, 219, 204, 44, 5, 220, 72, 44, 5, 219, 19, 44, 5, 218, - 240, 44, 5, 219, 232, 44, 5, 195, 184, 44, 5, 195, 66, 44, 5, 195, 48, - 44, 5, 193, 246, 44, 5, 193, 238, 44, 5, 195, 150, 44, 5, 195, 145, 44, - 5, 195, 180, 44, 5, 195, 21, 44, 5, 195, 5, 44, 5, 195, 157, 44, 5, 219, - 37, 44, 5, 219, 32, 44, 5, 219, 31, 44, 5, 219, 28, 44, 5, 219, 27, 44, - 5, 219, 34, 44, 5, 219, 33, 44, 5, 219, 36, 44, 5, 219, 30, 44, 5, 219, - 29, 44, 5, 219, 35, 44, 5, 219, 48, 44, 5, 219, 41, 44, 5, 219, 40, 44, - 5, 219, 24, 44, 5, 219, 23, 44, 5, 219, 44, 44, 5, 219, 43, 44, 5, 219, - 47, 44, 5, 219, 26, 44, 5, 219, 25, 44, 5, 219, 45, 44, 5, 206, 103, 44, - 5, 206, 92, 44, 5, 206, 91, 44, 5, 206, 84, 44, 5, 206, 77, 44, 5, 206, - 99, 44, 5, 206, 98, 44, 5, 206, 102, 44, 5, 206, 90, 44, 5, 206, 89, 44, - 5, 206, 101, 44, 5, 213, 47, 44, 5, 213, 42, 44, 5, 213, 41, 44, 5, 213, - 38, 44, 5, 213, 37, 44, 5, 213, 44, 44, 5, 213, 43, 44, 5, 213, 46, 44, - 5, 213, 40, 44, 5, 213, 39, 44, 5, 213, 45, 44, 5, 223, 3, 44, 5, 222, - 217, 44, 5, 222, 209, 44, 5, 222, 155, 44, 5, 222, 135, 44, 5, 222, 238, - 44, 5, 222, 236, 44, 5, 222, 253, 44, 5, 222, 174, 44, 5, 222, 164, 44, - 5, 222, 245, 44, 5, 203, 155, 44, 5, 203, 76, 44, 5, 203, 71, 44, 5, 203, - 0, 44, 5, 202, 238, 44, 5, 203, 108, 44, 5, 203, 106, 44, 5, 203, 143, - 44, 5, 203, 51, 44, 5, 203, 43, 44, 5, 203, 117, 44, 5, 201, 169, 44, 5, - 201, 137, 44, 5, 201, 133, 44, 5, 201, 124, 44, 5, 201, 121, 44, 5, 201, - 143, 44, 5, 201, 142, 44, 5, 201, 168, 44, 5, 201, 129, 44, 5, 201, 128, - 44, 5, 201, 145, 44, 5, 205, 192, 44, 5, 202, 217, 44, 5, 202, 188, 44, - 5, 200, 255, 44, 5, 200, 156, 44, 5, 205, 63, 44, 5, 205, 45, 44, 5, 205, - 176, 44, 5, 202, 41, 44, 5, 202, 11, 44, 5, 205, 109, 44, 5, 230, 58, 44, - 5, 229, 126, 44, 5, 229, 98, 44, 5, 228, 128, 44, 5, 228, 97, 44, 5, 229, - 213, 44, 5, 229, 183, 44, 5, 230, 47, 44, 5, 228, 247, 44, 5, 228, 220, - 44, 5, 229, 225, 44, 5, 220, 222, 44, 5, 220, 221, 44, 5, 220, 216, 44, - 5, 220, 215, 44, 5, 220, 212, 44, 5, 220, 211, 44, 5, 220, 218, 44, 5, - 220, 217, 44, 5, 220, 220, 44, 5, 220, 214, 44, 5, 220, 213, 44, 5, 220, - 219, 44, 5, 203, 9, 165, 119, 3, 192, 105, 165, 119, 3, 207, 139, 165, - 119, 3, 207, 45, 100, 1, 196, 220, 94, 119, 3, 242, 43, 157, 94, 119, 3, - 242, 43, 221, 190, 94, 119, 3, 242, 43, 221, 43, 94, 119, 3, 242, 43, - 221, 159, 94, 119, 3, 242, 43, 213, 235, 94, 119, 3, 242, 43, 247, 112, - 94, 119, 3, 242, 43, 246, 209, 94, 119, 3, 242, 43, 242, 51, 94, 119, 3, - 242, 43, 243, 20, 94, 119, 3, 242, 43, 212, 52, 94, 119, 3, 242, 43, 237, - 241, 94, 119, 3, 242, 43, 197, 116, 94, 119, 3, 242, 43, 236, 129, 94, - 119, 3, 242, 43, 197, 111, 94, 119, 3, 242, 43, 180, 94, 119, 3, 242, 43, - 199, 247, 94, 119, 3, 242, 43, 199, 44, 94, 119, 3, 242, 43, 159, 94, - 119, 3, 242, 43, 198, 236, 94, 119, 3, 242, 43, 213, 30, 94, 119, 3, 242, - 43, 249, 103, 94, 119, 3, 242, 43, 209, 219, 94, 119, 3, 242, 43, 209, - 65, 94, 119, 3, 242, 43, 209, 190, 94, 119, 3, 242, 43, 215, 251, 94, - 119, 3, 242, 43, 192, 12, 94, 119, 3, 242, 43, 206, 157, 94, 119, 3, 242, - 43, 219, 19, 94, 119, 3, 242, 43, 195, 21, 94, 119, 3, 242, 43, 203, 160, - 94, 119, 3, 242, 43, 201, 170, 94, 119, 3, 242, 43, 189, 94, 119, 3, 242, - 43, 144, 94, 119, 3, 242, 43, 171, 94, 18, 3, 242, 43, 208, 89, 94, 223, - 121, 18, 3, 242, 43, 208, 27, 94, 223, 121, 18, 3, 242, 43, 206, 12, 94, - 223, 121, 18, 3, 242, 43, 206, 5, 94, 223, 121, 18, 3, 242, 43, 208, 69, - 94, 18, 3, 211, 102, 94, 18, 3, 252, 115, 229, 88, 1, 248, 133, 214, 54, - 229, 88, 1, 248, 133, 214, 2, 229, 88, 1, 248, 133, 213, 223, 229, 88, 1, - 248, 133, 214, 41, 229, 88, 1, 248, 133, 213, 235, 71, 1, 248, 133, 214, - 54, 71, 1, 248, 133, 214, 2, 71, 1, 248, 133, 213, 223, 71, 1, 248, 133, - 214, 41, 71, 1, 248, 133, 213, 235, 71, 1, 251, 176, 246, 250, 71, 1, - 251, 176, 197, 90, 71, 1, 251, 176, 159, 71, 1, 251, 176, 210, 226, 59, - 1, 233, 159, 233, 158, 238, 235, 163, 164, 59, 1, 233, 158, 233, 159, - 238, 235, 163, 164, + 13, 28, 43, 2, 65, 13, 28, 43, 2, 250, 120, 13, 28, 43, 2, 247, 193, 13, + 28, 43, 2, 238, 127, 13, 28, 43, 2, 71, 13, 28, 43, 2, 233, 175, 13, 28, + 43, 2, 232, 51, 13, 28, 43, 2, 230, 116, 13, 28, 43, 2, 68, 13, 28, 43, + 2, 223, 35, 13, 28, 43, 2, 222, 152, 13, 28, 43, 2, 172, 13, 28, 43, 2, + 218, 168, 13, 28, 43, 2, 215, 61, 13, 28, 43, 2, 74, 13, 28, 43, 2, 210, + 236, 13, 28, 43, 2, 208, 104, 13, 28, 43, 2, 146, 13, 28, 43, 2, 206, 8, + 13, 28, 43, 2, 200, 43, 13, 28, 43, 2, 66, 13, 28, 43, 2, 196, 12, 13, + 28, 43, 2, 193, 224, 13, 28, 43, 2, 192, 235, 13, 28, 43, 2, 192, 159, + 13, 28, 43, 2, 191, 166, 13, 27, 6, 65, 13, 27, 6, 247, 193, 13, 27, 6, + 238, 127, 13, 27, 6, 232, 51, 13, 27, 6, 223, 35, 13, 27, 6, 222, 152, + 13, 27, 6, 215, 61, 13, 27, 6, 74, 13, 27, 6, 210, 236, 13, 27, 6, 208, + 104, 13, 27, 6, 206, 8, 13, 27, 6, 200, 43, 13, 27, 6, 66, 13, 27, 6, + 196, 12, 13, 27, 6, 193, 224, 13, 27, 6, 192, 235, 13, 27, 6, 192, 159, + 13, 27, 6, 191, 166, 13, 27, 2, 65, 13, 27, 2, 250, 120, 13, 27, 2, 247, + 193, 13, 27, 2, 238, 127, 13, 27, 2, 233, 175, 13, 27, 2, 230, 116, 13, + 27, 2, 68, 13, 27, 2, 223, 35, 13, 27, 2, 222, 152, 13, 27, 2, 172, 13, + 27, 2, 218, 168, 13, 27, 2, 215, 61, 13, 27, 2, 210, 236, 13, 27, 2, 208, + 104, 13, 27, 2, 146, 13, 27, 2, 206, 8, 13, 27, 2, 200, 43, 13, 27, 2, + 66, 13, 27, 2, 196, 12, 13, 27, 2, 193, 224, 13, 27, 2, 192, 235, 13, 27, + 2, 192, 159, 13, 27, 2, 191, 166, 13, 28, 27, 6, 65, 13, 28, 27, 6, 250, + 120, 13, 28, 27, 6, 247, 193, 13, 28, 27, 6, 238, 127, 13, 28, 27, 6, 71, + 13, 28, 27, 6, 233, 175, 13, 28, 27, 6, 232, 51, 13, 28, 27, 6, 230, 116, + 13, 28, 27, 6, 68, 13, 28, 27, 6, 223, 35, 13, 28, 27, 6, 222, 152, 13, + 28, 27, 6, 172, 13, 28, 27, 6, 218, 168, 13, 28, 27, 6, 215, 61, 13, 28, + 27, 6, 74, 13, 28, 27, 6, 210, 236, 13, 28, 27, 6, 208, 104, 13, 28, 27, + 6, 146, 13, 28, 27, 6, 206, 8, 13, 28, 27, 6, 200, 43, 13, 28, 27, 6, 66, + 13, 28, 27, 6, 196, 12, 13, 28, 27, 6, 193, 224, 13, 28, 27, 6, 192, 235, + 13, 28, 27, 6, 192, 159, 13, 28, 27, 6, 191, 166, 13, 28, 27, 2, 65, 13, + 28, 27, 2, 250, 120, 13, 28, 27, 2, 247, 193, 13, 28, 27, 2, 238, 127, + 13, 28, 27, 2, 71, 13, 28, 27, 2, 233, 175, 13, 28, 27, 2, 232, 51, 13, + 28, 27, 2, 230, 116, 13, 28, 27, 2, 68, 13, 28, 27, 2, 223, 35, 13, 28, + 27, 2, 222, 152, 13, 28, 27, 2, 172, 13, 28, 27, 2, 218, 168, 13, 28, 27, + 2, 215, 61, 13, 28, 27, 2, 74, 13, 28, 27, 2, 210, 236, 13, 28, 27, 2, + 208, 104, 13, 28, 27, 2, 146, 13, 28, 27, 2, 206, 8, 13, 28, 27, 2, 200, + 43, 13, 28, 27, 2, 66, 13, 28, 27, 2, 196, 12, 13, 28, 27, 2, 193, 224, + 13, 28, 27, 2, 192, 235, 13, 28, 27, 2, 192, 159, 13, 28, 27, 2, 191, + 166, 13, 232, 115, 6, 65, 13, 232, 115, 6, 250, 120, 13, 232, 115, 6, + 238, 127, 13, 232, 115, 6, 71, 13, 232, 115, 6, 233, 175, 13, 232, 115, + 6, 232, 51, 13, 232, 115, 6, 223, 35, 13, 232, 115, 6, 222, 152, 13, 232, + 115, 6, 172, 13, 232, 115, 6, 218, 168, 13, 232, 115, 6, 215, 61, 13, + 232, 115, 6, 74, 13, 232, 115, 6, 210, 236, 13, 232, 115, 6, 208, 104, + 13, 232, 115, 6, 206, 8, 13, 232, 115, 6, 200, 43, 13, 232, 115, 6, 66, + 13, 232, 115, 6, 196, 12, 13, 232, 115, 6, 193, 224, 13, 232, 115, 6, + 192, 235, 13, 232, 115, 6, 192, 159, 13, 232, 115, 2, 65, 13, 232, 115, + 2, 250, 120, 13, 232, 115, 2, 247, 193, 13, 232, 115, 2, 238, 127, 13, + 232, 115, 2, 71, 13, 232, 115, 2, 233, 175, 13, 232, 115, 2, 232, 51, 13, + 232, 115, 2, 230, 116, 13, 232, 115, 2, 68, 13, 232, 115, 2, 223, 35, 13, + 232, 115, 2, 222, 152, 13, 232, 115, 2, 172, 13, 232, 115, 2, 218, 168, + 13, 232, 115, 2, 215, 61, 13, 232, 115, 2, 74, 13, 232, 115, 2, 210, 236, + 13, 232, 115, 2, 208, 104, 13, 232, 115, 2, 146, 13, 232, 115, 2, 206, 8, + 13, 232, 115, 2, 200, 43, 13, 232, 115, 2, 66, 13, 232, 115, 2, 196, 12, + 13, 232, 115, 2, 193, 224, 13, 232, 115, 2, 192, 235, 13, 232, 115, 2, + 192, 159, 13, 232, 115, 2, 191, 166, 13, 235, 129, 6, 65, 13, 235, 129, + 6, 250, 120, 13, 235, 129, 6, 238, 127, 13, 235, 129, 6, 71, 13, 235, + 129, 6, 233, 175, 13, 235, 129, 6, 232, 51, 13, 235, 129, 6, 68, 13, 235, + 129, 6, 223, 35, 13, 235, 129, 6, 222, 152, 13, 235, 129, 6, 172, 13, + 235, 129, 6, 218, 168, 13, 235, 129, 6, 74, 13, 235, 129, 6, 206, 8, 13, + 235, 129, 6, 200, 43, 13, 235, 129, 6, 66, 13, 235, 129, 6, 196, 12, 13, + 235, 129, 6, 193, 224, 13, 235, 129, 6, 192, 235, 13, 235, 129, 6, 192, + 159, 13, 235, 129, 2, 65, 13, 235, 129, 2, 250, 120, 13, 235, 129, 2, + 247, 193, 13, 235, 129, 2, 238, 127, 13, 235, 129, 2, 71, 13, 235, 129, + 2, 233, 175, 13, 235, 129, 2, 232, 51, 13, 235, 129, 2, 230, 116, 13, + 235, 129, 2, 68, 13, 235, 129, 2, 223, 35, 13, 235, 129, 2, 222, 152, 13, + 235, 129, 2, 172, 13, 235, 129, 2, 218, 168, 13, 235, 129, 2, 215, 61, + 13, 235, 129, 2, 74, 13, 235, 129, 2, 210, 236, 13, 235, 129, 2, 208, + 104, 13, 235, 129, 2, 146, 13, 235, 129, 2, 206, 8, 13, 235, 129, 2, 200, + 43, 13, 235, 129, 2, 66, 13, 235, 129, 2, 196, 12, 13, 235, 129, 2, 193, + 224, 13, 235, 129, 2, 192, 235, 13, 235, 129, 2, 192, 159, 13, 235, 129, + 2, 191, 166, 13, 28, 232, 115, 6, 65, 13, 28, 232, 115, 6, 250, 120, 13, + 28, 232, 115, 6, 247, 193, 13, 28, 232, 115, 6, 238, 127, 13, 28, 232, + 115, 6, 71, 13, 28, 232, 115, 6, 233, 175, 13, 28, 232, 115, 6, 232, 51, + 13, 28, 232, 115, 6, 230, 116, 13, 28, 232, 115, 6, 68, 13, 28, 232, 115, + 6, 223, 35, 13, 28, 232, 115, 6, 222, 152, 13, 28, 232, 115, 6, 172, 13, + 28, 232, 115, 6, 218, 168, 13, 28, 232, 115, 6, 215, 61, 13, 28, 232, + 115, 6, 74, 13, 28, 232, 115, 6, 210, 236, 13, 28, 232, 115, 6, 208, 104, + 13, 28, 232, 115, 6, 146, 13, 28, 232, 115, 6, 206, 8, 13, 28, 232, 115, + 6, 200, 43, 13, 28, 232, 115, 6, 66, 13, 28, 232, 115, 6, 196, 12, 13, + 28, 232, 115, 6, 193, 224, 13, 28, 232, 115, 6, 192, 235, 13, 28, 232, + 115, 6, 192, 159, 13, 28, 232, 115, 6, 191, 166, 13, 28, 232, 115, 2, 65, + 13, 28, 232, 115, 2, 250, 120, 13, 28, 232, 115, 2, 247, 193, 13, 28, + 232, 115, 2, 238, 127, 13, 28, 232, 115, 2, 71, 13, 28, 232, 115, 2, 233, + 175, 13, 28, 232, 115, 2, 232, 51, 13, 28, 232, 115, 2, 230, 116, 13, 28, + 232, 115, 2, 68, 13, 28, 232, 115, 2, 223, 35, 13, 28, 232, 115, 2, 222, + 152, 13, 28, 232, 115, 2, 172, 13, 28, 232, 115, 2, 218, 168, 13, 28, + 232, 115, 2, 215, 61, 13, 28, 232, 115, 2, 74, 13, 28, 232, 115, 2, 210, + 236, 13, 28, 232, 115, 2, 208, 104, 13, 28, 232, 115, 2, 146, 13, 28, + 232, 115, 2, 206, 8, 13, 28, 232, 115, 2, 200, 43, 13, 28, 232, 115, 2, + 66, 13, 28, 232, 115, 2, 196, 12, 13, 28, 232, 115, 2, 193, 224, 13, 28, + 232, 115, 2, 192, 235, 13, 28, 232, 115, 2, 192, 159, 13, 28, 232, 115, + 2, 191, 166, 13, 49, 6, 65, 13, 49, 6, 250, 120, 13, 49, 6, 247, 193, 13, + 49, 6, 238, 127, 13, 49, 6, 71, 13, 49, 6, 233, 175, 13, 49, 6, 232, 51, + 13, 49, 6, 230, 116, 13, 49, 6, 68, 13, 49, 6, 223, 35, 13, 49, 6, 222, + 152, 13, 49, 6, 172, 13, 49, 6, 218, 168, 13, 49, 6, 215, 61, 13, 49, 6, + 74, 13, 49, 6, 210, 236, 13, 49, 6, 208, 104, 13, 49, 6, 146, 13, 49, 6, + 206, 8, 13, 49, 6, 200, 43, 13, 49, 6, 66, 13, 49, 6, 196, 12, 13, 49, 6, + 193, 224, 13, 49, 6, 192, 235, 13, 49, 6, 192, 159, 13, 49, 6, 191, 166, + 13, 49, 2, 65, 13, 49, 2, 250, 120, 13, 49, 2, 247, 193, 13, 49, 2, 238, + 127, 13, 49, 2, 71, 13, 49, 2, 233, 175, 13, 49, 2, 232, 51, 13, 49, 2, + 230, 116, 13, 49, 2, 68, 13, 49, 2, 223, 35, 13, 49, 2, 222, 152, 13, 49, + 2, 172, 13, 49, 2, 218, 168, 13, 49, 2, 215, 61, 13, 49, 2, 74, 13, 49, + 2, 210, 236, 13, 49, 2, 208, 104, 13, 49, 2, 146, 13, 49, 2, 206, 8, 13, + 49, 2, 200, 43, 13, 49, 2, 66, 13, 49, 2, 196, 12, 13, 49, 2, 193, 224, + 13, 49, 2, 192, 235, 13, 49, 2, 192, 159, 13, 49, 2, 191, 166, 13, 49, + 28, 6, 65, 13, 49, 28, 6, 250, 120, 13, 49, 28, 6, 247, 193, 13, 49, 28, + 6, 238, 127, 13, 49, 28, 6, 71, 13, 49, 28, 6, 233, 175, 13, 49, 28, 6, + 232, 51, 13, 49, 28, 6, 230, 116, 13, 49, 28, 6, 68, 13, 49, 28, 6, 223, + 35, 13, 49, 28, 6, 222, 152, 13, 49, 28, 6, 172, 13, 49, 28, 6, 218, 168, + 13, 49, 28, 6, 215, 61, 13, 49, 28, 6, 74, 13, 49, 28, 6, 210, 236, 13, + 49, 28, 6, 208, 104, 13, 49, 28, 6, 146, 13, 49, 28, 6, 206, 8, 13, 49, + 28, 6, 200, 43, 13, 49, 28, 6, 66, 13, 49, 28, 6, 196, 12, 13, 49, 28, 6, + 193, 224, 13, 49, 28, 6, 192, 235, 13, 49, 28, 6, 192, 159, 13, 49, 28, + 6, 191, 166, 13, 49, 28, 2, 65, 13, 49, 28, 2, 250, 120, 13, 49, 28, 2, + 247, 193, 13, 49, 28, 2, 238, 127, 13, 49, 28, 2, 71, 13, 49, 28, 2, 233, + 175, 13, 49, 28, 2, 232, 51, 13, 49, 28, 2, 230, 116, 13, 49, 28, 2, 68, + 13, 49, 28, 2, 223, 35, 13, 49, 28, 2, 222, 152, 13, 49, 28, 2, 172, 13, + 49, 28, 2, 218, 168, 13, 49, 28, 2, 215, 61, 13, 49, 28, 2, 74, 13, 49, + 28, 2, 210, 236, 13, 49, 28, 2, 208, 104, 13, 49, 28, 2, 146, 13, 49, 28, + 2, 206, 8, 13, 49, 28, 2, 200, 43, 13, 49, 28, 2, 66, 13, 49, 28, 2, 196, + 12, 13, 49, 28, 2, 193, 224, 13, 49, 28, 2, 192, 235, 13, 49, 28, 2, 192, + 159, 13, 49, 28, 2, 191, 166, 13, 49, 43, 6, 65, 13, 49, 43, 6, 250, 120, + 13, 49, 43, 6, 247, 193, 13, 49, 43, 6, 238, 127, 13, 49, 43, 6, 71, 13, + 49, 43, 6, 233, 175, 13, 49, 43, 6, 232, 51, 13, 49, 43, 6, 230, 116, 13, + 49, 43, 6, 68, 13, 49, 43, 6, 223, 35, 13, 49, 43, 6, 222, 152, 13, 49, + 43, 6, 172, 13, 49, 43, 6, 218, 168, 13, 49, 43, 6, 215, 61, 13, 49, 43, + 6, 74, 13, 49, 43, 6, 210, 236, 13, 49, 43, 6, 208, 104, 13, 49, 43, 6, + 146, 13, 49, 43, 6, 206, 8, 13, 49, 43, 6, 200, 43, 13, 49, 43, 6, 66, + 13, 49, 43, 6, 196, 12, 13, 49, 43, 6, 193, 224, 13, 49, 43, 6, 192, 235, + 13, 49, 43, 6, 192, 159, 13, 49, 43, 6, 191, 166, 13, 49, 43, 2, 65, 13, + 49, 43, 2, 250, 120, 13, 49, 43, 2, 247, 193, 13, 49, 43, 2, 238, 127, + 13, 49, 43, 2, 71, 13, 49, 43, 2, 233, 175, 13, 49, 43, 2, 232, 51, 13, + 49, 43, 2, 230, 116, 13, 49, 43, 2, 68, 13, 49, 43, 2, 223, 35, 13, 49, + 43, 2, 222, 152, 13, 49, 43, 2, 172, 13, 49, 43, 2, 218, 168, 13, 49, 43, + 2, 215, 61, 13, 49, 43, 2, 74, 13, 49, 43, 2, 210, 236, 13, 49, 43, 2, + 208, 104, 13, 49, 43, 2, 146, 13, 49, 43, 2, 206, 8, 13, 49, 43, 2, 200, + 43, 13, 49, 43, 2, 66, 13, 49, 43, 2, 196, 12, 13, 49, 43, 2, 193, 224, + 13, 49, 43, 2, 192, 235, 13, 49, 43, 2, 192, 159, 13, 49, 43, 2, 191, + 166, 13, 49, 28, 43, 6, 65, 13, 49, 28, 43, 6, 250, 120, 13, 49, 28, 43, + 6, 247, 193, 13, 49, 28, 43, 6, 238, 127, 13, 49, 28, 43, 6, 71, 13, 49, + 28, 43, 6, 233, 175, 13, 49, 28, 43, 6, 232, 51, 13, 49, 28, 43, 6, 230, + 116, 13, 49, 28, 43, 6, 68, 13, 49, 28, 43, 6, 223, 35, 13, 49, 28, 43, + 6, 222, 152, 13, 49, 28, 43, 6, 172, 13, 49, 28, 43, 6, 218, 168, 13, 49, + 28, 43, 6, 215, 61, 13, 49, 28, 43, 6, 74, 13, 49, 28, 43, 6, 210, 236, + 13, 49, 28, 43, 6, 208, 104, 13, 49, 28, 43, 6, 146, 13, 49, 28, 43, 6, + 206, 8, 13, 49, 28, 43, 6, 200, 43, 13, 49, 28, 43, 6, 66, 13, 49, 28, + 43, 6, 196, 12, 13, 49, 28, 43, 6, 193, 224, 13, 49, 28, 43, 6, 192, 235, + 13, 49, 28, 43, 6, 192, 159, 13, 49, 28, 43, 6, 191, 166, 13, 49, 28, 43, + 2, 65, 13, 49, 28, 43, 2, 250, 120, 13, 49, 28, 43, 2, 247, 193, 13, 49, + 28, 43, 2, 238, 127, 13, 49, 28, 43, 2, 71, 13, 49, 28, 43, 2, 233, 175, + 13, 49, 28, 43, 2, 232, 51, 13, 49, 28, 43, 2, 230, 116, 13, 49, 28, 43, + 2, 68, 13, 49, 28, 43, 2, 223, 35, 13, 49, 28, 43, 2, 222, 152, 13, 49, + 28, 43, 2, 172, 13, 49, 28, 43, 2, 218, 168, 13, 49, 28, 43, 2, 215, 61, + 13, 49, 28, 43, 2, 74, 13, 49, 28, 43, 2, 210, 236, 13, 49, 28, 43, 2, + 208, 104, 13, 49, 28, 43, 2, 146, 13, 49, 28, 43, 2, 206, 8, 13, 49, 28, + 43, 2, 200, 43, 13, 49, 28, 43, 2, 66, 13, 49, 28, 43, 2, 196, 12, 13, + 49, 28, 43, 2, 193, 224, 13, 49, 28, 43, 2, 192, 235, 13, 49, 28, 43, 2, + 192, 159, 13, 49, 28, 43, 2, 191, 166, 13, 215, 217, 6, 65, 13, 215, 217, + 6, 250, 120, 13, 215, 217, 6, 247, 193, 13, 215, 217, 6, 238, 127, 13, + 215, 217, 6, 71, 13, 215, 217, 6, 233, 175, 13, 215, 217, 6, 232, 51, 13, + 215, 217, 6, 230, 116, 13, 215, 217, 6, 68, 13, 215, 217, 6, 223, 35, 13, + 215, 217, 6, 222, 152, 13, 215, 217, 6, 172, 13, 215, 217, 6, 218, 168, + 13, 215, 217, 6, 215, 61, 13, 215, 217, 6, 74, 13, 215, 217, 6, 210, 236, + 13, 215, 217, 6, 208, 104, 13, 215, 217, 6, 146, 13, 215, 217, 6, 206, 8, + 13, 215, 217, 6, 200, 43, 13, 215, 217, 6, 66, 13, 215, 217, 6, 196, 12, + 13, 215, 217, 6, 193, 224, 13, 215, 217, 6, 192, 235, 13, 215, 217, 6, + 192, 159, 13, 215, 217, 6, 191, 166, 13, 215, 217, 2, 65, 13, 215, 217, + 2, 250, 120, 13, 215, 217, 2, 247, 193, 13, 215, 217, 2, 238, 127, 13, + 215, 217, 2, 71, 13, 215, 217, 2, 233, 175, 13, 215, 217, 2, 232, 51, 13, + 215, 217, 2, 230, 116, 13, 215, 217, 2, 68, 13, 215, 217, 2, 223, 35, 13, + 215, 217, 2, 222, 152, 13, 215, 217, 2, 172, 13, 215, 217, 2, 218, 168, + 13, 215, 217, 2, 215, 61, 13, 215, 217, 2, 74, 13, 215, 217, 2, 210, 236, + 13, 215, 217, 2, 208, 104, 13, 215, 217, 2, 146, 13, 215, 217, 2, 206, 8, + 13, 215, 217, 2, 200, 43, 13, 215, 217, 2, 66, 13, 215, 217, 2, 196, 12, + 13, 215, 217, 2, 193, 224, 13, 215, 217, 2, 192, 235, 13, 215, 217, 2, + 192, 159, 13, 215, 217, 2, 191, 166, 13, 43, 2, 236, 139, 68, 13, 43, 2, + 236, 139, 223, 35, 13, 28, 6, 251, 160, 13, 28, 6, 248, 212, 13, 28, 6, + 231, 211, 13, 28, 6, 237, 106, 13, 28, 6, 234, 47, 13, 28, 6, 191, 76, + 13, 28, 6, 233, 253, 13, 28, 6, 199, 15, 13, 28, 6, 223, 83, 13, 28, 6, + 222, 72, 13, 28, 6, 220, 31, 13, 28, 6, 215, 155, 13, 28, 6, 212, 178, + 13, 28, 6, 192, 207, 13, 28, 6, 211, 107, 13, 28, 6, 209, 185, 13, 28, 6, + 207, 3, 13, 28, 6, 199, 16, 113, 13, 28, 6, 202, 196, 13, 28, 6, 199, + 166, 13, 28, 6, 196, 70, 13, 28, 6, 209, 211, 13, 28, 6, 243, 95, 13, 28, + 6, 208, 176, 13, 28, 6, 211, 110, 13, 28, 214, 245, 13, 28, 2, 251, 160, + 13, 28, 2, 248, 212, 13, 28, 2, 231, 211, 13, 28, 2, 237, 106, 13, 28, 2, + 234, 47, 13, 28, 2, 191, 76, 13, 28, 2, 233, 253, 13, 28, 2, 199, 15, 13, + 28, 2, 223, 83, 13, 28, 2, 222, 72, 13, 28, 2, 220, 31, 13, 28, 2, 215, + 155, 13, 28, 2, 212, 178, 13, 28, 2, 192, 207, 13, 28, 2, 211, 107, 13, + 28, 2, 209, 185, 13, 28, 2, 207, 3, 13, 28, 2, 53, 202, 196, 13, 28, 2, + 202, 196, 13, 28, 2, 199, 166, 13, 28, 2, 196, 70, 13, 28, 2, 209, 211, + 13, 28, 2, 243, 95, 13, 28, 2, 208, 176, 13, 28, 2, 211, 110, 13, 28, + 210, 105, 237, 16, 13, 28, 234, 48, 113, 13, 28, 199, 16, 113, 13, 28, + 222, 73, 113, 13, 28, 209, 212, 113, 13, 28, 207, 4, 113, 13, 28, 209, + 186, 113, 13, 43, 6, 251, 160, 13, 43, 6, 248, 212, 13, 43, 6, 231, 211, + 13, 43, 6, 237, 106, 13, 43, 6, 234, 47, 13, 43, 6, 191, 76, 13, 43, 6, + 233, 253, 13, 43, 6, 199, 15, 13, 43, 6, 223, 83, 13, 43, 6, 222, 72, 13, + 43, 6, 220, 31, 13, 43, 6, 215, 155, 13, 43, 6, 212, 178, 13, 43, 6, 192, + 207, 13, 43, 6, 211, 107, 13, 43, 6, 209, 185, 13, 43, 6, 207, 3, 13, 43, + 6, 199, 16, 113, 13, 43, 6, 202, 196, 13, 43, 6, 199, 166, 13, 43, 6, + 196, 70, 13, 43, 6, 209, 211, 13, 43, 6, 243, 95, 13, 43, 6, 208, 176, + 13, 43, 6, 211, 110, 13, 43, 214, 245, 13, 43, 2, 251, 160, 13, 43, 2, + 248, 212, 13, 43, 2, 231, 211, 13, 43, 2, 237, 106, 13, 43, 2, 234, 47, + 13, 43, 2, 191, 76, 13, 43, 2, 233, 253, 13, 43, 2, 199, 15, 13, 43, 2, + 223, 83, 13, 43, 2, 222, 72, 13, 43, 2, 220, 31, 13, 43, 2, 215, 155, 13, + 43, 2, 212, 178, 13, 43, 2, 192, 207, 13, 43, 2, 211, 107, 13, 43, 2, + 209, 185, 13, 43, 2, 207, 3, 13, 43, 2, 53, 202, 196, 13, 43, 2, 202, + 196, 13, 43, 2, 199, 166, 13, 43, 2, 196, 70, 13, 43, 2, 209, 211, 13, + 43, 2, 243, 95, 13, 43, 2, 208, 176, 13, 43, 2, 211, 110, 13, 43, 210, + 105, 237, 16, 13, 43, 234, 48, 113, 13, 43, 199, 16, 113, 13, 43, 222, + 73, 113, 13, 43, 209, 212, 113, 13, 43, 207, 4, 113, 13, 43, 209, 186, + 113, 13, 28, 43, 6, 251, 160, 13, 28, 43, 6, 248, 212, 13, 28, 43, 6, + 231, 211, 13, 28, 43, 6, 237, 106, 13, 28, 43, 6, 234, 47, 13, 28, 43, 6, + 191, 76, 13, 28, 43, 6, 233, 253, 13, 28, 43, 6, 199, 15, 13, 28, 43, 6, + 223, 83, 13, 28, 43, 6, 222, 72, 13, 28, 43, 6, 220, 31, 13, 28, 43, 6, + 215, 155, 13, 28, 43, 6, 212, 178, 13, 28, 43, 6, 192, 207, 13, 28, 43, + 6, 211, 107, 13, 28, 43, 6, 209, 185, 13, 28, 43, 6, 207, 3, 13, 28, 43, + 6, 199, 16, 113, 13, 28, 43, 6, 202, 196, 13, 28, 43, 6, 199, 166, 13, + 28, 43, 6, 196, 70, 13, 28, 43, 6, 209, 211, 13, 28, 43, 6, 243, 95, 13, + 28, 43, 6, 208, 176, 13, 28, 43, 6, 211, 110, 13, 28, 43, 214, 245, 13, + 28, 43, 2, 251, 160, 13, 28, 43, 2, 248, 212, 13, 28, 43, 2, 231, 211, + 13, 28, 43, 2, 237, 106, 13, 28, 43, 2, 234, 47, 13, 28, 43, 2, 191, 76, + 13, 28, 43, 2, 233, 253, 13, 28, 43, 2, 199, 15, 13, 28, 43, 2, 223, 83, + 13, 28, 43, 2, 222, 72, 13, 28, 43, 2, 220, 31, 13, 28, 43, 2, 215, 155, + 13, 28, 43, 2, 212, 178, 13, 28, 43, 2, 192, 207, 13, 28, 43, 2, 211, + 107, 13, 28, 43, 2, 209, 185, 13, 28, 43, 2, 207, 3, 13, 28, 43, 2, 53, + 202, 196, 13, 28, 43, 2, 202, 196, 13, 28, 43, 2, 199, 166, 13, 28, 43, + 2, 196, 70, 13, 28, 43, 2, 209, 211, 13, 28, 43, 2, 243, 95, 13, 28, 43, + 2, 208, 176, 13, 28, 43, 2, 211, 110, 13, 28, 43, 210, 105, 237, 16, 13, + 28, 43, 234, 48, 113, 13, 28, 43, 199, 16, 113, 13, 28, 43, 222, 73, 113, + 13, 28, 43, 209, 212, 113, 13, 28, 43, 207, 4, 113, 13, 28, 43, 209, 186, + 113, 13, 49, 28, 6, 251, 160, 13, 49, 28, 6, 248, 212, 13, 49, 28, 6, + 231, 211, 13, 49, 28, 6, 237, 106, 13, 49, 28, 6, 234, 47, 13, 49, 28, 6, + 191, 76, 13, 49, 28, 6, 233, 253, 13, 49, 28, 6, 199, 15, 13, 49, 28, 6, + 223, 83, 13, 49, 28, 6, 222, 72, 13, 49, 28, 6, 220, 31, 13, 49, 28, 6, + 215, 155, 13, 49, 28, 6, 212, 178, 13, 49, 28, 6, 192, 207, 13, 49, 28, + 6, 211, 107, 13, 49, 28, 6, 209, 185, 13, 49, 28, 6, 207, 3, 13, 49, 28, + 6, 199, 16, 113, 13, 49, 28, 6, 202, 196, 13, 49, 28, 6, 199, 166, 13, + 49, 28, 6, 196, 70, 13, 49, 28, 6, 209, 211, 13, 49, 28, 6, 243, 95, 13, + 49, 28, 6, 208, 176, 13, 49, 28, 6, 211, 110, 13, 49, 28, 214, 245, 13, + 49, 28, 2, 251, 160, 13, 49, 28, 2, 248, 212, 13, 49, 28, 2, 231, 211, + 13, 49, 28, 2, 237, 106, 13, 49, 28, 2, 234, 47, 13, 49, 28, 2, 191, 76, + 13, 49, 28, 2, 233, 253, 13, 49, 28, 2, 199, 15, 13, 49, 28, 2, 223, 83, + 13, 49, 28, 2, 222, 72, 13, 49, 28, 2, 220, 31, 13, 49, 28, 2, 215, 155, + 13, 49, 28, 2, 212, 178, 13, 49, 28, 2, 192, 207, 13, 49, 28, 2, 211, + 107, 13, 49, 28, 2, 209, 185, 13, 49, 28, 2, 207, 3, 13, 49, 28, 2, 53, + 202, 196, 13, 49, 28, 2, 202, 196, 13, 49, 28, 2, 199, 166, 13, 49, 28, + 2, 196, 70, 13, 49, 28, 2, 209, 211, 13, 49, 28, 2, 243, 95, 13, 49, 28, + 2, 208, 176, 13, 49, 28, 2, 211, 110, 13, 49, 28, 210, 105, 237, 16, 13, + 49, 28, 234, 48, 113, 13, 49, 28, 199, 16, 113, 13, 49, 28, 222, 73, 113, + 13, 49, 28, 209, 212, 113, 13, 49, 28, 207, 4, 113, 13, 49, 28, 209, 186, + 113, 13, 49, 28, 43, 6, 251, 160, 13, 49, 28, 43, 6, 248, 212, 13, 49, + 28, 43, 6, 231, 211, 13, 49, 28, 43, 6, 237, 106, 13, 49, 28, 43, 6, 234, + 47, 13, 49, 28, 43, 6, 191, 76, 13, 49, 28, 43, 6, 233, 253, 13, 49, 28, + 43, 6, 199, 15, 13, 49, 28, 43, 6, 223, 83, 13, 49, 28, 43, 6, 222, 72, + 13, 49, 28, 43, 6, 220, 31, 13, 49, 28, 43, 6, 215, 155, 13, 49, 28, 43, + 6, 212, 178, 13, 49, 28, 43, 6, 192, 207, 13, 49, 28, 43, 6, 211, 107, + 13, 49, 28, 43, 6, 209, 185, 13, 49, 28, 43, 6, 207, 3, 13, 49, 28, 43, + 6, 199, 16, 113, 13, 49, 28, 43, 6, 202, 196, 13, 49, 28, 43, 6, 199, + 166, 13, 49, 28, 43, 6, 196, 70, 13, 49, 28, 43, 6, 209, 211, 13, 49, 28, + 43, 6, 243, 95, 13, 49, 28, 43, 6, 208, 176, 13, 49, 28, 43, 6, 211, 110, + 13, 49, 28, 43, 214, 245, 13, 49, 28, 43, 2, 251, 160, 13, 49, 28, 43, 2, + 248, 212, 13, 49, 28, 43, 2, 231, 211, 13, 49, 28, 43, 2, 237, 106, 13, + 49, 28, 43, 2, 234, 47, 13, 49, 28, 43, 2, 191, 76, 13, 49, 28, 43, 2, + 233, 253, 13, 49, 28, 43, 2, 199, 15, 13, 49, 28, 43, 2, 223, 83, 13, 49, + 28, 43, 2, 222, 72, 13, 49, 28, 43, 2, 220, 31, 13, 49, 28, 43, 2, 215, + 155, 13, 49, 28, 43, 2, 212, 178, 13, 49, 28, 43, 2, 192, 207, 13, 49, + 28, 43, 2, 211, 107, 13, 49, 28, 43, 2, 209, 185, 13, 49, 28, 43, 2, 207, + 3, 13, 49, 28, 43, 2, 53, 202, 196, 13, 49, 28, 43, 2, 202, 196, 13, 49, + 28, 43, 2, 199, 166, 13, 49, 28, 43, 2, 196, 70, 13, 49, 28, 43, 2, 209, + 211, 13, 49, 28, 43, 2, 243, 95, 13, 49, 28, 43, 2, 208, 176, 13, 49, 28, + 43, 2, 211, 110, 13, 49, 28, 43, 210, 105, 237, 16, 13, 49, 28, 43, 234, + 48, 113, 13, 49, 28, 43, 199, 16, 113, 13, 49, 28, 43, 222, 73, 113, 13, + 49, 28, 43, 209, 212, 113, 13, 49, 28, 43, 207, 4, 113, 13, 49, 28, 43, + 209, 186, 113, 13, 28, 6, 237, 10, 13, 28, 2, 237, 10, 13, 28, 17, 191, + 77, 13, 28, 17, 107, 13, 28, 17, 109, 13, 28, 17, 138, 13, 28, 17, 134, + 13, 28, 17, 149, 13, 28, 17, 169, 13, 28, 17, 175, 13, 28, 17, 171, 13, + 28, 17, 178, 13, 235, 129, 17, 191, 77, 13, 235, 129, 17, 107, 13, 235, + 129, 17, 109, 13, 235, 129, 17, 138, 13, 235, 129, 17, 134, 13, 235, 129, + 17, 149, 13, 235, 129, 17, 169, 13, 235, 129, 17, 175, 13, 235, 129, 17, + 171, 13, 235, 129, 17, 178, 13, 49, 17, 191, 77, 13, 49, 17, 107, 13, 49, + 17, 109, 13, 49, 17, 138, 13, 49, 17, 134, 13, 49, 17, 149, 13, 49, 17, + 169, 13, 49, 17, 175, 13, 49, 17, 171, 13, 49, 17, 178, 13, 49, 28, 17, + 191, 77, 13, 49, 28, 17, 107, 13, 49, 28, 17, 109, 13, 49, 28, 17, 138, + 13, 49, 28, 17, 134, 13, 49, 28, 17, 149, 13, 49, 28, 17, 169, 13, 49, + 28, 17, 175, 13, 49, 28, 17, 171, 13, 49, 28, 17, 178, 13, 215, 217, 17, + 191, 77, 13, 215, 217, 17, 107, 13, 215, 217, 17, 109, 13, 215, 217, 17, + 138, 13, 215, 217, 17, 134, 13, 215, 217, 17, 149, 13, 215, 217, 17, 169, + 13, 215, 217, 17, 175, 13, 215, 217, 17, 171, 13, 215, 217, 17, 178, 24, + 151, 223, 148, 24, 230, 50, 223, 148, 24, 230, 46, 223, 148, 24, 230, 35, + 223, 148, 24, 230, 39, 223, 148, 24, 230, 52, 223, 148, 24, 151, 141, + 248, 223, 24, 230, 50, 141, 248, 223, 24, 151, 176, 196, 105, 141, 248, + 223, 24, 151, 141, 207, 147, 221, 70, 24, 151, 141, 238, 177, 24, 151, + 141, 229, 124, 24, 151, 141, 229, 125, 218, 241, 24, 230, 50, 141, 229, + 126, 24, 151, 141, 216, 84, 24, 230, 50, 141, 216, 84, 24, 151, 141, 82, + 248, 223, 24, 151, 141, 82, 207, 147, 221, 69, 24, 151, 141, 82, 229, + 124, 24, 151, 141, 133, 82, 229, 124, 24, 151, 141, 229, 125, 82, 196, + 77, 24, 151, 141, 82, 239, 46, 24, 151, 141, 82, 239, 47, 141, 248, 223, + 24, 151, 141, 82, 239, 47, 82, 248, 223, 24, 151, 141, 82, 239, 47, 238, + 177, 24, 151, 141, 82, 239, 47, 229, 124, 24, 151, 141, 82, 238, 213, 24, + 230, 50, 141, 82, 238, 213, 24, 151, 82, 248, 224, 139, 223, 148, 24, + 151, 141, 248, 224, 139, 216, 84, 24, 151, 141, 82, 198, 212, 24, 230, + 50, 141, 82, 198, 212, 24, 151, 141, 82, 201, 53, 176, 248, 223, 24, 151, + 141, 82, 248, 224, 176, 201, 52, 24, 151, 141, 82, 176, 248, 223, 24, + 151, 141, 82, 229, 125, 201, 199, 176, 202, 207, 24, 151, 141, 133, 82, + 229, 125, 176, 202, 207, 24, 151, 141, 133, 82, 229, 125, 176, 239, 46, + 24, 151, 141, 229, 125, 82, 133, 176, 202, 207, 24, 151, 141, 82, 133, + 201, 199, 176, 232, 132, 24, 151, 141, 82, 176, 238, 177, 24, 151, 141, + 82, 176, 243, 9, 24, 151, 141, 82, 176, 228, 249, 24, 151, 141, 82, 176, + 229, 124, 24, 151, 176, 248, 210, 141, 82, 201, 52, 24, 151, 141, 82, + 239, 47, 176, 202, 207, 24, 151, 141, 82, 239, 47, 176, 202, 208, 239, + 46, 24, 151, 141, 82, 239, 47, 176, 202, 208, 248, 223, 24, 151, 82, 176, + 228, 250, 141, 196, 77, 24, 151, 141, 176, 228, 250, 82, 196, 77, 24, + 151, 141, 82, 239, 47, 229, 125, 176, 202, 207, 24, 151, 141, 82, 238, + 214, 176, 202, 207, 24, 151, 141, 82, 239, 47, 176, 232, 132, 24, 151, + 141, 82, 239, 47, 238, 178, 176, 232, 132, 24, 151, 82, 176, 238, 178, + 141, 196, 77, 24, 151, 141, 176, 238, 178, 82, 196, 77, 24, 151, 82, 176, + 47, 141, 196, 77, 24, 151, 82, 176, 47, 141, 229, 124, 24, 151, 141, 176, + 251, 114, 211, 15, 82, 196, 77, 24, 151, 141, 176, 251, 114, 223, 163, + 82, 196, 77, 24, 151, 141, 176, 47, 82, 196, 77, 24, 151, 141, 82, 176, + 239, 47, 229, 124, 24, 151, 141, 82, 176, 251, 114, 211, 14, 24, 151, + 141, 82, 176, 251, 113, 24, 151, 82, 176, 251, 114, 211, 15, 141, 196, + 77, 24, 151, 82, 176, 251, 114, 211, 15, 141, 238, 213, 24, 151, 82, 176, + 251, 114, 141, 196, 77, 24, 151, 141, 176, 228, 250, 82, 229, 124, 24, + 230, 41, 232, 128, 232, 247, 24, 230, 41, 232, 128, 232, 248, 248, 223, + 24, 230, 41, 232, 128, 232, 248, 229, 124, 24, 230, 41, 232, 128, 232, + 248, 239, 46, 24, 230, 41, 232, 128, 232, 248, 239, 47, 201, 209, 24, + 230, 48, 232, 128, 232, 248, 239, 46, 24, 151, 232, 128, 232, 248, 239, + 47, 248, 223, 24, 230, 39, 232, 128, 232, 248, 239, 46, 24, 230, 41, 232, + 226, 232, 248, 201, 198, 24, 230, 41, 229, 213, 232, 226, 232, 248, 201, + 198, 24, 230, 41, 232, 226, 232, 248, 201, 199, 232, 128, 248, 223, 24, + 230, 41, 229, 213, 232, 226, 232, 248, 201, 199, 232, 128, 248, 223, 24, + 230, 41, 232, 226, 232, 248, 201, 199, 248, 223, 24, 230, 41, 229, 213, + 232, 226, 232, 248, 201, 199, 248, 223, 24, 230, 41, 232, 226, 232, 248, + 201, 199, 176, 232, 132, 24, 230, 46, 232, 226, 232, 248, 201, 198, 24, + 230, 46, 232, 226, 232, 248, 201, 199, 211, 76, 24, 230, 39, 232, 226, + 232, 248, 201, 199, 211, 76, 24, 230, 35, 232, 226, 232, 248, 201, 198, + 24, 230, 41, 232, 226, 232, 248, 201, 199, 229, 124, 24, 230, 41, 232, + 226, 232, 248, 201, 199, 229, 125, 176, 202, 207, 24, 230, 41, 232, 226, + 232, 248, 201, 199, 229, 125, 213, 44, 198, 212, 24, 230, 40, 24, 230, + 41, 248, 210, 210, 183, 233, 95, 24, 230, 41, 229, 212, 24, 230, 41, 176, + 202, 207, 24, 230, 41, 229, 213, 176, 202, 207, 24, 230, 41, 176, 248, + 223, 24, 230, 41, 176, 232, 132, 24, 230, 41, 201, 210, 141, 176, 202, + 207, 24, 230, 41, 201, 210, 247, 21, 24, 230, 41, 201, 210, 247, 22, 176, + 202, 207, 24, 230, 41, 201, 210, 247, 22, 176, 202, 208, 248, 223, 24, + 230, 41, 201, 210, 219, 82, 24, 230, 47, 24, 230, 48, 176, 202, 207, 24, + 230, 48, 213, 44, 198, 212, 24, 230, 48, 176, 232, 132, 24, 230, 37, 238, + 173, 24, 230, 36, 24, 230, 46, 211, 76, 24, 230, 45, 24, 230, 46, 211, + 77, 176, 202, 207, 24, 230, 46, 176, 202, 207, 24, 230, 46, 211, 77, 213, + 44, 198, 212, 24, 230, 46, 213, 44, 198, 212, 24, 230, 46, 211, 77, 176, + 232, 132, 24, 230, 46, 176, 232, 132, 24, 230, 44, 211, 76, 24, 230, 43, + 24, 230, 49, 24, 230, 34, 24, 230, 35, 176, 202, 207, 24, 230, 35, 213, + 44, 198, 212, 24, 230, 35, 176, 232, 132, 24, 230, 39, 211, 76, 24, 230, + 39, 211, 77, 176, 232, 132, 24, 230, 38, 24, 230, 39, 202, 70, 24, 230, + 39, 211, 77, 176, 202, 207, 24, 230, 39, 176, 202, 207, 24, 230, 39, 211, + 77, 213, 44, 198, 212, 24, 230, 39, 213, 44, 198, 212, 24, 230, 39, 176, + 202, 208, 198, 35, 223, 148, 24, 230, 39, 176, 248, 210, 82, 206, 188, + 24, 230, 51, 24, 151, 141, 82, 206, 188, 24, 230, 50, 141, 82, 206, 188, + 24, 230, 39, 141, 82, 206, 188, 24, 230, 52, 141, 82, 206, 188, 24, 230, + 39, 219, 82, 24, 151, 141, 82, 206, 189, 248, 223, 24, 151, 141, 82, 206, + 189, 239, 46, 24, 230, 39, 141, 82, 206, 189, 239, 46, 24, 151, 219, 83, + 235, 123, 24, 151, 219, 83, 144, 206, 183, 201, 52, 24, 151, 219, 83, + 144, 206, 183, 238, 162, 24, 151, 219, 83, 144, 211, 26, 243, 9, 24, 151, + 219, 83, 196, 77, 24, 151, 176, 196, 105, 219, 83, 196, 77, 24, 230, 50, + 219, 83, 196, 77, 24, 230, 35, 219, 83, 196, 77, 24, 230, 52, 219, 83, + 196, 77, 24, 151, 219, 83, 207, 147, 221, 70, 24, 151, 219, 83, 248, 223, + 24, 151, 219, 83, 198, 36, 198, 212, 24, 151, 219, 83, 198, 212, 24, 230, + 39, 219, 83, 198, 212, 24, 151, 219, 83, 141, 198, 212, 24, 230, 39, 219, + 83, 141, 198, 212, 24, 230, 52, 219, 83, 141, 176, 141, 176, 211, 14, 24, + 230, 52, 219, 83, 141, 176, 141, 198, 212, 24, 151, 219, 83, 223, 148, + 24, 230, 50, 219, 83, 223, 148, 24, 230, 39, 219, 83, 223, 148, 24, 230, + 52, 219, 83, 223, 148, 24, 151, 141, 82, 219, 82, 24, 230, 50, 141, 82, + 219, 82, 24, 230, 39, 141, 82, 219, 82, 24, 230, 39, 206, 188, 24, 230, + 52, 141, 82, 219, 82, 24, 151, 141, 82, 238, 218, 219, 82, 24, 230, 50, + 141, 82, 238, 218, 219, 82, 24, 151, 206, 189, 235, 123, 24, 230, 39, + 206, 189, 144, 141, 176, 228, 251, 216, 84, 24, 230, 52, 206, 189, 144, + 82, 176, 141, 238, 217, 24, 151, 206, 189, 196, 77, 24, 151, 206, 189, + 207, 147, 221, 70, 24, 151, 206, 189, 219, 82, 24, 230, 50, 206, 189, + 219, 82, 24, 230, 35, 206, 189, 219, 82, 24, 230, 52, 206, 189, 219, 82, + 24, 151, 206, 189, 216, 84, 24, 151, 206, 189, 82, 239, 46, 24, 151, 206, + 189, 82, 207, 147, 221, 69, 24, 151, 206, 189, 223, 148, 24, 151, 206, + 189, 198, 212, 24, 230, 37, 206, 189, 198, 212, 24, 151, 141, 206, 189, + 219, 82, 24, 230, 50, 141, 206, 189, 219, 82, 24, 230, 44, 141, 206, 189, + 219, 83, 211, 104, 24, 230, 37, 141, 206, 189, 219, 83, 211, 14, 24, 230, + 37, 141, 206, 189, 219, 83, 223, 162, 24, 230, 37, 141, 206, 189, 219, + 83, 196, 104, 24, 230, 46, 141, 206, 189, 219, 82, 24, 230, 39, 141, 206, + 189, 219, 82, 24, 230, 52, 141, 206, 189, 219, 83, 211, 14, 24, 230, 52, + 141, 206, 189, 219, 82, 24, 151, 82, 235, 123, 24, 230, 39, 216, 84, 24, + 151, 82, 196, 77, 24, 230, 50, 82, 196, 77, 24, 151, 82, 207, 147, 221, + 70, 24, 151, 82, 133, 176, 202, 207, 24, 230, 37, 82, 198, 212, 24, 151, + 82, 176, 219, 82, 24, 151, 82, 219, 82, 24, 151, 82, 206, 189, 219, 82, + 24, 230, 50, 82, 206, 189, 219, 82, 24, 230, 44, 82, 206, 189, 219, 83, + 211, 104, 24, 230, 46, 82, 206, 189, 219, 82, 24, 230, 39, 82, 206, 189, + 219, 82, 24, 230, 52, 82, 206, 189, 219, 83, 211, 14, 24, 230, 52, 82, + 206, 189, 219, 83, 223, 162, 24, 230, 52, 82, 206, 189, 219, 82, 24, 230, + 50, 82, 206, 189, 219, 83, 248, 223, 24, 230, 48, 82, 206, 189, 219, 83, + 239, 46, 24, 230, 48, 82, 206, 189, 219, 83, 239, 47, 202, 207, 24, 230, + 37, 82, 206, 189, 219, 83, 239, 47, 211, 14, 24, 230, 37, 82, 206, 189, + 219, 83, 239, 47, 223, 162, 24, 230, 37, 82, 206, 189, 219, 83, 239, 46, + 24, 230, 39, 141, 229, 124, 24, 151, 141, 176, 202, 207, 24, 230, 39, + 141, 176, 202, 207, 24, 151, 141, 176, 202, 208, 176, 237, 38, 24, 151, + 141, 176, 202, 208, 176, 239, 46, 24, 151, 141, 176, 202, 208, 176, 248, + 223, 24, 151, 141, 176, 202, 208, 141, 248, 223, 24, 151, 141, 176, 202, + 208, 248, 80, 248, 223, 24, 151, 141, 176, 202, 208, 141, 229, 126, 24, + 151, 141, 176, 232, 133, 141, 201, 52, 24, 151, 141, 176, 232, 133, 141, + 248, 223, 24, 151, 141, 176, 102, 24, 151, 141, 176, 238, 173, 24, 151, + 141, 176, 238, 165, 176, 223, 117, 24, 230, 48, 141, 176, 238, 165, 176, + 223, 117, 24, 151, 141, 176, 238, 165, 176, 196, 104, 24, 151, 141, 176, + 243, 10, 24, 230, 46, 141, 198, 212, 24, 230, 46, 141, 176, 211, 76, 24, + 230, 39, 141, 176, 211, 76, 24, 230, 39, 141, 176, 220, 12, 24, 230, 39, + 141, 198, 212, 24, 230, 39, 141, 176, 202, 70, 24, 230, 52, 141, 176, + 211, 14, 24, 230, 52, 141, 176, 223, 162, 24, 230, 52, 141, 198, 212, 24, + 151, 198, 212, 24, 151, 176, 229, 212, 24, 151, 176, 202, 208, 237, 38, + 24, 151, 176, 202, 208, 239, 46, 24, 151, 176, 202, 208, 248, 223, 24, + 151, 176, 232, 132, 24, 151, 176, 248, 210, 141, 216, 84, 24, 151, 176, + 248, 210, 82, 206, 188, 24, 151, 176, 248, 210, 206, 189, 219, 82, 24, + 151, 176, 196, 105, 105, 232, 247, 24, 151, 176, 139, 105, 232, 247, 24, + 151, 176, 196, 105, 115, 232, 247, 24, 151, 176, 196, 105, 232, 128, 232, + 247, 24, 151, 176, 139, 232, 128, 207, 147, 221, 69, 24, 230, 42, 24, + 151, 229, 212, 24, 198, 37, 202, 169, 24, 198, 37, 215, 128, 24, 198, 37, + 248, 209, 24, 230, 215, 202, 169, 24, 230, 215, 215, 128, 24, 230, 215, + 248, 209, 24, 201, 33, 202, 169, 24, 201, 33, 215, 128, 24, 201, 33, 248, + 209, 24, 248, 18, 202, 169, 24, 248, 18, 215, 128, 24, 248, 18, 248, 209, + 24, 206, 60, 202, 169, 24, 206, 60, 215, 128, 24, 206, 60, 248, 209, 24, + 200, 171, 200, 76, 24, 200, 171, 248, 209, 24, 201, 186, 220, 13, 202, + 169, 24, 201, 186, 2, 202, 169, 24, 201, 186, 220, 13, 215, 128, 24, 201, + 186, 2, 215, 128, 24, 201, 186, 204, 6, 24, 232, 197, 220, 13, 202, 169, + 24, 232, 197, 2, 202, 169, 24, 232, 197, 220, 13, 215, 128, 24, 232, 197, + 2, 215, 128, 24, 232, 197, 204, 6, 24, 201, 186, 232, 197, 251, 154, 24, + 215, 172, 133, 144, 220, 12, 24, 215, 172, 133, 144, 202, 70, 24, 215, + 172, 133, 204, 6, 24, 215, 172, 144, 204, 6, 24, 215, 172, 133, 144, 251, + 155, 220, 12, 24, 215, 172, 133, 144, 251, 155, 202, 70, 24, 215, 172, + 202, 208, 119, 202, 208, 205, 84, 24, 215, 171, 232, 253, 239, 35, 24, + 215, 173, 232, 253, 239, 35, 24, 215, 171, 202, 170, 201, 53, 202, 70, + 24, 215, 171, 202, 170, 201, 53, 216, 212, 24, 215, 171, 202, 170, 201, + 53, 220, 12, 24, 215, 171, 202, 170, 201, 53, 220, 10, 24, 215, 171, 202, + 170, 193, 4, 232, 200, 24, 215, 171, 55, 201, 52, 24, 215, 171, 55, 193, + 4, 232, 200, 24, 215, 171, 55, 251, 154, 24, 215, 171, 55, 251, 155, 193, + 4, 232, 200, 24, 215, 171, 238, 217, 24, 215, 171, 197, 225, 201, 53, + 215, 175, 24, 215, 171, 197, 225, 193, 4, 232, 200, 24, 215, 171, 197, + 225, 251, 154, 24, 215, 171, 197, 225, 251, 155, 193, 4, 232, 200, 24, + 215, 171, 248, 228, 202, 70, 24, 215, 171, 248, 228, 216, 212, 24, 215, + 171, 248, 228, 220, 12, 24, 215, 171, 239, 2, 202, 70, 24, 215, 171, 239, + 2, 216, 212, 24, 215, 171, 239, 2, 220, 12, 24, 215, 171, 239, 2, 206, + 120, 24, 215, 171, 243, 126, 202, 70, 24, 215, 171, 243, 126, 216, 212, + 24, 215, 171, 243, 126, 220, 12, 24, 215, 171, 111, 202, 70, 24, 215, + 171, 111, 216, 212, 24, 215, 171, 111, 220, 12, 24, 215, 171, 191, 21, + 202, 70, 24, 215, 171, 191, 21, 216, 212, 24, 215, 171, 191, 21, 220, 12, + 24, 215, 171, 210, 57, 202, 70, 24, 215, 171, 210, 57, 216, 212, 24, 215, + 171, 210, 57, 220, 12, 24, 198, 3, 206, 118, 202, 169, 24, 198, 3, 206, + 118, 235, 133, 24, 198, 3, 206, 118, 251, 154, 24, 198, 3, 206, 119, 202, + 169, 24, 198, 3, 206, 119, 235, 133, 24, 198, 3, 206, 119, 251, 154, 24, + 198, 3, 203, 144, 24, 198, 3, 250, 251, 201, 218, 202, 169, 24, 198, 3, + 250, 251, 201, 218, 235, 133, 24, 198, 3, 250, 251, 201, 218, 197, 224, + 24, 215, 174, 250, 139, 202, 70, 24, 215, 174, 250, 139, 216, 212, 24, + 215, 174, 250, 139, 220, 12, 24, 215, 174, 250, 139, 220, 10, 24, 215, + 174, 198, 31, 202, 70, 24, 215, 174, 198, 31, 216, 212, 24, 215, 174, + 198, 31, 220, 12, 24, 215, 174, 198, 31, 220, 10, 24, 215, 174, 248, 210, + 250, 139, 202, 70, 24, 215, 174, 248, 210, 250, 139, 216, 212, 24, 215, + 174, 248, 210, 250, 139, 220, 12, 24, 215, 174, 248, 210, 250, 139, 220, + 10, 24, 215, 174, 248, 210, 198, 31, 202, 70, 24, 215, 174, 248, 210, + 198, 31, 216, 212, 24, 215, 174, 248, 210, 198, 31, 220, 12, 24, 215, + 174, 248, 210, 198, 31, 220, 10, 24, 215, 173, 202, 170, 201, 53, 202, + 70, 24, 215, 173, 202, 170, 201, 53, 216, 212, 24, 215, 173, 202, 170, + 201, 53, 220, 12, 24, 215, 173, 202, 170, 201, 53, 220, 10, 24, 215, 173, + 202, 170, 193, 4, 232, 200, 24, 215, 173, 55, 201, 52, 24, 215, 173, 55, + 193, 4, 232, 200, 24, 215, 173, 55, 251, 154, 24, 215, 173, 55, 251, 155, + 193, 4, 232, 200, 24, 215, 173, 238, 217, 24, 215, 173, 197, 225, 201, + 53, 215, 175, 24, 215, 173, 197, 225, 193, 4, 232, 200, 24, 215, 173, + 197, 225, 251, 155, 215, 175, 24, 215, 173, 197, 225, 251, 155, 193, 4, + 232, 200, 24, 215, 173, 248, 227, 24, 215, 173, 239, 2, 202, 70, 24, 215, + 173, 239, 2, 216, 212, 24, 215, 173, 239, 2, 220, 12, 24, 215, 173, 243, + 125, 24, 215, 173, 111, 202, 70, 24, 215, 173, 111, 216, 212, 24, 215, + 173, 111, 220, 12, 24, 215, 173, 191, 21, 202, 70, 24, 215, 173, 191, 21, + 216, 212, 24, 215, 173, 191, 21, 220, 12, 24, 215, 173, 210, 57, 202, 70, + 24, 215, 173, 210, 57, 216, 212, 24, 215, 173, 210, 57, 220, 12, 24, 198, + 4, 206, 119, 202, 169, 24, 198, 4, 206, 119, 235, 133, 24, 198, 4, 206, + 119, 251, 154, 24, 198, 4, 206, 118, 202, 169, 24, 198, 4, 206, 118, 235, + 133, 24, 198, 4, 206, 118, 251, 154, 24, 198, 4, 203, 144, 24, 215, 171, + 238, 165, 208, 23, 202, 70, 24, 215, 171, 238, 165, 208, 23, 216, 212, + 24, 215, 171, 238, 165, 208, 23, 220, 12, 24, 215, 171, 238, 165, 208, + 23, 220, 10, 24, 215, 171, 238, 165, 230, 67, 202, 70, 24, 215, 171, 238, + 165, 230, 67, 216, 212, 24, 215, 171, 238, 165, 230, 67, 220, 12, 24, + 215, 171, 238, 165, 230, 67, 220, 10, 24, 215, 171, 238, 165, 198, 218, + 243, 11, 202, 70, 24, 215, 171, 238, 165, 198, 218, 243, 11, 216, 212, + 24, 215, 171, 228, 143, 202, 70, 24, 215, 171, 228, 143, 216, 212, 24, + 215, 171, 228, 143, 220, 12, 24, 215, 171, 219, 5, 202, 70, 24, 215, 171, + 219, 5, 216, 212, 24, 215, 171, 219, 5, 220, 12, 24, 215, 171, 219, 5, 2, + 235, 133, 24, 215, 171, 193, 139, 238, 165, 55, 202, 70, 24, 215, 171, + 193, 139, 238, 165, 55, 216, 212, 24, 215, 171, 193, 139, 238, 165, 55, + 220, 12, 24, 215, 171, 193, 139, 238, 165, 197, 225, 202, 70, 24, 215, + 171, 193, 139, 238, 165, 197, 225, 216, 212, 24, 215, 171, 193, 139, 238, + 165, 197, 225, 220, 12, 24, 215, 171, 238, 165, 199, 25, 201, 52, 24, + 215, 171, 238, 163, 238, 218, 202, 70, 24, 215, 171, 238, 163, 238, 218, + 216, 212, 24, 206, 118, 202, 169, 24, 206, 118, 235, 133, 24, 206, 118, + 251, 156, 24, 215, 171, 203, 144, 24, 215, 171, 238, 165, 229, 116, 232, + 97, 193, 167, 24, 215, 171, 228, 143, 229, 116, 232, 97, 193, 167, 24, + 215, 171, 219, 5, 229, 116, 232, 97, 193, 167, 24, 215, 171, 193, 139, + 229, 116, 232, 97, 193, 167, 24, 206, 118, 202, 170, 229, 116, 232, 97, + 193, 167, 24, 206, 118, 55, 229, 116, 232, 97, 193, 167, 24, 206, 118, + 251, 155, 229, 116, 232, 97, 193, 167, 24, 215, 171, 238, 165, 229, 116, + 243, 104, 24, 215, 171, 228, 143, 229, 116, 243, 104, 24, 215, 171, 219, + 5, 229, 116, 243, 104, 24, 215, 171, 193, 139, 229, 116, 243, 104, 24, + 206, 118, 202, 170, 229, 116, 243, 104, 24, 206, 118, 55, 229, 116, 243, + 104, 24, 206, 118, 251, 155, 229, 116, 243, 104, 24, 215, 171, 193, 139, + 237, 39, 210, 86, 202, 70, 24, 215, 171, 193, 139, 237, 39, 210, 86, 216, + 212, 24, 215, 171, 193, 139, 237, 39, 210, 86, 220, 12, 24, 215, 173, + 238, 165, 229, 116, 247, 31, 202, 70, 24, 215, 173, 238, 165, 229, 116, + 247, 31, 220, 12, 24, 215, 173, 228, 143, 229, 116, 247, 31, 2, 235, 133, + 24, 215, 173, 228, 143, 229, 116, 247, 31, 220, 13, 235, 133, 24, 215, + 173, 228, 143, 229, 116, 247, 31, 2, 197, 224, 24, 215, 173, 228, 143, + 229, 116, 247, 31, 220, 13, 197, 224, 24, 215, 173, 219, 5, 229, 116, + 247, 31, 2, 202, 169, 24, 215, 173, 219, 5, 229, 116, 247, 31, 220, 13, + 202, 169, 24, 215, 173, 219, 5, 229, 116, 247, 31, 2, 235, 133, 24, 215, + 173, 219, 5, 229, 116, 247, 31, 220, 13, 235, 133, 24, 215, 173, 193, + 139, 229, 116, 247, 31, 202, 70, 24, 215, 173, 193, 139, 229, 116, 247, + 31, 220, 12, 24, 206, 119, 202, 170, 229, 116, 247, 30, 24, 206, 119, 55, + 229, 116, 247, 30, 24, 206, 119, 251, 155, 229, 116, 247, 30, 24, 215, + 173, 238, 165, 229, 116, 232, 194, 202, 70, 24, 215, 173, 238, 165, 229, + 116, 232, 194, 220, 12, 24, 215, 173, 228, 143, 229, 116, 232, 194, 2, + 235, 133, 24, 215, 173, 228, 143, 229, 116, 232, 194, 220, 13, 235, 133, + 24, 215, 173, 228, 143, 229, 116, 232, 194, 197, 225, 2, 197, 224, 24, + 215, 173, 228, 143, 229, 116, 232, 194, 197, 225, 220, 13, 197, 224, 24, + 215, 173, 219, 5, 229, 116, 232, 194, 2, 202, 169, 24, 215, 173, 219, 5, + 229, 116, 232, 194, 220, 13, 202, 169, 24, 215, 173, 219, 5, 229, 116, + 232, 194, 2, 235, 133, 24, 215, 173, 219, 5, 229, 116, 232, 194, 220, 13, + 235, 133, 24, 215, 173, 193, 139, 229, 116, 232, 194, 202, 70, 24, 215, + 173, 193, 139, 229, 116, 232, 194, 220, 12, 24, 206, 119, 202, 170, 229, + 116, 232, 193, 24, 206, 119, 55, 229, 116, 232, 193, 24, 206, 119, 251, + 155, 229, 116, 232, 193, 24, 215, 173, 238, 165, 202, 70, 24, 215, 173, + 238, 165, 216, 212, 24, 215, 173, 238, 165, 220, 12, 24, 215, 173, 238, + 165, 220, 10, 24, 215, 173, 238, 165, 242, 78, 24, 215, 173, 228, 143, + 202, 70, 24, 215, 173, 219, 5, 202, 70, 24, 215, 173, 193, 139, 202, 58, + 24, 215, 173, 193, 139, 202, 70, 24, 215, 173, 193, 139, 220, 12, 24, + 206, 119, 202, 169, 24, 206, 119, 235, 133, 24, 206, 119, 251, 154, 24, + 215, 173, 203, 145, 210, 118, 24, 215, 171, 250, 251, 243, 11, 2, 202, + 169, 24, 215, 171, 250, 251, 243, 11, 216, 213, 202, 169, 24, 215, 171, + 250, 251, 243, 11, 2, 235, 133, 24, 215, 171, 250, 251, 243, 11, 216, + 213, 235, 133, 24, 215, 173, 250, 251, 243, 11, 229, 116, 193, 168, 2, + 202, 169, 24, 215, 173, 250, 251, 243, 11, 229, 116, 193, 168, 216, 213, + 202, 169, 24, 215, 173, 250, 251, 243, 11, 229, 116, 193, 168, 220, 13, + 202, 169, 24, 215, 173, 250, 251, 243, 11, 229, 116, 193, 168, 2, 235, + 133, 24, 215, 173, 250, 251, 243, 11, 229, 116, 193, 168, 216, 213, 235, + 133, 24, 215, 173, 250, 251, 243, 11, 229, 116, 193, 168, 220, 13, 235, + 133, 24, 215, 171, 193, 4, 243, 11, 232, 97, 202, 169, 24, 215, 171, 193, + 4, 243, 11, 232, 97, 235, 133, 24, 215, 173, 193, 4, 243, 11, 229, 116, + 193, 168, 202, 169, 24, 215, 173, 193, 4, 243, 11, 229, 116, 193, 168, + 235, 133, 24, 215, 171, 232, 253, 243, 8, 202, 169, 24, 215, 171, 232, + 253, 243, 8, 235, 133, 24, 215, 173, 232, 253, 243, 8, 229, 116, 193, + 168, 202, 169, 24, 215, 173, 232, 253, 243, 8, 229, 116, 193, 168, 235, + 133, 24, 235, 40, 250, 236, 202, 70, 24, 235, 40, 250, 236, 220, 12, 24, + 235, 40, 233, 73, 24, 235, 40, 202, 75, 24, 235, 40, 199, 88, 24, 235, + 40, 207, 63, 24, 235, 40, 202, 176, 24, 235, 40, 202, 177, 251, 154, 24, + 235, 40, 233, 225, 211, 27, 198, 146, 24, 235, 40, 230, 226, 24, 229, + 235, 24, 229, 236, 206, 193, 24, 229, 236, 215, 171, 201, 52, 24, 229, + 236, 215, 171, 198, 149, 24, 229, 236, 215, 173, 201, 52, 24, 229, 236, + 215, 171, 238, 164, 24, 229, 236, 215, 173, 238, 164, 24, 229, 236, 215, + 176, 243, 10, 24, 233, 104, 236, 233, 209, 25, 213, 14, 232, 133, 198, + 147, 24, 233, 104, 236, 233, 209, 25, 213, 14, 133, 211, 57, 235, 123, + 24, 233, 104, 236, 233, 209, 25, 213, 14, 133, 211, 57, 144, 198, 147, + 24, 233, 191, 201, 53, 196, 77, 24, 233, 191, 201, 53, 214, 81, 24, 233, + 191, 201, 53, 235, 123, 24, 235, 107, 233, 191, 214, 82, 235, 123, 24, + 235, 107, 233, 191, 144, 214, 81, 24, 235, 107, 233, 191, 133, 214, 81, + 24, 235, 107, 233, 191, 214, 82, 196, 77, 24, 232, 151, 214, 81, 24, 232, + 151, 239, 35, 24, 232, 151, 193, 7, 24, 233, 186, 211, 76, 24, 233, 186, + 201, 185, 24, 233, 186, 242, 218, 24, 233, 194, 248, 130, 202, 169, 24, + 233, 194, 248, 130, 215, 128, 24, 233, 186, 132, 211, 76, 24, 233, 186, + 193, 78, 211, 76, 24, 233, 186, 132, 242, 218, 24, 233, 186, 193, 76, + 215, 175, 24, 233, 194, 193, 58, 24, 233, 187, 196, 77, 24, 233, 187, + 235, 123, 24, 233, 187, 232, 180, 24, 233, 189, 201, 52, 24, 233, 189, + 201, 53, 235, 133, 24, 233, 189, 201, 53, 251, 154, 24, 233, 190, 201, + 52, 24, 233, 190, 201, 53, 235, 133, 24, 233, 190, 201, 53, 251, 154, 24, + 233, 189, 238, 162, 24, 233, 190, 238, 162, 24, 233, 189, 243, 5, 24, + 243, 121, 208, 155, 24, 243, 121, 214, 81, 24, 243, 121, 200, 218, 24, + 199, 89, 243, 121, 229, 135, 24, 199, 89, 243, 121, 216, 84, 24, 199, 89, + 243, 121, 218, 241, 24, 234, 209, 24, 213, 14, 214, 81, 24, 213, 14, 239, + 35, 24, 213, 14, 193, 5, 24, 213, 14, 193, 73, 24, 251, 226, 248, 116, + 211, 14, 24, 251, 226, 200, 217, 223, 162, 24, 251, 226, 248, 118, 2, + 206, 117, 24, 251, 226, 200, 219, 2, 206, 117, 24, 248, 39, 223, 134, 24, + 248, 39, 233, 214, 24, 215, 180, 242, 219, 214, 81, 24, 215, 180, 242, + 219, 232, 132, 24, 215, 180, 242, 219, 239, 35, 24, 215, 180, 202, 65, + 24, 215, 180, 202, 66, 193, 7, 24, 215, 180, 202, 66, 211, 76, 24, 215, + 180, 232, 93, 24, 215, 180, 232, 94, 193, 7, 24, 215, 180, 232, 94, 211, + 76, 24, 215, 180, 211, 77, 243, 10, 24, 215, 180, 211, 77, 232, 132, 24, + 215, 180, 211, 77, 193, 7, 24, 215, 180, 211, 77, 211, 7, 24, 215, 180, + 211, 77, 211, 8, 193, 7, 24, 215, 180, 211, 77, 211, 8, 192, 88, 24, 215, + 180, 211, 77, 207, 92, 24, 215, 180, 211, 77, 207, 93, 193, 7, 24, 215, + 180, 211, 77, 207, 93, 192, 88, 24, 215, 180, 221, 122, 24, 215, 180, + 221, 123, 232, 132, 24, 215, 180, 221, 123, 193, 7, 24, 215, 180, 199, + 88, 24, 215, 180, 199, 89, 232, 132, 24, 215, 180, 199, 89, 200, 218, 24, + 219, 97, 208, 219, 198, 87, 24, 219, 99, 110, 139, 196, 74, 24, 219, 99, + 116, 139, 218, 236, 24, 215, 180, 239, 0, 24, 215, 180, 193, 6, 202, 169, + 24, 215, 180, 193, 6, 235, 133, 24, 198, 62, 201, 74, 211, 15, 233, 75, + 24, 198, 62, 219, 142, 219, 96, 24, 198, 62, 198, 136, 248, 210, 219, 96, + 24, 198, 62, 198, 136, 198, 35, 223, 118, 215, 179, 24, 198, 62, 223, + 118, 215, 180, 207, 63, 24, 198, 62, 215, 170, 251, 251, 243, 122, 24, + 198, 62, 247, 22, 201, 74, 211, 14, 24, 198, 62, 247, 22, 223, 118, 215, + 179, 24, 199, 117, 24, 199, 118, 215, 175, 24, 199, 118, 211, 105, 198, + 61, 24, 199, 118, 211, 105, 198, 62, 215, 175, 24, 199, 118, 211, 105, + 219, 96, 24, 199, 118, 211, 105, 219, 97, 215, 175, 24, 199, 118, 248, + 146, 219, 96, 24, 215, 171, 223, 14, 24, 215, 173, 223, 14, 24, 214, 112, + 24, 230, 78, 24, 233, 217, 24, 203, 22, 229, 123, 201, 219, 24, 203, 22, + 229, 123, 209, 23, 24, 193, 165, 203, 22, 229, 123, 215, 178, 24, 232, + 192, 203, 22, 229, 123, 215, 178, 24, 203, 22, 198, 148, 232, 98, 193, + 172, 24, 198, 43, 201, 53, 201, 37, 24, 198, 43, 238, 163, 248, 227, 24, + 198, 44, 197, 16, 24, 116, 248, 105, 198, 148, 232, 98, 229, 123, 222, + 195, 24, 219, 124, 242, 79, 24, 219, 124, 219, 197, 24, 219, 124, 219, + 196, 24, 219, 124, 219, 195, 24, 219, 124, 219, 194, 24, 219, 124, 219, + 193, 24, 219, 124, 219, 192, 24, 219, 124, 219, 191, 24, 232, 252, 24, + 219, 37, 201, 247, 24, 219, 38, 201, 247, 24, 219, 40, 229, 208, 24, 219, + 40, 193, 74, 24, 219, 40, 237, 92, 24, 219, 40, 229, 236, 214, 112, 24, + 219, 40, 198, 45, 24, 219, 40, 219, 123, 237, 9, 24, 242, 74, 24, 232, + 80, 201, 63, 24, 204, 25, 24, 242, 83, 24, 210, 113, 24, 233, 6, 215, + 244, 24, 233, 6, 215, 243, 24, 233, 6, 215, 242, 24, 233, 6, 215, 241, + 24, 233, 6, 215, 240, 24, 206, 121, 215, 244, 24, 206, 121, 215, 243, 24, + 206, 121, 215, 242, 24, 206, 121, 215, 241, 24, 206, 121, 215, 240, 24, + 206, 121, 215, 239, 24, 206, 121, 215, 238, 24, 206, 121, 215, 237, 24, + 206, 121, 215, 251, 24, 206, 121, 215, 250, 24, 206, 121, 215, 249, 24, + 206, 121, 215, 248, 24, 206, 121, 215, 247, 24, 206, 121, 215, 246, 24, + 206, 121, 215, 245, 8, 2, 1, 233, 37, 237, 3, 4, 197, 228, 8, 2, 1, 207, + 18, 27, 232, 51, 8, 1, 2, 6, 153, 232, 51, 8, 2, 1, 207, 18, 222, 152, 8, + 1, 2, 6, 220, 143, 4, 248, 231, 8, 2, 1, 219, 163, 4, 207, 24, 102, 8, 2, + 1, 153, 192, 160, 4, 248, 231, 8, 2, 1, 207, 18, 234, 88, 8, 2, 1, 153, + 207, 222, 4, 179, 219, 213, 23, 207, 24, 102, 8, 2, 1, 200, 44, 4, 228, + 251, 23, 207, 24, 102, 8, 1, 207, 24, 242, 232, 4, 207, 24, 102, 8, 2, 1, + 234, 13, 4, 55, 164, 8, 2, 1, 234, 13, 4, 55, 249, 88, 23, 238, 175, 8, + 2, 1, 153, 200, 44, 4, 238, 175, 8, 1, 223, 93, 231, 11, 201, 64, 4, 238, + 175, 8, 1, 201, 36, 247, 194, 4, 238, 175, 8, 1, 2, 6, 153, 222, 152, 8, + 2, 1, 220, 143, 4, 232, 233, 8, 2, 1, 237, 70, 237, 3, 4, 210, 192, 102, + 8, 2, 1, 220, 143, 4, 248, 232, 23, 210, 192, 102, 8, 2, 1, 234, 89, 4, + 210, 192, 102, 8, 2, 1, 153, 207, 222, 4, 210, 192, 102, 8, 2, 1, 207, + 222, 4, 232, 234, 23, 210, 192, 102, 8, 2, 1, 199, 79, 237, 3, 4, 210, + 192, 102, 8, 2, 1, 233, 179, 4, 210, 192, 102, 8, 2, 1, 237, 70, 237, 3, + 4, 207, 24, 102, 8, 2, 1, 228, 74, 4, 201, 28, 23, 207, 24, 102, 8, 2, 1, + 187, 4, 207, 24, 102, 8, 2, 1, 199, 79, 237, 3, 4, 207, 24, 102, 8, 2, 1, + 247, 194, 4, 207, 24, 102, 8, 2, 1, 206, 9, 4, 238, 175, 8, 2, 1, 238, + 128, 4, 216, 86, 45, 102, 8, 2, 1, 220, 143, 4, 216, 86, 45, 102, 8, 2, + 1, 215, 62, 4, 216, 86, 45, 102, 8, 2, 1, 207, 222, 4, 216, 86, 45, 102, + 8, 2, 1, 206, 9, 4, 216, 86, 45, 102, 8, 2, 1, 200, 44, 4, 216, 86, 45, + 102, 33, 135, 1, 250, 122, 33, 135, 1, 247, 252, 33, 135, 1, 195, 151, + 33, 135, 1, 231, 18, 33, 135, 1, 236, 169, 33, 135, 1, 192, 49, 33, 135, + 1, 191, 55, 33, 135, 1, 191, 82, 33, 135, 1, 223, 39, 33, 135, 1, 89, + 223, 39, 33, 135, 1, 68, 33, 135, 1, 236, 190, 33, 135, 1, 222, 94, 33, + 135, 1, 219, 75, 33, 135, 1, 215, 66, 33, 135, 1, 214, 210, 33, 135, 1, + 211, 89, 33, 135, 1, 209, 55, 33, 135, 1, 206, 179, 33, 135, 1, 202, 77, + 33, 135, 1, 197, 44, 33, 135, 1, 196, 124, 33, 135, 1, 232, 101, 33, 135, + 1, 229, 188, 33, 135, 1, 203, 8, 33, 135, 1, 197, 146, 33, 135, 1, 243, + 54, 33, 135, 1, 203, 165, 33, 135, 1, 192, 58, 33, 135, 1, 192, 60, 33, + 135, 1, 192, 93, 33, 135, 1, 191, 225, 33, 135, 1, 2, 191, 190, 33, 135, + 1, 192, 12, 33, 135, 1, 223, 82, 2, 191, 190, 33, 135, 1, 248, 175, 191, + 190, 33, 135, 1, 223, 82, 248, 175, 191, 190, 33, 135, 1, 232, 228, 52, + 1, 38, 2, 65, 52, 1, 38, 2, 249, 17, 52, 1, 38, 2, 195, 153, 52, 1, 38, + 2, 231, 77, 52, 1, 38, 2, 237, 146, 52, 1, 38, 2, 223, 226, 52, 1, 38, 2, + 191, 62, 52, 1, 38, 2, 191, 87, 52, 1, 38, 2, 68, 52, 1, 38, 2, 155, 52, + 1, 38, 2, 234, 140, 52, 1, 38, 2, 234, 114, 52, 1, 38, 2, 74, 52, 1, 38, + 2, 210, 63, 52, 1, 38, 2, 234, 34, 52, 1, 38, 2, 234, 22, 52, 1, 38, 2, + 199, 145, 52, 1, 38, 2, 66, 52, 1, 38, 2, 234, 181, 52, 1, 38, 2, 140, + 52, 1, 38, 2, 197, 161, 52, 1, 38, 2, 243, 127, 52, 1, 38, 2, 203, 165, + 52, 1, 38, 2, 192, 58, 52, 1, 38, 2, 71, 52, 1, 38, 2, 191, 225, 52, 1, + 38, 2, 235, 17, 52, 1, 38, 2, 205, 86, 52, 1, 38, 2, 247, 203, 68, 52, 1, + 38, 2, 223, 10, 52, 1, 38, 2, 249, 82, 74, 52, 1, 38, 2, 201, 53, 66, 52, + 1, 38, 2, 210, 179, 38, 200, 230, 2, 1, 65, 38, 200, 230, 2, 1, 249, 17, + 38, 200, 230, 2, 1, 195, 153, 38, 200, 230, 2, 1, 231, 77, 38, 200, 230, + 2, 1, 237, 146, 38, 200, 230, 2, 1, 223, 226, 38, 200, 230, 2, 1, 191, + 62, 38, 200, 230, 2, 1, 191, 87, 38, 200, 230, 2, 1, 68, 38, 200, 230, 2, + 1, 155, 38, 200, 230, 2, 1, 234, 140, 38, 200, 230, 2, 1, 74, 38, 200, + 230, 2, 1, 210, 63, 38, 200, 230, 2, 1, 234, 22, 38, 200, 230, 2, 1, 66, + 38, 200, 230, 2, 1, 234, 181, 38, 200, 230, 2, 1, 140, 38, 200, 230, 2, + 1, 197, 161, 38, 200, 230, 2, 1, 243, 127, 38, 200, 230, 2, 1, 203, 165, + 38, 200, 230, 2, 1, 230, 17, 56, 38, 200, 230, 2, 1, 192, 58, 38, 200, + 230, 2, 1, 231, 78, 4, 196, 69, 38, 200, 230, 2, 1, 247, 203, 68, 38, + 200, 230, 2, 1, 235, 32, 38, 200, 230, 2, 1, 235, 28, 52, 1, 38, 2, 234, + 23, 4, 237, 87, 52, 1, 38, 2, 192, 59, 4, 249, 147, 192, 62, 52, 1, 38, + 2, 201, 53, 126, 4, 106, 33, 38, 2, 1, 247, 203, 68, 212, 80, 208, 162, + 90, 1, 174, 212, 80, 208, 162, 90, 1, 197, 168, 212, 80, 208, 162, 90, 1, + 212, 199, 212, 80, 208, 162, 90, 1, 190, 190, 212, 80, 208, 162, 90, 1, + 140, 212, 80, 208, 162, 90, 1, 180, 212, 80, 208, 162, 90, 1, 192, 220, + 212, 80, 208, 162, 90, 1, 213, 111, 212, 80, 208, 162, 90, 1, 247, 160, + 212, 80, 208, 162, 90, 1, 173, 212, 80, 208, 162, 90, 1, 188, 212, 80, + 208, 162, 90, 1, 191, 123, 212, 80, 208, 162, 90, 1, 214, 166, 212, 80, + 208, 162, 90, 1, 212, 186, 212, 80, 208, 162, 90, 1, 155, 212, 80, 208, + 162, 90, 1, 238, 32, 212, 80, 208, 162, 90, 1, 212, 101, 212, 80, 208, + 162, 90, 1, 212, 244, 212, 80, 208, 162, 90, 1, 195, 188, 212, 80, 208, + 162, 90, 1, 212, 180, 212, 80, 208, 162, 90, 1, 197, 8, 212, 80, 208, + 162, 90, 1, 233, 109, 212, 80, 208, 162, 90, 1, 165, 212, 80, 208, 162, + 90, 1, 208, 96, 212, 80, 208, 162, 90, 1, 170, 212, 80, 208, 162, 90, 1, + 212, 246, 212, 80, 208, 162, 90, 1, 168, 212, 80, 208, 162, 90, 1, 192, + 175, 212, 80, 208, 162, 90, 1, 212, 248, 212, 80, 208, 162, 90, 1, 236, + 186, 212, 80, 208, 162, 90, 1, 212, 247, 212, 80, 208, 162, 90, 1, 230, + 81, 212, 80, 208, 162, 90, 1, 216, 19, 212, 80, 208, 162, 90, 1, 209, + 110, 212, 80, 208, 162, 90, 1, 231, 240, 212, 80, 208, 162, 90, 1, 206, + 109, 212, 80, 208, 162, 90, 1, 65, 212, 80, 208, 162, 90, 1, 252, 206, + 212, 80, 208, 162, 90, 1, 68, 212, 80, 208, 162, 90, 1, 66, 212, 80, 208, + 162, 90, 1, 74, 212, 80, 208, 162, 90, 1, 211, 87, 212, 80, 208, 162, 90, + 1, 71, 212, 80, 208, 162, 90, 1, 234, 188, 212, 80, 208, 162, 90, 1, 193, + 224, 212, 80, 208, 162, 90, 198, 70, 212, 80, 208, 162, 90, 198, 66, 212, + 80, 208, 162, 90, 198, 67, 212, 80, 208, 162, 90, 198, 64, 212, 80, 208, + 162, 90, 198, 65, 212, 80, 208, 162, 90, 198, 68, 212, 80, 208, 162, 90, + 198, 69, 212, 80, 208, 162, 90, 3, 40, 209, 250, 212, 80, 208, 162, 90, + 3, 40, 199, 3, 212, 80, 208, 162, 90, 3, 40, 219, 39, 212, 80, 208, 162, + 90, 3, 40, 251, 101, 212, 80, 208, 162, 90, 3, 40, 223, 94, 212, 80, 208, + 162, 90, 3, 192, 183, 192, 182, 212, 80, 208, 162, 90, 5, 219, 190, 212, + 80, 208, 162, 90, 17, 191, 77, 212, 80, 208, 162, 90, 17, 107, 212, 80, + 208, 162, 90, 17, 109, 212, 80, 208, 162, 90, 17, 138, 212, 80, 208, 162, + 90, 17, 134, 212, 80, 208, 162, 90, 17, 149, 212, 80, 208, 162, 90, 17, + 169, 212, 80, 208, 162, 90, 17, 175, 212, 80, 208, 162, 90, 17, 171, 212, + 80, 208, 162, 90, 17, 178, 212, 80, 208, 162, 90, 219, 28, 212, 96, 212, + 80, 208, 162, 90, 47, 247, 160, 198, 38, 1, 168, 198, 38, 1, 249, 153, + 198, 38, 1, 190, 190, 198, 38, 1, 238, 32, 198, 38, 1, 155, 198, 38, 1, + 231, 240, 198, 38, 1, 174, 198, 38, 1, 180, 198, 38, 1, 214, 68, 198, 38, + 1, 188, 198, 38, 1, 247, 1, 198, 38, 1, 170, 198, 38, 1, 193, 190, 198, + 38, 1, 223, 32, 198, 38, 1, 140, 198, 38, 1, 165, 198, 38, 1, 173, 198, + 38, 1, 68, 198, 38, 1, 248, 38, 68, 198, 38, 1, 223, 49, 198, 38, 1, 248, + 38, 223, 49, 198, 38, 1, 66, 198, 38, 1, 71, 198, 38, 1, 248, 38, 71, + 198, 38, 1, 234, 65, 198, 38, 1, 248, 38, 234, 65, 198, 38, 1, 74, 198, + 38, 1, 252, 25, 198, 38, 1, 248, 38, 252, 25, 198, 38, 1, 65, 198, 38, 3, + 206, 180, 198, 79, 193, 163, 1, 252, 206, 193, 163, 1, 65, 193, 163, 1, + 249, 153, 193, 163, 1, 247, 160, 193, 163, 1, 238, 32, 193, 163, 1, 231, + 240, 193, 163, 1, 170, 193, 163, 1, 209, 228, 193, 163, 1, 173, 193, 163, + 1, 180, 193, 163, 1, 168, 193, 163, 1, 190, 190, 193, 163, 1, 199, 49, + 193, 163, 1, 233, 109, 193, 163, 1, 188, 193, 163, 1, 203, 165, 193, 163, + 1, 223, 32, 193, 163, 1, 191, 123, 193, 163, 1, 193, 190, 193, 163, 1, + 195, 188, 193, 163, 1, 155, 193, 163, 1, 74, 193, 163, 1, 250, 163, 193, + 163, 1, 165, 193, 163, 1, 174, 193, 163, 1, 221, 215, 193, 163, 1, 140, + 193, 163, 1, 71, 193, 163, 1, 68, 193, 163, 1, 214, 68, 193, 163, 1, 66, + 193, 163, 1, 219, 66, 193, 163, 1, 197, 168, 193, 163, 1, 198, 26, 193, + 163, 1, 211, 94, 193, 163, 1, 252, 165, 193, 163, 1, 251, 122, 193, 163, + 1, 223, 136, 193, 163, 1, 211, 104, 193, 163, 1, 234, 103, 193, 163, 1, + 252, 166, 193, 163, 1, 212, 101, 193, 163, 1, 196, 147, 193, 163, 1, 192, + 24, 193, 163, 163, 197, 67, 193, 163, 163, 197, 66, 193, 163, 163, 221, + 54, 193, 163, 163, 221, 53, 193, 163, 17, 191, 77, 193, 163, 17, 107, + 193, 163, 17, 109, 193, 163, 17, 138, 193, 163, 17, 134, 193, 163, 17, + 149, 193, 163, 17, 169, 193, 163, 17, 175, 193, 163, 17, 171, 193, 163, + 17, 178, 193, 163, 213, 232, 56, 214, 243, 215, 120, 1, 74, 214, 243, + 215, 120, 1, 211, 78, 214, 243, 215, 120, 1, 211, 120, 214, 243, 215, + 120, 1, 210, 242, 214, 243, 215, 120, 1, 211, 94, 214, 243, 215, 120, 1, + 65, 214, 243, 215, 120, 1, 251, 218, 214, 243, 215, 120, 1, 252, 155, + 214, 243, 215, 120, 1, 251, 69, 214, 243, 215, 120, 1, 251, 245, 214, + 243, 215, 120, 1, 68, 214, 243, 215, 120, 1, 223, 68, 214, 243, 215, 120, + 1, 228, 18, 214, 243, 215, 120, 1, 223, 53, 214, 243, 215, 120, 1, 223, + 200, 214, 243, 215, 120, 1, 66, 214, 243, 215, 120, 1, 196, 160, 214, + 243, 215, 120, 1, 196, 158, 214, 243, 215, 120, 1, 196, 128, 214, 243, + 215, 120, 1, 196, 62, 214, 243, 215, 120, 1, 71, 214, 243, 215, 120, 1, + 234, 85, 214, 243, 215, 120, 1, 234, 180, 214, 243, 215, 120, 1, 234, + 114, 214, 243, 215, 120, 1, 234, 103, 214, 243, 215, 120, 1, 233, 245, + 214, 243, 215, 120, 1, 234, 122, 214, 243, 215, 120, 3, 211, 127, 214, + 243, 215, 120, 3, 215, 138, 214, 243, 215, 120, 3, 198, 28, 214, 243, + 215, 120, 3, 223, 193, 214, 243, 215, 120, 3, 200, 161, 214, 243, 215, + 120, 17, 191, 77, 214, 243, 215, 120, 17, 107, 214, 243, 215, 120, 17, + 109, 214, 243, 215, 120, 17, 138, 214, 243, 215, 120, 17, 134, 214, 243, + 215, 120, 17, 149, 214, 243, 215, 120, 17, 169, 214, 243, 215, 120, 17, + 175, 214, 243, 215, 120, 17, 171, 214, 243, 215, 120, 17, 178, 36, 5, + 229, 166, 36, 5, 229, 160, 36, 5, 229, 162, 36, 5, 229, 165, 36, 5, 229, + 163, 36, 5, 229, 164, 36, 5, 229, 161, 36, 5, 230, 147, 229, 170, 36, 5, + 229, 167, 36, 5, 229, 168, 36, 5, 229, 169, 36, 5, 230, 147, 215, 76, 36, + 5, 230, 147, 215, 77, 36, 5, 230, 147, 207, 236, 36, 5, 230, 147, 207, + 237, 36, 5, 230, 147, 207, 238, 36, 5, 230, 147, 247, 207, 36, 5, 230, + 147, 247, 208, 36, 5, 230, 147, 220, 172, 36, 5, 230, 147, 220, 173, 36, + 5, 230, 147, 220, 174, 36, 5, 230, 147, 230, 131, 36, 5, 230, 147, 230, + 132, 36, 5, 230, 147, 230, 133, 36, 5, 230, 147, 232, 58, 36, 5, 230, + 147, 232, 59, 36, 5, 230, 147, 208, 118, 36, 5, 230, 147, 208, 119, 85, + 84, 5, 218, 167, 221, 166, 85, 84, 5, 218, 163, 155, 85, 84, 5, 218, 161, + 220, 232, 85, 84, 5, 218, 37, 222, 13, 85, 84, 5, 218, 7, 222, 22, 85, + 84, 5, 218, 26, 221, 41, 85, 84, 5, 218, 54, 221, 67, 85, 84, 5, 217, + 179, 220, 219, 85, 84, 5, 218, 158, 193, 86, 85, 84, 5, 218, 156, 193, + 190, 85, 84, 5, 218, 154, 193, 0, 85, 84, 5, 217, 232, 193, 114, 85, 84, + 5, 217, 240, 193, 125, 85, 84, 5, 217, 244, 193, 29, 85, 84, 5, 218, 57, + 193, 48, 85, 84, 5, 217, 164, 192, 252, 85, 84, 5, 217, 215, 193, 112, + 85, 84, 5, 218, 41, 192, 240, 85, 84, 5, 218, 53, 192, 242, 85, 84, 5, + 217, 219, 192, 241, 85, 84, 5, 218, 152, 216, 44, 85, 84, 5, 218, 150, + 217, 90, 85, 84, 5, 218, 148, 215, 122, 85, 84, 5, 218, 43, 216, 186, 85, + 84, 5, 218, 8, 215, 231, 85, 84, 5, 217, 204, 215, 148, 85, 84, 5, 217, + 169, 215, 142, 85, 84, 5, 218, 146, 248, 188, 85, 84, 5, 218, 143, 249, + 153, 85, 84, 5, 218, 141, 248, 10, 85, 84, 5, 217, 208, 249, 1, 85, 84, + 5, 218, 5, 249, 17, 85, 84, 5, 217, 255, 248, 97, 85, 84, 5, 217, 220, + 248, 111, 85, 84, 5, 218, 131, 68, 85, 84, 5, 218, 129, 65, 85, 84, 5, + 218, 127, 66, 85, 84, 5, 217, 195, 234, 188, 85, 84, 5, 218, 2, 71, 85, + 84, 5, 217, 193, 211, 87, 85, 84, 5, 217, 211, 74, 85, 84, 5, 217, 221, + 234, 166, 85, 84, 5, 217, 227, 223, 162, 85, 84, 5, 217, 223, 223, 162, + 85, 84, 5, 217, 163, 251, 132, 85, 84, 5, 217, 180, 234, 103, 85, 84, 5, + 218, 116, 202, 222, 85, 84, 5, 218, 114, 188, 85, 84, 5, 218, 112, 201, + 4, 85, 84, 5, 217, 196, 205, 50, 85, 84, 5, 217, 242, 205, 68, 85, 84, 5, + 217, 222, 202, 16, 85, 84, 5, 218, 23, 202, 46, 85, 84, 5, 217, 162, 202, + 215, 85, 84, 5, 218, 102, 219, 146, 85, 84, 5, 218, 100, 173, 85, 84, 5, + 218, 98, 218, 225, 85, 84, 5, 218, 18, 219, 228, 85, 84, 5, 218, 29, 219, + 238, 85, 84, 5, 218, 48, 219, 8, 85, 84, 5, 217, 205, 219, 43, 85, 84, 5, + 217, 248, 179, 219, 238, 85, 84, 5, 218, 124, 237, 44, 85, 84, 5, 218, + 121, 238, 32, 85, 84, 5, 218, 118, 235, 89, 85, 84, 5, 218, 13, 237, 131, + 85, 84, 5, 217, 178, 236, 146, 85, 84, 5, 217, 177, 236, 174, 85, 84, 5, + 218, 110, 198, 193, 85, 84, 5, 218, 107, 190, 190, 85, 84, 5, 218, 105, + 197, 94, 85, 84, 5, 218, 11, 199, 121, 85, 84, 5, 218, 47, 199, 145, 85, + 84, 5, 217, 254, 198, 59, 85, 84, 5, 218, 33, 159, 85, 84, 5, 218, 96, + 222, 244, 85, 84, 5, 218, 93, 223, 32, 85, 84, 5, 218, 91, 222, 182, 85, + 84, 5, 217, 201, 223, 8, 85, 84, 5, 217, 245, 223, 10, 85, 84, 5, 217, + 198, 222, 191, 85, 84, 5, 218, 39, 222, 201, 85, 84, 5, 217, 183, 179, + 222, 201, 85, 84, 5, 218, 89, 192, 33, 85, 84, 5, 218, 86, 170, 85, 84, + 5, 218, 84, 191, 225, 85, 84, 5, 217, 249, 192, 77, 85, 84, 5, 218, 22, + 192, 80, 85, 84, 5, 217, 217, 191, 246, 85, 84, 5, 217, 237, 192, 12, 85, + 84, 5, 218, 80, 233, 23, 85, 84, 5, 218, 78, 233, 109, 85, 84, 5, 218, + 76, 232, 86, 85, 84, 5, 218, 24, 233, 52, 85, 84, 5, 218, 27, 233, 59, + 85, 84, 5, 217, 225, 232, 162, 85, 84, 5, 218, 14, 232, 175, 85, 84, 5, + 217, 161, 232, 85, 85, 84, 5, 218, 1, 233, 80, 85, 84, 5, 218, 74, 213, + 179, 85, 84, 5, 218, 72, 214, 226, 85, 84, 5, 218, 70, 212, 130, 85, 84, + 5, 217, 241, 214, 102, 85, 84, 5, 217, 189, 213, 31, 85, 84, 5, 217, 182, + 229, 158, 85, 84, 5, 218, 65, 140, 85, 84, 5, 217, 172, 228, 159, 85, 84, + 5, 218, 68, 229, 215, 85, 84, 5, 218, 6, 229, 245, 85, 84, 5, 218, 63, + 228, 252, 85, 84, 5, 217, 218, 229, 23, 85, 84, 5, 218, 19, 229, 214, 85, + 84, 5, 217, 230, 228, 245, 85, 84, 5, 218, 49, 229, 128, 85, 84, 5, 217, + 228, 230, 56, 85, 84, 5, 218, 15, 228, 142, 85, 84, 5, 218, 50, 229, 198, + 85, 84, 5, 217, 165, 228, 255, 85, 84, 5, 218, 56, 228, 155, 85, 84, 5, + 218, 12, 214, 33, 85, 84, 5, 218, 61, 214, 47, 85, 84, 5, 218, 20, 214, + 30, 85, 84, 5, 217, 243, 214, 41, 85, 84, 5, 217, 212, 214, 42, 85, 84, + 5, 217, 202, 214, 31, 85, 84, 5, 217, 238, 214, 32, 85, 84, 5, 217, 199, + 214, 46, 85, 84, 5, 217, 231, 214, 29, 85, 84, 5, 218, 16, 179, 214, 42, + 85, 84, 5, 217, 252, 179, 214, 31, 85, 84, 5, 217, 175, 179, 214, 32, 85, + 84, 5, 217, 203, 231, 53, 85, 84, 5, 217, 247, 231, 240, 85, 84, 5, 217, + 190, 230, 179, 85, 84, 5, 217, 168, 231, 157, 85, 84, 5, 217, 192, 230, + 165, 85, 84, 5, 217, 191, 230, 175, 85, 84, 5, 217, 174, 214, 52, 85, 84, + 5, 218, 45, 213, 245, 85, 84, 5, 217, 181, 213, 234, 85, 84, 5, 218, 34, + 209, 185, 85, 84, 5, 218, 3, 168, 85, 84, 5, 218, 52, 208, 165, 85, 84, + 5, 218, 21, 210, 49, 85, 84, 5, 218, 51, 210, 63, 85, 84, 5, 218, 0, 209, + 37, 85, 84, 5, 218, 36, 209, 73, 85, 84, 5, 217, 213, 216, 252, 85, 84, + 5, 218, 40, 217, 11, 85, 84, 5, 217, 236, 216, 246, 85, 84, 5, 218, 55, + 217, 3, 85, 84, 5, 217, 170, 217, 3, 85, 84, 5, 218, 30, 217, 4, 85, 84, + 5, 217, 186, 216, 247, 85, 84, 5, 217, 184, 216, 248, 85, 84, 5, 217, + 171, 216, 240, 85, 84, 5, 217, 197, 179, 217, 4, 85, 84, 5, 217, 253, + 179, 216, 247, 85, 84, 5, 217, 216, 179, 216, 248, 85, 84, 5, 217, 226, + 221, 13, 85, 84, 5, 218, 10, 221, 21, 85, 84, 5, 218, 28, 221, 9, 85, 84, + 5, 218, 59, 221, 16, 85, 84, 5, 217, 250, 221, 17, 85, 84, 5, 217, 246, + 221, 11, 85, 84, 5, 217, 200, 221, 12, 85, 84, 5, 217, 234, 231, 174, 85, + 84, 5, 218, 46, 231, 182, 85, 84, 5, 217, 210, 231, 169, 85, 84, 5, 218, + 9, 231, 178, 85, 84, 5, 217, 251, 231, 179, 85, 84, 5, 218, 31, 231, 170, + 85, 84, 5, 218, 32, 231, 172, 85, 84, 5, 217, 187, 165, 85, 84, 5, 217, + 235, 214, 147, 85, 84, 5, 217, 229, 214, 162, 85, 84, 5, 217, 233, 214, + 129, 85, 84, 5, 217, 167, 214, 153, 85, 84, 5, 217, 239, 214, 154, 85, + 84, 5, 218, 35, 214, 134, 85, 84, 5, 218, 38, 214, 138, 85, 84, 5, 217, + 206, 213, 157, 85, 84, 5, 217, 166, 213, 127, 85, 84, 5, 217, 209, 213, + 148, 85, 84, 5, 217, 224, 213, 131, 85, 84, 5, 217, 176, 195, 69, 85, 84, + 5, 217, 173, 195, 188, 85, 84, 5, 217, 207, 193, 249, 85, 84, 5, 217, + 185, 195, 148, 85, 84, 5, 218, 17, 195, 153, 85, 84, 5, 217, 214, 195, 8, + 85, 84, 5, 218, 25, 195, 24, 85, 84, 5, 217, 194, 212, 74, 85, 84, 5, + 218, 44, 212, 94, 85, 84, 5, 217, 188, 212, 56, 85, 84, 5, 218, 4, 212, + 86, 85, 84, 5, 218, 42, 212, 63, 85, 84, 17, 107, 85, 84, 17, 109, 85, + 84, 17, 138, 85, 84, 17, 134, 85, 84, 17, 149, 85, 84, 17, 169, 85, 84, + 17, 175, 85, 84, 17, 171, 85, 84, 17, 178, 85, 84, 33, 31, 199, 119, 85, + 84, 33, 31, 199, 90, 85, 84, 33, 31, 228, 138, 85, 84, 33, 31, 198, 228, + 85, 84, 33, 31, 199, 96, 198, 228, 85, 84, 33, 31, 228, 141, 198, 228, + 85, 84, 33, 31, 216, 47, 252, 33, 6, 1, 251, 180, 252, 33, 6, 1, 238, 29, + 252, 33, 6, 1, 220, 123, 252, 33, 6, 1, 216, 60, 252, 33, 6, 1, 249, 153, + 252, 33, 6, 1, 202, 164, 252, 33, 6, 1, 210, 63, 252, 33, 6, 1, 248, 196, + 252, 33, 6, 1, 165, 252, 33, 6, 1, 71, 252, 33, 6, 1, 233, 109, 252, 33, + 6, 1, 68, 252, 33, 6, 1, 74, 252, 33, 6, 1, 237, 68, 252, 33, 6, 1, 192, + 34, 252, 33, 6, 1, 193, 133, 252, 33, 6, 1, 212, 130, 252, 33, 6, 1, 222, + 106, 252, 33, 6, 1, 170, 252, 33, 6, 1, 66, 252, 33, 6, 1, 222, 235, 252, + 33, 6, 1, 243, 95, 252, 33, 6, 1, 140, 252, 33, 6, 1, 208, 94, 252, 33, + 6, 1, 231, 240, 252, 33, 6, 1, 212, 101, 252, 33, 6, 1, 197, 94, 252, 33, + 6, 1, 213, 224, 252, 33, 6, 1, 195, 188, 252, 33, 6, 1, 221, 215, 252, + 33, 6, 1, 231, 179, 252, 33, 6, 1, 191, 108, 252, 33, 6, 1, 221, 12, 252, + 33, 6, 1, 203, 165, 252, 33, 2, 1, 251, 180, 252, 33, 2, 1, 238, 29, 252, + 33, 2, 1, 220, 123, 252, 33, 2, 1, 216, 60, 252, 33, 2, 1, 249, 153, 252, + 33, 2, 1, 202, 164, 252, 33, 2, 1, 210, 63, 252, 33, 2, 1, 248, 196, 252, + 33, 2, 1, 165, 252, 33, 2, 1, 71, 252, 33, 2, 1, 233, 109, 252, 33, 2, 1, + 68, 252, 33, 2, 1, 74, 252, 33, 2, 1, 237, 68, 252, 33, 2, 1, 192, 34, + 252, 33, 2, 1, 193, 133, 252, 33, 2, 1, 212, 130, 252, 33, 2, 1, 222, + 106, 252, 33, 2, 1, 170, 252, 33, 2, 1, 66, 252, 33, 2, 1, 222, 235, 252, + 33, 2, 1, 243, 95, 252, 33, 2, 1, 140, 252, 33, 2, 1, 208, 94, 252, 33, + 2, 1, 231, 240, 252, 33, 2, 1, 212, 101, 252, 33, 2, 1, 197, 94, 252, 33, + 2, 1, 213, 224, 252, 33, 2, 1, 195, 188, 252, 33, 2, 1, 221, 215, 252, + 33, 2, 1, 231, 179, 252, 33, 2, 1, 191, 108, 252, 33, 2, 1, 221, 12, 252, + 33, 2, 1, 203, 165, 252, 33, 251, 181, 219, 190, 252, 33, 18, 219, 190, + 252, 33, 231, 153, 77, 252, 33, 230, 57, 252, 33, 120, 215, 252, 252, 33, + 231, 154, 120, 215, 252, 252, 33, 212, 141, 252, 33, 214, 213, 77, 252, + 33, 17, 191, 77, 252, 33, 17, 107, 252, 33, 17, 109, 252, 33, 17, 138, + 252, 33, 17, 134, 252, 33, 17, 149, 252, 33, 17, 169, 252, 33, 17, 175, + 252, 33, 17, 171, 252, 33, 17, 178, 252, 33, 89, 233, 216, 77, 252, 33, + 89, 208, 13, 77, 223, 146, 143, 31, 107, 223, 146, 143, 31, 109, 223, + 146, 143, 31, 138, 223, 146, 143, 31, 134, 223, 146, 143, 31, 149, 223, + 146, 143, 31, 169, 223, 146, 143, 31, 175, 223, 146, 143, 31, 171, 223, + 146, 143, 31, 178, 223, 146, 143, 31, 199, 95, 223, 146, 143, 31, 197, + 32, 223, 146, 143, 31, 198, 249, 223, 146, 143, 31, 232, 135, 223, 146, + 143, 31, 233, 15, 223, 146, 143, 31, 202, 120, 223, 146, 143, 31, 203, + 241, 223, 146, 143, 31, 234, 153, 223, 146, 143, 31, 213, 169, 223, 146, + 143, 31, 91, 228, 140, 223, 146, 143, 31, 105, 228, 140, 223, 146, 143, + 31, 115, 228, 140, 223, 146, 143, 31, 232, 128, 228, 140, 223, 146, 143, + 31, 232, 226, 228, 140, 223, 146, 143, 31, 202, 136, 228, 140, 223, 146, + 143, 31, 203, 247, 228, 140, 223, 146, 143, 31, 234, 164, 228, 140, 223, + 146, 143, 31, 213, 175, 228, 140, 223, 146, 143, 31, 91, 189, 223, 146, + 143, 31, 105, 189, 223, 146, 143, 31, 115, 189, 223, 146, 143, 31, 232, + 128, 189, 223, 146, 143, 31, 232, 226, 189, 223, 146, 143, 31, 202, 136, + 189, 223, 146, 143, 31, 203, 247, 189, 223, 146, 143, 31, 234, 164, 189, + 223, 146, 143, 31, 213, 175, 189, 223, 146, 143, 31, 199, 96, 189, 223, + 146, 143, 31, 197, 33, 189, 223, 146, 143, 31, 198, 250, 189, 223, 146, + 143, 31, 232, 136, 189, 223, 146, 143, 31, 233, 16, 189, 223, 146, 143, + 31, 202, 121, 189, 223, 146, 143, 31, 203, 242, 189, 223, 146, 143, 31, + 234, 154, 189, 223, 146, 143, 31, 213, 170, 189, 223, 146, 143, 31, 220, + 41, 223, 146, 143, 31, 220, 40, 223, 146, 143, 220, 42, 77, 223, 146, + 143, 31, 222, 60, 223, 146, 143, 31, 222, 59, 223, 146, 143, 31, 208, + 227, 107, 223, 146, 143, 31, 208, 227, 109, 223, 146, 143, 31, 208, 227, + 138, 223, 146, 143, 31, 208, 227, 134, 223, 146, 143, 31, 208, 227, 149, + 223, 146, 143, 31, 208, 227, 169, 223, 146, 143, 31, 208, 227, 175, 223, + 146, 143, 31, 208, 227, 171, 223, 146, 143, 31, 208, 227, 178, 223, 146, + 143, 209, 106, 223, 146, 143, 232, 118, 91, 208, 22, 223, 146, 143, 232, + 118, 91, 230, 70, 223, 146, 143, 232, 118, 115, 208, 20, 223, 146, 143, + 206, 36, 77, 223, 146, 143, 31, 251, 157, 107, 223, 146, 143, 31, 251, + 157, 109, 223, 146, 143, 31, 251, 157, 199, 96, 189, 223, 146, 143, 251, + 157, 220, 42, 77, 211, 21, 143, 31, 107, 211, 21, 143, 31, 109, 211, 21, + 143, 31, 138, 211, 21, 143, 31, 134, 211, 21, 143, 31, 149, 211, 21, 143, + 31, 169, 211, 21, 143, 31, 175, 211, 21, 143, 31, 171, 211, 21, 143, 31, + 178, 211, 21, 143, 31, 199, 95, 211, 21, 143, 31, 197, 32, 211, 21, 143, + 31, 198, 249, 211, 21, 143, 31, 232, 135, 211, 21, 143, 31, 233, 15, 211, + 21, 143, 31, 202, 120, 211, 21, 143, 31, 203, 241, 211, 21, 143, 31, 234, + 153, 211, 21, 143, 31, 213, 169, 211, 21, 143, 31, 91, 228, 140, 211, 21, + 143, 31, 105, 228, 140, 211, 21, 143, 31, 115, 228, 140, 211, 21, 143, + 31, 232, 128, 228, 140, 211, 21, 143, 31, 232, 226, 228, 140, 211, 21, + 143, 31, 202, 136, 228, 140, 211, 21, 143, 31, 203, 247, 228, 140, 211, + 21, 143, 31, 234, 164, 228, 140, 211, 21, 143, 31, 213, 175, 228, 140, + 211, 21, 143, 31, 91, 189, 211, 21, 143, 31, 105, 189, 211, 21, 143, 31, + 115, 189, 211, 21, 143, 31, 232, 128, 189, 211, 21, 143, 31, 232, 226, + 189, 211, 21, 143, 31, 202, 136, 189, 211, 21, 143, 31, 203, 247, 189, + 211, 21, 143, 31, 234, 164, 189, 211, 21, 143, 31, 213, 175, 189, 211, + 21, 143, 31, 199, 96, 189, 211, 21, 143, 31, 197, 33, 189, 211, 21, 143, + 31, 198, 250, 189, 211, 21, 143, 31, 232, 136, 189, 211, 21, 143, 31, + 233, 16, 189, 211, 21, 143, 31, 202, 121, 189, 211, 21, 143, 31, 203, + 242, 189, 211, 21, 143, 31, 234, 154, 189, 211, 21, 143, 31, 213, 170, + 189, 211, 21, 143, 217, 49, 211, 21, 143, 251, 157, 31, 109, 211, 21, + 143, 251, 157, 31, 138, 211, 21, 143, 251, 157, 31, 134, 211, 21, 143, + 251, 157, 31, 149, 211, 21, 143, 251, 157, 31, 169, 211, 21, 143, 251, + 157, 31, 175, 211, 21, 143, 251, 157, 31, 171, 211, 21, 143, 251, 157, + 31, 178, 211, 21, 143, 251, 157, 31, 199, 95, 211, 21, 143, 251, 157, 31, + 232, 128, 228, 140, 211, 21, 143, 251, 157, 31, 202, 136, 228, 140, 211, + 21, 143, 251, 157, 31, 105, 189, 211, 21, 143, 251, 157, 31, 199, 96, + 189, 211, 21, 143, 232, 118, 91, 230, 70, 211, 21, 143, 232, 118, 91, + 202, 124, 9, 13, 251, 192, 9, 13, 248, 245, 9, 13, 223, 6, 9, 13, 238, 3, + 9, 13, 193, 133, 9, 13, 191, 113, 9, 13, 230, 81, 9, 13, 199, 219, 9, 13, + 192, 75, 9, 13, 222, 106, 9, 13, 220, 35, 9, 13, 216, 208, 9, 13, 213, + 24, 9, 13, 205, 46, 9, 13, 251, 230, 9, 13, 233, 46, 9, 13, 205, 192, 9, + 13, 208, 89, 9, 13, 207, 71, 9, 13, 203, 109, 9, 13, 199, 114, 9, 13, + 199, 29, 9, 13, 221, 210, 9, 13, 199, 41, 9, 13, 238, 26, 9, 13, 191, + 116, 9, 13, 231, 86, 9, 13, 236, 139, 248, 245, 9, 13, 236, 139, 213, 24, + 9, 13, 236, 139, 233, 46, 9, 13, 236, 139, 208, 89, 9, 13, 89, 248, 245, + 9, 13, 89, 223, 6, 9, 13, 89, 229, 210, 9, 13, 89, 230, 81, 9, 13, 89, + 192, 75, 9, 13, 89, 222, 106, 9, 13, 89, 220, 35, 9, 13, 89, 216, 208, 9, + 13, 89, 213, 24, 9, 13, 89, 205, 46, 9, 13, 89, 251, 230, 9, 13, 89, 233, + 46, 9, 13, 89, 205, 192, 9, 13, 89, 208, 89, 9, 13, 89, 203, 109, 9, 13, + 89, 199, 114, 9, 13, 89, 199, 29, 9, 13, 89, 221, 210, 9, 13, 89, 238, + 26, 9, 13, 89, 231, 86, 9, 13, 199, 214, 223, 6, 9, 13, 199, 214, 230, + 81, 9, 13, 199, 214, 192, 75, 9, 13, 199, 214, 220, 35, 9, 13, 199, 214, + 213, 24, 9, 13, 199, 214, 205, 46, 9, 13, 199, 214, 251, 230, 9, 13, 199, + 214, 205, 192, 9, 13, 199, 214, 208, 89, 9, 13, 199, 214, 203, 109, 9, + 13, 199, 214, 221, 210, 9, 13, 199, 214, 238, 26, 9, 13, 199, 214, 231, + 86, 9, 13, 199, 214, 236, 139, 213, 24, 9, 13, 199, 214, 236, 139, 208, + 89, 9, 13, 201, 36, 248, 245, 9, 13, 201, 36, 223, 6, 9, 13, 201, 36, + 229, 210, 9, 13, 201, 36, 230, 81, 9, 13, 201, 36, 199, 219, 9, 13, 201, + 36, 192, 75, 9, 13, 201, 36, 222, 106, 9, 13, 201, 36, 216, 208, 9, 13, + 201, 36, 213, 24, 9, 13, 201, 36, 205, 46, 9, 13, 201, 36, 251, 230, 9, + 13, 201, 36, 233, 46, 9, 13, 201, 36, 205, 192, 9, 13, 201, 36, 208, 89, + 9, 13, 201, 36, 203, 109, 9, 13, 201, 36, 199, 114, 9, 13, 201, 36, 199, + 29, 9, 13, 201, 36, 221, 210, 9, 13, 201, 36, 238, 26, 9, 13, 201, 36, + 191, 116, 9, 13, 201, 36, 231, 86, 9, 13, 201, 36, 236, 139, 248, 245, 9, + 13, 201, 36, 236, 139, 233, 46, 9, 13, 219, 3, 251, 192, 9, 13, 219, 3, + 248, 245, 9, 13, 219, 3, 223, 6, 9, 13, 219, 3, 238, 3, 9, 13, 219, 3, + 229, 210, 9, 13, 219, 3, 193, 133, 9, 13, 219, 3, 191, 113, 9, 13, 219, + 3, 230, 81, 9, 13, 219, 3, 199, 219, 9, 13, 219, 3, 192, 75, 9, 13, 219, + 3, 220, 35, 9, 13, 219, 3, 216, 208, 9, 13, 219, 3, 213, 24, 9, 13, 219, + 3, 205, 46, 9, 13, 219, 3, 251, 230, 9, 13, 219, 3, 233, 46, 9, 13, 219, + 3, 205, 192, 9, 13, 219, 3, 208, 89, 9, 13, 219, 3, 207, 71, 9, 13, 219, + 3, 203, 109, 9, 13, 219, 3, 199, 114, 9, 13, 219, 3, 199, 29, 9, 13, 219, + 3, 221, 210, 9, 13, 219, 3, 199, 41, 9, 13, 219, 3, 238, 26, 9, 13, 219, + 3, 191, 116, 9, 13, 219, 3, 231, 86, 9, 13, 235, 129, 248, 245, 9, 13, + 235, 129, 223, 6, 9, 13, 235, 129, 238, 3, 9, 13, 235, 129, 193, 133, 9, + 13, 235, 129, 191, 113, 9, 13, 235, 129, 230, 81, 9, 13, 235, 129, 199, + 219, 9, 13, 235, 129, 192, 75, 9, 13, 235, 129, 220, 35, 9, 13, 235, 129, + 216, 208, 9, 13, 235, 129, 213, 24, 9, 13, 235, 129, 205, 46, 9, 13, 235, + 129, 251, 230, 9, 13, 235, 129, 233, 46, 9, 13, 235, 129, 205, 192, 9, + 13, 235, 129, 208, 89, 9, 13, 235, 129, 207, 71, 9, 13, 235, 129, 203, + 109, 9, 13, 235, 129, 199, 114, 9, 13, 235, 129, 199, 29, 9, 13, 235, + 129, 221, 210, 9, 13, 235, 129, 199, 41, 9, 13, 235, 129, 238, 26, 9, 13, + 235, 129, 191, 116, 9, 13, 235, 129, 231, 86, 9, 13, 211, 67, 92, 4, 182, + 4, 199, 168, 9, 13, 211, 67, 182, 4, 238, 3, 217, 114, 123, 234, 204, + 193, 66, 217, 114, 123, 202, 2, 193, 66, 217, 114, 123, 193, 105, 193, + 66, 217, 114, 123, 186, 193, 66, 217, 114, 123, 207, 87, 235, 111, 217, + 114, 123, 230, 201, 235, 111, 217, 114, 123, 63, 235, 111, 217, 114, 123, + 91, 79, 243, 140, 217, 114, 123, 105, 79, 243, 140, 217, 114, 123, 115, + 79, 243, 140, 217, 114, 123, 232, 128, 79, 243, 140, 217, 114, 123, 232, + 226, 79, 243, 140, 217, 114, 123, 202, 136, 79, 243, 140, 217, 114, 123, + 203, 247, 79, 243, 140, 217, 114, 123, 234, 164, 79, 243, 140, 217, 114, + 123, 213, 175, 79, 243, 140, 217, 114, 123, 91, 79, 249, 102, 217, 114, + 123, 105, 79, 249, 102, 217, 114, 123, 115, 79, 249, 102, 217, 114, 123, + 232, 128, 79, 249, 102, 217, 114, 123, 232, 226, 79, 249, 102, 217, 114, + 123, 202, 136, 79, 249, 102, 217, 114, 123, 203, 247, 79, 249, 102, 217, + 114, 123, 234, 164, 79, 249, 102, 217, 114, 123, 213, 175, 79, 249, 102, + 217, 114, 123, 91, 79, 243, 7, 217, 114, 123, 105, 79, 243, 7, 217, 114, + 123, 115, 79, 243, 7, 217, 114, 123, 232, 128, 79, 243, 7, 217, 114, 123, + 232, 226, 79, 243, 7, 217, 114, 123, 202, 136, 79, 243, 7, 217, 114, 123, + 203, 247, 79, 243, 7, 217, 114, 123, 234, 164, 79, 243, 7, 217, 114, 123, + 213, 175, 79, 243, 7, 217, 114, 123, 209, 85, 217, 114, 123, 211, 53, + 217, 114, 123, 249, 103, 217, 114, 123, 243, 49, 217, 114, 123, 201, 196, + 217, 114, 123, 200, 200, 217, 114, 123, 250, 149, 217, 114, 123, 193, 56, + 217, 114, 123, 222, 194, 217, 114, 123, 249, 146, 236, 151, 123, 228, + 241, 249, 146, 236, 151, 123, 228, 239, 236, 151, 123, 228, 238, 236, + 151, 123, 228, 237, 236, 151, 123, 228, 236, 236, 151, 123, 228, 235, + 236, 151, 123, 228, 234, 236, 151, 123, 228, 233, 236, 151, 123, 228, + 232, 236, 151, 123, 228, 231, 236, 151, 123, 228, 230, 236, 151, 123, + 228, 229, 236, 151, 123, 228, 228, 236, 151, 123, 228, 227, 236, 151, + 123, 228, 226, 236, 151, 123, 228, 225, 236, 151, 123, 228, 224, 236, + 151, 123, 228, 223, 236, 151, 123, 228, 222, 236, 151, 123, 228, 221, + 236, 151, 123, 228, 220, 236, 151, 123, 228, 219, 236, 151, 123, 228, + 218, 236, 151, 123, 228, 217, 236, 151, 123, 228, 216, 236, 151, 123, + 228, 215, 236, 151, 123, 228, 214, 236, 151, 123, 228, 213, 236, 151, + 123, 228, 212, 236, 151, 123, 228, 211, 236, 151, 123, 228, 210, 236, + 151, 123, 228, 209, 236, 151, 123, 228, 208, 236, 151, 123, 228, 207, + 236, 151, 123, 228, 206, 236, 151, 123, 228, 205, 236, 151, 123, 228, + 204, 236, 151, 123, 228, 203, 236, 151, 123, 228, 202, 236, 151, 123, + 228, 201, 236, 151, 123, 228, 200, 236, 151, 123, 228, 199, 236, 151, + 123, 228, 198, 236, 151, 123, 228, 197, 236, 151, 123, 228, 196, 236, + 151, 123, 228, 195, 236, 151, 123, 228, 194, 236, 151, 123, 228, 193, + 236, 151, 123, 228, 192, 236, 151, 123, 228, 191, 236, 151, 123, 81, 249, + 146, 236, 151, 123, 195, 134, 236, 151, 123, 195, 133, 236, 151, 123, + 195, 132, 236, 151, 123, 195, 131, 236, 151, 123, 195, 130, 236, 151, + 123, 195, 129, 236, 151, 123, 195, 128, 236, 151, 123, 195, 127, 236, + 151, 123, 195, 126, 236, 151, 123, 195, 125, 236, 151, 123, 195, 124, + 236, 151, 123, 195, 123, 236, 151, 123, 195, 122, 236, 151, 123, 195, + 121, 236, 151, 123, 195, 120, 236, 151, 123, 195, 119, 236, 151, 123, + 195, 118, 236, 151, 123, 195, 117, 236, 151, 123, 195, 116, 236, 151, + 123, 195, 115, 236, 151, 123, 195, 114, 236, 151, 123, 195, 113, 236, + 151, 123, 195, 112, 236, 151, 123, 195, 111, 236, 151, 123, 195, 110, + 236, 151, 123, 195, 109, 236, 151, 123, 195, 108, 236, 151, 123, 195, + 107, 236, 151, 123, 195, 106, 236, 151, 123, 195, 105, 236, 151, 123, + 195, 104, 236, 151, 123, 195, 103, 236, 151, 123, 195, 102, 236, 151, + 123, 195, 101, 236, 151, 123, 195, 100, 236, 151, 123, 195, 99, 236, 151, + 123, 195, 98, 236, 151, 123, 195, 97, 236, 151, 123, 195, 96, 236, 151, + 123, 195, 95, 236, 151, 123, 195, 94, 236, 151, 123, 195, 93, 236, 151, + 123, 195, 92, 236, 151, 123, 195, 91, 236, 151, 123, 195, 90, 236, 151, + 123, 195, 89, 236, 151, 123, 195, 88, 236, 151, 123, 195, 87, 236, 151, + 123, 195, 86, 209, 95, 247, 101, 249, 146, 209, 95, 247, 101, 252, 53, + 79, 201, 244, 209, 95, 247, 101, 105, 79, 201, 244, 209, 95, 247, 101, + 115, 79, 201, 244, 209, 95, 247, 101, 232, 128, 79, 201, 244, 209, 95, + 247, 101, 232, 226, 79, 201, 244, 209, 95, 247, 101, 202, 136, 79, 201, + 244, 209, 95, 247, 101, 203, 247, 79, 201, 244, 209, 95, 247, 101, 234, + 164, 79, 201, 244, 209, 95, 247, 101, 213, 175, 79, 201, 244, 209, 95, + 247, 101, 199, 96, 79, 201, 244, 209, 95, 247, 101, 223, 30, 79, 201, + 244, 209, 95, 247, 101, 221, 77, 79, 201, 244, 209, 95, 247, 101, 208, + 15, 79, 201, 244, 209, 95, 247, 101, 221, 139, 79, 201, 244, 209, 95, + 247, 101, 252, 53, 79, 229, 221, 209, 95, 247, 101, 105, 79, 229, 221, + 209, 95, 247, 101, 115, 79, 229, 221, 209, 95, 247, 101, 232, 128, 79, + 229, 221, 209, 95, 247, 101, 232, 226, 79, 229, 221, 209, 95, 247, 101, + 202, 136, 79, 229, 221, 209, 95, 247, 101, 203, 247, 79, 229, 221, 209, + 95, 247, 101, 234, 164, 79, 229, 221, 209, 95, 247, 101, 213, 175, 79, + 229, 221, 209, 95, 247, 101, 199, 96, 79, 229, 221, 209, 95, 247, 101, + 223, 30, 79, 229, 221, 209, 95, 247, 101, 221, 77, 79, 229, 221, 209, 95, + 247, 101, 208, 15, 79, 229, 221, 209, 95, 247, 101, 221, 139, 79, 229, + 221, 209, 95, 247, 101, 207, 87, 222, 194, 209, 95, 247, 101, 252, 53, + 79, 237, 31, 209, 95, 247, 101, 105, 79, 237, 31, 209, 95, 247, 101, 115, + 79, 237, 31, 209, 95, 247, 101, 232, 128, 79, 237, 31, 209, 95, 247, 101, + 232, 226, 79, 237, 31, 209, 95, 247, 101, 202, 136, 79, 237, 31, 209, 95, + 247, 101, 203, 247, 79, 237, 31, 209, 95, 247, 101, 234, 164, 79, 237, + 31, 209, 95, 247, 101, 213, 175, 79, 237, 31, 209, 95, 247, 101, 199, 96, + 79, 237, 31, 209, 95, 247, 101, 223, 30, 79, 237, 31, 209, 95, 247, 101, + 221, 77, 79, 237, 31, 209, 95, 247, 101, 208, 15, 79, 237, 31, 209, 95, + 247, 101, 221, 139, 79, 237, 31, 209, 95, 247, 101, 62, 222, 194, 209, + 95, 247, 101, 252, 53, 79, 242, 204, 209, 95, 247, 101, 105, 79, 242, + 204, 209, 95, 247, 101, 115, 79, 242, 204, 209, 95, 247, 101, 232, 128, + 79, 242, 204, 209, 95, 247, 101, 232, 226, 79, 242, 204, 209, 95, 247, + 101, 202, 136, 79, 242, 204, 209, 95, 247, 101, 203, 247, 79, 242, 204, + 209, 95, 247, 101, 234, 164, 79, 242, 204, 209, 95, 247, 101, 213, 175, + 79, 242, 204, 209, 95, 247, 101, 199, 96, 79, 242, 204, 209, 95, 247, + 101, 223, 30, 79, 242, 204, 209, 95, 247, 101, 221, 77, 79, 242, 204, + 209, 95, 247, 101, 208, 15, 79, 242, 204, 209, 95, 247, 101, 221, 139, + 79, 242, 204, 209, 95, 247, 101, 63, 222, 194, 209, 95, 247, 101, 232, + 160, 209, 95, 247, 101, 197, 200, 209, 95, 247, 101, 197, 189, 209, 95, + 247, 101, 197, 186, 209, 95, 247, 101, 197, 185, 209, 95, 247, 101, 197, + 184, 209, 95, 247, 101, 197, 183, 209, 95, 247, 101, 197, 182, 209, 95, + 247, 101, 197, 181, 209, 95, 247, 101, 197, 180, 209, 95, 247, 101, 197, + 199, 209, 95, 247, 101, 197, 198, 209, 95, 247, 101, 197, 197, 209, 95, + 247, 101, 197, 196, 209, 95, 247, 101, 197, 195, 209, 95, 247, 101, 197, + 194, 209, 95, 247, 101, 197, 193, 209, 95, 247, 101, 197, 192, 209, 95, + 247, 101, 197, 191, 209, 95, 247, 101, 197, 190, 209, 95, 247, 101, 197, + 188, 209, 95, 247, 101, 197, 187, 17, 191, 78, 232, 80, 201, 63, 17, 191, + 78, 242, 74, 17, 91, 242, 74, 17, 105, 242, 74, 17, 115, 242, 74, 17, + 232, 128, 242, 74, 17, 232, 226, 242, 74, 17, 202, 136, 242, 74, 17, 203, + 247, 242, 74, 17, 234, 164, 242, 74, 17, 213, 175, 242, 74, 236, 241, 47, + 49, 17, 191, 77, 236, 241, 214, 106, 47, 49, 17, 191, 77, 47, 191, 78, 4, + 202, 97, 47, 251, 85, 57, 47, 236, 155, 3, 4, 211, 4, 249, 141, 127, 8, + 6, 1, 65, 127, 8, 6, 1, 250, 120, 127, 8, 6, 1, 247, 193, 127, 8, 6, 1, + 238, 127, 127, 8, 6, 1, 71, 127, 8, 6, 1, 233, 175, 127, 8, 6, 1, 232, + 51, 127, 8, 6, 1, 230, 116, 127, 8, 6, 1, 68, 127, 8, 6, 1, 223, 35, 127, + 8, 6, 1, 222, 152, 127, 8, 6, 1, 172, 127, 8, 6, 1, 218, 168, 127, 8, 6, + 1, 215, 61, 127, 8, 6, 1, 74, 127, 8, 6, 1, 210, 236, 127, 8, 6, 1, 208, + 104, 127, 8, 6, 1, 146, 127, 8, 6, 1, 206, 8, 127, 8, 6, 1, 200, 43, 127, + 8, 6, 1, 66, 127, 8, 6, 1, 196, 12, 127, 8, 6, 1, 193, 224, 127, 8, 6, 1, + 192, 235, 127, 8, 6, 1, 192, 159, 127, 8, 6, 1, 191, 166, 198, 42, 203, + 103, 248, 52, 8, 6, 1, 206, 8, 47, 43, 8, 6, 1, 247, 193, 47, 43, 8, 6, + 1, 146, 47, 247, 43, 47, 192, 237, 239, 7, 113, 112, 8, 6, 1, 65, 112, 8, + 6, 1, 250, 120, 112, 8, 6, 1, 247, 193, 112, 8, 6, 1, 238, 127, 112, 8, + 6, 1, 71, 112, 8, 6, 1, 233, 175, 112, 8, 6, 1, 232, 51, 112, 8, 6, 1, + 230, 116, 112, 8, 6, 1, 68, 112, 8, 6, 1, 223, 35, 112, 8, 6, 1, 222, + 152, 112, 8, 6, 1, 172, 112, 8, 6, 1, 218, 168, 112, 8, 6, 1, 215, 61, + 112, 8, 6, 1, 74, 112, 8, 6, 1, 210, 236, 112, 8, 6, 1, 208, 104, 112, 8, + 6, 1, 146, 112, 8, 6, 1, 206, 8, 112, 8, 6, 1, 200, 43, 112, 8, 6, 1, 66, + 112, 8, 6, 1, 196, 12, 112, 8, 6, 1, 193, 224, 112, 8, 6, 1, 192, 235, + 112, 8, 6, 1, 192, 159, 112, 8, 6, 1, 191, 166, 112, 228, 126, 112, 215, + 87, 112, 205, 70, 112, 201, 178, 112, 208, 248, 112, 193, 126, 214, 106, + 47, 8, 6, 1, 65, 214, 106, 47, 8, 6, 1, 250, 120, 214, 106, 47, 8, 6, 1, + 247, 193, 214, 106, 47, 8, 6, 1, 238, 127, 214, 106, 47, 8, 6, 1, 71, + 214, 106, 47, 8, 6, 1, 233, 175, 214, 106, 47, 8, 6, 1, 232, 51, 214, + 106, 47, 8, 6, 1, 230, 116, 214, 106, 47, 8, 6, 1, 68, 214, 106, 47, 8, + 6, 1, 223, 35, 214, 106, 47, 8, 6, 1, 222, 152, 214, 106, 47, 8, 6, 1, + 172, 214, 106, 47, 8, 6, 1, 218, 168, 214, 106, 47, 8, 6, 1, 215, 61, + 214, 106, 47, 8, 6, 1, 74, 214, 106, 47, 8, 6, 1, 210, 236, 214, 106, 47, + 8, 6, 1, 208, 104, 214, 106, 47, 8, 6, 1, 146, 214, 106, 47, 8, 6, 1, + 206, 8, 214, 106, 47, 8, 6, 1, 200, 43, 214, 106, 47, 8, 6, 1, 66, 214, + 106, 47, 8, 6, 1, 196, 12, 214, 106, 47, 8, 6, 1, 193, 224, 214, 106, 47, + 8, 6, 1, 192, 235, 214, 106, 47, 8, 6, 1, 192, 159, 214, 106, 47, 8, 6, + 1, 191, 166, 207, 147, 216, 239, 56, 207, 147, 216, 235, 56, 207, 147, + 215, 164, 56, 47, 247, 66, 47, 247, 194, 4, 211, 4, 249, 141, 47, 228, + 145, 233, 12, 214, 106, 112, 8, 6, 1, 65, 214, 106, 112, 8, 6, 1, 250, + 120, 214, 106, 112, 8, 6, 1, 247, 193, 214, 106, 112, 8, 6, 1, 238, 127, + 214, 106, 112, 8, 6, 1, 71, 214, 106, 112, 8, 6, 1, 233, 175, 214, 106, + 112, 8, 6, 1, 232, 51, 214, 106, 112, 8, 6, 1, 230, 116, 214, 106, 112, + 8, 6, 1, 68, 214, 106, 112, 8, 6, 1, 223, 35, 214, 106, 112, 8, 6, 1, + 222, 152, 214, 106, 112, 8, 6, 1, 172, 214, 106, 112, 8, 6, 1, 218, 168, + 214, 106, 112, 8, 6, 1, 215, 61, 214, 106, 112, 8, 6, 1, 74, 214, 106, + 112, 8, 6, 1, 210, 236, 214, 106, 112, 8, 6, 1, 208, 104, 214, 106, 112, + 8, 6, 1, 146, 214, 106, 112, 8, 6, 1, 206, 8, 214, 106, 112, 8, 6, 1, + 200, 43, 214, 106, 112, 8, 6, 1, 66, 214, 106, 112, 8, 6, 1, 196, 12, + 214, 106, 112, 8, 6, 1, 193, 224, 214, 106, 112, 8, 6, 1, 192, 235, 214, + 106, 112, 8, 6, 1, 192, 159, 214, 106, 112, 8, 6, 1, 191, 166, 238, 214, + 214, 106, 112, 8, 6, 1, 210, 236, 214, 106, 112, 228, 28, 214, 106, 112, + 168, 214, 106, 112, 188, 214, 106, 112, 252, 155, 214, 106, 112, 193, + 126, 51, 236, 194, 112, 242, 247, 112, 239, 14, 112, 232, 108, 112, 228, + 19, 112, 214, 79, 112, 214, 70, 112, 211, 125, 112, 202, 9, 112, 133, 4, + 233, 216, 77, 112, 194, 252, 112, 115, 238, 127, 112, 205, 57, 205, 76, + 112, 105, 222, 152, 112, 232, 128, 222, 152, 112, 234, 164, 222, 152, + 112, 232, 226, 209, 62, 107, 112, 203, 247, 209, 62, 107, 112, 197, 21, + 209, 62, 109, 112, 202, 121, 210, 236, 112, 91, 228, 141, 197, 33, 210, + 236, 112, 8, 2, 1, 238, 127, 112, 229, 248, 112, 229, 247, 112, 229, 150, + 112, 218, 252, 112, 202, 241, 112, 196, 140, 112, 195, 21, 217, 36, 193, + 21, 113, 207, 79, 223, 145, 16, 1, 65, 207, 79, 223, 145, 16, 1, 250, + 120, 207, 79, 223, 145, 16, 1, 247, 193, 207, 79, 223, 145, 16, 1, 238, + 127, 207, 79, 223, 145, 16, 1, 71, 207, 79, 223, 145, 16, 1, 233, 175, + 207, 79, 223, 145, 16, 1, 232, 51, 207, 79, 223, 145, 16, 1, 230, 116, + 207, 79, 223, 145, 16, 1, 68, 207, 79, 223, 145, 16, 1, 223, 35, 207, 79, + 223, 145, 16, 1, 222, 152, 207, 79, 223, 145, 16, 1, 172, 207, 79, 223, + 145, 16, 1, 218, 168, 207, 79, 223, 145, 16, 1, 215, 61, 207, 79, 223, + 145, 16, 1, 74, 207, 79, 223, 145, 16, 1, 210, 236, 207, 79, 223, 145, + 16, 1, 208, 104, 207, 79, 223, 145, 16, 1, 146, 207, 79, 223, 145, 16, 1, + 206, 8, 207, 79, 223, 145, 16, 1, 200, 43, 207, 79, 223, 145, 16, 1, 66, + 207, 79, 223, 145, 16, 1, 196, 12, 207, 79, 223, 145, 16, 1, 193, 224, + 207, 79, 223, 145, 16, 1, 192, 235, 207, 79, 223, 145, 16, 1, 192, 159, + 207, 79, 223, 145, 16, 1, 191, 166, 51, 229, 120, 229, 9, 112, 72, 221, + 49, 112, 72, 188, 112, 12, 196, 95, 225, 217, 112, 12, 196, 95, 225, 221, + 112, 12, 196, 95, 225, 229, 112, 72, 237, 146, 112, 12, 196, 95, 225, + 236, 112, 12, 196, 95, 225, 223, 112, 12, 196, 95, 225, 195, 112, 12, + 196, 95, 225, 222, 112, 12, 196, 95, 225, 235, 112, 12, 196, 95, 225, + 209, 112, 12, 196, 95, 225, 202, 112, 12, 196, 95, 225, 211, 112, 12, + 196, 95, 225, 232, 112, 12, 196, 95, 225, 218, 112, 12, 196, 95, 225, + 234, 112, 12, 196, 95, 225, 210, 112, 12, 196, 95, 225, 233, 112, 12, + 196, 95, 225, 196, 112, 12, 196, 95, 225, 201, 112, 12, 196, 95, 225, + 194, 112, 12, 196, 95, 225, 224, 112, 12, 196, 95, 225, 226, 112, 12, + 196, 95, 225, 204, 112, 12, 196, 95, 225, 215, 112, 12, 196, 95, 225, + 213, 112, 12, 196, 95, 225, 239, 112, 12, 196, 95, 225, 238, 112, 12, + 196, 95, 225, 192, 112, 12, 196, 95, 225, 219, 112, 12, 196, 95, 225, + 237, 112, 12, 196, 95, 225, 228, 112, 12, 196, 95, 225, 214, 112, 12, + 196, 95, 225, 193, 112, 12, 196, 95, 225, 216, 112, 12, 196, 95, 225, + 198, 112, 12, 196, 95, 225, 197, 112, 12, 196, 95, 225, 227, 112, 12, + 196, 95, 225, 205, 112, 12, 196, 95, 225, 207, 112, 12, 196, 95, 225, + 208, 112, 12, 196, 95, 225, 200, 112, 12, 196, 95, 225, 231, 112, 12, + 196, 95, 225, 225, 112, 12, 196, 95, 225, 191, 198, 42, 203, 103, 248, + 52, 12, 196, 95, 225, 206, 198, 42, 203, 103, 248, 52, 12, 196, 95, 225, + 238, 198, 42, 203, 103, 248, 52, 12, 196, 95, 225, 236, 198, 42, 203, + 103, 248, 52, 12, 196, 95, 225, 220, 198, 42, 203, 103, 248, 52, 12, 196, + 95, 225, 203, 198, 42, 203, 103, 248, 52, 12, 196, 95, 225, 216, 198, 42, + 203, 103, 248, 52, 12, 196, 95, 225, 199, 198, 42, 203, 103, 248, 52, 12, + 196, 95, 225, 230, 198, 42, 203, 103, 248, 52, 12, 196, 95, 225, 212, 47, + 228, 14, 252, 27, 47, 228, 14, 252, 58, 206, 113, 16, 40, 232, 86, 206, + 113, 16, 40, 218, 225, 206, 113, 16, 40, 203, 23, 206, 113, 16, 40, 192, + 207, 206, 113, 16, 40, 203, 2, 206, 113, 16, 40, 247, 148, 238, 139, 232, + 173, 242, 219, 196, 117, 213, 191, 4, 201, 99, 200, 193, 139, 215, 183, + 200, 192, 242, 251, 250, 183, 235, 61, 200, 191, 139, 247, 253, 207, 148, + 248, 29, 250, 183, 213, 190, 193, 144, 193, 138, 195, 14, 216, 52, 193, + 128, 234, 208, 231, 12, 233, 232, 234, 208, 231, 12, 251, 140, 234, 208, + 231, 12, 250, 202, 231, 12, 4, 216, 177, 214, 80, 215, 206, 113, 193, + 130, 238, 228, 215, 206, 113, 232, 238, 208, 23, 215, 206, 113, 193, 130, + 231, 49, 215, 206, 113, 232, 80, 215, 206, 113, 193, 159, 231, 49, 215, + 206, 113, 220, 6, 208, 23, 215, 206, 113, 193, 159, 238, 228, 215, 206, + 113, 238, 228, 215, 205, 214, 80, 215, 206, 4, 233, 103, 232, 238, 208, + 23, 215, 206, 4, 233, 103, 220, 6, 208, 23, 215, 206, 4, 233, 103, 232, + 80, 215, 206, 4, 233, 103, 200, 199, 4, 233, 103, 231, 8, 201, 102, 203, + 45, 201, 102, 199, 21, 62, 235, 97, 63, 200, 198, 63, 200, 199, 4, 2, + 242, 210, 63, 200, 199, 248, 242, 242, 210, 63, 200, 199, 248, 242, 242, + 211, 4, 207, 149, 242, 211, 4, 207, 149, 242, 211, 4, 202, 52, 242, 211, + 4, 219, 129, 242, 211, 4, 198, 46, 232, 174, 193, 67, 248, 116, 233, 103, + 228, 181, 236, 162, 199, 227, 247, 228, 243, 103, 205, 48, 233, 226, 197, + 254, 237, 139, 197, 254, 210, 183, 197, 254, 247, 153, 228, 181, 210, 15, + 197, 78, 243, 107, 248, 119, 206, 126, 229, 149, 200, 196, 248, 119, 234, + 212, 79, 217, 103, 234, 212, 79, 206, 245, 229, 193, 232, 128, 219, 234, + 242, 209, 217, 69, 219, 233, 233, 84, 219, 233, 219, 234, 232, 181, 223, + 163, 193, 66, 215, 98, 198, 83, 250, 162, 230, 218, 216, 196, 193, 142, + 199, 187, 219, 201, 249, 98, 209, 133, 207, 87, 251, 46, 230, 201, 251, + 46, 210, 55, 210, 59, 243, 108, 201, 42, 230, 63, 202, 89, 79, 209, 112, + 216, 225, 211, 105, 248, 98, 209, 9, 219, 212, 206, 246, 238, 234, 206, + 246, 249, 111, 239, 17, 206, 245, 238, 167, 23, 206, 245, 201, 83, 248, + 66, 201, 243, 248, 43, 232, 106, 232, 102, 206, 152, 200, 142, 209, 12, + 237, 235, 211, 153, 200, 165, 232, 103, 203, 13, 232, 237, 247, 147, 4, + 200, 134, 237, 80, 202, 32, 228, 27, 238, 232, 203, 121, 228, 26, 228, + 27, 238, 232, 235, 126, 239, 16, 243, 66, 164, 247, 118, 219, 24, 238, + 158, 228, 254, 209, 14, 203, 29, 248, 222, 248, 62, 209, 15, 79, 232, + 161, 239, 15, 232, 150, 23, 221, 78, 199, 133, 193, 51, 230, 31, 205, + 176, 248, 79, 23, 238, 181, 193, 63, 231, 16, 242, 94, 231, 16, 197, 204, + 235, 104, 248, 253, 215, 140, 242, 226, 248, 253, 215, 139, 249, 149, + 248, 78, 232, 150, 23, 221, 79, 4, 209, 97, 248, 79, 4, 209, 30, 239, 3, + 209, 32, 206, 247, 193, 11, 208, 222, 248, 157, 247, 146, 223, 29, 243, + 56, 197, 254, 233, 67, 243, 55, 232, 240, 232, 241, 201, 241, 249, 109, + 210, 102, 209, 31, 239, 54, 249, 111, 199, 191, 197, 254, 238, 214, 232, + 211, 209, 134, 237, 136, 223, 19, 236, 154, 247, 90, 201, 41, 193, 67, + 243, 82, 215, 206, 195, 54, 247, 8, 205, 90, 205, 120, 230, 225, 247, + 111, 229, 224, 4, 198, 136, 211, 105, 199, 34, 219, 224, 248, 72, 79, + 232, 185, 216, 54, 216, 219, 207, 58, 206, 247, 37, 221, 221, 4, 223, 28, + 201, 11, 216, 89, 219, 168, 202, 86, 239, 22, 221, 72, 249, 13, 250, 213, + 37, 213, 1, 249, 13, 237, 86, 37, 213, 1, 233, 0, 232, 112, 252, 31, 198, + 180, 247, 91, 228, 183, 233, 33, 193, 93, 206, 139, 242, 97, 232, 232, + 209, 53, 23, 232, 236, 216, 89, 215, 169, 247, 132, 243, 14, 229, 231, + 250, 224, 210, 188, 198, 54, 230, 9, 243, 0, 199, 87, 198, 181, 242, 242, + 248, 107, 210, 6, 250, 222, 195, 65, 231, 214, 236, 234, 229, 117, 202, + 79, 217, 148, 248, 170, 231, 215, 237, 24, 248, 65, 232, 187, 209, 95, + 247, 99, 37, 213, 6, 215, 129, 37, 213, 1, 205, 104, 230, 162, 37, 221, + 220, 197, 179, 195, 42, 37, 205, 82, 206, 42, 203, 60, 4, 205, 123, 199, + 92, 207, 170, 23, 249, 111, 202, 109, 23, 202, 109, 248, 91, 249, 68, 23, + 228, 247, 243, 109, 232, 217, 202, 51, 206, 43, 200, 170, 201, 202, 216, + 219, 197, 205, 228, 184, 207, 171, 251, 141, 232, 158, 206, 56, 232, 158, + 200, 137, 193, 110, 219, 134, 230, 249, 207, 172, 215, 191, 207, 172, + 247, 102, 238, 225, 249, 65, 23, 249, 111, 195, 13, 233, 22, 229, 12, + 201, 75, 23, 249, 111, 228, 27, 229, 12, 201, 75, 23, 208, 157, 199, 234, + 199, 92, 210, 207, 23, 249, 111, 202, 53, 247, 107, 215, 184, 247, 130, + 249, 16, 4, 196, 117, 247, 255, 239, 36, 228, 173, 247, 253, 242, 250, + 237, 90, 228, 173, 247, 254, 242, 240, 247, 254, 237, 82, 237, 83, 223, + 60, 214, 208, 210, 109, 201, 113, 228, 173, 247, 254, 228, 173, 4, 231, + 198, 211, 144, 247, 254, 223, 19, 209, 20, 211, 143, 233, 231, 209, 20, + 211, 143, 228, 182, 249, 92, 250, 151, 199, 102, 217, 148, 228, 178, 218, + 242, 228, 178, 239, 20, 201, 57, 205, 89, 237, 94, 201, 57, 233, 92, 223, + 40, 220, 18, 223, 19, 247, 80, 233, 231, 247, 80, 63, 210, 28, 62, 210, + 28, 193, 136, 63, 232, 217, 193, 136, 62, 232, 217, 206, 125, 62, 206, + 125, 220, 117, 249, 132, 207, 170, 23, 202, 244, 248, 70, 23, 57, 251, + 136, 234, 109, 52, 232, 227, 196, 253, 234, 109, 52, 232, 227, 196, 250, + 234, 109, 52, 232, 227, 196, 248, 234, 109, 52, 232, 227, 196, 246, 234, + 109, 52, 232, 227, 196, 244, 207, 130, 215, 181, 210, 247, 193, 144, 248, + 3, 238, 239, 198, 173, 219, 185, 207, 174, 247, 78, 235, 111, 238, 223, + 193, 96, 202, 60, 202, 58, 228, 183, 207, 142, 230, 255, 203, 107, 215, + 225, 206, 129, 243, 93, 236, 162, 209, 147, 248, 109, 234, 131, 211, 156, + 201, 218, 203, 102, 248, 2, 251, 89, 228, 253, 220, 108, 248, 251, 232, + 236, 197, 204, 232, 236, 248, 117, 197, 55, 230, 7, 243, 94, 249, 149, + 243, 94, 232, 96, 249, 149, 243, 94, 248, 160, 210, 30, 221, 61, 209, 36, + 235, 101, 247, 134, 249, 137, 247, 134, 236, 153, 215, 182, 233, 103, + 238, 240, 233, 103, 198, 174, 233, 103, 207, 175, 233, 103, 247, 79, 233, + 103, 235, 112, 233, 103, 201, 200, 193, 96, 228, 184, 233, 103, 215, 226, + 233, 103, 236, 163, 233, 103, 209, 148, 233, 103, 232, 100, 233, 103, + 230, 59, 233, 103, 193, 38, 233, 103, 249, 10, 233, 103, 210, 162, 233, + 103, 209, 148, 213, 13, 210, 76, 208, 208, 243, 77, 233, 185, 233, 193, + 234, 211, 213, 13, 215, 179, 198, 61, 63, 133, 209, 58, 249, 144, 223, + 148, 63, 144, 209, 58, 249, 144, 223, 148, 63, 45, 209, 58, 249, 144, + 223, 148, 63, 50, 209, 58, 249, 144, 223, 148, 232, 230, 230, 54, 56, + 193, 136, 230, 54, 56, 211, 126, 230, 54, 56, 198, 211, 133, 56, 198, + 211, 144, 56, 242, 241, 230, 29, 56, 211, 77, 230, 29, 56, 238, 208, 193, + 34, 230, 9, 233, 188, 214, 111, 200, 41, 223, 9, 235, 106, 221, 142, 248, + 173, 193, 34, 242, 212, 208, 137, 230, 33, 209, 10, 217, 78, 203, 52, + 250, 178, 203, 52, 229, 134, 203, 52, 193, 34, 205, 139, 193, 34, 248, + 90, 232, 156, 247, 220, 223, 163, 202, 187, 247, 219, 223, 163, 202, 187, + 248, 60, 231, 28, 217, 90, 193, 35, 233, 81, 217, 91, 23, 193, 36, 229, + 6, 230, 28, 105, 216, 187, 229, 6, 230, 28, 105, 193, 33, 229, 6, 230, + 28, 209, 50, 211, 142, 193, 36, 4, 247, 239, 234, 209, 248, 30, 4, 195, + 144, 209, 251, 4, 248, 121, 230, 78, 217, 91, 4, 230, 176, 209, 186, 217, + 73, 217, 91, 4, 197, 63, 211, 118, 217, 90, 211, 118, 193, 35, 249, 148, + 239, 37, 193, 19, 208, 213, 223, 19, 211, 137, 223, 19, 230, 254, 231, + 61, 249, 149, 251, 120, 233, 198, 251, 182, 251, 183, 215, 215, 223, 168, + 202, 103, 223, 137, 237, 79, 209, 250, 230, 170, 237, 240, 219, 95, 214, + 235, 209, 48, 233, 104, 217, 33, 230, 77, 249, 86, 209, 52, 200, 62, 209, + 140, 221, 123, 77, 218, 242, 219, 175, 206, 188, 231, 155, 201, 65, 221, + 122, 248, 71, 238, 243, 4, 229, 223, 193, 117, 249, 6, 229, 223, 248, 22, + 229, 223, 105, 229, 221, 201, 239, 229, 223, 230, 186, 229, 223, 229, + 224, 4, 57, 248, 115, 229, 223, 230, 201, 229, 223, 192, 73, 229, 223, + 208, 138, 229, 223, 229, 224, 4, 206, 247, 207, 12, 229, 221, 229, 224, + 237, 136, 237, 33, 203, 135, 4, 42, 75, 223, 117, 234, 135, 156, 247, + 251, 251, 119, 113, 248, 99, 202, 92, 113, 242, 85, 113, 201, 212, 200, + 144, 113, 235, 97, 237, 216, 113, 209, 141, 79, 209, 37, 232, 199, 248, + 185, 236, 195, 113, 201, 230, 249, 109, 198, 231, 249, 109, 63, 232, 186, + 228, 141, 209, 56, 113, 215, 230, 249, 130, 238, 170, 233, 218, 88, 236, + 155, 56, 238, 230, 247, 100, 249, 91, 4, 192, 71, 56, 249, 91, 4, 236, + 155, 56, 249, 91, 4, 233, 234, 56, 249, 91, 4, 209, 8, 56, 215, 230, 4, + 193, 60, 243, 137, 4, 196, 66, 197, 250, 23, 192, 71, 56, 205, 60, 209, + 249, 239, 59, 248, 28, 216, 41, 232, 191, 236, 220, 211, 60, 236, 226, + 235, 55, 233, 7, 232, 171, 211, 77, 233, 7, 232, 171, 210, 205, 4, 238, + 175, 210, 205, 233, 96, 196, 77, 247, 140, 199, 130, 247, 140, 247, 101, + 223, 148, 243, 137, 4, 196, 66, 197, 249, 243, 137, 4, 235, 119, 197, + 249, 249, 88, 243, 136, 242, 225, 208, 133, 206, 115, 208, 133, 210, 134, + 201, 53, 206, 50, 197, 238, 206, 50, 248, 95, 199, 232, 219, 229, 213, 4, + 213, 5, 4, 237, 135, 238, 242, 242, 219, 248, 96, 211, 77, 248, 96, 230, + 201, 248, 96, 248, 115, 248, 96, 211, 55, 248, 96, 248, 93, 214, 228, + 249, 134, 205, 73, 216, 188, 199, 107, 207, 101, 210, 203, 233, 64, 217, + 148, 205, 119, 251, 86, 208, 158, 252, 39, 218, 244, 243, 119, 216, 201, + 211, 13, 198, 2, 223, 159, 198, 2, 210, 212, 235, 8, 113, 223, 156, 234, + 67, 234, 68, 4, 235, 119, 64, 58, 242, 219, 217, 109, 4, 218, 235, 232, + 217, 242, 219, 217, 109, 4, 207, 147, 232, 217, 211, 77, 217, 109, 4, + 207, 147, 232, 217, 211, 77, 217, 109, 4, 218, 235, 232, 217, 209, 17, + 209, 18, 228, 187, 214, 75, 216, 4, 209, 194, 216, 4, 209, 195, 4, 96, + 64, 250, 183, 219, 224, 195, 68, 216, 3, 216, 4, 209, 195, 211, 145, 213, + 44, 216, 4, 209, 193, 251, 87, 4, 249, 76, 247, 132, 247, 133, 4, 232, + 208, 195, 65, 247, 132, 199, 104, 207, 165, 195, 64, 233, 0, 208, 193, + 209, 27, 201, 77, 208, 236, 249, 15, 197, 17, 96, 250, 231, 242, 221, 96, + 23, 118, 211, 77, 243, 11, 250, 231, 242, 221, 96, 23, 118, 211, 77, 243, + 11, 250, 232, 4, 47, 91, 210, 255, 242, 221, 235, 119, 23, 196, 66, 211, + 77, 243, 11, 250, 231, 251, 85, 235, 119, 23, 196, 66, 211, 77, 243, 11, + 250, 231, 130, 248, 26, 113, 137, 248, 26, 113, 201, 235, 4, 247, 125, + 106, 201, 234, 201, 235, 4, 91, 202, 5, 193, 138, 201, 235, 4, 115, 202, + 5, 193, 137, 249, 58, 234, 135, 209, 87, 219, 219, 217, 121, 231, 16, + 206, 203, 217, 121, 231, 16, 219, 35, 4, 223, 129, 210, 34, 242, 219, + 219, 35, 4, 221, 222, 221, 222, 219, 34, 211, 77, 219, 34, 248, 235, 248, + 236, 4, 247, 125, 106, 248, 94, 219, 103, 113, 207, 166, 247, 213, 249, + 147, 4, 118, 64, 58, 234, 95, 4, 118, 64, 58, 211, 105, 4, 233, 216, 87, + 4, 45, 50, 64, 58, 202, 15, 4, 96, 64, 58, 198, 54, 4, 196, 66, 64, 58, + 213, 44, 91, 196, 105, 234, 162, 113, 221, 219, 199, 95, 223, 123, 16, + 40, 8, 6, 219, 174, 223, 123, 16, 40, 8, 2, 219, 174, 223, 123, 16, 40, + 212, 135, 223, 123, 16, 40, 200, 76, 223, 123, 16, 40, 8, 219, 174, 232, + 243, 234, 135, 198, 49, 193, 9, 230, 61, 212, 118, 23, 248, 101, 229, 13, + 209, 118, 216, 88, 199, 105, 238, 197, 249, 111, 202, 136, 209, 60, 201, + 103, 4, 82, 236, 140, 223, 19, 16, 40, 248, 248, 197, 236, 234, 111, 62, + 51, 247, 213, 63, 51, 247, 213, 220, 13, 207, 87, 243, 10, 220, 13, 248, + 115, 243, 10, 220, 13, 211, 55, 237, 32, 220, 13, 248, 115, 237, 32, 2, + 211, 55, 237, 32, 2, 248, 115, 237, 32, 196, 76, 207, 87, 197, 241, 235, + 122, 207, 87, 197, 241, 196, 76, 2, 207, 87, 197, 241, 235, 122, 2, 207, + 87, 197, 241, 110, 50, 203, 151, 63, 243, 10, 116, 50, 203, 151, 63, 243, + 10, 47, 238, 218, 209, 41, 238, 218, 209, 42, 4, 230, 67, 60, 238, 218, + 209, 41, 213, 8, 45, 204, 28, 4, 115, 236, 138, 213, 8, 50, 204, 28, 4, + 115, 236, 138, 16, 40, 217, 50, 246, 242, 63, 8, 238, 217, 88, 8, 238, + 217, 247, 26, 238, 217, 211, 114, 113, 235, 125, 79, 210, 60, 222, 125, + 215, 197, 200, 70, 216, 183, 4, 213, 175, 248, 46, 248, 67, 79, 228, 90, + 242, 223, 233, 104, 91, 211, 162, 242, 223, 233, 104, 105, 211, 162, 242, + 223, 233, 104, 115, 211, 162, 242, 223, 233, 104, 232, 128, 211, 162, + 242, 223, 233, 104, 232, 226, 211, 162, 242, 223, 233, 104, 202, 136, + 211, 162, 242, 223, 233, 104, 203, 247, 211, 162, 242, 223, 233, 104, + 234, 164, 211, 162, 242, 223, 233, 104, 213, 175, 211, 162, 242, 223, + 233, 104, 199, 96, 211, 162, 242, 223, 233, 104, 234, 128, 211, 162, 242, + 223, 233, 104, 197, 38, 211, 162, 242, 223, 233, 104, 211, 97, 242, 223, + 233, 104, 197, 11, 242, 223, 233, 104, 198, 217, 242, 223, 233, 104, 232, + 124, 242, 223, 233, 104, 232, 223, 242, 223, 233, 104, 202, 132, 242, + 223, 233, 104, 203, 246, 242, 223, 233, 104, 234, 163, 242, 223, 233, + 104, 213, 173, 242, 223, 233, 104, 199, 94, 242, 223, 233, 104, 234, 126, + 242, 223, 233, 104, 197, 36, 50, 201, 234, 50, 201, 235, 4, 91, 202, 5, + 193, 138, 50, 201, 235, 4, 115, 202, 5, 193, 137, 247, 246, 247, 247, 4, + 202, 5, 193, 137, 206, 186, 248, 235, 248, 96, 247, 123, 217, 75, 242, + 222, 62, 202, 104, 23, 238, 215, 213, 44, 209, 124, 229, 5, 217, 91, 223, + 163, 247, 222, 200, 212, 219, 165, 202, 90, 211, 57, 201, 191, 237, 221, + 200, 194, 201, 221, 201, 222, 193, 118, 222, 183, 217, 91, 237, 239, 45, + 230, 54, 199, 107, 207, 101, 199, 107, 207, 102, 4, 210, 204, 50, 230, + 54, 199, 107, 207, 101, 63, 198, 34, 199, 106, 62, 198, 34, 199, 106, + 199, 107, 211, 105, 198, 54, 79, 216, 0, 242, 245, 216, 4, 209, 194, 249, + 147, 79, 234, 67, 201, 109, 234, 67, 234, 68, 4, 219, 129, 232, 178, 234, + 67, 210, 35, 139, 201, 109, 234, 67, 219, 102, 210, 133, 62, 208, 133, + 110, 45, 210, 33, 110, 45, 249, 105, 210, 34, 110, 45, 232, 130, 210, 34, + 110, 45, 210, 197, 110, 45, 238, 233, 45, 193, 3, 230, 53, 153, 211, 126, + 230, 54, 56, 207, 147, 230, 54, 4, 232, 248, 201, 211, 207, 18, 207, 147, + 230, 54, 4, 232, 248, 201, 211, 207, 18, 198, 211, 133, 56, 207, 18, 198, + 211, 144, 56, 207, 18, 195, 67, 230, 53, 207, 18, 230, 54, 4, 82, 232, + 253, 233, 204, 207, 147, 230, 54, 4, 210, 107, 248, 210, 82, 23, 206, + 189, 232, 247, 63, 144, 209, 58, 45, 230, 54, 223, 148, 202, 206, 63, 45, + 209, 58, 223, 148, 202, 206, 63, 50, 209, 58, 223, 148, 202, 206, 62, 45, + 209, 58, 223, 148, 202, 206, 62, 50, 209, 58, 223, 148, 62, 45, 209, 58, + 249, 144, 223, 148, 62, 50, 209, 58, 249, 144, 223, 148, 202, 206, 63, + 133, 209, 58, 223, 148, 202, 206, 63, 144, 209, 58, 223, 148, 202, 206, + 62, 133, 209, 58, 223, 148, 202, 206, 62, 144, 209, 58, 223, 148, 62, + 133, 209, 58, 249, 144, 223, 148, 62, 144, 209, 58, 249, 144, 223, 148, + 62, 229, 223, 237, 78, 239, 59, 221, 221, 23, 215, 181, 115, 214, 84, + 239, 58, 208, 209, 209, 71, 247, 142, 62, 230, 17, 203, 103, 232, 191, + 236, 220, 63, 230, 17, 203, 103, 232, 191, 236, 220, 202, 32, 203, 103, + 232, 191, 236, 220, 199, 182, 247, 84, 193, 55, 221, 220, 91, 247, 214, + 215, 181, 105, 247, 214, 215, 181, 115, 247, 214, 215, 181, 198, 24, 39, + 209, 249, 239, 59, 230, 17, 236, 220, 205, 76, 208, 210, 228, 20, 233, + 64, 228, 20, 211, 60, 236, 227, 228, 20, 236, 168, 4, 199, 53, 236, 168, + 4, 199, 54, 23, 209, 177, 236, 168, 4, 209, 177, 232, 114, 4, 209, 177, + 232, 114, 4, 198, 150, 232, 114, 4, 251, 133, 192, 235, 62, 232, 171, + 232, 171, 211, 77, 232, 171, 247, 101, 141, 236, 204, 247, 101, 233, 7, + 248, 62, 233, 7, 247, 155, 234, 105, 213, 6, 234, 105, 213, 7, 210, 204, + 234, 105, 213, 7, 210, 210, 213, 6, 213, 7, 210, 204, 213, 7, 210, 210, + 234, 105, 236, 167, 234, 105, 210, 204, 234, 105, 210, 202, 236, 167, + 210, 204, 210, 202, 193, 148, 201, 218, 213, 7, 210, 210, 201, 218, 247, + 141, 210, 210, 237, 78, 193, 65, 216, 38, 217, 22, 211, 2, 242, 221, 50, + 23, 45, 204, 28, 250, 231, 247, 125, 192, 235, 223, 154, 232, 163, 202, + 116, 113, 237, 134, 232, 163, 202, 116, 113, 239, 60, 39, 221, 222, 206, + 140, 214, 75, 210, 205, 4, 47, 199, 53, 201, 67, 243, 136, 238, 15, 221, + 78, 219, 96, 201, 233, 229, 236, 223, 163, 202, 187, 115, 207, 120, 58, + 115, 207, 120, 60, 115, 207, 120, 219, 224, 115, 207, 120, 183, 45, 201, + 230, 248, 8, 50, 201, 230, 248, 8, 105, 201, 230, 248, 7, 115, 201, 230, + 248, 7, 45, 198, 231, 248, 8, 50, 198, 231, 248, 8, 45, 251, 119, 248, 8, + 50, 251, 119, 248, 8, 215, 210, 248, 8, 219, 130, 215, 210, 248, 8, 219, + 130, 215, 209, 249, 107, 111, 4, 249, 106, 249, 107, 27, 192, 235, 249, + 107, 111, 4, 27, 192, 235, 249, 107, 28, 27, 192, 235, 249, 107, 111, 4, + 28, 27, 192, 235, 156, 243, 126, 77, 249, 107, 111, 4, 28, 243, 125, 193, + 18, 217, 71, 215, 186, 232, 81, 198, 85, 198, 30, 201, 92, 79, 219, 144, + 202, 188, 79, 223, 20, 215, 167, 230, 196, 233, 103, 230, 196, 233, 104, + 4, 202, 64, 233, 185, 233, 104, 4, 199, 126, 79, 222, 185, 202, 64, 233, + 104, 4, 211, 77, 215, 179, 202, 64, 233, 104, 4, 211, 77, 215, 180, 23, + 202, 64, 233, 185, 202, 64, 233, 104, 4, 211, 77, 215, 180, 23, 242, 87, + 200, 143, 202, 64, 233, 104, 4, 211, 77, 215, 180, 23, 198, 171, 233, + 185, 202, 64, 233, 104, 4, 230, 66, 202, 64, 233, 104, 4, 228, 186, 193, + 57, 233, 103, 202, 64, 233, 104, 4, 202, 64, 233, 185, 233, 104, 205, + 109, 237, 114, 232, 161, 207, 61, 233, 103, 202, 64, 233, 104, 4, 229, + 222, 233, 185, 202, 64, 233, 104, 4, 200, 194, 202, 63, 233, 103, 214, + 82, 233, 103, 233, 206, 233, 103, 196, 111, 233, 103, 233, 104, 4, 242, + 87, 200, 143, 210, 26, 233, 103, 239, 51, 233, 103, 239, 52, 233, 103, + 221, 121, 233, 103, 233, 104, 198, 214, 42, 221, 122, 221, 121, 233, 104, + 4, 202, 64, 233, 185, 221, 121, 233, 104, 4, 242, 219, 233, 185, 233, + 104, 4, 201, 12, 198, 61, 233, 104, 4, 201, 12, 198, 62, 23, 193, 57, + 233, 193, 233, 104, 4, 201, 12, 198, 62, 23, 198, 171, 233, 185, 236, + 228, 233, 103, 193, 16, 233, 103, 251, 111, 233, 103, 209, 6, 233, 103, + 238, 199, 233, 103, 209, 253, 233, 103, 233, 104, 4, 219, 7, 79, 197, + 217, 236, 228, 247, 218, 207, 61, 233, 103, 232, 92, 233, 104, 4, 211, + 77, 215, 179, 251, 109, 233, 103, 233, 57, 233, 103, 193, 119, 233, 103, + 202, 91, 233, 103, 198, 130, 233, 103, 230, 197, 233, 103, 218, 245, 238, + 199, 233, 103, 233, 104, 4, 211, 77, 215, 179, 228, 130, 233, 103, 233, + 104, 4, 211, 77, 215, 180, 23, 242, 87, 200, 143, 233, 104, 205, 78, 223, + 163, 233, 58, 250, 190, 233, 103, 232, 183, 233, 103, 202, 92, 233, 103, + 236, 195, 233, 103, 233, 104, 193, 51, 215, 179, 233, 104, 4, 216, 216, + 217, 35, 230, 196, 247, 79, 233, 104, 4, 202, 64, 233, 185, 247, 79, 233, + 104, 4, 199, 126, 79, 222, 185, 202, 64, 247, 79, 233, 104, 4, 211, 77, + 215, 179, 202, 64, 247, 79, 233, 104, 4, 229, 222, 233, 185, 247, 79, + 233, 104, 4, 193, 1, 202, 65, 221, 121, 247, 79, 233, 104, 4, 242, 219, + 233, 185, 209, 6, 247, 79, 233, 103, 238, 199, 247, 79, 233, 103, 193, + 119, 247, 79, 233, 103, 202, 84, 232, 92, 233, 103, 202, 84, 202, 64, + 233, 103, 196, 72, 233, 103, 233, 104, 4, 206, 138, 233, 185, 233, 104, + 4, 213, 44, 230, 244, 231, 132, 233, 104, 4, 211, 126, 231, 132, 209, + 251, 248, 68, 237, 129, 205, 49, 215, 225, 229, 226, 215, 225, 201, 236, + 215, 225, 230, 20, 209, 251, 207, 145, 91, 230, 53, 209, 251, 207, 145, + 248, 80, 230, 29, 223, 163, 247, 28, 209, 251, 232, 91, 209, 251, 4, 209, + 6, 233, 103, 209, 251, 4, 232, 172, 230, 28, 186, 193, 105, 209, 58, 219, + 233, 202, 2, 193, 105, 209, 58, 219, 233, 186, 234, 204, 209, 58, 219, + 233, 202, 2, 234, 204, 209, 58, 219, 233, 153, 186, 193, 105, 209, 58, + 219, 233, 153, 202, 2, 193, 105, 209, 58, 219, 233, 153, 186, 234, 204, + 209, 58, 219, 233, 153, 202, 2, 234, 204, 209, 58, 219, 233, 186, 193, + 105, 209, 58, 195, 48, 219, 233, 202, 2, 193, 105, 209, 58, 195, 48, 219, + 233, 186, 234, 204, 209, 58, 195, 48, 219, 233, 202, 2, 234, 204, 209, + 58, 195, 48, 219, 233, 88, 186, 193, 105, 209, 58, 195, 48, 219, 233, 88, + 202, 2, 193, 105, 209, 58, 195, 48, 219, 233, 88, 186, 234, 204, 209, 58, + 195, 48, 219, 233, 88, 202, 2, 234, 204, 209, 58, 195, 48, 219, 233, 186, + 193, 105, 209, 58, 248, 4, 202, 2, 193, 105, 209, 58, 248, 4, 186, 234, + 204, 209, 58, 248, 4, 202, 2, 234, 204, 209, 58, 248, 4, 88, 186, 193, + 105, 209, 58, 248, 4, 88, 202, 2, 193, 105, 209, 58, 248, 4, 88, 186, + 234, 204, 209, 58, 248, 4, 88, 202, 2, 234, 204, 209, 58, 248, 4, 229, 4, + 208, 6, 51, 211, 42, 229, 4, 208, 6, 51, 211, 43, 223, 163, 62, 201, 190, + 202, 25, 208, 6, 51, 211, 42, 202, 25, 208, 6, 51, 211, 43, 223, 163, 62, + 201, 190, 118, 206, 146, 196, 66, 206, 146, 96, 206, 146, 235, 119, 206, + 146, 27, 34, 234, 0, 211, 42, 88, 27, 34, 234, 0, 211, 42, 34, 211, 77, + 234, 0, 211, 42, 88, 34, 211, 77, 234, 0, 211, 42, 88, 251, 138, 211, 42, + 200, 146, 251, 138, 211, 42, 49, 88, 55, 153, 242, 75, 207, 252, 87, 211, + 42, 49, 88, 55, 242, 75, 207, 252, 87, 211, 42, 49, 88, 130, 55, 242, 75, + 207, 252, 87, 211, 42, 88, 223, 103, 211, 42, 49, 223, 103, 211, 42, 88, + 49, 223, 103, 211, 42, 195, 83, 88, 202, 23, 195, 83, 88, 207, 19, 202, + 23, 243, 124, 248, 107, 207, 19, 243, 124, 248, 107, 206, 146, 229, 205, + 201, 85, 219, 32, 207, 152, 247, 102, 229, 131, 198, 16, 229, 131, 198, + 17, 4, 247, 249, 213, 13, 198, 16, 216, 158, 156, 207, 153, 201, 93, 198, + 14, 198, 15, 247, 102, 247, 223, 211, 101, 247, 223, 197, 212, 247, 224, + 201, 63, 216, 42, 251, 142, 232, 244, 234, 87, 209, 50, 247, 102, 211, + 101, 209, 50, 247, 102, 199, 155, 211, 101, 199, 155, 250, 150, 211, 101, + 250, 150, 207, 94, 195, 145, 237, 110, 197, 203, 250, 225, 218, 254, 198, + 23, 215, 218, 215, 185, 207, 151, 200, 164, 207, 151, 215, 185, 247, 154, + 252, 11, 198, 13, 203, 65, 206, 112, 201, 228, 228, 241, 198, 20, 219, + 132, 81, 198, 20, 219, 132, 239, 37, 56, 209, 50, 247, 86, 207, 12, 219, + 132, 197, 238, 232, 218, 211, 105, 209, 19, 236, 144, 213, 44, 234, 73, + 56, 202, 62, 113, 213, 44, 202, 62, 113, 208, 132, 219, 84, 223, 163, + 223, 50, 209, 108, 113, 236, 175, 213, 12, 219, 84, 113, 209, 13, 193, + 144, 113, 213, 28, 193, 144, 113, 248, 184, 213, 44, 248, 183, 248, 182, + 215, 185, 248, 182, 210, 51, 213, 44, 210, 50, 243, 85, 238, 209, 216, + 182, 113, 193, 32, 113, 207, 28, 249, 149, 113, 198, 86, 193, 144, 242, + 216, 203, 20, 249, 61, 249, 59, 210, 91, 239, 21, 238, 156, 249, 126, + 242, 246, 45, 218, 215, 197, 242, 4, 206, 113, 239, 0, 208, 196, 56, 47, + 223, 137, 202, 3, 248, 59, 113, 231, 27, 113, 238, 248, 23, 220, 25, 202, + 92, 252, 57, 203, 43, 249, 125, 248, 234, 248, 235, 249, 2, 209, 108, 79, + 193, 15, 211, 159, 56, 203, 43, 197, 213, 201, 8, 210, 201, 229, 127, + 199, 98, 228, 129, 234, 130, 193, 54, 209, 96, 202, 87, 193, 93, 206, + 189, 247, 233, 230, 62, 23, 193, 9, 203, 78, 211, 132, 235, 94, 215, 189, + 207, 152, 198, 25, 215, 192, 248, 106, 196, 76, 216, 54, 251, 223, 196, + 76, 251, 223, 196, 76, 2, 251, 223, 2, 251, 223, 213, 17, 251, 223, 251, + 224, 237, 93, 251, 224, 250, 238, 205, 118, 211, 101, 232, 244, 234, 87, + 237, 22, 219, 32, 210, 95, 203, 65, 205, 83, 215, 192, 205, 83, 247, 113, + 202, 94, 232, 178, 205, 113, 202, 111, 250, 152, 206, 243, 209, 178, 197, + 203, 206, 139, 202, 112, 160, 16, 40, 208, 2, 160, 16, 40, 251, 225, 160, + 16, 40, 232, 243, 160, 16, 40, 234, 207, 160, 16, 40, 193, 143, 160, 16, + 40, 251, 35, 160, 16, 40, 251, 36, 207, 81, 160, 16, 40, 251, 36, 207, + 80, 160, 16, 40, 251, 36, 195, 31, 160, 16, 40, 251, 36, 195, 30, 160, + 16, 40, 195, 45, 160, 16, 40, 195, 44, 160, 16, 40, 195, 43, 160, 16, 40, + 200, 205, 160, 16, 40, 209, 203, 200, 205, 160, 16, 40, 62, 200, 205, + 160, 16, 40, 216, 181, 200, 236, 160, 16, 40, 216, 181, 200, 235, 160, + 16, 40, 216, 181, 200, 234, 160, 16, 40, 243, 13, 160, 16, 40, 205, 158, + 160, 16, 40, 213, 161, 160, 16, 40, 195, 28, 160, 16, 40, 195, 27, 160, + 16, 40, 206, 148, 205, 158, 160, 16, 40, 206, 148, 205, 157, 160, 16, 40, + 230, 250, 160, 16, 40, 202, 184, 160, 16, 40, 223, 74, 211, 49, 160, 16, + 40, 223, 74, 211, 48, 160, 16, 40, 238, 222, 79, 223, 73, 160, 16, 40, + 207, 77, 79, 223, 73, 160, 16, 40, 239, 12, 211, 49, 160, 16, 40, 223, + 72, 211, 49, 160, 16, 40, 200, 237, 79, 239, 11, 160, 16, 40, 238, 222, + 79, 239, 11, 160, 16, 40, 238, 222, 79, 239, 10, 160, 16, 40, 239, 12, + 251, 79, 160, 16, 40, 205, 159, 79, 239, 12, 251, 79, 160, 16, 40, 200, + 237, 79, 205, 159, 79, 239, 11, 160, 16, 40, 195, 139, 160, 16, 40, 198, + 143, 211, 49, 160, 16, 40, 219, 237, 211, 49, 160, 16, 40, 251, 78, 211, + 49, 160, 16, 40, 200, 237, 79, 251, 77, 160, 16, 40, 205, 159, 79, 251, + 77, 160, 16, 40, 200, 237, 79, 205, 159, 79, 251, 77, 160, 16, 40, 195, + 46, 79, 251, 77, 160, 16, 40, 207, 77, 79, 251, 77, 160, 16, 40, 207, 77, + 79, 251, 76, 160, 16, 40, 207, 76, 160, 16, 40, 207, 75, 160, 16, 40, + 207, 74, 160, 16, 40, 207, 73, 160, 16, 40, 251, 177, 160, 16, 40, 251, + 176, 160, 16, 40, 217, 61, 160, 16, 40, 205, 168, 160, 16, 40, 250, 230, + 160, 16, 40, 207, 105, 160, 16, 40, 207, 104, 160, 16, 40, 250, 154, 160, + 16, 40, 248, 150, 211, 49, 160, 16, 40, 199, 177, 160, 16, 40, 199, 176, + 160, 16, 40, 208, 8, 219, 121, 160, 16, 40, 248, 87, 160, 16, 40, 248, + 86, 160, 16, 40, 248, 85, 160, 16, 40, 251, 151, 160, 16, 40, 211, 131, + 160, 16, 40, 201, 214, 160, 16, 40, 198, 141, 160, 16, 40, 230, 158, 160, + 16, 40, 193, 131, 160, 16, 40, 209, 1, 160, 16, 40, 247, 137, 160, 16, + 40, 197, 50, 160, 16, 40, 247, 104, 215, 198, 160, 16, 40, 205, 93, 79, + 222, 187, 160, 16, 40, 247, 151, 160, 16, 40, 197, 235, 160, 16, 40, 201, + 100, 197, 235, 160, 16, 40, 219, 31, 160, 16, 40, 202, 37, 160, 16, 40, + 196, 54, 160, 16, 40, 228, 184, 235, 71, 160, 16, 40, 250, 204, 160, 16, + 40, 209, 15, 250, 204, 160, 16, 40, 248, 31, 160, 16, 40, 209, 0, 248, + 31, 160, 16, 40, 251, 148, 160, 16, 40, 201, 46, 200, 186, 201, 45, 160, + 16, 40, 201, 46, 200, 186, 201, 44, 160, 16, 40, 200, 233, 160, 16, 40, + 208, 229, 160, 16, 40, 236, 215, 160, 16, 40, 236, 217, 160, 16, 40, 236, + 216, 160, 16, 40, 208, 141, 160, 16, 40, 208, 129, 160, 16, 40, 238, 207, + 160, 16, 40, 238, 206, 160, 16, 40, 238, 205, 160, 16, 40, 238, 204, 160, + 16, 40, 238, 203, 160, 16, 40, 251, 191, 160, 16, 40, 249, 62, 79, 217, + 42, 160, 16, 40, 249, 62, 79, 195, 174, 160, 16, 40, 207, 26, 160, 16, + 40, 228, 176, 160, 16, 40, 213, 190, 160, 16, 40, 237, 203, 160, 16, 40, + 215, 213, 160, 16, 40, 132, 235, 109, 160, 16, 40, 132, 211, 17, 218, + 250, 79, 232, 137, 211, 164, 218, 207, 234, 194, 230, 1, 217, 101, 230, + 246, 208, 24, 211, 52, 62, 219, 219, 223, 56, 50, 197, 241, 62, 196, 76, + 223, 56, 50, 197, 241, 62, 206, 203, 223, 56, 50, 197, 241, 62, 235, 122, + 223, 56, 50, 197, 241, 62, 202, 84, 2, 243, 10, 216, 213, 28, 63, 243, + 10, 28, 63, 243, 10, 88, 63, 243, 10, 195, 83, 88, 63, 243, 10, 233, 197, + 88, 63, 243, 10, 63, 243, 11, 239, 33, 62, 2, 243, 10, 206, 115, 199, + 178, 62, 198, 138, 201, 190, 62, 202, 84, 2, 201, 190, 156, 63, 201, 190, + 216, 213, 63, 201, 190, 28, 63, 201, 190, 88, 63, 201, 190, 195, 83, 88, + 63, 201, 190, 233, 197, 88, 63, 201, 190, 63, 51, 239, 33, 62, 195, 83, + 2, 201, 190, 63, 51, 239, 33, 62, 216, 213, 201, 190, 51, 199, 178, 62, + 198, 138, 237, 32, 62, 195, 83, 2, 237, 32, 62, 216, 213, 2, 237, 32, 63, + 237, 33, 239, 33, 62, 195, 83, 2, 237, 32, 63, 237, 33, 239, 33, 62, 216, + 213, 237, 32, 237, 33, 199, 178, 62, 198, 138, 218, 232, 62, 195, 83, 2, + 218, 232, 62, 216, 213, 2, 218, 232, 63, 218, 233, 239, 33, 62, 2, 218, + 232, 199, 4, 35, 238, 217, 156, 35, 238, 217, 216, 213, 35, 238, 217, 28, + 35, 238, 217, 195, 83, 28, 35, 238, 217, 195, 83, 88, 35, 238, 217, 233, + 197, 88, 35, 238, 217, 199, 4, 205, 154, 156, 205, 154, 216, 213, 205, + 154, 28, 205, 154, 88, 205, 154, 195, 83, 88, 205, 154, 233, 197, 88, + 205, 154, 156, 232, 226, 201, 206, 250, 193, 216, 213, 232, 226, 201, + 206, 250, 193, 28, 232, 226, 201, 206, 250, 193, 88, 232, 226, 201, 206, + 250, 193, 195, 83, 88, 232, 226, 201, 206, 250, 193, 233, 197, 88, 232, + 226, 201, 206, 250, 193, 156, 202, 136, 201, 206, 250, 193, 216, 213, + 202, 136, 201, 206, 250, 193, 28, 202, 136, 201, 206, 250, 193, 88, 202, + 136, 201, 206, 250, 193, 195, 83, 88, 202, 136, 201, 206, 250, 193, 233, + 197, 88, 202, 136, 201, 206, 250, 193, 156, 234, 164, 201, 206, 250, 193, + 216, 213, 234, 164, 201, 206, 250, 193, 28, 234, 164, 201, 206, 250, 193, + 88, 234, 164, 201, 206, 250, 193, 195, 83, 88, 234, 164, 201, 206, 250, + 193, 156, 115, 209, 60, 62, 201, 102, 216, 213, 115, 209, 60, 62, 201, + 102, 115, 209, 60, 62, 201, 102, 216, 213, 115, 209, 60, 209, 130, 201, + 102, 156, 232, 128, 209, 60, 62, 201, 102, 216, 213, 232, 128, 209, 60, + 62, 201, 102, 232, 128, 209, 60, 62, 201, 102, 216, 213, 232, 128, 209, + 60, 209, 130, 201, 102, 207, 19, 156, 232, 128, 209, 60, 209, 130, 201, + 102, 156, 232, 226, 209, 60, 62, 201, 102, 88, 232, 226, 209, 60, 62, + 201, 102, 216, 213, 202, 136, 209, 60, 62, 201, 102, 88, 202, 136, 209, + 60, 62, 201, 102, 202, 136, 209, 60, 209, 130, 201, 102, 216, 213, 234, + 164, 209, 60, 62, 201, 102, 88, 234, 164, 209, 60, 62, 201, 102, 195, 83, + 88, 234, 164, 209, 60, 62, 201, 102, 88, 234, 164, 209, 60, 209, 130, + 201, 102, 156, 197, 38, 209, 60, 62, 201, 102, 88, 197, 38, 209, 60, 62, + 201, 102, 88, 197, 38, 209, 60, 209, 130, 201, 102, 47, 197, 241, 214, + 106, 47, 197, 241, 47, 201, 190, 214, 106, 47, 201, 190, 213, 175, 209, + 60, 63, 201, 102, 220, 13, 211, 55, 243, 10, 220, 13, 192, 73, 243, 10, + 220, 13, 230, 201, 243, 10, 220, 13, 208, 138, 243, 10, 220, 13, 248, 19, + 243, 10, 220, 13, 207, 87, 201, 190, 220, 13, 248, 115, 201, 190, 220, + 13, 211, 55, 201, 190, 220, 13, 192, 73, 201, 190, 220, 13, 230, 201, + 201, 190, 220, 13, 208, 138, 201, 190, 220, 13, 248, 19, 201, 190, 88, + 234, 43, 56, 118, 64, 4, 2, 197, 242, 250, 235, 196, 66, 64, 4, 2, 197, + 242, 250, 235, 96, 64, 4, 2, 197, 242, 250, 235, 235, 119, 64, 4, 2, 197, + 242, 250, 235, 118, 64, 4, 216, 213, 197, 242, 250, 235, 196, 66, 64, 4, + 216, 213, 197, 242, 250, 235, 96, 64, 4, 216, 213, 197, 242, 250, 235, + 235, 119, 64, 4, 216, 213, 197, 242, 250, 235, 118, 64, 4, 220, 13, 197, + 242, 250, 235, 196, 66, 64, 4, 220, 13, 197, 242, 250, 235, 96, 64, 4, + 220, 13, 197, 242, 250, 235, 235, 119, 64, 4, 220, 13, 197, 242, 250, + 235, 118, 64, 4, 2, 234, 37, 250, 235, 196, 66, 64, 4, 2, 234, 37, 250, + 235, 96, 64, 4, 2, 234, 37, 250, 235, 235, 119, 64, 4, 2, 234, 37, 250, + 235, 118, 64, 4, 234, 37, 250, 235, 196, 66, 64, 4, 234, 37, 250, 235, + 96, 64, 4, 234, 37, 250, 235, 235, 119, 64, 4, 234, 37, 250, 235, 88, + 118, 64, 4, 234, 37, 250, 235, 88, 196, 66, 64, 4, 234, 37, 250, 235, 88, + 96, 64, 4, 234, 37, 250, 235, 88, 235, 119, 64, 4, 234, 37, 250, 235, 88, + 118, 64, 4, 220, 13, 234, 37, 250, 235, 88, 196, 66, 64, 4, 220, 13, 234, + 37, 250, 235, 88, 96, 64, 4, 220, 13, 234, 37, 250, 235, 88, 235, 119, + 64, 4, 220, 13, 234, 37, 250, 235, 118, 197, 240, 64, 4, 214, 215, 203, + 149, 196, 66, 197, 240, 64, 4, 214, 215, 203, 149, 96, 197, 240, 64, 4, + 214, 215, 203, 149, 235, 119, 197, 240, 64, 4, 214, 215, 203, 149, 118, + 197, 240, 64, 4, 216, 213, 203, 149, 196, 66, 197, 240, 64, 4, 216, 213, + 203, 149, 96, 197, 240, 64, 4, 216, 213, 203, 149, 235, 119, 197, 240, + 64, 4, 216, 213, 203, 149, 118, 197, 240, 64, 4, 28, 203, 149, 196, 66, + 197, 240, 64, 4, 28, 203, 149, 96, 197, 240, 64, 4, 28, 203, 149, 235, + 119, 197, 240, 64, 4, 28, 203, 149, 118, 197, 240, 64, 4, 88, 203, 149, + 196, 66, 197, 240, 64, 4, 88, 203, 149, 96, 197, 240, 64, 4, 88, 203, + 149, 235, 119, 197, 240, 64, 4, 88, 203, 149, 118, 197, 240, 64, 4, 195, + 83, 88, 203, 149, 196, 66, 197, 240, 64, 4, 195, 83, 88, 203, 149, 96, + 197, 240, 64, 4, 195, 83, 88, 203, 149, 235, 119, 197, 240, 64, 4, 195, + 83, 88, 203, 149, 118, 232, 251, 57, 196, 66, 232, 251, 57, 96, 232, 251, + 57, 235, 119, 232, 251, 57, 118, 112, 57, 196, 66, 112, 57, 96, 112, 57, + 235, 119, 112, 57, 118, 239, 61, 57, 196, 66, 239, 61, 57, 96, 239, 61, + 57, 235, 119, 239, 61, 57, 118, 88, 239, 61, 57, 196, 66, 88, 239, 61, + 57, 96, 88, 239, 61, 57, 235, 119, 88, 239, 61, 57, 118, 88, 57, 196, 66, + 88, 57, 96, 88, 57, 235, 119, 88, 57, 118, 49, 57, 196, 66, 49, 57, 96, + 49, 57, 235, 119, 49, 57, 186, 193, 105, 49, 57, 186, 234, 204, 49, 57, + 202, 2, 234, 204, 49, 57, 202, 2, 193, 105, 49, 57, 45, 50, 49, 57, 133, + 144, 49, 57, 193, 77, 118, 156, 181, 57, 193, 77, 196, 66, 156, 181, 57, + 193, 77, 96, 156, 181, 57, 193, 77, 235, 119, 156, 181, 57, 193, 77, 186, + 193, 105, 156, 181, 57, 193, 77, 186, 234, 204, 156, 181, 57, 193, 77, + 202, 2, 234, 204, 156, 181, 57, 193, 77, 202, 2, 193, 105, 156, 181, 57, + 193, 77, 118, 181, 57, 193, 77, 196, 66, 181, 57, 193, 77, 96, 181, 57, + 193, 77, 235, 119, 181, 57, 193, 77, 186, 193, 105, 181, 57, 193, 77, + 186, 234, 204, 181, 57, 193, 77, 202, 2, 234, 204, 181, 57, 193, 77, 202, + 2, 193, 105, 181, 57, 193, 77, 118, 216, 213, 181, 57, 193, 77, 196, 66, + 216, 213, 181, 57, 193, 77, 96, 216, 213, 181, 57, 193, 77, 235, 119, + 216, 213, 181, 57, 193, 77, 186, 193, 105, 216, 213, 181, 57, 193, 77, + 186, 234, 204, 216, 213, 181, 57, 193, 77, 202, 2, 234, 204, 216, 213, + 181, 57, 193, 77, 202, 2, 193, 105, 216, 213, 181, 57, 193, 77, 118, 88, + 181, 57, 193, 77, 196, 66, 88, 181, 57, 193, 77, 96, 88, 181, 57, 193, + 77, 235, 119, 88, 181, 57, 193, 77, 186, 193, 105, 88, 181, 57, 193, 77, + 186, 234, 204, 88, 181, 57, 193, 77, 202, 2, 234, 204, 88, 181, 57, 193, + 77, 202, 2, 193, 105, 88, 181, 57, 193, 77, 118, 195, 83, 88, 181, 57, + 193, 77, 196, 66, 195, 83, 88, 181, 57, 193, 77, 96, 195, 83, 88, 181, + 57, 193, 77, 235, 119, 195, 83, 88, 181, 57, 193, 77, 186, 193, 105, 195, + 83, 88, 181, 57, 193, 77, 186, 234, 204, 195, 83, 88, 181, 57, 193, 77, + 202, 2, 234, 204, 195, 83, 88, 181, 57, 193, 77, 202, 2, 193, 105, 195, + 83, 88, 181, 57, 118, 197, 242, 250, 235, 196, 66, 197, 242, 250, 235, + 96, 197, 242, 250, 235, 235, 119, 197, 242, 250, 235, 118, 63, 64, 193, + 53, 197, 242, 250, 235, 196, 66, 63, 64, 193, 53, 197, 242, 250, 235, 96, + 63, 64, 193, 53, 197, 242, 250, 235, 235, 119, 63, 64, 193, 53, 197, 242, + 250, 235, 118, 64, 4, 213, 8, 199, 215, 196, 66, 64, 4, 213, 8, 199, 215, + 96, 64, 4, 213, 8, 199, 215, 235, 119, 64, 4, 213, 8, 199, 215, 88, 64, + 203, 150, 193, 75, 107, 88, 64, 203, 150, 193, 75, 105, 198, 253, 88, 64, + 203, 150, 193, 75, 91, 230, 70, 88, 64, 203, 150, 193, 75, 91, 199, 0, + 118, 248, 74, 63, 57, 96, 248, 77, 203, 152, 63, 57, 118, 198, 54, 203, + 152, 63, 57, 96, 198, 54, 203, 152, 63, 57, 118, 219, 218, 63, 57, 96, + 206, 202, 63, 57, 118, 206, 202, 63, 57, 96, 219, 218, 63, 57, 118, 249, + 145, 203, 151, 63, 57, 96, 249, 145, 203, 151, 63, 57, 118, 232, 95, 203, + 151, 63, 57, 96, 232, 95, 203, 151, 63, 57, 63, 64, 203, 150, 193, 75, + 107, 63, 64, 203, 150, 193, 75, 105, 198, 253, 64, 209, 58, 196, 66, 199, + 25, 186, 193, 104, 64, 209, 58, 96, 199, 25, 238, 161, 202, 2, 193, 104, + 47, 238, 218, 232, 143, 4, 232, 128, 236, 138, 47, 238, 218, 232, 143, 4, + 105, 236, 138, 47, 238, 218, 232, 142, 45, 132, 243, 11, 4, 232, 128, + 236, 138, 45, 132, 243, 11, 4, 115, 236, 138, 45, 132, 243, 11, 4, 105, + 236, 138, 45, 132, 243, 11, 4, 236, 140, 45, 132, 243, 10, 235, 120, 233, + 96, 102, 235, 120, 233, 96, 213, 8, 102, 235, 120, 233, 96, 228, 251, 4, + 236, 140, 235, 120, 233, 96, 213, 8, 228, 251, 4, 236, 140, 209, 136, + 232, 247, 63, 229, 223, 248, 19, 229, 223, 209, 135, 230, 53, 191, 17, + 233, 103, 215, 229, 233, 103, 233, 104, 4, 199, 21, 214, 92, 233, 103, + 199, 2, 233, 103, 233, 104, 4, 229, 234, 206, 150, 233, 103, 228, 150, + 233, 103, 3, 79, 199, 34, 228, 186, 247, 139, 216, 233, 230, 53, 207, + 147, 249, 147, 79, 230, 53, 219, 223, 232, 231, 206, 207, 232, 231, 230, + 27, 230, 54, 4, 141, 23, 82, 232, 248, 238, 213, 228, 74, 218, 242, 191, + 239, 230, 54, 56, 233, 104, 4, 238, 238, 230, 9, 242, 208, 233, 103, 214, + 202, 233, 103, 206, 138, 211, 105, 199, 34, 232, 194, 219, 255, 235, 100, + 233, 103, 218, 178, 233, 103, 233, 104, 210, 182, 202, 56, 233, 103, 233, + 104, 4, 91, 233, 192, 207, 146, 230, 196, 233, 104, 4, 201, 103, 233, + 185, 230, 196, 233, 104, 4, 91, 220, 13, 23, 91, 2, 233, 193, 233, 104, + 4, 232, 253, 238, 241, 242, 219, 219, 96, 204, 2, 233, 104, 4, 200, 77, + 238, 241, 215, 179, 202, 64, 233, 104, 4, 202, 64, 233, 186, 23, 230, 54, + 238, 241, 215, 179, 233, 104, 4, 211, 77, 215, 180, 195, 9, 203, 54, 233, + 104, 4, 233, 208, 229, 235, 208, 226, 193, 35, 248, 40, 210, 181, 133, + 198, 87, 204, 31, 208, 214, 217, 91, 223, 163, 197, 46, 215, 194, 243, + 55, 203, 9, 209, 251, 236, 159, 247, 83, 222, 177, 233, 38, 215, 255, + 210, 21, 193, 8, 193, 144, 209, 44, 230, 32, 236, 201, 217, 35, 193, 69, + 232, 186, 235, 95, 4, 235, 93, 242, 226, 231, 15, 197, 74, 231, 16, 201, + 203, 231, 1, 214, 85, 206, 208, 232, 238, 209, 108, 216, 219, 205, 57, + 209, 108, 216, 219, 199, 1, 209, 108, 216, 219, 248, 61, 231, 10, 217, + 46, 250, 223, 196, 94, 238, 172, 201, 65, 220, 110, 201, 75, 23, 249, + 111, 202, 31, 232, 178, 236, 226, 238, 221, 250, 141, 238, 188, 249, 138, + 209, 12, 247, 87, 249, 124, 248, 43, 230, 201, 205, 165, 203, 142, 210, + 167, 79, 232, 161, 201, 9, 232, 205, 234, 179, 231, 17, 79, 216, 53, 210, + 56, 221, 116, 210, 163, 235, 76, 232, 138, 239, 16, 199, 207, 248, 62, + 243, 62, 248, 67, 4, 201, 203, 238, 182, 4, 201, 43, 242, 93, 248, 23, + 209, 176, 208, 218, 238, 155, 79, 216, 224, 205, 137, 247, 115, 232, 161, + 219, 232, 230, 200, 217, 82, 215, 206, 247, 146, 249, 127, 202, 64, 233, + 104, 4, 202, 64, 233, 186, 23, 115, 229, 221, 192, 87, 233, 103, 202, 64, + 233, 104, 4, 199, 131, 233, 104, 4, 210, 102, 228, 188, 23, 210, 102, + 230, 9, 233, 104, 4, 196, 98, 233, 186, 23, 193, 135, 215, 179, 211, 5, + 233, 103, 232, 107, 233, 103, 213, 168, 236, 224, 233, 103, 233, 104, + 229, 6, 249, 147, 199, 125, 233, 104, 4, 209, 93, 233, 185, 205, 125, + 220, 119, 242, 96, 230, 253, 229, 129, 248, 91, 232, 207, 203, 52, 238, + 235, 219, 100, 233, 103, 205, 81, 197, 62, 196, 96, 233, 103, 234, 214, + 235, 85, 249, 64, 203, 128, 210, 249, 232, 120, 233, 103, 247, 215, 237, + 128, 230, 235, 219, 78, 207, 5, 203, 13, 201, 184, 231, 29, 233, 103, + 191, 85, 233, 103, 229, 216, 205, 110, 200, 42, 238, 224, 222, 82, 219, + 70, 210, 58, 229, 121, 210, 108, 207, 173, 219, 41, 215, 196, 216, 90, + 249, 133, 200, 148, 217, 92, 236, 165, 202, 78, 211, 22, 211, 54, 202, + 102, 232, 209, 210, 239, 249, 4, 248, 149, 205, 61, 230, 163, 236, 162, + 208, 202, 247, 117, 234, 109, 242, 64, 207, 87, 230, 78, 234, 109, 242, + 64, 238, 171, 230, 78, 234, 109, 242, 64, 249, 113, 234, 109, 242, 64, + 63, 230, 78, 248, 98, 219, 212, 232, 159, 198, 56, 200, 184, 200, 179, + 205, 188, 195, 81, 234, 212, 4, 229, 225, 251, 235, 215, 190, 193, 91, + 217, 74, 193, 91, 216, 223, 250, 250, 216, 223, 219, 212, 243, 118, 193, + 116, 238, 180, 205, 159, 203, 146, 248, 208, 248, 62, 231, 197, 211, 93, + 233, 85, 193, 174, 247, 216, 217, 29, 235, 104, 228, 27, 238, 190, 248, + 9, 199, 134, 197, 214, 201, 105, 209, 250, 221, 80, 209, 250, 237, 144, + 209, 250, 233, 104, 4, 215, 224, 252, 29, 243, 86, 211, 118, 252, 29, + 249, 8, 209, 250, 209, 251, 4, 229, 230, 209, 251, 223, 163, 201, 82, + 206, 130, 209, 251, 242, 228, 209, 251, 223, 163, 218, 247, 209, 24, 217, + 124, 233, 87, 195, 177, 216, 174, 234, 125, 231, 148, 191, 5, 248, 50, + 211, 55, 229, 223, 248, 171, 247, 111, 205, 94, 231, 9, 242, 96, 202, 34, + 207, 87, 231, 43, 234, 67, 232, 242, 222, 238, 208, 125, 209, 175, 199, + 75, 197, 84, 209, 235, 236, 222, 236, 176, 55, 229, 204, 242, 69, 252, + 71, 232, 244, 233, 202, 198, 58, 248, 31, 217, 122, 218, 215, 218, 248, + 248, 78, 201, 204, 79, 198, 227, 249, 112, 79, 192, 100, 205, 188, 209, + 139, 199, 124, 249, 9, 248, 20, 249, 69, 206, 141, 79, 210, 135, 249, 88, + 79, 202, 37, 201, 205, 207, 103, 214, 196, 251, 134, 214, 82, 243, 105, + 221, 138, 214, 82, 243, 105, 208, 14, 214, 82, 243, 105, 206, 131, 214, + 82, 243, 105, 248, 152, 214, 82, 243, 105, 221, 76, 214, 82, 243, 105, + 210, 74, 63, 243, 105, 221, 77, 206, 122, 232, 134, 237, 124, 62, 243, + 105, 221, 77, 206, 122, 232, 134, 237, 124, 214, 82, 243, 105, 221, 77, + 206, 122, 232, 134, 237, 124, 63, 243, 105, 221, 139, 206, 122, 213, 170, + 237, 124, 63, 243, 105, 208, 15, 206, 122, 213, 170, 237, 124, 63, 243, + 105, 206, 132, 206, 122, 213, 170, 237, 124, 63, 243, 105, 248, 153, 206, + 122, 213, 170, 237, 124, 63, 243, 105, 221, 77, 206, 122, 213, 170, 237, + 124, 63, 243, 105, 210, 75, 206, 122, 213, 170, 237, 124, 62, 243, 105, + 221, 139, 206, 122, 213, 170, 237, 124, 62, 243, 105, 208, 15, 206, 122, + 213, 170, 237, 124, 62, 243, 105, 206, 132, 206, 122, 213, 170, 237, 124, + 62, 243, 105, 248, 153, 206, 122, 213, 170, 237, 124, 62, 243, 105, 221, + 77, 206, 122, 213, 170, 237, 124, 62, 243, 105, 210, 75, 206, 122, 213, + 170, 237, 124, 214, 82, 243, 105, 221, 139, 206, 122, 213, 170, 237, 124, + 214, 82, 243, 105, 208, 15, 206, 122, 213, 170, 237, 124, 214, 82, 243, + 105, 206, 132, 206, 122, 213, 170, 237, 124, 214, 82, 243, 105, 248, 153, + 206, 122, 213, 170, 237, 124, 214, 82, 243, 105, 221, 77, 206, 122, 213, + 170, 237, 124, 214, 82, 243, 105, 210, 75, 206, 122, 213, 170, 237, 124, + 63, 243, 105, 221, 77, 206, 122, 91, 228, 141, 198, 248, 237, 124, 62, + 243, 105, 221, 77, 206, 122, 91, 228, 141, 198, 248, 237, 124, 214, 82, + 243, 105, 221, 77, 206, 122, 91, 228, 141, 198, 248, 237, 124, 63, 243, + 105, 153, 221, 138, 63, 243, 105, 153, 208, 14, 63, 243, 105, 153, 206, + 131, 63, 243, 105, 153, 248, 152, 63, 243, 105, 153, 221, 76, 63, 243, + 105, 153, 210, 74, 62, 243, 105, 153, 221, 138, 62, 243, 105, 153, 208, + 14, 62, 243, 105, 153, 206, 131, 62, 243, 105, 153, 248, 152, 62, 243, + 105, 153, 221, 76, 62, 243, 105, 153, 210, 74, 214, 82, 243, 105, 153, + 221, 138, 214, 82, 243, 105, 153, 208, 14, 214, 82, 243, 105, 153, 206, + 131, 214, 82, 243, 105, 153, 248, 152, 214, 82, 243, 105, 153, 221, 76, + 214, 82, 243, 105, 153, 210, 74, 63, 243, 105, 221, 77, 206, 122, 105, + 228, 141, 197, 29, 237, 124, 62, 243, 105, 221, 77, 206, 122, 105, 228, + 141, 197, 29, 237, 124, 214, 82, 243, 105, 221, 77, 206, 122, 105, 228, + 141, 197, 29, 237, 124, 63, 243, 105, 221, 139, 206, 122, 105, 228, 141, + 203, 242, 237, 124, 63, 243, 105, 208, 15, 206, 122, 105, 228, 141, 203, + 242, 237, 124, 63, 243, 105, 206, 132, 206, 122, 105, 228, 141, 203, 242, + 237, 124, 63, 243, 105, 248, 153, 206, 122, 105, 228, 141, 203, 242, 237, + 124, 63, 243, 105, 221, 77, 206, 122, 105, 228, 141, 203, 242, 237, 124, + 63, 243, 105, 210, 75, 206, 122, 105, 228, 141, 203, 242, 237, 124, 62, + 243, 105, 221, 139, 206, 122, 105, 228, 141, 203, 242, 237, 124, 62, 243, + 105, 208, 15, 206, 122, 105, 228, 141, 203, 242, 237, 124, 62, 243, 105, + 206, 132, 206, 122, 105, 228, 141, 203, 242, 237, 124, 62, 243, 105, 248, + 153, 206, 122, 105, 228, 141, 203, 242, 237, 124, 62, 243, 105, 221, 77, + 206, 122, 105, 228, 141, 203, 242, 237, 124, 62, 243, 105, 210, 75, 206, + 122, 105, 228, 141, 203, 242, 237, 124, 214, 82, 243, 105, 221, 139, 206, + 122, 105, 228, 141, 203, 242, 237, 124, 214, 82, 243, 105, 208, 15, 206, + 122, 105, 228, 141, 203, 242, 237, 124, 214, 82, 243, 105, 206, 132, 206, + 122, 105, 228, 141, 203, 242, 237, 124, 214, 82, 243, 105, 248, 153, 206, + 122, 105, 228, 141, 203, 242, 237, 124, 214, 82, 243, 105, 221, 77, 206, + 122, 105, 228, 141, 203, 242, 237, 124, 214, 82, 243, 105, 210, 75, 206, + 122, 105, 228, 141, 203, 242, 237, 124, 63, 243, 105, 221, 77, 206, 122, + 115, 228, 141, 233, 20, 237, 124, 62, 243, 105, 221, 77, 206, 122, 115, + 228, 141, 233, 20, 237, 124, 214, 82, 243, 105, 221, 77, 206, 122, 115, + 228, 141, 233, 20, 237, 124, 63, 243, 105, 234, 38, 62, 243, 105, 234, + 38, 214, 82, 243, 105, 234, 38, 63, 243, 105, 234, 39, 206, 122, 213, + 170, 237, 124, 62, 243, 105, 234, 39, 206, 122, 213, 170, 237, 124, 214, + 82, 243, 105, 234, 39, 206, 122, 213, 170, 237, 124, 63, 243, 105, 221, + 74, 63, 243, 105, 221, 73, 63, 243, 105, 221, 75, 62, 243, 105, 221, 74, + 62, 243, 105, 221, 73, 62, 243, 105, 221, 75, 192, 205, 207, 87, 231, + 150, 192, 205, 207, 87, 217, 84, 192, 205, 207, 87, 234, 131, 192, 205, + 207, 87, 228, 183, 192, 205, 207, 87, 243, 138, 192, 205, 207, 87, 247, + 114, 192, 205, 207, 87, 202, 26, 192, 205, 62, 231, 150, 192, 205, 62, + 217, 84, 192, 205, 62, 234, 131, 192, 205, 62, 228, 183, 192, 205, 62, + 243, 138, 192, 205, 62, 247, 114, 192, 205, 62, 202, 26, 249, 110, 203, + 51, 211, 98, 200, 135, 248, 27, 203, 25, 198, 237, 205, 139, 156, 248, + 115, 229, 223, 230, 198, 229, 223, 209, 131, 229, 223, 235, 99, 79, 248, + 120, 252, 35, 249, 96, 201, 76, 192, 234, 238, 201, 191, 253, 221, 119, + 210, 129, 248, 92, 217, 123, 193, 162, 209, 137, 214, 87, 236, 154, 217, + 64, 232, 182, 206, 187, 209, 100, 246, 252, 207, 118, 250, 132, 236, 196, + 220, 25, 249, 94, 216, 54, 229, 200, 252, 56, 179, 235, 94, 242, 88, 247, + 89, 205, 108, 205, 75, 220, 109, 102, 216, 26, 193, 65, 209, 83, 203, + 239, 214, 109, 221, 71, 248, 6, 215, 182, 198, 6, 198, 55, 229, 228, 209, + 109, 206, 147, 216, 27, 249, 111, 228, 16, 247, 100, 130, 249, 58, 230, + 60, 232, 170, 230, 54, 233, 80, 230, 79, 209, 180, 221, 203, 232, 179, + 193, 17, 248, 251, 242, 95, 209, 11, 209, 99, 193, 28, 233, 54, 218, 246, + 239, 4, 234, 105, 214, 89, 214, 90, 4, 234, 178, 228, 92, 223, 2, 193, + 61, 230, 243, 251, 129, 229, 223, 218, 205, 210, 20, 228, 149, 208, 226, + 217, 90, 208, 226, 209, 250, 209, 251, 4, 238, 208, 215, 204, 236, 147, + 248, 113, 248, 236, 210, 15, 211, 115, 232, 205, 199, 196, 232, 165, 199, + 132, 209, 7, 219, 92, 249, 11, 223, 18, 231, 36, 206, 128, 210, 62, 209, + 70, 216, 195, 233, 103, 205, 153, 233, 103, 233, 104, 4, 211, 77, 233, + 186, 23, 230, 54, 139, 215, 179, 233, 104, 4, 210, 47, 233, 193, 233, + 104, 4, 237, 39, 215, 179, 235, 138, 219, 113, 233, 103, 248, 145, 219, + 98, 248, 7, 203, 145, 233, 103, 230, 54, 4, 141, 232, 253, 23, 176, 238, + 213, 96, 230, 53, 118, 230, 53, 210, 183, 144, 230, 53, 210, 183, 133, + 230, 53, 141, 209, 58, 250, 183, 199, 34, 195, 55, 229, 224, 230, 28, + 118, 208, 135, 230, 53, 96, 208, 135, 230, 53, 184, 203, 236, 184, 203, + 206, 184, 203, 235, 184, 203, 191, 184, 203, 220, 184, 203, 205, 184, + 203, 234, 184, 203, 183, 184, 203, 213, 184, 203, 197, 184, 203, 227, + 184, 203, 190, 184, 203, 219, 184, 203, 204, 184, 203, 233, 184, 203, + 179, 184, 203, 209, 184, 203, 194, 184, 203, 223, 184, 203, 186, 184, + 203, 200, 184, 203, 230, 184, 203, 182, 184, 203, 212, 184, 203, 196, + 184, 203, 226, 184, 203, 189, 184, 203, 218, 184, 203, 203, 184, 203, + 232, 184, 203, 177, 184, 203, 207, 184, 203, 192, 184, 203, 221, 184, + 203, 184, 184, 203, 214, 184, 203, 198, 184, 203, 228, 184, 203, 180, + 184, 203, 210, 184, 203, 224, 184, 203, 187, 184, 203, 216, 184, 203, + 201, 184, 203, 231, 184, 203, 178, 184, 203, 208, 184, 203, 193, 184, + 203, 222, 184, 203, 185, 184, 203, 215, 184, 203, 199, 184, 203, 229, + 184, 203, 181, 184, 203, 211, 184, 203, 195, 184, 203, 225, 184, 203, + 188, 184, 203, 217, 184, 203, 202, 110, 45, 184, 237, 39, 110, 82, 45, + 119, 110, 247, 21, 110, 45, 184, 237, 39, 110, 82, 45, 119, 110, 183, + 110, 45, 184, 237, 39, 116, 82, 45, 119, 110, 247, 21, 110, 45, 184, 237, + 39, 116, 82, 45, 119, 110, 183, 110, 45, 184, 237, 39, 116, 45, 119, 110, + 247, 21, 110, 50, 184, 237, 39, 116, 82, 45, 119, 116, 247, 21, 110, 50, + 184, 237, 39, 116, 82, 45, 119, 116, 183, 110, 50, 184, 237, 39, 110, 82, + 45, 119, 116, 247, 21, 110, 50, 184, 237, 39, 110, 82, 45, 119, 116, 183, + 110, 50, 184, 237, 39, 110, 45, 119, 116, 247, 21, 110, 50, 184, 237, 39, + 110, 82, 45, 119, 116, 82, 183, 110, 50, 184, 237, 39, 110, 247, 22, 119, + 110, 82, 183, 110, 50, 184, 237, 39, 110, 45, 119, 110, 82, 183, 110, 50, + 184, 237, 39, 110, 247, 22, 119, 116, 82, 183, 110, 50, 184, 237, 39, + 110, 45, 119, 116, 82, 183, 110, 50, 184, 237, 39, 110, 247, 22, 119, + 116, 183, 110, 45, 184, 237, 39, 116, 247, 22, 119, 116, 82, 183, 110, + 45, 184, 237, 39, 116, 45, 119, 116, 82, 183, 110, 45, 184, 237, 39, 116, + 247, 22, 119, 110, 82, 183, 110, 45, 184, 237, 39, 116, 45, 119, 110, 82, + 183, 110, 45, 184, 237, 39, 116, 247, 22, 119, 110, 183, 110, 45, 184, + 237, 39, 116, 82, 45, 119, 110, 82, 183, 116, 50, 184, 237, 39, 110, 82, + 45, 119, 110, 247, 21, 116, 50, 184, 237, 39, 110, 82, 45, 119, 110, 183, + 116, 50, 184, 237, 39, 116, 82, 45, 119, 110, 247, 21, 116, 50, 184, 237, + 39, 116, 82, 45, 119, 110, 183, 116, 50, 184, 237, 39, 116, 45, 119, 110, + 247, 21, 116, 45, 184, 237, 39, 116, 82, 45, 119, 116, 247, 21, 116, 45, + 184, 237, 39, 116, 82, 45, 119, 116, 183, 116, 45, 184, 237, 39, 110, 82, + 45, 119, 116, 247, 21, 116, 45, 184, 237, 39, 110, 82, 45, 119, 116, 183, + 116, 45, 184, 237, 39, 110, 45, 119, 116, 247, 21, 116, 45, 184, 237, 39, + 110, 82, 45, 119, 116, 82, 183, 116, 45, 184, 237, 39, 110, 247, 22, 119, + 110, 82, 183, 116, 45, 184, 237, 39, 110, 45, 119, 110, 82, 183, 116, 45, + 184, 237, 39, 110, 247, 22, 119, 116, 82, 183, 116, 45, 184, 237, 39, + 110, 45, 119, 116, 82, 183, 116, 45, 184, 237, 39, 110, 247, 22, 119, + 116, 183, 116, 50, 184, 237, 39, 116, 247, 22, 119, 116, 82, 183, 116, + 50, 184, 237, 39, 116, 45, 119, 116, 82, 183, 116, 50, 184, 237, 39, 116, + 247, 22, 119, 110, 82, 183, 116, 50, 184, 237, 39, 116, 45, 119, 110, 82, + 183, 116, 50, 184, 237, 39, 116, 247, 22, 119, 110, 183, 116, 50, 184, + 237, 39, 116, 82, 45, 119, 110, 82, 183, 116, 23, 50, 23, 110, 197, 238, + 115, 208, 21, 248, 129, 45, 23, 110, 23, 50, 197, 238, 115, 208, 21, 248, + 129, 116, 23, 45, 23, 110, 197, 238, 115, 208, 21, 248, 129, 45, 23, 116, + 23, 50, 197, 238, 115, 208, 21, 248, 129, 45, 197, 238, 91, 208, 23, 248, + 129, 116, 197, 238, 91, 208, 23, 248, 129, 50, 197, 238, 91, 208, 23, + 248, 129, 110, 197, 238, 91, 208, 23, 248, 129, 81, 91, 234, 160, 248, + 127, 81, 91, 234, 160, 248, 126, 81, 91, 234, 160, 248, 125, 81, 91, 234, + 160, 248, 124, 81, 91, 234, 160, 248, 123, 81, 91, 234, 160, 248, 122, + 228, 241, 91, 234, 160, 248, 127, 228, 241, 91, 234, 160, 248, 126, 228, + 241, 91, 234, 160, 248, 125, 228, 241, 91, 234, 160, 248, 124, 228, 241, + 91, 234, 160, 248, 123, 228, 241, 91, 234, 160, 248, 122, 45, 23, 110, + 91, 234, 160, 248, 129, 45, 23, 116, 91, 234, 160, 248, 129, 50, 23, 116, + 91, 234, 160, 248, 129, 50, 23, 110, 91, 234, 160, 248, 129, 116, 23, + 110, 91, 234, 160, 248, 129, 228, 241, 91, 234, 160, 248, 128, 116, 91, + 208, 23, 248, 129, 116, 115, 234, 158, 248, 129, 116, 232, 226, 234, 158, + 248, 129, 116, 115, 208, 21, 248, 129, 116, 203, 247, 234, 158, 248, 129, + 50, 91, 208, 23, 248, 129, 50, 115, 234, 158, 248, 129, 50, 232, 226, + 234, 158, 248, 129, 50, 115, 208, 21, 248, 129, 50, 203, 247, 234, 158, + 248, 129, 45, 132, 216, 213, 203, 153, 50, 132, 216, 213, 203, 153, 116, + 132, 216, 213, 203, 153, 110, 132, 216, 213, 203, 153, 223, 95, 216, 213, + 203, 153, 116, 132, 184, 23, 110, 132, 223, 95, 216, 213, 203, 153, 116, + 132, 223, 95, 216, 213, 203, 154, 23, 110, 132, 248, 129, 45, 132, 223, + 95, 216, 213, 203, 154, 23, 50, 132, 248, 129, 243, 124, 248, 108, 233, + 5, 223, 95, 243, 124, 248, 108, 233, 5, 88, 228, 241, 233, 5, 116, 45, + 119, 110, 50, 233, 5, 116, 50, 119, 110, 45, 233, 5, 116, 23, 110, 197, + 238, 132, 248, 129, 45, 23, 50, 197, 238, 132, 248, 129, 116, 45, 197, + 238, 216, 213, 203, 153, 116, 50, 197, 238, 216, 213, 203, 153, 110, 50, + 197, 238, 216, 213, 203, 153, 110, 45, 197, 238, 216, 213, 203, 153, 111, + 122, 156, 237, 39, 116, 247, 22, 119, 82, 219, 224, 111, 122, 156, 237, + 39, 116, 247, 22, 119, 82, 183, 111, 122, 156, 237, 39, 82, 45, 119, 110, + 247, 21, 111, 122, 156, 237, 39, 82, 50, 119, 110, 247, 21, 111, 122, + 156, 237, 39, 116, 247, 22, 119, 82, 45, 119, 110, 247, 21, 111, 122, + 156, 237, 39, 116, 247, 22, 119, 82, 50, 119, 110, 247, 21, 111, 122, + 156, 237, 39, 82, 45, 119, 110, 247, 22, 119, 82, 183, 111, 122, 156, + 237, 39, 82, 45, 119, 116, 247, 22, 119, 82, 183, 111, 122, 156, 237, 39, + 116, 247, 22, 119, 82, 45, 23, 82, 50, 119, 110, 247, 21, 111, 122, 156, + 237, 39, 116, 247, 22, 119, 82, 50, 23, 82, 45, 119, 110, 247, 21, 111, + 122, 156, 237, 39, 116, 247, 22, 119, 82, 50, 119, 110, 247, 22, 119, 82, + 219, 224, 111, 122, 156, 237, 39, 116, 247, 22, 119, 82, 45, 119, 110, + 247, 22, 119, 82, 183, 111, 122, 156, 237, 39, 82, 45, 119, 116, 247, 22, + 119, 82, 50, 119, 110, 247, 21, 111, 122, 156, 237, 39, 82, 50, 119, 116, + 247, 22, 119, 82, 45, 119, 110, 247, 21, 111, 122, 156, 237, 39, 237, 32, + 111, 122, 156, 228, 241, 4, 81, 106, 250, 234, 209, 59, 223, 95, 243, + 126, 77, 45, 132, 206, 42, 217, 90, 50, 132, 206, 42, 217, 90, 223, 95, + 235, 119, 64, 4, 198, 136, 219, 214, 118, 64, 23, 116, 23, 110, 91, 234, + 160, 248, 129, 96, 64, 23, 116, 23, 110, 91, 234, 160, 248, 129, 235, + 119, 64, 23, 50, 91, 234, 160, 248, 129, 196, 66, 64, 23, 50, 91, 234, + 160, 248, 129, 45, 132, 232, 171, 50, 132, 232, 171, 195, 16, 35, 238, + 217, 50, 211, 77, 112, 236, 140, 214, 106, 237, 39, 238, 217, 214, 106, + 237, 39, 82, 50, 119, 110, 247, 21, 214, 106, 237, 39, 237, 32, 63, 88, + 205, 155, 4, 206, 113, 239, 0, 45, 199, 1, 63, 50, 209, 58, 223, 148, 82, + 199, 1, 63, 50, 209, 58, 223, 148, 50, 199, 1, 63, 50, 209, 58, 223, 148, + 214, 106, 112, 208, 13, 77, 201, 75, 233, 12, 201, 75, 233, 13, 4, 250, + 247, 207, 146, 201, 75, 233, 13, 219, 231, 219, 224, 201, 75, 233, 13, + 219, 231, 183, 201, 75, 233, 13, 4, 235, 106, 63, 196, 76, 243, 100, 205, + 42, 17, 191, 77, 205, 42, 17, 107, 205, 42, 17, 109, 205, 42, 17, 138, + 205, 42, 17, 134, 205, 42, 17, 149, 205, 42, 17, 169, 205, 42, 17, 175, + 205, 42, 17, 171, 205, 42, 17, 178, 12, 15, 228, 13, 12, 15, 228, 12, 12, + 15, 228, 11, 12, 15, 228, 10, 12, 15, 228, 9, 12, 15, 228, 8, 12, 15, + 228, 7, 12, 15, 228, 6, 12, 15, 228, 5, 12, 15, 228, 4, 12, 15, 228, 3, + 12, 15, 228, 2, 12, 15, 228, 1, 12, 15, 228, 0, 12, 15, 227, 255, 12, 15, + 227, 254, 12, 15, 227, 253, 12, 15, 227, 252, 12, 15, 227, 251, 12, 15, + 227, 250, 12, 15, 227, 249, 12, 15, 227, 248, 12, 15, 227, 247, 12, 15, + 227, 246, 12, 15, 227, 245, 12, 15, 227, 244, 12, 15, 227, 243, 12, 15, + 227, 242, 12, 15, 227, 241, 12, 15, 227, 240, 12, 15, 227, 239, 12, 15, + 227, 238, 12, 15, 227, 237, 12, 15, 227, 236, 12, 15, 227, 235, 12, 15, + 227, 234, 12, 15, 227, 233, 12, 15, 227, 232, 12, 15, 227, 231, 12, 15, + 227, 230, 12, 15, 227, 229, 12, 15, 227, 228, 12, 15, 227, 227, 12, 15, + 227, 226, 12, 15, 227, 225, 12, 15, 227, 224, 12, 15, 227, 223, 12, 15, + 227, 222, 12, 15, 227, 221, 12, 15, 227, 220, 12, 15, 227, 219, 12, 15, + 227, 218, 12, 15, 227, 217, 12, 15, 227, 216, 12, 15, 227, 215, 12, 15, + 227, 214, 12, 15, 227, 213, 12, 15, 227, 212, 12, 15, 227, 211, 12, 15, + 227, 210, 12, 15, 227, 209, 12, 15, 227, 208, 12, 15, 227, 207, 12, 15, + 227, 206, 12, 15, 227, 205, 12, 15, 227, 204, 12, 15, 227, 203, 12, 15, + 227, 202, 12, 15, 227, 201, 12, 15, 227, 200, 12, 15, 227, 199, 12, 15, + 227, 198, 12, 15, 227, 197, 12, 15, 227, 196, 12, 15, 227, 195, 12, 15, + 227, 194, 12, 15, 227, 193, 12, 15, 227, 192, 12, 15, 227, 191, 12, 15, + 227, 190, 12, 15, 227, 189, 12, 15, 227, 188, 12, 15, 227, 187, 12, 15, + 227, 186, 12, 15, 227, 185, 12, 15, 227, 184, 12, 15, 227, 183, 12, 15, + 227, 182, 12, 15, 227, 181, 12, 15, 227, 180, 12, 15, 227, 179, 12, 15, + 227, 178, 12, 15, 227, 177, 12, 15, 227, 176, 12, 15, 227, 175, 12, 15, + 227, 174, 12, 15, 227, 173, 12, 15, 227, 172, 12, 15, 227, 171, 12, 15, + 227, 170, 12, 15, 227, 169, 12, 15, 227, 168, 12, 15, 227, 167, 12, 15, + 227, 166, 12, 15, 227, 165, 12, 15, 227, 164, 12, 15, 227, 163, 12, 15, + 227, 162, 12, 15, 227, 161, 12, 15, 227, 160, 12, 15, 227, 159, 12, 15, + 227, 158, 12, 15, 227, 157, 12, 15, 227, 156, 12, 15, 227, 155, 12, 15, + 227, 154, 12, 15, 227, 153, 12, 15, 227, 152, 12, 15, 227, 151, 12, 15, + 227, 150, 12, 15, 227, 149, 12, 15, 227, 148, 12, 15, 227, 147, 12, 15, + 227, 146, 12, 15, 227, 145, 12, 15, 227, 144, 12, 15, 227, 143, 12, 15, + 227, 142, 12, 15, 227, 141, 12, 15, 227, 140, 12, 15, 227, 139, 12, 15, + 227, 138, 12, 15, 227, 137, 12, 15, 227, 136, 12, 15, 227, 135, 12, 15, + 227, 134, 12, 15, 227, 133, 12, 15, 227, 132, 12, 15, 227, 131, 12, 15, + 227, 130, 12, 15, 227, 129, 12, 15, 227, 128, 12, 15, 227, 127, 12, 15, + 227, 126, 12, 15, 227, 125, 12, 15, 227, 124, 12, 15, 227, 123, 12, 15, + 227, 122, 12, 15, 227, 121, 12, 15, 227, 120, 12, 15, 227, 119, 12, 15, + 227, 118, 12, 15, 227, 117, 12, 15, 227, 116, 12, 15, 227, 115, 12, 15, + 227, 114, 12, 15, 227, 113, 12, 15, 227, 112, 12, 15, 227, 111, 12, 15, + 227, 110, 12, 15, 227, 109, 12, 15, 227, 108, 12, 15, 227, 107, 12, 15, + 227, 106, 12, 15, 227, 105, 12, 15, 227, 104, 12, 15, 227, 103, 12, 15, + 227, 102, 12, 15, 227, 101, 12, 15, 227, 100, 12, 15, 227, 99, 12, 15, + 227, 98, 12, 15, 227, 97, 12, 15, 227, 96, 12, 15, 227, 95, 12, 15, 227, + 94, 12, 15, 227, 93, 12, 15, 227, 92, 12, 15, 227, 91, 12, 15, 227, 90, + 12, 15, 227, 89, 12, 15, 227, 88, 12, 15, 227, 87, 12, 15, 227, 86, 12, + 15, 227, 85, 12, 15, 227, 84, 12, 15, 227, 83, 12, 15, 227, 82, 12, 15, + 227, 81, 12, 15, 227, 80, 12, 15, 227, 79, 12, 15, 227, 78, 12, 15, 227, + 77, 12, 15, 227, 76, 12, 15, 227, 75, 12, 15, 227, 74, 12, 15, 227, 73, + 12, 15, 227, 72, 12, 15, 227, 71, 12, 15, 227, 70, 12, 15, 227, 69, 12, + 15, 227, 68, 12, 15, 227, 67, 12, 15, 227, 66, 12, 15, 227, 65, 12, 15, + 227, 64, 12, 15, 227, 63, 12, 15, 227, 62, 12, 15, 227, 61, 12, 15, 227, + 60, 12, 15, 227, 59, 12, 15, 227, 58, 12, 15, 227, 57, 12, 15, 227, 56, + 12, 15, 227, 55, 12, 15, 227, 54, 12, 15, 227, 53, 12, 15, 227, 52, 12, + 15, 227, 51, 12, 15, 227, 50, 12, 15, 227, 49, 12, 15, 227, 48, 12, 15, + 227, 47, 12, 15, 227, 46, 12, 15, 227, 45, 12, 15, 227, 44, 12, 15, 227, + 43, 12, 15, 227, 42, 12, 15, 227, 41, 12, 15, 227, 40, 12, 15, 227, 39, + 12, 15, 227, 38, 12, 15, 227, 37, 12, 15, 227, 36, 12, 15, 227, 35, 12, + 15, 227, 34, 12, 15, 227, 33, 12, 15, 227, 32, 12, 15, 227, 31, 12, 15, + 227, 30, 12, 15, 227, 29, 12, 15, 227, 28, 12, 15, 227, 27, 12, 15, 227, + 26, 12, 15, 227, 25, 12, 15, 227, 24, 12, 15, 227, 23, 12, 15, 227, 22, + 12, 15, 227, 21, 12, 15, 227, 20, 12, 15, 227, 19, 12, 15, 227, 18, 12, + 15, 227, 17, 12, 15, 227, 16, 12, 15, 227, 15, 12, 15, 227, 14, 12, 15, + 227, 13, 12, 15, 227, 12, 12, 15, 227, 11, 12, 15, 227, 10, 12, 15, 227, + 9, 12, 15, 227, 8, 12, 15, 227, 7, 12, 15, 227, 6, 12, 15, 227, 5, 12, + 15, 227, 4, 12, 15, 227, 3, 12, 15, 227, 2, 12, 15, 227, 1, 12, 15, 227, + 0, 12, 15, 226, 255, 12, 15, 226, 254, 12, 15, 226, 253, 12, 15, 226, + 252, 12, 15, 226, 251, 12, 15, 226, 250, 12, 15, 226, 249, 12, 15, 226, + 248, 12, 15, 226, 247, 12, 15, 226, 246, 12, 15, 226, 245, 12, 15, 226, + 244, 12, 15, 226, 243, 12, 15, 226, 242, 12, 15, 226, 241, 12, 15, 226, + 240, 12, 15, 226, 239, 12, 15, 226, 238, 12, 15, 226, 237, 12, 15, 226, + 236, 12, 15, 226, 235, 12, 15, 226, 234, 12, 15, 226, 233, 12, 15, 226, + 232, 12, 15, 226, 231, 12, 15, 226, 230, 12, 15, 226, 229, 12, 15, 226, + 228, 12, 15, 226, 227, 12, 15, 226, 226, 12, 15, 226, 225, 12, 15, 226, + 224, 12, 15, 226, 223, 12, 15, 226, 222, 12, 15, 226, 221, 12, 15, 226, + 220, 12, 15, 226, 219, 12, 15, 226, 218, 12, 15, 226, 217, 12, 15, 226, + 216, 12, 15, 226, 215, 12, 15, 226, 214, 12, 15, 226, 213, 12, 15, 226, + 212, 12, 15, 226, 211, 12, 15, 226, 210, 12, 15, 226, 209, 12, 15, 226, + 208, 12, 15, 226, 207, 12, 15, 226, 206, 12, 15, 226, 205, 12, 15, 226, + 204, 12, 15, 226, 203, 12, 15, 226, 202, 12, 15, 226, 201, 12, 15, 226, + 200, 12, 15, 226, 199, 12, 15, 226, 198, 12, 15, 226, 197, 12, 15, 226, + 196, 12, 15, 226, 195, 12, 15, 226, 194, 12, 15, 226, 193, 12, 15, 226, + 192, 12, 15, 226, 191, 12, 15, 226, 190, 12, 15, 226, 189, 12, 15, 226, + 188, 12, 15, 226, 187, 12, 15, 226, 186, 12, 15, 226, 185, 12, 15, 226, + 184, 12, 15, 226, 183, 12, 15, 226, 182, 12, 15, 226, 181, 12, 15, 226, + 180, 12, 15, 226, 179, 12, 15, 226, 178, 12, 15, 226, 177, 12, 15, 226, + 176, 12, 15, 226, 175, 12, 15, 226, 174, 12, 15, 226, 173, 12, 15, 226, + 172, 12, 15, 226, 171, 12, 15, 226, 170, 12, 15, 226, 169, 12, 15, 226, + 168, 12, 15, 226, 167, 12, 15, 226, 166, 12, 15, 226, 165, 12, 15, 226, + 164, 12, 15, 226, 163, 12, 15, 226, 162, 12, 15, 226, 161, 12, 15, 226, + 160, 12, 15, 226, 159, 12, 15, 226, 158, 12, 15, 226, 157, 12, 15, 226, + 156, 12, 15, 226, 155, 12, 15, 226, 154, 12, 15, 226, 153, 12, 15, 226, + 152, 12, 15, 226, 151, 12, 15, 226, 150, 12, 15, 226, 149, 12, 15, 226, + 148, 12, 15, 226, 147, 12, 15, 226, 146, 12, 15, 226, 145, 12, 15, 226, + 144, 12, 15, 226, 143, 12, 15, 226, 142, 12, 15, 226, 141, 12, 15, 226, + 140, 12, 15, 226, 139, 12, 15, 226, 138, 12, 15, 226, 137, 12, 15, 226, + 136, 12, 15, 226, 135, 12, 15, 226, 134, 12, 15, 226, 133, 12, 15, 226, + 132, 12, 15, 226, 131, 12, 15, 226, 130, 12, 15, 226, 129, 12, 15, 226, + 128, 12, 15, 226, 127, 12, 15, 226, 126, 12, 15, 226, 125, 12, 15, 226, + 124, 12, 15, 226, 123, 12, 15, 226, 122, 12, 15, 226, 121, 12, 15, 226, + 120, 12, 15, 226, 119, 12, 15, 226, 118, 12, 15, 226, 117, 12, 15, 226, + 116, 12, 15, 226, 115, 12, 15, 226, 114, 12, 15, 226, 113, 12, 15, 226, + 112, 12, 15, 226, 111, 12, 15, 226, 110, 12, 15, 226, 109, 12, 15, 226, + 108, 12, 15, 226, 107, 12, 15, 226, 106, 12, 15, 226, 105, 12, 15, 226, + 104, 12, 15, 226, 103, 12, 15, 226, 102, 12, 15, 226, 101, 12, 15, 226, + 100, 12, 15, 226, 99, 12, 15, 226, 98, 12, 15, 226, 97, 12, 15, 226, 96, + 12, 15, 226, 95, 12, 15, 226, 94, 12, 15, 226, 93, 12, 15, 226, 92, 12, + 15, 226, 91, 12, 15, 226, 90, 12, 15, 226, 89, 12, 15, 226, 88, 12, 15, + 226, 87, 12, 15, 226, 86, 12, 15, 226, 85, 12, 15, 226, 84, 12, 15, 226, + 83, 12, 15, 226, 82, 12, 15, 226, 81, 12, 15, 226, 80, 12, 15, 226, 79, + 12, 15, 226, 78, 12, 15, 226, 77, 12, 15, 226, 76, 12, 15, 226, 75, 12, + 15, 226, 74, 12, 15, 226, 73, 12, 15, 226, 72, 12, 15, 226, 71, 12, 15, + 226, 70, 12, 15, 226, 69, 12, 15, 226, 68, 12, 15, 226, 67, 12, 15, 226, + 66, 12, 15, 226, 65, 12, 15, 226, 64, 12, 15, 226, 63, 12, 15, 226, 62, + 12, 15, 226, 61, 12, 15, 226, 60, 12, 15, 226, 59, 12, 15, 226, 58, 12, + 15, 226, 57, 12, 15, 226, 56, 12, 15, 226, 55, 12, 15, 226, 54, 12, 15, + 226, 53, 12, 15, 226, 52, 12, 15, 226, 51, 12, 15, 226, 50, 12, 15, 226, + 49, 12, 15, 226, 48, 12, 15, 226, 47, 12, 15, 226, 46, 12, 15, 226, 45, + 12, 15, 226, 44, 12, 15, 226, 43, 12, 15, 226, 42, 12, 15, 226, 41, 12, + 15, 226, 40, 12, 15, 226, 39, 12, 15, 226, 38, 12, 15, 226, 37, 12, 15, + 226, 36, 12, 15, 226, 35, 12, 15, 226, 34, 12, 15, 226, 33, 12, 15, 226, + 32, 12, 15, 226, 31, 12, 15, 226, 30, 12, 15, 226, 29, 12, 15, 226, 28, + 12, 15, 226, 27, 12, 15, 226, 26, 12, 15, 226, 25, 12, 15, 226, 24, 12, + 15, 226, 23, 12, 15, 226, 22, 12, 15, 226, 21, 12, 15, 226, 20, 12, 15, + 226, 19, 12, 15, 226, 18, 12, 15, 226, 17, 12, 15, 226, 16, 12, 15, 226, + 15, 12, 15, 226, 14, 12, 15, 226, 13, 12, 15, 226, 12, 12, 15, 226, 11, + 12, 15, 226, 10, 12, 15, 226, 9, 12, 15, 226, 8, 12, 15, 226, 7, 12, 15, + 226, 6, 12, 15, 226, 5, 12, 15, 226, 4, 12, 15, 226, 3, 12, 15, 226, 2, + 12, 15, 226, 1, 12, 15, 226, 0, 12, 15, 225, 255, 12, 15, 225, 254, 12, + 15, 225, 253, 12, 15, 225, 252, 12, 15, 225, 251, 12, 15, 225, 250, 12, + 15, 225, 249, 12, 15, 225, 248, 12, 15, 225, 247, 12, 15, 225, 246, 12, + 15, 225, 245, 12, 15, 225, 244, 12, 15, 225, 243, 12, 15, 225, 242, 12, + 15, 225, 241, 12, 15, 225, 240, 220, 20, 199, 223, 199, 224, 201, 247, + 199, 224, 233, 216, 77, 199, 224, 207, 252, 77, 199, 224, 31, 56, 199, + 224, 236, 155, 56, 199, 224, 210, 13, 56, 199, 224, 251, 137, 199, 224, + 251, 49, 199, 224, 45, 210, 113, 199, 224, 50, 210, 113, 199, 224, 250, + 193, 199, 224, 108, 56, 199, 224, 242, 74, 199, 224, 228, 87, 199, 224, + 232, 80, 201, 63, 199, 224, 202, 23, 199, 224, 17, 191, 77, 199, 224, 17, + 107, 199, 224, 17, 109, 199, 224, 17, 138, 199, 224, 17, 134, 199, 224, + 17, 149, 199, 224, 17, 169, 199, 224, 17, 175, 199, 224, 17, 171, 199, + 224, 17, 178, 199, 224, 242, 83, 199, 224, 204, 25, 199, 224, 219, 180, + 56, 199, 224, 234, 43, 56, 199, 224, 230, 204, 56, 199, 224, 208, 13, 77, + 199, 224, 242, 72, 250, 182, 199, 224, 8, 6, 1, 65, 199, 224, 8, 6, 1, + 250, 120, 199, 224, 8, 6, 1, 247, 193, 199, 224, 8, 6, 1, 238, 127, 199, + 224, 8, 6, 1, 71, 199, 224, 8, 6, 1, 233, 175, 199, 224, 8, 6, 1, 232, + 51, 199, 224, 8, 6, 1, 230, 116, 199, 224, 8, 6, 1, 68, 199, 224, 8, 6, + 1, 223, 35, 199, 224, 8, 6, 1, 222, 152, 199, 224, 8, 6, 1, 172, 199, + 224, 8, 6, 1, 218, 168, 199, 224, 8, 6, 1, 215, 61, 199, 224, 8, 6, 1, + 74, 199, 224, 8, 6, 1, 210, 236, 199, 224, 8, 6, 1, 208, 104, 199, 224, + 8, 6, 1, 146, 199, 224, 8, 6, 1, 206, 8, 199, 224, 8, 6, 1, 200, 43, 199, + 224, 8, 6, 1, 66, 199, 224, 8, 6, 1, 196, 12, 199, 224, 8, 6, 1, 193, + 224, 199, 224, 8, 6, 1, 192, 235, 199, 224, 8, 6, 1, 192, 159, 199, 224, + 8, 6, 1, 191, 166, 199, 224, 45, 51, 248, 53, 199, 224, 207, 19, 202, 23, + 199, 224, 50, 51, 248, 53, 199, 224, 243, 2, 252, 60, 199, 224, 130, 219, + 112, 199, 224, 230, 211, 252, 60, 199, 224, 8, 2, 1, 65, 199, 224, 8, 2, + 1, 250, 120, 199, 224, 8, 2, 1, 247, 193, 199, 224, 8, 2, 1, 238, 127, + 199, 224, 8, 2, 1, 71, 199, 224, 8, 2, 1, 233, 175, 199, 224, 8, 2, 1, + 232, 51, 199, 224, 8, 2, 1, 230, 116, 199, 224, 8, 2, 1, 68, 199, 224, 8, + 2, 1, 223, 35, 199, 224, 8, 2, 1, 222, 152, 199, 224, 8, 2, 1, 172, 199, + 224, 8, 2, 1, 218, 168, 199, 224, 8, 2, 1, 215, 61, 199, 224, 8, 2, 1, + 74, 199, 224, 8, 2, 1, 210, 236, 199, 224, 8, 2, 1, 208, 104, 199, 224, + 8, 2, 1, 146, 199, 224, 8, 2, 1, 206, 8, 199, 224, 8, 2, 1, 200, 43, 199, + 224, 8, 2, 1, 66, 199, 224, 8, 2, 1, 196, 12, 199, 224, 8, 2, 1, 193, + 224, 199, 224, 8, 2, 1, 192, 235, 199, 224, 8, 2, 1, 192, 159, 199, 224, + 8, 2, 1, 191, 166, 199, 224, 45, 238, 171, 248, 53, 199, 224, 81, 219, + 112, 199, 224, 50, 238, 171, 248, 53, 199, 224, 198, 152, 247, 127, 199, + 223, 67, 204, 211, 67, 204, 200, 67, 204, 189, 67, 204, 177, 67, 204, + 166, 67, 204, 155, 67, 204, 144, 67, 204, 133, 67, 204, 122, 67, 204, + 114, 67, 204, 113, 67, 204, 112, 67, 204, 111, 67, 204, 109, 67, 204, + 108, 67, 204, 107, 67, 204, 106, 67, 204, 105, 67, 204, 104, 67, 204, + 103, 67, 204, 102, 67, 204, 101, 67, 204, 100, 67, 204, 98, 67, 204, 97, + 67, 204, 96, 67, 204, 95, 67, 204, 94, 67, 204, 93, 67, 204, 92, 67, 204, + 91, 67, 204, 90, 67, 204, 89, 67, 204, 87, 67, 204, 86, 67, 204, 85, 67, + 204, 84, 67, 204, 83, 67, 204, 82, 67, 204, 81, 67, 204, 80, 67, 204, 79, + 67, 204, 78, 67, 204, 76, 67, 204, 75, 67, 204, 74, 67, 204, 73, 67, 204, + 72, 67, 204, 71, 67, 204, 70, 67, 204, 69, 67, 204, 68, 67, 204, 67, 67, + 204, 65, 67, 204, 64, 67, 204, 63, 67, 204, 62, 67, 204, 61, 67, 204, 60, + 67, 204, 59, 67, 204, 58, 67, 204, 57, 67, 204, 56, 67, 204, 54, 67, 204, + 53, 67, 204, 52, 67, 204, 51, 67, 204, 50, 67, 204, 49, 67, 204, 48, 67, + 204, 47, 67, 204, 46, 67, 204, 45, 67, 204, 43, 67, 204, 42, 67, 204, 41, + 67, 204, 40, 67, 204, 39, 67, 204, 38, 67, 204, 37, 67, 204, 36, 67, 204, + 35, 67, 204, 34, 67, 205, 31, 67, 205, 30, 67, 205, 29, 67, 205, 28, 67, + 205, 27, 67, 205, 26, 67, 205, 25, 67, 205, 24, 67, 205, 23, 67, 205, 22, + 67, 205, 20, 67, 205, 19, 67, 205, 18, 67, 205, 17, 67, 205, 16, 67, 205, + 15, 67, 205, 14, 67, 205, 13, 67, 205, 12, 67, 205, 11, 67, 205, 9, 67, + 205, 8, 67, 205, 7, 67, 205, 6, 67, 205, 5, 67, 205, 4, 67, 205, 3, 67, + 205, 2, 67, 205, 1, 67, 205, 0, 67, 204, 254, 67, 204, 253, 67, 204, 252, + 67, 204, 251, 67, 204, 250, 67, 204, 249, 67, 204, 248, 67, 204, 247, 67, + 204, 246, 67, 204, 245, 67, 204, 243, 67, 204, 242, 67, 204, 241, 67, + 204, 240, 67, 204, 239, 67, 204, 238, 67, 204, 237, 67, 204, 236, 67, + 204, 235, 67, 204, 234, 67, 204, 232, 67, 204, 231, 67, 204, 230, 67, + 204, 229, 67, 204, 228, 67, 204, 227, 67, 204, 226, 67, 204, 225, 67, + 204, 224, 67, 204, 223, 67, 204, 221, 67, 204, 220, 67, 204, 219, 67, + 204, 218, 67, 204, 217, 67, 204, 216, 67, 204, 215, 67, 204, 214, 67, + 204, 213, 67, 204, 212, 67, 204, 210, 67, 204, 209, 67, 204, 208, 67, + 204, 207, 67, 204, 206, 67, 204, 205, 67, 204, 204, 67, 204, 203, 67, + 204, 202, 67, 204, 201, 67, 204, 199, 67, 204, 198, 67, 204, 197, 67, + 204, 196, 67, 204, 195, 67, 204, 194, 67, 204, 193, 67, 204, 192, 67, + 204, 191, 67, 204, 190, 67, 204, 188, 67, 204, 187, 67, 204, 186, 67, + 204, 185, 67, 204, 184, 67, 204, 183, 67, 204, 182, 67, 204, 181, 67, + 204, 180, 67, 204, 179, 67, 204, 176, 67, 204, 175, 67, 204, 174, 67, + 204, 173, 67, 204, 172, 67, 204, 171, 67, 204, 170, 67, 204, 169, 67, + 204, 168, 67, 204, 167, 67, 204, 165, 67, 204, 164, 67, 204, 163, 67, + 204, 162, 67, 204, 161, 67, 204, 160, 67, 204, 159, 67, 204, 158, 67, + 204, 157, 67, 204, 156, 67, 204, 154, 67, 204, 153, 67, 204, 152, 67, + 204, 151, 67, 204, 150, 67, 204, 149, 67, 204, 148, 67, 204, 147, 67, + 204, 146, 67, 204, 145, 67, 204, 143, 67, 204, 142, 67, 204, 141, 67, + 204, 140, 67, 204, 139, 67, 204, 138, 67, 204, 137, 67, 204, 136, 67, + 204, 135, 67, 204, 134, 67, 204, 132, 67, 204, 131, 67, 204, 130, 67, + 204, 129, 67, 204, 128, 67, 204, 127, 67, 204, 126, 67, 204, 125, 67, + 204, 124, 67, 204, 123, 67, 204, 121, 67, 204, 120, 67, 204, 119, 67, + 204, 118, 67, 204, 117, 67, 204, 116, 67, 204, 115, 212, 138, 212, 140, + 201, 98, 79, 229, 232, 202, 27, 201, 98, 79, 199, 53, 201, 6, 234, 95, + 79, 199, 53, 233, 244, 234, 95, 79, 198, 11, 234, 57, 234, 81, 234, 82, + 252, 51, 252, 52, 251, 189, 248, 238, 249, 140, 248, 16, 246, 240, 199, + 230, 228, 241, 199, 230, 228, 165, 199, 236, 219, 113, 233, 50, 214, 80, + 219, 112, 234, 95, 79, 219, 112, 219, 161, 213, 105, 234, 60, 219, 113, + 199, 230, 81, 199, 230, 193, 251, 232, 146, 233, 50, 233, 27, 247, 88, + 207, 22, 238, 236, 203, 77, 211, 14, 219, 33, 107, 202, 46, 203, 77, 223, + 162, 219, 33, 191, 77, 202, 222, 237, 210, 219, 103, 234, 14, 236, 185, + 237, 75, 239, 22, 107, 237, 199, 237, 75, 239, 22, 109, 237, 198, 237, + 75, 239, 22, 138, 237, 197, 237, 75, 239, 22, 134, 237, 196, 214, 106, + 252, 51, 214, 233, 200, 69, 223, 228, 200, 73, 234, 95, 79, 198, 12, 248, + 129, 233, 252, 247, 126, 247, 128, 234, 95, 79, 216, 212, 234, 58, 234, + 114, 200, 226, 200, 245, 234, 14, 234, 15, 223, 137, 204, 11, 134, 233, + 7, 204, 10, 232, 90, 223, 137, 204, 11, 138, 230, 187, 204, 10, 230, 184, + 223, 137, 204, 11, 109, 207, 98, 204, 10, 206, 74, 223, 137, 204, 11, + 107, 196, 91, 204, 10, 196, 45, 201, 250, 237, 116, 237, 118, 210, 208, + 246, 239, 210, 210, 137, 211, 158, 208, 220, 228, 244, 248, 42, 210, 1, + 229, 192, 248, 58, 213, 44, 248, 42, 229, 192, 214, 191, 223, 148, 223, + 150, 214, 73, 219, 112, 214, 104, 201, 98, 79, 205, 36, 251, 8, 201, 175, + 234, 95, 79, 205, 36, 251, 8, 234, 17, 246, 240, 199, 231, 203, 252, 228, + 241, 199, 231, 203, 252, 228, 162, 246, 240, 199, 231, 4, 222, 164, 228, + 241, 199, 231, 4, 222, 164, 228, 163, 219, 113, 199, 231, 203, 252, 81, + 199, 231, 203, 252, 193, 250, 210, 105, 219, 113, 232, 132, 210, 105, + 219, 113, 235, 123, 209, 94, 210, 105, 219, 113, 249, 139, 210, 105, 219, + 113, 196, 77, 209, 88, 207, 19, 219, 113, 233, 50, 207, 19, 223, 148, + 207, 1, 202, 170, 203, 77, 109, 202, 167, 201, 177, 202, 170, 203, 77, + 138, 202, 166, 201, 176, 237, 75, 239, 22, 201, 30, 237, 194, 208, 205, + 196, 44, 107, 208, 205, 196, 42, 208, 164, 208, 205, 196, 44, 109, 208, + 205, 196, 41, 208, 163, 203, 253, 198, 10, 201, 95, 201, 13, 247, 127, + 246, 239, 247, 61, 216, 169, 193, 171, 215, 81, 201, 98, 79, 230, 172, + 251, 8, 201, 98, 79, 208, 182, 251, 8, 201, 249, 234, 95, 79, 230, 172, + 251, 8, 234, 95, 79, 208, 182, 251, 8, 234, 55, 201, 98, 79, 201, 30, + 202, 9, 202, 170, 230, 216, 246, 240, 223, 96, 203, 170, 202, 170, 246, + 240, 223, 96, 205, 85, 239, 22, 204, 7, 223, 96, 238, 196, 201, 31, 199, + 80, 201, 118, 211, 68, 200, 58, 242, 73, 211, 34, 208, 206, 216, 168, + 209, 76, 251, 45, 208, 198, 242, 73, 251, 62, 214, 179, 202, 231, 8, 6, + 1, 231, 91, 8, 2, 1, 231, 91, 247, 4, 9, 2, 137, 34, 131, 4, 99, 249, 80, + 251, 166, 200, 63, 200, 232, 242, 84, 202, 110, 219, 224, 222, 81, 1, + 219, 62, 220, 17, 1, 232, 176, 232, 166, 220, 17, 1, 232, 176, 233, 62, + 220, 17, 1, 206, 162, 220, 17, 1, 219, 43, 86, 87, 248, 141, 203, 50, + 231, 54, 216, 118, 207, 9, 30, 125, 192, 54, 30, 125, 192, 50, 30, 125, + 201, 153, 30, 125, 192, 55, 232, 66, 232, 65, 232, 64, 215, 83, 232, 63, + 200, 197, 1, 251, 14, 68, 190, 232, 190, 233, 190, 235, 218, 229, 206, + 170, 218, 231, 206, 172, 210, 66, 218, 228, 206, 169, 213, 75, 216, 16, + 193, 50, 218, 230, 206, 171, 232, 89, 210, 65, 193, 111, 234, 119, 232, + 76, 216, 92, 211, 105, 196, 46, 113, 216, 92, 237, 216, 113, 118, 197, + 240, 64, 4, 55, 81, 106, 96, 197, 240, 64, 4, 55, 81, 106, 11, 5, 223, + 51, 77, 80, 1, 221, 206, 219, 73, 194, 251, 194, 140, 194, 72, 194, 61, + 194, 50, 194, 39, 194, 28, 194, 17, 194, 6, 194, 250, 194, 239, 194, 228, + 194, 217, 194, 206, 194, 195, 194, 184, 208, 221, 232, 146, 40, 81, 50, + 63, 219, 187, 248, 53, 247, 198, 211, 51, 77, 248, 100, 190, 234, 10, 3, + 212, 148, 199, 84, 10, 3, 212, 148, 139, 212, 148, 247, 231, 139, 247, + 230, 216, 218, 6, 1, 230, 116, 216, 218, 6, 1, 214, 70, 216, 218, 2, 1, + 230, 116, 216, 218, 2, 1, 214, 70, 61, 1, 235, 14, 73, 37, 16, 232, 88, + 202, 106, 243, 52, 195, 164, 194, 173, 194, 162, 194, 151, 194, 139, 194, + 128, 194, 117, 194, 106, 194, 95, 194, 84, 194, 76, 194, 75, 194, 74, + 194, 73, 194, 71, 194, 70, 194, 69, 194, 68, 194, 67, 194, 66, 194, 65, + 194, 64, 194, 63, 194, 62, 194, 60, 194, 59, 194, 58, 194, 57, 194, 56, + 194, 55, 194, 54, 194, 53, 194, 52, 194, 51, 194, 49, 194, 48, 194, 47, + 194, 46, 194, 45, 194, 44, 194, 43, 194, 42, 194, 41, 194, 40, 194, 38, + 194, 37, 194, 36, 194, 35, 194, 34, 194, 33, 194, 32, 194, 31, 194, 30, + 194, 29, 194, 27, 194, 26, 194, 25, 194, 24, 194, 23, 194, 22, 194, 21, + 194, 20, 194, 19, 194, 18, 194, 16, 194, 15, 194, 14, 194, 13, 194, 12, + 194, 11, 194, 10, 194, 9, 194, 8, 194, 7, 194, 5, 194, 4, 194, 3, 194, 2, + 194, 1, 194, 0, 193, 255, 193, 254, 193, 253, 193, 252, 194, 249, 194, + 248, 194, 247, 194, 246, 194, 245, 194, 244, 194, 243, 194, 242, 194, + 241, 194, 240, 194, 238, 194, 237, 194, 236, 194, 235, 194, 234, 194, + 233, 194, 232, 194, 231, 194, 230, 194, 229, 194, 227, 194, 226, 194, + 225, 194, 224, 194, 223, 194, 222, 194, 221, 194, 220, 194, 219, 194, + 218, 194, 216, 194, 215, 194, 214, 194, 213, 194, 212, 194, 211, 194, + 210, 194, 209, 194, 208, 194, 207, 194, 205, 194, 204, 194, 203, 194, + 202, 194, 201, 194, 200, 194, 199, 194, 198, 194, 197, 194, 196, 194, + 194, 194, 193, 194, 192, 194, 191, 194, 190, 194, 189, 194, 188, 194, + 187, 194, 186, 194, 185, 194, 183, 194, 182, 194, 181, 194, 180, 194, + 179, 194, 178, 194, 177, 194, 176, 194, 175, 194, 174, 194, 172, 194, + 171, 194, 170, 194, 169, 194, 168, 194, 167, 194, 166, 194, 165, 194, + 164, 194, 163, 194, 161, 194, 160, 194, 159, 194, 158, 194, 157, 194, + 156, 194, 155, 194, 154, 194, 153, 194, 152, 194, 150, 194, 149, 194, + 148, 194, 147, 194, 146, 194, 145, 194, 144, 194, 143, 194, 142, 194, + 141, 194, 138, 194, 137, 194, 136, 194, 135, 194, 134, 194, 133, 194, + 132, 194, 131, 194, 130, 194, 129, 194, 127, 194, 126, 194, 125, 194, + 124, 194, 123, 194, 122, 194, 121, 194, 120, 194, 119, 194, 118, 194, + 116, 194, 115, 194, 114, 194, 113, 194, 112, 194, 111, 194, 110, 194, + 109, 194, 108, 194, 107, 194, 105, 194, 104, 194, 103, 194, 102, 194, + 101, 194, 100, 194, 99, 194, 98, 194, 97, 194, 96, 194, 94, 194, 93, 194, + 92, 194, 91, 194, 90, 194, 89, 194, 88, 194, 87, 194, 86, 194, 85, 194, + 83, 194, 82, 194, 81, 194, 80, 194, 79, 194, 78, 194, 77, 221, 219, 31, + 56, 221, 219, 250, 193, 221, 219, 17, 191, 77, 221, 219, 17, 107, 221, + 219, 17, 109, 221, 219, 17, 138, 221, 219, 17, 134, 221, 219, 17, 149, + 221, 219, 17, 169, 221, 219, 17, 175, 221, 219, 17, 171, 221, 219, 17, + 178, 8, 6, 1, 42, 4, 217, 147, 23, 230, 210, 8, 2, 1, 42, 4, 217, 147, + 23, 230, 210, 8, 6, 1, 228, 74, 4, 217, 147, 23, 230, 210, 8, 2, 1, 228, + 74, 4, 217, 147, 23, 230, 210, 8, 6, 1, 126, 4, 217, 147, 23, 230, 210, + 8, 2, 1, 126, 4, 217, 147, 23, 230, 210, 8, 6, 1, 235, 15, 4, 81, 219, + 113, 60, 8, 2, 1, 235, 15, 4, 81, 219, 113, 60, 8, 6, 1, 235, 15, 4, 81, + 219, 113, 248, 233, 23, 230, 210, 8, 2, 1, 235, 15, 4, 81, 219, 113, 248, + 233, 23, 230, 210, 8, 6, 1, 235, 15, 4, 81, 219, 113, 248, 233, 23, 252, + 46, 8, 2, 1, 235, 15, 4, 81, 219, 113, 248, 233, 23, 252, 46, 8, 6, 1, + 187, 4, 81, 219, 113, 60, 8, 2, 1, 187, 4, 81, 219, 113, 60, 8, 6, 1, + 187, 4, 81, 219, 113, 248, 233, 23, 230, 210, 8, 2, 1, 187, 4, 81, 219, + 113, 248, 233, 23, 230, 210, 8, 6, 1, 187, 4, 81, 219, 113, 248, 233, 23, + 252, 46, 8, 2, 1, 187, 4, 81, 219, 113, 248, 233, 23, 252, 46, 8, 6, 1, + 206, 9, 4, 81, 219, 113, 60, 8, 2, 1, 206, 9, 4, 81, 219, 113, 60, 8, 6, + 1, 235, 15, 4, 243, 2, 23, 217, 146, 8, 2, 1, 235, 15, 4, 243, 2, 23, + 217, 146, 8, 6, 1, 235, 15, 4, 243, 2, 23, 247, 92, 8, 2, 1, 235, 15, 4, + 243, 2, 23, 247, 92, 8, 2, 1, 228, 74, 4, 75, 93, 23, 252, 46, 8, 2, 1, + 214, 71, 4, 198, 153, 58, 8, 6, 1, 42, 4, 211, 139, 23, 252, 46, 8, 2, 1, + 42, 4, 211, 139, 23, 252, 46, 8, 6, 1, 42, 4, 211, 139, 23, 198, 152, 8, + 2, 1, 42, 4, 211, 139, 23, 198, 152, 8, 6, 1, 235, 15, 4, 211, 139, 23, + 252, 46, 8, 2, 1, 235, 15, 4, 211, 139, 23, 252, 46, 8, 6, 1, 235, 15, 4, + 211, 139, 23, 198, 152, 8, 2, 1, 235, 15, 4, 211, 139, 23, 198, 152, 8, + 6, 1, 235, 15, 4, 75, 93, 23, 252, 46, 8, 2, 1, 235, 15, 4, 75, 93, 23, + 252, 46, 8, 6, 1, 235, 15, 4, 75, 93, 23, 198, 152, 8, 2, 1, 235, 15, 4, + 75, 93, 23, 198, 152, 8, 2, 1, 228, 74, 4, 75, 93, 23, 230, 210, 8, 2, 1, + 228, 74, 4, 75, 93, 23, 198, 152, 8, 6, 1, 228, 74, 4, 211, 139, 23, 252, + 46, 8, 2, 1, 228, 74, 4, 211, 139, 23, 75, 93, 23, 252, 46, 8, 6, 1, 228, + 74, 4, 211, 139, 23, 198, 152, 8, 2, 1, 228, 74, 4, 211, 139, 23, 75, 93, + 23, 198, 152, 8, 6, 1, 223, 36, 4, 198, 152, 8, 2, 1, 223, 36, 4, 75, 93, + 23, 198, 152, 8, 6, 1, 220, 143, 4, 198, 152, 8, 2, 1, 220, 143, 4, 198, + 152, 8, 6, 1, 218, 169, 4, 198, 152, 8, 2, 1, 218, 169, 4, 198, 152, 8, + 6, 1, 207, 222, 4, 198, 152, 8, 2, 1, 207, 222, 4, 198, 152, 8, 6, 1, + 126, 4, 211, 139, 23, 252, 46, 8, 2, 1, 126, 4, 211, 139, 23, 252, 46, 8, + 6, 1, 126, 4, 211, 139, 23, 198, 152, 8, 2, 1, 126, 4, 211, 139, 23, 198, + 152, 8, 6, 1, 126, 4, 217, 147, 23, 252, 46, 8, 2, 1, 126, 4, 217, 147, + 23, 252, 46, 8, 6, 1, 126, 4, 217, 147, 23, 198, 152, 8, 2, 1, 126, 4, + 217, 147, 23, 198, 152, 8, 2, 1, 252, 26, 4, 230, 210, 8, 2, 1, 211, 77, + 187, 4, 230, 210, 8, 2, 1, 211, 77, 187, 4, 252, 46, 8, 2, 1, 153, 196, + 13, 4, 230, 210, 8, 2, 1, 153, 196, 13, 4, 252, 46, 8, 2, 1, 205, 87, 4, + 230, 210, 8, 2, 1, 205, 87, 4, 252, 46, 8, 2, 1, 228, 250, 205, 87, 4, + 230, 210, 8, 2, 1, 228, 250, 205, 87, 4, 252, 46, 9, 204, 7, 99, 4, 230, + 58, 93, 4, 251, 192, 9, 204, 7, 99, 4, 230, 58, 93, 4, 193, 133, 9, 204, + 7, 99, 4, 230, 58, 93, 4, 131, 217, 99, 9, 204, 7, 99, 4, 230, 58, 93, 4, + 211, 151, 9, 204, 7, 99, 4, 230, 58, 93, 4, 66, 9, 204, 7, 99, 4, 230, + 58, 93, 4, 191, 225, 9, 204, 7, 99, 4, 230, 58, 93, 4, 71, 9, 204, 7, 99, + 4, 230, 58, 93, 4, 252, 25, 9, 204, 7, 213, 25, 4, 222, 4, 100, 204, 7, + 40, 1, 208, 96, 100, 204, 7, 40, 1, 221, 193, 100, 204, 7, 40, 1, 231, + 66, 100, 204, 7, 40, 1, 191, 123, 100, 204, 7, 40, 1, 237, 180, 100, 204, + 7, 40, 1, 207, 6, 100, 204, 7, 40, 1, 233, 109, 100, 204, 7, 40, 1, 191, + 175, 248, 225, 204, 7, 40, 1, 206, 109, 248, 225, 204, 7, 40, 1, 207, 6, + 248, 225, 204, 7, 40, 1, 191, 175, 230, 144, 204, 7, 40, 1, 219, 73, 230, + 144, 204, 7, 40, 1, 203, 165, 230, 144, 204, 7, 40, 1, 221, 193, 230, + 144, 204, 7, 40, 1, 231, 66, 230, 144, 204, 7, 40, 1, 191, 123, 230, 144, + 204, 7, 40, 1, 233, 109, 211, 45, 204, 7, 40, 1, 206, 109, 211, 45, 204, + 7, 40, 1, 207, 6, 248, 225, 1, 221, 187, 44, 120, 222, 152, 44, 120, 214, + 70, 44, 120, 247, 193, 44, 120, 212, 103, 44, 120, 197, 135, 44, 120, + 213, 80, 44, 120, 200, 43, 44, 120, 215, 61, 44, 120, 210, 236, 44, 120, + 218, 168, 44, 120, 192, 159, 44, 120, 146, 44, 120, 172, 44, 120, 196, + 12, 44, 120, 219, 63, 44, 120, 219, 74, 44, 120, 206, 110, 44, 120, 213, + 62, 44, 120, 223, 35, 44, 120, 203, 167, 44, 120, 201, 178, 44, 120, 206, + 8, 44, 120, 230, 116, 44, 120, 220, 247, 44, 5, 222, 127, 44, 5, 221, + 166, 44, 5, 221, 145, 44, 5, 220, 232, 44, 5, 220, 187, 44, 5, 222, 22, + 44, 5, 222, 13, 44, 5, 222, 102, 44, 5, 221, 67, 44, 5, 221, 41, 44, 5, + 222, 42, 44, 5, 214, 67, 44, 5, 214, 16, 44, 5, 214, 12, 44, 5, 213, 237, + 44, 5, 213, 228, 44, 5, 214, 55, 44, 5, 214, 53, 44, 5, 214, 64, 44, 5, + 213, 249, 44, 5, 213, 244, 44, 5, 214, 57, 44, 5, 247, 159, 44, 5, 243, + 29, 44, 5, 243, 19, 44, 5, 238, 195, 44, 5, 238, 153, 44, 5, 247, 42, 44, + 5, 247, 34, 44, 5, 247, 148, 44, 5, 242, 99, 44, 5, 239, 18, 44, 5, 247, + 76, 44, 5, 212, 100, 44, 5, 212, 81, 44, 5, 212, 75, 44, 5, 212, 58, 44, + 5, 212, 50, 44, 5, 212, 90, 44, 5, 212, 89, 44, 5, 212, 97, 44, 5, 212, + 65, 44, 5, 212, 62, 44, 5, 212, 93, 44, 5, 197, 131, 44, 5, 197, 111, 44, + 5, 197, 110, 44, 5, 197, 99, 44, 5, 197, 96, 44, 5, 197, 127, 44, 5, 197, + 126, 44, 5, 197, 130, 44, 5, 197, 109, 44, 5, 197, 108, 44, 5, 197, 129, + 44, 5, 213, 78, 44, 5, 213, 64, 44, 5, 213, 63, 44, 5, 213, 47, 44, 5, + 213, 46, 44, 5, 213, 74, 44, 5, 213, 73, 44, 5, 213, 77, 44, 5, 213, 49, + 44, 5, 213, 48, 44, 5, 213, 76, 44, 5, 199, 245, 44, 5, 198, 193, 44, 5, + 198, 170, 44, 5, 197, 94, 44, 5, 197, 49, 44, 5, 199, 145, 44, 5, 199, + 121, 44, 5, 199, 217, 44, 5, 159, 44, 5, 198, 59, 44, 5, 199, 166, 44, 5, + 214, 250, 44, 5, 213, 219, 44, 5, 213, 186, 44, 5, 212, 178, 44, 5, 212, + 115, 44, 5, 214, 121, 44, 5, 214, 110, 44, 5, 214, 236, 44, 5, 213, 43, + 44, 5, 213, 26, 44, 5, 214, 205, 44, 5, 210, 220, 44, 5, 209, 185, 44, 5, + 209, 145, 44, 5, 208, 165, 44, 5, 208, 128, 44, 5, 210, 63, 44, 5, 210, + 49, 44, 5, 210, 198, 44, 5, 209, 73, 44, 5, 209, 37, 44, 5, 210, 80, 44, + 5, 217, 151, 44, 5, 216, 100, 44, 5, 216, 61, 44, 5, 215, 155, 44, 5, + 215, 93, 44, 5, 216, 232, 44, 5, 216, 211, 44, 5, 217, 112, 44, 5, 216, + 12, 44, 5, 215, 211, 44, 5, 217, 25, 44, 5, 192, 140, 44, 5, 192, 33, 44, + 5, 192, 23, 44, 5, 191, 225, 44, 5, 191, 188, 44, 5, 192, 80, 44, 5, 192, + 77, 44, 5, 192, 119, 44, 5, 192, 12, 44, 5, 191, 246, 44, 5, 192, 91, 44, + 5, 207, 178, 44, 5, 207, 1, 44, 5, 206, 195, 44, 5, 206, 68, 44, 5, 206, + 29, 44, 5, 207, 113, 44, 5, 207, 84, 44, 5, 207, 156, 44, 5, 206, 162, + 44, 5, 206, 134, 44, 5, 207, 125, 44, 5, 220, 125, 44, 5, 219, 146, 44, + 5, 219, 128, 44, 5, 218, 225, 44, 5, 218, 194, 44, 5, 219, 238, 44, 5, + 219, 228, 44, 5, 220, 96, 44, 5, 219, 43, 44, 5, 219, 8, 44, 5, 220, 0, + 44, 5, 195, 187, 44, 5, 195, 69, 44, 5, 195, 51, 44, 5, 193, 249, 44, 5, + 193, 241, 44, 5, 195, 153, 44, 5, 195, 148, 44, 5, 195, 183, 44, 5, 195, + 24, 44, 5, 195, 8, 44, 5, 195, 160, 44, 5, 219, 61, 44, 5, 219, 56, 44, + 5, 219, 55, 44, 5, 219, 52, 44, 5, 219, 51, 44, 5, 219, 58, 44, 5, 219, + 57, 44, 5, 219, 60, 44, 5, 219, 54, 44, 5, 219, 53, 44, 5, 219, 59, 44, + 5, 219, 72, 44, 5, 219, 65, 44, 5, 219, 64, 44, 5, 219, 48, 44, 5, 219, + 47, 44, 5, 219, 68, 44, 5, 219, 67, 44, 5, 219, 71, 44, 5, 219, 50, 44, + 5, 219, 49, 44, 5, 219, 69, 44, 5, 206, 108, 44, 5, 206, 97, 44, 5, 206, + 96, 44, 5, 206, 89, 44, 5, 206, 82, 44, 5, 206, 104, 44, 5, 206, 103, 44, + 5, 206, 107, 44, 5, 206, 95, 44, 5, 206, 94, 44, 5, 206, 106, 44, 5, 213, + 60, 44, 5, 213, 55, 44, 5, 213, 54, 44, 5, 213, 51, 44, 5, 213, 50, 44, + 5, 213, 57, 44, 5, 213, 56, 44, 5, 213, 59, 44, 5, 213, 53, 44, 5, 213, + 52, 44, 5, 213, 58, 44, 5, 223, 31, 44, 5, 222, 244, 44, 5, 222, 236, 44, + 5, 222, 182, 44, 5, 222, 162, 44, 5, 223, 10, 44, 5, 223, 8, 44, 5, 223, + 25, 44, 5, 222, 201, 44, 5, 222, 191, 44, 5, 223, 17, 44, 5, 203, 160, + 44, 5, 203, 81, 44, 5, 203, 76, 44, 5, 203, 5, 44, 5, 202, 243, 44, 5, + 203, 113, 44, 5, 203, 111, 44, 5, 203, 148, 44, 5, 203, 56, 44, 5, 203, + 48, 44, 5, 203, 122, 44, 5, 201, 174, 44, 5, 201, 142, 44, 5, 201, 138, + 44, 5, 201, 129, 44, 5, 201, 126, 44, 5, 201, 148, 44, 5, 201, 147, 44, + 5, 201, 173, 44, 5, 201, 134, 44, 5, 201, 133, 44, 5, 201, 150, 44, 5, + 205, 197, 44, 5, 202, 222, 44, 5, 202, 193, 44, 5, 201, 4, 44, 5, 200, + 160, 44, 5, 205, 68, 44, 5, 205, 50, 44, 5, 205, 181, 44, 5, 202, 46, 44, + 5, 202, 16, 44, 5, 205, 114, 44, 5, 230, 91, 44, 5, 229, 158, 44, 5, 229, + 130, 44, 5, 228, 159, 44, 5, 228, 128, 44, 5, 229, 245, 44, 5, 229, 215, + 44, 5, 230, 80, 44, 5, 229, 23, 44, 5, 228, 252, 44, 5, 230, 2, 44, 5, + 220, 246, 44, 5, 220, 245, 44, 5, 220, 240, 44, 5, 220, 239, 44, 5, 220, + 236, 44, 5, 220, 235, 44, 5, 220, 242, 44, 5, 220, 241, 44, 5, 220, 244, + 44, 5, 220, 238, 44, 5, 220, 237, 44, 5, 220, 243, 44, 5, 203, 14, 166, + 120, 3, 192, 105, 166, 120, 3, 207, 144, 166, 120, 3, 207, 50, 101, 1, + 196, 224, 95, 120, 3, 242, 91, 155, 95, 120, 3, 242, 91, 221, 215, 95, + 120, 3, 242, 91, 221, 67, 95, 120, 3, 242, 91, 221, 183, 95, 120, 3, 242, + 91, 213, 249, 95, 120, 3, 242, 91, 247, 160, 95, 120, 3, 242, 91, 247, 1, + 95, 120, 3, 242, 91, 242, 99, 95, 120, 3, 242, 91, 243, 68, 95, 120, 3, + 242, 91, 212, 65, 95, 120, 3, 242, 91, 238, 32, 95, 120, 3, 242, 91, 197, + 120, 95, 120, 3, 242, 91, 236, 174, 95, 120, 3, 242, 91, 197, 115, 95, + 120, 3, 242, 91, 180, 95, 120, 3, 242, 91, 190, 190, 95, 120, 3, 242, 91, + 199, 49, 95, 120, 3, 242, 91, 159, 95, 120, 3, 242, 91, 198, 241, 95, + 120, 3, 242, 91, 213, 43, 95, 120, 3, 242, 91, 249, 153, 95, 120, 3, 242, + 91, 209, 228, 95, 120, 3, 242, 91, 209, 73, 95, 120, 3, 242, 91, 209, + 199, 95, 120, 3, 242, 91, 216, 12, 95, 120, 3, 242, 91, 192, 12, 95, 120, + 3, 242, 91, 206, 162, 95, 120, 3, 242, 91, 219, 43, 95, 120, 3, 242, 91, + 195, 24, 95, 120, 3, 242, 91, 203, 165, 95, 120, 3, 242, 91, 201, 175, + 95, 120, 3, 242, 91, 188, 95, 120, 3, 242, 91, 140, 95, 120, 3, 242, 91, + 173, 95, 18, 3, 242, 91, 208, 96, 95, 223, 149, 18, 3, 242, 91, 208, 33, + 95, 223, 149, 18, 3, 242, 91, 206, 17, 95, 223, 149, 18, 3, 242, 91, 206, + 10, 95, 223, 149, 18, 3, 242, 91, 208, 75, 95, 18, 3, 211, 113, 95, 18, + 3, 252, 167, 229, 120, 1, 248, 181, 214, 68, 229, 120, 1, 248, 181, 214, + 16, 229, 120, 1, 248, 181, 213, 237, 229, 120, 1, 248, 181, 214, 55, 229, + 120, 1, 248, 181, 213, 249, 72, 1, 248, 181, 214, 68, 72, 1, 248, 181, + 214, 16, 72, 1, 248, 181, 213, 237, 72, 1, 248, 181, 214, 55, 72, 1, 248, + 181, 213, 249, 72, 1, 251, 228, 247, 42, 72, 1, 251, 228, 197, 94, 72, 1, + 251, 228, 159, 72, 1, 251, 228, 210, 236, 52, 1, 233, 200, 233, 199, 239, + 26, 163, 164, 52, 1, 233, 199, 233, 200, 239, 26, 163, 164, }; static const unsigned short phrasebook_offset1[] = { @@ -20584,39 +20721,39 @@ static const unsigned short phrasebook_offset1[] = { 148, 104, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 104, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 104, 182, 183, 104, 184, 185, - 186, 187, 104, 188, 189, 190, 191, 192, 193, 104, 104, 194, 195, 196, - 197, 104, 198, 104, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, - 209, 210, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 211, 212, 213, 214, 215, 216, - 217, 218, 219, 220, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 186, 187, 104, 188, 189, 190, 191, 192, 193, 194, 104, 195, 196, 197, + 198, 104, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, + 211, 212, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 213, 214, 215, 216, 217, 218, + 219, 220, 221, 222, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 221, 222, 223, 224, 225, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 223, 224, 225, 226, 227, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 226, 227, 228, 229, 230, - 231, 232, 233, 104, 104, 104, 104, 234, 235, 236, 237, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 228, 229, 230, 231, 232, + 233, 234, 235, 104, 104, 104, 104, 236, 237, 238, 239, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 104, + 104, 104, 104, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 248, 249, - 250, 251, 252, 253, 254, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 255, 256, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 250, 251, + 252, 253, 254, 255, 256, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 257, 258, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 257, 258, 259, 260, 261, 262, 263, 264, 265, - 104, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, - 279, 104, 104, 104, 104, 104, 104, 104, 104, 280, 104, 281, 104, 282, - 104, 104, 283, 104, 104, 104, 104, 104, 104, 104, 104, 104, 284, 285, - 286, 287, 104, 104, 104, 104, 104, 288, 289, 290, 104, 291, 292, 104, - 104, 293, 294, 295, 296, 297, 104, 298, 299, 300, 301, 302, 303, 304, - 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 104, 104, 104, + 104, 104, 104, 104, 104, 259, 260, 261, 262, 263, 264, 265, 266, 267, + 104, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, + 281, 104, 104, 104, 104, 104, 104, 104, 104, 282, 104, 283, 284, 285, + 104, 104, 286, 104, 104, 104, 287, 104, 104, 104, 104, 104, 288, 289, + 290, 291, 104, 104, 104, 104, 104, 292, 293, 294, 104, 295, 296, 104, + 104, 297, 298, 299, 300, 301, 104, 302, 303, 304, 305, 306, 307, 308, + 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, @@ -20652,8 +20789,8 @@ static const unsigned short phrasebook_offset1[] = { 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 316, 317, 318, - 319, 320, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 320, 321, 322, + 323, 324, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, @@ -21056,7 +21193,7 @@ static const unsigned short phrasebook_offset1[] = { 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 321, 104, 322, 323, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 325, 104, 326, 327, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, @@ -21092,8 +21229,8 @@ static const unsigned short phrasebook_offset1[] = { 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 324, 325, 326, - 327, 328, 329, 330, 331, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 328, 329, 330, + 331, 332, 333, 334, 335, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, @@ -21446,2045 +21583,2052 @@ static const unsigned int phrasebook_offset2[] = { 17007, 17013, 0, 17019, 17024, 17030, 17036, 0, 0, 0, 0, 0, 0, 0, 17041, 17046, 0, 0, 0, 0, 0, 0, 17053, 17060, 0, 17065, 17071, 17077, 17083, 0, 0, 17090, 17095, 17099, 17103, 17107, 17111, 17115, 17119, 17123, 17127, - 0, 17131, 17136, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17141, 17147, - 17151, 17155, 17159, 17165, 17168, 17172, 17175, 17179, 17182, 17186, - 17190, 0, 17194, 17197, 17201, 0, 17205, 17208, 17212, 17216, 17219, - 17223, 17227, 17231, 17235, 17239, 17243, 17247, 17251, 17255, 17259, - 17263, 17267, 17271, 17275, 17279, 17283, 17287, 17291, 17294, 17298, - 17301, 17305, 17309, 17313, 17316, 17319, 17322, 17326, 17329, 17333, - 17337, 17341, 17345, 17349, 17352, 17355, 17359, 17366, 17372, 17376, - 17381, 17385, 17390, 17394, 17399, 17404, 0, 17410, 17414, 17419, 0, - 17424, 17428, 17433, 17438, 17442, 17447, 0, 0, 0, 0, 17451, 17457, - 17463, 17469, 17475, 17481, 17487, 17493, 17499, 17505, 17511, 17517, - 17523, 17528, 17533, 17538, 0, 0, 17544, 17548, 17551, 17554, 17557, - 17560, 17563, 17566, 17569, 17572, 17575, 17579, 17584, 17588, 17594, - 17600, 17606, 17612, 17618, 17624, 17628, 17634, 17640, 17646, 17651, - 17657, 0, 17663, 17667, 17671, 0, 17675, 17679, 17683, 17687, 17691, - 17695, 17699, 17703, 17707, 17711, 17715, 17719, 17723, 17727, 17731, - 17735, 17739, 17743, 0, 0, 0, 17747, 17753, 17759, 17765, 17771, 17777, - 17783, 17789, 17795, 17801, 17807, 17813, 17821, 17827, 17833, 17839, - 17845, 17851, 17857, 17863, 17869, 17875, 17881, 17887, 0, 17893, 17899, - 17905, 17911, 17917, 17923, 17927, 17933, 17937, 0, 17941, 0, 0, 17947, - 17951, 17957, 17963, 17969, 17973, 17979, 0, 0, 0, 17983, 0, 0, 0, 0, - 17987, 17992, 17999, 18006, 18013, 18020, 0, 18027, 0, 18034, 18039, - 18044, 18051, 18058, 18067, 18078, 18087, 0, 0, 0, 0, 0, 0, 18092, 18098, - 18103, 18108, 18113, 18118, 18123, 18128, 18133, 18138, 0, 0, 18143, - 18150, 18157, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18162, 18170, 18178, - 18186, 18194, 18202, 18210, 18218, 18226, 18234, 18242, 18250, 18258, - 18266, 18274, 18281, 18289, 18297, 18305, 18313, 18321, 18328, 18336, - 18344, 18352, 18360, 18368, 18376, 18384, 18392, 18400, 18408, 18416, - 18423, 18431, 18439, 18445, 18453, 18459, 18467, 18475, 18483, 18491, - 18499, 18507, 18514, 18522, 18528, 18535, 18543, 18551, 18559, 18566, - 18574, 18582, 18590, 18597, 18605, 0, 0, 0, 0, 18611, 18618, 18625, - 18633, 18640, 18650, 18660, 18666, 18672, 18678, 18686, 18694, 18702, - 18710, 18716, 18722, 18728, 18734, 18739, 18743, 18747, 18751, 18755, - 18759, 18763, 18767, 18771, 18775, 18781, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 17131, 17136, 17141, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17149, 17155, + 17159, 17163, 17167, 17173, 17176, 17180, 17183, 17187, 17190, 17194, + 17198, 0, 17202, 17205, 17209, 0, 17213, 17216, 17220, 17224, 17227, + 17231, 17235, 17239, 17243, 17247, 17251, 17255, 17259, 17263, 17267, + 17271, 17275, 17279, 17283, 17287, 17291, 17295, 17299, 17302, 17306, + 17309, 17313, 17317, 17321, 17324, 17327, 17330, 17334, 17337, 17341, + 17345, 17349, 17353, 17357, 17360, 17363, 17367, 17374, 17380, 17384, + 17389, 17393, 17398, 17402, 17407, 17412, 0, 17418, 17422, 17427, 0, + 17432, 17436, 17441, 17446, 17450, 17455, 0, 0, 0, 0, 17459, 17465, + 17471, 17477, 17483, 17489, 17495, 17501, 17507, 17513, 17519, 17525, + 17531, 17536, 17541, 17546, 0, 0, 17552, 17556, 17559, 17562, 17565, + 17568, 17571, 17574, 17577, 17580, 17583, 17587, 17592, 17596, 17602, + 17608, 17614, 17620, 17626, 17632, 17636, 17642, 17648, 17654, 17659, + 17665, 0, 17671, 17675, 17679, 0, 17683, 17687, 17691, 17695, 17699, + 17703, 17707, 17711, 17715, 17719, 17723, 17727, 17731, 17735, 17739, + 17743, 17747, 17751, 0, 0, 0, 17755, 17761, 17767, 17773, 17779, 17785, + 17791, 17797, 17803, 17809, 17815, 17821, 17829, 17835, 17841, 17847, + 17853, 17859, 17865, 17871, 17877, 17883, 17889, 17895, 0, 17901, 17907, + 17913, 17919, 17925, 17931, 17935, 17941, 17945, 0, 17949, 0, 0, 17955, + 17959, 17965, 17971, 17977, 17981, 17987, 0, 0, 0, 17991, 0, 0, 0, 0, + 17995, 18000, 18007, 18014, 18021, 18028, 0, 18035, 0, 18042, 18047, + 18052, 18059, 18066, 18075, 18086, 18095, 0, 0, 0, 0, 0, 0, 18100, 18106, + 18111, 18116, 18121, 18126, 18131, 18136, 18141, 18146, 0, 0, 18151, + 18158, 18165, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18170, 18178, 18186, + 18194, 18202, 18210, 18218, 18226, 18234, 18242, 18250, 18258, 18266, + 18274, 18282, 18289, 18297, 18305, 18313, 18321, 18329, 18336, 18344, + 18352, 18360, 18368, 18376, 18384, 18392, 18400, 18408, 18416, 18424, + 18431, 18439, 18447, 18453, 18461, 18467, 18475, 18483, 18491, 18499, + 18507, 18515, 18522, 18530, 18536, 18543, 18551, 18559, 18567, 18574, + 18582, 18590, 18598, 18605, 18613, 0, 0, 0, 0, 18619, 18626, 18633, + 18641, 18648, 18658, 18668, 18674, 18680, 18686, 18694, 18702, 18710, + 18718, 18724, 18730, 18736, 18742, 18747, 18751, 18755, 18759, 18763, + 18767, 18771, 18775, 18779, 18783, 18789, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 18795, 18800, 0, 18807, 0, 18814, 18821, 18826, 18831, 18838, 0, + 18845, 18852, 18857, 18864, 18871, 18878, 18885, 18892, 18899, 18904, + 18908, 18915, 18922, 18929, 18934, 18939, 18944, 18951, 18958, 18965, + 18972, 18979, 18984, 18989, 0, 18996, 0, 19003, 19008, 19015, 19022, + 19029, 19036, 19043, 19047, 19054, 19058, 19063, 19071, 19077, 19083, + 19088, 19094, 19100, 19106, 19111, 19117, 19124, 19132, 19139, 0, 0, + 19146, 19151, 19157, 19162, 19168, 0, 19174, 0, 19179, 19186, 19193, + 19200, 19207, 19212, 19216, 0, 19220, 19225, 19229, 19233, 19237, 19241, + 19245, 19249, 19253, 19257, 0, 0, 19261, 19267, 19273, 19280, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 19287, 19291, 19302, 19317, 19332, 19342, 19353, 19366, + 19377, 19383, 19391, 19401, 19407, 19415, 19419, 19425, 19431, 19439, + 19449, 19457, 19470, 19476, 19484, 19492, 19504, 19511, 19519, 19527, + 19535, 19543, 19551, 19559, 19569, 19573, 19576, 19579, 19582, 19585, + 19588, 19591, 19594, 19597, 19600, 19604, 19608, 19612, 19616, 19620, + 19624, 19628, 19632, 19636, 19641, 19647, 19657, 19671, 19681, 19687, + 19693, 19701, 19709, 19717, 19725, 19731, 19737, 19740, 19744, 19748, + 19752, 19756, 19760, 19764, 0, 19768, 19772, 19776, 19780, 19784, 19788, + 19792, 19796, 19800, 19804, 19808, 19811, 19814, 19818, 19822, 19826, + 19829, 19833, 19837, 19841, 19845, 19849, 19853, 19857, 19861, 19864, + 19867, 19870, 19874, 19878, 19881, 19884, 19887, 19891, 19896, 19900, 0, + 0, 0, 0, 19904, 19909, 19913, 19918, 19922, 19927, 19932, 19938, 19943, + 19949, 19953, 19958, 19962, 19967, 19977, 19983, 19989, 19996, 20006, + 20012, 20016, 20020, 20026, 20032, 20040, 20046, 20054, 20062, 20070, + 20080, 20088, 20098, 20103, 20109, 20115, 20121, 20127, 20133, 20139, 0, + 20145, 20151, 20157, 20163, 20169, 20175, 20181, 20187, 20193, 20199, + 20205, 20210, 20215, 20221, 20227, 20233, 20238, 20244, 20250, 20256, + 20262, 20268, 20274, 20280, 20286, 20291, 20296, 20301, 20307, 20313, + 20318, 20323, 20328, 20334, 20342, 20349, 0, 20356, 20363, 20376, 20383, + 20390, 20398, 20406, 20412, 20418, 20424, 20434, 20439, 20445, 20455, + 20465, 0, 20475, 20485, 20493, 20505, 20517, 20523, 20537, 20552, 20557, + 20562, 20570, 20578, 20586, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20594, + 20597, 20601, 20605, 20609, 20613, 20617, 20621, 20625, 20629, 20633, + 20637, 20641, 20645, 20649, 20653, 20657, 20661, 20665, 20669, 20673, + 20676, 20679, 20683, 20687, 20691, 20694, 20697, 20700, 20703, 20707, + 20710, 20713, 20717, 20720, 20725, 20728, 20732, 20735, 20739, 20742, + 20747, 20750, 20754, 20761, 20766, 20770, 20775, 20779, 20784, 20788, + 20793, 20800, 20806, 20812, 20816, 20820, 20824, 20828, 20832, 20838, + 20844, 20851, 20857, 20862, 20866, 20869, 20872, 20875, 20878, 20881, + 20884, 20887, 20890, 20893, 20899, 20903, 20907, 20911, 20915, 20919, + 20923, 20927, 20931, 20936, 20940, 20945, 20950, 20956, 20961, 20967, + 20973, 20979, 20985, 20991, 20999, 21007, 21015, 21023, 21032, 21041, + 21052, 21062, 21072, 21083, 21094, 21104, 21114, 21124, 21134, 21144, + 21154, 21164, 21174, 21182, 21189, 21195, 21202, 21207, 21213, 21219, + 21225, 21231, 21237, 21243, 21248, 21254, 21260, 21266, 21272, 21277, + 21286, 21293, 21299, 21307, 21315, 21321, 21327, 21333, 21339, 21347, + 21355, 21365, 21373, 21381, 21387, 21392, 21397, 21402, 21407, 21412, + 21417, 21422, 21427, 21432, 21438, 21444, 21450, 21457, 21462, 21468, + 21473, 21478, 21483, 21488, 21493, 21498, 21503, 21508, 21513, 21518, + 21523, 21528, 21533, 21538, 21543, 21548, 21553, 21558, 21563, 21568, + 21573, 21578, 21583, 21588, 21593, 21598, 21603, 21608, 21613, 21618, + 21623, 21628, 21633, 21638, 21643, 21648, 21653, 0, 21658, 0, 0, 0, 0, 0, + 21663, 0, 0, 21668, 21672, 21676, 21680, 21684, 21688, 21692, 21696, + 21700, 21704, 21708, 21712, 21716, 21720, 21724, 21728, 21732, 21736, + 21740, 21744, 21748, 21752, 21756, 21760, 21764, 21768, 21772, 21776, + 21780, 21784, 21788, 21792, 21796, 21800, 21804, 21808, 21812, 21816, + 21820, 21824, 21828, 21832, 21837, 21841, 21846, 21851, 21855, 21860, + 21865, 21869, 21873, 21877, 21881, 21885, 21889, 21893, 21897, 21901, + 21905, 21909, 21913, 21917, 21921, 21925, 21929, 21933, 21937, 21941, + 21945, 21949, 21953, 21957, 21961, 21965, 21969, 21973, 21977, 21981, + 21985, 21989, 21993, 21997, 22001, 22005, 22009, 22013, 22017, 22021, + 22025, 22029, 22033, 22037, 22041, 22045, 22049, 22053, 22057, 22061, + 22065, 22069, 22073, 22077, 22081, 22085, 22089, 22093, 22097, 22101, + 22105, 22109, 22113, 22117, 22121, 22125, 22129, 22133, 22137, 22141, + 22145, 22149, 22153, 22157, 22161, 22165, 22169, 22173, 22177, 22181, + 22185, 22189, 22193, 22197, 22201, 22205, 22209, 22213, 22217, 22221, + 22225, 22229, 22233, 22237, 22241, 22245, 22249, 22254, 22258, 22263, + 22267, 22272, 22277, 22281, 22286, 22291, 22295, 22300, 22305, 22310, + 22315, 22319, 22324, 22329, 22334, 22339, 22344, 22349, 22353, 22358, + 22363, 22368, 22373, 22378, 22383, 22388, 22393, 22398, 22403, 22408, + 22413, 22418, 22423, 22428, 22433, 22438, 22443, 22448, 22453, 22458, + 22463, 22468, 22473, 22478, 22483, 22488, 22493, 22498, 22503, 22508, + 22513, 22518, 22523, 22528, 22533, 22538, 22543, 22548, 22553, 22558, + 22563, 22568, 22573, 22578, 22583, 22588, 22593, 22598, 22603, 22607, + 22611, 22615, 22619, 22623, 22627, 22631, 22635, 22639, 22643, 22647, + 22651, 22655, 22659, 22663, 22667, 22671, 22675, 22679, 22683, 22687, + 22691, 22695, 22699, 22703, 22707, 22711, 22715, 22719, 22723, 22727, + 22731, 22735, 22739, 22743, 22747, 22751, 22755, 22759, 22763, 22767, + 22771, 22775, 22779, 22783, 22787, 22791, 22795, 22799, 22803, 22807, + 22811, 22815, 22819, 22823, 22827, 22831, 22835, 22839, 22843, 22847, + 22851, 22855, 22859, 22863, 22867, 22871, 22875, 22879, 22883, 22887, + 22891, 22895, 22899, 22903, 22907, 22911, 22915, 22919, 22923, 22927, + 22931, 22935, 22939, 22943, 22947, 22951, 22955, 22958, 22962, 22966, + 22970, 22974, 22978, 22982, 22986, 22989, 22993, 22997, 23001, 23005, + 23009, 23013, 23017, 23021, 23025, 23029, 23033, 23037, 23041, 23045, + 23049, 23052, 23056, 23060, 23064, 23068, 23072, 23076, 23080, 23084, + 23088, 23092, 23096, 23100, 23104, 23108, 23112, 23115, 23119, 23123, + 23127, 23131, 23135, 23139, 23143, 23146, 23150, 23154, 23158, 23162, + 23166, 23170, 23174, 23178, 23182, 23186, 23190, 23194, 23198, 23202, + 23206, 23210, 23214, 23218, 23222, 23226, 23230, 23234, 23238, 0, 23242, + 23246, 23250, 23254, 0, 0, 23258, 23262, 23266, 23270, 23274, 23278, + 23282, 0, 23286, 0, 23290, 23294, 23298, 23302, 0, 0, 23306, 23310, + 23314, 23318, 23322, 23326, 23330, 23334, 23338, 23342, 23346, 23350, + 23354, 23358, 23362, 23366, 23370, 23374, 23378, 23382, 23386, 23390, + 23394, 23397, 23401, 23405, 23409, 23413, 23417, 23421, 23425, 23429, + 23433, 23437, 23441, 23445, 23449, 23453, 23457, 23461, 23465, 0, 23469, + 23473, 23477, 23481, 0, 0, 23485, 23488, 23492, 23496, 23500, 23504, + 23508, 23512, 23516, 23520, 23524, 23528, 23532, 23536, 23540, 23544, + 23548, 23553, 23558, 23563, 23569, 23575, 23580, 23585, 23591, 23594, + 23598, 23602, 23606, 23610, 23614, 23618, 23622, 0, 23626, 23630, 23634, + 23638, 0, 0, 23642, 23646, 23650, 23654, 23658, 23662, 23666, 0, 23670, + 0, 23674, 23678, 23682, 23686, 0, 0, 23690, 23694, 23698, 23702, 23706, + 23710, 23714, 23718, 23722, 23727, 23732, 23737, 23743, 23749, 23754, 0, + 23759, 23763, 23767, 23771, 23775, 23779, 23783, 23787, 23791, 23795, + 23799, 23803, 23807, 23811, 23815, 23819, 23823, 23826, 23830, 23834, + 23838, 23842, 23846, 23850, 23854, 23858, 23862, 23866, 23870, 23874, + 23878, 23882, 23886, 23890, 23894, 23898, 23902, 23906, 23910, 23914, + 23918, 23922, 23926, 23930, 23934, 23938, 23942, 23946, 23950, 23954, + 23958, 23962, 23966, 23970, 23974, 23978, 23982, 0, 23986, 23990, 23994, + 23998, 0, 0, 24002, 24006, 24010, 24014, 24018, 24022, 24026, 24030, + 24034, 24038, 24042, 24046, 24050, 24054, 24058, 24062, 24066, 24070, + 24074, 24078, 24082, 24086, 24090, 24094, 24098, 24102, 24106, 24110, + 24114, 24118, 24122, 24126, 24130, 24134, 24138, 24142, 24146, 24150, + 24154, 24158, 24162, 24166, 24170, 24174, 24178, 24182, 24186, 24190, + 24194, 24198, 24202, 24206, 24210, 24214, 24218, 24222, 24226, 24229, + 24233, 24237, 24241, 24245, 24249, 24253, 24257, 24261, 24265, 0, 0, + 24269, 24278, 24284, 24289, 24293, 24296, 24301, 24304, 24307, 24310, + 24315, 24319, 24324, 24327, 24330, 24333, 24336, 24339, 24342, 24345, + 24348, 24351, 24355, 24359, 24363, 24367, 24371, 24375, 24379, 24383, + 24387, 24391, 0, 0, 0, 24396, 24402, 24406, 24410, 24414, 24420, 24424, + 24428, 24432, 24438, 24442, 24446, 24450, 24456, 24460, 24464, 24468, + 24474, 24480, 24486, 24494, 24500, 24506, 24512, 24518, 24524, 0, 0, 0, + 0, 0, 0, 24530, 24533, 24536, 24539, 24542, 24545, 24549, 24553, 24556, + 24560, 24564, 24568, 24572, 24576, 24579, 24583, 24587, 24591, 24595, + 24599, 24602, 24606, 24610, 24614, 24618, 24622, 24625, 24629, 24633, + 24637, 24641, 24644, 24648, 24652, 24656, 24660, 24664, 24668, 24672, + 24676, 24680, 24684, 24688, 24692, 24696, 24699, 24703, 24707, 24711, + 24715, 24719, 24723, 24727, 24731, 24735, 24739, 24743, 24747, 24751, + 24755, 24759, 24763, 24767, 24771, 24775, 24779, 24783, 24787, 24791, + 24795, 24799, 24803, 24807, 24811, 24815, 24819, 24823, 24827, 24831, + 24835, 24838, 24842, 24846, 24850, 24854, 24858, 0, 0, 24862, 24867, + 24872, 24877, 24882, 24887, 0, 0, 24892, 24896, 24899, 24903, 24906, + 24910, 24913, 24917, 24923, 24928, 24932, 24935, 24939, 24943, 24949, + 24953, 24959, 24963, 24969, 24973, 24979, 24983, 24989, 24995, 24999, + 25005, 25009, 25015, 25021, 25025, 25031, 25037, 25042, 25047, 25055, + 25063, 25070, 25075, 25081, 25090, 25096, 25104, 25109, 25115, 25119, + 25123, 25127, 25131, 25135, 25139, 25143, 25147, 25151, 25155, 25161, + 25166, 25171, 25174, 25178, 25182, 25188, 25192, 25198, 25202, 25208, + 25212, 25218, 25222, 25228, 25232, 25238, 25242, 25248, 25254, 25258, + 25264, 25269, 25273, 25277, 25281, 25285, 25288, 25292, 25298, 25303, + 25308, 25312, 25316, 25320, 25326, 25330, 25336, 25340, 25346, 25349, + 25354, 25358, 25364, 25368, 25374, 25378, 25384, 25390, 25394, 25398, + 25402, 25406, 25410, 25414, 25418, 25422, 25426, 25430, 25434, 25440, + 25443, 25447, 25451, 25457, 25461, 25467, 25471, 25477, 25481, 25487, + 25491, 25497, 25501, 25507, 25511, 25517, 25523, 25527, 25531, 25537, + 25543, 25549, 25555, 25559, 25563, 25567, 25571, 25575, 25579, 25585, + 25589, 25593, 25597, 25603, 25607, 25613, 25617, 25623, 25627, 25633, + 25637, 25643, 25647, 25653, 25657, 25663, 25669, 25673, 25679, 25683, + 25687, 25691, 25695, 25699, 25703, 25709, 25712, 25716, 25720, 25726, + 25730, 25736, 25740, 25746, 25750, 25756, 25760, 25766, 25770, 25776, + 25780, 25786, 25792, 25796, 25802, 25806, 25812, 25818, 25822, 25826, + 25830, 25834, 25838, 25842, 25848, 25851, 25855, 25859, 25865, 25869, + 25875, 25879, 25885, 25891, 25895, 25900, 25904, 25908, 25912, 25916, + 25920, 25924, 25928, 25934, 25937, 25941, 25945, 25951, 25955, 25961, + 25965, 25971, 25975, 25981, 25985, 25991, 25995, 26001, 26005, 26011, + 26014, 26019, 26024, 26028, 26032, 26036, 26040, 26044, 26048, 26054, + 26057, 26061, 26065, 26071, 26075, 26081, 26085, 26091, 26095, 26101, + 26105, 26111, 26115, 26121, 26125, 26131, 26137, 26141, 26147, 26151, + 26157, 26163, 26169, 26175, 26181, 26187, 26193, 26199, 26203, 26207, + 26211, 26215, 26219, 26223, 26227, 26231, 26237, 26241, 26247, 26251, + 26257, 26261, 26267, 26271, 26277, 26281, 26287, 26291, 26297, 26301, + 26305, 26309, 26313, 26317, 26321, 26325, 26331, 26334, 26338, 26342, + 26348, 26352, 26358, 26362, 26368, 26372, 26378, 26382, 26388, 26392, + 26398, 26402, 26408, 26414, 26418, 26424, 26430, 26436, 26440, 26446, + 26452, 26456, 26460, 26464, 26468, 26472, 26478, 26481, 26485, 26490, + 26494, 26500, 26503, 26508, 26513, 26517, 26521, 26525, 26529, 26533, + 26537, 26541, 26545, 26549, 26555, 26559, 26563, 26569, 26573, 26579, + 26583, 26589, 26593, 26597, 26601, 26605, 26609, 26615, 26619, 26623, + 26627, 26631, 26635, 26639, 26643, 26647, 26651, 26655, 26661, 26667, + 26673, 26679, 26685, 26690, 26696, 26702, 26708, 26712, 26716, 26720, + 26724, 26728, 26732, 26736, 26740, 26744, 26748, 26752, 26756, 26760, + 26766, 26772, 26778, 26783, 26787, 26791, 26795, 26799, 26803, 26807, + 26811, 26815, 26819, 26825, 26831, 26837, 26843, 26849, 26855, 26861, + 26867, 26873, 26877, 26881, 26885, 26889, 26893, 26897, 26901, 26907, + 26913, 26919, 26925, 26931, 26937, 26943, 26949, 26955, 26960, 26965, + 26970, 26975, 26981, 26987, 26993, 26999, 27005, 27011, 27017, 27022, + 27028, 27034, 27040, 27045, 27051, 27057, 27063, 27068, 27073, 27078, + 27083, 27088, 27093, 27098, 27103, 27108, 27113, 27118, 27123, 27127, + 27132, 27137, 27142, 27147, 27152, 27157, 27162, 27167, 27172, 27177, + 27182, 27187, 27192, 27197, 27202, 27207, 27212, 27217, 27222, 27227, + 27232, 27237, 27242, 27247, 27252, 27257, 27262, 27267, 27272, 27276, + 27281, 27286, 27291, 27296, 27301, 27306, 27311, 27316, 27321, 27326, + 27331, 27336, 27341, 27346, 27351, 27356, 27361, 27366, 27371, 27376, + 27381, 27386, 27391, 27396, 27401, 27405, 27410, 27415, 27420, 27425, + 27430, 27434, 27439, 27444, 27449, 27454, 27459, 27463, 27468, 27474, + 27479, 27484, 27489, 27494, 27500, 27505, 27510, 27515, 27520, 27525, + 27530, 27535, 27540, 27545, 27550, 27555, 27560, 27564, 27569, 27574, + 27579, 27584, 27589, 27594, 27599, 27604, 27609, 27614, 27619, 27624, + 27629, 27634, 27639, 27644, 27649, 27654, 27659, 27664, 27669, 27674, + 27679, 27684, 27689, 27694, 27699, 27704, 27709, 27714, 27719, 27725, + 27730, 27735, 27740, 27745, 27750, 27755, 27760, 27765, 27770, 27775, + 27780, 27784, 27789, 27794, 27799, 27804, 27809, 27814, 27819, 27824, + 27829, 27834, 27839, 27844, 27849, 27854, 27859, 27864, 27869, 27874, + 27879, 27884, 27889, 27894, 27899, 27904, 27909, 27914, 27920, 27924, + 27928, 27932, 27936, 27940, 27944, 27948, 27952, 27958, 27964, 27970, + 27976, 27982, 27988, 27994, 28001, 28007, 28012, 28017, 28022, 28027, + 28032, 28037, 28042, 28047, 28052, 28057, 28062, 28067, 28072, 28077, + 28082, 28087, 28092, 28097, 28102, 28107, 28112, 28117, 28122, 28127, + 28132, 28137, 28142, 28147, 0, 0, 0, 28154, 28165, 28170, 28178, 28183, + 28188, 28193, 28202, 28207, 28213, 28219, 28225, 28230, 28236, 28242, + 28246, 28251, 28256, 28266, 28271, 28276, 28283, 28288, 28293, 28302, + 28307, 28316, 28323, 28330, 28337, 28344, 28355, 28362, 28367, 28377, + 28381, 28388, 28393, 28400, 28406, 28413, 28422, 28429, 28436, 28445, + 28452, 28457, 28462, 28473, 28480, 28485, 28496, 28503, 28508, 28513, + 28521, 28530, 28537, 28544, 28554, 28559, 28564, 28569, 28578, 28586, + 28591, 28596, 28601, 28606, 28611, 28616, 28621, 28626, 28631, 28636, + 28641, 28647, 28653, 28659, 28664, 28669, 28674, 28679, 28684, 28689, + 28698, 28707, 28716, 28725, 0, 0, 0, 0, 0, 0, 0, 28734, 28738, 28742, + 28746, 28750, 28755, 28760, 28765, 28770, 28774, 28778, 28783, 28787, + 28791, 28795, 28799, 28804, 28808, 28812, 28817, 28822, 28827, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 28832, 28838, 28842, 28846, 28850, 28854, 28859, 28864, + 28869, 28874, 28878, 28882, 28887, 28891, 28895, 28899, 28903, 28908, + 28912, 28916, 28921, 28926, 28931, 28937, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 28942, 28946, 28950, 28954, 28958, 28963, 28968, 28973, 28978, 28982, + 28986, 28991, 28995, 28999, 29003, 29007, 29012, 29016, 29020, 29025, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29030, 29034, 29038, 29042, 29046, + 29051, 29056, 29061, 29066, 29070, 29074, 29079, 29083, 0, 29087, 29091, + 29096, 0, 29100, 29105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29110, 29113, + 29117, 29121, 29125, 29129, 29133, 29137, 29141, 29145, 29149, 29153, + 29157, 29161, 29165, 29169, 29173, 29177, 29180, 29184, 29188, 29192, + 29196, 29200, 29204, 29208, 29212, 29216, 29220, 29224, 29228, 29232, + 29235, 29238, 29241, 29245, 29251, 29257, 29263, 29269, 29275, 29281, + 29287, 29293, 29299, 29305, 29311, 29317, 29323, 29329, 29338, 29347, + 29353, 29359, 29365, 29370, 29374, 29379, 29384, 29389, 29393, 29398, + 29403, 29408, 29412, 29417, 29421, 29426, 29431, 29436, 29441, 29445, + 29449, 29453, 29457, 29461, 29465, 29469, 29473, 29477, 29481, 29487, + 29491, 29495, 29499, 29503, 29507, 29515, 29521, 29525, 29531, 29535, + 29541, 29545, 0, 0, 29549, 29553, 29556, 29559, 29562, 29565, 29568, + 29571, 29574, 29577, 0, 0, 0, 0, 0, 0, 29580, 29588, 29596, 29604, 29612, + 29620, 29628, 29636, 29644, 29652, 0, 0, 0, 0, 0, 0, 29660, 29663, 29666, + 29669, 29674, 29677, 29682, 29689, 29697, 29702, 29709, 29712, 29719, + 29726, 29733, 29737, 29744, 29748, 29751, 29754, 29757, 29760, 29763, + 29766, 29769, 29772, 0, 0, 0, 0, 0, 0, 29775, 29778, 29781, 29784, 29787, + 29790, 29794, 29798, 29802, 29805, 29809, 29813, 29816, 29820, 29824, + 29827, 29830, 29833, 29837, 29841, 29845, 29849, 29853, 29856, 29859, + 29863, 29867, 29870, 29874, 29878, 29882, 29886, 29890, 29894, 29898, + 29902, 29909, 29914, 29919, 29924, 29929, 29935, 29941, 29947, 29953, + 29958, 29964, 29970, 29975, 29981, 29987, 29993, 29999, 30005, 30010, + 30016, 30021, 30027, 30033, 30039, 30045, 30051, 30056, 30061, 30067, + 30073, 30078, 30084, 30089, 30095, 30100, 30105, 30111, 30117, 30123, + 30129, 30135, 30141, 30147, 30153, 30159, 30165, 30171, 30177, 30182, + 30187, 30192, 30198, 30204, 0, 0, 0, 0, 0, 0, 0, 30212, 30221, 30230, + 30238, 30246, 30256, 30264, 30273, 30280, 30287, 30294, 30302, 30310, + 30318, 30326, 30334, 30342, 30350, 30358, 30365, 30373, 30381, 30389, + 30397, 30405, 30415, 30425, 30435, 30445, 30455, 30465, 30475, 30485, + 30495, 30505, 30515, 30525, 30535, 30545, 30553, 30561, 30571, 30579, 0, + 0, 0, 0, 0, 30589, 30593, 30597, 30601, 30605, 30609, 30613, 30617, + 30621, 30625, 30629, 30633, 30637, 30641, 30645, 30649, 30653, 30657, + 30661, 30665, 30669, 30673, 30677, 30681, 30687, 30691, 30697, 30701, + 30707, 30711, 30717, 30721, 30725, 30729, 30733, 30737, 30741, 30747, + 30753, 30759, 30765, 30771, 30777, 30783, 30789, 30795, 30801, 30807, + 30814, 30820, 30826, 30832, 30836, 30840, 30844, 30848, 30852, 30856, + 30860, 30866, 30872, 30878, 30883, 30890, 30895, 30900, 30906, 30911, + 30918, 30925, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30932, 30938, 30942, 30947, + 30952, 30957, 30962, 30967, 30972, 30977, 30982, 30987, 30992, 30997, + 31002, 31007, 31011, 31015, 31020, 31025, 31030, 31034, 31038, 31042, + 31046, 31051, 31056, 31061, 31065, 31069, 31074, 0, 31079, 31084, 31089, + 31094, 31100, 31106, 31112, 31118, 31123, 31128, 31134, 31140, 0, 0, 0, + 0, 31147, 31152, 31158, 31164, 31170, 31175, 31180, 31185, 31190, 31195, + 31200, 31205, 0, 0, 0, 0, 31210, 0, 0, 0, 31215, 31220, 31225, 31230, + 31234, 31238, 31242, 31246, 31250, 31254, 31258, 31262, 31266, 31271, + 31277, 31283, 31289, 31294, 31299, 31305, 31311, 31316, 31321, 31327, + 31332, 31338, 31344, 31349, 31355, 31361, 31367, 31372, 31377, 31382, + 31388, 31394, 31399, 31405, 31410, 31416, 31421, 31427, 0, 0, 31433, + 31439, 31445, 31451, 31457, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31463, + 31472, 31481, 31489, 31498, 31507, 31515, 31524, 31533, 31542, 31550, + 31558, 31567, 31575, 31583, 31592, 31601, 31609, 31618, 31627, 31635, + 31643, 31652, 31660, 31668, 31677, 31685, 31694, 31703, 31711, 31720, + 31729, 31737, 31745, 31754, 31763, 31771, 31780, 31789, 31798, 31807, + 31816, 31825, 31834, 0, 0, 0, 0, 31843, 31853, 31862, 31871, 31879, + 31888, 31896, 31905, 31913, 31922, 31931, 31940, 31949, 31958, 31967, + 31976, 31985, 31994, 32003, 32012, 32021, 32030, 32039, 32048, 32057, + 32065, 0, 0, 0, 0, 0, 0, 32073, 32081, 32088, 32095, 32102, 32109, 32116, + 32123, 32130, 32137, 32144, 0, 0, 0, 32152, 32160, 32168, 32172, 32178, + 32184, 32190, 32196, 32202, 32208, 32214, 32220, 32226, 32232, 32238, + 32244, 32250, 32256, 32262, 32266, 32272, 32278, 32284, 32290, 32296, + 32302, 32308, 32314, 32320, 32326, 32332, 32338, 32344, 32350, 32356, + 32360, 32365, 32370, 32375, 32379, 32384, 32388, 32393, 32398, 32403, + 32407, 32412, 32417, 32422, 32427, 32432, 32436, 32440, 32444, 32449, + 32453, 32457, 32461, 32466, 32471, 32476, 32481, 0, 0, 32487, 32491, + 32498, 32503, 32509, 32515, 32520, 32526, 32532, 32537, 32543, 32549, + 32555, 32560, 32566, 32571, 32576, 32582, 32587, 32593, 32598, 32604, + 32610, 32616, 32622, 32626, 32631, 32636, 32642, 32648, 32653, 32659, + 32665, 32669, 32674, 32679, 32683, 32688, 32692, 32697, 32702, 32708, + 32714, 32719, 32724, 32729, 32733, 32738, 32742, 32747, 32751, 32756, + 32761, 32766, 32771, 32777, 32784, 32791, 32801, 32810, 32817, 32823, + 32834, 32839, 32845, 0, 32850, 32855, 32860, 32868, 32874, 32882, 32887, + 32893, 32899, 32905, 32910, 32916, 32921, 32928, 32934, 32939, 32945, + 32951, 32957, 32964, 32971, 32978, 32983, 32988, 32995, 33002, 33009, + 33016, 33023, 0, 0, 33030, 33037, 33044, 33050, 33056, 33062, 33068, + 33074, 33080, 33086, 33092, 0, 0, 0, 0, 0, 0, 33098, 33104, 33109, 33114, + 33119, 33124, 33129, 33134, 33139, 33144, 0, 0, 0, 0, 0, 0, 33149, 33154, + 33159, 33164, 33169, 33174, 33179, 33188, 33195, 33200, 33205, 33210, + 33215, 33220, 0, 0, 33225, 33232, 33235, 33238, 33242, 33247, 33251, + 33257, 33262, 33268, 33275, 33283, 33287, 33292, 33296, 33301, 33308, + 33316, 33323, 33329, 33337, 33344, 33349, 33353, 33360, 33364, 33369, + 33374, 33381, 33389, 33396, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 18787, 18792, 0, 18799, 0, 18806, 18813, 18818, 18823, 18830, 0, - 18837, 18844, 18849, 18856, 18863, 18870, 18877, 18884, 18891, 18896, - 18900, 18907, 18914, 18921, 18926, 18931, 18936, 18943, 18950, 18957, - 18964, 18971, 18976, 18981, 0, 18988, 0, 18995, 19000, 19007, 19014, - 19021, 19028, 19035, 19039, 19046, 19050, 19055, 19063, 19069, 19075, - 19080, 19086, 19092, 19098, 19103, 19109, 19116, 19124, 19131, 0, 0, - 19138, 19143, 19149, 19154, 19160, 0, 19166, 0, 19171, 19178, 19185, - 19192, 19199, 19204, 0, 0, 19208, 19213, 19217, 19221, 19225, 19229, - 19233, 19237, 19241, 19245, 0, 0, 19249, 19255, 19261, 19268, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33404, 33410, 33416, 33420, 33424, 33428, + 33432, 33438, 33442, 33448, 33452, 33458, 33464, 33472, 33478, 33486, + 33490, 33494, 33498, 33504, 33507, 33513, 33517, 33523, 33527, 33531, + 33537, 33541, 33547, 33551, 33557, 33565, 33573, 33581, 33587, 33591, + 33597, 33601, 33607, 33610, 33613, 33619, 33623, 33629, 33632, 33635, + 33638, 33641, 33645, 33651, 33657, 33660, 33663, 33667, 33672, 33677, + 33684, 33689, 33696, 33703, 33712, 33719, 33728, 33733, 33740, 33747, + 33756, 33761, 33768, 33773, 33779, 33785, 33791, 33797, 33803, 33809, + 33815, 0, 0, 0, 33821, 33825, 33828, 33831, 33834, 33837, 33840, 33843, + 33846, 33849, 33852, 33855, 33858, 33861, 33866, 33871, 33876, 33879, + 33884, 33889, 33894, 33899, 33906, 33911, 33916, 33921, 33926, 33933, + 33939, 33945, 33951, 33957, 33963, 33972, 33981, 33987, 33993, 34002, + 34011, 34020, 34029, 34038, 34047, 34056, 34065, 34074, 34079, 0, 34084, + 34089, 34094, 34099, 34103, 34107, 34111, 34116, 34120, 34124, 34129, + 34133, 34138, 34143, 34148, 34153, 34158, 34163, 34168, 34173, 34178, + 34182, 34186, 34191, 34196, 34201, 34205, 34209, 34213, 34217, 34222, + 34226, 34231, 34235, 34241, 34247, 34253, 34259, 34265, 34271, 34277, + 34283, 34289, 34294, 34299, 34306, 34314, 34319, 34324, 34329, 34333, + 34337, 34341, 34345, 34349, 34353, 34357, 34361, 34365, 34369, 34374, + 34379, 34384, 34390, 34396, 34400, 34406, 34410, 34416, 34422, 34427, + 34434, 34438, 34444, 34448, 34454, 34459, 34466, 34473, 34478, 34485, + 34490, 34495, 34499, 34505, 34509, 34515, 34522, 34529, 34533, 34539, + 34545, 34549, 34555, 34560, 34564, 34570, 34575, 34580, 34585, 34590, + 34594, 34598, 34603, 34608, 34615, 34621, 34626, 34633, 34638, 34645, + 34650, 34659, 34665, 34671, 34675, 0, 0, 0, 0, 0, 0, 0, 0, 34679, 34688, + 34695, 34702, 34709, 34713, 34718, 34723, 34728, 34733, 34738, 34743, + 34748, 34753, 34758, 34763, 34768, 34773, 34777, 34781, 34786, 34791, + 34796, 34801, 34806, 34811, 34815, 34820, 34825, 34830, 34835, 34839, + 34843, 34847, 34851, 34856, 34861, 34865, 34870, 34875, 34879, 34885, + 34891, 34897, 34902, 34907, 34913, 34918, 34924, 34929, 34935, 34941, + 34946, 34952, 34958, 34963, 34969, 34975, 34981, 34986, 0, 0, 0, 34991, + 34997, 35007, 35013, 35021, 35027, 35032, 35036, 35040, 35044, 35048, + 35052, 35056, 35060, 35064, 0, 0, 0, 35068, 35073, 35078, 35083, 35090, + 35096, 35102, 35108, 35114, 35120, 35126, 35132, 35138, 35144, 35150, + 35157, 35164, 35171, 35178, 35185, 35192, 35199, 35206, 35213, 35220, + 35227, 35234, 35241, 35248, 35255, 35262, 35269, 35276, 35283, 35290, + 35297, 35304, 35311, 35318, 35325, 35332, 35339, 35346, 35353, 35361, + 35369, 35377, 35383, 35389, 35395, 35403, 35412, 35419, 35426, 35432, + 35439, 35446, 35453, 35461, 35468, 0, 0, 0, 0, 0, 0, 0, 35475, 35482, + 35489, 35496, 35503, 35510, 35517, 35524, 35531, 35538, 35545, 35552, + 35559, 35566, 35573, 35580, 35587, 35594, 35601, 35608, 35615, 35622, + 35629, 35636, 35643, 35650, 35657, 35664, 35671, 35678, 35685, 35692, + 35699, 35706, 35713, 35720, 35727, 35734, 35741, 35748, 35755, 35762, + 35770, 0, 0, 35777, 35784, 35792, 35800, 35808, 35816, 35824, 35832, + 35842, 35852, 35862, 0, 0, 0, 0, 0, 0, 0, 0, 35872, 35877, 35882, 35887, + 35892, 35901, 35912, 35921, 35932, 35938, 35951, 35957, 35964, 35971, + 35976, 35982, 35988, 35999, 36008, 36015, 36022, 36031, 36038, 36047, + 36057, 36067, 36074, 36081, 36088, 36098, 36103, 36111, 36117, 36125, + 36134, 36139, 36146, 36152, 36157, 36162, 36167, 36173, 36180, 0, 0, 0, + 0, 0, 36188, 36193, 36199, 36205, 36213, 36219, 36225, 36231, 36236, + 36243, 36248, 36254, 36260, 36268, 36274, 36282, 36287, 36294, 36300, + 36308, 36316, 36322, 36328, 36335, 36342, 36348, 36355, 36361, 36367, + 36372, 36378, 36386, 36394, 36400, 36406, 36412, 36418, 36426, 36430, + 36436, 36442, 36448, 36454, 36460, 36466, 36470, 36475, 36480, 36487, + 36492, 36496, 36502, 36507, 36512, 36516, 36521, 36526, 36530, 36535, + 36540, 36547, 36551, 36556, 36561, 36565, 36570, 36574, 36579, 36583, + 36588, 36593, 36599, 36604, 36609, 36613, 36618, 36624, 36631, 36636, + 36641, 36646, 36651, 36656, 36660, 36666, 36673, 36680, 36685, 36690, + 36694, 36700, 36706, 36711, 36716, 36721, 36727, 36732, 36738, 36743, + 36749, 36755, 36761, 36768, 36775, 36782, 36789, 36796, 36803, 36808, + 36816, 36825, 36834, 36843, 36852, 36861, 36870, 36882, 36891, 36900, + 36909, 36915, 36920, 36927, 36935, 36943, 36950, 36957, 36964, 36971, + 36979, 36988, 36997, 37006, 37015, 37024, 37033, 37042, 37051, 37060, + 37069, 37078, 37087, 37096, 37105, 37113, 37122, 37133, 37142, 37153, + 37166, 37175, 37184, 37194, 37203, 37211, 37220, 37226, 37231, 37239, + 37244, 37252, 37257, 37266, 37272, 37278, 37285, 37290, 37295, 37303, + 37311, 37320, 37329, 37334, 37341, 37351, 37359, 37368, 37374, 37380, + 37385, 37392, 37397, 37406, 37411, 37416, 37421, 37428, 37434, 37439, + 37448, 37456, 37461, 37466, 37473, 37480, 37484, 37488, 37491, 37494, + 37497, 37500, 37503, 37506, 37513, 37516, 37519, 37524, 37528, 37532, + 37536, 37540, 37544, 37554, 37560, 37566, 37572, 37580, 37588, 37594, + 37600, 37607, 37613, 37618, 37624, 37631, 37637, 37644, 37650, 37658, + 37664, 37671, 37677, 37683, 37689, 37695, 37701, 37707, 37718, 37728, + 37734, 37740, 37750, 37756, 37764, 37772, 37780, 37785, 37790, 37796, + 37801, 37809, 37815, 37819, 37826, 37833, 37838, 37847, 37855, 37863, + 37870, 37877, 37884, 37891, 37899, 37907, 37918, 37929, 37937, 37945, + 37953, 37961, 37970, 37979, 37987, 37995, 38004, 38013, 38024, 38035, + 38046, 38057, 38066, 38075, 38084, 38093, 38104, 38115, 38123, 38131, + 38139, 38147, 38155, 38163, 38171, 38179, 38187, 38195, 38203, 38211, + 38220, 38229, 38238, 38247, 38258, 38269, 38277, 38285, 38293, 38301, + 38310, 38319, 38327, 38335, 38347, 38359, 38368, 38377, 38386, 38395, + 38403, 38411, 38419, 38427, 38435, 38443, 38451, 38459, 38467, 38475, + 38484, 38493, 38502, 38511, 38521, 38531, 38541, 38551, 38561, 38571, + 38581, 38591, 38599, 38607, 38615, 38623, 38631, 38639, 38647, 38655, + 38667, 38679, 38688, 38697, 38705, 38713, 38721, 38729, 38740, 38751, + 38762, 38773, 38785, 38797, 38805, 38813, 38821, 38829, 38838, 38847, + 38856, 38865, 38873, 38881, 38889, 38897, 38905, 38913, 38923, 38933, + 38943, 38953, 38961, 38969, 38977, 38985, 38993, 39001, 39009, 39017, + 39025, 39033, 39041, 39049, 39057, 39065, 39073, 39081, 39089, 39097, + 39105, 39113, 39121, 39129, 39137, 39145, 39154, 39163, 39172, 39180, + 39189, 39198, 39207, 39216, 39226, 39235, 39242, 39247, 39254, 39261, + 39269, 39277, 39287, 39297, 39307, 39317, 39328, 39339, 39349, 39359, + 39369, 39379, 39389, 39399, 39409, 39419, 39430, 39441, 39451, 39461, + 39471, 39481, 39489, 39497, 39506, 39515, 39523, 39531, 39542, 39553, + 39564, 39575, 39587, 39599, 39610, 39621, 39632, 39643, 39652, 39661, + 39669, 39677, 39684, 39691, 39699, 39707, 39717, 39727, 39737, 39747, + 39758, 39769, 39779, 39789, 39799, 39809, 39819, 39829, 39839, 39849, + 39860, 39871, 39881, 39891, 39901, 39911, 39918, 39925, 39933, 39941, + 39951, 39961, 39971, 39981, 39992, 40003, 40013, 40023, 40033, 40043, + 40051, 40059, 40067, 40075, 40084, 40093, 40101, 40109, 40116, 40123, + 40130, 40137, 40145, 40153, 40161, 40169, 40180, 40191, 40202, 40213, + 40224, 40235, 40243, 40251, 40262, 40273, 40284, 40295, 40306, 40317, + 40325, 40333, 40344, 40355, 40366, 0, 0, 40377, 40385, 40393, 40404, + 40415, 40426, 0, 0, 40437, 40445, 40453, 40464, 40475, 40486, 40497, + 40508, 40519, 40527, 40535, 40546, 40557, 40568, 40579, 40590, 40601, + 40609, 40617, 40628, 40639, 40650, 40661, 40672, 40683, 40691, 40699, + 40710, 40721, 40732, 40743, 40754, 40765, 40773, 40781, 40792, 40803, + 40814, 0, 0, 40825, 40833, 40841, 40852, 40863, 40874, 0, 0, 40885, + 40893, 40901, 40912, 40923, 40934, 40945, 40956, 0, 40967, 0, 40975, 0, + 40986, 0, 40997, 41008, 41016, 41024, 41035, 41046, 41057, 41068, 41079, + 41090, 41098, 41106, 41117, 41128, 41139, 41150, 41161, 41172, 41180, + 41188, 41196, 41204, 41212, 41220, 41228, 41236, 41244, 41252, 41260, + 41268, 41276, 0, 0, 41284, 41295, 41306, 41320, 41334, 41348, 41362, + 41376, 41390, 41401, 41412, 41426, 41440, 41454, 41468, 41482, 41496, + 41507, 41518, 41532, 41546, 41560, 41574, 41588, 41602, 41613, 41624, + 41638, 41652, 41666, 41680, 41694, 41708, 41719, 41730, 41744, 41758, + 41772, 41786, 41800, 41814, 41825, 41836, 41850, 41864, 41878, 41892, + 41906, 41920, 41928, 41936, 41947, 41955, 0, 41966, 41974, 41985, 41993, + 42001, 42009, 42017, 42025, 42028, 42031, 42034, 42037, 42043, 42054, + 42062, 0, 42073, 42081, 42092, 42100, 42108, 42116, 42124, 42132, 42138, + 42144, 42150, 42158, 42166, 42177, 0, 0, 42188, 42196, 42207, 42215, + 42223, 42231, 0, 42239, 42245, 42251, 42257, 42265, 42273, 42284, 42295, + 42303, 42311, 42319, 42330, 42338, 42346, 42354, 42362, 42370, 42376, + 42382, 0, 0, 42385, 42396, 42404, 0, 42415, 42423, 42434, 42442, 42450, + 42458, 42466, 42474, 42477, 0, 42480, 42484, 42488, 42492, 42496, 42500, + 42504, 42508, 42512, 42516, 42520, 42524, 42530, 42536, 42542, 42545, + 42548, 42550, 42554, 42558, 42562, 42566, 42569, 42573, 42577, 42583, + 42589, 42596, 42603, 42608, 42613, 42619, 42625, 42627, 42630, 42632, + 42636, 42640, 42644, 42648, 42652, 42656, 42660, 42664, 42668, 42674, + 42678, 42682, 42688, 42693, 42700, 42702, 42705, 42709, 42713, 42718, + 42724, 42726, 42735, 42744, 42747, 42751, 42753, 42755, 42757, 42761, + 42767, 42769, 42773, 42777, 42784, 42791, 42795, 42800, 42805, 42810, + 42815, 42819, 42823, 42826, 42830, 42834, 42841, 42846, 42850, 42854, + 42859, 42863, 42867, 42872, 42877, 42881, 42885, 42889, 42891, 42896, + 42901, 42905, 42909, 42913, 42917, 0, 42921, 42925, 42929, 42935, 42941, + 42947, 42953, 42960, 42967, 42972, 42977, 42981, 0, 0, 42987, 42990, + 42993, 42996, 42999, 43002, 43005, 43009, 43013, 43018, 43023, 43028, + 43035, 43039, 43042, 43045, 43048, 43051, 43054, 43057, 43060, 43063, + 43066, 43070, 43074, 43079, 43084, 0, 43089, 43095, 43101, 43107, 43114, + 43121, 43128, 43135, 43141, 43148, 43155, 43162, 43169, 0, 0, 0, 43176, + 43179, 43182, 43185, 43190, 43193, 43196, 43199, 43202, 43205, 43208, + 43213, 43216, 43219, 43222, 43225, 43228, 43233, 43236, 43239, 43242, + 43245, 43248, 43253, 43256, 43259, 43264, 43269, 43273, 43276, 43279, + 43282, 43285, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43288, 43293, + 43298, 43305, 43313, 43318, 43323, 43327, 43331, 43336, 43343, 43350, + 43354, 43359, 43364, 43369, 43374, 43381, 43386, 43391, 43396, 43405, + 43412, 43419, 43423, 43428, 43434, 43439, 43446, 43454, 43462, 43466, + 43470, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43474, 43478, 43485, + 43490, 43494, 43499, 43503, 43507, 43511, 43513, 43517, 43521, 43525, + 43530, 43535, 43539, 43547, 43550, 43554, 43557, 43560, 43566, 43571, + 43574, 43580, 43584, 43589, 43594, 43597, 43601, 43605, 43609, 43611, + 43614, 43617, 43621, 43623, 43628, 43631, 43634, 43639, 43644, 43650, + 43653, 43656, 43660, 43665, 43668, 43671, 43674, 43678, 43682, 43686, + 43689, 43691, 43694, 43697, 43700, 43704, 43709, 43712, 43717, 43722, + 43727, 43732, 43738, 43743, 43747, 43752, 43757, 43763, 43769, 43774, + 43779, 43785, 43789, 43792, 43795, 43797, 43801, 43807, 43814, 43821, + 43828, 43835, 43842, 43849, 43856, 43863, 43871, 43878, 43886, 43893, + 43900, 43908, 43916, 43921, 43926, 43931, 43936, 43941, 43946, 43951, + 43956, 43961, 43966, 43972, 43978, 43984, 43990, 43997, 44005, 44011, + 44017, 44023, 44029, 44035, 44041, 44047, 44053, 44059, 44065, 44072, + 44079, 44086, 44093, 44101, 44110, 44117, 44128, 44135, 44142, 44151, + 44158, 44167, 44176, 44183, 44191, 44199, 44202, 0, 0, 0, 0, 44205, + 44207, 44210, 44212, 44215, 44218, 44221, 44225, 44229, 44234, 44239, + 44243, 44247, 44251, 44255, 44260, 44266, 44271, 44277, 44282, 44287, + 44292, 44298, 44303, 44309, 44315, 44319, 44323, 44328, 44333, 44338, + 44343, 44348, 44356, 44364, 44372, 44380, 44387, 44395, 44402, 44409, + 44416, 44426, 44433, 44440, 44447, 44454, 44462, 44470, 44477, 44484, + 44492, 44500, 44505, 44513, 44518, 44523, 44529, 44534, 44540, 44547, + 44554, 44559, 44565, 44570, 44573, 44577, 44580, 44584, 44588, 44592, + 44597, 44602, 44608, 44614, 44618, 44622, 44626, 44630, 44636, 44642, + 44646, 44651, 44655, 44660, 44664, 44668, 44671, 44675, 44678, 44682, + 44689, 44697, 44709, 44720, 44725, 44734, 44741, 44748, 44756, 44760, + 44766, 44774, 44778, 44783, 44788, 44794, 44800, 44806, 44813, 44817, + 44821, 44826, 44829, 44831, 44835, 44839, 44847, 44851, 44853, 44855, + 44859, 44867, 44872, 44878, 44888, 44895, 44900, 44904, 44908, 44912, + 44915, 44918, 44921, 44925, 44929, 44933, 44937, 44941, 44944, 44948, + 44952, 44955, 44957, 44960, 44962, 44966, 44970, 44972, 44978, 44981, + 44986, 44990, 44994, 44996, 44998, 45000, 45003, 45007, 45011, 45015, + 45019, 45023, 45029, 45035, 45037, 45039, 45041, 45043, 45046, 45048, + 45052, 45054, 45058, 45062, 45068, 45072, 45076, 45080, 45084, 45089, + 45096, 45101, 45112, 45123, 45128, 45135, 45144, 45148, 45153, 45156, + 45161, 45165, 45171, 45176, 45189, 45199, 45203, 45207, 45214, 45219, + 45222, 45224, 45227, 45231, 45236, 45243, 45247, 45252, 45257, 45260, + 45265, 45270, 45277, 45284, 45290, 45296, 45305, 45314, 45318, 45322, + 45324, 45329, 45333, 45337, 45346, 45355, 45362, 45369, 45378, 45387, + 45393, 45399, 45407, 45415, 45417, 45419, 45426, 45433, 45440, 45447, + 45453, 45459, 45463, 45467, 45474, 45481, 45489, 45497, 45508, 45519, + 45528, 45537, 45539, 45543, 45547, 45552, 45557, 45566, 45575, 45578, + 45581, 45584, 45587, 45590, 45595, 45599, 45604, 45609, 45612, 45615, + 45618, 45621, 45624, 45628, 45631, 45634, 45637, 45640, 45642, 45644, + 45646, 45648, 45656, 45664, 45670, 45674, 45680, 45690, 45696, 45702, + 45708, 45716, 45726, 45739, 45743, 45747, 45749, 45755, 45757, 45759, + 45761, 45763, 45769, 45772, 45778, 45784, 45788, 45792, 45796, 45799, + 45803, 45807, 45809, 45818, 45827, 45832, 45837, 45843, 45849, 45855, + 45858, 45861, 45864, 45867, 45869, 45875, 45880, 45885, 45891, 45897, + 45906, 45915, 45922, 45929, 45936, 45943, 45953, 45963, 45974, 45985, + 45996, 46007, 46016, 46025, 46034, 46043, 46051, 46063, 46075, 46091, + 46094, 46100, 46106, 46112, 46120, 46135, 46151, 46157, 46163, 46170, + 46176, 46185, 46192, 46206, 46221, 46226, 46232, 46240, 46243, 46246, + 46248, 46251, 46254, 46256, 46258, 46262, 46265, 46268, 46271, 46274, + 46279, 46284, 46289, 46294, 46299, 46302, 46304, 46306, 46308, 46312, + 46316, 46320, 46326, 46330, 46332, 46334, 46339, 46344, 46349, 46354, + 46359, 46364, 46366, 46368, 46378, 46382, 46388, 46397, 46399, 46405, + 46411, 46418, 46422, 46424, 46428, 46430, 46434, 46438, 46442, 46444, + 46446, 46448, 46455, 46464, 46473, 46482, 46491, 46500, 46509, 46518, + 46527, 46535, 46543, 46552, 46561, 46570, 46579, 46587, 46595, 46604, + 46613, 46622, 46632, 46641, 46651, 46660, 46670, 46679, 46689, 46699, + 46708, 46718, 46727, 46737, 46746, 46756, 46765, 46774, 46783, 46792, + 46801, 46811, 46820, 46829, 46838, 46848, 46857, 46866, 46875, 46884, + 46894, 46904, 46913, 46922, 46930, 46939, 46946, 46955, 46964, 46975, + 46984, 46994, 47004, 47011, 47018, 47025, 47034, 47043, 47052, 47061, + 47068, 47073, 47082, 47088, 47091, 47098, 47101, 47106, 47111, 47114, + 47117, 47125, 47128, 47133, 47136, 47144, 47149, 47157, 47160, 47163, + 47166, 47171, 47176, 47179, 47182, 47190, 47193, 47200, 47207, 47211, + 47215, 47220, 47225, 47230, 47235, 47240, 47245, 47250, 47255, 47262, + 47268, 47275, 47282, 47288, 47295, 47302, 47310, 47317, 47323, 47330, + 47338, 47345, 47349, 47355, 47367, 47379, 47383, 47387, 47392, 47397, + 47408, 47412, 47417, 47422, 47428, 47434, 47440, 47446, 47455, 47464, + 47472, 47483, 47494, 47502, 47513, 47524, 47532, 47543, 47554, 47562, + 47570, 47580, 47590, 47593, 47596, 47599, 47604, 47608, 47614, 47621, + 47628, 47636, 47643, 47647, 47651, 47655, 47659, 47661, 47665, 47669, + 47675, 47681, 47689, 47697, 47700, 47707, 47709, 47711, 47715, 47719, + 47724, 47730, 47736, 47742, 47748, 47757, 47766, 47775, 47779, 47781, + 47785, 47792, 47799, 47806, 47813, 47820, 47823, 47828, 47834, 47837, + 47842, 47847, 47852, 47857, 47861, 47868, 47875, 47882, 47889, 47893, + 47897, 47901, 47905, 47911, 47917, 47922, 47928, 47934, 47940, 47946, + 47954, 47961, 47968, 47975, 47982, 47988, 47994, 48003, 48007, 48014, + 48018, 48022, 48028, 48034, 48040, 48046, 48050, 48054, 48057, 48061, + 48065, 48072, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 48079, 48082, 48086, 48090, 48096, 48102, 48108, 48116, + 48123, 48127, 48135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 48140, 48143, 48146, 48149, 48152, 48155, 48158, 48161, + 48164, 48167, 48171, 48175, 48179, 48183, 48187, 48191, 48195, 48199, + 48203, 48207, 48211, 48214, 48217, 48220, 48223, 48226, 48229, 48232, + 48235, 48238, 48242, 48246, 48250, 48254, 48258, 48262, 48266, 48270, + 48274, 48278, 48282, 48288, 48294, 48300, 48307, 48314, 48321, 48328, + 48335, 48342, 48349, 48356, 48363, 48370, 48377, 48384, 48391, 48398, + 48405, 48412, 48419, 48424, 48430, 48436, 48442, 48447, 48453, 48459, + 48465, 48470, 48476, 48482, 48487, 48493, 48499, 48504, 48510, 48516, + 48521, 48527, 48533, 48538, 48544, 48550, 48556, 48562, 48568, 48573, + 48579, 48585, 48591, 48596, 48602, 48608, 48614, 48619, 48625, 48631, + 48636, 48642, 48648, 48653, 48659, 48665, 48670, 48676, 48682, 48687, + 48693, 48699, 48705, 48711, 48717, 48722, 48728, 48734, 48740, 48745, + 48751, 48757, 48763, 48768, 48774, 48780, 48785, 48791, 48797, 48802, + 48808, 48814, 48819, 48825, 48831, 48836, 48842, 48848, 48854, 48860, + 48866, 48870, 48876, 48882, 48888, 48894, 48900, 48906, 48912, 48918, + 48924, 48930, 48934, 48938, 48942, 48946, 48950, 48954, 48958, 48962, + 48966, 48971, 48977, 48982, 48987, 48992, 48997, 49006, 49015, 49024, + 49033, 49042, 49051, 49060, 49069, 49075, 49083, 49091, 49097, 49104, + 49112, 49120, 49127, 49133, 49141, 49149, 49155, 49162, 49170, 49178, + 49185, 49191, 49199, 49208, 49217, 49225, 49234, 49243, 49249, 49256, + 49264, 49273, 49282, 49290, 49299, 49308, 49315, 49322, 49331, 49340, + 49349, 49358, 49367, 49376, 49383, 49390, 49399, 49408, 49417, 49426, + 49435, 49444, 49451, 49458, 49467, 49476, 49485, 49495, 49505, 49514, + 49524, 49534, 49544, 49554, 49564, 49574, 49583, 49592, 49599, 49607, + 49615, 49623, 49631, 49636, 49641, 49650, 49658, 49664, 49673, 49681, + 49688, 49697, 49705, 49711, 49720, 49728, 49735, 49744, 49752, 49758, + 49767, 49775, 49782, 49792, 49801, 49808, 49818, 49827, 49834, 49844, + 49853, 49860, 49868, 49877, 49886, 49894, 49905, 49915, 49922, 49927, + 49932, 49936, 49941, 49946, 49951, 49955, 49960, 49967, 49975, 49982, + 49990, 49994, 50000, 50006, 50012, 50016, 50023, 50029, 50036, 50040, + 50047, 50053, 50060, 50064, 50070, 50076, 50082, 50086, 50089, 50093, + 50097, 50103, 50109, 50114, 50118, 50123, 50133, 50140, 50151, 50161, + 50165, 50173, 50183, 50186, 50189, 50196, 50204, 50210, 50215, 50223, + 50232, 50241, 50249, 50253, 50257, 50260, 50263, 50267, 50271, 50274, + 50277, 50282, 50287, 50293, 50299, 50304, 50309, 50315, 50321, 50326, + 50331, 50336, 50341, 50347, 50353, 50358, 50363, 50369, 50375, 50380, + 50385, 50388, 50391, 50400, 50402, 50404, 50407, 50411, 50417, 50419, + 50422, 50429, 50436, 50443, 50450, 50459, 50472, 50477, 50482, 50486, + 50491, 50498, 50505, 50513, 50521, 50529, 50537, 50541, 50545, 50550, + 50555, 50560, 50565, 50568, 50574, 50580, 50589, 50598, 50606, 50614, + 50623, 50632, 50636, 50643, 50650, 50657, 50664, 50672, 50680, 50688, + 50696, 50700, 50704, 50708, 50713, 50718, 50724, 50730, 50734, 50740, + 50742, 50744, 50746, 50748, 50751, 50754, 50756, 50758, 50760, 50764, + 50768, 50770, 50772, 50775, 50778, 50782, 50788, 50794, 50796, 50803, + 50807, 50812, 50817, 50819, 50829, 50835, 50841, 50847, 50853, 50859, + 50865, 50870, 50873, 50876, 50879, 50881, 50883, 50887, 50891, 50896, + 50901, 50906, 50909, 50913, 50918, 50921, 50925, 50930, 50935, 50940, + 50945, 50950, 50955, 50960, 50965, 50970, 50975, 50980, 50985, 50991, + 50997, 51003, 51005, 51008, 51010, 51013, 51015, 51017, 51019, 51021, + 51023, 51025, 51027, 51029, 51031, 51033, 51035, 51037, 51039, 51041, + 51043, 51045, 51047, 51052, 51057, 51062, 51067, 51072, 51077, 51082, + 51087, 51092, 51097, 51102, 51107, 51112, 51117, 51122, 51127, 51132, + 51137, 51142, 51147, 51151, 51155, 51159, 51165, 51171, 51176, 51181, + 51186, 51192, 51198, 51203, 51211, 51219, 51227, 51235, 51243, 51251, + 51259, 51267, 51273, 51278, 51283, 51288, 51291, 51295, 51299, 51303, + 51307, 51311, 51315, 51321, 51328, 51335, 51343, 51348, 51353, 51360, + 51367, 51374, 51381, 51384, 51387, 51392, 51394, 51398, 51403, 51405, + 51407, 51409, 51411, 51416, 51419, 51421, 51426, 51432, 51439, 51442, + 51446, 51451, 51456, 51464, 51470, 51476, 51488, 51495, 51503, 51508, + 51513, 51519, 51522, 51525, 51530, 51532, 51536, 51538, 51540, 51542, + 51544, 51546, 51548, 51553, 51555, 51557, 51559, 51561, 51565, 51567, + 51570, 51575, 51580, 51585, 51590, 51596, 51602, 51604, 51607, 51614, + 51620, 51626, 51633, 51637, 51641, 51643, 51645, 51649, 51655, 51660, + 51662, 51666, 51675, 51683, 51691, 51697, 51703, 51708, 51714, 51719, + 51722, 51736, 51739, 51744, 51749, 51755, 51765, 51767, 51773, 51779, + 51783, 51790, 51794, 51796, 51798, 51802, 51808, 51813, 51819, 51821, + 51827, 51829, 51835, 51837, 51839, 51844, 51846, 51850, 51855, 51857, + 51862, 51867, 51871, 51878, 51888, 51893, 51898, 51901, 51906, 51909, + 51914, 51919, 51923, 51925, 51927, 51931, 51935, 51939, 51943, 51947, + 51949, 51953, 51956, 51959, 51962, 51966, 51970, 51975, 51979, 51984, + 51989, 51993, 51999, 52006, 52009, 52015, 52020, 52024, 52029, 52035, + 52041, 52048, 52054, 52061, 52068, 52070, 52077, 52081, 52088, 52094, + 52099, 52105, 52109, 52114, 52117, 52123, 52129, 52136, 52144, 52151, + 52160, 52170, 52177, 52183, 52187, 52195, 52200, 52209, 52212, 52215, + 52224, 52235, 52242, 52244, 52250, 52255, 52257, 52260, 52264, 52272, + 52281, 52284, 52289, 52295, 52302, 52309, 52316, 52323, 52329, 52335, + 52341, 52349, 52354, 52357, 52361, 52364, 52375, 52385, 52395, 52404, + 52415, 52425, 52434, 52440, 52448, 52452, 52460, 52464, 52472, 52479, + 52486, 52495, 52504, 52514, 52524, 52534, 52544, 52553, 52562, 52572, + 52582, 52591, 52600, 52607, 52614, 52621, 52628, 52635, 52642, 52649, + 52656, 52663, 52671, 52677, 52683, 52689, 52695, 52701, 52707, 52713, + 52719, 52725, 52732, 52740, 52748, 52756, 52764, 52772, 52780, 52788, + 52796, 52804, 52813, 52818, 52821, 52825, 52829, 52835, 52838, 52843, + 52849, 52854, 52858, 52863, 52869, 52876, 52879, 52886, 52893, 52897, + 52906, 52915, 52920, 52926, 52931, 52936, 52943, 52950, 52957, 52964, + 52972, 52976, 52984, 52989, 52993, 53000, 53004, 53010, 53018, 53023, + 53030, 53034, 53039, 53043, 53048, 53052, 53057, 53062, 53071, 53073, + 53077, 53081, 53088, 53095, 53101, 53109, 53115, 53122, 53127, 53130, + 53135, 53140, 53145, 53153, 53157, 53164, 53171, 53178, 53183, 53188, + 53194, 53199, 53204, 53210, 53215, 53218, 53222, 53226, 53233, 53243, + 53248, 53257, 53266, 53272, 53278, 53284, 53290, 53296, 53302, 53309, + 53316, 53325, 53334, 53340, 53346, 53351, 53356, 53363, 53370, 53376, + 53379, 53382, 53386, 53390, 53394, 53399, 53405, 53411, 53418, 53425, + 53430, 53434, 53438, 53442, 53446, 53450, 53454, 53458, 53462, 53466, + 53470, 53474, 53478, 53482, 53486, 53490, 53494, 53498, 53502, 53506, + 53510, 53514, 53518, 53522, 53526, 53530, 53534, 53538, 53542, 53546, + 53550, 53554, 53558, 53562, 53566, 53570, 53574, 53578, 53582, 53586, + 53590, 53594, 53598, 53602, 53606, 53610, 53614, 53618, 53622, 53626, + 53630, 53634, 53638, 53642, 53646, 53650, 53654, 53658, 53662, 53666, + 53670, 53674, 53678, 53682, 53686, 53690, 53694, 53698, 53702, 53706, + 53710, 53714, 53718, 53722, 53726, 53730, 53734, 53738, 53742, 53746, + 53750, 53754, 53758, 53762, 53766, 53770, 53774, 53778, 53782, 53786, + 53790, 53794, 53798, 53802, 53806, 53810, 53814, 53818, 53822, 53826, + 53830, 53834, 53838, 53842, 53846, 53850, 53854, 53858, 53862, 53866, + 53870, 53874, 53878, 53882, 53886, 53890, 53894, 53898, 53902, 53906, + 53910, 53914, 53918, 53922, 53926, 53930, 53934, 53938, 53942, 53946, + 53950, 53954, 53958, 53962, 53966, 53970, 53974, 53978, 53982, 53986, + 53990, 53994, 53998, 54002, 54006, 54010, 54014, 54018, 54022, 54026, + 54030, 54034, 54038, 54042, 54046, 54050, 54054, 54058, 54062, 54066, + 54070, 54074, 54078, 54082, 54086, 54090, 54094, 54098, 54102, 54106, + 54110, 54114, 54118, 54122, 54126, 54130, 54134, 54138, 54142, 54146, + 54150, 54154, 54158, 54162, 54166, 54170, 54174, 54178, 54182, 54186, + 54190, 54194, 54198, 54202, 54206, 54210, 54214, 54218, 54222, 54226, + 54230, 54234, 54238, 54242, 54246, 54250, 54254, 54258, 54262, 54266, + 54270, 54274, 54278, 54282, 54286, 54290, 54294, 54298, 54302, 54306, + 54310, 54314, 54318, 54322, 54326, 54330, 54334, 54338, 54342, 54346, + 54350, 54354, 54358, 54362, 54366, 54370, 54374, 54378, 54382, 54386, + 54390, 54394, 54398, 54402, 54406, 54410, 54414, 54418, 54422, 54426, + 54430, 54434, 54438, 54442, 54446, 54450, 54454, 54461, 54469, 54475, + 54481, 54488, 54495, 54501, 54507, 54514, 54521, 54526, 54531, 54536, + 54541, 54547, 54553, 54561, 54568, 54573, 54578, 54586, 54595, 54602, + 54612, 54623, 54626, 54629, 54633, 54637, 54643, 54649, 54659, 54669, + 54678, 54687, 54693, 54699, 54706, 54713, 54722, 54732, 54743, 54753, + 54763, 54773, 54784, 54795, 54805, 54816, 54826, 54836, 54844, 54854, + 54864, 54875, 54886, 54893, 54900, 54907, 54914, 54924, 54934, 54941, + 54948, 54955, 54962, 54969, 54976, 54983, 54988, 54993, 54999, 55007, + 55017, 55025, 55033, 55041, 55049, 55057, 55065, 55073, 55081, 55089, + 55097, 55106, 55115, 55123, 55131, 55140, 55149, 55158, 55167, 55177, + 55187, 55196, 55205, 55215, 55225, 55239, 55255, 55269, 55285, 55299, + 55313, 55327, 55341, 55351, 55362, 55372, 55383, 55399, 55415, 55423, + 55429, 55436, 55443, 55450, 55458, 55463, 55469, 55474, 55479, 55485, + 55490, 55495, 55500, 55505, 55510, 55517, 55523, 55531, 55537, 55543, + 55547, 55551, 55560, 55569, 55578, 55587, 55594, 55601, 55614, 55627, + 55640, 55653, 55661, 55669, 55676, 55683, 55691, 55699, 55707, 55715, + 55719, 55724, 55732, 55740, 55748, 55755, 55759, 55767, 55775, 55778, + 55782, 55787, 55794, 55802, 55810, 55829, 55849, 55868, 55888, 55908, + 55928, 55948, 55968, 55974, 55981, 55990, 55998, 56006, 56012, 56015, + 56018, 56023, 56026, 56046, 56053, 56059, 56065, 56069, 56072, 56075, + 56078, 56088, 56100, 56107, 56114, 56117, 56121, 56124, 56129, 56134, + 56139, 56145, 56154, 56161, 56168, 56176, 56183, 56190, 56193, 56199, + 56205, 56208, 56211, 56216, 56221, 56227, 56233, 56237, 56242, 56249, + 56253, 56259, 56263, 56267, 56275, 56287, 56295, 56299, 56301, 56310, + 56319, 56325, 56328, 56334, 56340, 56345, 56350, 56355, 56360, 56365, + 56370, 56372, 56378, 56383, 56391, 56395, 56401, 56404, 56408, 56416, + 56424, 56426, 56428, 56434, 56440, 56446, 56455, 56464, 56471, 56478, + 56484, 56491, 56496, 56501, 56506, 56512, 56518, 56523, 56530, 56534, + 56538, 56551, 56564, 56576, 56585, 56591, 56598, 56603, 56608, 56613, + 56618, 56623, 56625, 56632, 56640, 56648, 56656, 56663, 56671, 56677, + 56682, 56688, 56694, 56700, 56707, 56713, 56721, 56729, 56737, 56745, + 56753, 56759, 56765, 56774, 56778, 56787, 56796, 56805, 56813, 56817, + 56823, 56830, 56837, 56841, 56847, 56855, 56861, 56866, 56872, 56877, + 56882, 56889, 56896, 56901, 56906, 56914, 56922, 56932, 56942, 56949, + 56956, 56960, 56964, 56976, 56982, 56989, 56994, 56999, 57006, 57013, + 57019, 57025, 57035, 57042, 57050, 57058, 57067, 57074, 57080, 57087, + 57093, 57101, 57109, 57117, 57125, 57131, 57136, 57146, 57157, 57164, + 57173, 57179, 57184, 57189, 57199, 57208, 57214, 57220, 57228, 57233, + 57240, 57247, 57258, 57265, 57272, 57279, 57286, 57293, 57302, 57311, + 57324, 57337, 57349, 57361, 57374, 57388, 57394, 57400, 57410, 57420, + 57427, 57434, 57444, 57454, 57463, 57472, 57480, 57488, 57498, 57508, + 57523, 57538, 57547, 57556, 57569, 57582, 57591, 57600, 57611, 57622, + 57628, 57634, 57643, 57652, 57657, 57662, 57670, 57676, 57682, 57690, + 57698, 57711, 57724, 57728, 57732, 57741, 57750, 57757, 57765, 57773, + 57783, 57793, 57799, 57805, 57813, 57821, 57829, 57837, 57847, 57857, + 57860, 57863, 57868, 57873, 57879, 57885, 57892, 57899, 57910, 57921, + 57928, 57935, 57943, 57951, 57960, 57969, 57978, 57987, 57994, 58001, + 58005, 58009, 58018, 58027, 58032, 58037, 58042, 58047, 58053, 58067, + 58074, 58081, 58085, 58087, 58089, 58094, 58099, 58104, 58109, 58117, + 58124, 58131, 58139, 58151, 58159, 58167, 58178, 58182, 58186, 58192, + 58200, 58213, 58220, 58227, 58234, 58240, 58247, 58256, 58265, 58271, + 58277, 58283, 58294, 58305, 58313, 58322, 58327, 58330, 58335, 58340, + 58345, 58351, 58357, 58361, 58364, 58368, 58372, 58377, 58382, 58388, + 58394, 58398, 58402, 58409, 58416, 58423, 58430, 58437, 58444, 58453, + 58462, 58469, 58476, 58484, 58492, 58496, 58501, 58506, 58512, 58518, + 58521, 58524, 58527, 58530, 58535, 58540, 58545, 58550, 58555, 58560, + 58564, 58568, 58572, 58577, 58582, 58586, 58590, 58596, 58600, 58606, + 58611, 58618, 58626, 58633, 58641, 58648, 58656, 58665, 58672, 58682, + 58693, 58699, 58708, 58714, 58723, 58733, 58739, 58745, 58749, 58753, + 58762, 58772, 58779, 58787, 58796, 58805, 58812, 58818, 58825, 58830, + 58834, 58838, 58843, 58848, 58853, 58861, 58869, 58872, 58876, 58885, + 58895, 58904, 58914, 58926, 58940, 58944, 58949, 58953, 58958, 58963, + 58968, 58974, 58980, 58987, 58994, 59000, 59007, 59013, 59020, 59029, + 59038, 59044, 59051, 59057, 0, 0, 59064, 59072, 59080, 59089, 59098, + 59107, 59117, 59126, 59136, 59142, 59147, 59156, 59168, 59177, 59189, + 59196, 59204, 59211, 59219, 59224, 59230, 59235, 59241, 59249, 59258, + 59266, 59275, 59279, 59282, 59286, 59289, 59299, 0, 59302, 59309, 59318, + 59328, 59337, 59347, 59353, 59360, 59366, 59373, 59384, 59395, 59406, + 59417, 59427, 59437, 59447, 59457, 59465, 59473, 59481, 59489, 59497, + 59505, 59513, 59521, 59527, 59532, 59538, 59543, 59549, 59555, 59561, + 59567, 59579, 59589, 59594, 59601, 59606, 59613, 59616, 59620, 59624, + 59629, 59633, 59638, 59641, 59650, 59659, 59668, 59677, 59682, 59688, + 59694, 59702, 59712, 59719, 59728, 59733, 59736, 59739, 59744, 59749, + 59754, 59759, 59761, 59763, 59765, 59767, 59769, 59771, 59776, 59783, + 59790, 59792, 59794, 59796, 59798, 59800, 59802, 59804, 59806, 59811, + 59816, 59823, 59830, 59839, 59849, 59858, 59868, 59873, 59878, 59880, + 59887, 59894, 59901, 59908, 59915, 59922, 59929, 59932, 59935, 59938, + 59941, 59946, 59951, 59956, 59961, 59966, 59971, 59976, 59981, 59986, + 59991, 59996, 60001, 60007, 60011, 60016, 60021, 60026, 60031, 60036, + 60041, 60046, 60051, 60056, 60061, 60066, 60071, 60076, 60081, 60086, + 60091, 60096, 60101, 60106, 60111, 60116, 60121, 60127, 60132, 60138, + 60147, 60152, 60160, 60167, 60176, 60181, 60186, 60191, 60197, 60204, + 60211, 60216, 60221, 60226, 60231, 60236, 60241, 60246, 60251, 60256, + 60261, 60267, 60271, 60276, 60281, 60286, 60291, 60296, 60301, 60306, + 60311, 60316, 60321, 60326, 60331, 60336, 60341, 60346, 60351, 60356, + 60361, 60366, 60371, 60376, 60381, 60387, 60392, 60398, 60407, 60412, + 60420, 60427, 60436, 60441, 60446, 60451, 60457, 60464, 60471, 60479, + 60487, 60496, 60503, 60511, 60517, 60526, 60534, 60542, 60550, 60558, + 60566, 60574, 60579, 60586, 60591, 60597, 60605, 60612, 60619, 60627, + 60633, 60639, 60646, 60654, 60663, 60673, 60679, 60686, 60691, 60701, + 60711, 60716, 60721, 60726, 60731, 60736, 60741, 60746, 60751, 60756, + 60761, 60766, 60771, 60776, 60781, 60786, 60791, 60796, 60801, 60806, + 60811, 60816, 60821, 60826, 60831, 60836, 60841, 60846, 60851, 60856, + 60861, 60865, 60869, 60874, 60879, 60884, 60889, 60894, 60899, 60904, + 60909, 60914, 60919, 60924, 60929, 60934, 60939, 60944, 60949, 60954, + 60959, 60966, 60973, 60980, 60987, 60994, 61001, 61008, 61015, 61022, + 61029, 61036, 61043, 61050, 61057, 61062, 61067, 61074, 61081, 61088, + 61095, 61102, 61109, 61116, 61123, 61130, 61137, 61144, 61151, 61157, + 61163, 61169, 61175, 61182, 61189, 61196, 61203, 61210, 61217, 61224, + 61231, 61238, 61245, 61253, 61261, 61269, 61277, 61285, 61293, 61301, + 61309, 61313, 61319, 61325, 61329, 61335, 61341, 61347, 61354, 61361, + 61368, 61375, 61380, 61386, 61392, 61399, 0, 0, 0, 0, 0, 61406, 61414, + 61423, 61432, 61440, 61446, 61451, 61456, 61461, 61466, 61471, 61476, + 61481, 61486, 61491, 61496, 61501, 61506, 61511, 61516, 61521, 61526, + 61531, 61536, 61541, 61546, 61551, 61556, 61561, 61566, 61571, 61576, + 61581, 61586, 61591, 61596, 61601, 61606, 61611, 61616, 61621, 61626, + 61631, 61636, 61641, 0, 61646, 0, 0, 0, 0, 0, 61651, 0, 0, 61656, 61660, + 61665, 61670, 61675, 61680, 61689, 61694, 61699, 61704, 61709, 61714, + 61719, 61724, 61729, 61736, 61741, 61746, 61755, 61762, 61767, 61772, + 61777, 61784, 61789, 61796, 61801, 61806, 61813, 61820, 61825, 61830, + 61835, 61842, 61849, 61854, 61859, 61864, 61869, 61874, 61881, 61888, + 61893, 61898, 61903, 61908, 61913, 61918, 61923, 61928, 61933, 61938, + 61943, 61950, 61955, 61960, 0, 0, 0, 0, 0, 0, 0, 61965, 61972, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61977, 61982, 61986, 61990, 61994, + 61998, 62002, 62006, 62010, 62014, 62018, 62022, 62028, 62032, 62036, + 62040, 62044, 62048, 62052, 62056, 62060, 62064, 62068, 62072, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 62076, 62080, 62084, 62088, 62092, 62096, 62100, 0, + 62104, 62108, 62112, 62116, 62120, 62124, 62128, 0, 62132, 62136, 62140, + 62144, 62148, 62152, 62156, 0, 62160, 62164, 62168, 62172, 62176, 62180, + 62184, 0, 62188, 62192, 62196, 62200, 62204, 62208, 62212, 0, 62216, + 62220, 62224, 62228, 62232, 62236, 62240, 0, 62244, 62248, 62252, 62256, + 62260, 62264, 62268, 0, 62272, 62276, 62280, 62284, 62288, 62292, 62296, + 0, 62300, 62305, 62310, 62315, 62320, 62325, 62330, 62334, 62339, 62344, + 62349, 62353, 62358, 62363, 62368, 62373, 62377, 62382, 62387, 62392, + 62397, 62402, 62407, 62411, 62416, 62421, 62428, 62433, 62438, 62444, + 62451, 62458, 62467, 62474, 62483, 62488, 62493, 62500, 62507, 62513, + 62521, 62527, 62532, 62537, 62541, 62548, 62555, 62559, 62561, 62565, + 62571, 62573, 62577, 62581, 62585, 62591, 62596, 62600, 62604, 62609, + 62615, 62621, 62627, 62632, 62637, 62644, 62651, 62657, 62663, 62669, + 62675, 62681, 62687, 62691, 62695, 62702, 62709, 62715, 62719, 62724, + 62727, 62731, 62738, 62741, 62745, 62749, 62752, 62758, 62764, 62767, + 62773, 62777, 62781, 62787, 62792, 62797, 62799, 62802, 62806, 62812, + 62818, 62822, 62827, 62836, 62839, 62845, 62850, 62854, 62858, 62862, + 62865, 62870, 62876, 62884, 62892, 62898, 62903, 62908, 62914, 62920, + 62927, 62934, 62940, 62946, 62952, 62958, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 19275, 19279, 19290, 19305, 19320, 19330, 19341, 19354, - 19365, 19371, 19379, 19389, 19395, 19403, 19407, 19413, 19419, 19427, - 19437, 19445, 19458, 19464, 19472, 19480, 19492, 19499, 19507, 19515, - 19523, 19531, 19539, 19547, 19557, 19561, 19564, 19567, 19570, 19573, - 19576, 19579, 19582, 19585, 19588, 19592, 19596, 19600, 19604, 19608, - 19612, 19616, 19620, 19624, 19629, 19635, 19645, 19659, 19669, 19675, - 19681, 19689, 19697, 19705, 19713, 19719, 19725, 19728, 19732, 19736, - 19740, 19744, 19748, 19752, 0, 19756, 19760, 19764, 19768, 19772, 19776, - 19780, 19784, 19788, 19792, 19796, 19799, 19802, 19806, 19810, 19814, - 19817, 19821, 19825, 19829, 19833, 19837, 19841, 19845, 19849, 19852, - 19855, 19858, 19862, 19866, 19869, 19872, 19875, 19879, 19884, 19888, 0, - 0, 0, 0, 19892, 19897, 19901, 19906, 19910, 19915, 19920, 19926, 19931, - 19937, 19941, 19946, 19950, 19955, 19965, 19971, 19977, 19984, 19994, - 20000, 20004, 20008, 20014, 20020, 20028, 20034, 20042, 20050, 20058, - 20068, 20076, 20086, 20091, 20097, 20103, 20109, 20115, 20121, 20127, 0, - 20133, 20139, 20145, 20151, 20157, 20163, 20169, 20175, 20181, 20187, - 20193, 20198, 20203, 20209, 20215, 20221, 20226, 20232, 20238, 20244, - 20250, 20256, 20262, 20268, 20274, 20279, 20284, 20289, 20295, 20301, - 20306, 20311, 20316, 20322, 20330, 20337, 0, 20344, 20351, 20364, 20371, - 20378, 20386, 20394, 20400, 20406, 20412, 20422, 20427, 20433, 20443, - 20453, 0, 20463, 20473, 20481, 20493, 20505, 20511, 20525, 20540, 20545, - 20550, 20558, 20566, 20574, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20582, - 20585, 20589, 20593, 20597, 20601, 20605, 20609, 20613, 20617, 20621, - 20625, 20629, 20633, 20637, 20641, 20645, 20649, 20653, 20657, 20661, - 20664, 20667, 20671, 20675, 20679, 20682, 20685, 20688, 20691, 20695, - 20698, 20701, 20705, 20708, 20713, 20716, 20720, 20723, 20727, 20730, - 20735, 20738, 20742, 20749, 20754, 20758, 20763, 20767, 20772, 20776, - 20781, 20788, 20794, 20800, 20804, 20808, 20812, 20816, 20820, 20826, - 20832, 20839, 20845, 20850, 20854, 20857, 20860, 20863, 20866, 20869, - 20872, 20875, 20878, 20881, 20887, 20891, 20895, 20899, 20903, 20907, - 20911, 20915, 20919, 20924, 20928, 20933, 20938, 20944, 20949, 20955, - 20961, 20967, 20973, 20979, 20987, 20995, 21003, 21011, 21020, 21029, - 21040, 21050, 21060, 21071, 21082, 21092, 21102, 21112, 21122, 21132, - 21142, 21152, 21162, 21170, 21177, 21183, 21190, 21195, 21201, 21207, - 21213, 21219, 21225, 21231, 21236, 21242, 21248, 21254, 21260, 21265, - 21274, 21281, 21287, 21295, 21303, 21309, 21315, 21321, 21327, 21335, - 21343, 21353, 21361, 21369, 21375, 21380, 21385, 21390, 21395, 21400, - 21405, 21410, 21415, 21420, 21426, 21432, 21438, 21445, 21450, 21456, - 21461, 21466, 21471, 21476, 21481, 21486, 21491, 21496, 21501, 21506, - 21511, 21516, 21521, 21526, 21531, 21536, 21541, 21546, 21551, 21556, - 21561, 21566, 21571, 21576, 21581, 21586, 21591, 21596, 21601, 21606, - 21611, 21616, 21621, 21626, 21631, 21636, 21641, 0, 21646, 0, 0, 0, 0, 0, - 21651, 0, 0, 21656, 21660, 21664, 21668, 21672, 21676, 21680, 21684, - 21688, 21692, 21696, 21700, 21704, 21708, 21712, 21716, 21720, 21724, - 21728, 21732, 21736, 21740, 21744, 21748, 21752, 21756, 21760, 21764, - 21768, 21772, 21776, 21780, 21784, 21788, 21792, 21796, 21800, 21804, - 21808, 21812, 21816, 21820, 21825, 21829, 21834, 21839, 21843, 21848, - 21853, 21857, 21861, 21865, 21869, 21873, 21877, 21881, 21885, 21889, - 21893, 21897, 21901, 21905, 21909, 21913, 21917, 21921, 21925, 21929, - 21933, 21937, 21941, 21945, 21949, 21953, 21957, 21961, 21965, 21969, - 21973, 21977, 21981, 21985, 21989, 21993, 21997, 22001, 22005, 22009, - 22013, 22017, 22021, 22025, 22029, 22033, 22037, 22041, 22045, 22049, - 22053, 22057, 22061, 22065, 22069, 22073, 22077, 22081, 22085, 22089, - 22093, 22097, 22101, 22105, 22109, 22113, 22117, 22121, 22125, 22129, - 22133, 22137, 22141, 22145, 22149, 22153, 22157, 22161, 22165, 22169, - 22173, 22177, 22181, 22185, 22189, 22193, 22197, 22201, 22205, 22209, - 22213, 22217, 22221, 22225, 22229, 22233, 22237, 22242, 22246, 22251, - 22255, 22260, 22265, 22269, 22274, 22279, 22283, 22288, 22293, 22298, - 22303, 22307, 22312, 22317, 22322, 22327, 22332, 22337, 22341, 22346, - 22351, 22356, 22361, 22366, 22371, 22376, 22381, 22386, 22391, 22396, - 22401, 22406, 22411, 22416, 22421, 22426, 22431, 22436, 22441, 22446, - 22451, 22456, 22461, 22466, 22471, 22476, 22481, 22486, 22491, 22496, - 22501, 22506, 22511, 22516, 22521, 22526, 22531, 22536, 22541, 22546, - 22551, 22556, 22561, 22566, 22571, 22576, 22581, 22586, 22591, 22595, - 22599, 22603, 22607, 22611, 22615, 22619, 22623, 22627, 22631, 22635, - 22639, 22643, 22647, 22651, 22655, 22659, 22663, 22667, 22671, 22675, - 22679, 22683, 22687, 22691, 22695, 22699, 22703, 22707, 22711, 22715, - 22719, 22723, 22727, 22731, 22735, 22739, 22743, 22747, 22751, 22755, - 22759, 22763, 22767, 22771, 22775, 22779, 22783, 22787, 22791, 22795, - 22799, 22803, 22807, 22811, 22815, 22819, 22823, 22827, 22831, 22835, - 22839, 22843, 22847, 22851, 22855, 22859, 22863, 22867, 22871, 22875, - 22879, 22883, 22887, 22891, 22895, 22899, 22903, 22907, 22911, 22915, - 22919, 22923, 22927, 22931, 22935, 22939, 22943, 22946, 22950, 22954, - 22958, 22962, 22966, 22970, 22974, 22977, 22981, 22985, 22989, 22993, - 22997, 23001, 23005, 23009, 23013, 23017, 23021, 23025, 23029, 23033, - 23037, 23040, 23044, 23048, 23052, 23056, 23060, 23064, 23068, 23072, - 23076, 23080, 23084, 23088, 23092, 23096, 23100, 23103, 23107, 23111, - 23115, 23119, 23123, 23127, 23131, 23134, 23138, 23142, 23146, 23150, - 23154, 23158, 23162, 23166, 23170, 23174, 23178, 23182, 23186, 23190, - 23194, 23198, 23202, 23206, 23210, 23214, 23218, 23222, 23226, 0, 23230, - 23234, 23238, 23242, 0, 0, 23246, 23250, 23254, 23258, 23262, 23266, - 23270, 0, 23274, 0, 23278, 23282, 23286, 23290, 0, 0, 23294, 23298, - 23302, 23306, 23310, 23314, 23318, 23322, 23326, 23330, 23334, 23338, - 23342, 23346, 23350, 23354, 23358, 23362, 23366, 23370, 23374, 23378, - 23382, 23385, 23389, 23393, 23397, 23401, 23405, 23409, 23413, 23417, - 23421, 23425, 23429, 23433, 23437, 23441, 23445, 23449, 23453, 0, 23457, - 23461, 23465, 23469, 0, 0, 23473, 23476, 23480, 23484, 23488, 23492, - 23496, 23500, 23504, 23508, 23512, 23516, 23520, 23524, 23528, 23532, - 23536, 23541, 23546, 23551, 23557, 23563, 23568, 23573, 23579, 23582, - 23586, 23590, 23594, 23598, 23602, 23606, 23610, 0, 23614, 23618, 23622, - 23626, 0, 0, 23630, 23634, 23638, 23642, 23646, 23650, 23654, 0, 23658, - 0, 23662, 23666, 23670, 23674, 0, 0, 23678, 23682, 23686, 23690, 23694, - 23698, 23702, 23706, 23710, 23715, 23720, 23725, 23731, 23737, 23742, 0, - 23747, 23751, 23755, 23759, 23763, 23767, 23771, 23775, 23779, 23783, - 23787, 23791, 23795, 23799, 23803, 23807, 23811, 23814, 23818, 23822, - 23826, 23830, 23834, 23838, 23842, 23846, 23850, 23854, 23858, 23862, - 23866, 23870, 23874, 23878, 23882, 23886, 23890, 23894, 23898, 23902, - 23906, 23910, 23914, 23918, 23922, 23926, 23930, 23934, 23938, 23942, - 23946, 23950, 23954, 23958, 23962, 23966, 23970, 0, 23974, 23978, 23982, - 23986, 0, 0, 23990, 23994, 23998, 24002, 24006, 24010, 24014, 24018, - 24022, 24026, 24030, 24034, 24038, 24042, 24046, 24050, 24054, 24058, - 24062, 24066, 24070, 24074, 24078, 24082, 24086, 24090, 24094, 24098, - 24102, 24106, 24110, 24114, 24118, 24122, 24126, 24130, 24134, 24138, - 24142, 24146, 24150, 24154, 24158, 24162, 24166, 24170, 24174, 24178, - 24182, 24186, 24190, 24194, 24198, 24202, 24206, 24210, 24214, 24217, - 24221, 24225, 24229, 24233, 24237, 24241, 24245, 24249, 24253, 0, 0, - 24257, 24266, 24272, 24277, 24281, 24284, 24289, 24292, 24295, 24298, - 24303, 24307, 24312, 24315, 24318, 24321, 24324, 24327, 24330, 24333, - 24336, 24339, 24343, 24347, 24351, 24355, 24359, 24363, 24367, 24371, - 24375, 24379, 0, 0, 0, 24384, 24390, 24394, 24398, 24402, 24408, 24412, - 24416, 24420, 24426, 24430, 24434, 24438, 24444, 24448, 24452, 24456, - 24462, 24468, 24474, 24482, 24488, 24494, 24500, 24506, 24512, 0, 0, 0, - 0, 0, 0, 24518, 24521, 24524, 24527, 24530, 24533, 24537, 24541, 24544, - 24548, 24552, 24556, 24560, 24564, 24567, 24571, 24575, 24579, 24583, - 24587, 24590, 24594, 24598, 24602, 24606, 24610, 24613, 24617, 24621, - 24625, 24629, 24632, 24636, 24640, 24644, 24648, 24652, 24656, 24660, - 24664, 24668, 24672, 24676, 24680, 24684, 24687, 24691, 24695, 24699, - 24703, 24707, 24711, 24715, 24719, 24723, 24727, 24731, 24735, 24739, - 24743, 24747, 24751, 24755, 24759, 24763, 24767, 24771, 24775, 24779, - 24783, 24787, 24791, 24795, 24799, 24803, 24807, 24811, 24815, 24819, - 24823, 24826, 24830, 24834, 24838, 24842, 24846, 0, 0, 24850, 24855, - 24860, 24865, 24870, 24875, 0, 0, 24880, 24884, 24887, 24891, 24894, - 24898, 24901, 24905, 24911, 24916, 24920, 24923, 24927, 24931, 24937, - 24941, 24947, 24951, 24957, 24961, 24967, 24971, 24977, 24983, 24987, - 24993, 24997, 25003, 25009, 25013, 25019, 25025, 25030, 25035, 25043, - 25051, 25058, 25063, 25069, 25078, 25084, 25092, 25097, 25103, 25107, - 25111, 25115, 25119, 25123, 25127, 25131, 25135, 25139, 25143, 25149, - 25154, 25159, 25162, 25166, 25170, 25176, 25180, 25186, 25190, 25196, - 25200, 25206, 25210, 25216, 25220, 25226, 25230, 25236, 25242, 25246, - 25252, 25257, 25261, 25265, 25269, 25273, 25276, 25280, 25286, 25291, - 25296, 25300, 25304, 25308, 25314, 25318, 25324, 25328, 25334, 25337, - 25342, 25346, 25352, 25356, 25362, 25366, 25372, 25378, 25382, 25386, - 25390, 25394, 25398, 25402, 25406, 25410, 25414, 25418, 25422, 25428, - 25431, 25435, 25439, 25445, 25449, 25455, 25459, 25465, 25469, 25475, - 25479, 25485, 25489, 25495, 25499, 25505, 25511, 25515, 25519, 25525, - 25531, 25537, 25543, 25547, 25551, 25555, 25559, 25563, 25567, 25573, - 25577, 25581, 25585, 25591, 25595, 25601, 25605, 25611, 25615, 25621, - 25625, 25631, 25635, 25641, 25645, 25651, 25657, 25661, 25667, 25671, - 25675, 25679, 25683, 25687, 25691, 25697, 25700, 25704, 25708, 25714, - 25718, 25724, 25728, 25734, 25738, 25744, 25748, 25754, 25758, 25764, - 25768, 25774, 25780, 25784, 25790, 25794, 25800, 25806, 25810, 25814, - 25818, 25822, 25826, 25830, 25836, 25839, 25843, 25847, 25853, 25857, - 25863, 25867, 25873, 25879, 25883, 25888, 25892, 25896, 25900, 25904, - 25908, 25912, 25916, 25922, 25925, 25929, 25933, 25939, 25943, 25949, - 25953, 25959, 25963, 25969, 25973, 25979, 25983, 25989, 25993, 25999, - 26002, 26007, 26012, 26016, 26020, 26024, 26028, 26032, 26036, 26042, - 26045, 26049, 26053, 26059, 26063, 26069, 26073, 26079, 26083, 26089, - 26093, 26099, 26103, 26109, 26113, 26119, 26125, 26129, 26135, 26139, - 26145, 26151, 26157, 26163, 26169, 26175, 26181, 26187, 26191, 26195, - 26199, 26203, 26207, 26211, 26215, 26219, 26225, 26229, 26235, 26239, - 26245, 26249, 26255, 26259, 26265, 26269, 26275, 26279, 26285, 26289, - 26293, 26297, 26301, 26305, 26309, 26313, 26319, 26322, 26326, 26330, - 26336, 26340, 26346, 26350, 26356, 26360, 26366, 26370, 26376, 26380, - 26386, 26390, 26396, 26402, 26406, 26412, 26418, 26424, 26428, 26434, - 26440, 26444, 26448, 26452, 26456, 26460, 26466, 26469, 26473, 26478, - 26482, 26488, 26491, 26496, 26501, 26505, 26509, 26513, 26517, 26521, - 26525, 26529, 26533, 26537, 26543, 26547, 26551, 26557, 26561, 26567, - 26571, 26577, 26581, 26585, 26589, 26593, 26597, 26603, 26607, 26611, - 26615, 26619, 26623, 26627, 26631, 26635, 26639, 26643, 26649, 26655, - 26661, 26667, 26673, 26678, 26684, 26690, 26696, 26700, 26704, 26708, - 26712, 26716, 26720, 26724, 26728, 26732, 26736, 26740, 26744, 26748, - 26754, 26760, 26766, 26771, 26775, 26779, 26783, 26787, 26791, 26795, - 26799, 26803, 26807, 26813, 26819, 26825, 26831, 26837, 26843, 26849, - 26855, 26861, 26865, 26869, 26873, 26877, 26881, 26885, 26889, 26895, - 26901, 26907, 26913, 26919, 26925, 26931, 26937, 26943, 26948, 26953, - 26958, 26963, 26969, 26975, 26981, 26987, 26993, 26999, 27005, 27010, - 27016, 27022, 27028, 27033, 27039, 27045, 27051, 27056, 27061, 27066, - 27071, 27076, 27081, 27086, 27091, 27096, 27101, 27106, 27111, 27115, - 27120, 27125, 27130, 27135, 27140, 27145, 27150, 27155, 27160, 27165, - 27170, 27175, 27180, 27185, 27190, 27195, 27200, 27205, 27210, 27215, - 27220, 27225, 27230, 27235, 27240, 27245, 27250, 27255, 27260, 27264, - 27269, 27274, 27279, 27284, 27289, 27294, 27299, 27304, 27309, 27314, - 27319, 27324, 27329, 27334, 27339, 27344, 27349, 27354, 27359, 27364, - 27369, 27374, 27379, 27384, 27389, 27393, 27398, 27403, 27408, 27413, - 27418, 27422, 27427, 27432, 27437, 27442, 27447, 27451, 27456, 27462, - 27467, 27472, 27477, 27482, 27488, 27493, 27498, 27503, 27508, 27513, - 27518, 27523, 27528, 27533, 27538, 27543, 27548, 27552, 27557, 27562, - 27567, 27572, 27577, 27582, 27587, 27592, 27597, 27602, 27607, 27612, - 27617, 27622, 27627, 27632, 27637, 27642, 27647, 27652, 27657, 27662, - 27667, 27672, 27677, 27682, 27687, 27692, 27697, 27702, 27707, 27713, - 27718, 27723, 27728, 27733, 27738, 27743, 27748, 27753, 27758, 27763, - 27768, 27772, 27777, 27782, 27787, 27792, 27797, 27802, 27807, 27812, - 27817, 27822, 27827, 27832, 27837, 27842, 27847, 27852, 27857, 27862, - 27867, 27872, 27877, 27882, 27887, 27892, 27897, 27902, 27908, 27912, - 27916, 27920, 27924, 27928, 27932, 27936, 27940, 27946, 27952, 27958, - 27964, 27970, 27976, 27982, 27989, 27995, 28000, 28005, 28010, 28015, - 28020, 28025, 28030, 28035, 28040, 28045, 28050, 28055, 28060, 28065, - 28070, 28075, 28080, 28085, 28090, 28095, 28100, 28105, 28110, 28115, - 28120, 28125, 28130, 28135, 0, 0, 0, 28142, 28153, 28158, 28166, 28171, - 28176, 28181, 28190, 28195, 28201, 28207, 28213, 28218, 28224, 28230, - 28234, 28239, 28244, 28254, 28259, 28264, 28271, 28276, 28281, 28290, - 28295, 28304, 28311, 28318, 28325, 28332, 28343, 28350, 28355, 28365, - 28369, 28376, 28381, 28388, 28394, 28401, 28410, 28417, 28424, 28433, - 28440, 28445, 28450, 28461, 28468, 28473, 28484, 28491, 28496, 28501, - 28509, 28518, 28525, 28532, 28542, 28547, 28552, 28557, 28566, 28574, - 28579, 28584, 28589, 28594, 28599, 28604, 28609, 28614, 28619, 28624, - 28629, 28635, 28641, 28647, 28652, 28657, 28662, 28667, 28672, 28677, - 28686, 28695, 28704, 28713, 0, 0, 0, 0, 0, 0, 0, 28722, 28726, 28730, - 28734, 28738, 28743, 28748, 28753, 28758, 28762, 28766, 28771, 28775, - 28779, 28783, 28787, 28792, 28796, 28800, 28805, 28810, 28815, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 28820, 28826, 28830, 28834, 28838, 28842, 28847, 28852, - 28857, 28862, 28866, 28870, 28875, 28879, 28883, 28887, 28891, 28896, - 28900, 28904, 28909, 28914, 28919, 28925, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 28930, 28934, 28938, 28942, 28946, 28951, 28956, 28961, 28966, 28970, - 28974, 28979, 28983, 28987, 28991, 28995, 29000, 29004, 29008, 29013, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29018, 29022, 29026, 29030, 29034, - 29039, 29044, 29049, 29054, 29058, 29062, 29067, 29071, 0, 29075, 29079, - 29084, 0, 29088, 29093, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29098, 29101, - 29105, 29109, 29113, 29117, 29121, 29125, 29129, 29133, 29137, 29141, - 29145, 29149, 29153, 29157, 29161, 29165, 29168, 29172, 29176, 29180, - 29184, 29188, 29192, 29196, 29200, 29204, 29208, 29212, 29216, 29220, - 29223, 29226, 29229, 29233, 29239, 29245, 29251, 29257, 29263, 29269, - 29275, 29281, 29287, 29293, 29299, 29305, 29311, 29317, 29326, 29335, - 29341, 29347, 29353, 29358, 29362, 29367, 29372, 29377, 29381, 29386, - 29391, 29396, 29400, 29405, 29409, 29414, 29419, 29424, 29429, 29433, - 29437, 29441, 29445, 29449, 29453, 29457, 29461, 29465, 29469, 29475, - 29479, 29483, 29487, 29491, 29495, 29503, 29509, 29513, 29519, 29523, - 29529, 29533, 0, 0, 29537, 29541, 29544, 29547, 29550, 29553, 29556, - 29559, 29562, 29565, 0, 0, 0, 0, 0, 0, 29568, 29576, 29584, 29592, 29600, - 29608, 29616, 29624, 29632, 29640, 0, 0, 0, 0, 0, 0, 29648, 29651, 29654, - 29657, 29662, 29665, 29670, 29677, 29685, 29690, 29697, 29700, 29707, - 29714, 29721, 29725, 29732, 29736, 29739, 29742, 29745, 29748, 29751, - 29754, 29757, 29760, 0, 0, 0, 0, 0, 0, 29763, 29766, 29769, 29772, 29775, - 29778, 29782, 29786, 29790, 29793, 29797, 29801, 29804, 29808, 29812, - 29815, 29818, 29821, 29825, 29829, 29833, 29837, 29841, 29844, 29847, - 29851, 29855, 29858, 29862, 29866, 29870, 29874, 29878, 29882, 29886, - 29890, 29897, 29902, 29907, 29912, 29917, 29923, 29929, 29935, 29941, - 29946, 29952, 29958, 29963, 29969, 29975, 29981, 29987, 29993, 29998, - 30004, 30009, 30015, 30021, 30027, 30033, 30039, 30044, 30049, 30055, - 30061, 30066, 30072, 30077, 30083, 30088, 30093, 30099, 30105, 30111, - 30117, 30123, 30129, 30135, 30141, 30147, 30153, 30159, 30165, 30170, - 30175, 30180, 30186, 30192, 0, 0, 0, 0, 0, 0, 0, 30200, 30209, 30218, - 30226, 30234, 30244, 30252, 30261, 30268, 30275, 30282, 30290, 30298, - 30306, 30314, 30322, 30330, 30338, 30346, 30353, 30361, 30369, 30377, - 30385, 30393, 30403, 30413, 30423, 30433, 30443, 30453, 30463, 30473, - 30483, 30493, 30503, 30513, 30523, 30533, 30541, 30549, 30559, 30567, 0, - 0, 0, 0, 0, 30577, 30581, 30585, 30589, 30593, 30597, 30601, 30605, - 30609, 30613, 30617, 30621, 30625, 30629, 30633, 30637, 30641, 30645, - 30649, 30653, 30657, 30661, 30665, 30669, 30675, 30679, 30685, 30689, - 30695, 30699, 30705, 30709, 30713, 30717, 30721, 30725, 30729, 30735, - 30741, 30747, 30753, 30759, 30765, 30771, 30777, 30783, 30789, 30795, - 30802, 30808, 30814, 30820, 30824, 30828, 30832, 30836, 30840, 30844, - 30848, 30854, 30860, 30866, 30871, 30878, 30883, 30888, 30894, 30899, - 30906, 30913, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30920, 30926, 30930, 30935, - 30940, 30945, 30950, 30955, 30960, 30965, 30970, 30975, 30980, 30985, - 30990, 30995, 30999, 31003, 31008, 31013, 31018, 31022, 31026, 31030, - 31034, 31039, 31044, 31049, 31053, 31057, 31062, 0, 31067, 31072, 31077, - 31082, 31088, 31094, 31100, 31106, 31111, 31116, 31122, 31128, 0, 0, 0, - 0, 31135, 31140, 31146, 31152, 31158, 31163, 31168, 31173, 31178, 31183, - 31188, 31193, 0, 0, 0, 0, 31198, 0, 0, 0, 31203, 31208, 31213, 31218, - 31222, 31226, 31230, 31234, 31238, 31242, 31246, 31250, 31254, 31259, - 31265, 31271, 31277, 31282, 31287, 31293, 31299, 31304, 31309, 31315, - 31320, 31326, 31332, 31337, 31343, 31349, 31355, 31360, 31365, 31370, - 31376, 31382, 31387, 31393, 31398, 31404, 31409, 31415, 0, 0, 31421, - 31427, 31433, 31439, 31445, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31451, - 31460, 31469, 31477, 31486, 31495, 31503, 31512, 31521, 31530, 31538, - 31546, 31555, 31563, 31571, 31580, 31589, 31597, 31606, 31615, 31623, - 31631, 31640, 31648, 31656, 31665, 31673, 31682, 31691, 31699, 31708, - 31717, 31725, 31733, 31742, 31751, 31759, 31768, 31777, 31786, 31795, - 31804, 31813, 31822, 0, 0, 0, 0, 31831, 31841, 31850, 31859, 31867, - 31876, 31884, 31893, 31901, 31910, 31919, 31928, 31937, 31946, 31955, - 31964, 31973, 31982, 31991, 32000, 32009, 32018, 32027, 32036, 32045, - 32053, 0, 0, 0, 0, 0, 0, 32061, 32069, 32076, 32083, 32090, 32097, 32104, - 32111, 32118, 32125, 32132, 0, 0, 0, 32140, 32148, 32156, 32160, 32166, - 32172, 32178, 32184, 32190, 32196, 32202, 32208, 32214, 32220, 32226, - 32232, 32238, 32244, 32250, 32254, 32260, 32266, 32272, 32278, 32284, - 32290, 32296, 32302, 32308, 32314, 32320, 32326, 32332, 32338, 32344, - 32348, 32353, 32358, 32363, 32367, 32372, 32376, 32381, 32386, 32391, - 32395, 32400, 32405, 32410, 32415, 32420, 32424, 32428, 32432, 32437, - 32441, 32445, 32449, 32454, 32459, 32464, 32469, 0, 0, 32475, 32479, - 32486, 32491, 32497, 32503, 32508, 32514, 32520, 32525, 32531, 32537, - 32543, 32548, 32554, 32559, 32564, 32570, 32575, 32581, 32586, 32592, - 32598, 32604, 32610, 32614, 32619, 32624, 32630, 32636, 32641, 32647, - 32653, 32657, 32662, 32667, 32671, 32676, 32680, 32685, 32690, 32696, - 32702, 32707, 32712, 32717, 32721, 32726, 32730, 32735, 32739, 32744, - 32749, 32754, 32759, 32765, 32772, 32779, 32789, 32798, 32805, 32811, - 32822, 32827, 32833, 0, 32838, 32843, 32848, 32856, 32862, 32870, 32875, - 32881, 32887, 32893, 32898, 32904, 32909, 32916, 32922, 32927, 32933, - 32939, 32945, 32952, 32959, 32966, 32971, 32976, 32983, 32990, 32997, - 33004, 33011, 0, 0, 33018, 33025, 33032, 33038, 33044, 33050, 33056, - 33062, 33068, 33074, 33080, 0, 0, 0, 0, 0, 0, 33086, 33092, 33097, 33102, - 33107, 33112, 33117, 33122, 33127, 33132, 0, 0, 0, 0, 0, 0, 33137, 33142, - 33147, 33152, 33157, 33162, 33167, 33176, 33183, 33188, 33193, 33198, - 33203, 33208, 0, 0, 33213, 33220, 33223, 33226, 33230, 33235, 33239, - 33245, 33250, 33256, 33263, 33271, 33275, 33280, 33284, 33289, 33296, - 33304, 33311, 33317, 33325, 33332, 33337, 33341, 33348, 33352, 33357, - 33362, 33369, 33377, 33384, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 62962, 62966, 62970, 62975, 62980, 62985, 62989, 62993, 62997, 63002, + 63007, 63011, 63015, 63019, 63023, 63028, 63033, 63038, 63043, 63047, + 63051, 63056, 63061, 63066, 63071, 63075, 0, 63079, 63083, 63087, 63091, + 63095, 63099, 63103, 63108, 63113, 63117, 63122, 63127, 63136, 63140, + 63144, 63148, 63155, 63159, 63164, 63169, 63173, 63177, 63183, 63188, + 63193, 63198, 63203, 63207, 63211, 63215, 63219, 63223, 63228, 63233, + 63237, 63241, 63246, 63251, 63256, 63260, 63264, 63269, 63274, 63280, + 63286, 63290, 63296, 63302, 63306, 63312, 63318, 63323, 63328, 63332, + 63338, 63342, 63346, 63352, 63358, 63363, 63368, 63372, 63376, 63384, + 63390, 63396, 63402, 63407, 63412, 63417, 63423, 63427, 63433, 63437, + 63441, 63447, 63453, 63459, 63465, 63471, 63477, 63483, 63489, 63495, + 63501, 63507, 63513, 63517, 63523, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 63529, 63532, 63536, 63540, 63544, 63548, 63551, 63554, 63558, 63562, + 63566, 63570, 63573, 63578, 63582, 63586, 63590, 63596, 63600, 63604, + 63608, 63612, 63619, 63625, 63629, 63633, 63637, 63641, 63645, 63649, + 63653, 63657, 63661, 63665, 63669, 63675, 63679, 63683, 63687, 63691, + 63695, 63699, 63703, 63707, 63711, 63715, 63719, 63723, 63727, 63731, + 63735, 63739, 63745, 63751, 63756, 63761, 63765, 63769, 63773, 63777, + 63781, 63785, 63789, 63793, 63797, 63801, 63805, 63809, 63813, 63817, + 63821, 63825, 63829, 63833, 63837, 63841, 63845, 63849, 63853, 63857, + 63863, 63867, 63871, 63875, 63879, 63883, 63887, 63891, 63895, 63900, + 63907, 63911, 63915, 63919, 63923, 63927, 63931, 63935, 63939, 63943, + 63947, 63951, 63955, 63962, 63966, 63972, 63976, 63980, 63984, 63988, + 63992, 63995, 63999, 64003, 64007, 64011, 64015, 64019, 64023, 64027, + 64031, 64035, 64039, 64043, 64047, 64051, 64055, 64059, 64063, 64067, + 64071, 64075, 64079, 64083, 64087, 64091, 64095, 64099, 64103, 64107, + 64111, 64115, 64119, 64123, 64129, 64133, 64137, 64141, 64145, 64149, + 64153, 64157, 64161, 64165, 64169, 64173, 64177, 64181, 64185, 64189, + 64193, 64197, 64201, 64205, 64209, 64213, 64217, 64221, 64225, 64229, + 64233, 64237, 64245, 64249, 64253, 64257, 64261, 64265, 64271, 64275, + 64279, 64283, 64287, 64291, 64295, 64299, 64303, 64307, 64311, 64315, + 64319, 64323, 64329, 64333, 64337, 64341, 64345, 64349, 64353, 64357, + 64361, 64365, 64369, 64373, 64377, 64381, 64385, 64389, 64393, 64397, + 64401, 64405, 64409, 64413, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64417, 64425, 64433, 64443, 64453, + 64462, 64472, 64482, 64493, 64505, 64516, 64528, 0, 0, 0, 0, 64535, + 64538, 64541, 64546, 64549, 64556, 64560, 64564, 64568, 64573, 64578, + 64584, 64590, 64595, 64600, 64606, 64612, 64618, 64624, 64627, 64630, + 64637, 64644, 64650, 64656, 64664, 64672, 64677, 64682, 64686, 64694, + 64700, 64707, 64712, 64717, 64722, 64727, 64732, 64737, 64742, 64747, + 64752, 64757, 64762, 64767, 64772, 64777, 64783, 64788, 64792, 64798, + 64809, 64818, 64832, 64841, 64845, 64855, 64861, 64867, 64873, 64878, + 64881, 64886, 64890, 0, 64896, 64901, 64905, 64910, 64914, 64919, 64923, + 64928, 64932, 64937, 64941, 64945, 64950, 64955, 64960, 64965, 64970, + 64975, 64980, 64985, 64990, 64994, 64999, 65004, 65009, 65014, 65019, + 65024, 65029, 65034, 65039, 65044, 65049, 65054, 65059, 65065, 65070, + 65075, 65080, 65085, 65089, 65094, 65098, 65103, 65108, 65113, 65118, + 65122, 65127, 65131, 65136, 65141, 65146, 65151, 65156, 65161, 65166, + 65171, 65176, 65181, 65186, 65191, 65195, 65200, 65205, 65210, 65215, + 65220, 65224, 65230, 65235, 65241, 65246, 65250, 65255, 65260, 65265, + 65270, 65276, 65281, 65286, 65291, 65296, 65301, 65306, 65311, 0, 0, + 65317, 65325, 65333, 65340, 65347, 65352, 65359, 65365, 65370, 65374, + 65377, 65381, 65384, 65388, 65391, 65395, 65398, 65402, 65405, 65408, + 65412, 65416, 65420, 65424, 65428, 65432, 65436, 65440, 65444, 65447, + 65451, 65455, 65459, 65463, 65467, 65471, 65475, 65479, 65483, 65487, + 65491, 65495, 65499, 65504, 65508, 65512, 65516, 65520, 65523, 65527, + 65530, 65534, 65538, 65542, 65546, 65549, 65553, 65556, 65560, 65564, + 65568, 65572, 65576, 65580, 65584, 65588, 65592, 65596, 65600, 65604, + 65607, 65611, 65615, 65619, 65623, 65627, 65630, 65635, 65639, 65644, + 65648, 65651, 65655, 65659, 65663, 65667, 65672, 65676, 65680, 65684, + 65688, 65692, 65696, 65700, 65705, 65709, 65713, 65717, 65721, 65725, + 65732, 65736, 65742, 0, 0, 0, 0, 0, 65747, 65752, 65757, 65762, 65767, + 65772, 65777, 65782, 65786, 65791, 65796, 65801, 65806, 65811, 65816, + 65821, 65826, 65831, 65835, 65840, 65845, 65850, 65854, 65858, 65862, + 65867, 65872, 65877, 65882, 65887, 65892, 65897, 65902, 65907, 65912, + 65916, 65920, 65925, 65930, 65935, 65940, 65945, 65952, 0, 65957, 65961, + 65965, 65969, 65973, 65977, 65981, 65985, 65989, 65993, 65997, 66001, + 66005, 66009, 66013, 66017, 66021, 66025, 66029, 66033, 66037, 66041, + 66045, 66049, 66053, 66057, 66061, 66065, 66069, 66073, 66077, 66080, + 66084, 66087, 66091, 66095, 66098, 66102, 66106, 66109, 66113, 66117, + 66121, 66125, 66128, 66132, 66136, 66140, 66144, 66148, 66152, 66155, + 66158, 66162, 66166, 66170, 66174, 66178, 66182, 66186, 66190, 66194, + 66198, 66202, 66206, 66210, 66214, 66218, 66222, 66226, 66230, 66234, + 66238, 66242, 66246, 66250, 66254, 66258, 66262, 66266, 66270, 66274, + 66278, 66282, 66286, 66290, 66294, 66298, 66302, 66306, 66310, 66314, + 66318, 66322, 0, 66326, 66332, 66338, 66343, 66348, 66353, 66359, 66365, + 66370, 66376, 66382, 66388, 66394, 66400, 66406, 66412, 66418, 66423, + 66428, 66433, 66438, 66443, 66448, 66453, 66458, 66463, 66468, 66473, + 66478, 66483, 66488, 66493, 66498, 66503, 66508, 66513, 66518, 66524, + 66530, 66536, 66542, 66547, 66552, 66557, 66563, 66568, 66573, 66578, + 66583, 66588, 66593, 66598, 66603, 66608, 66613, 66618, 66623, 66628, + 66633, 66638, 66643, 66648, 66653, 66658, 66663, 66668, 66673, 66678, + 66683, 66688, 66693, 66698, 66703, 66708, 66713, 66718, 66723, 66728, + 66733, 66738, 66743, 66748, 66753, 66758, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 66763, 66768, 66773, 66778, 66782, 66787, 66791, 66796, 66801, + 66806, 66811, 66816, 66820, 66825, 66830, 66835, 66840, 66844, 66848, + 66852, 66856, 66860, 66864, 66868, 66872, 66876, 66880, 66884, 66888, + 66892, 66896, 66901, 66906, 66911, 66916, 66921, 66926, 66931, 66936, + 66941, 66946, 66951, 66956, 66961, 66966, 66971, 66978, 0, 66986, 66990, + 66994, 66998, 67002, 67006, 67010, 67014, 67018, 67022, 67027, 67032, + 67037, 67042, 67047, 67052, 67057, 67062, 67067, 67072, 67077, 67082, + 67087, 67092, 67097, 67102, 67107, 67112, 67117, 67122, 67127, 67132, + 67137, 67142, 67147, 67152, 67157, 67162, 67167, 67172, 67177, 67186, + 67195, 67204, 67213, 67222, 67231, 67240, 67249, 67252, 67257, 67262, + 67267, 67272, 67277, 67282, 67287, 67292, 67297, 67301, 67306, 67311, + 67316, 67321, 67326, 67330, 67334, 67338, 67342, 67346, 67350, 67354, + 67358, 67362, 67366, 67370, 67374, 67378, 67382, 67387, 67392, 67397, + 67402, 67407, 67412, 67417, 67422, 67427, 67432, 67437, 67442, 67447, + 67452, 67459, 67466, 67471, 67476, 67480, 67484, 67488, 67492, 67496, + 67500, 67504, 67508, 67512, 67517, 67522, 67527, 67532, 67537, 67542, + 67547, 67552, 67557, 67562, 67567, 67572, 67577, 67582, 67587, 67592, + 67597, 67602, 67607, 67612, 67617, 67622, 67627, 67632, 67637, 67642, + 67647, 67652, 67657, 67662, 67667, 67671, 67676, 67681, 67686, 67691, + 67696, 67701, 67706, 67711, 67716, 67721, 67726, 67731, 67735, 67740, + 67745, 67750, 67755, 67760, 67765, 67770, 67775, 67780, 67784, 67791, + 67798, 67805, 67812, 67819, 67826, 67833, 67840, 67847, 67854, 67861, + 67868, 67871, 67874, 67877, 67882, 67885, 67888, 67891, 67894, 67897, + 67900, 67904, 67908, 67912, 67916, 67919, 67923, 67927, 67931, 67935, + 67939, 67943, 67947, 67951, 67954, 67957, 67961, 67965, 67969, 67973, + 67976, 67980, 67984, 67988, 67992, 67995, 67999, 68003, 68007, 68011, + 68014, 68018, 68022, 68025, 68029, 68033, 68037, 68041, 68045, 68049, + 68053, 68057, 68064, 68067, 68070, 68073, 68076, 68079, 68082, 68085, + 68088, 68091, 68094, 68097, 68100, 68103, 68106, 68109, 68112, 68115, + 68118, 68121, 68124, 68127, 68130, 68133, 68136, 68139, 68142, 68145, + 68148, 68151, 68154, 68157, 68160, 68163, 68166, 68169, 68172, 68175, + 68178, 68181, 68184, 68187, 68190, 68193, 68196, 68199, 68202, 68205, + 68208, 68211, 68214, 68217, 68220, 68223, 68226, 68229, 68232, 68235, + 68238, 68241, 68244, 68247, 68250, 68253, 68256, 68259, 68262, 68265, + 68268, 68271, 68274, 68277, 68280, 68283, 68286, 68289, 68292, 68295, + 68298, 68301, 68304, 68307, 68310, 68313, 68316, 68319, 68322, 68325, + 68328, 68337, 68345, 68353, 68361, 68369, 68377, 68385, 68393, 68401, + 68409, 68418, 68427, 68436, 68445, 68454, 68463, 68472, 68481, 68490, + 68499, 68508, 68517, 68526, 68535, 68544, 68547, 68550, 68553, 68555, + 68558, 68561, 68564, 68569, 68574, 68577, 68584, 68591, 68598, 68605, + 68608, 68613, 68615, 68619, 68621, 68623, 68626, 68629, 68632, 68635, + 68638, 68641, 68644, 68649, 68654, 68657, 68660, 68663, 68666, 68669, + 68672, 68675, 68679, 68682, 68685, 68688, 68691, 68694, 68699, 68702, + 68705, 68708, 68713, 68718, 68723, 68728, 68733, 68738, 68743, 68748, + 68754, 68762, 68764, 68767, 68770, 68773, 68776, 68782, 68790, 68793, + 68796, 68801, 68804, 68807, 68810, 68815, 68818, 68821, 68826, 68829, + 68832, 68837, 68840, 68843, 68848, 68853, 68858, 68861, 68864, 68867, + 68870, 68876, 68879, 68882, 68885, 68887, 68890, 68893, 68896, 68901, + 68904, 68907, 68910, 68913, 68916, 68921, 68924, 68927, 68930, 68933, + 68936, 68939, 68942, 68945, 68948, 68954, 68959, 68967, 68975, 68983, + 68991, 68999, 69007, 69015, 69023, 69031, 69040, 69049, 69058, 69067, + 69076, 69085, 69094, 69103, 69112, 69121, 69130, 69139, 69148, 69157, + 69166, 69175, 69184, 69193, 69202, 69211, 69220, 69229, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33392, 33398, 33404, 33408, 33412, 33416, - 33420, 33426, 33430, 33436, 33440, 33446, 33452, 33460, 33466, 33474, - 33478, 33482, 33486, 33492, 33495, 33501, 33505, 33511, 33515, 33519, - 33525, 33529, 33535, 33539, 33545, 33553, 33561, 33569, 33575, 33579, - 33585, 33589, 33595, 33598, 33601, 33607, 33611, 33617, 33620, 33623, - 33626, 33629, 33633, 33639, 33645, 33648, 33651, 33655, 33660, 33665, - 33672, 33677, 33684, 33691, 33700, 33707, 33716, 33721, 33728, 33735, - 33744, 33749, 33756, 33761, 33767, 33773, 33779, 33785, 33791, 33797, - 33803, 0, 0, 0, 33809, 33813, 33816, 33819, 33822, 33825, 33828, 33831, - 33834, 33837, 33840, 33843, 33846, 33849, 33854, 33859, 33864, 33867, - 33872, 33877, 33882, 33887, 33894, 33899, 33904, 33909, 33914, 33921, - 33927, 33933, 33939, 33945, 33951, 33960, 33969, 33975, 33981, 33990, - 33999, 34008, 34017, 34026, 34035, 34044, 34053, 34062, 34067, 0, 34072, - 34077, 34082, 34087, 34091, 34095, 34099, 34104, 34108, 34112, 34117, - 34121, 34126, 34131, 34136, 34141, 34146, 34151, 34156, 34161, 34166, - 34170, 34174, 34179, 34184, 34189, 34193, 34197, 34201, 34205, 34210, - 34214, 34219, 34223, 34229, 34235, 34241, 34247, 34253, 34259, 34265, - 34271, 34277, 34282, 34287, 34294, 34302, 34307, 34312, 34317, 34321, - 34325, 34329, 34333, 34337, 34341, 34345, 34349, 34353, 34357, 34362, - 34367, 34372, 34378, 34384, 34388, 34394, 34398, 34404, 34410, 34415, - 34422, 34426, 34432, 34436, 34442, 34447, 34454, 34461, 34466, 34473, - 34478, 34483, 34487, 34493, 34497, 34503, 34510, 34517, 34521, 34527, - 34533, 34537, 34543, 34548, 34552, 34558, 34563, 34568, 34573, 34578, - 34582, 34586, 34591, 34596, 34603, 34609, 34614, 34621, 34626, 34633, - 34638, 34647, 34653, 34659, 34663, 0, 0, 0, 0, 0, 0, 0, 0, 34667, 34676, - 34683, 34690, 34697, 34701, 34706, 34711, 34716, 34721, 34726, 34731, - 34736, 34741, 34746, 34751, 34756, 34761, 34765, 34769, 34774, 34779, - 34784, 34789, 34794, 34799, 34803, 34808, 34813, 34818, 34823, 34827, - 34831, 34835, 34839, 34844, 34849, 34853, 34858, 34863, 34867, 34873, - 34879, 34885, 34890, 34895, 34901, 34906, 34912, 34917, 34923, 34929, - 34934, 34940, 34946, 34951, 34957, 34963, 34969, 34974, 0, 0, 0, 34979, - 34985, 34995, 35001, 35009, 35015, 35020, 35024, 35028, 35032, 35036, - 35040, 35044, 35048, 35052, 0, 0, 0, 35056, 35061, 35066, 35071, 35078, - 35084, 35090, 35096, 35102, 35108, 35114, 35120, 35126, 35132, 35138, - 35145, 35152, 35159, 35166, 35173, 35180, 35187, 35194, 35201, 35208, - 35215, 35222, 35229, 35236, 35243, 35250, 35257, 35264, 35271, 35278, - 35285, 35292, 35299, 35306, 35313, 35320, 35327, 35334, 35341, 35349, - 35357, 35365, 35371, 35377, 35383, 35391, 35400, 35407, 35414, 35420, - 35427, 35434, 35441, 35449, 35456, 0, 0, 0, 0, 0, 0, 0, 35463, 35470, - 35477, 35484, 35491, 35498, 35505, 35512, 35519, 35526, 35533, 35540, - 35547, 35554, 35561, 35568, 35575, 35582, 35589, 35596, 35603, 35610, - 35617, 35624, 35631, 35638, 35645, 35652, 35659, 35666, 35673, 35680, - 35687, 35694, 35701, 35708, 35715, 35722, 35729, 35736, 35743, 35750, - 35758, 0, 0, 35765, 35772, 35780, 35788, 35796, 35804, 35812, 35820, - 35830, 35840, 35850, 0, 0, 0, 0, 0, 0, 0, 0, 35860, 35865, 35870, 35875, - 35880, 35889, 35900, 35909, 35920, 35926, 35939, 35945, 35952, 35959, - 35964, 35970, 35976, 35987, 35996, 36003, 36010, 36019, 36026, 36035, - 36045, 36055, 36062, 36069, 36076, 36086, 36091, 36099, 36105, 36113, - 36122, 36127, 36134, 36140, 36145, 36150, 36155, 36161, 36168, 0, 0, 0, - 0, 0, 36176, 36181, 36187, 36193, 36201, 36207, 36213, 36219, 36224, - 36231, 36236, 36242, 36248, 36256, 36262, 36270, 36275, 36282, 36288, - 36296, 36304, 36310, 36316, 36323, 36330, 36336, 36343, 36349, 36355, - 36360, 36366, 36374, 36382, 36388, 36394, 36400, 36406, 36414, 36418, - 36424, 36430, 36436, 36442, 36448, 36454, 36458, 36463, 36468, 36475, - 36480, 36484, 36490, 36495, 36500, 36504, 36509, 36514, 36518, 36523, - 36528, 36535, 36539, 36544, 36549, 36553, 36558, 36562, 36567, 36571, - 36576, 36581, 36587, 36592, 36597, 36601, 36606, 36612, 36619, 36624, - 36629, 36634, 36639, 36644, 36648, 36654, 36661, 36668, 36673, 36678, - 36682, 36688, 36694, 36699, 36704, 36709, 36715, 36720, 36726, 36731, - 36737, 36743, 36749, 36756, 36763, 36770, 36777, 36784, 36791, 36796, - 36804, 36813, 36822, 36831, 36840, 36849, 36858, 36870, 36879, 36888, - 36897, 36903, 36908, 36915, 36923, 36931, 36938, 36945, 36952, 36959, - 36967, 36976, 36985, 36994, 37003, 37012, 37021, 37030, 37039, 37048, - 37057, 37066, 37075, 37084, 37093, 37101, 37110, 37121, 37130, 37141, - 37154, 37163, 37172, 37182, 37191, 37199, 37208, 37214, 37219, 37227, - 37232, 37240, 37245, 37254, 37260, 37266, 37273, 37278, 37283, 37291, - 37299, 37308, 37317, 37322, 37329, 37339, 37347, 37356, 37362, 37368, - 37373, 37380, 37385, 37394, 37399, 37404, 37409, 37416, 37422, 37427, - 37436, 37444, 37449, 37454, 37461, 37468, 37472, 37476, 37479, 37482, - 37485, 37488, 37491, 37494, 37501, 37504, 37507, 37512, 37516, 37520, - 37524, 37528, 37532, 37542, 37548, 37554, 37560, 37568, 37576, 37582, - 37588, 37595, 37601, 37606, 37612, 37619, 37625, 37632, 37638, 37646, - 37652, 37659, 37665, 37671, 37677, 37683, 37689, 37695, 37706, 37716, - 37722, 37728, 37738, 37744, 37752, 37760, 37768, 37773, 37778, 37784, - 37789, 37797, 37803, 37807, 37814, 37821, 37826, 37835, 37843, 37851, - 37858, 37865, 37872, 37879, 37887, 37895, 37906, 37917, 37925, 37933, - 37941, 37949, 37958, 37967, 37975, 37983, 37992, 38001, 38012, 38023, - 38034, 38045, 38054, 38063, 38072, 38081, 38092, 38103, 38111, 38119, - 38127, 38135, 38143, 38151, 38159, 38167, 38175, 38183, 38191, 38199, - 38208, 38217, 38226, 38235, 38246, 38257, 38265, 38273, 38281, 38289, - 38298, 38307, 38315, 38323, 38335, 38347, 38356, 38365, 38374, 38383, - 38391, 38399, 38407, 38415, 38423, 38431, 38439, 38447, 38455, 38463, - 38472, 38481, 38490, 38499, 38509, 38519, 38529, 38539, 38549, 38559, - 38569, 38579, 38587, 38595, 38603, 38611, 38619, 38627, 38635, 38643, - 38655, 38667, 38676, 38685, 38693, 38701, 38709, 38717, 38728, 38739, - 38750, 38761, 38773, 38785, 38793, 38801, 38809, 38817, 38826, 38835, - 38844, 38853, 38861, 38869, 38877, 38885, 38893, 38901, 38911, 38921, - 38931, 38941, 38949, 38957, 38965, 38973, 38981, 38989, 38997, 39005, - 39013, 39021, 39029, 39037, 39045, 39053, 39061, 39069, 39077, 39085, - 39093, 39101, 39109, 39117, 39125, 39133, 39142, 39151, 39160, 39168, - 39177, 39186, 39195, 39204, 39214, 39223, 39230, 39235, 39242, 39249, - 39257, 39265, 39275, 39285, 39295, 39305, 39316, 39327, 39337, 39347, - 39357, 39367, 39377, 39387, 39397, 39407, 39418, 39429, 39439, 39449, - 39459, 39469, 39477, 39485, 39494, 39503, 39511, 39519, 39530, 39541, - 39552, 39563, 39575, 39587, 39598, 39609, 39620, 39631, 39640, 39649, - 39657, 39665, 39672, 39679, 39687, 39695, 39705, 39715, 39725, 39735, - 39746, 39757, 39767, 39777, 39787, 39797, 39807, 39817, 39827, 39837, - 39848, 39859, 39869, 39879, 39889, 39899, 39906, 39913, 39921, 39929, - 39939, 39949, 39959, 39969, 39980, 39991, 40001, 40011, 40021, 40031, - 40039, 40047, 40055, 40063, 40072, 40081, 40089, 40097, 40104, 40111, - 40118, 40125, 40133, 40141, 40149, 40157, 40168, 40179, 40190, 40201, - 40212, 40223, 40231, 40239, 40250, 40261, 40272, 40283, 40294, 40305, - 40313, 40321, 40332, 40343, 40354, 0, 0, 40365, 40373, 40381, 40392, - 40403, 40414, 0, 0, 40425, 40433, 40441, 40452, 40463, 40474, 40485, - 40496, 40507, 40515, 40523, 40534, 40545, 40556, 40567, 40578, 40589, - 40597, 40605, 40616, 40627, 40638, 40649, 40660, 40671, 40679, 40687, - 40698, 40709, 40720, 40731, 40742, 40753, 40761, 40769, 40780, 40791, - 40802, 0, 0, 40813, 40821, 40829, 40840, 40851, 40862, 0, 0, 40873, - 40881, 40889, 40900, 40911, 40922, 40933, 40944, 0, 40955, 0, 40963, 0, - 40974, 0, 40985, 40996, 41004, 41012, 41023, 41034, 41045, 41056, 41067, - 41078, 41086, 41094, 41105, 41116, 41127, 41138, 41149, 41160, 41168, - 41176, 41184, 41192, 41200, 41208, 41216, 41224, 41232, 41240, 41248, - 41256, 41264, 0, 0, 41272, 41283, 41294, 41308, 41322, 41336, 41350, - 41364, 41378, 41389, 41400, 41414, 41428, 41442, 41456, 41470, 41484, - 41495, 41506, 41520, 41534, 41548, 41562, 41576, 41590, 41601, 41612, - 41626, 41640, 41654, 41668, 41682, 41696, 41707, 41718, 41732, 41746, - 41760, 41774, 41788, 41802, 41813, 41824, 41838, 41852, 41866, 41880, - 41894, 41908, 41916, 41924, 41935, 41943, 0, 41954, 41962, 41973, 41981, - 41989, 41997, 42005, 42013, 42016, 42019, 42022, 42025, 42031, 42042, - 42050, 0, 42061, 42069, 42080, 42088, 42096, 42104, 42112, 42120, 42126, - 42132, 42138, 42146, 42154, 42165, 0, 0, 42176, 42184, 42195, 42203, - 42211, 42219, 0, 42227, 42233, 42239, 42245, 42253, 42261, 42272, 42283, - 42291, 42299, 42307, 42318, 42326, 42334, 42342, 42350, 42358, 42364, - 42370, 0, 0, 42373, 42384, 42392, 0, 42403, 42411, 42422, 42430, 42438, - 42446, 42454, 42462, 42465, 0, 42468, 42472, 42476, 42480, 42484, 42488, - 42492, 42496, 42500, 42504, 42508, 42512, 42518, 42524, 42530, 42533, - 42536, 42538, 42542, 42546, 42550, 42554, 42557, 42561, 42565, 42571, - 42577, 42584, 42591, 42596, 42601, 42607, 42613, 42615, 42618, 42620, - 42624, 42628, 42632, 42636, 42640, 42644, 42648, 42652, 42656, 42662, - 42666, 42670, 42676, 42681, 42688, 42690, 42693, 42697, 42701, 42706, - 42712, 42714, 42723, 42732, 42735, 42739, 42741, 42743, 42745, 42749, - 42755, 42757, 42761, 42765, 42772, 42779, 42783, 42788, 42793, 42798, - 42803, 42807, 42811, 42814, 42818, 42822, 42829, 42834, 42838, 42842, - 42847, 42851, 42855, 42860, 42865, 42869, 42873, 42877, 42879, 42884, - 42889, 42893, 42897, 42901, 42905, 0, 42909, 42913, 42917, 42923, 42929, - 42935, 42941, 42948, 42955, 42960, 42965, 42969, 0, 0, 42975, 42978, - 42981, 42984, 42987, 42990, 42993, 42997, 43001, 43006, 43011, 43016, - 43023, 43027, 43030, 43033, 43036, 43039, 43042, 43045, 43048, 43051, - 43054, 43058, 43062, 43067, 43072, 0, 43077, 43083, 43089, 43095, 43102, - 43109, 43116, 43123, 43129, 43136, 43143, 43150, 43157, 0, 0, 0, 43164, - 43167, 43170, 43173, 43178, 43181, 43184, 43187, 43190, 43193, 43196, - 43201, 43204, 43207, 43210, 43213, 43216, 43221, 43224, 43227, 43230, - 43233, 43236, 43241, 43244, 43247, 43252, 43257, 43261, 43264, 43267, - 43270, 43273, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43276, 43281, - 43286, 43293, 43301, 43306, 43311, 43315, 43319, 43324, 43331, 43338, - 43342, 43347, 43352, 43357, 43362, 43369, 43374, 43379, 43384, 43393, - 43400, 43407, 43411, 43416, 43422, 43427, 43434, 43442, 43450, 43454, - 43458, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43462, 43466, 43473, - 43478, 43482, 43487, 43491, 43495, 43499, 43501, 43505, 43509, 43513, - 43518, 43523, 43527, 43535, 43538, 43542, 43545, 43548, 43554, 43559, - 43562, 43568, 43572, 43577, 43582, 43585, 43589, 43593, 43597, 43599, - 43602, 43605, 43609, 43611, 43616, 43619, 43622, 43627, 43632, 43638, - 43641, 43644, 43648, 43653, 43656, 43659, 43662, 43666, 43670, 43674, - 43677, 43679, 43682, 43685, 43688, 43692, 43697, 43700, 43705, 43710, - 43715, 43720, 43726, 43731, 43735, 43740, 43745, 43751, 43757, 43762, - 43767, 43773, 43777, 43780, 43783, 43785, 43789, 43795, 43802, 43809, - 43816, 43823, 43830, 43837, 43844, 43851, 43859, 43866, 43874, 43881, - 43888, 43896, 43904, 43909, 43914, 43919, 43924, 43929, 43934, 43939, - 43944, 43949, 43954, 43960, 43966, 43972, 43978, 43985, 43993, 43999, - 44005, 44011, 44017, 44023, 44029, 44035, 44041, 44047, 44053, 44060, - 44067, 44074, 44081, 44089, 44098, 44105, 44116, 44123, 44130, 44139, - 44146, 44155, 44164, 44171, 44179, 44187, 44190, 0, 0, 0, 0, 44193, - 44195, 44198, 44200, 44203, 44206, 44209, 44213, 44217, 44222, 44227, - 44231, 44235, 44239, 44243, 44248, 44254, 44259, 44265, 44270, 44275, - 44280, 44286, 44291, 44297, 44303, 44307, 44311, 44316, 44321, 44326, - 44331, 44336, 44344, 44352, 44360, 44368, 44375, 44383, 44390, 44397, - 44404, 44414, 44421, 44428, 44435, 44442, 44450, 44458, 44465, 44472, - 44480, 44488, 44493, 44501, 44506, 44511, 44517, 44522, 44528, 44535, - 44542, 44547, 44553, 44558, 44561, 44565, 44568, 44572, 44576, 44580, - 44585, 44590, 44596, 44602, 44606, 44610, 44614, 44618, 44624, 44630, - 44634, 44639, 44643, 44648, 44652, 44656, 44659, 44663, 44666, 44670, - 44677, 44685, 44697, 44708, 44713, 44722, 44729, 44736, 44744, 44748, - 44754, 44762, 44766, 44771, 44776, 44782, 44788, 44794, 44801, 44805, - 44809, 44814, 44817, 44819, 44823, 44827, 44835, 44839, 44841, 44843, - 44847, 44855, 44860, 44866, 44876, 44883, 44888, 44892, 44896, 44900, - 44903, 44906, 44909, 44913, 44917, 44921, 44925, 44929, 44932, 44936, - 44940, 44943, 44945, 44948, 44950, 44954, 44958, 44960, 44966, 44969, - 44974, 44978, 44982, 44984, 44986, 44988, 44991, 44995, 44999, 45003, - 45007, 45011, 45017, 45023, 45025, 45027, 45029, 45031, 45034, 45036, - 45040, 45042, 45046, 45050, 45056, 45060, 45064, 45068, 45072, 45077, - 45084, 45089, 45100, 45111, 45116, 45123, 45132, 45136, 45141, 45144, - 45149, 45153, 45159, 45164, 45177, 45187, 45191, 45195, 45202, 45207, - 45210, 45212, 45215, 45219, 45224, 45231, 45235, 45240, 45245, 45248, - 45253, 45258, 45265, 45272, 45278, 45284, 45293, 45302, 45306, 45310, - 45312, 45317, 45321, 45325, 45334, 45343, 45350, 45357, 45366, 45375, - 45381, 45387, 45395, 45403, 45405, 45407, 45414, 45421, 45428, 45435, - 45441, 45447, 45451, 45455, 45462, 45469, 45477, 45485, 45496, 45507, - 45516, 45525, 45527, 45531, 45535, 45540, 45545, 45554, 45563, 45566, - 45569, 45572, 45575, 45578, 45583, 45587, 45592, 45597, 45600, 45603, - 45606, 45609, 45612, 45616, 45619, 45622, 45625, 45628, 45630, 45632, - 45634, 45636, 45644, 45652, 45658, 45662, 45668, 45678, 45684, 45690, - 45696, 45704, 45714, 45727, 45731, 45735, 45737, 45743, 45745, 45747, - 45749, 45751, 45757, 45760, 45766, 45772, 45776, 45780, 45784, 45787, - 45791, 45795, 45797, 45806, 45815, 45820, 45825, 45831, 45837, 45843, - 45846, 45849, 45852, 45855, 45857, 45863, 45868, 45873, 45879, 45885, - 45894, 45903, 45910, 45917, 45924, 45931, 45941, 45951, 45962, 45973, - 45984, 45995, 46004, 46013, 46022, 46031, 46039, 46051, 46063, 46079, - 46082, 46088, 46094, 46100, 46108, 46123, 46139, 46145, 46151, 46158, - 46164, 46173, 46180, 46194, 46209, 46214, 46220, 46228, 46231, 46234, - 46236, 46239, 46242, 46244, 46246, 46250, 46253, 46256, 46259, 46262, - 46267, 46272, 46277, 46282, 46287, 46290, 46292, 46294, 46296, 46300, - 46304, 46308, 46314, 46318, 46320, 46322, 46327, 46332, 46337, 46342, - 46347, 46352, 46354, 46356, 46366, 46370, 46376, 46385, 46387, 46393, - 46399, 46406, 46410, 46412, 46416, 46418, 46422, 46426, 46430, 46432, - 46434, 46436, 46443, 46452, 46461, 46470, 46479, 46488, 46497, 46506, - 46515, 46523, 46531, 46540, 46549, 46558, 46567, 46575, 46583, 46592, - 46601, 46610, 46620, 46629, 46639, 46648, 46658, 46667, 46677, 46687, - 46696, 46706, 46715, 46725, 46734, 46744, 46753, 46762, 46771, 46780, - 46789, 46799, 46808, 46817, 46826, 46836, 46845, 46854, 46863, 46872, - 46882, 46892, 46901, 46910, 46918, 46927, 46934, 46943, 46952, 46963, - 46972, 46982, 46992, 46999, 47006, 47013, 47022, 47031, 47040, 47049, - 47056, 47061, 47070, 47076, 47079, 47086, 47089, 47094, 47099, 47102, - 47105, 47113, 47116, 47121, 47124, 47132, 47137, 47145, 47148, 47151, - 47154, 47159, 47164, 47167, 47170, 47178, 47181, 47188, 47195, 47199, - 47203, 47208, 47213, 47218, 47223, 47228, 47233, 47238, 47243, 47250, - 47256, 47263, 47270, 47276, 47283, 47290, 47298, 47305, 47311, 47318, - 47326, 47333, 47337, 47343, 47355, 47367, 47371, 47375, 47380, 47385, - 47396, 47400, 47405, 47410, 47416, 47422, 47428, 47434, 47443, 47452, - 47460, 47471, 47482, 47490, 47501, 47512, 47520, 47531, 47542, 47550, - 47558, 47568, 47578, 47581, 47584, 47587, 47592, 47596, 47602, 47609, - 47616, 47624, 47631, 47635, 47639, 47643, 47647, 47649, 47653, 47657, - 47663, 47669, 47677, 47685, 47688, 47695, 47697, 47699, 47703, 47707, - 47712, 47718, 47724, 47730, 47736, 47745, 47754, 47763, 47767, 47769, - 47773, 47780, 47787, 47794, 47801, 47808, 47811, 47816, 47822, 47825, - 47830, 47835, 47840, 47845, 47849, 47856, 47863, 47870, 47877, 47881, - 47885, 47889, 47893, 47899, 47905, 47910, 47916, 47922, 47928, 47934, - 47942, 47949, 47956, 47963, 47970, 47976, 47982, 47991, 47995, 48002, - 48006, 48010, 48016, 48022, 48028, 48034, 48038, 48042, 48045, 48049, - 48053, 48060, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 48067, 48070, 48074, 48078, 48084, 48090, 48096, 48104, - 48111, 48115, 48123, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 48128, 48131, 48134, 48137, 48140, 48143, 48146, 48149, - 48152, 48155, 48159, 48163, 48167, 48171, 48175, 48179, 48183, 48187, - 48191, 48195, 48199, 48202, 48205, 48208, 48211, 48214, 48217, 48220, - 48223, 48226, 48230, 48234, 48238, 48242, 48246, 48250, 48254, 48258, - 48262, 48266, 48270, 48276, 48282, 48288, 48295, 48302, 48309, 48316, - 48323, 48330, 48337, 48344, 48351, 48358, 48365, 48372, 48379, 48386, - 48393, 48400, 48407, 48412, 48418, 48424, 48430, 48435, 48441, 48447, - 48453, 48458, 48464, 48470, 48475, 48481, 48487, 48492, 48498, 48504, - 48509, 48515, 48521, 48526, 48532, 48538, 48544, 48550, 48556, 48561, - 48567, 48573, 48579, 48584, 48590, 48596, 48602, 48607, 48613, 48619, - 48624, 48630, 48636, 48641, 48647, 48653, 48658, 48664, 48670, 48675, - 48681, 48687, 48693, 48699, 48705, 48710, 48716, 48722, 48728, 48733, - 48739, 48745, 48751, 48756, 48762, 48768, 48773, 48779, 48785, 48790, - 48796, 48802, 48807, 48813, 48819, 48824, 48830, 48836, 48842, 48848, - 48854, 48858, 48864, 48870, 48876, 48882, 48888, 48894, 48900, 48906, - 48912, 48918, 48922, 48926, 48930, 48934, 48938, 48942, 48946, 48950, - 48954, 48959, 48965, 48970, 48975, 48980, 48985, 48994, 49003, 49012, - 49021, 49030, 49039, 49048, 49057, 49063, 49071, 49079, 49085, 49092, - 49100, 49108, 49115, 49121, 49129, 49137, 49143, 49150, 49158, 49166, - 49173, 49179, 49187, 49196, 49205, 49213, 49222, 49231, 49237, 49244, - 49252, 49261, 49270, 49278, 49287, 49296, 49303, 49310, 49319, 49328, - 49337, 49346, 49355, 49364, 49371, 49378, 49387, 49396, 49405, 49414, - 49423, 49432, 49439, 49446, 49455, 49464, 49473, 49483, 49493, 49502, - 49512, 49522, 49532, 49542, 49552, 49562, 49571, 49580, 49587, 49595, - 49603, 49611, 49619, 49624, 49629, 49638, 49646, 49652, 49661, 49669, - 49676, 49685, 49693, 49699, 49708, 49716, 49723, 49732, 49740, 49746, - 49755, 49763, 49770, 49780, 49789, 49796, 49806, 49815, 49822, 49832, - 49841, 49848, 49856, 49865, 49874, 49882, 49893, 49903, 49910, 49915, - 49920, 49924, 49929, 49934, 49939, 49943, 49948, 49955, 49963, 49970, - 49978, 49982, 49988, 49994, 50000, 50004, 50011, 50017, 50024, 50028, - 50035, 50041, 50048, 50052, 50058, 50064, 50070, 50074, 50077, 50081, - 50085, 50091, 50097, 50102, 50106, 50111, 50121, 50128, 50139, 50149, - 50153, 50161, 50171, 50174, 50177, 50184, 50192, 50198, 50203, 50211, - 50220, 50229, 50237, 50241, 50245, 50248, 50251, 50255, 50259, 50262, - 50265, 50270, 50275, 50281, 50287, 50292, 50297, 50303, 50309, 50314, - 50319, 50324, 50329, 50335, 50341, 50346, 50351, 50357, 50363, 50368, - 50373, 50376, 50379, 50388, 50390, 50392, 50395, 50399, 50405, 50407, - 50410, 50417, 50424, 50431, 50438, 50447, 50460, 50465, 50470, 50474, - 50479, 50486, 50493, 50501, 50509, 50517, 50525, 50529, 50533, 50538, - 50543, 50548, 50553, 50556, 50562, 50568, 50577, 50586, 50594, 50602, - 50611, 50620, 50624, 50631, 50638, 50645, 50652, 50660, 50668, 50676, - 50684, 50688, 50692, 50696, 50701, 50706, 50712, 50718, 50722, 50728, - 50730, 50732, 50734, 50736, 50739, 50742, 50744, 50746, 50748, 50752, - 50756, 50758, 50760, 50763, 50766, 50770, 50776, 50782, 50784, 50791, - 50795, 50800, 50805, 50807, 50817, 50823, 50829, 50835, 50841, 50847, - 50853, 50858, 50861, 50864, 50867, 50869, 50871, 50875, 50879, 50884, - 50889, 50894, 50897, 50901, 50906, 50909, 50913, 50918, 50923, 50928, - 50933, 50938, 50943, 50948, 50953, 50958, 50963, 50968, 50973, 50979, - 50985, 50991, 50993, 50996, 50998, 51001, 51003, 51005, 51007, 51009, - 51011, 51013, 51015, 51017, 51019, 51021, 51023, 51025, 51027, 51029, - 51031, 51033, 51035, 51040, 51045, 51050, 51055, 51060, 51065, 51070, - 51075, 51080, 51085, 51090, 51095, 51100, 51105, 51110, 51115, 51120, - 51125, 51130, 51135, 51139, 51143, 51147, 51153, 51159, 51164, 51169, - 51174, 51180, 51186, 51191, 51199, 51207, 51215, 51223, 51231, 51239, - 51247, 51255, 51261, 51266, 51271, 51276, 51279, 51283, 51287, 51291, - 51295, 51299, 51303, 51309, 51316, 51323, 51331, 51336, 51341, 51348, - 51355, 51362, 51369, 51372, 51375, 51380, 51382, 51386, 51391, 51393, - 51395, 51397, 51399, 51404, 51407, 51409, 51414, 51420, 51427, 51430, - 51434, 51439, 51444, 51452, 51458, 51464, 51476, 51483, 51491, 51496, - 51501, 51507, 51510, 51513, 51518, 51520, 51524, 51526, 51528, 51530, - 51532, 51534, 51536, 51541, 51543, 51545, 51547, 51549, 51553, 51555, - 51558, 51563, 51568, 51573, 51578, 51584, 51590, 51592, 51595, 51602, - 51608, 51614, 51621, 51625, 51629, 51631, 51633, 51637, 51643, 51648, - 51650, 51654, 51663, 51671, 51679, 51685, 51691, 51696, 51702, 51707, - 51710, 51724, 51727, 51732, 51737, 51743, 51753, 51755, 51761, 51767, - 51771, 51778, 51782, 51784, 51786, 51790, 51796, 51801, 51807, 51809, - 51815, 51817, 51823, 51825, 51827, 51832, 51834, 51838, 51843, 51845, - 51850, 51855, 51859, 51866, 51876, 51881, 51886, 51889, 51894, 51897, - 51902, 51907, 51911, 51913, 51915, 51919, 51923, 51927, 51931, 51935, - 51937, 51941, 51944, 51947, 51950, 51954, 51958, 51963, 51967, 51972, - 51977, 51981, 51987, 51994, 51997, 52003, 52008, 52012, 52017, 52023, - 52029, 52036, 52042, 52049, 52056, 52058, 52065, 52069, 52076, 52082, - 52087, 52093, 52097, 52102, 52105, 52111, 52117, 52124, 52132, 52139, - 52148, 52158, 52165, 52171, 52175, 52183, 52188, 52197, 52200, 52203, - 52212, 52223, 52230, 52232, 52238, 52243, 52245, 52248, 52252, 52260, - 52269, 52272, 52277, 52283, 52290, 52297, 52304, 52311, 52317, 52323, - 52329, 52337, 52342, 52345, 52349, 52352, 52363, 52373, 52383, 52392, - 52403, 52413, 52422, 52428, 52436, 52440, 52448, 52452, 52460, 52467, - 52474, 52483, 52492, 52502, 52512, 52522, 52532, 52541, 52550, 52560, - 52570, 52579, 52588, 52595, 52602, 52609, 52616, 52623, 52630, 52637, - 52644, 52651, 52659, 52665, 52671, 52677, 52683, 52689, 52695, 52701, - 52707, 52713, 52720, 52728, 52736, 52744, 52752, 52760, 52768, 52776, - 52784, 52792, 52801, 52806, 52809, 52813, 52817, 52823, 52826, 52831, - 52837, 52842, 52846, 52851, 52857, 52864, 52867, 52874, 52881, 52885, - 52894, 52903, 52908, 52914, 52919, 52924, 52931, 52938, 52945, 52952, - 52960, 52964, 52972, 52977, 52981, 52988, 52992, 52998, 53006, 53011, - 53018, 53022, 53027, 53031, 53036, 53040, 53045, 53050, 53059, 53061, - 53065, 53069, 53076, 53083, 53089, 53097, 53103, 53110, 53115, 53118, - 53123, 53128, 53133, 53141, 53145, 53152, 53159, 53166, 53171, 53176, - 53182, 53187, 53192, 53198, 53203, 53206, 53210, 53214, 53221, 53231, - 53236, 53245, 53254, 53260, 53266, 53272, 53278, 53284, 53290, 53297, - 53304, 53313, 53322, 53328, 53334, 53339, 53344, 53351, 53358, 53364, - 53367, 53370, 53374, 53378, 53382, 53387, 53393, 53399, 53406, 53413, - 53418, 53422, 53426, 53430, 53434, 53438, 53442, 53446, 53450, 53454, - 53458, 53462, 53466, 53470, 53474, 53478, 53482, 53486, 53490, 53494, - 53498, 53502, 53506, 53510, 53514, 53518, 53522, 53526, 53530, 53534, - 53538, 53542, 53546, 53550, 53554, 53558, 53562, 53566, 53570, 53574, - 53578, 53582, 53586, 53590, 53594, 53598, 53602, 53606, 53610, 53614, - 53618, 53622, 53626, 53630, 53634, 53638, 53642, 53646, 53650, 53654, - 53658, 53662, 53666, 53670, 53674, 53678, 53682, 53686, 53690, 53694, - 53698, 53702, 53706, 53710, 53714, 53718, 53722, 53726, 53730, 53734, - 53738, 53742, 53746, 53750, 53754, 53758, 53762, 53766, 53770, 53774, - 53778, 53782, 53786, 53790, 53794, 53798, 53802, 53806, 53810, 53814, - 53818, 53822, 53826, 53830, 53834, 53838, 53842, 53846, 53850, 53854, - 53858, 53862, 53866, 53870, 53874, 53878, 53882, 53886, 53890, 53894, - 53898, 53902, 53906, 53910, 53914, 53918, 53922, 53926, 53930, 53934, - 53938, 53942, 53946, 53950, 53954, 53958, 53962, 53966, 53970, 53974, - 53978, 53982, 53986, 53990, 53994, 53998, 54002, 54006, 54010, 54014, - 54018, 54022, 54026, 54030, 54034, 54038, 54042, 54046, 54050, 54054, - 54058, 54062, 54066, 54070, 54074, 54078, 54082, 54086, 54090, 54094, - 54098, 54102, 54106, 54110, 54114, 54118, 54122, 54126, 54130, 54134, - 54138, 54142, 54146, 54150, 54154, 54158, 54162, 54166, 54170, 54174, - 54178, 54182, 54186, 54190, 54194, 54198, 54202, 54206, 54210, 54214, - 54218, 54222, 54226, 54230, 54234, 54238, 54242, 54246, 54250, 54254, - 54258, 54262, 54266, 54270, 54274, 54278, 54282, 54286, 54290, 54294, - 54298, 54302, 54306, 54310, 54314, 54318, 54322, 54326, 54330, 54334, - 54338, 54342, 54346, 54350, 54354, 54358, 54362, 54366, 54370, 54374, - 54378, 54382, 54386, 54390, 54394, 54398, 54402, 54406, 54410, 54414, - 54418, 54422, 54426, 54430, 54434, 54438, 54442, 54449, 54457, 54463, - 54469, 54476, 54483, 54489, 54495, 54502, 54509, 54514, 54519, 54524, - 54529, 54535, 54541, 54549, 54556, 54561, 54566, 54574, 54583, 54590, - 54600, 54611, 54614, 54617, 54621, 54625, 54631, 54637, 54647, 54657, - 54666, 54675, 54681, 54687, 54694, 54701, 54710, 54720, 54731, 54741, - 54751, 54761, 54772, 54783, 54793, 54804, 54814, 54824, 54832, 54842, - 54852, 54863, 54874, 54881, 54888, 54895, 54902, 54912, 54922, 54929, - 54936, 54943, 54950, 54957, 54964, 54971, 54976, 54981, 54987, 54995, - 55005, 55013, 55021, 55029, 55037, 55045, 55053, 55061, 55069, 55077, - 55085, 55094, 55103, 55111, 55119, 55128, 55137, 55146, 55155, 55165, - 55175, 55184, 55193, 55203, 55213, 55227, 55243, 55257, 55273, 55287, - 55301, 55315, 55329, 55339, 55350, 55360, 55371, 55387, 55403, 55411, - 55417, 55424, 55431, 55438, 55446, 55451, 55457, 55462, 55467, 55473, - 55478, 55483, 55488, 55493, 55498, 55505, 55511, 55519, 55525, 55531, - 55535, 55539, 55548, 55557, 55566, 55575, 55582, 55589, 55602, 55615, - 55628, 55641, 55649, 55657, 55664, 55671, 55679, 55687, 55695, 55703, - 55707, 55712, 55720, 55728, 55736, 55743, 55747, 55755, 55763, 55766, - 55770, 55775, 55782, 55790, 55798, 55817, 55837, 55856, 55876, 55896, - 55916, 55936, 55956, 55962, 55969, 55978, 55986, 55994, 56000, 56003, - 56006, 56011, 56014, 56034, 56041, 56047, 56053, 56057, 56060, 56063, - 56066, 56076, 56088, 56095, 56102, 56105, 56109, 56112, 56117, 56122, - 56127, 56133, 56142, 56149, 56156, 56164, 56171, 56178, 56181, 56187, - 56193, 56196, 56199, 56204, 56209, 56215, 56221, 56225, 56230, 56237, - 56241, 56247, 56251, 56255, 56263, 56275, 56283, 56287, 56289, 56298, - 56307, 56313, 56316, 56322, 56328, 56333, 56338, 56343, 56348, 56353, - 56358, 56360, 56366, 56371, 56379, 56383, 56389, 56392, 56396, 56404, - 56412, 56414, 56416, 56422, 56428, 56434, 56443, 56452, 56459, 56466, - 56472, 56479, 56484, 56489, 56494, 56500, 56506, 56511, 56518, 56522, - 56526, 56539, 56552, 56564, 56573, 56579, 56586, 56591, 56596, 56601, - 56606, 56611, 56613, 56620, 56628, 56636, 56644, 56651, 56659, 56665, - 56670, 56676, 56682, 56688, 56695, 56701, 56709, 56717, 56725, 56733, - 56741, 56747, 56753, 56762, 56766, 56775, 56784, 56793, 56801, 56805, - 56811, 56818, 56825, 56829, 56835, 56843, 56849, 56854, 56860, 56865, - 56870, 56877, 56884, 56889, 56894, 56902, 56910, 56920, 56930, 56937, - 56944, 56948, 56952, 56964, 56970, 56977, 56982, 56987, 56994, 57001, - 57007, 57013, 57023, 57030, 57038, 57046, 57055, 57062, 57068, 57075, - 57081, 57089, 57097, 57105, 57113, 57119, 57124, 57134, 57145, 57152, - 57161, 57167, 57172, 57177, 57187, 57196, 57202, 57208, 57216, 57221, - 57228, 57235, 57246, 57253, 57260, 57267, 57274, 57281, 57290, 57299, - 57312, 57325, 57337, 57349, 57362, 57376, 57382, 57388, 57398, 57408, - 57415, 57422, 57432, 57442, 57451, 57460, 57468, 57476, 57486, 57496, - 57511, 57526, 57535, 57544, 57557, 57570, 57579, 57588, 57599, 57610, - 57616, 57622, 57631, 57640, 57645, 57650, 57658, 57664, 57670, 57678, - 57686, 57699, 57712, 57716, 57720, 57729, 57738, 57745, 57753, 57761, - 57771, 57781, 57787, 57793, 57801, 57809, 57817, 57825, 57835, 57845, - 57848, 57851, 57856, 57861, 57867, 57873, 57880, 57887, 57898, 57909, - 57916, 57923, 57931, 57939, 57948, 57957, 57966, 57975, 57982, 57989, - 57993, 57997, 58006, 58015, 58020, 58025, 58030, 58035, 58041, 58055, - 58062, 58069, 58073, 58075, 58077, 58082, 58087, 58092, 58097, 58105, - 58112, 58119, 58127, 58139, 58147, 58155, 58166, 58170, 58174, 58180, - 58188, 58201, 58208, 58215, 58222, 58228, 58235, 58244, 58253, 58259, - 58265, 58271, 58282, 58293, 58301, 58310, 58315, 58318, 58323, 58328, - 58333, 58339, 58345, 58349, 58352, 58356, 58360, 58365, 58370, 58376, - 58382, 58386, 58390, 58397, 58404, 58411, 58418, 58425, 58432, 58441, - 58450, 58457, 58464, 58472, 58480, 58484, 58489, 58494, 58500, 58506, - 58509, 58512, 58515, 58518, 58523, 58528, 58533, 58538, 58543, 58548, - 58552, 58556, 58560, 58565, 58570, 58574, 58578, 58584, 58588, 58594, - 58599, 58606, 58614, 58621, 58629, 58636, 58644, 58653, 58660, 58670, - 58681, 58687, 58696, 58702, 58711, 58721, 58727, 58733, 58737, 58741, - 58750, 58760, 58767, 58775, 58784, 58793, 58800, 58806, 58813, 58818, - 58822, 58826, 58831, 58836, 58841, 58849, 58857, 58860, 58864, 58873, - 58883, 58892, 58902, 58914, 58928, 58932, 58937, 58941, 58946, 58951, - 58956, 58962, 58968, 58975, 58982, 58988, 58995, 59001, 59008, 59017, - 59026, 59032, 59039, 59045, 0, 0, 59052, 59060, 59068, 59077, 59086, - 59095, 59105, 59114, 59124, 59130, 59135, 59144, 59156, 59165, 59177, - 59184, 59192, 59199, 59207, 59212, 59218, 59223, 59229, 59237, 59246, - 59254, 59263, 59267, 59270, 59274, 59277, 59287, 0, 59290, 59297, 59306, - 59316, 59325, 59335, 59341, 59348, 59354, 59361, 59372, 59383, 59394, - 59405, 59415, 59425, 59435, 59445, 59453, 59461, 59469, 59477, 59485, - 59493, 59501, 59509, 59515, 59520, 59526, 59531, 59537, 59543, 59549, - 59555, 59567, 59577, 59582, 59589, 59594, 59601, 59604, 59608, 59612, - 59617, 59621, 59626, 59629, 59638, 59647, 59656, 59665, 59670, 59676, - 59682, 59690, 59700, 59707, 59716, 59721, 59724, 59727, 59732, 59737, - 59742, 59747, 59749, 59751, 59753, 59755, 59757, 59759, 59764, 59771, - 59778, 59780, 59782, 59784, 59786, 59788, 59790, 59792, 59794, 59799, - 59804, 59811, 59818, 59827, 59837, 59846, 59856, 59861, 59866, 59868, - 59875, 59882, 59889, 59896, 59903, 59910, 59917, 59920, 59923, 59926, - 59929, 59934, 59939, 59944, 59949, 59954, 59959, 59964, 59969, 59974, - 59979, 59984, 59989, 59995, 59999, 60004, 60009, 60014, 60019, 60024, - 60029, 60034, 60039, 60044, 60049, 60054, 60059, 60064, 60069, 60074, - 60079, 60084, 60089, 60094, 60099, 60104, 60109, 60115, 60120, 60126, - 60135, 60140, 60148, 60155, 60164, 60169, 60174, 60179, 60185, 60192, - 60199, 60204, 60209, 60214, 60219, 60224, 60229, 60234, 60239, 60244, - 60249, 60255, 60259, 60264, 60269, 60274, 60279, 60284, 60289, 60294, - 60299, 60304, 60309, 60314, 60319, 60324, 60329, 60334, 60339, 60344, - 60349, 60354, 60359, 60364, 60369, 60375, 60380, 60386, 60395, 60400, - 60408, 60415, 60424, 60429, 60434, 60439, 60445, 60452, 60459, 60467, - 60475, 60484, 60491, 60499, 60505, 60514, 60522, 60530, 60538, 60546, - 60554, 60562, 60567, 60574, 60579, 60585, 60593, 60600, 60607, 60615, - 60621, 60627, 60634, 60642, 60651, 60661, 60667, 60674, 60679, 60689, - 60699, 60704, 60709, 60714, 60719, 60724, 60729, 60734, 60739, 60744, - 60749, 60754, 60759, 60764, 60769, 60774, 60779, 60784, 60789, 60794, - 60799, 60804, 60809, 60814, 60819, 60824, 60829, 60834, 60839, 60844, - 60849, 60853, 60857, 60862, 60867, 60872, 60877, 60882, 60887, 60892, - 60897, 60902, 60907, 60912, 60917, 60922, 60927, 60932, 60937, 60942, - 60947, 60954, 60961, 60968, 60975, 60982, 60989, 60996, 61003, 61010, - 61017, 61024, 61031, 61038, 61045, 61050, 61055, 61062, 61069, 61076, - 61083, 61090, 61097, 61104, 61111, 61118, 61125, 61132, 61139, 61145, - 61151, 61157, 61163, 61170, 61177, 61184, 61191, 61198, 61205, 61212, - 61219, 61226, 61233, 61241, 61249, 61257, 61265, 61273, 61281, 61289, - 61297, 61301, 61307, 61313, 61317, 61323, 61329, 61335, 61342, 61349, - 61356, 61363, 61368, 61374, 61380, 61387, 0, 0, 0, 0, 0, 61394, 61402, - 61411, 61420, 61428, 61434, 61439, 61444, 61449, 61454, 61459, 61464, - 61469, 61474, 61479, 61484, 61489, 61494, 61499, 61504, 61509, 61514, - 61519, 61524, 61529, 61534, 61539, 61544, 61549, 61554, 61559, 61564, - 61569, 61574, 61579, 61584, 61589, 61594, 61599, 61604, 61609, 61614, - 61619, 61624, 61629, 0, 61634, 0, 0, 0, 0, 0, 61639, 0, 0, 61644, 61648, - 61653, 61658, 61663, 61668, 61677, 61682, 61687, 61692, 61697, 61702, - 61707, 61712, 61717, 61724, 61729, 61734, 61743, 61750, 61755, 61760, - 61765, 61772, 61777, 61784, 61789, 61794, 61801, 61808, 61813, 61818, - 61823, 61830, 61837, 61842, 61847, 61852, 61857, 61862, 61869, 61876, - 61881, 61886, 61891, 61896, 61901, 61906, 61911, 61916, 61921, 61926, - 61931, 61938, 61943, 61948, 0, 0, 0, 0, 0, 0, 0, 61953, 61960, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61965, 61970, 61974, 61978, 61982, - 61986, 61990, 61994, 61998, 62002, 62006, 62010, 62016, 62020, 62024, - 62028, 62032, 62036, 62040, 62044, 62048, 62052, 62056, 62060, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 62064, 62068, 62072, 62076, 62080, 62084, 62088, 0, - 62092, 62096, 62100, 62104, 62108, 62112, 62116, 0, 62120, 62124, 62128, - 62132, 62136, 62140, 62144, 0, 62148, 62152, 62156, 62160, 62164, 62168, - 62172, 0, 62176, 62180, 62184, 62188, 62192, 62196, 62200, 0, 62204, - 62208, 62212, 62216, 62220, 62224, 62228, 0, 62232, 62236, 62240, 62244, - 62248, 62252, 62256, 0, 62260, 62264, 62268, 62272, 62276, 62280, 62284, - 0, 62288, 62293, 62298, 62303, 62308, 62313, 62318, 62322, 62327, 62332, - 62337, 62341, 62346, 62351, 62356, 62361, 62365, 62370, 62375, 62380, - 62385, 62390, 62395, 62399, 62404, 62409, 62416, 62421, 62426, 62432, - 62439, 62446, 62455, 62462, 62471, 62476, 62481, 62488, 62495, 62501, - 62509, 62515, 62520, 62525, 62529, 62536, 62543, 62547, 62549, 62553, - 62559, 62561, 62565, 62569, 62573, 62579, 62584, 62588, 62592, 62597, - 62603, 62609, 62615, 62620, 62625, 62632, 62639, 62645, 62651, 62657, - 62663, 62669, 62675, 62679, 62683, 62690, 62697, 62703, 62707, 62712, - 62715, 62719, 62726, 62729, 62733, 62737, 62740, 62746, 62752, 62755, - 62761, 62765, 62769, 62775, 62780, 62785, 62787, 62790, 62794, 62800, - 62806, 62810, 62815, 62824, 62827, 62833, 62838, 62842, 62846, 62850, - 62853, 62858, 62864, 62872, 62880, 62886, 62891, 62896, 62902, 62908, - 62915, 62922, 62928, 62934, 62940, 62946, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 62950, 62954, 62958, 62963, 62968, 62973, 62977, 62981, 62985, 62990, - 62995, 62999, 63003, 63007, 63011, 63016, 63021, 63026, 63031, 63035, - 63039, 63044, 63049, 63054, 63059, 63063, 0, 63067, 63071, 63075, 63079, - 63083, 63087, 63091, 63096, 63101, 63105, 63110, 63115, 63124, 63128, - 63132, 63136, 63143, 63147, 63152, 63157, 63161, 63165, 63171, 63176, - 63181, 63186, 63191, 63195, 63199, 63203, 63207, 63211, 63216, 63221, - 63225, 63229, 63234, 63239, 63244, 63248, 63252, 63257, 63262, 63268, - 63274, 63278, 63284, 63290, 63294, 63300, 63306, 63311, 63316, 63320, - 63326, 63330, 63334, 63340, 63346, 63351, 63356, 63360, 63364, 63372, - 63378, 63384, 63390, 63395, 63400, 63405, 63411, 63415, 63421, 63425, - 63429, 63435, 63441, 63447, 63453, 63459, 63465, 63471, 63477, 63483, - 63489, 63495, 63501, 63505, 63511, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 63517, 63520, 63524, 63528, 63532, 63536, 63539, 63542, 63546, 63550, - 63554, 63558, 63561, 63566, 63570, 63574, 63578, 63584, 63588, 63592, - 63596, 63600, 63607, 63613, 63617, 63621, 63625, 63629, 63633, 63637, - 63641, 63645, 63649, 63653, 63657, 63663, 63667, 63671, 63675, 63679, - 63683, 63687, 63691, 63695, 63699, 63703, 63707, 63711, 63715, 63719, - 63723, 63727, 63733, 63739, 63744, 63749, 63753, 63757, 63761, 63765, - 63769, 63773, 63777, 63781, 63785, 63789, 63793, 63797, 63801, 63805, - 63809, 63813, 63817, 63821, 63825, 63829, 63833, 63837, 63841, 63845, - 63851, 63855, 63859, 63863, 63867, 63871, 63875, 63879, 63883, 63888, - 63895, 63899, 63903, 63907, 63911, 63915, 63919, 63923, 63927, 63931, - 63935, 63939, 63943, 63950, 63954, 63960, 63964, 63968, 63972, 63976, - 63980, 63983, 63987, 63991, 63995, 63999, 64003, 64007, 64011, 64015, - 64019, 64023, 64027, 64031, 64035, 64039, 64043, 64047, 64051, 64055, - 64059, 64063, 64067, 64071, 64075, 64079, 64083, 64087, 64091, 64095, - 64099, 64103, 64107, 64111, 64117, 64121, 64125, 64129, 64133, 64137, - 64141, 64145, 64149, 64153, 64157, 64161, 64165, 64169, 64173, 64177, - 64181, 64185, 64189, 64193, 64197, 64201, 64205, 64209, 64213, 64217, - 64221, 64225, 64233, 64237, 64241, 64245, 64249, 64253, 64259, 64263, - 64267, 64271, 64275, 64279, 64283, 64287, 64291, 64295, 64299, 64303, - 64307, 64311, 64317, 64321, 64325, 64329, 64333, 64337, 64341, 64345, - 64349, 64353, 64357, 64361, 64365, 64369, 64373, 64377, 64381, 64385, - 64389, 64393, 64397, 64401, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64405, 64413, 64421, 64431, 64441, - 64450, 64460, 64470, 64481, 64493, 64504, 64516, 0, 0, 0, 0, 64523, - 64526, 64529, 64534, 64537, 64544, 64548, 64552, 64556, 64561, 64566, - 64572, 64578, 64583, 64588, 64594, 64600, 64606, 64612, 64615, 64618, - 64625, 64632, 64638, 64644, 64652, 64660, 64665, 64670, 64674, 64682, - 64688, 64695, 64700, 64705, 64710, 64715, 64720, 64725, 64730, 64735, - 64740, 64745, 64750, 64755, 64760, 64765, 64771, 64776, 64780, 64786, - 64797, 64806, 64820, 64829, 64833, 64843, 64849, 64855, 64861, 64866, - 64869, 64874, 64878, 0, 64884, 64889, 64893, 64898, 64902, 64907, 64911, - 64916, 64920, 64925, 64929, 64933, 64938, 64943, 64948, 64953, 64958, - 64963, 64968, 64973, 64978, 64982, 64987, 64992, 64997, 65002, 65007, - 65012, 65017, 65022, 65027, 65032, 65037, 65042, 65047, 65053, 65058, - 65063, 65068, 65073, 65077, 65082, 65086, 65091, 65096, 65101, 65106, - 65110, 65115, 65119, 65124, 65129, 65134, 65139, 65144, 65149, 65154, - 65159, 65164, 65169, 65174, 65179, 65183, 65188, 65193, 65198, 65203, - 65208, 65212, 65218, 65223, 65229, 65234, 65238, 65243, 65248, 65253, - 65258, 65264, 65269, 65274, 65279, 65284, 65289, 65294, 65299, 0, 0, - 65305, 65313, 65321, 65328, 65335, 65340, 65347, 65353, 65358, 65362, - 65365, 65369, 65372, 65376, 65379, 65383, 65386, 65390, 65393, 65396, - 65400, 65404, 65408, 65412, 65416, 65420, 65424, 65428, 65432, 65435, - 65439, 65443, 65447, 65451, 65455, 65459, 65463, 65467, 65471, 65475, - 65479, 65483, 65487, 65492, 65496, 65500, 65504, 65508, 65511, 65515, - 65518, 65522, 65526, 65530, 65534, 65537, 65541, 65544, 65548, 65552, - 65556, 65560, 65564, 65568, 65572, 65576, 65580, 65584, 65588, 65592, - 65595, 65599, 65603, 65607, 65611, 65615, 65618, 65623, 65627, 65632, - 65636, 65639, 65643, 65647, 65651, 65655, 65660, 65664, 65668, 65672, - 65676, 65680, 65684, 65688, 65693, 65697, 65701, 65705, 65709, 65713, - 65720, 65724, 65730, 0, 0, 0, 0, 0, 65735, 65740, 65745, 65750, 65755, - 65760, 65765, 65770, 65774, 65779, 65784, 65789, 65794, 65799, 65804, - 65809, 65814, 65819, 65823, 65828, 65833, 65838, 65842, 65846, 65850, - 65855, 65860, 65865, 65870, 65875, 65880, 65885, 65890, 65895, 65900, - 65904, 65908, 65913, 65918, 65923, 65928, 65933, 65940, 0, 65945, 65949, - 65953, 65957, 65961, 65965, 65969, 65973, 65977, 65981, 65985, 65989, - 65993, 65997, 66001, 66005, 66009, 66013, 66017, 66021, 66025, 66029, - 66033, 66037, 66041, 66045, 66049, 66053, 66057, 66061, 66065, 66068, - 66072, 66075, 66079, 66083, 66086, 66090, 66094, 66097, 66101, 66105, - 66109, 66113, 66116, 66120, 66124, 66128, 66132, 66136, 66140, 66143, - 66146, 66150, 66154, 66158, 66162, 66166, 66170, 66174, 66178, 66182, - 66186, 66190, 66194, 66198, 66202, 66206, 66210, 66214, 66218, 66222, - 66226, 66230, 66234, 66238, 66242, 66246, 66250, 66254, 66258, 66262, - 66266, 66270, 66274, 66278, 66282, 66286, 66290, 66294, 66298, 66302, - 66306, 66310, 0, 66314, 66320, 66326, 66331, 66336, 66341, 66347, 66353, - 66358, 66364, 66370, 66376, 66382, 66388, 66394, 66400, 66406, 66411, - 66416, 66421, 66426, 66431, 66436, 66441, 66446, 66451, 66456, 66461, - 66466, 66471, 66476, 66481, 66486, 66491, 66496, 66501, 66506, 66512, - 66518, 66524, 66530, 66535, 66540, 66545, 66551, 66556, 66561, 66566, - 66571, 66576, 66581, 66586, 66591, 66596, 66601, 66606, 66611, 66616, - 66621, 66626, 66631, 66636, 66641, 66646, 66651, 66656, 66661, 66666, - 66671, 66676, 66681, 66686, 66691, 66696, 66701, 66706, 66711, 66716, - 66721, 66726, 66731, 66736, 66741, 66746, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 66751, 66756, 66761, 66766, 66770, 66775, 66779, 66784, 66789, - 66794, 66799, 66804, 66808, 66813, 66818, 66823, 66828, 66832, 66836, - 66840, 66844, 66848, 66852, 66856, 66860, 66864, 66868, 66872, 66876, - 66880, 66884, 66889, 66894, 66899, 66904, 66909, 66914, 66919, 66924, - 66929, 66934, 66939, 66944, 66949, 66954, 66959, 66966, 0, 66974, 66978, - 66982, 66986, 66990, 66994, 66998, 67002, 67006, 67010, 67015, 67020, - 67025, 67030, 67035, 67040, 67045, 67050, 67055, 67060, 67065, 67070, - 67075, 67080, 67085, 67090, 67095, 67100, 67105, 67110, 67115, 67120, - 67125, 67130, 67135, 67140, 67145, 67150, 67155, 67160, 67165, 67174, - 67183, 67192, 67201, 67210, 67219, 67228, 67237, 67240, 67245, 67250, - 67255, 67260, 67265, 67270, 67275, 67280, 67285, 67289, 67294, 67299, - 67304, 67309, 67314, 67318, 67322, 67326, 67330, 67334, 67338, 67342, - 67346, 67350, 67354, 67358, 67362, 67366, 67370, 67375, 67380, 67385, - 67390, 67395, 67400, 67405, 67410, 67415, 67420, 67425, 67430, 67435, - 67440, 67447, 67454, 67459, 67464, 67468, 67472, 67476, 67480, 67484, - 67488, 67492, 67496, 67500, 67505, 67510, 67515, 67520, 67525, 67530, - 67535, 67540, 67545, 67550, 67555, 67560, 67565, 67570, 67575, 67580, - 67585, 67590, 67595, 67600, 67605, 67610, 67615, 67620, 67625, 67630, - 67635, 67640, 67645, 67650, 67655, 67659, 67664, 67669, 67674, 67679, - 67684, 67689, 67694, 67699, 67704, 67709, 67714, 67719, 67723, 67728, - 67733, 67738, 67743, 67748, 67753, 67758, 67763, 67768, 67772, 67779, - 67786, 67793, 67800, 67807, 67814, 67821, 67828, 67835, 67842, 67849, - 67856, 67859, 67862, 67865, 67870, 67873, 67876, 67879, 67882, 67885, - 67888, 67892, 67896, 67900, 67904, 67907, 67911, 67915, 67919, 67923, - 67927, 67931, 67935, 67939, 67942, 67945, 67949, 67953, 67957, 67961, - 67964, 67968, 67972, 67976, 67980, 67983, 67987, 67991, 67995, 67999, - 68002, 68006, 68010, 68013, 68017, 68021, 68025, 68029, 68033, 68037, - 68041, 68045, 68052, 68055, 68058, 68061, 68064, 68067, 68070, 68073, - 68076, 68079, 68082, 68085, 68088, 68091, 68094, 68097, 68100, 68103, - 68106, 68109, 68112, 68115, 68118, 68121, 68124, 68127, 68130, 68133, - 68136, 68139, 68142, 68145, 68148, 68151, 68154, 68157, 68160, 68163, - 68166, 68169, 68172, 68175, 68178, 68181, 68184, 68187, 68190, 68193, - 68196, 68199, 68202, 68205, 68208, 68211, 68214, 68217, 68220, 68223, - 68226, 68229, 68232, 68235, 68238, 68241, 68244, 68247, 68250, 68253, - 68256, 68259, 68262, 68265, 68268, 68271, 68274, 68277, 68280, 68283, - 68286, 68289, 68292, 68295, 68298, 68301, 68304, 68307, 68310, 68313, - 68316, 68325, 68333, 68341, 68349, 68357, 68365, 68373, 68381, 68389, - 68397, 68406, 68415, 68424, 68433, 68442, 68451, 68460, 68469, 68478, - 68487, 68496, 68505, 68514, 68523, 68532, 68535, 68538, 68541, 68543, - 68546, 68549, 68552, 68557, 68562, 68565, 68572, 68579, 68586, 68593, - 68596, 68601, 68603, 68607, 68609, 68611, 68614, 68617, 68620, 68623, - 68626, 68629, 68632, 68637, 68642, 68645, 68648, 68651, 68654, 68657, - 68660, 68663, 68667, 68670, 68673, 68676, 68679, 68682, 68687, 68690, - 68693, 68696, 68701, 68706, 68711, 68716, 68721, 68726, 68731, 68736, - 68742, 68750, 68752, 68755, 68758, 68761, 68764, 68770, 68778, 68781, - 68784, 68789, 68792, 68795, 68798, 68803, 68806, 68809, 68814, 68817, - 68820, 68825, 68828, 68831, 68836, 68841, 68846, 68849, 68852, 68855, - 68858, 68864, 68867, 68870, 68873, 68875, 68878, 68881, 68884, 68889, - 68892, 68895, 68898, 68901, 68904, 68909, 68912, 68915, 68918, 68921, - 68924, 68927, 68930, 68933, 68936, 68942, 68947, 68955, 68963, 68971, - 68979, 68987, 68995, 69003, 69011, 69019, 69028, 69037, 69046, 69055, - 69064, 69073, 69082, 69091, 69100, 69109, 69118, 69127, 69136, 69145, - 69154, 69163, 69172, 69181, 69190, 69199, 69208, 69217, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69232, 69241, + 69250, 69261, 69268, 69273, 69278, 69285, 69292, 69298, 69303, 69308, + 69313, 69318, 69325, 69330, 69335, 69340, 69351, 69356, 69361, 69368, + 69373, 69380, 69385, 69390, 69397, 69404, 69411, 69420, 69429, 69434, + 69439, 69444, 69451, 69456, 69466, 69473, 69478, 69483, 69488, 69493, + 69498, 69503, 69511, 69518, 69525, 69530, 69537, 69542, 69549, 69558, + 69569, 69574, 69583, 69588, 69595, 69604, 69613, 69618, 69623, 69630, + 69636, 69643, 69650, 69654, 69658, 69661, 69665, 69669, 69673, 69677, + 69681, 69685, 69689, 69692, 69696, 69700, 69704, 69708, 69712, 69716, + 69719, 69723, 69727, 69730, 69734, 69738, 69742, 69746, 69750, 69754, + 69758, 69762, 69766, 69770, 69774, 69778, 69782, 69786, 69790, 69794, + 69798, 69802, 69806, 69810, 69814, 69818, 69822, 69826, 69830, 69834, + 69838, 69842, 69846, 69850, 69854, 69858, 69862, 69866, 69870, 69874, + 69878, 69882, 69886, 69890, 69894, 69898, 69902, 69906, 69909, 69913, + 69917, 69921, 69925, 69929, 69933, 69937, 69941, 69945, 69949, 69953, + 69957, 69961, 69965, 69969, 69973, 69977, 69981, 69985, 69989, 69993, + 69997, 70001, 70005, 70009, 70013, 70017, 70021, 70025, 70029, 70033, + 70037, 70041, 70045, 70049, 70053, 70057, 70061, 70065, 70069, 70073, + 70077, 70081, 70085, 70089, 70093, 70097, 70101, 70105, 70109, 70113, + 70117, 70121, 70125, 70129, 70133, 70137, 70141, 70145, 70149, 70153, + 70157, 70161, 70165, 70169, 70173, 70177, 70181, 70185, 70189, 70193, + 70197, 70201, 70205, 70209, 70213, 70217, 70221, 70225, 70229, 70233, + 70237, 70241, 70245, 70249, 70253, 70257, 70261, 70265, 70269, 70273, + 70277, 70281, 70285, 70289, 70293, 70297, 70301, 70305, 70309, 70313, + 70317, 70321, 70325, 70329, 70333, 70337, 70341, 70345, 70349, 70353, + 70357, 70361, 70365, 70369, 70373, 70377, 70380, 70384, 70388, 70392, + 70396, 70400, 70404, 70408, 70412, 70416, 70420, 70424, 70428, 70432, + 70436, 70440, 70444, 70448, 70452, 70456, 70460, 70464, 70468, 70472, + 70476, 70480, 70484, 70488, 70492, 70496, 70500, 70504, 70508, 70512, + 70516, 70520, 70524, 70528, 70532, 70536, 70540, 70544, 70548, 70552, + 70556, 70560, 70564, 70568, 70572, 70576, 70580, 70584, 70588, 70592, + 70596, 70600, 70604, 70608, 70612, 70616, 70620, 70624, 70628, 70632, + 70636, 70640, 70644, 70648, 70652, 70656, 70660, 70664, 70668, 70672, + 70676, 70680, 70684, 70688, 70692, 70696, 70700, 70704, 70708, 70712, + 70716, 70720, 70724, 70728, 70732, 70736, 70740, 70744, 70748, 70752, + 70756, 70760, 70764, 70768, 70772, 70776, 70780, 70784, 70788, 70792, + 70796, 70800, 70804, 70808, 70812, 70816, 70820, 70824, 70828, 70832, + 70836, 70840, 70843, 70847, 70851, 70855, 70859, 70863, 70867, 70871, + 70875, 70879, 70883, 70887, 70891, 70895, 70899, 70903, 70907, 70911, + 70915, 70919, 70923, 70927, 70931, 70935, 70939, 70943, 70947, 70951, + 70955, 70959, 70963, 70967, 70971, 70975, 70979, 70983, 70987, 70991, + 70995, 70999, 71003, 71007, 71011, 71015, 71019, 71023, 71027, 71031, + 71035, 71039, 71043, 71047, 71051, 71055, 71059, 71063, 71067, 71071, + 71075, 71079, 71083, 71087, 71091, 71095, 71099, 71103, 71107, 71111, + 71115, 71119, 71123, 71127, 71131, 71135, 71139, 71143, 71147, 71151, + 71155, 71159, 71163, 71167, 71171, 71175, 71179, 71183, 71187, 71191, + 71195, 71199, 71202, 71206, 71210, 71214, 71218, 71222, 71226, 71230, + 71234, 71238, 71242, 71246, 71250, 71254, 71258, 71262, 71266, 71270, + 71274, 71278, 71282, 71286, 71290, 71294, 71298, 71302, 71306, 71310, + 71314, 71318, 71322, 71326, 71330, 71334, 71338, 71342, 71346, 71350, + 71354, 71358, 71362, 71366, 71370, 71374, 71378, 71382, 71386, 71390, + 71394, 71398, 71402, 71406, 71410, 71414, 71418, 71422, 71426, 71430, + 71434, 71438, 71441, 71445, 71449, 71453, 71457, 71461, 71465, 71469, + 71473, 71477, 71481, 71485, 71489, 71493, 71497, 71501, 71505, 71509, + 71513, 71517, 71521, 71525, 71529, 71533, 71537, 71541, 71545, 71549, + 71553, 71557, 71561, 71565, 71569, 71573, 71577, 71581, 71585, 71589, + 71593, 71597, 71601, 71605, 71609, 71613, 71617, 71621, 71625, 71629, + 71633, 71637, 71641, 71645, 71649, 71653, 71657, 71661, 71665, 71669, + 71673, 71677, 71681, 71685, 71689, 71693, 71696, 71700, 71704, 71708, + 71712, 71716, 71720, 71724, 71728, 71732, 71736, 71740, 71744, 71748, + 71752, 71756, 71760, 71764, 71768, 71772, 71776, 71780, 71784, 71788, + 71792, 71796, 71800, 71804, 71808, 71812, 71816, 71820, 71824, 71828, + 71832, 71836, 71840, 71844, 71848, 71852, 71856, 71860, 71864, 71868, + 71872, 71876, 71880, 71884, 71888, 71892, 71896, 71900, 71904, 71908, + 71912, 71916, 71920, 71924, 71928, 71932, 71936, 71940, 71944, 71948, + 71952, 71956, 71960, 71964, 71968, 71972, 71976, 71980, 71984, 71988, + 71992, 71996, 72000, 72004, 72008, 72012, 72016, 72020, 72024, 72028, + 72032, 72036, 72040, 72044, 72048, 72052, 72056, 72060, 72064, 72068, + 72072, 72076, 72080, 72084, 72088, 72092, 72096, 72100, 72104, 72108, + 72112, 72116, 72120, 72124, 72128, 72132, 72136, 72140, 72144, 72148, + 72151, 72155, 72159, 72163, 72167, 72171, 72175, 72179, 72183, 72187, + 72191, 72195, 72199, 72203, 72207, 72211, 72215, 72219, 72223, 72227, + 72231, 72235, 72239, 72243, 72247, 72251, 72255, 72259, 72263, 72267, + 72271, 72275, 72279, 72283, 72287, 72291, 72295, 72299, 72303, 72307, + 72311, 72315, 72319, 72323, 72327, 72331, 72335, 72339, 72343, 72347, + 72351, 72355, 72359, 72363, 72367, 72371, 72375, 72379, 72383, 72387, + 72391, 72395, 72399, 72403, 72407, 72411, 72415, 72419, 72423, 72427, + 72431, 72435, 72439, 72443, 72447, 72451, 72455, 72459, 72463, 72467, + 72471, 72475, 72479, 72483, 72487, 72491, 72495, 72499, 72503, 72507, + 72511, 72515, 72519, 72523, 72527, 72531, 72535, 72539, 72543, 72547, + 72551, 72555, 72559, 72563, 72567, 72571, 72575, 72579, 72583, 72587, + 72591, 72595, 72599, 72603, 72607, 72611, 72615, 72619, 72623, 72627, + 72631, 72635, 72639, 72643, 72647, 72651, 72655, 72659, 72663, 72667, + 72671, 72675, 72679, 72683, 72687, 72691, 72695, 72699, 72703, 72707, + 72711, 72715, 72719, 72723, 72727, 72731, 72735, 72739, 72743, 72747, + 72751, 72754, 72758, 72762, 72766, 72770, 72774, 72778, 72782, 72785, + 72789, 72793, 72797, 72801, 72805, 72809, 72813, 72817, 72821, 72825, + 72829, 72833, 72837, 72841, 72845, 72849, 72853, 72857, 72861, 72865, + 72869, 72873, 72877, 72881, 72885, 72889, 72893, 72897, 72901, 72905, + 72909, 72913, 72917, 72921, 72925, 72929, 72933, 72937, 72941, 72945, + 72949, 72953, 72957, 72961, 72965, 72969, 72973, 72977, 72981, 72985, + 72989, 72993, 72997, 73001, 73005, 73009, 73013, 73017, 73021, 73025, + 73029, 73033, 73037, 73041, 73045, 73049, 73053, 73057, 73061, 73065, + 73069, 73073, 73077, 73081, 73085, 73089, 73093, 73097, 73101, 73105, + 73109, 73113, 73117, 73121, 73125, 73129, 73133, 73137, 73141, 73145, + 73149, 73153, 73157, 73161, 73165, 73169, 73173, 73177, 73181, 73185, + 73189, 73193, 73197, 73201, 73205, 73209, 73213, 73217, 73221, 73225, + 73229, 73233, 73237, 73241, 73245, 73249, 73253, 73257, 73261, 73265, + 73269, 73273, 73277, 73281, 73285, 73289, 73293, 73297, 73301, 73305, + 73309, 73313, 73317, 73321, 73325, 73329, 73333, 73337, 73341, 73345, + 73349, 73353, 73357, 73361, 73365, 73369, 73373, 73377, 73381, 73385, + 73389, 73393, 73397, 73401, 73405, 73409, 73413, 73417, 73421, 73425, + 73429, 73433, 73437, 73441, 73445, 73449, 73453, 73457, 73461, 73465, + 73469, 73473, 73477, 73481, 73485, 73489, 73493, 73497, 73501, 73505, + 73509, 73512, 73516, 73520, 73524, 73528, 73532, 73536, 73540, 73544, + 73548, 73552, 73556, 73560, 73564, 73568, 73572, 73576, 73580, 73584, + 73588, 73592, 73596, 73600, 73604, 73608, 73612, 73616, 73620, 73624, + 73628, 73632, 73636, 73640, 73644, 73648, 73652, 73656, 73660, 73664, + 73668, 73672, 73676, 73680, 73684, 73688, 73692, 73696, 73700, 73704, + 73708, 73712, 73716, 73720, 73724, 73728, 73732, 73736, 73740, 73744, + 73748, 73752, 73756, 73760, 73764, 73768, 73772, 73776, 73780, 73784, + 73788, 73792, 73796, 73800, 73804, 73808, 73812, 73816, 73820, 73824, + 73828, 73832, 73836, 73840, 73844, 73848, 73852, 73856, 73860, 73864, + 73868, 73872, 73876, 73880, 73884, 73888, 73892, 73896, 73900, 73904, + 73908, 73912, 73916, 73920, 73924, 73928, 73932, 73936, 73940, 73944, + 73948, 73952, 73956, 73960, 73964, 73968, 73972, 73976, 73980, 73984, + 73988, 73992, 73996, 74000, 74004, 74008, 74012, 74016, 74020, 74024, + 74028, 74032, 74036, 74040, 74044, 74048, 74052, 74056, 74060, 74064, + 74068, 74072, 74076, 74080, 74084, 74088, 74092, 74096, 74100, 74104, + 74108, 74112, 74116, 74120, 74124, 74128, 74132, 74136, 74140, 74144, + 74148, 74152, 74156, 74160, 74164, 74168, 74172, 74176, 74180, 74184, + 74188, 74192, 74196, 74200, 74204, 74208, 74212, 74216, 74220, 74224, + 74228, 74232, 74236, 74240, 74244, 74248, 74252, 74256, 74260, 74264, + 74268, 74272, 74276, 74280, 74284, 74288, 74292, 0, 0, 0, 74296, 74300, + 74304, 74308, 74312, 74316, 74320, 74324, 74328, 74332, 74336, 74340, + 74344, 74348, 74352, 74356, 74360, 74364, 74368, 74372, 74376, 74380, + 74384, 74388, 74392, 74396, 74400, 74404, 74408, 74412, 74416, 74420, + 74424, 74428, 74432, 74436, 74440, 74444, 74448, 74452, 74456, 74460, + 74464, 74468, 74472, 74476, 74480, 74484, 74488, 74492, 74496, 74500, + 74504, 74508, 74512, 0, 0, 0, 0, 0, 0, 0, 0, 0, 74516, 74521, 74525, + 74530, 74535, 74540, 74545, 74550, 74554, 74559, 74564, 74569, 74574, + 74579, 74584, 74589, 74593, 74597, 74601, 74605, 74610, 74615, 74620, + 74624, 74629, 74634, 74639, 74644, 74649, 74653, 74658, 74662, 74667, + 74671, 74676, 74680, 74684, 74688, 74693, 74698, 74703, 74711, 74719, + 74727, 74735, 74742, 74750, 74756, 74764, 74768, 74772, 74776, 74780, + 74784, 74788, 74792, 74796, 74800, 74804, 74808, 74812, 74816, 74820, + 74824, 74828, 74832, 74836, 74840, 74844, 74848, 74852, 74856, 74860, + 74864, 74868, 74872, 74876, 74880, 74884, 74888, 74892, 74896, 74900, + 74904, 74908, 74911, 74915, 74919, 74923, 74927, 74931, 74935, 74939, + 74943, 74947, 74951, 74955, 74959, 74963, 74967, 74971, 74975, 74979, + 74983, 74987, 74991, 74995, 74999, 75003, 75007, 75011, 75015, 75019, + 75023, 75027, 75031, 75035, 75039, 75043, 75047, 75051, 75055, 75058, + 75062, 75066, 75069, 75073, 75077, 75081, 75084, 75088, 75092, 75096, + 75100, 75104, 75108, 75112, 75116, 75120, 75124, 75128, 75132, 75136, + 75139, 75142, 75146, 75150, 75153, 75157, 75161, 75165, 75169, 75173, + 75177, 75180, 75183, 75187, 75191, 75195, 75198, 75201, 75205, 75209, + 75213, 75217, 75221, 75225, 75229, 75233, 75237, 75241, 75245, 75249, + 75253, 75257, 75261, 75265, 75269, 75273, 75277, 75281, 75285, 75289, + 75293, 75297, 75301, 75305, 75309, 75313, 75317, 75321, 75325, 75329, + 75333, 75337, 75341, 75345, 75349, 75352, 75356, 75360, 75364, 75368, + 75372, 75376, 75380, 75384, 75388, 75392, 75396, 75400, 75404, 75408, + 75412, 75416, 75420, 75424, 75428, 75432, 75436, 75440, 75444, 75448, + 75452, 75456, 75460, 75464, 75468, 75472, 75476, 75480, 75484, 75488, + 75492, 75496, 75499, 75503, 75507, 75511, 75515, 75519, 75523, 75527, + 75531, 75535, 75539, 75543, 75547, 75551, 75555, 75559, 75563, 75566, + 75570, 75574, 75578, 75582, 75586, 75590, 75594, 75598, 75602, 75606, + 75610, 75614, 75618, 75622, 75626, 75630, 75634, 75638, 75642, 75646, + 75650, 75653, 75657, 75661, 75665, 75669, 75673, 75677, 75681, 75685, + 75689, 75693, 75697, 75701, 75705, 75709, 75713, 75717, 75721, 75725, + 75729, 75733, 75737, 75741, 75745, 75749, 75753, 75757, 75761, 75765, + 75769, 75773, 75777, 75781, 75785, 75789, 75793, 75797, 75801, 75805, + 75809, 75813, 75817, 75821, 75825, 75828, 75833, 75837, 75843, 75848, + 75854, 75858, 75862, 75866, 75870, 75874, 75878, 75882, 75886, 75890, + 75894, 75898, 75902, 75906, 75910, 75913, 75916, 75919, 75922, 75925, + 75928, 75931, 75934, 75937, 75942, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 75948, 75953, 75958, 75963, 75968, 75975, 75982, + 75987, 75992, 75997, 76002, 76009, 76016, 76023, 76030, 76037, 76044, + 76054, 76064, 76071, 76078, 76085, 76092, 76098, 76104, 76113, 76122, + 76129, 76136, 76147, 76158, 76163, 76168, 76175, 76182, 76189, 76196, + 76203, 76210, 76217, 76224, 76230, 76236, 76242, 76248, 76255, 76262, + 76267, 76271, 76278, 76285, 76292, 76296, 76303, 76307, 76312, 76316, + 76322, 76327, 76333, 76338, 76342, 76346, 76349, 76352, 76357, 76362, + 76367, 76372, 76377, 76382, 76387, 76392, 76397, 76402, 76410, 76418, + 76423, 76428, 76433, 76438, 76443, 76448, 76453, 76458, 76463, 76468, + 76473, 76478, 76483, 76488, 76494, 76500, 76506, 76512, 76517, 76523, + 76526, 76529, 76532, 76536, 76540, 76544, 76548, 76551, 76555, 76558, + 76561, 76564, 76568, 76572, 76576, 76580, 76584, 76588, 76592, 76596, + 76600, 76604, 76608, 76612, 76616, 76620, 76624, 76628, 76632, 76636, + 76640, 76644, 76648, 76652, 76655, 76659, 76663, 76667, 76671, 76675, + 76679, 76683, 76687, 76691, 76695, 76699, 76703, 76707, 76711, 76715, + 76719, 76723, 76727, 76731, 76735, 76739, 76743, 76747, 76751, 76754, + 76758, 76762, 76766, 76770, 76774, 76778, 76782, 76785, 76789, 76793, + 76797, 76801, 76805, 76809, 76813, 76817, 76821, 76825, 76829, 76833, + 76838, 76843, 76846, 76851, 76854, 76857, 76860, 0, 0, 0, 0, 0, 0, 0, 0, + 76864, 76873, 76882, 76891, 76900, 76909, 76918, 76927, 76936, 76944, + 76951, 76959, 76966, 76974, 76984, 76993, 77003, 77012, 77022, 77030, + 77037, 77045, 77052, 77060, 77065, 77070, 77076, 77084, 77090, 77096, + 77103, 77112, 77120, 77128, 77136, 77143, 77150, 77157, 77164, 77169, + 77174, 77179, 77184, 77189, 77194, 77199, 77204, 77212, 77220, 77226, + 77232, 77237, 77242, 77247, 77252, 77257, 77262, 77267, 77272, 77281, + 77290, 77295, 77300, 77310, 77320, 77327, 77334, 77343, 77352, 77364, + 77376, 77382, 77388, 77396, 77404, 77414, 77424, 77431, 77438, 77443, + 77448, 77460, 77472, 77480, 77488, 77498, 77508, 77520, 77532, 77541, + 77550, 77557, 77564, 77571, 77578, 77587, 77596, 77601, 77606, 77613, + 77620, 77627, 77634, 77646, 77658, 77663, 77668, 77673, 77678, 77683, + 77688, 77693, 77698, 77702, 77707, 77712, 77717, 77722, 77727, 77733, + 77738, 77743, 77750, 77757, 77764, 77771, 77778, 77786, 77794, 77799, + 77804, 77810, 77816, 77823, 77830, 77837, 77844, 77851, 77855, 77862, + 77867, 77872, 77878, 77891, 77897, 77905, 77913, 77920, 77927, 77936, + 77945, 77952, 77959, 77966, 77973, 77980, 77987, 77994, 78001, 78008, + 78015, 78024, 78033, 78042, 78051, 78060, 78069, 78078, 78087, 78096, + 78105, 78112, 78120, 78126, 78134, 78140, 78146, 78152, 78158, 78166, + 78171, 78176, 78181, 78186, 78191, 78197, 78203, 78209, 78215, 78221, + 78227, 78233, 78239, 78246, 78253, 78260, 78267, 78276, 78283, 78292, + 78304, 78316, 78328, 0, 0, 0, 0, 0, 78340, 78349, 0, 78358, 0, 78364, + 78370, 78378, 78386, 78393, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 78400, 78405, 78410, 78415, 78423, 78431, + 78438, 78445, 78451, 78458, 78466, 78474, 78482, 78490, 78498, 78504, + 78510, 78517, 78523, 78529, 78535, 78542, 78549, 78556, 78563, 78570, + 78577, 78584, 78591, 78598, 78605, 78612, 78619, 78626, 78633, 78639, + 78646, 78653, 78660, 78667, 78674, 78681, 78688, 78695, 78702, 78709, + 78716, 78723, 78730, 78737, 78744, 78751, 78758, 78765, 78773, 78781, + 78789, 78797, 78805, 0, 0, 0, 78814, 78822, 78830, 78838, 78846, 78854, + 78862, 78868, 78874, 78880, 0, 0, 0, 0, 0, 0, 78886, 78890, 78895, 78900, + 78905, 78910, 78915, 78920, 78925, 78930, 78935, 78940, 78944, 78948, + 78953, 78958, 78962, 78967, 78972, 78977, 78982, 78987, 78992, 78997, + 79001, 79005, 79009, 79014, 79018, 79022, 79026, 79030, 79034, 79038, + 79042, 79047, 79052, 79057, 79062, 79067, 79074, 79080, 79085, 79090, + 79095, 79100, 79106, 79113, 79119, 79126, 79132, 79138, 79143, 79150, + 79156, 79161, 0, 0, 0, 0, 0, 0, 0, 0, 79167, 79172, 79177, 79181, 79186, + 79190, 79195, 79199, 79204, 79209, 79215, 79220, 79226, 79230, 79235, + 79240, 79244, 79249, 79254, 79258, 79263, 79268, 79273, 79278, 79283, + 79288, 79293, 79298, 79303, 79308, 79313, 79318, 79323, 79328, 79333, + 79338, 79343, 79348, 79352, 79356, 79361, 79366, 79371, 79375, 79379, + 79383, 79387, 79392, 79397, 79402, 79406, 79410, 79415, 79421, 79427, + 79432, 79438, 79443, 79449, 79455, 79462, 79468, 79475, 79480, 79486, + 79492, 79497, 79503, 79509, 79514, 0, 0, 0, 0, 0, 0, 0, 0, 79519, 79523, + 79528, 79533, 79537, 79541, 79545, 79549, 79553, 79557, 79561, 79565, 0, + 0, 0, 0, 0, 0, 79569, 79574, 79578, 79582, 79586, 79590, 79594, 79598, + 79602, 79606, 79610, 79614, 79618, 79622, 79626, 79630, 79634, 79639, + 79644, 79650, 79656, 79663, 79668, 79673, 79679, 79683, 79688, 79691, + 79694, 79698, 79703, 79707, 79712, 79719, 79725, 79731, 79737, 79743, + 79749, 79755, 79761, 79767, 79773, 79779, 79786, 79793, 79800, 79806, + 79813, 79820, 79827, 79834, 79841, 79847, 79853, 79860, 79866, 79873, + 79880, 79886, 79892, 79898, 79905, 79912, 79918, 79925, 79932, 79938, + 79945, 79951, 79958, 79965, 79971, 79977, 79984, 79990, 79997, 80004, + 80013, 80020, 80027, 80031, 80036, 80041, 80046, 80051, 80055, 80059, + 80064, 80068, 80073, 80078, 80083, 80087, 80091, 80095, 80099, 80104, + 80108, 80113, 80118, 80123, 80128, 80132, 80137, 80142, 80147, 80153, + 80158, 80164, 80170, 80176, 80182, 80188, 80193, 80199, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 80203, 80208, 80212, 80216, 80220, 80224, 80228, 80232, + 80236, 80240, 80244, 80248, 80252, 80256, 80260, 80264, 80268, 80272, + 80276, 80280, 80284, 80288, 80292, 80296, 80300, 80304, 80308, 80312, + 80316, 80320, 0, 0, 0, 80324, 80329, 80334, 80339, 80344, 80348, 80355, + 80359, 80364, 80368, 80375, 80382, 80391, 80395, 80400, 80404, 80408, + 80415, 80422, 80427, 80434, 80439, 80444, 80451, 80456, 80463, 80470, + 80475, 80480, 80487, 80492, 80499, 80506, 80511, 80518, 80523, 80530, + 80534, 80538, 80545, 80550, 80557, 80561, 80565, 80569, 80576, 80580, + 80585, 80592, 80599, 80603, 80607, 80614, 80620, 80626, 80632, 80640, + 80646, 80654, 80660, 80668, 80674, 80680, 80686, 80692, 80696, 80701, + 80706, 80712, 80718, 80724, 80730, 80736, 80742, 80748, 80754, 80762, + 80768, 0, 80775, 80779, 80784, 80788, 80792, 80796, 80800, 80804, 80808, + 80812, 80816, 0, 0, 0, 0, 80820, 80828, 80834, 80840, 80846, 80852, + 80858, 80864, 80870, 80877, 80884, 80891, 80898, 80905, 80912, 80919, + 80926, 80933, 80940, 80947, 80953, 80959, 80965, 80971, 80977, 80983, + 80989, 80995, 81001, 81008, 81015, 81022, 81029, 0, 81036, 81040, 81044, + 81048, 81052, 81057, 81061, 81065, 81070, 81075, 81080, 81085, 81090, + 81095, 81100, 81105, 81110, 81115, 81120, 81125, 81130, 81135, 81140, + 81145, 81150, 81154, 81159, 81163, 81168, 81173, 81178, 81183, 81188, + 81192, 81197, 81201, 81205, 81209, 81214, 81219, 81223, 81227, 81233, + 81238, 81244, 81250, 81255, 81261, 81266, 81272, 81278, 81284, 81289, + 81294, 81299, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81305, 81311, 81317, 81323, + 81330, 81336, 81342, 81348, 81354, 81360, 81365, 81370, 81376, 81383, 0, + 0, 81390, 81395, 81399, 81403, 81407, 81411, 81415, 81419, 81423, 81427, + 0, 0, 81431, 81437, 81443, 81450, 81458, 81464, 81470, 81476, 81482, + 81488, 81494, 81500, 81506, 81512, 81518, 81524, 81529, 81534, 81539, + 81545, 81551, 81558, 81564, 81570, 81575, 81582, 81589, 81596, 81602, + 81607, 81612, 81617, 81625, 81632, 81639, 81647, 81655, 81662, 81669, + 81676, 81683, 81690, 81697, 81704, 81711, 81718, 81725, 81732, 81739, + 81746, 81753, 81760, 81767, 81774, 81781, 81788, 81795, 81801, 81807, + 81814, 81821, 81828, 81835, 81842, 81849, 81856, 81863, 81870, 81877, + 81884, 81891, 81898, 81905, 81912, 81919, 81926, 81933, 81940, 81947, + 81954, 81961, 81968, 81975, 81981, 81987, 81994, 82000, 82005, 82011, + 82016, 82021, 82026, 82033, 82039, 82045, 82051, 82057, 82063, 82069, + 82075, 82083, 82091, 82099, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 82107, 82113, 82119, 82125, 82133, 82141, + 82147, 82153, 82160, 82167, 82174, 82181, 82188, 82195, 82202, 82209, + 82216, 82224, 82232, 82240, 82248, 82256, 82262, 82270, 82276, 82284, + 82293, 82301, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82307, 82311, 82315, 82319, + 82323, 82327, 0, 0, 82331, 82335, 82339, 82343, 82347, 82351, 0, 0, + 82355, 82359, 82363, 82367, 82371, 82375, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 82379, 82383, 82387, 82391, 82395, 82399, 82403, 0, 82407, 82411, 82415, + 82419, 82423, 82427, 82431, 0, 82435, 82442, 82448, 82454, 82460, 82468, + 82475, 82484, 82496, 82506, 82515, 82523, 82531, 82539, 82545, 82553, + 82561, 82568, 82576, 82586, 82593, 82602, 82608, 82618, 82627, 82632, + 82640, 82649, 82654, 82663, 82670, 82680, 82692, 82697, 82703, 82710, + 82715, 82725, 82735, 82745, 82755, 82770, 82783, 82794, 82802, 82807, + 82819, 82828, 82835, 82842, 82848, 82855, 82860, 82867, 82873, 82884, + 82895, 82905, 82911, 82916, 0, 0, 0, 0, 82921, 82925, 82929, 82933, + 82937, 82941, 82946, 82951, 82955, 82960, 82965, 82970, 82975, 82980, + 82984, 82989, 82994, 82999, 83004, 83009, 83013, 83018, 83023, 83028, + 83033, 83038, 83042, 83047, 83052, 83057, 83062, 83066, 83071, 83076, + 83081, 83086, 83091, 83096, 83101, 83106, 83111, 83116, 83121, 83126, + 83131, 83135, 83140, 83145, 83150, 83155, 83160, 83165, 83170, 83175, + 83180, 83185, 83190, 83195, 83200, 83205, 83210, 83215, 83220, 83225, + 83230, 83235, 83240, 83245, 83250, 83255, 83260, 83265, 83270, 83275, + 83280, 83285, 83290, 83295, 83300, 83305, 83309, 83316, 83323, 83330, + 83337, 83343, 83349, 83356, 83363, 83370, 83377, 83384, 83391, 83398, + 83405, 83412, 83418, 83425, 83432, 83439, 83446, 83453, 83460, 83467, + 83474, 83481, 83488, 83495, 83504, 83513, 83522, 83531, 83540, 83549, + 83558, 83567, 83575, 83583, 83591, 83599, 83607, 83615, 83623, 83631, + 83637, 83645, 0, 0, 83653, 83660, 83666, 83672, 83678, 83684, 83690, + 83696, 83702, 83708, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83714, 83719, 83724, 83729, 83734, + 83739, 83744, 83749, 83754, 83759, 83764, 83769, 83774, 83779, 83784, + 83789, 83794, 83799, 83804, 83809, 83814, 83819, 83824, 0, 0, 0, 0, + 83829, 83833, 83837, 83841, 83845, 83849, 83853, 83857, 83861, 83865, + 83869, 83873, 83877, 83881, 83885, 83889, 83893, 83897, 83901, 83905, + 83909, 83913, 83917, 83921, 83925, 83929, 83933, 83937, 83941, 83945, + 83949, 83953, 83957, 83961, 83965, 83969, 83973, 83977, 83981, 83985, + 83989, 83993, 83997, 84001, 84005, 84009, 84013, 84017, 84021, 0, 0, 0, + 0, 84025, 84029, 84033, 84037, 84041, 84045, 84049, 84053, 84057, 84061, + 84065, 84069, 84073, 84077, 84081, 84085, 84089, 84093, 84097, 84101, + 84105, 84109, 84113, 84117, 84121, 84125, 84129, 84133, 84137, 84141, + 84145, 84149, 84153, 84157, 84161, 84165, 84169, 84173, 84177, 84181, + 84185, 84189, 84193, 84197, 84201, 84205, 84209, 84213, 84217, 84221, + 84225, 84229, 84233, 84237, 84241, 84245, 84249, 84253, 84257, 84261, + 84265, 84269, 84273, 84277, 84281, 84285, 84289, 84293, 84297, 84301, + 84305, 84309, 84313, 84317, 84321, 84325, 84329, 84333, 84337, 84341, + 84345, 84349, 84353, 84357, 84361, 84365, 84369, 84373, 84377, 84381, + 84385, 84389, 84393, 84397, 84401, 84405, 84409, 84413, 84417, 84421, + 84425, 84429, 84433, 84437, 84441, 84445, 84449, 84453, 84457, 84461, + 84465, 84469, 84473, 84477, 84481, 84485, 84489, 84493, 84497, 84501, + 84505, 84509, 84513, 84517, 84521, 84525, 84529, 84533, 84537, 84541, + 84545, 84549, 84553, 84557, 84561, 84565, 84569, 84573, 84577, 84581, + 84585, 84589, 84593, 84597, 84601, 84605, 84609, 84613, 84617, 84621, + 84625, 84629, 84633, 84637, 84641, 84645, 84649, 84653, 84657, 84661, + 84665, 84669, 84673, 84677, 84681, 84685, 84689, 84693, 84697, 84701, + 84705, 84709, 84713, 84717, 84721, 84725, 84729, 84733, 84737, 84741, + 84745, 84749, 84753, 84757, 84761, 84765, 84769, 84773, 84777, 84781, + 84785, 84789, 84793, 84797, 84801, 84805, 84809, 84813, 84817, 84821, + 84825, 84829, 84833, 84837, 84841, 84845, 84849, 84853, 84857, 84861, + 84865, 84869, 84873, 84877, 84881, 84885, 84889, 84893, 84897, 84901, + 84905, 84909, 84913, 84917, 84921, 84925, 84929, 84933, 84937, 84941, + 84945, 84949, 84953, 84957, 84961, 84965, 84969, 84973, 84977, 84981, + 84985, 84989, 84993, 84997, 85001, 85005, 85009, 85013, 85017, 85021, + 85025, 85029, 85033, 85037, 85041, 85045, 85049, 85053, 85057, 85061, + 85065, 85069, 85073, 85077, 85081, 85085, 85089, 85093, 85097, 85101, + 85105, 85109, 85113, 85117, 85121, 85125, 85129, 85133, 85137, 85141, + 85145, 85149, 85153, 85157, 85161, 85165, 85169, 85173, 85177, 85181, + 85185, 85189, 85193, 85197, 85201, 85205, 85209, 85213, 85217, 85221, + 85225, 85229, 85233, 85237, 85241, 85245, 85249, 85253, 85257, 85261, + 85265, 85269, 85273, 85277, 85281, 85285, 85289, 85293, 85297, 85301, + 85305, 85309, 85313, 85317, 85321, 85325, 85329, 85333, 85337, 85341, + 85345, 85349, 85353, 85357, 85361, 85365, 85369, 85373, 85377, 85381, + 85385, 85389, 85393, 85397, 85401, 85405, 85409, 85413, 85417, 85421, + 85425, 85429, 85433, 85437, 85441, 85445, 85449, 85453, 85457, 85461, + 85465, 85469, 85473, 85477, 85481, 85485, 0, 0, 85489, 85493, 85497, + 85501, 85505, 85509, 85513, 85517, 85521, 85525, 85529, 85533, 85537, + 85541, 85545, 85549, 85553, 85557, 85561, 85565, 85569, 85573, 85577, + 85581, 85585, 85589, 85593, 85597, 85601, 85605, 85609, 85613, 85617, + 85621, 85625, 85629, 85633, 85637, 85641, 85645, 85649, 85653, 85657, + 85661, 85665, 85669, 85673, 85677, 85681, 85685, 85689, 85693, 85697, + 85701, 85705, 85709, 85713, 85717, 85721, 85725, 85729, 85733, 85737, + 85741, 85745, 85749, 85753, 85757, 85761, 85765, 85769, 85773, 85777, + 85781, 85785, 85789, 85793, 85797, 85801, 85805, 85809, 85813, 85817, + 85821, 85825, 85829, 85833, 85837, 85841, 85845, 85849, 85853, 85857, + 85861, 85865, 85869, 85873, 85877, 85881, 85885, 85889, 85893, 85897, + 85901, 85905, 85909, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85913, + 85918, 85923, 85928, 85933, 85938, 85946, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 85951, 85959, 85967, 85975, 85983, 0, 0, 0, 0, 0, 85991, 85998, + 86005, 86015, 86021, 86027, 86033, 86039, 86045, 86051, 86058, 86064, + 86070, 86076, 86085, 86094, 86106, 86118, 86124, 86130, 86136, 86143, + 86150, 86157, 86164, 86171, 0, 86178, 86185, 86192, 86200, 86207, 0, + 86214, 0, 86221, 86228, 0, 86235, 86243, 0, 86250, 86257, 86264, 86271, + 86278, 86285, 86292, 86299, 86306, 86313, 86318, 86325, 86332, 86338, + 86344, 86350, 86357, 86363, 86369, 86375, 86382, 86388, 86394, 86400, + 86407, 86413, 86419, 86425, 86432, 86438, 86444, 86450, 86457, 86463, + 86469, 86475, 86482, 86488, 86494, 86500, 86507, 86513, 86519, 86525, + 86532, 86538, 86544, 86550, 86557, 86563, 86569, 86575, 86582, 86588, + 86594, 86600, 86607, 86613, 86619, 86625, 86632, 86638, 86644, 86650, + 86656, 86662, 86668, 86674, 86680, 86686, 86692, 86698, 86704, 86710, + 86716, 86722, 86729, 86735, 86741, 86747, 86754, 86760, 86766, 86772, + 86779, 86785, 86791, 86797, 86804, 86812, 86820, 86826, 86832, 86838, + 86845, 86854, 86863, 86871, 86879, 86887, 86896, 86904, 86912, 86920, + 86929, 86936, 86943, 86954, 86965, 86969, 86973, 86978, 86983, 86988, + 86993, 87002, 87011, 87017, 87023, 87030, 87037, 87044, 87048, 87054, + 87060, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87065, 87071, + 87077, 87083, 87090, 87095, 87100, 87106, 87112, 87118, 87124, 87133, + 87139, 87145, 87153, 87161, 87169, 87177, 87183, 87189, 87195, 87202, + 87215, 87229, 87240, 87251, 87263, 87275, 87287, 87299, 87310, 87321, + 87333, 87345, 87357, 87369, 87381, 87393, 87405, 87422, 87439, 87456, + 87463, 87470, 87477, 87485, 87497, 87508, 87519, 87532, 87543, 87552, + 87560, 87569, 87577, 87587, 87595, 87604, 87612, 87621, 87629, 87639, + 87647, 87656, 87664, 87674, 87682, 87690, 87698, 87706, 87713, 87722, + 87730, 87738, 87747, 87755, 87764, 87772, 87780, 87788, 87797, 87805, + 87814, 87822, 87830, 87838, 87846, 87855, 87863, 87872, 87880, 87889, + 87897, 87906, 87914, 87924, 87932, 87940, 87948, 87958, 87966, 87974, + 87983, 87991, 88000, 88009, 88017, 88027, 88035, 88044, 88052, 88061, + 88069, 88079, 88087, 88095, 88102, 88110, 88117, 88126, 88133, 88142, + 88150, 88159, 88167, 88177, 88185, 88194, 88202, 88212, 88220, 88228, + 88235, 88243, 88250, 88259, 88266, 88276, 88286, 88297, 88306, 88315, + 88324, 88333, 88342, 88352, 88364, 88376, 88387, 88399, 88412, 88423, + 88432, 88441, 88449, 88458, 88468, 88476, 88485, 88494, 88502, 88511, + 88521, 88529, 88538, 88547, 88555, 88564, 88574, 88582, 88592, 88600, + 88610, 88618, 88626, 88635, 88643, 88653, 88661, 88669, 88679, 88687, + 88694, 88701, 88710, 88719, 88727, 88736, 88746, 88754, 88765, 88773, + 88781, 88788, 88796, 88805, 88812, 88824, 88835, 88847, 88858, 88870, + 88879, 88887, 88896, 88904, 88913, 88922, 88930, 88939, 88947, 88956, + 88964, 88972, 88980, 88988, 88995, 89004, 89012, 89021, 89029, 89038, + 89046, 89054, 89063, 89071, 89080, 89088, 89097, 89105, 89113, 89121, + 89130, 89138, 89147, 89155, 89164, 89172, 89181, 89189, 89197, 89205, + 89214, 89222, 89231, 89240, 89248, 89257, 89265, 89274, 89282, 89291, + 89299, 89306, 89314, 89321, 89330, 89338, 89347, 89355, 89364, 89373, + 89381, 89391, 89399, 89406, 89414, 89421, 89429, 89441, 89454, 89463, + 89473, 89482, 89492, 89501, 89511, 89520, 89530, 89539, 89549, 89559, + 89568, 89577, 89586, 89596, 89604, 89613, 89623, 89633, 89643, 89653, + 89661, 89671, 89679, 89689, 89697, 89707, 89715, 89725, 89733, 89742, + 89749, 89759, 89767, 89777, 89785, 89795, 89803, 89813, 89821, 89830, + 89838, 89847, 89855, 89864, 89873, 89882, 89891, 89901, 89909, 89919, + 89927, 89937, 89945, 89955, 89963, 89973, 89981, 89990, 89997, 90007, + 90015, 90025, 90033, 90043, 90051, 90061, 90069, 90078, 90086, 90095, + 90103, 90112, 90121, 90130, 90139, 90148, 90156, 90165, 90173, 90182, + 90191, 90199, 90209, 90218, 90228, 90238, 90247, 90257, 90266, 90275, + 90283, 90291, 90296, 90301, 90307, 90315, 90323, 90331, 90339, 90347, + 90355, 90361, 90367, 90373, 90381, 90387, 90397, 90403, 90409, 90415, + 90426, 90437, 90448, 90458, 90469, 90480, 90490, 90501, 90511, 90521, + 90530, 90541, 90552, 90563, 90576, 90586, 90596, 90607, 90617, 90627, + 90637, 90647, 90657, 90667, 90677, 90688, 90699, 90710, 90720, 90730, + 90742, 90753, 90764, 90774, 90784, 90794, 90804, 90815, 90825, 90835, + 90847, 90857, 90867, 90879, 90890, 90901, 90911, 90921, 90931, 90941, + 90953, 90965, 90977, 90988, 90999, 91009, 91019, 91029, 91038, 91047, + 91057, 91067, 91078, 0, 0, 91088, 91099, 91110, 91120, 91130, 91142, + 91153, 91164, 91177, 91187, 91199, 91208, 91217, 91228, 91239, 91252, + 91263, 91276, 91286, 91298, 91308, 91320, 91332, 91345, 91355, 91365, + 91375, 91386, 91396, 91405, 91415, 91424, 91433, 91443, 91453, 91463, + 91473, 91483, 91493, 91504, 91514, 91525, 91535, 91546, 91557, 91567, + 91577, 91587, 91597, 91607, 91617, 91628, 91638, 91649, 0, 0, 0, 0, 0, 0, + 0, 91660, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 91666, 91681, 91696, 91702, 91708, + 91714, 91720, 91726, 91732, 91738, 91744, 91752, 91756, 91759, 91767, + 91775, 91783, 91786, 91789, 91792, 91795, 91798, 91801, 91804, 91807, + 91810, 91813, 91816, 91819, 91822, 91825, 91828, 91831, 91839, 91848, + 91859, 91867, 91875, 91884, 91893, 91905, 91917, 0, 0, 0, 0, 0, 0, 91927, + 91932, 91937, 91944, 91951, 91957, 91963, 91968, 91973, 91978, 91984, + 91990, 91996, 92002, 92008, 92015, 92022, 92032, 92042, 92052, 92061, + 92072, 92081, 92090, 92101, 92112, 92125, 92138, 92150, 92162, 92174, + 92186, 92197, 92208, 92219, 92230, 92242, 92254, 92258, 92263, 92273, + 92283, 92287, 92291, 92295, 92300, 92305, 92310, 92315, 92318, 92322, 0, + 92327, 92330, 92333, 92337, 92341, 92346, 92350, 92354, 92360, 92366, + 92374, 92382, 92385, 92388, 92391, 92394, 92397, 92401, 92405, 0, 92409, + 92414, 92418, 92422, 0, 0, 0, 0, 92427, 92432, 92439, 92444, 92449, 0, + 92454, 92459, 92465, 92470, 92476, 92481, 92487, 92492, 92498, 92503, + 92509, 92515, 92524, 92533, 92542, 92551, 92561, 92571, 92581, 92591, + 92600, 92609, 92618, 92628, 92633, 92638, 92644, 92650, 92656, 92663, + 92671, 92679, 92685, 92691, 92697, 92704, 92710, 92716, 92722, 92729, + 92735, 92741, 92747, 92754, 92759, 92764, 92769, 92775, 92781, 92787, + 92793, 92800, 92806, 92812, 92818, 92824, 92830, 92836, 92842, 92848, + 92854, 92860, 92866, 92873, 92879, 92885, 92891, 92898, 92904, 92910, + 92916, 92923, 92929, 92935, 92941, 92948, 92954, 92960, 92966, 92973, + 92979, 92985, 92991, 92998, 93004, 93010, 93016, 93023, 93029, 93035, + 93041, 93048, 93054, 93060, 93066, 93073, 93079, 93085, 93091, 93098, + 93104, 93110, 93116, 93123, 93129, 93135, 93141, 93148, 93153, 93158, + 93163, 93169, 93175, 93181, 93187, 93194, 93200, 93206, 93212, 93219, + 93225, 93231, 93238, 93245, 93250, 93255, 93260, 93266, 93278, 93290, + 93302, 93314, 93327, 93340, 93348, 0, 0, 93356, 0, 93364, 93369, 93374, + 93378, 93383, 93388, 93392, 93396, 93401, 93406, 93410, 93414, 93418, + 93422, 93428, 93432, 93437, 93441, 93445, 93449, 93453, 93457, 93461, + 93465, 93469, 93473, 93477, 93481, 93486, 93491, 93496, 93501, 93507, + 93513, 93520, 93527, 93534, 93540, 93547, 93554, 93561, 93567, 93574, + 93581, 93587, 93594, 93601, 93607, 93614, 93621, 93627, 93634, 93641, + 93647, 93654, 93661, 93668, 93675, 93682, 93688, 93694, 93700, 93706, + 93711, 93717, 93723, 93730, 93737, 93744, 93750, 93757, 93764, 93771, + 93777, 93784, 93791, 93797, 93804, 93811, 93817, 93824, 93831, 93837, + 93844, 93851, 93857, 93864, 93871, 93878, 93885, 93892, 93899, 93904, + 93911, 93915, 93921, 93927, 93933, 93939, 93945, 93949, 93954, 93959, + 93964, 93969, 93974, 93979, 93984, 93989, 93995, 94001, 94007, 94015, + 94019, 94023, 94027, 94031, 94035, 94039, 94044, 94049, 94054, 94059, + 94063, 94068, 94073, 94078, 94083, 94088, 94093, 94098, 94103, 94107, + 94111, 94116, 94121, 94126, 94131, 94135, 94140, 94145, 94150, 94155, + 94159, 94164, 94169, 94174, 94179, 94183, 94188, 94193, 94197, 94202, + 94207, 94212, 94217, 94222, 94227, 94234, 94241, 94245, 94250, 94255, + 94260, 94265, 94270, 94275, 94280, 94285, 94290, 94295, 94300, 94305, + 94310, 94315, 94320, 94325, 94330, 94335, 94340, 94345, 94350, 94355, + 94360, 94365, 94370, 94375, 94380, 94385, 94390, 0, 0, 0, 94395, 94399, + 94404, 94408, 94413, 94418, 0, 0, 94422, 94427, 94432, 94436, 94441, + 94446, 0, 0, 94451, 94456, 94460, 94465, 94470, 94475, 0, 0, 94480, + 94485, 94490, 0, 0, 0, 94494, 94499, 94504, 94509, 94513, 94518, 94523, + 0, 94528, 94534, 94537, 94541, 94544, 94548, 94552, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 94556, 94562, 94568, 94574, 94580, 0, 0, 94584, 94590, 94596, + 94602, 94608, 94614, 94621, 94628, 94635, 94642, 94649, 94656, 0, 94663, + 94670, 94677, 94683, 94690, 94697, 94704, 94711, 94717, 94724, 94731, + 94738, 94745, 94751, 94758, 94765, 94772, 94779, 94785, 94792, 94799, + 94806, 94813, 94820, 94827, 94834, 0, 94841, 94847, 94854, 94861, 94868, + 94875, 94881, 94888, 94895, 94902, 94909, 94916, 94923, 94930, 94936, + 94943, 94950, 94957, 94964, 0, 94971, 94978, 0, 94985, 94992, 94999, + 95006, 95013, 95020, 95027, 95034, 95041, 95048, 95055, 95062, 95069, + 95076, 95083, 0, 0, 95089, 95094, 95099, 95104, 95109, 95114, 95119, + 95124, 95129, 95134, 95139, 95144, 95149, 95154, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69220, 69229, - 69238, 69249, 69256, 69261, 69266, 69273, 69280, 69286, 69291, 69296, - 69301, 69306, 69313, 69318, 69323, 69328, 69339, 69344, 69349, 69356, - 69361, 69368, 69373, 69378, 69385, 69392, 69399, 69408, 69417, 69422, - 69427, 69432, 69439, 69444, 69454, 69461, 69466, 69471, 69476, 69481, - 69486, 69491, 69499, 69506, 69513, 69518, 69525, 69530, 69537, 69546, - 69557, 69562, 69571, 69576, 69583, 69592, 69601, 69606, 69611, 69618, - 69624, 69631, 69638, 69642, 69646, 69649, 69653, 69657, 69661, 69665, - 69669, 69673, 69677, 69680, 69684, 69688, 69692, 69696, 69700, 69704, - 69707, 69711, 69715, 69718, 69722, 69726, 69730, 69734, 69738, 69742, - 69746, 69750, 69754, 69758, 69762, 69766, 69770, 69774, 69778, 69782, - 69786, 69790, 69794, 69798, 69802, 69806, 69810, 69814, 69818, 69822, - 69826, 69830, 69834, 69838, 69842, 69846, 69850, 69854, 69858, 69862, - 69866, 69870, 69874, 69878, 69882, 69886, 69890, 69894, 69897, 69901, - 69905, 69909, 69913, 69917, 69921, 69925, 69929, 69933, 69937, 69941, - 69945, 69949, 69953, 69957, 69961, 69965, 69969, 69973, 69977, 69981, - 69985, 69989, 69993, 69997, 70001, 70005, 70009, 70013, 70017, 70021, - 70025, 70029, 70033, 70037, 70041, 70045, 70049, 70053, 70057, 70061, - 70065, 70069, 70073, 70077, 70081, 70085, 70089, 70093, 70097, 70101, - 70105, 70109, 70113, 70117, 70121, 70125, 70129, 70133, 70137, 70141, - 70145, 70149, 70153, 70157, 70161, 70165, 70169, 70173, 70177, 70181, - 70185, 70189, 70193, 70197, 70201, 70205, 70209, 70213, 70217, 70221, - 70225, 70229, 70233, 70237, 70241, 70245, 70249, 70253, 70257, 70261, - 70265, 70269, 70273, 70277, 70281, 70285, 70289, 70293, 70297, 70301, - 70305, 70309, 70313, 70317, 70321, 70325, 70329, 70333, 70337, 70341, - 70345, 70349, 70353, 70357, 70361, 70365, 70368, 70372, 70376, 70380, - 70384, 70388, 70392, 70396, 70400, 70404, 70408, 70412, 70416, 70420, - 70424, 70428, 70432, 70436, 70440, 70444, 70448, 70452, 70456, 70460, - 70464, 70468, 70472, 70476, 70480, 70484, 70488, 70492, 70496, 70500, - 70504, 70508, 70512, 70516, 70520, 70524, 70528, 70532, 70536, 70540, - 70544, 70548, 70552, 70556, 70560, 70564, 70568, 70572, 70576, 70580, - 70584, 70588, 70592, 70596, 70600, 70604, 70608, 70612, 70616, 70620, - 70624, 70628, 70632, 70636, 70640, 70644, 70648, 70652, 70656, 70660, - 70664, 70668, 70672, 70676, 70680, 70684, 70688, 70692, 70696, 70700, - 70704, 70708, 70712, 70716, 70720, 70724, 70728, 70732, 70736, 70740, - 70744, 70748, 70752, 70756, 70760, 70764, 70768, 70772, 70776, 70780, - 70784, 70788, 70792, 70796, 70800, 70804, 70808, 70812, 70816, 70820, - 70824, 70828, 70831, 70835, 70839, 70843, 70847, 70851, 70855, 70859, - 70863, 70867, 70871, 70875, 70879, 70883, 70887, 70891, 70895, 70899, - 70903, 70907, 70911, 70915, 70919, 70923, 70927, 70931, 70935, 70939, - 70943, 70947, 70951, 70955, 70959, 70963, 70967, 70971, 70975, 70979, - 70983, 70987, 70991, 70995, 70999, 71003, 71007, 71011, 71015, 71019, - 71023, 71027, 71031, 71035, 71039, 71043, 71047, 71051, 71055, 71059, - 71063, 71067, 71071, 71075, 71079, 71083, 71087, 71091, 71095, 71099, - 71103, 71107, 71111, 71115, 71119, 71123, 71127, 71131, 71135, 71139, - 71143, 71147, 71151, 71155, 71159, 71163, 71167, 71171, 71175, 71179, - 71183, 71187, 71190, 71194, 71198, 71202, 71206, 71210, 71214, 71218, - 71222, 71226, 71230, 71234, 71238, 71242, 71246, 71250, 71254, 71258, - 71262, 71266, 71270, 71274, 71278, 71282, 71286, 71290, 71294, 71298, - 71302, 71306, 71310, 71314, 71318, 71322, 71326, 71330, 71334, 71338, - 71342, 71346, 71350, 71354, 71358, 71362, 71366, 71370, 71374, 71378, - 71382, 71386, 71390, 71394, 71398, 71402, 71406, 71410, 71414, 71418, - 71422, 71426, 71429, 71433, 71437, 71441, 71445, 71449, 71453, 71457, - 71461, 71465, 71469, 71473, 71477, 71481, 71485, 71489, 71493, 71497, - 71501, 71505, 71509, 71513, 71517, 71521, 71525, 71529, 71533, 71537, - 71541, 71545, 71549, 71553, 71557, 71561, 71565, 71569, 71573, 71577, - 71581, 71585, 71589, 71593, 71597, 71601, 71605, 71609, 71613, 71617, - 71621, 71625, 71629, 71633, 71637, 71641, 71645, 71649, 71653, 71657, - 71661, 71665, 71669, 71673, 71677, 71681, 71684, 71688, 71692, 71696, - 71700, 71704, 71708, 71712, 71716, 71720, 71724, 71728, 71732, 71736, - 71740, 71744, 71748, 71752, 71756, 71760, 71764, 71768, 71772, 71776, - 71780, 71784, 71788, 71792, 71796, 71800, 71804, 71808, 71812, 71816, - 71820, 71824, 71828, 71832, 71836, 71840, 71844, 71848, 71852, 71856, - 71860, 71864, 71868, 71872, 71876, 71880, 71884, 71888, 71892, 71896, - 71900, 71904, 71908, 71912, 71916, 71920, 71924, 71928, 71932, 71936, - 71940, 71944, 71948, 71952, 71956, 71960, 71964, 71968, 71972, 71976, - 71980, 71984, 71988, 71992, 71996, 72000, 72004, 72008, 72012, 72016, - 72020, 72024, 72028, 72032, 72036, 72040, 72044, 72048, 72052, 72056, - 72060, 72064, 72068, 72072, 72076, 72080, 72084, 72088, 72092, 72096, - 72100, 72104, 72108, 72112, 72116, 72120, 72124, 72128, 72132, 72136, - 72139, 72143, 72147, 72151, 72155, 72159, 72163, 72167, 72171, 72175, - 72179, 72183, 72187, 72191, 72195, 72199, 72203, 72207, 72211, 72215, - 72219, 72223, 72227, 72231, 72235, 72239, 72243, 72247, 72251, 72255, - 72259, 72263, 72267, 72271, 72275, 72279, 72283, 72287, 72291, 72295, - 72299, 72303, 72307, 72311, 72315, 72319, 72323, 72327, 72331, 72335, - 72339, 72343, 72347, 72351, 72355, 72359, 72363, 72367, 72371, 72375, - 72379, 72383, 72387, 72391, 72395, 72399, 72403, 72407, 72411, 72415, - 72419, 72423, 72427, 72431, 72435, 72439, 72443, 72447, 72451, 72455, - 72459, 72463, 72467, 72471, 72475, 72479, 72483, 72487, 72491, 72495, - 72499, 72503, 72507, 72511, 72515, 72519, 72523, 72527, 72531, 72535, - 72539, 72543, 72547, 72551, 72555, 72559, 72563, 72567, 72571, 72575, - 72579, 72583, 72587, 72591, 72595, 72599, 72603, 72607, 72611, 72615, - 72619, 72623, 72627, 72631, 72635, 72639, 72643, 72647, 72651, 72655, - 72659, 72663, 72667, 72671, 72675, 72679, 72683, 72687, 72691, 72695, - 72699, 72703, 72707, 72711, 72715, 72719, 72723, 72727, 72731, 72735, - 72739, 72742, 72746, 72750, 72754, 72758, 72762, 72766, 72770, 72773, - 72777, 72781, 72785, 72789, 72793, 72797, 72801, 72805, 72809, 72813, - 72817, 72821, 72825, 72829, 72833, 72837, 72841, 72845, 72849, 72853, - 72857, 72861, 72865, 72869, 72873, 72877, 72881, 72885, 72889, 72893, - 72897, 72901, 72905, 72909, 72913, 72917, 72921, 72925, 72929, 72933, - 72937, 72941, 72945, 72949, 72953, 72957, 72961, 72965, 72969, 72973, - 72977, 72981, 72985, 72989, 72993, 72997, 73001, 73005, 73009, 73013, - 73017, 73021, 73025, 73029, 73033, 73037, 73041, 73045, 73049, 73053, - 73057, 73061, 73065, 73069, 73073, 73077, 73081, 73085, 73089, 73093, - 73097, 73101, 73105, 73109, 73113, 73117, 73121, 73125, 73129, 73133, - 73137, 73141, 73145, 73149, 73153, 73157, 73161, 73165, 73169, 73173, - 73177, 73181, 73185, 73189, 73193, 73197, 73201, 73205, 73209, 73213, - 73217, 73221, 73225, 73229, 73233, 73237, 73241, 73245, 73249, 73253, - 73257, 73261, 73265, 73269, 73273, 73277, 73281, 73285, 73289, 73293, - 73297, 73301, 73305, 73309, 73313, 73317, 73321, 73325, 73329, 73333, - 73337, 73341, 73345, 73349, 73353, 73357, 73361, 73365, 73369, 73373, - 73377, 73381, 73385, 73389, 73393, 73397, 73401, 73405, 73409, 73413, - 73417, 73421, 73425, 73429, 73433, 73437, 73441, 73445, 73449, 73453, - 73457, 73461, 73465, 73469, 73473, 73477, 73481, 73485, 73489, 73493, - 73497, 73500, 73504, 73508, 73512, 73516, 73520, 73524, 73528, 73532, - 73536, 73540, 73544, 73548, 73552, 73556, 73560, 73564, 73568, 73572, - 73576, 73580, 73584, 73588, 73592, 73596, 73600, 73604, 73608, 73612, - 73616, 73620, 73624, 73628, 73632, 73636, 73640, 73644, 73648, 73652, - 73656, 73660, 73664, 73668, 73672, 73676, 73680, 73684, 73688, 73692, - 73696, 73700, 73704, 73708, 73712, 73716, 73720, 73724, 73728, 73732, - 73736, 73740, 73744, 73748, 73752, 73756, 73760, 73764, 73768, 73772, - 73776, 73780, 73784, 73788, 73792, 73796, 73800, 73804, 73808, 73812, - 73816, 73820, 73824, 73828, 73832, 73836, 73840, 73844, 73848, 73852, - 73856, 73860, 73864, 73868, 73872, 73876, 73880, 73884, 73888, 73892, - 73896, 73900, 73904, 73908, 73912, 73916, 73920, 73924, 73928, 73932, - 73936, 73940, 73944, 73948, 73952, 73956, 73960, 73964, 73968, 73972, - 73976, 73980, 73984, 73988, 73992, 73996, 74000, 74004, 74008, 74012, - 74016, 74020, 74024, 74028, 74032, 74036, 74040, 74044, 74048, 74052, - 74056, 74060, 74064, 74068, 74072, 74076, 74080, 74084, 74088, 74092, - 74096, 74100, 74104, 74108, 74112, 74116, 74120, 74124, 74128, 74132, - 74136, 74140, 74144, 74148, 74152, 74156, 74160, 74164, 74168, 74172, - 74176, 74180, 74184, 74188, 74192, 74196, 74200, 74204, 74208, 74212, - 74216, 74220, 74224, 74228, 74232, 74236, 74240, 74244, 74248, 74252, - 74256, 74260, 74264, 74268, 74272, 74276, 74280, 0, 0, 0, 74284, 74288, - 74292, 74296, 74300, 74304, 74308, 74312, 74316, 74320, 74324, 74328, - 74332, 74336, 74340, 74344, 74348, 74352, 74356, 74360, 74364, 74368, - 74372, 74376, 74380, 74384, 74388, 74392, 74396, 74400, 74404, 74408, - 74412, 74416, 74420, 74424, 74428, 74432, 74436, 74440, 74444, 74448, - 74452, 74456, 74460, 74464, 74468, 74472, 74476, 74480, 74484, 74488, - 74492, 74496, 74500, 0, 0, 0, 0, 0, 0, 0, 0, 0, 74504, 74509, 74513, - 74518, 74523, 74528, 74533, 74538, 74542, 74547, 74552, 74557, 74562, - 74567, 74572, 74577, 74581, 74585, 74589, 74593, 74598, 74603, 74608, - 74612, 74617, 74622, 74627, 74632, 74637, 74641, 74646, 74650, 74655, - 74659, 74664, 74668, 74672, 74676, 74681, 74686, 74691, 74699, 74707, - 74715, 74723, 74730, 74738, 74744, 74752, 74756, 74760, 74764, 74768, - 74772, 74776, 74780, 74784, 74788, 74792, 74796, 74800, 74804, 74808, - 74812, 74816, 74820, 74824, 74828, 74832, 74836, 74840, 74844, 74848, - 74852, 74856, 74860, 74864, 74868, 74872, 74876, 74880, 74884, 74888, - 74892, 74896, 74899, 74903, 74907, 74911, 74915, 74919, 74923, 74927, - 74931, 74935, 74939, 74943, 74947, 74951, 74955, 74959, 74963, 74967, - 74971, 74975, 74979, 74983, 74987, 74991, 74995, 74999, 75003, 75007, - 75011, 75015, 75019, 75023, 75027, 75031, 75035, 75039, 75043, 75046, - 75050, 75054, 75057, 75061, 75065, 75069, 75072, 75076, 75080, 75084, - 75088, 75092, 75096, 75100, 75104, 75108, 75112, 75116, 75120, 75124, - 75127, 75130, 75134, 75138, 75141, 75145, 75149, 75153, 75157, 75161, - 75165, 75168, 75171, 75175, 75179, 75183, 75186, 75189, 75193, 75197, - 75201, 75205, 75209, 75213, 75217, 75221, 75225, 75229, 75233, 75237, - 75241, 75245, 75249, 75253, 75257, 75261, 75265, 75269, 75273, 75277, - 75281, 75285, 75289, 75293, 75297, 75301, 75305, 75309, 75313, 75317, - 75321, 75325, 75329, 75333, 75337, 75340, 75344, 75348, 75352, 75356, - 75360, 75364, 75368, 75372, 75376, 75380, 75384, 75388, 75392, 75396, - 75400, 75404, 75408, 75412, 75416, 75420, 75424, 75428, 75432, 75436, - 75440, 75444, 75448, 75452, 75456, 75460, 75464, 75468, 75472, 75476, - 75480, 75484, 75487, 75491, 75495, 75499, 75503, 75507, 75511, 75515, - 75519, 75523, 75527, 75531, 75535, 75539, 75543, 75547, 75551, 75554, - 75558, 75562, 75566, 75570, 75574, 75578, 75582, 75586, 75590, 75594, - 75598, 75602, 75606, 75610, 75614, 75618, 75622, 75626, 75630, 75634, - 75638, 75641, 75645, 75649, 75653, 75657, 75661, 75665, 75669, 75673, - 75677, 75681, 75685, 75689, 75693, 75697, 75701, 75705, 75709, 75713, - 75717, 75721, 75725, 75729, 75733, 75737, 75741, 75745, 75749, 75753, - 75757, 75761, 75765, 75769, 75773, 75777, 75781, 75785, 75789, 75793, - 75797, 75801, 75805, 75809, 75813, 75816, 75821, 75825, 75831, 75836, - 75842, 75846, 75850, 75854, 75858, 75862, 75866, 75870, 75874, 75878, - 75882, 75886, 75890, 75894, 75898, 75901, 75904, 75907, 75910, 75913, - 75916, 75919, 75922, 75925, 75930, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 75936, 75941, 75946, 75951, 75956, 75963, 75970, - 75975, 75980, 75985, 75990, 75997, 76004, 76011, 76018, 76025, 76032, - 76042, 76052, 76059, 76066, 76073, 76080, 76086, 76092, 76101, 76110, - 76117, 76124, 76135, 76146, 76151, 76156, 76163, 76170, 76177, 76184, - 76191, 76198, 76205, 76212, 76218, 76224, 76230, 76236, 76243, 76250, - 76255, 76259, 76266, 76273, 76280, 76284, 76291, 76295, 76300, 76304, - 76310, 76315, 76321, 76326, 76330, 76334, 76337, 76340, 76345, 76350, - 76355, 76360, 76365, 76370, 76375, 76380, 76385, 76390, 76398, 76406, - 76411, 76416, 76421, 76426, 76431, 76436, 76441, 76446, 76451, 76456, - 76461, 76466, 76471, 76476, 76482, 76488, 76494, 76500, 76505, 76511, - 76514, 76517, 76520, 76524, 76528, 76532, 76536, 76539, 76543, 76546, - 76549, 76552, 76556, 76560, 76564, 76568, 76572, 76576, 76580, 76584, - 76588, 76592, 76596, 76600, 76604, 76608, 76612, 76616, 76620, 76624, - 76628, 76632, 76636, 76640, 76643, 76647, 76651, 76655, 76659, 76663, - 76667, 76671, 76675, 76679, 76683, 76687, 76691, 76695, 76699, 76703, - 76707, 76711, 76715, 76719, 76723, 76727, 76731, 76735, 76739, 76742, - 76746, 76750, 76754, 76758, 76762, 76766, 76770, 76773, 76777, 76781, - 76785, 76789, 76793, 76797, 76801, 76805, 76809, 76813, 76817, 76821, - 76826, 76831, 76834, 76839, 76842, 76845, 76848, 0, 0, 0, 0, 0, 0, 0, 0, - 76852, 76861, 76870, 76879, 76888, 76897, 76906, 76915, 76924, 76932, - 76939, 76947, 76954, 76962, 76972, 76981, 76991, 77000, 77010, 77018, - 77025, 77033, 77040, 77048, 77053, 77058, 77064, 77072, 77078, 77084, - 77091, 77100, 77108, 77116, 77124, 77131, 77138, 77145, 77152, 77157, - 77162, 77167, 77172, 77177, 77182, 77187, 77192, 77200, 77208, 77214, - 77220, 77225, 77230, 77235, 77240, 77245, 77250, 77255, 77260, 77269, - 77278, 77283, 77288, 77298, 77308, 77315, 77322, 77331, 77340, 77352, - 77364, 77370, 77376, 77384, 77392, 77402, 77412, 77419, 77426, 77431, - 77436, 77448, 77460, 77468, 77476, 77486, 77496, 77508, 77520, 77529, - 77538, 77545, 77552, 77559, 77566, 77575, 77584, 77589, 77594, 77601, - 77608, 77615, 77622, 77634, 77646, 77651, 77656, 77661, 77666, 77671, - 77676, 77681, 77686, 77690, 77695, 77700, 77705, 77710, 77715, 77721, - 77726, 77731, 77738, 77745, 77752, 77759, 77766, 77774, 77782, 77787, - 77792, 77798, 77804, 77811, 77818, 77825, 77832, 77839, 77843, 77850, - 77855, 77860, 77866, 77879, 77885, 77893, 77901, 77908, 77915, 77924, - 77933, 77940, 77947, 77954, 77961, 77968, 77975, 77982, 77989, 77996, - 78003, 78012, 78021, 78030, 78039, 78048, 78057, 78066, 78075, 78084, - 78093, 78100, 78108, 78114, 78122, 78128, 78134, 78140, 78146, 78154, - 78159, 78164, 78169, 78174, 78179, 78185, 78191, 78197, 78203, 78209, - 78215, 78221, 78227, 78234, 78241, 78248, 78255, 78264, 78271, 78280, - 78292, 78304, 78316, 0, 0, 0, 0, 0, 78328, 78337, 0, 78346, 0, 78352, - 78358, 78366, 78374, 78381, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 78388, 78393, 78398, 78403, 78411, 78419, - 78426, 78433, 78439, 78446, 78454, 78462, 78470, 78478, 78486, 78492, - 78498, 78505, 78511, 78517, 78523, 78530, 78537, 78544, 78551, 78558, - 78565, 78572, 78579, 78586, 78593, 78600, 78607, 78614, 78621, 78627, - 78634, 78641, 78648, 78655, 78662, 78669, 78676, 78683, 78690, 78697, - 78704, 78711, 78718, 78725, 78732, 78739, 78746, 78753, 78761, 78769, - 78777, 78785, 78793, 0, 0, 0, 78802, 78810, 78818, 78826, 78834, 78842, - 78850, 78856, 78862, 78868, 0, 0, 0, 0, 0, 0, 78874, 78878, 78883, 78888, - 78893, 78898, 78903, 78908, 78913, 78918, 78923, 78928, 78932, 78936, - 78941, 78946, 78950, 78955, 78960, 78965, 78970, 78975, 78980, 78985, - 78989, 78993, 78997, 79002, 79006, 79010, 79014, 79018, 79022, 79026, - 79030, 79035, 79040, 79045, 79050, 79055, 79062, 79068, 79073, 79078, - 79083, 79088, 79094, 79101, 79107, 79114, 79120, 79126, 79131, 79138, - 79144, 79149, 0, 0, 0, 0, 0, 0, 0, 0, 79155, 79160, 79165, 79169, 79174, - 79178, 79183, 79187, 79192, 79197, 79203, 79208, 79214, 79218, 79223, - 79228, 79232, 79237, 79242, 79246, 79251, 79256, 79261, 79266, 79271, - 79276, 79281, 79286, 79291, 79296, 79301, 79306, 79311, 79316, 79321, - 79326, 79331, 79336, 79340, 79344, 79349, 79354, 79359, 79363, 79367, - 79371, 79375, 79380, 79385, 79390, 79394, 79398, 79403, 79409, 79415, - 79420, 79426, 79431, 79437, 79443, 79450, 79456, 79463, 79468, 79474, - 79480, 79485, 79491, 79497, 79502, 0, 0, 0, 0, 0, 0, 0, 0, 79507, 79511, - 79516, 79521, 79525, 79529, 79533, 79537, 79541, 79545, 79549, 79553, 0, - 0, 0, 0, 0, 0, 79557, 79562, 79566, 79570, 79574, 79578, 79582, 79586, - 79590, 79594, 79598, 79602, 79606, 79610, 79614, 79618, 79622, 79627, - 79632, 79638, 79644, 79651, 79656, 79661, 79667, 79671, 79676, 79679, - 79682, 79686, 79691, 79695, 79700, 79707, 79713, 79719, 79725, 79731, - 79737, 79743, 79749, 79755, 79761, 79767, 79774, 79781, 79788, 79794, - 79801, 79808, 79815, 79822, 79829, 79835, 79841, 79848, 79854, 79861, - 79868, 79874, 79880, 79886, 79893, 79900, 79906, 79913, 79920, 79926, - 79933, 79939, 79946, 79953, 79959, 79965, 79972, 79978, 79985, 79992, - 80001, 80008, 80015, 80019, 80024, 80029, 80034, 80039, 80043, 80047, - 80052, 80056, 80061, 80066, 80071, 80075, 80079, 80083, 80087, 80092, - 80096, 80101, 80106, 80111, 80116, 80120, 80125, 80130, 80135, 80141, - 80146, 80152, 80158, 80164, 80170, 80176, 80181, 80187, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 80191, 80196, 80200, 80204, 80208, 80212, 80216, 80220, - 80224, 80228, 80232, 80236, 80240, 80244, 80248, 80252, 80256, 80260, - 80264, 80268, 80272, 80276, 80280, 80284, 80288, 80292, 80296, 80300, - 80304, 80308, 0, 0, 0, 80312, 80317, 80322, 80327, 80332, 80336, 80343, - 80347, 80352, 80356, 80363, 80370, 80379, 80383, 80388, 80392, 80396, - 80403, 80410, 80415, 80422, 80427, 80432, 80439, 80444, 80451, 80458, - 80463, 80468, 80475, 80480, 80487, 80494, 80499, 80506, 80511, 80518, - 80522, 80526, 80533, 80538, 80545, 80549, 80553, 80557, 80564, 80568, - 80573, 80580, 80587, 80591, 80595, 80602, 80608, 80614, 80620, 80628, - 80634, 80642, 80648, 80656, 80662, 80668, 80674, 80680, 80684, 80689, - 80694, 80700, 80706, 80712, 80718, 80724, 80730, 80736, 80742, 80750, - 80756, 0, 80763, 80767, 80772, 80776, 80780, 80784, 80788, 80792, 80796, - 80800, 80804, 0, 0, 0, 0, 80808, 80816, 80822, 80828, 80834, 80840, - 80846, 80852, 80858, 80865, 80872, 80879, 80886, 80893, 80900, 80907, - 80914, 80921, 80928, 80935, 80941, 80947, 80953, 80959, 80965, 80971, - 80977, 80983, 80989, 80996, 81003, 81010, 81017, 0, 81024, 81028, 81032, - 81036, 81040, 81045, 81049, 81053, 81058, 81063, 81068, 81073, 81078, - 81083, 81088, 81093, 81098, 81103, 81108, 81113, 81118, 81123, 81128, - 81133, 81138, 81142, 81147, 81151, 81156, 81161, 81166, 81171, 81176, - 81180, 81185, 81189, 81193, 81197, 81202, 81207, 81211, 81215, 81221, - 81226, 81232, 81238, 81243, 81249, 81254, 81260, 81266, 81272, 81277, - 81282, 81287, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81293, 81299, 81305, 81311, - 81318, 81324, 81330, 81336, 81342, 81348, 81353, 81358, 81364, 81371, 0, - 0, 81378, 81383, 81387, 81391, 81395, 81399, 81403, 81407, 81411, 81415, - 0, 0, 81419, 81425, 81431, 81438, 81446, 81452, 81458, 81464, 81470, - 81476, 81482, 81488, 81494, 81500, 81506, 81512, 81517, 81522, 81527, - 81533, 81539, 81546, 81552, 81558, 81563, 81570, 81577, 81584, 81590, - 81595, 81600, 81605, 81613, 81620, 81627, 81635, 81643, 81650, 81657, - 81664, 81671, 81678, 81685, 81692, 81699, 81706, 81713, 81720, 81727, - 81734, 81741, 81748, 81755, 81762, 81769, 81776, 81783, 81789, 81795, - 81802, 81809, 81816, 81823, 81830, 81837, 81844, 81851, 81858, 81865, - 81872, 81879, 81886, 81893, 81900, 81907, 81914, 81921, 81928, 81935, - 81942, 81949, 81956, 81963, 81969, 81975, 81982, 81988, 81993, 81999, - 82004, 82009, 82014, 82021, 82027, 82033, 82039, 82045, 82051, 82057, - 82063, 82071, 82079, 82087, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 82095, 82101, 82107, 82113, 82121, 82129, - 82135, 82141, 82148, 82155, 82162, 82169, 82176, 82183, 82190, 82197, - 82204, 82212, 82220, 82228, 82236, 82244, 82250, 82258, 82264, 82272, - 82281, 82289, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82295, 82299, 82303, 82307, - 82311, 82315, 0, 0, 82319, 82323, 82327, 82331, 82335, 82339, 0, 0, - 82343, 82347, 82351, 82355, 82359, 82363, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 82367, 82371, 82375, 82379, 82383, 82387, 82391, 0, 82395, 82399, 82403, - 82407, 82411, 82415, 82419, 0, 82423, 82430, 82436, 82442, 82448, 82456, - 82463, 82472, 82484, 82494, 82503, 82511, 82519, 82527, 82533, 82541, - 82549, 82556, 82564, 82574, 82581, 82590, 82596, 82606, 82615, 82620, - 82628, 82637, 82642, 82651, 82658, 82668, 82680, 82685, 82691, 82698, - 82703, 82713, 82723, 82733, 82743, 82758, 82771, 82782, 82790, 82795, - 82807, 82816, 82823, 82830, 82836, 82843, 82848, 82855, 82861, 82872, - 82883, 82893, 82899, 82904, 0, 0, 0, 0, 82909, 82913, 82917, 82921, - 82925, 82929, 82934, 82939, 82943, 82948, 82953, 82958, 82963, 82968, - 82972, 82977, 82982, 82987, 82992, 82997, 83001, 83006, 83011, 83016, - 83021, 83026, 83030, 83035, 83040, 83045, 83050, 83054, 83059, 83064, - 83069, 83074, 83079, 83084, 83089, 83094, 83099, 83104, 83109, 83114, - 83119, 83123, 83128, 83133, 83138, 83143, 83148, 83153, 83158, 83163, - 83168, 83173, 83178, 83183, 83188, 83193, 83198, 83203, 83208, 83213, - 83218, 83223, 83228, 83233, 83238, 83243, 83248, 83253, 83258, 83263, - 83268, 83273, 83278, 83283, 83288, 83293, 83297, 83304, 83311, 83318, - 83325, 83331, 83337, 83344, 83351, 83358, 83365, 83372, 83379, 83386, - 83393, 83400, 83406, 83413, 83420, 83427, 83434, 83441, 83448, 83455, - 83462, 83469, 83476, 83483, 83492, 83501, 83510, 83519, 83528, 83537, - 83546, 83555, 83563, 83571, 83579, 83587, 83595, 83603, 83611, 83619, - 83625, 83633, 0, 0, 83641, 83648, 83654, 83660, 83666, 83672, 83678, - 83684, 83690, 83696, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 95159, 95166, 95173, 95180, 95187, 95194, 95201, 95208, 95215, + 95222, 95229, 95236, 95243, 95250, 95257, 95264, 95271, 95278, 95285, + 95292, 95300, 95308, 95315, 95322, 95327, 95335, 95343, 95350, 95357, + 95362, 95369, 95374, 95379, 95386, 95391, 95396, 95401, 95409, 95414, + 95419, 95426, 95431, 95436, 95443, 95450, 95455, 95460, 95465, 95470, + 95475, 95480, 95485, 95490, 95495, 95502, 95507, 95514, 95519, 95524, + 95529, 95534, 95539, 95544, 95549, 95554, 95559, 95564, 95569, 95576, + 95583, 95590, 95597, 95603, 95608, 95615, 95620, 95625, 95634, 95641, + 95650, 95657, 95662, 95667, 95675, 95680, 95685, 95690, 95695, 95700, + 95707, 95712, 95717, 95722, 95727, 95732, 95739, 95746, 95753, 95760, + 95767, 95774, 95781, 95788, 95795, 95802, 95809, 95816, 95823, 95830, + 95837, 95844, 95851, 95858, 95865, 95872, 95879, 95886, 95893, 95900, + 95907, 95914, 95921, 95928, 0, 0, 0, 0, 0, 95935, 95943, 95951, 0, 0, 0, + 0, 95956, 95960, 95964, 95968, 95972, 95976, 95980, 95984, 95988, 95992, + 95997, 96002, 96007, 96012, 96017, 96022, 96027, 96032, 96037, 96043, + 96049, 96055, 96062, 96069, 96076, 96083, 96090, 96097, 96102, 96107, + 96112, 96118, 96124, 96130, 96136, 96142, 96148, 96154, 96160, 96166, + 96172, 96178, 96184, 96190, 96196, 0, 0, 0, 96202, 96210, 96218, 96226, + 96234, 96242, 96252, 96262, 96270, 96278, 96286, 96294, 96302, 96308, + 96315, 96324, 96332, 96340, 96349, 96358, 96367, 96377, 96388, 96398, + 96409, 96418, 96427, 96436, 96446, 96457, 96467, 96478, 96489, 96498, + 96506, 96512, 96518, 96524, 96530, 96538, 96546, 96552, 96559, 96569, + 96576, 96583, 96590, 96597, 96604, 96614, 96621, 96628, 96636, 96644, + 96653, 96662, 96671, 96680, 96689, 96696, 96704, 96713, 96722, 96726, + 96733, 96738, 96743, 96747, 96751, 96755, 96759, 96764, 96769, 96775, + 96781, 96785, 96791, 96795, 96799, 96803, 96807, 96811, 96815, 96821, + 96825, 96830, 96834, 96838, 0, 96841, 96846, 96851, 96856, 96861, 96868, + 96873, 96878, 96883, 96888, 96893, 96898, 96903, 0, 0, 0, 96906, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83702, 83707, 83712, 83717, 83722, - 83727, 83732, 83737, 83742, 83747, 83752, 83757, 83762, 83767, 83772, - 83777, 83782, 83787, 83792, 83797, 83802, 83807, 83812, 0, 0, 0, 0, - 83817, 83821, 83825, 83829, 83833, 83837, 83841, 83845, 83849, 83853, - 83857, 83861, 83865, 83869, 83873, 83877, 83881, 83885, 83889, 83893, - 83897, 83901, 83905, 83909, 83913, 83917, 83921, 83925, 83929, 83933, - 83937, 83941, 83945, 83949, 83953, 83957, 83961, 83965, 83969, 83973, - 83977, 83981, 83985, 83989, 83993, 83997, 84001, 84005, 84009, 0, 0, 0, - 0, 84013, 84017, 84021, 84025, 84029, 84033, 84037, 84041, 84045, 84049, - 84053, 84057, 84061, 84065, 84069, 84073, 84077, 84081, 84085, 84089, - 84093, 84097, 84101, 84105, 84109, 84113, 84117, 84121, 84125, 84129, - 84133, 84137, 84141, 84145, 84149, 84153, 84157, 84161, 84165, 84169, - 84173, 84177, 84181, 84185, 84189, 84193, 84197, 84201, 84205, 84209, - 84213, 84217, 84221, 84225, 84229, 84233, 84237, 84241, 84245, 84249, - 84253, 84257, 84261, 84265, 84269, 84273, 84277, 84281, 84285, 84289, - 84293, 84297, 84301, 84305, 84309, 84313, 84317, 84321, 84325, 84329, - 84333, 84337, 84341, 84345, 84349, 84353, 84357, 84361, 84365, 84369, - 84373, 84377, 84381, 84385, 84389, 84393, 84397, 84401, 84405, 84409, - 84413, 84417, 84421, 84425, 84429, 84433, 84437, 84441, 84445, 84449, - 84453, 84457, 84461, 84465, 84469, 84473, 84477, 84481, 84485, 84489, - 84493, 84497, 84501, 84505, 84509, 84513, 84517, 84521, 84525, 84529, - 84533, 84537, 84541, 84545, 84549, 84553, 84557, 84561, 84565, 84569, - 84573, 84577, 84581, 84585, 84589, 84593, 84597, 84601, 84605, 84609, - 84613, 84617, 84621, 84625, 84629, 84633, 84637, 84641, 84645, 84649, - 84653, 84657, 84661, 84665, 84669, 84673, 84677, 84681, 84685, 84689, - 84693, 84697, 84701, 84705, 84709, 84713, 84717, 84721, 84725, 84729, - 84733, 84737, 84741, 84745, 84749, 84753, 84757, 84761, 84765, 84769, - 84773, 84777, 84781, 84785, 84789, 84793, 84797, 84801, 84805, 84809, - 84813, 84817, 84821, 84825, 84829, 84833, 84837, 84841, 84845, 84849, - 84853, 84857, 84861, 84865, 84869, 84873, 84877, 84881, 84885, 84889, - 84893, 84897, 84901, 84905, 84909, 84913, 84917, 84921, 84925, 84929, - 84933, 84937, 84941, 84945, 84949, 84953, 84957, 84961, 84965, 84969, - 84973, 84977, 84981, 84985, 84989, 84993, 84997, 85001, 85005, 85009, - 85013, 85017, 85021, 85025, 85029, 85033, 85037, 85041, 85045, 85049, - 85053, 85057, 85061, 85065, 85069, 85073, 85077, 85081, 85085, 85089, - 85093, 85097, 85101, 85105, 85109, 85113, 85117, 85121, 85125, 85129, - 85133, 85137, 85141, 85145, 85149, 85153, 85157, 85161, 85165, 85169, - 85173, 85177, 85181, 85185, 85189, 85193, 85197, 85201, 85205, 85209, - 85213, 85217, 85221, 85225, 85229, 85233, 85237, 85241, 85245, 85249, - 85253, 85257, 85261, 85265, 85269, 85273, 85277, 85281, 85285, 85289, - 85293, 85297, 85301, 85305, 85309, 85313, 85317, 85321, 85325, 85329, - 85333, 85337, 85341, 85345, 85349, 85353, 85357, 85361, 85365, 85369, - 85373, 85377, 85381, 85385, 85389, 85393, 85397, 85401, 85405, 85409, - 85413, 85417, 85421, 85425, 85429, 85433, 85437, 85441, 85445, 85449, - 85453, 85457, 85461, 85465, 85469, 85473, 0, 0, 85477, 85481, 85485, - 85489, 85493, 85497, 85501, 85505, 85509, 85513, 85517, 85521, 85525, - 85529, 85533, 85537, 85541, 85545, 85549, 85553, 85557, 85561, 85565, - 85569, 85573, 85577, 85581, 85585, 85589, 85593, 85597, 85601, 85605, - 85609, 85613, 85617, 85621, 85625, 85629, 85633, 85637, 85641, 85645, - 85649, 85653, 85657, 85661, 85665, 85669, 85673, 85677, 85681, 85685, - 85689, 85693, 85697, 85701, 85705, 85709, 85713, 85717, 85721, 85725, - 85729, 85733, 85737, 85741, 85745, 85749, 85753, 85757, 85761, 85765, - 85769, 85773, 85777, 85781, 85785, 85789, 85793, 85797, 85801, 85805, - 85809, 85813, 85817, 85821, 85825, 85829, 85833, 85837, 85841, 85845, - 85849, 85853, 85857, 85861, 85865, 85869, 85873, 85877, 85881, 85885, - 85889, 85893, 85897, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85901, - 85906, 85911, 85916, 85921, 85926, 85934, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 85939, 85947, 85955, 85963, 85971, 0, 0, 0, 0, 0, 85979, 85986, - 85993, 86003, 86009, 86015, 86021, 86027, 86033, 86039, 86046, 86052, - 86058, 86064, 86073, 86082, 86094, 86106, 86112, 86118, 86124, 86131, - 86138, 86145, 86152, 86159, 0, 86166, 86173, 86180, 86188, 86195, 0, - 86202, 0, 86209, 86216, 0, 86223, 86231, 0, 86238, 86245, 86252, 86259, - 86266, 86273, 86280, 86287, 86294, 86301, 86306, 86313, 86320, 86326, - 86332, 86338, 86345, 86351, 86357, 86363, 86370, 86376, 86382, 86388, - 86395, 86401, 86407, 86413, 86420, 86426, 86432, 86438, 86445, 86451, - 86457, 86463, 86470, 86476, 86482, 86488, 86495, 86501, 86507, 86513, - 86520, 86526, 86532, 86538, 86545, 86551, 86557, 86563, 86570, 86576, - 86582, 86588, 86595, 86601, 86607, 86613, 86620, 86626, 86632, 86638, - 86644, 86650, 86656, 86662, 86668, 86674, 86680, 86686, 86692, 86698, - 86704, 86710, 86717, 86723, 86729, 86735, 86742, 86748, 86754, 86760, - 86767, 86773, 86779, 86785, 86792, 86800, 86808, 86814, 86820, 86826, - 86833, 86842, 86851, 86859, 86867, 86875, 86884, 86892, 86900, 86908, - 86917, 86924, 86931, 86942, 86953, 86957, 86961, 86966, 86971, 86976, - 86981, 86990, 86999, 87005, 87011, 87018, 87025, 87032, 87036, 87042, - 87048, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87053, 87059, - 87065, 87071, 87078, 87083, 87088, 87094, 87100, 87106, 87112, 87121, - 87127, 87133, 87141, 87149, 87157, 87165, 87171, 87177, 87183, 87190, - 87203, 87217, 87228, 87239, 87251, 87263, 87275, 87287, 87298, 87309, - 87321, 87333, 87345, 87357, 87369, 87381, 87393, 87410, 87427, 87444, - 87451, 87458, 87465, 87473, 87485, 87496, 87507, 87520, 87531, 87540, - 87548, 87557, 87565, 87575, 87583, 87592, 87600, 87609, 87617, 87627, - 87635, 87644, 87652, 87662, 87670, 87678, 87686, 87694, 87701, 87710, - 87718, 87726, 87735, 87743, 87752, 87760, 87768, 87776, 87785, 87793, - 87802, 87810, 87818, 87826, 87834, 87843, 87851, 87860, 87868, 87877, - 87885, 87894, 87902, 87912, 87920, 87928, 87936, 87946, 87954, 87962, - 87971, 87979, 87988, 87997, 88005, 88015, 88023, 88032, 88040, 88049, - 88057, 88067, 88075, 88083, 88090, 88098, 88105, 88114, 88121, 88130, - 88138, 88147, 88155, 88165, 88173, 88182, 88190, 88200, 88208, 88216, - 88223, 88231, 88238, 88247, 88254, 88264, 88274, 88285, 88294, 88303, - 88312, 88321, 88330, 88340, 88352, 88364, 88375, 88387, 88400, 88411, - 88420, 88429, 88437, 88446, 88456, 88464, 88473, 88482, 88490, 88499, - 88509, 88517, 88526, 88535, 88543, 88552, 88562, 88570, 88580, 88588, - 88598, 88606, 88614, 88623, 88631, 88641, 88649, 88657, 88667, 88675, - 88682, 88689, 88698, 88707, 88715, 88724, 88734, 88742, 88753, 88761, - 88769, 88776, 88784, 88793, 88800, 88812, 88823, 88835, 88846, 88858, - 88867, 88875, 88884, 88892, 88901, 88910, 88918, 88927, 88935, 88944, - 88952, 88960, 88968, 88976, 88983, 88992, 89000, 89009, 89017, 89026, - 89034, 89042, 89051, 89059, 89068, 89076, 89085, 89093, 89101, 89109, - 89118, 89126, 89135, 89143, 89152, 89160, 89169, 89177, 89185, 89193, - 89202, 89210, 89219, 89228, 89236, 89245, 89253, 89262, 89270, 89279, - 89287, 89294, 89302, 89309, 89318, 89326, 89335, 89343, 89352, 89361, - 89369, 89379, 89387, 89394, 89402, 89409, 89417, 89429, 89442, 89451, - 89461, 89470, 89480, 89489, 89499, 89508, 89518, 89527, 89537, 89547, - 89556, 89565, 89574, 89584, 89592, 89601, 89611, 89621, 89631, 89641, - 89649, 89659, 89667, 89677, 89685, 89695, 89703, 89713, 89721, 89730, - 89737, 89747, 89755, 89765, 89773, 89783, 89791, 89801, 89809, 89818, - 89826, 89835, 89843, 89852, 89861, 89870, 89879, 89889, 89897, 89907, - 89915, 89925, 89933, 89943, 89951, 89961, 89969, 89978, 89985, 89995, - 90003, 90013, 90021, 90031, 90039, 90049, 90057, 90066, 90074, 90083, - 90091, 90100, 90109, 90118, 90127, 90136, 90144, 90153, 90161, 90170, - 90179, 90187, 90197, 90206, 90216, 90226, 90235, 90245, 90254, 90263, - 90271, 90279, 90284, 90289, 90295, 90303, 90311, 90319, 90327, 90335, - 90343, 90349, 90355, 90361, 90369, 90375, 90385, 90391, 90397, 90403, - 90414, 90425, 90436, 90446, 90457, 90468, 90478, 90489, 90499, 90509, - 90518, 90529, 90540, 90551, 90564, 90574, 90584, 90595, 90605, 90615, - 90625, 90635, 90645, 90655, 90665, 90676, 90687, 90698, 90708, 90718, - 90730, 90741, 90752, 90762, 90772, 90782, 90792, 90803, 90813, 90823, - 90835, 90845, 90855, 90867, 90878, 90889, 90899, 90909, 90919, 90929, - 90941, 90953, 90965, 90976, 90987, 90997, 91007, 91017, 91026, 91035, - 91045, 91055, 91066, 0, 0, 91076, 91087, 91098, 91108, 91118, 91130, - 91141, 91152, 91165, 91175, 91187, 91196, 91205, 91216, 91227, 91240, - 91251, 91264, 91274, 91286, 91296, 91308, 91320, 91333, 91343, 91353, - 91363, 91374, 91384, 91393, 91403, 91412, 91421, 91431, 91441, 91451, - 91461, 91471, 91481, 91492, 91502, 91513, 91523, 91534, 91545, 91555, - 91565, 91575, 91585, 91595, 91605, 91616, 91626, 91637, 0, 0, 0, 0, 0, 0, - 0, 91648, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 91654, 91669, 91684, 91690, 91696, - 91702, 91708, 91714, 91720, 91726, 91732, 91740, 91744, 91747, 91755, - 91763, 91771, 91774, 91777, 91780, 91783, 91786, 91789, 91792, 91795, - 91798, 91801, 91804, 91807, 91810, 91813, 91816, 91819, 91827, 91836, - 91847, 91855, 91863, 91872, 91881, 91893, 91905, 0, 0, 0, 0, 0, 0, 91915, - 91920, 91925, 91932, 91939, 91945, 91951, 91956, 91961, 91966, 91972, - 91978, 91984, 91990, 91996, 92003, 92010, 92020, 92030, 92040, 92049, - 92060, 92069, 92078, 92089, 92100, 92113, 92126, 92138, 92150, 92162, - 92174, 92185, 92196, 92207, 92218, 92230, 92242, 92246, 92251, 92261, - 92271, 92275, 92279, 92283, 92288, 92293, 92298, 92303, 92306, 92310, 0, - 92315, 92318, 92321, 92325, 92329, 92334, 92338, 92342, 92348, 92354, - 92362, 92370, 92373, 92376, 92379, 92382, 92385, 92389, 92393, 0, 92397, - 92402, 92406, 92410, 0, 0, 0, 0, 92415, 92420, 92427, 92432, 92437, 0, - 92442, 92447, 92453, 92458, 92464, 92469, 92475, 92480, 92486, 92491, - 92497, 92503, 92512, 92521, 92530, 92539, 92549, 92559, 92569, 92579, - 92588, 92597, 92606, 92616, 92621, 92626, 92632, 92638, 92644, 92651, - 92659, 92667, 92673, 92679, 92685, 92692, 92698, 92704, 92710, 92717, - 92723, 92729, 92735, 92742, 92747, 92752, 92757, 92763, 92769, 92775, - 92781, 92788, 92794, 92800, 92806, 92812, 92818, 92824, 92830, 92836, - 92842, 92848, 92854, 92861, 92867, 92873, 92879, 92886, 92892, 92898, - 92904, 92911, 92917, 92923, 92929, 92936, 92942, 92948, 92954, 92961, - 92967, 92973, 92979, 92986, 92992, 92998, 93004, 93011, 93017, 93023, - 93029, 93036, 93042, 93048, 93054, 93061, 93067, 93073, 93079, 93086, - 93092, 93098, 93104, 93111, 93117, 93123, 93129, 93136, 93141, 93146, - 93151, 93157, 93163, 93169, 93175, 93182, 93188, 93194, 93200, 93207, - 93213, 93219, 93226, 93233, 93238, 93243, 93248, 93254, 93266, 93278, - 93290, 93302, 93315, 93328, 93336, 0, 0, 93344, 0, 93352, 93357, 93362, - 93366, 93371, 93376, 93380, 93384, 93389, 93394, 93398, 93402, 93406, - 93410, 93416, 93420, 93425, 93429, 93433, 93437, 93441, 93445, 93449, - 93453, 93457, 93461, 93465, 93469, 93474, 93479, 93484, 93489, 93495, - 93501, 93508, 93515, 93522, 93528, 93535, 93542, 93549, 93555, 93562, - 93569, 93575, 93582, 93589, 93595, 93602, 93609, 93615, 93622, 93629, - 93635, 93642, 93649, 93656, 93663, 93670, 93676, 93682, 93688, 93694, - 93699, 93705, 93711, 93718, 93725, 93732, 93738, 93745, 93752, 93759, - 93765, 93772, 93779, 93785, 93792, 93799, 93805, 93812, 93819, 93825, - 93832, 93839, 93845, 93852, 93859, 93866, 93873, 93880, 93887, 93892, - 93899, 93903, 93909, 93915, 93921, 93927, 93933, 93937, 93942, 93947, - 93952, 93957, 93962, 93967, 93972, 93977, 93983, 93989, 93995, 94003, - 94007, 94011, 94015, 94019, 94023, 94027, 94032, 94037, 94042, 94047, - 94051, 94056, 94061, 94066, 94071, 94076, 94081, 94086, 94091, 94095, - 94099, 94104, 94109, 94114, 94119, 94123, 94128, 94133, 94138, 94143, - 94147, 94152, 94157, 94162, 94167, 94171, 94176, 94181, 94185, 94190, - 94195, 94200, 94205, 94210, 94215, 94222, 94229, 94233, 94238, 94243, - 94248, 94253, 94258, 94263, 94268, 94273, 94278, 94283, 94288, 94293, - 94298, 94303, 94308, 94313, 94318, 94323, 94328, 94333, 94338, 94343, - 94348, 94353, 94358, 94363, 94368, 94373, 94378, 0, 0, 0, 94383, 94387, - 94392, 94396, 94401, 94406, 0, 0, 94410, 94415, 94420, 94424, 94429, - 94434, 0, 0, 94439, 94444, 94448, 94453, 94458, 94463, 0, 0, 94468, - 94473, 94478, 0, 0, 0, 94482, 94487, 94492, 94497, 94501, 94506, 94511, - 0, 94516, 94522, 94525, 94529, 94532, 94536, 94540, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 94544, 94550, 94556, 94562, 94568, 0, 0, 94572, 94578, 94584, - 94590, 94596, 94602, 94609, 94616, 94623, 94630, 94637, 94644, 0, 94651, - 94658, 94665, 94671, 94678, 94685, 94692, 94699, 94705, 94712, 94719, - 94726, 94733, 94739, 94746, 94753, 94760, 94767, 94773, 94780, 94787, - 94794, 94801, 94808, 94815, 94822, 0, 94829, 94835, 94842, 94849, 94856, - 94863, 94869, 94876, 94883, 94890, 94897, 94904, 94911, 94918, 94924, - 94931, 94938, 94945, 94952, 0, 94959, 94966, 0, 94973, 94980, 94987, - 94994, 95001, 95008, 95015, 95022, 95029, 95036, 95043, 95050, 95057, - 95064, 95071, 0, 0, 95077, 95082, 95087, 95092, 95097, 95102, 95107, - 95112, 95117, 95122, 95127, 95132, 95137, 95142, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96912, 96919, + 96928, 96937, 96944, 96951, 96958, 96965, 96972, 96979, 96985, 96992, + 96999, 97006, 97013, 97020, 97027, 97034, 97041, 97050, 97057, 97064, + 97071, 97078, 97085, 97092, 97099, 97106, 97115, 97122, 97129, 97136, + 97143, 97150, 97157, 97166, 97173, 97180, 97187, 97194, 97203, 97210, + 97217, 97224, 97232, 97241, 0, 0, 97250, 97254, 97258, 97263, 97268, + 97273, 97278, 97282, 97287, 97292, 97297, 97302, 97307, 97312, 97316, + 97321, 97326, 97331, 97336, 97340, 97345, 97350, 97354, 97359, 97364, + 97369, 97374, 97379, 97384, 0, 0, 0, 97389, 97393, 97398, 97403, 97407, + 97412, 97416, 97421, 97426, 97431, 97436, 97441, 97445, 97450, 97455, + 97460, 97465, 97470, 97475, 97479, 97484, 97489, 97494, 97499, 97504, + 97509, 97513, 97517, 97522, 97527, 97532, 97537, 97542, 97547, 97552, + 97557, 97562, 97567, 97572, 97577, 97582, 97587, 97592, 97597, 97602, + 97607, 97612, 97617, 97622, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 97627, 97633, 97638, 97643, 97648, 97653, 97658, 97663, 97668, 97673, + 97678, 97684, 97690, 97696, 97702, 97708, 97714, 97720, 97726, 97732, + 97739, 97746, 97753, 97761, 97769, 97777, 97785, 97793, 0, 0, 0, 0, + 97801, 97805, 97810, 97815, 97820, 97824, 97829, 97834, 97839, 97844, + 97848, 97852, 97857, 97862, 97867, 97872, 97876, 97881, 97886, 97891, + 97896, 97901, 97906, 97910, 97915, 97920, 97925, 97930, 97935, 97940, + 97945, 97950, 97955, 97960, 97965, 97971, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 97977, 97982, 97989, 97996, 98001, 98006, 98011, 98016, 98021, 98026, + 98031, 98036, 98041, 98046, 98051, 98056, 98061, 98066, 98071, 98076, + 98081, 98086, 98091, 98096, 98101, 98106, 98111, 98116, 98121, 98126, 0, + 0, 0, 0, 0, 98133, 98139, 98145, 98151, 98157, 98162, 98168, 98174, + 98180, 98186, 98191, 98197, 98203, 98209, 98215, 98221, 98227, 98233, + 98239, 98245, 98250, 98256, 98262, 98268, 98274, 98280, 98285, 98291, + 98297, 98302, 98308, 98314, 98320, 98326, 98332, 98338, 98344, 98349, + 98355, 98362, 98369, 98376, 98383, 0, 0, 0, 0, 0, 98390, 98395, 98400, + 98405, 98410, 98415, 98420, 98425, 98430, 98435, 98440, 98445, 98450, + 98455, 98460, 98465, 98470, 98475, 98480, 98485, 98490, 98495, 98500, + 98505, 98510, 98515, 98520, 98524, 98528, 98532, 0, 98537, 98543, 98548, + 98553, 98558, 98563, 98569, 98575, 98581, 98587, 98593, 98599, 98605, + 98611, 98617, 98623, 98629, 98635, 98641, 98646, 98652, 98658, 98663, + 98669, 98674, 98680, 98686, 98691, 98697, 98703, 98708, 98714, 98719, + 98724, 98730, 98736, 98742, 0, 0, 0, 0, 98747, 98753, 98759, 98765, + 98771, 98777, 98783, 98789, 98795, 98802, 98807, 98812, 98818, 98824, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 95147, 95154, 95161, 95168, 95175, 95182, 95189, 95196, 95203, - 95210, 95217, 95224, 95231, 95238, 95245, 95252, 95259, 95266, 95273, - 95280, 95288, 95296, 95303, 95310, 95315, 95323, 95331, 95338, 95345, - 95350, 95357, 95362, 95367, 95374, 95379, 95384, 95389, 95397, 95402, - 95407, 95414, 95419, 95424, 95431, 95438, 95443, 95448, 95453, 95458, - 95463, 95468, 95473, 95478, 95483, 95490, 95495, 95502, 95507, 95512, - 95517, 95522, 95527, 95532, 95537, 95542, 95547, 95552, 95557, 95564, - 95571, 95578, 95585, 95591, 95596, 95603, 95608, 95613, 95622, 95629, - 95638, 95645, 95650, 95655, 95663, 95668, 95673, 95678, 95683, 95688, - 95695, 95700, 95705, 95710, 95715, 95720, 95727, 95734, 95741, 95748, - 95755, 95762, 95769, 95776, 95783, 95790, 95797, 95804, 95811, 95818, - 95825, 95832, 95839, 95846, 95853, 95860, 95867, 95874, 95881, 95888, - 95895, 95902, 95909, 95916, 0, 0, 0, 0, 0, 95923, 95931, 95939, 0, 0, 0, - 0, 95944, 95948, 95952, 95956, 95960, 95964, 95968, 95972, 95976, 95980, - 95985, 95990, 95995, 96000, 96005, 96010, 96015, 96020, 96025, 96031, - 96037, 96043, 96050, 96057, 96064, 96071, 96078, 96085, 96090, 96095, - 96100, 96106, 96112, 96118, 96124, 96130, 96136, 96142, 96148, 96154, - 96160, 96166, 96172, 96178, 96184, 0, 0, 0, 96190, 96198, 96206, 96214, - 96222, 96230, 96240, 96250, 96258, 96266, 96274, 96282, 96290, 96296, - 96303, 96312, 96320, 96328, 96337, 96346, 96355, 96365, 96376, 96386, - 96397, 96406, 96415, 96424, 96434, 96445, 96455, 96466, 96477, 96486, - 96494, 96500, 96506, 96512, 96518, 96526, 96534, 96540, 96547, 96557, - 96564, 96571, 96578, 96585, 96592, 96602, 96609, 96616, 96624, 96632, - 96641, 96650, 96659, 96668, 96677, 96684, 96692, 96701, 96710, 96714, - 96721, 96726, 96731, 96735, 96739, 96743, 96747, 96752, 96757, 96763, - 96769, 96773, 96779, 96783, 96787, 96791, 96795, 96799, 96803, 96809, - 96813, 96818, 96822, 96826, 0, 96829, 96834, 96839, 96844, 96849, 96856, - 96861, 96866, 96871, 96876, 96881, 96886, 96891, 0, 0, 0, 96894, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 98830, 98836, 98842, + 98848, 98855, 98861, 98868, 98875, 98882, 98889, 98897, 98904, 98912, + 98918, 98924, 98930, 98936, 98942, 98948, 98954, 98960, 98966, 98972, + 98978, 98984, 98990, 98996, 99002, 99008, 99014, 99020, 99026, 99032, + 99038, 99044, 99050, 99056, 99062, 99068, 99074, 99080, 99086, 99092, + 99098, 99105, 99111, 99118, 99125, 99132, 99139, 99147, 99154, 99162, + 99168, 99174, 99180, 99186, 99192, 99198, 99204, 99210, 99216, 99222, + 99228, 99234, 99240, 99246, 99252, 99258, 99264, 99270, 99276, 99282, + 99288, 99294, 99300, 99306, 99312, 99318, 99324, 99330, 99335, 99340, + 99345, 99350, 99355, 99360, 99365, 99370, 99375, 99380, 99385, 99390, + 99395, 99400, 99405, 99410, 99415, 99420, 99425, 99430, 99435, 99440, + 99445, 99450, 99455, 99460, 99465, 99470, 99475, 99480, 99485, 99490, + 99495, 99500, 99505, 99510, 99515, 99520, 99525, 99530, 99535, 99540, + 99545, 99550, 99555, 99560, 99565, 99570, 99575, 99580, 99585, 99590, + 99595, 99600, 99605, 99609, 99613, 99618, 99623, 99628, 99633, 99638, + 99643, 99648, 99653, 99658, 99663, 99668, 99672, 99676, 99680, 99684, + 99688, 99692, 99696, 99701, 99706, 0, 0, 99711, 99716, 99720, 99724, + 99728, 99732, 99736, 99740, 99744, 99748, 0, 0, 0, 0, 0, 0, 99752, 99757, + 99763, 99769, 99775, 99781, 99787, 99793, 99798, 99804, 99809, 99815, + 99820, 99825, 99831, 99837, 99842, 99847, 99852, 99857, 99863, 99868, + 99874, 99879, 99885, 99891, 99897, 99903, 99909, 99915, 99921, 99926, + 99932, 99938, 99944, 99950, 0, 0, 0, 0, 99956, 99961, 99967, 99973, + 99979, 99985, 99991, 99997, 100002, 100008, 100013, 100019, 100024, + 100029, 100035, 100041, 100046, 100051, 100056, 100061, 100067, 100072, + 100078, 100083, 100089, 100095, 100101, 100107, 100113, 100119, 100125, + 100130, 100136, 100142, 100148, 100154, 0, 0, 0, 0, 100160, 100164, + 100169, 100174, 100179, 100184, 100189, 100194, 100199, 100203, 100208, + 100213, 100218, 100223, 100227, 100232, 100237, 100242, 100247, 100252, + 100257, 100261, 100266, 100270, 100275, 100280, 100285, 100290, 100295, + 100300, 100305, 100310, 100314, 100319, 100324, 100329, 100334, 100339, + 100344, 100349, 0, 0, 0, 0, 0, 0, 0, 0, 100354, 100361, 100368, 100375, + 100382, 100389, 100396, 100403, 100410, 100417, 100424, 100431, 100438, + 100445, 100452, 100459, 100466, 100473, 100480, 100487, 100494, 100501, + 100508, 100515, 100522, 100529, 100536, 100543, 100550, 100557, 100564, + 100571, 100578, 100585, 100592, 100599, 100606, 100613, 100620, 100627, + 100634, 100641, 100648, 100655, 100662, 100669, 100676, 100683, 100690, + 100697, 100704, 100711, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100718, 100725, + 100730, 100736, 100742, 100748, 100754, 100760, 100766, 100772, 100777, + 100783, 0, 100789, 100794, 100800, 100805, 100811, 100817, 100822, + 100827, 100833, 100839, 100845, 100851, 100856, 100862, 100868, 0, + 100874, 100880, 100886, 100892, 100898, 100903, 100909, 0, 100915, + 100921, 0, 100927, 100932, 100938, 100944, 100950, 100956, 100962, + 100968, 100974, 100979, 100985, 0, 100991, 100996, 101002, 101007, + 101013, 101019, 101024, 101029, 101035, 101041, 101047, 101053, 101058, + 101064, 101070, 0, 101076, 101082, 101088, 101094, 101100, 101105, + 101111, 0, 101117, 101123, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96900, 96907, - 96916, 96925, 96932, 96939, 96946, 96953, 96960, 96967, 96973, 96980, - 96987, 96994, 97001, 97008, 97015, 97022, 97029, 97038, 97045, 97052, - 97059, 97066, 97073, 97080, 97087, 97094, 97103, 97110, 97117, 97124, - 97131, 97138, 97145, 97154, 97161, 97168, 97175, 97182, 97191, 97198, - 97205, 97212, 97220, 97229, 0, 0, 97238, 97242, 97246, 97251, 97256, - 97261, 97266, 97270, 97275, 97280, 97285, 97290, 97295, 97300, 97304, - 97309, 97314, 97319, 97324, 97328, 97333, 97338, 97342, 97347, 97352, - 97357, 97362, 97367, 97372, 0, 0, 0, 97377, 97381, 97386, 97391, 97395, - 97400, 97404, 97409, 97414, 97419, 97424, 97429, 97433, 97438, 97443, - 97448, 97453, 97458, 97463, 97467, 97472, 97477, 97482, 97487, 97492, - 97497, 97501, 97505, 97510, 97515, 97520, 97525, 97530, 97535, 97540, - 97545, 97550, 97555, 97560, 97565, 97570, 97575, 97580, 97585, 97590, - 97595, 97600, 97605, 97610, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 97615, 97621, 97626, 97631, 97636, 97641, 97646, 97651, 97656, 97661, - 97666, 97672, 97678, 97684, 97690, 97696, 97702, 97708, 97714, 97720, - 97727, 97734, 97741, 97749, 97757, 97765, 97773, 97781, 0, 0, 0, 0, - 97789, 97793, 97798, 97803, 97808, 97812, 97817, 97822, 97827, 97832, - 97836, 97840, 97845, 97850, 97855, 97860, 97864, 97869, 97874, 97879, - 97884, 97889, 97894, 97898, 97903, 97908, 97913, 97918, 97923, 97928, - 97933, 97938, 97943, 97948, 97953, 97959, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 97965, 97970, 97977, 97984, 97989, 97994, 97999, 98004, 98009, 98014, - 98019, 98024, 98029, 98034, 98039, 98044, 98049, 98054, 98059, 98064, - 98069, 98074, 98079, 98084, 98089, 98094, 98099, 98104, 98109, 98114, 0, - 0, 0, 0, 0, 98121, 98127, 98133, 98139, 98145, 98150, 98156, 98162, - 98168, 98174, 98179, 98185, 98191, 98197, 98203, 98209, 98215, 98221, - 98227, 98233, 98238, 98244, 98250, 98256, 98262, 98268, 98273, 98279, - 98285, 98290, 98296, 98302, 98308, 98314, 98320, 98326, 98332, 98337, - 98343, 98350, 98357, 98364, 98371, 0, 0, 0, 0, 0, 98378, 98383, 98388, - 98393, 98398, 98403, 98408, 98413, 98418, 98423, 98428, 98433, 98438, - 98443, 98448, 98453, 98458, 98463, 98468, 98473, 98478, 98483, 98488, - 98493, 98498, 98503, 98508, 98512, 98516, 98520, 0, 98525, 98531, 98536, - 98541, 98546, 98551, 98557, 98563, 98569, 98575, 98581, 98587, 98593, - 98599, 98605, 98611, 98617, 98623, 98629, 98634, 98640, 98646, 98651, - 98657, 98662, 98668, 98674, 98679, 98685, 98691, 98696, 98702, 98707, - 98712, 98718, 98724, 98730, 0, 0, 0, 0, 98735, 98741, 98747, 98753, - 98759, 98765, 98771, 98777, 98783, 98790, 98795, 98800, 98806, 98812, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 98818, 98824, 98830, - 98836, 98843, 98849, 98856, 98863, 98870, 98877, 98885, 98892, 98900, - 98906, 98912, 98918, 98924, 98930, 98936, 98942, 98948, 98954, 98960, - 98966, 98972, 98978, 98984, 98990, 98996, 99002, 99008, 99014, 99020, - 99026, 99032, 99038, 99044, 99050, 99056, 99062, 99068, 99074, 99080, - 99086, 99093, 99099, 99106, 99113, 99120, 99127, 99135, 99142, 99150, - 99156, 99162, 99168, 99174, 99180, 99186, 99192, 99198, 99204, 99210, - 99216, 99222, 99228, 99234, 99240, 99246, 99252, 99258, 99264, 99270, - 99276, 99282, 99288, 99294, 99300, 99306, 99312, 99318, 99323, 99328, - 99333, 99338, 99343, 99348, 99353, 99358, 99363, 99368, 99373, 99378, - 99383, 99388, 99393, 99398, 99403, 99408, 99413, 99418, 99423, 99428, - 99433, 99438, 99443, 99448, 99453, 99458, 99463, 99468, 99473, 99478, - 99483, 99488, 99493, 99498, 99503, 99508, 99513, 99518, 99523, 99528, - 99533, 99538, 99543, 99548, 99553, 99558, 99563, 99568, 99573, 99578, - 99583, 99588, 99593, 99597, 99601, 99606, 99611, 99616, 99621, 99626, - 99631, 99636, 99641, 99646, 99651, 99656, 99660, 99664, 99668, 99672, - 99676, 99680, 99684, 99689, 99694, 0, 0, 99699, 99704, 99708, 99712, - 99716, 99720, 99724, 99728, 99732, 99736, 0, 0, 0, 0, 0, 0, 99740, 99745, - 99751, 99757, 99763, 99769, 99775, 99781, 99786, 99792, 99797, 99803, - 99808, 99813, 99819, 99825, 99830, 99835, 99840, 99845, 99851, 99856, - 99862, 99867, 99873, 99879, 99885, 99891, 99897, 99903, 99909, 99914, - 99920, 99926, 99932, 99938, 0, 0, 0, 0, 99944, 99949, 99955, 99961, - 99967, 99973, 99979, 99985, 99990, 99996, 100001, 100007, 100012, 100017, - 100023, 100029, 100034, 100039, 100044, 100049, 100055, 100060, 100066, - 100071, 100077, 100083, 100089, 100095, 100101, 100107, 100113, 100118, - 100124, 100130, 100136, 100142, 0, 0, 0, 0, 100148, 100152, 100157, - 100162, 100167, 100172, 100177, 100182, 100187, 100191, 100196, 100201, - 100206, 100211, 100215, 100220, 100225, 100230, 100235, 100240, 100245, - 100249, 100254, 100258, 100263, 100268, 100273, 100278, 100283, 100288, - 100293, 100298, 100302, 100307, 100312, 100317, 100322, 100327, 100332, - 100337, 0, 0, 0, 0, 0, 0, 0, 0, 100342, 100349, 100356, 100363, 100370, - 100377, 100384, 100391, 100398, 100405, 100412, 100419, 100426, 100433, - 100440, 100447, 100454, 100461, 100468, 100475, 100482, 100489, 100496, - 100503, 100510, 100517, 100524, 100531, 100538, 100545, 100552, 100559, - 100566, 100573, 100580, 100587, 100594, 100601, 100608, 100615, 100622, - 100629, 100636, 100643, 100650, 100657, 100664, 100671, 100678, 100685, - 100692, 100699, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100706, 100713, 100718, - 100724, 100730, 100736, 100742, 100748, 100754, 100760, 100765, 100771, - 0, 100777, 100782, 100788, 100793, 100799, 100805, 100810, 100815, - 100821, 100827, 100833, 100839, 100844, 100850, 100856, 0, 100862, - 100868, 100874, 100880, 100886, 100891, 100897, 0, 100903, 100909, 0, - 100915, 100920, 100926, 100932, 100938, 100944, 100950, 100956, 100962, - 100967, 100973, 0, 100979, 100984, 100990, 100995, 101001, 101007, - 101012, 101017, 101023, 101029, 101035, 101041, 101046, 101052, 101058, - 0, 101064, 101070, 101076, 101082, 101088, 101093, 101099, 0, 101105, - 101111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 101129, 101134, 101139, 101144, 101149, 101154, 101159, + 101164, 101169, 101174, 101179, 101184, 101189, 101194, 101199, 101204, + 101209, 101214, 101219, 101224, 101229, 101234, 101239, 101244, 101249, + 101254, 101259, 101264, 101269, 101274, 101279, 101284, 101289, 101294, + 101299, 101304, 101309, 101314, 101319, 101324, 101329, 101334, 101339, + 101344, 101349, 101354, 101359, 101364, 101369, 101374, 101379, 101384, + 101389, 101394, 101399, 101404, 101409, 101414, 101419, 101424, 101429, + 101434, 101439, 101444, 101449, 101454, 101459, 101464, 101469, 101474, + 101479, 101484, 101489, 101494, 101499, 101504, 101509, 101514, 101519, + 101524, 101529, 101534, 101539, 101544, 101549, 101554, 101559, 101564, + 101569, 101574, 101579, 101584, 101589, 101594, 101599, 101604, 101609, + 101614, 101619, 101624, 101629, 101634, 101639, 101644, 101649, 101654, + 101659, 101664, 101669, 101674, 101679, 101684, 101689, 101694, 101699, + 101704, 101709, 101714, 101719, 101724, 101729, 101734, 101739, 101744, + 101749, 101754, 101759, 101764, 101769, 101774, 101779, 101784, 101789, + 101794, 101799, 101804, 101809, 101814, 101819, 101824, 101829, 101834, + 101839, 101844, 101849, 101854, 101859, 101864, 101869, 101874, 101879, + 101884, 101889, 101894, 101899, 101904, 101909, 101914, 101919, 101924, + 101929, 101934, 101939, 101944, 101949, 101954, 101959, 101964, 101969, + 101974, 101979, 101984, 101989, 101994, 101999, 102004, 102009, 102014, + 102019, 102024, 102029, 102034, 102039, 102044, 102049, 102054, 102059, + 102064, 102069, 102074, 102079, 102084, 102089, 102094, 102099, 102104, + 102109, 102114, 102119, 102124, 102129, 102134, 102139, 102144, 102149, + 102154, 102159, 102164, 102169, 102174, 102179, 102184, 102189, 102194, + 102199, 102204, 102209, 102214, 102219, 102224, 102229, 102234, 102239, + 102244, 102249, 102254, 102259, 102264, 102269, 102274, 102279, 102284, + 102289, 102294, 102299, 102304, 102309, 102314, 102319, 102324, 102329, + 102334, 102339, 102344, 102349, 102354, 102359, 102364, 102369, 102374, + 102379, 102384, 102389, 102394, 102399, 102404, 102409, 102414, 102419, + 102424, 102429, 102434, 102439, 102444, 102449, 102454, 102459, 102464, + 102469, 102474, 102479, 102484, 102489, 102494, 102499, 102504, 102509, + 102514, 102519, 102524, 102529, 102534, 102539, 102544, 102549, 102554, + 102559, 102564, 102569, 102574, 102579, 102584, 102589, 102594, 102599, + 102604, 102609, 102614, 102619, 102624, 102629, 102634, 102639, 102644, + 102649, 102654, 102659, 102664, 102669, 102674, 102679, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 102684, 102690, 102697, 102704, 102710, 102717, 102724, 102731, + 102738, 102744, 102751, 102758, 102765, 102772, 102779, 102786, 102793, + 102800, 102807, 102814, 102821, 102828, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 102835, 102840, 102845, 102850, 102855, 102860, 102865, 102870, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 102875, + 102881, 102889, 102898, 102903, 102909, 0, 102915, 102922, 102933, + 102943, 102950, 102958, 102965, 102976, 102982, 102992, 102999, 103006, + 103012, 103019, 103027, 103034, 103040, 103047, 103059, 103066, 103073, + 103081, 103090, 103103, 103108, 103117, 103123, 103132, 103138, 103144, + 103151, 103156, 103166, 103180, 103188, 103196, 103201, 103211, 103218, + 103229, 103236, 103245, 0, 103253, 103259, 103267, 103277, 103283, + 103289, 103295, 103301, 103311, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 101117, - 101122, 101127, 101132, 101137, 101142, 101147, 101152, 101157, 101162, - 101167, 101172, 101177, 101182, 101187, 101192, 101197, 101202, 101207, - 101212, 101217, 101222, 101227, 101232, 101237, 101242, 101247, 101252, - 101257, 101262, 101267, 101272, 101277, 101282, 101287, 101292, 101297, - 101302, 101307, 101312, 101317, 101322, 101327, 101332, 101337, 101342, - 101347, 101352, 101357, 101362, 101367, 101372, 101377, 101382, 101387, - 101392, 101397, 101402, 101407, 101412, 101417, 101422, 101427, 101432, - 101437, 101442, 101447, 101452, 101457, 101462, 101467, 101472, 101477, - 101482, 101487, 101492, 101497, 101502, 101507, 101512, 101517, 101522, - 101527, 101532, 101537, 101542, 101547, 101552, 101557, 101562, 101567, - 101572, 101577, 101582, 101587, 101592, 101597, 101602, 101607, 101612, - 101617, 101622, 101627, 101632, 101637, 101642, 101647, 101652, 101657, - 101662, 101667, 101672, 101677, 101682, 101687, 101692, 101697, 101702, - 101707, 101712, 101717, 101722, 101727, 101732, 101737, 101742, 101747, - 101752, 101757, 101762, 101767, 101772, 101777, 101782, 101787, 101792, - 101797, 101802, 101807, 101812, 101817, 101822, 101827, 101832, 101837, - 101842, 101847, 101852, 101857, 101862, 101867, 101872, 101877, 101882, - 101887, 101892, 101897, 101902, 101907, 101912, 101917, 101922, 101927, - 101932, 101937, 101942, 101947, 101952, 101957, 101962, 101967, 101972, - 101977, 101982, 101987, 101992, 101997, 102002, 102007, 102012, 102017, - 102022, 102027, 102032, 102037, 102042, 102047, 102052, 102057, 102062, - 102067, 102072, 102077, 102082, 102087, 102092, 102097, 102102, 102107, - 102112, 102117, 102122, 102127, 102132, 102137, 102142, 102147, 102152, - 102157, 102162, 102167, 102172, 102177, 102182, 102187, 102192, 102197, - 102202, 102207, 102212, 102217, 102222, 102227, 102232, 102237, 102242, - 102247, 102252, 102257, 102262, 102267, 102272, 102277, 102282, 102287, - 102292, 102297, 102302, 102307, 102312, 102317, 102322, 102327, 102332, - 102337, 102342, 102347, 102352, 102357, 102362, 102367, 102372, 102377, - 102382, 102387, 102392, 102397, 102402, 102407, 102412, 102417, 102422, - 102427, 102432, 102437, 102442, 102447, 102452, 102457, 102462, 102467, - 102472, 102477, 102482, 102487, 102492, 102497, 102502, 102507, 102512, - 102517, 102522, 102527, 102532, 102537, 102542, 102547, 102552, 102557, - 102562, 102567, 102572, 102577, 102582, 102587, 102592, 102597, 102602, - 102607, 102612, 102617, 102622, 102627, 102632, 102637, 102642, 102647, - 102652, 102657, 102662, 102667, 0, 0, 0, 0, 0, 0, 0, 0, 0, 102672, - 102678, 102685, 102692, 102698, 102705, 102712, 102719, 102726, 102732, - 102739, 102746, 102753, 102760, 102767, 102774, 102781, 102788, 102795, - 102802, 102809, 102816, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 102823, 102828, - 102833, 102838, 102843, 102848, 102853, 102858, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 102863, 102869, 102877, - 102886, 102891, 102897, 0, 102903, 102910, 102921, 102931, 102938, - 102946, 102953, 102964, 102970, 102980, 102987, 102994, 103000, 103007, - 103015, 103022, 103028, 103035, 103047, 103054, 103061, 103069, 103078, - 103091, 103096, 103105, 103111, 103120, 103126, 103132, 103139, 103144, - 103154, 103168, 103176, 103184, 103189, 103199, 103206, 103217, 103224, - 103233, 0, 103241, 103247, 103255, 103265, 103271, 103277, 103283, - 103289, 103299, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 103319, 103323, 103327, 103331, 103335, 103339, 0, + 0, 103344, 0, 103349, 103353, 103358, 103363, 103368, 103373, 103377, + 103382, 103387, 103392, 103397, 103401, 103406, 103411, 103416, 103421, + 103425, 103430, 103435, 103440, 103445, 103449, 103454, 103459, 103464, + 103469, 103473, 103478, 103483, 103488, 103493, 103497, 103502, 103507, + 103512, 103517, 103522, 103527, 103532, 103536, 103541, 103546, 103551, + 103556, 0, 103561, 103566, 0, 0, 0, 103571, 0, 0, 103576, 103581, 103588, + 103595, 103602, 103609, 103616, 103623, 103630, 103637, 103644, 103651, + 103658, 103665, 103672, 103679, 103686, 103693, 103700, 103707, 103714, + 103721, 103728, 0, 103735, 103742, 103748, 103754, 103760, 103767, + 103774, 103782, 103789, 103797, 103802, 103807, 103812, 103817, 103822, + 103827, 103832, 103837, 103842, 103847, 103852, 103857, 103862, 103868, + 103873, 103878, 103883, 103888, 103893, 103898, 103903, 103908, 103913, + 103919, 103925, 103929, 103933, 103937, 103941, 103945, 103950, 103955, + 103961, 103966, 103972, 103977, 103982, 103987, 103993, 103998, 104003, + 104008, 104013, 104018, 104024, 104029, 104035, 104040, 104046, 104051, + 104057, 104062, 104068, 104073, 104078, 104083, 104088, 104093, 104098, + 104103, 104109, 104114, 0, 0, 0, 0, 0, 0, 0, 0, 104119, 104123, 104127, + 104131, 104135, 104141, 104145, 104150, 104155, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 103307, 103311, 103315, 103319, 103323, 103327, 0, 0, 103332, 0, - 103337, 103341, 103346, 103351, 103356, 103361, 103365, 103370, 103375, - 103380, 103385, 103389, 103394, 103399, 103404, 103409, 103413, 103418, - 103423, 103428, 103433, 103437, 103442, 103447, 103452, 103457, 103461, - 103466, 103471, 103476, 103481, 103485, 103490, 103495, 103500, 103505, - 103510, 103515, 103520, 103524, 103529, 103534, 103539, 103544, 0, - 103549, 103554, 0, 0, 0, 103559, 0, 0, 103564, 103569, 103576, 103583, - 103590, 103597, 103604, 103611, 103618, 103625, 103632, 103639, 103646, - 103653, 103660, 103667, 103674, 103681, 103688, 103695, 103702, 103709, - 103716, 0, 103723, 103730, 103736, 103742, 103748, 103755, 103762, - 103770, 103777, 103785, 103790, 103795, 103800, 103805, 103810, 103815, - 103820, 103825, 103830, 103835, 103840, 103845, 103850, 103856, 103861, - 103866, 103871, 103876, 103881, 103886, 103891, 103896, 103901, 103907, - 103913, 103917, 103921, 103925, 103929, 103933, 103938, 103943, 103949, - 103954, 103960, 103965, 103970, 103975, 103981, 103986, 103991, 103996, - 104001, 104006, 104012, 104017, 104023, 104028, 104034, 104039, 104045, - 104050, 104056, 104061, 104066, 104071, 104076, 104081, 104086, 104091, - 104097, 104102, 0, 0, 0, 0, 0, 0, 0, 0, 104107, 104111, 104115, 104119, - 104123, 104129, 104133, 104138, 104143, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 104161, 104166, 104171, + 104176, 104181, 104186, 104191, 104196, 104201, 104206, 104211, 104216, + 104221, 104226, 104231, 104236, 104241, 104246, 104251, 0, 104256, + 104261, 0, 0, 0, 0, 0, 104266, 104270, 104274, 104279, 104284, 104290, + 104295, 104300, 104305, 104310, 104315, 104320, 104325, 104330, 104335, + 104340, 104345, 104350, 104355, 104360, 104365, 104370, 104375, 104380, + 104385, 104390, 104395, 104400, 104404, 104409, 104414, 104420, 104424, + 0, 0, 0, 104428, 104434, 104438, 104443, 104448, 104453, 104457, 104462, + 104466, 104471, 104476, 104480, 104485, 104490, 104494, 104498, 104503, + 104508, 104512, 104517, 104522, 104527, 104532, 104537, 104542, 104547, + 104552, 0, 0, 0, 0, 0, 104557, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 104149, 104154, 104159, 104164, - 104169, 104174, 104179, 104184, 104189, 104194, 104199, 104204, 104209, - 104214, 104219, 104224, 104229, 104234, 104239, 0, 104244, 104249, 0, 0, - 0, 0, 0, 104254, 104258, 104262, 104267, 104272, 104278, 104283, 104288, - 104293, 104298, 104303, 104308, 104313, 104318, 104323, 104328, 104333, - 104338, 104343, 104348, 104353, 104358, 104363, 104368, 104373, 104378, - 104383, 104388, 104392, 104397, 104402, 104408, 104412, 0, 0, 0, 104416, - 104422, 104426, 104431, 104436, 104441, 104445, 104450, 104454, 104459, - 104464, 104468, 104473, 104478, 104482, 104486, 104491, 104496, 104500, - 104505, 104510, 104515, 104520, 104525, 104530, 104535, 104540, 0, 0, 0, - 0, 0, 104545, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 104550, - 104555, 104560, 104565, 104570, 104575, 104581, 104587, 104593, 104598, - 104603, 104608, 104614, 104620, 104626, 104631, 104637, 104642, 104648, - 104654, 104659, 104665, 104671, 104676, 104682, 104688, 104694, 104700, - 104706, 104711, 104717, 104723, 104729, 104734, 104739, 104744, 104749, - 104754, 104760, 104766, 104771, 104776, 104781, 104787, 104792, 104797, - 104803, 104809, 104814, 104821, 104827, 104832, 104838, 104844, 104850, - 104855, 0, 0, 0, 0, 104861, 104870, 104878, 104885, 104892, 104897, - 104902, 104907, 104912, 104917, 104922, 104927, 104932, 104937, 104943, - 104949, 104955, 104961, 104967, 104973, 0, 0, 104979, 104986, 104993, - 105000, 105008, 105016, 105024, 105032, 105040, 105048, 105054, 105060, - 105066, 105073, 105080, 105087, 105094, 105101, 105108, 105115, 105122, - 105129, 105136, 105143, 105150, 105157, 105164, 105171, 105179, 105187, - 105195, 105204, 105213, 105222, 105231, 105240, 105249, 105257, 105265, - 105273, 105282, 105291, 105300, 105309, 105318, 105327, 105336, 105340, - 105345, 105350, 0, 105356, 105361, 0, 0, 0, 0, 0, 105366, 105372, 105379, - 105384, 105389, 105393, 105398, 105403, 0, 105408, 105413, 105418, 0, - 105423, 105428, 105433, 105438, 105443, 105448, 105453, 105458, 105463, - 105468, 105473, 105477, 105481, 105486, 105491, 105496, 105500, 105504, - 105508, 105512, 105517, 105522, 105527, 105531, 105536, 105540, 105545, - 105550, 105555, 0, 0, 105560, 105566, 105571, 0, 0, 0, 0, 105576, 105580, - 105584, 105588, 105592, 105596, 105601, 105606, 105612, 105617, 0, 0, 0, - 0, 0, 0, 0, 105624, 105630, 105637, 105643, 105650, 105656, 105662, - 105668, 105675, 0, 0, 0, 0, 0, 0, 0, 105681, 105689, 105697, 105705, - 105713, 105721, 105729, 105737, 105745, 105753, 105761, 105769, 105777, - 105785, 105793, 105801, 105809, 105817, 105825, 105833, 105841, 105849, - 105857, 105865, 105873, 105881, 105889, 105897, 105905, 105913, 105920, - 105928, 105936, 105943, 105950, 105957, 105964, 105971, 105978, 105985, - 105992, 105999, 106006, 106013, 106020, 106027, 106034, 106041, 106048, - 106055, 106062, 106069, 106076, 106083, 106090, 106097, 106104, 106111, - 106118, 106125, 106132, 106139, 106145, 106152, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 104562, 104567, 104572, 104577, 104582, 104587, 104593, 104599, + 104605, 104610, 104615, 104620, 104626, 104632, 104638, 104643, 104649, + 104654, 104660, 104666, 104671, 104677, 104683, 104688, 104694, 104700, + 104706, 104712, 104718, 104723, 104729, 104735, 104741, 104746, 104751, + 104756, 104761, 104766, 104772, 104778, 104783, 104788, 104793, 104799, + 104804, 104809, 104815, 104821, 104826, 104833, 104839, 104844, 104850, + 104856, 104862, 104867, 0, 0, 0, 0, 104873, 104882, 104890, 104897, + 104904, 104909, 104914, 104919, 104924, 104929, 104934, 104939, 104944, + 104949, 104955, 104961, 104967, 104973, 104979, 104985, 0, 0, 104991, + 104998, 105005, 105012, 105020, 105028, 105036, 105044, 105052, 105060, + 105066, 105072, 105078, 105085, 105092, 105099, 105106, 105113, 105120, + 105127, 105134, 105141, 105148, 105155, 105162, 105169, 105176, 105183, + 105191, 105199, 105207, 105216, 105225, 105234, 105243, 105252, 105261, + 105269, 105277, 105285, 105294, 105303, 105312, 105321, 105330, 105339, + 105348, 105352, 105357, 105362, 0, 105368, 105373, 0, 0, 0, 0, 0, 105378, + 105384, 105391, 105396, 105401, 105405, 105410, 105415, 0, 105420, + 105425, 105430, 0, 105435, 105440, 105445, 105450, 105455, 105460, + 105465, 105470, 105475, 105480, 105485, 105489, 105493, 105498, 105503, + 105508, 105512, 105516, 105520, 105524, 105529, 105534, 105539, 105543, + 105548, 105552, 105557, 105562, 105567, 0, 0, 105572, 105578, 105583, 0, + 0, 0, 0, 105588, 105592, 105596, 105600, 105604, 105608, 105613, 105618, + 105624, 105629, 0, 0, 0, 0, 0, 0, 0, 105636, 105642, 105649, 105655, + 105662, 105668, 105674, 105680, 105687, 0, 0, 0, 0, 0, 0, 0, 105693, + 105701, 105709, 105717, 105725, 105733, 105741, 105749, 105757, 105765, + 105773, 105781, 105789, 105797, 105805, 105813, 105821, 105829, 105837, + 105845, 105853, 105861, 105869, 105877, 105885, 105893, 105901, 105909, + 105917, 105925, 105932, 105940, 105948, 105955, 105962, 105969, 105976, + 105983, 105990, 105997, 106004, 106011, 106018, 106025, 106032, 106039, + 106046, 106053, 106060, 106067, 106074, 106081, 106088, 106095, 106102, + 106109, 106116, 106123, 106130, 106137, 106144, 106151, 106157, 106164, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 106159, 106164, 106169, 106174, 106179, 106184, 106189, 106194, 106199, - 106204, 106209, 106214, 106219, 106224, 106229, 106234, 106239, 106244, - 106249, 106254, 106259, 106264, 106269, 106274, 106279, 106284, 106289, - 106294, 106299, 106304, 106309, 106314, 106319, 106324, 106329, 106334, - 106339, 106344, 106350, 0, 0, 0, 0, 106356, 106360, 106364, 106369, - 106374, 106380, 106386, 106392, 106402, 106411, 106417, 106424, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 106432, 106436, 106441, 106446, 106451, 106456, 106461, - 106466, 106471, 106475, 106480, 106484, 106489, 106493, 106498, 106502, - 106507, 106512, 106517, 106522, 106527, 106532, 106537, 106542, 106547, - 106552, 106557, 106562, 106567, 106572, 106577, 106582, 106587, 106592, - 106597, 106602, 106607, 106612, 106617, 106622, 106627, 106632, 106637, - 106642, 106647, 106652, 106657, 106662, 106667, 106672, 106677, 106682, - 106687, 106692, 0, 0, 0, 106697, 106702, 106711, 106719, 106728, 106737, - 106748, 106759, 106766, 106773, 106780, 106787, 106794, 106801, 106808, - 106815, 106822, 106829, 106836, 106843, 106850, 106857, 106864, 106871, - 106878, 106885, 106892, 106899, 106906, 0, 0, 106913, 106919, 106925, - 106931, 106937, 106944, 106951, 106959, 106966, 106973, 106980, 106987, - 106994, 107001, 107008, 107015, 107022, 107029, 107036, 107043, 107050, - 107057, 107064, 107071, 107078, 107085, 107092, 0, 0, 0, 0, 0, 107099, - 107105, 107111, 107117, 107123, 107130, 107137, 107145, 107152, 107159, - 107166, 107173, 107180, 107187, 107194, 107201, 107208, 107215, 107222, - 107229, 107236, 107243, 107250, 107257, 107264, 107271, 0, 0, 0, 0, 0, 0, - 0, 107278, 107285, 107293, 107303, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 107313, 107319, 107325, 107331, 107337, 107344, 107351, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 106171, 106176, 106181, 106186, 106191, 106196, + 106201, 106206, 106211, 106216, 106221, 106226, 106231, 106236, 106241, + 106246, 106251, 106256, 106261, 106266, 106271, 106276, 106281, 106286, + 106291, 106296, 106301, 106306, 106311, 106316, 106321, 106326, 106331, + 106336, 106341, 106346, 106351, 106356, 106362, 0, 0, 0, 0, 106368, + 106372, 106376, 106381, 106386, 106392, 106398, 106404, 106414, 106423, + 106429, 106436, 0, 0, 0, 0, 0, 0, 0, 0, 0, 106444, 106448, 106453, + 106458, 106463, 106468, 106473, 106478, 106483, 106487, 106492, 106496, + 106501, 106505, 106510, 106514, 106519, 106524, 106529, 106534, 106539, + 106544, 106549, 106554, 106559, 106564, 106569, 106574, 106579, 106584, + 106589, 106594, 106599, 106604, 106609, 106614, 106619, 106624, 106629, + 106634, 106639, 106644, 106649, 106654, 106659, 106664, 106669, 106674, + 106679, 106684, 106689, 106694, 106699, 106704, 0, 0, 0, 106709, 106714, + 106723, 106731, 106740, 106749, 106760, 106771, 106778, 106785, 106792, + 106799, 106806, 106813, 106820, 106827, 106834, 106841, 106848, 106855, + 106862, 106869, 106876, 106883, 106890, 106897, 106904, 106911, 106918, + 0, 0, 106925, 106931, 106937, 106943, 106949, 106956, 106963, 106971, + 106978, 106985, 106992, 106999, 107006, 107013, 107020, 107027, 107034, + 107041, 107048, 107055, 107062, 107069, 107076, 107083, 107090, 107097, + 107104, 0, 0, 0, 0, 0, 107111, 107117, 107123, 107129, 107135, 107142, + 107149, 107157, 107164, 107171, 107178, 107185, 107192, 107199, 107206, + 107213, 107220, 107227, 107234, 107241, 107248, 107255, 107262, 107269, + 107276, 107283, 0, 0, 0, 0, 0, 0, 0, 107290, 107297, 107305, 107315, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107325, 107331, 107337, 107343, 107349, + 107356, 107363, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107371, 107378, 107385, 107393, + 107400, 107407, 107414, 107421, 107429, 107437, 107445, 107453, 107461, + 107469, 107477, 107485, 107493, 107501, 107509, 107517, 107525, 107533, + 107541, 107549, 107557, 107565, 107573, 107581, 107589, 107597, 107605, + 107613, 107621, 107629, 107637, 107645, 107653, 107661, 107669, 107677, + 107685, 107693, 107701, 107709, 107717, 107725, 107733, 107741, 107749, + 107757, 107765, 107773, 107781, 107789, 107797, 107805, 107813, 107821, + 107829, 107837, 107845, 107853, 107861, 107869, 107877, 107885, 107893, + 107901, 107909, 107917, 107925, 107933, 107941, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 107359, 107366, 107373, 107381, 107388, 107395, 107402, 107409, - 107417, 107425, 107433, 107441, 107449, 107457, 107465, 107473, 107481, - 107489, 107497, 107505, 107513, 107521, 107529, 107537, 107545, 107553, - 107561, 107569, 107577, 107585, 107593, 107601, 107609, 107617, 107625, - 107633, 107641, 107649, 107657, 107665, 107673, 107681, 107689, 107697, - 107705, 107713, 107721, 107729, 107737, 107745, 107753, 107761, 107769, - 107777, 107785, 107793, 107801, 107809, 107817, 107825, 107833, 107841, - 107849, 107857, 107865, 107873, 107881, 107889, 107897, 107905, 107913, - 107921, 107929, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 107949, 107954, 107960, 107966, 107972, 107978, 107984, 107990, 107996, + 108002, 108007, 108014, 108020, 108026, 108032, 108038, 108044, 108049, + 108055, 108061, 108067, 108073, 108079, 108085, 108091, 108097, 108103, + 108109, 108114, 108120, 108128, 108136, 108142, 108148, 108154, 108160, + 108168, 108174, 108180, 108186, 108192, 108198, 108204, 108209, 108215, + 108223, 108231, 108237, 108243, 108249, 108256, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 108262, 108267, 108273, 108279, 108285, 108291, 108297, + 108303, 108309, 108315, 108320, 108327, 108333, 108339, 108345, 108351, + 108357, 108362, 108368, 108374, 108380, 108386, 108392, 108398, 108404, + 108410, 108416, 108422, 108427, 108433, 108441, 108449, 108455, 108461, + 108467, 108473, 108481, 108487, 108493, 108499, 108505, 108511, 108517, + 108522, 108528, 108536, 108544, 108550, 108556, 108562, 108569, 0, 0, 0, + 0, 0, 0, 0, 108575, 108579, 108583, 108588, 108593, 108599, 108604, + 108610, 108617, 108623, 108630, 108637, 108644, 108651, 108657, 108664, + 108671, 108678, 108685, 108691, 108698, 108705, 108711, 108718, 108724, + 108731, 108737, 108743, 108749, 108756, 108765, 108771, 108779, 108786, + 108793, 108800, 108806, 108812, 108818, 108824, 108830, 108837, 108846, + 108853, 108860, 108867, 0, 0, 0, 0, 0, 0, 0, 0, 108874, 108881, 108887, + 108893, 108899, 108905, 108911, 108917, 108923, 108929, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107937, 107942, 107948, 107954, - 107960, 107966, 107972, 107978, 107984, 107990, 107995, 108002, 108008, - 108014, 108020, 108026, 108032, 108037, 108043, 108049, 108055, 108061, - 108067, 108073, 108079, 108085, 108091, 108097, 108102, 108108, 108116, - 108124, 108130, 108136, 108142, 108148, 108156, 108162, 108168, 108174, - 108180, 108186, 108192, 108197, 108203, 108211, 108219, 108225, 108231, - 108237, 108244, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108250, 108255, - 108261, 108267, 108273, 108279, 108285, 108291, 108297, 108303, 108308, - 108315, 108321, 108327, 108333, 108339, 108345, 108350, 108356, 108362, - 108368, 108374, 108380, 108386, 108392, 108398, 108404, 108410, 108415, - 108421, 108429, 108437, 108443, 108449, 108455, 108461, 108469, 108475, - 108481, 108487, 108493, 108499, 108505, 108510, 108516, 108524, 108532, - 108538, 108544, 108550, 108557, 0, 0, 0, 0, 0, 0, 0, 108563, 108567, - 108571, 108576, 108581, 108587, 108592, 108598, 108605, 108611, 108618, - 108625, 108632, 108639, 108645, 108652, 108659, 108666, 108673, 108679, - 108686, 108693, 108699, 108706, 108712, 108719, 108725, 108731, 108737, - 108744, 108753, 108759, 108767, 108774, 108781, 108788, 108794, 108800, - 108806, 108812, 108818, 108825, 108834, 108841, 108848, 108855, 0, 0, 0, - 0, 0, 0, 0, 0, 108862, 108869, 108875, 108881, 108887, 108893, 108899, - 108905, 108911, 108917, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 108935, 108939, 108943, + 108947, 108951, 108955, 108959, 108963, 108967, 108971, 108976, 108981, + 108986, 108991, 108996, 109001, 109006, 109011, 109016, 109022, 109028, + 109034, 109041, 109048, 109055, 109062, 109069, 109076, 109083, 109090, + 109097, 0, 109104, 109109, 109114, 109119, 109124, 109129, 109134, + 109139, 109144, 109149, 109154, 109159, 109164, 109169, 109173, 109178, + 109183, 109188, 109193, 109198, 109203, 109208, 109213, 109218, 109223, + 109228, 109233, 109238, 109246, 109251, 109256, 109261, 109266, 109271, + 109276, 109281, 109286, 109291, 109296, 109301, 109306, 109311, 0, + 109316, 109322, 109328, 0, 0, 109333, 109341, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 108923, 108927, 108931, 108935, 108939, 108943, 108947, - 108951, 108955, 108959, 108964, 108969, 108974, 108979, 108984, 108989, - 108994, 108999, 109004, 109010, 109016, 109022, 109029, 109036, 109043, - 109050, 109057, 109064, 109071, 109078, 109085, 0, 109092, 109097, - 109102, 109107, 109112, 109117, 109122, 109127, 109132, 109137, 109142, - 109147, 109152, 109157, 109161, 109166, 109171, 109176, 109181, 109186, - 109191, 109196, 109201, 109206, 109211, 109216, 109221, 109226, 109234, - 109239, 109244, 109249, 109254, 109259, 109264, 109269, 109274, 109279, - 109284, 109289, 109294, 109299, 0, 109304, 109310, 109316, 0, 0, 109321, - 109329, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109350, 109357, + 109364, 109371, 109377, 109384, 109390, 109397, 109403, 109409, 109416, + 109422, 109428, 109434, 109440, 109446, 109452, 109458, 109464, 109471, + 109482, 109488, 109494, 109502, 109508, 109514, 109521, 109532, 109538, + 109544, 109550, 109557, 109568, 109573, 109578, 109583, 109588, 109593, + 109599, 109605, 109611, 109618, 109626, 0, 0, 0, 0, 0, 0, 0, 0, 109632, + 109637, 109642, 109647, 109652, 109657, 109662, 109667, 109672, 109677, + 109682, 109687, 109692, 109697, 109702, 109707, 109712, 109717, 109722, + 109727, 109732, 109737, 109743, 109748, 109754, 109759, 109765, 109771, + 109777, 109783, 109789, 109796, 109802, 109808, 109812, 109817, 109822, + 109828, 109836, 109847, 109856, 109866, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109876, 109882, 109888, 109894, 109900, + 109906, 109913, 109919, 109925, 109931, 109937, 109943, 109949, 109955, + 109961, 109967, 109973, 109979, 109985, 109991, 109997, 110004, 110011, + 110017, 110025, 110033, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 110042, + 110047, 110053, 110058, 110063, 110068, 110073, 110078, 110085, 110090, + 110095, 110100, 110105, 110110, 110115, 110120, 110125, 110130, 110135, + 110140, 110145, 110150, 110154, 110158, 110162, 110166, 110171, 110176, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 110182, + 110187, 110192, 110197, 110202, 110207, 110212, 110217, 110222, 110227, + 110232, 110237, 110242, 110247, 110252, 110257, 110262, 110267, 110272, + 110277, 110282, 110287, 110292, 0, 0, 0, 0, 0, 0, 0, 0, 0, 110297, + 110301, 110305, 110309, 110313, 110317, 110320, 110324, 110327, 110331, + 110334, 110338, 110342, 110347, 110351, 110356, 110359, 110363, 110366, + 110370, 110373, 110377, 110381, 110385, 110389, 110393, 110397, 110401, + 110405, 110409, 110413, 110417, 110421, 110425, 110429, 110433, 110437, + 110441, 110445, 110448, 110451, 110455, 110459, 110463, 110466, 110469, + 110472, 110475, 110479, 110483, 110487, 110490, 110493, 110497, 110503, + 110509, 110515, 110520, 110527, 110531, 110536, 110540, 110545, 110550, + 110556, 110561, 110567, 110571, 110576, 110580, 110585, 110588, 110591, + 110595, 110600, 110606, 110611, 110617, 0, 0, 0, 0, 110622, 110625, + 110628, 110631, 110634, 110637, 110640, 110643, 110646, 110649, 110653, + 110657, 110661, 110665, 110669, 110673, 110677, 110681, 110685, 110690, + 110694, 110698, 110701, 110704, 110707, 110710, 110713, 110716, 110719, + 110722, 110725, 110731, 110738, 110745, 110753, 110761, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 110767, 110771, 110776, 110781, 110786, 110790, 110795, 110799, + 110804, 110808, 110813, 110817, 110822, 110826, 110831, 110835, 110840, + 110845, 110850, 110855, 110860, 110865, 110870, 110875, 110880, 110885, + 110890, 110895, 110900, 110905, 110910, 110915, 110920, 110925, 110930, + 110935, 110939, 110943, 110948, 110953, 110958, 110962, 110966, 110970, + 110974, 110979, 110984, 110989, 110993, 110997, 111003, 111008, 111014, + 111019, 111025, 111030, 111036, 111041, 111047, 111052, 111057, 111062, + 111067, 111071, 111076, 111082, 111086, 111091, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 111097, 0, 0, 111102, 111109, 111116, 111123, 111130, 111137, + 111144, 111151, 111158, 111165, 111172, 111179, 111186, 111193, 111200, + 111207, 111214, 111221, 111228, 111235, 111242, 111249, 111256, 111263, + 111270, 0, 0, 0, 0, 0, 0, 0, 111277, 111284, 111290, 111296, 111302, + 111308, 111314, 111320, 111326, 111332, 0, 0, 0, 0, 0, 0, 111338, 111343, + 111348, 111353, 111358, 111362, 111366, 111370, 111375, 111380, 111385, + 111390, 111395, 111400, 111405, 111410, 111415, 111420, 111425, 111430, + 111435, 111440, 111445, 111450, 111455, 111460, 111465, 111470, 111475, + 111480, 111485, 111490, 111495, 111500, 111505, 111510, 111515, 111520, + 111525, 111530, 111535, 111540, 111546, 111551, 111557, 111562, 111568, + 111573, 111579, 111585, 111589, 111594, 111598, 0, 111602, 111607, + 111611, 111615, 111619, 111623, 111627, 111631, 111635, 111639, 111643, + 111648, 111652, 111657, 111662, 111667, 111673, 111679, 0, 0, 0, 0, 0, 0, + 0, 0, 111684, 111688, 111692, 111696, 111700, 111704, 111708, 111713, + 111718, 111723, 111728, 111733, 111738, 111743, 111748, 111753, 111758, + 111763, 111768, 111773, 111778, 111783, 111788, 111793, 111797, 111801, + 111806, 111811, 111816, 111820, 111824, 111828, 111833, 111837, 111841, + 111846, 111851, 111856, 111861, 0, 0, 0, 0, 0, 0, 0, 0, 0, 111866, + 111871, 111876, 111881, 111885, 111890, 111894, 111899, 111903, 111908, + 111913, 111919, 111924, 111930, 111934, 111939, 111943, 111948, 111952, + 111957, 111962, 111967, 111972, 111977, 111982, 111987, 111992, 111997, + 112002, 112007, 112012, 112017, 112022, 112027, 112032, 112037, 112042, + 112046, 112050, 112055, 112060, 112065, 112069, 112073, 112077, 112081, + 112086, 112091, 112096, 112101, 112105, 112109, 112115, 112120, 112126, + 112131, 112137, 112143, 112150, 112156, 112163, 112168, 112174, 112179, + 112185, 112190, 112195, 112200, 112205, 112209, 112213, 112218, 112223, + 112227, 112232, 112237, 112242, 112250, 112255, 112262, 112269, 112274, + 112278, 112282, 112286, 112290, 112294, 112298, 112302, 112306, 112310, + 112314, 112319, 112323, 112328, 112334, 0, 112340, 112345, 112350, + 112355, 112360, 112365, 112370, 112375, 112380, 112385, 112391, 112397, + 112403, 112409, 112415, 112421, 112427, 112433, 112439, 112446, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 112452, 112456, 112461, 112465, 112469, 112473, + 112478, 112482, 112487, 112491, 112496, 112501, 112506, 112511, 112516, + 112521, 112526, 112531, 0, 112536, 112541, 112546, 112551, 112556, + 112561, 112566, 112571, 112576, 112581, 112586, 112591, 112595, 112599, + 112604, 112609, 112614, 112619, 112623, 112627, 112631, 112635, 112640, + 112644, 112648, 112653, 112659, 112664, 112670, 112675, 112680, 112686, + 112691, 112697, 112702, 112707, 112712, 112717, 112721, 112726, 112732, + 112737, 112743, 112748, 112753, 112758, 112764, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 109338, 109344, 109351, 109357, 109364, 109370, - 109376, 109383, 109389, 109395, 109401, 109407, 109413, 109419, 109425, - 109431, 109438, 109449, 109455, 109461, 109469, 109475, 109481, 109488, - 109499, 109505, 109511, 109517, 109524, 109535, 109540, 109545, 109550, - 109555, 109560, 109566, 109572, 109578, 109585, 109593, 0, 0, 0, 0, 0, 0, - 0, 0, 109599, 109604, 109609, 109614, 109619, 109624, 109629, 109634, - 109639, 109644, 109649, 109654, 109659, 109664, 109669, 109674, 109679, - 109684, 109689, 109694, 109699, 109704, 109710, 109715, 109721, 109726, - 109732, 109738, 109744, 109750, 109756, 109763, 109769, 109775, 109779, - 109784, 109789, 109795, 109803, 109814, 109823, 109833, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109843, 109849, 109855, - 109861, 109867, 109873, 109880, 109886, 109892, 109898, 109904, 109910, - 109916, 109922, 109928, 109934, 109940, 109946, 109952, 109958, 109964, - 109971, 109978, 109984, 109992, 110000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 110009, 110014, 110020, 110025, 110030, 110035, 110040, 110045, - 110052, 110057, 110062, 110067, 110072, 110077, 110082, 110087, 110092, - 110097, 110102, 110107, 110112, 110117, 110121, 110125, 110129, 110133, - 110138, 110143, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 110149, 110154, 110159, 110164, 110169, 110174, 110179, 110184, - 110189, 110194, 110199, 110204, 110209, 110214, 110219, 110224, 110229, - 110234, 110239, 110244, 110249, 110254, 110259, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 110264, 110268, 110272, 110276, 110280, 110284, 110287, 110291, - 110294, 110298, 110301, 110305, 110309, 110314, 110318, 110323, 110326, - 110330, 110333, 110337, 110340, 110344, 110348, 110352, 110356, 110360, - 110364, 110368, 110372, 110376, 110380, 110384, 110388, 110392, 110396, - 110400, 110404, 110408, 110412, 110415, 110418, 110422, 110426, 110430, - 110433, 110436, 110439, 110442, 110446, 110450, 110454, 110457, 110460, - 110464, 110470, 110476, 110482, 110487, 110494, 110498, 110503, 110507, - 110512, 110517, 110523, 110528, 110534, 110538, 110543, 110547, 110552, - 110555, 110558, 110562, 110567, 110573, 110578, 110584, 0, 0, 0, 0, - 110589, 110592, 110595, 110598, 110601, 110604, 110607, 110610, 110613, - 110616, 110620, 110624, 110628, 110632, 110636, 110640, 110644, 110648, - 110652, 110657, 110661, 110665, 110668, 110671, 110674, 110677, 110680, - 110683, 110686, 110689, 110692, 110698, 110705, 110712, 110720, 110728, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 110734, 110738, 110743, 110748, 110753, - 110757, 110762, 110766, 110771, 110775, 110780, 110784, 110789, 110793, - 110798, 110802, 110807, 110812, 110817, 110822, 110827, 110832, 110837, - 110842, 110847, 110852, 110857, 110862, 110867, 110872, 110877, 110882, - 110887, 110892, 110897, 110902, 110906, 110910, 110915, 110920, 110925, - 110929, 110933, 110937, 110941, 110946, 110951, 110956, 110960, 110964, - 110970, 110975, 110981, 110986, 110992, 110997, 111003, 111008, 111014, - 111019, 111024, 111029, 111034, 111038, 111043, 111049, 111053, 111058, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 111064, 0, 0, 111069, 111076, 111083, - 111090, 111097, 111104, 111111, 111118, 111125, 111132, 111139, 111146, - 111153, 111160, 111167, 111174, 111181, 111188, 111195, 111202, 111209, - 111216, 111223, 111230, 111237, 0, 0, 0, 0, 0, 0, 0, 111244, 111251, - 111257, 111263, 111269, 111275, 111281, 111287, 111293, 111299, 0, 0, 0, - 0, 0, 0, 111305, 111310, 111315, 111320, 111325, 111329, 111333, 111337, - 111342, 111347, 111352, 111357, 111362, 111367, 111372, 111377, 111382, - 111387, 111392, 111397, 111402, 111407, 111412, 111417, 111422, 111427, - 111432, 111437, 111442, 111447, 111452, 111457, 111462, 111467, 111472, - 111477, 111482, 111487, 111492, 111497, 111502, 111507, 111513, 111518, - 111524, 111529, 111535, 111540, 111546, 111552, 111556, 111561, 111565, - 0, 111569, 111574, 111578, 111582, 111586, 111590, 111594, 111598, - 111602, 111606, 111610, 111615, 111619, 111624, 111629, 111634, 111640, - 111646, 0, 0, 0, 0, 0, 0, 0, 0, 111651, 111655, 111659, 111663, 111667, - 111671, 111675, 111680, 111685, 111690, 111695, 111700, 111705, 111710, - 111715, 111720, 111725, 111730, 111735, 111740, 111745, 111750, 111755, - 111760, 111764, 111768, 111773, 111778, 111783, 111787, 111791, 111795, - 111800, 111804, 111808, 111813, 111818, 111823, 111828, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 111833, 111838, 111843, 111848, 111852, 111857, 111861, 111866, - 111870, 111875, 111880, 111886, 111891, 111897, 111901, 111906, 111910, - 111915, 111919, 111924, 111929, 111934, 111939, 111944, 111949, 111954, - 111959, 111964, 111969, 111974, 111979, 111984, 111989, 111994, 111999, - 112004, 112009, 112013, 112017, 112022, 112027, 112032, 112036, 112040, - 112044, 112048, 112053, 112058, 112063, 112068, 112072, 112076, 112082, - 112087, 112093, 112098, 112104, 112110, 112117, 112123, 112130, 112135, - 112141, 112146, 112152, 112157, 112162, 112167, 112172, 112176, 112180, - 112185, 112190, 112194, 112199, 112204, 112209, 112217, 112222, 112229, - 112236, 112241, 112245, 112249, 112253, 112257, 112261, 112265, 112269, - 112273, 112277, 112281, 112286, 112290, 112295, 112301, 0, 112307, - 112312, 112317, 112322, 112327, 112332, 112337, 112342, 112347, 112352, - 112358, 112364, 112370, 112376, 112382, 112388, 112394, 112400, 112406, - 112413, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 112419, 112423, 112428, 112432, - 112436, 112440, 112445, 112449, 112454, 112458, 112463, 112468, 112473, - 112478, 112483, 112488, 112493, 112498, 0, 112503, 112508, 112513, - 112518, 112523, 112528, 112533, 112538, 112543, 112548, 112553, 112558, - 112562, 112566, 112571, 112576, 112581, 112586, 112590, 112594, 112598, - 112602, 112607, 112611, 112615, 112620, 112626, 112631, 112637, 112642, - 112647, 112653, 112658, 112664, 112669, 112674, 112679, 112684, 112688, - 112693, 112699, 112704, 112710, 112715, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 112770, 112774, 112778, 112782, 112786, 112790, 112795, + 0, 112800, 0, 112805, 112810, 112815, 112820, 0, 112825, 112830, 112835, + 112840, 112845, 112850, 112855, 112860, 112865, 112870, 112875, 112880, + 112884, 112888, 112893, 0, 112898, 112903, 112907, 112911, 112915, + 112919, 112924, 112928, 112932, 112937, 112942, 0, 0, 0, 0, 0, 0, 112947, + 112951, 112956, 112960, 112965, 112969, 112974, 112978, 112983, 112987, + 112992, 112996, 113001, 113006, 113011, 113016, 113021, 113026, 113031, + 113036, 113041, 113046, 113051, 113056, 113061, 113066, 113071, 113076, + 113081, 113086, 113091, 113096, 113101, 113106, 113110, 113114, 113119, + 113124, 113129, 113134, 113138, 113142, 113146, 113150, 113155, 113160, + 113164, 113168, 113173, 113179, 113184, 113190, 113195, 113201, 113206, + 113212, 113217, 113223, 113228, 0, 0, 0, 0, 0, 113233, 113238, 113242, + 113246, 113250, 113254, 113258, 113262, 113266, 113270, 0, 0, 0, 0, 0, 0, + 113274, 113281, 113286, 113291, 0, 113296, 113300, 113305, 113309, + 113314, 113318, 113323, 113328, 0, 0, 113333, 113338, 0, 0, 113343, + 113348, 113353, 113357, 113362, 113367, 113372, 113377, 113382, 113387, + 113392, 113397, 113402, 113407, 113412, 113417, 113422, 113427, 113432, + 113437, 113442, 113447, 0, 113451, 113455, 113460, 113465, 113470, + 113474, 113478, 0, 113482, 113486, 0, 113491, 113496, 113501, 113506, + 113510, 0, 113514, 113518, 113523, 113528, 113534, 113539, 113545, + 113550, 113556, 113562, 0, 0, 113569, 113575, 0, 0, 113581, 113587, + 113593, 0, 0, 113598, 0, 0, 0, 0, 0, 0, 113602, 0, 0, 0, 0, 0, 113609, + 113614, 113621, 113629, 113635, 113641, 113647, 0, 0, 113654, 113660, + 113665, 113670, 113675, 113680, 113685, 0, 0, 0, 113690, 113695, 113700, + 113705, 113711, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 113716, 113720, 113725, + 113729, 113734, 113738, 113743, 113748, 113754, 113759, 113765, 113769, + 113774, 113778, 113783, 113787, 113792, 113797, 113802, 113807, 113812, + 113817, 113822, 113827, 113832, 113837, 113842, 113847, 113852, 113857, + 113862, 113867, 113872, 113877, 113882, 113887, 113891, 113896, 113900, + 113905, 113910, 113915, 113919, 113924, 113928, 113932, 113937, 113941, + 113946, 113951, 113956, 113961, 113965, 113969, 113975, 113980, 113986, + 113991, 113997, 114003, 114010, 114016, 114023, 114028, 114034, 114039, + 114045, 114050, 114055, 114060, 114065, 114070, 114075, 114081, 114085, + 114089, 114093, 114098, 114102, 114108, 114113, 114118, 114122, 114126, + 114130, 114134, 114138, 114142, 114146, 114150, 114154, 114159, 0, + 114164, 114169, 114174, 114181, 114186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 114191, 114195, + 114199, 114204, 114208, 114213, 114217, 114222, 114227, 114233, 114238, + 114244, 114248, 114253, 114257, 114262, 114266, 114271, 114276, 114281, + 114286, 114291, 114296, 114301, 114306, 114311, 114316, 114321, 114326, + 114331, 114336, 114341, 114346, 114351, 114356, 114360, 114364, 114369, + 114374, 114379, 114383, 114387, 114391, 114395, 114400, 114405, 114410, + 114414, 114418, 114424, 114429, 114435, 114440, 114446, 114452, 114459, + 114465, 114472, 114477, 114484, 114490, 114495, 114502, 114508, 114513, + 114518, 114523, 114528, 114533, 114538, 114542, 114547, 0, 0, 0, 0, 0, 0, + 0, 0, 114551, 114556, 114560, 114564, 114568, 114572, 114576, 114580, + 114584, 114588, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 114592, 114596, + 114601, 114605, 114610, 114614, 114619, 114624, 114630, 114635, 114641, + 114645, 114650, 114654, 114659, 114663, 114668, 114673, 114678, 114683, + 114688, 114693, 114698, 114703, 114708, 114713, 114718, 114723, 114728, + 114733, 114738, 114743, 114748, 114753, 114757, 114761, 114766, 114771, + 114776, 114780, 114784, 114788, 114792, 114797, 114802, 114807, 114811, + 114815, 114821, 114826, 114832, 114837, 114843, 114849, 0, 0, 114856, + 114861, 114867, 114872, 114878, 114883, 114888, 114893, 114898, 114903, + 114908, 114912, 114917, 114923, 114928, 114934, 114940, 114946, 114954, + 114967, 114980, 114993, 115007, 115022, 115030, 115041, 115050, 115060, + 115070, 115080, 115091, 115103, 115116, 115124, 115132, 115141, 115147, + 115154, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115162, 115166, 115171, 115175, + 115180, 115184, 115189, 115194, 115200, 115205, 115211, 115215, 115220, + 115224, 115229, 115233, 115238, 115243, 115248, 115253, 115258, 115263, + 115268, 115273, 115278, 115283, 115288, 115293, 115298, 115303, 115308, + 115313, 115318, 115323, 115327, 115331, 115336, 115341, 115346, 115350, + 115354, 115358, 115362, 115367, 115372, 115377, 115381, 115385, 115390, + 115396, 115401, 115407, 115412, 115418, 115424, 115431, 115437, 115444, + 115449, 115455, 115460, 115466, 115471, 115476, 115481, 115486, 115490, + 115495, 115500, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115505, 115510, 115514, + 115518, 115522, 115526, 115530, 115534, 115538, 115542, 0, 0, 0, 0, 0, 0, + 115546, 115552, 115557, 115564, 115572, 115579, 115587, 115596, 115601, + 115610, 115615, 115623, 115632, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 115642, 115646, 115651, 115655, 115660, 115664, 115669, + 115673, 115678, 115682, 115687, 115691, 115696, 115701, 115706, 115711, + 115716, 115721, 115726, 115731, 115736, 115741, 115746, 115751, 115756, + 115761, 115766, 115771, 115776, 115781, 115785, 115789, 115794, 115799, + 115804, 115808, 115812, 115816, 115820, 115825, 115830, 115834, 115838, + 115843, 115848, 115853, 115859, 115864, 115870, 115875, 115881, 115886, + 115892, 115897, 115903, 115908, 115913, 115920, 0, 0, 0, 0, 0, 0, 115925, + 115930, 115934, 115938, 115942, 115946, 115950, 115954, 115958, 115962, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 112720, 112724, 112728, 112732, 112736, 112740, 112745, - 0, 112750, 0, 112755, 112760, 112765, 112770, 0, 112775, 112780, 112785, - 112790, 112795, 112800, 112805, 112810, 112815, 112820, 112825, 112830, - 112834, 112838, 112843, 0, 112848, 112853, 112857, 112861, 112865, - 112869, 112874, 112878, 112882, 112887, 112892, 0, 0, 0, 0, 0, 0, 112897, - 112901, 112906, 112910, 112915, 112919, 112924, 112928, 112933, 112937, - 112942, 112946, 112951, 112956, 112961, 112966, 112971, 112976, 112981, - 112986, 112991, 112996, 113001, 113006, 113011, 113016, 113021, 113026, - 113031, 113036, 113041, 113046, 113051, 113056, 113060, 113064, 113069, - 113074, 113079, 113084, 113088, 113092, 113096, 113100, 113105, 113110, - 113114, 113118, 113123, 113129, 113134, 113140, 113145, 113151, 113156, - 113162, 113167, 113173, 113178, 0, 0, 0, 0, 0, 113183, 113188, 113192, - 113196, 113200, 113204, 113208, 113212, 113216, 113220, 0, 0, 0, 0, 0, 0, - 113224, 113231, 113236, 113241, 0, 113246, 113250, 113255, 113259, - 113264, 113268, 113273, 113278, 0, 0, 113283, 113288, 0, 0, 113293, - 113298, 113303, 113307, 113312, 113317, 113322, 113327, 113332, 113337, - 113342, 113347, 113352, 113357, 113362, 113367, 113372, 113377, 113382, - 113387, 113392, 113397, 0, 113401, 113405, 113410, 113415, 113420, - 113424, 113428, 0, 113432, 113436, 0, 113441, 113446, 113451, 113456, - 113460, 0, 113464, 113468, 113473, 113478, 113484, 113489, 113495, - 113500, 113506, 113512, 0, 0, 113519, 113525, 0, 0, 113531, 113537, - 113543, 0, 0, 113548, 0, 0, 0, 0, 0, 0, 113552, 0, 0, 0, 0, 0, 113559, - 113564, 113571, 113579, 113585, 113591, 113597, 0, 0, 113604, 113610, - 113615, 113620, 113625, 113630, 113635, 0, 0, 0, 113640, 113645, 113650, - 113655, 113661, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 113666, 113670, 113675, - 113679, 113684, 113688, 113693, 113698, 113704, 113709, 113715, 113719, - 113724, 113728, 113733, 113737, 113742, 113747, 113752, 113757, 113762, - 113767, 113772, 113777, 113782, 113787, 113792, 113797, 113802, 113807, - 113812, 113817, 113822, 113827, 113832, 113837, 113841, 113846, 113850, - 113855, 113860, 113865, 113869, 113874, 113878, 113882, 113887, 113891, - 113896, 113901, 113906, 113911, 113915, 113919, 113925, 113930, 113936, - 113941, 113947, 113953, 113960, 113966, 113973, 113978, 113984, 113989, - 113995, 114000, 114005, 114010, 114015, 114020, 114025, 114031, 114035, - 114039, 114043, 114048, 114052, 114058, 114063, 114068, 114072, 114076, - 114080, 114084, 114088, 114092, 114096, 114100, 114104, 114109, 0, - 114114, 114119, 114124, 114131, 114136, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 114141, 114145, - 114149, 114154, 114158, 114163, 114167, 114172, 114177, 114183, 114188, - 114194, 114198, 114203, 114207, 114212, 114216, 114221, 114226, 114231, - 114236, 114241, 114246, 114251, 114256, 114261, 114266, 114271, 114276, - 114281, 114286, 114291, 114296, 114301, 114306, 114310, 114314, 114319, - 114324, 114329, 114333, 114337, 114341, 114345, 114350, 114355, 114360, - 114364, 114368, 114374, 114379, 114385, 114390, 114396, 114402, 114409, - 114415, 114422, 114427, 114434, 114440, 114445, 114452, 114458, 114463, - 114468, 114473, 114478, 114483, 114488, 114492, 114497, 0, 0, 0, 0, 0, 0, - 0, 0, 114501, 114506, 114510, 114514, 114518, 114522, 114526, 114530, - 114534, 114538, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 114542, 114546, - 114551, 114555, 114560, 114564, 114569, 114574, 114580, 114585, 114591, - 114595, 114600, 114604, 114609, 114613, 114618, 114623, 114628, 114633, - 114638, 114643, 114648, 114653, 114658, 114663, 114668, 114673, 114678, - 114683, 114688, 114693, 114698, 114703, 114707, 114711, 114716, 114721, - 114726, 114730, 114734, 114738, 114742, 114747, 114752, 114757, 114761, - 114765, 114771, 114776, 114782, 114787, 114793, 114799, 0, 0, 114806, - 114811, 114817, 114822, 114828, 114833, 114838, 114843, 114848, 114853, - 114858, 114862, 114867, 114873, 114878, 114884, 114890, 114896, 114904, - 114917, 114930, 114943, 114957, 114972, 114980, 114991, 115000, 115010, - 115020, 115030, 115041, 115053, 115066, 115074, 115082, 115091, 115097, - 115104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115112, 115116, 115121, 115125, - 115130, 115134, 115139, 115144, 115150, 115155, 115161, 115165, 115170, - 115174, 115179, 115183, 115188, 115193, 115198, 115203, 115208, 115213, - 115218, 115223, 115228, 115233, 115238, 115243, 115248, 115253, 115258, - 115263, 115268, 115273, 115277, 115281, 115286, 115291, 115296, 115300, - 115304, 115308, 115312, 115317, 115322, 115327, 115331, 115335, 115340, - 115346, 115351, 115357, 115362, 115368, 115374, 115381, 115387, 115394, - 115399, 115405, 115410, 115416, 115421, 115426, 115431, 115436, 115440, - 115445, 115450, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115455, 115460, 115464, - 115468, 115472, 115476, 115480, 115484, 115488, 115492, 0, 0, 0, 0, 0, 0, - 115496, 115502, 115507, 115514, 115522, 115529, 115537, 115546, 115551, - 115560, 115565, 115573, 115582, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 115592, 115596, 115601, 115605, 115610, 115614, 115619, - 115623, 115628, 115632, 115637, 115641, 115646, 115651, 115656, 115661, - 115666, 115671, 115676, 115681, 115686, 115691, 115696, 115701, 115706, - 115711, 115716, 115721, 115726, 115731, 115735, 115739, 115744, 115749, - 115754, 115758, 115762, 115766, 115770, 115775, 115780, 115784, 115788, - 115793, 115798, 115803, 115809, 115814, 115820, 115825, 115831, 115836, - 115842, 115847, 115853, 115858, 115863, 115870, 0, 0, 0, 0, 0, 0, 115875, - 115880, 115884, 115888, 115892, 115896, 115900, 115904, 115908, 115912, + 0, 0, 0, 0, 0, 0, 115966, 115970, 115975, 115980, 115984, 115989, 115996, + 116000, 116005, 116010, 116014, 116019, 116024, 116029, 116033, 116037, + 116041, 116046, 116050, 116054, 116059, 116064, 116069, 116076, 116081, + 116086, 116091, 0, 0, 116098, 116105, 116112, 116121, 116126, 116132, + 116137, 116143, 116148, 116154, 116159, 116165, 116170, 116176, 116182, + 0, 0, 0, 0, 116187, 116192, 116196, 116200, 116204, 116208, 116212, + 116216, 116220, 116224, 116228, 116233, 116238, 116244, 116249, 116254, + 116259, 116264, 116269, 116274, 116279, 116284, 116289, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 115916, 115920, 115925, 115930, 115934, 115939, 115946, - 115950, 115955, 115960, 115964, 115969, 115974, 115979, 115983, 115987, - 115991, 115996, 116000, 116004, 116009, 116014, 116019, 116026, 116031, - 116036, 116041, 0, 0, 116048, 116055, 116062, 116071, 116076, 116082, - 116087, 116093, 116098, 116104, 116109, 116115, 116120, 116126, 116132, - 0, 0, 0, 0, 116137, 116142, 116146, 116150, 116154, 116158, 116162, - 116166, 116170, 116174, 116178, 116183, 116188, 116194, 116199, 116204, - 116209, 116214, 116219, 116224, 116229, 116234, 116239, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 116294, 116298, 116303, 116307, 116312, 116316, 116321, 116325, + 116330, 116334, 116339, 116343, 116348, 116353, 116358, 116363, 116368, + 116373, 116378, 116383, 116388, 116393, 116398, 116403, 116408, 116413, + 116418, 116423, 116428, 116433, 116437, 116441, 116446, 116451, 116456, + 116460, 116464, 116468, 116472, 116477, 116482, 116487, 116491, 116495, + 116500, 116506, 116511, 116517, 116522, 116528, 116534, 116541, 116546, + 116552, 116557, 116563, 116568, 116573, 116578, 116583, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 116244, 116248, 116253, 116257, 116262, 116266, 116271, 116275, - 116280, 116284, 116289, 116293, 116298, 116303, 116308, 116313, 116318, - 116323, 116328, 116333, 116338, 116343, 116348, 116353, 116358, 116363, - 116368, 116373, 116378, 116383, 116387, 116391, 116396, 116401, 116406, - 116410, 116414, 116418, 116422, 116427, 116432, 116437, 116441, 116445, - 116450, 116456, 116461, 116467, 116472, 116478, 116484, 116491, 116496, - 116502, 116507, 116513, 116518, 116523, 116528, 116533, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 116588, + 116596, 116603, 116611, 116619, 116626, 116634, 116642, 116650, 116657, + 116664, 116672, 116680, 116688, 116696, 116704, 116712, 116720, 116728, + 116736, 116744, 116752, 116760, 116768, 116776, 116784, 116792, 116800, + 116808, 116816, 116824, 116832, 116840, 116848, 116855, 116863, 116871, + 116878, 116886, 116894, 116902, 116909, 116916, 116924, 116932, 116940, + 116948, 116956, 116964, 116972, 116980, 116988, 116996, 117004, 117012, + 117020, 117028, 117036, 117044, 117052, 117060, 117068, 117076, 117084, + 117092, 117099, 117105, 117111, 117117, 117123, 117129, 117135, 117141, + 117147, 117153, 117160, 117167, 117174, 117181, 117188, 117195, 117202, + 117209, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 117216, 117222, 117228, + 117235, 117241, 117248, 117254, 117261, 0, 0, 117267, 0, 0, 117273, + 117279, 117286, 117293, 117300, 117307, 117314, 117321, 0, 117328, + 117335, 0, 117342, 117349, 117356, 117363, 117370, 117377, 117384, + 117391, 117397, 117403, 117410, 117417, 117424, 117430, 117436, 117443, + 117449, 117455, 117462, 117469, 117476, 117482, 117488, 117495, 117502, + 117510, 117517, 117525, 117532, 117540, 0, 117547, 117555, 0, 0, 117562, + 117569, 117576, 117583, 117589, 117598, 117605, 117611, 117618, 117625, + 117632, 117640, 0, 0, 0, 0, 0, 0, 0, 0, 0, 117650, 117657, 117663, + 117669, 117675, 117681, 117687, 117693, 117699, 117705, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 116538, - 116546, 116553, 116561, 116569, 116576, 116584, 116592, 116600, 116607, - 116614, 116622, 116630, 116638, 116646, 116654, 116662, 116670, 116678, - 116686, 116694, 116702, 116710, 116718, 116726, 116734, 116742, 116750, - 116758, 116766, 116774, 116782, 116790, 116798, 116805, 116813, 116821, - 116828, 116836, 116844, 116852, 116859, 116866, 116874, 116882, 116890, - 116898, 116906, 116914, 116922, 116930, 116938, 116946, 116954, 116962, - 116970, 116978, 116986, 116994, 117002, 117010, 117018, 117026, 117034, - 117042, 117049, 117055, 117061, 117067, 117073, 117079, 117085, 117091, - 117097, 117103, 117110, 117117, 117124, 117131, 117138, 117145, 117152, - 117159, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 117166, 117172, 117178, - 117185, 117191, 117198, 117204, 117211, 0, 0, 117217, 0, 0, 117223, - 117229, 117236, 117243, 117250, 117257, 117264, 117271, 0, 117278, - 117285, 0, 117292, 117299, 117306, 117313, 117320, 117327, 117334, - 117341, 117347, 117353, 117360, 117367, 117374, 117380, 117386, 117393, - 117399, 117405, 117412, 117419, 117426, 117432, 117438, 117445, 117452, - 117460, 117467, 117475, 117482, 117490, 0, 117497, 117505, 0, 0, 117512, - 117519, 117526, 117533, 117539, 117548, 117555, 117561, 117568, 117575, - 117582, 117590, 0, 0, 0, 0, 0, 0, 0, 0, 0, 117600, 117607, 117613, - 117619, 117625, 117631, 117637, 117643, 117649, 117655, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 117711, 117715, 117720, + 117724, 117729, 117733, 117738, 117743, 0, 0, 117749, 117753, 117758, + 117762, 117767, 117771, 117776, 117781, 117786, 117791, 117796, 117801, + 117806, 117811, 117816, 117821, 117826, 117831, 117836, 117841, 117846, + 117851, 117856, 117861, 117865, 117869, 117874, 117879, 117884, 117888, + 117892, 117896, 117900, 117905, 117910, 117915, 117919, 117923, 117928, + 117933, 117939, 117944, 117950, 117955, 117961, 117967, 0, 0, 117974, + 117979, 117985, 117990, 117996, 118001, 118006, 118011, 118016, 118021, + 118025, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 118032, 118037, 118043, 118050, 118056, 118062, 118069, + 118075, 118082, 118089, 118097, 118104, 118109, 118115, 118121, 118127, + 118133, 118139, 118145, 118151, 118157, 118163, 118169, 118175, 118181, + 118187, 118193, 118199, 118205, 118211, 118216, 118221, 118227, 118233, + 118239, 118244, 118250, 118256, 118262, 118268, 118274, 118280, 118286, + 118291, 118296, 118301, 118307, 118313, 118319, 118324, 118329, 118335, + 118341, 118347, 118353, 118362, 118371, 118377, 118383, 118390, 118397, + 118404, 118411, 118419, 118426, 118434, 118440, 118446, 118453, 118460, + 118469, 118479, 0, 0, 0, 0, 0, 0, 0, 0, 118484, 118488, 118493, 118499, + 118504, 118509, 118514, 118520, 118526, 118532, 118538, 118544, 118550, + 118554, 118559, 118564, 118569, 118574, 118579, 118584, 118589, 118594, + 118599, 118604, 118609, 118614, 118619, 118624, 118629, 118634, 118639, + 118644, 118648, 118652, 118657, 118662, 118667, 118671, 118676, 118681, + 118686, 118691, 118696, 118701, 118705, 118709, 118713, 118718, 118723, + 118728, 118732, 118736, 118741, 118746, 118751, 118757, 118763, 118770, + 118776, 118783, 118790, 118797, 118804, 118811, 118818, 118825, 118831, + 118837, 118844, 118851, 118858, 118863, 118868, 118873, 118877, 118882, + 118887, 118893, 118898, 118914, 118928, 118939, 118945, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 118951, 118957, 118963, 118969, 118975, 118980, + 118986, 118992, 118998, 119004, 119010, 119016, 119022, 119026, 119030, + 119034, 119038, 119046, 119054, 119062, 119070, 119079, 119088, 119097, + 119106, 119114, 119123, 119132, 119140, 119149, 119158, 119167, 119176, + 119184, 119193, 119201, 119210, 119219, 119227, 119235, 119243, 119251, + 119259, 119268, 119277, 119287, 119297, 119307, 119317, 119327, 119336, + 119346, 119356, 119366, 119377, 119387, 119399, 119411, 119422, 119436, + 119447, 119457, 119469, 119480, 119490, 119502, 119514, 119525, 119536, + 119546, 119556, 119568, 119579, 0, 0, 0, 0, 0, 0, 0, 119591, 119595, + 119602, 119606, 119612, 119618, 119626, 119634, 119642, 119650, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 117661, 117665, 117670, - 117674, 117679, 117683, 117688, 117693, 0, 0, 117699, 117703, 117708, - 117712, 117717, 117721, 117726, 117731, 117736, 117741, 117746, 117751, - 117756, 117761, 117766, 117771, 117776, 117781, 117786, 117791, 117796, - 117801, 117806, 117811, 117815, 117819, 117824, 117829, 117834, 117838, - 117842, 117846, 117850, 117855, 117860, 117865, 117869, 117873, 117878, - 117883, 117889, 117894, 117900, 117905, 117911, 117917, 0, 0, 117924, - 117929, 117935, 117940, 117946, 117951, 117956, 117961, 117966, 117971, - 117975, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 117982, 117987, 117993, 118000, 118006, 118012, 118019, - 118025, 118032, 118039, 118047, 118054, 118059, 118065, 118071, 118077, - 118083, 118089, 118095, 118101, 118107, 118113, 118119, 118125, 118131, - 118137, 118143, 118149, 118155, 118161, 118166, 118171, 118177, 118183, - 118189, 118194, 118200, 118206, 118212, 118218, 118224, 118230, 118236, - 118241, 118246, 118251, 118257, 118263, 118269, 118274, 118279, 118285, - 118291, 118297, 118303, 118312, 118321, 118327, 118333, 118340, 118347, - 118354, 118361, 118369, 118376, 118384, 118390, 118396, 118403, 118410, - 118419, 118429, 0, 0, 0, 0, 0, 0, 0, 0, 118434, 118438, 118443, 118449, - 118454, 118459, 118464, 118470, 118476, 118482, 118488, 118494, 118500, - 118504, 118509, 118514, 118519, 118524, 118529, 118534, 118539, 118544, - 118549, 118554, 118559, 118564, 118569, 118574, 118579, 118584, 118589, - 118594, 118598, 118602, 118607, 118612, 118617, 118621, 118626, 118631, - 118636, 118641, 118646, 118651, 118655, 118659, 118663, 118668, 118673, - 118678, 118682, 118686, 118691, 118696, 118701, 118707, 118713, 118720, - 118726, 118733, 118740, 118747, 118754, 118761, 118768, 118775, 118781, - 118787, 118794, 118801, 118808, 118813, 118818, 118823, 118827, 118832, - 118837, 118843, 118848, 118864, 118878, 118889, 118895, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 118901, 118907, 118913, 118919, 118925, 118930, - 118936, 118942, 118948, 118954, 118960, 118966, 118972, 118976, 118980, - 118984, 118988, 118996, 119004, 119012, 119020, 119029, 119038, 119047, - 119056, 119064, 119073, 119082, 119090, 119099, 119108, 119117, 119126, - 119134, 119143, 119151, 119160, 119169, 119177, 119185, 119193, 119201, - 119209, 119218, 119227, 119237, 119247, 119257, 119267, 119277, 119286, - 119296, 119306, 119316, 119327, 119337, 119349, 119361, 119372, 119386, - 119397, 119407, 119419, 119430, 119440, 119452, 119464, 119475, 119486, - 119496, 119506, 119518, 119529, 0, 0, 0, 0, 0, 0, 0, 119541, 119545, - 119550, 119554, 119559, 119563, 119568, 119573, 119579, 0, 119584, - 119588, 119593, 119597, 119602, 119606, 119611, 119616, 119621, 119626, - 119631, 119636, 119641, 119646, 119651, 119656, 119661, 119666, 119671, - 119676, 119681, 119686, 119691, 119696, 119700, 119704, 119709, 119714, - 119719, 119723, 119727, 119731, 119735, 119740, 119745, 119750, 119754, - 119758, 119764, 119769, 119775, 119780, 119786, 119792, 119799, 0, - 119805, 119810, 119816, 119821, 119827, 119832, 119837, 119842, 119847, - 119852, 119856, 119861, 119867, 119873, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 119879, 119884, 119888, 119892, 119896, 119900, 119904, 119908, 119912, - 119916, 119920, 119924, 119928, 119932, 119936, 119940, 119944, 119948, - 119952, 119956, 119961, 119966, 119971, 119976, 119981, 119986, 119991, - 119996, 120001, 0, 0, 0, 120008, 120013, 120018, 120022, 120027, 120032, - 120037, 120042, 120047, 120052, 120057, 120062, 120067, 120072, 120076, - 120080, 120085, 120090, 120094, 120099, 120104, 120109, 120114, 120119, - 120124, 120129, 120133, 120137, 120141, 120146, 120150, 120154, 0, 0, - 120158, 120164, 120171, 120178, 120185, 120192, 120199, 120206, 120213, - 120220, 120227, 120234, 120240, 120246, 120253, 120260, 120266, 120273, - 120280, 120287, 120294, 120301, 0, 120308, 120314, 120320, 120326, - 120333, 120339, 120345, 120351, 120357, 120362, 120367, 120372, 120377, - 120382, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 120387, 120392, 120398, 120403, 120409, 120414, 120420, 0, - 120425, 120431, 0, 120436, 120442, 120447, 120453, 120459, 120465, - 120471, 120477, 120483, 120489, 120495, 120501, 120507, 120513, 120519, - 120525, 120531, 120537, 120543, 120549, 120555, 120560, 120565, 120571, - 120577, 120583, 120588, 120593, 120598, 120603, 120609, 120615, 120621, - 120626, 120631, 120637, 120643, 120649, 120655, 120662, 120668, 120675, - 120681, 120688, 0, 0, 0, 120695, 0, 120701, 120708, 0, 120714, 120721, - 120727, 120733, 120739, 120745, 120751, 120756, 120761, 0, 0, 0, 0, 0, 0, - 0, 0, 120766, 120772, 120777, 120782, 120787, 120792, 120797, 120802, - 120807, 120812, 0, 0, 0, 0, 0, 0, 120817, 120822, 120828, 120833, 120839, - 120844, 0, 120850, 120856, 0, 120862, 120868, 120874, 120879, 120885, - 120891, 120897, 120902, 120907, 120913, 120919, 120925, 120930, 120936, - 120942, 120948, 120954, 120959, 120965, 120971, 120977, 120983, 120989, - 120995, 121001, 121007, 121013, 121019, 121024, 121030, 121035, 121040, - 121045, 121052, 121058, 121065, 121071, 0, 121078, 121085, 0, 121092, - 121099, 121106, 121112, 121118, 121123, 0, 0, 0, 0, 0, 0, 0, 121128, - 121134, 121139, 121144, 121149, 121154, 121159, 121164, 121169, 121174, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 119654, 119658, + 119663, 119667, 119672, 119676, 119681, 119686, 119692, 0, 119697, + 119701, 119706, 119710, 119715, 119719, 119724, 119729, 119734, 119739, + 119744, 119749, 119754, 119759, 119764, 119769, 119774, 119779, 119784, + 119789, 119794, 119799, 119804, 119809, 119813, 119817, 119822, 119827, + 119832, 119836, 119840, 119844, 119848, 119853, 119858, 119863, 119867, + 119871, 119877, 119882, 119888, 119893, 119899, 119905, 119912, 0, + 119918, 119923, 119929, 119934, 119940, 119945, 119950, 119955, 119960, + 119965, 119969, 119974, 119980, 119986, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 119992, 119997, 120001, 120005, 120009, 120013, 120017, 120021, 120025, + 120029, 120033, 120037, 120041, 120045, 120049, 120053, 120057, 120061, + 120065, 120069, 120074, 120079, 120084, 120089, 120094, 120099, 120104, + 120109, 120114, 0, 0, 0, 120121, 120126, 120131, 120135, 120140, 120145, + 120150, 120155, 120160, 120165, 120170, 120175, 120180, 120185, 120189, + 120193, 120198, 120203, 120207, 120212, 120217, 120222, 120227, 120232, + 120237, 120242, 120246, 120250, 120254, 120259, 120263, 120267, 0, 0, + 120271, 120277, 120284, 120291, 120298, 120305, 120312, 120319, 120326, + 120333, 120340, 120347, 120353, 120359, 120366, 120373, 120379, 120386, + 120393, 120400, 120407, 120414, 0, 120421, 120427, 120433, 120439, + 120446, 120452, 120458, 120464, 120470, 120475, 120480, 120485, 120490, + 120495, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 120500, 120505, 120511, 120516, 120522, 120527, 120533, 0, + 120538, 120544, 0, 120549, 120555, 120560, 120566, 120572, 120578, + 120584, 120590, 120596, 120602, 120608, 120614, 120620, 120626, 120632, + 120638, 120644, 120650, 120656, 120662, 120668, 120673, 120678, 120684, + 120690, 120696, 120701, 120706, 120711, 120716, 120722, 120728, 120734, + 120739, 120744, 120750, 120756, 120762, 120768, 120775, 120781, 120788, + 120794, 120801, 0, 0, 0, 120808, 0, 120814, 120821, 0, 120827, 120834, + 120840, 120846, 120852, 120858, 120864, 120869, 120874, 0, 0, 0, 0, 0, 0, + 0, 0, 120879, 120885, 120890, 120895, 120900, 120905, 120910, 120915, + 120920, 120925, 0, 0, 0, 0, 0, 0, 120930, 120935, 120941, 120946, 120952, + 120957, 0, 120963, 120969, 0, 120975, 120981, 120987, 120992, 120998, + 121004, 121010, 121015, 121020, 121026, 121032, 121038, 121043, 121049, + 121055, 121061, 121067, 121072, 121078, 121084, 121090, 121096, 121102, + 121108, 121114, 121120, 121126, 121132, 121137, 121143, 121148, 121153, + 121158, 121165, 121171, 121178, 121184, 0, 121191, 121198, 0, 121205, + 121212, 121219, 121225, 121231, 121236, 0, 0, 0, 0, 0, 0, 0, 121241, + 121247, 121252, 121257, 121262, 121267, 121272, 121277, 121282, 121287, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -23492,1692 +23636,1727 @@ static const unsigned int phrasebook_offset2[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 121179, 121183, 121188, 121193, - 121197, 121202, 121206, 121211, 121216, 121220, 121225, 121230, 121235, - 121239, 121243, 121247, 121252, 121256, 121260, 121264, 121269, 121274, - 121279, 121284, 121288, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 121292, 121296, 121301, 121306, + 121310, 121315, 121319, 121324, 121329, 121333, 121338, 121343, 121348, + 121352, 121356, 121360, 121365, 121369, 121373, 121377, 121382, 121387, + 121392, 121397, 121401, 0, 0, 0, 0, 0, 0, 0, 121408, 121413, 121418, + 121423, 121428, 121432, 121437, 121441, 121446, 121450, 121455, 121460, + 121466, 121471, 121477, 121481, 121486, 0, 121490, 121494, 121499, + 121504, 121509, 121514, 121519, 121524, 121529, 121534, 121539, 121544, + 121549, 121554, 121559, 121564, 121569, 121574, 121579, 121584, 121588, + 121592, 121597, 121602, 121607, 121611, 121615, 121619, 121623, 121628, + 121633, 121638, 121642, 121646, 121651, 121657, 121665, 121670, 121676, + 121681, 121687, 0, 0, 0, 121693, 121698, 121704, 121710, 121715, 121719, + 121723, 121728, 121736, 121746, 121752, 121760, 121766, 121773, 121781, + 121787, 121795, 121801, 121809, 121814, 121818, 121822, 121826, 121830, + 121834, 121838, 121842, 121846, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 121295, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 121300, 121306, 121312, 121318, 121324, 121330, - 121336, 121342, 121348, 121354, 121360, 121366, 121372, 121378, 121384, - 121390, 121396, 121402, 121408, 121414, 121420, 121429, 121433, 121437, - 121441, 121445, 121449, 121453, 121457, 121461, 121465, 121469, 121473, - 121477, 121481, 121485, 121489, 121495, 121501, 121505, 121511, 121517, - 121522, 121526, 121531, 121535, 121539, 121545, 121551, 121555, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 121559, 121567, 121570, 121575, 121581, - 121589, 121594, 121600, 121608, 121614, 121620, 121624, 121628, 121635, - 121644, 121651, 121660, 121666, 121675, 121682, 121689, 121696, 121706, - 121712, 121716, 121723, 121732, 121742, 121749, 121756, 121760, 121764, - 121771, 121781, 121785, 121792, 121799, 121806, 121812, 121819, 121826, - 121833, 121840, 121844, 121848, 121852, 121859, 121863, 121870, 121877, - 121891, 121900, 121904, 121908, 121912, 121919, 121923, 121927, 121931, - 121939, 121947, 121966, 121976, 121996, 122000, 122004, 122008, 122012, - 122016, 122020, 122024, 122031, 122035, 122038, 122042, 122046, 122052, - 122059, 122068, 122072, 122081, 122090, 122098, 122102, 122109, 122113, - 122117, 122121, 122125, 122136, 122145, 122154, 122163, 122172, 122184, - 122193, 122202, 122211, 122219, 122228, 122240, 122249, 122257, 122266, - 122278, 122287, 122296, 122308, 122317, 122326, 122338, 122347, 122351, - 122355, 122359, 122363, 122367, 122371, 122375, 122382, 122386, 122390, - 122401, 122405, 122409, 122416, 122422, 122428, 122432, 122439, 122443, - 122447, 122451, 122455, 122459, 122463, 122469, 122477, 122481, 122485, - 122488, 122495, 122507, 122511, 122523, 122530, 122537, 122544, 122551, - 122557, 122561, 122565, 122569, 122573, 122580, 122589, 122596, 122604, - 122612, 122618, 122622, 122626, 122630, 122634, 122640, 122649, 122661, - 122668, 122675, 122684, 122695, 122701, 122710, 122719, 122726, 122735, - 122742, 122748, 122758, 122765, 122772, 122779, 122786, 122790, 122796, - 122800, 122811, 122819, 122828, 122840, 122847, 122854, 122864, 122871, - 122880, 122887, 122896, 122903, 122910, 122920, 122927, 122934, 122943, - 122950, 122962, 122971, 122978, 122985, 122992, 123001, 123011, 123024, - 123031, 123040, 123050, 123057, 123066, 123079, 123086, 123093, 123100, - 123110, 123120, 123126, 123136, 123143, 123150, 123160, 123166, 123173, - 123180, 123187, 123197, 123204, 123211, 123218, 123224, 123231, 123241, - 123248, 123252, 123260, 123264, 123276, 123280, 123294, 123298, 123302, - 123306, 123310, 123316, 123323, 123331, 123335, 123339, 123343, 123347, - 123354, 123358, 123364, 123370, 123378, 123382, 123389, 123397, 123401, - 123405, 123411, 123415, 123424, 123433, 123440, 123450, 123456, 123460, - 123464, 123472, 123479, 123486, 123492, 123496, 123504, 123508, 123515, - 123527, 123534, 123544, 123550, 123554, 123563, 123570, 123579, 123583, - 123587, 123594, 123598, 123602, 123606, 123610, 123613, 123619, 123625, - 123629, 123633, 123640, 123647, 123654, 123661, 123668, 123675, 123682, - 123689, 123695, 123699, 123703, 123710, 123717, 123724, 123731, 123738, - 123742, 123745, 123750, 123754, 123758, 123767, 123776, 123780, 123784, - 123790, 123796, 123813, 123819, 123823, 123832, 123836, 123840, 123847, - 123855, 123863, 123869, 123873, 123877, 123881, 123885, 123888, 123894, - 123901, 123911, 123918, 123925, 123932, 123938, 123945, 123952, 123959, - 123966, 123973, 123982, 123989, 124001, 124008, 124015, 124025, 124036, - 124043, 124050, 124057, 124064, 124071, 124078, 124085, 124092, 124099, - 124106, 124116, 124126, 124136, 124143, 124153, 124160, 124167, 124174, - 124181, 124187, 124194, 124201, 124208, 124215, 124222, 124229, 124236, - 124243, 124249, 124256, 124263, 124272, 124279, 124286, 124290, 124298, - 124302, 124306, 124310, 124314, 124318, 124325, 124329, 124338, 124342, - 124349, 124357, 124361, 124365, 124369, 124382, 124398, 124402, 124406, - 124413, 124419, 124426, 124430, 124434, 124438, 124442, 124446, 124453, - 124457, 124475, 124479, 124483, 124490, 124494, 124498, 124504, 124508, - 124512, 124520, 124524, 124528, 124531, 124535, 124541, 124552, 124561, - 124570, 124577, 124584, 124595, 124602, 124609, 124616, 124623, 124630, - 124637, 124644, 124654, 124660, 124667, 124677, 124686, 124693, 124702, - 124712, 124719, 124726, 124733, 124740, 124752, 124759, 124766, 124773, - 124780, 124787, 124797, 124804, 124811, 124821, 124834, 124846, 124853, - 124863, 124870, 124877, 124884, 124898, 124904, 124912, 124922, 124932, - 124939, 124946, 124952, 124956, 124963, 124973, 124979, 124992, 124996, - 125000, 125007, 125011, 125018, 125028, 125032, 125036, 125040, 125044, - 125048, 125055, 125059, 125066, 125073, 125080, 125089, 125098, 125108, - 125115, 125122, 125129, 125139, 125146, 125156, 125163, 125173, 125180, - 125187, 125197, 125207, 125214, 125220, 125228, 125236, 125242, 125248, - 125252, 125256, 125263, 125271, 125277, 125281, 125285, 125289, 125296, - 125308, 125311, 125318, 125324, 125328, 125332, 125336, 125340, 125344, - 125348, 125352, 125356, 125360, 125364, 125371, 125375, 125381, 125385, - 125389, 125393, 125399, 125406, 125413, 125420, 125431, 125439, 125443, - 125449, 125458, 125465, 125471, 125474, 125478, 125482, 125488, 125497, - 125505, 125509, 125515, 125519, 125523, 125527, 125533, 125540, 125546, - 125550, 125556, 125560, 125564, 125573, 125585, 125589, 125596, 125603, - 125613, 125620, 125632, 125639, 125646, 125653, 125664, 125674, 125687, - 125697, 125704, 125708, 125712, 125716, 125720, 125729, 125738, 125747, - 125764, 125773, 125779, 125786, 125794, 125807, 125811, 125820, 125829, - 125838, 125847, 125858, 125867, 125875, 125884, 125893, 125902, 125911, - 125921, 125924, 125928, 125932, 125936, 125940, 125944, 125950, 125957, - 125964, 125971, 125977, 125983, 125990, 125996, 126003, 126011, 126015, - 126022, 126029, 126036, 126044, 126047, 126051, 126055, 126059, 126062, - 126068, 126072, 126078, 126085, 126092, 126098, 126105, 126112, 126119, - 126126, 126133, 126140, 126147, 126154, 126161, 126168, 126175, 126182, - 126189, 126196, 126202, 126206, 126215, 126219, 126223, 126227, 126231, - 126237, 126244, 126251, 126258, 126265, 126272, 126278, 126286, 126290, - 126294, 126298, 126302, 126308, 126325, 126342, 126346, 126350, 126354, - 126358, 126362, 126366, 126372, 126379, 126383, 126389, 126396, 126403, - 126410, 126417, 126424, 126433, 126440, 126447, 126454, 126461, 126465, - 126469, 126475, 126487, 126491, 126495, 126504, 126508, 126512, 126516, - 126522, 126526, 126530, 126539, 126543, 126547, 126551, 126558, 126562, - 126566, 126570, 126574, 126578, 126582, 126586, 126590, 126596, 126603, - 126610, 126616, 126620, 126637, 126643, 126647, 126654, 126661, 126668, - 126675, 126682, 126689, 126693, 126697, 126701, 126707, 126711, 126717, - 126721, 126725, 126732, 126739, 126756, 126760, 126764, 126768, 126772, - 126776, 126788, 126791, 126796, 126801, 126816, 126826, 126838, 126842, - 126846, 126850, 126856, 126863, 126870, 126880, 126892, 126898, 126904, - 126913, 126917, 126921, 126928, 126938, 126945, 126951, 126955, 126959, - 126966, 126972, 126976, 126982, 126986, 126994, 127000, 127004, 127012, - 127020, 127027, 127033, 127040, 127047, 127057, 127067, 127071, 127075, - 127079, 127083, 127089, 127096, 127102, 127109, 127116, 127123, 127132, - 127139, 127146, 127152, 127159, 127166, 127173, 127180, 127187, 127194, - 127200, 127207, 127214, 127221, 127230, 127237, 127244, 127248, 127254, - 127258, 127264, 127271, 127278, 127285, 127289, 127293, 127297, 127301, - 127305, 127312, 127316, 127320, 127326, 127334, 127338, 127342, 127346, - 127350, 127357, 127361, 127365, 127373, 127377, 127381, 127385, 127389, - 127395, 127399, 127403, 127409, 127416, 127422, 127429, 127441, 127445, - 127452, 127459, 127466, 127473, 127485, 127492, 127496, 127500, 127504, - 127511, 127518, 127525, 127532, 127542, 127549, 127555, 127562, 127569, - 127576, 127583, 127592, 127602, 127609, 127613, 127620, 127624, 127628, - 127632, 127639, 127646, 127656, 127662, 127666, 127675, 127679, 127686, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 121850, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 121855, 121861, + 121867, 121873, 121879, 121885, 121891, 121897, 121903, 121909, 121915, + 121921, 121927, 121933, 121939, 121945, 121951, 121957, 121963, 121969, + 121975, 121984, 121988, 121992, 121996, 122000, 122004, 122008, 122012, + 122016, 122020, 122024, 122028, 122032, 122036, 122040, 122044, 122050, + 122056, 122060, 122066, 122072, 122077, 122081, 122086, 122090, 122094, + 122100, 122106, 122110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122114, + 122122, 122125, 122130, 122136, 122144, 122149, 122155, 122163, 122169, + 122175, 122179, 122183, 122190, 122199, 122206, 122215, 122221, 122230, + 122237, 122244, 122251, 122261, 122267, 122271, 122278, 122287, 122297, + 122304, 122311, 122315, 122319, 122326, 122336, 122340, 122347, 122354, + 122361, 122367, 122374, 122381, 122388, 122395, 122399, 122403, 122407, + 122414, 122418, 122425, 122432, 122446, 122455, 122459, 122463, 122467, + 122474, 122478, 122482, 122486, 122494, 122502, 122521, 122531, 122551, + 122555, 122559, 122563, 122567, 122571, 122575, 122579, 122586, 122590, + 122593, 122597, 122601, 122607, 122614, 122623, 122627, 122636, 122645, + 122653, 122657, 122664, 122668, 122672, 122676, 122680, 122691, 122700, + 122709, 122718, 122727, 122739, 122748, 122757, 122766, 122774, 122783, + 122795, 122804, 122812, 122821, 122833, 122842, 122851, 122863, 122872, + 122881, 122893, 122902, 122906, 122910, 122914, 122918, 122922, 122926, + 122930, 122937, 122941, 122945, 122956, 122960, 122964, 122971, 122977, + 122983, 122987, 122994, 122998, 123002, 123006, 123010, 123014, 123018, + 123024, 123032, 123036, 123040, 123043, 123050, 123062, 123066, 123078, + 123085, 123092, 123099, 123106, 123112, 123116, 123120, 123124, 123128, + 123135, 123144, 123151, 123159, 123167, 123173, 123177, 123181, 123185, + 123189, 123195, 123204, 123216, 123223, 123230, 123239, 123250, 123256, + 123265, 123274, 123281, 123290, 123297, 123303, 123313, 123320, 123327, + 123334, 123341, 123345, 123351, 123355, 123366, 123374, 123383, 123395, + 123402, 123409, 123419, 123426, 123435, 123442, 123451, 123458, 123465, + 123475, 123482, 123489, 123498, 123505, 123517, 123526, 123533, 123540, + 123547, 123556, 123566, 123579, 123586, 123595, 123605, 123612, 123621, + 123634, 123641, 123648, 123655, 123665, 123675, 123681, 123691, 123698, + 123705, 123715, 123721, 123728, 123735, 123742, 123752, 123759, 123766, + 123773, 123779, 123786, 123796, 123803, 123807, 123815, 123819, 123831, + 123835, 123849, 123853, 123857, 123861, 123865, 123871, 123878, 123886, + 123890, 123894, 123898, 123902, 123909, 123913, 123919, 123925, 123933, + 123937, 123944, 123952, 123956, 123960, 123966, 123970, 123979, 123988, + 123995, 124005, 124011, 124015, 124019, 124027, 124034, 124041, 124047, + 124051, 124059, 124063, 124070, 124082, 124089, 124099, 124105, 124109, + 124118, 124125, 124134, 124138, 124142, 124149, 124153, 124157, 124161, + 124165, 124168, 124174, 124180, 124184, 124188, 124195, 124202, 124209, + 124216, 124223, 124230, 124237, 124244, 124250, 124254, 124258, 124265, + 124272, 124279, 124286, 124293, 124297, 124300, 124305, 124309, 124313, + 124322, 124331, 124335, 124339, 124345, 124351, 124368, 124374, 124378, + 124387, 124391, 124395, 124402, 124410, 124418, 124424, 124428, 124432, + 124436, 124440, 124443, 124449, 124456, 124466, 124473, 124480, 124487, + 124493, 124500, 124507, 124514, 124521, 124528, 124537, 124544, 124556, + 124563, 124570, 124580, 124591, 124598, 124605, 124612, 124619, 124626, + 124633, 124640, 124647, 124654, 124661, 124671, 124681, 124691, 124698, + 124708, 124715, 124722, 124729, 124736, 124742, 124749, 124756, 124763, + 124770, 124777, 124784, 124791, 124798, 124804, 124811, 124818, 124827, + 124834, 124841, 124845, 124853, 124857, 124861, 124865, 124869, 124873, + 124880, 124884, 124893, 124897, 124904, 124912, 124916, 124920, 124924, + 124937, 124953, 124957, 124961, 124968, 124974, 124981, 124985, 124989, + 124993, 124997, 125001, 125008, 125012, 125030, 125034, 125038, 125045, + 125049, 125053, 125059, 125063, 125067, 125075, 125079, 125083, 125086, + 125090, 125096, 125107, 125116, 125125, 125132, 125139, 125150, 125157, + 125164, 125171, 125178, 125185, 125192, 125199, 125209, 125215, 125222, + 125232, 125241, 125248, 125257, 125267, 125274, 125281, 125288, 125295, + 125307, 125314, 125321, 125328, 125335, 125342, 125352, 125359, 125366, + 125376, 125389, 125401, 125408, 125418, 125425, 125432, 125439, 125453, + 125459, 125467, 125477, 125487, 125494, 125501, 125507, 125511, 125518, + 125528, 125534, 125547, 125551, 125555, 125562, 125566, 125573, 125583, + 125587, 125591, 125595, 125599, 125603, 125610, 125614, 125621, 125628, + 125635, 125644, 125653, 125663, 125670, 125677, 125684, 125694, 125701, + 125711, 125718, 125728, 125735, 125742, 125752, 125762, 125769, 125775, + 125783, 125791, 125797, 125803, 125807, 125811, 125818, 125826, 125832, + 125836, 125840, 125844, 125851, 125863, 125866, 125873, 125879, 125883, + 125887, 125891, 125895, 125899, 125903, 125907, 125911, 125915, 125919, + 125926, 125930, 125936, 125940, 125944, 125948, 125954, 125961, 125968, + 125975, 125986, 125994, 125998, 126004, 126013, 126020, 126026, 126029, + 126033, 126037, 126043, 126052, 126060, 126064, 126070, 126074, 126078, + 126082, 126088, 126095, 126101, 126105, 126111, 126115, 126119, 126128, + 126140, 126144, 126151, 126158, 126168, 126175, 126187, 126194, 126201, + 126208, 126219, 126229, 126242, 126252, 126259, 126263, 126267, 126271, + 126275, 126284, 126293, 126302, 126319, 126328, 126334, 126341, 126349, + 126362, 126366, 126375, 126384, 126393, 126402, 126413, 126422, 126430, + 126439, 126448, 126457, 126466, 126476, 126479, 126483, 126487, 126491, + 126495, 126499, 126505, 126512, 126519, 126526, 126532, 126538, 126545, + 126551, 126558, 126566, 126570, 126577, 126584, 126591, 126599, 126602, + 126606, 126610, 126614, 126617, 126623, 126627, 126633, 126640, 126647, + 126653, 126660, 126667, 126674, 126681, 126688, 126695, 126702, 126709, + 126716, 126723, 126730, 126737, 126744, 126751, 126757, 126761, 126770, + 126774, 126778, 126782, 126786, 126792, 126799, 126806, 126813, 126820, + 126827, 126833, 126841, 126845, 126849, 126853, 126857, 126863, 126880, + 126897, 126901, 126905, 126909, 126913, 126917, 126921, 126927, 126934, + 126938, 126944, 126951, 126958, 126965, 126972, 126979, 126988, 126995, + 127002, 127009, 127016, 127020, 127024, 127030, 127042, 127046, 127050, + 127059, 127063, 127067, 127071, 127077, 127081, 127085, 127094, 127098, + 127102, 127106, 127113, 127117, 127121, 127125, 127129, 127133, 127137, + 127141, 127145, 127151, 127158, 127165, 127171, 127175, 127192, 127198, + 127202, 127209, 127216, 127223, 127230, 127237, 127244, 127248, 127252, + 127256, 127262, 127266, 127272, 127276, 127280, 127287, 127294, 127311, + 127315, 127319, 127323, 127327, 127331, 127343, 127346, 127351, 127356, + 127371, 127381, 127393, 127397, 127401, 127405, 127411, 127418, 127425, + 127435, 127447, 127453, 127459, 127468, 127472, 127476, 127483, 127493, + 127500, 127506, 127510, 127514, 127521, 127527, 127531, 127537, 127541, + 127549, 127555, 127559, 127567, 127575, 127582, 127588, 127595, 127602, + 127612, 127622, 127626, 127630, 127634, 127638, 127644, 127651, 127657, + 127664, 127671, 127678, 127687, 127694, 127701, 127707, 127714, 127721, + 127728, 127735, 127742, 127749, 127755, 127762, 127769, 127776, 127785, + 127792, 127799, 127803, 127809, 127813, 127819, 127826, 127833, 127840, + 127844, 127848, 127852, 127856, 127860, 127867, 127871, 127875, 127881, + 127889, 127893, 127897, 127901, 127905, 127912, 127916, 127920, 127928, + 127932, 127936, 127940, 127944, 127950, 127954, 127958, 127964, 127971, + 127977, 127984, 127996, 128000, 128007, 128014, 128021, 128028, 128040, + 128047, 128051, 128055, 128059, 128066, 128073, 128080, 128087, 128097, + 128104, 128110, 128117, 128124, 128131, 128138, 128147, 128157, 128164, + 128168, 128175, 128179, 128183, 128187, 128194, 128201, 128211, 128217, + 128221, 128230, 128234, 128241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 127690, 127696, 127702, 127709, 127716, 127723, 127730, - 127737, 127744, 127750, 127757, 127764, 127771, 127778, 127785, 127792, - 127798, 127804, 127810, 127816, 127822, 127828, 127834, 127840, 127846, - 127853, 127860, 127867, 127874, 127881, 127888, 127894, 127900, 127906, - 127913, 127920, 127926, 127932, 127941, 127948, 127955, 127962, 127969, - 127976, 127983, 127989, 127995, 128001, 128010, 128017, 128024, 128035, - 128046, 128052, 128058, 128064, 128073, 128080, 128087, 128097, 128107, - 128118, 128129, 128141, 128154, 128165, 128176, 128188, 128201, 128212, - 128223, 128234, 128245, 128256, 128268, 128276, 128284, 128293, 128302, - 128311, 128317, 128323, 128329, 128336, 128346, 128353, 128363, 128368, - 128373, 128379, 128385, 128393, 128401, 128410, 128421, 128432, 128440, - 128448, 128457, 128466, 128474, 128481, 128489, 128497, 128504, 128511, - 128520, 128529, 128538, 128547, 128556, 0, 128565, 128576, 128583, - 128591, 128599, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128607, 128616, 128623, - 128630, 128639, 128646, 128653, 128660, 128670, 128677, 128684, 128691, - 128699, 128706, 128713, 128720, 128731, 128738, 128745, 128752, 128759, - 128766, 128775, 128782, 128788, 128795, 128804, 128811, 128818, 128825, - 128835, 128842, 128849, 128859, 128869, 128876, 128883, 128890, 128897, - 128904, 128911, 128920, 128927, 128934, 128940, 128948, 128957, 128966, - 128977, 128985, 128994, 129003, 129012, 129021, 129028, 129035, 129044, - 129056, 129066, 129073, 129080, 129090, 129100, 129109, 129119, 129126, - 129136, 129143, 129150, 129157, 129167, 129177, 129184, 129191, 129201, - 129207, 129218, 129227, 129237, 129245, 129258, 129265, 129271, 129279, - 129286, 129296, 129300, 129304, 129308, 129312, 129316, 129320, 129324, - 129333, 129337, 129344, 129348, 129352, 129356, 129360, 129364, 129368, - 129372, 129376, 129380, 129384, 129388, 129392, 129396, 129400, 129404, - 129408, 129412, 129416, 129420, 129427, 129434, 129444, 129457, 129467, - 129471, 129475, 129479, 129483, 129487, 129491, 129495, 129499, 129503, - 129507, 129511, 129518, 129525, 129536, 129543, 129549, 129556, 129563, - 129570, 129577, 129584, 129588, 129592, 129599, 129606, 129613, 129622, - 129629, 129642, 129652, 129659, 129666, 129670, 129674, 129683, 129690, - 129697, 129704, 129717, 129724, 129731, 129741, 129751, 129760, 129767, - 129774, 129781, 129788, 129795, 129802, 129812, 129818, 129826, 129833, - 129841, 129848, 129859, 129866, 129872, 129879, 129886, 129893, 129900, - 129910, 129920, 129927, 129934, 129943, 129951, 129957, 129964, 129971, - 129978, 129985, 129989, 129999, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128245, 128251, 128257, + 128264, 128271, 128278, 128285, 128292, 128299, 128305, 128312, 128319, + 128326, 128333, 128340, 128347, 128353, 128359, 128365, 128371, 128377, + 128383, 128389, 128395, 128401, 128408, 128415, 128422, 128429, 128436, + 128443, 128449, 128455, 128461, 128468, 128475, 128481, 128487, 128496, + 128503, 128510, 128517, 128524, 128531, 128538, 128544, 128550, 128556, + 128565, 128572, 128579, 128590, 128601, 128607, 128613, 128619, 128628, + 128635, 128642, 128652, 128662, 128673, 128684, 128696, 128709, 128720, + 128731, 128743, 128756, 128767, 128778, 128789, 128800, 128811, 128823, + 128831, 128839, 128848, 128857, 128866, 128872, 128878, 128884, 128891, + 128901, 128908, 128918, 128923, 128928, 128934, 128940, 128948, 128956, + 128965, 128976, 128987, 128995, 129003, 129012, 129021, 129029, 129036, + 129044, 129052, 129059, 129066, 129075, 129084, 129093, 129102, 129111, + 0, 129120, 129131, 129138, 129146, 129154, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 129162, 129171, 129178, 129185, 129194, 129201, 129208, 129215, + 129225, 129232, 129239, 129246, 129254, 129261, 129268, 129275, 129286, + 129293, 129300, 129307, 129314, 129321, 129330, 129337, 129343, 129350, + 129359, 129366, 129373, 129380, 129390, 129397, 129404, 129414, 129424, + 129431, 129438, 129445, 129452, 129459, 129466, 129475, 129482, 129489, + 129495, 129503, 129512, 129521, 129532, 129540, 129549, 129558, 129567, + 129576, 129583, 129590, 129599, 129611, 129621, 129628, 129635, 129645, + 129655, 129664, 129674, 129681, 129691, 129698, 129705, 129712, 129722, + 129732, 129739, 129746, 129756, 129762, 129773, 129782, 129792, 129800, + 129813, 129820, 129826, 129834, 129841, 129851, 129855, 129859, 129863, + 129867, 129871, 129875, 129879, 129888, 129892, 129899, 129903, 129907, + 129911, 129915, 129919, 129923, 129927, 129931, 129935, 129939, 129943, + 129947, 129951, 129955, 129959, 129963, 129967, 129971, 129975, 129982, + 129989, 129999, 130012, 130022, 130026, 130030, 130034, 130038, 130042, + 130046, 130050, 130054, 130058, 130062, 130066, 130073, 130080, 130091, + 130098, 130104, 130111, 130118, 130125, 130132, 130139, 130143, 130147, + 130154, 130161, 130168, 130177, 130184, 130197, 130207, 130214, 130221, + 130225, 130229, 130238, 130245, 130252, 130259, 130272, 130279, 130286, + 130296, 130306, 130315, 130322, 130329, 130336, 130343, 130350, 130357, + 130367, 130373, 130381, 130388, 130396, 130403, 130414, 130421, 130427, + 130434, 130441, 130448, 130455, 130465, 130475, 130482, 130489, 130498, + 130506, 130512, 130519, 130526, 130533, 130540, 130544, 130554, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 130009, 130014, 130019, 130024, - 130029, 130034, 130039, 130044, 130049, 130054, 130059, 130064, 130069, - 130074, 130079, 130084, 130089, 130094, 130099, 130104, 130109, 130114, - 130119, 130124, 130129, 130134, 130139, 130144, 130149, 130154, 130159, - 130164, 130169, 130174, 130179, 130184, 130189, 130194, 130199, 130204, - 130209, 130214, 130219, 130224, 130229, 130234, 130239, 130244, 130249, - 130254, 130259, 130264, 130269, 130274, 130279, 130284, 130289, 130294, - 130299, 130304, 130309, 130314, 130319, 130324, 130329, 130334, 130339, - 130344, 130349, 130354, 130359, 130364, 130369, 130374, 130379, 130384, - 130389, 130394, 130399, 130404, 130409, 130414, 130419, 130424, 130429, - 130434, 130439, 130444, 130449, 130454, 130459, 130464, 130469, 130474, - 130479, 130484, 130489, 130494, 130499, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 130504, 130508, 130512, 130516, 130520, 130524, 130528, 130532, - 130536, 130540, 130544, 130548, 130552, 130556, 130560, 130564, 130568, - 130572, 130576, 130580, 130584, 130588, 130592, 130596, 130600, 130604, - 130608, 130612, 130616, 130620, 130624, 130628, 130632, 130636, 130640, - 130644, 130648, 130652, 130656, 130660, 130664, 130668, 130672, 130676, - 130680, 130684, 130688, 130692, 130696, 130700, 130704, 130708, 130712, - 130716, 130720, 130724, 130728, 130732, 130736, 130740, 130744, 130748, - 130752, 130756, 130760, 130764, 130768, 130772, 130776, 130780, 130784, - 130788, 130792, 130796, 130800, 130804, 130808, 130812, 130816, 130820, - 130824, 130828, 130832, 130836, 130840, 130844, 130848, 130852, 130856, - 130860, 130864, 130868, 130872, 130876, 130880, 130884, 130888, 130892, - 130896, 130900, 130904, 130908, 130912, 130916, 130920, 130924, 130928, - 130932, 130936, 130940, 130944, 130948, 130952, 130956, 130960, 130964, - 130968, 130972, 130976, 130980, 130984, 130988, 130992, 130996, 131000, - 131004, 131008, 131012, 131016, 131020, 131024, 131028, 131032, 131036, - 131040, 131044, 131048, 131052, 131056, 131060, 131064, 131068, 131072, - 131076, 131080, 131084, 131088, 131092, 131096, 131100, 131104, 131108, - 131112, 131116, 131120, 131124, 131128, 131132, 131136, 131140, 131144, - 131148, 131152, 131156, 131160, 131164, 131168, 131172, 131176, 131180, - 131184, 131188, 131192, 131196, 131200, 131204, 131208, 131212, 131216, - 131220, 131224, 131228, 131232, 131236, 131240, 131244, 131248, 131252, - 131256, 131260, 131264, 131268, 131272, 131276, 131280, 131284, 131288, - 131292, 131296, 131300, 131304, 131308, 131312, 131316, 131320, 131324, - 131328, 131332, 131336, 131340, 131344, 131348, 131352, 131356, 131360, - 131364, 131368, 131372, 131376, 131380, 131384, 131388, 131392, 131396, - 131400, 131404, 131408, 131412, 131416, 131420, 131424, 131428, 131432, - 131436, 131440, 131444, 131448, 131452, 131456, 131460, 131464, 131468, - 131472, 131476, 131480, 131484, 131488, 131492, 131496, 131500, 131504, - 131508, 131512, 131516, 131520, 131524, 131528, 131532, 131536, 131540, - 131544, 131548, 131552, 131556, 131560, 131564, 131568, 131572, 131576, - 131580, 131584, 131588, 131592, 131596, 131600, 131604, 131608, 131612, - 131616, 131620, 131624, 131628, 131632, 131636, 131640, 131644, 131648, - 131652, 131656, 131660, 131664, 131668, 131672, 131676, 131680, 131684, - 131688, 131692, 131696, 131700, 131704, 131708, 131712, 131716, 131720, - 131724, 131728, 131732, 131736, 131740, 131744, 131748, 131752, 131756, - 131760, 131764, 131768, 131772, 131776, 131780, 131784, 131788, 131792, - 131796, 131800, 131804, 131808, 131812, 131816, 131820, 131824, 131828, - 131832, 131836, 131840, 131844, 131848, 131852, 131856, 131860, 131864, - 131868, 131872, 131876, 131880, 131884, 131888, 131892, 131896, 131900, - 131904, 131908, 131912, 131916, 131920, 131924, 131928, 131932, 131936, - 131940, 131944, 131948, 131952, 131956, 131960, 131964, 131968, 131972, - 131976, 131980, 131984, 131988, 131992, 131996, 132000, 132004, 132008, - 132012, 132016, 132020, 132024, 132028, 132032, 132036, 132040, 132044, - 132048, 132052, 132056, 132060, 132064, 132068, 132072, 132076, 132080, - 132084, 132088, 132092, 132096, 132100, 132104, 132108, 132112, 132116, - 132120, 132124, 132128, 132132, 132136, 132140, 132144, 132148, 132152, - 132156, 132160, 132164, 132168, 132172, 132176, 132180, 132184, 132188, - 132192, 132196, 132200, 132204, 132208, 132212, 132216, 132220, 132224, - 132228, 132232, 132236, 132240, 132244, 132248, 132252, 132256, 132260, - 132264, 132268, 132272, 132276, 132280, 132284, 132288, 132292, 132296, - 132300, 132304, 132308, 132312, 132316, 132320, 132324, 132328, 132332, - 132336, 132340, 132344, 132348, 132352, 132356, 132360, 132364, 132368, - 132372, 132376, 132380, 132384, 132388, 132392, 132396, 132400, 132404, - 132408, 132412, 132416, 132420, 132424, 132428, 132432, 132436, 132440, - 132444, 132448, 132452, 132456, 132460, 132464, 132468, 132472, 132476, - 132480, 132484, 132488, 132492, 132496, 132500, 132504, 132508, 132512, - 132516, 132520, 132524, 132528, 132532, 132536, 132540, 132544, 132548, - 132552, 132556, 132560, 132564, 132568, 132572, 132576, 132580, 132584, - 132588, 132592, 132596, 132600, 132604, 132608, 132612, 132616, 132620, - 132624, 132628, 132632, 132636, 132640, 132644, 132648, 132652, 132656, - 132660, 132664, 132668, 132672, 132676, 132680, 132684, 132688, 132692, - 132696, 132700, 132704, 132708, 132712, 132716, 132720, 132724, 132728, - 132732, 132736, 132740, 132744, 132748, 132752, 132756, 132760, 132764, - 132768, 132772, 132776, 132780, 132784, 132788, 132792, 132796, 132800, - 132804, 132808, 132812, 132816, 132820, 132824, 132828, 132832, 132836, - 132840, 132844, 132848, 132852, 132856, 132860, 132864, 132868, 132872, - 132876, 132880, 132884, 132888, 132892, 132896, 132900, 132904, 132908, - 132912, 132916, 132920, 132924, 132928, 132932, 132936, 132940, 132944, - 132948, 132952, 132956, 132960, 132964, 132968, 132972, 132976, 132980, - 132984, 132988, 132992, 132996, 133000, 133004, 133008, 133012, 133016, - 133020, 133024, 133028, 133032, 133036, 133040, 133044, 133048, 133052, - 133056, 133060, 133064, 133068, 133072, 133076, 133080, 133084, 133088, - 133092, 133096, 133100, 133104, 133108, 133112, 133116, 133120, 133124, - 133128, 133132, 133136, 133140, 133144, 133148, 133152, 133156, 133160, - 133164, 133168, 133172, 133176, 133180, 133184, 133188, 133192, 133196, - 133200, 133204, 133208, 133212, 133216, 133220, 133224, 133228, 133232, - 133236, 133240, 133244, 133248, 133252, 133256, 133260, 133264, 133268, - 133272, 133276, 133280, 133284, 133288, 133292, 133296, 133300, 133304, - 133308, 133312, 133316, 133320, 133324, 133328, 133332, 133336, 133340, - 133344, 133348, 133352, 133356, 133360, 133364, 133368, 133372, 133376, - 133380, 133384, 133388, 133392, 133396, 133400, 133404, 133408, 133412, - 133416, 133420, 133424, 133428, 133432, 133436, 133440, 133444, 133448, - 133452, 133456, 133460, 133464, 133468, 133472, 133476, 133480, 133484, - 133488, 133492, 133496, 133500, 133504, 133508, 133512, 133516, 133520, - 133524, 133528, 133532, 133536, 133540, 133544, 133548, 133552, 133556, - 133560, 133564, 133568, 133572, 133576, 133580, 133584, 133588, 133592, - 133596, 133600, 133604, 133608, 133612, 133616, 133620, 133624, 133628, - 133632, 133636, 133640, 133644, 133648, 133652, 133656, 133660, 133664, - 133668, 133672, 133676, 133680, 133684, 133688, 133692, 133696, 133700, - 133704, 133708, 133712, 133716, 133720, 133724, 133728, 133732, 133736, - 133740, 133744, 133748, 133752, 133756, 133760, 133764, 133768, 133772, - 133776, 133780, 133784, 133788, 133792, 133796, 133800, 133804, 133808, - 133812, 133816, 133820, 133824, 133828, 133832, 133836, 133840, 133844, - 133848, 133852, 133856, 133860, 133864, 133868, 133872, 133876, 133880, - 133884, 133888, 133892, 133896, 133900, 133904, 133908, 133912, 133916, - 133920, 133924, 133928, 133932, 133936, 133940, 133944, 133948, 133952, - 133956, 133960, 133964, 133968, 133972, 133976, 133980, 133984, 133988, - 133992, 133996, 134000, 134004, 134008, 134012, 134016, 134020, 134024, - 134028, 134032, 134036, 134040, 134044, 134048, 134052, 134056, 134060, - 134064, 134068, 134072, 134076, 134080, 134084, 134088, 134092, 134096, - 134100, 134104, 134108, 134112, 134116, 134120, 134124, 134128, 134132, - 134136, 134140, 134144, 134148, 134152, 134156, 134160, 134164, 134168, - 134172, 134176, 134180, 134184, 134188, 134192, 134196, 134200, 134204, - 134208, 134212, 134216, 134220, 134224, 134228, 134232, 134236, 134240, - 134244, 134248, 134252, 134256, 134260, 134264, 134268, 134272, 134276, - 134280, 134284, 134288, 134292, 134296, 134300, 134304, 134308, 134312, - 134316, 134320, 134324, 134328, 134332, 134336, 134340, 134344, 134348, - 134352, 134356, 134360, 134364, 134368, 134372, 134376, 134380, 134384, - 134388, 134392, 134396, 134400, 134404, 134408, 134412, 134416, 134420, - 134424, 134428, 134432, 134436, 134440, 134444, 134448, 134452, 134456, - 134460, 134464, 134468, 134472, 134476, 134480, 134484, 134488, 134492, - 134496, 134500, 134504, 134508, 134512, 134516, 134520, 134524, 134528, - 134532, 134536, 134540, 134544, 134548, 134552, 134556, 134560, 134564, - 134568, 134572, 134576, 134580, 134584, 134588, 134592, 134596, 134600, - 134604, 134608, 134612, 134616, 134620, 134624, 134628, 134632, 134636, - 134640, 134644, 134648, 134652, 134656, 134660, 134664, 134668, 134672, - 134676, 134680, 134684, 134688, 134692, 134696, 134700, 134704, 134708, - 134712, 134716, 134720, 134724, 134728, 134732, 134736, 134740, 134744, - 134748, 134752, 134756, 134760, 134764, 134768, 134772, 134776, 134780, - 134784, 0, 134788, 134793, 134799, 134809, 134819, 134829, 134839, - 134845, 134851, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 134857, 134861, 134865, 134869, 134873, 134877, 134881, - 134885, 134889, 134893, 134897, 134901, 134905, 134909, 134913, 134917, - 134921, 134925, 134929, 134933, 134937, 134941, 134945, 134949, 134953, - 134957, 134961, 134965, 134969, 134973, 134977, 134981, 134985, 134989, - 134993, 134997, 135001, 135005, 135009, 135013, 135017, 135021, 135025, - 135029, 135033, 135037, 135041, 135045, 135049, 135053, 135057, 135061, - 135065, 135069, 135073, 135077, 135081, 135085, 135089, 135093, 135097, - 135101, 135105, 135109, 135113, 135117, 135121, 135125, 135129, 135133, - 135137, 135141, 135145, 135149, 135153, 135157, 135161, 135165, 135169, - 135173, 135177, 135181, 135185, 135189, 135193, 135197, 135201, 135205, - 135209, 135213, 135217, 135221, 135225, 135229, 135233, 135237, 135241, - 135245, 135249, 135253, 135257, 135261, 135265, 135269, 135273, 135277, - 135281, 135285, 135289, 135293, 135297, 135301, 135305, 135309, 135313, - 135317, 135321, 135325, 135329, 135333, 135337, 135341, 135345, 135349, - 135353, 135357, 135361, 135365, 135369, 135373, 135377, 135381, 135385, - 135389, 135393, 135397, 135401, 135405, 135409, 135413, 135417, 135421, - 135425, 135429, 135433, 135437, 135441, 135445, 135449, 135453, 135457, - 135461, 135465, 135469, 135473, 135477, 135481, 135485, 135489, 135493, - 135497, 135501, 135505, 135509, 135513, 135517, 135521, 135525, 135529, - 135533, 135537, 135541, 135545, 135549, 135553, 135557, 135561, 135565, - 135569, 135573, 135577, 135581, 135585, 135589, 135593, 135597, 135601, - 135605, 135609, 135613, 135617, 135621, 135625, 135629, 135633, 135637, - 135641, 135645, 135649, 135653, 135657, 135661, 135665, 135669, 135673, - 135677, 135681, 135685, 135689, 135693, 135697, 135701, 135705, 135709, - 135713, 135717, 135721, 135725, 135729, 135733, 135737, 135741, 135745, - 135749, 135753, 135757, 135761, 135765, 135769, 135773, 135777, 135781, - 135785, 135789, 135793, 135797, 135801, 135805, 135809, 135813, 135817, - 135821, 135825, 135829, 135833, 135837, 135841, 135845, 135849, 135853, - 135857, 135861, 135865, 135869, 135873, 135877, 135881, 135885, 135889, - 135893, 135897, 135901, 135905, 135909, 135913, 135917, 135921, 135925, - 135929, 135933, 135937, 135941, 135945, 135949, 135953, 135957, 135961, - 135965, 135969, 135973, 135977, 135981, 135985, 135989, 135993, 135997, - 136001, 136005, 136009, 136013, 136017, 136021, 136025, 136029, 136033, - 136037, 136041, 136045, 136049, 136053, 136057, 136061, 136065, 136069, - 136073, 136077, 136081, 136085, 136089, 136093, 136097, 136101, 136105, - 136109, 136113, 136117, 136121, 136125, 136129, 136133, 136137, 136141, - 136145, 136149, 136153, 136157, 136161, 136165, 136169, 136173, 136177, - 136181, 136185, 136189, 136193, 136197, 136201, 136205, 136209, 136213, - 136217, 136221, 136225, 136229, 136233, 136237, 136241, 136245, 136249, - 136253, 136257, 136261, 136265, 136269, 136273, 136277, 136281, 136285, - 136289, 136293, 136297, 136301, 136305, 136309, 136313, 136317, 136321, - 136325, 136329, 136333, 136337, 136341, 136345, 136349, 136353, 136357, - 136361, 136365, 136369, 136373, 136377, 136381, 136385, 136389, 136393, - 136397, 136401, 136405, 136409, 136413, 136417, 136421, 136425, 136429, - 136433, 136437, 136441, 136445, 136449, 136453, 136457, 136461, 136465, - 136469, 136473, 136477, 136481, 136485, 136489, 136493, 136497, 136501, - 136505, 136509, 136513, 136517, 136521, 136525, 136529, 136533, 136537, - 136541, 136545, 136549, 136553, 136557, 136561, 136565, 136569, 136573, - 136577, 136581, 136585, 136589, 136599, 136603, 136607, 136611, 136615, - 136619, 136623, 136627, 136631, 136635, 136639, 136643, 136648, 136652, - 136656, 136660, 136664, 136668, 136672, 136676, 136680, 136684, 136688, - 136692, 136696, 136700, 136704, 136708, 136712, 136721, 136730, 136734, - 136738, 136742, 136746, 136750, 136754, 136758, 136762, 136766, 136770, - 136774, 136778, 136782, 136786, 136790, 136794, 136798, 136802, 136806, - 136810, 136814, 136818, 136822, 136826, 136830, 136834, 136838, 136842, - 136846, 136850, 136854, 136858, 136862, 136866, 136870, 136874, 136878, - 136882, 136886, 136890, 136894, 136898, 136902, 136906, 136910, 136914, - 136918, 136922, 136926, 136930, 136934, 136938, 136942, 136946, 136950, - 136954, 136958, 136962, 136966, 136970, 136974, 136978, 136982, 136986, - 136990, 136994, 136998, 137002, 137006, 137010, 137014, 137018, 137022, - 137026, 137030, 137034, 137038, 137042, 137046, 137050, 137054, 137058, - 137062, 137066, 137070, 137074, 137078, 137082, 137086, 137090, 137094, - 137098, 137102, 137106, 137110, 137114, 137118, 137122, 137126, 137130, - 137134, 137138, 137142, 137146, 137150, 137154, 137158, 137162, 137166, - 137170, 137174, 137178, 137182, 137186, 137190, 137194, 137198, 137202, + 0, 130564, 130569, 130574, 130579, 130584, 130589, 130594, 130599, + 130604, 130609, 130614, 130619, 130624, 130629, 130634, 130639, 130644, + 130649, 130654, 130659, 130664, 130669, 130674, 130679, 130684, 130689, + 130694, 130699, 130704, 130709, 130714, 130719, 130724, 130729, 130734, + 130739, 130744, 130749, 130754, 130759, 130764, 130769, 130774, 130779, + 130784, 130789, 130794, 130799, 130804, 130809, 130814, 130819, 130824, + 130829, 130834, 130839, 130844, 130849, 130854, 130859, 130864, 130869, + 130874, 130879, 130884, 130889, 130894, 130899, 130904, 130909, 130914, + 130919, 130924, 130929, 130934, 130939, 130944, 130949, 130954, 130959, + 130964, 130969, 130974, 130979, 130984, 130989, 130994, 130999, 131004, + 131009, 131014, 131019, 131024, 131029, 131034, 131039, 131044, 131049, + 131054, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 131059, 131063, 131067, + 131071, 131075, 131079, 131083, 131087, 131091, 131095, 131099, 131103, + 131107, 131111, 131115, 131119, 131123, 131127, 131131, 131135, 131139, + 131143, 131147, 131151, 131155, 131159, 131163, 131167, 131171, 131175, + 131179, 131183, 131187, 131191, 131195, 131199, 131203, 131207, 131211, + 131215, 131219, 131223, 131227, 131231, 131235, 131239, 131243, 131247, + 131251, 131255, 131259, 131263, 131267, 131271, 131275, 131279, 131283, + 131287, 131291, 131295, 131299, 131303, 131307, 131311, 131315, 131319, + 131323, 131327, 131331, 131335, 131339, 131343, 131347, 131351, 131355, + 131359, 131363, 131367, 131371, 131375, 131379, 131383, 131387, 131391, + 131395, 131399, 131403, 131407, 131411, 131415, 131419, 131423, 131427, + 131431, 131435, 131439, 131443, 131447, 131451, 131455, 131459, 131463, + 131467, 131471, 131475, 131479, 131483, 131487, 131491, 131495, 131499, + 131503, 131507, 131511, 131515, 131519, 131523, 131527, 131531, 131535, + 131539, 131543, 131547, 131551, 131555, 131559, 131563, 131567, 131571, + 131575, 131579, 131583, 131587, 131591, 131595, 131599, 131603, 131607, + 131611, 131615, 131619, 131623, 131627, 131631, 131635, 131639, 131643, + 131647, 131651, 131655, 131659, 131663, 131667, 131671, 131675, 131679, + 131683, 131687, 131691, 131695, 131699, 131703, 131707, 131711, 131715, + 131719, 131723, 131727, 131731, 131735, 131739, 131743, 131747, 131751, + 131755, 131759, 131763, 131767, 131771, 131775, 131779, 131783, 131787, + 131791, 131795, 131799, 131803, 131807, 131811, 131815, 131819, 131823, + 131827, 131831, 131835, 131839, 131843, 131847, 131851, 131855, 131859, + 131863, 131867, 131871, 131875, 131879, 131883, 131887, 131891, 131895, + 131899, 131903, 131907, 131911, 131915, 131919, 131923, 131927, 131931, + 131935, 131939, 131943, 131947, 131951, 131955, 131959, 131963, 131967, + 131971, 131975, 131979, 131983, 131987, 131991, 131995, 131999, 132003, + 132007, 132011, 132015, 132019, 132023, 132027, 132031, 132035, 132039, + 132043, 132047, 132051, 132055, 132059, 132063, 132067, 132071, 132075, + 132079, 132083, 132087, 132091, 132095, 132099, 132103, 132107, 132111, + 132115, 132119, 132123, 132127, 132131, 132135, 132139, 132143, 132147, + 132151, 132155, 132159, 132163, 132167, 132171, 132175, 132179, 132183, + 132187, 132191, 132195, 132199, 132203, 132207, 132211, 132215, 132219, + 132223, 132227, 132231, 132235, 132239, 132243, 132247, 132251, 132255, + 132259, 132263, 132267, 132271, 132275, 132279, 132283, 132287, 132291, + 132295, 132299, 132303, 132307, 132311, 132315, 132319, 132323, 132327, + 132331, 132335, 132339, 132343, 132347, 132351, 132355, 132359, 132363, + 132367, 132371, 132375, 132379, 132383, 132387, 132391, 132395, 132399, + 132403, 132407, 132411, 132415, 132419, 132423, 132427, 132431, 132435, + 132439, 132443, 132447, 132451, 132455, 132459, 132463, 132467, 132471, + 132475, 132479, 132483, 132487, 132491, 132495, 132499, 132503, 132507, + 132511, 132515, 132519, 132523, 132527, 132531, 132535, 132539, 132543, + 132547, 132551, 132555, 132559, 132563, 132567, 132571, 132575, 132579, + 132583, 132587, 132591, 132595, 132599, 132603, 132607, 132611, 132615, + 132619, 132623, 132627, 132631, 132635, 132639, 132643, 132647, 132651, + 132655, 132659, 132663, 132667, 132671, 132675, 132679, 132683, 132687, + 132691, 132695, 132699, 132703, 132707, 132711, 132715, 132719, 132723, + 132727, 132731, 132735, 132739, 132743, 132747, 132751, 132755, 132759, + 132763, 132767, 132771, 132775, 132779, 132783, 132787, 132791, 132795, + 132799, 132803, 132807, 132811, 132815, 132819, 132823, 132827, 132831, + 132835, 132839, 132843, 132847, 132851, 132855, 132859, 132863, 132867, + 132871, 132875, 132879, 132883, 132887, 132891, 132895, 132899, 132903, + 132907, 132911, 132915, 132919, 132923, 132927, 132931, 132935, 132939, + 132943, 132947, 132951, 132955, 132959, 132963, 132967, 132971, 132975, + 132979, 132983, 132987, 132991, 132995, 132999, 133003, 133007, 133011, + 133015, 133019, 133023, 133027, 133031, 133035, 133039, 133043, 133047, + 133051, 133055, 133059, 133063, 133067, 133071, 133075, 133079, 133083, + 133087, 133091, 133095, 133099, 133103, 133107, 133111, 133115, 133119, + 133123, 133127, 133131, 133135, 133139, 133143, 133147, 133151, 133155, + 133159, 133163, 133167, 133171, 133175, 133179, 133183, 133187, 133191, + 133195, 133199, 133203, 133207, 133211, 133215, 133219, 133223, 133227, + 133231, 133235, 133239, 133243, 133247, 133251, 133255, 133259, 133263, + 133267, 133271, 133275, 133279, 133283, 133287, 133291, 133295, 133299, + 133303, 133307, 133311, 133315, 133319, 133323, 133327, 133331, 133335, + 133339, 133343, 133347, 133351, 133355, 133359, 133363, 133367, 133371, + 133375, 133379, 133383, 133387, 133391, 133395, 133399, 133403, 133407, + 133411, 133415, 133419, 133423, 133427, 133431, 133435, 133439, 133443, + 133447, 133451, 133455, 133459, 133463, 133467, 133471, 133475, 133479, + 133483, 133487, 133491, 133495, 133499, 133503, 133507, 133511, 133515, + 133519, 133523, 133527, 133531, 133535, 133539, 133543, 133547, 133551, + 133555, 133559, 133563, 133567, 133571, 133575, 133579, 133583, 133587, + 133591, 133595, 133599, 133603, 133607, 133611, 133615, 133619, 133623, + 133627, 133631, 133635, 133639, 133643, 133647, 133651, 133655, 133659, + 133663, 133667, 133671, 133675, 133679, 133683, 133687, 133691, 133695, + 133699, 133703, 133707, 133711, 133715, 133719, 133723, 133727, 133731, + 133735, 133739, 133743, 133747, 133751, 133755, 133759, 133763, 133767, + 133771, 133775, 133779, 133783, 133787, 133791, 133795, 133799, 133803, + 133807, 133811, 133815, 133819, 133823, 133827, 133831, 133835, 133839, + 133843, 133847, 133851, 133855, 133859, 133863, 133867, 133871, 133875, + 133879, 133883, 133887, 133891, 133895, 133899, 133903, 133907, 133911, + 133915, 133919, 133923, 133927, 133931, 133935, 133939, 133943, 133947, + 133951, 133955, 133959, 133963, 133967, 133971, 133975, 133979, 133983, + 133987, 133991, 133995, 133999, 134003, 134007, 134011, 134015, 134019, + 134023, 134027, 134031, 134035, 134039, 134043, 134047, 134051, 134055, + 134059, 134063, 134067, 134071, 134075, 134079, 134083, 134087, 134091, + 134095, 134099, 134103, 134107, 134111, 134115, 134119, 134123, 134127, + 134131, 134135, 134139, 134143, 134147, 134151, 134155, 134159, 134163, + 134167, 134171, 134175, 134179, 134183, 134187, 134191, 134195, 134199, + 134203, 134207, 134211, 134215, 134219, 134223, 134227, 134231, 134235, + 134239, 134243, 134247, 134251, 134255, 134259, 134263, 134267, 134271, + 134275, 134279, 134283, 134287, 134291, 134295, 134299, 134303, 134307, + 134311, 134315, 134319, 134323, 134327, 134331, 134335, 134339, 134343, + 134347, 134351, 134355, 134359, 134363, 134367, 134371, 134375, 134379, + 134383, 134387, 134391, 134395, 134399, 134403, 134407, 134411, 134415, + 134419, 134423, 134427, 134431, 134435, 134439, 134443, 134447, 134451, + 134455, 134459, 134463, 134467, 134471, 134475, 134479, 134483, 134487, + 134491, 134495, 134499, 134503, 134507, 134511, 134515, 134519, 134523, + 134527, 134531, 134535, 134539, 134543, 134547, 134551, 134555, 134559, + 134563, 134567, 134571, 134575, 134579, 134583, 134587, 134591, 134595, + 134599, 134603, 134607, 134611, 134615, 134619, 134623, 134627, 134631, + 134635, 134639, 134643, 134647, 134651, 134655, 134659, 134663, 134667, + 134671, 134675, 134679, 134683, 134687, 134691, 134695, 134699, 134703, + 134707, 134711, 134715, 134719, 134723, 134727, 134731, 134735, 134739, + 134743, 134747, 134751, 134755, 134759, 134763, 134767, 134771, 134775, + 134779, 134783, 134787, 134791, 134795, 134799, 134803, 134807, 134811, + 134815, 134819, 134823, 134827, 134831, 134835, 134839, 134843, 134847, + 134851, 134855, 134859, 134863, 134867, 134871, 134875, 134879, 134883, + 134887, 134891, 134895, 134899, 134903, 134907, 134911, 134915, 134919, + 134923, 134927, 134931, 134935, 134939, 134943, 134947, 134951, 134955, + 134959, 134963, 134967, 134971, 134975, 134979, 134983, 134987, 134991, + 134995, 134999, 135003, 135007, 135011, 135015, 135019, 135023, 135027, + 135031, 135035, 135039, 135043, 135047, 135051, 135055, 135059, 135063, + 135067, 135071, 135075, 135079, 135083, 135087, 135091, 135095, 135099, + 135103, 135107, 135111, 135115, 135119, 135123, 135127, 135131, 135135, + 135139, 135143, 135147, 135151, 135155, 135159, 135163, 135167, 135171, + 135175, 135179, 135183, 135187, 135191, 135195, 135199, 135203, 135207, + 135211, 135215, 135219, 135223, 135227, 135231, 135235, 135239, 135243, + 135247, 135251, 135255, 135259, 135263, 135267, 135271, 135275, 135279, + 135283, 135287, 135291, 135295, 135299, 135303, 135307, 135311, 135315, + 135319, 135323, 135327, 135331, 135335, 135339, 135343, 135347, 135352, + 135358, 135368, 135378, 135388, 135398, 135404, 135410, 135416, 135424, + 135432, 135440, 135446, 135452, 135460, 135468, 135474, 135480, 135485, + 135490, 135496, 135503, 135510, 135521, 135532, 135541, 135552, 135561, + 135577, 135589, 135600, 135616, 135625, 135637, 135646, 135658, 135670, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 135675, 135679, + 135683, 135687, 135691, 135695, 135699, 135703, 135707, 135711, 135715, + 135719, 135723, 135727, 135731, 135735, 135739, 135743, 135747, 135751, + 135755, 135759, 135763, 135767, 135771, 135775, 135779, 135783, 135787, + 135791, 135795, 135799, 135803, 135807, 135811, 135815, 135819, 135823, + 135827, 135831, 135835, 135839, 135843, 135847, 135851, 135855, 135859, + 135863, 135867, 135871, 135875, 135879, 135883, 135887, 135891, 135895, + 135899, 135903, 135907, 135911, 135915, 135919, 135923, 135927, 135931, + 135935, 135939, 135943, 135947, 135951, 135955, 135959, 135963, 135967, + 135971, 135975, 135979, 135983, 135987, 135991, 135995, 135999, 136003, + 136007, 136011, 136015, 136019, 136023, 136027, 136031, 136035, 136039, + 136043, 136047, 136051, 136055, 136059, 136063, 136067, 136071, 136075, + 136079, 136083, 136087, 136091, 136095, 136099, 136103, 136107, 136111, + 136115, 136119, 136123, 136127, 136131, 136135, 136139, 136143, 136147, + 136151, 136155, 136159, 136163, 136167, 136171, 136175, 136179, 136183, + 136187, 136191, 136195, 136199, 136203, 136207, 136211, 136215, 136219, + 136223, 136227, 136231, 136235, 136239, 136243, 136247, 136251, 136255, + 136259, 136263, 136267, 136271, 136275, 136279, 136283, 136287, 136291, + 136295, 136299, 136303, 136307, 136311, 136315, 136319, 136323, 136327, + 136331, 136335, 136339, 136343, 136347, 136351, 136355, 136359, 136363, + 136367, 136371, 136375, 136379, 136383, 136387, 136391, 136395, 136399, + 136403, 136407, 136411, 136415, 136419, 136423, 136427, 136431, 136435, + 136439, 136443, 136447, 136451, 136455, 136459, 136463, 136467, 136471, + 136475, 136479, 136483, 136487, 136491, 136495, 136499, 136503, 136507, + 136511, 136515, 136519, 136523, 136527, 136531, 136535, 136539, 136543, + 136547, 136551, 136555, 136559, 136563, 136567, 136571, 136575, 136579, + 136583, 136587, 136591, 136595, 136599, 136603, 136607, 136611, 136615, + 136619, 136623, 136627, 136631, 136635, 136639, 136643, 136647, 136651, + 136655, 136659, 136663, 136667, 136671, 136675, 136679, 136683, 136687, + 136691, 136695, 136699, 136703, 136707, 136711, 136715, 136719, 136723, + 136727, 136731, 136735, 136739, 136743, 136747, 136751, 136755, 136759, + 136763, 136767, 136771, 136775, 136779, 136783, 136787, 136791, 136795, + 136799, 136803, 136807, 136811, 136815, 136819, 136823, 136827, 136831, + 136835, 136839, 136843, 136847, 136851, 136855, 136859, 136863, 136867, + 136871, 136875, 136879, 136883, 136887, 136891, 136895, 136899, 136903, + 136907, 136911, 136915, 136919, 136923, 136927, 136931, 136935, 136939, + 136943, 136947, 136951, 136955, 136959, 136963, 136967, 136971, 136975, + 136979, 136983, 136987, 136991, 136995, 136999, 137003, 137007, 137011, + 137015, 137019, 137023, 137027, 137031, 137035, 137039, 137043, 137047, + 137051, 137055, 137059, 137063, 137067, 137071, 137075, 137079, 137083, + 137087, 137091, 137095, 137099, 137103, 137107, 137111, 137115, 137119, + 137123, 137127, 137131, 137135, 137139, 137143, 137147, 137151, 137155, + 137159, 137163, 137167, 137171, 137175, 137179, 137183, 137187, 137191, + 137195, 137199, 137203, 137207, 137211, 137215, 137219, 137223, 137227, + 137231, 137235, 137239, 137243, 137247, 137251, 137255, 137259, 137263, + 137267, 137271, 137275, 137279, 137283, 137287, 137291, 137295, 137299, + 137303, 137307, 137311, 137315, 137319, 137323, 137327, 137331, 137335, + 137339, 137343, 137347, 137351, 137355, 137359, 137363, 137367, 137371, + 137375, 137379, 137383, 137387, 137391, 137395, 137399, 137403, 137407, + 137417, 137421, 137425, 137429, 137433, 137437, 137441, 137445, 137449, + 137453, 137457, 137461, 137466, 137470, 137474, 137478, 137482, 137486, + 137490, 137494, 137498, 137502, 137506, 137510, 137514, 137518, 137522, + 137526, 137530, 137539, 137548, 137552, 137556, 137560, 137564, 137568, + 137572, 137576, 137580, 137584, 137588, 137592, 137596, 137600, 137604, + 137608, 137612, 137616, 137620, 137624, 137628, 137632, 137636, 137640, + 137644, 137648, 137652, 137656, 137660, 137664, 137668, 137672, 137676, + 137680, 137684, 137688, 137692, 137696, 137700, 137704, 137708, 137712, + 137716, 137720, 137724, 137728, 137732, 137736, 137740, 137744, 137748, + 137752, 137756, 137760, 137764, 137768, 137772, 137776, 137780, 137784, + 137788, 137792, 137796, 137800, 137804, 137808, 137812, 137816, 137820, + 137824, 137828, 137832, 137836, 137840, 137844, 137848, 137852, 137856, + 137860, 137864, 137868, 137872, 137876, 137880, 137884, 137888, 137892, + 137896, 137900, 137904, 137908, 137912, 137916, 137920, 137924, 137928, + 137932, 137936, 137940, 137944, 137948, 137952, 137956, 137960, 137964, + 137968, 137972, 137976, 137980, 137984, 137988, 137992, 137996, 138000, + 138004, 138008, 138012, 138016, 138020, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 137206, 137214, 137222, 137232, 137242, - 137250, 137256, 137264, 137272, 137282, 137294, 137306, 137312, 137320, - 137326, 137332, 137338, 137344, 137350, 137356, 137362, 137368, 137374, - 137380, 137386, 137394, 137402, 137408, 137414, 137420, 137426, 137434, - 137442, 137451, 137457, 137465, 137471, 137477, 137483, 137489, 137495, - 137503, 137511, 137517, 137523, 137529, 137535, 137541, 137547, 137553, - 137559, 137565, 137571, 137577, 137583, 137589, 137595, 137601, 137607, - 137613, 137619, 137625, 137633, 137639, 137645, 137655, 137663, 137669, - 137675, 137681, 137687, 137693, 137699, 137705, 137711, 137717, 137723, - 137729, 137735, 137741, 137747, 137753, 137759, 137765, 137771, 137777, - 137783, 137789, 137795, 137803, 137809, 137817, 137825, 137833, 137839, - 137845, 137851, 137857, 137863, 137871, 137881, 137889, 137897, 137903, - 137909, 137917, 137925, 137931, 137939, 137947, 137955, 137961, 137967, - 137973, 137979, 137985, 137991, 137999, 138007, 138013, 138019, 138025, - 138031, 138037, 138045, 138051, 138057, 138063, 138069, 138075, 138081, - 138089, 138095, 138101, 138107, 138113, 138121, 138129, 138135, 138141, - 138147, 138152, 138158, 138164, 138172, 138178, 138184, 138190, 138196, - 138202, 138208, 138214, 138220, 138226, 138236, 138244, 138250, 138256, - 138262, 138270, 138276, 138282, 138288, 138296, 138302, 138308, 138314, - 138320, 138326, 138332, 138338, 138344, 138350, 138356, 138362, 138370, - 138376, 138384, 138390, 138396, 138404, 138410, 138416, 138422, 138428, - 138434, 138440, 138446, 138452, 138458, 138464, 138470, 138476, 138482, - 138488, 138494, 138500, 138506, 138512, 138518, 138526, 138532, 138538, - 138544, 138550, 138556, 138562, 138568, 138574, 138580, 138586, 138592, - 138598, 138604, 138612, 138618, 138624, 138632, 138638, 138644, 138650, - 138656, 138662, 138668, 138674, 138680, 138686, 138692, 138700, 138706, - 138712, 138718, 138724, 138730, 138738, 138746, 138752, 138758, 138764, - 138770, 138776, 138782, 138787, 138792, 138797, 138802, 138807, 138812, - 138817, 138822, 138827, 138832, 138837, 138842, 138847, 138852, 138857, - 138862, 138867, 138872, 138877, 138882, 138887, 138892, 138897, 138902, - 138907, 138912, 138917, 138922, 138927, 138932, 138939, 138944, 138949, - 138954, 138959, 138964, 138969, 138974, 138979, 138984, 138989, 138994, - 138999, 139004, 139009, 139014, 139019, 139024, 139029, 139034, 139039, - 139044, 139049, 139054, 139059, 139064, 139069, 139074, 139079, 139084, - 139089, 139094, 139099, 139104, 139109, 139114, 139119, 139124, 139129, - 139134, 139139, 139144, 139149, 139154, 139159, 139164, 139169, 139174, - 139179, 139184, 139189, 139194, 139199, 139204, 139209, 139214, 139219, - 139224, 139229, 139236, 139241, 139246, 139251, 139256, 139261, 139266, - 139271, 139276, 139281, 139286, 139291, 139296, 139301, 139306, 139311, - 139316, 139321, 139326, 139331, 139336, 139341, 139348, 139353, 139358, - 139364, 139369, 139374, 139379, 139384, 139389, 139394, 139399, 139404, - 139409, 139414, 139419, 139424, 139429, 139434, 139439, 139444, 139449, - 139454, 139459, 139464, 139469, 139474, 139479, 139484, 139489, 139494, - 139499, 139504, 139509, 139514, 139519, 139524, 139529, 139534, 139539, - 139544, 139549, 139554, 139559, 139564, 139569, 139574, 139579, 139586, - 139591, 139596, 139603, 139610, 139615, 139620, 139625, 139630, 139635, - 139640, 139645, 139650, 139655, 139660, 139665, 139670, 139675, 139680, - 139685, 139690, 139695, 139700, 139705, 139710, 139715, 139720, 139725, - 139730, 139735, 139742, 139747, 139752, 139757, 139762, 139767, 139772, - 139777, 139782, 139787, 139792, 139797, 139802, 139807, 139812, 139817, - 139822, 139827, 139832, 139839, 139844, 139849, 139854, 139859, 139864, - 139869, 139874, 139880, 139885, 139890, 139895, 139900, 139905, 139910, - 139915, 139920, 139927, 139934, 139939, 139944, 139948, 139953, 139957, - 139961, 139966, 139973, 139978, 139983, 139992, 139997, 140002, 140007, - 140012, 140019, 140026, 140031, 140036, 140041, 140046, 140053, 140058, - 140063, 140068, 140073, 140078, 140083, 140088, 140093, 140098, 140103, - 140108, 140113, 140120, 140124, 140129, 140134, 140139, 140144, 140148, - 140153, 140158, 140163, 140168, 140173, 140178, 140183, 140188, 140193, - 140199, 140205, 140211, 140217, 140223, 140228, 140234, 140240, 140246, - 140252, 140258, 140264, 140270, 140276, 140282, 140288, 140294, 140300, - 140306, 140312, 140318, 140324, 140330, 140336, 140341, 140347, 140353, - 140359, 140365, 140371, 140377, 140383, 140389, 140395, 140401, 140407, - 140413, 140419, 140425, 140431, 140437, 140443, 140449, 140455, 140461, - 140466, 140472, 140478, 140484, 140490, 140496, 0, 0, 0, 0, 0, 0, 0, - 140502, 140507, 140512, 140517, 140522, 140527, 140532, 140536, 140541, - 140546, 140551, 140556, 140561, 140566, 140571, 140576, 140581, 140585, - 140590, 140594, 140599, 140604, 140609, 140614, 140619, 140623, 140628, - 140633, 140637, 140642, 140647, 0, 140652, 140657, 140661, 140665, - 140669, 140673, 140677, 140681, 140685, 140689, 0, 0, 0, 0, 140693, - 140697, 140702, 140707, 140712, 140717, 140722, 140727, 140732, 140737, - 140742, 140747, 140752, 140757, 140762, 140767, 140772, 140777, 140782, - 140787, 140792, 140797, 140802, 140807, 140812, 140817, 140822, 140827, - 140832, 140837, 140842, 140847, 140852, 140857, 140862, 140868, 140874, - 140881, 140888, 140893, 140898, 140903, 140908, 140913, 140918, 140923, - 140928, 140933, 140938, 140943, 140948, 140952, 140957, 140962, 140967, - 140971, 140975, 140980, 140984, 140989, 140994, 140999, 141003, 141007, - 141011, 141015, 141020, 141025, 141030, 141034, 141039, 141044, 141049, - 141054, 141059, 141064, 141069, 141074, 141079, 141084, 141089, 0, - 141094, 141099, 141103, 141107, 141111, 141115, 141119, 141123, 141127, - 141131, 0, 0, 0, 0, 0, 0, 141135, 141142, 141148, 141155, 141162, 141169, - 141176, 141183, 141190, 141197, 141204, 141211, 141218, 141225, 141232, - 141239, 141246, 141253, 141259, 141266, 141273, 141280, 141286, 141293, - 141299, 141305, 141312, 141318, 141325, 141331, 0, 0, 141337, 141345, - 141353, 141362, 141371, 141380, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 141388, - 141393, 141398, 141403, 141408, 141413, 141418, 141423, 141428, 141433, - 141438, 141443, 141448, 141453, 141458, 141463, 141468, 141473, 141478, - 141483, 141488, 141493, 141498, 141503, 141508, 141513, 141518, 141523, - 141528, 141533, 141538, 141543, 141548, 141553, 141558, 141563, 141568, - 141573, 141578, 141583, 141588, 141593, 141598, 141603, 141608, 141613, - 141618, 141623, 141628, 141635, 141642, 141649, 141656, 141663, 141670, - 141677, 141684, 141693, 141700, 141707, 141714, 141721, 141728, 141735, - 141742, 141749, 141756, 141763, 141770, 141775, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 141784, 141789, 141793, 141797, 141801, 141805, 141809, 141813, - 141817, 141821, 0, 141825, 141830, 141835, 141842, 141847, 141854, - 141861, 0, 141866, 141873, 141878, 141883, 141890, 141897, 141902, - 141907, 141912, 141917, 141922, 141929, 141936, 141941, 141946, 141951, - 141964, 141973, 141980, 141989, 141998, 0, 0, 0, 0, 0, 142007, 142014, - 142021, 142028, 142035, 142042, 142049, 142056, 142063, 142070, 142077, - 142084, 142091, 142098, 142105, 142112, 142119, 142126, 142133, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 138024, + 138032, 138040, 138050, 138060, 138068, 138074, 138082, 138090, 138100, + 138112, 138124, 138130, 138138, 138144, 138150, 138156, 138162, 138168, + 138174, 138180, 138186, 138192, 138198, 138204, 138212, 138220, 138226, + 138232, 138238, 138244, 138252, 138260, 138269, 138275, 138283, 138289, + 138295, 138301, 138307, 138313, 138321, 138329, 138335, 138341, 138347, + 138353, 138359, 138365, 138371, 138377, 138383, 138389, 138395, 138401, + 138407, 138413, 138419, 138425, 138431, 138437, 138443, 138451, 138457, + 138463, 138473, 138481, 138487, 138493, 138499, 138505, 138511, 138517, + 138523, 138529, 138535, 138541, 138547, 138553, 138559, 138565, 138571, + 138577, 138583, 138589, 138595, 138601, 138607, 138613, 138621, 138627, + 138635, 138643, 138651, 138657, 138663, 138669, 138675, 138681, 138689, + 138699, 138707, 138715, 138721, 138727, 138735, 138743, 138749, 138757, + 138765, 138773, 138779, 138785, 138791, 138797, 138803, 138809, 138817, + 138825, 138831, 138837, 138843, 138849, 138855, 138863, 138869, 138875, + 138881, 138887, 138893, 138899, 138907, 138913, 138919, 138925, 138931, + 138939, 138947, 138953, 138959, 138965, 138970, 138976, 138982, 138990, + 138996, 139002, 139008, 139014, 139020, 139026, 139032, 139038, 139044, + 139054, 139062, 139068, 139074, 139080, 139088, 139094, 139100, 139106, + 139114, 139120, 139126, 139132, 139138, 139144, 139150, 139156, 139162, + 139168, 139174, 139180, 139188, 139194, 139202, 139208, 139214, 139222, + 139228, 139234, 139240, 139246, 139252, 139258, 139264, 139270, 139276, + 139282, 139288, 139294, 139300, 139306, 139312, 139318, 139324, 139330, + 139336, 139344, 139350, 139356, 139362, 139368, 139374, 139380, 139386, + 139392, 139398, 139404, 139410, 139416, 139422, 139430, 139436, 139442, + 139450, 139456, 139462, 139468, 139474, 139480, 139486, 139492, 139498, + 139504, 139510, 139518, 139524, 139530, 139536, 139542, 139548, 139556, + 139564, 139570, 139576, 139582, 139588, 139594, 139600, 139605, 139610, + 139615, 139620, 139625, 139630, 139635, 139640, 139645, 139650, 139655, + 139660, 139665, 139670, 139675, 139680, 139685, 139690, 139695, 139700, + 139705, 139710, 139715, 139720, 139725, 139730, 139735, 139740, 139745, + 139750, 139757, 139762, 139767, 139772, 139777, 139782, 139787, 139792, + 139797, 139802, 139807, 139812, 139817, 139822, 139827, 139832, 139837, + 139842, 139847, 139852, 139857, 139862, 139867, 139872, 139877, 139882, + 139887, 139892, 139897, 139902, 139907, 139912, 139917, 139922, 139927, + 139932, 139937, 139942, 139947, 139952, 139957, 139962, 139967, 139972, + 139977, 139982, 139987, 139992, 139997, 140002, 140007, 140012, 140017, + 140022, 140027, 140032, 140037, 140042, 140047, 140054, 140059, 140064, + 140069, 140074, 140079, 140084, 140089, 140094, 140099, 140104, 140109, + 140114, 140119, 140124, 140129, 140134, 140139, 140144, 140149, 140154, + 140159, 140166, 140171, 140176, 140182, 140187, 140192, 140197, 140202, + 140207, 140212, 140217, 140222, 140227, 140232, 140237, 140242, 140247, + 140252, 140257, 140262, 140267, 140272, 140277, 140282, 140287, 140292, + 140297, 140302, 140307, 140312, 140317, 140322, 140327, 140332, 140337, + 140342, 140347, 140352, 140357, 140362, 140367, 140372, 140377, 140382, + 140387, 140392, 140397, 140404, 140409, 140414, 140421, 140428, 140433, + 140438, 140443, 140448, 140453, 140458, 140463, 140468, 140473, 140478, + 140483, 140488, 140493, 140498, 140503, 140508, 140513, 140518, 140523, + 140528, 140533, 140538, 140543, 140548, 140553, 140560, 140565, 140570, + 140575, 140580, 140585, 140590, 140595, 140600, 140605, 140610, 140615, + 140620, 140625, 140630, 140635, 140640, 140645, 140650, 140657, 140662, + 140667, 140672, 140677, 140682, 140687, 140692, 140698, 140703, 140708, + 140713, 140718, 140723, 140728, 140733, 140738, 140745, 140752, 140757, + 140762, 140766, 140771, 140775, 140779, 140784, 140791, 140796, 140801, + 140810, 140815, 140820, 140825, 140830, 140837, 140844, 140849, 140854, + 140859, 140864, 140871, 140876, 140881, 140886, 140891, 140896, 140901, + 140906, 140911, 140916, 140921, 140926, 140931, 140938, 140942, 140947, + 140952, 140957, 140962, 140966, 140971, 140976, 140981, 140986, 140991, + 140996, 141001, 141006, 141011, 141017, 141023, 141029, 141035, 141041, + 141046, 141052, 141058, 141064, 141070, 141076, 141082, 141088, 141094, + 141100, 141106, 141112, 141118, 141124, 141130, 141136, 141142, 141148, + 141154, 141159, 141165, 141171, 141177, 141183, 141189, 141195, 141201, + 141207, 141213, 141219, 141225, 141231, 141237, 141243, 141249, 141255, + 141261, 141267, 141273, 141279, 141284, 141290, 141296, 141302, 141308, + 141314, 0, 0, 0, 0, 0, 0, 0, 141320, 141325, 141330, 141335, 141340, + 141345, 141350, 141354, 141359, 141364, 141369, 141374, 141379, 141384, + 141389, 141394, 141399, 141403, 141408, 141412, 141417, 141422, 141427, + 141432, 141437, 141441, 141446, 141451, 141455, 141460, 141465, 0, + 141470, 141475, 141479, 141483, 141487, 141491, 141495, 141499, 141503, + 141507, 0, 0, 0, 0, 141511, 141515, 141520, 141525, 141530, 141535, + 141540, 141545, 141550, 141555, 141560, 141565, 141570, 141575, 141580, + 141585, 141590, 141595, 141600, 141605, 141610, 141615, 141620, 141625, + 141630, 141635, 141640, 141645, 141650, 141655, 141660, 141665, 141670, + 141675, 141680, 141686, 141692, 141699, 141706, 141711, 141716, 141721, + 141726, 141731, 141736, 141741, 141746, 141751, 141756, 141761, 141766, + 141770, 141775, 141780, 141785, 141789, 141793, 141798, 141802, 141807, + 141812, 141817, 141821, 141825, 141829, 141833, 141838, 141843, 141848, + 141852, 141857, 141862, 141867, 141872, 141877, 141882, 141887, 141892, + 141897, 141902, 141907, 0, 141912, 141917, 141921, 141925, 141929, + 141933, 141937, 141941, 141945, 141949, 0, 0, 0, 0, 0, 0, 141953, 141960, + 141966, 141973, 141980, 141987, 141994, 142001, 142008, 142015, 142022, + 142029, 142036, 142043, 142050, 142057, 142064, 142071, 142077, 142084, + 142091, 142098, 142104, 142111, 142117, 142123, 142130, 142136, 142143, + 142149, 0, 0, 142155, 142163, 142171, 142180, 142189, 142198, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 142206, 142211, 142216, 142221, 142226, 142231, 142236, + 142241, 142246, 142251, 142256, 142261, 142266, 142271, 142276, 142281, + 142286, 142291, 142296, 142301, 142306, 142311, 142316, 142321, 142326, + 142331, 142336, 142341, 142346, 142351, 142356, 142361, 142366, 142371, + 142376, 142381, 142386, 142391, 142396, 142401, 142406, 142411, 142416, + 142421, 142426, 142431, 142436, 142441, 142446, 142453, 142460, 142467, + 142474, 142481, 142488, 142495, 142502, 142511, 142518, 142525, 142532, + 142539, 142546, 142553, 142560, 142567, 142574, 142581, 142588, 142593, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 142602, 142607, 142611, 142615, 142619, + 142623, 142627, 142631, 142635, 142639, 0, 142643, 142648, 142653, + 142660, 142665, 142672, 142679, 0, 142684, 142691, 142696, 142701, + 142708, 142715, 142720, 142725, 142730, 142735, 142740, 142747, 142754, + 142759, 142764, 142769, 142782, 142791, 142798, 142807, 142816, 0, 0, 0, + 0, 0, 142825, 142832, 142839, 142846, 142853, 142860, 142867, 142874, + 142881, 142888, 142895, 142902, 142909, 142916, 142923, 142930, 142937, + 142944, 142951, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 142958, 142964, 142970, 142976, + 142982, 142988, 142994, 143000, 143006, 143012, 143018, 143024, 143029, + 143035, 143040, 143046, 143051, 143057, 143063, 143068, 143074, 143079, + 143085, 143091, 143097, 143103, 143109, 143115, 143121, 143126, 143131, + 143137, 143143, 143149, 143155, 143161, 143167, 143173, 143179, 143185, + 143191, 143197, 143203, 143209, 143214, 143220, 143225, 143231, 143236, + 143242, 143248, 143253, 143259, 143264, 143270, 143276, 143282, 143288, + 143294, 143300, 143306, 143311, 143316, 143322, 143328, 143333, 143337, + 143341, 143345, 143349, 143353, 143357, 143361, 143365, 143369, 143374, + 143379, 143384, 143389, 143394, 143399, 143404, 143409, 143414, 143419, + 143426, 143433, 143440, 143444, 143450, 143455, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 142140, 142146, 142152, 142158, 142164, 142170, 142176, - 142182, 142188, 142194, 142200, 142206, 142211, 142217, 142222, 142228, - 142233, 142239, 142245, 142250, 142256, 142261, 142267, 142273, 142279, - 142285, 142291, 142297, 142303, 142308, 142313, 142319, 142325, 142331, - 142337, 142343, 142349, 142355, 142361, 142367, 142373, 142379, 142385, - 142391, 142396, 142402, 142407, 142413, 142418, 142424, 142430, 142435, - 142441, 142446, 142452, 142458, 142464, 142470, 142476, 142482, 142488, - 142493, 142498, 142504, 142510, 142515, 142519, 142523, 142527, 142531, - 142535, 142539, 142543, 142547, 142551, 142556, 142561, 142566, 142571, - 142576, 142581, 142586, 142591, 142596, 142601, 142608, 142615, 142622, - 142626, 142632, 142637, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 143461, + 143464, 143468, 143472, 143476, 143479, 143483, 143488, 143492, 143496, + 143500, 143504, 143508, 143513, 143518, 143522, 143526, 143529, 143533, + 143538, 143543, 143547, 143551, 143554, 143558, 143562, 143566, 143570, + 143574, 143578, 143582, 143585, 143589, 143593, 143597, 143601, 143605, + 143609, 143615, 143618, 143622, 143626, 143630, 143634, 143638, 143642, + 143646, 143650, 143654, 143659, 143664, 143670, 143674, 143678, 143682, + 143686, 143690, 143694, 143699, 143702, 143706, 143710, 143714, 143718, + 143724, 143728, 143732, 143736, 143740, 143744, 143748, 143752, 143756, + 143760, 143764, 0, 0, 0, 0, 143768, 143773, 143777, 143781, 143787, + 143793, 143797, 143802, 143807, 143812, 143817, 143821, 143826, 143831, + 143836, 143840, 143845, 143850, 143855, 143859, 143864, 143869, 143874, + 143879, 143884, 143889, 143894, 143899, 143903, 143908, 143913, 143918, + 143923, 143928, 143933, 143938, 143943, 143948, 143953, 143958, 143965, + 143970, 143977, 143982, 143987, 143992, 143997, 144002, 144007, 144012, + 144017, 144022, 144027, 144032, 144037, 144042, 144047, 0, 0, 0, 0, 0, 0, + 0, 144052, 144055, 144060, 144063, 144066, 144070, 144074, 144078, + 144082, 144086, 144090, 144094, 144100, 144106, 144112, 144118, 144124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 142643, 142646, 142650, 142654, - 142658, 142661, 142665, 142670, 142674, 142678, 142682, 142686, 142690, - 142695, 142700, 142704, 142708, 142711, 142715, 142720, 142725, 142729, - 142733, 142736, 142740, 142744, 142748, 142752, 142756, 142760, 142764, - 142767, 142771, 142775, 142779, 142783, 142787, 142791, 142797, 142800, - 142804, 142808, 142812, 142816, 142820, 142824, 142828, 142832, 142836, - 142841, 142846, 142852, 142856, 142860, 142864, 142868, 142872, 142876, - 142881, 142884, 142888, 142892, 142896, 142900, 142906, 142910, 142914, - 142918, 142922, 142926, 142930, 142934, 142938, 142942, 142946, 0, 0, 0, - 0, 142950, 142955, 142959, 142963, 142969, 142975, 142979, 142984, - 142989, 142994, 142999, 143003, 143008, 143013, 143018, 143022, 143027, - 143032, 143037, 143041, 143046, 143051, 143056, 143061, 143066, 143071, - 143076, 143081, 143085, 143090, 143095, 143100, 143105, 143110, 143115, - 143120, 143125, 143130, 143135, 143140, 143147, 143152, 143159, 143164, - 143169, 143174, 143179, 143184, 143189, 143194, 143199, 143204, 143209, - 143214, 143219, 143224, 143229, 0, 0, 0, 0, 0, 0, 0, 143234, 143237, - 143242, 143245, 143248, 143252, 143256, 143260, 143264, 143268, 143272, - 143276, 143282, 143288, 143294, 143300, 143306, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 144130, 144134, 144138, + 144144, 144150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 144155, 144164, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 144173, 144176, 144179, 144182, 144185, + 144188, 144191, 144194, 144197, 144200, 144203, 144206, 144209, 144212, + 144215, 144218, 144221, 144224, 144227, 144230, 144233, 144236, 144239, + 144242, 144245, 144248, 144251, 144254, 144257, 144260, 144263, 144266, + 144269, 144272, 144275, 144278, 144281, 144284, 144287, 144290, 144293, + 144296, 144299, 144302, 144305, 144308, 144311, 144314, 144317, 144320, + 144323, 144326, 144329, 144332, 144335, 144338, 144341, 144344, 144347, + 144350, 144353, 144356, 144359, 144362, 144365, 144368, 144371, 144374, + 144377, 144380, 144383, 144386, 144389, 144392, 144395, 144398, 144401, + 144404, 144407, 144410, 144413, 144416, 144419, 144422, 144425, 144428, + 144431, 144434, 144437, 144440, 144443, 144446, 144449, 144452, 144455, + 144458, 144461, 144464, 144467, 144470, 144473, 144476, 144479, 144482, + 144485, 144488, 144491, 144494, 144497, 144500, 144503, 144506, 144509, + 144512, 144515, 144518, 144521, 144524, 144527, 144530, 144533, 144536, + 144539, 144542, 144545, 144548, 144551, 144554, 144557, 144560, 144563, + 144566, 144569, 144572, 144575, 144578, 144581, 144584, 144587, 144590, + 144593, 144596, 144599, 144602, 144605, 144608, 144611, 144614, 144617, + 144620, 144623, 144626, 144629, 144632, 144635, 144638, 144641, 144644, + 144647, 144650, 144653, 144656, 144659, 144662, 144665, 144668, 144671, + 144674, 144677, 144680, 144683, 144686, 144689, 144692, 144695, 144698, + 144701, 144704, 144707, 144710, 144713, 144716, 144719, 144722, 144725, + 144728, 144731, 144734, 144737, 144740, 144743, 144746, 144749, 144752, + 144755, 144758, 144761, 144764, 144767, 144770, 144773, 144776, 144779, + 144782, 144785, 144788, 144791, 144794, 144797, 144800, 144803, 144806, + 144809, 144812, 144815, 144818, 144821, 144824, 144827, 144830, 144833, + 144836, 144839, 144842, 144845, 144848, 144851, 144854, 144857, 144860, + 144863, 144866, 144869, 144872, 144875, 144878, 144881, 144884, 144887, + 144890, 144893, 144896, 144899, 144902, 144905, 144908, 144911, 144914, + 144917, 144920, 144923, 144926, 144929, 144932, 144935, 144938, 144941, + 144944, 144947, 144950, 144953, 144956, 144959, 144962, 144965, 144968, + 144971, 144974, 144977, 144980, 144983, 144986, 144989, 144992, 144995, + 144998, 145001, 145004, 145007, 145010, 145013, 145016, 145019, 145022, + 145025, 145028, 145031, 145034, 145037, 145040, 145043, 145046, 145049, + 145052, 145055, 145058, 145061, 145064, 145067, 145070, 145073, 145076, + 145079, 145082, 145085, 145088, 145091, 145094, 145097, 145100, 145103, + 145106, 145109, 145112, 145115, 145118, 145121, 145124, 145127, 145130, + 145133, 145136, 145139, 145142, 145145, 145148, 145151, 145154, 145157, + 145160, 145163, 145166, 145169, 145172, 145175, 145178, 145181, 145184, + 145187, 145190, 145193, 145196, 145199, 145202, 145205, 145208, 145211, + 145214, 145217, 145220, 145223, 145226, 145229, 145232, 145235, 145238, + 145241, 145244, 145247, 145250, 145253, 145256, 145259, 145262, 145265, + 145268, 145271, 145274, 145277, 145280, 145283, 145286, 145289, 145292, + 145295, 145298, 145301, 145304, 145307, 145310, 145313, 145316, 145319, + 145322, 145325, 145328, 145331, 145334, 145337, 145340, 145343, 145346, + 145349, 145352, 145355, 145358, 145361, 145364, 145367, 145370, 145373, + 145376, 145379, 145382, 145385, 145388, 145391, 145394, 145397, 145400, + 145403, 145406, 145409, 145412, 145415, 145418, 145421, 145424, 145427, + 145430, 145433, 145436, 145439, 145442, 145445, 145448, 145451, 145454, + 145457, 145460, 145463, 145466, 145469, 145472, 145475, 145478, 145481, + 145484, 145487, 145490, 145493, 145496, 145499, 145502, 145505, 145508, + 145511, 145514, 145517, 145520, 145523, 145526, 145529, 145532, 145535, + 145538, 145541, 145544, 145547, 145550, 145553, 145556, 145559, 145562, + 145565, 145568, 145571, 145574, 145577, 145580, 145583, 145586, 145589, + 145592, 145595, 145598, 145601, 145604, 145607, 145610, 145613, 145616, + 145619, 145622, 145625, 145628, 145631, 145634, 145637, 145640, 145643, + 145646, 145649, 145652, 145655, 145658, 145661, 145664, 145667, 145670, + 145673, 145676, 145679, 145682, 145685, 145688, 145691, 145694, 145697, + 145700, 145703, 145706, 145709, 145712, 145715, 145718, 145721, 145724, + 145727, 145730, 145733, 145736, 145739, 145742, 145745, 145748, 145751, + 145754, 145757, 145760, 145763, 145766, 145769, 145772, 145775, 145778, + 145781, 145784, 145787, 145790, 145793, 145796, 145799, 145802, 145805, + 145808, 145811, 145814, 145817, 145820, 145823, 145826, 145829, 145832, + 145835, 145838, 145841, 145844, 145847, 145850, 145853, 145856, 145859, + 145862, 145865, 145868, 145871, 145874, 145877, 145880, 145883, 145886, + 145889, 145892, 145895, 145898, 145901, 145904, 145907, 145910, 145913, + 145916, 145919, 145922, 145925, 145928, 145931, 145934, 145937, 145940, + 145943, 145946, 145949, 145952, 145955, 145958, 145961, 145964, 145967, + 145970, 145973, 145976, 145979, 145982, 145985, 145988, 145991, 145994, + 145997, 146000, 146003, 146006, 146009, 146012, 146015, 146018, 146021, + 146024, 146027, 146030, 146033, 146036, 146039, 146042, 146045, 146048, + 146051, 146054, 146057, 146060, 146063, 146066, 146069, 146072, 146075, + 146078, 146081, 146084, 146087, 146090, 146093, 146096, 146099, 146102, + 146105, 146108, 146111, 146114, 146117, 146120, 146123, 146126, 146129, + 146132, 146135, 146138, 146141, 146144, 146147, 146150, 146153, 146156, + 146159, 146162, 146165, 146168, 146171, 146174, 146177, 146180, 146183, + 146186, 146189, 146192, 146195, 146198, 146201, 146204, 146207, 146210, + 146213, 146216, 146219, 146222, 146225, 146228, 146231, 146234, 146237, + 146240, 146243, 146246, 146249, 146252, 146255, 146258, 146261, 146264, + 146267, 146270, 146273, 146276, 146279, 146282, 146285, 146288, 146291, + 146294, 146297, 146300, 146303, 146306, 146309, 146312, 146315, 146318, + 146321, 146324, 146327, 146330, 146333, 146336, 146339, 146342, 146345, + 146348, 146351, 146354, 146357, 146360, 146363, 146366, 146369, 146372, + 146375, 146378, 146381, 146384, 146387, 146390, 146393, 146396, 146399, + 146402, 146405, 146408, 146411, 146414, 146417, 146420, 146423, 146426, + 146429, 146432, 146435, 146438, 146441, 146444, 146447, 146450, 146453, + 146456, 146459, 146462, 146465, 146468, 146471, 146474, 146477, 146482, + 146487, 146492, 146497, 146502, 146507, 146512, 146517, 146522, 146527, + 146532, 146537, 146542, 146547, 146552, 146557, 146562, 146567, 146572, + 146577, 146582, 146587, 146592, 146597, 146602, 146607, 146612, 146617, + 146622, 146627, 146632, 146637, 146642, 146647, 146652, 146657, 146662, + 146667, 146672, 146677, 146682, 146687, 146692, 146697, 146702, 146707, + 146712, 146717, 146722, 146727, 146732, 146737, 146742, 146747, 146752, + 146757, 146762, 146767, 146772, 146777, 146782, 146787, 146792, 146797, + 146802, 146807, 146812, 146817, 146822, 146827, 146832, 146837, 146842, + 146847, 146852, 146857, 146862, 146867, 146872, 146877, 146882, 146887, + 146892, 146897, 146902, 146907, 146912, 146917, 146922, 146927, 146932, + 146937, 146942, 146947, 146952, 146957, 146962, 146967, 146972, 146977, + 146982, 146987, 146992, 146997, 147002, 147007, 147012, 147017, 147022, + 147027, 147032, 147037, 147042, 147047, 147052, 147057, 147062, 147067, + 147072, 147077, 147082, 147087, 147092, 147097, 147102, 147107, 147112, + 147117, 147122, 147127, 147132, 147137, 147142, 147147, 147152, 147157, + 147162, 147167, 147172, 147177, 147182, 147187, 147192, 147197, 147202, + 147207, 147212, 147217, 147222, 147227, 147232, 147237, 147242, 147247, + 147252, 147257, 147262, 147267, 147272, 147277, 147282, 147287, 147292, + 147297, 147302, 147307, 147312, 147317, 147322, 147327, 147332, 147337, + 147342, 147347, 147352, 147357, 147362, 147367, 147372, 147377, 147382, + 147387, 147392, 147397, 147402, 147407, 147412, 147417, 147422, 147427, + 147432, 147437, 147442, 147447, 147452, 147457, 147462, 147467, 147472, + 147477, 147482, 147487, 147492, 147497, 147502, 147507, 147512, 147517, + 147522, 147527, 147532, 147537, 147542, 147547, 147552, 147557, 147562, + 147567, 147572, 147577, 147582, 147587, 147592, 147597, 147602, 147607, + 147612, 147617, 147622, 147627, 147632, 147637, 147642, 147647, 147652, + 147657, 147662, 147667, 147672, 147677, 147682, 147687, 147692, 147697, + 147702, 147707, 147712, 147717, 147722, 147727, 147732, 147737, 147742, + 147747, 147752, 147757, 147762, 147767, 147772, 147777, 147782, 147787, + 147792, 147797, 147802, 147807, 147812, 147817, 147822, 147827, 147832, + 147837, 147842, 147847, 147852, 147857, 147862, 147867, 147872, 147877, + 147882, 147887, 147892, 147897, 147902, 147907, 147912, 147917, 147922, + 147927, 147932, 147937, 147942, 147947, 147952, 147957, 147962, 147967, + 147972, 147977, 147982, 147987, 147992, 147997, 148002, 148007, 148012, + 148017, 148022, 148027, 148032, 148037, 148042, 148047, 148052, 148057, + 148062, 148067, 148072, 148077, 148082, 148087, 148092, 148097, 148102, + 148107, 148112, 148117, 148122, 148127, 148132, 148137, 148142, 148147, + 148152, 148157, 148162, 148167, 148172, 148177, 148182, 148187, 148192, + 148197, 148202, 148207, 148212, 148217, 148222, 148227, 148232, 148237, + 148242, 148247, 148252, 148257, 148262, 148267, 148272, 148277, 148282, + 148287, 148292, 148297, 148302, 148307, 148312, 148317, 148322, 148327, + 148332, 148337, 148342, 148347, 148352, 148357, 148362, 148367, 148372, + 148377, 148382, 148387, 148392, 148397, 148402, 148407, 148412, 148417, + 148422, 148427, 148432, 148437, 148442, 148447, 148452, 148457, 148462, + 148467, 148472, 148477, 148482, 148487, 148492, 148497, 148502, 148507, + 148512, 148517, 148522, 148527, 148532, 148537, 148542, 148547, 148552, + 148557, 148562, 148567, 148572, 148577, 148582, 148587, 148592, 148597, + 148602, 148607, 148612, 148617, 148622, 148627, 148632, 148637, 148642, + 148647, 148652, 148657, 148662, 148667, 148672, 148677, 148682, 148687, + 148692, 148697, 148702, 148707, 148712, 148717, 148722, 148727, 148732, + 148737, 148742, 148747, 148752, 148757, 148762, 148767, 148772, 148777, + 148782, 148787, 148792, 148797, 148802, 148807, 148812, 148817, 148822, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 143312, 143316, 143320, 143326, 143332, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 143337, 143346, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 143355, 143358, 143361, 143364, 143367, 143370, 143373, 143376, - 143379, 143382, 143385, 143388, 143391, 143394, 143397, 143400, 143403, - 143406, 143409, 143412, 143415, 143418, 143421, 143424, 143427, 143430, - 143433, 143436, 143439, 143442, 143445, 143448, 143451, 143454, 143457, - 143460, 143463, 143466, 143469, 143472, 143475, 143478, 143481, 143484, - 143487, 143490, 143493, 143496, 143499, 143502, 143505, 143508, 143511, - 143514, 143517, 143520, 143523, 143526, 143529, 143532, 143535, 143538, - 143541, 143544, 143547, 143550, 143553, 143556, 143559, 143562, 143565, - 143568, 143571, 143574, 143577, 143580, 143583, 143586, 143589, 143592, - 143595, 143598, 143601, 143604, 143607, 143610, 143613, 143616, 143619, - 143622, 143625, 143628, 143631, 143634, 143637, 143640, 143643, 143646, - 143649, 143652, 143655, 143658, 143661, 143664, 143667, 143670, 143673, - 143676, 143679, 143682, 143685, 143688, 143691, 143694, 143697, 143700, - 143703, 143706, 143709, 143712, 143715, 143718, 143721, 143724, 143727, - 143730, 143733, 143736, 143739, 143742, 143745, 143748, 143751, 143754, - 143757, 143760, 143763, 143766, 143769, 143772, 143775, 143778, 143781, - 143784, 143787, 143790, 143793, 143796, 143799, 143802, 143805, 143808, - 143811, 143814, 143817, 143820, 143823, 143826, 143829, 143832, 143835, - 143838, 143841, 143844, 143847, 143850, 143853, 143856, 143859, 143862, - 143865, 143868, 143871, 143874, 143877, 143880, 143883, 143886, 143889, - 143892, 143895, 143898, 143901, 143904, 143907, 143910, 143913, 143916, - 143919, 143922, 143925, 143928, 143931, 143934, 143937, 143940, 143943, - 143946, 143949, 143952, 143955, 143958, 143961, 143964, 143967, 143970, - 143973, 143976, 143979, 143982, 143985, 143988, 143991, 143994, 143997, - 144000, 144003, 144006, 144009, 144012, 144015, 144018, 144021, 144024, - 144027, 144030, 144033, 144036, 144039, 144042, 144045, 144048, 144051, - 144054, 144057, 144060, 144063, 144066, 144069, 144072, 144075, 144078, - 144081, 144084, 144087, 144090, 144093, 144096, 144099, 144102, 144105, - 144108, 144111, 144114, 144117, 144120, 144123, 144126, 144129, 144132, - 144135, 144138, 144141, 144144, 144147, 144150, 144153, 144156, 144159, - 144162, 144165, 144168, 144171, 144174, 144177, 144180, 144183, 144186, - 144189, 144192, 144195, 144198, 144201, 144204, 144207, 144210, 144213, - 144216, 144219, 144222, 144225, 144228, 144231, 144234, 144237, 144240, - 144243, 144246, 144249, 144252, 144255, 144258, 144261, 144264, 144267, - 144270, 144273, 144276, 144279, 144282, 144285, 144288, 144291, 144294, - 144297, 144300, 144303, 144306, 144309, 144312, 144315, 144318, 144321, - 144324, 144327, 144330, 144333, 144336, 144339, 144342, 144345, 144348, - 144351, 144354, 144357, 144360, 144363, 144366, 144369, 144372, 144375, - 144378, 144381, 144384, 144387, 144390, 144393, 144396, 144399, 144402, - 144405, 144408, 144411, 144414, 144417, 144420, 144423, 144426, 144429, - 144432, 144435, 144438, 144441, 144444, 144447, 144450, 144453, 144456, - 144459, 144462, 144465, 144468, 144471, 144474, 144477, 144480, 144483, - 144486, 144489, 144492, 144495, 144498, 144501, 144504, 144507, 144510, - 144513, 144516, 144519, 144522, 144525, 144528, 144531, 144534, 144537, - 144540, 144543, 144546, 144549, 144552, 144555, 144558, 144561, 144564, - 144567, 144570, 144573, 144576, 144579, 144582, 144585, 144588, 144591, - 144594, 144597, 144600, 144603, 144606, 144609, 144612, 144615, 144618, - 144621, 144624, 144627, 144630, 144633, 144636, 144639, 144642, 144645, - 144648, 144651, 144654, 144657, 144660, 144663, 144666, 144669, 144672, - 144675, 144678, 144681, 144684, 144687, 144690, 144693, 144696, 144699, - 144702, 144705, 144708, 144711, 144714, 144717, 144720, 144723, 144726, - 144729, 144732, 144735, 144738, 144741, 144744, 144747, 144750, 144753, - 144756, 144759, 144762, 144765, 144768, 144771, 144774, 144777, 144780, - 144783, 144786, 144789, 144792, 144795, 144798, 144801, 144804, 144807, - 144810, 144813, 144816, 144819, 144822, 144825, 144828, 144831, 144834, - 144837, 144840, 144843, 144846, 144849, 144852, 144855, 144858, 144861, - 144864, 144867, 144870, 144873, 144876, 144879, 144882, 144885, 144888, - 144891, 144894, 144897, 144900, 144903, 144906, 144909, 144912, 144915, - 144918, 144921, 144924, 144927, 144930, 144933, 144936, 144939, 144942, - 144945, 144948, 144951, 144954, 144957, 144960, 144963, 144966, 144969, - 144972, 144975, 144978, 144981, 144984, 144987, 144990, 144993, 144996, - 144999, 145002, 145005, 145008, 145011, 145014, 145017, 145020, 145023, - 145026, 145029, 145032, 145035, 145038, 145041, 145044, 145047, 145050, - 145053, 145056, 145059, 145062, 145065, 145068, 145071, 145074, 145077, - 145080, 145083, 145086, 145089, 145092, 145095, 145098, 145101, 145104, - 145107, 145110, 145113, 145116, 145119, 145122, 145125, 145128, 145131, - 145134, 145137, 145140, 145143, 145146, 145149, 145152, 145155, 145158, - 145161, 145164, 145167, 145170, 145173, 145176, 145179, 145182, 145185, - 145188, 145191, 145194, 145197, 145200, 145203, 145206, 145209, 145212, - 145215, 145218, 145221, 145224, 145227, 145230, 145233, 145236, 145239, - 145242, 145245, 145248, 145251, 145254, 145257, 145260, 145263, 145266, - 145269, 145272, 145275, 145278, 145281, 145284, 145287, 145290, 145293, - 145296, 145299, 145302, 145305, 145308, 145311, 145314, 145317, 145320, - 145323, 145326, 145329, 145332, 145335, 145338, 145341, 145344, 145347, - 145350, 145353, 145356, 145359, 145362, 145365, 145368, 145371, 145374, - 145377, 145380, 145383, 145386, 145389, 145392, 145395, 145398, 145401, - 145404, 145407, 145410, 145413, 145416, 145419, 145422, 145425, 145428, - 145431, 145434, 145437, 145440, 145443, 145446, 145449, 145452, 145455, - 145458, 145461, 145464, 145467, 145470, 145473, 145476, 145479, 145482, - 145485, 145488, 145491, 145494, 145497, 145500, 145503, 145506, 145509, - 145512, 145515, 145518, 145521, 145524, 145527, 145530, 145533, 145536, - 145539, 145542, 145545, 145548, 145551, 145554, 145557, 145560, 145563, - 145566, 145569, 145572, 145575, 145578, 145581, 145584, 145587, 145590, - 145593, 145596, 145599, 145602, 145605, 145608, 145611, 145614, 145617, - 145620, 145623, 145626, 145629, 145632, 145635, 145638, 145641, 145644, - 145647, 145650, 145653, 145656, 145659, 145664, 145669, 145674, 145679, - 145684, 145689, 145694, 145699, 145704, 145709, 145714, 145719, 145724, - 145729, 145734, 145739, 145744, 145749, 145754, 145759, 145764, 145769, - 145774, 145779, 145784, 145789, 145794, 145799, 145804, 145809, 145814, - 145819, 145824, 145829, 145834, 145839, 145844, 145849, 145854, 145859, - 145864, 145869, 145874, 145879, 145884, 145889, 145894, 145899, 145904, - 145909, 145914, 145919, 145924, 145929, 145934, 145939, 145944, 145949, - 145954, 145959, 145964, 145969, 145974, 145979, 145984, 145989, 145994, - 145999, 146004, 146009, 146014, 146019, 146024, 146029, 146034, 146039, - 146044, 146049, 146054, 146059, 146064, 146069, 146074, 146079, 146084, - 146089, 146094, 146099, 146104, 146109, 146114, 146119, 146124, 146129, - 146134, 146139, 146144, 146149, 146154, 146159, 146164, 146169, 146174, - 146179, 146184, 146189, 146194, 146199, 146204, 146209, 146214, 146219, - 146224, 146229, 146234, 146239, 146244, 146249, 146254, 146259, 146264, - 146269, 146274, 146279, 146284, 146289, 146294, 146299, 146304, 146309, - 146314, 146319, 146324, 146329, 146334, 146339, 146344, 146349, 146354, - 146359, 146364, 146369, 146374, 146379, 146384, 146389, 146394, 146399, - 146404, 146409, 146414, 146419, 146424, 146429, 146434, 146439, 146444, - 146449, 146454, 146459, 146464, 146469, 146474, 146479, 146484, 146489, - 146494, 146499, 146504, 146509, 146514, 146519, 146524, 146529, 146534, - 146539, 146544, 146549, 146554, 146559, 146564, 146569, 146574, 146579, - 146584, 146589, 146594, 146599, 146604, 146609, 146614, 146619, 146624, - 146629, 146634, 146639, 146644, 146649, 146654, 146659, 146664, 146669, - 146674, 146679, 146684, 146689, 146694, 146699, 146704, 146709, 146714, - 146719, 146724, 146729, 146734, 146739, 146744, 146749, 146754, 146759, - 146764, 146769, 146774, 146779, 146784, 146789, 146794, 146799, 146804, - 146809, 146814, 146819, 146824, 146829, 146834, 146839, 146844, 146849, - 146854, 146859, 146864, 146869, 146874, 146879, 146884, 146889, 146894, - 146899, 146904, 146909, 146914, 146919, 146924, 146929, 146934, 146939, - 146944, 146949, 146954, 146959, 146964, 146969, 146974, 146979, 146984, - 146989, 146994, 146999, 147004, 147009, 147014, 147019, 147024, 147029, - 147034, 147039, 147044, 147049, 147054, 147059, 147064, 147069, 147074, - 147079, 147084, 147089, 147094, 147099, 147104, 147109, 147114, 147119, - 147124, 147129, 147134, 147139, 147144, 147149, 147154, 147159, 147164, - 147169, 147174, 147179, 147184, 147189, 147194, 147199, 147204, 147209, - 147214, 147219, 147224, 147229, 147234, 147239, 147244, 147249, 147254, - 147259, 147264, 147269, 147274, 147279, 147284, 147289, 147294, 147299, - 147304, 147309, 147314, 147319, 147324, 147329, 147334, 147339, 147344, - 147349, 147354, 147359, 147364, 147369, 147374, 147379, 147384, 147389, - 147394, 147399, 147404, 147409, 147414, 147419, 147424, 147429, 147434, - 147439, 147444, 147449, 147454, 147459, 147464, 147469, 147474, 147479, - 147484, 147489, 147494, 147499, 147504, 147509, 147514, 147519, 147524, - 147529, 147534, 147539, 147544, 147549, 147554, 147559, 147564, 147569, - 147574, 147579, 147584, 147589, 147594, 147599, 147604, 147609, 147614, - 147619, 147624, 147629, 147634, 147639, 147644, 147649, 147654, 147659, - 147664, 147669, 147674, 147679, 147684, 147689, 147694, 147699, 147704, - 147709, 147714, 147719, 147724, 147729, 147734, 147739, 147744, 147749, - 147754, 147759, 147764, 147769, 147774, 147779, 147784, 147789, 147794, - 147799, 147804, 147809, 147814, 147819, 147824, 147829, 147834, 147839, - 147844, 147849, 147854, 147859, 147864, 147869, 147874, 147879, 147884, - 147889, 147894, 147899, 147904, 147909, 147914, 147919, 147924, 147929, - 147934, 147939, 147944, 147949, 147954, 147959, 147964, 147969, 147974, - 147979, 147984, 147989, 147994, 147999, 148004, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148827, 148833, 148839, 148845, 0, 148851, + 148857, 148863, 148871, 148879, 148887, 148895, 0, 148903, 148911, 0, + 148919, 148924, 148931, 148935, 148939, 148943, 148947, 148951, 148955, + 148959, 148963, 148967, 148971, 148975, 148979, 148983, 148987, 148991, + 148995, 148999, 149003, 149007, 149011, 149015, 149019, 149023, 149027, + 149031, 149035, 149039, 149043, 149047, 149051, 149055, 149059, 149063, + 149067, 149071, 149075, 149079, 149083, 149087, 149091, 149095, 149099, + 149103, 149107, 149111, 149115, 149119, 149123, 149127, 149131, 149135, + 149139, 149143, 149147, 149151, 149155, 149159, 149163, 149167, 149171, + 149175, 149179, 149183, 149187, 149191, 149195, 149199, 149203, 149207, + 149211, 149215, 149219, 149223, 149227, 149231, 149235, 149239, 149243, + 149247, 149251, 149255, 149259, 149263, 149267, 149271, 149275, 149279, + 149283, 149287, 149291, 149295, 149299, 149303, 149307, 149311, 149315, + 149319, 149323, 149327, 149331, 149335, 149339, 149343, 149347, 149351, + 149355, 149359, 149363, 149367, 149371, 149375, 149379, 149383, 149387, + 149391, 149395, 149399, 149403, 149407, 149411, 149415, 149419, 149423, + 149427, 149431, 149435, 149439, 149443, 149447, 149451, 149455, 149459, + 149463, 149467, 149471, 149475, 149479, 149483, 149487, 149491, 149495, + 149499, 149503, 149507, 149511, 149515, 149519, 149523, 149527, 149531, + 149535, 149539, 149543, 149547, 149551, 149555, 149559, 149563, 149567, + 149571, 149575, 149579, 149583, 149587, 149591, 149595, 149599, 149603, + 149607, 149611, 149615, 149619, 149623, 149627, 149631, 149635, 149639, + 149643, 149647, 149651, 149655, 149659, 149663, 149667, 149671, 149675, + 149679, 149683, 149687, 149691, 149695, 149699, 149703, 149707, 149711, + 149715, 149719, 149723, 149727, 149731, 149735, 149739, 149743, 149747, + 149751, 149755, 149759, 149763, 149767, 149771, 149775, 149779, 149783, + 149787, 149791, 149795, 149799, 149803, 149807, 149811, 149815, 149819, + 149823, 149827, 149831, 149835, 149839, 149843, 149847, 149851, 149855, + 149859, 149863, 149867, 149871, 149875, 149879, 149883, 149887, 149891, + 149895, 149899, 149903, 149907, 149911, 149915, 149919, 149923, 149927, + 149931, 149935, 149939, 149943, 149947, 149951, 149955, 149959, 149963, + 149967, 149971, 149975, 149979, 149983, 149987, 149991, 149995, 149999, + 150003, 150007, 150011, 150015, 150019, 150023, 150027, 150031, 150035, + 150039, 150043, 150047, 150051, 150055, 150059, 150063, 150067, 150071, + 150078, 150084, 150090, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 150096, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 150102, 150108, 150114, 0, 0, 150120, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 150125, 150130, 150135, 150140, 0, 0, 0, 0, 0, + 0, 0, 0, 150145, 150148, 150151, 150154, 150157, 150160, 150163, 150166, + 150169, 150172, 150175, 150178, 150181, 150184, 150187, 150190, 150193, + 150196, 150199, 150202, 150205, 150208, 150211, 150214, 150217, 150220, + 150223, 150226, 150229, 150232, 150235, 150238, 150241, 150244, 150247, + 150250, 150253, 150256, 150259, 150262, 150265, 150268, 150271, 150274, + 150277, 150280, 150283, 150286, 150289, 150292, 150295, 150298, 150301, + 150304, 150307, 150310, 150313, 150316, 150319, 150322, 150325, 150328, + 150331, 150334, 150337, 150340, 150343, 150346, 150349, 150352, 150355, + 150358, 150361, 150364, 150367, 150370, 150373, 150376, 150379, 150382, + 150385, 150388, 150391, 150394, 150397, 150400, 150403, 150406, 150409, + 150412, 150415, 150418, 150421, 150424, 150427, 150430, 150433, 150436, + 150439, 150442, 150445, 150448, 150451, 150454, 150457, 150460, 150463, + 150466, 150469, 150472, 150475, 150478, 150481, 150484, 150487, 150490, + 150493, 150496, 150499, 150502, 150505, 150508, 150511, 150514, 150517, + 150520, 150523, 150526, 150529, 150532, 150535, 150538, 150541, 150544, + 150547, 150550, 150553, 150556, 150559, 150562, 150565, 150568, 150571, + 150574, 150577, 150580, 150583, 150586, 150589, 150592, 150595, 150598, + 150601, 150604, 150607, 150610, 150613, 150616, 150619, 150622, 150625, + 150628, 150631, 150634, 150637, 150640, 150643, 150646, 150649, 150652, + 150655, 150658, 150661, 150664, 150667, 150670, 150673, 150676, 150679, + 150682, 150685, 150688, 150691, 150694, 150697, 150700, 150703, 150706, + 150709, 150712, 150715, 150718, 150721, 150724, 150727, 150730, 150733, + 150736, 150739, 150742, 150745, 150748, 150751, 150754, 150757, 150760, + 150763, 150766, 150769, 150772, 150775, 150778, 150781, 150784, 150787, + 150790, 150793, 150796, 150799, 150802, 150805, 150808, 150811, 150814, + 150817, 150820, 150823, 150826, 150829, 150832, 150835, 150838, 150841, + 150844, 150847, 150850, 150853, 150856, 150859, 150862, 150865, 150868, + 150871, 150874, 150877, 150880, 150883, 150886, 150889, 150892, 150895, + 150898, 150901, 150904, 150907, 150910, 150913, 150916, 150919, 150922, + 150925, 150928, 150931, 150934, 150937, 150940, 150943, 150946, 150949, + 150952, 150955, 150958, 150961, 150964, 150967, 150970, 150973, 150976, + 150979, 150982, 150985, 150988, 150991, 150994, 150997, 151000, 151003, + 151006, 151009, 151012, 151015, 151018, 151021, 151024, 151027, 151030, + 151033, 151036, 151039, 151042, 151045, 151048, 151051, 151054, 151057, + 151060, 151063, 151066, 151069, 151072, 151075, 151078, 151081, 151084, + 151087, 151090, 151093, 151096, 151099, 151102, 151105, 151108, 151111, + 151114, 151117, 151120, 151123, 151126, 151129, 151132, 151135, 151138, + 151141, 151144, 151147, 151150, 151153, 151156, 151159, 151162, 151165, + 151168, 151171, 151174, 151177, 151180, 151183, 151186, 151189, 151192, + 151195, 151198, 151201, 151204, 151207, 151210, 151213, 151216, 151219, + 151222, 151225, 151228, 151231, 151234, 151237, 151240, 151243, 151246, + 151249, 151252, 151255, 151258, 151261, 151264, 151267, 151270, 151273, + 151276, 151279, 151282, 151285, 151288, 151291, 151294, 151297, 151300, + 151303, 151306, 151309, 151312, 151315, 151318, 151321, 151324, 151327, + 151330, 0, 0, 0, 0, 151333, 151337, 151341, 151345, 151349, 151353, + 151357, 151360, 151364, 151368, 151372, 151376, 151379, 151385, 151391, + 151397, 151403, 151409, 151413, 151419, 151423, 151427, 151433, 151437, + 151441, 151445, 151449, 151453, 151457, 151461, 151467, 151473, 151479, + 151485, 151492, 151499, 151506, 151516, 151523, 151530, 151536, 151542, + 151548, 151554, 151562, 151570, 151578, 151586, 151595, 151601, 151609, + 151615, 151622, 151628, 151635, 151641, 151649, 151653, 151657, 151662, + 151668, 151674, 151682, 151690, 151696, 151703, 151706, 151712, 151716, + 151719, 151723, 151726, 151729, 151733, 151738, 151742, 151746, 151752, + 151757, 151763, 151767, 151771, 151774, 151778, 151782, 151787, 151791, + 151796, 151800, 151805, 151809, 151813, 151817, 151821, 151825, 151829, + 151833, 151837, 151842, 151847, 151852, 151857, 151863, 151869, 151875, + 151881, 151887, 0, 0, 0, 0, 0, 151892, 151900, 151909, 151917, 151924, + 151932, 151939, 151946, 151955, 151962, 151969, 151977, 151985, 0, 0, 0, + 151993, 151999, 152007, 152013, 152020, 152026, 152032, 152038, 152044, + 0, 0, 0, 0, 0, 0, 0, 152050, 152056, 152064, 152070, 152077, 152083, + 152089, 152095, 152101, 152107, 0, 0, 152112, 152118, 152124, 152127, + 152136, 152143, 152151, 152158, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 148009, 148015, 148021, 148027, 0, 148033, 148039, 148045, 148053, - 148061, 148069, 148077, 0, 148085, 148093, 0, 148101, 148106, 148113, - 148117, 148121, 148125, 148129, 148133, 148137, 148141, 148145, 148149, - 148153, 148157, 148161, 148165, 148169, 148173, 148177, 148181, 148185, - 148189, 148193, 148197, 148201, 148205, 148209, 148213, 148217, 148221, - 148225, 148229, 148233, 148237, 148241, 148245, 148249, 148253, 148257, - 148261, 148265, 148269, 148273, 148277, 148281, 148285, 148289, 148293, - 148297, 148301, 148305, 148309, 148313, 148317, 148321, 148325, 148329, - 148333, 148337, 148341, 148345, 148349, 148353, 148357, 148361, 148365, - 148369, 148373, 148377, 148381, 148385, 148389, 148393, 148397, 148401, - 148405, 148409, 148413, 148417, 148421, 148425, 148429, 148433, 148437, - 148441, 148445, 148449, 148453, 148457, 148461, 148465, 148469, 148473, - 148477, 148481, 148485, 148489, 148493, 148497, 148501, 148505, 148509, - 148513, 148517, 148521, 148525, 148529, 148533, 148537, 148541, 148545, - 148549, 148553, 148557, 148561, 148565, 148569, 148573, 148577, 148581, - 148585, 148589, 148593, 148597, 148601, 148605, 148609, 148613, 148617, - 148621, 148625, 148629, 148633, 148637, 148641, 148645, 148649, 148653, - 148657, 148661, 148665, 148669, 148673, 148677, 148681, 148685, 148689, - 148693, 148697, 148701, 148705, 148709, 148713, 148717, 148721, 148725, - 148729, 148733, 148737, 148741, 148745, 148749, 148753, 148757, 148761, - 148765, 148769, 148773, 148777, 148781, 148785, 148789, 148793, 148797, - 148801, 148805, 148809, 148813, 148817, 148821, 148825, 148829, 148833, - 148837, 148841, 148845, 148849, 148853, 148857, 148861, 148865, 148869, - 148873, 148877, 148881, 148885, 148889, 148893, 148897, 148901, 148905, - 148909, 148913, 148917, 148921, 148925, 148929, 148933, 148937, 148941, - 148945, 148949, 148953, 148957, 148961, 148965, 148969, 148973, 148977, - 148981, 148985, 148989, 148993, 148997, 149001, 149005, 149009, 149013, - 149017, 149021, 149025, 149029, 149033, 149037, 149041, 149045, 149049, - 149053, 149057, 149061, 149065, 149069, 149073, 149077, 149081, 149085, - 149089, 149093, 149097, 149101, 149105, 149109, 149113, 149117, 149121, - 149125, 149129, 149133, 149137, 149141, 149145, 149149, 149153, 149157, - 149161, 149165, 149169, 149173, 149177, 149181, 149185, 149189, 149193, - 149197, 149201, 149205, 149209, 149213, 149217, 149221, 149225, 149229, - 149233, 149237, 149241, 149245, 149249, 149253, 149260, 149266, 149272, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 149278, - 149284, 149290, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 149296, 149301, 149306, 149311, 0, 0, 0, 0, 0, 0, 0, 0, 149316, 149319, - 149322, 149325, 149328, 149331, 149334, 149337, 149340, 149343, 149346, - 149349, 149352, 149355, 149358, 149361, 149364, 149367, 149370, 149373, - 149376, 149379, 149382, 149385, 149388, 149391, 149394, 149397, 149400, - 149403, 149406, 149409, 149412, 149415, 149418, 149421, 149424, 149427, - 149430, 149433, 149436, 149439, 149442, 149445, 149448, 149451, 149454, - 149457, 149460, 149463, 149466, 149469, 149472, 149475, 149478, 149481, - 149484, 149487, 149490, 149493, 149496, 149499, 149502, 149505, 149508, - 149511, 149514, 149517, 149520, 149523, 149526, 149529, 149532, 149535, - 149538, 149541, 149544, 149547, 149550, 149553, 149556, 149559, 149562, - 149565, 149568, 149571, 149574, 149577, 149580, 149583, 149586, 149589, - 149592, 149595, 149598, 149601, 149604, 149607, 149610, 149613, 149616, - 149619, 149622, 149625, 149628, 149631, 149634, 149637, 149640, 149643, - 149646, 149649, 149652, 149655, 149658, 149661, 149664, 149667, 149670, - 149673, 149676, 149679, 149682, 149685, 149688, 149691, 149694, 149697, - 149700, 149703, 149706, 149709, 149712, 149715, 149718, 149721, 149724, - 149727, 149730, 149733, 149736, 149739, 149742, 149745, 149748, 149751, - 149754, 149757, 149760, 149763, 149766, 149769, 149772, 149775, 149778, - 149781, 149784, 149787, 149790, 149793, 149796, 149799, 149802, 149805, - 149808, 149811, 149814, 149817, 149820, 149823, 149826, 149829, 149832, - 149835, 149838, 149841, 149844, 149847, 149850, 149853, 149856, 149859, - 149862, 149865, 149868, 149871, 149874, 149877, 149880, 149883, 149886, - 149889, 149892, 149895, 149898, 149901, 149904, 149907, 149910, 149913, - 149916, 149919, 149922, 149925, 149928, 149931, 149934, 149937, 149940, - 149943, 149946, 149949, 149952, 149955, 149958, 149961, 149964, 149967, - 149970, 149973, 149976, 149979, 149982, 149985, 149988, 149991, 149994, - 149997, 150000, 150003, 150006, 150009, 150012, 150015, 150018, 150021, - 150024, 150027, 150030, 150033, 150036, 150039, 150042, 150045, 150048, - 150051, 150054, 150057, 150060, 150063, 150066, 150069, 150072, 150075, - 150078, 150081, 150084, 150087, 150090, 150093, 150096, 150099, 150102, - 150105, 150108, 150111, 150114, 150117, 150120, 150123, 150126, 150129, - 150132, 150135, 150138, 150141, 150144, 150147, 150150, 150153, 150156, - 150159, 150162, 150165, 150168, 150171, 150174, 150177, 150180, 150183, - 150186, 150189, 150192, 150195, 150198, 150201, 150204, 150207, 150210, - 150213, 150216, 150219, 150222, 150225, 150228, 150231, 150234, 150237, - 150240, 150243, 150246, 150249, 150252, 150255, 150258, 150261, 150264, - 150267, 150270, 150273, 150276, 150279, 150282, 150285, 150288, 150291, - 150294, 150297, 150300, 150303, 150306, 150309, 150312, 150315, 150318, - 150321, 150324, 150327, 150330, 150333, 150336, 150339, 150342, 150345, - 150348, 150351, 150354, 150357, 150360, 150363, 150366, 150369, 150372, - 150375, 150378, 150381, 150384, 150387, 150390, 150393, 150396, 150399, - 150402, 150405, 150408, 150411, 150414, 150417, 150420, 150423, 150426, - 150429, 150432, 150435, 150438, 150441, 150444, 150447, 150450, 150453, - 150456, 150459, 150462, 150465, 150468, 150471, 150474, 150477, 150480, - 150483, 150486, 150489, 150492, 150495, 150498, 150501, 0, 0, 0, 0, - 150504, 150508, 150512, 150516, 150520, 150524, 150528, 150531, 150535, - 150539, 150543, 150547, 150550, 150556, 150562, 150568, 150574, 150580, - 150584, 150590, 150594, 150598, 150604, 150608, 150612, 150616, 150620, - 150624, 150628, 150632, 150638, 150644, 150650, 150656, 150663, 150670, - 150677, 150687, 150694, 150701, 150707, 150713, 150719, 150725, 150733, - 150741, 150749, 150757, 150766, 150772, 150780, 150786, 150793, 150799, - 150806, 150812, 150820, 150824, 150828, 150833, 150839, 150845, 150853, - 150861, 150867, 150874, 150877, 150883, 150887, 150890, 150894, 150897, - 150900, 150904, 150909, 150913, 150917, 150923, 150928, 150934, 150938, - 150942, 150945, 150949, 150953, 150958, 150962, 150967, 150971, 150976, - 150980, 150984, 150988, 150992, 150996, 151000, 151004, 151008, 151013, - 151018, 151023, 151028, 151034, 151040, 151046, 151052, 151058, 0, 0, 0, - 0, 0, 151063, 151071, 151080, 151088, 151095, 151103, 151110, 151117, - 151126, 151133, 151140, 151148, 151156, 0, 0, 0, 151164, 151170, 151178, - 151184, 151191, 151197, 151203, 151209, 151215, 0, 0, 0, 0, 0, 0, 0, - 151221, 151227, 151235, 151241, 151248, 151254, 151260, 151266, 151272, - 151278, 0, 0, 151283, 151289, 151295, 151298, 151307, 151314, 151322, - 151329, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 152165, 152180, 152193, 152202, 152213, 152222, 152231, + 152242, 152251, 152260, 152275, 152288, 152301, 152315, 152327, 152335, + 152345, 152353, 152361, 152371, 152379, 152387, 152401, 152413, 152425, + 152434, 152445, 152454, 152463, 152470, 152479, 152488, 152495, 152500, + 152505, 152510, 152515, 152520, 152525, 152530, 152535, 152540, 152545, + 152550, 152555, 152560, 0, 0, 152569, 152578, 152587, 152596, 152601, + 152608, 152613, 152618, 152626, 152631, 152638, 152643, 152650, 152655, + 152660, 152667, 152674, 152679, 152688, 152694, 152700, 152708, 152714, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 152720, 152724, 152730, 152734, 152742, + 152746, 152750, 152754, 152762, 152766, 152772, 152781, 152785, 152789, + 152793, 152799, 152805, 152811, 152817, 152823, 152829, 152835, 152841, + 152847, 152855, 152863, 152871, 152879, 152884, 152890, 152894, 152898, + 152902, 152906, 152912, 152918, 152924, 152930, 152936, 152944, 152950, + 152958, 152966, 152974, 152982, 152990, 152994, 153002, 153008, 153016, + 153020, 153024, 153028, 153032, 153036, 153040, 153048, 153056, 153068, + 153080, 153086, 153096, 153104, 153114, 153126, 153130, 153136, 153142, + 153148, 153154, 153160, 153166, 153172, 153178, 153184, 153192, 153198, + 153204, 153210, 153218, 153226, 153237, 153248, 153254, 153260, 153270, + 153276, 153284, 153288, 153294, 153300, 153306, 153312, 153318, 153324, + 153330, 153334, 153340, 153346, 153354, 153362, 153370, 153376, 153384, + 153397, 153410, 153418, 153426, 153438, 153446, 153456, 153464, 153468, + 153472, 153476, 153480, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 151336, - 151351, 151364, 151373, 151384, 151393, 151402, 151413, 151422, 151431, - 151446, 151459, 151472, 151486, 151498, 151506, 151516, 151524, 151532, - 151542, 151550, 151558, 151572, 151584, 151596, 151605, 151616, 151625, - 151634, 151641, 151650, 151659, 151666, 151671, 151676, 151681, 151686, - 151691, 151696, 151701, 151706, 151711, 151716, 151721, 151726, 151731, - 0, 0, 151740, 151749, 151758, 151767, 151772, 151779, 151784, 151789, - 151797, 151802, 151809, 151814, 151821, 151826, 151831, 151838, 151845, - 151850, 151859, 151865, 151871, 151879, 151885, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 151891, 151895, 151901, 151905, 151913, 151917, 151921, 151925, - 151933, 151937, 151943, 151952, 151956, 151960, 151964, 151970, 151976, - 151982, 151988, 151994, 152000, 152006, 152012, 152018, 152026, 152034, - 152042, 152050, 152055, 152061, 152065, 152069, 152073, 152077, 152083, - 152089, 152095, 152101, 152107, 152115, 152121, 152129, 152137, 152145, - 152153, 152161, 152165, 152173, 152179, 152187, 152191, 152195, 152199, - 152203, 152207, 152211, 152219, 152227, 152239, 152251, 152257, 152267, - 152275, 152285, 152297, 152301, 152307, 152313, 152319, 152325, 152331, - 152337, 152343, 152349, 152355, 152363, 152369, 152375, 152381, 152389, - 152397, 152408, 152419, 152425, 152431, 152441, 152447, 152455, 152459, - 152465, 152471, 152477, 152483, 152489, 152495, 152501, 152505, 152511, - 152517, 152525, 152533, 152541, 152547, 152555, 152568, 152581, 152589, - 152597, 152609, 152617, 152627, 152635, 152639, 152643, 152647, 152651, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 153484, + 153489, 153494, 153499, 153506, 153513, 153520, 153527, 153532, 153537, + 153542, 153547, 153554, 153559, 153566, 153573, 153578, 153583, 153588, + 153595, 153600, 153605, 153612, 153619, 153624, 153629, 153634, 153641, + 153648, 153655, 153660, 153665, 153672, 153679, 153686, 153693, 153698, + 153703, 153708, 153715, 153720, 153725, 153730, 153737, 153746, 153753, + 153758, 153763, 153768, 153773, 153778, 153783, 153792, 153799, 153804, + 153811, 153818, 153823, 153828, 153833, 153840, 153845, 153852, 153859, + 153864, 153869, 153874, 153881, 153888, 153893, 153898, 153905, 153912, + 153919, 153924, 153929, 153934, 153939, 153946, 153955, 153964, 153969, + 153976, 153985, 153990, 153995, 154000, 154005, 154012, 154019, 154026, + 154033, 154038, 154043, 154048, 154055, 154062, 154069, 154074, 154079, + 154086, 154091, 154098, 154103, 154110, 154115, 154122, 154129, 154134, + 154139, 154144, 154149, 154154, 154159, 154164, 154169, 154174, 154181, + 154188, 154195, 154202, 154209, 154218, 154223, 154228, 154235, 154242, + 154247, 154254, 154261, 154268, 154275, 154282, 154289, 154294, 154299, + 154304, 154309, 154314, 154323, 154332, 154341, 154350, 154359, 154368, + 154377, 154386, 154391, 154402, 154413, 154422, 154427, 154432, 154437, + 154442, 154451, 154458, 154465, 154472, 154479, 154486, 154493, 154502, + 154511, 154522, 154531, 154542, 154551, 154558, 154567, 154578, 154587, + 154596, 154605, 154614, 154621, 154628, 154635, 154644, 154653, 154664, + 154673, 154682, 154693, 154698, 154703, 154714, 154722, 154731, 154740, + 154749, 154760, 154769, 154778, 154789, 154800, 154811, 154822, 154833, + 154844, 154851, 154858, 154865, 154872, 154883, 154892, 154899, 154906, + 154913, 154924, 154935, 154946, 154957, 154968, 154979, 154990, 155001, + 155008, 155015, 155024, 155033, 155040, 155047, 155054, 155063, 155072, + 155081, 155088, 155097, 155106, 155115, 155122, 155129, 155134, 155140, + 155147, 155154, 155161, 155168, 155175, 155182, 155191, 155200, 155209, + 155218, 155225, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 155234, 155240, 155245, + 155250, 155257, 155263, 155269, 155275, 155281, 155287, 155293, 155299, + 155303, 155307, 155313, 155319, 155325, 155329, 155334, 155339, 155343, + 155347, 155351, 155357, 155363, 155369, 155375, 155381, 155387, 155393, + 155399, 155405, 155415, 155425, 155431, 155437, 155447, 155457, 155463, + 0, 0, 155469, 155477, 155482, 155487, 155493, 155499, 155505, 155511, + 155517, 155523, 155530, 155537, 155543, 155549, 155555, 155561, 155567, + 155573, 155579, 155585, 155590, 155596, 155602, 155608, 155614, 155620, + 155629, 155635, 155640, 155648, 155655, 155662, 155671, 155680, 155689, + 155698, 155707, 155716, 155725, 155734, 155744, 155754, 155762, 155770, + 155779, 155788, 155794, 155800, 155806, 155812, 155820, 155828, 155832, + 155838, 155843, 155849, 155855, 155861, 155867, 155873, 155882, 155887, + 155894, 155899, 155904, 155909, 155915, 155921, 155927, 155934, 155939, + 155944, 155949, 155954, 155959, 155965, 155971, 155977, 155983, 155989, + 155995, 156001, 156007, 156012, 156017, 156022, 156027, 156032, 156037, + 156042, 156047, 156053, 156059, 156064, 156069, 156074, 156079, 156084, + 156090, 156097, 156101, 156105, 156109, 156113, 156117, 156121, 156125, + 156129, 156137, 156147, 156151, 156155, 156161, 156167, 156173, 156179, + 156185, 156191, 156197, 156203, 156209, 156215, 156221, 156227, 156233, + 156239, 156243, 156247, 156254, 156260, 156266, 156272, 156277, 156284, + 156289, 156295, 156301, 156307, 156313, 156318, 156322, 156328, 156332, + 156336, 156340, 156346, 156352, 156356, 156362, 156368, 156374, 156380, + 156386, 156394, 156402, 156408, 156414, 156420, 156426, 156438, 156450, + 156464, 156476, 156488, 156502, 156516, 156530, 156534, 156542, 156550, + 156555, 156559, 156563, 156567, 156571, 156575, 156579, 156583, 156589, + 156595, 156601, 156607, 156615, 156624, 156631, 156638, 156646, 156653, + 156665, 156677, 156689, 156701, 156708, 156712, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156716, 156723, 156730, 156737, + 156744, 156751, 156758, 156765, 156772, 156779, 156786, 156793, 156800, + 156807, 156814, 156821, 156828, 156835, 156842, 156849, 156856, 156863, + 156870, 156877, 156884, 156891, 156898, 156905, 156912, 156919, 156926, + 156933, 156940, 156947, 156954, 156961, 156968, 156975, 156982, 156989, + 156996, 157003, 157010, 157017, 157024, 157031, 157038, 157045, 157052, + 157059, 157066, 157073, 157080, 157087, 157094, 157101, 157108, 157115, + 157122, 157129, 157136, 157143, 157150, 157157, 157164, 157171, 157178, + 157183, 157188, 157193, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 152655, 152660, 152665, 152670, - 152677, 152684, 152691, 152698, 152703, 152708, 152713, 152718, 152725, - 152730, 152737, 152744, 152749, 152754, 152759, 152766, 152771, 152776, - 152783, 152790, 152795, 152800, 152805, 152812, 152819, 152826, 152831, - 152836, 152843, 152850, 152857, 152864, 152869, 152874, 152879, 152886, - 152891, 152896, 152901, 152908, 152917, 152924, 152929, 152934, 152939, - 152944, 152949, 152954, 152963, 152970, 152975, 152982, 152989, 152994, - 152999, 153004, 153011, 153016, 153023, 153030, 153035, 153040, 153045, - 153052, 153059, 153064, 153069, 153076, 153083, 153090, 153095, 153100, - 153105, 153110, 153117, 153126, 153135, 153140, 153147, 153156, 153161, - 153166, 153171, 153176, 153183, 153190, 153197, 153204, 153209, 153214, - 153219, 153226, 153233, 153240, 153245, 153250, 153257, 153262, 153269, - 153274, 153281, 153286, 153293, 153300, 153305, 153310, 153315, 153320, - 153325, 153330, 153335, 153340, 153345, 153352, 153359, 153366, 153373, - 153380, 153389, 153394, 153399, 153406, 153413, 153418, 153425, 153432, - 153439, 153446, 153453, 153460, 153465, 153470, 153475, 153480, 153485, - 153494, 153503, 153512, 153521, 153530, 153539, 153548, 153557, 153562, - 153573, 153584, 153593, 153598, 153603, 153608, 153613, 153622, 153629, - 153636, 153643, 153650, 153657, 153664, 153673, 153682, 153693, 153702, - 153713, 153722, 153729, 153738, 153749, 153758, 153767, 153776, 153785, - 153792, 153799, 153806, 153815, 153824, 153835, 153844, 153853, 153864, - 153869, 153874, 153885, 153893, 153902, 153911, 153920, 153931, 153940, - 153949, 153960, 153971, 153982, 153993, 154004, 154015, 154022, 154029, - 154036, 154043, 154054, 154063, 154070, 154077, 154084, 154095, 154106, - 154117, 154128, 154139, 154150, 154161, 154172, 154179, 154186, 154195, - 154204, 154211, 154218, 154225, 154234, 154243, 154252, 154259, 154268, - 154277, 154286, 154293, 154300, 154305, 154311, 154318, 154325, 154332, - 154339, 154346, 154353, 154362, 154371, 154380, 154389, 154396, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 154405, 154411, 154416, 154421, 154428, 154434, - 154440, 154446, 154452, 154458, 154464, 154470, 154474, 154478, 154484, - 154490, 154496, 154500, 154505, 154510, 154514, 154518, 154522, 154528, - 154534, 154540, 154546, 154552, 154558, 154564, 154570, 154576, 154586, - 154596, 154602, 154608, 154618, 154628, 154634, 0, 0, 154640, 154648, - 154653, 154658, 154664, 154670, 154676, 154682, 154688, 154694, 154701, - 154708, 154714, 154720, 154726, 154732, 154738, 154744, 154750, 154756, - 154761, 154767, 154773, 154779, 154785, 154791, 154800, 154806, 154811, - 154819, 154826, 154833, 154842, 154851, 154860, 154869, 154878, 154887, - 154896, 154905, 154915, 154925, 154933, 154941, 154950, 154959, 154965, - 154971, 154977, 154983, 154991, 154999, 155003, 155009, 155014, 155020, - 155026, 155032, 155038, 155044, 155053, 155058, 155065, 155070, 155075, - 155080, 155086, 155092, 155098, 155105, 155110, 155115, 155120, 155125, - 155130, 155136, 155142, 155148, 155154, 155160, 155166, 155172, 155178, - 155183, 155188, 155193, 155198, 155203, 155208, 155213, 155218, 155224, - 155230, 155235, 155240, 155245, 155250, 155255, 155261, 155268, 155272, - 155276, 155280, 155284, 155288, 155292, 155296, 155300, 155308, 155318, - 155322, 155326, 155332, 155338, 155344, 155350, 155356, 155362, 155368, - 155374, 155380, 155386, 155392, 155398, 155404, 155410, 155414, 155418, - 155425, 155431, 155437, 155443, 155448, 155455, 155460, 155466, 155472, - 155478, 155484, 155489, 155493, 155499, 155503, 155507, 155511, 155517, - 155523, 155527, 155533, 155539, 155545, 155551, 155557, 155565, 155573, - 155579, 155585, 155591, 155597, 155609, 155621, 155635, 155647, 155659, - 155673, 155687, 155701, 155705, 155713, 155721, 155726, 155730, 155734, - 155738, 155742, 155746, 155750, 155754, 155760, 155766, 155772, 155778, - 155786, 155795, 155802, 155809, 155817, 155824, 155836, 155848, 155860, - 155872, 155879, 155883, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 155887, 155894, 155901, 155908, 155915, 155922, 155929, - 155936, 155943, 155950, 155957, 155964, 155971, 155978, 155985, 155992, - 155999, 156006, 156013, 156020, 156027, 156034, 156041, 156048, 156055, - 156062, 156069, 156076, 156083, 156090, 156097, 156104, 156111, 156118, - 156125, 156132, 156139, 156146, 156153, 156160, 156167, 156174, 156181, - 156188, 156195, 156202, 156209, 156216, 156223, 156230, 156237, 156244, - 156251, 156258, 156265, 156272, 156279, 156286, 156293, 156300, 156307, - 156314, 156321, 156328, 156335, 156342, 156349, 156354, 156359, 156364, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 157197, 157203, 157208, 157213, 157218, + 157223, 157228, 157233, 157238, 157243, 157248, 157254, 157260, 157266, + 157272, 157278, 157284, 157290, 157296, 157302, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 157308, 157314, 157319, 157324, 157329, 157334, 157339, + 157344, 157349, 157354, 157359, 157365, 157371, 157377, 157383, 157389, + 157395, 157401, 157407, 157413, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 157419, 157424, 157431, 157438, 157445, 157452, 157457, 157462, 157469, + 157474, 157479, 157486, 157491, 157496, 157501, 157508, 157517, 157522, + 157527, 157532, 157537, 157542, 157547, 157554, 157559, 157564, 157569, + 157574, 157579, 157584, 157589, 157594, 157599, 157604, 157609, 157614, + 157620, 157625, 157630, 157635, 157640, 157645, 157650, 157655, 157660, + 157665, 157674, 157679, 157687, 157692, 157697, 157702, 157707, 157712, + 157717, 157722, 157731, 157736, 157741, 157746, 157751, 157756, 157763, + 157768, 157775, 157780, 157785, 157790, 157795, 157800, 157805, 157810, + 157815, 157820, 157825, 157830, 157835, 157840, 157845, 157850, 157855, + 157860, 157865, 157870, 157879, 157884, 157889, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 157894, 157902, 157910, 157918, 157926, 157934, 157942, 157950, + 157958, 157966, 157974, 157982, 157990, 157998, 158006, 158014, 158022, + 158030, 158038, 158043, 158048, 158053, 158058, 158063, 158067, 0, 0, 0, + 0, 0, 0, 0, 158071, 158075, 158080, 158085, 158090, 158094, 158099, + 158104, 158109, 158113, 158118, 158123, 158127, 158132, 158137, 158141, + 158146, 158151, 158155, 158160, 158165, 158169, 158174, 158179, 158184, + 158189, 158194, 158198, 158203, 158208, 158213, 158217, 158222, 158227, + 158232, 158236, 158241, 158246, 158250, 158255, 158260, 158264, 158269, + 158274, 158278, 158283, 158288, 158292, 158297, 158302, 158307, 158312, + 158317, 158321, 158326, 158331, 158336, 158340, 158345, 158350, 158355, + 158359, 158364, 158369, 158373, 158378, 158383, 158387, 158392, 158397, + 158401, 158406, 158411, 158415, 158420, 158425, 158430, 158435, 158440, + 158444, 158449, 158454, 158459, 158463, 158468, 0, 158473, 158477, + 158482, 158487, 158491, 158496, 158501, 158505, 158510, 158515, 158519, + 158524, 158529, 158533, 158538, 158543, 158548, 158553, 158558, 158563, + 158569, 158575, 158581, 158586, 158592, 158598, 158604, 158609, 158615, + 158621, 158626, 158632, 158638, 158643, 158649, 158655, 158660, 158666, + 158672, 158677, 158683, 158689, 158695, 158701, 158707, 158712, 158718, + 158724, 158730, 158735, 158741, 158747, 158753, 158758, 158764, 158770, + 158775, 158781, 158787, 158792, 158798, 158804, 158809, 158815, 158821, + 158826, 158832, 158838, 158844, 158850, 158856, 0, 158860, 158865, 0, 0, + 158870, 0, 0, 158875, 158880, 0, 0, 158885, 158890, 158894, 158899, 0, + 158904, 158909, 158914, 158918, 158923, 158928, 158933, 158938, 158943, + 158947, 158952, 158957, 0, 158962, 0, 158967, 158972, 158976, 158981, + 158986, 158990, 158995, 0, 159000, 159005, 159010, 159014, 159019, + 159024, 159028, 159033, 159038, 159043, 159048, 159053, 159058, 159064, + 159070, 159076, 159081, 159087, 159093, 159099, 159104, 159110, 159116, + 159121, 159127, 159133, 159138, 159144, 159150, 159155, 159161, 159167, + 159172, 159178, 159184, 159190, 159196, 159202, 159207, 159213, 159219, + 159225, 159230, 159236, 159242, 159248, 159253, 159259, 159265, 159270, + 159276, 159282, 159287, 159293, 159299, 159304, 159310, 159316, 159321, + 159327, 159333, 159339, 159345, 159351, 159356, 0, 159362, 159368, + 159373, 159379, 0, 0, 159385, 159391, 159397, 159402, 159408, 159414, + 159419, 159425, 0, 159431, 159437, 159443, 159448, 159454, 159460, + 159466, 0, 159472, 159477, 159483, 159489, 159495, 159500, 159506, + 159512, 159518, 159523, 159529, 159535, 159540, 159546, 159552, 159557, + 159563, 159569, 159574, 159580, 159586, 159591, 159597, 159603, 159609, + 159615, 159621, 159626, 0, 159632, 159638, 159643, 159649, 0, 159655, + 159660, 159666, 159672, 159677, 0, 159683, 0, 0, 0, 159688, 159694, + 159700, 159705, 159711, 159717, 159723, 0, 159729, 159734, 159740, + 159746, 159752, 159757, 159763, 159769, 159775, 159780, 159786, 159792, + 159797, 159803, 159809, 159814, 159820, 159826, 159831, 159837, 159843, + 159848, 159854, 159860, 159866, 159872, 159878, 159884, 159891, 159898, + 159905, 159911, 159918, 159925, 159932, 159938, 159945, 159952, 159958, + 159965, 159972, 159978, 159985, 159992, 159998, 160005, 160012, 160018, + 160025, 160032, 160039, 160046, 160053, 160059, 160066, 160073, 160080, + 160086, 160093, 160100, 160107, 160113, 160120, 160127, 160133, 160140, + 160147, 160153, 160160, 160167, 160173, 160180, 160187, 160193, 160200, + 160207, 160214, 160221, 160228, 160232, 160237, 160242, 160247, 160251, + 160256, 160261, 160266, 160270, 160275, 160280, 160284, 160289, 160294, + 160298, 160303, 160308, 160312, 160317, 160322, 160326, 160331, 160336, + 160341, 160346, 160351, 160355, 160360, 160365, 160370, 160374, 160379, + 160384, 160389, 160393, 160398, 160403, 160407, 160412, 160417, 160421, + 160426, 160431, 160435, 160440, 160445, 160449, 160454, 160459, 160464, + 160469, 160474, 160479, 160485, 160491, 160497, 160502, 160508, 160514, + 160520, 160525, 160531, 160537, 160542, 160548, 160554, 160559, 160565, + 160571, 160576, 160582, 160588, 160593, 160599, 160605, 160611, 160617, + 160623, 160628, 160634, 160640, 160646, 160651, 160657, 160663, 160669, + 160674, 160680, 160686, 160691, 160697, 160703, 160708, 160714, 160720, + 160725, 160731, 160737, 160742, 160748, 160754, 160760, 160766, 160772, + 160777, 160783, 160789, 160795, 160800, 160806, 160812, 160818, 160823, + 160829, 160835, 160840, 160846, 160852, 160857, 160863, 160869, 160874, + 160880, 160886, 160891, 160897, 160903, 160909, 160915, 160921, 160926, + 160932, 160938, 160944, 160949, 160955, 160961, 160967, 160972, 160978, + 160984, 160989, 160995, 161001, 161006, 161012, 161018, 161023, 161029, + 161035, 161040, 161046, 161052, 161058, 161064, 161070, 161076, 161083, + 161090, 161097, 161103, 161110, 161117, 161124, 161130, 161137, 161144, + 161150, 161157, 161164, 161170, 161177, 161184, 161190, 161197, 161204, + 161210, 161217, 161224, 161231, 161238, 161245, 161251, 161258, 161265, + 161272, 161278, 161285, 161292, 161299, 161305, 161312, 161319, 161325, + 161332, 161339, 161345, 161352, 161359, 161365, 161372, 161379, 161385, + 161392, 161399, 161406, 161413, 161420, 161425, 161431, 161437, 161443, + 161448, 161454, 161460, 161466, 161471, 161477, 161483, 161488, 161494, + 161500, 161505, 161511, 161517, 161522, 161528, 161534, 161539, 161545, + 161551, 161557, 161563, 161569, 161574, 161580, 161586, 161592, 161597, + 161603, 161609, 161615, 161620, 161626, 161632, 161637, 161643, 161649, + 161654, 161660, 161666, 161671, 161677, 161683, 161688, 161694, 161700, + 161706, 161712, 161718, 161724, 0, 0, 161731, 161736, 161741, 161746, + 161751, 161756, 161761, 161766, 161771, 161776, 161781, 161786, 161791, + 161796, 161801, 161806, 161811, 161816, 161822, 161827, 161832, 161837, + 161842, 161847, 161852, 161857, 161861, 161866, 161871, 161876, 161881, + 161886, 161891, 161896, 161901, 161906, 161911, 161916, 161921, 161926, + 161931, 161936, 161941, 161946, 161952, 161957, 161962, 161967, 161972, + 161977, 161982, 161987, 161993, 161998, 162003, 162008, 162013, 162018, + 162023, 162028, 162033, 162038, 162043, 162048, 162053, 162058, 162063, + 162068, 162073, 162078, 162083, 162088, 162093, 162098, 162103, 162108, + 162114, 162119, 162124, 162129, 162134, 162139, 162144, 162149, 162153, + 162158, 162163, 162168, 162173, 162178, 162183, 162188, 162193, 162198, + 162203, 162208, 162213, 162218, 162223, 162228, 162233, 162238, 162244, + 162249, 162254, 162259, 162264, 162269, 162274, 162279, 162285, 162290, + 162295, 162300, 162305, 162310, 162315, 162321, 162327, 162333, 162339, + 162345, 162351, 162357, 162363, 162369, 162375, 162381, 162387, 162393, + 162399, 162405, 162411, 162417, 162424, 162430, 162436, 162442, 162448, + 162454, 162460, 162466, 162471, 162477, 162483, 162489, 162495, 162501, + 162507, 162513, 162519, 162525, 162531, 162537, 162543, 162549, 162555, + 162561, 162567, 162573, 162580, 162586, 162592, 162598, 162604, 162610, + 162616, 162622, 162629, 162635, 162641, 162647, 162653, 162659, 162665, + 162671, 162677, 162683, 162689, 162695, 162701, 162707, 162713, 162719, + 162725, 162731, 162737, 162743, 162749, 162755, 162761, 162767, 162774, + 162780, 162786, 162792, 162798, 162804, 162810, 162816, 162821, 162827, + 162833, 162839, 162845, 162851, 162857, 162863, 162869, 162875, 162881, + 162887, 162893, 162899, 162905, 162911, 162917, 162923, 162930, 162936, + 162942, 162948, 162954, 162960, 162966, 162972, 162979, 162985, 162991, + 162997, 163003, 163009, 163015, 163022, 163029, 163036, 163043, 163050, + 163057, 163064, 163071, 163078, 163085, 163092, 163099, 163106, 163113, + 163120, 163127, 163134, 163142, 163149, 163156, 163163, 163170, 163177, + 163184, 163191, 163197, 163204, 163211, 163218, 163225, 163232, 163239, + 163246, 163253, 163260, 163267, 163274, 163281, 163288, 163295, 163302, + 163309, 163316, 163324, 163331, 163338, 163345, 163352, 163359, 163366, + 163373, 163381, 163388, 163395, 163402, 163409, 163416, 163423, 163428, + 0, 0, 163433, 163438, 163442, 163446, 163450, 163454, 163458, 163462, + 163466, 163470, 163474, 163480, 163485, 163490, 163495, 163500, 163505, + 163510, 163515, 163520, 163525, 163530, 163534, 163538, 163542, 163546, + 163550, 163554, 163558, 163562, 163566, 163572, 163577, 163582, 163587, + 163592, 163597, 163602, 163607, 163612, 163617, 163623, 163628, 163633, + 163638, 163643, 163648, 163653, 163658, 163663, 163668, 163672, 163677, + 163682, 163687, 163692, 163697, 163702, 163708, 163716, 163723, 163728, + 163733, 163740, 163746, 163751, 163757, 163763, 163771, 163777, 163784, + 163792, 163798, 163807, 163816, 163824, 163832, 163838, 163845, 163853, + 163861, 163867, 163874, 163883, 163892, 163899, 163910, 163920, 163930, + 163940, 163950, 163957, 163964, 163971, 163978, 163987, 163996, 164007, + 164018, 164027, 164036, 164047, 164056, 164065, 164076, 164085, 164094, + 164102, 164110, 164121, 164132, 164140, 164149, 164158, 164165, 164176, + 164187, 164196, 164205, 164212, 164221, 164230, 164239, 164250, 164259, + 164269, 164278, 164287, 164298, 164311, 164326, 164337, 164350, 164362, + 164371, 164382, 164393, 164402, 164413, 164427, 164442, 164445, 164454, + 164459, 164465, 164473, 164479, 164485, 164494, 164501, 164511, 164523, + 164530, 164533, 164539, 164546, 164552, 164557, 164560, 164565, 164568, + 164576, 164582, 164591, 164598, 164606, 164612, 164617, 164620, 164623, + 164626, 164632, 164639, 164645, 164650, 164658, 164661, 164666, 164674, + 164680, 164689, 164696, 164706, 164715, 164718, 164724, 164731, 164738, + 164745, 164750, 164758, 164766, 164775, 164781, 164790, 164799, 164808, + 164814, 164823, 164830, 164837, 164844, 164852, 164858, 164866, 164872, + 164879, 164886, 164894, 164905, 164915, 164921, 164928, 164935, 164942, + 164948, 164955, 164962, 164967, 164974, 164982, 164991, 164997, 165009, + 165020, 165026, 165034, 165040, 165047, 165054, 165061, 165067, 165074, + 165083, 165089, 165095, 165102, 165109, 165117, 165127, 165137, 165147, + 165157, 165165, 165173, 165183, 165191, 165196, 165201, 165206, 165212, + 165219, 165226, 165232, 165238, 165243, 165250, 165258, 165268, 165276, + 165284, 165294, 165304, 165312, 165322, 165332, 165344, 165356, 165368, + 165378, 165384, 165390, 165397, 165406, 165415, 165424, 165433, 165443, + 165452, 165461, 165470, 165475, 165481, 165490, 165500, 165509, 165515, + 165521, 165528, 165535, 165542, 165548, 165555, 165562, 165569, 165575, + 165579, 165584, 165591, 165598, 165605, 165610, 165618, 165626, 165635, + 165643, 165650, 165658, 165667, 165677, 165680, 165684, 165689, 165694, + 165699, 165704, 165709, 165714, 165719, 165724, 165729, 165734, 165739, + 165744, 165749, 165754, 165759, 165764, 165769, 165776, 165782, 165789, + 165795, 165800, 165807, 165813, 165820, 165826, 165831, 165838, 165845, + 165852, 165858, 165864, 165873, 165882, 165892, 165899, 165906, 165915, + 165924, 165933, 165942, 165951, 165957, 165965, 165971, 165981, 165986, + 165995, 166004, 166011, 166022, 166029, 166036, 166043, 166050, 166057, + 166064, 166071, 166078, 166085, 166092, 166098, 166104, 166110, 166117, + 166124, 166131, 166138, 166145, 166152, 166159, 166166, 166173, 166180, + 166187, 166194, 166199, 166208, 166217, 166226, 166233, 166240, 166247, + 166254, 166261, 166268, 166275, 166282, 166291, 166300, 166309, 166318, + 166327, 166336, 166345, 166354, 166363, 166372, 166381, 166390, 166399, + 166405, 166413, 166419, 166429, 166434, 166443, 166452, 166461, 166472, + 166477, 166484, 166491, 166498, 166503, 166509, 166515, 166521, 166528, + 166535, 166542, 166549, 166556, 166563, 166570, 166577, 166584, 166591, + 166598, 166605, 166610, 166619, 166628, 166637, 166646, 166655, 166664, + 166673, 166682, 166693, 166704, 166711, 166718, 166725, 166732, 166739, + 166746, 166754, 166764, 166774, 166784, 166795, 166806, 166817, 166826, + 166835, 166844, 166849, 166854, 166859, 166864, 166875, 166886, 166897, + 166908, 166919, 166929, 166940, 166949, 166958, 166967, 166976, 166985, + 166993, 167002, 167013, 167024, 167035, 167046, 167057, 167069, 167082, + 167094, 167107, 167119, 167132, 167144, 167157, 167168, 167179, 167188, + 167196, 167205, 167216, 167227, 167239, 167252, 167266, 167281, 167293, + 167306, 167318, 167331, 167342, 167353, 167362, 167370, 167379, 167386, + 167393, 167400, 167407, 167414, 167421, 167428, 167435, 167442, 167449, + 167454, 167459, 167464, 167471, 167481, 167492, 167502, 167513, 167527, + 167542, 167557, 167571, 167586, 167601, 167612, 167623, 167636, 167649, + 167658, 167667, 167680, 167693, 167700, 167707, 167712, 167717, 167722, + 167727, 167732, 167739, 167748, 167753, 167756, 167761, 167768, 167775, + 167782, 167789, 167796, 167803, 167816, 167830, 167845, 167852, 167859, + 167866, 167875, 167883, 167891, 167900, 167905, 167910, 167915, 167920, + 167925, 167930, 167937, 167944, 167950, 167957, 167963, 167970, 167975, + 167980, 167985, 167990, 167995, 168002, 168009, 168014, 168021, 168028, + 168033, 168038, 168043, 168048, 168053, 168058, 168065, 168072, 168079, + 168082, 168087, 168092, 168097, 168102, 168109, 168116, 168124, 168132, + 168137, 168142, 168149, 168156, 168163, 168168, 168175, 168182, 168187, + 168194, 168201, 168208, 168215, 168222, 168229, 168238, 168247, 168254, + 168263, 168272, 168277, 168284, 168291, 168296, 168303, 168310, 168317, + 168324, 168331, 168336, 168343, 168350, 168359, 168366, 168375, 168386, + 168395, 168404, 168413, 168422, 168425, 168430, 168437, 168446, 168453, + 168462, 168469, 168474, 168479, 168482, 168485, 168488, 168495, 168502, + 168511, 168520, 168529, 168536, 168543, 168548, 168560, 168565, 168570, + 168575, 168580, 168585, 168590, 168595, 168600, 168603, 168608, 168613, + 168618, 168623, 168628, 168635, 168640, 168647, 168650, 168655, 168658, + 168661, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 168664, 168669, + 168674, 168679, 168684, 0, 168689, 168694, 168699, 168704, 168709, + 168714, 168719, 168724, 168729, 168734, 168739, 168744, 168749, 168754, + 168759, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 168764, 168774, 168782, 168789, 168796, + 168805, 168814, 168823, 168830, 168844, 168856, 168866, 168874, 168886, + 168895, 168906, 168915, 168922, 168930, 168941, 168953, 168962, 168972, + 168984, 168995, 169004, 169015, 169027, 169035, 169046, 169055, 0, 0, 0, + 0, 0, 0, 169063, 169073, 169083, 169093, 169103, 169113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156368, 156374, 156379, 156384, 156389, - 156394, 156399, 156404, 156409, 156414, 156419, 156425, 156431, 156437, - 156443, 156449, 156455, 156461, 156467, 156473, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 156479, 156484, 156491, 156498, 156505, 156512, 156517, - 156522, 156529, 156534, 156539, 156546, 156551, 156556, 156561, 156568, - 156577, 156582, 156587, 156592, 156597, 156602, 156607, 156614, 156619, - 156624, 156629, 156634, 156639, 156644, 156649, 156654, 156659, 156664, - 156669, 156674, 156680, 156685, 156690, 156695, 156700, 156705, 156710, - 156715, 156720, 156725, 156734, 156739, 156747, 156752, 156757, 156762, - 156767, 156772, 156777, 156782, 156791, 156796, 156801, 156806, 156811, - 156816, 156823, 156828, 156835, 156840, 156845, 156850, 156855, 156860, - 156865, 156870, 156875, 156880, 156885, 156890, 156895, 156900, 156905, - 156910, 156915, 156920, 156925, 156930, 156939, 156944, 156949, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 156954, 156962, 156970, 156978, 156986, 156994, 157002, - 157010, 157018, 157026, 157034, 157042, 157050, 157058, 157066, 157074, - 157082, 157090, 157098, 157103, 157108, 157113, 157118, 157123, 157127, - 0, 0, 0, 0, 0, 0, 0, 157131, 157135, 157140, 157145, 157150, 157154, - 157159, 157164, 157169, 157173, 157178, 157183, 157187, 157192, 157197, - 157201, 157206, 157211, 157215, 157220, 157225, 157229, 157234, 157239, - 157244, 157249, 157254, 157258, 157263, 157268, 157273, 157277, 157282, - 157287, 157292, 157296, 157301, 157306, 157310, 157315, 157320, 157324, - 157329, 157334, 157338, 157343, 157348, 157352, 157357, 157362, 157367, - 157372, 157377, 157381, 157386, 157391, 157396, 157400, 157405, 157410, - 157415, 157419, 157424, 157429, 157433, 157438, 157443, 157447, 157452, - 157457, 157461, 157466, 157471, 157475, 157480, 157485, 157490, 157495, - 157500, 157504, 157509, 157514, 157519, 157523, 157528, 0, 157533, - 157537, 157542, 157547, 157551, 157556, 157561, 157565, 157570, 157575, - 157579, 157584, 157589, 157593, 157598, 157603, 157608, 157613, 157618, - 157623, 157629, 157635, 157641, 157646, 157652, 157658, 157664, 157669, - 157675, 157681, 157686, 157692, 157698, 157703, 157709, 157715, 157720, - 157726, 157732, 157737, 157743, 157749, 157755, 157761, 157767, 157772, - 157778, 157784, 157790, 157795, 157801, 157807, 157813, 157818, 157824, - 157830, 157835, 157841, 157847, 157852, 157858, 157864, 157869, 157875, - 157881, 157886, 157892, 157898, 157904, 157910, 157916, 0, 157920, - 157925, 0, 0, 157930, 0, 0, 157935, 157940, 0, 0, 157945, 157950, 157954, - 157959, 0, 157964, 157969, 157974, 157978, 157983, 157988, 157993, - 157998, 158003, 158007, 158012, 158017, 0, 158022, 0, 158027, 158032, - 158036, 158041, 158046, 158050, 158055, 0, 158060, 158065, 158070, - 158074, 158079, 158084, 158088, 158093, 158098, 158103, 158108, 158113, - 158118, 158124, 158130, 158136, 158141, 158147, 158153, 158159, 158164, - 158170, 158176, 158181, 158187, 158193, 158198, 158204, 158210, 158215, - 158221, 158227, 158232, 158238, 158244, 158250, 158256, 158262, 158267, - 158273, 158279, 158285, 158290, 158296, 158302, 158308, 158313, 158319, - 158325, 158330, 158336, 158342, 158347, 158353, 158359, 158364, 158370, - 158376, 158381, 158387, 158393, 158399, 158405, 158411, 158416, 0, - 158422, 158428, 158433, 158439, 0, 0, 158445, 158451, 158457, 158462, - 158468, 158474, 158479, 158485, 0, 158491, 158497, 158503, 158508, - 158514, 158520, 158526, 0, 158532, 158537, 158543, 158549, 158555, - 158560, 158566, 158572, 158578, 158583, 158589, 158595, 158600, 158606, - 158612, 158617, 158623, 158629, 158634, 158640, 158646, 158651, 158657, - 158663, 158669, 158675, 158681, 158686, 0, 158692, 158698, 158703, - 158709, 0, 158715, 158720, 158726, 158732, 158737, 0, 158743, 0, 0, 0, - 158748, 158754, 158760, 158765, 158771, 158777, 158783, 0, 158789, - 158794, 158800, 158806, 158812, 158817, 158823, 158829, 158835, 158840, - 158846, 158852, 158857, 158863, 158869, 158874, 158880, 158886, 158891, - 158897, 158903, 158908, 158914, 158920, 158926, 158932, 158938, 158944, - 158951, 158958, 158965, 158971, 158978, 158985, 158992, 158998, 159005, - 159012, 159018, 159025, 159032, 159038, 159045, 159052, 159058, 159065, - 159072, 159078, 159085, 159092, 159099, 159106, 159113, 159119, 159126, - 159133, 159140, 159146, 159153, 159160, 159167, 159173, 159180, 159187, - 159193, 159200, 159207, 159213, 159220, 159227, 159233, 159240, 159247, - 159253, 159260, 159267, 159274, 159281, 159288, 159292, 159297, 159302, - 159307, 159311, 159316, 159321, 159326, 159330, 159335, 159340, 159344, - 159349, 159354, 159358, 159363, 159368, 159372, 159377, 159382, 159386, - 159391, 159396, 159401, 159406, 159411, 159415, 159420, 159425, 159430, - 159434, 159439, 159444, 159449, 159453, 159458, 159463, 159467, 159472, - 159477, 159481, 159486, 159491, 159495, 159500, 159505, 159509, 159514, - 159519, 159524, 159529, 159534, 159539, 159545, 159551, 159557, 159562, - 159568, 159574, 159580, 159585, 159591, 159597, 159602, 159608, 159614, - 159619, 159625, 159631, 159636, 159642, 159648, 159653, 159659, 159665, - 159671, 159677, 159683, 159688, 159694, 159700, 159706, 159711, 159717, - 159723, 159729, 159734, 159740, 159746, 159751, 159757, 159763, 159768, - 159774, 159780, 159785, 159791, 159797, 159802, 159808, 159814, 159820, - 159826, 159832, 159837, 159843, 159849, 159855, 159860, 159866, 159872, - 159878, 159883, 159889, 159895, 159900, 159906, 159912, 159917, 159923, - 159929, 159934, 159940, 159946, 159951, 159957, 159963, 159969, 159975, - 159981, 159986, 159992, 159998, 160004, 160009, 160015, 160021, 160027, - 160032, 160038, 160044, 160049, 160055, 160061, 160066, 160072, 160078, - 160083, 160089, 160095, 160100, 160106, 160112, 160118, 160124, 160130, - 160136, 160143, 160150, 160157, 160163, 160170, 160177, 160184, 160190, - 160197, 160204, 160210, 160217, 160224, 160230, 160237, 160244, 160250, - 160257, 160264, 160270, 160277, 160284, 160291, 160298, 160305, 160311, - 160318, 160325, 160332, 160338, 160345, 160352, 160359, 160365, 160372, - 160379, 160385, 160392, 160399, 160405, 160412, 160419, 160425, 160432, - 160439, 160445, 160452, 160459, 160466, 160473, 160480, 160485, 160491, - 160497, 160503, 160508, 160514, 160520, 160526, 160531, 160537, 160543, - 160548, 160554, 160560, 160565, 160571, 160577, 160582, 160588, 160594, - 160599, 160605, 160611, 160617, 160623, 160629, 160634, 160640, 160646, - 160652, 160657, 160663, 160669, 160675, 160680, 160686, 160692, 160697, - 160703, 160709, 160714, 160720, 160726, 160731, 160737, 160743, 160748, - 160754, 160760, 160766, 160772, 160778, 160784, 0, 0, 160791, 160796, - 160801, 160806, 160811, 160816, 160821, 160826, 160831, 160836, 160841, - 160846, 160851, 160856, 160861, 160866, 160871, 160876, 160882, 160887, - 160892, 160897, 160902, 160907, 160912, 160917, 160921, 160926, 160931, - 160936, 160941, 160946, 160951, 160956, 160961, 160966, 160971, 160976, - 160981, 160986, 160991, 160996, 161001, 161006, 161012, 161017, 161022, - 161027, 161032, 161037, 161042, 161047, 161053, 161058, 161063, 161068, - 161073, 161078, 161083, 161088, 161093, 161098, 161103, 161108, 161113, - 161118, 161123, 161128, 161133, 161138, 161143, 161148, 161153, 161158, - 161163, 161168, 161174, 161179, 161184, 161189, 161194, 161199, 161204, - 161209, 161213, 161218, 161223, 161228, 161233, 161238, 161243, 161248, - 161253, 161258, 161263, 161268, 161273, 161278, 161283, 161288, 161293, - 161298, 161304, 161309, 161314, 161319, 161324, 161329, 161334, 161339, - 161345, 161350, 161355, 161360, 161365, 161370, 161375, 161381, 161387, - 161393, 161399, 161405, 161411, 161417, 161423, 161429, 161435, 161441, - 161447, 161453, 161459, 161465, 161471, 161477, 161484, 161490, 161496, - 161502, 161508, 161514, 161520, 161526, 161531, 161537, 161543, 161549, - 161555, 161561, 161567, 161573, 161579, 161585, 161591, 161597, 161603, - 161609, 161615, 161621, 161627, 161633, 161640, 161646, 161652, 161658, - 161664, 161670, 161676, 161682, 161689, 161695, 161701, 161707, 161713, - 161719, 161725, 161731, 161737, 161743, 161749, 161755, 161761, 161767, - 161773, 161779, 161785, 161791, 161797, 161803, 161809, 161815, 161821, - 161827, 161834, 161840, 161846, 161852, 161858, 161864, 161870, 161876, - 161881, 161887, 161893, 161899, 161905, 161911, 161917, 161923, 161929, - 161935, 161941, 161947, 161953, 161959, 161965, 161971, 161977, 161983, - 161990, 161996, 162002, 162008, 162014, 162020, 162026, 162032, 162039, - 162045, 162051, 162057, 162063, 162069, 162075, 162082, 162089, 162096, - 162103, 162110, 162117, 162124, 162131, 162138, 162145, 162152, 162159, - 162166, 162173, 162180, 162187, 162194, 162202, 162209, 162216, 162223, - 162230, 162237, 162244, 162251, 162257, 162264, 162271, 162278, 162285, - 162292, 162299, 162306, 162313, 162320, 162327, 162334, 162341, 162348, - 162355, 162362, 162369, 162376, 162384, 162391, 162398, 162405, 162412, - 162419, 162426, 162433, 162441, 162448, 162455, 162462, 162469, 162476, - 162483, 162488, 0, 0, 162493, 162498, 162502, 162506, 162510, 162514, - 162518, 162522, 162526, 162530, 162534, 162540, 162545, 162550, 162555, - 162560, 162565, 162570, 162575, 162580, 162585, 162590, 162594, 162598, - 162602, 162606, 162610, 162614, 162618, 162622, 162626, 162632, 162637, - 162642, 162647, 162652, 162657, 162662, 162667, 162672, 162677, 162683, - 162688, 162693, 162698, 162703, 162708, 162713, 162718, 162723, 162728, - 162732, 162737, 162742, 162747, 162752, 162757, 162762, 162768, 162776, - 162783, 162788, 162793, 162800, 162806, 162811, 162817, 162823, 162831, - 162837, 162844, 162852, 162858, 162867, 162876, 162884, 162892, 162898, - 162905, 162913, 162921, 162927, 162934, 162943, 162952, 162959, 162970, - 162980, 162990, 163000, 163010, 163017, 163024, 163031, 163038, 163047, - 163056, 163067, 163078, 163087, 163096, 163107, 163116, 163125, 163136, - 163145, 163154, 163162, 163170, 163181, 163192, 163200, 163209, 163218, - 163225, 163236, 163247, 163256, 163265, 163272, 163281, 163290, 163299, - 163310, 163319, 163329, 163338, 163347, 163358, 163371, 163386, 163397, - 163410, 163422, 163431, 163442, 163453, 163462, 163473, 163487, 163502, - 163505, 163514, 163519, 163525, 163533, 163539, 163545, 163554, 163561, - 163571, 163583, 163590, 163593, 163599, 163606, 163612, 163617, 163620, - 163625, 163628, 163636, 163642, 163651, 163658, 163666, 163672, 163677, - 163680, 163683, 163686, 163692, 163699, 163705, 163710, 163718, 163721, - 163726, 163734, 163740, 163749, 163756, 163766, 163775, 163778, 163784, - 163791, 163798, 163805, 163810, 163818, 163826, 163835, 163841, 163850, - 163859, 163868, 163874, 163883, 163890, 163897, 163904, 163912, 163918, - 163926, 163932, 163939, 163946, 163954, 163965, 163975, 163981, 163988, - 163995, 164002, 164008, 164015, 164022, 164027, 164034, 164042, 164051, - 164057, 164069, 164080, 164086, 164094, 164100, 164107, 164114, 164121, - 164127, 164134, 164143, 164149, 164155, 164162, 164169, 164177, 164187, - 164197, 164207, 164217, 164225, 164233, 164243, 164251, 164256, 164261, - 164266, 164272, 164279, 164286, 164292, 164298, 164303, 164310, 164318, - 164328, 164336, 164344, 164354, 164364, 164372, 164382, 164392, 164404, - 164416, 164428, 164438, 164444, 164450, 164457, 164466, 164475, 164484, - 164493, 164503, 164512, 164521, 164530, 164535, 164541, 164550, 164560, - 164569, 164575, 164581, 164588, 164595, 164602, 164608, 164615, 164622, - 164629, 164635, 164639, 164644, 164651, 164658, 164665, 164670, 164678, - 164686, 164695, 164703, 164710, 164718, 164727, 164737, 164740, 164744, - 164749, 164754, 164759, 164764, 164769, 164774, 164779, 164784, 164789, - 164794, 164799, 164804, 164809, 164814, 164819, 164824, 164829, 164836, - 164842, 164849, 164855, 164860, 164867, 164873, 164880, 164886, 164891, - 164898, 164905, 164912, 164918, 164924, 164933, 164942, 164952, 164959, - 164966, 164975, 164984, 164993, 165002, 165011, 165017, 165025, 165031, - 165041, 165046, 165055, 165064, 165071, 165082, 165089, 165096, 165103, - 165110, 165117, 165124, 165131, 165138, 165145, 165152, 165158, 165164, - 165170, 165177, 165184, 165191, 165198, 165205, 165212, 165219, 165226, - 165233, 165240, 165247, 165254, 165259, 165268, 165277, 165286, 165293, - 165300, 165307, 165314, 165321, 165328, 165335, 165342, 165351, 165360, - 165369, 165378, 165387, 165396, 165405, 165414, 165423, 165432, 165441, - 165450, 165459, 165465, 165473, 165479, 165489, 165494, 165503, 165512, - 165521, 165532, 165537, 165544, 165551, 165558, 165563, 165569, 165575, - 165581, 165588, 165595, 165602, 165609, 165616, 165623, 165630, 165637, - 165644, 165651, 165658, 165665, 165670, 165679, 165688, 165697, 165706, - 165715, 165724, 165733, 165742, 165753, 165764, 165771, 165778, 165785, - 165792, 165799, 165806, 165814, 165824, 165834, 165844, 165855, 165866, - 165877, 165886, 165895, 165904, 165909, 165914, 165919, 165924, 165935, - 165946, 165957, 165968, 165979, 165989, 166000, 166009, 166018, 166027, - 166036, 166045, 166053, 166062, 166073, 166084, 166095, 166106, 166117, - 166129, 166142, 166154, 166167, 166179, 166192, 166204, 166217, 166228, - 166239, 166248, 166256, 166265, 166276, 166287, 166299, 166312, 166326, - 166341, 166353, 166366, 166378, 166391, 166402, 166413, 166422, 166430, - 166439, 166446, 166453, 166460, 166467, 166474, 166481, 166488, 166495, - 166502, 166509, 166514, 166519, 166524, 166531, 166541, 166552, 166562, - 166573, 166587, 166602, 166617, 166631, 166646, 166661, 166672, 166683, - 166696, 166709, 166718, 166727, 166740, 166753, 166760, 166767, 166772, - 166777, 166782, 166787, 166792, 166799, 166808, 166813, 166816, 166821, - 166828, 166835, 166842, 166849, 166856, 166863, 166876, 166890, 166905, - 166912, 166919, 166926, 166935, 166943, 166951, 166960, 166965, 166970, - 166975, 166980, 166985, 166990, 166997, 167004, 167010, 167017, 167023, - 167030, 167035, 167040, 167045, 167050, 167055, 167062, 167069, 167074, - 167081, 167088, 167093, 167098, 167103, 167108, 167113, 167118, 167125, - 167132, 167139, 167142, 167147, 167152, 167157, 167162, 167169, 167176, - 167184, 167192, 167197, 167202, 167209, 167216, 167223, 167228, 167235, - 167242, 167247, 167254, 167261, 167268, 167275, 167282, 167289, 167298, - 167307, 167314, 167323, 167332, 167337, 167344, 167351, 167356, 167363, - 167370, 167377, 167384, 167391, 167396, 167403, 167410, 167419, 167426, - 167435, 167446, 167455, 167464, 167473, 167482, 167485, 167490, 167497, - 167506, 167513, 167522, 167529, 167534, 167539, 167542, 167545, 167548, - 167555, 167562, 167571, 167580, 167589, 167596, 167603, 167608, 167620, - 167625, 167630, 167635, 167640, 167645, 167650, 167655, 167660, 167663, - 167668, 167673, 167678, 167683, 167688, 167695, 167700, 167707, 167710, - 167715, 167718, 167721, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 167724, 167729, 167734, 167739, 167744, 0, 167749, 167754, 167759, - 167764, 167769, 167774, 167779, 167784, 167789, 167794, 167799, 167804, - 167809, 167814, 167819, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 169123, 169128, 169133, 169138, 169143, 169148, + 169153, 0, 169158, 169163, 169168, 169174, 169178, 169183, 169188, + 169193, 169198, 169203, 169208, 169213, 169218, 169223, 169228, 169233, + 169238, 0, 0, 169243, 169248, 169253, 169258, 169263, 169268, 169273, 0, + 169278, 169283, 0, 169289, 169294, 169302, 169309, 169318, 0, 0, 0, 0, 0, + 169323, 169328, 169334, 169340, 169346, 169352, 169358, 169364, 169370, + 169375, 169380, 169386, 169392, 169397, 169403, 169409, 169415, 169421, + 169426, 169432, 169437, 169443, 169449, 169455, 169461, 169466, 169472, + 169478, 169484, 169491, 169497, 169504, 169511, 169517, 169523, 169530, + 169537, 169544, 169551, 169558, 169565, 169572, 169578, 169584, 169591, + 169597, 169604, 169611, 169617, 169624, 169630, 169637, 169644, 169651, + 169659, 169666, 169676, 169684, 169691, 169698, 169707, 169718, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 167824, 167834, 167842, - 167849, 167856, 167865, 167874, 167883, 167890, 167904, 167916, 167926, - 167934, 167946, 167955, 167966, 167975, 167982, 167990, 168001, 168013, - 168022, 168032, 168044, 168055, 168064, 168075, 168087, 168095, 168106, - 168115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 169727, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 168123, 168128, 168133, 168138, 168143, 168148, 168153, 0, - 168158, 168163, 168168, 168174, 168178, 168183, 168188, 168193, 168198, - 168203, 168208, 168213, 168218, 168223, 168228, 168233, 168238, 0, 0, - 168243, 168248, 168253, 168258, 168263, 168268, 168273, 0, 168278, - 168283, 0, 168289, 168294, 168302, 168309, 168318, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 169734, 169741, 169749, 169757, 169765, 169772, 169779, 169787, 169795, + 169803, 169810, 169817, 169825, 169833, 169841, 169848, 169856, 169864, + 169872, 169880, 169888, 169896, 169904, 169911, 169919, 169926, 169934, + 169941, 169949, 169957, 169965, 169973, 169981, 169989, 169997, 170005, + 170013, 170020, 170028, 170035, 170042, 170049, 170057, 170064, 170072, + 0, 0, 0, 170080, 170087, 170094, 170101, 170108, 170115, 170122, 170129, + 170138, 170147, 170156, 170165, 170174, 170184, 0, 0, 170192, 170200, + 170207, 170214, 170221, 170228, 170235, 170242, 170249, 170256, 0, 0, 0, + 0, 170263, 170272, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 170280, + 170284, 170289, 170294, 170299, 170303, 170308, 170312, 170316, 170321, + 170325, 170330, 170334, 170339, 170344, 170348, 170352, 170356, 170360, + 170366, 170371, 170378, 170382, 170386, 170392, 170397, 170404, 170408, + 170413, 170420, 170424, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 170431, 170436, 170440, 170445, 170450, 170455, 170460, 170464, + 170469, 170473, 170477, 170481, 170486, 170491, 170496, 170500, 170505, + 170510, 170515, 170520, 170525, 170529, 170533, 170538, 170542, 170546, + 170551, 170555, 170559, 170563, 170568, 170572, 170577, 170582, 170587, + 170592, 170597, 170602, 170607, 170612, 170617, 170622, 170627, 170632, + 170637, 170642, 170647, 170652, 170657, 170662, 170666, 170670, 170674, + 170678, 170682, 170686, 170690, 170694, 0, 0, 0, 0, 0, 170698, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 168323, 168330, 168338, 168346, 168354, 168361, 168368, - 168376, 168384, 168392, 168399, 168406, 168414, 168422, 168430, 168437, - 168445, 168453, 168461, 168469, 168477, 168485, 168493, 168500, 168508, - 168515, 168523, 168530, 168538, 168546, 168554, 168562, 168570, 168578, - 168586, 168594, 168602, 168609, 168617, 168624, 168631, 168638, 168646, - 168653, 168661, 0, 0, 0, 168669, 168676, 168683, 168690, 168697, 168704, - 168711, 168718, 168727, 168736, 168745, 168754, 168763, 168773, 0, 0, - 168781, 168789, 168796, 168803, 168810, 168817, 168824, 168831, 168838, - 168845, 0, 0, 0, 0, 168852, 168861, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 168869, 168873, 168878, 168883, 168888, 168892, 168897, - 168901, 168905, 168910, 168914, 168919, 168923, 168928, 168933, 168937, - 168941, 168945, 168949, 168955, 168960, 168967, 168971, 168975, 168981, - 168986, 168993, 168997, 169002, 169009, 169013, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 169020, 169025, 169029, 169034, 169039, - 169044, 169049, 169053, 169058, 169062, 169066, 169070, 169075, 169080, - 169085, 169089, 169094, 169099, 169104, 169109, 169114, 169118, 169122, - 169127, 169131, 169135, 169140, 169144, 169148, 169152, 169157, 169161, - 169166, 169171, 169176, 169181, 169186, 169191, 169196, 169201, 169206, - 169211, 169216, 169221, 169226, 169231, 169236, 169241, 169246, 169251, - 169255, 169259, 169263, 169267, 169271, 169275, 169279, 169283, 0, 0, 0, - 0, 0, 169287, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 170703, 170709, 170716, 170723, 170730, 170737, 170743, + 170750, 170757, 170764, 170771, 170777, 170784, 170791, 170798, 170805, + 170811, 170818, 170825, 170832, 170839, 170845, 170852, 170859, 170866, + 170873, 170880, 170887, 170894, 170901, 170908, 170915, 170922, 170929, + 170935, 170941, 170947, 170953, 170959, 170965, 170971, 170977, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 169292, 169296, 169300, 169304, 169308, 169312, 169316, 0, - 169320, 169326, 169330, 169334, 0, 169338, 169344, 0, 169350, 169356, - 169362, 169368, 169374, 169380, 169386, 169392, 169398, 169404, 169410, - 169416, 169422, 169428, 169434, 0, 169440, 169447, 169453, 169460, - 169467, 169474, 169481, 169488, 169495, 169502, 169509, 169516, 169523, - 169530, 169537, 169544, 169551, 169558, 169565, 169572, 169579, 169586, - 169593, 169600, 169607, 169614, 169621, 169628, 169635, 169642, 169649, - 169656, 169663, 169670, 169677, 169683, 169689, 169695, 169702, 169708, - 169715, 169721, 169728, 169735, 169742, 169749, 169756, 169763, 169769, - 169776, 169783, 169790, 169797, 169804, 169811, 169818, 169824, 169831, - 169838, 169845, 169852, 169859, 169867, 169874, 169881, 169888, 169895, - 169902, 169909, 169916, 169923, 169930, 169937, 169944, 169951, 169957, - 169964, 169971, 169978, 169985, 169992, 169999, 170006, 170014, 170021, - 170027, 170034, 170041, 170048, 170055, 170062, 170069, 170076, 170083, - 170090, 170097, 170104, 170111, 170118, 170125, 170132, 170139, 170146, - 170153, 170160, 170167, 170173, 170180, 170187, 170194, 170201, 170208, - 170215, 170222, 170229, 170236, 170243, 170250, 170257, 170264, 170271, - 170278, 170285, 170292, 170299, 170306, 170313, 170320, 170327, 170335, - 170343, 170351, 170358, 170365, 170372, 170379, 170386, 170393, 170400, - 170407, 170414, 170421, 170427, 170434, 170441, 170448, 170455, 170462, - 170469, 170476, 170483, 170490, 170497, 170504, 170511, 170518, 170525, - 170533, 170541, 170549, 170556, 170563, 170570, 170577, 170584, 170591, - 170598, 170605, 170612, 170619, 170626, 170633, 170640, 170647, 170653, - 170660, 170667, 170674, 170681, 170688, 170695, 170702, 170709, 170716, - 170723, 170730, 170737, 170744, 170751, 170758, 170765, 170772, 170779, - 170786, 170793, 170800, 170807, 0, 0, 170814, 170818, 170822, 170826, - 170830, 170834, 170838, 170842, 170846, 170850, 170856, 170862, 170868, - 170874, 170882, 170890, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 170896, 170902, 170908, 170914, 170920, 170926, 170932, 170938, - 170944, 170949, 170954, 170960, 170965, 170970, 170976, 170982, 170988, - 170994, 171000, 171005, 171010, 171016, 171022, 171027, 171033, 171039, - 171045, 171051, 171057, 171063, 171069, 171075, 171081, 171087, 171093, - 171099, 171105, 171111, 171117, 171123, 171129, 171135, 171141, 171146, - 171151, 171157, 171162, 171167, 171173, 171179, 171185, 171191, 171197, - 171202, 171207, 171213, 171219, 171224, 171230, 171236, 171242, 171248, - 171254, 171260, 171266, 171272, 171278, 171284, 171290, 171296, 171301, - 171306, 171310, 171315, 171322, 171326, 0, 0, 0, 0, 171331, 171336, - 171340, 171344, 171348, 171352, 171356, 171360, 171364, 171368, 0, 0, 0, - 0, 171372, 171378, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 170983, 170987, 170991, 170995, 170999, 171003, 171007, 0, + 171011, 171017, 171021, 171025, 0, 171029, 171035, 0, 171041, 171047, + 171053, 171059, 171065, 171071, 171077, 171083, 171089, 171095, 171101, + 171107, 171113, 171119, 171125, 0, 171131, 171138, 171144, 171151, + 171158, 171165, 171172, 171179, 171186, 171193, 171200, 171207, 171214, + 171221, 171228, 171235, 171242, 171249, 171256, 171263, 171270, 171277, + 171284, 171291, 171298, 171305, 171312, 171319, 171326, 171333, 171340, + 171347, 171354, 171361, 171368, 171374, 171380, 171386, 171393, 171399, + 171406, 171412, 171419, 171426, 171433, 171440, 171447, 171454, 171460, + 171467, 171474, 171481, 171488, 171495, 171502, 171509, 171515, 171522, + 171529, 171536, 171543, 171550, 171558, 171565, 171572, 171579, 171586, + 171593, 171600, 171607, 171614, 171621, 171628, 171635, 171642, 171648, + 171655, 171662, 171669, 171676, 171683, 171690, 171697, 171705, 171712, + 171718, 171725, 171732, 171739, 171746, 171753, 171760, 171767, 171774, + 171781, 171788, 171795, 171802, 171809, 171816, 171823, 171830, 171837, + 171844, 171851, 171858, 171864, 171871, 171878, 171885, 171892, 171899, + 171906, 171913, 171920, 171927, 171934, 171941, 171948, 171955, 171962, + 171969, 171976, 171983, 171990, 171997, 172004, 172011, 172018, 172026, + 172034, 172042, 172049, 172056, 172063, 172070, 172077, 172084, 172091, + 172098, 172105, 172112, 172118, 172125, 172132, 172139, 172146, 172153, + 172160, 172167, 172174, 172181, 172188, 172195, 172202, 172209, 172216, + 172224, 172232, 172240, 172247, 172254, 172261, 172268, 172275, 172282, + 172289, 172296, 172303, 172310, 172317, 172324, 172331, 172338, 172344, + 172351, 172358, 172365, 172372, 172379, 172386, 172393, 172400, 172407, + 172414, 172421, 172428, 172435, 172442, 172449, 172456, 172463, 172470, + 172477, 172484, 172491, 172498, 0, 0, 172505, 172509, 172513, 172517, + 172521, 172525, 172529, 172533, 172537, 172541, 172547, 172553, 172559, + 172565, 172573, 172581, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 172587, 172593, 172599, 172605, 172611, 172617, 172623, 172629, + 172635, 172640, 172645, 172651, 172656, 172661, 172667, 172673, 172679, + 172685, 172691, 172696, 172701, 172707, 172713, 172718, 172724, 172730, + 172736, 172742, 172748, 172754, 172760, 172766, 172772, 172778, 172784, + 172790, 172796, 172802, 172808, 172814, 172820, 172826, 172832, 172837, + 172842, 172848, 172853, 172858, 172864, 172870, 172876, 172882, 172888, + 172893, 172898, 172904, 172910, 172915, 172921, 172927, 172933, 172939, + 172945, 172951, 172957, 172963, 172969, 172975, 172981, 172987, 172992, + 172997, 173001, 173006, 173013, 173017, 0, 0, 0, 0, 173022, 173027, + 173031, 173035, 173039, 173043, 173047, 173051, 173055, 173059, 0, 0, 0, + 0, 173063, 173069, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 171384, 171389, 171394, 171399, 171404, 171409, - 171414, 171419, 171424, 171429, 171435, 171441, 171447, 171453, 171459, - 171465, 171471, 171477, 171483, 171490, 171497, 171504, 171512, 171520, - 171528, 171536, 171544, 171552, 171558, 171564, 171570, 171577, 171584, - 171591, 171598, 171605, 171612, 171619, 171626, 171633, 171640, 171647, - 171654, 171661, 171668, 171675, 171681, 171687, 171693, 171699, 171705, - 171712, 171719, 171726, 171733, 171740, 171747, 171754, 171761, 171768, - 171773, 171781, 171789, 171797, 171803, 171810, 171817, 171826, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 173075, 173080, 173085, 173090, 173095, 173100, + 173105, 173110, 173115, 173120, 173126, 173132, 173138, 173144, 173150, + 173156, 173162, 173168, 173174, 173181, 173188, 173195, 173203, 173211, + 173219, 173227, 173235, 173243, 173249, 173255, 173261, 173268, 173275, + 173282, 173289, 173296, 173303, 173310, 173317, 173324, 173331, 173338, + 173345, 173352, 173359, 173366, 173372, 173378, 173384, 173390, 173396, + 173403, 173410, 173417, 173424, 173431, 173438, 173445, 173452, 173459, + 173464, 173472, 173480, 173488, 173494, 173501, 173508, 173517, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 171834, 171839, 171844, 171849, 171854, 171859, 171864, 171869, - 171874, 171879, 171885, 171891, 171897, 171903, 171909, 171915, 171921, - 171927, 171933, 171940, 171947, 171954, 171962, 171970, 171978, 171986, - 171994, 172002, 172008, 172014, 172020, 172027, 172034, 172041, 172048, - 172055, 172062, 172069, 172076, 172083, 172090, 172097, 172104, 172111, - 172118, 172125, 172130, 172137, 172144, 172151, 172158, 172165, 172172, - 172179, 172186, 172194, 172204, 172214, 172222, 172231, 172239, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 173525, 173530, 173535, 173540, 173545, 173550, 173555, 173560, + 173565, 173570, 173576, 173582, 173588, 173594, 173600, 173606, 173612, + 173618, 173624, 173631, 173638, 173645, 173653, 173661, 173669, 173677, + 173685, 173693, 173699, 173705, 173711, 173718, 173725, 173732, 173739, + 173746, 173753, 173760, 173767, 173774, 173781, 173788, 173795, 173802, + 173809, 173816, 173821, 173828, 173835, 173842, 173849, 173856, 173863, + 173870, 173877, 173885, 173895, 173905, 173913, 173922, 173930, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 172247, 172251, 172255, - 172259, 0, 172263, 172267, 172271, 172275, 172279, 172283, 172287, - 172291, 172295, 172299, 172303, 172307, 172311, 172315, 172319, 172323, - 172327, 172331, 172335, 172339, 172343, 172347, 172351, 172355, 172361, - 172367, 172373, 0, 172379, 172384, 0, 172389, 0, 0, 172394, 0, 172399, - 172404, 172409, 172414, 172419, 172424, 172429, 172434, 172439, 172444, - 0, 172449, 172454, 172459, 172464, 0, 172469, 0, 172474, 0, 0, 0, 0, 0, - 0, 172479, 0, 0, 0, 0, 172485, 0, 172491, 0, 172497, 0, 172503, 172509, - 172515, 0, 172521, 172527, 0, 172533, 0, 0, 172539, 0, 172545, 0, 172551, - 0, 172557, 0, 172565, 0, 172573, 172579, 0, 172585, 0, 0, 172591, 172597, - 172603, 172609, 0, 172615, 172621, 172627, 172633, 172639, 172645, - 172651, 0, 172657, 172663, 172669, 172675, 0, 172681, 172687, 172693, - 172699, 0, 172707, 0, 172715, 172721, 172727, 172733, 172739, 172745, - 172751, 172757, 172763, 172769, 0, 172775, 172781, 172787, 172793, - 172799, 172805, 172811, 172817, 172823, 172829, 172835, 172841, 172847, - 172853, 172859, 172865, 172871, 0, 0, 0, 0, 0, 172877, 172883, 172889, 0, - 172895, 172901, 172907, 172913, 172919, 0, 172925, 172931, 172937, - 172943, 172949, 172955, 172961, 172967, 172973, 172979, 172985, 172991, - 172997, 173003, 173009, 173015, 173021, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 173027, 173037, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 173045, 173052, 173059, 173066, - 173072, 173079, 173086, 173092, 173099, 173106, 173113, 173121, 173129, - 173137, 173145, 173153, 173161, 173168, 173175, 173182, 173190, 173198, - 173206, 173214, 173222, 173230, 173237, 173244, 173251, 173259, 173267, - 173275, 173283, 173291, 173299, 173304, 173309, 173314, 173319, 173324, - 173329, 173334, 173339, 173344, 0, 0, 0, 0, 173349, 173356, 173361, - 173366, 173371, 173376, 173381, 173386, 173391, 173396, 173401, 173406, - 173411, 173416, 173421, 173426, 173431, 173436, 173441, 173446, 173451, - 173456, 173461, 173466, 173471, 173476, 173481, 173486, 173491, 173496, - 173501, 173506, 173511, 173516, 173521, 173526, 173531, 173536, 173541, - 173546, 173551, 173556, 173561, 173566, 173571, 173576, 173581, 173586, - 173591, 173596, 173601, 173607, 173612, 173617, 173622, 173627, 173632, - 173637, 173642, 173647, 173652, 173657, 173662, 173667, 173672, 173677, - 173682, 173687, 173692, 173697, 173702, 173707, 173712, 173717, 173722, - 173727, 173732, 173737, 173742, 173747, 173752, 173757, 173762, 173767, - 173772, 173777, 173782, 173787, 173792, 173797, 173802, 173807, 173812, - 173817, 173822, 173827, 173832, 173837, 173842, 173847, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 173852, 173858, 173867, 173875, 173883, 173892, 173901, - 173910, 173919, 173928, 173937, 173946, 173955, 173964, 173973, 0, 0, - 173982, 173991, 173999, 174007, 174016, 174025, 174034, 174043, 174052, - 174061, 174070, 174079, 174088, 174097, 174106, 0, 174114, 174123, - 174131, 174139, 174148, 174157, 174166, 174175, 174184, 174193, 174202, - 174211, 174220, 174229, 174238, 0, 174245, 174254, 174262, 174270, - 174279, 174288, 174297, 174306, 174315, 174324, 174333, 174342, 174351, - 174360, 174369, 174376, 174382, 174388, 174394, 174400, 174406, 174412, - 174418, 174424, 174430, 174436, 174442, 174448, 174454, 174460, 174466, - 174472, 174478, 174484, 174490, 174496, 174502, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 174508, 174515, 174520, 174524, 174528, 174532, 174537, 174542, - 174547, 174552, 174557, 174562, 174569, 174578, 174584, 174588, 174597, - 174602, 174608, 174614, 174620, 174625, 174631, 174637, 174643, 174648, - 174654, 174660, 174665, 174671, 174677, 174682, 174688, 174694, 174699, - 174705, 174711, 174716, 174722, 174728, 174734, 174740, 174746, 174757, - 174764, 174770, 174773, 174776, 174779, 174784, 174790, 174796, 174802, - 174807, 174813, 174819, 174825, 174830, 174836, 174842, 174847, 174853, - 174859, 174864, 174870, 174876, 174881, 174887, 174893, 174898, 174904, - 174910, 174916, 174922, 174928, 174931, 174934, 174937, 174940, 174943, - 174946, 174953, 174961, 174969, 174977, 174984, 174992, 175000, 175008, - 175015, 175023, 175031, 175038, 175046, 175054, 175061, 175069, 175077, - 175084, 175092, 175100, 175107, 175115, 175123, 175131, 175139, 175147, - 175152, 175157, 175162, 175165, 175173, 175178, 175185, 175193, 175201, - 175209, 175216, 175224, 175232, 175240, 175247, 175255, 175263, 175270, - 175278, 175286, 175293, 175301, 175309, 175316, 175324, 175332, 175339, - 175347, 175355, 175363, 175371, 175379, 175389, 175394, 175398, 175402, - 175407, 175412, 175415, 175418, 175421, 175424, 175427, 175430, 175433, - 175436, 175439, 175445, 175448, 175452, 175457, 175461, 175466, 175471, - 175477, 175483, 175489, 175494, 175502, 175508, 175511, 175514, 175517, - 175520, 175523, 175526, 175529, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 173938, 173942, 173946, + 173950, 0, 173954, 173958, 173962, 173966, 173970, 173974, 173978, + 173982, 173986, 173990, 173994, 173998, 174002, 174006, 174010, 174014, + 174018, 174022, 174026, 174030, 174034, 174038, 174042, 174046, 174052, + 174058, 174064, 0, 174070, 174075, 0, 174080, 0, 0, 174085, 0, 174090, + 174095, 174100, 174105, 174110, 174115, 174120, 174125, 174130, 174135, + 0, 174140, 174145, 174150, 174155, 0, 174160, 0, 174165, 0, 0, 0, 0, 0, + 0, 174170, 0, 0, 0, 0, 174176, 0, 174182, 0, 174188, 0, 174194, 174200, + 174206, 0, 174212, 174218, 0, 174224, 0, 0, 174230, 0, 174236, 0, 174242, + 0, 174248, 0, 174256, 0, 174264, 174270, 0, 174276, 0, 0, 174282, 174288, + 174294, 174300, 0, 174306, 174312, 174318, 174324, 174330, 174336, + 174342, 0, 174348, 174354, 174360, 174366, 0, 174372, 174378, 174384, + 174390, 0, 174398, 0, 174406, 174412, 174418, 174424, 174430, 174436, + 174442, 174448, 174454, 174460, 0, 174466, 174472, 174478, 174484, + 174490, 174496, 174502, 174508, 174514, 174520, 174526, 174532, 174538, + 174544, 174550, 174556, 174562, 0, 0, 0, 0, 0, 174568, 174574, 174580, 0, + 174586, 174592, 174598, 174604, 174610, 0, 174616, 174622, 174628, + 174634, 174640, 174646, 174652, 174658, 174664, 174670, 174676, 174682, + 174688, 174694, 174700, 174706, 174712, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 175534, 175541, - 175549, 175557, 175565, 175572, 175580, 175588, 175596, 175603, 175611, - 175619, 175626, 175634, 175642, 175649, 175657, 175665, 175672, 175680, - 175688, 175695, 175703, 175711, 175719, 175727, 175735, 175740, 175744, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 175747, 175753, 175759, 175765, - 175769, 175775, 175781, 175787, 175793, 175799, 175805, 175811, 175817, - 175823, 175829, 175835, 175841, 175847, 175853, 175859, 175865, 175871, - 175877, 175883, 175889, 175895, 175901, 175907, 175913, 175919, 175925, - 175931, 175937, 175943, 175949, 175955, 175961, 175967, 175973, 175979, - 175985, 175991, 175997, 176003, 0, 0, 0, 0, 176009, 176020, 176031, - 176042, 176053, 176064, 176075, 176086, 176097, 0, 0, 0, 0, 0, 0, 0, - 176108, 176113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 176118, 176124, - 176130, 176136, 176142, 176148, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 176154, 176156, 176158, 176162, - 176167, 176172, 176174, 176180, 176185, 176187, 176193, 176197, 176199, - 176203, 176209, 176215, 176221, 176226, 176231, 176238, 176245, 176252, - 176257, 176264, 176271, 176278, 176282, 176289, 176298, 176307, 176314, - 176319, 176323, 176327, 176329, 176332, 176335, 176342, 176349, 176359, - 176364, 176369, 176374, 176379, 176381, 176387, 176391, 176393, 176395, - 176397, 176399, 176403, 176407, 176411, 176413, 176417, 176419, 176423, - 176425, 176427, 176429, 176431, 176436, 176441, 176443, 176449, 176453, - 176457, 176465, 176467, 176469, 176471, 176473, 176475, 176477, 176479, - 176481, 176483, 176485, 176489, 176493, 176495, 176497, 176499, 176501, - 176503, 176508, 176514, 176518, 176522, 176526, 176530, 176535, 176539, - 176541, 176543, 176547, 176553, 176555, 176557, 176559, 176563, 176572, - 176578, 176582, 176586, 176588, 176590, 176593, 176595, 176597, 176599, - 176603, 176605, 176609, 176614, 176616, 176621, 176627, 176634, 176638, - 176642, 176646, 176650, 176656, 176660, 176668, 176675, 176677, 176679, - 176683, 176687, 176689, 176693, 176697, 176699, 176703, 176705, 176709, - 176713, 176717, 176721, 176725, 176729, 176733, 176737, 176743, 176747, - 176751, 176762, 176767, 176771, 176775, 176781, 176785, 176789, 176793, - 176800, 176807, 176811, 176815, 176819, 176823, 176827, 176834, 176836, - 176840, 176842, 176844, 176848, 176852, 176856, 176858, 176862, 176866, - 176870, 176874, 176878, 176880, 176884, 176886, 176892, 176895, 176900, - 176902, 176904, 176907, 176909, 176911, 176914, 176921, 176928, 176935, - 176940, 176944, 176946, 176948, 176950, 176954, 176956, 176960, 176964, - 176968, 176970, 176974, 176976, 176980, 176984, 176991, 176993, 177002, - 177011, 177020, 177026, 177028, 177033, 177037, 177041, 177043, 177049, - 177053, 177055, 177059, 177063, 177065, 177069, 177074, 177078, 177084, - 177090, 177092, 177094, 177100, 177102, 177106, 177110, 177112, 177116, - 177118, 177122, 177126, 177130, 177133, 177136, 177141, 177146, 177148, - 177151, 177153, 177160, 177164, 177166, 177173, 177180, 177187, 177194, - 177201, 177203, 177205, 177207, 177211, 177213, 177215, 177217, 177219, - 177221, 177223, 177225, 177227, 177229, 177231, 177233, 177235, 177237, - 177239, 177241, 177243, 177245, 177247, 177249, 177251, 177253, 177255, - 177259, 177261, 177263, 177265, 177269, 177271, 177275, 177277, 177279, - 177283, 177287, 177293, 177295, 177297, 177299, 177301, 177305, 177309, - 177311, 177315, 177319, 177323, 177327, 177331, 177335, 177339, 177343, - 177347, 177351, 177355, 177359, 177363, 177367, 177371, 177375, 177379, - 177383, 177385, 177387, 177389, 177391, 177393, 177395, 177397, 177405, - 177413, 177421, 177429, 177434, 177439, 177444, 177448, 177452, 177457, - 177462, 177464, 177468, 177470, 177472, 177474, 177476, 177478, 177480, - 177482, 177486, 177488, 177490, 177492, 177496, 177500, 177504, 177508, - 177512, 177514, 177520, 177526, 177528, 177530, 177532, 177534, 177536, - 177545, 177552, 177559, 177563, 177570, 177575, 177582, 177591, 177596, - 177600, 177604, 177606, 177610, 177612, 177616, 177620, 177622, 177626, - 177630, 177634, 177636, 177638, 177644, 177646, 177648, 177650, 177654, - 177658, 177660, 177664, 177666, 177668, 177671, 177675, 177677, 177681, - 177683, 177685, 177690, 177692, 177696, 177700, 177703, 177707, 177711, - 177715, 177719, 177723, 177727, 177731, 177736, 177740, 177744, 177753, - 177758, 177761, 177763, 177766, 177769, 177774, 177776, 177779, 177784, - 177788, 177791, 177795, 177799, 177802, 177807, 177811, 177815, 177819, - 177823, 177829, 177835, 177841, 177847, 177852, 177863, 177865, 177869, - 177871, 177873, 177877, 177881, 177883, 177887, 177893, 177898, 177904, - 177906, 177910, 177914, 177921, 177928, 177932, 177934, 177936, 177940, - 177942, 177946, 177950, 177954, 177956, 177958, 177965, 177969, 177973, - 177977, 177981, 177985, 177987, 177991, 177993, 177995, 177999, 178001, - 178005, 178009, 178015, 178019, 178023, 178027, 178029, 178032, 178036, - 178043, 178052, 178061, 178070, 178079, 178081, 178085, 178087, 178091, - 178102, 178106, 178112, 178118, 178123, 178125, 178130, 178134, 178136, - 178138, 178140, 178144, 178148, 178152, 178157, 178168, 178184, 178197, - 178210, 178214, 178218, 178224, 178226, 178234, 178242, 178244, 178248, - 178254, 178260, 178267, 178274, 178276, 178278, 178282, 178284, 178290, - 178292, 178295, 178299, 178305, 178311, 178322, 178328, 178335, 178343, - 178347, 178355, 178363, 178369, 178375, 178382, 178384, 178388, 178390, - 178392, 178397, 178399, 178401, 178403, 178405, 178409, 178419, 178425, - 178429, 178433, 178437, 178443, 178449, 178455, 178461, 178466, 178471, - 178477, 178483, 178490, 178497, 178504, 178511, 178516, 178524, 178528, - 178537, 178546, 178552, 178556, 178560, 178564, 178567, 178572, 178574, - 178576, 178578, 178585, 178590, 178597, 178604, 178611, 178619, 178627, - 178635, 178643, 178651, 178659, 178667, 178675, 178683, 178689, 178695, - 178701, 178707, 178713, 178719, 178725, 178731, 178737, 178743, 178749, - 178755, 178758, 178767, 178776, 178778, 178785, 178789, 178791, 178793, - 178797, 178803, 178807, 178809, 178819, 178825, 178829, 178831, 178835, - 178837, 178841, 178848, 178855, 178862, 178867, 178872, 178881, 178887, - 178892, 178896, 178901, 178905, 178912, 178916, 178919, 178923, 178929, - 178935, 178939, 178943, 178948, 178954, 178963, 178974, 178980, 178986, - 178992, 179002, 179017, 179026, 179034, 179042, 179050, 179058, 179066, - 179074, 179082, 179090, 179098, 179106, 179114, 179122, 179125, 179129, - 179134, 179139, 179141, 179145, 179154, 179163, 179171, 179175, 179179, - 179184, 179189, 179194, 179196, 179201, 179205, 179207, 179211, 179215, - 179221, 179226, 179234, 179239, 179244, 179249, 179256, 179259, 179261, - 179265, 179270, 179276, 179280, 179284, 179290, 179296, 179298, 179302, - 179306, 179310, 179314, 179318, 179320, 179322, 179324, 179326, 179332, - 179338, 179342, 179344, 179346, 179348, 179357, 179361, 179368, 179375, - 179377, 179380, 179384, 179390, 179394, 179398, 179400, 179408, 179412, - 179416, 179421, 179425, 179430, 179435, 179440, 179445, 179450, 179455, - 179460, 179465, 179469, 179475, 179479, 179485, 179490, 179497, 179503, - 179511, 179515, 179522, 179526, 179530, 179534, 179539, 179544, 179546, - 179550, 179559, 179567, 179576, 179590, 179604, 179618, 179625, 179632, - 179636, 179645, 179653, 179657, 179666, 179673, 179677, 179681, 179685, - 179689, 179696, 179700, 179704, 179708, 179712, 179719, 179728, 179737, - 179744, 179756, 179768, 179772, 179776, 179780, 179784, 179788, 179792, - 179800, 179808, 179817, 179821, 179825, 179829, 179833, 179837, 179841, - 179847, 179854, 179858, 179870, 179878, 179882, 179886, 179890, 179894, - 179900, 179907, 179918, 179928, 179939, 179950, 179959, 179970, 179976, - 179982, 179988, 179994, 180000, 180004, 180011, 180020, 180027, 180033, - 180037, 180041, 180045, 180054, 180066, 180070, 180077, 180084, 180091, - 180099, 180106, 180114, 180122, 180131, 180139, 180148, 180157, 180167, - 180176, 180186, 180196, 180207, 180217, 180228, 180235, 180243, 180250, - 180258, 180266, 180275, 180283, 180292, 180299, 180311, 180318, 180330, - 180333, 180337, 180340, 180344, 180350, 180357, 180364, 180372, 180377, - 180383, 180394, 180404, 180415, 180420, 180425, 180431, 180436, 180443, - 180447, 180453, 180455, 180457, 180461, 180465, 180469, 180478, 180480, - 180482, 180485, 180487, 180489, 180493, 180495, 180499, 180501, 180505, - 180507, 180509, 180513, 180517, 180523, 180525, 180529, 180531, 180535, - 180539, 180543, 180547, 180549, 180551, 180555, 180559, 180563, 180567, - 180569, 180571, 180573, 180579, 180584, 180587, 180595, 180603, 180605, - 180610, 180613, 180618, 180629, 180636, 180641, 180646, 180648, 180652, - 180654, 180658, 180660, 180664, 180668, 180671, 180674, 180676, 180679, - 180681, 180685, 180687, 180689, 180691, 180695, 180697, 180701, 180704, - 180711, 180714, 180719, 180722, 180725, 180730, 180734, 180738, 180742, - 180744, 180749, 180752, 180756, 180758, 180760, 180764, 180766, 0, 0, 0, - 0, 0, 180768, 180772, 180774, 180778, 180783, 180785, 180789, 180791, - 180795, 180799, 180805, 180809, 180814, 180817, 180821, 180825, 0, 0, 0, - 180829, 180831, 180837, 180841, 180845, 180847, 180851, 180853, 180855, - 180859, 180861, 180865, 180869, 0, 0, 0, 180873, 180878, 180883, 180888, - 180893, 180898, 180903, 180910, 180917, 180924, 180931, 180936, 180941, - 180946, 180951, 180958, 180964, 180971, 180978, 180985, 180990, 180995, - 181000, 181005, 181010, 181017, 181024, 181029, 181034, 181041, 181048, - 181056, 181064, 181071, 181078, 181086, 181094, 181102, 181109, 181119, - 181130, 181135, 181142, 181149, 181156, 181164, 181172, 181183, 181191, - 181199, 181207, 181212, 181217, 181222, 181227, 181232, 181237, 181242, - 181247, 181252, 181257, 181262, 181267, 181274, 181279, 181284, 181291, - 181296, 181301, 181306, 181311, 181316, 181321, 181326, 181331, 181336, - 181341, 181346, 181351, 181358, 181366, 181371, 181376, 181383, 181388, - 181393, 181398, 181405, 181410, 181417, 181422, 181429, 181434, 181443, - 181452, 181457, 181462, 181467, 181472, 181477, 181482, 181487, 181492, - 181497, 181502, 181507, 181512, 181517, 181525, 181533, 181538, 181543, - 181548, 181553, 181558, 181564, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 181570, 181578, 181586, 181594, 181602, 181608, 181614, 181618, 181622, - 181628, 181634, 181643, 181647, 181652, 181658, 181662, 181667, 181671, - 181675, 181681, 181687, 181697, 181706, 181709, 181714, 181720, 181726, - 181737, 181747, 181751, 181756, 181762, 181768, 181777, 181782, 181786, - 181791, 181795, 181801, 181807, 181813, 181817, 181820, 181824, 181827, - 181830, 181835, 181840, 181847, 181855, 181862, 181869, 181878, 181887, - 181894, 181902, 181909, 181916, 181925, 181934, 181941, 181949, 181956, - 181963, 181972, 181979, 181987, 181993, 182002, 182010, 182019, 182026, - 182036, 182047, 182055, 182063, 182072, 182080, 182088, 182097, 182105, - 182115, 182124, 182132, 182140, 182149, 182152, 182157, 182160, 0, 0, 0, - 0, 0, 0, 0, 182165, 182171, 182177, 182183, 182189, 182195, 182201, - 182207, 182213, 182219, 182225, 182231, 0, 0, 0, 0, 182237, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 182241, 182249, 182258, 182266, 182275, - 182284, 182294, 182303, 182313, 182322, 182332, 182341, 0, 0, 0, 0, - 182351, 182359, 182368, 182376, 182385, 182392, 182400, 182407, 182415, - 182423, 182432, 182440, 182449, 182459, 182470, 182480, 182491, 182500, - 182510, 182519, 182529, 182538, 182548, 182557, 182567, 182575, 182584, - 182592, 182601, 182609, 182618, 182626, 182635, 182645, 182656, 182666, - 182677, 182681, 182686, 182690, 182695, 182698, 182702, 182705, 182709, - 182713, 182718, 182722, 182727, 182732, 182738, 182743, 182749, 182752, - 182756, 182759, 0, 0, 0, 0, 0, 0, 0, 0, 182763, 182766, 182770, 182773, - 182777, 182782, 182787, 182793, 182799, 182803, 0, 0, 0, 0, 0, 0, 182807, - 182813, 182820, 182826, 182833, 182841, 182849, 182858, 182867, 182872, - 182878, 182883, 182889, 182896, 182903, 182911, 182919, 182926, 182934, - 182941, 182949, 182958, 182967, 182977, 182987, 182993, 183000, 183006, - 183013, 183021, 183029, 183038, 183047, 183055, 183064, 183072, 183081, - 183091, 183101, 183112, 0, 0, 0, 0, 0, 0, 0, 0, 183123, 183128, 183134, - 183139, 183145, 183154, 183164, 183173, 183183, 183190, 183198, 183205, - 183213, 183220, 183229, 183238, 183247, 183252, 183259, 183266, 183273, - 183278, 183283, 183288, 183293, 183300, 183307, 183314, 183321, 183328, - 0, 0, 183337, 183347, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 174718, 174728, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 174736, 174743, 174750, 174757, + 174763, 174770, 174777, 174783, 174790, 174797, 174804, 174812, 174820, + 174828, 174836, 174844, 174852, 174859, 174866, 174873, 174881, 174889, + 174897, 174905, 174913, 174921, 174928, 174935, 174942, 174950, 174958, + 174966, 174974, 174982, 174990, 174995, 175000, 175005, 175010, 175015, + 175020, 175025, 175030, 175035, 0, 0, 0, 0, 175040, 175047, 175052, + 175057, 175062, 175067, 175072, 175077, 175082, 175087, 175092, 175097, + 175102, 175107, 175112, 175117, 175122, 175127, 175132, 175137, 175142, + 175147, 175152, 175157, 175162, 175167, 175172, 175177, 175182, 175187, + 175192, 175197, 175202, 175207, 175212, 175217, 175222, 175227, 175232, + 175237, 175242, 175247, 175252, 175257, 175262, 175267, 175272, 175277, + 175282, 175287, 175292, 175298, 175303, 175308, 175313, 175318, 175323, + 175328, 175333, 175338, 175343, 175348, 175353, 175358, 175363, 175368, + 175373, 175378, 175383, 175388, 175393, 175398, 175403, 175408, 175413, + 175418, 175423, 175428, 175433, 175438, 175443, 175448, 175453, 175458, + 175463, 175468, 175473, 175478, 175483, 175488, 175493, 175498, 175503, + 175508, 175513, 175518, 175523, 175528, 175533, 175538, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 175543, 175549, 175558, 175566, 175574, 175583, 175592, + 175601, 175610, 175619, 175628, 175637, 175646, 175655, 175664, 0, 0, + 175673, 175682, 175690, 175698, 175707, 175716, 175725, 175734, 175743, + 175752, 175761, 175770, 175779, 175788, 175797, 0, 175805, 175814, + 175822, 175830, 175839, 175848, 175857, 175866, 175875, 175884, 175893, + 175902, 175911, 175920, 175929, 0, 175936, 175945, 175953, 175961, + 175970, 175979, 175988, 175997, 176006, 176015, 176024, 176033, 176042, + 176051, 176060, 176067, 176073, 176079, 176085, 176091, 176097, 176103, + 176109, 176115, 176121, 176127, 176133, 176139, 176145, 176151, 176157, + 176163, 176169, 176175, 176181, 176187, 176193, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 176199, 176206, 176211, 176215, 176219, 176223, 176228, 176233, + 176238, 176243, 176248, 176253, 176260, 176269, 176275, 176279, 176288, + 176293, 176299, 176305, 176311, 176316, 176322, 176328, 176334, 176339, + 176345, 176351, 176356, 176362, 176368, 176373, 176379, 176385, 176390, + 176396, 176402, 176407, 176413, 176419, 176425, 176431, 176437, 176448, + 176455, 176461, 176464, 176467, 176470, 176475, 176481, 176487, 176493, + 176498, 176504, 176510, 176516, 176521, 176527, 176533, 176538, 176544, + 176550, 176555, 176561, 176567, 176572, 176578, 176584, 176589, 176595, + 176601, 176607, 176613, 176619, 176622, 176625, 176628, 176631, 176634, + 176637, 176644, 176652, 176660, 176668, 176675, 176683, 176691, 176699, + 176706, 176714, 176722, 176729, 176737, 176745, 176752, 176760, 176768, + 176775, 176783, 176791, 176798, 176806, 176814, 176822, 176830, 176838, + 176843, 176848, 176853, 176856, 176864, 176869, 176876, 176884, 176892, + 176900, 176907, 176915, 176923, 176931, 176938, 176946, 176954, 176961, + 176969, 176977, 176984, 176992, 177000, 177007, 177015, 177023, 177030, + 177038, 177046, 177054, 177062, 177070, 177080, 177085, 177089, 177093, + 177098, 177103, 177106, 177109, 177112, 177115, 177118, 177121, 177124, + 177127, 177130, 177136, 177139, 177143, 177148, 177152, 177157, 177162, + 177168, 177174, 177180, 177185, 177193, 177199, 177202, 177205, 177208, + 177211, 177214, 177217, 177220, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 177225, 177232, + 177240, 177248, 177256, 177263, 177271, 177279, 177287, 177294, 177302, + 177310, 177317, 177325, 177333, 177340, 177348, 177356, 177363, 177371, + 177379, 177386, 177394, 177402, 177410, 177418, 177426, 177431, 177435, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 177438, 177444, 177450, 177456, + 177460, 177466, 177472, 177478, 177484, 177490, 177496, 177502, 177508, + 177514, 177520, 177526, 177532, 177538, 177544, 177550, 177556, 177562, + 177568, 177574, 177580, 177586, 177592, 177598, 177604, 177610, 177616, + 177622, 177628, 177634, 177640, 177646, 177652, 177658, 177664, 177670, + 177676, 177682, 177688, 177694, 0, 0, 0, 0, 177700, 177711, 177722, + 177733, 177744, 177755, 177766, 177777, 177788, 0, 0, 0, 0, 0, 0, 0, + 177799, 177804, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 177809, 177815, + 177821, 177827, 177833, 177839, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 177845, 177847, 177849, 177853, + 177858, 177863, 177865, 177871, 177876, 177878, 177884, 177888, 177890, + 177894, 177900, 177906, 177912, 177917, 177922, 177929, 177936, 177943, + 177948, 177955, 177962, 177969, 177973, 177980, 177989, 177998, 178005, + 178010, 178014, 178018, 178020, 178023, 178026, 178033, 178040, 178050, + 178055, 178060, 178065, 178070, 178072, 178078, 178082, 178084, 178086, + 178088, 178090, 178094, 178098, 178102, 178104, 178108, 178110, 178114, + 178116, 178118, 178120, 178122, 178127, 178132, 178134, 178140, 178144, + 178148, 178156, 178158, 178160, 178162, 178164, 178166, 178168, 178170, + 178172, 178174, 178176, 178180, 178184, 178186, 178188, 178190, 178192, + 178194, 178199, 178205, 178209, 178213, 178217, 178221, 178226, 178230, + 178232, 178234, 178238, 178244, 178246, 178248, 178250, 178254, 178263, + 178269, 178273, 178277, 178279, 178281, 178284, 178286, 178288, 178290, + 178294, 178296, 178300, 178305, 178307, 178312, 178318, 178325, 178329, + 178333, 178337, 178341, 178347, 178351, 178359, 178366, 178368, 178370, + 178374, 178378, 178380, 178384, 178388, 178390, 178394, 178396, 178400, + 178404, 178408, 178412, 178416, 178420, 178424, 178428, 178434, 178438, + 178442, 178453, 178458, 178462, 178466, 178472, 178476, 178480, 178484, + 178491, 178498, 178502, 178506, 178510, 178514, 178518, 178525, 178527, + 178531, 178533, 178535, 178539, 178543, 178547, 178549, 178553, 178557, + 178561, 178565, 178569, 178571, 178575, 178577, 178583, 178586, 178591, + 178593, 178595, 178598, 178600, 178602, 178605, 178612, 178619, 178626, + 178631, 178635, 178637, 178639, 178641, 178645, 178647, 178651, 178655, + 178659, 178661, 178665, 178667, 178671, 178675, 178682, 178684, 178693, + 178702, 178711, 178717, 178719, 178724, 178728, 178732, 178734, 178740, + 178744, 178746, 178750, 178754, 178756, 178760, 178765, 178769, 178775, + 178781, 178783, 178785, 178791, 178793, 178797, 178801, 178803, 178807, + 178809, 178813, 178817, 178821, 178824, 178827, 178832, 178837, 178839, + 178842, 178844, 178851, 178855, 178857, 178864, 178871, 178878, 178885, + 178892, 178894, 178896, 178898, 178902, 178904, 178906, 178908, 178910, + 178912, 178914, 178916, 178918, 178920, 178922, 178924, 178926, 178928, + 178930, 178932, 178934, 178936, 178938, 178940, 178942, 178944, 178946, + 178950, 178952, 178954, 178956, 178960, 178962, 178966, 178968, 178970, + 178974, 178978, 178984, 178986, 178988, 178990, 178992, 178996, 179000, + 179002, 179006, 179010, 179014, 179018, 179022, 179026, 179030, 179034, + 179038, 179042, 179046, 179050, 179054, 179058, 179062, 179066, 179070, + 179074, 179076, 179078, 179080, 179082, 179084, 179086, 179088, 179096, + 179104, 179112, 179120, 179125, 179130, 179135, 179139, 179143, 179148, + 179153, 179155, 179159, 179161, 179163, 179165, 179167, 179169, 179171, + 179173, 179177, 179179, 179181, 179183, 179187, 179191, 179195, 179199, + 179203, 179205, 179211, 179217, 179219, 179221, 179223, 179225, 179227, + 179236, 179243, 179250, 179254, 179261, 179266, 179273, 179282, 179287, + 179291, 179295, 179297, 179301, 179303, 179307, 179311, 179313, 179317, + 179321, 179325, 179327, 179329, 179335, 179337, 179339, 179341, 179345, + 179349, 179351, 179355, 179357, 179359, 179362, 179366, 179368, 179372, + 179374, 179376, 179381, 179383, 179387, 179391, 179394, 179398, 179402, + 179406, 179410, 179414, 179418, 179422, 179427, 179431, 179435, 179444, + 179449, 179452, 179454, 179457, 179460, 179465, 179467, 179470, 179475, + 179479, 179482, 179486, 179490, 179493, 179498, 179502, 179506, 179510, + 179514, 179520, 179526, 179532, 179538, 179543, 179554, 179556, 179560, + 179562, 179564, 179568, 179572, 179574, 179578, 179584, 179589, 179595, + 179597, 179601, 179605, 179612, 179619, 179623, 179625, 179627, 179631, + 179633, 179637, 179641, 179645, 179647, 179649, 179656, 179660, 179664, + 179668, 179672, 179676, 179678, 179682, 179684, 179686, 179690, 179692, + 179696, 179700, 179706, 179710, 179714, 179718, 179720, 179723, 179727, + 179734, 179743, 179752, 179761, 179770, 179772, 179776, 179778, 179782, + 179793, 179797, 179803, 179809, 179814, 179816, 179821, 179825, 179827, + 179829, 179831, 179835, 179839, 179843, 179848, 179859, 179875, 179888, + 179901, 179905, 179909, 179915, 179917, 179925, 179933, 179935, 179939, + 179945, 179951, 179958, 179965, 179967, 179969, 179973, 179975, 179981, + 179983, 179986, 179990, 179996, 180002, 180013, 180019, 180026, 180034, + 180038, 180046, 180054, 180060, 180066, 180073, 180075, 180079, 180081, + 180083, 180088, 180090, 180092, 180094, 180096, 180100, 180110, 180116, + 180120, 180124, 180128, 180134, 180140, 180146, 180152, 180157, 180162, + 180168, 180174, 180181, 180188, 180195, 180202, 180207, 180215, 180219, + 180228, 180237, 180243, 180247, 180251, 180255, 180258, 180263, 180265, + 180267, 180269, 180276, 180281, 180288, 180295, 180302, 180310, 180318, + 180326, 180334, 180342, 180350, 180358, 180366, 180374, 180380, 180386, + 180392, 180398, 180404, 180410, 180416, 180422, 180428, 180434, 180440, + 180446, 180449, 180458, 180467, 180469, 180476, 180480, 180482, 180484, + 180488, 180494, 180498, 180500, 180510, 180516, 180520, 180522, 180526, + 180528, 180532, 180539, 180546, 180553, 180558, 180563, 180572, 180578, + 180583, 180587, 180592, 180596, 180603, 180607, 180610, 180614, 180620, + 180626, 180630, 180634, 180639, 180645, 180654, 180665, 180671, 180677, + 180683, 180693, 180708, 180717, 180725, 180733, 180741, 180749, 180757, + 180765, 180773, 180781, 180789, 180797, 180805, 180813, 180816, 180820, + 180825, 180830, 180832, 180836, 180845, 180854, 180862, 180866, 180870, + 180875, 180880, 180885, 180887, 180892, 180896, 180898, 180902, 180906, + 180912, 180917, 180925, 180930, 180935, 180940, 180947, 180950, 180952, + 180956, 180961, 180967, 180971, 180975, 180981, 180987, 180989, 180993, + 180997, 181001, 181005, 181009, 181011, 181013, 181015, 181017, 181023, + 181029, 181033, 181035, 181037, 181039, 181048, 181052, 181059, 181066, + 181068, 181071, 181075, 181081, 181085, 181089, 181091, 181099, 181103, + 181107, 181112, 181116, 181121, 181126, 181131, 181136, 181141, 181146, + 181151, 181156, 181160, 181166, 181170, 181176, 181181, 181188, 181194, + 181202, 181206, 181213, 181217, 181221, 181225, 181230, 181235, 181237, + 181241, 181250, 181258, 181267, 181281, 181295, 181309, 181316, 181323, + 181327, 181336, 181344, 181348, 181357, 181364, 181368, 181372, 181376, + 181380, 181387, 181391, 181395, 181399, 181403, 181410, 181419, 181428, + 181435, 181447, 181459, 181463, 181467, 181471, 181475, 181479, 181483, + 181491, 181499, 181508, 181512, 181516, 181520, 181524, 181528, 181532, + 181538, 181545, 181549, 181561, 181569, 181573, 181577, 181581, 181585, + 181591, 181598, 181609, 181619, 181630, 181641, 181650, 181661, 181667, + 181673, 181679, 181685, 181691, 181695, 181702, 181711, 181718, 181724, + 181728, 181732, 181736, 181745, 181757, 181761, 181768, 181775, 181782, + 181790, 181797, 181805, 181813, 181822, 181830, 181839, 181848, 181858, + 181867, 181877, 181887, 181898, 181908, 181919, 181926, 181934, 181941, + 181949, 181957, 181966, 181974, 181983, 181990, 182002, 182009, 182021, + 182024, 182028, 182031, 182035, 182041, 182048, 182055, 182063, 182068, + 182074, 182085, 182095, 182106, 182111, 182116, 182122, 182127, 182134, + 182138, 182144, 182146, 182148, 182152, 182156, 182160, 182169, 182171, + 182173, 182176, 182178, 182180, 182184, 182186, 182190, 182192, 182196, + 182198, 182200, 182204, 182208, 182214, 182216, 182220, 182222, 182226, + 182230, 182234, 182238, 182240, 182242, 182246, 182250, 182254, 182258, + 182260, 182262, 182264, 182270, 182275, 182278, 182286, 182294, 182296, + 182301, 182304, 182309, 182320, 182327, 182332, 182337, 182339, 182343, + 182345, 182349, 182351, 182355, 182359, 182362, 182365, 182367, 182370, + 182372, 182376, 182378, 182380, 182382, 182386, 182388, 182392, 182395, + 182402, 182405, 182410, 182413, 182416, 182421, 182425, 182429, 182433, + 182435, 182440, 182443, 182447, 182449, 182451, 182455, 182457, 0, 0, 0, + 0, 182459, 182461, 182465, 182467, 182471, 182476, 182478, 182482, + 182484, 182488, 182492, 182498, 182502, 182507, 182510, 182514, 182518, + 0, 0, 0, 182522, 182524, 182530, 182534, 182538, 182540, 182544, 182546, + 182548, 182552, 182554, 182558, 182562, 0, 0, 0, 182566, 182571, 182576, + 182581, 182586, 182591, 182596, 182603, 182610, 182617, 182624, 182629, + 182634, 182639, 182644, 182651, 182657, 182664, 182671, 182678, 182683, + 182688, 182693, 182698, 182703, 182710, 182717, 182722, 182727, 182734, + 182741, 182749, 182757, 182764, 182771, 182779, 182787, 182795, 182802, + 182812, 182823, 182828, 182835, 182842, 182849, 182857, 182865, 182876, + 182884, 182892, 182900, 182905, 182910, 182915, 182920, 182925, 182930, + 182935, 182940, 182945, 182950, 182955, 182960, 182967, 182972, 182977, + 182984, 182989, 182994, 182999, 183004, 183009, 183014, 183019, 183024, + 183029, 183034, 183039, 183044, 183051, 183059, 183064, 183069, 183076, + 183081, 183086, 183091, 183098, 183103, 183110, 183115, 183122, 183127, + 183136, 183145, 183150, 183155, 183160, 183165, 183170, 183175, 183180, + 183185, 183190, 183195, 183200, 183205, 183210, 183218, 183226, 183231, + 183236, 183241, 183246, 183251, 183257, 183263, 183268, 183270, 0, 0, 0, + 0, 183274, 183276, 183278, 183280, 183282, 183284, 183292, 183300, + 183308, 183316, 183322, 183328, 183332, 183336, 183342, 183348, 183357, + 183361, 183366, 183372, 183376, 183381, 183385, 183389, 183395, 183401, + 183411, 183420, 183423, 183428, 183434, 183440, 183451, 183461, 183465, + 183470, 183476, 183482, 183491, 183496, 183500, 183505, 183509, 183515, + 183521, 183527, 183531, 183534, 183538, 183541, 183544, 183549, 183554, + 183561, 183569, 183576, 183583, 183592, 183601, 183608, 183616, 183623, + 183630, 183639, 183648, 183655, 183663, 183670, 183677, 183686, 183693, + 183701, 183707, 183716, 183724, 183733, 183740, 183750, 183761, 183769, + 183777, 183786, 183794, 183802, 183811, 183819, 183829, 183838, 183846, + 183854, 183863, 183866, 183871, 183874, 183879, 0, 0, 0, 0, 0, 0, 183886, + 183892, 183898, 183904, 183910, 183916, 183922, 183928, 183934, 183940, + 183946, 183952, 0, 0, 0, 0, 183958, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 183962, 183970, 183979, 183987, 183996, 184005, 184015, 184024, + 184034, 184043, 184053, 184062, 0, 0, 0, 0, 184072, 184080, 184089, + 184097, 184106, 184113, 184121, 184128, 184136, 184144, 184153, 184161, + 184170, 184180, 184191, 184201, 184212, 184221, 184231, 184240, 184250, + 184259, 184269, 184278, 184288, 184296, 184305, 184313, 184322, 184330, + 184339, 184347, 184356, 184366, 184377, 184387, 184398, 184402, 184407, + 184411, 184416, 184419, 184423, 184426, 184430, 184434, 184439, 184443, + 184448, 184453, 184459, 184464, 184470, 184473, 184477, 184480, 0, 0, 0, + 0, 0, 0, 0, 0, 184484, 184487, 184491, 184494, 184498, 184503, 184508, + 184514, 184520, 184524, 0, 0, 0, 0, 0, 0, 184528, 184534, 184541, 184547, + 184554, 184562, 184570, 184579, 184588, 184593, 184599, 184604, 184610, + 184617, 184624, 184632, 184640, 184647, 184655, 184662, 184670, 184679, + 184688, 184698, 184708, 184714, 184721, 184727, 184734, 184742, 184750, + 184759, 184768, 184776, 184785, 184793, 184802, 184812, 184822, 184833, + 0, 0, 0, 0, 0, 0, 0, 0, 184844, 184849, 184855, 184860, 184866, 184875, + 184885, 184894, 184904, 184911, 184919, 184926, 184934, 184941, 184950, + 184959, 184968, 184973, 184980, 184987, 184994, 184999, 185004, 185009, + 185014, 185021, 185028, 185035, 185042, 185049, 0, 0, 185058, 185068, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 183359, 183369, 183378, 183383, - 183392, 183400, 183408, 183415, 183419, 183424, 183431, 183440, 183451, - 183455, 183458, 183462, 183466, 183470, 183474, 183479, 183483, 183487, - 183492, 183496, 183500, 183506, 183512, 183519, 183523, 183527, 183529, - 183539, 183548, 183555, 183559, 183563, 183573, 183577, 183581, 183585, - 183589, 183597, 183606, 183619, 183630, 183641, 183657, 183666, 183675, - 183679, 183681, 183686, 183688, 183690, 183696, 183700, 183702, 183708, - 183710, 183712, 183716, 183718, 183722, 183724, 183728, 183732, 183737, - 183741, 183745, 183747, 183751, 183753, 183759, 183765, 183771, 183775, - 183781, 183785, 183792, 183794, 183798, 183800, 183802, 183804, 183806, - 183808, 183810, 183814, 183818, 183825, 183829, 183831, 183836, 183838, - 183840, 183842, 183844, 183848, 183852, 183854, 183859, 183864, 183866, - 183868, 183870, 183872, 183877, 183879, 183883, 183887, 183889, 183893, - 183895, 183908, 183912, 183919, 183931, 183943, 183947, 183951, 183953, - 183957, 183965, 183972, 183974, 183978, 183980, 183984, 183988, 183990, - 183994, 183996, 183998, 184002, 184004, 184006, 184008, 184010, 184012, - 184016, 184018, 184020, 184022, 184024, 184026, 184028, 184030, 184034, - 184038, 184040, 184042, 184044, 184046, 184048, 184050, 184052, 184054, - 184056, 184058, 184060, 184062, 184064, 184066, 184068, 184070, 184072, - 184074, 184076, 184078, 184080, 184082, 184084, 184086, 184088, 184090, - 184094, 184098, 184106, 184114, 184120, 184127, 184129, 184131, 184133, - 184135, 184137, 184139, 184143, 184150, 184154, 184158, 184162, 184166, - 184170, 184172, 184176, 184180, 184182, 184184, 184186, 184188, 184190, - 184194, 184198, 184202, 184204, 184208, 184212, 184216, 184221, 184223, - 184225, 184229, 184233, 184238, 184246, 184250, 184258, 184260, 184262, - 184264, 184266, 184268, 184270, 184272, 184274, 184278, 184282, 184284, - 184286, 184288, 184290, 184296, 184298, 184304, 184308, 184312, 184317, - 184319, 184321, 184325, 184327, 184329, 184331, 184333, 184337, 184342, - 184347, 184351, 184355, 184357, 184359, 184364, 184369, 184371, 184373, - 184377, 184383, 184389, 184395, 184401, 184407, 184413, 184424, 184435, - 184447, 184458, 184469, 184480, 184491, 184502, 184513, 184524, 184535, - 184546, 184557, 184568, 184579, 184591, 184603, 184615, 184627, 184639, - 184651, 184665, 184679, 184694, 184700, 184706, 184712, 184718, 184724, - 184730, 184736, 184742, 184748, 184754, 184760, 184766, 184773, 184780, - 184787, 184794, 184801, 184808, 184822, 184836, 184851, 184865, 184879, - 184893, 184907, 184921, 184935, 184949, 184963, 184977, 184991, 185005, - 185019, 185034, 185049, 185064, 185079, 185094, 185109, 185123, 185137, - 185152, 185157, 185162, 185168, 185179, 185190, 185202, 185207, 185212, - 185217, 185222, 185227, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 185232, - 185238, 185244, 185250, 185256, 185262, 185268, 185274, 185279, 185284, - 185289, 185294, 185299, 185304, 0, 0, 185309, 185313, 185317, 185319, - 185321, 0, 0, 0, 185325, 185330, 185334, 185336, 185338, 0, 0, 0, 185340, - 185342, 185344, 185346, 185348, 185352, 185354, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 185358, 185362, 185364, 185366, 185368, 185372, 185374, 185378, - 185380, 185383, 185385, 185389, 185391, 185393, 185394, 185396, 185398, - 185400, 185404, 185406, 185408, 185412, 185414, 185416, 185418, 185420, - 185424, 185428, 185431, 0, 0, 0, 185433, 185435, 185437, 185439, 185441, - 185445, 185447, 185449, 185451, 185453, 185457, 0, 0, 0, 0, 0, 185462, - 185466, 185468, 185472, 185476, 185480, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 185485, 185487, 185491, 185493, 185495, 185497, 185499, 185501, 185505, - 185507, 0, 0, 0, 0, 0, 0, 185509, 185513, 185517, 185530, 185537, 185544, - 185550, 185554, 0, 0, 0, 0, 0, 0, 0, 0, 185556, 185566, 185569, 185572, - 185577, 185582, 185591, 0, 0, 0, 0, 0, 0, 0, 0, 0, 185595, 185598, - 185601, 185604, 185607, 185610, 185613, 185616, 185619, 185622, 185625, - 185628, 185631, 185634, 185637, 185640, 185643, 185646, 185649, 185652, - 185655, 185658, 185661, 185664, 185667, 185670, 185673, 185676, 185679, - 185682, 185685, 185688, 185691, 185694, 185697, 185700, 185703, 185706, - 185709, 185712, 185715, 185718, 185721, 185724, 185727, 185730, 185733, - 185736, 185739, 185742, 185745, 185748, 185751, 185754, 185757, 185760, - 185763, 185766, 185769, 185772, 185775, 185787, 185798, 185810, 185821, - 185832, 185844, 185855, 185867, 185878, 185889, 185901, 185913, 185924, - 185936, 185947, 185958, 185970, 185981, 185993, 186004, 186015, 186027, - 186039, 186050, 186062, 186073, 186084, 186096, 186107, 186119, 186130, - 186141, 186153, 186165, 186176, 186188, 186199, 186210, 186222, 186233, - 186245, 186256, 186267, 186279, 186291, 186303, 186315, 186327, 186335, - 186343, 186351, 186359, 186365, 186371, 186377, 186383, 186389, 186395, - 186402, 186409, 186416, 186423, 186430, 186437, 186445, 186453, 186461, - 186469, 186477, 186484, 186490, 186496, 186503, 186509, 186516, 186522, - 186528, 186535, 186541, 186548, 186554, 186560, 186566, 186572, 186578, - 186590, 0, 186603, 186616, 186622, 186630, 186635, 186642, 186649, - 186657, 186665, 186673, 186681, 186689, 186697, 186709, 186720, 186731, - 186742, 186757, 186772, 186786, 186800, 186818, 186836, 186855, 186873, - 186891, 186909, 186916, 186924, 186928, 186933, 186939, 186945, 186955, - 186966, 186977, 186987, 186997, 187001, 187005, 187010, 187016, 187022, - 187032, 187038, 187047, 187056, 187065, 187074, 187080, 187084, 187093, - 187101, 187108, 187115, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 187120, - 187125, 187129, 187133, 187137, 187141, 187145, 187149, 187153, 187157, - 0, 0, 0, 0, 0, 0, 187161, 187165, 187169, 187173, 187177, 187181, 187185, - 187189, 187193, 187197, 187201, 187205, 187209, 187213, 187217, 187221, - 187225, 187229, 187233, 187237, 187241, 187245, 187249, 187253, 187257, - 187261, 187265, 187269, 187273, 187277, 187281, 187285, 187289, 187293, - 187297, 187301, 187305, 187309, 187313, 187317, 187321, 187325, 187329, - 187333, 187337, 187341, 187345, 187349, 187353, 187357, 187361, 187365, - 187369, 187373, 187377, 187381, 187385, 187389, 187393, 187397, 187401, - 187405, 187409, 187413, 187417, 187421, 187425, 187429, 187433, 187437, - 187441, 187445, 187449, 187453, 187457, 187461, 187465, 187469, 187473, - 187477, 187481, 187485, 187489, 187493, 187497, 187501, 187505, 187509, - 187513, 187517, 187521, 187525, 187529, 187533, 187537, 187541, 187545, - 187549, 187553, 187557, 187561, 187565, 187569, 187573, 187577, 187581, - 187585, 187589, 187593, 187597, 187601, 187605, 187609, 187613, 187617, - 187621, 187625, 187629, 187633, 187637, 187641, 187645, 187649, 187653, - 187657, 187661, 187665, 187669, 187673, 187677, 187681, 187685, 187689, - 187693, 187697, 187701, 187705, 187709, 187713, 187717, 187721, 187725, - 187729, 187733, 187737, 187741, 187745, 187749, 187753, 187757, 187761, - 187765, 187769, 187773, 187777, 187781, 187785, 187789, 187793, 187797, - 187801, 187805, 187809, 187813, 187817, 187821, 187825, 187829, 187833, - 187837, 187841, 187845, 187849, 187853, 187857, 187861, 187865, 187869, - 187873, 187877, 187881, 187885, 187889, 187893, 187897, 187901, 187905, - 187909, 187913, 187917, 187921, 187925, 187929, 187933, 187937, 187941, - 187945, 187949, 187953, 187957, 187961, 187965, 187969, 187973, 187977, - 187981, 187985, 187989, 187993, 187997, 188001, 188005, 188009, 188013, - 188017, 188021, 188025, 188029, 188033, 188037, 188041, 188045, 188049, - 188053, 188057, 188061, 188065, 188069, 188073, 188077, 188081, 188085, - 188089, 188093, 188097, 188101, 188105, 188109, 188113, 188117, 188121, - 188125, 188129, 188133, 188137, 188141, 188145, 188149, 188153, 188157, - 188161, 188165, 188169, 188173, 188177, 188181, 188185, 188189, 188193, - 188197, 188201, 188205, 188209, 188213, 188217, 188221, 188225, 188229, - 188233, 188237, 188241, 188245, 188249, 188253, 188257, 188261, 188265, - 188269, 188273, 188277, 188281, 188285, 188289, 188293, 188297, 188301, - 188305, 188309, 188313, 188317, 188321, 188325, 188329, 188333, 188337, - 188341, 188345, 188349, 188353, 188357, 188361, 188365, 188369, 188373, - 188377, 188381, 188385, 188389, 188393, 188397, 188401, 188405, 188409, - 188413, 188417, 188421, 188425, 188429, 188433, 188437, 188441, 188445, - 188449, 188453, 188457, 188461, 188465, 188469, 188473, 188477, 188481, - 188485, 188489, 188493, 188497, 188501, 188505, 188509, 188513, 188517, - 188521, 188525, 188529, 188533, 188537, 188541, 188545, 188549, 188553, - 188557, 188561, 188565, 188569, 188573, 188577, 188581, 188585, 188589, - 188593, 188597, 188601, 188605, 188609, 188613, 188617, 188621, 188625, - 188629, 188633, 188637, 188641, 188645, 188649, 188653, 188657, 188661, - 188665, 188669, 188673, 188677, 188681, 188685, 188689, 188693, 188697, - 188701, 188705, 188709, 188713, 188717, 188721, 188725, 188729, 188733, - 188737, 188741, 188745, 188749, 188753, 188757, 188761, 188765, 188769, - 188773, 188777, 188781, 188785, 188789, 188793, 188797, 188801, 188805, - 188809, 188813, 188817, 188821, 188825, 188829, 188833, 188837, 188841, - 188845, 188849, 188853, 188857, 188861, 188865, 188869, 188873, 188877, - 188881, 188885, 188889, 188893, 188897, 188901, 188905, 188909, 188913, - 188917, 188921, 188925, 188929, 188933, 188937, 188941, 188945, 188949, - 188953, 188957, 188961, 188965, 188969, 188973, 188977, 188981, 188985, - 188989, 188993, 188997, 189001, 189005, 189009, 189013, 189017, 189021, - 189025, 189029, 189033, 189037, 189041, 189045, 189049, 189053, 189057, - 189061, 189065, 189069, 189073, 189077, 189081, 189085, 189089, 189093, - 189097, 189101, 189105, 189109, 189113, 189117, 189121, 189125, 189129, - 189133, 189137, 189141, 189145, 189149, 189153, 189157, 189161, 189165, - 189169, 189173, 189177, 189181, 189185, 189189, 189193, 189197, 189201, - 189205, 189209, 189213, 189217, 189221, 189225, 189229, 189233, 189237, - 189241, 189245, 189249, 189253, 189257, 189261, 189265, 189269, 189273, - 189277, 189281, 189285, 189289, 189293, 189297, 189301, 189305, 189309, - 189313, 189317, 189321, 189325, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 185080, 185090, 185099, 185104, 185113, 185121, 185129, + 185136, 185140, 185145, 185152, 185161, 185172, 185176, 185179, 185183, + 185187, 185191, 185195, 185200, 185204, 185208, 185213, 185217, 185221, + 185227, 185233, 185240, 185244, 185248, 185250, 185260, 185269, 185276, + 185280, 185284, 185294, 185298, 185302, 185306, 185310, 185318, 185327, + 185340, 185351, 185362, 185378, 185387, 185396, 185400, 185402, 185407, + 185409, 185411, 185417, 185421, 185423, 185429, 185431, 185433, 185437, + 185439, 185443, 185445, 185449, 185453, 185458, 185462, 185466, 185468, + 185472, 185474, 185480, 185486, 185492, 185496, 185502, 185506, 185513, + 185515, 185519, 185521, 185523, 185525, 185527, 185529, 185531, 185535, + 185539, 185546, 185550, 185552, 185557, 185559, 185561, 185563, 185565, + 185569, 185573, 185575, 185580, 185585, 185587, 185589, 185591, 185593, + 185598, 185600, 185604, 185608, 185610, 185614, 185616, 185629, 185633, + 185640, 185652, 185664, 185668, 185672, 185674, 185678, 185686, 185693, + 185695, 185699, 185701, 185705, 185709, 185711, 185715, 185717, 185719, + 185723, 185725, 185727, 185729, 185731, 185733, 185737, 185739, 185741, + 185743, 185745, 185747, 185749, 185751, 185755, 185759, 185761, 185763, + 185765, 185767, 185769, 185771, 185773, 185775, 185777, 185779, 185781, + 185783, 185785, 185787, 185789, 185791, 185793, 185795, 185797, 185799, + 185801, 185803, 185805, 185807, 185809, 185811, 185815, 185819, 185827, + 185835, 185841, 185848, 185850, 185852, 185854, 185856, 185858, 185860, + 185864, 185871, 185875, 185879, 185883, 185887, 185891, 185893, 185897, + 185901, 185903, 185905, 185907, 185909, 185911, 185915, 185919, 185923, + 185925, 185929, 185933, 185937, 185942, 185944, 185946, 185950, 185954, + 185959, 185967, 185971, 185979, 185981, 185983, 185985, 185987, 185989, + 185991, 185993, 185995, 185999, 186003, 186005, 186007, 186009, 186011, + 186017, 186019, 186025, 186029, 186033, 186038, 186040, 186042, 186046, + 186048, 186050, 186052, 186054, 186058, 186063, 186068, 186072, 186076, + 186078, 186080, 186085, 186090, 186092, 186094, 186098, 186104, 186110, + 186116, 186122, 186128, 186134, 186145, 186156, 186168, 186179, 186190, + 186201, 186212, 186223, 186234, 186245, 186256, 186267, 186278, 186289, + 186300, 186312, 186324, 186336, 186348, 186360, 186372, 186386, 186400, + 186415, 186421, 186427, 186433, 186439, 186445, 186451, 186457, 186463, + 186469, 186475, 186481, 186487, 186494, 186501, 186508, 186515, 186522, + 186529, 186543, 186557, 186572, 186586, 186600, 186614, 186628, 186642, + 186656, 186670, 186684, 186698, 186712, 186726, 186740, 186755, 186770, + 186785, 186800, 186815, 186830, 186844, 186858, 186873, 186878, 186883, + 186889, 186900, 186911, 186923, 186928, 186933, 186938, 186943, 186948, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 186953, 186959, 186965, 186971, + 186977, 186983, 186989, 186995, 187000, 187005, 187010, 187015, 187020, + 187025, 0, 0, 187030, 187034, 187038, 187040, 187042, 187046, 187051, + 187055, 187059, 187064, 187068, 187070, 187072, 0, 0, 0, 187074, 187076, + 187078, 187080, 187082, 187086, 187088, 187092, 187094, 0, 0, 0, 0, 0, 0, + 0, 187096, 187100, 187102, 187104, 187106, 187110, 187112, 187116, + 187118, 187121, 187123, 187127, 187129, 187131, 187132, 187134, 187136, + 187138, 187142, 187144, 187146, 187150, 187152, 187154, 187156, 187158, + 187162, 187166, 187169, 187171, 187177, 187181, 187183, 187185, 187187, + 187189, 187191, 187195, 187197, 187199, 187201, 187203, 187207, 187212, + 187214, 187216, 0, 187218, 187220, 187224, 187226, 187230, 187234, + 187238, 0, 0, 0, 0, 0, 0, 0, 0, 187243, 187245, 187247, 187249, 187253, + 187255, 187257, 187259, 187261, 187263, 187267, 187269, 187271, 187275, + 0, 0, 0, 0, 187279, 187283, 187287, 187300, 187307, 187314, 187320, + 187324, 187326, 0, 0, 0, 0, 0, 0, 0, 187330, 187340, 187343, 187346, + 187351, 187356, 187365, 187369, 187374, 0, 0, 0, 0, 0, 0, 0, 187379, + 187382, 187385, 187388, 187391, 187394, 187397, 187400, 187403, 187406, + 187409, 187412, 187415, 187418, 187421, 187424, 187427, 187430, 187433, + 187436, 187439, 187442, 187445, 187448, 187451, 187454, 187457, 187460, + 187463, 187466, 187469, 187472, 187475, 187478, 187481, 187484, 187487, + 187490, 187493, 187496, 187499, 187502, 187505, 187508, 187511, 187514, + 187517, 187520, 187523, 187526, 187529, 187532, 187535, 187538, 187541, + 187544, 187547, 187550, 187553, 187556, 187559, 187571, 187582, 187594, + 187605, 187616, 187628, 187639, 187651, 187662, 187673, 187685, 187697, + 187708, 187720, 187731, 187742, 187754, 187765, 187777, 187788, 187799, + 187811, 187823, 187834, 187846, 187857, 187868, 187880, 187891, 187903, + 187914, 187925, 187937, 187949, 187960, 187972, 187983, 187994, 188006, + 188017, 188029, 188040, 188051, 188063, 188075, 188087, 188099, 188111, + 188119, 188127, 188135, 188143, 188149, 188155, 188161, 188167, 188173, + 188179, 188186, 188193, 188200, 188207, 188214, 188221, 188229, 188237, + 188245, 188253, 188261, 188268, 188274, 188280, 188287, 188293, 188300, + 188306, 188312, 188319, 188325, 188332, 188338, 188344, 188350, 188356, + 188362, 188374, 0, 188387, 188400, 188406, 188414, 188419, 188426, + 188433, 188441, 188449, 188457, 188465, 188473, 188481, 188493, 188504, + 188515, 188526, 188541, 188556, 188570, 188584, 188602, 188620, 188639, + 188657, 188675, 188693, 188700, 188708, 188712, 188717, 188723, 188729, + 188739, 188750, 188761, 188771, 188781, 188785, 188789, 188794, 188800, + 188806, 188816, 188822, 188831, 188840, 188849, 188858, 188864, 188868, + 188877, 188885, 188892, 188899, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 188904, 188909, 188913, 188917, 188921, 188925, 188929, 188933, 188937, + 188941, 0, 0, 0, 0, 0, 0, 188945, 188949, 188953, 188957, 188961, 188965, + 188969, 188973, 188977, 188981, 188985, 188989, 188993, 188997, 189001, + 189005, 189009, 189013, 189017, 189021, 189025, 189029, 189033, 189037, + 189041, 189045, 189049, 189053, 189057, 189061, 189065, 189069, 189073, + 189077, 189081, 189085, 189089, 189093, 189097, 189101, 189105, 189109, + 189113, 189117, 189121, 189125, 189129, 189133, 189137, 189141, 189145, + 189149, 189153, 189157, 189161, 189165, 189169, 189173, 189177, 189181, + 189185, 189189, 189193, 189197, 189201, 189205, 189209, 189213, 189217, + 189221, 189225, 189229, 189233, 189237, 189241, 189245, 189249, 189253, + 189257, 189261, 189265, 189269, 189273, 189277, 189281, 189285, 189289, + 189293, 189297, 189301, 189305, 189309, 189313, 189317, 189321, 189325, + 189329, 189333, 189337, 189341, 189345, 189349, 189353, 189357, 189361, + 189365, 189369, 189373, 189377, 189381, 189385, 189389, 189393, 189397, + 189401, 189405, 189409, 189413, 189417, 189421, 189425, 189429, 189433, + 189437, 189441, 189445, 189449, 189453, 189457, 189461, 189465, 189469, + 189473, 189477, 189481, 189485, 189489, 189493, 189497, 189501, 189505, + 189509, 189513, 189517, 189521, 189525, 189529, 189533, 189537, 189541, + 189545, 189549, 189553, 189557, 189561, 189565, 189569, 189573, 189577, + 189581, 189585, 189589, 189593, 189597, 189601, 189605, 189609, 189613, + 189617, 189621, 189625, 189629, 189633, 189637, 189641, 189645, 189649, + 189653, 189657, 189661, 189665, 189669, 189673, 189677, 189681, 189685, + 189689, 189693, 189697, 189701, 189705, 189709, 189713, 189717, 189721, + 189725, 189729, 189733, 189737, 189741, 189745, 189749, 189753, 189757, + 189761, 189765, 189769, 189773, 189777, 189781, 189785, 189789, 189793, + 189797, 189801, 189805, 189809, 189813, 189817, 189821, 189825, 189829, + 189833, 189837, 189841, 189845, 189849, 189853, 189857, 189861, 189865, + 189869, 189873, 189877, 189881, 189885, 189889, 189893, 189897, 189901, + 189905, 189909, 189913, 189917, 189921, 189925, 189929, 189933, 189937, + 189941, 189945, 189949, 189953, 189957, 189961, 189965, 189969, 189973, + 189977, 189981, 189985, 189989, 189993, 189997, 190001, 190005, 190009, + 190013, 190017, 190021, 190025, 190029, 190033, 190037, 190041, 190045, + 190049, 190053, 190057, 190061, 190065, 190069, 190073, 190077, 190081, + 190085, 190089, 190093, 190097, 190101, 190105, 190109, 190113, 190117, + 190121, 190125, 190129, 190133, 190137, 190141, 190145, 190149, 190153, + 190157, 190161, 190165, 190169, 190173, 190177, 190181, 190185, 190189, + 190193, 190197, 190201, 190205, 190209, 190213, 190217, 190221, 190225, + 190229, 190233, 190237, 190241, 190245, 190249, 190253, 190257, 190261, + 190265, 190269, 190273, 190277, 190281, 190285, 190289, 190293, 190297, + 190301, 190305, 190309, 190313, 190317, 190321, 190325, 190329, 190333, + 190337, 190341, 190345, 190349, 190353, 190357, 190361, 190365, 190369, + 190373, 190377, 190381, 190385, 190389, 190393, 190397, 190401, 190405, + 190409, 190413, 190417, 190421, 190425, 190429, 190433, 190437, 190441, + 190445, 190449, 190453, 190457, 190461, 190465, 190469, 190473, 190477, + 190481, 190485, 190489, 190493, 190497, 190501, 190505, 190509, 190513, + 190517, 190521, 190525, 190529, 190533, 190537, 190541, 190545, 190549, + 190553, 190557, 190561, 190565, 190569, 190573, 190577, 190581, 190585, + 190589, 190593, 190597, 190601, 190605, 190609, 190613, 190617, 190621, + 190625, 190629, 190633, 190637, 190641, 190645, 190649, 190653, 190657, + 190661, 190665, 190669, 190673, 190677, 190681, 190685, 190689, 190693, + 190697, 190701, 190705, 190709, 190713, 190717, 190721, 190725, 190729, + 190733, 190737, 190741, 190745, 190749, 190753, 190757, 190761, 190765, + 190769, 190773, 190777, 190781, 190785, 190789, 190793, 190797, 190801, + 190805, 190809, 190813, 190817, 190821, 190825, 190829, 190833, 190837, + 190841, 190845, 190849, 190853, 190857, 190861, 190865, 190869, 190873, + 190877, 190881, 190885, 190889, 190893, 190897, 190901, 190905, 190909, + 190913, 190917, 190921, 190925, 190929, 190933, 190937, 190941, 190945, + 190949, 190953, 190957, 190961, 190965, 190969, 190973, 190977, 190981, + 190985, 190989, 190993, 190997, 191001, 191005, 191009, 191013, 191017, + 191021, 191025, 191029, 191033, 191037, 191041, 191045, 191049, 191053, + 191057, 191061, 191065, 191069, 191073, 191077, 191081, 191085, 191089, + 191093, 191097, 191101, 191105, 191109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 189329, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 189333, - 189337, 189342, 189347, 189351, 189356, 189361, 189365, 189369, 189374, - 189379, 189383, 189387, 189391, 189395, 189401, 189405, 189410, 189414, - 189418, 189422, 189426, 189430, 189434, 189438, 189442, 189446, 189450, - 189454, 189459, 189464, 189469, 189474, 189480, 189486, 189493, 189500, - 189507, 189513, 189520, 189527, 189534, 189540, 189547, 189554, 189560, - 189567, 189574, 189580, 189587, 189594, 189600, 189607, 189614, 189620, - 189627, 189634, 189641, 189648, 189655, 189661, 189667, 189673, 189679, - 189684, 189690, 189696, 189703, 189710, 189717, 189723, 189730, 189737, - 189744, 189750, 189757, 189764, 189770, 189777, 189784, 189790, 189797, - 189804, 189810, 189817, 189824, 189830, 189837, 189844, 189851, 189858, - 189865, 189872, 189877, 189884, 189888, 189892, 189895, 189898, 189901, - 189904, 189907, 189910, 189913, 189916, 189919, 189922, 189925, 189928, - 189931, 189934, 189937, 189940, 189943, 189946, 189949, 189952, 189955, - 189958, 189961, 189964, 189967, 189970, 189973, 189976, 189979, 189982, - 189985, 189988, 189991, 189994, 189997, 190000, 190003, 190006, 190009, - 190012, 190015, 190018, 190021, 190024, 190027, 190030, 190033, 190036, - 190039, 190042, 190045, 190048, 190051, 190054, 190057, 190060, 190063, - 190066, 190069, 190072, 190075, 190078, 190081, 190084, 190087, 190090, - 190093, 190096, 190099, 190102, 190105, 190108, 190111, 190114, 190117, - 190120, 190123, 190126, 190129, 190132, 190135, 190138, 190141, 190144, - 190147, 190150, 190153, 190156, 190159, 190162, 190165, 190168, 190171, - 190174, 190177, 190180, 190183, 190186, 190189, 190192, 190195, 190198, - 190201, 190204, 190207, 190210, 190213, 190216, 190219, 190222, 190225, - 190228, 190231, 190234, 190237, 190240, 190243, 190246, 190249, 190252, - 190255, 190258, 190261, 190264, 190267, 190270, 190273, 190276, 190279, - 190282, 190285, 190288, 190291, 190294, 190297, 190300, 190303, 190306, - 190309, 190312, 190315, 190318, 190321, 190324, 190327, 190330, 190333, - 190336, 190339, 190342, 190345, 190348, 190351, 190354, 190357, 190360, - 190363, 190366, 190369, 190372, 190375, 190378, 190381, 190384, 190387, - 190390, 190393, 190396, 190399, 190402, 190405, 190408, 190411, 190414, - 190417, 190420, 190423, 190426, 190429, 190432, 190435, 190438, 190441, - 190444, 190447, 190450, 190453, 190456, 190459, 190462, 190465, 190468, - 190471, 190474, 190477, 190480, 190483, 190486, 190489, 190492, 190495, - 190498, 190501, 190504, 190507, 190510, 190513, 190516, 190519, 190522, - 190525, 190528, 190531, 190534, 190537, 190540, 190543, 190546, 190549, - 190552, 190555, 190558, 190561, 190564, 190567, 190570, 190573, 190576, - 190579, 190582, 190585, 190588, 190591, 190594, 190597, 190600, 190603, - 190606, 190609, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 190612, - 190614, 190616, 190621, 190623, 190628, 190630, 190635, 190637, 190642, - 190644, 190646, 190648, 190650, 190652, 190654, 190656, 190658, 190660, - 190664, 190668, 190670, 190672, 190676, 190680, 190685, 190687, 190689, - 190691, 190695, 190698, 190700, 190704, 190706, 190710, 190712, 190716, - 190719, 190721, 190725, 190729, 190731, 190737, 190739, 190744, 190746, - 190751, 190753, 190758, 190760, 190765, 190767, 190771, 190773, 190777, - 190779, 190786, 190788, 190790, 190792, 190797, 190799, 190801, 190803, - 190805, 190807, 190812, 190816, 190818, 190823, 190827, 190829, 190834, - 190838, 190840, 190845, 190849, 190851, 190853, 190855, 190857, 190861, - 190863, 190868, 190870, 190876, 190878, 190884, 190886, 190888, 190890, - 190894, 190896, 190903, 190905, 190912, 190914, 190920, 190926, 190928, - 190935, 190942, 190944, 190950, 190955, 190957, 190963, 190969, 190971, - 190977, 190983, 190985, 190991, 190995, 190997, 191002, 191004, 191006, - 191011, 191013, 191015, 191021, 191023, 191028, 191032, 191034, 191039, - 191043, 191045, 191051, 191053, 191057, 191059, 191063, 191065, 191072, - 191079, 191081, 191088, 191095, 191097, 191102, 191104, 191112, 191114, - 191120, 191122, 191128, 191130, 191134, 191136, 191142, 191144, 191148, - 191150, 191156, 191158, 191160, 191162, 191167, 191172, 191174, 191176, - 191186, 191191, 191198, 191205, 191210, 191215, 191227, 191231, 191235, - 191239, 191243, 191245, 191247, 191249, 191251, 191253, 191255, 191257, - 191259, 191261, 191263, 191265, 191267, 191269, 191271, 191273, 191275, - 191277, 191279, 191281, 191283, 191285, 191287, 191293, 191300, 191305, - 191313, 191321, 191326, 191332, 191334, 191336, 191338, 191340, 191342, - 191344, 191346, 191348, 191350, 191352, 191354, 191356, 191358, 191360, - 191362, 191364, 191376, 191381, 191383, 191385, 191391, 191403, 191409, - 191415, 191421, 191427, 191431, 191442, 191444, 191446, 191448, 191450, - 191452, 191454, 191456, 191458, 191460, 191462, 191464, 191466, 191468, - 191470, 191472, 191474, 191476, 191478, 191480, 191482, 191484, 191486, - 191488, 191490, 191492, 191494, 191496, 191498, 191500, 191502, 191504, - 191506, 191508, 191510, 191512, 191514, 191516, 191518, 191520, 191522, - 191524, 191526, 191528, 191530, 191532, 191534, 191536, 191538, 191540, - 191542, 191544, 191546, 191548, 191550, 191552, 191554, 191556, 191558, - 191560, 191562, 191564, 191566, 191568, 191570, 191572, 191574, 191576, - 191578, 191580, 191582, 191584, 191586, 191588, 191590, 191592, 191594, - 191596, 191598, 191600, 191602, 191604, 191606, 191608, 191610, 191612, - 191614, 191616, 191618, 191620, 191622, 191624, 191626, 191628, 191630, - 191632, 191634, 191636, 191638, 191640, 191642, 191644, 191646, 191648, - 191650, 191652, 191654, 191656, 191658, 191660, 191662, 191664, 191666, - 191668, 191670, 191672, 191674, 191676, 191678, 191680, 191682, 191684, - 191686, 191688, 191690, 191692, 191694, 191696, 191698, 191700, 191702, - 191704, 191706, 191708, 191710, 191712, 191714, 191716, 191718, 191720, - 191722, 191724, 191726, 191728, 191730, 191732, 191734, 191736, 191738, - 191740, 191742, 191744, 191746, 191748, 191750, 191752, 191754, 191756, - 191758, 191760, 191762, 191764, 191766, 191768, 191770, 191772, 191774, - 191776, 191778, 191780, 191782, 191784, 191786, 191788, 191790, 191792, - 191794, 191796, 191798, 191800, 191802, 191804, 191806, 191808, 191810, - 191812, 191814, 191816, 191818, 191820, 191822, 191824, 191826, 191828, - 191830, 191832, 191834, 191836, 191838, 191840, 191842, 191844, 191846, - 191848, 191850, 191852, 191854, 191856, 191858, 191860, 191862, 191864, - 191866, 191868, 191870, 191872, 191874, 191876, 191878, 191880, 191882, - 191884, 191886, 191888, 191890, 191892, 191894, 191896, 191898, 191900, - 191902, 191904, 191906, 191908, 191910, 191912, 191914, 191916, 191918, - 191920, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 191922, - 191926, 191930, 191935, 191939, 191943, 191947, 191951, 191955, 191959, - 191963, 191967, 191971, 191981, 191991, 192002, 192013, 192023, 192033, - 192043, 192053, 192067, 192081, 192095, 192109, 192118, 192127, 192140, - 192153, 192166, 192179, 192189, 192199, 192210, 192221, 192232, 192243, - 192254, 192263, 192273, 192283, 192293, 192303, 192314, 192325, 192336, - 192347, 192358, 192369, 192380, 192391, 192402, 192413, 192424, 192438, - 192449, 192463, 192471, 192482, 192490, 192498, 192506, 192514, 192522, - 192530, 192540, 192550, 192560, 192570, 192580, 192590, 192600, 192610, - 192618, 192627, 192636, 192645, 192654, 192662, 192670, 192680, 192690, - 192701, 192712, 192724, 192735, 192745, 192756, 192766, 192777, 192785, - 192792, 192799, 192806, 192813, 192820, 192827, 192834, 192841, 192849, - 192857, 192865, 192873, 192881, 192889, 192897, 192905, 192913, 192921, - 192929, 192934, 192938, 192942, 192946, 192950, 192954, 192958, 192962, - 192966, 192970, 192974, 192978, 192981, 192984, 192988, 192992, 192996, - 193000, 193004, 193008, 193012, 193016, 193020, 193024, 193028, 193032, - 193036, 193040, 193044, 193048, 193052, 193056, 193060, 193064, 193068, - 193072, 193076, 193080, 193084, 193088, 193092, 193096, 193100, 193104, - 193108, 193112, 193116, 193120, 193124, 193128, 193132, 193136, 193140, - 193144, 193148, 193152, 193156, 193160, 193164, 193168, 193172, 193176, - 193180, 193184, 193188, 193192, 193196, 193200, 193204, 193208, 193212, - 193216, 193220, 193224, 193228, 193232, 193236, 193240, 193244, 193248, - 193252, 193256, 193260, 193264, 193268, 193272, 193276, 193280, 193284, - 193288, 193292, 193296, 193300, 193304, 193308, 193312, 193316, 193320, - 193324, 193327, 193331, 193335, 193339, 193343, 193347, 193351, 193355, - 193359, 193363, 193367, 193371, 193375, 193379, 193383, 193387, 193391, - 193395, 193399, 193403, 193407, 193411, 193415, 193419, 193423, 193427, - 193431, 193435, 193439, 193443, 193447, 193451, 193455, 193459, 193463, - 193467, 193471, 193475, 193479, 193483, 193487, 193491, 193495, 193499, - 193503, 193507, 193511, 193515, 193519, 193523, 193527, 193531, 193535, - 193539, 193543, 193547, 193551, 193555, 193559, 193563, 193567, 193571, - 193575, 193579, 193583, 193587, 193591, 193595, 193599, 193603, 193607, - 193611, 193615, 193619, 193623, 193627, 193631, 193635, 193639, 193643, - 193647, 193651, 193655, 193659, 193663, 193667, 193671, 193675, 193679, - 193683, 193687, 193691, 193695, 193699, 193703, 193707, 193711, 193715, - 193719, 193723, 193727, 193731, 193735, 193739, 193743, 193747, 193751, - 193755, 193759, 193763, 193767, 193771, 193775, 193779, 193783, 193787, - 193791, 193795, 193799, 193803, 193807, 193811, 193815, 193819, 193823, - 193827, 193831, 193835, 193839, 193843, 193847, 193851, 193855, 193859, - 193863, 193867, 193871, 193875, 193879, 193883, 193887, 193891, 193895, - 193899, 193903, 193907, 193911, 193915, 193919, 193923, 193927, 193931, - 193935, 193939, 193943, 193947, 193951, 193955, 193959, 193963, 193967, - 193971, 193975, 193979, 193983, 193987, 193991, 193995, 193999, 194003, - 194007, 194011, 194015, 194019, 194023, 194027, 194031, 194035, 194039, - 194043, 194047, 194051, 194055, 194059, 194063, 194067, 194071, 194075, - 194079, 194083, 194087, 194091, 194096, 194101, 194106, 194110, 194116, - 194123, 194130, 194137, 194144, 194151, 194158, 194165, 194172, 194179, - 194186, 194193, 194200, 194207, 194213, 194220, 194227, 194233, 194240, - 194247, 194254, 194261, 194268, 194275, 194282, 194289, 194296, 194303, - 194310, 194317, 194324, 194330, 194336, 194342, 194349, 194358, 194367, - 194376, 194385, 194390, 194395, 194402, 194409, 194416, 194423, 194430, - 194436, 194442, 194448, 194454, 194460, 194466, 194472, 194477, 194483, - 194493, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 191113, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 191117, 191121, 191126, 191131, 191135, 191140, 191145, 191149, 191153, + 191158, 191163, 191167, 191171, 191175, 191179, 191185, 191189, 191194, + 191198, 191202, 191206, 191210, 191214, 191218, 191222, 191226, 191230, + 191234, 191238, 191243, 191248, 191253, 191258, 191264, 191270, 191277, + 191284, 191291, 191297, 191304, 191311, 191318, 191324, 191331, 191338, + 191344, 191351, 191358, 191364, 191371, 191378, 191384, 191391, 191398, + 191404, 191411, 191418, 191425, 191432, 191439, 191445, 191451, 191457, + 191463, 191468, 191474, 191480, 191487, 191494, 191501, 191507, 191514, + 191521, 191528, 191534, 191541, 191548, 191554, 191561, 191568, 191574, + 191581, 191588, 191594, 191601, 191608, 191614, 191621, 191628, 191635, + 191642, 191649, 191656, 191661, 191668, 191672, 191676, 191679, 191682, + 191685, 191688, 191691, 191694, 191697, 191700, 191703, 191706, 191709, + 191712, 191715, 191718, 191721, 191724, 191727, 191730, 191733, 191736, + 191739, 191742, 191745, 191748, 191751, 191754, 191757, 191760, 191763, + 191766, 191769, 191772, 191775, 191778, 191781, 191784, 191787, 191790, + 191793, 191796, 191799, 191802, 191805, 191808, 191811, 191814, 191817, + 191820, 191823, 191826, 191829, 191832, 191835, 191838, 191841, 191844, + 191847, 191850, 191853, 191856, 191859, 191862, 191865, 191868, 191871, + 191874, 191877, 191880, 191883, 191886, 191889, 191892, 191895, 191898, + 191901, 191904, 191907, 191910, 191913, 191916, 191919, 191922, 191925, + 191928, 191931, 191934, 191937, 191940, 191943, 191946, 191949, 191952, + 191955, 191958, 191961, 191964, 191967, 191970, 191973, 191976, 191979, + 191982, 191985, 191988, 191991, 191994, 191997, 192000, 192003, 192006, + 192009, 192012, 192015, 192018, 192021, 192024, 192027, 192030, 192033, + 192036, 192039, 192042, 192045, 192048, 192051, 192054, 192057, 192060, + 192063, 192066, 192069, 192072, 192075, 192078, 192081, 192084, 192087, + 192090, 192093, 192096, 192099, 192102, 192105, 192108, 192111, 192114, + 192117, 192120, 192123, 192126, 192129, 192132, 192135, 192138, 192141, + 192144, 192147, 192150, 192153, 192156, 192159, 192162, 192165, 192168, + 192171, 192174, 192177, 192180, 192183, 192186, 192189, 192192, 192195, + 192198, 192201, 192204, 192207, 192210, 192213, 192216, 192219, 192222, + 192225, 192228, 192231, 192234, 192237, 192240, 192243, 192246, 192249, + 192252, 192255, 192258, 192261, 192264, 192267, 192270, 192273, 192276, + 192279, 192282, 192285, 192288, 192291, 192294, 192297, 192300, 192303, + 192306, 192309, 192312, 192315, 192318, 192321, 192324, 192327, 192330, + 192333, 192336, 192339, 192342, 192345, 192348, 192351, 192354, 192357, + 192360, 192363, 192366, 192369, 192372, 192375, 192378, 192381, 192384, + 192387, 192390, 192393, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 192396, 192398, 192400, 192405, 192407, 192412, 192414, 192419, 192421, + 192426, 192428, 192430, 192432, 192434, 192436, 192438, 192440, 192442, + 192444, 192448, 192452, 192454, 192456, 192460, 192464, 192469, 192471, + 192473, 192475, 192479, 192482, 192484, 192488, 192490, 192494, 192496, + 192500, 192503, 192505, 192509, 192513, 192515, 192521, 192523, 192528, + 192530, 192535, 192537, 192542, 192544, 192549, 192551, 192555, 192557, + 192561, 192563, 192570, 192572, 192574, 192576, 192581, 192583, 192585, + 192587, 192589, 192591, 192593, 192598, 192602, 192604, 192609, 192613, + 192615, 192620, 192624, 192626, 192631, 192635, 192637, 192639, 192641, + 192643, 192647, 192649, 192654, 192656, 192662, 192664, 192670, 192672, + 192674, 192676, 192680, 192682, 192689, 192691, 192698, 192700, 192706, + 192712, 192714, 192721, 192728, 192730, 192736, 192741, 192743, 192749, + 192755, 192757, 192763, 192769, 192771, 192777, 192781, 192783, 192788, + 192790, 192792, 192797, 192799, 192801, 192807, 192809, 192814, 192818, + 192820, 192825, 192829, 192831, 192837, 192839, 192843, 192845, 192849, + 192851, 192858, 192865, 192867, 192874, 192881, 192883, 192888, 192890, + 192898, 192900, 192906, 192908, 192914, 192916, 192920, 192922, 192928, + 192930, 192934, 192936, 192942, 192944, 192946, 192948, 192953, 192958, + 192960, 192969, 192971, 192981, 192986, 192993, 193000, 193005, 193010, + 193022, 193026, 193030, 193034, 193038, 193040, 193042, 193044, 193046, + 193048, 193054, 193056, 193058, 193060, 193062, 193064, 193066, 193068, + 193070, 193072, 193074, 193076, 193078, 193080, 193082, 193084, 193086, + 193088, 193094, 193101, 193106, 193114, 193122, 193127, 193133, 193135, + 193137, 193139, 193141, 193143, 193145, 193147, 193149, 193151, 193153, + 193155, 193157, 193159, 193161, 193163, 193165, 193177, 193182, 193184, + 193186, 193192, 193204, 193210, 193216, 193222, 193228, 193232, 193243, + 193245, 193247, 193249, 193251, 193253, 193255, 193257, 193259, 193261, + 193263, 193265, 193267, 193269, 193271, 193273, 193275, 193277, 193279, + 193281, 193283, 193285, 193287, 193289, 193291, 193293, 193295, 193297, + 193299, 193301, 193303, 193305, 193307, 193309, 193311, 193313, 193315, + 193317, 193319, 193321, 193323, 193325, 193327, 193329, 193331, 193333, + 193335, 193337, 193339, 193341, 193343, 193345, 193347, 193349, 193351, + 193353, 193355, 193357, 193359, 193361, 193363, 193365, 193367, 193369, + 193371, 193373, 193375, 193377, 193379, 193381, 193383, 193385, 193387, + 193389, 193391, 193393, 193395, 193397, 193399, 193401, 193403, 193405, + 193407, 193409, 193411, 193413, 193415, 193417, 193419, 193421, 193423, + 193425, 193427, 193429, 193431, 193433, 193435, 193437, 193439, 193441, + 193443, 193445, 193447, 193449, 193451, 193453, 193455, 193457, 193459, + 193461, 193463, 193465, 193467, 193469, 193471, 193473, 193475, 193477, + 193479, 193481, 193483, 193485, 193487, 193489, 193491, 193493, 193495, + 193497, 193499, 193501, 193503, 193505, 193507, 193509, 193511, 193513, + 193515, 193517, 193519, 193521, 193523, 193525, 193527, 193529, 193531, + 193533, 193535, 193537, 193539, 193541, 193543, 193545, 193547, 193549, + 193551, 193553, 193555, 193557, 193559, 193561, 193563, 193565, 193567, + 193569, 193571, 193573, 193575, 193577, 193579, 193581, 193583, 193585, + 193587, 193589, 193591, 193593, 193595, 193597, 193599, 193601, 193603, + 193605, 193607, 193609, 193611, 193613, 193615, 193617, 193619, 193621, + 193623, 193625, 193627, 193629, 193631, 193633, 193635, 193637, 193639, + 193641, 193643, 193645, 193647, 193649, 193651, 193653, 193655, 193657, + 193659, 193661, 193663, 193665, 193667, 193669, 193671, 193673, 193675, + 193677, 193679, 193681, 193683, 193685, 193687, 193689, 193691, 193693, + 193695, 193697, 193699, 193701, 193703, 193705, 193707, 193709, 193711, + 193713, 193715, 193717, 193719, 193721, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 193723, 193727, 193731, 193736, 193740, 193744, 193748, + 193752, 193756, 193760, 193764, 193768, 193772, 193782, 193792, 193803, + 193814, 193824, 193834, 193844, 193854, 193868, 193882, 193896, 193910, + 193919, 193928, 193941, 193954, 193967, 193980, 193990, 194000, 194011, + 194022, 194033, 194044, 194055, 194064, 194074, 194084, 194094, 194104, + 194115, 194126, 194137, 194148, 194159, 194170, 194181, 194192, 194203, + 194214, 194225, 194239, 194250, 194264, 194272, 194283, 194291, 194299, + 194307, 194315, 194323, 194331, 194341, 194351, 194361, 194371, 194381, + 194391, 194401, 194411, 194419, 194428, 194437, 194446, 194455, 194463, + 194471, 194481, 194491, 194502, 194513, 194525, 194536, 194546, 194557, + 194567, 194578, 194586, 194593, 194600, 194607, 194614, 194621, 194628, + 194635, 194642, 194650, 194658, 194666, 194674, 194682, 194690, 194698, + 194706, 194714, 194722, 194730, 194735, 194739, 194743, 194747, 194751, + 194755, 194759, 194763, 194767, 194771, 194775, 194779, 194782, 194785, + 194789, 194793, 194797, 194801, 194805, 194809, 194813, 194817, 194821, + 194825, 194829, 194833, 194837, 194841, 194845, 194849, 194853, 194857, + 194861, 194865, 194869, 194873, 194877, 194881, 194885, 194889, 194893, + 194897, 194901, 194905, 194909, 194913, 194917, 194921, 194925, 194929, + 194933, 194937, 194941, 194945, 194949, 194953, 194957, 194961, 194965, + 194969, 194973, 194977, 194981, 194985, 194989, 194993, 194997, 195001, + 195005, 195009, 195013, 195017, 195021, 195025, 195029, 195033, 195037, + 195041, 195045, 195049, 195053, 195057, 195061, 195065, 195069, 195073, + 195077, 195081, 195085, 195089, 195093, 195097, 195101, 195105, 195109, + 195113, 195117, 195121, 195125, 195128, 195132, 195136, 195140, 195144, + 195148, 195152, 195156, 195160, 195164, 195168, 195172, 195176, 195180, + 195184, 195188, 195192, 195196, 195200, 195204, 195208, 195212, 195216, + 195220, 195224, 195228, 195232, 195236, 195240, 195244, 195248, 195252, + 195256, 195260, 195264, 195268, 195272, 195276, 195280, 195284, 195288, + 195292, 195296, 195300, 195304, 195308, 195312, 195316, 195320, 195324, + 195328, 195332, 195336, 195340, 195344, 195348, 195352, 195356, 195360, + 195364, 195368, 195372, 195376, 195380, 195384, 195388, 195392, 195396, + 195400, 195404, 195408, 195412, 195416, 195420, 195424, 195428, 195432, + 195436, 195440, 195444, 195448, 195452, 195456, 195460, 195464, 195468, + 195472, 195476, 195480, 195484, 195488, 195492, 195496, 195500, 195504, + 195508, 195512, 195516, 195520, 195524, 195528, 195532, 195536, 195540, + 195544, 195548, 195552, 195556, 195560, 195564, 195568, 195572, 195576, + 195580, 195584, 195588, 195592, 195596, 195600, 195604, 195608, 195612, + 195616, 195620, 195624, 195628, 195632, 195636, 195640, 195644, 195648, + 195652, 195656, 195660, 195664, 195668, 195672, 195676, 195680, 195684, + 195688, 195692, 195696, 195700, 195704, 195708, 195712, 195716, 195720, + 195724, 195728, 195732, 195736, 195740, 195744, 195748, 195752, 195756, + 195760, 195764, 195768, 195772, 195776, 195780, 195784, 195788, 195792, + 195796, 195800, 195804, 195808, 195812, 195816, 195820, 195824, 195828, + 195832, 195836, 195840, 195844, 195848, 195852, 195856, 195860, 195864, + 195868, 195872, 195876, 195880, 195884, 195888, 195892, 195897, 195902, + 195907, 195911, 195917, 195924, 195931, 195938, 195945, 195952, 195959, + 195966, 195973, 195980, 195987, 195994, 196001, 196008, 196014, 196021, + 196028, 196034, 196041, 196048, 196055, 196062, 196069, 196076, 196083, + 196090, 196097, 196104, 196111, 196118, 196125, 196131, 196137, 196143, + 196150, 196159, 196168, 196177, 196186, 196191, 196196, 196203, 196210, + 196217, 196224, 196231, 196237, 196243, 196249, 196255, 196261, 196267, + 196273, 196278, 196284, 196294, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; /* name->code dictionary */ @@ -25185,7 +25364,7 @@ static const unsigned int code_hash[] = { 74224, 4851, 0, 0, 0, 0, 7929, 0, 0, 0, 0, 127931, 0, 42833, 983091, 12064, 110752, 129548, 194597, 69850, 65842, 0, 0, 0, 78159, 68476, 72392, 1373, 0, 0, 5816, 0, 0, 4231, 0, 0, 4233, 4234, 4232, 68885, - 70351, 0, 7404, 72393, 0, 0, 0, 0, 0, 41601, 8874, 0, 0, 0, 0, 0, 0, + 70351, 0, 7404, 72393, 0, 0, 0, 0, 0, 41601, 8874, 0, 0, 0, 128498, 0, 0, 41603, 9784, 0, 9188, 41600, 0, 0, 0, 0, 3535, 0, 0, 0, 66797, 0, 74491, 0, 3404, 100419, 0, 72411, 1759, 100417, 0, 100418, 69972, 11240, 121038, 100416, 127764, 0, 0, 0, 0, 0, 69970, 0, 0, 9834, 43249, 2234, 983891, 0, @@ -25197,102 +25376,103 @@ static const unsigned int code_hash[] = { 5194, 11657, 128353, 0, 0, 0, 0, 0, 120766, 100525, 0, 0, 74350, 0, 10682, 110820, 10602, 800, 70044, 118883, 0, 0, 64930, 118940, 67853, 72001, 0, 762, 120485, 0, 0, 0, 10906, 1353, 6960, 0, 0, 5828, 8724, 0, - 0, 118548, 0, 0, 7080, 0, 128806, 0, 0, 72388, 0, 11859, 0, 0, 68878, 0, - 0, 0, 7240, 0, 556, 0, 118544, 0, 0, 0, 72397, 0, 0, 0, 0, 0, 0, 0, 0, - 72986, 0, 0, 43931, 0, 11093, 0, 0, 125016, 7341, 66801, 68527, 0, 1874, - 0, 0, 129314, 0, 0, 0, 0, 0, 0, 7688, 0, 0, 9036, 0, 0, 66389, 0, 121347, - 0, 0, 10100, 0, 2725, 0, 0, 43981, 42128, 0, 0, 68146, 0, 0, 0, 0, 71349, - 7859, 1945, 0, 0, 0, 65918, 7188, 9992, 0, 7389, 127008, 71341, 0, 0, 0, - 528, 129681, 44017, 11429, 71347, 0, 0, 120864, 0, 0, 0, 11530, 73102, - 6188, 0, 0, 68208, 1823, 0, 0, 92928, 0, 64843, 7233, 92929, 0, 0, 6639, - 0, 0, 123149, 0, 1176, 0, 0, 8276, 128667, 0, 0, 68892, 42931, 0, 0, 0, - 0, 0, 0, 0, 5388, 0, 0, 0, 11310, 0, 123607, 0, 68888, 4199, 119264, 0, - 119020, 0, 0, 9560, 0, 0, 43869, 0, 0, 0, 83172, 0, 0, 0, 83173, 101559, - 128875, 0, 0, 74327, 0, 0, 0, 0, 0, 123623, 68886, 0, 0, 0, 8408, 64704, - 0, 0, 0, 0, 118711, 67999, 0, 0, 0, 0, 43049, 0, 43050, 73028, 0, 0, 0, - 0, 0, 127396, 0, 69847, 9322, 0, 0, 129321, 68192, 120507, 983634, 0, 0, - 0, 6199, 67249, 0, 0, 0, 0, 11329, 66285, 0, 983086, 0, 0, 0, 0, 41335, - 118866, 43401, 0, 41334, 0, 0, 0, 983481, 71997, 983480, 128114, 0, - 42627, 0, 32, 6187, 0, 123619, 983477, 3665, 121083, 42871, 983118, - 41336, 0, 0, 983473, 0, 0, 0, 4412, 0, 0, 0, 0, 119533, 0, 4181, 0, 0, - 127589, 0, 0, 71453, 6181, 74755, 917895, 0, 0, 0, 0, 121107, 0, 0, - 10073, 0, 100738, 127186, 0, 42844, 7498, 1098, 92565, 119530, 0, 0, - 10207, 0, 983230, 0, 983555, 0, 9234, 0, 6182, 0, 92552, 0, 0, 0, 0, - 5471, 9461, 6697, 0, 5473, 0, 0, 0, 0, 0, 0, 70073, 0, 0, 7767, 8304, - 41339, 0, 983491, 69450, 0, 0, 983489, 43855, 41337, 0, 0, 0, 129706, 0, - 0, 0, 72396, 0, 0, 0, 42633, 0, 0, 0, 0, 0, 0, 0, 70005, 129506, 0, 0, 0, - 129580, 69817, 128299, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1437, 41617, 0, 0, 0, - 128853, 0, 0, 0, 0, 0, 128529, 12113, 0, 42772, 0, 0, 7693, 10749, 67485, - 65210, 5773, 978, 128134, 0, 41619, 10239, 0, 0, 0, 74328, 0, 9748, 0, 0, - 0, 0, 0, 0, 0, 70681, 0, 72811, 0, 67464, 0, 92776, 0, 0, 2379, 11325, 0, - 0, 67854, 0, 78547, 42209, 0, 120392, 2369, 0, 984003, 984004, 0, 0, - 73936, 7008, 69415, 122919, 0, 43841, 2367, 127827, 983888, 0, 2375, - 8060, 6194, 0, 0, 119084, 0, 0, 0, 0, 6961, 0, 0, 0, 68426, 0, 42862, 0, - 0, 6192, 127900, 42771, 0, 0, 11435, 128445, 118797, 120800, 0, 12892, 0, - 128621, 67149, 0, 0, 0, 0, 120707, 0, 0, 19954, 0, 121164, 8983, 0, 0, 0, - 0, 0, 6198, 121344, 0, 196, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 983509, 41323, 0, 0, 92289, 0, 0, 0, 983505, 41321, 12907, 3048, 7752, - 41320, 0, 0, 12819, 111247, 72127, 0, 0, 0, 0, 0, 72971, 0, 0, 0, 0, - 78650, 78649, 0, 41326, 0, 11806, 43167, 0, 1245, 0, 66463, 0, 0, 0, 0, - 0, 194619, 0, 194618, 0, 0, 194620, 0, 70403, 325, 12874, 128454, 74178, - 0, 0, 119110, 0, 0, 0, 0, 0, 0, 983563, 92175, 0, 0, 0, 121049, 0, 0, 0, - 0, 0, 0, 110844, 11776, 0, 19908, 0, 0, 0, 8753, 69278, 0, 0, 9511, - 43493, 0, 93032, 6205, 0, 0, 0, 0, 0, 0, 0, 0, 120269, 0, 41607, 0, 0, - 120617, 0, 0, 0, 7005, 41609, 9580, 0, 401, 0, 43779, 0, 127962, 0, - 65486, 0, 12857, 0, 11983, 0, 0, 0, 121371, 0, 194971, 74258, 983647, 0, - 0, 0, 0, 0, 8295, 6200, 0, 127864, 0, 0, 71435, 0, 92523, 0, 128631, 0, - 0, 125197, 0, 0, 0, 127556, 0, 0, 0, 64775, 0, 68862, 120590, 0, 0, - 129959, 8074, 8199, 126641, 1907, 127269, 4432, 127271, 10808, 120668, - 127272, 127259, 3888, 127261, 72724, 127263, 127262, 127265, 123169, - 121195, 127250, 66879, 127252, 100422, 66023, 67363, 7663, 0, 0, 0, 0, - 66321, 0, 12814, 127248, 127169, 0, 0, 194603, 7641, 92694, 0, 0, 0, 0, - 74320, 120818, 120268, 0, 128475, 0, 110627, 0, 9622, 128972, 120264, 0, - 0, 0, 0, 68319, 0, 0, 71484, 118613, 0, 0, 69906, 0, 0, 947, 0, 194586, - 129059, 10969, 119935, 7613, 119937, 119936, 4795, 119930, 119933, 7376, - 0, 0, 0, 72343, 0, 0, 0, 0, 119919, 7216, 119921, 7217, 119915, 7218, - 119917, 7219, 119927, 119926, 119929, 119928, 7213, 119922, 7214, 7215, - 128622, 0, 8880, 7685, 128849, 0, 0, 119618, 119853, 8187, 119913, 12815, - 7236, 7915, 71906, 0, 121284, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 10468, 0, 0, 0, 0, 0, 0, 0, 0, 917909, 0, 110633, 1616, 3795, 67732, - 11529, 0, 126225, 0, 0, 1138, 194577, 12677, 0, 0, 3239, 0, 0, 194809, - 194583, 0, 42164, 0, 11778, 67473, 43259, 118543, 119073, 0, 0, 0, 67094, - 129638, 0, 78421, 128123, 78418, 0, 0, 0, 0, 43959, 43960, 0, 72257, 0, - 9359, 78416, 0, 0, 0, 6662, 0, 0, 3863, 0, 41329, 55266, 0, 127822, - 41328, 75026, 194569, 129516, 0, 0, 2178, 119595, 569, 0, 0, 0, 119085, - 110669, 0, 0, 11610, 11368, 0, 194570, 41331, 1006, 127747, 120883, 1550, - 8201, 0, 194811, 5499, 43956, 77908, 77910, 77906, 43957, 77904, 77905, - 128410, 0, 0, 129581, 100447, 43955, 77913, 0, 0, 5511, 0, 983721, 0, - 69241, 8255, 5512, 128560, 119560, 127858, 64313, 127928, 5906, 1119, - 128180, 67088, 983364, 0, 113798, 0, 66423, 0, 0, 0, 67089, 0, 0, 0, 0, - 128177, 983728, 0, 0, 0, 5821, 6186, 129960, 128034, 19961, 0, 983719, 0, - 65138, 302, 41113, 41115, 0, 6637, 5907, 128789, 0, 43642, 0, 128625, 0, - 70345, 5513, 6666, 100567, 78442, 5510, 0, 0, 0, 983725, 78437, 0, 0, 0, - 110838, 0, 0, 0, 92710, 0, 0, 0, 0, 0, 74497, 92395, 120511, 6929, 69412, - 0, 110835, 64442, 0, 0, 74496, 0, 6674, 43397, 0, 1476, 0, 0, 72276, - 3233, 0, 0, 10164, 118555, 0, 3530, 67243, 0, 111219, 6656, 0, 0, 74647, - 8512, 72275, 74261, 8967, 0, 0, 0, 72277, 7986, 73782, 120556, 9006, - 983562, 72273, 0, 7853, 0, 983357, 0, 0, 0, 0, 983971, 0, 0, 0, 0, 0, 0, - 0, 0, 127971, 67983, 13296, 517, 0, 0, 0, 41528, 19923, 65454, 0, 0, 0, - 10531, 7784, 41526, 71727, 0, 8057, 1126, 73895, 0, 0, 130040, 119186, - 4251, 8235, 43142, 0, 489, 71733, 4250, 71731, 110721, 43151, 94177, - 71725, 0, 121238, 0, 0, 0, 110726, 0, 8711, 6183, 110722, 110723, 0, 0, - 7623, 0, 0, 9235, 12760, 74176, 0, 0, 0, 0, 3743, 11514, 11078, 74582, 0, - 0, 126597, 0, 0, 0, 0, 983907, 267, 3393, 127504, 2364, 0, 69233, 6958, - 0, 6201, 0, 42360, 0, 10652, 41612, 917802, 3402, 917801, 3398, 0, 0, 0, - 3391, 70683, 0, 92541, 128017, 126087, 126590, 0, 12767, 0, 983377, - 64261, 0, 127537, 70852, 70347, 0, 6673, 0, 0, 129346, 12438, 0, 0, 0, - 71128, 0, 9053, 43954, 74523, 0, 0, 0, 6195, 0, 6660, 0, 917760, 917793, - 0, 12629, 0, 0, 0, 0, 0, 127940, 0, 0, 0, 65448, 0, 0, 121084, 129688, - 43949, 0, 78099, 0, 983382, 0, 0, 0, 5741, 1131, 0, 0, 74862, 0, 43952, - 42533, 119598, 78107, 0, 0, 43950, 121297, 118990, 7691, 43951, 578, 0, - 0, 0, 42514, 74547, 74196, 120608, 74561, 0, 983976, 0, 0, 0, 0, 0, 0, 0, - 0, 7241, 0, 93846, 119167, 0, 12811, 78082, 3946, 0, 10998, 66807, 673, - 0, 0, 0, 0, 119301, 0, 68890, 0, 0, 78085, 10267, 0, 74560, 78083, 0, - 8729, 0, 0, 0, 0, 0, 0, 0, 119296, 0, 0, 0, 2181, 983460, 731, 0, 71904, - 128316, 0, 0, 0, 1175, 0, 68167, 0, 0, 10793, 0, 67644, 7723, 983455, 0, - 0, 0, 0, 5273, 0, 5269, 0, 69607, 2404, 5267, 124967, 124913, 0, 5277, 0, - 0, 6189, 65469, 1314, 0, 0, 118873, 8785, 0, 0, 127527, 68414, 43535, - 9204, 0, 3879, 0, 71696, 6197, 9497, 0, 7567, 64484, 78128, 41390, 41379, + 0, 118548, 0, 0, 7080, 0, 128806, 122979, 0, 72388, 0, 11859, 0, 0, + 68878, 0, 0, 0, 7240, 0, 556, 0, 118544, 0, 0, 0, 72397, 0, 0, 0, 0, 0, + 0, 0, 0, 72986, 0, 0, 43931, 0, 11093, 0, 0, 122960, 7341, 66801, 68527, + 0, 1874, 0, 0, 129314, 0, 0, 0, 0, 0, 0, 7688, 0, 0, 9036, 0, 0, 66389, + 0, 121347, 0, 0, 10100, 0, 2725, 0, 0, 43981, 42128, 0, 0, 68146, 0, 0, + 0, 0, 71349, 7859, 1945, 0, 0, 0, 65918, 7188, 9992, 0, 7389, 127008, + 71341, 0, 0, 0, 528, 129681, 44017, 11429, 71347, 0, 0, 120864, 0, 0, 0, + 11530, 73102, 6188, 0, 0, 68208, 1823, 0, 0, 92928, 0, 64843, 7233, + 92929, 0, 0, 6639, 0, 0, 123149, 0, 1176, 0, 0, 8276, 128667, 0, 0, + 68892, 42931, 0, 0, 0, 0, 0, 0, 0, 5388, 0, 0, 0, 11310, 0, 123607, 0, + 68888, 4199, 119264, 0, 119020, 0, 0, 9560, 0, 0, 43869, 0, 0, 0, 83172, + 0, 0, 0, 83173, 101559, 128875, 0, 0, 74327, 0, 0, 0, 0, 0, 123623, + 68886, 0, 0, 0, 8408, 64704, 0, 0, 0, 0, 118711, 67999, 0, 0, 0, 0, + 43049, 0, 43050, 73028, 0, 0, 0, 0, 0, 127396, 0, 69847, 9322, 0, 0, + 129321, 68192, 120507, 983634, 0, 0, 0, 6199, 67249, 0, 0, 0, 0, 11329, + 66285, 0, 983086, 0, 0, 0, 0, 41335, 118866, 43401, 0, 41334, 0, 0, 0, + 983484, 71997, 983483, 128114, 0, 42627, 0, 32, 6187, 0, 123619, 983480, + 3665, 121083, 42871, 983119, 41336, 0, 0, 983476, 0, 0, 0, 4412, 0, 0, 0, + 0, 119533, 0, 4181, 0, 0, 127589, 0, 0, 71453, 6181, 74755, 917895, 0, 0, + 0, 73557, 121107, 0, 0, 10073, 0, 100738, 127186, 0, 42844, 7498, 1098, + 92565, 119530, 0, 0, 10207, 0, 983233, 0, 983555, 0, 9234, 0, 6182, 0, + 92552, 0, 0, 0, 0, 5471, 9461, 6697, 0, 5473, 0, 0, 0, 0, 0, 0, 70073, 0, + 0, 7767, 8304, 41339, 0, 983494, 69450, 0, 0, 983492, 43855, 41337, 0, 0, + 0, 129706, 0, 0, 0, 72396, 0, 0, 0, 42633, 0, 0, 0, 0, 0, 0, 0, 70005, + 129506, 0, 0, 0, 129580, 69817, 128299, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1437, + 41617, 0, 0, 0, 128853, 0, 0, 0, 0, 0, 128529, 12113, 0, 42772, 0, 0, + 7693, 10749, 67485, 65210, 5773, 978, 128134, 0, 41619, 10239, 0, 0, 0, + 74328, 0, 9748, 0, 0, 0, 0, 0, 0, 0, 70681, 0, 72811, 0, 67464, 0, 92776, + 0, 0, 2379, 11325, 0, 0, 67854, 0, 78547, 42209, 0, 120392, 2369, 0, + 984003, 984004, 0, 0, 73936, 7008, 69415, 122919, 0, 43841, 2367, 127827, + 983888, 0, 2375, 8060, 6194, 0, 0, 119084, 0, 0, 0, 0, 6961, 0, 0, 0, + 68426, 0, 42862, 0, 0, 6192, 127900, 42771, 0, 0, 11435, 128445, 118797, + 120800, 0, 12892, 0, 128621, 67149, 0, 0, 0, 0, 120707, 0, 0, 19954, 0, + 121164, 8983, 0, 0, 0, 0, 0, 6198, 121344, 0, 196, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 983512, 41323, 0, 0, 92289, 0, 0, 0, 983508, 41321, + 12907, 3048, 7752, 41320, 0, 0, 12819, 111247, 72127, 0, 0, 0, 0, 0, + 72971, 0, 0, 0, 0, 78650, 78649, 0, 41326, 0, 11806, 43167, 0, 1245, 0, + 66463, 0, 0, 0, 0, 0, 194619, 0, 194618, 0, 0, 194620, 0, 70403, 325, + 12874, 128454, 74178, 0, 0, 119110, 0, 0, 0, 0, 0, 0, 983563, 92175, 0, + 125016, 0, 121049, 0, 0, 0, 0, 0, 0, 110844, 11776, 0, 19908, 0, 0, 0, + 8753, 69278, 0, 0, 9511, 43493, 0, 93032, 6205, 0, 0, 0, 0, 0, 78928, 0, + 0, 120269, 0, 41607, 0, 0, 120617, 0, 0, 0, 7005, 41609, 9580, 0, 401, 0, + 43779, 0, 127962, 0, 65486, 0, 12857, 0, 11983, 0, 0, 0, 121371, 0, + 194971, 74258, 983647, 0, 0, 0, 0, 0, 8295, 6200, 0, 127864, 0, 0, 71435, + 0, 92523, 0, 128631, 0, 0, 125197, 0, 100426, 0, 127556, 0, 0, 0, 64775, + 0, 68862, 120590, 0, 0, 129959, 8074, 8199, 126641, 1907, 127269, 4432, + 127271, 10808, 120668, 127272, 127259, 3888, 127261, 72724, 127263, + 127262, 127265, 123169, 121195, 127250, 66879, 127252, 100422, 66023, + 67363, 7663, 0, 0, 0, 0, 66321, 0, 12814, 127248, 127169, 0, 0, 194603, + 7641, 92694, 0, 0, 0, 0, 74320, 120818, 120268, 0, 128475, 0, 110627, 0, + 9622, 128972, 120264, 0, 0, 0, 0, 68319, 0, 0, 71484, 118613, 0, 0, + 69906, 0, 0, 947, 0, 194586, 129059, 10969, 119935, 7613, 119937, 119936, + 4795, 119930, 119933, 7376, 0, 0, 0, 72343, 69373, 0, 0, 0, 119919, 7216, + 119921, 7217, 119915, 7218, 119917, 7219, 119927, 119926, 119929, 119928, + 7213, 119922, 7214, 7215, 128622, 0, 8880, 7685, 128849, 0, 0, 119618, + 119853, 8187, 119913, 12815, 7236, 7915, 71906, 0, 121284, 0, 0, 0, 0, 0, + 0, 0, 122969, 0, 0, 0, 0, 0, 10468, 0, 0, 0, 0, 0, 0, 0, 0, 917909, 0, + 110633, 1616, 3795, 67732, 11529, 0, 126225, 0, 0, 1138, 194577, 12677, + 0, 0, 3239, 0, 0, 194809, 194583, 0, 42164, 0, 11778, 67473, 43259, + 118543, 119073, 122975, 0, 0, 67094, 129638, 0, 78421, 128123, 78418, 0, + 0, 0, 0, 43959, 43960, 0, 72257, 0, 9359, 78416, 0, 0, 0, 6662, 0, 0, + 3863, 0, 41329, 55266, 0, 127822, 41328, 75026, 194569, 129516, 0, 0, + 2178, 119595, 569, 0, 0, 0, 119085, 110669, 0, 0, 11610, 11368, 0, + 194570, 41331, 1006, 127747, 120883, 1550, 8201, 0, 194811, 5499, 43956, + 77908, 77910, 77906, 43957, 77904, 77905, 128410, 0, 0, 129581, 100447, + 43955, 77913, 122989, 0, 5511, 0, 983721, 0, 69241, 8255, 5512, 128560, + 119560, 127858, 64313, 127928, 5906, 1119, 128180, 67088, 983367, 0, + 113798, 0, 66423, 0, 0, 0, 67089, 0, 0, 0, 0, 128177, 983728, 0, 0, 0, + 5821, 6186, 129960, 128034, 19961, 0, 983719, 0, 65138, 302, 41113, + 41115, 0, 6637, 5907, 128789, 0, 43642, 0, 128625, 0, 70345, 5513, 6666, + 100567, 78442, 5510, 0, 0, 0, 983725, 78437, 0, 0, 0, 110838, 0, 0, 0, + 92710, 0, 0, 0, 0, 0, 74497, 92395, 120511, 6929, 69412, 0, 110835, + 64442, 0, 0, 74496, 0, 6674, 43397, 0, 1476, 0, 0, 72276, 3233, 0, 0, + 10164, 118555, 0, 3530, 67243, 0, 111219, 6656, 0, 0, 74647, 8512, 72275, + 74261, 8967, 0, 0, 0, 72277, 7986, 73782, 120556, 9006, 983562, 72273, 0, + 7853, 0, 983360, 0, 0, 0, 0, 983971, 0, 0, 0, 0, 0, 0, 0, 0, 127971, + 67983, 13296, 517, 0, 0, 0, 41528, 19923, 65454, 73518, 0, 0, 10531, + 7784, 41526, 71727, 0, 8057, 1126, 73895, 0, 0, 130040, 119186, 4251, + 8235, 43142, 0, 489, 71733, 4250, 71731, 110721, 43151, 94177, 71725, 0, + 121238, 0, 0, 0, 110726, 0, 8711, 6183, 110722, 110723, 0, 0, 7623, 0, 0, + 9235, 12760, 74176, 0, 0, 0, 0, 3743, 11514, 11078, 74582, 0, 0, 126597, + 0, 0, 0, 0, 983907, 267, 3393, 127504, 2364, 0, 69233, 6958, 0, 6201, 0, + 42360, 0, 10652, 41612, 917802, 3402, 917801, 3398, 0, 0, 0, 3391, 70683, + 0, 92541, 128017, 126087, 126590, 0, 12767, 0, 983380, 64261, 0, 127537, + 70852, 70347, 0, 6673, 0, 0, 129346, 12438, 0, 0, 0, 71128, 0, 9053, + 43954, 74523, 0, 0, 0, 6195, 0, 6660, 0, 917760, 917793, 0, 12629, 0, 0, + 0, 0, 0, 127940, 0, 0, 0, 65448, 0, 0, 121084, 129688, 43949, 0, 78099, + 0, 983385, 0, 0, 0, 5741, 1131, 0, 0, 74862, 0, 43952, 42533, 119598, + 78107, 0, 0, 43950, 121297, 118990, 7691, 43951, 578, 0, 0, 0, 42514, + 74547, 74196, 120608, 74561, 0, 983976, 0, 0, 0, 0, 0, 0, 0, 0, 7241, 0, + 93846, 119167, 0, 12811, 78082, 3946, 0, 10998, 66807, 673, 0, 0, 0, 0, + 119301, 0, 68890, 0, 0, 78085, 10267, 0, 74560, 78083, 0, 8729, 0, 0, 0, + 0, 0, 0, 0, 119296, 0, 0, 0, 2181, 983463, 731, 0, 71904, 128316, 0, + 73539, 0, 1175, 0, 68167, 0, 0, 10793, 0, 67644, 7723, 983458, 0, 0, 0, + 0, 5273, 0, 5269, 0, 69607, 2404, 5267, 124967, 124913, 0, 5277, 0, 0, + 6189, 65469, 1314, 0, 0, 118873, 8785, 0, 0, 127527, 68414, 43535, 9204, + 0, 3879, 0, 71696, 6197, 9497, 0, 7567, 64484, 78128, 41390, 41379, 41882, 67647, 67279, 70085, 0, 121413, 41388, 64446, 41392, 64288, 41387, 0, 8706, 10675, 0, 700, 0, 5775, 0, 7088, 74756, 7499, 0, 78120, 78111, 67251, 126557, 0, 0, 128945, 10311, 78115, 6665, 11115, 0, 7618, 10821, @@ -25304,17 +25484,17 @@ static const unsigned int code_hash[] = { 42087, 3063, 0, 0, 7838, 0, 129282, 0, 0, 67968, 0, 128582, 9078, 92446, 0, 0, 0, 0, 0, 0, 119586, 0, 7750, 128422, 68237, 6190, 0, 0, 0, 72340, 9857, 7014, 9856, 0, 92620, 120547, 0, 8481, 0, 6202, 0, 10920, 67970, 0, - 0, 983294, 0, 7843, 65818, 66824, 0, 0, 0, 0, 0, 0, 0, 6657, 207, 0, + 0, 983297, 0, 7843, 65818, 66824, 0, 73481, 0, 0, 0, 0, 0, 6657, 207, 0, 69728, 74819, 0, 0, 0, 0, 0, 0, 0, 0, 41368, 43974, 488, 0, 0, 71339, 10157, 118700, 43034, 11982, 0, 0, 0, 0, 0, 41372, 6669, 8504, 72103, 0, 41367, 129328, 119272, 0, 11726, 8261, 129793, 304, 129799, 129795, - 129822, 129807, 113683, 983236, 238, 74522, 0, 0, 19905, 120577, 983471, - 129200, 41044, 67640, 67302, 64814, 9912, 65939, 983467, 0, 0, 0, 917925, + 129822, 129807, 113683, 983239, 238, 74522, 0, 0, 19905, 120577, 122968, + 129200, 41044, 67640, 67302, 64814, 9912, 65939, 983470, 0, 0, 0, 917925, 0, 0, 309, 6622, 0, 10858, 0, 67636, 0, 72749, 0, 0, 0, 67637, 123138, 9712, 68680, 43970, 0, 65165, 93047, 983831, 0, 0, 0, 0, 0, 6191, 12944, 0, 0, 67634, 43763, 0, 0, 67635, 9370, 41381, 0, 0, 123148, 118817, 0, - 3222, 121439, 0, 0, 66663, 0, 0, 0, 0, 0, 65732, 121144, 0, 983217, 0, 0, - 67309, 72192, 41383, 64568, 0, 0, 0, 0, 984009, 66725, 0, 0, 0, 0, 0, + 3222, 121439, 0, 0, 66663, 0, 0, 0, 0, 0, 65732, 121144, 0, 983219, 0, 0, + 67309, 72192, 41383, 64568, 0, 0, 0, 0, 984009, 66725, 0, 0, 0, 0, 73766, 67306, 3632, 128246, 0, 8376, 3648, 0, 74844, 67639, 3636, 0, 3650, 8837, 0, 0, 0, 43250, 41562, 0, 0, 68839, 3640, 127190, 0, 11781, 0, 0, 0, 0, 129659, 0, 126649, 0, 42080, 2529, 0, 78004, 0, 42083, 0, 0, 120531, @@ -25327,97 +25507,97 @@ static const unsigned int code_hash[] = { 12753, 0, 983753, 67626, 67722, 0, 0, 0, 0, 12751, 74906, 8542, 0, 0, 3626, 66706, 0, 0, 3883, 64388, 0, 0, 0, 0, 0, 0, 126268, 67624, 0, 10932, 0, 65585, 64338, 806, 0, 41884, 110845, 1318, 128828, 0, 0, 0, - 983808, 3465, 2405, 983392, 0, 12756, 65259, 69381, 983812, 12752, 5833, + 983808, 3465, 2405, 983395, 0, 12756, 65259, 69381, 983812, 12752, 5833, 1432, 110843, 41883, 110841, 9799, 0, 41886, 0, 0, 2062, 0, 0, 0, 0, - 129376, 0, 124969, 983389, 0, 120971, 0, 118832, 0, 983283, 0, 68005, + 129376, 0, 124969, 983392, 0, 120971, 0, 118832, 0, 983286, 0, 68005, 10622, 0, 0, 0, 6566, 71195, 0, 73780, 0, 68865, 0, 0, 0, 8284, 0, 0, 0, - 0, 0, 43023, 0, 983287, 6642, 3977, 72743, 64729, 836, 983383, 92947, 0, + 0, 0, 43023, 0, 983290, 6642, 3977, 72743, 64729, 836, 983386, 92947, 0, 0, 0, 0, 0, 0, 125239, 917923, 0, 0, 0, 0, 0, 0, 1374, 65149, 119014, 67720, 0, 2273, 0, 0, 0, 11234, 0, 0, 9630, 12597, 0, 0, 0, 6661, 0, 113751, 120551, 125015, 0, 0, 72151, 0, 73674, 7718, 113755, 0, 69570, 0, - 0, 983777, 0, 0, 0, 127841, 6365, 1887, 983411, 0, 8080, 113681, 0, 0, 0, - 129855, 1544, 0, 0, 64677, 0, 0, 0, 0, 119019, 0, 0, 12812, 7342, 0, + 0, 983777, 0, 0, 0, 127841, 6365, 1887, 983414, 0, 8080, 113681, 0, 0, 0, + 129855, 1544, 0, 0, 64677, 0, 0, 0, 0, 73561, 0, 0, 12812, 7342, 0, 73784, 66947, 7904, 0, 0, 120910, 0, 0, 0, 0, 9724, 0, 983804, 9524, 0, - 0, 0, 0, 0, 129344, 0, 471, 0, 0, 128302, 0, 0, 0, 983769, 0, 0, 6918, - 118685, 0, 5156, 0, 128683, 10232, 10615, 10213, 0, 0, 42528, 0, 0, 0, 0, - 65311, 74935, 0, 13306, 10533, 7870, 0, 7625, 0, 120544, 0, 0, 128816, - 126098, 118870, 0, 92819, 0, 0, 92341, 0, 12978, 128533, 0, 0, 43836, - 42675, 0, 12845, 0, 19942, 0, 0, 0, 0, 0, 120000, 120008, 120001, 0, - 194894, 0, 0, 0, 0, 7186, 73107, 0, 70093, 445, 119028, 0, 0, 0, 73047, - 0, 0, 128442, 0, 0, 0, 3902, 68913, 129916, 0, 0, 1560, 43958, 0, 4584, - 0, 67862, 0, 10866, 92905, 1118, 92209, 74888, 0, 1081, 7436, 11147, - 7252, 0, 121188, 0, 0, 0, 41386, 5162, 129823, 1330, 0, 121270, 0, 12047, - 7675, 0, 0, 1848, 74528, 983147, 64708, 0, 0, 194880, 0, 0, 0, 983772, - 12715, 128349, 0, 0, 0, 66672, 73710, 66685, 0, 0, 92464, 0, 68884, 0, - 72835, 123546, 70800, 70101, 120725, 0, 194893, 9214, 43494, 0, 0, - 120841, 0, 0, 6313, 65513, 119355, 0, 0, 0, 2345, 72975, 0, 0, 129937, 0, - 3117, 0, 71882, 0, 73100, 0, 0, 0, 0, 78415, 983233, 100907, 0, 13248, 0, - 120241, 129416, 128415, 0, 94193, 12382, 71120, 0, 0, 0, 0, 1471, 0, + 0, 0, 0, 0, 129344, 0, 471, 0, 0, 128302, 72450, 0, 0, 983769, 0, 0, + 6918, 118685, 0, 5156, 0, 128683, 10232, 10615, 10213, 0, 0, 42528, 0, 0, + 0, 0, 65311, 74935, 0, 13306, 10533, 7870, 0, 7625, 0, 120544, 0, 0, + 128816, 126098, 118870, 0, 92819, 0, 0, 92341, 0, 12978, 128533, 0, 0, + 43836, 42675, 0, 12845, 0, 19942, 0, 0, 0, 0, 0, 120000, 120008, 120001, + 0, 194894, 983746, 0, 0, 0, 7186, 73107, 0, 70093, 445, 119028, 0, 0, 0, + 73047, 0, 0, 128442, 0, 0, 0, 3902, 68913, 129916, 0, 0, 1560, 43958, 0, + 4584, 0, 67862, 0, 10866, 92905, 1118, 92209, 74888, 0, 1081, 7436, + 11147, 7252, 0, 121188, 0, 0, 0, 41386, 5162, 129823, 1330, 0, 121270, 0, + 12047, 7675, 0, 0, 1848, 74528, 983148, 64708, 0, 0, 194880, 0, 0, 0, + 983772, 12715, 128349, 0, 101402, 0, 66672, 73710, 66685, 0, 0, 92464, 0, + 68884, 0, 72835, 123546, 70800, 70101, 120725, 0, 194893, 9214, 43494, 0, + 0, 120841, 0, 0, 6313, 65513, 119355, 0, 0, 0, 2345, 72975, 0, 0, 129937, + 0, 3117, 0, 71882, 0, 73100, 0, 0, 0, 0, 78415, 983236, 100907, 0, 13248, + 0, 120241, 129416, 128415, 0, 94193, 12382, 71120, 0, 0, 0, 0, 1471, 0, 113747, 0, 12378, 0, 69664, 0, 12374, 121357, 0, 0, 0, 0, 0, 0, 12376, 0, 0, 0, 12380, 10557, 0, 12520, 11122, 2024, 127180, 0, 0, 74588, 0, 0, 70120, 3853, 0, 0, 0, 983763, 0, 0, 12090, 0, 12474, 92579, 9503, 0, 0, - 983273, 68318, 0, 110834, 0, 0, 0, 12470, 0, 74189, 2742, 12476, 66370, - 10946, 0, 12472, 0, 0, 0, 0, 8213, 43824, 7771, 6161, 983277, 68010, 0, + 73505, 68318, 0, 110834, 0, 0, 0, 12470, 0, 74189, 2742, 12476, 66370, + 10946, 0, 12472, 0, 0, 0, 0, 8213, 43824, 7771, 6161, 983280, 68010, 0, 0, 0, 68235, 0, 0, 0, 120985, 0, 0, 0, 129814, 73791, 129830, 68871, 0, 0, 0, 0, 0, 73704, 12015, 128561, 8275, 0, 43459, 120927, 127555, 0, 0, 0, 68881, 71215, 983642, 118841, 0, 12516, 4444, 0, 119017, 120506, 10892, 118828, 0, 6473, 0, 0, 71735, 3591, 0, 0, 0, 0, 72345, 0, 0, 0, - 127547, 0, 0, 0, 0, 128253, 0, 0, 0, 0, 94060, 687, 0, 0, 983401, 0, 0, + 127547, 0, 0, 0, 0, 128253, 0, 0, 0, 0, 94060, 687, 0, 0, 983404, 0, 0, 43882, 0, 128526, 285, 0, 0, 0, 4459, 0, 0, 74917, 0, 0, 126255, 0, 119248, 0, 9743, 0, 0, 126535, 0, 0, 73104, 0, 69659, 0, 0, 3081, 74577, 42921, 0, 0, 0, 0, 0, 0, 0, 9125, 119023, 0, 120820, 0, 65221, 0, 0, 64852, 0, 0, 0, 0, 66578, 5001, 41879, 0, 0, 5003, 884, 0, 0, 4943, 5150, - 73889, 74182, 0, 41876, 0, 0, 42448, 42299, 72804, 0, 0, 0, 0, 8491, 0, - 0, 983635, 4530, 42409, 7126, 119526, 66200, 0, 118559, 19929, 0, 0, 0, - 4242, 0, 0, 0, 0, 66034, 65941, 124929, 64522, 10740, 8958, 128257, 9754, - 119102, 983248, 74222, 983246, 983245, 119064, 983243, 983242, 0, 0, 0, - 74518, 66026, 4306, 41468, 68432, 0, 0, 66667, 0, 0, 983496, 42200, 0, 0, - 0, 120236, 6948, 0, 8524, 0, 0, 12385, 0, 74926, 0, 1386, 73996, 0, 0, 0, - 121184, 12392, 0, 8064, 0, 0, 78216, 119004, 2080, 710, 128491, 12390, - 1666, 42091, 0, 12383, 92968, 42092, 68418, 0, 128106, 0, 0, 42096, 0, - 3362, 12377, 127878, 0, 0, 0, 0, 1244, 4401, 73786, 12683, 10662, 0, - 8112, 129837, 119021, 121017, 12379, 73108, 120534, 0, 42208, 0, 12381, - 0, 0, 0, 4327, 0, 0, 128350, 0, 78232, 0, 584, 12933, 0, 12373, 73105, - 13000, 0, 2935, 129113, 12665, 0, 43081, 73098, 120505, 12427, 0, 983625, - 78227, 0, 0, 0, 0, 128760, 74551, 0, 0, 12426, 0, 0, 0, 12428, 0, 0, 0, - 0, 0, 12429, 6727, 0, 0, 0, 3387, 0, 0, 0, 0, 0, 0, 74427, 0, 3536, - 120589, 9752, 92397, 6162, 0, 0, 10113, 0, 0, 0, 12422, 0, 439, 3072, 0, - 42207, 74549, 120830, 0, 0, 0, 0, 8308, 0, 70807, 0, 0, 0, 13218, 0, 0, - 8082, 12424, 0, 6819, 3539, 93838, 0, 0, 74539, 0, 68181, 0, 72964, 0, - 72969, 12420, 11371, 0, 4600, 0, 127810, 0, 0, 0, 72962, 128552, 6704, - 4591, 72966, 0, 0, 0, 72960, 120623, 561, 12159, 78223, 0, 78224, 0, - 71068, 11932, 7172, 42687, 8368, 0, 0, 93068, 0, 0, 75010, 0, 0, 0, 0, - 42463, 0, 2924, 67183, 0, 129947, 0, 128958, 0, 0, 42330, 73079, 3969, 0, - 129973, 7169, 1992, 9652, 0, 0, 42086, 0, 100865, 0, 0, 0, 0, 0, 327, 0, - 0, 0, 0, 0, 12433, 0, 0, 118570, 12431, 0, 12434, 983436, 0, 0, 0, 7712, - 12432, 0, 69377, 129147, 100867, 0, 8212, 0, 128014, 0, 119066, 7333, 0, - 0, 0, 67407, 70006, 128461, 0, 12436, 0, 43160, 0, 74896, 92757, 71360, - 42350, 0, 0, 0, 100566, 0, 11348, 0, 0, 9194, 983184, 0, 55250, 0, - 100569, 0, 0, 0, 0, 0, 64746, 66012, 100565, 3444, 75029, 64651, 0, - 41503, 0, 0, 0, 0, 0, 0, 0, 120876, 0, 0, 129408, 65309, 12416, 0, 0, 0, - 0, 93024, 12418, 74111, 121046, 0, 0, 0, 119361, 0, 4596, 66339, 12417, - 66001, 0, 126491, 12414, 8287, 0, 69499, 0, 1143, 0, 0, 12415, 0, 0, - 983244, 0, 9021, 120783, 0, 11724, 0, 0, 0, 194794, 0, 0, 8027, 194796, - 74257, 127375, 11400, 74197, 194799, 66833, 194798, 0, 0, 983249, 0, 0, - 1324, 0, 0, 0, 194878, 7715, 0, 0, 194777, 194780, 0, 0, 0, 194787, 0, 0, - 0, 0, 0, 66289, 127109, 3889, 129561, 194800, 0, 0, 0, 0, 121226, 12999, - 0, 120902, 0, 0, 0, 0, 0, 64802, 42210, 4597, 983133, 0, 0, 12371, 67164, - 0, 67163, 10805, 0, 0, 0, 0, 118662, 12367, 0, 0, 92557, 12363, 0, 0, - 128611, 983645, 0, 0, 8005, 12365, 0, 0, 3756, 12369, 10649, 0, 70095, 0, - 0, 0, 42923, 0, 0, 0, 0, 0, 0, 66659, 0, 0, 0, 0, 5268, 4954, 0, 0, 5266, - 126980, 5272, 92294, 0, 42230, 983980, 0, 9128, 0, 0, 0, 0, 6928, 9803, - 42282, 9110, 1505, 0, 0, 5276, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8722, 120805, - 0, 0, 66695, 0, 0, 4383, 8900, 0, 0, 74930, 64297, 0, 0, 0, 0, 3419, - 42229, 0, 0, 8911, 0, 42353, 0, 0, 0, 0, 0, 0, 0, 100629, 41576, 42215, - 122888, 0, 0, 8578, 68178, 7573, 41575, 74789, 92310, 0, 73863, 0, 2670, - 0, 0, 11723, 0, 0, 0, 0, 0, 43414, 0, 0, 65675, 0, 67179, 67168, 12413, - 129746, 67177, 0, 0, 0, 0, 12302, 0, 5250, 12407, 12245, 4404, 9189, - 12401, 42007, 0, 42005, 65806, 43997, 122922, 42002, 12404, 0, 74928, - 4940, 12410, 0, 128761, 0, 64567, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11956, 0, - 0, 122882, 0, 6631, 128923, 120704, 74583, 42218, 0, 0, 70094, 0, 0, 0, - 71058, 0, 0, 0, 127341, 0, 0, 0, 0, 0, 43370, 0, 5016, 121052, 0, 0, - 9491, 0, 0, 0, 0, 64922, 0, 0, 0, 0, 92198, 0, 118622, 0, 74619, 0, 0, - 70422, 983688, 10565, 0, 12177, 0, 0, 0, 0, 0, 12395, 127874, 12878, + 73889, 74182, 0, 41876, 0, 78915, 42448, 42299, 72804, 0, 0, 0, 0, 8491, + 0, 0, 983635, 4530, 42409, 7126, 119526, 66200, 0, 118559, 19929, 0, 0, + 0, 4242, 0, 0, 0, 0, 66034, 65941, 124929, 64522, 10740, 8958, 128257, + 9754, 119102, 983251, 74222, 983249, 983248, 119064, 983246, 983245, 0, + 0, 0, 74518, 66026, 4306, 41468, 68432, 0, 0, 66667, 0, 0, 983499, 42200, + 0, 0, 0, 120236, 6948, 0, 8524, 0, 0, 12385, 0, 74926, 0, 1386, 73996, 0, + 0, 0, 121184, 12392, 0, 8064, 0, 0, 78216, 119004, 2080, 710, 128491, + 12390, 1666, 42091, 0, 12383, 92968, 42092, 68418, 0, 128106, 0, 0, + 42096, 0, 3362, 12377, 127878, 0, 0, 0, 0, 1244, 4401, 73786, 12683, + 10662, 0, 8112, 129837, 119021, 121017, 12379, 73108, 120534, 0, 42208, + 0, 12381, 0, 0, 0, 4327, 0, 0, 128350, 0, 78232, 0, 584, 12933, 0, 12373, + 73105, 13000, 0, 2935, 129113, 12665, 0, 43081, 73098, 120505, 12427, 0, + 983625, 78227, 0, 0, 0, 0, 128760, 74551, 0, 0, 12426, 0, 73497, 0, + 12428, 0, 0, 0, 0, 0, 12429, 6727, 0, 0, 0, 3387, 0, 0, 0, 0, 0, 0, + 73517, 0, 3536, 120589, 9752, 92397, 6162, 0, 0, 10113, 0, 0, 0, 12422, + 0, 439, 3072, 0, 42207, 74549, 120830, 0, 0, 0, 0, 8308, 0, 70807, 0, 0, + 0, 13218, 0, 0, 8082, 12424, 0, 6819, 3539, 93838, 0, 0, 74539, 0, 68181, + 0, 72964, 0, 72969, 12420, 11371, 0, 4600, 0, 127810, 0, 0, 0, 72962, + 128552, 6704, 4591, 72966, 0, 0, 0, 72960, 120623, 561, 12159, 78223, 0, + 78224, 0, 71068, 11932, 7172, 42687, 8368, 0, 0, 93068, 0, 0, 75010, 0, + 0, 0, 0, 42463, 0, 2924, 67183, 0, 129947, 0, 128958, 0, 0, 42330, 73079, + 3969, 0, 129973, 7169, 1992, 9652, 0, 0, 42086, 0, 100865, 0, 0, 0, 0, 0, + 327, 0, 0, 0, 0, 73509, 12433, 0, 0, 118570, 12431, 0, 12434, 983439, 0, + 73544, 0, 7712, 12432, 0, 69377, 129147, 100867, 0, 8212, 0, 128014, 0, + 119066, 7333, 0, 0, 0, 67407, 70006, 128461, 0, 12436, 0, 43160, 0, + 74896, 92757, 71360, 42350, 0, 0, 0, 100566, 0, 11348, 0, 0, 9194, + 983185, 0, 55250, 0, 100569, 0, 0, 0, 0, 0, 64746, 66012, 100565, 3444, + 75029, 64651, 0, 41503, 0, 0, 0, 0, 0, 0, 0, 120876, 0, 0, 129408, 65309, + 12416, 0, 0, 0, 0, 93024, 12418, 74111, 121046, 0, 0, 0, 119361, 0, 4596, + 66339, 12417, 66001, 0, 126491, 12414, 8287, 0, 69499, 0, 1143, 0, 0, + 12415, 0, 0, 983247, 0, 9021, 120783, 0, 11724, 0, 0, 0, 194794, 0, 0, + 8027, 194796, 74257, 127375, 11400, 74197, 194799, 66833, 194798, 0, 0, + 983252, 0, 0, 1324, 0, 0, 0, 194878, 7715, 0, 0, 194777, 194780, 0, 0, 0, + 194787, 0, 0, 0, 0, 0, 66289, 127109, 3889, 129561, 194800, 0, 0, 0, 0, + 121226, 12999, 0, 120902, 0, 0, 0, 0, 0, 64802, 42210, 4597, 983134, 0, + 0, 12371, 67164, 0, 67163, 10805, 0, 0, 0, 0, 118662, 12367, 0, 0, 92557, + 12363, 0, 0, 128611, 983645, 0, 0, 8005, 12365, 0, 0, 3756, 12369, 10649, + 0, 70095, 0, 0, 0, 42923, 0, 0, 0, 0, 0, 0, 66659, 0, 0, 0, 0, 5268, + 4954, 0, 0, 5266, 126980, 5272, 92294, 0, 42230, 983980, 0, 9128, 0, 0, + 0, 0, 6928, 9803, 42282, 9110, 1505, 0, 0, 5276, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 8722, 120805, 0, 0, 66695, 0, 0, 4383, 8900, 0, 0, 74930, 64297, 0, 0, + 0, 0, 3419, 42229, 0, 0, 8911, 0, 42353, 0, 0, 0, 0, 0, 0, 0, 100629, + 41576, 42215, 122888, 0, 0, 8578, 68178, 7573, 41575, 74789, 92310, 0, + 73863, 0, 2670, 0, 0, 11723, 0, 0, 0, 0, 0, 43414, 0, 0, 65675, 0, 67179, + 67168, 12413, 129746, 67177, 0, 0, 0, 0, 12302, 0, 5250, 12407, 12245, + 4404, 9189, 12401, 42007, 0, 42005, 65806, 43997, 122922, 42002, 12404, + 0, 74928, 4940, 12410, 0, 128761, 0, 64567, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 11956, 0, 0, 122882, 0, 6631, 128923, 120704, 74583, 42218, 0, 0, 70094, + 0, 0, 0, 71058, 0, 0, 0, 127341, 0, 0, 0, 0, 0, 43370, 0, 5016, 121052, + 0, 0, 9491, 0, 0, 0, 0, 64922, 0, 0, 0, 0, 92198, 0, 118622, 0, 74619, 0, + 0, 70422, 983688, 10565, 0, 12177, 0, 0, 0, 0, 0, 12395, 127874, 12878, 92630, 12396, 0, 0, 92537, 0, 43113, 0, 0, 0, 9781, 0, 4927, 0, 0, 0, 0, 12397, 129089, 128910, 0, 12394, 0, 0, 0, 0, 0, 72789, 10781, 1546, 0, 5010, 0, 10507, 127891, 128291, 0, 0, 0, 0, 7267, 0, 0, 0, 0, 2819, 0, 0, @@ -25464,10 +25644,10 @@ static const unsigned int code_hash[] = { 67600, 67477, 0, 127293, 8575, 127295, 127296, 127289, 127290, 127291, 127292, 127285, 127286, 127287, 118877, 127281, 127282, 9460, 823, 11587, 0, 0, 0, 127305, 12387, 0, 0, 127301, 126979, 42783, 69998, 64208, - 127298, 127299, 66031, 0, 11606, 64784, 0, 69973, 0, 0, 0, 5152, 11048, - 0, 120121, 67605, 0, 69604, 0, 70276, 194847, 0, 127052, 42587, 42214, - 41394, 0, 4763, 0, 118935, 0, 5260, 0, 94038, 326, 120131, 74119, 0, - 10771, 42198, 194920, 194835, 194925, 41398, 127079, 41393, 127077, + 127298, 127299, 66031, 0, 11606, 64784, 0, 69973, 0, 124149, 0, 5152, + 11048, 0, 120121, 67605, 0, 69604, 0, 70276, 194847, 0, 127052, 42587, + 42214, 41394, 0, 4763, 0, 118935, 0, 5260, 0, 94038, 326, 120131, 74119, + 0, 10771, 42198, 194920, 194835, 194925, 41398, 127079, 41393, 127077, 127076, 453, 41396, 0, 13159, 11227, 9572, 0, 0, 194576, 128835, 127081, 0, 126617, 43144, 0, 72972, 194887, 0, 0, 0, 0, 0, 64061, 0, 0, 64056, 70310, 0, 0, 0, 66971, 0, 111084, 64301, 72998, 10464, 0, 128393, 72847, @@ -25481,7 +25661,7 @@ static const unsigned int code_hash[] = { 194829, 1833, 11576, 74334, 0, 0, 42854, 69438, 0, 70307, 0, 194856, 8085, 0, 194850, 0, 72996, 128778, 1949, 11614, 7847, 120489, 120997, 64483, 0, 0, 0, 122639, 0, 0, 0, 126651, 42864, 0, 64667, 74624, 0, 0, - 43261, 11484, 127535, 67840, 0, 0, 128965, 0, 72974, 0, 110928, 8995, + 43261, 11484, 127535, 67840, 0, 0, 128965, 0, 72974, 0, 72456, 8995, 3455, 0, 0, 9879, 0, 0, 4158, 128050, 0, 0, 110929, 0, 0, 0, 332, 118808, 0, 0, 2407, 0, 42199, 92386, 110865, 0, 77921, 55217, 123161, 125199, 70043, 0, 0, 0, 121093, 1834, 0, 0, 71315, 0, 65249, 0, 8662, 0, 0, @@ -25490,12 +25670,12 @@ static const unsigned int code_hash[] = { 1620, 0, 3601, 0, 0, 67246, 609, 11555, 0, 12496, 0, 74181, 120492, 12505, 0, 194902, 0, 43567, 239, 0, 127085, 0, 0, 42671, 0, 0, 83095, 43565, 127082, 983955, 12696, 127753, 0, 94062, 12929, 0, 712, 0, 4197, - 0, 42818, 0, 70306, 0, 0, 983824, 0, 43562, 0, 129034, 68076, 0, 111074, + 0, 42818, 0, 70306, 0, 0, 983824, 0, 43562, 0, 119506, 68076, 0, 111074, 64628, 0, 0, 0, 0, 7494, 0, 4924, 0, 0, 0, 0, 72368, 0, 127087, 69987, - 64796, 0, 0, 12033, 0, 0, 72370, 0, 0, 0, 0, 70299, 0, 0, 68324, 72420, - 0, 0, 0, 0, 70309, 127000, 0, 0, 0, 72418, 72963, 0, 5699, 0, 983898, - 9488, 74410, 119112, 70477, 11170, 0, 0, 72312, 0, 5265, 0, 0, 0, 0, - 12464, 0, 43264, 72977, 0, 43345, 120853, 0, 120592, 6807, 0, 9829, + 64796, 0, 0, 12033, 119492, 0, 72370, 0, 0, 0, 0, 70299, 0, 0, 68324, + 72420, 0, 0, 0, 0, 70309, 127000, 0, 0, 0, 72418, 72963, 0, 5699, 0, + 983898, 9488, 74410, 119112, 70477, 11170, 0, 0, 72312, 0, 5265, 0, 0, 0, + 0, 12464, 0, 43264, 72977, 0, 43345, 120853, 0, 120592, 6807, 0, 9829, 69997, 0, 0, 43346, 11393, 795, 0, 72412, 12462, 72416, 72415, 0, 0, 64362, 0, 0, 120811, 0, 12468, 8607, 1008, 0, 120670, 0, 0, 67855, 125018, 72372, 6758, 0, 0, 1820, 41112, 0, 11202, 129451, 0, 13223, 0, @@ -25519,13 +25699,13 @@ static const unsigned int code_hash[] = { 0, 9282, 0, 224, 0, 68670, 9332, 65581, 68677, 0, 68644, 0, 11764, 68634, 0, 10732, 68640, 850, 0, 0, 71123, 0, 68619, 44008, 68627, 0, 0, 0, 0, 66969, 0, 0, 0, 12507, 0, 0, 128311, 0, 120529, 4375, 0, 0, 0, 12198, 0, - 67339, 0, 0, 72994, 74293, 128434, 0, 0, 64546, 0, 71208, 0, 0, 125241, + 67339, 0, 0, 72994, 74293, 128434, 0, 0, 64546, 0, 71208, 0, 0, 78916, 42334, 42502, 0, 120887, 72961, 0, 917838, 5767, 0, 0, 71710, 8353, 0, 0, 0, 121233, 0, 0, 0, 0, 119920, 0, 0, 121186, 0, 0, 0, 72719, 64604, 0, 6096, 122632, 10063, 0, 0, 119630, 3485, 12987, 0, 127522, 0, 0, 0, 0, 0, 0, 0, 0, 127173, 0, 0, 68249, 0, 0, 118923, 0, 64574, 128794, 0, 1640, 12495, 66691, 0, 3138, 12504, 11171, 1922, 0, 12498, 128733, 0, 69939, 0, - 65543, 0, 0, 0, 66643, 0, 120734, 0, 4228, 0, 10303, 0, 0, 0, 10335, + 65543, 0, 0, 0, 66643, 0, 120734, 0, 4228, 0, 10303, 128884, 0, 0, 10335, 3520, 0, 12490, 0, 0, 0, 12493, 121452, 64636, 1002, 12491, 0, 0, 92615, 2096, 0, 0, 0, 0, 11611, 66228, 0, 11241, 66224, 66221, 66226, 66229, 66219, 66231, 66216, 0, 66236, 66211, 66218, 0, 66240, 78041, 66233, @@ -25551,7 +25731,7 @@ static const unsigned int code_hash[] = { 77995, 0, 3608, 0, 0, 1107, 0, 129658, 0, 0, 0, 0, 983956, 43217, 66571, 13222, 118963, 0, 126514, 10463, 11553, 0, 63995, 9043, 128634, 71722, 0, 0, 127751, 92974, 12529, 8042, 0, 2344, 12528, 0, 0, 0, 69719, 120956, 0, - 0, 66512, 0, 12530, 0, 0, 68917, 12658, 0, 71683, 0, 983238, 0, 127526, + 0, 66512, 0, 12530, 0, 0, 68917, 12658, 0, 71683, 0, 983241, 0, 127526, 469, 0, 4363, 3313, 0, 0, 2023, 0, 72251, 78225, 65706, 10051, 78219, 78220, 0, 9920, 12215, 0, 4931, 1951, 12497, 119363, 0, 0, 119336, 0, 0, 0, 0, 0, 1491, 128578, 129169, 0, 0, 0, 0, 78898, 94086, 41993, 0, 67379, @@ -25574,7 +25754,7 @@ static const unsigned int code_hash[] = { 4156, 0, 0, 0, 78591, 1611, 73058, 13018, 78586, 78588, 78584, 3337, 4537, 78593, 11736, 0, 0, 0, 4214, 73790, 0, 0, 13046, 194844, 425, 74763, 42066, 78595, 0, 2392, 13047, 0, 0, 12425, 13049, 0, 92243, 0, - 72715, 73944, 13050, 0, 0, 0, 0, 983503, 0, 0, 8929, 6849, 0, 0, 0, + 72715, 73944, 13050, 0, 0, 0, 0, 983506, 0, 0, 8929, 6849, 0, 0, 0, 983990, 0, 13045, 0, 0, 7751, 0, 9726, 0, 3997, 0, 8768, 13044, 0, 0, 4024, 0, 0, 2419, 9757, 69736, 0, 0, 0, 129500, 0, 0, 0, 72735, 0, 0, 0, 0, 0, 11911, 124990, 0, 2346, 194691, 69931, 0, 9646, 3773, 43557, 68154, @@ -25609,7 +25789,7 @@ static const unsigned int code_hash[] = { 0, 111011, 92960, 74356, 0, 74562, 0, 72745, 0, 0, 120568, 0, 0, 0, 0, 0, 8703, 5462, 83195, 0, 10101, 0, 70049, 0, 0, 128793, 0, 0, 66254, 120821, 0, 1565, 123621, 0, 119194, 0, 42651, 0, 0, 917847, 83227, 83218, 0, - 75011, 0, 917846, 0, 64399, 0, 12899, 74564, 0, 42206, 0, 72718, 71715, + 75011, 0, 129724, 0, 64399, 0, 12899, 74564, 0, 42206, 0, 72718, 71715, 83149, 983794, 83146, 12192, 917826, 0, 0, 0, 0, 68056, 0, 67426, 128687, 0, 0, 0, 0, 0, 0, 67431, 71718, 74357, 0, 121176, 43596, 6090, 0, 7812, 10534, 0, 0, 0, 0, 129763, 0, 0, 0, 0, 0, 0, 43306, 0, 0, 0, 7930, 0, @@ -25620,76 +25800,76 @@ static const unsigned int code_hash[] = { 310, 0, 0, 68403, 100480, 72738, 125279, 0, 0, 6497, 127320, 0, 0, 19958, 0, 128691, 74953, 0, 118998, 67332, 374, 0, 41933, 120975, 0, 0, 41934, 7465, 0, 128168, 70666, 11151, 6101, 0, 41936, 100476, 4879, 0, 65446, 0, - 0, 0, 0, 5374, 0, 128059, 127390, 0, 126618, 983575, 129146, 0, 0, 1929, - 0, 12142, 0, 0, 0, 121472, 0, 12982, 0, 5378, 0, 128679, 0, 0, 127869, 0, - 127343, 0, 0, 0, 78832, 74481, 0, 43262, 100511, 2421, 0, 2324, 828, - 3611, 121055, 0, 64314, 0, 0, 0, 0, 0, 0, 7999, 0, 11217, 983263, 10634, - 10942, 0, 2348, 0, 0, 0, 0, 118587, 9982, 64324, 41240, 0, 100470, 78462, - 1810, 0, 92566, 71299, 0, 0, 917848, 0, 0, 100515, 0, 0, 0, 43912, - 128385, 0, 0, 0, 917850, 0, 7485, 0, 129382, 74576, 44019, 128171, - 917851, 3967, 129335, 0, 0, 0, 0, 119096, 0, 0, 8699, 723, 83084, 966, 0, - 0, 0, 128428, 78778, 2320, 0, 65740, 4968, 0, 0, 8075, 55276, 123589, - 8047, 983787, 78827, 12634, 0, 78781, 71322, 0, 12174, 42610, 0, 0, 0, - 1584, 0, 6045, 0, 0, 65218, 11559, 0, 0, 0, 124991, 0, 2257, 64418, 0, 0, - 0, 0, 0, 0, 67821, 0, 13092, 0, 128365, 0, 0, 0, 0, 0, 11414, 0, 2531, - 13034, 0, 0, 0, 13036, 0, 70866, 70198, 10394, 129979, 13037, 0, 129956, - 0, 0, 100496, 120640, 41129, 0, 42850, 13035, 0, 0, 5466, 0, 0, 0, - 129439, 4535, 0, 4271, 0, 0, 6769, 0, 0, 67350, 6767, 0, 66273, 0, 6755, - 73827, 9046, 67355, 0, 0, 0, 0, 0, 0, 0, 0, 92221, 83235, 2563, 13033, - 247, 83229, 0, 12338, 0, 83231, 11270, 0, 0, 0, 0, 70107, 0, 0, 0, 0, - 3752, 83243, 68895, 66973, 68897, 0, 0, 0, 0, 5009, 0, 0, 0, 0, 119521, - 78823, 78824, 70353, 68399, 3877, 0, 78825, 10145, 43566, 0, 0, 10236, 0, - 43782, 0, 127329, 0, 69652, 2247, 120612, 128058, 0, 43200, 43777, 71253, - 983644, 69558, 0, 71866, 43203, 0, 68894, 0, 127326, 0, 43778, 119538, 0, - 0, 43781, 11303, 65547, 0, 7031, 0, 0, 67343, 83237, 83267, 0, 67341, - 120522, 8535, 0, 0, 0, 66032, 0, 0, 120786, 42233, 0, 9946, 7667, 0, - 11822, 0, 43189, 120673, 100507, 2979, 1579, 0, 0, 0, 0, 0, 12635, 71337, - 0, 94055, 0, 1285, 64882, 0, 0, 83113, 12640, 83112, 7401, 92869, 12625, - 0, 71296, 72744, 0, 74286, 55260, 3396, 12642, 0, 110719, 0, 12630, 0, 0, - 10153, 0, 6166, 120516, 0, 110680, 0, 0, 0, 9285, 913, 42259, 83017, 0, - 2142, 127889, 0, 94012, 7878, 0, 72733, 0, 0, 0, 0, 92868, 0, 0, 0, 0, - 128918, 5263, 74782, 0, 41939, 43702, 0, 917856, 0, 10139, 980, 43698, 0, - 2208, 0, 43701, 0, 125132, 0, 100528, 0, 10085, 0, 0, 119989, 100529, 0, - 71699, 0, 8072, 0, 43700, 0, 7304, 7783, 66894, 12398, 0, 0, 0, 0, 0, 0, - 120565, 0, 2217, 0, 94015, 6367, 0, 66688, 0, 0, 0, 0, 0, 92199, 7808, - 1829, 0, 41937, 0, 43272, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92467, 6627, 0, - 6258, 10683, 0, 0, 0, 5649, 0, 0, 0, 1643, 127898, 0, 127846, 67244, 0, - 42452, 0, 0, 0, 0, 64291, 0, 0, 0, 6576, 74773, 0, 0, 66309, 0, 9886, - 55225, 11292, 0, 72867, 55227, 0, 12632, 0, 194817, 0, 7680, 0, 92745, - 120714, 12639, 3380, 8123, 0, 12638, 42262, 4501, 0, 0, 0, 0, 125131, - 1494, 983146, 0, 0, 0, 0, 10494, 0, 65872, 0, 0, 0, 0, 0, 0, 983587, 0, - 0, 0, 0, 0, 0, 0, 71077, 0, 127335, 121128, 0, 5570, 1881, 7210, 0, 1012, - 66630, 0, 128982, 7208, 66442, 5569, 113723, 42339, 92655, 0, 0, 0, 0, - 92378, 65602, 0, 92375, 64727, 9160, 0, 0, 0, 124928, 10503, 0, 3423, - 3870, 8483, 10162, 0, 4319, 0, 0, 0, 0, 0, 983116, 0, 69562, 0, 0, 0, 0, - 0, 0, 5571, 7630, 9740, 9121, 5568, 0, 0, 42085, 0, 0, 65056, 0, 589, 0, - 0, 0, 10233, 66252, 66251, 78734, 66253, 0, 0, 42645, 0, 128424, 8583, 0, - 0, 0, 129932, 0, 0, 0, 0, 0, 12204, 92436, 120453, 0, 0, 0, 983259, 0, 0, - 70311, 0, 0, 128012, 41063, 0, 10664, 0, 983660, 0, 4551, 129090, 74759, - 0, 983267, 0, 0, 72806, 0, 0, 12517, 7806, 0, 12034, 0, 6355, 12519, - 41004, 0, 0, 93849, 0, 71707, 0, 121231, 7332, 129075, 12111, 3927, 0, - 12515, 1474, 68768, 0, 6923, 69509, 0, 127802, 0, 43990, 74639, 126229, - 121007, 0, 92706, 0, 0, 0, 0, 0, 9645, 0, 121026, 5853, 0, 10363, 120729, - 12956, 0, 0, 0, 0, 127888, 0, 0, 0, 0, 0, 10514, 65517, 0, 0, 71101, 0, - 0, 0, 43570, 2969, 43420, 129944, 0, 0, 92366, 70809, 0, 0, 0, 0, 0, - 118714, 12125, 41124, 0, 1164, 128817, 0, 120466, 0, 0, 65014, 66009, - 74451, 125075, 983128, 7469, 0, 0, 0, 69988, 120671, 83171, 41123, 11176, - 0, 0, 41126, 9991, 41128, 0, 0, 110949, 0, 0, 42877, 7994, 0, 6104, - 983612, 0, 129869, 0, 0, 0, 0, 74438, 128272, 121409, 41981, 0, 69296, - 42904, 0, 0, 74435, 126640, 0, 0, 0, 127968, 92442, 12703, 9661, 67360, - 67359, 7455, 70732, 11473, 119217, 128512, 0, 92323, 0, 0, 129632, 67358, - 0, 0, 0, 0, 174, 121131, 883, 4161, 128033, 42603, 0, 0, 72256, 0, 0, - 128356, 0, 0, 0, 0, 3846, 8070, 6150, 128109, 4370, 118617, 0, 0, 74587, - 0, 0, 0, 0, 4986, 12189, 917553, 67648, 120499, 0, 4257, 71695, 123620, - 6220, 0, 65561, 0, 0, 0, 0, 122652, 0, 0, 0, 69684, 0, 0, 128452, 120873, - 0, 0, 74922, 0, 71897, 0, 0, 67368, 67367, 8871, 67366, 0, 0, 0, 0, 0, - 67361, 0, 0, 67365, 67364, 3427, 4240, 67376, 67375, 67374, 67373, 0, 0, - 0, 67377, 0, 71689, 0, 0, 67372, 67371, 67370, 67369, 0, 0, 0, 124962, 0, - 0, 0, 0, 65898, 0, 65312, 0, 0, 0, 0, 4010, 121208, 41106, 0, 0, 0, - 41105, 0, 64803, 83456, 0, 0, 0, 0, 0, 0, 0, 11008, 0, 0, 71351, 41110, - 71681, 64892, 9113, 1954, 41108, 0, 42878, 0, 67405, 0, 0, 0, 0, 0, - 119539, 69435, 73463, 0, 4586, 129342, 0, 0, 0, 0, 0, 125233, 92307, 0, - 0, 0, 67382, 0, 9500, 0, 4957, 0, 2422, 2212, 0, 67381, 67380, 11045, + 0, 983695, 0, 5374, 0, 128059, 127390, 0, 126618, 983575, 129146, 0, 0, + 1929, 0, 12142, 0, 0, 0, 121472, 0, 12982, 0, 5378, 0, 128679, 0, 0, + 127869, 0, 127343, 0, 0, 0, 78832, 74481, 0, 43262, 100511, 2421, 0, + 2324, 828, 3611, 121055, 0, 64314, 0, 0, 0, 0, 0, 0, 7999, 0, 11217, + 983266, 10634, 10942, 0, 2348, 0, 0, 0, 0, 118587, 9982, 64324, 41240, 0, + 100470, 78462, 1810, 0, 92566, 71299, 0, 0, 917848, 0, 0, 100515, 0, 0, + 0, 43912, 128385, 0, 0, 0, 917850, 0, 7485, 0, 129382, 74576, 44019, + 128171, 917851, 3967, 129335, 0, 0, 0, 0, 119096, 0, 0, 8699, 723, 83084, + 966, 0, 0, 0, 128428, 78778, 2320, 0, 65740, 4968, 0, 0, 8075, 55276, + 123589, 8047, 983787, 78827, 12634, 0, 78781, 71322, 0, 12174, 42610, 0, + 0, 0, 1584, 0, 6045, 0, 0, 65218, 11559, 0, 0, 0, 124991, 0, 2257, 64418, + 0, 0, 0, 0, 0, 0, 67821, 0, 13092, 0, 128365, 0, 0, 0, 0, 0, 11414, 0, + 2531, 13034, 0, 0, 0, 13036, 0, 70866, 70198, 10394, 129979, 13037, 0, + 129956, 0, 0, 100496, 120640, 41129, 0, 42850, 13035, 0, 0, 5466, 0, 0, + 0, 129439, 4535, 0, 4271, 0, 0, 6769, 0, 0, 67350, 6767, 0, 66273, 0, + 6755, 73827, 9046, 67355, 0, 0, 0, 0, 0, 0, 0, 0, 92221, 83235, 2563, + 13033, 247, 83229, 0, 12338, 0, 83231, 11270, 0, 0, 0, 0, 70107, 0, 0, 0, + 0, 3752, 83243, 68895, 66973, 68897, 0, 0, 0, 0, 5009, 0, 0, 0, 0, + 119521, 78823, 78824, 70353, 68399, 3877, 0, 78825, 10145, 43566, 0, 0, + 10236, 0, 43782, 0, 127329, 0, 69652, 2247, 120612, 128058, 0, 43200, + 43777, 71253, 983644, 69558, 0, 71866, 43203, 0, 68894, 0, 127326, 0, + 43778, 119538, 0, 0, 43781, 11303, 65547, 0, 7031, 0, 0, 67343, 83237, + 83267, 0, 67341, 120522, 8535, 0, 0, 0, 66032, 0, 0, 120786, 42233, 0, + 9946, 7667, 0, 11822, 0, 43189, 120673, 100507, 2979, 1579, 0, 0, 0, 0, + 0, 12635, 71337, 0, 94055, 0, 1285, 64882, 0, 0, 83113, 12640, 83112, + 7401, 92869, 12625, 0, 71296, 72744, 0, 74286, 55260, 3396, 12642, 0, + 110719, 0, 12630, 0, 0, 10153, 0, 6166, 120516, 0, 110680, 0, 0, 119499, + 9285, 913, 42259, 83017, 0, 2142, 127889, 0, 94012, 7878, 0, 72733, 0, 0, + 0, 0, 92868, 0, 0, 0, 0, 128918, 5263, 74782, 0, 41939, 43702, 0, 917856, + 0, 10139, 980, 43698, 0, 2208, 0, 43701, 0, 125132, 0, 100528, 0, 10085, + 0, 0, 119989, 100529, 0, 71699, 0, 8072, 0, 43700, 0, 7304, 7783, 66894, + 12398, 0, 0, 0, 0, 0, 0, 120565, 0, 2217, 0, 94015, 6367, 0, 66688, 0, 0, + 0, 0, 0, 92199, 7808, 1829, 0, 41937, 0, 43272, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 92467, 6627, 0, 6258, 10683, 0, 0, 0, 5649, 0, 0, 0, 1643, 127898, + 0, 127846, 67244, 0, 42452, 0, 0, 0, 0, 64291, 0, 0, 0, 6576, 74773, 0, + 0, 66309, 0, 9886, 55225, 11292, 0, 72867, 55227, 0, 12632, 0, 194817, 0, + 7680, 0, 92745, 120714, 12639, 3380, 8123, 0, 12638, 42262, 4501, 0, 0, + 0, 0, 125131, 1494, 983147, 0, 0, 0, 0, 10494, 0, 65872, 0, 0, 0, 0, 0, + 0, 983587, 0, 0, 0, 0, 0, 0, 0, 71077, 0, 127335, 121128, 0, 5570, 1881, + 7210, 0, 1012, 66630, 0, 128982, 7208, 66442, 5569, 113723, 42339, 92655, + 0, 0, 0, 0, 92378, 65602, 0, 92375, 64727, 9160, 0, 0, 0, 124928, 10503, + 0, 3423, 3870, 8483, 10162, 0, 4319, 0, 0, 0, 0, 0, 983117, 0, 69562, 0, + 0, 0, 0, 0, 0, 5571, 7630, 9740, 9121, 5568, 0, 0, 42085, 0, 0, 65056, 0, + 589, 0, 0, 0, 10233, 66252, 66251, 78734, 66253, 0, 0, 42645, 0, 128424, + 8583, 0, 0, 0, 129932, 0, 0, 0, 0, 0, 12204, 92436, 120453, 0, 0, 0, + 983262, 0, 0, 70311, 0, 0, 128012, 41063, 0, 10664, 0, 983660, 0, 4551, + 129090, 74759, 0, 983270, 0, 0, 72806, 0, 0, 12517, 7806, 0, 12034, 0, + 6355, 12519, 41004, 0, 0, 93849, 0, 71707, 0, 121231, 7332, 129075, + 12111, 3927, 0, 12515, 1474, 68768, 0, 6923, 69509, 0, 127802, 0, 43990, + 74639, 126229, 121007, 0, 92706, 0, 0, 0, 0, 0, 9645, 0, 121026, 5853, 0, + 10363, 120729, 12956, 0, 0, 0, 0, 127888, 0, 0, 0, 0, 0, 10514, 65517, 0, + 0, 71101, 0, 0, 0, 43570, 2969, 43420, 129944, 0, 0, 92366, 70809, 0, 0, + 0, 0, 0, 118714, 12125, 41124, 0, 1164, 128817, 0, 120466, 0, 0, 65014, + 66009, 74451, 125075, 983129, 7469, 0, 0, 0, 69988, 120671, 83171, 41123, + 11176, 0, 0, 41126, 9991, 41128, 0, 0, 110949, 0, 0, 42877, 7994, 0, + 6104, 983612, 0, 129869, 0, 0, 0, 0, 74438, 128272, 121409, 41981, 0, + 69296, 42904, 0, 0, 74435, 126640, 0, 0, 0, 127968, 92442, 12703, 9661, + 67360, 67359, 7455, 70732, 11473, 119217, 128512, 0, 92323, 0, 0, 129632, + 67358, 0, 0, 0, 0, 174, 121131, 883, 4161, 128033, 42603, 0, 0, 72256, 0, + 0, 128356, 0, 0, 0, 0, 3846, 8070, 6150, 128109, 4370, 118617, 0, 0, + 74587, 0, 0, 0, 0, 4986, 12189, 917553, 67648, 120499, 0, 4257, 71695, + 123620, 6220, 0, 65561, 0, 0, 0, 0, 122652, 0, 0, 0, 69684, 0, 0, 128452, + 120873, 0, 0, 74922, 0, 71897, 0, 0, 67368, 67367, 8871, 67366, 0, 0, 0, + 0, 0, 67361, 0, 0, 67365, 67364, 3427, 4240, 67376, 67375, 67374, 67373, + 0, 0, 0, 67377, 0, 71689, 0, 0, 67372, 67371, 67370, 67369, 0, 0, 0, + 124962, 0, 0, 0, 0, 65898, 0, 65312, 0, 0, 0, 0, 4010, 121208, 41106, 0, + 0, 0, 41105, 0, 64803, 83456, 0, 0, 0, 0, 0, 0, 0, 11008, 0, 0, 71351, + 41110, 71681, 64892, 9113, 1954, 41108, 0, 42878, 0, 67405, 0, 0, 0, 0, + 0, 119539, 69435, 73463, 0, 4586, 129342, 0, 0, 0, 0, 0, 125233, 92307, + 0, 0, 0, 67382, 0, 9500, 0, 4957, 0, 2422, 2212, 0, 67381, 67380, 11045, 67378, 0, 0, 3890, 12168, 121328, 0, 0, 0, 41947, 0, 120828, 74946, 917901, 0, 1571, 66461, 41949, 42805, 8270, 943, 41946, 0, 2073, 0, 41980, 0, 0, 0, 0, 4429, 6272, 0, 1460, 6954, 128572, 41120, 0, 65733, 0, @@ -25697,286 +25877,287 @@ static const unsigned int code_hash[] = { 0, 0, 0, 0, 0, 41122, 0, 2457, 0, 0, 0, 0, 0, 0, 8840, 8035, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8681, 0, 121505, 128747, 0, 0, 70102, 0, 124976, 9605, 0, 13220, 0, 67354, 11312, 0, 9246, 67349, 0, 0, 0, 0, 10012, 12123, 0, - 0, 0, 0, 983846, 0, 0, 0, 67817, 0, 1272, 0, 0, 0, 983578, 0, 1467, 0, - 917806, 0, 0, 0, 70312, 0, 124955, 0, 70400, 0, 0, 72817, 0, 19935, 0, - 92162, 0, 0, 0, 128406, 5275, 0, 0, 44006, 129082, 0, 3789, 128205, 0, 0, - 0, 11474, 0, 0, 0, 129050, 0, 92194, 129503, 9537, 4496, 0, 120443, 2605, - 4500, 0, 55224, 8600, 0, 0, 41646, 11667, 69569, 0, 0, 917905, 4499, - 41649, 0, 0, 0, 69254, 0, 0, 0, 65804, 0, 70034, 41866, 0, 0, 0, 11174, - 0, 0, 0, 9559, 128773, 41940, 8299, 41945, 0, 41941, 5455, 7190, 0, 0, - 917810, 65266, 0, 41943, 10762, 0, 41931, 0, 0, 8106, 4128, 0, 0, 4494, - 0, 0, 72405, 0, 119567, 42068, 917808, 0, 11004, 12794, 65072, 5271, - 7317, 0, 0, 0, 0, 0, 0, 92281, 0, 0, 0, 0, 71880, 3868, 71881, 983573, - 128431, 7703, 0, 64390, 0, 7406, 120358, 93850, 0, 3985, 66425, 0, 66615, - 10177, 0, 41853, 71873, 12809, 0, 12193, 0, 10879, 0, 0, 9055, 0, 3851, - 8132, 0, 0, 119263, 917908, 0, 0, 0, 0, 0, 42657, 0, 7643, 0, 0, 0, - 43568, 0, 11949, 7650, 43569, 64951, 7647, 7649, 0, 7646, 0, 0, 9651, - 125005, 3891, 0, 0, 2337, 77831, 77832, 67860, 129288, 0, 0, 43561, - 67706, 119669, 0, 1860, 0, 68835, 5812, 12784, 0, 0, 0, 0, 69260, 7727, - 0, 69292, 69818, 66444, 128665, 42719, 0, 1569, 0, 12534, 12124, 7690, - 194871, 12533, 0, 68383, 67997, 0, 6969, 0, 0, 0, 67974, 63895, 128650, - 0, 0, 0, 42144, 0, 0, 0, 0, 92211, 119043, 0, 0, 917545, 0, 0, 12791, 0, - 0, 0, 4447, 71065, 12793, 0, 0, 43385, 0, 0, 12790, 120256, 0, 983840, - 12792, 120254, 0, 0, 12789, 128489, 12317, 74934, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 127840, 41652, 2974, 78689, 11476, 0, 0, 0, 0, 43871, 0, 10894, - 119176, 74557, 65686, 0, 0, 3724, 67335, 67334, 67333, 67338, 67337, 0, - 67336, 0, 65306, 0, 128421, 0, 8646, 129593, 77829, 0, 0, 74852, 0, 0, 0, - 0, 0, 220, 120252, 43551, 0, 10044, 0, 0, 983847, 68659, 110825, 5707, - 71362, 0, 0, 0, 0, 0, 0, 10297, 0, 41308, 67331, 0, 0, 0, 0, 2467, 0, - 6003, 0, 0, 8040, 0, 0, 4182, 0, 11135, 120501, 0, 0, 2510, 0, 10208, 0, - 78302, 70829, 0, 0, 6837, 0, 0, 67348, 0, 0, 0, 0, 1559, 67342, 11104, - 67340, 67347, 67346, 67345, 67344, 0, 0, 67357, 67356, 0, 0, 0, 0, 67352, - 67351, 5516, 2845, 7717, 8036, 65161, 67353, 5514, 12045, 6278, 0, 5515, - 0, 0, 0, 0, 0, 65194, 100387, 5517, 70116, 92774, 0, 67884, 0, 67890, - 42094, 67880, 67881, 67882, 67883, 0, 0, 67879, 120411, 1902, 67887, - 67888, 12976, 126546, 12483, 12368, 41769, 42726, 41765, 69557, 12787, - 67874, 7556, 67878, 74351, 67897, 989, 42677, 67889, 0, 6060, 0, 4326, - 11000, 64601, 68478, 0, 0, 6917, 0, 120837, 0, 0, 0, 6148, 8605, 74205, - 0, 0, 0, 42715, 0, 101047, 0, 68663, 0, 41796, 1269, 42703, 64754, - 101049, 101042, 5144, 12221, 42716, 71048, 5133, 4331, 0, 128675, 0, - 5279, 121362, 71046, 0, 0, 42701, 0, 0, 0, 121470, 0, 0, 0, 983308, 0, - 983608, 121259, 42666, 12207, 1067, 255, 12131, 0, 0, 0, 0, 0, 0, 0, - 70728, 43460, 0, 42723, 125216, 0, 70427, 0, 12797, 0, 0, 983722, 0, - 67977, 12799, 0, 92504, 9746, 5135, 0, 12796, 0, 0, 0, 5139, 346, 74303, - 121134, 12795, 125109, 5168, 0, 43845, 983727, 0, 8253, 8817, 1136, - 983735, 43563, 127774, 129542, 0, 0, 0, 0, 0, 0, 983619, 0, 0, 4041, 0, - 2357, 43240, 12786, 0, 0, 0, 44004, 7142, 0, 67984, 0, 0, 0, 0, 12785, 0, - 0, 7770, 10712, 64853, 42679, 118916, 42375, 0, 983123, 94074, 12119, 0, - 11059, 10791, 111092, 450, 0, 0, 0, 0, 5450, 64691, 0, 0, 44009, 0, 0, - 111097, 94085, 1839, 94004, 0, 10927, 1701, 0, 129610, 41749, 41761, - 5453, 8361, 66045, 41758, 5444, 41763, 0, 0, 0, 66349, 983137, 121274, 0, - 0, 8801, 0, 4340, 0, 0, 0, 0, 70001, 41824, 0, 0, 0, 0, 42700, 0, 127980, - 0, 0, 0, 0, 0, 0, 4493, 4336, 129171, 2314, 983061, 41808, 0, 0, 0, - 64638, 0, 65937, 4489, 71331, 0, 0, 5358, 42717, 0, 71236, 0, 0, 0, - 127042, 41813, 2712, 0, 127044, 1410, 0, 0, 0, 0, 0, 0, 0, 0, 128587, 0, - 0, 0, 4892, 0, 0, 0, 0, 0, 5777, 0, 759, 0, 2079, 65248, 12788, 0, 64552, - 0, 41803, 68043, 0, 0, 0, 0, 128785, 0, 68492, 67991, 75071, 2340, 0, - 120638, 0, 983902, 0, 0, 917865, 64749, 0, 2321, 3587, 0, 67236, 9953, - 9952, 0, 0, 42714, 9951, 0, 0, 127902, 74150, 0, 0, 74757, 127554, 0, - 983826, 2395, 0, 9976, 0, 125128, 0, 0, 0, 42809, 42807, 0, 66290, 70854, - 4150, 64424, 8318, 41790, 67976, 65559, 2360, 41794, 0, 0, 120987, 0, 0, - 2418, 0, 2411, 0, 41783, 0, 41786, 65108, 0, 0, 41772, 42813, 2317, 0, - 118980, 0, 0, 0, 0, 0, 0, 78682, 7753, 2351, 6655, 64489, 0, 0, 0, 4443, - 41697, 230, 65793, 0, 65943, 42803, 0, 0, 5441, 0, 0, 127053, 0, 855, 0, - 6109, 101021, 0, 119116, 69989, 0, 0, 72146, 0, 101023, 0, 72148, 124918, - 19915, 41892, 0, 0, 128901, 41887, 0, 67980, 9735, 0, 0, 120591, 13082, - 101026, 0, 0, 0, 0, 0, 0, 0, 289, 0, 0, 64504, 0, 69489, 120514, 0, - 92962, 0, 42724, 69977, 0, 0, 0, 0, 67994, 0, 0, 0, 3565, 0, 0, 127553, - 43035, 69898, 0, 0, 0, 0, 4891, 0, 0, 4602, 0, 121065, 0, 0, 121157, 0, - 43978, 8988, 0, 0, 0, 0, 0, 119184, 121436, 73902, 69740, 0, 0, 72976, 0, - 0, 8771, 0, 0, 0, 119209, 74974, 71737, 0, 0, 67987, 0, 0, 0, 67989, 0, - 10065, 8207, 0, 983588, 0, 0, 662, 0, 41927, 0, 0, 0, 0, 0, 0, 0, 41929, - 0, 0, 0, 41926, 69994, 0, 0, 0, 126230, 68013, 1433, 64648, 6475, 0, - 120983, 0, 73876, 0, 0, 0, 67992, 78052, 0, 3978, 0, 0, 0, 0, 120761, - 12281, 0, 0, 13241, 0, 0, 0, 0, 11765, 42577, 0, 0, 2641, 7192, 0, 0, - 118809, 101015, 0, 101016, 128948, 101013, 6479, 64294, 118683, 0, 0, 0, - 64334, 0, 0, 0, 92266, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9478, 127339, - 124964, 0, 202, 0, 0, 1242, 0, 121170, 0, 63940, 0, 0, 0, 63939, 11990, - 92430, 67982, 0, 65440, 70068, 0, 0, 64829, 0, 0, 0, 0, 0, 2858, 0, - 63989, 0, 69239, 0, 121152, 0, 77841, 0, 70078, 92574, 129519, 0, 0, 0, - 128974, 0, 12922, 92498, 0, 66424, 71124, 0, 0, 0, 2856, 0, 47, 0, - 126986, 65858, 0, 0, 0, 0, 119161, 8417, 65903, 0, 0, 0, 4033, 128164, 0, - 0, 0, 129961, 64600, 1903, 12320, 0, 120894, 0, 0, 8915, 0, 945, 0, 0, 0, - 0, 111068, 0, 74828, 0, 69560, 9531, 0, 8505, 0, 119238, 0, 0, 65538, 0, - 0, 0, 0, 0, 0, 63935, 0, 0, 0, 0, 0, 64787, 111060, 0, 0, 110828, 0, - 2230, 0, 0, 71886, 9843, 0, 92419, 111062, 67488, 92715, 0, 1320, 0, - 1673, 0, 92383, 129902, 9338, 128355, 0, 0, 0, 0, 11997, 0, 0, 0, 0, 0, - 0, 43308, 0, 0, 0, 0, 0, 0, 0, 63920, 0, 0, 0, 0, 0, 0, 3514, 78723, 0, - 7492, 0, 0, 0, 7514, 0, 63924, 0, 7502, 7587, 0, 0, 0, 118689, 43881, - 7610, 0, 0, 118710, 692, 43588, 0, 0, 75056, 9688, 0, 9535, 0, 0, 0, - 64530, 0, 125251, 194861, 0, 72209, 7453, 0, 8013, 66396, 0, 0, 8895, - 5356, 0, 5458, 0, 2866, 0, 127860, 71732, 71724, 6700, 0, 111081, 120583, - 0, 110614, 0, 9641, 63830, 65294, 0, 0, 67969, 0, 7441, 0, 63826, 0, 0, - 0, 0, 2844, 983972, 0, 63824, 12139, 67971, 0, 0, 3358, 65295, 0, 3104, - 0, 0, 0, 0, 65772, 0, 0, 0, 0, 2862, 11326, 0, 0, 94001, 3268, 66591, 0, - 6552, 42367, 7035, 120558, 0, 0, 1814, 195092, 10240, 195093, 0, 0, 0, 0, - 0, 66960, 0, 0, 2837, 4341, 0, 0, 129982, 125064, 195094, 0, 0, 66964, 0, - 72721, 863, 66936, 0, 0, 43323, 66928, 0, 0, 68054, 0, 3654, 66951, 0, - 66942, 0, 0, 7653, 0, 0, 66587, 0, 0, 92401, 0, 0, 12927, 0, 0, 129697, - 13056, 0, 0, 3056, 0, 0, 195101, 0, 0, 74506, 73770, 0, 0, 0, 0, 0, 0, 0, - 0, 72233, 0, 5811, 0, 0, 0, 66817, 983855, 0, 0, 128636, 129311, 0, - 128041, 0, 67739, 120965, 0, 0, 67507, 0, 68375, 0, 0, 70300, 0, 0, 0, - 983698, 111078, 0, 11991, 128079, 0, 92943, 1502, 74117, 127988, 0, - 129478, 121253, 0, 67661, 0, 0, 125084, 68667, 0, 74057, 68639, 0, 42898, - 120742, 0, 74388, 74838, 120822, 0, 0, 0, 0, 69452, 43214, 5893, 0, 0, - 92496, 0, 0, 119907, 119900, 0, 0, 0, 0, 41950, 0, 0, 68610, 0, 68626, - 894, 0, 0, 12306, 73846, 0, 0, 0, 8636, 0, 121028, 42503, 0, 92942, 0, - 121468, 119241, 0, 126569, 5096, 5095, 2863, 127505, 0, 10454, 42530, - 5094, 0, 0, 13156, 0, 111035, 5093, 127178, 983416, 0, 5092, 10708, - 11327, 0, 5091, 0, 0, 9153, 4104, 78599, 78601, 2929, 42712, 75067, - 12272, 9832, 0, 0, 111105, 0, 0, 0, 0, 0, 0, 13106, 0, 0, 129111, 0, 0, - 0, 0, 9074, 111111, 0, 111110, 0, 8113, 11168, 92563, 1786, 111109, 0, - 111108, 0, 74423, 0, 586, 74414, 64359, 1267, 0, 127531, 0, 65731, 0, 0, - 0, 92932, 0, 0, 0, 0, 0, 0, 1228, 0, 42846, 0, 0, 70343, 1714, 74406, 0, - 0, 0, 127389, 66225, 0, 0, 42660, 0, 0, 3804, 0, 0, 129859, 0, 2826, 0, - 0, 0, 128396, 0, 0, 0, 0, 0, 0, 12206, 5839, 0, 68524, 74065, 0, 0, 0, - 126240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67241, 917821, 7030, 0, 10479, - 64959, 2852, 0, 121225, 0, 0, 128586, 0, 6963, 0, 0, 0, 74786, 0, 0, 0, - 0, 121281, 0, 0, 0, 0, 113815, 121360, 0, 9994, 118680, 2864, 64719, - 1148, 0, 41677, 0, 0, 2765, 0, 128181, 0, 0, 0, 92516, 74777, 0, 0, - 65206, 0, 0, 0, 0, 69391, 0, 0, 983770, 0, 41839, 129616, 983773, 0, 0, - 6931, 0, 0, 7177, 125137, 0, 0, 0, 93020, 0, 10722, 0, 0, 128186, 121050, - 0, 0, 127207, 0, 750, 0, 129453, 63912, 0, 0, 7032, 0, 0, 4314, 128600, - 0, 128409, 730, 0, 127866, 0, 0, 41380, 0, 0, 0, 69697, 8240, 92939, 0, - 41378, 0, 6938, 70026, 0, 0, 66246, 0, 0, 0, 0, 0, 0, 983094, 0, 92754, - 41470, 64805, 0, 0, 0, 0, 0, 0, 0, 0, 92938, 68370, 0, 0, 73831, 0, 0, 0, - 2872, 0, 0, 0, 0, 604, 41097, 0, 0, 0, 0, 0, 127488, 0, 2836, 0, 0, 9707, - 0, 43202, 0, 0, 0, 0, 0, 120916, 2832, 92702, 9670, 12937, 0, 0, 0, 0, - 2822, 0, 0, 92519, 0, 73752, 0, 0, 0, 1331, 92603, 0, 11856, 0, 129432, - 5090, 5089, 0, 3200, 0, 0, 0, 5088, 0, 0, 9477, 0, 0, 5087, 92325, 0, 96, - 5086, 0, 0, 0, 5085, 64286, 0, 0, 43820, 0, 983741, 0, 0, 119042, 0, - 129660, 0, 0, 0, 0, 0, 127241, 120891, 7601, 0, 591, 0, 118953, 0, 0, 0, - 0, 0, 10939, 7246, 6933, 67142, 67141, 0, 74600, 120695, 0, 67138, 65574, - 0, 78058, 67140, 73851, 74598, 67139, 128094, 0, 6372, 0, 0, 7963, 6371, - 0, 0, 125040, 0, 0, 0, 0, 0, 0, 0, 8258, 123591, 0, 0, 65148, 118919, 42, - 0, 0, 0, 0, 0, 0, 0, 0, 67135, 67134, 67133, 0, 0, 0, 0, 67136, 67130, - 74597, 11550, 0, 67132, 65868, 0, 12826, 127872, 0, 126235, 9737, 92448, - 0, 0, 0, 8878, 0, 0, 0, 0, 0, 72220, 9086, 0, 0, 0, 7437, 7454, 0, 0, 0, - 0, 9042, 0, 0, 0, 0, 3805, 0, 67128, 44001, 67126, 0, 44022, 19949, - 12200, 43522, 983045, 43525, 0, 0, 0, 64422, 67125, 67124, 7602, 0, 0, - 43521, 0, 0, 43711, 43523, 41447, 8424, 68483, 8704, 2397, 0, 0, 0, 0, 0, - 10916, 0, 129290, 93998, 0, 0, 0, 127800, 67686, 9961, 123203, 0, 68842, - 10792, 8889, 121402, 6951, 0, 68827, 917835, 74342, 0, 0, 0, 68816, - 129152, 0, 42909, 66597, 70092, 0, 0, 10481, 4559, 0, 1956, 43138, 0, 0, - 43490, 43148, 0, 0, 0, 43140, 0, 0, 0, 0, 69268, 8533, 0, 0, 0, 0, 0, - 4357, 0, 70289, 983156, 0, 42911, 0, 0, 0, 10941, 0, 6962, 0, 0, 113808, - 0, 11014, 0, 8942, 12000, 0, 0, 0, 0, 0, 0, 42650, 0, 75016, 63975, 0, - 66210, 0, 0, 129150, 0, 11193, 0, 0, 0, 0, 0, 0, 0, 43476, 0, 11024, - 74811, 72787, 10563, 92954, 0, 0, 2462, 92955, 0, 0, 66213, 6957, 0, - 120559, 0, 0, 0, 74594, 983421, 92347, 0, 110702, 110708, 110707, 127119, - 3109, 127117, 119909, 0, 121434, 0, 0, 4042, 0, 0, 0, 127123, 127122, - 127121, 0, 127999, 0, 3503, 74444, 68300, 6694, 127997, 0, 0, 74306, 0, - 983757, 7736, 0, 0, 0, 10521, 0, 42173, 9705, 0, 129719, 6955, 71467, 0, - 6149, 3887, 19956, 1411, 2824, 0, 0, 0, 1403, 0, 1347, 66282, 127996, 0, - 0, 0, 0, 8640, 0, 1178, 1654, 0, 0, 129529, 43314, 0, 0, 0, 0, 2873, - 67461, 0, 0, 67085, 10861, 0, 0, 70377, 0, 67082, 11159, 41391, 67084, 0, - 376, 6987, 983181, 119904, 0, 8823, 0, 12943, 65185, 100988, 42099, 0, 0, - 100990, 0, 8301, 0, 0, 1684, 0, 0, 0, 120620, 0, 0, 0, 42121, 0, 66781, - 78067, 42115, 0, 127998, 0, 67080, 1493, 42111, 67077, 4097, 0, 983767, - 0, 65808, 41642, 0, 118568, 67076, 41636, 67074, 65095, 110660, 72254, - 121240, 41629, 12154, 75073, 0, 128179, 74084, 64380, 0, 0, 0, 0, 0, - 71193, 65371, 7078, 121218, 0, 0, 74592, 0, 0, 43275, 0, 41434, 6062, 0, - 0, 19916, 0, 6950, 9606, 9842, 0, 65744, 0, 0, 128659, 0, 41615, 10105, - 0, 0, 41632, 7493, 0, 0, 41622, 0, 0, 0, 0, 7632, 983215, 983214, 9805, - 5990, 900, 0, 983388, 0, 120869, 3612, 0, 64376, 0, 5389, 129469, 0, 0, - 2839, 9621, 582, 0, 0, 3749, 0, 7569, 0, 0, 92865, 6956, 4403, 0, 0, - 3299, 0, 0, 119127, 65676, 0, 74372, 0, 983494, 7598, 69819, 42469, - 42242, 1918, 9542, 480, 7716, 0, 0, 0, 0, 0, 69918, 0, 8328, 0, 118894, - 0, 0, 0, 0, 11132, 0, 66743, 74185, 100531, 2854, 66747, 0, 65755, 0, - 67120, 67119, 65835, 67117, 66736, 67123, 67122, 67121, 9881, 100481, - 65757, 100538, 100459, 67116, 8648, 128377, 6741, 43047, 0, 13180, 0, - 100487, 66754, 0, 128946, 0, 0, 41752, 0, 8641, 100490, 125185, 100489, - 100462, 100541, 6942, 69501, 1024, 42849, 41751, 0, 8941, 101034, 11121, - 0, 9023, 40973, 121476, 9928, 67109, 66865, 0, 67114, 67113, 67112, - 67111, 0, 41206, 120724, 9049, 67108, 43166, 0, 41200, 128201, 125142, - 126537, 0, 0, 41188, 119553, 0, 101007, 917548, 74585, 78626, 0, 0, - 11466, 0, 120797, 0, 125067, 2261, 0, 2860, 0, 0, 70828, 127925, 92357, - 67106, 12065, 42872, 0, 43875, 67103, 43856, 0, 67102, 67105, 7531, - 40981, 2413, 100522, 67404, 100521, 0, 67101, 41196, 100523, 0, 0, - 983746, 43117, 100495, 0, 0, 0, 0, 69876, 0, 7173, 496, 0, 4313, 64607, - 0, 0, 0, 2065, 42793, 2842, 0, 83152, 13132, 798, 0, 12801, 67098, 10686, - 118528, 128143, 0, 8054, 9174, 67087, 67086, 67097, 67096, 41611, 67095, - 74504, 78854, 42512, 0, 78857, 42089, 74613, 78856, 0, 101029, 100468, - 42079, 100467, 0, 66961, 100474, 0, 0, 0, 68338, 69958, 0, 0, 0, 0, 0, - 78859, 42093, 128951, 100504, 0, 0, 0, 4580, 0, 0, 0, 92167, 0, 3021, - 42004, 0, 0, 42317, 41998, 0, 6946, 77920, 0, 123610, 0, 0, 0, 121442, - 42690, 9880, 0, 0, 64589, 0, 0, 127880, 68035, 0, 11360, 0, 0, 72242, 0, - 0, 0, 0, 0, 64941, 0, 0, 0, 6856, 65671, 11244, 73706, 6959, 41994, - 42907, 0, 0, 122902, 8617, 41982, 8860, 0, 0, 121256, 0, 0, 9597, 0, - 43172, 0, 10117, 0, 92297, 65865, 0, 0, 128077, 0, 126065, 0, 187, 0, - 65669, 0, 4963, 0, 0, 0, 8964, 0, 7775, 0, 41948, 0, 0, 101010, 41942, - 65449, 3160, 65922, 13226, 42665, 0, 42663, 128210, 41766, 983500, 78848, - 78849, 41760, 1189, 905, 110620, 42658, 78851, 67859, 9629, 6742, 0, - 43625, 12952, 7888, 0, 3980, 0, 42656, 0, 42055, 0, 0, 0, 64540, 0, 7867, - 69218, 6236, 0, 0, 10505, 0, 12851, 118948, 0, 5474, 128843, 3103, 0, - 41753, 41733, 78051, 983474, 78844, 78845, 41739, 78843, 70744, 10931, - 41756, 43347, 68098, 122909, 41746, 119147, 92591, 41259, 66954, 69930, - 2691, 121338, 11231, 41244, 0, 69800, 66364, 41262, 67503, 0, 0, 41251, - 0, 0, 11805, 0, 0, 68331, 94045, 0, 0, 0, 74633, 41266, 126642, 0, 0, 0, - 65741, 41737, 2275, 2666, 121232, 41738, 4967, 419, 13126, 0, 0, 42822, - 0, 6434, 74913, 0, 0, 6432, 0, 69932, 128862, 769, 41742, 69927, 74805, - 6433, 0, 547, 1943, 6439, 0, 4994, 487, 0, 0, 3754, 0, 0, 0, 0, 74780, 0, - 0, 1595, 92777, 74431, 0, 0, 74860, 43267, 0, 0, 129083, 12185, 69406, 0, - 0, 100984, 0, 42856, 0, 0, 983765, 128319, 75057, 0, 0, 0, 65612, 0, 669, - 0, 0, 0, 0, 0, 70445, 100404, 69929, 0, 0, 460, 121513, 0, 0, 0, 120747, - 0, 121519, 121518, 0, 0, 121515, 71491, 65187, 9044, 78497, 11760, 78494, - 7577, 78491, 41912, 100412, 0, 100411, 0, 0, 100394, 78501, 0, 2933, - 78500, 0, 66441, 100392, 100397, 100391, 1549, 0, 100415, 0, 41755, 6206, - 8670, 120587, 0, 69935, 0, 0, 69768, 100952, 0, 66958, 0, 0, 10552, - 64342, 41922, 0, 917858, 0, 917857, 2717, 0, 0, 0, 73664, 41908, 100722, - 41916, 0, 0, 0, 92506, 100723, 66664, 69803, 0, 100725, 0, 0, 43373, 0, - 0, 8468, 100729, 121173, 128297, 119210, 118952, 0, 0, 0, 100686, 0, 0, - 0, 128703, 100670, 457, 78502, 78503, 123180, 43006, 0, 8802, 113777, 0, - 0, 0, 0, 126632, 0, 41757, 0, 100657, 44000, 0, 0, 43534, 0, 0, 11961, - 121316, 0, 0, 0, 128736, 0, 0, 9499, 92977, 128330, 0, 0, 92260, 68184, - 0, 0, 7256, 66993, 983179, 0, 42161, 0, 119126, 128022, 65880, 0, 10802, - 64861, 0, 0, 0, 0, 0, 0, 73109, 0, 955, 0, 0, 5350, 64339, 0, 100705, - 10875, 0, 5477, 73121, 0, 0, 0, 67693, 69790, 0, 0, 3874, 0, 0, 0, 0, - 83272, 100674, 127397, 0, 100989, 0, 41038, 67502, 9207, 42239, 0, 0, 0, - 0, 74432, 0, 0, 1455, 129680, 0, 11753, 119233, 0, 118594, 127854, - 100716, 69801, 0, 0, 43520, 0, 119556, 0, 0, 0, 0, 100733, 10788, 6088, - 0, 129587, 190, 983343, 12593, 100737, 129308, 64408, 0, 4417, 128615, - 74359, 41744, 0, 0, 100435, 6965, 0, 0, 13201, 100430, 69896, 78868, - 74382, 11841, 7918, 92721, 0, 0, 0, 1728, 0, 0, 0, 983347, 92679, 0, 0, - 92711, 0, 0, 119536, 0, 66679, 8382, 0, 0, 100381, 0, 917889, 42254, - 68371, 100383, 0, 0, 0, 9923, 0, 0, 11763, 100386, 120688, 0, 78187, 0, - 0, 0, 0, 8333, 0, 0, 0, 917805, 74464, 0, 92320, 74080, 0, 69911, 11910, - 0, 74141, 8963, 0, 0, 0, 121396, 0, 41747, 0, 0, 8968, 0, 0, 129110, - 110590, 0, 8836, 12315, 0, 8300, 0, 0, 0, 8856, 0, 0, 69891, 0, 66965, - 120405, 120402, 120403, 120400, 120401, 12853, 43269, 7263, 120244, 6536, - 120238, 120239, 65516, 12321, 120391, 120388, 55287, 2237, 120246, 9588, - 120248, 120382, 120383, 120380, 120381, 0, 0, 3561, 0, 0, 10613, 0, - 110583, 0, 0, 0, 128689, 5006, 64328, 68219, 917894, 0, 8825, 129880, 0, - 0, 0, 128616, 0, 119177, 0, 0, 128641, 120225, 71366, 120227, 120228, - 438, 4510, 41707, 8721, 120233, 120234, 120235, 12840, 120229, 10845, - 120231, 8096, 0, 120935, 0, 0, 65589, 8733, 0, 0, 0, 0, 0, 0, 93984, - 11262, 73747, 128522, 917902, 64591, 42405, 0, 0, 1632, 127982, 128326, - 0, 0, 121327, 121477, 42444, 0, 0, 215, 41258, 128494, 64494, 1953, - 10185, 0, 1256, 3910, 41260, 917903, 0, 0, 41257, 0, 8675, 10700, 0, - 124951, 0, 9333, 0, 121471, 0, 0, 0, 0, 0, 499, 0, 70729, 42915, 0, - 101000, 0, 100999, 0, 0, 73111, 0, 122897, 0, 125006, 0, 11118, 0, - 128009, 0, 0, 118633, 9180, 0, 0, 0, 100986, 43438, 118588, 0, 0, 0, 0, - 120669, 64782, 0, 0, 73969, 565, 42484, 118913, 201, 0, 42292, 69610, 0, - 0, 119625, 43518, 0, 0, 1022, 113788, 3880, 74247, 0, 0, 0, 0, 0, 0, 0, - 0, 72272, 100997, 0, 0, 66937, 74255, 0, 0, 92598, 0, 9903, 118993, 0, - 68226, 0, 0, 0, 127788, 100955, 83280, 7892, 0, 10777, 0, 0, 65562, 0, - 101002, 0, 8039, 3363, 101009, 0, 0, 66940, 12596, 70812, 0, 0, 0, 0, - 42944, 92425, 74992, 64541, 0, 0, 10520, 12802, 0, 12998, 0, 83270, - 42861, 83273, 11415, 0, 7541, 125068, 65878, 822, 0, 0, 5774, 194746, - 43252, 0, 92619, 7672, 129281, 0, 0, 7463, 0, 0, 0, 0, 0, 0, 121411, 0, - 0, 0, 66938, 0, 475, 0, 120586, 7329, 0, 0, 195088, 66291, 10645, 0, - 6543, 100966, 0, 0, 119065, 0, 0, 0, 983234, 195095, 0, 8923, 1645, 0, 0, - 0, 3196, 72404, 0, 0, 43595, 0, 0, 0, 0, 0, 195076, 0, 0, 5258, 4328, 0, - 0, 0, 405, 11454, 0, 0, 0, 0, 75052, 41245, 0, 195078, 4523, 11369, 0, 0, - 0, 195079, 0, 0, 983507, 0, 100961, 10480, 74610, 0, 0, 0, 12610, 0, - 41247, 0, 7609, 118837, 0, 0, 92253, 0, 984, 0, 92621, 0, 0, 129885, - 73982, 0, 0, 0, 43369, 0, 0, 0, 983504, 6634, 0, 71952, 0, 66930, 74214, - 0, 67709, 0, 0, 0, 71114, 9552, 0, 0, 0, 12997, 0, 0, 0, 0, 129109, - 12883, 10994, 10529, 55283, 0, 74618, 0, 67736, 10661, 19951, 9614, 2428, - 0, 121023, 92837, 126224, 66933, 71127, 0, 124996, 119162, 1952, 92181, - 8455, 100958, 0, 93033, 119566, 100960, 0, 12183, 100951, 0, 64929, 0, 0, - 0, 128290, 42509, 73087, 3922, 9187, 983626, 0, 0, 119057, 0, 3353, 9358, - 0, 0, 66680, 0, 73975, 12879, 0, 9795, 68380, 0, 0, 0, 0, 0, 41027, 0, - 66931, 0, 983631, 0, 70378, 0, 11751, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 129356, 0, 0, 0, 0, 41029, 0, 126513, 0, 0, 0, 11294, 0, 66665, 0, 0, - 127750, 0, 0, 70105, 0, 983643, 0, 67843, 0, 0, 121167, 983895, 0, 8088, - 129412, 0, 0, 0, 983992, 6926, 72423, 0, 129569, 42369, 4350, 0, 65145, - 9041, 43559, 0, 0, 0, 41263, 0, 0, 0, 65825, 9577, 68199, 0, 0, 983121, - 0, 6793, 0, 70409, 0, 0, 0, 0, 64669, 0, 0, 0, 11200, 72725, 2995, 0, 0, - 0, 7868, 72720, 72020, 11386, 1009, 70405, 66871, 2333, 0, 0, 0, 0, 0, - 70407, 128121, 0, 0, 0, 0, 983657, 66949, 0, 74968, 0, 0, 110601, 0, 0, - 41261, 0, 0, 0, 0, 118989, 6736, 917883, 0, 43010, 66952, 0, 69635, - 73011, 983716, 0, 0, 7293, 0, 0, 0, 0, 111332, 0, 128245, 69928, 0, 0, + 0, 0, 0, 983846, 0, 0, 0, 67817, 0, 1272, 0, 0, 0, 983578, 0, 1467, + 119501, 917806, 0, 0, 0, 70312, 73537, 124955, 0, 70400, 0, 0, 72817, 0, + 19935, 0, 92162, 0, 0, 0, 128406, 5275, 0, 0, 44006, 129082, 0, 3789, + 128205, 0, 0, 0, 11474, 0, 0, 0, 129050, 0, 92194, 129503, 9537, 4496, 0, + 120443, 2605, 4500, 0, 55224, 8600, 0, 0, 41646, 11667, 69569, 0, 0, + 917905, 4499, 41649, 0, 0, 0, 69254, 0, 0, 0, 65804, 0, 70034, 41866, 0, + 0, 0, 11174, 0, 0, 0, 9559, 128773, 41940, 8299, 41945, 0, 41941, 5455, + 7190, 0, 0, 917810, 65266, 0, 41943, 10762, 0, 41931, 0, 0, 8106, 4128, + 0, 0, 4494, 0, 0, 72405, 0, 119567, 42068, 917808, 0, 11004, 12794, + 65072, 5271, 7317, 0, 0, 0, 0, 0, 0, 92281, 0, 0, 0, 0, 71880, 3868, + 71881, 983573, 128431, 7703, 0, 64390, 0, 7406, 120358, 93850, 0, 3985, + 66425, 0, 66615, 10177, 0, 41853, 71873, 12809, 0, 12193, 0, 10879, + 122945, 0, 9055, 0, 3851, 8132, 0, 0, 119263, 917908, 0, 0, 0, 0, 122940, + 42657, 122952, 7643, 0, 0, 122936, 43568, 0, 11949, 7650, 43569, 64951, + 7647, 7649, 0, 7646, 0, 0, 9651, 125005, 3891, 0, 0, 2337, 77831, 77832, + 67860, 129288, 0, 0, 43561, 67706, 119669, 0, 1860, 0, 68835, 5812, + 12784, 0, 0, 0, 0, 69260, 7727, 0, 69292, 69818, 66444, 128665, 42719, 0, + 1569, 0, 12534, 12124, 7690, 194871, 12533, 0, 68383, 67997, 0, 6969, 0, + 0, 0, 67974, 63895, 128650, 0, 0, 0, 42144, 0, 0, 0, 0, 92211, 119043, 0, + 0, 917545, 0, 0, 12791, 0, 0, 0, 4447, 71065, 12793, 0, 0, 43385, 0, 0, + 12790, 120256, 0, 983840, 12792, 120254, 0, 0, 12789, 128489, 12317, + 74934, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127840, 41652, 2974, 78689, 11476, + 0, 0, 0, 0, 43871, 0, 10894, 119176, 74557, 65686, 0, 0, 3724, 67335, + 67334, 67333, 67338, 67337, 0, 67336, 0, 65306, 0, 128421, 0, 8646, + 129593, 77829, 0, 0, 74852, 0, 0, 0, 0, 0, 220, 120252, 43551, 0, 10044, + 0, 0, 983847, 68659, 110825, 5707, 71362, 0, 0, 0, 0, 0, 0, 10297, 0, + 41308, 67331, 0, 0, 0, 0, 2467, 0, 6003, 0, 0, 8040, 0, 0, 4182, 0, + 11135, 120501, 0, 0, 2510, 0, 10208, 0, 78302, 70829, 0, 0, 6837, 0, 0, + 67348, 0, 0, 0, 0, 1559, 67342, 11104, 67340, 67347, 67346, 67345, 67344, + 0, 0, 67357, 67356, 0, 0, 0, 0, 67352, 67351, 5516, 2845, 7717, 8036, + 65161, 67353, 5514, 12045, 6278, 0, 5515, 0, 0, 0, 0, 0, 65194, 100387, + 5517, 70116, 92774, 0, 67884, 0, 67890, 42094, 67880, 67881, 67882, + 67883, 0, 0, 67879, 120411, 1902, 67887, 67888, 12976, 126546, 12483, + 12368, 41769, 42726, 41765, 69557, 12787, 67874, 7556, 67878, 74351, + 67897, 989, 42677, 67889, 0, 6060, 0, 4326, 11000, 64601, 68478, 0, 0, + 6917, 0, 120837, 0, 0, 0, 6148, 8605, 74205, 0, 0, 0, 42715, 0, 101047, + 0, 68663, 0, 41796, 1269, 42703, 64754, 101049, 101042, 5144, 12221, + 42716, 71048, 5133, 4331, 0, 128675, 0, 5279, 121362, 71046, 0, 0, 42701, + 0, 0, 0, 121470, 0, 0, 0, 983311, 0, 72455, 121259, 42666, 12207, 1067, + 255, 12131, 0, 0, 0, 0, 0, 0, 0, 70728, 43460, 0, 42723, 125216, 0, + 70427, 0, 12797, 0, 0, 983722, 0, 67977, 12799, 0, 92504, 9746, 5135, 0, + 12796, 0, 0, 0, 5139, 346, 74303, 121134, 12795, 125109, 5168, 0, 43845, + 983727, 0, 8253, 8817, 1136, 983735, 43563, 127774, 129542, 0, 0, 0, 0, + 0, 0, 983619, 0, 0, 4041, 0, 2357, 43240, 12786, 0, 0, 0, 44004, 7142, 0, + 67984, 0, 0, 0, 0, 12785, 0, 0, 7770, 10712, 64853, 42679, 118916, 42375, + 0, 983124, 94074, 12119, 0, 11059, 10791, 111092, 450, 0, 0, 0, 0, 5450, + 64691, 0, 0, 44009, 0, 0, 111097, 94085, 1839, 94004, 0, 10927, 1701, 0, + 129610, 41749, 41761, 5453, 8361, 66045, 41758, 5444, 41763, 0, 0, 0, + 66349, 983138, 121274, 0, 0, 8801, 0, 4340, 0, 0, 0, 0, 70001, 41824, 0, + 0, 0, 0, 42700, 0, 127980, 0, 0, 0, 0, 0, 0, 4493, 4336, 129171, 2314, + 983061, 41808, 0, 0, 0, 64638, 0, 65937, 4489, 71331, 0, 0, 5358, 42717, + 0, 71236, 0, 0, 0, 127042, 41813, 2712, 0, 127044, 1410, 0, 0, 0, 0, 0, + 0, 0, 0, 128587, 0, 0, 0, 4892, 0, 0, 0, 0, 122966, 5777, 0, 759, 0, + 2079, 65248, 12788, 0, 64552, 0, 41803, 68043, 0, 0, 0, 0, 128785, 0, + 68492, 67991, 75071, 2340, 0, 120638, 0, 983902, 0, 0, 917865, 64749, 0, + 2321, 3587, 0, 67236, 9953, 9952, 0, 0, 42714, 9951, 0, 0, 127902, 74150, + 0, 0, 74757, 127554, 0, 983826, 2395, 0, 9976, 0, 125128, 0, 0, 0, 42809, + 42807, 0, 66290, 70854, 4150, 64424, 8318, 41790, 67976, 65559, 2360, + 41794, 0, 0, 120987, 0, 0, 2418, 0, 2411, 0, 41783, 0, 41786, 65108, 0, + 0, 41772, 42813, 2317, 0, 118980, 0, 0, 0, 0, 0, 0, 78682, 7753, 2351, + 6655, 64489, 0, 0, 0, 4443, 41697, 230, 65793, 0, 65943, 42803, 0, 0, + 5441, 0, 0, 127053, 0, 855, 0, 6109, 101021, 0, 119116, 69989, 0, 0, + 72146, 0, 101023, 0, 72148, 124918, 19915, 41892, 0, 0, 128901, 41887, 0, + 67980, 9735, 0, 0, 120591, 13082, 101026, 0, 0, 0, 0, 0, 0, 0, 289, 0, 0, + 64504, 0, 69489, 120514, 0, 92962, 0, 42724, 69977, 0, 0, 0, 0, 67994, 0, + 0, 983823, 3565, 0, 0, 127553, 43035, 69898, 0, 0, 0, 0, 4891, 0, 0, + 4602, 0, 121065, 0, 0, 121157, 0, 43978, 8988, 0, 0, 0, 0, 0, 119184, + 121436, 73902, 69740, 0, 0, 72976, 0, 0, 8771, 0, 0, 0, 119209, 74974, + 71737, 0, 0, 67987, 0, 0, 0, 67989, 0, 10065, 8207, 0, 983588, 0, 0, 662, + 0, 41927, 0, 0, 0, 0, 0, 0, 0, 41929, 0, 0, 0, 41926, 69994, 0, 0, 0, + 126230, 68013, 1433, 64648, 6475, 0, 120983, 0, 73876, 0, 0, 0, 67992, + 78052, 0, 3978, 0, 0, 0, 0, 120761, 12281, 0, 0, 13241, 0, 0, 0, 0, + 11765, 42577, 0, 0, 2641, 7192, 0, 0, 118809, 101015, 0, 101016, 128948, + 101013, 6479, 64294, 118683, 0, 0, 0, 64334, 0, 0, 0, 92266, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 9478, 127339, 124964, 0, 202, 0, 0, 1242, 0, 121170, 0, + 63940, 0, 0, 0, 63939, 11990, 92430, 67982, 0, 65440, 70068, 0, 0, 64829, + 0, 0, 0, 0, 0, 2858, 0, 63989, 0, 69239, 0, 121152, 0, 77841, 0, 70078, + 92574, 129519, 0, 0, 0, 128974, 0, 12922, 92498, 0, 66424, 71124, 0, 0, + 0, 2856, 0, 47, 0, 126986, 65858, 0, 0, 0, 0, 119161, 8417, 65903, 0, 0, + 0, 4033, 128164, 0, 0, 0, 129961, 64600, 1903, 12320, 0, 120894, 0, 0, + 8915, 0, 945, 0, 0, 0, 0, 111068, 0, 74828, 0, 69560, 9531, 0, 8505, 0, + 119238, 0, 0, 65538, 0, 0, 0, 0, 0, 0, 63935, 0, 0, 0, 0, 0, 64787, + 111060, 0, 0, 110828, 0, 2230, 0, 0, 71886, 9843, 0, 92419, 111062, + 67488, 92715, 0, 1320, 0, 1673, 0, 92383, 129902, 9338, 128355, 0, 0, 0, + 0, 11997, 0, 0, 0, 0, 0, 0, 43308, 0, 0, 0, 0, 0, 0, 0, 63920, 0, 0, 0, + 0, 0, 0, 3514, 78723, 0, 7492, 0, 0, 0, 7514, 0, 63924, 0, 7502, 7587, 0, + 0, 0, 118689, 43881, 7610, 0, 0, 118710, 692, 43588, 0, 0, 75056, 9688, + 0, 9535, 0, 0, 0, 64530, 0, 125251, 194861, 0, 72209, 7453, 0, 8013, + 66396, 0, 0, 8895, 5356, 0, 5458, 0, 2866, 0, 127860, 71732, 71724, 6700, + 0, 111081, 120583, 0, 110614, 0, 9641, 63830, 65294, 0, 0, 67969, 0, + 7441, 0, 63826, 0, 0, 0, 0, 2844, 983972, 0, 63824, 12139, 67971, 0, 0, + 3358, 65295, 0, 3104, 0, 0, 0, 0, 65772, 0, 0, 0, 0, 2862, 11326, 0, 0, + 94001, 3268, 66591, 0, 6552, 42367, 7035, 120558, 0, 0, 1814, 195092, + 10240, 195093, 0, 0, 0, 0, 0, 66960, 0, 0, 2837, 4341, 0, 0, 129982, + 125064, 195094, 0, 0, 66964, 0, 72721, 863, 66936, 0, 0, 43323, 66928, 0, + 0, 68054, 0, 3654, 66951, 0, 66942, 0, 0, 7653, 0, 0, 66587, 0, 0, 92401, + 0, 0, 12927, 0, 0, 129697, 13056, 0, 0, 3056, 0, 0, 195101, 0, 0, 74506, + 73770, 0, 0, 0, 0, 0, 0, 0, 0, 72233, 0, 5811, 0, 0, 0, 66817, 983855, 0, + 0, 128636, 129311, 0, 128041, 0, 67739, 120965, 0, 0, 67507, 0, 68375, 0, + 0, 70300, 0, 0, 0, 983698, 111078, 0, 11991, 128079, 0, 92943, 1502, + 74117, 127988, 0, 129478, 121253, 0, 67661, 0, 0, 125084, 68667, 0, + 74057, 68639, 0, 42898, 120742, 0, 74388, 74838, 120822, 0, 0, 0, 0, + 69452, 43214, 5893, 0, 0, 92496, 0, 0, 119907, 119900, 0, 0, 0, 0, 41950, + 0, 0, 68610, 0, 68626, 894, 0, 0, 12306, 73846, 0, 0, 0, 8636, 0, 121028, + 42503, 0, 92942, 0, 121468, 119241, 0, 126569, 5096, 5095, 2863, 127505, + 0, 10454, 42530, 5094, 0, 0, 13156, 0, 111035, 5093, 111024, 983419, 0, + 5092, 10708, 11327, 0, 5091, 0, 0, 9153, 4104, 78599, 78601, 2929, 42712, + 75067, 12272, 9832, 0, 0, 111105, 0, 0, 0, 0, 0, 0, 13106, 0, 0, 129111, + 0, 0, 0, 0, 9074, 111111, 0, 111110, 0, 8113, 11168, 92563, 1786, 111109, + 0, 111108, 0, 74423, 0, 586, 74414, 64359, 1267, 0, 127531, 0, 65731, 0, + 0, 0, 92932, 0, 0, 0, 0, 0, 0, 1228, 0, 42846, 0, 0, 70343, 1714, 74406, + 0, 0, 0, 127389, 66225, 0, 0, 42660, 0, 0, 3804, 0, 0, 129859, 0, 2826, + 0, 0, 0, 128396, 0, 0, 0, 0, 0, 0, 12206, 5839, 0, 68524, 74065, 73521, + 0, 0, 126240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67241, 917821, 7030, 0, + 10479, 64959, 2852, 0, 121225, 0, 0, 128586, 0, 6963, 0, 0, 0, 74786, 0, + 0, 0, 0, 121281, 0, 0, 0, 0, 113815, 121360, 0, 9994, 118680, 2864, + 64719, 1148, 0, 41677, 0, 0, 2765, 0, 128181, 0, 0, 0, 92516, 74777, 0, + 0, 65206, 0, 0, 0, 0, 69391, 0, 0, 983770, 0, 41839, 129616, 983773, 0, + 0, 6931, 0, 0, 7177, 125137, 0, 0, 0, 93020, 0, 10722, 0, 0, 128186, + 121050, 0, 0, 127207, 0, 750, 0, 129453, 63912, 0, 0, 7032, 0, 0, 4314, + 128600, 0, 128409, 730, 0, 127866, 0, 0, 41380, 0, 0, 0, 69697, 8240, + 92939, 0, 41378, 0, 6938, 70026, 0, 0, 66246, 0, 0, 0, 0, 0, 0, 983094, + 0, 92754, 41470, 64805, 0, 0, 0, 0, 0, 0, 0, 0, 92938, 68370, 0, 0, + 73831, 0, 0, 0, 2872, 0, 0, 0, 0, 604, 41097, 0, 0, 0, 0, 0, 127488, 0, + 2836, 0, 0, 9707, 0, 43202, 0, 0, 69374, 0, 0, 120916, 2832, 92702, 9670, + 12937, 0, 0, 0, 0, 2822, 0, 0, 92519, 0, 73752, 0, 0, 0, 1331, 92603, 0, + 11856, 73510, 129432, 5090, 5089, 0, 3200, 0, 0, 0, 5088, 0, 0, 9477, 0, + 0, 5087, 92325, 0, 96, 5086, 0, 0, 0, 5085, 64286, 0, 0, 43820, 0, + 129710, 0, 0, 119042, 0, 129660, 0, 0, 0, 0, 0, 127241, 120891, 7601, 0, + 591, 0, 118953, 0, 0, 0, 0, 0, 10939, 7246, 6933, 67142, 67141, 0, 74600, + 120695, 0, 67138, 65574, 0, 78058, 67140, 73851, 74598, 67139, 128094, 0, + 6372, 0, 73514, 7963, 6371, 0, 0, 125040, 0, 0, 0, 0, 0, 0, 0, 8258, + 123591, 0, 0, 65148, 118919, 42, 0, 0, 0, 0, 0, 0, 0, 0, 67135, 67134, + 67133, 0, 0, 0, 0, 67136, 67130, 74597, 11550, 0, 67132, 65868, 0, 12826, + 127872, 124116, 126235, 9737, 92448, 0, 0, 0, 8878, 0, 0, 0, 0, 0, 72220, + 9086, 0, 100952, 0, 7437, 7454, 0, 0, 0, 0, 9042, 0, 0, 0, 0, 3805, 0, + 67128, 44001, 67126, 0, 44022, 19949, 12200, 43522, 983045, 43525, 0, 0, + 0, 64422, 67125, 67124, 7602, 0, 0, 43521, 0, 0, 43711, 43523, 41447, + 8424, 68483, 8704, 2397, 0, 0, 0, 0, 0, 10916, 0, 129290, 93998, 0, 0, 0, + 127800, 67686, 9961, 123203, 0, 68842, 10792, 8889, 121402, 6951, 0, + 68827, 917835, 74342, 0, 0, 0, 68816, 129152, 0, 42909, 66597, 70092, 0, + 0, 10481, 4559, 0, 1956, 43138, 0, 0, 43490, 43148, 0, 0, 0, 43140, 0, 0, + 0, 0, 69268, 8533, 0, 0, 0, 0, 0, 4357, 0, 70289, 983157, 0, 42911, 0, 0, + 0, 10941, 0, 6962, 0, 0, 113808, 0, 11014, 0, 8942, 12000, 0, 0, 73515, + 0, 0, 0, 42650, 0, 75016, 63975, 0, 66210, 0, 0, 129150, 0, 11193, 0, 0, + 0, 0, 0, 0, 0, 43476, 0, 11024, 74811, 72787, 10563, 92954, 0, 0, 2462, + 92955, 0, 0, 66213, 6957, 0, 120559, 0, 0, 0, 74594, 983424, 92347, 0, + 110702, 110708, 110707, 127119, 3109, 127117, 119909, 0, 121434, 0, 0, + 4042, 0, 0, 0, 127123, 127122, 127121, 0, 127999, 0, 3503, 74444, 68300, + 6694, 127997, 0, 0, 74306, 0, 983757, 7736, 0, 0, 0, 10521, 0, 42173, + 9705, 0, 129719, 6955, 71467, 0, 6149, 3887, 19956, 1411, 2824, 0, 0, 0, + 1403, 0, 1347, 66282, 127996, 0, 0, 0, 0, 8640, 0, 1178, 1654, 0, 0, + 129529, 43314, 0, 0, 0, 0, 2873, 67461, 0, 0, 67085, 10861, 0, 0, 70377, + 0, 67082, 11159, 41391, 67084, 0, 376, 6987, 983182, 119904, 0, 8823, 0, + 12943, 65185, 100988, 42099, 0, 0, 100990, 0, 8301, 0, 0, 1684, 0, 0, 0, + 120620, 0, 0, 0, 42121, 0, 66781, 78067, 42115, 0, 127998, 0, 67080, + 1493, 42111, 67077, 4097, 0, 983767, 0, 65808, 41642, 0, 118568, 67076, + 41636, 67074, 65095, 110660, 72254, 121240, 41629, 12154, 75073, 0, + 128179, 74084, 64380, 0, 0, 0, 0, 0, 71193, 65371, 7078, 121218, 0, 0, + 74592, 0, 0, 43275, 0, 41434, 6062, 0, 0, 19916, 0, 6950, 9606, 9842, 0, + 65744, 0, 0, 128659, 0, 41615, 10105, 0, 0, 41632, 7493, 0, 0, 41622, 0, + 0, 0, 0, 7632, 983217, 983216, 9805, 5990, 900, 0, 122955, 0, 120869, + 3612, 0, 64376, 0, 5389, 129469, 73495, 0, 2839, 9621, 582, 0, 0, 3749, + 0, 7569, 0, 0, 92865, 6956, 4403, 0, 0, 3299, 0, 0, 119127, 65676, 0, + 74372, 0, 983497, 7598, 69819, 42469, 42242, 1918, 9542, 480, 7716, 0, 0, + 0, 0, 0, 69918, 0, 8328, 0, 118894, 0, 0, 0, 0, 11132, 983502, 66743, + 74185, 100531, 2854, 66747, 0, 65755, 0, 67120, 67119, 65835, 67117, + 66736, 67123, 67122, 67121, 9881, 100481, 65757, 100538, 100459, 67116, + 8648, 128377, 6741, 43047, 0, 13180, 0, 100487, 66754, 73507, 73487, 0, + 0, 41752, 0, 8641, 100490, 125185, 73477, 100462, 100541, 6942, 69501, + 1024, 42849, 41751, 0, 8941, 101034, 11121, 0, 9023, 40973, 121476, 9928, + 67109, 66865, 0, 67114, 67113, 67112, 67111, 0, 41206, 120724, 9049, + 67108, 43166, 0, 41200, 128201, 125142, 126537, 0, 0, 41188, 119553, 0, + 101007, 917548, 74585, 78626, 0, 0, 11466, 0, 120797, 0, 125067, 2261, 0, + 2860, 0, 0, 70828, 127925, 92357, 67106, 12065, 42872, 0, 43875, 67103, + 43856, 0, 67102, 67105, 7531, 40981, 2413, 100522, 67404, 100521, 0, + 67101, 41196, 100523, 0, 129723, 73512, 43117, 100495, 0, 0, 0, 0, 69876, + 0, 7173, 496, 0, 4313, 64607, 0, 0, 983202, 2065, 42793, 2842, 0, 83152, + 13132, 798, 0, 12801, 67098, 10686, 118528, 128143, 0, 8054, 9174, 67087, + 67086, 67097, 67096, 41611, 67095, 74504, 78854, 42512, 0, 78857, 42089, + 74613, 78856, 0, 101029, 100468, 42079, 100467, 0, 66961, 100474, 0, 0, + 0, 68338, 69958, 0, 0, 0, 0, 0, 78859, 42093, 128951, 100504, 0, 0, 0, + 4580, 0, 0, 0, 92167, 0, 3021, 42004, 0, 0, 42317, 41998, 0, 6946, 77920, + 0, 123610, 0, 0, 0, 121442, 42690, 9880, 0, 0, 64589, 0, 0, 127880, + 68035, 0, 11360, 0, 0, 72242, 0, 0, 0, 0, 0, 64941, 0, 0, 0, 6856, 65671, + 11244, 73706, 6959, 41994, 42907, 0, 0, 122902, 8617, 41982, 8860, 0, 0, + 121256, 0, 0, 9597, 0, 43172, 0, 10117, 0, 92297, 65865, 73549, 0, + 128077, 0, 126065, 0, 187, 0, 65669, 0, 4963, 0, 0, 0, 8964, 0, 7775, 0, + 41948, 0, 0, 101010, 41942, 65449, 3160, 65922, 13226, 42665, 0, 42663, + 128210, 41766, 983503, 78848, 78849, 41760, 1189, 905, 110620, 42658, + 78851, 67859, 9629, 6742, 0, 43625, 12952, 7888, 0, 3980, 0, 42656, 0, + 42055, 0, 0, 0, 64540, 0, 7867, 69218, 6236, 0, 73490, 10505, 0, 12851, + 118948, 0, 5474, 128843, 3103, 0, 41753, 41733, 78051, 983477, 78844, + 78845, 41739, 78843, 70744, 10931, 41756, 43347, 68098, 122909, 41746, + 119147, 92591, 41259, 66954, 69930, 2691, 121338, 11231, 41244, 0, 69800, + 66364, 41262, 67503, 0, 0, 41251, 0, 0, 11805, 0, 0, 68331, 94045, 0, 0, + 0, 74633, 41266, 126642, 0, 0, 0, 65741, 41737, 2275, 2666, 121232, + 41738, 4967, 419, 13126, 0, 0, 42822, 0, 6434, 74913, 0, 0, 6432, 0, + 69932, 128862, 769, 41742, 69927, 74805, 6433, 0, 547, 1943, 6439, 0, + 4994, 487, 0, 0, 3754, 0, 0, 0, 0, 74780, 0, 0, 1595, 92777, 74431, 0, 0, + 74860, 43267, 0, 0, 129083, 12185, 69406, 0, 73479, 100984, 0, 42856, 0, + 0, 983765, 128319, 75057, 0, 0, 0, 65612, 0, 669, 0, 0, 0, 0, 0, 70445, + 100404, 69929, 0, 0, 460, 121513, 0, 0, 0, 120747, 0, 121519, 121518, 0, + 0, 121515, 71491, 65187, 9044, 78497, 11760, 78494, 7577, 78491, 41912, + 100412, 0, 100411, 0, 0, 100394, 78501, 0, 2933, 78500, 0, 66441, 100392, + 100397, 100391, 1549, 0, 100415, 0, 41755, 6206, 8670, 120587, 0, 69935, + 0, 0, 69768, 73492, 0, 66958, 0, 0, 10552, 64342, 41922, 0, 917858, 0, + 917857, 2717, 0, 0, 0, 73664, 41908, 100722, 41916, 0, 0, 0, 92506, + 100723, 66664, 69803, 0, 100725, 0, 0, 43373, 0, 0, 8468, 100729, 121173, + 128297, 119210, 118952, 0, 0, 0, 100686, 0, 0, 0, 128703, 100670, 457, + 78502, 78503, 123180, 43006, 0, 8802, 113777, 0, 0, 0, 0, 126632, 0, + 41757, 0, 100657, 44000, 0, 0, 43534, 0, 0, 11961, 121316, 0, 0, 0, + 128736, 0, 0, 9499, 73522, 128330, 0, 0, 92260, 68184, 0, 0, 7256, 66993, + 983180, 0, 42161, 0, 119126, 128022, 65880, 0, 10802, 64861, 0, 0, 0, 0, + 0, 0, 73109, 0, 955, 0, 0, 5350, 64339, 0, 100705, 10875, 0, 5477, 73121, + 0, 0, 0, 67693, 69790, 0, 0, 3874, 0, 983741, 0, 0, 83272, 100674, + 127397, 0, 100989, 0, 41038, 67502, 9207, 42239, 0, 0, 0, 0, 74432, 0, 0, + 1455, 129680, 0, 11753, 119233, 0, 118594, 127854, 100716, 69801, 0, 0, + 43520, 0, 119556, 0, 0, 0, 0, 100733, 10788, 6088, 0, 129587, 190, + 983346, 12593, 100737, 129308, 64408, 0, 4417, 128615, 74359, 41744, 0, + 0, 100435, 6965, 0, 0, 13201, 100430, 69896, 78868, 74382, 11841, 7918, + 92721, 0, 0, 0, 1728, 0, 0, 0, 983350, 92679, 0, 0, 92711, 0, 0, 119536, + 73491, 66679, 8382, 0, 0, 100381, 0, 917889, 42254, 68371, 100383, 0, 0, + 0, 9923, 0, 0, 11763, 100386, 120688, 0, 78187, 0, 0, 0, 0, 8333, 0, 0, + 0, 917805, 74464, 0, 92320, 74080, 0, 69911, 11910, 0, 74141, 8963, 0, 0, + 0, 121396, 0, 41747, 0, 0, 8968, 0, 0, 129110, 110590, 0, 8836, 12315, 0, + 8300, 0, 0, 0, 8856, 0, 0, 69891, 0, 66965, 120405, 120402, 120403, + 120400, 120401, 12853, 43269, 7263, 120244, 6536, 120238, 120239, 65516, + 12321, 120391, 120388, 55287, 2237, 120246, 9588, 120248, 120382, 120383, + 120380, 120381, 0, 0, 3561, 0, 0, 10613, 0, 110583, 0, 0, 0, 128689, + 5006, 64328, 68219, 917894, 0, 8825, 122972, 0, 0, 0, 128616, 0, 119177, + 0, 0, 128641, 120225, 71366, 120227, 120228, 438, 4510, 41707, 8721, + 120233, 120234, 120235, 12840, 120229, 10845, 120231, 8096, 0, 120935, 0, + 0, 65589, 8733, 0, 0, 0, 0, 0, 0, 93984, 11262, 73747, 128522, 917902, + 64591, 42405, 0, 0, 1632, 127982, 128326, 0, 0, 121327, 121477, 42444, 0, + 0, 215, 41258, 128494, 64494, 1953, 10185, 0, 1256, 3910, 41260, 917903, + 0, 0, 41257, 0, 8675, 10700, 0, 124951, 0, 9333, 0, 121471, 0, 0, 0, 0, + 0, 499, 0, 70729, 42915, 0, 101000, 0, 100999, 0, 0, 73111, 128893, + 122897, 0, 125006, 0, 11118, 0, 128009, 0, 0, 118633, 9180, 0, 0, 0, + 100986, 43438, 118588, 0, 0, 0, 0, 120669, 64782, 0, 0, 73969, 565, + 42484, 118913, 201, 0, 42292, 69610, 0, 0, 119625, 43518, 0, 0, 1022, + 113788, 3880, 74247, 0, 0, 0, 0, 0, 0, 0, 0, 72272, 100997, 0, 0, 66937, + 74255, 0, 0, 92598, 0, 9903, 118993, 0, 68226, 0, 0, 0, 127788, 100955, + 83280, 7892, 0, 10777, 0, 0, 65562, 0, 101002, 0, 8039, 3363, 101009, 0, + 0, 66940, 12596, 70812, 0, 0, 0, 0, 42944, 92425, 74992, 64541, 0, 0, + 10520, 12802, 0, 12998, 0, 83270, 42861, 83273, 11415, 0, 7541, 125068, + 65878, 822, 0, 0, 5774, 194746, 43252, 0, 92619, 7672, 129281, 0, 0, + 7463, 0, 0, 0, 0, 0, 0, 121411, 0, 0, 0, 66938, 0, 475, 0, 120586, 7329, + 0, 0, 195088, 66291, 10645, 0, 6543, 100966, 0, 0, 119065, 0, 0, 0, + 983237, 195095, 0, 8923, 1645, 0, 0, 0, 3196, 72404, 0, 0, 43595, 0, 0, + 0, 0, 0, 195076, 0, 0, 5258, 4328, 0, 0, 0, 405, 11454, 0, 0, 0, 0, + 75052, 41245, 0, 195078, 4523, 11369, 0, 0, 0, 195079, 0, 0, 983510, 0, + 100961, 10480, 74610, 0, 0, 0, 12610, 0, 41247, 0, 7609, 118837, 0, 0, + 92253, 0, 984, 0, 92621, 0, 0, 129885, 73982, 0, 0, 0, 43369, 0, 0, 0, + 983507, 6634, 0, 71952, 0, 66930, 74214, 0, 67709, 0, 0, 0, 71114, 9552, + 0, 0, 0, 12997, 0, 0, 0, 0, 129109, 12883, 10994, 10529, 55283, 0, 74618, + 0, 67736, 10661, 19951, 9614, 2428, 0, 121023, 92837, 126224, 66933, + 71127, 0, 124996, 119162, 1952, 92181, 8455, 100958, 118654, 93033, + 119566, 100960, 0, 12183, 100951, 0, 64929, 0, 0, 0, 128290, 42509, + 73087, 3922, 9187, 983626, 0, 0, 119057, 0, 3353, 9358, 0, 0, 66680, 0, + 73975, 12879, 0, 9795, 68380, 0, 0, 119488, 0, 0, 41027, 0, 66931, 0, + 983631, 0, 70378, 0, 11751, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 129356, 0, 0, + 0, 0, 41029, 0, 126513, 0, 0, 0, 11294, 0, 66665, 0, 0, 127750, 0, 0, + 70105, 0, 983643, 0, 67843, 0, 0, 121167, 983895, 0, 8088, 129412, 0, 0, + 0, 983992, 6926, 72423, 0, 129569, 42369, 4350, 0, 65145, 9041, 43559, 0, + 0, 0, 41263, 0, 0, 0, 65825, 9577, 68199, 0, 0, 983122, 0, 6793, 0, + 70409, 0, 0, 0, 0, 64669, 0, 0, 0, 11200, 72725, 2995, 0, 0, 0, 7868, + 72720, 72020, 11386, 1009, 70405, 66871, 2333, 0, 0, 0, 0, 0, 70407, + 128121, 0, 0, 0, 0, 983657, 66949, 0, 74968, 0, 0, 110601, 0, 0, 41261, + 0, 0, 0, 0, 118989, 6736, 917883, 124132, 43010, 66952, 0, 69635, 73011, + 983716, 0, 0, 7293, 0, 0, 0, 0, 111332, 0, 128245, 69928, 127071, 0, 127072, 64445, 111336, 6635, 0, 0, 72707, 74936, 0, 0, 917876, 0, 93025, 66948, 0, 111329, 0, 129887, 128045, 65219, 11925, 0, 92434, 0, 0, 9845, 101317, 7546, 0, 0, 11230, 4985, 13288, 672, 8098, 0, 0, 0, 128126, 42655, 0, 0, 1577, 11772, 78327, 0, 66673, 0, 65911, 118705, 0, 0, 101303, 92180, 0, 0, 120566, 125140, 127177, 0, 0, 119593, 1539, 0, 74969, 42731, 0, 74970, 71066, 0, 3051, 0, 73783, 0, 0, 0, 0, 78777, 0, - 983160, 0, 0, 101310, 0, 0, 0, 0, 0, 0, 3505, 8707, 0, 6725, 128013, 0, - 92314, 0, 66391, 5479, 0, 6686, 0, 0, 983315, 42754, 0, 0, 0, 0, 0, 0, + 983161, 0, 0, 101310, 0, 0, 0, 0, 0, 0, 3505, 8707, 0, 6725, 128013, 0, + 92314, 0, 66391, 5479, 0, 6686, 0, 0, 983318, 42754, 0, 0, 0, 0, 0, 0, 128523, 0, 0, 4433, 41156, 0, 74971, 1443, 9339, 0, 92871, 10926, 0, - 43511, 0, 0, 983321, 0, 126086, 72236, 10021, 0, 101329, 0, 65914, 0, + 43511, 0, 0, 983324, 0, 126086, 72236, 10021, 0, 101329, 0, 65914, 0, 66749, 0, 6721, 217, 12466, 0, 0, 10443, 0, 68654, 0, 0, 0, 78334, 0, 41250, 0, 129532, 128375, 0, 0, 69232, 0, 41252, 66682, 0, 119637, 41249, 1366, 0, 0, 101326, 0, 0, 4397, 101324, 0, 66946, 9545, 101323, 0, 0, 0, @@ -25989,17 +26170,17 @@ static const unsigned int code_hash[] = { 128436, 68845, 0, 69724, 67412, 92952, 0, 43811, 0, 128924, 0, 11062, 128748, 0, 0, 0, 69276, 2901, 7865, 66945, 78354, 0, 78347, 0, 126123, 0, 66363, 0, 0, 0, 74967, 7414, 0, 0, 92691, 0, 128507, 885, 64772, 65180, - 0, 71267, 852, 0, 0, 0, 78614, 121174, 129092, 67809, 9609, 12156, 0, 0, - 43586, 11035, 10411, 0, 13268, 6710, 0, 0, 0, 43853, 77949, 4315, 0, - 111104, 0, 43639, 43343, 0, 0, 0, 73074, 0, 65812, 43431, 0, 0, 0, 0, 0, - 129890, 0, 0, 0, 0, 994, 125222, 127104, 127103, 73966, 66890, 0, 65291, - 70753, 0, 0, 0, 0, 66873, 4186, 92531, 127106, 127105, 6718, 7330, 4406, - 0, 8480, 7319, 64373, 128699, 4413, 0, 0, 3198, 0, 0, 92469, 111126, 0, - 128591, 128681, 0, 0, 0, 101321, 73023, 742, 0, 2893, 78738, 0, 0, 0, - 2553, 42294, 6756, 0, 73020, 8363, 0, 2993, 128381, 3916, 4301, 0, 1141, - 42407, 0, 0, 7572, 973, 0, 125077, 0, 2415, 0, 0, 9640, 42333, 0, 0, - 129546, 42486, 43381, 65390, 0, 69434, 1202, 0, 0, 0, 0, 68484, 0, 0, - 64542, 3260, 0, 65388, 43502, 69904, 0, 6738, 0, 0, 74193, 0, 0, 0, + 0, 71267, 852, 0, 0, 0, 78614, 121174, 129092, 67809, 9609, 12156, 0, + 122930, 43586, 11035, 10411, 0, 13268, 6710, 0, 0, 0, 43853, 77949, 4315, + 0, 111104, 0, 43639, 43343, 0, 0, 0, 73074, 0, 65812, 43431, 0, 0, 0, 0, + 0, 129890, 0, 0, 0, 0, 994, 125222, 127104, 127103, 73966, 66890, 0, + 65291, 70753, 0, 0, 0, 0, 66873, 4186, 92531, 127106, 127105, 6718, 7330, + 4406, 122946, 8480, 7319, 64373, 128699, 4413, 0, 0, 3198, 0, 0, 92469, + 111126, 0, 128591, 128681, 0, 0, 0, 101321, 73023, 742, 0, 2893, 78738, + 0, 0, 0, 2553, 42294, 6756, 0, 73020, 8363, 0, 2993, 128381, 3916, 4301, + 0, 1141, 42407, 0, 0, 7572, 973, 0, 125077, 0, 2415, 0, 0, 9640, 42333, + 0, 0, 129546, 42486, 43381, 65390, 0, 69434, 1202, 0, 0, 0, 0, 68484, 0, + 0, 64542, 3260, 0, 65388, 43502, 69904, 0, 6738, 0, 0, 74193, 0, 0, 0, 74641, 6312, 0, 74556, 12446, 0, 0, 128076, 8229, 1235, 0, 11472, 83064, 0, 0, 101366, 0, 0, 1740, 12872, 0, 985, 0, 0, 0, 12068, 983658, 0, 101363, 0, 0, 0, 13133, 65071, 110780, 12655, 12134, 0, 92934, 0, 66915, @@ -26010,21 +26191,21 @@ static const unsigned int code_hash[] = { 7525, 3346, 8339, 125004, 72705, 69462, 268, 0, 0, 5754, 94019, 0, 110684, 8336, 0, 0, 0, 8337, 8341, 0, 11388, 7522, 0, 0, 0, 11090, 6953, 125240, 0, 74973, 120708, 0, 0, 0, 0, 0, 110782, 0, 9038, 7887, 0, 0, - 42534, 64347, 0, 0, 67660, 120341, 0, 0, 0, 120878, 0, 0, 73999, 0, + 42534, 64347, 0, 0, 67660, 120341, 0, 122933, 0, 120878, 0, 0, 73999, 0, 64580, 0, 0, 64643, 0, 0, 74975, 0, 92227, 129052, 0, 83071, 83072, 83073, 119154, 0, 119153, 0, 0, 5349, 72440, 2160, 917554, 7411, 0, - 983221, 0, 0, 0, 42736, 70747, 5756, 983226, 92946, 0, 42764, 0, 0, + 983224, 0, 0, 0, 42736, 70747, 5756, 983229, 92946, 0, 42764, 0, 0, 119529, 5752, 120600, 0, 0, 0, 0, 0, 78893, 0, 0, 0, 125242, 0, 0, - 120331, 0, 0, 0, 67501, 0, 10080, 83056, 12647, 0, 0, 69252, 66882, 0, 0, - 0, 0, 0, 72005, 72845, 0, 0, 0, 0, 0, 74213, 0, 0, 0, 0, 0, 6302, 0, 0, - 0, 0, 1417, 983223, 0, 9452, 0, 74393, 0, 0, 110850, 0, 65391, 63789, - 69251, 78659, 78660, 41264, 78658, 6426, 42398, 9179, 78654, 64906, - 41255, 42036, 0, 41269, 0, 41267, 42436, 67759, 42323, 42034, 0, 0, - 42475, 42033, 0, 0, 68916, 43948, 0, 78673, 78674, 1659, 919, 42784, + 120331, 122957, 0, 0, 67501, 0, 10080, 83056, 12647, 0, 0, 69252, 66882, + 0, 0, 0, 0, 0, 72005, 72845, 0, 0, 0, 0, 0, 74213, 0, 0, 0, 0, 0, 6302, + 0, 0, 0, 0, 1417, 983226, 0, 9452, 0, 74393, 0, 0, 110850, 0, 65391, + 63789, 69251, 78659, 78660, 41264, 78658, 6426, 42398, 9179, 78654, + 64906, 41255, 42036, 0, 41269, 0, 41267, 42436, 67759, 42323, 42034, 0, + 0, 42475, 42033, 0, 0, 68916, 43948, 0, 78673, 78674, 1659, 919, 42784, 1671, 0, 6069, 9219, 0, 1661, 71489, 0, 92690, 10140, 9713, 78400, 119143, 125236, 0, 2306, 0, 0, 6068, 10612, 0, 0, 121314, 92561, 41462, - 0, 0, 0, 0, 0, 0, 0, 128204, 10635, 0, 983222, 0, 0, 0, 983232, 92251, 0, - 121029, 983224, 0, 8100, 0, 78669, 78670, 13301, 78667, 9667, 78665, 0, + 0, 0, 0, 0, 0, 0, 0, 128204, 10635, 0, 983225, 0, 0, 0, 983235, 92251, 0, + 121029, 983227, 0, 8100, 0, 78669, 78670, 13301, 78667, 9667, 78665, 0, 0, 11003, 9904, 0, 0, 0, 0, 0, 0, 78680, 78681, 78677, 78678, 0, 10313, 0, 0, 64320, 10265, 78686, 129404, 78684, 78685, 8945, 78683, 70750, 41, 0, 0, 0, 0, 8655, 0, 0, 71333, 0, 0, 0, 0, 2585, 0, 65254, 3126, 0, @@ -26034,7 +26215,7 @@ static const unsigned int code_hash[] = { 78688, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 119925, 0, 983637, 0, 0, 0, 71494, 83399, 127541, 83398, 8022, 78808, 0, 73794, 0, 0, 83414, 119916, 0, 0, 0, 0, 0, 0, 63799, 78427, 12063, 78425, 78424, 0, 0, 0, 75025, 0, - 297, 0, 0, 68326, 0, 78429, 78428, 7077, 2497, 128651, 0, 983111, 0, 0, + 297, 0, 0, 68326, 0, 78429, 78428, 7077, 2497, 128651, 0, 983112, 0, 0, 0, 4292, 0, 74815, 10512, 0, 74814, 119931, 0, 72841, 2503, 65070, 1762, 69794, 2495, 0, 71230, 94069, 77984, 0, 12654, 0, 1899, 0, 2507, 0, 8726, 0, 65594, 0, 71272, 8892, 0, 0, 0, 0, 0, 420, 0, 0, 125130, 10797, 74637, @@ -26069,12 +26250,12 @@ static const unsigned int code_hash[] = { 66604, 72025, 0, 0, 0, 66600, 523, 92642, 71100, 74436, 0, 0, 0, 8608, 83435, 72828, 128704, 0, 127402, 11307, 66707, 67301, 67300, 67299, 0, 67304, 67303, 0, 0, 0, 0, 122654, 5908, 0, 0, 6744, 67310, 1699, 67308, - 67307, 67314, 67313, 6306, 67311, 983207, 72150, 69862, 3766, 2389, + 67307, 67314, 67313, 6306, 67311, 983209, 72150, 69862, 3766, 2389, 67305, 74569, 6611, 65700, 0, 0, 0, 42386, 0, 0, 2599, 917972, 119131, - 119049, 65717, 0, 0, 119654, 0, 0, 0, 74203, 3760, 1718, 68160, 0, 3776, - 7335, 0, 0, 67324, 69861, 0, 69792, 0, 0, 3778, 0, 9462, 7824, 0, 78896, - 3768, 68142, 765, 72822, 3764, 0, 0, 113822, 129667, 12947, 0, 0, 0, - 118806, 73753, 0, 0, 0, 6829, 5225, 66901, 0, 0, 0, 0, 67319, 67318, + 119049, 65717, 0, 0, 119654, 0, 0, 73538, 74203, 3760, 1718, 68160, 0, + 3776, 7335, 0, 0, 67324, 69861, 0, 69792, 0, 0, 3778, 0, 9462, 7824, 0, + 78896, 3768, 68142, 765, 72822, 3764, 0, 0, 113822, 129667, 12947, 0, 0, + 0, 118806, 73753, 0, 0, 0, 6829, 5225, 66901, 0, 0, 0, 0, 67319, 67318, 3162, 67316, 67323, 67322, 67321, 67320, 0, 5353, 128190, 74179, 67315, 0, 1010, 6851, 0, 67326, 67325, 127870, 6952, 67329, 67328, 67327, 2590, 120036, 65552, 120034, 120039, 7183, 120037, 120038, 120027, 120028, @@ -26103,13 +26284,13 @@ static const unsigned int code_hash[] = { 3140, 0, 0, 68007, 0, 67258, 10909, 0, 1428, 0, 67254, 67253, 7699, 12393, 67257, 0, 67256, 67255, 0, 0, 69389, 0, 0, 0, 0, 0, 67153, 0, 0, 127383, 69376, 64554, 0, 3878, 0, 42352, 1752, 0, 129702, 42506, 0, - 10199, 0, 983465, 125231, 0, 0, 0, 720, 0, 0, 0, 68831, 0, 1464, 128339, + 10199, 0, 983468, 125231, 0, 0, 0, 720, 0, 0, 0, 68831, 0, 1464, 128339, 0, 7974, 0, 125017, 68082, 0, 0, 0, 0, 74787, 0, 78864, 92258, 0, 0, 78863, 0, 1302, 66288, 0, 0, 0, 67152, 0, 983611, 983618, 0, 0, 3995, 0, 65608, 3714, 0, 0, 67262, 67261, 67260, 67259, 43251, 67264, 67263, 0, 120557, 92346, 8672, 68006, 11964, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 92610, 0, 468, 0, 0, 0, 983472, 0, 0, 128544, 129397, 65907, 983163, 0, - 0, 0, 0, 0, 983470, 41743, 0, 0, 0, 74880, 0, 121001, 820, 41741, 0, + 92610, 0, 468, 0, 0, 0, 983475, 0, 0, 128544, 129397, 65907, 983164, 0, + 0, 0, 0, 0, 983473, 41743, 0, 0, 0, 74880, 0, 121001, 820, 41741, 0, 120667, 0, 64684, 126992, 128604, 126082, 69934, 65177, 6226, 353, 43645, 0, 119612, 120738, 67700, 0, 0, 0, 0, 42457, 120276, 0, 120277, 1884, 129637, 42418, 113678, 41157, 0, 42305, 120279, 0, 0, 41151, 0, 71430, 0, @@ -26124,7 +26305,7 @@ static const unsigned int code_hash[] = { 119083, 0, 71437, 119854, 69936, 0, 0, 3525, 6824, 0, 0, 119858, 128451, 0, 72239, 113738, 0, 71424, 0, 0, 0, 0, 0, 10727, 7212, 129071, 71957, 0, 0, 0, 67156, 808, 7207, 42387, 0, 0, 0, 0, 0, 0, 0, 0, 9225, 121149, 0, - 9145, 128060, 41018, 67841, 983158, 42300, 0, 3084, 983155, 125014, + 9145, 128060, 41018, 67841, 983159, 42300, 0, 3084, 983156, 125014, 41025, 6037, 0, 194885, 0, 10290, 0, 3083, 10322, 111017, 129030, 0, 41036, 0, 0, 43321, 65606, 0, 41032, 42388, 0, 64700, 0, 1445, 40961, 0, 0, 0, 40960, 0, 67727, 0, 2223, 64952, 10402, 0, 0, 0, 10603, 0, 118577, @@ -26141,15 +26322,15 @@ static const unsigned int code_hash[] = { 0, 13099, 71445, 70371, 0, 6435, 72154, 11362, 0, 0, 0, 0, 41420, 0, 3625, 74915, 41409, 71441, 0, 0, 0, 9672, 0, 0, 43317, 0, 0, 0, 41424, 917598, 0, 0, 0, 0, 41417, 1261, 0, 0, 12102, 119662, 41401, 0, 127538, - 129518, 0, 124943, 72765, 3275, 92472, 0, 0, 0, 118686, 0, 0, 0, 0, - 125129, 983140, 10598, 0, 128633, 6711, 0, 2920, 0, 0, 0, 0, 19928, 0, 0, + 129518, 0, 124943, 72765, 3275, 92472, 0, 0, 0, 118686, 0, 128946, 0, 0, + 125129, 983141, 10598, 0, 128633, 6711, 0, 2920, 0, 0, 0, 0, 19928, 0, 0, 3917, 0, 113756, 0, 0, 66588, 128078, 0, 0, 113721, 113758, 983081, 0, 0, 41184, 0, 232, 0, 0, 74170, 0, 0, 0, 0, 9094, 0, 0, 92585, 0, 1064, 0, 0, 10115, 0, 0, 0, 7862, 0, 13224, 0, 0, 66650, 0, 0, 72877, 1878, 0, 71434, 2911, 0, 41178, 5427, 0, 0, 0, 12617, 41174, 0, 67148, 67147, 0, 42413, 41167, 2406, 0, 0, 0, 0, 0, 9618, 128668, 0, 0, 0, 0, 41436, 9337, 126067, 0, 41456, 0, 119086, 11333, 0, 6703, 0, 125071, 1613, 0, 0, 0, - 983191, 0, 0, 74500, 41460, 78197, 0, 0, 194899, 67144, 65841, 0, 121109, + 983192, 0, 0, 74500, 41460, 78197, 0, 0, 194899, 67144, 65841, 0, 121109, 74064, 111146, 111144, 120375, 0, 111122, 0, 111121, 64687, 111120, 42592, 3871, 0, 128305, 9111, 111163, 0, 111156, 120366, 121462, 11150, 111154, 71488, 111179, 0, 111168, 0, 120362, 41587, 70391, 0, 74322, @@ -26157,8 +26338,8 @@ static const unsigned int code_hash[] = { 111127, 111140, 41595, 0, 0, 65801, 110587, 110586, 110585, 110584, 73712, 0, 41598, 3993, 121269, 1545, 40971, 121286, 72874, 0, 0, 0, 120767, 65286, 0, 0, 0, 0, 2201, 0, 0, 5402, 0, 0, 74462, 73457, 0, 0, - 78194, 64326, 40969, 0, 128110, 983703, 40968, 0, 121139, 0, 0, 0, 0, - 128513, 8020, 0, 41012, 0, 0, 65805, 41006, 0, 0, 74605, 0, 118942, + 78194, 64326, 40969, 0, 128110, 983703, 40968, 0, 121139, 0, 128891, 0, + 0, 128513, 8020, 0, 41012, 0, 0, 65805, 41006, 0, 0, 74605, 0, 118942, 43432, 0, 0, 92900, 0, 0, 68671, 120687, 0, 92958, 0, 0, 68332, 0, 40992, 0, 0, 0, 0, 0, 42235, 0, 1741, 42370, 0, 0, 0, 11413, 126583, 0, 0, 128769, 6470, 0, 74517, 0, 0, 120651, 40984, 0, 42742, 0, 12916, 6284, 0, @@ -26167,7 +26348,7 @@ static const unsigned int code_hash[] = { 2796, 0, 0, 9902, 0, 67988, 64785, 82995, 128822, 42631, 983040, 71890, 0, 74164, 41238, 10049, 11405, 0, 64368, 0, 120925, 0, 397, 12299, 42139, 0, 9590, 0, 0, 43661, 43819, 0, 6651, 3544, 0, 0, 9620, 0, 0, 0, 92229, - 1333, 7104, 0, 6425, 0, 0, 123561, 0, 0, 0, 11976, 8554, 13055, 0, + 1333, 7104, 0, 6425, 0, 0, 123561, 0, 0, 129725, 11976, 8554, 13055, 0, 110733, 0, 110731, 41218, 0, 0, 128673, 1883, 0, 0, 70443, 41225, 70788, 42419, 983707, 129450, 0, 127896, 0, 65809, 11837, 0, 129104, 7141, 0, 0, 0, 0, 0, 42363, 0, 0, 0, 0, 69949, 119157, 64732, 0, 0, 126983, 0, 0, @@ -26178,9 +26359,9 @@ static const unsigned int code_hash[] = { 11273, 120986, 43004, 0, 82988, 0, 961, 64307, 0, 0, 129752, 67711, 110615, 0, 1696, 0, 9762, 12105, 0, 110622, 110623, 3264, 110621, 110618, 43003, 110616, 110617, 0, 120359, 0, 128660, 0, 2322, 0, 70831, 11449, - 128187, 42868, 0, 0, 0, 0, 113746, 983235, 0, 129583, 66398, 0, 0, 0, 0, + 128187, 42868, 0, 0, 0, 0, 113746, 983238, 0, 129583, 66398, 0, 0, 0, 0, 0, 69494, 119224, 0, 0, 64421, 0, 113739, 0, 65823, 0, 11182, 0, 0, 0, - 7766, 55268, 0, 4598, 0, 65839, 0, 0, 0, 10851, 0, 6179, 92602, 6180, + 7766, 55268, 0, 4598, 0, 65839, 0, 0, 3315, 10851, 0, 6179, 92602, 6180, 129524, 11952, 0, 78648, 78651, 78646, 78647, 78644, 78645, 3801, 78643, 6176, 120580, 0, 0, 6177, 0, 78652, 78653, 6178, 0, 0, 0, 0, 2214, 8754, 0, 0, 2137, 0, 0, 0, 0, 66889, 0, 0, 0, 8974, 2308, 0, 74579, 0, 2318, @@ -26224,151 +26405,152 @@ static const unsigned int code_hash[] = { 0, 127321, 0, 127322, 0, 0, 0, 1050, 7549, 127319, 0, 9314, 0, 0, 0, 0, 0, 70434, 127314, 12527, 66504, 0, 0, 0, 0, 64333, 127312, 128547, 92594, 0, 0, 0, 129316, 0, 124960, 10360, 6746, 0, 0, 0, 0, 13085, 9233, 0, 0, - 0, 0, 0, 0, 92766, 0, 121114, 983944, 74212, 42819, 10910, 118627, 68044, - 9896, 0, 0, 120915, 0, 0, 7970, 0, 0, 0, 0, 113699, 9849, 0, 122910, 0, - 0, 10487, 69714, 0, 10103, 0, 4769, 0, 129967, 0, 2283, 0, 0, 74785, 0, - 0, 0, 110595, 110596, 0, 110594, 64565, 4773, 0, 0, 0, 4770, 0, 0, 0, - 65457, 69441, 0, 0, 127338, 983593, 4774, 0, 68497, 2259, 0, 0, 10215, 0, - 0, 0, 0, 0, 74776, 92160, 4768, 0, 0, 4099, 0, 110699, 110700, 110697, - 2225, 0, 0, 0, 0, 125217, 11255, 42814, 880, 0, 0, 0, 0, 0, 67756, 65246, - 0, 0, 129463, 7095, 0, 0, 0, 0, 0, 0, 2427, 0, 7093, 0, 11585, 0, 9962, - 0, 12223, 0, 78211, 1434, 42939, 0, 11573, 0, 0, 0, 121257, 0, 0, 0, 0, - 74437, 0, 113711, 917596, 0, 8740, 0, 3782, 64331, 0, 65167, 1014, 0, 0, - 0, 10835, 129987, 0, 0, 0, 0, 0, 118824, 7302, 0, 67707, 0, 1150, 10547, - 0, 0, 68427, 0, 0, 0, 0, 118788, 0, 0, 0, 42257, 8010, 0, 0, 0, 9643, 0, - 0, 12864, 0, 0, 0, 0, 0, 0, 0, 0, 1426, 68217, 0, 68447, 129971, 0, 0, 0, - 73701, 0, 0, 0, 65383, 0, 0, 0, 0, 0, 0, 43196, 43194, 92549, 10744, 0, - 990, 93772, 0, 0, 0, 0, 0, 66470, 0, 0, 0, 3945, 0, 0, 0, 130039, 0, - 127546, 127746, 1020, 73763, 92257, 118669, 0, 64748, 0, 0, 10205, 0, 0, - 10016, 0, 74051, 0, 43242, 125096, 2667, 0, 125037, 0, 9911, 0, 0, 10097, - 0, 0, 0, 118836, 0, 0, 0, 0, 68889, 10159, 113759, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 983340, 92291, 0, 127973, 72882, 0, 1041, 127182, 6354, 0, 65364, - 0, 0, 0, 72884, 0, 128477, 0, 65906, 127819, 72883, 0, 128470, 5375, - 72881, 0, 8215, 0, 10074, 0, 0, 0, 69899, 0, 0, 121426, 41382, 0, 0, - 5173, 65348, 527, 0, 0, 0, 128250, 0, 0, 0, 0, 0, 0, 42695, 0, 42250, 0, - 11187, 113695, 0, 1568, 66806, 0, 0, 113705, 0, 0, 129487, 0, 0, 128839, - 9069, 6144, 0, 0, 0, 0, 66783, 0, 74027, 118934, 66787, 74580, 0, 110790, - 6364, 0, 66794, 43508, 0, 92612, 0, 0, 0, 0, 128405, 66449, 0, 0, 0, 0, - 70714, 0, 70716, 0, 1044, 42411, 0, 0, 0, 0, 43239, 0, 0, 0, 118572, - 42450, 0, 0, 68479, 119237, 0, 0, 0, 0, 0, 69956, 11537, 0, 121206, 0, 0, - 0, 0, 1057, 566, 0, 0, 10907, 42274, 43464, 0, 118698, 0, 78472, 71207, - 42636, 0, 123603, 0, 0, 121171, 64659, 0, 127749, 0, 6357, 6362, 0, 0, - 2216, 9090, 0, 0, 0, 0, 68227, 0, 0, 0, 0, 1053, 12830, 0, 0, 0, 1052, - 1051, 459, 1060, 0, 66479, 0, 0, 0, 128061, 42490, 689, 6508, 4163, - 42298, 8639, 983335, 4246, 0, 43514, 42362, 0, 42337, 64596, 0, 0, 0, 0, - 0, 6359, 0, 43471, 0, 0, 0, 127274, 0, 6358, 6361, 1926, 6356, 0, 7898, - 0, 10935, 0, 127972, 121285, 0, 43685, 0, 0, 42910, 0, 8693, 0, 0, 44010, - 0, 120991, 121454, 0, 0, 0, 0, 129514, 0, 0, 0, 0, 73947, 0, 129361, - 92412, 0, 66477, 0, 0, 0, 43854, 71913, 0, 0, 0, 0, 72227, 65899, 92275, - 0, 0, 0, 68887, 0, 71057, 0, 0, 0, 0, 119183, 2923, 10853, 0, 0, 0, 0, - 72864, 0, 72773, 72772, 0, 120801, 65251, 122624, 68228, 0, 128548, 0, 0, - 5370, 70465, 2931, 73848, 0, 10188, 0, 118848, 0, 983942, 0, 0, 120584, - 72212, 0, 10844, 121016, 128195, 92424, 0, 0, 0, 286, 0, 1062, 0, 0, 0, - 7395, 0, 1070, 128993, 0, 6095, 0, 0, 0, 127796, 126465, 64497, 0, 0, 0, - 0, 70054, 8189, 78272, 0, 0, 0, 0, 0, 113783, 42102, 78276, 0, 0, 42101, - 0, 78402, 67427, 33, 67425, 67424, 10824, 67430, 67429, 67428, 427, - 64723, 0, 0, 0, 0, 1031, 0, 0, 42104, 0, 0, 2328, 0, 1071, 42899, 128486, - 0, 7673, 0, 0, 1047, 194837, 0, 42908, 0, 0, 10651, 0, 0, 0, 72433, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13216, 0, 69716, 0, 0, 0, 0, 0, 92411, - 69654, 0, 0, 129904, 2761, 129909, 0, 0, 0, 0, 8643, 0, 0, 94021, 2757, - 11067, 0, 74498, 8910, 10689, 0, 0, 0, 71173, 0, 9196, 71214, 0, 0, 0, 0, - 118911, 0, 0, 0, 0, 0, 0, 0, 0, 68130, 119616, 0, 0, 42477, 67482, 0, - 4495, 0, 0, 0, 0, 70080, 10992, 0, 0, 0, 0, 9318, 0, 6002, 0, 73808, 0, - 92601, 42249, 7639, 43995, 0, 0, 5454, 0, 0, 0, 0, 0, 0, 0, 121189, 0, - 119173, 0, 9704, 120686, 0, 78436, 78435, 11204, 0, 0, 1731, 0, 92937, 0, - 67990, 0, 0, 0, 126576, 127018, 71951, 55265, 0, 0, 0, 0, 127257, 73826, - 0, 3840, 0, 41432, 0, 0, 68430, 0, 43253, 128284, 0, 3371, 92936, 0, 0, - 1479, 69282, 0, 1109, 77997, 0, 129154, 0, 92782, 0, 0, 8868, 399, 67978, - 74842, 0, 0, 194839, 0, 551, 0, 10156, 0, 92572, 0, 2544, 65074, 0, 0, 0, - 0, 0, 0, 0, 128713, 0, 0, 74268, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68045, 0, - 0, 0, 3447, 0, 0, 121414, 2549, 110818, 0, 0, 43564, 8946, 0, 74411, - 66864, 0, 70480, 7980, 0, 113698, 0, 119653, 66489, 0, 64695, 128063, 0, - 0, 0, 0, 0, 0, 43452, 0, 92993, 0, 10919, 0, 67810, 0, 0, 0, 0, 6450, - 10055, 0, 0, 0, 0, 42720, 0, 9626, 0, 128055, 74447, 0, 125127, 92573, 0, - 0, 0, 119075, 0, 0, 66486, 0, 0, 0, 0, 0, 0, 75028, 983883, 74839, 0, 0, - 0, 0, 0, 55286, 0, 1055, 917628, 0, 0, 0, 70516, 12146, 118623, 73956, - 66488, 0, 0, 0, 0, 0, 0, 42518, 0, 0, 0, 7407, 74978, 0, 0, 0, 0, 0, 0, - 0, 10231, 0, 66626, 0, 0, 92951, 0, 65927, 0, 0, 69696, 0, 92389, 0, 0, - 0, 68095, 92950, 0, 10555, 0, 0, 9091, 10798, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 43222, 0, 74982, 0, 0, 120952, 0, 0, 2992, 7826, 74321, 110879, 125103, - 74981, 92628, 0, 129903, 128289, 128203, 4361, 129597, 1306, 78770, 1497, - 983628, 0, 0, 0, 8248, 0, 127253, 7973, 128706, 0, 0, 73122, 983949, 0, - 0, 2963, 120653, 0, 128554, 0, 0, 64258, 0, 0, 69677, 74983, 65103, 0, - 125008, 42625, 0, 72022, 0, 0, 64905, 0, 9512, 0, 119076, 6443, 983264, - 0, 9135, 0, 0, 123202, 0, 0, 983882, 93788, 0, 0, 0, 93767, 64256, 0, - 11669, 0, 0, 4524, 0, 129182, 128390, 0, 74266, 0, 0, 0, 70119, 78410, - 69809, 121031, 55219, 69815, 93765, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2986, 0, 93763, 3437, 0, 6203, 4247, 0, 11920, 8274, 68240, 129694, 1657, - 0, 121276, 0, 0, 2954, 43506, 42837, 0, 0, 71179, 0, 0, 0, 66476, 68450, - 0, 0, 0, 43362, 983134, 129596, 11705, 0, 0, 0, 127354, 0, 11710, 0, 0, - 0, 0, 74429, 0, 0, 1058, 129555, 0, 0, 5484, 1144, 0, 0, 0, 0, 0, 118972, - 0, 65322, 0, 6441, 0, 0, 2547, 66484, 43634, 0, 5871, 0, 0, 0, 0, 0, 0, - 71204, 0, 0, 1865, 0, 0, 69950, 0, 93021, 73713, 0, 71199, 65826, 2069, - 0, 119092, 43999, 2997, 0, 126588, 0, 65319, 0, 12316, 0, 0, 123630, - 8776, 0, 0, 66294, 13130, 0, 71191, 126625, 0, 10030, 11709, 12364, - 983853, 0, 11704, 0, 118641, 68672, 0, 0, 0, 0, 11706, 9710, 0, 82985, 0, - 413, 65623, 0, 0, 0, 74446, 0, 1042, 0, 128378, 12171, 119240, 0, 69384, - 4984, 0, 708, 11391, 0, 0, 0, 983930, 1308, 0, 3673, 810, 0, 120933, - 118567, 0, 0, 1917, 3000, 0, 0, 0, 65628, 66387, 74470, 0, 0, 0, 10027, - 0, 0, 0, 0, 128831, 983167, 2980, 755, 0, 0, 65622, 0, 121012, 7277, - 121022, 0, 0, 0, 0, 8730, 0, 0, 0, 7274, 119250, 0, 7275, 0, 935, 0, 0, - 377, 42325, 121103, 0, 101133, 101132, 101135, 101134, 0, 74911, 2417, - 101130, 0, 19912, 0, 0, 101128, 101127, 0, 101129, 101124, 7248, 101126, - 101125, 1781, 5496, 3627, 62, 1649, 0, 964, 0, 0, 0, 0, 92897, 0, 0, - 127364, 0, 43689, 127911, 66287, 78812, 64389, 66575, 0, 73041, 0, - 129687, 0, 7677, 2991, 3293, 0, 0, 0, 72201, 0, 11341, 127049, 0, 65625, - 9714, 11692, 0, 0, 120850, 6478, 10195, 43673, 65237, 6241, 0, 0, 0, - 6238, 0, 129889, 0, 4409, 0, 0, 67170, 0, 0, 0, 94047, 6237, 5461, 66851, - 9176, 92882, 121341, 65231, 0, 0, 121182, 110581, 0, 44018, 0, 64765, 0, - 0, 0, 5685, 0, 2461, 0, 7091, 0, 0, 0, 68163, 0, 73030, 0, 0, 73928, 0, - 0, 0, 0, 0, 0, 110582, 0, 0, 68506, 0, 0, 0, 0, 0, 2542, 0, 0, 0, 128176, - 5776, 0, 0, 0, 0, 0, 11987, 0, 0, 75036, 68744, 0, 0, 10039, 42828, 0, 0, - 0, 0, 0, 10721, 67664, 43433, 0, 0, 41875, 0, 41870, 266, 129066, 0, - 41873, 71271, 0, 0, 0, 0, 0, 0, 41871, 66186, 3734, 7734, 43683, 8750, - 110600, 66011, 92899, 0, 127937, 0, 0, 10572, 0, 42906, 0, 64349, 7287, - 0, 0, 0, 0, 11167, 69220, 0, 43429, 0, 1697, 0, 0, 68633, 7286, 0, - 128738, 10031, 78754, 0, 68645, 8620, 0, 42162, 0, 0, 7285, 0, 119577, 0, - 66842, 43677, 41583, 0, 65799, 129332, 0, 0, 0, 0, 110806, 0, 3609, 0, - 129448, 119074, 125116, 126254, 128108, 73948, 0, 0, 0, 0, 129189, 42732, - 92699, 74984, 68620, 11691, 74985, 0, 0, 0, 0, 0, 6348, 243, 74075, 0, 0, - 92309, 123585, 0, 0, 10648, 8538, 43687, 0, 118723, 0, 70515, 0, 118954, - 92886, 13307, 129573, 92891, 0, 120770, 983850, 0, 0, 0, 0, 214, 0, 0, 0, - 65893, 0, 120488, 128386, 0, 92893, 0, 2603, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 43, 0, 0, 1016, 0, 0, 0, 3885, 92, 65456, 64608, 0, 0, 0, 70656, - 113742, 0, 0, 0, 128128, 983857, 0, 0, 6791, 983861, 127960, 0, 0, 0, - 118976, 0, 7328, 92358, 0, 7995, 8759, 43421, 0, 68029, 92860, 0, 125272, - 0, 3197, 0, 0, 0, 983150, 0, 11595, 0, 0, 43435, 0, 0, 0, 0, 0, 70660, 0, - 741, 83291, 5494, 0, 70668, 1990, 11107, 4498, 0, 0, 70658, 0, 0, 2960, - 73779, 0, 8969, 101256, 43424, 0, 101257, 2950, 101251, 101254, 101253, - 370, 0, 101250, 101249, 0, 0, 0, 0, 0, 0, 0, 122900, 0, 0, 983253, 0, - 2964, 43663, 0, 6344, 0, 0, 10144, 0, 8252, 729, 66016, 78446, 0, 0, 0, - 78740, 43669, 9032, 0, 0, 0, 0, 0, 0, 0, 0, 74612, 3761, 101261, 101260, - 101263, 101262, 0, 0, 3850, 101258, 0, 128389, 0, 0, 0, 0, 8611, 0, 0, 0, - 43691, 125032, 0, 41802, 120540, 0, 0, 0, 0, 0, 3848, 101230, 113800, - 127536, 101227, 101226, 101229, 101228, 663, 0, 0, 0, 0, 0, 0, 0, 0, - 13221, 0, 0, 101244, 101243, 101246, 101245, 0, 65579, 12980, 68046, - 12143, 101069, 128067, 0, 43441, 41804, 101241, 101240, 101235, 101234, - 101237, 101236, 66329, 0, 72324, 101232, 0, 125038, 0, 129383, 101214, - 101213, 0, 101215, 101210, 0, 101212, 101211, 0, 1097, 129033, 0, 101209, - 101208, 93828, 0, 101205, 101204, 101207, 101206, 101201, 101200, 101203, - 101202, 0, 13110, 0, 983886, 68229, 1000, 0, 0, 101222, 1209, 101224, - 101223, 92354, 1073, 6321, 77878, 92818, 0, 68213, 0, 12167, 0, 0, 0, 0, - 73673, 121500, 0, 121501, 0, 6587, 0, 0, 0, 9231, 0, 2959, 101191, 0, - 101193, 101188, 101187, 101190, 101189, 101184, 0, 101186, 42941, 0, 0, - 68434, 0, 70742, 0, 0, 12290, 0, 0, 110801, 0, 77873, 8205, 110803, 5131, - 118542, 0, 0, 0, 0, 0, 1944, 78453, 0, 0, 119990, 119991, 12701, 78492, - 11308, 119995, 0, 113702, 66836, 119999, 74263, 92382, 120002, 120003, - 7075, 101196, 101199, 101198, 41817, 73934, 42275, 101194, 120012, - 120013, 120014, 42943, 6041, 0, 41899, 0, 8002, 0, 41902, 0, 0, 64332, 0, - 7813, 119117, 0, 41900, 120633, 101167, 7281, 78455, 7279, 12041, 93027, - 101165, 12673, 0, 129123, 9660, 0, 72984, 101161, 0, 0, 0, 92901, 2970, - 0, 101180, 101179, 77870, 101181, 0, 0, 101178, 0, 0, 0, 0, 0, 3486, - 101174, 69498, 101176, 101171, 101170, 101173, 101172, 0, 69920, 101169, - 66834, 0, 984006, 0, 68312, 101150, 65673, 1019, 78495, 4148, 0, 12289, - 101147, 4316, 0, 13119, 983932, 101145, 101144, 0, 0, 101141, 101140, - 43434, 41865, 101137, 9163, 8659, 9072, 5867, 13302, 7622, 7120, 0, 0, 0, - 0, 7400, 5416, 101160, 101159, 10817, 101153, 101156, 101155, 0, 68162, - 41855, 41867, 0, 983225, 0, 11536, 71988, 0, 7115, 0, 0, 5498, 7337, + 0, 0, 983474, 0, 92766, 0, 121114, 983944, 74212, 42819, 10910, 118627, + 68044, 9896, 0, 0, 120915, 0, 0, 7970, 0, 0, 0, 0, 113699, 9849, 0, + 122910, 0, 0, 10487, 69714, 0, 10103, 0, 4769, 0, 129967, 0, 2283, 0, 0, + 74785, 0, 0, 0, 110595, 110596, 0, 110594, 64565, 4773, 0, 0, 0, 4770, 0, + 0, 0, 65457, 69441, 0, 0, 127338, 983593, 4774, 0, 68497, 2259, 0, 0, + 10215, 0, 0, 0, 0, 0, 74776, 92160, 4768, 0, 0, 4099, 0, 110699, 110700, + 110697, 2225, 0, 0, 0, 41183, 125217, 11255, 42814, 880, 0, 0, 0, 0, 0, + 67756, 65246, 0, 0, 129463, 7095, 0, 0, 0, 0, 0, 0, 2427, 0, 7093, 0, + 11585, 0, 9962, 0, 12223, 0, 78211, 1434, 42939, 0, 11573, 0, 0, 0, + 121257, 0, 0, 0, 0, 74437, 0, 113711, 917596, 0, 8740, 0, 3782, 64331, 0, + 65167, 1014, 0, 0, 0, 10835, 129987, 0, 0, 0, 0, 0, 118824, 7302, 0, + 67707, 0, 1150, 10547, 0, 0, 68427, 0, 0, 0, 0, 118788, 0, 0, 0, 42257, + 8010, 0, 0, 0, 9643, 0, 0, 12864, 0, 0, 0, 0, 0, 0, 0, 0, 1426, 68217, 0, + 68447, 129971, 0, 0, 0, 73701, 0, 0, 0, 65383, 0, 0, 0, 0, 0, 0, 43196, + 43194, 92549, 10744, 0, 990, 93772, 0, 0, 0, 0, 0, 66470, 0, 0, 0, 3945, + 0, 0, 0, 130039, 0, 127546, 127746, 1020, 73763, 92257, 118669, 0, 64748, + 0, 0, 10205, 0, 0, 10016, 0, 74051, 0, 43242, 125096, 2667, 0, 125037, 0, + 9911, 0, 0, 10097, 0, 0, 0, 118836, 0, 0, 0, 0, 68889, 10159, 113759, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 983343, 92291, 0, 127973, 72882, 0, 1041, 127182, + 6354, 0, 65364, 0, 0, 0, 72884, 0, 128477, 0, 65906, 127819, 72883, 0, + 128470, 5375, 72881, 0, 8215, 0, 10074, 0, 0, 0, 69899, 0, 0, 121426, + 41382, 0, 0, 5173, 65348, 527, 0, 0, 0, 128250, 0, 0, 0, 0, 0, 0, 42695, + 0, 42250, 0, 11187, 113695, 0, 1568, 66806, 0, 0, 113705, 0, 0, 129487, + 0, 0, 128839, 9069, 6144, 0, 0, 0, 0, 66783, 0, 74027, 118934, 66787, + 74580, 0, 110790, 6364, 0, 66794, 43508, 0, 92612, 0, 0, 0, 0, 128405, + 66449, 0, 0, 0, 0, 70714, 0, 70716, 0, 1044, 42411, 0, 0, 0, 0, 43239, 0, + 0, 0, 118572, 42450, 0, 0, 68479, 119237, 0, 0, 0, 0, 0, 69956, 11537, 0, + 121206, 0, 0, 0, 0, 1057, 566, 0, 0, 10907, 42274, 43464, 0, 118698, 0, + 78472, 71207, 42636, 0, 123603, 0, 0, 121171, 64659, 0, 127749, 0, 6357, + 6362, 0, 0, 2216, 9090, 0, 0, 0, 0, 68227, 0, 0, 0, 0, 1053, 12830, 0, 0, + 0, 1052, 1051, 459, 1060, 0, 66479, 0, 0, 0, 128061, 42490, 689, 6508, + 4163, 42298, 8639, 983338, 4246, 0, 43514, 42362, 0, 42337, 64596, 0, 0, + 0, 0, 0, 6359, 0, 43471, 0, 0, 0, 127274, 0, 6358, 6361, 1926, 6356, 0, + 7898, 0, 10935, 0, 127972, 121285, 0, 43685, 0, 0, 42910, 0, 8693, 0, 0, + 44010, 0, 120991, 121454, 0, 0, 0, 0, 129514, 0, 0, 0, 0, 73947, 0, + 129361, 92412, 0, 66477, 0, 0, 0, 43854, 71913, 0, 0, 0, 0, 72227, 65899, + 92275, 0, 0, 0, 68887, 0, 71057, 0, 0, 0, 0, 119183, 2923, 10853, 0, 0, + 0, 0, 72864, 0, 72773, 72772, 0, 120801, 65251, 122624, 68228, 0, 128548, + 0, 0, 5370, 70465, 2931, 73848, 0, 10188, 0, 118848, 0, 983942, 0, 0, + 120584, 72212, 0, 10844, 121016, 128195, 92424, 0, 0, 0, 286, 0, 1062, 0, + 0, 124127, 7395, 0, 1070, 128993, 0, 6095, 0, 0, 0, 127796, 126465, + 64497, 0, 0, 0, 0, 70054, 8189, 78272, 0, 0, 0, 0, 0, 113783, 42102, + 78276, 0, 0, 42101, 0, 78402, 67427, 33, 67425, 67424, 10824, 67430, + 67429, 67428, 427, 64723, 0, 0, 0, 0, 1031, 0, 0, 42104, 0, 0, 2328, 0, + 1071, 42899, 128486, 0, 7673, 0, 0, 1047, 194837, 0, 42908, 0, 0, 10651, + 0, 0, 0, 72433, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13216, 0, 69716, 0, + 0, 0, 0, 0, 92411, 69654, 0, 0, 129904, 2761, 129909, 0, 0, 0, 0, 8643, + 0, 0, 94021, 2757, 11067, 0, 74498, 8910, 10689, 0, 0, 0, 71173, 0, 9196, + 71214, 0, 0, 0, 0, 118911, 0, 0, 0, 0, 0, 0, 0, 0, 68130, 119616, 0, 0, + 42477, 67482, 0, 4495, 0, 0, 0, 0, 70080, 10992, 0, 0, 0, 0, 9318, 0, + 6002, 0, 73808, 0, 92601, 42249, 7639, 43995, 0, 0, 5454, 0, 0, 0, 0, 0, + 0, 0, 121189, 0, 119173, 0, 9704, 120686, 0, 78436, 78435, 11204, 0, 0, + 1731, 0, 92937, 0, 67990, 0, 0, 0, 126576, 127018, 71951, 55265, 0, 0, 0, + 0, 127257, 73826, 0, 3840, 0, 41432, 0, 0, 68430, 0, 43253, 128284, 0, + 3371, 92936, 0, 0, 1479, 69282, 0, 1109, 77997, 0, 129154, 0, 92782, 0, + 0, 8868, 399, 67978, 74842, 0, 0, 194839, 73498, 551, 0, 10156, 0, 92572, + 0, 2544, 65074, 0, 0, 0, 0, 0, 0, 0, 128713, 0, 0, 74268, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 68045, 0, 0, 0, 3447, 0, 0, 121414, 2549, 110818, 0, 0, + 43564, 8946, 0, 74411, 66864, 0, 70480, 7980, 0, 113698, 0, 119653, + 66489, 0, 64695, 128063, 0, 0, 0, 0, 0, 0, 43452, 0, 92993, 0, 10919, 0, + 67810, 0, 0, 0, 0, 6450, 10055, 0, 0, 0, 0, 42720, 0, 9626, 0, 128055, + 74447, 0, 125127, 92573, 0, 0, 0, 119075, 0, 0, 66486, 0, 0, 0, 0, 0, 0, + 75028, 983883, 74839, 0, 0, 0, 0, 0, 55286, 0, 1055, 917628, 0, 0, 0, + 70516, 12146, 118623, 73956, 66488, 0, 0, 0, 0, 0, 0, 42518, 0, 0, 0, + 7407, 74978, 0, 0, 0, 0, 0, 0, 0, 10231, 0, 66626, 0, 0, 92951, 0, 65927, + 0, 0, 69696, 0, 92389, 0, 0, 0, 68095, 92950, 0, 10555, 0, 0, 9091, + 10798, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43222, 0, 74982, 0, 0, 120952, 0, 0, + 2992, 7826, 74321, 110879, 125103, 74981, 92628, 0, 129903, 128289, + 128203, 4361, 129597, 1306, 78770, 1497, 983628, 0, 0, 0, 8248, 0, + 127253, 7973, 128706, 0, 0, 73122, 983949, 0, 0, 2963, 120653, 0, 128554, + 0, 0, 64258, 0, 0, 69677, 74983, 65103, 0, 125008, 42625, 0, 72022, 0, 0, + 64905, 0, 9512, 0, 119076, 6443, 983267, 0, 9135, 0, 0, 123202, 0, 0, + 983882, 93788, 0, 0, 0, 93767, 64256, 0, 11669, 0, 0, 4524, 0, 129182, + 128390, 0, 74266, 0, 0, 0, 70119, 78410, 69809, 121031, 55219, 69815, + 93765, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2986, 0, 93763, 3437, 0, 6203, + 4247, 0, 11920, 8274, 68240, 129694, 1657, 0, 121276, 122951, 0, 2954, + 43506, 42837, 0, 0, 71179, 0, 0, 0, 66476, 68450, 0, 0, 0, 43362, 983135, + 129596, 11705, 0, 0, 0, 127354, 0, 11710, 0, 0, 0, 119507, 74429, 0, 0, + 1058, 129555, 0, 0, 5484, 1144, 0, 0, 0, 0, 0, 118972, 0, 65322, 0, 6441, + 0, 0, 2547, 66484, 43634, 0, 5871, 0, 0, 0, 0, 0, 0, 71204, 0, 0, 1865, + 0, 0, 69950, 0, 93021, 73713, 0, 71199, 65826, 2069, 0, 119092, 43999, + 2997, 0, 126588, 0, 65319, 0, 12316, 0, 0, 123630, 8776, 0, 0, 66294, + 13130, 0, 71191, 126625, 0, 10030, 11709, 12364, 983853, 0, 11704, 0, + 118641, 68672, 0, 0, 0, 0, 11706, 9710, 0, 82985, 0, 413, 65623, 0, 0, + 93980, 74446, 0, 1042, 0, 128378, 12171, 119240, 0, 69384, 4984, 0, 708, + 11391, 0, 0, 0, 983930, 1308, 0, 3673, 810, 0, 120933, 118567, 0, 0, + 1917, 3000, 0, 0, 0, 65628, 66387, 74470, 0, 0, 0, 10027, 0, 0, 0, 0, + 128831, 983168, 2980, 755, 0, 0, 65622, 0, 121012, 7277, 121022, 0, 0, 0, + 0, 8730, 0, 0, 0, 7274, 119250, 0, 7275, 0, 935, 0, 0, 377, 42325, + 121103, 0, 101133, 101132, 101135, 101134, 0, 74911, 2417, 101130, 0, + 19912, 0, 0, 101128, 101127, 0, 101129, 101124, 7248, 101126, 101125, + 1781, 5496, 3627, 62, 1649, 0, 964, 0, 0, 0, 0, 92897, 0, 0, 127364, 0, + 43689, 127911, 66287, 78812, 64389, 66575, 0, 73041, 0, 129687, 0, 7677, + 2991, 3293, 0, 0, 0, 72201, 0, 11341, 127049, 0, 65625, 9714, 11692, 0, + 0, 120850, 6478, 10195, 43673, 65237, 6241, 0, 0, 0, 6238, 0, 129889, 0, + 4409, 0, 0, 67170, 0, 0, 0, 94047, 6237, 5461, 66851, 9176, 92882, + 121341, 65231, 0, 0, 121182, 110581, 0, 44018, 0, 64765, 0, 0, 0, 5685, + 0, 2461, 0, 7091, 0, 0, 0, 68163, 0, 73030, 0, 0, 73928, 0, 0, 0, 0, 0, + 0, 110582, 0, 0, 68506, 0, 0, 0, 0, 0, 2542, 0, 0, 0, 128176, 5776, 0, 0, + 0, 0, 0, 11987, 0, 0, 75036, 68744, 0, 0, 10039, 42828, 0, 0, 0, 0, 0, + 10721, 67664, 43433, 0, 0, 41875, 0, 41870, 266, 129066, 0, 41873, 71271, + 0, 0, 0, 0, 0, 0, 41871, 66186, 3734, 7734, 43683, 8750, 110600, 66011, + 92899, 0, 127937, 0, 0, 10572, 0, 42906, 0, 64349, 7287, 0, 0, 0, 0, + 11167, 69220, 0, 43429, 0, 1697, 0, 0, 68633, 7286, 0, 128738, 10031, + 78754, 0, 68645, 8620, 0, 42162, 0, 0, 7285, 0, 119577, 0, 66842, 43677, + 41583, 0, 65799, 129332, 0, 0, 0, 0, 110806, 0, 3609, 0, 129448, 119074, + 125116, 126254, 128108, 73948, 0, 0, 0, 0, 129189, 42732, 92699, 74984, + 68620, 11691, 74985, 0, 0, 0, 0, 0, 6348, 243, 74075, 0, 0, 92309, + 123585, 0, 0, 10648, 8538, 43687, 0, 118723, 0, 70515, 0, 118954, 92886, + 13307, 129573, 92891, 0, 120770, 983850, 0, 0, 0, 0, 214, 0, 0, 0, 65893, + 0, 120488, 128386, 0, 92893, 0, 2603, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 43, 0, 0, 1016, 0, 0, 0, 3885, 92, 65456, 64608, 0, 0, 0, 70656, 113742, + 0, 0, 0, 128128, 983857, 0, 0, 6791, 983861, 127960, 0, 0, 0, 118976, 0, + 7328, 92358, 0, 7995, 8759, 43421, 0, 68029, 92860, 0, 125272, 0, 3197, + 0, 0, 0, 983151, 0, 11595, 0, 0, 43435, 0, 0, 0, 0, 0, 70660, 0, 741, + 83291, 5494, 0, 70668, 1990, 11107, 4498, 0, 0, 70658, 0, 0, 2960, 73779, + 0, 8969, 101256, 43424, 0, 101257, 2950, 101251, 101254, 101253, 370, 0, + 101250, 101249, 0, 0, 0, 122967, 0, 0, 0, 122900, 0, 0, 983256, 0, 2964, + 43663, 0, 6344, 0, 0, 10144, 0, 8252, 729, 66016, 78446, 0, 0, 0, 78740, + 43669, 9032, 0, 0, 0, 0, 0, 0, 0, 0, 74612, 3761, 101261, 101260, 101263, + 101262, 0, 0, 3850, 101258, 0, 128389, 0, 0, 0, 0, 8611, 0, 0, 0, 43691, + 125032, 0, 41802, 120540, 0, 0, 0, 0, 0, 3848, 101230, 113800, 127536, + 101227, 101226, 101229, 101228, 663, 0, 0, 0, 0, 0, 0, 0, 0, 13221, 0, 0, + 101244, 101243, 101246, 101245, 0, 65579, 12980, 68046, 12143, 101069, + 128067, 0, 43441, 41804, 101241, 101240, 101235, 101234, 101237, 101236, + 66329, 0, 72324, 101232, 0, 125038, 0, 129383, 101214, 101213, 0, 101215, + 101210, 0, 101212, 101211, 0, 1097, 129033, 0, 101209, 101208, 93828, 0, + 101205, 101204, 101207, 101206, 101201, 101200, 101203, 101202, 0, 13110, + 0, 983886, 68229, 1000, 0, 0, 101222, 1209, 101224, 101223, 92354, 1073, + 6321, 77878, 92818, 0, 68213, 0, 12167, 0, 0, 0, 0, 73673, 121500, 0, + 121501, 0, 6587, 0, 0, 0, 9231, 0, 2959, 101191, 0, 101193, 101188, + 101187, 101190, 101189, 101184, 0, 101186, 42941, 0, 0, 68434, 0, 70742, + 0, 0, 12290, 0, 0, 110801, 0, 77873, 8205, 110803, 5131, 118542, 0, 0, 0, + 0, 0, 1944, 78453, 0, 0, 119990, 119991, 12701, 78492, 11308, 119995, 0, + 113702, 66836, 119999, 74263, 92382, 120002, 120003, 7075, 101196, + 101199, 101198, 41817, 73934, 42275, 101194, 120012, 120013, 120014, + 42943, 6041, 0, 41899, 0, 8002, 0, 41902, 0, 0, 64332, 0, 7813, 119117, + 0, 41900, 120633, 101167, 7281, 78455, 7279, 12041, 93027, 101165, 12673, + 0, 129123, 9660, 0, 72984, 101161, 0, 0, 0, 92901, 2970, 0, 101180, + 101179, 77870, 101181, 0, 0, 101178, 0, 0, 0, 0, 0, 3486, 101174, 69498, + 101176, 101171, 101170, 101173, 101172, 0, 69920, 101169, 66834, 0, + 984006, 0, 68312, 101150, 65673, 1019, 78495, 4148, 0, 12289, 101147, + 4316, 0, 13119, 983932, 101145, 101144, 0, 0, 101141, 101140, 43434, + 41865, 101137, 9163, 8659, 9072, 5867, 13302, 7622, 7120, 0, 0, 0, 0, + 7400, 5416, 101160, 101159, 10817, 101153, 101156, 101155, 0, 68162, + 41855, 41867, 0, 983228, 0, 11536, 71988, 0, 7115, 0, 0, 5498, 7337, 41536, 0, 0, 92587, 7221, 8997, 0, 0, 0, 71949, 0, 0, 127814, 0, 0, 0, 0, 0, 295, 0, 0, 0, 0, 121292, 0, 43454, 63903, 63902, 63901, 122644, 3971, 0, 0, 2952, 0, 11038, 10901, 63900, 63899, 63898, 5198, 667, 43273, @@ -26393,7 +26575,7 @@ static const unsigned int code_hash[] = { 63932, 75050, 63929, 63928, 63927, 77934, 9806, 65566, 77933, 63922, 63921, 2086, 0, 63926, 2984, 5968, 63923, 0, 0, 129458, 11137, 13169, 5290, 2089, 0, 63827, 1088, 63825, 7268, 1084, 1085, 63829, 1083, 10131, - 7283, 0, 0, 0, 1092, 0, 7273, 983274, 44016, 43627, 0, 0, 0, 11809, 0, 0, + 7283, 0, 0, 0, 1092, 0, 7273, 983277, 44016, 43627, 0, 0, 0, 11809, 0, 0, 0, 2965, 7258, 8808, 0, 1089, 7278, 63937, 63936, 43405, 11106, 940, 5787, 10099, 63938, 101269, 63897, 101271, 2994, 101265, 101264, 101267, 101266, 77939, 77940, 77937, 77938, 74343, 93043, 72704, 660, 10127, 666, @@ -26419,36 +26601,36 @@ static const unsigned int code_hash[] = { 128100, 0, 42612, 43655, 0, 0, 0, 66468, 0, 0, 68623, 101423, 0, 0, 101420, 101419, 101422, 101421, 0, 1151, 101418, 73709, 127544, 0, 71106, 118722, 0, 0, 0, 0, 101437, 101436, 11527, 101438, 0, 0, 11538, 101434, - 0, 11020, 0, 66467, 101432, 8087, 71700, 101433, 9894, 101427, 101430, + 0, 11020, 0, 66467, 101432, 8087, 71700, 101433, 9894, 101427, 73485, 70824, 101424, 0, 78513, 8053, 0, 0, 0, 0, 101407, 101406, 0, 63845, - 101403, 101402, 78602, 101404, 13084, 42966, 8741, 0, 0, 101401, 0, - 64605, 83051, 101397, 473, 43415, 101394, 101393, 101396, 1087, 124966, - 71275, 101392, 0, 66439, 43218, 0, 0, 7237, 101414, 101417, 101416, - 71996, 101410, 92261, 101412, 121036, 4384, 74220, 101408, 2058, 917561, - 0, 129462, 0, 0, 0, 3857, 0, 0, 0, 64630, 0, 0, 74168, 127113, 125088, - 4421, 0, 0, 101381, 66400, 101383, 68431, 101377, 101376, 101379, 83053, - 0, 0, 69640, 127861, 0, 437, 0, 0, 0, 0, 65236, 13290, 119180, 4997, - 64306, 0, 0, 4999, 0, 0, 0, 4711, 120769, 0, 2739, 0, 92915, 74834, 0, - 127175, 0, 0, 0, 0, 0, 1779, 6600, 6601, 0, 5325, 101390, 101389, 13058, - 101391, 101386, 0, 92186, 101387, 71845, 10575, 43399, 0, 101385, 101384, - 1104, 0, 0, 10655, 0, 0, 69497, 0, 1082, 110878, 0, 67401, 0, 0, 0, 0, - 6783, 0, 0, 42867, 69655, 44021, 6458, 0, 0, 0, 0, 0, 0, 1273, 43407, 0, - 0, 0, 0, 1313, 6322, 41720, 128627, 66433, 0, 0, 0, 11216, 0, 0, 0, - 43437, 93833, 0, 0, 0, 5122, 0, 72728, 129520, 70161, 0, 0, 0, 0, 0, - 8303, 0, 128926, 0, 10003, 0, 0, 0, 1686, 0, 0, 42834, 3664, 0, 126088, - 121346, 0, 0, 4324, 126, 0, 0, 0, 0, 0, 65166, 0, 0, 0, 0, 43817, 0, - 43822, 0, 0, 65600, 13002, 0, 0, 0, 1103, 0, 119575, 129452, 0, 13078, 0, - 8116, 0, 2050, 0, 0, 1102, 0, 6555, 0, 0, 74003, 74794, 0, 0, 42591, - 127278, 0, 1111, 0, 75047, 4707, 0, 0, 0, 0, 43468, 4522, 8645, 0, 74857, - 0, 11352, 0, 92787, 0, 2293, 0, 0, 0, 128265, 71709, 0, 121194, 0, 93827, - 0, 0, 0, 128488, 0, 160, 2677, 0, 0, 120141, 0, 983646, 70790, 0, 42770, - 0, 71986, 0, 43821, 113769, 0, 0, 43816, 0, 0, 1079, 3867, 64817, 0, - 118549, 0, 0, 64768, 0, 0, 4005, 983211, 0, 10991, 0, 92957, 917578, - 92850, 917580, 917575, 128314, 917577, 917576, 917571, 78534, 917573, - 917572, 0, 0, 128359, 73458, 0, 3339, 11448, 1106, 917591, 917590, - 917593, 3340, 917587, 917586, 917589, 917588, 917583, 10605, 1309, 74996, - 120743, 92650, 0, 0, 9485, 0, 129781, 0, 0, 0, 125002, 92533, 128487, 0, - 129285, 4338, 11238, 0, 66825, 0, 0, 0, 0, 0, 0, 74128, 0, 0, 73680, 0, + 101403, 78912, 78602, 101404, 13084, 42966, 8741, 0, 0, 101401, 0, 64605, + 83051, 101397, 473, 43415, 101394, 101393, 101396, 1087, 124966, 71275, + 101392, 0, 66439, 43218, 0, 0, 7237, 101414, 101417, 101416, 71996, + 101410, 92261, 101412, 121036, 4384, 74220, 101408, 2058, 917561, 0, + 129462, 0, 0, 0, 3857, 0, 0, 0, 64630, 0, 0, 74168, 127113, 125088, 4421, + 0, 0, 101381, 66400, 101383, 68431, 101377, 101376, 101379, 83053, 0, 0, + 69640, 127861, 0, 437, 73483, 0, 0, 0, 65236, 13290, 119180, 4997, 64306, + 0, 0, 4999, 0, 0, 0, 4711, 120769, 0, 2739, 0, 92915, 74834, 0, 127175, + 0, 0, 0, 0, 0, 1779, 6600, 6601, 0, 5325, 101390, 101389, 13058, 101391, + 101386, 0, 92186, 101387, 71845, 10575, 43399, 0, 101385, 101384, 1104, + 0, 0, 10655, 0, 0, 69497, 0, 1082, 110878, 0, 67401, 0, 0, 0, 0, 6783, 0, + 0, 42867, 69655, 44021, 6458, 0, 0, 0, 0, 0, 0, 1273, 43407, 0, 0, 0, 0, + 1313, 6322, 41720, 128627, 66433, 0, 0, 0, 11216, 0, 0, 0, 43437, 93833, + 0, 0, 0, 5122, 0, 72728, 129520, 70161, 0, 0, 0, 0, 0, 8303, 0, 128926, + 0, 10003, 0, 0, 0, 1686, 0, 0, 42834, 3664, 0, 126088, 121346, 0, 0, + 4324, 126, 0, 0, 0, 0, 0, 65166, 0, 0, 0, 0, 43817, 0, 43822, 0, 0, + 65600, 13002, 0, 0, 0, 1103, 0, 119575, 129452, 0, 13078, 0, 8116, 0, + 2050, 0, 0, 1102, 0, 6555, 0, 0, 74003, 74794, 0, 0, 42591, 127278, 0, + 1111, 0, 75047, 4707, 0, 0, 0, 0, 43468, 4522, 8645, 0, 74857, 0, 11352, + 0, 92787, 0, 2293, 0, 0, 0, 128265, 71709, 0, 121194, 0, 93827, 0, 0, 0, + 128488, 0, 160, 2677, 0, 0, 120141, 0, 983646, 70790, 0, 42770, 0, 71986, + 0, 43821, 113769, 0, 0, 43816, 0, 0, 1079, 3867, 64817, 0, 118549, 0, 0, + 64768, 0, 0, 4005, 983213, 0, 10991, 0, 92957, 917578, 92850, 917580, + 917575, 128314, 917577, 917576, 917571, 78534, 917573, 917572, 0, 0, + 128359, 73458, 0, 3339, 11448, 1106, 917591, 917590, 129192, 3340, + 917587, 917586, 917589, 917588, 917583, 10605, 1309, 74996, 120743, + 92650, 0, 0, 9485, 0, 129781, 0, 0, 0, 125002, 92533, 128487, 0, 129285, + 4338, 11238, 0, 66825, 0, 0, 0, 0, 122939, 0, 74128, 0, 0, 73680, 0, 129438, 9553, 1590, 63777, 63776, 128677, 63782, 63781, 63780, 63779, 1583, 101525, 101528, 101527, 101522, 101521, 101524, 101523, 41522, 0, 92168, 983803, 66759, 0, 983580, 0, 0, 0, 0, 11394, 0, 983071, 0, 66823, @@ -26463,14 +26645,14 @@ static const unsigned int code_hash[] = { 121136, 0, 7950, 63772, 63771, 63770, 0, 63767, 63766, 2793, 63764, 0, 128501, 63769, 9530, 0, 92398, 0, 128642, 63763, 63762, 4595, 63760, 792, 92808, 0, 0, 8742, 0, 0, 0, 63744, 0, 0, 120815, 63748, 63747, 63746, - 63745, 5055, 0, 0, 1090, 0, 125268, 11665, 92830, 4558, 0, 72211, 0, 0, - 0, 11513, 983978, 6157, 63775, 63774, 63773, 0, 12170, 9067, 92843, 0, + 63745, 5055, 0, 0, 1090, 0, 125268, 11665, 92830, 4558, 78919, 72211, 0, + 0, 0, 11513, 983978, 6157, 63775, 63774, 63773, 0, 12170, 9067, 92843, 0, 10872, 129643, 43891, 43893, 43892, 129747, 43933, 0, 128231, 0, 0, 0, 0, - 0, 11063, 0, 43888, 0, 0, 128368, 43889, 0, 73807, 983104, 7386, 0, 0, + 0, 11063, 0, 43888, 0, 0, 128368, 43889, 0, 73807, 983105, 7386, 0, 0, 70295, 0, 0, 0, 71201, 128460, 0, 0, 0, 0, 69915, 2918, 66820, 65300, 0, 124898, 64726, 2790, 0, 3793, 42065, 127829, 0, 124901, 0, 0, 0, 0, 0, 92712, 0, 12923, 5270, 2166, 0, 0, 65813, 0, 128499, 0, 75012, 0, 10888, - 0, 93997, 94180, 3330, 129417, 0, 0, 0, 0, 0, 8220, 0, 0, 101581, 101580, + 0, 93997, 94180, 3330, 129417, 0, 0, 0, 0, 0, 8220, 0, 0, 101581, 72457, 1627, 101582, 0, 0, 5371, 101578, 0, 1826, 118794, 0, 0, 70023, 0, 0, 0, 71108, 0, 0, 124907, 0, 92207, 68125, 74898, 71353, 0, 72006, 71098, 70029, 0, 43116, 10190, 70019, 64346, 0, 101585, 66818, 101587, 70031, 0, @@ -26485,37 +26667,37 @@ static const unsigned int code_hash[] = { 5788, 127852, 0, 65491, 1831, 66020, 0, 984012, 92588, 0, 1343, 120784, 0, 0, 12018, 0, 0, 0, 0, 0, 4422, 4708, 3799, 101550, 119357, 0, 101547, 101546, 101549, 101548, 983095, 0, 1364, 0, 8038, 101545, 0, 12868, - 129560, 70425, 55223, 0, 64414, 110689, 0, 0, 0, 0, 0, 0, 118802, 118644, - 42855, 118856, 42866, 0, 0, 0, 0, 66438, 0, 983996, 119356, 92853, - 119354, 0, 123556, 0, 73013, 67685, 128062, 119350, 0, 11864, 10404, - 10340, 119352, 1556, 5274, 0, 127821, 10017, 9733, 0, 69488, 0, 41373, 0, - 0, 0, 0, 0, 349, 4863, 41371, 0, 0, 0, 0, 72295, 4398, 8543, 65618, - 128018, 0, 0, 0, 0, 12441, 0, 119348, 119347, 4318, 10452, 0, 8032, 0, - 119349, 119344, 0, 127844, 121156, 0, 110729, 119345, 8597, 0, 110727, - 9864, 0, 92796, 0, 92799, 0, 0, 0, 7722, 0, 0, 92797, 0, 0, 66590, 0, 0, - 129850, 0, 0, 0, 4965, 0, 917536, 0, 123196, 0, 0, 0, 10436, 119342, - 43147, 119340, 10356, 10420, 982, 2756, 0, 983997, 0, 0, 11162, 119338, - 0, 92914, 0, 65110, 0, 0, 983800, 78543, 0, 118793, 0, 128112, 119179, - 64476, 1694, 8216, 0, 0, 78539, 0, 65620, 0, 78537, 0, 0, 42158, 65621, - 69955, 120324, 120327, 120326, 120321, 120320, 120323, 120322, 12314, - 65616, 55221, 43825, 983553, 119337, 68060, 119335, 0, 71874, 123628, - 128537, 119332, 73089, 0, 41347, 0, 0, 8842, 0, 0, 4379, 127393, 12692, - 0, 0, 66353, 71875, 0, 0, 92907, 0, 0, 71877, 120303, 65619, 9872, 0, 0, - 1846, 120309, 120308, 119256, 71192, 120305, 120304, 120307, 6442, + 129560, 70425, 55223, 0, 64414, 110689, 122978, 0, 0, 0, 0, 0, 118802, + 118644, 42855, 118856, 42866, 73525, 0, 0, 0, 66438, 0, 983996, 119356, + 92853, 119354, 0, 123556, 0, 73013, 67685, 128062, 119350, 0, 11864, + 10404, 10340, 119352, 1556, 5274, 0, 127821, 10017, 9733, 0, 69488, 0, + 41373, 0, 0, 0, 0, 0, 349, 4863, 41371, 0, 0, 0, 0, 72295, 4398, 8543, + 65618, 128018, 129784, 0, 0, 0, 12441, 0, 119348, 119347, 4318, 10452, 0, + 8032, 0, 119349, 119344, 0, 127844, 121156, 0, 110729, 119345, 8597, 0, + 110727, 9864, 0, 92796, 0, 92799, 0, 0, 0, 7722, 0, 0, 92797, 0, 0, + 66590, 0, 0, 129850, 0, 0, 0, 4965, 0, 917536, 0, 123196, 0, 0, 0, 10436, + 119342, 43147, 119340, 10356, 10420, 982, 2756, 0, 983997, 0, 0, 11162, + 119338, 0, 92914, 0, 65110, 0, 0, 983800, 78543, 0, 118793, 0, 128112, + 119179, 64476, 1694, 8216, 0, 0, 78539, 0, 65620, 0, 78537, 0, 0, 42158, + 65621, 69955, 120324, 120327, 120326, 120321, 120320, 120323, 120322, + 12314, 65616, 55221, 43825, 983553, 119337, 68060, 119335, 0, 71874, + 123628, 128537, 119332, 73089, 0, 41347, 0, 0, 8842, 0, 0, 4379, 127393, + 12692, 0, 0, 66353, 71875, 0, 0, 92907, 0, 0, 71877, 120303, 65619, 9872, + 0, 0, 1846, 120309, 120308, 119256, 71192, 120305, 120304, 120307, 6442, 120317, 120316, 5379, 120318, 110717, 120312, 120315, 71876, 0, 65934, 66497, 0, 66986, 0, 0, 0, 0, 0, 0, 0, 0, 72002, 0, 6151, 12110, 0, - 129761, 0, 66959, 0, 0, 0, 0, 68335, 0, 0, 0, 0, 0, 0, 66041, 9676, - 10202, 0, 0, 0, 64575, 126637, 11965, 0, 124936, 0, 0, 0, 0, 0, 9698, + 129761, 0, 66959, 0, 0, 0, 0, 68335, 129655, 0, 0, 0, 0, 0, 66041, 9676, + 10202, 0, 0, 0, 64575, 78929, 11965, 0, 124936, 0, 0, 0, 0, 0, 9698, 66293, 0, 119651, 0, 0, 41921, 0, 0, 0, 119258, 0, 0, 0, 0, 0, 8012, 12355, 12353, 0, 0, 74107, 0, 0, 41925, 0, 41920, 65444, 0, 0, 41923, 12694, 0, 10112, 1294, 0, 120091, 0, 120092, 0, 0, 128474, 121400, 0, 0, 0, 8718, 0, 10284, 10268, 10380, 10316, 92593, 0, 71850, 0, 0, 92889, 0, 0, 0, 0, 9342, 12829, 0, 0, 101239, 127978, 0, 0, 69428, 0, 73767, 72347, 0, 7956, 598, 0, 72329, 93837, 0, 0, 128860, 0, 120041, 0, 0, 101242, 0, - 0, 847, 0, 9529, 0, 0, 0, 101247, 120035, 0, 0, 0, 67411, 0, 0, 0, + 0, 847, 0, 9529, 0, 0, 0, 101247, 120035, 0, 0, 0, 67411, 0, 0, 119497, 120040, 0, 128580, 0, 9624, 0, 0, 0, 65463, 1554, 0, 0, 0, 0, 71879, 0, 0, 0, 121161, 19963, 123566, 0, 72326, 92933, 71887, 10324, 10292, 65546, - 0, 68141, 8372, 0, 0, 83018, 120022, 10175, 10388, 42799, 0, 983180, + 0, 68141, 8372, 0, 0, 83018, 120022, 10175, 10388, 42799, 0, 983181, 10568, 0, 127400, 0, 0, 0, 983762, 0, 4366, 0, 983805, 0, 0, 42608, 0, 9884, 0, 0, 0, 0, 129180, 0, 128964, 0, 0, 1609, 0, 92773, 73448, 0, 11661, 0, 5818, 0, 0, 0, 9540, 0, 2554, 5158, 0, 2213, 0, 0, 78522, @@ -26524,7 +26706,7 @@ static const unsigned int code_hash[] = { 0, 0, 127061, 11005, 0, 66656, 127063, 0, 129936, 0, 127065, 43393, 0, 120643, 0, 0, 0, 0, 120798, 0, 0, 0, 0, 0, 0, 70435, 64356, 0, 0, 0, 383, 7154, 127815, 43495, 128809, 121448, 0, 0, 0, 11286, 0, 0, 0, 0, 0, 0, 0, - 42644, 129824, 129797, 129801, 8292, 0, 4980, 113726, 92674, 70130, 0, 0, + 42644, 73555, 129797, 129801, 8292, 0, 4980, 113726, 92674, 70130, 0, 0, 0, 0, 74912, 0, 10631, 83330, 100488, 68042, 0, 0, 7900, 101252, 0, 78779, 4198, 128555, 0, 0, 0, 123159, 0, 0, 12931, 0, 0, 0, 2088, 0, 72164, 129284, 0, 0, 69265, 0, 0, 0, 69694, 92838, 129794, 8593, 0, 0, 0, @@ -26539,70 +26721,71 @@ static const unsigned int code_hash[] = { 127558, 0, 7539, 0, 0, 0, 0, 0, 0, 0, 92898, 42567, 0, 0, 73886, 0, 129988, 12326, 0, 92848, 0, 0, 11355, 0, 0, 0, 0, 69437, 128222, 129803, 129811, 119537, 72327, 43005, 65342, 118902, 0, 0, 8644, 0, 0, 11186, - 74296, 41909, 0, 128682, 2791, 0, 1891, 0, 0, 41907, 66647, 0, 0, 41906, - 0, 0, 10773, 70206, 0, 0, 0, 6412, 2061, 8520, 13146, 0, 92836, 83275, - 65902, 2882, 0, 126232, 65852, 0, 92795, 0, 123627, 0, 0, 92794, 0, 0, - 128098, 0, 0, 0, 70871, 0, 92792, 0, 120087, 0, 0, 92793, 93971, 0, 3844, - 6842, 0, 0, 6612, 0, 0, 0, 0, 0, 783, 0, 0, 0, 983064, 68032, 119225, 0, - 0, 68378, 4556, 67839, 68480, 78663, 120069, 120074, 67657, 10510, 4382, - 74218, 42194, 0, 92806, 9177, 8902, 93958, 9839, 92804, 120700, 92807, 0, - 63999, 41904, 41917, 9788, 120973, 92805, 1862, 0, 0, 0, 41915, 0, 41919, - 63994, 41914, 7981, 0, 0, 0, 0, 0, 0, 0, 120834, 0, 0, 0, 6784, 78788, 0, - 0, 0, 0, 127534, 127484, 127476, 983874, 0, 983960, 64289, 65289, 0, - 129539, 129575, 64509, 0, 0, 126505, 11051, 0, 66635, 55259, 65885, 0, - 128310, 0, 0, 0, 0, 7500, 4506, 0, 0, 0, 0, 0, 126609, 4040, 128680, - 6167, 0, 42945, 0, 0, 0, 0, 7830, 43036, 0, 0, 63990, 19947, 63988, - 63987, 0, 63993, 10440, 9611, 2244, 71883, 0, 65260, 63986, 11446, 63984, - 92641, 3435, 119652, 0, 119108, 0, 128632, 0, 0, 12748, 0, 0, 92705, 0, - 78790, 0, 0, 63956, 42458, 63954, 63953, 63960, 63959, 63958, 11596, 0, - 11469, 69267, 42306, 2723, 0, 0, 70027, 0, 0, 0, 128093, 2880, 0, 0, 0, - 0, 128506, 3498, 4378, 0, 129825, 0, 65551, 118928, 0, 43387, 0, 64415, - 128898, 0, 0, 0, 0, 8161, 393, 12013, 0, 92216, 126479, 63965, 63964, - 63963, 42345, 0, 2174, 63967, 42498, 0, 2927, 0, 63961, 0, 0, 983946, 0, - 69699, 0, 42340, 0, 0, 0, 10730, 0, 69688, 0, 64187, 118535, 0, 12437, - 9813, 0, 42453, 1604, 9565, 0, 69701, 69235, 42414, 110724, 129196, 0, - 42301, 11372, 0, 917973, 0, 0, 63980, 63979, 63978, 0, 128207, 12017, - 63982, 63981, 73687, 0, 63977, 63976, 72794, 0, 0, 0, 63971, 4347, 4416, - 63968, 11009, 63974, 63973, 402, 69390, 13147, 0, 0, 64646, 13228, 0, 0, - 3515, 74252, 65261, 0, 0, 6259, 0, 0, 0, 0, 0, 0, 74813, 74425, 0, - 126998, 126114, 0, 0, 0, 129933, 983717, 0, 0, 74301, 0, 122633, 0, 0, - 74060, 69508, 0, 66235, 5145, 0, 0, 128394, 0, 73120, 0, 7402, 0, 0, 0, - 7952, 7832, 43382, 66616, 0, 983950, 120852, 0, 127875, 64866, 0, 0, 0, - 78784, 74248, 0, 0, 983196, 0, 0, 0, 78656, 42390, 0, 0, 983940, 0, 0, 0, - 92839, 9508, 0, 9544, 11520, 0, 0, 3377, 0, 129562, 0, 0, 0, 0, 66989, - 66280, 0, 127198, 0, 0, 0, 1955, 119565, 0, 0, 3076, 0, 42168, 73049, - 66304, 0, 0, 8917, 42403, 301, 0, 111175, 0, 0, 0, 0, 0, 0, 67819, 92987, - 0, 0, 0, 983204, 0, 69403, 3182, 0, 0, 0, 0, 0, 42169, 123162, 74244, 0, - 42329, 0, 66326, 6841, 0, 128913, 0, 1219, 3934, 71276, 11483, 74510, - 101122, 121110, 42442, 65470, 69565, 0, 64622, 7759, 42482, 485, 0, 0, - 42290, 0, 0, 42280, 0, 0, 11655, 64379, 127913, 42431, 10126, 42318, 0, - 119631, 74397, 42470, 0, 68315, 0, 110829, 74041, 0, 0, 0, 5411, 0, 0, 0, - 64205, 0, 64206, 42393, 64478, 1310, 125007, 0, 12052, 10643, 55271, - 72727, 0, 121045, 0, 0, 118852, 0, 0, 0, 0, 113826, 0, 0, 64385, 0, 0, 0, - 0, 0, 0, 93848, 92560, 2713, 0, 9650, 0, 0, 120602, 1406, 983650, 78174, - 92659, 0, 68223, 0, 0, 0, 0, 43475, 0, 65287, 1508, 127938, 8779, 10569, - 75034, 0, 0, 0, 0, 0, 0, 0, 70786, 0, 0, 128344, 9185, 0, 42932, 43403, - 0, 0, 0, 0, 0, 0, 0, 0, 12955, 0, 2888, 0, 0, 0, 0, 0, 0, 0, 2878, 0, 0, - 0, 0, 0, 0, 129028, 13203, 129722, 10429, 10365, 0, 0, 127165, 7503, 0, - 113676, 68381, 119658, 0, 8986, 0, 10632, 11934, 11452, 1332, 0, 0, 0, 0, - 73741, 1791, 8850, 9288, 0, 2892, 0, 43394, 555, 0, 0, 0, 0, 64172, - 118899, 0, 0, 0, 0, 8854, 0, 5858, 73101, 10582, 0, 0, 1361, 0, 0, 7905, - 0, 65256, 0, 41210, 0, 0, 71884, 0, 0, 0, 6828, 0, 92302, 0, 1342, 68440, - 0, 64161, 10903, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64381, 0, 0, 0, 42245, - 126467, 41972, 0, 0, 0, 9127, 0, 66619, 126489, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 11620, 0, 1149, 68316, 0, 0, 0, 0, 0, 92492, 0, 118784, 0, 0, 0, - 12838, 0, 118819, 0, 0, 0, 0, 41087, 0, 0, 0, 0, 12036, 0, 0, 0, 0, 0, - 64428, 12227, 0, 0, 0, 0, 125248, 120964, 0, 0, 0, 0, 0, 69566, 0, 0, 0, - 0, 0, 1743, 0, 0, 0, 65186, 122626, 0, 0, 0, 0, 64439, 0, 68062, 0, - 111259, 111258, 43866, 0, 111263, 3395, 9362, 111260, 0, 111257, 111256, - 111255, 0, 0, 41091, 3426, 1344, 111249, 111248, 126215, 4735, 11111, - 6119, 111251, 42699, 0, 0, 74818, 1423, 0, 0, 0, 0, 12039, 10559, 0, 0, - 0, 9472, 67734, 11929, 0, 0, 0, 0, 128826, 0, 11579, 0, 0, 128364, 0, - 92185, 0, 0, 1004, 92584, 0, 0, 0, 0, 0, 2556, 0, 0, 72790, 0, 0, 9686, - 0, 0, 0, 70109, 111102, 0, 10718, 13154, 111100, 9139, 0, 0, 0, 0, 0, 0, - 0, 0, 92831, 92810, 41708, 12860, 41703, 0, 42090, 5403, 10352, 73917, + 74296, 41909, 0, 128682, 2791, 127472, 1891, 0, 0, 41907, 66647, 0, 0, + 41906, 0, 129672, 10773, 70206, 0, 0, 0, 6412, 2061, 8520, 13146, 0, + 92836, 83275, 65902, 2882, 0, 126232, 65852, 0, 92795, 0, 123627, 0, 0, + 92794, 0, 0, 128098, 0, 0, 0, 70871, 0, 92792, 0, 120087, 0, 0, 92793, + 93971, 0, 3844, 6842, 0, 0, 6612, 0, 0, 0, 0, 0, 783, 0, 0, 0, 983064, + 68032, 119225, 0, 0, 68378, 4556, 67839, 68480, 78663, 120069, 120074, + 67657, 10510, 4382, 74218, 42194, 0, 92806, 9177, 8902, 93958, 9839, + 92804, 120700, 92807, 0, 63999, 41904, 41917, 9788, 120973, 92805, 1862, + 0, 0, 0, 41915, 0, 41919, 63994, 41914, 7981, 0, 0, 0, 0, 0, 0, 0, + 120834, 0, 0, 0, 6784, 78788, 0, 0, 0, 0, 127534, 127484, 127476, 983874, + 0, 983960, 64289, 65289, 0, 129539, 129575, 64509, 0, 0, 126505, 11051, + 0, 66635, 55259, 65885, 0, 128310, 0, 0, 0, 0, 7500, 4506, 0, 0, 0, 0, 0, + 126609, 4040, 128680, 6167, 0, 42945, 0, 0, 0, 0, 7830, 43036, 0, 0, + 63990, 19947, 63988, 63987, 0, 63993, 10440, 9611, 2244, 71883, 0, 65260, + 63986, 11446, 63984, 92641, 3435, 119652, 0, 119108, 0, 128632, 0, 0, + 12748, 0, 0, 92705, 0, 78790, 0, 0, 63956, 42458, 63954, 63953, 63960, + 63959, 63958, 11596, 0, 11469, 69267, 42306, 2723, 0, 0, 70027, 0, 0, 0, + 128093, 2880, 0, 0, 0, 0, 128506, 3498, 4378, 0, 129825, 0, 65551, + 118928, 0, 43387, 0, 64415, 128898, 0, 0, 0, 0, 8161, 393, 12013, 0, + 92216, 126479, 63965, 63964, 63963, 42345, 0, 2174, 63967, 42498, 0, + 2927, 0, 63961, 0, 0, 983946, 0, 69699, 0, 42340, 0, 0, 0, 10730, 0, + 69688, 0, 64187, 118535, 0, 12437, 9813, 0, 42453, 1604, 9565, 0, 69701, + 69235, 42414, 110724, 129196, 0, 42301, 11372, 0, 917973, 0, 0, 63980, + 63979, 63978, 0, 128207, 12017, 63982, 63981, 73687, 0, 63977, 63976, + 72794, 0, 0, 0, 63971, 4347, 4416, 63968, 11009, 63974, 63973, 402, + 69390, 13147, 0, 0, 64646, 13228, 0, 0, 3515, 74252, 65261, 0, 0, 6259, + 0, 0, 0, 0, 0, 0, 74813, 74425, 0, 126998, 126114, 0, 0, 0, 129933, + 983717, 0, 0, 74301, 0, 122633, 0, 0, 74060, 69508, 0, 66235, 5145, 0, 0, + 128394, 0, 73120, 0, 7402, 0, 0, 0, 7952, 7832, 43382, 66616, 0, 983950, + 120852, 0, 127875, 64866, 0, 0, 0, 78784, 74248, 0, 0, 983197, 0, 0, 0, + 78656, 42390, 0, 0, 983940, 0, 0, 0, 92839, 9508, 0, 9544, 11520, 0, + 110898, 3377, 0, 129562, 0, 0, 0, 0, 66989, 66280, 0, 127198, 0, 0, 0, + 1955, 119565, 0, 0, 3076, 0, 42168, 73049, 66304, 0, 0, 8917, 42403, 301, + 0, 111175, 0, 0, 0, 0, 0, 0, 67819, 92987, 0, 0, 0, 983206, 0, 69403, + 3182, 0, 0, 0, 0, 0, 42169, 123162, 74244, 0, 42329, 0, 66326, 6841, 0, + 128913, 0, 1219, 3934, 71276, 11483, 74510, 101122, 121110, 42442, 65470, + 69565, 0, 64622, 7759, 42482, 485, 0, 0, 42290, 0, 0, 42280, 0, 0, 11655, + 64379, 127913, 42431, 10126, 42318, 0, 119631, 74397, 42470, 0, 68315, 0, + 110829, 74041, 0, 0, 0, 5411, 0, 0, 0, 64205, 0, 64206, 42393, 64478, + 1310, 125007, 0, 12052, 10643, 55271, 72727, 0, 121045, 0, 0, 118852, 0, + 0, 0, 0, 113826, 0, 0, 64385, 0, 0, 0, 0, 0, 0, 93848, 92560, 2713, 0, + 9650, 0, 0, 120602, 1406, 983650, 78174, 92659, 0, 68223, 0, 0, 0, 0, + 43475, 0, 65287, 1508, 127938, 8779, 10569, 75034, 0, 0, 0, 0, 0, 0, 0, + 70786, 0, 0, 128344, 9185, 0, 42932, 43403, 0, 0, 0, 0, 0, 0, 0, 0, + 12955, 0, 2888, 0, 0, 0, 0, 0, 0, 0, 2878, 0, 0, 0, 0, 0, 0, 129028, + 13203, 129722, 10429, 10365, 0, 0, 127165, 7503, 0, 113676, 68381, + 119658, 0, 8986, 0, 10632, 11934, 11452, 1332, 0, 0, 0, 0, 73741, 1791, + 8850, 9288, 0, 2892, 0, 43394, 555, 0, 0, 0, 0, 64172, 118899, 0, 0, 0, + 0, 8854, 0, 5858, 73101, 10582, 0, 0, 1361, 0, 0, 7905, 0, 65256, 0, + 41210, 0, 0, 71884, 0, 0, 0, 6828, 0, 92302, 0, 1342, 68440, 0, 64161, + 10903, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64381, 0, 0, 0, 42245, 126467, + 41972, 0, 0, 0, 9127, 0, 66619, 126489, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11620, + 0, 1149, 68316, 0, 0, 0, 0, 0, 92492, 0, 118784, 0, 0, 0, 12838, 0, + 118819, 0, 0, 0, 0, 41087, 0, 0, 0, 0, 12036, 0, 124143, 0, 0, 0, 64428, + 12227, 0, 0, 0, 0, 125248, 120964, 0, 0, 0, 0, 0, 69566, 0, 0, 0, 0, 0, + 1743, 0, 0, 0, 65186, 122626, 0, 0, 0, 0, 64439, 0, 68062, 0, 111259, + 111258, 43866, 0, 111263, 3395, 9362, 111260, 0, 111257, 111256, 111255, + 0, 0, 41091, 3426, 1344, 111249, 111248, 126215, 4735, 11111, 6119, + 111251, 42699, 0, 0, 74818, 1423, 0, 0, 0, 0, 12039, 10559, 0, 0, 0, + 9472, 67734, 11929, 0, 0, 0, 0, 128826, 0, 11579, 0, 0, 128364, 0, 92185, + 0, 0, 1004, 92584, 0, 0, 0, 129755, 0, 2556, 0, 0, 72790, 0, 0, 9686, 0, + 0, 0, 70109, 111102, 0, 10718, 13154, 111100, 9139, 0, 0, 0, 0, 0, 0, 0, + 0, 92831, 92810, 41708, 12860, 41703, 0, 42090, 5403, 10352, 73917, 129144, 111096, 111088, 5140, 3753, 118785, 41704, 0, 43078, 127789, - 2207, 129360, 0, 983205, 92362, 0, 0, 2410, 92525, 0, 0, 0, 0, 0, 0, 0, + 2207, 129360, 0, 983207, 92362, 0, 0, 2410, 92525, 0, 0, 0, 0, 0, 0, 0, 0, 119253, 0, 126601, 0, 2066, 74199, 0, 43463, 10659, 119623, 68863, 0, 1336, 0, 0, 69463, 0, 0, 0, 0, 0, 0, 0, 0, 0, 126639, 0, 272, 0, 0, 0, 0, 983965, 128133, 0, 0, 124940, 0, 1190, 42146, 1335, 42177, 43867, 0, 0, @@ -26612,9 +26795,9 @@ static const unsigned int code_hash[] = { 111193, 111192, 43097, 11688, 0, 78797, 194, 111186, 111185, 111184, 0, 0, 0, 11226, 4519, 70337, 10898, 43072, 70205, 0, 0, 0, 73094, 10695, 0, 7540, 0, 110984, 41859, 6067, 92790, 110982, 0, 110981, 13311, 92788, - 41857, 92791, 8359, 121224, 12689, 0, 983131, 64577, 92789, 111203, + 41857, 92791, 8359, 121224, 12689, 0, 983132, 64577, 92789, 111203, 68183, 111209, 111208, 6064, 110988, 0, 110979, 74142, 0, 111201, 111200, - 6051, 123613, 0, 0, 983371, 0, 983651, 0, 0, 0, 110864, 10537, 110862, + 6051, 123613, 0, 0, 983374, 0, 983651, 0, 0, 0, 110864, 10537, 110862, 1276, 0, 6549, 6052, 0, 0, 0, 0, 118687, 0, 0, 0, 0, 1960, 0, 71232, 66297, 0, 129313, 0, 0, 1345, 111213, 111212, 111211, 8956, 43083, 0, 111215, 64682, 0, 6430, 69563, 111210, 119814, 0, 0, 0, 119817, 0, 492, @@ -26636,7 +26819,7 @@ static const unsigned int code_hash[] = { 121097, 2847, 111028, 10330, 0, 1251, 7777, 41852, 125059, 111327, 111032, 111325, 12646, 0, 10259, 0, 65821, 75046, 6018, 0, 111324, 111323, 111322, 68372, 111319, 111318, 71893, 2558, 0, 64584, 111321, - 111320, 0, 0, 0, 0, 111309, 111308, 111307, 69500, 73987, 74599, 71895, + 111320, 0, 0, 0, 0, 78911, 111308, 111307, 69500, 73987, 74599, 71895, 93012, 0, 128715, 0, 12867, 111296, 0, 0, 11044, 111300, 111299, 8904, 11824, 65857, 0, 128674, 129027, 4387, 0, 0, 124920, 0, 0, 0, 0, 11842, 0, 0, 0, 5136, 1968, 983041, 126627, 1337, 0, 0, 0, 0, 66506, 0, 0, 0, 0, @@ -26644,7 +26827,7 @@ static const unsigned int code_hash[] = { 71894, 4276, 111314, 3619, 41638, 69691, 0, 42322, 8853, 111043, 0, 490, 0, 13231, 68384, 72310, 65350, 0, 0, 0, 68245, 42435, 6154, 0, 65354, 0, 0, 42397, 334, 72732, 42416, 65359, 65273, 74634, 128227, 4442, 10364, 0, - 778, 41626, 42455, 7989, 0, 3227, 69907, 111053, 0, 2915, 11502, 983212, + 778, 41626, 42455, 7989, 0, 3227, 69907, 111053, 0, 2915, 11502, 983214, 41702, 10309, 0, 0, 0, 0, 0, 0, 0, 127268, 127258, 127267, 65215, 64410, 127260, 71175, 0, 0, 0, 0, 0, 0, 41700, 110651, 69266, 126488, 0, 0, 42495, 0, 0, 0, 10460, 43364, 0, 1356, 3728, 42713, 0, 0, 42342, 10914, @@ -26654,75 +26837,76 @@ static const unsigned int code_hash[] = { 69888, 65508, 0, 0, 121451, 0, 0, 0, 129780, 69272, 4732, 128283, 0, 0, 0, 121113, 2236, 126551, 0, 6048, 0, 0, 73965, 0, 0, 0, 0, 10151, 9681, 4475, 0, 41142, 2100, 0, 0, 6035, 0, 123599, 10296, 0, 0, 0, 0, 0, 0, 0, - 983309, 68488, 10392, 10328, 0, 43462, 0, 0, 0, 8979, 0, 0, 983306, 0, 0, + 983312, 68488, 10392, 10328, 0, 43462, 0, 0, 0, 8979, 0, 0, 983309, 0, 0, 0, 10977, 0, 10344, 0, 65299, 10408, 0, 0, 121187, 66505, 0, 0, 0, 0, 0, - 122648, 43074, 73799, 0, 0, 0, 0, 3446, 0, 129891, 128692, 0, 0, 119582, - 4474, 0, 43093, 6282, 0, 0, 127372, 0, 0, 0, 129881, 0, 0, 0, 0, 66910, - 67811, 92277, 0, 64948, 0, 74347, 0, 0, 0, 983981, 8194, 0, 121165, - 11010, 0, 8893, 0, 983988, 0, 0, 0, 983319, 7925, 0, 0, 113825, 0, 1352, - 11069, 7707, 0, 126486, 0, 0, 0, 0, 65605, 6040, 0, 10071, 0, 128156, - 43750, 0, 8899, 69873, 0, 0, 983313, 128208, 7820, 69615, 0, 0, 7746, - 1492, 0, 0, 0, 66866, 0, 11788, 65913, 0, 0, 43095, 0, 0, 92265, 2999, 0, - 120720, 0, 371, 120759, 6023, 0, 0, 11708, 0, 0, 6323, 0, 0, 0, 8938, - 6043, 65866, 0, 0, 0, 72419, 0, 129480, 2589, 74332, 1689, 7802, 0, 0, 0, - 0, 66704, 0, 129992, 0, 0, 128127, 6049, 0, 4027, 0, 0, 111334, 111333, - 1503, 111331, 0, 111337, 11951, 111335, 2387, 0, 0, 8289, 111330, 7326, - 66514, 65514, 0, 64865, 0, 9668, 0, 0, 0, 0, 93060, 6036, 92768, 4026, - 74089, 127091, 0, 0, 75044, 110821, 0, 110819, 0, 0, 0, 0, 6021, 0, - 128288, 0, 43155, 0, 110822, 0, 111343, 42691, 111341, 111340, 2246, 166, - 0, 0, 0, 10623, 408, 0, 111339, 13298, 0, 7426, 43694, 0, 0, 8811, 0, 0, - 129753, 0, 0, 74134, 983054, 0, 127811, 0, 0, 0, 6645, 646, 128813, 0, - 42129, 0, 120880, 0, 8697, 0, 120936, 0, 0, 0, 0, 5809, 1950, 0, 92432, - 68339, 0, 42136, 0, 0, 0, 0, 0, 0, 111354, 983984, 0, 0, 111349, 111348, - 43330, 111346, 111353, 111352, 41567, 111350, 0, 0, 0, 0, 111345, 111344, - 8285, 0, 4509, 0, 128361, 0, 77774, 129851, 0, 0, 41727, 0, 0, 0, 0, 0, - 71188, 0, 74512, 7027, 3886, 0, 74023, 92888, 0, 0, 126092, 94058, - 119855, 0, 121455, 11707, 119852, 0, 7939, 10342, 92460, 72747, 121408, - 917569, 0, 71198, 94077, 119847, 0, 0, 7201, 0, 123554, 120866, 983987, - 1540, 0, 0, 124923, 0, 119856, 41718, 71177, 0, 0, 128001, 118699, 0, - 119040, 0, 9619, 120840, 0, 0, 0, 0, 3560, 0, 6070, 129000, 0, 2922, - 6082, 70147, 65009, 983973, 0, 0, 0, 0, 0, 0, 3607, 65863, 0, 92487, - 42153, 121042, 0, 983862, 2032, 0, 0, 0, 0, 129985, 0, 43085, 6057, 0, 0, - 0, 0, 0, 0, 0, 0, 638, 6083, 126976, 0, 0, 2305, 0, 0, 118658, 6056, - 10878, 0, 0, 6085, 119351, 0, 3915, 0, 0, 0, 0, 0, 0, 4028, 1787, 0, - 43096, 0, 0, 1768, 0, 0, 0, 128125, 0, 0, 583, 129137, 0, 0, 66004, 0, 0, - 0, 92859, 0, 55267, 120810, 128995, 43075, 65049, 0, 74531, 0, 93009, - 70694, 0, 0, 129375, 9869, 128815, 1771, 0, 0, 0, 0, 0, 0, 119115, - 113708, 0, 0, 74101, 0, 0, 0, 0, 83367, 0, 0, 0, 12539, 123631, 0, 0, - 129846, 73862, 69842, 9897, 0, 100561, 0, 0, 0, 0, 0, 8931, 0, 1415, - 8866, 74552, 0, 128312, 0, 983566, 43106, 127275, 71089, 1580, 92278, - 68424, 0, 0, 7658, 3440, 78215, 1562, 0, 0, 129031, 0, 0, 0, 0, 0, 0, - 6028, 68900, 42892, 0, 111016, 0, 0, 0, 0, 0, 128269, 0, 66776, 42946, - 127276, 92849, 0, 0, 120510, 11599, 0, 11602, 11591, 11574, 11581, 11597, - 11598, 6253, 11571, 11584, 70273, 11569, 0, 8906, 0, 5755, 2636, 0, - 10815, 11619, 129094, 0, 7815, 11616, 11617, 70064, 11618, 11604, 7869, - 11612, 0, 42152, 0, 0, 0, 92586, 126247, 0, 92173, 0, 0, 6616, 0, 0, - 120875, 391, 0, 0, 0, 42296, 11588, 0, 0, 0, 68397, 0, 0, 42335, 983188, - 0, 0, 7538, 94040, 0, 42491, 0, 0, 128088, 4576, 0, 0, 43809, 4277, 0, - 3563, 0, 42338, 368, 0, 0, 42412, 0, 78209, 119144, 0, 43814, 983616, - 1849, 0, 9921, 42451, 4253, 0, 0, 118688, 42404, 64657, 73919, 3618, - 78338, 0, 0, 0, 0, 0, 929, 6827, 42035, 0, 0, 0, 67847, 0, 0, 0, 0, 0, 0, - 0, 0, 4578, 64513, 0, 0, 0, 71049, 68090, 127086, 43305, 0, 73462, - 118530, 0, 42048, 10166, 0, 127095, 113810, 983127, 0, 983991, 0, 0, - 42483, 0, 0, 0, 42291, 0, 71047, 0, 6641, 525, 66404, 0, 8763, 125091, 0, - 0, 0, 0, 0, 42504, 42581, 74280, 6915, 42310, 0, 8559, 0, 983994, 125100, - 0, 0, 11666, 8679, 0, 1576, 42423, 0, 0, 73840, 983092, 11374, 0, 10889, - 129076, 0, 42462, 0, 77982, 0, 2718, 42424, 0, 0, 127166, 0, 1179, 0, 0, - 0, 363, 11015, 72229, 0, 43857, 0, 66692, 0, 0, 0, 11041, 72018, 0, 0, 0, - 0, 125184, 0, 92520, 0, 9492, 66709, 9212, 12833, 0, 0, 1297, 0, 0, 0, 0, - 0, 0, 12924, 0, 0, 10090, 125249, 0, 42505, 0, 42507, 0, 42311, 92940, - 120919, 68401, 10759, 0, 0, 120924, 42351, 42919, 9398, 66292, 0, 9422, - 0, 0, 0, 0, 0, 129440, 92575, 1603, 0, 0, 0, 0, 0, 69703, 11250, 0, 0, - 10546, 0, 0, 11600, 0, 2797, 73821, 42427, 306, 714, 3058, 120154, 0, 0, - 0, 42395, 0, 11607, 0, 11198, 127512, 0, 72232, 129067, 0, 42433, 0, - 7603, 74063, 0, 42141, 0, 0, 0, 129085, 8244, 362, 125069, 0, 8037, 0, 0, - 0, 69510, 41606, 66696, 77912, 0, 2093, 0, 120676, 0, 41604, 0, 0, 0, 0, - 10523, 1446, 42320, 0, 0, 64773, 42472, 0, 0, 1722, 5581, 0, 64496, 0, 0, - 64914, 0, 42620, 128603, 124988, 0, 0, 10549, 130035, 71190, 0, 0, 0, 0, - 0, 71712, 0, 0, 0, 0, 0, 0, 0, 7684, 66338, 0, 1174, 0, 0, 983621, 0, 0, - 0, 42277, 0, 42456, 65667, 0, 0, 0, 0, 42417, 0, 0, 120812, 42304, 0, 0, - 0, 74443, 127894, 0, 8313, 0, 0, 1316, 66690, 0, 0, 0, 0, 0, 0, 66844, - 983715, 0, 0, 0, 65200, 3383, 0, 0, 70063, 0, 0, 0, 42420, 119185, 0, 0, + 122648, 43074, 73799, 0, 0, 122944, 0, 3446, 0, 129891, 128692, 0, 0, + 119582, 4474, 0, 43093, 6282, 0, 0, 127372, 0, 0, 0, 129881, 0, 0, 0, 0, + 66910, 67811, 92277, 0, 64948, 0, 74347, 0, 0, 0, 983981, 8194, 0, + 121165, 11010, 0, 8893, 0, 983988, 0, 0, 0, 983322, 7925, 0, 0, 113825, + 0, 1352, 11069, 7707, 0, 126486, 0, 0, 0, 0, 65605, 6040, 0, 10071, 0, + 128156, 43750, 0, 8899, 69873, 0, 0, 983316, 128208, 7820, 69615, 0, 0, + 7746, 1492, 0, 0, 0, 66866, 0, 11788, 65913, 0, 0, 43095, 0, 0, 92265, + 2999, 0, 120720, 0, 371, 120759, 6023, 0, 0, 11708, 0, 0, 6323, 0, 0, 0, + 8938, 6043, 65866, 0, 78910, 0, 72419, 0, 129480, 2589, 74332, 1689, + 7802, 0, 0, 0, 0, 66704, 0, 129992, 0, 0, 128127, 6049, 0, 4027, 0, 0, + 111334, 111333, 1503, 111331, 0, 111337, 11951, 111335, 2387, 0, 0, 8289, + 111330, 7326, 66514, 65514, 0, 64865, 0, 9668, 0, 0, 0, 0, 93060, 6036, + 92768, 4026, 74089, 127091, 0, 0, 75044, 110821, 0, 110819, 0, 0, 0, 0, + 6021, 0, 128288, 0, 43155, 0, 110822, 124152, 111343, 42691, 111341, + 111340, 2246, 166, 0, 0, 0, 10623, 408, 0, 111339, 13298, 0, 7426, 43694, + 0, 0, 8811, 0, 0, 129753, 0, 0, 74134, 983054, 0, 127811, 0, 0, 0, 6645, + 646, 128813, 0, 42129, 0, 120880, 0, 8697, 0, 120936, 122953, 0, 0, 0, + 5809, 1950, 0, 92432, 68339, 0, 42136, 0, 0, 0, 0, 0, 0, 111354, 983984, + 0, 0, 111349, 111348, 43330, 111346, 111353, 111352, 41567, 111350, 0, 0, + 0, 0, 111345, 111344, 8285, 0, 4509, 0, 128361, 0, 77774, 129851, 0, 0, + 41727, 0, 0, 0, 0, 0, 71188, 0, 74512, 7027, 3886, 0, 74023, 92888, 0, 0, + 126092, 94058, 119855, 0, 121455, 11707, 119852, 0, 7939, 10342, 92460, + 72747, 121408, 917569, 0, 71198, 94077, 119847, 0, 0, 7201, 0, 123554, + 120866, 983987, 1540, 0, 0, 124923, 0, 119856, 41718, 71177, 0, 0, + 128001, 118699, 0, 119040, 0, 9619, 120840, 0, 0, 0, 0, 3560, 0, 6070, + 129000, 0, 2922, 6082, 70147, 65009, 983973, 0, 0, 0, 0, 0, 0, 3607, + 65863, 0, 92487, 42153, 121042, 0, 983862, 2032, 0, 0, 0, 0, 129985, 0, + 43085, 6057, 0, 0, 0, 0, 0, 0, 0, 0, 638, 6083, 126976, 0, 0, 2305, 0, 0, + 118658, 6056, 10878, 0, 0, 6085, 119351, 0, 3915, 0, 0, 0, 0, 0, 0, 4028, + 1787, 0, 43096, 0, 0, 1768, 0, 0, 0, 128125, 0, 0, 583, 129137, 0, 0, + 66004, 0, 0, 0, 92859, 0, 55267, 120810, 128995, 43075, 65049, 0, 74531, + 0, 93009, 70694, 0, 0, 129375, 9869, 128815, 1771, 0, 0, 0, 0, 0, 0, + 119115, 113708, 0, 0, 74101, 0, 0, 0, 0, 83367, 0, 0, 0, 12539, 123631, + 0, 0, 129846, 73862, 69842, 9897, 0, 100561, 0, 124142, 0, 0, 0, 8931, 0, + 1415, 8866, 74552, 0, 128312, 0, 983566, 43106, 127275, 71089, 1580, + 92278, 68424, 0, 0, 7658, 3440, 78215, 1562, 0, 0, 129031, 0, 0, 0, 0, 0, + 0, 6028, 68900, 42892, 0, 111016, 0, 0, 0, 0, 0, 128269, 0, 66776, 42946, + 127276, 92849, 0, 72448, 120510, 11599, 0, 11602, 11591, 11574, 11581, + 11597, 11598, 6253, 11571, 11584, 70273, 11569, 122937, 8906, 0, 5755, + 2636, 0, 10815, 11619, 129094, 0, 7815, 11616, 11617, 70064, 11618, + 11604, 7869, 11612, 0, 42152, 0, 122941, 0, 92586, 126247, 0, 92173, 0, + 0, 6616, 0, 0, 120875, 391, 0, 0, 0, 42296, 11588, 0, 0, 0, 68397, 0, 0, + 42335, 983189, 0, 0, 7538, 94040, 0, 42491, 0, 0, 128088, 4576, 0, 0, + 43809, 4277, 0, 3563, 0, 42338, 368, 0, 0, 42412, 0, 78209, 119144, 0, + 43814, 983616, 1849, 0, 9921, 42451, 4253, 0, 0, 118688, 42404, 64657, + 73919, 3618, 78338, 0, 0, 0, 0, 0, 929, 6827, 42035, 0, 0, 0, 67847, 0, + 0, 0, 0, 0, 0, 0, 0, 4578, 64513, 0, 0, 0, 71049, 68090, 127086, 43305, + 0, 73462, 118530, 0, 42048, 10166, 0, 127095, 113810, 983128, 0, 983991, + 0, 0, 42483, 0, 0, 0, 42291, 0, 71047, 0, 6641, 525, 66404, 0, 8763, + 125091, 0, 0, 0, 0, 0, 42504, 42581, 74280, 6915, 42310, 0, 8559, 0, + 983994, 125100, 0, 0, 11666, 8679, 0, 1576, 42423, 0, 0, 73840, 983092, + 11374, 0, 10889, 129076, 0, 42462, 0, 77982, 0, 2718, 42424, 0, 0, + 127166, 0, 1179, 0, 0, 0, 363, 11015, 72229, 0, 43857, 0, 66692, 0, 0, 0, + 11041, 72018, 0, 0, 0, 0, 125184, 0, 92520, 0, 9492, 66709, 9212, 12833, + 0, 0, 1297, 122932, 0, 0, 0, 0, 0, 12924, 0, 0, 10090, 125249, 0, 42505, + 0, 42507, 0, 42311, 92940, 120919, 68401, 10759, 0, 0, 120924, 42351, + 42919, 9398, 66292, 0, 9422, 122942, 122943, 0, 0, 0, 129440, 92575, + 1603, 0, 0, 0, 0, 0, 69703, 11250, 0, 0, 10546, 0, 0, 11600, 0, 2797, + 73821, 42427, 306, 714, 3058, 120154, 0, 0, 0, 42395, 0, 11607, 0, 11198, + 127512, 0, 72232, 129067, 0, 42433, 0, 7603, 74063, 0, 42141, 0, 0, 0, + 129085, 8244, 362, 125069, 0, 8037, 0, 0, 0, 69510, 41606, 66696, 77912, + 0, 2093, 0, 120676, 122929, 41604, 0, 0, 0, 0, 10523, 1446, 42320, 0, + 120247, 64773, 42472, 0, 0, 1722, 5581, 0, 64496, 0, 0, 64914, 0, 42620, + 128603, 124988, 0, 0, 10549, 130035, 71190, 0, 0, 0, 0, 0, 71712, 0, 0, + 0, 0, 0, 0, 0, 7684, 66338, 0, 1174, 0, 0, 983621, 0, 0, 0, 42277, 0, + 42456, 65667, 0, 0, 0, 0, 42417, 0, 0, 120812, 42304, 0, 0, 0, 74443, + 127894, 0, 8313, 0, 0, 1316, 66690, 0, 0, 0, 0, 0, 0, 66844, 983715, 0, + 0, 0, 65200, 3383, 0, 0, 70063, 122947, 0, 0, 42420, 119185, 0, 0, 983917, 0, 121079, 72369, 0, 42343, 124980, 42706, 1751, 42496, 65742, 13166, 0, 0, 0, 0, 0, 42683, 12697, 0, 0, 0, 125047, 0, 42346, 0, 0, 3757, 0, 0, 121075, 65869, 0, 9247, 74976, 3193, 0, 0, 42459, 7596, 7921, @@ -26747,17 +26931,17 @@ static const unsigned int code_hash[] = { 10502, 74457, 0, 11221, 41554, 0, 0, 0, 41557, 11209, 0, 11070, 119221, 0, 0, 73858, 41555, 9514, 0, 66771, 64641, 92447, 0, 7520, 73888, 77955, 0, 0, 0, 0, 0, 64527, 0, 118707, 12723, 0, 68776, 0, 0, 0, 78835, 4055, - 78826, 77960, 65212, 0, 127353, 12319, 0, 0, 983216, 7964, 65427, 0, + 78826, 77960, 65212, 0, 127353, 12319, 0, 0, 983218, 7964, 65427, 0, 65424, 72217, 120966, 0, 65425, 74890, 128251, 0, 0, 0, 3448, 10827, 0, 9866, 74527, 0, 0, 8625, 69783, 92304, 10477, 0, 0, 0, 65423, 0, 0, 0, 0, 6152, 0, 0, 6629, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11046, 11490, 0, 4485, 71126, 0, 0, 0, 0, 0, 5869, 118533, 119633, 0, 7040, 3588, 0, 12825, 0, - 0, 128569, 0, 0, 0, 0, 0, 0, 0, 0, 128449, 64499, 65245, 127367, 1171, - 127368, 69717, 127365, 1805, 8772, 0, 127363, 9930, 65247, 0, 0, 2338, - 127362, 92695, 0, 0, 0, 69219, 0, 120104, 0, 120103, 72221, 120102, + 0, 128569, 0, 0, 0, 0, 0, 126637, 0, 0, 128449, 64499, 65245, 127367, + 1171, 127368, 69717, 127365, 1805, 8772, 0, 127363, 9930, 65247, 0, 0, + 2338, 127362, 92695, 0, 0, 0, 69219, 0, 120104, 0, 120103, 72221, 120102, 129924, 118814, 8734, 4212, 0, 0, 66701, 0, 65862, 0, 120095, 42903, 0, 0, 0, 126117, 426, 0, 120098, 8251, 0, 65436, 0, 2120, 43302, 1224, 0, - 65576, 0, 66876, 1764, 6074, 0, 12858, 0, 0, 65439, 6378, 74566, 0, + 65576, 0, 66876, 1764, 6074, 0, 12858, 0, 0, 65439, 6378, 74566, 128885, 41960, 0, 41644, 0, 2129, 0, 9222, 0, 0, 4259, 9092, 0, 41961, 0, 0, 66357, 42331, 64935, 0, 0, 1293, 0, 2132, 0, 983569, 0, 2454, 0, 3613, 128837, 71117, 0, 0, 69681, 10978, 10840, 0, 10668, 72826, 127197, 9118, @@ -26771,128 +26955,129 @@ static const unsigned int code_hash[] = { 2430, 41678, 71492, 0, 43785, 113716, 0, 121263, 0, 0, 1921, 0, 19927, 70390, 65406, 0, 43786, 4284, 128346, 72210, 43789, 12841, 9229, 0, 42285, 0, 0, 0, 0, 3521, 0, 118690, 8325, 0, 65403, 0, 1854, 0, 0, 0, 0, - 0, 0, 0, 0, 4344, 0, 65433, 6076, 0, 0, 74764, 12074, 0, 0, 0, 0, 12934, - 119555, 65432, 128877, 0, 6071, 65434, 0, 65435, 4053, 128623, 0, 0, 0, - 917934, 69823, 127463, 0, 121403, 127473, 8421, 127472, 0, 43705, 502, 0, - 65431, 0, 0, 0, 1303, 316, 7364, 0, 2136, 0, 120796, 64365, 43480, 92639, - 4860, 0, 127877, 0, 129728, 9583, 0, 5546, 0, 118565, 0, 0, 0, 5544, - 127475, 0, 70352, 5543, 128917, 72821, 12137, 5548, 0, 0, 10007, 0, - 127523, 6077, 0, 65452, 0, 119341, 11214, 65952, 0, 72226, 0, 0, 1319, + 0, 0, 0, 0, 4344, 0, 65433, 6076, 0, 0, 74764, 12074, 0, 0, 129148, 0, + 12934, 119555, 65432, 128877, 0, 6071, 65434, 0, 65435, 4053, 128623, 0, + 0, 0, 917934, 69823, 127463, 0, 121403, 127473, 8421, 73836, 0, 43705, + 502, 0, 65431, 0, 0, 0, 1303, 316, 7364, 0, 2136, 0, 120796, 64365, + 43480, 92639, 4860, 0, 127877, 0, 129728, 9583, 0, 5546, 0, 118565, 0, 0, + 0, 5544, 127475, 0, 70352, 5543, 128917, 72821, 12137, 5548, 0, 0, 10007, + 0, 127523, 6077, 0, 65452, 0, 119341, 11214, 65952, 0, 72226, 0, 0, 1319, 74210, 65410, 67399, 92606, 0, 0, 118660, 0, 66716, 83513, 4691, 128619, 9345, 621, 92872, 0, 122889, 65411, 0, 74575, 121246, 65408, 73899, 0, 9474, 2812, 119118, 65412, 3786, 65409, 8894, 83246, 119611, 7923, 3716, - 92798, 0, 0, 0, 7012, 0, 128439, 9566, 0, 94176, 0, 65012, 126242, 545, - 9575, 0, 10050, 12718, 0, 8859, 6820, 124915, 129941, 120740, 0, 0, 9119, - 2787, 0, 984000, 8507, 2012, 7985, 0, 0, 0, 0, 194634, 0, 410, 0, 0, - 120789, 120609, 0, 120378, 120379, 0, 0, 120374, 72742, 120376, 120377, - 120370, 120371, 120372, 120373, 3860, 120367, 72205, 74031, 111131, - 73685, 11748, 120365, 7941, 111134, 8749, 111132, 12698, 111129, 361, - 110793, 845, 67509, 0, 0, 4562, 72241, 2926, 0, 4569, 0, 110797, 43487, - 0, 0, 0, 74287, 122885, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6291, 0, 0, 0, 9734, - 0, 0, 0, 0, 127754, 7359, 83523, 43863, 0, 111150, 8769, 111148, 111147, - 111145, 4859, 111143, 111142, 0, 0, 0, 0, 12172, 111136, 0, 127899, - 111141, 64764, 4210, 111138, 0, 804, 0, 83520, 0, 70344, 0, 0, 67202, - 10091, 67200, 119257, 67206, 67205, 67204, 67203, 72302, 0, 0, 0, 128959, - 0, 1425, 92259, 119229, 11049, 0, 71480, 42649, 8482, 0, 0, 66715, 67209, - 11940, 67207, 664, 0, 0, 0, 70200, 127525, 0, 70194, 93061, 111155, - 68474, 111153, 6032, 67218, 67217, 7430, 194670, 70191, 0, 0, 0, 0, 0, - 41161, 0, 9765, 10993, 41162, 0, 70189, 1169, 111181, 0, 1905, 6034, - 41164, 64744, 43236, 0, 128800, 73110, 0, 0, 788, 0, 0, 111167, 111128, - 1663, 128976, 42901, 127237, 67211, 67210, 0, 0, 67215, 67214, 67213, - 67212, 111160, 111159, 111158, 111157, 0, 69492, 0, 111161, 43612, 0, 0, - 0, 10855, 67223, 9355, 67221, 65198, 120355, 0, 221, 0, 0, 0, 121141, - 7191, 118930, 72208, 125212, 0, 0, 0, 0, 67228, 67227, 43333, 67225, 0, - 0, 0, 67229, 0, 7245, 0, 74405, 69922, 72219, 111178, 3873, 8367, 111174, - 111173, 111172, 43649, 0, 111177, 111176, 0, 11164, 0, 74403, 111171, - 111170, 111169, 7682, 74404, 1462, 10235, 0, 0, 0, 0, 0, 111130, 0, 0, - 74402, 0, 92299, 0, 0, 74052, 0, 126127, 120549, 0, 64295, 0, 0, 0, 0, 0, - 120662, 0, 0, 67231, 67230, 10755, 55257, 11155, 128568, 983136, 9470, 0, - 127540, 0, 69680, 64384, 0, 128607, 0, 0, 0, 0, 73764, 8204, 0, 0, 0, 0, - 0, 8728, 0, 10904, 73446, 19936, 7833, 0, 0, 0, 0, 92546, 0, 0, 0, 8537, - 0, 0, 0, 121244, 0, 0, 2254, 128193, 0, 0, 0, 0, 3062, 0, 0, 0, 0, 0, - 41160, 41147, 41158, 0, 120777, 0, 41155, 111116, 111115, 111114, 0, - 121332, 111119, 111118, 111117, 129878, 0, 129091, 0, 0, 0, 64594, 2456, - 66867, 0, 0, 0, 0, 3721, 0, 0, 1230, 2678, 0, 3597, 917795, 0, 0, 92215, - 0, 67737, 8352, 0, 0, 0, 64515, 121378, 0, 129128, 67846, 0, 129767, - 92466, 0, 0, 71338, 0, 8660, 0, 0, 0, 0, 0, 4483, 0, 0, 0, 6080, 0, 0, - 1746, 1315, 0, 70201, 0, 13140, 74508, 0, 0, 4480, 0, 111113, 111112, 0, - 67979, 0, 6360, 10897, 111106, 605, 68302, 110737, 69875, 110735, 110736, - 66681, 0, 0, 0, 0, 0, 0, 0, 10877, 118868, 64885, 0, 0, 0, 0, 0, 0, 345, - 0, 0, 64606, 9917, 0, 0, 92196, 0, 1776, 8422, 43992, 0, 0, 0, 126543, - 43328, 0, 0, 1295, 0, 42869, 0, 0, 0, 0, 128772, 65123, 125210, 11293, - 11288, 0, 0, 65666, 0, 92369, 65420, 0, 0, 4252, 0, 0, 0, 706, 72800, 0, - 0, 129931, 65419, 92177, 0, 8419, 65421, 0, 66702, 0, 12670, 118608, 0, - 0, 0, 72825, 65422, 83008, 0, 0, 0, 0, 0, 0, 9736, 4184, 65418, 0, 0, - 74035, 0, 129955, 0, 0, 0, 0, 129447, 0, 7962, 12211, 9837, 83505, 0, 0, - 5719, 0, 129720, 119068, 73777, 1857, 0, 9927, 0, 983959, 0, 10037, 0, - 73695, 78322, 78319, 7818, 0, 0, 127769, 0, 0, 0, 65077, 0, 78325, 78326, - 78323, 43327, 43989, 0, 65828, 0, 0, 83499, 0, 68390, 0, 110687, 78336, - 78339, 9543, 78335, 78332, 78333, 0, 127964, 0, 129552, 983914, 0, 69448, - 0, 71429, 0, 0, 0, 11914, 69431, 0, 0, 0, 9949, 0, 0, 119215, 0, 12073, - 0, 0, 0, 0, 101218, 2260, 0, 0, 0, 0, 0, 0, 1939, 0, 0, 0, 69903, 0, 0, - 0, 0, 6643, 92477, 0, 0, 78330, 78331, 78328, 78329, 0, 92551, 0, 0, 0, - 0, 0, 72417, 0, 0, 0, 0, 78341, 78342, 120944, 78340, 129513, 127529, - 92350, 3784, 78350, 0, 78348, 78349, 78345, 43324, 78343, 78344, 2231, 0, - 0, 0, 42467, 0, 0, 42894, 78363, 13281, 78360, 78361, 78356, 78358, - 78353, 64899, 0, 41149, 0, 43162, 68096, 41150, 0, 10571, 67162, 67161, - 67160, 67159, 6947, 41152, 887, 9249, 6565, 64806, 74366, 0, 67158, - 67157, 0, 10831, 67175, 67174, 120232, 65827, 43325, 67178, 10168, 67176, - 0, 0, 9190, 128497, 9666, 41997, 0, 0, 0, 0, 0, 0, 129411, 0, 78508, 0, - 78351, 78352, 0, 75063, 72839, 983749, 0, 126604, 0, 0, 0, 983419, 0, - 2270, 0, 129957, 0, 78365, 0, 67189, 72818, 0, 0, 0, 0, 0, 0, 0, 72833, - 101119, 78366, 78367, 0, 0, 0, 0, 10137, 6121, 10995, 0, 71050, 8119, 0, - 71052, 0, 0, 0, 0, 0, 0, 0, 1394, 0, 0, 128960, 0, 67184, 2998, 67182, - 67181, 67188, 67187, 67186, 67185, 0, 101185, 0, 0, 67180, 42003, 0, 0, - 67193, 67192, 67191, 67190, 67197, 67196, 67195, 67194, 0, 72770, 43315, - 71051, 0, 1593, 0, 125120, 619, 4635, 0, 72875, 0, 128859, 118657, 0, 0, - 0, 67199, 67198, 0, 42790, 42006, 0, 0, 0, 128998, 10757, 9347, 127767, - 0, 0, 74227, 78904, 0, 74116, 128423, 121073, 120860, 0, 92427, 0, 0, 0, - 0, 64590, 0, 4371, 0, 0, 92478, 0, 0, 73977, 0, 0, 127847, 0, 120862, 0, - 64550, 73745, 70451, 0, 121013, 0, 0, 0, 129286, 0, 0, 0, 0, 9131, - 118648, 125214, 983220, 0, 0, 64260, 0, 12606, 0, 0, 0, 0, 562, 983614, - 0, 129648, 66455, 127533, 3219, 0, 0, 0, 1037, 0, 64491, 0, 983695, - 78572, 78580, 4568, 549, 0, 0, 0, 0, 0, 128095, 70851, 2205, 0, 0, 0, 0, - 129716, 0, 10825, 8079, 118962, 0, 0, 0, 128855, 0, 13071, 0, 0, 41049, - 42840, 43614, 129341, 74881, 74596, 127191, 5212, 0, 66402, 119191, 0, - 9747, 0, 0, 129778, 984008, 41047, 1668, 0, 0, 0, 1187, 0, 74416, 0, 0, - 0, 0, 3240, 128518, 9213, 0, 0, 0, 127174, 69822, 0, 0, 0, 0, 1623, 0, 0, - 0, 0, 0, 0, 11272, 0, 73914, 65048, 1909, 42172, 0, 0, 10736, 11580, - 72228, 7615, 0, 0, 4237, 66576, 0, 65815, 68083, 0, 0, 0, 3489, 0, 0, 0, - 0, 0, 0, 127146, 3796, 6800, 0, 65582, 0, 129521, 0, 0, 68036, 0, 0, - 64857, 121213, 126493, 0, 66308, 0, 0, 64634, 127817, 0, 0, 0, 0, 3246, - 0, 43972, 128643, 0, 0, 0, 0, 120751, 0, 0, 0, 0, 1496, 42827, 0, 942, - 2378, 119213, 0, 0, 0, 0, 9510, 1232, 8139, 0, 0, 0, 11409, 0, 6382, 0, - 66319, 121237, 0, 0, 0, 127887, 2374, 0, 8475, 120844, 66313, 0, 0, - 64879, 119298, 0, 0, 70869, 0, 0, 129025, 0, 7705, 11942, 0, 0, 3309, 0, - 0, 0, 83345, 983866, 0, 0, 1280, 6998, 128104, 0, 0, 0, 129945, 0, 0, 0, - 0, 0, 0, 0, 74239, 983073, 0, 0, 0, 6078, 121354, 0, 1475, 0, 9938, 6084, - 0, 983995, 0, 118571, 0, 3256, 0, 43973, 0, 0, 0, 8727, 0, 0, 0, 110831, - 110832, 10562, 110830, 0, 0, 0, 3248, 0, 0, 9015, 0, 0, 3635, 64337, 0, - 0, 43852, 7195, 0, 2007, 64431, 0, 0, 0, 0, 0, 0, 0, 65613, 77909, 0, 0, - 0, 0, 119218, 7984, 11670, 74434, 127770, 4176, 69248, 2034, 69442, - 11154, 65891, 0, 0, 318, 2038, 0, 0, 0, 3649, 13149, 42145, 42798, 3634, - 0, 0, 128483, 0, 0, 0, 11402, 120954, 94032, 74238, 0, 43313, 0, 0, 7938, - 0, 1761, 0, 65379, 68386, 128185, 1159, 71183, 0, 0, 0, 66687, 120851, 0, - 41680, 0, 0, 0, 1514, 11668, 67891, 9313, 0, 128490, 67877, 0, 41681, 0, - 0, 12848, 69982, 67873, 0, 74278, 0, 0, 12649, 0, 0, 1194, 3242, 9761, - 9555, 8598, 0, 120524, 0, 1551, 65447, 129414, 126211, 0, 0, 0, 67875, 0, - 3495, 66648, 125079, 0, 73024, 983229, 0, 126130, 10641, 0, 0, 0, 77845, - 0, 0, 0, 0, 0, 11131, 0, 0, 0, 0, 0, 42685, 72017, 193, 0, 0, 0, 42667, - 0, 0, 92318, 71958, 0, 1362, 9558, 0, 0, 0, 7351, 73789, 0, 0, 4426, 0, - 0, 0, 0, 7276, 42163, 5220, 0, 0, 67822, 0, 0, 0, 0, 41692, 0, 72283, 0, - 0, 3223, 65492, 0, 0, 4549, 983706, 0, 0, 101162, 10807, 0, 0, 0, 42182, - 8688, 12866, 0, 3294, 0, 0, 128101, 0, 64514, 0, 43329, 129989, 0, 0, 0, - 119061, 0, 43422, 0, 0, 128618, 0, 42729, 0, 3215, 120982, 68880, 917564, - 0, 0, 0, 65682, 0, 0, 65924, 0, 983823, 0, 1501, 0, 118807, 0, 0, 9607, - 0, 65794, 72243, 983046, 10989, 0, 74399, 0, 0, 7152, 0, 0, 129530, 7483, - 125083, 0, 8104, 70128, 7474, 0, 5189, 0, 0, 0, 8141, 0, 42537, 69612, 0, - 0, 0, 0, 0, 127307, 42934, 0, 0, 0, 0, 0, 0, 64517, 0, 0, 1650, 0, 0, - 128502, 7901, 3238, 0, 65556, 0, 0, 65158, 43416, 74959, 0, 7527, 0, - 43319, 0, 0, 45, 0, 0, 0, 0, 0, 7347, 0, 0, 0, 13129, 0, 9084, 0, 8737, - 0, 0, 0, 66808, 9639, 7912, 2620, 0, 3564, 0, 0, 0, 0, 75049, 0, 2853, 0, - 0, 0, 0, 0, 2850, 8084, 0, 0, 71446, 92284, 43122, 0, 0, 0, 126503, - 72214, 0, 74767, 0, 7331, 110646, 0, 8245, 0, 3158, 92396, 3983, 0, 923, - 0, 69397, 292, 0, 126548, 0, 3221, 1763, 0, 0, 0, 0, 7253, 194636, 68391, + 92798, 0, 0, 0, 7012, 124122, 128439, 9566, 0, 94176, 0, 65012, 126242, + 545, 9575, 0, 10050, 12718, 0, 8859, 6820, 124915, 129941, 120740, 0, 0, + 9119, 2787, 0, 984000, 8507, 2012, 7985, 0, 0, 0, 0, 194634, 0, 410, 0, + 0, 120789, 120609, 0, 120378, 120379, 0, 0, 120374, 72742, 120376, + 120377, 120370, 120371, 120372, 120373, 3860, 120367, 72205, 74031, + 111131, 73685, 11748, 120365, 7941, 111134, 8749, 111132, 12698, 111129, + 361, 110793, 845, 67509, 0, 0, 4562, 72241, 2926, 0, 4569, 0, 110797, + 43487, 0, 0, 0, 74287, 122885, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6291, 0, 0, 0, + 9734, 0, 0, 0, 0, 127754, 7359, 83523, 43863, 0, 111150, 8769, 111148, + 111147, 111145, 4859, 111143, 111142, 0, 0, 0, 0, 12172, 111136, 0, + 127899, 111141, 64764, 4210, 111138, 0, 804, 0, 83520, 0, 70344, 0, 0, + 67202, 10091, 67200, 119257, 67206, 67205, 67204, 67203, 72302, 0, 0, 0, + 128959, 0, 1425, 92259, 119229, 11049, 0, 71480, 42649, 8482, 0, 0, + 66715, 67209, 11940, 67207, 664, 0, 0, 0, 70200, 127525, 0, 70194, 93061, + 111155, 68474, 111153, 6032, 67218, 67217, 7430, 194670, 70191, 0, 0, 0, + 0, 0, 41161, 0, 9765, 10993, 41162, 0, 70189, 1169, 111181, 0, 1905, + 6034, 41164, 64744, 43236, 0, 128800, 73110, 0, 0, 788, 0, 0, 111167, + 111128, 1663, 128976, 42901, 127237, 67211, 67210, 0, 0, 67215, 67214, + 67213, 67212, 111160, 111159, 111158, 111157, 0, 69492, 0, 111161, 43612, + 0, 0, 0, 10855, 67223, 9355, 67221, 65198, 120355, 0, 221, 0, 0, 0, + 121141, 7191, 118930, 72208, 125212, 0, 0, 0, 0, 67228, 67227, 43333, + 67225, 0, 0, 0, 67229, 0, 7245, 0, 74405, 69922, 72219, 111178, 3873, + 8367, 111174, 111173, 111172, 43649, 0, 111177, 111176, 0, 11164, 0, + 74403, 111171, 111170, 111169, 7682, 74404, 1462, 10235, 0, 0, 0, 0, 0, + 111130, 0, 0, 74402, 0, 92299, 0, 0, 74052, 0, 126127, 120549, 0, 64295, + 0, 0, 0, 0, 0, 120662, 0, 0, 67231, 67230, 10755, 55257, 11155, 128568, + 983137, 9470, 0, 127540, 0, 69680, 64384, 0, 128607, 0, 0, 0, 122987, + 73764, 8204, 0, 0, 0, 0, 0, 8728, 0, 10904, 73446, 19936, 7833, 0, 0, 0, + 0, 92546, 0, 0, 0, 8537, 0, 0, 0, 121244, 0, 0, 2254, 128193, 0, 0, 0, 0, + 3062, 0, 0, 0, 0, 0, 41160, 41147, 41158, 0, 120777, 0, 41155, 111116, + 111115, 111114, 0, 121332, 111119, 111118, 111117, 129878, 0, 129091, 0, + 0, 0, 64594, 2456, 66867, 0, 0, 0, 0, 3721, 0, 0, 1230, 2678, 0, 3597, + 917795, 0, 0, 92215, 0, 67737, 8352, 0, 0, 0, 64515, 121378, 0, 129128, + 67846, 0, 129767, 92466, 0, 0, 71338, 0, 8660, 0, 0, 0, 0, 0, 4483, 0, 0, + 0, 6080, 0, 0, 1746, 1315, 0, 70201, 0, 13140, 74508, 0, 0, 4480, 0, + 111113, 111112, 0, 67979, 0, 6360, 10897, 111106, 605, 68302, 110737, + 69875, 110735, 110736, 66681, 0, 0, 0, 0, 0, 0, 0, 10877, 118868, 64885, + 0, 0, 0, 0, 0, 0, 345, 0, 0, 64606, 9917, 0, 0, 92196, 0, 1776, 8422, + 43992, 0, 0, 0, 126543, 43328, 0, 0, 1295, 0, 42869, 0, 0, 0, 0, 128772, + 65123, 125210, 11293, 11288, 0, 0, 65666, 0, 92369, 65420, 0, 0, 4252, 0, + 0, 0, 706, 72800, 0, 0, 129931, 65419, 92177, 0, 8419, 65421, 0, 66702, + 0, 12670, 118608, 0, 0, 0, 72825, 65422, 83008, 0, 0, 0, 0, 0, 124153, + 9736, 4184, 65418, 0, 0, 74035, 0, 129955, 0, 0, 0, 0, 129447, 0, 7962, + 12211, 9837, 83505, 0, 0, 5719, 0, 129720, 119068, 73777, 1857, 0, 9927, + 0, 983959, 0, 10037, 0, 73695, 78322, 78319, 7818, 0, 0, 127769, 0, 0, 0, + 65077, 0, 78325, 78326, 78323, 43327, 43989, 0, 65828, 0, 0, 83499, 0, + 68390, 0, 110687, 78336, 78339, 9543, 78335, 78332, 78333, 0, 127964, 0, + 129552, 983914, 0, 69448, 0, 71429, 0, 0, 0, 11914, 69431, 0, 0, 0, 9949, + 0, 0, 119215, 0, 12073, 73519, 0, 0, 0, 101218, 2260, 0, 0, 0, 0, 0, 0, + 1939, 0, 0, 0, 69903, 0, 0, 0, 0, 6643, 92477, 128485, 0, 78330, 78331, + 78328, 78329, 0, 92551, 0, 0, 0, 0, 124124, 72417, 0, 0, 0, 0, 78341, + 78342, 120944, 78340, 129513, 127529, 92350, 3784, 78350, 0, 78348, + 78349, 78345, 43324, 78343, 78344, 2231, 0, 0, 0, 42467, 0, 0, 42894, + 78363, 13281, 78360, 78361, 78356, 78358, 78353, 64899, 0, 41149, 0, + 43162, 68096, 41150, 0, 10571, 67162, 67161, 67160, 67159, 6947, 41152, + 887, 9249, 6565, 64806, 74366, 0, 67158, 67157, 0, 10831, 67175, 67174, + 120232, 65827, 43325, 67178, 10168, 67176, 0, 0, 9190, 128497, 9666, + 41997, 0, 0, 0, 0, 0, 0, 129411, 0, 78508, 0, 78351, 78352, 0, 75063, + 72839, 983749, 0, 126604, 0, 0, 0, 983422, 0, 2270, 0, 129957, 0, 78365, + 0, 67189, 72818, 0, 0, 0, 0, 0, 0, 0, 72833, 101119, 78366, 78367, 0, 0, + 0, 0, 10137, 6121, 10995, 0, 71050, 8119, 0, 71052, 0, 0, 0, 0, 0, 0, 0, + 1394, 0, 0, 128960, 0, 67184, 2998, 67182, 67181, 67188, 67187, 67186, + 67185, 0, 101185, 0, 0, 67180, 42003, 0, 0, 67193, 67192, 67191, 67190, + 67197, 67196, 67195, 67194, 0, 72770, 43315, 71051, 0, 1593, 0, 125120, + 619, 4635, 0, 72875, 0, 128859, 118657, 0, 0, 0, 67199, 67198, 0, 42790, + 42006, 0, 0, 0, 128998, 10757, 9347, 127767, 0, 0, 74227, 78904, 0, + 74116, 128423, 121073, 120860, 0, 92427, 0, 0, 0, 0, 64590, 0, 4371, 0, + 0, 92478, 0, 0, 73977, 0, 0, 127847, 0, 120862, 0, 64550, 73745, 70451, + 0, 121013, 0, 0, 0, 129286, 0, 0, 0, 0, 9131, 118648, 125214, 983223, 0, + 0, 64260, 0, 12606, 0, 0, 0, 0, 562, 983614, 0, 129648, 66455, 127533, + 3219, 0, 0, 0, 1037, 0, 64491, 0, 78579, 78572, 78580, 4568, 549, 0, 0, + 0, 0, 0, 128095, 70851, 2205, 0, 0, 0, 0, 129716, 0, 10825, 8079, 118962, + 0, 0, 0, 128855, 0, 13071, 0, 0, 41049, 42840, 43614, 129341, 74881, + 74596, 127191, 5212, 0, 66402, 119191, 0, 9747, 0, 0, 129778, 984008, + 41047, 1668, 0, 0, 0, 1187, 0, 74416, 0, 0, 0, 0, 3240, 128518, 9213, 0, + 0, 0, 127174, 69822, 0, 0, 0, 0, 1623, 0, 0, 0, 0, 0, 0, 11272, 0, 73914, + 65048, 1909, 42172, 0, 0, 10736, 11580, 72228, 7615, 0, 0, 4237, 66576, + 0, 65815, 68083, 0, 0, 0, 3489, 0, 0, 0, 0, 0, 0, 127146, 3796, 6800, 0, + 65582, 0, 129521, 0, 0, 68036, 0, 0, 64857, 121213, 126493, 0, 66308, 0, + 0, 64634, 127817, 0, 0, 0, 0, 3246, 0, 43972, 128643, 0, 0, 0, 0, 120751, + 0, 0, 0, 0, 1496, 42827, 0, 942, 2378, 119213, 0, 0, 0, 0, 9510, 1232, + 8139, 0, 0, 0, 11409, 0, 6382, 0, 66319, 121237, 0, 0, 0, 127887, 2374, + 0, 8475, 120844, 66313, 0, 0, 64879, 119298, 0, 0, 70869, 0, 0, 129025, + 0, 7705, 11942, 0, 0, 3309, 0, 119302, 0, 83345, 983866, 0, 0, 1280, + 6998, 128104, 0, 0, 0, 129945, 0, 0, 0, 0, 0, 0, 0, 74239, 983073, 0, 0, + 0, 6078, 121354, 0, 1475, 0, 9938, 6084, 0, 983995, 0, 118571, 0, 3256, + 0, 43973, 0, 0, 0, 8727, 0, 0, 0, 110831, 110832, 10562, 110830, 0, 0, 0, + 3248, 0, 0, 9015, 0, 0, 3635, 64337, 0, 0, 43852, 7195, 0, 2007, 64431, + 0, 0, 0, 0, 0, 0, 0, 65613, 77909, 0, 0, 0, 0, 119218, 7984, 11670, + 74434, 127770, 4176, 69248, 2034, 69442, 11154, 65891, 0, 0, 318, 2038, + 0, 0, 0, 3649, 13149, 42145, 42798, 3634, 0, 0, 128483, 122928, 124113, + 0, 11402, 120954, 94032, 74238, 0, 43313, 0, 0, 7938, 0, 1761, 0, 65379, + 68386, 128185, 1159, 71183, 0, 0, 0, 66687, 120851, 0, 41680, 0, 0, 0, + 1514, 11668, 67891, 9313, 0, 128490, 67877, 0, 41681, 0, 0, 12848, 69982, + 67873, 0, 74278, 0, 0, 12649, 0, 0, 1194, 3242, 9761, 9555, 8598, 0, + 120524, 0, 1551, 65447, 129414, 126211, 0, 0, 0, 67875, 0, 3495, 66648, + 125079, 0, 73024, 983232, 0, 126130, 10641, 0, 0, 0, 77845, 0, 0, 0, 0, + 0, 11131, 0, 0, 0, 0, 0, 42685, 72017, 193, 0, 0, 0, 42667, 0, 0, 92318, + 71958, 0, 1362, 9558, 0, 0, 0, 7351, 73789, 0, 0, 4426, 0, 0, 0, 0, 7276, + 42163, 5220, 0, 0, 67822, 0, 0, 0, 0, 41692, 0, 72283, 0, 0, 3223, 65492, + 0, 0, 4549, 983706, 0, 0, 101162, 10807, 0, 0, 0, 42182, 8688, 12866, 0, + 3294, 0, 0, 128101, 0, 64514, 0, 43329, 129989, 0, 0, 0, 119061, 0, + 43422, 0, 0, 128618, 0, 42729, 0, 3215, 120982, 68880, 917564, 0, 0, 0, + 65682, 0, 0, 65924, 0, 73506, 0, 1501, 0, 118807, 0, 0, 9607, 0, 65794, + 72243, 983046, 10989, 0, 74399, 0, 0, 7152, 0, 0, 129530, 7483, 125083, + 0, 8104, 70128, 7474, 0, 5189, 0, 0, 0, 8141, 0, 42537, 69612, 0, 0, 0, + 0, 0, 127307, 42934, 0, 0, 0, 0, 0, 0, 64517, 0, 0, 1650, 0, 0, 128502, + 7901, 3238, 0, 65556, 0, 0, 65158, 43416, 74959, 0, 7527, 0, 43319, 0, 0, + 45, 0, 0, 0, 0, 0, 7347, 0, 0, 0, 13129, 0, 9084, 0, 8737, 0, 0, 0, + 66808, 9639, 7912, 2620, 129653, 3564, 0, 0, 0, 0, 75049, 0, 2853, 0, 0, + 0, 0, 0, 2850, 8084, 0, 0, 71446, 92284, 43122, 0, 0, 0, 126503, 72214, + 0, 74767, 0, 7331, 110646, 0, 8245, 0, 3158, 92396, 3983, 0, 923, 0, + 69397, 292, 0, 126548, 0, 3221, 1763, 0, 0, 0, 0, 7253, 194636, 68391, 75002, 0, 3637, 12996, 0, 70461, 0, 0, 3228, 0, 0, 0, 0, 0, 0, 120833, 118939, 0, 7696, 78589, 0, 0, 0, 43316, 4177, 0, 9089, 0, 128805, 72116, 64500, 68133, 0, 0, 1856, 100572, 0, 6379, 0, 118999, 0, 3208, 0, 0, 0, @@ -26901,20 +27086,20 @@ static const unsigned int code_hash[] = { 4573, 0, 0, 0, 0, 0, 92961, 0, 118620, 41688, 0, 0, 0, 8314, 0, 0, 0, 0, 0, 66721, 0, 0, 121033, 0, 128226, 0, 0, 0, 13164, 0, 66237, 983982, 0, 0, 0, 3257, 0, 0, 1845, 0, 0, 0, 0, 128783, 0, 0, 0, 0, 3499, 8609, 0, - 7145, 0, 0, 0, 0, 74829, 984007, 983293, 0, 0, 0, 7591, 0, 0, 0, 73778, + 7145, 0, 0, 0, 0, 74829, 984007, 983296, 0, 0, 0, 7591, 0, 0, 0, 73778, 70132, 128167, 0, 0, 0, 0, 119261, 0, 0, 118561, 13083, 0, 0, 0, 0, - 66177, 983271, 5429, 0, 0, 68168, 66181, 0, 0, 983255, 0, 0, 5433, 67659, + 66177, 983274, 5429, 0, 0, 68168, 66181, 0, 0, 983258, 0, 0, 5433, 67659, 0, 42776, 1547, 66176, 92428, 0, 5425, 4977, 9999, 0, 5423, 64560, 125094, 0, 0, 0, 74122, 0, 0, 0, 128003, 4418, 66199, 0, 92300, 0, 0, 0, - 11863, 124995, 0, 11908, 0, 9360, 125101, 983202, 0, 66187, 12837, - 983290, 0, 11112, 0, 92321, 43318, 0, 0, 0, 0, 126518, 120604, 0, 983288, + 11863, 124995, 0, 11908, 0, 9360, 125101, 983204, 0, 66187, 12837, + 983293, 0, 11112, 0, 92321, 43318, 0, 0, 0, 0, 126518, 120604, 0, 983291, 0, 129595, 0, 983801, 0, 9958, 0, 125108, 0, 0, 0, 2433, 128602, 0, 3352, 0, 0, 0, 0, 0, 0, 305, 567, 67662, 0, 69979, 65242, 0, 41695, 0, 0, 0, 7837, 92873, 129002, 5337, 917622, 7325, 43312, 917619, 68742, 917617, 74086, 68777, 917614, 917613, 10973, 917611, 1372, 128768, 917608, 917607, 1254, 917605, 917604, 93967, 917602, 65228, 113753, 129367, 67723, 8068, 0, 0, 983970, 0, 3245, 64393, 119069, 118681, 0, 0, 0, 0, 0, - 0, 983281, 0, 119563, 129935, 78865, 0, 126638, 0, 0, 43322, 0, 0, 0, 0, + 0, 983284, 0, 119563, 129935, 78865, 0, 126638, 0, 0, 43322, 0, 0, 0, 0, 92698, 3226, 67695, 0, 0, 983958, 10200, 0, 128779, 101143, 0, 65610, 0, 0, 0, 3585, 250, 101142, 43320, 0, 0, 0, 0, 1152, 129849, 1688, 0, 0, 0, 0, 0, 121040, 128340, 0, 0, 0, 2107, 0, 129048, 0, 0, 0, 43868, 129832, @@ -26929,97 +27114,98 @@ static const unsigned int code_hash[] = { 0, 0, 2625, 92724, 0, 74309, 0, 0, 0, 7850, 120296, 69639, 127032, 0, 0, 43384, 12660, 110663, 0, 0, 110706, 110661, 0, 92380, 0, 0, 69649, 0, 713, 41073, 0, 3990, 0, 0, 0, 5017, 128313, 120352, 0, 0, 1030, 0, - 983120, 9513, 0, 0, 0, 4668, 0, 120350, 0, 6339, 0, 0, 0, 64650, 0, 0, + 983121, 9513, 0, 0, 0, 4668, 0, 120350, 0, 6339, 0, 0, 0, 64650, 0, 0, 74766, 983869, 8908, 0, 0, 0, 0, 10752, 13003, 68769, 0, 41307, 8732, - 120336, 0, 41310, 0, 4696, 0, 983953, 0, 120334, 3641, 5419, 0, 0, 0, 0, - 120344, 128129, 0, 7320, 65230, 11808, 0, 93970, 936, 13289, 0, 69892, - 65774, 0, 65243, 0, 19953, 0, 126469, 121375, 127256, 12913, 70722, - 68759, 0, 0, 70203, 0, 4113, 0, 2372, 1819, 0, 128053, 12152, 0, 682, - 7655, 120330, 129921, 0, 10593, 1703, 0, 0, 8033, 69953, 0, 9810, 0, 0, - 127949, 0, 119159, 10109, 0, 73898, 0, 71730, 126704, 0, 0, 917620, 1965, - 917621, 0, 0, 73887, 0, 0, 0, 6314, 0, 8501, 0, 0, 0, 41317, 0, 5417, - 983582, 0, 0, 9353, 68148, 41315, 0, 11161, 0, 41314, 194892, 0, 126562, - 119236, 634, 0, 0, 0, 69779, 4355, 12016, 0, 9654, 12856, 6924, 7660, 0, - 0, 0, 0, 0, 42692, 0, 74604, 0, 0, 0, 680, 6274, 0, 1181, 0, 3174, 67248, - 0, 0, 0, 0, 113776, 10650, 917603, 92295, 70672, 118965, 0, 64644, - 126981, 0, 0, 0, 0, 983961, 0, 65302, 40989, 68239, 68230, 68234, 0, 0, - 124989, 0, 40987, 4667, 0, 983963, 8828, 0, 0, 0, 4746, 0, 129840, 2269, - 4749, 0, 100598, 65192, 4744, 7345, 0, 242, 100595, 0, 8217, 0, 68919, 0, - 2245, 0, 0, 66790, 10850, 0, 0, 0, 0, 0, 129853, 64680, 0, 0, 120562, 0, - 127324, 0, 100551, 128721, 0, 7316, 0, 983610, 100552, 74157, 1646, 0, 0, - 73995, 120857, 129047, 0, 7350, 0, 0, 0, 9099, 4107, 3441, 0, 2975, - 194701, 0, 983966, 55220, 10084, 73943, 120845, 118649, 0, 0, 3399, 0, 0, - 11909, 0, 0, 7687, 0, 6789, 0, 0, 72739, 71367, 0, 0, 92589, 9151, 1137, - 0, 749, 7505, 125076, 5385, 0, 69387, 0, 0, 41298, 0, 69461, 0, 0, 0, 0, - 0, 0, 128455, 0, 519, 0, 64547, 5766, 0, 0, 0, 8848, 0, 41297, 0, 0, 0, - 41300, 74468, 65160, 0, 129839, 127511, 0, 0, 6558, 0, 0, 128686, 92775, - 0, 71450, 41302, 127927, 0, 0, 128646, 68762, 11729, 8719, 9060, 0, - 128796, 0, 0, 118573, 129682, 0, 11734, 93011, 11730, 73450, 9593, 5757, - 2403, 0, 55275, 0, 11728, 65894, 0, 0, 0, 68741, 0, 0, 0, 43489, 4282, - 983864, 0, 83497, 70328, 128103, 70324, 0, 69490, 127509, 0, 8456, 0, 0, - 74783, 0, 78250, 0, 70320, 120722, 9792, 0, 70326, 0, 0, 83500, 70322, - 10019, 71701, 123617, 6568, 4365, 0, 0, 3647, 0, 41134, 128341, 0, - 125043, 41135, 0, 0, 0, 129938, 0, 123616, 0, 41137, 41139, 0, 6545, 0, - 125139, 7597, 10528, 75054, 0, 3732, 73910, 0, 0, 0, 7312, 983639, 9062, - 93840, 11853, 0, 0, 128324, 41538, 0, 0, 118702, 0, 194706, 41531, 1263, - 3720, 0, 68028, 0, 41524, 64692, 119635, 0, 41534, 0, 92193, 0, 41168, 0, - 67398, 127347, 3524, 0, 8831, 127349, 127357, 0, 127360, 127352, 129816, - 0, 0, 0, 0, 0, 5845, 0, 0, 0, 71909, 8200, 0, 68460, 0, 43283, 5551, 0, - 0, 0, 6340, 983552, 100602, 0, 0, 0, 0, 0, 5422, 0, 0, 0, 2471, 0, 0, - 2749, 0, 73774, 10913, 72122, 0, 8666, 675, 74093, 0, 194986, 0, 69262, - 0, 0, 0, 10928, 0, 41153, 0, 0, 0, 3738, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 42347, 12092, 9615, 7234, 74047, 129782, 0, 0, 123639, 0, 0, 2934, - 0, 0, 0, 0, 74507, 0, 74461, 0, 0, 74290, 0, 64562, 129975, 64473, 0, 0, - 73728, 0, 11212, 0, 12128, 6534, 0, 0, 1901, 0, 0, 0, 0, 0, 127520, 0, 0, - 0, 0, 69940, 65459, 68293, 92290, 128808, 3770, 0, 0, 0, 64579, 128511, - 0, 0, 983334, 983342, 0, 0, 0, 5941, 0, 0, 65079, 0, 0, 0, 73961, 983336, - 0, 0, 0, 0, 0, 0, 10638, 0, 0, 0, 71486, 0, 0, 983351, 0, 43840, 129495, - 0, 5233, 983348, 64792, 71233, 0, 983326, 0, 0, 9847, 0, 1685, 595, 0, - 73971, 1292, 8940, 0, 11088, 0, 10004, 0, 0, 6541, 0, 0, 0, 5603, 9014, - 5606, 0, 538, 128705, 5602, 8467, 74391, 6547, 0, 0, 0, 0, 8458, 129534, - 8495, 0, 0, 917552, 10981, 78314, 125057, 2465, 0, 0, 0, 9730, 9280, 0, - 0, 74155, 72766, 113690, 0, 504, 0, 120715, 0, 983606, 0, 0, 0, 123141, - 125024, 0, 0, 732, 3737, 0, 1548, 0, 0, 1832, 5604, 0, 41141, 0, 5607, - 72854, 2176, 3745, 0, 0, 128137, 0, 0, 3869, 11937, 5725, 0, 66566, 7416, - 5728, 0, 0, 0, 11918, 66567, 5724, 118829, 5727, 0, 0, 0, 5723, 118585, - 128116, 71999, 0, 0, 0, 42532, 0, 12303, 0, 11423, 0, 983115, 68303, - 74074, 0, 128267, 6559, 64557, 71348, 0, 66763, 43019, 0, 10238, 0, 0, - 43377, 0, 71346, 124937, 9783, 42704, 0, 71719, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 41144, 129465, 0, 0, 0, 72793, 92176, 0, 70682, 0, 8820, 0, 0, - 0, 11515, 526, 0, 0, 0, 0, 0, 0, 8635, 0, 0, 8288, 11815, 0, 0, 0, 1543, - 3713, 0, 0, 0, 68041, 127816, 0, 0, 64357, 0, 42082, 0, 0, 8987, 42081, - 0, 0, 0, 0, 0, 0, 6553, 0, 0, 11253, 0, 0, 5475, 0, 0, 0, 119334, 12990, - 1160, 42084, 0, 123152, 0, 0, 360, 0, 0, 128274, 5863, 3137, 0, 983317, - 0, 0, 10959, 3146, 0, 127374, 0, 68341, 13076, 3135, 983300, 0, 0, 3142, - 0, 94068, 10819, 128479, 0, 74635, 12877, 119867, 73967, 0, 70808, 0, 0, - 0, 0, 6163, 129745, 113728, 0, 0, 0, 8603, 0, 0, 3306, 0, 43392, 0, - 917565, 5751, 0, 0, 0, 0, 0, 7403, 0, 118933, 0, 122628, 64783, 92658, 0, - 0, 129592, 0, 0, 65569, 7021, 0, 0, 0, 0, 0, 6540, 6974, 0, 0, 0, 0, 0, - 0, 0, 983655, 0, 43585, 0, 6551, 983993, 0, 0, 0, 0, 0, 72216, 8977, 602, - 120814, 0, 0, 0, 72119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 983624, 74812, 0, - 0, 0, 9475, 0, 65105, 0, 118556, 0, 43592, 7831, 66751, 0, 0, 73915, 0, - 43593, 0, 43591, 43061, 0, 0, 43589, 43584, 0, 13113, 0, 0, 43590, 8766, - 9087, 0, 0, 41574, 78337, 0, 42900, 6376, 0, 0, 0, 0, 9854, 0, 0, 0, 0, - 0, 0, 0, 2909, 0, 0, 0, 6529, 110930, 75004, 3751, 0, 0, 0, 1798, 0, 0, - 1354, 0, 13152, 6557, 12430, 0, 94098, 0, 0, 0, 68123, 128097, 0, 0, 0, - 71264, 123559, 11082, 0, 65677, 8682, 42054, 92595, 42045, 9804, 0, 0, - 3595, 0, 0, 0, 0, 42399, 0, 0, 0, 65541, 0, 7324, 0, 0, 0, 8797, 77895, - 0, 64888, 7167, 2356, 95, 110810, 0, 0, 42286, 0, 0, 69999, 0, 120877, 0, - 0, 42324, 129359, 0, 0, 43492, 0, 43406, 0, 0, 0, 0, 0, 43400, 0, 0, - 71720, 0, 66435, 0, 0, 3201, 514, 74502, 0, 43396, 0, 64493, 0, 43404, - 11218, 0, 0, 43398, 0, 0, 41341, 129485, 6564, 1463, 41342, 0, 5293, 0, - 0, 3733, 0, 0, 41344, 0, 0, 0, 0, 41346, 0, 69747, 0, 0, 0, 0, 0, 0, 0, - 983764, 0, 0, 0, 65272, 0, 0, 1270, 1132, 0, 0, 0, 66655, 0, 0, 74314, - 64761, 0, 110853, 8510, 0, 129600, 0, 0, 0, 0, 0, 0, 69692, 0, 0, 42383, - 69690, 0, 69700, 13141, 0, 92465, 0, 0, 0, 41566, 0, 0, 129334, 127171, - 0, 0, 0, 0, 0, 0, 0, 6308, 0, 0, 2611, 0, 66881, 0, 65063, 0, 0, 0, 0, - 4484, 8747, 110597, 128369, 0, 0, 0, 0, 0, 0, 12902, 0, 0, 7299, 0, 0, - 12107, 7100, 10905, 65010, 0, 125135, 66018, 9284, 0, 0, 0, 0, 0, 0, 0, - 12010, 0, 126093, 120949, 121032, 0, 0, 0, 0, 0, 0, 0, 0, 6618, 3562, - 66365, 0, 42234, 12648, 128039, 0, 0, 0, 41309, 9764, 41316, 0, 0, 13230, - 41299, 0, 0, 68365, 0, 0, 0, 0, 0, 0, 4153, 0, 0, 128047, 0, 0, 42889, 0, - 129322, 41578, 0, 41577, 0, 68092, 0, 6533, 0, 41570, 0, 72414, 0, 41580, - 74628, 0, 12901, 0, 0, 0, 0, 71461, 41360, 0, 0, 4743, 0, 0, 0, 0, 68398, + 120336, 0, 41310, 0, 4696, 0, 983953, 0, 120334, 3641, 5419, 124119, 0, + 0, 0, 120344, 128129, 0, 7320, 65230, 11808, 0, 93970, 936, 13289, 0, + 69892, 65774, 0, 65243, 0, 19953, 0, 126469, 121375, 127256, 12913, + 70722, 68759, 0, 0, 70203, 0, 4113, 0, 2372, 1819, 0, 128053, 12152, 0, + 682, 7655, 120330, 129921, 0, 10593, 1703, 0, 0, 8033, 69953, 0, 9810, 0, + 0, 127949, 0, 119159, 10109, 0, 73898, 0, 71730, 126704, 0, 0, 917620, + 1965, 917621, 0, 0, 73887, 0, 0, 0, 6314, 0, 8501, 0, 0, 0, 41317, 0, + 5417, 983582, 0, 0, 9353, 68148, 41315, 0, 11161, 0, 41314, 194892, 0, + 126562, 119236, 634, 0, 0, 0, 69779, 4355, 12016, 0, 9654, 12856, 6924, + 7660, 0, 0, 0, 0, 0, 42692, 0, 74604, 0, 0, 0, 680, 6274, 0, 1181, 0, + 3174, 67248, 0, 0, 0, 0, 113776, 10650, 917603, 92295, 70672, 118965, 0, + 64644, 126981, 0, 0, 0, 0, 983961, 0, 65302, 40989, 68239, 68230, 68234, + 0, 0, 124989, 0, 40987, 4667, 0, 983963, 8828, 0, 0, 0, 4746, 0, 129840, + 2269, 4749, 0, 100598, 65192, 4744, 7345, 0, 242, 100595, 0, 8217, 0, + 68919, 0, 2245, 0, 0, 66790, 10850, 0, 0, 0, 983391, 0, 129853, 64680, 0, + 0, 120562, 0, 127324, 0, 100551, 128721, 0, 7316, 0, 983610, 100552, + 74157, 1646, 0, 0, 73995, 120857, 73500, 0, 7350, 0, 0, 0, 9099, 4107, + 3441, 0, 2975, 194701, 0, 983966, 55220, 10084, 73943, 120845, 118649, 0, + 0, 3399, 0, 0, 11909, 0, 0, 7687, 0, 6789, 0, 0, 72739, 71367, 0, 0, + 92589, 9151, 1137, 0, 749, 7505, 125076, 5385, 0, 69387, 0, 0, 41298, 0, + 69461, 0, 0, 0, 0, 0, 0, 128455, 0, 519, 0, 64547, 5766, 0, 0, 0, 8848, + 0, 41297, 0, 0, 0, 41300, 74468, 65160, 0, 129839, 127511, 0, 0, 6558, 0, + 0, 128686, 92775, 0, 71450, 41302, 127927, 0, 0, 128646, 68762, 11729, + 8719, 9060, 0, 128796, 0, 0, 118573, 129682, 0, 11734, 93011, 11730, + 73450, 9593, 5757, 2403, 0, 55275, 0, 11728, 65894, 0, 0, 0, 68741, 0, 0, + 0, 43489, 4282, 983864, 0, 83497, 70328, 128103, 70324, 0, 69490, 127509, + 0, 8456, 0, 0, 74783, 0, 78250, 0, 70320, 120722, 9792, 0, 70326, 0, 0, + 83500, 70322, 10019, 71701, 123617, 6568, 4365, 129399, 0, 3647, 0, + 41134, 128341, 0, 125043, 41135, 0, 0, 0, 129938, 0, 123616, 0, 41137, + 41139, 0, 6545, 0, 125139, 7597, 10528, 75054, 0, 3732, 73910, 0, 0, 0, + 7312, 983639, 9062, 93840, 11853, 0, 0, 128324, 41538, 0, 0, 118702, 0, + 194706, 41531, 1263, 3720, 0, 68028, 0, 41524, 64692, 119635, 0, 41534, + 0, 92193, 0, 41168, 0, 67398, 127347, 3524, 0, 8831, 127349, 127357, 0, + 127360, 127352, 129816, 0, 0, 0, 0, 0, 5845, 0, 0, 0, 71909, 8200, 0, + 68460, 0, 43283, 5551, 0, 0, 0, 6340, 983552, 100602, 0, 0, 0, 0, 0, + 5422, 0, 0, 0, 2471, 0, 0, 2749, 0, 73774, 10913, 72122, 0, 8666, 675, + 74093, 0, 194986, 0, 69262, 0, 0, 0, 10928, 0, 41153, 0, 0, 0, 3738, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42347, 12092, 9615, 7234, 74047, + 129782, 0, 0, 123639, 0, 0, 2934, 0, 0, 0, 0, 74507, 0, 74461, 0, 0, + 74290, 0, 64562, 129975, 64473, 0, 0, 73728, 0, 11212, 0, 12128, 6534, 0, + 0, 1901, 0, 0, 0, 0, 0, 127520, 0, 0, 0, 0, 69940, 65459, 68293, 92290, + 128808, 3770, 0, 0, 0, 64579, 128511, 0, 0, 983337, 983345, 0, 0, 0, + 5941, 0, 0, 65079, 0, 0, 0, 73961, 983339, 0, 0, 0, 0, 0, 0, 10638, 0, 0, + 0, 71486, 0, 0, 983354, 0, 43840, 129495, 0, 5233, 983351, 64792, 71233, + 0, 983329, 0, 73553, 9847, 0, 1685, 595, 0, 73971, 1292, 8940, 0, 11088, + 0, 10004, 0, 0, 6541, 0, 0, 0, 5603, 9014, 5606, 0, 538, 128705, 5602, + 8467, 74391, 6547, 0, 0, 0, 0, 8458, 129534, 8495, 0, 0, 917552, 10981, + 78314, 125057, 2465, 0, 0, 0, 9730, 9280, 0, 0, 74155, 72766, 113690, 0, + 504, 0, 120715, 0, 983606, 0, 0, 0, 123141, 125024, 0, 0, 732, 3737, 0, + 1548, 0, 0, 1832, 5604, 0, 41141, 0, 5607, 72854, 2176, 3745, 0, 0, + 128137, 0, 0, 3869, 11937, 5725, 0, 66566, 7416, 5728, 0, 0, 0, 11918, + 66567, 5724, 118829, 5727, 0, 0, 0, 5723, 118585, 128116, 71999, 0, 0, 0, + 42532, 0, 12303, 0, 11423, 0, 983116, 68303, 74074, 0, 128267, 6559, + 64557, 71348, 0, 66763, 43019, 0, 10238, 0, 0, 43377, 0, 71346, 124937, + 9783, 42704, 0, 71719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41144, 129465, 0, + 0, 0, 72793, 92176, 0, 70682, 0, 8820, 0, 0, 0, 11515, 526, 0, 0, 0, 0, + 0, 0, 8635, 0, 0, 8288, 11815, 0, 0, 0, 1543, 3713, 0, 0, 0, 68041, + 127816, 0, 0, 64357, 0, 42082, 0, 0, 8987, 42081, 0, 0, 0, 0, 0, 0, 6553, + 0, 0, 11253, 0, 0, 5475, 0, 0, 0, 119334, 12990, 1160, 42084, 0, 123152, + 0, 0, 360, 0, 0, 128274, 5863, 3137, 0, 983320, 0, 0, 10959, 3146, 0, + 127374, 0, 68341, 13076, 3135, 983303, 0, 0, 3142, 0, 94068, 10819, + 128479, 0, 74635, 12877, 119867, 73967, 0, 70808, 0, 0, 0, 0, 6163, + 129745, 113728, 0, 0, 0, 8603, 0, 0, 3306, 0, 43392, 0, 917565, 5751, 0, + 0, 0, 0, 0, 7403, 0, 118933, 0, 122628, 64783, 92658, 0, 0, 129592, 0, 0, + 65569, 7021, 0, 0, 119864, 0, 0, 6540, 6974, 0, 0, 0, 0, 0, 0, 0, 983655, + 0, 43585, 0, 6551, 983993, 0, 0, 0, 0, 0, 72216, 8977, 602, 120814, 0, 0, + 0, 72119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 983624, 74812, 0, 0, 0, 9475, 0, + 65105, 0, 118556, 0, 43592, 7831, 66751, 0, 0, 73915, 0, 43593, 0, 43591, + 43061, 0, 0, 43589, 43584, 0, 13113, 0, 0, 43590, 8766, 9087, 0, 0, + 41574, 78337, 0, 42900, 6376, 0, 0, 0, 0, 9854, 0, 0, 0, 0, 0, 0, 0, + 2909, 110928, 0, 0, 6529, 110930, 75004, 3751, 0, 0, 0, 1798, 0, 0, 1354, + 0, 13152, 6557, 12430, 0, 94098, 0, 0, 0, 68123, 128097, 0, 0, 0, 71264, + 123559, 11082, 0, 65677, 8682, 42054, 92595, 42045, 9804, 0, 0, 3595, 0, + 0, 119498, 0, 42399, 0, 0, 0, 65541, 0, 7324, 0, 0, 0, 8797, 77895, 0, + 64888, 7167, 2356, 95, 110810, 0, 0, 42286, 0, 0, 69999, 0, 120877, 0, 0, + 42324, 129359, 0, 0, 43492, 0, 43406, 0, 0, 0, 0, 0, 43400, 0, 0, 71720, + 0, 66435, 0, 0, 3201, 514, 74502, 0, 43396, 0, 64493, 0, 43404, 11218, 0, + 0, 43398, 0, 0, 41341, 129485, 6564, 1463, 41342, 0, 5293, 0, 0, 3733, 0, + 0, 41344, 0, 0, 0, 0, 41346, 0, 69747, 0, 0, 0, 0, 0, 0, 0, 983764, 0, 0, + 0, 65272, 0, 0, 1270, 1132, 0, 0, 0, 66655, 0, 0, 74314, 64761, 0, + 110853, 8510, 0, 129600, 0, 0, 0, 0, 0, 0, 69692, 0, 0, 42383, 69690, 0, + 69700, 13141, 0, 92465, 0, 0, 0, 41566, 0, 0, 129334, 127171, 0, 0, 0, 0, + 0, 0, 0, 6308, 0, 0, 2611, 0, 66881, 0, 65063, 0, 0, 0, 0, 4484, 8747, + 110597, 128369, 0, 0, 0, 0, 0, 0, 12902, 0, 0, 7299, 0, 0, 12107, 7100, + 10905, 65010, 0, 125135, 66018, 9284, 0, 0, 0, 0, 0, 0, 0, 12010, 0, + 126093, 120949, 121032, 0, 0, 0, 0, 0, 0, 0, 0, 6618, 3562, 66365, 0, + 42234, 12648, 128039, 0, 0, 0, 41309, 9764, 41316, 0, 0, 13230, 41299, 0, + 0, 68365, 0, 0, 0, 0, 0, 0, 4153, 0, 0, 128047, 0, 0, 42889, 0, 129322, + 41578, 0, 41577, 0, 68092, 0, 6533, 0, 41570, 0, 72414, 0, 41580, 74628, + 0, 12901, 0, 0, 0, 0, 71461, 41360, 0, 0, 4743, 0, 0, 0, 0, 68398, 110781, 5890, 110779, 111103, 3739, 8695, 92514, 0, 3964, 8984, 111095, 68288, 0, 0, 70000, 111090, 111089, 67504, 3956, 82952, 111093, 6563, 111091, 41305, 0, 0, 12067, 41312, 0, 0, 0, 129708, 0, 8175, 0, 3600, 0, @@ -27036,30 +27222,30 @@ static const unsigned int code_hash[] = { 7396, 0, 0, 69788, 0, 43512, 7965, 111039, 111038, 111037, 111036, 41350, 0, 0, 0, 2294, 64501, 68034, 0, 68405, 111034, 0, 0, 111030, 111029, 71105, 111027, 0, 111033, 92200, 111031, 0, 6764, 0, 0, 111026, 111025, - 111024, 65203, 128010, 0, 0, 0, 3210, 0, 129978, 0, 0, 82958, 127970, + 72454, 65203, 128010, 0, 0, 0, 3210, 0, 129978, 0, 0, 82958, 127970, 82957, 0, 68875, 10043, 71979, 1186, 41571, 0, 5209, 9464, 82960, 66657, 5207, 65062, 5213, 0, 0, 41348, 41568, 128803, 3253, 111045, 111044, 74067, 111042, 111049, 5596, 111047, 111046, 0, 64887, 0, 5217, 111041, 72252, 0, 0, 0, 0, 2635, 92760, 0, 0, 0, 92742, 0, 113672, 0, 0, 0, 2258, 67081, 0, 67083, 0, 0, 0, 5784, 0, 0, 0, 0, 4011, 0, 0, 0, 0, 4254, 0, 111054, 5600, 111052, 111051, 10447, 5598, 1207, 111055, 0, 3501, 42582, - 0, 111050, 0, 1124, 5597, 983498, 983499, 9321, 129464, 75040, 983495, 0, - 1719, 68356, 68354, 9671, 1125, 2721, 0, 129876, 983501, 7631, 5488, + 0, 111050, 0, 1124, 5597, 983501, 78908, 9321, 129464, 75040, 983498, 0, + 1719, 68356, 68354, 9671, 1125, 2721, 0, 129876, 983504, 7631, 5488, 111082, 0, 0, 5491, 111086, 8937, 0, 3236, 74187, 5490, 0, 5489, 8522, 68358, 111069, 6300, 111067, 111066, 0, 0, 111071, 111070, 0, 9875, 7593, 111065, 0, 0, 43182, 0, 68379, 3311, 111058, 111057, 3746, 11016, 65752, 111061, 0, 43423, 68775, 0, 111056, 72225, 0, 0, 127120, 0, 2232, 0, 0, - 0, 0, 0, 126555, 0, 0, 8656, 0, 128358, 0, 0, 983487, 983488, 917563, - 983486, 983483, 983484, 0, 0, 0, 129669, 0, 111183, 128043, 983492, 1036, - 983490, 111075, 1723, 111073, 111072, 111079, 41579, 111077, 111076, - 10705, 0, 983482, 74486, 71693, 740, 983478, 983479, 129645, 0, 0, 74846, + 0, 0, 0, 126555, 0, 0, 8656, 0, 128358, 0, 0, 983490, 983491, 917563, + 983489, 983486, 983487, 0, 0, 0, 129669, 0, 111183, 128043, 983495, 1036, + 983493, 111075, 1723, 111073, 111072, 111079, 41579, 111077, 111076, + 10705, 0, 983485, 74486, 71693, 740, 983481, 983482, 129645, 0, 0, 74846, 92255, 0, 0, 0, 0, 0, 10438, 74487, 73798, 13285, 0, 0, 0, 5690, 0, 93992, 0, 0, 13095, 0, 127857, 121419, 7321, 121203, 13254, 70176, 75070, 0, 0, 0, 0, 127845, 3247, 317, 0, 0, 0, 0, 917543, 0, 10173, 0, 0, 0, 0, 0, 5223, 0, 0, 119564, 5226, 0, 94044, 5880, 94065, 7758, 0, 0, 5224, - 5487, 94041, 5692, 41725, 983464, 0, 5695, 41711, 0, 43171, 0, 94049, - 5691, 983469, 866, 1488, 983468, 983454, 65665, 94036, 983453, 74797, 0, - 0, 11039, 983462, 11145, 71211, 983461, 983458, 983459, 983456, 983457, + 5487, 94041, 5692, 41725, 983467, 0, 5695, 41711, 0, 43171, 0, 94049, + 5691, 983472, 866, 1488, 983471, 983457, 65665, 94036, 983456, 74797, 0, + 0, 11039, 983465, 11145, 71211, 983464, 983461, 983462, 983459, 983460, 42492, 43402, 125208, 3302, 0, 72842, 43153, 0, 0, 120885, 121300, 0, 7856, 8690, 0, 73076, 110880, 0, 0, 73091, 0, 69925, 120635, 65153, 0, 0, 0, 0, 0, 0, 4540, 0, 0, 0, 0, 11844, 121209, 8863, 0, 75061, 71978, 6389, @@ -27067,7 +27253,7 @@ static const unsigned int code_hash[] = { 9648, 111123, 71170, 10270, 10286, 10318, 10382, 43529, 0, 0, 0, 0, 0, 70110, 43835, 119520, 70111, 119360, 118815, 127084, 127083, 8767, 0, 128437, 41281, 0, 5201, 0, 6215, 67072, 6214, 13101, 0, 0, 65268, 67073, - 0, 0, 127976, 72995, 127073, 10511, 42075, 0, 127071, 129509, 0, 67115, + 0, 0, 127976, 72995, 127073, 10511, 42075, 0, 73475, 129509, 0, 67115, 127069, 111293, 127068, 0, 127067, 0, 74845, 0, 42071, 43156, 0, 0, 0, 0, 7954, 0, 0, 0, 8485, 4671, 0, 69513, 4740, 0, 0, 42618, 78294, 3064, 6212, 0, 0, 0, 9554, 0, 83044, 0, 126598, 0, 78291, 6159, 6213, 12885, 0, @@ -27085,14 +27271,14 @@ static const unsigned int code_hash[] = { 125136, 128583, 0, 7022, 0, 4739, 0, 5802, 9816, 8615, 0, 0, 491, 65837, 0, 0, 128644, 0, 8426, 11092, 9891, 0, 0, 0, 41881, 118823, 3736, 7394, 42648, 0, 68448, 9095, 7741, 12684, 41885, 0, 0, 0, 0, 5815, 0, 0, 0, - 127392, 0, 0, 41878, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120804, 0, 0, 2267, 0, - 78289, 78359, 78288, 0, 0, 78318, 65920, 0, 194819, 7057, 9408, 9409, - 9410, 9411, 9412, 9413, 9414, 9415, 9416, 9417, 9418, 9419, 9420, 9421, - 5897, 9423, 917933, 127107, 0, 127108, 917937, 127963, 8955, 9399, 9400, - 9401, 9402, 9403, 9404, 9405, 9406, 9407, 0, 128626, 42669, 73832, 78261, - 67683, 2631, 119308, 78259, 0, 78260, 3996, 0, 119307, 0, 0, 0, 0, 0, 0, - 64825, 917916, 917913, 917914, 917919, 5899, 917917, 129990, 12085, 0, - 574, 69734, 77825, 73828, 9473, 77824, 118918, 73900, 41735, 42211, 0, + 127392, 0, 0, 41878, 0, 0, 0, 0, 0, 0, 0, 0, 119503, 0, 120804, 0, 0, + 2267, 0, 78289, 78359, 78288, 0, 0, 78318, 65920, 0, 194819, 7057, 9408, + 9409, 9410, 9411, 9412, 9413, 9414, 9415, 9416, 9417, 9418, 9419, 9420, + 9421, 5897, 9423, 917933, 127107, 0, 127108, 917937, 127963, 8955, 9399, + 9400, 9401, 9402, 9403, 9404, 9405, 9406, 9407, 0, 128626, 42669, 73832, + 78261, 67683, 2631, 119308, 78259, 0, 78260, 3996, 0, 119307, 0, 0, 0, 0, + 0, 0, 64825, 917916, 917913, 917914, 917919, 5899, 917917, 129990, 12085, + 0, 574, 69734, 77825, 73828, 9473, 77824, 118918, 73900, 41735, 42211, 0, 4190, 77834, 77835, 77830, 77833, 3616, 77828, 77837, 77838, 7708, 77836, 2228, 113765, 0, 0, 4191, 42968, 77844, 73800, 77842, 77843, 77839, 77840, 0, 78311, 83375, 0, 0, 10415, 74102, 0, 5896, 0, 10351, 67151, 0, @@ -27115,45 +27301,45 @@ static const unsigned int code_hash[] = { 0, 101166, 82976, 0, 0, 67812, 0, 101163, 0, 42572, 0, 128300, 119146, 1963, 11622, 0, 43237, 82981, 7550, 67100, 5903, 82984, 78009, 129750, 9662, 0, 128391, 0, 0, 0, 0, 11013, 0, 0, 0, 128433, 67090, 0, 0, 0, 0, - 0, 11568, 983704, 43367, 0, 0, 7852, 0, 0, 0, 0, 0, 194676, 0, 194675, 0, - 0, 416, 129668, 0, 73834, 0, 68921, 10984, 0, 0, 101175, 129838, 101182, - 0, 127013, 92423, 0, 983258, 121199, 0, 0, 12540, 0, 0, 0, 0, 11445, - 101168, 2112, 0, 0, 0, 1021, 0, 9507, 10210, 78005, 8023, 93963, 78006, - 78001, 43181, 78003, 9532, 119094, 0, 0, 0, 0, 0, 1885, 43268, 129802, - 129798, 120542, 121153, 392, 7894, 4391, 129810, 8221, 119597, 77999, - 77998, 0, 0, 0, 92967, 0, 3558, 0, 3913, 70429, 121376, 0, 0, 1265, 0, - 6309, 0, 12969, 0, 101151, 0, 101146, 0, 101139, 0, 41864, 0, 0, 74294, - 0, 167, 0, 917584, 0, 93983, 72354, 68477, 0, 0, 917594, 0, 2493, 129827, - 0, 129804, 0, 917570, 0, 0, 0, 406, 917592, 0, 0, 0, 0, 0, 0, 0, 127161, - 0, 128597, 0, 0, 0, 3421, 10561, 0, 8365, 917581, 0, 127569, 120787, - 128669, 0, 0, 0, 0, 7834, 0, 0, 101154, 10298, 6624, 4908, 0, 1639, - 120842, 0, 0, 6327, 6724, 0, 0, 0, 69910, 4817, 0, 0, 0, 68059, 0, 11022, - 0, 0, 0, 118888, 0, 0, 7548, 64794, 0, 12291, 983165, 0, 0, 0, 0, 0, 0, - 1134, 1838, 0, 2057, 0, 0, 0, 0, 0, 0, 5206, 0, 0, 42523, 0, 0, 0, 0, - 65550, 8570, 4816, 0, 127926, 0, 4821, 0, 0, 0, 4818, 125257, 119974, - 119977, 0, 0, 119970, 119973, 0, 119983, 119982, 67470, 119984, 119979, - 119978, 0, 119980, 119670, 129297, 0, 11284, 119987, 70097, 65155, - 119988, 0, 9363, 0, 0, 0, 5900, 93990, 7889, 2722, 128770, 0, 0, 0, 0, - 2282, 0, 0, 0, 68093, 0, 0, 0, 0, 0, 70150, 118628, 0, 0, 0, 129651, - 70146, 983079, 119967, 71330, 70148, 0, 0, 94006, 70144, 119964, 110677, - 110678, 110675, 110676, 0, 110674, 4226, 0, 123165, 5732, 71327, 0, 0, - 65119, 0, 0, 92971, 64770, 0, 0, 6093, 0, 0, 1395, 0, 0, 0, 121179, 786, - 0, 43174, 64340, 0, 125269, 0, 983662, 125138, 10132, 0, 0, 0, 0, 0, - 93956, 0, 68444, 0, 92437, 123143, 0, 0, 92656, 0, 0, 0, 1399, 121463, 0, - 121465, 121464, 120808, 241, 121469, 4907, 0, 0, 0, 0, 0, 0, 0, 0, - 127904, 0, 0, 42780, 0, 0, 0, 4217, 0, 0, 0, 0, 72158, 0, 0, 43099, 3965, - 0, 0, 0, 13300, 0, 0, 43057, 0, 0, 0, 0, 0, 65372, 0, 6410, 126073, + 0, 11568, 983704, 43367, 0, 0, 7852, 119496, 0, 0, 0, 0, 194676, 0, + 194675, 0, 0, 416, 129668, 0, 73834, 0, 68921, 10984, 0, 0, 101175, + 129838, 101182, 0, 127013, 92423, 0, 983261, 121199, 0, 0, 12540, 0, + 983220, 0, 0, 11445, 101168, 2112, 0, 0, 0, 1021, 0, 9507, 10210, 78005, + 8023, 93963, 78006, 78001, 43181, 78003, 9532, 119094, 0, 0, 0, 0, 0, + 1885, 43268, 129802, 129798, 120542, 121153, 392, 7894, 4391, 129810, + 8221, 119597, 77999, 77998, 0, 0, 0, 92967, 0, 3558, 0, 3913, 70429, + 121376, 0, 0, 1265, 0, 6309, 0, 12969, 0, 101151, 0, 101146, 0, 101139, + 0, 41864, 0, 0, 74294, 0, 167, 0, 917584, 0, 93983, 72354, 68477, 0, 0, + 917594, 0, 2493, 129827, 0, 129804, 0, 917570, 917593, 0, 0, 406, 917592, + 0, 0, 0, 0, 0, 0, 0, 127161, 0, 128597, 0, 0, 0, 3421, 10561, 0, 8365, + 917581, 0, 127569, 120787, 128669, 0, 0, 0, 0, 7834, 0, 0, 101154, 10298, + 6624, 4908, 0, 1639, 120842, 0, 0, 6327, 6724, 0, 0, 0, 69910, 4817, 0, + 0, 0, 68059, 0, 11022, 0, 0, 0, 118888, 0, 0, 7548, 64794, 0, 12291, + 983166, 0, 0, 0, 0, 0, 0, 1134, 1838, 0, 2057, 0, 0, 0, 0, 0, 0, 5206, 0, + 0, 42523, 0, 0, 0, 0, 65550, 8570, 4816, 0, 127926, 0, 4821, 0, 0, 0, + 4818, 125257, 119974, 119977, 0, 0, 119970, 119973, 0, 119983, 119982, + 67470, 119984, 119979, 119978, 0, 119980, 119670, 129297, 0, 11284, + 119987, 70097, 65155, 119988, 0, 9363, 0, 0, 0, 5900, 93990, 7889, 2722, + 128770, 0, 0, 0, 0, 2282, 0, 0, 0, 68093, 0, 0, 0, 0, 0, 70150, 118628, + 0, 0, 0, 129651, 70146, 983079, 119967, 71330, 70148, 0, 0, 94006, 70144, + 119964, 110677, 110678, 110675, 110676, 0, 110674, 4226, 0, 123165, 5732, + 71327, 0, 0, 65119, 0, 0, 92971, 64770, 0, 0, 6093, 0, 0, 1395, 0, 0, 0, + 121179, 786, 0, 43174, 64340, 0, 125269, 0, 983662, 125138, 10132, 0, 0, + 0, 0, 0, 93956, 0, 68444, 0, 92437, 123143, 0, 0, 92656, 0, 0, 0, 1399, + 121463, 0, 121465, 121464, 120808, 241, 121469, 4907, 0, 0, 0, 0, 0, 0, + 0, 0, 127904, 0, 0, 42780, 0, 0, 0, 4217, 0, 0, 0, 0, 72158, 0, 0, 43099, + 3965, 0, 0, 0, 13300, 0, 0, 43057, 0, 0, 0, 0, 0, 65372, 0, 6410, 126073, 125252, 70468, 0, 0, 0, 119558, 0, 0, 0, 0, 0, 0, 43188, 2626, 7762, 0, 0, 0, 127183, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67726, 0, 126993, 1542, 0, 0, 92550, 0, 0, 74311, 0, 0, 10181, 2150, 0, 0, 0, 0, 124921, 68053, 6029, 72852, 0, 0, 0, 0, 8993, 0, 0, 0, 93968, 606, 118664, 0, 0, 0, 4311, 0, 6027, 126615, 4322, 0, 65207, 0, 2184, 983920, 0, 0, 2735, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 70806, 0, 0, 0, 92783, 92844, 0, 65817, 55288, 127934, - 66564, 8530, 0, 7709, 0, 121202, 66560, 128528, 917595, 12876, 66561, 0, - 121430, 983957, 7789, 5855, 809, 0, 0, 72853, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 64386, 0, 74909, 64845, 120607, 66416, 83360, 6532, 0, 0, 0, 0, - 128224, 0, 0, 0, 0, 43091, 92287, 0, 0, 129312, 0, 0, 0, 11361, 0, 0, - 8153, 128105, 0, 10741, 0, 0, 0, 0, 0, 64706, 917922, 0, 69505, 78870, + 0, 0, 0, 0, 0, 0, 70806, 0, 73547, 0, 92783, 92844, 0, 65817, 55288, + 127934, 66564, 8530, 0, 7709, 0, 121202, 66560, 128528, 917595, 12876, + 66561, 0, 121430, 983957, 7789, 5855, 809, 0, 0, 72853, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 64386, 0, 74909, 64845, 120607, 66416, 83360, 6532, 0, 0, + 0, 0, 128224, 0, 0, 0, 0, 43091, 92287, 0, 0, 129312, 0, 0, 0, 11361, 0, + 0, 8153, 128105, 0, 10741, 0, 0, 0, 0, 0, 64706, 917922, 0, 69505, 78870, 9466, 78866, 9824, 0, 0, 0, 120977, 915, 0, 0, 43865, 0, 0, 0, 67131, 70096, 67137, 0, 129614, 73648, 6730, 78862, 68161, 0, 78861, 126542, 0, 0, 94010, 118655, 0, 0, 66043, 0, 0, 43107, 0, 0, 92343, 0, 73879, 0, 0, @@ -27163,7 +27349,7 @@ static const unsigned int code_hash[] = { 0, 128273, 0, 0, 7379, 64581, 5386, 0, 0, 10633, 72316, 64488, 0, 0, 0, 0, 0, 0, 0, 0, 0, 124956, 71307, 0, 0, 0, 0, 0, 92370, 0, 0, 0, 0, 0, 71314, 1801, 0, 0, 120867, 0, 0, 77888, 2085, 702, 77887, 77884, 77885, - 13074, 77883, 66299, 0, 0, 12106, 0, 0, 1755, 0, 77897, 77898, 1163, + 13074, 77883, 66299, 0, 0, 12106, 78905, 0, 1755, 0, 77897, 77898, 1163, 3102, 77893, 77894, 0, 0, 0, 0, 69227, 0, 77901, 77902, 77899, 77900, 65171, 0, 0, 0, 70157, 0, 0, 0, 64846, 2908, 0, 11177, 64902, 64950, 0, 128740, 66906, 124959, 70499, 0, 0, 0, 64352, 0, 125031, 1007, 0, 9199, @@ -27183,70 +27369,71 @@ static const unsigned int code_hash[] = { 127233, 0, 0, 0, 92345, 68254, 983661, 77991, 0, 2724, 0, 0, 12313, 110619, 515, 119947, 119944, 119945, 119942, 119943, 119940, 119941, 119938, 8606, 4046, 4589, 4521, 0, 9141, 0, 0, 2741, 0, 0, 1370, 0, 0, 0, - 0, 0, 0, 66880, 0, 66003, 0, 64440, 0, 0, 69458, 0, 11593, 68669, 68666, - 68660, 0, 0, 2744, 72285, 68638, 0, 814, 0, 119962, 119963, 119960, - 119961, 101106, 43029, 119956, 11623, 119954, 11955, 119952, 119953, - 41986, 119951, 0, 120497, 4847, 110975, 0, 0, 0, 0, 1581, 64920, 93830, - 12954, 963, 110973, 110972, 110971, 110969, 5278, 110967, 68621, 92222, - 983451, 68625, 983449, 68617, 110960, 0, 101459, 101487, 110964, 110963, - 110962, 0, 0, 101464, 101483, 101463, 983440, 983437, 92648, 127379, 0, - 65137, 6483, 65392, 0, 4213, 129649, 41303, 0, 0, 0, 41306, 129751, 2698, - 0, 0, 0, 68396, 0, 41304, 824, 0, 78011, 72315, 78894, 74827, 78892, - 64804, 9820, 119820, 110985, 110976, 0, 6739, 0, 5481, 3490, 110978, - 110977, 71706, 69947, 67702, 9124, 12688, 119833, 101496, 0, 101495, - 119821, 119824, 67480, 42575, 101474, 101478, 119827, 101481, 101476, - 71087, 68658, 119946, 8025, 68630, 101490, 68675, 92445, 71097, 69613, 0, - 0, 0, 0, 983432, 2745, 11797, 110990, 983428, 9202, 983426, 983427, 0, 0, - 0, 10525, 5436, 74584, 110987, 110986, 121506, 43080, 121508, 121507, - 983417, 6246, 119958, 10921, 9723, 6777, 6776, 6775, 0, 0, 70287, 92384, - 0, 8669, 0, 0, 65093, 0, 78881, 2716, 0, 0, 11252, 101475, 68369, 0, - 11060, 12985, 2711, 78872, 78027, 78026, 7992, 0, 0, 42938, 78033, 78032, - 78877, 70724, 78029, 78028, 78031, 78030, 64535, 110998, 10130, 110996, - 0, 0, 111001, 111000, 127914, 983414, 78014, 5713, 110995, 7570, 110993, - 110992, 0, 11190, 129700, 9026, 0, 74864, 7547, 78891, 0, 10008, 10222, - 0, 129543, 9744, 0, 68809, 983410, 119656, 983408, 94070, 983406, 983407, - 983404, 9045, 78888, 4225, 78886, 78887, 68757, 78885, 78882, 78883, - 983399, 983400, 8405, 983398, 10423, 10359, 983393, 983394, 0, 129149, - 4215, 9789, 0, 4321, 12309, 983402, 41313, 0, 5368, 66886, 0, 0, 5366, 0, - 5372, 101482, 67512, 0, 7720, 7390, 2696, 0, 0, 8268, 0, 1790, 0, 0, - 118977, 0, 0, 0, 5376, 1835, 72313, 78704, 128089, 0, 0, 68655, 1180, 0, - 0, 0, 0, 119274, 0, 0, 9122, 118584, 11928, 0, 65283, 0, 101449, 5971, - 101448, 43500, 1268, 65097, 983219, 0, 101445, 0, 1427, 128440, 0, 5970, - 3431, 72299, 101439, 101435, 983386, 983387, 983384, 2738, 125066, 10455, - 0, 74026, 0, 4222, 6240, 0, 119013, 983391, 68377, 6248, 983375, 67815, - 983373, 917907, 92582, 0, 101453, 125215, 0, 2728, 65549, 64563, 101428, - 101425, 101429, 128145, 0, 10713, 7166, 119559, 2622, 101450, 0, 0, 0, - 8954, 0, 94008, 2632, 42617, 10108, 1011, 42852, 12080, 2709, 0, 5716, 0, - 0, 0, 0, 127100, 69378, 0, 9515, 127098, 66465, 6451, 0, 127097, 8918, - 983556, 0, 0, 19950, 0, 0, 0, 44003, 0, 64735, 0, 0, 0, 0, 983497, 74022, - 0, 128795, 68643, 67410, 0, 5721, 0, 0, 0, 121074, 11267, 983366, 66464, - 5720, 983365, 0, 4219, 5718, 8696, 5717, 122651, 983372, 983897, 983370, - 541, 983368, 983369, 119948, 119089, 68389, 983354, 119949, 56, 4216, - 10577, 0, 0, 77849, 69620, 983359, 983360, 66899, 983358, 0, 0, 67628, 0, - 0, 7086, 0, 67998, 67621, 0, 2734, 69616, 0, 67627, 118937, 0, 67625, 0, - 0, 0, 42593, 0, 128217, 0, 0, 119939, 0, 68180, 0, 0, 71104, 7442, 43665, - 359, 41253, 68392, 6239, 120599, 41256, 0, 67740, 111023, 111022, 111021, - 9346, 69660, 41254, 0, 43291, 78002, 0, 67491, 124993, 93841, 0, 0, 0, - 4368, 983502, 0, 68137, 0, 0, 41024, 0, 0, 121359, 121420, 0, 0, 0, 4223, - 0, 8574, 83502, 0, 0, 0, 118576, 0, 92718, 983636, 70432, 128323, 68382, - 0, 0, 0, 0, 0, 4144, 0, 83193, 6245, 0, 2732, 92644, 0, 0, 64558, 83501, - 0, 0, 0, 128005, 0, 0, 129652, 983148, 3097, 0, 0, 77996, 0, 0, 10863, - 111020, 111019, 111018, 0, 111015, 111014, 111013, 111012, 118964, 0, - 10216, 64293, 0, 0, 69393, 128331, 12325, 111010, 8717, 111008, 101413, - 0, 101380, 0, 8700, 0, 101382, 68363, 10426, 0, 71091, 10362, 0, 1715, - 101378, 0, 64918, 101409, 43278, 42635, 0, 0, 65275, 0, 0, 101319, 0, - 69746, 1607, 466, 118949, 0, 0, 127918, 6243, 983901, 1350, 74195, 64420, - 1993, 5362, 10666, 2708, 92471, 0, 13143, 234, 3199, 0, 41268, 6334, - 2173, 0, 0, 73750, 0, 73762, 10458, 0, 8576, 127136, 0, 2704, 64953, 0, - 64832, 8322, 0, 3132, 0, 2694, 0, 0, 2439, 65104, 69804, 0, 303, 74625, - 92622, 0, 2437, 0, 9817, 4844, 0, 0, 0, 0, 0, 121120, 43292, 0, 2441, 0, - 0, 0, 0, 0, 2451, 2714, 0, 0, 43379, 127984, 74541, 753, 5849, 0, 43089, - 0, 0, 119534, 72380, 0, 0, 0, 2726, 3107, 0, 0, 64937, 0, 78841, 1408, 0, - 4607, 101299, 181, 0, 67728, 9539, 0, 0, 65201, 121121, 92973, 64185, - 4142, 64183, 0, 0, 0, 9706, 64178, 64177, 64176, 0, 64182, 64181, 64180, - 64179, 11401, 125124, 0, 1822, 0, 128581, 68055, 3865, 122918, 0, 10500, - 129602, 119024, 0, 110732, 9830, 0, 0, 0, 65131, 0, 0, 0, 0, 74608, 7038, - 0, 9599, 8748, 0, 0, 9557, 0, 0, 0, 11494, 0, 0, 10865, 0, 43279, 64186, + 0, 0, 0, 66880, 0, 66003, 0, 64440, 0, 129943, 69458, 0, 11593, 68669, + 68666, 68660, 0, 0, 2744, 72285, 68638, 0, 814, 0, 119962, 119963, + 119960, 119961, 101106, 43029, 119956, 11623, 119954, 11955, 119952, + 119953, 41986, 119951, 0, 120497, 4847, 110975, 0, 0, 0, 0, 1581, 64920, + 93830, 12954, 963, 110973, 110972, 110971, 110969, 5278, 110967, 68621, + 92222, 983454, 68625, 983452, 68617, 110960, 0, 101459, 101487, 110964, + 110963, 110962, 0, 0, 101464, 101483, 101463, 983443, 983440, 92648, + 127379, 0, 65137, 6483, 65392, 0, 4213, 129649, 41303, 0, 0, 0, 41306, + 129751, 2698, 0, 0, 0, 68396, 0, 41304, 824, 0, 78011, 72315, 78894, + 74827, 78892, 64804, 9820, 119820, 110985, 110976, 0, 6739, 0, 5481, + 3490, 110978, 110977, 71706, 69947, 67702, 9124, 12688, 119833, 101496, + 0, 101495, 119821, 119824, 67480, 42575, 101474, 101478, 119827, 101481, + 101476, 71087, 68658, 119946, 8025, 68630, 101490, 68675, 92445, 71097, + 69613, 0, 0, 0, 0, 983435, 2745, 11797, 110990, 983431, 9202, 983429, + 983430, 0, 0, 0, 10525, 5436, 74584, 110987, 110986, 121506, 43080, + 121508, 121507, 983420, 6246, 119958, 10921, 9723, 6777, 6776, 6775, 0, + 0, 70287, 92384, 0, 8669, 0, 0, 65093, 0, 78881, 2716, 0, 0, 11252, + 101475, 68369, 0, 11060, 12985, 2711, 78872, 78027, 78026, 7992, 0, 0, + 42938, 78033, 78032, 78877, 70724, 78029, 78028, 78031, 78030, 64535, + 110998, 10130, 110996, 0, 0, 111001, 111000, 127914, 983417, 78014, 5713, + 110995, 7570, 110993, 110992, 0, 11190, 129700, 9026, 0, 74864, 7547, + 78891, 0, 10008, 10222, 0, 129543, 9744, 0, 68809, 983413, 119656, + 983411, 94070, 983409, 983410, 983407, 9045, 78888, 4225, 78886, 78887, + 68757, 78885, 78882, 78883, 983402, 983403, 8405, 983401, 10423, 10359, + 983396, 983397, 0, 129149, 4215, 9789, 0, 4321, 12309, 983405, 41313, 0, + 5368, 66886, 0, 0, 5366, 0, 5372, 101482, 67512, 0, 7720, 7390, 2696, 0, + 0, 8268, 0, 1790, 0, 0, 118977, 0, 0, 0, 5376, 1835, 72313, 78704, + 128089, 0, 0, 68655, 1180, 0, 0, 0, 0, 119274, 0, 0, 9122, 118584, 11928, + 0, 65283, 0, 101449, 5971, 101448, 43500, 1268, 65097, 983222, 0, 101445, + 0, 1427, 128440, 0, 5970, 3431, 72299, 101439, 101435, 983389, 983390, + 983387, 2738, 125066, 10455, 0, 74026, 0, 4222, 6240, 0, 119013, 983394, + 68377, 6248, 983378, 67815, 983376, 917907, 92582, 0, 101453, 125215, 0, + 2728, 65549, 64563, 101428, 101425, 101429, 128145, 0, 10713, 7166, + 119559, 2622, 101450, 0, 0, 0, 8954, 0, 94008, 2632, 42617, 10108, 1011, + 42852, 12080, 2709, 0, 5716, 0, 0, 0, 0, 127100, 69378, 0, 9515, 127098, + 66465, 6451, 0, 127097, 8918, 983556, 0, 0, 19950, 0, 0, 0, 44003, 0, + 64735, 0, 0, 0, 0, 983500, 74022, 0, 128795, 68643, 67410, 0, 5721, 0, 0, + 0, 121074, 11267, 983369, 66464, 5720, 983368, 0, 4219, 5718, 8696, 5717, + 122651, 983375, 983897, 983373, 541, 983371, 983372, 119948, 119089, + 68389, 983357, 119949, 56, 4216, 10577, 0, 0, 77849, 69620, 983362, + 983363, 66899, 983361, 0, 0, 67628, 0, 0, 7086, 0, 67998, 67621, 0, 2734, + 69616, 0, 67627, 118937, 0, 67625, 0, 0, 0, 42593, 0, 128217, 0, 0, + 119939, 0, 68180, 0, 0, 71104, 7442, 43665, 359, 41253, 68392, 6239, + 120599, 41256, 0, 67740, 111023, 111022, 111021, 9346, 69660, 41254, 0, + 43291, 78002, 0, 67491, 124993, 93841, 0, 0, 0, 4368, 983505, 0, 68137, + 0, 0, 41024, 0, 0, 121359, 121420, 0, 0, 0, 4223, 0, 8574, 83502, 0, 0, + 0, 118576, 0, 92718, 983636, 70432, 128323, 68382, 0, 0, 0, 0, 0, 4144, + 0, 83193, 6245, 0, 2732, 92644, 0, 0, 64558, 83501, 0, 0, 0, 128005, 0, + 0, 129652, 983149, 3097, 0, 0, 77996, 0, 0, 10863, 111020, 111019, + 111018, 0, 111015, 111014, 111013, 111012, 118964, 0, 10216, 64293, 0, 0, + 69393, 128331, 12325, 111010, 8717, 111008, 101413, 0, 101380, 0, 8700, + 0, 101382, 68363, 10426, 0, 71091, 10362, 0, 1715, 101378, 0, 64918, + 101409, 43278, 42635, 0, 0, 65275, 0, 0, 101319, 0, 69746, 1607, 466, + 118949, 0, 0, 127918, 6243, 983901, 1350, 74195, 64420, 1993, 5362, + 10666, 2708, 92471, 0, 13143, 234, 3199, 0, 41268, 6334, 2173, 0, 0, + 73750, 0, 73762, 10458, 0, 8576, 127136, 0, 2704, 64953, 0, 64832, 8322, + 0, 3132, 0, 2694, 0, 0, 2439, 65104, 69804, 0, 303, 74625, 92622, 0, + 2437, 0, 9817, 4844, 0, 0, 0, 0, 0, 121120, 43292, 0, 2441, 0, 0, 0, 0, + 0, 2451, 2714, 0, 0, 43379, 127984, 74541, 753, 5849, 0, 43089, 0, 0, + 119534, 72380, 0, 0, 0, 2726, 3107, 0, 0, 64937, 0, 78841, 1408, 0, 4607, + 101299, 181, 0, 67728, 9539, 0, 0, 65201, 121121, 92973, 64185, 4142, + 64183, 0, 0, 0, 9706, 64178, 64177, 64176, 0, 64182, 64181, 64180, 64179, + 11401, 125124, 0, 1822, 0, 128581, 68055, 3865, 122918, 0, 10500, 129602, + 119024, 0, 110732, 9830, 0, 0, 0, 65131, 0, 0, 0, 0, 74608, 7038, 0, + 9599, 8748, 0, 0, 9557, 0, 0, 0, 11494, 0, 0, 10865, 0, 43279, 64186, 68521, 0, 64191, 64190, 8898, 64188, 129153, 41030, 78836, 0, 0, 78820, 126100, 0, 78805, 78806, 78801, 78802, 6745, 78800, 0, 0, 0, 110866, 0, 0, 73679, 67838, 41039, 78809, 128162, 0, 129893, 0, 110869, 127045, @@ -27265,78 +27452,79 @@ static const unsigned int code_hash[] = { 0, 0, 0, 83484, 83485, 83486, 83487, 83480, 8355, 7854, 83483, 954, 64927, 0, 41045, 0, 41438, 0, 0, 10711, 0, 0, 0, 0, 64774, 13309, 10947, 66727, 101426, 0, 0, 66795, 0, 0, 0, 0, 0, 0, 0, 120634, 69228, 0, 0, 0, - 0, 0, 0, 3060, 83478, 9986, 0, 83473, 83474, 11698, 77880, 83469, 9916, - 11701, 83472, 42586, 0, 8320, 0, 119095, 0, 0, 1477, 43289, 0, 74358, - 10884, 69446, 9908, 0, 0, 0, 3414, 74304, 0, 0, 0, 0, 2110, 0, 68306, 0, - 74532, 0, 129865, 0, 0, 7164, 0, 0, 0, 11950, 5392, 42248, 65129, 68656, - 5397, 129579, 0, 68136, 0, 0, 5395, 72870, 5393, 354, 68615, 0, 0, 0, 0, - 0, 126236, 0, 0, 626, 0, 5895, 0, 0, 5780, 0, 66407, 10220, 0, 71121, - 43297, 0, 0, 11468, 64436, 0, 0, 0, 73818, 3918, 0, 3797, 72786, 0, 0, - 4140, 0, 71254, 0, 9030, 813, 0, 68131, 4146, 119957, 5360, 0, 129498, 0, - 0, 6249, 0, 0, 0, 0, 0, 73092, 0, 4911, 988, 0, 73125, 0, 42948, 0, 0, 0, - 0, 74972, 0, 0, 0, 9825, 0, 0, 12803, 126977, 11032, 67654, 6244, 0, 0, - 68662, 0, 129351, 0, 72131, 4169, 0, 0, 0, 129986, 121410, 120657, 0, 0, - 68657, 128943, 78496, 0, 0, 5898, 74540, 0, 41856, 93056, 194926, 118538, - 127373, 83424, 83425, 83426, 73736, 83420, 68870, 6448, 6835, 0, 4831, - 83418, 83419, 67731, 0, 0, 0, 0, 0, 0, 0, 78499, 0, 0, 0, 43288, 0, 0, 0, - 0, 0, 43418, 0, 0, 0, 7876, 68132, 917872, 0, 917870, 43378, 0, 0, - 120890, 5892, 43605, 0, 0, 0, 129058, 0, 0, 6251, 83409, 83410, 83411, - 83412, 126512, 0, 71092, 83408, 10114, 0, 0, 5387, 0, 0, 0, 0, 65553, - 78346, 1747, 917849, 65109, 69240, 917852, 126509, 0, 0, 0, 0, 125065, 0, - 9850, 0, 367, 1472, 917859, 6687, 0, 0, 5905, 12339, 8919, 73953, 65680, - 0, 2204, 78664, 0, 9134, 118589, 78666, 43011, 0, 126626, 0, 0, 0, 43013, - 10614, 0, 0, 83413, 66646, 83415, 83416, 0, 73881, 43012, 121127, 83293, - 54, 43009, 73885, 0, 6211, 0, 0, 83295, 68119, 43008, 10758, 0, 0, 0, 0, - 0, 70018, 0, 0, 0, 0, 12765, 0, 0, 0, 0, 126580, 0, 0, 43657, 0, 0, 0, - 983737, 0, 83405, 917843, 0, 0, 83401, 83402, 83403, 83404, 83397, 11363, - 12057, 83400, 1567, 0, 0, 83396, 0, 8957, 4139, 0, 0, 129336, 0, 0, - 12740, 0, 92195, 12761, 127793, 12759, 0, 72304, 67169, 83467, 44002, 0, - 83462, 83463, 83464, 12755, 12762, 41022, 67690, 64217, 476, 0, 983734, - 0, 64212, 41020, 1382, 64209, 64216, 64215, 64214, 64213, 0, 0, 0, 67584, - 8720, 3908, 0, 0, 0, 0, 101529, 129576, 0, 0, 3849, 92324, 94026, 9778, - 917906, 5891, 917912, 55, 917910, 917911, 0, 0, 7935, 67586, 0, 1114, - 92599, 67585, 78675, 0, 83447, 83449, 0, 0, 0, 64717, 0, 0, 0, 66884, - 6292, 65303, 0, 6452, 917886, 917887, 66249, 917885, 917890, 917891, - 917888, 719, 101446, 0, 917892, 0, 0, 0, 94083, 10868, 121333, 2349, - 5902, 917896, 6335, 101350, 917899, 917900, 0, 64369, 0, 0, 0, 69245, 0, + 0, 101430, 0, 3060, 83478, 9986, 0, 83473, 83474, 11698, 77880, 83469, + 9916, 11701, 83472, 42586, 0, 8320, 0, 119095, 0, 0, 1477, 43289, 0, + 74358, 10884, 69446, 9908, 0, 0, 0, 3414, 74304, 0, 0, 0, 0, 2110, 0, + 68306, 0, 74532, 0, 129865, 0, 0, 7164, 0, 0, 0, 11950, 5392, 42248, + 65129, 68656, 5397, 129579, 0, 68136, 0, 0, 5395, 72870, 5393, 354, + 68615, 0, 0, 0, 0, 0, 126236, 0, 0, 626, 0, 5895, 0, 0, 5780, 0, 66407, + 10220, 0, 71121, 43297, 0, 0, 11468, 64436, 0, 0, 0, 73818, 3918, 0, + 3797, 72786, 122961, 0, 4140, 0, 71254, 0, 9030, 813, 0, 68131, 4146, + 119957, 5360, 0, 129498, 0, 0, 6249, 0, 0, 0, 0, 0, 73092, 0, 4911, 988, + 0, 73125, 0, 42948, 0, 0, 0, 0, 74972, 0, 0, 0, 9825, 0, 0, 12803, + 126977, 11032, 67654, 6244, 0, 0, 68662, 0, 129351, 0, 72131, 4169, 0, 0, + 0, 129986, 121410, 120657, 0, 0, 68657, 128943, 78496, 0, 0, 5898, 74540, + 0, 41856, 93056, 194926, 118538, 127373, 83424, 83425, 83426, 73736, + 83420, 68870, 6448, 6835, 0, 4831, 83418, 83419, 67731, 0, 0, 0, 0, 0, 0, + 0, 78499, 0, 0, 0, 43288, 122931, 0, 0, 0, 0, 43418, 0, 0, 0, 7876, + 68132, 917872, 0, 917870, 43378, 0, 0, 120890, 5892, 43605, 0, 0, 0, + 129058, 0, 0, 6251, 83409, 83410, 83411, 83412, 126512, 0, 71092, 83408, + 10114, 0, 0, 5387, 0, 0, 0, 0, 65553, 78346, 1747, 917849, 65109, 69240, + 917852, 126509, 0, 0, 0, 0, 125065, 0, 9850, 0, 367, 1472, 917859, 6687, + 0, 0, 5905, 12339, 8919, 73953, 65680, 0, 2204, 78664, 0, 9134, 118589, + 78666, 43011, 0, 126626, 0, 0, 0, 43013, 10614, 0, 0, 83413, 66646, + 83415, 83416, 0, 73881, 43012, 121127, 83293, 54, 43009, 73885, 0, 6211, + 0, 0, 83295, 68119, 43008, 10758, 0, 0, 0, 0, 0, 70018, 0, 0, 0, 0, + 12765, 0, 0, 0, 0, 126580, 0, 0, 43657, 0, 0, 0, 983737, 0, 83405, + 917843, 0, 0, 83401, 83402, 83403, 83404, 83397, 11363, 12057, 83400, + 1567, 0, 0, 83396, 0, 8957, 4139, 0, 0, 129336, 0, 0, 12740, 0, 92195, + 12761, 127793, 12759, 0, 72304, 67169, 83467, 44002, 0, 83462, 83463, + 83464, 12755, 12762, 41022, 67690, 64217, 476, 0, 983734, 0, 64212, + 41020, 1382, 64209, 64216, 64215, 64214, 64213, 0, 0, 0, 67584, 8720, + 3908, 0, 0, 0, 0, 101529, 129576, 0, 0, 3849, 92324, 94026, 9778, 917906, + 5891, 917912, 55, 917910, 917911, 0, 0, 7935, 67586, 0, 1114, 92599, + 67585, 78675, 0, 83447, 83449, 0, 0, 0, 64717, 0, 0, 0, 66884, 6292, + 65303, 0, 6452, 917886, 917887, 66249, 917885, 917890, 917891, 917888, + 719, 101446, 0, 917892, 0, 0, 0, 94083, 10868, 121333, 2349, 5902, + 917896, 6335, 101350, 917899, 917900, 0, 64369, 0, 0, 0, 69245, 0, 126564, 0, 0, 128565, 0, 0, 0, 0, 0, 6454, 1229, 83457, 83458, 83450, 83451, 83452, 65100, 120508, 8224, 917873, 917874, 917879, 917880, 917877, 917878, 128929, 0, 917881, 917882, 5365, 67836, 8901, 0, 0, 129951, 0, 69257, 5925, 83436, 64330, 128400, 83431, 83432, 83433, 83434, 83427, 83428, 83429, 83430, 64928, 10543, 0, 0, 83446, 414, 0, 0, 83442, 6456, 71490, 83445, 11905, 83439, 66284, 83441, 0, 68337, 0, 83437, - 43832, 983139, 9751, 0, 128085, 11770, 0, 0, 69600, 65061, 0, 0, 0, 0, 0, + 43832, 983140, 9751, 0, 128085, 11770, 0, 0, 69600, 65061, 0, 0, 0, 0, 0, 0, 121087, 0, 0, 69924, 0, 0, 0, 69913, 0, 121387, 101513, 101504, 101512, 42038, 387, 0, 12737, 0, 0, 43368, 0, 0, 0, 0, 129713, 129449, 121295, 0, 69400, 127309, 0, 375, 0, 0, 0, 983905, 0, 0, 119202, 119203, - 0, 43120, 0, 0, 119196, 119197, 0, 4529, 119200, 119201, 119198, 119199, - 0, 0, 69698, 13150, 64492, 0, 0, 0, 0, 0, 42891, 66327, 74298, 0, 0, 0, - 2587, 42193, 0, 6455, 0, 4241, 0, 0, 0, 0, 0, 0, 0, 118821, 0, 0, 0, - 125030, 0, 128684, 129390, 6988, 5373, 0, 0, 119232, 10015, 0, 0, 0, + 124117, 43120, 0, 0, 119196, 119197, 0, 4529, 119200, 119201, 119198, + 119199, 0, 0, 69698, 13150, 64492, 0, 0, 0, 0, 0, 42891, 66327, 74298, 0, + 0, 0, 2587, 42193, 0, 6455, 0, 4241, 0, 0, 0, 0, 0, 0, 0, 118821, 0, 0, + 0, 125030, 0, 128684, 129390, 6988, 5373, 0, 0, 119232, 10015, 0, 0, 0, 68642, 0, 120855, 42040, 128827, 5779, 129841, 42037, 83282, 0, 0, 93040, 83283, 101116, 0, 101117, 6983, 0, 0, 101115, 0, 0, 0, 127323, 101111, 0, 119588, 0, 92495, 74558, 0, 68138, 70163, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 11144, 0, 2551, 0, 6453, 0, 6235, 0, 0, 129081, 72886, 44020, 11826, 0, - 7780, 5369, 118958, 0, 0, 5367, 66870, 0, 0, 5377, 0, 68143, 128624, - 78245, 5218, 0, 127333, 0, 0, 129717, 0, 0, 1300, 0, 127334, 64505, 0, 0, - 119624, 1465, 0, 127316, 0, 0, 0, 101109, 0, 113694, 10729, 0, 0, 8839, - 119243, 0, 7785, 126530, 0, 0, 0, 0, 118638, 0, 0, 0, 3897, 0, 92331, - 74417, 113704, 0, 68127, 71425, 70688, 0, 0, 0, 0, 69287, 3542, 0, - 120685, 7951, 68152, 118857, 0, 92972, 0, 0, 127311, 73683, 0, 65150, + 11144, 73484, 2551, 73482, 6453, 0, 6235, 0, 0, 129081, 72886, 44020, + 11826, 0, 7780, 5369, 118958, 0, 0, 5367, 66870, 0, 0, 5377, 0, 68143, + 128624, 78245, 5218, 0, 127333, 0, 0, 129717, 0, 0, 1300, 0, 127334, + 64505, 0, 0, 119624, 1465, 0, 127316, 0, 0, 0, 101109, 0, 113694, 10729, + 0, 0, 8839, 119243, 0, 7785, 126530, 0, 0, 0, 0, 118638, 0, 0, 0, 3897, + 0, 92331, 74417, 113704, 0, 68127, 71425, 70688, 0, 0, 0, 0, 69287, 3542, + 0, 120685, 7951, 68152, 118857, 0, 92972, 0, 0, 127311, 73683, 0, 65150, 68031, 0, 0, 0, 0, 9985, 0, 127328, 0, 0, 0, 0, 10830, 0, 615, 64490, 7574, 0, 0, 0, 12909, 73698, 64559, 127332, 73951, 0, 67996, 2020, 0, 0, 0, 120701, 0, 983640, 0, 0, 0, 92991, 0, 0, 9070, 0, 68411, 11281, 42829, - 0, 1033, 0, 0, 0, 118610, 0, 65226, 0, 0, 0, 0, 0, 3450, 0, 7397, 0, 0, - 42778, 10000, 41088, 449, 0, 0, 68458, 113725, 0, 0, 10738, 69634, 0, 0, - 41085, 0, 0, 0, 12764, 0, 93058, 3596, 7322, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1033, 0, 78918, 0, 118610, 0, 65226, 0, 0, 0, 0, 0, 3450, 0, 7397, 0, + 0, 42778, 10000, 41088, 449, 0, 0, 68458, 113725, 0, 0, 10738, 69634, 0, + 0, 41085, 0, 0, 0, 12764, 0, 93058, 3596, 7322, 0, 0, 0, 0, 0, 0, 0, 0, 2092, 0, 0, 0, 121350, 10820, 0, 0, 126567, 1853, 0, 0, 93014, 0, 12770, 0, 0, 124997, 0, 0, 0, 0, 0, 129053, 4828, 1258, 0, 2006, 0, 0, 74285, 127987, 0, 120683, 122880, 983900, 983903, 8846, 128255, 0, 128091, 2650, 9182, 1961, 121399, 11525, 0, 1959, 0, 55228, 11774, 41016, 0, 0, 128054, 41017, 13109, 0, 10519, 66331, 3454, 19930, 0, 41019, 92894, 0, 0, 78362, 41021, 101566, 0, 0, 0, 0, 65531, 0, 0, 0, 0, 0, 0, 8865, 6402, 113827, - 77923, 0, 101536, 0, 7733, 0, 4998, 68493, 0, 0, 0, 4268, 101368, 0, 0, - 101555, 101579, 10881, 0, 0, 0, 0, 2014, 0, 71901, 0, 0, 195057, 0, 0, + 77923, 0, 101536, 0, 7733, 0, 4998, 68493, 0, 78930, 0, 4268, 101368, 0, + 0, 101555, 101579, 10881, 0, 0, 0, 0, 2014, 0, 71901, 0, 0, 195057, 0, 0, 78357, 65281, 0, 0, 0, 0, 0, 2015, 0, 0, 71840, 66318, 74824, 101575, 0, 101574, 101569, 0, 70061, 8094, 10135, 101551, 0, 794, 0, 0, 66335, 0, 121303, 4343, 0, 4833, 0, 0, 0, 0, 189, 12611, 0, 72215, 0, 4838, 126214, @@ -27356,143 +27544,144 @@ static const unsigned int code_hash[] = { 0, 0, 121068, 92418, 0, 0, 0, 43280, 0, 70718, 1812, 0, 73046, 0, 0, 0, 0, 0, 6054, 10697, 3169, 0, 0, 70720, 11487, 70712, 0, 0, 0, 194716, 0, 0, 41863, 0, 0, 2304, 0, 92326, 0, 42951, 0, 0, 64760, 11766, 0, 0, 0, 0, - 69236, 0, 0, 8773, 10733, 36, 0, 0, 0, 0, 0, 11074, 0, 64910, 983130, - 2009, 0, 0, 128036, 68114, 128906, 0, 0, 0, 983998, 12852, 3031, 0, 0, - 129088, 0, 66414, 0, 0, 119950, 42613, 65933, 366, 0, 9892, 0, 11754, - 101107, 83329, 65301, 44013, 83058, 67245, 10102, 0, 7739, 41026, 0, 0, - 0, 0, 0, 0, 0, 0, 78386, 129475, 71868, 113811, 13081, 10923, 129330, 0, - 68145, 0, 65861, 74083, 0, 0, 128392, 83063, 83065, 0, 70706, 0, 0, 0, - 70168, 66586, 4183, 64967, 66250, 0, 92547, 0, 0, 113685, 0, 3792, 2011, - 0, 0, 77748, 83332, 77749, 120595, 0, 68489, 41023, 77747, 0, 11659, - 7922, 12614, 2005, 8523, 0, 0, 7513, 1863, 129436, 83337, 128969, 0, - 120274, 120033, 0, 8144, 0, 73031, 77767, 127524, 120270, 42241, 8783, - 77764, 77765, 77766, 77760, 77761, 77762, 77763, 0, 10680, 0, 43293, - 68771, 0, 119164, 83320, 72003, 10187, 77742, 77743, 0, 77737, 77738, - 77739, 0, 10968, 43296, 119044, 0, 0, 101400, 0, 1005, 43826, 120030, 0, - 2870, 0, 101399, 0, 0, 983798, 0, 235, 1384, 77758, 74887, 70494, 77754, - 77755, 9796, 69895, 77750, 77751, 77752, 13186, 120407, 120250, 0, 0, 0, - 42527, 12911, 43427, 1383, 983581, 0, 0, 0, 6156, 68117, 0, 7993, 4288, - 0, 0, 13238, 13244, 0, 0, 120426, 13234, 120427, 0, 118904, 0, 11364, 0, - 1380, 65617, 120253, 120261, 13196, 13197, 120311, 120419, 9495, 0, 0, - 120418, 0, 73976, 128160, 0, 6941, 0, 13205, 13211, 5801, 0, 74271, - 120319, 0, 120302, 7670, 0, 68075, 983583, 0, 19957, 72314, 2021, 93811, - 43877, 0, 0, 0, 0, 3875, 120431, 64341, 0, 9814, 43457, 13066, 3314, - 7787, 0, 0, 0, 0, 0, 0, 64531, 129860, 0, 0, 0, 0, 0, 127138, 0, 0, 9742, - 0, 0, 10800, 77718, 8404, 0, 92592, 77714, 7089, 77716, 78545, 0, 77712, - 77713, 0, 0, 4772, 5771, 101405, 0, 9841, 8843, 0, 0, 0, 129862, 120816, - 0, 123137, 0, 77735, 0, 0, 0, 77731, 8849, 77733, 77734, 65112, 1796, - 77729, 77730, 69665, 8164, 41301, 3502, 0, 122884, 128387, 0, 983835, - 5825, 0, 0, 0, 0, 121322, 10983, 10354, 10418, 0, 2022, 0, 1409, 100789, - 0, 0, 0, 0, 1390, 0, 0, 10471, 65904, 5846, 126472, 0, 0, 0, 0, 0, 0, - 66035, 77725, 0, 77726, 77720, 77721, 67458, 3168, 67733, 0, 0, 2370, 0, - 126243, 0, 195049, 0, 0, 1836, 0, 121207, 119137, 118959, 125232, 0, 0, - 0, 2390, 3944, 0, 0, 0, 0, 69908, 125011, 0, 0, 123200, 0, 0, 8975, - 64739, 0, 0, 0, 0, 64409, 0, 0, 0, 0, 128564, 0, 0, 0, 0, 6204, 0, 0, 0, - 10911, 64954, 119003, 74809, 118903, 4267, 0, 0, 0, 0, 0, 0, 72023, 0, 0, - 0, 92887, 0, 0, 0, 0, 121125, 0, 128337, 5842, 0, 41439, 0, 0, 0, 9328, - 0, 120980, 120917, 0, 0, 2285, 0, 0, 0, 0, 118634, 64555, 0, 0, 72162, - 9541, 0, 0, 0, 41441, 0, 0, 0, 41040, 2459, 0, 0, 41041, 0, 0, 0, 0, 0, - 10450, 0, 41043, 0, 0, 43125, 0, 0, 0, 0, 0, 121008, 68436, 128040, 0, - 120649, 0, 0, 4312, 43927, 0, 0, 11923, 42227, 0, 5763, 0, 4827, 74559, - 42228, 64406, 0, 0, 129703, 433, 119620, 0, 2499, 67167, 67166, 0, 11973, - 0, 4293, 42271, 42224, 0, 0, 66322, 42226, 0, 0, 0, 74180, 0, 55277, 0, - 0, 0, 119317, 0, 74632, 0, 0, 71103, 0, 0, 0, 585, 2383, 0, 43263, 0, - 4290, 64842, 0, 68920, 0, 8511, 0, 0, 0, 119048, 2380, 126119, 0, 71704, - 2376, 0, 0, 0, 5197, 127046, 127047, 127048, 2366, 127050, 127051, 73442, - 0, 0, 0, 93835, 0, 93818, 0, 0, 74188, 113813, 0, 0, 0, 983838, 0, 0, 0, - 0, 1847, 0, 72771, 0, 42384, 0, 4227, 74158, 0, 92501, 0, 0, 42365, 0, - 128902, 0, 92821, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128563, 0, 983506, 127560, - 2754, 0, 0, 128900, 0, 127867, 119638, 0, 1711, 12984, 92365, 77776, - 6255, 77770, 77771, 77772, 77773, 0, 42063, 74184, 0, 0, 0, 0, 0, 77785, - 77786, 41035, 43274, 77781, 11256, 77783, 77784, 520, 77778, 41037, - 77780, 0, 0, 41034, 0, 983829, 64815, 0, 0, 321, 41028, 0, 0, 0, 0, 0, 0, - 0, 74191, 0, 0, 72767, 1861, 118938, 129666, 0, 0, 100770, 0, 0, 128530, - 3859, 0, 41660, 0, 70793, 0, 983756, 75014, 0, 127514, 41658, 0, 0, 0, 0, - 0, 4414, 77769, 0, 42632, 0, 0, 0, 0, 0, 1405, 0, 43220, 43341, 0, 0, 0, - 0, 0, 983733, 11199, 0, 3513, 0, 70341, 43342, 0, 65529, 0, 0, 0, 6485, - 1397, 0, 0, 92678, 118566, 0, 0, 82961, 0, 82962, 0, 74270, 43287, - 983731, 0, 0, 983738, 0, 71914, 4317, 10490, 0, 0, 194867, 74463, 128952, - 464, 41624, 0, 0, 0, 1346, 128240, 69271, 64724, 128566, 423, 0, 0, - 113748, 0, 128161, 0, 0, 120563, 64960, 0, 0, 0, 0, 9584, 77795, 77796, - 125026, 0, 9718, 77792, 42642, 77794, 64750, 77789, 77790, 0, 0, 128333, - 0, 3204, 64666, 0, 43530, 2752, 0, 0, 119594, 0, 0, 0, 0, 92371, 0, - 41983, 0, 7010, 0, 0, 41495, 92379, 5877, 42252, 93070, 8009, 3305, 0, 0, - 0, 0, 92293, 0, 0, 0, 100836, 0, 65915, 1400, 75018, 10685, 75017, 2103, - 122908, 0, 43276, 0, 11169, 0, 6481, 0, 0, 0, 100837, 72249, 100838, - 74198, 0, 9116, 0, 0, 0, 0, 0, 0, 8129, 92994, 0, 124992, 0, 11658, 0, 0, - 3452, 41031, 0, 1385, 0, 0, 0, 43340, 11123, 41033, 6493, 12758, 0, 0, - 11426, 0, 1681, 100755, 1204, 11960, 69902, 0, 69457, 0, 119322, 129483, - 7415, 43338, 0, 0, 67717, 64915, 0, 100759, 72021, 41497, 65044, 0, - 19960, 65358, 983601, 0, 0, 0, 73670, 0, 1789, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 64728, 0, 0, 0, 6506, 64312, 0, 2368, 0, 0, 0, 0, 3439, 1825, 1192, 0, - 73739, 10639, 0, 7790, 5430, 0, 0, 2848, 92981, 0, 0, 7607, 0, 0, 0, - 120658, 0, 0, 8883, 0, 728, 0, 0, 0, 0, 92931, 0, 121372, 128348, 0, - 68078, 8091, 11447, 0, 0, 126261, 983729, 0, 70003, 0, 0, 74419, 12335, - 0, 0, 3443, 0, 0, 0, 127145, 0, 0, 0, 0, 11843, 0, 9205, 8624, 128543, - 92930, 43295, 0, 65445, 0, 6277, 41672, 0, 10010, 70186, 983052, 0, 835, - 71340, 0, 0, 0, 0, 0, 5426, 4258, 0, 64891, 5424, 0, 8283, 0, 5434, 0, 0, - 0, 0, 0, 11947, 0, 1404, 0, 11432, 0, 3464, 6486, 4819, 0, 0, 570, 8095, - 0, 0, 1498, 0, 0, 0, 431, 67820, 0, 120574, 128096, 0, 0, 13096, 0, 0, - 43408, 0, 128538, 8835, 77875, 0, 0, 0, 0, 0, 0, 0, 0, 3477, 227, 10488, - 0, 382, 11418, 0, 5878, 0, 0, 0, 0, 6484, 92355, 66039, 0, 0, 0, 78717, - 0, 92662, 119665, 0, 0, 43290, 0, 0, 0, 0, 8782, 0, 0, 4323, 128649, 0, - 120903, 12094, 67499, 0, 0, 0, 92953, 3856, 120970, 0, 5872, 6495, 72306, - 0, 0, 0, 67173, 67172, 67171, 3953, 0, 0, 93063, 11994, 4339, 0, 92654, - 0, 0, 0, 0, 128804, 0, 5228, 0, 9766, 0, 92741, 0, 0, 0, 0, 68860, 0, - 1162, 0, 2671, 0, 73666, 92632, 92631, 72117, 0, 73811, 0, 194895, 0, - 68085, 0, 74331, 11424, 0, 10466, 121239, 0, 194890, 0, 4820, 0, 0, 0, - 194891, 0, 119212, 4896, 0, 4897, 42821, 64611, 0, 4438, 0, 0, 1753, - 11331, 6147, 0, 43282, 8833, 0, 0, 6504, 0, 0, 0, 118670, 0, 1413, 0, 0, - 64353, 12141, 121138, 0, 0, 43163, 0, 72880, 64789, 127094, 838, 127092, - 120697, 127090, 5014, 0, 256, 0, 0, 42443, 42739, 0, 7542, 0, 70389, 0, - 6489, 10048, 74326, 0, 66573, 0, 125271, 78712, 11761, 126078, 129603, - 41094, 0, 0, 0, 0, 92689, 8453, 0, 0, 120942, 128184, 0, 11816, 0, 0, - 2930, 93845, 0, 41098, 92771, 41093, 0, 0, 6498, 41096, 0, 0, 1238, 200, - 0, 1660, 74476, 0, 0, 74362, 0, 0, 72301, 9224, 0, 0, 0, 0, 0, 0, 0, 0, + 69236, 119171, 0, 8773, 10733, 36, 0, 0, 0, 0, 0, 11074, 0, 64910, + 983131, 2009, 0, 0, 128036, 68114, 128906, 0, 0, 0, 983998, 12852, 3031, + 0, 0, 129088, 0, 66414, 0, 0, 119950, 42613, 65933, 366, 0, 9892, 0, + 11754, 101107, 83329, 65301, 44013, 83058, 67245, 10102, 0, 7739, 41026, + 0, 0, 0, 0, 0, 0, 0, 0, 78386, 129475, 71868, 113811, 13081, 10923, + 129330, 0, 68145, 0, 65861, 74083, 0, 0, 128392, 83063, 83065, 0, 70706, + 0, 0, 0, 70168, 66586, 4183, 64967, 66250, 0, 92547, 0, 0, 113685, 0, + 3792, 2011, 0, 0, 77748, 83332, 77749, 120595, 0, 68489, 41023, 77747, 0, + 11659, 7922, 12614, 2005, 8523, 129880, 0, 7513, 1863, 129436, 83337, + 128969, 0, 120274, 120033, 0, 8144, 0, 73031, 77767, 127524, 120270, + 42241, 8783, 77764, 77765, 77766, 77760, 77761, 77762, 77763, 0, 10680, + 0, 43293, 68771, 0, 119164, 83320, 72003, 10187, 77742, 77743, 0, 77737, + 77738, 77739, 0, 10968, 43296, 119044, 0, 0, 101400, 0, 1005, 43826, + 120030, 0, 2870, 0, 101399, 0, 0, 983798, 0, 235, 1384, 77758, 74887, + 70494, 77754, 77755, 9796, 69895, 77750, 77751, 77752, 13186, 120407, + 120250, 0, 0, 0, 42527, 12911, 43427, 1383, 983581, 0, 0, 0, 6156, 68117, + 0, 7993, 4288, 0, 0, 13238, 13244, 0, 0, 120426, 13234, 120427, 0, + 118904, 0, 11364, 0, 1380, 65617, 120253, 120261, 13196, 13197, 120311, + 120419, 9495, 0, 0, 120418, 0, 73976, 128160, 0, 6941, 0, 13205, 13211, + 5801, 0, 74271, 120319, 0, 120302, 7670, 0, 68075, 983583, 0, 19957, + 72314, 2021, 93811, 43877, 0, 0, 0, 0, 3875, 120431, 64341, 0, 9814, + 43457, 13066, 3314, 7787, 0, 0, 0, 0, 0, 0, 64531, 129860, 0, 0, 0, 0, 0, + 127138, 0, 0, 9742, 0, 0, 10800, 77718, 8404, 0, 92592, 77714, 7089, + 77716, 78545, 0, 77712, 77713, 0, 0, 4772, 5771, 101405, 0, 9841, 8843, + 0, 0, 0, 129862, 120816, 0, 123137, 0, 77735, 0, 0, 0, 77731, 8849, + 77733, 77734, 65112, 1796, 77729, 77730, 69665, 8164, 41301, 3502, 0, + 122884, 128387, 0, 983835, 5825, 0, 0, 0, 0, 121322, 10983, 10354, 10418, + 0, 2022, 0, 1409, 100789, 0, 0, 0, 0, 1390, 0, 0, 10471, 65904, 5846, + 126472, 0, 0, 0, 0, 0, 0, 66035, 77725, 0, 77726, 77720, 77721, 67458, + 3168, 67733, 0, 0, 2370, 0, 126243, 0, 195049, 0, 0, 1836, 0, 121207, + 119137, 118959, 125232, 0, 0, 0, 2390, 3944, 0, 0, 0, 0, 69908, 125011, + 0, 0, 123200, 0, 0, 8975, 64739, 0, 0, 0, 0, 64409, 0, 0, 0, 0, 128564, + 0, 0, 0, 0, 6204, 0, 0, 0, 10911, 64954, 119003, 74809, 118903, 4267, 0, + 0, 0, 0, 0, 0, 72023, 0, 0, 119504, 92887, 0, 0, 0, 0, 121125, 0, 128337, + 5842, 0, 41439, 0, 0, 0, 9328, 0, 120980, 120917, 0, 0, 2285, 0, 0, 0, 0, + 118634, 64555, 0, 0, 72162, 9541, 0, 0, 0, 41441, 0, 0, 0, 41040, 2459, + 0, 0, 41041, 0, 0, 0, 0, 0, 10450, 0, 41043, 0, 0, 43125, 0, 0, 0, 0, 0, + 121008, 68436, 128040, 0, 120649, 0, 0, 4312, 43927, 0, 0, 11923, 42227, + 0, 5763, 0, 4827, 74559, 42228, 64406, 0, 0, 129703, 433, 119620, 0, + 2499, 67167, 67166, 0, 11973, 0, 4293, 42271, 42224, 0, 0, 66322, 42226, + 0, 0, 0, 74180, 0, 55277, 0, 0, 0, 119317, 0, 74632, 0, 0, 71103, 0, 0, + 0, 585, 2383, 0, 43263, 0, 4290, 64842, 0, 68920, 0, 8511, 0, 0, 0, + 119048, 2380, 126119, 0, 71704, 2376, 0, 0, 0, 5197, 127046, 127047, + 127048, 2366, 127050, 127051, 73442, 0, 0, 0, 93835, 0, 93818, 0, 0, + 74188, 113813, 0, 0, 0, 983838, 0, 0, 0, 0, 1847, 0, 72771, 0, 42384, 0, + 4227, 74158, 0, 92501, 0, 0, 42365, 0, 128902, 0, 92821, 0, 0, 0, 0, 0, + 0, 0, 0, 122934, 128563, 0, 983509, 127560, 2754, 0, 0, 128900, 0, + 127867, 119638, 0, 1711, 12984, 92365, 77776, 6255, 77770, 77771, 77772, + 77773, 0, 42063, 74184, 0, 0, 0, 0, 0, 77785, 77786, 41035, 43274, 77781, + 11256, 77783, 77784, 520, 77778, 41037, 77780, 0, 0, 41034, 0, 983829, + 64815, 0, 0, 321, 41028, 0, 0, 0, 0, 0, 0, 0, 74191, 0, 0, 72767, 1861, + 118938, 129666, 0, 0, 100770, 0, 0, 128530, 3859, 0, 41660, 0, 70793, 0, + 983756, 75014, 0, 127514, 41658, 0, 0, 0, 0, 0, 4414, 77769, 0, 42632, 0, + 0, 0, 0, 0, 1405, 0, 43220, 43341, 0, 0, 0, 0, 0, 983733, 11199, 0, 3513, + 0, 70341, 43342, 0, 65529, 0, 0, 0, 6485, 1397, 0, 0, 92678, 118566, + 124137, 0, 82961, 0, 82962, 0, 74270, 43287, 983731, 0, 0, 983738, 0, + 71914, 4317, 10490, 0, 0, 194867, 74463, 128952, 464, 41624, 0, 0, 0, + 1346, 128240, 69271, 64724, 128566, 423, 0, 0, 113748, 0, 128161, 0, 0, + 120563, 64960, 0, 0, 0, 0, 9584, 77795, 77796, 78927, 0, 9718, 77792, + 42642, 77794, 64750, 77789, 77790, 0, 0, 128333, 0, 3204, 64666, 0, + 43530, 2752, 0, 0, 119594, 0, 0, 0, 0, 92371, 0, 41983, 0, 7010, 0, 0, + 41495, 92379, 5877, 42252, 93070, 8009, 3305, 0, 0, 0, 0, 92293, 0, 0, 0, + 100836, 0, 65915, 1400, 75018, 10685, 75017, 2103, 122908, 0, 43276, 0, + 11169, 0, 6481, 0, 0, 0, 100837, 72249, 100838, 74198, 0, 9116, 0, 0, 0, + 0, 0, 0, 8129, 92994, 0, 124992, 0, 11658, 0, 0, 3452, 41031, 0, 1385, 0, + 100754, 0, 43340, 11123, 41033, 6493, 12758, 0, 0, 11426, 0, 1681, + 100755, 1204, 11960, 69902, 0, 69457, 0, 119322, 129483, 7415, 43338, 0, + 0, 67717, 64915, 0, 100759, 72021, 41497, 65044, 0, 19960, 65358, 983601, + 0, 0, 0, 73670, 0, 1789, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64728, 0, 0, 0, + 6506, 64312, 0, 2368, 0, 0, 0, 0, 3439, 1825, 1192, 0, 73739, 10639, 0, + 7790, 5430, 0, 0, 2848, 92981, 0, 0, 7607, 0, 0, 0, 120658, 0, 0, 8883, + 0, 728, 0, 0, 0, 0, 92931, 0, 121372, 128348, 0, 68078, 8091, 11447, 0, + 0, 126261, 983729, 0, 70003, 0, 0, 74419, 12335, 0, 0, 3443, 0, 0, 0, + 127145, 0, 0, 0, 0, 11843, 0, 9205, 8624, 128543, 92930, 43295, 0, 65445, + 0, 6277, 41672, 0, 10010, 70186, 983052, 0, 835, 71340, 0, 0, 0, 0, 0, + 5426, 4258, 0, 64891, 5424, 0, 8283, 0, 5434, 0, 0, 0, 0, 0, 11947, 0, + 1404, 0, 11432, 0, 3464, 6486, 4819, 0, 0, 570, 8095, 0, 0, 1498, 0, 0, + 0, 431, 67820, 0, 120574, 128096, 0, 0, 13096, 0, 0, 43408, 0, 128538, + 8835, 77875, 0, 0, 122973, 0, 0, 0, 0, 0, 3477, 227, 10488, 0, 382, + 11418, 0, 5878, 0, 0, 0, 0, 6484, 92355, 66039, 0, 0, 0, 78717, 0, 92662, + 119665, 0, 0, 43290, 0, 0, 0, 0, 8782, 0, 0, 4323, 128649, 0, 120903, + 12094, 67499, 0, 0, 0, 92953, 3856, 120970, 124138, 5872, 6495, 72306, 0, + 0, 0, 67173, 67172, 67171, 3953, 0, 0, 93063, 11994, 4339, 0, 92654, 0, + 0, 0, 0, 128804, 0, 5228, 0, 9766, 0, 92741, 0, 0, 0, 0, 68860, 0, 1162, + 0, 2671, 0, 73666, 92632, 92631, 72117, 0, 73811, 0, 194895, 0, 68085, 0, + 74331, 11424, 0, 10466, 121239, 0, 194890, 0, 4820, 0, 0, 0, 194891, 0, + 119212, 4896, 0, 4897, 42821, 64611, 0, 4438, 0, 0, 1753, 11331, 6147, 0, + 43282, 8833, 0, 0, 6504, 0, 0, 0, 118670, 0, 1413, 0, 0, 64353, 12141, + 121138, 0, 0, 43163, 0, 72880, 64789, 127094, 838, 127092, 120697, + 127090, 5014, 0, 256, 0, 0, 42443, 42739, 0, 7542, 0, 70389, 0, 6489, + 10048, 74326, 0, 66573, 0, 125271, 78712, 11761, 126078, 129603, 41094, + 0, 0, 0, 0, 92689, 8453, 0, 0, 120942, 128184, 0, 11816, 0, 0, 2930, + 93845, 0, 41098, 92771, 41093, 0, 0, 6498, 41096, 0, 0, 1238, 200, 0, + 1660, 74476, 0, 0, 74362, 0, 0, 72301, 9224, 0, 0, 0, 0, 0, 0, 0, 0, 72729, 43284, 0, 72110, 67459, 13183, 0, 0, 0, 1669, 10776, 0, 0, 0, 0, 0, 1732, 4030, 0, 3963, 0, 0, 0, 6491, 0, 0, 914, 121394, 0, 0, 0, 78713, 0, 92441, 74367, 42960, 0, 0, 0, 0, 0, 0, 0, 65537, 0, 0, 43430, 5301, 0, 92618, 0, 43285, 0, 0, 125186, 0, 0, 5876, 0, 69555, 0, 0, 110713, 0, 0, - 0, 0, 0, 0, 11114, 74536, 0, 0, 0, 0, 983129, 0, 0, 0, 0, 10915, 983069, + 0, 0, 0, 0, 11114, 74536, 0, 0, 0, 0, 983130, 0, 0, 0, 0, 10915, 983069, 12007, 0, 0, 0, 0, 67655, 92604, 0, 8629, 0, 43168, 41872, 0, 0, 0, 42488, 0, 0, 0, 0, 0, 64730, 70041, 0, 122895, 0, 0, 0, 92306, 11416, 4280, 128516, 8765, 73451, 0, 1393, 0, 11157, 74386, 0, 0, 0, 0, 6683, 0, - 93832, 12144, 0, 74513, 13019, 74994, 0, 0, 0, 983269, 0, 6488, 357, 0, + 93832, 12144, 0, 74513, 13019, 74994, 0, 0, 0, 983272, 0, 6488, 357, 0, 41100, 0, 41104, 0, 41099, 0, 71320, 0, 0, 0, 4434, 0, 0, 0, 74231, 83107, 0, 194914, 0, 0, 72286, 68305, 0, 41759, 12757, 0, 0, 72769, 9790, - 7674, 0, 121095, 68209, 0, 41764, 0, 0, 72322, 2268, 0, 129845, 0, 12743, - 0, 6480, 0, 41779, 0, 66601, 0, 74490, 10986, 66602, 0, 64807, 0, 0, - 41767, 119629, 0, 0, 0, 3955, 64571, 194918, 127089, 0, 70187, 69975, - 9770, 12305, 12230, 0, 78579, 0, 0, 74752, 0, 0, 123168, 128263, 74449, + 7674, 0, 121095, 68209, 0, 41764, 0, 0, 72322, 2268, 0, 129845, 983608, + 12743, 0, 6480, 0, 41779, 0, 66601, 0, 74490, 10986, 66602, 0, 64807, 0, + 0, 41767, 119629, 0, 0, 0, 3955, 64571, 194918, 127089, 0, 70187, 69975, + 9770, 12305, 12230, 0, 73551, 0, 0, 74752, 0, 0, 123168, 128263, 74449, 0, 65948, 69611, 0, 0, 71131, 129505, 78573, 0, 0, 11116, 0, 5747, 0, 110667, 9802, 41092, 120731, 0, 0, 0, 0, 0, 120733, 41090, 0, 0, 0, - 11271, 57, 0, 0, 983241, 0, 71268, 121290, 43137, 0, 0, 110672, 126221, + 11271, 57, 0, 0, 983244, 0, 71268, 121290, 43137, 0, 0, 110672, 126221, 0, 0, 0, 0, 0, 277, 74385, 0, 0, 0, 72155, 0, 13025, 8757, 0, 0, 1574, 0, 126124, 100800, 0, 5749, 129923, 0, 42824, 0, 1039, 9801, 0, 5745, 0, - 41858, 0, 0, 120655, 0, 41862, 0, 0, 0, 436, 4771, 118635, 42501, 0, - 10573, 0, 0, 118560, 917986, 9644, 0, 0, 0, 0, 69837, 0, 0, 0, 0, 67409, - 0, 0, 0, 125204, 11939, 0, 0, 0, 0, 0, 0, 0, 3504, 0, 0, 92854, 126209, - 0, 10226, 65558, 0, 3594, 0, 0, 40, 0, 0, 0, 0, 0, 74312, 72138, 74337, - 0, 69577, 0, 0, 0, 70476, 0, 121143, 72317, 0, 0, 4304, 0, 0, 78707, 0, - 0, 0, 78597, 1348, 78596, 0, 0, 0, 70406, 92392, 0, 7599, 0, 0, 13269, 0, - 129729, 0, 100804, 0, 74494, 6097, 7568, 43980, 4982, 78592, 0, 0, 0, 0, - 13270, 0, 128090, 13138, 0, 9484, 0, 0, 71364, 0, 0, 0, 9487, 0, 92913, - 0, 71911, 78668, 73963, 6193, 0, 0, 0, 194848, 7228, 10011, 194849, - 194852, 194851, 11654, 194853, 126218, 194855, 0, 194857, 3604, 0, 0, 0, - 0, 0, 94110, 43740, 94109, 194860, 194863, 66750, 121021, 0, 94111, 6995, - 74173, 5437, 74174, 0, 8702, 7339, 129981, 0, 199, 194843, 194846, - 194845, 0, 126069, 0, 67818, 0, 7560, 0, 0, 0, 0, 6472, 65814, 0, 128983, - 70845, 0, 0, 9191, 0, 0, 0, 0, 124904, 10196, 0, 0, 6585, 0, 120750, 0, - 0, 71872, 129129, 0, 0, 78590, 72308, 11382, 129499, 0, 983670, 0, - 194833, 194832, 2165, 129540, 94020, 194836, 42727, 194838, 128252, - 78585, 43874, 119610, 0, 0, 43248, 0, 194816, 0, 194818, 128845, 194820, - 127879, 5297, 194821, 13284, 6112, 93964, 93010, 73927, 42947, 0, 65746, - 0, 0, 194827, 194826, 4342, 42839, 194831, 1677, 0, 72135, 0, 0, 0, - 11011, 66399, 0, 0, 0, 10160, 0, 0, 0, 0, 2052, 4308, 92174, 43000, - 118659, 543, 64916, 0, 0, 0, 119170, 0, 118922, 2064, 0, 43158, 0, 0, - 69984, 0, 0, 129187, 0, 0, 0, 0, 41631, 92728, 0, 0, 6228, 0, 0, 0, 0, 0, - 0, 506, 0, 0, 65735, 2055, 43255, 121407, 0, 0, 0, 0, 0, 0, 194666, 2063, - 0, 0, 0, 0, 72136, 0, 74333, 194912, 11827, 74308, 194913, 194916, + 41858, 0, 0, 120655, 0, 41862, 0, 0, 78822, 436, 4771, 118635, 42501, 0, + 10573, 0, 77931, 118560, 917986, 9644, 0, 0, 0, 0, 69837, 0, 0, 0, 0, + 67409, 0, 0, 0, 125204, 11939, 0, 0, 0, 0, 0, 0, 0, 3504, 0, 0, 92854, + 126209, 0, 10226, 65558, 0, 3594, 0, 0, 40, 0, 0, 0, 0, 0, 74312, 72138, + 74337, 0, 69577, 0, 0, 0, 70476, 0, 121143, 72317, 0, 0, 4304, 0, 0, + 78707, 0, 0, 0, 78597, 1348, 78596, 0, 0, 0, 70406, 92392, 0, 7599, 0, 0, + 13269, 0, 129729, 0, 100804, 0, 74494, 6097, 7568, 43980, 4982, 78592, 0, + 0, 0, 0, 13270, 0, 128090, 13138, 0, 9484, 0, 0, 71364, 0, 0, 0, 9487, 0, + 92913, 0, 71911, 78668, 73963, 6193, 0, 0, 0, 194848, 7228, 10011, + 194849, 194852, 194851, 11654, 194853, 126218, 194855, 0, 194857, 3604, + 0, 0, 0, 0, 0, 94110, 43740, 94109, 194860, 194863, 66750, 121021, 0, + 94111, 6995, 74173, 5437, 74174, 0, 8702, 7339, 129981, 0, 199, 194843, + 194846, 194845, 0, 126069, 0, 67818, 0, 7560, 0, 0, 0, 0, 6472, 65814, 0, + 128983, 70845, 0, 0, 9191, 0, 0, 0, 0, 124904, 10196, 0, 72452, 6585, 0, + 120750, 0, 0, 71872, 129129, 0, 0, 78590, 72308, 11382, 129499, 0, + 983670, 0, 194833, 194832, 2165, 129540, 94020, 194836, 42727, 194838, + 128252, 78585, 43874, 119610, 0, 0, 43248, 0, 194816, 0, 194818, 128845, + 194820, 127879, 5297, 194821, 13284, 6112, 93964, 93010, 73927, 42947, 0, + 65746, 0, 0, 194827, 194826, 4342, 42839, 194831, 1677, 0, 72135, 0, 0, + 0, 11011, 66399, 0, 0, 0, 10160, 0, 0, 0, 0, 2052, 4308, 92174, 43000, + 118659, 543, 64916, 122964, 0, 0, 119170, 0, 118922, 2064, 0, 43158, 0, + 0, 69984, 0, 0, 129187, 0, 0, 0, 0, 41631, 92728, 0, 0, 6228, 0, 0, 0, 0, + 0, 0, 506, 0, 0, 65735, 2055, 43255, 121407, 0, 0, 0, 0, 0, 0, 194666, + 2063, 0, 0, 0, 0, 72136, 0, 74333, 194912, 11827, 74308, 194913, 194916, 194915, 64564, 194917, 67986, 194919, 0, 11037, 0, 121102, 0, 0, 10560, 0, 120756, 194922, 113737, 194924, 194927, 120495, 1931, 0, 0, 0, 128228, 0, 12643, 8751, 123629, 0, 12294, 0, 78834, 9138, 78831, 78833, 12631, @@ -27511,7 +27700,7 @@ static const unsigned int code_hash[] = { 94042, 0, 8373, 41989, 69507, 73460, 3418, 3263, 0, 0, 0, 3270, 64539, 11489, 0, 118945, 126220, 0, 127795, 0, 94031, 0, 0, 0, 0, 0, 70512, 983983, 186, 0, 119156, 5770, 13179, 0, 12612, 12949, 64856, 12800, 0, 0, - 983151, 11507, 0, 0, 118929, 0, 0, 72141, 0, 73459, 0, 0, 0, 73461, 9254, + 983152, 11507, 0, 0, 118929, 0, 0, 72141, 0, 73459, 0, 0, 0, 73461, 9254, 66877, 194907, 0, 92338, 5624, 126253, 0, 0, 0, 120472, 120464, 0, 0, 122915, 120462, 0, 1872, 66508, 120467, 41079, 0, 5502, 119330, 41078, 194906, 0, 0, 4511, 68449, 0, 0, 0, 0, 43245, 41083, 68861, 0, 0, 9003, @@ -27538,7 +27727,7 @@ static const unsigned int code_hash[] = { 120188, 0, 9137, 0, 0, 0, 0, 3466, 0, 0, 1996, 0, 3453, 3412, 0, 2002, 2000, 120176, 0, 0, 0, 0, 1998, 0, 1842, 7037, 0, 9628, 68446, 0, 9826, 64502, 1767, 3413, 0, 0, 0, 0, 0, 0, 13108, 44024, 120204, 0, 92693, 0, - 0, 0, 70291, 12650, 983208, 0, 68061, 0, 3592, 0, 0, 0, 0, 983975, 0, + 0, 0, 70291, 12650, 983210, 0, 68061, 0, 3592, 0, 0, 0, 0, 983975, 0, 66417, 128792, 10742, 0, 0, 1994, 9281, 3296, 64475, 1997, 1895, 128936, 43024, 0, 0, 123184, 72391, 0, 8999, 0, 983633, 0, 66480, 0, 0, 0, 983083, 0, 596, 0, 0, 120216, 8651, 120217, 0, 0, 12995, 0, 0, 70740, 0, @@ -27571,9 +27760,9 @@ static const unsigned int code_hash[] = { 69816, 0, 118796, 0, 8708, 0, 64077, 64076, 8996, 4992, 4471, 83343, 64079, 64078, 92179, 0, 0, 123540, 64615, 0, 0, 12075, 42041, 0, 0, 0, 0, 127557, 3123, 0, 983754, 0, 0, 0, 83328, 0, 9223, 0, 83321, 83322, 73797, - 83327, 1116, 0, 83319, 7136, 0, 0, 0, 0, 75031, 0, 0, 0, 64092, 43675, - 10104, 83338, 83331, 64095, 64094, 8111, 66247, 0, 64089, 64088, 0, - 70106, 42236, 11434, 64083, 64082, 43216, 7737, 64087, 64086, 64085, + 83327, 1116, 0, 83319, 7136, 73550, 0, 0, 0, 75031, 0, 0, 0, 64092, + 43675, 10104, 83338, 83331, 64095, 64094, 8111, 66247, 0, 64089, 64088, + 0, 70106, 42236, 11434, 64083, 64082, 43216, 7737, 64087, 64086, 64085, 64084, 0, 0, 0, 4118, 1797, 83312, 0, 0, 46, 83308, 83309, 298, 83303, 72402, 83305, 83306, 0, 0, 0, 128905, 11495, 0, 67490, 0, 127377, 194828, 127370, 0, 0, 0, 66239, 74945, 64403, 0, 0, 83314, 0, 0, 65758, 43536, 0, @@ -27586,7 +27775,7 @@ static const unsigned int code_hash[] = { 0, 0, 0, 66802, 5058, 0, 0, 0, 5057, 125256, 0, 74538, 5054, 0, 0, 0, 0, 0, 0, 658, 3497, 128509, 0, 5061, 5060, 4235, 0, 0, 0, 127757, 4236, 4727, 0, 0, 0, 128791, 0, 7488, 128693, 7476, 0, 125259, 120646, 0, 0, 0, - 66209, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128903, 0, 9341, + 66209, 0, 0, 0, 78931, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128903, 0, 9341, 119596, 0, 0, 0, 64668, 0, 8125, 0, 6743, 119175, 0, 129441, 83406, 0, 127966, 119235, 74092, 0, 0, 43660, 71125, 0, 127901, 0, 0, 0, 264, 0, 74954, 0, 0, 0, 0, 0, 6019, 0, 0, 129121, 0, 0, 0, 8800, 0, 66376, 0, @@ -27595,7 +27784,7 @@ static const unsigned int code_hash[] = { 70723, 5072, 128576, 13098, 72403, 0, 11040, 0, 0, 0, 4929, 0, 0, 0, 0, 0, 0, 0, 0, 67754, 4934, 0, 0, 9758, 0, 0, 70181, 42584, 0, 4329, 0, 4979, 8663, 74521, 0, 983042, 74418, 983653, 0, 5071, 0, 3642, 0, 5070, - 10042, 0, 3987, 5068, 120209, 8909, 0, 0, 69917, 0, 73981, 983141, 70749, + 10042, 0, 3987, 5068, 120209, 8909, 0, 0, 69917, 0, 73981, 983142, 70749, 4531, 120212, 9105, 0, 4921, 121059, 4926, 65544, 113786, 69621, 0, 0, 0, 83269, 0, 120790, 4922, 0, 992, 119568, 4925, 0, 0, 9526, 4920, 128617, 948, 0, 0, 4930, 0, 0, 0, 4933, 0, 0, 0, 4928, 0, 0, 0, 0, 128379, 722, @@ -27614,12 +27803,12 @@ static const unsigned int code_hash[] = { 0, 0, 0, 129172, 118715, 67703, 0, 0, 0, 0, 0, 72290, 0, 0, 0, 0, 7018, 66241, 0, 0, 0, 0, 0, 74056, 0, 11833, 0, 67975, 65232, 40964, 251, 12686, 7895, 4395, 43538, 0, 0, 0, 78042, 0, 0, 40967, 5879, 0, 0, 0, 0, - 0, 65540, 128590, 625, 0, 120194, 1113, 0, 13103, 3630, 67224, 8179, + 0, 65540, 128590, 625, 0, 120194, 1113, 120195, 13103, 3630, 67224, 8179, 74264, 67886, 9316, 10980, 2489, 120958, 8150, 1359, 121353, 70464, 127330, 127327, 5042, 5041, 42769, 12084, 11196, 42961, 92279, 72398, - 120535, 127317, 127318, 127315, 12283, 127313, 11453, 0, 8795, 66245, 0, - 5919, 0, 5037, 118864, 0, 0, 67724, 0, 66893, 74006, 129535, 8431, 0, 0, - 0, 0, 12620, 6826, 73773, 70169, 5040, 0, 0, 0, 0, 0, 5039, 0, 0, 0, + 120535, 127317, 127318, 127315, 12283, 127313, 11453, 70207, 8795, 66245, + 0, 5919, 0, 5037, 118864, 0, 0, 67724, 0, 66893, 74006, 129535, 8431, 0, + 0, 0, 0, 12620, 6826, 73773, 70169, 5040, 0, 0, 0, 0, 0, 5039, 0, 0, 0, 5038, 0, 0, 0, 0, 0, 65908, 0, 0, 0, 0, 0, 65157, 0, 0, 70182, 0, 73909, 4835, 0, 0, 0, 4309, 7127, 0, 0, 0, 1301, 0, 0, 12222, 0, 73813, 711, 92439, 7133, 0, 0, 0, 0, 0, 0, 0, 7661, 72263, 129541, 0, 0, 70453, 7627, @@ -27632,12 +27821,12 @@ static const unsigned int code_hash[] = { 0, 120854, 0, 0, 0, 2470, 0, 0, 1925, 71251, 0, 10971, 113770, 5048, 5047, 0, 0, 194946, 92313, 129972, 0, 0, 8089, 128468, 639, 0, 68179, 0, 70180, 0, 4599, 0, 0, 0, 0, 983817, 648, 194948, 65819, 0, 0, 0, 129968, - 94017, 0, 11777, 9750, 983122, 0, 0, 92367, 70175, 5046, 66255, 0, 0, + 94017, 0, 11777, 9750, 983123, 0, 0, 92367, 70175, 5046, 66255, 0, 0, 65253, 0, 5045, 0, 1916, 74069, 5044, 92348, 0, 0, 5043, 0, 0, 0, 74004, 9669, 12341, 0, 8402, 0, 0, 70174, 0, 3586, 64508, 92456, 0, 0, 119606, 0, 42628, 10069, 0, 0, 0, 0, 123, 120703, 0, 121326, 0, 10719, 129409, 120444, 10829, 120593, 0, 12130, 0, 0, 0, 0, 3925, 0, 0, 75065, 71112, - 92372, 71110, 71111, 0, 120441, 120452, 983178, 0, 0, 0, 0, 0, 0, 0, 0, + 92372, 71110, 71111, 0, 120441, 120452, 983179, 0, 0, 0, 0, 0, 0, 0, 0, 69879, 8509, 120449, 0, 0, 0, 120448, 0, 118889, 194858, 0, 0, 0, 66445, 0, 71109, 0, 0, 72425, 0, 12136, 0, 983629, 0, 0, 0, 0, 19922, 41768, 74002, 0, 0, 0, 0, 2458, 0, 0, 0, 41074, 4266, 64834, 0, 41077, 0, 9050, @@ -27652,7 +27841,7 @@ static const unsigned int code_hash[] = { 65925, 194997, 195000, 194999, 0, 66996, 0, 64397, 0, 0, 0, 71310, 194977, 194976, 2448, 194978, 194981, 194980, 2452, 194982, 194985, 194984, 78694, 72292, 7845, 0, 78692, 4408, 4122, 6772, 194988, 8723, - 72147, 194989, 119302, 11857, 119304, 119303, 2438, 119297, 119300, + 72147, 194989, 73472, 11857, 119304, 119303, 2438, 119297, 119300, 119299, 41953, 0, 42135, 373, 119172, 2119, 11457, 129618, 41955, 0, 0, 0, 41952, 0, 0, 2127, 0, 128496, 5202, 0, 78765, 42823, 11291, 0, 0, 12963, 0, 0, 4125, 41958, 12133, 0, 125099, 1271, 129427, 0, 66024, 0, @@ -27665,7 +27854,7 @@ static const unsigned int code_hash[] = { 983669, 0, 950, 0, 983673, 983683, 983668, 0, 983675, 0, 119121, 0, 5098, 0, 0, 119099, 5097, 0, 9848, 0, 10293, 983664, 72798, 0, 0, 70303, 983684, 5102, 5101, 128370, 0, 8138, 4517, 1932, 5100, 195060, 65022, - 1247, 10034, 195064, 5099, 0, 1441, 0, 4724, 650, 0, 73954, 983268, + 1247, 10034, 195064, 5099, 0, 1441, 0, 4724, 650, 0, 73954, 983271, 129348, 195040, 195043, 9031, 195045, 195044, 195047, 8545, 66356, 195048, 0, 9154, 127243, 0, 0, 2676, 2277, 0, 73812, 195051, 8599, 195053, 917918, 195055, 65462, 0, 92524, 195033, 71903, 0, 0, 41199, 0, @@ -27677,185 +27866,186 @@ static const unsigned int code_hash[] = { 127342, 70149, 932, 0, 6567, 195009, 195008, 195011, 195010, 70145, 43850, 195015, 195014, 195017, 195016, 0, 0, 0, 69511, 10670, 0, 13273, 0, 195020, 121370, 8803, 195021, 72431, 8151, 67145, 72436, 0, 12553, 0, - 0, 0, 0, 13065, 12570, 0, 0, 0, 983198, 124985, 0, 0, 66466, 0, 0, + 0, 0, 0, 13065, 12570, 0, 0, 0, 983199, 124985, 0, 0, 66466, 0, 0, 194595, 0, 194596, 11351, 43256, 0, 0, 0, 0, 41754, 0, 0, 2720, 194975, - 68462, 8232, 120758, 0, 0, 0, 0, 0, 0, 0, 93067, 10834, 0, 0, 119266, 0, - 0, 125025, 67679, 0, 75064, 7781, 0, 0, 126076, 0, 12077, 0, 64586, - 127164, 42396, 0, 3475, 0, 2479, 0, 0, 0, 120728, 0, 42434, 194960, - 194963, 194962, 110611, 67894, 42473, 194966, 110609, 1843, 42283, 0, 0, - 0, 0, 0, 194970, 0, 42321, 7284, 194974, 194973, 194950, 194949, 194952, - 194951, 0, 194953, 123614, 128645, 0, 0, 0, 0, 74952, 194954, 194957, - 194956, 66367, 194958, 41069, 67689, 9988, 0, 41068, 0, 4295, 0, 0, - 41951, 67835, 0, 785, 8236, 128647, 9027, 0, 194943, 0, 0, 0, 0, 0, 0, - 41071, 41059, 0, 92458, 129442, 0, 0, 0, 123612, 2067, 4310, 0, 123611, - 5180, 123605, 0, 73872, 0, 69880, 5184, 42385, 194947, 983774, 128531, 0, - 0, 119149, 0, 121334, 0, 983781, 0, 0, 5178, 194929, 120548, 194931, - 5188, 194933, 194932, 72245, 194934, 1166, 64429, 42639, 0, 0, 0, 0, - 128071, 2442, 10703, 194940, 194939, 194635, 42439, 0, 0, 0, 73933, - 983239, 42401, 0, 0, 0, 42288, 0, 0, 0, 13145, 0, 2468, 0, 42327, 0, 0, - 0, 42479, 128698, 0, 0, 92580, 0, 74939, 120678, 0, 73733, 0, 0, 2715, 0, - 71257, 0, 74114, 0, 0, 0, 0, 0, 66325, 69603, 0, 9240, 0, 0, 129142, 0, - 0, 0, 9815, 0, 11246, 0, 73912, 42733, 0, 0, 2480, 0, 0, 0, 6494, 5537, - 0, 0, 0, 0, 1211, 0, 121379, 0, 0, 12318, 0, 113796, 0, 0, 0, 0, 0, - 64642, 0, 0, 0, 0, 64864, 0, 0, 0, 121212, 0, 0, 3589, 92719, 4035, 6492, - 92236, 4265, 6843, 0, 74186, 41778, 113764, 119216, 2488, 0, 4582, 0, - 71426, 41777, 12926, 72708, 7528, 10550, 113761, 0, 0, 11439, 0, 0, - 64878, 0, 0, 0, 0, 2286, 0, 0, 126646, 127909, 5909, 400, 126500, 0, 0, - 0, 0, 0, 64827, 0, 74948, 390, 0, 71301, 0, 3473, 0, 0, 66742, 0, 55285, - 0, 0, 0, 92206, 194964, 0, 8004, 0, 6763, 0, 0, 7006, 0, 0, 6757, 73707, - 126648, 0, 6766, 0, 0, 0, 6146, 0, 771, 0, 0, 41318, 0, 42272, 0, 120211, - 69559, 0, 953, 12917, 72287, 12300, 64837, 11491, 68612, 0, 0, 71321, - 7490, 11389, 7489, 3379, 0, 7487, 42996, 7486, 7484, 7482, 6753, 7480, - 7479, 7478, 7477, 6501, 7475, 42995, 7473, 7472, 2474, 7470, 7468, - 124977, 0, 0, 0, 0, 71871, 11834, 128376, 0, 6017, 0, 128763, 0, 0, 0, - 119365, 73949, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2472, 69945, 120699, 121133, - 2139, 4256, 120776, 74380, 0, 73847, 73844, 0, 0, 101375, 0, 101374, 0, - 0, 101347, 7083, 0, 8066, 7678, 0, 121124, 101341, 101373, 101336, 0, - 101331, 0, 101304, 0, 101301, 0, 0, 0, 8330, 0, 101298, 101322, 101297, - 0, 0, 19934, 0, 1770, 67091, 0, 128671, 129617, 110605, 101355, 73843, - 110604, 0, 101362, 67092, 0, 71334, 0, 0, 0, 0, 0, 8162, 0, 5996, 129644, - 4903, 0, 0, 43063, 0, 5172, 0, 7139, 0, 127385, 0, 118667, 0, 0, 4334, - 6324, 41975, 12186, 10674, 12308, 0, 0, 0, 72807, 41977, 68002, 0, - 126630, 2018, 121388, 41979, 68003, 0, 68000, 0, 0, 126984, 68001, 9334, - 118609, 71440, 0, 7975, 0, 0, 0, 66621, 4884, 70367, 983759, 0, 121010, - 0, 0, 0, 0, 127799, 0, 0, 0, 463, 0, 194584, 69617, 6509, 5460, 0, 0, 0, - 0, 42279, 0, 0, 0, 0, 0, 0, 0, 125027, 0, 121119, 0, 0, 0, 5663, 0, 0, 0, - 0, 2482, 66202, 0, 0, 42247, 65174, 73925, 0, 100940, 0, 0, 126573, 0, 0, - 2460, 0, 11944, 0, 0, 64679, 120835, 127310, 0, 0, 0, 5870, 0, 0, 0, - 100931, 539, 100933, 100932, 100935, 9064, 100937, 100936, 100939, - 100938, 0, 0, 0, 0, 0, 0, 41295, 100941, 2478, 100943, 4162, 100945, - 4260, 12953, 100950, 100949, 129800, 0, 0, 0, 0, 0, 0, 0, 5000, 0, 0, 0, - 69672, 71439, 0, 74017, 0, 0, 6709, 0, 0, 983739, 0, 0, 100922, 100921, - 10301, 10333, 10397, 100925, 100928, 100927, 0, 0, 0, 127830, 0, 4014, - 12842, 0, 67413, 0, 0, 3893, 0, 0, 12210, 0, 42147, 0, 983622, 74465, 0, - 0, 0, 0, 0, 0, 0, 0, 110805, 8231, 0, 69946, 41968, 100929, 41973, 12935, - 41969, 0, 2453, 0, 0, 78807, 122893, 0, 10349, 10413, 0, 41962, 3202, - 119097, 0, 8316, 129174, 0, 7314, 0, 0, 0, 0, 1840, 0, 0, 0, 4883, - 100908, 4723, 70099, 100909, 0, 0, 0, 0, 11089, 240, 19906, 0, 0, 0, - 43600, 121004, 13134, 93065, 0, 65931, 110649, 110650, 42634, 110648, 0, - 121005, 11463, 0, 0, 129861, 10445, 0, 92969, 0, 2614, 0, 129954, 1729, - 0, 0, 100911, 0, 43334, 100912, 100915, 100914, 66201, 100916, 69662, - 100896, 100899, 100898, 4121, 100900, 70272, 82954, 63879, 0, 70872, 0, - 0, 4039, 643, 7726, 120082, 0, 120068, 58, 0, 0, 0, 63872, 0, 0, 100891, - 0, 10625, 100892, 100895, 100894, 1416, 120073, 917761, 67393, 0, 0, 0, - 6996, 4264, 0, 100902, 66179, 66768, 100903, 13114, 72311, 67510, 3094, - 0, 0, 127074, 4437, 0, 0, 0, 55280, 42174, 0, 42430, 129796, 72246, - 42355, 0, 0, 0, 0, 121251, 127401, 0, 0, 0, 0, 0, 0, 100882, 100881, - 74037, 100883, 0, 127099, 0, 0, 0, 0, 0, 69646, 65035, 65034, 11480, - 6116, 65039, 65038, 41180, 65036, 194565, 0, 12101, 5822, 0, 0, 0, 0, - 11663, 127873, 63854, 119657, 63853, 0, 63852, 65810, 4289, 100885, - 63896, 100887, 100890, 43621, 0, 0, 0, 129613, 194560, 7461, 73901, 0, - 331, 0, 0, 0, 128029, 0, 0, 0, 74629, 0, 0, 0, 41964, 0, 63843, 2084, - 41965, 0, 100864, 100863, 100866, 63841, 78549, 41220, 13032, 100869, - 8383, 0, 78548, 126102, 0, 0, 1351, 983865, 8698, 100874, 100877, 1930, - 100879, 78554, 74360, 100880, 69859, 78551, 0, 0, 129433, 3657, 0, 65202, - 6000, 119206, 41901, 0, 0, 41740, 0, 41283, 0, 119267, 0, 0, 100871, - 9695, 100873, 7562, 100853, 5170, 100855, 100854, 676, 100856, 100859, - 100858, 9978, 100860, 0, 0, 64934, 0, 0, 0, 113714, 113706, 41829, 65886, - 5159, 0, 41832, 704, 43077, 0, 120532, 0, 68496, 65065, 41830, 0, 917799, - 917798, 917797, 917796, 0, 67864, 113696, 917800, 12336, 4135, 69805, - 341, 2727, 4129, 100862, 100861, 0, 64503, 7913, 0, 0, 4131, 63868, 0, - 63871, 4133, 63864, 210, 0, 0, 0, 4137, 78505, 78506, 0, 78504, 78830, 0, - 0, 43873, 0, 0, 0, 0, 11988, 78510, 195, 68321, 41501, 0, 42031, 0, - 13135, 0, 0, 0, 41499, 0, 0, 9680, 41498, 917794, 42025, 78567, 78556, 0, - 0, 0, 0, 0, 0, 101074, 120502, 92597, 0, 0, 917784, 7864, 129001, 129704, - 917788, 121106, 917786, 917785, 5753, 67816, 72371, 2219, 0, 0, 0, 0, 0, - 0, 121277, 0, 917777, 917776, 917775, 69644, 917781, 917780, 917779, - 917778, 8668, 0, 121383, 917782, 5999, 0, 0, 129195, 128243, 43653, 1726, - 1015, 0, 127247, 0, 0, 64919, 0, 0, 0, 128478, 0, 69791, 927, 0, 0, - 42010, 0, 42021, 0, 0, 1299, 12240, 64537, 0, 0, 0, 0, 0, 0, 69454, 0, 0, - 0, 122903, 19914, 12179, 0, 2296, 0, 0, 63832, 917773, 0, 63816, 2594, - 63823, 63817, 11178, 0, 0, 0, 11265, 68295, 0, 0, 0, 10554, 3972, 0, - 121198, 0, 917766, 10816, 917764, 119608, 74374, 917769, 11210, 93069, - 8586, 3882, 8532, 120183, 1573, 128648, 0, 69916, 0, 101051, 67719, 0, 0, - 0, 0, 0, 0, 0, 128821, 119169, 0, 0, 6626, 42763, 130034, 118884, 128613, - 0, 83128, 0, 0, 0, 0, 0, 983561, 0, 0, 0, 9171, 0, 0, 71305, 983919, - 121146, 0, 101095, 128881, 119604, 126596, 0, 0, 0, 128214, 42368, 0, - 983105, 2271, 41487, 12118, 74124, 68651, 110836, 110833, 3009, 41476, - 41489, 69825, 3007, 1448, 3018, 0, 41491, 8521, 5083, 5082, 0, 0, 8519, - 0, 3014, 5081, 73926, 0, 128549, 0, 69951, 5079, 129963, 2557, 128086, - 65532, 11828, 0, 71297, 11105, 0, 0, 0, 8518, 10779, 0, 71303, 0, 0, - 42170, 110769, 0, 629, 1924, 0, 12037, 0, 5987, 8462, 127744, 0, 63933, - 69735, 110770, 128295, 63941, 67981, 5077, 0, 10880, 64849, 5075, 0, - 128152, 65075, 0, 11007, 983736, 0, 0, 0, 66684, 72331, 3434, 72338, - 1904, 0, 0, 72730, 0, 10499, 4507, 9578, 63925, 0, 7979, 0, 9831, 66689, - 0, 461, 194834, 0, 4504, 0, 0, 6325, 0, 43021, 0, 0, 55236, 0, 0, 5177, - 41324, 12055, 63831, 0, 41327, 12591, 0, 4114, 409, 0, 0, 8948, 41325, 0, - 721, 10182, 0, 71311, 0, 0, 94052, 74963, 83503, 5998, 0, 0, 74825, 0, - 12587, 0, 78571, 74889, 71328, 128955, 0, 74121, 78570, 78822, 0, 0, - 5995, 0, 42568, 0, 0, 63944, 73860, 126586, 0, 4167, 0, 43175, 0, 74120, - 0, 65076, 938, 73857, 73854, 11737, 9721, 0, 0, 0, 11742, 0, 0, 11493, - 12334, 128762, 0, 66623, 0, 9173, 0, 11978, 0, 12734, 113750, 113741, 0, - 6759, 0, 0, 0, 126222, 0, 70388, 129093, 13027, 42777, 7683, 1167, 0, - 4983, 0, 861, 0, 0, 68297, 0, 43757, 92978, 129298, 122630, 127804, 0, - 118654, 70815, 9616, 0, 0, 12816, 43759, 0, 12710, 68674, 12721, 4101, - 66185, 0, 5992, 7616, 0, 0, 12577, 0, 0, 853, 42693, 0, 121088, 0, 0, - 917915, 0, 42835, 0, 0, 0, 0, 0, 12712, 7105, 127807, 65060, 66875, 9900, - 0, 0, 0, 121482, 119265, 0, 64778, 12585, 0, 0, 0, 0, 0, 0, 77826, 0, - 4900, 125245, 0, 0, 0, 4119, 74768, 8971, 0, 0, 0, 78594, 41132, 9245, - 73060, 0, 4138, 194841, 0, 0, 0, 77827, 0, 13054, 0, 0, 128416, 110760, - 0, 0, 3948, 128878, 0, 0, 0, 1680, 0, 11861, 0, 0, 120032, 0, 0, 0, 0, - 74833, 74190, 5993, 42709, 0, 12706, 77846, 1893, 0, 63915, 0, 0, 110744, - 129826, 0, 63997, 120018, 63996, 3077, 0, 0, 1512, 0, 12589, 41479, 0, 0, - 0, 0, 11831, 120727, 0, 41481, 0, 118912, 0, 3090, 0, 3086, 1664, 1850, - 0, 3079, 0, 0, 94080, 127140, 0, 0, 74401, 0, 917555, 0, 0, 0, 0, 0, - 11526, 63985, 5864, 0, 63992, 0, 63991, 0, 5480, 7858, 0, 4116, 78149, 0, - 0, 0, 63907, 0, 0, 126131, 63905, 119601, 0, 983190, 0, 119666, 0, 0, - 7534, 507, 91, 2042, 120775, 118596, 0, 66028, 118811, 41844, 70680, 774, - 0, 0, 0, 5994, 0, 12733, 0, 0, 0, 72297, 0, 0, 0, 0, 6026, 0, 0, 0, 162, - 0, 125247, 78151, 78152, 983590, 92709, 0, 68304, 0, 0, 0, 66658, 0, 0, - 0, 0, 121511, 2226, 121512, 129349, 10492, 0, 121510, 0, 43119, 0, 0, 0, - 66192, 0, 0, 4899, 12729, 0, 0, 0, 0, 4103, 0, 129842, 77851, 69429, - 129046, 0, 12859, 70087, 0, 0, 0, 0, 0, 0, 0, 0, 65264, 5146, 0, 194694, - 71684, 0, 0, 983652, 983863, 0, 71688, 78463, 5147, 125019, 0, 74524, - 71682, 128435, 0, 194692, 5991, 3445, 0, 4976, 66193, 0, 0, 0, 0, 128309, - 128594, 129819, 69579, 0, 63855, 0, 10138, 0, 0, 8897, 0, 75027, 0, - 120931, 77862, 65836, 0, 0, 77860, 0, 0, 1123, 4124, 41553, 77903, 0, - 71680, 121386, 398, 0, 129035, 41551, 0, 0, 0, 41550, 9970, 0, 93062, - 42392, 1305, 78901, 0, 129292, 0, 7346, 41464, 0, 0, 0, 41465, 983567, - 8528, 9149, 0, 63955, 165, 3024, 11852, 119163, 0, 9093, 0, 9147, 0, 0, - 110989, 9148, 0, 4096, 53, 8296, 0, 71352, 0, 9594, 0, 0, 63952, 0, - 10997, 0, 0, 5805, 0, 0, 129777, 42176, 71455, 74601, 129604, 10591, 0, - 92852, 0, 0, 0, 0, 0, 0, 92475, 0, 0, 42379, 0, 0, 9220, 0, 121425, 0, 0, - 4132, 0, 0, 11239, 0, 0, 74837, 0, 66408, 0, 8055, 0, 0, 0, 63962, 74042, - 8924, 43123, 5988, 0, 63969, 0, 42718, 8788, 1357, 77872, 65743, 0, 8774, - 0, 0, 0, 0, 92748, 120598, 128234, 9564, 0, 0, 119124, 0, 121241, 110983, - 92975, 3121, 0, 0, 0, 70081, 0, 0, 0, 0, 0, 64851, 0, 0, 73085, 119532, - 0, 0, 0, 0, 1198, 69293, 66708, 64619, 0, 64663, 93991, 0, 0, 2101, 1398, - 0, 92554, 0, 0, 92684, 11406, 101588, 12127, 66998, 840, 0, 0, 7101, - 120938, 0, 0, 12880, 0, 43104, 0, 0, 0, 2117, 0, 0, 0, 0, 0, 0, 0, 7769, - 129867, 92413, 0, 0, 100695, 0, 40986, 83117, 0, 0, 4127, 0, 0, 0, 0, 0, - 0, 70738, 0, 129466, 0, 0, 0, 0, 119081, 0, 10581, 0, 4533, 0, 128941, - 6490, 0, 12038, 0, 0, 68225, 0, 0, 69704, 0, 1948, 119007, 129607, - 101586, 0, 0, 0, 120802, 0, 9494, 0, 0, 0, 4843, 0, 74772, 4098, 0, 0, 0, - 3436, 0, 127279, 12817, 0, 126607, 118678, 0, 0, 0, 74433, 0, 0, 71962, - 0, 121296, 65916, 0, 0, 121458, 0, 129107, 93815, 0, 73743, 0, 0, 983132, - 67676, 0, 0, 74627, 128928, 0, 127892, 0, 71326, 67222, 0, 75013, 92435, - 0, 128500, 0, 0, 9613, 43425, 4526, 121415, 0, 64520, 71336, 0, 0, 55278, - 10228, 64957, 0, 0, 3807, 2081, 66640, 0, 0, 0, 0, 119269, 0, 128688, 0, - 128142, 1451, 0, 0, 4134, 0, 74847, 0, 74793, 0, 0, 74295, 9960, 1201, 0, - 12846, 121271, 0, 11919, 64962, 0, 43739, 0, 66358, 0, 0, 0, 43679, - 72284, 72289, 0, 129523, 1253, 983870, 65766, 500, 65764, 65765, 65762, - 65763, 65760, 65761, 70334, 983867, 9821, 11702, 110630, 110631, 110628, - 110629, 128481, 0, 7533, 66717, 92500, 92305, 0, 0, 69277, 127758, 71332, - 0, 0, 0, 0, 11188, 0, 4112, 0, 0, 12890, 0, 0, 9915, 0, 68423, 0, 0, - 2876, 0, 0, 0, 0, 7382, 92415, 0, 128132, 0, 0, 0, 0, 69561, 127915, 0, - 7003, 0, 0, 7704, 0, 0, 0, 4123, 0, 0, 9977, 0, 0, 65759, 0, 0, 128266, - 9808, 0, 92611, 4126, 0, 9521, 9589, 64755, 0, 0, 0, 69948, 0, 92368, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 93814, 0, 0, 92234, 0, 10693, 0, 0, 65897, 4058, - 0, 0, 64660, 0, 0, 0, 983730, 1139, 43298, 0, 65929, 8970, 0, 9934, 0, - 11023, 128020, 42522, 0, 0, 0, 78899, 3057, 128113, 7349, 69959, 128722, - 68065, 110813, 0, 92826, 67201, 0, 0, 0, 9528, 0, 0, 0, 9102, 627, 92827, - 6273, 129496, 0, 0, 983210, 92966, 43300, 0, 983740, 11696, 92825, 1018, - 65554, 0, 74338, 0, 7645, 0, 128321, 0, 0, 0, 0, 73814, 11544, 12563, - 10728, 0, 0, 127340, 43311, 64966, 92841, 0, 0, 118946, 0, 0, 74779, 0, - 185, 65085, 74533, 0, 0, 7535, 0, 42525, 0, 9749, 41701, 6131, 0, 4117, - 129062, 126988, 0, 92429, 65693, 0, 73445, 0, 69695, 0, 0, 0, 0, 0, 0, 0, - 1184, 0, 815, 0, 0, 0, 0, 0, 71325, 0, 0, 64683, 983816, 0, 127959, 0, 0, - 0, 0, 0, 0, 0, 68166, 0, 0, 0, 0, 66799, 0, 128912, 0, 5142, 0, 69643, 0, - 0, 68367, 93975, 0, 0, 0, 123209, 0, 0, 0, 74855, 121330, 0, 0, 0, 0, - 10940, 66030, 0, 70385, 0, 0, 2652, 120527, 0, 129946, 0, 126508, 0, 0, - 0, 0, 0, 0, 1828, 0, 128357, 0, 8531, 0, 74799, 12324, 72434, 65238, + 68462, 8232, 120758, 0, 0, 0, 0, 122959, 0, 0, 93067, 10834, 0, 0, + 119266, 0, 0, 125025, 67679, 0, 75064, 7781, 0, 0, 126076, 0, 12077, 0, + 64586, 127164, 42396, 0, 3475, 0, 2479, 0, 0, 0, 120728, 0, 42434, + 129709, 194963, 194962, 110611, 67894, 42473, 194966, 110609, 1843, + 42283, 0, 0, 0, 0, 0, 194970, 0, 42321, 7284, 194974, 194973, 194950, + 194949, 194952, 194951, 0, 194953, 123614, 128645, 0, 0, 0, 0, 74952, + 194954, 194957, 194956, 66367, 194958, 41069, 67689, 9988, 0, 41068, 0, + 4295, 0, 0, 41951, 67835, 0, 785, 8236, 128647, 9027, 0, 194943, 0, + 122986, 0, 0, 0, 0, 41071, 41059, 0, 92458, 129442, 0, 0, 0, 123612, + 2067, 4310, 0, 123611, 5180, 123605, 0, 73872, 0, 69880, 5184, 42385, + 194947, 983774, 128531, 0, 0, 119149, 73503, 121334, 0, 983781, 0, 0, + 5178, 194929, 120548, 194931, 5188, 194933, 194932, 72245, 194934, 1166, + 64429, 42639, 0, 0, 0, 0, 128071, 2442, 10703, 194940, 194939, 194635, + 42439, 0, 0, 0, 73933, 983242, 42401, 0, 0, 0, 42288, 0, 0, 0, 13145, 0, + 2468, 0, 42327, 0, 0, 0, 42479, 128698, 0, 0, 92580, 0, 74939, 120678, 0, + 73733, 0, 0, 2715, 0, 71257, 0, 74114, 0, 0, 0, 0, 0, 66325, 69603, 0, + 9240, 0, 0, 129142, 0, 0, 0, 9815, 0, 11246, 0, 73912, 42733, 0, 0, 2480, + 0, 0, 0, 6494, 5537, 0, 0, 0, 0, 1211, 0, 121379, 0, 0, 12318, 0, 113796, + 0, 0, 0, 0, 0, 64642, 0, 0, 0, 0, 64864, 0, 0, 0, 121212, 0, 0, 3589, + 92719, 4035, 6492, 92236, 4265, 6843, 0, 74186, 41778, 113764, 119216, + 2488, 0, 4582, 0, 71426, 41777, 12926, 72708, 7528, 10550, 113761, 0, 0, + 11439, 0, 0, 64878, 0, 0, 0, 0, 2286, 0, 0, 126646, 127909, 5909, 400, + 126500, 0, 0, 0, 0, 0, 64827, 0, 74948, 390, 0, 71301, 0, 3473, 0, 0, + 66742, 0, 55285, 0, 0, 0, 92206, 194964, 0, 8004, 0, 6763, 0, 0, 7006, 0, + 0, 6757, 73707, 126648, 0, 6766, 0, 0, 0, 6146, 0, 771, 0, 0, 41318, 0, + 42272, 0, 120211, 69559, 0, 953, 12917, 72287, 12300, 64837, 11491, + 68612, 0, 0, 71321, 7490, 11389, 7489, 3379, 0, 7487, 42996, 7486, 7484, + 7482, 6753, 7480, 7479, 7478, 7477, 6501, 7475, 42995, 7473, 7472, 2474, + 7470, 7468, 124977, 0, 0, 0, 0, 71871, 11834, 128376, 0, 6017, 0, 128763, + 0, 0, 0, 119365, 73949, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2472, 69945, + 120699, 121133, 2139, 4256, 120776, 74380, 0, 73847, 73844, 0, 0, 101375, + 0, 101374, 0, 0, 101347, 7083, 0, 8066, 7678, 0, 121124, 101341, 101373, + 101336, 0, 101331, 0, 101304, 0, 101301, 0, 0, 0, 8330, 0, 101298, + 101322, 101297, 0, 0, 19934, 0, 1770, 67091, 0, 128671, 129617, 110605, + 101355, 73843, 110604, 0, 101362, 67092, 0, 71334, 0, 0, 0, 0, 0, 8162, + 0, 5996, 129644, 4903, 0, 0, 43063, 0, 5172, 0, 7139, 0, 127385, 0, + 118667, 0, 0, 4334, 6324, 41975, 12186, 10674, 12308, 0, 0, 0, 72807, + 41977, 68002, 0, 126630, 2018, 121388, 41979, 68003, 0, 68000, 0, 0, + 126984, 68001, 9334, 118609, 71440, 0, 7975, 0, 0, 0, 66621, 4884, 70367, + 983759, 0, 121010, 0, 0, 0, 0, 127799, 0, 0, 0, 463, 0, 194584, 69617, + 6509, 5460, 0, 0, 0, 0, 42279, 0, 0, 0, 0, 0, 0, 0, 125027, 0, 121119, 0, + 0, 0, 5663, 0, 0, 0, 0, 2482, 66202, 0, 0, 42247, 65174, 73925, 0, + 100940, 0, 0, 126573, 0, 0, 2460, 0, 11944, 0, 0, 64679, 120835, 127310, + 0, 0, 0, 5870, 0, 0, 0, 100931, 539, 100933, 100932, 100935, 9064, + 100937, 100936, 100939, 100938, 0, 0, 0, 0, 0, 0, 41295, 100941, 2478, + 100943, 4162, 100945, 4260, 12953, 100950, 100949, 129800, 0, 0, 0, 0, 0, + 0, 0, 5000, 0, 0, 0, 69672, 71439, 0, 74017, 0, 0, 6709, 0, 0, 983739, 0, + 0, 100922, 100921, 10301, 10333, 10397, 100925, 100928, 100927, 0, 0, 0, + 127830, 0, 4014, 12842, 0, 67413, 0, 0, 3893, 0, 0, 12210, 0, 42147, 0, + 983622, 74465, 0, 0, 0, 0, 0, 0, 0, 0, 110805, 8231, 0, 69946, 41968, + 100929, 41973, 12935, 41969, 0, 2453, 0, 0, 78807, 122893, 0, 10349, + 10413, 122956, 41962, 3202, 119097, 0, 8316, 129174, 0, 7314, 0, 0, 0, 0, + 1840, 0, 0, 0, 4883, 100908, 4723, 70099, 100909, 0, 0, 0, 0, 11089, 240, + 19906, 0, 0, 0, 43600, 121004, 13134, 93065, 0, 65931, 110649, 110650, + 42634, 110648, 0, 121005, 11463, 0, 0, 129861, 10445, 0, 92969, 0, 2614, + 0, 129954, 1729, 0, 0, 100911, 0, 43334, 100912, 100915, 100914, 66201, + 100916, 69662, 100896, 100899, 100898, 4121, 100900, 70272, 82954, 63879, + 0, 70872, 0, 0, 4039, 643, 7726, 120082, 0, 120068, 58, 0, 0, 0, 63872, + 0, 0, 100891, 0, 10625, 100892, 100895, 100894, 1416, 120073, 917761, + 67393, 0, 0, 0, 6996, 4264, 0, 100902, 66179, 66768, 100903, 13114, + 72311, 67510, 3094, 0, 0, 127074, 4437, 0, 0, 0, 55280, 42174, 0, 42430, + 129796, 72246, 42355, 0, 0, 0, 0, 121251, 127401, 0, 0, 0, 0, 0, 0, + 100882, 100881, 74037, 100883, 0, 127099, 0, 0, 0, 0, 0, 69646, 65035, + 65034, 11480, 6116, 65039, 65038, 41180, 65036, 194565, 0, 12101, 5822, + 0, 0, 0, 0, 11663, 127873, 63854, 119657, 63853, 0, 63852, 65810, 4289, + 100885, 63896, 100887, 100890, 43621, 0, 0, 0, 129613, 194560, 7461, + 73901, 0, 331, 0, 0, 0, 128029, 0, 0, 0, 74629, 0, 0, 0, 41964, 0, 63843, + 2084, 41965, 0, 100864, 100863, 100866, 63841, 78549, 41220, 13032, + 100869, 8383, 0, 78548, 126102, 0, 0, 1351, 983865, 8698, 100874, 100877, + 1930, 100879, 78554, 74360, 100880, 69859, 78551, 0, 0, 129433, 3657, 0, + 65202, 6000, 119206, 41901, 0, 0, 41740, 0, 41283, 73543, 119267, 0, 0, + 100871, 9695, 100873, 7562, 100853, 5170, 100855, 100854, 676, 100856, + 100859, 100858, 9978, 100860, 0, 0, 64934, 0, 0, 0, 113714, 113706, + 41829, 65886, 5159, 0, 41832, 704, 43077, 0, 120532, 0, 68496, 65065, + 41830, 0, 917799, 917798, 917797, 917796, 0, 67864, 113696, 917800, + 12336, 4135, 69805, 341, 2727, 4129, 100862, 100861, 0, 64503, 7913, 0, + 0, 4131, 63868, 0, 63871, 4133, 63864, 210, 0, 0, 0, 4137, 78505, 78506, + 0, 78504, 78830, 0, 0, 43873, 0, 0, 0, 0, 11988, 78510, 195, 68321, + 41501, 0, 42031, 0, 13135, 0, 0, 0, 41499, 0, 0, 9680, 41498, 917794, + 42025, 78567, 78556, 0, 0, 0, 0, 0, 0, 101074, 120502, 92597, 0, 0, + 917784, 7864, 129001, 129704, 917788, 121106, 917786, 917785, 5753, + 67816, 72371, 2219, 0, 0, 0, 0, 0, 0, 121277, 0, 917777, 917776, 917775, + 69644, 917781, 917780, 917779, 917778, 8668, 0, 121383, 917782, 5999, 0, + 0, 129195, 128243, 43653, 1726, 1015, 0, 127247, 0, 0, 64919, 0, 0, 0, + 128478, 0, 69791, 927, 0, 0, 42010, 0, 42021, 0, 0, 1299, 12240, 64537, + 0, 0, 0, 0, 0, 0, 69454, 0, 0, 0, 122903, 19914, 12179, 0, 2296, 0, 0, + 63832, 917773, 0, 63816, 2594, 63823, 63817, 11178, 0, 0, 0, 11265, + 68295, 0, 0, 0, 10554, 3972, 0, 121198, 0, 917766, 10816, 917764, 119608, + 74374, 917769, 11210, 93069, 8586, 3882, 8532, 120183, 1573, 128648, 0, + 69916, 0, 101051, 67719, 0, 0, 0, 0, 0, 0, 0, 128821, 119169, 0, 0, 6626, + 42763, 130034, 118884, 128613, 0, 83128, 0, 0, 0, 0, 0, 983561, 0, 0, 0, + 9171, 0, 0, 71305, 983919, 121146, 0, 101095, 128881, 119604, 126596, 0, + 0, 0, 128214, 42368, 0, 983106, 2271, 41487, 12118, 74124, 68651, 110836, + 110833, 3009, 41476, 41489, 69825, 3007, 1448, 3018, 0, 41491, 8521, + 5083, 5082, 0, 0, 8519, 0, 3014, 5081, 73926, 0, 128549, 0, 69951, 5079, + 129963, 2557, 128086, 65532, 11828, 0, 71297, 11105, 0, 0, 0, 8518, + 10779, 0, 71303, 0, 0, 42170, 110769, 0, 629, 1924, 0, 12037, 0, 5987, + 8462, 127744, 0, 63933, 69735, 110770, 128295, 63941, 67981, 5077, 0, + 10880, 64849, 5075, 0, 128152, 65075, 0, 11007, 983736, 0, 0, 0, 66684, + 72331, 3434, 72338, 1904, 0, 0, 72730, 0, 10499, 4507, 9578, 63925, 0, + 7979, 0, 9831, 66689, 0, 461, 194834, 0, 4504, 0, 0, 6325, 0, 43021, 0, + 0, 55236, 0, 0, 5177, 41324, 12055, 63831, 0, 41327, 12591, 0, 4114, 409, + 0, 0, 8948, 41325, 0, 721, 10182, 0, 71311, 0, 0, 94052, 74963, 83503, + 5998, 0, 0, 74825, 0, 12587, 0, 78571, 74889, 71328, 128955, 0, 74121, + 78570, 73499, 0, 0, 5995, 0, 42568, 0, 0, 63944, 73860, 126586, 0, 4167, + 0, 43175, 0, 74120, 0, 65076, 938, 73857, 73854, 11737, 9721, 0, 0, 0, + 11742, 0, 0, 11493, 12334, 128762, 0, 66623, 0, 9173, 0, 11978, 0, 12734, + 113750, 113741, 0, 6759, 0, 0, 0, 126222, 0, 70388, 129093, 13027, 42777, + 7683, 1167, 0, 4983, 0, 861, 0, 0, 68297, 0, 43757, 92978, 129298, + 122630, 127804, 0, 73546, 70815, 9616, 0, 0, 12816, 43759, 0, 12710, + 68674, 12721, 4101, 66185, 0, 5992, 7616, 0, 0, 12577, 0, 0, 853, 42693, + 0, 121088, 0, 0, 917915, 0, 42835, 0, 0, 0, 0, 0, 12712, 7105, 127807, + 65060, 66875, 9900, 0, 0, 0, 121482, 119265, 0, 64778, 12585, 0, 0, 0, 0, + 0, 0, 77826, 0, 4900, 125245, 0, 0, 0, 4119, 74768, 8971, 0, 0, 0, 78594, + 41132, 9245, 73060, 0, 4138, 194841, 0, 0, 0, 77827, 0, 13054, 0, 0, + 128416, 110760, 0, 0, 3948, 128878, 0, 0, 0, 1680, 0, 11861, 0, 0, + 120032, 0, 0, 0, 0, 74833, 74190, 5993, 42709, 0, 12706, 77846, 1893, 0, + 63915, 0, 0, 110744, 129826, 0, 63997, 120018, 63996, 3077, 0, 0, 1512, + 0, 12589, 41479, 0, 0, 0, 0, 11831, 120727, 122949, 41481, 0, 118912, 0, + 3090, 0, 3086, 1664, 1850, 0, 3079, 0, 0, 94080, 127140, 0, 0, 74401, 0, + 917555, 0, 0, 0, 0, 0, 11526, 63985, 5864, 0, 63992, 0, 63991, 0, 5480, + 7858, 0, 4116, 78149, 0, 0, 0, 63907, 0, 0, 126131, 63905, 119601, 0, + 983191, 0, 119666, 0, 0, 7534, 507, 91, 2042, 120775, 118596, 0, 66028, + 118811, 41844, 70680, 774, 0, 0, 0, 5994, 0, 12733, 0, 0, 0, 72297, 0, 0, + 0, 0, 6026, 0, 0, 0, 162, 0, 125247, 78151, 78152, 983590, 92709, 0, + 68304, 0, 0, 0, 66658, 0, 0, 0, 0, 121511, 2226, 121512, 129349, 10492, + 0, 121510, 0, 43119, 0, 0, 0, 66192, 0, 0, 4899, 12729, 0, 0, 0, 0, 4103, + 0, 129842, 77851, 69429, 129046, 0, 12859, 70087, 0, 101580, 0, 0, 0, 0, + 0, 0, 65264, 5146, 0, 194694, 71684, 0, 0, 983652, 983863, 78924, 71688, + 78463, 5147, 125019, 0, 74524, 71682, 128435, 0, 194692, 5991, 3445, 0, + 4976, 66193, 0, 0, 0, 0, 128309, 128594, 129819, 69579, 0, 63855, 0, + 10138, 0, 0, 8897, 0, 75027, 0, 120931, 77862, 65836, 0, 0, 77860, 0, 0, + 1123, 4124, 41553, 77903, 0, 71680, 121386, 398, 0, 129035, 41551, 0, 0, + 0, 41550, 9970, 0, 93062, 42392, 1305, 78901, 0, 129292, 0, 7346, 41464, + 0, 0, 0, 41465, 983567, 8528, 9149, 0, 63955, 165, 3024, 11852, 119163, + 0, 9093, 0, 9147, 0, 0, 110989, 9148, 0, 4096, 53, 8296, 0, 71352, 0, + 9594, 0, 0, 63952, 0, 10997, 0, 0, 5805, 0, 0, 129777, 42176, 71455, + 74601, 129604, 10591, 0, 92852, 0, 0, 0, 0, 0, 0, 92475, 0, 0, 42379, 0, + 0, 9220, 0, 121425, 0, 0, 4132, 0, 0, 11239, 0, 0, 74837, 0, 66408, 0, + 8055, 0, 0, 0, 63962, 74042, 8924, 43123, 5988, 0, 63969, 0, 42718, 8788, + 1357, 77872, 65743, 0, 8774, 0, 0, 0, 0, 92748, 120598, 128234, 9564, 0, + 0, 119124, 0, 121241, 110983, 92975, 3121, 0, 0, 0, 70081, 0, 0, 0, 0, 0, + 64851, 0, 0, 73085, 119532, 0, 0, 0, 0, 1198, 69293, 66708, 64619, 0, + 64663, 93991, 0, 0, 2101, 1398, 0, 92554, 0, 0, 92684, 11406, 101588, + 12127, 66998, 840, 0, 0, 7101, 120938, 0, 0, 12880, 0, 43104, 0, 0, 0, + 2117, 0, 0, 0, 0, 123023, 0, 0, 7769, 129867, 92413, 0, 0, 100695, 0, + 40986, 83117, 0, 0, 4127, 0, 0, 129034, 0, 0, 0, 70738, 0, 129466, 0, 0, + 0, 0, 119081, 0, 10581, 0, 4533, 0, 128941, 6490, 0, 12038, 0, 0, 68225, + 0, 0, 69704, 0, 1948, 119007, 129607, 101586, 0, 0, 0, 120802, 0, 9494, + 0, 0, 0, 4843, 0, 74772, 4098, 0, 0, 0, 3436, 0, 127279, 12817, 0, + 126607, 118678, 0, 0, 0, 74433, 0, 0, 71962, 0, 121296, 65916, 0, 0, + 121458, 0, 129107, 93815, 0, 73743, 0, 0, 983133, 67676, 0, 0, 74627, + 128928, 0, 127892, 0, 71326, 67222, 0, 75013, 92435, 0, 128500, 0, 0, + 9613, 43425, 4526, 121415, 0, 64520, 71336, 0, 0, 55278, 10228, 64957, 0, + 0, 3807, 2081, 66640, 0, 0, 0, 0, 119269, 0, 128688, 0, 128142, 1451, 0, + 0, 4134, 0, 74847, 0, 74793, 0, 78913, 74295, 9960, 1201, 0, 12846, + 121271, 0, 11919, 64962, 0, 43739, 0, 66358, 0, 0, 0, 43679, 72284, + 72289, 0, 129523, 1253, 983870, 65766, 500, 65764, 65765, 65762, 65763, + 65760, 65761, 70334, 983867, 9821, 11702, 110630, 110631, 110628, 110629, + 128481, 0, 7533, 66717, 92500, 92305, 0, 0, 69277, 127758, 71332, 0, 0, + 0, 0, 11188, 0, 4112, 0, 0, 12890, 0, 0, 9915, 0, 68423, 0, 0, 2876, 0, + 0, 0, 0, 7382, 92415, 0, 128132, 0, 0, 0, 0, 69561, 127915, 0, 7003, 0, + 0, 7704, 0, 0, 0, 4123, 0, 0, 9977, 0, 0, 65759, 0, 0, 128266, 9808, 0, + 92611, 4126, 0, 9521, 9589, 64755, 0, 0, 0, 69948, 0, 92368, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 93814, 0, 0, 92234, 0, 10693, 0, 0, 65897, 4058, 0, 0, + 64660, 0, 0, 0, 983730, 1139, 43298, 0, 65929, 8970, 0, 9934, 0, 11023, + 128020, 42522, 0, 0, 0, 78899, 3057, 128113, 7349, 69959, 128722, 68065, + 110813, 0, 92826, 67201, 0, 0, 0, 9528, 0, 0, 0, 9102, 627, 92827, 6273, + 129496, 0, 0, 983212, 92966, 43300, 0, 983740, 11696, 92825, 1018, 65554, + 0, 74338, 0, 7645, 0, 128321, 0, 0, 0, 0, 73814, 11544, 12563, 10728, 0, + 0, 127340, 43311, 64966, 92841, 0, 0, 118946, 0, 0, 74779, 0, 185, 65085, + 74533, 0, 0, 7535, 0, 42525, 0, 9749, 41701, 6131, 0, 4117, 129062, + 126988, 0, 92429, 65693, 0, 73445, 0, 69695, 0, 0, 0, 0, 0, 0, 0, 1184, + 0, 815, 0, 0, 0, 0, 0, 71325, 0, 0, 64683, 983816, 0, 127959, 0, 0, 0, 0, + 0, 0, 0, 68166, 0, 0, 0, 0, 66799, 0, 128912, 0, 5142, 0, 69643, 0, 0, + 68367, 93975, 0, 0, 0, 123209, 124133, 0, 0, 74855, 121330, 0, 0, 0, 0, + 10940, 66030, 0, 70385, 73494, 0, 2652, 120527, 0, 129946, 0, 126508, 0, + 0, 0, 0, 0, 0, 1828, 0, 128357, 0, 8531, 0, 74799, 12324, 72434, 65238, 68374, 0, 65573, 0, 68308, 68679, 12904, 43445, 0, 0, 0, 11247, 0, 0, 41426, 0, 0, 0, 0, 0, 67250, 69451, 83354, 11869, 0, 0, 0, 0, 0, 0, 637, 0, 0, 0, 121178, 0, 0, 74474, 71306, 0, 7298, 128256, 0, 0, 0, 0, 8210, @@ -27866,32 +28056,32 @@ static const unsigned int code_hash[] = { 129875, 0, 71485, 0, 917837, 0, 0, 78157, 0, 0, 0, 0, 0, 71313, 0, 70710, 128212, 0, 72238, 67858, 0, 0, 0, 0, 0, 0, 0, 10770, 118994, 0, 465, 0, 983656, 74348, 0, 0, 0, 0, 0, 0, 0, 10930, 0, 0, 0, 119091, 69388, - 122637, 129918, 0, 0, 0, 0, 0, 10092, 0, 0, 0, 0, 0, 1766, 11282, 11996, - 66644, 4547, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120906, 4345, 0, 0, 128947, 0, 0, - 0, 0, 0, 5382, 0, 0, 118552, 0, 0, 5406, 43127, 120007, 0, 3590, 129874, - 0, 0, 0, 42016, 0, 0, 121002, 0, 7742, 0, 66562, 71323, 0, 0, 5310, 0, - 123625, 0, 43594, 0, 128260, 66723, 0, 73816, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1326, 128723, 0, 0, 74519, 0, 0, 0, 0, 71308, 0, 5410, 5783, 0, 8403, - 5400, 120526, 0, 128863, 0, 0, 0, 64412, 0, 0, 5587, 42865, 71858, 0, 0, - 129854, 0, 113785, 0, 120755, 0, 69738, 0, 74867, 10461, 12103, 0, 0, - 70701, 0, 0, 0, 0, 0, 94009, 0, 2760, 0, 8816, 41515, 0, 11802, 0, 7585, - 910, 0, 0, 0, 3658, 83386, 120525, 0, 7617, 0, 12888, 0, 0, 64631, 0, - 41514, 11097, 5703, 0, 41517, 41504, 41519, 0, 70104, 0, 65864, 0, - 120533, 0, 121037, 0, 0, 43553, 120774, 0, 0, 0, 0, 0, 1578, 0, 43449, 0, - 0, 8225, 121191, 94024, 72799, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 110655, - 0, 110656, 121247, 72213, 0, 110658, 0, 74997, 0, 3195, 10999, 983570, - 7897, 0, 1203, 74396, 0, 64544, 0, 0, 0, 2877, 0, 0, 0, 121112, 0, 0, - 128977, 119607, 0, 0, 0, 0, 983623, 0, 0, 0, 0, 0, 0, 0, 0, 983078, 0, 0, - 0, 9939, 0, 0, 0, 0, 0, 0, 0, 10714, 0, 0, 0, 0, 0, 67738, 0, 74038, 0, - 42897, 0, 0, 0, 0, 0, 0, 7730, 0, 0, 0, 11163, 0, 0, 0, 113701, 4966, - 128802, 70674, 129468, 123207, 3841, 0, 0, 983228, 77886, 0, 4972, 0, - 64699, 0, 0, 0, 0, 0, 12705, 10203, 9608, 0, 0, 11962, 121397, 0, 1196, - 67684, 0, 777, 0, 0, 65271, 0, 0, 0, 0, 64824, 983194, 0, 9454, 63778, - 8658, 0, 0, 2705, 0, 64894, 0, 0, 11986, 92636, 0, 8280, 0, 2701, 0, 0, - 0, 0, 0, 9809, 0, 0, 0, 0, 0, 63761, 1748, 0, 65719, 121078, 0, 0, 0, - 55244, 3061, 0, 63765, 63787, 0, 41520, 0, 7694, 0, 8896, 63768, 55282, - 0, 127781, 0, 0, 63807, 1591, 0, 6386, 118554, 0, 0, 0, 983199, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 68289, 0, 0, 7624, 67487, 10996, 92247, 10609, 0, + 122637, 129918, 0, 0, 0, 0, 0, 10092, 0, 0, 0, 0, 119019, 1766, 11282, + 11996, 66644, 4547, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120906, 4345, 0, 0, + 128947, 0, 0, 0, 0, 0, 5382, 0, 0, 118552, 0, 0, 5406, 43127, 120007, 0, + 3590, 129874, 0, 0, 0, 42016, 0, 0, 121002, 0, 7742, 0, 66562, 71323, 0, + 0, 5310, 0, 123625, 0, 43594, 0, 128260, 66723, 0, 73816, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1326, 128723, 0, 0, 74519, 0, 0, 0, 0, 71308, 0, 5410, 5783, + 0, 8403, 5400, 120526, 0, 128863, 0, 0, 0, 64412, 0, 0, 5587, 42865, + 71858, 0, 0, 129854, 0, 113785, 0, 120755, 0, 69738, 0, 74867, 10461, + 12103, 0, 0, 70701, 0, 0, 0, 0, 0, 94009, 0, 2760, 0, 8816, 41515, 0, + 11802, 0, 7585, 910, 0, 0, 0, 3658, 83386, 120525, 0, 7617, 0, 12888, 0, + 0, 64631, 0, 41514, 11097, 5703, 0, 41517, 41504, 41519, 0, 70104, 0, + 65864, 0, 120533, 0, 121037, 0, 0, 43553, 120774, 0, 0, 0, 0, 0, 1578, 0, + 43449, 0, 0, 8225, 121191, 94024, 72799, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 110655, 0, 110656, 121247, 72213, 0, 110658, 0, 74997, 0, 3195, 10999, + 983570, 7897, 0, 1203, 74396, 0, 64544, 0, 0, 0, 2877, 0, 0, 0, 121112, + 0, 0, 128977, 119607, 0, 0, 0, 0, 983623, 0, 0, 0, 0, 0, 0, 0, 0, 983078, + 0, 0, 0, 9939, 0, 0, 0, 0, 0, 0, 0, 10714, 0, 0, 0, 0, 0, 67738, 0, + 74038, 0, 42897, 0, 0, 0, 0, 0, 0, 7730, 0, 0, 0, 11163, 0, 0, 0, 113701, + 4966, 128802, 70674, 129468, 123207, 3841, 0, 0, 983231, 77886, 0, 4972, + 0, 64699, 0, 0, 0, 0, 0, 12705, 10203, 9608, 0, 0, 11962, 121397, 0, + 1196, 67684, 0, 777, 0, 0, 65271, 0, 0, 0, 0, 64824, 983195, 0, 9454, + 63778, 8658, 0, 0, 2705, 0, 64894, 0, 0, 11986, 92636, 0, 8280, 0, 2701, + 0, 0, 0, 0, 0, 9809, 0, 0, 0, 0, 0, 63761, 1748, 0, 65719, 121078, 0, 0, + 0, 55244, 3061, 0, 63765, 63787, 0, 41520, 0, 7694, 0, 8896, 63768, + 55282, 0, 127781, 0, 0, 63807, 1591, 0, 6386, 118554, 0, 0, 0, 983200, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 68289, 0, 0, 7624, 67487, 10996, 92247, 10609, 0, 127181, 10987, 0, 70370, 3894, 0, 0, 0, 0, 493, 0, 0, 1717, 12228, 479, 917941, 129347, 129473, 917935, 917939, 917924, 917932, 92303, 64315, 92170, 0, 83522, 6233, 42681, 83525, 83518, 83519, 64911, 83521, 0, 0, @@ -27929,9 +28119,9 @@ static const unsigned int code_hash[] = { 128832, 100930, 0, 0, 0, 0, 0, 129776, 128546, 0, 0, 120914, 0, 0, 0, 0, 917822, 128810, 983676, 65599, 0, 9966, 12607, 4948, 128070, 0, 128149, 0, 0, 6207, 0, 6117, 73916, 0, 0, 0, 0, 68244, 41511, 0, 129489, 127304, - 0, 121289, 0, 118618, 83031, 83032, 0, 41556, 0, 0, 0, 128571, 73766, 0, + 0, 121289, 0, 118618, 83031, 83032, 0, 41556, 0, 0, 0, 128571, 73504, 0, 0, 118645, 41510, 7953, 0, 0, 41513, 0, 0, 0, 83038, 83039, 83040, 83041, - 83034, 83035, 848, 9868, 983149, 6424, 118625, 83033, 0, 0, 0, 0, 118539, + 83034, 83035, 848, 9868, 983150, 6424, 118625, 83033, 0, 0, 0, 0, 118539, 0, 893, 64576, 13299, 0, 0, 71998, 71447, 0, 0, 0, 0, 8903, 0, 0, 0, 8099, 0, 0, 0, 0, 0, 0, 0, 0, 113713, 0, 0, 0, 0, 0, 83027, 41483, 83029, 83030, 83023, 83024, 69436, 64836, 194756, 41485, 194758, 194757, 194760, @@ -27943,7 +28133,7 @@ static const unsigned int code_hash[] = { 0, 2108, 0, 73929, 0, 0, 10617, 194737, 128031, 194739, 194738, 68614, 194740, 68611, 9924, 129952, 194744, 0, 0, 0, 3277, 0, 4947, 41055, 0, 194722, 129930, 194724, 194723, 64626, 194725, 42266, 194727, 8371, - 194729, 127028, 12806, 41492, 0, 0, 73930, 194731, 194730, 41054, 1078, + 194729, 127028, 12806, 41492, 0, 0, 73930, 194731, 124140, 41054, 1078, 194735, 194734, 41057, 0, 0, 0, 0, 0, 92210, 73009, 0, 41496, 0, 9165, 1572, 0, 129712, 0, 128635, 9215, 9330, 129809, 10032, 41745, 43183, 6401, 5831, 0, 0, 0, 8056, 0, 65681, 92377, 0, 0, 0, 121048, 0, 118887, @@ -27972,13 +28162,13 @@ static const unsigned int code_hash[] = { 74317, 0, 8319, 194714, 194717, 10960, 72196, 8305, 12573, 983620, 72193, 0, 13202, 0, 12582, 0, 72198, 69856, 0, 0, 78598, 0, 72195, 0, 65802, 74822, 7698, 12708, 74045, 0, 0, 70460, 4913, 127990, 0, 123539, 0, 0, - 12728, 129980, 0, 0, 101281, 0, 130038, 0, 101283, 0, 12588, 8821, 6153, - 194705, 78900, 194707, 194710, 194709, 194712, 194711, 118854, 194713, - 651, 0, 0, 0, 0, 0, 78468, 78469, 69433, 78467, 69614, 74905, 194695, - 78461, 194697, 194696, 0, 4716, 43277, 0, 2185, 78475, 128592, 120928, - 194700, 55264, 194702, 12732, 0, 12707, 0, 0, 0, 0, 121417, 8479, 4151, - 0, 0, 0, 0, 0, 0, 0, 0, 113799, 0, 74050, 0, 0, 0, 0, 0, 129467, 12278, - 0, 129507, 0, 2700, 12576, 7842, 0, 67471, 0, 2699, 0, 0, 2985, 0, + 12728, 129980, 128895, 0, 101281, 0, 130038, 0, 101283, 0, 12588, 8821, + 6153, 194705, 78900, 194707, 194710, 194709, 194712, 194711, 118854, + 194713, 651, 0, 0, 0, 0, 0, 78468, 78469, 69433, 78467, 69614, 74905, + 194695, 78461, 194697, 194696, 0, 4716, 43277, 0, 2185, 78475, 128592, + 120928, 194700, 55264, 194702, 12732, 0, 12707, 0, 0, 0, 0, 121417, 8479, + 4151, 0, 0, 0, 0, 0, 0, 0, 0, 113799, 0, 74050, 0, 0, 0, 0, 0, 129467, + 12278, 0, 129507, 0, 2700, 12576, 7842, 0, 67471, 0, 2699, 0, 0, 2985, 0, 126475, 0, 129873, 119314, 0, 119312, 9827, 101292, 119311, 101291, 119309, 119306, 11481, 118718, 119305, 0, 35, 78481, 78482, 66694, 78480, 78477, 78478, 0, 0, 64257, 0, 0, 0, 78485, 78486, 78483, 4272, 0, 0, @@ -27988,7 +28178,7 @@ static const unsigned int code_hash[] = { 128628, 101088, 0, 12346, 128596, 101089, 0, 0, 7251, 0, 0, 118850, 73025, 0, 0, 0, 0, 0, 12564, 66457, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 101131, 0, 41564, 10976, 0, 121223, 0, 0, 10054, 9197, 120618, 0, 9012, 65737, - 74420, 0, 13215, 12730, 0, 0, 0, 0, 816, 0, 101123, 0, 83191, 0, 0, + 74420, 0, 13215, 12730, 0, 0, 0, 0, 816, 0, 101123, 122664, 83191, 0, 0, 92752, 101120, 4715, 94107, 94106, 71075, 0, 0, 0, 67729, 0, 307, 0, 9585, 0, 0, 0, 101255, 0, 125267, 0, 70727, 65567, 101238, 75006, 101231, 983909, 0, 12236, 41419, 101259, 194621, 101248, 75003, 194622, 73675, @@ -28010,89 +28200,90 @@ static const unsigned int code_hash[] = { 100813, 100816, 100815, 100818, 100817, 100798, 100797, 41410, 100799, 64262, 0, 41407, 75000, 0, 0, 93812, 0, 0, 72803, 74999, 78897, 0, 0, 67675, 0, 0, 0, 0, 43647, 0, 0, 100792, 100791, 100794, 100793, 100796, - 100795, 0, 74630, 11933, 0, 0, 41903, 67892, 11001, 100801, 42255, + 100795, 983276, 74630, 11933, 0, 0, 41903, 67892, 11001, 100801, 42255, 100803, 100802, 100805, 41905, 100807, 100806, 10775, 9793, 0, 0, 74452, 0, 983063, 42535, 0, 64529, 41408, 42853, 0, 0, 42674, 118915, 0, 0, 983807, 0, 70838, 0, 0, 0, 64506, 0, 66738, 4747, 100783, 69844, 100785, - 5832, 0, 0, 5141, 42600, 0, 0, 0, 0, 0, 0, 93790, 0, 7657, 0, 71132, + 5832, 0, 0, 5141, 42600, 124147, 0, 0, 0, 0, 0, 93790, 0, 7657, 0, 71132, 74137, 0, 128362, 73682, 73681, 859, 0, 0, 0, 6059, 126985, 55235, 0, 0, - 0, 0, 0, 100787, 11488, 72838, 100788, 0, 100790, 10558, 0, 0, 118646, - 126090, 71069, 0, 0, 1788, 0, 0, 0, 0, 119571, 92822, 9028, 0, 69234, - 73665, 0, 9905, 128485, 41242, 70086, 0, 74109, 100765, 100764, 100767, - 100766, 70830, 83184, 70082, 3940, 0, 43754, 0, 128188, 8665, 0, 0, 0, - 1653, 100775, 42406, 100777, 100780, 70825, 120523, 0, 8815, 0, 65046, 0, - 42445, 0, 11180, 119318, 119315, 68454, 42485, 0, 0, 8211, 42293, 983602, - 0, 0, 0, 0, 65385, 100771, 42332, 100773, 78431, 78432, 78423, 78430, - 78420, 10022, 65387, 78419, 65384, 0, 0, 0, 65386, 0, 11248, 0, 43198, - 64751, 0, 0, 0, 0, 0, 0, 101102, 7363, 0, 0, 119323, 119324, 100752, - 100751, 0, 119320, 0, 983632, 0, 8237, 0, 0, 0, 0, 0, 0, 9914, 0, 100763, - 100762, 120009, 6351, 119993, 92740, 68766, 0, 120010, 41243, 0, 74108, - 11467, 120165, 119998, 4358, 0, 6353, 0, 0, 0, 93045, 1710, 0, 0, 92237, - 0, 49, 73871, 120005, 78671, 0, 78672, 9741, 78443, 78444, 78441, 43443, - 78439, 78440, 69244, 78438, 3470, 0, 0, 92814, 0, 0, 78445, 0, 1072, - 78457, 78452, 78454, 74230, 78451, 78447, 78449, 1080, 0, 74100, 0, 1101, - 68404, 78458, 78459, 71082, 0, 1086, 1869, 0, 0, 0, 65458, 0, 0, 41988, - 0, 1091, 0, 7977, 0, 66992, 0, 0, 0, 92758, 0, 0, 0, 0, 0, 71255, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 64582, 0, 0, 70794, 0, 120989, 128495, 74106, 0, - 66883, 0, 0, 0, 0, 0, 0, 0, 92553, 43752, 110592, 0, 71249, 120886, 0, 0, - 0, 0, 6063, 100857, 101221, 917995, 6053, 74096, 0, 0, 74169, 13100, 0, - 917999, 0, 71081, 0, 70387, 6055, 7800, 4279, 8490, 120114, 120111, - 64786, 8602, 120110, 83389, 92204, 0, 0, 74961, 0, 120117, 120118, - 120099, 120100, 65087, 64402, 3674, 120096, 0, 120094, 120107, 118624, - 120105, 10107, 42159, 42870, 120101, 69632, 0, 0, 43281, 127078, 0, - 74098, 0, 0, 126497, 74099, 129056, 0, 0, 0, 121123, 5847, 125258, 0, 0, - 0, 0, 0, 66592, 64469, 71698, 19966, 0, 42561, 0, 129170, 66854, 8120, - 75042, 0, 0, 0, 0, 0, 0, 126068, 8369, 0, 0, 122912, 3369, 0, 121094, 0, - 0, 69238, 10495, 121365, 0, 557, 9457, 0, 0, 121054, 73880, 127220, 0, - 74937, 74094, 0, 0, 0, 92171, 127219, 128175, 127939, 120424, 0, 127214, - 2109, 67893, 127211, 69656, 127217, 10604, 127215, 0, 0, 0, 0, 126561, 0, - 0, 0, 0, 1618, 0, 0, 83175, 10430, 0, 0, 13063, 917585, 0, 92982, 113666, - 0, 78390, 83489, 12060, 0, 113669, 0, 6329, 0, 0, 0, 74395, 2707, 8309, - 0, 127054, 78398, 0, 2697, 0, 78396, 127057, 2695, 0, 0, 68334, 0, 0, 0, - 72325, 2693, 74091, 0, 0, 2703, 113729, 70283, 41918, 983168, 127542, - 8687, 127543, 12178, 43361, 92540, 64075, 110705, 5248, 110703, 120538, - 6427, 0, 0, 0, 0, 110710, 0, 74990, 74989, 70703, 127031, 0, 9873, 0, 0, - 0, 64762, 2053, 0, 6591, 9340, 0, 1589, 0, 296, 67712, 128315, 12766, - 118931, 74370, 120417, 2414, 128068, 43829, 111202, 74836, 0, 12579, 0, - 12575, 6416, 5656, 0, 13262, 65590, 5299, 983702, 0, 5449, 1252, 0, - 78404, 69748, 74369, 65373, 5295, 0, 121066, 1223, 1642, 78408, 0, 12158, - 5303, 0, 120546, 41413, 3212, 127025, 3211, 74810, 41425, 127029, 0, - 74450, 9728, 0, 10924, 74778, 6636, 0, 129884, 0, 0, 129882, 9519, 0, 0, - 129106, 101110, 68780, 0, 0, 0, 119182, 0, 12104, 77942, 77951, 9004, 0, - 74249, 10230, 0, 0, 0, 77947, 0, 69679, 121475, 9890, 125049, 12971, 0, - 92556, 0, 67903, 70051, 983924, 0, 0, 9635, 12600, 0, 0, 0, 118900, 6469, - 0, 101113, 65304, 4679, 101114, 64300, 64867, 6531, 101118, 101099, - 101098, 92813, 101100, 42916, 0, 0, 0, 0, 0, 0, 4445, 72296, 0, 11533, 0, - 3416, 129148, 0, 0, 0, 78566, 0, 0, 101091, 92815, 101093, 5447, 72140, - 70752, 101097, 101096, 0, 0, 0, 64448, 0, 43920, 70677, 0, 6232, 101101, - 101104, 101103, 43608, 101105, 101108, 6538, 4335, 0, 3941, 74986, 11061, - 0, 74988, 74987, 0, 12155, 128278, 0, 0, 0, 0, 74578, 0, 65832, 0, - 129459, 70789, 0, 125050, 0, 0, 350, 10951, 101081, 509, 101083, 101086, - 101085, 0, 0, 0, 917540, 0, 100905, 110970, 12162, 64741, 0, 9354, 0, - 70802, 100901, 2496, 11516, 944, 128238, 0, 0, 1438, 0, 0, 120185, 70785, - 1220, 917952, 93844, 0, 0, 5008, 42630, 70787, 101087, 2229, 68206, 564, - 0, 312, 0, 0, 0, 70797, 8877, 269, 0, 128065, 9617, 0, 0, 100910, 0, 0, - 10862, 0, 0, 41416, 0, 4173, 0, 0, 0, 1906, 983854, 41418, 74073, 101068, - 101067, 41415, 69622, 9582, 0, 64287, 0, 0, 11428, 1730, 0, 0, 19918, - 10469, 101076, 101079, 68088, 0, 101080, 72342, 0, 129692, 0, 6129, 0, 0, - 0, 0, 7874, 0, 0, 11206, 13136, 118529, 129305, 0, 64374, 74925, 0, - 73892, 0, 101073, 101072, 101075, 74960, 9228, 101054, 101057, 101056, - 5240, 9811, 0, 101060, 129718, 0, 0, 74079, 65873, 0, 0, 0, 9501, 0, - 68081, 72808, 65465, 64654, 7467, 0, 0, 83460, 10040, 0, 3096, 0, 101053, - 101052, 68820, 83461, 0, 0, 0, 0, 0, 0, 83377, 0, 68801, 0, 101062, - 101061, 101064, 101063, 0, 8637, 70741, 0, 77983, 77969, 11471, 43554, 0, - 77968, 0, 0, 0, 2426, 12042, 0, 0, 0, 3961, 12115, 129633, 0, 77972, - 64561, 0, 4981, 74644, 129558, 0, 0, 42686, 77976, 128776, 64686, 0, - 77958, 7589, 0, 0, 3237, 0, 68215, 0, 8541, 127157, 71067, 120174, 0, 0, - 0, 0, 0, 43555, 0, 0, 10060, 111261, 100917, 0, 0, 0, 64877, 0, 0, 8614, - 65220, 41493, 0, 0, 0, 43780, 0, 0, 70689, 0, 0, 0, 0, 0, 0, 4012, 10395, - 0, 0, 111253, 126511, 111254, 125051, 695, 739, 696, 7611, 0, 42755, - 68421, 9227, 7506, 7510, 67493, 691, 738, 7511, 7512, 7515, 7501, 688, - 41847, 690, 2548, 737, 974, 43386, 0, 0, 0, 0, 0, 0, 65860, 0, 7051, - 69777, 4682, 0, 983096, 6406, 4685, 0, 0, 10347, 4680, 6341, 0, 0, 92607, - 74325, 0, 123555, 0, 0, 0, 0, 0, 0, 43505, 92468, 11718, 42373, 11714, 0, - 0, 129567, 11717, 0, 10594, 129732, 11712, 0, 0, 10967, 0, 0, 0, 66632, - 118647, 0, 0, 0, 1735, 0, 11134, 2363, 983135, 0, 0, 70695, 128032, 0, + 0, 0, 0, 100787, 11488, 72838, 100788, 0, 100790, 10558, 0, 124144, + 118646, 126090, 71069, 0, 0, 1788, 0, 0, 0, 0, 119571, 92822, 9028, 0, + 69234, 73665, 0, 9905, 73556, 41242, 70086, 0, 74109, 100765, 100764, + 100767, 100766, 70830, 83184, 70082, 3940, 0, 43754, 0, 128188, 8665, 0, + 0, 0, 1653, 100775, 42406, 100777, 100780, 70825, 120523, 0, 8815, 0, + 65046, 0, 42445, 0, 11180, 119318, 119315, 68454, 42485, 0, 0, 8211, + 42293, 983602, 0, 0, 0, 0, 65385, 100771, 42332, 100773, 78431, 78432, + 78423, 78430, 78420, 10022, 65387, 78419, 65384, 0, 0, 0, 65386, 0, + 11248, 0, 43198, 64751, 0, 0, 0, 0, 0, 0, 101102, 7363, 0, 0, 119323, + 119324, 100752, 100751, 0, 119320, 0, 983632, 0, 8237, 0, 0, 0, 0, 0, 0, + 9914, 0, 100763, 100762, 120009, 6351, 119993, 92740, 68766, 0, 120010, + 41243, 0, 74108, 11467, 120165, 119998, 4358, 0, 6353, 0, 0, 0, 93045, + 1710, 0, 0, 92237, 0, 49, 73871, 120005, 78671, 0, 78672, 9741, 78443, + 78444, 78441, 43443, 78439, 78440, 69244, 78438, 3470, 0, 0, 92814, 0, 0, + 78445, 0, 1072, 78457, 78452, 78454, 74230, 78451, 78447, 78449, 1080, 0, + 74100, 0, 1101, 68404, 78458, 78459, 71082, 0, 1086, 1869, 0, 0, 0, + 65458, 0, 0, 41988, 0, 1091, 0, 7977, 0, 66992, 0, 0, 0, 92758, 0, 0, 0, + 0, 0, 71255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64582, 0, 0, 70794, 0, 120989, + 128495, 74106, 0, 66883, 0, 0, 0, 0, 0, 0, 0, 92553, 43752, 110592, 0, + 71249, 120886, 0, 0, 0, 0, 6063, 100857, 101221, 917995, 6053, 74096, 0, + 0, 74169, 13100, 0, 917999, 0, 71081, 0, 70387, 6055, 7800, 4279, 8490, + 120114, 120111, 64786, 8602, 120110, 83389, 92204, 0, 0, 74961, 0, + 120117, 120118, 120099, 120100, 65087, 64402, 3674, 120096, 0, 120094, + 120107, 118624, 120105, 10107, 42159, 42870, 120101, 69632, 0, 0, 43281, + 127078, 0, 74098, 0, 0, 126497, 74099, 129056, 0, 0, 0, 121123, 5847, + 125258, 0, 0, 0, 0, 0, 66592, 64469, 71698, 19966, 0, 42561, 0, 129170, + 66854, 8120, 75042, 0, 0, 0, 0, 0, 0, 126068, 8369, 0, 0, 122912, 3369, + 0, 121094, 0, 0, 69238, 10495, 121365, 0, 557, 9457, 0, 0, 121054, 73880, + 127220, 0, 74937, 74094, 0, 0, 119001, 92171, 127219, 128175, 127939, + 120424, 0, 127214, 2109, 67893, 127211, 69656, 127217, 10604, 127215, 0, + 0, 0, 129727, 126561, 0, 0, 0, 0, 1618, 0, 0, 83175, 10430, 0, 0, 13063, + 917585, 0, 92982, 113666, 0, 78390, 83489, 12060, 0, 113669, 0, 6329, 0, + 0, 0, 74395, 2707, 8309, 0, 127054, 78398, 0, 2697, 0, 78396, 127057, + 2695, 0, 0, 68334, 0, 0, 0, 72325, 2693, 74091, 0, 0, 2703, 113729, + 70283, 41918, 983169, 127542, 8687, 127543, 12178, 43361, 92540, 64075, + 110705, 5248, 110703, 120538, 6427, 0, 0, 0, 0, 110710, 0, 74990, 74989, + 70703, 127031, 0, 9873, 0, 0, 0, 64762, 2053, 0, 6591, 9340, 0, 1589, 0, + 296, 67712, 128315, 12766, 118931, 74370, 120417, 2414, 128068, 43829, + 111202, 74836, 0, 12579, 0, 12575, 6416, 5656, 0, 13262, 65590, 5299, + 983702, 0, 5449, 1252, 0, 78404, 69748, 74369, 65373, 5295, 0, 121066, + 1223, 1642, 78408, 0, 12158, 5303, 0, 120546, 41413, 3212, 127025, 3211, + 74810, 41425, 127029, 0, 74450, 9728, 0, 10924, 74778, 6636, 73552, + 129884, 0, 0, 129882, 9519, 0, 0, 129106, 101110, 68780, 0, 0, 0, 119182, + 0, 12104, 77942, 77951, 9004, 0, 74249, 10230, 0, 0, 0, 77947, 0, 69679, + 121475, 9890, 125049, 12971, 0, 92556, 0, 67903, 70051, 983924, 0, 0, + 9635, 12600, 0, 0, 0, 118900, 6469, 0, 101113, 65304, 4679, 101114, + 64300, 64867, 6531, 101118, 101099, 101098, 92813, 101100, 42916, 0, 0, + 0, 0, 0, 0, 4445, 72296, 0, 11533, 0, 3416, 124112, 0, 0, 0, 78566, 0, 0, + 101091, 92815, 101093, 5447, 72140, 70752, 101097, 101096, 0, 0, 0, + 64448, 0, 43920, 70677, 0, 6232, 101101, 101104, 101103, 43608, 101105, + 101108, 6538, 4335, 0, 3941, 74986, 11061, 0, 74988, 74987, 0, 12155, + 128278, 0, 0, 0, 0, 74578, 0, 65832, 0, 129459, 70789, 0, 125050, 0, 0, + 350, 10951, 101081, 509, 101083, 101086, 101085, 0, 0, 0, 917540, 0, + 100905, 110970, 12162, 64741, 0, 9354, 0, 70802, 100901, 2496, 11516, + 944, 128238, 0, 0, 1438, 0, 0, 120185, 70785, 1220, 917952, 93844, 0, 0, + 5008, 42630, 70787, 101087, 2229, 68206, 564, 0, 312, 0, 0, 0, 70797, + 8877, 269, 0, 128065, 9617, 0, 0, 100910, 0, 0, 10862, 0, 0, 41416, 0, + 4173, 0, 0, 0, 1906, 983854, 41418, 74073, 101068, 101067, 41415, 69622, + 9582, 0, 64287, 0, 0, 11428, 1730, 0, 0, 19918, 10469, 101076, 101079, + 68088, 0, 101080, 72342, 0, 129692, 0, 6129, 0, 0, 0, 0, 7874, 0, 0, + 11206, 13136, 118529, 129305, 0, 64374, 74925, 0, 73892, 0, 101073, + 101072, 101075, 74960, 9228, 101054, 101057, 101056, 5240, 9811, 0, + 101060, 129718, 0, 0, 74079, 65873, 0, 0, 0, 9501, 0, 68081, 72808, + 65465, 64654, 7467, 0, 0, 83460, 10040, 0, 3096, 0, 101053, 101052, + 68820, 83461, 0, 0, 0, 0, 0, 0, 83377, 0, 68801, 0, 101062, 101061, + 101064, 101063, 0, 8637, 70741, 0, 77983, 77969, 11471, 43554, 0, 77968, + 0, 0, 0, 2426, 12042, 0, 0, 0, 3961, 12115, 129633, 0, 77972, 64561, 0, + 4981, 74644, 129558, 0, 0, 42686, 77976, 128776, 64686, 0, 77958, 7589, + 0, 0, 3237, 0, 68215, 0, 8541, 127157, 71067, 120174, 0, 0, 0, 0, 0, + 43555, 0, 0, 10060, 111261, 100917, 0, 0, 0, 64877, 0, 0, 8614, 65220, + 41493, 0, 0, 0, 43780, 0, 0, 70689, 0, 0, 0, 0, 0, 0, 4012, 10395, 0, 0, + 111253, 126511, 111254, 125051, 695, 739, 696, 7611, 0, 42755, 68421, + 9227, 7506, 7510, 67493, 691, 738, 7511, 7512, 7515, 7501, 688, 41847, + 690, 2548, 737, 974, 43386, 0, 0, 0, 0, 0, 0, 65860, 0, 7051, 69777, + 4682, 0, 983096, 6406, 4685, 0, 0, 10347, 4680, 6341, 0, 0, 92607, 74325, + 0, 123555, 0, 0, 0, 0, 0, 0, 43505, 92468, 11718, 42373, 11714, 0, 0, + 129567, 11717, 0, 10594, 129732, 11712, 122962, 0, 10967, 0, 0, 0, 66632, + 118647, 0, 0, 0, 1735, 0, 11134, 2363, 983136, 0, 0, 70695, 128032, 0, 7491, 7495, 7580, 7496, 7497, 7584, 121478, 127853, 0, 0, 70025, 0, 8498, 0, 8949, 3065, 0, 0, 0, 0, 0, 0, 11713, 0, 64939, 0, 6418, 4543, 0, 0, 0, 74800, 0, 0, 0, 0, 0, 0, 0, 12282, 3165, 0, 0, 64556, 0, 9238, 0, 68063, @@ -28100,166 +28291,167 @@ static const unsigned int code_hash[] = { 41400, 126636, 119664, 0, 42232, 0, 1744, 0, 41402, 0, 0, 0, 41399, 0, 125028, 0, 0, 12690, 0, 0, 43672, 0, 0, 0, 100870, 11315, 0, 278, 121204, 41405, 129345, 0, 10077, 129650, 70667, 0, 0, 0, 68210, 0, 0, 11189, - 70657, 0, 0, 0, 7934, 0, 93829, 120940, 0, 0, 0, 0, 0, 0, 6413, 6550, 0, - 1940, 2809, 43637, 70045, 0, 0, 10678, 0, 0, 0, 129701, 78804, 6403, - 6556, 78803, 0, 0, 123557, 0, 0, 0, 123553, 0, 3742, 74408, 3959, 0, 0, - 917969, 123565, 0, 128024, 0, 123558, 127956, 0, 0, 0, 6855, 4676, + 70657, 0, 0, 0, 7934, 0, 93829, 120940, 0, 0, 122971, 0, 0, 0, 6413, + 6550, 0, 1940, 2809, 43637, 70045, 0, 0, 10678, 0, 0, 0, 129701, 78804, + 6403, 6556, 78803, 0, 0, 123557, 0, 0, 0, 123553, 0, 3742, 74408, 3959, + 0, 0, 917969, 123565, 0, 128024, 0, 123558, 127956, 0, 0, 0, 6855, 4676, 983049, 9210, 0, 78143, 983922, 0, 78168, 983100, 11540, 43546, 6692, 0, 0, 0, 0, 9083, 0, 0, 78144, 128515, 0, 9677, 0, 70867, 74175, 0, 74070, 0, 0, 365, 0, 43027, 0, 0, 128236, 0, 119574, 70284, 13151, 0, 0, 127935, 127950, 544, 13249, 119018, 0, 120846, 0, 0, 73671, 65339, 73000, 2211, - 0, 0, 0, 0, 0, 0, 0, 0, 128037, 0, 0, 0, 0, 0, 0, 0, 127188, 0, 69708, - 9638, 0, 100878, 0, 0, 0, 74545, 128820, 128819, 75062, 128963, 0, 0, 0, - 11264, 43994, 0, 0, 0, 1311, 0, 0, 0, 0, 13068, 0, 0, 78164, 78155, 0, - 949, 0, 0, 0, 78176, 69709, 78177, 63828, 0, 0, 118629, 70282, 0, 0, 0, - 64822, 0, 6530, 983272, 0, 70493, 0, 129325, 0, 0, 4431, 118839, 127490, - 983760, 73667, 127986, 0, 10336, 10400, 0, 0, 92959, 0, 0, 0, 42270, - 128880, 6428, 0, 0, 0, 0, 43455, 0, 43526, 100888, 12835, 129501, 9493, - 0, 0, 11793, 0, 127897, 74394, 0, 10653, 0, 0, 0, 0, 6560, 7016, 74274, - 983627, 43556, 3929, 123615, 6614, 2768, 0, 65609, 0, 11811, 129696, 0, - 118615, 127513, 0, 6554, 0, 6305, 66283, 4675, 118826, 78552, 0, 0, - 74361, 0, 0, 68108, 0, 0, 92232, 0, 93022, 7392, 8230, 9365, 983742, 0, - 0, 0, 0, 42925, 0, 0, 0, 0, 229, 43834, 119884, 0, 43552, 119881, 119880, - 119883, 119882, 119877, 119876, 119879, 119878, 119873, 119872, 119875, - 119874, 0, 0, 0, 0, 0, 66352, 0, 0, 0, 128663, 0, 12239, 0, 0, 10432, - 12097, 0, 194815, 1233, 0, 0, 127200, 0, 66395, 0, 0, 129504, 0, 0, 0, 0, - 2388, 92555, 119868, 119871, 119870, 119865, 895, 92668, 119866, 64889, - 7143, 119863, 119862, 0, 0, 69983, 0, 74376, 3053, 2168, 0, 2047, 0, 0, - 0, 121279, 67985, 194801, 92600, 194803, 194802, 194805, 194804, 194807, - 194806, 129134, 194808, 0, 0, 0, 10473, 129331, 0, 194810, 129806, - 194812, 129813, 194814, 194813, 123195, 43528, 69673, 194791, 0, 194793, - 1912, 120779, 10306, 10370, 0, 0, 8867, 10250, 10258, 10274, 1635, - 120152, 0, 0, 0, 129379, 0, 0, 9919, 120148, 559, 128157, 41825, 127975, - 92989, 0, 74016, 194781, 6542, 41957, 7318, 0, 0, 41956, 65749, 65750, - 65751, 121323, 64487, 0, 0, 10223, 42062, 100640, 101195, 125044, 3668, - 65754, 43560, 12226, 0, 93973, 194784, 41959, 194786, 194785, 194788, - 43618, 65747, 10937, 2962, 0, 2953, 10062, 65745, 71457, 8921, 66013, - 129370, 0, 194769, 194768, 43409, 194770, 2949, 194772, 194775, 194774, - 2958, 194776, 74868, 2300, 2951, 120061, 0, 120043, 194778, 0, 120051, - 194779, 120056, 120065, 70798, 120048, 0, 120062, 120055, 71989, 100668, - 0, 0, 71985, 0, 71992, 70796, 127818, 0, 0, 64890, 0, 43630, 11336, 799, - 0, 10276, 10308, 10372, 917541, 0, 0, 10252, 10260, 68220, 55284, 125225, - 0, 10384, 0, 0, 0, 64523, 129744, 0, 65736, 0, 0, 0, 0, 0, 0, 0, 124912, - 43549, 65738, 42150, 65739, 0, 78195, 10288, 10320, 0, 10596, 129829, - 67673, 65045, 121283, 78198, 2049, 10098, 0, 122904, 127943, 10264, - 10280, 10312, 10376, 7013, 0, 69504, 0, 0, 66375, 0, 4862, 0, 6537, 0, - 128335, 3914, 92178, 93976, 9065, 64816, 0, 72218, 73026, 0, 0, 72139, - 4694, 11420, 4690, 0, 0, 983209, 4693, 0, 0, 0, 4688, 0, 0, 0, 0, 8238, - 3110, 0, 983939, 0, 6528, 0, 0, 0, 218, 0, 1520, 129577, 70039, 0, - 983594, 0, 120167, 78167, 10088, 6548, 100786, 0, 0, 0, 8888, 0, 124954, - 0, 0, 126593, 68876, 0, 0, 0, 0, 0, 0, 0, 4689, 43541, 77954, 120157, 0, - 120156, 78810, 120163, 0, 0, 0, 0, 78121, 0, 0, 11450, 0, 71900, 92613, - 0, 121317, 74622, 128720, 9244, 0, 0, 127763, 0, 0, 0, 0, 0, 0, 71084, 0, - 0, 0, 0, 10513, 0, 0, 0, 52, 119178, 0, 0, 93961, 0, 0, 4812, 0, 0, 0, 0, - 0, 0, 128425, 0, 6850, 0, 77959, 10170, 120450, 6544, 0, 0, 69782, - 121517, 0, 0, 65258, 10369, 0, 1585, 74014, 10249, 422, 1500, 2036, 986, - 0, 64394, 69502, 5599, 917981, 2494, 0, 0, 74021, 983896, 78203, 127808, - 0, 72871, 65102, 8961, 74305, 10243, 10245, 128170, 0, 0, 0, 0, 0, 2508, - 129591, 120440, 0, 120439, 0, 0, 0, 0, 0, 0, 64533, 983186, 0, 0, 74008, - 0, 0, 43375, 0, 2504, 0, 121313, 0, 983941, 6943, 0, 5859, 100677, 0, 0, - 72873, 983945, 0, 0, 983923, 92390, 2753, 1936, 2153, 67701, 2751, 12662, - 2763, 8953, 0, 10731, 0, 7052, 0, 0, 0, 0, 119899, 0, 66675, 0, 119897, - 0, 71053, 0, 119903, 0, 67829, 7899, 119901, 71119, 43798, 7072, 119902, - 122898, 11260, 0, 71059, 0, 0, 212, 0, 12350, 0, 0, 0, 0, 0, 128402, - 2759, 0, 0, 93064, 0, 0, 0, 1291, 0, 195065, 121318, 119911, 0, 119910, - 0, 12062, 0, 121216, 0, 129124, 121044, 120611, 8246, 128874, 0, 0, 0, 0, - 0, 73962, 0, 0, 43524, 0, 64426, 0, 0, 0, 0, 65664, 6693, 0, 0, 8674, 0, - 128812, 0, 11846, 70690, 121461, 69395, 4811, 0, 5986, 0, 3046, 74480, - 5985, 0, 0, 0, 0, 12187, 83148, 71041, 5984, 0, 93817, 4393, 126264, - 120206, 917599, 0, 0, 0, 93806, 93805, 0, 3491, 0, 67146, 0, 93819, 0, - 72428, 0, 0, 0, 124968, 41284, 126228, 0, 0, 41287, 0, 100689, 0, 0, - 92189, 0, 0, 219, 120874, 0, 0, 0, 68485, 119672, 43241, 0, 7147, 0, 0, - 0, 0, 0, 0, 64610, 11804, 0, 7149, 64808, 0, 0, 0, 92301, 73690, 0, 5253, - 0, 0, 0, 0, 129045, 983596, 11098, 68433, 0, 120484, 111009, 0, 0, 0, 0, - 0, 70801, 100779, 0, 128198, 9604, 0, 130036, 0, 0, 118941, 64392, 0, - 118684, 0, 0, 41974, 126262, 0, 0, 0, 129818, 0, 129833, 0, 0, 0, 0, 0, - 983240, 5308, 0, 290, 0, 125278, 128382, 2792, 0, 0, 120521, 0, 126237, - 0, 126099, 0, 0, 0, 0, 128503, 0, 0, 72816, 0, 0, 0, 92671, 0, 195061, - 42646, 7606, 2591, 73896, 0, 43513, 64482, 0, 0, 65270, 0, 0, 983701, - 9112, 0, 113763, 9490, 0, 0, 0, 0, 0, 9071, 0, 0, 0, 0, 74607, 0, 2535, - 65504, 43602, 0, 0, 71256, 2248, 0, 123147, 11845, 11006, 92315, 7807, - 8073, 0, 10629, 0, 74088, 0, 10823, 0, 113762, 8762, 0, 69689, 123536, - 43969, 65047, 10737, 3463, 67467, 129585, 66645, 0, 4815, 0, 0, 12345, - 983761, 0, 5195, 129808, 0, 66639, 0, 0, 66941, 0, 92759, 92385, 1262, 0, - 6561, 19939, 0, 0, 100772, 123160, 69269, 0, 100774, 0, 0, 0, 0, 0, 0, - 67511, 0, 0, 0, 0, 0, 0, 5702, 3655, 0, 8430, 0, 68807, 0, 0, 121137, 0, - 0, 5254, 0, 0, 124917, 0, 119107, 5129, 0, 70816, 0, 92280, 5614, 0, 0, - 11720, 0, 11721, 70804, 4798, 0, 120541, 66038, 4793, 67851, 7352, 0, 0, - 0, 0, 917600, 0, 300, 0, 0, 128575, 92660, 0, 0, 2562, 70156, 120856, 0, - 0, 92738, 0, 0, 127820, 71093, 0, 127969, 128221, 0, 3424, 93843, 0, 0, - 7074, 70873, 128519, 0, 0, 10832, 0, 0, 69852, 72430, 0, 0, 0, 0, 0, 176, - 0, 0, 0, 0, 0, 1215, 0, 5744, 0, 66440, 0, 0, 0, 42881, 0, 8980, 118988, - 67861, 8844, 7433, 0, 0, 4278, 124925, 0, 0, 70821, 9312, 4348, 0, - 128401, 65946, 0, 7087, 5255, 0, 661, 0, 0, 0, 0, 0, 0, 0, 121009, 73694, - 0, 123154, 0, 73688, 0, 127179, 3621, 83325, 66666, 72968, 0, 6562, - 12928, 0, 73991, 0, 0, 11383, 0, 0, 65588, 120739, 0, 0, 0, 0, 0, 0, 0, - 0, 11436, 2070, 64, 110824, 0, 10291, 10323, 10387, 0, 0, 0, 42008, 9708, - 42710, 0, 42011, 0, 92164, 0, 0, 1702, 1240, 128383, 6286, 9689, 111080, - 0, 0, 0, 1765, 0, 0, 92373, 0, 0, 0, 8401, 72991, 42014, 0, 67237, 0, 0, - 0, 0, 0, 0, 0, 70819, 0, 0, 0, 0, 12667, 0, 0, 10147, 0, 127568, 126483, - 72812, 0, 0, 0, 0, 123139, 128968, 0, 64947, 0, 0, 0, 0, 10435, 11462, 0, - 7084, 0, 0, 0, 0, 0, 126084, 0, 66662, 0, 0, 0, 0, 125134, 0, 0, 77990, - 263, 983747, 41288, 127953, 0, 78387, 74340, 70313, 129140, 0, 0, 0, - 42022, 71265, 0, 0, 0, 0, 0, 0, 42020, 123146, 0, 6992, 42019, 0, 41290, - 0, 12295, 126233, 71304, 0, 120984, 71300, 120631, 5954, 64931, 69385, - 100699, 198, 68453, 78129, 0, 121351, 0, 70818, 13165, 7107, 0, 42804, - 678, 72850, 118960, 0, 72985, 42806, 42808, 0, 0, 2097, 0, 120560, 70823, - 0, 0, 3892, 68632, 0, 6712, 917959, 0, 0, 0, 0, 123158, 69954, 0, 497, - 12100, 5953, 92667, 7796, 0, 43254, 0, 0, 11072, 5952, 1281, 43747, 0, - 69380, 10677, 0, 0, 0, 1859, 0, 72856, 3425, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 65199, 1738, 0, 122911, 0, 0, 0, 11101, 0, 0, 0, 0, 127002, 69651, - 4436, 194683, 73984, 6860, 70305, 64872, 128296, 0, 0, 0, 121377, 0, - 6862, 0, 6861, 983108, 0, 119109, 0, 70826, 319, 0, 43479, 73001, 0, 0, - 12849, 0, 7640, 71083, 9673, 0, 0, 0, 92670, 0, 92665, 113717, 41422, 0, - 100708, 74941, 3772, 0, 120660, 5011, 0, 0, 126587, 111315, 0, 0, 6677, - 111312, 0, 41427, 64419, 129445, 92262, 0, 70799, 0, 0, 0, 6106, 0, - 41271, 6760, 983758, 4534, 41270, 128876, 0, 0, 119561, 0, 0, 3671, 8976, - 123177, 0, 41275, 0, 128084, 55261, 0, 42013, 0, 568, 0, 41273, 0, 0, - 6728, 0, 9715, 0, 0, 121058, 74820, 0, 92268, 0, 194564, 11191, 43688, - 128023, 0, 0, 0, 126266, 0, 0, 0, 11958, 11165, 0, 125087, 0, 0, 66336, - 127944, 0, 0, 0, 0, 42858, 11789, 72878, 5557, 0, 69444, 7300, 0, 9467, - 5558, 64486, 43844, 0, 0, 6706, 10146, 0, 127185, 64566, 0, 0, 0, 0, 0, - 0, 0, 4546, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64528, 123136, 6307, 128966, 0, - 7544, 0, 43469, 111317, 0, 10152, 0, 65091, 0, 0, 0, 0, 66652, 0, 0, 0, - 0, 64823, 5559, 0, 70711, 6702, 5556, 0, 0, 0, 0, 0, 11166, 0, 0, 5506, - 0, 1911, 73021, 0, 12598, 8845, 66698, 0, 73012, 123145, 0, 2098, 0, 0, - 0, 66622, 194678, 0, 0, 0, 9898, 0, 0, 7552, 0, 0, 0, 7223, 65723, 0, 0, - 0, 7024, 65728, 127155, 1210, 0, 65175, 10184, 65726, 43654, 0, 0, 0, 38, - 65729, 66669, 0, 917948, 0, 0, 0, 0, 0, 0, 74233, 73018, 119843, 42860, - 111301, 92576, 65721, 65722, 0, 0, 0, 0, 68843, 0, 68850, 0, 92388, - 92267, 128536, 65577, 42967, 0, 127518, 11650, 5013, 92663, 68810, 92568, - 118914, 6613, 74371, 0, 0, 0, 0, 64714, 71479, 0, 983797, 12120, 0, 0, - 43124, 0, 0, 78037, 69263, 0, 126219, 0, 0, 1837, 125086, 0, 0, 0, - 127210, 4952, 65718, 64405, 5504, 65720, 65714, 65715, 65716, 10403, - 127005, 0, 41449, 0, 74028, 72019, 0, 119234, 1127, 455, 0, 0, 72860, - 3483, 0, 1989, 0, 69678, 9104, 0, 65375, 0, 0, 0, 1864, 0, 72810, 8107, - 2540, 0, 0, 11257, 128807, 119576, 0, 120999, 0, 0, 8604, 0, 0, 0, 0, - 128270, 0, 0, 3115, 0, 10106, 120498, 118842, 101136, 0, 9631, 0, 0, 0, - 0, 0, 0, 0, 258, 129079, 0, 0, 0, 92292, 0, 70699, 0, 11478, 0, 129640, - 11522, 0, 8549, 0, 128430, 0, 0, 0, 0, 0, 0, 123140, 0, 0, 0, 9221, - 12590, 73048, 0, 0, 0, 67741, 111294, 12619, 0, 10154, 111266, 74439, - 2039, 0, 7446, 0, 111276, 10974, 458, 72831, 0, 0, 0, 11916, 0, 0, 69671, - 0, 121057, 12288, 0, 111288, 0, 111289, 983176, 0, 128199, 13080, 0, - 67828, 6610, 6030, 8059, 7508, 123170, 0, 0, 0, 0, 41278, 129393, 118691, - 128192, 41277, 64658, 984002, 101278, 6625, 983159, 19904, 0, 0, 0, 0, 0, - 0, 833, 0, 6369, 0, 0, 42664, 0, 0, 0, 0, 129765, 0, 6913, 933, 1341, - 68828, 6720, 0, 0, 983604, 0, 0, 7405, 128025, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 128037, 0, 0, 0, 0, 0, 0, 0, 127188, 92977, + 69708, 9638, 0, 100878, 0, 0, 0, 74545, 128820, 128819, 75062, 128963, 0, + 0, 0, 11264, 43994, 0, 0, 0, 1311, 0, 0, 0, 0, 13068, 0, 0, 78164, 78155, + 0, 949, 0, 0, 0, 78176, 69709, 78177, 63828, 0, 0, 118629, 70282, 0, 0, + 0, 64822, 0, 6530, 983275, 0, 70493, 0, 129325, 0, 0, 4431, 118839, + 127490, 983760, 73667, 127986, 0, 10336, 10400, 0, 0, 92959, 0, 0, 0, + 42270, 128880, 6428, 0, 0, 0, 0, 43455, 0, 43526, 100888, 12835, 129501, + 9493, 0, 0, 11793, 0, 127897, 74394, 0, 10653, 0, 0, 0, 0, 6560, 7016, + 74274, 983627, 43556, 3929, 123615, 6614, 2768, 0, 65609, 0, 11811, + 129696, 0, 118615, 127513, 0, 6554, 0, 6305, 66283, 4675, 118826, 78552, + 0, 0, 74361, 0, 0, 68108, 0, 0, 92232, 0, 93022, 7392, 8230, 9365, + 983742, 0, 0, 0, 0, 42925, 0, 0, 122965, 0, 229, 43834, 119884, 0, 43552, + 119881, 119880, 119883, 119882, 119877, 119876, 119879, 119878, 119873, + 119872, 119875, 119874, 0, 0, 0, 0, 0, 66352, 0, 0, 0, 128663, 0, 12239, + 0, 0, 10432, 12097, 0, 194815, 1233, 78179, 0, 127200, 0, 66395, 0, 0, + 129504, 0, 0, 92342, 0, 2388, 92555, 119868, 119871, 119870, 119865, 895, + 92668, 119866, 64889, 7143, 119863, 119862, 0, 0, 69983, 0, 74376, 3053, + 2168, 0, 2047, 0, 0, 0, 121279, 67985, 194801, 92600, 194803, 194802, + 194805, 194804, 194807, 194806, 129134, 194808, 0, 0, 0, 10473, 129331, + 0, 194810, 129806, 194812, 129813, 194814, 194813, 123195, 43528, 69673, + 194791, 0, 194793, 1912, 120779, 10306, 10370, 0, 0, 8867, 10250, 10258, + 10274, 1635, 120152, 0, 0, 0, 129379, 0, 0, 9919, 120148, 559, 128157, + 41825, 127975, 92989, 0, 74016, 194781, 6542, 41957, 7318, 124126, 0, + 41956, 65749, 65750, 65751, 121323, 64487, 0, 0, 10223, 42062, 100640, + 101195, 125044, 3668, 65754, 43560, 12226, 0, 93973, 194784, 41959, + 194786, 194785, 194788, 43618, 65747, 10937, 2962, 0, 2953, 10062, 65745, + 71457, 8921, 66013, 129370, 0, 194769, 194768, 43409, 194770, 2949, + 194772, 194775, 194774, 2958, 194776, 74868, 2300, 2951, 120061, 0, + 120043, 194778, 0, 120051, 194779, 120056, 120065, 70798, 120048, 0, + 120062, 120055, 71989, 100668, 0, 0, 71985, 0, 71992, 70796, 127818, 0, + 0, 64890, 0, 43630, 11336, 799, 0, 10276, 10308, 10372, 917541, 0, 0, + 10252, 10260, 68220, 55284, 125225, 0, 10384, 0, 0, 0, 64523, 129744, 0, + 65736, 0, 0, 0, 0, 0, 0, 0, 124912, 43549, 65738, 42150, 65739, 0, 78195, + 10288, 10320, 0, 10596, 129829, 67673, 65045, 121283, 78198, 2049, 10098, + 0, 122904, 127943, 10264, 10280, 10312, 10376, 7013, 0, 69504, 0, 0, + 66375, 0, 4862, 0, 6537, 0, 128335, 3914, 92178, 93976, 9065, 64816, 0, + 72218, 73026, 0, 0, 72139, 4694, 11420, 4690, 0, 0, 983211, 4693, 0, 0, + 0, 4688, 0, 0, 128892, 0, 8238, 3110, 0, 983939, 0, 6528, 0, 0, 0, 218, + 0, 1520, 129577, 70039, 0, 983594, 0, 120167, 78167, 10088, 6548, 100786, + 0, 0, 0, 8888, 0, 124954, 0, 0, 126593, 68876, 0, 0, 0, 0, 0, 0, 0, 4689, + 43541, 77954, 120157, 0, 120156, 78810, 120163, 0, 0, 0, 0, 78121, 0, 0, + 11450, 0, 71900, 92613, 0, 121317, 74622, 128720, 9244, 0, 0, 127763, 0, + 0, 0, 0, 0, 0, 71084, 0, 0, 0, 0, 10513, 0, 0, 0, 52, 119178, 0, 0, + 93961, 0, 0, 4812, 0, 0, 0, 0, 0, 0, 128425, 0, 6850, 0, 77959, 10170, + 120450, 6544, 0, 0, 69782, 121517, 0, 0, 65258, 10369, 0, 1585, 74014, + 10249, 422, 1500, 2036, 986, 0, 64394, 69502, 5599, 917981, 2494, 0, 0, + 74021, 983896, 78203, 127808, 0, 72871, 65102, 8961, 74305, 10243, 10245, + 128170, 0, 0, 0, 0, 0, 2508, 129591, 120440, 0, 120439, 0, 0, 0, 0, 0, 0, + 64533, 983187, 0, 0, 74008, 0, 0, 43375, 0, 2504, 0, 121313, 0, 983941, + 6943, 0, 5859, 100677, 0, 0, 72873, 983945, 0, 0, 983923, 92390, 2753, + 1936, 2153, 67701, 2751, 12662, 2763, 8953, 0, 10731, 0, 7052, 0, 0, 0, + 0, 119899, 0, 66675, 0, 119897, 0, 71053, 0, 119903, 0, 67829, 7899, + 119901, 71119, 43798, 7072, 119902, 122898, 11260, 0, 71059, 0, 0, 212, + 0, 12350, 0, 0, 0, 0, 0, 128402, 2759, 0, 0, 93064, 0, 0, 0, 1291, 0, + 195065, 121318, 119911, 0, 119910, 0, 12062, 0, 121216, 0, 129124, + 121044, 120611, 8246, 128874, 0, 0, 0, 0, 0, 73962, 0, 0, 43524, 0, + 64426, 0, 0, 0, 0, 65664, 6693, 0, 0, 8674, 0, 128812, 0, 11846, 70690, + 121461, 69395, 4811, 0, 5986, 0, 3046, 74480, 5985, 0, 0, 0, 0, 12187, + 83148, 71041, 5984, 0, 93817, 4393, 126264, 120206, 917599, 0, 0, 0, + 93806, 93805, 0, 3491, 0, 67146, 0, 93819, 0, 72428, 0, 0, 0, 124968, + 41284, 126228, 0, 0, 41287, 0, 100689, 0, 0, 92189, 0, 0, 219, 120874, 0, + 0, 0, 68485, 119672, 43241, 0, 7147, 73554, 0, 0, 0, 0, 0, 64610, 11804, + 0, 7149, 64808, 0, 0, 0, 92301, 73690, 0, 5253, 0, 0, 0, 0, 129045, + 983596, 11098, 68433, 0, 120484, 111009, 0, 0, 0, 0, 0, 70801, 100779, 0, + 128198, 9604, 0, 130036, 0, 0, 118941, 64392, 0, 118684, 0, 0, 41974, + 126262, 0, 0, 0, 129818, 0, 129833, 0, 0, 0, 0, 0, 983243, 5308, 0, 290, + 0, 125278, 128382, 2792, 0, 0, 120521, 0, 126237, 0, 126099, 0, 0, 0, 0, + 128503, 0, 0, 72816, 0, 0, 0, 92671, 0, 195061, 42646, 7606, 2591, 73896, + 0, 43513, 64482, 0, 0, 65270, 0, 0, 983701, 9112, 0, 113763, 9490, 0, 0, + 0, 0, 0, 9071, 0, 0, 0, 0, 74607, 0, 2535, 65504, 43602, 0, 0, 71256, + 2248, 0, 123147, 11845, 11006, 92315, 7807, 8073, 0, 10629, 0, 74088, 0, + 10823, 0, 113762, 8762, 0, 69689, 123536, 43969, 65047, 10737, 3463, + 67467, 129585, 66645, 0, 4815, 0, 0, 12345, 983761, 0, 5195, 129808, 0, + 66639, 0, 0, 66941, 0, 92759, 92385, 1262, 0, 6561, 19939, 0, 0, 100772, + 123160, 69269, 0, 100774, 0, 0, 0, 0, 0, 0, 67511, 0, 0, 0, 0, 0, 0, + 5702, 3655, 0, 8430, 0, 68807, 0, 0, 121137, 0, 0, 5254, 0, 0, 124917, 0, + 119107, 5129, 0, 70816, 0, 92280, 5614, 0, 0, 11720, 0, 11721, 70804, + 4798, 0, 120541, 66038, 4793, 67851, 7352, 0, 0, 0, 0, 917600, 0, 300, 0, + 0, 128575, 92660, 0, 0, 2562, 70156, 120856, 0, 0, 92738, 0, 0, 127820, + 71093, 0, 127969, 128221, 0, 3424, 93843, 0, 0, 7074, 70873, 128519, 0, + 0, 10832, 0, 0, 69852, 72430, 0, 0, 0, 0, 0, 176, 0, 0, 0, 0, 0, 1215, 0, + 5744, 0, 66440, 0, 0, 0, 42881, 0, 8980, 118988, 67861, 8844, 7433, 0, 0, + 4278, 124925, 0, 0, 70821, 9312, 4348, 0, 128401, 65946, 0, 7087, 5255, + 0, 661, 0, 0, 0, 0, 0, 0, 0, 121009, 73694, 0, 123154, 0, 73688, 0, + 127179, 3621, 83325, 66666, 72968, 0, 6562, 12928, 0, 73991, 0, 0, 11383, + 0, 0, 65588, 120739, 0, 0, 0, 0, 0, 0, 0, 0, 11436, 2070, 64, 110824, 0, + 10291, 10323, 10387, 0, 0, 0, 42008, 9708, 42710, 0, 42011, 0, 92164, 0, + 0, 1702, 1240, 128383, 6286, 9689, 111080, 0, 0, 0, 1765, 0, 0, 92373, 0, + 0, 0, 8401, 72991, 42014, 0, 67237, 0, 0, 0, 0, 0, 0, 0, 70819, 0, 0, 0, + 0, 12667, 0, 0, 10147, 0, 127568, 126483, 72812, 0, 0, 0, 0, 123139, + 128968, 0, 64947, 0, 0, 0, 0, 10435, 11462, 0, 7084, 0, 0, 0, 0, 0, + 126084, 0, 66662, 0, 0, 0, 0, 125134, 0, 0, 77990, 263, 983747, 41288, + 127953, 0, 78387, 74340, 70313, 129140, 0, 0, 0, 42022, 71265, 0, 0, 0, + 0, 0, 0, 42020, 123146, 0, 6992, 42019, 0, 41290, 0, 12295, 126233, + 71304, 0, 120984, 71300, 120631, 5954, 64931, 69385, 100699, 198, 68453, + 78129, 0, 121351, 0, 70818, 13165, 7107, 0, 42804, 678, 72850, 118960, 0, + 72985, 42806, 42808, 0, 0, 2097, 0, 120560, 70823, 0, 0, 3892, 68632, 0, + 6712, 917959, 0, 0, 0, 0, 123158, 69954, 0, 497, 12100, 5953, 92667, + 7796, 0, 43254, 0, 0, 11072, 5952, 1281, 43747, 0, 69380, 10677, 0, 0, 0, + 1859, 0, 72856, 3425, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65199, 1738, 0, + 122911, 0, 0, 0, 11101, 0, 0, 0, 0, 127002, 69651, 4436, 194683, 73984, + 6860, 70305, 64872, 128296, 0, 0, 0, 121377, 0, 6862, 0, 6861, 983109, 0, + 119109, 0, 70826, 319, 0, 43479, 73001, 0, 0, 12849, 0, 7640, 71083, + 9673, 0, 0, 0, 92670, 0, 92665, 113717, 41422, 0, 100708, 74941, 3772, 0, + 120660, 5011, 0, 0, 126587, 111315, 0, 0, 6677, 111312, 0, 41427, 64419, + 129445, 92262, 0, 70799, 0, 0, 0, 6106, 0, 41271, 6760, 983758, 4534, + 41270, 128876, 0, 0, 119561, 0, 0, 3671, 8976, 123177, 0, 41275, 0, + 128084, 55261, 0, 42013, 0, 568, 0, 41273, 0, 0, 6728, 0, 9715, 0, 0, + 121058, 74820, 0, 92268, 0, 194564, 11191, 43688, 128023, 0, 0, 0, + 126266, 0, 0, 0, 11958, 11165, 0, 125087, 0, 0, 66336, 127944, 0, 0, 0, + 0, 42858, 11789, 72878, 5557, 0, 69444, 7300, 0, 9467, 5558, 64486, + 43844, 0, 0, 6706, 10146, 0, 127185, 64566, 0, 0, 0, 0, 0, 0, 0, 4546, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 64528, 123136, 6307, 128966, 0, 7544, 0, 43469, + 111317, 0, 10152, 0, 65091, 0, 129047, 0, 0, 66652, 0, 0, 0, 0, 64823, + 5559, 0, 70711, 6702, 5556, 0, 0, 0, 0, 0, 11166, 0, 0, 5506, 0, 1911, + 73021, 0, 12598, 8845, 66698, 0, 73012, 123145, 73496, 2098, 0, 0, 0, + 66622, 194678, 0, 0, 0, 9898, 0, 0, 7552, 0, 0, 0, 7223, 65723, 0, 0, 0, + 7024, 65728, 127155, 1210, 0, 65175, 10184, 65726, 43654, 0, 0, 0, 38, + 65729, 66669, 0, 917948, 0, 0, 0, 0, 119837, 0, 74233, 73018, 119843, + 42860, 111301, 92576, 65721, 65722, 0, 0, 0, 0, 68843, 0, 68850, 0, + 92388, 92267, 128536, 65577, 42967, 0, 127518, 11650, 5013, 92663, 68810, + 92568, 118914, 6613, 74371, 0, 0, 122985, 0, 64714, 71479, 0, 983797, + 12120, 0, 0, 43124, 0, 0, 78037, 69263, 0, 126219, 0, 0, 1837, 125086, 0, + 0, 0, 127210, 4952, 65718, 64405, 5504, 65720, 65714, 65715, 65716, + 10403, 127005, 0, 41449, 0, 74028, 72019, 0, 119234, 1127, 455, 0, 0, + 72860, 3483, 0, 1989, 0, 69678, 9104, 0, 65375, 0, 0, 0, 1864, 0, 72810, + 8107, 2540, 0, 0, 11257, 128807, 119576, 0, 120999, 0, 73501, 8604, 0, 0, + 0, 0, 128270, 0, 0, 3115, 0, 10106, 120498, 118842, 101136, 0, 9631, 0, + 0, 0, 0, 0, 0, 0, 258, 129079, 0, 0, 0, 92292, 0, 70699, 0, 11478, 0, + 129640, 11522, 0, 8549, 0, 128430, 0, 0, 0, 0, 0, 0, 123140, 0, 0, 0, + 9221, 12590, 73048, 0, 0, 0, 67741, 111294, 12619, 0, 10154, 111266, + 74439, 2039, 0, 7446, 0, 111276, 10974, 458, 72831, 0, 0, 0, 11916, 0, 0, + 69671, 0, 121057, 12288, 0, 111288, 0, 111289, 983177, 0, 128199, 13080, + 0, 67828, 6610, 6030, 8059, 7508, 123170, 0, 0, 0, 0, 41278, 129393, + 118691, 128192, 41277, 64658, 984002, 101278, 6625, 983160, 19904, 0, 0, + 0, 0, 0, 0, 833, 0, 6369, 0, 0, 42664, 0, 0, 0, 0, 129765, 0, 6913, 933, + 1341, 68828, 6720, 0, 0, 983604, 0, 0, 7405, 128025, 0, 0, 0, 0, 0, 0, 0, 70704, 0, 0, 0, 0, 9716, 0, 0, 0, 70719, 0, 0, 0, 0, 72862, 70687, 0, 93987, 0, 0, 0, 70721, 9573, 0, 0, 111245, 83225, 83226, 6949, 126482, 74061, 83222, 83223, 83224, 0, 19962, 83219, 83220, 0, 111233, 0, 42830, 0, 111234, 74236, 66276, 0, 546, 72861, 0, 70661, 0, 472, 11083, 10319, 10383, 917971, 0, 83202, 83203, 3602, 83206, 41182, 83199, 83200, 69796, - 41183, 0, 10271, 10287, 684, 0, 0, 0, 83214, 4592, 83216, 83217, 83210, + 3790, 0, 10271, 10287, 684, 0, 0, 0, 83214, 4592, 83216, 83217, 83210, 11963, 43620, 83213, 0, 0, 83208, 83209, 0, 92623, 128559, 3415, 0, 121267, 0, 0, 123151, 43447, 0, 92212, 0, 418, 0, 0, 10295, 10327, 10391, 0, 83189, 83190, 83192, 83194, 83185, 83186, 83187, 83188, 120879, 0, - 41446, 70700, 118652, 0, 120809, 10599, 66892, 0, 0, 0, 0, 0, 0, 11437, - 0, 0, 0, 0, 0, 0, 12624, 0, 41185, 72865, 69439, 8159, 0, 11686, 71478, - 65224, 0, 4655, 0, 0, 92183, 0, 10343, 10407, 0, 0, 0, 111221, 0, 0, 0, - 94057, 68201, 129574, 0, 983572, 72156, 42792, 5743, 10424, 0, 0, 0, 0, - 0, 8875, 111225, 0, 917991, 13117, 12847, 4651, 118917, 0, 962, 0, 0, - 2242, 42564, 0, 1582, 0, 5508, 0, 0, 0, 10801, 123602, 118798, 73705, 0, - 66911, 10439, 66891, 0, 0, 7860, 0, 906, 917985, 0, 6405, 64722, 0, + 41446, 70700, 118652, 0, 120809, 10599, 66892, 0, 0, 0, 0, 0, 129184, + 11437, 0, 0, 0, 0, 0, 0, 12624, 0, 41185, 72865, 69439, 8159, 0, 11686, + 71478, 65224, 0, 4655, 0, 0, 92183, 0, 10343, 10407, 0, 0, 0, 111221, 0, + 0, 0, 94057, 68201, 129574, 0, 983572, 72156, 42792, 5743, 10424, 0, 0, + 0, 0, 0, 8875, 111225, 0, 917991, 13117, 12847, 4651, 118917, 0, 962, 0, + 0, 2242, 42564, 0, 1582, 0, 5508, 0, 0, 0, 10801, 123602, 118798, 73705, + 0, 66911, 10439, 66891, 0, 0, 7860, 0, 906, 917985, 0, 6405, 64722, 0, 83266, 64694, 83268, 917990, 1153, 83263, 64788, 83265, 0, 12626, 83260, 83261, 9964, 0, 0, 4642, 66574, 127886, 0, 0, 0, 0, 0, 9008, 100847, 0, 0, 0, 83248, 917976, 917993, 123173, 42842, 83244, 83245, 83247, 83239, @@ -28267,344 +28459,345 @@ static const unsigned int code_hash[] = { 41967, 83258, 83251, 83252, 83253, 8920, 0, 0, 83249, 83250, 0, 0, 43919, 0, 0, 0, 0, 128021, 0, 68113, 65196, 0, 0, 128472, 0, 10111, 64875, 0, 83491, 43998, 83232, 83233, 83234, 70691, 83228, 42149, 83230, 68508, 0, - 0, 0, 0, 0, 0, 0, 4110, 66005, 74034, 0, 0, 0, 66703, 0, 0, 983157, 6025, - 69242, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70733, 0, 983043, 0, 0, 0, 68817, 0, 0, - 0, 0, 0, 0, 43286, 0, 68765, 0, 0, 0, 0, 129871, 65144, 0, 0, 83236, - 65840, 0, 0, 10081, 0, 0, 983912, 0, 0, 0, 127394, 65882, 0, 128758, 0, - 0, 3605, 10985, 0, 0, 128872, 93972, 1745, 0, 73835, 0, 0, 0, 0, 0, 0, - 8806, 7023, 0, 0, 0, 70702, 70304, 0, 0, 0, 0, 0, 0, 0, 0, 348, 10089, 0, - 9017, 0, 0, 0, 0, 0, 0, 0, 67465, 0, 42515, 0, 0, 0, 0, 5391, 983237, - 110576, 0, 0, 5561, 0, 9429, 0, 67150, 7933, 5562, 0, 0, 0, 0, 78039, 0, - 0, 0, 0, 3979, 71248, 0, 0, 0, 68847, 0, 0, 118847, 65847, 68836, 68838, - 0, 10585, 0, 92676, 7334, 0, 0, 0, 831, 0, 0, 10716, 0, 121325, 0, 12218, - 0, 6939, 70697, 65042, 0, 0, 916, 0, 0, 11968, 0, 122641, 5563, 0, 0, - 128830, 5560, 41212, 41774, 0, 4497, 0, 0, 0, 9039, 70678, 41776, 0, - 8716, 3567, 119252, 0, 0, 74260, 0, 93954, 0, 0, 100827, 0, 128879, - 70072, 68355, 68357, 0, 0, 8634, 0, 0, 4209, 120702, 68832, 65879, 68825, - 68819, 68822, 0, 5679, 68813, 68815, 68811, 68812, 64697, 5678, 11821, - 68802, 93969, 0, 0, 0, 0, 70114, 0, 0, 0, 0, 0, 0, 0, 0, 7782, 0, 0, 0, - 0, 129977, 65711, 65712, 1216, 0, 69409, 5792, 0, 0, 0, 0, 0, 12244, 0, - 5683, 0, 120895, 121336, 43448, 70670, 0, 0, 5682, 10242, 75043, 74520, - 5680, 917568, 10001, 0, 0, 1449, 10241, 0, 70708, 0, 0, 83180, 83182, - 83183, 8584, 83176, 5567, 83178, 83179, 0, 5564, 42886, 42884, 42882, - 5565, 119022, 120881, 0, 65708, 65709, 5566, 0, 65704, 65705, 11904, - 42875, 0, 42873, 5942, 0, 0, 10361, 10425, 65697, 65698, 65699, 0, 66598, - 0, 64664, 10647, 78702, 78703, 78690, 78700, 0, 65701, 1934, 0, 0, 0, - 78710, 0, 78706, 78709, 6087, 78705, 78716, 78719, 78711, 8043, 8950, - 65694, 64485, 0, 10457, 0, 78724, 78725, 78722, 72332, 78720, 78721, 0, - 65515, 0, 10035, 13069, 0, 0, 127773, 0, 0, 0, 125207, 0, 0, 1667, 0, 0, - 42428, 110950, 0, 0, 41750, 0, 0, 93999, 0, 8101, 3610, 113670, 41748, - 110948, 0, 78394, 119208, 0, 0, 113691, 64549, 68359, 0, 0, 65692, 92701, - 0, 917960, 12896, 10456, 68298, 0, 0, 0, 0, 917962, 0, 0, 113665, 70502, - 0, 65687, 0, 0, 74009, 0, 113673, 8536, 70671, 0, 78726, 0, 724, 0, - 113675, 78749, 9975, 78746, 78747, 78744, 4175, 78741, 78743, 78751, 939, - 0, 128799, 983119, 0, 0, 0, 78763, 78764, 78760, 78761, 78758, 78759, - 78755, 8425, 0, 0, 0, 8188, 0, 0, 0, 0, 0, 6370, 0, 7827, 68441, 75008, - 0, 917943, 0, 118863, 0, 0, 0, 0, 121243, 73988, 0, 113668, 0, 11012, 0, - 43764, 178, 12972, 74620, 113671, 0, 113735, 0, 66764, 0, 0, 65690, - 72339, 0, 0, 917950, 9252, 0, 4652, 74259, 0, 917947, 0, 0, 0, 10806, 0, - 0, 70016, 0, 6723, 0, 0, 6993, 0, 0, 12855, 0, 0, 11390, 0, 0, 0, 92503, - 0, 0, 983161, 125270, 92627, 8278, 0, 4034, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 12750, 9350, 66037, 0, 0, 73700, 12747, 0, 0, 128064, 8922, 74640, 0, 0, - 43150, 0, 983090, 983088, 66779, 66777, 10813, 2592, 43139, 0, 0, 118612, - 0, 0, 71891, 0, 0, 0, 0, 0, 0, 71697, 0, 128825, 1596, 0, 0, 0, 0, 6838, - 66572, 0, 126574, 120627, 8092, 12805, 41928, 0, 78406, 78409, 0, 0, 0, - 9931, 0, 0, 0, 0, 0, 983778, 6107, 0, 0, 0, 0, 128745, 0, 335, 127003, - 64689, 0, 0, 5765, 0, 0, 119227, 6092, 118851, 0, 8876, 83465, 74947, - 83455, 129186, 83454, 70713, 0, 0, 126606, 70121, 41602, 0, 92308, 74831, - 0, 11783, 68482, 0, 0, 0, 0, 0, 0, 843, 0, 71099, 0, 0, 41935, 0, 0, 0, - 0, 1371, 0, 43818, 43159, 8069, 9579, 41938, 41608, 0, 92444, 6242, 0, 0, - 128595, 128244, 0, 92499, 8805, 1742, 113722, 0, 8202, 72399, 0, 983197, - 0, 0, 73882, 100809, 0, 43467, 123636, 55290, 0, 1712, 5932, 0, 41762, - 71982, 0, 11967, 1775, 0, 75009, 0, 11868, 120387, 9458, 0, 126614, 0, 0, - 43176, 101032, 101031, 42782, 101033, 101036, 101035, 101038, 101037, - 101040, 101039, 0, 0, 0, 0, 101041, 5794, 92274, 2662, 101045, 101044, - 8254, 101046, 10975, 101048, 120625, 101050, 917977, 4108, 8478, 917982, - 194790, 0, 92263, 917980, 7507, 0, 43149, 0, 65031, 7961, 1636, 0, 65029, - 0, 129665, 70188, 9674, 0, 99, 98, 97, 101022, 92203, 4049, 101027, - 43880, 7090, 101028, 0, 101030, 66589, 0, 65310, 66593, 66599, 129805, 0, - 0, 7447, 66594, 0, 0, 0, 73920, 66595, 66596, 42570, 5593, 0, 0, 0, 0, - 6061, 64854, 119, 118, 117, 116, 0, 122, 121, 120, 111, 110, 109, 108, - 115, 114, 113, 112, 103, 102, 101, 100, 107, 106, 105, 104, 128504, - 73974, 534, 0, 67713, 1536, 73973, 73970, 0, 0, 0, 6020, 12716, 0, 12744, - 65143, 0, 13266, 127813, 0, 0, 0, 127116, 0, 1212, 65560, 0, 8134, 42935, - 12129, 73870, 0, 1866, 0, 0, 0, 0, 65073, 12059, 66585, 121391, 0, 0, 0, - 5935, 1250, 0, 8174, 9787, 6733, 9859, 9858, 9861, 9860, 101012, 1882, - 1892, 6731, 10882, 10795, 101018, 73911, 101020, 101019, 41169, 8939, 0, - 120713, 41170, 1454, 0, 65130, 69732, 0, 0, 129611, 41172, 7855, 0, - 71472, 0, 0, 0, 71691, 65901, 0, 0, 645, 100992, 100991, 100994, 100993, - 100996, 100995, 100998, 65587, 0, 10688, 0, 0, 7729, 0, 101001, 120518, - 101003, 66722, 101005, 101004, 68415, 101006, 4538, 101008, 43141, 0, 0, - 73699, 0, 0, 0, 71918, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71454, 0, 2381, 983752, - 0, 0, 69857, 100981, 0, 100983, 100982, 100985, 10856, 100987, 55255, - 41478, 8582, 10064, 0, 0, 0, 0, 64896, 0, 74609, 0, 128048, 10082, 11575, - 0, 0, 0, 917505, 0, 6145, 75020, 0, 92433, 71916, 83279, 43186, 0, 0, - 83274, 83276, 83277, 83278, 10191, 83271, 69633, 72353, 0, 0, 0, 0, - 120090, 120089, 7931, 8558, 917946, 0, 0, 0, 119145, 120081, 120084, - 120083, 120086, 71449, 120088, 7366, 7019, 75021, 0, 917951, 120078, - 120077, 120080, 8657, 100967, 8594, 100969, 100968, 0, 100970, 120072, - 120071, 0, 0, 43154, 0, 0, 11332, 0, 7728, 100978, 100977, 100980, - 100979, 7851, 0, 8375, 128662, 0, 0, 126095, 9085, 0, 0, 9327, 6160, 0, - 0, 0, 0, 70698, 74012, 0, 0, 4439, 121151, 100972, 100971, 100974, - 100973, 100976, 100975, 100956, 42524, 71220, 100957, 10826, 100959, - 11296, 0, 0, 0, 7504, 43161, 127868, 0, 64670, 0, 78056, 0, 11295, 0, - 78053, 0, 0, 0, 10902, 0, 0, 122650, 78068, 10472, 100954, 100953, - 120215, 78062, 2371, 78069, 118893, 259, 0, 0, 2402, 12157, 6440, 0, - 100963, 100962, 100965, 100964, 65380, 9103, 2278, 0, 0, 7301, 0, 10219, - 0, 0, 0, 67718, 43178, 0, 120214, 119362, 917974, 8613, 0, 126121, - 917978, 917979, 121449, 12005, 7353, 0, 1890, 129130, 0, 0, 0, 42815, - 7991, 0, 10578, 0, 0, 0, 0, 0, 0, 0, 111190, 120601, 42668, 9348, 0, - 6164, 0, 0, 0, 7676, 0, 0, 0, 0, 0, 129422, 83443, 71096, 83444, 9175, 0, - 78047, 9088, 73689, 0, 1396, 0, 0, 11461, 71088, 127835, 92252, 0, 71090, - 121185, 69872, 0, 0, 0, 0, 74043, 119632, 0, 0, 0, 5928, 4525, 10658, 0, - 1266, 10180, 64472, 0, 12622, 0, 0, 0, 0, 127139, 13310, 773, 19933, 0, - 0, 0, 0, 92205, 0, 0, 0, 0, 5862, 7823, 0, 0, 0, 3250, 43991, 69687, - 66649, 0, 0, 0, 0, 0, 64673, 917963, 917964, 0, 0, 917967, 917968, - 917965, 917966, 127791, 75041, 3471, 917970, 64573, 882, 0, 119584, 0, - 120772, 0, 0, 0, 92696, 0, 0, 72988, 0, 3225, 0, 73729, 0, 0, 43173, - 11752, 4381, 0, 0, 917945, 11756, 11757, 917944, 917949, 42654, 127848, - 118663, 0, 0, 5160, 1387, 0, 917953, 0, 128933, 917956, 917957, 917954, - 917955, 118595, 121082, 917958, 10789, 68314, 0, 126521, 11143, 0, 0, - 70669, 128904, 42179, 0, 5931, 11744, 11215, 70676, 119245, 0, 0, 0, - 77915, 10217, 64635, 128661, 83292, 0, 0, 0, 0, 0, 41296, 11747, 41291, - 0, 0, 0, 41294, 41282, 5923, 120610, 0, 0, 0, 0, 66800, 5786, 68252, - 42539, 119869, 119860, 0, 41474, 0, 0, 0, 5934, 74572, 66583, 119231, 0, - 94072, 64481, 0, 0, 0, 0, 67240, 0, 0, 123201, 0, 5819, 0, 0, 0, 0, 0, - 129387, 0, 0, 0, 67993, 1237, 194749, 0, 0, 983557, 0, 0, 0, 0, 0, 0, 0, - 69789, 11266, 69845, 0, 10506, 194747, 0, 0, 0, 0, 43185, 194748, 100533, - 100532, 100535, 10769, 100537, 100536, 100539, 9753, 121035, 100540, 0, - 0, 121433, 0, 100542, 6072, 100544, 100543, 100546, 100545, 100548, - 100547, 100550, 100549, 0, 113744, 0, 0, 7222, 10283, 10315, 10379, 4996, - 0, 129294, 66517, 0, 10087, 127833, 74938, 0, 0, 83492, 7565, 42890, 0, - 77931, 43180, 77928, 74891, 77929, 43982, 100526, 622, 77926, 100527, - 100530, 1602, 0, 0, 0, 129559, 12160, 0, 10212, 77936, 194605, 12071, - 43143, 77935, 917983, 917984, 917989, 77932, 917987, 917988, 10255, - 10263, 10279, 4194, 10375, 93035, 0, 0, 12644, 127516, 917994, 75007, - 110791, 67408, 110789, 11501, 41177, 0, 0, 71912, 0, 0, 8715, 0, 41179, - 0, 0, 0, 41176, 0, 41181, 0, 8452, 121006, 13161, 0, 70503, 5921, 0, - 2597, 0, 5922, 72128, 0, 74242, 128374, 0, 0, 0, 0, 0, 0, 0, 127906, 0, - 64944, 0, 0, 0, 0, 5924, 5920, 129508, 6921, 78081, 74007, 78078, 8418, - 11681, 43169, 10176, 0, 0, 0, 78087, 10772, 65276, 5937, 1914, 78084, - 11682, 0, 0, 0, 11685, 0, 100513, 7772, 11680, 100514, 100517, 100516, - 100519, 7417, 718, 100520, 70083, 100500, 120718, 3235, 0, 43164, 0, - 8018, 0, 0, 128708, 6937, 67672, 128508, 0, 10067, 120849, 0, 0, 0, - 118693, 0, 100491, 0, 100493, 100492, 13116, 100494, 100497, 9945, - 100499, 100498, 0, 0, 0, 0, 2059, 0, 100502, 100501, 1431, 100503, 66565, - 100505, 100508, 12804, 100510, 100509, 78090, 3307, 78088, 78089, 0, - 4544, 71228, 0, 0, 0, 78097, 11110, 66810, 12882, 64511, 78094, 78100, - 78102, 71226, 10141, 0, 78280, 65298, 4476, 78109, 94005, 71216, 8907, - 78105, 78106, 78103, 78104, 120898, 0, 10665, 64616, 128944, 0, 127545, - 69605, 83159, 83160, 4554, 0, 83155, 83156, 83157, 83158, 0, 125123, 0, - 72258, 129831, 0, 129815, 0, 43179, 0, 0, 0, 717, 10754, 83168, 83169, - 83162, 83163, 83164, 83165, 78282, 0, 0, 83161, 68848, 10611, 72859, - 126978, 71474, 129426, 127871, 0, 0, 0, 12820, 110882, 0, 7009, 70103, 0, - 0, 67848, 41173, 4574, 0, 0, 128338, 575, 78110, 43456, 8563, 100469, 0, - 0, 65565, 0, 5936, 7290, 78117, 78118, 74919, 308, 78113, 78114, 83151, - 78123, 83153, 83154, 0, 0, 0, 0, 67496, 5926, 68250, 78130, 78126, 78127, - 78124, 78125, 42513, 0, 129026, 0, 11651, 13093, 78135, 0, 100471, 0, - 100473, 100472, 100475, 74048, 100477, 71995, 100457, 100456, 43703, - 13097, 0, 100460, 13283, 0, 0, 125073, 3488, 5933, 10033, 983947, 0, - 65570, 0, 12297, 0, 0, 0, 128517, 42538, 0, 129293, 0, 100451, 0, 100453, - 100452, 100455, 100454, 121221, 0, 0, 7638, 0, 129193, 0, 43109, 7637, 0, - 11213, 100461, 83355, 100463, 100466, 100465, 0, 0, 7636, 0, 0, 0, - 128848, 983087, 291, 0, 0, 2027, 78141, 78142, 78136, 78137, 83481, 4640, - 64713, 10224, 120429, 11183, 83482, 120430, 0, 0, 0, 127148, 83479, 0, 0, - 83488, 0, 0, 0, 0, 68837, 5778, 0, 0, 0, 12680, 119130, 0, 67242, 93041, - 0, 0, 0, 11552, 0, 127855, 0, 70091, 0, 10172, 65453, 120408, 66014, - 120410, 0, 4641, 11556, 64819, 78269, 120416, 72341, 41469, 41467, - 120412, 120415, 4646, 120425, 865, 78275, 78274, 78273, 4645, 78271, - 78270, 0, 983172, 7338, 0, 68840, 0, 12565, 0, 0, 0, 195089, 119655, - 195091, 195090, 2913, 13120, 128956, 69493, 195097, 195096, 128019, 0, - 71462, 0, 7916, 10485, 195098, 0, 195100, 195099, 0, 67705, 128351, - 195077, 195080, 129636, 129549, 195081, 0, 0, 0, 10229, 10687, 826, - 128081, 195082, 195085, 195084, 195087, 195086, 0, 1808, 7848, 0, 0, 0, - 0, 0, 0, 128897, 69255, 42942, 67704, 0, 0, 0, 0, 42940, 0, 9144, 0, 0, - 92992, 9840, 0, 0, 0, 0, 0, 0, 74448, 83475, 0, 10962, 66904, 113718, - 983187, 0, 0, 74537, 195072, 1792, 195074, 195073, 78266, 195075, 0, 0, - 12066, 0, 385, 4152, 0, 0, 0, 67397, 0, 0, 0, 0, 43258, 0, 0, 13157, 0, - 0, 3570, 0, 0, 0, 67252, 0, 71218, 126631, 7879, 68247, 128579, 0, 0, - 70196, 0, 0, 8463, 7810, 917862, 7839, 983878, 127768, 917860, 9691, 0, - 129323, 0, 120385, 0, 917844, 0, 10066, 0, 2175, 0, 0, 0, 8016, 0, - 983072, 64831, 0, 126103, 0, 119171, 1634, 68115, 94192, 11056, 0, 0, 0, - 41165, 11328, 12450, 0, 41166, 0, 12456, 0, 171, 67508, 12452, 917544, - 12458, 12531, 0, 917853, 0, 74162, 0, 0, 9969, 0, 12454, 74160, 42132, - 110755, 78878, 110753, 3230, 73711, 0, 0, 8932, 4399, 5810, 64534, 8415, - 0, 110756, 110757, 74159, 0, 0, 960, 74156, 6981, 92374, 12938, 9201, 0, - 118713, 74904, 0, 72866, 92270, 0, 0, 0, 129792, 5851, 73833, 5824, 0, - 5844, 110848, 110849, 110846, 110847, 4663, 0, 0, 0, 0, 0, 74085, 0, 0, - 0, 0, 0, 92339, 0, 0, 5782, 67495, 0, 0, 43796, 129639, 0, 195083, - 125223, 128004, 0, 43861, 0, 0, 0, 92976, 0, 0, 0, 4659, 0, 129764, 0, 0, - 129386, 0, 11129, 2238, 329, 0, 92707, 121416, 0, 0, 0, 69943, 67692, - 42167, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69618, 43671, 0, 64701, 0, 0, 0, - 93055, 1172, 125089, 6786, 43601, 0, 74126, 0, 0, 0, 0, 0, 118695, 0, 0, - 118804, 0, 66741, 5347, 0, 983663, 0, 0, 10588, 0, 0, 0, 0, 5343, 0, 0, - 0, 5341, 0, 0, 74916, 5351, 0, 0, 917884, 0, 92692, 0, 121148, 128916, 0, - 0, 66785, 126256, 6638, 0, 0, 271, 0, 917904, 0, 0, 12653, 67588, 0, 0, - 0, 0, 128838, 11912, 128301, 983665, 0, 11800, 0, 0, 11103, 0, 7340, 0, - 110695, 0, 0, 70170, 0, 2423, 0, 0, 0, 128136, 42705, 0, 0, 0, 11854, 0, - 0, 0, 0, 4916, 0, 380, 10958, 66563, 127790, 78284, 67587, 0, 12918, 0, - 917897, 0, 917898, 917893, 10684, 0, 125063, 92906, 0, 0, 8182, 0, 0, - 129434, 0, 0, 0, 6859, 0, 6630, 100405, 0, 123191, 0, 0, 0, 65876, 5535, - 129892, 0, 0, 92609, 0, 983345, 6477, 43795, 92217, 129571, 72163, 69496, - 43848, 0, 0, 74256, 2665, 11304, 43751, 0, 4970, 74353, 0, 8934, 0, - 93996, 4492, 92908, 65011, 0, 0, 92909, 1188, 7254, 1100, 0, 0, 0, 2912, - 11749, 92643, 0, 0, 65057, 0, 12343, 0, 78879, 0, 78880, 0, 0, 0, 70355, - 0, 0, 11803, 0, 0, 41450, 0, 100897, 0, 41451, 0, 0, 8273, 0, 3451, 0, - 972, 41453, 68164, 78876, 0, 92408, 73945, 43504, 2288, 78873, 9538, - 78874, 128685, 0, 129095, 0, 0, 0, 0, 11019, 0, 0, 121205, 0, 73007, - 71365, 92716, 5927, 0, 0, 0, 0, 128484, 0, 6073, 0, 0, 0, 6075, 93995, - 282, 126510, 0, 74078, 121459, 2206, 0, 0, 66791, 0, 3474, 0, 0, 0, 6081, - 0, 127843, 74076, 0, 0, 0, 128908, 0, 0, 0, 12623, 120273, 9120, 120275, - 4665, 12628, 4670, 120271, 120272, 0, 0, 121480, 958, 0, 0, 0, 4666, 0, - 4915, 0, 4669, 0, 0, 0, 4664, 0, 120550, 0, 0, 0, 0, 94023, 0, 917875, - 8664, 11664, 0, 129327, 11224, 0, 0, 1063, 119088, 120251, 9772, 7255, - 8886, 0, 127932, 120257, 120258, 120259, 120260, 42661, 71345, 120255, - 119125, 120265, 120266, 120267, 42721, 92407, 120262, 120263, 66788, - 1017, 0, 118580, 505, 1447, 0, 0, 70340, 66793, 65115, 42789, 128443, 0, - 0, 123634, 0, 119195, 0, 0, 11745, 7919, 0, 1641, 0, 0, 8966, 0, 0, 8743, - 71870, 0, 67813, 0, 0, 0, 123206, 0, 0, 128505, 10169, 71324, 0, 10068, - 0, 120457, 120456, 120455, 120454, 257, 43170, 13153, 0, 0, 0, 0, 0, 0, - 6496, 19917, 5930, 128354, 11033, 0, 0, 5622, 120436, 8477, 8474, 120433, - 120432, 0, 0, 0, 41435, 4352, 0, 2435, 0, 5621, 0, 4201, 8450, 4203, - 4202, 4205, 4204, 120447, 120446, 120445, 66792, 41440, 120442, 8473, - 6373, 8469, 120438, 0, 4564, 125206, 0, 0, 0, 8374, 73669, 0, 0, 66796, - 0, 0, 0, 0, 0, 69297, 129762, 5626, 43507, 11771, 0, 0, 0, 42614, 0, - 5625, 0, 0, 0, 5623, 0, 0, 42623, 64277, 69942, 0, 0, 120752, 0, 5817, - 5629, 0, 7551, 10325, 5632, 69674, 0, 0, 124946, 125194, 5628, 129766, - 5631, 0, 0, 2400, 5627, 0, 0, 118786, 74792, 0, 0, 0, 203, 129084, 74365, - 0, 0, 0, 0, 83382, 83422, 0, 0, 554, 0, 0, 0, 12182, 0, 64569, 110840, - 73891, 0, 0, 0, 7689, 69798, 9323, 10269, 10285, 10317, 175, 0, 0, 0, 0, - 0, 1243, 42154, 0, 92387, 0, 0, 43651, 0, 125021, 0, 9075, 118597, 0, - 64777, 128570, 0, 0, 0, 0, 65255, 0, 121142, 4490, 0, 6649, 120698, - 12181, 0, 11977, 7249, 8366, 0, 7756, 12342, 0, 51, 41516, 69432, 0, - 9568, 71318, 456, 0, 10437, 1168, 9251, 9082, 0, 0, 42781, 3866, 0, - 41512, 0, 0, 68121, 41494, 0, 4660, 0, 10405, 0, 0, 0, 0, 0, 73918, - 119627, 110686, 41454, 12605, 0, 126611, 41455, 917996, 983605, 0, 8214, - 0, 100413, 129320, 41457, 0, 0, 1969, 127771, 0, 69554, 7413, 0, 69426, - 10341, 43864, 78079, 5854, 0, 0, 0, 129684, 72819, 0, 0, 0, 0, 0, 8429, - 0, 72328, 0, 6429, 0, 0, 0, 0, 110688, 83417, 0, 917864, 120813, 83423, - 1662, 125000, 0, 0, 917871, 917868, 0, 0, 66, 65, 68, 67, 70, 69, 72, 71, - 74, 73, 76, 75, 78, 77, 80, 79, 82, 81, 84, 83, 86, 85, 88, 87, 90, 89, - 0, 0, 7385, 70508, 1704, 12993, 0, 0, 0, 0, 0, 0, 0, 0, 11353, 72207, 0, - 0, 0, 0, 118831, 0, 0, 0, 0, 0, 118719, 83364, 0, 0, 1289, 0, 0, 119583, - 0, 65507, 0, 0, 0, 128042, 0, 74409, 0, 0, 0, 0, 64793, 0, 0, 100843, - 5675, 119239, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6972, 70735, 0, 121108, - 126217, 0, 0, 0, 0, 0, 110640, 67687, 0, 0, 119634, 0, 43977, 111252, - 129105, 0, 7412, 64671, 0, 1412, 4594, 1391, 0, 8067, 12478, 110639, - 78375, 110637, 10281, 110635, 0, 0, 7960, 43271, 0, 12518, 69846, 0, - 3566, 0, 0, 69864, 0, 0, 68021, 0, 0, 0, 8223, 0, 4261, 121460, 68918, 0, - 0, 121294, 113712, 0, 128046, 43419, 72748, 92866, 10574, 0, 67691, 0, 0, - 73785, 0, 78875, 128541, 0, 127366, 0, 0, 0, 0, 6695, 65113, 324, 0, - 128373, 40985, 0, 0, 0, 0, 0, 72307, 43474, 0, 121190, 0, 0, 3420, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 110871, 9574, 120684, 110870, 110814, 5204, 74774, - 0, 11835, 0, 0, 983185, 0, 0, 0, 0, 0, 0, 11750, 68898, 127004, 0, 0, 0, - 0, 8130, 0, 0, 0, 121268, 0, 129443, 0, 68455, 42863, 73839, 0, 0, 0, - 92288, 0, 0, 0, 612, 110875, 110876, 72231, 10538, 0, 1674, 0, 0, 0, - 12280, 0, 540, 74550, 0, 66422, 8432, 0, 11073, 0, 64316, 129894, 0, - 7388, 0, 0, 0, 0, 126107, 0, 3359, 0, 0, 67284, 0, 0, 65482, 129589, 0, - 64742, 129304, 0, 0, 74273, 0, 19941, 0, 0, 0, 0, 9481, 65555, 0, 66628, - 129126, 1195, 64898, 0, 0, 0, 2010, 0, 0, 0, 0, 0, 0, 4360, 127009, 9739, - 0, 72885, 0, 0, 0, 126265, 72200, 0, 0, 120025, 72199, 0, 0, 65734, 0, 0, - 129690, 13075, 0, 94063, 0, 43532, 10837, 2492, 74516, 983075, 120882, 0, - 0, 11813, 9649, 0, 119617, 5128, 7377, 0, 65604, 0, 0, 6771, 1648, 7819, - 0, 0, 0, 125192, 128131, 12709, 6986, 0, 0, 0, 0, 0, 12581, 0, 5175, 0, - 73806, 0, 128420, 0, 0, 77950, 0, 0, 607, 0, 0, 128846, 119605, 67475, - 129528, 65477, 0, 121130, 0, 8265, 0, 0, 0, 5840, 42838, 0, 0, 68366, 0, - 119255, 0, 0, 0, 127929, 0, 2550, 121011, 6779, 70059, 0, 0, 0, 0, 0, 0, - 5619, 65822, 0, 0, 0, 129392, 5616, 11486, 0, 0, 0, 0, 5615, 0, 121319, - 42380, 127958, 0, 66451, 74407, 0, 11347, 0, 1026, 5620, 0, 0, 11350, - 5617, 0, 0, 64639, 0, 0, 0, 1338, 0, 0, 0, 4603, 0, 70715, 92484, 0, - 9002, 0, 3974, 78213, 0, 0, 0, 0, 0, 0, 75038, 66040, 70455, 0, 0, 0, - 72982, 0, 0, 0, 0, 0, 118661, 0, 0, 119105, 0, 0, 0, 0, 0, 128883, 0, - 66897, 0, 0, 0, 42594, 0, 0, 0, 0, 6714, 10083, 0, 121019, 0, 69976, 0, - 0, 9073, 0, 64302, 0, 128286, 9725, 0, 0, 121288, 73769, 121306, 0, 9570, - 0, 11500, 2689, 917626, 0, 983813, 66740, 0, 0, 0, 917623, 13286, 5500, - 42598, 42596, 503, 0, 0, 917618, 0, 0, 0, 0, 917615, 1652, 772, 6688, - 8310, 0, 0, 72124, 0, 10194, 43542, 0, 125054, 0, 6468, 68110, 0, 917606, - 11767, 0, 0, 5836, 12358, 0, 0, 65624, 12180, 0, 127994, 0, 43699, 0, 0, - 72114, 43706, 0, 12362, 12435, 12360, 0, 9020, 0, 12356, 8616, 0, 42924, - 2227, 0, 0, 7315, 12354, 83097, 83098, 83099, 2358, 83092, 83093, 83094, - 0, 0, 83089, 83090, 0, 11759, 71723, 0, 72834, 83109, 41423, 0, 83103, - 83104, 83105, 42237, 110653, 70717, 72260, 83102, 0, 67856, 0, 128534, - 110657, 129354, 129194, 0, 64395, 0, 73008, 120897, 74816, 0, 0, 0, - 83088, 0, 0, 94064, 83083, 83085, 83086, 83087, 83079, 83080, 2041, 9178, - 0, 64870, 0, 83076, 74924, 0, 0, 0, 0, 0, 78739, 0, 0, 0, 0, 0, 0, 3726, - 0, 0, 0, 0, 0, 121432, 129457, 0, 0, 0, 0, 0, 74901, 0, 0, 0, 0, 0, - 124944, 113781, 0, 7410, 2669, 903, 0, 0, 0, 127232, 74603, 0, 128264, 0, - 128411, 0, 0, 11732, 0, 72797, 41448, 41461, 124934, 0, 917558, 0, 8819, - 0, 0, 74606, 92847, 121412, 74835, 0, 9168, 65786, 0, 73691, 0, 67665, 0, - 11758, 68425, 0, 0, 0, 128044, 0, 19924, 67312, 0, 128755, 64551, 0, - 8516, 0, 0, 7561, 983999, 74018, 0, 0, 0, 0, 83074, 83075, 0, 11233, - 83062, 83066, 3787, 83070, 83055, 41458, 83059, 41463, 65308, 41459, - 8683, 775, 0, 65584, 69923, 0, 110798, 110799, 110796, 43440, 0, 0, 0, - 3656, 0, 0, 0, 67694, 1599, 83138, 83139, 8514, 8513, 83036, 83135, - 83136, 110794, 110795, 83131, 83132, 0, 0, 0, 11684, 10542, 9937, 83150, - 0, 75037, 83145, 65730, 83147, 0, 8427, 83142, 55246, 0, 0, 11497, 0, 0, - 0, 119222, 0, 983598, 0, 10621, 0, 0, 129295, 119111, 120745, 0, 0, 0, - 11648, 83126, 83127, 42118, 83129, 83122, 65512, 83124, 83125, 0, 0, 0, - 83121, 74530, 128456, 0, 0, 0, 65724, 0, 0, 0, 65727, 0, 0, 64963, 73830, - 66042, 0, 0, 7875, 0, 0, 0, 129476, 0, 0, 536, 0, 0, 0, 0, 65173, 129122, - 0, 70331, 0, 0, 118598, 0, 129419, 0, 0, 0, 1687, 0, 0, 0, 0, 0, 0, - 10526, 0, 8323, 0, 83301, 11731, 0, 0, 65460, 12242, 0, 0, 10843, 11554, - 0, 0, 8266, 0, 121101, 0, 0, 0, 0, 67667, 118694, 119155, 0, 0, 119636, - 67857, 0, 0, 0, 11755, 66305, 0, 0, 10917, 93979, 113688, 0, 2040, 92596, - 0, 0, 0, 0, 1227, 83119, 83120, 0, 0, 83115, 83116, 11149, 4978, 83111, - 1984, 11830, 83114, 128934, 74548, 118545, 9373, 0, 0, 0, 0, 0, 0, 0, 0, - 9237, 9390, 0, 0, 0, 0, 0, 1830, 0, 0, 0, 0, 0, 128577, 983839, 68086, 0, - 0, 0, 983059, 0, 983144, 0, 0, 0, 72197, 55291, 11683, 0, 983659, 0, - 11451, 0, 72714, 3731, 2359, 0, 67844, 0, 121503, 548, 121502, 983247, - 121405, 983250, 0, 66272, 0, 64678, 0, 9547, 0, 0, 1614, 0, 0, 66307, - 128092, 1358, 120871, 428, 0, 1466, 0, 10982, 0, 0, 0, 407, 0, 0, 0, 0, - 0, 0, 5804, 73464, 0, 0, 0, 70167, 9057, 42446, 0, 125097, 0, 0, 8250, - 10952, 8048, 0, 129155, 0, 118955, 0, 0, 118593, 4407, 74648, 0, 0, 0, - 8448, 92491, 0, 0, 12675, 12659, 0, 0, 983282, 68077, 55273, 10766, - 12012, 2386, 0, 9170, 0, 9123, 128194, 0, 0, 0, 0, 129942, 0, 0, 0, 0, 0, - 0, 8709, 0, 72383, 0, 0, 0, 0, 0, 0, 0, 128342, 0, 577, 128610, 0, 0, - 124999, 68087, 74840, 126474, 127036, 0, 0, 0, 1414, 124963, 9683, 43486, - 92231, 0, 2536, 0, 66330, 0, 0, 0, 0, 0, 0, 0, 66317, 0, 66315, 66316, 0, - 0, 0, 0, 0, 0, 0, 0, 66323, 66324, 0, 0, 3106, 65917, 0, 2182, 0, 891, 0, - 0, 42624, 0, 0, 8824, 65089, 128734, 10936, 0, 0, 0, 0, 92688, 0, 0, 0, - 0, 12745, 0, 0, 41285, 3547, 0, 0, 129877, 0, 118701, 6089, 0, 68490, - 120578, 4170, 1029, 127761, 0, 0, 42374, 917625, 744, 917624, 0, 0, 0, - 93046, 0, 3551, 0, 0, 4623, 0, 0, 12340, 0, 65136, 0, 0, 0, 0, 0, 0, 0, - 72291, 0, 0, 120778, 0, 11972, 0, 78757, 0, 122886, 177, 122894, 0, 0, 0, - 0, 55243, 0, 0, 0, 70172, 120249, 120242, 128027, 120243, 0, 0, 0, - 120237, 120245, 94079, 0, 0, 9136, 120240, 120614, 41280, 0, 0, 0, 0, - 74149, 128327, 0, 0, 66361, 12601, 72194, 64360, 65163, 0, 0, 0, 0, 0, 0, - 5404, 43332, 3667, 7936, 12925, 0, 0, 0, 0, 0, 10874, 65505, 0, 0, 0, 0, - 128920, 983681, 0, 0, 0, 0, 0, 0, 0, 0, 66677, 0, 0, 0, 70088, 74148, 0, - 0, 72868, 120230, 120224, 74172, 0, 0, 94096, 0, 128414, 120636, 0, - 127519, 917609, 917616, 0, 128652, 0, 0, 11441, 0, 3512, 0, 0, 43597, 0, - 0, 72734, 68153, 41563, 0, 0, 129352, 41544, 0, 0, 74927, 0, 129177, 0, - 0, 0, 118908, 0, 78108, 67396, 73804, 64711, 0, 0, 917610, 0, 0, 0, - 11557, 127776, 0, 12079, 0, 0, 0, 0, 128861, 0, 0, 0, 0, 0, 983200, 8103, - 72303, 128174, 92486, 110698, 0, 64587, 0, 0, 124961, 0, 0, 0, 126481, 0, - 0, 0, 0, 0, 70348, 1450, 0, 1340, 0, 0, 128970, 0, 0, 125117, 0, 0, 0, 0, - 6539, 92948, 0, 128213, 125060, 0, 0, 0, 3973, 0, 70504, 121193, 7982, 0, - 0, 127194, 0, 0, 0, 128408, 118968, 6417, 120619, 129748, 0, 0, 0, - 129455, 4919, 65121, 110872, 7755, 0, 0, 64548, 0, 1621, 0, 0, 0, 0, 0, - 12188, 0, 0, 0, 0, 5015, 0, 0, 42590, 70354, 1756, 0, 0, 0, 120694, 0, 0, - 7555, 73874, 5408, 2817, 1214, 69919, 0, 983125, 0, 0, 125055, 127195, - 7957, 0, 0, 1056, 74944, 0, 0, 0, 0, 7073, 74979, 0, 70853, 0, 110874, 0, - 0, 2341, 126644, 8484, 0, 0, 68322, 0, 8461, 67721, 42269, 0, 0, 43709, - 43708, 9451, 7571, 13073, 43847, 126647, 0, 983260, 0, 0, 0, 8781, 12894, - 78134, 0, 78132, 0, 0, 78184, 0, 11338, 120768, 0, 0, 0, 0, 0, 121367, - 65021, 64795, 74574, 0, 10047, 0, 0, 0, 0, 0, 0, 119181, 163, 576, 9895, - 0, 0, 74591, 0, 0, 66888, 0, 0, 0, 0, 0, 0, 7017, 128111, 0, 0, 129922, - 0, 41591, 11036, 65252, 120795, 129488, 0, 0, 0, 0, 0, 0, 8887, 0, 7295, - 71203, 0, 127221, 0, 0, 0, 0, 8755, 0, 0, 8147, 73127, 0, 0, 121348, 0, - 129377, 0, 74499, 0, 0, 0, 4619, 0, 6654, 123192, 0, 0, 0, 65689, 10128, - 0, 129612, 0, 0, 92651, 0, 2401, 0, 8792, 118546, 0, 74980, 0, 92246, 0, - 0, 0, 12886, 0, 66624, 0, 0, 74133, 65170, 0, 74135, 0, 0, 9984, 73867, - 3010, 0, 70349, 10698, 41475, 0, 119151, 0, 119152, 0, 0, 9100, 0, 0, 0, - 78116, 64780, 2001, 0, 55230, 0, 4052, 92856, 7626, 78080, 0, 0, 0, - 41477, 0, 0, 0, 43707, 74127, 0, 0, 0, 78086, 73758, 2335, 10663, 0, 0, - 129872, 119602, 0, 0, 70325, 0, 41443, 0, 0, 0, 9711, 1523, 0, 0, 41445, - 0, 0, 8567, 41442, 12821, 0, 0, 118978, 0, 65274, 0, 94082, 0, 127515, 0, - 0, 43446, 0, 0, 0, 0, 127985, 0, 10206, 127167, 6375, 2673, 0, 0, 0, - 43219, 129355, 0, 0, 0, 0, 129400, 11799, 101225, 68466, 0, 0, 0, 0, 0, - 120736, 0, 7203, 0, 0, 70361, 127213, 120615, 127216, 0, 0, 0, 0, 43121, - 0, 128366, 72161, 0, 129868, 0, 121260, 73781, 70365, 0, 68039, 70446, + 0, 0, 0, 0, 0, 0, 4110, 66005, 74034, 0, 0, 0, 66703, 0, 0, 983158, 6025, + 69242, 0, 0, 0, 0, 0, 0, 0, 0, 0, 70733, 0, 983043, 0, 73513, 0, 68817, + 0, 0, 0, 0, 0, 0, 43286, 0, 68765, 0, 0, 0, 0, 129871, 65144, 0, 0, + 83236, 65840, 0, 0, 10081, 0, 0, 983912, 0, 0, 0, 127394, 65882, 0, + 128758, 0, 0, 3605, 10985, 0, 0, 128872, 93972, 1745, 0, 73835, 0, 0, 0, + 0, 0, 0, 8806, 7023, 0, 0, 0, 70702, 70304, 0, 0, 0, 0, 0, 0, 0, 0, 348, + 10089, 0, 9017, 0, 0, 0, 0, 0, 0, 0, 67465, 0, 42515, 0, 0, 0, 0, 5391, + 983240, 110576, 0, 0, 5561, 0, 9429, 0, 67150, 7933, 5562, 0, 0, 0, 0, + 78039, 0, 0, 0, 0, 3979, 71248, 0, 0, 0, 68847, 0, 0, 118847, 65847, + 68836, 68838, 0, 10585, 0, 92676, 7334, 0, 0, 0, 831, 0, 0, 10716, 0, + 121325, 0, 12218, 0, 6939, 70697, 65042, 0, 0, 916, 0, 0, 11968, 0, + 122641, 5563, 0, 0, 128830, 5560, 41212, 41774, 0, 4497, 0, 0, 0, 9039, + 70678, 41776, 0, 8716, 3567, 119252, 0, 0, 74260, 0, 93954, 0, 0, 100827, + 0, 128879, 70072, 68355, 68357, 0, 0, 8634, 0, 0, 4209, 120702, 68832, + 65879, 68825, 68819, 68822, 0, 5679, 68813, 68815, 68811, 68812, 64697, + 5678, 11821, 68802, 93969, 0, 0, 0, 0, 70114, 0, 0, 0, 0, 0, 0, 0, 0, + 7782, 0, 0, 0, 0, 129977, 65711, 65712, 1216, 0, 69409, 5792, 0, 0, 0, 0, + 0, 12244, 0, 5683, 0, 120895, 121336, 43448, 70670, 0, 0, 5682, 10242, + 75043, 74520, 5680, 917568, 10001, 0, 0, 1449, 10241, 0, 70708, 0, 0, + 83180, 83182, 83183, 8584, 83176, 5567, 83178, 83179, 0, 5564, 42886, + 42884, 42882, 5565, 119022, 120881, 0, 65708, 65709, 5566, 0, 65704, + 65705, 11904, 42875, 0, 42873, 5942, 0, 0, 10361, 10425, 65697, 65698, + 65699, 0, 66598, 0, 64664, 10647, 78702, 78703, 78690, 78700, 0, 65701, + 1934, 0, 0, 0, 78710, 0, 78706, 78709, 6087, 78705, 78716, 78719, 78711, + 8043, 8950, 65694, 64485, 0, 10457, 0, 78724, 78725, 78722, 72332, 78720, + 78721, 0, 65515, 0, 10035, 13069, 0, 0, 127773, 0, 0, 0, 125207, 0, 0, + 1667, 0, 0, 42428, 110950, 0, 0, 41750, 0, 0, 93999, 0, 8101, 3610, + 113670, 41748, 110948, 0, 78394, 119208, 0, 0, 113691, 64549, 68359, 0, + 0, 65692, 92701, 0, 917960, 12896, 10456, 68298, 0, 0, 0, 0, 917962, 0, + 0, 113665, 70502, 0, 65687, 0, 0, 74009, 0, 113673, 8536, 70671, 0, + 78726, 0, 724, 0, 113675, 78749, 9975, 78746, 78747, 78744, 4175, 78741, + 78743, 78751, 939, 0, 128799, 983120, 0, 0, 0, 78763, 78764, 78760, + 78761, 78758, 78759, 78755, 8425, 0, 0, 0, 8188, 0, 0, 0, 0, 0, 6370, 0, + 7827, 68441, 75008, 0, 917943, 0, 118863, 0, 0, 0, 0, 121243, 73988, 0, + 113668, 0, 11012, 0, 43764, 178, 12972, 74620, 113671, 0, 113735, 0, + 66764, 0, 0, 65690, 72339, 0, 0, 917950, 9252, 0, 4652, 74259, 0, 917947, + 0, 0, 0, 10806, 0, 0, 70016, 0, 6723, 0, 0, 6993, 0, 0, 12855, 0, 0, + 11390, 0, 0, 0, 92503, 0, 0, 983162, 125270, 92627, 8278, 0, 4034, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 12750, 9350, 66037, 0, 0, 73700, 12747, 0, 0, + 128064, 8922, 74640, 0, 0, 43150, 0, 983090, 983088, 66779, 66777, 10813, + 2592, 43139, 0, 0, 118612, 0, 0, 71891, 0, 0, 0, 0, 0, 0, 71697, 0, + 128825, 1596, 0, 0, 0, 0, 6838, 66572, 0, 126574, 120627, 8092, 12805, + 41928, 0, 78406, 78409, 0, 0, 0, 9931, 0, 0, 0, 0, 0, 983778, 6107, 0, 0, + 0, 0, 128745, 0, 335, 127003, 64689, 0, 0, 5765, 0, 0, 119227, 6092, + 118851, 0, 8876, 83465, 74947, 83455, 129186, 83454, 70713, 0, 0, 126606, + 70121, 41602, 0, 92308, 74831, 0, 11783, 68482, 0, 0, 0, 0, 0, 0, 843, 0, + 71099, 0, 0, 41935, 0, 0, 0, 0, 1371, 0, 43818, 43159, 8069, 9579, 41938, + 41608, 0, 92444, 6242, 0, 0, 128595, 128244, 0, 92499, 8805, 1742, + 113722, 0, 8202, 72399, 0, 983198, 0, 0, 73882, 100809, 0, 43467, 123636, + 55290, 0, 1712, 5932, 0, 41762, 71982, 0, 11967, 1775, 0, 75009, 0, + 11868, 120387, 9458, 0, 126614, 0, 0, 43176, 101032, 101031, 42782, + 101033, 101036, 101035, 101038, 101037, 101040, 101039, 0, 0, 0, 0, + 101041, 5794, 92274, 2662, 101045, 101044, 8254, 101046, 10975, 101048, + 120625, 101050, 917977, 4108, 8478, 917982, 194790, 0, 92263, 917980, + 7507, 0, 43149, 0, 65031, 7961, 1636, 0, 65029, 0, 129665, 70188, 9674, + 0, 99, 98, 97, 101022, 92203, 4049, 101027, 43880, 7090, 101028, 0, + 101030, 66589, 0, 65310, 66593, 66599, 129805, 0, 0, 7447, 66594, 0, 0, + 0, 73920, 66595, 66596, 42570, 5593, 0, 0, 0, 0, 6061, 64854, 119, 118, + 117, 116, 0, 122, 121, 120, 111, 110, 109, 108, 115, 114, 113, 112, 103, + 102, 101, 100, 107, 106, 105, 104, 128504, 73974, 534, 0, 67713, 1536, + 73973, 73970, 0, 129671, 0, 6020, 12716, 0, 12744, 65143, 0, 13266, + 127813, 0, 0, 0, 127116, 0, 1212, 65560, 0, 8134, 42935, 12129, 73870, 0, + 1866, 0, 122948, 0, 0, 65073, 12059, 66585, 121391, 0, 0, 0, 5935, 1250, + 0, 8174, 9787, 6733, 9859, 9858, 9861, 9860, 101012, 1882, 1892, 6731, + 10882, 10795, 101018, 73911, 101020, 101019, 41169, 8939, 0, 120713, + 41170, 1454, 0, 65130, 69732, 0, 0, 129611, 41172, 7855, 0, 71472, 0, 0, + 0, 71691, 65901, 0, 0, 645, 100992, 100991, 100994, 100993, 100996, + 100995, 100998, 65587, 0, 10688, 0, 0, 7729, 0, 101001, 120518, 101003, + 66722, 101005, 101004, 68415, 101006, 4538, 101008, 43141, 0, 0, 73699, + 0, 0, 0, 71918, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71454, 0, 2381, 983752, 0, 0, + 69857, 100981, 0, 100983, 100982, 100985, 10856, 100987, 55255, 41478, + 8582, 10064, 0, 0, 0, 0, 64896, 0, 74609, 0, 128048, 10082, 11575, 0, 0, + 0, 917505, 0, 6145, 75020, 0, 92433, 71916, 83279, 43186, 0, 0, 83274, + 83276, 83277, 83278, 10191, 83271, 69633, 72353, 0, 0, 0, 0, 120090, + 120089, 7931, 8558, 917946, 0, 0, 0, 119145, 120081, 120084, 120083, + 120086, 71449, 120088, 7366, 7019, 75021, 0, 917951, 120078, 120077, + 120080, 8657, 100967, 8594, 100969, 100968, 0, 100970, 120072, 120071, 0, + 0, 43154, 0, 0, 11332, 0, 7728, 100978, 100977, 100980, 100979, 7851, 0, + 8375, 128662, 0, 0, 126095, 9085, 0, 0, 9327, 6160, 0, 0, 0, 0, 70698, + 74012, 0, 0, 4439, 121151, 100972, 100971, 100974, 100973, 100976, + 100975, 100956, 42524, 71220, 100957, 10826, 100959, 11296, 0, 0, 0, + 7504, 43161, 127868, 0, 64670, 0, 78056, 0, 11295, 0, 78053, 0, 0, 0, + 10902, 0, 0, 122650, 78068, 10472, 100954, 100953, 120215, 78062, 2371, + 78069, 118893, 259, 0, 0, 2402, 12157, 6440, 0, 100963, 100962, 100965, + 100964, 65380, 9103, 2278, 0, 0, 7301, 0, 10219, 0, 0, 0, 67718, 43178, + 0, 120214, 119362, 917974, 8613, 0, 126121, 917978, 917979, 121449, + 12005, 7353, 0, 1890, 129130, 0, 0, 0, 42815, 7991, 0, 10578, 0, 0, 0, 0, + 0, 0, 0, 111190, 120601, 42668, 9348, 0, 6164, 0, 0, 0, 7676, 0, 0, 0, 0, + 128732, 129422, 83443, 71096, 83444, 9175, 0, 78047, 9088, 73689, 0, + 1396, 0, 0, 11461, 71088, 127835, 92252, 0, 71090, 121185, 69872, 0, 0, + 0, 0, 74043, 119632, 0, 0, 0, 5928, 4525, 10658, 0, 1266, 10180, 64472, + 0, 12622, 0, 0, 0, 0, 127139, 13310, 773, 19933, 0, 0, 0, 0, 92205, 0, 0, + 0, 0, 5862, 7823, 0, 0, 0, 3250, 43991, 69687, 66649, 0, 0, 0, 0, 0, + 64673, 917963, 917964, 0, 0, 917967, 917968, 917965, 917966, 127791, + 75041, 3471, 917970, 64573, 882, 0, 119584, 0, 120772, 0, 0, 0, 92696, 0, + 0, 72988, 0, 3225, 0, 73729, 0, 0, 43173, 11752, 4381, 0, 0, 917945, + 11756, 11757, 917944, 917949, 42654, 127848, 118663, 0, 0, 5160, 1387, 0, + 917953, 0, 128933, 917956, 917957, 917954, 917955, 118595, 121082, + 917958, 10789, 68314, 0, 126521, 11143, 0, 0, 70669, 128904, 42179, 0, + 5931, 11744, 11215, 70676, 119245, 0, 0, 0, 77915, 10217, 64635, 128661, + 83292, 0, 0, 0, 0, 0, 41296, 11747, 41291, 0, 0, 0, 41294, 41282, 5923, + 120610, 0, 0, 0, 0, 66800, 5786, 68252, 42539, 119869, 119860, 0, 41474, + 0, 0, 0, 5934, 74572, 66583, 119231, 0, 94072, 64481, 0, 0, 0, 0, 67240, + 0, 0, 123201, 0, 5819, 0, 0, 0, 0, 0, 129387, 0, 0, 0, 67993, 1237, + 194749, 0, 0, 983557, 0, 0, 0, 0, 0, 0, 0, 69789, 11266, 69845, 0, 10506, + 194747, 0, 0, 0, 0, 43185, 194748, 100533, 100532, 100535, 10769, 100537, + 100536, 100539, 9753, 121035, 100540, 0, 0, 121433, 0, 100542, 6072, + 100544, 100543, 100546, 100545, 100548, 100547, 100550, 100549, 0, + 113744, 0, 0, 7222, 10283, 10315, 10379, 4996, 0, 129294, 66517, 0, + 10087, 127833, 74938, 0, 0, 83492, 7565, 42890, 0, 73520, 43180, 77928, + 74891, 77929, 43982, 100526, 622, 77926, 100527, 100530, 1602, 0, 0, 0, + 129559, 12160, 0, 10212, 77936, 194605, 12071, 43143, 77935, 917983, + 917984, 917989, 77932, 917987, 917988, 10255, 10263, 10279, 4194, 10375, + 93035, 0, 0, 12644, 127516, 917994, 75007, 110791, 67408, 110789, 11501, + 41177, 0, 0, 71912, 0, 0, 8715, 0, 41179, 0, 0, 0, 41176, 0, 41181, 0, + 8452, 121006, 13161, 0, 70503, 5921, 0, 2597, 0, 5922, 72128, 0, 74242, + 128374, 0, 0, 0, 0, 0, 0, 0, 127906, 0, 64944, 0, 0, 0, 0, 5924, 5920, + 129508, 6921, 78081, 74007, 78078, 8418, 11681, 43169, 10176, 0, 0, 0, + 78087, 10772, 65276, 5937, 1914, 78084, 11682, 0, 0, 0, 11685, 0, 100513, + 7772, 11680, 100514, 100517, 100516, 100519, 7417, 718, 100520, 70083, + 100500, 120718, 3235, 0, 43164, 0, 8018, 0, 0, 128708, 6937, 67672, + 128508, 0, 10067, 120849, 0, 0, 0, 118693, 0, 100491, 0, 100493, 100492, + 13116, 100494, 100497, 9945, 100499, 100498, 0, 0, 0, 0, 2059, 0, 100502, + 100501, 1431, 100503, 66565, 100505, 100508, 12804, 100510, 100509, + 78090, 3307, 78088, 78089, 0, 4544, 71228, 0, 0, 0, 78097, 11110, 66810, + 12882, 64511, 78094, 78100, 78102, 71226, 10141, 0, 78280, 65298, 4476, + 78109, 94005, 71216, 8907, 78105, 78106, 78103, 78104, 120898, 0, 10665, + 64616, 128944, 0, 127545, 69605, 83159, 83160, 4554, 0, 83155, 83156, + 83157, 83158, 0, 125123, 0, 72258, 129831, 0, 129815, 0, 43179, 0, 0, 0, + 717, 10754, 83168, 83169, 83162, 83163, 83164, 83165, 78282, 0, 0, 83161, + 68848, 10611, 72859, 126978, 71474, 129426, 127871, 0, 0, 0, 12820, + 110882, 0, 7009, 70103, 0, 0, 67848, 41173, 4574, 0, 0, 128338, 575, + 78110, 43456, 8563, 100469, 0, 0, 65565, 123598, 5936, 7290, 78117, + 78118, 74919, 308, 78113, 78114, 83151, 78123, 83153, 83154, 0, 0, 0, 0, + 67496, 5926, 68250, 78130, 78126, 78127, 78124, 78125, 42513, 0, 129026, + 0, 11651, 13093, 78135, 0, 100471, 0, 100473, 100472, 100475, 74048, + 100477, 71995, 100457, 100456, 43703, 13097, 0, 100460, 13283, 0, 0, + 125073, 3488, 5933, 10033, 983947, 0, 65570, 0, 12297, 0, 0, 0, 128517, + 42538, 0, 129293, 0, 100451, 0, 100453, 100452, 100455, 100454, 121221, + 0, 0, 7638, 0, 129193, 0, 43109, 7637, 0, 11213, 100461, 83355, 100463, + 100466, 100465, 0, 0, 7636, 0, 0, 0, 128848, 983087, 291, 0, 0, 2027, + 78141, 78142, 78136, 78137, 83481, 4640, 64713, 10224, 120429, 11183, + 83482, 120430, 0, 0, 0, 127148, 83479, 0, 0, 83488, 0, 0, 0, 0, 68837, + 5778, 0, 0, 0, 12680, 119130, 0, 67242, 93041, 0, 0, 0, 11552, 0, 127855, + 0, 70091, 0, 10172, 65453, 120408, 66014, 120410, 0, 4641, 11556, 64819, + 78269, 120416, 72341, 41469, 41467, 120412, 120415, 4646, 120425, 865, + 78275, 78274, 78273, 4645, 78271, 78270, 0, 983173, 7338, 0, 68840, 0, + 12565, 0, 0, 0, 195089, 119655, 195091, 195090, 2913, 13120, 128956, + 69493, 195097, 195096, 128019, 0, 71462, 0, 7916, 10485, 195098, 0, + 195100, 195099, 0, 67705, 128351, 195077, 195080, 129636, 129549, 195081, + 0, 0, 0, 10229, 10687, 826, 128081, 195082, 195085, 195084, 195087, + 195086, 0, 1808, 7848, 0, 0, 0, 0, 0, 0, 128897, 69255, 42942, 67704, 0, + 0, 0, 0, 42940, 0, 9144, 0, 0, 92992, 9840, 0, 0, 0, 0, 0, 0, 74448, + 83475, 0, 10962, 66904, 113718, 983188, 0, 0, 74537, 195072, 1792, + 195074, 195073, 78266, 195075, 0, 0, 12066, 0, 385, 4152, 0, 0, 0, 67397, + 0, 0, 0, 0, 43258, 0, 0, 13157, 0, 0, 3570, 0, 0, 0, 67252, 0, 71218, + 126631, 7879, 68247, 128579, 78914, 0, 70196, 0, 0, 8463, 7810, 917862, + 7839, 983878, 127768, 917860, 9691, 0, 129323, 0, 120385, 0, 917844, 0, + 10066, 0, 2175, 0, 0, 0, 8016, 0, 983072, 64831, 0, 126103, 0, 73493, + 1634, 68115, 94192, 11056, 0, 0, 0, 41165, 11328, 12450, 0, 41166, 0, + 12456, 0, 171, 67508, 12452, 917544, 12458, 12531, 0, 917853, 0, 74162, + 0, 0, 9969, 0, 12454, 74160, 42132, 110755, 78878, 110753, 3230, 73711, + 0, 0, 8932, 4399, 5810, 64534, 8415, 0, 110756, 110757, 74159, 0, 0, 960, + 74156, 6981, 92374, 12938, 9201, 0, 118713, 74904, 0, 72866, 92270, 0, 0, + 0, 129792, 5851, 73833, 5824, 0, 5844, 110848, 110849, 110846, 110847, + 4663, 0, 0, 0, 0, 0, 74085, 0, 0, 0, 0, 0, 92339, 0, 0, 5782, 67495, 0, + 0, 43796, 129639, 0, 195083, 125223, 128004, 0, 43861, 0, 0, 0, 92976, 0, + 0, 0, 4659, 0, 128894, 0, 0, 129386, 0, 11129, 2238, 329, 0, 92707, + 121416, 0, 0, 0, 69943, 67692, 42167, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 69618, 43671, 0, 64701, 0, 0, 0, 93055, 1172, 125089, 6786, 43601, 0, + 74126, 0, 0, 0, 0, 0, 118695, 0, 0, 118804, 0, 66741, 5347, 125026, + 983663, 0, 0, 10588, 0, 0, 0, 0, 5343, 0, 0, 0, 5341, 0, 0, 74916, 5351, + 0, 0, 917884, 0, 92692, 0, 121148, 128916, 0, 0, 66785, 126256, 6638, 0, + 0, 271, 0, 917904, 0, 0, 12653, 67588, 0, 0, 0, 0, 128838, 11912, 128301, + 983665, 0, 11800, 0, 0, 11103, 0, 7340, 0, 110695, 0, 0, 70170, 0, 2423, + 0, 0, 0, 128136, 42705, 0, 0, 0, 11854, 0, 0, 0, 0, 4916, 0, 380, 10958, + 66563, 127790, 78284, 67587, 0, 12918, 0, 917897, 0, 917898, 917893, + 10684, 0, 125063, 92906, 0, 0, 8182, 0, 0, 129434, 0, 0, 0, 6859, 0, + 6630, 100405, 0, 123191, 0, 0, 0, 65876, 5535, 129892, 0, 0, 92609, 0, + 983348, 6477, 43795, 92217, 129571, 72163, 69496, 43848, 0, 0, 74256, + 2665, 11304, 43751, 0, 4970, 74353, 0, 8934, 0, 93996, 4492, 92908, + 65011, 0, 0, 92909, 1188, 7254, 1100, 0, 0, 0, 2912, 11749, 92643, 0, 0, + 65057, 0, 12343, 0, 78879, 0, 78880, 0, 0, 0, 70355, 0, 0, 11803, 0, 0, + 41450, 0, 100897, 0, 41451, 0, 0, 8273, 0, 3451, 0, 972, 41453, 68164, + 78876, 0, 92408, 73945, 43504, 2288, 78873, 9538, 78874, 128685, 0, + 129095, 0, 0, 0, 0, 11019, 0, 0, 121205, 0, 73007, 71365, 92716, 5927, 0, + 0, 0, 0, 128484, 0, 6073, 0, 0, 0, 6075, 93995, 282, 126510, 0, 74078, + 121459, 2206, 0, 0, 66791, 0, 3474, 0, 0, 0, 6081, 0, 127843, 74076, 0, + 0, 0, 128908, 0, 0, 0, 12623, 120273, 9120, 120275, 4665, 12628, 4670, + 120271, 120272, 0, 0, 121480, 958, 0, 0, 0, 4666, 0, 4915, 0, 4669, 0, 0, + 0, 4664, 0, 120550, 0, 0, 0, 0, 94023, 0, 917875, 8664, 11664, 0, 129327, + 11224, 0, 0, 1063, 119088, 120251, 9772, 7255, 8886, 0, 127932, 120257, + 120258, 120259, 120260, 42661, 71345, 120255, 119125, 120265, 120266, + 120267, 42721, 92407, 120262, 120263, 66788, 1017, 0, 118580, 505, 1447, + 0, 0, 70340, 66793, 65115, 42789, 128443, 0, 0, 123634, 0, 119195, 0, 0, + 11745, 7919, 0, 1641, 0, 0, 8966, 0, 0, 8743, 71870, 0, 67813, 0, 0, 0, + 123206, 0, 0, 128505, 10169, 71324, 0, 10068, 0, 120457, 120456, 120455, + 120454, 257, 43170, 13153, 0, 0, 0, 0, 0, 0, 6496, 19917, 5930, 128354, + 11033, 0, 0, 5622, 120436, 8477, 8474, 120433, 120432, 0, 0, 0, 41435, + 4352, 0, 2435, 0, 5621, 0, 4201, 8450, 4203, 4202, 4205, 4204, 120447, + 120446, 120445, 66792, 41440, 120442, 8473, 6373, 8469, 120438, 0, 4564, + 125206, 0, 0, 0, 8374, 73669, 0, 0, 66796, 0, 0, 0, 0, 0, 69297, 129762, + 5626, 43507, 11771, 0, 0, 0, 42614, 0, 5625, 0, 0, 0, 5623, 0, 0, 42623, + 64277, 69942, 0, 0, 120752, 0, 5817, 5629, 0, 7551, 10325, 5632, 69674, + 0, 0, 124946, 125194, 5628, 129766, 5631, 0, 0, 2400, 5627, 0, 0, 118786, + 74792, 0, 0, 0, 203, 129084, 74365, 0, 0, 0, 0, 83382, 83422, 0, 0, 554, + 0, 0, 0, 12182, 0, 64569, 110840, 73891, 0, 0, 0, 7689, 69798, 9323, + 10269, 10285, 10317, 175, 0, 0, 0, 0, 0, 1243, 42154, 0, 92387, 0, 0, + 43651, 0, 125021, 0, 9075, 118597, 0, 64777, 128570, 0, 0, 0, 0, 65255, + 0, 121142, 4490, 0, 6649, 120698, 12181, 0, 11977, 7249, 8366, 0, 7756, + 12342, 0, 51, 41516, 69432, 0, 9568, 71318, 456, 0, 10437, 1168, 9251, + 9082, 0, 0, 42781, 3866, 0, 41512, 0, 0, 68121, 41494, 0, 4660, 0, 10405, + 0, 0, 0, 0, 0, 73918, 119627, 110686, 41454, 12605, 0, 126611, 41455, + 917996, 983605, 0, 8214, 0, 100413, 129320, 41457, 983077, 0, 1969, + 127771, 0, 69554, 7413, 0, 69426, 10341, 43864, 78079, 5854, 0, 0, 0, + 129684, 72819, 0, 0, 73548, 0, 0, 8429, 0, 72328, 0, 6429, 0, 0, 0, 0, + 110688, 83417, 0, 917864, 120813, 83423, 1662, 125000, 0, 0, 917871, + 917868, 0, 0, 66, 65, 68, 67, 70, 69, 72, 71, 74, 73, 76, 75, 78, 77, 80, + 79, 82, 81, 84, 83, 86, 85, 88, 87, 90, 89, 0, 0, 7385, 70508, 1704, + 12993, 0, 0, 0, 0, 0, 0, 0, 0, 11353, 72207, 0, 0, 0, 0, 118831, 0, 0, 0, + 0, 0, 118719, 83364, 0, 0, 1289, 0, 0, 119583, 0, 65507, 0, 0, 0, 128042, + 0, 74409, 0, 0, 0, 0, 64793, 0, 0, 100843, 5675, 119239, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 6972, 70735, 0, 121108, 126217, 0, 0, 0, 0, 0, 110640, + 67687, 0, 0, 119634, 0, 43977, 111252, 129105, 0, 7412, 64671, 0, 1412, + 4594, 1391, 0, 8067, 12478, 110639, 78375, 110637, 10281, 110635, 0, 0, + 7960, 43271, 0, 12518, 69846, 0, 3566, 0, 0, 69864, 0, 0, 68021, 0, 0, 0, + 8223, 0, 4261, 121460, 68918, 0, 0, 121294, 113712, 0, 128046, 43419, + 72748, 92866, 10574, 0, 67691, 0, 0, 73785, 0, 78875, 128541, 0, 127366, + 0, 0, 0, 0, 6695, 65113, 324, 0, 128373, 40985, 0, 0, 0, 0, 0, 72307, + 43474, 0, 121190, 0, 0, 3420, 0, 0, 0, 0, 0, 0, 0, 0, 0, 110871, 9574, + 120684, 110870, 110814, 5204, 74774, 0, 11835, 0, 0, 983186, 0, 0, 0, 0, + 0, 0, 11750, 68898, 127004, 0, 0, 0, 0, 8130, 0, 0, 0, 121268, 0, 129443, + 0, 68455, 42863, 73839, 0, 0, 0, 92288, 0, 0, 0, 612, 110875, 110876, + 72231, 10538, 0, 1674, 0, 0, 0, 12280, 0, 540, 74550, 0, 66422, 8432, 0, + 11073, 0, 64316, 129894, 0, 7388, 0, 0, 0, 0, 126107, 0, 3359, 0, 0, + 67284, 0, 0, 65482, 129589, 0, 64742, 129304, 0, 124141, 74273, 0, 19941, + 0, 0, 0, 0, 9481, 65555, 0, 66628, 129126, 1195, 64898, 0, 0, 0, 2010, 0, + 0, 0, 0, 0, 0, 4360, 127009, 9739, 0, 72885, 0, 0, 0, 126265, 72200, 0, + 0, 120025, 72199, 0, 0, 65734, 0, 0, 129690, 13075, 0, 94063, 0, 43532, + 10837, 2492, 74516, 983075, 120882, 0, 0, 11813, 9649, 0, 119617, 5128, + 7377, 0, 65604, 0, 0, 6771, 1648, 7819, 0, 0, 0, 125192, 128131, 12709, + 6986, 0, 0, 0, 0, 0, 12581, 0, 5175, 0, 73806, 0, 128420, 0, 0, 77950, 0, + 0, 607, 0, 0, 128846, 119605, 67475, 129528, 65477, 0, 121130, 0, 8265, + 0, 0, 0, 5840, 42838, 0, 0, 68366, 0, 119255, 0, 0, 0, 127929, 0, 2550, + 121011, 6779, 70059, 0, 0, 0, 0, 0, 0, 5619, 65822, 0, 0, 0, 129392, + 5616, 11486, 0, 0, 0, 0, 5615, 0, 121319, 42380, 127958, 0, 66451, 74407, + 0, 11347, 0, 1026, 5620, 0, 0, 11350, 5617, 0, 0, 64639, 0, 0, 0, 1338, + 0, 0, 0, 4603, 0, 70715, 92484, 0, 9002, 0, 3974, 78213, 0, 0, 0, 0, 0, + 0, 75038, 66040, 70455, 0, 0, 0, 72982, 0, 0, 0, 0, 0, 118661, 0, 0, + 119105, 0, 0, 0, 0, 0, 128883, 0, 66897, 0, 0, 0, 42594, 0, 0, 0, 0, + 6714, 10083, 0, 121019, 0, 69976, 0, 0, 9073, 0, 64302, 0, 128286, 9725, + 0, 0, 121288, 73769, 121306, 0, 9570, 0, 11500, 2689, 917626, 0, 983813, + 66740, 0, 0, 0, 917623, 13286, 5500, 42598, 42596, 503, 0, 0, 917618, 0, + 0, 0, 0, 917615, 1652, 772, 6688, 8310, 0, 0, 72124, 0, 10194, 43542, 0, + 125054, 0, 6468, 68110, 0, 917606, 11767, 0, 0, 5836, 12358, 0, 0, 65624, + 12180, 0, 127994, 0, 43699, 0, 0, 72114, 43706, 0, 12362, 12435, 12360, + 0, 9020, 0, 12356, 8616, 0, 42924, 2227, 0, 0, 7315, 12354, 83097, 83098, + 83099, 2358, 83092, 83093, 83094, 0, 0, 83089, 83090, 0, 11759, 71723, 0, + 72834, 83109, 41423, 0, 83103, 83104, 83105, 42237, 110653, 70717, 72260, + 83102, 0, 67856, 0, 128534, 110657, 129354, 129194, 0, 64395, 0, 73008, + 120897, 74816, 0, 0, 0, 83088, 0, 0, 94064, 83083, 83085, 83086, 83087, + 83079, 83080, 2041, 9178, 0, 64870, 0, 83076, 74924, 0, 0, 0, 0, 0, + 78739, 0, 0, 0, 0, 0, 0, 3726, 0, 0, 0, 0, 0, 121432, 129457, 0, 0, 0, 0, + 0, 74901, 0, 0, 0, 0, 0, 124944, 113781, 0, 7410, 2669, 903, 0, 0, 0, + 127232, 74603, 0, 128264, 0, 128411, 0, 0, 11732, 0, 72797, 41448, 41461, + 124934, 0, 917558, 0, 8819, 0, 0, 74606, 92847, 121412, 74835, 0, 9168, + 65786, 0, 73691, 0, 67665, 0, 11758, 68425, 0, 0, 0, 128044, 0, 19924, + 67312, 0, 128755, 64551, 0, 8516, 0, 0, 7561, 983999, 74018, 0, 0, 0, 0, + 83074, 83075, 0, 11233, 83062, 83066, 3787, 83070, 83055, 41458, 83059, + 41463, 65308, 41459, 8683, 775, 0, 65584, 69923, 0, 110798, 110799, + 110796, 43440, 0, 0, 0, 3656, 0, 0, 0, 67694, 1599, 83138, 83139, 8514, + 8513, 83036, 83135, 83136, 110794, 110795, 83131, 83132, 0, 0, 0, 11684, + 10542, 9937, 83150, 0, 75037, 83145, 65730, 83147, 0, 8427, 83142, 55246, + 0, 0, 11497, 0, 0, 0, 119222, 0, 983598, 0, 10621, 0, 0, 129295, 119111, + 120745, 0, 0, 0, 11648, 83126, 83127, 42118, 83129, 83122, 65512, 83124, + 83125, 0, 0, 0, 83121, 74530, 128456, 0, 0, 0, 65724, 0, 0, 0, 65727, 0, + 0, 64963, 73830, 66042, 0, 0, 7875, 0, 0, 0, 129476, 0, 0, 536, 0, 0, 0, + 0, 65173, 129122, 0, 70331, 0, 0, 118598, 0, 129419, 0, 0, 0, 1687, 0, 0, + 0, 0, 0, 0, 10526, 0, 8323, 0, 83301, 11731, 73530, 0, 65460, 12242, 0, + 0, 10843, 11554, 0, 0, 8266, 0, 121101, 0, 0, 0, 0, 67667, 118694, + 119155, 0, 0, 119636, 67857, 0, 0, 0, 11755, 66305, 0, 0, 10917, 93979, + 113688, 0, 2040, 92596, 0, 0, 0, 0, 1227, 83119, 83120, 0, 0, 83115, + 74427, 11149, 4978, 83111, 1984, 11830, 83114, 128934, 74548, 118545, + 9373, 0, 0, 0, 0, 0, 0, 0, 0, 9237, 9390, 0, 0, 0, 0, 0, 1830, 0, 0, 0, + 0, 0, 128577, 983839, 68086, 0, 0, 0, 983059, 0, 983145, 0, 0, 0, 72197, + 55291, 11683, 0, 983659, 0, 11451, 0, 72714, 3731, 2359, 0, 67844, 0, + 121503, 548, 121502, 983250, 121405, 983253, 0, 66272, 0, 64678, 0, 9547, + 0, 0, 1614, 0, 0, 66307, 128092, 1358, 120871, 428, 0, 1466, 0, 10982, 0, + 0, 0, 407, 0, 0, 0, 0, 0, 0, 5804, 73464, 0, 0, 0, 70167, 9057, 42446, 0, + 125097, 0, 0, 8250, 10952, 8048, 0, 129155, 0, 118955, 0, 0, 118593, + 4407, 74648, 0, 0, 0, 8448, 92491, 0, 0, 12675, 12659, 0, 0, 983285, + 68077, 55273, 10766, 12012, 2386, 0, 9170, 0, 9123, 128194, 0, 0, 0, 0, + 129942, 0, 0, 0, 0, 0, 0, 8709, 0, 72383, 0, 0, 0, 0, 0, 0, 0, 128342, 0, + 577, 128610, 0, 0, 124999, 68087, 74840, 126474, 127036, 0, 0, 0, 1414, + 124963, 9683, 43486, 92231, 0, 2536, 0, 66330, 0, 0, 0, 0, 0, 0, 0, + 66317, 0, 66315, 66316, 0, 0, 0, 0, 0, 0, 0, 0, 66323, 66324, 0, 0, 3106, + 65917, 0, 2182, 0, 891, 0, 0, 42624, 0, 0, 8824, 65089, 128734, 10936, 0, + 0, 0, 0, 92688, 0, 0, 0, 0, 12745, 0, 0, 41285, 3547, 0, 0, 129877, 0, + 118701, 6089, 0, 68490, 120578, 4170, 1029, 127761, 0, 0, 42374, 917625, + 744, 917624, 0, 0, 0, 93046, 0, 3551, 0, 0, 4623, 0, 0, 12340, 0, 65136, + 0, 0, 0, 0, 0, 0, 0, 72291, 0, 0, 120778, 0, 11972, 0, 78757, 0, 122886, + 177, 122894, 0, 0, 0, 0, 55243, 0, 0, 0, 70172, 120249, 120242, 128027, + 120243, 0, 0, 0, 120237, 120245, 94079, 0, 0, 9136, 120240, 120614, + 41280, 0, 0, 0, 0, 74149, 128327, 0, 0, 66361, 12601, 72194, 64360, + 65163, 125241, 0, 0, 0, 0, 0, 5404, 43332, 3667, 7936, 12925, 0, 0, 0, 0, + 0, 10874, 65505, 0, 0, 0, 0, 128920, 983681, 0, 0, 0, 0, 0, 0, 0, 0, + 66677, 0, 0, 0, 70088, 74148, 0, 0, 72868, 120230, 120224, 74172, 0, 0, + 94096, 0, 128414, 120636, 0, 127519, 917609, 917616, 0, 128652, 0, 0, + 11441, 0, 3512, 0, 0, 43597, 0, 0, 72734, 68153, 41563, 0, 0, 129352, + 41544, 0, 0, 74927, 0, 129177, 0, 0, 0, 118908, 0, 78108, 67396, 73804, + 64711, 0, 0, 917610, 0, 0, 0, 11557, 127776, 0, 12079, 0, 0, 0, 0, + 128861, 0, 0, 0, 0, 0, 983201, 8103, 72303, 128174, 92486, 110698, 0, + 64587, 0, 0, 124961, 0, 0, 0, 126481, 0, 0, 0, 0, 0, 70348, 1450, 0, + 1340, 0, 0, 128970, 0, 0, 125117, 0, 0, 0, 0, 6539, 92948, 0, 128213, + 125060, 0, 0, 0, 3973, 0, 70504, 121193, 7982, 0, 0, 127194, 0, 0, 0, + 128408, 118968, 6417, 120619, 129748, 0, 0, 0, 129455, 4919, 65121, + 110872, 7755, 0, 0, 64548, 0, 1621, 0, 0, 0, 0, 0, 12188, 0, 0, 0, 0, + 5015, 0, 0, 42590, 70354, 1756, 0, 0, 0, 120694, 0, 0, 7555, 73874, 5408, + 2817, 1214, 69919, 0, 983126, 0, 0, 125055, 127195, 7957, 0, 0, 1056, + 74944, 0, 0, 0, 0, 7073, 74979, 0, 70853, 0, 110874, 0, 0, 2341, 126644, + 8484, 0, 0, 68322, 0, 8461, 67721, 42269, 0, 0, 43709, 43708, 9451, 7571, + 13073, 43847, 126647, 0, 983263, 0, 0, 0, 8781, 12894, 78134, 0, 78132, + 0, 0, 78184, 0, 11338, 120768, 0, 0, 0, 0, 0, 121367, 65021, 64795, + 74574, 0, 10047, 0, 0, 0, 0, 0, 0, 119181, 163, 576, 9895, 0, 0, 74591, + 0, 0, 66888, 0, 0, 0, 0, 0, 0, 7017, 128111, 0, 0, 129922, 0, 41591, + 11036, 65252, 120795, 129488, 0, 0, 0, 0, 0, 0, 8887, 0, 7295, 71203, 0, + 127221, 0, 0, 0, 0, 8755, 0, 0, 8147, 73127, 0, 0, 121348, 0, 129377, 0, + 74499, 0, 0, 0, 4619, 0, 6654, 123192, 0, 0, 0, 65689, 10128, 0, 129612, + 0, 0, 92651, 0, 2401, 0, 8792, 118546, 0, 74980, 0, 92246, 0, 0, 0, + 12886, 0, 66624, 0, 0, 74133, 65170, 0, 74135, 0, 0, 9984, 73867, 3010, + 0, 70349, 10698, 41475, 0, 119151, 0, 119152, 0, 0, 9100, 0, 0, 0, 78116, + 64780, 2001, 0, 55230, 0, 4052, 92856, 7626, 78080, 0, 0, 0, 41477, 0, 0, + 0, 43707, 74127, 0, 0, 0, 78086, 73758, 2335, 10663, 0, 0, 129872, + 119602, 0, 0, 70325, 0, 41443, 0, 0, 0, 9711, 1523, 0, 0, 41445, 0, 0, + 8567, 41442, 12821, 0, 0, 118978, 0, 65274, 0, 94082, 0, 127515, 0, 0, + 43446, 0, 0, 0, 0, 127985, 0, 10206, 127167, 6375, 2673, 0, 0, 0, 43219, + 129355, 0, 0, 0, 0, 129400, 11799, 101225, 68466, 0, 0, 0, 0, 0, 120736, + 0, 7203, 0, 0, 70361, 127213, 120615, 127216, 0, 0, 0, 0, 43121, 0, + 128366, 72161, 0, 129868, 0, 121260, 73781, 70365, 0, 68039, 70446, 10057, 0, 0, 0, 101219, 120963, 101220, 2307, 0, 0, 0, 0, 73873, 0, 94035, 0, 0, 67469, 0, 129983, 7327, 0, 0, 440, 0, 0, 68613, 75059, 0, 0, 9957, 0, 0, 8046, 0, 119158, 0, 0, 68609, 0, 129405, 1521, 129460, 92256, @@ -28625,9 +28818,9 @@ static const unsigned int code_hash[] = { 120458, 5647, 120473, 7387, 0, 92675, 11477, 5646, 0, 11018, 0, 0, 0, 0, 0, 0, 69280, 128459, 126128, 5651, 0, 0, 0, 5648, 0, 120920, 0, 127517, 3545, 0, 6984, 0, 0, 0, 69414, 126613, 0, 10123, 0, 69274, 0, 0, 65020, - 74885, 119166, 0, 0, 0, 0, 0, 1140, 78426, 0, 0, 0, 0, 8128, 9889, 0, 0, - 1815, 0, 890, 0, 3267, 0, 0, 0, 983686, 4410, 125081, 10576, 8102, 0, - 580, 74232, 0, 0, 0, 0, 0, 19938, 0, 0, 0, 0, 3298, 6546, 0, 0, 0, 0, + 74885, 119166, 0, 0, 0, 0, 0, 1140, 78426, 0, 0, 0, 122665, 8128, 9889, + 0, 0, 1815, 0, 890, 0, 3267, 0, 0, 0, 983686, 4410, 125081, 10576, 8102, + 0, 580, 74232, 0, 0, 0, 0, 0, 19938, 0, 0, 0, 0, 3298, 6546, 0, 0, 0, 0, 6134, 41246, 0, 0, 0, 917770, 0, 6264, 0, 0, 0, 0, 0, 0, 69445, 0, 0, 0, 92697, 11915, 10377, 0, 10072, 0, 0, 2329, 0, 0, 0, 0, 0, 0, 0, 67498, 0, 101164, 0, 11201, 92708, 74769, 0, 13263, 0, 0, 92404, 126066, 69491, 0, @@ -28637,12 +28830,12 @@ static const unsigned int code_hash[] = { 11829, 68197, 0, 0, 11475, 70329, 3020, 42264, 0, 0, 0, 7098, 0, 0, 127967, 957, 42696, 0, 3016, 0, 0, 0, 0, 0, 121248, 92510, 3006, 4620, 0, 0, 0, 0, 129369, 129425, 0, 0, 0, 126246, 8626, 0, 128824, 0, 65377, 0, - 983102, 42920, 1698, 0, 64477, 0, 0, 43813, 100432, 100431, 100434, + 983103, 42920, 1698, 0, 64477, 0, 0, 43813, 100432, 100431, 100434, 100433, 100436, 70321, 100438, 100437, 100440, 100439, 0, 121024, 101177, 70327, 100441, 55252, 100443, 100442, 100445, 100444, 66641, 100446, 100449, 100448, 0, 100450, 113820, 74866, 64375, 0, 127850, 129477, 0, 0, 0, 0, 983799, 0, 0, 120827, 0, 0, 123637, 0, 0, 0, 101183, 8110, 100421, - 0, 100423, 5830, 100425, 100424, 100427, 100426, 100429, 100428, 42389, + 0, 100423, 5830, 100425, 100424, 100427, 73540, 100429, 100428, 42389, 78611, 121398, 0, 0, 0, 0, 0, 0, 0, 83342, 983954, 0, 127147, 119187, 2135, 11836, 0, 0, 78869, 42313, 5579, 0, 70384, 983082, 94002, 0, 5578, 11840, 73006, 42023, 69849, 5669, 92559, 0, 0, 68833, 917845, 128275, @@ -28678,75 +28871,76 @@ static const unsigned int code_hash[] = { 118626, 0, 0, 113710, 0, 73449, 68069, 0, 70332, 0, 5659, 0, 0, 66729, 5655, 0, 0, 0, 68806, 0, 128225, 66310, 73444, 0, 0, 70362, 0, 11609, 0, 126990, 92949, 10272, 10304, 10368, 74511, 594, 10244, 10248, 10256, - 983918, 0, 0, 3467, 41010, 0, 3331, 946, 0, 1495, 13184, 74330, 128242, - 9562, 0, 123175, 0, 70036, 0, 0, 0, 123176, 0, 0, 0, 5666, 65227, 123174, - 68419, 0, 11796, 123178, 0, 0, 10186, 123172, 7732, 983755, 0, 0, 0, - 5668, 83334, 0, 74645, 5670, 0, 0, 12741, 126619, 123638, 5667, 19952, - 120807, 113766, 12749, 0, 67757, 2263, 0, 0, 119260, 129131, 9286, 83335, - 128457, 83336, 70359, 0, 3571, 13247, 5874, 78279, 73447, 68435, 78278, - 78267, 78268, 0, 78265, 553, 113768, 0, 93053, 5829, 0, 4587, 78285, - 78299, 129699, 12746, 0, 70338, 0, 5633, 0, 94101, 94102, 94099, 94100, - 94105, 74856, 94103, 12742, 0, 983837, 0, 0, 0, 70330, 0, 983830, 0, 0, - 0, 12148, 0, 0, 0, 0, 0, 64938, 67234, 5634, 0, 0, 2146, 0, 118880, 2425, - 65182, 983832, 43636, 0, 83326, 328, 0, 68736, 0, 5636, 123163, 5329, 0, - 5638, 0, 7940, 0, 43223, 43760, 5635, 3373, 72424, 78292, 74223, 73441, - 68763, 78287, 9833, 0, 74208, 41635, 0, 77775, 43040, 78297, 68778, - 78295, 5639, 65603, 5660, 5640, 78303, 0, 78300, 0, 68301, 0, 0, 78312, - 0, 78310, 41625, 78308, 78309, 100731, 41780, 5642, 100732, 100735, - 100734, 4356, 100736, 100739, 12051, 70166, 100740, 5641, 8259, 0, 0, 0, - 119570, 0, 0, 121264, 983558, 0, 0, 0, 73890, 0, 0, 2800, 11220, 5645, - 64964, 8652, 83323, 0, 0, 121356, 5608, 128281, 119932, 118562, 0, 0, - 9000, 0, 83324, 92673, 129176, 0, 5613, 74267, 100721, 100724, 5610, - 100726, 92965, 100728, 5612, 100730, 10787, 0, 3615, 123647, 5609, 78316, - 78317, 78313, 78315, 5875, 5808, 0, 8186, 0, 74269, 0, 70004, 65874, - 72422, 5807, 0, 66320, 5306, 12936, 0, 92970, 127961, 0, 92583, 10211, 0, - 0, 78871, 121063, 0, 129512, 0, 0, 0, 0, 0, 74237, 0, 9133, 74262, 0, - 92840, 0, 64779, 4672, 0, 6185, 64776, 0, 121266, 6499, 0, 0, 0, 92720, - 0, 67494, 93791, 2534, 0, 93768, 93778, 93762, 71849, 71869, 93781, - 64583, 93761, 93780, 93760, 93787, 92443, 128714, 71848, 93774, 66411, - 93785, 71841, 93770, 93769, 0, 0, 0, 121168, 68443, 69774, 931, 0, - 125052, 6363, 2748, 0, 0, 0, 983603, 44011, 0, 0, 100711, 119009, 100713, - 100712, 100715, 65896, 100717, 78298, 100719, 100718, 128836, 100720, - 11649, 0, 0, 0, 0, 0, 42341, 65284, 0, 0, 12884, 0, 7907, 127255, 0, 0, - 0, 0, 68779, 0, 68786, 0, 100691, 0, 100693, 100692, 42851, 100694, - 100697, 100696, 92276, 78226, 66393, 100700, 0, 93773, 93776, 93777, - 100702, 78301, 100704, 100703, 42415, 78307, 4542, 69909, 94022, 100709, - 0, 0, 0, 0, 42454, 11565, 7949, 124939, 0, 0, 42494, 3073, 0, 0, 42302, - 0, 126553, 70810, 0, 72401, 0, 0, 0, 129319, 4877, 100681, 100684, - 100683, 10548, 100685, 100688, 100687, 100690, 64798, 70805, 5346, 0, - 126570, 0, 4874, 0, 0, 0, 0, 0, 65884, 0, 0, 0, 11378, 0, 42785, 0, 3251, - 11203, 0, 0, 0, 69568, 11052, 0, 5342, 8317, 0, 0, 5340, 0, 0, 128599, 0, - 129538, 0, 128395, 0, 128510, 0, 0, 9142, 0, 0, 0, 10938, 0, 0, 1182, - 127381, 4829, 0, 0, 72438, 529, 0, 0, 0, 10586, 10790, 10839, 121427, - 41593, 100669, 0, 0, 41594, 225, 66418, 0, 0, 983969, 11376, 0, 41596, 0, - 64975, 0, 0, 11084, 3194, 0, 78306, 78305, 0, 0, 0, 11324, 0, 0, 8420, - 127756, 128844, 0, 41338, 129683, 11485, 0, 41322, 66605, 100671, 0, - 100673, 100672, 100675, 5161, 41330, 100676, 100679, 100678, 100659, - 100658, 0, 100660, 0, 100485, 12361, 0, 12359, 983559, 41369, 66412, - 12191, 0, 0, 0, 0, 78221, 41376, 0, 9870, 0, 41385, 65824, 100651, 11938, - 100653, 100652, 100655, 100654, 42678, 100656, 0, 64649, 0, 0, 0, 0, 0, - 983967, 100662, 100661, 100664, 66334, 100666, 70280, 832, 100667, 2240, - 78473, 66007, 78471, 65703, 0, 0, 0, 12357, 0, 41395, 0, 0, 0, 0, 0, 0, - 983463, 0, 41114, 65466, 0, 983844, 6024, 0, 9979, 0, 0, 0, 0, 0, 0, 0, - 4285, 0, 0, 4230, 0, 7367, 0, 92353, 7563, 42376, 0, 128532, 0, 0, 0, 0, - 67500, 0, 78466, 0, 12208, 128138, 0, 66311, 71309, 0, 41130, 78286, 0, - 0, 70047, 0, 6022, 0, 0, 0, 0, 0, 41125, 0, 66453, 0, 41107, 0, 41121, - 5300, 129588, 0, 0, 0, 74801, 70855, 2074, 73456, 0, 0, 12453, 0, 0, 0, - 0, 68159, 12457, 0, 0, 66278, 0, 0, 0, 0, 0, 66637, 12455, 0, 128473, 0, - 12449, 0, 71224, 0, 0, 66908, 0, 10165, 0, 119249, 113715, 0, 128223, 0, - 0, 0, 0, 4993, 0, 6168, 74033, 4995, 0, 69459, 77756, 4639, 0, 72223, 0, - 0, 0, 0, 0, 0, 66991, 0, 0, 0, 0, 0, 0, 83310, 0, 0, 0, 0, 0, 0, 0, 0, - 129594, 4953, 0, 0, 0, 0, 83311, 0, 73453, 65688, 0, 10125, 3517, 0, 0, - 0, 65094, 74791, 78262, 10627, 66333, 78256, 78257, 83304, 78253, 0, - 71317, 64923, 0, 65208, 10608, 78263, 78264, 0, 0, 0, 65883, 0, 0, 74914, - 0, 0, 6853, 0, 0, 12912, 119012, 0, 128191, 0, 0, 129586, 0, 1290, 0, 0, - 0, 0, 113719, 71442, 0, 0, 8978, 0, 119135, 120979, 10527, 71079, 0, 0, - 0, 0, 0, 0, 5336, 0, 0, 6934, 0, 10780, 0, 0, 78767, 0, 0, 0, 347, 0, 0, - 78775, 64675, 41582, 78774, 78771, 68094, 74903, 78769, 69221, 69657, 0, - 0, 11153, 120981, 78526, 0, 0, 0, 0, 41584, 0, 69464, 0, 0, 0, 0, 43510, + 983918, 122974, 0, 3467, 41010, 0, 3331, 946, 0, 1495, 13184, 74330, + 128242, 9562, 0, 123175, 0, 70036, 122976, 0, 0, 123176, 0, 0, 0, 5666, + 65227, 123174, 68419, 0, 11796, 123178, 0, 0, 10186, 123172, 7732, + 983755, 0, 0, 0, 5668, 83334, 0, 74645, 5670, 0, 0, 12741, 126619, + 123638, 5667, 19952, 120807, 113766, 12749, 0, 67757, 2263, 0, 0, 119260, + 129131, 9286, 83335, 128457, 83336, 70359, 0, 3571, 13247, 5874, 78279, + 73447, 68435, 78278, 78267, 78268, 0, 78265, 553, 113768, 0, 93053, 5829, + 0, 4587, 78285, 78299, 129699, 12746, 0, 70338, 0, 5633, 0, 94101, 94102, + 94099, 94100, 94105, 74856, 94103, 12742, 0, 983837, 0, 0, 0, 70330, 0, + 983830, 0, 0, 0, 12148, 0, 0, 0, 0, 0, 64938, 67234, 5634, 0, 0, 2146, 0, + 118880, 2425, 65182, 983832, 43636, 0, 83326, 328, 0, 68736, 0, 5636, + 123163, 5329, 0, 5638, 0, 7940, 0, 43223, 43760, 5635, 3373, 72424, + 78292, 74223, 73441, 68763, 78287, 9833, 0, 74208, 41635, 0, 77775, + 43040, 78297, 68778, 78295, 5639, 65603, 5660, 5640, 78303, 0, 78300, 0, + 68301, 0, 0, 78312, 0, 78310, 41625, 78308, 78309, 100731, 41780, 5642, + 100732, 100735, 100734, 4356, 100736, 100739, 12051, 70166, 100740, 5641, + 8259, 0, 0, 0, 119570, 0, 0, 121264, 983558, 0, 0, 0, 73890, 0, 0, 2800, + 11220, 5645, 64964, 8652, 83323, 0, 0, 121356, 5608, 128281, 119932, + 118562, 0, 0, 9000, 0, 83324, 92673, 129176, 0, 5613, 74267, 100721, + 100724, 5610, 100726, 92965, 100728, 5612, 100730, 10787, 0, 3615, + 123647, 5609, 78316, 78317, 78313, 78315, 5875, 5808, 0, 8186, 0, 74269, + 122977, 70004, 65874, 72422, 5807, 0, 66320, 5306, 12936, 0, 92970, + 127961, 0, 92583, 10211, 0, 0, 78871, 121063, 0, 129512, 0, 0, 0, 0, 0, + 74237, 0, 9133, 74262, 0, 92840, 0, 64779, 4672, 73529, 6185, 64776, 0, + 121266, 6499, 0, 0, 0, 92720, 0, 67494, 93791, 2534, 0, 93768, 93778, + 93762, 71849, 71869, 93781, 64583, 93761, 93780, 78922, 93787, 92443, + 128714, 71848, 93774, 66411, 93785, 71841, 93770, 93769, 0, 0, 0, 121168, + 68443, 69774, 931, 0, 125052, 6363, 2748, 0, 0, 0, 983603, 44011, 0, 0, + 100711, 119009, 100713, 100712, 100715, 65896, 100717, 78298, 100719, + 100718, 128836, 100720, 11649, 0, 0, 0, 0, 0, 42341, 65284, 0, 0, 12884, + 0, 7907, 127255, 0, 0, 0, 0, 68779, 0, 68786, 0, 100691, 0, 100693, + 100692, 42851, 100694, 100697, 100696, 92276, 78226, 66393, 100700, 0, + 93773, 93776, 93777, 100702, 78301, 100704, 100703, 42415, 78307, 4542, + 69909, 94022, 100709, 0, 0, 0, 0, 42454, 11565, 7949, 124939, 0, 0, + 42494, 3073, 0, 0, 42302, 0, 126553, 70810, 0, 72401, 0, 0, 0, 129319, + 4877, 100681, 100684, 100683, 10548, 100685, 100688, 100687, 100690, + 64798, 70805, 5346, 0, 126570, 124135, 4874, 124136, 0, 0, 0, 0, 65884, + 0, 0, 0, 11378, 0, 42785, 0, 3251, 11203, 0, 0, 0, 69568, 11052, 0, 5342, + 8317, 0, 0, 5340, 0, 122970, 128599, 0, 129538, 0, 128395, 0, 128510, 0, + 0, 9142, 0, 0, 0, 10938, 0, 0, 1182, 127381, 4829, 0, 0, 72438, 529, 0, + 0, 0, 10586, 10790, 10839, 121427, 41593, 100669, 0, 118532, 41594, 225, + 66418, 0, 0, 983969, 11376, 0, 41596, 0, 64975, 0, 0, 11084, 3194, 0, + 78306, 78305, 0, 0, 0, 11324, 0, 0, 8420, 127756, 128844, 0, 41338, + 129683, 11485, 0, 41322, 66605, 100671, 0, 100673, 100672, 100675, 5161, + 41330, 100676, 100679, 100678, 100659, 100658, 0, 100660, 0, 100485, + 12361, 0, 12359, 983559, 41369, 66412, 12191, 0, 0, 0, 0, 78221, 41376, + 0, 9870, 0, 41385, 65824, 100651, 11938, 100653, 100652, 100655, 100654, + 42678, 100656, 0, 64649, 0, 0, 0, 0, 0, 983967, 100662, 100661, 100664, + 66334, 100666, 70280, 832, 100667, 2240, 78473, 66007, 78471, 65703, 0, + 0, 0, 12357, 0, 41395, 0, 0, 0, 0, 0, 0, 983466, 0, 41114, 65466, 0, + 983844, 6024, 0, 9979, 0, 0, 0, 0, 0, 0, 0, 4285, 0, 0, 4230, 0, 7367, 0, + 92353, 7563, 42376, 0, 128532, 0, 0, 0, 0, 67500, 0, 78466, 0, 12208, + 128138, 0, 66311, 71309, 0, 41130, 78286, 0, 0, 70047, 0, 6022, 0, 0, 0, + 0, 0, 41125, 0, 66453, 0, 41107, 0, 41121, 5300, 129588, 0, 0, 128759, + 74801, 70855, 2074, 73456, 0, 0, 12453, 0, 0, 0, 0, 68159, 12457, 0, 0, + 66278, 0, 0, 0, 0, 0, 66637, 12455, 0, 128473, 0, 12449, 0, 71224, 0, 0, + 66908, 0, 10165, 0, 119249, 113715, 0, 128223, 0, 0, 0, 0, 4993, 0, 6168, + 74033, 4995, 0, 69459, 77756, 4639, 0, 72223, 0, 73478, 0, 0, 0, 73486, + 66991, 0, 0, 0, 0, 0, 0, 83310, 0, 0, 0, 0, 0, 0, 0, 0, 129594, 4953, 0, + 0, 0, 0, 83311, 0, 73453, 65688, 0, 10125, 3517, 0, 0, 0, 65094, 74791, + 78262, 10627, 66333, 78256, 78257, 83304, 78253, 0, 71317, 64923, 0, + 65208, 10608, 78263, 78264, 0, 0, 0, 65883, 0, 0, 74914, 0, 0, 6853, 0, + 0, 12912, 119012, 0, 128191, 0, 0, 129586, 0, 1290, 0, 0, 0, 0, 113719, + 71442, 0, 0, 8978, 0, 119135, 120979, 10527, 71079, 0, 0, 0, 0, 0, 0, + 5336, 0, 0, 6934, 0, 10780, 0, 0, 78767, 0, 0, 0, 347, 0, 0, 78775, + 64675, 41582, 78774, 78771, 68094, 74903, 78769, 69221, 69657, 0, 0, + 11153, 120981, 78526, 0, 0, 0, 0, 41584, 0, 69464, 0, 0, 0, 0, 43510, 66661, 0, 66306, 78791, 66384, 0, 6609, 0, 0, 11319, 0, 66984, 0, 41730, 0, 0, 127920, 0, 65172, 41728, 41721, 0, 0, 0, 41203, 0, 0, 41726, 0, 0, - 5758, 0, 0, 41140, 2028, 78092, 0, 0, 0, 92739, 983195, 41138, 0, 0, 0, + 5758, 0, 0, 41140, 2028, 78092, 0, 0, 0, 92739, 983196, 41138, 0, 0, 0, 125082, 1115, 127060, 9794, 127062, 67671, 92238, 12237, 78787, 66314, 78785, 9290, 73668, 78783, 78780, 66985, 127144, 7926, 0, 0, 0, 64398, 100924, 71274, 12311, 101268, 78796, 78798, 78794, 78795, 78792, 78793, @@ -28760,113 +28954,114 @@ static const unsigned int code_hash[] = { 66511, 68066, 2637, 110685, 8460, 110683, 8476, 110681, 0, 110679, 0, 127919, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5412, 66243, 9935, 122892, 0, 73864, 41734, 8206, 74081, 0, 3286, 120730, 0, 0, 41732, 0, 41736, - 983201, 41731, 0, 0, 70842, 0, 0, 0, 0, 129329, 0, 66853, 0, 0, 78742, + 983203, 41731, 0, 0, 70842, 0, 0, 0, 0, 129329, 0, 66853, 0, 0, 78742, 72755, 11277, 65892, 0, 10620, 92272, 68165, 0, 0, 0, 73942, 67001, 100479, 0, 119093, 3459, 0, 129398, 0, 0, 72130, 92512, 0, 66377, 69781, 128718, 0, 111304, 3161, 69981, 0, 0, 0, 0, 0, 9016, 78153, 0, 0, 43641, 0, 121018, 0, 101279, 0, 0, 0, 0, 0, 68342, 120950, 94043, 0, 12332, 121310, 6086, 41722, 0, 120709, 0, 0, 111305, 118677, 0, 128307, 74288, - 0, 74546, 0, 129178, 129399, 92224, 42460, 0, 0, 0, 0, 120941, 42421, 0, - 41723, 110606, 64358, 11460, 983508, 0, 64718, 120838, 66869, 0, 42348, - 0, 6752, 452, 42500, 0, 128258, 0, 42308, 0, 0, 0, 12932, 0, 69968, - 42950, 66827, 917582, 0, 0, 8302, 0, 66929, 0, 0, 7250, 13214, 10041, - 8105, 65568, 127780, 69969, 127759, 0, 0, 121467, 0, 121466, 41384, 0, - 69878, 0, 5538, 9987, 111298, 118932, 129307, 0, 552, 0, 7357, 10785, - 66995, 0, 4557, 0, 0, 10171, 68320, 0, 5540, 0, 0, 281, 0, 0, 42622, 0, - 5536, 0, 0, 1388, 0, 0, 10504, 0, 0, 11531, 74324, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 3663, 0, 121081, 70335, 74859, 0, 5334, 0, 110738, 72319, 0, - 11305, 66997, 68456, 0, 66611, 0, 19907, 64363, 3478, 7583, 7679, 74154, - 0, 0, 1158, 0, 983890, 73748, 0, 0, 1915, 4846, 0, 120132, 118984, - 120134, 120129, 120128, 805, 120130, 64438, 120124, 8760, 120126, 72137, - 120120, 120123, 94003, 0, 0, 0, 0, 0, 12225, 0, 0, 0, 70173, 75045, 0, - 129515, 8083, 0, 0, 0, 111094, 92626, 0, 0, 0, 0, 0, 0, 110837, 0, 67699, - 560, 5643, 0, 0, 0, 0, 0, 0, 0, 120144, 0, 120661, 78304, 1597, 120143, - 120142, 206, 70126, 120139, 120138, 8168, 0, 73086, 0, 0, 0, 118650, - 125036, 0, 0, 3546, 42573, 66811, 67000, 0, 128397, 8400, 0, 0, 0, 0, 0, - 7903, 9287, 72791, 0, 0, 0, 0, 72134, 66603, 1695, 917861, 0, 0, 111101, - 0, 0, 0, 0, 0, 0, 0, 111099, 0, 111098, 4754, 0, 69222, 128229, 0, 0, - 7354, 7408, 0, 0, 121181, 0, 0, 0, 12739, 0, 1278, 4187, 0, 42119, 42120, - 0, 121158, 0, 12467, 0, 68902, 0, 12463, 0, 0, 118827, 0, 9664, 70834, - 74475, 0, 0, 0, 0, 0, 3661, 0, 0, 9022, 127955, 0, 101460, 126257, 0, - 6118, 222, 126250, 3884, 0, 74151, 0, 6502, 0, 11085, 121261, 0, 0, 0, 0, - 0, 0, 0, 0, 12461, 0, 0, 0, 94059, 11254, 10860, 64880, 0, 64685, 0, 0, - 94087, 7776, 11219, 0, 0, 121339, 69730, 801, 43165, 0, 78212, 0, 0, - 13277, 0, 12951, 0, 9906, 5486, 2334, 128672, 67680, 5483, 73732, 120884, - 119128, 2256, 0, 127876, 2539, 0, 78507, 5485, 69826, 42697, 0, 0, - 113689, 4502, 68057, 253, 73672, 0, 0, 9203, 0, 0, 0, 0, 0, 121242, - 11127, 0, 0, 0, 13257, 0, 0, 0, 69645, 0, 0, 0, 70431, 0, 5693, 64470, 0, - 66610, 67678, 0, 983678, 0, 0, 0, 0, 0, 0, 0, 94078, 0, 0, 66608, 3111, - 0, 8804, 66607, 0, 0, 0, 66606, 0, 0, 0, 1436, 0, 55226, 0, 111287, 7393, - 41592, 0, 0, 1598, 78101, 0, 0, 65193, 4423, 0, 113692, 10515, 41589, 0, - 0, 0, 101485, 1430, 101486, 0, 120606, 0, 66223, 7619, 3255, 128280, - 74032, 11549, 10735, 93038, 100741, 6801, 100743, 100746, 2148, 100748, - 100747, 100750, 100749, 0, 121229, 101479, 69243, 41724, 67716, 69669, - 41690, 111269, 983666, 8380, 100355, 983849, 0, 101480, 0, 0, 0, 0, 6333, - 111264, 42315, 0, 129502, 111265, 0, 0, 5339, 74323, 0, 13004, 0, 0, 0, - 0, 0, 0, 5684, 0, 0, 0, 5689, 0, 0, 68464, 12633, 12870, 0, 65183, 5688, - 0, 0, 6310, 5686, 0, 0, 0, 120647, 70046, 50, 94095, 9871, 0, 0, 121446, - 0, 0, 0, 66905, 0, 4448, 0, 121406, 113734, 72125, 1321, 0, 10640, 0, 0, - 101497, 0, 0, 118532, 0, 0, 0, 0, 0, 12501, 0, 0, 0, 0, 8812, 0, 69986, - 8673, 0, 129024, 0, 0, 2105, 72101, 72712, 0, 129929, 0, 0, 0, 4636, - 55262, 77745, 4515, 2382, 0, 0, 7313, 101477, 0, 0, 194626, 0, 0, 0, 0, - 0, 0, 0, 10197, 194719, 0, 0, 0, 194718, 0, 0, 0, 64189, 0, 1873, 0, 0, - 0, 0, 0, 983682, 0, 0, 101499, 72282, 126991, 71113, 0, 0, 129340, 9489, - 0, 70843, 0, 0, 0, 0, 128030, 13295, 43191, 0, 0, 1154, 0, 1205, 0, 0, 0, - 12958, 0, 0, 0, 66968, 0, 10592, 0, 495, 0, 41712, 7983, 0, 0, 0, 6347, - 69465, 7654, 41710, 4196, 0, 0, 41709, 73772, 70832, 0, 9465, 983783, 0, - 0, 917612, 0, 72374, 41714, 0, 0, 0, 6343, 72376, 0, 43996, 0, 8044, - 66979, 0, 41789, 0, 10809, 71953, 0, 0, 0, 8146, 11025, 0, 120513, 642, - 0, 0, 0, 12875, 0, 0, 13229, 71950, 41788, 0, 92835, 0, 41791, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 8428, 6569, 92851, 0, 0, 0, 10167, 0, 68248, 8049, - 0, 0, 0, 0, 128882, 4761, 0, 4766, 64623, 0, 121180, 194653, 118876, 0, - 6912, 9232, 7033, 0, 0, 41545, 0, 71970, 72160, 72107, 0, 0, 0, 3484, 0, - 0, 0, 8503, 41539, 41527, 0, 0, 983842, 0, 0, 66983, 41537, 0, 41541, - 8282, 11817, 129965, 128219, 0, 0, 126132, 0, 0, 70115, 66609, 111235, - 65921, 0, 0, 194664, 0, 129326, 77970, 42246, 75030, 120605, 0, 65926, - 7744, 68859, 94056, 74277, 126108, 0, 6966, 194633, 8136, 0, 0, 0, 0, 0, - 4762, 0, 0, 0, 4765, 69443, 983585, 66970, 4760, 0, 0, 10871, 43199, - 194645, 0, 93955, 0, 0, 11546, 0, 337, 0, 0, 0, 12279, 7768, 0, 128352, - 0, 69812, 10143, 7883, 121444, 7880, 64618, 13012, 5704, 13010, 0, 0, - 119531, 0, 0, 0, 0, 66654, 0, 0, 0, 13008, 0, 4385, 0, 13011, 0, 92569, - 66972, 13009, 74771, 70159, 0, 0, 41793, 64450, 74221, 120996, 41792, - 111242, 94054, 126094, 0, 111244, 5709, 120689, 71076, 0, 0, 0, 0, 0, - 5708, 0, 0, 0, 5706, 66362, 5705, 8791, 41797, 0, 10237, 66436, 0, 66974, - 0, 0, 128083, 13170, 0, 127075, 0, 0, 41377, 0, 0, 10058, 120735, 101431, - 0, 0, 0, 0, 0, 0, 129641, 119525, 0, 0, 72350, 0, 983584, 2144, 0, - 120765, 0, 0, 1754, 92226, 13246, 864, 0, 118926, 8972, 0, 7849, 0, 0, - 13240, 0, 5192, 0, 0, 10948, 0, 13199, 0, 1236, 13208, 13261, 13189, - 13188, 93993, 0, 7440, 66976, 0, 0, 1844, 125229, 0, 13178, 0, 0, 0, - 125230, 0, 0, 13260, 4550, 121249, 125227, 0, 71071, 0, 0, 68523, 0, 0, - 11354, 94071, 0, 42795, 129317, 0, 0, 0, 125237, 0, 13194, 13274, 0, 0, - 129533, 65586, 68311, 0, 119193, 4601, 194661, 101454, 194658, 0, 194659, - 0, 121422, 128790, 194657, 41717, 67402, 101444, 121129, 41716, 127376, - 7910, 0, 0, 754, 41944, 0, 8183, 120741, 2037, 101440, 0, 101441, 125, 0, - 0, 0, 983124, 101442, 41719, 0, 7990, 12637, 13258, 9536, 71056, 0, 4427, - 0, 71200, 0, 12217, 0, 41532, 129315, 0, 0, 0, 0, 111063, 83349, 0, 0, - 120622, 0, 0, 0, 0, 43632, 0, 0, 8140, 0, 6260, 0, 0, 66765, 129657, 0, - 3898, 0, 0, 13200, 0, 0, 66582, 0, 0, 0, 0, 1068, 71178, 13259, 12945, 0, - 42203, 0, 3124, 69411, 0, 4386, 12224, 6973, 129563, 0, 0, 119535, 0, - 121312, 0, 12232, 0, 0, 5681, 64578, 75023, 72016, 13209, 0, 0, 0, 0, 0, - 11053, 0, 74902, 128107, 128942, 7588, 0, 1693, 74942, 43204, 65831, 0, - 0, 0, 68803, 111216, 111223, 0, 0, 65685, 9523, 2243, 0, 0, 0, 0, 0, 0, - 0, 0, 13191, 0, 3500, 3139, 100643, 3170, 100645, 100644, 66934, 100646, - 13006, 64433, 0, 100650, 941, 0, 0, 120967, 3727, 0, 0, 0, 72378, 0, 0, - 118611, 94039, 129299, 92455, 0, 0, 64444, 0, 0, 43603, 94075, 65397, - 288, 0, 0, 0, 10025, 73692, 0, 0, 68182, 0, 0, 0, 92438, 65395, 0, 0, 0, - 65393, 83078, 121111, 0, 0, 0, 0, 0, 65394, 11548, 72305, 0, 65396, 0, 0, - 13256, 1282, 0, 0, 0, 111085, 0, 0, 0, 111087, 72115, 0, 0, 0, 0, 0, - 3304, 0, 0, 0, 126595, 72437, 68353, 0, 0, 42113, 0, 0, 0, 0, 0, 43094, - 0, 0, 94037, 68317, 9035, 0, 0, 0, 0, 0, 70822, 128467, 164, 68309, - 94067, 94000, 100631, 100634, 100633, 100636, 100635, 100638, 100637, - 68808, 100639, 110665, 73893, 11099, 110664, 13175, 13207, 0, 127552, 0, - 74643, 5929, 0, 0, 129192, 983654, 11306, 0, 119059, 3180, 125102, 0, 0, - 0, 13062, 0, 129551, 128707, 0, 0, 74428, 0, 128000, 0, 11251, 70204, 0, - 10045, 0, 13275, 0, 11057, 0, 13276, 125133, 41525, 983084, 128015, - 11444, 0, 129158, 0, 122642, 41523, 127765, 0, 0, 0, 0, 0, 0, 0, 3858, 0, - 119573, 0, 0, 0, 0, 0, 0, 101014, 369, 74908, 41784, 0, 120994, 0, 71180, - 0, 0, 13210, 41782, 0, 0, 101388, 41781, 10486, 74058, 43002, 0, 0, 0, 0, + 0, 74546, 124123, 129178, 124125, 92224, 42460, 0, 0, 0, 0, 120941, + 42421, 0, 41723, 110606, 64358, 11460, 983511, 0, 64718, 120838, 66869, + 0, 42348, 0, 6752, 452, 42500, 0, 128258, 0, 42308, 0, 0, 0, 12932, 0, + 69968, 42950, 66827, 917582, 0, 0, 8302, 0, 66929, 0, 0, 7250, 13214, + 10041, 8105, 65568, 127780, 69969, 127759, 0, 0, 121467, 0, 121466, + 41384, 0, 69878, 0, 5538, 9987, 111298, 118932, 129307, 0, 552, 0, 7357, + 10785, 66995, 0, 4557, 0, 0, 10171, 68320, 0, 5540, 0, 0, 281, 0, 0, + 42622, 0, 5536, 0, 0, 1388, 0, 0, 10504, 0, 0, 11531, 74324, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 3663, 0, 121081, 70335, 74859, 0, 5334, 0, 110738, + 72319, 0, 11305, 66997, 68456, 0, 66611, 0, 19907, 64363, 3478, 7583, + 7679, 74154, 0, 0, 1158, 0, 983890, 73748, 0, 0, 1915, 4846, 0, 120132, + 118984, 120134, 120129, 120128, 805, 120130, 64438, 120124, 8760, 120126, + 72137, 120120, 120123, 94003, 0, 0, 0, 0, 0, 12225, 0, 0, 0, 70173, + 75045, 0, 129515, 8083, 0, 0, 0, 111094, 92626, 0, 0, 0, 0, 0, 0, 110837, + 0, 67699, 560, 5643, 0, 0, 0, 0, 0, 0, 0, 120144, 0, 120661, 78304, 1597, + 120143, 120142, 206, 70126, 120139, 120138, 8168, 0, 73086, 0, 0, 0, + 118650, 125036, 0, 0, 3546, 42573, 66811, 67000, 0, 128397, 8400, 0, 0, + 0, 0, 0, 7903, 9287, 72791, 0, 0, 0, 0, 72134, 66603, 1695, 917861, + 124150, 0, 111101, 0, 0, 0, 0, 0, 0, 0, 111099, 0, 111098, 4754, 0, + 69222, 128229, 0, 0, 7354, 7408, 0, 0, 121181, 0, 0, 0, 12739, 0, 1278, + 4187, 0, 42119, 42120, 0, 121158, 0, 12467, 0, 68902, 0, 12463, 0, 0, + 118827, 0, 9664, 70834, 74475, 0, 0, 0, 0, 0, 3661, 0, 0, 9022, 127955, + 0, 101460, 126257, 0, 6118, 222, 126250, 3884, 0, 74151, 0, 6502, 0, + 11085, 121261, 0, 0, 0, 0, 0, 0, 0, 0, 12461, 0, 0, 0, 94059, 11254, + 10860, 64880, 0, 64685, 0, 0, 94087, 7776, 11219, 0, 0, 121339, 69730, + 801, 43165, 0, 78212, 0, 0, 13277, 0, 12951, 0, 9906, 5486, 2334, 128672, + 67680, 5483, 73732, 120884, 119128, 2256, 0, 127876, 2539, 0, 78507, + 5485, 69826, 42697, 0, 0, 113689, 4502, 68057, 253, 73672, 0, 0, 9203, 0, + 0, 0, 0, 0, 121242, 11127, 0, 0, 0, 13257, 0, 0, 0, 69645, 0, 0, 0, + 70431, 0, 5693, 64470, 0, 66610, 67678, 0, 983678, 0, 0, 0, 0, 0, 0, 0, + 94078, 0, 0, 66608, 3111, 0, 8804, 66607, 0, 0, 0, 66606, 0, 0, 0, 1436, + 0, 55226, 0, 111287, 7393, 41592, 0, 0, 1598, 78101, 0, 0, 65193, 4423, + 0, 113692, 10515, 41589, 0, 0, 0, 101485, 1430, 101486, 0, 120606, 0, + 66223, 7619, 3255, 128280, 74032, 11549, 10735, 93038, 100741, 6801, + 100743, 100746, 2148, 100748, 100747, 100750, 100749, 0, 121229, 101479, + 69243, 41724, 67716, 69669, 41690, 111269, 983666, 8380, 100355, 983849, + 0, 101480, 0, 0, 0, 0, 6333, 111264, 42315, 0, 129502, 111265, 0, 0, + 5339, 74323, 0, 13004, 0, 0, 0, 0, 0, 0, 5684, 0, 0, 0, 5689, 0, 0, + 68464, 12633, 12870, 0, 65183, 5688, 0, 0, 6310, 5686, 0, 0, 0, 120647, + 70046, 50, 94095, 9871, 0, 0, 121446, 0, 0, 0, 66905, 0, 4448, 0, 121406, + 113734, 72125, 1321, 0, 10640, 0, 0, 101497, 0, 0, 73542, 0, 0, 0, 0, 0, + 12501, 0, 0, 0, 0, 8812, 0, 69986, 8673, 0, 129024, 0, 0, 2105, 72101, + 72712, 0, 129929, 0, 0, 0, 4636, 55262, 77745, 4515, 2382, 0, 0, 7313, + 101477, 0, 0, 194626, 0, 0, 0, 0, 0, 0, 0, 10197, 194719, 0, 0, 0, + 194718, 0, 0, 0, 64189, 0, 1873, 0, 0, 0, 0, 0, 983682, 0, 0, 101499, + 72282, 126991, 71113, 0, 0, 129340, 9489, 0, 70843, 0, 0, 0, 0, 128030, + 13295, 43191, 0, 0, 1154, 0, 1205, 0, 0, 0, 12958, 0, 0, 0, 66968, 0, + 10592, 0, 495, 0, 41712, 7983, 0, 0, 0, 6347, 69465, 7654, 41710, 4196, + 0, 0, 41709, 73772, 70832, 0, 9465, 983783, 0, 0, 917612, 0, 72374, + 41714, 0, 0, 0, 6343, 72376, 0, 43996, 0, 8044, 66979, 0, 41789, 0, + 10809, 71953, 0, 0, 0, 8146, 11025, 0, 120513, 642, 0, 0, 0, 12875, 0, 0, + 13229, 71950, 41788, 0, 92835, 0, 41791, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 8428, 6569, 92851, 0, 0, 0, 10167, 0, 68248, 8049, 0, 0, 0, 0, 128882, + 4761, 0, 4766, 64623, 0, 121180, 194653, 118876, 0, 6912, 9232, 7033, 0, + 0, 41545, 0, 71970, 72160, 72107, 0, 0, 0, 3484, 0, 0, 0, 8503, 41539, + 41527, 0, 0, 983842, 0, 0, 66983, 41537, 0, 41541, 8282, 11817, 129965, + 128219, 0, 0, 126132, 0, 0, 70115, 66609, 111235, 65921, 0, 0, 194664, 0, + 129326, 77970, 42246, 75030, 120605, 0, 65926, 7744, 68859, 94056, 74277, + 126108, 0, 6966, 194633, 8136, 0, 0, 0, 0, 0, 4762, 0, 0, 0, 4765, 69443, + 983585, 66970, 4760, 0, 0, 10871, 43199, 194645, 0, 93955, 0, 0, 11546, + 0, 337, 0, 0, 0, 12279, 7768, 0, 128352, 0, 69812, 10143, 7883, 121444, + 7880, 64618, 13012, 5704, 13010, 0, 0, 119531, 0, 0, 0, 0, 66654, 0, 0, + 0, 13008, 0, 4385, 0, 13011, 0, 92569, 66972, 13009, 74771, 70159, 0, 0, + 41793, 64450, 74221, 120996, 41792, 111242, 94054, 126094, 0, 111244, + 5709, 120689, 71076, 0, 0, 0, 0, 0, 5708, 0, 0, 0, 5706, 66362, 5705, + 8791, 41797, 0, 10237, 66436, 0, 66974, 0, 0, 128083, 13170, 0, 127075, + 0, 0, 41377, 0, 0, 10058, 120735, 101431, 0, 0, 0, 0, 0, 0, 129641, + 119525, 0, 0, 72350, 0, 983584, 2144, 0, 120765, 0, 0, 1754, 92226, + 13246, 864, 0, 118926, 8972, 0, 7849, 0, 0, 13240, 0, 5192, 0, 0, 10948, + 0, 13199, 0, 1236, 13208, 13261, 13189, 13188, 93993, 0, 7440, 66976, 0, + 0, 1844, 125229, 0, 13178, 0, 0, 0, 125230, 0, 0, 13260, 4550, 121249, + 125227, 0, 71071, 0, 0, 68523, 0, 0, 11354, 94071, 0, 42795, 129317, 0, + 0, 0, 125237, 0, 13194, 13274, 0, 0, 129533, 65586, 68311, 0, 119193, + 4601, 194661, 101454, 194658, 0, 194659, 0, 121422, 128790, 194657, + 41717, 67402, 101444, 121129, 41716, 127376, 7910, 0, 0, 754, 41944, 0, + 8183, 120741, 2037, 101440, 0, 101441, 125, 0, 0, 0, 983125, 101442, + 41719, 0, 7990, 12637, 13258, 9536, 71056, 0, 4427, 0, 71200, 0, 12217, + 0, 41532, 129315, 0, 0, 0, 0, 111063, 83349, 0, 0, 120622, 0, 0, 0, 0, + 43632, 0, 0, 8140, 0, 6260, 0, 0, 66765, 129657, 0, 3898, 0, 0, 13200, 0, + 0, 66582, 0, 0, 0, 0, 1068, 71178, 13259, 12945, 0, 42203, 0, 3124, + 69411, 0, 4386, 12224, 6973, 129563, 0, 0, 119535, 0, 121312, 0, 12232, + 0, 0, 5681, 64578, 75023, 72016, 13209, 0, 0, 0, 0, 0, 11053, 0, 74902, + 128107, 128942, 7588, 0, 1693, 74942, 43204, 65831, 124120, 0, 0, 68803, + 111216, 111223, 0, 0, 65685, 9523, 2243, 0, 0, 0, 0, 0, 0, 0, 0, 13191, + 0, 3500, 3139, 100643, 3170, 100645, 100644, 66934, 100646, 13006, 64433, + 0, 100650, 941, 0, 0, 120967, 3727, 0, 0, 0, 72378, 0, 0, 118611, 94039, + 129299, 92455, 0, 0, 64444, 0, 0, 43603, 94075, 65397, 288, 0, 0, 0, + 10025, 73692, 0, 0, 68182, 0, 0, 0, 92438, 65395, 0, 0, 0, 65393, 83078, + 121111, 0, 122666, 0, 0, 0, 65394, 11548, 72305, 0, 65396, 0, 0, 13256, + 1282, 0, 0, 0, 111085, 0, 0, 0, 111087, 72115, 0, 0, 0, 0, 0, 3304, 0, 0, + 0, 126595, 72437, 68353, 0, 0, 42113, 0, 0, 0, 0, 0, 43094, 0, 0, 94037, + 68317, 9035, 0, 0, 0, 0, 0, 70822, 128467, 164, 68309, 94067, 94000, + 100631, 100634, 100633, 100636, 100635, 100638, 100637, 68808, 100639, + 110665, 73893, 11099, 110664, 13175, 13207, 0, 127552, 0, 74643, 5929, 0, + 0, 119502, 983654, 11306, 0, 119059, 3180, 125102, 0, 0, 0, 13062, 0, + 129551, 128707, 0, 0, 74428, 0, 128000, 0, 11251, 70204, 0, 10045, 0, + 13275, 0, 11057, 0, 13276, 125133, 41525, 983084, 128015, 11444, 0, + 129158, 0, 122642, 41523, 127765, 0, 0, 0, 0, 0, 0, 0, 3858, 0, 119573, + 0, 0, 0, 0, 0, 0, 101014, 369, 74908, 41784, 0, 120994, 0, 71180, 0, 0, + 13210, 41782, 0, 73536, 101388, 41781, 10486, 74058, 43002, 0, 0, 0, 0, 0, 3741, 0, 0, 0, 118540, 41222, 0, 128317, 3982, 0, 4388, 126105, 746, - 0, 0, 0, 13131, 0, 0, 0, 0, 0, 10434, 8794, 0, 0, 0, 0, 0, 0, 11700, + 0, 0, 0, 13131, 0, 0, 0, 0, 0, 10434, 8794, 122963, 0, 0, 0, 0, 0, 11700, 4374, 129413, 0, 0, 0, 0, 0, 917597, 0, 69814, 0, 6735, 73979, 13174, 73968, 13225, 0, 69808, 0, 0, 2365, 7841, 71476, 0, 120934, 66510, 128099, 0, 0, 0, 41785, 41171, 0, 13173, 4372, 6854, 0, 0, 0, 128939, 0, @@ -28878,78 +29073,79 @@ static const unsigned int code_hash[] = { 124949, 0, 0, 0, 41533, 66337, 0, 92184, 0, 126091, 0, 0, 73849, 0, 43638, 0, 101398, 6261, 0, 129568, 0, 1957, 0, 0, 0, 13292, 13206, 0, 0, 2925, 73809, 42576, 101395, 13212, 43238, 0, 13190, 13187, 0, 13198, 0, - 0, 5242, 0, 0, 128146, 0, 0, 6770, 43331, 127539, 0, 0, 71074, 126466, 0, - 41444, 0, 0, 64799, 5246, 119106, 13185, 9709, 0, 0, 92751, 0, 5238, 0, - 71085, 0, 5236, 40979, 0, 74201, 8286, 0, 3936, 92833, 11699, 0, 127249, - 13235, 69578, 41248, 127264, 13245, 13239, 0, 7969, 127266, 74832, - 127251, 0, 120509, 0, 983893, 734, 127270, 0, 127254, 70297, 127273, - 64921, 120969, 66631, 41771, 120490, 0, 983171, 41770, 1670, 42560, 0, - 121349, 129634, 0, 41163, 0, 11136, 0, 11506, 0, 42841, 13267, 126109, 0, - 41775, 0, 7130, 41773, 0, 0, 0, 0, 0, 0, 0, 42673, 65572, 0, 65250, - 13265, 13264, 64518, 66798, 6100, 0, 0, 6740, 71080, 67814, 12967, 70028, - 68101, 4583, 0, 0, 68097, 0, 0, 0, 0, 119211, 0, 0, 42653, 83181, 68102, - 0, 7814, 71045, 0, 73702, 0, 0, 0, 9756, 6985, 0, 0, 74219, 0, 0, 129069, - 124987, 5674, 0, 66421, 0, 5677, 5588, 0, 0, 0, 0, 5673, 0, 5676, 0, - 94048, 0, 5672, 6476, 0, 0, 110951, 42511, 1727, 0, 0, 0, 0, 0, 0, 0, - 3550, 736, 0, 4505, 5873, 74090, 5826, 55232, 5813, 0, 120712, 5841, - 5837, 55234, 0, 3105, 64370, 5838, 5796, 0, 119592, 5793, 0, 5866, 5797, - 41011, 5865, 0, 0, 71899, 0, 71235, 5806, 0, 0, 9037, 5671, 0, 0, 0, 0, - 71266, 126616, 7296, 0, 0, 0, 0, 6980, 0, 72108, 0, 0, 0, 0, 0, 64613, - 983910, 0, 129969, 0, 78277, 7114, 0, 72100, 43190, 93842, 128666, 72096, - 42611, 42563, 0, 125080, 0, 6792, 43201, 72098, 0, 128719, 0, 72106, 0, - 0, 5644, 0, 66627, 69727, 0, 0, 0, 65116, 0, 0, 0, 0, 66410, 94104, - 41013, 0, 0, 0, 2869, 0, 41015, 0, 2785, 120616, 0, 73907, 194689, 0, 0, - 0, 194688, 4759, 0, 0, 43192, 129913, 1170, 43365, 69810, 73908, 0, 902, - 0, 0, 0, 0, 8122, 66420, 129642, 0, 3861, 0, 11028, 0, 73820, 5714, 0, 0, - 0, 807, 127001, 78474, 0, 976, 113782, 0, 0, 0, 0, 0, 128657, 118801, - 71043, 0, 127017, 0, 0, 5582, 0, 0, 5798, 0, 0, 0, 128521, 0, 0, 68058, - 120553, 983183, 0, 0, 74933, 74283, 0, 0, 194698, 66044, 0, 0, 0, 0, 0, - 10094, 0, 0, 10857, 69225, 0, 0, 93, 0, 10954, 0, 0, 0, 8171, 0, 0, - 82996, 0, 0, 0, 119001, 92634, 0, 0, 5187, 120711, 71086, 118704, 0, 0, - 0, 5232, 0, 41009, 0, 41005, 0, 43205, 0, 0, 0, 194708, 0, 71054, 10028, - 66478, 7076, 13182, 100385, 0, 0, 0, 78782, 7972, 78786, 0, 0, 0, 78789, - 11309, 3806, 71252, 0, 0, 0, 78819, 0, 125218, 0, 127532, 0, 0, 0, 78817, - 0, 64366, 65156, 8814, 0, 0, 0, 0, 12836, 42725, 120079, 0, 0, 0, 0, - 69258, 13255, 0, 0, 7464, 0, 93831, 0, 0, 0, 0, 13213, 118557, 0, 64516, - 0, 0, 0, 41007, 983929, 0, 40995, 12209, 983933, 119136, 123635, 0, 0, 0, - 0, 0, 69283, 43558, 5522, 0, 71061, 0, 74105, 3633, 983931, 119364, - 41234, 41231, 0, 9771, 983936, 13251, 0, 0, 6262, 2784, 0, 71078, 8126, - 66483, 0, 0, 441, 0, 0, 0, 41002, 40999, 0, 129394, 7108, 0, 10890, 0, - 74445, 8324, 0, 0, 74817, 2813, 119056, 74853, 983690, 0, 0, 0, 1193, - 10462, 65197, 13253, 13252, 7829, 120992, 130032, 0, 0, 0, 77911, 0, - 77907, 0, 10386, 0, 41042, 0, 65944, 65683, 10338, 66469, 0, 0, 0, 0, 0, - 41966, 0, 0, 0, 68915, 0, 0, 911, 983889, 128932, 40963, 0, 65159, 0, 0, - 0, 5520, 0, 0, 0, 0, 0, 0, 0, 42965, 0, 0, 0, 0, 0, 983892, 0, 0, 66839, - 0, 0, 0, 68647, 0, 5857, 68135, 92727, 119120, 983694, 13171, 0, 0, 0, - 120338, 0, 0, 0, 13250, 69663, 0, 92201, 66397, 0, 0, 0, 8761, 12942, - 5748, 92713, 92414, 0, 83174, 8796, 0, 0, 0, 43633, 0, 72805, 71073, 0, - 0, 0, 0, 0, 12843, 4520, 0, 0, 73004, 983691, 0, 0, 194935, 110754, - 64345, 0, 983677, 3457, 0, 0, 0, 110750, 110758, 110751, 0, 0, 10427, 0, - 73859, 0, 9755, 1110, 65239, 0, 0, 0, 0, 0, 0, 0, 194936, 0, 983821, 0, - 70437, 3620, 0, 0, 72855, 0, 0, 0, 74250, 0, 0, 11980, 0, 66482, 67823, - 0, 128345, 110768, 0, 0, 0, 0, 12891, 983786, 983667, 0, 2016, 0, 65668, - 92311, 67696, 10366, 70117, 9155, 120652, 9786, 65082, 0, 8579, 0, 0, 0, - 0, 4508, 64883, 0, 92522, 129847, 0, 64592, 74276, 67688, 0, 69270, 0, + 0, 5242, 0, 0, 128146, 0, 73535, 6770, 43331, 127539, 0, 0, 71074, + 126466, 73524, 41444, 0, 0, 64799, 5246, 119106, 13185, 9709, 0, 0, + 92751, 0, 5238, 0, 71085, 0, 5236, 40979, 0, 74201, 8286, 0, 3936, 92833, + 11699, 0, 127249, 13235, 69578, 41248, 127264, 13245, 13239, 0, 7969, + 127266, 74832, 127251, 0, 120509, 0, 983893, 734, 127270, 0, 127254, + 70297, 127273, 64921, 120969, 66631, 41771, 120490, 0, 983172, 41770, + 1670, 42560, 0, 121349, 129634, 0, 41163, 0, 11136, 0, 11506, 0, 42841, + 13267, 126109, 0, 41775, 0, 7130, 41773, 0, 0, 0, 0, 0, 0, 0, 42673, + 65572, 0, 65250, 13265, 13264, 64518, 66798, 6100, 0, 0, 6740, 71080, + 67814, 12967, 70028, 68101, 4583, 0, 0, 68097, 0, 0, 0, 0, 119211, 0, 0, + 42653, 83181, 68102, 0, 7814, 71045, 0, 73702, 0, 0, 0, 9756, 6985, 0, 0, + 74219, 0, 0, 129069, 124987, 5674, 0, 66421, 0, 5677, 5588, 0, 0, 0, 0, + 5673, 73488, 5676, 0, 94048, 0, 5672, 6476, 0, 128798, 110951, 42511, + 1727, 0, 0, 0, 0, 0, 0, 0, 3550, 736, 0, 4505, 5873, 74090, 5826, 55232, + 5813, 0, 120712, 5841, 5837, 55234, 0, 3105, 64370, 5838, 5796, 0, + 119592, 5793, 0, 5866, 5797, 41011, 5865, 0, 0, 71899, 0, 71235, 5806, + 73528, 0, 9037, 5671, 0, 0, 0, 0, 71266, 126616, 7296, 0, 0, 0, 0, 6980, + 0, 72108, 0, 0, 0, 0, 0, 64613, 983910, 0, 129969, 0, 78277, 7114, 0, + 72100, 43190, 93842, 128666, 72096, 42611, 42563, 0, 125080, 0, 6792, + 43201, 72098, 0, 128719, 0, 72106, 73534, 0, 5644, 0, 66627, 69727, 0, 0, + 0, 65116, 0, 0, 73526, 0, 66410, 94104, 41013, 0, 0, 0, 2869, 0, 41015, + 0, 2785, 120616, 0, 73907, 194689, 0, 0, 0, 194688, 4759, 0, 0, 43192, + 129913, 1170, 43365, 69810, 73908, 0, 902, 0, 0, 0, 0, 8122, 66420, + 129642, 0, 3861, 0, 11028, 0, 73820, 5714, 0, 0, 0, 807, 127001, 78474, + 0, 976, 113782, 0, 0, 0, 0, 0, 128657, 118801, 71043, 0, 127017, 0, 0, + 5582, 0, 0, 5798, 0, 0, 0, 128521, 0, 0, 68058, 120553, 983184, 0, 0, + 74933, 74283, 0, 0, 194698, 66044, 0, 0, 0, 0, 0, 10094, 0, 0, 10857, + 69225, 0, 0, 93, 0, 10954, 0, 0, 0, 8171, 0, 0, 82996, 0, 0, 0, 73527, + 92634, 0, 0, 5187, 120711, 71086, 118704, 0, 0, 0, 5232, 0, 41009, 0, + 41005, 0, 43205, 0, 0, 0, 194708, 0, 71054, 10028, 66478, 7076, 13182, + 100385, 0, 0, 0, 78782, 7972, 78786, 0, 0, 0, 78789, 11309, 3806, 71252, + 0, 0, 0, 78819, 0, 125218, 0, 127532, 0, 0, 0, 78817, 0, 64366, 65156, + 8814, 0, 0, 0, 0, 12836, 42725, 120079, 0, 0, 0, 0, 69258, 13255, 0, 0, + 7464, 0, 93831, 0, 0, 0, 0, 13213, 118557, 0, 64516, 0, 0, 0, 41007, + 983929, 0, 40995, 12209, 983933, 119136, 123635, 0, 0, 0, 0, 0, 69283, + 43558, 5522, 0, 71061, 0, 74105, 3633, 983931, 119364, 41234, 41231, 0, + 9771, 983936, 13251, 0, 0, 6262, 2784, 0, 71078, 8126, 66483, 0, 0, 441, + 0, 0, 0, 41002, 40999, 0, 129394, 7108, 0, 10890, 0, 74445, 8324, 0, 0, + 74817, 2813, 119056, 74853, 983690, 0, 0, 0, 1193, 10462, 65197, 13253, + 13252, 7829, 120992, 130032, 0, 0, 0, 77911, 0, 77907, 0, 10386, 0, + 41042, 0, 65944, 65683, 10338, 66469, 0, 0, 0, 0, 0, 41966, 0, 0, 0, + 68915, 0, 0, 911, 983889, 128932, 40963, 0, 65159, 0, 122950, 0, 5520, 0, + 0, 0, 0, 0, 0, 0, 42965, 0, 0, 0, 0, 0, 983892, 0, 0, 66839, 0, 0, 0, + 68647, 0, 5857, 68135, 92727, 119120, 983694, 13171, 0, 0, 0, 120338, 0, + 0, 0, 13250, 69663, 0, 92201, 66397, 0, 0, 0, 8761, 12942, 5748, 92713, + 92414, 0, 83174, 8796, 0, 0, 0, 43633, 0, 72805, 71073, 0, 0, 0, 0, 0, + 12843, 4520, 0, 0, 73004, 983691, 0, 0, 194935, 110754, 64345, 0, 983677, + 3457, 0, 0, 0, 110750, 110758, 110751, 0, 0, 10427, 0, 73859, 0, 9755, + 1110, 65239, 0, 0, 0, 0, 0, 0, 0, 194936, 0, 983821, 0, 70437, 3620, 0, + 0, 72855, 0, 0, 0, 74250, 0, 0, 11980, 0, 66482, 67823, 0, 128345, + 110768, 0, 0, 0, 0, 12891, 983786, 983667, 0, 2016, 0, 65668, 92311, + 67696, 10366, 70117, 9155, 120652, 9786, 65082, 0, 8579, 0, 0, 0, 0, + 4508, 64883, 0, 92522, 129847, 0, 64592, 74276, 67688, 0, 69270, 0, 69456, 0, 113821, 0, 12147, 9024, 66378, 66472, 0, 0, 0, 0, 0, 71935, 0, 0, 113697, 0, 0, 69285, 0, 74275, 0, 122896, 127941, 41214, 0, 67476, 0, 0, 0, 7773, 0, 0, 9963, 68649, 0, 73734, 0, 0, 0, 0, 6594, 983771, 0, 0, 3624, 70342, 0, 64655, 121481, 0, 0, 0, 0, 0, 65932, 0, 983809, 6803, 120968, 7738, 0, 0, 120628, 129721, 66614, 122921, 0, 43810, 7029, 0, 41292, 118898, 0, 43115, 9517, 11518, 0, 0, 0, 0, 64423, 0, 0, 0, 12503, - 9591, 4516, 0, 118845, 0, 0, 129479, 43650, 983192, 69250, 0, 0, 68079, + 9591, 4516, 0, 118845, 0, 0, 129479, 43650, 983193, 69250, 0, 0, 68079, 0, 11397, 2884, 0, 0, 12678, 0, 0, 41014, 73730, 917539, 4270, 92254, - 127836, 68205, 6633, 118947, 0, 5230, 101055, 0, 0, 983231, 121392, 0, + 127836, 68205, 6633, 118947, 0, 5230, 101055, 0, 0, 983234, 121392, 0, 92985, 0, 0, 0, 0, 415, 0, 0, 0, 0, 5183, 1877, 0, 0, 0, 0, 0, 4472, 0, 0, 0, 128285, 110682, 78230, 4756, 0, 7081, 0, 0, 0, 78606, 0, 42922, 42103, 8628, 74861, 0, 0, 0, 43059, 10539, 0, 0, 0, 0, 0, 0, 0, 0, 64873, - 11992, 129444, 0, 0, 11801, 3622, 0, 0, 983213, 0, 0, 11521, 0, 1966, + 11992, 129444, 0, 0, 11801, 3622, 0, 0, 983215, 0, 0, 11521, 0, 1966, 43628, 111048, 0, 0, 0, 0, 0, 0, 42098, 66671, 10694, 128520, 0, 0, 0, 0, 42100, 0, 111040, 0, 42097, 0, 0, 0, 0, 11302, 118640, 129145, 43395, 83259, 0, 0, 92351, 0, 0, 11299, 1561, 0, 92359, 92725, 69253, 0, 194733, - 0, 0, 0, 127893, 11280, 0, 0, 983802, 0, 0, 72760, 0, 12486, 65018, + 0, 194730, 0, 127893, 11280, 0, 0, 983802, 0, 0, 72760, 0, 12486, 65018, 66516, 5409, 0, 0, 194720, 5399, 9685, 0, 983713, 5401, 0, 0, 66832, 0, 0, 5405, 0, 0, 0, 0, 0, 2235, 0, 11330, 983711, 64690, 3254, 0, 129974, - 0, 0, 43678, 0, 0, 983145, 0, 6388, 3355, 0, 9867, 0, 55258, 5611, 0, + 0, 0, 43678, 0, 0, 983146, 0, 6388, 3355, 0, 9867, 0, 55258, 5611, 0, 128527, 0, 0, 129181, 0, 78228, 0, 0, 119119, 0, 0, 194959, 0, 0, 1379, 246, 0, 0, 64736, 0, 0, 0, 121227, 0, 0, 0, 0, 0, 0, 11855, 0, 0, 0, 71961, 10656, 0, 65214, 119242, 0, 0, 13163, 0, 120831, 0, 0, 101484, 0, @@ -28965,11 +29161,11 @@ static const unsigned int code_hash[] = { 119207, 0, 0, 9550, 100621, 0, 100623, 100622, 78050, 100624, 65753, 100626, 65756, 72731, 0, 100630, 0, 0, 0, 0, 9657, 9019, 121154, 0, 0, 5390, 0, 0, 194965, 72144, 69937, 69286, 6328, 0, 0, 0, 0, 0, 983047, 0, - 5235, 803, 69289, 0, 0, 127979, 43838, 0, 119562, 43544, 0, 0, 0, 0, 0, - 70426, 9107, 5191, 119113, 0, 0, 0, 121099, 0, 0, 0, 0, 0, 128150, - 983067, 0, 7289, 74055, 0, 0, 0, 0, 0, 0, 0, 1784, 124947, 0, 0, 0, 0, - 64868, 0, 13158, 0, 7211, 0, 9371, 129378, 0, 0, 1625, 7664, 0, 0, 0, 0, - 0, 0, 69273, 0, 0, 0, 0, 4482, 118886, 0, 0, 0, 0, 0, 0, 0, 100612, + 5235, 803, 69289, 0, 0, 127979, 43838, 0, 119562, 43544, 0, 0, 0, 0, + 194960, 70426, 9107, 5191, 119113, 0, 0, 0, 121099, 0, 0, 0, 0, 0, + 128150, 983067, 0, 7289, 74055, 0, 0, 0, 0, 0, 0, 0, 1784, 124947, 0, 0, + 0, 0, 64868, 0, 13158, 0, 7211, 0, 9371, 129378, 0, 0, 1625, 7664, 0, 0, + 0, 0, 0, 0, 69273, 0, 0, 0, 0, 4482, 118886, 0, 0, 0, 0, 0, 0, 0, 100612, 66849, 100614, 100613, 100616, 444, 100618, 100617, 100620, 100619, 0, 129401, 0, 11349, 40991, 0, 0, 129324, 0, 0, 1197, 0, 40993, 0, 0, 0, 40990, 43765, 0, 3492, 0, 127942, 0, 0, 100592, 100591, 100594, 19948, @@ -28979,13 +29175,13 @@ static const unsigned int code_hash[] = { 0, 130037, 0, 118820, 0, 0, 0, 0, 0, 100581, 0, 100583, 100582, 100585, 100584, 100587, 100586, 100589, 7576, 11995, 100590, 43260, 0, 0, 64830, 0, 125046, 101526, 0, 43979, 8870, 0, 0, 42357, 0, 0, 12822, 0, 0, 0, - 118944, 0, 0, 42637, 0, 0, 70725, 0, 129934, 0, 71344, 0, 0, 0, 194745, - 7170, 9596, 8277, 194743, 43629, 110610, 0, 0, 983571, 123545, 0, 66699, - 42952, 0, 0, 0, 43234, 66008, 12627, 0, 0, 0, 43619, 43303, 11300, 0, 0, - 8745, 0, 7558, 71342, 100570, 0, 0, 127881, 3461, 121258, 129471, 69264, - 0, 0, 0, 73877, 74335, 124982, 0, 0, 0, 64620, 74762, 12069, 10838, - 92548, 43616, 0, 10061, 0, 64840, 10508, 209, 0, 43193, 120581, 0, 0, - 128049, 0, 10899, 69855, 100571, 100574, 100573, 100576, 993, 100578, + 118944, 0, 0, 42637, 0, 0, 70725, 0, 129934, 0, 71344, 0, 0, 72449, + 194745, 7170, 9596, 8277, 194743, 43629, 110610, 0, 0, 983571, 123545, 0, + 66699, 42952, 0, 0, 0, 43234, 66008, 12627, 0, 0, 0, 43619, 43303, 11300, + 0, 0, 8745, 0, 7558, 71342, 100570, 0, 0, 127881, 3461, 121258, 129471, + 69264, 0, 0, 0, 73877, 74335, 124982, 0, 0, 0, 64620, 74762, 12069, + 10838, 92548, 43616, 0, 10061, 0, 64840, 10508, 209, 0, 43193, 120581, 0, + 0, 128049, 0, 10899, 69855, 100571, 100574, 100573, 100576, 993, 100578, 100577, 100580, 100579, 100560, 100559, 7232, 0, 0, 0, 0, 0, 0, 10489, 42166, 0, 128588, 0, 0, 4224, 7671, 41518, 121311, 0, 0, 0, 0, 64820, 92538, 12966, 100554, 100553, 100556, 100555, 100558, 100557, 4263, 8793, @@ -28994,25 +29190,25 @@ static const unsigned int code_hash[] = { 0, 2147, 0, 0, 66629, 0, 0, 1255, 4149, 0, 0, 66633, 0, 129391, 92352, 0, 65101, 0, 0, 0, 0, 5835, 128797, 66625, 10842, 0, 42123, 0, 0, 66634, 1094, 66636, 0, 0, 0, 0, 0, 9972, 73865, 129289, 6114, 0, 0, 0, 0, 93960, - 0, 0, 0, 0, 12070, 0, 881, 7857, 0, 65164, 0, 0, 118703, 0, 0, 64404, - 64321, 0, 125187, 0, 0, 11245, 129395, 69506, 71859, 0, 0, 0, 1287, - 121509, 0, 0, 0, 125264, 74152, 120504, 64545, 0, 69668, 8985, 0, 0, 0, - 0, 0, 0, 3652, 0, 0, 0, 0, 0, 279, 0, 0, 0, 0, 1489, 125189, 0, 0, 3899, - 0, 42124, 43828, 42122, 0, 0, 0, 11985, 73755, 78600, 0, 0, 10988, 0, 0, - 42138, 78610, 0, 65768, 78608, 78604, 78605, 6285, 78603, 78612, 78613, - 74339, 65767, 8685, 0, 0, 0, 78622, 78623, 68475, 11470, 64538, 78618, - 78615, 78616, 0, 0, 0, 101534, 2527, 0, 128209, 2799, 0, 0, 0, 9933, 0, - 0, 767, 5524, 7028, 0, 101520, 0, 0, 0, 78633, 67481, 0, 94011, 0, 6971, - 0, 70731, 0, 0, 118979, 126075, 2434, 94018, 0, 120579, 0, 4631, 0, 0, - 6407, 0, 19931, 0, 0, 124905, 0, 3192, 0, 8414, 0, 0, 0, 124902, 0, 9164, - 66612, 93959, 8228, 124897, 0, 0, 0, 78624, 0, 0, 9993, 0, 0, 129350, - 78631, 78632, 78629, 78630, 78627, 78628, 78625, 2399, 0, 92399, 71202, - 41208, 0, 0, 8178, 2149, 3367, 0, 78640, 78641, 78636, 78638, 78634, - 6337, 0, 92342, 0, 0, 11068, 0, 9331, 0, 74798, 9181, 0, 0, 8017, 0, 0, - 0, 0, 0, 0, 0, 12126, 129184, 129306, 0, 0, 69650, 0, 0, 0, 43436, + 0, 0, 0, 0, 12070, 0, 881, 7857, 0, 65164, 0, 0, 118703, 124151, 0, + 64404, 64321, 0, 125187, 0, 0, 11245, 129395, 69506, 71859, 128886, 0, 0, + 1287, 121509, 0, 0, 0, 125264, 74152, 120504, 64545, 0, 69668, 8985, 0, + 0, 0, 0, 0, 0, 3652, 0, 0, 0, 0, 0, 279, 0, 0, 0, 0, 1489, 125189, 0, 0, + 3899, 0, 42124, 43828, 42122, 0, 0, 0, 11985, 73755, 78600, 0, 0, 10988, + 0, 0, 42138, 78610, 0, 65768, 78608, 78604, 78605, 6285, 78603, 78612, + 78613, 74339, 65767, 8685, 0, 0, 0, 78622, 78623, 68475, 11470, 64538, + 78618, 78615, 78616, 0, 0, 0, 101534, 2527, 0, 128209, 2799, 0, 0, 0, + 9933, 0, 0, 767, 5524, 7028, 0, 101520, 0, 0, 0, 78633, 67481, 0, 94011, + 0, 6971, 0, 70731, 0, 0, 118979, 126075, 2434, 94018, 0, 120579, 0, 4631, + 0, 0, 6407, 0, 19931, 0, 0, 124905, 0, 3192, 0, 8414, 0, 0, 0, 124902, 0, + 9164, 66612, 93959, 8228, 124897, 0, 0, 0, 78624, 0, 0, 9993, 0, 0, + 129350, 78631, 78632, 78629, 78630, 78627, 78628, 78625, 2399, 0, 92399, + 71202, 41208, 0, 0, 8178, 2149, 3367, 0, 78640, 78641, 78636, 78638, + 78634, 6337, 0, 78909, 0, 0, 11068, 0, 9331, 0, 74798, 9181, 0, 0, 8017, + 0, 0, 0, 0, 0, 0, 0, 12126, 119494, 129306, 0, 0, 69650, 0, 0, 0, 43436, 983744, 0, 0, 0, 0, 66845, 69249, 0, 0, 5398, 0, 127386, 93953, 0, 0, 0, 0, 0, 9476, 68899, 0, 12763, 126603, 74788, 0, 42114, 11181, 92502, 0, 0, - 0, 3469, 42107, 42116, 0, 0, 0, 0, 9853, 69648, 9040, 101518, 64665, + 0, 3469, 42107, 42116, 0, 0, 119493, 0, 9853, 69648, 9040, 101518, 64665, 119557, 0, 0, 0, 69638, 12602, 983068, 3852, 0, 67872, 12231, 11317, 0, 119812, 0, 11410, 10964, 12274, 122890, 100524, 0, 119810, 9865, 195019, 0, 0, 0, 0, 12276, 0, 124919, 0, 0, 119613, 0, 111214, 10467, 0, 2443, @@ -29022,16 +29218,16 @@ static const unsigned int code_hash[] = { 120613, 67247, 1629, 124926, 796, 0, 0, 74123, 72334, 127587, 72336, 43388, 0, 43944, 72335, 478, 65151, 0, 128147, 0, 0, 0, 0, 0, 42933, 1206, 71209, 43837, 0, 3843, 12011, 0, 3361, 0, 8121, 10715, 7578, 0, 0, - 0, 10530, 12348, 8653, 0, 0, 0, 9551, 0, 0, 784, 0, 0, 0, 0, 0, 0, 43937, - 0, 0, 43938, 43935, 73765, 66230, 0, 0, 0, 43936, 0, 43932, 11102, 0, 0, - 42753, 67165, 0, 78324, 0, 0, 6975, 917928, 5415, 12176, 0, 0, 3462, - 43940, 42629, 78691, 128016, 43942, 0, 9759, 0, 0, 78320, 8114, 78321, - 78697, 78696, 78695, 8710, 118812, 118956, 0, 4051, 92657, 0, 71206, 0, - 0, 0, 128857, 0, 1619, 9703, 77986, 0, 42112, 0, 1875, 0, 42109, 0, 0, - 71189, 121160, 64907, 5396, 13144, 0, 0, 5575, 9675, 0, 5940, 226, 0, - 6336, 0, 0, 0, 5116, 64521, 0, 0, 0, 121390, 125048, 74138, 0, 74139, - 128447, 92249, 0, 0, 0, 0, 8935, 0, 0, 0, 0, 616, 78131, 65178, 4684, - 78701, 983899, 74631, 0, 0, 0, 74460, 42110, 0, 10870, 8557, 11054, + 0, 10530, 12348, 8653, 0, 73545, 0, 9551, 0, 0, 784, 0, 0, 0, 0, 0, 0, + 43937, 0, 0, 43938, 43935, 73765, 66230, 0, 0, 0, 43936, 0, 43932, 11102, + 0, 0, 42753, 67165, 0, 78324, 0, 0, 6975, 917928, 5415, 12176, 0, 0, + 3462, 43940, 42629, 78691, 128016, 43942, 0, 9759, 0, 0, 78320, 8114, + 78321, 78697, 78696, 78695, 8710, 118812, 118956, 0, 4051, 92657, 0, + 71206, 0, 0, 0, 128857, 0, 1619, 9703, 77986, 0, 42112, 0, 1875, 0, + 42109, 0, 0, 71189, 121160, 64907, 5396, 13144, 0, 0, 5575, 9675, 0, + 5940, 226, 0, 6336, 0, 0, 0, 5116, 64521, 0, 0, 0, 121390, 125048, 74138, + 0, 74139, 128447, 92249, 0, 0, 0, 0, 8935, 0, 0, 0, 0, 616, 78131, 65178, + 4684, 78701, 983899, 74631, 0, 0, 0, 74460, 42110, 0, 10870, 8557, 11054, 68664, 0, 0, 0, 122629, 0, 0, 0, 0, 65597, 0, 7651, 6846, 0, 0, 68868, 0, 0, 118966, 129302, 40997, 127218, 0, 0, 40998, 0, 74488, 71182, 9800, 0, 0, 0, 41000, 0, 5114, 55263, 3386, 70730, 42574, 0, 5115, 5394, 0, @@ -29041,55 +29237,55 @@ static const unsigned int code_hash[] = { 4514, 72149, 0, 0, 0, 65041, 10965, 120905, 0, 0, 12542, 0, 65341, 0, 65829, 0, 0, 10475, 0, 0, 0, 0, 11795, 0, 0, 2164, 127102, 127101, 74956, 7099, 11275, 67681, 127096, 0, 9336, 0, 42626, 43966, 7798, 64474, 64259, - 0, 5730, 119809, 43018, 983174, 93796, 0, 0, 0, 69401, 0, 0, 5127, 11285, + 0, 5730, 119809, 43018, 983175, 93796, 0, 0, 0, 69401, 0, 0, 5127, 11285, 0, 5495, 4273, 0, 74765, 10849, 6346, 5493, 6342, 68636, 74319, 5492, 0, 0, 169, 5497, 125053, 0, 0, 68198, 0, 0, 128417, 0, 0, 12738, 0, 983076, 5321, 0, 0, 0, 5323, 120732, 9773, 125209, 4683, 74318, 0, 68823, 0, 0, 0, 0, 129553, 0, 123562, 0, 0, 834, 0, 1803, 0, 5733, 0, 0, 71312, 5731, - 1381, 2891, 0, 0, 127212, 64525, 0, 2881, 92996, 93847, 9601, 2879, 0, 0, - 73129, 5729, 0, 0, 0, 64881, 127905, 9361, 0, 2887, 0, 3526, 6298, 0, - 121219, 0, 0, 0, 8572, 127863, 77896, 0, 71174, 0, 0, 71197, 0, 12096, 0, - 0, 0, 110745, 71176, 110746, 65279, 0, 121236, 5734, 0, 0, 0, 0, 0, + 1381, 2891, 128639, 0, 127212, 64525, 0, 2881, 92996, 93847, 9601, 2879, + 0, 0, 73129, 5729, 0, 0, 0, 64881, 127905, 9361, 0, 2887, 0, 3526, 6298, + 0, 121219, 0, 0, 0, 8572, 127863, 77896, 0, 71174, 0, 0, 71197, 0, 12096, + 0, 0, 0, 110745, 71176, 110746, 65279, 0, 121236, 5734, 0, 0, 0, 0, 0, 41641, 12717, 0, 12552, 983615, 66713, 0, 0, 41643, 110747, 0, 8713, 41640, 78657, 41645, 66712, 125196, 0, 66726, 66711, 0, 93994, 0, 3472, 64863, 0, 121424, 0, 0, 0, 125203, 67837, 0, 0, 0, 0, 0, 0, 121440, 0, 0, 129461, 119008, 92402, 65017, 0, 0, 66668, 0, 0, 0, 0, 0, 119822, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 121043, 66471, 12216, 0, 40988, 0, 0, 0, 0, 0, - 2396, 129078, 0, 0, 0, 64940, 0, 8321, 119823, 128165, 100409, 83299, - 996, 0, 0, 4249, 0, 83294, 92535, 8222, 0, 118875, 71213, 0, 0, 0, 0, - 8534, 72844, 40983, 0, 125195, 0, 12551, 73960, 125193, 74469, 12558, + 124148, 0, 0, 0, 0, 0, 0, 0, 0, 121043, 66471, 12216, 0, 40988, 0, 0, 0, + 0, 0, 2396, 129078, 0, 0, 0, 64940, 0, 8321, 119823, 128165, 100409, + 83299, 996, 0, 0, 4249, 0, 83294, 92535, 8222, 0, 118875, 71213, 0, 0, 0, + 0, 8534, 72844, 40983, 0, 125195, 0, 12551, 73960, 125193, 74469, 12558, 121039, 0, 10052, 40982, 129371, 0, 0, 0, 127403, 0, 917559, 0, 78364, 1563, 0, 0, 19911, 0, 0, 0, 71363, 0, 7797, 78708, 10006, 0, 3308, 119134, 74940, 0, 0, 78488, 0, 0, 0, 0, 0, 128462, 9200, 10046, 9612, 0, 8218, 66496, 0, 43742, 78489, 0, 0, 0, 0, 67826, 0, 70056, 508, 128585, 0, 126539, 0, 0, 0, 0, 0, 0, 0, 124950, 0, 194601, 0, 0, 0, 0, 6659, 0, 0, 0, 0, 0, 0, 41634, 0, 41639, 71169, 11941, 0, 0, 0, 42180, 68505, - 43753, 3249, 41637, 93982, 12328, 501, 93985, 10601, 0, 6503, 0, 92192, - 0, 71181, 0, 6505, 74010, 0, 13064, 126112, 121105, 6500, 5526, 0, + 43753, 3249, 41637, 93982, 12328, 501, 93985, 10601, 129783, 6503, 0, + 92192, 0, 71181, 0, 6505, 74010, 0, 13064, 126112, 121105, 6500, 5526, 0, 128949, 0, 0, 92376, 0, 9678, 120832, 0, 41706, 0, 0, 0, 8936, 92964, - 119123, 4208, 0, 0, 0, 67742, 0, 74379, 128605, 0, 0, 92422, 983109, 0, + 119123, 4208, 0, 0, 0, 67742, 0, 74379, 128605, 0, 0, 92422, 983110, 0, 66475, 0, 5027, 0, 0, 0, 5069, 0, 5028, 0, 0, 0, 5026, 0, 0, 6331, 0, 0, 0, 0, 41076, 0, 74790, 0, 0, 0, 0, 5029, 0, 5317, 3598, 0, 41070, 92166, 11185, 6663, 0, 6507, 0, 126079, 0, 1716, 983710, 0, 917824, 620, 41001, - 0, 917823, 43758, 0, 71116, 5024, 0, 41003, 0, 5025, 7297, 0, 75039, + 0, 917823, 43758, 0, 71116, 5024, 0, 41003, 0, 5025, 7297, 122988, 75039, 69745, 119328, 65557, 0, 0, 983599, 0, 0, 0, 0, 43947, 43946, 0, 0, - 128363, 6105, 0, 119325, 983227, 0, 68203, 43945, 66491, 43939, 0, 68144, + 128363, 6105, 0, 119325, 983230, 0, 68203, 43945, 66491, 43939, 0, 68144, 78718, 2301, 0, 0, 66490, 6979, 101561, 7721, 0, 0, 1592, 0, 0, 121096, - 41048, 129358, 829, 0, 92406, 0, 120247, 0, 41056, 0, 118665, 10953, + 41048, 129358, 829, 0, 92406, 0, 73541, 0, 41056, 0, 118665, 10953, 41066, 0, 917813, 482, 101554, 0, 0, 43606, 71185, 0, 917926, 0, 72262, 110863, 72421, 12050, 0, 5315, 917817, 0, 0, 42061, 917816, 0, 0, 68417, 917815, 0, 0, 42059, 0, 0, 120723, 42058, 3960, 11043, 11337, 121358, 0, 92824, 3958, 101568, 0, 917818, 0, 917819, 0, 0, 42064, 11959, 983714, 0, - 0, 0, 0, 128498, 64336, 10478, 92629, 70350, 118692, 0, 0, 42437, 1555, - 0, 8691, 129656, 2215, 41662, 119046, 0, 0, 0, 93952, 0, 66481, 41664, 0, + 0, 0, 0, 73511, 64336, 10478, 92629, 70350, 118692, 0, 0, 42437, 1555, 0, + 8691, 129656, 2215, 41662, 119046, 0, 0, 0, 93952, 0, 66481, 41664, 0, 42578, 0, 41661, 78715, 78714, 9356, 0, 129544, 0, 1286, 110701, 0, 0, - 983206, 128925, 42476, 0, 11156, 0, 0, 0, 101583, 72123, 0, 10020, 43359, - 72827, 0, 120946, 41627, 0, 11979, 0, 41628, 533, 11931, 65225, 0, + 983208, 128925, 42476, 0, 11156, 78895, 0, 0, 101583, 72123, 0, 10020, + 43359, 72827, 0, 120946, 41627, 0, 11979, 0, 41628, 533, 11931, 65225, 0, 125122, 129994, 0, 68118, 0, 4377, 0, 0, 8587, 72097, 13193, 64350, 68233, 0, 41924, 0, 7735, 0, 127585, 120843, 0, 65820, 0, 0, 43461, 7757, 0, 0, 43787, 66493, 77943, 4168, 43904, 73952, 0, 0, 121072, 4440, 43902, 77948, 66837, 77946, 43903, 77944, 77945, 0, 120909, 120826, 120226, - 66492, 43901, 64625, 0, 0, 0, 0, 10013, 64434, 0, 983112, 0, 11782, + 66492, 43901, 64625, 0, 0, 0, 0, 10013, 64434, 0, 983113, 0, 11782, 64382, 0, 0, 0, 0, 41630, 630, 120960, 0, 0, 70165, 1043, 93017, 0, 0, 0, 124945, 313, 129590, 0, 0, 65593, 7445, 43906, 5750, 42258, 0, 55222, 68222, 11268, 11225, 0, 8526, 0, 0, 43894, 66495, 69990, 0, 92990, 0, @@ -29116,8 +29312,8 @@ static const unsigned int code_hash[] = { 19940, 43668, 41667, 0, 0, 1923, 0, 0, 0, 0, 0, 0, 0, 0, 6464, 92750, 2996, 125221, 0, 68481, 41835, 4047, 41842, 0, 0, 129601, 0, 0, 0, 0, 293, 0, 0, 64791, 41827, 0, 0, 10579, 8560, 0, 0, 118835, 4803, 73805, - 1739, 0, 3900, 128967, 73737, 0, 0, 73957, 0, 66474, 41971, 0, 0, 0, 0, - 0, 11716, 66473, 0, 92647, 0, 128080, 0, 0, 0, 0, 0, 0, 0, 6632, 73861, + 1739, 0, 3900, 128967, 73737, 0, 72451, 73957, 0, 66474, 41971, 0, 0, 0, + 0, 0, 11716, 66473, 0, 92647, 0, 78920, 0, 0, 0, 0, 0, 0, 0, 6632, 73861, 0, 74770, 0, 0, 8914, 0, 0, 3183, 1435, 0, 0, 0, 0, 0, 0, 5746, 67392, 0, 0, 0, 83506, 0, 7082, 71481, 12618, 5059, 983597, 83524, 43604, 0, 0, 0, 0, 0, 0, 8227, 0, 1218, 0, 64416, 65848, 92884, 0, 0, 0, 126987, 0, 0, 0, @@ -29125,40 +29321,40 @@ static const unsigned int code_hash[] = { 65905, 0, 42662, 0, 121159, 0, 129536, 0, 7794, 0, 42953, 6377, 0, 126080, 3669, 3968, 0, 71319, 69658, 129550, 0, 66296, 118616, 0, 0, 0, 124998, 6699, 126120, 0, 0, 66678, 0, 0, 0, 8409, 119527, 19967, 0, 0, - 9502, 0, 0, 6115, 0, 41654, 0, 0, 0, 41655, 113779, 43975, 72427, 0, 0, - 0, 0, 41657, 10778, 0, 9533, 184, 1553, 128868, 69574, 0, 0, 0, 129420, - 0, 101589, 983576, 73697, 0, 92480, 0, 128938, 74292, 0, 5157, 4020, 0, - 128154, 43788, 64818, 0, 0, 0, 92979, 0, 0, 74377, 11029, 66651, 0, 0, - 125202, 0, 0, 7877, 121070, 101411, 0, 119828, 2810, 9955, 0, 0, 42817, - 0, 65122, 11715, 0, 0, 0, 71270, 0, 0, 0, 0, 0, 70199, 0, 0, 0, 0, 0, 0, - 127862, 0, 0, 0, 78222, 127981, 0, 0, 0, 0, 0, 11290, 0, 0, 0, 0, 8315, - 0, 0, 0, 74595, 0, 0, 0, 42531, 0, 0, 0, 74589, 43993, 0, 0, 0, 0, 43690, - 0, 119139, 42730, 0, 0, 0, 64926, 0, 0, 43830, 65257, 0, 42728, 0, - 128697, 123150, 0, 43540, 0, 0, 12725, 72993, 78635, 127826, 223, 0, - 69675, 0, 0, 0, 0, 0, 0, 42605, 0, 0, 0, 0, 0, 0, 0, 0, 78621, 0, 78619, - 119062, 0, 0, 0, 42676, 129353, 64800, 78617, 83504, 68126, 1213, 0, 0, - 797, 0, 0, 83021, 83005, 64387, 4115, 0, 0, 0, 129857, 10679, 83001, - 121091, 0, 64276, 83498, 13168, 83011, 0, 10136, 0, 0, 65088, 0, 4262, - 129866, 0, 0, 10701, 0, 3101, 0, 123204, 0, 0, 11373, 0, 0, 12731, 9117, - 0, 0, 4539, 0, 0, 12727, 0, 0, 0, 43684, 74567, 68877, 983726, 12724, - 73940, 0, 0, 0, 0, 0, 7947, 12003, 0, 74593, 121140, 69653, 74807, 42018, - 0, 0, 0, 65888, 0, 0, 69683, 0, 120306, 0, 0, 12595, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 69848, 68307, 0, 4405, 0, 128336, 129032, 69216, 0, 128011, - 118656, 0, 6817, 67400, 120314, 0, 0, 998, 0, 13105, 120313, 64327, 1558, - 0, 1991, 7882, 0, 0, 0, 530, 0, 0, 0, 12002, 0, 68422, 0, 10979, 0, - 41823, 70696, 0, 0, 7896, 0, 66676, 0, 120325, 0, 0, 129407, 94033, 0, - 6311, 110725, 41698, 0, 12049, 78133, 0, 125020, 41705, 0, 0, 121298, 0, - 66822, 0, 65389, 0, 66027, 0, 0, 41699, 8340, 0, 69776, 0, 128639, 0, - 1988, 5407, 69978, 0, 65912, 93059, 0, 2336, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 126238, 0, 19913, 0, 113733, 0, 0, 74279, 0, 10956, 0, 41674, 19964, - 41679, 65084, 41675, 195031, 0, 0, 0, 0, 983089, 0, 10794, 128961, 13217, - 0, 0, 0, 5280, 0, 0, 12905, 41610, 11532, 0, 0, 768, 120545, 442, 0, 0, - 0, 64081, 41682, 0, 41693, 0, 77993, 77994, 0, 4804, 6994, 983114, 0, 0, - 41696, 467, 983934, 0, 0, 0, 0, 8678, 0, 69682, 64801, 0, 0, 0, 2193, - 64093, 12043, 0, 69666, 0, 2029, 65191, 119246, 42847, 0, 0, 0, 0, 0, 0, - 0, 70339, 126116, 0, 0, 8019, 73856, 0, 0, 0, 118709, 2355, 12150, 65725, - 77988, 77989, 68033, 77987, 0, 77985, 0, 0, 68388, 0, 74171, 0, 0, 0, - 11301, 78013, 78008, 78010, 9874, 78007, 983328, 71064, 3050, 0, 0, 0, + 9502, 0, 0, 6115, 0, 41654, 0, 0, 0, 41655, 113779, 43975, 72427, 128080, + 0, 0, 0, 41657, 10778, 0, 9533, 184, 1553, 128868, 69574, 0, 0, 0, + 129420, 0, 101589, 983576, 73697, 0, 92480, 0, 128938, 74292, 0, 5157, + 4020, 0, 128154, 43788, 64818, 0, 0, 0, 92979, 0, 0, 74377, 11029, 66651, + 0, 0, 125202, 0, 0, 7877, 121070, 101411, 0, 119828, 2810, 9955, 0, + 69375, 42817, 0, 65122, 11715, 0, 0, 0, 71270, 0, 0, 0, 0, 0, 70199, 0, + 0, 0, 0, 0, 0, 127862, 0, 0, 0, 78222, 127981, 0, 0, 0, 0, 0, 11290, 0, + 0, 0, 0, 8315, 0, 0, 0, 74595, 0, 0, 0, 42531, 0, 0, 0, 74589, 43993, 0, + 0, 0, 0, 43690, 0, 119139, 42730, 0, 0, 0, 64926, 0, 0, 43830, 65257, 0, + 42728, 0, 128697, 123150, 0, 43540, 0, 0, 12725, 72993, 78635, 127826, + 223, 0, 69675, 0, 0, 0, 0, 0, 0, 42605, 0, 0, 0, 0, 0, 0, 0, 0, 78621, 0, + 78619, 119062, 0, 0, 0, 42676, 129353, 64800, 78617, 83504, 68126, 1213, + 0, 0, 797, 0, 0, 83021, 83005, 64387, 4115, 0, 0, 0, 129857, 10679, + 83001, 121091, 0, 64276, 83498, 13168, 83011, 0, 10136, 0, 0, 65088, 0, + 4262, 129866, 0, 0, 10701, 0, 3101, 0, 123204, 0, 0, 11373, 0, 0, 12731, + 9117, 0, 0, 4539, 0, 0, 12727, 0, 0, 0, 43684, 74567, 68877, 983726, + 12724, 73940, 0, 0, 0, 0, 0, 7947, 12003, 0, 74593, 121140, 69653, 74807, + 42018, 0, 0, 0, 65888, 0, 0, 69683, 0, 120306, 0, 0, 12595, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 69848, 68307, 0, 4405, 0, 128336, 129032, 69216, 0, + 128011, 118656, 0, 6817, 67400, 120314, 0, 0, 998, 0, 13105, 120313, + 64327, 1558, 0, 1991, 7882, 0, 0, 0, 530, 0, 0, 0, 12002, 0, 68422, 0, + 10979, 0, 41823, 70696, 0, 0, 7896, 0, 66676, 0, 120325, 0, 0, 129407, + 94033, 0, 6311, 110725, 41698, 0, 12049, 78133, 0, 125020, 41705, 0, 0, + 121298, 0, 66822, 0, 65389, 0, 66027, 0, 0, 41699, 8340, 0, 69776, 0, + 78921, 0, 1988, 5407, 69978, 0, 65912, 93059, 0, 2336, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 126238, 0, 19913, 0, 113733, 0, 0, 74279, 0, 10956, 0, 41674, + 19964, 41679, 65084, 41675, 195031, 0, 0, 0, 0, 983089, 0, 10794, 128961, + 13217, 0, 0, 0, 5280, 0, 0, 12905, 41610, 11532, 0, 0, 768, 120545, 442, + 0, 0, 0, 64081, 41682, 0, 41693, 0, 77993, 77994, 0, 4804, 6994, 983115, + 0, 0, 41696, 467, 983934, 0, 0, 0, 0, 8678, 0, 69682, 64801, 0, 0, 0, + 2193, 64093, 12043, 0, 69666, 0, 2029, 65191, 119246, 42847, 0, 0, 0, 0, + 0, 0, 0, 70339, 126116, 0, 0, 8019, 73856, 0, 0, 0, 118709, 2355, 12150, + 65725, 77988, 77989, 68033, 77987, 0, 77985, 0, 0, 68388, 0, 74171, 0, 0, + 0, 11301, 78013, 78008, 78010, 9874, 78007, 983331, 71064, 3050, 0, 0, 0, 78016, 78017, 71852, 78015, 0, 0, 0, 92242, 0, 69642, 0, 0, 43883, 0, 0, 0, 78025, 0, 78023, 78024, 11847, 10545, 0, 10887, 0, 123179, 0, 0, 0, 83352, 64942, 92363, 9996, 8508, 0, 0, 8195, 0, 42171, 0, 3722, 0, 63751, @@ -29170,59 +29366,60 @@ static const unsigned int code_hash[] = { 68495, 74131, 74130, 0, 0, 0, 611, 74129, 64871, 129958, 0, 0, 0, 74854, 0, 70466, 0, 0, 0, 121147, 0, 68487, 41669, 7094, 917921, 0, 123144, 74054, 0, 0, 0, 839, 0, 7695, 0, 0, 0, 92202, 0, 121053, 123157, 67885, - 0, 7206, 0, 6647, 43986, 0, 0, 0, 122646, 0, 0, 127936, 43748, 66746, 0, - 12298, 110802, 984011, 110800, 64924, 0, 73931, 9468, 74245, 0, 0, 74246, - 0, 0, 118830, 0, 71851, 1279, 0, 6224, 0, 92405, 128601, 129886, 128997, - 0, 0, 0, 5032, 0, 0, 0, 0, 0, 5034, 0, 0, 72846, 42702, 0, 0, 13294, 0, - 64869, 0, 67808, 9129, 123632, 0, 0, 120819, 68387, 120168, 120169, - 120170, 120171, 5518, 4174, 120166, 66932, 120160, 120161, 120162, 434, - 41437, 66212, 120158, 120159, 0, 0, 118867, 0, 524, 0, 74029, 0, 126559, - 0, 0, 0, 10355, 10419, 74025, 77847, 0, 69725, 0, 120656, 0, 67876, 0, 0, - 0, 74145, 74039, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5445, 0, 93779, 71855, - 7391, 8989, 0, 74068, 0, 0, 0, 0, 4962, 120409, 8855, 0, 70820, 0, 0, 0, - 0, 71847, 0, 120406, 0, 10451, 0, 67653, 120153, 12443, 120155, 9947, - 120149, 120150, 120151, 13128, 0, 120146, 120147, 0, 0, 0, 0, 0, 129715, - 74059, 74062, 6217, 74053, 43846, 0, 74049, 0, 0, 0, 0, 0, 0, 0, 0, - 42595, 0, 68112, 118860, 0, 0, 92497, 74949, 128953, 126245, 0, 0, 0, - 42997, 0, 119251, 0, 0, 0, 0, 0, 6216, 0, 0, 9455, 127027, 8124, 128851, - 0, 6944, 0, 0, 0, 2828, 128550, 531, 42638, 0, 0, 129888, 43428, 0, 3614, - 2827, 9696, 0, 0, 0, 4354, 0, 78562, 78561, 0, 118553, 0, 42599, 42597, - 0, 68829, 125012, 0, 127277, 0, 120421, 0, 983164, 0, 0, 10121, 120422, - 74950, 123142, 69715, 0, 0, 120423, 120630, 12608, 125244, 0, 74144, - 9700, 12580, 0, 128911, 0, 71864, 0, 74071, 0, 0, 12713, 0, 70402, 0, 0, - 0, 1734, 0, 0, 0, 0, 118951, 231, 0, 74167, 542, 0, 0, 0, 0, 128074, 0, - 121343, 0, 4446, 10584, 74235, 0, 4037, 0, 0, 0, 5687, 0, 0, 0, 0, 0, 0, - 78434, 92816, 0, 113709, 74284, 0, 0, 0, 126495, 0, 0, 0, 74482, 93978, - 1709, 69721, 9909, 92286, 0, 0, 0, 55229, 8667, 0, 0, 0, 0, 0, 0, 0, 0, - 127586, 1226, 6930, 0, 71736, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41500, 0, 311, - 74282, 6221, 92988, 0, 67682, 0, 120528, 122901, 74272, 0, 0, 0, 0, - 69667, 0, 124933, 74456, 74302, 42589, 0, 0, 0, 0, 64847, 0, 66987, 0, - 41508, 0, 323, 125211, 0, 42698, 8131, 0, 4625, 0, 4630, 0, 0, 0, 74316, - 78417, 2668, 92483, 0, 42640, 0, 2519, 0, 92474, 92479, 0, 983085, 5049, - 42659, 119011, 64705, 7754, 10854, 8738, 74623, 0, 0, 0, 649, 0, 0, 0, 0, - 0, 1013, 70707, 68212, 705, 0, 0, 127803, 1183, 126519, 9320, 0, 0, 8157, - 0, 0, 0, 0, 0, 0, 0, 11913, 0, 42848, 0, 64925, 0, 0, 70693, 0, 0, 2051, - 0, 0, 0, 66988, 0, 0, 0, 8466, 0, 4626, 8464, 8472, 68844, 4629, 8499, 0, - 0, 4624, 194623, 0, 94025, 0, 7805, 0, 94007, 6935, 0, 0, 0, 0, 0, 0, 0, - 8492, 0, 8459, 0, 8497, 8496, 0, 129864, 0, 0, 129834, 69553, 0, 0, - 65849, 0, 0, 0, 12451, 3328, 8684, 0, 6102, 0, 5298, 110881, 5294, 0, - 129615, 0, 0, 0, 0, 43617, 0, 0, 0, 0, 0, 77863, 128695, 0, 0, 0, 0, 0, - 5292, 0, 0, 42688, 5302, 3970, 0, 0, 1793, 0, 0, 0, 0, 0, 65263, 0, 0, 0, - 0, 0, 0, 13219, 9569, 69567, 74383, 0, 0, 72157, 0, 42949, 0, 0, 0, 5322, - 0, 0, 43631, 5324, 0, 128694, 41614, 65269, 6230, 0, 0, 0, 3360, 0, - 11523, 72726, 92488, 9926, 7197, 0, 68429, 126575, 41821, 1249, 0, - 127951, 0, 123641, 0, 0, 0, 74459, 41807, 0, 41815, 0, 0, 0, 119918, 0, - 128248, 0, 66835, 0, 0, 72145, 41800, 0, 0, 0, 41811, 74466, 93966, 6670, - 77882, 0, 0, 43092, 0, 0, 0, 0, 0, 128655, 0, 0, 0, 0, 74501, 74005, 0, - 74387, 69860, 315, 12813, 128556, 72409, 0, 72408, 0, 0, 73061, 0, 0, - 1378, 0, 0, 0, 72407, 3066, 0, 0, 72406, 0, 0, 0, 8787, 194615, 0, 41618, - 0, 0, 0, 194614, 64652, 194611, 42088, 125226, 0, 0, 0, 0, 7176, 43756, - 0, 122649, 74492, 0, 74534, 0, 0, 0, 127199, 0, 128630, 74525, 0, 194594, - 12930, 7168, 74514, 0, 74515, 0, 128919, 43962, 9527, 120659, 70123, - 12977, 69723, 0, 93783, 194598, 41236, 92235, 65168, 118838, 41237, 5848, - 0, 194600, 3670, 129905, 129906, 129907, 129908, 7890, 0, 11298, 0, 0, - 6229, 0, 0, 0, 194593, 128907, 0, 0, 194592, 4120, 65337, 65336, 0, 0, 0, - 0, 9366, 0, 0, 0, 65327, 65326, 65325, 65324, 65323, 42216, 65321, 65320, + 0, 7206, 0, 6647, 43986, 129743, 0, 0, 122646, 0, 0, 127936, 43748, + 66746, 0, 12298, 110802, 984011, 110800, 64924, 0, 73931, 9468, 74245, 0, + 0, 74246, 0, 0, 118830, 0, 71851, 1279, 0, 6224, 0, 92405, 128601, + 129886, 128997, 0, 0, 0, 5032, 0, 0, 0, 0, 0, 5034, 0, 0, 72846, 42702, + 0, 0, 13294, 0, 64869, 0, 67808, 9129, 123632, 0, 0, 120819, 68387, + 120168, 120169, 120170, 120171, 5518, 4174, 120166, 66932, 120160, + 120161, 120162, 434, 41437, 66212, 120158, 120159, 0, 0, 118867, 0, 524, + 0, 74029, 0, 126559, 0, 0, 0, 10355, 10419, 74025, 77847, 0, 69725, 0, + 120656, 0, 67876, 0, 0, 0, 74145, 74039, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 5445, 0, 93779, 71855, 7391, 8989, 0, 74068, 0, 0, 0, 0, 4962, 120409, + 8855, 0, 70820, 0, 0, 0, 0, 71847, 0, 120406, 0, 10451, 0, 67653, 120153, + 12443, 120155, 9947, 120149, 120150, 120151, 13128, 0, 120146, 120147, 0, + 0, 0, 0, 0, 129715, 74059, 74062, 6217, 74053, 43846, 0, 74049, 0, 0, 0, + 0, 0, 0, 0, 0, 42595, 0, 68112, 118860, 0, 0, 92497, 74949, 128953, + 126245, 0, 0, 0, 42997, 122984, 119251, 0, 0, 0, 0, 0, 6216, 0, 0, 9455, + 127027, 8124, 128851, 0, 6944, 0, 0, 0, 2828, 128550, 531, 42638, 0, 0, + 129888, 43428, 0, 3614, 2827, 9696, 0, 129711, 0, 4354, 0, 78562, 78561, + 0, 118553, 0, 42599, 42597, 0, 68829, 125012, 0, 127277, 0, 120421, 0, + 983165, 0, 0, 10121, 120422, 74950, 123142, 69715, 0, 0, 120423, 120630, + 12608, 125244, 0, 74144, 9700, 12580, 0, 128911, 0, 71864, 0, 74071, 0, + 0, 12713, 0, 70402, 0, 0, 0, 1734, 0, 0, 0, 119491, 118951, 231, 0, + 74167, 542, 0, 0, 0, 0, 128074, 0, 121343, 0, 4446, 10584, 74235, 0, + 4037, 0, 0, 0, 5687, 0, 0, 0, 0, 0, 0, 78434, 92816, 0, 113709, 74284, 0, + 0, 0, 126495, 0, 0, 0, 74482, 93978, 1709, 69721, 9909, 92286, 0, 0, 0, + 55229, 8667, 0, 0, 0, 0, 0, 0, 0, 0, 127586, 1226, 6930, 124146, 71736, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 41500, 0, 311, 74282, 6221, 92988, 0, 67682, + 0, 120528, 122901, 74272, 0, 0, 0, 0, 69667, 0, 124933, 74456, 74302, + 42589, 0, 0, 0, 0, 64847, 0, 66987, 0, 41508, 0, 323, 125211, 0, 42698, + 8131, 0, 4625, 0, 4630, 0, 0, 0, 74316, 78417, 2668, 92483, 0, 42640, 0, + 2519, 0, 92474, 92479, 0, 983085, 5049, 42659, 119011, 64705, 7754, + 10854, 8738, 74623, 0, 0, 0, 649, 0, 0, 73480, 0, 0, 1013, 70707, 68212, + 705, 0, 0, 127803, 1183, 126519, 9320, 0, 0, 8157, 0, 0, 0, 0, 0, 0, 0, + 11913, 0, 42848, 0, 64925, 0, 0, 70693, 0, 0, 2051, 0, 0, 0, 66988, 0, 0, + 0, 8466, 0, 4626, 8464, 8472, 68844, 4629, 8499, 0, 0, 4624, 194623, 0, + 94025, 0, 7805, 0, 94007, 6935, 0, 0, 0, 0, 0, 0, 0, 8492, 0, 8459, 0, + 8497, 8496, 0, 129864, 0, 0, 129834, 69553, 73476, 0, 65849, 0, 0, 0, + 12451, 3328, 8684, 0, 6102, 0, 5298, 110881, 5294, 0, 129615, 0, 0, 0, 0, + 43617, 0, 0, 0, 0, 0, 77863, 128695, 0, 0, 0, 0, 0, 5292, 0, 0, 42688, + 5302, 3970, 73516, 0, 1793, 0, 0, 0, 0, 0, 65263, 0, 0, 0, 0, 0, 0, + 13219, 9569, 69567, 74383, 0, 0, 72157, 0, 42949, 0, 0, 0, 5322, 0, 0, + 43631, 5324, 0, 128694, 41614, 65269, 6230, 0, 0, 0, 3360, 0, 11523, + 72726, 92488, 9926, 7197, 0, 68429, 126575, 41821, 1249, 0, 127951, 0, + 123641, 0, 0, 0, 74459, 41807, 0, 41815, 0, 0, 0, 119918, 0, 128248, 0, + 66835, 0, 0, 72145, 41800, 0, 0, 0, 41811, 74466, 93966, 6670, 77882, 0, + 0, 43092, 0, 0, 0, 0, 0, 128655, 0, 0, 0, 0, 74501, 74005, 0, 74387, + 69860, 315, 12813, 128556, 72409, 0, 72408, 0, 0, 73061, 0, 0, 1378, 0, + 0, 0, 72407, 3066, 0, 0, 72406, 0, 0, 0, 8787, 194615, 0, 41618, 0, 0, 0, + 194614, 64652, 194611, 42088, 125226, 0, 0, 0, 0, 7176, 43756, 0, 122649, + 74492, 0, 74534, 0, 0, 0, 127199, 0, 128630, 74525, 0, 194594, 12930, + 7168, 74514, 0, 74515, 0, 128919, 43962, 9527, 120659, 70123, 12977, + 69723, 0, 93783, 194598, 41236, 92235, 65168, 118838, 41237, 5848, 0, + 194600, 3670, 129905, 129906, 129907, 129908, 7890, 0, 11298, 0, 0, 6229, + 0, 0, 0, 194593, 128907, 0, 0, 194592, 4120, 65337, 65336, 0, 0, 0, 0, + 9366, 0, 0, 0, 65327, 65326, 65325, 65324, 65323, 42216, 65321, 65320, 65335, 65334, 65333, 65332, 65331, 65330, 65329, 42689, 0, 43943, 118885, 42073, 6785, 68491, 0, 42076, 7196, 65318, 2035, 65316, 4106, 65314, 65313, 42074, 0, 41228, 0, 0, 41241, 93786, 41239, 43533, 0, 7189, @@ -29233,161 +29430,161 @@ static const unsigned int code_hash[] = { 83043, 0, 68296, 0, 2823, 0, 0, 0, 2831, 0, 0, 11465, 0, 0, 0, 0, 0, 7181, 92855, 41332, 0, 12333, 0, 0, 0, 124914, 0, 9883, 127294, 73906, 70751, 0, 71863, 0, 0, 0, 0, 0, 0, 43741, 0, 8166, 70739, 0, 0, 74535, 0, - 65297, 68294, 571, 0, 8752, 0, 5288, 118822, 1541, 0, 127284, 8864, 0, 0, - 0, 0, 0, 113778, 12151, 0, 66874, 0, 1035, 0, 0, 7881, 701, 65936, - 128493, 0, 70462, 0, 11403, 0, 0, 82991, 0, 983142, 70472, 3994, 11421, + 65297, 68294, 571, 0, 8752, 0, 5288, 118822, 1541, 0, 127284, 8864, 0, + 73559, 0, 0, 0, 113778, 12151, 0, 66874, 0, 1035, 0, 0, 7881, 701, 65936, + 128493, 0, 70462, 0, 11403, 0, 0, 82991, 0, 983143, 70472, 3994, 11421, 121217, 127297, 127242, 127300, 70659, 127303, 0, 125205, 2855, 127828, 0, 41621, 68214, 0, 0, 10654, 82945, 119226, 12164, 41623, 7906, 0, 74297, 7182, 0, 83069, 0, 0, 0, 0, 121115, 0, 0, 747, 0, 92463, 12019, 43136, 0, 110861, 0, 0, 8001, 0, 0, 69394, 0, 0, 0, 68373, 0, 0, 0, - 128279, 0, 71915, 0, 0, 7282, 94066, 0, 0, 0, 0, 0, 5286, 83061, 0, 3718, - 0, 83057, 0, 124906, 71905, 0, 128480, 0, 0, 0, 0, 9206, 82980, 113824, - 6802, 0, 41653, 0, 1241, 0, 0, 0, 0, 68124, 41651, 42937, 0, 83042, - 41650, 0, 83037, 0, 12914, 2814, 0, 119552, 120691, 0, 0, 71968, 0, 0, 0, - 917546, 71862, 0, 0, 0, 3494, 10189, 69784, 0, 0, 71861, 0, 0, 65875, 0, - 0, 127762, 0, 74215, 43065, 0, 0, 7200, 0, 3261, 0, 0, 0, 65889, 71888, - 71975, 0, 0, 0, 0, 0, 77793, 0, 0, 129424, 77791, 635, 0, 0, 74753, 0, - 92420, 73997, 0, 0, 43905, 0, 118834, 126125, 0, 6667, 0, 983265, 0, 0, - 125200, 0, 0, 0, 0, 83137, 0, 0, 0, 0, 0, 121104, 127856, 125112, 71885, - 0, 120125, 7866, 194573, 92770, 194574, 0, 120140, 126074, 2849, 0, 0, - 42157, 12960, 0, 11812, 0, 74509, 0, 69881, 0, 0, 0, 123156, 7178, 0, 0, - 0, 0, 129041, 11534, 1967, 0, 0, 71361, 7015, 120298, 72757, 0, 12989, 0, - 9368, 983638, 1624, 43270, 0, 0, 10818, 0, 83091, 0, 120908, 0, 0, 0, 0, - 0, 0, 6169, 12871, 0, 2798, 65176, 4958, 42752, 119025, 0, 0, 0, 70346, - 66448, 0, 113780, 68364, 0, 0, 0, 68360, 0, 73746, 120945, 68352, 0, - 73787, 83110, 2154, 7199, 64955, 0, 0, 0, 0, 71980, 66507, 0, 69853, 0, - 0, 0, 0, 0, 0, 0, 92517, 118882, 120301, 13297, 0, 129446, 71963, 0, 0, - 0, 6658, 8045, 0, 0, 983873, 92319, 83101, 0, 72126, 0, 0, 0, 2416, 3310, - 0, 0, 379, 0, 43755, 0, 0, 0, 68362, 1284, 0, 73756, 0, 0, 83141, 70784, - 71977, 0, 0, 0, 8515, 83144, 83143, 0, 0, 0, 8529, 93782, 0, 7564, 0, 0, - 0, 0, 73757, 73760, 42359, 0, 2031, 0, 7202, 129984, 12676, 0, 0, 128418, - 0, 7710, 1610, 73801, 0, 0, 118706, 983607, 43917, 0, 9974, 228, 0, - 10398, 0, 0, 0, 92241, 70062, 118927, 42999, 1725, 65533, 8196, 9352, 0, - 0, 66868, 0, 8502, 5762, 0, 0, 43898, 0, 0, 0, 0, 43914, 0, 126507, - 64598, 13001, 9326, 83082, 43916, 1557, 0, 983879, 6330, 6805, 8631, - 2545, 70052, 0, 0, 0, 42998, 70410, 0, 42762, 71941, 42914, 126516, 262, - 1637, 0, 83025, 129491, 83026, 128757, 0, 0, 0, 128922, 0, 43658, 0, 0, - 129183, 6419, 0, 0, 0, 0, 93989, 0, 128173, 7194, 5291, 67395, 43666, 0, - 0, 0, 0, 128293, 0, 12881, 123596, 0, 73842, 0, 9011, 0, 0, 0, 70436, - 179, 43644, 0, 0, 64747, 0, 118813, 0, 0, 121389, 92649, 126629, 0, - 73850, 2801, 119837, 42069, 119839, 119838, 119841, 42072, 92736, 119842, - 0, 0, 0, 8377, 0, 42070, 119313, 119834, 119310, 4389, 43656, 1633, - 119857, 118632, 119859, 11119, 119845, 119844, 9967, 119846, 119849, - 4612, 92867, 119850, 42913, 70456, 0, 71983, 10782, 66898, 0, 119141, 0, - 0, 0, 11541, 69636, 0, 0, 119614, 2731, 0, 0, 0, 4102, 0, 73878, 0, 0, 0, - 0, 0, 11283, 0, 0, 0, 0, 0, 43674, 0, 0, 126705, 0, 0, 0, 0, 11142, - 128304, 0, 12975, 0, 123208, 0, 0, 74072, 0, 55269, 0, 0, 0, 78577, - 78576, 0, 0, 82966, 82974, 70448, 0, 0, 82968, 0, 0, 0, 0, 0, 113809, 0, - 69399, 64909, 0, 11790, 74019, 0, 128066, 0, 8561, 94076, 129481, 125045, - 69259, 65674, 7230, 0, 0, 8778, 0, 0, 67725, 2071, 0, 6459, 68325, 7628, - 65092, 73903, 0, 11342, 129388, 0, 0, 93965, 94081, 0, 11810, 70057, - 10723, 967, 0, 71973, 73905, 0, 6387, 0, 12307, 43913, 121089, 0, 127584, - 0, 1886, 0, 43895, 870, 7648, 0, 7662, 7652, 876, 871, 877, 7665, 878, - 42015, 879, 43692, 4563, 0, 0, 0, 73072, 867, 9520, 872, 7656, 868, 873, - 7642, 7659, 869, 874, 7644, 0, 875, 790, 0, 0, 0, 0, 0, 124899, 0, 0, 0, - 0, 0, 68452, 0, 0, 42067, 0, 0, 0, 12292, 0, 0, 0, 42012, 0, 0, 83388, 0, - 0, 8494, 4611, 0, 72344, 0, 9679, 0, 0, 0, 0, 93015, 0, 74364, 4628, - 4245, 0, 0, 0, 1851, 0, 127189, 0, 0, 0, 118897, 0, 64674, 124971, - 983887, 8829, 983693, 128864, 0, 0, 0, 0, 8809, 983696, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 7427, 0, 4588, 43680, 72300, 74484, 0, 0, 0, 0, 113787, 74363, - 129043, 0, 793, 0, 11197, 0, 0, 0, 842, 0, 8208, 70833, 0, 1647, 0, - 70841, 0, 0, 818, 0, 0, 0, 0, 0, 0, 120594, 0, 0, 70179, 0, 13167, 66359, - 0, 127172, 0, 4969, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2840, 0, 0, 0, 66887, - 65877, 9068, 0, 68194, 0, 0, 12991, 0, 2651, 68016, 983915, 0, 983261, - 70835, 0, 70844, 43648, 0, 0, 0, 0, 0, 0, 64372, 121064, 7458, 655, 752, - 7457, 7456, 7452, 3285, 74894, 11152, 73099, 0, 2391, 93766, 92271, 671, - 7435, 7434, 618, 668, 610, 42800, 7431, 7451, 42801, 640, 42927, 7448, - 7439, 628, 3905, 100742, 0, 0, 0, 67850, 0, 0, 0, 4605, 0, 100745, 43372, - 65945, 72710, 0, 119590, 0, 0, 70495, 987, 71229, 11572, 0, 0, 10002, - 9971, 70673, 0, 0, 0, 0, 0, 0, 11334, 0, 129493, 42364, 11503, 0, 0, 0, - 4627, 70090, 127784, 0, 0, 74046, 68872, 92562, 0, 0, 129900, 0, 129812, - 0, 0, 42569, 64965, 0, 0, 10516, 129828, 12190, 0, 42140, 0, 0, 0, 0, - 9887, 0, 4000, 7429, 7428, 665, 7424, 0, 0, 7884, 0, 0, 0, 0, 0, 2509, 0, - 120573, 0, 0, 92449, 0, 10690, 0, 119114, 126226, 0, 0, 73080, 4590, 0, - 74440, 0, 0, 0, 1708, 0, 0, 983609, 0, 0, 69226, 69974, 8813, 0, 1066, 0, - 0, 71965, 127921, 70447, 0, 0, 0, 2202, 0, 7516, 0, 0, 0, 8034, 0, 0, - 3631, 110696, 0, 0, 8416, 110694, 71937, 0, 0, 110692, 74621, 0, 70185, - 0, 74850, 0, 0, 12099, 70475, 0, 6252, 0, 0, 0, 0, 0, 0, 66368, 0, 64956, - 7071, 129070, 70457, 128159, 118800, 0, 77757, 0, 9357, 0, 1773, 0, - 125092, 0, 68451, 7745, 9844, 0, 0, 94, 1880, 120929, 0, 0, 0, 0, 0, 0, - 0, 0, 11237, 0, 129173, 0, 0, 0, 1757, 6964, 42480, 72823, 0, 120806, 0, - 0, 7731, 0, 0, 127883, 0, 77777, 43988, 70423, 74758, 0, 7592, 856, - 74299, 0, 0, 0, 78138, 1459, 0, 0, 0, 0, 0, 1504, 0, 0, 0, 0, 7529, 0, 0, - 0, 0, 12594, 0, 0, 336, 0, 7509, 0, 0, 0, 0, 127882, 0, 0, 0, 65859, 0, - 983986, 43062, 124948, 0, 0, 0, 0, 12970, 0, 0, 0, 0, 0, 0, 0, 119247, 0, - 65068, 74291, 129943, 7069, 0, 0, 66977, 11130, 2087, 0, 0, 0, 0, 126249, - 0, 92747, 0, 92614, 2091, 0, 2090, 0, 0, 7117, 2077, 72281, 0, 77889, - 2083, 0, 71196, 0, 0, 71981, 0, 0, 0, 0, 4165, 8746, 0, 0, 0, 0, 129572, - 7066, 77779, 70415, 128135, 0, 0, 7786, 127766, 2233, 0, 124965, 121122, - 2302, 0, 0, 7056, 0, 0, 0, 0, 118639, 0, 126506, 6920, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 983099, 70438, 2613, 0, 0, 110734, 0, 74571, 42760, 0, 0, 0, - 0, 0, 0, 71843, 0, 0, 70506, 1246, 74243, 0, 0, 41008, 0, 0, 0, 921, - 70048, 0, 12702, 0, 0, 1566, 8407, 0, 64653, 0, 74617, 0, 0, 72711, 5313, - 951, 0, 0, 0, 0, 77807, 4009, 70277, 71844, 0, 83123, 0, 72250, 0, - 119898, 113760, 0, 0, 0, 0, 70024, 0, 0, 119892, 0, 0, 0, 119890, 2579, - 119906, 3177, 11357, 69224, 0, 0, 83130, 64734, 0, 9822, 110670, 70471, - 110668, 66990, 110666, 66967, 0, 0, 0, 9851, 983748, 110673, 9059, - 110671, 77736, 0, 41687, 129054, 0, 71842, 70178, 0, 66975, 1777, 67003, - 10158, 69767, 0, 42366, 70444, 0, 0, 0, 70127, 71955, 5989, 110716, - 74636, 126999, 0, 41685, 0, 0, 9769, 41684, 0, 6225, 111328, 11740, 0, - 118840, 0, 2600, 0, 70416, 0, 118720, 3666, 70420, 127193, 71976, 0, 0, - 74542, 69771, 0, 0, 0, 0, 0, 69765, 77804, 252, 0, 69769, 0, 194616, 0, - 69763, 0, 0, 0, 0, 0, 0, 0, 120947, 0, 129410, 0, 118792, 0, 68323, - 125219, 0, 119188, 0, 2177, 121335, 0, 0, 0, 0, 0, 7764, 983745, 11094, - 120825, 0, 0, 92505, 8298, 0, 0, 0, 0, 0, 64449, 0, 126650, 0, 0, 0, - 70442, 0, 0, 0, 0, 7774, 10607, 0, 0, 0, 0, 0, 120764, 0, 0, 77746, 0, - 3458, 0, 70053, 0, 120995, 0, 2602, 0, 0, 0, 74907, 0, 0, 0, 0, 172, 0, - 4971, 70419, 1889, 7238, 0, 0, 0, 8257, 0, 0, 0, 129570, 0, 111342, - 71948, 0, 43366, 43363, 9807, 0, 0, 0, 72247, 64479, 0, 0, 0, 113707, 0, - 10900, 121355, 0, 0, 12048, 0, 64292, 0, 0, 0, 6099, 94084, 129486, 0, 0, - 299, 0, 8525, 92356, 0, 0, 111338, 0, 92564, 3075, 0, 94053, 0, 94050, 0, - 0, 70440, 0, 123590, 0, 0, 0, 2581, 11395, 0, 0, 0, 0, 128584, 0, 0, - 129423, 101092, 118855, 0, 0, 0, 7204, 70065, 2588, 2914, 7011, 55281, 0, - 7466, 0, 2883, 42253, 83118, 0, 0, 0, 123598, 0, 41230, 68299, 0, 43571, - 0, 6219, 0, 9980, 41232, 92245, 0, 66036, 41229, 118967, 0, 120666, - 94016, 0, 12711, 0, 0, 74289, 68472, 42857, 66950, 0, 0, 0, 127306, - 119006, 0, 11380, 72348, 0, 0, 0, 0, 0, 0, 0, 983579, 12722, 0, 922, 0, - 0, 983126, 74958, 3218, 120471, 120470, 120469, 120476, 120475, 8569, - 11404, 70450, 120463, 3214, 120461, 120468, 74910, 3207, 120465, 78729, - 78728, 78727, 0, 120460, 7425, 3205, 0, 78737, 78736, 71729, 43383, - 78733, 78732, 2606, 78730, 73897, 0, 11496, 1173, 0, 0, 129135, 0, 0, 0, - 120737, 120953, 120872, 120629, 378, 2610, 0, 0, 0, 0, 0, 37, 7068, 0, - 120480, 70421, 3209, 120477, 0, 120483, 9768, 120481, 0, 0, 0, 0, 0, 0, - 65510, 0, 100625, 0, 0, 0, 100627, 0, 126633, 0, 7060, 100628, 0, 127752, - 0, 69284, 70428, 71463, 0, 7380, 0, 0, 100593, 126997, 0, 124900, 0, - 71465, 121030, 3243, 0, 0, 0, 7050, 0, 70050, 0, 0, 0, 71466, 8203, - 71102, 68241, 0, 65211, 194599, 983403, 118636, 0, 779, 125061, 64367, - 100906, 69901, 8193, 55279, 0, 0, 0, 7065, 0, 4346, 0, 0, 908, 0, 0, - 8982, 0, 0, 0, 782, 0, 10883, 0, 0, 129396, 65542, 121302, 0, 68650, - 100575, 92244, 0, 0, 111351, 0, 4376, 0, 11787, 12961, 0, 0, 42888, 0, - 100610, 6231, 0, 65713, 100608, 1783, 0, 68238, 0, 0, 0, 194945, 0, 0, 0, - 68653, 0, 983051, 0, 764, 0, 0, 43531, 0, 9033, 0, 0, 6223, 11042, 0, 0, - 0, 0, 0, 917792, 0, 0, 0, 0, 0, 0, 120648, 0, 0, 0, 0, 0, 0, 71971, 0, - 1478, 0, 11825, 2607, 0, 0, 0, 74543, 0, 0, 100588, 6132, 0, 0, 0, 70058, - 0, 0, 0, 43537, 6761, 10093, 4369, 0, 0, 73735, 100564, 3947, 110778, 0, - 0, 0, 0, 100942, 0, 0, 0, 0, 0, 0, 7686, 0, 0, 0, 100934, 0, 100944, - 66577, 41221, 0, 42281, 0, 74024, 12293, 0, 94014, 11794, 0, 120893, - 1737, 0, 0, 0, 7205, 0, 9335, 12850, 77810, 2272, 7055, 0, 0, 0, 67751, - 0, 124910, 6780, 65067, 0, 1327, 68393, 983574, 0, 41217, 0, 10018, 0, 0, - 0, 100611, 68176, 41219, 0, 4147, 983170, 41216, 983712, 2616, 70197, - 68461, 65234, 0, 0, 0, 0, 119660, 0, 0, 0, 0, 127930, 119580, 70675, - 64943, 2608, 1470, 0, 0, 6227, 0, 0, 74775, 0, 0, 72320, 101024, 0, - 73822, 67456, 0, 0, 0, 0, 10876, 92482, 0, 0, 5834, 0, 6222, 0, 0, 12086, - 0, 1600, 64309, 0, 0, 68883, 127957, 93836, 0, 8882, 0, 129415, 2570, 0, - 0, 194606, 0, 0, 1234, 0, 13115, 110743, 110740, 100923, 5002, 110739, - 41286, 100926, 127019, 0, 0, 0, 0, 0, 0, 0, 41289, 0, 0, 75051, 41272, 0, - 0, 0, 0, 0, 124978, 0, 41279, 0, 0, 0, 11081, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 9637, 7112, 77975, 128984, 0, 10886, 0, 8548, 983860, 0, 0, 0, 8076, - 43048, 8290, 8291, 43051, 92570, 0, 2596, 0, 0, 41293, 0, 0, 2393, 7058, - 66432, 0, 68673, 0, 0, 0, 0, 0, 128558, 0, 0, 0, 0, 0, 64696, 0, 0, - 121086, 74165, 0, 0, 0, 0, 0, 0, 7063, 983182, 64893, 73096, 0, 68038, - 113757, 709, 0, 0, 1876, 0, 0, 120868, 8137, 110662, 67752, 70850, - 100832, 245, 100831, 11456, 41233, 7070, 0, 94046, 6136, 100835, 0, - 100781, 41235, 0, 0, 100782, 100642, 432, 0, 100784, 65437, 0, 100647, - 128909, 0, 100641, 100649, 0, 100648, 0, 43215, 0, 0, 0, 0, 9052, 0, 0, - 110826, 110827, 74784, 10580, 0, 100845, 0, 64640, 983175, 74455, 0, - 129670, 70035, 0, 12652, 12199, 127030, 0, 2566, 11971, 0, 0, 1065, 0, 0, - 0, 2576, 0, 66819, 0, 984005, 129852, 0, 0, 983050, 983845, 0, 2921, + 128279, 0, 71915, 0, 129742, 7282, 94066, 0, 0, 0, 0, 0, 5286, 83061, 0, + 3718, 0, 83057, 78933, 124906, 71905, 0, 128480, 0, 0, 0, 0, 9206, 82980, + 113824, 6802, 0, 41653, 0, 1241, 0, 0, 0, 0, 68124, 41651, 42937, 0, + 83042, 41650, 0, 83037, 0, 12914, 2814, 0, 119552, 120691, 0, 0, 71968, + 0, 0, 0, 917546, 71862, 0, 0, 0, 3494, 10189, 69784, 0, 0, 71861, 0, 0, + 65875, 0, 0, 127762, 0, 74215, 43065, 0, 0, 7200, 0, 3261, 0, 0, 0, + 65889, 71888, 71975, 0, 0, 0, 0, 0, 77793, 0, 0, 129424, 77791, 635, 0, + 0, 74753, 0, 92420, 73997, 0, 0, 43905, 0, 118834, 126125, 0, 6667, 0, + 983268, 0, 0, 125200, 0, 0, 0, 0, 83137, 0, 0, 0, 0, 0, 121104, 127856, + 125112, 71885, 0, 120125, 7866, 194573, 92770, 194574, 0, 120140, 126074, + 2849, 0, 0, 42157, 12960, 0, 11812, 0, 74509, 0, 69881, 0, 0, 0, 123156, + 7178, 0, 0, 0, 0, 129041, 11534, 1967, 0, 0, 71361, 7015, 120298, 72757, + 0, 12989, 0, 9368, 983638, 1624, 43270, 0, 0, 10818, 0, 83091, 0, 120908, + 0, 0, 0, 0, 0, 0, 6169, 12871, 0, 2798, 65176, 4958, 42752, 119025, 0, 0, + 0, 70346, 66448, 0, 113780, 68364, 0, 0, 0, 68360, 0, 73746, 120945, + 68352, 0, 73787, 83110, 2154, 7199, 64955, 0, 0, 0, 0, 71980, 66507, 0, + 69853, 0, 0, 0, 0, 0, 0, 0, 92517, 118882, 120301, 13297, 0, 129446, + 71963, 0, 0, 0, 6658, 8045, 0, 0, 983873, 92319, 83101, 0, 72126, 0, 0, + 0, 2416, 3310, 0, 0, 379, 0, 43755, 0, 0, 0, 68362, 1284, 0, 73756, 0, 0, + 83141, 70784, 71977, 0, 0, 0, 8515, 83144, 83143, 0, 0, 0, 8529, 93782, + 0, 7564, 0, 0, 0, 0, 73757, 73760, 42359, 0, 2031, 0, 7202, 129984, + 12676, 0, 0, 128418, 0, 7710, 1610, 73801, 0, 0, 118706, 983607, 43917, + 0, 9974, 228, 0, 10398, 0, 0, 0, 92241, 70062, 118927, 42999, 1725, + 65533, 8196, 9352, 0, 0, 66868, 0, 8502, 5762, 0, 0, 43898, 0, 0, 0, 0, + 43914, 0, 126507, 64598, 13001, 9326, 83082, 43916, 1557, 0, 983879, + 6330, 6805, 8631, 2545, 70052, 0, 0, 0, 42998, 70410, 0, 42762, 71941, + 42914, 126516, 262, 1637, 0, 83025, 129491, 83026, 128757, 0, 0, 0, + 128922, 0, 43658, 0, 0, 129183, 6419, 0, 0, 0, 0, 93989, 0, 128173, 7194, + 5291, 67395, 43666, 0, 0, 0, 0, 128293, 0, 12881, 123596, 0, 73842, 0, + 9011, 0, 0, 0, 70436, 179, 43644, 0, 0, 64747, 0, 118813, 0, 0, 121389, + 92649, 126629, 0, 73850, 2801, 119495, 42069, 119839, 119838, 119841, + 42072, 92736, 119842, 0, 0, 0, 8377, 0, 42070, 119313, 119834, 119310, + 4389, 43656, 1633, 119857, 118632, 119859, 11119, 119845, 119844, 9967, + 119846, 119849, 4612, 92867, 119850, 42913, 70456, 0, 71983, 10782, + 66898, 0, 119141, 0, 0, 0, 11541, 69636, 0, 0, 119614, 2731, 0, 0, 0, + 4102, 0, 73878, 0, 0, 0, 0, 0, 11283, 0, 0, 0, 0, 0, 43674, 0, 0, 126705, + 0, 0, 0, 0, 11142, 128304, 0, 12975, 0, 123208, 0, 0, 74072, 0, 55269, 0, + 0, 0, 78577, 78576, 0, 0, 82966, 82974, 70448, 0, 0, 82968, 0, 0, 0, 0, + 0, 113809, 0, 69399, 64909, 0, 11790, 74019, 0, 128066, 0, 8561, 94076, + 129481, 125045, 69259, 65674, 7230, 0, 0, 8778, 0, 0, 67725, 2071, 0, + 6459, 68325, 7628, 65092, 73903, 0, 11342, 129388, 0, 0, 93965, 94081, 0, + 11810, 70057, 10723, 967, 0, 71973, 73905, 0, 6387, 0, 12307, 43913, + 121089, 0, 127584, 0, 1886, 0, 43895, 870, 7648, 0, 7662, 7652, 876, 871, + 877, 7665, 878, 42015, 879, 43692, 4563, 0, 0, 0, 73072, 867, 9520, 872, + 7656, 868, 873, 7642, 7659, 869, 874, 7644, 0, 875, 790, 0, 0, 0, 0, 0, + 124899, 0, 0, 0, 0, 0, 68452, 0, 0, 42067, 0, 0, 0, 12292, 0, 0, 0, + 42012, 0, 0, 83388, 0, 0, 8494, 4611, 0, 72344, 0, 9679, 0, 0, 0, 0, + 93015, 0, 74364, 4628, 4245, 0, 0, 0, 1851, 0, 127189, 0, 0, 0, 118897, + 0, 64674, 124971, 983887, 8829, 983693, 128864, 0, 0, 0, 0, 8809, 983696, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 7427, 0, 4588, 43680, 72300, 74484, 0, 0, 0, + 0, 113787, 74363, 129043, 0, 793, 0, 11197, 0, 0, 0, 842, 0, 8208, 70833, + 0, 1647, 0, 70841, 0, 73508, 818, 0, 0, 0, 0, 0, 0, 120594, 0, 0, 70179, + 0, 13167, 66359, 0, 127172, 0, 4969, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2840, 0, + 0, 0, 66887, 65877, 9068, 0, 68194, 0, 0, 12991, 0, 2651, 68016, 983915, + 0, 983264, 70835, 0, 70844, 43648, 0, 0, 0, 0, 0, 0, 64372, 121064, 7458, + 655, 752, 7457, 7456, 7452, 3285, 74894, 11152, 73099, 0, 2391, 93766, + 92271, 671, 7435, 7434, 618, 668, 610, 42800, 7431, 7451, 42801, 640, + 42927, 7448, 7439, 628, 3905, 100742, 0, 0, 0, 67850, 0, 0, 0, 4605, 0, + 100745, 43372, 65945, 72710, 0, 119590, 0, 0, 70495, 987, 71229, 11572, + 0, 0, 10002, 9971, 70673, 0, 0, 0, 0, 0, 0, 11334, 0, 129493, 42364, + 11503, 0, 0, 0, 4627, 70090, 127784, 73473, 0, 74046, 68872, 92562, 0, 0, + 129900, 0, 129812, 0, 0, 42569, 64965, 0, 0, 10516, 129828, 12190, 0, + 42140, 0, 0, 0, 0, 9887, 0, 4000, 7429, 7428, 665, 7424, 0, 0, 7884, 0, + 0, 0, 0, 0, 2509, 0, 120573, 0, 0, 92449, 0, 10690, 0, 119114, 126226, 0, + 0, 73080, 4590, 0, 74440, 0, 0, 0, 1708, 0, 0, 983609, 0, 0, 69226, + 69974, 8813, 0, 1066, 0, 0, 71965, 127921, 70447, 0, 0, 0, 2202, 0, 7516, + 0, 0, 0, 8034, 0, 0, 3631, 110696, 0, 0, 8416, 110694, 71937, 0, 0, + 110692, 74621, 0, 70185, 0, 74850, 0, 0, 12099, 70475, 0, 6252, 0, 0, 0, + 0, 0, 0, 66368, 0, 64956, 7071, 129070, 70457, 128159, 118800, 0, 77757, + 0, 9357, 0, 1773, 0, 125092, 0, 68451, 7745, 9844, 0, 0, 94, 1880, + 120929, 0, 0, 0, 0, 0, 0, 0, 0, 11237, 0, 129173, 0, 0, 0, 1757, 6964, + 42480, 72823, 0, 120806, 0, 0, 7731, 0, 0, 127883, 0, 77777, 43988, + 70423, 74758, 0, 7592, 856, 74299, 0, 0, 0, 78138, 1459, 0, 0, 0, 0, 0, + 1504, 0, 0, 0, 0, 7529, 0, 0, 0, 0, 12594, 0, 0, 336, 0, 7509, 0, 0, 0, + 0, 127882, 0, 0, 0, 65859, 0, 983986, 43062, 124948, 0, 0, 0, 0, 12970, + 0, 0, 0, 0, 0, 0, 0, 119247, 0, 65068, 74291, 122938, 7069, 0, 0, 66977, + 11130, 2087, 0, 0, 0, 0, 126249, 0, 92747, 0, 92614, 2091, 0, 2090, 0, 0, + 7117, 2077, 72281, 0, 77889, 2083, 0, 71196, 0, 0, 71981, 0, 0, 0, 0, + 4165, 8746, 0, 0, 0, 0, 129572, 7066, 77779, 70415, 128135, 0, 0, 7786, + 127766, 2233, 0, 124965, 121122, 2302, 0, 0, 7056, 0, 0, 0, 0, 118639, 0, + 126506, 6920, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 983099, 70438, 2613, 0, 0, + 110734, 0, 74571, 42760, 0, 0, 0, 0, 0, 0, 71843, 0, 0, 70506, 1246, + 74243, 0, 0, 41008, 0, 0, 0, 921, 70048, 0, 12702, 119500, 0, 1566, 8407, + 0, 64653, 0, 74617, 0, 0, 72711, 5313, 951, 0, 0, 0, 0, 77807, 4009, + 70277, 71844, 0, 83123, 0, 72250, 0, 119898, 113760, 0, 0, 0, 0, 70024, + 0, 0, 119892, 0, 0, 0, 119890, 2579, 119906, 3177, 11357, 69224, 0, 0, + 83130, 64734, 0, 9822, 110670, 70471, 110668, 66990, 110666, 66967, 0, 0, + 0, 9851, 983748, 110673, 9059, 110671, 77736, 0, 41687, 129054, 0, 71842, + 70178, 0, 66975, 1777, 67003, 10158, 69767, 122982, 42366, 70444, 0, 0, + 0, 70127, 71955, 5989, 110716, 74636, 126999, 0, 41685, 0, 0, 9769, + 41684, 0, 6225, 111328, 11740, 0, 118840, 0, 2600, 0, 70416, 0, 118720, + 3666, 70420, 127193, 71976, 0, 0, 74542, 69771, 0, 0, 0, 0, 0, 69765, + 77804, 252, 0, 69769, 0, 194616, 0, 69763, 0, 0, 0, 0, 0, 0, 0, 120947, + 0, 129410, 0, 118792, 0, 68323, 125219, 0, 119188, 0, 2177, 121335, 0, 0, + 0, 0, 0, 7764, 983745, 11094, 120825, 119490, 0, 92505, 8298, 0, 0, 0, 0, + 0, 64449, 0, 126650, 0, 0, 0, 70442, 0, 0, 0, 0, 7774, 10607, 0, 0, 0, 0, + 0, 120764, 0, 0, 77746, 0, 3458, 0, 70053, 0, 120995, 0, 2602, 0, 0, 0, + 74907, 0, 0, 0, 0, 172, 0, 4971, 70419, 1889, 7238, 0, 0, 0, 8257, 0, 0, + 78917, 129570, 0, 111342, 71948, 0, 43366, 43363, 9807, 0, 0, 0, 72247, + 64479, 0, 0, 0, 113707, 0, 10900, 121355, 0, 0, 12048, 0, 64292, 0, 0, 0, + 6099, 94084, 129486, 0, 0, 299, 0, 8525, 92356, 0, 0, 111338, 0, 92564, + 3075, 0, 94053, 0, 94050, 0, 0, 70440, 0, 123590, 0, 0, 0, 2581, 11395, + 0, 0, 0, 0, 128584, 0, 0, 129423, 101092, 118855, 0, 0, 0, 7204, 70065, + 2588, 2914, 7011, 55281, 0, 7466, 0, 2883, 42253, 83118, 0, 0, 0, 83116, + 0, 41230, 68299, 0, 43571, 0, 6219, 0, 9980, 41232, 92245, 0, 66036, + 41229, 118967, 0, 120666, 94016, 0, 12711, 0, 0, 74289, 68472, 42857, + 66950, 0, 0, 0, 127306, 119006, 0, 11380, 72348, 0, 0, 0, 0, 0, 0, 0, + 983579, 12722, 0, 922, 0, 0, 983127, 74958, 3218, 120471, 120470, 120469, + 120476, 120475, 8569, 11404, 70450, 120463, 3214, 120461, 120468, 74910, + 3207, 120465, 78729, 78728, 78727, 0, 120460, 7425, 3205, 0, 78737, + 78736, 71729, 43383, 78733, 78732, 2606, 78730, 73897, 0, 11496, 1173, 0, + 0, 129135, 0, 0, 0, 120737, 120953, 120872, 120629, 378, 2610, 0, 0, 0, + 0, 0, 37, 7068, 0, 120480, 70421, 3209, 120477, 0, 120483, 9768, 120481, + 0, 0, 0, 0, 0, 0, 65510, 0, 100625, 0, 0, 0, 100627, 0, 126633, 0, 7060, + 100628, 0, 127752, 0, 69284, 70428, 71463, 0, 7380, 0, 0, 100593, 126997, + 0, 124900, 0, 71465, 121030, 3243, 0, 0, 0, 7050, 0, 70050, 0, 0, 122983, + 71466, 8203, 71102, 68241, 0, 65211, 194599, 983406, 118636, 0, 779, + 125061, 64367, 100906, 69901, 8193, 55279, 0, 0, 0, 7065, 0, 4346, 0, 0, + 908, 0, 0, 8982, 0, 0, 0, 782, 0, 10883, 0, 0, 129396, 65542, 121302, 0, + 68650, 100575, 92244, 0, 0, 111351, 0, 4376, 0, 11787, 12961, 0, 0, + 42888, 0, 100610, 6231, 0, 65713, 100608, 1783, 0, 68238, 0, 0, 0, + 194945, 0, 0, 0, 68653, 0, 983051, 0, 764, 0, 0, 43531, 0, 9033, 0, 0, + 6223, 11042, 0, 0, 0, 0, 0, 917792, 0, 0, 0, 0, 0, 0, 120648, 0, 0, 0, 0, + 0, 0, 71971, 0, 1478, 78923, 11825, 2607, 0, 0, 0, 74543, 0, 0, 100588, + 6132, 0, 0, 0, 70058, 0, 0, 0, 43537, 6761, 10093, 4369, 0, 0, 73735, + 100564, 3947, 110778, 0, 0, 0, 0, 100942, 0, 0, 0, 0, 0, 0, 7686, 0, 0, + 0, 100934, 0, 100944, 66577, 41221, 0, 42281, 0, 74024, 12293, 0, 94014, + 11794, 0, 120893, 1737, 0, 0, 0, 7205, 0, 9335, 12850, 77810, 2272, 7055, + 0, 0, 0, 67751, 0, 124910, 6780, 65067, 0, 1327, 68393, 983574, 0, 41217, + 0, 10018, 0, 0, 0, 100611, 68176, 41219, 0, 4147, 983171, 41216, 983712, + 2616, 70197, 68461, 65234, 0, 0, 0, 0, 119660, 0, 0, 0, 0, 127930, + 119580, 70675, 64943, 2608, 1470, 0, 0, 6227, 0, 0, 74775, 0, 0, 72320, + 101024, 0, 73822, 67456, 0, 0, 0, 0, 10876, 92482, 0, 0, 5834, 0, 6222, + 0, 0, 12086, 0, 1600, 64309, 0, 0, 68883, 127957, 93836, 0, 8882, 0, + 129415, 2570, 0, 0, 194606, 0, 0, 1234, 0, 13115, 110743, 110740, 100923, + 5002, 110739, 41286, 100926, 127019, 0, 0, 0, 0, 0, 0, 0, 41289, 0, 0, + 75051, 41272, 0, 0, 0, 0, 0, 124978, 0, 41279, 0, 0, 0, 11081, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 9637, 7112, 77975, 128984, 0, 10886, 0, 8548, 983860, + 0, 0, 0, 8076, 43048, 8290, 8291, 43051, 92570, 0, 2596, 0, 0, 41293, 0, + 0, 2393, 7058, 66432, 0, 68673, 0, 0, 0, 0, 0, 128558, 0, 0, 0, 0, 0, + 64696, 0, 0, 121086, 74165, 0, 0, 0, 0, 0, 0, 7063, 983183, 64893, 73096, + 0, 68038, 113757, 709, 0, 0, 1876, 0, 0, 120868, 8137, 110662, 67752, + 70850, 100832, 245, 100831, 11456, 41233, 7070, 0, 94046, 6136, 100835, + 0, 100781, 41235, 73474, 0, 100782, 100642, 432, 0, 100784, 65437, 0, + 100647, 128909, 0, 100641, 100649, 0, 100648, 0, 43215, 0, 0, 0, 0, 9052, + 0, 0, 110826, 110827, 74784, 10580, 0, 100845, 0, 64640, 983176, 74455, + 0, 129670, 70035, 0, 12652, 12199, 127030, 0, 2566, 11971, 0, 0, 1065, 0, + 0, 0, 2576, 0, 66819, 0, 984005, 129852, 0, 0, 983050, 983845, 0, 2921, 119104, 0, 5772, 12968, 70055, 0, 0, 0, 2580, 983841, 0, 0, 70032, 0, 0, 0, 128148, 0, 0, 121308, 11346, 0, 12054, 100824, 92426, 101112, 0, 13091, 0, 0, 100821, 100828, 0, 127026, 128334, 74821, 0, 66295, 68037, @@ -29395,13 +29592,13 @@ static const unsigned int code_hash[] = { 100776, 119319, 42356, 42432, 100778, 92823, 0, 0, 0, 78752, 70030, 66914, 0, 0, 7061, 0, 3854, 0, 70020, 68413, 0, 42319, 0, 0, 7067, 0, 0, 0, 0, 0, 0, 127797, 9029, 43543, 92820, 2353, 119316, 0, 100769, 0, - 100768, 983177, 0, 0, 43664, 0, 0, 0, 12277, 0, 78122, 11066, 65233, 0, + 100768, 983178, 0, 0, 43664, 0, 0, 0, 12277, 0, 78122, 11066, 65233, 0, 41224, 0, 0, 3747, 10522, 0, 77722, 1691, 41226, 0, 77724, 0, 41223, 121135, 121299, 697, 0, 121051, 4244, 0, 0, 0, 13121, 128573, 0, 0, 0, 0, 0, 0, 129879, 0, 65816, 68111, 0, 127933, 0, 0, 0, 0, 0, 0, 66895, 74602, 0, 7123, 70038, 5785, 9198, 0, 100810, 0, 7383, 64656, 0, 0, 0, 0, 0, 0, 0, 0, 13122, 0, 191, 70060, 8585, 126610, 64411, 0, 0, 64850, 41072, - 118996, 0, 0, 0, 0, 100754, 127010, 100753, 0, 100756, 683, 396, 0, + 118996, 0, 0, 0, 0, 78907, 127010, 100753, 0, 100756, 683, 396, 0, 100758, 0, 100757, 43058, 100760, 343, 7129, 42680, 0, 0, 0, 0, 0, 100761, 0, 74040, 0, 1724, 0, 119321, 0, 0, 2203, 0, 0, 0, 6592, 0, 983044, 0, 0, 0, 0, 3730, 1778, 0, 0, 128854, 121254, 0, 9018, 0, 0, 0, @@ -29410,269 +29607,272 @@ static const unsigned int code_hash[] = { 101084, 0, 92812, 68800, 42471, 0, 0, 67232, 64304, 42243, 101094, 2583, 0, 77728, 0, 0, 0, 71702, 3855, 0, 0, 0, 0, 0, 0, 0, 92416, 7132, 0, 92743, 0, 64756, 3798, 6578, 0, 0, 92481, 9774, 1275, 0, 119273, 983056, - 0, 120515, 7873, 77719, 0, 0, 0, 77717, 0, 73994, 73992, 0, 0, 0, 41851, - 0, 41846, 126485, 92337, 7633, 41849, 68385, 70726, 3224, 0, 69806, 0, 0, - 0, 1510, 68129, 0, 0, 0, 0, 12109, 0, 0, 0, 0, 0, 78377, 1910, 8671, - 78374, 127118, 70290, 0, 0, 0, 2654, 7893, 0, 0, 0, 72394, 0, 67394, 0, - 118970, 70066, 78372, 78371, 78370, 78369, 78368, 0, 0, 0, 1733, 0, 2568, - 0, 0, 0, 0, 41486, 0, 127839, 7116, 0, 0, 0, 7185, 0, 0, 0, 0, 0, 120575, - 120829, 0, 0, 0, 0, 92489, 0, 0, 0, 70022, 7171, 0, 340, 0, 0, 72980, 0, - 128535, 0, 124979, 94073, 0, 0, 0, 11392, 92509, 0, 0, 0, 0, 0, 0, 0, - 100632, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11948, 0, 6999, 617, 983825, 0, 3675, - 10600, 0, 0, 74616, 2617, 0, 0, 0, 128446, 0, 0, 8630, 194771, 7288, - 983828, 5545, 983818, 2586, 0, 0, 73123, 983851, 0, 0, 0, 70847, 0, 0, 0, - 0, 11195, 71708, 0, 7835, 70040, 0, 0, 92285, 0, 0, 72973, 0, 0, 100852, - 71118, 10029, 983166, 0, 0, 70033, 11359, 0, 0, 194782, 0, 0, 118975, 0, - 0, 3903, 100893, 983858, 0, 120555, 0, 93036, 110645, 0, 983565, 0, 0, - 194773, 0, 0, 0, 127238, 983822, 100919, 0, 100918, 64752, 0, 983138, - 100920, 118642, 43045, 100904, 0, 0, 0, 66394, 7128, 0, 0, 0, 0, 0, - 43044, 2604, 0, 100851, 43046, 121421, 69985, 11768, 43043, 10470, 0, - 7122, 194789, 4390, 454, 41397, 194792, 0, 78762, 0, 0, 120576, 64572, 0, - 68091, 2394, 2575, 113749, 0, 0, 74802, 100913, 129280, 0, 0, 11989, 0, - 0, 128856, 0, 0, 8249, 128172, 0, 0, 6640, 74806, 2598, 513, 0, 6586, - 127521, 129301, 120710, 65008, 0, 0, 92515, 0, 194795, 66755, 0, 126585, - 0, 43152, 78637, 0, 194797, 0, 69893, 6582, 0, 0, 12839, 0, 0, 983218, 0, - 2444, 128759, 66620, 0, 0, 0, 0, 69894, 0, 0, 0, 0, 4238, 11071, 9459, - 68437, 78140, 78139, 0, 10079, 0, 0, 0, 0, 0, 11907, 43928, 0, 0, 0, 0, - 92490, 43929, 0, 43926, 64498, 0, 9506, 6978, 126234, 0, 0, 0, 0, 43934, - 0, 1122, 65564, 0, 71055, 0, 0, 1920, 0, 43930, 827, 0, 0, 0, 0, 6577, - 1304, 64733, 0, 10606, 0, 0, 69503, 9329, 92997, 9239, 74422, 0, 129373, - 1222, 11076, 0, 69229, 43615, 8262, 72280, 64627, 19909, 983554, 72279, - 0, 287, 0, 233, 0, 0, 42816, 0, 0, 65140, 128158, 8830, 0, 0, 10524, - 41175, 125033, 72294, 0, 5296, 0, 127559, 0, 0, 0, 127154, 74858, 6516, - 6515, 6514, 6513, 6512, 0, 70870, 0, 0, 0, 12122, 92462, 100868, 43976, - 1785, 92507, 0, 0, 917771, 5138, 0, 0, 0, 100884, 0, 0, 0, 123564, 0, - 5134, 69980, 322, 4643, 5132, 0, 194942, 0, 5143, 0, 72309, 119628, 0, 0, - 72112, 0, 129964, 0, 0, 0, 0, 0, 0, 73097, 0, 0, 0, 127923, 0, 0, 0, 0, - 0, 3234, 0, 100886, 0, 100889, 118924, 0, 0, 100875, 68231, 74489, - 100872, 120746, 0, 100876, 0, 12714, 0, 64585, 93775, 0, 0, 0, 129428, 0, - 11027, 0, 10059, 0, 64524, 9767, 789, 1749, 0, 66766, 984010, 320, 0, 0, - 0, 3049, 0, 6471, 0, 74479, 9925, 127356, 127355, 127358, 4960, 5549, - 127359, 127346, 127345, 127348, 5418, 127350, 3351, 120892, 127351, - 10610, 5414, 0, 0, 4286, 5421, 127344, 67867, 0, 127794, 0, 6653, 0, 0, - 64510, 0, 41868, 0, 128823, 0, 0, 11613, 70737, 12603, 7131, 11108, 4566, - 0, 0, 0, 0, 0, 124938, 127369, 0, 0, 5200, 0, 129484, 0, 9183, 127361, - 74458, 73075, 395, 5482, 1376, 4349, 0, 0, 5196, 0, 6113, 42009, 5205, 0, - 120530, 0, 118973, 70467, 0, 0, 129691, 0, 9126, 70498, 0, 0, 0, 0, 0, - 3203, 192, 0, 3385, 120785, 128620, 5383, 0, 0, 0, 5738, 69449, 3336, 0, - 5361, 9633, 0, 0, 0, 0, 8581, 0, 1260, 3149, 5359, 12962, 74955, 10441, - 5357, 0, 0, 0, 5364, 0, 11431, 0, 9101, 0, 0, 0, 0, 78378, 121155, 42917, - 0, 129179, 0, 0, 0, 43360, 78385, 78384, 78383, 78382, 78381, 78380, - 78379, 9319, 7097, 0, 127748, 0, 0, 0, 120632, 0, 71205, 0, 0, 0, 1720, - 0, 0, 0, 8622, 0, 70430, 68772, 0, 0, 0, 73084, 0, 0, 11921, 0, 11769, - 68782, 0, 0, 0, 0, 194571, 41586, 0, 0, 0, 3356, 194572, 64709, 194575, - 0, 7134, 0, 78389, 0, 677, 0, 0, 0, 129474, 68747, 0, 68751, 3349, 74125, - 0, 8927, 0, 0, 0, 0, 0, 0, 0, 6806, 0, 8384, 68755, 0, 0, 0, 0, 0, - 124924, 0, 7113, 7586, 0, 10852, 0, 0, 4606, 0, 0, 70084, 0, 0, 1046, - 7124, 121192, 68753, 0, 5171, 65539, 0, 0, 0, 42394, 0, 74849, 127823, 0, - 5169, 11935, 0, 0, 3175, 0, 1537, 0, 5176, 8905, 4136, 4871, 78388, 0, 0, - 0, 0, 1128, 0, 0, 0, 74066, 0, 73069, 0, 0, 3662, 113767, 3378, 0, 71298, - 0, 127995, 6320, 71302, 983162, 10163, 0, 5165, 5126, 0, 66902, 41389, 0, - 71368, 3374, 113740, 0, 7119, 0, 0, 3507, 0, 7629, 6848, 19925, 0, 68463, - 183, 127208, 127209, 70811, 10636, 0, 128465, 2250, 0, 78772, 0, 0, 0, - 78768, 6580, 4332, 123584, 0, 10726, 66686, 127203, 127204, 127205, - 127206, 0, 70813, 127201, 127202, 0, 0, 5448, 41058, 5446, 0, 0, 71369, - 5442, 7135, 0, 0, 5451, 0, 78470, 0, 0, 0, 0, 11243, 10859, 65867, 10345, - 10409, 123606, 0, 0, 129077, 42181, 0, 0, 2060, 0, 7111, 0, 0, 0, 0, - 72741, 0, 205, 93784, 72346, 93771, 0, 9862, 6588, 43257, 0, 0, 0, 5505, - 93789, 5503, 65376, 0, 7125, 9819, 0, 0, 0, 5507, 12044, 194567, 0, 0, 0, - 7109, 0, 0, 7911, 10329, 10393, 8991, 125104, 69778, 11133, 129619, 8550, - 0, 5592, 2919, 0, 0, 5595, 0, 0, 4367, 0, 0, 5591, 41060, 5594, 0, 0, - 13142, 5590, 0, 72274, 118909, 75069, 123586, 9731, 71225, 64633, 0, 0, - 71217, 121361, 71227, 0, 0, 0, 0, 7137, 0, 0, 0, 10551, 10710, 0, 0, 0, - 120570, 0, 92364, 9936, 3348, 0, 0, 1444, 119058, 0, 74206, 983106, 0, - 1442, 129080, 0, 120959, 0, 0, 0, 0, 0, 0, 0, 3334, 73068, 118803, 0, 0, - 71219, 69770, 1651, 0, 8861, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43626, 0, - 0, 3344, 0, 0, 12920, 0, 0, 0, 71853, 3438, 128711, 0, 0, 0, 0, 129068, - 0, 0, 65117, 0, 0, 0, 0, 66366, 128915, 0, 69772, 0, 0, 0, 0, 4973, 8784, - 0, 0, 0, 0, 0, 0, 0, 125198, 983285, 0, 0, 66413, 0, 0, 0, 0, 0, 9243, - 2464, 0, 0, 3372, 0, 0, 0, 70364, 7121, 0, 0, 0, 92163, 0, 0, 0, 0, 0, 0, - 0, 3354, 0, 0, 983103, 101233, 0, 3876, 0, 127983, 6858, 43696, 43380, 0, - 74240, 0, 0, 0, 983985, 75074, 6589, 0, 0, 120993, 0, 0, 69609, 0, 66962, - 0, 10630, 71960, 0, 121293, 0, 0, 121287, 917942, 121337, 121215, 0, 0, - 0, 0, 0, 917940, 3366, 0, 917938, 0, 0, 0, 71062, 0, 121197, 0, 6925, - 71856, 0, 917929, 66780, 66274, 0, 72768, 0, 917930, 129482, 11138, 0, - 6754, 7118, 0, 64672, 65296, 0, 118957, 0, 0, 12296, 68457, 121320, 0, - 5282, 0, 72278, 0, 0, 0, 0, 0, 0, 66355, 0, 0, 68073, 64343, 0, 92744, - 195058, 195029, 0, 0, 195056, 195027, 0, 0, 128814, 195025, 6584, 195026, - 10657, 0, 74544, 0, 1200, 12243, 92269, 195062, 0, 129300, 11545, 0, - 120493, 3343, 4424, 11047, 0, 69863, 3896, 0, 0, 2947, 0, 0, 42221, 0, - 68139, 13059, 7942, 0, 3381, 0, 0, 0, 0, 0, 0, 78235, 0, 0, 0, 7044, - 65800, 78236, 0, 7045, 7175, 7047, 127884, 11791, 0, 0, 3881, 0, 0, - 127395, 0, 0, 67075, 7106, 72000, 0, 0, 74211, 41897, 92513, 0, 73040, - 66745, 0, 0, 0, 0, 121245, 0, 64354, 73083, 8777, 0, 129108, 8884, 2385, - 73067, 92450, 0, 0, 0, 42027, 12114, 0, 0, 64936, 0, 0, 0, 0, 0, 126605, - 0, 0, 0, 0, 73064, 0, 0, 0, 0, 0, 0, 0, 73057, 0, 123587, 0, 0, 0, 0, 0, - 70803, 0, 0, 124953, 0, 0, 0, 7048, 11087, 123600, 92536, 7043, 9600, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 42050, 0, 55289, 0, 0, 657, 0, 195054, 4461, - 92903, 0, 92904, 126490, 0, 4468, 0, 0, 0, 4456, 73070, 10720, 123588, 0, - 123544, 0, 0, 0, 195046, 260, 7714, 74163, 2045, 0, 65064, 4466, 0, 0, - 128087, 0, 41403, 0, 0, 0, 41406, 120692, 0, 0, 73939, 0, 0, 0, 41404, - 1165, 0, 4451, 13087, 0, 11258, 0, 73855, 0, 43014, 5439, 12061, 74586, - 3375, 128869, 0, 0, 0, 0, 0, 0, 0, 113823, 67078, 0, 67079, 0, 0, 0, 0, - 68459, 0, 0, 0, 0, 0, 0, 7280, 0, 0, 0, 4868, 8297, 0, 0, 42791, 0, - 66737, 66739, 0, 0, 5182, 0, 0, 72764, 0, 4465, 0, 12135, 0, 4464, 0, 0, - 977, 4458, 43827, 0, 0, 120888, 0, 344, 67463, 0, 0, 0, 0, 92240, 0, - 64443, 126995, 73078, 129525, 0, 0, 0, 43026, 7612, 119591, 64413, 0, 0, - 0, 0, 0, 0, 0, 0, 123622, 0, 119160, 10204, 127947, 73063, 0, 0, 127236, - 0, 68746, 0, 8852, 0, 0, 0, 0, 128427, 123597, 7932, 92858, 128463, 0, 0, - 0, 0, 0, 0, 0, 74893, 9567, 0, 73095, 0, 8650, 0, 0, 0, 69900, 118872, 0, - 70868, 0, 6719, 0, 0, 0, 72836, 0, 0, 118991, 0, 123594, 73815, 4420, 0, - 10583, 7760, 0, 0, 128752, 71711, 0, 128407, 0, 0, 77809, 9066, 0, 74795, - 0, 0, 0, 0, 0, 0, 0, 42825, 41854, 5304, 0, 124942, 6919, 8619, 0, 10038, - 66454, 9592, 129049, 0, 0, 110771, 110777, 110772, 0, 0, 0, 0, 0, 78498, - 110773, 43624, 0, 7779, 0, 0, 9479, 78493, 0, 66956, 2224, 0, 0, 0, 0, 0, - 42378, 3368, 0, 66804, 7697, 69237, 0, 2030, 0, 68236, 8370, 0, 66953, 0, - 0, 983352, 127903, 983350, 983349, 5174, 42831, 983346, 70439, 983344, - 8881, 119047, 0, 70433, 0, 0, 0, 0, 0, 0, 9576, 0, 3347, 4160, 5154, 0, - 3794, 0, 0, 0, 0, 0, 127916, 73073, 8381, 4572, 69564, 126101, 0, 0, 0, - 0, 0, 0, 0, 92283, 0, 0, 5799, 983341, 70100, 983339, 983338, 983337, - 43031, 64425, 65128, 983333, 0, 73059, 0, 68616, 0, 0, 0, 0, 119826, 0, - 0, 123604, 0, 0, 283, 68665, 0, 532, 0, 0, 983827, 0, 0, 3370, 73077, - 119132, 5443, 71431, 0, 118630, 0, 0, 0, 2298, 0, 0, 0, 983332, 983331, - 983330, 983329, 7144, 983327, 119600, 983325, 983324, 983323, 0, 78816, - 128833, 0, 0, 0, 0, 0, 0, 0, 0, 73088, 0, 123592, 983952, 0, 0, 0, 0, - 5186, 7360, 127837, 0, 12108, 0, 65124, 0, 0, 0, 6326, 43344, 0, 0, - 42562, 0, 0, 0, 983322, 65495, 983320, 101066, 983318, 101065, 983316, - 65490, 983314, 125034, 0, 101070, 0, 55245, 128927, 1630, 128232, 65483, - 0, 0, 0, 65476, 0, 0, 119214, 9283, 10183, 0, 0, 65499, 0, 64593, 66758, - 3376, 0, 0, 0, 101077, 43872, 12940, 0, 0, 78587, 101078, 5957, 0, 8926, - 983312, 983311, 983310, 10745, 10174, 983307, 113793, 983305, 983304, - 983303, 0, 123593, 5056, 0, 0, 0, 120773, 0, 9812, 0, 4460, 127792, - 73066, 0, 128038, 0, 123608, 0, 64278, 0, 0, 0, 66760, 0, 0, 70122, 0, 0, - 917627, 0, 73823, 101071, 127922, 2276, 0, 42579, 0, 983302, 983301, - 127831, 983299, 983298, 983297, 983296, 983295, 74207, 121255, 10482, - 12863, 73002, 2412, 0, 9522, 0, 983906, 120674, 101059, 3384, 101058, - 10702, 830, 0, 128166, 0, 8451, 0, 0, 121380, 69739, 128957, 0, 0, 0, 0, - 0, 0, 0, 4243, 92454, 73093, 0, 129705, 4441, 0, 983292, 983291, 66618, - 983289, 125141, 411, 983286, 68068, 983284, 4056, 983913, 0, 92666, 0, - 983916, 983968, 0, 0, 3364, 42265, 64437, 129635, 118816, 0, 9684, 216, - 0, 1401, 0, 0, 0, 122643, 0, 0, 0, 11126, 5768, 3191, 0, 0, 0, 0, 0, 0, - 65895, 0, 0, 3338, 73935, 983280, 983279, 983278, 129605, 983276, 983275, - 2794, 8807, 0, 0, 110720, 0, 8312, 0, 110718, 11953, 11662, 0, 0, 0, 0, - 9534, 66767, 129040, 0, 11113, 0, 0, 73082, 0, 981, 0, 4330, 119244, - 120536, 1824, 0, 0, 7034, 41683, 123166, 0, 73754, 0, 0, 74478, 128259, - 983270, 983257, 983256, 43831, 983254, 66752, 983252, 983251, 0, 70288, - 65343, 0, 0, 43225, 0, 0, 0, 0, 126129, 0, 128608, 0, 0, 0, 120726, 0, - 983852, 11746, 0, 5216, 0, 0, 0, 0, 3468, 127149, 9230, 65942, 0, 0, - 5803, 120677, 0, 0, 13124, 0, 0, 0, 42843, 0, 0, 0, 66753, 11739, 128318, - 0, 128444, 0, 0, 0, 12448, 0, 121441, 13057, 73852, 124994, 0, 0, 0, 0, - 0, 0, 126612, 0, 68903, 0, 129470, 0, 917992, 0, 0, 0, 0, 0, 0, 0, 92457, - 0, 0, 0, 0, 0, 0, 0, 0, 125078, 0, 0, 0, 10970, 92208, 0, 0, 0, 19944, 0, - 9009, 8551, 0, 0, 0, 7575, 67484, 0, 128899, 0, 129609, 78847, 0, 78846, - 0, 0, 69256, 0, 0, 0, 0, 9775, 100682, 129191, 119052, 68629, 194703, 0, - 0, 78850, 92880, 0, 0, 0, 0, 0, 0, 0, 71273, 6184, 41540, 3303, 66182, - 11786, 66180, 66203, 3422, 0, 68290, 43007, 4478, 66178, 0, 0, 126216, 0, - 4477, 0, 69608, 66184, 66183, 66204, 66194, 0, 66198, 41880, 66188, - 66197, 78148, 66195, 66190, 66191, 41111, 66189, 73788, 7788, 0, 0, 0, 0, - 0, 2221, 78163, 6535, 78161, 78162, 430, 78160, 78156, 78158, 0, 0, 4945, - 0, 4950, 0, 78165, 0, 67118, 0, 5964, 12908, 0, 0, 0, 74477, 83390, 0, - 4949, 0, 443, 0, 4944, 5467, 119603, 983262, 0, 9364, 0, 119148, 4946, 0, - 3788, 126106, 983718, 0, 120847, 129858, 74441, 0, 0, 12072, 92248, 0, - 983708, 0, 128676, 12091, 0, 0, 0, 4673, 0, 4678, 0, 0, 65059, 43860, 0, - 0, 0, 128151, 1199, 0, 8356, 0, 0, 4677, 0, 0, 0, 2192, 78173, 78175, - 78171, 78172, 72255, 78170, 78166, 4674, 128450, 194944, 0, 124970, 0, - 119579, 0, 129919, 1855, 0, 0, 127806, 0, 0, 68912, 72323, 0, 12988, - 121000, 0, 0, 0, 4654, 6840, 983429, 0, 73993, 0, 4649, 65209, 983908, - 93839, 4648, 122635, 121169, 983433, 126231, 983424, 66846, 7828, 4650, - 983423, 72879, 0, 4653, 7822, 0, 0, 43187, 0, 983586, 6821, 0, 0, 0, 0, - 0, 0, 66756, 983430, 0, 0, 0, 8547, 0, 42165, 0, 119228, 6836, 0, 0, - 4662, 0, 0, 0, 9146, 599, 4657, 0, 120754, 0, 4656, 0, 0, 7811, 40994, 0, - 6414, 5967, 4658, 3725, 0, 5814, 4661, 127760, 194961, 0, 0, 64904, 0, - 10833, 0, 0, 4867, 128717, 0, 11459, 3054, 0, 40996, 0, 7605, 4622, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 19926, 0, 0, 65307, 4617, 0, 0, 0, 4616, 10518, 0, - 127160, 0, 5958, 0, 983446, 4618, 0, 983439, 120675, 4621, 0, 983441, - 522, 125213, 11139, 65803, 194972, 0, 12201, 6135, 121060, 983422, 0, - 983093, 0, 983420, 983413, 983434, 4638, 983418, 0, 78242, 5965, 78240, - 66569, 68646, 0, 983452, 74392, 5335, 0, 0, 4633, 0, 119045, 983448, - 4632, 0, 5542, 5333, 0, 983425, 68648, 5331, 4634, 0, 92870, 5338, 4637, - 0, 0, 43477, 0, 42493, 0, 42361, 0, 0, 73853, 0, 0, 0, 74204, 11343, 0, - 10358, 10422, 4758, 0, 1608, 5252, 0, 0, 4753, 78239, 11344, 78237, 0, - 5231, 74384, 0, 0, 118676, 0, 0, 0, 0, 71991, 5229, 4757, 0, 0, 5227, - 4752, 0, 65235, 5234, 73044, 0, 0, 0, 0, 0, 0, 7460, 0, 917936, 0, 0, - 74760, 65189, 0, 92230, 0, 0, 5574, 128980, 0, 65139, 5577, 0, 0, 118871, - 68641, 8965, 7635, 0, 5316, 70021, 5314, 74555, 5572, 0, 5312, 0, 5525, - 5330, 5319, 68292, 0, 65066, 0, 0, 983493, 0, 0, 127851, 0, 74851, 0, 0, - 64609, 0, 0, 128593, 0, 129339, 0, 8632, 0, 0, 0, 195012, 5735, 195013, - 1692, 70151, 4610, 122653, 4305, 0, 4609, 43478, 4614, 77753, 118534, - 5287, 5309, 5285, 0, 5961, 4647, 5283, 10743, 0, 71889, 601, 4613, 77759, - 0, 9208, 4608, 74044, 71107, 5190, 0, 0, 92410, 43965, 2265, 0, 0, 0, 0, - 0, 0, 0, 129953, 0, 0, 5960, 0, 8992, 65293, 0, 1782, 0, 0, 0, 0, 0, - 5501, 0, 42508, 69759, 120749, 129120, 0, 195023, 77740, 43900, 77741, 0, + 0, 120515, 7873, 77719, 129754, 0, 0, 77717, 0, 73994, 73992, 0, 0, 0, + 41851, 0, 41846, 126485, 92337, 7633, 41849, 68385, 70726, 3224, 0, + 69806, 0, 0, 0, 1510, 68129, 0, 0, 0, 0, 12109, 0, 0, 0, 0, 0, 78377, + 1910, 8671, 78374, 127118, 70290, 0, 0, 0, 2654, 7893, 0, 0, 0, 72394, 0, + 67394, 0, 118970, 70066, 78372, 78371, 78370, 78369, 78368, 0, 0, 0, + 1733, 0, 2568, 0, 0, 0, 0, 41486, 0, 127839, 7116, 0, 0, 0, 7185, 0, 0, + 0, 0, 0, 120575, 120829, 0, 0, 0, 0, 92489, 0, 0, 0, 70022, 7171, 0, 340, + 0, 0, 72980, 0, 128535, 0, 124979, 94073, 0, 0, 0, 11392, 92509, 0, 0, 0, + 0, 0, 0, 0, 100632, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11948, 0, 6999, 617, + 983825, 0, 3675, 10600, 0, 0, 74616, 2617, 0, 0, 0, 128446, 0, 0, 8630, + 194771, 7288, 983828, 5545, 983818, 2586, 0, 0, 73123, 983851, 0, 0, 0, + 70847, 0, 0, 0, 0, 11195, 71708, 0, 7835, 70040, 0, 0, 92285, 0, 0, + 72973, 0, 0, 100852, 71118, 10029, 983167, 0, 0, 70033, 11359, 0, 0, + 194782, 0, 0, 118975, 0, 0, 3903, 100893, 983858, 0, 120555, 0, 93036, + 110645, 0, 983565, 0, 0, 194773, 0, 0, 0, 127238, 983822, 100919, 0, + 100918, 64752, 0, 983139, 100920, 118642, 43045, 100904, 0, 0, 0, 66394, + 7128, 0, 0, 0, 0, 0, 43044, 2604, 0, 100851, 43046, 121421, 69985, 11768, + 43043, 10470, 0, 7122, 194789, 4390, 454, 41397, 194792, 0, 78762, 0, 0, + 120576, 64572, 0, 68091, 2394, 2575, 113749, 0, 0, 74802, 100913, 129280, + 0, 0, 11989, 0, 0, 128856, 0, 0, 8249, 128172, 0, 0, 6640, 74806, 2598, + 513, 0, 6586, 127521, 129301, 120710, 65008, 0, 0, 92515, 0, 194795, + 66755, 0, 126585, 0, 43152, 78637, 0, 194797, 0, 69893, 6582, 0, 0, + 12839, 0, 78906, 983221, 0, 2444, 119489, 66620, 0, 0, 0, 0, 69894, 0, 0, + 0, 0, 4238, 11071, 9459, 68437, 78140, 78139, 0, 10079, 128985, 0, 0, 0, + 0, 11907, 43928, 0, 0, 0, 0, 92490, 43929, 0, 43926, 64498, 0, 9506, + 6978, 126234, 0, 0, 0, 0, 43934, 0, 1122, 65564, 0, 71055, 0, 0, 1920, 0, + 43930, 827, 0, 0, 0, 0, 6577, 1304, 64733, 0, 10606, 0, 0, 69503, 9329, + 92997, 9239, 74422, 0, 129373, 1222, 11076, 0, 69229, 43615, 8262, 72280, + 64627, 19909, 983554, 72279, 0, 287, 0, 233, 0, 0, 42816, 0, 0, 65140, + 128158, 8830, 0, 0, 10524, 41175, 125033, 72294, 0, 5296, 0, 127559, 0, + 0, 0, 127154, 74858, 6516, 6515, 6514, 6513, 6512, 0, 70870, 0, 0, 0, + 12122, 92462, 100868, 43976, 1785, 92507, 0, 0, 917771, 5138, 0, 0, 0, + 100884, 0, 0, 0, 123564, 0, 5134, 69980, 322, 4643, 5132, 0, 194942, 0, + 5143, 0, 72309, 119628, 0, 0, 72112, 0, 129964, 0, 0, 0, 0, 0, 0, 73097, + 0, 0, 0, 127923, 0, 0, 0, 0, 0, 3234, 0, 100886, 0, 100889, 118924, 0, 0, + 100875, 68231, 74489, 100872, 120746, 0, 100876, 0, 12714, 0, 64585, + 93775, 0, 0, 0, 129428, 0, 11027, 0, 10059, 0, 64524, 9767, 789, 1749, 0, + 66766, 984010, 320, 0, 0, 0, 3049, 0, 6471, 0, 74479, 9925, 127356, + 127355, 127358, 4960, 5549, 127359, 127346, 127345, 127348, 5418, 127350, + 3351, 120892, 127351, 10610, 5414, 93789, 0, 4286, 5421, 127344, 67867, + 0, 127794, 0, 6653, 122958, 0, 64510, 0, 41868, 0, 128823, 0, 0, 11613, + 70737, 12603, 7131, 11108, 4566, 0, 0, 0, 0, 0, 124938, 127369, 0, 0, + 5200, 0, 129484, 0, 9183, 127361, 74458, 73075, 395, 5482, 1376, 4349, 0, + 0, 5196, 0, 6113, 42009, 5205, 0, 120530, 0, 118973, 70467, 0, 0, 129691, + 0, 9126, 70498, 0, 0, 0, 0, 0, 3203, 192, 0, 3385, 120785, 128620, 5383, + 0, 0, 0, 5738, 69449, 3336, 0, 5361, 9633, 0, 0, 0, 0, 8581, 0, 1260, + 3149, 5359, 12962, 74955, 10441, 5357, 0, 0, 0, 5364, 0, 11431, 0, 9101, + 0, 0, 0, 0, 78378, 121155, 42917, 0, 129179, 0, 0, 0, 43360, 78385, + 78384, 78383, 78382, 78381, 78380, 78379, 9319, 7097, 0, 127748, 0, 0, 0, + 120632, 0, 71205, 0, 0, 0, 1720, 0, 0, 0, 8622, 0, 70430, 68772, 0, 0, 0, + 73084, 0, 0, 11921, 0, 11769, 68782, 0, 0, 0, 0, 194571, 41586, 0, 0, 0, + 3356, 194572, 64709, 194575, 0, 7134, 0, 78389, 0, 677, 0, 0, 0, 129474, + 68747, 0, 68751, 3349, 74125, 0, 8927, 0, 0, 0, 0, 0, 0, 0, 6806, 0, + 8384, 68755, 0, 0, 0, 0, 0, 124924, 0, 7113, 7586, 0, 10852, 0, 0, 4606, + 0, 0, 70084, 0, 0, 1046, 7124, 121192, 68753, 0, 5171, 65539, 0, 0, 0, + 42394, 0, 74849, 127823, 0, 5169, 11935, 0, 0, 3175, 0, 1537, 0, 5176, + 8905, 4136, 4871, 78388, 0, 0, 122661, 0, 1128, 0, 0, 0, 74066, 0, 73069, + 0, 0, 3662, 113767, 3378, 0, 71298, 0, 127995, 6320, 71302, 983163, + 10163, 0, 5165, 5126, 0, 66902, 41389, 0, 71368, 3374, 113740, 0, 7119, + 0, 0, 3507, 0, 7629, 6848, 19925, 0, 68463, 183, 127208, 127209, 70811, + 10636, 0, 128465, 2250, 0, 78772, 0, 0, 0, 78768, 6580, 4332, 123584, 0, + 10726, 66686, 127203, 127204, 127205, 127206, 0, 70813, 127201, 127202, + 0, 0, 5448, 41058, 5446, 0, 0, 71369, 5442, 7135, 0, 0, 5451, 0, 78470, + 0, 0, 0, 0, 11243, 10859, 65867, 10345, 10409, 123606, 0, 0, 129077, + 42181, 0, 0, 2060, 0, 7111, 0, 0, 0, 0, 72741, 0, 205, 93784, 72346, + 93771, 0, 9862, 6588, 43257, 0, 0, 0, 5505, 93760, 5503, 65376, 0, 7125, + 9819, 0, 0, 0, 5507, 12044, 194567, 0, 0, 0, 7109, 0, 0, 7911, 10329, + 10393, 8991, 125104, 69778, 11133, 129619, 8550, 0, 5592, 2919, 0, 0, + 5595, 0, 0, 4367, 0, 0, 5591, 41060, 5594, 0, 0, 13142, 5590, 0, 72274, + 118909, 75069, 123586, 9731, 71225, 64633, 0, 0, 71217, 121361, 71227, 0, + 0, 0, 0, 7137, 0, 0, 0, 10551, 10710, 0, 0, 0, 120570, 0, 92364, 9936, + 3348, 0, 0, 1444, 119058, 0, 74206, 983107, 0, 1442, 129080, 0, 120959, + 0, 0, 0, 0, 0, 0, 0, 3334, 73068, 118803, 0, 0, 71219, 69770, 1651, 0, + 8861, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43626, 0, 0, 3344, 0, 0, 12920, 0, + 0, 0, 71853, 3438, 128711, 0, 0, 0, 0, 129068, 0, 0, 65117, 0, 0, 0, 0, + 66366, 128915, 0, 69772, 0, 0, 0, 0, 4973, 8784, 0, 0, 0, 0, 0, 0, 0, + 125198, 983288, 0, 0, 66413, 0, 0, 0, 0, 122663, 9243, 2464, 0, 0, 3372, + 0, 0, 0, 70364, 7121, 0, 0, 0, 92163, 0, 0, 0, 0, 0, 0, 0, 3354, 0, 0, + 983104, 101233, 0, 3876, 0, 127983, 6858, 43696, 43380, 0, 74240, 0, 0, + 0, 983985, 75074, 6589, 0, 0, 120993, 0, 0, 69609, 0, 66962, 0, 10630, + 71960, 0, 121293, 0, 0, 121287, 917942, 121337, 121215, 0, 0, 0, 0, 0, + 917940, 3366, 0, 917938, 0, 0, 0, 71062, 0, 121197, 0, 6925, 71856, 0, + 917929, 66780, 66274, 0, 72768, 0, 917930, 129482, 11138, 0, 6754, 7118, + 0, 64672, 65296, 0, 118957, 0, 0, 12296, 68457, 121320, 0, 5282, 0, + 72278, 0, 0, 0, 0, 0, 0, 66355, 0, 0, 68073, 64343, 0, 92744, 195058, + 195029, 0, 0, 195056, 195027, 0, 0, 128814, 195025, 6584, 195026, 10657, + 0, 74544, 0, 1200, 12243, 92269, 195062, 0, 129300, 11545, 0, 120493, + 3343, 4424, 11047, 0, 69863, 3896, 0, 0, 2947, 0, 0, 42221, 0, 68139, + 13059, 7942, 0, 3381, 0, 0, 0, 0, 0, 0, 78235, 0, 0, 0, 7044, 65800, + 78236, 0, 7045, 7175, 7047, 127884, 11791, 0, 0, 3881, 0, 0, 127395, 0, + 0, 67075, 7106, 72000, 0, 0, 74211, 41897, 92513, 0, 73040, 66745, 0, 0, + 0, 0, 121245, 0, 64354, 73083, 8777, 0, 129108, 8884, 2385, 73067, 92450, + 0, 0, 0, 42027, 12114, 0, 0, 64936, 0, 0, 0, 0, 0, 126605, 0, 0, 0, 0, + 73064, 0, 0, 0, 0, 0, 0, 0, 73057, 0, 123587, 0, 0, 0, 0, 0, 70803, 0, 0, + 124953, 0, 0, 0, 7048, 11087, 123600, 92536, 7043, 9600, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 42050, 0, 55289, 0, 0, 657, 0, 195054, 4461, 92903, 0, 92904, + 126490, 0, 4468, 0, 0, 0, 4456, 73070, 10720, 123588, 0, 123544, 0, 0, 0, + 195046, 260, 7714, 74163, 2045, 0, 65064, 4466, 0, 0, 128087, 129768, + 41403, 0, 0, 0, 41406, 120692, 0, 0, 73939, 0, 0, 0, 41404, 1165, 0, + 4451, 13087, 0, 11258, 0, 73855, 0, 43014, 5439, 12061, 74586, 3375, + 128869, 0, 0, 0, 0, 0, 0, 0, 113823, 67078, 0, 67079, 0, 0, 0, 0, 68459, + 0, 0, 0, 0, 0, 0, 7280, 0, 0, 0, 4868, 8297, 0, 0, 42791, 0, 66737, + 66739, 0, 0, 5182, 0, 0, 72764, 0, 4465, 0, 12135, 0, 4464, 0, 0, 977, + 4458, 43827, 0, 0, 120888, 0, 344, 67463, 0, 0, 0, 0, 92240, 0, 64443, + 126995, 73078, 129525, 0, 0, 0, 43026, 7612, 119591, 64413, 0, 0, 0, 0, + 0, 0, 0, 0, 123622, 0, 119160, 10204, 127947, 73063, 0, 0, 127236, 0, + 68746, 0, 8852, 0, 0, 0, 0, 128427, 123597, 7932, 92858, 128463, 0, 0, + 72453, 0, 0, 0, 0, 74893, 9567, 0, 73095, 0, 8650, 0, 0, 0, 69900, + 118872, 0, 70868, 0, 6719, 0, 0, 0, 72836, 0, 0, 118991, 0, 123594, + 73815, 4420, 0, 10583, 7760, 0, 0, 128752, 71711, 0, 128407, 0, 0, 77809, + 9066, 0, 74795, 0, 0, 0, 0, 0, 0, 0, 42825, 41854, 5304, 0, 124942, 6919, + 8619, 0, 10038, 66454, 9592, 129049, 0, 0, 110771, 110777, 110772, 0, 0, + 0, 0, 0, 78498, 110773, 43624, 0, 7779, 0, 0, 9479, 78493, 0, 66956, + 2224, 0, 0, 0, 0, 0, 42378, 3368, 0, 66804, 7697, 69237, 0, 2030, 0, + 68236, 8370, 0, 66953, 0, 0, 983355, 127903, 983353, 983352, 5174, 42831, + 983349, 70439, 983347, 8881, 119047, 0, 70433, 0, 0, 0, 0, 0, 0, 9576, 0, + 3347, 4160, 5154, 0, 3794, 0, 0, 0, 0, 0, 127916, 73073, 8381, 4572, + 69564, 126101, 0, 0, 0, 0, 0, 0, 0, 92283, 0, 0, 5799, 983344, 70100, + 983342, 983341, 983340, 43031, 64425, 65128, 983336, 0, 73059, 0, 68616, + 0, 0, 0, 0, 119826, 0, 0, 123604, 0, 0, 283, 68665, 0, 532, 0, 0, 983827, + 0, 0, 3370, 73077, 119132, 5443, 71431, 0, 118630, 0, 0, 0, 2298, 0, 0, + 0, 983335, 983334, 983333, 983332, 7144, 983330, 119600, 983328, 983327, + 983326, 0, 78816, 128833, 0, 0, 0, 0, 0, 0, 0, 0, 73088, 0, 123592, + 983952, 0, 0, 0, 0, 5186, 7360, 127837, 0, 12108, 0, 65124, 0, 0, 0, + 6326, 43344, 0, 0, 42562, 0, 0, 0, 983325, 65495, 983323, 101066, 983321, + 101065, 983319, 65490, 983317, 125034, 0, 101070, 127178, 55245, 128927, + 1630, 128232, 65483, 0, 0, 0, 65476, 0, 0, 119214, 9283, 10183, 0, 0, + 65499, 0, 64593, 66758, 3376, 0, 0, 0, 101077, 43872, 12940, 0, 0, 78587, + 101078, 5957, 0, 8926, 983315, 983314, 983313, 10745, 10174, 983310, + 113793, 983308, 983307, 983306, 0, 123593, 5056, 0, 0, 0, 120773, 0, + 9812, 0, 4460, 127792, 73066, 0, 128038, 0, 123608, 0, 64278, 0, 0, 0, + 66760, 0, 0, 70122, 0, 0, 917627, 0, 73823, 101071, 127922, 2276, 0, + 42579, 0, 983305, 983304, 127831, 983302, 983301, 983300, 983299, 983298, + 74207, 121255, 10482, 12863, 73002, 2412, 0, 9522, 0, 983906, 120674, + 101059, 3384, 101058, 10702, 830, 0, 128166, 0, 8451, 0, 0, 121380, + 69739, 128957, 0, 0, 0, 0, 0, 0, 0, 4243, 92454, 73093, 0, 129705, 4441, + 0, 983295, 983294, 66618, 983292, 125141, 411, 983289, 68068, 983287, + 4056, 983913, 0, 92666, 0, 983916, 983968, 0, 0, 3364, 42265, 64437, + 129635, 118816, 0, 9684, 216, 0, 1401, 0, 0, 0, 122643, 0, 0, 0, 11126, + 5768, 3191, 0, 0, 0, 0, 0, 0, 65895, 0, 0, 3338, 73935, 983283, 983282, + 983281, 129605, 983279, 983278, 2794, 8807, 0, 0, 110720, 0, 8312, 0, + 110718, 11953, 11662, 0, 0, 0, 0, 9534, 66767, 129040, 0, 11113, 0, 0, + 73082, 0, 981, 0, 4330, 119244, 120536, 1824, 0, 0, 7034, 41683, 123166, + 0, 73754, 0, 0, 74478, 128259, 983273, 983260, 983259, 43831, 983257, + 66752, 983255, 983254, 0, 70288, 65343, 0, 0, 43225, 0, 0, 0, 0, 126129, + 0, 128608, 0, 0, 0, 120726, 0, 983852, 11746, 0, 5216, 0, 0, 0, 0, 3468, + 127149, 9230, 65942, 0, 0, 5803, 120677, 0, 0, 13124, 0, 0, 0, 42843, 0, + 0, 0, 66753, 11739, 128318, 0, 128444, 0, 0, 0, 12448, 0, 121441, 13057, + 73852, 124994, 0, 0, 0, 0, 0, 0, 126612, 0, 68903, 0, 129470, 0, 917992, + 0, 0, 0, 0, 0, 0, 0, 92457, 0, 0, 0, 0, 0, 0, 0, 0, 125078, 0, 0, 0, + 10970, 92208, 0, 0, 0, 19944, 0, 9009, 8551, 0, 0, 0, 7575, 67484, 0, + 128899, 0, 129609, 78847, 0, 78846, 73502, 0, 69256, 0, 0, 0, 0, 9775, + 100682, 129191, 119052, 68629, 194703, 0, 0, 78850, 92880, 0, 0, 0, 0, 0, + 0, 0, 71273, 6184, 41540, 3303, 66182, 11786, 66180, 66203, 3422, 0, + 68290, 43007, 4478, 66178, 0, 0, 126216, 0, 4477, 0, 69608, 66184, 66183, + 66204, 66194, 0, 66198, 41880, 66188, 66197, 78148, 66195, 66190, 66191, + 41111, 66189, 73788, 7788, 0, 0, 0, 0, 0, 2221, 78163, 6535, 78161, + 78162, 430, 78160, 78156, 78158, 0, 0, 4945, 0, 4950, 0, 78165, 0, 67118, + 0, 5964, 12908, 0, 0, 0, 74477, 83390, 0, 4949, 0, 443, 0, 4944, 5467, + 119603, 983265, 0, 9364, 0, 119148, 4946, 0, 3788, 126106, 983718, 0, + 120847, 129858, 74441, 0, 0, 12072, 92248, 0, 983708, 0, 128676, 12091, + 0, 0, 0, 4673, 0, 4678, 0, 0, 65059, 43860, 0, 0, 0, 128151, 1199, 0, + 8356, 0, 0, 4677, 0, 0, 0, 2192, 78173, 78175, 78171, 78172, 72255, + 78170, 78166, 4674, 128450, 194944, 0, 124970, 0, 119579, 0, 129919, + 1855, 0, 0, 127806, 0, 0, 68912, 72323, 0, 12988, 121000, 0, 0, 0, 4654, + 6840, 983432, 0, 73993, 0, 4649, 65209, 983908, 93839, 4648, 122635, + 121169, 983436, 126231, 983427, 66846, 7828, 4650, 983426, 72879, 0, + 4653, 7822, 0, 0, 43187, 0, 983586, 6821, 0, 0, 0, 0, 0, 0, 66756, + 983433, 0, 0, 0, 8547, 0, 42165, 0, 119228, 6836, 0, 0, 4662, 0, 0, 0, + 9146, 599, 4657, 0, 120754, 0, 4656, 0, 0, 7811, 40994, 0, 6414, 5967, + 4658, 3725, 0, 5814, 4661, 127760, 194961, 0, 0, 64904, 0, 10833, 0, 0, + 4867, 128717, 0, 11459, 3054, 0, 40996, 0, 7605, 4622, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 19926, 0, 0, 65307, 4617, 0, 0, 0, 4616, 10518, 0, 127160, 0, + 5958, 0, 983449, 4618, 0, 983442, 120675, 4621, 0, 983444, 522, 125213, + 11139, 65803, 194972, 0, 12201, 6135, 121060, 983425, 0, 983093, 0, + 983423, 983416, 983437, 4638, 983421, 0, 78242, 5965, 78240, 66569, + 68646, 0, 983455, 74392, 5335, 0, 0, 4633, 0, 119045, 983451, 4632, 0, + 5542, 5333, 0, 983428, 68648, 5331, 4634, 0, 92870, 5338, 4637, 0, 0, + 43477, 0, 42493, 0, 42361, 0, 0, 73853, 0, 0, 0, 74204, 11343, 0, 10358, + 10422, 4758, 0, 1608, 5252, 0, 0, 4753, 78239, 11344, 78237, 0, 5231, + 74384, 0, 0, 118676, 0, 0, 0, 0, 71991, 5229, 4757, 0, 0, 5227, 4752, 0, + 65235, 5234, 73044, 0, 0, 0, 0, 0, 0, 7460, 0, 917936, 0, 0, 74760, + 65189, 0, 92230, 0, 0, 5574, 128980, 0, 65139, 5577, 0, 0, 118871, 68641, + 8965, 7635, 0, 5316, 70021, 5314, 74555, 5572, 0, 5312, 0, 5525, 5330, + 5319, 68292, 0, 65066, 0, 0, 983496, 0, 0, 127851, 0, 74851, 0, 0, 64609, + 0, 0, 128593, 0, 129339, 0, 8632, 0, 0, 0, 195012, 5735, 195013, 1692, + 70151, 4610, 122653, 4305, 0, 4609, 43478, 4614, 77753, 118534, 5287, + 5309, 5285, 0, 5961, 4647, 5283, 10743, 0, 71889, 601, 4613, 77759, 0, + 9208, 4608, 74044, 71107, 5190, 0, 0, 92410, 43965, 2265, 0, 0, 0, 0, 0, + 0, 0, 129953, 0, 0, 5960, 0, 8992, 65293, 0, 1782, 0, 0, 0, 0, 0, 5501, + 0, 42508, 69759, 120749, 129120, 0, 195023, 77740, 43900, 77741, 0, 68134, 111180, 74209, 0, 64740, 0, 0, 0, 983935, 3767, 5737, 0, 4865, 0, 5740, 0, 5736, 7724, 0, 7193, 0, 0, 5739, 77744, 4866, 0, 0, 0, 4869, - 67093, 0, 0, 128514, 6650, 983485, 0, 983476, 78376, 4870, 0, 68661, - 6716, 983475, 2190, 69786, 68676, 0, 10122, 4864, 66568, 0, 0, 0, 9603, - 68652, 126213, 42734, 745, 0, 0, 0, 4777, 0, 77788, 68631, 42775, 68196, - 0, 0, 0, 0, 5966, 0, 4778, 127890, 0, 0, 4781, 127196, 64407, 0, 74132, - 8577, 71221, 0, 71223, 0, 4782, 0, 0, 120757, 68618, 43472, 43056, 68622, - 0, 92986, 4776, 0, 11492, 0, 0, 13176, 0, 0, 0, 0, 0, 0, 0, 4849, 8242, - 9561, 73922, 0, 0, 0, 0, 5963, 0, 125201, 0, 4850, 72121, 0, 590, 4853, - 0, 4854, 0, 5164, 0, 1605, 5124, 0, 111165, 0, 8471, 0, 111164, 12445, - 3785, 0, 111162, 0, 0, 4848, 2530, 0, 2068, 1964, 0, 0, 10796, 0, 0, 0, - 0, 0, 4794, 0, 0, 0, 4797, 68040, 111152, 43465, 4792, 0, 0, 0, 0, 0, - 110842, 983101, 92963, 0, 0, 0, 4221, 92360, 118869, 0, 0, 0, 70042, 0, - 0, 0, 0, 10739, 65090, 0, 119327, 126541, 0, 0, 119326, 0, 0, 4937, - 43376, 0, 0, 10597, 983442, 11722, 9248, 129566, 42879, 11725, 0, 0, - 7579, 11141, 73958, 4941, 0, 917538, 9140, 4936, 5261, 0, 0, 72298, 0, - 4942, 0, 4938, 0, 0, 5259, 9369, 983431, 111182, 5257, 0, 6844, 4964, - 5264, 0, 0, 0, 41411, 0, 121473, 73684, 128233, 9482, 4873, 41991, 64707, - 42526, 127989, 64480, 64725, 983444, 0, 0, 0, 0, 0, 0, 73043, 0, 389, - 10893, 7521, 0, 4872, 5463, 0, 3125, 111124, 0, 4878, 5459, 4604, 0, 0, - 5465, 0, 0, 0, 0, 9563, 0, 0, 128419, 125273, 82963, 0, 0, 0, 67735, 0, - 0, 0, 0, 0, 78179, 0, 129707, 0, 917833, 0, 917836, 0, 0, 3082, 0, 0, 0, - 0, 118621, 7079, 5856, 917842, 5163, 0, 0, 1817, 66724, 0, 0, 10564, - 7763, 13077, 0, 0, 68140, 111137, 0, 77782, 0, 111139, 123548, 77787, - 121457, 0, 0, 0, 983189, 73081, 0, 0, 983117, 983077, 0, 42156, 0, 0, 0, - 983080, 0, 0, 0, 119254, 120693, 0, 69386, 0, 118881, 0, 78189, 0, 78186, - 78188, 0, 0, 0, 0, 110877, 0, 3108, 9745, 0, 0, 0, 118825, 92785, 0, 0, - 0, 0, 10972, 92786, 0, 42768, 715, 983113, 121117, 9453, 5348, 10943, 0, - 983169, 92784, 0, 0, 983153, 0, 0, 11551, 128464, 0, 0, 9051, 0, 71728, - 0, 120791, 119523, 0, 6404, 66458, 68376, 11984, 9156, 65222, 74454, - 78180, 0, 3128, 4789, 5067, 5066, 0, 4784, 0, 8827, 1146, 5065, 78196, - 78192, 78193, 78190, 78191, 5064, 5326, 0, 9450, 5063, 120361, 78200, - 78201, 5062, 69733, 74146, 0, 0, 0, 0, 77992, 0, 3933, 77768, 0, 12337, - 0, 125023, 0, 0, 0, 194759, 0, 0, 82993, 42130, 0, 5151, 917832, 120357, - 0, 93980, 0, 7620, 3800, 0, 0, 0, 127952, 0, 0, 4786, 127991, 4185, 0, - 128742, 0, 983193, 73978, 0, 4593, 77715, 77727, 124909, 0, 110715, - 10532, 77732, 110714, 110711, 110712, 64759, 1325, 5166, 9888, 0, 5148, - 0, 0, 78205, 78206, 64140, 78204, 64131, 3119, 917814, 0, 983435, 917820, - 12095, 0, 0, 636, 128002, 0, 983466, 0, 78531, 7836, 42741, 64137, 0, - 118969, 0, 92431, 0, 0, 0, 0, 0, 8618, 0, 11865, 0, 0, 0, 3937, 12312, - 128261, 0, 0, 0, 912, 6349, 4536, 71964, 0, 126594, 0, 0, 0, 3935, - 120665, 0, 0, 0, 0, 118859, 0, 121116, 0, 0, 12046, 12599, 0, 0, 0, 0, - 7227, 0, 0, 0, 983066, 0, 0, 0, 113817, 2179, 78246, 0, 0, 0, 0, 0, - 127405, 101531, 0, 101530, 43907, 0, 0, 0, 0, 4644, 8818, 0, 0, 0, 0, - 93066, 66452, 126081, 1644, 101043, 9658, 43744, 11385, 65947, 983173, - 43983, 0, 0, 0, 8962, 0, 0, 2466, 42039, 67669, 0, 0, 42117, 100698, 0, - 0, 0, 0, 43745, 5318, 0, 77723, 0, 0, 0, 7054, 64147, 0, 917804, 68195, - 6698, 0, 0, 0, 70849, 11981, 12202, 0, 121364, 0, 7059, 11608, 975, 0, - 65843, 170, 0, 67239, 42708, 0, 0, 6058, 0, 0, 0, 70507, 0, 0, 9818, 0, - 0, 42106, 0, 983065, 4738, 42105, 7062, 0, 4737, 11779, 4742, 120564, - 92391, 0, 41374, 41375, 983378, 6715, 12700, 7049, 983376, 0, 0, 0, 4741, - 42108, 983367, 64159, 4736, 64148, 0, 849, 0, 128247, 983363, 0, 120913, - 917997, 0, 983381, 9496, 66371, 983405, 983379, 11322, 0, 93008, 3928, - 983152, 0, 10706, 7198, 0, 4842, 12053, 0, 0, 4841, 0, 4171, 12008, - 68416, 3923, 1490, 0, 0, 983395, 40972, 5245, 72288, 983397, 126578, 0, - 4845, 8332, 40974, 0, 4840, 9077, 2252, 2408, 72851, 4825, 0, 917574, 0, - 0, 126251, 0, 0, 983355, 0, 983356, 0, 4826, 42440, 0, 0, 1274, 0, 74315, - 0, 120384, 118614, 121200, 0, 0, 0, 4830, 983390, 129044, 0, 0, 119082, - 0, 64105, 0, 0, 4824, 120397, 0, 0, 1888, 64127, 7861, 125111, 78524, - 41836, 110613, 10873, 72439, 0, 64098, 12214, 0, 41834, 0, 358, 128120, - 41833, 11442, 0, 0, 0, 0, 64115, 0, 0, 0, 120721, 119053, 0, 119055, - 119054, 0, 0, 0, 0, 4017, 12827, 5241, 0, 73042, 41118, 3924, 0, 11366, - 0, 0, 0, 0, 41116, 69455, 0, 0, 0, 0, 11917, 0, 74000, 4721, 123551, - 983937, 0, 0, 0, 0, 0, 0, 122907, 0, 128702, 4722, 6816, 124974, 0, 4725, - 67099, 4726, 0, 129856, 123171, 0, 123194, 0, 0, 0, 4015, 0, 8052, 78766, - 123538, 0, 128294, 0, 0, 4720, 73090, 125003, 0, 0, 1656, 41831, 0, 0, - 41843, 92846, 0, 1452, 13111, 0, 0, 0, 8552, 64113, 41845, 64073, 120354, - 0, 0, 120066, 120067, 7064, 64070, 9948, 0, 0, 0, 92828, 2420, 92811, 0, - 0, 0, 120052, 120053, 120050, 74920, 3938, 120057, 120054, 92829, 120060, - 71920, 120058, 120059, 120064, 72203, 7955, 64074, 4713, 128196, 983107, - 0, 0, 0, 65152, 10198, 120044, 120045, 120042, 6713, 4532, 120049, - 120046, 120047, 4717, 7046, 0, 66450, 4712, 75055, 0, 121085, 0, 8155, - 4718, 3942, 4714, 9625, 0, 6383, 0, 12006, 0, 0, 0, 0, 0, 65414, 0, 0, - 129061, 66437, 66025, 74115, 0, 0, 11228, 4809, 0, 68211, 72352, 0, 0, 0, + 67093, 0, 0, 128514, 6650, 983488, 0, 983479, 78376, 4870, 0, 68661, + 6716, 983478, 2190, 69786, 68676, 0, 10122, 4864, 66568, 0, 0, 0, 9603, + 68652, 126213, 42734, 745, 0, 124131, 124130, 4777, 0, 77788, 68631, + 42775, 68196, 0, 124128, 124129, 0, 5966, 0, 4778, 127890, 0, 0, 4781, + 127196, 64407, 0, 74132, 8577, 71221, 0, 71223, 0, 4782, 0, 0, 120757, + 68618, 43472, 43056, 68622, 0, 92986, 4776, 0, 11492, 0, 0, 13176, 0, 0, + 0, 73558, 0, 0, 0, 4849, 8242, 9561, 73922, 0, 0, 0, 0, 5963, 0, 125201, + 0, 4850, 72121, 0, 590, 4853, 0, 4854, 0, 5164, 0, 1605, 5124, 0, 111165, + 0, 8471, 0, 111164, 12445, 3785, 0, 111162, 0, 0, 4848, 2530, 0, 2068, + 1964, 0, 0, 10796, 0, 0, 0, 0, 0, 4794, 0, 0, 0, 4797, 68040, 111152, + 43465, 4792, 0, 0, 0, 0, 0, 110842, 983102, 92963, 0, 0, 0, 4221, 92360, + 118869, 0, 0, 0, 70042, 0, 0, 0, 0, 10739, 65090, 0, 119327, 126541, 0, + 0, 119326, 0, 0, 4937, 43376, 0, 0, 10597, 983445, 11722, 9248, 129566, + 42879, 11725, 0, 0, 7579, 11141, 73958, 4941, 0, 917538, 9140, 4936, + 5261, 0, 0, 72298, 0, 4942, 0, 4938, 0, 0, 5259, 9369, 983434, 111182, + 5257, 78932, 6844, 4964, 5264, 0, 0, 0, 41411, 0, 121473, 73684, 128233, + 9482, 4873, 41991, 64707, 42526, 127989, 64480, 64725, 983447, 0, 0, 0, + 0, 0, 0, 73043, 0, 389, 10893, 7521, 0, 4872, 5463, 0, 3125, 111124, 0, + 4878, 5459, 4604, 0, 0, 5465, 0, 0, 0, 0, 9563, 0, 0, 128419, 125273, + 82963, 0, 0, 0, 67735, 0, 0, 0, 0, 0, 73560, 0, 129707, 0, 917833, 0, + 917836, 0, 0, 3082, 0, 0, 0, 0, 118621, 7079, 5856, 917842, 5163, 0, 0, + 1817, 66724, 0, 0, 10564, 7763, 13077, 124115, 0, 68140, 111137, 0, + 77782, 0, 111139, 123548, 77787, 121457, 0, 0, 0, 983190, 73081, 0, 0, + 983118, 124114, 0, 42156, 0, 0, 0, 983080, 0, 0, 0, 119254, 120693, 0, + 69386, 0, 118881, 0, 78189, 0, 78186, 78188, 129654, 0, 0, 0, 110877, 0, + 3108, 9745, 0, 0, 0, 118825, 92785, 0, 122954, 0, 0, 10972, 92786, 0, + 42768, 715, 983114, 121117, 9453, 5348, 10943, 0, 983170, 92784, 0, 0, + 983154, 0, 0, 11551, 128464, 0, 0, 9051, 0, 71728, 0, 120791, 119523, 0, + 6404, 66458, 68376, 11984, 9156, 65222, 74454, 78180, 0, 3128, 4789, + 5067, 5066, 0, 4784, 0, 8827, 1146, 5065, 78196, 78192, 78193, 78190, + 78191, 5064, 5326, 0, 9450, 5063, 120361, 78200, 78201, 5062, 69733, + 74146, 0, 0, 0, 0, 77992, 0, 3933, 77768, 0, 12337, 0, 125023, 0, 0, 0, + 194759, 0, 0, 82993, 42130, 0, 5151, 917832, 120357, 0, 73523, 0, 7620, + 3800, 0, 0, 0, 127952, 0, 0, 4786, 127991, 4185, 0, 128742, 0, 983194, + 73978, 0, 4593, 77715, 77727, 124909, 0, 110715, 10532, 77732, 110714, + 110711, 110712, 64759, 1325, 5166, 9888, 0, 5148, 0, 0, 78205, 78206, + 64140, 78204, 64131, 3119, 917814, 0, 983438, 917820, 12095, 0, 0, 636, + 128002, 0, 983469, 0, 78531, 7836, 42741, 64137, 0, 118969, 0, 92431, 0, + 0, 0, 0, 0, 8618, 0, 11865, 0, 0, 0, 3937, 12312, 128261, 0, 0, 0, 912, + 6349, 4536, 71964, 0, 126594, 0, 0, 0, 3935, 120665, 0, 0, 0, 0, 118859, + 0, 121116, 0, 0, 12046, 12599, 0, 0, 0, 0, 7227, 0, 0, 0, 983066, 0, 0, + 0, 113817, 2179, 78246, 0, 0, 0, 0, 0, 127405, 101531, 0, 101530, 43907, + 0, 0, 0, 0, 4644, 8818, 0, 0, 0, 0, 93066, 66452, 126081, 1644, 101043, + 9658, 43744, 11385, 65947, 983174, 43983, 0, 0, 0, 8962, 0, 0, 2466, + 42039, 67669, 0, 0, 42117, 100698, 0, 0, 0, 0, 43745, 5318, 0, 77723, 0, + 0, 0, 7054, 64147, 0, 917804, 68195, 6698, 0, 0, 0, 70849, 11981, 12202, + 0, 121364, 0, 7059, 11608, 975, 0, 65843, 170, 0, 67239, 42708, 0, 0, + 6058, 0, 0, 0, 70507, 0, 0, 9818, 0, 0, 42106, 0, 983065, 4738, 42105, + 7062, 0, 4737, 11779, 4742, 120564, 92391, 0, 41374, 41375, 983381, 6715, + 12700, 7049, 983379, 0, 0, 0, 4741, 42108, 983370, 64159, 4736, 64148, 0, + 849, 0, 128247, 983366, 0, 120913, 917997, 0, 983384, 9496, 66371, + 983408, 983382, 11322, 0, 93008, 3928, 983153, 0, 10706, 7198, 0, 4842, + 12053, 0, 0, 4841, 0, 4171, 12008, 68416, 3923, 1490, 0, 0, 983398, + 40972, 5245, 72288, 983400, 126578, 0, 4845, 8332, 40974, 0, 4840, 9077, + 2252, 2408, 72851, 4825, 0, 917574, 0, 0, 126251, 0, 0, 983358, 0, + 983359, 0, 4826, 42440, 0, 0, 1274, 0, 74315, 0, 120384, 118614, 121200, + 0, 0, 0, 4830, 983393, 129044, 0, 0, 119082, 0, 64105, 0, 0, 4824, + 120397, 0, 0, 1888, 64127, 7861, 125111, 78524, 41836, 110613, 10873, + 72439, 0, 64098, 12214, 124134, 41834, 0, 358, 128120, 41833, 11442, 0, + 0, 0, 0, 64115, 0, 0, 0, 120721, 119053, 0, 119055, 119054, 0, 0, 0, 0, + 4017, 12827, 5241, 0, 73042, 41118, 3924, 0, 11366, 0, 0, 0, 0, 41116, + 69455, 0, 0, 0, 0, 11917, 0, 74000, 4721, 123551, 983937, 0, 0, 0, 0, 0, + 0, 122907, 0, 128702, 4722, 6816, 124974, 0, 4725, 67099, 4726, 0, + 129856, 123171, 0, 123194, 0, 0, 0, 4015, 0, 8052, 78766, 123538, 0, + 128294, 0, 0, 4720, 73090, 125003, 0, 0, 1656, 41831, 0, 0, 41843, 92846, + 0, 1452, 13111, 0, 0, 0, 8552, 64113, 41845, 64073, 120354, 0, 0, 120066, + 120067, 7064, 64070, 9948, 0, 0, 0, 92828, 2420, 92811, 0, 0, 0, 120052, + 120053, 120050, 74920, 3938, 120057, 120054, 92829, 120060, 71920, + 120058, 120059, 120064, 72203, 7955, 64074, 4713, 128196, 983108, 0, 0, + 0, 65152, 10198, 120044, 120045, 120042, 6713, 4532, 120049, 120046, + 120047, 4717, 7046, 0, 66450, 4712, 75055, 0, 121085, 0, 8155, 4718, + 3942, 4714, 9625, 0, 6383, 0, 12006, 0, 0, 0, 0, 0, 65414, 0, 0, 129061, + 66437, 66025, 74115, 0, 0, 11228, 4809, 0, 68211, 72352, 0, 0, 983101, 65405, 129912, 0, 0, 2163, 4545, 0, 917566, 0, 4813, 78699, 0, 0, 4808, 0, 0, 65475, 0, 0, 4814, 72240, 4810, 0, 0, 68784, 10761, 67514, 3522, 0, 78693, 65404, 0, 0, 0, 0, 0, 6691, 70125, 0, 126223, 0, 0, 0, 43858, @@ -29683,35 +29883,35 @@ static const unsigned int code_hash[] = { 2315, 0, 1938, 0, 0, 0, 0, 0, 0, 0, 111135, 93794, 0, 0, 0, 93810, 0, 2291, 0, 0, 0, 0, 129429, 0, 10799, 0, 0, 66372, 0, 4193, 0, 0, 983057, 7998, 0, 0, 0, 0, 2316, 0, 0, 0, 0, 120106, 0, 0, 74140, 0, 0, 0, 0, - 3762, 93813, 120672, 93820, 0, 0, 0, 70098, 3780, 12808, 8163, 983154, 0, + 3762, 93813, 120672, 93820, 0, 0, 0, 70098, 3780, 12808, 8163, 983155, 0, 0, 3906, 12349, 0, 8326, 0, 65498, 3763, 0, 5618, 0, 3779, 0, 43613, 0, - 128007, 0, 0, 0, 0, 280, 0, 126252, 983450, 13072, 1894, 0, 0, 65478, - 43310, 7231, 0, 11773, 0, 0, 0, 101517, 0, 0, 7559, 11652, 10009, 110765, - 110766, 110763, 110764, 4470, 110762, 0, 0, 983443, 0, 5249, 0, 0, 8756, - 0, 0, 41694, 120585, 92349, 0, 0, 0, 69685, 123549, 983447, 113794, 0, - 6808, 41319, 13125, 66332, 127977, 0, 2290, 0, 983415, 0, 0, 3943, 0, - 41205, 0, 0, 0, 0, 5352, 0, 0, 41207, 0, 7384, 69647, 41204, 123552, - 41209, 69637, 0, 43607, 0, 0, 5420, 0, 10134, 0, 0, 4018, 7150, 0, 0, 0, - 0, 0, 129606, 2561, 65023, 0, 7148, 12076, 0, 0, 129201, 0, 6276, 1706, - 0, 0, 7146, 0, 128277, 41819, 74991, 0, 10847, 41822, 72248, 860, 0, 0, - 0, 69641, 10753, 41820, 126118, 0, 71898, 0, 92617, 128567, 0, 121514, - 43016, 0, 0, 92225, 0, 0, 0, 0, 4022, 0, 0, 110807, 0, 41691, 0, 75060, - 11866, 0, 65292, 0, 110812, 0, 3911, 110811, 110808, 110809, 0, 125191, - 7000, 3904, 118997, 72261, 0, 0, 0, 13123, 10846, 0, 0, 0, 0, 0, 74082, - 0, 123542, 0, 0, 3777, 128329, 0, 9636, 71726, 0, 0, 9367, 593, 0, 3999, - 0, 41713, 0, 0, 67677, 0, 0, 0, 9763, 120280, 120283, 12347, 124, 12981, - 41127, 92527, 0, 0, 0, 0, 0, 43987, 0, 0, 1769, 41715, 2463, 2151, 0, 0, - 71222, 1538, 93044, 0, 0, 123543, 7795, 120300, 0, 92493, 10955, 0, 0, - 72375, 78208, 9498, 78207, 127033, 78210, 120288, 3939, 120290, 120285, - 8943, 120287, 120286, 120297, 4491, 120299, 42602, 120293, 120292, - 120295, 120294, 0, 0, 0, 0, 0, 0, 1511, 9324, 0, 0, 0, 0, 0, 64536, 0, 0, - 0, 124935, 6822, 12862, 0, 0, 42143, 41828, 0, 917629, 70864, 118879, 0, - 0, 0, 41826, 128413, 0, 0, 13279, 7917, 0, 0, 0, 0, 0, 92800, 92332, 0, - 0, 43515, 0, 0, 0, 4013, 0, 66980, 0, 72224, 125266, 0, 68243, 2432, - 92834, 0, 0, 0, 0, 69952, 0, 0, 0, 10949, 0, 0, 0, 0, 0, 0, 0, 128574, - 43233, 0, 42517, 0, 0, 0, 0, 0, 64468, 119359, 6474, 119358, 43497, - 12656, 128122, 119353, 0, 1665, 0, 0, 0, 64512, 0, 0, 5256, 0, 0, 0, - 2859, 123563, 0, 0, 0, 0, 92801, 128220, 0, 770, 0, 811, 0, 0, 917551, + 128007, 0, 0, 0, 0, 280, 0, 126252, 983453, 13072, 1894, 0, 0, 65478, + 43310, 7231, 0, 11773, 0, 0, 0, 101517, 122662, 0, 7559, 11652, 10009, + 110765, 110766, 110763, 110764, 4470, 110762, 0, 0, 983446, 0, 5249, 0, + 0, 8756, 0, 0, 41694, 120585, 92349, 0, 0, 0, 69685, 123549, 983450, + 113794, 0, 6808, 41319, 13125, 66332, 127977, 0, 2290, 0, 983418, 0, 0, + 3943, 0, 41205, 0, 0, 0, 0, 5352, 0, 0, 41207, 0, 7384, 69647, 41204, + 123552, 41209, 69637, 0, 43607, 0, 0, 5420, 0, 10134, 0, 0, 4018, 7150, + 0, 0, 0, 0, 0, 129606, 2561, 65023, 0, 7148, 12076, 0, 0, 129201, 0, + 6276, 1706, 0, 0, 7146, 0, 128277, 41819, 74991, 0, 10847, 41822, 72248, + 860, 0, 0, 0, 69641, 10753, 41820, 126118, 0, 71898, 0, 92617, 128567, 0, + 121514, 43016, 0, 0, 92225, 0, 0, 0, 0, 4022, 0, 0, 110807, 0, 41691, 0, + 75060, 11866, 0, 65292, 0, 110812, 0, 3911, 110811, 110808, 110809, 0, + 125191, 7000, 3904, 118997, 72261, 0, 0, 0, 13123, 10846, 0, 0, 0, 0, 0, + 74082, 0, 123542, 0, 0, 3777, 128329, 0, 9636, 71726, 0, 0, 9367, 593, 0, + 3999, 0, 41713, 0, 0, 67677, 0, 0, 0, 9763, 120280, 120283, 12347, 124, + 12981, 41127, 92527, 0, 0, 0, 0, 0, 43987, 0, 0, 1769, 41715, 2463, 2151, + 0, 0, 71222, 1538, 93044, 0, 0, 123543, 7795, 120300, 0, 92493, 10955, 0, + 0, 72375, 78208, 9498, 78207, 127033, 78210, 120288, 3939, 120290, + 120285, 8943, 120287, 120286, 120297, 4491, 120299, 42602, 120293, + 120292, 120295, 120294, 0, 0, 0, 0, 0, 0, 1511, 9324, 0, 0, 0, 0, 0, + 64536, 0, 0, 0, 124935, 6822, 12862, 0, 0, 42143, 41828, 0, 917629, + 70864, 118879, 0, 0, 0, 41826, 128413, 0, 0, 13279, 7917, 0, 0, 0, 0, 0, + 92800, 92332, 0, 0, 43515, 0, 0, 0, 4013, 0, 66980, 0, 72224, 125266, 0, + 68243, 2432, 92834, 0, 0, 0, 0, 69952, 0, 0, 0, 10949, 0, 0, 0, 0, 0, 0, + 0, 128574, 43233, 0, 42517, 0, 0, 0, 0, 0, 64468, 119359, 6474, 119358, + 43497, 12656, 128122, 119353, 0, 1665, 0, 0, 0, 64512, 0, 0, 5256, 0, 0, + 0, 2859, 123563, 0, 0, 0, 0, 92801, 128220, 0, 770, 0, 811, 0, 0, 917551, 42244, 64427, 0, 72222, 0, 3895, 0, 74341, 12087, 0, 42859, 10193, 3116, 7747, 0, 0, 43496, 0, 0, 0, 0, 41877, 0, 65382, 64614, 0, 64296, 0, 6345, 0, 2663, 0, 121234, 0, 0, 10150, 0, 64308, 1522, 597, 0, 0, 41201, 64731, @@ -29746,19 +29946,19 @@ static const unsigned int code_hash[] = { 0, 67708, 0, 119346, 0, 5959, 0, 0, 66275, 43371, 0, 0, 0, 0, 0, 12769, 69793, 0, 1283, 0, 4779, 0, 3719, 4006, 0, 0, 71186, 68204, 124957, 0, 119331, 43028, 65493, 0, 125058, 5962, 65485, 92616, 0, 43501, 5827, 0, - 120951, 0, 65494, 0, 129365, 0, 0, 43879, 0, 0, 0, 0, 983203, 65467, 0, + 120951, 0, 65494, 0, 129365, 0, 0, 43879, 0, 0, 0, 0, 983205, 65467, 0, 0, 0, 0, 521, 0, 0, 983928, 0, 0, 483, 7096, 0, 0, 928, 0, 0, 0, 0, - 92983, 3989, 73972, 0, 0, 0, 0, 12145, 0, 73932, 0, 0, 3769, 67460, 0, 0, - 0, 0, 0, 65290, 92223, 0, 65855, 0, 0, 0, 0, 128811, 0, 0, 0, 0, 0, 0, - 73838, 0, 0, 13007, 67506, 0, 0, 12661, 7608, 75032, 12213, 0, 0, 0, 0, - 12195, 4001, 3112, 67474, 0, 7590, 0, 0, 421, 0, 0, 0, 4130, 127775, + 92983, 3989, 73972, 122980, 0, 0, 0, 12145, 0, 73932, 0, 0, 3769, 67460, + 0, 0, 0, 0, 0, 65290, 92223, 0, 65855, 0, 0, 0, 0, 128811, 0, 0, 0, 0, 0, + 0, 73838, 0, 0, 13007, 67506, 0, 0, 12661, 7608, 75032, 12213, 0, 0, 0, + 0, 12195, 4001, 3112, 67474, 0, 7590, 0, 0, 421, 0, 0, 0, 4130, 127775, 7595, 42588, 7600, 0, 0, 0, 0, 65851, 42607, 0, 92403, 8680, 0, 42134, 0, 0, 2846, 92605, 0, 0, 0, 0, 12979, 0, 0, 92558, 3740, 69843, 120437, 0, 120451, 65923, 120435, 0, 120434, 0, 93800, 3118, 74265, 93795, 93816, 93823, 93797, 8127, 92912, 93792, 7943, 93821, 93799, 10618, 2584, 93793, 0, 0, 9998, 0, 0, 0, 66350, 0, 0, 0, 121374, 8279, 128169, 0, 4975, 70075, 0, 118675, 1631, 0, 0, 0, 6290, 128994, 66386, 0, 64645, 0, 0, 0, - 0, 0, 9242, 93807, 93802, 93801, 983266, 93803, 3122, 93804, 7793, 0, 0, + 0, 0, 9242, 93807, 93802, 93801, 983269, 93803, 3122, 93804, 7793, 0, 0, 0, 0, 12604, 92885, 6615, 67650, 0, 3986, 44025, 0, 8912, 0, 7409, 0, 0, 0, 0, 0, 0, 8540, 11498, 0, 0, 0, 0, 0, 13060, 120682, 0, 0, 0, 0, 0, 121345, 0, 0, 7020, 120353, 3765, 92881, 0, 1606, 120348, 120351, 3093, @@ -29768,150 +29968,151 @@ static const unsigned int code_hash[] = { 42758, 12196, 128429, 0, 0, 0, 0, 128867, 94179, 0, 3120, 9797, 0, 0, 11086, 10389, 0, 101025, 4895, 128153, 124941, 4359, 0, 0, 3509, 70037, 486, 0, 0, 0, 0, 0, 7004, 0, 0, 0, 0, 4855, 128200, 0, 0, 0, 0, 0, 0, - 10381, 70839, 0, 0, 0, 0, 125121, 70837, 125070, 129431, 983374, 983362, - 0, 983361, 0, 120063, 0, 0, 0, 75048, 0, 74900, 0, 0, 120978, 12161, - 983353, 0, 10339, 0, 77808, 0, 0, 0, 77806, 0, 43032, 125010, 0, 983380, - 12671, 11384, 0, 0, 120901, 64797, 0, 5820, 0, 0, 0, 0, 0, 120650, 42137, - 9893, 8851, 12664, 0, 0, 13192, 0, 41799, 65530, 0, 0, 43039, 3114, 0, 0, - 0, 0, 0, 926, 77803, 72004, 77805, 77799, 77800, 77801, 77802, 43037, - 41798, 77797, 77798, 123214, 41801, 0, 0, 0, 4200, 12699, 8331, 70118, - 3091, 92980, 66298, 70293, 8360, 0, 78044, 0, 4229, 64543, 126227, 65563, - 0, 129310, 2861, 43793, 10095, 121428, 9195, 121381, 121132, 0, 129578, - 0, 0, 43041, 0, 43794, 0, 83167, 0, 43797, 8209, 0, 129132, 12973, 0, 0, - 0, 0, 0, 121235, 5760, 0, 743, 0, 0, 0, 118712, 0, 0, 83170, 128589, - 129537, 0, 119063, 0, 0, 0, 19919, 0, 64532, 0, 43710, 0, 0, 9483, 71115, - 0, 43697, 0, 0, 83211, 0, 0, 0, 7247, 0, 0, 0, 0, 0, 113674, 0, 7471, - 120823, 128743, 12682, 0, 0, 65679, 983143, 0, 0, 83201, 1099, 74241, 0, - 10501, 0, 0, 113743, 0, 64743, 128476, 67663, 0, 0, 92219, 0, 83197, - 64897, 9973, 1818, 0, 0, 8272, 127812, 0, 4218, 3087, 0, 127234, 0, - 101300, 65181, 9954, 10465, 0, 0, 0, 9106, 0, 67406, 0, 0, 0, 0, 43038, - 0, 0, 265, 0, 0, 0, 0, 0, 0, 69405, 0, 59, 0, 0, 0, 0, 126239, 41810, 0, - 126492, 0, 41809, 41888, 0, 41795, 0, 42213, 0, 0, 43033, 511, 42963, 0, - 13127, 0, 0, 0, 0, 111107, 0, 4467, 41812, 41215, 0, 41211, 917783, 4453, - 69575, 0, 129883, 0, 983409, 41213, 92864, 118716, 0, 0, 129730, 41841, - 6617, 130041, 0, 92995, 462, 0, 10493, 0, 55248, 0, 0, 74471, 6644, 0, 0, - 0, 983385, 100484, 9581, 67104, 3098, 0, 0, 983412, 125250, 0, 120621, 0, - 0, 0, 129584, 101011, 0, 118789, 74473, 3755, 64661, 7748, 7235, 3966, 0, - 0, 127510, 0, 0, 0, 5726, 66456, 42175, 100486, 0, 42212, 92681, 121443, - 2851, 43017, 120108, 121056, 4373, 0, 0, 9587, 0, 6671, 128840, 3100, 0, - 917790, 0, 0, 0, 917789, 73836, 8190, 12083, 917791, 0, 6689, 64629, 0, - 0, 0, 4419, 917787, 101017, 0, 69851, 0, 0, 8891, 3080, 0, 2347, 0, 0, - 8990, 0, 121201, 0, 92528, 249, 129008, 0, 69424, 0, 0, 0, 55253, 0, 0, - 11173, 995, 0, 121047, 119861, 0, 73708, 0, 0, 19945, 0, 558, 983396, - 12273, 0, 983881, 0, 69912, 120861, 129492, 67274, 94178, 0, 68019, - 43030, 3129, 0, 2102, 0, 0, 121450, 0, 7725, 0, 11120, 0, 126111, 69246, - 0, 0, 0, 41894, 0, 41898, 0, 41893, 74921, 128678, 3540, 11848, 0, 73005, - 120848, 0, 0, 126113, 73959, 0, 0, 128735, 120858, 0, 0, 9699, 128656, - 41896, 0, 83196, 69230, 74951, 0, 72736, 0, 0, 3095, 983689, 11946, - 983885, 0, 0, 0, 0, 0, 113677, 3672, 119864, 0, 0, 0, 128539, 8890, - 93826, 0, 128182, 0, 0, 0, 126568, 0, 0, 983617, 9516, 983438, 72109, 0, - 42220, 0, 4450, 0, 11547, 43417, 128542, 356, 0, 0, 0, 0, 64901, 0, 0, 0, - 0, 0, 0, 111302, 65940, 2541, 71231, 0, 123215, 126470, 3549, 0, 0, 0, - 2743, 0, 0, 0, 9097, 128896, 43015, 0, 0, 776, 2524, 0, 8573, 100665, - 126494, 0, 0, 42694, 71122, 8952, 10814, 118818, 0, 43646, 128598, 66944, - 0, 0, 128380, 100663, 0, 65853, 42707, 1897, 93071, 0, 0, 71907, 69410, - 0, 125106, 0, 0, 0, 68473, 66778, 43573, 92638, 0, 0, 0, 120955, 73986, - 0, 0, 43022, 0, 74841, 0, 67714, 0, 0, 0, 0, 0, 4553, 0, 0, 0, 0, 0, - 19921, 0, 0, 983687, 4567, 41891, 0, 983819, 55249, 194663, 0, 194662, 0, - 194665, 43042, 121291, 1377, 12869, 0, 0, 9250, 0, 0, 0, 129779, 125039, - 194642, 0, 74995, 0, 194644, 0, 0, 101328, 194668, 121166, 0, 70275, - 1898, 69556, 0, 0, 802, 0, 0, 0, 6648, 0, 2528, 0, 0, 194646, 194625, - 101330, 68804, 844, 0, 68824, 0, 68818, 194650, 0, 0, 0, 983743, 65464, - 0, 0, 0, 0, 83221, 0, 0, 100680, 42954, 0, 64371, 70665, 0, 194654, 0, 0, - 0, 0, 0, 6196, 6945, 0, 0, 0, 120491, 0, 68846, 6210, 0, 70274, 0, 0, 0, - 68067, 68834, 194715, 588, 9760, 129112, 0, 983723, 128798, 0, 127992, 0, - 0, 118905, 0, 0, 92485, 110839, 69396, 0, 3394, 70734, 194639, 0, 0, 0, - 0, 0, 0, 194656, 7817, 1841, 11055, 195001, 194979, 194983, 127011, - 67403, 194987, 7701, 194998, 0, 194995, 1946, 121404, 0, 0, 917631, 0, 0, - 10934, 0, 70376, 0, 0, 8071, 3538, 0, 2287, 65328, 0, 0, 7614, 0, 0, 0, - 12009, 43968, 0, 67852, 0, 0, 10841, 123640, 0, 0, 0, 0, 8960, 0, 0, - 65317, 128829, 0, 0, 70374, 0, 0, 0, 65315, 0, 0, 0, 0, 0, 119621, 0, - 11849, 12447, 0, 0, 110741, 0, 0, 0, 129976, 42767, 0, 0, 0, 43695, - 120520, 11975, 194941, 983445, 0, 2555, 0, 128640, 70070, 42936, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 66714, 0, 0, 70076, 65596, 121034, 66710, 67658, - 0, 126994, 65338, 7792, 0, 0, 67871, 119027, 0, 8233, 43572, 0, 0, 0, - 3442, 0, 2841, 12543, 0, 1473, 42820, 64329, 127832, 917772, 126126, - 7937, 0, 1048, 0, 0, 983943, 0, 3406, 1054, 100701, 1040, 65450, 0, - 92329, 1069, 917763, 128367, 128940, 0, 917765, 0, 983724, 9693, 110873, - 0, 0, 0, 983948, 4353, 118653, 1059, 127530, 0, 0, 0, 127093, 118862, - 120500, 10646, 118708, 100710, 917762, 70424, 74830, 0, 0, 983720, 10221, - 100706, 68255, 0, 0, 74346, 119619, 100707, 64945, 12921, 0, 0, 0, 0, 0, - 983795, 43020, 0, 0, 74254, 0, 983785, 0, 0, 983792, 0, 71954, 0, 0, 0, - 0, 122625, 0, 120503, 70663, 0, 2755, 0, 0, 0, 4857, 0, 4428, 0, 0, - 983791, 0, 0, 0, 43842, 0, 122899, 0, 7978, 0, 70392, 127080, 11924, - 43812, 0, 65015, 67472, 563, 68340, 0, 12798, 0, 100727, 0, 0, 0, 74110, - 0, 94051, 0, 694, 0, 9876, 0, 119168, 0, 0, 0, 92361, 0, 0, 7229, 0, 0, - 0, 0, 64811, 0, 119087, 126478, 0, 7381, 0, 2525, 4852, 11586, 68465, - 41605, 126089, 0, 11582, 7151, 10155, 92578, 188, 0, 11592, 0, 74015, 0, - 0, 4858, 122645, 0, 0, 4861, 0, 2786, 121431, 4856, 8051, 0, 119609, 0, - 113797, 71133, 0, 78448, 0, 0, 67842, 68084, 0, 0, 0, 0, 0, 10234, 5843, - 0, 71865, 66728, 0, 3157, 0, 0, 75035, 72788, 983750, 0, 10822, 5149, - 129517, 0, 65142, 129454, 4565, 0, 0, 0, 12657, 0, 0, 386, 0, 8834, - 120974, 0, 43574, 0, 0, 0, 70113, 7220, 11839, 124984, 74883, 194752, 0, - 65241, 74503, 8160, 0, 194753, 0, 0, 0, 0, 0, 121265, 6847, 13303, 0, 0, - 194755, 0, 118865, 0, 194761, 0, 0, 74505, 0, 0, 0, 100518, 194721, 8780, - 100512, 0, 68745, 110626, 66697, 0, 2672, 3735, 983641, 0, 68752, 11205, - 10724, 41202, 0, 100714, 0, 0, 0, 0, 194765, 3842, 0, 78183, 12442, - 78182, 9791, 78181, 0, 42516, 67730, 64821, 195059, 78178, 0, 78464, - 119219, 78465, 127466, 194690, 195063, 0, 0, 0, 0, 78540, 78541, 78538, - 1962, 78490, 78476, 65930, 11660, 0, 2072, 0, 0, 78544, 194704, 78542, - 10669, 110859, 110860, 110857, 110858, 129749, 110856, 4105, 0, 194699, - 0, 0, 0, 13148, 195068, 78479, 9226, 0, 0, 10765, 127486, 71919, 6263, - 195050, 0, 195041, 0, 0, 0, 0, 0, 0, 92312, 7886, 0, 6682, 0, 6680, - 195042, 126473, 195052, 6679, 74412, 0, 72206, 74421, 66281, 0, 0, - 127478, 0, 0, 92861, 6681, 0, 12693, 0, 0, 0, 0, 0, 65442, 129055, 0, - 9989, 74415, 194673, 0, 0, 983788, 0, 0, 0, 0, 7042, 127240, 119026, - 7968, 0, 983768, 194741, 194736, 983793, 0, 69889, 74389, 128696, 0, 0, - 128979, 5781, 0, 78199, 0, 0, 11091, 0, 2719, 0, 0, 0, 64495, 0, 0, 0, - 65169, 42845, 0, 128551, 983766, 2200, 72435, 0, 0, 0, 917855, 66670, 0, - 983709, 0, 0, 0, 7902, 0, 65265, 0, 0, 0, 0, 0, 0, 0, 12994, 0, 10828, - 983974, 0, 4307, 3482, 0, 0, 72389, 0, 64299, 74573, 41194, 7343, 0, 0, - 41195, 0, 8169, 0, 8841, 66770, 516, 72981, 41197, 119051, 34, 128850, - 120186, 11504, 1612, 120187, 120182, 120181, 120184, 12001, 120178, - 120177, 120180, 120179, 71966, 120173, 7749, 120175, 0, 1758, 0, 10667, - 0, 120197, 0, 1935, 11517, 120193, 120196, 120195, 120190, 120189, - 120192, 120191, 1217, 64702, 128075, 825, 0, 0, 0, 0, 66748, 0, 11050, 0, - 123187, 0, 0, 74554, 110577, 0, 8677, 123188, 11313, 123185, 3403, 0, - 123186, 64364, 92683, 0, 0, 0, 0, 123189, 0, 0, 983880, 0, 69408, 41850, - 0, 3433, 127965, 0, 1594, 65607, 0, 66392, 0, 129291, 74565, 41353, - 125119, 0, 0, 0, 0, 918, 127280, 41351, 0, 0, 12140, 0, 12668, 72395, 0, - 128753, 0, 127302, 0, 127288, 129497, 127235, 573, 0, 0, 11417, 0, - 127283, 0, 0, 0, 72410, 0, 11482, 0, 3981, 74345, 0, 0, 0, 0, 0, 0, - 125238, 0, 0, 42195, 0, 123190, 0, 64602, 0, 0, 121366, 0, 121061, - 128690, 0, 8423, 0, 448, 66907, 9717, 0, 0, 0, 0, 0, 0, 0, 71910, 129898, - 0, 0, 120679, 65013, 78169, 0, 72390, 0, 0, 127917, 0, 74892, 0, 0, - 127798, 0, 0, 66982, 0, 0, 0, 12197, 125074, 0, 121447, 0, 0, 0, 0, 0, 0, - 0, 74563, 64828, 11419, 0, 8592, 0, 0, 0, 11381, 0, 0, 74529, 0, 0, - 83254, 0, 72796, 0, 83257, 0, 0, 0, 129437, 65672, 0, 0, 0, 0, 0, 0, 0, - 0, 9505, 0, 0, 756, 0, 125243, 100358, 110852, 7261, 0, 0, 0, 0, 0, - 64401, 65830, 41365, 0, 0, 0, 127834, 0, 0, 0, 0, 0, 74626, 123155, - 11578, 0, 2170, 0, 0, 0, 0, 74568, 0, 113684, 1794, 68310, 120218, - 120219, 120220, 120221, 120222, 120223, 3617, 120011, 64886, 94061, - 78202, 120213, 66999, 10225, 983060, 0, 65223, 983058, 0, 0, 4452, - 127779, 0, 0, 66981, 0, 0, 0, 11425, 0, 0, 1231, 0, 0, 0, 0, 8192, 0, 0, - 0, 10616, 8694, 0, 68867, 128332, 123595, 120200, 120201, 120202, 120203, - 9878, 120205, 119626, 120207, 0, 8799, 42131, 0, 127163, 0, 120198, - 120199, 837, 120015, 72384, 0, 983836, 2180, 11427, 0, 78154, 0, 70171, - 0, 78150, 42606, 0, 119615, 78147, 64637, 78146, 43060, 78145, 125009, - 3392, 0, 194783, 119067, 119650, 65468, 43498, 126083, 0, 0, 0, 194928, - 194937, 194938, 64681, 194930, 83264, 92451, 0, 194955, 83262, 983751, - 8973, 0, 194967, 70177, 194968, 0, 4800, 195018, 0, 0, 11820, 6852, 0, 0, - 4802, 4111, 111268, 0, 4805, 127308, 68193, 7885, 121220, 0, 0, 0, 4767, - 0, 0, 0, 0, 0, 125234, 100366, 43453, 0, 41340, 0, 0, 10005, 65856, - 41333, 0, 9518, 0, 0, 0, 42520, 100850, 0, 0, 917562, 100506, 0, 0, 0, 0, - 0, 0, 9167, 42151, 124958, 0, 2026, 100848, 0, 0, 100534, 12768, 0, 7582, - 0, 0, 0, 0, 129557, 0, 120539, 68879, 0, 43547, 119992, 8546, 126071, - 78520, 7604, 78518, 78519, 78514, 78517, 78511, 78512, 73802, 128140, 0, - 6708, 10535, 0, 68218, 55274, 68221, 92296, 0, 0, 0, 0, 0, 72385, 0, 0, - 0, 73727, 0, 120706, 74442, 66943, 0, 0, 4351, 0, 119887, 119888, 0, - 119886, 119891, 68866, 119889, 11433, 119895, 119896, 0, 119894, 65578, - 194693, 0, 0, 983070, 10681, 0, 0, 128737, 0, 983110, 0, 6722, 129364, 0, - 119997, 41546, 64860, 68394, 0, 41549, 118619, 72386, 0, 0, 0, 0, 64710, - 41547, 0, 0, 0, 78530, 78532, 78528, 78529, 71343, 78527, 78523, 78525, - 3537, 119908, 119905, 7155, 2264, 0, 78533, 67755, 0, 0, 0, 0, 0, 0, 0, - 64715, 0, 0, 537, 0, 4179, 0, 0, 0, 0, 0, 0, 0, 0, 12081, 0, 0, 4048, - 7053, 0, 0, 70459, 0, 124975, 0, 3059, 0, 0, 43491, 983833, 0, 0, 127993, - 4100, 920, 1811, 1355, 0, 0, 64383, 10078, 69398, 0, 118651, 0, 65870, 0, + 10381, 70839, 0, 0, 0, 0, 125121, 70837, 125070, 129431, 983377, 983365, + 0, 983364, 0, 120063, 0, 0, 0, 75048, 0, 74900, 0, 0, 120978, 12161, + 983356, 0, 10339, 0, 77808, 0, 0, 917846, 77806, 0, 43032, 125010, 0, + 983383, 12671, 11384, 0, 0, 120901, 64797, 0, 5820, 0, 0, 0, 0, 0, + 120650, 42137, 9893, 8851, 12664, 0, 0, 13192, 0, 41799, 65530, 0, 0, + 43039, 3114, 0, 0, 0, 0, 0, 926, 77803, 72004, 77805, 77799, 77800, + 77801, 77802, 43037, 41798, 77797, 77798, 123214, 41801, 0, 0, 0, 4200, + 12699, 8331, 70118, 3091, 92980, 66298, 70293, 8360, 0, 78044, 0, 4229, + 64543, 126227, 65563, 0, 129310, 2861, 43793, 10095, 121428, 9195, + 121381, 121132, 0, 129578, 0, 0, 43041, 0, 43794, 0, 83167, 0, 43797, + 8209, 0, 129132, 12973, 0, 0, 0, 0, 0, 121235, 5760, 0, 743, 0, 0, 0, + 118712, 0, 0, 83170, 128589, 129537, 0, 119063, 0, 0, 0, 19919, 0, 64532, + 0, 43710, 0, 0, 9483, 71115, 0, 43697, 0, 0, 83211, 0, 0, 0, 7247, 0, 0, + 0, 0, 0, 113674, 0, 7471, 120823, 128743, 12682, 0, 0, 65679, 983144, 0, + 0, 83201, 1099, 74241, 0, 10501, 0, 0, 113743, 0, 64743, 128476, 67663, + 0, 0, 92219, 0, 83197, 64897, 9973, 1818, 0, 0, 8272, 127812, 0, 4218, + 3087, 0, 127234, 122935, 101300, 65181, 9954, 10465, 0, 0, 0, 9106, 0, + 67406, 0, 0, 0, 0, 43038, 0, 0, 265, 70208, 0, 0, 0, 0, 0, 69405, 0, 59, + 0, 0, 0, 0, 126239, 41810, 0, 126492, 0, 41809, 41888, 0, 41795, 0, + 42213, 0, 0, 43033, 511, 42963, 0, 13127, 0, 0, 0, 0, 111107, 100489, + 4467, 41812, 41215, 0, 41211, 917783, 4453, 69575, 0, 129883, 0, 983412, + 41213, 92864, 118716, 0, 0, 129730, 41841, 6617, 130041, 0, 92995, 462, + 0, 10493, 0, 55248, 0, 0, 74471, 6644, 0, 0, 0, 983388, 100484, 9581, + 67104, 3098, 0, 0, 983415, 125250, 0, 120621, 0, 0, 0, 129584, 101011, 0, + 118789, 74473, 3755, 64661, 7748, 7235, 3966, 0, 0, 127510, 0, 0, 0, + 5726, 66456, 42175, 100486, 0, 42212, 92681, 121443, 2851, 43017, 120108, + 121056, 4373, 0, 0, 9587, 0, 6671, 128840, 3100, 0, 917790, 0, 0, 0, + 917789, 70209, 8190, 12083, 917791, 0, 6689, 64629, 0, 0, 0, 4419, + 917787, 101017, 0, 69851, 0, 0, 8891, 3080, 0, 2347, 0, 0, 8990, 0, + 121201, 0, 92528, 249, 129008, 0, 69424, 0, 0, 0, 55253, 0, 0, 11173, + 995, 0, 121047, 119861, 0, 73708, 0, 0, 19945, 0, 558, 983399, 12273, 0, + 983881, 0, 69912, 120861, 129492, 67274, 94178, 0, 68019, 43030, 3129, 0, + 2102, 0, 0, 121450, 0, 7725, 0, 11120, 0, 126111, 69246, 0, 0, 0, 41894, + 0, 41898, 0, 41893, 74921, 128678, 3540, 11848, 0, 73005, 120848, 0, 0, + 126113, 73959, 0, 0, 128735, 120858, 0, 0, 9699, 128656, 41896, 0, 83196, + 69230, 74951, 0, 72736, 0, 0, 3095, 983689, 11946, 983885, 0, 0, 0, 0, 0, + 113677, 3672, 111309, 0, 0, 0, 128539, 8890, 93826, 0, 128182, 0, 0, 0, + 126568, 0, 0, 983617, 9516, 983441, 72109, 0, 42220, 0, 4450, 0, 11547, + 43417, 128542, 356, 0, 0, 0, 0, 64901, 0, 0, 0, 0, 0, 0, 111302, 65940, + 2541, 71231, 0, 123215, 126470, 3549, 0, 0, 0, 2743, 0, 0, 0, 9097, + 128896, 43015, 0, 0, 776, 2524, 0, 8573, 100665, 126494, 0, 0, 42694, + 71122, 8952, 10814, 118818, 0, 43646, 128598, 66944, 0, 0, 128380, + 100663, 0, 65853, 42707, 1897, 93071, 0, 0, 71907, 69410, 0, 125106, 0, + 0, 0, 68473, 66778, 43573, 92638, 0, 0, 0, 120955, 73986, 0, 0, 43022, 0, + 74841, 0, 67714, 0, 0, 0, 0, 0, 4553, 0, 0, 0, 0, 0, 19921, 0, 0, 983687, + 4567, 41891, 0, 983819, 55249, 194663, 0, 194662, 0, 194665, 43042, + 121291, 1377, 12869, 0, 0, 9250, 0, 0, 0, 129779, 125039, 194642, 0, + 74995, 0, 194644, 0, 0, 101328, 194668, 121166, 0, 70275, 1898, 69556, 0, + 0, 802, 0, 0, 0, 6648, 0, 2528, 0, 0, 194646, 194625, 101330, 68804, 844, + 0, 68824, 0, 68818, 194650, 0, 0, 0, 983743, 65464, 0, 0, 0, 0, 83221, 0, + 0, 100680, 42954, 0, 64371, 70665, 0, 194654, 0, 0, 0, 0, 0, 6196, 6945, + 0, 0, 0, 120491, 0, 68846, 6210, 0, 70274, 0, 0, 0, 68067, 68834, 194715, + 588, 9760, 129112, 0, 983723, 119505, 0, 127992, 0, 0, 118905, 0, 0, + 92485, 110839, 69396, 0, 3394, 70734, 194639, 0, 0, 0, 0, 0, 0, 194656, + 7817, 1841, 11055, 195001, 194979, 194983, 127011, 67403, 194987, 7701, + 194998, 0, 194995, 1946, 121404, 0, 0, 917631, 0, 0, 10934, 0, 70376, 0, + 0, 8071, 3538, 0, 2287, 65328, 0, 0, 7614, 0, 0, 0, 12009, 43968, 0, + 67852, 0, 0, 10841, 123640, 0, 0, 0, 0, 8960, 0, 0, 65317, 128829, 0, 0, + 70374, 0, 0, 0, 65315, 0, 0, 0, 0, 0, 119621, 0, 11849, 12447, 0, 0, + 110741, 0, 0, 0, 129976, 42767, 0, 0, 0, 43695, 120520, 11975, 194941, + 983448, 0, 2555, 0, 128640, 70070, 42936, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 66714, 0, 0, 70076, 65596, 121034, 66710, 67658, 0, 126994, 65338, + 7792, 0, 0, 67871, 119027, 0, 8233, 43572, 0, 0, 0, 3442, 110933, 2841, + 12543, 0, 1473, 42820, 64329, 127832, 917772, 126126, 7937, 0, 1048, 0, + 0, 983943, 0, 3406, 1054, 100701, 1040, 65450, 0, 92329, 1069, 917763, + 128367, 128940, 0, 917765, 0, 983724, 9693, 110873, 0, 0, 0, 983948, + 4353, 118653, 1059, 127530, 0, 0, 0, 127093, 118862, 120500, 10646, + 118708, 100710, 917762, 70424, 74830, 0, 0, 983720, 10221, 100706, 68255, + 0, 0, 74346, 119619, 100707, 64945, 12921, 0, 0, 0, 0, 0, 983795, 43020, + 0, 0, 74254, 0, 983785, 0, 0, 983792, 0, 71954, 0, 0, 0, 0, 122625, 0, + 120503, 70663, 0, 2755, 0, 0, 0, 4857, 0, 4428, 0, 0, 983791, 0, 0, 0, + 43842, 0, 122899, 0, 7978, 0, 70392, 127080, 11924, 43812, 0, 65015, + 67472, 563, 68340, 0, 12798, 0, 100727, 0, 0, 0, 74110, 0, 94051, 0, 694, + 0, 9876, 0, 119168, 0, 0, 0, 92361, 0, 0, 7229, 0, 0, 0, 0, 64811, 0, + 119087, 126478, 0, 7381, 0, 2525, 4852, 11586, 68465, 41605, 126089, 0, + 11582, 7151, 10155, 92578, 188, 0, 11592, 0, 74015, 0, 0, 4858, 122645, + 0, 0, 4861, 0, 2786, 121431, 4856, 8051, 0, 119609, 0, 113797, 71133, 0, + 78448, 0, 0, 67842, 68084, 0, 0, 0, 0, 0, 10234, 5843, 0, 71865, 66728, + 0, 3157, 0, 0, 75035, 72788, 983750, 0, 10822, 5149, 129517, 0, 65142, + 129454, 4565, 0, 0, 0, 12657, 0, 0, 386, 0, 8834, 120974, 0, 43574, 0, 0, + 0, 70113, 7220, 11839, 124984, 74883, 194752, 0, 65241, 74503, 8160, 0, + 194753, 0, 0, 0, 0, 0, 121265, 6847, 13303, 0, 0, 194755, 0, 118865, 0, + 194761, 0, 0, 74505, 0, 0, 0, 100518, 194721, 8780, 100512, 0, 68745, + 110626, 66697, 0, 2672, 3735, 983641, 0, 68752, 11205, 10724, 41202, 0, + 100714, 0, 0, 0, 0, 194765, 3842, 0, 78183, 12442, 78182, 9791, 78181, 0, + 42516, 67730, 64821, 195059, 78178, 0, 78464, 119219, 78465, 127466, + 194690, 195063, 0, 0, 0, 0, 78540, 78541, 78538, 1962, 78490, 78476, + 65930, 11660, 0, 2072, 0, 0, 78544, 194704, 78542, 10669, 110859, 110860, + 110857, 110858, 129749, 110856, 4105, 0, 194699, 0, 0, 0, 13148, 195068, + 78479, 9226, 0, 0, 10765, 127486, 71919, 6263, 195050, 0, 195041, 0, 0, + 0, 0, 0, 0, 92312, 7886, 0, 6682, 0, 6680, 195042, 126473, 195052, 6679, + 74412, 0, 72206, 74421, 66281, 0, 0, 127478, 0, 0, 92861, 6681, 0, 12693, + 0, 0, 0, 0, 0, 65442, 129055, 0, 9989, 74415, 194673, 0, 0, 983788, 0, 0, + 0, 0, 7042, 127240, 119026, 7968, 0, 983768, 194741, 194736, 983793, 0, + 69889, 74389, 128696, 0, 0, 128979, 5781, 0, 78199, 0, 124145, 11091, 0, + 2719, 0, 0, 0, 64495, 0, 0, 0, 65169, 42845, 0, 128551, 983766, 2200, + 72435, 0, 0, 0, 917855, 66670, 0, 983709, 0, 0, 0, 7902, 0, 65265, 0, 0, + 0, 0, 0, 0, 0, 12994, 0, 10828, 983974, 0, 4307, 3482, 0, 0, 72389, 0, + 64299, 74573, 41194, 7343, 0, 0, 41195, 0, 8169, 0, 8841, 66770, 516, + 72981, 41197, 119051, 34, 128850, 120186, 11504, 1612, 120187, 120182, + 120181, 120184, 12001, 120178, 120177, 120180, 120179, 71966, 120173, + 7749, 120175, 0, 1758, 0, 10667, 0, 120197, 0, 1935, 11517, 120193, + 120196, 78925, 120190, 120189, 120192, 120191, 1217, 64702, 128075, 825, + 0, 129824, 0, 0, 66748, 0, 11050, 0, 123187, 0, 0, 74554, 110577, 0, + 8677, 123188, 11313, 123185, 3403, 0, 123186, 64364, 92683, 0, 0, 0, 0, + 123189, 0, 0, 983880, 0, 69408, 41850, 0, 3433, 127965, 0, 1594, 65607, + 0, 66392, 0, 129291, 74565, 41353, 125119, 78926, 0, 0, 0, 918, 127280, + 41351, 0, 0, 12140, 0, 12668, 72395, 0, 128753, 0, 127302, 0, 127288, + 129497, 127235, 573, 0, 0, 11417, 0, 127283, 0, 0, 0, 72410, 0, 11482, 0, + 3981, 74345, 0, 0, 0, 0, 0, 0, 125238, 0, 0, 42195, 0, 123190, 129764, + 64602, 0, 0, 121366, 0, 121061, 128690, 0, 8423, 0, 448, 66907, 9717, 0, + 0, 0, 0, 0, 0, 0, 71910, 129898, 0, 0, 120679, 65013, 78169, 0, 72390, 0, + 0, 127917, 0, 74892, 0, 0, 127798, 0, 0, 66982, 0, 0, 0, 12197, 125074, + 0, 121447, 0, 0, 0, 0, 0, 0, 0, 74563, 64828, 11419, 0, 8592, 0, 0, 0, + 11381, 0, 0, 74529, 0, 0, 83254, 0, 72796, 0, 83257, 0, 0, 0, 129437, + 65672, 0, 0, 0, 0, 0, 0, 0, 0, 9505, 0, 0, 756, 0, 125243, 100358, + 110852, 7261, 0, 0, 0, 0, 0, 64401, 65830, 41365, 0, 0, 0, 127834, 0, 0, + 0, 0, 0, 74626, 123155, 11578, 0, 2170, 0, 0, 0, 0, 74568, 0, 113684, + 1794, 68310, 120218, 120219, 120220, 120221, 120222, 120223, 3617, + 120011, 64886, 94061, 78202, 120213, 66999, 10225, 983060, 0, 65223, + 983058, 0, 0, 4452, 127779, 0, 0, 66981, 0, 0, 0, 11425, 0, 0, 1231, 0, + 0, 0, 124121, 8192, 124118, 0, 0, 10616, 8694, 0, 68867, 128332, 123595, + 120200, 120201, 120202, 120203, 9878, 120205, 119626, 120207, 0, 8799, + 42131, 0, 127163, 0, 120198, 120199, 837, 120015, 72384, 0, 983836, 2180, + 11427, 0, 78154, 0, 70171, 0, 78150, 42606, 0, 119615, 78147, 64637, + 78146, 43060, 78145, 125009, 3392, 0, 194783, 119067, 119650, 65468, + 43498, 126083, 0, 0, 0, 194928, 194937, 194938, 64681, 194930, 83264, + 92451, 0, 194955, 83262, 983751, 8973, 0, 194967, 70177, 194968, 0, 4800, + 195018, 0, 0, 11820, 6852, 122981, 0, 4802, 4111, 111268, 0, 4805, + 127308, 68193, 7885, 121220, 0, 0, 0, 4767, 0, 0, 0, 0, 0, 125234, + 100366, 43453, 0, 41340, 0, 0, 10005, 65856, 41333, 0, 9518, 0, 0, 0, + 42520, 100850, 0, 0, 917562, 100506, 0, 0, 0, 0, 0, 0, 9167, 42151, + 124958, 0, 2026, 100848, 124139, 0, 100534, 12768, 0, 7582, 0, 0, 0, 0, + 129557, 0, 120539, 68879, 0, 43547, 119992, 8546, 126071, 78520, 7604, + 78518, 78519, 78514, 78517, 78511, 78512, 73802, 128140, 0, 6708, 10535, + 0, 68218, 55274, 68221, 92296, 0, 0, 0, 0, 0, 72385, 0, 0, 0, 73727, 0, + 120706, 74442, 66943, 0, 0, 4351, 0, 119887, 119888, 0, 119886, 119891, + 68866, 119889, 11433, 119895, 119896, 0, 119894, 65578, 194693, 0, 0, + 983070, 10681, 0, 0, 128737, 0, 983111, 0, 6722, 129364, 0, 119997, + 41546, 64860, 68394, 0, 41549, 118619, 72386, 0, 0, 0, 0, 64710, 41547, + 0, 0, 0, 78530, 78532, 78528, 78529, 71343, 78527, 78523, 78525, 3537, + 119908, 119905, 7155, 2264, 0, 78533, 67755, 0, 0, 0, 0, 0, 0, 0, 64715, + 0, 0, 537, 0, 4179, 0, 0, 0, 0, 0, 0, 0, 0, 12081, 0, 0, 4048, 7053, 0, + 0, 70459, 0, 124975, 0, 3059, 0, 0, 43491, 983833, 0, 0, 127993, 4100, + 920, 1811, 1355, 0, 0, 64383, 10078, 69398, 0, 118651, 0, 65870, 0, 129565, 0, 72400, 42918, 0, 66789, 0, 12865, 0, 73938, }; @@ -29920,7 +30121,7 @@ static const unsigned int code_hash[] = { #define code_poly 65581 static const unsigned int aliases_start = 0xf0000; -static const unsigned int aliases_end = 0xf01d6; +static const unsigned int aliases_end = 0xf01d9; static const unsigned int name_aliases[] = { 0x0000, 0x0000, @@ -29983,6 +30184,7 @@ static const unsigned int name_aliases[] = { 0x0018, 0x0019, 0x0019, + 0x0019, 0x001A, 0x001A, 0x001B, @@ -30083,6 +30285,7 @@ static const unsigned int name_aliases[] = { 0x01A2, 0x01A3, 0x034F, + 0x0616, 0x061C, 0x0709, 0x0CDE, @@ -30100,6 +30303,7 @@ static const unsigned int name_aliases[] = { 0x180D, 0x180E, 0x180F, + 0x1BBD, 0x200B, 0x200C, 0x200D, diff --git a/Modules/xxlimited.c b/Modules/xxlimited.c index e234504e..3935c00f 100644 --- a/Modules/xxlimited.c +++ b/Modules/xxlimited.c @@ -155,8 +155,7 @@ Xxo_getattro(XxoObject *self, PyObject *name) if (self->x_attr != NULL) { PyObject *v = PyDict_GetItemWithError(self->x_attr, name); if (v != NULL) { - Py_INCREF(v); - return v; + return Py_NewRef(v); } else if (PyErr_Occurred()) { return NULL; @@ -210,18 +209,15 @@ Xxo_demo(XxoObject *self, PyTypeObject *defining_class, /* Test if the argument is "str" */ if (PyUnicode_Check(o)) { - Py_INCREF(o); - return o; + return Py_NewRef(o); } /* test if the argument is of the Xxo class */ if (PyObject_TypeCheck(o, defining_class)) { - Py_INCREF(o); - return o; + return Py_NewRef(o); } - Py_INCREF(Py_None); - return Py_None; + return Py_NewRef(Py_None); } static PyMethodDef Xxo_methods[] = { @@ -394,6 +390,7 @@ xx_modexec(PyObject *m) static PyModuleDef_Slot xx_slots[] = { {Py_mod_exec, xx_modexec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; diff --git a/Modules/xxlimited_35.c b/Modules/xxlimited_35.c index 8d29c719..1ff3ef1c 100644 --- a/Modules/xxlimited_35.c +++ b/Modules/xxlimited_35.c @@ -64,11 +64,9 @@ Xxo_demo(XxoObject *self, PyObject *args) return NULL; /* Test availability of fast type checks */ if (o != NULL && PyUnicode_Check(o)) { - Py_INCREF(o); - return o; + return Py_NewRef(o); } - Py_INCREF(Py_None); - return Py_None; + return Py_NewRef(Py_None); } static PyMethodDef Xxo_methods[] = { @@ -83,8 +81,7 @@ Xxo_getattro(XxoObject *self, PyObject *name) if (self->x_attr != NULL) { PyObject *v = PyDict_GetItemWithError(self->x_attr, name); if (v != NULL) { - Py_INCREF(v); - return v; + return Py_NewRef(v); } else if (PyErr_Occurred()) { return NULL; @@ -176,8 +173,7 @@ xx_roj(PyObject *self, PyObject *args) long b; if (!PyArg_ParseTuple(args, "O#:roj", &a, &b)) return NULL; - Py_INCREF(Py_None); - return Py_None; + return Py_NewRef(Py_None); } @@ -297,6 +293,7 @@ xx_modexec(PyObject *m) static PyModuleDef_Slot xx_slots[] = { {Py_mod_exec, xx_modexec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; diff --git a/Modules/xxmodule.c b/Modules/xxmodule.c index a6e5071d..1e4e0ea3 100644 --- a/Modules/xxmodule.c +++ b/Modules/xxmodule.c @@ -52,8 +52,7 @@ Xxo_demo(XxoObject *self, PyObject *args) { if (!PyArg_ParseTuple(args, ":demo")) return NULL; - Py_INCREF(Py_None); - return Py_None; + return Py_NewRef(Py_None); } static PyMethodDef Xxo_methods[] = { @@ -68,8 +67,7 @@ Xxo_getattro(XxoObject *self, PyObject *name) if (self->x_attr != NULL) { PyObject *v = PyDict_GetItemWithError(self->x_attr, name); if (v != NULL) { - Py_INCREF(v); - return v; + return Py_NewRef(v); } else if (PyErr_Occurred()) { return NULL; @@ -195,8 +193,7 @@ xx_bug(PyObject *self, PyObject *args) printf("\n"); /* Py_DECREF(item); */ - Py_INCREF(Py_None); - return Py_None; + return Py_NewRef(Py_None); } /* Test bad format character */ @@ -208,8 +205,7 @@ xx_roj(PyObject *self, PyObject *args) long b; if (!PyArg_ParseTuple(args, "O#:roj", &a, &b)) return NULL; - Py_INCREF(Py_None); - return Py_None; + return Py_NewRef(Py_None); } @@ -266,8 +262,7 @@ static PyTypeObject Str_Type = { static PyObject * null_richcompare(PyObject *self, PyObject *other, int op) { - Py_INCREF(Py_NotImplemented); - return Py_NotImplemented; + return Py_NewRef(Py_NotImplemented); } static PyTypeObject Null_Type = { @@ -388,6 +383,7 @@ xx_exec(PyObject *m) static struct PyModuleDef_Slot xx_slots[] = { {Py_mod_exec, xx_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL}, }; diff --git a/Modules/xxsubtype.c b/Modules/xxsubtype.c index 12306f2f..9e4a3d66 100644 --- a/Modules/xxsubtype.c +++ b/Modules/xxsubtype.c @@ -39,8 +39,7 @@ spamlist_setstate(spamlistobject *self, PyObject *args) if (!PyArg_ParseTuple(args, "i:setstate", &state)) return NULL; self->state = state; - Py_INCREF(Py_None); - return Py_None; + return Py_NewRef(Py_None); } static PyObject * @@ -53,12 +52,9 @@ spamlist_specialmeth(PyObject *self, PyObject *args, PyObject *kw) self = Py_None; if (kw == NULL) kw = Py_None; - Py_INCREF(self); - PyTuple_SET_ITEM(result, 0, self); - Py_INCREF(args); - PyTuple_SET_ITEM(result, 1, args); - Py_INCREF(kw); - PyTuple_SET_ITEM(result, 2, kw); + PyTuple_SET_ITEM(result, 0, Py_NewRef(self)); + PyTuple_SET_ITEM(result, 1, Py_NewRef(args)); + PyTuple_SET_ITEM(result, 2, Py_NewRef(kw)); } return result; } @@ -164,8 +160,7 @@ spamdict_setstate(spamdictobject *self, PyObject *args) if (!PyArg_ParseTuple(args, "i:setstate", &state)) return NULL; self->state = state; - Py_INCREF(Py_None); - return Py_None; + return Py_NewRef(Py_None); } static PyMethodDef spamdict_methods[] = { @@ -279,20 +274,17 @@ xxsubtype_exec(PyObject* m) if (PyType_Ready(&spamdict_type) < 0) return -1; - Py_INCREF(&spamlist_type); - if (PyModule_AddObject(m, "spamlist", - (PyObject *) &spamlist_type) < 0) + if (PyModule_AddObjectRef(m, "spamlist", (PyObject *)&spamlist_type) < 0) return -1; - Py_INCREF(&spamdict_type); - if (PyModule_AddObject(m, "spamdict", - (PyObject *) &spamdict_type) < 0) + if (PyModule_AddObjectRef(m, "spamdict", (PyObject *)&spamdict_type) < 0) return -1; return 0; } static struct PyModuleDef_Slot xxsubtype_slots[] = { {Py_mod_exec, xxsubtype_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL}, }; diff --git a/Modules/zlibmodule.c b/Modules/zlibmodule.c index 2fc39a3b..b67844a6 100644 --- a/Modules/zlibmodule.c +++ b/Modules/zlibmodule.c @@ -8,6 +8,11 @@ #include "Python.h" #include "structmember.h" // PyMemberDef #include "zlib.h" +#include "stdbool.h" + +#if defined(ZLIB_VERNUM) && ZLIB_VERNUM < 0x1221 +#error "At least zlib version 1.2.2.1 is required" +#endif // Blocks output buffer wrappers #include "pycore_blocks_output_buffer.h" @@ -171,9 +176,6 @@ OutputBuffer_WindowOnError(_BlocksOutputBuffer *buffer, _Uint32Window *window) } } while (0) #define LEAVE_ZLIB(obj) PyThread_release_lock((obj)->lock); -#if defined(ZLIB_VERNUM) && ZLIB_VERNUM >= 0x1221 -# define AT_LEAST_ZLIB_1_2_2_1 -#endif /* The following parameters are copied from zutil.h, version 0.95 */ #define DEFLATED 8 @@ -185,12 +187,14 @@ OutputBuffer_WindowOnError(_BlocksOutputBuffer *buffer, _Uint32Window *window) /* Initial buffer size. */ #define DEF_BUF_SIZE (16*1024) +#define DEF_MAX_INITIAL_BUF_SIZE (16 * 1024 * 1024) static PyModuleDef zlibmodule; typedef struct { PyTypeObject *Comptype; PyTypeObject *Decomptype; + PyTypeObject *ZlibDecompressorType; PyObject *ZlibError; } zlibstate; @@ -209,7 +213,7 @@ typedef struct PyObject *unused_data; PyObject *unconsumed_tail; char eof; - int is_initialised; + bool is_initialised; PyObject *zdict; PyThread_type_lock lock; } compobject; @@ -320,7 +324,7 @@ static PyObject * zlib_compress_impl(PyObject *module, Py_buffer *data, int level, int wbits) /*[clinic end generated code: output=46bd152fadd66df2 input=c4d06ee5782a7e3f]*/ { - PyObject *RetVal; + PyObject *return_value; int flush; z_stream zst; _BlocksOutputBuffer buffer = {.list = NULL}; @@ -387,11 +391,11 @@ zlib_compress_impl(PyObject *module, Py_buffer *data, int level, int wbits) err = deflateEnd(&zst); if (err == Z_OK) { - RetVal = OutputBuffer_Finish(&buffer, zst.avail_out); - if (RetVal == NULL) { + return_value = OutputBuffer_Finish(&buffer, zst.avail_out); + if (return_value == NULL) { goto error; } - return RetVal; + return return_value; } else zlib_error(state, zst, err, "while finishing compression"); @@ -419,7 +423,7 @@ zlib_decompress_impl(PyObject *module, Py_buffer *data, int wbits, Py_ssize_t bufsize) /*[clinic end generated code: output=77c7e35111dc8c42 input=a9ac17beff1f893f]*/ { - PyObject *RetVal; + PyObject *return_value; Byte *ibuf; Py_ssize_t ibuflen; int err, flush; @@ -514,9 +518,9 @@ zlib_decompress_impl(PyObject *module, Py_buffer *data, int wbits, goto error; } - RetVal = OutputBuffer_WindowFinish(&buffer, &window, zst.avail_out); - if (RetVal != NULL) { - return RetVal; + return_value = OutputBuffer_WindowFinish(&buffer, &window, zst.avail_out); + if (return_value != NULL) { + return return_value; } error: @@ -667,26 +671,17 @@ zlib_decompressobj_impl(PyObject *module, int wbits, PyObject *zdict) self->zst.next_in = NULL; self->zst.avail_in = 0; if (zdict != NULL) { - Py_INCREF(zdict); - self->zdict = zdict; + self->zdict = Py_NewRef(zdict); } int err = inflateInit2(&self->zst, wbits); switch (err) { case Z_OK: self->is_initialised = 1; if (self->zdict != NULL && wbits < 0) { -#ifdef AT_LEAST_ZLIB_1_2_2_1 if (set_inflate_zdict(state, self) < 0) { Py_DECREF(self); return NULL; } -#else - PyErr_Format(state->ZlibError, - "zlib version %s does not allow raw inflate with dictionary", - ZLIB_VERSION); - Py_DECREF(self); - return NULL; -#endif } return (PyObject *)self; case Z_STREAM_ERROR: @@ -753,7 +748,7 @@ zlib_Compress_compress_impl(compobject *self, PyTypeObject *cls, Py_buffer *data) /*[clinic end generated code: output=6731b3f0ff357ca6 input=04d00f65ab01d260]*/ { - PyObject *RetVal; + PyObject *return_value; int err; _BlocksOutputBuffer buffer = {.list = NULL}; zlibstate *state = PyType_GetModuleState(cls); @@ -791,17 +786,17 @@ zlib_Compress_compress_impl(compobject *self, PyTypeObject *cls, } while (ibuflen != 0); - RetVal = OutputBuffer_Finish(&buffer, self->zst.avail_out); - if (RetVal != NULL) { + return_value = OutputBuffer_Finish(&buffer, self->zst.avail_out); + if (return_value != NULL) { goto success; } error: OutputBuffer_OnError(&buffer); - RetVal = NULL; + return_value = NULL; success: LEAVE_ZLIB(self); - return RetVal; + return return_value; } /* Helper for objdecompress() and flush(). Saves any unconsumed input data in @@ -875,7 +870,7 @@ zlib_Decompress_decompress_impl(compobject *self, PyTypeObject *cls, { int err = Z_OK; Py_ssize_t ibuflen; - PyObject *RetVal; + PyObject *return_value; _BlocksOutputBuffer buffer = {.list = NULL}; PyObject *module = PyType_GetModule(cls); @@ -953,17 +948,17 @@ zlib_Decompress_decompress_impl(compobject *self, PyTypeObject *cls, goto abort; } - RetVal = OutputBuffer_Finish(&buffer, self->zst.avail_out); - if (RetVal != NULL) { + return_value = OutputBuffer_Finish(&buffer, self->zst.avail_out); + if (return_value != NULL) { goto success; } abort: OutputBuffer_OnError(&buffer); - RetVal = NULL; + return_value = NULL; success: LEAVE_ZLIB(self); - return RetVal; + return return_value; } /*[clinic input] @@ -985,7 +980,7 @@ zlib_Compress_flush_impl(compobject *self, PyTypeObject *cls, int mode) /*[clinic end generated code: output=c7efd13efd62add2 input=286146e29442eb6c]*/ { int err; - PyObject *RetVal; + PyObject *return_value; _BlocksOutputBuffer buffer = {.list = NULL}; zlibstate *state = PyType_GetModuleState(cls); @@ -1042,17 +1037,17 @@ zlib_Compress_flush_impl(compobject *self, PyTypeObject *cls, int mode) goto error; } - RetVal = OutputBuffer_Finish(&buffer, self->zst.avail_out); - if (RetVal != NULL) { + return_value = OutputBuffer_Finish(&buffer, self->zst.avail_out); + if (return_value != NULL) { goto success; } error: OutputBuffer_OnError(&buffer); - RetVal = NULL; + return_value = NULL; success: LEAVE_ZLIB(self); - return RetVal; + return return_value; } #ifdef HAVE_ZLIB_COPY @@ -1071,14 +1066,14 @@ zlib_Compress_copy_impl(compobject *self, PyTypeObject *cls) { zlibstate *state = PyType_GetModuleState(cls); - compobject *retval = newcompobject(state->Comptype); - if (!retval) return NULL; + compobject *return_value = newcompobject(state->Comptype); + if (!return_value) return NULL; /* Copy the zstream state * We use ENTER_ZLIB / LEAVE_ZLIB to make this thread-safe */ ENTER_ZLIB(self); - int err = deflateCopy(&retval->zst, &self->zst); + int err = deflateCopy(&return_value->zst, &self->zst); switch (err) { case Z_OK: break; @@ -1093,23 +1088,20 @@ zlib_Compress_copy_impl(compobject *self, PyTypeObject *cls) zlib_error(state, self->zst, err, "while copying compression object"); goto error; } - Py_INCREF(self->unused_data); - Py_XSETREF(retval->unused_data, self->unused_data); - Py_INCREF(self->unconsumed_tail); - Py_XSETREF(retval->unconsumed_tail, self->unconsumed_tail); - Py_XINCREF(self->zdict); - Py_XSETREF(retval->zdict, self->zdict); - retval->eof = self->eof; + Py_XSETREF(return_value->unused_data, Py_NewRef(self->unused_data)); + Py_XSETREF(return_value->unconsumed_tail, Py_NewRef(self->unconsumed_tail)); + Py_XSETREF(return_value->zdict, Py_XNewRef(self->zdict)); + return_value->eof = self->eof; /* Mark it as being initialized */ - retval->is_initialised = 1; + return_value->is_initialised = 1; LEAVE_ZLIB(self); - return (PyObject *)retval; + return (PyObject *)return_value; error: LEAVE_ZLIB(self); - Py_XDECREF(retval); + Py_XDECREF(return_value); return NULL; } @@ -1158,14 +1150,14 @@ zlib_Decompress_copy_impl(compobject *self, PyTypeObject *cls) { zlibstate *state = PyType_GetModuleState(cls); - compobject *retval = newcompobject(state->Decomptype); - if (!retval) return NULL; + compobject *return_value = newcompobject(state->Decomptype); + if (!return_value) return NULL; /* Copy the zstream state * We use ENTER_ZLIB / LEAVE_ZLIB to make this thread-safe */ ENTER_ZLIB(self); - int err = inflateCopy(&retval->zst, &self->zst); + int err = inflateCopy(&return_value->zst, &self->zst); switch (err) { case Z_OK: break; @@ -1181,23 +1173,20 @@ zlib_Decompress_copy_impl(compobject *self, PyTypeObject *cls) goto error; } - Py_INCREF(self->unused_data); - Py_XSETREF(retval->unused_data, self->unused_data); - Py_INCREF(self->unconsumed_tail); - Py_XSETREF(retval->unconsumed_tail, self->unconsumed_tail); - Py_XINCREF(self->zdict); - Py_XSETREF(retval->zdict, self->zdict); - retval->eof = self->eof; + Py_XSETREF(return_value->unused_data, Py_NewRef(self->unused_data)); + Py_XSETREF(return_value->unconsumed_tail, Py_NewRef(self->unconsumed_tail)); + Py_XSETREF(return_value->zdict, Py_XNewRef(self->zdict)); + return_value->eof = self->eof; /* Mark it as being initialized */ - retval->is_initialised = 1; + return_value->is_initialised = 1; LEAVE_ZLIB(self); - return (PyObject *)retval; + return (PyObject *)return_value; error: LEAVE_ZLIB(self); - Py_XDECREF(retval); + Py_XDECREF(return_value); return NULL; } @@ -1252,7 +1241,7 @@ zlib_Decompress_flush_impl(compobject *self, PyTypeObject *cls, { int err, flush; Py_buffer data; - PyObject *RetVal; + PyObject *return_value; Py_ssize_t ibuflen; _BlocksOutputBuffer buffer = {.list = NULL}; _Uint32Window window; // output buffer's UINT32_MAX sliding window @@ -1306,13 +1295,6 @@ zlib_Decompress_flush_impl(compobject *self, PyTypeObject *cls, case Z_STREAM_END: break; default: - if (err == Z_NEED_DICT && self->zdict != NULL) { - if (set_inflate_zdict(state, self) < 0) { - goto abort; - } - else - break; - } goto save; } @@ -1336,18 +1318,457 @@ zlib_Decompress_flush_impl(compobject *self, PyTypeObject *cls, } } - RetVal = OutputBuffer_WindowFinish(&buffer, &window, self->zst.avail_out); - if (RetVal != NULL) { + return_value = OutputBuffer_WindowFinish(&buffer, &window, self->zst.avail_out); + if (return_value != NULL) { goto success; } abort: OutputBuffer_WindowOnError(&buffer, &window); - RetVal = NULL; + return_value = NULL; success: PyBuffer_Release(&data); LEAVE_ZLIB(self); - return RetVal; + return return_value; +} + + +typedef struct { + PyObject_HEAD + z_stream zst; + PyObject *zdict; + PyThread_type_lock lock; + PyObject *unused_data; + uint8_t *input_buffer; + Py_ssize_t input_buffer_size; + /* zst>avail_in is only 32 bit, so we store the true length + separately. Conversion and looping is encapsulated in + decompress_buf() */ + Py_ssize_t avail_in_real; + bool is_initialised; + char eof; /* T_BOOL expects a char */ + char needs_input; +} ZlibDecompressor; + +/*[clinic input] +class zlib.ZlibDecompressor "ZlibDecompressor *" "&ZlibDecompressorType" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=0658178ab94645df]*/ + +static void +ZlibDecompressor_dealloc(ZlibDecompressor *self) +{ + PyObject *type = (PyObject *)Py_TYPE(self); + PyThread_free_lock(self->lock); + if (self->is_initialised) { + inflateEnd(&self->zst); + } + PyMem_Free(self->input_buffer); + Py_CLEAR(self->unused_data); + Py_CLEAR(self->zdict); + PyObject_Free(self); + Py_DECREF(type); +} + +static int +set_inflate_zdict_ZlibDecompressor(zlibstate *state, ZlibDecompressor *self) +{ + Py_buffer zdict_buf; + if (PyObject_GetBuffer(self->zdict, &zdict_buf, PyBUF_SIMPLE) == -1) { + return -1; + } + if ((size_t)zdict_buf.len > UINT_MAX) { + PyErr_SetString(PyExc_OverflowError, + "zdict length does not fit in an unsigned int"); + PyBuffer_Release(&zdict_buf); + return -1; + } + int err; + err = inflateSetDictionary(&self->zst, + zdict_buf.buf, (unsigned int)zdict_buf.len); + PyBuffer_Release(&zdict_buf); + if (err != Z_OK) { + zlib_error(state, self->zst, err, "while setting zdict"); + return -1; + } + return 0; +} + +static Py_ssize_t +arrange_output_buffer_with_maximum(uint32_t *avail_out, + uint8_t **next_out, + PyObject **buffer, + Py_ssize_t length, + Py_ssize_t max_length) +{ + Py_ssize_t occupied; + + if (*buffer == NULL) { + if (!(*buffer = PyBytes_FromStringAndSize(NULL, length))) + return -1; + occupied = 0; + } + else { + occupied = *next_out - (uint8_t *)PyBytes_AS_STRING(*buffer); + + if (length == occupied) { + Py_ssize_t new_length; + assert(length <= max_length); + /* can not scale the buffer over max_length */ + if (length == max_length) + return -2; + if (length <= (max_length >> 1)) + new_length = length << 1; + else + new_length = max_length; + if (_PyBytes_Resize(buffer, new_length) < 0) + return -1; + length = new_length; + } + } + + *avail_out = (uint32_t)Py_MIN((size_t)(length - occupied), UINT32_MAX); + *next_out = (uint8_t *)PyBytes_AS_STRING(*buffer) + occupied; + + return length; +} + +/* Decompress data of length self->avail_in_real in self->state.next_in. The + output buffer is allocated dynamically and returned. If the max_length is + of sufficiently low size, max_length is allocated immediately. At most + max_length bytes are returned, so some of the input may not be consumed. + self->state.next_in and self->avail_in_real are updated to reflect the + consumed input. */ +static PyObject* +decompress_buf(ZlibDecompressor *self, Py_ssize_t max_length) +{ + /* data_size is strictly positive, but because we repeatedly have to + compare against max_length and PyBytes_GET_SIZE we declare it as + signed */ + PyObject *return_value = NULL; + Py_ssize_t hard_limit; + Py_ssize_t obuflen; + zlibstate *state = PyType_GetModuleState(Py_TYPE(self)); + + int err = Z_OK; + + /* When sys.maxsize is passed as default use DEF_BUF_SIZE as start buffer. + In this particular case the data may not necessarily be very big, so + it is better to grow dynamically.*/ + if ((max_length < 0) || max_length == PY_SSIZE_T_MAX) { + hard_limit = PY_SSIZE_T_MAX; + obuflen = DEF_BUF_SIZE; + } else { + /* Assume that decompressor is used in file decompression with a fixed + block size of max_length. In that case we will reach max_length almost + always (except at the end of the file). So it makes sense to allocate + max_length. */ + hard_limit = max_length; + obuflen = max_length; + if (obuflen > DEF_MAX_INITIAL_BUF_SIZE){ + // Safeguard against memory overflow. + obuflen = DEF_MAX_INITIAL_BUF_SIZE; + } + } + + do { + arrange_input_buffer(&(self->zst), &(self->avail_in_real)); + + do { + obuflen = arrange_output_buffer_with_maximum(&(self->zst.avail_out), + &(self->zst.next_out), + &return_value, + obuflen, + hard_limit); + if (obuflen == -1){ + PyErr_SetString(PyExc_MemoryError, + "Insufficient memory for buffer allocation"); + goto error; + } + else if (obuflen == -2) { + break; + } + Py_BEGIN_ALLOW_THREADS + err = inflate(&self->zst, Z_SYNC_FLUSH); + Py_END_ALLOW_THREADS + switch (err) { + case Z_OK: /* fall through */ + case Z_BUF_ERROR: /* fall through */ + case Z_STREAM_END: + break; + default: + if (err == Z_NEED_DICT) { + goto error; + } + else { + break; + } + } + } while (self->zst.avail_out == 0); + } while(err != Z_STREAM_END && self->avail_in_real != 0); + + if (err == Z_STREAM_END) { + self->eof = 1; + self->is_initialised = 0; + /* Unlike the Decompress object we call inflateEnd here as there are no + backwards compatibility issues */ + err = inflateEnd(&self->zst); + if (err != Z_OK) { + zlib_error(state, self->zst, err, "while finishing decompression"); + goto error; + } + } else if (err != Z_OK && err != Z_BUF_ERROR) { + zlib_error(state, self->zst, err, "while decompressing data"); + goto error; + } + + self->avail_in_real += self->zst.avail_in; + + if (_PyBytes_Resize(&return_value, self->zst.next_out - + (uint8_t *)PyBytes_AS_STRING(return_value)) != 0) { + goto error; + } + + goto success; +error: + Py_CLEAR(return_value); +success: + return return_value; +} + + +static PyObject * +decompress(ZlibDecompressor *self, uint8_t *data, + size_t len, Py_ssize_t max_length) +{ + bool input_buffer_in_use; + PyObject *result; + + /* Prepend unconsumed input if necessary */ + if (self->zst.next_in != NULL) { + size_t avail_now, avail_total; + + /* Number of bytes we can append to input buffer */ + avail_now = (self->input_buffer + self->input_buffer_size) + - (self->zst.next_in + self->avail_in_real); + + /* Number of bytes we can append if we move existing + contents to beginning of buffer (overwriting + consumed input) */ + avail_total = self->input_buffer_size - self->avail_in_real; + + if (avail_total < len) { + size_t offset = self->zst.next_in - self->input_buffer; + uint8_t *tmp; + size_t new_size = self->input_buffer_size + len - avail_now; + + /* Assign to temporary variable first, so we don't + lose address of allocated buffer if realloc fails */ + tmp = PyMem_Realloc(self->input_buffer, new_size); + if (tmp == NULL) { + PyErr_SetNone(PyExc_MemoryError); + return NULL; + } + self->input_buffer = tmp; + self->input_buffer_size = new_size; + + self->zst.next_in = self->input_buffer + offset; + } + else if (avail_now < len) { + memmove(self->input_buffer, self->zst.next_in, + self->avail_in_real); + self->zst.next_in = self->input_buffer; + } + memcpy((void*)(self->zst.next_in + self->avail_in_real), data, len); + self->avail_in_real += len; + input_buffer_in_use = 1; + } + else { + self->zst.next_in = data; + self->avail_in_real = len; + input_buffer_in_use = 0; + } + + result = decompress_buf(self, max_length); + if(result == NULL) { + self->zst.next_in = NULL; + return NULL; + } + + if (self->eof) { + self->needs_input = 0; + + if (self->avail_in_real > 0) { + PyObject *unused_data = PyBytes_FromStringAndSize( + (char *)self->zst.next_in, self->avail_in_real); + if (unused_data == NULL) { + goto error; + } + Py_XSETREF(self->unused_data, unused_data); + } + } + else if (self->avail_in_real == 0) { + self->zst.next_in = NULL; + self->needs_input = 1; + } + else { + self->needs_input = 0; + + /* If we did not use the input buffer, we now have + to copy the tail from the caller's buffer into the + input buffer */ + if (!input_buffer_in_use) { + + /* Discard buffer if it's too small + (resizing it may needlessly copy the current contents) */ + if (self->input_buffer != NULL && + self->input_buffer_size < self->avail_in_real) { + PyMem_Free(self->input_buffer); + self->input_buffer = NULL; + } + + /* Allocate if necessary */ + if (self->input_buffer == NULL) { + self->input_buffer = PyMem_Malloc(self->avail_in_real); + if (self->input_buffer == NULL) { + PyErr_SetNone(PyExc_MemoryError); + goto error; + } + self->input_buffer_size = self->avail_in_real; + } + + /* Copy tail */ + memcpy(self->input_buffer, self->zst.next_in, self->avail_in_real); + self->zst.next_in = self->input_buffer; + } + } + return result; + +error: + Py_XDECREF(result); + return NULL; +} + +/*[clinic input] +zlib.ZlibDecompressor.decompress + + data: Py_buffer + max_length: Py_ssize_t=-1 + +Decompress *data*, returning uncompressed data as bytes. + +If *max_length* is nonnegative, returns at most *max_length* bytes of +decompressed data. If this limit is reached and further output can be +produced, *self.needs_input* will be set to ``False``. In this case, the next +call to *decompress()* may provide *data* as b'' to obtain more of the output. + +If all of the input data was decompressed and returned (either because this +was less than *max_length* bytes, or because *max_length* was negative), +*self.needs_input* will be set to True. + +Attempting to decompress data after the end of stream is reached raises an +EOFError. Any data found after the end of the stream is ignored and saved in +the unused_data attribute. +[clinic start generated code]*/ + +static PyObject * +zlib_ZlibDecompressor_decompress_impl(ZlibDecompressor *self, + Py_buffer *data, Py_ssize_t max_length) +/*[clinic end generated code: output=990d32787b775f85 input=0b29d99715250b96]*/ + +{ + PyObject *result = NULL; + + ENTER_ZLIB(self); + if (self->eof) { + PyErr_SetString(PyExc_EOFError, "End of stream already reached"); + } + else { + result = decompress(self, data->buf, data->len, max_length); + } + LEAVE_ZLIB(self); + return result; +} + +PyDoc_STRVAR(ZlibDecompressor__new____doc__, +"_ZlibDecompressor(wbits=15, zdict=b\'\')\n" +"--\n" +"\n" +"Create a decompressor object for decompressing data incrementally.\n" +"\n" +" wbits = 15\n" +" zdict\n" +" The predefined compression dictionary. This is a sequence of bytes\n" +" (such as a bytes object) containing subsequences that are expected\n" +" to occur frequently in the data that is to be compressed. Those\n" +" subsequences that are expected to be most common should come at the\n" +" end of the dictionary. This must be the same dictionary as used by the\n" +" compressor that produced the input data.\n" +"\n"); + +static PyObject * +ZlibDecompressor__new__(PyTypeObject *cls, + PyObject *args, + PyObject *kwargs) +{ + static char *keywords[] = {"wbits", "zdict", NULL}; + static const char * const format = "|iO:_ZlibDecompressor"; + int wbits = MAX_WBITS; + PyObject *zdict = NULL; + zlibstate *state = PyType_GetModuleState(cls); + + if (!PyArg_ParseTupleAndKeywords( + args, kwargs, format, keywords, &wbits, &zdict)) { + return NULL; + } + ZlibDecompressor *self = PyObject_New(ZlibDecompressor, cls); + self->eof = 0; + self->needs_input = 1; + self->avail_in_real = 0; + self->input_buffer = NULL; + self->input_buffer_size = 0; + self->zdict = Py_XNewRef(zdict); + self->zst.opaque = NULL; + self->zst.zalloc = PyZlib_Malloc; + self->zst.zfree = PyZlib_Free; + self->zst.next_in = NULL; + self->zst.avail_in = 0; + self->unused_data = PyBytes_FromStringAndSize(NULL, 0); + if (self->unused_data == NULL) { + Py_CLEAR(self); + return NULL; + } + self->lock = PyThread_allocate_lock(); + if (self->lock == NULL) { + Py_DECREF(self); + PyErr_SetString(PyExc_MemoryError, "Unable to allocate lock"); + return NULL; + } + int err = inflateInit2(&(self->zst), wbits); + switch (err) { + case Z_OK: + self->is_initialised = 1; + if (self->zdict != NULL && wbits < 0) { + if (set_inflate_zdict_ZlibDecompressor(state, self) < 0) { + Py_DECREF(self); + return NULL; + } + } + return (PyObject *)self; + case Z_STREAM_ERROR: + Py_DECREF(self); + PyErr_SetString(PyExc_ValueError, "Invalid initialization option"); + return NULL; + case Z_MEM_ERROR: + Py_DECREF(self); + PyErr_SetString(PyExc_MemoryError, + "Can't allocate memory for decompression object"); + return NULL; + default: + zlib_error(state, self->zst, err, "while creating decompression object"); + Py_DECREF(self); + return NULL; + } } #include "clinic/zlibmodule.c.h" @@ -1372,6 +1793,11 @@ static PyMethodDef Decomp_methods[] = {NULL, NULL} }; +static PyMethodDef ZlibDecompressor_methods[] = { + ZLIB_ZLIBDECOMPRESSOR_DECOMPRESS_METHODDEF + {NULL} +}; + #define COMP_OFF(x) offsetof(compobject, x) static PyMemberDef Decomp_members[] = { {"unused_data", T_OBJECT, COMP_OFF(unused_data), READONLY}, @@ -1380,6 +1806,26 @@ static PyMemberDef Decomp_members[] = { {NULL}, }; +PyDoc_STRVAR(ZlibDecompressor_eof__doc__, +"True if the end-of-stream marker has been reached."); + +PyDoc_STRVAR(ZlibDecompressor_unused_data__doc__, +"Data found after the end of the compressed stream."); + +PyDoc_STRVAR(ZlibDecompressor_needs_input_doc, +"True if more input is needed before more decompressed data can be produced."); + +static PyMemberDef ZlibDecompressor_members[] = { + {"eof", T_BOOL, offsetof(ZlibDecompressor, eof), + READONLY, ZlibDecompressor_eof__doc__}, + {"unused_data", T_OBJECT_EX, offsetof(ZlibDecompressor, unused_data), + READONLY, ZlibDecompressor_unused_data__doc__}, + {"needs_input", T_BOOL, offsetof(ZlibDecompressor, needs_input), READONLY, + ZlibDecompressor_needs_input_doc}, + {NULL}, +}; + + /*[clinic input] zlib.adler32 @@ -1497,6 +1943,25 @@ static PyType_Spec Decomptype_spec = { .slots = Decomptype_slots, }; +static PyType_Slot ZlibDecompressor_type_slots[] = { + {Py_tp_dealloc, ZlibDecompressor_dealloc}, + {Py_tp_members, ZlibDecompressor_members}, + {Py_tp_new, ZlibDecompressor__new__}, + {Py_tp_doc, (char *)ZlibDecompressor__new____doc__}, + {Py_tp_methods, ZlibDecompressor_methods}, + {0, 0}, +}; + +static PyType_Spec ZlibDecompressor_type_spec = { + .name = "zlib._ZlibDecompressor", + .basicsize = sizeof(ZlibDecompressor), + // Calling PyType_GetModuleState() on a subclass is not safe. + // ZlibDecompressor_type_spec does not have Py_TPFLAGS_BASETYPE flag + // which prevents to create a subclass. + // So calling PyType_GetModuleState() in this file is always safe. + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE), + .slots = ZlibDecompressor_type_slots, +}; PyDoc_STRVAR(zlib_module_documentation, "The functions in this module allow compression and decompression using the\n" "zlib library, which is based on GNU zip.\n" @@ -1518,6 +1983,7 @@ zlib_clear(PyObject *mod) zlibstate *state = get_zlib_state(mod); Py_CLEAR(state->Comptype); Py_CLEAR(state->Decomptype); + Py_CLEAR(state->ZlibDecompressorType); Py_CLEAR(state->ZlibError); return 0; } @@ -1528,6 +1994,7 @@ zlib_traverse(PyObject *mod, visitproc visit, void *arg) zlibstate *state = get_zlib_state(mod); Py_VISIT(state->Comptype); Py_VISIT(state->Decomptype); + Py_VISIT(state->ZlibDecompressorType); Py_VISIT(state->ZlibError); return 0; } @@ -1555,16 +2022,26 @@ zlib_exec(PyObject *mod) return -1; } + state->ZlibDecompressorType = (PyTypeObject *)PyType_FromModuleAndSpec( + mod, &ZlibDecompressor_type_spec, NULL); + if (state->ZlibDecompressorType == NULL) { + return -1; + } + state->ZlibError = PyErr_NewException("zlib.error", NULL, NULL); if (state->ZlibError == NULL) { return -1; } - Py_INCREF(state->ZlibError); - if (PyModule_AddObject(mod, "error", state->ZlibError) < 0) { + if (PyModule_AddObject(mod, "error", Py_NewRef(state->ZlibError)) < 0) { Py_DECREF(state->ZlibError); return -1; } + if (PyModule_AddObject(mod, "_ZlibDecompressor", + Py_NewRef(state->ZlibDecompressorType)) < 0) { + Py_DECREF(state->ZlibDecompressorType); + return -1; + } #define ZLIB_ADD_INT_MACRO(c) \ do { \ @@ -1632,6 +2109,7 @@ zlib_exec(PyObject *mod) static PyModuleDef_Slot zlib_slots[] = { {Py_mod_exec, zlib_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; diff --git a/Objects/abstract.c b/Objects/abstract.c index 93987c20..e9578590 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -5,6 +5,7 @@ #include "pycore_call.h" // _PyObject_CallNoArgs() #include "pycore_ceval.h" // _Py_EnterRecursiveCallTstate() #include "pycore_object.h" // _Py_CheckSlotResult() +#include "pycore_long.h" // _Py_IsNegative #include "pycore_pyerrors.h" // _PyErr_Occurred() #include "pycore_pystate.h" // _PyThreadState_GET() #include "pycore_unionobject.h" // _PyUnion_Check() @@ -45,8 +46,7 @@ PyObject_Type(PyObject *o) } v = (PyObject *)Py_TYPE(o); - Py_INCREF(v); - return v; + return Py_NewRef(v); } Py_ssize_t @@ -526,18 +526,12 @@ _Py_add_one_to_index_C(int nd, Py_ssize_t *index, const Py_ssize_t *shape) Py_ssize_t PyBuffer_SizeFromFormat(const char *format) { - PyObject *structmodule = NULL; PyObject *calcsize = NULL; PyObject *res = NULL; PyObject *fmt = NULL; Py_ssize_t itemsize = -1; - structmodule = PyImport_ImportModule("struct"); - if (structmodule == NULL) { - return itemsize; - } - - calcsize = PyObject_GetAttrString(structmodule, "calcsize"); + calcsize = _PyImport_GetModuleAttrString("struct", "calcsize"); if (calcsize == NULL) { goto done; } @@ -558,7 +552,6 @@ PyBuffer_SizeFromFormat(const char *format) } done: - Py_DECREF(structmodule); Py_XDECREF(calcsize); Py_XDECREF(fmt); Py_XDECREF(res); @@ -729,9 +722,7 @@ PyBuffer_FillInfo(Py_buffer *view, PyObject *obj, void *buf, Py_ssize_t len, return -1; } - view->obj = obj; - if (obj) - Py_INCREF(obj); + view->obj = Py_XNewRef(obj); view->buf = buf; view->len = len; view->readonly = readonly; @@ -783,8 +774,7 @@ PyObject_Format(PyObject *obj, PyObject *format_spec) /* Fast path for common types. */ if (format_spec == NULL || PyUnicode_GET_LENGTH(format_spec) == 0) { if (PyUnicode_CheckExact(obj)) { - Py_INCREF(obj); - return obj; + return Py_NewRef(obj); } if (PyLong_CheckExact(obj)) { return PyObject_Str(obj); @@ -817,8 +807,7 @@ PyObject_Format(PyObject *obj, PyObject *format_spec) PyErr_Format(PyExc_TypeError, "__format__ must return a str, not %.200s", Py_TYPE(result)->tp_name); - Py_DECREF(result); - result = NULL; + Py_SETREF(result, NULL); goto done; } @@ -1412,8 +1401,7 @@ _PyNumber_Index(PyObject *item) } if (PyLong_Check(item)) { - Py_INCREF(item); - return item; + return Py_NewRef(item); } if (!_PyIndex_Check(item)) { PyErr_Format(PyExc_TypeError, @@ -1496,7 +1484,7 @@ PyNumber_AsSsize_t(PyObject *item, PyObject *err) /* Whether or not it is less than or equal to zero is determined by the sign of ob_size */ - if (_PyLong_Sign(value) < 0) + if (_PyLong_IsNegative((PyLongObject *)value)) result = PY_SSIZE_T_MIN; else result = PY_SSIZE_T_MAX; @@ -1527,8 +1515,7 @@ PyNumber_Long(PyObject *o) } if (PyLong_CheckExact(o)) { - Py_INCREF(o); - return o; + return Py_NewRef(o); } m = Py_TYPE(o)->tp_as_number; if (m && m->nb_int) { /* This should include subclasses of int */ @@ -2052,8 +2039,7 @@ PySequence_Tuple(PyObject *v) a tuple *subclass* instance as-is, hence the restriction to exact tuples here. In contrast, lists always make a copy, so there's no need for exactness below. */ - Py_INCREF(v); - return v; + return Py_NewRef(v); } if (PyList_CheckExact(v)) return PyList_AsTuple(v); @@ -2151,8 +2137,7 @@ PySequence_Fast(PyObject *v, const char *m) } if (PyList_CheckExact(v) || PyTuple_CheckExact(v)) { - Py_INCREF(v); - return v; + return Py_NewRef(v); } it = PyObject_GetIter(v); @@ -2806,8 +2791,7 @@ PyObject_GetIter(PyObject *o) "iter() returned non-iterator " "of type '%.100s'", Py_TYPE(res)->tp_name); - Py_DECREF(res); - res = NULL; + Py_SETREF(res, NULL); } return res; } @@ -2827,8 +2811,7 @@ PyObject_GetAIter(PyObject *o) { PyErr_Format(PyExc_TypeError, "aiter() returned not an async iterator of type '%.100s'", Py_TYPE(it)->tp_name); - Py_DECREF(it); - it = NULL; + Py_SETREF(it, NULL); } return it; } diff --git a/Objects/accu.c b/Objects/accu.c deleted file mode 100644 index c8b5d382..00000000 --- a/Objects/accu.c +++ /dev/null @@ -1,115 +0,0 @@ -/* Accumulator struct implementation */ - -#include "Python.h" -#include "pycore_accu.h" - -static PyObject * -join_list_unicode(PyObject *lst) -{ - /* return ''.join(lst) */ - PyObject *sep, *ret; - sep = PyUnicode_FromStringAndSize("", 0); - ret = PyUnicode_Join(sep, lst); - Py_DECREF(sep); - return ret; -} - -int -_PyAccu_Init(_PyAccu *acc) -{ - /* Lazily allocated */ - acc->large = NULL; - acc->small = PyList_New(0); - if (acc->small == NULL) - return -1; - return 0; -} - -static int -flush_accumulator(_PyAccu *acc) -{ - Py_ssize_t nsmall = PyList_GET_SIZE(acc->small); - if (nsmall) { - int ret; - PyObject *joined; - if (acc->large == NULL) { - acc->large = PyList_New(0); - if (acc->large == NULL) - return -1; - } - joined = join_list_unicode(acc->small); - if (joined == NULL) - return -1; - if (PyList_SetSlice(acc->small, 0, nsmall, NULL)) { - Py_DECREF(joined); - return -1; - } - ret = PyList_Append(acc->large, joined); - Py_DECREF(joined); - return ret; - } - return 0; -} - -int -_PyAccu_Accumulate(_PyAccu *acc, PyObject *unicode) -{ - Py_ssize_t nsmall; - assert(PyUnicode_Check(unicode)); - - if (PyList_Append(acc->small, unicode)) - return -1; - nsmall = PyList_GET_SIZE(acc->small); - /* Each item in a list of unicode objects has an overhead (in 64-bit - * builds) of: - * - 8 bytes for the list slot - * - 56 bytes for the header of the unicode object - * that is, 64 bytes. 100000 such objects waste more than 6 MiB - * compared to a single concatenated string. - */ - if (nsmall < 100000) - return 0; - return flush_accumulator(acc); -} - -PyObject * -_PyAccu_FinishAsList(_PyAccu *acc) -{ - int ret; - PyObject *res; - - ret = flush_accumulator(acc); - Py_CLEAR(acc->small); - if (ret) { - Py_CLEAR(acc->large); - return NULL; - } - res = acc->large; - acc->large = NULL; - return res; -} - -PyObject * -_PyAccu_Finish(_PyAccu *acc) -{ - PyObject *list, *res; - if (acc->large == NULL) { - list = acc->small; - acc->small = NULL; - } - else { - list = _PyAccu_FinishAsList(acc); - if (!list) - return NULL; - } - res = join_list_unicode(list); - Py_DECREF(list); - return res; -} - -void -_PyAccu_Destroy(_PyAccu *acc) -{ - Py_CLEAR(acc->small); - Py_CLEAR(acc->large); -} diff --git a/Objects/boolobject.c b/Objects/boolobject.c index 8a20e368..f43e26f3 100644 --- a/Objects/boolobject.c +++ b/Objects/boolobject.c @@ -2,8 +2,11 @@ #include "Python.h" #include "pycore_object.h" // _Py_FatalRefcountError() +#include "pycore_long.h" // FALSE_TAG TRUE_TAG #include "pycore_runtime.h" // _Py_ID() +#include <stddef.h> + /* We define bool_repr to return "False" or "True" */ static PyObject * @@ -17,14 +20,7 @@ bool_repr(PyObject *self) PyObject *PyBool_FromLong(long ok) { - PyObject *result; - - if (ok) - result = Py_True; - else - result = Py_False; - Py_INCREF(result); - return result; + return ok ? Py_True : Py_False; } /* We define bool_new to always return either Py_True or Py_False */ @@ -71,6 +67,22 @@ bool_vectorcall(PyObject *type, PyObject * const*args, /* Arithmetic operations redefined to return bool if both args are bool. */ +static PyObject * +bool_invert(PyObject *v) +{ + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "Bitwise inversion '~' on bool is deprecated. This " + "returns the bitwise inversion of the underlying int " + "object and is usually not what you expect from negating " + "a bool. Use the 'not' operator for boolean negation or " + "~int(x) if you really want the bitwise inversion of the " + "underlying int.", + 1) < 0) { + return NULL; + } + return PyLong_Type.tp_as_number->nb_invert(v); +} + static PyObject * bool_and(PyObject *a, PyObject *b) { @@ -117,7 +129,7 @@ static PyNumberMethods bool_as_number = { 0, /* nb_positive */ 0, /* nb_absolute */ 0, /* nb_bool */ - 0, /* nb_invert */ + (unaryfunc)bool_invert, /* nb_invert */ 0, /* nb_lshift */ 0, /* nb_rshift */ bool_and, /* nb_and */ @@ -143,10 +155,14 @@ static PyNumberMethods bool_as_number = { 0, /* nb_index */ }; -static void _Py_NO_RETURN -bool_dealloc(PyObject* Py_UNUSED(ignore)) +static void +bool_dealloc(PyObject *boolean) { - _Py_FatalRefcountError("deallocating True or False"); + /* This should never get called, but we also don't want to SEGV if + * we accidentally decref Booleans out of existence. Instead, + * since bools are immortal, re-set the reference count. + */ + _Py_SetImmortal(boolean); } /* The type object for bool. Note that this cannot be subclassed! */ @@ -154,8 +170,8 @@ bool_dealloc(PyObject* Py_UNUSED(ignore)) PyTypeObject PyBool_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "bool", - sizeof(struct _longobject), - 0, + offsetof(struct _longobject, long_value.ob_digit), /* tp_basicsize */ + sizeof(digit), /* tp_itemsize */ bool_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ @@ -196,11 +212,15 @@ PyTypeObject PyBool_Type = { /* The objects representing bool values False and True */ struct _longobject _Py_FalseStruct = { - PyVarObject_HEAD_INIT(&PyBool_Type, 0) - { 0 } + PyObject_HEAD_INIT(&PyBool_Type) + { .lv_tag = _PyLong_FALSE_TAG, + { 0 } + } }; struct _longobject _Py_TrueStruct = { - PyVarObject_HEAD_INIT(&PyBool_Type, 1) - { 1 } + PyObject_HEAD_INIT(&PyBool_Type) + { .lv_tag = _PyLong_TRUE_TAG, + { 1 } + } }; diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index dfeed684..c36db59b 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -61,6 +61,7 @@ static void bytearray_releasebuffer(PyByteArrayObject *obj, Py_buffer *view) { obj->ob_exports--; + assert(obj->ob_exports >= 0); } static int @@ -313,8 +314,7 @@ bytearray_iconcat(PyByteArrayObject *self, PyObject *other) } memcpy(PyByteArray_AS_STRING(self) + size, vo.buf, vo.len); PyBuffer_Release(&vo); - Py_INCREF(self); - return (PyObject *)self; + return Py_NewRef(self); } static PyObject * @@ -340,8 +340,7 @@ bytearray_irepeat(PyByteArrayObject *self, Py_ssize_t count) if (count < 0) count = 0; else if (count == 1) { - Py_INCREF(self); - return (PyObject*)self; + return Py_NewRef(self); } const Py_ssize_t mysize = Py_SIZE(self); @@ -354,8 +353,7 @@ bytearray_irepeat(PyByteArrayObject *self, Py_ssize_t count) char* buf = PyByteArray_AS_STRING(self); _PyBytes_Repeat(buf, size, buf, mysize); - Py_INCREF(self); - return (PyObject *)self; + return Py_NewRef(self); } static PyObject * @@ -1110,6 +1108,7 @@ bytearray_dealloc(PyByteArrayObject *self) #define STRINGLIB_ISSPACE Py_ISSPACE #define STRINGLIB_ISLINEBREAK(x) ((x == '\n') || (x == '\r')) #define STRINGLIB_CHECK_EXACT PyByteArray_CheckExact +#define STRINGLIB_FAST_MEMCHR memchr #define STRINGLIB_MUTABLE 1 #include "stringlib/fastsearch.h" @@ -2014,7 +2013,7 @@ bytearray_join(PyByteArrayObject *self, PyObject *iterable_of_bytes) /*[clinic input] bytearray.splitlines - keepends: bool(accept={int}) = False + keepends: bool = False Return a list of the lines in the bytearray, breaking at line boundaries. @@ -2024,7 +2023,7 @@ true. static PyObject * bytearray_splitlines_impl(PyByteArrayObject *self, int keepends) -/*[clinic end generated code: output=4223c94b895f6ad9 input=99a27ad959b9cf6b]*/ +/*[clinic end generated code: output=4223c94b895f6ad9 input=66b2dcdea8d093bf]*/ { return stringlib_splitlines( (PyObject*) self, PyByteArray_AS_STRING(self), @@ -2153,10 +2152,9 @@ static PyObject * bytearray_sizeof_impl(PyByteArrayObject *self) /*[clinic end generated code: output=738abdd17951c427 input=e27320fd98a4bc5a]*/ { - Py_ssize_t res; - - res = _PyObject_SIZE(Py_TYPE(self)) + self->ob_alloc * sizeof(char); - return PyLong_FromSsize_t(res); + size_t res = _PyObject_SIZE(Py_TYPE(self)); + res += (size_t)self->ob_alloc * sizeof(char); + return PyLong_FromSize_t(res); } static PySequenceMethods bytearray_as_sequence = { @@ -2394,11 +2392,16 @@ PyDoc_STRVAR(length_hint_doc, static PyObject * bytearrayiter_reduce(bytesiterobject *it, PyObject *Py_UNUSED(ignored)) { + PyObject *iter = _PyEval_GetBuiltin(&_Py_ID(iter)); + + /* _PyEval_GetBuiltin can invoke arbitrary code, + * call must be before access of iterator pointers. + * see issue #101765 */ + if (it->it_seq != NULL) { - return Py_BuildValue("N(O)n", _PyEval_GetBuiltin(&_Py_ID(iter)), - it->it_seq, it->it_index); + return Py_BuildValue("N(O)n", iter, it->it_seq, it->it_index); } else { - return Py_BuildValue("N(())", _PyEval_GetBuiltin(&_Py_ID(iter))); + return Py_BuildValue("N(())", iter); } } @@ -2476,8 +2479,7 @@ bytearray_iter(PyObject *seq) if (it == NULL) return NULL; it->it_index = 0; - Py_INCREF(seq); - it->it_seq = (PyByteArrayObject *)seq; + it->it_seq = (PyByteArrayObject *)Py_NewRef(seq); _PyObject_GC_TRACK(it); return (PyObject *)it; } diff --git a/Objects/bytes_methods.c b/Objects/bytes_methods.c index 994fb8a7..33aa9c3d 100644 --- a/Objects/bytes_methods.c +++ b/Objects/bytes_methods.c @@ -258,9 +258,12 @@ _Py_bytes_istitle(const char *cptr, Py_ssize_t len) const unsigned char *e; int cased, previous_is_cased; - /* Shortcut for single character strings */ - if (len == 1) - return PyBool_FromLong(Py_ISUPPER(*p)); + if (len == 1) { + if (Py_ISUPPER(*p)) { + Py_RETURN_TRUE; + } + Py_RETURN_FALSE; + } /* Special case for empty strings */ if (len == 0) @@ -431,6 +434,7 @@ _Py_bytes_maketrans(Py_buffer *frm, Py_buffer *to) #define STRINGLIB(F) stringlib_##F #define STRINGLIB_CHAR char #define STRINGLIB_SIZEOF_CHAR 1 +#define STRINGLIB_FAST_MEMCHR memchr #include "stringlib/fastsearch.h" #include "stringlib/count.h" @@ -773,7 +777,7 @@ _Py_bytes_tailmatch(const char *str, Py_ssize_t len, { Py_ssize_t start = 0; Py_ssize_t end = PY_SSIZE_T_MAX; - PyObject *subobj; + PyObject *subobj = NULL; int result; if (!stringlib_parse_args_finds(function_name, args, &subobj, &start, &end)) diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index 17a2661e..f3a978c8 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -53,8 +53,7 @@ static inline PyObject* bytes_get_empty(void) // Return a strong reference to the empty bytes string singleton. static inline PyObject* bytes_new_empty(void) { - Py_INCREF(EMPTY); - return (PyObject *)EMPTY; + return Py_NewRef(EMPTY); } @@ -126,8 +125,7 @@ PyBytes_FromStringAndSize(const char *str, Py_ssize_t size) } if (size == 1 && str != NULL) { op = CHARACTER(*str & 255); - Py_INCREF(op); - return (PyObject *)op; + return Py_NewRef(op); } if (size == 0) { return bytes_new_empty(); @@ -162,8 +160,7 @@ PyBytes_FromString(const char *str) } else if (size == 1) { op = CHARACTER(*str & 255); - Py_INCREF(op); - return (PyObject *)op; + return Py_NewRef(op); } /* Inline PyObject_NewVar */ @@ -377,11 +374,7 @@ PyBytes_FromFormat(const char *format, ...) PyObject* ret; va_list vargs; -#ifdef HAVE_STDARG_PROTOTYPES va_start(vargs, format); -#else - va_start(vargs); -#endif ret = PyBytes_FromFormatV(format, vargs); va_end(vargs); return ret; @@ -430,9 +423,6 @@ formatfloat(PyObject *v, int flags, int prec, int type, if (flags & F_ALT) { dtoa_flags |= Py_DTSF_ALT; } - if (flags & F_NO_NEG_0) { - dtoa_flags |= Py_DTSF_NO_NEG_0; - } p = PyOS_double_to_string(x, type, prec, dtoa_flags, NULL); if (p == NULL) @@ -533,14 +523,12 @@ format_obj(PyObject *v, const char **pbuf, Py_ssize_t *plen) if (PyBytes_Check(v)) { *pbuf = PyBytes_AS_STRING(v); *plen = PyBytes_GET_SIZE(v); - Py_INCREF(v); - return v; + return Py_NewRef(v); } if (PyByteArray_Check(v)) { *pbuf = PyByteArray_AS_STRING(v); *plen = PyByteArray_GET_SIZE(v); - Py_INCREF(v); - return v; + return Py_NewRef(v); } /* does it support __bytes__? */ func = _PyObject_LookupSpecial(v, &_Py_ID(__bytes__)); @@ -714,7 +702,6 @@ _PyBytes_FormatEx(const char *format, Py_ssize_t format_len, case ' ': flags |= F_BLANK; continue; case '#': flags |= F_ALT; continue; case '0': flags |= F_ZERO; continue; - case 'z': flags |= F_NO_NEG_0; continue; } break; } @@ -1287,8 +1274,25 @@ _PyBytes_Find(const char *haystack, Py_ssize_t len_haystack, const char *needle, Py_ssize_t len_needle, Py_ssize_t offset) { - return stringlib_find(haystack, len_haystack, - needle, len_needle, offset); + assert(len_haystack >= 0); + assert(len_needle >= 0); + // Extra checks because stringlib_find accesses haystack[len_haystack]. + if (len_needle == 0) { + return offset; + } + if (len_needle > len_haystack) { + return -1; + } + assert(len_haystack >= 1); + Py_ssize_t res = stringlib_find(haystack, len_haystack - 1, + needle, len_needle, offset); + if (res == -1) { + Py_ssize_t last_align = len_haystack - len_needle; + if (memcmp(haystack + last_align, needle, len_needle) == 0) { + return offset + last_align; + } + } + return res; } Py_ssize_t @@ -1417,13 +1421,11 @@ bytes_concat(PyObject *a, PyObject *b) /* Optimize end cases */ if (va.len == 0 && PyBytes_CheckExact(b)) { - result = b; - Py_INCREF(result); + result = Py_NewRef(b); goto done; } if (vb.len == 0 && PyBytes_CheckExact(a)) { - result = a; - Py_INCREF(result); + result = Py_NewRef(a); goto done; } @@ -1464,8 +1466,7 @@ bytes_repeat(PyBytesObject *a, Py_ssize_t n) } size = Py_SIZE(a) * n; if (size == Py_SIZE(a) && PyBytes_CheckExact(a)) { - Py_INCREF(a); - return (PyObject *)a; + return Py_NewRef(a); } nbytes = (size_t)size; if (nbytes + PyBytesObject_SIZE <= nbytes) { @@ -1631,8 +1632,7 @@ bytes_subscript(PyBytesObject* self, PyObject* item) else if (start == 0 && step == 1 && slicelength == PyBytes_GET_SIZE(self) && PyBytes_CheckExact(self)) { - Py_INCREF(self); - return (PyObject *)self; + return Py_NewRef(self); } else if (step == 1) { return PyBytes_FromStringAndSize( @@ -1702,8 +1702,7 @@ bytes___bytes___impl(PyBytesObject *self) /*[clinic end generated code: output=63a306a9bc0caac5 input=34ec5ddba98bd6bb]*/ { if (PyBytes_CheckExact(self)) { - Py_INCREF(self); - return (PyObject *)self; + return Py_NewRef(self); } else { return PyBytes_FromStringAndSize(self->ob_sval, Py_SIZE(self)); @@ -1928,8 +1927,7 @@ do_xstrip(PyBytesObject *self, int striptype, PyObject *sepobj) PyBuffer_Release(&vsep); if (i == 0 && j == len && PyBytes_CheckExact(self)) { - Py_INCREF(self); - return (PyObject*)self; + return Py_NewRef(self); } else return PyBytes_FromStringAndSize(s+i, j-i); @@ -1958,8 +1956,7 @@ do_strip(PyBytesObject *self, int striptype) } if (i == 0 && j == len && PyBytes_CheckExact(self)) { - Py_INCREF(self); - return (PyObject*)self; + return Py_NewRef(self); } else return PyBytes_FromStringAndSize(s+i, j-i); @@ -2127,9 +2124,7 @@ bytes_translate_impl(PyBytesObject *self, PyObject *table, changed = 1; } if (!changed && PyBytes_CheckExact(input_obj)) { - Py_INCREF(input_obj); - Py_DECREF(result); - result = input_obj; + Py_SETREF(result, Py_NewRef(input_obj)); } PyBuffer_Release(&del_table_view); PyBuffer_Release(&table_view); @@ -2158,8 +2153,7 @@ bytes_translate_impl(PyBytesObject *self, PyObject *table, } if (!changed && PyBytes_CheckExact(input_obj)) { Py_DECREF(result); - Py_INCREF(input_obj); - return input_obj; + return Py_NewRef(input_obj); } /* Fix the size of the resulting byte string */ if (inlen > 0) @@ -2251,8 +2245,7 @@ bytes_removeprefix_impl(PyBytesObject *self, Py_buffer *prefix) } if (PyBytes_CheckExact(self)) { - Py_INCREF(self); - return (PyObject *)self; + return Py_NewRef(self); } return PyBytes_FromStringAndSize(self_start, self_len); @@ -2290,8 +2283,7 @@ bytes_removesuffix_impl(PyBytesObject *self, Py_buffer *suffix) } if (PyBytes_CheckExact(self)) { - Py_INCREF(self); - return (PyObject *)self; + return Py_NewRef(self); } return PyBytes_FromStringAndSize(self_start, self_len); @@ -2337,7 +2329,7 @@ bytes_decode_impl(PyBytesObject *self, const char *encoding, /*[clinic input] bytes.splitlines - keepends: bool(accept={int}) = False + keepends: bool = False Return a list of the lines in the bytes, breaking at line boundaries. @@ -2347,7 +2339,7 @@ true. static PyObject * bytes_splitlines_impl(PyBytesObject *self, int keepends) -/*[clinic end generated code: output=3484149a5d880ffb input=a8b32eb01ff5a5ed]*/ +/*[clinic end generated code: output=3484149a5d880ffb input=5d7b898af2fe55c0]*/ { return stringlib_splitlines( (PyObject*) self, PyBytes_AS_STRING(self), @@ -2398,7 +2390,7 @@ _PyBytes_FromHex(PyObject *string, int use_bytearray) if (!PyUnicode_IS_ASCII(string)) { const void *data = PyUnicode_DATA(string); - unsigned int kind = PyUnicode_KIND(string); + int kind = PyUnicode_KIND(string); Py_ssize_t i; /* search for the first non-ASCII character */ @@ -2850,8 +2842,7 @@ PyBytes_FromObject(PyObject *x) } if (PyBytes_CheckExact(x)) { - Py_INCREF(x); - return x; + return Py_NewRef(x); } /* Use the modern buffer interface */ @@ -3082,21 +3073,20 @@ _PyBytes_Resize(PyObject **pv, Py_ssize_t newsize) Py_DECREF(v); return 0; } - /* XXX UNREF/NEWREF interface should be more symmetrical */ -#ifdef Py_REF_DEBUG - _Py_RefTotal--; -#endif #ifdef Py_TRACE_REFS _Py_ForgetReference(v); #endif *pv = (PyObject *) PyObject_Realloc(v, PyBytesObject_SIZE + newsize); if (*pv == NULL) { +#ifdef Py_REF_DEBUG + _Py_DecRefTotal(_PyInterpreterState_GET()); +#endif PyObject_Free(v); PyErr_NoMemory(); return -1; } - _Py_NewReference(*pv); + _Py_NewReferenceNoTotal(*pv); sv = (PyBytesObject *) *pv; Py_SET_SIZE(sv, newsize); sv->ob_sval[newsize] = '\0'; @@ -3113,25 +3103,6 @@ error: } -PyStatus -_PyBytes_InitTypes(PyInterpreterState *interp) -{ - if (!_Py_IsMainInterpreter(interp)) { - return _PyStatus_OK(); - } - - if (PyType_Ready(&PyBytes_Type) < 0) { - return _PyStatus_ERR("Can't initialize bytes type"); - } - - if (PyType_Ready(&PyBytesIter_Type) < 0) { - return _PyStatus_ERR("Can't initialize bytes iterator type"); - } - - return _PyStatus_OK(); -} - - /*********************** Bytes Iterator ****************************/ typedef struct { @@ -3191,11 +3162,16 @@ PyDoc_STRVAR(length_hint_doc, static PyObject * striter_reduce(striterobject *it, PyObject *Py_UNUSED(ignored)) { + PyObject *iter = _PyEval_GetBuiltin(&_Py_ID(iter)); + + /* _PyEval_GetBuiltin can invoke arbitrary code, + * call must be before access of iterator pointers. + * see issue #101765 */ + if (it->it_seq != NULL) { - return Py_BuildValue("N(O)n", _PyEval_GetBuiltin(&_Py_ID(iter)), - it->it_seq, it->it_index); + return Py_BuildValue("N(O)n", iter, it->it_seq, it->it_index); } else { - return Py_BuildValue("N(())", _PyEval_GetBuiltin(&_Py_ID(iter))); + return Py_BuildValue("N(())", iter); } } @@ -3275,8 +3251,7 @@ bytes_iter(PyObject *seq) if (it == NULL) return NULL; it->it_index = 0; - Py_INCREF(seq); - it->it_seq = (PyBytesObject *)seq; + it->it_seq = (PyBytesObject *)Py_NewRef(seq); _PyObject_GC_TRACK(it); return (PyObject *)it; } diff --git a/Objects/call.c b/Objects/call.c index 678d1626..0d548dcd 100644 --- a/Objects/call.c +++ b/Objects/call.c @@ -1,21 +1,11 @@ #include "Python.h" #include "pycore_call.h" // _PyObject_CallNoArgsTstate() -#include "pycore_ceval.h" // _PyEval_EvalFrame() -#include "pycore_object.h" // _PyObject_GC_TRACK() +#include "pycore_ceval.h" // _Py_EnterRecursiveCallTstate() +#include "pycore_dict.h" // _PyDict_FromItems() +#include "pycore_object.h" // _PyCFunctionWithKeywords_TrampolineCall() #include "pycore_pyerrors.h" // _PyErr_Occurred() #include "pycore_pystate.h" // _PyThreadState_GET() #include "pycore_tuple.h" // _PyTuple_ITEMS() -#include "frameobject.h" // _PyFrame_New_NoTrack() - - -static PyObject *const * -_PyStack_UnpackDict(PyThreadState *tstate, - PyObject *const *args, Py_ssize_t nargs, - PyObject *kwargs, PyObject **p_kwnames); - -static void -_PyStack_UnpackDict_Free(PyObject *const *stack, Py_ssize_t nargs, - PyObject *kwnames); static PyObject * @@ -109,7 +99,9 @@ _Py_CheckSlotResult(PyObject *obj, const char *slot_name, int success) PyObject * PyObject_CallNoArgs(PyObject *func) { - return _PyObject_CallNoArgs(func); + EVAL_CALL_STAT_INC_IF_FUNCTION(EVAL_CALL_API, func); + PyThreadState *tstate = _PyThreadState_GET(); + return _PyObject_VectorcallTstate(tstate, func, NULL, 0, NULL); } @@ -165,6 +157,42 @@ PyObject_VectorcallDict(PyObject *callable, PyObject *const *args, return _PyObject_FastCallDictTstate(tstate, callable, args, nargsf, kwargs); } +static void +object_is_not_callable(PyThreadState *tstate, PyObject *callable) +{ + if (Py_IS_TYPE(callable, &PyModule_Type)) { + // >>> import pprint + // >>> pprint(thing) + // Traceback (most recent call last): + // File "<stdin>", line 1, in <module> + // TypeError: 'module' object is not callable. Did you mean: 'pprint.pprint(...)'? + PyObject *name = PyModule_GetNameObject(callable); + if (name == NULL) { + _PyErr_Clear(tstate); + goto basic_type_error; + } + PyObject *attr; + int res = _PyObject_LookupAttr(callable, name, &attr); + if (res < 0) { + _PyErr_Clear(tstate); + } + else if (res > 0 && PyCallable_Check(attr)) { + _PyErr_Format(tstate, PyExc_TypeError, + "'%.200s' object is not callable. " + "Did you mean: '%U.%U(...)'?", + Py_TYPE(callable)->tp_name, name, name); + Py_DECREF(attr); + Py_DECREF(name); + return; + } + Py_XDECREF(attr); + Py_DECREF(name); + } +basic_type_error: + _PyErr_Format(tstate, PyExc_TypeError, "'%.200s' object is not callable", + Py_TYPE(callable)->tp_name); +} + PyObject * _PyObject_MakeTpCall(PyThreadState *tstate, PyObject *callable, @@ -179,9 +207,7 @@ _PyObject_MakeTpCall(PyThreadState *tstate, PyObject *callable, * temporary dictionary for keyword arguments (if any) */ ternaryfunc call = Py_TYPE(callable)->tp_call; if (call == NULL) { - _PyErr_Format(tstate, PyExc_TypeError, - "'%.200s' object is not callable", - Py_TYPE(callable)->tp_name); + object_is_not_callable(tstate, callable); return NULL; } @@ -322,7 +348,7 @@ _PyObject_Call(PyThreadState *tstate, PyObject *callable, assert(!_PyErr_Occurred(tstate)); assert(PyTuple_Check(args)); assert(kwargs == NULL || PyDict_Check(kwargs)); - + EVAL_CALL_STAT_INC_IF_FUNCTION(EVAL_CALL_API, callable); vectorcallfunc vector_func = _PyVectorcall_Function(callable); if (vector_func != NULL) { return _PyVectorcall_Call(tstate, vector_func, callable, args, kwargs); @@ -330,9 +356,7 @@ _PyObject_Call(PyThreadState *tstate, PyObject *callable, else { call = Py_TYPE(callable)->tp_call; if (call == NULL) { - _PyErr_Format(tstate, PyExc_TypeError, - "'%.200s' object is not callable", - Py_TYPE(callable)->tp_name); + object_is_not_callable(tstate, callable); return NULL; } @@ -367,6 +391,7 @@ PyCFunction_Call(PyObject *callable, PyObject *args, PyObject *kwargs) PyObject * PyObject_CallOneArg(PyObject *func, PyObject *arg) { + EVAL_CALL_STAT_INC_IF_FUNCTION(EVAL_CALL_API, func); assert(arg != NULL); PyObject *_args[2]; PyObject **args = _args + 1; // For PY_VECTORCALL_ARGUMENTS_OFFSET @@ -389,6 +414,7 @@ _PyFunction_Vectorcall(PyObject *func, PyObject* const* stack, assert(nargs >= 0); PyThreadState *tstate = _PyThreadState_GET(); assert(nargs == 0 || stack != NULL); + EVAL_CALL_STAT_INC(EVAL_CALL_FUNCTION_VECTORCALL); if (((PyCodeObject *)f->func_code)->co_flags & CO_OPTIMIZED) { return _PyEval_Vector(tstate, f, NULL, stack, nargs, kwnames); } @@ -520,7 +546,7 @@ _PyObject_CallFunctionVa(PyThreadState *tstate, PyObject *callable, if (stack == NULL) { return NULL; } - + EVAL_CALL_STAT_INC_IF_FUNCTION(EVAL_CALL_API, callable); if (nargs == 1 && PyTuple_Check(stack[0])) { /* Special cases for backward compatibility: - PyObject_CallFunction(func, "O", tuple) calls func(*tuple) @@ -815,6 +841,11 @@ object_vacall(PyThreadState *tstate, PyObject *base, stack[i] = va_arg(vargs, PyObject *); } +#ifdef Py_STATS + if (PyFunction_Check(callable)) { + EVAL_CALL_STAT_INC(EVAL_CALL_API); + } +#endif /* Call the function */ result = _PyObject_VectorcallTstate(tstate, callable, stack, nargs, NULL); @@ -852,6 +883,7 @@ PyObject_VectorcallMethod(PyObject *name, PyObject *const *args, args++; nargsf--; } + EVAL_CALL_STAT_INC_IF_FUNCTION(EVAL_CALL_METHOD, callable); PyObject *result = _PyObject_VectorcallTstate(tstate, callable, args, nargsf, kwnames); Py_DECREF(callable); @@ -955,7 +987,7 @@ _PyStack_AsDict(PyObject *const *values, PyObject *kwnames) The newly allocated argument vector supports PY_VECTORCALL_ARGUMENTS_OFFSET. When done, you must call _PyStack_UnpackDict_Free(stack, nargs, kwnames) */ -static PyObject *const * +PyObject *const * _PyStack_UnpackDict(PyThreadState *tstate, PyObject *const *args, Py_ssize_t nargs, PyObject *kwargs, PyObject **p_kwnames) @@ -991,8 +1023,7 @@ _PyStack_UnpackDict(PyThreadState *tstate, /* Copy positional arguments */ for (Py_ssize_t i = 0; i < nargs; i++) { - Py_INCREF(args[i]); - stack[i] = args[i]; + stack[i] = Py_NewRef(args[i]); } PyObject **kwstack = stack + nargs; @@ -1004,10 +1035,8 @@ _PyStack_UnpackDict(PyThreadState *tstate, unsigned long keys_are_strings = Py_TPFLAGS_UNICODE_SUBCLASS; while (PyDict_Next(kwargs, &pos, &key, &value)) { keys_are_strings &= Py_TYPE(key)->tp_flags; - Py_INCREF(key); - Py_INCREF(value); - PyTuple_SET_ITEM(kwnames, i, key); - kwstack[i] = value; + PyTuple_SET_ITEM(kwnames, i, Py_NewRef(key)); + kwstack[i] = Py_NewRef(value); i++; } @@ -1027,7 +1056,7 @@ _PyStack_UnpackDict(PyThreadState *tstate, return stack; } -static void +void _PyStack_UnpackDict_Free(PyObject *const *stack, Py_ssize_t nargs, PyObject *kwnames) { @@ -1035,6 +1064,20 @@ _PyStack_UnpackDict_Free(PyObject *const *stack, Py_ssize_t nargs, for (Py_ssize_t i = 0; i < n; i++) { Py_DECREF(stack[i]); } + _PyStack_UnpackDict_FreeNoDecRef(stack, kwnames); +} + +void +_PyStack_UnpackDict_FreeNoDecRef(PyObject *const *stack, PyObject *kwnames) +{ PyMem_Free((PyObject **)stack - 1); Py_DECREF(kwnames); } + +// Export for the stable ABI +#undef PyVectorcall_NARGS +Py_ssize_t +PyVectorcall_NARGS(size_t n) +{ + return _PyVectorcall_NARGS(n); +} diff --git a/Objects/capsule.c b/Objects/capsule.c index 606e50e6..baaddb3f 100644 --- a/Objects/capsule.c +++ b/Objects/capsule.c @@ -220,8 +220,7 @@ PyCapsule_Import(const char *name, int no_block) } } else { PyObject *object2 = PyObject_GetAttrString(object, trace); - Py_DECREF(object); - object = object2; + Py_SETREF(object, object2); } if (!object) { goto EXIT; diff --git a/Objects/cellobject.c b/Objects/cellobject.c index 86a89f02..f516707f 100644 --- a/Objects/cellobject.c +++ b/Objects/cellobject.c @@ -11,8 +11,7 @@ PyCell_New(PyObject *obj) op = (PyCellObject *)PyObject_GC_New(PyCellObject, &PyCell_Type); if (op == NULL) return NULL; - op->ob_ref = obj; - Py_XINCREF(obj); + op->ob_ref = Py_XNewRef(obj); _PyObject_GC_TRACK(op); return (PyObject *)op; @@ -56,22 +55,20 @@ PyCell_Get(PyObject *op) PyErr_BadInternalCall(); return NULL; } - Py_XINCREF(((PyCellObject*)op)->ob_ref); - return PyCell_GET(op); + PyObject *value = PyCell_GET(op); + return Py_XNewRef(value); } int -PyCell_Set(PyObject *op, PyObject *obj) +PyCell_Set(PyObject *op, PyObject *value) { - PyObject* oldobj; if (!PyCell_Check(op)) { PyErr_BadInternalCall(); return -1; } - oldobj = PyCell_GET(op); - Py_XINCREF(obj); - PyCell_SET(op, obj); - Py_XDECREF(oldobj); + PyObject *old_value = PyCell_GET(op); + PyCell_SET(op, Py_XNewRef(value)); + Py_XDECREF(old_value); return 0; } @@ -136,15 +133,13 @@ cell_get_contents(PyCellObject *op, void *closure) PyErr_SetString(PyExc_ValueError, "Cell is empty"); return NULL; } - Py_INCREF(op->ob_ref); - return op->ob_ref; + return Py_NewRef(op->ob_ref); } static int cell_set_contents(PyCellObject *op, PyObject *obj, void *Py_UNUSED(ignored)) { - Py_XINCREF(obj); - Py_XSETREF(op->ob_ref, obj); + Py_XSETREF(op->ob_ref, Py_XNewRef(obj)); return 0; } diff --git a/Objects/classobject.c b/Objects/classobject.c index b9708ba0..12dc276f 100644 --- a/Objects/classobject.c +++ b/Objects/classobject.c @@ -48,6 +48,7 @@ method_vectorcall(PyObject *method, PyObject *const *args, PyObject *self = PyMethod_GET_SELF(method); PyObject *func = PyMethod_GET_FUNCTION(method); Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + assert(nargs == 0 || args[nargs-1]); PyObject *result; if (nargsf & PY_VECTORCALL_ARGUMENTS_OFFSET) { @@ -56,6 +57,7 @@ method_vectorcall(PyObject *method, PyObject *const *args, nargs += 1; PyObject *tmp = newargs[0]; newargs[0] = self; + assert(newargs[nargs-1]); result = _PyObject_VectorcallTstate(tstate, func, newargs, nargs, kwnames); newargs[0] = tmp; @@ -113,10 +115,8 @@ PyMethod_New(PyObject *func, PyObject *self) return NULL; } im->im_weakreflist = NULL; - Py_INCREF(func); - im->im_func = func; - Py_INCREF(self); - im->im_self = self; + im->im_func = Py_NewRef(func); + im->im_self = Py_NewRef(self); im->vectorcall = method_vectorcall; _PyObject_GC_TRACK(im); return (PyObject *)im; @@ -183,7 +183,7 @@ method_getattro(PyObject *obj, PyObject *name) PyObject *descr = NULL; { - if (tp->tp_dict == NULL) { + if (!_PyType_IsReady(tp)) { if (PyType_Ready(tp) < 0) return NULL; } @@ -195,8 +195,7 @@ method_getattro(PyObject *obj, PyObject *name) if (f != NULL) return f(descr, obj, (PyObject *)Py_TYPE(obj)); else { - Py_INCREF(descr); - return descr; + return Py_NewRef(descr); } } @@ -267,8 +266,7 @@ method_richcompare(PyObject *self, PyObject *other, int op) res = eq ? Py_True : Py_False; else res = eq ? Py_False : Py_True; - Py_INCREF(res); - return res; + return Py_NewRef(res); } static PyObject * @@ -287,8 +285,7 @@ method_repr(PyMethodObject *a) } if (funcname != NULL && !PyUnicode_Check(funcname)) { - Py_DECREF(funcname); - funcname = NULL; + Py_SETREF(funcname, NULL); } /* XXX Shouldn't use repr()/%R here! */ @@ -359,8 +356,7 @@ PyInstanceMethod_New(PyObject *func) { method = PyObject_GC_New(PyInstanceMethodObject, &PyInstanceMethod_Type); if (method == NULL) return NULL; - Py_INCREF(func); - method->func = func; + method->func = Py_NewRef(func); _PyObject_GC_TRACK(method); return (PyObject *)method; } @@ -401,7 +397,7 @@ instancemethod_getattro(PyObject *self, PyObject *name) PyTypeObject *tp = Py_TYPE(self); PyObject *descr = NULL; - if (tp->tp_dict == NULL) { + if (!_PyType_IsReady(tp)) { if (PyType_Ready(tp) < 0) return NULL; } @@ -412,8 +408,7 @@ instancemethod_getattro(PyObject *self, PyObject *name) if (f != NULL) return f(descr, self, (PyObject *)Py_TYPE(self)); else { - Py_INCREF(descr); - return descr; + return Py_NewRef(descr); } } @@ -443,8 +438,7 @@ static PyObject * instancemethod_descr_get(PyObject *descr, PyObject *obj, PyObject *type) { PyObject *func = PyInstanceMethod_GET_FUNCTION(descr); if (obj == NULL) { - Py_INCREF(func); - return func; + return Py_NewRef(func); } else return PyMethod_New(func, obj); @@ -472,8 +466,7 @@ instancemethod_richcompare(PyObject *self, PyObject *other, int op) res = eq ? Py_True : Py_False; else res = eq ? Py_False : Py_True; - Py_INCREF(res); - return res; + return Py_NewRef(res); } static PyObject * @@ -492,8 +485,7 @@ instancemethod_repr(PyObject *self) return NULL; } if (funcname != NULL && !PyUnicode_Check(funcname)) { - Py_DECREF(funcname); - funcname = NULL; + Py_SETREF(funcname, NULL); } result = PyUnicode_FromFormat("<instancemethod %V at %p>", diff --git a/Objects/clinic/bytearrayobject.c.h b/Objects/clinic/bytearrayobject.c.h index 0b5c01a8..e7bf3183 100644 --- a/Objects/clinic/bytearrayobject.c.h +++ b/Objects/clinic/bytearrayobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + static int bytearray___init___impl(PyByteArrayObject *self, PyObject *arg, const char *encoding, const char *errors); @@ -10,8 +16,31 @@ static int bytearray___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(source), &_Py_ID(encoding), &_Py_ID(errors), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"source", "encoding", "errors", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "bytearray", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "bytearray", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -210,8 +239,31 @@ static PyObject * bytearray_translate(PyByteArrayObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(delete), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "delete", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "translate", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "translate", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *table; @@ -390,8 +442,31 @@ static PyObject * bytearray_split(PyByteArrayObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(sep), &_Py_ID(maxsplit), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"sep", "maxsplit", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "split", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "split", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *sep = Py_None; @@ -489,8 +564,31 @@ static PyObject * bytearray_rsplit(PyByteArrayObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(sep), &_Py_ID(maxsplit), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"sep", "maxsplit", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "rsplit", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "rsplit", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *sep = Py_None; @@ -843,8 +941,31 @@ static PyObject * bytearray_decode(PyByteArrayObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(encoding), &_Py_ID(errors), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"encoding", "errors", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "decode", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "decode", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; const char *encoding = NULL; @@ -927,8 +1048,31 @@ static PyObject * bytearray_splitlines(PyByteArrayObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(keepends), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"keepends", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "splitlines", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "splitlines", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int keepends = 0; @@ -940,8 +1084,8 @@ bytearray_splitlines(PyByteArrayObject *self, PyObject *const *args, Py_ssize_t if (!noptargs) { goto skip_optional_pos; } - keepends = _PyLong_AsInt(args[0]); - if (keepends == -1 && PyErr_Occurred()) { + keepends = PyObject_IsTrue(args[0]); + if (keepends < 0) { goto exit; } skip_optional_pos: @@ -1019,8 +1163,31 @@ static PyObject * bytearray_hex(PyByteArrayObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(sep), &_Py_ID(bytes_per_sep), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"sep", "bytes_per_sep", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "hex", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "hex", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *sep = NULL; @@ -1120,4 +1287,4 @@ bytearray_sizeof(PyByteArrayObject *self, PyObject *Py_UNUSED(ignored)) { return bytearray_sizeof_impl(self); } -/*[clinic end generated code: output=033e9eb5f2bb0139 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=022698e8b0faa272 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/bytesobject.c.h b/Objects/clinic/bytesobject.c.h index 7e857203..060056da 100644 --- a/Objects/clinic/bytesobject.c.h +++ b/Objects/clinic/bytesobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(bytes___bytes____doc__, "__bytes__($self, /)\n" "--\n" @@ -44,8 +50,31 @@ static PyObject * bytes_split(PyBytesObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(sep), &_Py_ID(maxsplit), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"sep", "maxsplit", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "split", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "split", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *sep = Py_None; @@ -195,8 +224,31 @@ static PyObject * bytes_rsplit(PyBytesObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(sep), &_Py_ID(maxsplit), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"sep", "maxsplit", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "rsplit", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "rsplit", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *sep = Py_None; @@ -374,8 +426,31 @@ static PyObject * bytes_translate(PyBytesObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(delete), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "delete", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "translate", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "translate", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *table; @@ -634,8 +709,31 @@ static PyObject * bytes_decode(PyBytesObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(encoding), &_Py_ID(errors), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"encoding", "errors", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "decode", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "decode", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; const char *encoding = NULL; @@ -705,8 +803,31 @@ static PyObject * bytes_splitlines(PyBytesObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(keepends), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"keepends", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "splitlines", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "splitlines", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int keepends = 0; @@ -718,8 +839,8 @@ bytes_splitlines(PyBytesObject *self, PyObject *const *args, Py_ssize_t nargs, P if (!noptargs) { goto skip_optional_pos; } - keepends = _PyLong_AsInt(args[0]); - if (keepends == -1 && PyErr_Occurred()) { + keepends = PyObject_IsTrue(args[0]); + if (keepends < 0) { goto exit; } skip_optional_pos: @@ -797,8 +918,31 @@ static PyObject * bytes_hex(PyBytesObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(sep), &_Py_ID(bytes_per_sep), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"sep", "bytes_per_sep", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "hex", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "hex", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *sep = NULL; @@ -836,8 +980,31 @@ static PyObject * bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(source), &_Py_ID(encoding), &_Py_ID(errors), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"source", "encoding", "errors", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "bytes", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "bytes", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -896,4 +1063,4 @@ skip_optional_pos: exit: return return_value; } -/*[clinic end generated code: output=5727702e63a0a8b7 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=31a9e4af85562612 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/classobject.c.h b/Objects/clinic/classobject.c.h index a4f19001..a7bac630 100644 --- a/Objects/clinic/classobject.c.h +++ b/Objects/clinic/classobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(method___reduce____doc__, "__reduce__($self, /)\n" "--\n" @@ -32,11 +38,11 @@ static PyObject * method_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + PyTypeObject *base_tp = &PyMethod_Type; PyObject *function; PyObject *instance; - if ((type == &PyMethod_Type || - type->tp_init == PyMethod_Type.tp_init) && + if ((type == base_tp || type->tp_init == base_tp->tp_init) && !_PyArg_NoKeywords("method", kwargs)) { goto exit; } @@ -64,10 +70,10 @@ static PyObject * instancemethod_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + PyTypeObject *base_tp = &PyInstanceMethod_Type; PyObject *function; - if ((type == &PyInstanceMethod_Type || - type->tp_init == PyInstanceMethod_Type.tp_init) && + if ((type == base_tp || type->tp_init == base_tp->tp_init) && !_PyArg_NoKeywords("instancemethod", kwargs)) { goto exit; } @@ -80,4 +86,4 @@ instancemethod_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=a230fe125f664416 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=2a5e7fa5947a86cb input=a9049054013a1b77]*/ diff --git a/Objects/clinic/codeobject.c.h b/Objects/clinic/codeobject.c.h index df82524a..1034627e 100644 --- a/Objects/clinic/codeobject.c.h +++ b/Objects/clinic/codeobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(code_new__doc__, "code(argcount, posonlyargcount, kwonlyargcount, nlocals, stacksize,\n" " flags, codestring, constants, names, varnames, filename, name,\n" @@ -24,6 +30,7 @@ static PyObject * code_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + PyTypeObject *base_tp = &PyCode_Type; int argcount; int posonlyargcount; int kwonlyargcount; @@ -43,8 +50,7 @@ code_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) PyObject *freevars = NULL; PyObject *cellvars = NULL; - if ((type == &PyCode_Type || - type->tp_init == PyCode_Type.tp_init) && + if ((type == base_tp || type->tp_init == base_tp->tp_init) && !_PyArg_NoKeywords("code", kwargs)) { goto exit; } @@ -157,12 +163,7 @@ exit: } PyDoc_STRVAR(code_replace__doc__, -"replace($self, /, *, co_argcount=-1, co_posonlyargcount=-1,\n" -" co_kwonlyargcount=-1, co_nlocals=-1, co_stacksize=-1,\n" -" co_flags=-1, co_firstlineno=-1, co_code=None, co_consts=None,\n" -" co_names=None, co_varnames=None, co_freevars=None,\n" -" co_cellvars=None, co_filename=None, co_name=None,\n" -" co_qualname=None, co_linetable=None, co_exceptiontable=None)\n" +"replace($self, /, **changes)\n" "--\n" "\n" "Return a copy of the code object with new values for the specified fields."); @@ -174,20 +175,42 @@ static PyObject * code_replace_impl(PyCodeObject *self, int co_argcount, int co_posonlyargcount, int co_kwonlyargcount, int co_nlocals, int co_stacksize, int co_flags, - int co_firstlineno, PyBytesObject *co_code, - PyObject *co_consts, PyObject *co_names, - PyObject *co_varnames, PyObject *co_freevars, - PyObject *co_cellvars, PyObject *co_filename, - PyObject *co_name, PyObject *co_qualname, - PyBytesObject *co_linetable, - PyBytesObject *co_exceptiontable); + int co_firstlineno, PyObject *co_code, PyObject *co_consts, + PyObject *co_names, PyObject *co_varnames, + PyObject *co_freevars, PyObject *co_cellvars, + PyObject *co_filename, PyObject *co_name, + PyObject *co_qualname, PyObject *co_linetable, + PyObject *co_exceptiontable); static PyObject * code_replace(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 18 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(co_argcount), &_Py_ID(co_posonlyargcount), &_Py_ID(co_kwonlyargcount), &_Py_ID(co_nlocals), &_Py_ID(co_stacksize), &_Py_ID(co_flags), &_Py_ID(co_firstlineno), &_Py_ID(co_code), &_Py_ID(co_consts), &_Py_ID(co_names), &_Py_ID(co_varnames), &_Py_ID(co_freevars), &_Py_ID(co_cellvars), &_Py_ID(co_filename), &_Py_ID(co_name), &_Py_ID(co_qualname), &_Py_ID(co_linetable), &_Py_ID(co_exceptiontable), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"co_argcount", "co_posonlyargcount", "co_kwonlyargcount", "co_nlocals", "co_stacksize", "co_flags", "co_firstlineno", "co_code", "co_consts", "co_names", "co_varnames", "co_freevars", "co_cellvars", "co_filename", "co_name", "co_qualname", "co_linetable", "co_exceptiontable", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "replace", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "replace", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[18]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int co_argcount = self->co_argcount; @@ -197,7 +220,7 @@ code_replace(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObje int co_stacksize = self->co_stacksize; int co_flags = self->co_flags; int co_firstlineno = self->co_firstlineno; - PyBytesObject *co_code = NULL; + PyObject *co_code = NULL; PyObject *co_consts = self->co_consts; PyObject *co_names = self->co_names; PyObject *co_varnames = NULL; @@ -206,8 +229,8 @@ code_replace(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObje PyObject *co_filename = self->co_filename; PyObject *co_name = self->co_name; PyObject *co_qualname = self->co_qualname; - PyBytesObject *co_linetable = (PyBytesObject *)self->co_linetable; - PyBytesObject *co_exceptiontable = (PyBytesObject *)self->co_exceptiontable; + PyObject *co_linetable = self->co_linetable; + PyObject *co_exceptiontable = self->co_exceptiontable; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 0, 0, argsbuf); if (!args) { @@ -284,7 +307,7 @@ code_replace(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObje _PyArg_BadArgument("replace", "argument 'co_code'", "bytes", args[7]); goto exit; } - co_code = (PyBytesObject *)args[7]; + co_code = args[7]; if (!--noptargs) { goto skip_optional_kwonly; } @@ -383,7 +406,7 @@ code_replace(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObje _PyArg_BadArgument("replace", "argument 'co_linetable'", "bytes", args[16]); goto exit; } - co_linetable = (PyBytesObject *)args[16]; + co_linetable = args[16]; if (!--noptargs) { goto skip_optional_kwonly; } @@ -392,7 +415,7 @@ code_replace(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObje _PyArg_BadArgument("replace", "argument 'co_exceptiontable'", "bytes", args[17]); goto exit; } - co_exceptiontable = (PyBytesObject *)args[17]; + co_exceptiontable = args[17]; skip_optional_kwonly: return_value = code_replace_impl(self, co_argcount, co_posonlyargcount, co_kwonlyargcount, co_nlocals, co_stacksize, co_flags, co_firstlineno, co_code, co_consts, co_names, co_varnames, co_freevars, co_cellvars, co_filename, co_name, co_qualname, co_linetable, co_exceptiontable); @@ -418,8 +441,31 @@ static PyObject * code__varname_from_oparg(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(oparg), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"oparg", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "_varname_from_oparg", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "_varname_from_oparg", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int oparg; @@ -436,4 +482,4 @@ code__varname_from_oparg(PyCodeObject *self, PyObject *const *args, Py_ssize_t n exit: return return_value; } -/*[clinic end generated code: output=9c521b6c79f90ff7 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=ff40f7bdd3851de3 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/complexobject.c.h b/Objects/clinic/complexobject.c.h index e7d8065e..e92c6e98 100644 --- a/Objects/clinic/complexobject.c.h +++ b/Objects/clinic/complexobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(complex_conjugate__doc__, "conjugate($self, /)\n" "--\n" @@ -102,8 +108,31 @@ static PyObject * complex_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(real), &_Py_ID(imag), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"real", "imag", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "complex", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "complex", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -131,4 +160,4 @@ skip_optional_pos: exit: return return_value; } -/*[clinic end generated code: output=6d85094ace15677e input=a9049054013a1b77]*/ +/*[clinic end generated code: output=52e85a1e258425d6 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/descrobject.c.h b/Objects/clinic/descrobject.c.h index d248b91b..75706437 100644 --- a/Objects/clinic/descrobject.c.h +++ b/Objects/clinic/descrobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + static PyObject * mappingproxy_new_impl(PyTypeObject *type, PyObject *mapping); @@ -9,8 +15,31 @@ static PyObject * mappingproxy_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(mapping), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"mapping", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "mappingproxy", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "mappingproxy", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -72,8 +101,31 @@ static int property_init(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(fget), &_Py_ID(fset), &_Py_ID(fdel), &_Py_ID(doc), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"fget", "fset", "fdel", "doc", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "property", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "property", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -115,4 +167,4 @@ skip_optional_pos: exit: return return_value; } -/*[clinic end generated code: output=916624e717862abc input=a9049054013a1b77]*/ +/*[clinic end generated code: output=8dc1ddfcf764ac8e input=a9049054013a1b77]*/ diff --git a/Objects/clinic/dictobject.c.h b/Objects/clinic/dictobject.c.h index eda86c31..bc245233 100644 --- a/Objects/clinic/dictobject.c.h +++ b/Objects/clinic/dictobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(dict_fromkeys__doc__, "fromkeys($type, iterable, value=None, /)\n" "--\n" @@ -191,4 +197,4 @@ dict___reversed__(PyDictObject *self, PyObject *Py_UNUSED(ignored)) { return dict___reversed___impl(self); } -/*[clinic end generated code: output=582766ac0154c8bf input=a9049054013a1b77]*/ +/*[clinic end generated code: output=c0064abbea6091c5 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/enumobject.c.h b/Objects/clinic/enumobject.c.h index 7513c952..adf78efd 100644 --- a/Objects/clinic/enumobject.c.h +++ b/Objects/clinic/enumobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(enum_new__doc__, "enumerate(iterable, start=0)\n" "--\n" @@ -24,8 +30,31 @@ static PyObject * enum_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(iterable), &_Py_ID(start), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"iterable", "start", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "enumerate", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "enumerate", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -62,10 +91,10 @@ static PyObject * reversed_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + PyTypeObject *base_tp = &PyReversed_Type; PyObject *seq; - if ((type == &PyReversed_Type || - type->tp_init == PyReversed_Type.tp_init) && + if ((type == base_tp || type->tp_init == base_tp->tp_init) && !_PyArg_NoKeywords("reversed", kwargs)) { goto exit; } @@ -78,4 +107,4 @@ reversed_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=a3937b6b33499560 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=aba0ddbeab1601e3 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/floatobject.c.h b/Objects/clinic/floatobject.c.h index bf0748f3..a99fd74e 100644 --- a/Objects/clinic/floatobject.c.h +++ b/Objects/clinic/floatobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(float_is_integer__doc__, "is_integer($self, /)\n" "--\n" @@ -167,12 +173,10 @@ PyDoc_STRVAR(float_as_integer_ratio__doc__, "as_integer_ratio($self, /)\n" "--\n" "\n" -"Return integer ratio.\n" -"\n" -"Return a pair of integers, whose ratio is exactly equal to the original float\n" -"and with a positive denominator.\n" +"Return a pair of integers, whose ratio is exactly equal to the original float.\n" "\n" -"Raise OverflowError on infinities and a ValueError on NaNs.\n" +"The ratio is in lowest terms and has a positive denominator. Raise\n" +"OverflowError on infinities and a ValueError on NaNs.\n" "\n" ">>> (10.0).as_integer_ratio()\n" "(10, 1)\n" @@ -206,10 +210,10 @@ static PyObject * float_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + PyTypeObject *base_tp = &PyFloat_Type; PyObject *x = NULL; - if ((type == &PyFloat_Type || - type->tp_init == PyFloat_Type.tp_init) && + if ((type == base_tp || type->tp_init == base_tp->tp_init) && !_PyArg_NoKeywords("float", kwargs)) { goto exit; } @@ -321,4 +325,4 @@ float___format__(PyObject *self, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=a6e6467624a92a43 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=ea329577074911b9 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/funcobject.c.h b/Objects/clinic/funcobject.c.h index 17fb13fe..c3a3a8ed 100644 --- a/Objects/clinic/funcobject.c.h +++ b/Objects/clinic/funcobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(func_new__doc__, "function(code, globals, name=None, argdefs=None, closure=None)\n" "--\n" @@ -27,8 +33,31 @@ static PyObject * func_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 5 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(code), &_Py_ID(globals), &_Py_ID(name), &_Py_ID(argdefs), &_Py_ID(closure), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"code", "globals", "name", "argdefs", "closure", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "function", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "function", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -75,4 +104,4 @@ skip_optional_pos: exit: return return_value; } -/*[clinic end generated code: output=3d96afa3396e5c82 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=777cead7b1f6fad3 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/listobject.c.h b/Objects/clinic/listobject.c.h index 2499383c..e3d6ffa9 100644 --- a/Objects/clinic/listobject.c.h +++ b/Objects/clinic/listobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(list_insert__doc__, "insert($self, index, object, /)\n" "--\n" @@ -166,8 +172,31 @@ static PyObject * list_sort(PyListObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(key), &_Py_ID(reverse), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"key", "reverse", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "sort", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "sort", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *keyfunc = Py_None; @@ -186,8 +215,8 @@ list_sort(PyListObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject goto skip_optional_kwonly; } } - reverse = _PyLong_AsInt(args[1]); - if (reverse == -1 && PyErr_Occurred()) { + reverse = PyObject_IsTrue(args[1]); + if (reverse < 0) { goto exit; } skip_optional_kwonly: @@ -297,10 +326,11 @@ static int list___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; + PyTypeObject *base_tp = &PyList_Type; PyObject *iterable = NULL; - if ((Py_IS_TYPE(self, &PyList_Type) || - Py_TYPE(self)->tp_new == PyList_Type.tp_new) && + if ((Py_IS_TYPE(self, base_tp) || + Py_TYPE(self)->tp_new == base_tp->tp_new) && !_PyArg_NoKeywords("list", kwargs)) { goto exit; } @@ -353,4 +383,4 @@ list___reversed__(PyListObject *self, PyObject *Py_UNUSED(ignored)) { return list___reversed___impl(self); } -/*[clinic end generated code: output=eab97a76b1568a03 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=2ca109d8acc775bc input=a9049054013a1b77]*/ diff --git a/Objects/clinic/longobject.c.h b/Objects/clinic/longobject.c.h index 59b79636..c26ceafb 100644 --- a/Objects/clinic/longobject.c.h +++ b/Objects/clinic/longobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + static PyObject * long_new_impl(PyTypeObject *type, PyObject *x, PyObject *obase); @@ -9,8 +15,31 @@ static PyObject * long_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(base), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "base", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "int", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "int", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -59,7 +88,8 @@ int___getnewargs__(PyObject *self, PyObject *Py_UNUSED(ignored)) PyDoc_STRVAR(int___format____doc__, "__format__($self, format_spec, /)\n" "--\n" -"\n"); +"\n" +"Convert to a string according to format_spec."); #define INT___FORMAT___METHODDEF \ {"__format__", (PyCFunction)int___format__, METH_O, int___format____doc__}, @@ -201,10 +231,9 @@ PyDoc_STRVAR(int_as_integer_ratio__doc__, "as_integer_ratio($self, /)\n" "--\n" "\n" -"Return integer ratio.\n" +"Return a pair of integers, whose ratio is equal to the original int.\n" "\n" -"Return a pair of integers, whose ratio is exactly equal to the original int\n" -"and with a positive denominator.\n" +"The ratio is in lowest terms and has a positive denominator.\n" "\n" ">>> (10).as_integer_ratio()\n" "(10, 1)\n" @@ -257,8 +286,31 @@ static PyObject * int_to_bytes(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(length), &_Py_ID(byteorder), &_Py_ID(signed), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"length", "byteorder", "signed", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "to_bytes", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "to_bytes", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; Py_ssize_t length = 1; @@ -348,8 +400,31 @@ static PyObject * int_from_bytes(PyTypeObject *type, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(bytes), &_Py_ID(byteorder), &_Py_ID(signed), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"bytes", "byteorder", "signed", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "from_bytes", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "from_bytes", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *bytes_obj; @@ -391,4 +466,22 @@ skip_optional_kwonly: exit: return return_value; } -/*[clinic end generated code: output=899e57c41861a8e9 input=a9049054013a1b77]*/ + +PyDoc_STRVAR(int_is_integer__doc__, +"is_integer($self, /)\n" +"--\n" +"\n" +"Returns True. Exists for duck type compatibility with float.is_integer."); + +#define INT_IS_INTEGER_METHODDEF \ + {"is_integer", (PyCFunction)int_is_integer, METH_NOARGS, int_is_integer__doc__}, + +static PyObject * +int_is_integer_impl(PyObject *self); + +static PyObject * +int_is_integer(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return int_is_integer_impl(self); +} +/*[clinic end generated code: output=cfdf35d916158d4f input=a9049054013a1b77]*/ diff --git a/Objects/clinic/memoryobject.c.h b/Objects/clinic/memoryobject.c.h index 73ef8d14..25a22341 100644 --- a/Objects/clinic/memoryobject.c.h +++ b/Objects/clinic/memoryobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(memoryview__doc__, "memoryview(object)\n" "--\n" @@ -15,8 +21,31 @@ static PyObject * memoryview(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(object), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"object", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "memoryview", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "memoryview", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -33,6 +62,66 @@ exit: return return_value; } +PyDoc_STRVAR(memoryview__from_flags__doc__, +"_from_flags($type, /, object, flags)\n" +"--\n" +"\n" +"Create a new memoryview object which references the given object."); + +#define MEMORYVIEW__FROM_FLAGS_METHODDEF \ + {"_from_flags", _PyCFunction_CAST(memoryview__from_flags), METH_FASTCALL|METH_KEYWORDS|METH_CLASS, memoryview__from_flags__doc__}, + +static PyObject * +memoryview__from_flags_impl(PyTypeObject *type, PyObject *object, int flags); + +static PyObject * +memoryview__from_flags(PyTypeObject *type, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(object), &_Py_ID(flags), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"object", "flags", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "_from_flags", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + PyObject *object; + int flags; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); + if (!args) { + goto exit; + } + object = args[0]; + flags = _PyLong_AsInt(args[1]); + if (flags == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = memoryview__from_flags_impl(type, object, flags); + +exit: + return return_value; +} + PyDoc_STRVAR(memoryview_release__doc__, "release($self, /)\n" "--\n" @@ -68,8 +157,31 @@ static PyObject * memoryview_cast(PyMemoryViewObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(format), &_Py_ID(shape), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"format", "shape", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "cast", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "cast", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *format; @@ -156,8 +268,31 @@ static PyObject * memoryview_tobytes(PyMemoryViewObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(order), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"order", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "tobytes", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "tobytes", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; const char *order = NULL; @@ -228,8 +363,31 @@ static PyObject * memoryview_hex(PyMemoryViewObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(sep), &_Py_ID(bytes_per_sep), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"sep", "bytes_per_sep", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "hex", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "hex", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *sep = NULL; @@ -258,4 +416,4 @@ skip_optional_pos: exit: return return_value; } -/*[clinic end generated code: output=48be570b5e6038e3 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=01613814112cedd7 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/moduleobject.c.h b/Objects/clinic/moduleobject.c.h index c1534eae..861bcea6 100644 --- a/Objects/clinic/moduleobject.c.h +++ b/Objects/clinic/moduleobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(module___init____doc__, "module(name, doc=None)\n" "--\n" @@ -17,8 +23,31 @@ static int module___init__(PyObject *self, PyObject *args, PyObject *kwargs) { int return_value = -1; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(name), &_Py_ID(doc), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"name", "doc", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "module", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "module", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -48,4 +77,4 @@ skip_optional_pos: exit: return return_value; } -/*[clinic end generated code: output=680276bc3a496d7a input=a9049054013a1b77]*/ +/*[clinic end generated code: output=2f897c9e4721f03f input=a9049054013a1b77]*/ diff --git a/Objects/clinic/odictobject.c.h b/Objects/clinic/odictobject.c.h index 5bb9952c..115a134e 100644 --- a/Objects/clinic/odictobject.c.h +++ b/Objects/clinic/odictobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(OrderedDict_fromkeys__doc__, "fromkeys($type, /, iterable, value=None)\n" "--\n" @@ -18,8 +24,31 @@ static PyObject * OrderedDict_fromkeys(PyTypeObject *type, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(iterable), &_Py_ID(value), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"iterable", "value", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "fromkeys", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "fromkeys", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *seq; @@ -60,8 +89,31 @@ static PyObject * OrderedDict_setdefault(PyODictObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(key), &_Py_ID(default), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"key", "default", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "setdefault", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "setdefault", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *key; @@ -103,8 +155,31 @@ static PyObject * OrderedDict_pop(PyODictObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(key), &_Py_ID(default), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"key", "default", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "pop", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "pop", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *key; @@ -144,8 +219,31 @@ static PyObject * OrderedDict_popitem(PyODictObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(last), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"last", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "popitem", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "popitem", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int last = 1; @@ -186,8 +284,31 @@ static PyObject * OrderedDict_move_to_end(PyODictObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(key), &_Py_ID(last), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"key", "last", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "move_to_end", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "move_to_end", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *key; @@ -211,4 +332,4 @@ skip_optional_pos: exit: return return_value; } -/*[clinic end generated code: output=4182a5dab66963d0 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=76d85a9162d62ca8 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/structseq.c.h b/Objects/clinic/structseq.c.h index b3b48365..40ba18a5 100644 --- a/Objects/clinic/structseq.c.h +++ b/Objects/clinic/structseq.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + static PyObject * structseq_new_impl(PyTypeObject *type, PyObject *arg, PyObject *dict); @@ -9,8 +15,31 @@ static PyObject * structseq_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(sequence), &_Py_ID(dict), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"sequence", "dict", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "structseq", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "structseq", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -33,4 +62,4 @@ skip_optional_pos: exit: return return_value; } -/*[clinic end generated code: output=ed3019acf49b656c input=a9049054013a1b77]*/ +/*[clinic end generated code: output=802d5663c7d01024 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/tupleobject.c.h b/Objects/clinic/tupleobject.c.h index 224fc0c3..3de95759 100644 --- a/Objects/clinic/tupleobject.c.h +++ b/Objects/clinic/tupleobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(tuple_index__doc__, "index($self, value, start=0, stop=sys.maxsize, /)\n" "--\n" @@ -75,10 +81,10 @@ static PyObject * tuple_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + PyTypeObject *base_tp = &PyTuple_Type; PyObject *iterable = NULL; - if ((type == &PyTuple_Type || - type->tp_init == PyTuple_Type.tp_init) && + if ((type == base_tp || type->tp_init == base_tp->tp_init) && !_PyArg_NoKeywords("tuple", kwargs)) { goto exit; } @@ -112,4 +118,4 @@ tuple___getnewargs__(PyTupleObject *self, PyObject *Py_UNUSED(ignored)) { return tuple___getnewargs___impl(self); } -/*[clinic end generated code: output=044496dc917f8a97 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=48a9e0834b300ac3 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/typeobject.c.h b/Objects/clinic/typeobject.c.h index dee3139b..dc9746ab 100644 --- a/Objects/clinic/typeobject.c.h +++ b/Objects/clinic/typeobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(type___instancecheck____doc__, "__instancecheck__($self, instance, /)\n" "--\n" @@ -198,7 +204,9 @@ PyDoc_STRVAR(object___format____doc__, "__format__($self, format_spec, /)\n" "--\n" "\n" -"Default object formatter."); +"Default object formatter.\n" +"\n" +"Return str(self) if format_spec is empty. Raise TypeError otherwise."); #define OBJECT___FORMAT___METHODDEF \ {"__format__", (PyCFunction)object___format__, METH_O, object___format____doc__}, @@ -261,4 +269,4 @@ object___dir__(PyObject *self, PyObject *Py_UNUSED(ignored)) { return object___dir___impl(self); } -/*[clinic end generated code: output=a30090032b8e6195 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=d2fc52440a89f2fa input=a9049054013a1b77]*/ diff --git a/Objects/clinic/typevarobject.c.h b/Objects/clinic/typevarobject.c.h new file mode 100644 index 00000000..54189b98 --- /dev/null +++ b/Objects/clinic/typevarobject.c.h @@ -0,0 +1,786 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + +PyDoc_STRVAR(typevar_new__doc__, +"typevar(name, *constraints, *, bound=None, covariant=False,\n" +" contravariant=False, infer_variance=False)\n" +"--\n" +"\n" +"Create a TypeVar."); + +static PyObject * +typevar_new_impl(PyTypeObject *type, PyObject *name, PyObject *constraints, + PyObject *bound, int covariant, int contravariant, + int infer_variance); + +static PyObject * +typevar_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 5 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(name), &_Py_ID(bound), &_Py_ID(covariant), &_Py_ID(contravariant), &_Py_ID(infer_variance), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"name", "bound", "covariant", "contravariant", "infer_variance", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "typevar", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[6]; + PyObject * const *fastargs; + Py_ssize_t nargs = PyTuple_GET_SIZE(args); + Py_ssize_t noptargs = Py_MIN(nargs, 1) + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 1; + PyObject *name; + PyObject *constraints = NULL; + PyObject *bound = Py_None; + int covariant = 0; + int contravariant = 0; + int infer_variance = 0; + + fastargs = _PyArg_UnpackKeywordsWithVararg(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 1, 0, 1, argsbuf); + if (!fastargs) { + goto exit; + } + if (!PyUnicode_Check(fastargs[0])) { + _PyArg_BadArgument("typevar", "argument 'name'", "str", fastargs[0]); + goto exit; + } + name = fastargs[0]; + constraints = fastargs[1]; + if (!noptargs) { + goto skip_optional_kwonly; + } + if (fastargs[2]) { + bound = fastargs[2]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (fastargs[3]) { + covariant = PyObject_IsTrue(fastargs[3]); + if (covariant < 0) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (fastargs[4]) { + contravariant = PyObject_IsTrue(fastargs[4]); + if (contravariant < 0) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + infer_variance = PyObject_IsTrue(fastargs[5]); + if (infer_variance < 0) { + goto exit; + } +skip_optional_kwonly: + return_value = typevar_new_impl(type, name, constraints, bound, covariant, contravariant, infer_variance); + +exit: + Py_XDECREF(constraints); + return return_value; +} + +PyDoc_STRVAR(typevar_typing_subst__doc__, +"__typing_subst__($self, /, arg)\n" +"--\n" +"\n"); + +#define TYPEVAR_TYPING_SUBST_METHODDEF \ + {"__typing_subst__", _PyCFunction_CAST(typevar_typing_subst), METH_FASTCALL|METH_KEYWORDS, typevar_typing_subst__doc__}, + +static PyObject * +typevar_typing_subst_impl(typevarobject *self, PyObject *arg); + +static PyObject * +typevar_typing_subst(typevarobject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(arg), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"arg", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "__typing_subst__", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject *arg; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + arg = args[0]; + return_value = typevar_typing_subst_impl(self, arg); + +exit: + return return_value; +} + +PyDoc_STRVAR(typevar_reduce__doc__, +"__reduce__($self, /)\n" +"--\n" +"\n"); + +#define TYPEVAR_REDUCE_METHODDEF \ + {"__reduce__", (PyCFunction)typevar_reduce, METH_NOARGS, typevar_reduce__doc__}, + +static PyObject * +typevar_reduce_impl(typevarobject *self); + +static PyObject * +typevar_reduce(typevarobject *self, PyObject *Py_UNUSED(ignored)) +{ + return typevar_reduce_impl(self); +} + +PyDoc_STRVAR(paramspecargs_new__doc__, +"paramspecargs(origin)\n" +"--\n" +"\n" +"Create a ParamSpecArgs object."); + +static PyObject * +paramspecargs_new_impl(PyTypeObject *type, PyObject *origin); + +static PyObject * +paramspecargs_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(origin), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"origin", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "paramspecargs", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject * const *fastargs; + Py_ssize_t nargs = PyTuple_GET_SIZE(args); + PyObject *origin; + + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 1, 0, argsbuf); + if (!fastargs) { + goto exit; + } + origin = fastargs[0]; + return_value = paramspecargs_new_impl(type, origin); + +exit: + return return_value; +} + +PyDoc_STRVAR(paramspeckwargs_new__doc__, +"paramspeckwargs(origin)\n" +"--\n" +"\n" +"Create a ParamSpecKwargs object."); + +static PyObject * +paramspeckwargs_new_impl(PyTypeObject *type, PyObject *origin); + +static PyObject * +paramspeckwargs_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(origin), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"origin", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "paramspeckwargs", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject * const *fastargs; + Py_ssize_t nargs = PyTuple_GET_SIZE(args); + PyObject *origin; + + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 1, 0, argsbuf); + if (!fastargs) { + goto exit; + } + origin = fastargs[0]; + return_value = paramspeckwargs_new_impl(type, origin); + +exit: + return return_value; +} + +PyDoc_STRVAR(paramspec_new__doc__, +"paramspec(name, *, bound=None, covariant=False, contravariant=False,\n" +" infer_variance=False)\n" +"--\n" +"\n" +"Create a ParamSpec object."); + +static PyObject * +paramspec_new_impl(PyTypeObject *type, PyObject *name, PyObject *bound, + int covariant, int contravariant, int infer_variance); + +static PyObject * +paramspec_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 5 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(name), &_Py_ID(bound), &_Py_ID(covariant), &_Py_ID(contravariant), &_Py_ID(infer_variance), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"name", "bound", "covariant", "contravariant", "infer_variance", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "paramspec", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[5]; + PyObject * const *fastargs; + Py_ssize_t nargs = PyTuple_GET_SIZE(args); + Py_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 1; + PyObject *name; + PyObject *bound = Py_None; + int covariant = 0; + int contravariant = 0; + int infer_variance = 0; + + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 1, 0, argsbuf); + if (!fastargs) { + goto exit; + } + if (!PyUnicode_Check(fastargs[0])) { + _PyArg_BadArgument("paramspec", "argument 'name'", "str", fastargs[0]); + goto exit; + } + name = fastargs[0]; + if (!noptargs) { + goto skip_optional_kwonly; + } + if (fastargs[1]) { + bound = fastargs[1]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (fastargs[2]) { + covariant = PyObject_IsTrue(fastargs[2]); + if (covariant < 0) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (fastargs[3]) { + contravariant = PyObject_IsTrue(fastargs[3]); + if (contravariant < 0) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + infer_variance = PyObject_IsTrue(fastargs[4]); + if (infer_variance < 0) { + goto exit; + } +skip_optional_kwonly: + return_value = paramspec_new_impl(type, name, bound, covariant, contravariant, infer_variance); + +exit: + return return_value; +} + +PyDoc_STRVAR(paramspec_typing_subst__doc__, +"__typing_subst__($self, /, arg)\n" +"--\n" +"\n"); + +#define PARAMSPEC_TYPING_SUBST_METHODDEF \ + {"__typing_subst__", _PyCFunction_CAST(paramspec_typing_subst), METH_FASTCALL|METH_KEYWORDS, paramspec_typing_subst__doc__}, + +static PyObject * +paramspec_typing_subst_impl(paramspecobject *self, PyObject *arg); + +static PyObject * +paramspec_typing_subst(paramspecobject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(arg), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"arg", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "__typing_subst__", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject *arg; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + arg = args[0]; + return_value = paramspec_typing_subst_impl(self, arg); + +exit: + return return_value; +} + +PyDoc_STRVAR(paramspec_typing_prepare_subst__doc__, +"__typing_prepare_subst__($self, /, alias, args)\n" +"--\n" +"\n"); + +#define PARAMSPEC_TYPING_PREPARE_SUBST_METHODDEF \ + {"__typing_prepare_subst__", _PyCFunction_CAST(paramspec_typing_prepare_subst), METH_FASTCALL|METH_KEYWORDS, paramspec_typing_prepare_subst__doc__}, + +static PyObject * +paramspec_typing_prepare_subst_impl(paramspecobject *self, PyObject *alias, + PyObject *args); + +static PyObject * +paramspec_typing_prepare_subst(paramspecobject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(alias), &_Py_ID(args), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"alias", "args", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "__typing_prepare_subst__", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + PyObject *alias; + PyObject *__clinic_args; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); + if (!args) { + goto exit; + } + alias = args[0]; + __clinic_args = args[1]; + return_value = paramspec_typing_prepare_subst_impl(self, alias, __clinic_args); + +exit: + return return_value; +} + +PyDoc_STRVAR(paramspec_reduce__doc__, +"__reduce__($self, /)\n" +"--\n" +"\n"); + +#define PARAMSPEC_REDUCE_METHODDEF \ + {"__reduce__", (PyCFunction)paramspec_reduce, METH_NOARGS, paramspec_reduce__doc__}, + +static PyObject * +paramspec_reduce_impl(paramspecobject *self); + +static PyObject * +paramspec_reduce(paramspecobject *self, PyObject *Py_UNUSED(ignored)) +{ + return paramspec_reduce_impl(self); +} + +PyDoc_STRVAR(typevartuple__doc__, +"typevartuple(name)\n" +"--\n" +"\n" +"Create a new TypeVarTuple with the given name."); + +static PyObject * +typevartuple_impl(PyTypeObject *type, PyObject *name); + +static PyObject * +typevartuple(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(name), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"name", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "typevartuple", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject * const *fastargs; + Py_ssize_t nargs = PyTuple_GET_SIZE(args); + PyObject *name; + + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 1, 0, argsbuf); + if (!fastargs) { + goto exit; + } + if (!PyUnicode_Check(fastargs[0])) { + _PyArg_BadArgument("typevartuple", "argument 'name'", "str", fastargs[0]); + goto exit; + } + name = fastargs[0]; + return_value = typevartuple_impl(type, name); + +exit: + return return_value; +} + +PyDoc_STRVAR(typevartuple_typing_subst__doc__, +"__typing_subst__($self, /, arg)\n" +"--\n" +"\n"); + +#define TYPEVARTUPLE_TYPING_SUBST_METHODDEF \ + {"__typing_subst__", _PyCFunction_CAST(typevartuple_typing_subst), METH_FASTCALL|METH_KEYWORDS, typevartuple_typing_subst__doc__}, + +static PyObject * +typevartuple_typing_subst_impl(typevartupleobject *self, PyObject *arg); + +static PyObject * +typevartuple_typing_subst(typevartupleobject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(arg), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"arg", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "__typing_subst__", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject *arg; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + arg = args[0]; + return_value = typevartuple_typing_subst_impl(self, arg); + +exit: + return return_value; +} + +PyDoc_STRVAR(typevartuple_typing_prepare_subst__doc__, +"__typing_prepare_subst__($self, /, alias, args)\n" +"--\n" +"\n"); + +#define TYPEVARTUPLE_TYPING_PREPARE_SUBST_METHODDEF \ + {"__typing_prepare_subst__", _PyCFunction_CAST(typevartuple_typing_prepare_subst), METH_FASTCALL|METH_KEYWORDS, typevartuple_typing_prepare_subst__doc__}, + +static PyObject * +typevartuple_typing_prepare_subst_impl(typevartupleobject *self, + PyObject *alias, PyObject *args); + +static PyObject * +typevartuple_typing_prepare_subst(typevartupleobject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(alias), &_Py_ID(args), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"alias", "args", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "__typing_prepare_subst__", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + PyObject *alias; + PyObject *__clinic_args; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf); + if (!args) { + goto exit; + } + alias = args[0]; + __clinic_args = args[1]; + return_value = typevartuple_typing_prepare_subst_impl(self, alias, __clinic_args); + +exit: + return return_value; +} + +PyDoc_STRVAR(typevartuple_reduce__doc__, +"__reduce__($self, /)\n" +"--\n" +"\n"); + +#define TYPEVARTUPLE_REDUCE_METHODDEF \ + {"__reduce__", (PyCFunction)typevartuple_reduce, METH_NOARGS, typevartuple_reduce__doc__}, + +static PyObject * +typevartuple_reduce_impl(typevartupleobject *self); + +static PyObject * +typevartuple_reduce(typevartupleobject *self, PyObject *Py_UNUSED(ignored)) +{ + return typevartuple_reduce_impl(self); +} + +PyDoc_STRVAR(typealias_reduce__doc__, +"__reduce__($self, /)\n" +"--\n" +"\n"); + +#define TYPEALIAS_REDUCE_METHODDEF \ + {"__reduce__", (PyCFunction)typealias_reduce, METH_NOARGS, typealias_reduce__doc__}, + +static PyObject * +typealias_reduce_impl(typealiasobject *self); + +static PyObject * +typealias_reduce(typealiasobject *self, PyObject *Py_UNUSED(ignored)) +{ + return typealias_reduce_impl(self); +} + +PyDoc_STRVAR(typealias_new__doc__, +"typealias(name, value, *, type_params=<unrepresentable>)\n" +"--\n" +"\n" +"Create a TypeAliasType."); + +static PyObject * +typealias_new_impl(PyTypeObject *type, PyObject *name, PyObject *value, + PyObject *type_params); + +static PyObject * +typealias_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(name), &_Py_ID(value), &_Py_ID(type_params), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"name", "value", "type_params", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "typealias", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[3]; + PyObject * const *fastargs; + Py_ssize_t nargs = PyTuple_GET_SIZE(args); + Py_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 2; + PyObject *name; + PyObject *value; + PyObject *type_params = NULL; + + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 2, 2, 0, argsbuf); + if (!fastargs) { + goto exit; + } + if (!PyUnicode_Check(fastargs[0])) { + _PyArg_BadArgument("typealias", "argument 'name'", "str", fastargs[0]); + goto exit; + } + name = fastargs[0]; + value = fastargs[1]; + if (!noptargs) { + goto skip_optional_kwonly; + } + type_params = fastargs[2]; +skip_optional_kwonly: + return_value = typealias_new_impl(type, name, value, type_params); + +exit: + return return_value; +} +/*[clinic end generated code: output=807bcd30ebd10ac3 input=a9049054013a1b77]*/ diff --git a/Objects/clinic/unicodeobject.c.h b/Objects/clinic/unicodeobject.c.h index 07877693..d3769eb0 100644 --- a/Objects/clinic/unicodeobject.c.h +++ b/Objects/clinic/unicodeobject.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(EncodingMap_size__doc__, "size($self, /)\n" "--\n" @@ -154,8 +160,31 @@ static PyObject * unicode_encode(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(encoding), &_Py_ID(errors), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"encoding", "errors", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "encode", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "encode", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; const char *encoding = NULL; @@ -224,8 +253,31 @@ static PyObject * unicode_expandtabs(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(tabsize), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"tabsize", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "expandtabs", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "expandtabs", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int tabsize = 8; @@ -882,7 +934,7 @@ PyDoc_STRVAR(unicode_split__doc__, " The separator used to split the string.\n" "\n" " When set to None (the default value), will split on any whitespace\n" -" character (including \\\\n \\\\r \\\\t \\\\f and spaces) and will discard\n" +" character (including \\n \\r \\t \\f and spaces) and will discard\n" " empty strings from the result.\n" " maxsplit\n" " Maximum number of splits (starting from the left).\n" @@ -902,8 +954,31 @@ static PyObject * unicode_split(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(sep), &_Py_ID(maxsplit), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"sep", "maxsplit", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "split", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "split", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *sep = Py_None; @@ -983,7 +1058,7 @@ PyDoc_STRVAR(unicode_rsplit__doc__, " The separator used to split the string.\n" "\n" " When set to None (the default value), will split on any whitespace\n" -" character (including \\\\n \\\\r \\\\t \\\\f and spaces) and will discard\n" +" character (including \\n \\r \\t \\f and spaces) and will discard\n" " empty strings from the result.\n" " maxsplit\n" " Maximum number of splits (starting from the left).\n" @@ -1001,8 +1076,31 @@ static PyObject * unicode_rsplit(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(sep), &_Py_ID(maxsplit), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"sep", "maxsplit", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "rsplit", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "rsplit", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *sep = Py_None; @@ -1059,8 +1157,31 @@ static PyObject * unicode_splitlines(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(keepends), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"keepends", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "splitlines", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "splitlines", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int keepends = 0; @@ -1072,8 +1193,8 @@ unicode_splitlines(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyOb if (!noptargs) { goto skip_optional_pos; } - keepends = _PyLong_AsInt(args[0]); - if (keepends == -1 && PyErr_Occurred()) { + keepends = PyObject_IsTrue(args[0]); + if (keepends < 0) { goto exit; } skip_optional_pos: @@ -1293,8 +1414,31 @@ static PyObject * unicode_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(object), &_Py_ID(encoding), &_Py_ID(errors), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"object", "encoding", "errors", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "str", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "str", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -1353,4 +1497,4 @@ skip_optional_pos: exit: return return_value; } -/*[clinic end generated code: output=b5dd7cefead9a8e7 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=32edbbf75dc8a03b input=a9049054013a1b77]*/ diff --git a/Objects/codeobject.c b/Objects/codeobject.c index 32938b52..aee12136 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -4,12 +4,108 @@ #include "opcode.h" #include "structmember.h" // PyMemberDef #include "pycore_code.h" // _PyCodeConstructor +#include "pycore_frame.h" // FRAME_SPECIALS_SIZE #include "pycore_interp.h" // PyInterpreterState.co_extra_freefuncs #include "pycore_opcode.h" // _PyOpcode_Deopt #include "pycore_pystate.h" // _PyInterpreterState_GET() #include "pycore_tuple.h" // _PyTuple_ITEMS() #include "clinic/codeobject.c.h" +static PyObject* code_repr(PyCodeObject *co); + +static const char * +code_event_name(PyCodeEvent event) { + switch (event) { + #define CASE(op) \ + case PY_CODE_EVENT_##op: \ + return "PY_CODE_EVENT_" #op; + PY_FOREACH_CODE_EVENT(CASE) + #undef CASE + } + Py_UNREACHABLE(); +} + +static void +notify_code_watchers(PyCodeEvent event, PyCodeObject *co) +{ + assert(Py_REFCNT(co) > 0); + PyInterpreterState *interp = _PyInterpreterState_GET(); + assert(interp->_initialized); + uint8_t bits = interp->active_code_watchers; + int i = 0; + while (bits) { + assert(i < CODE_MAX_WATCHERS); + if (bits & 1) { + PyCode_WatchCallback cb = interp->code_watchers[i]; + // callback must be non-null if the watcher bit is set + assert(cb != NULL); + if (cb(event, co) < 0) { + // Don't risk resurrecting the object if an unraisablehook keeps + // a reference; pass a string as context. + PyObject *context = NULL; + PyObject *repr = code_repr(co); + if (repr) { + context = PyUnicode_FromFormat( + "%s watcher callback for %U", + code_event_name(event), repr); + Py_DECREF(repr); + } + if (context == NULL) { + context = Py_NewRef(Py_None); + } + PyErr_WriteUnraisable(context); + Py_DECREF(context); + } + } + i++; + bits >>= 1; + } +} + +int +PyCode_AddWatcher(PyCode_WatchCallback callback) +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + assert(interp->_initialized); + + for (int i = 0; i < CODE_MAX_WATCHERS; i++) { + if (!interp->code_watchers[i]) { + interp->code_watchers[i] = callback; + interp->active_code_watchers |= (1 << i); + return i; + } + } + + PyErr_SetString(PyExc_RuntimeError, "no more code watcher IDs available"); + return -1; +} + +static inline int +validate_watcher_id(PyInterpreterState *interp, int watcher_id) +{ + if (watcher_id < 0 || watcher_id >= CODE_MAX_WATCHERS) { + PyErr_Format(PyExc_ValueError, "Invalid code watcher ID %d", watcher_id); + return -1; + } + if (!interp->code_watchers[watcher_id]) { + PyErr_Format(PyExc_ValueError, "No code watcher set for ID %d", watcher_id); + return -1; + } + return 0; +} + +int +PyCode_ClearWatcher(int watcher_id) +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + assert(interp->_initialized); + if (validate_watcher_id(interp, watcher_id) < 0) { + return -1; + } + interp->code_watchers[watcher_id] = NULL; + interp->active_code_watchers &= ~(1 << watcher_id); + return 0; +} /****************** * generic helpers @@ -149,7 +245,22 @@ validate_and_copy_tuple(PyObject *tup) return newtuple; } +static int +init_co_cached(PyCodeObject *self) { + if (self->_co_cached == NULL) { + self->_co_cached = PyMem_New(_PyCoCached, 1); + if (self->_co_cached == NULL) { + PyErr_NoMemory(); + return -1; + } + self->_co_cached->_co_code = NULL; + self->_co_cached->_co_cellvars = NULL; + self->_co_cached->_co_freevars = NULL; + self->_co_cached->_co_varnames = NULL; + } + return 0; +} /****************** * _PyCode_New() ******************/ @@ -159,18 +270,16 @@ void _Py_set_localsplus_info(int offset, PyObject *name, _PyLocals_Kind kind, PyObject *names, PyObject *kinds) { - Py_INCREF(name); - PyTuple_SET_ITEM(names, offset, name); + PyTuple_SET_ITEM(names, offset, Py_NewRef(name)); _PyLocals_SetKind(kinds, offset, kind); } static void get_localsplus_counts(PyObject *names, PyObject *kinds, - int *pnlocals, int *pnplaincellvars, int *pncellvars, + int *pnlocals, int *pncellvars, int *pnfreevars) { int nlocals = 0; - int nplaincellvars = 0; int ncellvars = 0; int nfreevars = 0; Py_ssize_t nlocalsplus = PyTuple_GET_SIZE(names); @@ -184,7 +293,6 @@ get_localsplus_counts(PyObject *names, PyObject *kinds, } else if (kind & CO_FAST_CELL) { ncellvars += 1; - nplaincellvars += 1; } else if (kind & CO_FAST_FREE) { nfreevars += 1; @@ -193,9 +301,6 @@ get_localsplus_counts(PyObject *names, PyObject *kinds, if (pnlocals != NULL) { *pnlocals = nlocals; } - if (pnplaincellvars != NULL) { - *pnplaincellvars = nplaincellvars; - } if (pncellvars != NULL) { *pncellvars = ncellvars; } @@ -219,8 +324,7 @@ get_localsplus_names(PyCodeObject *co, _PyLocals_Kind kind, int num) } assert(index < num); PyObject *name = PyTuple_GET_ITEM(co->co_localsplusnames, offset); - Py_INCREF(name); - PyTuple_SET_ITEM(names, index, name); + PyTuple_SET_ITEM(names, index, Py_NewRef(name)); index += 1; } assert(index == num); @@ -271,7 +375,7 @@ _PyCode_Validate(struct _PyCodeConstructor *con) * here to avoid the possibility of overflow (however remote). */ int nlocals; get_localsplus_counts(con->localsplusnames, con->localspluskinds, - &nlocals, NULL, NULL, NULL); + &nlocals, NULL, NULL); int nplainlocals = nlocals - con->argcount - con->kwonlyargcount - @@ -285,35 +389,29 @@ _PyCode_Validate(struct _PyCodeConstructor *con) return 0; } +extern void _PyCode_Quicken(PyCodeObject *code); + static void init_code(PyCodeObject *co, struct _PyCodeConstructor *con) { int nlocalsplus = (int)PyTuple_GET_SIZE(con->localsplusnames); - int nlocals, nplaincellvars, ncellvars, nfreevars; + int nlocals, ncellvars, nfreevars; get_localsplus_counts(con->localsplusnames, con->localspluskinds, - &nlocals, &nplaincellvars, &ncellvars, &nfreevars); - - Py_INCREF(con->filename); - co->co_filename = con->filename; - Py_INCREF(con->name); - co->co_name = con->name; - Py_INCREF(con->qualname); - co->co_qualname = con->qualname; + &nlocals, &ncellvars, &nfreevars); + + co->co_filename = Py_NewRef(con->filename); + co->co_name = Py_NewRef(con->name); + co->co_qualname = Py_NewRef(con->qualname); co->co_flags = con->flags; co->co_firstlineno = con->firstlineno; - Py_INCREF(con->linetable); - co->co_linetable = con->linetable; + co->co_linetable = Py_NewRef(con->linetable); - Py_INCREF(con->consts); - co->co_consts = con->consts; - Py_INCREF(con->names); - co->co_names = con->names; + co->co_consts = Py_NewRef(con->consts); + co->co_names = Py_NewRef(con->names); - Py_INCREF(con->localsplusnames); - co->co_localsplusnames = con->localsplusnames; - Py_INCREF(con->localspluskinds); - co->co_localspluskinds = con->localspluskinds; + co->co_localsplusnames = Py_NewRef(con->localsplusnames); + co->co_localspluskinds = Py_NewRef(con->localspluskinds); co->co_argcount = con->argcount; co->co_posonlyargcount = con->posonlyargcount; @@ -321,32 +419,35 @@ init_code(PyCodeObject *co, struct _PyCodeConstructor *con) co->co_stacksize = con->stacksize; - Py_INCREF(con->exceptiontable); - co->co_exceptiontable = con->exceptiontable; + co->co_exceptiontable = Py_NewRef(con->exceptiontable); /* derived values */ co->co_nlocalsplus = nlocalsplus; co->co_nlocals = nlocals; - co->co_nplaincellvars = nplaincellvars; + co->co_framesize = nlocalsplus + con->stacksize + FRAME_SPECIALS_SIZE; co->co_ncellvars = ncellvars; co->co_nfreevars = nfreevars; - + co->co_version = _Py_next_func_version; + if (_Py_next_func_version != 0) { + _Py_next_func_version++; + } + co->_co_monitoring = NULL; + co->_co_instrumentation_version = 0; /* not set */ co->co_weakreflist = NULL; co->co_extra = NULL; - co->_co_code = NULL; + co->_co_cached = NULL; - co->co_warmup = QUICKENING_INITIAL_WARMUP_VALUE; - co->_co_linearray_entry_size = 0; - co->_co_linearray = NULL; memcpy(_PyCode_CODE(co), PyBytes_AS_STRING(con->code), PyBytes_GET_SIZE(con->code)); int entry_point = 0; while (entry_point < Py_SIZE(co) && - _Py_OPCODE(_PyCode_CODE(co)[entry_point]) != RESUME) { + _PyCode_CODE(co)[entry_point].op.code != RESUME) { entry_point++; } co->_co_firsttraceable = entry_point; + _PyCode_Quicken(co); + notify_code_watchers(PY_CODE_EVENT_CREATE, co); } static int @@ -495,7 +596,8 @@ _PyCode_New(struct _PyCodeConstructor *con) ******************/ PyCodeObject * -PyCode_NewWithPosOnlyArgs(int argcount, int posonlyargcount, int kwonlyargcount, +PyUnstable_Code_NewWithPosOnlyArgs( + int argcount, int posonlyargcount, int kwonlyargcount, int nlocals, int stacksize, int flags, PyObject *code, PyObject *consts, PyObject *names, PyObject *varnames, PyObject *freevars, PyObject *cellvars, @@ -619,7 +721,7 @@ error: } PyCodeObject * -PyCode_New(int argcount, int kwonlyargcount, +PyUnstable_Code_New(int argcount, int kwonlyargcount, int nlocals, int stacksize, int flags, PyObject *code, PyObject *consts, PyObject *names, PyObject *varnames, PyObject *freevars, PyObject *cellvars, @@ -714,54 +816,6 @@ failed: * source location tracking (co_lines/co_positions) ******************/ -/* Use co_linetable to compute the line number from a bytecode index, addrq. See - lnotab_notes.txt for the details of the lnotab representation. -*/ - -int -_PyCode_CreateLineArray(PyCodeObject *co) -{ - assert(co->_co_linearray == NULL); - PyCodeAddressRange bounds; - int size; - int max_line = 0; - _PyCode_InitAddressRange(co, &bounds); - while(_PyLineTable_NextAddressRange(&bounds)) { - if (bounds.ar_line > max_line) { - max_line = bounds.ar_line; - } - } - if (max_line < (1 << 15)) { - size = 2; - } - else { - size = 4; - } - co->_co_linearray = PyMem_Malloc(Py_SIZE(co)*size); - if (co->_co_linearray == NULL) { - PyErr_NoMemory(); - return -1; - } - co->_co_linearray_entry_size = size; - _PyCode_InitAddressRange(co, &bounds); - while(_PyLineTable_NextAddressRange(&bounds)) { - int start = bounds.ar_start / sizeof(_Py_CODEUNIT); - int end = bounds.ar_end / sizeof(_Py_CODEUNIT); - for (int index = start; index < end; index++) { - assert(index < (int)Py_SIZE(co)); - if (size == 2) { - assert(((int16_t)bounds.ar_line) == bounds.ar_line); - ((int16_t *)co->_co_linearray)[index] = bounds.ar_line; - } - else { - assert(size == 4); - ((int32_t *)co->_co_linearray)[index] = bounds.ar_line; - } - } - } - return 0; -} - int PyCode_Addr2Line(PyCodeObject *co, int addrq) { @@ -769,9 +823,6 @@ PyCode_Addr2Line(PyCodeObject *co, int addrq) return co->co_firstlineno; } assert(addrq >= 0 && addrq < _PyCode_NBYTES(co)); - if (co->_co_linearray) { - return _PyCode_LineNumberFromArray(co, addrq / sizeof(_Py_CODEUNIT)); - } PyCodeAddressRange bounds; _PyCode_InitAddressRange(co, &bounds); return _PyCode_CheckLineNumber(addrq, &bounds); @@ -1025,33 +1076,6 @@ _PyLineTable_NextAddressRange(PyCodeAddressRange *range) return 1; } -int -_PyLineTable_StartsLine(PyCodeAddressRange *range) -{ - if (range->ar_start <= 0) { - return 0; - } - const uint8_t *ptr = range->opaque.lo_next; - do { - ptr--; - } while (((*ptr) & 128) == 0); - int code = ((*ptr)>> 3) & 15; - switch(code) { - case PY_CODE_LOCATION_INFO_LONG: - return 0; - case PY_CODE_LOCATION_INFO_NO_COLUMNS: - case PY_CODE_LOCATION_INFO_NONE: - return ptr[1] != 0; - case PY_CODE_LOCATION_INFO_ONE_LINE0: - return 0; - case PY_CODE_LOCATION_INFO_ONE_LINE1: - case PY_CODE_LOCATION_INFO_ONE_LINE2: - return 1; - default: - return 0; - } -} - static int emit_pair(PyObject **bytes, int *offset, int a, int b) { @@ -1138,6 +1162,14 @@ lineiter_dealloc(lineiterator *li) Py_TYPE(li)->tp_free(li); } +static PyObject * +_source_offset_converter(int *value) { + if (*value == -1) { + Py_RETURN_NONE; + } + return PyLong_FromLong(*value); +} + static PyObject * lineiter_next(lineiterator *li) { @@ -1145,35 +1177,20 @@ lineiter_next(lineiterator *li) if (!_PyLineTable_NextAddressRange(bounds)) { return NULL; } - PyObject *start = NULL; - PyObject *end = NULL; - PyObject *line = NULL; - PyObject *result = PyTuple_New(3); - start = PyLong_FromLong(bounds->ar_start); - end = PyLong_FromLong(bounds->ar_end); - if (bounds->ar_line < 0) { - Py_INCREF(Py_None); - line = Py_None; - } - else { - line = PyLong_FromLong(bounds->ar_line); - } - if (result == NULL || start == NULL || end == NULL || line == NULL) { - goto error; + int start = bounds->ar_start; + int line = bounds->ar_line; + // Merge overlapping entries: + while (_PyLineTable_NextAddressRange(bounds)) { + if (bounds->ar_line != line) { + _PyLineTable_PreviousAddressRange(bounds); + break; + } } - PyTuple_SET_ITEM(result, 0, start); - PyTuple_SET_ITEM(result, 1, end); - PyTuple_SET_ITEM(result, 2, line); - return result; -error: - Py_XDECREF(start); - Py_XDECREF(end); - Py_XDECREF(line); - Py_XDECREF(result); - return result; + return Py_BuildValue("iiO&", start, bounds->ar_end, + _source_offset_converter, &line); } -static PyTypeObject LineIterator = { +PyTypeObject _PyLineIterator = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "line_iterator", /* tp_name */ sizeof(lineiterator), /* tp_basicsize */ @@ -1219,12 +1236,11 @@ static PyTypeObject LineIterator = { static lineiterator * new_linesiterator(PyCodeObject *code) { - lineiterator *li = (lineiterator *)PyType_GenericAlloc(&LineIterator, 0); + lineiterator *li = (lineiterator *)PyType_GenericAlloc(&_PyLineIterator, 0); if (li == NULL) { return NULL; } - Py_INCREF(code); - li->li_code = code; + li->li_code = (PyCodeObject*)Py_NewRef(code); _PyCode_InitAddressRange(code, &li->li_line); return li; } @@ -1247,14 +1263,6 @@ positionsiter_dealloc(positionsiterator* pi) Py_TYPE(pi)->tp_free(pi); } -static PyObject* -_source_offset_converter(int* value) { - if (*value == -1) { - Py_RETURN_NONE; - } - return PyLong_FromLong(*value); -} - static PyObject* positionsiter_next(positionsiterator* pi) { @@ -1273,7 +1281,7 @@ positionsiter_next(positionsiterator* pi) _source_offset_converter, &pi->pi_endcolumn); } -static PyTypeObject PositionsIterator = { +PyTypeObject _PyPositionsIterator = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "positions_iterator", /* tp_name */ sizeof(positionsiterator), /* tp_basicsize */ @@ -1319,12 +1327,11 @@ static PyTypeObject PositionsIterator = { static PyObject* code_positionsiterator(PyCodeObject* code, PyObject* Py_UNUSED(args)) { - positionsiterator* pi = (positionsiterator*)PyType_GenericAlloc(&PositionsIterator, 0); + positionsiterator* pi = (positionsiterator*)PyType_GenericAlloc(&_PyPositionsIterator, 0); if (pi == NULL) { return NULL; } - Py_INCREF(code); - pi->pi_code = code; + pi->pi_code = (PyCodeObject*)Py_NewRef(code); _PyCode_InitAddressRange(code, &pi->pi_range); pi->pi_offset = pi->pi_range.ar_end; return (PyObject*)pi; @@ -1343,7 +1350,7 @@ typedef struct { int -_PyCode_GetExtra(PyObject *code, Py_ssize_t index, void **extra) +PyUnstable_Code_GetExtra(PyObject *code, Py_ssize_t index, void **extra) { if (!PyCode_Check(code)) { PyErr_BadInternalCall(); @@ -1364,7 +1371,7 @@ _PyCode_GetExtra(PyObject *code, Py_ssize_t index, void **extra) int -_PyCode_SetExtra(PyObject *code, Py_ssize_t index, void *extra) +PyUnstable_Code_SetExtra(PyObject *code, Py_ssize_t index, void *extra) { PyInterpreterState *interp = _PyInterpreterState_GET(); @@ -1409,10 +1416,31 @@ _PyCode_SetExtra(PyObject *code, Py_ssize_t index, void *extra) * other PyCodeObject accessor functions ******************/ +static PyObject * +get_cached_locals(PyCodeObject *co, PyObject **cached_field, + _PyLocals_Kind kind, int num) +{ + assert(cached_field != NULL); + assert(co->_co_cached != NULL); + if (*cached_field != NULL) { + return Py_NewRef(*cached_field); + } + assert(*cached_field == NULL); + PyObject *varnames = get_localsplus_names(co, kind, num); + if (varnames == NULL) { + return NULL; + } + *cached_field = Py_NewRef(varnames); + return varnames; +} + PyObject * _PyCode_GetVarnames(PyCodeObject *co) { - return get_localsplus_names(co, CO_FAST_LOCAL, co->co_nlocals); + if (init_co_cached(co)) { + return NULL; + } + return get_cached_locals(co, &co->_co_cached->_co_varnames, CO_FAST_LOCAL, co->co_nlocals); } PyObject * @@ -1424,7 +1452,10 @@ PyCode_GetVarnames(PyCodeObject *code) PyObject * _PyCode_GetCellvars(PyCodeObject *co) { - return get_localsplus_names(co, CO_FAST_CELL, co->co_ncellvars); + if (init_co_cached(co)) { + return NULL; + } + return get_cached_locals(co, &co->_co_cached->_co_cellvars, CO_FAST_CELL, co->co_ncellvars); } PyObject * @@ -1436,7 +1467,10 @@ PyCode_GetCellvars(PyCodeObject *code) PyObject * _PyCode_GetFreevars(PyCodeObject *co) { - return get_localsplus_names(co, CO_FAST_FREE, co->co_nfreevars); + if (init_co_cached(co)) { + return NULL; + } + return get_cached_locals(co, &co->_co_cached->_co_freevars, CO_FAST_FREE, co->co_nfreevars); } PyObject * @@ -1446,33 +1480,37 @@ PyCode_GetFreevars(PyCodeObject *code) } static void -deopt_code(_Py_CODEUNIT *instructions, Py_ssize_t len) +deopt_code(PyCodeObject *code, _Py_CODEUNIT *instructions) { + Py_ssize_t len = Py_SIZE(code); for (int i = 0; i < len; i++) { - _Py_CODEUNIT instruction = instructions[i]; - int opcode = _PyOpcode_Deopt[_Py_OPCODE(instruction)]; + int opcode = _Py_GetBaseOpcode(code, i); int caches = _PyOpcode_Caches[opcode]; - instructions[i] = _Py_MAKECODEUNIT(opcode, _Py_OPARG(instruction)); - while (caches--) { - instructions[++i] = _Py_MAKECODEUNIT(CACHE, 0); + instructions[i].op.code = opcode; + for (int j = 1; j <= caches; j++) { + instructions[i+j].cache = 0; } + i += caches; } } PyObject * _PyCode_GetCode(PyCodeObject *co) { - if (co->_co_code != NULL) { - return Py_NewRef(co->_co_code); + if (init_co_cached(co)) { + return NULL; + } + if (co->_co_cached->_co_code != NULL) { + return Py_NewRef(co->_co_cached->_co_code); } PyObject *code = PyBytes_FromStringAndSize((const char *)_PyCode_CODE(co), _PyCode_NBYTES(co)); if (code == NULL) { return NULL; } - deopt_code((_Py_CODEUNIT *)PyBytes_AS_STRING(code), Py_SIZE(co)); - assert(co->_co_code == NULL); - co->_co_code = Py_NewRef(code); + deopt_code(co, (_Py_CODEUNIT *)PyBytes_AS_STRING(code)); + assert(co->_co_cached->_co_code == NULL); + co->_co_cached->_co_code = Py_NewRef(code); return code; } @@ -1604,9 +1642,42 @@ code_new_impl(PyTypeObject *type, int argcount, int posonlyargcount, return co; } +static void +free_monitoring_data(_PyCoMonitoringData *data) +{ + if (data == NULL) { + return; + } + if (data->tools) { + PyMem_Free(data->tools); + } + if (data->lines) { + PyMem_Free(data->lines); + } + if (data->line_tools) { + PyMem_Free(data->line_tools); + } + if (data->per_instruction_opcodes) { + PyMem_Free(data->per_instruction_opcodes); + } + if (data->per_instruction_tools) { + PyMem_Free(data->per_instruction_tools); + } + PyMem_Free(data); +} + static void code_dealloc(PyCodeObject *co) { + assert(Py_REFCNT(co) == 0); + Py_SET_REFCNT(co, 1); + notify_code_watchers(PY_CODE_EVENT_DESTROY, co); + if (Py_REFCNT(co) > 1) { + Py_SET_REFCNT(co, Py_REFCNT(co) - 1); + return; + } + Py_SET_REFCNT(co, 0); + if (co->co_extra != NULL) { PyInterpreterState *interp = _PyInterpreterState_GET(); _PyCodeObjectExtra *co_extra = co->co_extra; @@ -1631,16 +1702,17 @@ code_dealloc(PyCodeObject *co) Py_XDECREF(co->co_qualname); Py_XDECREF(co->co_linetable); Py_XDECREF(co->co_exceptiontable); - Py_XDECREF(co->_co_code); + if (co->_co_cached != NULL) { + Py_XDECREF(co->_co_cached->_co_code); + Py_XDECREF(co->_co_cached->_co_cellvars); + Py_XDECREF(co->_co_cached->_co_freevars); + Py_XDECREF(co->_co_cached->_co_varnames); + PyMem_Free(co->_co_cached); + } if (co->co_weakreflist != NULL) { PyObject_ClearWeakRefs((PyObject*)co); } - if (co->_co_linearray) { - PyMem_Free(co->_co_linearray); - } - if (co->co_warmup == 0) { - _Py_QuickenedCount--; - } + free_monitoring_data(co->_co_monitoring); PyObject_Free(co); } @@ -1699,13 +1771,13 @@ code_richcompare(PyObject *self, PyObject *other, int op) for (int i = 0; i < Py_SIZE(co); i++) { _Py_CODEUNIT co_instr = _PyCode_CODE(co)[i]; _Py_CODEUNIT cp_instr = _PyCode_CODE(cp)[i]; - _Py_SET_OPCODE(co_instr, _PyOpcode_Deopt[_Py_OPCODE(co_instr)]); - _Py_SET_OPCODE(cp_instr, _PyOpcode_Deopt[_Py_OPCODE(cp_instr)]); - eq = co_instr == cp_instr; + co_instr.op.code = _PyOpcode_Deopt[co_instr.op.code]; + cp_instr.op.code = _PyOpcode_Deopt[cp_instr.op.code]; + eq = co_instr.cache == cp_instr.cache; if (!eq) { goto unequal; } - i += _PyOpcode_Caches[_Py_OPCODE(co_instr)]; + i += _PyOpcode_Caches[co_instr.op.code]; } /* compare constants */ @@ -1752,35 +1824,47 @@ code_richcompare(PyObject *self, PyObject *other, int op) res = Py_False; done: - Py_INCREF(res); - return res; + return Py_NewRef(res); } static Py_hash_t code_hash(PyCodeObject *co) { - Py_hash_t h, h0, h1, h2, h3; - h0 = PyObject_Hash(co->co_name); - if (h0 == -1) return -1; - h1 = PyObject_Hash(co->co_consts); - if (h1 == -1) return -1; - h2 = PyObject_Hash(co->co_names); - if (h2 == -1) return -1; - h3 = PyObject_Hash(co->co_localsplusnames); - if (h3 == -1) return -1; - Py_hash_t h4 = PyObject_Hash(co->co_linetable); - if (h4 == -1) { - return -1; + Py_uhash_t uhash = 20221211; + #define SCRAMBLE_IN(H) do { \ + uhash ^= (Py_uhash_t)(H); \ + uhash *= _PyHASH_MULTIPLIER; \ + } while (0) + #define SCRAMBLE_IN_HASH(EXPR) do { \ + Py_hash_t h = PyObject_Hash(EXPR); \ + if (h == -1) { \ + return -1; \ + } \ + SCRAMBLE_IN(h); \ + } while (0) + + SCRAMBLE_IN_HASH(co->co_name); + SCRAMBLE_IN_HASH(co->co_consts); + SCRAMBLE_IN_HASH(co->co_names); + SCRAMBLE_IN_HASH(co->co_localsplusnames); + SCRAMBLE_IN_HASH(co->co_linetable); + SCRAMBLE_IN_HASH(co->co_exceptiontable); + SCRAMBLE_IN(co->co_argcount); + SCRAMBLE_IN(co->co_posonlyargcount); + SCRAMBLE_IN(co->co_kwonlyargcount); + SCRAMBLE_IN(co->co_flags); + SCRAMBLE_IN(co->co_firstlineno); + SCRAMBLE_IN(Py_SIZE(co)); + for (int i = 0; i < Py_SIZE(co); i++) { + int deop = _Py_GetBaseOpcode(co, i); + SCRAMBLE_IN(deop); + SCRAMBLE_IN(_PyCode_CODE(co)[i].op.arg); + i += _PyOpcode_Caches[deop]; } - Py_hash_t h5 = PyObject_Hash(co->co_exceptiontable); - if (h5 == -1) { - return -1; + if ((Py_hash_t)uhash == -1) { + return -2; } - h = h0 ^ h1 ^ h2 ^ h3 ^ h4 ^ h5 ^ - co->co_argcount ^ co->co_posonlyargcount ^ co->co_kwonlyargcount ^ - co->co_flags; - if (h == -1) h = -2; - return h; + return (Py_hash_t)uhash; } @@ -1808,6 +1892,11 @@ static PyMemberDef code_memberlist[] = { static PyObject * code_getlnotab(PyCodeObject *code, void *closure) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "co_lnotab is deprecated, use co_lines instead.", + 1) < 0) { + return NULL; + } return decode_linetable(code); } @@ -1857,15 +1946,13 @@ static PyGetSetDef code_getsetlist[] = { static PyObject * code_sizeof(PyCodeObject *co, PyObject *Py_UNUSED(args)) { - Py_ssize_t res = _PyObject_VAR_SIZE(Py_TYPE(co), Py_SIZE(co)); - + size_t res = _PyObject_VAR_SIZE(Py_TYPE(co), Py_SIZE(co)); _PyCodeObjectExtra *co_extra = (_PyCodeObjectExtra*) co->co_extra; if (co_extra != NULL) { - res += sizeof(_PyCodeObjectExtra) + - (co_extra->ce_size-1) * sizeof(co_extra->ce_extras[0]); + res += sizeof(_PyCodeObjectExtra); + res += ((size_t)co_extra->ce_size - 1) * sizeof(co_extra->ce_extras[0]); } - - return PyLong_FromSsize_t(res); + return PyLong_FromSize_t(res); } static PyObject * @@ -1875,27 +1962,28 @@ code_linesiterator(PyCodeObject *code, PyObject *Py_UNUSED(args)) } /*[clinic input] +@text_signature "($self, /, **changes)" code.replace * - co_argcount: int(c_default="self->co_argcount") = -1 - co_posonlyargcount: int(c_default="self->co_posonlyargcount") = -1 - co_kwonlyargcount: int(c_default="self->co_kwonlyargcount") = -1 - co_nlocals: int(c_default="self->co_nlocals") = -1 - co_stacksize: int(c_default="self->co_stacksize") = -1 - co_flags: int(c_default="self->co_flags") = -1 - co_firstlineno: int(c_default="self->co_firstlineno") = -1 - co_code: PyBytesObject(c_default="NULL") = None - co_consts: object(subclass_of="&PyTuple_Type", c_default="self->co_consts") = None - co_names: object(subclass_of="&PyTuple_Type", c_default="self->co_names") = None - co_varnames: object(subclass_of="&PyTuple_Type", c_default="NULL") = None - co_freevars: object(subclass_of="&PyTuple_Type", c_default="NULL") = None - co_cellvars: object(subclass_of="&PyTuple_Type", c_default="NULL") = None - co_filename: unicode(c_default="self->co_filename") = None - co_name: unicode(c_default="self->co_name") = None - co_qualname: unicode(c_default="self->co_qualname") = None - co_linetable: PyBytesObject(c_default="(PyBytesObject *)self->co_linetable") = None - co_exceptiontable: PyBytesObject(c_default="(PyBytesObject *)self->co_exceptiontable") = None + co_argcount: int(c_default="self->co_argcount") = unchanged + co_posonlyargcount: int(c_default="self->co_posonlyargcount") = unchanged + co_kwonlyargcount: int(c_default="self->co_kwonlyargcount") = unchanged + co_nlocals: int(c_default="self->co_nlocals") = unchanged + co_stacksize: int(c_default="self->co_stacksize") = unchanged + co_flags: int(c_default="self->co_flags") = unchanged + co_firstlineno: int(c_default="self->co_firstlineno") = unchanged + co_code: object(subclass_of="&PyBytes_Type", c_default="NULL") = unchanged + co_consts: object(subclass_of="&PyTuple_Type", c_default="self->co_consts") = unchanged + co_names: object(subclass_of="&PyTuple_Type", c_default="self->co_names") = unchanged + co_varnames: object(subclass_of="&PyTuple_Type", c_default="NULL") = unchanged + co_freevars: object(subclass_of="&PyTuple_Type", c_default="NULL") = unchanged + co_cellvars: object(subclass_of="&PyTuple_Type", c_default="NULL") = unchanged + co_filename: unicode(c_default="self->co_filename") = unchanged + co_name: unicode(c_default="self->co_name") = unchanged + co_qualname: unicode(c_default="self->co_qualname") = unchanged + co_linetable: object(subclass_of="&PyBytes_Type", c_default="self->co_linetable") = unchanged + co_exceptiontable: object(subclass_of="&PyBytes_Type", c_default="self->co_exceptiontable") = unchanged Return a copy of the code object with new values for the specified fields. [clinic start generated code]*/ @@ -1904,14 +1992,13 @@ static PyObject * code_replace_impl(PyCodeObject *self, int co_argcount, int co_posonlyargcount, int co_kwonlyargcount, int co_nlocals, int co_stacksize, int co_flags, - int co_firstlineno, PyBytesObject *co_code, - PyObject *co_consts, PyObject *co_names, - PyObject *co_varnames, PyObject *co_freevars, - PyObject *co_cellvars, PyObject *co_filename, - PyObject *co_name, PyObject *co_qualname, - PyBytesObject *co_linetable, - PyBytesObject *co_exceptiontable) -/*[clinic end generated code: output=b6cd9988391d5711 input=f6f68e03571f8d7c]*/ + int co_firstlineno, PyObject *co_code, PyObject *co_consts, + PyObject *co_names, PyObject *co_varnames, + PyObject *co_freevars, PyObject *co_cellvars, + PyObject *co_filename, PyObject *co_name, + PyObject *co_qualname, PyObject *co_linetable, + PyObject *co_exceptiontable) +/*[clinic end generated code: output=e75c48a15def18b9 input=18e280e07846c122]*/ { #define CHECK_INT_ARG(ARG) \ if (ARG < 0) { \ @@ -1936,13 +2023,14 @@ code_replace_impl(PyCodeObject *self, int co_argcount, if (code == NULL) { return NULL; } - co_code = (PyBytesObject *)code; + co_code = code; } if (PySys_Audit("code.__new__", "OOOiiiiii", co_code, co_filename, co_name, co_argcount, co_posonlyargcount, co_kwonlyargcount, co_nlocals, co_stacksize, co_flags) < 0) { + Py_XDECREF(code); return NULL; } @@ -1974,10 +2062,10 @@ code_replace_impl(PyCodeObject *self, int co_argcount, co = PyCode_NewWithPosOnlyArgs( co_argcount, co_posonlyargcount, co_kwonlyargcount, co_nlocals, - co_stacksize, co_flags, (PyObject*)co_code, co_consts, co_names, + co_stacksize, co_flags, co_code, co_consts, co_names, co_varnames, co_freevars, co_cellvars, co_filename, co_name, co_qualname, co_firstlineno, - (PyObject*)co_linetable, (PyObject*)co_exceptiontable); + co_linetable, co_exceptiontable); error: Py_XDECREF(code); @@ -2005,8 +2093,7 @@ code__varname_from_oparg_impl(PyCodeObject *self, int oparg) if (name == NULL) { return NULL; } - Py_INCREF(name); - return name; + return Py_NewRef(name); } /* XXX code objects need to participate in GC? */ @@ -2081,8 +2168,7 @@ _PyCode_ConstantKey(PyObject *op) { /* Objects of these types are always different from object of other * type and from tuples. */ - Py_INCREF(op); - key = op; + key = Py_NewRef(op); } else if (PyBool_Check(op) || PyBytes_CheckExact(op)) { /* Make booleans different from integers 0 and 1. @@ -2198,28 +2284,29 @@ _PyCode_ConstantKey(PyObject *op) } void -_PyStaticCode_Dealloc(PyCodeObject *co) +_PyStaticCode_Fini(PyCodeObject *co) { - if (co->co_warmup == 0) { - _Py_QuickenedCount--; - } - deopt_code(_PyCode_CODE(co), Py_SIZE(co)); - co->co_warmup = QUICKENING_INITIAL_WARMUP_VALUE; + deopt_code(co, _PyCode_CODE(co)); PyMem_Free(co->co_extra); - Py_CLEAR(co->_co_code); + if (co->_co_cached != NULL) { + Py_CLEAR(co->_co_cached->_co_code); + Py_CLEAR(co->_co_cached->_co_cellvars); + Py_CLEAR(co->_co_cached->_co_freevars); + Py_CLEAR(co->_co_cached->_co_varnames); + PyMem_Free(co->_co_cached); + co->_co_cached = NULL; + } co->co_extra = NULL; if (co->co_weakreflist != NULL) { PyObject_ClearWeakRefs((PyObject *)co); co->co_weakreflist = NULL; } - if (co->_co_linearray) { - PyMem_Free(co->_co_linearray); - co->_co_linearray = NULL; - } + free_monitoring_data(co->_co_monitoring); + co->_co_monitoring = NULL; } int -_PyStaticCode_InternStrings(PyCodeObject *co) +_PyStaticCode_Init(PyCodeObject *co) { int res = intern_strings(co->co_names); if (res < 0) { @@ -2233,5 +2320,81 @@ _PyStaticCode_InternStrings(PyCodeObject *co) if (res < 0) { return -1; } + _PyCode_Quicken(co); return 0; } + +#define MAX_CODE_UNITS_PER_LOC_ENTRY 8 + +PyCodeObject * +_Py_MakeShimCode(const _PyShimCodeDef *codedef) +{ + PyObject *name = NULL; + PyObject *co_code = NULL; + PyObject *lines = NULL; + PyCodeObject *codeobj = NULL; + uint8_t *loc_table = NULL; + + name = _PyUnicode_FromASCII(codedef->cname, strlen(codedef->cname)); + if (name == NULL) { + goto cleanup; + } + co_code = PyBytes_FromStringAndSize( + (const char *)codedef->code, codedef->codelen); + if (co_code == NULL) { + goto cleanup; + } + int code_units = codedef->codelen / sizeof(_Py_CODEUNIT); + int loc_entries = (code_units + MAX_CODE_UNITS_PER_LOC_ENTRY - 1) / + MAX_CODE_UNITS_PER_LOC_ENTRY; + loc_table = PyMem_Malloc(loc_entries); + if (loc_table == NULL) { + PyErr_NoMemory(); + goto cleanup; + } + for (int i = 0; i < loc_entries-1; i++) { + loc_table[i] = 0x80 | (PY_CODE_LOCATION_INFO_NONE << 3) | 7; + code_units -= MAX_CODE_UNITS_PER_LOC_ENTRY; + } + assert(loc_entries > 0); + assert(code_units > 0 && code_units <= MAX_CODE_UNITS_PER_LOC_ENTRY); + loc_table[loc_entries-1] = 0x80 | + (PY_CODE_LOCATION_INFO_NONE << 3) | (code_units-1); + lines = PyBytes_FromStringAndSize((const char *)loc_table, loc_entries); + PyMem_Free(loc_table); + if (lines == NULL) { + goto cleanup; + } + _Py_DECLARE_STR(shim_name, "<shim>"); + struct _PyCodeConstructor con = { + .filename = &_Py_STR(shim_name), + .name = name, + .qualname = name, + .flags = CO_NEWLOCALS | CO_OPTIMIZED, + + .code = co_code, + .firstlineno = 1, + .linetable = lines, + + .consts = (PyObject *)&_Py_SINGLETON(tuple_empty), + .names = (PyObject *)&_Py_SINGLETON(tuple_empty), + + .localsplusnames = (PyObject *)&_Py_SINGLETON(tuple_empty), + .localspluskinds = (PyObject *)&_Py_SINGLETON(bytes_empty), + + .argcount = 0, + .posonlyargcount = 0, + .kwonlyargcount = 0, + + .stacksize = codedef->stacksize, + + .exceptiontable = (PyObject *)&_Py_SINGLETON(bytes_empty), + }; + + codeobj = _PyCode_New(&con); +cleanup: + Py_XDECREF(name); + Py_XDECREF(co_code); + Py_XDECREF(lines); + return codeobj; +} diff --git a/Objects/complexobject.c b/Objects/complexobject.c index 9bd68d50..aee03ddf 100644 --- a/Objects/complexobject.c +++ b/Objects/complexobject.c @@ -449,8 +449,7 @@ to_complex(PyObject **pobj, Py_complex *pc) pc->real = PyFloat_AsDouble(obj); return 0; } - Py_INCREF(Py_NotImplemented); - *pobj = Py_NotImplemented; + *pobj = Py_NewRef(Py_NotImplemented); return -1; } @@ -553,8 +552,7 @@ static PyObject * complex_pos(PyComplexObject *v) { if (PyComplex_CheckExact(v)) { - Py_INCREF(v); - return (PyObject *)v; + return Py_NewRef(v); } else return PyComplex_FromCComplex(v->cval); @@ -631,8 +629,7 @@ complex_richcompare(PyObject *v, PyObject *w, int op) else res = Py_False; - Py_INCREF(res); - return res; + return Py_NewRef(res); Unimplemented: Py_RETURN_NOTIMPLEMENTED; @@ -705,8 +702,7 @@ complex___complex___impl(PyComplexObject *self) /*[clinic end generated code: output=e6b35ba3d275dc9c input=3589ada9d27db854]*/ { if (PyComplex_CheckExact(self)) { - Py_INCREF(self); - return (PyObject *)self; + return Py_NewRef(self); } else { return PyComplex_FromCComplex(self->cval); @@ -917,8 +913,7 @@ complex_new_impl(PyTypeObject *type, PyObject *r, PyObject *i) to exact complexes here. If either the input or the output is a complex subclass, it will be handled below as a non-orthogonal vector. */ - Py_INCREF(r); - return r; + return Py_NewRef(r); } if (PyUnicode_Check(r)) { if (i != NULL) { diff --git a/Objects/descrobject.c b/Objects/descrobject.c index 4d8b8375..72ac4703 100644 --- a/Objects/descrobject.c +++ b/Objects/descrobject.c @@ -6,6 +6,7 @@ #include "pycore_pystate.h" // _PyThreadState_GET() #include "pycore_tuple.h" // _PyTuple_ITEMS() #include "structmember.h" // PyMemberDef +#include "pycore_descrobject.h" /*[clinic input] class mappingproxy "mappingproxyobject *" "&PyDictProxy_Type" @@ -621,8 +622,7 @@ descr_get_qualname(PyDescrObject *descr, void *Py_UNUSED(ignored)) { if (descr->d_qualname == NULL) descr->d_qualname = calculate_qualname(descr); - Py_XINCREF(descr->d_qualname); - return descr->d_qualname; + return Py_XNewRef(descr->d_qualname); } static PyObject * @@ -903,12 +903,10 @@ descr_new(PyTypeObject *descrtype, PyTypeObject *type, const char *name) descr = (PyDescrObject *)PyType_GenericAlloc(descrtype, 0); if (descr != NULL) { - Py_XINCREF(type); - descr->d_type = type; + descr->d_type = (PyTypeObject*)Py_XNewRef(type); descr->d_name = PyUnicode_InternFromString(name); if (descr->d_name == NULL) { - Py_DECREF(descr); - descr = NULL; + Py_SETREF(descr, NULL); } else { descr->d_qualname = NULL; @@ -980,6 +978,12 @@ PyDescr_NewMember(PyTypeObject *type, PyMemberDef *member) { PyMemberDescrObject *descr; + if (member->flags & Py_RELATIVE_OFFSET) { + PyErr_SetString( + PyExc_SystemError, + "PyDescr_NewMember used with Py_RELATIVE_OFFSET"); + return NULL; + } descr = (PyMemberDescrObject *)descr_new(&PyMemberDescr_Type, type, member->name); if (descr != NULL) @@ -1177,6 +1181,12 @@ mappingproxy_getiter(mappingproxyobject *pp) return PyObject_GetIter(pp->mapping); } +static Py_hash_t +mappingproxy_hash(mappingproxyobject *pp) +{ + return PyObject_Hash(pp->mapping); +} + static PyObject * mappingproxy_str(mappingproxyobject *pp) { @@ -1237,8 +1247,7 @@ mappingproxy_new_impl(PyTypeObject *type, PyObject *mapping) mappingproxy = PyObject_GC_New(mappingproxyobject, &PyDictProxy_Type); if (mappingproxy == NULL) return NULL; - Py_INCREF(mapping); - mappingproxy->mapping = mapping; + mappingproxy->mapping = Py_NewRef(mapping); _PyObject_GC_TRACK(mappingproxy); return (PyObject *)mappingproxy; } @@ -1253,8 +1262,7 @@ PyDictProxy_New(PyObject *mapping) pp = PyObject_GC_New(mappingproxyobject, &PyDictProxy_Type); if (pp != NULL) { - Py_INCREF(mapping); - pp->mapping = mapping; + pp->mapping = Py_NewRef(mapping); _PyObject_GC_TRACK(pp); } return (PyObject *)pp; @@ -1354,8 +1362,7 @@ wrapper_objclass(wrapperobject *wp, void *Py_UNUSED(ignored)) { PyObject *c = (PyObject *)PyDescr_TYPE(wp->descr); - Py_INCREF(c); - return c; + return Py_NewRef(c); } static PyObject * @@ -1459,10 +1466,8 @@ PyWrapper_New(PyObject *d, PyObject *self) wp = PyObject_GC_New(wrapperobject, &_PyMethodWrapper_Type); if (wp != NULL) { - Py_INCREF(descr); - wp->descr = descr; - Py_INCREF(self); - wp->self = self; + wp->descr = (PyWrapperDescrObject*)Py_NewRef(descr); + wp->self = Py_NewRef(self); _PyObject_GC_TRACK(wp); } return (PyObject *)wp; @@ -1480,7 +1485,10 @@ class property(object): self.__get = fget self.__set = fset self.__del = fdel - self.__doc__ = doc + try: + self.__doc__ = doc + except AttributeError: # read-only or dict-less class + pass def __get__(self, inst, type=None): if inst is None: @@ -1501,16 +1509,6 @@ class property(object): */ -typedef struct { - PyObject_HEAD - PyObject *prop_get; - PyObject *prop_set; - PyObject *prop_del; - PyObject *prop_doc; - PyObject *prop_name; - int getter_doc; -} propertyobject; - static PyObject * property_copy(PyObject *, PyObject *, PyObject *, PyObject *); @@ -1569,8 +1567,7 @@ property_set_name(PyObject *self, PyObject *args) { propertyobject *prop = (propertyobject *)self; PyObject *name = PyTuple_GET_ITEM(args, 1); - Py_XINCREF(name); - Py_XSETREF(prop->prop_name, name); + Py_XSETREF(prop->prop_name, Py_XNewRef(name)); Py_RETURN_NONE; } @@ -1602,8 +1599,7 @@ static PyObject * property_descr_get(PyObject *self, PyObject *obj, PyObject *type) { if (obj == NULL || obj == Py_None) { - Py_INCREF(self); - return self; + return Py_NewRef(self); } propertyobject *gs = (propertyobject *)self; @@ -1677,6 +1673,7 @@ property_descr_set(PyObject *self, PyObject *obj, PyObject *value) res = PyObject_CallOneArg(func, obj); } else { + EVAL_CALL_STAT_INC_IF_FUNCTION(EVAL_CALL_API, func); PyObject *args[] = { obj, value }; res = PyObject_Vectorcall(func, args, 2, NULL); } @@ -1723,9 +1720,9 @@ property_copy(PyObject *old, PyObject *get, PyObject *set, PyObject *del) Py_DECREF(type); if (new == NULL) return NULL; + if (PyObject_TypeCheck((new), &PyProperty_Type)) { - Py_XINCREF(pold->prop_name); - Py_XSETREF(((propertyobject *) new)->prop_name, pold->prop_name); + Py_XSETREF(((propertyobject *) new)->prop_name, Py_XNewRef(pold->prop_name)); } return new; } @@ -1779,41 +1776,78 @@ property_init_impl(propertyobject *self, PyObject *fget, PyObject *fset, if (fdel == Py_None) fdel = NULL; - Py_XINCREF(fget); - Py_XINCREF(fset); - Py_XINCREF(fdel); - Py_XINCREF(doc); - - Py_XSETREF(self->prop_get, fget); - Py_XSETREF(self->prop_set, fset); - Py_XSETREF(self->prop_del, fdel); - Py_XSETREF(self->prop_doc, doc); + Py_XSETREF(self->prop_get, Py_XNewRef(fget)); + Py_XSETREF(self->prop_set, Py_XNewRef(fset)); + Py_XSETREF(self->prop_del, Py_XNewRef(fdel)); + Py_XSETREF(self->prop_doc, NULL); Py_XSETREF(self->prop_name, NULL); self->getter_doc = 0; + PyObject *prop_doc = NULL; + if (doc != NULL && doc != Py_None) { + prop_doc = Py_XNewRef(doc); + } /* if no docstring given and the getter has one, use that one */ - if ((doc == NULL || doc == Py_None) && fget != NULL) { - PyObject *get_doc; - int rc = _PyObject_LookupAttr(fget, &_Py_ID(__doc__), &get_doc); + else if (fget != NULL) { + int rc = _PyObject_LookupAttr(fget, &_Py_ID(__doc__), &prop_doc); if (rc <= 0) { return rc; } - if (Py_IS_TYPE(self, &PyProperty_Type)) { - Py_XSETREF(self->prop_doc, get_doc); - } - else { - /* If this is a property subclass, put __doc__ - in dict of the subclass instance instead, - otherwise it gets shadowed by __doc__ in the - class's dict. */ + if (!Py_IS_TYPE(self, &PyProperty_Type) && + prop_doc != NULL && prop_doc != Py_None) { + // This oddity preserves the long existing behavior of surfacing + // an AttributeError when using a dict-less (__slots__) property + // subclass as a decorator on a getter method with a docstring. + // See PropertySubclassTest.test_slots_docstring_copy_exception. int err = PyObject_SetAttr( - (PyObject *)self, &_Py_ID(__doc__), get_doc); - Py_DECREF(get_doc); - if (err < 0) + (PyObject *)self, &_Py_ID(__doc__), prop_doc); + if (err < 0) { + Py_DECREF(prop_doc); // release our new reference. + return -1; + } + } + if (prop_doc == Py_None) { + prop_doc = NULL; + Py_DECREF(Py_None); + } + if (prop_doc != NULL){ + self->getter_doc = 1; + } + } + + /* At this point `prop_doc` is either NULL or + a non-None object with incremented ref counter */ + + if (Py_IS_TYPE(self, &PyProperty_Type)) { + Py_XSETREF(self->prop_doc, prop_doc); + } else { + /* If this is a property subclass, put __doc__ in the dict + or designated slot of the subclass instance instead, otherwise + it gets shadowed by __doc__ in the class's dict. */ + + if (prop_doc == NULL) { + prop_doc = Py_NewRef(Py_None); + } + int err = PyObject_SetAttr( + (PyObject *)self, &_Py_ID(__doc__), prop_doc); + Py_DECREF(prop_doc); + if (err < 0) { + assert(PyErr_Occurred()); + if (PyErr_ExceptionMatches(PyExc_AttributeError)) { + PyErr_Clear(); + // https://github.com/python/cpython/issues/98963#issuecomment-1574413319 + // Python silently dropped this doc assignment through 3.11. + // We preserve that behavior for backwards compatibility. + // + // If we ever want to deprecate this behavior, only raise a + // warning or error when proc_doc is not None so that + // property without a specific doc= still works. + return 0; + } else { return -1; + } } - self->getter_doc = 1; } return 0; @@ -1893,7 +1927,7 @@ PyTypeObject PyDictProxy_Type = { &mappingproxy_as_number, /* tp_as_number */ &mappingproxy_as_sequence, /* tp_as_sequence */ &mappingproxy_as_mapping, /* tp_as_mapping */ - 0, /* tp_hash */ + (hashfunc)mappingproxy_hash, /* tp_hash */ 0, /* tp_call */ (reprfunc)mappingproxy_str, /* tp_str */ PyObject_GenericGetAttr, /* tp_getattro */ diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 4a214f8c..254cd9ad 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -119,7 +119,7 @@ As a consequence of this, split keys have a maximum size of 16. #include "pycore_dict.h" // PyDictKeysObject #include "pycore_gc.h" // _PyObject_GC_IS_TRACKED() #include "pycore_object.h" // _PyObject_GC_TRACK() -#include "pycore_pyerrors.h" // _PyErr_Fetch() +#include "pycore_pyerrors.h" // _PyErr_GetRaisedException() #include "pycore_pystate.h" // _PyThreadState_GET() #include "stringlib/eq.h" // unicode_eq() @@ -232,23 +232,18 @@ equally good collision statistics, needed less code & used less memory. */ -static int dictresize(PyDictObject *mp, uint8_t log_newsize, int unicode); +static int dictresize(PyInterpreterState *interp, PyDictObject *mp, + uint8_t log_newsize, int unicode); static PyObject* dict_iter(PyDictObject *dict); -/*Global counter used to set ma_version_tag field of dictionary. - * It is incremented each time that a dictionary is created and each - * time that a dictionary is modified. */ -uint64_t _pydict_global_version = 0; - #include "clinic/dictobject.c.h" #if PyDict_MAXFREELIST > 0 static struct _Py_dict_state * -get_dict_state(void) +get_dict_state(PyInterpreterState *interp) { - PyInterpreterState *interp = _PyInterpreterState_GET(); return &interp->dict_state; } #endif @@ -294,7 +289,8 @@ void _PyDict_DebugMallocStats(FILE *out) { #if PyDict_MAXFREELIST > 0 - struct _Py_dict_state *state = get_dict_state(); + PyInterpreterState *interp = _PyInterpreterState_GET(); + struct _Py_dict_state *state = get_dict_state(interp); _PyDebugAllocatorStats(out, "free PyDictObject", state->numfree, sizeof(PyDictObject)); #endif @@ -302,26 +298,39 @@ _PyDict_DebugMallocStats(FILE *out) #define DK_MASK(dk) (DK_SIZE(dk)-1) -static void free_keys_object(PyDictKeysObject *keys); +static void free_keys_object(PyInterpreterState *interp, PyDictKeysObject *keys); + +/* PyDictKeysObject has refcounts like PyObject does, so we have the + following two functions to mirror what Py_INCREF() and Py_DECREF() do. + (Keep in mind that PyDictKeysObject isn't actually a PyObject.) + Likewise a PyDictKeysObject can be immortal (e.g. Py_EMPTY_KEYS), + so we apply a naive version of what Py_INCREF() and Py_DECREF() do + for immortal objects. */ static inline void dictkeys_incref(PyDictKeysObject *dk) { + if (dk->dk_refcnt == _Py_IMMORTAL_REFCNT) { + return; + } #ifdef Py_REF_DEBUG - _Py_RefTotal++; + _Py_IncRefTotal(_PyInterpreterState_GET()); #endif dk->dk_refcnt++; } static inline void -dictkeys_decref(PyDictKeysObject *dk) +dictkeys_decref(PyInterpreterState *interp, PyDictKeysObject *dk) { + if (dk->dk_refcnt == _Py_IMMORTAL_REFCNT) { + return; + } assert(dk->dk_refcnt > 0); #ifdef Py_REF_DEBUG - _Py_RefTotal--; + _Py_DecRefTotal(_PyInterpreterState_GET()); #endif if (--dk->dk_refcnt == 0) { - free_keys_object(dk); + free_keys_object(interp, dk); } } @@ -451,7 +460,7 @@ estimate_log2_keysize(Py_ssize_t n) * (which cannot fail and thus can do no allocation). */ static PyDictKeysObject empty_keys_struct = { - 1, /* dk_refcnt */ + _Py_IMMORTAL_REFCNT, /* dk_refcnt */ 0, /* dk_log2_size */ 0, /* dk_log2_index_bytes */ DICT_KEYS_UNICODE, /* dk_kind */ @@ -591,7 +600,7 @@ _PyDict_CheckConsistency(PyObject *op, int check_content) static PyDictKeysObject* -new_keys_object(uint8_t log2_size, bool unicode) +new_keys_object(PyInterpreterState *interp, uint8_t log2_size, bool unicode) { PyDictKeysObject *dk; Py_ssize_t usable; @@ -600,7 +609,7 @@ new_keys_object(uint8_t log2_size, bool unicode) assert(log2_size >= PyDict_LOG_MINSIZE); - usable = USABLE_FRACTION(1<<log2_size); + usable = USABLE_FRACTION((size_t)1<<log2_size); if (log2_size < 8) { log2_bytes = log2_size; } @@ -617,7 +626,7 @@ new_keys_object(uint8_t log2_size, bool unicode) } #if PyDict_MAXFREELIST > 0 - struct _Py_dict_state *state = get_dict_state(); + struct _Py_dict_state *state = get_dict_state(interp); #ifdef Py_DEBUG // new_keys_object() must not be called after _PyDict_Fini() assert(state->keys_numfree != -1); @@ -638,7 +647,7 @@ new_keys_object(uint8_t log2_size, bool unicode) } } #ifdef Py_REF_DEBUG - _Py_RefTotal++; + _Py_IncRefTotal(_PyInterpreterState_GET()); #endif dk->dk_refcnt = 1; dk->dk_log2_size = log2_size; @@ -653,7 +662,7 @@ new_keys_object(uint8_t log2_size, bool unicode) } static void -free_keys_object(PyDictKeysObject *keys) +free_keys_object(PyInterpreterState *interp, PyDictKeysObject *keys) { assert(keys != Py_EMPTY_KEYS); if (DK_IS_UNICODE(keys)) { @@ -673,7 +682,7 @@ free_keys_object(PyDictKeysObject *keys) } } #if PyDict_MAXFREELIST > 0 - struct _Py_dict_state *state = get_dict_state(); + struct _Py_dict_state *state = get_dict_state(interp); #ifdef Py_DEBUG // free_keys_object() must not be called after _PyDict_Fini() assert(state->keys_numfree != -1); @@ -690,9 +699,9 @@ free_keys_object(PyDictKeysObject *keys) } static inline PyDictValues* -new_values(Py_ssize_t size) +new_values(size_t size) { - assert(size > 0); + assert(size >= 1); size_t prefix_size = _Py_SIZE_ROUND_UP(size+2, sizeof(PyObject *)); assert(prefix_size < 256); size_t n = prefix_size + size * sizeof(PyObject *); @@ -714,12 +723,14 @@ free_values(PyDictValues *values) /* Consumes a reference to the keys object */ static PyObject * -new_dict(PyDictKeysObject *keys, PyDictValues *values, Py_ssize_t used, int free_values_on_failure) +new_dict(PyInterpreterState *interp, + PyDictKeysObject *keys, PyDictValues *values, + Py_ssize_t used, int free_values_on_failure) { PyDictObject *mp; assert(keys != NULL); #if PyDict_MAXFREELIST > 0 - struct _Py_dict_state *state = get_dict_state(); + struct _Py_dict_state *state = get_dict_state(interp); #ifdef Py_DEBUG // new_dict() must not be called after _PyDict_Fini() assert(state->numfree != -1); @@ -736,7 +747,7 @@ new_dict(PyDictKeysObject *keys, PyDictValues *values, Py_ssize_t used, int free { mp = PyObject_GC_New(PyDictObject, &PyDict_Type); if (mp == NULL) { - dictkeys_decref(keys); + dictkeys_decref(interp, keys); if (free_values_on_failure) { free_values(values); } @@ -746,35 +757,32 @@ new_dict(PyDictKeysObject *keys, PyDictValues *values, Py_ssize_t used, int free mp->ma_keys = keys; mp->ma_values = values; mp->ma_used = used; - mp->ma_version_tag = DICT_NEXT_VERSION(); + mp->ma_version_tag = DICT_NEXT_VERSION(interp); ASSERT_CONSISTENT(mp); return (PyObject *)mp; } -static inline Py_ssize_t +static inline size_t shared_keys_usable_size(PyDictKeysObject *keys) { - return keys->dk_nentries + keys->dk_usable; + return (size_t)keys->dk_nentries + (size_t)keys->dk_usable; } /* Consumes a reference to the keys object */ static PyObject * -new_dict_with_shared_keys(PyDictKeysObject *keys) +new_dict_with_shared_keys(PyInterpreterState *interp, PyDictKeysObject *keys) { - PyDictValues *values; - Py_ssize_t i, size; - - size = shared_keys_usable_size(keys); - values = new_values(size); + size_t size = shared_keys_usable_size(keys); + PyDictValues *values = new_values(size); if (values == NULL) { - dictkeys_decref(keys); + dictkeys_decref(interp, keys); return PyErr_NoMemory(); } ((char *)values)[-2] = 0; - for (i = 0; i < size; i++) { + for (size_t i = 0; i < size; i++) { values->values[i] = NULL; } - return new_dict(keys, values, 0, 1); + return new_dict(interp, keys, values, 0, 1); } @@ -784,9 +792,10 @@ clone_combined_dict_keys(PyDictObject *orig) assert(PyDict_Check(orig)); assert(Py_TYPE(orig)->tp_iter == (getiterfunc)dict_iter); assert(orig->ma_values == NULL); + assert(orig->ma_keys != Py_EMPTY_KEYS); assert(orig->ma_keys->dk_refcnt == 1); - Py_ssize_t keys_size = _PyDict_KeysSize(orig->ma_keys); + size_t keys_size = _PyDict_KeysSize(orig->ma_keys); PyDictKeysObject *keys = PyObject_Malloc(keys_size); if (keys == NULL) { PyErr_NoMemory(); @@ -829,7 +838,7 @@ clone_combined_dict_keys(PyDictObject *orig) we have it now; calling dictkeys_incref would be an error as keys->dk_refcnt is already set to 1 (after memcpy). */ #ifdef Py_REF_DEBUG - _Py_RefTotal++; + _Py_IncRefTotal(_PyInterpreterState_GET()); #endif return keys; } @@ -837,8 +846,9 @@ clone_combined_dict_keys(PyDictObject *orig) PyObject * PyDict_New(void) { - dictkeys_incref(Py_EMPTY_KEYS); - return new_dict(Py_EMPTY_KEYS, NULL, 0, 0); + PyInterpreterState *interp = _PyInterpreterState_GET(); + /* We don't incref Py_EMPTY_KEYS here because it is immortal. */ + return new_dict(interp, Py_EMPTY_KEYS, NULL, 0, 0); } /* Search index of hash table from offset of entry table */ @@ -934,6 +944,7 @@ unicodekeys_lookup_unicode(PyDictKeysObject* dk, PyObject *key, Py_hash_t hash) } perturb >>= PERTURB_SHIFT; i = mask & (i*5 + perturb + 1); + // Manual loop unrolling ix = dictkeys_get_index(dk, i); if (ix >= 0) { PyDictUnicodeEntry *ep = &ep0[ix]; @@ -1178,9 +1189,9 @@ find_empty_slot(PyDictKeysObject *keys, Py_hash_t hash) } static int -insertion_resize(PyDictObject *mp, int unicode) +insertion_resize(PyInterpreterState *interp, PyDictObject *mp, int unicode) { - return dictresize(mp, calculate_log2_keysize(GROWTH_RATE(mp)), unicode); + return dictresize(interp, mp, calculate_log2_keysize(GROWTH_RATE(mp)), unicode); } static Py_ssize_t @@ -1200,7 +1211,6 @@ insert_into_dictkeys(PyDictKeysObject *keys, PyObject *name) if (keys->dk_usable <= 0) { return DKIX_EMPTY; } - Py_INCREF(name); /* Insert into new slot. */ keys->dk_version = 0; Py_ssize_t hashpos = find_empty_slot(keys, hash); @@ -1208,7 +1218,7 @@ insert_into_dictkeys(PyDictKeysObject *keys, PyObject *name) PyDictUnicodeEntry *ep = &DK_UNICODE_ENTRIES(keys)[ix]; dictkeys_set_index(keys, hashpos, ix); assert(ep->me_key == NULL); - ep->me_key = name; + ep->me_key = Py_NewRef(name); keys->dk_usable--; keys->dk_nentries++; } @@ -1223,12 +1233,13 @@ Returns -1 if an error occurred, or 0 on success. Consumes key and value references. */ static int -insertdict(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject *value) +insertdict(PyInterpreterState *interp, PyDictObject *mp, + PyObject *key, Py_hash_t hash, PyObject *value) { PyObject *old_value; if (DK_IS_UNICODE(mp->ma_keys) && !PyUnicode_CheckExact(key)) { - if (insertion_resize(mp, 0) < 0) + if (insertion_resize(interp, mp, 0) < 0) goto Fail; assert(mp->ma_keys->dk_kind == DICT_KEYS_GENERAL); } @@ -1240,12 +1251,14 @@ insertdict(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject *value) MAINTAIN_TRACKING(mp, key, value); if (ix == DKIX_EMPTY) { + uint64_t new_version = _PyDict_NotifyEvent( + interp, PyDict_EVENT_ADDED, mp, key, value); /* Insert into new slot. */ mp->ma_keys->dk_version = 0; assert(old_value == NULL); if (mp->ma_keys->dk_usable <= 0) { /* Need to resize. */ - if (insertion_resize(mp, 1) < 0) + if (insertion_resize(interp, mp, 1) < 0) goto Fail; } @@ -1274,7 +1287,7 @@ insertdict(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject *value) ep->me_value = value; } mp->ma_used++; - mp->ma_version_tag = DICT_NEXT_VERSION(); + mp->ma_version_tag = new_version; mp->ma_keys->dk_usable--; mp->ma_keys->dk_nentries++; assert(mp->ma_keys->dk_usable >= 0); @@ -1283,6 +1296,8 @@ insertdict(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject *value) } if (old_value != value) { + uint64_t new_version = _PyDict_NotifyEvent( + interp, PyDict_EVENT_MODIFIED, mp, key, value); if (_PyDict_HasSplitTable(mp)) { mp->ma_values->values[ix] = value; if (old_value == NULL) { @@ -1299,7 +1314,7 @@ insertdict(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject *value) DK_ENTRIES(mp->ma_keys)[ix].me_value = value; } } - mp->ma_version_tag = DICT_NEXT_VERSION(); + mp->ma_version_tag = new_version; } Py_XDECREF(old_value); /* which **CAN** re-enter (see issue #22653) */ ASSERT_CONSISTENT(mp); @@ -1315,19 +1330,23 @@ Fail: // Same to insertdict but specialized for ma_keys = Py_EMPTY_KEYS. // Consumes key and value references. static int -insert_to_emptydict(PyDictObject *mp, PyObject *key, Py_hash_t hash, - PyObject *value) +insert_to_emptydict(PyInterpreterState *interp, PyDictObject *mp, + PyObject *key, Py_hash_t hash, PyObject *value) { assert(mp->ma_keys == Py_EMPTY_KEYS); + uint64_t new_version = _PyDict_NotifyEvent( + interp, PyDict_EVENT_ADDED, mp, key, value); + int unicode = PyUnicode_CheckExact(key); - PyDictKeysObject *newkeys = new_keys_object(PyDict_LOG_MINSIZE, unicode); + PyDictKeysObject *newkeys = new_keys_object( + interp, PyDict_LOG_MINSIZE, unicode); if (newkeys == NULL) { Py_DECREF(key); Py_DECREF(value); return -1; } - dictkeys_decref(Py_EMPTY_KEYS); + /* We don't decref Py_EMPTY_KEYS here because it is immortal. */ mp->ma_keys = newkeys; mp->ma_values = NULL; @@ -1347,7 +1366,7 @@ insert_to_emptydict(PyDictObject *mp, PyObject *key, Py_hash_t hash, ep->me_value = value; } mp->ma_used++; - mp->ma_version_tag = DICT_NEXT_VERSION(); + mp->ma_version_tag = new_version; mp->ma_keys->dk_usable--; mp->ma_keys->dk_nentries++; return 0; @@ -1402,7 +1421,8 @@ This function supports: - Generic -> Generic */ static int -dictresize(PyDictObject *mp, uint8_t log2_newsize, int unicode) +dictresize(PyInterpreterState *interp, PyDictObject *mp, + uint8_t log2_newsize, int unicode) { PyDictKeysObject *oldkeys; PyDictValues *oldvalues; @@ -1426,7 +1446,7 @@ dictresize(PyDictObject *mp, uint8_t log2_newsize, int unicode) */ /* Allocate a new table. */ - mp->ma_keys = new_keys_object(log2_newsize, unicode); + mp->ma_keys = new_keys_object(interp, log2_newsize, unicode); if (mp->ma_keys == NULL) { mp->ma_keys = oldkeys; return -1; @@ -1449,8 +1469,7 @@ dictresize(PyDictObject *mp, uint8_t log2_newsize, int unicode) int index = get_index_from_order(mp, i); PyDictUnicodeEntry *ep = &oldentries[index]; assert(oldvalues->values[index] != NULL); - Py_INCREF(ep->me_key); - newentries[i].me_key = ep->me_key; + newentries[i].me_key = Py_NewRef(ep->me_key); newentries[i].me_hash = unicode_get_hash(ep->me_key); newentries[i].me_value = oldvalues->values[index]; } @@ -1463,13 +1482,12 @@ dictresize(PyDictObject *mp, uint8_t log2_newsize, int unicode) int index = get_index_from_order(mp, i); PyDictUnicodeEntry *ep = &oldentries[index]; assert(oldvalues->values[index] != NULL); - Py_INCREF(ep->me_key); - newentries[i].me_key = ep->me_key; + newentries[i].me_key = Py_NewRef(ep->me_key); newentries[i].me_value = oldvalues->values[index]; } build_indices_unicode(mp->ma_keys, newentries, numentries); } - dictkeys_decref(oldkeys); + dictkeys_decref(interp, oldkeys); mp->ma_values = NULL; free_values(oldvalues); } @@ -1526,18 +1544,14 @@ dictresize(PyDictObject *mp, uint8_t log2_newsize, int unicode) // We can not use free_keys_object here because key's reference // are moved already. + if (oldkeys != Py_EMPTY_KEYS) { #ifdef Py_REF_DEBUG - _Py_RefTotal--; + _Py_DecRefTotal(_PyInterpreterState_GET()); #endif - if (oldkeys == Py_EMPTY_KEYS) { - oldkeys->dk_refcnt--; - assert(oldkeys->dk_refcnt > 0); - } - else { assert(oldkeys->dk_kind != DICT_KEYS_SPLIT); assert(oldkeys->dk_refcnt == 1); #if PyDict_MAXFREELIST > 0 - struct _Py_dict_state *state = get_dict_state(); + struct _Py_dict_state *state = get_dict_state(interp); #ifdef Py_DEBUG // dictresize() must not be called after _PyDict_Fini() assert(state->keys_numfree != -1); @@ -1564,7 +1578,7 @@ dictresize(PyDictObject *mp, uint8_t log2_newsize, int unicode) } static PyObject * -dict_new_presized(Py_ssize_t minused, bool unicode) +dict_new_presized(PyInterpreterState *interp, Py_ssize_t minused, bool unicode) { const uint8_t log2_max_presize = 17; const Py_ssize_t max_presize = ((Py_ssize_t)1) << log2_max_presize; @@ -1585,16 +1599,17 @@ dict_new_presized(Py_ssize_t minused, bool unicode) log2_newsize = estimate_log2_keysize(minused); } - new_keys = new_keys_object(log2_newsize, unicode); + new_keys = new_keys_object(interp, log2_newsize, unicode); if (new_keys == NULL) return NULL; - return new_dict(new_keys, NULL, 0, 0); + return new_dict(interp, new_keys, NULL, 0, 0); } PyObject * _PyDict_NewPresized(Py_ssize_t minused) { - return dict_new_presized(minused, false); + PyInterpreterState *interp = _PyInterpreterState_GET(); + return dict_new_presized(interp, minused, false); } PyObject * @@ -1604,6 +1619,7 @@ _PyDict_FromItems(PyObject *const *keys, Py_ssize_t keys_offset, { bool unicode = true; PyObject *const *ks = keys; + PyInterpreterState *interp = _PyInterpreterState_GET(); for (Py_ssize_t i = 0; i < length; i++) { if (!PyUnicode_CheckExact(*ks)) { @@ -1613,7 +1629,7 @@ _PyDict_FromItems(PyObject *const *keys, Py_ssize_t keys_offset, ks += keys_offset; } - PyObject *dict = dict_new_presized(length, unicode); + PyObject *dict = dict_new_presized(interp, length, unicode); if (dict == NULL) { return NULL; } @@ -1670,15 +1686,15 @@ PyDict_GetItem(PyObject *op, PyObject *key) #endif /* Preserve the existing exception */ - PyObject *exc_type, *exc_value, *exc_tb; PyObject *value; Py_ssize_t ix; (void)ix; - _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb); + + PyObject *exc = _PyErr_GetRaisedException(tstate); ix = _Py_dict_lookup(mp, key, hash, &value); /* Ignore any exception raised by the lookup */ - _PyErr_Restore(tstate, exc_type, exc_value, exc_tb); + _PyErr_SetRaisedException(tstate, exc); assert(ix >= 0 || value == NULL); @@ -1686,50 +1702,12 @@ PyDict_GetItem(PyObject *op, PyObject *key) } Py_ssize_t -_PyDict_GetItemHint(PyDictObject *mp, PyObject *key, - Py_ssize_t hint, PyObject **value) +_PyDict_LookupIndex(PyDictObject *mp, PyObject *key) { - assert(*value == NULL); + PyObject *value; assert(PyDict_CheckExact((PyObject*)mp)); assert(PyUnicode_CheckExact(key)); - if (hint >= 0 && hint < mp->ma_keys->dk_nentries) { - PyObject *res = NULL; - - if (DK_IS_UNICODE(mp->ma_keys)) { - PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(mp->ma_keys) + (size_t)hint; - if (ep->me_key == key) { - if (mp->ma_keys->dk_kind == DICT_KEYS_SPLIT) { - assert(mp->ma_values != NULL); - res = mp->ma_values->values[(size_t)hint]; - } - else { - res = ep->me_value; - } - if (res != NULL) { - *value = res; - return hint; - } - } - } - else { - PyDictKeyEntry *ep = DK_ENTRIES(mp->ma_keys) + (size_t)hint; - if (ep->me_key == key) { - if (mp->ma_keys->dk_kind == DICT_KEYS_SPLIT) { - assert(mp->ma_values != NULL); - res = mp->ma_values->values[(size_t)hint]; - } - else { - res = ep->me_value; - } - if (res != NULL) { - *value = res; - return hint; - } - } - } - } - Py_hash_t hash = unicode_get_hash(key); if (hash == -1) { hash = PyObject_Hash(key); @@ -1738,7 +1716,7 @@ _PyDict_GetItemHint(PyDictObject *mp, PyObject *key, } } - return _Py_dict_lookup(mp, key, hash, value); + return _Py_dict_lookup(mp, key, hash, &value); } /* Same as PyDict_GetItemWithError() but with hash supplied by caller. @@ -1879,11 +1857,12 @@ _PyDict_SetItem_Take2(PyDictObject *mp, PyObject *key, PyObject *value) return -1; } } + PyInterpreterState *interp = _PyInterpreterState_GET(); if (mp->ma_keys == Py_EMPTY_KEYS) { - return insert_to_emptydict(mp, key, hash, value); + return insert_to_emptydict(interp, mp, key, hash, value); } /* insertdict() handles any resizing that might be necessary */ - return insertdict(mp, key, hash, value); + return insertdict(interp, mp, key, hash, value); } /* CAUTION: PyDict_SetItem() must guarantee that it won't resize the @@ -1901,9 +1880,8 @@ PyDict_SetItem(PyObject *op, PyObject *key, PyObject *value) } assert(key); assert(value); - Py_INCREF(key); - Py_INCREF(value); - return _PyDict_SetItem_Take2((PyDictObject *)op, key, value); + return _PyDict_SetItem_Take2((PyDictObject *)op, + Py_NewRef(key), Py_NewRef(value)); } int @@ -1921,13 +1899,12 @@ _PyDict_SetItem_KnownHash(PyObject *op, PyObject *key, PyObject *value, assert(hash != -1); mp = (PyDictObject *)op; - Py_INCREF(key); - Py_INCREF(value); + PyInterpreterState *interp = _PyInterpreterState_GET(); if (mp->ma_keys == Py_EMPTY_KEYS) { - return insert_to_emptydict(mp, key, hash, value); + return insert_to_emptydict(interp, mp, Py_NewRef(key), hash, Py_NewRef(value)); } /* insertdict() handles any resizing that might be necessary */ - return insertdict(mp, key, hash, value); + return insertdict(interp, mp, Py_NewRef(key), hash, Py_NewRef(value)); } static void @@ -1948,7 +1925,7 @@ delete_index_from_values(PyDictValues *values, Py_ssize_t ix) static int delitem_common(PyDictObject *mp, Py_hash_t hash, Py_ssize_t ix, - PyObject *old_value) + PyObject *old_value, uint64_t new_version) { PyObject *old_key; @@ -1956,7 +1933,7 @@ delitem_common(PyDictObject *mp, Py_hash_t hash, Py_ssize_t ix, assert(hashpos >= 0); mp->ma_used--; - mp->ma_version_tag = DICT_NEXT_VERSION(); + mp->ma_version_tag = new_version; if (mp->ma_values) { assert(old_value == mp->ma_values->values[ix]); mp->ma_values->values[ix] = NULL; @@ -2025,7 +2002,10 @@ _PyDict_DelItem_KnownHash(PyObject *op, PyObject *key, Py_hash_t hash) return -1; } - return delitem_common(mp, hash, ix, old_value); + PyInterpreterState *interp = _PyInterpreterState_GET(); + uint64_t new_version = _PyDict_NotifyEvent( + interp, PyDict_EVENT_DELETED, mp, key, NULL); + return delitem_common(mp, hash, ix, old_value, new_version); } /* This function promises that the predicate -> deletion sequence is atomic @@ -2066,10 +2046,14 @@ _PyDict_DelItemIf(PyObject *op, PyObject *key, hashpos = lookdict_index(mp->ma_keys, hash, ix); assert(hashpos >= 0); - if (res > 0) - return delitem_common(mp, hashpos, ix, old_value); - else + if (res > 0) { + PyInterpreterState *interp = _PyInterpreterState_GET(); + uint64_t new_version = _PyDict_NotifyEvent( + interp, PyDict_EVENT_DELETED, mp, key, NULL); + return delitem_common(mp, hashpos, ix, old_value, new_version); + } else { return 0; + } } @@ -2090,22 +2074,25 @@ PyDict_Clear(PyObject *op) return; } /* Empty the dict... */ + PyInterpreterState *interp = _PyInterpreterState_GET(); + uint64_t new_version = _PyDict_NotifyEvent( + interp, PyDict_EVENT_CLEARED, mp, NULL, NULL); dictkeys_incref(Py_EMPTY_KEYS); mp->ma_keys = Py_EMPTY_KEYS; mp->ma_values = NULL; mp->ma_used = 0; - mp->ma_version_tag = DICT_NEXT_VERSION(); + mp->ma_version_tag = new_version; /* ...then clear the keys and values */ if (oldvalues != NULL) { n = oldkeys->dk_nentries; for (i = 0; i < n; i++) Py_CLEAR(oldvalues->values[i]); free_values(oldvalues); - dictkeys_decref(oldkeys); + dictkeys_decref(interp, oldkeys); } else { - assert(oldkeys->dk_refcnt == 1); - dictkeys_decref(oldkeys); + assert(oldkeys->dk_refcnt == 1); + dictkeys_decref(interp, oldkeys); } ASSERT_CONSISTENT(mp); } @@ -2209,14 +2196,14 @@ _PyDict_Pop_KnownHash(PyObject *dict, PyObject *key, Py_hash_t hash, PyObject *d Py_ssize_t ix; PyObject *old_value; PyDictObject *mp; + PyInterpreterState *interp = _PyInterpreterState_GET(); assert(PyDict_Check(dict)); mp = (PyDictObject *)dict; if (mp->ma_used == 0) { if (deflt) { - Py_INCREF(deflt); - return deflt; + return Py_NewRef(deflt); } _PyErr_SetKeyError(key); return NULL; @@ -2226,15 +2213,15 @@ _PyDict_Pop_KnownHash(PyObject *dict, PyObject *key, Py_hash_t hash, PyObject *d return NULL; if (ix == DKIX_EMPTY || old_value == NULL) { if (deflt) { - Py_INCREF(deflt); - return deflt; + return Py_NewRef(deflt); } _PyErr_SetKeyError(key); return NULL; } assert(old_value != NULL); - Py_INCREF(old_value); - delitem_common(mp, hash, ix, old_value); + uint64_t new_version = _PyDict_NotifyEvent( + interp, PyDict_EVENT_DELETED, mp, key, NULL); + delitem_common(mp, hash, ix, Py_NewRef(old_value), new_version); ASSERT_CONSISTENT(mp); return old_value; @@ -2247,8 +2234,7 @@ _PyDict_Pop(PyObject *dict, PyObject *key, PyObject *deflt) if (((PyDictObject *)dict)->ma_used == 0) { if (deflt) { - Py_INCREF(deflt); - return deflt; + return Py_NewRef(deflt); } _PyErr_SetKeyError(key); return NULL; @@ -2269,6 +2255,7 @@ _PyDict_FromKeys(PyObject *cls, PyObject *iterable, PyObject *value) PyObject *key; PyObject *d; int status; + PyInterpreterState *interp = _PyInterpreterState_GET(); d = _PyObject_CallNoArgs(cls); if (d == NULL) @@ -2283,15 +2270,16 @@ _PyDict_FromKeys(PyObject *cls, PyObject *iterable, PyObject *value) Py_hash_t hash; int unicode = DK_IS_UNICODE(((PyDictObject*)iterable)->ma_keys); - if (dictresize(mp, estimate_log2_keysize(PyDict_GET_SIZE(iterable)), unicode)) { + if (dictresize(interp, mp, + estimate_log2_keysize(PyDict_GET_SIZE(iterable)), + unicode)) { Py_DECREF(d); return NULL; } while (_PyDict_Next(iterable, &pos, &key, &oldvalue, &hash)) { - Py_INCREF(key); - Py_INCREF(value); - if (insertdict(mp, key, hash, value)) { + if (insertdict(interp, mp, + Py_NewRef(key), hash, Py_NewRef(value))) { Py_DECREF(d); return NULL; } @@ -2304,15 +2292,14 @@ _PyDict_FromKeys(PyObject *cls, PyObject *iterable, PyObject *value) PyObject *key; Py_hash_t hash; - if (dictresize(mp, estimate_log2_keysize(PySet_GET_SIZE(iterable)), 0)) { + if (dictresize(interp, mp, + estimate_log2_keysize(PySet_GET_SIZE(iterable)), 0)) { Py_DECREF(d); return NULL; } while (_PySet_NextEntry(iterable, &pos, &key, &hash)) { - Py_INCREF(key); - Py_INCREF(value); - if (insertdict(mp, key, hash, value)) { + if (insertdict(interp, mp, Py_NewRef(key), hash, Py_NewRef(value))) { Py_DECREF(d); return NULL; } @@ -2359,6 +2346,15 @@ Fail: static void dict_dealloc(PyDictObject *mp) { + PyInterpreterState *interp = _PyInterpreterState_GET(); + assert(Py_REFCNT(mp) == 0); + Py_SET_REFCNT(mp, 1); + _PyDict_NotifyEvent(interp, PyDict_EVENT_DEALLOCATED, mp, NULL, NULL); + if (Py_REFCNT(mp) > 1) { + Py_SET_REFCNT(mp, Py_REFCNT(mp) - 1); + return; + } + Py_SET_REFCNT(mp, 0); PyDictValues *values = mp->ma_values; PyDictKeysObject *keys = mp->ma_keys; Py_ssize_t i, n; @@ -2371,14 +2367,14 @@ dict_dealloc(PyDictObject *mp) Py_XDECREF(values->values[i]); } free_values(values); - dictkeys_decref(keys); + dictkeys_decref(interp, keys); } else if (keys != NULL) { assert(keys->dk_refcnt == 1 || keys == Py_EMPTY_KEYS); - dictkeys_decref(keys); + dictkeys_decref(interp, keys); } #if PyDict_MAXFREELIST > 0 - struct _Py_dict_state *state = get_dict_state(); + struct _Py_dict_state *state = get_dict_state(interp); #ifdef Py_DEBUG // new_dict() must not be called after _PyDict_Fini() assert(state->numfree != -1); @@ -2517,8 +2513,7 @@ dict_subscript(PyDictObject *mp, PyObject *key) _PyErr_SetKeyError(key); return NULL; } - Py_INCREF(value); - return value; + return Py_NewRef(value); } static int @@ -2560,8 +2555,7 @@ dict_keys(PyDictObject *mp) PyObject *key; while (_PyDict_Next((PyObject*)mp, &pos, &key, NULL, NULL)) { assert(j < n); - Py_INCREF(key); - PyList_SET_ITEM(v, j, key); + PyList_SET_ITEM(v, j, Py_NewRef(key)); j++; } assert(j == n); @@ -2592,8 +2586,7 @@ dict_values(PyDictObject *mp) PyObject *value; while (_PyDict_Next((PyObject*)mp, &pos, NULL, &value, NULL)) { assert(j < n); - Py_INCREF(value); - PyList_SET_ITEM(v, j, value); + PyList_SET_ITEM(v, j, Py_NewRef(value)); j++; } assert(j == n); @@ -2638,10 +2631,8 @@ dict_items(PyDictObject *mp) while (_PyDict_Next((PyObject*)mp, &pos, &key, &value, NULL)) { assert(j < n); PyObject *item = PyList_GET_ITEM(v, j); - Py_INCREF(key); - PyTuple_SET_ITEM(item, 0, key); - Py_INCREF(value); - PyTuple_SET_ITEM(item, 1, value); + PyTuple_SET_ITEM(item, 0, Py_NewRef(key)); + PyTuple_SET_ITEM(item, 1, Py_NewRef(value)); j++; } assert(j == n); @@ -2813,7 +2804,7 @@ Return: } static int -dict_merge(PyObject *a, PyObject *b, int override) +dict_merge(PyInterpreterState *interp, PyObject *a, PyObject *b, int override) { PyDictObject *mp, *other; @@ -2847,12 +2838,14 @@ dict_merge(PyObject *a, PyObject *b, int override) other->ma_used == okeys->dk_nentries && (DK_LOG_SIZE(okeys) == PyDict_LOG_MINSIZE || USABLE_FRACTION(DK_SIZE(okeys)/2) < other->ma_used)) { + uint64_t new_version = _PyDict_NotifyEvent( + interp, PyDict_EVENT_CLONED, mp, b, NULL); PyDictKeysObject *keys = clone_combined_dict_keys(other); if (keys == NULL) { return -1; } - dictkeys_decref(mp->ma_keys); + dictkeys_decref(interp, mp->ma_keys); mp->ma_keys = keys; if (mp->ma_values != NULL) { free_values(mp->ma_values); @@ -2860,7 +2853,7 @@ dict_merge(PyObject *a, PyObject *b, int override) } mp->ma_used = other->ma_used; - mp->ma_version_tag = DICT_NEXT_VERSION(); + mp->ma_version_tag = new_version; ASSERT_CONSISTENT(mp); if (_PyObject_GC_IS_TRACKED(other) && !_PyObject_GC_IS_TRACKED(mp)) { @@ -2877,7 +2870,9 @@ dict_merge(PyObject *a, PyObject *b, int override) */ if (USABLE_FRACTION(DK_SIZE(mp->ma_keys)) < other->ma_used) { int unicode = DK_IS_UNICODE(other->ma_keys); - if (dictresize(mp, estimate_log2_keysize(mp->ma_used + other->ma_used), unicode)) { + if (dictresize(interp, mp, + estimate_log2_keysize(mp->ma_used + other->ma_used), + unicode)) { return -1; } } @@ -2892,16 +2887,14 @@ dict_merge(PyObject *a, PyObject *b, int override) Py_INCREF(key); Py_INCREF(value); if (override == 1) { - Py_INCREF(key); - Py_INCREF(value); - err = insertdict(mp, key, hash, value); + err = insertdict(interp, mp, + Py_NewRef(key), hash, Py_NewRef(value)); } else { err = _PyDict_Contains_KnownHash(a, key, hash); if (err == 0) { - Py_INCREF(key); - Py_INCREF(value); - err = insertdict(mp, key, hash, value); + err = insertdict(interp, mp, + Py_NewRef(key), hash, Py_NewRef(value)); } else if (err > 0) { if (override != 0) { @@ -2987,20 +2980,23 @@ dict_merge(PyObject *a, PyObject *b, int override) int PyDict_Update(PyObject *a, PyObject *b) { - return dict_merge(a, b, 1); + PyInterpreterState *interp = _PyInterpreterState_GET(); + return dict_merge(interp, a, b, 1); } int PyDict_Merge(PyObject *a, PyObject *b, int override) { + PyInterpreterState *interp = _PyInterpreterState_GET(); /* XXX Deprecate override not in (0, 1). */ - return dict_merge(a, b, override != 0); + return dict_merge(interp, a, b, override != 0); } int _PyDict_MergeEx(PyObject *a, PyObject *b, int override) { - return dict_merge(a, b, override); + PyInterpreterState *interp = _PyInterpreterState_GET(); + return dict_merge(interp, a, b, override); } static PyObject * @@ -3014,7 +3010,7 @@ PyDict_Copy(PyObject *o) { PyObject *copy; PyDictObject *mp; - Py_ssize_t i, n; + PyInterpreterState *interp = _PyInterpreterState_GET(); if (o == NULL || !PyDict_Check(o)) { PyErr_BadInternalCall(); @@ -3029,9 +3025,8 @@ PyDict_Copy(PyObject *o) if (_PyDict_HasSplitTable(mp)) { PyDictObject *split_copy; - Py_ssize_t size = shared_keys_usable_size(mp->ma_keys); - PyDictValues *newvalues; - newvalues = new_values(size); + size_t size = shared_keys_usable_size(mp->ma_keys); + PyDictValues *newvalues = new_values(size); if (newvalues == NULL) return PyErr_NoMemory(); split_copy = PyObject_GC_New(PyDictObject, &PyDict_Type); @@ -3044,12 +3039,11 @@ PyDict_Copy(PyObject *o) split_copy->ma_values = newvalues; split_copy->ma_keys = mp->ma_keys; split_copy->ma_used = mp->ma_used; - split_copy->ma_version_tag = DICT_NEXT_VERSION(); + split_copy->ma_version_tag = DICT_NEXT_VERSION(interp); dictkeys_incref(mp->ma_keys); - for (i = 0, n = size; i < n; i++) { + for (size_t i = 0; i < size; i++) { PyObject *value = mp->ma_values->values[i]; - Py_XINCREF(value); - split_copy->ma_values->values[i] = value; + split_copy->ma_values->values[i] = Py_XNewRef(value); } if (_PyObject_GC_IS_TRACKED(mp)) _PyObject_GC_TRACK(split_copy); @@ -3078,7 +3072,7 @@ PyDict_Copy(PyObject *o) if (keys == NULL) { return NULL; } - PyDictObject *new = (PyDictObject *)new_dict(keys, NULL, 0, 0); + PyDictObject *new = (PyDictObject *)new_dict(interp, keys, NULL, 0, 0); if (new == NULL) { /* In case of an error, `new_dict()` takes care of cleaning up `keys`. */ @@ -3098,7 +3092,7 @@ PyDict_Copy(PyObject *o) copy = PyDict_New(); if (copy == NULL) return NULL; - if (dict_merge(copy, o, 1) == 0) + if (dict_merge(interp, copy, o, 1) == 0) return copy; Py_DECREF(copy); return NULL; @@ -3224,8 +3218,7 @@ dict_richcompare(PyObject *v, PyObject *w, int op) } else res = Py_NotImplemented; - Py_INCREF(res); - return res; + return Py_NewRef(res); } /*[clinic input] @@ -3290,8 +3283,7 @@ dict_get_impl(PyDictObject *self, PyObject *key, PyObject *default_value) if (ix == DKIX_EMPTY || val == NULL) { val = default_value; } - Py_INCREF(val); - return val; + return Py_NewRef(val); } PyObject * @@ -3300,6 +3292,7 @@ PyDict_SetDefault(PyObject *d, PyObject *key, PyObject *defaultobj) PyDictObject *mp = (PyDictObject *)d; PyObject *value; Py_hash_t hash; + PyInterpreterState *interp = _PyInterpreterState_GET(); if (!PyDict_Check(d)) { PyErr_BadInternalCall(); @@ -3313,16 +3306,15 @@ PyDict_SetDefault(PyObject *d, PyObject *key, PyObject *defaultobj) } if (mp->ma_keys == Py_EMPTY_KEYS) { - Py_INCREF(key); - Py_INCREF(defaultobj); - if (insert_to_emptydict(mp, key, hash, defaultobj) < 0) { + if (insert_to_emptydict(interp, mp, Py_NewRef(key), hash, + Py_NewRef(defaultobj)) < 0) { return NULL; } return defaultobj; } if (!PyUnicode_CheckExact(key) && DK_IS_UNICODE(mp->ma_keys)) { - if (insertion_resize(mp, 0) < 0) { + if (insertion_resize(interp, mp, 0) < 0) { return NULL; } } @@ -3332,10 +3324,12 @@ PyDict_SetDefault(PyObject *d, PyObject *key, PyObject *defaultobj) return NULL; if (ix == DKIX_EMPTY) { + uint64_t new_version = _PyDict_NotifyEvent( + interp, PyDict_EVENT_ADDED, mp, key, defaultobj); mp->ma_keys->dk_version = 0; value = defaultobj; if (mp->ma_keys->dk_usable <= 0) { - if (insertion_resize(mp, 1) < 0) { + if (insertion_resize(interp, mp, 1) < 0) { return NULL; } } @@ -3344,43 +3338,42 @@ PyDict_SetDefault(PyObject *d, PyObject *key, PyObject *defaultobj) if (DK_IS_UNICODE(mp->ma_keys)) { assert(PyUnicode_CheckExact(key)); PyDictUnicodeEntry *ep = &DK_UNICODE_ENTRIES(mp->ma_keys)[mp->ma_keys->dk_nentries]; - ep->me_key = key; + ep->me_key = Py_NewRef(key); if (_PyDict_HasSplitTable(mp)) { Py_ssize_t index = (int)mp->ma_keys->dk_nentries; assert(index < SHARED_KEYS_MAX_SIZE); assert(mp->ma_values->values[index] == NULL); - mp->ma_values->values[index] = value; + mp->ma_values->values[index] = Py_NewRef(value); _PyDictValues_AddToInsertionOrder(mp->ma_values, index); } else { - ep->me_value = value; + ep->me_value = Py_NewRef(value); } } else { PyDictKeyEntry *ep = &DK_ENTRIES(mp->ma_keys)[mp->ma_keys->dk_nentries]; - ep->me_key = key; + ep->me_key = Py_NewRef(key); ep->me_hash = hash; - ep->me_value = value; + ep->me_value = Py_NewRef(value); } - Py_INCREF(key); - Py_INCREF(value); MAINTAIN_TRACKING(mp, key, value); mp->ma_used++; - mp->ma_version_tag = DICT_NEXT_VERSION(); + mp->ma_version_tag = new_version; mp->ma_keys->dk_usable--; mp->ma_keys->dk_nentries++; assert(mp->ma_keys->dk_usable >= 0); } else if (value == NULL) { + uint64_t new_version = _PyDict_NotifyEvent( + interp, PyDict_EVENT_ADDED, mp, key, defaultobj); value = defaultobj; assert(_PyDict_HasSplitTable(mp)); assert(mp->ma_values->values[ix] == NULL); - Py_INCREF(value); MAINTAIN_TRACKING(mp, key, value); - mp->ma_values->values[ix] = value; + mp->ma_values->values[ix] = Py_NewRef(value); _PyDictValues_AddToInsertionOrder(mp->ma_values, ix); mp->ma_used++; - mp->ma_version_tag = DICT_NEXT_VERSION(); + mp->ma_version_tag = new_version; } ASSERT_CONSISTENT(mp); @@ -3407,8 +3400,7 @@ dict_setdefault_impl(PyDictObject *self, PyObject *key, PyObject *val; val = PyDict_SetDefault((PyObject *)self, key, default_value); - Py_XINCREF(val); - return val; + return Py_XNewRef(val); } static PyObject * @@ -3453,6 +3445,8 @@ dict_popitem_impl(PyDictObject *self) { Py_ssize_t i, j; PyObject *res; + uint64_t new_version; + PyInterpreterState *interp = _PyInterpreterState_GET(); /* Allocate the result tuple before checking the size. Believe it * or not, this allocation could trigger a garbage collection which @@ -3473,7 +3467,7 @@ dict_popitem_impl(PyDictObject *self) } /* Convert split table to combined table */ if (self->ma_keys->dk_kind == DICT_KEYS_SPLIT) { - if (dictresize(self, DK_LOG_SIZE(self->ma_keys), 1)) { + if (dictresize(interp, self, DK_LOG_SIZE(self->ma_keys), 1)) { Py_DECREF(res); return NULL; } @@ -3492,6 +3486,8 @@ dict_popitem_impl(PyDictObject *self) assert(i >= 0); key = ep0[i].me_key; + new_version = _PyDict_NotifyEvent( + interp, PyDict_EVENT_DELETED, self, key, NULL); hash = unicode_get_hash(key); value = ep0[i].me_value; ep0[i].me_key = NULL; @@ -3506,6 +3502,8 @@ dict_popitem_impl(PyDictObject *self) assert(i >= 0); key = ep0[i].me_key; + new_version = _PyDict_NotifyEvent( + interp, PyDict_EVENT_DELETED, self, key, NULL); hash = ep0[i].me_hash; value = ep0[i].me_value; ep0[i].me_key = NULL; @@ -3523,7 +3521,7 @@ dict_popitem_impl(PyDictObject *self) /* We can't dk_usable++ since there is DKIX_DUMMY in indices */ self->ma_keys->dk_nentries = i; self->ma_used--; - self->ma_version_tag = DICT_NEXT_VERSION(); + self->ma_version_tag = new_version; ASSERT_CONSISTENT(self); return res; } @@ -3572,9 +3570,7 @@ static PyObject *dictiter_new(PyDictObject *, PyTypeObject *); Py_ssize_t _PyDict_SizeOf(PyDictObject *mp) { - Py_ssize_t res; - - res = _PyObject_SIZE(Py_TYPE(mp)); + size_t res = _PyObject_SIZE(Py_TYPE(mp)); if (mp->ma_values) { res += shared_keys_usable_size(mp->ma_keys) * sizeof(PyObject*); } @@ -3583,17 +3579,19 @@ _PyDict_SizeOf(PyDictObject *mp) if (mp->ma_keys->dk_refcnt == 1) { res += _PyDict_KeysSize(mp->ma_keys); } - return res; + assert(res <= (size_t)PY_SSIZE_T_MAX); + return (Py_ssize_t)res; } -Py_ssize_t +size_t _PyDict_KeysSize(PyDictKeysObject *keys) { - size_t es = keys->dk_kind == DICT_KEYS_GENERAL - ? sizeof(PyDictKeyEntry) : sizeof(PyDictUnicodeEntry); - return (sizeof(PyDictKeysObject) - + ((size_t)1 << keys->dk_log2_index_bytes) - + USABLE_FRACTION(DK_SIZE(keys)) * es); + size_t es = (keys->dk_kind == DICT_KEYS_GENERAL + ? sizeof(PyDictKeyEntry) : sizeof(PyDictUnicodeEntry)); + size_t size = sizeof(PyDictKeysObject); + size += (size_t)1 << keys->dk_log2_index_bytes; + size += USABLE_FRACTION((size_t)DK_SIZE(keys)) * es; + return size; } static PyObject * @@ -3625,11 +3623,11 @@ dict_ior(PyObject *self, PyObject *other) if (dict_update_arg(self, other)) { return NULL; } - Py_INCREF(self); - return self; + return Py_NewRef(self); } -PyDoc_STRVAR(getitem__doc__, "x.__getitem__(y) <==> x[y]"); +PyDoc_STRVAR(getitem__doc__, +"__getitem__($self, key, /)\n--\n\nReturn self[key]."); PyDoc_STRVAR(sizeof__doc__, "D.__sizeof__() -> size of D in memory, in bytes"); @@ -3764,7 +3762,8 @@ dict_new(PyTypeObject *type, PyObject *args, PyObject *kwds) PyDictObject *d = (PyDictObject *)self; d->ma_used = 0; - d->ma_version_tag = DICT_NEXT_VERSION(); + d->ma_version_tag = DICT_NEXT_VERSION( + _PyInterpreterState_GET()); dictkeys_incref(Py_EMPTY_KEYS); d->ma_keys = Py_EMPTY_KEYS; d->ma_values = NULL; @@ -3963,8 +3962,7 @@ dictiter_new(PyDictObject *dict, PyTypeObject *itertype) if (di == NULL) { return NULL; } - Py_INCREF(dict); - di->di_dict = dict; + di->di_dict = (PyDictObject*)Py_NewRef(dict); di->di_used = dict->ma_used; di->len = dict->ma_used; if (itertype == &PyDictRevIterKey_Type || @@ -4098,8 +4096,7 @@ dictiter_iternextkey(dictiterobject *di) } di->di_pos = i+1; di->len--; - Py_INCREF(key); - return key; + return Py_NewRef(key); fail: di->di_dict = NULL; @@ -4198,8 +4195,7 @@ dictiter_iternextvalue(dictiterobject *di) } di->di_pos = i+1; di->len--; - Py_INCREF(value); - return value; + return Py_NewRef(value); fail: di->di_dict = NULL; @@ -4301,14 +4297,12 @@ dictiter_iternextitem(dictiterobject *di) } di->di_pos = i+1; di->len--; - Py_INCREF(key); - Py_INCREF(value); result = di->di_result; if (Py_REFCNT(result) == 1) { PyObject *oldkey = PyTuple_GET_ITEM(result, 0); PyObject *oldvalue = PyTuple_GET_ITEM(result, 1); - PyTuple_SET_ITEM(result, 0, key); /* steals reference */ - PyTuple_SET_ITEM(result, 1, value); /* steals reference */ + PyTuple_SET_ITEM(result, 0, Py_NewRef(key)); + PyTuple_SET_ITEM(result, 1, Py_NewRef(value)); Py_INCREF(result); Py_DECREF(oldkey); Py_DECREF(oldvalue); @@ -4322,8 +4316,8 @@ dictiter_iternextitem(dictiterobject *di) result = PyTuple_New(2); if (result == NULL) return NULL; - PyTuple_SET_ITEM(result, 0, key); /* steals reference */ - PyTuple_SET_ITEM(result, 1, value); /* steals reference */ + PyTuple_SET_ITEM(result, 0, Py_NewRef(key)); + PyTuple_SET_ITEM(result, 1, Py_NewRef(value)); } return result; @@ -4427,22 +4421,18 @@ dictreviter_iternext(dictiterobject *di) di->len--; if (Py_IS_TYPE(di, &PyDictRevIterKey_Type)) { - Py_INCREF(key); - return key; + return Py_NewRef(key); } else if (Py_IS_TYPE(di, &PyDictRevIterValue_Type)) { - Py_INCREF(value); - return value; + return Py_NewRef(value); } else if (Py_IS_TYPE(di, &PyDictRevIterItem_Type)) { - Py_INCREF(key); - Py_INCREF(value); result = di->di_result; if (Py_REFCNT(result) == 1) { PyObject *oldkey = PyTuple_GET_ITEM(result, 0); PyObject *oldvalue = PyTuple_GET_ITEM(result, 1); - PyTuple_SET_ITEM(result, 0, key); /* steals reference */ - PyTuple_SET_ITEM(result, 1, value); /* steals reference */ + PyTuple_SET_ITEM(result, 0, Py_NewRef(key)); + PyTuple_SET_ITEM(result, 1, Py_NewRef(value)); Py_INCREF(result); Py_DECREF(oldkey); Py_DECREF(oldvalue); @@ -4457,8 +4447,8 @@ dictreviter_iternext(dictiterobject *di) if (result == NULL) { return NULL; } - PyTuple_SET_ITEM(result, 0, key); /* steals reference */ - PyTuple_SET_ITEM(result, 1, value); /* steals reference */ + PyTuple_SET_ITEM(result, 0, Py_NewRef(key)); + PyTuple_SET_ITEM(result, 1, Py_NewRef(value)); } return result; } @@ -4505,7 +4495,6 @@ dictiter_reduce(dictiterobject *di, PyObject *Py_UNUSED(ignored)) /* copy the iterator state */ dictiterobject tmp = *di; Py_XINCREF(tmp.di_dict); - PyObject *list = PySequence_List((PyObject*)&tmp); Py_XDECREF(tmp.di_dict); if (list == NULL) { @@ -4587,8 +4576,7 @@ _PyDictView_New(PyObject *dict, PyTypeObject *type) dv = PyObject_GC_New(_PyDictViewObject, type); if (dv == NULL) return NULL; - Py_INCREF(dict); - dv->dv_dict = (PyDictObject *)dict; + dv->dv_dict = (PyDictObject *)Py_NewRef(dict); _PyObject_GC_TRACK(dv); return (PyObject *)dv; } @@ -4699,8 +4687,7 @@ dictview_richcompare(PyObject *self, PyObject *other, int op) if (ok < 0) return NULL; result = ok ? Py_True : Py_False; - Py_INCREF(result); - return result; + return Py_NewRef(result); } static PyObject * @@ -4756,7 +4743,7 @@ static PySequenceMethods dictkeys_as_sequence = { (objobjproc)dictkeys_contains, /* sq_contains */ }; -// Create an set object from dictviews object. +// Create a set object from dictviews object. // Returns a new reference. // This utility function is used by set operations. static PyObject* @@ -5330,7 +5317,9 @@ dictvalues_reversed(_PyDictViewObject *dv, PyObject *Py_UNUSED(ignored)) PyDictKeysObject * _PyDict_NewKeysForClass(void) { - PyDictKeysObject *keys = new_keys_object(NEXT_LOG2_SHARED_KEYS_MAX_SIZE, 1); + PyInterpreterState *interp = _PyInterpreterState_GET(); + PyDictKeysObject *keys = new_keys_object( + interp, NEXT_LOG2_SHARED_KEYS_MAX_SIZE, 1); if (keys == NULL) { PyErr_Clear(); } @@ -5356,25 +5345,25 @@ init_inline_values(PyObject *obj, PyTypeObject *tp) if (keys->dk_usable > 1) { keys->dk_usable--; } - Py_ssize_t size = shared_keys_usable_size(keys); - assert(size > 0); + size_t size = shared_keys_usable_size(keys); PyDictValues *values = new_values(size); if (values == NULL) { PyErr_NoMemory(); return -1; } - assert(((uint8_t *)values)[-1] >= size+2); + assert(((uint8_t *)values)[-1] >= (size + 2)); ((uint8_t *)values)[-2] = 0; - for (int i = 0; i < size; i++) { + for (size_t i = 0; i < size; i++) { values->values[i] = NULL; } - *_PyObject_ValuesPointer(obj) = values; + _PyDictOrValues_SetValues(_PyObject_DictOrValuesPointer(obj), values); return 0; } int _PyObject_InitializeDict(PyObject *obj) { + PyInterpreterState *interp = _PyInterpreterState_GET(); PyTypeObject *tp = Py_TYPE(obj); if (tp->tp_dictoffset == 0) { return 0; @@ -5386,7 +5375,7 @@ _PyObject_InitializeDict(PyObject *obj) PyObject *dict; if (_PyType_HasFeature(tp, Py_TPFLAGS_HEAPTYPE) && CACHED_KEYS(tp)) { dictkeys_incref(CACHED_KEYS(tp)); - dict = new_dict_with_shared_keys(CACHED_KEYS(tp)); + dict = new_dict_with_shared_keys(interp, CACHED_KEYS(tp)); } else { dict = PyDict_New(); @@ -5394,25 +5383,27 @@ _PyObject_InitializeDict(PyObject *obj) if (dict == NULL) { return -1; } - PyObject **dictptr = _PyObject_DictPointer(obj); + PyObject **dictptr = _PyObject_ComputedDictPointer(obj); *dictptr = dict; return 0; } static PyObject * -make_dict_from_instance_attributes(PyDictKeysObject *keys, PyDictValues *values) +make_dict_from_instance_attributes(PyInterpreterState *interp, + PyDictKeysObject *keys, PyDictValues *values) { dictkeys_incref(keys); Py_ssize_t used = 0; Py_ssize_t track = 0; - for (Py_ssize_t i = 0; i < shared_keys_usable_size(keys); i++) { + size_t size = shared_keys_usable_size(keys); + for (size_t i = 0; i < size; i++) { PyObject *val = values->values[i]; if (val != NULL) { used += 1; track += _PyObject_GC_MAY_BE_TRACKED(val); } } - PyObject *res = new_dict(keys, values, used, 0); + PyObject *res = new_dict(interp, keys, values, used, 0); if (track && res) { _PyObject_GC_TRACK(res); } @@ -5422,16 +5413,17 @@ make_dict_from_instance_attributes(PyDictKeysObject *keys, PyDictValues *values) PyObject * _PyObject_MakeDictFromInstanceAttributes(PyObject *obj, PyDictValues *values) { - assert(Py_TYPE(obj)->tp_flags & Py_TPFLAGS_MANAGED_DICT); + PyInterpreterState *interp = _PyInterpreterState_GET(); PyDictKeysObject *keys = CACHED_KEYS(Py_TYPE(obj)); OBJECT_STAT_INC(dict_materialized_on_request); - return make_dict_from_instance_attributes(keys, values); + return make_dict_from_instance_attributes(interp, keys, values); } int _PyObject_StoreInstanceAttribute(PyObject *obj, PyDictValues *values, PyObject *name, PyObject *value) { + PyInterpreterState *interp = _PyInterpreterState_GET(); PyDictKeysObject *keys = CACHED_KEYS(Py_TYPE(obj)); assert(keys != NULL); assert(values != NULL); @@ -5454,12 +5446,12 @@ _PyObject_StoreInstanceAttribute(PyObject *obj, PyDictValues *values, OBJECT_STAT_INC(dict_materialized_str_subclass); } #endif - PyObject *dict = make_dict_from_instance_attributes(keys, values); + PyObject *dict = make_dict_from_instance_attributes( + interp, keys, values); if (dict == NULL) { return -1; } - *_PyObject_ValuesPointer(obj) = NULL; - *_PyObject_ManagedDictPointer(obj) = dict; + _PyObject_DictOrValuesPointer(obj)->dict = dict; if (value == NULL) { return PyDict_DelItem(dict, name); } @@ -5468,8 +5460,7 @@ _PyObject_StoreInstanceAttribute(PyObject *obj, PyDictValues *values, } } PyObject *old_value = values->values[ix]; - Py_XINCREF(value); - values->values[ix] = value; + values->values[ix] = Py_XNewRef(value); if (old_value == NULL) { if (value == NULL) { PyErr_Format(PyExc_AttributeError, @@ -5488,6 +5479,37 @@ _PyObject_StoreInstanceAttribute(PyObject *obj, PyDictValues *values, return 0; } +/* Sanity check for managed dicts */ +#if 0 +#define CHECK(val) assert(val); if (!(val)) { return 0; } + +int +_PyObject_ManagedDictValidityCheck(PyObject *obj) +{ + PyTypeObject *tp = Py_TYPE(obj); + CHECK(tp->tp_flags & Py_TPFLAGS_MANAGED_DICT); + PyDictOrValues *dorv_ptr = _PyObject_DictOrValuesPointer(obj); + if (_PyDictOrValues_IsValues(*dorv_ptr)) { + PyDictValues *values = _PyDictOrValues_GetValues(*dorv_ptr); + int size = ((uint8_t *)values)[-2]; + int count = 0; + PyDictKeysObject *keys = CACHED_KEYS(tp); + for (Py_ssize_t i = 0; i < keys->dk_nentries; i++) { + if (values->values[i] != NULL) { + count++; + } + } + CHECK(size == count); + } + else { + if (dorv_ptr->dict != NULL) { + CHECK(PyDict_Check(dorv_ptr->dict)); + } + } + return 1; +} +#endif + PyObject * _PyObject_GetInstanceAttribute(PyObject *obj, PyDictValues *values, PyObject *name) @@ -5500,8 +5522,7 @@ _PyObject_GetInstanceAttribute(PyObject *obj, PyDictValues *values, return NULL; } PyObject *value = values->values[ix]; - Py_XINCREF(value); - return value; + return Py_XNewRef(value); } int @@ -5511,105 +5532,124 @@ _PyObject_IsInstanceDictEmpty(PyObject *obj) if (tp->tp_dictoffset == 0) { return 1; } - PyObject **dictptr; + PyObject *dict; if (tp->tp_flags & Py_TPFLAGS_MANAGED_DICT) { - PyDictValues *values = *_PyObject_ValuesPointer(obj); - if (values) { + PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(obj); + if (_PyDictOrValues_IsValues(dorv)) { PyDictKeysObject *keys = CACHED_KEYS(tp); for (Py_ssize_t i = 0; i < keys->dk_nentries; i++) { - if (values->values[i] != NULL) { + if (_PyDictOrValues_GetValues(dorv)->values[i] != NULL) { return 0; } } return 1; } - dictptr = _PyObject_ManagedDictPointer(obj); + dict = _PyDictOrValues_GetDict(dorv); } else { - dictptr = _PyObject_DictPointer(obj); + PyObject **dictptr = _PyObject_ComputedDictPointer(obj); + dict = *dictptr; } - PyObject *dict = *dictptr; if (dict == NULL) { return 1; } return ((PyDictObject *)dict)->ma_used == 0; } - -int -_PyObject_VisitInstanceAttributes(PyObject *self, visitproc visit, void *arg) +void +_PyObject_FreeInstanceAttributes(PyObject *self) { PyTypeObject *tp = Py_TYPE(self); assert(Py_TYPE(self)->tp_flags & Py_TPFLAGS_MANAGED_DICT); - PyDictValues **values_ptr = _PyObject_ValuesPointer(self); - if (*values_ptr == NULL) { - return 0; + PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(self); + if (!_PyDictOrValues_IsValues(dorv)) { + return; } + PyDictValues *values = _PyDictOrValues_GetValues(dorv); PyDictKeysObject *keys = CACHED_KEYS(tp); for (Py_ssize_t i = 0; i < keys->dk_nentries; i++) { - Py_VISIT((*values_ptr)->values[i]); + Py_XDECREF(values->values[i]); } - return 0; + free_values(values); } -void -_PyObject_ClearInstanceAttributes(PyObject *self) +int +_PyObject_VisitManagedDict(PyObject *obj, visitproc visit, void *arg) { - PyTypeObject *tp = Py_TYPE(self); - assert(Py_TYPE(self)->tp_flags & Py_TPFLAGS_MANAGED_DICT); - PyDictValues **values_ptr = _PyObject_ValuesPointer(self); - if (*values_ptr == NULL) { - return; + PyTypeObject *tp = Py_TYPE(obj); + if((tp->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0) { + return 0; } - PyDictKeysObject *keys = CACHED_KEYS(tp); - for (Py_ssize_t i = 0; i < keys->dk_nentries; i++) { - Py_CLEAR((*values_ptr)->values[i]); + assert(tp->tp_dictoffset); + PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(obj); + if (_PyDictOrValues_IsValues(dorv)) { + PyDictValues *values = _PyDictOrValues_GetValues(dorv); + PyDictKeysObject *keys = CACHED_KEYS(tp); + for (Py_ssize_t i = 0; i < keys->dk_nentries; i++) { + Py_VISIT(values->values[i]); + } } + else { + PyObject *dict = _PyDictOrValues_GetDict(dorv); + Py_VISIT(dict); + } + return 0; } void -_PyObject_FreeInstanceAttributes(PyObject *self) +_PyObject_ClearManagedDict(PyObject *obj) { - PyTypeObject *tp = Py_TYPE(self); - assert(Py_TYPE(self)->tp_flags & Py_TPFLAGS_MANAGED_DICT); - PyDictValues **values_ptr = _PyObject_ValuesPointer(self); - PyDictValues *values = *values_ptr; - if (values == NULL) { + PyTypeObject *tp = Py_TYPE(obj); + if((tp->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0) { return; } - *values_ptr = NULL; - PyDictKeysObject *keys = CACHED_KEYS(tp); - for (Py_ssize_t i = 0; i < keys->dk_nentries; i++) { - Py_XDECREF(values->values[i]); + PyDictOrValues *dorv_ptr = _PyObject_DictOrValuesPointer(obj); + if (_PyDictOrValues_IsValues(*dorv_ptr)) { + PyDictValues *values = _PyDictOrValues_GetValues(*dorv_ptr); + PyDictKeysObject *keys = CACHED_KEYS(tp); + for (Py_ssize_t i = 0; i < keys->dk_nentries; i++) { + Py_CLEAR(values->values[i]); + } + dorv_ptr->dict = NULL; + free_values(values); + } + else { + PyObject *dict = dorv_ptr->dict; + if (dict) { + dorv_ptr->dict = NULL; + Py_DECREF(dict); + } } - free_values(values); } PyObject * PyObject_GenericGetDict(PyObject *obj, void *context) { PyObject *dict; + PyInterpreterState *interp = _PyInterpreterState_GET(); PyTypeObject *tp = Py_TYPE(obj); if (_PyType_HasFeature(tp, Py_TPFLAGS_MANAGED_DICT)) { - PyDictValues **values_ptr = _PyObject_ValuesPointer(obj); - PyObject **dictptr = _PyObject_ManagedDictPointer(obj); - if (*values_ptr) { - assert(*dictptr == NULL); + PyDictOrValues *dorv_ptr = _PyObject_DictOrValuesPointer(obj); + if (_PyDictOrValues_IsValues(*dorv_ptr)) { + PyDictValues *values = _PyDictOrValues_GetValues(*dorv_ptr); OBJECT_STAT_INC(dict_materialized_on_request); - *dictptr = dict = make_dict_from_instance_attributes(CACHED_KEYS(tp), *values_ptr); + dict = make_dict_from_instance_attributes( + interp, CACHED_KEYS(tp), values); if (dict != NULL) { - *values_ptr = NULL; + dorv_ptr->dict = dict; } } - else if (*dictptr == NULL) { - *dictptr = dict = PyDict_New(); - } else { - dict = *dictptr; + dict = _PyDictOrValues_GetDict(*dorv_ptr); + if (dict == NULL) { + dictkeys_incref(CACHED_KEYS(tp)); + dict = new_dict_with_shared_keys(interp, CACHED_KEYS(tp)); + dorv_ptr->dict = dict; + } } } else { - PyObject **dictptr = _PyObject_DictPointer(obj); + PyObject **dictptr = _PyObject_ComputedDictPointer(obj); if (dictptr == NULL) { PyErr_SetString(PyExc_AttributeError, "This object has no __dict__"); @@ -5620,15 +5660,15 @@ PyObject_GenericGetDict(PyObject *obj, void *context) PyTypeObject *tp = Py_TYPE(obj); if (_PyType_HasFeature(tp, Py_TPFLAGS_HEAPTYPE) && CACHED_KEYS(tp)) { dictkeys_incref(CACHED_KEYS(tp)); - *dictptr = dict = new_dict_with_shared_keys(CACHED_KEYS(tp)); + *dictptr = dict = new_dict_with_shared_keys( + interp, CACHED_KEYS(tp)); } else { *dictptr = dict = PyDict_New(); } } } - Py_XINCREF(dict); - return dict; + return Py_XNewRef(dict); } int @@ -5638,6 +5678,7 @@ _PyObjectDict_SetItem(PyTypeObject *tp, PyObject **dictptr, PyObject *dict; int res; PyDictKeysObject *cached; + PyInterpreterState *interp = _PyInterpreterState_GET(); assert(dictptr != NULL); if ((tp->tp_flags & Py_TPFLAGS_HEAPTYPE) && (cached = CACHED_KEYS(tp))) { @@ -5645,7 +5686,7 @@ _PyObjectDict_SetItem(PyTypeObject *tp, PyObject **dictptr, dict = *dictptr; if (dict == NULL) { dictkeys_incref(cached); - dict = new_dict_with_shared_keys(cached); + dict = new_dict_with_shared_keys(interp, cached); if (dict == NULL) return -1; *dictptr = dict; @@ -5677,20 +5718,133 @@ _PyObjectDict_SetItem(PyTypeObject *tp, PyObject **dictptr, void _PyDictKeys_DecRef(PyDictKeysObject *keys) { - dictkeys_decref(keys); + PyInterpreterState *interp = _PyInterpreterState_GET(); + dictkeys_decref(interp, keys); } -static uint32_t next_dict_keys_version = 2; - -uint32_t _PyDictKeys_GetVersionForCurrentState(PyDictKeysObject *dictkeys) +uint32_t _PyDictKeys_GetVersionForCurrentState(PyInterpreterState *interp, + PyDictKeysObject *dictkeys) { if (dictkeys->dk_version != 0) { return dictkeys->dk_version; } - if (next_dict_keys_version == 0) { + if (interp->dict_state.next_keys_version == 0) { return 0; } - uint32_t v = next_dict_keys_version++; + uint32_t v = interp->dict_state.next_keys_version++; dictkeys->dk_version = v; return v; } + +static inline int +validate_watcher_id(PyInterpreterState *interp, int watcher_id) +{ + if (watcher_id < 0 || watcher_id >= DICT_MAX_WATCHERS) { + PyErr_Format(PyExc_ValueError, "Invalid dict watcher ID %d", watcher_id); + return -1; + } + if (!interp->dict_state.watchers[watcher_id]) { + PyErr_Format(PyExc_ValueError, "No dict watcher set for ID %d", watcher_id); + return -1; + } + return 0; +} + +int +PyDict_Watch(int watcher_id, PyObject* dict) +{ + if (!PyDict_Check(dict)) { + PyErr_SetString(PyExc_ValueError, "Cannot watch non-dictionary"); + return -1; + } + PyInterpreterState *interp = _PyInterpreterState_GET(); + if (validate_watcher_id(interp, watcher_id)) { + return -1; + } + ((PyDictObject*)dict)->ma_version_tag |= (1LL << watcher_id); + return 0; +} + +int +PyDict_Unwatch(int watcher_id, PyObject* dict) +{ + if (!PyDict_Check(dict)) { + PyErr_SetString(PyExc_ValueError, "Cannot watch non-dictionary"); + return -1; + } + PyInterpreterState *interp = _PyInterpreterState_GET(); + if (validate_watcher_id(interp, watcher_id)) { + return -1; + } + ((PyDictObject*)dict)->ma_version_tag &= ~(1LL << watcher_id); + return 0; +} + +int +PyDict_AddWatcher(PyDict_WatchCallback callback) +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + + for (int i = 0; i < DICT_MAX_WATCHERS; i++) { + if (!interp->dict_state.watchers[i]) { + interp->dict_state.watchers[i] = callback; + return i; + } + } + + PyErr_SetString(PyExc_RuntimeError, "no more dict watcher IDs available"); + return -1; +} + +int +PyDict_ClearWatcher(int watcher_id) +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + if (validate_watcher_id(interp, watcher_id)) { + return -1; + } + interp->dict_state.watchers[watcher_id] = NULL; + return 0; +} + +static const char * +dict_event_name(PyDict_WatchEvent event) { + switch (event) { + #define CASE(op) \ + case PyDict_EVENT_##op: \ + return "PyDict_EVENT_" #op; + PY_FOREACH_DICT_EVENT(CASE) + #undef CASE + } + Py_UNREACHABLE(); +} + +void +_PyDict_SendEvent(int watcher_bits, + PyDict_WatchEvent event, + PyDictObject *mp, + PyObject *key, + PyObject *value) +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + for (int i = 0; i < DICT_MAX_WATCHERS; i++) { + if (watcher_bits & 1) { + PyDict_WatchCallback cb = interp->dict_state.watchers[i]; + if (cb && (cb(event, (PyObject*)mp, key, value) < 0)) { + // We don't want to resurrect the dict by potentially having an + // unraisablehook keep a reference to it, so we don't pass the + // dict as context, just an informative string message. Dict + // repr can call arbitrary code, so we invent a simpler version. + PyObject *context = PyUnicode_FromFormat( + "%s watcher callback for <dict at %p>", + dict_event_name(event), mp); + if (context == NULL) { + context = Py_NewRef(Py_None); + } + PyErr_WriteUnraisable(context); + Py_DECREF(context); + } + } + watcher_bits >>= 1; + } +} diff --git a/Objects/enumobject.c b/Objects/enumobject.c index d84bac6f..c9d90584 100644 --- a/Objects/enumobject.c +++ b/Objects/enumobject.c @@ -389,8 +389,7 @@ reversed_new_impl(PyTypeObject *type, PyObject *seq) return NULL; ro->index = n-1; - Py_INCREF(seq); - ro->seq = seq; + ro->seq = Py_NewRef(seq); return (PyObject *)ro; } diff --git a/Objects/exceptions.c b/Objects/exceptions.c index 4fba9b0a..f376ff24 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -8,6 +8,7 @@ #include <Python.h> #include <stdbool.h> #include "pycore_ceval.h" // _Py_EnterRecursiveCall +#include "pycore_pyerrors.h" // struct _PyErr_SetRaisedException #include "pycore_exceptions.h" // struct _Py_exc_state #include "pycore_initconfig.h" #include "pycore_object.h" @@ -53,8 +54,7 @@ BaseException_new(PyTypeObject *type, PyObject *args, PyObject *kwds) self->suppress_context = 0; if (args) { - self->args = args; - Py_INCREF(args); + self->args = Py_NewRef(args); return (PyObject *)self; } @@ -73,9 +73,7 @@ BaseException_init(PyBaseExceptionObject *self, PyObject *args, PyObject *kwds) if (!_PyArg_NoKeywords(Py_TYPE(self)->tp_name, kwds)) return -1; - Py_INCREF(args); - Py_XSETREF(self->args, args); - + Py_XSETREF(self->args, Py_NewRef(args)); return 0; } @@ -185,8 +183,7 @@ BaseException_with_traceback(PyObject *self, PyObject *tb) { if (PyException_SetTraceback(self, tb)) return NULL; - Py_INCREF(self); - return self; + return Py_NewRef(self); } PyDoc_STRVAR(with_traceback_doc, @@ -210,22 +207,21 @@ BaseException_add_note(PyObject *self, PyObject *note) return NULL; } - if (!PyObject_HasAttr(self, &_Py_ID(__notes__))) { - PyObject *new_notes = PyList_New(0); - if (new_notes == NULL) { + PyObject *notes; + if (_PyObject_LookupAttr(self, &_Py_ID(__notes__), ¬es) < 0) { + return NULL; + } + if (notes == NULL) { + notes = PyList_New(0); + if (notes == NULL) { return NULL; } - if (PyObject_SetAttr(self, &_Py_ID(__notes__), new_notes) < 0) { - Py_DECREF(new_notes); + if (PyObject_SetAttr(self, &_Py_ID(__notes__), notes) < 0) { + Py_DECREF(notes); return NULL; } - Py_DECREF(new_notes); } - PyObject *notes = PyObject_GetAttr(self, &_Py_ID(__notes__)); - if (notes == NULL) { - return NULL; - } - if (!PyList_Check(notes)) { + else if (!PyList_Check(notes)) { Py_DECREF(notes); PyErr_SetString(PyExc_TypeError, "Cannot add note: __notes__ is not a list"); return NULL; @@ -258,8 +254,7 @@ BaseException_get_args(PyBaseExceptionObject *self, void *Py_UNUSED(ignored)) if (self->args == NULL) { Py_RETURN_NONE; } - Py_INCREF(self->args); - return self->args; + return Py_NewRef(self->args); } static int @@ -283,8 +278,7 @@ BaseException_get_tb(PyBaseExceptionObject *self, void *Py_UNUSED(ignored)) if (self->traceback == NULL) { Py_RETURN_NONE; } - Py_INCREF(self->traceback); - return self->traceback; + return Py_NewRef(self->traceback); } static int @@ -294,14 +288,17 @@ BaseException_set_tb(PyBaseExceptionObject *self, PyObject *tb, void *Py_UNUSED( PyErr_SetString(PyExc_TypeError, "__traceback__ may not be deleted"); return -1; } - else if (!(tb == Py_None || PyTraceBack_Check(tb))) { + if (PyTraceBack_Check(tb)) { + Py_XSETREF(self->traceback, Py_NewRef(tb)); + } + else if (tb == Py_None) { + Py_CLEAR(self->traceback); + } + else { PyErr_SetString(PyExc_TypeError, "__traceback__ must be a traceback or None"); return -1; } - - Py_INCREF(tb); - Py_XSETREF(self->traceback, tb); return 0; } @@ -380,8 +377,7 @@ PyObject * PyException_GetTraceback(PyObject *self) { PyBaseExceptionObject *base_self = _PyBaseExceptionObject_cast(self); - Py_XINCREF(base_self->traceback); - return base_self->traceback; + return Py_XNewRef(base_self->traceback); } @@ -395,8 +391,7 @@ PyObject * PyException_GetCause(PyObject *self) { PyObject *cause = _PyBaseExceptionObject_cast(self)->cause; - Py_XINCREF(cause); - return cause; + return Py_XNewRef(cause); } /* Steals a reference to cause */ @@ -412,8 +407,7 @@ PyObject * PyException_GetContext(PyObject *self) { PyObject *context = _PyBaseExceptionObject_cast(self)->context; - Py_XINCREF(context); - return context; + return Py_XNewRef(context); } /* Steals a reference to context */ @@ -423,6 +417,20 @@ PyException_SetContext(PyObject *self, PyObject *context) Py_XSETREF(_PyBaseExceptionObject_cast(self)->context, context); } +PyObject * +PyException_GetArgs(PyObject *self) +{ + PyObject *args = _PyBaseExceptionObject_cast(self)->args; + return Py_NewRef(args); +} + +void +PyException_SetArgs(PyObject *self, PyObject *args) +{ + Py_INCREF(args); + Py_XSETREF(_PyBaseExceptionObject_cast(self)->args, args); +} + const char * PyExceptionClass_Name(PyObject *ob) { @@ -579,8 +587,7 @@ StopIteration_init(PyStopIterationObject *self, PyObject *args, PyObject *kwds) value = PyTuple_GET_ITEM(args, 0); else value = Py_None; - Py_INCREF(value); - self->value = value; + self->value = Py_NewRef(value); return 0; } @@ -606,17 +613,9 @@ StopIteration_traverse(PyStopIterationObject *self, visitproc visit, void *arg) return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg); } -ComplexExtendsException( - PyExc_Exception, /* base */ - StopIteration, /* name */ - StopIteration, /* prefix for *_init, etc */ - 0, /* new */ - 0, /* methods */ - StopIteration_members, /* members */ - 0, /* getset */ - 0, /* str */ - "Signal the end from iterator.__next__()." -); +ComplexExtendsException(PyExc_Exception, StopIteration, StopIteration, + 0, 0, StopIteration_members, 0, 0, + "Signal the end from iterator.__next__()."); /* @@ -641,12 +640,10 @@ SystemExit_init(PySystemExitObject *self, PyObject *args, PyObject *kwds) if (size == 0) return 0; if (size == 1) { - Py_INCREF(PyTuple_GET_ITEM(args, 0)); - Py_XSETREF(self->code, PyTuple_GET_ITEM(args, 0)); + Py_XSETREF(self->code, Py_NewRef(PyTuple_GET_ITEM(args, 0))); } else { /* size > 1 */ - Py_INCREF(args); - Py_XSETREF(self->code, args); + Py_XSETREF(self->code, Py_NewRef(args)); } return 0; } @@ -943,11 +940,11 @@ exceptiongroup_subset( PyException_SetContext(eg, PyException_GetContext(orig)); PyException_SetCause(eg, PyException_GetCause(orig)); - if (PyObject_HasAttr(orig, &_Py_ID(__notes__))) { - PyObject *notes = PyObject_GetAttr(orig, &_Py_ID(__notes__)); - if (notes == NULL) { - goto error; - } + PyObject *notes; + if (_PyObject_LookupAttr(orig, &_Py_ID(__notes__), ¬es) < 0) { + goto error; + } + if (notes) { if (PySequence_Check(notes)) { /* Make a copy so the parts have independent notes lists. */ PyObject *notes_copy = PySequence_List(notes); @@ -1353,7 +1350,10 @@ is_same_exception_metadata(PyObject *exc1, PyObject *exc2) PyObject * _PyExc_PrepReraiseStar(PyObject *orig, PyObject *excs) { + /* orig must be a raised & caught exception, so it has a traceback */ assert(PyExceptionInstance_Check(orig)); + assert(_PyBaseExceptionObject_cast(orig)->traceback != NULL); + assert(PyList_Check(excs)); Py_ssize_t numexcs = PyList_GET_SIZE(excs); @@ -1423,7 +1423,12 @@ _PyExc_PrepReraiseStar(PyObject *orig, PyObject *excs) if (res < 0) { goto done; } - result = _PyExc_CreateExceptionGroup("", raised_list); + if (PyList_GET_SIZE(raised_list) > 1) { + result = _PyExc_CreateExceptionGroup("", raised_list); + } + else { + result = Py_NewRef(PyList_GetItem(raised_list, 0)); + } if (result == NULL) { goto done; } @@ -1435,6 +1440,42 @@ done: return result; } +PyObject * +PyUnstable_Exc_PrepReraiseStar(PyObject *orig, PyObject *excs) +{ + if (orig == NULL || !PyExceptionInstance_Check(orig)) { + PyErr_SetString(PyExc_TypeError, "orig must be an exception instance"); + return NULL; + } + if (excs == NULL || !PyList_Check(excs)) { + PyErr_SetString(PyExc_TypeError, + "excs must be a list of exception instances"); + return NULL; + } + Py_ssize_t numexcs = PyList_GET_SIZE(excs); + for (Py_ssize_t i = 0; i < numexcs; i++) { + PyObject *exc = PyList_GET_ITEM(excs, i); + if (exc == NULL || !(PyExceptionInstance_Check(exc) || Py_IsNone(exc))) { + PyErr_Format(PyExc_TypeError, + "item %d of excs is not an exception", i); + return NULL; + } + } + + /* Make sure that orig has something as traceback, in the interpreter + * it always does becuase it's a raised exception. + */ + PyObject *tb = PyException_GetTraceback(orig); + + if (tb == NULL) { + PyErr_Format(PyExc_ValueError, "orig must be a raised exception"); + return NULL; + } + Py_DECREF(tb); + + return _PyExc_PrepReraiseStar(orig, excs); +} + static PyMemberDef BaseExceptionGroup_members[] = { {"message", T_OBJECT, offsetof(PyBaseExceptionGroupObject, msg), READONLY, PyDoc_STR("exception message")}, @@ -1493,11 +1534,12 @@ SimpleExtendsException(PyExc_BaseException, KeyboardInterrupt, static int ImportError_init(PyImportErrorObject *self, PyObject *args, PyObject *kwds) { - static char *kwlist[] = {"name", "path", 0}; + static char *kwlist[] = {"name", "path", "name_from", 0}; PyObject *empty_tuple; PyObject *msg = NULL; PyObject *name = NULL; PyObject *path = NULL; + PyObject *name_from = NULL; if (BaseException_init((PyBaseExceptionObject *)self, args, NULL) == -1) return -1; @@ -1505,22 +1547,19 @@ ImportError_init(PyImportErrorObject *self, PyObject *args, PyObject *kwds) empty_tuple = PyTuple_New(0); if (!empty_tuple) return -1; - if (!PyArg_ParseTupleAndKeywords(empty_tuple, kwds, "|$OO:ImportError", kwlist, - &name, &path)) { + if (!PyArg_ParseTupleAndKeywords(empty_tuple, kwds, "|$OOO:ImportError", kwlist, + &name, &path, &name_from)) { Py_DECREF(empty_tuple); return -1; } Py_DECREF(empty_tuple); - Py_XINCREF(name); - Py_XSETREF(self->name, name); - - Py_XINCREF(path); - Py_XSETREF(self->path, path); + Py_XSETREF(self->name, Py_XNewRef(name)); + Py_XSETREF(self->path, Py_XNewRef(path)); + Py_XSETREF(self->name_from, Py_XNewRef(name_from)); if (PyTuple_GET_SIZE(args) == 1) { - msg = PyTuple_GET_ITEM(args, 0); - Py_INCREF(msg); + msg = Py_NewRef(PyTuple_GET_ITEM(args, 0)); } Py_XSETREF(self->msg, msg); @@ -1533,6 +1572,7 @@ ImportError_clear(PyImportErrorObject *self) Py_CLEAR(self->msg); Py_CLEAR(self->name); Py_CLEAR(self->path); + Py_CLEAR(self->name_from); return BaseException_clear((PyBaseExceptionObject *)self); } @@ -1550,6 +1590,7 @@ ImportError_traverse(PyImportErrorObject *self, visitproc visit, void *arg) Py_VISIT(self->msg); Py_VISIT(self->name); Py_VISIT(self->path); + Py_VISIT(self->name_from); return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg); } @@ -1557,8 +1598,7 @@ static PyObject * ImportError_str(PyImportErrorObject *self) { if (self->msg && PyUnicode_CheckExact(self->msg)) { - Py_INCREF(self->msg); - return self->msg; + return Py_NewRef(self->msg); } else { return BaseException_str((PyBaseExceptionObject *)self); @@ -1569,7 +1609,7 @@ static PyObject * ImportError_getstate(PyImportErrorObject *self) { PyObject *dict = ((PyBaseExceptionObject *)self)->dict; - if (self->name || self->path) { + if (self->name || self->path || self->name_from) { dict = dict ? PyDict_Copy(dict) : PyDict_New(); if (dict == NULL) return NULL; @@ -1581,11 +1621,14 @@ ImportError_getstate(PyImportErrorObject *self) Py_DECREF(dict); return NULL; } + if (self->name_from && PyDict_SetItem(dict, &_Py_ID(name_from), self->name_from) < 0) { + Py_DECREF(dict); + return NULL; + } return dict; } else if (dict) { - Py_INCREF(dict); - return dict; + return Py_NewRef(dict); } else { Py_RETURN_NONE; @@ -1617,6 +1660,8 @@ static PyMemberDef ImportError_members[] = { PyDoc_STR("module name")}, {"path", T_OBJECT, offsetof(PyImportErrorObject, path), 0, PyDoc_STR("module path")}, + {"name_from", T_OBJECT, offsetof(PyImportErrorObject, name_from), 0, + PyDoc_STR("name imported from module")}, {NULL} /* Sentinel */ }; @@ -1710,8 +1755,7 @@ oserror_parse_args(PyObject **p_args, PyTuple_SET_ITEM(newargs, 0, *myerrno); for (i = 1; i < nargs; i++) { PyObject *val = PyTuple_GET_ITEM(args, i); - Py_INCREF(val); - PyTuple_SET_ITEM(newargs, i, val); + PyTuple_SET_ITEM(newargs, i, Py_NewRef(val)); } Py_DECREF(args); args = *p_args = newargs; @@ -1746,12 +1790,10 @@ oserror_init(PyOSErrorObject *self, PyObject **p_args, return -1; } else { - Py_INCREF(filename); - self->filename = filename; + self->filename = Py_NewRef(filename); if (filename2 && filename2 != Py_None) { - Py_INCREF(filename2); - self->filename2 = filename2; + self->filename2 = Py_NewRef(filename2); } if (nargs >= 2 && nargs <= 5) { @@ -1766,15 +1808,10 @@ oserror_init(PyOSErrorObject *self, PyObject **p_args, } } } - Py_XINCREF(myerrno); - self->myerrno = myerrno; - - Py_XINCREF(strerror); - self->strerror = strerror; - + self->myerrno = Py_XNewRef(myerrno); + self->strerror = Py_XNewRef(strerror); #ifdef MS_WINDOWS - Py_XINCREF(winerror); - self->winerror = winerror; + self->winerror = Py_XNewRef(winerror); #endif /* Steals the reference to args */ @@ -2000,7 +2037,7 @@ static PyObject * OSError_reduce(PyOSErrorObject *self, PyObject *Py_UNUSED(ignored)) { PyObject *args = self->args; - PyObject *res = NULL, *tmp; + PyObject *res = NULL; /* self->args is only the first two real arguments if there was a * file name given to OSError. */ @@ -2010,16 +2047,9 @@ OSError_reduce(PyOSErrorObject *self, PyObject *Py_UNUSED(ignored)) if (!args) return NULL; - tmp = PyTuple_GET_ITEM(self->args, 0); - Py_INCREF(tmp); - PyTuple_SET_ITEM(args, 0, tmp); - - tmp = PyTuple_GET_ITEM(self->args, 1); - Py_INCREF(tmp); - PyTuple_SET_ITEM(args, 1, tmp); - - Py_INCREF(self->filename); - PyTuple_SET_ITEM(args, 2, self->filename); + PyTuple_SET_ITEM(args, 0, Py_NewRef(PyTuple_GET_ITEM(self->args, 0))); + PyTuple_SET_ITEM(args, 1, Py_NewRef(PyTuple_GET_ITEM(self->args, 1))); + PyTuple_SET_ITEM(args, 2, Py_NewRef(self->filename)); if (self->filename2) { /* @@ -2027,12 +2057,10 @@ OSError_reduce(PyOSErrorObject *self, PyObject *Py_UNUSED(ignored)) * So, to recreate filename2, we need to pass in * winerror as well. */ - Py_INCREF(Py_None); - PyTuple_SET_ITEM(args, 3, Py_None); + PyTuple_SET_ITEM(args, 3, Py_NewRef(Py_None)); /* filename2 */ - Py_INCREF(self->filename2); - PyTuple_SET_ITEM(args, 4, self->filename2); + PyTuple_SET_ITEM(args, 4, Py_NewRef(self->filename2)); } } else Py_INCREF(args); @@ -2193,8 +2221,7 @@ NameError_init(PyNameErrorObject *self, PyObject *args, PyObject *kwds) } Py_DECREF(empty_tuple); - Py_XINCREF(name); - Py_XSETREF(self->name, name); + Py_XSETREF(self->name, Py_XNewRef(name)); return 0; } @@ -2268,11 +2295,8 @@ AttributeError_init(PyAttributeErrorObject *self, PyObject *args, PyObject *kwds } Py_DECREF(empty_tuple); - Py_XINCREF(name); - Py_XSETREF(self->name, name); - - Py_XINCREF(obj); - Py_XSETREF(self->obj, obj); + Py_XSETREF(self->name, Py_XNewRef(name)); + Py_XSETREF(self->obj, Py_XNewRef(obj)); return 0; } @@ -2301,6 +2325,48 @@ AttributeError_traverse(PyAttributeErrorObject *self, visitproc visit, void *arg return BaseException_traverse((PyBaseExceptionObject *)self, visit, arg); } +/* Pickling support */ +static PyObject * +AttributeError_getstate(PyAttributeErrorObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject *dict = ((PyAttributeErrorObject *)self)->dict; + if (self->name || self->args) { + dict = dict ? PyDict_Copy(dict) : PyDict_New(); + if (dict == NULL) { + return NULL; + } + if (self->name && PyDict_SetItemString(dict, "name", self->name) < 0) { + Py_DECREF(dict); + return NULL; + } + /* We specifically are not pickling the obj attribute since there are many + cases where it is unlikely to be picklable. See GH-103352. + */ + if (self->args && PyDict_SetItemString(dict, "args", self->args) < 0) { + Py_DECREF(dict); + return NULL; + } + return dict; + } + else if (dict) { + return Py_NewRef(dict); + } + Py_RETURN_NONE; +} + +static PyObject * +AttributeError_reduce(PyAttributeErrorObject *self, PyObject *Py_UNUSED(ignored)) +{ + PyObject *state = AttributeError_getstate(self, NULL); + if (state == NULL) { + return NULL; + } + + PyObject *return_value = PyTuple_Pack(3, Py_TYPE(self), self->args, state); + Py_DECREF(state); + return return_value; +} + static PyMemberDef AttributeError_members[] = { {"name", T_OBJECT, offsetof(PyAttributeErrorObject, name), 0, PyDoc_STR("attribute name")}, {"obj", T_OBJECT, offsetof(PyAttributeErrorObject, obj), 0, PyDoc_STR("object")}, @@ -2308,7 +2374,9 @@ static PyMemberDef AttributeError_members[] = { }; static PyMethodDef AttributeError_methods[] = { - {NULL} /* Sentinel */ + {"__getstate__", (PyCFunction)AttributeError_getstate, METH_NOARGS}, + {"__reduce__", (PyCFunction)AttributeError_reduce, METH_NOARGS }, + {NULL} }; ComplexExtendsException(PyExc_Exception, AttributeError, @@ -2330,8 +2398,7 @@ SyntaxError_init(PySyntaxErrorObject *self, PyObject *args, PyObject *kwds) return -1; if (lenargs >= 1) { - Py_INCREF(PyTuple_GET_ITEM(args, 0)); - Py_XSETREF(self->msg, PyTuple_GET_ITEM(args, 0)); + Py_XSETREF(self->msg, Py_NewRef(PyTuple_GET_ITEM(args, 0))); } if (lenargs == 2) { info = PyTuple_GET_ITEM(args, 1); @@ -2427,8 +2494,7 @@ my_basename(PyObject *name) return PyUnicode_Substring(name, offset, size); } else { - Py_INCREF(name); - return name; + return Py_NewRef(name); } } @@ -2580,8 +2646,7 @@ get_string(PyObject *attr, const char *name) PyErr_Format(PyExc_TypeError, "%.200s attribute must be bytes", name); return NULL; } - Py_INCREF(attr); - return attr; + return Py_NewRef(attr); } static PyObject * @@ -2597,8 +2662,7 @@ get_unicode(PyObject *attr, const char *name) "%.200s attribute must be unicode", name); return NULL; } - Py_INCREF(attr); - return attr; + return Py_NewRef(attr); } static int @@ -3231,19 +3295,18 @@ SimpleExtendsException(PyExc_Exception, ReferenceError, #define MEMERRORS_SAVE 16 static PyObject * -MemoryError_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +get_memory_error(int allow_allocation, PyObject *args, PyObject *kwds) { PyBaseExceptionObject *self; - - /* If this is a subclass of MemoryError, don't use the freelist - * and just return a fresh object */ - if (type != (PyTypeObject *) PyExc_MemoryError) { - return BaseException_new(type, args, kwds); - } - struct _Py_exc_state *state = get_exc_state(); if (state->memerrors_freelist == NULL) { - return BaseException_new(type, args, kwds); + if (!allow_allocation) { + PyInterpreterState *interp = _PyInterpreterState_GET(); + return Py_NewRef( + &_Py_INTERP_SINGLETON(interp, last_resort_memory_error)); + } + PyObject *result = BaseException_new((PyTypeObject *)PyExc_MemoryError, args, kwds); + return result; } /* Fetch object from freelist and revive it */ @@ -3263,6 +3326,33 @@ MemoryError_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return (PyObject *)self; } +static PyObject * +MemoryError_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + /* If this is a subclass of MemoryError, don't use the freelist + * and just return a fresh object */ + if (type != (PyTypeObject *) PyExc_MemoryError) { + return BaseException_new(type, args, kwds); + } + return get_memory_error(1, args, kwds); +} + +PyObject * +_PyErr_NoMemory(PyThreadState *tstate) +{ + if (Py_IS_TYPE(PyExc_MemoryError, NULL)) { + /* PyErr_NoMemory() has been called before PyExc_MemoryError has been + initialized by _PyExc_Init() */ + Py_FatalError("Out of memory and PyExc_MemoryError is not " + "initialized yet"); + } + PyObject *err = get_memory_error(0, NULL, NULL); + if (err != NULL) { + _PyErr_SetRaisedException(tstate, err); + } + return NULL; +} + static void MemoryError_dealloc(PyBaseExceptionObject *self) { @@ -3294,6 +3384,7 @@ preallocate_memerrors(void) /* We create enough MemoryErrors and then decref them, which will fill up the freelist. */ int i; + PyObject *errors[MEMERRORS_SAVE]; for (i = 0; i < MEMERRORS_SAVE; i++) { errors[i] = MemoryError_new((PyTypeObject *) PyExc_MemoryError, @@ -3319,7 +3410,7 @@ free_preallocated_memerrors(struct _Py_exc_state *state) } -static PyTypeObject _PyExc_MemoryError = { +PyTypeObject _PyExc_MemoryError = { PyVarObject_HEAD_INIT(NULL, 0) "MemoryError", sizeof(PyBaseExceptionObject), @@ -3587,14 +3678,9 @@ static struct static_exception static_exceptions[] = { int _PyExc_InitTypes(PyInterpreterState *interp) { - if (!_Py_IsMainInterpreter(interp)) { - return 0; - } - for (size_t i=0; i < Py_ARRAY_LENGTH(static_exceptions); i++) { PyTypeObject *exc = static_exceptions[i].exc; - - if (PyType_Ready(exc) < 0) { + if (_PyStaticType_InitBuiltin(interp, exc) < 0) { return -1; } } @@ -3605,13 +3691,9 @@ _PyExc_InitTypes(PyInterpreterState *interp) static void _PyExc_FiniTypes(PyInterpreterState *interp) { - if (!_Py_IsMainInterpreter(interp)) { - return; - } - for (Py_ssize_t i=Py_ARRAY_LENGTH(static_exceptions) - 1; i >= 0; i--) { PyTypeObject *exc = static_exceptions[i].exc; - _PyStaticType_Dealloc(exc); + _PyStaticType_Dealloc(interp, exc); } } @@ -3746,130 +3828,18 @@ _PyExc_Fini(PyInterpreterState *interp) _PyExc_FiniTypes(interp); } -/* Helper to do the equivalent of "raise X from Y" in C, but always using - * the current exception rather than passing one in. - * - * We currently limit this to *only* exceptions that use the BaseException - * tp_init and tp_new methods, since we can be reasonably sure we can wrap - * those correctly without losing data and without losing backwards - * compatibility. - * - * We also aim to rule out *all* exceptions that might be storing additional - * state, whether by having a size difference relative to BaseException, - * additional arguments passed in during construction or by having a - * non-empty instance dict. - * - * We need to be very careful with what we wrap, since changing types to - * a broader exception type would be backwards incompatible for - * existing codecs, and with different init or new method implementations - * may either not support instantiation with PyErr_Format or lose - * information when instantiated that way. - * - * XXX (ncoghlan): This could be made more comprehensive by exploiting the - * fact that exceptions are expected to support pickling. If more builtin - * exceptions (e.g. AttributeError) start to be converted to rich - * exceptions with additional attributes, that's probably a better approach - * to pursue over adding special cases for particular stateful subclasses. - * - * Returns a borrowed reference to the new exception (if any), NULL if the - * existing exception was left in place. - */ -PyObject * -_PyErr_TrySetFromCause(const char *format, ...) -{ - PyObject* msg_prefix; - PyObject *exc, *val, *tb; - PyTypeObject *caught_type; - PyObject *instance_args; - Py_ssize_t num_args, caught_type_size, base_exc_size; - PyObject *new_exc, *new_val, *new_tb; - va_list vargs; - int same_basic_size; - - PyErr_Fetch(&exc, &val, &tb); - caught_type = (PyTypeObject *)exc; - /* Ensure type info indicates no extra state is stored at the C level - * and that the type can be reinstantiated using PyErr_Format - */ - caught_type_size = caught_type->tp_basicsize; - base_exc_size = _PyExc_BaseException.tp_basicsize; - same_basic_size = ( - caught_type_size == base_exc_size || - (_PyType_SUPPORTS_WEAKREFS(caught_type) && - (caught_type_size == base_exc_size + (Py_ssize_t)sizeof(PyObject *)) - ) - ); - if (caught_type->tp_init != (initproc)BaseException_init || - caught_type->tp_new != BaseException_new || - !same_basic_size || - caught_type->tp_itemsize != _PyExc_BaseException.tp_itemsize) { - /* We can't be sure we can wrap this safely, since it may contain - * more state than just the exception type. Accordingly, we just - * leave it alone. - */ - PyErr_Restore(exc, val, tb); - return NULL; - } - - /* Check the args are empty or contain a single string */ - PyErr_NormalizeException(&exc, &val, &tb); - instance_args = ((PyBaseExceptionObject *)val)->args; - num_args = PyTuple_GET_SIZE(instance_args); - if (num_args > 1 || - (num_args == 1 && - !PyUnicode_CheckExact(PyTuple_GET_ITEM(instance_args, 0)))) { - /* More than 1 arg, or the one arg we do have isn't a string - */ - PyErr_Restore(exc, val, tb); - return NULL; - } - - /* Ensure the instance dict is also empty */ - if (!_PyObject_IsInstanceDictEmpty(val)) { - /* While we could potentially copy a non-empty instance dictionary - * to the replacement exception, for now we take the more - * conservative path of leaving exceptions with attributes set - * alone. - */ - PyErr_Restore(exc, val, tb); - return NULL; - } - - /* For exceptions that we can wrap safely, we chain the original - * exception to a new one of the exact same type with an - * error message that mentions the additional details and the - * original exception. - * - * It would be nice to wrap OSError and various other exception - * types as well, but that's quite a bit trickier due to the extra - * state potentially stored on OSError instances. - */ - /* Ensure the traceback is set correctly on the existing exception */ - if (tb != NULL) { - PyException_SetTraceback(val, tb); - Py_DECREF(tb); - } - -#ifdef HAVE_STDARG_PROTOTYPES - va_start(vargs, format); -#else - va_start(vargs); -#endif - msg_prefix = PyUnicode_FromFormatV(format, vargs); - va_end(vargs); - if (msg_prefix == NULL) { - Py_DECREF(exc); - Py_DECREF(val); - return NULL; +int +_PyException_AddNote(PyObject *exc, PyObject *note) +{ + if (!PyExceptionInstance_Check(exc)) { + PyErr_Format(PyExc_TypeError, + "exc must be an exception, not '%s'", + Py_TYPE(exc)->tp_name); + return -1; } - - PyErr_Format(exc, "%U (%s: %S)", - msg_prefix, Py_TYPE(val)->tp_name, val); - Py_DECREF(exc); - Py_DECREF(msg_prefix); - PyErr_Fetch(&new_exc, &new_val, &new_tb); - PyErr_NormalizeException(&new_exc, &new_val, &new_tb); - PyException_SetCause(new_val, val); - PyErr_Restore(new_exc, new_val, new_tb); - return new_val; + PyObject *r = BaseException_add_note(exc, note); + int res = r == NULL ? -1 : 0; + Py_XDECREF(r); + return res; } + diff --git a/Objects/fileobject.c b/Objects/fileobject.c index 8dba5b9a..e99e155f 100644 --- a/Objects/fileobject.c +++ b/Objects/fileobject.c @@ -32,16 +32,16 @@ PyObject * PyFile_FromFd(int fd, const char *name, const char *mode, int buffering, const char *encoding, const char *errors, const char *newline, int closefd) { - PyObject *io, *stream; + PyObject *open, *stream; /* import _io in case we are being used to open io.py */ - io = PyImport_ImportModule("_io"); - if (io == NULL) + open = _PyImport_GetModuleAttrString("_io", "open"); + if (open == NULL) return NULL; - stream = _PyObject_CallMethod(io, &_Py_ID(open), "isisssO", fd, mode, + stream = PyObject_CallFunction(open, "isisssO", fd, mode, buffering, encoding, errors, newline, closefd ? Py_True : Py_False); - Py_DECREF(io); + Py_DECREF(open); if (stream == NULL) return NULL; /* ignore name attribute because the name attribute of _BufferedIOMixin @@ -67,8 +67,7 @@ PyFile_GetLine(PyObject *f, int n) } if (result != NULL && !PyBytes_Check(result) && !PyUnicode_Check(result)) { - Py_DECREF(result); - result = NULL; + Py_SETREF(result, NULL); PyErr_SetString(PyExc_TypeError, "object.readline() returned non-string"); } @@ -77,8 +76,7 @@ PyFile_GetLine(PyObject *f, int n) const char *s = PyBytes_AS_STRING(result); Py_ssize_t len = PyBytes_GET_SIZE(result); if (len == 0) { - Py_DECREF(result); - result = NULL; + Py_SETREF(result, NULL); PyErr_SetString(PyExc_EOFError, "EOF when reading a line"); } @@ -88,24 +86,21 @@ PyFile_GetLine(PyObject *f, int n) else { PyObject *v; v = PyBytes_FromStringAndSize(s, len-1); - Py_DECREF(result); - result = v; + Py_SETREF(result, v); } } } if (n < 0 && result != NULL && PyUnicode_Check(result)) { Py_ssize_t len = PyUnicode_GET_LENGTH(result); if (len == 0) { - Py_DECREF(result); - result = NULL; + Py_SETREF(result, NULL); PyErr_SetString(PyExc_EOFError, "EOF when reading a line"); } else if (PyUnicode_READ_CHAR(result, len-1) == '\n') { PyObject *v; v = PyUnicode_Substring(result, 0, len-1); - Py_DECREF(result); - result = v; + Py_SETREF(result, v); } } return result; @@ -230,16 +225,8 @@ _PyLong_FileDescriptor_Converter(PyObject *o, void *ptr) return 1; } -/* -** Py_UniversalNewlineFgets is an fgets variation that understands -** all of \r, \n and \r\n conventions. -** The stream should be opened in binary mode. -** The fobj parameter exists solely for legacy reasons and must be NULL. -** Note that we need no error handling: fgets() treats error and eof -** identically. -*/ char * -Py_UniversalNewlineFgets(char *buf, int n, FILE *stream, PyObject *fobj) +_Py_UniversalNewlineFgetsWithSize(char *buf, int n, FILE *stream, PyObject *fobj, size_t* size) { char *p = buf; int c; @@ -265,11 +252,28 @@ Py_UniversalNewlineFgets(char *buf, int n, FILE *stream, PyObject *fobj) } FUNLOCKFILE(stream); *p = '\0'; - if (p == buf) + if (p == buf) { return NULL; + } + *size = p - buf; return buf; } +/* +** Py_UniversalNewlineFgets is an fgets variation that understands +** all of \r, \n and \r\n conventions. +** The stream should be opened in binary mode. +** The fobj parameter exists solely for legacy reasons and must be NULL. +** Note that we need no error handling: fgets() treats error and eof +** identically. +*/ + +char * +Py_UniversalNewlineFgets(char *buf, int n, FILE *stream, PyObject *fobj) { + size_t size; + return _Py_UniversalNewlineFgetsWithSize(buf, n, stream, fobj, &size); +} + /* **************************** std printer **************************** * The stdprinter is used during the boot strapping phase as a preliminary * file like object for sys.stderr. @@ -490,7 +494,7 @@ PyFile_SetOpenCodeHook(Py_OpenCodeHookFunction hook, void *userData) { PyObject * PyFile_OpenCodeObject(PyObject *path) { - PyObject *iomod, *f = NULL; + PyObject *f = NULL; if (!PyUnicode_Check(path)) { PyErr_Format(PyExc_TypeError, "'path' must be 'str', not '%.200s'", @@ -502,10 +506,10 @@ PyFile_OpenCodeObject(PyObject *path) if (hook) { f = hook(path, _PyRuntime.open_code_userdata); } else { - iomod = PyImport_ImportModule("_io"); - if (iomod) { - f = _PyObject_CallMethod(iomod, &_Py_ID(open), "Os", path, "rb"); - Py_DECREF(iomod); + PyObject *open = _PyImport_GetModuleAttrString("_io", "open"); + if (open) { + f = PyObject_CallFunction(open, "Os", path, "rb"); + Py_DECREF(open); } } diff --git a/Objects/floatobject.c b/Objects/floatobject.c index be602465..83a263c0 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -12,7 +12,7 @@ #include "pycore_object.h" // _PyObject_Init() #include "pycore_pymath.h" // _PY_SHORT_FLOAT_REPR #include "pycore_pystate.h" // _PyInterpreterState_GET() -#include "pycore_structseq.h" // _PyStructSequence_FiniType() +#include "pycore_structseq.h" // _PyStructSequence_FiniBuiltin() #include <ctype.h> #include <float.h> @@ -371,8 +371,7 @@ convert_to_double(PyObject **v, double *dbl) } } else { - Py_INCREF(Py_NotImplemented); - *v = Py_NotImplemented; + *v = Py_NewRef(Py_NotImplemented); return -1; } return 0; @@ -532,20 +531,17 @@ float_richcompare(PyObject *v, PyObject *w, int op) temp = _PyLong_Lshift(ww, 1); if (temp == NULL) goto Error; - Py_DECREF(ww); - ww = temp; + Py_SETREF(ww, temp); temp = _PyLong_Lshift(vv, 1); if (temp == NULL) goto Error; - Py_DECREF(vv); - vv = temp; + Py_SETREF(vv, temp); temp = PyNumber_Or(vv, _PyLong_GetOne()); if (temp == NULL) goto Error; - Py_DECREF(vv); - vv = temp; + Py_SETREF(vv, temp); } r = PyObject_RichCompareBool(vv, ww, op); @@ -904,8 +900,7 @@ float_is_integer_impl(PyObject *self) PyExc_ValueError); return NULL; } - Py_INCREF(o); - return o; + return Py_NewRef(o); } /*[clinic input] @@ -1124,11 +1119,12 @@ float___round___impl(PyObject *self, PyObject *o_ndigits) static PyObject * float_float(PyObject *v) { - if (PyFloat_CheckExact(v)) - Py_INCREF(v); - else - v = PyFloat_FromDouble(((PyFloatObject *)v)->ob_fval); - return v; + if (PyFloat_CheckExact(v)) { + return Py_NewRef(v); + } + else { + return PyFloat_FromDouble(((PyFloatObject *)v)->ob_fval); + } } /*[clinic input] @@ -1550,12 +1546,10 @@ float_fromhex(PyTypeObject *type, PyObject *string) /*[clinic input] float.as_integer_ratio -Return integer ratio. +Return a pair of integers, whose ratio is exactly equal to the original float. -Return a pair of integers, whose ratio is exactly equal to the original float -and with a positive denominator. - -Raise OverflowError on infinities and a ValueError on NaNs. +The ratio is in lowest terms and has a positive denominator. Raise +OverflowError on infinities and a ValueError on NaNs. >>> (10.0).as_integer_ratio() (10, 1) @@ -1567,7 +1561,7 @@ Raise OverflowError on infinities and a ValueError on NaNs. static PyObject * float_as_integer_ratio_impl(PyObject *self) -/*[clinic end generated code: output=65f25f0d8d30a712 input=e21d08b4630c2e44]*/ +/*[clinic end generated code: output=65f25f0d8d30a712 input=d5ba7765655d75bd]*/ { double self_double; double float_part; @@ -1724,12 +1718,14 @@ float___getnewargs___impl(PyObject *self) } /* this is for the benefit of the pack/unpack routines below */ +typedef enum _py_float_format_type float_format_type; +#define unknown_format _py_float_format_unknown +#define ieee_big_endian_format _py_float_format_ieee_big_endian +#define ieee_little_endian_format _py_float_format_ieee_little_endian -typedef enum { - unknown_format, ieee_big_endian_format, ieee_little_endian_format -} float_format_type; +#define float_format (_PyRuntime.float_state.float_format) +#define double_format (_PyRuntime.float_state.double_format) -static float_format_type double_format, float_format; /*[clinic input] @classmethod @@ -1930,13 +1926,9 @@ PyTypeObject PyFloat_Type = { .tp_vectorcall = (vectorcallfunc)float_vectorcall, }; -void -_PyFloat_InitState(PyInterpreterState *interp) +static void +_init_global_state(void) { - if (!_Py_IsMainInterpreter(interp)) { - return; - } - float_format_type detected_double_format, detected_float_format; /* We attempt to determine if this machine is using IEEE @@ -1986,22 +1978,23 @@ _PyFloat_InitState(PyInterpreterState *interp) float_format = detected_float_format; } -PyStatus -_PyFloat_InitTypes(PyInterpreterState *interp) +void +_PyFloat_InitState(PyInterpreterState *interp) { if (!_Py_IsMainInterpreter(interp)) { - return _PyStatus_OK(); - } - - if (PyType_Ready(&PyFloat_Type) < 0) { - return _PyStatus_ERR("Can't initialize float type"); + return; } + _init_global_state(); +} +PyStatus +_PyFloat_InitTypes(PyInterpreterState *interp) +{ /* Init float info */ - if (FloatInfoType.tp_name == NULL) { - if (PyStructSequence_InitType2(&FloatInfoType, &floatinfo_desc) < 0) { - return _PyStatus_ERR("can't init float info type"); - } + if (_PyStructSequence_InitBuiltin(interp, &FloatInfoType, + &floatinfo_desc) < 0) + { + return _PyStatus_ERR("can't init float info type"); } return _PyStatus_OK(); @@ -2036,9 +2029,7 @@ _PyFloat_Fini(PyInterpreterState *interp) void _PyFloat_FiniType(PyInterpreterState *interp) { - if (_Py_IsMainInterpreter(interp)) { - _PyStructSequence_FiniType(&FloatInfoType); - } + _PyStructSequence_FiniBuiltin(interp, &FloatInfoType); } /* Print summary info about the state of the optimized allocator */ @@ -2433,25 +2424,14 @@ PyFloat_Unpack2(const char *data, int le) f |= *p; if (e == 0x1f) { -#if _PY_SHORT_FLOAT_REPR == 0 if (f == 0) { /* Infinity */ return sign ? -Py_HUGE_VAL : Py_HUGE_VAL; } else { /* NaN */ - return sign ? -Py_NAN : Py_NAN; - } -#else // _PY_SHORT_FLOAT_REPR == 1 - if (f == 0) { - /* Infinity */ - return _Py_dg_infinity(sign); - } - else { - /* NaN */ - return _Py_dg_stdnan(sign); + return sign ? -fabs(Py_NAN) : fabs(Py_NAN); } -#endif // _PY_SHORT_FLOAT_REPR == 1 } x = (double)f / 1024.0; diff --git a/Objects/frame_layout.md b/Objects/frame_layout.md index 11688f68..2f95214d 100644 --- a/Objects/frame_layout.md +++ b/Objects/frame_layout.md @@ -9,10 +9,10 @@ results in poor locality of reference. In 3.11, rather than have these frames scattered about memory, as happens for heap-allocated objects, frames are allocated -contiguously in a per-thread stack. +contiguously in a per-thread stack. This improves performance significantly for two reasons: * It reduces allocation overhead to a pointer comparison and increment. -* Stack allocated data has the best possible locality and will always be in +* Stack allocated data has the best possible locality and will always be in CPU cache. Generator and coroutines still need heap allocated activation records, but @@ -63,7 +63,7 @@ We may implement this in the future. > In a contiguous stack, we would need to save one fewer registers, as the > top of the caller's activation record would be the same at the base of the -> callee's. However, since some activation records are kept on the heap we +> callee's. However, since some activation records are kept on the heap we > cannot do this. ### Generators and Coroutines @@ -85,7 +85,7 @@ and builtins, than strong references to both globals and builtins. ### Frame objects When creating a backtrace or when calling `sys._getframe()` the frame becomes -visible to Python code. When this happens a new `PyFrameObject` is created +visible to Python code. When this happens a new `PyFrameObject` is created and a strong reference to it placed in the `frame_obj` field of the specials section. The `frame_obj` field is initially `NULL`. @@ -104,7 +104,7 @@ Generator objects have a `_PyInterpreterFrame` embedded in them. This means that creating a generator requires only a single allocation, reducing allocation overhead and improving locality of reference. The embedded frame is linked into the per-thread frame when iterated or -awaited. +awaited. If a frame object associated with a generator outlives the generator, then the embedded `_PyInterpreterFrame` is copied into the frame object. @@ -119,4 +119,14 @@ Thus, some of the field names may be a bit misleading. For example the `f_globals` field has a `f_` prefix implying it belongs to the `PyFrameObject` struct, although it belongs to the `_PyInterpreterFrame` struct. -We may rationalize this naming scheme for 3.12. \ No newline at end of file +We may rationalize this naming scheme for 3.12. + + +### Shim frames + +On entry to `_PyEval_EvalFrameDefault()` a shim `_PyInterpreterFrame` is pushed. +This frame is stored on the C stack, and popped when `_PyEval_EvalFrameDefault()` +returns. This extra frame is inserted so that `RETURN_VALUE`, `YIELD_VALUE`, and +`RETURN_GENERATOR` do not need to check whether the current frame is the entry frame. +The shim frame points to a special code object containing the `INTERPRETER_EXIT` +instruction which cleans up the shim frame and returns. diff --git a/Objects/frameobject.c b/Objects/frameobject.c index 1e6bdcfb..30c8d3c5 100644 --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -17,7 +17,6 @@ static PyMemberDef frame_memberlist[] = { {"f_trace_lines", T_BOOL, OFF(f_trace_lines), 0}, - {"f_trace_opcodes", T_BOOL, OFF(f_trace_opcodes), 0}, {NULL} /* Sentinel */ }; @@ -25,10 +24,15 @@ static PyMemberDef frame_memberlist[] = { static PyObject * frame_getlocals(PyFrameObject *f, void *closure) { - if (PyFrame_FastToLocalsWithError(f) < 0) + if (f == NULL) { + PyErr_BadInternalCall(); return NULL; - PyObject *locals = f->f_frame->f_locals; - Py_INCREF(locals); + } + assert(!_PyFrame_IsIncomplete(f->f_frame)); + PyObject *locals = _PyFrame_GetLocals(f->f_frame, 1); + if (locals) { + f->f_fast_as_locals = 1; + } return locals; } @@ -40,7 +44,7 @@ PyFrame_GetLineNumber(PyFrameObject *f) return f->f_lineno; } else { - return _PyInterpreterFrame_GetLine(f->f_frame); + return PyUnstable_InterpreterFrame_GetLine(f->f_frame); } } @@ -73,8 +77,7 @@ frame_getglobals(PyFrameObject *f, void *closure) if (globals == NULL) { globals = Py_None; } - Py_INCREF(globals); - return globals; + return Py_NewRef(globals); } static PyObject * @@ -84,8 +87,7 @@ frame_getbuiltins(PyFrameObject *f, void *closure) if (builtins == NULL) { builtins = Py_None; } - Py_INCREF(builtins); - return builtins; + return Py_NewRef(builtins); } static PyObject * @@ -107,24 +109,29 @@ frame_getback(PyFrameObject *f, void *closure) return res; } -// Given the index of the effective opcode, scan back to construct the oparg -// with EXTENDED_ARG. This only works correctly with *unquickened* code, -// obtained via a call to _PyCode_GetCode! -static unsigned int -get_arg(const _Py_CODEUNIT *codestr, Py_ssize_t i) +static PyObject * +frame_gettrace_opcodes(PyFrameObject *f, void *closure) { - _Py_CODEUNIT word; - unsigned int oparg = _Py_OPARG(codestr[i]); - if (i >= 1 && _Py_OPCODE(word = codestr[i-1]) == EXTENDED_ARG) { - oparg |= _Py_OPARG(word) << 8; - if (i >= 2 && _Py_OPCODE(word = codestr[i-2]) == EXTENDED_ARG) { - oparg |= _Py_OPARG(word) << 16; - if (i >= 3 && _Py_OPCODE(word = codestr[i-3]) == EXTENDED_ARG) { - oparg |= _Py_OPARG(word) << 24; - } - } + PyObject *result = f->f_trace_opcodes ? Py_True : Py_False; + return Py_NewRef(result); +} + +static int +frame_settrace_opcodes(PyFrameObject *f, PyObject* value, void *Py_UNUSED(ignored)) +{ + if (!PyBool_Check(value)) { + PyErr_SetString(PyExc_TypeError, + "attribute value type must be bool"); + return -1; + } + if (value == Py_True) { + f->f_trace_opcodes = 1; + _PyInterpreterState_GET()->f_opcode_trace_set = true; + } + else { + f->f_trace_opcodes = 0; } - return oparg; + return 0; } /* Model the evaluation stack, to determine which jumps @@ -302,69 +309,52 @@ mark_stacks(PyCodeObject *code_obj, int len) while (todo) { todo = 0; /* Scan instructions */ - for (i = 0; i < len; i++) { + for (i = 0; i < len;) { int64_t next_stack = stacks[i]; + opcode = _Py_GetBaseOpcode(code_obj, i); + int oparg = 0; + while (opcode == EXTENDED_ARG) { + oparg = (oparg << 8) | code[i].op.arg; + i++; + opcode = _Py_GetBaseOpcode(code_obj, i); + stacks[i] = next_stack; + } + int next_i = i + _PyOpcode_Caches[opcode] + 1; if (next_stack == UNINITIALIZED) { + i = next_i; continue; } - opcode = _Py_OPCODE(code[i]); + oparg = (oparg << 8) | code[i].op.arg; switch (opcode) { - case JUMP_IF_FALSE_OR_POP: - case JUMP_IF_TRUE_OR_POP: - case POP_JUMP_FORWARD_IF_FALSE: - case POP_JUMP_BACKWARD_IF_FALSE: - case POP_JUMP_FORWARD_IF_TRUE: - case POP_JUMP_BACKWARD_IF_TRUE: + case POP_JUMP_IF_FALSE: + case POP_JUMP_IF_TRUE: { int64_t target_stack; - int j = get_arg(code, i); - if (opcode == POP_JUMP_FORWARD_IF_FALSE || - opcode == POP_JUMP_FORWARD_IF_TRUE || - opcode == JUMP_IF_FALSE_OR_POP || - opcode == JUMP_IF_TRUE_OR_POP) - { - j += i + 1; - } - else { - assert(opcode == POP_JUMP_BACKWARD_IF_FALSE || - opcode == POP_JUMP_BACKWARD_IF_TRUE); - j = i + 1 - j; - } + int j = next_i + oparg; assert(j < len); - if (stacks[j] == UNINITIALIZED && j < i) { - todo = 1; - } - if (opcode == JUMP_IF_FALSE_OR_POP || - opcode == JUMP_IF_TRUE_OR_POP) - { - target_stack = next_stack; - next_stack = pop_value(next_stack); - } - else { - next_stack = pop_value(next_stack); - target_stack = next_stack; - } + next_stack = pop_value(next_stack); + target_stack = next_stack; assert(stacks[j] == UNINITIALIZED || stacks[j] == target_stack); stacks[j] = target_stack; - stacks[i+1] = next_stack; + stacks[next_i] = next_stack; break; } case SEND: - j = get_arg(code, i) + i + 1; + j = oparg + i + INLINE_CACHE_ENTRIES_SEND + 1; assert(j < len); - assert(stacks[j] == UNINITIALIZED || stacks[j] == pop_value(next_stack)); - stacks[j] = pop_value(next_stack); - stacks[i+1] = next_stack; + assert(stacks[j] == UNINITIALIZED || stacks[j] == next_stack); + stacks[j] = next_stack; + stacks[next_i] = next_stack; break; case JUMP_FORWARD: - j = get_arg(code, i) + i + 1; + j = oparg + i + 1; assert(j < len); assert(stacks[j] == UNINITIALIZED || stacks[j] == next_stack); stacks[j] = next_stack; break; case JUMP_BACKWARD: case JUMP_BACKWARD_NO_INTERRUPT: - j = i + 1 - get_arg(code, i); + j = i + 1 - oparg; assert(j >= 0); assert(j < len); if (stacks[j] == UNINITIALIZED && j < i) { @@ -376,13 +366,13 @@ mark_stacks(PyCodeObject *code_obj, int len) case GET_ITER: case GET_AITER: next_stack = push_value(pop_value(next_stack), Iterator); - stacks[i+1] = next_stack; + stacks[next_i] = next_stack; break; case FOR_ITER: { - int64_t target_stack = pop_value(next_stack); - stacks[i+1] = push_value(next_stack, Object); - j = get_arg(code, i) + i + 1; + int64_t target_stack = push_value(next_stack, Object); + stacks[next_i] = target_stack; + j = oparg + 1 + INLINE_CACHE_ENTRIES_FOR_ITER + i; assert(j < len); assert(stacks[j] == UNINITIALIZED || stacks[j] == target_stack); stacks[j] = target_stack; @@ -390,21 +380,23 @@ mark_stacks(PyCodeObject *code_obj, int len) } case END_ASYNC_FOR: next_stack = pop_value(pop_value(next_stack)); - stacks[i+1] = next_stack; + stacks[next_i] = next_stack; break; case PUSH_EXC_INFO: next_stack = push_value(next_stack, Except); - stacks[i+1] = next_stack; + stacks[next_i] = next_stack; break; case POP_EXCEPT: assert(top_of_stack(next_stack) == Except); next_stack = pop_value(next_stack); - stacks[i+1] = next_stack; + stacks[next_i] = next_stack; break; case RETURN_VALUE: assert(pop_value(next_stack) == EMPTY_STACK); assert(top_of_stack(next_stack) == Object); break; + case RETURN_CONST: + break; case RAISE_VARARGS: break; case RERAISE: @@ -413,46 +405,62 @@ mark_stacks(PyCodeObject *code_obj, int len) break; case PUSH_NULL: next_stack = push_value(next_stack, Null); - stacks[i+1] = next_stack; + stacks[next_i] = next_stack; break; case LOAD_GLOBAL: - if (_Py_OPARG(code[i]) & 1) { + { + int j = oparg; + if (j & 1) { next_stack = push_value(next_stack, Null); } next_stack = push_value(next_stack, Object); - stacks[i+1] = next_stack; + stacks[next_i] = next_stack; break; - case LOAD_METHOD: + } + case LOAD_ATTR: + { assert(top_of_stack(next_stack) == Object); - next_stack = pop_value(next_stack); - next_stack = push_value(next_stack, Null); - next_stack = push_value(next_stack, Object); - stacks[i+1] = next_stack; + int j = oparg; + if (j & 1) { + next_stack = pop_value(next_stack); + next_stack = push_value(next_stack, Null); + next_stack = push_value(next_stack, Object); + } + stacks[next_i] = next_stack; break; + } case CALL: { - next_stack = pop_value(pop_value(next_stack)); + int args = oparg; + for (int j = 0; j < args+2; j++) { + next_stack = pop_value(next_stack); + } next_stack = push_value(next_stack, Object); - stacks[i+1] = next_stack; + stacks[next_i] = next_stack; break; } case SWAP: { - int n = get_arg(code, i); + int n = oparg; next_stack = stack_swap(next_stack, n); - stacks[i+1] = next_stack; + stacks[next_i] = next_stack; break; } case COPY: { - int n = get_arg(code, i); + int n = oparg; next_stack = push_value(next_stack, peek(next_stack, n)); - stacks[i+1] = next_stack; + stacks[next_i] = next_stack; break; } + case CACHE: + case RESERVED: + { + assert(0); + } default: { - int delta = PyCompile_OpcodeStackEffect(opcode, get_arg(code, i)); + int delta = PyCompile_OpcodeStackEffect(opcode, oparg); assert(delta != PY_INVALID_STACK_EFFECT); while (delta < 0) { next_stack = pop_value(next_stack); @@ -462,9 +470,10 @@ mark_stacks(PyCodeObject *code_obj, int len) next_stack = push_value(next_stack, Object); delta--; } - stacks[i+1] = next_stack; + stacks[next_i] = next_stack; } } + i = next_i; } /* Scan exception table */ unsigned char *start = (unsigned char *)PyBytes_AS_STRING(code_obj->co_exceptiontable); @@ -605,7 +614,7 @@ _PyFrame_GetState(PyFrameObject *frame) if (_PyInterpreterFrame_LASTI(frame->f_frame) < 0) { return FRAME_CREATED; } - switch (_PyOpcode_Deopt[_Py_OPCODE(*frame->f_frame->prev_instr)]) + switch (frame->f_frame->prev_instr->op.code) { case COPY_FREE_VARS: case MAKE_CELL: @@ -622,7 +631,6 @@ _PyFrame_GetState(PyFrameObject *frame) Py_UNREACHABLE(); } - /* Setter for f_lineno - you can set f_lineno from within a trace function in * order to jump to a given line of code, subject to some restrictions. Most * lines are OK to jump to because they don't make any assumptions about the @@ -660,31 +668,43 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno, void *Py_UNUSED(ignore * In addition, jumps are forbidden when not tracing, * as this is a debugging feature. */ - switch(PyThreadState_GET()->tracing_what) { - case PyTrace_EXCEPTION: - PyErr_SetString(PyExc_ValueError, - "can only jump from a 'line' trace event"); - return -1; - case PyTrace_CALL: + int what_event = PyThreadState_GET()->what_event; + if (what_event < 0) { + PyErr_Format(PyExc_ValueError, + "f_lineno can only be set in a trace function"); + return -1; + } + switch (what_event) { + case PY_MONITORING_EVENT_PY_RESUME: + case PY_MONITORING_EVENT_JUMP: + case PY_MONITORING_EVENT_BRANCH: + case PY_MONITORING_EVENT_LINE: + case PY_MONITORING_EVENT_PY_YIELD: + /* Setting f_lineno is allowed for the above events */ + break; + case PY_MONITORING_EVENT_PY_START: PyErr_Format(PyExc_ValueError, "can't jump from the 'call' trace event of a new frame"); return -1; - case PyTrace_LINE: - break; - case PyTrace_RETURN: - if (state == FRAME_SUSPENDED) { - break; - } - /* fall through */ - default: + case PY_MONITORING_EVENT_CALL: + case PY_MONITORING_EVENT_C_RETURN: PyErr_SetString(PyExc_ValueError, + "can't jump during a call"); + return -1; + case PY_MONITORING_EVENT_PY_RETURN: + case PY_MONITORING_EVENT_PY_UNWIND: + case PY_MONITORING_EVENT_PY_THROW: + case PY_MONITORING_EVENT_RAISE: + case PY_MONITORING_EVENT_C_RAISE: + case PY_MONITORING_EVENT_INSTRUCTION: + case PY_MONITORING_EVENT_EXCEPTION_HANDLED: + PyErr_Format(PyExc_ValueError, "can only jump from a 'line' trace event"); return -1; - } - if (!f->f_trace) { - PyErr_Format(PyExc_ValueError, - "f_lineno can only be set by a trace function"); - return -1; + default: + PyErr_SetString(PyExc_SystemError, + "unexpected event type"); + return -1; } int new_lineno; @@ -770,6 +790,31 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno, void *Py_UNUSED(ignore PyErr_SetString(PyExc_ValueError, msg); return -1; } + // Populate any NULL locals that the compiler might have "proven" to exist + // in the new location. Rather than crashing or changing co_code, just bind + // None instead: + int unbound = 0; + for (int i = 0; i < f->f_frame->f_code->co_nlocalsplus; i++) { + // Counting every unbound local is overly-cautious, but a full flow + // analysis (like we do in the compiler) is probably too expensive: + unbound += f->f_frame->localsplus[i] == NULL; + } + if (unbound) { + const char *e = "assigning None to %d unbound local%s"; + const char *s = (unbound == 1) ? "" : "s"; + if (PyErr_WarnFormat(PyExc_RuntimeWarning, 0, e, unbound, s)) { + return -1; + } + // Do this in a second pass to avoid writing a bunch of Nones when + // warnings are being treated as errors and the previous bit raises: + for (int i = 0; i < f->f_frame->f_code->co_nlocalsplus; i++) { + if (f->f_frame->localsplus[i] == NULL) { + f->f_frame->localsplus[i] = Py_NewRef(Py_None); + unbound--; + } + } + assert(unbound == 0); + } if (state == FRAME_SUSPENDED) { /* Account for value popped by yield */ start_stack = pop_value(start_stack); @@ -801,13 +846,9 @@ static PyObject * frame_gettrace(PyFrameObject *f, void *closure) { PyObject* trace = f->f_trace; - if (trace == NULL) trace = Py_None; - - Py_INCREF(trace); - - return trace; + return Py_NewRef(trace); } static int @@ -816,9 +857,9 @@ frame_settrace(PyFrameObject *f, PyObject* v, void *closure) if (v == Py_None) { v = NULL; } - Py_XINCREF(v); - Py_XSETREF(f->f_trace, v); - + if (v != f->f_trace) { + Py_XSETREF(f->f_trace, Py_XNewRef(v)); + } return 0; } @@ -833,27 +874,16 @@ static PyGetSetDef frame_getsetlist[] = { {"f_globals", (getter)frame_getglobals, NULL, NULL}, {"f_builtins", (getter)frame_getbuiltins, NULL, NULL}, {"f_code", (getter)frame_getcode, NULL, NULL}, + {"f_trace_opcodes", (getter)frame_gettrace_opcodes, (setter)frame_settrace_opcodes, NULL}, {0} }; -/* Stack frames are allocated and deallocated at a considerable rate. - In an attempt to improve the speed of function calls, we maintain - a separate free list of stack frames (just like floats are - allocated in a special way -- see floatobject.c). When a stack - frame is on the free list, only the following members have a meaning: - ob_type == &Frametype - f_back next item on free list, or NULL -*/ - static void frame_dealloc(PyFrameObject *f) { /* It is the responsibility of the owning generator/coroutine * to have cleared the generator pointer */ - assert(f->f_frame->owner != FRAME_OWNED_BY_GENERATOR || - _PyFrame_GetGenerator(f->f_frame)->gi_frame_state == FRAME_CLEARED); - if (_PyObject_GC_IS_TRACKED(f)) { _PyObject_GC_UNTRACK(f); } @@ -861,14 +891,18 @@ frame_dealloc(PyFrameObject *f) Py_TRASHCAN_BEGIN(f, frame_dealloc); PyCodeObject *co = NULL; + /* GH-106092: If f->f_frame was on the stack and we reached the maximum + * nesting depth for deallocations, the trashcan may have delayed this + * deallocation until after f->f_frame is freed. Avoid dereferencing + * f->f_frame unless we know it still points to valid memory. */ + _PyInterpreterFrame *frame = (_PyInterpreterFrame *)f->_f_frame_data; + /* Kill all local variables including specials, if we own them */ - if (f->f_frame->owner == FRAME_OWNED_BY_FRAME_OBJECT) { - assert(f->f_frame == (_PyInterpreterFrame *)f->_f_frame_data); - _PyInterpreterFrame *frame = (_PyInterpreterFrame *)f->_f_frame_data; + if (f->f_frame == frame && frame->owner == FRAME_OWNED_BY_FRAME_OBJECT) { /* Don't clear code object until the end */ co = frame->f_code; frame->f_code = NULL; - Py_CLEAR(frame->f_func); + Py_CLEAR(frame->f_funcobj); Py_CLEAR(frame->f_locals); PyObject **locals = _PyFrame_GetLocalsArray(frame); for (int i = 0; i < frame->stacktop; i++) { @@ -942,7 +976,7 @@ frame_sizeof(PyFrameObject *f, PyObject *Py_UNUSED(ignored)) Py_ssize_t res; res = offsetof(PyFrameObject, _f_frame_data) + offsetof(_PyInterpreterFrame, localsplus); PyCodeObject *code = f->f_frame->f_code; - res += (code->co_nlocalsplus+code->co_stacksize) * sizeof(PyObject *); + res += _PyFrame_NumSlotsForCodeObject(code) * sizeof(PyObject *); return PyLong_FromSsize_t(res); } @@ -1006,14 +1040,10 @@ PyTypeObject PyFrame_Type = { static void init_frame(_PyInterpreterFrame *frame, PyFunctionObject *func, PyObject *locals) { - /* _PyFrame_InitializeSpecials consumes reference to func */ - Py_INCREF(func); PyCodeObject *code = (PyCodeObject *)func->func_code; - _PyFrame_InitializeSpecials(frame, func, locals, code->co_nlocalsplus); + _PyFrame_Initialize(frame, (PyFunctionObject*)Py_NewRef(func), + Py_XNewRef(locals), code, 0); frame->previous = NULL; - for (Py_ssize_t i = 0; i < code->co_nlocalsplus; i++) { - frame->localsplus[i] = NULL; - } } PyFrameObject* @@ -1082,8 +1112,8 @@ _PyFrame_OpAlreadyRan(_PyInterpreterFrame *frame, int opcode, int oparg) for (_Py_CODEUNIT *instruction = _PyCode_CODE(frame->f_code); instruction < frame->prev_instr; instruction++) { - int check_opcode = _PyOpcode_Deopt[_Py_OPCODE(*instruction)]; - check_oparg |= _Py_OPARG(*instruction); + int check_opcode = _PyOpcode_Deopt[instruction->op.code]; + check_oparg |= instruction->op.arg; if (check_opcode == opcode && check_oparg == oparg) { return 1; } @@ -1098,79 +1128,127 @@ _PyFrame_OpAlreadyRan(_PyInterpreterFrame *frame, int opcode, int oparg) return 0; } -int -_PyFrame_FastToLocalsWithError(_PyInterpreterFrame *frame) { + +// Initialize frame free variables if needed +static void +frame_init_get_vars(_PyInterpreterFrame *frame) +{ + // COPY_FREE_VARS has no quickened forms, so no need to use _PyOpcode_Deopt + // here: + PyCodeObject *co = frame->f_code; + int lasti = _PyInterpreterFrame_LASTI(frame); + if (!(lasti < 0 && _PyCode_CODE(co)->op.code == COPY_FREE_VARS + && PyFunction_Check(frame->f_funcobj))) + { + /* Free vars are initialized */ + return; + } + + /* Free vars have not been initialized -- Do that */ + PyObject *closure = ((PyFunctionObject *)frame->f_funcobj)->func_closure; + int offset = PyCode_GetFirstFree(co); + for (int i = 0; i < co->co_nfreevars; ++i) { + PyObject *o = PyTuple_GET_ITEM(closure, i); + frame->localsplus[offset + i] = Py_NewRef(o); + } + // COPY_FREE_VARS doesn't have inline CACHEs, either: + frame->prev_instr = _PyCode_CODE(frame->f_code); +} + + +static int +frame_get_var(_PyInterpreterFrame *frame, PyCodeObject *co, int i, + PyObject **pvalue) +{ + _PyLocals_Kind kind = _PyLocals_GetKind(co->co_localspluskinds, i); + + /* If the namespace is unoptimized, then one of the + following cases applies: + 1. It does not contain free variables, because it + uses import * or is a top-level namespace. + 2. It is a class namespace. + We don't want to accidentally copy free variables + into the locals dict used by the class. + */ + if (kind & CO_FAST_FREE && !(co->co_flags & CO_OPTIMIZED)) { + return 0; + } + + PyObject *value = frame->localsplus[i]; + if (frame->stacktop) { + if (kind & CO_FAST_FREE) { + // The cell was set by COPY_FREE_VARS. + assert(value != NULL && PyCell_Check(value)); + value = PyCell_GET(value); + } + else if (kind & CO_FAST_CELL) { + // Note that no *_DEREF ops can happen before MAKE_CELL + // executes. So there's no need to duplicate the work + // that MAKE_CELL would otherwise do later, if it hasn't + // run yet. + if (value != NULL) { + if (PyCell_Check(value) && + _PyFrame_OpAlreadyRan(frame, MAKE_CELL, i)) { + // (likely) MAKE_CELL must have executed already. + value = PyCell_GET(value); + } + // (likely) Otherwise it it is an arg (kind & CO_FAST_LOCAL), + // with the initial value set when the frame was created... + // (unlikely) ...or it was set to some initial value by + // an earlier call to PyFrame_LocalsToFast(). + } + } + } + else { + assert(value == NULL); + } + *pvalue = value; + return 1; +} + + +PyObject * +_PyFrame_GetLocals(_PyInterpreterFrame *frame, int include_hidden) +{ /* Merge fast locals into f->f_locals */ - PyObject *locals; - PyObject **fast; - PyCodeObject *co; - locals = frame->f_locals; + PyObject *locals = frame->f_locals; if (locals == NULL) { locals = frame->f_locals = PyDict_New(); - if (locals == NULL) - return -1; + if (locals == NULL) { + return NULL; + } } - co = frame->f_code; - fast = _PyFrame_GetLocalsArray(frame); - // COPY_FREE_VARS has no quickened forms, so no need to use _PyOpcode_Deopt - // here: - int lasti = _PyInterpreterFrame_LASTI(frame); - if (lasti < 0 && _Py_OPCODE(_PyCode_CODE(co)[0]) == COPY_FREE_VARS) { - /* Free vars have not been initialized -- Do that */ - PyCodeObject *co = frame->f_code; - PyObject *closure = frame->f_func->func_closure; - int offset = co->co_nlocals + co->co_nplaincellvars; - for (int i = 0; i < co->co_nfreevars; ++i) { - PyObject *o = PyTuple_GET_ITEM(closure, i); - Py_INCREF(o); - frame->localsplus[offset + i] = o; + PyObject *hidden = NULL; + + /* If include_hidden, "hidden" fast locals (from inlined comprehensions in + module/class scopes) will be included in the returned dict, but not in + frame->f_locals; the returned dict will be a modified copy. Non-hidden + locals will still be updated in frame->f_locals. */ + if (include_hidden) { + hidden = PyDict_New(); + if (hidden == NULL) { + return NULL; } - // COPY_FREE_VARS doesn't have inline CACHEs, either: - frame->prev_instr = _PyCode_CODE(frame->f_code); } - for (int i = 0; i < co->co_nlocalsplus; i++) { - _PyLocals_Kind kind = _PyLocals_GetKind(co->co_localspluskinds, i); - /* If the namespace is unoptimized, then one of the - following cases applies: - 1. It does not contain free variables, because it - uses import * or is a top-level namespace. - 2. It is a class namespace. - We don't want to accidentally copy free variables - into the locals dict used by the class. - */ - if (kind & CO_FAST_FREE && !(co->co_flags & CO_OPTIMIZED)) { + frame_init_get_vars(frame); + + PyCodeObject *co = frame->f_code; + for (int i = 0; i < co->co_nlocalsplus; i++) { + PyObject *value; // borrowed reference + if (!frame_get_var(frame, co, i, &value)) { continue; } PyObject *name = PyTuple_GET_ITEM(co->co_localsplusnames, i); - PyObject *value = fast[i]; - if (frame->stacktop) { - if (kind & CO_FAST_FREE) { - // The cell was set by COPY_FREE_VARS. - assert(value != NULL && PyCell_Check(value)); - value = PyCell_GET(value); - } - else if (kind & CO_FAST_CELL) { - // Note that no *_DEREF ops can happen before MAKE_CELL - // executes. So there's no need to duplicate the work - // that MAKE_CELL would otherwise do later, if it hasn't - // run yet. - if (value != NULL) { - if (PyCell_Check(value) && - _PyFrame_OpAlreadyRan(frame, MAKE_CELL, i)) { - // (likely) MAKE_CELL must have executed already. - value = PyCell_GET(value); - } - // (likely) Otherwise it it is an arg (kind & CO_FAST_LOCAL), - // with the initial value set when the frame was created... - // (unlikely) ...or it was set to some initial value by - // an earlier call to PyFrame_LocalsToFast(). + _PyLocals_Kind kind = _PyLocals_GetKind(co->co_localspluskinds, i); + if (kind & CO_FAST_HIDDEN) { + if (include_hidden && value != NULL) { + if (PyObject_SetItem(hidden, name, value) != 0) { + goto error; } } - } - else { - assert(value == NULL); + continue; } if (value == NULL) { if (PyObject_DelItem(locals, name) != 0) { @@ -1178,27 +1256,112 @@ _PyFrame_FastToLocalsWithError(_PyInterpreterFrame *frame) { PyErr_Clear(); } else { - return -1; + goto error; } } } else { if (PyObject_SetItem(locals, name, value) != 0) { - return -1; + goto error; } } } + + if (include_hidden && PyDict_Size(hidden)) { + PyObject *innerlocals = PyDict_New(); + if (innerlocals == NULL) { + goto error; + } + if (PyDict_Merge(innerlocals, locals, 1) != 0) { + Py_DECREF(innerlocals); + goto error; + } + if (PyDict_Merge(innerlocals, hidden, 1) != 0) { + Py_DECREF(innerlocals); + goto error; + } + locals = innerlocals; + } + else { + Py_INCREF(locals); + } + Py_CLEAR(hidden); + + return locals; + + error: + Py_XDECREF(hidden); + return NULL; +} + + +int +_PyFrame_FastToLocalsWithError(_PyInterpreterFrame *frame) +{ + PyObject *locals = _PyFrame_GetLocals(frame, 0); + if (locals == NULL) { + return -1; + } + Py_DECREF(locals); return 0; } + +PyObject * +PyFrame_GetVar(PyFrameObject *frame_obj, PyObject *name) +{ + if (!PyUnicode_Check(name)) { + PyErr_Format(PyExc_TypeError, "name must be str, not %s", + Py_TYPE(name)->tp_name); + return NULL; + } + + _PyInterpreterFrame *frame = frame_obj->f_frame; + frame_init_get_vars(frame); + + PyCodeObject *co = frame->f_code; + for (int i = 0; i < co->co_nlocalsplus; i++) { + PyObject *var_name = PyTuple_GET_ITEM(co->co_localsplusnames, i); + if (!_PyUnicode_Equal(var_name, name)) { + continue; + } + + PyObject *value; // borrowed reference + if (!frame_get_var(frame, co, i, &value)) { + break; + } + if (value == NULL) { + break; + } + return Py_NewRef(value); + } + + PyErr_Format(PyExc_NameError, "variable %R does not exist", name); + return NULL; +} + + +PyObject * +PyFrame_GetVarString(PyFrameObject *frame, const char *name) +{ + PyObject *name_obj = PyUnicode_FromString(name); + if (name_obj == NULL) { + return NULL; + } + PyObject *value = PyFrame_GetVar(frame, name_obj); + Py_DECREF(name_obj); + return value; +} + + int PyFrame_FastToLocalsWithError(PyFrameObject *f) { - assert(!_PyFrame_IsIncomplete(f->f_frame)); if (f == NULL) { PyErr_BadInternalCall(); return -1; } + assert(!_PyFrame_IsIncomplete(f->f_frame)); int err = _PyFrame_FastToLocalsWithError(f->f_frame); if (err == 0) { f->f_fast_as_locals = 1; @@ -1224,7 +1387,6 @@ _PyFrame_LocalsToFast(_PyInterpreterFrame *frame, int clear) /* Merge locals into fast locals */ PyObject *locals; PyObject **fast; - PyObject *error_type, *error_value, *error_traceback; PyCodeObject *co; locals = frame->f_locals; if (locals == NULL) { @@ -1233,7 +1395,7 @@ _PyFrame_LocalsToFast(_PyInterpreterFrame *frame, int clear) fast = _PyFrame_GetLocalsArray(frame); co = frame->f_code; - PyErr_Fetch(&error_type, &error_value, &error_traceback); + PyObject *exc = PyErr_GetRaisedException(); for (int i = 0; i < co->co_nlocalsplus; i++) { _PyLocals_Kind kind = _PyLocals_GetKind(co->co_localspluskinds, i); @@ -1271,18 +1433,26 @@ _PyFrame_LocalsToFast(_PyInterpreterFrame *frame, int clear) if (cell != NULL) { oldvalue = PyCell_GET(cell); if (value != oldvalue) { + PyCell_SET(cell, Py_XNewRef(value)); Py_XDECREF(oldvalue); - Py_XINCREF(value); - PyCell_SET(cell, value); } } else if (value != oldvalue) { - Py_XINCREF(value); - Py_XSETREF(fast[i], value); + if (value == NULL) { + // Probably can't delete this, since the compiler's flow + // analysis may have already "proven" that it exists here: + const char *e = "assigning None to unbound local %R"; + if (PyErr_WarnFormat(PyExc_RuntimeWarning, 0, e, name)) { + // It's okay if frame_obj is NULL, just try anyways: + PyErr_WriteUnraisable((PyObject *)frame->frame_obj); + } + value = Py_NewRef(Py_None); + } + Py_XSETREF(fast[i], Py_NewRef(value)); } Py_XDECREF(value); } - PyErr_Restore(error_type, error_value, error_traceback); + PyErr_SetRaisedException(exc); } void @@ -1295,15 +1465,15 @@ PyFrame_LocalsToFast(PyFrameObject *f, int clear) } } - -int _PyFrame_IsEntryFrame(PyFrameObject *frame) +int +_PyFrame_IsEntryFrame(PyFrameObject *frame) { assert(frame != NULL); - assert(!_PyFrame_IsIncomplete(frame->f_frame)); - return frame->f_frame->is_entry; + _PyInterpreterFrame *f = frame->f_frame; + assert(!_PyFrame_IsIncomplete(f)); + return f->previous && f->previous->owner == FRAME_OWNED_BY_CSTACK; } - PyCodeObject * PyFrame_GetCode(PyFrameObject *frame) { @@ -1311,8 +1481,7 @@ PyFrame_GetCode(PyFrameObject *frame) assert(!_PyFrame_IsIncomplete(frame->f_frame)); PyCodeObject *code = frame->f_frame->f_code; assert(code != NULL); - Py_INCREF(code); - return code; + return (PyCodeObject*)Py_NewRef(code); } @@ -1324,15 +1493,12 @@ PyFrame_GetBack(PyFrameObject *frame) PyFrameObject *back = frame->f_back; if (back == NULL) { _PyInterpreterFrame *prev = frame->f_frame->previous; - while (prev && _PyFrame_IsIncomplete(prev)) { - prev = prev->previous; - } + prev = _PyFrame_GetFirstComplete(prev); if (prev) { back = _PyFrame_GetFrameObject(prev); } } - Py_XINCREF(back); - return back; + return (PyFrameObject*)Py_XNewRef(back); } PyObject* @@ -1395,5 +1561,3 @@ _PyEval_BuiltinsFromGlobals(PyThreadState *tstate, PyObject *globals) return _PyEval_GetBuiltins(tstate); } - - diff --git a/Objects/funcobject.c b/Objects/funcobject.c index 57600c97..f43e3a27 100644 --- a/Objects/funcobject.c +++ b/Objects/funcobject.c @@ -3,45 +3,137 @@ #include "Python.h" #include "pycore_ceval.h" // _PyEval_BuiltinsFromGlobals() +#include "pycore_code.h" // _Py_next_func_version #include "pycore_object.h" // _PyObject_GC_UNTRACK() #include "pycore_pyerrors.h" // _PyErr_Occurred() #include "structmember.h" // PyMemberDef -static uint32_t next_func_version = 1; +static PyObject* func_repr(PyFunctionObject *op); +static const char * +func_event_name(PyFunction_WatchEvent event) { + switch (event) { + #define CASE(op) \ + case PyFunction_EVENT_##op: \ + return "PyFunction_EVENT_" #op; + PY_FOREACH_FUNC_EVENT(CASE) + #undef CASE + } + Py_UNREACHABLE(); +} + +static void +notify_func_watchers(PyInterpreterState *interp, PyFunction_WatchEvent event, + PyFunctionObject *func, PyObject *new_value) +{ + uint8_t bits = interp->active_func_watchers; + int i = 0; + while (bits) { + assert(i < FUNC_MAX_WATCHERS); + if (bits & 1) { + PyFunction_WatchCallback cb = interp->func_watchers[i]; + // callback must be non-null if the watcher bit is set + assert(cb != NULL); + if (cb(event, func, new_value) < 0) { + // Don't risk resurrecting the func if an unraisablehook keeps a + // reference; pass a string as context. + PyObject *context = NULL; + PyObject *repr = func_repr(func); + if (repr != NULL) { + context = PyUnicode_FromFormat( + "%s watcher callback for %U", + func_event_name(event), repr); + Py_DECREF(repr); + } + if (context == NULL) { + context = Py_NewRef(Py_None); + } + PyErr_WriteUnraisable(context); + Py_DECREF(context); + } + } + i++; + bits >>= 1; + } +} + +static inline void +handle_func_event(PyFunction_WatchEvent event, PyFunctionObject *func, + PyObject *new_value) +{ + assert(Py_REFCNT(func) > 0); + PyInterpreterState *interp = _PyInterpreterState_GET(); + assert(interp->_initialized); + if (interp->active_func_watchers) { + notify_func_watchers(interp, event, func, new_value); + } +} + +int +PyFunction_AddWatcher(PyFunction_WatchCallback callback) +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + assert(interp->_initialized); + for (int i = 0; i < FUNC_MAX_WATCHERS; i++) { + if (interp->func_watchers[i] == NULL) { + interp->func_watchers[i] = callback; + interp->active_func_watchers |= (1 << i); + return i; + } + } + PyErr_SetString(PyExc_RuntimeError, "no more func watcher IDs available"); + return -1; +} + +int +PyFunction_ClearWatcher(int watcher_id) +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + if (watcher_id < 0 || watcher_id >= FUNC_MAX_WATCHERS) { + PyErr_Format(PyExc_ValueError, "invalid func watcher ID %d", + watcher_id); + return -1; + } + if (!interp->func_watchers[watcher_id]) { + PyErr_Format(PyExc_ValueError, "no func watcher set for ID %d", + watcher_id); + return -1; + } + interp->func_watchers[watcher_id] = NULL; + interp->active_func_watchers &= ~(1 << watcher_id); + return 0; +} PyFunctionObject * _PyFunction_FromConstructor(PyFrameConstructor *constr) { + PyObject *module = Py_XNewRef(PyDict_GetItemWithError(constr->fc_globals, &_Py_ID(__name__))); + if (!module && PyErr_Occurred()) { + return NULL; + } PyFunctionObject *op = PyObject_GC_New(PyFunctionObject, &PyFunction_Type); if (op == NULL) { + Py_XDECREF(module); return NULL; } - Py_INCREF(constr->fc_globals); - op->func_globals = constr->fc_globals; - Py_INCREF(constr->fc_builtins); - op->func_builtins = constr->fc_builtins; - Py_INCREF(constr->fc_name); - op->func_name = constr->fc_name; - Py_INCREF(constr->fc_qualname); - op->func_qualname = constr->fc_qualname; - Py_INCREF(constr->fc_code); - op->func_code = constr->fc_code; - Py_XINCREF(constr->fc_defaults); - op->func_defaults = constr->fc_defaults; - Py_XINCREF(constr->fc_kwdefaults); - op->func_kwdefaults = constr->fc_kwdefaults; - Py_XINCREF(constr->fc_closure); - op->func_closure = constr->fc_closure; - Py_INCREF(Py_None); - op->func_doc = Py_None; + op->func_globals = Py_NewRef(constr->fc_globals); + op->func_builtins = Py_NewRef(constr->fc_builtins); + op->func_name = Py_NewRef(constr->fc_name); + op->func_qualname = Py_NewRef(constr->fc_qualname); + op->func_code = Py_NewRef(constr->fc_code); + op->func_defaults = Py_XNewRef(constr->fc_defaults); + op->func_kwdefaults = Py_XNewRef(constr->fc_kwdefaults); + op->func_closure = Py_XNewRef(constr->fc_closure); + op->func_doc = Py_NewRef(Py_None); op->func_dict = NULL; op->func_weakreflist = NULL; - op->func_module = NULL; + op->func_module = module; op->func_annotations = NULL; + op->func_typeparams = NULL; op->vectorcall = _PyFunction_Vectorcall; op->func_version = 0; _PyObject_GC_TRACK(op); + handle_func_event(PyFunction_EVENT_CREATE, op, NULL); return op; } @@ -54,12 +146,10 @@ PyFunction_NewWithQualName(PyObject *code, PyObject *globals, PyObject *qualname PyThreadState *tstate = _PyThreadState_GET(); - PyCodeObject *code_obj = (PyCodeObject *)code; - Py_INCREF(code_obj); + PyCodeObject *code_obj = (PyCodeObject *)Py_NewRef(code); - PyObject *name = code_obj->co_name; - assert(name != NULL); - Py_INCREF(name); + assert(code_obj->co_name != NULL); + PyObject *name = Py_NewRef(code_obj->co_name); if (!qualname) { qualname = code_obj->co_qualname; @@ -115,9 +205,11 @@ PyFunction_NewWithQualName(PyObject *code, PyObject *globals, PyObject *qualname op->func_weakreflist = NULL; op->func_module = module; op->func_annotations = NULL; + op->func_typeparams = NULL; op->vectorcall = _PyFunction_Vectorcall; op->func_version = 0; _PyObject_GC_TRACK(op); + handle_func_event(PyFunction_EVENT_CREATE, op, NULL); return (PyObject *)op; error: @@ -136,10 +228,14 @@ uint32_t _PyFunction_GetVersionForCurrentState(PyFunctionObject *func) if (func->func_version != 0) { return func->func_version; } - if (next_func_version == 0) { + if (func->vectorcall != _PyFunction_Vectorcall) { + return 0; + } + PyInterpreterState *interp = _PyInterpreterState_GET(); + if (interp->func_state.next_version == 0) { return 0; } - uint32_t v = next_func_version++; + uint32_t v = interp->func_state.next_version++; func->func_version = v; return v; } @@ -206,11 +302,21 @@ PyFunction_SetDefaults(PyObject *op, PyObject *defaults) PyErr_SetString(PyExc_SystemError, "non-tuple default args"); return -1; } + handle_func_event(PyFunction_EVENT_MODIFY_DEFAULTS, + (PyFunctionObject *) op, defaults); ((PyFunctionObject *)op)->func_version = 0; Py_XSETREF(((PyFunctionObject *)op)->func_defaults, defaults); return 0; } +void +PyFunction_SetVectorcall(PyFunctionObject *func, vectorcallfunc vectorcall) +{ + assert(func != NULL); + func->func_version = 0; + func->vectorcall = vectorcall; +} + PyObject * PyFunction_GetKwDefaults(PyObject *op) { @@ -238,6 +344,8 @@ PyFunction_SetKwDefaults(PyObject *op, PyObject *defaults) "non-dict keyword only default args"); return -1; } + handle_func_event(PyFunction_EVENT_MODIFY_KWDEFAULTS, + (PyFunctionObject *) op, defaults); ((PyFunctionObject *)op)->func_version = 0; Py_XSETREF(((PyFunctionObject *)op)->func_kwdefaults, defaults); return 0; @@ -358,8 +466,7 @@ func_get_code(PyFunctionObject *op, void *Py_UNUSED(ignored)) return NULL; } - Py_INCREF(op->func_code); - return op->func_code; + return Py_NewRef(op->func_code); } static int @@ -392,17 +499,16 @@ func_set_code(PyFunctionObject *op, PyObject *value, void *Py_UNUSED(ignored)) nclosure, nfree); return -1; } + handle_func_event(PyFunction_EVENT_MODIFY_CODE, op, value); op->func_version = 0; - Py_INCREF(value); - Py_XSETREF(op->func_code, value); + Py_XSETREF(op->func_code, Py_NewRef(value)); return 0; } static PyObject * func_get_name(PyFunctionObject *op, void *Py_UNUSED(ignored)) { - Py_INCREF(op->func_name); - return op->func_name; + return Py_NewRef(op->func_name); } static int @@ -415,16 +521,14 @@ func_set_name(PyFunctionObject *op, PyObject *value, void *Py_UNUSED(ignored)) "__name__ must be set to a string object"); return -1; } - Py_INCREF(value); - Py_XSETREF(op->func_name, value); + Py_XSETREF(op->func_name, Py_NewRef(value)); return 0; } static PyObject * func_get_qualname(PyFunctionObject *op, void *Py_UNUSED(ignored)) { - Py_INCREF(op->func_qualname); - return op->func_qualname; + return Py_NewRef(op->func_qualname); } static int @@ -437,8 +541,7 @@ func_set_qualname(PyFunctionObject *op, PyObject *value, void *Py_UNUSED(ignored "__qualname__ must be set to a string object"); return -1; } - Py_INCREF(value); - Py_XSETREF(op->func_qualname, value); + Py_XSETREF(op->func_qualname, Py_NewRef(value)); return 0; } @@ -451,8 +554,7 @@ func_get_defaults(PyFunctionObject *op, void *Py_UNUSED(ignored)) if (op->func_defaults == NULL) { Py_RETURN_NONE; } - Py_INCREF(op->func_defaults); - return op->func_defaults; + return Py_NewRef(op->func_defaults); } static int @@ -477,9 +579,9 @@ func_set_defaults(PyFunctionObject *op, PyObject *value, void *Py_UNUSED(ignored return -1; } + handle_func_event(PyFunction_EVENT_MODIFY_DEFAULTS, op, value); op->func_version = 0; - Py_XINCREF(value); - Py_XSETREF(op->func_defaults, value); + Py_XSETREF(op->func_defaults, Py_XNewRef(value)); return 0; } @@ -493,8 +595,7 @@ func_get_kwdefaults(PyFunctionObject *op, void *Py_UNUSED(ignored)) if (op->func_kwdefaults == NULL) { Py_RETURN_NONE; } - Py_INCREF(op->func_kwdefaults); - return op->func_kwdefaults; + return Py_NewRef(op->func_kwdefaults); } static int @@ -519,9 +620,9 @@ func_set_kwdefaults(PyFunctionObject *op, PyObject *value, void *Py_UNUSED(ignor return -1; } + handle_func_event(PyFunction_EVENT_MODIFY_KWDEFAULTS, op, value); op->func_version = 0; - Py_XINCREF(value); - Py_XSETREF(op->func_kwdefaults, value); + Py_XSETREF(op->func_kwdefaults, Py_XNewRef(value)); return 0; } @@ -534,10 +635,7 @@ func_get_annotations(PyFunctionObject *op, void *Py_UNUSED(ignored)) return NULL; } PyObject *d = func_get_annotation_dict(op); - if (d) { - Py_INCREF(d); - } - return d; + return Py_XNewRef(d); } static int @@ -554,11 +652,46 @@ func_set_annotations(PyFunctionObject *op, PyObject *value, void *Py_UNUSED(igno return -1; } op->func_version = 0; - Py_XINCREF(value); - Py_XSETREF(op->func_annotations, value); + Py_XSETREF(op->func_annotations, Py_XNewRef(value)); + return 0; +} + +static PyObject * +func_get_type_params(PyFunctionObject *op, void *Py_UNUSED(ignored)) +{ + if (op->func_typeparams == NULL) { + return PyTuple_New(0); + } + + assert(PyTuple_Check(op->func_typeparams)); + return Py_NewRef(op->func_typeparams); +} + +static int +func_set_type_params(PyFunctionObject *op, PyObject *value, void *Py_UNUSED(ignored)) +{ + /* Not legal to del f.__type_params__ or to set it to anything + * other than a tuple object. */ + if (value == NULL || !PyTuple_Check(value)) { + PyErr_SetString(PyExc_TypeError, + "__type_params__ must be set to a tuple"); + return -1; + } + Py_XSETREF(op->func_typeparams, Py_NewRef(value)); return 0; } +PyObject * +_Py_set_function_type_params(PyThreadState *Py_UNUSED(ignored), PyObject *func, + PyObject *type_params) +{ + assert(PyFunction_Check(func)); + assert(PyTuple_Check(type_params)); + PyFunctionObject *f = (PyFunctionObject *)func; + Py_XSETREF(f->func_typeparams, Py_NewRef(type_params)); + return Py_NewRef(func); +} + static PyGetSetDef func_getsetlist[] = { {"__code__", (getter)func_get_code, (setter)func_set_code}, {"__defaults__", (getter)func_get_defaults, @@ -570,6 +703,8 @@ static PyGetSetDef func_getsetlist[] = { {"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict}, {"__name__", (getter)func_get_name, (setter)func_set_name}, {"__qualname__", (getter)func_get_qualname, (setter)func_set_qualname}, + {"__type_params__", (getter)func_get_type_params, + (setter)func_set_type_params}, {NULL} /* Sentinel */ }; @@ -665,16 +800,13 @@ func_new_impl(PyTypeObject *type, PyCodeObject *code, PyObject *globals, return NULL; } if (name != Py_None) { - Py_INCREF(name); - Py_SETREF(newfunc->func_name, name); + Py_SETREF(newfunc->func_name, Py_NewRef(name)); } if (defaults != Py_None) { - Py_INCREF(defaults); - newfunc->func_defaults = defaults; + newfunc->func_defaults = Py_NewRef(defaults); } if (closure != Py_None) { - Py_INCREF(closure); - newfunc->func_closure = closure; + newfunc->func_closure = Py_NewRef(closure); } return (PyObject *)newfunc; @@ -693,6 +825,7 @@ func_clear(PyFunctionObject *op) Py_CLEAR(op->func_dict); Py_CLEAR(op->func_closure); Py_CLEAR(op->func_annotations); + Py_CLEAR(op->func_typeparams); // Don't Py_CLEAR(op->func_code), since code is always required // to be non-NULL. Similarly, name and qualname shouldn't be NULL. // However, name and qualname could be str subclasses, so they @@ -706,6 +839,14 @@ func_clear(PyFunctionObject *op) static void func_dealloc(PyFunctionObject *op) { + assert(Py_REFCNT(op) == 0); + Py_SET_REFCNT(op, 1); + handle_func_event(PyFunction_EVENT_DESTROY, op, NULL); + if (Py_REFCNT(op) > 1) { + Py_SET_REFCNT(op, Py_REFCNT(op) - 1); + return; + } + Py_SET_REFCNT(op, 0); _PyObject_GC_UNTRACK(op); if (op->func_weakreflist != NULL) { PyObject_ClearWeakRefs((PyObject *) op); @@ -739,6 +880,7 @@ func_traverse(PyFunctionObject *f, visitproc visit, void *arg) Py_VISIT(f->func_dict); Py_VISIT(f->func_closure); Py_VISIT(f->func_annotations); + Py_VISIT(f->func_typeparams); Py_VISIT(f->func_qualname); return 0; } @@ -748,8 +890,7 @@ static PyObject * func_descr_get(PyObject *func, PyObject *obj, PyObject *type) { if (obj == Py_None || obj == NULL) { - Py_INCREF(func); - return func; + return Py_NewRef(func); } return PyMethod_New(func, obj); } @@ -845,7 +986,7 @@ functools_wraps(PyObject *wrapper, PyObject *wrapped) class C: @classmethod - def f(cls, arg1, arg2, ...): + def f(cls, arg1, arg2, argN): ... It can be called either on the class (e.g. C.f()) or on an instance @@ -918,8 +1059,7 @@ cm_init(PyObject *self, PyObject *args, PyObject *kwds) return -1; if (!PyArg_UnpackTuple(args, "classmethod", 1, 1, &callable)) return -1; - Py_INCREF(callable); - Py_XSETREF(cm->cm_callable, callable); + Py_XSETREF(cm->cm_callable, Py_NewRef(callable)); if (functools_wraps((PyObject *)cm, cm->cm_callable) < 0) { return -1; @@ -970,7 +1110,7 @@ To declare a class method, use this idiom:\n\ \n\ class C:\n\ @classmethod\n\ - def f(cls, arg1, arg2, ...):\n\ + def f(cls, arg1, arg2, argN):\n\ ...\n\ \n\ It can be called either on the class (e.g. C.f()) or on an instance\n\ @@ -1029,8 +1169,7 @@ PyClassMethod_New(PyObject *callable) classmethod *cm = (classmethod *) PyType_GenericAlloc(&PyClassMethod_Type, 0); if (cm != NULL) { - Py_INCREF(callable); - cm->cm_callable = callable; + cm->cm_callable = Py_NewRef(callable); } return (PyObject *)cm; } @@ -1043,7 +1182,7 @@ PyClassMethod_New(PyObject *callable) class C: @staticmethod - def f(arg1, arg2, ...): + def f(arg1, arg2, argN): ... It can be called either on the class (e.g. C.f()) or on an instance @@ -1095,8 +1234,7 @@ sm_descr_get(PyObject *self, PyObject *obj, PyObject *type) "uninitialized staticmethod object"); return NULL; } - Py_INCREF(sm->sm_callable); - return sm->sm_callable; + return Py_NewRef(sm->sm_callable); } static int @@ -1109,8 +1247,7 @@ sm_init(PyObject *self, PyObject *args, PyObject *kwds) return -1; if (!PyArg_UnpackTuple(args, "staticmethod", 1, 1, &callable)) return -1; - Py_INCREF(callable); - Py_XSETREF(sm->sm_callable, callable); + Py_XSETREF(sm->sm_callable, Py_NewRef(callable)); if (functools_wraps((PyObject *)sm, sm->sm_callable) < 0) { return -1; @@ -1167,7 +1304,7 @@ To declare a static method, use this idiom:\n\ \n\ class C:\n\ @staticmethod\n\ - def f(arg1, arg2, ...):\n\ + def f(arg1, arg2, argN):\n\ ...\n\ \n\ It can be called either on the class (e.g. C.f()) or on an instance\n\ @@ -1225,8 +1362,7 @@ PyStaticMethod_New(PyObject *callable) staticmethod *sm = (staticmethod *) PyType_GenericAlloc(&PyStaticMethod_Type, 0); if (sm != NULL) { - Py_INCREF(callable); - sm->sm_callable = callable; + sm->sm_callable = Py_NewRef(callable); } return (PyObject *)sm; } diff --git a/Objects/genericaliasobject.c b/Objects/genericaliasobject.c index 77acd1bc..117b4e8d 100644 --- a/Objects/genericaliasobject.c +++ b/Objects/genericaliasobject.c @@ -121,6 +121,36 @@ done: return err; } +static int +ga_repr_items_list(_PyUnicodeWriter *writer, PyObject *p) +{ + assert(PyList_CheckExact(p)); + + Py_ssize_t len = PyList_GET_SIZE(p); + + if (_PyUnicodeWriter_WriteASCIIString(writer, "[", 1) < 0) { + return -1; + } + + for (Py_ssize_t i = 0; i < len; i++) { + if (i > 0) { + if (_PyUnicodeWriter_WriteASCIIString(writer, ", ", 2) < 0) { + return -1; + } + } + PyObject *item = PyList_GET_ITEM(p, i); + if (ga_repr_item(writer, item) < 0) { + return -1; + } + } + + if (_PyUnicodeWriter_WriteASCIIString(writer, "]", 1) < 0) { + return -1; + } + + return 0; +} + static PyObject * ga_repr(PyObject *self) { @@ -148,7 +178,13 @@ ga_repr(PyObject *self) } } PyObject *p = PyTuple_GET_ITEM(alias->args, i); - if (ga_repr_item(&writer, p) < 0) { + if (PyList_CheckExact(p)) { + // Looks like we are working with ParamSpec's list of type args: + if (ga_repr_items_list(&writer, p) < 0) { + goto error; + } + } + else if (ga_repr_item(&writer, p) < 0) { goto error; } } @@ -183,8 +219,7 @@ static int tuple_add(PyObject *self, Py_ssize_t len, PyObject *item) { if (tuple_index(self, len, item) < 0) { - Py_INCREF(item); - PyTuple_SET_ITEM(self, len, item); + PyTuple_SET_ITEM(self, len, Py_NewRef(item)); return 1; } return 0; @@ -201,8 +236,7 @@ tuple_extend(PyObject **dst, Py_ssize_t dstindex, assert(dstindex + count <= PyTuple_GET_SIZE(*dst)); for (Py_ssize_t i = 0; i < count; ++i) { PyObject *item = src[i]; - Py_INCREF(item); - PyTuple_SET_ITEM(*dst, dstindex + i, item); + PyTuple_SET_ITEM(*dst, dstindex + i, Py_NewRef(item)); } return dstindex + count; } @@ -304,8 +338,7 @@ subs_tvars(PyObject *obj, PyObject *params, continue; } } - Py_INCREF(arg); - PyTuple_SET_ITEM(subargs, j, arg); + PyTuple_SET_ITEM(subargs, j, Py_NewRef(arg)); j++; } assert(j == PyTuple_GET_SIZE(subargs)); @@ -347,8 +380,7 @@ _unpacked_tuple_args(PyObject *arg) ((gaobject *)arg)->origin == (PyObject *)&PyTuple_Type) { result = ((gaobject *)arg)->args; - Py_INCREF(result); - return result; + return Py_NewRef(result); } if (_PyObject_LookupAttr(arg, &_Py_ID(__typing_unpacked_tuple_args__), &result) > 0) { @@ -459,8 +491,7 @@ _Py_subs_parameters(PyObject *self, PyObject *args, PyObject *parameters, PyObje for (Py_ssize_t iarg = 0, jarg = 0; iarg < nargs; iarg++) { PyObject *arg = PyTuple_GET_ITEM(args, iarg); if (PyType_Check(arg)) { - Py_INCREF(arg); - PyTuple_SET_ITEM(newargs, jarg, arg); + PyTuple_SET_ITEM(newargs, jarg, Py_NewRef(arg)); jarg++; continue; } @@ -767,8 +798,7 @@ ga_parameters(PyObject *self, void *unused) return NULL; } } - Py_INCREF(alias->parameters); - return alias->parameters; + return Py_NewRef(alias->parameters); } static PyObject * @@ -776,8 +806,7 @@ ga_unpacked_tuple_args(PyObject *self, void *unused) { gaobject *alias = (gaobject *)self; if (alias->starred && alias->origin == (PyObject *)&PyTuple_Type) { - Py_INCREF(alias->args); - return alias->args; + return Py_NewRef(alias->args); } Py_RETURN_NONE; } @@ -803,8 +832,7 @@ setup_ga(gaobject *alias, PyObject *origin, PyObject *args) { Py_INCREF(args); } - Py_INCREF(origin); - alias->origin = origin; + alias->origin = Py_NewRef(origin); alias->args = args; alias->parameters = NULL; alias->weakreflist = NULL; @@ -885,8 +913,17 @@ ga_iter_clear(PyObject *self) { static PyObject * ga_iter_reduce(PyObject *self, PyObject *Py_UNUSED(ignored)) { + PyObject *iter = _PyEval_GetBuiltin(&_Py_ID(iter)); gaiterobject *gi = (gaiterobject *)self; - return Py_BuildValue("N(O)", _PyEval_GetBuiltin(&_Py_ID(iter)), gi->obj); + + /* _PyEval_GetBuiltin can invoke arbitrary code, + * call must be before access of iterator pointers. + * see issue #101765 */ + + if (gi->obj) + return Py_BuildValue("N(O)", iter, gi->obj); + else + return Py_BuildValue("N(())", iter); } static PyMethodDef ga_iter_methods[] = { diff --git a/Objects/genobject.c b/Objects/genobject.c index b9a0c30c..b13b52ed 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -1,16 +1,19 @@ /* Generator object implementation */ +#define _PY_INTERPRETER + #include "Python.h" #include "pycore_call.h" // _PyObject_CallNoArgs() #include "pycore_ceval.h" // _PyEval_EvalFrame() #include "pycore_frame.h" // _PyInterpreterFrame #include "pycore_genobject.h" // struct _Py_async_gen_state #include "pycore_object.h" // _PyObject_GC_UNTRACK() -#include "pycore_opcode.h" // _PyOpcode_Deopt #include "pycore_pyerrors.h" // _PyErr_ClearExcState() #include "pycore_pystate.h" // _PyThreadState_GET() #include "structmember.h" // PyMemberDef #include "opcode.h" // SEND +#include "frameobject.h" // _PyInterpreterFrame_GetLine +#include "pystats.h" static PyObject *gen_close(PyGenObject *, PyObject *); static PyObject *async_gen_asend_new(PyAsyncGenObject *, PyObject *); @@ -22,6 +25,21 @@ static const char *NON_INIT_CORO_MSG = "can't send non-None value to a " static const char *ASYNC_GEN_IGNORED_EXIT_MSG = "async generator ignored GeneratorExit"; +/* Returns a borrowed reference */ +static inline PyCodeObject * +_PyGen_GetCode(PyGenObject *gen) { + _PyInterpreterFrame *frame = (_PyInterpreterFrame *)(gen->gi_iframe); + return frame->f_code; +} + +PyCodeObject * +PyGen_GetCode(PyGenObject *gen) { + assert(PyGen_Check(gen)); + PyCodeObject *res = _PyGen_GetCode(gen); + Py_INCREF(res); + return res; +} + static inline int exc_state_traverse(_PyErr_StackItem *exc_state, visitproc visit, void *arg) { @@ -32,7 +50,6 @@ exc_state_traverse(_PyErr_StackItem *exc_state, visitproc visit, void *arg) static int gen_traverse(PyGenObject *gen, visitproc visit, void *arg) { - Py_VISIT(gen->gi_code); Py_VISIT(gen->gi_name); Py_VISIT(gen->gi_qualname); if (gen->gi_frame_state < FRAME_CLEARED) { @@ -53,8 +70,6 @@ void _PyGen_Finalize(PyObject *self) { PyGenObject *gen = (PyGenObject *)self; - PyObject *res = NULL; - PyObject *error_type, *error_value, *error_traceback; if (gen->gi_frame_state >= FRAME_COMPLETED) { /* Generator isn't paused, so no need to close */ @@ -66,47 +81,45 @@ _PyGen_Finalize(PyObject *self) PyObject *finalizer = agen->ag_origin_or_finalizer; if (finalizer && !agen->ag_closed) { /* Save the current exception, if any. */ - PyErr_Fetch(&error_type, &error_value, &error_traceback); - - res = PyObject_CallOneArg(finalizer, self); + PyObject *exc = PyErr_GetRaisedException(); + PyObject *res = PyObject_CallOneArg(finalizer, self); if (res == NULL) { PyErr_WriteUnraisable(self); } else { Py_DECREF(res); } /* Restore the saved exception. */ - PyErr_Restore(error_type, error_value, error_traceback); + PyErr_SetRaisedException(exc); return; } } /* Save the current exception, if any. */ - PyErr_Fetch(&error_type, &error_value, &error_traceback); + PyObject *exc = PyErr_GetRaisedException(); /* If `gen` is a coroutine, and if it was never awaited on, issue a RuntimeWarning. */ - if (gen->gi_code != NULL && - ((PyCodeObject *)gen->gi_code)->co_flags & CO_COROUTINE && + assert(_PyGen_GetCode(gen) != NULL); + if (_PyGen_GetCode(gen)->co_flags & CO_COROUTINE && gen->gi_frame_state == FRAME_CREATED) { _PyErr_WarnUnawaitedCoroutine((PyObject *)gen); } else { - res = gen_close(gen, NULL); - } - - if (res == NULL) { - if (PyErr_Occurred()) { - PyErr_WriteUnraisable(self); + PyObject *res = gen_close(gen, NULL); + if (res == NULL) { + if (PyErr_Occurred()) { + PyErr_WriteUnraisable(self); + } + } + else { + Py_DECREF(res); } - } - else { - Py_DECREF(res); } /* Restore the saved exception. */ - PyErr_Restore(error_type, error_value, error_traceback); + PyErr_SetRaisedException(exc); } static void @@ -135,12 +148,12 @@ gen_dealloc(PyGenObject *gen) _PyInterpreterFrame *frame = (_PyInterpreterFrame *)gen->gi_iframe; gen->gi_frame_state = FRAME_CLEARED; frame->previous = NULL; - _PyFrame_Clear(frame); + _PyFrame_ClearExceptCode(frame); } - if (((PyCodeObject *)gen->gi_code)->co_flags & CO_COROUTINE) { + if (_PyGen_GetCode(gen)->co_flags & CO_COROUTINE) { Py_CLEAR(((PyCoroObject *)gen)->cr_origin_or_finalizer); } - Py_CLEAR(gen->gi_code); + Py_DECREF(_PyGen_GetCode(gen)); Py_CLEAR(gen->gi_name); Py_CLEAR(gen->gi_qualname); _PyErr_ClearExcState(&gen->gi_exc_state); @@ -192,8 +205,7 @@ gen_send_ex2(PyGenObject *gen, PyObject *arg, PyObject **presult, else if (arg && !exc) { /* `gen` is an exhausted generator: only return value if called from send(). */ - *presult = Py_None; - Py_INCREF(*presult); + *presult = Py_NewRef(Py_None); return PYGEN_RETURN; } return PYGEN_ERROR; @@ -202,12 +214,10 @@ gen_send_ex2(PyGenObject *gen, PyObject *arg, PyObject **presult, assert(gen->gi_frame_state < FRAME_EXECUTING); /* Push arg onto the frame's value stack */ result = arg ? arg : Py_None; - Py_INCREF(result); - _PyFrame_StackPush(frame, result); - - frame->previous = tstate->cframe->current_frame; + _PyFrame_StackPush(frame, Py_NewRef(result)); - gen->gi_exc_state.previous_item = tstate->exc_info; + _PyErr_StackItem *prev_exc_info = tstate->exc_info; + gen->gi_exc_state.previous_item = prev_exc_info; tstate->exc_info = &gen->gi_exc_state; if (exc) { @@ -216,18 +226,12 @@ gen_send_ex2(PyGenObject *gen, PyObject *arg, PyObject **presult, } gen->gi_frame_state = FRAME_EXECUTING; + EVAL_CALL_STAT_INC(EVAL_CALL_GENERATOR); result = _PyEval_EvalFrame(tstate, frame, exc); - if (gen->gi_frame_state == FRAME_EXECUTING) { - gen->gi_frame_state = FRAME_COMPLETED; - } - tstate->exc_info = gen->gi_exc_state.previous_item; - gen->gi_exc_state.previous_item = NULL; - - assert(tstate->cframe->current_frame == frame->previous); - /* Don't keep the reference to previous any longer than necessary. It - * may keep a chain of frames alive or it could create a reference - * cycle. */ - frame->previous = NULL; + assert(tstate->exc_info == prev_exc_info); + assert(gen->gi_exc_state.previous_item == NULL); + assert(gen->gi_frame_state != FRAME_EXECUTING); + assert(frame->previous == NULL); /* If the generator just returned (as opposed to yielding), signal * that the generator is exhausted. */ @@ -243,33 +247,16 @@ gen_send_ex2(PyGenObject *gen, PyObject *arg, PyObject **presult, } } else { - if (PyErr_ExceptionMatches(PyExc_StopIteration)) { - const char *msg = "generator raised StopIteration"; - if (PyCoro_CheckExact(gen)) { - msg = "coroutine raised StopIteration"; - } - else if (PyAsyncGen_CheckExact(gen)) { - msg = "async generator raised StopIteration"; - } - _PyErr_FormatFromCause(PyExc_RuntimeError, "%s", msg); - } - else if (PyAsyncGen_CheckExact(gen) && - PyErr_ExceptionMatches(PyExc_StopAsyncIteration)) - { - /* code in `gen` raised a StopAsyncIteration error: - raise a RuntimeError. - */ - const char *msg = "async generator raised StopAsyncIteration"; - _PyErr_FormatFromCause(PyExc_RuntimeError, "%s", msg); - } + assert(!PyErr_ExceptionMatches(PyExc_StopIteration)); + assert(!PyAsyncGen_CheckExact(gen) || + !PyErr_ExceptionMatches(PyExc_StopAsyncIteration)); } /* generator can't be rerun, so release the frame */ /* first clean reference cycle through stored exception traceback */ _PyErr_ClearExcState(&gen->gi_exc_state); - gen->gi_frame_state = FRAME_CLEARED; - _PyFrame_Clear(frame); + assert(gen->gi_frame_state == FRAME_CLEARED); *presult = result; return result ? PYGEN_RETURN : PYGEN_ERROR; } @@ -344,6 +331,18 @@ gen_close_iter(PyObject *yf) return 0; } +static inline bool +is_resume(_Py_CODEUNIT *instr) +{ + return instr->op.code == RESUME || instr->op.code == INSTRUMENTED_RESUME; +} + +static inline bool +is_yield(_Py_CODEUNIT *instr) +{ + return instr->op.code == YIELD_VALUE || instr->op.code == INSTRUMENTED_YIELD_VALUE; +} + PyObject * _PyGen_yf(PyGenObject *gen) { @@ -356,17 +355,16 @@ _PyGen_yf(PyGenObject *gen) /* Return immediately if the frame didn't start yet. SEND always come after LOAD_CONST: a code object should not start with SEND */ - assert(_Py_OPCODE(_PyCode_CODE(gen->gi_code)[0]) != SEND); + assert(_PyCode_CODE(_PyGen_GetCode(gen))[0].op.code != SEND); return NULL; } _Py_CODEUNIT next = frame->prev_instr[1]; - if (_PyOpcode_Deopt[_Py_OPCODE(next)] != RESUME || _Py_OPARG(next) < 2) + if (!is_resume(&next) || next.op.arg < 2) { /* Not in a yield from */ return NULL; } - yf = _PyFrame_StackPeek(frame); - Py_INCREF(yf); + yf = Py_NewRef(_PyFrame_StackPeek(frame)); } return yf; @@ -379,6 +377,13 @@ gen_close(PyGenObject *gen, PyObject *args) PyObject *yf = _PyGen_yf(gen); int err = 0; + if (gen->gi_frame_state == FRAME_CREATED) { + gen->gi_frame_state = FRAME_COMPLETED; + Py_RETURN_NONE; + } + if (gen->gi_frame_state >= FRAME_COMPLETED) { + Py_RETURN_NONE; + } if (yf) { PyFrameState state = gen->gi_frame_state; gen->gi_frame_state = FRAME_EXECUTING; @@ -386,8 +391,23 @@ gen_close(PyGenObject *gen, PyObject *args) gen->gi_frame_state = state; Py_DECREF(yf); } - if (err == 0) + _PyInterpreterFrame *frame = (_PyInterpreterFrame *)gen->gi_iframe; + /* It is possible for the previous instruction to not be a + * YIELD_VALUE if the debugger has changed the lineno. */ + if (err == 0 && is_yield(frame->prev_instr)) { + assert(is_resume(frame->prev_instr + 1)); + int exception_handler_depth = frame->prev_instr[0].op.code; + assert(exception_handler_depth > 0); + /* We can safely ignore the outermost try block + * as it automatically generated to handle + * StopIteration. */ + if (exception_handler_depth == 1) { + Py_RETURN_NONE; + } + } + if (err == 0) { PyErr_SetNone(PyExc_GeneratorExit); + } retval = gen_send_ex(gen, Py_None, 1, 1); if (retval) { const char *msg = "generator ignored GeneratorExit"; @@ -414,7 +434,9 @@ PyDoc_STRVAR(throw_doc, throw(type[,value[,tb]])\n\ \n\ Raise exception in generator, return next yielded value or raise\n\ -StopIteration."); +StopIteration.\n\ +the (type, val, tb) signature is deprecated, \n\ +and may be removed in a future version of Python."); static PyObject * _gen_throw(PyGenObject *gen, int close_on_genexit, @@ -481,26 +503,7 @@ _gen_throw(PyGenObject *gen, int close_on_genexit, } Py_DECREF(yf); if (!ret) { - PyObject *val; - /* Pop subiterator from stack */ - assert(gen->gi_frame_state < FRAME_CLEARED); - ret = _PyFrame_StackPop((_PyInterpreterFrame *)gen->gi_iframe); - assert(ret == yf); - Py_DECREF(ret); - // XXX: Performing this jump ourselves is awkward and problematic. - // See https://github.com/python/cpython/pull/31968. - /* Termination repetition of SEND loop */ - assert(_PyInterpreterFrame_LASTI(frame) >= 0); - /* Backup to SEND */ - assert(_Py_OPCODE(frame->prev_instr[-1]) == SEND); - int jump = _Py_OPARG(frame->prev_instr[-1]); - frame->prev_instr += jump - 1; - if (_PyGen_FetchStopIterationValue(&val) == 0) { - ret = gen_send(gen, val); - Py_DECREF(val); - } else { - ret = gen_send_ex(gen, Py_None, 1, 0); - } + ret = gen_send_ex(gen, Py_None, 1, 0); } return ret; } @@ -533,10 +536,8 @@ throw_here: } else { /* Normalize to raise <class>, <instance> */ - Py_XDECREF(val); - val = typ; - typ = PyExceptionInstance_Class(typ); - Py_INCREF(typ); + Py_XSETREF(val, typ); + typ = Py_NewRef(PyExceptionInstance_Class(typ)); if (tb == NULL) /* Returns NULL if there's no traceback */ @@ -574,6 +575,14 @@ gen_throw(PyGenObject *gen, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("throw", nargs, 1, 3)) { return NULL; } + if (nargs > 1) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "the (type, exc, tb) signature of throw() is deprecated, " + "use the single-arg signature instead.", + 1) < 0) { + return NULL; + } + } typ = args[0]; if (nargs == 3) { val = args[1]; @@ -648,47 +657,16 @@ _PyGen_SetStopIterationValue(PyObject *value) int _PyGen_FetchStopIterationValue(PyObject **pvalue) { - PyObject *et, *ev, *tb; PyObject *value = NULL; - if (PyErr_ExceptionMatches(PyExc_StopIteration)) { - PyErr_Fetch(&et, &ev, &tb); - if (ev) { - /* exception will usually be normalised already */ - if (PyObject_TypeCheck(ev, (PyTypeObject *) et)) { - value = ((PyStopIterationObject *)ev)->value; - Py_INCREF(value); - Py_DECREF(ev); - } else if (et == PyExc_StopIteration && !PyTuple_Check(ev)) { - /* Avoid normalisation and take ev as value. - * - * Normalization is required if the value is a tuple, in - * that case the value of StopIteration would be set to - * the first element of the tuple. - * - * (See _PyErr_CreateException code for details.) - */ - value = ev; - } else { - /* normalisation required */ - PyErr_NormalizeException(&et, &ev, &tb); - if (!PyObject_TypeCheck(ev, (PyTypeObject *)PyExc_StopIteration)) { - PyErr_Restore(et, ev, tb); - return -1; - } - value = ((PyStopIterationObject *)ev)->value; - Py_INCREF(value); - Py_DECREF(ev); - } - } - Py_XDECREF(et); - Py_XDECREF(tb); + PyObject *exc = PyErr_GetRaisedException(); + value = Py_NewRef(((PyStopIterationObject *)exc)->value); + Py_DECREF(exc); } else if (PyErr_Occurred()) { return -1; } if (value == NULL) { - value = Py_None; - Py_INCREF(value); + value = Py_NewRef(Py_None); } *pvalue = value; return 0; @@ -704,8 +682,7 @@ gen_repr(PyGenObject *gen) static PyObject * gen_get_name(PyGenObject *op, void *Py_UNUSED(ignored)) { - Py_INCREF(op->gi_name); - return op->gi_name; + return Py_NewRef(op->gi_name); } static int @@ -718,16 +695,14 @@ gen_set_name(PyGenObject *op, PyObject *value, void *Py_UNUSED(ignored)) "__name__ must be set to a string object"); return -1; } - Py_INCREF(value); - Py_XSETREF(op->gi_name, value); + Py_XSETREF(op->gi_name, Py_NewRef(value)); return 0; } static PyObject * gen_get_qualname(PyGenObject *op, void *Py_UNUSED(ignored)) { - Py_INCREF(op->gi_qualname); - return op->gi_qualname; + return Py_NewRef(op->gi_qualname); } static int @@ -740,8 +715,7 @@ gen_set_qualname(PyGenObject *op, PyObject *value, void *Py_UNUSED(ignored)) "__qualname__ must be set to a string object"); return -1; } - Py_INCREF(value); - Py_XSETREF(op->gi_qualname, value); + Py_XSETREF(op->gi_qualname, Py_NewRef(value)); return 0; } @@ -788,6 +762,21 @@ gen_getframe(PyGenObject *gen, void *Py_UNUSED(ignored)) return _gen_getframe(gen, "gi_frame"); } +static PyObject * +_gen_getcode(PyGenObject *gen, const char *const name) +{ + if (PySys_Audit("object.__getattr__", "Os", gen, name) < 0) { + return NULL; + } + return Py_NewRef(_PyGen_GetCode(gen)); +} + +static PyObject * +gen_getcode(PyGenObject *gen, void *Py_UNUSED(ignored)) +{ + return _gen_getcode(gen, "gi_code"); +} + static PyGetSetDef gen_getsetlist[] = { {"__name__", (getter)gen_get_name, (setter)gen_set_name, PyDoc_STR("name of the generator")}, @@ -798,11 +787,11 @@ static PyGetSetDef gen_getsetlist[] = { {"gi_running", (getter)gen_getrunning, NULL, NULL}, {"gi_frame", (getter)gen_getframe, NULL, NULL}, {"gi_suspended", (getter)gen_getsuspended, NULL, NULL}, + {"gi_code", (getter)gen_getcode, NULL, NULL}, {NULL} /* Sentinel */ }; static PyMemberDef gen_memberlist[] = { - {"gi_code", T_OBJECT, offsetof(PyGenObject, gi_code), READONLY|PY_AUDIT_READ}, {NULL} /* Sentinel */ }; @@ -811,8 +800,8 @@ gen_sizeof(PyGenObject *gen, PyObject *Py_UNUSED(ignored)) { Py_ssize_t res; res = offsetof(PyGenObject, gi_iframe) + offsetof(_PyInterpreterFrame, localsplus); - PyCodeObject *code = gen->gi_code; - res += (code->co_nlocalsplus+code->co_stacksize) * sizeof(PyObject *); + PyCodeObject *code = _PyGen_GetCode(gen); + res += _PyFrame_NumSlotsForCodeObject(code) * sizeof(PyObject *); return PyLong_FromSsize_t(res); } @@ -893,14 +882,12 @@ static PyObject * make_gen(PyTypeObject *type, PyFunctionObject *func) { PyCodeObject *code = (PyCodeObject *)func->func_code; - int slots = code->co_nlocalsplus + code->co_stacksize; + int slots = _PyFrame_NumSlotsForCodeObject(code); PyGenObject *gen = PyObject_GC_NewVar(PyGenObject, type, slots); if (gen == NULL) { return NULL; } gen->gi_frame_state = FRAME_CLEARED; - gen->gi_code = (PyCodeObject *)func->func_code; - Py_INCREF(gen->gi_code); gen->gi_weakreflist = NULL; gen->gi_exc_state.exc_value = NULL; gen->gi_exc_state.previous_item = NULL; @@ -947,8 +934,11 @@ _Py_MakeCoro(PyFunctionObject *func) if (origin_depth == 0) { ((PyCoroObject *)coro)->cr_origin_or_finalizer = NULL; } else { - assert(_PyEval_GetFrame()); - PyObject *cr_origin = compute_cr_origin(origin_depth, _PyEval_GetFrame()->previous); + _PyInterpreterFrame *frame = tstate->cframe->current_frame; + assert(frame); + assert(_PyFrame_IsIncomplete(frame)); + frame = _PyFrame_GetFirstComplete(frame->previous); + PyObject *cr_origin = compute_cr_origin(origin_depth, frame); ((PyCoroObject *)coro)->cr_origin_or_finalizer = cr_origin; if (!cr_origin) { Py_DECREF(coro); @@ -979,22 +969,18 @@ gen_new_with_qualname(PyTypeObject *type, PyFrameObject *f, f->f_frame = frame; frame->owner = FRAME_OWNED_BY_GENERATOR; assert(PyObject_GC_IsTracked((PyObject *)f)); - gen->gi_code = PyFrame_GetCode(f); - Py_INCREF(gen->gi_code); Py_DECREF(f); gen->gi_weakreflist = NULL; gen->gi_exc_state.exc_value = NULL; gen->gi_exc_state.previous_item = NULL; if (name != NULL) - gen->gi_name = name; + gen->gi_name = Py_NewRef(name); else - gen->gi_name = gen->gi_code->co_name; - Py_INCREF(gen->gi_name); + gen->gi_name = Py_NewRef(_PyGen_GetCode(gen)->co_name); if (qualname != NULL) - gen->gi_qualname = qualname; + gen->gi_qualname = Py_NewRef(qualname); else - gen->gi_qualname = gen->gi_code->co_qualname; - Py_INCREF(gen->gi_qualname); + gen->gi_qualname = Py_NewRef(_PyGen_GetCode(gen)->co_qualname); _PyObject_GC_TRACK(gen); return (PyObject *)gen; } @@ -1022,7 +1008,7 @@ static int gen_is_coroutine(PyObject *o) { if (PyGen_CheckExact(o)) { - PyCodeObject *code = (PyCodeObject *)((PyGenObject*)o)->gi_code; + PyCodeObject *code = _PyGen_GetCode((PyGenObject*)o); if (code->co_flags & CO_ITERABLE_COROUTINE) { return 1; } @@ -1046,8 +1032,7 @@ _PyCoro_GetAwaitableIter(PyObject *o) if (PyCoro_CheckExact(o) || gen_is_coroutine(o)) { /* 'o' is a coroutine. */ - Py_INCREF(o); - return o; + return Py_NewRef(o); } ot = Py_TYPE(o); @@ -1094,8 +1079,7 @@ coro_await(PyCoroObject *coro) if (cw == NULL) { return NULL; } - Py_INCREF(coro); - cw->cw_coroutine = coro; + cw->cw_coroutine = (PyCoroObject*)Py_NewRef(coro); _PyObject_GC_TRACK(cw); return (PyObject *)cw; } @@ -1133,6 +1117,12 @@ cr_getframe(PyCoroObject *coro, void *Py_UNUSED(ignored)) return _gen_getframe((PyGenObject *)coro, "cr_frame"); } +static PyObject * +cr_getcode(PyCoroObject *coro, void *Py_UNUSED(ignored)) +{ + return _gen_getcode((PyGenObject *)coro, "cr_code"); +} + static PyGetSetDef coro_getsetlist[] = { {"__name__", (getter)gen_get_name, (setter)gen_set_name, @@ -1143,12 +1133,12 @@ static PyGetSetDef coro_getsetlist[] = { PyDoc_STR("object being awaited on, or None")}, {"cr_running", (getter)cr_getrunning, NULL, NULL}, {"cr_frame", (getter)cr_getframe, NULL, NULL}, + {"cr_code", (getter)cr_getcode, NULL, NULL}, {"cr_suspended", (getter)cr_getsuspended, NULL, NULL}, {NULL} /* Sentinel */ }; static PyMemberDef coro_memberlist[] = { - {"cr_code", T_OBJECT, offsetof(PyCoroObject, cr_code), READONLY|PY_AUDIT_READ}, {"cr_origin", T_OBJECT, offsetof(PyCoroObject, cr_origin_or_finalizer), READONLY}, {NULL} /* Sentinel */ }; @@ -1162,7 +1152,10 @@ PyDoc_STRVAR(coro_throw_doc, throw(type[,value[,traceback]])\n\ \n\ Raise exception in coroutine, return next iterated value or raise\n\ -StopIteration."); +StopIteration.\n\ +the (type, val, tb) signature is deprecated, \n\ +and may be removed in a future version of Python."); + PyDoc_STRVAR(coro_close_doc, "close() -> raise GeneratorExit inside coroutine."); @@ -1331,7 +1324,7 @@ compute_cr_origin(int origin_depth, _PyInterpreterFrame *current_frame) /* First count how many frames we have */ int frame_count = 0; for (; frame && frame_count < origin_depth; ++frame_count) { - frame = frame->previous; + frame = _PyFrame_GetFirstComplete(frame->previous); } /* Now collect them */ @@ -1342,7 +1335,7 @@ compute_cr_origin(int origin_depth, _PyInterpreterFrame *current_frame) frame = current_frame; for (int i = 0; i < frame_count; ++i) { PyCodeObject *code = frame->f_code; - int line = _PyInterpreterFrame_GetLine(frame); + int line = PyUnstable_InterpreterFrame_GetLine(frame); PyObject *frameinfo = Py_BuildValue("OiO", code->co_filename, line, code->co_name); if (!frameinfo) { @@ -1350,7 +1343,7 @@ compute_cr_origin(int origin_depth, _PyInterpreterFrame *current_frame) return NULL; } PyTuple_SET_ITEM(cr_origin, i, frameinfo); - frame = frame->previous; + frame = _PyFrame_GetFirstComplete(frame->previous); } return cr_origin; @@ -1425,9 +1418,6 @@ typedef struct _PyAsyncGenWrappedValue { #define _PyAsyncGenWrappedValue_CheckExact(o) \ Py_IS_TYPE(o, &_PyAsyncGenWrappedValue_Type) -#define PyAsyncGenASend_CheckExact(o) \ - Py_IS_TYPE(o, &_PyAsyncGenASend_Type) - static int async_gen_traverse(PyAsyncGenObject *gen, visitproc visit, void *arg) @@ -1462,8 +1452,7 @@ async_gen_init_hooks(PyAsyncGenObject *o) finalizer = tstate->async_gen_finalizer; if (finalizer) { - Py_INCREF(finalizer); - o->ag_origin_or_finalizer = finalizer; + o->ag_origin_or_finalizer = Py_NewRef(finalizer); } firstiter = tstate->async_gen_firstiter; @@ -1515,6 +1504,14 @@ async_gen_aclose(PyAsyncGenObject *o, PyObject *arg) static PyObject * async_gen_athrow(PyAsyncGenObject *o, PyObject *args) { + if (PyTuple_GET_SIZE(args) > 1) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "the (type, exc, tb) signature of athrow() is deprecated, " + "use the single-arg signature instead.", + 1) < 0) { + return NULL; + } + } if (async_gen_init_hooks(o)) { return NULL; } @@ -1527,6 +1524,21 @@ ag_getframe(PyAsyncGenObject *ag, void *Py_UNUSED(ignored)) return _gen_getframe((PyGenObject *)ag, "ag_frame"); } +static PyObject * +ag_getcode(PyGenObject *gen, void *Py_UNUSED(ignored)) +{ + return _gen_getcode(gen, "ag_code"); +} + +static PyObject * +ag_getsuspended(PyAsyncGenObject *ag, void *Py_UNUSED(ignored)) +{ + if (ag->ag_frame_state == FRAME_SUSPENDED) { + Py_RETURN_TRUE; + } + Py_RETURN_FALSE; +} + static PyGetSetDef async_gen_getsetlist[] = { {"__name__", (getter)gen_get_name, (setter)gen_set_name, PyDoc_STR("name of the async generator")}, @@ -1535,13 +1547,14 @@ static PyGetSetDef async_gen_getsetlist[] = { {"ag_await", (getter)coro_get_cr_await, NULL, PyDoc_STR("object being awaited on, or None")}, {"ag_frame", (getter)ag_getframe, NULL, NULL}, + {"ag_code", (getter)ag_getcode, NULL, NULL}, + {"ag_suspended", (getter)ag_getsuspended, NULL, NULL}, {NULL} /* Sentinel */ }; static PyMemberDef async_gen_memberlist[] = { {"ag_running", T_BOOL, offsetof(PyAsyncGenObject, ag_running_async), READONLY}, - {"ag_code", T_OBJECT, offsetof(PyAsyncGenObject, ag_code), READONLY|PY_AUDIT_READ}, {NULL} /* Sentinel */ }; @@ -1552,7 +1565,12 @@ PyDoc_STRVAR(async_asend_doc, "asend(v) -> send 'v' in generator."); PyDoc_STRVAR(async_athrow_doc, -"athrow(typ[,val[,tb]]) -> raise exception in generator."); +"athrow(value)\n\ +athrow(type[,value[,tb]])\n\ +\n\ +raise exception in generator.\n\ +the (type, val, tb) signature is deprecated, \n\ +and may be removed in a future version of Python."); static PyMethodDef async_gen_methods[] = { {"asend", (PyCFunction)async_gen_asend, METH_O, async_asend_doc}, @@ -1912,11 +1930,9 @@ async_gen_asend_new(PyAsyncGenObject *gen, PyObject *sendval) } } - Py_INCREF(gen); - o->ags_gen = gen; + o->ags_gen = (PyAsyncGenObject*)Py_NewRef(gen); - Py_XINCREF(sendval); - o->ags_sendval = sendval; + o->ags_sendval = Py_XNewRef(sendval); o->ags_state = AWAITABLE_STATE_INIT; @@ -2005,13 +2021,13 @@ PyTypeObject _PyAsyncGenWrappedValue_Type = { PyObject * -_PyAsyncGenValueWrapperNew(PyObject *val) +_PyAsyncGenValueWrapperNew(PyThreadState *tstate, PyObject *val) { _PyAsyncGenWrappedValue *o; assert(val); #if _PyAsyncGen_MAXFREELIST > 0 - struct _Py_async_gen_state *state = get_async_gen_state(); + struct _Py_async_gen_state *state = &tstate->interp->async_gen; #ifdef Py_DEBUG // _PyAsyncGenValueWrapperNew() must not be called after _PyAsyncGen_Fini() assert(state->value_numfree != -1); @@ -2032,8 +2048,7 @@ _PyAsyncGenValueWrapperNew(PyObject *val) return NULL; } } - o->agw_val = val; - Py_INCREF(val); + o->agw_val = Py_NewRef(val); _PyObject_GC_TRACK((PyObject*)o); return (PyObject*)o; } @@ -2316,11 +2331,9 @@ async_gen_athrow_new(PyAsyncGenObject *gen, PyObject *args) if (o == NULL) { return NULL; } - o->agt_gen = gen; - o->agt_args = args; + o->agt_gen = (PyAsyncGenObject*)Py_NewRef(gen); + o->agt_args = Py_XNewRef(args); o->agt_state = AWAITABLE_STATE_INIT; - Py_INCREF(gen); - Py_XINCREF(args); _PyObject_GC_TRACK((PyObject*)o); return (PyObject*)o; } diff --git a/Objects/interpreteridobject.c b/Objects/interpreteridobject.c index 7b3e31be..46239100 100644 --- a/Objects/interpreteridobject.c +++ b/Objects/interpreteridobject.c @@ -3,7 +3,7 @@ #include "Python.h" #include "pycore_abstract.h" // _PyIndex_Check() #include "pycore_interp.h" // _PyInterpreterState_LookUpID() -#include "pycore_interpreteridobject.h" +#include "interpreteridobject.h" typedef struct interpid { diff --git a/Objects/iterobject.c b/Objects/iterobject.c index 1732a037..7cb17a6c 100644 --- a/Objects/iterobject.c +++ b/Objects/iterobject.c @@ -23,8 +23,7 @@ PySeqIter_New(PyObject *seq) if (it == NULL) return NULL; it->it_index = 0; - Py_INCREF(seq); - it->it_seq = seq; + it->it_seq = Py_NewRef(seq); _PyObject_GC_TRACK(it); return (PyObject *)it; } @@ -103,11 +102,16 @@ PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list( static PyObject * iter_reduce(seqiterobject *it, PyObject *Py_UNUSED(ignored)) { + PyObject *iter = _PyEval_GetBuiltin(&_Py_ID(iter)); + + /* _PyEval_GetBuiltin can invoke arbitrary code, + * call must be before access of iterator pointers. + * see issue #101765 */ + if (it->it_seq != NULL) - return Py_BuildValue("N(O)n", _PyEval_GetBuiltin(&_Py_ID(iter)), - it->it_seq, it->it_index); + return Py_BuildValue("N(O)n", iter, it->it_seq, it->it_index); else - return Py_BuildValue("N(())", _PyEval_GetBuiltin(&_Py_ID(iter))); + return Py_BuildValue("N(())", iter); } PyDoc_STRVAR(reduce_doc, "Return state information for pickling."); @@ -183,10 +187,8 @@ PyCallIter_New(PyObject *callable, PyObject *sentinel) it = PyObject_GC_New(calliterobject, &PyCallIter_Type); if (it == NULL) return NULL; - Py_INCREF(callable); - it->it_callable = callable; - Py_INCREF(sentinel); - it->it_sentinel = sentinel; + it->it_callable = Py_NewRef(callable); + it->it_sentinel = Py_NewRef(sentinel); _PyObject_GC_TRACK(it); return (PyObject *)it; } @@ -217,7 +219,7 @@ calliter_iternext(calliterobject *it) } result = _PyObject_CallNoArgs(it->it_callable); - if (result != NULL) { + if (result != NULL && it->it_sentinel != NULL){ int ok; ok = PyObject_RichCompareBool(it->it_sentinel, result, Py_EQ); @@ -225,7 +227,6 @@ calliter_iternext(calliterobject *it) return result; /* Common case, fast path */ } - Py_DECREF(result); if (ok > 0) { Py_CLEAR(it->it_callable); Py_CLEAR(it->it_sentinel); @@ -236,17 +237,23 @@ calliter_iternext(calliterobject *it) Py_CLEAR(it->it_callable); Py_CLEAR(it->it_sentinel); } + Py_XDECREF(result); return NULL; } static PyObject * calliter_reduce(calliterobject *it, PyObject *Py_UNUSED(ignored)) { + PyObject *iter = _PyEval_GetBuiltin(&_Py_ID(iter)); + + /* _PyEval_GetBuiltin can invoke arbitrary code, + * call must be before access of iterator pointers. + * see issue #101765 */ + if (it->it_callable != NULL && it->it_sentinel != NULL) - return Py_BuildValue("N(OO)", _PyEval_GetBuiltin(&_Py_ID(iter)), - it->it_callable, it->it_sentinel); + return Py_BuildValue("N(OO)", iter, it->it_callable, it->it_sentinel); else - return Py_BuildValue("N(())", _PyEval_GetBuiltin(&_Py_ID(iter))); + return Py_BuildValue("N(())", iter); } static PyMethodDef calliter_methods[] = { @@ -428,8 +435,13 @@ return next yielded value or raise StopIteration."); PyDoc_STRVAR(throw_doc, -"throw(typ[,val[,tb]]) -> raise exception in the wrapped iterator,\n\ -return next yielded value or raise StopIteration."); +"throw(value)\n\ +throw(typ[,val[,tb]])\n\ +\n\ +raise exception in the wrapped iterator, return next yielded value\n\ +or raise StopIteration.\n\ +the (type, val, tb) signature is deprecated, \n\ +and may be removed in a future version of Python."); PyDoc_STRVAR(close_doc, @@ -491,10 +503,8 @@ PyAnextAwaitable_New(PyObject *awaitable, PyObject *default_value) if (anext == NULL) { return NULL; } - Py_INCREF(awaitable); - anext->wrapped = awaitable; - Py_INCREF(default_value); - anext->default_value = default_value; + anext->wrapped = Py_NewRef(awaitable); + anext->default_value = Py_NewRef(default_value); _PyObject_GC_TRACK(anext); return (PyObject *)anext; } diff --git a/Objects/listobject.c b/Objects/listobject.c index 19009133..f1edfb3a 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -3,7 +3,8 @@ #include "Python.h" #include "pycore_abstract.h" // _PyIndex_Check() #include "pycore_interp.h" // PyInterpreterState.list -#include "pycore_list.h" // struct _Py_list_state +#include "pycore_list.h" // struct _Py_list_state, _PyListIterObject +#include "pycore_long.h" // _PyLong_DigitCount #include "pycore_object.h" // _PyObject_GC_TRACK() #include "pycore_tuple.h" // _PyTuple_FromArray() #include <stddef.h> @@ -299,8 +300,7 @@ ins1(PyListObject *self, Py_ssize_t where, PyObject *v) items = self->ob_item; for (i = n; --i >= where; ) items[i+1] = items[i]; - Py_INCREF(v); - items[where] = v; + items[where] = Py_NewRef(v); return 0; } @@ -332,8 +332,7 @@ int PyList_Append(PyObject *op, PyObject *newitem) { if (PyList_Check(op) && (newitem != NULL)) { - Py_INCREF(newitem); - return _PyList_AppendTakeRef((PyListObject *)op, newitem); + return _PyList_AppendTakeRef((PyListObject *)op, Py_NewRef(newitem)); } PyErr_BadInternalCall(); return -1; @@ -461,8 +460,7 @@ list_item(PyListObject *a, Py_ssize_t i) PyErr_SetObject(PyExc_IndexError, &_Py_STR(list_err)); return NULL; } - Py_INCREF(a->ob_item[i]); - return a->ob_item[i]; + return Py_NewRef(a->ob_item[i]); } static PyObject * @@ -483,8 +481,7 @@ list_slice(PyListObject *a, Py_ssize_t ilow, Py_ssize_t ihigh) dest = np->ob_item; for (i = 0; i < len; i++) { PyObject *v = src[i]; - Py_INCREF(v); - dest[i] = v; + dest[i] = Py_NewRef(v); } Py_SET_SIZE(np, len); return (PyObject *)np; @@ -539,15 +536,13 @@ list_concat(PyListObject *a, PyObject *bb) dest = np->ob_item; for (i = 0; i < Py_SIZE(a); i++) { PyObject *v = src[i]; - Py_INCREF(v); - dest[i] = v; + dest[i] = Py_NewRef(v); } src = b->ob_item; dest = np->ob_item + Py_SIZE(a); for (i = 0; i < Py_SIZE(b); i++) { PyObject *v = src[i]; - Py_INCREF(v); - dest[i] = v; + dest[i] = Py_NewRef(v); } Py_SET_SIZE(np, size); return (PyObject *)np; @@ -557,47 +552,41 @@ list_concat(PyListObject *a, PyObject *bb) static PyObject * list_repeat(PyListObject *a, Py_ssize_t n) { - Py_ssize_t size; - PyListObject *np; - if (n < 0) - n = 0; - if (n > 0 && Py_SIZE(a) > PY_SSIZE_T_MAX / n) - return PyErr_NoMemory(); - size = Py_SIZE(a) * n; - if (size == 0) + const Py_ssize_t input_size = Py_SIZE(a); + if (input_size == 0 || n <= 0) return PyList_New(0); - np = (PyListObject *) list_new_prealloc(size); + assert(n > 0); + + if (input_size > PY_SSIZE_T_MAX / n) + return PyErr_NoMemory(); + Py_ssize_t output_size = input_size * n; + + PyListObject *np = (PyListObject *) list_new_prealloc(output_size); if (np == NULL) return NULL; + PyObject **dest = np->ob_item; - PyObject **dest_end = dest + size; - if (Py_SIZE(a) == 1) { + if (input_size == 1) { PyObject *elem = a->ob_item[0]; - Py_SET_REFCNT(elem, Py_REFCNT(elem) + n); -#ifdef Py_REF_DEBUG - _Py_RefTotal += n; -#endif + _Py_RefcntAdd(elem, n); + PyObject **dest_end = dest + output_size; while (dest < dest_end) { *dest++ = elem; } } else { PyObject **src = a->ob_item; - PyObject **src_end = src + Py_SIZE(a); + PyObject **src_end = src + input_size; while (src < src_end) { - Py_SET_REFCNT(*src, Py_REFCNT(*src) + n); -#ifdef Py_REF_DEBUG - _Py_RefTotal += n; -#endif - *dest++ = *src++; - } - // Now src chases after dest in the same buffer - src = np->ob_item; - while (dest < dest_end) { + _Py_RefcntAdd(*src, n); *dest++ = *src++; } + + _Py_memory_repeat((char *)np->ob_item, sizeof(PyObject *)*output_size, + sizeof(PyObject *)*input_size); } - Py_SET_SIZE(np, size); + + Py_SET_SIZE(np, output_size); return (PyObject *) np; } @@ -722,8 +711,7 @@ list_ass_slice(PyListObject *a, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *v) } for (k = 0; k < n; k++, ilow++) { PyObject *w = vitem[k]; - Py_XINCREF(w); - item[ilow] = w; + item[ilow] = Py_XNewRef(w); } for (k = norig - 1; k >= 0; --k) Py_XDECREF(recycle[k]); @@ -749,40 +737,32 @@ PyList_SetSlice(PyObject *a, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *v) static PyObject * list_inplace_repeat(PyListObject *self, Py_ssize_t n) { - PyObject **items; - Py_ssize_t size, i, j, p; - - - size = PyList_GET_SIZE(self); - if (size == 0 || n == 1) { - Py_INCREF(self); - return (PyObject *)self; + Py_ssize_t input_size = PyList_GET_SIZE(self); + if (input_size == 0 || n == 1) { + return Py_NewRef(self); } if (n < 1) { (void)_list_clear(self); - Py_INCREF(self); - return (PyObject *)self; + return Py_NewRef(self); } - if (size > PY_SSIZE_T_MAX / n) { + if (input_size > PY_SSIZE_T_MAX / n) { return PyErr_NoMemory(); } + Py_ssize_t output_size = input_size * n; - if (list_resize(self, size*n) < 0) + if (list_resize(self, output_size) < 0) return NULL; - p = size; - items = self->ob_item; - for (i = 1; i < n; i++) { /* Start counting at 1, not 0 */ - for (j = 0; j < size; j++) { - PyObject *o = items[j]; - Py_INCREF(o); - items[p++] = o; - } + PyObject **items = self->ob_item; + for (Py_ssize_t j = 0; j < input_size; j++) { + _Py_RefcntAdd(items[j], n-1); } - Py_INCREF(self); - return (PyObject *)self; + _Py_memory_repeat((char *)items, sizeof(PyObject *)*output_size, + sizeof(PyObject *)*input_size); + + return Py_NewRef(self); } static int @@ -795,8 +775,7 @@ list_ass_item(PyListObject *a, Py_ssize_t i, PyObject *v) } if (v == NULL) return list_ass_slice(a, i, i+1, v); - Py_INCREF(v); - Py_SETREF(a->ob_item[i], v); + Py_SETREF(a->ob_item[i], Py_NewRef(v)); return 0; } @@ -924,8 +903,7 @@ list_extend(PyListObject *self, PyObject *iterable) dest = self->ob_item + m; for (i = 0; i < n; i++) { PyObject *o = src[i]; - Py_INCREF(o); - dest[i] = o; + dest[i] = Py_NewRef(o); } Py_DECREF(iterable); Py_RETURN_NONE; @@ -1013,8 +991,7 @@ list_inplace_concat(PyListObject *self, PyObject *other) if (result == NULL) return result; Py_DECREF(result); - Py_INCREF(self); - return (PyObject *)self; + return Py_NewRef(self); } /*[clinic input] @@ -1046,21 +1023,29 @@ list_pop_impl(PyListObject *self, Py_ssize_t index) PyErr_SetString(PyExc_IndexError, "pop index out of range"); return NULL; } - v = self->ob_item[index]; - if (index == Py_SIZE(self) - 1) { - status = list_resize(self, Py_SIZE(self) - 1); - if (status >= 0) - return v; /* and v now owns the reference the list had */ - else - return NULL; + + PyObject **items = self->ob_item; + v = items[index]; + const Py_ssize_t size_after_pop = Py_SIZE(self) - 1; + if (size_after_pop == 0) { + Py_INCREF(v); + status = _list_clear(self); + } + else { + if ((size_after_pop - index) > 0) { + memmove(&items[index], &items[index+1], (size_after_pop - index) * sizeof(PyObject *)); + } + status = list_resize(self, size_after_pop); + } + if (status >= 0) { + return v; // and v now owns the reference the list had } - Py_INCREF(v); - status = list_ass_slice(self, index, index+1, (PyObject *)NULL); - if (status < 0) { - Py_DECREF(v); + else { + // list resize failed, need to restore + memmove(&items[index+1], &items[index], (size_after_pop - index)* sizeof(PyObject *)); + items[index] = v; return NULL; } - return v; } /* Reverse a slice of a list in place, from lo up to (exclusive) hi. */ @@ -2160,24 +2145,21 @@ unsafe_latin_compare(PyObject *v, PyObject *w, MergeState *ms) static int unsafe_long_compare(PyObject *v, PyObject *w, MergeState *ms) { - PyLongObject *vl, *wl; sdigit v0, w0; int res; + PyLongObject *vl, *wl; + intptr_t v0, w0; + int res; /* Modified from Objects/longobject.c:long_compare, assuming: */ assert(Py_IS_TYPE(v, &PyLong_Type)); assert(Py_IS_TYPE(w, &PyLong_Type)); - assert(Py_ABS(Py_SIZE(v)) <= 1); - assert(Py_ABS(Py_SIZE(w)) <= 1); + assert(_PyLong_IsCompact((PyLongObject *)v)); + assert(_PyLong_IsCompact((PyLongObject *)w)); vl = (PyLongObject*)v; wl = (PyLongObject*)w; - v0 = Py_SIZE(vl) == 0 ? 0 : (sdigit)vl->ob_digit[0]; - w0 = Py_SIZE(wl) == 0 ? 0 : (sdigit)wl->ob_digit[0]; - - if (Py_SIZE(vl) < 0) - v0 = -v0; - if (Py_SIZE(wl) < 0) - w0 = -w0; + v0 = _PyLong_CompactValue(vl); + w0 = _PyLong_CompactValue(wl); res = v0 < w0; assert(res == PyObject_RichCompareBool(v, w, Py_LT)); @@ -2251,7 +2233,7 @@ list.sort * key as keyfunc: object = None - reverse: bool(accept={int}) = False + reverse: bool = False Sort the list in ascending order and return None. @@ -2266,7 +2248,7 @@ The reverse flag can be set to sort in descending order. static PyObject * list_sort_impl(PyListObject *self, PyObject *keyfunc, int reverse) -/*[clinic end generated code: output=57b9f9c5e23fbe42 input=cb56cd179a713060]*/ +/*[clinic end generated code: output=57b9f9c5e23fbe42 input=a74c4cd3ec6b5c08]*/ { MergeState ms; Py_ssize_t nremaining; @@ -2375,7 +2357,7 @@ list_sort_impl(PyListObject *self, PyObject *keyfunc, int reverse) if (keys_are_all_same_type) { if (key_type == &PyLong_Type && ints_are_bounded && - Py_ABS(Py_SIZE(key)) > 1) { + !_PyLong_IsCompact((PyLongObject *)key)) { ints_are_bounded = 0; } @@ -2523,8 +2505,7 @@ keyfunc_fail: } PyMem_Free(final_ob_item); } - Py_XINCREF(result); - return result; + return Py_XNewRef(result); } #undef IFLT #undef ISLT @@ -2582,6 +2563,27 @@ PyList_AsTuple(PyObject *v) return _PyTuple_FromArray(((PyListObject *)v)->ob_item, Py_SIZE(v)); } +PyObject * +_PyList_FromArraySteal(PyObject *const *src, Py_ssize_t n) +{ + if (n == 0) { + return PyList_New(0); + } + + PyListObject *list = (PyListObject *)PyList_New(n); + if (list == NULL) { + for (Py_ssize_t i = 0; i < n; i++) { + Py_DECREF(src[i]); + } + return NULL; + } + + PyObject **dst = list->ob_item; + memcpy(dst, src, n * sizeof(PyObject *)); + + return (PyObject *)list; +} + /*[clinic input] list.index @@ -2831,17 +2833,17 @@ static PyObject * list___sizeof___impl(PyListObject *self) /*[clinic end generated code: output=3417541f95f9a53e input=b8030a5d5ce8a187]*/ { - Py_ssize_t res; - - res = _PyObject_SIZE(Py_TYPE(self)) + self->allocated * sizeof(void*); - return PyLong_FromSsize_t(res); + size_t res = _PyObject_SIZE(Py_TYPE(self)); + res += (size_t)self->allocated * sizeof(void*); + return PyLong_FromSize_t(res); } static PyObject *list_iter(PyObject *seq); static PyObject *list_subscript(PyListObject*, PyObject*); static PyMethodDef list_methods[] = { - {"__getitem__", (PyCFunction)list_subscript, METH_O|METH_COEXIST, "x.__getitem__(y) <==> x[y]"}, + {"__getitem__", (PyCFunction)list_subscript, METH_O|METH_COEXIST, + PyDoc_STR("__getitem__($self, index, /)\n--\n\nReturn self[index].")}, LIST___REVERSED___METHODDEF LIST___SIZEOF___METHODDEF LIST_CLEAR_METHODDEF @@ -2911,8 +2913,7 @@ list_subscript(PyListObject* self, PyObject* item) dest = ((PyListObject *)result)->ob_item; for (cur = start, i = 0; i < slicelength; cur += (size_t)step, i++) { - it = src[cur]; - Py_INCREF(it); + it = Py_NewRef(src[cur]); dest[i] = it; } Py_SET_SIZE(result, slicelength); @@ -3067,8 +3068,7 @@ list_ass_subscript(PyListObject* self, PyObject* item, PyObject* value) for (cur = start, i = 0; i < slicelength; cur += (size_t)step, i++) { garbage[i] = selfitems[cur]; - ins = seqitems[i]; - Py_INCREF(ins); + ins = Py_NewRef(seqitems[i]); selfitems[cur] = ins; } @@ -3143,19 +3143,13 @@ PyTypeObject PyList_Type = { /*********************** List Iterator **************************/ -typedef struct { - PyObject_HEAD - Py_ssize_t it_index; - PyListObject *it_seq; /* Set to NULL when iterator is exhausted */ -} listiterobject; - -static void listiter_dealloc(listiterobject *); -static int listiter_traverse(listiterobject *, visitproc, void *); -static PyObject *listiter_next(listiterobject *); -static PyObject *listiter_len(listiterobject *, PyObject *); +static void listiter_dealloc(_PyListIterObject *); +static int listiter_traverse(_PyListIterObject *, visitproc, void *); +static PyObject *listiter_next(_PyListIterObject *); +static PyObject *listiter_len(_PyListIterObject *, PyObject *); static PyObject *listiter_reduce_general(void *_it, int forward); -static PyObject *listiter_reduce(listiterobject *, PyObject *); -static PyObject *listiter_setstate(listiterobject *, PyObject *state); +static PyObject *listiter_reduce(_PyListIterObject *, PyObject *); +static PyObject *listiter_setstate(_PyListIterObject *, PyObject *state); PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it))."); PyDoc_STRVAR(reduce_doc, "Return state information for pickling."); @@ -3171,7 +3165,7 @@ static PyMethodDef listiter_methods[] = { PyTypeObject PyListIter_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "list_iterator", /* tp_name */ - sizeof(listiterobject), /* tp_basicsize */ + sizeof(_PyListIterObject), /* tp_basicsize */ 0, /* tp_itemsize */ /* methods */ (destructor)listiter_dealloc, /* tp_dealloc */ @@ -3205,24 +3199,23 @@ PyTypeObject PyListIter_Type = { static PyObject * list_iter(PyObject *seq) { - listiterobject *it; + _PyListIterObject *it; if (!PyList_Check(seq)) { PyErr_BadInternalCall(); return NULL; } - it = PyObject_GC_New(listiterobject, &PyListIter_Type); + it = PyObject_GC_New(_PyListIterObject, &PyListIter_Type); if (it == NULL) return NULL; it->it_index = 0; - Py_INCREF(seq); - it->it_seq = (PyListObject *)seq; + it->it_seq = (PyListObject *)Py_NewRef(seq); _PyObject_GC_TRACK(it); return (PyObject *)it; } static void -listiter_dealloc(listiterobject *it) +listiter_dealloc(_PyListIterObject *it) { _PyObject_GC_UNTRACK(it); Py_XDECREF(it->it_seq); @@ -3230,14 +3223,14 @@ listiter_dealloc(listiterobject *it) } static int -listiter_traverse(listiterobject *it, visitproc visit, void *arg) +listiter_traverse(_PyListIterObject *it, visitproc visit, void *arg) { Py_VISIT(it->it_seq); return 0; } static PyObject * -listiter_next(listiterobject *it) +listiter_next(_PyListIterObject *it) { PyListObject *seq; PyObject *item; @@ -3251,8 +3244,7 @@ listiter_next(listiterobject *it) if (it->it_index < PyList_GET_SIZE(seq)) { item = PyList_GET_ITEM(seq, it->it_index); ++it->it_index; - Py_INCREF(item); - return item; + return Py_NewRef(item); } it->it_seq = NULL; @@ -3261,7 +3253,7 @@ listiter_next(listiterobject *it) } static PyObject * -listiter_len(listiterobject *it, PyObject *Py_UNUSED(ignored)) +listiter_len(_PyListIterObject *it, PyObject *Py_UNUSED(ignored)) { Py_ssize_t len; if (it->it_seq) { @@ -3273,13 +3265,13 @@ listiter_len(listiterobject *it, PyObject *Py_UNUSED(ignored)) } static PyObject * -listiter_reduce(listiterobject *it, PyObject *Py_UNUSED(ignored)) +listiter_reduce(_PyListIterObject *it, PyObject *Py_UNUSED(ignored)) { return listiter_reduce_general(it, 1); } static PyObject * -listiter_setstate(listiterobject *it, PyObject *state) +listiter_setstate(_PyListIterObject *it, PyObject *state) { Py_ssize_t index = PyLong_AsSsize_t(state); if (index == -1 && PyErr_Occurred()) @@ -3366,8 +3358,7 @@ list___reversed___impl(PyListObject *self) return NULL; assert(PyList_Check(self)); it->it_index = PyList_GET_SIZE(self) - 1; - Py_INCREF(self); - it->it_seq = self; + it->it_seq = (PyListObject*)Py_NewRef(self); PyObject_GC_Track(it); return (PyObject *)it; } @@ -3405,8 +3396,7 @@ listreviter_next(listreviterobject *it) if (index>=0 && index < PyList_GET_SIZE(seq)) { item = PyList_GET_ITEM(seq, index); it->it_index--; - Py_INCREF(item); - return item; + return Py_NewRef(item); } it->it_index = -1; it->it_seq = NULL; @@ -3452,19 +3442,31 @@ listiter_reduce_general(void *_it, int forward) { PyObject *list; + /* _PyEval_GetBuiltin can invoke arbitrary code, + * call must be before access of iterator pointers. + * see issue #101765 */ + /* the objects are not the same, index is of different types! */ if (forward) { - listiterobject *it = (listiterobject *)_it; + PyObject *iter = _PyEval_GetBuiltin(&_Py_ID(iter)); + if (!iter) { + return NULL; + } + _PyListIterObject *it = (_PyListIterObject *)_it; if (it->it_seq) { - return Py_BuildValue("N(O)n", _PyEval_GetBuiltin(&_Py_ID(iter)), - it->it_seq, it->it_index); + return Py_BuildValue("N(O)n", iter, it->it_seq, it->it_index); } + Py_DECREF(iter); } else { + PyObject *reversed = _PyEval_GetBuiltin(&_Py_ID(reversed)); + if (!reversed) { + return NULL; + } listreviterobject *it = (listreviterobject *)_it; if (it->it_seq) { - return Py_BuildValue("N(O)n", _PyEval_GetBuiltin(&_Py_ID(reversed)), - it->it_seq, it->it_index); + return Py_BuildValue("N(O)n", reversed, it->it_seq, it->it_index); } + Py_DECREF(reversed); } /* empty iterator, create an empty list */ list = PyList_New(0); diff --git a/Objects/longobject.c b/Objects/longobject.c index 84c05e8a..5d9b4138 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -6,10 +6,9 @@ #include "pycore_bitutils.h" // _Py_popcount32() #include "pycore_initconfig.h" // _PyStatus_OK() #include "pycore_long.h" // _Py_SmallInts -#include "pycore_object.h" // _PyObject_InitVar() -#include "pycore_pystate.h" // _Py_IsMainInterpreter() +#include "pycore_object.h" // _PyObject_Init() #include "pycore_runtime.h" // _PY_NSMALLPOSINTS -#include "pycore_structseq.h" // _PyStructSequence_FiniType() +#include "pycore_structseq.h" // _PyStructSequence_FiniBuiltin() #include <ctype.h> #include <float.h> @@ -22,16 +21,7 @@ class int "PyObject *" "&PyLong_Type" [clinic start generated code]*/ /*[clinic end generated code: output=da39a3ee5e6b4b0d input=ec0275e3422a36e3]*/ -/* Is this PyLong of size 1, 0 or -1? */ -#define IS_MEDIUM_VALUE(x) (((size_t)Py_SIZE(x)) + 1U < 3U) - -/* convert a PyLong of size 1, 0 or -1 to a C integer */ -static inline stwodigits -medium_value(PyLongObject *x) -{ - assert(IS_MEDIUM_VALUE(x)); - return ((stwodigits)Py_SIZE(x)) * x->ob_digit[0]; -} +#define medium_value(x) ((stwodigits)_PyLong_CompactValue(x)) #define IS_SMALL_INT(ival) (-_PY_NSMALLNEGINTS <= (ival) && (ival) < _PY_NSMALLPOSINTS) #define IS_SMALL_UINT(ival) ((ival) < _PY_NSMALLPOSINTS) @@ -39,6 +29,9 @@ medium_value(PyLongObject *x) #define _MAX_STR_DIGITS_ERROR_FMT_TO_INT "Exceeds the limit (%d digits) for integer string conversion: value has %zd digits; use sys.set_int_max_str_digits() to increase the limit" #define _MAX_STR_DIGITS_ERROR_FMT_TO_STR "Exceeds the limit (%d digits) for integer string conversion; use sys.set_int_max_str_digits() to increase the limit" +/* If defined, use algorithms from the _pylong.py module */ +#define WITH_PYLONG_MODULE 1 + static inline void _Py_DECREF_INT(PyLongObject *op) { @@ -58,15 +51,13 @@ static PyObject * get_small_int(sdigit ival) { assert(IS_SMALL_INT(ival)); - PyObject *v = (PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS + ival]; - Py_INCREF(v); - return v; + return (PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS + ival]; } static PyLongObject * maybe_small_long(PyLongObject *v) { - if (v && IS_MEDIUM_VALUE(v)) { + if (v && _PyLong_IsCompact(v)) { stwodigits ival = medium_value(v); if (IS_SMALL_INT(ival)) { _Py_DECREF_INT(v); @@ -124,13 +115,18 @@ maybe_small_long(PyLongObject *v) static PyLongObject * long_normalize(PyLongObject *v) { - Py_ssize_t j = Py_ABS(Py_SIZE(v)); + Py_ssize_t j = _PyLong_DigitCount(v); Py_ssize_t i = j; - while (i > 0 && v->ob_digit[i-1] == 0) + while (i > 0 && v->long_value.ob_digit[i-1] == 0) --i; if (i != j) { - Py_SET_SIZE(v, (Py_SIZE(v) < 0) ? -(i) : i); + if (i == 0) { + _PyLong_SetSignAndDigitCount(v, 0, 0); + } + else { + _PyLong_SetDigitCount(v, i); + } } return v; } @@ -139,11 +135,12 @@ long_normalize(PyLongObject *v) Return NULL and set exception if we run out of memory. */ #define MAX_LONG_DIGITS \ - ((PY_SSIZE_T_MAX - offsetof(PyLongObject, ob_digit))/sizeof(digit)) + ((PY_SSIZE_T_MAX - offsetof(PyLongObject, long_value.ob_digit))/sizeof(digit)) PyLongObject * _PyLong_New(Py_ssize_t size) { + assert(size >= 0); PyLongObject *result; if (size > (Py_ssize_t)MAX_LONG_DIGITS) { PyErr_SetString(PyExc_OverflowError, @@ -155,43 +152,53 @@ _PyLong_New(Py_ssize_t size) Py_ssize_t ndigits = size ? size : 1; /* Number of bytes needed is: offsetof(PyLongObject, ob_digit) + sizeof(digit)*size. Previous incarnations of this code used - sizeof(PyVarObject) instead of the offsetof, but this risks being - incorrect in the presence of padding between the PyVarObject header + sizeof() instead of the offsetof, but this risks being + incorrect in the presence of padding between the header and the digits. */ - result = PyObject_Malloc(offsetof(PyLongObject, ob_digit) + + result = PyObject_Malloc(offsetof(PyLongObject, long_value.ob_digit) + ndigits*sizeof(digit)); if (!result) { PyErr_NoMemory(); return NULL; } - _PyObject_InitVar((PyVarObject*)result, &PyLong_Type, size); + _PyLong_SetSignAndDigitCount(result, size != 0, size); + _PyObject_Init((PyObject*)result, &PyLong_Type); + /* The digit has to be initialized explicitly to avoid + * use-of-uninitialized-value. */ + result->long_value.ob_digit[0] = 0; + return result; +} + +PyLongObject * +_PyLong_FromDigits(int negative, Py_ssize_t digit_count, digit *digits) +{ + assert(digit_count >= 0); + if (digit_count == 0) { + return (PyLongObject *)Py_NewRef(_PyLong_GetZero()); + } + PyLongObject *result = _PyLong_New(digit_count); + if (result == NULL) { + PyErr_NoMemory(); + return NULL; + } + _PyLong_SetSignAndDigitCount(result, negative?-1:1, digit_count); + memcpy(result->long_value.ob_digit, digits, digit_count * sizeof(digit)); return result; } PyObject * _PyLong_Copy(PyLongObject *src) { - PyLongObject *result; - Py_ssize_t i; - assert(src != NULL); - i = Py_SIZE(src); - if (i < 0) - i = -(i); - if (i < 2) { + + if (_PyLong_IsCompact(src)) { stwodigits ival = medium_value(src); if (IS_SMALL_INT(ival)) { return get_small_int((sdigit)ival); } } - result = _PyLong_New(i); - if (result != NULL) { - Py_SET_SIZE(result, Py_SIZE(src)); - while (--i >= 0) { - result->ob_digit[i] = src->ob_digit[i]; - } - } - return (PyObject *)result; + Py_ssize_t size = _PyLong_DigitCount(src); + return (PyObject *)_PyLong_FromDigits(_PyLong_IsNegative(src), size, src->long_value.ob_digit); } static PyObject * @@ -205,10 +212,10 @@ _PyLong_FromMedium(sdigit x) PyErr_NoMemory(); return NULL; } - Py_ssize_t sign = x < 0 ? -1: 1; digit abs_x = x < 0 ? -x : x; - _PyObject_InitVar((PyVarObject*)v, &PyLong_Type, sign); - v->ob_digit[0] = abs_x; + _PyLong_SetSignAndDigitCount(v, x<0?-1:1, 1); + _PyObject_Init((PyObject*)v, &PyLong_Type); + v->long_value.ob_digit[0] = abs_x; return (PyObject*)v; } @@ -239,8 +246,8 @@ _PyLong_FromLarge(stwodigits ival) } PyLongObject *v = _PyLong_New(ndigits); if (v != NULL) { - digit *p = v->ob_digit; - Py_SET_SIZE(v, ndigits * sign); + digit *p = v->long_value.ob_digit; + _PyLong_SetSignAndDigitCount(v, sign, ndigits); t = abs_ival; while (t) { *p++ = Py_SAFE_DOWNCAST( @@ -274,7 +281,7 @@ _PyLong_Negate(PyLongObject **x_p) x = (PyLongObject *)*x_p; if (Py_REFCNT(x) == 1) { - Py_SET_SIZE(x, -Py_SIZE(x)); + _PyLong_FlipSign(x); return; } @@ -312,8 +319,8 @@ PyLong_FromLong(long ival) /* Construct output value. */ v = _PyLong_New(ndigits); if (v != NULL) { - digit *p = v->ob_digit; - Py_SET_SIZE(v, ival < 0 ? -ndigits : ndigits); + digit *p = v->long_value.ob_digit; + _PyLong_SetSignAndDigitCount(v, ival < 0 ? -1 : 1, ndigits); t = abs_ival; while (t) { *p++ = (digit)(t & PyLong_MASK); @@ -339,7 +346,7 @@ PyLong_FromLong(long ival) if (v == NULL) { \ return NULL; \ } \ - digit *p = v->ob_digit; \ + digit *p = v->long_value.ob_digit; \ while ((ival)) { \ *p++ = (digit)((ival) & PyLong_MASK); \ (ival) >>= PyLong_SHIFT; \ @@ -418,12 +425,12 @@ PyLong_FromDouble(double dval) frac = ldexp(frac, (expo-1) % PyLong_SHIFT + 1); for (i = ndig; --i >= 0; ) { digit bits = (digit)frac; - v->ob_digit[i] = bits; + v->long_value.ob_digit[i] = bits; frac = frac - (double)bits; frac = ldexp(frac, PyLong_SHIFT); } if (neg) { - Py_SET_SIZE(v, -(Py_SIZE(v))); + _PyLong_FlipSign(v); } return (PyObject *)v; } @@ -476,38 +483,33 @@ PyLong_AsLongAndOverflow(PyObject *vv, int *overflow) return -1; do_decref = 1; } - - res = -1; - i = Py_SIZE(v); - - switch (i) { - case -1: - res = -(sdigit)v->ob_digit[0]; - break; - case 0: - res = 0; - break; - case 1: - res = v->ob_digit[0]; - break; - default: - sign = 1; - x = 0; - if (i < 0) { - sign = -1; - i = -(i); + if (_PyLong_IsCompact(v)) { +#if SIZEOF_LONG < SIZEOF_VOID_P + intptr_t tmp = _PyLong_CompactValue(v); + res = (long)tmp; + if (res != tmp) { + *overflow = tmp < 0 ? -1 : 1; } +#else + res = _PyLong_CompactValue(v); +#endif + } + else { + res = -1; + i = _PyLong_DigitCount(v); + sign = _PyLong_NonCompactSign(v); + x = 0; while (--i >= 0) { prev = x; - x = (x << PyLong_SHIFT) | v->ob_digit[i]; + x = (x << PyLong_SHIFT) | v->long_value.ob_digit[i]; if ((x >> PyLong_SHIFT) != prev) { *overflow = sign; goto exit; } } /* Haven't lost any bits, but casting to long requires extra - * care (see comment above). - */ + * care (see comment above). + */ if (x <= (unsigned long)LONG_MAX) { res = (long)x * sign; } @@ -581,21 +583,15 @@ PyLong_AsSsize_t(PyObject *vv) { } v = (PyLongObject *)vv; - i = Py_SIZE(v); - switch (i) { - case -1: return -(sdigit)v->ob_digit[0]; - case 0: return 0; - case 1: return v->ob_digit[0]; + if (_PyLong_IsCompact(v)) { + return _PyLong_CompactValue(v); } - sign = 1; + i = _PyLong_DigitCount(v); + sign = _PyLong_NonCompactSign(v); x = 0; - if (i < 0) { - sign = -1; - i = -(i); - } while (--i >= 0) { prev = x; - x = (x << PyLong_SHIFT) | v->ob_digit[i]; + x = (x << PyLong_SHIFT) | v->long_value.ob_digit[i]; if ((x >> PyLong_SHIFT) != prev) goto overflow; } @@ -636,28 +632,37 @@ PyLong_AsUnsignedLong(PyObject *vv) } v = (PyLongObject *)vv; - i = Py_SIZE(v); - x = 0; - if (i < 0) { + if (_PyLong_IsNonNegativeCompact(v)) { +#if SIZEOF_LONG < SIZEOF_VOID_P + intptr_t tmp = _PyLong_CompactValue(v); + unsigned long res = (unsigned long)tmp; + if (res != tmp) { + goto overflow; + } +#else + return _PyLong_CompactValue(v); +#endif + } + if (_PyLong_IsNegative(v)) { PyErr_SetString(PyExc_OverflowError, "can't convert negative value to unsigned int"); return (unsigned long) -1; } - switch (i) { - case 0: return 0; - case 1: return v->ob_digit[0]; - } + i = _PyLong_DigitCount(v); + x = 0; while (--i >= 0) { prev = x; - x = (x << PyLong_SHIFT) | v->ob_digit[i]; + x = (x << PyLong_SHIFT) | v->long_value.ob_digit[i]; if ((x >> PyLong_SHIFT) != prev) { - PyErr_SetString(PyExc_OverflowError, - "Python int too large to convert " - "to C unsigned long"); - return (unsigned long) -1; + goto overflow; } } return x; +overflow: + PyErr_SetString(PyExc_OverflowError, + "Python int too large to convert " + "to C unsigned long"); + return (unsigned long) -1; } /* Get a C size_t from an int object. Returns (size_t)-1 and sets @@ -680,20 +685,19 @@ PyLong_AsSize_t(PyObject *vv) } v = (PyLongObject *)vv; - i = Py_SIZE(v); - x = 0; - if (i < 0) { + if (_PyLong_IsNonNegativeCompact(v)) { + return _PyLong_CompactValue(v); + } + if (_PyLong_IsNegative(v)) { PyErr_SetString(PyExc_OverflowError, "can't convert negative value to size_t"); return (size_t) -1; } - switch (i) { - case 0: return 0; - case 1: return v->ob_digit[0]; - } + i = _PyLong_DigitCount(v); + x = 0; while (--i >= 0) { prev = x; - x = (x << PyLong_SHIFT) | v->ob_digit[i]; + x = (x << PyLong_SHIFT) | v->long_value.ob_digit[i]; if ((x >> PyLong_SHIFT) != prev) { PyErr_SetString(PyExc_OverflowError, "Python int too large to convert to C size_t"); @@ -712,26 +716,20 @@ _PyLong_AsUnsignedLongMask(PyObject *vv) PyLongObject *v; unsigned long x; Py_ssize_t i; - int sign; if (vv == NULL || !PyLong_Check(vv)) { PyErr_BadInternalCall(); return (unsigned long) -1; } v = (PyLongObject *)vv; - i = Py_SIZE(v); - switch (i) { - case 0: return 0; - case 1: return v->ob_digit[0]; + if (_PyLong_IsCompact(v)) { + return (unsigned long)_PyLong_CompactValue(v); } - sign = 1; + i = _PyLong_DigitCount(v); + int sign = _PyLong_NonCompactSign(v); x = 0; - if (i < 0) { - sign = -1; - i = -i; - } while (--i >= 0) { - x = (x << PyLong_SHIFT) | v->ob_digit[i]; + x = (x << PyLong_SHIFT) | v->long_value.ob_digit[i]; } return x * sign; } @@ -767,8 +765,10 @@ _PyLong_Sign(PyObject *vv) assert(v != NULL); assert(PyLong_Check(v)); - - return Py_SIZE(v) == 0 ? 0 : (Py_SIZE(v) < 0 ? -1 : 1); + if (_PyLong_IsCompact(v)) { + return _PyLong_CompactSign(v); + } + return _PyLong_NonCompactSign(v); } static int @@ -791,10 +791,10 @@ _PyLong_NumBits(PyObject *vv) assert(v != NULL); assert(PyLong_Check(v)); - ndigits = Py_ABS(Py_SIZE(v)); - assert(ndigits == 0 || v->ob_digit[ndigits - 1] != 0); + ndigits = _PyLong_DigitCount(v); + assert(ndigits == 0 || v->long_value.ob_digit[ndigits - 1] != 0); if (ndigits > 0) { - digit msd = v->ob_digit[ndigits - 1]; + digit msd = v->long_value.ob_digit[ndigits - 1]; if ((size_t)(ndigits - 1) > SIZE_MAX / (size_t)PyLong_SHIFT) goto Overflow; result = (size_t)(ndigits - 1) * (size_t)PyLong_SHIFT; @@ -821,7 +821,7 @@ _PyLong_FromByteArray(const unsigned char* bytes, size_t n, size_t numsignificantbytes; /* number of bytes that matter */ Py_ssize_t ndigits; /* number of Python int digits */ PyLongObject* v; /* result */ - Py_ssize_t idigit = 0; /* next free index in v->ob_digit */ + Py_ssize_t idigit = 0; /* next free index in v->long_value.ob_digit */ if (n == 0) return PyLong_FromLong(0L); @@ -903,7 +903,7 @@ _PyLong_FromByteArray(const unsigned char* bytes, size_t n, if (accumbits >= PyLong_SHIFT) { /* There's enough to fill a Python digit. */ assert(idigit < ndigits); - v->ob_digit[idigit] = (digit)(accum & PyLong_MASK); + v->long_value.ob_digit[idigit] = (digit)(accum & PyLong_MASK); ++idigit; accum >>= PyLong_SHIFT; accumbits -= PyLong_SHIFT; @@ -913,12 +913,16 @@ _PyLong_FromByteArray(const unsigned char* bytes, size_t n, assert(accumbits < PyLong_SHIFT); if (accumbits) { assert(idigit < ndigits); - v->ob_digit[idigit] = (digit)accum; + v->long_value.ob_digit[idigit] = (digit)accum; ++idigit; } } - Py_SET_SIZE(v, is_signed ? -idigit : idigit); + int sign = is_signed ? -1: 1; + if (idigit == 0) { + sign = 0; + } + _PyLong_SetSignAndDigitCount(v, sign, idigit); return (PyObject *)maybe_small_long(long_normalize(v)); } @@ -927,8 +931,8 @@ _PyLong_AsByteArray(PyLongObject* v, unsigned char* bytes, size_t n, int little_endian, int is_signed) { - Py_ssize_t i; /* index into v->ob_digit */ - Py_ssize_t ndigits; /* |v->ob_size| */ + Py_ssize_t i; /* index into v->long_value.ob_digit */ + Py_ssize_t ndigits; /* number of digits */ twodigits accum; /* sliding register */ unsigned int accumbits; /* # bits in accum */ int do_twos_comp; /* store 2's-comp? is_signed and v < 0 */ @@ -939,8 +943,8 @@ _PyLong_AsByteArray(PyLongObject* v, assert(v != NULL && PyLong_Check(v)); - if (Py_SIZE(v) < 0) { - ndigits = -(Py_SIZE(v)); + ndigits = _PyLong_DigitCount(v); + if (_PyLong_IsNegative(v)) { if (!is_signed) { PyErr_SetString(PyExc_OverflowError, "can't convert negative int to unsigned"); @@ -949,7 +953,6 @@ _PyLong_AsByteArray(PyLongObject* v, do_twos_comp = 1; } else { - ndigits = Py_SIZE(v); do_twos_comp = 0; } @@ -966,13 +969,13 @@ _PyLong_AsByteArray(PyLongObject* v, It's crucial that every Python digit except for the MSD contribute exactly PyLong_SHIFT bits to the total, so first assert that the int is normalized. */ - assert(ndigits == 0 || v->ob_digit[ndigits - 1] != 0); + assert(ndigits == 0 || v->long_value.ob_digit[ndigits - 1] != 0); j = 0; accum = 0; accumbits = 0; carry = do_twos_comp ? 1 : 0; for (i = 0; i < ndigits; ++i) { - digit thisdigit = v->ob_digit[i]; + digit thisdigit = v->long_value.ob_digit[i]; if (do_twos_comp) { thisdigit = (thisdigit ^ PyLong_MASK) + carry; carry = thisdigit >> PyLong_SHIFT; @@ -1080,10 +1083,12 @@ PyLong_AsVoidPtr(PyObject *vv) #if SIZEOF_VOID_P <= SIZEOF_LONG long x; - if (PyLong_Check(vv) && _PyLong_Sign(vv) < 0) + if (PyLong_Check(vv) && _PyLong_IsNegative((PyLongObject *)vv)) { x = PyLong_AsLong(vv); - else + } + else { x = PyLong_AsUnsignedLong(vv); + } #else #if SIZEOF_LONG_LONG < SIZEOF_VOID_P @@ -1091,10 +1096,12 @@ PyLong_AsVoidPtr(PyObject *vv) #endif long long x; - if (PyLong_Check(vv) && _PyLong_Sign(vv) < 0) + if (PyLong_Check(vv) && _PyLong_IsNegative((PyLongObject *)vv)) { x = PyLong_AsLongLong(vv); - else + } + else { x = PyLong_AsUnsignedLongLong(vv); + } #endif /* SIZEOF_VOID_P <= SIZEOF_LONG */ @@ -1139,8 +1146,8 @@ PyLong_FromLongLong(long long ival) /* Construct output value. */ v = _PyLong_New(ndigits); if (v != NULL) { - digit *p = v->ob_digit; - Py_SET_SIZE(v, ival < 0 ? -ndigits : ndigits); + digit *p = v->long_value.ob_digit; + _PyLong_SetSignAndDigitCount(v, ival < 0 ? -1 : 1, ndigits); t = abs_ival; while (t) { *p++ = (digit)(t & PyLong_MASK); @@ -1182,8 +1189,8 @@ PyLong_FromSsize_t(Py_ssize_t ival) } v = _PyLong_New(ndigits); if (v != NULL) { - digit *p = v->ob_digit; - Py_SET_SIZE(v, negative ? -ndigits : ndigits); + digit *p = v->long_value.ob_digit; + _PyLong_SetSignAndDigitCount(v, negative ? -1 : 1, ndigits); t = abs_ival; while (t) { *p++ = (digit)(t & PyLong_MASK); @@ -1219,18 +1226,11 @@ PyLong_AsLongLong(PyObject *vv) do_decref = 1; } - res = 0; - switch(Py_SIZE(v)) { - case -1: - bytes = -(sdigit)v->ob_digit[0]; - break; - case 0: - bytes = 0; - break; - case 1: - bytes = v->ob_digit[0]; - break; - default: + if (_PyLong_IsCompact(v)) { + res = 0; + bytes = _PyLong_CompactValue(v); + } + else { res = _PyLong_AsByteArray((PyLongObject *)v, (unsigned char *)&bytes, SIZEOF_LONG_LONG, PY_LITTLE_ENDIAN, 1); } @@ -1265,13 +1265,14 @@ PyLong_AsUnsignedLongLong(PyObject *vv) } v = (PyLongObject*)vv; - switch(Py_SIZE(v)) { - case 0: return 0; - case 1: return v->ob_digit[0]; + if (_PyLong_IsNonNegativeCompact(v)) { + res = 0; + bytes = _PyLong_CompactValue(v); } - - res = _PyLong_AsByteArray((PyLongObject *)vv, (unsigned char *)&bytes, + else { + res = _PyLong_AsByteArray((PyLongObject *)vv, (unsigned char *)&bytes, SIZEOF_LONG_LONG, PY_LITTLE_ENDIAN, 0); + } /* Plan 9 can't handle long long in ? : expressions */ if (res < 0) @@ -1296,19 +1297,14 @@ _PyLong_AsUnsignedLongLongMask(PyObject *vv) return (unsigned long long) -1; } v = (PyLongObject *)vv; - switch(Py_SIZE(v)) { - case 0: return 0; - case 1: return v->ob_digit[0]; + if (_PyLong_IsCompact(v)) { + return (unsigned long long)(signed long long)_PyLong_CompactValue(v); } - i = Py_SIZE(v); - sign = 1; + i = _PyLong_DigitCount(v); + sign = _PyLong_NonCompactSign(v); x = 0; - if (i < 0) { - sign = -1; - i = -i; - } while (--i >= 0) { - x = (x << PyLong_SHIFT) | v->ob_digit[i]; + x = (x << PyLong_SHIFT) | v->long_value.ob_digit[i]; } return x * sign; } @@ -1373,32 +1369,19 @@ PyLong_AsLongLongAndOverflow(PyObject *vv, int *overflow) return -1; do_decref = 1; } - - res = -1; - i = Py_SIZE(v); - - switch (i) { - case -1: - res = -(sdigit)v->ob_digit[0]; - break; - case 0: - res = 0; - break; - case 1: - res = v->ob_digit[0]; - break; - default: - sign = 1; + if (_PyLong_IsCompact(v)) { + res = _PyLong_CompactValue(v); + } + else { + i = _PyLong_DigitCount(v); + sign = _PyLong_NonCompactSign(v); x = 0; - if (i < 0) { - sign = -1; - i = -(i); - } while (--i >= 0) { prev = x; - x = (x << PyLong_SHIFT) + v->ob_digit[i]; + x = (x << PyLong_SHIFT) + v->long_value.ob_digit[i]; if ((x >> PyLong_SHIFT) != prev) { *overflow = sign; + res = -1; goto exit; } } @@ -1413,7 +1396,7 @@ PyLong_AsLongLongAndOverflow(PyObject *vv, int *overflow) } else { *overflow = sign; - /* res is already set to -1 */ + res = -1; } } exit: @@ -1428,7 +1411,7 @@ _PyLong_UnsignedShort_Converter(PyObject *obj, void *ptr) { unsigned long uval; - if (PyLong_Check(obj) && _PyLong_Sign(obj) < 0) { + if (PyLong_Check(obj) && _PyLong_IsNegative((PyLongObject *)obj)) { PyErr_SetString(PyExc_ValueError, "value must be positive"); return 0; } @@ -1450,7 +1433,7 @@ _PyLong_UnsignedInt_Converter(PyObject *obj, void *ptr) { unsigned long uval; - if (PyLong_Check(obj) && _PyLong_Sign(obj) < 0) { + if (PyLong_Check(obj) && _PyLong_IsNegative((PyLongObject *)obj)) { PyErr_SetString(PyExc_ValueError, "value must be positive"); return 0; } @@ -1472,7 +1455,7 @@ _PyLong_UnsignedLong_Converter(PyObject *obj, void *ptr) { unsigned long uval; - if (PyLong_Check(obj) && _PyLong_Sign(obj) < 0) { + if (PyLong_Check(obj) && _PyLong_IsNegative((PyLongObject *)obj)) { PyErr_SetString(PyExc_ValueError, "value must be positive"); return 0; } @@ -1489,7 +1472,7 @@ _PyLong_UnsignedLongLong_Converter(PyObject *obj, void *ptr) { unsigned long long uval; - if (PyLong_Check(obj) && _PyLong_Sign(obj) < 0) { + if (PyLong_Check(obj) && _PyLong_IsNegative((PyLongObject *)obj)) { PyErr_SetString(PyExc_ValueError, "value must be positive"); return 0; } @@ -1506,7 +1489,7 @@ _PyLong_Size_t_Converter(PyObject *obj, void *ptr) { size_t uval; - if (PyLong_Check(obj) && _PyLong_Sign(obj) < 0) { + if (PyLong_Check(obj) && _PyLong_IsNegative((PyLongObject *)obj)) { PyErr_SetString(PyExc_ValueError, "value must be positive"); return 0; } @@ -1660,14 +1643,14 @@ inplace_divrem1(digit *pout, digit *pin, Py_ssize_t size, digit n) static PyLongObject * divrem1(PyLongObject *a, digit n, digit *prem) { - const Py_ssize_t size = Py_ABS(Py_SIZE(a)); + const Py_ssize_t size = _PyLong_DigitCount(a); PyLongObject *z; assert(n > 0 && n <= PyLong_MASK); z = _PyLong_New(size); if (z == NULL) return NULL; - *prem = inplace_divrem1(z->ob_digit, a->ob_digit, size, n); + *prem = inplace_divrem1(z->long_value.ob_digit, a->long_value.ob_digit, size, n); return long_normalize(z); } @@ -1692,14 +1675,80 @@ inplace_rem1(digit *pin, Py_ssize_t size, digit n) static PyLongObject * rem1(PyLongObject *a, digit n) { - const Py_ssize_t size = Py_ABS(Py_SIZE(a)); + const Py_ssize_t size = _PyLong_DigitCount(a); assert(n > 0 && n <= PyLong_MASK); return (PyLongObject *)PyLong_FromLong( - (long)inplace_rem1(a->ob_digit, size, n) + (long)inplace_rem1(a->long_value.ob_digit, size, n) ); } +#ifdef WITH_PYLONG_MODULE +/* asymptotically faster long_to_decimal_string, using _pylong.py */ +static int +pylong_int_to_decimal_string(PyObject *aa, + PyObject **p_output, + _PyUnicodeWriter *writer, + _PyBytesWriter *bytes_writer, + char **bytes_str) +{ + PyObject *s = NULL; + PyObject *mod = PyImport_ImportModule("_pylong"); + if (mod == NULL) { + return -1; + } + s = PyObject_CallMethod(mod, "int_to_decimal_string", "O", aa); + if (s == NULL) { + goto error; + } + if (!PyUnicode_Check(s)) { + PyErr_SetString(PyExc_TypeError, + "_pylong.int_to_decimal_string did not return a str"); + goto error; + } + if (writer) { + Py_ssize_t size = PyUnicode_GET_LENGTH(s); + if (_PyUnicodeWriter_Prepare(writer, size, '9') == -1) { + goto error; + } + if (_PyUnicodeWriter_WriteStr(writer, s) < 0) { + goto error; + } + goto success; + } + else if (bytes_writer) { + Py_ssize_t size = PyUnicode_GET_LENGTH(s); + const void *data = PyUnicode_DATA(s); + int kind = PyUnicode_KIND(s); + *bytes_str = _PyBytesWriter_Prepare(bytes_writer, *bytes_str, size); + if (*bytes_str == NULL) { + goto error; + } + char *p = *bytes_str; + for (Py_ssize_t i=0; i < size; i++) { + Py_UCS4 ch = PyUnicode_READ(kind, data, i); + *p++ = (char) ch; + } + (*bytes_str) = p; + goto success; + } + else { + *p_output = Py_NewRef(s); + goto success; + } + +error: + Py_DECREF(mod); + Py_XDECREF(s); + return -1; + +success: + Py_DECREF(mod); + Py_DECREF(s); + return 0; +} +#endif /* WITH_PYLONG_MODULE */ + /* Convert an integer to a base 10 string. Returns a new non-shared string. (Return value is non-shared so that callers can modify the returned value if necessary.) */ @@ -1717,15 +1766,15 @@ long_to_decimal_string_internal(PyObject *aa, digit *pout, *pin, rem, tenpow; int negative; int d; - enum PyUnicode_Kind kind; + int kind; a = (PyLongObject *)aa; if (a == NULL || !PyLong_Check(a)) { PyErr_BadInternalCall(); return -1; } - size_a = Py_ABS(Py_SIZE(a)); - negative = Py_SIZE(a) < 0; + size_a = _PyLong_DigitCount(a); + negative = _PyLong_IsNegative(a); /* quick and dirty pre-check for overflowing the decimal digit limit, based on the inequality 10/3 >= log2(10) @@ -1735,7 +1784,7 @@ long_to_decimal_string_internal(PyObject *aa, if (size_a >= 10 * _PY_LONG_MAX_STR_DIGITS_THRESHOLD / (3 * PyLong_SHIFT) + 2) { PyInterpreterState *interp = _PyInterpreterState_GET(); - int max_str_digits = interp->int_max_str_digits; + int max_str_digits = interp->long_state.max_str_digits; if ((max_str_digits > 0) && (max_str_digits / (3 * PyLong_SHIFT) <= (size_a - 11) / 10)) { PyErr_Format(PyExc_ValueError, _MAX_STR_DIGITS_ERROR_FMT_TO_STR, @@ -1744,6 +1793,17 @@ long_to_decimal_string_internal(PyObject *aa, } } +#if WITH_PYLONG_MODULE + if (size_a > 1000) { + /* Switch to _pylong.int_to_decimal_string(). */ + return pylong_int_to_decimal_string(aa, + p_output, + writer, + bytes_writer, + bytes_str); + } +#endif + /* quick and dirty upper bound for the number of digits required to express a in base _PyLong_DECIMAL_BASE: @@ -1769,8 +1829,8 @@ long_to_decimal_string_internal(PyObject *aa, /* convert array of base _PyLong_BASE digits in pin to an array of base _PyLong_DECIMAL_BASE digits in pout, following Knuth (TAOCP, Volume 2 (3rd edn), section 4.4, Method 1b). */ - pin = a->ob_digit; - pout = scratch->ob_digit; + pin = a->long_value.ob_digit; + pout = scratch->long_value.ob_digit; size = 0; for (i = size_a; --i >= 0; ) { digit hi = pin[i]; @@ -1805,7 +1865,7 @@ long_to_decimal_string_internal(PyObject *aa, } if (strlen > _PY_LONG_MAX_STR_DIGITS_THRESHOLD) { PyInterpreterState *interp = _PyInterpreterState_GET(); - int max_str_digits = interp->int_max_str_digits; + int max_str_digits = interp->long_state.max_str_digits; Py_ssize_t strlen_nosign = strlen - negative; if ((max_str_digits > 0) && (strlen_nosign > max_str_digits)) { Py_DECREF(scratch); @@ -1935,7 +1995,7 @@ long_format_binary(PyObject *aa, int base, int alternate, PyObject *v = NULL; Py_ssize_t sz; Py_ssize_t size_a; - enum PyUnicode_Kind kind; + int kind; int negative; int bits; @@ -1944,8 +2004,8 @@ long_format_binary(PyObject *aa, int base, int alternate, PyErr_BadInternalCall(); return -1; } - size_a = Py_ABS(Py_SIZE(a)); - negative = Py_SIZE(a) < 0; + size_a = _PyLong_DigitCount(a); + negative = _PyLong_IsNegative(a); /* Compute a rough upper bound for the length of the string */ switch (base) { @@ -1975,7 +2035,7 @@ long_format_binary(PyObject *aa, int base, int alternate, return -1; } size_a_in_bits = (size_a - 1) * PyLong_SHIFT + - bit_length_digit(a->ob_digit[size_a - 1]); + bit_length_digit(a->long_value.ob_digit[size_a - 1]); /* Allow 1 character for a '-' sign. */ sz = negative + (size_a_in_bits + (bits - 1)) / bits; } @@ -2012,7 +2072,7 @@ long_format_binary(PyObject *aa, int base, int alternate, int accumbits = 0; /* # of bits in accum */ \ Py_ssize_t i; \ for (i = 0; i < size_a; ++i) { \ - accum |= (twodigits)a->ob_digit[i] << accumbits; \ + accum |= (twodigits)a->long_value.ob_digit[i] << accumbits; \ accumbits += PyLong_SHIFT; \ assert(accumbits >= bits); \ do { \ @@ -2161,23 +2221,23 @@ unsigned char _PyLong_DigitValue[256] = { 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, }; -/* *str points to the first digit in a string of base `base` digits. base - * is a power of 2 (2, 4, 8, 16, or 32). *str is set to point to the first - * non-digit (which may be *str!). A normalized int is returned. - * The point to this routine is that it takes time linear in the number of - * string characters. +/* `start` and `end` point to the start and end of a string of base `base` + * digits. base is a power of 2 (2, 4, 8, 16, or 32). An unnormalized int is + * returned in *res. The string should be already validated by the caller and + * consists only of valid digit characters and underscores. `digits` gives the + * number of digit characters. + * + * The point to this routine is that it takes time linear in the + * number of string characters. * * Return values: * -1 on syntax error (exception needs to be set, *res is untouched) * 0 else (exception may be set, in that case *res is set to NULL) */ static int -long_from_binary_base(const char **str, int base, PyLongObject **res) +long_from_binary_base(const char *start, const char *end, Py_ssize_t digits, int base, PyLongObject **res) { - const char *p = *str; - const char *start = p; - char prev = 0; - Py_ssize_t digits = 0; + const char *p; int bits_per_char; Py_ssize_t n; PyLongObject *z; @@ -2190,26 +2250,7 @@ long_from_binary_base(const char **str, int base, PyLongObject **res) for (bits_per_char = -1; n; ++bits_per_char) { n >>= 1; } - /* count digits and set p to end-of-string */ - while (_PyLong_DigitValue[Py_CHARMASK(*p)] < base || *p == '_') { - if (*p == '_') { - if (prev == '_') { - *str = p - 1; - return -1; - } - } else { - ++digits; - } - prev = *p; - ++p; - } - if (prev == '_') { - /* Trailing underscore not allowed. */ - *str = p - 1; - return -1; - } - *str = p; /* 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) { @@ -2229,7 +2270,8 @@ long_from_binary_base(const char **str, int base, PyLongObject **res) */ accum = 0; bits_in_accum = 0; - pdigit = z->ob_digit; + pdigit = z->long_value.ob_digit; + p = end; while (--p >= start) { int k; if (*p == '_') { @@ -2241,7 +2283,7 @@ long_from_binary_base(const char **str, int base, PyLongObject **res) bits_in_accum += bits_per_char; if (bits_in_accum >= PyLong_SHIFT) { *pdigit++ = (digit)(accum & PyLong_MASK); - assert(pdigit - z->ob_digit <= n); + assert(pdigit - z->long_value.ob_digit <= n); accum >>= PyLong_SHIFT; bits_in_accum -= PyLong_SHIFT; assert(bits_in_accum < PyLong_SHIFT); @@ -2250,92 +2292,54 @@ long_from_binary_base(const char **str, int base, PyLongObject **res) if (bits_in_accum) { assert(bits_in_accum <= PyLong_SHIFT); *pdigit++ = (digit)accum; - assert(pdigit - z->ob_digit <= n); + assert(pdigit - z->long_value.ob_digit <= n); } - while (pdigit - z->ob_digit < n) + while (pdigit - z->long_value.ob_digit < n) *pdigit++ = 0; - *res = long_normalize(z); + *res = z; return 0; } -/* Parses an int from a bytestring. Leading and trailing whitespace will be - * ignored. - * - * If successful, a PyLong object will be returned and 'pend' will be pointing - * to the first unused byte unless it's NULL. - * - * If unsuccessful, NULL will be returned. - */ -PyObject * -PyLong_FromString(const char *str, char **pend, int base) -{ - int sign = 1, error_if_nonzero = 0; - const char *start, *orig_str = str; - PyLongObject *z = NULL; - PyObject *strobj; - Py_ssize_t slen; +static PyObject *long_neg(PyLongObject *v); - if ((base != 0 && base < 2) || base > 36) { - PyErr_SetString(PyExc_ValueError, - "int() arg 2 must be >= 2 and <= 36"); - return NULL; - } - while (*str != '\0' && Py_ISSPACE(*str)) { - str++; - } - if (*str == '+') { - ++str; - } - else if (*str == '-') { - ++str; - sign = -1; +#ifdef WITH_PYLONG_MODULE +/* asymptotically faster str-to-long conversion for base 10, using _pylong.py */ +static int +pylong_int_from_string(const char *start, const char *end, PyLongObject **res) +{ + PyObject *mod = PyImport_ImportModule("_pylong"); + if (mod == NULL) { + goto error; } - if (base == 0) { - if (str[0] != '0') { - base = 10; - } - else if (str[1] == 'x' || str[1] == 'X') { - base = 16; - } - else if (str[1] == 'o' || str[1] == 'O') { - base = 8; - } - else if (str[1] == 'b' || str[1] == 'B') { - base = 2; - } - else { - /* "old" (C-style) octal literal, now invalid. - it might still be zero though */ - error_if_nonzero = 1; - base = 10; - } + PyObject *s = PyUnicode_FromStringAndSize(start, end-start); + if (s == NULL) { + Py_DECREF(mod); + goto error; } - if (str[0] == '0' && - ((base == 16 && (str[1] == 'x' || str[1] == 'X')) || - (base == 8 && (str[1] == 'o' || str[1] == 'O')) || - (base == 2 && (str[1] == 'b' || str[1] == 'B')))) { - str += 2; - /* One underscore allowed here. */ - if (*str == '_') { - ++str; - } + PyObject *result = PyObject_CallMethod(mod, "int_from_string", "O", s); + Py_DECREF(s); + Py_DECREF(mod); + if (result == NULL) { + goto error; } - if (str[0] == '_') { - /* May not start with underscores. */ - goto onError; + if (!PyLong_Check(result)) { + Py_DECREF(result); + PyErr_SetString(PyExc_TypeError, + "_pylong.int_from_string did not return an int"); + goto error; } + *res = (PyLongObject *)result; + return 0; +error: + *res = NULL; + return 0; // See the long_from_string_base() API comment. +} +#endif /* WITH_PYLONG_MODULE */ - start = str; - if ((base & (base - 1)) == 0) { - /* binary bases are not limited by int_max_str_digits */ - int res = long_from_binary_base(&str, base, &z); - if (res < 0) { - /* Syntax error. */ - goto onError; - } - } - else { /*** +long_from_non_binary_base: parameters and return values are the same as +long_from_binary_base. + Binary bases can be converted in time linear in the number of digits, because Python's representation base is binary. Other bases (including decimal!) use the simple quadratic-time algorithm below, complicated by some speed tricks. @@ -2420,198 +2424,336 @@ that triggers it(!). Instead the code was tested by artificially allocating just 1 digit at the start, so that the copying code was exercised for every digit beyond the first. ***/ - twodigits c; /* current input character */ - Py_ssize_t size_z; - Py_ssize_t digits = 0; - int i; - int convwidth; - twodigits convmultmax, convmult; - digit *pz, *pzstop; - const char *scan, *lastdigit; - char prev = 0; - - static double log_base_BASE[37] = {0.0e0,}; - static int convwidth_base[37] = {0,}; - static twodigits convmultmax_base[37] = {0,}; - - if (log_base_BASE[base] == 0.0) { - twodigits convmax = base; - int i = 1; - - log_base_BASE[base] = (log((double)base) / - log((double)PyLong_BASE)); - for (;;) { - twodigits next = convmax * base; - if (next > PyLong_BASE) { - break; - } - convmax = next; - ++i; +static int +long_from_non_binary_base(const char *start, const char *end, Py_ssize_t digits, int base, PyLongObject **res) +{ + twodigits c; /* current input character */ + Py_ssize_t size_z; + int i; + int convwidth; + twodigits convmultmax, convmult; + digit *pz, *pzstop; + PyLongObject *z; + const char *p; + + static double log_base_BASE[37] = {0.0e0,}; + static int convwidth_base[37] = {0,}; + static twodigits convmultmax_base[37] = {0,}; + + if (log_base_BASE[base] == 0.0) { + twodigits convmax = base; + int i = 1; + + log_base_BASE[base] = (log((double)base) / + log((double)PyLong_BASE)); + for (;;) { + twodigits next = convmax * base; + if (next > PyLong_BASE) { + break; + } + convmax = next; + ++i; + } + convmultmax_base[base] = convmax; + assert(i > 0); + convwidth_base[base] = i; + } + + /* Create an int object that can contain the largest possible + * integer with this base and length. Note that there's no + * need to initialize z->long_value.ob_digit -- no slot is read up before + * being stored into. + */ + double fsize_z = (double)digits * log_base_BASE[base] + 1.0; + if (fsize_z > (double)MAX_LONG_DIGITS) { + /* The same exception as in _PyLong_New(). */ + PyErr_SetString(PyExc_OverflowError, + "too many digits in integer"); + *res = NULL; + return 0; + } + size_z = (Py_ssize_t)fsize_z; + /* Uncomment next line to test exceedingly rare copy code */ + /* size_z = 1; */ + assert(size_z > 0); + z = _PyLong_New(size_z); + if (z == NULL) { + *res = NULL; + return 0; + } + _PyLong_SetSignAndDigitCount(z, 0, 0); + + /* `convwidth` consecutive input digits are treated as a single + * digit in base `convmultmax`. + */ + convwidth = convwidth_base[base]; + convmultmax = convmultmax_base[base]; + + /* Work ;-) */ + p = start; + while (p < end) { + if (*p == '_') { + p++; + continue; + } + /* grab up to convwidth digits from the input string */ + c = (digit)_PyLong_DigitValue[Py_CHARMASK(*p++)]; + for (i = 1; i < convwidth && p != end; ++p) { + if (*p == '_') { + continue; } - convmultmax_base[base] = convmax; - assert(i > 0); - convwidth_base[base] = i; + i++; + c = (twodigits)(c * base + + (int)_PyLong_DigitValue[Py_CHARMASK(*p)]); + assert(c < PyLong_BASE); } - /* Find length of the string of numeric characters. */ - scan = str; - lastdigit = str; + convmult = convmultmax; + /* Calculate the shift only if we couldn't get + * convwidth digits. + */ + if (i != convwidth) { + convmult = base; + for ( ; i > 1; --i) { + convmult *= base; + } + } - while (_PyLong_DigitValue[Py_CHARMASK(*scan)] < base || *scan == '_') { - if (*scan == '_') { - if (prev == '_') { - /* Only one underscore allowed. */ - str = lastdigit + 1; - goto onError; - } + /* Multiply z by convmult, and add c. */ + pz = z->long_value.ob_digit; + pzstop = pz + _PyLong_DigitCount(z); + for (; pz < pzstop; ++pz) { + c += (twodigits)*pz * convmult; + *pz = (digit)(c & PyLong_MASK); + c >>= PyLong_SHIFT; + } + /* carry off the current end? */ + if (c) { + assert(c < PyLong_BASE); + if (_PyLong_DigitCount(z) < size_z) { + *pz = (digit)c; + assert(!_PyLong_IsNegative(z)); + _PyLong_SetSignAndDigitCount(z, 1, _PyLong_DigitCount(z) + 1); } else { - ++digits; - lastdigit = scan; + PyLongObject *tmp; + /* Extremely rare. Get more space. */ + assert(_PyLong_DigitCount(z) == size_z); + tmp = _PyLong_New(size_z + 1); + if (tmp == NULL) { + Py_DECREF(z); + *res = NULL; + return 0; + } + memcpy(tmp->long_value.ob_digit, + z->long_value.ob_digit, + sizeof(digit) * size_z); + Py_SETREF(z, tmp); + z->long_value.ob_digit[size_z] = (digit)c; + ++size_z; } - prev = *scan; - ++scan; } - if (prev == '_') { - /* Trailing underscore not allowed. */ - /* Set error pointer to first underscore. */ - str = lastdigit + 1; - goto onError; + } + *res = z; + return 0; +} + +/* *str points to the first digit in a string of base `base` digits. base is an + * integer from 2 to 36 inclusive. Here we don't need to worry about prefixes + * like 0x or leading +- signs. The string should be null terminated consisting + * of ASCII digits and separating underscores possibly with trailing whitespace + * but we have to validate all of those points here. + * + * If base is a power of 2 then the complexity is linear in the number of + * characters in the string. Otherwise a quadratic algorithm is used for + * non-binary bases. + * + * Return values: + * + * - Returns -1 on syntax error (exception needs to be set, *res is untouched) + * - Returns 0 and sets *res to NULL for MemoryError, OverflowError, or + * _pylong.int_from_string() errors. + * - Returns 0 and sets *res to an unsigned, unnormalized PyLong (success!). + * + * Afterwards *str is set to point to the first non-digit (which may be *str!). + */ +static int +long_from_string_base(const char **str, int base, PyLongObject **res) +{ + const char *start, *end, *p; + char prev = 0; + Py_ssize_t digits = 0; + int is_binary_base = (base & (base - 1)) == 0; + + /* Here we do four things: + * + * - Find the `end` of the string. + * - Validate the string. + * - Count the number of `digits` (rather than underscores) + * - Point *str to the end-of-string or first invalid character. + */ + start = p = *str; + /* Leading underscore not allowed. */ + if (*start == '_') { + return -1; + } + /* Verify all characters are digits and underscores. */ + while (_PyLong_DigitValue[Py_CHARMASK(*p)] < base || *p == '_') { + if (*p == '_') { + /* Double underscore not allowed. */ + if (prev == '_') { + *str = p - 1; + return -1; + } + } else { + ++digits; } + prev = *p; + ++p; + } + /* Trailing underscore not allowed. */ + if (prev == '_') { + *str = p - 1; + return -1; + } + *str = end = p; + /* Reject empty strings */ + if (start == end) { + return -1; + } + /* Allow only trailing whitespace after `end` */ + while (*p && Py_ISSPACE(*p)) { + p++; + } + *str = p; + if (*p != '\0') { + return -1; + } - /* Limit the size to avoid excessive computation attacks. */ + /* + * Pass a validated string consisting of only valid digits and underscores + * to long_from_xxx_base. + */ + if (is_binary_base) { + /* Use the linear algorithm for binary bases. */ + return long_from_binary_base(start, end, digits, base, res); + } + else { + /* Limit the size to avoid excessive computation attacks exploiting the + * quadratic algorithm. */ if (digits > _PY_LONG_MAX_STR_DIGITS_THRESHOLD) { PyInterpreterState *interp = _PyInterpreterState_GET(); - int max_str_digits = interp->int_max_str_digits; + int max_str_digits = interp->long_state.max_str_digits; if ((max_str_digits > 0) && (digits > max_str_digits)) { PyErr_Format(PyExc_ValueError, _MAX_STR_DIGITS_ERROR_FMT_TO_INT, max_str_digits, digits); - return NULL; + *res = NULL; + return 0; } } - - /* Create an int object that can contain the largest possible - * integer with this base and length. Note that there's no - * need to initialize z->ob_digit -- no slot is read up before - * being stored into. - */ - double fsize_z = (double)digits * log_base_BASE[base] + 1.0; - if (fsize_z > (double)MAX_LONG_DIGITS) { - /* The same exception as in _PyLong_New(). */ - PyErr_SetString(PyExc_OverflowError, - "too many digits in integer"); - return NULL; +#if WITH_PYLONG_MODULE + if (digits > 6000 && base == 10) { + /* Switch to _pylong.int_from_string() */ + return pylong_int_from_string(start, end, res); } - size_z = (Py_ssize_t)fsize_z; - /* Uncomment next line to test exceedingly rare copy code */ - /* size_z = 1; */ - assert(size_z > 0); - z = _PyLong_New(size_z); - if (z == NULL) { - return NULL; - } - Py_SET_SIZE(z, 0); - - /* `convwidth` consecutive input digits are treated as a single - * digit in base `convmultmax`. - */ - convwidth = convwidth_base[base]; - convmultmax = convmultmax_base[base]; - - /* Work ;-) */ - while (str < scan) { - if (*str == '_') { - str++; - continue; - } - /* grab up to convwidth digits from the input string */ - c = (digit)_PyLong_DigitValue[Py_CHARMASK(*str++)]; - for (i = 1; i < convwidth && str != scan; ++str) { - if (*str == '_') { - continue; - } - i++; - c = (twodigits)(c * base + - (int)_PyLong_DigitValue[Py_CHARMASK(*str)]); - assert(c < PyLong_BASE); - } +#endif + /* Use the quadratic algorithm for non binary bases. */ + return long_from_non_binary_base(start, end, digits, base, res); + } +} - convmult = convmultmax; - /* Calculate the shift only if we couldn't get - * convwidth digits. - */ - if (i != convwidth) { - convmult = base; - for ( ; i > 1; --i) { - convmult *= base; - } - } +/* Parses an int from a bytestring. Leading and trailing whitespace will be + * ignored. + * + * If successful, a PyLong object will be returned and 'pend' will be pointing + * to the first unused byte unless it's NULL. + * + * If unsuccessful, NULL will be returned. + */ +PyObject * +PyLong_FromString(const char *str, char **pend, int base) +{ + int sign = 1, error_if_nonzero = 0; + const char *orig_str = str; + PyLongObject *z = NULL; + PyObject *strobj; + Py_ssize_t slen; - /* Multiply z by convmult, and add c. */ - pz = z->ob_digit; - pzstop = pz + Py_SIZE(z); - for (; pz < pzstop; ++pz) { - c += (twodigits)*pz * convmult; - *pz = (digit)(c & PyLong_MASK); - c >>= PyLong_SHIFT; - } - /* carry off the current end? */ - if (c) { - assert(c < PyLong_BASE); - if (Py_SIZE(z) < size_z) { - *pz = (digit)c; - Py_SET_SIZE(z, Py_SIZE(z) + 1); - } - else { - PyLongObject *tmp; - /* Extremely rare. Get more space. */ - assert(Py_SIZE(z) == size_z); - tmp = _PyLong_New(size_z + 1); - if (tmp == NULL) { - Py_DECREF(z); - return NULL; - } - memcpy(tmp->ob_digit, - z->ob_digit, - sizeof(digit) * size_z); - Py_DECREF(z); - z = tmp; - z->ob_digit[size_z] = (digit)c; - ++size_z; - } - } + if ((base != 0 && base < 2) || base > 36) { + PyErr_SetString(PyExc_ValueError, + "int() arg 2 must be >= 2 and <= 36"); + return NULL; + } + while (*str != '\0' && Py_ISSPACE(*str)) { + ++str; + } + if (*str == '+') { + ++str; + } + else if (*str == '-') { + ++str; + sign = -1; + } + if (base == 0) { + if (str[0] != '0') { + base = 10; + } + else if (str[1] == 'x' || str[1] == 'X') { + base = 16; + } + else if (str[1] == 'o' || str[1] == 'O') { + base = 8; + } + else if (str[1] == 'b' || str[1] == 'B') { + base = 2; + } + else { + /* "old" (C-style) octal literal, now invalid. + it might still be zero though */ + error_if_nonzero = 1; + base = 10; + } + } + if (str[0] == '0' && + ((base == 16 && (str[1] == 'x' || str[1] == 'X')) || + (base == 8 && (str[1] == 'o' || str[1] == 'O')) || + (base == 2 && (str[1] == 'b' || str[1] == 'B')))) { + str += 2; + /* One underscore allowed here. */ + if (*str == '_') { + ++str; } } + + /* long_from_string_base is the main workhorse here. */ + int ret = long_from_string_base(&str, base, &z); + if (ret == -1) { + /* Syntax error. */ + goto onError; + } if (z == NULL) { + /* Error. exception already set. */ return NULL; } + if (error_if_nonzero) { /* reset the base to 0, else the exception message doesn't make too much sense */ base = 0; - if (Py_SIZE(z) != 0) { + if (!_PyLong_IsZero(z)) { goto onError; } /* there might still be other problems, therefore base remains zero here for the same reason */ } - if (str == start) { - goto onError; - } + + /* Set sign and normalize */ if (sign < 0) { - Py_SET_SIZE(z, -(Py_SIZE(z))); - } - while (*str && Py_ISSPACE(*str)) { - str++; - } - if (*str != '\0') { - goto onError; + _PyLong_FlipSign(z); } long_normalize(z); z = maybe_small_long(z); - if (z == NULL) { - return NULL; - } + if (pend != NULL) { *pend = (char *)str; } @@ -2699,7 +2841,7 @@ static int long_divrem(PyLongObject *a, PyLongObject *b, PyLongObject **pdiv, PyLongObject **prem) { - Py_ssize_t size_a = Py_ABS(Py_SIZE(a)), size_b = Py_ABS(Py_SIZE(b)); + Py_ssize_t size_a = _PyLong_DigitCount(a), size_b = _PyLong_DigitCount(b); PyLongObject *z; if (size_b == 0) { @@ -2709,20 +2851,19 @@ long_divrem(PyLongObject *a, PyLongObject *b, } if (size_a < size_b || (size_a == size_b && - a->ob_digit[size_a-1] < b->ob_digit[size_b-1])) { + a->long_value.ob_digit[size_a-1] < b->long_value.ob_digit[size_b-1])) { /* |a| < |b|. */ *prem = (PyLongObject *)long_long((PyObject *)a); if (*prem == NULL) { return -1; } PyObject *zero = _PyLong_GetZero(); - Py_INCREF(zero); - *pdiv = (PyLongObject*)zero; + *pdiv = (PyLongObject*)Py_NewRef(zero); return 0; } if (size_b == 1) { digit rem = 0; - z = divrem1(a, b->ob_digit[0], &rem); + z = divrem1(a, b->long_value.ob_digit[0], &rem); if (z == NULL) return -1; *prem = (PyLongObject *) PyLong_FromLong((long)rem); @@ -2741,14 +2882,14 @@ long_divrem(PyLongObject *a, PyLongObject *b, The quotient z has the sign of a*b; the remainder r has the sign of a, so a = b*z + r. */ - if ((Py_SIZE(a) < 0) != (Py_SIZE(b) < 0)) { + if ((_PyLong_IsNegative(a)) != (_PyLong_IsNegative(b))) { _PyLong_Negate(&z); if (z == NULL) { Py_CLEAR(*prem); return -1; } } - if (Py_SIZE(a) < 0 && Py_SIZE(*prem) != 0) { + if (_PyLong_IsNegative(a) && !_PyLong_IsZero(*prem)) { _PyLong_Negate(prem); if (*prem == NULL) { Py_DECREF(z); @@ -2765,7 +2906,7 @@ long_divrem(PyLongObject *a, PyLongObject *b, static int long_rem(PyLongObject *a, PyLongObject *b, PyLongObject **prem) { - Py_ssize_t size_a = Py_ABS(Py_SIZE(a)), size_b = Py_ABS(Py_SIZE(b)); + Py_ssize_t size_a = _PyLong_DigitCount(a), size_b = _PyLong_DigitCount(b); if (size_b == 0) { PyErr_SetString(PyExc_ZeroDivisionError, @@ -2774,13 +2915,13 @@ long_rem(PyLongObject *a, PyLongObject *b, PyLongObject **prem) } if (size_a < size_b || (size_a == size_b && - a->ob_digit[size_a-1] < b->ob_digit[size_b-1])) { + a->long_value.ob_digit[size_a-1] < b->long_value.ob_digit[size_b-1])) { /* |a| < |b|. */ *prem = (PyLongObject *)long_long((PyObject *)a); return -(*prem == NULL); } if (size_b == 1) { - *prem = rem1(a, b->ob_digit[0]); + *prem = rem1(a, b->long_value.ob_digit[0]); if (*prem == NULL) return -1; } @@ -2792,7 +2933,7 @@ long_rem(PyLongObject *a, PyLongObject *b, PyLongObject **prem) return -1; } /* Set the sign. */ - if (Py_SIZE(a) < 0 && Py_SIZE(*prem) != 0) { + if (_PyLong_IsNegative(a) && !_PyLong_IsZero(*prem)) { _PyLong_Negate(prem); if (*prem == NULL) { Py_CLEAR(*prem); @@ -2803,7 +2944,7 @@ long_rem(PyLongObject *a, PyLongObject *b, PyLongObject **prem) } /* Unsigned int division with remainder -- the algorithm. The arguments v1 - and w1 should satisfy 2 <= Py_ABS(Py_SIZE(w1)) <= Py_ABS(Py_SIZE(v1)). */ + and w1 should satisfy 2 <= _PyLong_DigitCount(w1) <= _PyLong_DigitCount(v1). */ static PyLongObject * x_divrem(PyLongObject *v1, PyLongObject *w1, PyLongObject **prem) @@ -2823,8 +2964,8 @@ x_divrem(PyLongObject *v1, PyLongObject *w1, PyLongObject **prem) that won't overflow a digit. */ /* allocate space; w will also be used to hold the final remainder */ - size_v = Py_ABS(Py_SIZE(v1)); - size_w = Py_ABS(Py_SIZE(w1)); + size_v = _PyLong_DigitCount(v1); + size_w = _PyLong_DigitCount(w1); assert(size_v >= size_w && size_w >= 2); /* Assert checks by div() */ v = _PyLong_New(size_v+1); if (v == NULL) { @@ -2840,16 +2981,16 @@ x_divrem(PyLongObject *v1, PyLongObject *w1, PyLongObject **prem) /* normalize: shift w1 left so that its top digit is >= PyLong_BASE/2. shift v1 left by the same amount. Results go into w and v. */ - d = PyLong_SHIFT - bit_length_digit(w1->ob_digit[size_w-1]); - carry = v_lshift(w->ob_digit, w1->ob_digit, size_w, d); + d = PyLong_SHIFT - bit_length_digit(w1->long_value.ob_digit[size_w-1]); + carry = v_lshift(w->long_value.ob_digit, w1->long_value.ob_digit, size_w, d); assert(carry == 0); - carry = v_lshift(v->ob_digit, v1->ob_digit, size_v, d); - if (carry != 0 || v->ob_digit[size_v-1] >= w->ob_digit[size_w-1]) { - v->ob_digit[size_v] = carry; + carry = v_lshift(v->long_value.ob_digit, v1->long_value.ob_digit, size_v, d); + if (carry != 0 || v->long_value.ob_digit[size_v-1] >= w->long_value.ob_digit[size_w-1]) { + v->long_value.ob_digit[size_v] = carry; size_v++; } - /* Now v->ob_digit[size_v-1] < w->ob_digit[size_w-1], so quotient has + /* Now v->long_value.ob_digit[size_v-1] < w->long_value.ob_digit[size_w-1], so quotient has at most (and usually exactly) k = size_v - size_w digits. */ k = size_v - size_w; assert(k >= 0); @@ -2860,11 +3001,11 @@ x_divrem(PyLongObject *v1, PyLongObject *w1, PyLongObject **prem) *prem = NULL; return NULL; } - v0 = v->ob_digit; - w0 = w->ob_digit; + v0 = v->long_value.ob_digit; + w0 = w->long_value.ob_digit; wm1 = w0[size_w-1]; wm2 = w0[size_w-2]; - for (vk = v0+k, ak = a->ob_digit + k; vk-- > v0;) { + for (vk = v0+k, ak = a->long_value.ob_digit + k; vk-- > v0;) { /* inner loop: divide vk[0:size_w+1] by w0[0:size_w], giving single-digit quotient q, remainder in vk[0:size_w]. */ @@ -2963,13 +3104,13 @@ _PyLong_Frexp(PyLongObject *a, Py_ssize_t *e) multiple of 4, rounding ties to a multiple of 8. */ static const int half_even_correction[8] = {0, -1, -2, 1, 0, -1, 2, 1}; - a_size = Py_ABS(Py_SIZE(a)); + a_size = _PyLong_DigitCount(a); if (a_size == 0) { /* Special case for 0: significand 0.0, exponent 0. */ *e = 0; return 0.0; } - a_bits = bit_length_digit(a->ob_digit[a_size-1]); + a_bits = bit_length_digit(a->long_value.ob_digit[a_size-1]); /* The following is an overflow-free version of the check "if ((a_size - 1) * PyLong_SHIFT + a_bits > PY_SSIZE_T_MAX) ..." */ if (a_size >= (PY_SSIZE_T_MAX - 1) / PyLong_SHIFT + 1 && @@ -3007,7 +3148,7 @@ _PyLong_Frexp(PyLongObject *a, Py_ssize_t *e) shift_digits = (DBL_MANT_DIG + 2 - a_bits) / PyLong_SHIFT; shift_bits = (DBL_MANT_DIG + 2 - a_bits) % PyLong_SHIFT; x_size = shift_digits; - rem = v_lshift(x_digits + x_size, a->ob_digit, a_size, + rem = v_lshift(x_digits + x_size, a->long_value.ob_digit, a_size, (int)shift_bits); x_size += a_size; x_digits[x_size++] = rem; @@ -3015,7 +3156,7 @@ _PyLong_Frexp(PyLongObject *a, Py_ssize_t *e) else { shift_digits = (a_bits - DBL_MANT_DIG - 2) / PyLong_SHIFT; shift_bits = (a_bits - DBL_MANT_DIG - 2) % PyLong_SHIFT; - rem = v_rshift(x_digits, a->ob_digit + shift_digits, + rem = v_rshift(x_digits, a->long_value.ob_digit + shift_digits, a_size - shift_digits, (int)shift_bits); x_size = a_size - shift_digits; /* For correct rounding below, we need the least significant @@ -3026,7 +3167,7 @@ _PyLong_Frexp(PyLongObject *a, Py_ssize_t *e) x_digits[0] |= 1; else while (shift_digits > 0) - if (a->ob_digit[--shift_digits]) { + if (a->long_value.ob_digit[--shift_digits]) { x_digits[0] |= 1; break; } @@ -3049,7 +3190,7 @@ _PyLong_Frexp(PyLongObject *a, Py_ssize_t *e) } *e = a_bits; - return Py_SIZE(a) < 0 ? -dx : dx; + return _PyLong_IsNegative(a) ? -dx : dx; overflow: /* exponent > PY_SSIZE_T_MAX */ @@ -3076,7 +3217,7 @@ PyLong_AsDouble(PyObject *v) PyErr_SetString(PyExc_TypeError, "an integer is required"); return -1.0; } - if (IS_MEDIUM_VALUE(v)) { + if (_PyLong_IsCompact((PyLongObject *)v)) { /* Fast path; single digit long (31 bits) will cast safely to double. This improves performance of FP/long operations by 20%. @@ -3101,17 +3242,20 @@ PyLong_AsDouble(PyObject *v) static Py_ssize_t long_compare(PyLongObject *a, PyLongObject *b) { - Py_ssize_t sign = Py_SIZE(a) - Py_SIZE(b); + if (_PyLong_BothAreCompact(a, b)) { + return _PyLong_CompactValue(a) - _PyLong_CompactValue(b); + } + Py_ssize_t sign = _PyLong_SignedDigitCount(a) - _PyLong_SignedDigitCount(b); if (sign == 0) { - Py_ssize_t i = Py_ABS(Py_SIZE(a)); + Py_ssize_t i = _PyLong_DigitCount(a); sdigit diff = 0; while (--i >= 0) { - diff = (sdigit) a->ob_digit[i] - (sdigit) b->ob_digit[i]; + diff = (sdigit) a->long_value.ob_digit[i] - (sdigit) b->long_value.ob_digit[i]; if (diff) { break; } } - sign = Py_SIZE(a) < 0 ? -diff : diff; + sign = _PyLong_IsNegative(a) ? -diff : diff; } return sign; } @@ -3128,6 +3272,27 @@ long_richcompare(PyObject *self, PyObject *other, int op) Py_RETURN_RICHCOMPARE(result, 0, op); } +static void +long_dealloc(PyObject *self) +{ + /* This should never get called, but we also don't want to SEGV if + * we accidentally decref small Ints out of existence. Instead, + * since small Ints are immortal, re-set the reference count. + */ + PyLongObject *pylong = (PyLongObject*)self; + if (pylong && _PyLong_IsCompact(pylong)) { + stwodigits ival = medium_value(pylong); + if (IS_SMALL_INT(ival)) { + PyLongObject *small_pylong = (PyLongObject *)get_small_int((sdigit)ival); + if (pylong == small_pylong) { + _Py_SetImmortal(self); + return; + } + } + } + Py_TYPE(self)->tp_free(self); +} + static Py_hash_t long_hash(PyLongObject *v) { @@ -3135,21 +3300,19 @@ long_hash(PyLongObject *v) Py_ssize_t i; int sign; - i = Py_SIZE(v); - switch(i) { - case -1: return v->ob_digit[0]==1 ? -2 : -(sdigit)v->ob_digit[0]; - case 0: return 0; - case 1: return v->ob_digit[0]; + if (_PyLong_IsCompact(v)) { + x = _PyLong_CompactValue(v); + if (x == (Py_uhash_t)-1) { + x = (Py_uhash_t)-2; + } + return x; } - sign = 1; + i = _PyLong_DigitCount(v); + sign = _PyLong_NonCompactSign(v); x = 0; - if (i < 0) { - sign = -1; - i = -(i); - } while (--i >= 0) { /* Here x is a quantity in the range [0, _PyHASH_MODULUS); we - want to compute x * 2**PyLong_SHIFT + v->ob_digit[i] modulo + want to compute x * 2**PyLong_SHIFT + v->long_value.ob_digit[i] modulo _PyHASH_MODULUS. The computation of x * 2**PyLong_SHIFT % _PyHASH_MODULUS @@ -3175,7 +3338,7 @@ long_hash(PyLongObject *v) _PyHASH_MODULUS. */ x = ((x << PyLong_SHIFT) & _PyHASH_MODULUS) | (x >> (_PyHASH_BITS - PyLong_SHIFT)); - x += v->ob_digit[i]; + x += v->long_value.ob_digit[i]; if (x >= _PyHASH_MODULUS) x -= _PyHASH_MODULUS; } @@ -3191,7 +3354,7 @@ long_hash(PyLongObject *v) static PyLongObject * x_add(PyLongObject *a, PyLongObject *b) { - Py_ssize_t size_a = Py_ABS(Py_SIZE(a)), size_b = Py_ABS(Py_SIZE(b)); + Py_ssize_t size_a = _PyLong_DigitCount(a), size_b = _PyLong_DigitCount(b); PyLongObject *z; Py_ssize_t i; digit carry = 0; @@ -3207,16 +3370,16 @@ x_add(PyLongObject *a, PyLongObject *b) if (z == NULL) return NULL; for (i = 0; i < size_b; ++i) { - carry += a->ob_digit[i] + b->ob_digit[i]; - z->ob_digit[i] = carry & PyLong_MASK; + carry += a->long_value.ob_digit[i] + b->long_value.ob_digit[i]; + z->long_value.ob_digit[i] = carry & PyLong_MASK; carry >>= PyLong_SHIFT; } for (; i < size_a; ++i) { - carry += a->ob_digit[i]; - z->ob_digit[i] = carry & PyLong_MASK; + carry += a->long_value.ob_digit[i]; + z->long_value.ob_digit[i] = carry & PyLong_MASK; carry >>= PyLong_SHIFT; } - z->ob_digit[i] = carry; + z->long_value.ob_digit[i] = carry; return long_normalize(z); } @@ -3225,7 +3388,7 @@ x_add(PyLongObject *a, PyLongObject *b) static PyLongObject * x_sub(PyLongObject *a, PyLongObject *b) { - Py_ssize_t size_a = Py_ABS(Py_SIZE(a)), size_b = Py_ABS(Py_SIZE(b)); + Py_ssize_t size_a = _PyLong_DigitCount(a), size_b = _PyLong_DigitCount(b); PyLongObject *z; Py_ssize_t i; int sign = 1; @@ -3242,11 +3405,11 @@ x_sub(PyLongObject *a, PyLongObject *b) else if (size_a == size_b) { /* Find highest digit where a and b differ: */ i = size_a; - while (--i >= 0 && a->ob_digit[i] == b->ob_digit[i]) + while (--i >= 0 && a->long_value.ob_digit[i] == b->long_value.ob_digit[i]) ; if (i < 0) return (PyLongObject *)PyLong_FromLong(0); - if (a->ob_digit[i] < b->ob_digit[i]) { + if (a->long_value.ob_digit[i] < b->long_value.ob_digit[i]) { sign = -1; { PyLongObject *temp = a; a = b; b = temp; } } @@ -3258,20 +3421,20 @@ x_sub(PyLongObject *a, PyLongObject *b) for (i = 0; i < size_b; ++i) { /* The following assumes unsigned arithmetic works module 2**N for some N>PyLong_SHIFT. */ - borrow = a->ob_digit[i] - b->ob_digit[i] - borrow; - z->ob_digit[i] = borrow & PyLong_MASK; + borrow = a->long_value.ob_digit[i] - b->long_value.ob_digit[i] - borrow; + z->long_value.ob_digit[i] = borrow & PyLong_MASK; borrow >>= PyLong_SHIFT; borrow &= 1; /* Keep only one sign bit */ } for (; i < size_a; ++i) { - borrow = a->ob_digit[i] - borrow; - z->ob_digit[i] = borrow & PyLong_MASK; + borrow = a->long_value.ob_digit[i] - borrow; + z->long_value.ob_digit[i] = borrow & PyLong_MASK; borrow >>= PyLong_SHIFT; borrow &= 1; /* Keep only one sign bit */ } assert(borrow == 0); if (sign < 0) { - Py_SET_SIZE(z, -Py_SIZE(z)); + _PyLong_FlipSign(z); } return maybe_small_long(long_normalize(z)); } @@ -3279,13 +3442,13 @@ x_sub(PyLongObject *a, PyLongObject *b) PyObject * _PyLong_Add(PyLongObject *a, PyLongObject *b) { - if (IS_MEDIUM_VALUE(a) && IS_MEDIUM_VALUE(b)) { + if (_PyLong_BothAreCompact(a, b)) { return _PyLong_FromSTwoDigits(medium_value(a) + medium_value(b)); } PyLongObject *z; - if (Py_SIZE(a) < 0) { - if (Py_SIZE(b) < 0) { + if (_PyLong_IsNegative(a)) { + if (_PyLong_IsNegative(b)) { z = x_add(a, b); if (z != NULL) { /* x_add received at least one multiple-digit int, @@ -3293,14 +3456,14 @@ _PyLong_Add(PyLongObject *a, PyLongObject *b) That also means z is not an element of small_ints, so negating it in-place is safe. */ assert(Py_REFCNT(z) == 1); - Py_SET_SIZE(z, -(Py_SIZE(z))); + _PyLong_FlipSign(z); } } else z = x_sub(b, a); } else { - if (Py_SIZE(b) < 0) + if (_PyLong_IsNegative(b)) z = x_sub(a, b); else z = x_add(a, b); @@ -3320,23 +3483,23 @@ _PyLong_Subtract(PyLongObject *a, PyLongObject *b) { PyLongObject *z; - if (IS_MEDIUM_VALUE(a) && IS_MEDIUM_VALUE(b)) { + if (_PyLong_BothAreCompact(a, b)) { return _PyLong_FromSTwoDigits(medium_value(a) - medium_value(b)); } - if (Py_SIZE(a) < 0) { - if (Py_SIZE(b) < 0) { + if (_PyLong_IsNegative(a)) { + if (_PyLong_IsNegative(b)) { z = x_sub(b, a); } else { z = x_add(a, b); if (z != NULL) { - assert(Py_SIZE(z) == 0 || Py_REFCNT(z) == 1); - Py_SET_SIZE(z, -(Py_SIZE(z))); + assert(_PyLong_IsZero(z) || Py_REFCNT(z) == 1); + _PyLong_FlipSign(z); } } } else { - if (Py_SIZE(b) < 0) + if (_PyLong_IsNegative(b)) z = x_add(a, b); else z = x_sub(a, b); @@ -3358,15 +3521,15 @@ static PyLongObject * x_mul(PyLongObject *a, PyLongObject *b) { PyLongObject *z; - Py_ssize_t size_a = Py_ABS(Py_SIZE(a)); - Py_ssize_t size_b = Py_ABS(Py_SIZE(b)); + Py_ssize_t size_a = _PyLong_DigitCount(a); + Py_ssize_t size_b = _PyLong_DigitCount(b); Py_ssize_t i; z = _PyLong_New(size_a + size_b); if (z == NULL) return NULL; - memset(z->ob_digit, 0, Py_SIZE(z) * sizeof(digit)); + memset(z->long_value.ob_digit, 0, _PyLong_DigitCount(z) * sizeof(digit)); if (a == b) { /* Efficient squaring per HAC, Algorithm 14.16: * http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf @@ -3374,12 +3537,12 @@ x_mul(PyLongObject *a, PyLongObject *b) * via exploiting that each entry in the multiplication * pyramid appears twice (except for the size_a squares). */ - digit *paend = a->ob_digit + size_a; + digit *paend = a->long_value.ob_digit + size_a; for (i = 0; i < size_a; ++i) { twodigits carry; - twodigits f = a->ob_digit[i]; - digit *pz = z->ob_digit + (i << 1); - digit *pa = a->ob_digit + i + 1; + twodigits f = a->long_value.ob_digit[i]; + digit *pz = z->long_value.ob_digit + (i << 1); + digit *pa = a->long_value.ob_digit + i + 1; SIGCHECK({ Py_DECREF(z); @@ -3428,10 +3591,10 @@ x_mul(PyLongObject *a, PyLongObject *b) else { /* a is not the same as b -- gradeschool int mult */ for (i = 0; i < size_a; ++i) { twodigits carry = 0; - twodigits f = a->ob_digit[i]; - digit *pz = z->ob_digit + i; - digit *pb = b->ob_digit; - digit *pbend = b->ob_digit + size_b; + twodigits f = a->long_value.ob_digit[i]; + digit *pz = z->long_value.ob_digit + i; + digit *pb = b->long_value.ob_digit; + digit *pbend = b->long_value.ob_digit + size_b; SIGCHECK({ Py_DECREF(z); @@ -3467,7 +3630,7 @@ kmul_split(PyLongObject *n, { PyLongObject *hi, *lo; Py_ssize_t size_lo, size_hi; - const Py_ssize_t size_n = Py_ABS(Py_SIZE(n)); + const Py_ssize_t size_n = _PyLong_DigitCount(n); size_lo = Py_MIN(size_n, size); size_hi = size_n - size_lo; @@ -3479,8 +3642,8 @@ kmul_split(PyLongObject *n, return -1; } - memcpy(lo->ob_digit, n->ob_digit, size_lo * sizeof(digit)); - memcpy(hi->ob_digit, n->ob_digit + size_lo, size_hi * sizeof(digit)); + memcpy(lo->long_value.ob_digit, n->long_value.ob_digit, size_lo * sizeof(digit)); + memcpy(hi->long_value.ob_digit, n->long_value.ob_digit + size_lo, size_hi * sizeof(digit)); *high = long_normalize(hi); *low = long_normalize(lo); @@ -3496,8 +3659,8 @@ static PyLongObject *k_lopsided_mul(PyLongObject *a, PyLongObject *b); static PyLongObject * k_mul(PyLongObject *a, PyLongObject *b) { - Py_ssize_t asize = Py_ABS(Py_SIZE(a)); - Py_ssize_t bsize = Py_ABS(Py_SIZE(b)); + Py_ssize_t asize = _PyLong_DigitCount(a); + Py_ssize_t bsize = _PyLong_DigitCount(b); PyLongObject *ah = NULL; PyLongObject *al = NULL; PyLongObject *bh = NULL; @@ -3540,7 +3703,7 @@ k_mul(PyLongObject *a, PyLongObject *b) /* If a is small compared to b, splitting on b gives a degenerate * case with ah==0, and Karatsuba may be (even much) less efficient * than "grade school" then. However, we can still win, by viewing - * b as a string of "big digits", each of width a->ob_size. That + * b as a string of "big digits", each of the same width as a. That * leads to a sequence of balanced calls to k_mul. */ if (2 * asize <= bsize) @@ -3549,13 +3712,11 @@ k_mul(PyLongObject *a, PyLongObject *b) /* Split a & b into hi & lo pieces. */ shift = bsize >> 1; if (kmul_split(a, shift, &ah, &al) < 0) goto fail; - assert(Py_SIZE(ah) > 0); /* the split isn't degenerate */ + assert(_PyLong_IsPositive(ah)); /* the split isn't degenerate */ if (a == b) { - bh = ah; - bl = al; - Py_INCREF(bh); - Py_INCREF(bl); + bh = (PyLongObject*)Py_NewRef(ah); + bl = (PyLongObject*)Py_NewRef(al); } else if (kmul_split(b, shift, &bh, &bl) < 0) goto fail; @@ -3580,20 +3741,20 @@ k_mul(PyLongObject *a, PyLongObject *b) if (ret == NULL) goto fail; #ifdef Py_DEBUG /* Fill with trash, to catch reference to uninitialized digits. */ - memset(ret->ob_digit, 0xDF, Py_SIZE(ret) * sizeof(digit)); + memset(ret->long_value.ob_digit, 0xDF, _PyLong_DigitCount(ret) * sizeof(digit)); #endif /* 2. t1 <- ah*bh, and copy into high digits of result. */ if ((t1 = k_mul(ah, bh)) == NULL) goto fail; - assert(Py_SIZE(t1) >= 0); - assert(2*shift + Py_SIZE(t1) <= Py_SIZE(ret)); - memcpy(ret->ob_digit + 2*shift, t1->ob_digit, - Py_SIZE(t1) * sizeof(digit)); + assert(!_PyLong_IsNegative(t1)); + assert(2*shift + _PyLong_DigitCount(t1) <= _PyLong_DigitCount(ret)); + memcpy(ret->long_value.ob_digit + 2*shift, t1->long_value.ob_digit, + _PyLong_DigitCount(t1) * sizeof(digit)); /* Zero-out the digits higher than the ah*bh copy. */ - i = Py_SIZE(ret) - 2*shift - Py_SIZE(t1); + i = _PyLong_DigitCount(ret) - 2*shift - _PyLong_DigitCount(t1); if (i) - memset(ret->ob_digit + 2*shift + Py_SIZE(t1), 0, + memset(ret->long_value.ob_digit + 2*shift + _PyLong_DigitCount(t1), 0, i * sizeof(digit)); /* 3. t2 <- al*bl, and copy into the low digits. */ @@ -3601,23 +3762,23 @@ k_mul(PyLongObject *a, PyLongObject *b) Py_DECREF(t1); goto fail; } - assert(Py_SIZE(t2) >= 0); - assert(Py_SIZE(t2) <= 2*shift); /* no overlap with high digits */ - memcpy(ret->ob_digit, t2->ob_digit, Py_SIZE(t2) * sizeof(digit)); + assert(!_PyLong_IsNegative(t2)); + assert(_PyLong_DigitCount(t2) <= 2*shift); /* no overlap with high digits */ + memcpy(ret->long_value.ob_digit, t2->long_value.ob_digit, _PyLong_DigitCount(t2) * sizeof(digit)); /* Zero out remaining digits. */ - i = 2*shift - Py_SIZE(t2); /* number of uninitialized digits */ + i = 2*shift - _PyLong_DigitCount(t2); /* number of uninitialized digits */ if (i) - memset(ret->ob_digit + Py_SIZE(t2), 0, i * sizeof(digit)); + memset(ret->long_value.ob_digit + _PyLong_DigitCount(t2), 0, i * sizeof(digit)); /* 4 & 5. Subtract ah*bh (t1) and al*bl (t2). We do al*bl first * because it's fresher in cache. */ - i = Py_SIZE(ret) - shift; /* # digits after shift */ - (void)v_isub(ret->ob_digit + shift, i, t2->ob_digit, Py_SIZE(t2)); + i = _PyLong_DigitCount(ret) - shift; /* # digits after shift */ + (void)v_isub(ret->long_value.ob_digit + shift, i, t2->long_value.ob_digit, _PyLong_DigitCount(t2)); _Py_DECREF_INT(t2); - (void)v_isub(ret->ob_digit + shift, i, t1->ob_digit, Py_SIZE(t1)); + (void)v_isub(ret->long_value.ob_digit + shift, i, t1->long_value.ob_digit, _PyLong_DigitCount(t1)); _Py_DECREF_INT(t1); /* 6. t3 <- (ah+al)(bh+bl), and add into result. */ @@ -3627,8 +3788,7 @@ k_mul(PyLongObject *a, PyLongObject *b) ah = al = NULL; if (a == b) { - t2 = t1; - Py_INCREF(t2); + t2 = (PyLongObject*)Py_NewRef(t1); } else if ((t2 = x_add(bh, bl)) == NULL) { Py_DECREF(t1); @@ -3642,12 +3802,12 @@ k_mul(PyLongObject *a, PyLongObject *b) _Py_DECREF_INT(t1); _Py_DECREF_INT(t2); if (t3 == NULL) goto fail; - assert(Py_SIZE(t3) >= 0); + assert(!_PyLong_IsNegative(t3)); /* Add t3. It's not obvious why we can't run out of room here. * See the (*) comment after this function. */ - (void)v_iadd(ret->ob_digit + shift, i, t3->ob_digit, Py_SIZE(t3)); + (void)v_iadd(ret->long_value.ob_digit + shift, i, t3->long_value.ob_digit, _PyLong_DigitCount(t3)); _Py_DECREF_INT(t3); return long_normalize(ret); @@ -3708,17 +3868,17 @@ ah*bh and al*bl too. /* b has at least twice the digits of a, and a is big enough that Karatsuba * would pay off *if* the inputs had balanced sizes. View b as a sequence - * of slices, each with a->ob_size digits, and multiply the slices by a, - * one at a time. This gives k_mul balanced inputs to work with, and is - * also cache-friendly (we compute one double-width slice of the result + * of slices, each with the same number of digits as a, and multiply the + * slices by a, one at a time. This gives k_mul balanced inputs to work with, + * and is also cache-friendly (we compute one double-width slice of the result * at a time, then move on, never backtracking except for the helpful * single-width slice overlap between successive partial sums). */ static PyLongObject * k_lopsided_mul(PyLongObject *a, PyLongObject *b) { - const Py_ssize_t asize = Py_ABS(Py_SIZE(a)); - Py_ssize_t bsize = Py_ABS(Py_SIZE(b)); + const Py_ssize_t asize = _PyLong_DigitCount(a); + Py_ssize_t bsize = _PyLong_DigitCount(b); Py_ssize_t nbdone; /* # of b digits already multiplied */ PyLongObject *ret; PyLongObject *bslice = NULL; @@ -3730,7 +3890,7 @@ k_lopsided_mul(PyLongObject *a, PyLongObject *b) ret = _PyLong_New(asize + bsize); if (ret == NULL) return NULL; - memset(ret->ob_digit, 0, Py_SIZE(ret) * sizeof(digit)); + memset(ret->long_value.ob_digit, 0, _PyLong_DigitCount(ret) * sizeof(digit)); /* Successive slices of b are copied into bslice. */ bslice = _PyLong_New(asize); @@ -3743,16 +3903,17 @@ k_lopsided_mul(PyLongObject *a, PyLongObject *b) const Py_ssize_t nbtouse = Py_MIN(bsize, asize); /* Multiply the next slice of b by a. */ - memcpy(bslice->ob_digit, b->ob_digit + nbdone, + memcpy(bslice->long_value.ob_digit, b->long_value.ob_digit + nbdone, nbtouse * sizeof(digit)); - Py_SET_SIZE(bslice, nbtouse); + assert(nbtouse >= 0); + _PyLong_SetSignAndDigitCount(bslice, 1, nbtouse); product = k_mul(a, bslice); if (product == NULL) goto fail; /* Add into result. */ - (void)v_iadd(ret->ob_digit + nbdone, Py_SIZE(ret) - nbdone, - product->ob_digit, Py_SIZE(product)); + (void)v_iadd(ret->long_value.ob_digit + nbdone, _PyLong_DigitCount(ret) - nbdone, + product->long_value.ob_digit, _PyLong_DigitCount(product)); _Py_DECREF_INT(product); bsize -= nbtouse; @@ -3774,14 +3935,14 @@ _PyLong_Multiply(PyLongObject *a, PyLongObject *b) PyLongObject *z; /* fast path for single-digit multiplication */ - if (IS_MEDIUM_VALUE(a) && IS_MEDIUM_VALUE(b)) { + if (_PyLong_BothAreCompact(a, b)) { stwodigits v = medium_value(a) * medium_value(b); return _PyLong_FromSTwoDigits(v); } z = k_mul(a, b); /* Negate if exactly one of the inputs is negative. */ - if (((Py_SIZE(a) ^ Py_SIZE(b)) < 0) && z) { + if (!_PyLong_SameSign(a, b) && z) { _PyLong_Negate(&z); if (z == NULL) return NULL; @@ -3800,15 +3961,14 @@ long_mul(PyLongObject *a, PyLongObject *b) static PyObject * fast_mod(PyLongObject *a, PyLongObject *b) { - sdigit left = a->ob_digit[0]; - sdigit right = b->ob_digit[0]; + sdigit left = a->long_value.ob_digit[0]; + sdigit right = b->long_value.ob_digit[0]; sdigit mod; - assert(Py_ABS(Py_SIZE(a)) == 1); - assert(Py_ABS(Py_SIZE(b)) == 1); - - if (Py_SIZE(a) == Py_SIZE(b)) { - /* 'a' and 'b' have the same sign. */ + assert(_PyLong_DigitCount(a) == 1); + assert(_PyLong_DigitCount(b) == 1); + sdigit sign = _PyLong_CompactSign(b); + if (_PyLong_SameSign(a, b)) { mod = left % right; } else { @@ -3816,22 +3976,21 @@ fast_mod(PyLongObject *a, PyLongObject *b) mod = right - 1 - (left - 1) % right; } - return PyLong_FromLong(mod * (sdigit)Py_SIZE(b)); + return PyLong_FromLong(mod * sign); } /* Fast floor division for single-digit longs. */ static PyObject * fast_floor_div(PyLongObject *a, PyLongObject *b) { - sdigit left = a->ob_digit[0]; - sdigit right = b->ob_digit[0]; + sdigit left = a->long_value.ob_digit[0]; + sdigit right = b->long_value.ob_digit[0]; sdigit div; - assert(Py_ABS(Py_SIZE(a)) == 1); - assert(Py_ABS(Py_SIZE(b)) == 1); + assert(_PyLong_DigitCount(a) == 1); + assert(_PyLong_DigitCount(b) == 1); - if (Py_SIZE(a) == Py_SIZE(b)) { - /* 'a' and 'b' have the same sign. */ + if (_PyLong_SameSign(a, b)) { div = left / right; } else { @@ -3842,6 +4001,46 @@ fast_floor_div(PyLongObject *a, PyLongObject *b) return PyLong_FromLong(div); } +#ifdef WITH_PYLONG_MODULE +/* asymptotically faster divmod, using _pylong.py */ +static int +pylong_int_divmod(PyLongObject *v, PyLongObject *w, + PyLongObject **pdiv, PyLongObject **pmod) +{ + PyObject *mod = PyImport_ImportModule("_pylong"); + if (mod == NULL) { + return -1; + } + PyObject *result = PyObject_CallMethod(mod, "int_divmod", "OO", v, w); + Py_DECREF(mod); + if (result == NULL) { + return -1; + } + if (!PyTuple_Check(result)) { + Py_DECREF(result); + PyErr_SetString(PyExc_ValueError, + "tuple is required from int_divmod()"); + return -1; + } + PyObject *q = PyTuple_GET_ITEM(result, 0); + PyObject *r = PyTuple_GET_ITEM(result, 1); + if (!PyLong_Check(q) || !PyLong_Check(r)) { + Py_DECREF(result); + PyErr_SetString(PyExc_ValueError, + "tuple of int is required from int_divmod()"); + return -1; + } + if (pdiv != NULL) { + *pdiv = (PyLongObject *)Py_NewRef(q); + } + if (pmod != NULL) { + *pmod = (PyLongObject *)Py_NewRef(r); + } + Py_DECREF(result); + return 0; +} +#endif /* WITH_PYLONG_MODULE */ + /* The / and % operators are now defined in terms of divmod(). The expression a mod b has the value a - b*floor(a/b). The long_divrem function gives the remainder after division of @@ -3869,7 +4068,7 @@ l_divmod(PyLongObject *v, PyLongObject *w, { PyLongObject *div, *mod; - if (Py_ABS(Py_SIZE(v)) == 1 && Py_ABS(Py_SIZE(w)) == 1) { + if (_PyLong_DigitCount(v) == 1 && _PyLong_DigitCount(w) == 1) { /* Fast path for single-digit longs */ div = NULL; if (pdiv != NULL) { @@ -3893,14 +4092,25 @@ l_divmod(PyLongObject *v, PyLongObject *w, } return 0; } +#if WITH_PYLONG_MODULE + Py_ssize_t size_v = _PyLong_DigitCount(v); /* digits in numerator */ + Py_ssize_t size_w = _PyLong_DigitCount(w); /* digits in denominator */ + if (size_w > 300 && (size_v - size_w) > 150) { + /* Switch to _pylong.int_divmod(). If the quotient is small then + "schoolbook" division is linear-time so don't use in that case. + These limits are empirically determined and should be slightly + conservative so that _pylong is used in cases it is likely + to be faster. See Tools/scripts/divmod_threshold.py. */ + return pylong_int_divmod(v, w, pdiv, pmod); + } +#endif if (long_divrem(v, w, &div, &mod) < 0) return -1; - if ((Py_SIZE(mod) < 0 && Py_SIZE(w) > 0) || - (Py_SIZE(mod) > 0 && Py_SIZE(w) < 0)) { + if ((_PyLong_IsNegative(mod) && _PyLong_IsPositive(w)) || + (_PyLong_IsPositive(mod) && _PyLong_IsNegative(w))) { PyLongObject *temp; temp = (PyLongObject *) long_add(mod, w); - Py_DECREF(mod); - mod = temp; + Py_SETREF(mod, temp); if (mod == NULL) { Py_DECREF(div); return -1; @@ -3911,8 +4121,7 @@ l_divmod(PyLongObject *v, PyLongObject *w, Py_DECREF(div); return -1; } - Py_DECREF(div); - div = temp; + Py_SETREF(div, temp); } if (pdiv != NULL) *pdiv = div; @@ -3937,19 +4146,18 @@ l_mod(PyLongObject *v, PyLongObject *w, PyLongObject **pmod) PyLongObject *mod; assert(pmod); - if (Py_ABS(Py_SIZE(v)) == 1 && Py_ABS(Py_SIZE(w)) == 1) { + if (_PyLong_DigitCount(v) == 1 && _PyLong_DigitCount(w) == 1) { /* Fast path for single-digit longs */ *pmod = (PyLongObject *)fast_mod(v, w); return -(*pmod == NULL); } if (long_rem(v, w, &mod) < 0) return -1; - if ((Py_SIZE(mod) < 0 && Py_SIZE(w) > 0) || - (Py_SIZE(mod) > 0 && Py_SIZE(w) < 0)) { + if ((_PyLong_IsNegative(mod) && _PyLong_IsPositive(w)) || + (_PyLong_IsPositive(mod) && _PyLong_IsNegative(w))) { PyLongObject *temp; temp = (PyLongObject *) long_add(mod, w); - Py_DECREF(mod); - mod = temp; + Py_SETREF(mod, temp); if (mod == NULL) return -1; } @@ -3965,7 +4173,7 @@ long_div(PyObject *a, PyObject *b) CHECK_BINOP(a, b); - if (Py_ABS(Py_SIZE(a)) == 1 && Py_ABS(Py_SIZE(b)) == 1) { + if (_PyLong_DigitCount((PyLongObject*)a) == 1 && _PyLong_DigitCount((PyLongObject*)b) == 1) { return fast_floor_div((PyLongObject*)a, (PyLongObject*)b); } @@ -4080,9 +4288,9 @@ long_true_divide(PyObject *v, PyObject *w) */ /* Reduce to case where a and b are both positive. */ - a_size = Py_ABS(Py_SIZE(a)); - b_size = Py_ABS(Py_SIZE(b)); - negate = (Py_SIZE(a) < 0) ^ (Py_SIZE(b) < 0); + a_size = _PyLong_DigitCount(a); + b_size = _PyLong_DigitCount(b); + negate = (_PyLong_IsNegative(a)) != (_PyLong_IsNegative(b)); if (b_size == 0) { PyErr_SetString(PyExc_ZeroDivisionError, "division by zero"); @@ -4097,18 +4305,18 @@ long_true_divide(PyObject *v, PyObject *w) the x87 FPU set to 64-bit precision. */ a_is_small = a_size <= MANT_DIG_DIGITS || (a_size == MANT_DIG_DIGITS+1 && - a->ob_digit[MANT_DIG_DIGITS] >> MANT_DIG_BITS == 0); + a->long_value.ob_digit[MANT_DIG_DIGITS] >> MANT_DIG_BITS == 0); b_is_small = b_size <= MANT_DIG_DIGITS || (b_size == MANT_DIG_DIGITS+1 && - b->ob_digit[MANT_DIG_DIGITS] >> MANT_DIG_BITS == 0); + b->long_value.ob_digit[MANT_DIG_DIGITS] >> MANT_DIG_BITS == 0); if (a_is_small && b_is_small) { double da, db; - da = a->ob_digit[--a_size]; + da = a->long_value.ob_digit[--a_size]; while (a_size > 0) - da = da * PyLong_BASE + a->ob_digit[--a_size]; - db = b->ob_digit[--b_size]; + da = da * PyLong_BASE + a->long_value.ob_digit[--a_size]; + db = b->long_value.ob_digit[--b_size]; while (b_size > 0) - db = db * PyLong_BASE + b->ob_digit[--b_size]; + db = db * PyLong_BASE + b->long_value.ob_digit[--b_size]; result = da / db; goto success; } @@ -4122,8 +4330,8 @@ long_true_divide(PyObject *v, PyObject *w) /* Extreme underflow */ goto underflow_or_zero; /* Next line is now safe from overflowing a Py_ssize_t */ - diff = diff * PyLong_SHIFT + bit_length_digit(a->ob_digit[a_size - 1]) - - bit_length_digit(b->ob_digit[b_size - 1]); + diff = diff * PyLong_SHIFT + bit_length_digit(a->long_value.ob_digit[a_size - 1]) - + bit_length_digit(b->long_value.ob_digit[b_size - 1]); /* Now diff = a_bits - b_bits. */ if (diff > DBL_MAX_EXP) goto overflow; @@ -4152,10 +4360,10 @@ long_true_divide(PyObject *v, PyObject *w) if (x == NULL) goto error; for (i = 0; i < shift_digits; i++) - x->ob_digit[i] = 0; - rem = v_lshift(x->ob_digit + shift_digits, a->ob_digit, + x->long_value.ob_digit[i] = 0; + rem = v_lshift(x->long_value.ob_digit + shift_digits, a->long_value.ob_digit, a_size, -shift % PyLong_SHIFT); - x->ob_digit[a_size + shift_digits] = rem; + x->long_value.ob_digit[a_size + shift_digits] = rem; } else { Py_ssize_t shift_digits = shift / PyLong_SHIFT; @@ -4165,23 +4373,23 @@ long_true_divide(PyObject *v, PyObject *w) x = _PyLong_New(a_size - shift_digits); if (x == NULL) goto error; - rem = v_rshift(x->ob_digit, a->ob_digit + shift_digits, + rem = v_rshift(x->long_value.ob_digit, a->long_value.ob_digit + shift_digits, a_size - shift_digits, shift % PyLong_SHIFT); /* set inexact if any of the bits shifted out is nonzero */ if (rem) inexact = 1; while (!inexact && shift_digits > 0) - if (a->ob_digit[--shift_digits]) + if (a->long_value.ob_digit[--shift_digits]) inexact = 1; } long_normalize(x); - x_size = Py_SIZE(x); + x_size = _PyLong_SignedDigitCount(x); /* x //= b. If the remainder is nonzero, set inexact. We own the only reference to x, so it's safe to modify it in-place. */ if (b_size == 1) { - digit rem = inplace_divrem1(x->ob_digit, x->ob_digit, x_size, - b->ob_digit[0]); + digit rem = inplace_divrem1(x->long_value.ob_digit, x->long_value.ob_digit, x_size, + b->long_value.ob_digit[0]); long_normalize(x); if (rem) inexact = 1; @@ -4189,17 +4397,16 @@ long_true_divide(PyObject *v, PyObject *w) else { PyLongObject *div, *rem; div = x_divrem(x, b, &rem); - Py_DECREF(x); - x = div; + Py_SETREF(x, div); if (x == NULL) goto error; - if (Py_SIZE(rem)) + if (!_PyLong_IsZero(rem)) inexact = 1; Py_DECREF(rem); } - x_size = Py_ABS(Py_SIZE(x)); + x_size = _PyLong_DigitCount(x); assert(x_size > 0); /* result of division is never zero */ - x_bits = (x_size-1)*PyLong_SHIFT+bit_length_digit(x->ob_digit[x_size-1]); + x_bits = (x_size-1)*PyLong_SHIFT+bit_length_digit(x->long_value.ob_digit[x_size-1]); /* The number of extra bits that have to be rounded away. */ extra_bits = Py_MAX(x_bits, DBL_MIN_EXP - shift) - DBL_MANT_DIG; @@ -4207,15 +4414,15 @@ long_true_divide(PyObject *v, PyObject *w) /* Round by directly modifying the low digit of x. */ mask = (digit)1 << (extra_bits - 1); - low = x->ob_digit[0] | inexact; + low = x->long_value.ob_digit[0] | inexact; if ((low & mask) && (low & (3U*mask-1U))) low += mask; - x->ob_digit[0] = low & ~(2U*mask-1U); + x->long_value.ob_digit[0] = low & ~(2U*mask-1U); /* Convert x to a double dx; the conversion is exact. */ - dx = x->ob_digit[--x_size]; + dx = x->long_value.ob_digit[--x_size]; while (x_size > 0) - dx = dx * PyLong_BASE + x->ob_digit[--x_size]; + dx = dx * PyLong_BASE + x->long_value.ob_digit[--x_size]; Py_DECREF(x); /* Check whether ldexp result will overflow a double. */ @@ -4299,7 +4506,7 @@ long_invmod(PyLongObject *a, PyLongObject *n) PyLongObject *b, *c; /* Should only ever be called for positive n */ - assert(Py_SIZE(n) > 0); + assert(_PyLong_IsPositive(n)); b = (PyLongObject *)PyLong_FromLong(1L); if (b == NULL) { @@ -4314,14 +4521,13 @@ long_invmod(PyLongObject *a, PyLongObject *n) Py_INCREF(n); /* references now owned: a, b, c, n */ - while (Py_SIZE(n) != 0) { + while (!_PyLong_IsZero(n)) { PyLongObject *q, *r, *s, *t; if (l_divmod(a, n, &q, &r) == -1) { goto Error; } - Py_DECREF(a); - a = n; + Py_SETREF(a, n); n = r; t = (PyLongObject *)long_mul(q, c); Py_DECREF(q); @@ -4333,8 +4539,7 @@ long_invmod(PyLongObject *a, PyLongObject *n) if (s == NULL) { goto Error; } - Py_DECREF(b); - b = c; + Py_SETREF(b, c); c = s; } /* references now owned: a, b, c, n */ @@ -4379,7 +4584,7 @@ long_pow(PyObject *v, PyObject *w, PyObject *x) /* k-ary values. If the exponent is large enough, table is * precomputed so that table[i] == a**(2*i+1) % c for i in * range(EXP_TABLE_LEN). - * Note: this is uninitialzed stack trash: don't pay to set it to known + * Note: this is uninitialized stack trash: don't pay to set it to known * values unless it's needed. Instead ensure that num_table_entries is * set to the number of entries actually filled whenever a branch to the * Error or Done labels is possible. @@ -4389,11 +4594,10 @@ long_pow(PyObject *v, PyObject *w, PyObject *x) /* a, b, c = v, w, x */ CHECK_BINOP(v, w); - a = (PyLongObject*)v; Py_INCREF(a); - b = (PyLongObject*)w; Py_INCREF(b); + a = (PyLongObject*)Py_NewRef(v); + b = (PyLongObject*)Py_NewRef(w); if (PyLong_Check(x)) { - c = (PyLongObject *)x; - Py_INCREF(x); + c = (PyLongObject *)Py_NewRef(x); } else if (x == Py_None) c = NULL; @@ -4403,7 +4607,7 @@ long_pow(PyObject *v, PyObject *w, PyObject *x) Py_RETURN_NOTIMPLEMENTED; } - if (Py_SIZE(b) < 0 && c == NULL) { + if (_PyLong_IsNegative(b) && c == NULL) { /* if exponent is negative and there's no modulus: return a float. This works because we know that this calls float_pow() which converts its @@ -4416,7 +4620,7 @@ long_pow(PyObject *v, PyObject *w, PyObject *x) if (c) { /* if modulus == 0: raise ValueError() */ - if (Py_SIZE(c) == 0) { + if (_PyLong_IsZero(c)) { PyErr_SetString(PyExc_ValueError, "pow() 3rd argument cannot be 0"); goto Error; @@ -4425,13 +4629,12 @@ long_pow(PyObject *v, PyObject *w, PyObject *x) /* if modulus < 0: negativeOutput = True modulus = -modulus */ - if (Py_SIZE(c) < 0) { + if (_PyLong_IsNegative(c)) { negativeOutput = 1; temp = (PyLongObject *)_PyLong_Copy(c); if (temp == NULL) goto Error; - Py_DECREF(c); - c = temp; + Py_SETREF(c, temp); temp = NULL; _PyLong_Negate(&c); if (c == NULL) @@ -4440,19 +4643,18 @@ long_pow(PyObject *v, PyObject *w, PyObject *x) /* if modulus == 1: return 0 */ - if ((Py_SIZE(c) == 1) && (c->ob_digit[0] == 1)) { + if (_PyLong_IsNonNegativeCompact(c) && (c->long_value.ob_digit[0] == 1)) { z = (PyLongObject *)PyLong_FromLong(0L); goto Done; } /* if exponent is negative, negate the exponent and replace the base with a modular inverse */ - if (Py_SIZE(b) < 0) { + if (_PyLong_IsNegative(b)) { temp = (PyLongObject *)_PyLong_Copy(b); if (temp == NULL) goto Error; - Py_DECREF(b); - b = temp; + Py_SETREF(b, temp); temp = NULL; _PyLong_Negate(&b); if (b == NULL) @@ -4461,8 +4663,7 @@ long_pow(PyObject *v, PyObject *w, PyObject *x) temp = long_invmod(a, c); if (temp == NULL) goto Error; - Py_DECREF(a); - a = temp; + Py_SETREF(a, temp); temp = NULL; } @@ -4475,11 +4676,10 @@ long_pow(PyObject *v, PyObject *w, PyObject *x) base % modulus instead. We could _always_ do this reduction, but l_mod() isn't cheap, so we only do it when it buys something. */ - if (Py_SIZE(a) < 0 || Py_SIZE(a) > Py_SIZE(c)) { + if (_PyLong_IsNegative(a) || _PyLong_DigitCount(a) > _PyLong_DigitCount(c)) { if (l_mod(a, c, &temp) < 0) goto Error; - Py_DECREF(a); - a = temp; + Py_SETREF(a, temp); temp = NULL; } } @@ -4518,8 +4718,8 @@ long_pow(PyObject *v, PyObject *w, PyObject *x) REDUCE(result); \ } while(0) - i = Py_SIZE(b); - digit bi = i ? b->ob_digit[i-1] : 0; + i = _PyLong_SignedDigitCount(b); + digit bi = i ? b->long_value.ob_digit[i-1] : 0; digit bit; if (i <= 1 && bi <= 3) { /* aim for minimal overhead */ @@ -4546,9 +4746,7 @@ long_pow(PyObject *v, PyObject *w, PyObject *x) * because we're primarily trying to cut overhead for small powers. */ assert(bi); /* else there is no significant bit */ - Py_INCREF(a); - Py_DECREF(z); - z = a; + Py_SETREF(z, (PyLongObject*)Py_NewRef(a)); for (bit = 2; ; bit <<= 1) { if (bit > bi) { /* found the first bit */ assert((bi & bit) == 0); @@ -4567,7 +4765,7 @@ long_pow(PyObject *v, PyObject *w, PyObject *x) if (--i < 0) { break; } - bi = b->ob_digit[i]; + bi = b->long_value.ob_digit[i]; bit = (digit)1 << (PyLong_SHIFT-1); } } @@ -4575,8 +4773,7 @@ long_pow(PyObject *v, PyObject *w, PyObject *x) /* Left-to-right k-ary sliding window exponentiation * (Handbook of Applied Cryptography (HAC) Algorithm 14.85) */ - Py_INCREF(a); - table[0] = a; + table[0] = (PyLongObject*)Py_NewRef(a); num_table_entries = 1; MULT(a, a, a2); /* table[i] == a**(2*i + 1) % c */ @@ -4613,8 +4810,8 @@ long_pow(PyObject *v, PyObject *w, PyObject *x) pending = 0; \ } while(0) - for (i = Py_SIZE(b) - 1; i >= 0; --i) { - const digit bi = b->ob_digit[i]; + for (i = _PyLong_SignedDigitCount(b) - 1; i >= 0; --i) { + const digit bi = b->long_value.ob_digit[i]; for (j = PyLong_SHIFT - 1; j >= 0; --j) { const int bit = (bi >> j) & 1; pending = (pending << 1) | bit; @@ -4631,12 +4828,11 @@ long_pow(PyObject *v, PyObject *w, PyObject *x) ABSORB_PENDING; } - if (negativeOutput && (Py_SIZE(z) != 0)) { + if (negativeOutput && !_PyLong_IsZero(z)) { temp = (PyLongObject *)long_sub(z, c); if (temp == NULL) goto Error; - Py_DECREF(z); - z = temp; + Py_SETREF(z, temp); temp = NULL; } goto Done; @@ -4660,14 +4856,14 @@ long_invert(PyLongObject *v) { /* Implement ~x as -(x+1) */ PyLongObject *x; - if (IS_MEDIUM_VALUE(v)) + if (_PyLong_IsCompact(v)) return _PyLong_FromSTwoDigits(~medium_value(v)); x = (PyLongObject *) long_add(v, (PyLongObject *)_PyLong_GetOne()); if (x == NULL) return NULL; _PyLong_Negate(&x); - /* No need for maybe_small_long here, since any small - longs will have been caught in the Py_SIZE <= 1 fast path. */ + /* No need for maybe_small_long here, since any small longs + will have been caught in the _PyLong_IsCompact() fast path. */ return (PyObject *)x; } @@ -4675,18 +4871,18 @@ static PyObject * long_neg(PyLongObject *v) { PyLongObject *z; - if (IS_MEDIUM_VALUE(v)) + if (_PyLong_IsCompact(v)) return _PyLong_FromSTwoDigits(-medium_value(v)); z = (PyLongObject *)_PyLong_Copy(v); if (z != NULL) - Py_SET_SIZE(z, -(Py_SIZE(v))); + _PyLong_FlipSign(z); return (PyObject *)z; } static PyObject * long_abs(PyLongObject *v) { - if (Py_SIZE(v) < 0) + if (_PyLong_IsNegative(v)) return long_neg(v); else return long_long((PyObject *)v); @@ -4695,7 +4891,7 @@ long_abs(PyLongObject *v) static int long_bool(PyLongObject *v) { - return Py_SIZE(v) != 0; + return !_PyLong_IsZero(v); } /* wordshift, remshift = divmod(shiftby, PyLong_SHIFT) */ @@ -4703,14 +4899,14 @@ static int divmod_shift(PyObject *shiftby, Py_ssize_t *wordshift, digit *remshift) { assert(PyLong_Check(shiftby)); - assert(Py_SIZE(shiftby) >= 0); + assert(!_PyLong_IsNegative((PyLongObject *)shiftby)); Py_ssize_t lshiftby = PyLong_AsSsize_t((PyObject *)shiftby); if (lshiftby >= 0) { *wordshift = lshiftby / PyLong_SHIFT; *remshift = lshiftby % PyLong_SHIFT; return 0; } - /* PyLong_Check(shiftby) is true and Py_SIZE(shiftby) >= 0, so it must + /* PyLong_Check(shiftby) is true and shiftby is not negative, so it must be that PyLong_AsSsize_t raised an OverflowError. */ assert(PyErr_ExceptionMatches(PyExc_OverflowError)); PyErr_Clear(); @@ -4748,7 +4944,7 @@ long_rshift1(PyLongObject *a, Py_ssize_t wordshift, digit remshift) assert(remshift < PyLong_SHIFT); /* Fast path for small a. */ - if (IS_MEDIUM_VALUE(a)) { + if (_PyLong_IsCompact(a)) { stwodigits m, x; digit shift; m = medium_value(a); @@ -4757,8 +4953,8 @@ long_rshift1(PyLongObject *a, Py_ssize_t wordshift, digit remshift) return _PyLong_FromSTwoDigits(x); } - a_negative = Py_SIZE(a) < 0; - size_a = Py_ABS(Py_SIZE(a)); + a_negative = _PyLong_IsNegative(a); + size_a = _PyLong_DigitCount(a); if (a_negative) { /* For negative 'a', adjust so that 0 < remshift <= PyLong_SHIFT, @@ -4786,7 +4982,7 @@ long_rshift1(PyLongObject *a, Py_ssize_t wordshift, digit remshift) } hishift = PyLong_SHIFT - remshift; - accum = a->ob_digit[wordshift]; + accum = a->long_value.ob_digit[wordshift]; if (a_negative) { /* For a positive integer a and nonnegative shift, we have: @@ -4799,23 +4995,23 @@ long_rshift1(PyLongObject *a, Py_ssize_t wordshift, digit remshift) significant `wordshift` digits of `a` is nonzero. Digit `wordshift` of `2**shift - 1` has value `PyLong_MASK >> hishift`. */ - Py_SET_SIZE(z, -newsize); + _PyLong_SetSignAndDigitCount(z, -1, newsize); digit sticky = 0; for (Py_ssize_t j = 0; j < wordshift; j++) { - sticky |= a->ob_digit[j]; + sticky |= a->long_value.ob_digit[j]; } accum += (PyLong_MASK >> hishift) + (digit)(sticky != 0); } accum >>= remshift; for (Py_ssize_t i = 0, j = wordshift + 1; j < size_a; i++, j++) { - accum += (twodigits)a->ob_digit[j] << hishift; - z->ob_digit[i] = (digit)(accum & PyLong_MASK); + accum += (twodigits)a->long_value.ob_digit[j] << hishift; + z->long_value.ob_digit[i] = (digit)(accum & PyLong_MASK); accum >>= PyLong_SHIFT; } assert(accum <= PyLong_MASK); - z->ob_digit[newsize - 1] = (digit)accum; + z->long_value.ob_digit[newsize - 1] = (digit)accum; z = maybe_small_long(long_normalize(z)); return (PyObject *)z; @@ -4829,11 +5025,11 @@ long_rshift(PyObject *a, PyObject *b) CHECK_BINOP(a, b); - if (Py_SIZE(b) < 0) { + if (_PyLong_IsNegative((PyLongObject *)b)) { PyErr_SetString(PyExc_ValueError, "negative shift count"); return NULL; } - if (Py_SIZE(a) == 0) { + if (_PyLong_IsZero((PyLongObject *)a)) { return PyLong_FromLong(0); } if (divmod_shift(b, &wordshift, &remshift) < 0) @@ -4849,7 +5045,7 @@ _PyLong_Rshift(PyObject *a, size_t shiftby) digit remshift; assert(PyLong_Check(a)); - if (Py_SIZE(a) == 0) { + if (_PyLong_IsZero((PyLongObject *)a)) { return PyLong_FromLong(0); } wordshift = shiftby / PyLong_SHIFT; @@ -4864,34 +5060,34 @@ long_lshift1(PyLongObject *a, Py_ssize_t wordshift, digit remshift) Py_ssize_t oldsize, newsize, i, j; twodigits accum; - if (wordshift == 0 && IS_MEDIUM_VALUE(a)) { + if (wordshift == 0 && _PyLong_IsCompact(a)) { stwodigits m = medium_value(a); // bypass undefined shift operator behavior stwodigits x = m < 0 ? -(-m << remshift) : m << remshift; return _PyLong_FromSTwoDigits(x); } - oldsize = Py_ABS(Py_SIZE(a)); + oldsize = _PyLong_DigitCount(a); newsize = oldsize + wordshift; if (remshift) ++newsize; z = _PyLong_New(newsize); if (z == NULL) return NULL; - if (Py_SIZE(a) < 0) { + if (_PyLong_IsNegative(a)) { assert(Py_REFCNT(z) == 1); - Py_SET_SIZE(z, -Py_SIZE(z)); + _PyLong_FlipSign(z); } for (i = 0; i < wordshift; i++) - z->ob_digit[i] = 0; + z->long_value.ob_digit[i] = 0; accum = 0; - for (i = wordshift, j = 0; j < oldsize; i++, j++) { - accum |= (twodigits)a->ob_digit[j] << remshift; - z->ob_digit[i] = (digit)(accum & PyLong_MASK); + for (j = 0; j < oldsize; i++, j++) { + accum |= (twodigits)a->long_value.ob_digit[j] << remshift; + z->long_value.ob_digit[i] = (digit)(accum & PyLong_MASK); accum >>= PyLong_SHIFT; } if (remshift) - z->ob_digit[newsize-1] = (digit)accum; + z->long_value.ob_digit[newsize-1] = (digit)accum; else assert(!accum); z = long_normalize(z); @@ -4906,11 +5102,11 @@ long_lshift(PyObject *a, PyObject *b) CHECK_BINOP(a, b); - if (Py_SIZE(b) < 0) { + if (_PyLong_IsNegative((PyLongObject *)b)) { PyErr_SetString(PyExc_ValueError, "negative shift count"); return NULL; } - if (Py_SIZE(a) == 0) { + if (_PyLong_IsZero((PyLongObject *)a)) { return PyLong_FromLong(0); } if (divmod_shift(b, &wordshift, &remshift) < 0) @@ -4926,7 +5122,7 @@ _PyLong_Lshift(PyObject *a, size_t shiftby) digit remshift; assert(PyLong_Check(a)); - if (Py_SIZE(a) == 0) { + if (_PyLong_IsZero((PyLongObject *)a)) { return PyLong_FromLong(0); } wordshift = shiftby / PyLong_SHIFT; @@ -4968,13 +5164,13 @@ long_bitwise(PyLongObject *a, result back to sign-magnitude at the end. */ /* If a is negative, replace it by its two's complement. */ - size_a = Py_ABS(Py_SIZE(a)); - nega = Py_SIZE(a) < 0; + size_a = _PyLong_DigitCount(a); + nega = _PyLong_IsNegative(a); if (nega) { z = _PyLong_New(size_a); if (z == NULL) return NULL; - v_complement(z->ob_digit, a->ob_digit, size_a); + v_complement(z->long_value.ob_digit, a->long_value.ob_digit, size_a); a = z; } else @@ -4982,15 +5178,15 @@ long_bitwise(PyLongObject *a, Py_INCREF(a); /* Same for b. */ - size_b = Py_ABS(Py_SIZE(b)); - negb = Py_SIZE(b) < 0; + size_b = _PyLong_DigitCount(b); + negb = _PyLong_IsNegative(b); if (negb) { z = _PyLong_New(size_b); if (z == NULL) { Py_DECREF(a); return NULL; } - v_complement(z->ob_digit, b->ob_digit, size_b); + v_complement(z->long_value.ob_digit, b->long_value.ob_digit, size_b); b = z; } else @@ -5040,15 +5236,15 @@ long_bitwise(PyLongObject *a, switch(op) { case '&': for (i = 0; i < size_b; ++i) - z->ob_digit[i] = a->ob_digit[i] & b->ob_digit[i]; + z->long_value.ob_digit[i] = a->long_value.ob_digit[i] & b->long_value.ob_digit[i]; break; case '|': for (i = 0; i < size_b; ++i) - z->ob_digit[i] = a->ob_digit[i] | b->ob_digit[i]; + z->long_value.ob_digit[i] = a->long_value.ob_digit[i] | b->long_value.ob_digit[i]; break; case '^': for (i = 0; i < size_b; ++i) - z->ob_digit[i] = a->ob_digit[i] ^ b->ob_digit[i]; + z->long_value.ob_digit[i] = a->long_value.ob_digit[i] ^ b->long_value.ob_digit[i]; break; default: Py_UNREACHABLE(); @@ -5057,16 +5253,16 @@ long_bitwise(PyLongObject *a, /* Copy any remaining digits of a, inverting if necessary. */ if (op == '^' && negb) for (; i < size_z; ++i) - z->ob_digit[i] = a->ob_digit[i] ^ PyLong_MASK; + z->long_value.ob_digit[i] = a->long_value.ob_digit[i] ^ PyLong_MASK; else if (i < size_z) - memcpy(&z->ob_digit[i], &a->ob_digit[i], + memcpy(&z->long_value.ob_digit[i], &a->long_value.ob_digit[i], (size_z-i)*sizeof(digit)); /* Complement result if negative. */ if (negz) { - Py_SET_SIZE(z, -(Py_SIZE(z))); - z->ob_digit[size_z] = PyLong_MASK; - v_complement(z->ob_digit, z->ob_digit, size_z+1); + _PyLong_FlipSign(z); + z->long_value.ob_digit[size_z] = PyLong_MASK; + v_complement(z->long_value.ob_digit, z->long_value.ob_digit, size_z+1); } Py_DECREF(a); @@ -5080,7 +5276,7 @@ long_and(PyObject *a, PyObject *b) CHECK_BINOP(a, b); PyLongObject *x = (PyLongObject*)a; PyLongObject *y = (PyLongObject*)b; - if (IS_MEDIUM_VALUE(x) && IS_MEDIUM_VALUE(y)) { + if (_PyLong_IsCompact(x) && _PyLong_IsCompact(y)) { return _PyLong_FromSTwoDigits(medium_value(x) & medium_value(y)); } return long_bitwise(x, '&', y); @@ -5092,7 +5288,7 @@ long_xor(PyObject *a, PyObject *b) CHECK_BINOP(a, b); PyLongObject *x = (PyLongObject*)a; PyLongObject *y = (PyLongObject*)b; - if (IS_MEDIUM_VALUE(x) && IS_MEDIUM_VALUE(y)) { + if (_PyLong_IsCompact(x) && _PyLong_IsCompact(y)) { return _PyLong_FromSTwoDigits(medium_value(x) ^ medium_value(y)); } return long_bitwise(x, '^', y); @@ -5104,7 +5300,7 @@ long_or(PyObject *a, PyObject *b) CHECK_BINOP(a, b); PyLongObject *x = (PyLongObject*)a; PyLongObject *y = (PyLongObject*)b; - if (IS_MEDIUM_VALUE(x) && IS_MEDIUM_VALUE(y)) { + if (_PyLong_IsCompact(x) && _PyLong_IsCompact(y)) { return _PyLong_FromSTwoDigits(medium_value(x) | medium_value(y)); } return long_bitwise(x, '|', y); @@ -5113,11 +5309,12 @@ long_or(PyObject *a, PyObject *b) static PyObject * long_long(PyObject *v) { - if (PyLong_CheckExact(v)) - Py_INCREF(v); - else - v = _PyLong_Copy((PyLongObject *)v); - return v; + if (PyLong_CheckExact(v)) { + return Py_NewRef(v); + } + else { + return _PyLong_Copy((PyLongObject *)v); + } } PyObject * @@ -5127,14 +5324,11 @@ _PyLong_GCD(PyObject *aarg, PyObject *barg) stwodigits x, y, q, s, t, c_carry, d_carry; stwodigits A, B, C, D, T; int nbits, k; - Py_ssize_t size_a, size_b, alloc_a, alloc_b; digit *a_digit, *b_digit, *c_digit, *d_digit, *a_end, *b_end; a = (PyLongObject *)aarg; b = (PyLongObject *)barg; - size_a = Py_SIZE(a); - size_b = Py_SIZE(b); - if (-2 <= size_a && size_a <= 2 && -2 <= size_b && size_b <= 2) { + if (_PyLong_DigitCount(a) <= 2 && _PyLong_DigitCount(b) <= 2) { Py_INCREF(a); Py_INCREF(b); goto simple; @@ -5156,14 +5350,15 @@ _PyLong_GCD(PyObject *aarg, PyObject *barg) } /* We now own references to a and b */ - alloc_a = Py_SIZE(a); - alloc_b = Py_SIZE(b); + Py_ssize_t size_a, size_b, alloc_a, alloc_b; + alloc_a = _PyLong_DigitCount(a); + alloc_b = _PyLong_DigitCount(b); /* reduce until a fits into 2 digits */ - while ((size_a = Py_SIZE(a)) > 2) { - nbits = bit_length_digit(a->ob_digit[size_a-1]); + while ((size_a = _PyLong_DigitCount(a)) > 2) { + nbits = bit_length_digit(a->long_value.ob_digit[size_a-1]); /* extract top 2*PyLong_SHIFT bits of a into x, along with corresponding bits of b into y */ - size_b = Py_SIZE(b); + size_b = _PyLong_DigitCount(b); assert(size_b <= size_a); if (size_b == 0) { if (size_a < alloc_a) { @@ -5177,13 +5372,13 @@ _PyLong_GCD(PyObject *aarg, PyObject *barg) Py_XDECREF(d); return (PyObject *)r; } - x = (((twodigits)a->ob_digit[size_a-1] << (2*PyLong_SHIFT-nbits)) | - ((twodigits)a->ob_digit[size_a-2] << (PyLong_SHIFT-nbits)) | - (a->ob_digit[size_a-3] >> nbits)); + x = (((twodigits)a->long_value.ob_digit[size_a-1] << (2*PyLong_SHIFT-nbits)) | + ((twodigits)a->long_value.ob_digit[size_a-2] << (PyLong_SHIFT-nbits)) | + (a->long_value.ob_digit[size_a-3] >> nbits)); - y = ((size_b >= size_a - 2 ? b->ob_digit[size_a-3] >> nbits : 0) | - (size_b >= size_a - 1 ? (twodigits)b->ob_digit[size_a-2] << (PyLong_SHIFT-nbits) : 0) | - (size_b >= size_a ? (twodigits)b->ob_digit[size_a-1] << (2*PyLong_SHIFT-nbits) : 0)); + y = ((size_b >= size_a - 2 ? b->long_value.ob_digit[size_a-3] >> nbits : 0) | + (size_b >= size_a - 1 ? (twodigits)b->long_value.ob_digit[size_a-2] << (PyLong_SHIFT-nbits) : 0) | + (size_b >= size_a ? (twodigits)b->long_value.ob_digit[size_a-1] << (2*PyLong_SHIFT-nbits) : 0)); /* inner loop of Lehmer's algorithm; A, B, C, D never grow larger than PyLong_MASK during the algorithm. */ @@ -5204,11 +5399,10 @@ _PyLong_GCD(PyObject *aarg, PyObject *barg) /* no progress; do a Euclidean step */ if (l_mod(a, b, &r) < 0) goto error; - Py_DECREF(a); - a = b; + Py_SETREF(a, b); b = r; alloc_a = alloc_b; - alloc_b = Py_SIZE(b); + alloc_b = _PyLong_DigitCount(b); continue; } @@ -5221,11 +5415,11 @@ _PyLong_GCD(PyObject *aarg, PyObject *barg) T = -C; C = -D; D = T; } if (c != NULL) { - Py_SET_SIZE(c, size_a); + assert(size_a >= 0); + _PyLong_SetSignAndDigitCount(c, 1, size_a); } else if (Py_REFCNT(a) == 1) { - Py_INCREF(a); - c = a; + c = (PyLongObject*)Py_NewRef(a); } else { alloc_a = size_a; @@ -5235,12 +5429,13 @@ _PyLong_GCD(PyObject *aarg, PyObject *barg) } if (d != NULL) { - Py_SET_SIZE(d, size_a); + assert(size_a >= 0); + _PyLong_SetSignAndDigitCount(d, 1, size_a); } else if (Py_REFCNT(b) == 1 && size_a <= alloc_b) { - Py_INCREF(b); - d = b; - Py_SET_SIZE(d, size_a); + d = (PyLongObject*)Py_NewRef(b); + assert(size_a >= 0); + _PyLong_SetSignAndDigitCount(d, 1, size_a); } else { alloc_b = size_a; @@ -5248,14 +5443,14 @@ _PyLong_GCD(PyObject *aarg, PyObject *barg) if (d == NULL) goto error; } - a_end = a->ob_digit + size_a; - b_end = b->ob_digit + size_b; + a_end = a->long_value.ob_digit + size_a; + b_end = b->long_value.ob_digit + size_b; /* compute new a and new b in parallel */ - a_digit = a->ob_digit; - b_digit = b->ob_digit; - c_digit = c->ob_digit; - d_digit = d->ob_digit; + a_digit = a->long_value.ob_digit; + b_digit = b->long_value.ob_digit; + c_digit = c->long_value.ob_digit; + d_digit = d->long_value.ob_digit; c_carry = 0; d_carry = 0; while (b_digit < b_end) { @@ -5412,9 +5607,7 @@ long_subtype_new(PyTypeObject *type, PyObject *x, PyObject *obase) if (tmp == NULL) return NULL; assert(PyLong_Check(tmp)); - n = Py_SIZE(tmp); - if (n < 0) - n = -n; + n = _PyLong_DigitCount(tmp); /* Fast operations for single digit integers (including zero) * assume that there is always at least one digit present. */ if (n == 0) { @@ -5426,9 +5619,9 @@ long_subtype_new(PyTypeObject *type, PyObject *x, PyObject *obase) return NULL; } assert(PyLong_Check(newobj)); - Py_SET_SIZE(newobj, Py_SIZE(tmp)); + newobj->long_value.lv_tag = tmp->long_value.lv_tag; for (i = 0; i < n; i++) { - newobj->ob_digit[i] = tmp->ob_digit[i]; + newobj->long_value.ob_digit[i] = tmp->long_value.ob_digit[i]; } Py_DECREF(tmp); return (PyObject *)newobj; @@ -5462,11 +5655,13 @@ int.__format__ format_spec: unicode / + +Convert to a string according to format_spec. [clinic start generated code]*/ static PyObject * int___format___impl(PyObject *self, PyObject *format_spec) -/*[clinic end generated code: output=b4929dee9ae18689 input=e31944a9b3e428b7]*/ +/*[clinic end generated code: output=b4929dee9ae18689 input=d5e1254a47e8d1dc]*/ { _PyUnicodeWriter writer; int ret; @@ -5518,7 +5713,7 @@ _PyLong_DivmodNear(PyObject *a, PyObject *b) } /* Do a and b have different signs? If so, quotient is negative. */ - quo_is_neg = (Py_SIZE(a) < 0) != (Py_SIZE(b) < 0); + quo_is_neg = (_PyLong_IsNegative((PyLongObject *)a)) != (_PyLong_IsNegative((PyLongObject *)b)); if (long_divrem((PyLongObject*)a, (PyLongObject*)b, &quo, &rem) < 0) goto error; @@ -5531,23 +5726,21 @@ _PyLong_DivmodNear(PyObject *a, PyObject *b) goto error; if (quo_is_neg) { temp = long_neg((PyLongObject*)twice_rem); - Py_DECREF(twice_rem); - twice_rem = temp; + Py_SETREF(twice_rem, temp); if (twice_rem == NULL) goto error; } cmp = long_compare((PyLongObject *)twice_rem, (PyLongObject *)b); Py_DECREF(twice_rem); - quo_is_odd = Py_SIZE(quo) != 0 && ((quo->ob_digit[0] & 1) != 0); - if ((Py_SIZE(b) < 0 ? cmp < 0 : cmp > 0) || (cmp == 0 && quo_is_odd)) { + quo_is_odd = (quo->long_value.ob_digit[0] & 1) != 0; + if ((_PyLong_IsNegative((PyLongObject *)b) ? cmp < 0 : cmp > 0) || (cmp == 0 && quo_is_odd)) { /* fix up quotient */ if (quo_is_neg) temp = long_sub(quo, (PyLongObject *)one); else temp = long_add(quo, (PyLongObject *)one); - Py_DECREF(quo); - quo = (PyLongObject *)temp; + Py_SETREF(quo, (PyLongObject *)temp); if (quo == NULL) goto error; /* and remainder */ @@ -5555,8 +5748,7 @@ _PyLong_DivmodNear(PyObject *a, PyObject *b) temp = long_add(rem, (PyLongObject *)b); else temp = long_sub(rem, (PyLongObject *)b); - Py_DECREF(rem); - rem = (PyLongObject *)temp; + Py_SETREF(rem, (PyLongObject *)temp); if (rem == NULL) goto error; } @@ -5615,15 +5807,14 @@ int___round___impl(PyObject *self, PyObject *o_ndigits) return NULL; /* if ndigits >= 0 then no rounding is necessary; return self unchanged */ - if (Py_SIZE(ndigits) >= 0) { + if (!_PyLong_IsNegative((PyLongObject *)ndigits)) { Py_DECREF(ndigits); return long_long(self); } /* result = self - divmod_near(self, 10 ** -ndigits)[1] */ temp = long_neg((PyLongObject*)ndigits); - Py_DECREF(ndigits); - ndigits = temp; + Py_SETREF(ndigits, temp); if (ndigits == NULL) return NULL; @@ -5635,21 +5826,18 @@ int___round___impl(PyObject *self, PyObject *o_ndigits) temp = long_pow(result, ndigits, Py_None); Py_DECREF(ndigits); - Py_DECREF(result); - result = temp; + Py_SETREF(result, temp); if (result == NULL) return NULL; temp = _PyLong_DivmodNear(self, result); - Py_DECREF(result); - result = temp; + Py_SETREF(result, temp); if (result == NULL) return NULL; temp = long_sub((PyLongObject *)self, (PyLongObject *)PyTuple_GET_ITEM(result, 1)); - Py_DECREF(result); - result = temp; + Py_SETREF(result, temp); return result; } @@ -5664,13 +5852,10 @@ static Py_ssize_t int___sizeof___impl(PyObject *self) /*[clinic end generated code: output=3303f008eaa6a0a5 input=9b51620c76fc4507]*/ { - Py_ssize_t res; - - res = offsetof(PyLongObject, ob_digit) - /* using Py_MAX(..., 1) because we always allocate space for at least - one digit, even though the integer zero has a Py_SIZE of 0 */ - + Py_MAX(Py_ABS(Py_SIZE(self)), 1)*sizeof(digit); - return res; + /* using Py_MAX(..., 1) because we always allocate space for at least + one digit, even though the integer zero has a digit count of 0 */ + Py_ssize_t ndigits = Py_MAX(_PyLong_DigitCount((PyLongObject *)self), 1); + return Py_TYPE(self)->tp_basicsize + Py_TYPE(self)->tp_itemsize * ndigits; } /*[clinic input] @@ -5696,11 +5881,11 @@ int_bit_length_impl(PyObject *self) assert(self != NULL); assert(PyLong_Check(self)); - ndigits = Py_ABS(Py_SIZE(self)); + ndigits = _PyLong_DigitCount((PyLongObject *)self); if (ndigits == 0) return PyLong_FromLong(0); - msd = ((PyLongObject *)self)->ob_digit[ndigits-1]; + msd = ((PyLongObject *)self)->long_value.ob_digit[ndigits-1]; msd_bits = bit_length_digit(msd); if (ndigits <= PY_SSIZE_T_MAX/PyLong_SHIFT) @@ -5717,8 +5902,7 @@ int_bit_length_impl(PyObject *self) Py_DECREF(x); if (y == NULL) goto error; - Py_DECREF(result); - result = y; + Py_SETREF(result, y); x = (PyLongObject *)PyLong_FromLong((long)msd_bits); if (x == NULL) @@ -5727,8 +5911,7 @@ int_bit_length_impl(PyObject *self) Py_DECREF(x); if (y == NULL) goto error; - Py_DECREF(result); - result = y; + Py_SETREF(result, y); return (PyObject *)result; @@ -5767,7 +5950,7 @@ int_bit_count_impl(PyObject *self) assert(PyLong_Check(self)); PyLongObject *z = (PyLongObject *)self; - Py_ssize_t ndigits = Py_ABS(Py_SIZE(z)); + Py_ssize_t ndigits = _PyLong_DigitCount(z); Py_ssize_t bit_count = 0; /* Each digit has up to PyLong_SHIFT ones, so the accumulated bit count @@ -5775,7 +5958,7 @@ int_bit_count_impl(PyObject *self) Py_ssize_t. */ Py_ssize_t ndigits_fast = Py_MIN(ndigits, PY_SSIZE_T_MAX/PyLong_SHIFT); for (Py_ssize_t i = 0; i < ndigits_fast; i++) { - bit_count += popcount_digit(z->ob_digit[i]); + bit_count += popcount_digit(z->long_value.ob_digit[i]); } PyObject *result = PyLong_FromSsize_t(bit_count); @@ -5785,7 +5968,7 @@ int_bit_count_impl(PyObject *self) /* Use Python integers if bit_count would overflow. */ for (Py_ssize_t i = ndigits_fast; i < ndigits; i++) { - PyObject *x = PyLong_FromLong(popcount_digit(z->ob_digit[i])); + PyObject *x = PyLong_FromLong(popcount_digit(z->long_value.ob_digit[i])); if (x == NULL) { goto error; } @@ -5794,8 +5977,7 @@ int_bit_count_impl(PyObject *self) if (y == NULL) { goto error; } - Py_DECREF(result); - result = y; + Py_SETREF(result, y); } return result; @@ -5808,10 +5990,9 @@ int_bit_count_impl(PyObject *self) /*[clinic input] int.as_integer_ratio -Return integer ratio. +Return a pair of integers, whose ratio is equal to the original int. -Return a pair of integers, whose ratio is exactly equal to the original int -and with a positive denominator. +The ratio is in lowest terms and has a positive denominator. >>> (10).as_integer_ratio() (10, 1) @@ -5823,7 +6004,7 @@ and with a positive denominator. static PyObject * int_as_integer_ratio_impl(PyObject *self) -/*[clinic end generated code: output=e60803ae1cc8621a input=55ce3058e15de393]*/ +/*[clinic end generated code: output=e60803ae1cc8621a input=384ff1766634bec2]*/ { PyObject *ratio_tuple; PyObject *numerator = long_long(self); @@ -5961,6 +6142,19 @@ long_long_meth(PyObject *self, PyObject *Py_UNUSED(ignored)) return long_long(self); } +/*[clinic input] +int.is_integer + +Returns True. Exists for duck type compatibility with float.is_integer. +[clinic start generated code]*/ + +static PyObject * +int_is_integer_impl(PyObject *self) +/*[clinic end generated code: output=90f8e794ce5430ef input=7e41c4d4416e05f2]*/ +{ + Py_RETURN_TRUE; +} + static PyMethodDef long_methods[] = { {"conjugate", long_long_meth, METH_NOARGS, "Returns self, the complex conjugate of any int."}, @@ -5979,6 +6173,7 @@ static PyMethodDef long_methods[] = { INT___GETNEWARGS___METHODDEF INT___FORMAT___METHODDEF INT___SIZEOF___METHODDEF + INT_IS_INTEGER_METHODDEF {NULL, NULL} /* sentinel */ }; @@ -6058,9 +6253,9 @@ static PyNumberMethods long_as_number = { PyTypeObject PyLong_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "int", /* tp_name */ - offsetof(PyLongObject, ob_digit), /* tp_basicsize */ + offsetof(PyLongObject, long_value.ob_digit), /* tp_basicsize */ sizeof(digit), /* tp_itemsize */ - 0, /* tp_dealloc */ + long_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ @@ -6158,23 +6353,11 @@ PyLong_GetInfo(void) PyStatus _PyLong_InitTypes(PyInterpreterState *interp) { - if (!_Py_IsMainInterpreter(interp)) { - return _PyStatus_OK(); - } - - if (PyType_Ready(&PyLong_Type) < 0) { - return _PyStatus_ERR("Can't initialize int type"); - } - /* initialize int_info */ - if (Int_InfoType.tp_name == NULL) { - if (PyStructSequence_InitType2(&Int_InfoType, &int_info_desc) < 0) { - return _PyStatus_ERR("can't init int info type"); - } - } - interp->int_max_str_digits = _Py_global_config_int_max_str_digits; - if (interp->int_max_str_digits == -1) { - interp->int_max_str_digits = _PY_LONG_DEFAULT_MAX_STR_DIGITS; + if (_PyStructSequence_InitBuiltin(interp, &Int_InfoType, + &int_info_desc) < 0) + { + return _PyStatus_ERR("can't init int info type"); } return _PyStatus_OK(); @@ -6184,9 +6367,19 @@ _PyLong_InitTypes(PyInterpreterState *interp) void _PyLong_FiniTypes(PyInterpreterState *interp) { - if (!_Py_IsMainInterpreter(interp)) { - return; - } + _PyStructSequence_FiniBuiltin(interp, &Int_InfoType); +} + +#undef PyUnstable_Long_IsCompact - _PyStructSequence_FiniType(&Int_InfoType); +int +PyUnstable_Long_IsCompact(const PyLongObject* op) { + return _PyLong_IsCompact(op); +} + +#undef PyUnstable_Long_CompactValue + +Py_ssize_t +PyUnstable_Long_CompactValue(const PyLongObject* op) { + return _PyLong_CompactValue(op); } diff --git a/Objects/memoryobject.c b/Objects/memoryobject.c index e958ab45..b0168044 100644 --- a/Objects/memoryobject.c +++ b/Objects/memoryobject.c @@ -85,7 +85,7 @@ mbuf_alloc(void) } static PyObject * -_PyManagedBuffer_FromObject(PyObject *base) +_PyManagedBuffer_FromObject(PyObject *base, int flags) { _PyManagedBufferObject *mbuf; @@ -93,7 +93,7 @@ _PyManagedBuffer_FromObject(PyObject *base) if (mbuf == NULL) return NULL; - if (PyObject_GetBuffer(base, &mbuf->master, PyBUF_FULL_RO) < 0) { + if (PyObject_GetBuffer(base, &mbuf->master, flags) < 0) { mbuf->master.obj = NULL; Py_DECREF(mbuf); return NULL; @@ -193,6 +193,20 @@ PyTypeObject _PyManagedBuffer_Type = { return -1; \ } +#define CHECK_RESTRICTED(mv) \ + if (((PyMemoryViewObject *)(mv))->flags & _Py_MEMORYVIEW_RESTRICTED) { \ + PyErr_SetString(PyExc_ValueError, \ + "cannot create new view on restricted memoryview"); \ + return NULL; \ + } + +#define CHECK_RESTRICTED_INT(mv) \ + if (((PyMemoryViewObject *)(mv))->flags & _Py_MEMORYVIEW_RESTRICTED) { \ + PyErr_SetString(PyExc_ValueError, \ + "cannot create new view on restricted memoryview"); \ + return -1; \ + } + /* See gh-92888. These macros signal that we need to check the memoryview again due to possible read after frees. */ #define CHECK_RELEASED_AGAIN(mv) CHECK_RELEASED(mv) @@ -682,8 +696,7 @@ mbuf_add_view(_PyManagedBufferObject *mbuf, const Py_buffer *src) init_suboffsets(dest, src); init_flags(mv); - mv->mbuf = mbuf; - Py_INCREF(mbuf); + mv->mbuf = (_PyManagedBufferObject*)Py_NewRef(mbuf); mbuf->exports++; return (PyObject *)mv; @@ -713,8 +726,7 @@ mbuf_add_incomplete_view(_PyManagedBufferObject *mbuf, const Py_buffer *src, dest = &mv->view; init_shared_values(dest, src); - mv->mbuf = mbuf; - Py_INCREF(mbuf); + mv->mbuf = (_PyManagedBufferObject*)Py_NewRef(mbuf); mbuf->exports++; return (PyObject *)mv; @@ -779,22 +791,24 @@ PyMemoryView_FromBuffer(const Py_buffer *info) return mv; } -/* Create a memoryview from an object that implements the buffer protocol. +/* Create a memoryview from an object that implements the buffer protocol, + using the given flags. If the object is a memoryview, the new memoryview must be registered with the same managed buffer. Otherwise, a new managed buffer is created. */ -PyObject * -PyMemoryView_FromObject(PyObject *v) +static PyObject * +PyMemoryView_FromObjectAndFlags(PyObject *v, int flags) { _PyManagedBufferObject *mbuf; if (PyMemoryView_Check(v)) { PyMemoryViewObject *mv = (PyMemoryViewObject *)v; CHECK_RELEASED(mv); + CHECK_RESTRICTED(mv); return mbuf_add_view(mv->mbuf, &mv->view); } else if (PyObject_CheckBuffer(v)) { PyObject *ret; - mbuf = (_PyManagedBufferObject *)_PyManagedBuffer_FromObject(v); + mbuf = (_PyManagedBufferObject *)_PyManagedBuffer_FromObject(v, flags); if (mbuf == NULL) return NULL; ret = mbuf_add_view(mbuf, NULL); @@ -808,6 +822,38 @@ PyMemoryView_FromObject(PyObject *v) return NULL; } +/* Create a memoryview from an object that implements the buffer protocol, + using the given flags. + If the object is a memoryview, the new memoryview must be registered + with the same managed buffer. Otherwise, a new managed buffer is created. */ +PyObject * +_PyMemoryView_FromBufferProc(PyObject *v, int flags, getbufferproc bufferproc) +{ + _PyManagedBufferObject *mbuf = mbuf_alloc(); + if (mbuf == NULL) + return NULL; + + int res = bufferproc(v, &mbuf->master, flags); + if (res < 0) { + mbuf->master.obj = NULL; + Py_DECREF(mbuf); + return NULL; + } + + PyObject *ret = mbuf_add_view(mbuf, NULL); + Py_DECREF(mbuf); + return ret; +} + +/* Create a memoryview from an object that implements the buffer protocol. + If the object is a memoryview, the new memoryview must be registered + with the same managed buffer. Otherwise, a new managed buffer is created. */ +PyObject * +PyMemoryView_FromObject(PyObject *v) +{ + return PyMemoryView_FromObjectAndFlags(v, PyBUF_FULL_RO); +} + /* Copy the format string from a base object that might vanish. */ static int mbuf_copy_format(_PyManagedBufferObject *mbuf, const char *fmt) @@ -853,7 +899,7 @@ memory_from_contiguous_copy(const Py_buffer *src, char order) if (bytes == NULL) return NULL; - mbuf = (_PyManagedBufferObject *)_PyManagedBuffer_FromObject(bytes); + mbuf = (_PyManagedBufferObject *)_PyManagedBuffer_FromObject(bytes, PyBUF_FULL_RO); Py_DECREF(bytes); if (mbuf == NULL) return NULL; @@ -970,6 +1016,24 @@ memoryview_impl(PyTypeObject *type, PyObject *object) } +/*[clinic input] +@classmethod +memoryview._from_flags + + object: object + flags: int + +Create a new memoryview object which references the given object. +[clinic start generated code]*/ + +static PyObject * +memoryview__from_flags_impl(PyTypeObject *type, PyObject *object, int flags) +/*[clinic end generated code: output=bf71f9906c266ee2 input=f5f82fd0e744356b]*/ +{ + return PyMemoryView_FromObjectAndFlags(object, flags); +} + + /****************************************************************************/ /* Previously in abstract.c */ /****************************************************************************/ @@ -1102,8 +1166,7 @@ static PyObject * memory_enter(PyObject *self, PyObject *args) { CHECK_RELEASED(self); - Py_INCREF(self); - return self; + return Py_NewRef(self); } static PyObject * @@ -1135,6 +1198,7 @@ get_native_fmtchar(char *result, const char *fmt) case 'n': case 'N': size = sizeof(Py_ssize_t); break; case 'f': size = sizeof(float); break; case 'd': size = sizeof(double); break; + case 'e': size = sizeof(float) / 2; break; case '?': size = sizeof(_Bool); break; case 'P': size = sizeof(void *); break; } @@ -1178,6 +1242,7 @@ get_native_fmtstr(const char *fmt) case 'N': RETURN("N"); case 'f': RETURN("f"); case 'd': RETURN("d"); + case 'e': RETURN("e"); case '?': RETURN("?"); case 'P': RETURN("P"); } @@ -1371,6 +1436,7 @@ memoryview_cast_impl(PyMemoryViewObject *self, PyObject *format, Py_ssize_t ndim = 1; CHECK_RELEASED(self); + CHECK_RESTRICTED(self); if (!MV_C_CONTIGUOUS(self->flags)) { PyErr_SetString(PyExc_TypeError, @@ -1426,6 +1492,7 @@ memoryview_toreadonly_impl(PyMemoryViewObject *self) /*[clinic end generated code: output=2c7e056f04c99e62 input=dc06d20f19ba236f]*/ { CHECK_RELEASED(self); + CHECK_RESTRICTED(self); /* Even if self is already readonly, we still need to create a new * object for .release() to work correctly. */ @@ -1448,6 +1515,7 @@ memory_getbuf(PyMemoryViewObject *self, Py_buffer *view, int flags) int baseflags = self->flags; CHECK_RELEASED_INT(self); + CHECK_RESTRICTED_INT(self); /* start with complete information */ *view = *base; @@ -1513,8 +1581,7 @@ memory_getbuf(PyMemoryViewObject *self, Py_buffer *view, int flags) } - view->obj = (PyObject *)self; - Py_INCREF(view->obj); + view->obj = Py_NewRef(self); self->exports++; return 0; @@ -1697,6 +1764,12 @@ unpack_single(PyMemoryViewObject *self, const char *ptr, const char *fmt) CHECK_RELEASED_AGAIN(self); +#if PY_LITTLE_ENDIAN + int endian = 1; +#else + int endian = 0; +#endif + switch (fmt[0]) { /* signed integers and fast path for 'B' */ @@ -1725,6 +1798,7 @@ unpack_single(PyMemoryViewObject *self, const char *ptr, const char *fmt) /* floats */ case 'f': UNPACK_SINGLE(d, ptr, float); goto convert_double; case 'd': UNPACK_SINGLE(d, ptr, double); goto convert_double; + case 'e': d = PyFloat_Unpack2(ptr, endian); goto convert_double; /* bytes object */ case 'c': goto convert_bytes; @@ -1786,6 +1860,11 @@ pack_single(PyMemoryViewObject *self, char *ptr, PyObject *item, const char *fmt double d; void *p; +#if PY_LITTLE_ENDIAN + int endian = 1; +#else + int endian = 0; +#endif switch (fmt[0]) { /* signed integers */ case 'b': case 'h': case 'i': case 'l': @@ -1862,7 +1941,7 @@ pack_single(PyMemoryViewObject *self, char *ptr, PyObject *item, const char *fmt break; /* floats */ - case 'f': case 'd': + case 'f': case 'd': case 'e': d = PyFloat_AsDouble(item); if (d == -1.0 && PyErr_Occurred()) goto err_occurred; @@ -1870,9 +1949,14 @@ pack_single(PyMemoryViewObject *self, char *ptr, PyObject *item, const char *fmt if (fmt[0] == 'f') { PACK_SINGLE(ptr, d, float); } - else { + else if (fmt[0] == 'd') { PACK_SINGLE(ptr, d, double); } + else { + if (PyFloat_Pack2(d, ptr, endian) < 0) { + goto err_occurred; + } + } break; /* bool */ @@ -1882,7 +1966,7 @@ pack_single(PyMemoryViewObject *self, char *ptr, PyObject *item, const char *fmt return -1; /* preserve original error */ CHECK_RELEASED_INT_AGAIN(self); PACK_SINGLE(ptr, ld, _Bool); - break; + break; /* bytes object */ case 'c': @@ -1967,18 +2051,12 @@ unpacker_free(struct unpacker *x) static struct unpacker * struct_get_unpacker(const char *fmt, Py_ssize_t itemsize) { - PyObject *structmodule; /* XXX cache these two */ - PyObject *Struct = NULL; /* XXX in globals? */ + PyObject *Struct = NULL; /* XXX cache it in globals? */ PyObject *structobj = NULL; PyObject *format = NULL; struct unpacker *x = NULL; - structmodule = PyImport_ImportModule("struct"); - if (structmodule == NULL) - return NULL; - - Struct = PyObject_GetAttrString(structmodule, "Struct"); - Py_DECREF(structmodule); + Struct = _PyImport_GetModuleAttrString("struct", "Struct"); if (Struct == NULL) return NULL; @@ -2034,10 +2112,9 @@ struct_unpack_single(const char *ptr, struct unpacker *x) return NULL; if (PyTuple_GET_SIZE(v) == 1) { - PyObject *tmp = PyTuple_GET_ITEM(v, 0); - Py_INCREF(tmp); + PyObject *res = Py_NewRef(PyTuple_GET_ITEM(v, 0)); Py_DECREF(v); - return tmp; + return res; } return v; @@ -2483,8 +2560,7 @@ memory_subscript(PyMemoryViewObject *self, PyObject *key) return unpack_single(self, view->buf, fmt); } else if (key == Py_Ellipsis) { - Py_INCREF(self); - return (PyObject *)self; + return Py_NewRef(self); } else { PyErr_SetString(PyExc_TypeError, @@ -2501,6 +2577,7 @@ memory_subscript(PyMemoryViewObject *self, PyObject *key) return memory_item(self, index); } else if (PySlice_Check(key)) { + CHECK_RESTRICTED(self); PyMemoryViewObject *sliced; sliced = (PyMemoryViewObject *)mbuf_add_view(self->mbuf, view); @@ -2635,7 +2712,11 @@ static Py_ssize_t memory_length(PyMemoryViewObject *self) { CHECK_RELEASED_INT(self); - return self->view.ndim == 0 ? 1 : self->view.shape[0]; + if (self->view.ndim == 0) { + PyErr_SetString(PyExc_TypeError, "0-dim memory has no length"); + return -1; + } + return self->view.shape[0]; } /* As mapping */ @@ -2754,6 +2835,17 @@ unpack_cmp(const char *p, const char *q, char fmt, /* XXX DBL_EPSILON? */ case 'f': CMP_SINGLE(p, q, float); return equal; case 'd': CMP_SINGLE(p, q, double); return equal; + case 'e': { +#if PY_LITTLE_ENDIAN + int endian = 1; +#else + int endian = 0; +#endif + /* Note: PyFloat_Unpack2 should never fail */ + double u = PyFloat_Unpack2(p, endian); + double v = PyFloat_Unpack2(q, endian); + return (u == v); + } /* bytes object */ case 'c': return *p == *q; @@ -2933,8 +3025,7 @@ result: unpacker_free(unpack_v); unpacker_free(unpack_w); - Py_XINCREF(res); - return res; + return Py_XNewRef(res); } /**************************************************************************/ @@ -3028,8 +3119,7 @@ memory_obj_get(PyMemoryViewObject *self, void *Py_UNUSED(ignored)) if (view->obj == NULL) { Py_RETURN_NONE; } - Py_INCREF(view->obj); - return view->obj; + return Py_NewRef(view->obj); } static PyObject * @@ -3164,6 +3254,7 @@ static PyMethodDef memory_methods[] = { MEMORYVIEW_TOLIST_METHODDEF MEMORYVIEW_CAST_METHODDEF MEMORYVIEW_TOREADONLY_METHODDEF + MEMORYVIEW__FROM_FLAGS_METHODDEF {"__enter__", memory_enter, METH_NOARGS, NULL}, {"__exit__", memory_exit, METH_VARARGS, NULL}, {NULL, NULL} @@ -3257,8 +3348,7 @@ memory_iter(PyObject *seq) it->it_fmt = fmt; it->it_length = memory_length(obj); it->it_index = 0; - Py_INCREF(seq); - it->it_seq = obj; + it->it_seq = (PyMemoryViewObject*)Py_NewRef(obj); _PyObject_GC_TRACK(it); return (PyObject *)it; } diff --git a/Objects/methodobject.c b/Objects/methodobject.c index 953cf466..51752dec 100644 --- a/Objects/methodobject.c +++ b/Objects/methodobject.c @@ -88,8 +88,7 @@ PyCMethod_New(PyMethodDef *ml, PyObject *self, PyObject *module, PyTypeObject *c if (om == NULL) { return NULL; } - Py_INCREF(cls); - om->mm_class = cls; + om->mm_class = (PyTypeObject*)Py_NewRef(cls); op = (PyCFunctionObject *)om; } else { if (cls) { @@ -106,10 +105,8 @@ PyCMethod_New(PyMethodDef *ml, PyObject *self, PyObject *module, PyTypeObject *c op->m_weakreflist = NULL; op->m_ml = ml; - Py_XINCREF(self); - op->m_self = self; - Py_XINCREF(module); - op->m_module = module; + op->m_self = Py_XNewRef(self); + op->m_module = Py_XNewRef(module); op->vectorcall = vectorcall; _PyObject_GC_TRACK(op); return (PyObject *)op; @@ -260,8 +257,7 @@ meth_get__self__(PyCFunctionObject *m, void *closure) self = PyCFunction_GET_SELF(m); if (self == NULL) self = Py_None; - Py_INCREF(self); - return self; + return Py_NewRef(self); } static PyGetSetDef meth_getsets [] = { @@ -314,8 +310,7 @@ meth_richcompare(PyObject *self, PyObject *other, int op) res = eq ? Py_True : Py_False; else res = eq ? Py_False : Py_True; - Py_INCREF(res); - return res; + return Py_NewRef(res); } static Py_hash_t diff --git a/Objects/moduleobject.c b/Objects/moduleobject.c index dba20a0b..4daf1a92 100644 --- a/Objects/moduleobject.c +++ b/Objects/moduleobject.c @@ -9,7 +9,6 @@ #include "pycore_moduleobject.h" // _PyModule_GetDef() #include "structmember.h" // PyMemberDef -static Py_ssize_t max_module_number; static PyMemberDef module_members[] = { {"__dict__", T_OBJECT, offsetof(PyModuleObject, md_dict), READONLY}, @@ -43,10 +42,9 @@ PyModuleDef_Init(PyModuleDef* def) { assert(PyModuleDef_Type.tp_flags & Py_TPFLAGS_READY); if (def->m_base.m_index == 0) { - max_module_number++; Py_SET_REFCNT(def, 1); Py_SET_TYPE(def, &PyModuleDef_Type); - def->m_base.m_index = max_module_number; + def->m_base.m_index = _PyImport_GetNextModuleIndex(); } return (PyObject*)def; } @@ -70,8 +68,7 @@ module_init_dict(PyModuleObject *mod, PyObject *md_dict, if (PyDict_SetItem(md_dict, &_Py_ID(__spec__), Py_None) != 0) return -1; if (PyUnicode_CheckExact(name)) { - Py_INCREF(name); - Py_XSETREF(mod->md_name, name); + Py_XSETREF(mod->md_name, Py_NewRef(name)); } return 0; @@ -211,22 +208,7 @@ _PyModule_CreateInitialized(PyModuleDef* module, int module_api_version) "module %s: PyModule_Create is incompatible with m_slots", name); return NULL; } - /* Make sure name is fully qualified. - - This is a bit of a hack: when the shared library is loaded, - the module name is "package.module", but the module calls - PyModule_Create*() with just "module" for the name. The shared - library loader squirrels away the true name of the module in - _Py_PackageContext, and PyModule_Create*() will substitute this - (if the name actually matches). - */ - if (_Py_PackageContext != NULL) { - const char *p = strrchr(_Py_PackageContext, '.'); - if (p != NULL && strcmp(module->m_name, p+1) == 0) { - name = _Py_PackageContext; - _Py_PackageContext = NULL; - } - } + name = _PyImport_ResolveNameWithPackageContext(name); if ((m = (PyModuleObject*)PyModule_New(name)) == NULL) return NULL; @@ -263,9 +245,12 @@ PyModule_FromDefAndSpec2(PyModuleDef* def, PyObject *spec, int module_api_versio PyObject *(*create)(PyObject *, PyModuleDef*) = NULL; PyObject *nameobj; PyObject *m = NULL; + int has_multiple_interpreters_slot = 0; + void *multiple_interpreters = (void *)0; int has_execution_slots = 0; const char *name; int ret; + PyInterpreterState *interp = _PyInterpreterState_GET(); PyModuleDef_Init(def); @@ -291,25 +276,60 @@ PyModule_FromDefAndSpec2(PyModuleDef* def, PyObject *spec, int module_api_versio } for (cur_slot = def->m_slots; cur_slot && cur_slot->slot; cur_slot++) { - if (cur_slot->slot == Py_mod_create) { - if (create) { + switch (cur_slot->slot) { + case Py_mod_create: + if (create) { + PyErr_Format( + PyExc_SystemError, + "module %s has multiple create slots", + name); + goto error; + } + create = cur_slot->value; + break; + case Py_mod_exec: + has_execution_slots = 1; + break; + case Py_mod_multiple_interpreters: + if (has_multiple_interpreters_slot) { + PyErr_Format( + PyExc_SystemError, + "module %s has more than one 'multiple interpreters' slots", + name); + goto error; + } + multiple_interpreters = cur_slot->value; + has_multiple_interpreters_slot = 1; + break; + default: + assert(cur_slot->slot < 0 || cur_slot->slot > _Py_mod_LAST_SLOT); PyErr_Format( PyExc_SystemError, - "module %s has multiple create slots", - name); + "module %s uses unknown slot ID %i", + name, cur_slot->slot); goto error; - } - create = cur_slot->value; - } else if (cur_slot->slot < 0 || cur_slot->slot > _Py_mod_LAST_SLOT) { - PyErr_Format( - PyExc_SystemError, - "module %s uses unknown slot ID %i", - name, cur_slot->slot); + } + } + + /* By default, multi-phase init modules are expected + to work under multiple interpreters. */ + if (!has_multiple_interpreters_slot) { + multiple_interpreters = Py_MOD_MULTIPLE_INTERPRETERS_SUPPORTED; + } + if (multiple_interpreters == Py_MOD_MULTIPLE_INTERPRETERS_NOT_SUPPORTED) { + if (!_Py_IsMainInterpreter(interp) + && _PyImport_CheckSubinterpIncompatibleExtensionAllowed(name) < 0) + { goto error; - } else { - has_execution_slots = 1; } } + else if (multiple_interpreters != Py_MOD_PER_INTERPRETER_GIL_SUPPORTED + && interp->ceval.own_gil + && !_Py_IsMainInterpreter(interp) + && _PyImport_CheckSubinterpIncompatibleExtensionAllowed(name) < 0) + { + goto error; + } if (create) { m = create(spec, def); @@ -323,9 +343,10 @@ PyModule_FromDefAndSpec2(PyModuleDef* def, PyObject *spec, int module_api_versio goto error; } else { if (PyErr_Occurred()) { - PyErr_Format(PyExc_SystemError, - "creation of module %s raised unreported exception", - name); + _PyErr_FormatFromCause( + PyExc_SystemError, + "creation of module %s raised unreported exception", + name); goto error; } } @@ -427,13 +448,16 @@ PyModule_ExecDef(PyObject *module, PyModuleDef *def) return -1; } if (PyErr_Occurred()) { - PyErr_Format( + _PyErr_FormatFromCause( PyExc_SystemError, "execution of module %s raised unreported exception", name); return -1; } break; + case Py_mod_multiple_interpreters: + /* handled in PyModule_FromDefAndSpec2 */ + break; default: PyErr_Format( PyExc_SystemError, @@ -502,8 +526,7 @@ PyModule_GetNameObject(PyObject *m) } return NULL; } - Py_INCREF(name); - return name; + return Py_NewRef(name); } const char * @@ -537,8 +560,7 @@ PyModule_GetFilenameObject(PyObject *m) } return NULL; } - Py_INCREF(fileobj); - return fileobj; + return Py_NewRef(fileobj); } const char * @@ -707,8 +729,7 @@ static PyObject * module_repr(PyModuleObject *m) { PyInterpreterState *interp = _PyInterpreterState_GET(); - - return PyObject_CallMethod(interp->importlib, "_module_repr", "O", m); + return _PyImport_ImportlibModuleRepr(interp, (PyObject *)m); } /* Check if the "_initializing" attribute of the module spec is set to true. @@ -718,7 +739,11 @@ int _PyModuleSpec_IsInitializing(PyObject *spec) { if (spec != NULL) { - PyObject *value = PyObject_GetAttr(spec, &_Py_ID(_initializing)); + PyObject *value; + int ok = _PyObject_LookupAttr(spec, &_Py_ID(_initializing), &value); + if (ok == 0) { + return 0; + } if (value != NULL) { int initializing = PyObject_IsTrue(value); Py_DECREF(value); @@ -754,19 +779,37 @@ _PyModuleSpec_IsUninitializedSubmodule(PyObject *spec, PyObject *name) return is_uninitialized; } -static PyObject* -module_getattro(PyModuleObject *m, PyObject *name) +PyObject* +_Py_module_getattro_impl(PyModuleObject *m, PyObject *name, int suppress) { + // When suppress=1, this function suppresses AttributeError. PyObject *attr, *mod_name, *getattr; - attr = PyObject_GenericGetAttr((PyObject *)m, name); - if (attr || !PyErr_ExceptionMatches(PyExc_AttributeError)) { + attr = _PyObject_GenericGetAttrWithDict((PyObject *)m, name, NULL, suppress); + if (attr) { return attr; } - PyErr_Clear(); + if (suppress == 1) { + if (PyErr_Occurred()) { + // pass up non-AttributeError exception + return NULL; + } + } + else { + if (!PyErr_ExceptionMatches(PyExc_AttributeError)) { + // pass up non-AttributeError exception + return NULL; + } + PyErr_Clear(); + } assert(m->md_dict != NULL); getattr = PyDict_GetItemWithError(m->md_dict, &_Py_ID(__getattr__)); if (getattr) { - return PyObject_CallOneArg(getattr, name); + PyObject *result = PyObject_CallOneArg(getattr, name); + if (result == NULL && suppress == 1 && PyErr_ExceptionMatches(PyExc_AttributeError)) { + // suppress AttributeError + PyErr_Clear(); + } + return result; } if (PyErr_Occurred()) { return NULL; @@ -779,37 +822,48 @@ module_getattro(PyModuleObject *m, PyObject *name) Py_DECREF(mod_name); return NULL; } - Py_XINCREF(spec); - if (_PyModuleSpec_IsInitializing(spec)) { - PyErr_Format(PyExc_AttributeError, - "partially initialized " - "module '%U' has no attribute '%U' " - "(most likely due to a circular import)", - mod_name, name); - } - else if (_PyModuleSpec_IsUninitializedSubmodule(spec, name)) { - PyErr_Format(PyExc_AttributeError, - "cannot access submodule '%U' of module '%U' " - "(most likely due to a circular import)", - name, mod_name); - } - else { - PyErr_Format(PyExc_AttributeError, - "module '%U' has no attribute '%U'", - mod_name, name); + if (suppress != 1) { + Py_XINCREF(spec); + if (_PyModuleSpec_IsInitializing(spec)) { + PyErr_Format(PyExc_AttributeError, + "partially initialized " + "module '%U' has no attribute '%U' " + "(most likely due to a circular import)", + mod_name, name); + } + else if (_PyModuleSpec_IsUninitializedSubmodule(spec, name)) { + PyErr_Format(PyExc_AttributeError, + "cannot access submodule '%U' of module '%U' " + "(most likely due to a circular import)", + name, mod_name); + } + else { + PyErr_Format(PyExc_AttributeError, + "module '%U' has no attribute '%U'", + mod_name, name); + } + Py_XDECREF(spec); } - Py_XDECREF(spec); Py_DECREF(mod_name); return NULL; } else if (PyErr_Occurred()) { return NULL; } - PyErr_Format(PyExc_AttributeError, - "module has no attribute '%U'", name); + if (suppress != 1) { + PyErr_Format(PyExc_AttributeError, + "module has no attribute '%U'", name); + } return NULL; } + +PyObject* +_Py_module_getattro(PyModuleObject *m, PyObject *name) +{ + return _Py_module_getattro_impl(m, name, 0); +} + static int module_traverse(PyModuleObject *m, visitproc visit, void *arg) { @@ -881,26 +935,20 @@ static PyObject * module_get_annotations(PyModuleObject *m, void *Py_UNUSED(ignored)) { PyObject *dict = PyObject_GetAttr((PyObject *)m, &_Py_ID(__dict__)); - - if ((dict == NULL) || !PyDict_Check(dict)) { + if (dict == NULL) { + return NULL; + } + if (!PyDict_Check(dict)) { PyErr_Format(PyExc_TypeError, "<module>.__dict__ is not a dictionary"); - Py_XDECREF(dict); + Py_DECREF(dict); return NULL; } - PyObject *annotations; - /* there's no _PyDict_GetItemId without WithError, so let's LBYL. */ - if (PyDict_Contains(dict, &_Py_ID(__annotations__))) { - annotations = PyDict_GetItemWithError(dict, &_Py_ID(__annotations__)); - /* - ** _PyDict_GetItemIdWithError could still fail, - ** for instance with a well-timed Ctrl-C or a MemoryError. - ** so let's be totally safe. - */ - if (annotations) { - Py_INCREF(annotations); - } - } else { + PyObject *annotations = PyDict_GetItemWithError(dict, &_Py_ID(__annotations__)); + if (annotations) { + Py_INCREF(annotations); + } + else if (!PyErr_Occurred()) { annotations = PyDict_New(); if (annotations) { int result = PyDict_SetItem( @@ -919,8 +967,10 @@ module_set_annotations(PyModuleObject *m, PyObject *value, void *Py_UNUSED(ignor { int ret = -1; PyObject *dict = PyObject_GetAttr((PyObject *)m, &_Py_ID(__dict__)); - - if ((dict == NULL) || !PyDict_Check(dict)) { + if (dict == NULL) { + return -1; + } + if (!PyDict_Check(dict)) { PyErr_Format(PyExc_TypeError, "<module>.__dict__ is not a dictionary"); goto exit; } @@ -928,19 +978,17 @@ module_set_annotations(PyModuleObject *m, PyObject *value, void *Py_UNUSED(ignor if (value != NULL) { /* set */ ret = PyDict_SetItem(dict, &_Py_ID(__annotations__), value); - goto exit; } - - /* delete */ - if (!PyDict_Contains(dict, &_Py_ID(__annotations__))) { - PyErr_Format(PyExc_AttributeError, "__annotations__"); - goto exit; + else { + /* delete */ + ret = PyDict_DelItem(dict, &_Py_ID(__annotations__)); + if (ret < 0 && PyErr_ExceptionMatches(PyExc_KeyError)) { + PyErr_SetString(PyExc_AttributeError, "__annotations__"); + } } - ret = PyDict_DelItem(dict, &_Py_ID(__annotations__)); - exit: - Py_XDECREF(dict); + Py_DECREF(dict); return ret; } @@ -967,7 +1015,7 @@ PyTypeObject PyModule_Type = { 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ - (getattrofunc)module_getattro, /* tp_getattro */ + (getattrofunc)_Py_module_getattro, /* tp_getattro */ PyObject_GenericSetAttr, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | diff --git a/Objects/namespaceobject.c b/Objects/namespaceobject.c index 7875e7ca..2cc4ddd3 100644 --- a/Objects/namespaceobject.c +++ b/Objects/namespaceobject.c @@ -85,9 +85,8 @@ namespace_repr(PyObject *ns) if (pairs == NULL) goto error; - d = ((_PyNamespaceObject *)ns)->ns_dict; - assert(d != NULL); - Py_INCREF(d); + assert(((_PyNamespaceObject *)ns)->ns_dict != NULL); + d = Py_NewRef(((_PyNamespaceObject *)ns)->ns_dict); keys = PyDict_Keys(d); if (keys == NULL) diff --git a/Objects/object.c b/Objects/object.c index c4f2786c..8a4010fb 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -14,9 +14,10 @@ #include "pycore_pymem.h" // _PyMem_IsPtrFreed() #include "pycore_pystate.h" // _PyThreadState_GET() #include "pycore_symtable.h" // PySTEntry_Type -#include "pycore_typeobject.h" // _PyTypes_InitSlotDefs() +#include "pycore_typevarobject.h" // _PyTypeAlias_Type, _Py_initialize_generic +#include "pycore_typeobject.h" // _PyBufferWrapper_Type #include "pycore_unionobject.h" // _PyUnion_Type -#include "pycore_interpreteridobject.h" // _PyInterpreterID_Type +#include "interpreteridobject.h" // _PyInterpreterID_Type #ifdef Py_LIMITED_API // Prevent recursive call _Py_IncRef() <=> Py_INCREF() @@ -55,19 +56,100 @@ _PyObject_CheckConsistency(PyObject *op, int check_content) #ifdef Py_REF_DEBUG +/* We keep the legacy symbol around for backward compatibility. */ Py_ssize_t _Py_RefTotal; -Py_ssize_t -_Py_GetRefTotal(void) +static inline Py_ssize_t +get_legacy_reftotal(void) { return _Py_RefTotal; } +#endif + +#ifdef Py_REF_DEBUG + +# define REFTOTAL(interp) \ + interp->object_state.reftotal + +static inline void +reftotal_increment(PyInterpreterState *interp) +{ + REFTOTAL(interp)++; +} + +static inline void +reftotal_decrement(PyInterpreterState *interp) +{ + REFTOTAL(interp)--; +} + +static inline void +reftotal_add(PyInterpreterState *interp, Py_ssize_t n) +{ + REFTOTAL(interp) += n; +} + +static inline Py_ssize_t get_global_reftotal(_PyRuntimeState *); + +/* We preserve the number of refs leaked during runtime finalization, + so they can be reported if the runtime is initialized again. */ +// XXX We don't lose any information by dropping this, +// so we should consider doing so. +static Py_ssize_t last_final_reftotal = 0; + +void +_Py_FinalizeRefTotal(_PyRuntimeState *runtime) +{ + last_final_reftotal = get_global_reftotal(runtime); + runtime->object_state.interpreter_leaks = 0; +} + +void +_PyInterpreterState_FinalizeRefTotal(PyInterpreterState *interp) +{ + interp->runtime->object_state.interpreter_leaks += REFTOTAL(interp); + REFTOTAL(interp) = 0; +} + +static inline Py_ssize_t +get_reftotal(PyInterpreterState *interp) +{ + /* For a single interpreter, we ignore the legacy _Py_RefTotal, + since we can't determine which interpreter updated it. */ + return REFTOTAL(interp); +} + +static inline Py_ssize_t +get_global_reftotal(_PyRuntimeState *runtime) +{ + Py_ssize_t total = 0; + + /* Add up the total from each interpreter. */ + HEAD_LOCK(&_PyRuntime); + PyInterpreterState *interp = PyInterpreterState_Head(); + for (; interp != NULL; interp = PyInterpreterState_Next(interp)) { + total += REFTOTAL(interp); + } + HEAD_UNLOCK(&_PyRuntime); + + /* Add in the updated value from the legacy _Py_RefTotal. */ + total += get_legacy_reftotal(); + total += last_final_reftotal; + total += runtime->object_state.interpreter_leaks; + + return total; +} + +#undef REFTOTAL void _PyDebug_PrintTotalRefs(void) { + _PyRuntimeState *runtime = &_PyRuntime; fprintf(stderr, "[%zd refs, %zd blocks]\n", - _Py_GetRefTotal(), _Py_GetAllocatedBlocks()); + get_global_reftotal(runtime), _Py_GetGlobalAllocatedBlocks()); + /* It may be helpful to also print the "legacy" reftotal separately. + Likewise for the total for each interpreter. */ } #endif /* Py_REF_DEBUG */ @@ -76,11 +158,16 @@ _PyDebug_PrintTotalRefs(void) { Do not call them otherwise, they do not initialize the object! */ #ifdef Py_TRACE_REFS -/* Head of circular doubly-linked list of all objects. These are linked - * together via the _ob_prev and _ob_next members of a PyObject, which - * exist only in a Py_TRACE_REFS build. - */ -static PyObject refchain = {&refchain, &refchain}; + +#define REFCHAIN(interp) &interp->object_state.refchain + +static inline void +init_refchain(PyInterpreterState *interp) +{ + PyObject *refchain = REFCHAIN(interp); + refchain->_ob_prev = refchain; + refchain->_ob_next = refchain; +} /* Insert op at the front of the list of all objects. If force is true, * op is added even if _ob_prev and _ob_next are non-NULL already. If @@ -105,10 +192,11 @@ _Py_AddToAllObjects(PyObject *op, int force) } #endif if (force || op->_ob_prev == NULL) { - op->_ob_next = refchain._ob_next; - op->_ob_prev = &refchain; - refchain._ob_next->_ob_prev = op; - refchain._ob_next = op; + PyObject *refchain = REFCHAIN(_PyInterpreterState_GET()); + op->_ob_next = refchain->_ob_next; + op->_ob_prev = refchain; + refchain->_ob_next->_ob_prev = op; + refchain->_ob_next = op; } } #endif /* Py_TRACE_REFS */ @@ -122,6 +210,58 @@ _Py_NegativeRefcount(const char *filename, int lineno, PyObject *op) filename, lineno, __func__); } +/* This is used strictly by Py_INCREF(). */ +void +_Py_INCREF_IncRefTotal(void) +{ + reftotal_increment(_PyInterpreterState_GET()); +} + +/* This is used strictly by Py_DECREF(). */ +void +_Py_DECREF_DecRefTotal(void) +{ + reftotal_decrement(_PyInterpreterState_GET()); +} + +void +_Py_IncRefTotal(PyInterpreterState *interp) +{ + reftotal_increment(interp); +} + +void +_Py_DecRefTotal(PyInterpreterState *interp) +{ + reftotal_decrement(interp); +} + +void +_Py_AddRefTotal(PyInterpreterState *interp, Py_ssize_t n) +{ + reftotal_add(interp, n); +} + +/* This includes the legacy total + and any carried over from the last runtime init/fini cycle. */ +Py_ssize_t +_Py_GetGlobalRefTotal(void) +{ + return get_global_reftotal(&_PyRuntime); +} + +Py_ssize_t +_Py_GetLegacyRefTotal(void) +{ + return get_legacy_reftotal(); +} + +Py_ssize_t +_PyInterpreterState_GetRefTotal(PyInterpreterState *interp) +{ + return get_reftotal(interp); +} + #endif /* Py_REF_DEBUG */ void @@ -148,6 +288,9 @@ _Py_DecRef(PyObject *o) Py_DECREF(o); } + +/**************************************/ + PyObject * PyObject_Init(PyObject *op, PyTypeObject *tp) { @@ -239,17 +382,12 @@ PyObject_CallFinalizerFromDealloc(PyObject *self) /* tp_finalize resurrected it! Make it look like the original Py_DECREF * never happened. */ Py_ssize_t refcnt = Py_REFCNT(self); - _Py_NewReference(self); + _Py_NewReferenceNoTotal(self); Py_SET_REFCNT(self, refcnt); _PyObject_ASSERT(self, (!_PyType_IS_GC(Py_TYPE(self)) || _PyObject_GC_IS_TRACKED(self))); - /* If Py_REF_DEBUG macro is defined, _Py_NewReference() increased - _Py_RefTotal, so we need to undo that. */ -#ifdef Py_REF_DEBUG - _Py_RefTotal--; -#endif return -1; } @@ -273,11 +411,8 @@ PyObject_Print(PyObject *op, FILE *fp, int flags) } else { if (Py_REFCNT(op) <= 0) { - /* XXX(twouters) cast refcount to long until %zd is - universally available */ Py_BEGIN_ALLOW_THREADS - fprintf(fp, "<refcnt %ld at %p>", - (long)Py_REFCNT(op), (void *)op); + fprintf(fp, "<refcnt %zd at %p>", Py_REFCNT(op), (void *)op); Py_END_ALLOW_THREADS } else { @@ -286,31 +421,22 @@ PyObject_Print(PyObject *op, FILE *fp, int flags) s = PyObject_Str(op); else s = PyObject_Repr(op); - if (s == NULL) + if (s == NULL) { ret = -1; - else if (PyBytes_Check(s)) { - fwrite(PyBytes_AS_STRING(s), 1, - PyBytes_GET_SIZE(s), fp); } - else if (PyUnicode_Check(s)) { - PyObject *t; - t = PyUnicode_AsEncodedString(s, "utf-8", "backslashreplace"); + else { + assert(PyUnicode_Check(s)); + const char *t; + Py_ssize_t len; + t = PyUnicode_AsUTF8AndSize(s, &len); if (t == NULL) { ret = -1; } else { - fwrite(PyBytes_AS_STRING(t), 1, - PyBytes_GET_SIZE(t), fp); - Py_DECREF(t); + fwrite(t, 1, len, fp); } + Py_DECREF(s); } - else { - PyErr_Format(PyExc_TypeError, - "str() or repr() returned '%.100s'", - Py_TYPE(s)->tp_name); - ret = -1; - } - Py_XDECREF(s); } } if (ret == 0) { @@ -370,9 +496,7 @@ _PyObject_Dump(PyObject* op) /* first, write fields which are the least likely to crash */ fprintf(stderr, "object address : %p\n", (void *)op); - /* XXX(twouters) cast refcount to long until %zd is - universally available */ - fprintf(stderr, "object refcount : %ld\n", (long)Py_REFCNT(op)); + fprintf(stderr, "object refcount : %zd\n", Py_REFCNT(op)); fflush(stderr); PyTypeObject *type = Py_TYPE(op); @@ -385,13 +509,12 @@ _PyObject_Dump(PyObject* op) fflush(stderr); PyGILState_STATE gil = PyGILState_Ensure(); - PyObject *error_type, *error_value, *error_traceback; - PyErr_Fetch(&error_type, &error_value, &error_traceback); + PyObject *exc = PyErr_GetRaisedException(); (void)PyObject_Print(op, stderr, 0); fflush(stderr); - PyErr_Restore(error_type, error_value, error_traceback); + PyErr_SetRaisedException(exc); PyGILState_Release(gil); fprintf(stderr, "\n"); @@ -470,8 +593,7 @@ PyObject_Str(PyObject *v) if (PyUnicode_READY(v) < 0) return NULL; #endif - Py_INCREF(v); - return v; + return Py_NewRef(v); } if (Py_TYPE(v)->tp_str == NULL) return PyObject_Repr(v); @@ -547,8 +669,7 @@ PyObject_Bytes(PyObject *v) return PyBytes_FromString("<NULL>"); if (PyBytes_CheckExact(v)) { - Py_INCREF(v); - return v; + return Py_NewRef(v); } func = _PyObject_LookupSpecial(v, &_Py_ID(__bytes__)); @@ -704,8 +825,7 @@ do_richcompare(PyThreadState *tstate, PyObject *v, PyObject *w, int op) Py_TYPE(w)->tp_name); return NULL; } - Py_INCREF(res); - return res; + return Py_NewRef(res); } /* Perform a rich comparison with object result. This wraps do_richcompare() @@ -778,7 +898,7 @@ PyObject_Hash(PyObject *v) * an explicit call to PyType_Ready, we implicitly call * PyType_Ready here and then check the tp_hash slot again */ - if (tp->tp_dict == NULL) { + if (!_PyType_IsReady(tp)) { if (PyType_Ready(tp) < 0) return -1; if (tp->tp_hash != NULL) @@ -806,13 +926,24 @@ PyObject_GetAttrString(PyObject *v, const char *name) int PyObject_HasAttrString(PyObject *v, const char *name) { - PyObject *res = PyObject_GetAttrString(v, name); - if (res != NULL) { - Py_DECREF(res); - return 1; + if (Py_TYPE(v)->tp_getattr != NULL) { + PyObject *res = (*Py_TYPE(v)->tp_getattr)(v, (char*)name); + if (res != NULL) { + Py_DECREF(res); + return 1; + } + PyErr_Clear(); + return 0; } - PyErr_Clear(); - return 0; + + PyObject *attr_name = PyUnicode_FromString(name); + if (attr_name == NULL) { + PyErr_Clear(); + return 0; + } + int ok = PyObject_HasAttr(v, attr_name); + Py_DECREF(attr_name); + return ok; } int @@ -878,25 +1009,22 @@ set_attribute_error_context(PyObject* v, PyObject* name) return 0; } // Intercept AttributeError exceptions and augment them to offer suggestions later. - PyObject *type, *value, *traceback; - PyErr_Fetch(&type, &value, &traceback); - PyErr_NormalizeException(&type, &value, &traceback); - // Check if the normalized exception is indeed an AttributeError - if (!PyErr_GivenExceptionMatches(value, PyExc_AttributeError)) { + PyObject *exc = PyErr_GetRaisedException(); + if (!PyErr_GivenExceptionMatches(exc, PyExc_AttributeError)) { goto restore; } - PyAttributeErrorObject* the_exc = (PyAttributeErrorObject*) value; + PyAttributeErrorObject* the_exc = (PyAttributeErrorObject*) exc; // Check if this exception was already augmented if (the_exc->name || the_exc->obj) { goto restore; } // Augment the exception with the name and object - if (PyObject_SetAttr(value, &_Py_ID(name), name) || - PyObject_SetAttr(value, &_Py_ID(obj), v)) { + if (PyObject_SetAttr(exc, &_Py_ID(name), name) || + PyObject_SetAttr(exc, &_Py_ID(obj), v)) { return 1; } restore: - PyErr_Restore(type, value, traceback); + PyErr_SetRaisedException(exc); return 0; } @@ -924,7 +1052,7 @@ PyObject_GetAttr(PyObject *v, PyObject *name) } else { PyErr_Format(PyExc_AttributeError, - "'%.50s' object has no attribute '%U'", + "'%.100s' object has no attribute '%U'", tp->tp_name, name); } @@ -957,7 +1085,26 @@ _PyObject_LookupAttr(PyObject *v, PyObject *name, PyObject **result) } return 0; } - if (tp->tp_getattro != NULL) { + if (tp->tp_getattro == (getattrofunc)_Py_type_getattro) { + int supress_missing_attribute_exception = 0; + *result = _Py_type_getattro_impl((PyTypeObject*)v, name, &supress_missing_attribute_exception); + if (supress_missing_attribute_exception) { + // return 0 without having to clear the exception + return 0; + } + } + else if (tp->tp_getattro == (getattrofunc)_Py_module_getattro) { + // optimization: suppress attribute error from module getattro method + *result = _Py_module_getattro_impl((PyModuleObject*)v, name, 1); + if (*result != NULL) { + return 1; + } + if (PyErr_Occurred()) { + return -1; + } + return 0; + } + else if (tp->tp_getattro != NULL) { *result = (*tp->tp_getattro)(v, name); } else if (tp->tp_getattr != NULL) { @@ -1059,18 +1206,19 @@ PyObject_SetAttr(PyObject *v, PyObject *name, PyObject *value) } PyObject ** -_PyObject_DictPointer(PyObject *obj) +_PyObject_ComputedDictPointer(PyObject *obj) { - Py_ssize_t dictoffset; PyTypeObject *tp = Py_TYPE(obj); + assert((tp->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0); - if (tp->tp_flags & Py_TPFLAGS_MANAGED_DICT) { - return _PyObject_ManagedDictPointer(obj); - } - dictoffset = tp->tp_dictoffset; - if (dictoffset == 0) + Py_ssize_t dictoffset = tp->tp_dictoffset; + if (dictoffset == 0) { return NULL; + } + if (dictoffset < 0) { + assert(dictoffset != -1); + Py_ssize_t tsize = Py_SIZE(obj); if (tsize < 0) { tsize = -tsize; @@ -1096,29 +1244,24 @@ PyObject ** _PyObject_GetDictPtr(PyObject *obj) { if ((Py_TYPE(obj)->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0) { - return _PyObject_DictPointer(obj); - } - PyObject **dict_ptr = _PyObject_ManagedDictPointer(obj); - PyDictValues **values_ptr = _PyObject_ValuesPointer(obj); - if (*values_ptr == NULL) { - return dict_ptr; + return _PyObject_ComputedDictPointer(obj); } - assert(*dict_ptr == NULL); - PyObject *dict = _PyObject_MakeDictFromInstanceAttributes(obj, *values_ptr); - if (dict == NULL) { - PyErr_Clear(); - return NULL; + PyDictOrValues *dorv_ptr = _PyObject_DictOrValuesPointer(obj); + if (_PyDictOrValues_IsValues(*dorv_ptr)) { + PyObject *dict = _PyObject_MakeDictFromInstanceAttributes(obj, _PyDictOrValues_GetValues(*dorv_ptr)); + if (dict == NULL) { + PyErr_Clear(); + return NULL; + } + dorv_ptr->dict = dict; } - *values_ptr = NULL; - *dict_ptr = dict; - return dict_ptr; + return &dorv_ptr->dict; } PyObject * PyObject_SelfIter(PyObject *obj) { - Py_INCREF(obj); - return obj; + return Py_NewRef(obj); } /* Helper used when the __next__ method is removed from a type: @@ -1180,36 +1323,46 @@ _PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method) } } } - PyDictValues *values; - if ((tp->tp_flags & Py_TPFLAGS_MANAGED_DICT) && - (values = *_PyObject_ValuesPointer(obj))) - { - assert(*_PyObject_DictPointer(obj) == NULL); - PyObject *attr = _PyObject_GetInstanceAttribute(obj, values, name); - if (attr != NULL) { - *method = attr; - Py_XDECREF(descr); - return 0; - } - } - else { - PyObject **dictptr = _PyObject_DictPointer(obj); - PyObject *dict; - if (dictptr != NULL && (dict = *dictptr) != NULL) { - Py_INCREF(dict); - PyObject *attr = PyDict_GetItemWithError(dict, name); + PyObject *dict; + if ((tp->tp_flags & Py_TPFLAGS_MANAGED_DICT)) { + PyDictOrValues* dorv_ptr = _PyObject_DictOrValuesPointer(obj); + if (_PyDictOrValues_IsValues(*dorv_ptr)) { + PyDictValues *values = _PyDictOrValues_GetValues(*dorv_ptr); + PyObject *attr = _PyObject_GetInstanceAttribute(obj, values, name); if (attr != NULL) { - *method = Py_NewRef(attr); - Py_DECREF(dict); + *method = attr; Py_XDECREF(descr); return 0; } + dict = NULL; + } + else { + dict = dorv_ptr->dict; + } + } + else { + PyObject **dictptr = _PyObject_ComputedDictPointer(obj); + if (dictptr != NULL) { + dict = *dictptr; + } + else { + dict = NULL; + } + } + if (dict != NULL) { + Py_INCREF(dict); + PyObject *attr = PyDict_GetItemWithError(dict, name); + if (attr != NULL) { + *method = Py_NewRef(attr); Py_DECREF(dict); + Py_XDECREF(descr); + return 0; + } + Py_DECREF(dict); - if (PyErr_Occurred()) { - Py_XDECREF(descr); - return 0; - } + if (PyErr_Occurred()) { + Py_XDECREF(descr); + return 0; } } @@ -1230,7 +1383,7 @@ _PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method) } PyErr_Format(PyExc_AttributeError, - "'%.50s' object has no attribute '%U'", + "'%.100s' object has no attribute '%U'", tp->tp_name, name); set_attribute_error_context(obj, name); @@ -1253,7 +1406,6 @@ _PyObject_GenericGetAttrWithDict(PyObject *obj, PyObject *name, PyObject *descr = NULL; PyObject *res = NULL; descrgetfunc f; - PyObject **dictptr; if (!PyUnicode_Check(name)){ PyErr_Format(PyExc_TypeError, @@ -1263,7 +1415,7 @@ _PyObject_GenericGetAttrWithDict(PyObject *obj, PyObject *name, } Py_INCREF(name); - if (tp->tp_dict == NULL) { + if (!_PyType_IsReady(tp)) { if (PyType_Ready(tp) < 0) goto done; } @@ -1284,30 +1436,31 @@ _PyObject_GenericGetAttrWithDict(PyObject *obj, PyObject *name, } } if (dict == NULL) { - if ((tp->tp_flags & Py_TPFLAGS_MANAGED_DICT) && - *_PyObject_ValuesPointer(obj)) - { - PyDictValues **values_ptr = _PyObject_ValuesPointer(obj); - if (PyUnicode_CheckExact(name)) { - assert(*_PyObject_DictPointer(obj) == NULL); - res = _PyObject_GetInstanceAttribute(obj, *values_ptr, name); - if (res != NULL) { - goto done; + if ((tp->tp_flags & Py_TPFLAGS_MANAGED_DICT)) { + PyDictOrValues* dorv_ptr = _PyObject_DictOrValuesPointer(obj); + if (_PyDictOrValues_IsValues(*dorv_ptr)) { + PyDictValues *values = _PyDictOrValues_GetValues(*dorv_ptr); + if (PyUnicode_CheckExact(name)) { + res = _PyObject_GetInstanceAttribute(obj, values, name); + if (res != NULL) { + goto done; + } + } + else { + dict = _PyObject_MakeDictFromInstanceAttributes(obj, values); + if (dict == NULL) { + res = NULL; + goto done; + } + dorv_ptr->dict = dict; } } else { - dictptr = _PyObject_DictPointer(obj); - assert(dictptr != NULL && *dictptr == NULL); - *dictptr = dict = _PyObject_MakeDictFromInstanceAttributes(obj, *values_ptr); - if (dict == NULL) { - res = NULL; - goto done; - } - *values_ptr = NULL; + dict = _PyDictOrValues_GetDict(*dorv_ptr); } } else { - dictptr = _PyObject_DictPointer(obj); + PyObject **dictptr = _PyObject_ComputedDictPointer(obj); if (dictptr) { dict = *dictptr; } @@ -1351,7 +1504,7 @@ _PyObject_GenericGetAttrWithDict(PyObject *obj, PyObject *name, if (!suppress) { PyErr_Format(PyExc_AttributeError, - "'%.50s' object has no attribute '%U'", + "'%.100s' object has no attribute '%U'", tp->tp_name, name); set_attribute_error_context(obj, name); @@ -1384,8 +1537,9 @@ _PyObject_GenericSetAttrWithDict(PyObject *obj, PyObject *name, return -1; } - if (tp->tp_dict == NULL && PyType_Ready(tp) < 0) + if (!_PyType_IsReady(tp) && PyType_Ready(tp) < 0) { return -1; + } Py_INCREF(name); Py_INCREF(tp); @@ -1401,27 +1555,34 @@ _PyObject_GenericSetAttrWithDict(PyObject *obj, PyObject *name, } if (dict == NULL) { - if ((tp->tp_flags & Py_TPFLAGS_MANAGED_DICT) && *_PyObject_ValuesPointer(obj)) { - res = _PyObject_StoreInstanceAttribute(obj, *_PyObject_ValuesPointer(obj), name, value); + PyObject **dictptr; + if ((tp->tp_flags & Py_TPFLAGS_MANAGED_DICT)) { + PyDictOrValues *dorv_ptr = _PyObject_DictOrValuesPointer(obj); + if (_PyDictOrValues_IsValues(*dorv_ptr)) { + res = _PyObject_StoreInstanceAttribute( + obj, _PyDictOrValues_GetValues(*dorv_ptr), name, value); + goto error_check; + } + dictptr = &dorv_ptr->dict; } else { - PyObject **dictptr = _PyObject_DictPointer(obj); - if (dictptr == NULL) { - if (descr == NULL) { - PyErr_Format(PyExc_AttributeError, - "'%.100s' object has no attribute '%U'", - tp->tp_name, name); - } - else { - PyErr_Format(PyExc_AttributeError, - "'%.50s' object attribute '%U' is read-only", - tp->tp_name, name); - } - goto done; + dictptr = _PyObject_ComputedDictPointer(obj); + } + if (dictptr == NULL) { + if (descr == NULL) { + PyErr_Format(PyExc_AttributeError, + "'%.100s' object has no attribute '%U'", + tp->tp_name, name); } else { - res = _PyObjectDict_SetItem(tp, dictptr, name, value); + PyErr_Format(PyExc_AttributeError, + "'%.100s' object attribute '%U' is read-only", + tp->tp_name, name); } + goto done; + } + else { + res = _PyObjectDict_SetItem(tp, dictptr, name, value); } } else { @@ -1432,6 +1593,7 @@ _PyObject_GenericSetAttrWithDict(PyObject *obj, PyObject *name, res = PyDict_SetItem(dict, name, value); Py_DECREF(dict); } + error_check: if (res < 0 && PyErr_ExceptionMatches(PyExc_KeyError)) { if (PyType_IsSubtype(tp, &PyType_Type)) { PyErr_Format(PyExc_AttributeError, @@ -1463,7 +1625,7 @@ PyObject_GenericSetDict(PyObject *obj, PyObject *value, void *context) PyObject **dictptr = _PyObject_GetDictPtr(obj); if (dictptr == NULL) { if (_PyType_HasFeature(Py_TYPE(obj), Py_TPFLAGS_MANAGED_DICT) && - *_PyObject_ValuesPointer(obj) != NULL) + _PyDictOrValues_IsValues(*_PyObject_DictOrValuesPointer(obj))) { /* Was unable to convert to dict */ PyErr_NoMemory(); @@ -1484,8 +1646,7 @@ PyObject_GenericSetDict(PyObject *obj, PyObject *value, void *context) "not a '%.200s'", Py_TYPE(value)->tp_name); return -1; } - Py_INCREF(value); - Py_XSETREF(*dictptr, value); + Py_XSETREF(*dictptr, Py_NewRef(value)); return 0; } @@ -1549,13 +1710,15 @@ _dir_locals(void) PyObject *names; PyObject *locals; - locals = PyEval_GetLocals(); + locals = _PyEval_GetFrameLocals(); if (locals == NULL) return NULL; names = PyMapping_Keys(locals); - if (!names) + Py_DECREF(locals); + if (!names) { return NULL; + } if (!PyList_Check(names)) { PyErr_Format(PyExc_TypeError, "dir(): expected keys() of locals to be a list, " @@ -1567,7 +1730,6 @@ _dir_locals(void) Py_DECREF(names); return NULL; } - /* the locals don't need to be DECREF'd */ return names; } @@ -1624,10 +1786,14 @@ none_repr(PyObject *op) return PyUnicode_FromString("None"); } -static void _Py_NO_RETURN -none_dealloc(PyObject* Py_UNUSED(ignore)) +static void +none_dealloc(PyObject* none) { - _Py_FatalRefcountError("deallocating None"); + /* This should never get called, but we also don't want to SEGV if + * we accidentally decref None out of existence. Instead, + * since None is an immortal object, re-set the reference count. + */ + _Py_SetImmortal(none); } static PyObject * @@ -1646,6 +1812,11 @@ none_bool(PyObject *v) return 0; } +static Py_hash_t none_hash(PyObject *v) +{ + return 0xFCA86420; +} + static PyNumberMethods none_as_number = { 0, /* nb_add */ 0, /* nb_subtract */ @@ -1688,7 +1859,7 @@ PyTypeObject _PyNone_Type = { "NoneType", 0, 0, - none_dealloc, /*tp_dealloc*/ /*never called*/ + none_dealloc, /*tp_dealloc*/ 0, /*tp_vectorcall_offset*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ @@ -1697,7 +1868,7 @@ PyTypeObject _PyNone_Type = { &none_as_number, /*tp_as_number*/ 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ - 0, /*tp_hash */ + (hashfunc)none_hash,/*tp_hash */ 0, /*tp_call */ 0, /*tp_str */ 0, /*tp_getattro */ @@ -1725,8 +1896,9 @@ PyTypeObject _PyNone_Type = { }; PyObject _Py_NoneStruct = { - _PyObject_EXTRA_INIT - 1, &_PyNone_Type + _PyObject_EXTRA_INIT + { _Py_IMMORTAL_REFCNT }, + &_PyNone_Type }; /* NotImplemented is an object that can be used to signal that an @@ -1759,13 +1931,14 @@ notimplemented_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) Py_RETURN_NOTIMPLEMENTED; } -static void _Py_NO_RETURN -notimplemented_dealloc(PyObject* ignore) +static void +notimplemented_dealloc(PyObject *notimplemented) { /* This should never get called, but we also don't want to SEGV if - * we accidentally decref NotImplemented out of existence. + * we accidentally decref NotImplemented out of existence. Instead, + * since Notimplemented is an immortal object, re-set the reference count. */ - Py_FatalError("deallocating NotImplemented"); + _Py_SetImmortal(notimplemented); } static int @@ -1827,31 +2000,27 @@ PyTypeObject _PyNotImplemented_Type = { PyObject _Py_NotImplementedStruct = { _PyObject_EXTRA_INIT - 1, &_PyNotImplemented_Type + { _Py_IMMORTAL_REFCNT }, + &_PyNotImplemented_Type }; -PyStatus -_PyTypes_InitState(PyInterpreterState *interp) + +void +_PyObject_InitState(PyInterpreterState *interp) { +#ifdef Py_TRACE_REFS if (!_Py_IsMainInterpreter(interp)) { - return _PyStatus_OK(); - } - - PyStatus status = _PyTypes_InitSlotDefs(); - if (_PyStatus_EXCEPTION(status)) { - return status; + init_refchain(interp); } - - return _PyStatus_OK(); +#endif } - -#ifdef MS_WINDOWS -extern PyTypeObject PyHKEY_Type; -#endif extern PyTypeObject _Py_GenericAliasIterType; extern PyTypeObject _PyMemoryIter_Type; +extern PyTypeObject _PyLineIterator; +extern PyTypeObject _PyPositionsIterator; +extern PyTypeObject _PyLegacyEventHandler_Type; static PyTypeObject* static_types[] = { // The two most important base types: must be initialized first and @@ -1897,9 +2066,6 @@ static PyTypeObject* static_types[] = { &PyFunction_Type, &PyGen_Type, &PyGetSetDescr_Type, -#ifdef MS_WINDOWS - &PyHKEY_Type, -#endif &PyInstanceMethod_Type, &PyListIter_Type, &PyListRevIter_Type, @@ -1939,6 +2105,7 @@ static PyTypeObject* static_types[] = { &_PyAsyncGenASend_Type, &_PyAsyncGenAThrow_Type, &_PyAsyncGenWrappedValue_Type, + &_PyBufferWrapper_Type, &_PyContextTokenMissing_Type, &_PyCoroWrapper_Type, &_Py_GenericAliasIterType, @@ -1949,18 +2116,22 @@ static PyTypeObject* static_types[] = { &_PyHamt_BitmapNode_Type, &_PyHamt_CollisionNode_Type, &_PyHamt_Type, + &_PyLegacyEventHandler_Type, &_PyInterpreterID_Type, + &_PyLineIterator, &_PyManagedBuffer_Type, &_PyMemoryIter_Type, &_PyMethodWrapper_Type, &_PyNamespace_Type, &_PyNone_Type, &_PyNotImplemented_Type, + &_PyPositionsIterator, &_PyUnicodeASCIIIter_Type, &_PyUnion_Type, &_PyWeakref_CallableProxyType, &_PyWeakref_ProxyType, &_PyWeakref_RefType, + &_PyTypeAlias_Type, // subclasses: _PyTypes_FiniTypes() deallocates them before their base // class @@ -1976,15 +2147,11 @@ static PyTypeObject* static_types[] = { PyStatus _PyTypes_InitTypes(PyInterpreterState *interp) { - if (!_Py_IsMainInterpreter(interp)) { - return _PyStatus_OK(); - } - // All other static types (unless initialized elsewhere) for (size_t i=0; i < Py_ARRAY_LENGTH(static_types); i++) { PyTypeObject *type = static_types[i]; - if (PyType_Ready(type) < 0) { - return _PyStatus_ERR("Can't initialize types"); + if (_PyStaticType_InitBuiltin(interp, type) < 0) { + return _PyStatus_ERR("Can't initialize builtin type"); } if (type == &PyType_Type) { // Sanitify checks of the two most important types @@ -1993,6 +2160,11 @@ _PyTypes_InitTypes(PyInterpreterState *interp) } } + // Must be after static types are initialized + if (_Py_initialize_generic(interp) < 0) { + return _PyStatus_ERR("Can't initialize generic types"); + } + return _PyStatus_OK(); } @@ -2006,34 +2178,43 @@ _PyTypes_InitTypes(PyInterpreterState *interp) void _PyTypes_FiniTypes(PyInterpreterState *interp) { - if (!_Py_IsMainInterpreter(interp)) { - return; - } - // Deallocate types in the reverse order to deallocate subclasses before // their base classes. for (Py_ssize_t i=Py_ARRAY_LENGTH(static_types)-1; i>=0; i--) { PyTypeObject *type = static_types[i]; - _PyStaticType_Dealloc(type); + _PyStaticType_Dealloc(interp, type); } } -void -_Py_NewReference(PyObject *op) +static inline void +new_reference(PyObject *op) { - if (_Py_tracemalloc_config.tracing) { + if (_PyRuntime.tracemalloc.config.tracing) { _PyTraceMalloc_NewReference(op); } -#ifdef Py_REF_DEBUG - _Py_RefTotal++; -#endif - Py_SET_REFCNT(op, 1); + // Skip the immortal object check in Py_SET_REFCNT; always set refcnt to 1 + op->ob_refcnt = 1; #ifdef Py_TRACE_REFS _Py_AddToAllObjects(op, 1); #endif } +void +_Py_NewReference(PyObject *op) +{ +#ifdef Py_REF_DEBUG + reftotal_increment(_PyInterpreterState_GET()); +#endif + new_reference(op); +} + +void +_Py_NewReferenceNoTotal(PyObject *op) +{ + new_reference(op); +} + #ifdef Py_TRACE_REFS void @@ -2043,7 +2224,8 @@ _Py_ForgetReference(PyObject *op) _PyObject_ASSERT_FAILED_MSG(op, "negative refcnt"); } - if (op == &refchain || + PyObject *refchain = REFCHAIN(_PyInterpreterState_GET()); + if (op == refchain || op->_ob_prev->_ob_next != op || op->_ob_next->_ob_prev != op) { _PyObject_ASSERT_FAILED_MSG(op, "invalid object chain"); @@ -2051,12 +2233,12 @@ _Py_ForgetReference(PyObject *op) #ifdef SLOW_UNREF_CHECK PyObject *p; - for (p = refchain._ob_next; p != &refchain; p = p->_ob_next) { + for (p = refchain->_ob_next; p != refchain; p = p->_ob_next) { if (p == op) { break; } } - if (p == &refchain) { + if (p == refchain) { /* Not found */ _PyObject_ASSERT_FAILED_MSG(op, "object not found in the objects list"); @@ -2072,11 +2254,15 @@ _Py_ForgetReference(PyObject *op) * interpreter must be in a healthy state. */ void -_Py_PrintReferences(FILE *fp) +_Py_PrintReferences(PyInterpreterState *interp, FILE *fp) { PyObject *op; + if (interp == NULL) { + interp = _PyInterpreterState_Main(); + } fprintf(fp, "Remaining objects:\n"); - for (op = refchain._ob_next; op != &refchain; op = op->_ob_next) { + PyObject *refchain = REFCHAIN(interp); + for (op = refchain->_ob_next; op != refchain; op = op->_ob_next) { fprintf(fp, "%p [%zd] ", (void *)op, Py_REFCNT(op)); if (PyObject_Print(op, fp, 0) != 0) { PyErr_Clear(); @@ -2088,34 +2274,42 @@ _Py_PrintReferences(FILE *fp) /* Print the addresses of all live objects. Unlike _Py_PrintReferences, this * doesn't make any calls to the Python C API, so is always safe to call. */ +// XXX This function is not safe to use if the interpreter has been +// freed or is in an unhealthy state (e.g. late in finalization). +// The call in Py_FinalizeEx() is okay since the main interpreter +// is statically allocated. void -_Py_PrintReferenceAddresses(FILE *fp) +_Py_PrintReferenceAddresses(PyInterpreterState *interp, FILE *fp) { PyObject *op; + PyObject *refchain = REFCHAIN(interp); fprintf(fp, "Remaining object addresses:\n"); - for (op = refchain._ob_next; op != &refchain; op = op->_ob_next) + for (op = refchain->_ob_next; op != refchain; op = op->_ob_next) fprintf(fp, "%p [%zd] %s\n", (void *)op, Py_REFCNT(op), Py_TYPE(op)->tp_name); } +/* The implementation of sys.getobjects(). */ PyObject * _Py_GetObjects(PyObject *self, PyObject *args) { int i, n; PyObject *t = NULL; PyObject *res, *op; + PyInterpreterState *interp = _PyInterpreterState_GET(); if (!PyArg_ParseTuple(args, "i|O", &n, &t)) return NULL; - op = refchain._ob_next; + PyObject *refchain = REFCHAIN(interp); + op = refchain->_ob_next; res = PyList_New(0); if (res == NULL) return NULL; - for (i = 0; (n == 0 || i < n) && op != &refchain; i++) { + for (i = 0; (n == 0 || i < n) && op != refchain; i++) { while (op == self || op == args || op == res || op == t || (t != NULL && !Py_IS_TYPE(op, (PyTypeObject *) t))) { op = op->_ob_next; - if (op == &refchain) + if (op == refchain) return res; } if (PyList_Append(res, op) < 0) { @@ -2127,7 +2321,9 @@ _Py_GetObjects(PyObject *self, PyObject *args) return res; } -#endif +#undef REFCHAIN + +#endif /* Py_TRACE_REFS */ /* Hack to force loading of abstract.o */ @@ -2195,9 +2391,8 @@ Py_ReprLeave(PyObject *obj) PyObject *dict; PyObject *list; Py_ssize_t i; - PyObject *error_type, *error_value, *error_traceback; - PyErr_Fetch(&error_type, &error_value, &error_traceback); + PyObject *exc = PyErr_GetRaisedException(); dict = PyThreadState_GetDict(); if (dict == NULL) @@ -2218,7 +2413,7 @@ Py_ReprLeave(PyObject *obj) finally: /* ignore exceptions because there is no way to report them. */ - PyErr_Restore(error_type, error_value, error_traceback); + PyErr_SetRaisedException(exc); } /* Trashcan support. */ @@ -2230,22 +2425,20 @@ finally: * object, with refcount 0. Py_DECREF must already have been called on it. */ static void -_PyTrash_thread_deposit_object(PyObject *op) +_PyTrash_thread_deposit_object(struct _py_trashcan *trash, PyObject *op) { - PyThreadState *tstate = _PyThreadState_GET(); _PyObject_ASSERT(op, _PyObject_IS_GC(op)); _PyObject_ASSERT(op, !_PyObject_GC_IS_TRACKED(op)); _PyObject_ASSERT(op, Py_REFCNT(op) == 0); - _PyGCHead_SET_PREV(_Py_AS_GC(op), tstate->trash_delete_later); - tstate->trash_delete_later = op; + _PyGCHead_SET_PREV(_Py_AS_GC(op), (PyGC_Head*)trash->delete_later); + trash->delete_later = op; } /* Deallocate all the objects in the gcstate->trash_delete_later list. * Called when the call-stack unwinds again. */ static void -_PyTrash_thread_destroy_chain(void) +_PyTrash_thread_destroy_chain(struct _py_trashcan *trash) { - PyThreadState *tstate = _PyThreadState_GET(); /* We need to increase trash_delete_nesting here, otherwise, _PyTrash_thread_destroy_chain will be called recursively and then possibly crash. An example that may crash without @@ -2257,13 +2450,13 @@ _PyTrash_thread_destroy_chain(void) tups = [(tup,) for tup in tups] del tups */ - assert(tstate->trash_delete_nesting == 0); - ++tstate->trash_delete_nesting; - while (tstate->trash_delete_later) { - PyObject *op = tstate->trash_delete_later; + assert(trash->delete_nesting == 0); + ++trash->delete_nesting; + while (trash->delete_later) { + PyObject *op = trash->delete_later; destructor dealloc = Py_TYPE(op)->tp_dealloc; - tstate->trash_delete_later = + trash->delete_later = (PyObject*) _PyGCHead_PREV(_Py_AS_GC(op)); /* Call the deallocator directly. This used to try to @@ -2274,22 +2467,64 @@ _PyTrash_thread_destroy_chain(void) */ _PyObject_ASSERT(op, Py_REFCNT(op) == 0); (*dealloc)(op); - assert(tstate->trash_delete_nesting == 1); + assert(trash->delete_nesting == 1); + } + --trash->delete_nesting; +} + + +static struct _py_trashcan * +_PyTrash_get_state(PyThreadState *tstate) +{ + if (tstate != NULL) { + return &tstate->trash; + } + // The current thread must be finalizing. + // Fall back to using thread-local state. + // XXX Use thread-local variable syntax? + assert(PyThread_tss_is_created(&_PyRuntime.trashTSSkey)); + struct _py_trashcan *trash = + (struct _py_trashcan *)PyThread_tss_get(&_PyRuntime.trashTSSkey); + if (trash == NULL) { + trash = PyMem_RawMalloc(sizeof(struct _py_trashcan)); + if (trash == NULL) { + Py_FatalError("Out of memory"); + } + PyThread_tss_set(&_PyRuntime.trashTSSkey, (void *)trash); + } + return trash; +} + +static void +_PyTrash_clear_state(PyThreadState *tstate) +{ + if (tstate != NULL) { + assert(tstate->trash.delete_later == NULL); + return; + } + if (PyThread_tss_is_created(&_PyRuntime.trashTSSkey)) { + struct _py_trashcan *trash = + (struct _py_trashcan *)PyThread_tss_get(&_PyRuntime.trashTSSkey); + if (trash != NULL) { + PyThread_tss_set(&_PyRuntime.trashTSSkey, (void *)NULL); + PyMem_RawFree(trash); + } } - --tstate->trash_delete_nesting; } int _PyTrash_begin(PyThreadState *tstate, PyObject *op) { - if (tstate->trash_delete_nesting >= _PyTrash_UNWIND_LEVEL) { + // XXX Make sure the GIL is held. + struct _py_trashcan *trash = _PyTrash_get_state(tstate); + if (trash->delete_nesting >= _PyTrash_UNWIND_LEVEL) { /* Store the object (to be deallocated later) and jump past * Py_TRASHCAN_END, skipping the body of the deallocator */ - _PyTrash_thread_deposit_object(op); + _PyTrash_thread_deposit_object(trash, op); return 1; } - ++tstate->trash_delete_nesting; + ++trash->delete_nesting; return 0; } @@ -2297,9 +2532,14 @@ _PyTrash_begin(PyThreadState *tstate, PyObject *op) void _PyTrash_end(PyThreadState *tstate) { - --tstate->trash_delete_nesting; - if (tstate->trash_delete_later && tstate->trash_delete_nesting <= 0) { - _PyTrash_thread_destroy_chain(); + // XXX Make sure the GIL is held. + struct _py_trashcan *trash = _PyTrash_get_state(tstate); + --trash->delete_nesting; + if (trash->delete_nesting <= 0) { + if (trash->delete_later != NULL) { + _PyTrash_thread_destroy_chain(trash); + } + _PyTrash_clear_state(tstate); } } @@ -2347,14 +2587,9 @@ _PyObject_AssertFailed(PyObject *obj, const char *expr, const char *msg, /* Display the traceback where the object has been allocated. Do it before dumping repr(obj), since repr() is more likely to crash than dumping the traceback. */ - void *ptr; PyTypeObject *type = Py_TYPE(obj); - if (_PyType_IS_GC(type)) { - ptr = (void *)((char *)obj - sizeof(PyGC_Head)); - } - else { - ptr = (void *)obj; - } + const size_t presize = _PyType_PreHeaderSize(type); + void *ptr = (void *)((char *)obj - presize); _PyMem_DumpTraceback(fileno(stderr), ptr); /* This might succeed or fail, but we're about to abort, so at least @@ -2376,10 +2611,10 @@ _Py_Dealloc(PyObject *op) destructor dealloc = type->tp_dealloc; #ifdef Py_DEBUG PyThreadState *tstate = _PyThreadState_GET(); - PyObject *old_exc_type = tstate->curexc_type; + PyObject *old_exc = tstate != NULL ? tstate->current_exception : NULL; // Keep the old exception type alive to prevent undefined behavior // on (tstate->curexc_type != old_exc_type) below - Py_XINCREF(old_exc_type); + Py_XINCREF(old_exc); // Make sure that type->tp_name remains valid Py_INCREF(type); #endif @@ -2392,12 +2627,12 @@ _Py_Dealloc(PyObject *op) #ifdef Py_DEBUG // gh-89373: The tp_dealloc function must leave the current exception // unchanged. - if (tstate->curexc_type != old_exc_type) { + if (tstate != NULL && tstate->current_exception != old_exc) { const char *err; - if (old_exc_type == NULL) { + if (old_exc == NULL) { err = "Deallocator of type '%s' raised an exception"; } - else if (tstate->curexc_type == NULL) { + else if (tstate->current_exception == NULL) { err = "Deallocator of type '%s' cleared the current exception"; } else { @@ -2408,7 +2643,7 @@ _Py_Dealloc(PyObject *op) } _Py_FatalErrorFormat(__func__, err, type->tp_name); } - Py_XDECREF(old_exc_type); + Py_XDECREF(old_exc); Py_DECREF(type); #endif } diff --git a/Objects/object_layout.md b/Objects/object_layout.md new file mode 100644 index 00000000..9380b579 --- /dev/null +++ b/Objects/object_layout.md @@ -0,0 +1,82 @@ +# Object layout + +## Common header + +Each Python object starts with two fields: + +* ob_refcnt +* ob_type + +which the form the header common to all Python objects, for all versions, +and hold the reference count and class of the object, respectively. + +## Pre-header + +Since the introduction of the cycle GC, there has also been a pre-header. +Before 3.11, this pre-header was two words in size. +It should be considered opaque to all code except the cycle GC. + +## 3.11 pre-header + +In 3.11 the pre-header was extended to include pointers to the VM managed ``__dict__``. +The reason for moving the ``__dict__`` to the pre-header is that it allows +faster access, as it is at a fixed offset, and it also allows object's +dictionaries to be lazily created when the ``__dict__`` attribute is +specifically asked for. + +In the 3.11 the non-GC part of the pre-header consists of two pointers: + +* dict +* values + +The values pointer refers to the ``PyDictValues`` array which holds the +values of the objects's attributes. +Should the dictionary be needed, then ``values`` is set to ``NULL`` +and the ``dict`` field points to the dictionary. + +## 3.12 pre-header + +In 3.12 the the pointer to the list of weak references is added to the +pre-header. In order to make space for it, the ``dict`` and ``values`` +pointers are combined into a single tagged pointer: + +* weakreflist +* dict_or_values + +If the object has no physical dictionary, then the ``dict_or_values`` +has its low bit set to one, and points to the values array. +If the object has a physical dictioanry, then the ``dict_or_values`` +has its low bit set to zero, and points to the dictionary. + +The untagged form is chosen for the dictionary pointer, rather than +the values pointer, to enable the (legacy) C-API function +`_PyObject_GetDictPtr(PyObject *obj)` to work. + + +## Layout of a "normal" Python object in 3.12: + +* weakreflist +* dict_or_values +* GC 1 +* GC 2 +* ob_refcnt +* ob_type + +For a "normal" Python object, that is one that doesn't inherit from a builtin +class or have slots, the header and pre-header form the entire object. + +![Layout of "normal" object in 3.12](./object_layout_312.png) + +There are several advantages to this layout: + +* It allows lazy `__dict__`s, as described above. +* The regular layout allows us to create tailored traversal and deallocation + functions based on layout, rather than inheritance. +* Multiple inheritance works properly, + as the weakrefs and dict are always at the same offset. + +The full layout object, with an opaque part defined by a C extension, +and `__slots__` looks like this: + +![Layout of "full" object in 3.12](./object_layout_full_312.png) + diff --git a/Objects/object_layout_312.gv b/Objects/object_layout_312.gv new file mode 100644 index 00000000..c0068d78 --- /dev/null +++ b/Objects/object_layout_312.gv @@ -0,0 +1,50 @@ +digraph ideal { + + rankdir = "LR" + + + object [ + shape = none + label = <<table border="0" cellspacing="0"> + <tr><td><b>object</b></td></tr> + <tr><td port="w" border="1">weakrefs</td></tr> + <tr><td port="dv" border="1">dict or values</td></tr> + <tr><td border="1" >GC info 0</td></tr> + <tr><td border="1" >GC info 1</td></tr> + <tr><td port="r" border="1" >refcount</td></tr> + <tr><td port="h" border="1" >__class__</td></tr> + </table>> + ] + + values [ + shape = none + label = <<table border="0" cellspacing="0"> + <tr><td><b>values</b></td></tr> + <tr><td port="0" border="1">values[0]</td></tr> + <tr><td border="1">values[1]</td></tr> + <tr><td border="1">...</td></tr> + </table>> + + ] + + class [ + shape = none + label = <<table border="0" cellspacing="0"> + <tr><td><b>class</b></td></tr> + <tr><td port="head" bgcolor="lightgreen" border="1">...</td></tr> + <tr><td border="1" bgcolor="lightgreen">dict_offset</td></tr> + <tr><td border="1" bgcolor="lightgreen">...</td></tr> + <tr><td port="k" border="1" bgcolor="lightgreen">cached_keys</td></tr> + </table>> + ] + + keys [label = "dictionary keys"; fillcolor="lightgreen"; style="filled"] + NULL [ label = " NULL"; shape="plain"] + object:w -> NULL + object:h -> class:head + object:dv -> values:0 + class:k -> keys + + oop [ label = "pointer"; shape="plain"] + oop -> object:r +} diff --git a/Objects/object_layout_312.png b/Objects/object_layout_312.png new file mode 100644 index 0000000000000000000000000000000000000000..396dab183b3e9b2f39edb49b033a612e66d3a09a GIT binary patch literal 30688 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%0D4>uj@4HG zz(6GtCUR4|489u})9T^I>3VM4uHJHbPhG5^@pz|3f&C}F;_uTy(BvU>zMCXOfAi^p zxw$#v_xiP($%zx>LIDELqap@e;gt6dA`zBQjG_qBBb<fe%QH`%mJ)@vL$-_EVRK(y zS)QDlx|*K8i$mU<N>ES`Y~|axS0Q3M{?y*22Wg|)xbg70b5EKroSh}M(bKnN7>l8m z&(F`F`cmlNu{3|NETPwUYWk->iN}DHuid=4adCDmq_}uL$vx58s!_S#+&szdHr#gf zf;_f61#xHh34z<_g)~I2%b<4WmoG}HsvA%iRu|s;n(r3_dK_5PR#$&2<(tv-#S>=@ z`|Pm3KE1=2!XwJc{!XK9>H0%mC3~l5X7Zf+6iNJb^XAPNS0n7+tFa%PE?p9^wjM0% znZScO|F!b!<0ns4&=!@IZ$EgTH9I>?7F?7*#covQ7Idogw6vhY3*G8lw{E>18><Gk zz3)sdm7cC{QfH?L4^MtxUee0)AAM6(*6wnj`ywJDXd2o>!h81IBAOqmMg#>7VX^js z;sl3<@yBVZ$a&5385$a{In?Vj$9}TZBNA*}r9Ohw_h+ZFGT5;Io>9r1t)-<B8Z!9; zAZ7CJ)HO7`Mg|!O++^EjSp|i}Z~gs0QQD>fKwAN|(y;*R{K$Uz?p=8K^6Uw9O-=8S zJV~ax@oxHey9gW?0iNXid<j<ZGwTBU{dJBXXIWTSpd*6A!=IqLGzW5CQ6paW^q3FX z0fH+kNW_H#;=Bg--1!nsE#~&^W-w|0{0|@Wcz6z8p5B?Bo*tQzA&eUeEua4eY^Cfv z-gThy?OXnv%8GKAryt_VKY)#@Sy&`yo0TNrazWh^8~uSw*JkXjs?0!7uSD!b+ur%5 z_#!XG!#8)uHd&$I;vSSi7tY$-YXS^x3rCsvBbv8ccpp|)#))~fg-wd89xHZCFWq3i z+}61WIN;ah<ip@#>XKrd$^eDZm|+Pi-I?#%xw&`>DH?bE^YJv>?VRVZ@%6E<8>*_V zk`2`MV>UaU=*Eo%A+c}Y<Ev{oeDGcUV?iEoIiJPptol}y<*9nkYR{GNmlHujX~o5{ z0-CX0ZQ@c=0>pFlEFPYFsG$^Gc%n(~6ryE#k_X=0eZ%jrti0FyUFMxGLxEWI9%bd{ zj=l104k_K(oTPDAl#Y<tv*#fW**3Zs(BdJo>3W?3H+a_V{hmF8UPea7<oNN^xK8H1 z=Qa~uQc_Hml$1fCp|z@<KK?kUhjC=dl9z3E`10k0=w>=uIpC#KV-#Pj12&mdT#>u7 zvS4jvYipEI;raU<S)|cbb1pTZ9up+bN*euKU?;}@QUE~S=JWGii_<^X($LTV;hyTq zJT7){w__$~k4^Ur$$k6wJ<Q750+oPNYHV7P*P9mD1~Bb5J*29dYHn%ML>_1qn|{1u z=L<LCAMYN7kYYuR@5*n^q<4dfzTqg5vG?y^54v^#{-&=BauGl(j?c@QaK-~PGI6Y& z>(Nh|law}qH1R@j!iK6v1<kc-;YmxM%DGTyGB%$eV`SZ57gp2qNLAOwBnbQUA?ot{ zuQy_O?i1!jCAQh*z+H<qgoK0yK{PZpaPgFU1hgY$dxOt{V~{X~l7?gR_U+qgbqg+% zrEh-T!@j4q<a6G=gmqbOIty-whWbNc!I5u)E+u06oC@?V$LWswTRbCLfO>49(=)^E zCZ!(Y=ibF{L_u^N?Tn;<>0a5|N?-X~jz-L)JQR=j^y^#P)l;By6z>z{NI5|sA{!qc zA632Wy_}rnVIMCLtBfu)t)oY;nuyea3R0rk-M(|@%%^;-q1IFyh%h}iW_7X70PyXf zaJIRl8=R(xbVs{N=+Ql1p`ct`UGXt{;kpt3`750rvasN+{CzfE07sf65as3aXDluI zhKEi2pR!LbQMzx~u%YRJOp&&9RE7QM_PnAZ)iY;!)~sE7+Qufxv3!B@@ZrNbT{K?4 z05;UZl_ah~DSMdwtHL4-<uf-guPXk4OD@EKr9Zu^+4>cRf6~H8_+O5{3Ujk}aG>Ml z6w4G)QC01~?^vF$zd1Co?q)Qe+S~ims)_PGli+<MUIdjsgj0RW!66K|;pq6Tx1uLs zkXK(`UXJ#uYHKUx?Ba3}8kC2pC%2Fg_1r{nJ!t87Q9Hwv8+Yy6MOVI+h9(fok=e<U z1C7GQ?N8-B=kxP2W-ZLjM7%8^P61vWLPK!*(M0NdI30emv9U$2l*g4Gr>AcO_#oaJ z>#2tC*tLU~2SQgLo_OqDYwfVRi*}E)vUYo)Ja7y;(7-V8Ky_y)Gm#6a#5SWApKVfL z%LpYW4~H4NVngNcHzhzlY}(_U!Yn{aD4V=R=ST2(@~qx4dCz{bR*b`iqNCmT_U#P% zVr5s?4zw~zS~aNLr_Y_EBsvT1w&RA$T^ujtzBM2qpxE=bz?IcycdR#M<!=YFzyyQI z@SqCd;U9rgK}}8V^y~Xk;t)>ngL=w@)t1oUV8ts}<h36h<bQs$-1~r{q9RUPNLQB` zEgjCbzOUeINvgf)n*1O|k+qtcnVD(;g-?-ZW~haikDtE}jhH@s@W+qj$B)-x$+tHO zjku3@9p4!e5<*HIdDibal12fwbpB@!L;_y2dS;#|+FDXlqG%6-n;rP9l3Aa1Vu@v| zk>l|1^PkkQLHD6xmE@D%0p-EmavA(2G9`uo{Q2{`XjVV5e%0c@c^_I^AK{K#&|Y_m zh=kUj5r6wY#`r=AHSrwi-1NCkq}lQIy9PojB=A2!+9>FoQ4Trrs6e!?lhYo2PGnx5 zc-;N_t-l7|WXL7`k^0JiA}QB>B1Eh_?P5qI>PMuB$P@Atumg61azQOQnxc14&Pz%w zLAK<xcjN2VTs%A$78W1c+xhqI-Rtb`em6syDI`FA&6+i7h8aeWv$M4!QY1;*b?D%^ z#Kgq3MDc6v+_&#Gi32)2WABI@*AsJz5`VJqQb<tGWcaC$QwHYRPrWOzN}BORQh`x3 zOWNK}RyqxQY*xLHFY<q6001lRqSFRbfhTaA>YqM>vQ`U4ZqeY<!f!Qg?HeS*+?l!c z%$YMDi7%xY(Bn}0js#Bi^o?n;=wFEM+7(&o@I?`NhEm{GL)V?7{MW8sJ7r~+GPLKm z3UE}il80DrZ7tW%ooXb$9A*)8SFdeuroD0F2G!=x2LF74jZGR}K$+v$!H(<LrBFWj zzgidna^<W^z&57=llSc1tE8v5jo=a%-URgw=PTySb*~L)C0HP_QJ`i)eN}Gh%cWG) zb>Z8&lZq!&%_EFu?-T7YXxMxo-@SX6oxp1qDtR`(OH%RKxwnd7y&pb&_}+MPC}!^U zrmb65w6))T*__j}4DmZw#$6Pmk!M8?<r&}z0MxwX8rq%C;X$v?(9#8wDm6o6Yin!Y zw{L6Y<m8^)w5(y1vZoC{aNxj32Z3V=OWOVTC|UBOpw{2W$;mN`yLy!Z%p&(x)wP3j z`Z_w3<`-T{T%NY6ef4VB!Ocdm(AiI4xDa0M^XCj8F|d@OjqDbOaA<Q?Jv|(dch%I@ z70;gK!#=r&K48?61bc@|dz^KbrDebLI4la5Vwg53f_`-G1toN)8s&r-?DV6FrMRR7 zC;*}-U1yOa=UIt3#c$`;Tx#FHr-8IXwPi~Ht_)RK+-ugJT*KmmYvOf67o9(<Edc_N zN^D`F)Qd}FLU(UBoR#no2&igl$@?7KLlSg5yG^@y?*_A=hLp3GD1Q0U5}F9%M<YK^ zVAJAY6@>fZ680ZF2;xxF*2VxRy<K#$r`(4PmdhSV$yYUjG=1N{uLEo~EA_}TRY0%5 z`?6?gqGFYjShsE+l@)ka4Sq@7`MVmFH9Uan(NFZCaEyx!g9Fx*l9EY2T9$@Bj**d( zxrK$;bd;HynPd;yRR3R?#+G4cOC@74d;man(QhcNP8Tm;Rpz-0D!i3LHV8Z7?rf61 z%j4waH8Ph*{j##My6Qe&r`)1={(So6#4Yi<b+xx|;Fk}`$QTPN_^!yFx3!I`s8F!7 zw${hfL1CgJUH}7+b>>}%fK0)~$;p{?(!*oFq{HXi?-JxRP`3BE{Lox;sIRXNU=Oy` znnPeSVxc4G-j6dfG&az1Jch#%92CTrXQC-3C1qf0s{TJwft(Iwz`B|7?)yYDbk~4i zxG@soqLu0cPJHU@)B!f!wR?Bih2C;4oSU=O)`D$!8_urt12BV3fRAnio_e}?jA!rO zXl#Rx1V9%ZT?;rb34O7IyLfr8tAsKi#&%+0W7AMp#x*@h6N+j$>k3juqT%PypW9BX zB?(9AWT~V8VLlIalb0ZG2OA;<9Gbiu{J2@cH>~Wv3m-U7?U}r;KQ|*H1c`k(1|`2x z<hK#55@&<V7N8L~baWKf{Wfb|I1{?-LHE*>WmqNHTFXm!$EHLDPGS#s10)Mh@Jb4T z6gAO!v9bZpPl}6~6A}_k^3JS>Q9ux|GL*3T=!3(uQgo+(G{uoZMSOfbA-kHE2BnQu zN$cR1(6O^`!LyqG^9NLngG5T8vL=?kdg%-!A9LzKd3F|k)-7@V_TvZT*9F^p>qH+C zi^bl%muyjSh1B-#!t{9}NwucfZRC#5xl^b7(2n|nvI#$MDG`%g!unnOVK@?mtS>F- z<XV$w=eB?^27}E!f}h#k*5?1{5$_$*lZ(~AYdG&4N?Tc35edCsh3Kd_cS&eNxdjDT zM#i6hs110{4`wj{ArO;Tt?h-@p_1~X&a(`)WFEIfDzUF)+<$&JGVYabAT+o9Dr7rO z$W=HAYCA{T(&-_<Tl_p<3TDbDAW;4JvuQTeDfY_Wfiixp-MwwF2JX&&O4k>h9{ETE z>-Uk)rGZAqk}*zTMRCXzr2RqKqRPs(8e%`wGct^YTXDS0%P)<wq8qnhPxa}Ug)r?V z2)JN=ckVEe;6&bMvGU``?Z8K|l6Fj*T3Qy137ub3G+iD8OAufWyP*h~o7-su5{4O% z-!>Z%s!@n8^3~IgeE%EumVy8haoo28xIhqi+|C2%&Yf%S=uiO`^c$X&E^7i5+GF3j z2mR<P3;^lsnwmT~bA29gHM_dHZr!<aW8wFp5<DpY>k+oHyNxc9@$s8oTz<2Tkd6|B zMU%42k{#J6L-2c+3%>^1-#NA~jt&$Yb9?g7EP#S9st%;3!^XzjflPNnTMxXlym)$| zr>tPbEXFF_K;Q~YFy{drF6Vj{%gk*#UAsyeSKB{cihCvnen$8K+e))m{Gu^y*Ek*n zZ=)F+<Huq5q2?r;FNM3ITttEap|qmh5r+WRu$Ld^<V4_U0d+TKWtWQj`1lZF+OJ2) z#z=<>nja~-08by*(P?Ij=w?oT`cx5T4&o3qSp1bgW722OojZf-Jk(pUszI-4701gi zbICs;fdfZ;pb^6OS^}2bN4EO6%=)5e`Ug&&IFXi?b_zHP|46%3>YS4F%h_O{ObfDG zpoxeIjurN5FbEbG>>;wxB_?wEt!5QAZ<6waO(_hy;sy%WYdNjh`1nwe(W+Ok))W4n zLiN5Zk!tH8u#G~zf%g5%e<QuWCD<=1iNkJQM{?v++xS)Q3W79dh+84goY}%*4Y~gO zupW-c<jhO}iY|%_)+q$iKj{b^IdX(N_WL9y#jW4%0E>DEyb^TtW_qjFnfJ!GU`CVg zwVC}O1HjblhK4HiT5_-SSsQF`lu(8IP1?)Ks;X}sn6Hd>irbt&PsRn@<OQ)C;j;2u zqd(&e_ThQM|J;F~f<M4X-(8C<6omJ$2EqB+FOC=gqHRsh%>X8@uCBRf8@AEXLDGYk zO%0?#s=d&aC?~x)F??Mp(>PIRe;DR-!4%jtEiJ8IeEbelFNTkfP7*8cbC7cD4k~MF zYxrtZ{j0zA_nM!D@lEb{Gqd<E>W6W0EX1jg*(ZS)UiFlDU4*JaIzOmq`+XMo0kE$B zy1=>6xIr0cmxA;uNQWCpY*O_joT!(V#;WtJ-sqT_ZAR$>^HxFuLp39nWa1PyKPlT? zxF8DFaab92^Vox4eak0kjjF1uq*{i<xZmk35&z&pQcB9qXCI+AJB~xC#km%DA2$PZ z=>tHgqNc76W)!w9TY}MC%P^lN>h;F<3w26nW+?1vHNEuPSSOp&&OEXg4u445<j|RW zwa~Fwv}nw~prD{xYUj=%QusP}@Zdg}l`otJf}KRrt4OLGrJnK}k6?QpeqTPnuux#j zmMykDr3ZGK72krg9TeoB#Yf!w7u>%f_x`?gL^y|>X;#;lFZZXXr_;cao+F$=y=fCK zdM(7#6d;W^Wfm?jE<8L!A|j99E3C$2L#3mOxk4s4#s0#f*0r(OIWRa#PuBvM?)8Tc zQRshZxDMBEwHtXZm%FL_7gCX)oSbax{WVMHyZ7qyoa6<T-x6-0KKJ|F<CSy>(EEu; zx6h`Ti!^Cw$G)`U|8|-6CzAGb42?0-O$FKsg*3j|iw`h#;v2PsP0Pc>;~{+epIAL* zA@u9Rhg>4&rSk!7*D6Bq-)Dp3cX4G2ZR+-zH*z5if8B`xzybc|SL_a<G5T-0RUgWt zpDGo&m3`Z1*sC2b{xC+urNz&M=24z`7k>bp_nmN&i?j2$KSRuxYoNXVTg2!;GK^lA zRONSx3K8GGf4_U>hkzaPzpx5}g`c#tgDjS#zWYn`d7wWApd;Ma%Kmgnr&D9y`t?<f zjS#0x=Y-z(jmY{pGeaO{t5{umN$TD0d$q@J2PGwOlgS8X=Cpslq`6t=A1~p4zwiQ* z%=ho%c`ANz`TwVj`zQUut#>>;Yh_hcUA-p5DC=_8?0;t*lnv~R%a8uo%mGevl)Kag z9i3Z~EO|M9KIH@7Ub=K?X2&keOm5OX)zQ_ZL*YK{=tx6PPmkh}bn@jT6sjX&Ek@a9 z$FsEHLVyiI>ZJjxK7^wNyxv*nC7o?i5e{Bh>ZHkYIm_qG|KvaXYV@Hv1hi*nX7(^O zH4ymiRLzYoIqfuFt4sgJS$Y?&3xoe1OW{<w5=#16j=klRlasgX^cOzmEBnKVuW0o^ za0A)0Oe0dZDJUQ-DvGZ^LR>sDGHeygvurpclkl`iob2p?M@c$V_Me|`BrVNt+qT`h zcP|(~on!FbgX;walIZ((?5&lR1gU?3=m^)dA@G94)MnOwRDdcgD=Qw0)4M>&ry6~L zGXGm*GaK{g%tRu@J6=&y?UvK8r)FkeMJTKU;iyj8?z0>X@JN&~dW1T;dB=WQ!fEQ; z5kN5NdLiR+L^}kF)SV!Aku@GfpxE{2HfZ|+mK_}(aQfGNE^>^(&2?xrf%rh3@D=s} zL*a&nA}%hzXU`s>{oUu@Cxr29+^IyTf~V~*+@E{n4GfVM?$@6R9oS&^aWjQ5vQt}T zUhR*OG2%svs;k16^Xk>B&NojQLdmWqh3|<$m`$Uj_5hP__%9iHdU#Y;S0~q5!YPB5 z=H%+?5Buq_H{8?HvqxO~Ff0KkG4sv5yu7h-aU_l){NUss;@ifJ$QGbPwT~)<O2QB4 zu(G9v4rws>(PVpYc6PS)nSlBT@~{EueL#wpW1kHz902%0;oIX6JhAyps8&b+cS5B< zuE4QcDtQR*zl}w!36@3C6LcmsD+@h?0^yXUrQh$X^J;6Ar-$3gYy{X_Cl-W5;fh)6 z+>@tIskOA;emp3K=%D|<Iw#WOf-*AqQ9h3v8{dUNFx>V7$rRE>xp(g#r2A>p{_%fD zli-jP6$$<|Jb>U`0XG{P8o0siqty7ofrOqX%6dw$u(CGJc%nN)Xh{JK)H65d0I#@Z zA|k-X##T~j_^Q61o?w-`>{>8K<#%H<%P-T393cWNf2wYI-z9YZ>Gu|vaB<o|CDt4Q z*<xrE77}`0Q*&L)u}2dtc@}=k@}Id>q#<7T{E<3tVsh)jg9kbm0?~8?wk{o=+^RbX zZ%d{Cp+Qsb5IVR9IyzW%F@R}1#l<6`EZcx?gG4GKkfN+iz9p*nf3#?Ld6I$JwuQVB z^L`IVvk%6WX#^a|I6TG??{auh*3vm$dA4MANKWQ?ZvSZ;?9cXaEXbRzP(-CP<0RID zAs|^5c;iN$T^RVPNo{@on-~D0jfrdreOJ6)$38RSz2^}-h>VWD4ye}lne*SXATn%- zL|PT#(_JwOk_Xw@8<zy1f!S;<8mUHn4X~7W6|J5^8U@7btRTbeZ0L1|`L-ni1t9ZB z_WG7WhZ7`AKsC!Mu(+vw4YcP?3=1>!Yp7f?r>m~5?|goq9@(C?*x#h$heal-4-k?l zWN>JniqK%g!^2GwWH=$e7HBIRa<CSF2k{kxq9n)M<Rk=4R@e!EGfE8lPc$hA6xgzs zPQCQ!rpK+K3}>8gL!}@dq7iqLgQAe}7&|+=66kR5MB3~gwG^ZmO2mZ_Em>Q6;$==m zdm_M563N`aA_MY~7kKSJw~dW0gk|qJ(itJ`6m(hh{fU0}d}j>@2jCFgN=OKYm_)TY zmG1p;5Gb(u!v{qW%$C$+ob!u|JpBCYAuK(e>DU1GiXEvD+s}m#n+RxZ2qLP4xnZqH zAs2}3L!+|TfddO+h2c87>GJ$`LKz|0i39;4GSK+8sR>Ld46K0li{VNV{`I!-`*-i| z$h>1MM8K5vcu=nhzsX6b5}$r_3o_)O`QRWUj>C<RkT-0OUU~}?DZhFTxBtV}sNg)t z6L|`LgiZTXMzjroKqG0^yW(|EzkLrkY=y~##1$ErKoHK&wiU5lcu*YBvi3u$kW)30 z{_*1n;di3wf}so<gCT=Zo!KZa&8@9UXU-&>EkJW7h_cHwm)}I@FYbY4OUBNSb_FU$ zpT9Ht`22sSFy%2D7=<|bf<r?y3&P9F<iJ7D+Nq!ddH;SZ4aj)8KaV6%=uRq7*8E<) zI7sF;fY6Xp8Te8Acb%gy;NU@;G_vE2x%=wrct0Tiy05->k5Etvvm1`UhJ09DY%*UC zhGEl@$wF%Gb9|O?pyAR`Zr^^F)e=ph9+?_icJ|$K24g6h4^vVCAZ&H8D%kA@&XSdr zBNcoy8-VB^Z8%O=A9i=_zVlICJ}HLA<F@xgwC?SrAW9baq8kWVi-HjVSo9pE<TfEE zfLh0cC@H8<z}>ssvFy2LUQxqrBSDp#n%W^CF8}r;*ez_xrAZFAJlYVx<G>m?Xwzd~ zwr|=lS_>UV7d{1Q5$WjQgawd+jZbY24IAO&)gsE(oOMFlzPFqmJ$L8s-LD|E<k@`` zh1&42<1sa%oglmM>w=FrIu9hopzv@?BL1KowX#2~Sww41(~c>t9X)y&aj;*%e_sT` zCHx?u0i_@Yy%q@)@&<PA-U8@f55b~ubkxjl2jZXC;q;UC9dxSr{TJ835d!lH$mMy> zT8<$3p%W+AE?&IoEL;#%!~pwn6G{dd8i)56SY55yRq9C(v4`mg?u-HWlOV812tU9% zupF*^`wY~YkTl69@8U!udD&#Nprqsg<TSMSz`mNmwFH@Sxpj;7`;Q;w`YQWFSSXz? z`<pa}0|s0ow3Hf%4X)dy{~}YqG%HKzDVj-Adxo)oj(M4yP)ro;4TR2a0k(L0dbXfR zW)zfMSw4uTdDFDe{wSHJI(6z0=<8!rOT+JESuVpvTzAOh_=ywIj~+cT`vg|vpCu?{ z0VCSEcP*EOhDK5^bf`$YC(>0qh_IdSs}6AcoIUVg@x8?aUk6dj*my$sZk8O%t|~;Q zETi$UF|Es&FGJ}P{ETca6b{mNC~+D5fV&>}5sg)#qhn-ZBHa*eG|{#^OVxvJ!wgv_ zdDliqM@c&Y&+%puawJ-3&!0aE*Qc$_%l+WRZ|msfdd>Ow?~er+CG7?zB+rB386aM- zEY?G9)l=%({$l~_lhNLvrNeADO}Y?M8wB$&>wA{uI=fhOINem{fna#5EloFg>p&S3 z3(JBLhri8Em;t#SQ)f!vl;^<E-vTJTADySbvhfmnm?ZTeGD75t!hafGkmN#gqMGux z;oN{%BzXEp2iVjj2Ndf}lv1Az5nvT^(qQp@{j=r)(b4q1s`bqDlZ}Y+{`XT4aDDlm zSC%}H1H!n&u7eCl8&D%l-*>Y;U2>&L_>IJt!vAJu^mxS#PP%a@+Jr(U4MXzv<o~Oc zLB8bHpm#T9BWLG&6W+=>3>y4LHuUcZ$G^^P*y$h(c<S`&t1yMijQ+q{-pnGg?!}82 zz=2nbill*)dYo_LHce_?HL!c3&+@F>u%QMXfPjDi*>FJGzmANAAQG8rR+4XeA5a)N z`9tg<62dC;90q*M^P0P0R&j;ht|Qa4FIIWl^v|7?$B!$kswjZ0$jEeE1ZM<_2U^xZ z%%3%Wh)7t%Gbdx)va+(~88o=u(UYX7EF>;YS6Em`#+6{Lk{L!Q$o;SYuR}SKUz$|f z0hKgc3xdZ%_wi8JbA1^(<?s~OK%1F@DB6!46J&W6?CLB_R%T`{G|5d&A|3-CHPzJs zPT_~IQy%7ttVH_pSfV_F*1OG1#0b!)e+B)+oCwU#QBJtj+ujC-LGWS?A!=Sq1@X1d zWT5e6#g%0;MxC^T!pwZobthQj#h)Mehfsm*fnUkQHQCPK7-ZdzjgE?Xn4P`Su?Ual zU(kH7X(GAWKL3B>c_gCnKL7)iV|cf~J{UD1-H_>@tpIBJslOlo15zJsx5CA-uF)Ph zkwil#EnuYEV3<r-zv%V;y@lY~yO(~$)*XH@j{$b|?0g`sDJWF1Mxdh6;9>9gniUD6 zBEBL-J5l~;D}XPlZ?61KT>T1*mdu+$_SH2qx`EZZ9`rYl&dPc%=#VlL%F3z!dT|J3 zq~Z=>S_O@goM50>OF5ZhL>_6<wSPM^@{w#&B#bjOEciV2_3NqAZkfL%tr{7ikygRS zMlH>e1k$%8jelb%Mn-<`3qvp;TMF!q@tFEsk0~4hH%^fC)U)$d_K(|ZeP(HX%E{UJ z8bYNQx>*mFWmfLZ0=521)_xXjhZ~{)HvlmX<}UI2Bu9Hk2PFa9r{l9R@GT(6X$Obh z#>g&iCE7VCVXW5OrU2l$2S~Aoh>DJeUao7&PKx|-aTEmVEFa%x(6DO$_K!))dOqqM z21eUyIAjR|l3QcU{kXWpXncq|<+O{TPIcVE0MXO)hz+5ekvsj?ty>2R&i9tfkvtTq z7Ek_30&gZ8#3rH=hw&--QA#k<dfn8>9a%=6KO0bd5~V;vb3%UeU_p9Uya$3e1?C^# zBEgSKwH<r(OTw-_kR8Z?Ak7=a<A5mzm-+emcZ!NKl~4Se63eBaV6pR<wssv9)34vY z>7~vga2r~7?Eic4@ipLRJ2VE2dqf-)h)#kjgB(BM2NHiZ2r>C!0E$gBH>m(xg8ns+ zu%2jcZaxHC7NquHGNX@EQcfe3z`Wmy3nHV1$JQV!tnaOcvzUZpjMA(V!m@1z8$~SM zV?d&gIYSJn+jIutiG)g!qe;kt=Bosy9$`i*Dyqs@am&fMUf)eL(nKXr8y!NXP&2*Z zn;>284_t!}0))uDvV6H@(U3HQt2=~!R~7_UmM45IVcYCSo{b>q6HH!S+6}_zFE@^4 zKrp~#HS{DX3yNJZ`r%5kN>Y>FB~UrkeLG|ilK@|#msV;he6xo*2jZrRVI$a%R8aci z1DCZNuxd>CwesPqOL{iWy^)3Tw19iXGfFGS&;%Esd}be#bL5QR-)wH9*KP@kZAiI0 zPSYN<tR4)>Q{j$B=$7n}|K|1oU(F2K25<E%lY@Gp3Y6@4docm>d7saC&$j=Q4$A4f zBo4}i&@e*tJC`;xs{1P>eOs<d)WHN+X2PT(W}?XcNdI5*2>*JGdJ_#Njf|KOiO98W zf4ayKT($v9ruf;{wB)b_23Me$>=YK(cQwI1#(wY+6m}<@o6h<T8+Zi;Q#p9f1mB8^ zS_6vgaryE$h)AT_M_O#RZ!;VT6!>}o!Q@dN<B5g`|K`RU+ZyZW_*GU`UJicRhwiJW zs~eeIleQg7%}zvWA0EEW6{+@hVj=>V6<IT;;H_H@^*?YS7g^(a+2DnL81D(mH6DZ7 z@%tT4cN`-fT{sk=2uKwE+X6TI~il27l*u}o1(0e6J)t_B8fxF_uxj_X3M=rBUH zNP~fHg_?E$XN~8D({T-fXl@aa&1e&7jOz(l8<k(aumKOKX=v0SW_$YV*>wn=oc?_h zbQencS^@z)PEtNnfLBV3L<hLAjg3uZV<WY~>e61~D-`DcHn2P6^m*7AWbM*KPZ&CL z6+%s*TGffZD;tkYNH6ERn0<Nw1ET)FMtTLnlJGxNO9}!(sjHCCz`@CJO)!1!3tija zijx+7g*y7t_C|oyUJr5|EGHPB9tKF=NB}7}BMF1`Qg!|PLklybD@V{UFfWPufrFPu znSTxse}J{UOH3>RyGu=kDLO1{OU#`+A22zi#uG_P{F<8L=HbC`lb)d=Kk@zN&!br2 zBotU@CnqlCOA!$LcSgIS8Hg-Db_hbRkKrhh8CL{%b<h!JMnCBf&Apr`e}urL9`1W+ zeyU%x>=mUj56?B?br~F@jYM2*>@AFCqQtg$c6|C2hjKBpyKwu1{_V^5LI?xJ0e=iE zZl<A0g*Wg4@<lq5r3e8YC3ecn#s`_p*XKWbmJY;g;3i~!?pzcWi~`)dRQjF^9xbG- zwm+Cntz&)Ajh&*bjOrnP>L7&CnMRPgql69WA&J_dq4Oh$S#k**ho5+Uv0sIU2f^Jt z8skAhB%dJ26;=F%tmQ_6Ur>-<cShm)KcccCe0P+U(YLsW=~vq=Xz3z>Iw>AvWbLCo zZ?KWRv$1~i$0u5BrY~G~L54qJbE3C_UH9!^v8V!D@^HgR$lQoNQE%Kx*9d7!8+PV% znAZp2=N*4`u7QlR0>f>Kl1ct}-(>~>0nd8oY>}yh@MWYAppjpNh^5m3#boH`&pyPh zg2KX%AYX_u?!f1gmoNKCJ04_5+-K2ME#-r)4^+Li1T@3|2?qxU;t*`Huqm^bm$m@O zz%5lOu!Ox#5PxSxaIb>yOGs!HBM$E1SaA4&@5<7qh`YCM69jtab<Am1BlUtnPYp=F zj)4K6yY`5Z7I|m)?;(9c2S00m=uw1!KC~fj04u@?6zSmGynEyQe+E509+2fDv@F6_ zYuv!V_DTm?@6lyFCcjb;4|8*M#*1OcVJ0u~-aS)0g@T!79=svp_x<}>SZg0mQVYk7 z(64U*Fjf4D-EwlEh6(B*lJr8Mp`m2-_%i#mCoX1p6ScIUqz`;v)jv6Ca<cSYJXz3t zRK=D;R3*DA6EQ9X4Ts9N78A0DS>fQZrbQQ)?<jg}{|$EDpS5TQP&=eN@e12ES$pEB z)|jXH1uLrnd;*#EhsnDgy1x0sQfd0f<xj982#@k3>RLTBJN|Z#s!h=^K{{TamFW9} zqtb^qPCCd)00m>d<1~V*&c_%rA4o<t5uTx#tk5twESgU1s?RDdHQSkymUb({xJ1z) z?$o9K*{sc|lfSJsFrW(T({x{&#&>mD8h!#fL<<*i_(82s>w)Yy?<qa594+}P;XpkF zLZ+gjsmBn`)b|E@(p-cqfkDHJ-#hFuQboLOPmeE($+(uYcMwl0Z>~kdcpPz$>zE)S zC3=X4hhb%7Akzeukc*3p0G@Wj&=H~oNd4@=ej^<P<irR+Wb4-uusgV-8{mzG4h`85 zmFfDahm=W$<!7snyW8D=W&u(I7M1<UxKrhCjd0S<J$LSZOmXV!=x~Liav6yUYS0PM zA4IEwolGWIfhqyZ-3q)mjht{8G||`p9iYJWbs<$>`N$EnhGU3$4S^GSsv(M>i)Vge zp$b_GP%1LjOo}pt2hN>8zmY(gi=4~`lcuAmUrUftT&R>5cJCw~AA3iBnZR&nq3Uj+ z74<WDu~PP(hj4f?d7?^YbeftpOD+Si@S;_GXl{Op8qx|Kl$>b@3c9i|u)Rc34r!={ zmKNP?`?vQbs|y)pa<G;4al<}{;_$_&pU3)Edm!M#11SV+nhb`~is|g2pzn(q*5BvY zQ+iik`va|^kEzkIV-a25s}^4F97cu(@=i-3PWv|pvQVrQRAxBh#Ifd;_}<jE`1@@V ze@?ojX|nD3pm)FIoLkv|z0iU02Ip{5`}f#r@4CK|i&o;j)2Y=JuJ>Wehu715{o~2O zaWSW?<BIgdQoFH&j)Y8-pY9SB&Cb2xmUAa-$j&=;Ld(f%(jnu@eM!3~8G{oOIs5E8 zby{rpse?)02JMj;>lw4w)Men8mNsU=%ndd|^79MbrW+AvB*)NFpeHsq#t6rt0m(PN zH*-5=^oE+-KaGQJ3q#71wGMU~#`U)3M~*1Xg4*PrZxyHuXMaO~Og72uy9o=gYWTWl zhbCcL(Y0&WLTMvoo#je&id4Eq_AmNvKOx~R@jJS<M%?M^A-Ml(6MOt=@k5OmnL$w` zu^^M7i*BT*j@tM`k&4@&wxHIb;UsK9m|U3qSxefBup1Ye*V6y}@!WV}eLj9Bp(pr{ z_h~3x{`&*BAU^m1^oQ5%MT&F<<UoB;NJwj$ibk6~RNVac4`>yGgajK-vVSP`bb*R( zl~`&@GIpR1pFmtf^46&D*<16TJ*&Y$iCFo(VsBCqHOwzdYwOg%m)~|+Vo;mB*yOE| z-~YEi3~52q1qFJ91CJ28ac>{_Dz|I6R7d1ItB|EWaCthd^t}oGK8+`;YhxLU%q0;7 zt6JQdaW~2jcp4rw3j+-J1ajei+jd2D-Lx%2S`FU9HK2Pa6jsR2zsUb(9&>4V(M=_M z$5Di=#W9{<Umplb{iLU|@;cJU`~3MHD%>+nZh$EYi;%0yv7UUl0?bLkC#_9QyrPcc zfr0t6=*bumSO|9`b8>hVFhu)tsgPhEkP{BAF%fLiWOM|!#B2Rya<A~+3_^wixIS5G zz7qQOCl4R`;iq}{UXB;;6XCc_?4c@HOUS9obO`U-MGh(hC$?bu@li_9O?6&WOY!lM z-_39e-}wNh^Ly}pPOfIq(>>tb_$CckPI!2WTaQw4U*Mg%!`S`<nj*xpRv1^^;z-`W zHW)V*+qaK_EOx&z50UTiMG7OY1XPF=AV1iAAt-qgZo>xVUSpCcyI;n%E5l(r^r+>O zrR8;%M~5G^U`ozUJ>`SDO){wo^Kx@vh2#BGhJo9^n3n~&^#kdNbzJZ{5{BW*?L~OQ z+;f1Dax-%!u*n<ym|rzC3P|_AMM*!8$r9)jqG+d#ciNS4d>+A@A%`ZQE8s+2gYpSA z1Dq-txvXcnR_IGJ>`#f%urRzfy}Sln^kvj{Z38yMmI%zqTKqhSq=xH64?EmTR79li zOE0vIGa;i57&-qfL@f8&Gs~%Oudq*zO^oOn85lqv6tT3}OntaOJfj<!711*@YeFrA zEwmW}D6;rE4syB$alD^0qX#F@g5dm|Id|>`l6zuh)7y?8KklCO44RX-j}K}J2I=-9 zc`Fg(i2;hKU%#pw8-v|@JOgpB;i#+BZ~SS$CG1Lm=kX)X`nGj~r%LbXAtV!a!Ep(O zsVw2xBg-!?uG`SmWB~i(QR(W+pWx)3>gUcqS+f%)-iYCd?iI}Mtk(gcPqiD2F*esl z(ueVg?rli(R)|f%$Op!KRa2wniBA|eHEJc)L9tWby?yu22=l!unhCPU&v)h~t=Wn1 zg9xsusECS*F?<^-e;KkaLyUR~dd)7d-_&p8<Jm+bqK4#q!^IW$TeB0QI4-6UU4rot zc`BoB-+ui3e5(ot0~Yy+uDUN18b%Bthp@C`&)@6EtkN#<D)-&=ia~#Jbydcd3$REy z=-ZFzniM;6Yiny`ltKbAtOU;=EDv34*C16M1SrqpH7ZV&udaB(TJ6lY+Jqb%ue9`C z;B@DqW^Ul2S_mYs5yI!?U3)~AggBKa-`ENRUSO1`2|p`_wvSqd5YJ6`Xc$jZ0+=!E zlU336#7v6-;C$)y2aUEIi$v`DGZ;LMj&5ZiA?JGikO%#SolcH(;~fZmOF#g|dhyi| zH^alvK@iCNhxq>T&PMK9pB9%(yPoQ3v6Z}h)!S=9u55CP&26Luf2#1!j(2CUQBW`- z&vitXVIZrhM~{41IE`e;xe?|DBQDqqpanoaJRg$_R`3skuV26ZZFDpfV@7JwOLQ^v zGj3wk>O{lq?j98%pZRxm7k<PUB=QjfG69xIPp0D3!Wh@bWm%5>P7k|W8re$jOIQV; zxo{yH<CNy)+n^<7$f#zt3*nTIAF*bqP>lNV+*4QeFuuAo*!iObjxh}ze@TXtt*x`* z1!KmB?%mkkjn~$1VhB@tv|mO>81*16>JsM>*jOL<tq_VAnT!7wC4(J;Ar>n{0M!vq zi^0|$c~=sX_F(@-#f#3)AK2$+W(?t-lQlKSi!Z_|AZ=_P>lPF+K}=R4l=lmE_3tj1 z_YKrv{yc24aZT*~9F;18Q#;g|$BWUFQ|(U;!4Jm@T~O4kQ4d&vPjwcl+;N&2$)`|; zLJ)MYx}_x&v6@_@XUS+cNE<xXHg}VPV0dvj%ZGjnIc6DU2n!<<R}`MS6DgG-G=OtW zv0&%*4ukO0pCP^nUxl1j!{-v}gWtNdG^x191Nq#OL&;QZ)7B-LUl;9K{L9;4dA+y~ zaoV}BdOeExJGA>M@Y=>v`kmvNDSCN$CnDRtj66a|wX_BxK@H+7R-S+yB9b!vuEKeM zM1e1qMWm$eU<gU#{toN2XL0wj(vBQtb>-z%D$;89qgXp`ipDXg)T6`QXoF7nKx5tT zH#x&vv@1+fFD);7j${?>_x#02rk3Hh^(M7@AWMRQj9bXHOhS^UXJDuWh4=h3Rup&8 z%{H#~Ez)oxDNi)xs<8(Tz$~Jmpde?GmPRaA*Qgsi`A)Z}mM+hJvDwE8M-&q_XF;bl z;gm&1Mahs0zPv|=qoDV)Tj%RYUJ9JgkOW>jMnq}=v;7b+F#J=1asr^kfMqAY1EILM z*x-+30IlNCTLDiIVP*D@aH-%Lz`=M3k?hxvP3Z3ZXpP_K@a+dpD8tAuJ%ogh?`lx% z<=%*&3Pg3ai-VtJ<-c0{OV@{Uk?bUp`aBWDWWg7Pkl!q#u>(!}>D?ymVI;F|hK04e zGbcxJ_%2;6Yw{Hq75&j}Y+;4X<UQBzUW%4LBS#6e(S9yE^G=o$NR-j|k95VQ2Z){t z8)a73)!hIxib_bx{&GSKP-9H6;Q?&~7f>8IABxmQ+yNH>M5#nhzA)%LO<v;~;FBq; z`<M~}_br|MYzLwE7e=o2auPIOF)9Xq){K(j=D4^z=ersR9RSFQ2UB{a+l-lxK#qFS z<pWk#s>n`@9euD%d5mY1kUuSfMF;};xQB!F8+!-`e?})q0g3oo&fa7F;bEM^Zm%9# zb-m^i;QJBjRTDy65HFHOt9W}DUj_x6$g0wh0!=F)5@}%hy`qctb($u7`;yG{yN=I? zJDm}z8<N?~T`L#WAgM^jj^YGW>oClHNKXR@Vl}&~VNu5;fyja+AbuS1nB)R!A{!${ zSXBQ$oZ=0*aqbI%fAz2xSfuQkG0xgoHrMkAWbPkJv+n4)Kka~oq@)$b-o3FE$^C{D zNd)#j^+<Q|#p^hC!!$Zr=MwA##jbYp3umq@?Z+WOkGYY9{C0MRAm#(rF)nU`K{lAB zG~#-Aeq4Ag$=e_XsN(yYAT(P8GGS&U8v48Q`!Zz0pdn}`%CqCETJVh+d?(IRan~yG zkuTC~vz6rZo}@rdMmeMX1Hx`95gb}DJ>!0(i;-e2@CnMo-YZKUva+&gdCj=}J=FeQ zUNjzt3t~wKqP~M)OU}b09#2x#LqA`4@5bwP29x7E_$sVq@CSSckfue_Chl6^!`K3~ zKAwv|QxCY0??4U(ar_$yD15+IfdJz;%FK1Be*x$xYf2Cu?*+CgAW>b(zaJ`%yhMW6 z_yO_>nV2x+>xha+7EH64j_8uHLNs)A_c(ul|3HQ;KuuQiH3m1)^+{6)GRb^J42XVk zNXT(mLL@N8sb*kgl=I&iK$|=s?G9G+v<a%g9tnx3ZA|D7)JJqtE58D^)gnC{Sh$sj zTOHf{%ilMSLo@D?T4Rm52ly>`8asnYzzwSS2(Zv~sQD_gGtI~fVJ!NPa#B+bs{aOl za@iX(OmMg;mDFUhlSt49ndBS39t^@1F6$LyQtu<Fxs|*B{<iwg;A&v#0Mv7g3Sci# zZrZfTCy?KtHe$zd9bC>fuv#?kc!20h@@uTN-RzEJRE=#tyY-`DPWNwd{E8^KKWlv! z|L_iZ$)TLKzd96oSDu>N)(_#2ZMw`={*v_5?7{OII1nA$X2KJcOv#r%@$vp=!t`G$ z)c^K3qb`E}X>?G!N*FF~+{?DtCy-|)`E6@d^c~(mT^n^@+DDN~ZoAoq&4tz7K67GE zt%byev$yD@9+4z!P7OOnISk*~6MmR}t*6qFE!)a@<701%FK$($x)^cx9atJp3p)tV z|M&;8e7LErYf=kJ#ee-iCm5IKNLd(W-=OtofVVedXhqL`@!e>~1g+aPQT|-J718AD zk96bGhh(4Zz5Zh>&n}+yuKt<O#|onUX|YSku#WnLZ+q&h1~xQkHj12hNKnpo7&R9i z{%-Z%@VLG2-N;*2`KfnW`eQgm_E-45vpneX>rb@Vrk6(JQ`7#_f69&AdID*ae~^q& zH&t_MtY$^ra^sG@&&2zeLnd0?RR&bYs9iQ4n0}ii6h7{&y&?X|<KlG@@*J_IaT4E` zxxJYexOM9vHOgK1(mY$9t=~O|EAk}wV%q^$ueWQ9@&?}Seq8(5;PAcyjk1K`$f>ct zmgBBVR}ANTsJLx8;>gD_lb!IQF?-=<kPKU(lFNoJui}x$;9nv8pZ(q}*pc|~{NR(# z_oUT~FP&fIpB3%as18^svSatqg6*-(r5~>Qu~5YKc(eKy-7nu#shY=`BxP(Yl<?Xz za`a^W-OfpqHdaaV>!r;59BH2zJuy4r9gq{~lO^MRV{9`~x0|!RE}hL$ru^&Dn&4l- zo%<Z<rA50c2aj;>xF_?q<^5WX4H^$!pY`?1{|S2>#Ana;S;D4=t8{~x!X$b1f@J+H z_*~Fz=PfsFM_Ibpui?I+%R;kNx$lhE$%VKF)}8X!GM+4+`+l}5yUW^pG0XIHSA}Gl zKR*5P#%O#|^q8Zgs=h^y&1y@hWS-^wYB`aT7whzeTh;5ycQKNy2p+8P;gGhF7G1d% zsiiM{ak<Iu-1z;QFB4@}(pT&g3gcW968mdj<BNM_B1X){r`|7mtMvZ#Ip1Ev_)#%C zZ!w_VWBNBi?y>_VQ+)IvwQJiNZ@+Does->!wP*ii-P&$E{Mo4be8nKsvA{TmuRlgq zCO%%aw6#+IlH~An-;?O<($*pErUUY+n(Pi&?~J(={{9{>cya7UaHDd-`*oa6_DwsR zc9%|=FdR8Ol9}bo@g=Tf`NShB<JR$?m!_{|N$2(Dt;^X|J}4FPD<o)3#H+%j-9iP_ z(wx$Z744jU+Z;B&+&+Hp`Krz6$uaSwz1H&|`gZbDZ>W&<=p}bj_gQjZ+PzAQ5M1$= zeNcBv$fc_!%q6bEZnW`T)k}^`4@U2Q+Bbb6O{Syr5k<%&CIubYi`L)N!quO=e=cto z?(UVuR^dIpY5SEjzxT?CUbgyH$<-fPq6U=iv@Q>fyZV;M$O+8tEbIBSKR^1}@efuF z4l~<U)QVTx=oH&*$pU4Y^;r05<ygZP1(r79mmAbO-ii?U`uQ3A655Il{JyBHX2xgk zk&+bHEB>t1mhtk%nUGAc^Xz|?=ji7Rxymd?-s(@tri836Z<?@duN<zrwq3D}<(G*O zZi*#c{ZH!oi|6MI-Zy>T?03uWmQdKB(KR>WpGz+<tIXuu*}Geey}0By(B16LGTXPO z$)Ras?04_}rNo+8lY2x8Sx3Gx{oR5_0370J)`x~VbZ&1ODExJT_r$BuXCAtSvmSah z8@5MkuYmmtX0N;B{K5x9u8pn{UAY|T!#T0Gvhtzp^JBUf9OtynJ{O-Fv)AgJ-9zn6 z?ONaJ_&7Q-=Ge==G1vOwkl+?38%MkT#QG5G;Q5(W3*B_X`Lf}9nbh8@mhQ-m)a-9v zbu9E6^s^#eHCL@RyjE-CQrMfA)~`Dn|MGYFgc6nR%cIUX=LMOpCVhLW0&5kveVQDm z{LtTe^ybmNt^^mtd+!q4)}=oLohlCzbbwt+_X?e@i{!HPjH)iftWRk~$?hK#FI((8 z%1XCRB=r!nrgyVN!erR$Z_Wt5R(qYchl96(PHFoVelgyNndpzvk+Fx*=?R?Z=~R5v zvwMm|@AD-UMM~W&U54)rv~&zf8NR9gf8@LCrzGne-Zu#<?B!&z=_xxPR1i$@Y{SFd z&G}wc7k(7odmk_0GC%w?XL83^&wuR3%?v-^VN3kG1~r~;e)Qr-ue+oC9w+x4@jT+O z<yUoH0B@hdjn=V+3(WUfo=sV-eo=V$sWtAn>NyIhd4<4@OG3B6a~<?3#h61w?rtJV z&X;)0%$|sP6wOk8cK?{_^Bh-AYxl%~kH@a?@8a1QvdHARqdjuv*`noRDINhn%2mOo zH}Q_WZ3))KvM0u;KGj>hI4>V{{@_ftC`zTotK=;(-#ig^<%Mp^SGTGi^K%pu+azqh zw)h?XP1!d-xKcSshn`hH|FJPGk+$HC0J(!CtCt1blNZ&T1(ma&ALSsWROoix<N^5m zhrjZp0T<bP!mh10c;!mdcQjgBar<8(A1p1Sll^#*?^EAbf<OpcxWFdK?l(+JzV(0n z!zW0Py1X7<UM{=7Z96A*ZgK08r6c!K`2}~Y&X&-V{hi#_k~d1i4ur`_b+|Ks6JwE< zc)hWKloml$NvNXY<nCVo@aEOhq-4sCy>!}5walafTKxZ%_LWgluF?J|CWstGk>)5V zNREKCB1lRjND4!zG?IFhR6s<!6zLRUq!~b9M0x<Jp*x1|ynBxST=#ysYu&Z@zyNF3 z@V?Lc?7e^W$o@C+&HoMt`ak}g<?jE~?>ySSd>^U?r;HjA%vfc!NU5G{z<+?eb7UK$ zt)u|6gqNVd1dX$@y&?CDy%%ZenGq>5D)54cdY-x>Wkc^9|2KAk4xE*c*>#<rUzhku z$w1efrO5%)do*QqR<Cs)S3VyCK}eVc76BxNMJN>44rCr?c%tP{?_RBUtOUT!R|ivK zF#Ee__3;-8_khJ)_MQz}K{Y<+dlo$~Uyw`&-j6Ww8VsitITkgrHBc}zsw}i=l8}-( z<l5Mqg*82SogH<X19AP4HB(QtwI(YEd@0>|tPmcTdrCDSH#?K#fLGNnqp7pZ_Et<n zveyu59lJr)Nojezm6KVLGi9RQWW9L3YsTs}_Z?Oq@$h<_6s+N&$}Jf>dioimo?8pX zHV%q_3tQo`_>{wxfg$({R3hNK0aa3cW1~L?04cROQ@allqOeL+DLJ^gfsPLVrU+sK z%7M~T>r#_`Bzx6aAYik{Ww_iLAs`q&@NE3qt7&Akj!Vg>#m<7*p?IV{GAu6t>3qs> z^Voq{W7R@)w)=Ze_ogzYKO{seD(hZ`=hJkwl@<2Ro?Xp?MnmLD_K_*G`TMB&^jwQP z!3@Xlrn2&iu2vK^h)^rYVWa_ge#=8!OBR|%_+aM%JiZAZ479}00hj=5R!8~U*)s2W z{<C{$iDI9|tD)t6@@VyteQjYg$OL3x!(|%_n>@ziriOay4tF(_(j6t<BHp_15qAEw zl-I9C#J!h?{Y(gH|G|mNe=64Wmeeh|fp{rh6B<>K{k|+KrYf;&%i$aW0BeECBLRlG z$J*6(R6PnH83JT~^P0>!a3`QWj)&3AnPci2I^`${mx#s0ZIj_0ZO4PY6fz}8iaA=( zzcHW?ZMAFLqI=PnuAckV#v~AapkG-&^2G3?ku)^1@>k@Uk0a!k(siWV-+b7#x;l7^ zi(vafJ^!MJ;U++Rgv1V*C1{dX|J^I3=H%Vn1VOC~j<YM?{IM`r!J6jf7fdx?3=sRh z%op&E;h)Gr3T3Xu1>6Pw$DjDs#(S_AGozI~$hUvf^Kf&p3UkE0k-Qotd81<<kvZ_) znO2xum@507<#2|;u!#E);1CR}J%N(T!&I^>{(BE5Zo<eq4oZSE=gv8;c0Q0&4phzK zYAR1haMSD0of!Jjpd8*f+sqD8G6e;;sG4Od?hlF&UuLI&T21W}xj5bzOcrkD*YEqJ zz))W8!IgqGgZb`aa)K}!@DOkf-ghWcBy5CInqOjLsX(~V);=sM?6iA9#$V>H<p`0s zk#@4r{8OCw@YgJd&nvt#EI|3HqM!OK2<55-T8I#(hr1RgS1C*t$(??E`f0Vf09?lW zp%U}CvCkk)eFN7}t#IVWkgm?3B^3gRV5=}zeY5G{Za?v5Kqw+~x2>Az%)U78IAgF~ z>Z3P9I8x!tEzgEQvq<D$?k}D4ZU*ZRv%7uZ@Dw7Ew&)iTE~}~pWHwSoBDko?5!J*D z6VOfTGmz!NEu&xG+N1;&654X3WGZd?r-XZy%VZPTciVybUjm%M?lW|RrLuxoUOdjX z8mLScGxw2BZ%BK79J7%)<QkTx0l81QyyiVrgxT2J+dBt2TK)LnhKlh11*28U(6ek2 z#=EA_OD0k#%;lA&`A=G4q3D!bvz#ZVYv{p#{QhGIYo)|S<NiLyOzp{jsEd^Eg`0Q( z{`jWlVu@w%KfydorjUUPsxGZwvwvrfOX~q4@v<YTjuwEZ5)dWt<rCpG$F-8>zW6Yt zD0V;iH&wP-Q)E^@H0>}p#IM?ov&)cBuql}W;#*cRQe)5}{y|8Su>D5?OWeek;$7c& zvKJ2#t0IzpaW^unf(#}(XkD*_2Q|^tbeBCuLKSaqCSw~oY%{Mpp0NS)sSdX@g9YKq zfxX_JyLDPOKl<c&2VEt!A|A4Mz5B>$cr9*>$yvIQSR)~KeocYgn{Cg@ZRhFf6MDHJ zH@mpQbyI>xq`LY@ymW8%_cWm#qf{ZUb_8D)C*drDZ$eEby?3A6@syNbl8(x;&<uC` zG02B_&Wc3SDb}_V#S1tDfRhk(`!Ed(G_n(lxHY`0+8OZzTSJUz`&O)vt>D8E##;`- zfA#*Vt$nGC6yclgp{r0@s9!3z=-vsgft(?&3Nk_s56_#*GIitWZ}Z|BVcO_u<**TA zVf9au*bRQcupw8SteY(&R5)S^15B$OU(6=$ycXr#G6?3_V>>#(IUCs_VLW&K;R~y7 z#U6(zMx(~TvO$CTZME*_`SCGU`tQnvGGo}l>8O{!pa2h%hw0hYOMkB}-iMAnw`AC^ zxYY6a-UI$fjuc+|l;Wh?!qd$P?KxPThU&LLL7xl)-Sk%*13_JK!;x@CK$+*Od9*Ud zAtc3cg1s>EeL{50;qQ%slg8uo)|EMfU8S<0HKrz}>uCc=K1Db%5r{AV89DNpptG2W z5OD3&^i-aII*nKUGYT)4E3a5p=ZaA}I)DgnZE-qqP`+(*G-Glp8y!<OS`_(-Xs2w& z?$5w2{#;a`?F;s{x=oMR$?yiDM}8Ab(GO6RK}QU1y=!uaQlY|VH-YVVuL7jKo_LX% z!ezR91UV%95gUl{cQir!&u`nn+gZ!0XH?hot0X=(FL7PuBD6|XerrDa?Q?qbZvSf_ zKX0GO>e(YA^N{lL=OO1|s*@!T@N#)$HcUCM0Z8HgUyaMeFH6eqx>c3Fh5`B7H03z1 zDeekmcx_`#y80H`Leyo0kCuwN^RH9xecz{oewgq(oA)sVp{w-chuZ@V%reZzL!Hrt zPEx#IPuq8^N6W2kR0cP2k1#Ng{5VQp=^kVJ!7k~uOM&*;MhgoThqq<Cl6@`O#E;(c zhDOw7){koK=8W4+;-E)JsD{vK-kDLP<+cYx@bOSXD5=oui>~v5GnZj(t;K%cMz7oj z$r)hk1kbMJT>|w8!oF@`-AIgZ%PT7#zz)Bd?4*s=`Tb6YVy9bvH<Qc3{w51+I!S7F z90N+ZYc)K8!kslto=0V3F5=5{GT}a_J|Z1rXbN+8U!BOgVbx!7Q*;(@dN4H9)zjDM z>*4jJ`YVZsqJ}wR!s7=|P8pFMh2%Tfn>7_8IJ8cpUmG!`wUlvhdZXAz!w#Zf#+@pm z?mq|kv$C(>he%o#en-5tQohoFm=D5+HE%qW*kNn}U;kf11PAA9c4lhY<ik}kE7v9I z^h8qCbC+pa7S9{b9%!Rye~oiiIgXLF;uZYnU1^4bH_(X~uOK0OVCn3JZ%Vhjr;+ZK zLnG?FO`fl@00V(#8i{8GuP5X!f^d@q0(hu^LZ=^{g-op$Y<LXT*;<8en11Wp+OX(F znLU}rffoT3iz=NZ&Kl?1Xwx_=HO{j>dqk8elyYtipW#5fS{FrL<}#*Uj+bV5Yr68G zx*-6Q`a5flW~%Yii`Tp;{^^dNlEOvDXEFs-Ci0mau523oh0$ijsG9v;P5)sfTEg{w z=d!kwrjr$Ig7Vt_tG<Et8A=mn3_Oy0GmFnN!{qyBD@L{jykH3ja6EkEE%Hytfp0s2 z)$>C;+g;kgNxaD_DmknBy<?y~(mA;SmB7hC5oJHw51k^>$E#-x9~kP0=%_;##U0_w zshx|lTMlap6M@dO7OnVJE5uha;oHK{xn)S})i3*3QsX6QytKXGSJX8w_Y{Kb>v+gd zul{Ide7@oOWyhwP55=F3@5H*ll?c*EP<C9Nb$)kXO~*aLoz;^=f-G|SX0jB6%!aM@ zJ=e{O@9X^QKb3x^{Xo!nQd&cI@c#iDC$CKMn@LC&(H$T@%QLKw2NBNX#6&%4oiCD; z_a&8rpAD<tJ-6mW?&F`c$XxOwhm4emD{XY~=w8LT9}~jDE!p@W5id<2&at6T_7!hz z>uE=!!s8j=sC}b*A^3@{pO>id&<`rSq;5<V7l1}5ntt5$Wt#S)G2{j_Lq((51JuZ! zif=*VjAXMewN^C@#{w*aR|QpuT0a+(M<gY-L1Z2DQ|9*l`hdJ#jJ<L{7~)8^c=B$+ z2t9x?M=bulgPp+k@6S9T5>y_}N?>w_`jnh_#N1@w^zOt{Y}q$Gcu7)}6|gmrWpqcE znRkqW4}HRcU}kr$auxM1YYMZs6mj^u#KU9e2czfs;IW`I)CtlcW&5q9^AI)+L&;Uo z^nz;pb&*5EHDuSc3_SAB`VI|twtNamLI;IXpT?Nm0(FaX0vUr;k51o@f=C}kLcj=_ zD~877?lZ?8li|_POWqXhM~xm+XxUw#z7?uCDy@oRE)I>TWoM)Y@{>#2RFglgDVs%c zTFZx_1?Izu`-giT6CIdtE879n_VTtPl?HOd8?7sqeiqwB17=~`*GON6z9qva+sm$2 zJWKZ2xCqVf#fuj{ch6yWVZOOT&-GNoRCw5ES$QX>vK#sB_-cG0D4{OA1SjBXo6smh zJqH;#1j#dKB0qh$czAb<@sMxsXy1$N)F*uBcLD-AX%j}=Y30HOKqmrrMS~<g`q<17 zACf-%^cCi<xUq-*-@gut@Rok;14h&~2^H0j6z#6?vmt_>G%T$}{&2mE2S7FR!H({J zVRyDyMrR4PTSwBI>}B759>9yCK-TBH(u%u$<MP<@Y<uG<_i0|A6&FGU2Ykj7SHl-N zC}2`o4*BPM6-8M`x1_$m>HKOij~+m~D{)NrWN0)b2b<xvCtbc2mx{;~;$M(?^<hiJ zFByp>5)j9+nDZ}=D`%+>ru!=mE7{RmO|BvFJGSi+cCx>?A_<Tk(royS!Ks)er`dc3 z*!BCx>=1GCaRfjx;8DQgara78fuHuTlZ6_;aUVd1hTRkZdLp{(rWJE7tuZ~~`R!ML zUATDFBrJQ#6ydNo);v<B0Zwq6sdz1jjECxDzqy7K95(jyd|OU;UD_EfJdio+5mlL= zVLa{zwF=Ojn%9R7+MaWEy@gN;AY3sJi2!iFy?$98GM~|FZcX!h<Z4GsvDbVpE<dRZ z;m9n@(ruxe!jGw}?hG}O*!L$z8`fH+hI8*}WuNp>SM>66aC7*)tsfTAe`#;pTG#fu z6~(a-t2w2%cx|Apf7Jq;G9CRd%vIEyr)act?do6u$fgX<zPUbi?dwvu*<I_=pco;v zlK2l#>9ew06~1P;cpXMSVv-BDtMYMjTKl7xy844YD5GRH3(4lTT%o<SBu2*#$8Ni1 zJ+(WfWgg{lFO{LwC=*`}cwPB0?(FFT1A`Yrn+9QpBJHpI7{^LG{C?nmCnle0`zC<E zb`tWkvc4VUDnopLH?YT1B7G1joBu=+d{>~gV*AYdfG3##J~j$lO0L->ziV;Y7fm1Q z_dSwEyCQr<Qug5gLYp|x>2kfm+>!{<zWgktlaN5ZhUV}(|3;_I$CC{L*^%00-BWV~ z_J%ihq(4S_8Aj!6s1j%>T*X5A5k-W5{iDt8cZc50TbE7*{dKbSkB%L-GSjkLlHaQz zqRV9!<mYE$e@Yy>hcvOOPxkj>=jO<m%nHkD>uE>{pFJGe*gQlhQ}rPJcClgivDmD} zOYSdyw6&!jc(UM&lF=QW<?-G*&FFp-3-BKTminboGR}8qbE%&z_Nz0tO&Wh*&x<Pw zh^g_DcdyF&6jaMY{9>YwZPlwcoV&wq{H?Fi^R1p<QC4?wazL#6H}#!Q4q&r(f4mIZ zCg9o|Kx7VKW6@x&?M#&+C0Mss_w)L0b8|GQn(h9@#O;bsdXqB;$vA1VPd@CqZ@pVE z27k6XUbAOBM^1)5vNGE$DRsdOzbP>2S;|$aL<u8?^&M1sJivNi*hvl~Mld)^=eS`@ z!9_#Ez#UbGJ4p)K+5YwySpZ2zh;}^Rn$jZKAd#<1l(Y3%GFY6=m|gH)lRhK!=_C8K z8`mjZt2T9}*5uy33#H=qA{so+Re58{+&6cx)rvo`F!`9I<5aSaz}I?<f5?OVn7@tp zlBHoXBd<o*my6F5?V9fj0ZjOcWCg`r_&y8iXRu?*932)dRypz1q@(HTswWXkBMVf) z%BFR91|KoY&YV+}+mv_lxDus-8kHSK?>5JE#0EgA=g-EwI~+e7&7*1UFLSwU2H*|h z+#DG8!C6z}GOrHV4X0|s&B5NvGu0Y~@C+^j=DR|<J|Fg|VHzKf-_a8LRVa_~75dm} z#hnjPi82q|PTlaU{#g^gb82oT`N(IjL2}5^YVsdcu>cf6_MdyB$1mrFu+1I6GKW{) zh%7f0MZw<4QsI0&LLG8BjCER<#2^{3ZXdX~G7FKKF$btQ0n`nEbYMMXv|hj^9Tsb( z@v9a2u6u@%Dh{1^WzN-pBPPH*DRC-2YwT|AT$R+TNd*R)sttuH#~}*&^($JEBf>|Q z!<NJJ#a&VLyEzZtoCI%d8$9dpG@g!b`AKLn7ZKIu0F0eRlQ09c#hMh)>rwYCQTJX{ zw94X-qFxM8U6_}p=Q}Mt8GSvD&MW7M)^*A}blh;QL>^7Qj-hyQ=jux`4Z-)mOi9I+ z?N_~6DPOjA3xaQ2{LpagM?Wr>_(bA9fIwtoG`v7b#fy(zVoyr61KtMeR{M!J12jiv zuI@~W=9I(9D~~V{^qf^4Dn}B~vtjoTv?r*D&0Uuek`PseYsz+FjoG1@bNja1O?POW z`*e;ApusJ*+dIX(^xD{z#bWJ2COPk2{sve)5)?kmE3}#qhdrmPt*n|s!A}LsPsjpx z$1S!4BnJkp^_CAtme6~_UO+A|qL=jM3uicC!Cgugik(QE;7@u}gV@IcTSLT`iDdu9 zgLQrBhDIj<AJNU?!b-_nfq$u#uPB5J6Qz}1*wPf+_x#I`yGBWrgW@_M{ATzDR9;F| zazsjK0}QQP4z{1oR-!$~*B<G8V%e9zt2#(+EtE$Od&#Zv=wsT7t1kXccv|9g`T|z^ z_*L04Ml%up>^}A2dsk20H#ada9}2=P#IiU3vZIgm+qcNf0<w#+?2kqF(Pyd{YGeJv zyIezjy?0~@wR8Dw<tyx!W<UI{c6wp;O1F>Yl47aquMVt3=G-i~U(?{Pcu<Sf;GBr3 zSF)=BWNrR`LDuwk9X{)`9mlf+2P0DgfAH3H!K3*8VheJRx0!>y^c^TvL8kUuJ)5K8 z0%#Dh-?S8UHy!HA3Nc#FX{DUExs9O@hti+HUU&iS@V)QPnGZ3~E5t|1kO-vUvCWrd zZwnO*bNaZmwc{srHTlHOHcTtH68#$b1Fq(-=1WHWbWy<}Q62erN?~1ftS_>mKU|A= zBjZCV61E_B^7M#Loi=Lz(u4V-tL@8TEikrJAekg+9(a0-V4g7kXle{N<v{+4xAZ-u z;mIqEkw@YjMVCG~`tnEnPMnoXCV%%ud*RKko1lGN_1aoq*)qVrC@Ro6vkIkIO;c6V zJf%`EDHSSvscVS6-7EDj6fjEn%8!|at%T3`+(=uzw&nH3sGL4)!NslbDWOrkf4?>< zL(!H1T&gk2Icd9IOLr;ZS+``KL{s~X;(MB=xFH$=r5hR-H{jEI0vcMXdzOFuWb7D^ zc@gK{6H$9gKFF7y-&Y{l5OJY~c85Na?Xfv1w%kSRBE_OX{v$F0bC$Qzu_z4HYBoKs zB4Uc8H^p5bUXxt&1o9hAdw*#uCEksIix|Mg5D=m3t0i%#RD_jAwC$lv!R8D6uM0zz zO*2*r)O@yQjJ($x4LYJybO2<11jy+0a^aTB$m{C3uiJHxxO!;>U=eRW##8SN$Soxd zN~(H==iD&#I0Z`mWWTi+6CDj3xSUyzYF$knqmP@CwP&WB-X}9mr6^$<2kqM!Aa!+} ztIM1fEYK1MSx@!juAFF|1Ulsd7PVnK6-Yj<>pBeKM;A6OO~$EptjZMfP*r%a)62Sh z&u!!~T;E@c?U_<mgYMfmc8%DI&kBwTivpvMc1|)#i9om@41T!w=CMdPeCe%&;X%M; zZWzL4O*P)dHg%<QfsXK@OfuOwI+T13HxX<?Noh8v1$39h<%-Qq3xm)U1a=3A7-GoY zsySR&1aFR|ZC9+{&WR8$s{^}xvC&NiO?yx71Bn65hcLw;(h%h24y`by%Tn@H(f5C_ z>Gz-ue08390Mvfev-~=PcDFe(`8{?XTn(?~LLX0K+<i@r6a488W~dy{TY}ohW%Yob zEZcCrwDrFQ!VZv<Hy=+PSmBC_K+o^jTo&;_Nlqz$kYw5zXcJ>FM|dC3W9TG36Eo=J z*LTw}Ycxy#gZlX^tI}MbKeEH5JJnD@0i*G`%yY_B5|gfmzI$e1g=9#x`j@&wcpvZ0 zLKeWH=q0r<2&bA8eM7?ui4GkSC+|REW1PjG);1>S!q80(tbKL0s$q|9vs!cF<$I6k zW>nQD)aN?0i4hrX1nX+l$n#2qI1R8pat;<2e^A*JnGe%QsRWwLngsT#^5{wq(DW4) zn2i>5FbEUg<zSC)b|;Z--{me@BJC<}ch+Ov{|4mAXlWTK|3Ml#2q#n!002D3PJeHb zgz`IO$x`1{sQx8O!&gy{7>0klLM?Ad3>$}@O8;>BR`8YJ{{8`8%dx+k!f91TYkW9y zxyz@32qb{nF~Fq|!0ZC?%6kB2hop{8%>R>+LR(;<Z#C0>iGq~EC-8R8eV_qi$c<Ph zo}Y=3z16JHmKtnB5pap79!?=!18-0crr`P?$AJeGNZxlL9TjXGQ)8cBOUp<bo7zfu zZ$Ea#FDn35Z3#^z<rbqQf3?R2Xm^57#FK4|`+_7G9&fH$e(Q$QJBsTH0~xD5w<m(x zk_iV;?q5*(_g|M{1bmM0wxISp!*G#V<Q9#L+E@1?OnMS2H(uYer{D_NkRZq(G)KoJ zzJ-v!l`s2PyS2KgPhP3)?I9+_J^D#U@122<sJD;zd~fj$5Zl#vcSm||ZAzfk|6E*F zIE-@&G^1>g@bSL$FJ=G4iC^iQM6r4alRfnpG0|bL9jCpLC1$WWqN4E%P5x3Ks!+m0 z7-x26Zw1Ft$R9FAOtm!Qb|=sI@A=2tw63jhr)mT$|8H4Vj#h5`u7b$Fq-jw60=S02 zogM&^TxSSa^F^<U#_$-h3bEZF(zDQ8O6W&+H=L_%a_bkkee~7AHaw$-+4n><R!<J@ z22eu_$4a5{EO=d-X1-?2w<T0G)Yt~pMZ;vn68l~n5EMcb)I*T8+SF(1oBg@lJ**+A zglq}Ob@&N_Gsvl7<rn$zGfQrw0P~p(d-_=p9|7cuR*tr$6CgB`*t)B^n7pqpB@H>R zuG4stHDxq;)_ggyt*@yBtXW)eoGG*E`?$@%6!?zS{6o^m$Ah7F`Hx#WdmU}Zg5W3; z`vQ9i+QdRb4MIK;m)_4W=;e$j>}^0Elfa+?eo(NigZ~Ob3sm&==`IFe)DN$0Pm%Zg zkoZwQBdjQxk4BFSu+iA33C1SKf8tQoGv8-`#rw>!W^8Km1_;VWO^>qLdb0$qp*42l z^a<^Gl%>>Ca7HU3mrpZlc$rB^ytH*xF+_p==WU`-?C7A>!&?CD0H$-hl`HM<N+P?@ z(TA<xAd2|;xP?WCE2gSM%t=F0vO~V*rckbJ<qYM_y~=x&Q*+WxF^|9<0%7EYG%80| z*T&x7>j*?K$6kEj{Xb86_y<t>fm#>bme8U4L$(w@BT%_GrD}NvYpbVVx&c1WG{Zt- zQ@bn9sui+G>gutlL(9*>0V7Lxc;Imx+uJY03y`_G`nkKfKvR7dQgZ`oEXWA3CR{a+ zOmMNlF#@3MzRk`~h-oLJnL?sfOJYJq!~-zK$00!m3r@}XV|x$@LP`#iHHrp&%K#Uu z=Js0N<+oUs_`}m(Pz$upx!xiH8v#^?=|77Ee)xaBIh1t5B<y^MD;0nvdx_*_l%)%# Hp8fM5b4R8? literal 0 HcmV?d00001 diff --git a/Objects/object_layout_full_312.gv b/Objects/object_layout_full_312.gv new file mode 100644 index 00000000..522fa32b --- /dev/null +++ b/Objects/object_layout_full_312.gv @@ -0,0 +1,25 @@ +digraph ideal { + + rankdir = "LR" + + + object [ + shape = none + label = <<table border="0" cellspacing="0"> + <tr><td><b>object</b></td></tr> + <tr><td port="w" border="1">weakrefs</td></tr> + <tr><td port="dv" border="1">dict or values</td></tr> + <tr><td border="1" >GC info 0</td></tr> + <tr><td border="1" >GC info 1</td></tr> + <tr><td port="r" border="1" >refcount</td></tr> + <tr><td port="h" border="1" >__class__</td></tr> + <tr><td border="1">opaque (extension) data </td></tr> + <tr><td border="1">...</td></tr> + <tr><td border="1">__slot__ 0</td></tr> + <tr><td border="1">...</td></tr> + </table>> + ] + + oop [ label = "pointer"; shape="plain"] + oop -> object:r +} diff --git a/Objects/object_layout_full_312.png b/Objects/object_layout_full_312.png new file mode 100644 index 0000000000000000000000000000000000000000..4f46ca86091d452c52f53dcb102b72e7c0954e41 GIT binary patch literal 17092 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%0D-RvO?#w2 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 F{{lUT7J2{x literal 0 HcmV?d00001 diff --git a/Objects/obmalloc.c b/Objects/obmalloc.c index fae9c811..9620a8fb 100644 --- a/Objects/obmalloc.c +++ b/Objects/obmalloc.c @@ -1,96 +1,40 @@ -#include "Python.h" -#include "pycore_pymem.h" // _PyTraceMalloc_Config -#include "pycore_code.h" // stats - -#include <stdbool.h> -#include <stdlib.h> // malloc() - +/* Python's malloc wrappers (see pymem.h) */ -/* Defined in tracemalloc.c */ -extern void _PyMem_DumpTraceback(int fd, const void *ptr); +#include "Python.h" +#include "pycore_code.h" // stats +#include "pycore_pystate.h" // _PyInterpreterState_GET +#include "pycore_obmalloc.h" +#include "pycore_pymem.h" -/* Python's malloc wrappers (see pymem.h) */ +#include <stdlib.h> // malloc() +#include <stdbool.h> #undef uint -#define uint unsigned int /* assuming >= 16 bits */ +#define uint pymem_uint -/* Forward declaration */ -static void* _PyMem_DebugRawMalloc(void *ctx, size_t size); -static void* _PyMem_DebugRawCalloc(void *ctx, size_t nelem, size_t elsize); -static void* _PyMem_DebugRawRealloc(void *ctx, void *ptr, size_t size); -static void _PyMem_DebugRawFree(void *ctx, void *ptr); -static void* _PyMem_DebugMalloc(void *ctx, size_t size); -static void* _PyMem_DebugCalloc(void *ctx, size_t nelem, size_t elsize); -static void* _PyMem_DebugRealloc(void *ctx, void *ptr, size_t size); -static void _PyMem_DebugFree(void *ctx, void *p); +/* Defined in tracemalloc.c */ +extern void _PyMem_DumpTraceback(int fd, const void *ptr); static void _PyObject_DebugDumpAddress(const void *p); static void _PyMem_DebugCheckAddress(const char *func, char api_id, const void *p); -static void _PyMem_SetupDebugHooksDomain(PyMemAllocatorDomain domain); -#if defined(__has_feature) /* Clang */ -# if __has_feature(address_sanitizer) /* is ASAN enabled? */ -# define _Py_NO_SANITIZE_ADDRESS \ - __attribute__((no_sanitize("address"))) -# endif -# if __has_feature(thread_sanitizer) /* is TSAN enabled? */ -# define _Py_NO_SANITIZE_THREAD __attribute__((no_sanitize_thread)) -# endif -# if __has_feature(memory_sanitizer) /* is MSAN enabled? */ -# define _Py_NO_SANITIZE_MEMORY __attribute__((no_sanitize_memory)) -# endif -#elif defined(__GNUC__) -# if defined(__SANITIZE_ADDRESS__) /* GCC 4.8+, is ASAN enabled? */ -# define _Py_NO_SANITIZE_ADDRESS \ - __attribute__((no_sanitize_address)) -# endif - // TSAN is supported since GCC 5.1, but __SANITIZE_THREAD__ macro - // is provided only since GCC 7. -# if __GNUC__ > 5 || (__GNUC__ == 5 && __GNUC_MINOR__ >= 1) -# define _Py_NO_SANITIZE_THREAD __attribute__((no_sanitize_thread)) -# endif -#endif - -#ifndef _Py_NO_SANITIZE_ADDRESS -# define _Py_NO_SANITIZE_ADDRESS -#endif -#ifndef _Py_NO_SANITIZE_THREAD -# define _Py_NO_SANITIZE_THREAD -#endif -#ifndef _Py_NO_SANITIZE_MEMORY -# define _Py_NO_SANITIZE_MEMORY -#endif - -#ifdef WITH_PYMALLOC - -#ifdef MS_WINDOWS -# include <windows.h> -#elif defined(HAVE_MMAP) -# include <sys/mman.h> -# ifdef MAP_ANONYMOUS -# define ARENAS_USE_MMAP -# endif -#endif - -/* Forward declaration */ -static void* _PyObject_Malloc(void *ctx, size_t size); -static void* _PyObject_Calloc(void *ctx, size_t nelem, size_t elsize); -static void _PyObject_Free(void *ctx, void *p); -static void* _PyObject_Realloc(void *ctx, void *ptr, size_t size); -#endif +static void set_up_debug_hooks_domain_unlocked(PyMemAllocatorDomain domain); +static void set_up_debug_hooks_unlocked(void); +static void get_allocator_unlocked(PyMemAllocatorDomain, PyMemAllocatorEx *); +static void set_allocator_unlocked(PyMemAllocatorDomain, PyMemAllocatorEx *); -/* bpo-35053: Declare tracemalloc configuration here rather than - Modules/_tracemalloc.c because _tracemalloc can be compiled as dynamic - library, whereas _Py_NewReference() requires it. */ -struct _PyTraceMalloc_Config _Py_tracemalloc_config = _PyTraceMalloc_Config_INIT; +/***************************************/ +/* low-level allocator implementations */ +/***************************************/ +/* the default raw allocator (wraps malloc) */ -static void * -_PyMem_RawMalloc(void *ctx, size_t size) +void * +_PyMem_RawMalloc(void *Py_UNUSED(ctx), size_t size) { /* PyMem_RawMalloc(0) means malloc(1). Some systems would return NULL for malloc(0), which would be treated as an error. Some platforms would @@ -101,8 +45,8 @@ _PyMem_RawMalloc(void *ctx, size_t size) return malloc(size); } -static void * -_PyMem_RawCalloc(void *ctx, size_t nelem, size_t elsize) +void * +_PyMem_RawCalloc(void *Py_UNUSED(ctx), size_t nelem, size_t elsize) { /* PyMem_RawCalloc(0, 0) means calloc(1, 1). Some systems would return NULL for calloc(0, 0), which would be treated as an error. Some platforms @@ -115,39 +59,81 @@ _PyMem_RawCalloc(void *ctx, size_t nelem, size_t elsize) return calloc(nelem, elsize); } -static void * -_PyMem_RawRealloc(void *ctx, void *ptr, size_t size) +void * +_PyMem_RawRealloc(void *Py_UNUSED(ctx), void *ptr, size_t size) { if (size == 0) size = 1; return realloc(ptr, size); } -static void -_PyMem_RawFree(void *ctx, void *ptr) +void +_PyMem_RawFree(void *Py_UNUSED(ctx), void *ptr) { free(ptr); } +#define MALLOC_ALLOC {NULL, _PyMem_RawMalloc, _PyMem_RawCalloc, _PyMem_RawRealloc, _PyMem_RawFree} +#define PYRAW_ALLOC MALLOC_ALLOC -#ifdef MS_WINDOWS -static void * -_PyObject_ArenaVirtualAlloc(void *ctx, size_t size) +/* the default object allocator */ + +// The actual implementation is further down. + +#ifdef WITH_PYMALLOC +void* _PyObject_Malloc(void *ctx, size_t size); +void* _PyObject_Calloc(void *ctx, size_t nelem, size_t elsize); +void _PyObject_Free(void *ctx, void *p); +void* _PyObject_Realloc(void *ctx, void *ptr, size_t size); +# define PYMALLOC_ALLOC {NULL, _PyObject_Malloc, _PyObject_Calloc, _PyObject_Realloc, _PyObject_Free} +# define PYOBJ_ALLOC PYMALLOC_ALLOC +#else +# define PYOBJ_ALLOC MALLOC_ALLOC +#endif // WITH_PYMALLOC + +#define PYMEM_ALLOC PYOBJ_ALLOC + +/* the default debug allocators */ + +// The actual implementation is further down. + +void* _PyMem_DebugRawMalloc(void *ctx, size_t size); +void* _PyMem_DebugRawCalloc(void *ctx, size_t nelem, size_t elsize); +void* _PyMem_DebugRawRealloc(void *ctx, void *ptr, size_t size); +void _PyMem_DebugRawFree(void *ctx, void *ptr); + +void* _PyMem_DebugMalloc(void *ctx, size_t size); +void* _PyMem_DebugCalloc(void *ctx, size_t nelem, size_t elsize); +void* _PyMem_DebugRealloc(void *ctx, void *ptr, size_t size); +void _PyMem_DebugFree(void *ctx, void *p); + +#define PYDBGRAW_ALLOC \ + {&_PyRuntime.allocators.debug.raw, _PyMem_DebugRawMalloc, _PyMem_DebugRawCalloc, _PyMem_DebugRawRealloc, _PyMem_DebugRawFree} +#define PYDBGMEM_ALLOC \ + {&_PyRuntime.allocators.debug.mem, _PyMem_DebugMalloc, _PyMem_DebugCalloc, _PyMem_DebugRealloc, _PyMem_DebugFree} +#define PYDBGOBJ_ALLOC \ + {&_PyRuntime.allocators.debug.obj, _PyMem_DebugMalloc, _PyMem_DebugCalloc, _PyMem_DebugRealloc, _PyMem_DebugFree} + +/* the low-level virtual memory allocator */ + +#ifdef WITH_PYMALLOC +# ifdef MS_WINDOWS +# include <windows.h> +# elif defined(HAVE_MMAP) +# include <sys/mman.h> +# ifdef MAP_ANONYMOUS +# define ARENAS_USE_MMAP +# endif +# endif +#endif + +void * +_PyMem_ArenaAlloc(void *Py_UNUSED(ctx), size_t size) { +#ifdef MS_WINDOWS return VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); -} - -static void -_PyObject_ArenaVirtualFree(void *ctx, void *ptr, size_t size) -{ - VirtualFree(ptr, 0, MEM_RELEASE); -} - #elif defined(ARENAS_USE_MMAP) -static void * -_PyObject_ArenaMmap(void *ctx, size_t size) -{ void *ptr; ptr = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); @@ -155,80 +141,86 @@ _PyObject_ArenaMmap(void *ctx, size_t size) return NULL; assert(ptr != NULL); return ptr; -} - -static void -_PyObject_ArenaMunmap(void *ctx, void *ptr, size_t size) -{ - munmap(ptr, size); -} - #else -static void * -_PyObject_ArenaMalloc(void *ctx, size_t size) -{ return malloc(size); +#endif } -static void -_PyObject_ArenaFree(void *ctx, void *ptr, size_t size) +void +_PyMem_ArenaFree(void *Py_UNUSED(ctx), void *ptr, +#if defined(ARENAS_USE_MMAP) + size_t size +#else + size_t Py_UNUSED(size) +#endif +) { +#ifdef MS_WINDOWS + VirtualFree(ptr, 0, MEM_RELEASE); +#elif defined(ARENAS_USE_MMAP) + munmap(ptr, size); +#else free(ptr); -} #endif +} -#define MALLOC_ALLOC {NULL, _PyMem_RawMalloc, _PyMem_RawCalloc, _PyMem_RawRealloc, _PyMem_RawFree} -#ifdef WITH_PYMALLOC -# define PYMALLOC_ALLOC {NULL, _PyObject_Malloc, _PyObject_Calloc, _PyObject_Realloc, _PyObject_Free} +/*******************************************/ +/* end low-level allocator implementations */ +/*******************************************/ + + +#if defined(__has_feature) /* Clang */ +# if __has_feature(address_sanitizer) /* is ASAN enabled? */ +# define _Py_NO_SANITIZE_ADDRESS \ + __attribute__((no_sanitize("address"))) +# endif +# if __has_feature(thread_sanitizer) /* is TSAN enabled? */ +# define _Py_NO_SANITIZE_THREAD __attribute__((no_sanitize_thread)) +# endif +# if __has_feature(memory_sanitizer) /* is MSAN enabled? */ +# define _Py_NO_SANITIZE_MEMORY __attribute__((no_sanitize_memory)) +# endif +#elif defined(__GNUC__) +# if defined(__SANITIZE_ADDRESS__) /* GCC 4.8+, is ASAN enabled? */ +# define _Py_NO_SANITIZE_ADDRESS \ + __attribute__((no_sanitize_address)) +# endif + // TSAN is supported since GCC 5.1, but __SANITIZE_THREAD__ macro + // is provided only since GCC 7. +# if __GNUC__ > 5 || (__GNUC__ == 5 && __GNUC_MINOR__ >= 1) +# define _Py_NO_SANITIZE_THREAD __attribute__((no_sanitize_thread)) +# endif #endif -#define PYRAW_ALLOC MALLOC_ALLOC -#ifdef WITH_PYMALLOC -# define PYOBJ_ALLOC PYMALLOC_ALLOC -#else -# define PYOBJ_ALLOC MALLOC_ALLOC +#ifndef _Py_NO_SANITIZE_ADDRESS +# define _Py_NO_SANITIZE_ADDRESS +#endif +#ifndef _Py_NO_SANITIZE_THREAD +# define _Py_NO_SANITIZE_THREAD +#endif +#ifndef _Py_NO_SANITIZE_MEMORY +# define _Py_NO_SANITIZE_MEMORY #endif -#define PYMEM_ALLOC PYOBJ_ALLOC -typedef struct { - /* We tag each block with an API ID in order to tag API violations */ - char api_id; - PyMemAllocatorEx alloc; -} debug_alloc_api_t; -static struct { - debug_alloc_api_t raw; - debug_alloc_api_t mem; - debug_alloc_api_t obj; -} _PyMem_Debug = { - {'r', PYRAW_ALLOC}, - {'m', PYMEM_ALLOC}, - {'o', PYOBJ_ALLOC} - }; -#define PYDBGRAW_ALLOC \ - {&_PyMem_Debug.raw, _PyMem_DebugRawMalloc, _PyMem_DebugRawCalloc, _PyMem_DebugRawRealloc, _PyMem_DebugRawFree} -#define PYDBGMEM_ALLOC \ - {&_PyMem_Debug.mem, _PyMem_DebugMalloc, _PyMem_DebugCalloc, _PyMem_DebugRealloc, _PyMem_DebugFree} -#define PYDBGOBJ_ALLOC \ - {&_PyMem_Debug.obj, _PyMem_DebugMalloc, _PyMem_DebugCalloc, _PyMem_DebugRealloc, _PyMem_DebugFree} +#define ALLOCATORS_MUTEX (_PyRuntime.allocators.mutex) +#define _PyMem_Raw (_PyRuntime.allocators.standard.raw) +#define _PyMem (_PyRuntime.allocators.standard.mem) +#define _PyObject (_PyRuntime.allocators.standard.obj) +#define _PyMem_Debug (_PyRuntime.allocators.debug) +#define _PyObject_Arena (_PyRuntime.allocators.obj_arena) -#ifdef Py_DEBUG -static PyMemAllocatorEx _PyMem_Raw = PYDBGRAW_ALLOC; -static PyMemAllocatorEx _PyMem = PYDBGMEM_ALLOC; -static PyMemAllocatorEx _PyObject = PYDBGOBJ_ALLOC; -#else -static PyMemAllocatorEx _PyMem_Raw = PYRAW_ALLOC; -static PyMemAllocatorEx _PyMem = PYMEM_ALLOC; -static PyMemAllocatorEx _PyObject = PYOBJ_ALLOC; -#endif +/***************************/ +/* managing the allocators */ +/***************************/ static int -pymem_set_default_allocator(PyMemAllocatorDomain domain, int debug, - PyMemAllocatorEx *old_alloc) +set_default_allocator_unlocked(PyMemAllocatorDomain domain, int debug, + PyMemAllocatorEx *old_alloc) { if (old_alloc != NULL) { - PyMem_GetAllocator(domain, old_alloc); + get_allocator_unlocked(domain, old_alloc); } @@ -248,24 +240,32 @@ pymem_set_default_allocator(PyMemAllocatorDomain domain, int debug, /* unknown domain */ return -1; } - PyMem_SetAllocator(domain, &new_alloc); + set_allocator_unlocked(domain, &new_alloc); if (debug) { - _PyMem_SetupDebugHooksDomain(domain); + set_up_debug_hooks_domain_unlocked(domain); } return 0; } +#ifdef Py_DEBUG +static const int pydebug = 1; +#else +static const int pydebug = 0; +#endif + int _PyMem_SetDefaultAllocator(PyMemAllocatorDomain domain, PyMemAllocatorEx *old_alloc) { -#ifdef Py_DEBUG - const int debug = 1; -#else - const int debug = 0; -#endif - return pymem_set_default_allocator(domain, debug, old_alloc); + if (ALLOCATORS_MUTEX == NULL) { + /* The runtime must be initializing. */ + return set_default_allocator_unlocked(domain, pydebug, old_alloc); + } + PyThread_acquire_lock(ALLOCATORS_MUTEX, WAIT_LOCK); + int res = set_default_allocator_unlocked(domain, pydebug, old_alloc); + PyThread_release_lock(ALLOCATORS_MUTEX); + return res; } @@ -305,8 +305,8 @@ _PyMem_GetAllocatorName(const char *name, PyMemAllocatorName *allocator) } -int -_PyMem_SetupAllocators(PyMemAllocatorName allocator) +static int +set_up_allocators_unlocked(PyMemAllocatorName allocator) { switch (allocator) { case PYMEM_ALLOCATOR_NOT_SET: @@ -314,15 +314,15 @@ _PyMem_SetupAllocators(PyMemAllocatorName allocator) break; case PYMEM_ALLOCATOR_DEFAULT: - (void)_PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, NULL); - (void)_PyMem_SetDefaultAllocator(PYMEM_DOMAIN_MEM, NULL); - (void)_PyMem_SetDefaultAllocator(PYMEM_DOMAIN_OBJ, NULL); + (void)set_default_allocator_unlocked(PYMEM_DOMAIN_RAW, pydebug, NULL); + (void)set_default_allocator_unlocked(PYMEM_DOMAIN_MEM, pydebug, NULL); + (void)set_default_allocator_unlocked(PYMEM_DOMAIN_OBJ, pydebug, NULL); break; case PYMEM_ALLOCATOR_DEBUG: - (void)pymem_set_default_allocator(PYMEM_DOMAIN_RAW, 1, NULL); - (void)pymem_set_default_allocator(PYMEM_DOMAIN_MEM, 1, NULL); - (void)pymem_set_default_allocator(PYMEM_DOMAIN_OBJ, 1, NULL); + (void)set_default_allocator_unlocked(PYMEM_DOMAIN_RAW, 1, NULL); + (void)set_default_allocator_unlocked(PYMEM_DOMAIN_MEM, 1, NULL); + (void)set_default_allocator_unlocked(PYMEM_DOMAIN_OBJ, 1, NULL); break; #ifdef WITH_PYMALLOC @@ -330,14 +330,14 @@ _PyMem_SetupAllocators(PyMemAllocatorName allocator) case PYMEM_ALLOCATOR_PYMALLOC_DEBUG: { PyMemAllocatorEx malloc_alloc = MALLOC_ALLOC; - PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &malloc_alloc); + set_allocator_unlocked(PYMEM_DOMAIN_RAW, &malloc_alloc); PyMemAllocatorEx pymalloc = PYMALLOC_ALLOC; - PyMem_SetAllocator(PYMEM_DOMAIN_MEM, &pymalloc); - PyMem_SetAllocator(PYMEM_DOMAIN_OBJ, &pymalloc); + set_allocator_unlocked(PYMEM_DOMAIN_MEM, &pymalloc); + set_allocator_unlocked(PYMEM_DOMAIN_OBJ, &pymalloc); if (allocator == PYMEM_ALLOCATOR_PYMALLOC_DEBUG) { - PyMem_SetupDebugHooks(); + set_up_debug_hooks_unlocked(); } break; } @@ -347,12 +347,12 @@ _PyMem_SetupAllocators(PyMemAllocatorName allocator) case PYMEM_ALLOCATOR_MALLOC_DEBUG: { PyMemAllocatorEx malloc_alloc = MALLOC_ALLOC; - PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &malloc_alloc); - PyMem_SetAllocator(PYMEM_DOMAIN_MEM, &malloc_alloc); - PyMem_SetAllocator(PYMEM_DOMAIN_OBJ, &malloc_alloc); + set_allocator_unlocked(PYMEM_DOMAIN_RAW, &malloc_alloc); + set_allocator_unlocked(PYMEM_DOMAIN_MEM, &malloc_alloc); + set_allocator_unlocked(PYMEM_DOMAIN_OBJ, &malloc_alloc); if (allocator == PYMEM_ALLOCATOR_MALLOC_DEBUG) { - PyMem_SetupDebugHooks(); + set_up_debug_hooks_unlocked(); } break; } @@ -361,9 +361,19 @@ _PyMem_SetupAllocators(PyMemAllocatorName allocator) /* unknown allocator */ return -1; } + return 0; } +int +_PyMem_SetupAllocators(PyMemAllocatorName allocator) +{ + PyThread_acquire_lock(ALLOCATORS_MUTEX, WAIT_LOCK); + int res = set_up_allocators_unlocked(allocator); + PyThread_release_lock(ALLOCATORS_MUTEX); + return res; +} + static int pymemallocator_eq(PyMemAllocatorEx *a, PyMemAllocatorEx *b) @@ -372,8 +382,8 @@ pymemallocator_eq(PyMemAllocatorEx *a, PyMemAllocatorEx *b) } -const char* -_PyMem_GetCurrentAllocatorName(void) +static const char* +get_current_allocator_name_unlocked(void) { PyMemAllocatorEx malloc_alloc = MALLOC_ALLOC; #ifdef WITH_PYMALLOC @@ -422,26 +432,15 @@ _PyMem_GetCurrentAllocatorName(void) return NULL; } +const char* +_PyMem_GetCurrentAllocatorName(void) +{ + PyThread_acquire_lock(ALLOCATORS_MUTEX, WAIT_LOCK); + const char *name = get_current_allocator_name_unlocked(); + PyThread_release_lock(ALLOCATORS_MUTEX); + return name; +} -#undef MALLOC_ALLOC -#undef PYMALLOC_ALLOC -#undef PYRAW_ALLOC -#undef PYMEM_ALLOC -#undef PYOBJ_ALLOC -#undef PYDBGRAW_ALLOC -#undef PYDBGMEM_ALLOC -#undef PYDBGOBJ_ALLOC - - -static PyObjectArenaAllocator _PyObject_Arena = {NULL, -#ifdef MS_WINDOWS - _PyObject_ArenaVirtualAlloc, _PyObject_ArenaVirtualFree -#elif defined(ARENAS_USE_MMAP) - _PyObject_ArenaMmap, _PyObject_ArenaMunmap -#else - _PyObject_ArenaMalloc, _PyObject_ArenaFree -#endif - }; #ifdef WITH_PYMALLOC static int @@ -464,7 +463,7 @@ _PyMem_PymallocEnabled(void) static void -_PyMem_SetupDebugHooksDomain(PyMemAllocatorDomain domain) +set_up_debug_hooks_domain_unlocked(PyMemAllocatorDomain domain) { PyMemAllocatorEx alloc; @@ -473,53 +472,66 @@ _PyMem_SetupDebugHooksDomain(PyMemAllocatorDomain domain) return; } - PyMem_GetAllocator(PYMEM_DOMAIN_RAW, &_PyMem_Debug.raw.alloc); + get_allocator_unlocked(domain, &_PyMem_Debug.raw.alloc); alloc.ctx = &_PyMem_Debug.raw; alloc.malloc = _PyMem_DebugRawMalloc; alloc.calloc = _PyMem_DebugRawCalloc; alloc.realloc = _PyMem_DebugRawRealloc; alloc.free = _PyMem_DebugRawFree; - PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &alloc); + set_allocator_unlocked(domain, &alloc); } else if (domain == PYMEM_DOMAIN_MEM) { if (_PyMem.malloc == _PyMem_DebugMalloc) { return; } - PyMem_GetAllocator(PYMEM_DOMAIN_MEM, &_PyMem_Debug.mem.alloc); + get_allocator_unlocked(domain, &_PyMem_Debug.mem.alloc); alloc.ctx = &_PyMem_Debug.mem; alloc.malloc = _PyMem_DebugMalloc; alloc.calloc = _PyMem_DebugCalloc; alloc.realloc = _PyMem_DebugRealloc; alloc.free = _PyMem_DebugFree; - PyMem_SetAllocator(PYMEM_DOMAIN_MEM, &alloc); + set_allocator_unlocked(domain, &alloc); } else if (domain == PYMEM_DOMAIN_OBJ) { if (_PyObject.malloc == _PyMem_DebugMalloc) { return; } - PyMem_GetAllocator(PYMEM_DOMAIN_OBJ, &_PyMem_Debug.obj.alloc); + get_allocator_unlocked(domain, &_PyMem_Debug.obj.alloc); alloc.ctx = &_PyMem_Debug.obj; alloc.malloc = _PyMem_DebugMalloc; alloc.calloc = _PyMem_DebugCalloc; alloc.realloc = _PyMem_DebugRealloc; alloc.free = _PyMem_DebugFree; - PyMem_SetAllocator(PYMEM_DOMAIN_OBJ, &alloc); + set_allocator_unlocked(domain, &alloc); } } +static void +set_up_debug_hooks_unlocked(void) +{ + set_up_debug_hooks_domain_unlocked(PYMEM_DOMAIN_RAW); + set_up_debug_hooks_domain_unlocked(PYMEM_DOMAIN_MEM); + set_up_debug_hooks_domain_unlocked(PYMEM_DOMAIN_OBJ); +} + void PyMem_SetupDebugHooks(void) { - _PyMem_SetupDebugHooksDomain(PYMEM_DOMAIN_RAW); - _PyMem_SetupDebugHooksDomain(PYMEM_DOMAIN_MEM); - _PyMem_SetupDebugHooksDomain(PYMEM_DOMAIN_OBJ); + if (ALLOCATORS_MUTEX == NULL) { + /* The runtime must not be completely initialized yet. */ + set_up_debug_hooks_unlocked(); + return; + } + PyThread_acquire_lock(ALLOCATORS_MUTEX, WAIT_LOCK); + set_up_debug_hooks_unlocked(); + PyThread_release_lock(ALLOCATORS_MUTEX); } -void -PyMem_GetAllocator(PyMemAllocatorDomain domain, PyMemAllocatorEx *allocator) +static void +get_allocator_unlocked(PyMemAllocatorDomain domain, PyMemAllocatorEx *allocator) { switch(domain) { @@ -536,8 +548,8 @@ PyMem_GetAllocator(PyMemAllocatorDomain domain, PyMemAllocatorEx *allocator) } } -void -PyMem_SetAllocator(PyMemAllocatorDomain domain, PyMemAllocatorEx *allocator) +static void +set_allocator_unlocked(PyMemAllocatorDomain domain, PyMemAllocatorEx *allocator) { switch(domain) { @@ -548,12 +560,77 @@ PyMem_SetAllocator(PyMemAllocatorDomain domain, PyMemAllocatorEx *allocator) } } +void +PyMem_GetAllocator(PyMemAllocatorDomain domain, PyMemAllocatorEx *allocator) +{ + if (ALLOCATORS_MUTEX == NULL) { + /* The runtime must not be completely initialized yet. */ + get_allocator_unlocked(domain, allocator); + return; + } + PyThread_acquire_lock(ALLOCATORS_MUTEX, WAIT_LOCK); + get_allocator_unlocked(domain, allocator); + PyThread_release_lock(ALLOCATORS_MUTEX); +} + +void +PyMem_SetAllocator(PyMemAllocatorDomain domain, PyMemAllocatorEx *allocator) +{ + if (ALLOCATORS_MUTEX == NULL) { + /* The runtime must not be completely initialized yet. */ + set_allocator_unlocked(domain, allocator); + return; + } + PyThread_acquire_lock(ALLOCATORS_MUTEX, WAIT_LOCK); + set_allocator_unlocked(domain, allocator); + PyThread_release_lock(ALLOCATORS_MUTEX); +} + void PyObject_GetArenaAllocator(PyObjectArenaAllocator *allocator) { + if (ALLOCATORS_MUTEX == NULL) { + /* The runtime must not be completely initialized yet. */ + *allocator = _PyObject_Arena; + return; + } + PyThread_acquire_lock(ALLOCATORS_MUTEX, WAIT_LOCK); *allocator = _PyObject_Arena; + PyThread_release_lock(ALLOCATORS_MUTEX); +} + +void +PyObject_SetArenaAllocator(PyObjectArenaAllocator *allocator) +{ + if (ALLOCATORS_MUTEX == NULL) { + /* The runtime must not be completely initialized yet. */ + _PyObject_Arena = *allocator; + return; + } + PyThread_acquire_lock(ALLOCATORS_MUTEX, WAIT_LOCK); + _PyObject_Arena = *allocator; + PyThread_release_lock(ALLOCATORS_MUTEX); } + +/* Note that there is a possible, but very unlikely, race in any place + * below where we call one of the allocator functions. We access two + * fields in each case: "malloc", etc. and "ctx". + * + * It is unlikely that the allocator will be changed while one of those + * calls is happening, much less in that very narrow window. + * Furthermore, the likelihood of a race is drastically reduced by the + * fact that the allocator may not be changed after runtime init + * (except with a wrapper). + * + * With the above in mind, we currently don't worry about locking + * around these uses of the runtime-global allocators state. */ + + +/*************************/ +/* the "arena" allocator */ +/*************************/ + void * _PyObject_VirtualAlloc(size_t size) { @@ -566,11 +643,10 @@ _PyObject_VirtualFree(void *obj, size_t size) _PyObject_Arena.free(_PyObject_Arena.ctx, obj, size); } -void -PyObject_SetArenaAllocator(PyObjectArenaAllocator *allocator) -{ - _PyObject_Arena = *allocator; -} + +/***********************/ +/* the "raw" allocator */ +/***********************/ void * PyMem_RawMalloc(size_t size) @@ -610,6 +686,10 @@ void PyMem_RawFree(void *ptr) } +/***********************/ +/* the "mem" allocator */ +/***********************/ + void * PyMem_Malloc(size_t size) { @@ -653,6 +733,10 @@ PyMem_Free(void *ptr) } +/***************************/ +/* pymem utility functions */ +/***************************/ + wchar_t* _PyMem_RawWcsdup(const wchar_t *str) { @@ -699,6 +783,11 @@ _PyMem_Strdup(const char *str) return copy; } + +/**************************/ +/* the "object" allocator */ +/**************************/ + void * PyObject_Malloc(size_t size) { @@ -761,534 +850,64 @@ PyObject_Free(void *ptr) static int running_on_valgrind = -1; #endif +typedef struct _obmalloc_state OMState; -/* An object allocator for Python. - - Here is an introduction to the layers of the Python memory architecture, - showing where the object allocator is actually used (layer +2), It is - called for every object allocation and deallocation (PyObject_New/Del), - unless the object-specific allocators implement a proprietary allocation - scheme (ex.: ints use a simple free list). This is also the place where - the cyclic garbage collector operates selectively on container objects. - - - Object-specific allocators - _____ ______ ______ ________ - [ int ] [ dict ] [ list ] ... [ string ] Python core | -+3 | <----- Object-specific memory -----> | <-- Non-object memory --> | - _______________________________ | | - [ Python's object allocator ] | | -+2 | ####### Object memory ####### | <------ Internal buffers ------> | - ______________________________________________________________ | - [ Python's raw memory allocator (PyMem_ API) ] | -+1 | <----- Python memory (under PyMem manager's control) ------> | | - __________________________________________________________________ - [ Underlying general-purpose allocator (ex: C library malloc) ] - 0 | <------ Virtual memory allocated for the python process -------> | - - ========================================================================= - _______________________________________________________________________ - [ OS-specific Virtual Memory Manager (VMM) ] --1 | <--- Kernel dynamic storage allocation & management (page-based) ---> | - __________________________________ __________________________________ - [ ] [ ] --2 | <-- Physical memory: ROM/RAM --> | | <-- Secondary storage (swap) --> | - -*/ -/*==========================================================================*/ - -/* A fast, special-purpose memory allocator for small blocks, to be used - on top of a general-purpose malloc -- heavily based on previous art. */ - -/* Vladimir Marangozov -- August 2000 */ - -/* - * "Memory management is where the rubber meets the road -- if we do the wrong - * thing at any level, the results will not be good. And if we don't make the - * levels work well together, we are in serious trouble." (1) - * - * (1) Paul R. Wilson, Mark S. Johnstone, Michael Neely, and David Boles, - * "Dynamic Storage Allocation: A Survey and Critical Review", - * in Proc. 1995 Int'l. Workshop on Memory Management, September 1995. - */ - -/* #undef WITH_MEMORY_LIMITS */ /* disable mem limit checks */ - -/*==========================================================================*/ - -/* - * Allocation strategy abstract: - * - * For small requests, the allocator sub-allocates <Big> blocks of memory. - * Requests greater than SMALL_REQUEST_THRESHOLD bytes are routed to the - * system's allocator. - * - * Small requests are grouped in size classes spaced 8 bytes apart, due - * to the required valid alignment of the returned address. Requests of - * a particular size are serviced from memory pools of 4K (one VMM page). - * Pools are fragmented on demand and contain free lists of blocks of one - * particular size class. In other words, there is a fixed-size allocator - * for each size class. Free pools are shared by the different allocators - * thus minimizing the space reserved for a particular size class. - * - * This allocation strategy is a variant of what is known as "simple - * segregated storage based on array of free lists". The main drawback of - * simple segregated storage is that we might end up with lot of reserved - * memory for the different free lists, which degenerate in time. To avoid - * this, we partition each free list in pools and we share dynamically the - * reserved space between all free lists. This technique is quite efficient - * for memory intensive programs which allocate mainly small-sized blocks. - * - * For small requests we have the following table: - * - * Request in bytes Size of allocated block Size class idx - * ---------------------------------------------------------------- - * 1-8 8 0 - * 9-16 16 1 - * 17-24 24 2 - * 25-32 32 3 - * 33-40 40 4 - * 41-48 48 5 - * 49-56 56 6 - * 57-64 64 7 - * 65-72 72 8 - * ... ... ... - * 497-504 504 62 - * 505-512 512 63 - * - * 0, SMALL_REQUEST_THRESHOLD + 1 and up: routed to the underlying - * allocator. - */ - -/*==========================================================================*/ - -/* - * -- Main tunable settings section -- - */ - -/* - * Alignment of addresses returned to the user. 8-bytes alignment works - * on most current architectures (with 32-bit or 64-bit address buses). - * The alignment value is also used for grouping small requests in size - * classes spaced ALIGNMENT bytes apart. - * - * You shouldn't change this unless you know what you are doing. - */ - -#if SIZEOF_VOID_P > 4 -#define ALIGNMENT 16 /* must be 2^N */ -#define ALIGNMENT_SHIFT 4 -#else -#define ALIGNMENT 8 /* must be 2^N */ -#define ALIGNMENT_SHIFT 3 -#endif - -/* Return the number of bytes in size class I, as a uint. */ -#define INDEX2SIZE(I) (((uint)(I) + 1) << ALIGNMENT_SHIFT) - -/* - * Max size threshold below which malloc requests are considered to be - * small enough in order to use preallocated memory pools. You can tune - * this value according to your application behaviour and memory needs. - * - * Note: a size threshold of 512 guarantees that newly created dictionaries - * will be allocated from preallocated memory pools on 64-bit. - * - * The following invariants must hold: - * 1) ALIGNMENT <= SMALL_REQUEST_THRESHOLD <= 512 - * 2) SMALL_REQUEST_THRESHOLD is evenly divisible by ALIGNMENT - * - * Although not required, for better performance and space efficiency, - * it is recommended that SMALL_REQUEST_THRESHOLD is set to a power of 2. - */ -#define SMALL_REQUEST_THRESHOLD 512 -#define NB_SMALL_SIZE_CLASSES (SMALL_REQUEST_THRESHOLD / ALIGNMENT) - -/* - * The system's VMM page size can be obtained on most unices with a - * getpagesize() call or deduced from various header files. To make - * things simpler, we assume that it is 4K, which is OK for most systems. - * It is probably better if this is the native page size, but it doesn't - * have to be. In theory, if SYSTEM_PAGE_SIZE is larger than the native page - * size, then `POOL_ADDR(p)->arenaindex' could rarely cause a segmentation - * violation fault. 4K is apparently OK for all the platforms that python - * currently targets. - */ -#define SYSTEM_PAGE_SIZE (4 * 1024) - -/* - * Maximum amount of memory managed by the allocator for small requests. - */ -#ifdef WITH_MEMORY_LIMITS -#ifndef SMALL_MEMORY_LIMIT -#define SMALL_MEMORY_LIMIT (64 * 1024 * 1024) /* 64 MB -- more? */ -#endif -#endif - -#if !defined(WITH_PYMALLOC_RADIX_TREE) -/* Use radix-tree to track arena memory regions, for address_in_range(). - * Enable by default since it allows larger pool sizes. Can be disabled - * using -DWITH_PYMALLOC_RADIX_TREE=0 */ -#define WITH_PYMALLOC_RADIX_TREE 1 -#endif - -#if SIZEOF_VOID_P > 4 -/* on 64-bit platforms use larger pools and arenas if we can */ -#define USE_LARGE_ARENAS -#if WITH_PYMALLOC_RADIX_TREE -/* large pools only supported if radix-tree is enabled */ -#define USE_LARGE_POOLS -#endif -#endif +static inline int +has_own_state(PyInterpreterState *interp) +{ + return (_Py_IsMainInterpreter(interp) || + !(interp->feature_flags & Py_RTFLAGS_USE_MAIN_OBMALLOC) || + _Py_IsMainInterpreterFinalizing(interp)); +} -/* - * The allocator sub-allocates <Big> blocks of memory (called arenas) aligned - * on a page boundary. This is a reserved virtual address space for the - * current process (obtained through a malloc()/mmap() call). In no way this - * means that the memory arenas will be used entirely. A malloc(<Big>) is - * usually an address range reservation for <Big> bytes, unless all pages within - * this space are referenced subsequently. So malloc'ing big blocks and not - * using them does not mean "wasting memory". It's an addressable range - * wastage... - * - * Arenas are allocated with mmap() on systems supporting anonymous memory - * mappings to reduce heap fragmentation. - */ -#ifdef USE_LARGE_ARENAS -#define ARENA_BITS 20 /* 1 MiB */ -#else -#define ARENA_BITS 18 /* 256 KiB */ -#endif -#define ARENA_SIZE (1 << ARENA_BITS) -#define ARENA_SIZE_MASK (ARENA_SIZE - 1) +static inline OMState * +get_state(void) +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + if (!has_own_state(interp)) { + interp = _PyInterpreterState_Main(); + } + return &interp->obmalloc; +} -#ifdef WITH_MEMORY_LIMITS -#define MAX_ARENAS (SMALL_MEMORY_LIMIT / ARENA_SIZE) -#endif +// These macros all rely on a local "state" variable. +#define usedpools (state->pools.used) +#define allarenas (state->mgmt.arenas) +#define maxarenas (state->mgmt.maxarenas) +#define unused_arena_objects (state->mgmt.unused_arena_objects) +#define usable_arenas (state->mgmt.usable_arenas) +#define nfp2lasta (state->mgmt.nfp2lasta) +#define narenas_currently_allocated (state->mgmt.narenas_currently_allocated) +#define ntimes_arena_allocated (state->mgmt.ntimes_arena_allocated) +#define narenas_highwater (state->mgmt.narenas_highwater) +#define raw_allocated_blocks (state->mgmt.raw_allocated_blocks) -/* - * Size of the pools used for small blocks. Must be a power of 2. - */ -#ifdef USE_LARGE_POOLS -#define POOL_BITS 14 /* 16 KiB */ +Py_ssize_t +_PyInterpreterState_GetAllocatedBlocks(PyInterpreterState *interp) +{ +#ifdef Py_DEBUG + assert(has_own_state(interp)); #else -#define POOL_BITS 12 /* 4 KiB */ -#endif -#define POOL_SIZE (1 << POOL_BITS) -#define POOL_SIZE_MASK (POOL_SIZE - 1) - -#if !WITH_PYMALLOC_RADIX_TREE -#if POOL_SIZE != SYSTEM_PAGE_SIZE -# error "pool size must be equal to system page size" -#endif -#endif - -#define MAX_POOLS_IN_ARENA (ARENA_SIZE / POOL_SIZE) -#if MAX_POOLS_IN_ARENA * POOL_SIZE != ARENA_SIZE -# error "arena size not an exact multiple of pool size" + if (!has_own_state(interp)) { + _Py_FatalErrorFunc(__func__, + "the interpreter doesn't have its own allocator"); + } #endif + OMState *state = &interp->obmalloc; -/* - * -- End of tunable settings section -- - */ - -/*==========================================================================*/ - -/* When you say memory, my mind reasons in terms of (pointers to) blocks */ -typedef uint8_t block; - -/* Pool for small blocks. */ -struct pool_header { - union { block *_padding; - uint count; } ref; /* number of allocated blocks */ - block *freeblock; /* pool's free list head */ - struct pool_header *nextpool; /* next pool of this size class */ - struct pool_header *prevpool; /* previous pool "" */ - uint arenaindex; /* index into arenas of base adr */ - uint szidx; /* block size class index */ - uint nextoffset; /* bytes to virgin block */ - uint maxnextoffset; /* largest valid nextoffset */ -}; - -typedef struct pool_header *poolp; - -/* Record keeping for arenas. */ -struct arena_object { - /* The address of the arena, as returned by malloc. Note that 0 - * will never be returned by a successful malloc, and is used - * here to mark an arena_object that doesn't correspond to an - * allocated arena. - */ - uintptr_t address; - - /* Pool-aligned pointer to the next pool to be carved off. */ - block* pool_address; - - /* The number of available pools in the arena: free pools + never- - * allocated pools. - */ - uint nfreepools; - - /* The total number of pools in the arena, whether or not available. */ - uint ntotalpools; - - /* Singly-linked list of available pools. */ - struct pool_header* freepools; - - /* Whenever this arena_object is not associated with an allocated - * arena, the nextarena member is used to link all unassociated - * arena_objects in the singly-linked `unused_arena_objects` list. - * The prevarena member is unused in this case. - * - * When this arena_object is associated with an allocated arena - * with at least one available pool, both members are used in the - * doubly-linked `usable_arenas` list, which is maintained in - * increasing order of `nfreepools` values. - * - * Else this arena_object is associated with an allocated arena - * all of whose pools are in use. `nextarena` and `prevarena` - * are both meaningless in this case. - */ - struct arena_object* nextarena; - struct arena_object* prevarena; -}; - -#define POOL_OVERHEAD _Py_SIZE_ROUND_UP(sizeof(struct pool_header), ALIGNMENT) - -#define DUMMY_SIZE_IDX 0xffff /* size class of newly cached pools */ - -/* Round pointer P down to the closest pool-aligned address <= P, as a poolp */ -#define POOL_ADDR(P) ((poolp)_Py_ALIGN_DOWN((P), POOL_SIZE)) - -/* Return total number of blocks in pool of size index I, as a uint. */ -#define NUMBLOCKS(I) ((uint)(POOL_SIZE - POOL_OVERHEAD) / INDEX2SIZE(I)) - -/*==========================================================================*/ - -/* - * Pool table -- headed, circular, doubly-linked lists of partially used pools. - -This is involved. For an index i, usedpools[i+i] is the header for a list of -all partially used pools holding small blocks with "size class idx" i. So -usedpools[0] corresponds to blocks of size 8, usedpools[2] to blocks of size -16, and so on: index 2*i <-> blocks of size (i+1)<<ALIGNMENT_SHIFT. - -Pools are carved off an arena's highwater mark (an arena_object's pool_address -member) as needed. Once carved off, a pool is in one of three states forever -after: - -used == partially used, neither empty nor full - At least one block in the pool is currently allocated, and at least one - block in the pool is not currently allocated (note this implies a pool - has room for at least two blocks). - This is a pool's initial state, as a pool is created only when malloc - needs space. - The pool holds blocks of a fixed size, and is in the circular list headed - at usedpools[i] (see above). It's linked to the other used pools of the - same size class via the pool_header's nextpool and prevpool members. - If all but one block is currently allocated, a malloc can cause a - transition to the full state. If all but one block is not currently - allocated, a free can cause a transition to the empty state. - -full == all the pool's blocks are currently allocated - On transition to full, a pool is unlinked from its usedpools[] list. - It's not linked to from anything then anymore, and its nextpool and - prevpool members are meaningless until it transitions back to used. - A free of a block in a full pool puts the pool back in the used state. - Then it's linked in at the front of the appropriate usedpools[] list, so - that the next allocation for its size class will reuse the freed block. - -empty == all the pool's blocks are currently available for allocation - On transition to empty, a pool is unlinked from its usedpools[] list, - and linked to the front of its arena_object's singly-linked freepools list, - via its nextpool member. The prevpool member has no meaning in this case. - Empty pools have no inherent size class: the next time a malloc finds - an empty list in usedpools[], it takes the first pool off of freepools. - If the size class needed happens to be the same as the size class the pool - last had, some pool initialization can be skipped. - - -Block Management - -Blocks within pools are again carved out as needed. pool->freeblock points to -the start of a singly-linked list of free blocks within the pool. When a -block is freed, it's inserted at the front of its pool's freeblock list. Note -that the available blocks in a pool are *not* linked all together when a pool -is initialized. Instead only "the first two" (lowest addresses) blocks are -set up, returning the first such block, and setting pool->freeblock to a -one-block list holding the second such block. This is consistent with that -pymalloc strives at all levels (arena, pool, and block) never to touch a piece -of memory until it's actually needed. - -So long as a pool is in the used state, we're certain there *is* a block -available for allocating, and pool->freeblock is not NULL. If pool->freeblock -points to the end of the free list before we've carved the entire pool into -blocks, that means we simply haven't yet gotten to one of the higher-address -blocks. The offset from the pool_header to the start of "the next" virgin -block is stored in the pool_header nextoffset member, and the largest value -of nextoffset that makes sense is stored in the maxnextoffset member when a -pool is initialized. All the blocks in a pool have been passed out at least -once when and only when nextoffset > maxnextoffset. - - -Major obscurity: While the usedpools vector is declared to have poolp -entries, it doesn't really. It really contains two pointers per (conceptual) -poolp entry, the nextpool and prevpool members of a pool_header. The -excruciating initialization code below fools C so that - - usedpool[i+i] - -"acts like" a genuine poolp, but only so long as you only reference its -nextpool and prevpool members. The "- 2*sizeof(block *)" gibberish is -compensating for that a pool_header's nextpool and prevpool members -immediately follow a pool_header's first two members: - - union { block *_padding; - uint count; } ref; - block *freeblock; - -each of which consume sizeof(block *) bytes. So what usedpools[i+i] really -contains is a fudged-up pointer p such that *if* C believes it's a poolp -pointer, then p->nextpool and p->prevpool are both p (meaning that the headed -circular list is empty). - -It's unclear why the usedpools setup is so convoluted. It could be to -minimize the amount of cache required to hold this heavily-referenced table -(which only *needs* the two interpool pointer members of a pool_header). OTOH, -referencing code has to remember to "double the index" and doing so isn't -free, usedpools[0] isn't a strictly legal pointer, and we're crucially relying -on that C doesn't insert any padding anywhere in a pool_header at or before -the prevpool member. -**************************************************************************** */ - -#define PTA(x) ((poolp )((uint8_t *)&(usedpools[2*(x)]) - 2*sizeof(block *))) -#define PT(x) PTA(x), PTA(x) - -static poolp usedpools[2 * ((NB_SMALL_SIZE_CLASSES + 7) / 8) * 8] = { - PT(0), PT(1), PT(2), PT(3), PT(4), PT(5), PT(6), PT(7) -#if NB_SMALL_SIZE_CLASSES > 8 - , PT(8), PT(9), PT(10), PT(11), PT(12), PT(13), PT(14), PT(15) -#if NB_SMALL_SIZE_CLASSES > 16 - , PT(16), PT(17), PT(18), PT(19), PT(20), PT(21), PT(22), PT(23) -#if NB_SMALL_SIZE_CLASSES > 24 - , PT(24), PT(25), PT(26), PT(27), PT(28), PT(29), PT(30), PT(31) -#if NB_SMALL_SIZE_CLASSES > 32 - , PT(32), PT(33), PT(34), PT(35), PT(36), PT(37), PT(38), PT(39) -#if NB_SMALL_SIZE_CLASSES > 40 - , PT(40), PT(41), PT(42), PT(43), PT(44), PT(45), PT(46), PT(47) -#if NB_SMALL_SIZE_CLASSES > 48 - , PT(48), PT(49), PT(50), PT(51), PT(52), PT(53), PT(54), PT(55) -#if NB_SMALL_SIZE_CLASSES > 56 - , PT(56), PT(57), PT(58), PT(59), PT(60), PT(61), PT(62), PT(63) -#if NB_SMALL_SIZE_CLASSES > 64 -#error "NB_SMALL_SIZE_CLASSES should be less than 64" -#endif /* NB_SMALL_SIZE_CLASSES > 64 */ -#endif /* NB_SMALL_SIZE_CLASSES > 56 */ -#endif /* NB_SMALL_SIZE_CLASSES > 48 */ -#endif /* NB_SMALL_SIZE_CLASSES > 40 */ -#endif /* NB_SMALL_SIZE_CLASSES > 32 */ -#endif /* NB_SMALL_SIZE_CLASSES > 24 */ -#endif /* NB_SMALL_SIZE_CLASSES > 16 */ -#endif /* NB_SMALL_SIZE_CLASSES > 8 */ -}; - -/*========================================================================== -Arena management. - -`arenas` is a vector of arena_objects. It contains maxarenas entries, some of -which may not be currently used (== they're arena_objects that aren't -currently associated with an allocated arena). Note that arenas proper are -separately malloc'ed. - -Prior to Python 2.5, arenas were never free()'ed. Starting with Python 2.5, -we do try to free() arenas, and use some mild heuristic strategies to increase -the likelihood that arenas eventually can be freed. - -unused_arena_objects - - This is a singly-linked list of the arena_objects that are currently not - being used (no arena is associated with them). Objects are taken off the - head of the list in new_arena(), and are pushed on the head of the list in - PyObject_Free() when the arena is empty. Key invariant: an arena_object - is on this list if and only if its .address member is 0. - -usable_arenas - - This is a doubly-linked list of the arena_objects associated with arenas - that have pools available. These pools are either waiting to be reused, - or have not been used before. The list is sorted to have the most- - allocated arenas first (ascending order based on the nfreepools member). - This means that the next allocation will come from a heavily used arena, - which gives the nearly empty arenas a chance to be returned to the system. - In my unscientific tests this dramatically improved the number of arenas - that could be freed. - -Note that an arena_object associated with an arena all of whose pools are -currently in use isn't on either list. - -Changed in Python 3.8: keeping usable_arenas sorted by number of free pools -used to be done by one-at-a-time linear search when an arena's number of -free pools changed. That could, overall, consume time quadratic in the -number of arenas. That didn't really matter when there were only a few -hundred arenas (typical!), but could be a timing disaster when there were -hundreds of thousands. See bpo-37029. - -Now we have a vector of "search fingers" to eliminate the need to search: -nfp2lasta[nfp] returns the last ("rightmost") arena in usable_arenas -with nfp free pools. This is NULL if and only if there is no arena with -nfp free pools in usable_arenas. -*/ - -/* Array of objects used to track chunks of memory (arenas). */ -static struct arena_object* arenas = NULL; -/* Number of slots currently allocated in the `arenas` vector. */ -static uint maxarenas = 0; - -/* The head of the singly-linked, NULL-terminated list of available - * arena_objects. - */ -static struct arena_object* unused_arena_objects = NULL; - -/* The head of the doubly-linked, NULL-terminated at each end, list of - * arena_objects associated with arenas that have pools available. - */ -static struct arena_object* usable_arenas = NULL; - -/* nfp2lasta[nfp] is the last arena in usable_arenas with nfp free pools */ -static struct arena_object* nfp2lasta[MAX_POOLS_IN_ARENA + 1] = { NULL }; - -/* How many arena_objects do we initially allocate? - * 16 = can allocate 16 arenas = 16 * ARENA_SIZE = 4MB before growing the - * `arenas` vector. - */ -#define INITIAL_ARENA_OBJECTS 16 - -/* Number of arenas allocated that haven't been free()'d. */ -static size_t narenas_currently_allocated = 0; - -/* Total number of times malloc() called to allocate an arena. */ -static size_t ntimes_arena_allocated = 0; -/* High water mark (max value ever seen) for narenas_currently_allocated. */ -static size_t narenas_highwater = 0; - -static Py_ssize_t raw_allocated_blocks; - -Py_ssize_t -_Py_GetAllocatedBlocks(void) -{ Py_ssize_t n = raw_allocated_blocks; /* add up allocated blocks for used pools */ for (uint i = 0; i < maxarenas; ++i) { /* Skip arenas which are not allocated. */ - if (arenas[i].address == 0) { + if (allarenas[i].address == 0) { continue; } - uintptr_t base = (uintptr_t)_Py_ALIGN_UP(arenas[i].address, POOL_SIZE); + uintptr_t base = (uintptr_t)_Py_ALIGN_UP(allarenas[i].address, POOL_SIZE); /* visit every pool in the arena */ - assert(base <= (uintptr_t) arenas[i].pool_address); - for (; base < (uintptr_t) arenas[i].pool_address; base += POOL_SIZE) { + assert(base <= (uintptr_t) allarenas[i].pool_address); + for (; base < (uintptr_t) allarenas[i].pool_address; base += POOL_SIZE) { poolp p = (poolp)base; n += p->ref.count; } @@ -1296,157 +915,100 @@ _Py_GetAllocatedBlocks(void) return n; } -#if WITH_PYMALLOC_RADIX_TREE -/*==========================================================================*/ -/* radix tree for tracking arena usage. If enabled, used to implement - address_in_range(). - - memory address bit allocation for keys - - 64-bit pointers, IGNORE_BITS=0 and 2^20 arena size: - 15 -> MAP_TOP_BITS - 15 -> MAP_MID_BITS - 14 -> MAP_BOT_BITS - 20 -> ideal aligned arena - ---- - 64 - - 64-bit pointers, IGNORE_BITS=16, and 2^20 arena size: - 16 -> IGNORE_BITS - 10 -> MAP_TOP_BITS - 10 -> MAP_MID_BITS - 8 -> MAP_BOT_BITS - 20 -> ideal aligned arena - ---- - 64 - - 32-bit pointers and 2^18 arena size: - 14 -> MAP_BOT_BITS - 18 -> ideal aligned arena - ---- - 32 - -*/ - -#if SIZEOF_VOID_P == 8 - -/* number of bits in a pointer */ -#define POINTER_BITS 64 - -/* High bits of memory addresses that will be ignored when indexing into the - * radix tree. Setting this to zero is the safe default. For most 64-bit - * machines, setting this to 16 would be safe. The kernel would not give - * user-space virtual memory addresses that have significant information in - * those high bits. The main advantage to setting IGNORE_BITS > 0 is that less - * virtual memory will be used for the top and middle radix tree arrays. Those - * arrays are allocated in the BSS segment and so will typically consume real - * memory only if actually accessed. - */ -#define IGNORE_BITS 0 - -/* use the top and mid layers of the radix tree */ -#define USE_INTERIOR_NODES - -#elif SIZEOF_VOID_P == 4 - -#define POINTER_BITS 32 -#define IGNORE_BITS 0 +void +_PyInterpreterState_FinalizeAllocatedBlocks(PyInterpreterState *interp) +{ + if (has_own_state(interp)) { + Py_ssize_t leaked = _PyInterpreterState_GetAllocatedBlocks(interp); + assert(has_own_state(interp) || leaked == 0); + interp->runtime->obmalloc.interpreter_leaks += leaked; + } +} -#else +static Py_ssize_t get_num_global_allocated_blocks(_PyRuntimeState *); - /* Currently this code works for 64-bit or 32-bit pointers only. */ -#error "obmalloc radix tree requires 64-bit or 32-bit pointers." +/* We preserve the number of blockss leaked during runtime finalization, + so they can be reported if the runtime is initialized again. */ +// XXX We don't lose any information by dropping this, +// so we should consider doing so. +static Py_ssize_t last_final_leaks = 0; -#endif /* SIZEOF_VOID_P */ +void +_Py_FinalizeAllocatedBlocks(_PyRuntimeState *runtime) +{ + last_final_leaks = get_num_global_allocated_blocks(runtime); + runtime->obmalloc.interpreter_leaks = 0; +} -/* arena_coverage_t members require this to be true */ -#if ARENA_BITS >= 32 -# error "arena size must be < 2^32" +static Py_ssize_t +get_num_global_allocated_blocks(_PyRuntimeState *runtime) +{ + Py_ssize_t total = 0; + if (_PyRuntimeState_GetFinalizing(runtime) != NULL) { + PyInterpreterState *interp = _PyInterpreterState_Main(); + if (interp == NULL) { + /* We are at the very end of runtime finalization. + We can't rely on finalizing->interp since that thread + state is probably already freed, so we don't worry + about it. */ + assert(PyInterpreterState_Head() == NULL); + } + else { + assert(interp != NULL); + /* It is probably the last interpreter but not necessarily. */ + assert(PyInterpreterState_Next(interp) == NULL); + total += _PyInterpreterState_GetAllocatedBlocks(interp); + } + } + else { + HEAD_LOCK(runtime); + PyInterpreterState *interp = PyInterpreterState_Head(); + assert(interp != NULL); +#ifdef Py_DEBUG + int got_main = 0; #endif - -/* the lower bits of the address that are not ignored */ -#define ADDRESS_BITS (POINTER_BITS - IGNORE_BITS) - -#ifdef USE_INTERIOR_NODES -/* number of bits used for MAP_TOP and MAP_MID nodes */ -#define INTERIOR_BITS ((ADDRESS_BITS - ARENA_BITS + 2) / 3) -#else -#define INTERIOR_BITS 0 + for (; interp != NULL; interp = PyInterpreterState_Next(interp)) { +#ifdef Py_DEBUG + if (_Py_IsMainInterpreter(interp)) { + assert(!got_main); + got_main = 1; + assert(has_own_state(interp)); + } #endif - -#define MAP_TOP_BITS INTERIOR_BITS -#define MAP_TOP_LENGTH (1 << MAP_TOP_BITS) -#define MAP_TOP_MASK (MAP_TOP_LENGTH - 1) - -#define MAP_MID_BITS INTERIOR_BITS -#define MAP_MID_LENGTH (1 << MAP_MID_BITS) -#define MAP_MID_MASK (MAP_MID_LENGTH - 1) - -#define MAP_BOT_BITS (ADDRESS_BITS - ARENA_BITS - 2*INTERIOR_BITS) -#define MAP_BOT_LENGTH (1 << MAP_BOT_BITS) -#define MAP_BOT_MASK (MAP_BOT_LENGTH - 1) - -#define MAP_BOT_SHIFT ARENA_BITS -#define MAP_MID_SHIFT (MAP_BOT_BITS + MAP_BOT_SHIFT) -#define MAP_TOP_SHIFT (MAP_MID_BITS + MAP_MID_SHIFT) - -#define AS_UINT(p) ((uintptr_t)(p)) -#define MAP_BOT_INDEX(p) ((AS_UINT(p) >> MAP_BOT_SHIFT) & MAP_BOT_MASK) -#define MAP_MID_INDEX(p) ((AS_UINT(p) >> MAP_MID_SHIFT) & MAP_MID_MASK) -#define MAP_TOP_INDEX(p) ((AS_UINT(p) >> MAP_TOP_SHIFT) & MAP_TOP_MASK) - -#if IGNORE_BITS > 0 -/* Return the ignored part of the pointer address. Those bits should be same - * for all valid pointers if IGNORE_BITS is set correctly. - */ -#define HIGH_BITS(p) (AS_UINT(p) >> ADDRESS_BITS) -#else -#define HIGH_BITS(p) 0 + if (has_own_state(interp)) { + total += _PyInterpreterState_GetAllocatedBlocks(interp); + } + } + HEAD_UNLOCK(runtime); +#ifdef Py_DEBUG + assert(got_main); #endif + } + total += runtime->obmalloc.interpreter_leaks; + total += last_final_leaks; + return total; +} +Py_ssize_t +_Py_GetGlobalAllocatedBlocks(void) +{ + return get_num_global_allocated_blocks(&_PyRuntime); +} -/* This is the leaf of the radix tree. See arena_map_mark_used() for the - * meaning of these members. */ -typedef struct { - int32_t tail_hi; - int32_t tail_lo; -} arena_coverage_t; - -typedef struct arena_map_bot { - /* The members tail_hi and tail_lo are accessed together. So, it - * better to have them as an array of structs, rather than two - * arrays. - */ - arena_coverage_t arenas[MAP_BOT_LENGTH]; -} arena_map_bot_t; - -#ifdef USE_INTERIOR_NODES -typedef struct arena_map_mid { - struct arena_map_bot *ptrs[MAP_MID_LENGTH]; -} arena_map_mid_t; - -typedef struct arena_map_top { - struct arena_map_mid *ptrs[MAP_TOP_LENGTH]; -} arena_map_top_t; -#endif +#if WITH_PYMALLOC_RADIX_TREE +/*==========================================================================*/ +/* radix tree for tracking arena usage. */ -/* The root of radix tree. Note that by initializing like this, the memory - * should be in the BSS. The OS will only memory map pages as the MAP_MID - * nodes get used (OS pages are demand loaded as needed). - */ +#define arena_map_root (state->usage.arena_map_root) #ifdef USE_INTERIOR_NODES -static arena_map_top_t arena_map_root; -/* accounting for number of used interior nodes */ -static int arena_map_mid_count; -static int arena_map_bot_count; -#else -static arena_map_bot_t arena_map_root; +#define arena_map_mid_count (state->usage.arena_map_mid_count) +#define arena_map_bot_count (state->usage.arena_map_bot_count) #endif /* Return a pointer to a bottom tree node, return NULL if it doesn't exist or * it cannot be created */ -static Py_ALWAYS_INLINE arena_map_bot_t * -arena_map_get(block *p, int create) +static inline Py_ALWAYS_INLINE arena_map_bot_t * +arena_map_get(OMState *state, pymem_block *p, int create) { #ifdef USE_INTERIOR_NODES /* sanity check that IGNORE_BITS is correct */ @@ -1507,16 +1069,17 @@ arena_map_get(block *p, int create) /* mark or unmark addresses covered by arena */ static int -arena_map_mark_used(uintptr_t arena_base, int is_used) +arena_map_mark_used(OMState *state, uintptr_t arena_base, int is_used) { /* sanity check that IGNORE_BITS is correct */ assert(HIGH_BITS(arena_base) == HIGH_BITS(&arena_map_root)); - arena_map_bot_t *n_hi = arena_map_get((block *)arena_base, is_used); + arena_map_bot_t *n_hi = arena_map_get( + state, (pymem_block *)arena_base, is_used); if (n_hi == NULL) { assert(is_used); /* otherwise node should already exist */ return 0; /* failed to allocate space for node */ } - int i3 = MAP_BOT_INDEX((block *)arena_base); + int i3 = MAP_BOT_INDEX((pymem_block *)arena_base); int32_t tail = (int32_t)(arena_base & ARENA_SIZE_MASK); if (tail == 0) { /* is ideal arena address */ @@ -1536,7 +1099,8 @@ arena_map_mark_used(uintptr_t arena_base, int is_used) * must overflow to 0. However, that would mean arena_base was * "ideal" and we should not be in this case. */ assert(arena_base < arena_base_next); - arena_map_bot_t *n_lo = arena_map_get((block *)arena_base_next, is_used); + arena_map_bot_t *n_lo = arena_map_get( + state, (pymem_block *)arena_base_next, is_used); if (n_lo == NULL) { assert(is_used); /* otherwise should already exist */ n_hi->arenas[i3].tail_hi = 0; @@ -1551,9 +1115,9 @@ arena_map_mark_used(uintptr_t arena_base, int is_used) /* Return true if 'p' is a pointer inside an obmalloc arena. * _PyObject_Free() calls this so it needs to be very fast. */ static int -arena_map_is_used(block *p) +arena_map_is_used(OMState *state, pymem_block *p) { - arena_map_bot_t *n = arena_map_get(p, 0); + arena_map_bot_t *n = arena_map_get(state, p, 0); if (n == NULL) { return 0; } @@ -1576,16 +1140,17 @@ arena_map_is_used(block *p) * `usable_arenas` to the return value. */ static struct arena_object* -new_arena(void) +new_arena(OMState *state) { struct arena_object* arenaobj; uint excess; /* number of bytes above pool alignment */ void *address; - static int debug_stats = -1; + int debug_stats = _PyRuntime.obmalloc.dump_debug_stats; if (debug_stats == -1) { const char *opt = Py_GETENV("PYTHONMALLOCSTATS"); debug_stats = (opt != NULL && *opt != '\0'); + _PyRuntime.obmalloc.dump_debug_stats = debug_stats; } if (debug_stats) { _PyObject_DebugMallocStats(stderr); @@ -1603,14 +1168,14 @@ new_arena(void) if (numarenas <= maxarenas) return NULL; /* overflow */ #if SIZEOF_SIZE_T <= SIZEOF_INT - if (numarenas > SIZE_MAX / sizeof(*arenas)) + if (numarenas > SIZE_MAX / sizeof(*allarenas)) return NULL; /* overflow */ #endif - nbytes = numarenas * sizeof(*arenas); - arenaobj = (struct arena_object *)PyMem_RawRealloc(arenas, nbytes); + nbytes = numarenas * sizeof(*allarenas); + arenaobj = (struct arena_object *)PyMem_RawRealloc(allarenas, nbytes); if (arenaobj == NULL) return NULL; - arenas = arenaobj; + allarenas = arenaobj; /* We might need to fix pointers that were copied. However, * new_arena only gets called when all the pages in the @@ -1623,13 +1188,13 @@ new_arena(void) /* Put the new arenas on the unused_arena_objects list. */ for (i = maxarenas; i < numarenas; ++i) { - arenas[i].address = 0; /* mark as unassociated */ - arenas[i].nextarena = i < numarenas - 1 ? - &arenas[i+1] : NULL; + allarenas[i].address = 0; /* mark as unassociated */ + allarenas[i].nextarena = i < numarenas - 1 ? + &allarenas[i+1] : NULL; } /* Update globals. */ - unused_arena_objects = &arenas[maxarenas]; + unused_arena_objects = &allarenas[maxarenas]; maxarenas = numarenas; } @@ -1641,7 +1206,7 @@ new_arena(void) address = _PyObject_Arena.alloc(_PyObject_Arena.ctx, ARENA_SIZE); #if WITH_PYMALLOC_RADIX_TREE if (address != NULL) { - if (!arena_map_mark_used((uintptr_t)address, 1)) { + if (!arena_map_mark_used(state, (uintptr_t)address, 1)) { /* marking arena in radix tree failed, abort */ _PyObject_Arena.free(_PyObject_Arena.ctx, address, ARENA_SIZE); address = NULL; @@ -1665,7 +1230,7 @@ new_arena(void) arenaobj->freepools = NULL; /* pool_address <- first pool-aligned address in the arena nfreepools <- number of whole pools that fit after alignment */ - arenaobj->pool_address = (block*)arenaobj->address; + arenaobj->pool_address = (pymem_block*)arenaobj->address; arenaobj->nfreepools = MAX_POOLS_IN_ARENA; excess = (uint)(arenaobj->address & POOL_SIZE_MASK); if (excess != 0) { @@ -1684,9 +1249,9 @@ new_arena(void) pymalloc. When the radix tree is used, 'poolp' is unused. */ static bool -address_in_range(void *p, poolp pool) +address_in_range(OMState *state, void *p, poolp Py_UNUSED(pool)) { - return arena_map_is_used(p); + return arena_map_is_used(state, p); } #else /* @@ -1767,7 +1332,7 @@ extremely desirable that it be this fast. static bool _Py_NO_SANITIZE_ADDRESS _Py_NO_SANITIZE_THREAD _Py_NO_SANITIZE_MEMORY -address_in_range(void *p, poolp pool) +address_in_range(OMState *state, void *p, poolp pool) { // Since address_in_range may be reading from memory which was not allocated // by Python, it is important that pool->arenaindex is read only once, as @@ -1776,8 +1341,8 @@ address_in_range(void *p, poolp pool) // only once. uint arenaindex = *((volatile uint *)&pool->arenaindex); return arenaindex < maxarenas && - (uintptr_t)p - arenas[arenaindex].address < ARENA_SIZE && - arenas[arenaindex].address != 0; + (uintptr_t)p - allarenas[arenaindex].address < ARENA_SIZE && + allarenas[arenaindex].address != 0; } #endif /* !WITH_PYMALLOC_RADIX_TREE */ @@ -1791,9 +1356,9 @@ pymalloc_pool_extend(poolp pool, uint size) { if (UNLIKELY(pool->nextoffset <= pool->maxnextoffset)) { /* There is room for another block. */ - pool->freeblock = (block*)pool + pool->nextoffset; + pool->freeblock = (pymem_block*)pool + pool->nextoffset; pool->nextoffset += INDEX2SIZE(size); - *(block **)(pool->freeblock) = NULL; + *(pymem_block **)(pool->freeblock) = NULL; return; } @@ -1809,7 +1374,7 @@ pymalloc_pool_extend(poolp pool, uint size) * This function takes new pool and allocate a block from it. */ static void* -allocate_from_new_pool(uint size) +allocate_from_new_pool(OMState *state, uint size) { /* There isn't a pool of the right size class immediately * available: use a free pool. @@ -1821,7 +1386,7 @@ allocate_from_new_pool(uint size) return NULL; } #endif - usable_arenas = new_arena(); + usable_arenas = new_arena(state); if (usable_arenas == NULL) { return NULL; } @@ -1873,7 +1438,7 @@ allocate_from_new_pool(uint size) */ assert(usable_arenas->freepools != NULL || usable_arenas->pool_address <= - (block*)usable_arenas->address + + (pymem_block*)usable_arenas->address + ARENA_SIZE - POOL_SIZE); } } @@ -1882,10 +1447,10 @@ allocate_from_new_pool(uint size) assert(usable_arenas->nfreepools > 0); assert(usable_arenas->freepools == NULL); pool = (poolp)usable_arenas->pool_address; - assert((block*)pool <= (block*)usable_arenas->address + + assert((pymem_block*)pool <= (pymem_block*)usable_arenas->address + ARENA_SIZE - POOL_SIZE); - pool->arenaindex = (uint)(usable_arenas - arenas); - assert(&arenas[pool->arenaindex] == usable_arenas); + pool->arenaindex = (uint)(usable_arenas - allarenas); + assert(&allarenas[pool->arenaindex] == usable_arenas); pool->szidx = DUMMY_SIZE_IDX; usable_arenas->pool_address += POOL_SIZE; --usable_arenas->nfreepools; @@ -1904,7 +1469,7 @@ allocate_from_new_pool(uint size) } /* Frontlink to used pools. */ - block *bp; + pymem_block *bp; poolp next = usedpools[size + size]; /* == prev */ pool->nextpool = next; pool->prevpool = next; @@ -1918,7 +1483,7 @@ allocate_from_new_pool(uint size) */ bp = pool->freeblock; assert(bp != NULL); - pool->freeblock = *(block **)bp; + pool->freeblock = *(pymem_block **)bp; return bp; } /* @@ -1928,11 +1493,11 @@ allocate_from_new_pool(uint size) */ pool->szidx = size; size = INDEX2SIZE(size); - bp = (block *)pool + POOL_OVERHEAD; + bp = (pymem_block *)pool + POOL_OVERHEAD; pool->nextoffset = POOL_OVERHEAD + (size << 1); pool->maxnextoffset = POOL_SIZE - size; pool->freeblock = bp + size; - *(block **)(pool->freeblock) = NULL; + *(pymem_block **)(pool->freeblock) = NULL; return bp; } @@ -1945,7 +1510,7 @@ allocate_from_new_pool(uint size) or when the max memory limit has been reached. */ static inline void* -pymalloc_alloc(void *ctx, size_t nbytes) +pymalloc_alloc(OMState *state, void *Py_UNUSED(ctx), size_t nbytes) { #ifdef WITH_VALGRIND if (UNLIKELY(running_on_valgrind == -1)) { @@ -1965,7 +1530,7 @@ pymalloc_alloc(void *ctx, size_t nbytes) uint size = (uint)(nbytes - 1) >> ALIGNMENT_SHIFT; poolp pool = usedpools[size + size]; - block *bp; + pymem_block *bp; if (LIKELY(pool != pool->nextpool)) { /* @@ -1976,7 +1541,7 @@ pymalloc_alloc(void *ctx, size_t nbytes) bp = pool->freeblock; assert(bp != NULL); - if (UNLIKELY((pool->freeblock = *(block **)bp) == NULL)) { + if (UNLIKELY((pool->freeblock = *(pymem_block **)bp) == NULL)) { // Reached the end of the free list, try to extend it. pymalloc_pool_extend(pool, size); } @@ -1985,17 +1550,18 @@ pymalloc_alloc(void *ctx, size_t nbytes) /* There isn't a pool of the right size class immediately * available: use a free pool. */ - bp = allocate_from_new_pool(size); + bp = allocate_from_new_pool(state, size); } return (void *)bp; } -static void * +void * _PyObject_Malloc(void *ctx, size_t nbytes) { - void* ptr = pymalloc_alloc(ctx, nbytes); + OMState *state = get_state(); + void* ptr = pymalloc_alloc(state, ctx, nbytes); if (LIKELY(ptr != NULL)) { return ptr; } @@ -2008,13 +1574,14 @@ _PyObject_Malloc(void *ctx, size_t nbytes) } -static void * +void * _PyObject_Calloc(void *ctx, size_t nelem, size_t elsize) { assert(elsize == 0 || nelem <= (size_t)PY_SSIZE_T_MAX / elsize); size_t nbytes = nelem * elsize; - void* ptr = pymalloc_alloc(ctx, nbytes); + OMState *state = get_state(); + void* ptr = pymalloc_alloc(state, ctx, nbytes); if (LIKELY(ptr != NULL)) { memset(ptr, 0, nbytes); return ptr; @@ -2029,7 +1596,7 @@ _PyObject_Calloc(void *ctx, size_t nelem, size_t elsize) static void -insert_to_usedpool(poolp pool) +insert_to_usedpool(OMState *state, poolp pool) { assert(pool->ref.count > 0); /* else the pool is empty */ @@ -2045,7 +1612,7 @@ insert_to_usedpool(poolp pool) } static void -insert_to_freepool(poolp pool) +insert_to_freepool(OMState *state, poolp pool) { poolp next = pool->nextpool; poolp prev = pool->prevpool; @@ -2055,7 +1622,7 @@ insert_to_freepool(poolp pool) /* Link the pool to freepools. This is a singly-linked * list, and pool->prevpool isn't used there. */ - struct arena_object *ao = &arenas[pool->arenaindex]; + struct arena_object *ao = &allarenas[pool->arenaindex]; pool->nextpool = ao->freepools; ao->freepools = pool; uint nf = ao->nfreepools; @@ -2128,7 +1695,7 @@ insert_to_freepool(poolp pool) #if WITH_PYMALLOC_RADIX_TREE /* mark arena region as not under control of obmalloc */ - arena_map_mark_used(ao->address, 0); + arena_map_mark_used(state, ao->address, 0); #endif /* Free the entire arena. */ @@ -2215,7 +1782,7 @@ insert_to_freepool(poolp pool) Return 1 if it was freed. Return 0 if the block was not allocated by pymalloc_alloc(). */ static inline int -pymalloc_free(void *ctx, void *p) +pymalloc_free(OMState *state, void *Py_UNUSED(ctx), void *p) { assert(p != NULL); @@ -2226,7 +1793,7 @@ pymalloc_free(void *ctx, void *p) #endif poolp pool = POOL_ADDR(p); - if (UNLIKELY(!address_in_range(p, pool))) { + if (UNLIKELY(!address_in_range(state, p, pool))) { return 0; } /* We allocated this address. */ @@ -2238,9 +1805,9 @@ pymalloc_free(void *ctx, void *p) * list in any case). */ assert(pool->ref.count > 0); /* else it was empty */ - block *lastfree = pool->freeblock; - *(block **)p = lastfree; - pool->freeblock = (block *)p; + pymem_block *lastfree = pool->freeblock; + *(pymem_block **)p = lastfree; + pool->freeblock = (pymem_block *)p; pool->ref.count--; if (UNLIKELY(lastfree == NULL)) { @@ -2250,7 +1817,7 @@ pymalloc_free(void *ctx, void *p) * targets optimal filling when several pools contain * blocks of the same size class. */ - insert_to_usedpool(pool); + insert_to_usedpool(state, pool); return 1; } @@ -2267,12 +1834,12 @@ pymalloc_free(void *ctx, void *p) * previously freed pools will be allocated later * (being not referenced, they are perhaps paged out). */ - insert_to_freepool(pool); + insert_to_freepool(state, pool); return 1; } -static void +void _PyObject_Free(void *ctx, void *p) { /* PyObject_Free(NULL) has no effect */ @@ -2280,7 +1847,8 @@ _PyObject_Free(void *ctx, void *p) return; } - if (UNLIKELY(!pymalloc_free(ctx, p))) { + OMState *state = get_state(); + if (UNLIKELY(!pymalloc_free(state, ctx, p))) { /* pymalloc didn't allocate this address */ PyMem_RawFree(p); raw_allocated_blocks--; @@ -2298,7 +1866,8 @@ _PyObject_Free(void *ctx, void *p) Return 0 if pymalloc didn't allocated p. */ static int -pymalloc_realloc(void *ctx, void **newptr_p, void *p, size_t nbytes) +pymalloc_realloc(OMState *state, void *ctx, + void **newptr_p, void *p, size_t nbytes) { void *bp; poolp pool; @@ -2314,7 +1883,7 @@ pymalloc_realloc(void *ctx, void **newptr_p, void *p, size_t nbytes) #endif pool = POOL_ADDR(p); - if (!address_in_range(p, pool)) { + if (!address_in_range(state, p, pool)) { /* pymalloc is not managing this block. If nbytes <= SMALL_REQUEST_THRESHOLD, it's tempting to try to take @@ -2358,7 +1927,7 @@ pymalloc_realloc(void *ctx, void **newptr_p, void *p, size_t nbytes) } -static void * +void * _PyObject_Realloc(void *ctx, void *ptr, size_t nbytes) { void *ptr2; @@ -2367,7 +1936,8 @@ _PyObject_Realloc(void *ctx, void *ptr, size_t nbytes) return _PyObject_Malloc(ctx, nbytes); } - if (pymalloc_realloc(ctx, &ptr2, ptr, nbytes)) { + OMState *state = get_state(); + if (pymalloc_realloc(state, ctx, &ptr2, ptr, nbytes)) { return ptr2; } @@ -2381,11 +1951,29 @@ _PyObject_Realloc(void *ctx, void *ptr, size_t nbytes) * only be used by extensions that are compiled with pymalloc enabled. */ Py_ssize_t -_Py_GetAllocatedBlocks(void) +_PyInterpreterState_GetAllocatedBlocks(PyInterpreterState *Py_UNUSED(interp)) { return 0; } +Py_ssize_t +_Py_GetGlobalAllocatedBlocks(void) +{ + return 0; +} + +void +_PyInterpreterState_FinalizeAllocatedBlocks(PyInterpreterState *Py_UNUSED(interp)) +{ + return; +} + +void +_Py_FinalizeAllocatedBlocks(_PyRuntimeState *Py_UNUSED(runtime)) +{ + return; +} + #endif /* WITH_PYMALLOC */ @@ -2535,13 +2123,13 @@ _PyMem_DebugRawAlloc(int use_calloc, void *ctx, size_t nbytes) return data; } -static void * +void * _PyMem_DebugRawMalloc(void *ctx, size_t nbytes) { return _PyMem_DebugRawAlloc(0, ctx, nbytes); } -static void * +void * _PyMem_DebugRawCalloc(void *ctx, size_t nelem, size_t elsize) { size_t nbytes; @@ -2556,7 +2144,7 @@ _PyMem_DebugRawCalloc(void *ctx, size_t nelem, size_t elsize) Then fills the original bytes with PYMEM_DEADBYTE. Then calls the underlying free. */ -static void +void _PyMem_DebugRawFree(void *ctx, void *p) { /* PyMem_Free(NULL) has no effect */ @@ -2576,7 +2164,7 @@ _PyMem_DebugRawFree(void *ctx, void *p) } -static void * +void * _PyMem_DebugRawRealloc(void *ctx, void *p, size_t nbytes) { if (p == NULL) { @@ -2686,14 +2274,14 @@ _PyMem_DebugCheckGIL(const char *func) } } -static void * +void * _PyMem_DebugMalloc(void *ctx, size_t nbytes) { _PyMem_DebugCheckGIL(__func__); return _PyMem_DebugRawMalloc(ctx, nbytes); } -static void * +void * _PyMem_DebugCalloc(void *ctx, size_t nelem, size_t elsize) { _PyMem_DebugCheckGIL(__func__); @@ -2701,7 +2289,7 @@ _PyMem_DebugCalloc(void *ctx, size_t nelem, size_t elsize) } -static void +void _PyMem_DebugFree(void *ctx, void *ptr) { _PyMem_DebugCheckGIL(__func__); @@ -2709,7 +2297,7 @@ _PyMem_DebugFree(void *ctx, void *ptr) } -static void * +void * _PyMem_DebugRealloc(void *ctx, void *ptr, size_t nbytes) { _PyMem_DebugCheckGIL(__func__); @@ -2960,6 +2548,7 @@ _PyObject_DebugMallocStats(FILE *out) if (!_PyMem_PymallocEnabled()) { return 0; } + OMState *state = get_state(); uint i; const uint numclasses = SMALL_REQUEST_THRESHOLD >> ALIGNMENT_SHIFT; @@ -2999,14 +2588,14 @@ _PyObject_DebugMallocStats(FILE *out) * will be living in full pools -- would be a shame to miss them. */ for (i = 0; i < maxarenas; ++i) { - uintptr_t base = arenas[i].address; + uintptr_t base = allarenas[i].address; /* Skip arenas which are not allocated. */ - if (arenas[i].address == (uintptr_t)NULL) + if (allarenas[i].address == (uintptr_t)NULL) continue; narenas += 1; - numfreepools += arenas[i].nfreepools; + numfreepools += allarenas[i].nfreepools; /* round up to pool alignment */ if (base & (uintptr_t)POOL_SIZE_MASK) { @@ -3016,8 +2605,8 @@ _PyObject_DebugMallocStats(FILE *out) } /* visit every pool in the arena */ - assert(base <= (uintptr_t) arenas[i].pool_address); - for (; base < (uintptr_t) arenas[i].pool_address; base += POOL_SIZE) { + assert(base <= (uintptr_t) allarenas[i].pool_address); + for (; base < (uintptr_t) allarenas[i].pool_address; base += POOL_SIZE) { poolp p = (poolp)base; const uint sz = p->szidx; uint freeblocks; @@ -3025,7 +2614,7 @@ _PyObject_DebugMallocStats(FILE *out) if (p->ref.count == 0) { /* currently unused */ #ifdef Py_DEBUG - assert(pool_is_in_list(p, arenas[i].freepools)); + assert(pool_is_in_list(p, allarenas[i].freepools)); #endif continue; } diff --git a/Objects/odictobject.c b/Objects/odictobject.c index bd2a7677..39b0f684 100644 --- a/Objects/odictobject.c +++ b/Objects/odictobject.c @@ -889,8 +889,7 @@ odict_inplace_or(PyObject *self, PyObject *other) if (mutablemapping_update_arg(self, other) < 0) { return NULL; } - Py_INCREF(self); - return self; + return Py_NewRef(self); } /* tp_as_number */ @@ -1007,8 +1006,7 @@ OrderedDict_setdefault_impl(PyODictObject *self, PyObject *key, return NULL; assert(_odict_find_node(self, key) == NULL); if (PyODict_SetItem((PyObject *)self, key, default_value) >= 0) { - result = default_value; - Py_INCREF(result); + result = Py_NewRef(default_value); } } else { @@ -1024,8 +1022,7 @@ OrderedDict_setdefault_impl(PyODictObject *self, PyObject *key, result = PyObject_GetItem((PyObject *)self, key); } else if (PyObject_SetItem((PyObject *)self, key, default_value) >= 0) { - result = default_value; - Py_INCREF(result); + result = Py_NewRef(default_value); } } @@ -1055,8 +1052,7 @@ _odict_popkey_hash(PyObject *od, PyObject *key, PyObject *failobj, else if (value == NULL && !PyErr_Occurred()) { /* Apply the fallback value, if necessary. */ if (failobj) { - value = failobj; - Py_INCREF(failobj); + value = Py_NewRef(failobj); } else { PyErr_SetObject(PyExc_KeyError, key); @@ -1118,8 +1114,7 @@ OrderedDict_popitem_impl(PyODictObject *self, int last) } node = last ? _odict_LAST(self) : _odict_FIRST(self); - key = _odictnode_KEY(node); - Py_INCREF(key); + key = Py_NewRef(_odictnode_KEY(node)); value = _odict_popkey_hash((PyObject *)self, key, NULL, _odictnode_HASH(node)); if (value == NULL) return NULL; @@ -1372,7 +1367,7 @@ static PyObject * odict_repr(PyODictObject *self) { int i; - PyObject *pieces = NULL, *result = NULL; + PyObject *result = NULL, *dcopy = NULL; if (PyODict_SIZE(self) == 0) return PyUnicode_FromFormat("%s()", _PyType_Name(Py_TYPE(self))); @@ -1382,57 +1377,17 @@ odict_repr(PyODictObject *self) return i > 0 ? PyUnicode_FromString("...") : NULL; } - if (PyODict_CheckExact(self)) { - Py_ssize_t count = 0; - _ODictNode *node; - pieces = PyList_New(PyODict_SIZE(self)); - if (pieces == NULL) - goto Done; - - _odict_FOREACH(self, node) { - PyObject *pair; - PyObject *key = _odictnode_KEY(node); - PyObject *value = _odictnode_VALUE(node, self); - if (value == NULL) { - if (!PyErr_Occurred()) - PyErr_SetObject(PyExc_KeyError, key); - goto Done; - } - pair = PyTuple_Pack(2, key, value); - if (pair == NULL) - goto Done; - - if (count < PyList_GET_SIZE(pieces)) - PyList_SET_ITEM(pieces, count, pair); /* steals reference */ - else { - if (PyList_Append(pieces, pair) < 0) { - Py_DECREF(pair); - goto Done; - } - Py_DECREF(pair); - } - count++; - } - if (count < PyList_GET_SIZE(pieces)) { - Py_SET_SIZE(pieces, count); - } - } - else { - PyObject *items = PyObject_CallMethodNoArgs( - (PyObject *)self, &_Py_ID(items)); - if (items == NULL) - goto Done; - pieces = PySequence_List(items); - Py_DECREF(items); - if (pieces == NULL) - goto Done; + dcopy = PyDict_Copy((PyObject *)self); + if (dcopy == NULL) { + goto Done; } result = PyUnicode_FromFormat("%s(%R)", - _PyType_Name(Py_TYPE(self)), pieces); + _PyType_Name(Py_TYPE(self)), + dcopy); + Py_DECREF(dcopy); Done: - Py_XDECREF(pieces); Py_ReprLeave((PyObject *)self); return result; } @@ -1497,8 +1452,7 @@ odict_richcompare(PyObject *v, PyObject *w, int op) return NULL; res = (eq == (op == Py_EQ)) ? Py_True : Py_False; - Py_INCREF(res); - return res; + return Py_NewRef(res); } else { Py_RETURN_NOTIMPLEMENTED; } @@ -1602,10 +1556,9 @@ _PyODict_SetItem_KnownHash(PyObject *od, PyObject *key, PyObject *value, res = _odict_add_new_node((PyODictObject *)od, key, hash); if (res < 0) { /* Revert setting the value on the dict */ - PyObject *exc, *val, *tb; - PyErr_Fetch(&exc, &val, &tb); + PyObject *exc = PyErr_GetRaisedException(); (void) _PyDict_DelItem_KnownHash(od, key, hash); - _PyErr_ChainExceptions(exc, val, tb); + _PyErr_ChainExceptions1(exc); } } return res; @@ -1714,8 +1667,7 @@ odictiter_nextkey(odictiterobject *di) di->di_current = NULL; } else { - di->di_current = _odictnode_KEY(node); - Py_INCREF(di->di_current); + di->di_current = Py_NewRef(_odictnode_KEY(node)); } return key; @@ -1872,12 +1824,10 @@ odictiter_new(PyODictObject *od, int kind) di->kind = kind; node = reversed ? _odict_LAST(od) : _odict_FIRST(od); - di->di_current = node ? _odictnode_KEY(node) : NULL; - Py_XINCREF(di->di_current); + di->di_current = node ? Py_NewRef(_odictnode_KEY(node)) : NULL; di->di_size = PyODict_SIZE(od); di->di_state = od->od_state; - di->di_odict = od; - Py_INCREF(od); + di->di_odict = (PyODictObject*)Py_NewRef(od); _PyObject_GC_TRACK(di); return (PyObject *)di; diff --git a/Objects/rangeobject.c b/Objects/rangeobject.c index 5d583b2e..beb86b96 100644 --- a/Objects/rangeobject.c +++ b/Objects/rangeobject.c @@ -2,6 +2,7 @@ #include "Python.h" #include "pycore_abstract.h" // _PyIndex_Check() +#include "pycore_range.h" #include "pycore_long.h" // _PyLong_GetZero() #include "pycore_tuple.h" // _PyTuple_ITEMS() #include "structmember.h" // PyMemberDef @@ -32,7 +33,7 @@ validate_step(PyObject *step) return PyLong_FromLong(1); step = PyNumber_Index(step); - if (step && _PyLong_Sign(step) == 0) { + if (step && _PyLong_IsZero((PyLongObject *)step)) { PyErr_SetString(PyExc_ValueError, "range() arg 3 must not be zero"); Py_CLEAR(step); @@ -104,10 +105,8 @@ range_from_array(PyTypeObject *type, PyObject *const *args, Py_ssize_t num_args) if (!stop) { return NULL; } - start = _PyLong_GetZero(); - Py_INCREF(start); - step = _PyLong_GetOne(); - Py_INCREF(step); + start = Py_NewRef(_PyLong_GetZero()); + step = Py_NewRef(_PyLong_GetOne()); break; case 0: PyErr_SetString(PyExc_TypeError, @@ -172,6 +171,49 @@ range_dealloc(rangeobject *r) PyObject_Free(r); } +static unsigned long +get_len_of_range(long lo, long hi, long step); + +/* Return the length as a long, -2 for an overflow and -1 for any other type of error + * + * In case of an overflow no error is set + */ +static long compute_range_length_long(PyObject *start, + PyObject *stop, PyObject *step) { + int overflow = 0; + + long long_start = PyLong_AsLongAndOverflow(start, &overflow); + if (overflow) { + return -2; + } + if (long_start == -1 && PyErr_Occurred()) { + return -1; + } + long long_stop = PyLong_AsLongAndOverflow(stop, &overflow); + if (overflow) { + return -2; + } + if (long_stop == -1 && PyErr_Occurred()) { + return -1; + } + long long_step = PyLong_AsLongAndOverflow(step, &overflow); + if (overflow) { + return -2; + } + if (long_step == -1 && PyErr_Occurred()) { + return -1; + } + + unsigned long ulen = get_len_of_range(long_start, long_stop, long_step); + if (ulen > (unsigned long)LONG_MAX) { + /* length too large for a long */ + return -2; + } + else { + return (long)ulen; + } +} + /* Return number of items in range (lo, hi, step) as a PyLong object, * when arguments are PyLong objects. Arguments MUST return 1 with * PyLong_Check(). Return NULL when there is an error. @@ -192,6 +234,21 @@ compute_range_length(PyObject *start, PyObject *stop, PyObject *step) PyObject *zero = _PyLong_GetZero(); // borrowed reference PyObject *one = _PyLong_GetOne(); // borrowed reference + assert(PyLong_Check(start)); + assert(PyLong_Check(stop)); + assert(PyLong_Check(step)); + + /* fast path when all arguments fit into a long integer */ + long len = compute_range_length_long(start, stop, step); + if (len >= 0) { + return PyLong_FromLong(len); + } + else if (len == -1) { + /* unexpected error from compute_range_length_long, we propagate to the caller */ + return NULL; + } + assert(len == -2); + cmp_result = PyObject_RichCompareBool(step, zero, Py_GT); if (cmp_result == -1) return NULL; @@ -215,8 +272,7 @@ compute_range_length(PyObject *start, PyObject *stop, PyObject *step) if (cmp_result < 0) return NULL; result = zero; - Py_INCREF(result); - return result; + return Py_NewRef(result); } if ((tmp1 = PyNumber_Subtract(hi, lo)) == NULL) @@ -296,8 +352,7 @@ compute_range_item(rangeobject *r, PyObject *arg) return NULL; } } else { - i = arg; - Py_INCREF(i); + i = Py_NewRef(arg); } /* PyLong equivalent to: @@ -521,30 +576,24 @@ range_hash(rangeobject *r) t = PyTuple_New(3); if (!t) return -1; - Py_INCREF(r->length); - PyTuple_SET_ITEM(t, 0, r->length); + PyTuple_SET_ITEM(t, 0, Py_NewRef(r->length)); cmp_result = PyObject_Not(r->length); if (cmp_result == -1) goto end; if (cmp_result == 1) { - Py_INCREF(Py_None); - Py_INCREF(Py_None); - PyTuple_SET_ITEM(t, 1, Py_None); - PyTuple_SET_ITEM(t, 2, Py_None); + PyTuple_SET_ITEM(t, 1, Py_NewRef(Py_None)); + PyTuple_SET_ITEM(t, 2, Py_NewRef(Py_None)); } else { - Py_INCREF(r->start); - PyTuple_SET_ITEM(t, 1, r->start); + PyTuple_SET_ITEM(t, 1, Py_NewRef(r->start)); cmp_result = PyObject_RichCompareBool(r->length, _PyLong_GetOne(), Py_EQ); if (cmp_result == -1) goto end; if (cmp_result == 1) { - Py_INCREF(Py_None); - PyTuple_SET_ITEM(t, 2, Py_None); + PyTuple_SET_ITEM(t, 2, Py_NewRef(Py_None)); } else { - Py_INCREF(r->step); - PyTuple_SET_ITEM(t, 2, r->step); + PyTuple_SET_ITEM(t, 2, Py_NewRef(r->step)); } } result = PyObject_Hash(t); @@ -762,36 +811,29 @@ PyTypeObject PyRange_Type = { in the normal case, but possible for any numeric value. */ -typedef struct { - PyObject_HEAD - long index; - long start; - long step; - long len; -} rangeiterobject; - static PyObject * -rangeiter_next(rangeiterobject *r) +rangeiter_next(_PyRangeIterObject *r) { - if (r->index < r->len) - /* cast to unsigned to avoid possible signed overflow - in intermediate calculations. */ - return PyLong_FromLong((long)(r->start + - (unsigned long)(r->index++) * r->step)); + if (r->len > 0) { + long result = r->start; + r->start = result + r->step; + r->len--; + return PyLong_FromLong(result); + } return NULL; } static PyObject * -rangeiter_len(rangeiterobject *r, PyObject *Py_UNUSED(ignored)) +rangeiter_len(_PyRangeIterObject *r, PyObject *Py_UNUSED(ignored)) { - return PyLong_FromLong(r->len - r->index); + return PyLong_FromLong(r->len); } PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it))."); static PyObject * -rangeiter_reduce(rangeiterobject *r, PyObject *Py_UNUSED(ignored)) +rangeiter_reduce(_PyRangeIterObject *r, PyObject *Py_UNUSED(ignored)) { PyObject *start=NULL, *stop=NULL, *step=NULL; PyObject *range; @@ -811,8 +853,8 @@ rangeiter_reduce(rangeiterobject *r, PyObject *Py_UNUSED(ignored)) if (range == NULL) goto err; /* return the result */ - return Py_BuildValue( - "N(N)l", _PyEval_GetBuiltin(&_Py_ID(iter)), range, r->index); + return Py_BuildValue("N(N)O", _PyEval_GetBuiltin(&_Py_ID(iter)), + range, Py_None); err: Py_XDECREF(start); Py_XDECREF(stop); @@ -821,7 +863,7 @@ err: } static PyObject * -rangeiter_setstate(rangeiterobject *r, PyObject *state) +rangeiter_setstate(_PyRangeIterObject *r, PyObject *state) { long index = PyLong_AsLong(state); if (index == -1 && PyErr_Occurred()) @@ -831,7 +873,8 @@ rangeiter_setstate(rangeiterobject *r, PyObject *state) index = 0; else if (index > r->len) index = r->len; /* exhausted iterator */ - r->index = index; + r->start += index * r->step; + r->len -= index; Py_RETURN_NONE; } @@ -850,8 +893,8 @@ static PyMethodDef rangeiter_methods[] = { PyTypeObject PyRangeIter_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) - "range_iterator", /* tp_name */ - sizeof(rangeiterobject), /* tp_basicsize */ + "range_iterator", /* tp_name */ + sizeof(_PyRangeIterObject), /* tp_basicsize */ 0, /* tp_itemsize */ /* methods */ (destructor)PyObject_Del, /* tp_dealloc */ @@ -915,19 +958,17 @@ get_len_of_range(long lo, long hi, long step) static PyObject * fast_range_iter(long start, long stop, long step, long len) { - rangeiterobject *it = PyObject_New(rangeiterobject, &PyRangeIter_Type); + _PyRangeIterObject *it = PyObject_New(_PyRangeIterObject, &PyRangeIter_Type); if (it == NULL) return NULL; it->start = start; it->step = step; it->len = len; - it->index = 0; return (PyObject *)it; } typedef struct { PyObject_HEAD - PyObject *index; PyObject *start; PyObject *step; PyObject *len; @@ -936,7 +977,8 @@ typedef struct { static PyObject * longrangeiter_len(longrangeiterobject *r, PyObject *no_args) { - return PyNumber_Subtract(r->len, r->index); + Py_INCREF(r->len); + return r->len; } static PyObject * @@ -953,10 +995,8 @@ longrangeiter_reduce(longrangeiterobject *r, PyObject *Py_UNUSED(ignored)) Py_DECREF(product); if (stop == NULL) return NULL; - Py_INCREF(r->start); - Py_INCREF(r->step); range = (PyObject*)make_range_object(&PyRange_Type, - r->start, stop, r->step); + Py_NewRef(r->start), stop, Py_NewRef(r->step)); if (range == NULL) { Py_DECREF(r->start); Py_DECREF(stop); @@ -965,8 +1005,8 @@ longrangeiter_reduce(longrangeiterobject *r, PyObject *Py_UNUSED(ignored)) } /* return the result */ - return Py_BuildValue( - "N(N)O", _PyEval_GetBuiltin(&_Py_ID(iter)), range, r->index); + return Py_BuildValue("N(N)O", _PyEval_GetBuiltin(&_Py_ID(iter)), + range, Py_None); } static PyObject * @@ -989,8 +1029,22 @@ longrangeiter_setstate(longrangeiterobject *r, PyObject *state) if (cmp > 0) state = r->len; } - Py_INCREF(state); - Py_XSETREF(r->index, state); + PyObject *product = PyNumber_Multiply(state, r->step); + if (product == NULL) + return NULL; + PyObject *new_start = PyNumber_Add(r->start, product); + Py_DECREF(product); + if (new_start == NULL) + return NULL; + PyObject *new_len = PyNumber_Subtract(r->len, state); + if (new_len == NULL) { + Py_DECREF(new_start); + return NULL; + } + PyObject *tmp = r->start; + r->start = new_start; + Py_SETREF(r->len, new_len); + Py_DECREF(tmp); Py_RETURN_NONE; } @@ -1007,7 +1061,6 @@ static PyMethodDef longrangeiter_methods[] = { static void longrangeiter_dealloc(longrangeiterobject *r) { - Py_XDECREF(r->index); Py_XDECREF(r->start); Py_XDECREF(r->step); Py_XDECREF(r->len); @@ -1017,29 +1070,21 @@ longrangeiter_dealloc(longrangeiterobject *r) static PyObject * longrangeiter_next(longrangeiterobject *r) { - PyObject *product, *new_index, *result; - if (PyObject_RichCompareBool(r->index, r->len, Py_LT) != 1) + if (PyObject_RichCompareBool(r->len, _PyLong_GetZero(), Py_GT) != 1) return NULL; - new_index = PyNumber_Add(r->index, _PyLong_GetOne()); - if (!new_index) - return NULL; - - product = PyNumber_Multiply(r->index, r->step); - if (!product) { - Py_DECREF(new_index); + PyObject *new_start = PyNumber_Add(r->start, r->step); + if (new_start == NULL) { return NULL; } - - result = PyNumber_Add(r->start, product); - Py_DECREF(product); - if (result) { - Py_SETREF(r->index, new_index); - } - else { - Py_DECREF(new_index); + PyObject *new_len = PyNumber_Subtract(r->len, _PyLong_GetOne()); + if (new_len == NULL) { + Py_DECREF(new_start); + return NULL; } - + PyObject *result = r->start; + r->start = new_start; + Py_SETREF(r->len, new_len); return result; } @@ -1125,14 +1170,9 @@ range_iter(PyObject *seq) if (it == NULL) return NULL; - it->start = r->start; - it->step = r->step; - it->len = r->length; - it->index = _PyLong_GetZero(); - Py_INCREF(it->start); - Py_INCREF(it->step); - Py_INCREF(it->len); - Py_INCREF(it->index); + it->start = Py_NewRef(r->start); + it->step = Py_NewRef(r->step); + it->len = Py_NewRef(r->length); return (PyObject *)it; } @@ -1210,11 +1250,10 @@ long_range: it = PyObject_New(longrangeiterobject, &PyLongRangeIter_Type); if (it == NULL) return NULL; - it->index = it->start = it->step = NULL; + it->start = it->step = NULL; /* start + (len - 1) * step */ - it->len = range->length; - Py_INCREF(it->len); + it->len = Py_NewRef(range->length); diff = PyNumber_Subtract(it->len, _PyLong_GetOne()); if (!diff) @@ -1235,8 +1274,6 @@ long_range: if (!it->step) goto create_failure; - it->index = _PyLong_GetZero(); - Py_INCREF(it->index); return (PyObject *)it; create_failure: diff --git a/Objects/setobject.c b/Objects/setobject.c index 4b6a8b8d..58f0ae73 100644 --- a/Objects/setobject.c +++ b/Objects/setobject.c @@ -588,8 +588,7 @@ set_merge(PySetObject *so, PyObject *otherset) key = other_entry->key; if (key != NULL) { assert(so_entry->key == NULL); - Py_INCREF(key); - so_entry->key = key; + so_entry->key = Py_NewRef(key); so_entry->hash = other_entry->hash; } } @@ -607,8 +606,8 @@ set_merge(PySetObject *so, PyObject *otherset) for (i = other->mask + 1; i > 0 ; i--, other_entry++) { key = other_entry->key; if (key != NULL && key != dummy) { - Py_INCREF(key); - set_insert_clean(newtable, newmask, key, other_entry->hash); + set_insert_clean(newtable, newmask, Py_NewRef(key), + other_entry->hash); } } return 0; @@ -820,8 +819,7 @@ static PyObject *setiter_iternext(setiterobject *si) goto fail; si->len--; key = entry[i].key; - Py_INCREF(key); - return key; + return Py_NewRef(key); fail: si->si_set = NULL; @@ -868,8 +866,7 @@ set_iter(PySetObject *so) setiterobject *si = PyObject_GC_New(setiterobject, &PySetIter_Type); if (si == NULL) return NULL; - Py_INCREF(so); - si->si_set = so; + si->si_set = (PySetObject*)Py_NewRef(so); si->si_used = so->used; si->si_pos = 0; si->len = so->used; @@ -997,8 +994,7 @@ make_new_frozenset(PyTypeObject *type, PyObject *iterable) if (iterable != NULL && PyFrozenSet_CheckExact(iterable)) { /* frozenset(f) is idempotent */ - Py_INCREF(iterable); - return iterable; + return Py_NewRef(iterable); } return make_new_set(type, iterable); } @@ -1100,8 +1096,7 @@ static PyObject * frozenset_copy(PySetObject *so, PyObject *Py_UNUSED(ignored)) { if (PyFrozenSet_CheckExact(so)) { - Py_INCREF(so); - return (PyObject *)so; + return Py_NewRef(so); } return set_copy(so, NULL); } @@ -1173,8 +1168,7 @@ set_ior(PySetObject *so, PyObject *other) if (set_update_internal(so, other)) return NULL; - Py_INCREF(so); - return (PyObject *)so; + return Py_NewRef(so); } static PyObject * @@ -1264,12 +1258,11 @@ static PyObject * set_intersection_multi(PySetObject *so, PyObject *args) { Py_ssize_t i; - PyObject *result = (PyObject *)so; if (PyTuple_GET_SIZE(args) == 0) return set_copy(so, NULL); - Py_INCREF(so); + PyObject *result = Py_NewRef(so); for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) { PyObject *other = PyTuple_GET_ITEM(args, i); PyObject *newresult = set_intersection((PySetObject *)result, other); @@ -1277,8 +1270,7 @@ set_intersection_multi(PySetObject *so, PyObject *args) Py_DECREF(result); return NULL; } - Py_DECREF(result); - result = newresult; + Py_SETREF(result, newresult); } return result; } @@ -1336,8 +1328,7 @@ set_iand(PySetObject *so, PyObject *other) if (result == NULL) return NULL; Py_DECREF(result); - Py_INCREF(so); - return (PyObject *)so; + return Py_NewRef(so); } static PyObject * @@ -1609,8 +1600,7 @@ set_isub(PySetObject *so, PyObject *other) Py_RETURN_NOTIMPLEMENTED; if (set_difference_update_internal(so, other)) return NULL; - Py_INCREF(so); - return (PyObject *)so; + return Py_NewRef(so); } static PyObject * @@ -1647,8 +1637,7 @@ set_symmetric_difference_update(PySetObject *so, PyObject *other) } if (PyAnySet_Check(other)) { - Py_INCREF(other); - otherset = (PySetObject *)other; + otherset = (PySetObject *)Py_NewRef(other); } else { otherset = (PySetObject *)make_new_set_basetype(Py_TYPE(so), other); if (otherset == NULL) @@ -1723,8 +1712,7 @@ set_ixor(PySetObject *so, PyObject *other) if (result == NULL) return NULL; Py_DECREF(result); - Py_INCREF(so); - return (PyObject *)so; + return Py_NewRef(so); } static PyObject * @@ -1735,13 +1723,13 @@ set_issubset(PySetObject *so, PyObject *other) int rv; if (!PyAnySet_Check(other)) { - PyObject *tmp, *result; - tmp = make_new_set(&PySet_Type, other); - if (tmp == NULL) + PyObject *tmp = set_intersection(so, other); + if (tmp == NULL) { return NULL; - result = set_issubset(so, tmp); + } + int result = (PySet_GET_SIZE(tmp) == PySet_GET_SIZE(so)); Py_DECREF(tmp); - return result; + return PyBool_FromLong(result); } if (PySet_GET_SIZE(so) > PySet_GET_SIZE(other)) Py_RETURN_FALSE; @@ -1969,12 +1957,11 @@ done: static PyObject * set_sizeof(PySetObject *so, PyObject *Py_UNUSED(ignored)) { - Py_ssize_t res; - - res = _PyObject_SIZE(Py_TYPE(so)); - if (so->table != so->smalltable) - res = res + (so->mask + 1) * sizeof(setentry); - return PyLong_FromSsize_t(res); + size_t res = _PyObject_SIZE(Py_TYPE(so)); + if (so->table != so->smalltable) { + res += ((size_t)so->mask + 1) * sizeof(setentry); + } + return PyLong_FromSize_t(res); } PyDoc_STRVAR(sizeof_doc, "S.__sizeof__() -> size of S in memory, in bytes"); @@ -2556,6 +2543,7 @@ static PyTypeObject _PySetDummy_Type = { }; static PyObject _dummy_struct = { - _PyObject_EXTRA_INIT - 2, &_PySetDummy_Type + _PyObject_EXTRA_INIT + { _Py_IMMORTAL_REFCNT }, + &_PySetDummy_Type }; diff --git a/Objects/sliceobject.c b/Objects/sliceobject.c index 713829da..e6776ac9 100644 --- a/Objects/sliceobject.c +++ b/Objects/sliceobject.c @@ -26,8 +26,17 @@ ellipsis_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) PyErr_SetString(PyExc_TypeError, "EllipsisType takes no arguments"); return NULL; } - Py_INCREF(Py_Ellipsis); - return Py_Ellipsis; + return Py_NewRef(Py_Ellipsis); +} + +static void +ellipsis_dealloc(PyObject *ellipsis) +{ + /* This should never get called, but we also don't want to SEGV if + * we accidentally decref Ellipsis out of existence. Instead, + * since Ellipsis is an immortal object, re-set the reference count. + */ + _Py_SetImmortal(ellipsis); } static PyObject * @@ -52,7 +61,7 @@ PyTypeObject PyEllipsis_Type = { "ellipsis", /* tp_name */ 0, /* tp_basicsize */ 0, /* tp_itemsize */ - 0, /*never called*/ /* tp_dealloc */ + ellipsis_dealloc, /* tp_dealloc */ 0, /* tp_vectorcall_offset */ 0, /* tp_getattr */ 0, /* tp_setattr */ @@ -90,7 +99,8 @@ PyTypeObject PyEllipsis_Type = { PyObject _Py_EllipsisObject = { _PyObject_EXTRA_INIT - 1, &PyEllipsis_Type + { _Py_IMMORTAL_REFCNT }, + &PyEllipsis_Type }; @@ -110,18 +120,10 @@ void _PySlice_Fini(PyInterpreterState *interp) index is present. */ -PyObject * -PySlice_New(PyObject *start, PyObject *stop, PyObject *step) +static PySliceObject * +_PyBuildSlice_Consume2(PyObject *start, PyObject *stop, PyObject *step) { - if (step == NULL) { - step = Py_None; - } - if (start == NULL) { - start = Py_None; - } - if (stop == NULL) { - stop = Py_None; - } + assert(start != NULL && stop != NULL && step != NULL); PyInterpreterState *interp = _PyInterpreterState_GET(); PySliceObject *obj; @@ -133,19 +135,43 @@ PySlice_New(PyObject *start, PyObject *stop, PyObject *step) else { obj = PyObject_GC_New(PySliceObject, &PySlice_Type); if (obj == NULL) { - return NULL; + goto error; } } - Py_INCREF(step); - obj->step = step; - Py_INCREF(start); obj->start = start; - Py_INCREF(stop); obj->stop = stop; + obj->step = Py_NewRef(step); _PyObject_GC_TRACK(obj); - return (PyObject *) obj; + return obj; +error: + Py_DECREF(start); + Py_DECREF(stop); + return NULL; +} + +PyObject * +PySlice_New(PyObject *start, PyObject *stop, PyObject *step) +{ + if (step == NULL) { + step = Py_None; + } + if (start == NULL) { + start = Py_None; + } + if (stop == NULL) { + stop = Py_None; + } + return (PyObject *)_PyBuildSlice_Consume2(Py_NewRef(start), + Py_NewRef(stop), step); +} + +PyObject * +_PyBuildSlice_ConsumeRefs(PyObject *start, PyObject *stop) +{ + assert(start != NULL && stop != NULL); + return (PyObject *)_PyBuildSlice_Consume2(start, stop, Py_None); } PyObject * @@ -389,8 +415,7 @@ _PySlice_GetLongIndices(PySliceObject *self, PyObject *length, /* Convert step to an integer; raise for zero step. */ if (self->step == Py_None) { - step = _PyLong_GetOne(); - Py_INCREF(step); + step = Py_NewRef(_PyLong_GetOne()); step_is_negative = 0; } else { @@ -418,27 +443,23 @@ _PySlice_GetLongIndices(PySliceObject *self, PyObject *length, goto error; } else { - lower = _PyLong_GetZero(); - Py_INCREF(lower); - upper = length; - Py_INCREF(upper); + lower = Py_NewRef(_PyLong_GetZero()); + upper = Py_NewRef(length); } /* Compute start. */ if (self->start == Py_None) { - start = step_is_negative ? upper : lower; - Py_INCREF(start); + start = Py_NewRef(step_is_negative ? upper : lower); } else { start = evaluate_slice_index(self->start); if (start == NULL) goto error; - if (_PyLong_Sign(start) < 0) { + if (_PyLong_IsNegative((PyLongObject *)start)) { /* start += length */ PyObject *tmp = PyNumber_Add(start, length); - Py_DECREF(start); - start = tmp; + Py_SETREF(start, tmp); if (start == NULL) goto error; @@ -446,9 +467,7 @@ _PySlice_GetLongIndices(PySliceObject *self, PyObject *length, if (cmp_result < 0) goto error; if (cmp_result) { - Py_INCREF(lower); - Py_DECREF(start); - start = lower; + Py_SETREF(start, Py_NewRef(lower)); } } else { @@ -456,28 +475,24 @@ _PySlice_GetLongIndices(PySliceObject *self, PyObject *length, if (cmp_result < 0) goto error; if (cmp_result) { - Py_INCREF(upper); - Py_DECREF(start); - start = upper; + Py_SETREF(start, Py_NewRef(upper)); } } } /* Compute stop. */ if (self->stop == Py_None) { - stop = step_is_negative ? lower : upper; - Py_INCREF(stop); + stop = Py_NewRef(step_is_negative ? lower : upper); } else { stop = evaluate_slice_index(self->stop); if (stop == NULL) goto error; - if (_PyLong_Sign(stop) < 0) { + if (_PyLong_IsNegative((PyLongObject *)stop)) { /* stop += length */ PyObject *tmp = PyNumber_Add(stop, length); - Py_DECREF(stop); - stop = tmp; + Py_SETREF(stop, tmp); if (stop == NULL) goto error; @@ -485,9 +500,7 @@ _PySlice_GetLongIndices(PySliceObject *self, PyObject *length, if (cmp_result < 0) goto error; if (cmp_result) { - Py_INCREF(lower); - Py_DECREF(stop); - stop = lower; + Py_SETREF(stop, Py_NewRef(lower)); } } else { @@ -495,9 +508,7 @@ _PySlice_GetLongIndices(PySliceObject *self, PyObject *length, if (cmp_result < 0) goto error; if (cmp_result) { - Py_INCREF(upper); - Py_DECREF(stop); - stop = upper; + Py_SETREF(stop, Py_NewRef(upper)); } } } @@ -533,7 +544,7 @@ slice_indices(PySliceObject* self, PyObject* len) if (length == NULL) return NULL; - if (_PyLong_Sign(length) < 0) { + if (_PyLong_IsNegative((PyLongObject *)length)) { PyErr_SetString(PyExc_ValueError, "length should not be negative"); Py_DECREF(length); @@ -592,8 +603,7 @@ slice_richcompare(PyObject *v, PyObject *w, int op) res = Py_False; break; } - Py_INCREF(res); - return res; + return Py_NewRef(res); } @@ -629,6 +639,42 @@ slice_traverse(PySliceObject *v, visitproc visit, void *arg) return 0; } +/* code based on tuplehash() of Objects/tupleobject.c */ +#if SIZEOF_PY_UHASH_T > 4 +#define _PyHASH_XXPRIME_1 ((Py_uhash_t)11400714785074694791ULL) +#define _PyHASH_XXPRIME_2 ((Py_uhash_t)14029467366897019727ULL) +#define _PyHASH_XXPRIME_5 ((Py_uhash_t)2870177450012600261ULL) +#define _PyHASH_XXROTATE(x) ((x << 31) | (x >> 33)) /* Rotate left 31 bits */ +#else +#define _PyHASH_XXPRIME_1 ((Py_uhash_t)2654435761UL) +#define _PyHASH_XXPRIME_2 ((Py_uhash_t)2246822519UL) +#define _PyHASH_XXPRIME_5 ((Py_uhash_t)374761393UL) +#define _PyHASH_XXROTATE(x) ((x << 13) | (x >> 19)) /* Rotate left 13 bits */ +#endif + +static Py_hash_t +slicehash(PySliceObject *v) +{ + Py_uhash_t acc = _PyHASH_XXPRIME_5; +#define _PyHASH_SLICE_PART(com) { \ + Py_uhash_t lane = PyObject_Hash(v->com); \ + if(lane == (Py_uhash_t)-1) { \ + return -1; \ + } \ + acc += lane * _PyHASH_XXPRIME_2; \ + acc = _PyHASH_XXROTATE(acc); \ + acc *= _PyHASH_XXPRIME_1; \ +} + _PyHASH_SLICE_PART(start); + _PyHASH_SLICE_PART(stop); + _PyHASH_SLICE_PART(step); +#undef _PyHASH_SLICE_PART + if(acc == (Py_uhash_t)-1) { + return 1546275796; + } + return acc; +} + PyTypeObject PySlice_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "slice", /* Name of this type */ @@ -643,7 +689,7 @@ PyTypeObject PySlice_Type = { 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ - PyObject_HashNotImplemented, /* tp_hash */ + (hashfunc)slicehash, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ PyObject_GenericGetAttr, /* tp_getattro */ diff --git a/Objects/stringlib/asciilib.h b/Objects/stringlib/asciilib.h index eebe888e..b3016bfb 100644 --- a/Objects/stringlib/asciilib.h +++ b/Objects/stringlib/asciilib.h @@ -21,6 +21,7 @@ #define STRINGLIB_CHECK PyUnicode_Check #define STRINGLIB_CHECK_EXACT PyUnicode_CheckExact #define STRINGLIB_MUTABLE 0 +#define STRINGLIB_FAST_MEMCHR memchr #define STRINGLIB_TOSTR PyObject_Str #define STRINGLIB_TOASCII PyObject_ASCII diff --git a/Objects/stringlib/clinic/transmogrify.h.h b/Objects/stringlib/clinic/transmogrify.h.h index b88517bd..49388cf0 100644 --- a/Objects/stringlib/clinic/transmogrify.h.h +++ b/Objects/stringlib/clinic/transmogrify.h.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(stringlib_expandtabs__doc__, "expandtabs($self, /, tabsize=8)\n" "--\n" @@ -20,8 +26,31 @@ static PyObject * stringlib_expandtabs(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(tabsize), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"tabsize", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "expandtabs", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "expandtabs", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int tabsize = 8; @@ -249,4 +278,4 @@ stringlib_zfill(PyObject *self, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=46d058103bffedf7 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=d44a269805f6739e input=a9049054013a1b77]*/ diff --git a/Objects/stringlib/count.h b/Objects/stringlib/count.h index f48500bf..e20edcd1 100644 --- a/Objects/stringlib/count.h +++ b/Objects/stringlib/count.h @@ -4,6 +4,11 @@ #error must include "stringlib/fastsearch.h" before including this module #endif +// gh-97982: Implementing asciilib_count() is not worth it, FASTSEARCH() does +// not specialize the code for ASCII strings. Use ucs1lib_count() for ASCII and +// UCS1 strings: it's the same than asciilib_count(). +#if !STRINGLIB_IS_UNICODE || STRINGLIB_MAX_CHAR > 0x7Fu + Py_LOCAL_INLINE(Py_ssize_t) STRINGLIB(count)(const STRINGLIB_CHAR* str, Py_ssize_t str_len, const STRINGLIB_CHAR* sub, Py_ssize_t sub_len, @@ -24,4 +29,4 @@ STRINGLIB(count)(const STRINGLIB_CHAR* str, Py_ssize_t str_len, return count; } - +#endif diff --git a/Objects/stringlib/eq.h b/Objects/stringlib/eq.h index 9c1058b8..2eac4baf 100644 --- a/Objects/stringlib/eq.h +++ b/Objects/stringlib/eq.h @@ -4,16 +4,8 @@ * unicode_eq() is called when the hash of two unicode objects is equal. */ Py_LOCAL_INLINE(int) -unicode_eq(PyObject *aa, PyObject *bb) +unicode_eq(PyObject *a, PyObject *b) { - assert(PyUnicode_Check(aa)); - assert(PyUnicode_Check(bb)); - assert(PyUnicode_IS_READY(aa)); - assert(PyUnicode_IS_READY(bb)); - - PyUnicodeObject *a = (PyUnicodeObject *)aa; - PyUnicodeObject *b = (PyUnicodeObject *)bb; - if (PyUnicode_GET_LENGTH(a) != PyUnicode_GET_LENGTH(b)) return 0; if (PyUnicode_GET_LENGTH(a) == 0) diff --git a/Objects/stringlib/fastsearch.h b/Objects/stringlib/fastsearch.h index 7403d8a3..257b7bd6 100644 --- a/Objects/stringlib/fastsearch.h +++ b/Objects/stringlib/fastsearch.h @@ -18,7 +18,8 @@ algorithm, which has worst-case O(n) runtime and best-case O(n/k). Also compute a table of shifts to achieve O(n/k) in more cases, and often (data dependent) deduce larger shifts than pure C&P can - deduce. */ + deduce. See stringlib_find_two_way_notes.txt in this folder for a + detailed explanation. */ #define FAST_COUNT 0 #define FAST_SEARCH 1 @@ -39,7 +40,7 @@ #define STRINGLIB_BLOOM(mask, ch) \ ((mask & (1UL << ((ch) & (STRINGLIB_BLOOM_WIDTH -1))))) -#if STRINGLIB_SIZEOF_CHAR == 1 +#ifdef STRINGLIB_FAST_MEMCHR # define MEMCHR_CUT_OFF 15 #else # define MEMCHR_CUT_OFF 40 @@ -53,8 +54,8 @@ STRINGLIB(find_char)(const STRINGLIB_CHAR* s, Py_ssize_t n, STRINGLIB_CHAR ch) p = s; e = s + n; if (n > MEMCHR_CUT_OFF) { -#if STRINGLIB_SIZEOF_CHAR == 1 - p = memchr(s, ch, n); +#ifdef STRINGLIB_FAST_MEMCHR + p = STRINGLIB_FAST_MEMCHR(s, ch, n); if (p != NULL) return (p - s); return -1; @@ -102,16 +103,26 @@ STRINGLIB(find_char)(const STRINGLIB_CHAR* s, Py_ssize_t n, STRINGLIB_CHAR ch) return -1; } +#undef MEMCHR_CUT_OFF + +#if STRINGLIB_SIZEOF_CHAR == 1 +# define MEMRCHR_CUT_OFF 15 +#else +# define MEMRCHR_CUT_OFF 40 +#endif + + Py_LOCAL_INLINE(Py_ssize_t) STRINGLIB(rfind_char)(const STRINGLIB_CHAR* s, Py_ssize_t n, STRINGLIB_CHAR ch) { const STRINGLIB_CHAR *p; #ifdef HAVE_MEMRCHR - /* memrchr() is a GNU extension, available since glibc 2.1.91. - it doesn't seem as optimized as memchr(), but is still quite - faster than our hand-written loop below */ + /* memrchr() is a GNU extension, available since glibc 2.1.91. it + doesn't seem as optimized as memchr(), but is still quite + faster than our hand-written loop below. There is no wmemrchr + for 4-byte chars. */ - if (n > MEMCHR_CUT_OFF) { + if (n > MEMRCHR_CUT_OFF) { #if STRINGLIB_SIZEOF_CHAR == 1 p = memrchr(s, ch, n); if (p != NULL) @@ -139,11 +150,11 @@ STRINGLIB(rfind_char)(const STRINGLIB_CHAR* s, Py_ssize_t n, STRINGLIB_CHAR ch) if (*p == ch) return n; /* False positive */ - if (n1 - n > MEMCHR_CUT_OFF) + if (n1 - n > MEMRCHR_CUT_OFF) continue; - if (n <= MEMCHR_CUT_OFF) + if (n <= MEMRCHR_CUT_OFF) break; - s1 = p - MEMCHR_CUT_OFF; + s1 = p - MEMRCHR_CUT_OFF; while (p > s1) { p--; if (*p == ch) @@ -151,7 +162,7 @@ STRINGLIB(rfind_char)(const STRINGLIB_CHAR* s, Py_ssize_t n, STRINGLIB_CHAR ch) } n = p - s; } - while (n > MEMCHR_CUT_OFF); + while (n > MEMRCHR_CUT_OFF); } #endif } @@ -165,7 +176,7 @@ STRINGLIB(rfind_char)(const STRINGLIB_CHAR* s, Py_ssize_t n, STRINGLIB_CHAR ch) return -1; } -#undef MEMCHR_CUT_OFF +#undef MEMRCHR_CUT_OFF /* Change to a 1 to see logging comments walk through the algorithm. */ #if 0 && STRINGLIB_SIZEOF_CHAR == 1 @@ -388,7 +399,7 @@ STRINGLIB(_two_way)(const STRINGLIB_CHAR *haystack, Py_ssize_t len_haystack, if (window_last >= haystack_end) { return -1; } - LOG("Horspool skip"); + LOG("Horspool skip\n"); } no_shift: window = window_last - len_needle + 1; @@ -447,7 +458,7 @@ STRINGLIB(_two_way)(const STRINGLIB_CHAR *haystack, Py_ssize_t len_haystack, if (window_last >= haystack_end) { return -1; } - LOG("Horspool skip"); + LOG("Horspool skip\n"); } window = window_last - len_needle + 1; assert((window[len_needle - 1] & TABLE_MASK) == diff --git a/Objects/stringlib/join.h b/Objects/stringlib/join.h index bb011f7d..de6bd83f 100644 --- a/Objects/stringlib/join.h +++ b/Objects/stringlib/join.h @@ -63,8 +63,7 @@ STRINGLIB(bytes_join)(PyObject *sep, PyObject *iterable) item = PySequence_Fast_GET_ITEM(seq, i); if (PyBytes_CheckExact(item)) { /* Fast path. */ - Py_INCREF(item); - buffers[i].obj = item; + buffers[i].obj = Py_NewRef(item); buffers[i].buf = PyBytes_AS_STRING(item); buffers[i].len = PyBytes_GET_SIZE(item); } diff --git a/Objects/stringlib/localeutil.h b/Objects/stringlib/localeutil.h index bd16e0a1..d77715ec 100644 --- a/Objects/stringlib/localeutil.h +++ b/Objects/stringlib/localeutil.h @@ -75,7 +75,7 @@ InsertThousandsGrouping_fill(_PyUnicodeWriter *writer, Py_ssize_t *buffer_pos, if (n_zeros) { *buffer_pos -= n_zeros; - enum PyUnicode_Kind kind = PyUnicode_KIND(writer->buffer); + int kind = PyUnicode_KIND(writer->buffer); void *data = PyUnicode_DATA(writer->buffer); unicode_fill(kind, data, '0', *buffer_pos, n_zeros); } diff --git a/Objects/stringlib/replace.h b/Objects/stringlib/replace.h index ef318ed6..123c9f85 100644 --- a/Objects/stringlib/replace.h +++ b/Objects/stringlib/replace.h @@ -29,9 +29,9 @@ STRINGLIB(replace_1char_inplace)(STRINGLIB_CHAR* s, STRINGLIB_CHAR* end, if (!--attempts) { /* if u1 was not found for attempts iterations, use FASTSEARCH() or memchr() */ -#if STRINGLIB_SIZEOF_CHAR == 1 +#ifdef STRINGLIB_FAST_MEMCHR s++; - s = memchr(s, u1, end - s); + s = STRINGLIB_FAST_MEMCHR(s, u1, end - s); if (s == NULL) return; #else diff --git a/Objects/stringlib/stringdefs.h b/Objects/stringlib/stringdefs.h index 88641b25..484b98b7 100644 --- a/Objects/stringlib/stringdefs.h +++ b/Objects/stringlib/stringdefs.h @@ -24,4 +24,5 @@ #define STRINGLIB_CHECK_EXACT PyBytes_CheckExact #define STRINGLIB_TOSTR PyObject_Str #define STRINGLIB_TOASCII PyObject_Repr +#define STRINGLIB_FAST_MEMCHR memchr #endif /* !STRINGLIB_STRINGDEFS_H */ diff --git a/Objects/stringlib/stringlib_find_two_way_notes.txt b/Objects/stringlib/stringlib_find_two_way_notes.txt index afe45431..f97615b4 100644 --- a/Objects/stringlib/stringlib_find_two_way_notes.txt +++ b/Objects/stringlib/stringlib_find_two_way_notes.txt @@ -239,7 +239,7 @@ We cut as AA + bAAbAAbA, and then the algorithm runs as follows: ~~ AA != bA at the cut bbbAbbAAbAAbAAbbbAAbAAbAAbAA AAbAAbAAbA - ^^^^X 7-3=4 match, and the 5th misses. + ^^^^X 7-3=4 match, and the 5th misses. bbbAbbAAbAAbAAbbbAAbAAbAAbAA AAbAAbAAbA ~ A != b at the cut @@ -395,7 +395,7 @@ of their proof goes something like this (this is far from complete): needle == (a + w) + (w + b), meaning there's a bad equality w == w, it's impossible for w + b to be bigger than both b and w + w + b, so this can't happen. We thus have all of - the ineuqalities with no question marks. + the inequalities with no question marks. * By maximality, the right part is not a substring of the left part. Thus, we have all of the inequalities involving no left-side question marks. diff --git a/Objects/stringlib/transmogrify.h b/Objects/stringlib/transmogrify.h index e1165ea3..71099bb5 100644 --- a/Objects/stringlib/transmogrify.h +++ b/Objects/stringlib/transmogrify.h @@ -17,8 +17,7 @@ return_self(PyObject *self) { #if !STRINGLIB_MUTABLE if (STRINGLIB_CHECK_EXACT(self)) { - Py_INCREF(self); - return self; + return Py_NewRef(self); } #endif return STRINGLIB_NEW(STRINGLIB_STR(self), STRINGLIB_LEN(self)); diff --git a/Objects/stringlib/ucs1lib.h b/Objects/stringlib/ucs1lib.h index 026ab11f..1b9b65ec 100644 --- a/Objects/stringlib/ucs1lib.h +++ b/Objects/stringlib/ucs1lib.h @@ -20,6 +20,7 @@ #define STRINGLIB_NEW _PyUnicode_FromUCS1 #define STRINGLIB_CHECK PyUnicode_Check #define STRINGLIB_CHECK_EXACT PyUnicode_CheckExact +#define STRINGLIB_FAST_MEMCHR memchr #define STRINGLIB_MUTABLE 0 #define STRINGLIB_TOSTR PyObject_Str diff --git a/Objects/stringlib/ucs2lib.h b/Objects/stringlib/ucs2lib.h index 75f11bc2..4b49bbb3 100644 --- a/Objects/stringlib/ucs2lib.h +++ b/Objects/stringlib/ucs2lib.h @@ -21,6 +21,10 @@ #define STRINGLIB_CHECK PyUnicode_Check #define STRINGLIB_CHECK_EXACT PyUnicode_CheckExact #define STRINGLIB_MUTABLE 0 +#if SIZEOF_WCHAR_T == 2 +#define STRINGLIB_FAST_MEMCHR(s, c, n) \ + (Py_UCS2 *)wmemchr((const wchar_t *)(s), c, n) +#endif #define STRINGLIB_TOSTR PyObject_Str #define STRINGLIB_TOASCII PyObject_ASCII diff --git a/Objects/stringlib/ucs4lib.h b/Objects/stringlib/ucs4lib.h index 57344f23..def4ca5d 100644 --- a/Objects/stringlib/ucs4lib.h +++ b/Objects/stringlib/ucs4lib.h @@ -21,6 +21,10 @@ #define STRINGLIB_CHECK PyUnicode_Check #define STRINGLIB_CHECK_EXACT PyUnicode_CheckExact #define STRINGLIB_MUTABLE 0 +#if SIZEOF_WCHAR_T == 4 +#define STRINGLIB_FAST_MEMCHR(s, c, n) \ + (Py_UCS4 *)wmemchr((const wchar_t *)(s), c, n) +#endif #define STRINGLIB_TOSTR PyObject_Str #define STRINGLIB_TOASCII PyObject_ASCII diff --git a/Objects/stringlib/undef.h b/Objects/stringlib/undef.h index bf322985..cc873a2e 100644 --- a/Objects/stringlib/undef.h +++ b/Objects/stringlib/undef.h @@ -8,3 +8,4 @@ #undef STRINGLIB_NEW #undef STRINGLIB_IS_UNICODE #undef STRINGLIB_MUTABLE +#undef STRINGLIB_FAST_MEMCHR diff --git a/Objects/stringlib/unicode_format.h b/Objects/stringlib/unicode_format.h index a4eea7b9..ccd7c77c 100644 --- a/Objects/stringlib/unicode_format.h +++ b/Objects/stringlib/unicode_format.h @@ -473,8 +473,7 @@ get_field_object(SubString *input, PyObject *args, PyObject *kwargs, goto error; /* assign to obj */ - Py_DECREF(obj); - obj = tmp; + Py_SETREF(obj, tmp); } /* end of iterator, this is the non-error case */ if (ok == 1) @@ -825,8 +824,7 @@ output_markup(SubString *field_name, SubString *format_spec, goto done; /* do the assignment, transferring ownership: fieldobj = tmp */ - Py_DECREF(fieldobj); - fieldobj = tmp; + Py_SETREF(fieldobj, tmp); tmp = NULL; } @@ -1042,8 +1040,7 @@ formatteriter_next(formatteriterobject *it) otherwise create a one length string with the conversion character */ if (conversion == '\0') { - conversion_str = Py_None; - Py_INCREF(conversion_str); + conversion_str = Py_NewRef(Py_None); } else conversion_str = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, @@ -1121,8 +1118,7 @@ formatter_parser(PyObject *ignored, PyObject *self) return NULL; /* take ownership, give the object to the iterator */ - Py_INCREF(self); - it->str = self; + it->str = Py_NewRef(self); /* initialize the contained MarkupIterator */ MarkupIterator_init(&it->it_markup, (PyObject*)self, 0, PyUnicode_GET_LENGTH(self)); @@ -1265,8 +1261,7 @@ formatter_field_name_split(PyObject *ignored, PyObject *self) /* take ownership, give the object to the iterator. this is just to keep the field_name alive */ - Py_INCREF(self); - it->str = self; + it->str = Py_NewRef(self); /* Pass in auto_number = NULL. We'll return an empty string for first_obj in that case. */ diff --git a/Objects/stringlib/unicodedefs.h b/Objects/stringlib/unicodedefs.h deleted file mode 100644 index ba2ce0ae..00000000 --- a/Objects/stringlib/unicodedefs.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef STRINGLIB_UNICODEDEFS_H -#define STRINGLIB_UNICODEDEFS_H - -/* this is sort of a hack. there's at least one place (formatting - floats) where some stringlib code takes a different path if it's - compiled as unicode. */ -#define STRINGLIB_IS_UNICODE 1 - -#define FASTSEARCH fastsearch -#define STRINGLIB(F) stringlib_##F -#define STRINGLIB_OBJECT PyUnicodeObject -#define STRINGLIB_SIZEOF_CHAR Py_UNICODE_SIZE -#define STRINGLIB_CHAR Py_UNICODE -#define STRINGLIB_TYPE_NAME "unicode" -#define STRINGLIB_PARSE_CODE "U" -#define STRINGLIB_ISSPACE Py_UNICODE_ISSPACE -#define STRINGLIB_ISLINEBREAK BLOOM_LINEBREAK -#define STRINGLIB_ISDECIMAL Py_UNICODE_ISDECIMAL -#define STRINGLIB_TODECIMAL Py_UNICODE_TODECIMAL -#define STRINGLIB_STR PyUnicode_AS_UNICODE -#define STRINGLIB_LEN PyUnicode_GET_SIZE -#define STRINGLIB_NEW PyUnicode_FromUnicode -#define STRINGLIB_CHECK PyUnicode_Check -#define STRINGLIB_CHECK_EXACT PyUnicode_CheckExact -#define STRINGLIB_MUTABLE 0 - -#define STRINGLIB_TOSTR PyObject_Str -#define STRINGLIB_TOASCII PyObject_ASCII - -#define STRINGLIB_WANT_CONTAINS_OBJ 1 - -#endif /* !STRINGLIB_UNICODEDEFS_H */ diff --git a/Objects/structseq.c b/Objects/structseq.c index 229e3d89..8b189595 100644 --- a/Objects/structseq.c +++ b/Objects/structseq.c @@ -26,11 +26,12 @@ const char * const PyStructSequence_UnnamedField = "unnamed field"; static Py_ssize_t get_type_attr_as_size(PyTypeObject *tp, PyObject *name) { - PyObject *v = PyDict_GetItemWithError(tp->tp_dict, name); + PyObject *v = PyDict_GetItemWithError(_PyType_GetDict(tp), name); if (v == NULL && !PyErr_Occurred()) { PyErr_Format(PyExc_TypeError, "Missed attribute '%U' of type %s", name, tp->tp_name); + return -1; } return PyLong_AsSsize_t(v); } @@ -200,8 +201,7 @@ structseq_new_impl(PyTypeObject *type, PyObject *arg, PyObject *dict) } for (i = 0; i < len; ++i) { PyObject *v = PySequence_Fast_GET_ITEM(arg, i); - Py_INCREF(v); - res->ob_item[i] = v; + res->ob_item[i] = Py_NewRef(v); } Py_DECREF(arg); for (; i < max_len; ++i) { @@ -219,8 +219,7 @@ structseq_new_impl(PyTypeObject *type, PyObject *arg, PyObject *dict) ob = Py_None; } } - Py_INCREF(ob); - res->ob_item[i] = ob; + res->ob_item[i] = Py_NewRef(ob); } _PyObject_GC_TRACK(res); @@ -432,11 +431,19 @@ error: return -1; } -static void -initialize_members(PyStructSequence_Desc *desc, PyMemberDef* members, - Py_ssize_t n_members) { - Py_ssize_t i, k; +static PyMemberDef * +initialize_members(PyStructSequence_Desc *desc, + Py_ssize_t n_members, Py_ssize_t n_unnamed_members) +{ + PyMemberDef *members; + members = PyMem_NEW(PyMemberDef, n_members - n_unnamed_members + 1); + if (members == NULL) { + PyErr_NoMemory(); + return NULL; + } + + Py_ssize_t i, k; for (i = k = 0; i < n_members; ++i) { if (desc->fields[i].name == PyStructSequence_UnnamedField) { continue; @@ -453,30 +460,15 @@ initialize_members(PyStructSequence_Desc *desc, PyMemberDef* members, k++; } members[k].name = NULL; + + return members; } -int -_PyStructSequence_InitType(PyTypeObject *type, PyStructSequence_Desc *desc, - unsigned long tp_flags) +static void +initialize_static_fields(PyTypeObject *type, PyStructSequence_Desc *desc, + PyMemberDef *tp_members, unsigned long tp_flags) { - PyMemberDef *members; - Py_ssize_t n_members, n_unnamed_members; - -#ifdef Py_TRACE_REFS - /* if the type object was chained, unchain it first - before overwriting its storage */ - if (type->ob_base.ob_base._ob_next) { - _Py_ForgetReference((PyObject *)type); - } -#endif - - /* PyTypeObject has already been initialized */ - if (Py_REFCNT(type) != 0) { - PyErr_BadInternalCall(); - return -1; - } - type->tp_name = desc->name; type->tp_basicsize = sizeof(PyStructSequence) - sizeof(PyObject *); type->tp_itemsize = sizeof(PyObject *); @@ -488,25 +480,20 @@ _PyStructSequence_InitType(PyTypeObject *type, PyStructSequence_Desc *desc, type->tp_new = structseq_new; type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | tp_flags; type->tp_traverse = (traverseproc) structseq_traverse; + type->tp_members = tp_members; +} - n_members = count_members(desc, &n_unnamed_members); - members = PyMem_NEW(PyMemberDef, n_members - n_unnamed_members + 1); - if (members == NULL) { - PyErr_NoMemory(); - return -1; - } - initialize_members(desc, members, n_members); - type->tp_members = members; - +static int +initialize_static_type(PyTypeObject *type, PyStructSequence_Desc *desc, + Py_ssize_t n_members, Py_ssize_t n_unnamed_members) { + /* initialize_static_fields() should have been called already. */ if (PyType_Ready(type) < 0) { - PyMem_Free(members); return -1; } Py_INCREF(type); if (initialize_structseq_dict( - desc, type->tp_dict, n_members, n_unnamed_members) < 0) { - PyMem_Free(members); + desc, _PyType_GetDict(type), n_members, n_unnamed_members) < 0) { Py_DECREF(type); return -1; } @@ -514,10 +501,93 @@ _PyStructSequence_InitType(PyTypeObject *type, PyStructSequence_Desc *desc, return 0; } +int +_PyStructSequence_InitBuiltinWithFlags(PyInterpreterState *interp, + PyTypeObject *type, + PyStructSequence_Desc *desc, + unsigned long tp_flags) +{ + Py_ssize_t n_unnamed_members; + Py_ssize_t n_members = count_members(desc, &n_unnamed_members); + PyMemberDef *members = NULL; + + if ((type->tp_flags & Py_TPFLAGS_READY) == 0) { + assert(type->tp_name == NULL); + assert(type->tp_members == NULL); + assert(type->tp_base == NULL); + + members = initialize_members(desc, n_members, n_unnamed_members); + if (members == NULL) { + goto error; + } + initialize_static_fields(type, desc, members, tp_flags); + + _Py_SetImmortal(type); + } +#ifndef NDEBUG + else { + // Ensure that the type was initialized. + assert(type->tp_name != NULL); + assert(type->tp_members != NULL); + assert(type->tp_base == &PyTuple_Type); + assert((type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN)); + assert(_Py_IsImmortal(type)); + } +#endif + + if (_PyStaticType_InitBuiltin(interp, type) < 0) { + PyErr_Format(PyExc_RuntimeError, + "Can't initialize builtin type %s", + desc->name); + goto error; + } + + if (initialize_structseq_dict( + desc, _PyType_GetDict(type), n_members, n_unnamed_members) < 0) + { + goto error; + } + + return 0; + +error: + if (members != NULL) { + PyMem_Free(members); + } + return -1; +} + int PyStructSequence_InitType2(PyTypeObject *type, PyStructSequence_Desc *desc) { - return _PyStructSequence_InitType(type, desc, 0); + PyMemberDef *members; + Py_ssize_t n_members, n_unnamed_members; + +#ifdef Py_TRACE_REFS + /* if the type object was chained, unchain it first + before overwriting its storage */ + if (type->ob_base.ob_base._ob_next) { + _Py_ForgetReference((PyObject *)type); + } +#endif + + /* PyTypeObject has already been initialized */ + if (Py_REFCNT(type) != 0) { + PyErr_BadInternalCall(); + return -1; + } + + n_members = count_members(desc, &n_unnamed_members); + members = initialize_members(desc, n_members, n_unnamed_members); + if (members == NULL) { + return -1; + } + initialize_static_fields(type, desc, members, 0); + if (initialize_static_type(type, desc, n_members, n_unnamed_members) < 0) { + PyMem_Free(members); + return -1; + } + return 0; } void @@ -527,35 +597,34 @@ PyStructSequence_InitType(PyTypeObject *type, PyStructSequence_Desc *desc) } +/* This is exposed in the internal API, not the public API. + It is only called on builtin static types, which are all + initialized via _PyStructSequence_InitBuiltinWithFlags(). */ + void -_PyStructSequence_FiniType(PyTypeObject *type) +_PyStructSequence_FiniBuiltin(PyInterpreterState *interp, PyTypeObject *type) { // Ensure that the type is initialized assert(type->tp_name != NULL); assert(type->tp_base == &PyTuple_Type); + assert((type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN)); + assert(_Py_IsImmortal(type)); // Cannot delete a type if it still has subclasses - if (type->tp_subclasses != NULL) { + if (_PyType_HasSubclasses(type)) { + // XXX Shouldn't this be an error? return; } - // Undo PyStructSequence_NewType() - type->tp_name = NULL; - PyMem_Free(type->tp_members); - - _PyStaticType_Dealloc(type); - assert(Py_REFCNT(type) == 1); - // Undo Py_INCREF(type) of _PyStructSequence_InitType(). - // Don't use Py_DECREF(): static type must not be deallocated - Py_SET_REFCNT(type, 0); -#ifdef Py_REF_DEBUG - _Py_RefTotal--; -#endif + _PyStaticType_Dealloc(interp, type); - // Make sure that _PyStructSequence_InitType() will initialize - // the type again - assert(Py_REFCNT(type) == 0); - assert(type->tp_name == NULL); + if (_Py_IsMainInterpreter(interp)) { + // Undo _PyStructSequence_InitBuiltinWithFlags(). + type->tp_name = NULL; + PyMem_Free(type->tp_members); + type->tp_members = NULL; + type->tp_base = NULL; + } } @@ -570,12 +639,10 @@ _PyStructSequence_NewType(PyStructSequence_Desc *desc, unsigned long tp_flags) /* Initialize MemberDefs */ n_members = count_members(desc, &n_unnamed_members); - members = PyMem_NEW(PyMemberDef, n_members - n_unnamed_members + 1); + members = initialize_members(desc, n_members, n_unnamed_members); if (members == NULL) { - PyErr_NoMemory(); return NULL; } - initialize_members(desc, members, n_members); /* Initialize Slots */ slots[0] = (PyType_Slot){Py_tp_dealloc, (destructor)structseq_dealloc}; @@ -603,7 +670,7 @@ _PyStructSequence_NewType(PyStructSequence_Desc *desc, unsigned long tp_flags) } if (initialize_structseq_dict( - desc, type->tp_dict, n_members, n_unnamed_members) < 0) { + desc, _PyType_GetDict(type), n_members, n_unnamed_members) < 0) { Py_DECREF(type); return NULL; } diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c index dfb8597b..991edcc8 100644 --- a/Objects/tupleobject.c +++ b/Objects/tupleobject.c @@ -61,8 +61,7 @@ tuple_alloc(Py_ssize_t size) static inline PyObject * tuple_get_empty(void) { - Py_INCREF(&_Py_SINGLETON(tuple_empty)); - return (PyObject *)&_Py_SINGLETON(tuple_empty); + return Py_NewRef(&_Py_SINGLETON(tuple_empty)); } PyObject * @@ -171,8 +170,7 @@ PyTuple_Pack(Py_ssize_t n, ...) items = result->ob_item; for (i = 0; i < n; i++) { o = va_arg(vargs, PyObject *); - Py_INCREF(o); - items[i] = o; + items[i] = Py_NewRef(o); } va_end(vargs); _PyObject_GC_TRACK(result); @@ -290,7 +288,7 @@ error: /* Hash for tuples. This is a slightly simplified version of the xxHash non-cryptographic hash: - - we do not use any parallellism, there is only 1 accumulator. + - we do not use any parallelism, there is only 1 accumulator. - we drop the final mixing since this is just a permutation of the output space: it does not help against collisions. - at the end, we mangle the length with a single constant. @@ -367,8 +365,7 @@ tupleitem(PyTupleObject *a, Py_ssize_t i) PyErr_SetString(PyExc_IndexError, "tuple index out of range"); return NULL; } - Py_INCREF(a->ob_item[i]); - return a->ob_item[i]; + return Py_NewRef(a->ob_item[i]); } PyObject * @@ -385,8 +382,7 @@ _PyTuple_FromArray(PyObject *const *src, Py_ssize_t n) PyObject **dst = tuple->ob_item; for (Py_ssize_t i = 0; i < n; i++) { PyObject *item = src[i]; - Py_INCREF(item); - dst[i] = item; + dst[i] = Py_NewRef(item); } _PyObject_GC_TRACK(tuple); return (PyObject *)tuple; @@ -425,8 +421,7 @@ tupleslice(PyTupleObject *a, Py_ssize_t ilow, if (ihigh < ilow) ihigh = ilow; if (ilow == 0 && ihigh == Py_SIZE(a) && PyTuple_CheckExact(a)) { - Py_INCREF(a); - return (PyObject *)a; + return Py_NewRef(a); } return _PyTuple_FromArray(a->ob_item + ilow, ihigh - ilow); } @@ -449,8 +444,7 @@ tupleconcat(PyTupleObject *a, PyObject *bb) PyObject **src, **dest; PyTupleObject *np; if (Py_SIZE(a) == 0 && PyTuple_CheckExact(bb)) { - Py_INCREF(bb); - return bb; + return Py_NewRef(bb); } if (!PyTuple_Check(bb)) { PyErr_Format(PyExc_TypeError, @@ -461,8 +455,7 @@ tupleconcat(PyTupleObject *a, PyObject *bb) PyTupleObject *b = (PyTupleObject *)bb; if (Py_SIZE(b) == 0 && PyTuple_CheckExact(a)) { - Py_INCREF(a); - return (PyObject *)a; + return Py_NewRef(a); } assert((size_t)Py_SIZE(a) + (size_t)Py_SIZE(b) < PY_SSIZE_T_MAX); size = Py_SIZE(a) + Py_SIZE(b); @@ -478,15 +471,13 @@ tupleconcat(PyTupleObject *a, PyObject *bb) dest = np->ob_item; for (i = 0; i < Py_SIZE(a); i++) { PyObject *v = src[i]; - Py_INCREF(v); - dest[i] = v; + dest[i] = Py_NewRef(v); } src = b->ob_item; dest = np->ob_item + Py_SIZE(a); for (i = 0; i < Py_SIZE(b); i++) { PyObject *v = src[i]; - Py_INCREF(v); - dest[i] = v; + dest[i] = Py_NewRef(v); } _PyObject_GC_TRACK(np); return (PyObject *)np; @@ -495,52 +486,46 @@ tupleconcat(PyTupleObject *a, PyObject *bb) static PyObject * tuplerepeat(PyTupleObject *a, Py_ssize_t n) { - Py_ssize_t size; - PyTupleObject *np; - if (Py_SIZE(a) == 0 || n == 1) { + const Py_ssize_t input_size = Py_SIZE(a); + if (input_size == 0 || n == 1) { if (PyTuple_CheckExact(a)) { /* Since tuples are immutable, we can return a shared copy in this case */ - Py_INCREF(a); - return (PyObject *)a; + return Py_NewRef(a); } } - if (Py_SIZE(a) == 0 || n <= 0) { + if (input_size == 0 || n <= 0) { return tuple_get_empty(); } - if (n > PY_SSIZE_T_MAX / Py_SIZE(a)) + assert(n>0); + + if (input_size > PY_SSIZE_T_MAX / n) return PyErr_NoMemory(); - size = Py_SIZE(a) * n; - np = tuple_alloc(size); + Py_ssize_t output_size = input_size * n; + + PyTupleObject *np = tuple_alloc(output_size); if (np == NULL) return NULL; + PyObject **dest = np->ob_item; - PyObject **dest_end = dest + size; - if (Py_SIZE(a) == 1) { + if (input_size == 1) { PyObject *elem = a->ob_item[0]; - Py_SET_REFCNT(elem, Py_REFCNT(elem) + n); -#ifdef Py_REF_DEBUG - _Py_RefTotal += n; -#endif + _Py_RefcntAdd(elem, n); + PyObject **dest_end = dest + output_size; while (dest < dest_end) { *dest++ = elem; } } else { PyObject **src = a->ob_item; - PyObject **src_end = src + Py_SIZE(a); + PyObject **src_end = src + input_size; while (src < src_end) { - Py_SET_REFCNT(*src, Py_REFCNT(*src) + n); -#ifdef Py_REF_DEBUG - _Py_RefTotal += n; -#endif - *dest++ = *src++; - } - // Now src chases after dest in the same buffer - src = np->ob_item; - while (dest < dest_end) { + _Py_RefcntAdd(*src, n); *dest++ = *src++; } + + _Py_memory_repeat((char *)np->ob_item, sizeof(PyObject *)*output_size, + sizeof(PyObject *)*input_size); } _PyObject_GC_TRACK(np); return (PyObject *) np; @@ -752,8 +737,7 @@ tuple_subtype_new(PyTypeObject *type, PyObject *iterable) } for (i = 0; i < n; i++) { item = PyTuple_GET_ITEM(tmp, i); - Py_INCREF(item); - PyTuple_SET_ITEM(newobj, i, item); + PyTuple_SET_ITEM(newobj, i, Py_NewRef(item)); } Py_DECREF(tmp); @@ -804,8 +788,7 @@ tuplesubscript(PyTupleObject* self, PyObject* item) else if (start == 0 && step == 1 && slicelength == PyTuple_GET_SIZE(self) && PyTuple_CheckExact(self)) { - Py_INCREF(self); - return (PyObject *)self; + return Py_NewRef(self); } else { PyTupleObject* result = tuple_alloc(slicelength); @@ -815,8 +798,7 @@ tuplesubscript(PyTupleObject* self, PyObject* item) dest = result->ob_item; for (cur = start, i = 0; i < slicelength; cur += step, i++) { - it = src[cur]; - Py_INCREF(it); + it = Py_NewRef(src[cur]); dest[i] = it; } @@ -948,10 +930,6 @@ _PyTuple_Resize(PyObject **pv, Py_ssize_t newsize) return *pv == NULL ? -1 : 0; } - /* XXX UNREF/NEWREF interface should be more symmetrical */ -#ifdef Py_REF_DEBUG - _Py_RefTotal--; -#endif if (_PyObject_GC_IS_TRACKED(v)) { _PyObject_GC_UNTRACK(v); } @@ -965,10 +943,13 @@ _PyTuple_Resize(PyObject **pv, Py_ssize_t newsize) sv = PyObject_GC_Resize(PyTupleObject, v, newsize); if (sv == NULL) { *pv = NULL; +#ifdef Py_REF_DEBUG + _Py_DecRefTotal(_PyInterpreterState_GET()); +#endif PyObject_GC_Del(v); return -1; } - _Py_NewReference((PyObject *) sv); + _Py_NewReferenceNoTotal((PyObject *) sv); /* Zero out items added by growing */ if (newsize > oldsize) memset(&sv->ob_item[oldsize], 0, @@ -979,24 +960,6 @@ _PyTuple_Resize(PyObject **pv, Py_ssize_t newsize) } -PyStatus -_PyTuple_InitTypes(PyInterpreterState *interp) -{ - if (!_Py_IsMainInterpreter(interp)) { - return _PyStatus_OK(); - } - - if (PyType_Ready(&PyTuple_Type) < 0) { - return _PyStatus_ERR("Can't initialize tuple type"); - } - - if (PyType_Ready(&PyTupleIter_Type) < 0) { - return _PyStatus_ERR("Can't initialize tuple iterator type"); - } - - return _PyStatus_OK(); -} - static void maybe_freelist_clear(PyInterpreterState *, int); void @@ -1013,14 +976,9 @@ _PyTuple_ClearFreeList(PyInterpreterState *interp) /*********************** Tuple Iterator **************************/ -typedef struct { - PyObject_HEAD - Py_ssize_t it_index; - PyTupleObject *it_seq; /* Set to NULL when iterator is exhausted */ -} tupleiterobject; static void -tupleiter_dealloc(tupleiterobject *it) +tupleiter_dealloc(_PyTupleIterObject *it) { _PyObject_GC_UNTRACK(it); Py_XDECREF(it->it_seq); @@ -1028,14 +986,14 @@ tupleiter_dealloc(tupleiterobject *it) } static int -tupleiter_traverse(tupleiterobject *it, visitproc visit, void *arg) +tupleiter_traverse(_PyTupleIterObject *it, visitproc visit, void *arg) { Py_VISIT(it->it_seq); return 0; } static PyObject * -tupleiter_next(tupleiterobject *it) +tupleiter_next(_PyTupleIterObject *it) { PyTupleObject *seq; PyObject *item; @@ -1049,8 +1007,7 @@ tupleiter_next(tupleiterobject *it) if (it->it_index < PyTuple_GET_SIZE(seq)) { item = PyTuple_GET_ITEM(seq, it->it_index); ++it->it_index; - Py_INCREF(item); - return item; + return Py_NewRef(item); } it->it_seq = NULL; @@ -1059,7 +1016,7 @@ tupleiter_next(tupleiterobject *it) } static PyObject * -tupleiter_len(tupleiterobject *it, PyObject *Py_UNUSED(ignored)) +tupleiter_len(_PyTupleIterObject *it, PyObject *Py_UNUSED(ignored)) { Py_ssize_t len = 0; if (it->it_seq) @@ -1070,17 +1027,22 @@ tupleiter_len(tupleiterobject *it, PyObject *Py_UNUSED(ignored)) PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it))."); static PyObject * -tupleiter_reduce(tupleiterobject *it, PyObject *Py_UNUSED(ignored)) +tupleiter_reduce(_PyTupleIterObject *it, PyObject *Py_UNUSED(ignored)) { + PyObject *iter = _PyEval_GetBuiltin(&_Py_ID(iter)); + + /* _PyEval_GetBuiltin can invoke arbitrary code, + * call must be before access of iterator pointers. + * see issue #101765 */ + if (it->it_seq) - return Py_BuildValue("N(O)n", _PyEval_GetBuiltin(&_Py_ID(iter)), - it->it_seq, it->it_index); + return Py_BuildValue("N(O)n", iter, it->it_seq, it->it_index); else - return Py_BuildValue("N(())", _PyEval_GetBuiltin(&_Py_ID(iter))); + return Py_BuildValue("N(())", iter); } static PyObject * -tupleiter_setstate(tupleiterobject *it, PyObject *state) +tupleiter_setstate(_PyTupleIterObject *it, PyObject *state) { Py_ssize_t index = PyLong_AsSsize_t(state); if (index == -1 && PyErr_Occurred()) @@ -1108,7 +1070,7 @@ static PyMethodDef tupleiter_methods[] = { PyTypeObject PyTupleIter_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "tuple_iterator", /* tp_name */ - sizeof(tupleiterobject), /* tp_basicsize */ + sizeof(_PyTupleIterObject), /* tp_basicsize */ 0, /* tp_itemsize */ /* methods */ (destructor)tupleiter_dealloc, /* tp_dealloc */ @@ -1141,18 +1103,17 @@ PyTypeObject PyTupleIter_Type = { static PyObject * tuple_iter(PyObject *seq) { - tupleiterobject *it; + _PyTupleIterObject *it; if (!PyTuple_Check(seq)) { PyErr_BadInternalCall(); return NULL; } - it = PyObject_GC_New(tupleiterobject, &PyTupleIter_Type); + it = PyObject_GC_New(_PyTupleIterObject, &PyTupleIter_Type); if (it == NULL) return NULL; it->it_index = 0; - Py_INCREF(seq); - it->it_seq = (PyTupleObject *)seq; + it->it_seq = (PyTupleObject *)Py_NewRef(seq); _PyObject_GC_TRACK(it); return (PyObject *)it; } diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 9ee57105..5c71c28f 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -3,10 +3,13 @@ #include "Python.h" #include "pycore_call.h" #include "pycore_code.h" // CO_FAST_FREE -#include "pycore_compile.h" // _Py_Mangle() +#include "pycore_symtable.h" // _Py_Mangle() +#include "pycore_dict.h" // _PyDict_KeysSize() #include "pycore_initconfig.h" // _PyStatus_OK() +#include "pycore_memoryobject.h" // _PyMemoryView_FromBufferProc() #include "pycore_moduleobject.h" // _PyModule_GetDef() #include "pycore_object.h" // _PyType_HasFeature() +#include "pycore_long.h" // _PyLong_IsNegative() #include "pycore_pyerrors.h" // _PyErr_Occurred() #include "pycore_pystate.h" // _PyThreadState_GET() #include "pycore_typeobject.h" // struct type_cache @@ -16,6 +19,7 @@ #include "structmember.h" // PyMemberDef #include <ctype.h> +#include <stddef.h> // ptrdiff_t /*[clinic input] class type "PyTypeObject *" "&PyType_Type" @@ -43,28 +47,432 @@ class object "PyObject *" "&PyBaseObject_Type" PyUnicode_IS_READY(name) && \ (PyUnicode_GET_LENGTH(name) <= MCACHE_MAX_ATTR_SIZE) -// bpo-42745: next_version_tag remains shared by all interpreters because of static types -// Used to set PyTypeObject.tp_version_tag -static unsigned int next_version_tag = 1; +#define NEXT_GLOBAL_VERSION_TAG _PyRuntime.types.next_version_tag +#define NEXT_VERSION_TAG(interp) \ + (interp)->types.next_version_tag typedef struct PySlot_Offset { short subslot_offset; short slot_offset; } PySlot_Offset; +static void +slot_bf_releasebuffer(PyObject *self, Py_buffer *buffer); + +static void +releasebuffer_call_python(PyObject *self, Py_buffer *buffer); static PyObject * slot_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds); -static void -clear_slotdefs(void); - static PyObject * lookup_maybe_method(PyObject *self, PyObject *attr, int *unbound); static int slot_tp_setattro(PyObject *self, PyObject *name, PyObject *value); + +static inline PyTypeObject * +type_from_ref(PyObject *ref) +{ + assert(PyWeakref_CheckRef(ref)); + PyObject *obj = PyWeakref_GET_OBJECT(ref); // borrowed ref + assert(obj != NULL); + if (obj == Py_None) { + return NULL; + } + assert(PyType_Check(obj)); + return _PyType_CAST(obj); +} + + +/* helpers for for static builtin types */ + +static inline int +static_builtin_index_is_set(PyTypeObject *self) +{ + return self->tp_subclasses != NULL; +} + +static inline size_t +static_builtin_index_get(PyTypeObject *self) +{ + assert(static_builtin_index_is_set(self)); + /* We store a 1-based index so 0 can mean "not initialized". */ + return (size_t)self->tp_subclasses - 1; +} + +static inline void +static_builtin_index_set(PyTypeObject *self, size_t index) +{ + assert(index < _Py_MAX_STATIC_BUILTIN_TYPES); + /* We store a 1-based index so 0 can mean "not initialized". */ + self->tp_subclasses = (PyObject *)(index + 1); +} + +static inline void +static_builtin_index_clear(PyTypeObject *self) +{ + self->tp_subclasses = NULL; +} + +static inline static_builtin_state * +static_builtin_state_get(PyInterpreterState *interp, PyTypeObject *self) +{ + return &(interp->types.builtins[static_builtin_index_get(self)]); +} + +/* For static types we store some state in an array on each interpreter. */ +static_builtin_state * +_PyStaticType_GetState(PyInterpreterState *interp, PyTypeObject *self) +{ + assert(self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN); + return static_builtin_state_get(interp, self); +} + +/* Set the type's per-interpreter state. */ +static void +static_builtin_state_init(PyInterpreterState *interp, PyTypeObject *self) +{ + if (!static_builtin_index_is_set(self)) { + static_builtin_index_set(self, interp->types.num_builtins_initialized); + } + static_builtin_state *state = static_builtin_state_get(interp, self); + + /* It should only be called once for each builtin type. */ + assert(state->type == NULL); + state->type = self; + + /* state->tp_subclasses is left NULL until init_subclasses() sets it. */ + /* state->tp_weaklist is left NULL until insert_head() or insert_after() + (in weakrefobject.c) sets it. */ + + interp->types.num_builtins_initialized++; +} + +/* Reset the type's per-interpreter state. + This basically undoes what static_builtin_state_init() did. */ +static void +static_builtin_state_clear(PyInterpreterState *interp, PyTypeObject *self) +{ + static_builtin_state *state = static_builtin_state_get(interp, self); + + assert(state->type != NULL); + state->type = NULL; + assert(state->tp_weaklist == NULL); // It was already cleared out. + + if (_Py_IsMainInterpreter(interp)) { + static_builtin_index_clear(self); + } + + assert(interp->types.num_builtins_initialized > 0); + interp->types.num_builtins_initialized--; +} + +// Also see _PyStaticType_InitBuiltin() and _PyStaticType_Dealloc(). + +/* end static builtin helpers */ + + +static inline void +start_readying(PyTypeObject *type) +{ + if (type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) { + PyInterpreterState *interp = _PyInterpreterState_GET(); + static_builtin_state *state = static_builtin_state_get(interp, type); + assert(state != NULL); + assert(!state->readying); + state->readying = 1; + return; + } + assert((type->tp_flags & Py_TPFLAGS_READYING) == 0); + type->tp_flags |= Py_TPFLAGS_READYING; +} + +static inline void +stop_readying(PyTypeObject *type) +{ + if (type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) { + PyInterpreterState *interp = _PyInterpreterState_GET(); + static_builtin_state *state = static_builtin_state_get(interp, type); + assert(state != NULL); + assert(state->readying); + state->readying = 0; + return; + } + assert(type->tp_flags & Py_TPFLAGS_READYING); + type->tp_flags &= ~Py_TPFLAGS_READYING; +} + +static inline int +is_readying(PyTypeObject *type) +{ + if (type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) { + PyInterpreterState *interp = _PyInterpreterState_GET(); + static_builtin_state *state = static_builtin_state_get(interp, type); + assert(state != NULL); + return state->readying; + } + return (type->tp_flags & Py_TPFLAGS_READYING) != 0; +} + + +/* accessors for objects stored on PyTypeObject */ + +static inline PyObject * +lookup_tp_dict(PyTypeObject *self) +{ + if (self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) { + PyInterpreterState *interp = _PyInterpreterState_GET(); + static_builtin_state *state = _PyStaticType_GetState(interp, self); + assert(state != NULL); + return state->tp_dict; + } + return self->tp_dict; +} + +PyObject * +_PyType_GetDict(PyTypeObject *self) +{ + /* It returns a borrowed reference. */ + return lookup_tp_dict(self); +} + +PyObject * +PyType_GetDict(PyTypeObject *self) +{ + PyObject *dict = lookup_tp_dict(self); + return _Py_XNewRef(dict); +} + +static inline void +set_tp_dict(PyTypeObject *self, PyObject *dict) +{ + if (self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) { + PyInterpreterState *interp = _PyInterpreterState_GET(); + static_builtin_state *state = _PyStaticType_GetState(interp, self); + assert(state != NULL); + state->tp_dict = dict; + return; + } + self->tp_dict = dict; +} + +static inline void +clear_tp_dict(PyTypeObject *self) +{ + if (self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) { + PyInterpreterState *interp = _PyInterpreterState_GET(); + static_builtin_state *state = _PyStaticType_GetState(interp, self); + assert(state != NULL); + Py_CLEAR(state->tp_dict); + return; + } + Py_CLEAR(self->tp_dict); +} + + +static inline PyObject * +lookup_tp_bases(PyTypeObject *self) +{ + return self->tp_bases; +} + +PyObject * +_PyType_GetBases(PyTypeObject *self) +{ + /* It returns a borrowed reference. */ + return lookup_tp_bases(self); +} + +static inline void +set_tp_bases(PyTypeObject *self, PyObject *bases) +{ + assert(PyTuple_CheckExact(bases)); + if (self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) { + // XXX tp_bases can probably be statically allocated for each + // static builtin type. + assert(_Py_IsMainInterpreter(_PyInterpreterState_GET())); + assert(self->tp_bases == NULL); + if (PyTuple_GET_SIZE(bases) == 0) { + assert(self->tp_base == NULL); + } + else { + assert(PyTuple_GET_SIZE(bases) == 1); + assert(PyTuple_GET_ITEM(bases, 0) == (PyObject *)self->tp_base); + assert(self->tp_base->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN); + assert(_Py_IsImmortal(self->tp_base)); + } + _Py_SetImmortal(bases); + } + self->tp_bases = bases; +} + +static inline void +clear_tp_bases(PyTypeObject *self) +{ + if (self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) { + if (_Py_IsMainInterpreter(_PyInterpreterState_GET())) { + if (self->tp_bases != NULL) { + if (PyTuple_GET_SIZE(self->tp_bases) == 0) { + Py_CLEAR(self->tp_bases); + } + else { + assert(_Py_IsImmortal(self->tp_bases)); + _Py_ClearImmortal(self->tp_bases); + } + } + } + return; + } + Py_CLEAR(self->tp_bases); +} + + +static inline PyObject * +lookup_tp_mro(PyTypeObject *self) +{ + return self->tp_mro; +} + +PyObject * +_PyType_GetMRO(PyTypeObject *self) +{ + /* It returns a borrowed reference. */ + return lookup_tp_mro(self); +} + +static inline void +set_tp_mro(PyTypeObject *self, PyObject *mro) +{ + assert(PyTuple_CheckExact(mro)); + if (self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) { + // XXX tp_mro can probably be statically allocated for each + // static builtin type. + assert(_Py_IsMainInterpreter(_PyInterpreterState_GET())); + assert(self->tp_mro == NULL); + /* Other checks are done via set_tp_bases. */ + _Py_SetImmortal(mro); + } + self->tp_mro = mro; +} + +static inline void +clear_tp_mro(PyTypeObject *self) +{ + if (self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) { + if (_Py_IsMainInterpreter(_PyInterpreterState_GET())) { + if (self->tp_mro != NULL) { + if (PyTuple_GET_SIZE(self->tp_mro) == 0) { + Py_CLEAR(self->tp_mro); + } + else { + assert(_Py_IsImmortal(self->tp_mro)); + _Py_ClearImmortal(self->tp_mro); + } + } + } + return; + } + Py_CLEAR(self->tp_mro); +} + + +static PyObject * +init_tp_subclasses(PyTypeObject *self) +{ + PyObject *subclasses = PyDict_New(); + if (subclasses == NULL) { + return NULL; + } + if (self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) { + PyInterpreterState *interp = _PyInterpreterState_GET(); + static_builtin_state *state = _PyStaticType_GetState(interp, self); + state->tp_subclasses = subclasses; + return subclasses; + } + self->tp_subclasses = (void *)subclasses; + return subclasses; +} + +static void +clear_tp_subclasses(PyTypeObject *self) +{ + /* Delete the dictionary to save memory. _PyStaticType_Dealloc() + callers also test if tp_subclasses is NULL to check if a static type + has no subclass. */ + if (self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) { + PyInterpreterState *interp = _PyInterpreterState_GET(); + static_builtin_state *state = _PyStaticType_GetState(interp, self); + Py_CLEAR(state->tp_subclasses); + return; + } + Py_CLEAR(self->tp_subclasses); +} + +static inline PyObject * +lookup_tp_subclasses(PyTypeObject *self) +{ + if (self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) { + PyInterpreterState *interp = _PyInterpreterState_GET(); + static_builtin_state *state = _PyStaticType_GetState(interp, self); + assert(state != NULL); + return state->tp_subclasses; + } + return (PyObject *)self->tp_subclasses; +} + +int +_PyType_HasSubclasses(PyTypeObject *self) +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + if (self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN + // XXX _PyStaticType_GetState() should never return NULL. + && _PyStaticType_GetState(interp, self) == NULL) + { + return 0; + } + if (lookup_tp_subclasses(self) == NULL) { + return 0; + } + return 1; +} + +PyObject* +_PyType_GetSubclasses(PyTypeObject *self) +{ + PyObject *list = PyList_New(0); + if (list == NULL) { + return NULL; + } + + PyObject *subclasses = lookup_tp_subclasses(self); // borrowed ref + if (subclasses == NULL) { + return list; + } + assert(PyDict_CheckExact(subclasses)); + // The loop cannot modify tp_subclasses, there is no need + // to hold a strong reference (use a borrowed reference). + + Py_ssize_t i = 0; + PyObject *ref; // borrowed ref + while (PyDict_Next(subclasses, &i, NULL, &ref)) { + PyTypeObject *subclass = type_from_ref(ref); // borrowed + if (subclass == NULL) { + continue; + } + + if (PyList_Append(list, _PyObject_CAST(subclass)) < 0) { + Py_DECREF(list); + return NULL; + } + } + return list; +} + +/* end accessors for objects stored on PyTypeObject */ + + /* * finds the beginning of the docstring's introspection signature. * if present, returns a pointer pointing to the first '('. @@ -134,8 +542,8 @@ _PyType_CheckConsistency(PyTypeObject *type) CHECK(Py_REFCNT(type) >= 1); CHECK(PyType_Check(type)); - CHECK(!(type->tp_flags & Py_TPFLAGS_READYING)); - CHECK(type->tp_dict != NULL); + CHECK(!is_readying(type)); + CHECK(lookup_tp_dict(type) != NULL); if (type->tp_flags & Py_TPFLAGS_HAVE_GC) { // bpo-44263: tp_traverse is required if Py_TPFLAGS_HAVE_GC is set. @@ -145,7 +553,7 @@ _PyType_CheckConsistency(PyTypeObject *type) if (type->tp_flags & Py_TPFLAGS_DISALLOW_INSTANTIATION) { CHECK(type->tp_new == NULL); - CHECK(PyDict_Contains(type->tp_dict, &_Py_ID(__new__)) == 0); + CHECK(PyDict_Contains(lookup_tp_dict(type), &_Py_ID(__new__)) == 0); } return 1; @@ -204,7 +612,7 @@ static struct type_cache* get_type_cache(void) { PyInterpreterState *interp = _PyInterpreterState_GET(); - return &interp->type_cache; + return &interp->types.type_cache; } @@ -223,7 +631,7 @@ type_cache_clear(struct type_cache *cache, PyObject *value) void _PyType_InitCache(PyInterpreterState *interp) { - struct type_cache *cache = &interp->type_cache; + struct type_cache *cache = &interp->types.type_cache; for (Py_ssize_t i = 0; i < (1 << MCACHE_SIZE_EXP); i++) { struct type_cache_entry *entry = &cache->hashtable[i]; assert(entry->name == NULL); @@ -231,7 +639,7 @@ _PyType_InitCache(PyInterpreterState *interp) entry->version = 0; // Set to None so _PyType_Lookup() can use Py_SETREF(), // rather than using slower Py_XSETREF(). - entry->name = Py_NewRef(Py_None); + entry->name = Py_None; entry->value = NULL; } } @@ -240,24 +648,12 @@ _PyType_InitCache(PyInterpreterState *interp) static unsigned int _PyType_ClearCache(PyInterpreterState *interp) { - struct type_cache *cache = &interp->type_cache; -#if MCACHE_STATS - size_t total = cache->hits + cache->collisions + cache->misses; - fprintf(stderr, "-- Method cache hits = %zd (%d%%)\n", - cache->hits, (int) (100.0 * cache->hits / total)); - fprintf(stderr, "-- Method cache true misses = %zd (%d%%)\n", - cache->misses, (int) (100.0 * cache->misses / total)); - fprintf(stderr, "-- Method cache collisions = %zd (%d%%)\n", - cache->collisions, (int) (100.0 * cache->collisions / total)); - fprintf(stderr, "-- Method cache size = %zd KiB\n", - sizeof(cache->hashtable) / 1024); -#endif - + struct type_cache *cache = &interp->types.type_cache; // Set to None, rather than NULL, so _PyType_Lookup() can // use Py_SETREF() rather than using slower Py_XSETREF(). type_cache_clear(cache, Py_None); - return next_version_tag - 1; + return NEXT_VERSION_TAG(interp) - 1; } @@ -272,13 +668,93 @@ PyType_ClearCache(void) void _PyTypes_Fini(PyInterpreterState *interp) { - struct type_cache *cache = &interp->type_cache; + struct type_cache *cache = &interp->types.type_cache; type_cache_clear(cache, NULL); - if (_Py_IsMainInterpreter(interp)) { - clear_slotdefs(); + + assert(interp->types.num_builtins_initialized == 0); + // All the static builtin types should have been finalized already. + for (size_t i = 0; i < _Py_MAX_STATIC_BUILTIN_TYPES; i++) { + assert(interp->types.builtins[i].type == NULL); + } +} + + +int +PyType_AddWatcher(PyType_WatchCallback callback) +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + + for (int i = 0; i < TYPE_MAX_WATCHERS; i++) { + if (!interp->type_watchers[i]) { + interp->type_watchers[i] = callback; + return i; + } + } + + PyErr_SetString(PyExc_RuntimeError, "no more type watcher IDs available"); + return -1; +} + +static inline int +validate_watcher_id(PyInterpreterState *interp, int watcher_id) +{ + if (watcher_id < 0 || watcher_id >= TYPE_MAX_WATCHERS) { + PyErr_Format(PyExc_ValueError, "Invalid type watcher ID %d", watcher_id); + return -1; + } + if (!interp->type_watchers[watcher_id]) { + PyErr_Format(PyExc_ValueError, "No type watcher set for ID %d", watcher_id); + return -1; } + return 0; +} + +int +PyType_ClearWatcher(int watcher_id) +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + if (validate_watcher_id(interp, watcher_id) < 0) { + return -1; + } + interp->type_watchers[watcher_id] = NULL; + return 0; +} + +static int assign_version_tag(PyInterpreterState *interp, PyTypeObject *type); + +int +PyType_Watch(int watcher_id, PyObject* obj) +{ + if (!PyType_Check(obj)) { + PyErr_SetString(PyExc_ValueError, "Cannot watch non-type"); + return -1; + } + PyTypeObject *type = (PyTypeObject *)obj; + PyInterpreterState *interp = _PyInterpreterState_GET(); + if (validate_watcher_id(interp, watcher_id) < 0) { + return -1; + } + // ensure we will get a callback on the next modification + assign_version_tag(interp, type); + type->tp_watched |= (1 << watcher_id); + return 0; } +int +PyType_Unwatch(int watcher_id, PyObject* obj) +{ + if (!PyType_Check(obj)) { + PyErr_SetString(PyExc_ValueError, "Cannot watch non-type"); + return -1; + } + PyTypeObject *type = (PyTypeObject *)obj; + PyInterpreterState *interp = _PyInterpreterState_GET(); + if (validate_watcher_id(interp, watcher_id)) { + return -1; + } + type->tp_watched &= ~(1 << watcher_id); + return 0; +} void PyType_Modified(PyTypeObject *type) @@ -302,24 +778,46 @@ PyType_Modified(PyTypeObject *type) return; } - PyObject *subclasses = type->tp_subclasses; + PyObject *subclasses = lookup_tp_subclasses(type); if (subclasses != NULL) { assert(PyDict_CheckExact(subclasses)); Py_ssize_t i = 0; PyObject *ref; while (PyDict_Next(subclasses, &i, NULL, &ref)) { - assert(PyWeakref_CheckRef(ref)); - PyObject *obj = PyWeakref_GET_OBJECT(ref); - if (obj == Py_None) { + PyTypeObject *subclass = type_from_ref(ref); // borrowed + if (subclass == NULL) { continue; } - PyType_Modified(_PyType_CAST(obj)); + PyType_Modified(subclass); + } + } + + // Notify registered type watchers, if any + if (type->tp_watched) { + PyInterpreterState *interp = _PyInterpreterState_GET(); + int bits = type->tp_watched; + int i = 0; + while (bits) { + assert(i < TYPE_MAX_WATCHERS); + if (bits & 1) { + PyType_WatchCallback cb = interp->type_watchers[i]; + if (cb && (cb(type) < 0)) { + PyErr_WriteUnraisable((PyObject *)type); + } + } + i++; + bits >>= 1; } } type->tp_flags &= ~Py_TPFLAGS_VALID_VERSION_TAG; type->tp_version_tag = 0; /* 0 is not a valid version tag */ + if (PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE)) { + // This field *must* be invalidated if the type is modified (see the + // comment on struct _specialization_cache): + ((PyHeapTypeObject *)type)->_spec_cache.getitem = NULL; + } } static void @@ -370,13 +868,20 @@ type_mro_modified(PyTypeObject *type, PyObject *bases) { } } return; + clear: + assert(!(type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN)); type->tp_flags &= ~Py_TPFLAGS_VALID_VERSION_TAG; type->tp_version_tag = 0; /* 0 is not a valid version tag */ + if (PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE)) { + // This field *must* be invalidated if the type is modified (see the + // comment on struct _specialization_cache): + ((PyHeapTypeObject *)type)->_spec_cache.getitem = NULL; + } } static int -assign_version_tag(struct type_cache *cache, PyTypeObject *type) +assign_version_tag(PyInterpreterState *interp, PyTypeObject *type) { /* Ensure that the tp_version_tag is valid and set Py_TPFLAGS_VALID_VERSION_TAG. To respect the invariant, this @@ -390,35 +895,54 @@ assign_version_tag(struct type_cache *cache, PyTypeObject *type) return 0; } - if (next_version_tag == 0) { - /* We have run out of version numbers */ - return 0; + if (type->tp_flags & Py_TPFLAGS_IMMUTABLETYPE) { + /* static types */ + if (NEXT_GLOBAL_VERSION_TAG > _Py_MAX_GLOBAL_TYPE_VERSION_TAG) { + /* We have run out of version numbers */ + return 0; + } + type->tp_version_tag = NEXT_GLOBAL_VERSION_TAG++; + assert (type->tp_version_tag <= _Py_MAX_GLOBAL_TYPE_VERSION_TAG); + } + else { + /* heap types */ + if (NEXT_VERSION_TAG(interp) == 0) { + /* We have run out of version numbers */ + return 0; + } + type->tp_version_tag = NEXT_VERSION_TAG(interp)++; + assert (type->tp_version_tag != 0); } - type->tp_version_tag = next_version_tag++; - assert (type->tp_version_tag != 0); - PyObject *bases = type->tp_bases; + PyObject *bases = lookup_tp_bases(type); Py_ssize_t n = PyTuple_GET_SIZE(bases); for (Py_ssize_t i = 0; i < n; i++) { PyObject *b = PyTuple_GET_ITEM(bases, i); - if (!assign_version_tag(cache, _PyType_CAST(b))) + if (!assign_version_tag(interp, _PyType_CAST(b))) return 0; } type->tp_flags |= Py_TPFLAGS_VALID_VERSION_TAG; return 1; } +int PyUnstable_Type_AssignVersionTag(PyTypeObject *type) +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + return assign_version_tag(interp, type); +} + static PyMemberDef type_members[] = { {"__basicsize__", T_PYSSIZET, offsetof(PyTypeObject,tp_basicsize),READONLY}, {"__itemsize__", T_PYSSIZET, offsetof(PyTypeObject, tp_itemsize), READONLY}, {"__flags__", T_ULONG, offsetof(PyTypeObject, tp_flags), READONLY}, + /* Note that this value is misleading for static builtin types, + since the memory at this offset will always be NULL. */ {"__weakrefoffset__", T_PYSSIZET, offsetof(PyTypeObject, tp_weaklistoffset), READONLY}, {"__base__", T_OBJECT, offsetof(PyTypeObject, tp_base), READONLY}, {"__dictoffset__", T_PYSSIZET, offsetof(PyTypeObject, tp_dictoffset), READONLY}, - {"__mro__", T_OBJECT, offsetof(PyTypeObject, tp_mro), READONLY}, {0} }; @@ -466,8 +990,7 @@ type_name(PyTypeObject *type, void *context) if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) { PyHeapTypeObject* et = (PyHeapTypeObject*)type; - Py_INCREF(et->ht_name); - return et->ht_name; + return Py_NewRef(et->ht_name); } else { return PyUnicode_FromString(_PyType_Name(type)); @@ -479,8 +1002,7 @@ type_qualname(PyTypeObject *type, void *context) { if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) { PyHeapTypeObject* et = (PyHeapTypeObject*)type; - Py_INCREF(et->ht_qualname); - return et->ht_qualname; + return Py_NewRef(et->ht_qualname); } else { return PyUnicode_FromString(_PyType_Name(type)); @@ -512,8 +1034,7 @@ type_set_name(PyTypeObject *type, PyObject *value, void *context) } type->tp_name = tp_name; - Py_INCREF(value); - Py_SETREF(((PyHeapTypeObject*)type)->ht_name, value); + Py_SETREF(((PyHeapTypeObject*)type)->ht_name, Py_NewRef(value)); return 0; } @@ -533,8 +1054,7 @@ type_set_qualname(PyTypeObject *type, PyObject *value, void *context) } et = (PyHeapTypeObject*)type; - Py_INCREF(value); - Py_SETREF(et->ht_qualname, value); + Py_SETREF(et->ht_qualname, Py_NewRef(value)); return 0; } @@ -544,7 +1064,8 @@ type_module(PyTypeObject *type, void *context) PyObject *mod; if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) { - mod = PyDict_GetItemWithError(type->tp_dict, &_Py_ID(__module__)); + PyObject *dict = lookup_tp_dict(type); + mod = PyDict_GetItemWithError(dict, &_Py_ID(__module__)); if (mod == NULL) { if (!PyErr_Occurred()) { PyErr_Format(PyExc_AttributeError, "__module__"); @@ -562,8 +1083,7 @@ type_module(PyTypeObject *type, void *context) PyUnicode_InternInPlace(&mod); } else { - mod = &_Py_ID(builtins); - Py_INCREF(mod); + mod = Py_NewRef(&_Py_ID(builtins)); } } return mod; @@ -577,7 +1097,8 @@ type_set_module(PyTypeObject *type, PyObject *value, void *context) PyType_Modified(type); - return PyDict_SetItem(type->tp_dict, &_Py_ID(__module__), value); + PyObject *dict = lookup_tp_dict(type); + return PyDict_SetItem(dict, &_Py_ID(__module__), value); } static PyObject * @@ -586,17 +1107,17 @@ type_abstractmethods(PyTypeObject *type, void *context) PyObject *mod = NULL; /* type itself has an __abstractmethods__ descriptor (this). Don't return that. */ - if (type != &PyType_Type) - mod = PyDict_GetItemWithError(type->tp_dict, - &_Py_ID(__abstractmethods__)); + if (type != &PyType_Type) { + PyObject *dict = lookup_tp_dict(type); + mod = PyDict_GetItemWithError(dict, &_Py_ID(__abstractmethods__)); + } if (!mod) { if (!PyErr_Occurred()) { PyErr_SetObject(PyExc_AttributeError, &_Py_ID(__abstractmethods__)); } return NULL; } - Py_INCREF(mod); - return mod; + return Py_NewRef(mod); } static int @@ -607,15 +1128,16 @@ type_set_abstractmethods(PyTypeObject *type, PyObject *value, void *context) special to update subclasses. */ int abstract, res; + PyObject *dict = lookup_tp_dict(type); if (value != NULL) { abstract = PyObject_IsTrue(value); if (abstract < 0) return -1; - res = PyDict_SetItem(type->tp_dict, &_Py_ID(__abstractmethods__), value); + res = PyDict_SetItem(dict, &_Py_ID(__abstractmethods__), value); } else { abstract = 0; - res = PyDict_DelItem(type->tp_dict, &_Py_ID(__abstractmethods__)); + res = PyDict_DelItem(dict, &_Py_ID(__abstractmethods__)); if (res && PyErr_ExceptionMatches(PyExc_KeyError)) { PyErr_SetObject(PyExc_AttributeError, &_Py_ID(__abstractmethods__)); return -1; @@ -634,8 +1156,21 @@ type_set_abstractmethods(PyTypeObject *type, PyObject *value, void *context) static PyObject * type_get_bases(PyTypeObject *type, void *context) { - Py_INCREF(type->tp_bases); - return type->tp_bases; + PyObject *bases = lookup_tp_bases(type); + if (bases == NULL) { + Py_RETURN_NONE; + } + return Py_NewRef(bases); +} + +static PyObject * +type_get_mro(PyTypeObject *type, void *context) +{ + PyObject *mro = lookup_tp_mro(type); + if (mro == NULL) { + Py_RETURN_NONE; + } + return Py_NewRef(mro); } static PyTypeObject *best_base(PyObject *); @@ -663,7 +1198,7 @@ mro_hierarchy(PyTypeObject *type, PyObject *temp) /* error / reentrance */ return res; } - PyObject *new_mro = type->tp_mro; + PyObject *new_mro = lookup_tp_mro(type); PyObject *tuple; if (old_mro != NULL) { @@ -682,14 +1217,14 @@ mro_hierarchy(PyTypeObject *type, PyObject *temp) Py_XDECREF(tuple); if (res < 0) { - type->tp_mro = old_mro; + set_tp_mro(type, old_mro); Py_DECREF(new_mro); return -1; } Py_XDECREF(old_mro); // Avoid creating an empty list if there is no subclass - if (type->tp_subclasses != NULL) { + if (_PyType_HasSubclasses(type)) { /* Obtain a copy of subclasses list to iterate over. Otherwise type->tp_subclasses might be altered @@ -761,7 +1296,8 @@ type_set_bases(PyTypeObject *type, PyObject *new_bases, void *context) below), which in turn may cause an inheritance cycle through tp_base chain. And this is definitely not what you want to ever happen. */ - (base->tp_mro != NULL && type_is_subtype_base_chain(base, type))) + (lookup_tp_mro(base) != NULL + && type_is_subtype_base_chain(base, type))) { PyErr_SetString(PyExc_TypeError, "a __bases__ item causes an inheritance cycle"); @@ -778,11 +1314,11 @@ type_set_bases(PyTypeObject *type, PyObject *new_bases, void *context) return -1; } - PyObject *old_bases = type->tp_bases; + PyObject *old_bases = lookup_tp_bases(type); assert(old_bases != NULL); PyTypeObject *old_base = type->tp_base; - type->tp_bases = Py_NewRef(new_bases); + set_tp_bases(type, Py_NewRef(new_bases)); type->tp_base = (PyTypeObject *)Py_NewRef(new_base); PyObject *temp = PyList_New(0); @@ -797,7 +1333,7 @@ type_set_bases(PyTypeObject *type, PyObject *new_bases, void *context) /* Take no action in case if type->tp_bases has been replaced through reentrance. */ int res; - if (type->tp_bases == new_bases) { + if (lookup_tp_bases(type) == new_bases) { /* any base that was in __bases__ but now isn't, we need to remove |type| from its tp_subclasses. conversely, any class now in __bases__ that wasn't @@ -828,19 +1364,18 @@ type_set_bases(PyTypeObject *type, PyObject *new_bases, void *context) PyArg_UnpackTuple(PyList_GET_ITEM(temp, i), "", 2, 3, &cls, &new_mro, &old_mro); /* Do not rollback if cls has a newer version of MRO. */ - if (cls->tp_mro == new_mro) { - Py_XINCREF(old_mro); - cls->tp_mro = old_mro; + if (lookup_tp_mro(cls) == new_mro) { + set_tp_mro(cls, Py_XNewRef(old_mro)); Py_DECREF(new_mro); } } Py_DECREF(temp); bail: - if (type->tp_bases == new_bases) { + if (lookup_tp_bases(type) == new_bases) { assert(type->tp_base == new_base); - type->tp_bases = old_bases; + set_tp_bases(type, old_bases); type->tp_base = old_base; Py_DECREF(new_bases); @@ -858,10 +1393,11 @@ type_set_bases(PyTypeObject *type, PyObject *new_bases, void *context) static PyObject * type_dict(PyTypeObject *type, void *context) { - if (type->tp_dict == NULL) { + PyObject *dict = lookup_tp_dict(type); + if (dict == NULL) { Py_RETURN_NONE; } - return PyDictProxy_New(type->tp_dict); + return PyDictProxy_New(dict); } static PyObject * @@ -871,11 +1407,11 @@ type_get_doc(PyTypeObject *type, void *context) if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE) && type->tp_doc != NULL) { return _PyType_GetDocFromInternalDoc(type->tp_name, type->tp_doc); } - result = PyDict_GetItemWithError(type->tp_dict, &_Py_ID(__doc__)); + PyObject *dict = lookup_tp_dict(type); + result = PyDict_GetItemWithError(dict, &_Py_ID(__doc__)); if (result == NULL) { if (!PyErr_Occurred()) { - result = Py_None; - Py_INCREF(result); + result = Py_NewRef(Py_None); } } else if (Py_TYPE(result)->tp_descr_get) { @@ -900,7 +1436,8 @@ type_set_doc(PyTypeObject *type, PyObject *value, void *context) if (!check_set_special_type_attr(type, value, "__doc__")) return -1; PyType_Modified(type); - return PyDict_SetItem(type->tp_dict, &_Py_ID(__doc__), value); + PyObject *dict = lookup_tp_dict(type); + return PyDict_SetItem(dict, &_Py_ID(__doc__), value); } static PyObject * @@ -912,28 +1449,21 @@ type_get_annotations(PyTypeObject *type, void *context) } PyObject *annotations; - /* there's no _PyDict_GetItemId without WithError, so let's LBYL. */ - if (PyDict_Contains(type->tp_dict, &_Py_ID(__annotations__))) { - annotations = PyDict_GetItemWithError( - type->tp_dict, &_Py_ID(__annotations__)); - /* - ** PyDict_GetItemWithError could still fail, - ** for instance with a well-timed Ctrl-C or a MemoryError. - ** so let's be totally safe. - */ - if (annotations) { - if (Py_TYPE(annotations)->tp_descr_get) { - annotations = Py_TYPE(annotations)->tp_descr_get( - annotations, NULL, (PyObject *)type); - } else { - Py_INCREF(annotations); - } + PyObject *dict = lookup_tp_dict(type); + annotations = PyDict_GetItemWithError(dict, &_Py_ID(__annotations__)); + if (annotations) { + if (Py_TYPE(annotations)->tp_descr_get) { + annotations = Py_TYPE(annotations)->tp_descr_get( + annotations, NULL, (PyObject *)type); + } else { + Py_INCREF(annotations); } - } else { + } + else if (!PyErr_Occurred()) { annotations = PyDict_New(); if (annotations) { int result = PyDict_SetItem( - type->tp_dict, &_Py_ID(__annotations__), annotations); + dict, &_Py_ID(__annotations__), annotations); if (result) { Py_CLEAR(annotations); } else { @@ -955,16 +1485,16 @@ type_set_annotations(PyTypeObject *type, PyObject *value, void *context) } int result; + PyObject *dict = lookup_tp_dict(type); if (value != NULL) { /* set */ - result = PyDict_SetItem(type->tp_dict, &_Py_ID(__annotations__), value); + result = PyDict_SetItem(dict, &_Py_ID(__annotations__), value); } else { /* delete */ - if (!PyDict_Contains(type->tp_dict, &_Py_ID(__annotations__))) { - PyErr_Format(PyExc_AttributeError, "__annotations__"); - return -1; + result = PyDict_DelItem(dict, &_Py_ID(__annotations__)); + if (result < 0 && PyErr_ExceptionMatches(PyExc_KeyError)) { + PyErr_SetString(PyExc_AttributeError, "__annotations__"); } - result = PyDict_DelItem(type->tp_dict, &_Py_ID(__annotations__)); } if (result == 0) { @@ -973,6 +1503,37 @@ type_set_annotations(PyTypeObject *type, PyObject *value, void *context) return result; } +static PyObject * +type_get_type_params(PyTypeObject *type, void *context) +{ + PyObject *params = PyDict_GetItemWithError(lookup_tp_dict(type), &_Py_ID(__type_params__)); + + if (params) { + return Py_NewRef(params); + } + if (PyErr_Occurred()) { + return NULL; + } + + return PyTuple_New(0); +} + +static int +type_set_type_params(PyTypeObject *type, PyObject *value, void *context) +{ + if (!check_set_special_type_attr(type, value, "__type_params__")) { + return -1; + } + + PyObject *dict = lookup_tp_dict(type); + int result = PyDict_SetItem(dict, &_Py_ID(__type_params__), value); + + if (result == 0) { + PyType_Modified(type); + } + return result; +} + /*[clinic input] type.__instancecheck__ -> bool @@ -1011,6 +1572,7 @@ static PyGetSetDef type_getsets[] = { {"__name__", (getter)type_name, (setter)type_set_name, NULL}, {"__qualname__", (getter)type_qualname, (setter)type_set_qualname, NULL}, {"__bases__", (getter)type_get_bases, (setter)type_set_bases, NULL}, + {"__mro__", (getter)type_get_mro, NULL, NULL}, {"__module__", (getter)type_module, (setter)type_set_module, NULL}, {"__abstractmethods__", (getter)type_abstractmethods, (setter)type_set_abstractmethods, NULL}, @@ -1018,6 +1580,7 @@ static PyGetSetDef type_getsets[] = { {"__doc__", (getter)type_get_doc, (setter)type_set_doc, NULL}, {"__text_signature__", (getter)type_get_text_signature, NULL, NULL}, {"__annotations__", (getter)type_get_annotations, (setter)type_set_annotations, NULL}, + {"__type_params__", (getter)type_get_type_params, (setter)type_set_type_params, NULL}, {0} }; @@ -1036,8 +1599,7 @@ type_repr(PyTypeObject *type) if (mod == NULL) PyErr_Clear(); else if (!PyUnicode_Check(mod)) { - Py_DECREF(mod); - mod = NULL; + Py_SETREF(mod, NULL); } name = type_qualname(type, NULL); if (name == NULL) { @@ -1077,8 +1639,7 @@ type_call(PyTypeObject *type, PyObject *args, PyObject *kwds) if (nargs == 1 && (kwds == NULL || !PyDict_GET_SIZE(kwds))) { obj = (PyObject *) Py_TYPE(PyTuple_GET_ITEM(args, 0)); - Py_INCREF(obj); - return obj; + return Py_NewRef(obj); } /* SF bug 475327 -- if that didn't trigger, we need 3 @@ -1112,8 +1673,7 @@ type_call(PyTypeObject *type, PyObject *args, PyObject *kwds) int res = type->tp_init(obj, args, kwds); if (res < 0) { assert(_PyErr_Occurred(tstate)); - Py_DECREF(obj); - obj = NULL; + Py_SETREF(obj, NULL); } else { assert(!_PyErr_Occurred(tstate)); @@ -1126,8 +1686,13 @@ PyObject * _PyType_AllocNoTrack(PyTypeObject *type, Py_ssize_t nitems) { PyObject *obj; + /* The +1 on nitems is needed for most types but not all. We could save a + * bit of space by allocating one less item in certain cases, depending on + * the type. However, given the extra complexity (e.g. an additional type + * flag to indicate when that is safe) it does not seem worth the memory + * savings. An example type that doesn't need the +1 is a subclass of + * tuple. See GH-100659 and GH-81381. */ const size_t size = _PyObject_VAR_SIZE(type, nitems+1); - /* note that we need to add one, for the sentinel */ const size_t presize = _PyType_PreHeaderSize(type); char *alloc = PyObject_Malloc(size + presize); @@ -1173,6 +1738,12 @@ PyType_GenericNew(PyTypeObject *type, PyObject *args, PyObject *kwds) /* Helpers for subtyping */ +static inline PyMemberDef * +_PyHeapType_GET_MEMBERS(PyHeapTypeObject* type) +{ + return PyObject_GetItemData((PyObject *)type); +} + static int traverse_slots(PyTypeObject *type, PyObject *self, visitproc visit, void *arg) { @@ -1215,18 +1786,21 @@ subtype_traverse(PyObject *self, visitproc visit, void *arg) assert(base); } - if (type->tp_flags & Py_TPFLAGS_MANAGED_DICT) { - assert(type->tp_dictoffset); - int err = _PyObject_VisitInstanceAttributes(self, visit, arg); - if (err) { - return err; - } - } - if (type->tp_dictoffset != base->tp_dictoffset) { - PyObject **dictptr = _PyObject_DictPointer(self); - if (dictptr && *dictptr) - Py_VISIT(*dictptr); + assert(base->tp_dictoffset == 0); + if (type->tp_flags & Py_TPFLAGS_MANAGED_DICT) { + assert(type->tp_dictoffset == -1); + int err = _PyObject_VisitManagedDict(self, visit, arg); + if (err) { + return err; + } + } + else { + PyObject **dictptr = _PyObject_ComputedDictPointer(self); + if (dictptr && *dictptr) { + Py_VISIT(*dictptr); + } + } } if (type->tp_flags & Py_TPFLAGS_HEAPTYPE @@ -1285,10 +1859,12 @@ subtype_clear(PyObject *self) /* Clear the instance dict (if any), to break cycles involving only __dict__ slots (as in the case 'self.__dict__ is self'). */ if (type->tp_flags & Py_TPFLAGS_MANAGED_DICT) { - _PyObject_ClearInstanceAttributes(self); + if ((base->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0) { + _PyObject_ClearManagedDict(self); + } } - if (type->tp_dictoffset != base->tp_dictoffset) { - PyObject **dictptr = _PyObject_DictPointer(self); + else if (type->tp_dictoffset != base->tp_dictoffset) { + PyObject **dictptr = _PyObject_ComputedDictPointer(self); if (dictptr && *dictptr) Py_CLEAR(*dictptr); } @@ -1413,11 +1989,15 @@ subtype_dealloc(PyObject *self) finalizers since they might rely on part of the object being finalized that has already been destroyed. */ if (type->tp_weaklistoffset && !base->tp_weaklistoffset) { - /* Modeled after GET_WEAKREFS_LISTPTR() */ - PyWeakReference **list = (PyWeakReference **) \ - _PyObject_GET_WEAKREFS_LISTPTR(self); - while (*list) + /* Modeled after GET_WEAKREFS_LISTPTR(). + + This is never triggered for static types so we can avoid the + (slightly) more costly _PyObject_GET_WEAKREFS_LISTPTR(). */ + PyWeakReference **list = \ + _PyObject_GET_WEAKREFS_LISTPTR_FROM_OFFSET(self); + while (*list) { _PyWeakref_ClearRef(*list); + } } } @@ -1432,18 +2012,17 @@ subtype_dealloc(PyObject *self) /* If we added a dict, DECREF it, or free inline values. */ if (type->tp_flags & Py_TPFLAGS_MANAGED_DICT) { - PyObject **dictptr = _PyObject_ManagedDictPointer(self); - if (*dictptr != NULL) { - assert(*_PyObject_ValuesPointer(self) == NULL); - Py_DECREF(*dictptr); - *dictptr = NULL; + PyDictOrValues *dorv_ptr = _PyObject_DictOrValuesPointer(self); + if (_PyDictOrValues_IsValues(*dorv_ptr)) { + _PyObject_FreeInstanceAttributes(self); } else { - _PyObject_FreeInstanceAttributes(self); + Py_XDECREF(_PyDictOrValues_GetDict(*dorv_ptr)); } + dorv_ptr->values = NULL; } else if (type->tp_dictoffset && !base->tp_dictoffset) { - PyObject **dictptr = _PyObject_DictPointer(self); + PyObject **dictptr = _PyObject_ComputedDictPointer(self); if (dictptr != NULL) { PyObject *dict = *dictptr; if (dict != NULL) { @@ -1541,7 +2120,7 @@ PyType_IsSubtype(PyTypeObject *a, PyTypeObject *b) { PyObject *mro; - mro = a->tp_mro; + mro = lookup_tp_mro(a); if (mro != NULL) { /* Deal with multiple inheritance without recursion by walking the MRO tuple */ @@ -1647,6 +2226,7 @@ vectorcall_unbound(PyThreadState *tstate, int unbound, PyObject *func, args++; nargsf = nargsf - 1 + PY_VECTORCALL_ARGUMENTS_OFFSET; } + EVAL_CALL_STAT_INC_IF_FUNCTION(EVAL_CALL_SLOT, func); return _PyObject_VectorcallTstate(tstate, func, args, nargsf, NULL); } @@ -1924,17 +2504,17 @@ mro_implementation(PyTypeObject *type) return NULL; } - PyObject *bases = type->tp_bases; + PyObject *bases = lookup_tp_bases(type); Py_ssize_t n = PyTuple_GET_SIZE(bases); for (Py_ssize_t i = 0; i < n; i++) { PyTypeObject *base = _PyType_CAST(PyTuple_GET_ITEM(bases, i)); - if (base->tp_mro == NULL) { + if (lookup_tp_mro(base) == NULL) { PyErr_Format(PyExc_TypeError, "Cannot extend an incomplete type '%.100s'", base->tp_name); return NULL; } - assert(PyTuple_Check(base->tp_mro)); + assert(PyTuple_Check(lookup_tp_mro(base))); } if (n == 1) { @@ -1942,18 +2522,18 @@ mro_implementation(PyTypeObject *type) * is trivial. */ PyTypeObject *base = _PyType_CAST(PyTuple_GET_ITEM(bases, 0)); - Py_ssize_t k = PyTuple_GET_SIZE(base->tp_mro); + PyObject *base_mro = lookup_tp_mro(base); + Py_ssize_t k = PyTuple_GET_SIZE(base_mro); PyObject *result = PyTuple_New(k + 1); if (result == NULL) { return NULL; } - Py_INCREF(type); - PyTuple_SET_ITEM(result, 0, (PyObject *) type); + ; + PyTuple_SET_ITEM(result, 0, Py_NewRef(type)); for (Py_ssize_t i = 0; i < k; i++) { - PyObject *cls = PyTuple_GET_ITEM(base->tp_mro, i); - Py_INCREF(cls); - PyTuple_SET_ITEM(result, i + 1, cls); + PyObject *cls = PyTuple_GET_ITEM(base_mro, i); + PyTuple_SET_ITEM(result, i + 1, Py_NewRef(cls)); } return result; } @@ -1979,7 +2559,7 @@ mro_implementation(PyTypeObject *type) for (Py_ssize_t i = 0; i < n; i++) { PyTypeObject *base = _PyType_CAST(PyTuple_GET_ITEM(bases, i)); - to_merge[i] = base->tp_mro; + to_merge[i] = lookup_tp_mro(base); } to_merge[n] = bases; @@ -1989,8 +2569,7 @@ mro_implementation(PyTypeObject *type) return NULL; } - Py_INCREF(type); - PyList_SET_ITEM(result, 0, (PyObject *)type); + PyList_SET_ITEM(result, 0, Py_NewRef(type)); if (pmerge(result, to_merge, n + 1) < 0) { Py_CLEAR(result); } @@ -2135,10 +2714,9 @@ mro_internal(PyTypeObject *type, PyObject **p_old_mro) /* Keep a reference to be able to do a reentrancy check below. Don't let old_mro be GC'ed and its address be reused for another object, like (suddenly!) a new tp_mro. */ - old_mro = type->tp_mro; - Py_XINCREF(old_mro); + old_mro = Py_XNewRef(lookup_tp_mro(type)); new_mro = mro_invoke(type); /* might cause reentrance */ - reent = (type->tp_mro != old_mro); + reent = (lookup_tp_mro(type) != old_mro); Py_XDECREF(old_mro); if (new_mro == NULL) { return -1; @@ -2149,14 +2727,22 @@ mro_internal(PyTypeObject *type, PyObject **p_old_mro) return 0; } - type->tp_mro = new_mro; + set_tp_mro(type, new_mro); - type_mro_modified(type, type->tp_mro); + type_mro_modified(type, new_mro); /* corner case: the super class might have been hidden from the custom MRO */ - type_mro_modified(type, type->tp_bases); + type_mro_modified(type, lookup_tp_bases(type)); - PyType_Modified(type); + // XXX Expand this to Py_TPFLAGS_IMMUTABLETYPE? + if (!(type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN)) { + PyType_Modified(type); + } + else { + /* For static builtin types, this is only called during init + before the method cache has been populated. */ + assert(_PyType_HasFeature(type, Py_TPFLAGS_VALID_VERSION_TAG)); + } if (p_old_mro != NULL) *p_old_mro = old_mro; /* transfer the ownership */ @@ -2224,36 +2810,13 @@ best_base(PyObject *bases) return base; } -#define ADDED_FIELD_AT_OFFSET(name, offset) \ - (type->tp_ ## name && (base->tp_ ##name == 0) && \ - type->tp_ ## name + sizeof(PyObject *) == (offset) && \ - type->tp_flags & Py_TPFLAGS_HEAPTYPE) - static int -extra_ivars(PyTypeObject *type, PyTypeObject *base) +shape_differs(PyTypeObject *t1, PyTypeObject *t2) { - size_t t_size = type->tp_basicsize; - size_t b_size = base->tp_basicsize; - - assert(t_size >= b_size); /* Else type smaller than base! */ - if (type->tp_itemsize || base->tp_itemsize) { - /* If itemsize is involved, stricter rules */ - return t_size != b_size || - type->tp_itemsize != base->tp_itemsize; - } - /* Check for __dict__ and __weakrefs__ slots in either order */ - if (ADDED_FIELD_AT_OFFSET(weaklistoffset, t_size)) { - t_size -= sizeof(PyObject *); - } - if ((type->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0 && - ADDED_FIELD_AT_OFFSET(dictoffset, t_size)) { - t_size -= sizeof(PyObject *); - } - /* Check __weakrefs__ again, in case it precedes __dict__ */ - if (ADDED_FIELD_AT_OFFSET(weaklistoffset, t_size)) { - t_size -= sizeof(PyObject *); - } - return t_size != b_size; + return ( + t1->tp_basicsize != t2->tp_basicsize || + t1->tp_itemsize != t2->tp_itemsize + ); } static PyTypeObject * @@ -2261,14 +2824,18 @@ solid_base(PyTypeObject *type) { PyTypeObject *base; - if (type->tp_base) + if (type->tp_base) { base = solid_base(type->tp_base); - else + } + else { base = &PyBaseObject_Type; - if (extra_ivars(type, base)) + } + if (shape_differs(type, base)) { return type; - else + } + else { return base; + } } static void object_dealloc(PyObject *); @@ -2373,8 +2940,7 @@ subtype_setdict(PyObject *obj, PyObject *value, void *context) "not a '%.200s'", Py_TYPE(value)->tp_name); return -1; } - Py_XINCREF(value); - Py_XSETREF(*dictptr, value); + Py_XSETREF(*dictptr, Py_XNewRef(value)); return 0; } @@ -2391,17 +2957,17 @@ subtype_getweakref(PyObject *obj, void *context) return NULL; } _PyObject_ASSERT((PyObject *)type, - type->tp_weaklistoffset > 0); + type->tp_weaklistoffset > 0 || + type->tp_weaklistoffset == MANAGED_WEAKREF_OFFSET); _PyObject_ASSERT((PyObject *)type, - ((type->tp_weaklistoffset + sizeof(PyObject *)) - <= (size_t)(type->tp_basicsize))); + ((type->tp_weaklistoffset + (Py_ssize_t)sizeof(PyObject *)) + <= type->tp_basicsize)); weaklistptr = (PyObject **)((char *)obj + type->tp_weaklistoffset); if (*weaklistptr == NULL) result = Py_None; else result = *weaklistptr; - Py_INCREF(result); - return result; + return Py_NewRef(result); } /* Three variants on the subtype_getsets list. */ @@ -2563,8 +3129,7 @@ type_new_visit_slots(type_new_ctx *ctx) if (!ctx->may_add_weak || ctx->add_weak != 0) { PyErr_SetString(PyExc_TypeError, "__weakref__ slot disallowed: " - "either we already got one, " - "or __itemsize__ != 0"); + "we already got one"); return -1; } ctx->add_weak++; @@ -2610,11 +3175,12 @@ type_new_copy_slots(type_new_ctx *ctx, PyObject *dict) goto error; } if (r > 0) { - /* CPython inserts __qualname__ and __classcell__ (when needed) + /* CPython inserts these names (when needed) into the namespace when creating a class. They will be deleted below so won't act as class variables. */ if (!_PyUnicode_Equal(slot, &_Py_ID(__qualname__)) && - !_PyUnicode_Equal(slot, &_Py_ID(__classcell__))) + !_PyUnicode_Equal(slot, &_Py_ID(__classcell__)) && + !_PyUnicode_Equal(slot, &_Py_ID(__classdictcell__))) { PyErr_Format(PyExc_ValueError, "%R in __slots__ conflicts with class variable", @@ -2769,7 +3335,7 @@ type_new_alloc(type_new_ctx *ctx) type->tp_as_mapping = &et->as_mapping; type->tp_as_buffer = &et->as_buffer; - type->tp_bases = Py_NewRef(ctx->bases); + set_tp_bases(type, Py_NewRef(ctx->bases)); type->tp_base = (PyTypeObject *)Py_NewRef(ctx->base); type->tp_dealloc = subtype_dealloc; @@ -2809,7 +3375,8 @@ type_new_set_name(const type_new_ctx *ctx, PyTypeObject *type) static int type_new_set_module(PyTypeObject *type) { - int r = PyDict_Contains(type->tp_dict, &_Py_ID(__module__)); + PyObject *dict = lookup_tp_dict(type); + int r = PyDict_Contains(dict, &_Py_ID(__module__)); if (r < 0) { return -1; } @@ -2830,7 +3397,7 @@ type_new_set_module(PyTypeObject *type) return 0; } - if (PyDict_SetItem(type->tp_dict, &_Py_ID(__module__), module) < 0) { + if (PyDict_SetItem(dict, &_Py_ID(__module__), module) < 0) { return -1; } return 0; @@ -2843,8 +3410,8 @@ static int type_new_set_ht_name(PyTypeObject *type) { PyHeapTypeObject *et = (PyHeapTypeObject *)type; - PyObject *qualname = PyDict_GetItemWithError( - type->tp_dict, &_Py_ID(__qualname__)); + PyObject *dict = lookup_tp_dict(type); + PyObject *qualname = PyDict_GetItemWithError(dict, &_Py_ID(__qualname__)); if (qualname != NULL) { if (!PyUnicode_Check(qualname)) { PyErr_Format(PyExc_TypeError, @@ -2853,7 +3420,7 @@ type_new_set_ht_name(PyTypeObject *type) return -1; } et->ht_qualname = Py_NewRef(qualname); - if (PyDict_DelItem(type->tp_dict, &_Py_ID(__qualname__)) < 0) { + if (PyDict_DelItem(dict, &_Py_ID(__qualname__)) < 0) { return -1; } } @@ -2873,7 +3440,8 @@ type_new_set_ht_name(PyTypeObject *type) static int type_new_set_doc(PyTypeObject *type) { - PyObject *doc = PyDict_GetItemWithError(type->tp_dict, &_Py_ID(__doc__)); + PyObject *dict = lookup_tp_dict(type); + PyObject *doc = PyDict_GetItemWithError(dict, &_Py_ID(__doc__)); if (doc == NULL) { if (PyErr_Occurred()) { return -1; @@ -2908,7 +3476,8 @@ type_new_set_doc(PyTypeObject *type) static int type_new_staticmethod(PyTypeObject *type, PyObject *attr) { - PyObject *func = PyDict_GetItemWithError(type->tp_dict, attr); + PyObject *dict = lookup_tp_dict(type); + PyObject *func = PyDict_GetItemWithError(dict, attr); if (func == NULL) { if (PyErr_Occurred()) { return -1; @@ -2923,7 +3492,7 @@ type_new_staticmethod(PyTypeObject *type, PyObject *attr) if (static_func == NULL) { return -1; } - if (PyDict_SetItem(type->tp_dict, attr, static_func) < 0) { + if (PyDict_SetItem(dict, attr, static_func) < 0) { Py_DECREF(static_func); return -1; } @@ -2935,7 +3504,8 @@ type_new_staticmethod(PyTypeObject *type, PyObject *attr) static int type_new_classmethod(PyTypeObject *type, PyObject *attr) { - PyObject *func = PyDict_GetItemWithError(type->tp_dict, attr); + PyObject *dict = lookup_tp_dict(type); + PyObject *func = PyDict_GetItemWithError(dict, attr); if (func == NULL) { if (PyErr_Occurred()) { return -1; @@ -2951,7 +3521,7 @@ type_new_classmethod(PyTypeObject *type, PyObject *attr) return -1; } - if (PyDict_SetItem(type->tp_dict, attr, method) < 0) { + if (PyDict_SetItem(dict, attr, method) < 0) { Py_DECREF(method); return -1; } @@ -2986,20 +3556,15 @@ type_new_descriptors(const type_new_ctx *ctx, PyTypeObject *type) } } - if (ctx->add_dict && ctx->base->tp_itemsize) { - type->tp_dictoffset = -(long)sizeof(PyObject *); - slotoffset += sizeof(PyObject *); - } - if (ctx->add_weak) { - assert(!ctx->base->tp_itemsize); - type->tp_weaklistoffset = slotoffset; - slotoffset += sizeof(PyObject *); + assert((type->tp_flags & Py_TPFLAGS_MANAGED_WEAKREF) == 0); + type->tp_flags |= Py_TPFLAGS_MANAGED_WEAKREF; + type->tp_weaklistoffset = MANAGED_WEAKREF_OFFSET; } - if (ctx->add_dict && ctx->base->tp_itemsize == 0) { + if (ctx->add_dict) { assert((type->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0); type->tp_flags |= Py_TPFLAGS_MANAGED_DICT; - type->tp_dictoffset = -slotoffset - sizeof(PyObject *)*3; + type->tp_dictoffset = -1; } type->tp_basicsize = slotoffset; @@ -3042,8 +3607,8 @@ type_new_set_slots(const type_new_ctx *ctx, PyTypeObject *type) static int type_new_set_classcell(PyTypeObject *type) { - PyObject *cell = PyDict_GetItemWithError( - type->tp_dict, &_Py_ID(__classcell__)); + PyObject *dict = lookup_tp_dict(type); + PyObject *cell = PyDict_GetItemWithError(dict, &_Py_ID(__classcell__)); if (cell == NULL) { if (PyErr_Occurred()) { return -1; @@ -3060,12 +3625,38 @@ type_new_set_classcell(PyTypeObject *type) } (void)PyCell_Set(cell, (PyObject *) type); - if (PyDict_DelItem(type->tp_dict, &_Py_ID(__classcell__)) < 0) { + if (PyDict_DelItem(dict, &_Py_ID(__classcell__)) < 0) { return -1; } return 0; } +static int +type_new_set_classdictcell(PyTypeObject *type) +{ + PyObject *dict = lookup_tp_dict(type); + PyObject *cell = PyDict_GetItemWithError(dict, &_Py_ID(__classdictcell__)); + if (cell == NULL) { + if (PyErr_Occurred()) { + return -1; + } + return 0; + } + + /* At least one method requires a reference to the dict of its defining class */ + if (!PyCell_Check(cell)) { + PyErr_Format(PyExc_TypeError, + "__classdictcell__ must be a nonlocal cell, not %.200R", + Py_TYPE(cell)); + return -1; + } + + (void)PyCell_Set(cell, (PyObject *)dict); + if (PyDict_DelItem(dict, &_Py_ID(__classdictcell__)) < 0) { + return -1; + } + return 0; +} static int type_new_set_attrs(const type_new_ctx *ctx, PyTypeObject *type) @@ -3110,6 +3701,9 @@ type_new_set_attrs(const type_new_ctx *ctx, PyTypeObject *type) if (type_new_set_classcell(type) < 0) { return -1; } + if (type_new_set_classdictcell(type) < 0) { + return -1; + } return 0; } @@ -3167,7 +3761,7 @@ type_new_init(type_new_ctx *ctx) goto error; } - type->tp_dict = dict; + set_tp_dict(type, dict); PyHeapTypeObject *et = (PyHeapTypeObject*)type; et->ht_slots = ctx->slots; @@ -3367,29 +3961,135 @@ static const PySlot_Offset pyslot_offsets[] = { #include "typeslots.inc" }; -PyObject * -PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases) +/* Align up to the nearest multiple of alignof(max_align_t) + * (like _Py_ALIGN_UP, but for a size rather than pointer) + */ +static Py_ssize_t +_align_up(Py_ssize_t size) { - return PyType_FromModuleAndSpec(NULL, spec, bases); + return (size + ALIGNOF_MAX_ALIGN_T - 1) & ~(ALIGNOF_MAX_ALIGN_T - 1); } -PyObject * -PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases) +/* Given a PyType_FromMetaclass `bases` argument (NULL, type, or tuple of + * types), return a tuple of types. + */ +inline static PyObject * +get_bases_tuple(PyObject *bases_in, PyType_Spec *spec) +{ + if (!bases_in) { + /* Default: look in the spec, fall back to (type,). */ + PyTypeObject *base = &PyBaseObject_Type; // borrowed ref + PyObject *bases = NULL; // borrowed ref + const PyType_Slot *slot; + for (slot = spec->slots; slot->slot; slot++) { + switch (slot->slot) { + case Py_tp_base: + base = slot->pfunc; + break; + case Py_tp_bases: + bases = slot->pfunc; + break; + } + } + if (!bases) { + return PyTuple_Pack(1, base); + } + if (PyTuple_Check(bases)) { + return Py_NewRef(bases); + } + PyErr_SetString(PyExc_SystemError, "Py_tp_bases is not a tuple"); + return NULL; + } + if (PyTuple_Check(bases_in)) { + return Py_NewRef(bases_in); + } + // Not a tuple, should be a single type + return PyTuple_Pack(1, bases_in); +} + +static inline int +check_basicsize_includes_size_and_offsets(PyTypeObject* type) { - PyHeapTypeObject *res; - PyObject *modname; - PyTypeObject *type, *base; + if (type->tp_alloc != PyType_GenericAlloc) { + // Custom allocators can ignore tp_basicsize + return 1; + } + Py_ssize_t max = (Py_ssize_t)type->tp_basicsize; + + if (type->tp_base && type->tp_base->tp_basicsize > type->tp_basicsize) { + PyErr_Format(PyExc_TypeError, + "tp_basicsize for type '%s' (%d) is too small for base '%s' (%d)", + type->tp_name, type->tp_basicsize, + type->tp_base->tp_name, type->tp_base->tp_basicsize); + return 0; + } + if (type->tp_weaklistoffset + (Py_ssize_t)sizeof(PyObject*) > max) { + PyErr_Format(PyExc_TypeError, + "weaklist offset %d is out of bounds for type '%s' (tp_basicsize = %d)", + type->tp_weaklistoffset, + type->tp_name, type->tp_basicsize); + return 0; + } + if (type->tp_dictoffset + (Py_ssize_t)sizeof(PyObject*) > max) { + PyErr_Format(PyExc_TypeError, + "dict offset %d is out of bounds for type '%s' (tp_basicsize = %d)", + type->tp_dictoffset, + type->tp_name, type->tp_basicsize); + return 0; + } + if (type->tp_vectorcall_offset + (Py_ssize_t)sizeof(vectorcallfunc*) > max) { + PyErr_Format(PyExc_TypeError, + "vectorcall offset %d is out of bounds for type '%s' (tp_basicsize = %d)", + type->tp_vectorcall_offset, + type->tp_name, type->tp_basicsize); + return 0; + } + return 1; +} + +static PyObject * +_PyType_FromMetaclass_impl( + PyTypeObject *metaclass, PyObject *module, + PyType_Spec *spec, PyObject *bases_in, int _allow_tp_new) +{ + /* Invariant: A non-NULL value in one of these means this function holds + * a strong reference or owns allocated memory. + * These get decrefed/freed/returned at the end, on both success and error. + */ + PyHeapTypeObject *res = NULL; + PyTypeObject *type; + PyObject *bases = NULL; + char *tp_doc = NULL; + PyObject *ht_name = NULL; + char *_ht_tpname = NULL; + int r; + /* Prepare slots that need special handling. + * Keep in mind that a slot can be given multiple times: + * if that would cause trouble (leaks, UB, ...), raise an exception. + */ + const PyType_Slot *slot; - Py_ssize_t nmembers, weaklistoffset, dictoffset, vectorcalloffset; + Py_ssize_t nmembers = 0; + Py_ssize_t weaklistoffset, dictoffset, vectorcalloffset; char *res_start; - short slot_offset, subslot_offset; nmembers = weaklistoffset = dictoffset = vectorcalloffset = 0; for (slot = spec->slots; slot->slot; slot++) { - if (slot->slot == Py_tp_members) { - nmembers = 0; + if (slot->slot < 0 + || (size_t)slot->slot >= Py_ARRAY_LENGTH(pyslot_offsets)) { + PyErr_SetString(PyExc_RuntimeError, "invalid slot offset"); + goto finally; + } + switch (slot->slot) { + case Py_tp_members: + if (nmembers != 0) { + PyErr_SetString( + PyExc_SystemError, + "Multiple Py_tp_members slots are not supported."); + goto finally; + } for (const PyMemberDef *memb = slot->pfunc; memb->name != NULL; memb++) { nmembers++; if (strcmp(memb->name, "__weaklistoffset__") == 0) { @@ -3410,26 +4110,56 @@ PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases) assert(memb->flags == READONLY); vectorcalloffset = memb->offset; } + if (memb->flags & Py_RELATIVE_OFFSET) { + if (spec->basicsize > 0) { + PyErr_SetString( + PyExc_SystemError, + "With Py_RELATIVE_OFFSET, basicsize must be negative."); + goto finally; + } + if (memb->offset < 0 || memb->offset >= -spec->basicsize) { + PyErr_SetString( + PyExc_SystemError, + "Member offset out of range (0..-basicsize)"); + goto finally; + } + } + } + break; + case Py_tp_doc: + /* For the docstring slot, which usually points to a static string + literal, we need to make a copy */ + if (tp_doc != NULL) { + PyErr_SetString( + PyExc_SystemError, + "Multiple Py_tp_doc slots are not supported."); + goto finally; + } + if (slot->pfunc == NULL) { + PyObject_Free(tp_doc); + tp_doc = NULL; + } + else { + size_t len = strlen(slot->pfunc)+1; + tp_doc = PyObject_Malloc(len); + if (tp_doc == NULL) { + PyErr_NoMemory(); + goto finally; + } + memcpy(tp_doc, slot->pfunc, len); } + break; } } - res = (PyHeapTypeObject*)PyType_GenericAlloc(&PyType_Type, nmembers); - if (res == NULL) - return NULL; - res_start = (char*)res; + /* Prepare the type name and qualname */ if (spec->name == NULL) { PyErr_SetString(PyExc_SystemError, "Type spec does not define the name field."); - goto fail; + goto finally; } - type = &res->ht_type; - /* The flags must be initialized early, before the GC traverses us */ - type->tp_flags = spec->flags | Py_TPFLAGS_HEAPTYPE; - - /* Set the type name and qualname */ const char *s = strrchr(spec->name, '.'); if (s == NULL) { s = spec->name; @@ -3438,11 +4168,10 @@ PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases) s++; } - res->ht_name = PyUnicode_FromString(s); - if (!res->ht_name) { - goto fail; + ht_name = PyUnicode_FromString(s); + if (!ht_name) { + goto finally; } - res->ht_qualname = Py_NewRef(res->ht_name); /* Copy spec->name to a buffer we own. * @@ -3454,119 +4183,207 @@ PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases) * deallocated with the type (if it's non-NULL). */ Py_ssize_t name_buf_len = strlen(spec->name) + 1; - res->_ht_tpname = PyMem_Malloc(name_buf_len); - if (res->_ht_tpname == NULL) { - goto fail; + _ht_tpname = PyMem_Malloc(name_buf_len); + if (_ht_tpname == NULL) { + goto finally; } - type->tp_name = memcpy(res->_ht_tpname, spec->name, name_buf_len); - - res->ht_module = Py_XNewRef(module); + memcpy(_ht_tpname, spec->name, name_buf_len); - /* Adjust for empty tuple bases */ + /* Get a tuple of bases. + * bases is a strong reference (unlike bases_in). + */ + bases = get_bases_tuple(bases_in, spec); if (!bases) { - base = &PyBaseObject_Type; - /* See whether Py_tp_base(s) was specified */ - for (slot = spec->slots; slot->slot; slot++) { - if (slot->slot == Py_tp_base) - base = slot->pfunc; - else if (slot->slot == Py_tp_bases) { - bases = slot->pfunc; + goto finally; + } + + /* If this is an immutable type, check if all bases are also immutable, + * and (for now) fire a deprecation warning if not. + * (This isn't necessary for static types: those can't have heap bases, + * and only heap types can be mutable.) + */ + if (spec->flags & Py_TPFLAGS_IMMUTABLETYPE) { + for (int i=0; i<PyTuple_GET_SIZE(bases); i++) { + PyTypeObject *b = (PyTypeObject*)PyTuple_GET_ITEM(bases, i); + if (!b) { + goto finally; + } + if (!_PyType_HasFeature(b, Py_TPFLAGS_IMMUTABLETYPE)) { + if (PyErr_WarnFormat( + PyExc_DeprecationWarning, + 0, + "Creating immutable type %s from mutable base %s is " + "deprecated, and slated to be disallowed in Python 3.14.", + spec->name, + b->tp_name)) + { + goto finally; + } } } - if (!bases) { - bases = PyTuple_Pack(1, base); - if (!bases) - goto fail; - } - else if (!PyTuple_Check(bases)) { - PyErr_SetString(PyExc_SystemError, "Py_tp_bases is not a tuple"); - goto fail; + } + + /* Calculate the metaclass */ + + if (!metaclass) { + metaclass = &PyType_Type; + } + metaclass = _PyType_CalculateMetaclass(metaclass, bases); + if (metaclass == NULL) { + goto finally; + } + if (!PyType_Check(metaclass)) { + PyErr_Format(PyExc_TypeError, + "Metaclass '%R' is not a subclass of 'type'.", + metaclass); + goto finally; + } + if (metaclass->tp_new && metaclass->tp_new != PyType_Type.tp_new) { + if (_allow_tp_new) { + if (PyErr_WarnFormat( + PyExc_DeprecationWarning, 1, + "Type %s uses PyType_Spec with a metaclass that has custom " + "tp_new. This is deprecated and will no longer be allowed in " + "Python 3.14.", spec->name) < 0) { + goto finally; + } } else { - Py_INCREF(bases); + PyErr_SetString( + PyExc_TypeError, + "Metaclasses with custom tp_new are not supported."); + goto finally; } } - else if (!PyTuple_Check(bases)) { - bases = PyTuple_Pack(1, bases); - if (!bases) - goto fail; - } - else { - Py_INCREF(bases); - } /* Calculate best base, and check that all bases are type objects */ - base = best_base(bases); + PyTypeObject *base = best_base(bases); // borrowed ref if (base == NULL) { - Py_DECREF(bases); - goto fail; + goto finally; } - if (!_PyType_HasFeature(base, Py_TPFLAGS_BASETYPE)) { - PyErr_Format(PyExc_TypeError, - "type '%.100s' is not an acceptable base type", - base->tp_name); - Py_DECREF(bases); - goto fail; + // best_base should check Py_TPFLAGS_BASETYPE & raise a proper exception, + // here we just check its work + assert(_PyType_HasFeature(base, Py_TPFLAGS_BASETYPE)); + + /* Calculate sizes */ + + Py_ssize_t basicsize = spec->basicsize; + Py_ssize_t type_data_offset = spec->basicsize; + if (basicsize == 0) { + /* Inherit */ + basicsize = base->tp_basicsize; + } + else if (basicsize < 0) { + /* Extend */ + type_data_offset = _align_up(base->tp_basicsize); + basicsize = type_data_offset + _align_up(-spec->basicsize); + + /* Inheriting variable-sized types is limited */ + if (base->tp_itemsize + && !((base->tp_flags | spec->flags) & Py_TPFLAGS_ITEMS_AT_END)) + { + PyErr_SetString( + PyExc_SystemError, + "Cannot extend variable-size class without Py_TPFLAGS_ITEMS_AT_END."); + goto finally; + } + } + + Py_ssize_t itemsize = spec->itemsize; + + /* Allocate the new type + * + * Between here and PyType_Ready, we should limit: + * - calls to Python code + * - raising exceptions + * - memory allocations + */ + + res = (PyHeapTypeObject*)metaclass->tp_alloc(metaclass, nmembers); + if (res == NULL) { + goto finally; } + res_start = (char*)res; + + type = &res->ht_type; + /* The flags must be initialized early, before the GC traverses us */ + type->tp_flags = spec->flags | Py_TPFLAGS_HEAPTYPE; + + res->ht_module = Py_XNewRef(module); /* Initialize essential fields */ + type->tp_as_async = &res->as_async; type->tp_as_number = &res->as_number; type->tp_as_sequence = &res->as_sequence; type->tp_as_mapping = &res->as_mapping; type->tp_as_buffer = &res->as_buffer; - /* Set tp_base and tp_bases */ - type->tp_bases = bases; - Py_INCREF(base); - type->tp_base = base; - type->tp_basicsize = spec->basicsize; - type->tp_itemsize = spec->itemsize; + /* Set slots we have prepared */ + + type->tp_base = (PyTypeObject *)Py_NewRef(base); + set_tp_bases(type, bases); + bases = NULL; // We give our reference to bases to the type + + type->tp_doc = tp_doc; + tp_doc = NULL; // Give ownership of the allocated memory to the type + + res->ht_qualname = Py_NewRef(ht_name); + res->ht_name = ht_name; + ht_name = NULL; // Give our reference to the type + + type->tp_name = _ht_tpname; + res->_ht_tpname = _ht_tpname; + _ht_tpname = NULL; // Give ownership to the type + + /* Copy the sizes */ + + type->tp_basicsize = basicsize; + type->tp_itemsize = itemsize; + + /* Copy all the ordinary slots */ for (slot = spec->slots; slot->slot; slot++) { - if (slot->slot < 0 - || (size_t)slot->slot >= Py_ARRAY_LENGTH(pyslot_offsets)) { - PyErr_SetString(PyExc_RuntimeError, "invalid slot offset"); - goto fail; - } - else if (slot->slot == Py_tp_base || slot->slot == Py_tp_bases) { + switch (slot->slot) { + case Py_tp_base: + case Py_tp_bases: + case Py_tp_doc: /* Processed above */ - continue; - } - else if (slot->slot == Py_tp_doc) { - /* For the docstring slot, which usually points to a static string - literal, we need to make a copy */ - if (slot->pfunc == NULL) { - type->tp_doc = NULL; - continue; - } - size_t len = strlen(slot->pfunc)+1; - char *tp_doc = PyObject_Malloc(len); - if (tp_doc == NULL) { - type->tp_doc = NULL; - PyErr_NoMemory(); - goto fail; + break; + case Py_tp_members: + { + /* Move the slots to the heap type itself */ + size_t len = Py_TYPE(type)->tp_itemsize * nmembers; + memcpy(_PyHeapType_GET_MEMBERS(res), slot->pfunc, len); + type->tp_members = _PyHeapType_GET_MEMBERS(res); + PyMemberDef *memb; + Py_ssize_t i; + for (memb = _PyHeapType_GET_MEMBERS(res), i = nmembers; + i > 0; ++memb, --i) + { + if (memb->flags & Py_RELATIVE_OFFSET) { + memb->flags &= ~Py_RELATIVE_OFFSET; + memb->offset += type_data_offset; + } + } } - memcpy(tp_doc, slot->pfunc, len); - type->tp_doc = tp_doc; - } - else if (slot->slot == Py_tp_members) { - /* Move the slots to the heap type itself */ - size_t len = Py_TYPE(type)->tp_itemsize * nmembers; - memcpy(_PyHeapType_GET_MEMBERS(res), slot->pfunc, len); - type->tp_members = _PyHeapType_GET_MEMBERS(res); - } - else { - /* Copy other slots directly */ - PySlot_Offset slotoffsets = pyslot_offsets[slot->slot]; - slot_offset = slotoffsets.slot_offset; - if (slotoffsets.subslot_offset == -1) { - *(void**)((char*)res_start + slot_offset) = slot->pfunc; - } else { - void *parent_slot = *(void**)((char*)res_start + slot_offset); - subslot_offset = slotoffsets.subslot_offset; - *(void**)((char*)parent_slot + subslot_offset) = slot->pfunc; + break; + default: + { + /* Copy other slots directly */ + PySlot_Offset slotoffsets = pyslot_offsets[slot->slot]; + short slot_offset = slotoffsets.slot_offset; + if (slotoffsets.subslot_offset == -1) { + /* Set a slot in the main PyTypeObject */ + *(void**)((char*)res_start + slot_offset) = slot->pfunc; + } + else { + void *procs = *(void**)((char*)res_start + slot_offset); + short subslot_offset = slotoffsets.subslot_offset; + *(void**)((char*)procs + subslot_offset) = slot->pfunc; + } } + break; } } if (type->tp_dealloc == NULL) { @@ -3576,71 +4393,113 @@ PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases) type->tp_dealloc = subtype_dealloc; } - if (vectorcalloffset) { - type->tp_vectorcall_offset = vectorcalloffset; + /* Set up offsets */ + + type->tp_vectorcall_offset = vectorcalloffset; + type->tp_weaklistoffset = weaklistoffset; + type->tp_dictoffset = dictoffset; + + /* Ready the type (which includes inheritance). + * + * After this call we should generally only touch up what's + * accessible to Python code, like __dict__. + */ + + if (PyType_Ready(type) < 0) { + goto finally; } - if (PyType_Ready(type) < 0) - goto fail; + if (!check_basicsize_includes_size_and_offsets(type)) { + goto finally; + } + PyObject *dict = lookup_tp_dict(type); if (type->tp_doc) { PyObject *__doc__ = PyUnicode_FromString(_PyType_DocWithoutSignature(type->tp_name, type->tp_doc)); - if (!__doc__) - goto fail; - r = PyDict_SetItem(type->tp_dict, &_Py_ID(__doc__), __doc__); + if (!__doc__) { + goto finally; + } + r = PyDict_SetItem(dict, &_Py_ID(__doc__), __doc__); Py_DECREF(__doc__); - if (r < 0) - goto fail; + if (r < 0) { + goto finally; + } } if (weaklistoffset) { - type->tp_weaklistoffset = weaklistoffset; - if (PyDict_DelItemString((PyObject *)type->tp_dict, "__weaklistoffset__") < 0) - goto fail; + if (PyDict_DelItem(dict, &_Py_ID(__weaklistoffset__)) < 0) { + goto finally; + } } if (dictoffset) { - type->tp_dictoffset = dictoffset; - if (PyDict_DelItemString((PyObject *)type->tp_dict, "__dictoffset__") < 0) - goto fail; + if (PyDict_DelItem(dict, &_Py_ID(__dictoffset__)) < 0) { + goto finally; + } } /* Set type.__module__ */ - r = PyDict_Contains(type->tp_dict, &_Py_ID(__module__)); + r = PyDict_Contains(dict, &_Py_ID(__module__)); if (r < 0) { - goto fail; + goto finally; } if (r == 0) { s = strrchr(spec->name, '.'); if (s != NULL) { - modname = PyUnicode_FromStringAndSize( + PyObject *modname = PyUnicode_FromStringAndSize( spec->name, (Py_ssize_t)(s - spec->name)); if (modname == NULL) { - goto fail; + goto finally; } - r = PyDict_SetItem(type->tp_dict, &_Py_ID(__module__), modname); + r = PyDict_SetItem(dict, &_Py_ID(__module__), modname); Py_DECREF(modname); - if (r != 0) - goto fail; - } else { + if (r != 0) { + goto finally; + } + } + else { if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, "builtin type %.200s has no __module__ attribute", spec->name)) - goto fail; + goto finally; } } assert(_PyType_CheckConsistency(type)); + + finally: + if (PyErr_Occurred()) { + Py_CLEAR(res); + } + Py_XDECREF(bases); + PyObject_Free(tp_doc); + Py_XDECREF(ht_name); + PyMem_Free(_ht_tpname); return (PyObject*)res; +} - fail: - Py_DECREF(res); - return NULL; +PyObject * +PyType_FromMetaclass(PyTypeObject *metaclass, PyObject *module, + PyType_Spec *spec, PyObject *bases_in) +{ + return _PyType_FromMetaclass_impl(metaclass, module, spec, bases_in, 0); +} + +PyObject * +PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases) +{ + return _PyType_FromMetaclass_impl(NULL, module, spec, bases, 1); +} + +PyObject * +PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases) +{ + return _PyType_FromMetaclass_impl(NULL, NULL, spec, bases, 1); } PyObject * PyType_FromSpec(PyType_Spec *spec) { - return PyType_FromSpecWithBases(spec, NULL); + return _PyType_FromMetaclass_impl(NULL, NULL, spec, NULL, 1); } PyObject * @@ -3720,7 +4579,7 @@ PyType_GetModuleByDef(PyTypeObject *type, PyModuleDef *def) { assert(PyType_Check(type)); - PyObject *mro = type->tp_mro; + PyObject *mro = lookup_tp_mro(type); // The type must be ready assert(mro != NULL); assert(PyTuple_Check(mro)); @@ -3750,6 +4609,34 @@ PyType_GetModuleByDef(PyTypeObject *type, PyModuleDef *def) return NULL; } +void * +PyObject_GetTypeData(PyObject *obj, PyTypeObject *cls) +{ + assert(PyObject_TypeCheck(obj, cls)); + return (char *)obj + _align_up(cls->tp_base->tp_basicsize); +} + +Py_ssize_t +PyType_GetTypeDataSize(PyTypeObject *cls) +{ + ptrdiff_t result = cls->tp_basicsize - _align_up(cls->tp_base->tp_basicsize); + if (result < 0) { + return 0; + } + return result; +} + +void * +PyObject_GetItemData(PyObject *obj) +{ + if (!PyType_HasFeature(Py_TYPE(obj), Py_TPFLAGS_ITEMS_AT_END)) { + PyErr_Format(PyExc_TypeError, + "type '%s' does not have Py_TPFLAGS_ITEMS_AT_END", + Py_TYPE(obj)->tp_name); + return NULL; + } + return (char *)obj + Py_TYPE(obj)->tp_basicsize; +} /* Internal API to look for a name through the MRO, bypassing the method cache. This returns a borrowed reference, and might set an exception. @@ -3769,14 +4656,14 @@ find_name_in_mro(PyTypeObject *type, PyObject *name, int *error) } /* Look in tp_dict of types in MRO */ - PyObject *mro = type->tp_mro; + PyObject *mro = lookup_tp_mro(type); if (mro == NULL) { - if ((type->tp_flags & Py_TPFLAGS_READYING) == 0) { + if (!is_readying(type)) { if (PyType_Ready(type) < 0) { *error = -1; return NULL; } - mro = type->tp_mro; + mro = lookup_tp_mro(type); } if (mro == NULL) { *error = 1; @@ -3791,7 +4678,7 @@ find_name_in_mro(PyTypeObject *type, PyObject *name, int *error) Py_ssize_t n = PyTuple_GET_SIZE(mro); for (Py_ssize_t i = 0; i < n; i++) { PyObject *base = PyTuple_GET_ITEM(mro, i); - PyObject *dict = _PyType_CAST(base)->tp_dict; + PyObject *dict = lookup_tp_dict(_PyType_CAST(base)); assert(dict && PyDict_Check(dict)); res = _PyDict_GetItem_KnownHash(dict, name, hash); if (res != NULL) { @@ -3808,6 +4695,24 @@ done: return res; } +/* Check if the "readied" PyUnicode name + is a double-underscore special name. */ +static int +is_dunder_name(PyObject *name) +{ + Py_ssize_t length = PyUnicode_GET_LENGTH(name); + int kind = PyUnicode_KIND(name); + /* Special names contain at least "__x__" and are always ASCII. */ + if (length > 4 && kind == PyUnicode_1BYTE_KIND) { + const Py_UCS1 *characters = PyUnicode_1BYTE_DATA(name); + return ( + ((characters[length-2] == '_') && (characters[length-1] == '_')) && + ((characters[0] == '_') && (characters[1] == '_')) + ); + } + return 0; +} + /* Internal API to look for a name through the MRO. This returns a borrowed reference, and doesn't set an exception! */ PyObject * @@ -3815,18 +4720,20 @@ _PyType_Lookup(PyTypeObject *type, PyObject *name) { PyObject *res; int error; + PyInterpreterState *interp = _PyInterpreterState_GET(); unsigned int h = MCACHE_HASH_METHOD(type, name); struct type_cache *cache = get_type_cache(); struct type_cache_entry *entry = &cache->hashtable[h]; if (entry->version == type->tp_version_tag && entry->name == name) { -#if MCACHE_STATS - cache->hits++; -#endif assert(_PyType_HasFeature(type, Py_TPFLAGS_VALID_VERSION_TAG)); + OBJECT_STAT_INC_COND(type_cache_hits, !is_dunder_name(name)); + OBJECT_STAT_INC_COND(type_cache_dunder_hits, is_dunder_name(name)); return entry->value; } + OBJECT_STAT_INC_COND(type_cache_misses, !is_dunder_name(name)); + OBJECT_STAT_INC_COND(type_cache_dunder_misses, is_dunder_name(name)); /* We may end up clearing live exceptions below, so make sure it's ours. */ assert(!PyErr_Occurred()); @@ -3848,20 +4755,13 @@ _PyType_Lookup(PyTypeObject *type, PyObject *name) return NULL; } - if (MCACHE_CACHEABLE_NAME(name) && assign_version_tag(cache, type)) { + if (MCACHE_CACHEABLE_NAME(name) && assign_version_tag(interp, type)) { h = MCACHE_HASH_METHOD(type, name); struct type_cache_entry *entry = &cache->hashtable[h]; entry->version = type->tp_version_tag; entry->value = res; /* borrowed */ assert(_PyASCIIObject_CAST(name)->hash != -1); -#if MCACHE_STATS - if (entry->name != Py_None && entry->name != name) { - cache->collisions++; - } - else { - cache->misses++; - } -#endif + OBJECT_STAT_INC_COND(type_cache_collisions, entry->name != Py_None && entry->name != name); assert(_PyType_HasFeature(type, Py_TPFLAGS_VALID_VERSION_TAG)); Py_SETREF(entry->name, Py_NewRef(name)); } @@ -3878,28 +4778,20 @@ _PyType_LookupId(PyTypeObject *type, _Py_Identifier *name) return _PyType_Lookup(type, oname); } -/* Check if the "readied" PyUnicode name - is a double-underscore special name. */ -static int -is_dunder_name(PyObject *name) -{ - Py_ssize_t length = PyUnicode_GET_LENGTH(name); - int kind = PyUnicode_KIND(name); - /* Special names contain at least "__x__" and are always ASCII. */ - if (length > 4 && kind == PyUnicode_1BYTE_KIND) { - const Py_UCS1 *characters = PyUnicode_1BYTE_DATA(name); - return ( - ((characters[length-2] == '_') && (characters[length-1] == '_')) && - ((characters[0] == '_') && (characters[1] == '_')) - ); - } - return 0; -} - /* This is similar to PyObject_GenericGetAttr(), - but uses _PyType_Lookup() instead of just looking in type->tp_dict. */ -static PyObject * -type_getattro(PyTypeObject *type, PyObject *name) + but uses _PyType_Lookup() instead of just looking in type->tp_dict. + + The argument suppress_missing_attribute is used to provide a + fast path for hasattr. The possible values are: + + * NULL: do not suppress the exception + * Non-zero pointer: suppress the PyExc_AttributeError and + set *suppress_missing_attribute to 1 to signal we are returning NULL while + having suppressed the exception (other exceptions are not suppressed) + + */ +PyObject * +_Py_type_getattro_impl(PyTypeObject *type, PyObject *name, int * suppress_missing_attribute) { PyTypeObject *metatype = Py_TYPE(type); PyObject *meta_attribute, *attribute; @@ -3979,12 +4871,25 @@ type_getattro(PyTypeObject *type, PyObject *name) } /* Give up */ - PyErr_Format(PyExc_AttributeError, - "type object '%.50s' has no attribute '%U'", - type->tp_name, name); + if (suppress_missing_attribute == NULL) { + PyErr_Format(PyExc_AttributeError, + "type object '%.100s' has no attribute '%U'", + type->tp_name, name); + } else { + // signal the caller we have not set an PyExc_AttributeError and gave up + *suppress_missing_attribute = 1; + } return NULL; } +/* This is similar to PyObject_GenericGetAttr(), + but uses _PyType_Lookup() instead of just looking in type->tp_dict. */ +PyObject * +_Py_type_getattro(PyTypeObject *type, PyObject *name) +{ + return _Py_type_getattro_impl(type, name, NULL); +} + static int type_setattro(PyTypeObject *type, PyObject *name, PyObject *value) { @@ -4047,39 +4952,89 @@ _PyDictKeys_DecRef(PyDictKeysObject *keys); static void type_dealloc_common(PyTypeObject *type) { - if (type->tp_bases != NULL) { - PyObject *tp, *val, *tb; - PyErr_Fetch(&tp, &val, &tb); - remove_all_subclasses(type, type->tp_bases); - PyErr_Restore(tp, val, tb); + PyObject *bases = lookup_tp_bases(type); + if (bases != NULL) { + PyObject *exc = PyErr_GetRaisedException(); + remove_all_subclasses(type, bases); + PyErr_SetRaisedException(exc); } } -void -_PyStaticType_Dealloc(PyTypeObject *type) +static void +clear_static_tp_subclasses(PyTypeObject *type) { - // If a type still has subtypes, it cannot be deallocated. - // A subtype can inherit attributes and methods of its parent type, - // and a type must no longer be used once it's deallocated. - if (type->tp_subclasses != NULL) { + PyObject *subclasses = lookup_tp_subclasses(type); + if (subclasses == NULL) { return; } + /* Normally it would be a problem to finalize the type if its + tp_subclasses wasn't cleared first. However, this is only + ever called at the end of runtime finalization, so we can be + more liberal in cleaning up. If the given type still has + subtypes at this point then some extension module did not + correctly finalize its objects. + + We can safely obliterate such subtypes since the extension + module and its objects won't be used again, except maybe if + the runtime were re-initialized. In that case the sticky + situation would only happen if the module were re-imported + then and only if the subtype were stored in a global and only + if that global were not overwritten during import. We'd be + fine since the extension is otherwise unsafe and unsupported + in that situation, and likely problematic already. + + In any case, this situation means at least some memory is + going to leak. This mostly only affects embedding scenarios. + */ + + // For now we just do a sanity check and then clear tp_subclasses. + Py_ssize_t i = 0; + PyObject *key, *ref; // borrowed ref + while (PyDict_Next(subclasses, &i, &key, &ref)) { + PyTypeObject *subclass = type_from_ref(ref); // borrowed + if (subclass == NULL) { + continue; + } + // All static builtin subtypes should have been finalized already. + assert(!(subclass->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN)); + } + + clear_tp_subclasses(type); +} + +static void +clear_static_type_objects(PyInterpreterState *interp, PyTypeObject *type) +{ + if (_Py_IsMainInterpreter(interp)) { + Py_CLEAR(type->tp_cache); + } + clear_tp_dict(type); + clear_tp_bases(type); + clear_tp_mro(type); + clear_static_tp_subclasses(type); +} + +void +_PyStaticType_Dealloc(PyInterpreterState *interp, PyTypeObject *type) +{ + assert(type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN); + assert(_Py_IsImmortal((PyObject *)type)); + type_dealloc_common(type); - Py_CLEAR(type->tp_dict); - Py_CLEAR(type->tp_bases); - Py_CLEAR(type->tp_mro); - Py_CLEAR(type->tp_cache); - // type->tp_subclasses is NULL + clear_static_type_objects(interp, type); - // PyObject_ClearWeakRefs() raises an exception if Py_REFCNT() != 0 - if (Py_REFCNT(type) == 0) { - PyObject_ClearWeakRefs((PyObject *)type); + if (_Py_IsMainInterpreter(interp)) { + type->tp_flags &= ~Py_TPFLAGS_READY; + type->tp_flags &= ~Py_TPFLAGS_VALID_VERSION_TAG; + type->tp_version_tag = 0; } - type->tp_flags &= ~Py_TPFLAGS_READY; + _PyStaticType_ClearWeakRefs(interp, type); + static_builtin_state_clear(interp, type); + /* We leave _Py_TPFLAGS_STATIC_BUILTIN set on tp_flags. */ } @@ -4102,7 +5057,7 @@ type_dealloc(PyTypeObject *type) Py_XDECREF(type->tp_bases); Py_XDECREF(type->tp_mro); Py_XDECREF(type->tp_cache); - Py_XDECREF(type->tp_subclasses); + clear_tp_subclasses(type); /* A type's tp_doc is heap allocated, unlike the tp_doc slots * of most other objects. It's okay to cast it to char *. @@ -4122,41 +5077,6 @@ type_dealloc(PyTypeObject *type) } -PyObject* -_PyType_GetSubclasses(PyTypeObject *self) -{ - PyObject *list = PyList_New(0); - if (list == NULL) { - return NULL; - } - - PyObject *subclasses = self->tp_subclasses; // borrowed ref - if (subclasses == NULL) { - return list; - } - assert(PyDict_CheckExact(subclasses)); - // The loop cannot modify tp_subclasses, there is no need - // to hold a strong reference (use a borrowed reference). - - Py_ssize_t i = 0; - PyObject *ref; // borrowed ref - while (PyDict_Next(subclasses, &i, NULL, &ref)) { - assert(PyWeakref_CheckRef(ref)); - PyObject *obj = PyWeakref_GET_OBJECT(ref); // borrowed ref - if (obj == Py_None) { - continue; - } - assert(PyType_Check(obj)); - - if (PyList_Append(list, obj) < 0) { - Py_DECREF(list); - return NULL; - } - } - return list; -} - - /*[clinic input] type.__subclasses__ @@ -4273,16 +5193,17 @@ static PyObject * type___sizeof___impl(PyTypeObject *self) /*[clinic end generated code: output=766f4f16cd3b1854 input=99398f24b9cf45d6]*/ { - Py_ssize_t size; + size_t size; if (self->tp_flags & Py_TPFLAGS_HEAPTYPE) { PyHeapTypeObject* et = (PyHeapTypeObject*)self; size = sizeof(PyHeapTypeObject); if (et->ht_cached_keys) size += _PyDict_KeysSize(et->ht_cached_keys); } - else + else { size = sizeof(PyTypeObject); - return PyLong_FromSsize_t(size); + } + return PyLong_FromSize_t(size); } static PyMethodDef type_methods[] = { @@ -4369,8 +5290,9 @@ type_clear(PyTypeObject *type) */ PyType_Modified(type); - if (type->tp_dict) { - PyDict_Clear(type->tp_dict); + PyObject *dict = lookup_tp_dict(type); + if (dict) { + PyDict_Clear(dict); } Py_CLEAR(((PyHeapTypeObject *)type)->ht_module); @@ -4407,12 +5329,13 @@ PyTypeObject PyType_Type = { 0, /* tp_hash */ (ternaryfunc)type_call, /* tp_call */ 0, /* tp_str */ - (getattrofunc)type_getattro, /* tp_getattro */ + (getattrofunc)_Py_type_getattro, /* tp_getattro */ (setattrofunc)type_setattro, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_TYPE_SUBCLASS | - Py_TPFLAGS_HAVE_VECTORCALL, /* tp_flags */ + Py_TPFLAGS_HAVE_VECTORCALL | + Py_TPFLAGS_ITEMS_AT_END, /* tp_flags */ type_doc, /* tp_doc */ (traverseproc)type_traverse, /* tp_traverse */ (inquiry)type_clear, /* tp_clear */ @@ -4530,9 +5453,10 @@ object_new(PyTypeObject *type, PyObject *args, PyObject *kwds) PyObject *abstract_methods; PyObject *sorted_methods; PyObject *joined; + PyObject* comma_w_quotes_sep; Py_ssize_t method_count; - /* Compute ", ".join(sorted(type.__abstractmethods__)) + /* Compute "', '".join(sorted(type.__abstractmethods__)) into joined. */ abstract_methods = type_abstractmethods(type, NULL); if (abstract_methods == NULL) @@ -4545,22 +5469,28 @@ object_new(PyTypeObject *type, PyObject *args, PyObject *kwds) Py_DECREF(sorted_methods); return NULL; } - _Py_DECLARE_STR(comma_sep, ", "); - joined = PyUnicode_Join(&_Py_STR(comma_sep), sorted_methods); + comma_w_quotes_sep = PyUnicode_FromString("', '"); + joined = PyUnicode_Join(comma_w_quotes_sep, sorted_methods); method_count = PyObject_Length(sorted_methods); Py_DECREF(sorted_methods); - if (joined == NULL) + if (joined == NULL) { + Py_DECREF(comma_w_quotes_sep); return NULL; - if (method_count == -1) + } + if (method_count == -1) { + Py_DECREF(comma_w_quotes_sep); + Py_DECREF(joined); return NULL; + } PyErr_Format(PyExc_TypeError, "Can't instantiate abstract class %s " - "with abstract method%s %U", + "without an implementation for abstract method%s '%U'", type->tp_name, method_count > 1 ? "s" : "", joined); Py_DECREF(joined); + Py_DECREF(comma_w_quotes_sep); return NULL; } PyObject *obj = type->tp_alloc(type, 0); @@ -4591,8 +5521,7 @@ object_repr(PyObject *self) if (mod == NULL) PyErr_Clear(); else if (!PyUnicode_Check(mod)) { - Py_DECREF(mod); - mod = NULL; + Py_SETREF(mod, NULL); } name = type_qualname(type, NULL); if (name == NULL) { @@ -4631,16 +5560,14 @@ object_richcompare(PyObject *self, PyObject *other, int op) /* Return NotImplemented instead of False, so if two objects are compared, both get a chance at the comparison. See issue #1393. */ - res = (self == other) ? Py_True : Py_NotImplemented; - Py_INCREF(res); + res = Py_NewRef((self == other) ? Py_True : Py_NotImplemented); break; case Py_NE: /* By default, __ne__() delegates to __eq__() and inverts the result, unless the latter returns NotImplemented. */ if (Py_TYPE(self)->tp_richcompare == NULL) { - res = Py_NotImplemented; - Py_INCREF(res); + res = Py_NewRef(Py_NotImplemented); break; } res = (*Py_TYPE(self)->tp_richcompare)(self, other, Py_EQ); @@ -4651,17 +5578,15 @@ object_richcompare(PyObject *self, PyObject *other, int op) res = NULL; else { if (ok) - res = Py_False; + res = Py_NewRef(Py_False); else - res = Py_True; - Py_INCREF(res); + res = Py_NewRef(Py_True); } } break; default: - res = Py_NotImplemented; - Py_INCREF(res); + res = Py_NewRef(Py_NotImplemented); break; } @@ -4671,8 +5596,7 @@ object_richcompare(PyObject *self, PyObject *other, int op) static PyObject * object_get_class(PyObject *self, void *closure) { - Py_INCREF(Py_TYPE(self)); - return (PyObject *)(Py_TYPE(self)); + return Py_NewRef(Py_TYPE(self)); } static int @@ -4754,9 +5678,9 @@ compatible_for_assignment(PyTypeObject* oldto, PyTypeObject* newto, const char* !same_slots_added(newbase, oldbase))) { goto differs; } - /* The above does not check for managed __dicts__ */ - if ((oldto->tp_flags & Py_TPFLAGS_MANAGED_DICT) == - ((newto->tp_flags & Py_TPFLAGS_MANAGED_DICT))) + /* The above does not check for the preheader */ + if ((oldto->tp_flags & Py_TPFLAGS_PREHEADER) == + ((newto->tp_flags & Py_TPFLAGS_PREHEADER))) { return 1; } @@ -4855,9 +5779,11 @@ object_set_class(PyObject *self, PyObject *value, void *closure) if (compatible_for_assignment(oldto, newto, "__class__")) { /* Changing the class will change the implicit dict keys, * so we must materialize the dictionary first. */ - assert((oldto->tp_flags & Py_TPFLAGS_MANAGED_DICT) == (newto->tp_flags & Py_TPFLAGS_MANAGED_DICT)); + assert((oldto->tp_flags & Py_TPFLAGS_PREHEADER) == (newto->tp_flags & Py_TPFLAGS_PREHEADER)); _PyObject_GetDictPtr(self); - if (oldto->tp_flags & Py_TPFLAGS_MANAGED_DICT && *_PyObject_ValuesPointer(self)) { + if (oldto->tp_flags & Py_TPFLAGS_MANAGED_DICT && + _PyDictOrValues_IsValues(*_PyObject_DictOrValuesPointer(self))) + { /* Was unable to convert to dict */ PyErr_NoMemory(); return -1; @@ -4916,7 +5842,8 @@ _PyType_GetSlotNames(PyTypeObject *cls) assert(PyType_Check(cls)); /* Get the slot names from the cache in the class if possible. */ - slotnames = PyDict_GetItemWithError(cls->tp_dict, &_Py_ID(__slotnames__)); + PyObject *dict = lookup_tp_dict(cls); + slotnames = PyDict_GetItemWithError(dict, &_Py_ID(__slotnames__)); if (slotnames != NULL) { if (slotnames != Py_None && !PyList_Check(slotnames)) { PyErr_Format(PyExc_TypeError, @@ -4925,8 +5852,7 @@ _PyType_GetSlotNames(PyTypeObject *cls) cls->tp_name, Py_TYPE(slotnames)->tp_name); return NULL; } - Py_INCREF(slotnames); - return slotnames; + return Py_NewRef(slotnames); } else { if (PyErr_Occurred()) { @@ -4972,8 +5898,7 @@ object_getstate_default(PyObject *obj, int required) } if (_PyObject_IsInstanceDictEmpty(obj)) { - state = Py_None; - Py_INCREF(state); + state = Py_NewRef(Py_None); } else { state = PyObject_GenericGetDict(obj, NULL); @@ -4996,7 +5921,7 @@ object_getstate_default(PyObject *obj, int required) { basicsize += sizeof(PyObject *); } - if (Py_TYPE(obj)->tp_weaklistoffset) { + if (Py_TYPE(obj)->tp_weaklistoffset > 0) { basicsize += sizeof(PyObject *); } if (slotnames != Py_None) { @@ -5027,8 +5952,7 @@ object_getstate_default(PyObject *obj, int required) for (i = 0; i < slotnames_size; i++) { PyObject *name, *value; - name = PyList_GET_ITEM(slotnames, i); - Py_INCREF(name); + name = Py_NewRef(PyList_GET_ITEM(slotnames, i)); if (_PyObject_LookupAttr(obj, name, &value) < 0) { Py_DECREF(name); goto error; @@ -5098,7 +6022,7 @@ object_getstate(PyObject *obj, int required) PyCFunction_GET_SELF(getstate) == obj && PyCFunction_GET_FUNCTION(getstate) == object___getstate__) { - /* If __getstate__ is not overriden pass the required argument. */ + /* If __getstate__ is not overridden pass the required argument. */ state = object_getstate_default(obj, required); } else { @@ -5160,10 +6084,8 @@ _PyObject_GetNewArguments(PyObject *obj, PyObject **args, PyObject **kwargs) Py_DECREF(newargs); return -1; } - *args = PyTuple_GET_ITEM(newargs, 0); - Py_INCREF(*args); - *kwargs = PyTuple_GET_ITEM(newargs, 1); - Py_INCREF(*kwargs); + *args = Py_NewRef(PyTuple_GET_ITEM(newargs, 0)); + *kwargs = Py_NewRef(PyTuple_GET_ITEM(newargs, 1)); Py_DECREF(newargs); /* XXX We should perhaps allow None to be passed here. */ @@ -5231,8 +6153,7 @@ _PyObject_GetItemsIter(PyObject *obj, PyObject **listitems, } if (!PyList_Check(obj)) { - *listitems = Py_None; - Py_INCREF(*listitems); + *listitems = Py_NewRef(Py_None); } else { *listitems = PyObject_GetIter(obj); @@ -5241,8 +6162,7 @@ _PyObject_GetItemsIter(PyObject *obj, PyObject **listitems, } if (!PyDict_Check(obj)) { - *dictitems = Py_None; - Py_INCREF(*dictitems); + *dictitems = Py_NewRef(Py_None); } else { PyObject *items = PyObject_CallMethodNoArgs(obj, &_Py_ID(items)); @@ -5307,12 +6227,10 @@ reduce_newobj(PyObject *obj) return NULL; } cls = (PyObject *) Py_TYPE(obj); - Py_INCREF(cls); - PyTuple_SET_ITEM(newargs, 0, cls); + PyTuple_SET_ITEM(newargs, 0, Py_NewRef(cls)); for (i = 0; i < n; i++) { PyObject *v = PyTuple_GET_ITEM(args, i); - Py_INCREF(v); - PyTuple_SET_ITEM(newargs, i+1, v); + PyTuple_SET_ITEM(newargs, i+1, Py_NewRef(v)); } Py_XDECREF(args); } @@ -5420,12 +6338,13 @@ static PyObject * object___reduce_ex___impl(PyObject *self, int protocol) /*[clinic end generated code: output=2e157766f6b50094 input=f326b43fb8a4c5ff]*/ { - static PyObject *objreduce; +#define objreduce \ + (_Py_INTERP_CACHED_OBJECT(_PyInterpreterState_Get(), objreduce)) PyObject *reduce, *res; if (objreduce == NULL) { - objreduce = PyDict_GetItemWithError( - PyBaseObject_Type.tp_dict, &_Py_ID(__reduce__)); + PyObject *dict = lookup_tp_dict(&PyBaseObject_Type); + objreduce = PyDict_GetItemWithError(dict, &_Py_ID(__reduce__)); if (objreduce == NULL && PyErr_Occurred()) { return NULL; } @@ -5456,6 +6375,7 @@ object___reduce_ex___impl(PyObject *self, int protocol) } return _common_reduce(self, protocol); +#undef objreduce } static PyObject * @@ -5491,11 +6411,13 @@ object.__format__ / Default object formatter. + +Return str(self) if format_spec is empty. Raise TypeError otherwise. [clinic start generated code]*/ static PyObject * object___format___impl(PyObject *self, PyObject *format_spec) -/*[clinic end generated code: output=34897efb543a974b input=7c3b3bc53a6fb7fa]*/ +/*[clinic end generated code: output=34897efb543a974b input=b94d8feb006689ea]*/ { /* Issue 7994: If we're converting to a string, we should reject format specifications */ @@ -5560,8 +6482,7 @@ object___dir___impl(PyObject *self) else { /* Copy __dict__ to avoid mutating it. */ PyObject *temp = PyDict_Copy(dict); - Py_DECREF(dict); - dict = temp; + Py_SETREF(dict, temp); } if (dict == NULL) @@ -5689,11 +6610,12 @@ type_add_method(PyTypeObject *type, PyMethodDef *meth) } int err; + PyObject *dict = lookup_tp_dict(type); if (!(meth->ml_flags & METH_COEXIST)) { - err = PyDict_SetDefault(type->tp_dict, name, descr) == NULL; + err = PyDict_SetDefault(dict, name, descr) == NULL; } else { - err = PyDict_SetItem(type->tp_dict, name, descr) < 0; + err = PyDict_SetItem(dict, name, descr) < 0; } if (!isdescr) { Py_DECREF(name); @@ -5732,7 +6654,7 @@ type_add_members(PyTypeObject *type) return 0; } - PyObject *dict = type->tp_dict; + PyObject *dict = lookup_tp_dict(type); for (; memb->name != NULL; memb++) { PyObject *descr = PyDescr_NewMember(type, memb); if (descr == NULL) @@ -5756,7 +6678,7 @@ type_add_getset(PyTypeObject *type) return 0; } - PyObject *dict = type->tp_dict; + PyObject *dict = lookup_tp_dict(type); for (; gsp->name != NULL; gsp++) { PyObject *descr = PyDescr_NewGetSet(type, gsp); if (descr == NULL) { @@ -5786,7 +6708,7 @@ inherit_special(PyTypeObject *type, PyTypeObject *base) if (type->tp_clear == NULL) type->tp_clear = base->tp_clear; } - type->tp_flags |= (base->tp_flags & Py_TPFLAGS_MANAGED_DICT); + type->tp_flags |= (base->tp_flags & Py_TPFLAGS_PREHEADER); if (type->tp_basicsize == 0) type->tp_basicsize = base->tp_basicsize; @@ -5799,6 +6721,7 @@ inherit_special(PyTypeObject *type, PyTypeObject *base) COPYVAL(tp_itemsize); COPYVAL(tp_weaklistoffset); COPYVAL(tp_dictoffset); + #undef COPYVAL /* Setup fast subclass flags */ @@ -5826,15 +6749,20 @@ inherit_special(PyTypeObject *type, PyTypeObject *base) else if (PyType_IsSubtype(base, &PyDict_Type)) { type->tp_flags |= Py_TPFLAGS_DICT_SUBCLASS; } + + /* Setup some inheritable flags */ if (PyType_HasFeature(base, _Py_TPFLAGS_MATCH_SELF)) { type->tp_flags |= _Py_TPFLAGS_MATCH_SELF; } + if (PyType_HasFeature(base, Py_TPFLAGS_ITEMS_AT_END)) { + type->tp_flags |= Py_TPFLAGS_ITEMS_AT_END; + } } static int overrides_hash(PyTypeObject *type) { - PyObject *dict = type->tp_dict; + PyObject *dict = lookup_tp_dict(type); assert(dict != NULL); int r = PyDict_Contains(dict, &_Py_ID(__eq__)); @@ -5972,11 +6900,9 @@ inherit_slots(PyTypeObject *type, PyTypeObject *base) * won't be used automatically. */ COPYSLOT(tp_vectorcall_offset); - /* Inherit Py_TPFLAGS_HAVE_VECTORCALL for non-heap types - * if tp_call is not overridden */ + /* Inherit Py_TPFLAGS_HAVE_VECTORCALL if tp_call is not overridden */ if (!type->tp_call && - _PyType_HasFeature(base, Py_TPFLAGS_HAVE_VECTORCALL) && - _PyType_HasFeature(type, Py_TPFLAGS_IMMUTABLETYPE)) + _PyType_HasFeature(base, Py_TPFLAGS_HAVE_VECTORCALL)) { type->tp_flags |= Py_TPFLAGS_HAVE_VECTORCALL; } @@ -6078,7 +7004,7 @@ type_ready_pre_checks(PyTypeObject *type) static int -type_ready_set_bases(PyTypeObject *type) +type_ready_set_base(PyTypeObject *type) { /* Initialize tp_base (defaults to BaseObject unless that's us) */ PyTypeObject *base = type->tp_base; @@ -6103,6 +7029,12 @@ type_ready_set_bases(PyTypeObject *type) } } + return 0; +} + +static int +type_ready_set_type(PyTypeObject *type) +{ /* Initialize ob_type if NULL. This means extensions that want to be compilable separately on Windows can call PyType_Ready() instead of initializing the ob_type field of their type objects. */ @@ -6110,12 +7042,26 @@ type_ready_set_bases(PyTypeObject *type) NULL when type is &PyBaseObject_Type, and we know its ob_type is not NULL (it's initialized to &PyType_Type). But coverity doesn't know that. */ + PyTypeObject *base = type->tp_base; if (Py_IS_TYPE(type, NULL) && base != NULL) { Py_SET_TYPE(type, Py_TYPE(base)); } - /* Initialize tp_bases */ - PyObject *bases = type->tp_bases; + return 0; +} + +static int +type_ready_set_bases(PyTypeObject *type) +{ + if (type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) { + if (!_Py_IsMainInterpreter(_PyInterpreterState_GET())) { + assert(lookup_tp_bases(type) != NULL); + return 0; + } + assert(lookup_tp_bases(type) == NULL); + } + + PyObject *bases = lookup_tp_bases(type); if (bases == NULL) { PyTypeObject *base = type->tp_base; if (base == NULL) { @@ -6127,7 +7073,7 @@ type_ready_set_bases(PyTypeObject *type) if (bases == NULL) { return -1; } - type->tp_bases = bases; + set_tp_bases(type, bases); } return 0; } @@ -6136,7 +7082,7 @@ type_ready_set_bases(PyTypeObject *type) static int type_ready_set_dict(PyTypeObject *type) { - if (type->tp_dict != NULL) { + if (lookup_tp_dict(type) != NULL) { return 0; } @@ -6144,7 +7090,7 @@ type_ready_set_dict(PyTypeObject *type) if (dict == NULL) { return -1; } - type->tp_dict = dict; + set_tp_dict(type, dict); return 0; } @@ -6154,7 +7100,8 @@ type_ready_set_dict(PyTypeObject *type) static int type_dict_set_doc(PyTypeObject *type) { - int r = PyDict_Contains(type->tp_dict, &_Py_ID(__doc__)); + PyObject *dict = lookup_tp_dict(type); + int r = PyDict_Contains(dict, &_Py_ID(__doc__)); if (r < 0) { return -1; } @@ -6170,14 +7117,14 @@ type_dict_set_doc(PyTypeObject *type) return -1; } - if (PyDict_SetItem(type->tp_dict, &_Py_ID(__doc__), doc) < 0) { + if (PyDict_SetItem(dict, &_Py_ID(__doc__), doc) < 0) { Py_DECREF(doc); return -1; } Py_DECREF(doc); } else { - if (PyDict_SetItem(type->tp_dict, &_Py_ID(__doc__), Py_None) < 0) { + if (PyDict_SetItem(dict, &_Py_ID(__doc__), Py_None) < 0) { return -1; } } @@ -6207,20 +7154,57 @@ type_ready_fill_dict(PyTypeObject *type) return 0; } +static int +type_ready_preheader(PyTypeObject *type) +{ + if (type->tp_flags & Py_TPFLAGS_MANAGED_DICT) { + if (type->tp_dictoffset > 0 || type->tp_dictoffset < -1) { + PyErr_Format(PyExc_TypeError, + "type %s has the Py_TPFLAGS_MANAGED_DICT flag " + "but tp_dictoffset is set", + type->tp_name); + return -1; + } + type->tp_dictoffset = -1; + } + if (type->tp_flags & Py_TPFLAGS_MANAGED_WEAKREF) { + if (type->tp_weaklistoffset != 0 && + type->tp_weaklistoffset != MANAGED_WEAKREF_OFFSET) + { + PyErr_Format(PyExc_TypeError, + "type %s has the Py_TPFLAGS_MANAGED_WEAKREF flag " + "but tp_weaklistoffset is set", + type->tp_name); + return -1; + } + type->tp_weaklistoffset = MANAGED_WEAKREF_OFFSET; + } + return 0; +} static int type_ready_mro(PyTypeObject *type) { + if (type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) { + if (!_Py_IsMainInterpreter(_PyInterpreterState_GET())) { + assert(lookup_tp_mro(type) != NULL); + return 0; + } + assert(lookup_tp_mro(type) == NULL); + } + /* Calculate method resolution order */ if (mro_internal(type, NULL) < 0) { return -1; } - assert(type->tp_mro != NULL); - assert(PyTuple_Check(type->tp_mro)); + PyObject *mro = lookup_tp_mro(type); + assert(mro != NULL); + assert(PyTuple_Check(mro)); - /* All bases of statically allocated type should be statically allocated */ + /* All bases of statically allocated type should be statically allocated, + and static builtin types must have static builtin bases. */ if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) { - PyObject *mro = type->tp_mro; + assert(type->tp_flags & Py_TPFLAGS_IMMUTABLETYPE); Py_ssize_t n = PyTuple_GET_SIZE(mro); for (Py_ssize_t i = 0; i < n; i++) { PyTypeObject *base = _PyType_CAST(PyTuple_GET_ITEM(mro, i)); @@ -6231,6 +7215,8 @@ type_ready_mro(PyTypeObject *type) type->tp_name, base->tp_name); return -1; } + assert(!(type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) || + (base->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN)); } } return 0; @@ -6279,8 +7265,8 @@ type_ready_inherit(PyTypeObject *type) } // Inherit slots - PyObject *mro = type->tp_mro; - Py_ssize_t n = PyTuple_GET_SIZE(type->tp_mro); + PyObject *mro = lookup_tp_mro(type); + Py_ssize_t n = PyTuple_GET_SIZE(mro); for (Py_ssize_t i = 1; i < n; i++) { PyObject *b = PyTuple_GET_ITEM(mro, i); if (PyType_Check(b)) { @@ -6325,7 +7311,8 @@ type_ready_set_hash(PyTypeObject *type) return 0; } - int r = PyDict_Contains(type->tp_dict, &_Py_ID(__hash__)); + PyObject *dict = lookup_tp_dict(type); + int r = PyDict_Contains(dict, &_Py_ID(__hash__)); if (r < 0) { return -1; } @@ -6333,7 +7320,7 @@ type_ready_set_hash(PyTypeObject *type) return 0; } - if (PyDict_SetItem(type->tp_dict, &_Py_ID(__hash__), Py_None) < 0) { + if (PyDict_SetItem(dict, &_Py_ID(__hash__), Py_None) < 0) { return -1; } type->tp_hash = PyObject_HashNotImplemented; @@ -6345,7 +7332,7 @@ type_ready_set_hash(PyTypeObject *type) static int type_ready_add_subclasses(PyTypeObject *type) { - PyObject *bases = type->tp_bases; + PyObject *bases = lookup_tp_bases(type); Py_ssize_t nbase = PyTuple_GET_SIZE(bases); for (Py_ssize_t i = 0; i < nbase; i++) { PyObject *b = PyTuple_GET_ITEM(bases, i); @@ -6360,7 +7347,7 @@ type_ready_add_subclasses(PyTypeObject *type) // Set tp_new and the "__new__" key in the type dictionary. // Use the Py_TPFLAGS_DISALLOW_INSTANTIATION flag. static int -type_ready_set_new(PyTypeObject *type) +type_ready_set_new(PyTypeObject *type, int rerunbuiltin) { PyTypeObject *base = type->tp_base; /* The condition below could use some explanation. @@ -6382,10 +7369,12 @@ type_ready_set_new(PyTypeObject *type) if (!(type->tp_flags & Py_TPFLAGS_DISALLOW_INSTANTIATION)) { if (type->tp_new != NULL) { - // If "__new__" key does not exists in the type dictionary, - // set it to tp_new_wrapper(). - if (add_tp_new_wrapper(type) < 0) { - return -1; + if (!rerunbuiltin || base == NULL || type->tp_new != base->tp_new) { + // If "__new__" key does not exists in the type dictionary, + // set it to tp_new_wrapper(). + if (add_tp_new_wrapper(type) < 0) { + return -1; + } } } else { @@ -6438,15 +7427,34 @@ type_ready_post_checks(PyTypeObject *type) type->tp_name); return -1; } + if (type->tp_flags & Py_TPFLAGS_MANAGED_DICT) { + if (type->tp_dictoffset != -1) { + PyErr_Format(PyExc_SystemError, + "type %s has the Py_TPFLAGS_MANAGED_DICT flag " + "but tp_dictoffset is set to incompatible value", + type->tp_name); + return -1; + } + } + else if (type->tp_dictoffset < (Py_ssize_t)sizeof(PyObject)) { + if (type->tp_dictoffset + type->tp_basicsize <= 0) { + PyErr_Format(PyExc_SystemError, + "type %s has a tp_dictoffset that is too small", + type->tp_name); + } + } return 0; } static int -type_ready(PyTypeObject *type) +type_ready(PyTypeObject *type, int rerunbuiltin) { + _PyObject_ASSERT((PyObject *)type, !is_readying(type)); + start_readying(type); + if (type_ready_pre_checks(type) < 0) { - return -1; + goto error; } #ifdef Py_TRACE_REFS @@ -6460,38 +7468,60 @@ type_ready(PyTypeObject *type) /* Initialize tp_dict: _PyType_IsReady() tests if tp_dict != NULL */ if (type_ready_set_dict(type) < 0) { - return -1; + goto error; + } + if (type_ready_set_base(type) < 0) { + goto error; + } + if (type_ready_set_type(type) < 0) { + goto error; } if (type_ready_set_bases(type) < 0) { - return -1; + goto error; } if (type_ready_mro(type) < 0) { - return -1; + goto error; } - if (type_ready_set_new(type) < 0) { - return -1; + if (type_ready_set_new(type, rerunbuiltin) < 0) { + goto error; } if (type_ready_fill_dict(type) < 0) { - return -1; + goto error; } - if (type_ready_inherit(type) < 0) { - return -1; + if (!rerunbuiltin) { + if (type_ready_inherit(type) < 0) { + goto error; + } + if (type_ready_preheader(type) < 0) { + goto error; + } } if (type_ready_set_hash(type) < 0) { - return -1; + goto error; } if (type_ready_add_subclasses(type) < 0) { - return -1; - } - if (type_ready_managed_dict(type) < 0) { - return -1; + goto error; } - if (type_ready_post_checks(type) < 0) { - return -1; + if (!rerunbuiltin) { + if (type_ready_managed_dict(type) < 0) { + goto error; + } + if (type_ready_post_checks(type) < 0) { + goto error; + } } + + /* All done -- set the ready flag */ + type->tp_flags = type->tp_flags | Py_TPFLAGS_READY; + stop_readying(type); + + assert(_PyType_CheckConsistency(type)); return 0; -} +error: + stop_readying(type); + return -1; +} int PyType_Ready(PyTypeObject *type) @@ -6500,25 +7530,48 @@ PyType_Ready(PyTypeObject *type) assert(_PyType_CheckConsistency(type)); return 0; } - _PyObject_ASSERT((PyObject *)type, - (type->tp_flags & Py_TPFLAGS_READYING) == 0); - - type->tp_flags |= Py_TPFLAGS_READYING; + assert(!(type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN)); /* Historically, all static types were immutable. See bpo-43908 */ if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) { type->tp_flags |= Py_TPFLAGS_IMMUTABLETYPE; } - if (type_ready(type) < 0) { - type->tp_flags &= ~Py_TPFLAGS_READYING; - return -1; + return type_ready(type, 0); +} + +int +_PyStaticType_InitBuiltin(PyInterpreterState *interp, PyTypeObject *self) +{ + assert(_Py_IsImmortal((PyObject *)self)); + assert(!(self->tp_flags & Py_TPFLAGS_HEAPTYPE)); + assert(!(self->tp_flags & Py_TPFLAGS_MANAGED_DICT)); + assert(!(self->tp_flags & Py_TPFLAGS_MANAGED_WEAKREF)); + + int ismain = _Py_IsMainInterpreter(interp); + if ((self->tp_flags & Py_TPFLAGS_READY) == 0) { + assert(ismain); + + self->tp_flags |= _Py_TPFLAGS_STATIC_BUILTIN; + self->tp_flags |= Py_TPFLAGS_IMMUTABLETYPE; + + assert(NEXT_GLOBAL_VERSION_TAG <= _Py_MAX_GLOBAL_TYPE_VERSION_TAG); + self->tp_version_tag = NEXT_GLOBAL_VERSION_TAG++; + self->tp_flags |= Py_TPFLAGS_VALID_VERSION_TAG; + } + else { + assert(!ismain); + assert(self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN); + assert(self->tp_flags & Py_TPFLAGS_VALID_VERSION_TAG); } - /* All done -- set the ready flag */ - type->tp_flags = (type->tp_flags & ~Py_TPFLAGS_READYING) | Py_TPFLAGS_READY; - assert(_PyType_CheckConsistency(type)); - return 0; + static_builtin_state_init(interp, self); + + int res = type_ready(self, !ismain); + if (res < 0) { + static_builtin_state_clear(interp, self); + } + return res; } @@ -6538,9 +7591,9 @@ add_subclass(PyTypeObject *base, PyTypeObject *type) // Only get tp_subclasses after creating the key and value. // PyWeakref_NewRef() can trigger a garbage collection which can execute // arbitrary Python code and so modify base->tp_subclasses. - PyObject *subclasses = base->tp_subclasses; + PyObject *subclasses = lookup_tp_subclasses(base); if (subclasses == NULL) { - base->tp_subclasses = subclasses = PyDict_New(); + subclasses = init_tp_subclasses(base); if (subclasses == NULL) { Py_DECREF(key); Py_DECREF(ref); @@ -6571,17 +7624,43 @@ add_all_subclasses(PyTypeObject *type, PyObject *bases) return res; } +static PyObject * +get_subclasses_key(PyTypeObject *type, PyTypeObject *base) +{ + PyObject *key = PyLong_FromVoidPtr((void *) type); + if (key != NULL) { + return key; + } + PyErr_Clear(); + + /* This basically means we're out of memory. + We fall back to manually traversing the values. */ + Py_ssize_t i = 0; + PyObject *ref; // borrowed ref + PyObject *subclasses = lookup_tp_subclasses(base); + if (subclasses != NULL) { + while (PyDict_Next(subclasses, &i, &key, &ref)) { + PyTypeObject *subclass = type_from_ref(ref); // borrowed + if (subclass == type) { + return Py_NewRef(key); + } + } + } + /* It wasn't found. */ + return NULL; +} + static void remove_subclass(PyTypeObject *base, PyTypeObject *type) { - PyObject *subclasses = base->tp_subclasses; // borrowed ref + PyObject *subclasses = lookup_tp_subclasses(base); // borrowed ref if (subclasses == NULL) { return; } assert(PyDict_CheckExact(subclasses)); - PyObject *key = PyLong_FromVoidPtr((void *) type); - if (key == NULL || PyDict_DelItem(subclasses, key)) { + PyObject *key = get_subclasses_key(type, base); + if (key != NULL && PyDict_DelItem(subclasses, key)) { /* This can happen if the type initialization errored out before the base subclasses were updated (e.g. a non-str __qualname__ was passed in the type dict). */ @@ -6590,10 +7669,7 @@ remove_subclass(PyTypeObject *base, PyTypeObject *type) Py_XDECREF(key); if (PyDict_Size(subclasses) == 0) { - // Delete the dictionary to save memory. _PyStaticType_Dealloc() - // callers also test if tp_subclasses is NULL to check if a static type - // has no subclass. - Py_CLEAR(base->tp_subclasses); + clear_tp_subclasses(base); } } @@ -6891,7 +7967,7 @@ static int hackcheck(PyObject *self, setattrofunc func, const char *what) { PyTypeObject *type = Py_TYPE(self); - PyObject *mro = type->tp_mro; + PyObject *mro = lookup_tp_mro(type); if (!mro) { /* Probably ok not to check the call in this case. */ return 1; @@ -7085,12 +8161,69 @@ wrap_descr_delete(PyObject *self, PyObject *args, void *wrapped) PyObject *obj; int ret; - if (!check_num_args(args, 1)) + if (!check_num_args(args, 1)) + return NULL; + obj = PyTuple_GET_ITEM(args, 0); + ret = (*func)(self, obj, NULL); + if (ret < 0) + return NULL; + Py_RETURN_NONE; +} + +static PyObject * +wrap_buffer(PyObject *self, PyObject *args, void *wrapped) +{ + PyObject *arg = NULL; + + if (!PyArg_UnpackTuple(args, "", 1, 1, &arg)) { + return NULL; + } + Py_ssize_t flags = PyNumber_AsSsize_t(arg, PyExc_OverflowError); + if (flags == -1 && PyErr_Occurred()) { + return NULL; + } + if (flags > INT_MAX) { + PyErr_SetString(PyExc_OverflowError, + "buffer flags too large"); + return NULL; + } + + return _PyMemoryView_FromBufferProc(self, Py_SAFE_DOWNCAST(flags, Py_ssize_t, int), + (getbufferproc)wrapped); +} + +static PyObject * +wrap_releasebuffer(PyObject *self, PyObject *args, void *wrapped) +{ + PyObject *arg = NULL; + if (!PyArg_UnpackTuple(args, "", 1, 1, &arg)) { return NULL; - obj = PyTuple_GET_ITEM(args, 0); - ret = (*func)(self, obj, NULL); - if (ret < 0) + } + if (!PyMemoryView_Check(arg)) { + PyErr_SetString(PyExc_TypeError, + "expected a memoryview object"); + return NULL; + } + PyMemoryViewObject *mview = (PyMemoryViewObject *)arg; + if (mview->view.obj == NULL) { + // Already released, ignore + Py_RETURN_NONE; + } + if (mview->view.obj != self) { + PyErr_SetString(PyExc_ValueError, + "memoryview's buffer is not this object"); + return NULL; + } + if (mview->flags & _Py_MEMORYVIEW_RELEASED) { + PyErr_SetString(PyExc_ValueError, + "memoryview's buffer has already been released"); + return NULL; + } + PyObject *res = PyObject_CallMethodNoArgs((PyObject *)mview, &_Py_ID(release)); + if (res == NULL) { return NULL; + } + Py_DECREF(res); Py_RETURN_NONE; } @@ -7179,7 +8312,8 @@ static struct PyMethodDef tp_new_methoddef[] = { static int add_tp_new_wrapper(PyTypeObject *type) { - int r = PyDict_Contains(type->tp_dict, &_Py_ID(__new__)); + PyObject *dict = lookup_tp_dict(type); + int r = PyDict_Contains(dict, &_Py_ID(__new__)); if (r > 0) { return 0; } @@ -7191,7 +8325,7 @@ add_tp_new_wrapper(PyTypeObject *type) if (func == NULL) { return -1; } - r = PyDict_SetItem(type->tp_dict, &_Py_ID(__new__), func); + r = PyDict_SetItem(dict, &_Py_ID(__new__), func); Py_DECREF(func); return r; } @@ -7309,7 +8443,7 @@ slot_sq_length(PyObject *self) return -1; assert(PyLong_Check(res)); - if (Py_SIZE(res) < 0) { + if (_PyLong_IsNegative((PyLongObject *)res)) { Py_DECREF(res); PyErr_SetString(PyExc_ValueError, "__len__() should return >= 0"); @@ -7576,8 +8710,7 @@ slot_tp_hash(PyObject *self) func = lookup_maybe_method(self, &_Py_ID(__hash__), &unbound); if (func == Py_None) { - Py_DECREF(func); - func = NULL; + Py_SETREF(func, NULL); } if (func == NULL) { @@ -7639,26 +8772,33 @@ slot_tp_call(PyObject *self, PyObject *args, PyObject *kwds) /* There are two slot dispatch functions for tp_getattro. - - slot_tp_getattro() is used when __getattribute__ is overridden + - _Py_slot_tp_getattro() is used when __getattribute__ is overridden but no __getattr__ hook is present; - - slot_tp_getattr_hook() is used when a __getattr__ hook is present. + - _Py_slot_tp_getattr_hook() is used when a __getattr__ hook is present. - The code in update_one_slot() always installs slot_tp_getattr_hook(); this - detects the absence of __getattr__ and then installs the simpler slot if - necessary. */ + The code in update_one_slot() always installs _Py_slot_tp_getattr_hook(); + this detects the absence of __getattr__ and then installs the simpler + slot if necessary. */ -static PyObject * -slot_tp_getattro(PyObject *self, PyObject *name) +PyObject * +_Py_slot_tp_getattro(PyObject *self, PyObject *name) { PyObject *stack[2] = {self, name}; return vectorcall_method(&_Py_ID(__getattribute__), stack, 2); } -static PyObject * +static inline PyObject * call_attribute(PyObject *self, PyObject *attr, PyObject *name) { PyObject *res, *descr = NULL; + + if (_PyType_HasFeature(Py_TYPE(attr), Py_TPFLAGS_METHOD_DESCRIPTOR)) { + PyObject *args[] = { self, name }; + res = PyObject_Vectorcall(attr, args, 2, NULL); + return res; + } + descrgetfunc f = Py_TYPE(attr)->tp_descr_get; if (f != NULL) { @@ -7673,8 +8813,8 @@ call_attribute(PyObject *self, PyObject *attr, PyObject *name) return res; } -static PyObject * -slot_tp_getattr_hook(PyObject *self, PyObject *name) +PyObject * +_Py_slot_tp_getattr_hook(PyObject *self, PyObject *name) { PyTypeObject *tp = Py_TYPE(self); PyObject *getattr, *getattribute, *res; @@ -7687,8 +8827,8 @@ slot_tp_getattr_hook(PyObject *self, PyObject *name) getattr = _PyType_Lookup(tp, &_Py_ID(__getattr__)); if (getattr == NULL) { /* No __getattr__ hook: use a simpler dispatcher */ - tp->tp_getattro = slot_tp_getattro; - return slot_tp_getattro(self, name); + tp->tp_getattro = _Py_slot_tp_getattro; + return _Py_slot_tp_getattro(self, name); } Py_INCREF(getattr); /* speed hack: we could use lookup_maybe, but that would resolve the @@ -7700,17 +8840,23 @@ slot_tp_getattr_hook(PyObject *self, PyObject *name) if (getattribute == NULL || (Py_IS_TYPE(getattribute, &PyWrapperDescr_Type) && ((PyWrapperDescrObject *)getattribute)->d_wrapped == - (void *)PyObject_GenericGetAttr)) - res = PyObject_GenericGetAttr(self, name); - else { + (void *)PyObject_GenericGetAttr)) { + res = _PyObject_GenericGetAttrWithDict(self, name, NULL, 1); + /* if res == NULL with no exception set, then it must be an + AttributeError suppressed by us. */ + if (res == NULL && !PyErr_Occurred()) { + res = call_attribute(self, getattr, name); + } + } else { Py_INCREF(getattribute); res = call_attribute(self, getattribute, name); Py_DECREF(getattribute); + if (res == NULL && PyErr_ExceptionMatches(PyExc_AttributeError)) { + PyErr_Clear(); + res = call_attribute(self, getattr, name); + } } - if (res == NULL && PyErr_ExceptionMatches(PyExc_AttributeError)) { - PyErr_Clear(); - res = call_attribute(self, getattr, name); - } + Py_DECREF(getattr); return res; } @@ -7814,14 +8960,14 @@ slot_tp_descr_get(PyObject *self, PyObject *obj, PyObject *type) /* Avoid further slowdowns */ if (tp->tp_descr_get == slot_tp_descr_get) tp->tp_descr_get = NULL; - Py_INCREF(self); - return self; + return Py_NewRef(self); } if (obj == NULL) obj = Py_None; if (type == NULL) type = Py_None; - return PyObject_CallFunctionObjArgs(get, self, obj, type, NULL); + PyObject *stack[3] = {self, obj, type}; + return PyObject_Vectorcall(get, stack, 3, NULL); } static int @@ -7898,10 +9044,9 @@ slot_tp_finalize(PyObject *self) { int unbound; PyObject *del, *res; - PyObject *error_type, *error_value, *error_traceback; /* Save the current exception, if any. */ - PyErr_Fetch(&error_type, &error_value, &error_traceback); + PyObject *exc = PyErr_GetRaisedException(); /* Execute __del__ method, if any. */ del = lookup_maybe_method(self, &_Py_ID(__del__), &unbound); @@ -7915,7 +9060,244 @@ slot_tp_finalize(PyObject *self) } /* Restore the saved exception. */ - PyErr_Restore(error_type, error_value, error_traceback); + PyErr_SetRaisedException(exc); +} + +typedef struct _PyBufferWrapper { + PyObject_HEAD + PyObject *mv; + PyObject *obj; +} PyBufferWrapper; + +static int +bufferwrapper_traverse(PyBufferWrapper *self, visitproc visit, void *arg) +{ + Py_VISIT(self->mv); + Py_VISIT(self->obj); + return 0; +} + +static void +bufferwrapper_dealloc(PyObject *self) +{ + PyBufferWrapper *bw = (PyBufferWrapper *)self; + + _PyObject_GC_UNTRACK(self); + Py_XDECREF(bw->mv); + Py_XDECREF(bw->obj); + Py_TYPE(self)->tp_free(self); +} + +static void +bufferwrapper_releasebuf(PyObject *self, Py_buffer *view) +{ + PyBufferWrapper *bw = (PyBufferWrapper *)self; + + if (bw->mv == NULL || bw->obj == NULL) { + // Already released + return; + } + + PyObject *mv = bw->mv; + PyObject *obj = bw->obj; + + assert(PyMemoryView_Check(mv)); + Py_TYPE(mv)->tp_as_buffer->bf_releasebuffer(mv, view); + // We only need to call bf_releasebuffer if it's a Python function. If it's a C + // bf_releasebuf, it will be called when the memoryview is released. + if (((PyMemoryViewObject *)mv)->view.obj != obj + && Py_TYPE(obj)->tp_as_buffer != NULL + && Py_TYPE(obj)->tp_as_buffer->bf_releasebuffer == slot_bf_releasebuffer) { + releasebuffer_call_python(obj, view); + } + + Py_CLEAR(bw->mv); + Py_CLEAR(bw->obj); +} + +static PyBufferProcs bufferwrapper_as_buffer = { + .bf_releasebuffer = bufferwrapper_releasebuf, +}; + + +PyTypeObject _PyBufferWrapper_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + .tp_name = "_buffer_wrapper", + .tp_basicsize = sizeof(PyBufferWrapper), + .tp_alloc = PyType_GenericAlloc, + .tp_free = PyObject_GC_Del, + .tp_traverse = (traverseproc)bufferwrapper_traverse, + .tp_dealloc = bufferwrapper_dealloc, + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, + .tp_as_buffer = &bufferwrapper_as_buffer, +}; + +static int +slot_bf_getbuffer(PyObject *self, Py_buffer *buffer, int flags) +{ + PyObject *flags_obj = PyLong_FromLong(flags); + if (flags_obj == NULL) { + return -1; + } + PyBufferWrapper *wrapper = NULL; + PyObject *stack[2] = {self, flags_obj}; + PyObject *ret = vectorcall_method(&_Py_ID(__buffer__), stack, 2); + if (ret == NULL) { + goto fail; + } + if (!PyMemoryView_Check(ret)) { + PyErr_Format(PyExc_TypeError, + "__buffer__ returned non-memoryview object"); + goto fail; + } + + if (PyObject_GetBuffer(ret, buffer, flags) < 0) { + goto fail; + } + assert(buffer->obj == ret); + + wrapper = PyObject_GC_New(PyBufferWrapper, &_PyBufferWrapper_Type); + if (wrapper == NULL) { + goto fail; + } + wrapper->mv = ret; + wrapper->obj = Py_NewRef(self); + _PyObject_GC_TRACK(wrapper); + + buffer->obj = (PyObject *)wrapper; + Py_DECREF(ret); + Py_DECREF(flags_obj); + return 0; + +fail: + Py_XDECREF(wrapper); + Py_XDECREF(ret); + Py_DECREF(flags_obj); + return -1; +} + +static int +releasebuffer_maybe_call_super(PyObject *self, Py_buffer *buffer) +{ + PyTypeObject *self_type = Py_TYPE(self); + PyObject *mro = lookup_tp_mro(self_type); + if (mro == NULL) { + return -1; + } + + assert(PyTuple_Check(mro)); + Py_ssize_t n = PyTuple_GET_SIZE(mro); + Py_ssize_t i; + + /* No need to check the last one: it's gonna be skipped anyway. */ + for (i = 0; i < n -1; i++) { + if ((PyObject *)(self_type) == PyTuple_GET_ITEM(mro, i)) + break; + } + i++; /* skip self_type */ + if (i >= n) + return -1; + + releasebufferproc base_releasebuffer = NULL; + for (; i < n; i++) { + PyObject *obj = PyTuple_GET_ITEM(mro, i); + if (!PyType_Check(obj)) { + continue; + } + PyTypeObject *base_type = (PyTypeObject *)obj; + if (base_type->tp_as_buffer != NULL + && base_type->tp_as_buffer->bf_releasebuffer != NULL + && base_type->tp_as_buffer->bf_releasebuffer != slot_bf_releasebuffer) { + base_releasebuffer = base_type->tp_as_buffer->bf_releasebuffer; + break; + } + } + + if (base_releasebuffer != NULL) { + base_releasebuffer(self, buffer); + } + return 0; +} + +static void +releasebuffer_call_python(PyObject *self, Py_buffer *buffer) +{ + // bf_releasebuffer may be called while an exception is already active. + // We have no way to report additional errors up the stack, because + // this slot returns void, so we simply stash away the active exception + // and restore it after the call to Python returns. + PyObject *exc = PyErr_GetRaisedException(); + + PyObject *mv; + bool is_buffer_wrapper = Py_TYPE(buffer->obj) == &_PyBufferWrapper_Type; + if (is_buffer_wrapper) { + // Make sure we pass the same memoryview to + // __release_buffer__() that __buffer__() returned. + PyBufferWrapper *bw = (PyBufferWrapper *)buffer->obj; + if (bw->mv == NULL) { + goto end; + } + mv = Py_NewRef(bw->mv); + } + else { + // This means we are not dealing with a memoryview returned + // from a Python __buffer__ function. + mv = PyMemoryView_FromBuffer(buffer); + if (mv == NULL) { + PyErr_WriteUnraisable(self); + goto end; + } + // Set the memoryview to restricted mode, which forbids + // users from saving any reference to the underlying buffer + // (e.g., by doing .cast()). This is necessary to ensure + // no Python code retains a reference to the to-be-released + // buffer. + ((PyMemoryViewObject *)mv)->flags |= _Py_MEMORYVIEW_RESTRICTED; + } + PyObject *stack[2] = {self, mv}; + PyObject *ret = vectorcall_method(&_Py_ID(__release_buffer__), stack, 2); + if (ret == NULL) { + PyErr_WriteUnraisable(self); + } + else { + Py_DECREF(ret); + } + if (!is_buffer_wrapper) { + PyObject *res = PyObject_CallMethodNoArgs(mv, &_Py_ID(release)); + if (res == NULL) { + PyErr_WriteUnraisable(self); + } + else { + Py_DECREF(res); + } + } + Py_DECREF(mv); +end: + assert(!PyErr_Occurred()); + + PyErr_SetRaisedException(exc); +} + +/* + * bf_releasebuffer is very delicate, because we need to ensure that + * C bf_releasebuffer slots are called correctly (or we'll leak memory), + * but we cannot trust any __release_buffer__ implemented in Python to + * do so correctly. Therefore, if a base class has a C bf_releasebuffer + * slot, we call it directly here. That is safe because this function + * only gets called from C callers of the bf_releasebuffer slot. Python + * code that calls __release_buffer__ directly instead goes through + * wrap_releasebuffer(), which doesn't call the bf_releasebuffer slot + * directly but instead simply releases the associated memoryview. + */ +static void +slot_bf_releasebuffer(PyObject *self, Py_buffer *buffer) +{ + releasebuffer_call_python(self, buffer); + if (releasebuffer_maybe_call_super(self, buffer) < 0) { + if (PyErr_Occurred()) { + PyErr_WriteUnraisable(self); + } + } } static PyObject * @@ -7980,14 +9362,12 @@ which incorporates the additional structures used for numbers, sequences and mappings. Note that multiple names may map to the same slot (e.g. __eq__, __ne__ etc. all map to tp_richcompare) and one name may map to multiple slots (e.g. __str__ affects tp_str as well as tp_repr). The table is terminated with -an all-zero entry. (This table is further initialized in -_PyTypes_InitSlotDefs().) +an all-zero entry. */ -typedef struct wrapperbase slotdef; - #undef TPSLOT #undef FLSLOT +#undef BUFSLOT #undef AMSLOT #undef ETSLOT #undef SQSLOT @@ -7999,14 +9379,16 @@ typedef struct wrapperbase slotdef; #undef RBINSLOT #define TPSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ - {NAME, offsetof(PyTypeObject, SLOT), (void *)(FUNCTION), WRAPPER, \ - PyDoc_STR(DOC)} + {#NAME, offsetof(PyTypeObject, SLOT), (void *)(FUNCTION), WRAPPER, \ + PyDoc_STR(DOC), .name_strobj = &_Py_ID(NAME)} #define FLSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC, FLAGS) \ - {NAME, offsetof(PyTypeObject, SLOT), (void *)(FUNCTION), WRAPPER, \ - PyDoc_STR(DOC), FLAGS} + {#NAME, offsetof(PyTypeObject, SLOT), (void *)(FUNCTION), WRAPPER, \ + PyDoc_STR(DOC), FLAGS, .name_strobj = &_Py_ID(NAME) } #define ETSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ - {NAME, offsetof(PyHeapTypeObject, SLOT), (void *)(FUNCTION), WRAPPER, \ - PyDoc_STR(DOC)} + {#NAME, offsetof(PyHeapTypeObject, SLOT), (void *)(FUNCTION), WRAPPER, \ + PyDoc_STR(DOC), .name_strobj = &_Py_ID(NAME) } +#define BUFSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ + ETSLOT(NAME, as_buffer.SLOT, FUNCTION, WRAPPER, DOC) #define AMSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ ETSLOT(NAME, as_async.SLOT, FUNCTION, WRAPPER, DOC) #define SQSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ @@ -8017,204 +9399,211 @@ typedef struct wrapperbase slotdef; ETSLOT(NAME, as_number.SLOT, FUNCTION, WRAPPER, DOC) #define UNSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ ETSLOT(NAME, as_number.SLOT, FUNCTION, WRAPPER, \ - NAME "($self, /)\n--\n\n" DOC) + #NAME "($self, /)\n--\n\n" DOC) #define IBSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \ ETSLOT(NAME, as_number.SLOT, FUNCTION, WRAPPER, \ - NAME "($self, value, /)\n--\n\nReturn self" DOC "value.") + #NAME "($self, value, /)\n--\n\nReturn self" DOC "value.") #define BINSLOT(NAME, SLOT, FUNCTION, DOC) \ ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_l, \ - NAME "($self, value, /)\n--\n\nReturn self" DOC "value.") + #NAME "($self, value, /)\n--\n\nReturn self" DOC "value.") #define RBINSLOT(NAME, SLOT, FUNCTION, DOC) \ ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_r, \ - NAME "($self, value, /)\n--\n\nReturn value" DOC "self.") + #NAME "($self, value, /)\n--\n\nReturn value" DOC "self.") #define BINSLOTNOTINFIX(NAME, SLOT, FUNCTION, DOC) \ ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_l, \ - NAME "($self, value, /)\n--\n\n" DOC) + #NAME "($self, value, /)\n--\n\n" DOC) #define RBINSLOTNOTINFIX(NAME, SLOT, FUNCTION, DOC) \ ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_r, \ - NAME "($self, value, /)\n--\n\n" DOC) - -static slotdef slotdefs[] = { - TPSLOT("__getattribute__", tp_getattr, NULL, NULL, ""), - TPSLOT("__getattr__", tp_getattr, NULL, NULL, ""), - TPSLOT("__setattr__", tp_setattr, NULL, NULL, ""), - TPSLOT("__delattr__", tp_setattr, NULL, NULL, ""), - TPSLOT("__repr__", tp_repr, slot_tp_repr, wrap_unaryfunc, + #NAME "($self, value, /)\n--\n\n" DOC) + +static pytype_slotdef slotdefs[] = { + TPSLOT(__getattribute__, tp_getattr, NULL, NULL, ""), + TPSLOT(__getattr__, tp_getattr, NULL, NULL, ""), + TPSLOT(__setattr__, tp_setattr, NULL, NULL, ""), + TPSLOT(__delattr__, tp_setattr, NULL, NULL, ""), + TPSLOT(__repr__, tp_repr, slot_tp_repr, wrap_unaryfunc, "__repr__($self, /)\n--\n\nReturn repr(self)."), - TPSLOT("__hash__", tp_hash, slot_tp_hash, wrap_hashfunc, + TPSLOT(__hash__, tp_hash, slot_tp_hash, wrap_hashfunc, "__hash__($self, /)\n--\n\nReturn hash(self)."), - FLSLOT("__call__", tp_call, slot_tp_call, (wrapperfunc)(void(*)(void))wrap_call, + FLSLOT(__call__, tp_call, slot_tp_call, (wrapperfunc)(void(*)(void))wrap_call, "__call__($self, /, *args, **kwargs)\n--\n\nCall self as a function.", PyWrapperFlag_KEYWORDS), - TPSLOT("__str__", tp_str, slot_tp_str, wrap_unaryfunc, + TPSLOT(__str__, tp_str, slot_tp_str, wrap_unaryfunc, "__str__($self, /)\n--\n\nReturn str(self)."), - TPSLOT("__getattribute__", tp_getattro, slot_tp_getattr_hook, + TPSLOT(__getattribute__, tp_getattro, _Py_slot_tp_getattr_hook, wrap_binaryfunc, "__getattribute__($self, name, /)\n--\n\nReturn getattr(self, name)."), - TPSLOT("__getattr__", tp_getattro, slot_tp_getattr_hook, NULL, ""), - TPSLOT("__setattr__", tp_setattro, slot_tp_setattro, wrap_setattr, + TPSLOT(__getattr__, tp_getattro, _Py_slot_tp_getattr_hook, NULL, ""), + TPSLOT(__setattr__, tp_setattro, slot_tp_setattro, wrap_setattr, "__setattr__($self, name, value, /)\n--\n\nImplement setattr(self, name, value)."), - TPSLOT("__delattr__", tp_setattro, slot_tp_setattro, wrap_delattr, + TPSLOT(__delattr__, tp_setattro, slot_tp_setattro, wrap_delattr, "__delattr__($self, name, /)\n--\n\nImplement delattr(self, name)."), - TPSLOT("__lt__", tp_richcompare, slot_tp_richcompare, richcmp_lt, + TPSLOT(__lt__, tp_richcompare, slot_tp_richcompare, richcmp_lt, "__lt__($self, value, /)\n--\n\nReturn self<value."), - TPSLOT("__le__", tp_richcompare, slot_tp_richcompare, richcmp_le, + TPSLOT(__le__, tp_richcompare, slot_tp_richcompare, richcmp_le, "__le__($self, value, /)\n--\n\nReturn self<=value."), - TPSLOT("__eq__", tp_richcompare, slot_tp_richcompare, richcmp_eq, + TPSLOT(__eq__, tp_richcompare, slot_tp_richcompare, richcmp_eq, "__eq__($self, value, /)\n--\n\nReturn self==value."), - TPSLOT("__ne__", tp_richcompare, slot_tp_richcompare, richcmp_ne, + TPSLOT(__ne__, tp_richcompare, slot_tp_richcompare, richcmp_ne, "__ne__($self, value, /)\n--\n\nReturn self!=value."), - TPSLOT("__gt__", tp_richcompare, slot_tp_richcompare, richcmp_gt, + TPSLOT(__gt__, tp_richcompare, slot_tp_richcompare, richcmp_gt, "__gt__($self, value, /)\n--\n\nReturn self>value."), - TPSLOT("__ge__", tp_richcompare, slot_tp_richcompare, richcmp_ge, + TPSLOT(__ge__, tp_richcompare, slot_tp_richcompare, richcmp_ge, "__ge__($self, value, /)\n--\n\nReturn self>=value."), - TPSLOT("__iter__", tp_iter, slot_tp_iter, wrap_unaryfunc, + TPSLOT(__iter__, tp_iter, slot_tp_iter, wrap_unaryfunc, "__iter__($self, /)\n--\n\nImplement iter(self)."), - TPSLOT("__next__", tp_iternext, slot_tp_iternext, wrap_next, + TPSLOT(__next__, tp_iternext, slot_tp_iternext, wrap_next, "__next__($self, /)\n--\n\nImplement next(self)."), - TPSLOT("__get__", tp_descr_get, slot_tp_descr_get, wrap_descr_get, + TPSLOT(__get__, tp_descr_get, slot_tp_descr_get, wrap_descr_get, "__get__($self, instance, owner=None, /)\n--\n\nReturn an attribute of instance, which is of type owner."), - TPSLOT("__set__", tp_descr_set, slot_tp_descr_set, wrap_descr_set, + TPSLOT(__set__, tp_descr_set, slot_tp_descr_set, wrap_descr_set, "__set__($self, instance, value, /)\n--\n\nSet an attribute of instance to value."), - TPSLOT("__delete__", tp_descr_set, slot_tp_descr_set, + TPSLOT(__delete__, tp_descr_set, slot_tp_descr_set, wrap_descr_delete, "__delete__($self, instance, /)\n--\n\nDelete an attribute of instance."), - FLSLOT("__init__", tp_init, slot_tp_init, (wrapperfunc)(void(*)(void))wrap_init, + FLSLOT(__init__, tp_init, slot_tp_init, (wrapperfunc)(void(*)(void))wrap_init, "__init__($self, /, *args, **kwargs)\n--\n\n" "Initialize self. See help(type(self)) for accurate signature.", PyWrapperFlag_KEYWORDS), - TPSLOT("__new__", tp_new, slot_tp_new, NULL, + TPSLOT(__new__, tp_new, slot_tp_new, NULL, "__new__(type, /, *args, **kwargs)\n--\n\n" "Create and return new object. See help(type) for accurate signature."), - TPSLOT("__del__", tp_finalize, slot_tp_finalize, (wrapperfunc)wrap_del, ""), + TPSLOT(__del__, tp_finalize, slot_tp_finalize, (wrapperfunc)wrap_del, ""), - AMSLOT("__await__", am_await, slot_am_await, wrap_unaryfunc, + BUFSLOT(__buffer__, bf_getbuffer, slot_bf_getbuffer, wrap_buffer, + "__buffer__($self, flags, /)\n--\n\n" + "Return a buffer object that exposes the underlying memory of the object."), + BUFSLOT(__release_buffer__, bf_releasebuffer, slot_bf_releasebuffer, wrap_releasebuffer, + "__release_buffer__($self, buffer, /)\n--\n\n" + "Release the buffer object that exposes the underlying memory of the object."), + + AMSLOT(__await__, am_await, slot_am_await, wrap_unaryfunc, "__await__($self, /)\n--\n\nReturn an iterator to be used in await expression."), - AMSLOT("__aiter__", am_aiter, slot_am_aiter, wrap_unaryfunc, + AMSLOT(__aiter__, am_aiter, slot_am_aiter, wrap_unaryfunc, "__aiter__($self, /)\n--\n\nReturn an awaitable, that resolves in asynchronous iterator."), - AMSLOT("__anext__", am_anext, slot_am_anext, wrap_unaryfunc, + AMSLOT(__anext__, am_anext, slot_am_anext, wrap_unaryfunc, "__anext__($self, /)\n--\n\nReturn a value or raise StopAsyncIteration."), - BINSLOT("__add__", nb_add, slot_nb_add, + BINSLOT(__add__, nb_add, slot_nb_add, "+"), - RBINSLOT("__radd__", nb_add, slot_nb_add, + RBINSLOT(__radd__, nb_add, slot_nb_add, "+"), - BINSLOT("__sub__", nb_subtract, slot_nb_subtract, + BINSLOT(__sub__, nb_subtract, slot_nb_subtract, "-"), - RBINSLOT("__rsub__", nb_subtract, slot_nb_subtract, + RBINSLOT(__rsub__, nb_subtract, slot_nb_subtract, "-"), - BINSLOT("__mul__", nb_multiply, slot_nb_multiply, + BINSLOT(__mul__, nb_multiply, slot_nb_multiply, "*"), - RBINSLOT("__rmul__", nb_multiply, slot_nb_multiply, + RBINSLOT(__rmul__, nb_multiply, slot_nb_multiply, "*"), - BINSLOT("__mod__", nb_remainder, slot_nb_remainder, + BINSLOT(__mod__, nb_remainder, slot_nb_remainder, "%"), - RBINSLOT("__rmod__", nb_remainder, slot_nb_remainder, + RBINSLOT(__rmod__, nb_remainder, slot_nb_remainder, "%"), - BINSLOTNOTINFIX("__divmod__", nb_divmod, slot_nb_divmod, + BINSLOTNOTINFIX(__divmod__, nb_divmod, slot_nb_divmod, "Return divmod(self, value)."), - RBINSLOTNOTINFIX("__rdivmod__", nb_divmod, slot_nb_divmod, + RBINSLOTNOTINFIX(__rdivmod__, nb_divmod, slot_nb_divmod, "Return divmod(value, self)."), - NBSLOT("__pow__", nb_power, slot_nb_power, wrap_ternaryfunc, + NBSLOT(__pow__, nb_power, slot_nb_power, wrap_ternaryfunc, "__pow__($self, value, mod=None, /)\n--\n\nReturn pow(self, value, mod)."), - NBSLOT("__rpow__", nb_power, slot_nb_power, wrap_ternaryfunc_r, + NBSLOT(__rpow__, nb_power, slot_nb_power, wrap_ternaryfunc_r, "__rpow__($self, value, mod=None, /)\n--\n\nReturn pow(value, self, mod)."), - UNSLOT("__neg__", nb_negative, slot_nb_negative, wrap_unaryfunc, "-self"), - UNSLOT("__pos__", nb_positive, slot_nb_positive, wrap_unaryfunc, "+self"), - UNSLOT("__abs__", nb_absolute, slot_nb_absolute, wrap_unaryfunc, + UNSLOT(__neg__, nb_negative, slot_nb_negative, wrap_unaryfunc, "-self"), + UNSLOT(__pos__, nb_positive, slot_nb_positive, wrap_unaryfunc, "+self"), + UNSLOT(__abs__, nb_absolute, slot_nb_absolute, wrap_unaryfunc, "abs(self)"), - UNSLOT("__bool__", nb_bool, slot_nb_bool, wrap_inquirypred, + UNSLOT(__bool__, nb_bool, slot_nb_bool, wrap_inquirypred, "True if self else False"), - UNSLOT("__invert__", nb_invert, slot_nb_invert, wrap_unaryfunc, "~self"), - BINSLOT("__lshift__", nb_lshift, slot_nb_lshift, "<<"), - RBINSLOT("__rlshift__", nb_lshift, slot_nb_lshift, "<<"), - BINSLOT("__rshift__", nb_rshift, slot_nb_rshift, ">>"), - RBINSLOT("__rrshift__", nb_rshift, slot_nb_rshift, ">>"), - BINSLOT("__and__", nb_and, slot_nb_and, "&"), - RBINSLOT("__rand__", nb_and, slot_nb_and, "&"), - BINSLOT("__xor__", nb_xor, slot_nb_xor, "^"), - RBINSLOT("__rxor__", nb_xor, slot_nb_xor, "^"), - BINSLOT("__or__", nb_or, slot_nb_or, "|"), - RBINSLOT("__ror__", nb_or, slot_nb_or, "|"), - UNSLOT("__int__", nb_int, slot_nb_int, wrap_unaryfunc, + UNSLOT(__invert__, nb_invert, slot_nb_invert, wrap_unaryfunc, "~self"), + BINSLOT(__lshift__, nb_lshift, slot_nb_lshift, "<<"), + RBINSLOT(__rlshift__, nb_lshift, slot_nb_lshift, "<<"), + BINSLOT(__rshift__, nb_rshift, slot_nb_rshift, ">>"), + RBINSLOT(__rrshift__, nb_rshift, slot_nb_rshift, ">>"), + BINSLOT(__and__, nb_and, slot_nb_and, "&"), + RBINSLOT(__rand__, nb_and, slot_nb_and, "&"), + BINSLOT(__xor__, nb_xor, slot_nb_xor, "^"), + RBINSLOT(__rxor__, nb_xor, slot_nb_xor, "^"), + BINSLOT(__or__, nb_or, slot_nb_or, "|"), + RBINSLOT(__ror__, nb_or, slot_nb_or, "|"), + UNSLOT(__int__, nb_int, slot_nb_int, wrap_unaryfunc, "int(self)"), - UNSLOT("__float__", nb_float, slot_nb_float, wrap_unaryfunc, + UNSLOT(__float__, nb_float, slot_nb_float, wrap_unaryfunc, "float(self)"), - IBSLOT("__iadd__", nb_inplace_add, slot_nb_inplace_add, + IBSLOT(__iadd__, nb_inplace_add, slot_nb_inplace_add, wrap_binaryfunc, "+="), - IBSLOT("__isub__", nb_inplace_subtract, slot_nb_inplace_subtract, + IBSLOT(__isub__, nb_inplace_subtract, slot_nb_inplace_subtract, wrap_binaryfunc, "-="), - IBSLOT("__imul__", nb_inplace_multiply, slot_nb_inplace_multiply, + IBSLOT(__imul__, nb_inplace_multiply, slot_nb_inplace_multiply, wrap_binaryfunc, "*="), - IBSLOT("__imod__", nb_inplace_remainder, slot_nb_inplace_remainder, + IBSLOT(__imod__, nb_inplace_remainder, slot_nb_inplace_remainder, wrap_binaryfunc, "%="), - IBSLOT("__ipow__", nb_inplace_power, slot_nb_inplace_power, + IBSLOT(__ipow__, nb_inplace_power, slot_nb_inplace_power, wrap_ternaryfunc, "**="), - IBSLOT("__ilshift__", nb_inplace_lshift, slot_nb_inplace_lshift, + IBSLOT(__ilshift__, nb_inplace_lshift, slot_nb_inplace_lshift, wrap_binaryfunc, "<<="), - IBSLOT("__irshift__", nb_inplace_rshift, slot_nb_inplace_rshift, + IBSLOT(__irshift__, nb_inplace_rshift, slot_nb_inplace_rshift, wrap_binaryfunc, ">>="), - IBSLOT("__iand__", nb_inplace_and, slot_nb_inplace_and, + IBSLOT(__iand__, nb_inplace_and, slot_nb_inplace_and, wrap_binaryfunc, "&="), - IBSLOT("__ixor__", nb_inplace_xor, slot_nb_inplace_xor, + IBSLOT(__ixor__, nb_inplace_xor, slot_nb_inplace_xor, wrap_binaryfunc, "^="), - IBSLOT("__ior__", nb_inplace_or, slot_nb_inplace_or, + IBSLOT(__ior__, nb_inplace_or, slot_nb_inplace_or, wrap_binaryfunc, "|="), - BINSLOT("__floordiv__", nb_floor_divide, slot_nb_floor_divide, "//"), - RBINSLOT("__rfloordiv__", nb_floor_divide, slot_nb_floor_divide, "//"), - BINSLOT("__truediv__", nb_true_divide, slot_nb_true_divide, "/"), - RBINSLOT("__rtruediv__", nb_true_divide, slot_nb_true_divide, "/"), - IBSLOT("__ifloordiv__", nb_inplace_floor_divide, + BINSLOT(__floordiv__, nb_floor_divide, slot_nb_floor_divide, "//"), + RBINSLOT(__rfloordiv__, nb_floor_divide, slot_nb_floor_divide, "//"), + BINSLOT(__truediv__, nb_true_divide, slot_nb_true_divide, "/"), + RBINSLOT(__rtruediv__, nb_true_divide, slot_nb_true_divide, "/"), + IBSLOT(__ifloordiv__, nb_inplace_floor_divide, slot_nb_inplace_floor_divide, wrap_binaryfunc, "//="), - IBSLOT("__itruediv__", nb_inplace_true_divide, + IBSLOT(__itruediv__, nb_inplace_true_divide, slot_nb_inplace_true_divide, wrap_binaryfunc, "/="), - NBSLOT("__index__", nb_index, slot_nb_index, wrap_unaryfunc, + NBSLOT(__index__, nb_index, slot_nb_index, wrap_unaryfunc, "__index__($self, /)\n--\n\n" "Return self converted to an integer, if self is suitable " "for use as an index into a list."), - BINSLOT("__matmul__", nb_matrix_multiply, slot_nb_matrix_multiply, + BINSLOT(__matmul__, nb_matrix_multiply, slot_nb_matrix_multiply, "@"), - RBINSLOT("__rmatmul__", nb_matrix_multiply, slot_nb_matrix_multiply, + RBINSLOT(__rmatmul__, nb_matrix_multiply, slot_nb_matrix_multiply, "@"), - IBSLOT("__imatmul__", nb_inplace_matrix_multiply, slot_nb_inplace_matrix_multiply, + IBSLOT(__imatmul__, nb_inplace_matrix_multiply, slot_nb_inplace_matrix_multiply, wrap_binaryfunc, "@="), - MPSLOT("__len__", mp_length, slot_mp_length, wrap_lenfunc, + MPSLOT(__len__, mp_length, slot_mp_length, wrap_lenfunc, "__len__($self, /)\n--\n\nReturn len(self)."), - MPSLOT("__getitem__", mp_subscript, slot_mp_subscript, + MPSLOT(__getitem__, mp_subscript, slot_mp_subscript, wrap_binaryfunc, "__getitem__($self, key, /)\n--\n\nReturn self[key]."), - MPSLOT("__setitem__", mp_ass_subscript, slot_mp_ass_subscript, + MPSLOT(__setitem__, mp_ass_subscript, slot_mp_ass_subscript, wrap_objobjargproc, "__setitem__($self, key, value, /)\n--\n\nSet self[key] to value."), - MPSLOT("__delitem__", mp_ass_subscript, slot_mp_ass_subscript, + MPSLOT(__delitem__, mp_ass_subscript, slot_mp_ass_subscript, wrap_delitem, "__delitem__($self, key, /)\n--\n\nDelete self[key]."), - SQSLOT("__len__", sq_length, slot_sq_length, wrap_lenfunc, + SQSLOT(__len__, sq_length, slot_sq_length, wrap_lenfunc, "__len__($self, /)\n--\n\nReturn len(self)."), /* Heap types defining __add__/__mul__ have sq_concat/sq_repeat == NULL. The logic in abstract.c always falls back to nb_add/nb_multiply in this case. Defining both the nb_* and the sq_* slots to call the user-defined methods has unexpected side-effects, as shown by test_descr.notimplemented() */ - SQSLOT("__add__", sq_concat, NULL, wrap_binaryfunc, + SQSLOT(__add__, sq_concat, NULL, wrap_binaryfunc, "__add__($self, value, /)\n--\n\nReturn self+value."), - SQSLOT("__mul__", sq_repeat, NULL, wrap_indexargfunc, + SQSLOT(__mul__, sq_repeat, NULL, wrap_indexargfunc, "__mul__($self, value, /)\n--\n\nReturn self*value."), - SQSLOT("__rmul__", sq_repeat, NULL, wrap_indexargfunc, + SQSLOT(__rmul__, sq_repeat, NULL, wrap_indexargfunc, "__rmul__($self, value, /)\n--\n\nReturn value*self."), - SQSLOT("__getitem__", sq_item, slot_sq_item, wrap_sq_item, + SQSLOT(__getitem__, sq_item, slot_sq_item, wrap_sq_item, "__getitem__($self, key, /)\n--\n\nReturn self[key]."), - SQSLOT("__setitem__", sq_ass_item, slot_sq_ass_item, wrap_sq_setitem, + SQSLOT(__setitem__, sq_ass_item, slot_sq_ass_item, wrap_sq_setitem, "__setitem__($self, key, value, /)\n--\n\nSet self[key] to value."), - SQSLOT("__delitem__", sq_ass_item, slot_sq_ass_item, wrap_sq_delitem, + SQSLOT(__delitem__, sq_ass_item, slot_sq_ass_item, wrap_sq_delitem, "__delitem__($self, key, /)\n--\n\nDelete self[key]."), - SQSLOT("__contains__", sq_contains, slot_sq_contains, wrap_objobjproc, - "__contains__($self, key, /)\n--\n\nReturn key in self."), - SQSLOT("__iadd__", sq_inplace_concat, NULL, + SQSLOT(__contains__, sq_contains, slot_sq_contains, wrap_objobjproc, + "__contains__($self, key, /)\n--\n\nReturn bool(key in self)."), + SQSLOT(__iadd__, sq_inplace_concat, NULL, wrap_binaryfunc, "__iadd__($self, value, /)\n--\n\nImplement self+=value."), - SQSLOT("__imul__", sq_inplace_repeat, NULL, + SQSLOT(__imul__, sq_inplace_repeat, NULL, wrap_indexargfunc, "__imul__($self, value, /)\n--\n\nImplement self*=value."), @@ -8234,8 +9623,12 @@ slotptr(PyTypeObject *type, int ioffset) /* Note: this depends on the order of the members of PyHeapTypeObject! */ assert(offset >= 0); - assert((size_t)offset < offsetof(PyHeapTypeObject, as_buffer)); - if ((size_t)offset >= offsetof(PyHeapTypeObject, as_sequence)) { + assert((size_t)offset < offsetof(PyHeapTypeObject, ht_name)); + if ((size_t)offset >= offsetof(PyHeapTypeObject, as_buffer)) { + ptr = (char *)type->tp_as_buffer; + offset -= offsetof(PyHeapTypeObject, as_buffer); + } + else if ((size_t)offset >= offsetof(PyHeapTypeObject, as_sequence)) { ptr = (char *)type->tp_as_sequence; offset -= offsetof(PyHeapTypeObject, as_sequence); } @@ -8259,12 +9652,6 @@ slotptr(PyTypeObject *type, int ioffset) return (void **)ptr; } -/* Length of array of slotdef pointers used to store slots with the - same __name__. There should be at most MAX_EQUIV-1 slotdef entries with - the same __name__, for any __name__. Since that's a static property, it is - appropriate to declare fixed-size arrays for this. */ -#define MAX_EQUIV 10 - /* Return a slot pointer for a given name, but ONLY if the attribute has exactly one slot function. The name must be an interned string. */ static void ** @@ -8273,9 +9660,10 @@ resolve_slotdups(PyTypeObject *type, PyObject *name) /* XXX Maybe this could be optimized more -- but is it worth it? */ /* pname and ptrs act as a little cache */ - static PyObject *pname; - static slotdef *ptrs[MAX_EQUIV]; - slotdef *p, **pp; + PyInterpreterState *interp = _PyInterpreterState_Get(); +#define pname _Py_INTERP_CACHED_OBJECT(interp, type_slots_pname) +#define ptrs _Py_INTERP_CACHED_OBJECT(interp, type_slots_ptrs) + pytype_slotdef *p, **pp; void **res, **ptr; if (pname != name) { @@ -8302,6 +9690,8 @@ resolve_slotdups(PyTypeObject *type, PyObject *name) res = ptr; } return res; +#undef pname +#undef ptrs } @@ -8359,13 +9749,22 @@ resolve_slotdups(PyTypeObject *type, PyObject *name) * When done, return a pointer to the next slotdef with a different offset, * because that's convenient for fixup_slot_dispatchers(). This function never * sets an exception: if an internal error happens (unlikely), it's ignored. */ -static slotdef * -update_one_slot(PyTypeObject *type, slotdef *p) +static pytype_slotdef * +update_one_slot(PyTypeObject *type, pytype_slotdef *p) { PyObject *descr; PyWrapperDescrObject *d; - void *generic = NULL, *specific = NULL; + + // The correct specialized C function, like "tp_repr of str" in the + // example above + void *specific = NULL; + + // A generic wrapper that uses method lookup (safe but slow) + void *generic = NULL; + + // Set to 1 if the generic wrapper is necessary int use_generic = 0; + int offset = p->offset; int error; void **ptr = slotptr(type, offset); @@ -8448,6 +9847,10 @@ update_one_slot(PyTypeObject *type, slotdef *p) else { use_generic = 1; generic = p->function; + if (p->function == slot_tp_call) { + /* A generic __call__ is incompatible with vectorcall */ + type->tp_flags &= ~Py_TPFLAGS_HAVE_VECTORCALL; + } } } while ((++p)->offset == offset); if (specific && !use_generic) @@ -8462,61 +9865,29 @@ update_one_slot(PyTypeObject *type, slotdef *p) static int update_slots_callback(PyTypeObject *type, void *data) { - slotdef **pp = (slotdef **)data; + pytype_slotdef **pp = (pytype_slotdef **)data; for (; *pp; pp++) { update_one_slot(type, *pp); } return 0; } -static int slotdefs_initialized = 0; -/* Initialize the slotdefs table by adding interned string objects for the - names. */ -PyStatus -_PyTypes_InitSlotDefs(void) -{ - if (slotdefs_initialized) { - return _PyStatus_OK(); - } - - for (slotdef *p = slotdefs; p->name; p++) { - /* Slots must be ordered by their offset in the PyHeapTypeObject. */ - assert(!p[1].name || p->offset <= p[1].offset); - /* bpo-40521: Interned strings are shared by all subinterpreters */ - p->name_strobj = PyUnicode_InternFromString(p->name); - if (!p->name_strobj || !PyUnicode_CHECK_INTERNED(p->name_strobj)) { - return _PyStatus_NO_MEMORY(); - } - } - slotdefs_initialized = 1; - return _PyStatus_OK(); -} - -/* Undo _PyTypes_InitSlotDefs(), releasing the interned strings. */ -static void clear_slotdefs(void) -{ - for (slotdef *p = slotdefs; p->name; p++) { - Py_CLEAR(p->name_strobj); - } - slotdefs_initialized = 0; -} - /* Update the slots after assignment to a class (type) attribute. */ static int update_slot(PyTypeObject *type, PyObject *name) { - slotdef *ptrs[MAX_EQUIV]; - slotdef *p; - slotdef **pp; + pytype_slotdef *ptrs[MAX_EQUIV]; + pytype_slotdef *p; + pytype_slotdef **pp; int offset; assert(PyUnicode_CheckExact(name)); assert(PyUnicode_CHECK_INTERNED(name)); - assert(slotdefs_initialized); pp = ptrs; for (p = slotdefs; p->name; p++) { assert(PyUnicode_CheckExact(p->name_strobj)); + assert(PyUnicode_CHECK_INTERNED(p->name_strobj)); assert(PyUnicode_CheckExact(name)); /* bpo-40521: Using interned strings. */ if (p->name_strobj == name) { @@ -8544,8 +9915,7 @@ static void fixup_slot_dispatchers(PyTypeObject *type) { assert(!PyErr_Occurred()); - assert(slotdefs_initialized); - for (slotdef *p = slotdefs; p->name; ) { + for (pytype_slotdef *p = slotdefs; p->name; ) { p = update_one_slot(type, p); } } @@ -8553,12 +9923,11 @@ fixup_slot_dispatchers(PyTypeObject *type) static void update_all_slots(PyTypeObject* type) { - slotdef *p; + pytype_slotdef *p; /* Clear the VALID_VERSION flag of 'type' and all its subclasses. */ PyType_Modified(type); - assert(slotdefs_initialized); for (p = slotdefs; p->name; p++) { /* update_slot returns int but can't actually fail */ update_slot(type, p->name_strobj); @@ -8571,7 +9940,8 @@ update_all_slots(PyTypeObject* type) static int type_new_set_names(PyTypeObject *type) { - PyObject *names_to_set = PyDict_Copy(type->tp_dict); + PyObject *dict = lookup_tp_dict(type); + PyObject *names_to_set = PyDict_Copy(dict); if (names_to_set == NULL) { return -1; } @@ -8592,13 +9962,15 @@ type_new_set_names(PyTypeObject *type) Py_DECREF(set_name); if (res == NULL) { - _PyErr_FormatFromCause(PyExc_RuntimeError, + _PyErr_FormatNote( "Error calling __set_name__ on '%.100s' instance %R " "in '%.100s'", Py_TYPE(value)->tp_name, key, type->tp_name); goto error; } - Py_DECREF(res); + else { + Py_DECREF(res); + } } Py_DECREF(names_to_set); @@ -8658,7 +10030,7 @@ recurse_down_subclasses(PyTypeObject *type, PyObject *attr_name, // It is safe to use a borrowed reference because update_subclasses() is // only used with update_slots_callback() which doesn't modify // tp_subclasses. - PyObject *subclasses = type->tp_subclasses; // borrowed ref + PyObject *subclasses = lookup_tp_subclasses(type); // borrowed ref if (subclasses == NULL) { return 0; } @@ -8667,16 +10039,13 @@ recurse_down_subclasses(PyTypeObject *type, PyObject *attr_name, Py_ssize_t i = 0; PyObject *ref; while (PyDict_Next(subclasses, &i, NULL, &ref)) { - assert(PyWeakref_CheckRef(ref)); - PyObject *obj = PyWeakref_GET_OBJECT(ref); - assert(obj != NULL); - if (obj == Py_None) { + PyTypeObject *subclass = type_from_ref(ref); // borrowed + if (subclass == NULL) { continue; } - PyTypeObject *subclass = _PyType_CAST(obj); /* Avoid recursing down into unaffected classes */ - PyObject *dict = subclass->tp_dict; + PyObject *dict = lookup_tp_dict(subclass); if (dict != NULL && PyDict_Check(dict)) { int r = PyDict_Contains(dict, attr_name); if (r < 0) { @@ -8727,12 +10096,11 @@ recurse_down_subclasses(PyTypeObject *type, PyObject *attr_name, static int add_operators(PyTypeObject *type) { - PyObject *dict = type->tp_dict; - slotdef *p; + PyObject *dict = lookup_tp_dict(type); + pytype_slotdef *p; PyObject *descr; void **ptr; - assert(slotdefs_initialized); for (p = slotdefs; p->name; p++) { if (p->wrapper == NULL) continue; @@ -8814,65 +10182,43 @@ super_repr(PyObject *self) su->type ? su->type->tp_name : "NULL"); } +/* Do a super lookup without executing descriptors or falling back to getattr +on the super object itself. + +May return NULL with or without an exception set, like PyDict_GetItemWithError. */ static PyObject * -super_getattro(PyObject *self, PyObject *name) +_super_lookup_descr(PyTypeObject *su_type, PyTypeObject *su_obj_type, PyObject *name) { - superobject *su = (superobject *)self; - PyTypeObject *starttype; - PyObject *mro; + PyObject *mro, *res; Py_ssize_t i, n; - starttype = su->obj_type; - if (starttype == NULL) - goto skip; - - /* We want __class__ to return the class of the super object - (i.e. super, or a subclass), not the class of su->obj. */ - if (PyUnicode_Check(name) && - PyUnicode_GET_LENGTH(name) == 9 && - _PyUnicode_Equal(name, &_Py_ID(__class__))) - goto skip; - - mro = starttype->tp_mro; + mro = lookup_tp_mro(su_obj_type); if (mro == NULL) - goto skip; + return NULL; assert(PyTuple_Check(mro)); n = PyTuple_GET_SIZE(mro); /* No need to check the last one: it's gonna be skipped anyway. */ for (i = 0; i+1 < n; i++) { - if ((PyObject *)(su->type) == PyTuple_GET_ITEM(mro, i)) + if ((PyObject *)(su_type) == PyTuple_GET_ITEM(mro, i)) break; } i++; /* skip su->type (if any) */ if (i >= n) - goto skip; + return NULL; - /* keep a strong reference to mro because starttype->tp_mro can be + /* keep a strong reference to mro because su_obj_type->tp_mro can be replaced during PyDict_GetItemWithError(dict, name) */ Py_INCREF(mro); do { PyObject *obj = PyTuple_GET_ITEM(mro, i); - PyObject *dict = _PyType_CAST(obj)->tp_dict; + PyObject *dict = lookup_tp_dict(_PyType_CAST(obj)); assert(dict != NULL && PyDict_Check(dict)); - PyObject *res = PyDict_GetItemWithError(dict, name); + res = PyDict_GetItemWithError(dict, name); if (res != NULL) { Py_INCREF(res); - - descrgetfunc f = Py_TYPE(res)->tp_descr_get; - if (f != NULL) { - PyObject *res2; - res2 = f(res, - /* Only pass 'obj' param if this is instance-mode super - (See SF ID #743627) */ - (su->obj == (PyObject *)starttype) ? NULL : su->obj, - (PyObject *)starttype); - Py_DECREF(res); - res = res2; - } - Py_DECREF(mro); return res; } @@ -8884,9 +10230,75 @@ super_getattro(PyObject *self, PyObject *name) i++; } while (i < n); Py_DECREF(mro); + return NULL; +} + +// if `method` is non-NULL, we are looking for a method descriptor, +// and setting `*method = 1` means we found one. +static PyObject * +do_super_lookup(superobject *su, PyTypeObject *su_type, PyObject *su_obj, + PyTypeObject *su_obj_type, PyObject *name, int *method) +{ + PyObject *res; + int temp_su = 0; + + if (su_obj_type == NULL) { + goto skip; + } + + res = _super_lookup_descr(su_type, su_obj_type, name); + if (res != NULL) { + if (method && _PyType_HasFeature(Py_TYPE(res), Py_TPFLAGS_METHOD_DESCRIPTOR)) { + *method = 1; + } + else { + descrgetfunc f = Py_TYPE(res)->tp_descr_get; + if (f != NULL) { + PyObject *res2; + res2 = f(res, + /* Only pass 'obj' param if this is instance-mode super + (See SF ID #743627) */ + (su_obj == (PyObject *)su_obj_type) ? NULL : su_obj, + (PyObject *)su_obj_type); + Py_SETREF(res, res2); + } + } + + return res; + } + else if (PyErr_Occurred()) { + return NULL; + } skip: - return PyObject_GenericGetAttr(self, name); + if (su == NULL) { + PyObject *args[] = {(PyObject *)su_type, su_obj}; + su = (superobject *)PyObject_Vectorcall((PyObject *)&PySuper_Type, args, 2, NULL); + if (su == NULL) { + return NULL; + } + temp_su = 1; + } + res = PyObject_GenericGetAttr((PyObject *)su, name); + if (temp_su) { + Py_DECREF(su); + } + return res; +} + +static PyObject * +super_getattro(PyObject *self, PyObject *name) +{ + superobject *su = (superobject *)self; + + /* We want __class__ to return the class of the super object + (i.e. super, or a subclass), not the class of su->obj. */ + if (PyUnicode_Check(name) && + PyUnicode_GET_LENGTH(name) == 9 && + _PyUnicode_Equal(name, &_Py_ID(__class__))) + return PyObject_GenericGetAttr(self, name); + + return do_super_lookup(su, su->type, su->obj, su->obj_type, name, NULL); } static PyTypeObject * @@ -8909,14 +10321,12 @@ supercheck(PyTypeObject *type, PyObject *obj) /* Check for first bullet above (special case) */ if (PyType_Check(obj) && PyType_IsSubtype((PyTypeObject *)obj, type)) { - Py_INCREF(obj); - return (PyTypeObject *)obj; + return (PyTypeObject *)Py_NewRef(obj); } /* Normal case */ if (PyType_IsSubtype(Py_TYPE(obj), type)) { - Py_INCREF(Py_TYPE(obj)); - return Py_TYPE(obj); + return (PyTypeObject*)Py_NewRef(Py_TYPE(obj)); } else { /* Try the slow way */ @@ -8944,6 +10354,18 @@ supercheck(PyTypeObject *type, PyObject *obj) return NULL; } +PyObject * +_PySuper_Lookup(PyTypeObject *su_type, PyObject *su_obj, PyObject *name, int *method) +{ + PyTypeObject *su_obj_type = supercheck(su_type, su_obj); + if (su_obj_type == NULL) { + return NULL; + } + PyObject *res = do_super_lookup(NULL, su_type, su_obj, su_obj_type, name, method); + Py_DECREF(su_obj_type); + return res; +} + static PyObject * super_descr_get(PyObject *self, PyObject *obj, PyObject *type) { @@ -8952,8 +10374,7 @@ super_descr_get(PyObject *self, PyObject *obj, PyObject *type) if (obj == NULL || obj == Py_None || su->obj != NULL) { /* Not binding to an object, or already bound */ - Py_INCREF(self); - return self; + return Py_NewRef(self); } if (!Py_IS_TYPE(su, &PySuper_Type)) /* If su is an instance of a (strict) subclass of super, @@ -8967,12 +10388,12 @@ super_descr_get(PyObject *self, PyObject *obj, PyObject *type) return NULL; newobj = (superobject *)PySuper_Type.tp_new(&PySuper_Type, NULL, NULL); - if (newobj == NULL) + if (newobj == NULL) { + Py_DECREF(obj_type); return NULL; - Py_INCREF(su->type); - Py_INCREF(obj); - newobj->type = su->type; - newobj->obj = obj; + } + newobj->type = (PyTypeObject*)Py_NewRef(su->type); + newobj->obj = Py_NewRef(obj); newobj->obj_type = obj_type; return (PyObject *)newobj; } @@ -8997,8 +10418,8 @@ super_init_without_args(_PyInterpreterFrame *cframe, PyCodeObject *co, if (_PyInterpreterFrame_LASTI(cframe) >= 0) { // MAKE_CELL and COPY_FREE_VARS have no quickened forms, so no need // to use _PyOpcode_Deopt here: - assert(_Py_OPCODE(_PyCode_CODE(co)[0]) == MAKE_CELL || - _Py_OPCODE(_PyCode_CODE(co)[0]) == COPY_FREE_VARS); + assert(_PyCode_CODE(co)[0].op.code == MAKE_CELL || + _PyCode_CODE(co)[0].op.code == COPY_FREE_VARS); assert(PyCell_Check(firstarg)); firstarg = PyCell_GET(firstarg); } @@ -9011,7 +10432,7 @@ super_init_without_args(_PyInterpreterFrame *cframe, PyCodeObject *co, // Look for __class__ in the free vars. PyTypeObject *type = NULL; - int i = co->co_nlocals + co->co_nplaincellvars; + int i = PyCode_GetFirstFree(co); for (; i < co->co_nlocalsplus; i++) { assert((_PyLocals_GetKind(co->co_localspluskinds, i) & CO_FAST_FREE) != 0); PyObject *name = PyTuple_GET_ITEM(co->co_localsplusnames, i); @@ -9075,13 +10496,13 @@ super_init_impl(PyObject *self, PyTypeObject *type, PyObject *obj) { /* Call super(), without args -- fill in from __class__ and first local variable on the stack. */ PyThreadState *tstate = _PyThreadState_GET(); - _PyInterpreterFrame *cframe = tstate->cframe->current_frame; - if (cframe == NULL) { + _PyInterpreterFrame *frame = _PyThreadState_GetFrame(tstate); + if (frame == NULL) { PyErr_SetString(PyExc_RuntimeError, "super(): no current frame"); return -1; } - int res = super_init_without_args(cframe, cframe->f_code, &type, &obj); + int res = super_init_without_args(frame, frame->f_code, &type, &obj); if (res < 0) { return -1; @@ -9096,8 +10517,7 @@ super_init_impl(PyObject *self, PyTypeObject *type, PyObject *obj) { return -1; Py_INCREF(obj); } - Py_INCREF(type); - Py_XSETREF(su->type, type); + Py_XSETREF(su->type, (PyTypeObject*)Py_NewRef(type)); Py_XSETREF(su->obj, obj); Py_XSETREF(su->obj_type, obj_type); return 0; diff --git a/Objects/typevarobject.c b/Objects/typevarobject.c new file mode 100644 index 00000000..069e1d98 --- /dev/null +++ b/Objects/typevarobject.c @@ -0,0 +1,1689 @@ +// TypeVar, TypeVarTuple, and ParamSpec +#include "Python.h" +#include "pycore_object.h" // _PyObject_GC_TRACK/UNTRACK +#include "pycore_typevarobject.h" +#include "pycore_unionobject.h" // _Py_union_type_or +#include "structmember.h" + +/*[clinic input] +class typevar "typevarobject *" "&_PyTypeVar_Type" +class paramspec "paramspecobject *" "&_PyParamSpec_Type" +class paramspecargs "paramspecattrobject *" "&_PyParamSpecArgs_Type" +class paramspeckwargs "paramspecattrobject *" "&_PyParamSpecKwargs_Type" +class typevartuple "typevartupleobject *" "&_PyTypeVarTuple_Type" +class typealias "typealiasobject *" "&_PyTypeAlias_Type" +class Generic "PyObject *" "&PyGeneric_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=aa86741931a0f55c]*/ + +typedef struct { + PyObject_HEAD + PyObject *name; + PyObject *bound; + PyObject *evaluate_bound; + PyObject *constraints; + PyObject *evaluate_constraints; + bool covariant; + bool contravariant; + bool infer_variance; +} typevarobject; + +typedef struct { + PyObject_HEAD + PyObject *name; +} typevartupleobject; + +typedef struct { + PyObject_HEAD + PyObject *name; + PyObject *bound; + bool covariant; + bool contravariant; + bool infer_variance; +} paramspecobject; + +typedef struct { + PyObject_HEAD + PyObject *name; + PyObject *type_params; + PyObject *compute_value; + PyObject *value; + PyObject *module; +} typealiasobject; + +#include "clinic/typevarobject.c.h" + +static PyObject * +call_typing_func_object(const char *name, PyObject **args, size_t nargs) +{ + PyObject *typing = PyImport_ImportModule("typing"); + if (typing == NULL) { + return NULL; + } + PyObject *func = PyObject_GetAttrString(typing, name); + if (func == NULL) { + Py_DECREF(typing); + return NULL; + } + PyObject *result = PyObject_Vectorcall(func, args, nargs, NULL); + Py_DECREF(func); + Py_DECREF(typing); + return result; +} + +static PyObject * +type_check(PyObject *arg, const char *msg) +{ + // Calling typing.py here leads to bootstrapping problems + if (Py_IsNone(arg)) { + return Py_NewRef(Py_TYPE(arg)); + } + PyObject *message_str = PyUnicode_FromString(msg); + if (message_str == NULL) { + return NULL; + } + PyObject *args[2] = {arg, message_str}; + PyObject *result = call_typing_func_object("_type_check", args, 2); + Py_DECREF(message_str); + return result; +} + +/* + * Return a typing.Union. This is used as the nb_or (|) operator for + * TypeVar and ParamSpec. We use this rather than _Py_union_type_or + * (which would produce a types.Union) because historically TypeVar + * supported unions with string forward references, and we want to + * preserve that behavior. _Py_union_type_or only allows a small set + * of types. + */ +static PyObject * +make_union(PyObject *self, PyObject *other) +{ + PyObject *args[2] = {self, other}; + PyObject *result = call_typing_func_object("_make_union", args, 2); + return result; +} + +static PyObject * +caller(void) +{ + _PyInterpreterFrame *f = _PyThreadState_GET()->cframe->current_frame; + if (f == NULL) { + Py_RETURN_NONE; + } + if (f == NULL || f->f_funcobj == NULL) { + Py_RETURN_NONE; + } + PyObject *r = PyFunction_GetModule(f->f_funcobj); + if (!r) { + PyErr_Clear(); + Py_RETURN_NONE; + } + return Py_NewRef(r); +} + +static PyObject * +typevartuple_unpack(PyObject *tvt) +{ + PyObject *typing = PyImport_ImportModule("typing"); + if (typing == NULL) { + return NULL; + } + PyObject *unpack = PyObject_GetAttrString(typing, "Unpack"); + if (unpack == NULL) { + Py_DECREF(typing); + return NULL; + } + PyObject *unpacked = PyObject_GetItem(unpack, tvt); + Py_DECREF(typing); + Py_DECREF(unpack); + return unpacked; +} + +static int +contains_typevartuple(PyTupleObject *params) +{ + Py_ssize_t n = PyTuple_GET_SIZE(params); + PyTypeObject *tp = PyInterpreterState_Get()->cached_objects.typevartuple_type; + for (Py_ssize_t i = 0; i < n; i++) { + PyObject *param = PyTuple_GET_ITEM(params, i); + if (Py_IS_TYPE(param, tp)) { + return 1; + } + } + return 0; +} + +static PyObject * +unpack_typevartuples(PyObject *params) +{ + assert(PyTuple_Check(params)); + // TypeVarTuple must be unpacked when passed to Generic, so we do that here. + if (contains_typevartuple((PyTupleObject *)params)) { + Py_ssize_t n = PyTuple_GET_SIZE(params); + PyObject *new_params = PyTuple_New(n); + if (new_params == NULL) { + return NULL; + } + PyTypeObject *tp = PyInterpreterState_Get()->cached_objects.typevartuple_type; + for (Py_ssize_t i = 0; i < n; i++) { + PyObject *param = PyTuple_GET_ITEM(params, i); + if (Py_IS_TYPE(param, tp)) { + PyObject *unpacked = typevartuple_unpack(param); + if (unpacked == NULL) { + Py_DECREF(new_params); + return NULL; + } + PyTuple_SET_ITEM(new_params, i, unpacked); + } + else { + PyTuple_SET_ITEM(new_params, i, Py_NewRef(param)); + } + } + return new_params; + } + else { + return Py_NewRef(params); + } +} + +static void +typevar_dealloc(PyObject *self) +{ + PyTypeObject *tp = Py_TYPE(self); + typevarobject *tv = (typevarobject *)self; + + _PyObject_GC_UNTRACK(self); + + Py_DECREF(tv->name); + Py_XDECREF(tv->bound); + Py_XDECREF(tv->evaluate_bound); + Py_XDECREF(tv->constraints); + Py_XDECREF(tv->evaluate_constraints); + _PyObject_ClearManagedDict(self); + PyObject_ClearWeakRefs(self); + + Py_TYPE(self)->tp_free(self); + Py_DECREF(tp); +} + +static int +typevar_traverse(PyObject *self, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(self)); + typevarobject *tv = (typevarobject *)self; + Py_VISIT(tv->bound); + Py_VISIT(tv->evaluate_bound); + Py_VISIT(tv->constraints); + Py_VISIT(tv->evaluate_constraints); + _PyObject_VisitManagedDict(self, visit, arg); + return 0; +} + +static int +typevar_clear(typevarobject *self) +{ + Py_CLEAR(self->bound); + Py_CLEAR(self->evaluate_bound); + Py_CLEAR(self->constraints); + Py_CLEAR(self->evaluate_constraints); + _PyObject_ClearManagedDict((PyObject *)self); + return 0; +} + +static PyObject * +typevar_repr(PyObject *self) +{ + typevarobject *tv = (typevarobject *)self; + + if (tv->infer_variance) { + return Py_NewRef(tv->name); + } + + char variance = tv->covariant ? '+' : tv->contravariant ? '-' : '~'; + return PyUnicode_FromFormat("%c%U", variance, tv->name); +} + +static PyMemberDef typevar_members[] = { + {"__name__", T_OBJECT, offsetof(typevarobject, name), READONLY}, + {"__covariant__", T_BOOL, offsetof(typevarobject, covariant), READONLY}, + {"__contravariant__", T_BOOL, offsetof(typevarobject, contravariant), READONLY}, + {"__infer_variance__", T_BOOL, offsetof(typevarobject, infer_variance), READONLY}, + {0} +}; + +static PyObject * +typevar_bound(typevarobject *self, void *Py_UNUSED(ignored)) +{ + if (self->bound != NULL) { + return Py_NewRef(self->bound); + } + if (self->evaluate_bound == NULL) { + Py_RETURN_NONE; + } + PyObject *bound = PyObject_CallNoArgs(self->evaluate_bound); + self->bound = Py_XNewRef(bound); + return bound; +} + +static PyObject * +typevar_constraints(typevarobject *self, void *Py_UNUSED(ignored)) +{ + if (self->constraints != NULL) { + return Py_NewRef(self->constraints); + } + if (self->evaluate_constraints == NULL) { + return PyTuple_New(0); + } + PyObject *constraints = PyObject_CallNoArgs(self->evaluate_constraints); + self->constraints = Py_XNewRef(constraints); + return constraints; +} + +static PyGetSetDef typevar_getset[] = { + {"__bound__", (getter)typevar_bound, NULL, NULL, NULL}, + {"__constraints__", (getter)typevar_constraints, NULL, NULL, NULL}, + {0} +}; + +static typevarobject * +typevar_alloc(PyObject *name, PyObject *bound, PyObject *evaluate_bound, + PyObject *constraints, PyObject *evaluate_constraints, + bool covariant, bool contravariant, bool infer_variance, + PyObject *module) +{ + PyTypeObject *tp = PyInterpreterState_Get()->cached_objects.typevar_type; + assert(tp != NULL); + typevarobject *tv = PyObject_GC_New(typevarobject, tp); + if (tv == NULL) { + return NULL; + } + + tv->name = Py_NewRef(name); + + tv->bound = Py_XNewRef(bound); + tv->evaluate_bound = Py_XNewRef(evaluate_bound); + tv->constraints = Py_XNewRef(constraints); + tv->evaluate_constraints = Py_XNewRef(evaluate_constraints); + + tv->covariant = covariant; + tv->contravariant = contravariant; + tv->infer_variance = infer_variance; + _PyObject_GC_TRACK(tv); + + if (module != NULL) { + if (PyObject_SetAttrString((PyObject *)tv, "__module__", module) < 0) { + Py_DECREF(tv); + return NULL; + } + } + + return tv; +} + +/*[clinic input] +@classmethod +typevar.__new__ as typevar_new + + name: object(subclass_of="&PyUnicode_Type") + *constraints: object + * + bound: object = None + covariant: bool = False + contravariant: bool = False + infer_variance: bool = False + +Create a TypeVar. +[clinic start generated code]*/ + +static PyObject * +typevar_new_impl(PyTypeObject *type, PyObject *name, PyObject *constraints, + PyObject *bound, int covariant, int contravariant, + int infer_variance) +/*[clinic end generated code: output=1d200450ee99226d input=2c07ab87c94f462b]*/ +{ + if (covariant && contravariant) { + PyErr_SetString(PyExc_ValueError, + "Bivariant types are not supported."); + return NULL; + } + + if (infer_variance && (covariant || contravariant)) { + PyErr_SetString(PyExc_ValueError, + "Variance cannot be specified with infer_variance."); + return NULL; + } + + if (Py_IsNone(bound)) { + bound = NULL; + } + if (bound != NULL) { + bound = type_check(bound, "Bound must be a type."); + if (bound == NULL) { + return NULL; + } + } + + if (!PyTuple_CheckExact(constraints)) { + PyErr_SetString(PyExc_TypeError, + "constraints must be a tuple"); + return NULL; + } + Py_ssize_t n_constraints = PyTuple_GET_SIZE(constraints); + if (n_constraints == 1) { + PyErr_SetString(PyExc_TypeError, + "A single constraint is not allowed"); + Py_XDECREF(bound); + return NULL; + } else if (n_constraints == 0) { + constraints = NULL; + } else if (bound != NULL) { + PyErr_SetString(PyExc_TypeError, + "Constraints cannot be combined with bound=..."); + Py_XDECREF(bound); + return NULL; + } + PyObject *module = caller(); + if (module == NULL) { + Py_XDECREF(bound); + return NULL; + } + + PyObject *tv = (PyObject *)typevar_alloc(name, bound, NULL, + constraints, NULL, + covariant, contravariant, + infer_variance, module); + Py_XDECREF(bound); + Py_XDECREF(module); + return tv; +} + +/*[clinic input] +typevar.__typing_subst__ as typevar_typing_subst + + arg: object + +[clinic start generated code]*/ + +static PyObject * +typevar_typing_subst_impl(typevarobject *self, PyObject *arg) +/*[clinic end generated code: output=c76ced134ed8f4e1 input=6b70a4bb2da838de]*/ +{ + PyObject *args[2] = {(PyObject *)self, arg}; + PyObject *result = call_typing_func_object("_typevar_subst", args, 2); + return result; +} + +/*[clinic input] +typevar.__reduce__ as typevar_reduce + +[clinic start generated code]*/ + +static PyObject * +typevar_reduce_impl(typevarobject *self) +/*[clinic end generated code: output=02e5c55d7cf8a08f input=de76bc95f04fb9ff]*/ +{ + return Py_NewRef(self->name); +} + +static PyObject * +typevar_mro_entries(PyObject *self, PyObject *args) +{ + PyErr_SetString(PyExc_TypeError, + "Cannot subclass an instance of TypeVar"); + return NULL; +} + +static PyMethodDef typevar_methods[] = { + TYPEVAR_TYPING_SUBST_METHODDEF + TYPEVAR_REDUCE_METHODDEF + {"__mro_entries__", typevar_mro_entries, METH_O}, + {0} +}; + +PyDoc_STRVAR(typevar_doc, +"Type variable.\n\ +\n\ +The preferred way to construct a type variable is via the dedicated\n\ +syntax for generic functions, classes, and type aliases::\n\ +\n\ + class Sequence[T]: # T is a TypeVar\n\ + ...\n\ +\n\ +This syntax can also be used to create bound and constrained type\n\ +variables::\n\ +\n\ + # S is a TypeVar bound to str\n\ + class StrSequence[S: str]:\n\ + ...\n\ +\n\ + # A is a TypeVar constrained to str or bytes\n\ + class StrOrBytesSequence[A: (str, bytes)]:\n\ + ...\n\ +\n\ +However, if desired, reusable type variables can also be constructed\n\ +manually, like so::\n\ +\n\ + T = TypeVar('T') # Can be anything\n\ + S = TypeVar('S', bound=str) # Can be any subtype of str\n\ + A = TypeVar('A', str, bytes) # Must be exactly str or bytes\n\ +\n\ +Type variables exist primarily for the benefit of static type\n\ +checkers. They serve as the parameters for generic types as well\n\ +as for generic function and type alias definitions.\n\ +\n\ +The variance of type variables is inferred by type checkers when they\n\ +are created through the type parameter syntax and when\n\ +``infer_variance=True`` is passed. Manually created type variables may\n\ +be explicitly marked covariant or contravariant by passing\n\ +``covariant=True`` or ``contravariant=True``. By default, manually\n\ +created type variables are invariant. See PEP 484 and PEP 695 for more\n\ +details.\n\ +"); + +static PyType_Slot typevar_slots[] = { + {Py_tp_doc, (void *)typevar_doc}, + {Py_tp_methods, typevar_methods}, + {Py_nb_or, make_union}, + {Py_tp_new, typevar_new}, + {Py_tp_dealloc, typevar_dealloc}, + {Py_tp_alloc, PyType_GenericAlloc}, + {Py_tp_free, PyObject_GC_Del}, + {Py_tp_traverse, typevar_traverse}, + {Py_tp_clear, typevar_clear}, + {Py_tp_repr, typevar_repr}, + {Py_tp_members, typevar_members}, + {Py_tp_getset, typevar_getset}, + {0, NULL}, +}; + +PyType_Spec typevar_spec = { + .name = "typing.TypeVar", + .basicsize = sizeof(typevarobject), + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE + | Py_TPFLAGS_MANAGED_DICT | Py_TPFLAGS_MANAGED_WEAKREF, + .slots = typevar_slots, +}; + +typedef struct { + PyObject_HEAD + PyObject *__origin__; +} paramspecattrobject; + +static void +paramspecattr_dealloc(PyObject *self) +{ + PyTypeObject *tp = Py_TYPE(self); + paramspecattrobject *psa = (paramspecattrobject *)self; + + _PyObject_GC_UNTRACK(self); + + Py_XDECREF(psa->__origin__); + + Py_TYPE(self)->tp_free(self); + Py_DECREF(tp); +} + +static int +paramspecattr_traverse(PyObject *self, visitproc visit, void *arg) +{ + paramspecattrobject *psa = (paramspecattrobject *)self; + Py_VISIT(psa->__origin__); + return 0; +} + +static int +paramspecattr_clear(paramspecattrobject *self) +{ + Py_CLEAR(self->__origin__); + return 0; +} + +static PyObject * +paramspecattr_richcompare(PyObject *a, PyObject *b, int op) +{ + if (!Py_IS_TYPE(a, Py_TYPE(b))) { + Py_RETURN_NOTIMPLEMENTED; + } + if (op != Py_EQ && op != Py_NE) { + Py_RETURN_NOTIMPLEMENTED; + } + return PyObject_RichCompare( + ((paramspecattrobject *)a)->__origin__, + ((paramspecattrobject *)b)->__origin__, + op + ); +} + +static PyMemberDef paramspecattr_members[] = { + {"__origin__", T_OBJECT, offsetof(paramspecattrobject, __origin__), READONLY}, + {0} +}; + +static paramspecattrobject * +paramspecattr_new(PyTypeObject *tp, PyObject *origin) +{ + paramspecattrobject *psa = PyObject_GC_New(paramspecattrobject, tp); + if (psa == NULL) { + return NULL; + } + psa->__origin__ = Py_NewRef(origin); + _PyObject_GC_TRACK(psa); + return psa; +} + +static PyObject * +paramspecargs_repr(PyObject *self) +{ + paramspecattrobject *psa = (paramspecattrobject *)self; + + PyTypeObject *tp = PyInterpreterState_Get()->cached_objects.paramspec_type; + if (Py_IS_TYPE(psa->__origin__, tp)) { + return PyUnicode_FromFormat("%U.args", + ((paramspecobject *)psa->__origin__)->name); + } + return PyUnicode_FromFormat("%R.args", psa->__origin__); +} + + +/*[clinic input] +@classmethod +paramspecargs.__new__ as paramspecargs_new + + origin: object + +Create a ParamSpecArgs object. +[clinic start generated code]*/ + +static PyObject * +paramspecargs_new_impl(PyTypeObject *type, PyObject *origin) +/*[clinic end generated code: output=9a1463dc8942fe4e input=3596a0bb6183c208]*/ +{ + return (PyObject *)paramspecattr_new(type, origin); +} + +static PyObject * +paramspecargs_mro_entries(PyObject *self, PyObject *args) +{ + PyErr_SetString(PyExc_TypeError, + "Cannot subclass an instance of ParamSpecArgs"); + return NULL; +} + +static PyMethodDef paramspecargs_methods[] = { + {"__mro_entries__", paramspecargs_mro_entries, METH_O}, + {0} +}; + +PyDoc_STRVAR(paramspecargs_doc, +"The args for a ParamSpec object.\n\ +\n\ +Given a ParamSpec object P, P.args is an instance of ParamSpecArgs.\n\ +\n\ +ParamSpecArgs objects have a reference back to their ParamSpec::\n\ +\n\ + >>> P = ParamSpec(\"P\")\n\ + >>> P.args.__origin__ is P\n\ + True\n\ +\n\ +This type is meant for runtime introspection and has no special meaning\n\ +to static type checkers.\n\ +"); + +static PyType_Slot paramspecargs_slots[] = { + {Py_tp_doc, (void *)paramspecargs_doc}, + {Py_tp_methods, paramspecargs_methods}, + {Py_tp_new, paramspecargs_new}, + {Py_tp_dealloc, paramspecattr_dealloc}, + {Py_tp_alloc, PyType_GenericAlloc}, + {Py_tp_free, PyObject_GC_Del}, + {Py_tp_traverse, paramspecattr_traverse}, + {Py_tp_clear, (inquiry)paramspecattr_clear}, + {Py_tp_repr, paramspecargs_repr}, + {Py_tp_members, paramspecattr_members}, + {Py_tp_richcompare, paramspecattr_richcompare}, + {0, NULL}, +}; + +PyType_Spec paramspecargs_spec = { + .name = "typing.ParamSpecArgs", + .basicsize = sizeof(paramspecattrobject), + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE + | Py_TPFLAGS_MANAGED_WEAKREF, + .slots = paramspecargs_slots, +}; + +static PyObject * +paramspeckwargs_repr(PyObject *self) +{ + paramspecattrobject *psk = (paramspecattrobject *)self; + + PyTypeObject *tp = PyInterpreterState_Get()->cached_objects.paramspec_type; + if (Py_IS_TYPE(psk->__origin__, tp)) { + return PyUnicode_FromFormat("%U.kwargs", + ((paramspecobject *)psk->__origin__)->name); + } + return PyUnicode_FromFormat("%R.kwargs", psk->__origin__); +} + +/*[clinic input] +@classmethod +paramspeckwargs.__new__ as paramspeckwargs_new + + origin: object + +Create a ParamSpecKwargs object. +[clinic start generated code]*/ + +static PyObject * +paramspeckwargs_new_impl(PyTypeObject *type, PyObject *origin) +/*[clinic end generated code: output=277b11967ebaf4ab input=981bca9b0cf9e40a]*/ +{ + return (PyObject *)paramspecattr_new(type, origin); +} + +static PyObject * +paramspeckwargs_mro_entries(PyObject *self, PyObject *args) +{ + PyErr_SetString(PyExc_TypeError, + "Cannot subclass an instance of ParamSpecKwargs"); + return NULL; +} + +static PyMethodDef paramspeckwargs_methods[] = { + {"__mro_entries__", paramspeckwargs_mro_entries, METH_O}, + {0} +}; + +PyDoc_STRVAR(paramspeckwargs_doc, +"The kwargs for a ParamSpec object.\n\ +\n\ +Given a ParamSpec object P, P.kwargs is an instance of ParamSpecKwargs.\n\ +\n\ +ParamSpecKwargs objects have a reference back to their ParamSpec::\n\ +\n\ + >>> P = ParamSpec(\"P\")\n\ + >>> P.kwargs.__origin__ is P\n\ + True\n\ +\n\ +This type is meant for runtime introspection and has no special meaning\n\ +to static type checkers.\n\ +"); + +static PyType_Slot paramspeckwargs_slots[] = { + {Py_tp_doc, (void *)paramspeckwargs_doc}, + {Py_tp_methods, paramspeckwargs_methods}, + {Py_tp_new, paramspeckwargs_new}, + {Py_tp_dealloc, paramspecattr_dealloc}, + {Py_tp_alloc, PyType_GenericAlloc}, + {Py_tp_free, PyObject_GC_Del}, + {Py_tp_traverse, paramspecattr_traverse}, + {Py_tp_clear, (inquiry)paramspecattr_clear}, + {Py_tp_repr, paramspeckwargs_repr}, + {Py_tp_members, paramspecattr_members}, + {Py_tp_richcompare, paramspecattr_richcompare}, + {0, NULL}, +}; + +PyType_Spec paramspeckwargs_spec = { + .name = "typing.ParamSpecKwargs", + .basicsize = sizeof(paramspecattrobject), + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE + | Py_TPFLAGS_MANAGED_WEAKREF, + .slots = paramspeckwargs_slots, +}; + +static void +paramspec_dealloc(PyObject *self) +{ + PyTypeObject *tp = Py_TYPE(self); + paramspecobject *ps = (paramspecobject *)self; + + _PyObject_GC_UNTRACK(self); + + Py_DECREF(ps->name); + Py_XDECREF(ps->bound); + _PyObject_ClearManagedDict(self); + PyObject_ClearWeakRefs(self); + + Py_TYPE(self)->tp_free(self); + Py_DECREF(tp); +} + +static int +paramspec_traverse(PyObject *self, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(self)); + paramspecobject *ps = (paramspecobject *)self; + Py_VISIT(ps->bound); + _PyObject_VisitManagedDict(self, visit, arg); + return 0; +} + +static int +paramspec_clear(paramspecobject *self) +{ + Py_CLEAR(self->bound); + _PyObject_ClearManagedDict((PyObject *)self); + return 0; +} + +static PyObject * +paramspec_repr(PyObject *self) +{ + paramspecobject *ps = (paramspecobject *)self; + + if (ps->infer_variance) { + return Py_NewRef(ps->name); + } + + char variance = ps->covariant ? '+' : ps->contravariant ? '-' : '~'; + return PyUnicode_FromFormat("%c%U", variance, ps->name); +} + +static PyMemberDef paramspec_members[] = { + {"__name__", T_OBJECT, offsetof(paramspecobject, name), READONLY}, + {"__bound__", T_OBJECT, offsetof(paramspecobject, bound), READONLY}, + {"__covariant__", T_BOOL, offsetof(paramspecobject, covariant), READONLY}, + {"__contravariant__", T_BOOL, offsetof(paramspecobject, contravariant), READONLY}, + {"__infer_variance__", T_BOOL, offsetof(paramspecobject, infer_variance), READONLY}, + {0} +}; + +static PyObject * +paramspec_args(PyObject *self, void *unused) +{ + PyTypeObject *tp = PyInterpreterState_Get()->cached_objects.paramspecargs_type; + return (PyObject *)paramspecattr_new(tp, self); +} + +static PyObject * +paramspec_kwargs(PyObject *self, void *unused) +{ + PyTypeObject *tp = PyInterpreterState_Get()->cached_objects.paramspeckwargs_type; + return (PyObject *)paramspecattr_new(tp, self); +} + +static PyGetSetDef paramspec_getset[] = { + {"args", (getter)paramspec_args, NULL, "Represents positional arguments.", NULL}, + {"kwargs", (getter)paramspec_kwargs, NULL, "Represents keyword arguments.", NULL}, + {0}, +}; + +static paramspecobject * +paramspec_alloc(PyObject *name, PyObject *bound, bool covariant, + bool contravariant, bool infer_variance, PyObject *module) +{ + PyTypeObject *tp = PyInterpreterState_Get()->cached_objects.paramspec_type; + paramspecobject *ps = PyObject_GC_New(paramspecobject, tp); + if (ps == NULL) { + return NULL; + } + ps->name = Py_NewRef(name); + ps->bound = Py_XNewRef(bound); + ps->covariant = covariant; + ps->contravariant = contravariant; + ps->infer_variance = infer_variance; + _PyObject_GC_TRACK(ps); + if (module != NULL) { + if (PyObject_SetAttrString((PyObject *)ps, "__module__", module) < 0) { + Py_DECREF(ps); + return NULL; + } + } + return ps; +} + +/*[clinic input] +@classmethod +paramspec.__new__ as paramspec_new + + name: object(subclass_of="&PyUnicode_Type") + * + bound: object = None + covariant: bool = False + contravariant: bool = False + infer_variance: bool = False + +Create a ParamSpec object. +[clinic start generated code]*/ + +static PyObject * +paramspec_new_impl(PyTypeObject *type, PyObject *name, PyObject *bound, + int covariant, int contravariant, int infer_variance) +/*[clinic end generated code: output=fd2daab79cba62da input=57c49c581979b952]*/ +{ + if (covariant && contravariant) { + PyErr_SetString(PyExc_ValueError, "Bivariant types are not supported."); + return NULL; + } + if (infer_variance && (covariant || contravariant)) { + PyErr_SetString(PyExc_ValueError, "Variance cannot be specified with infer_variance."); + return NULL; + } + if (bound != NULL) { + bound = type_check(bound, "Bound must be a type."); + if (bound == NULL) { + return NULL; + } + } + PyObject *module = caller(); + if (module == NULL) { + Py_XDECREF(bound); + return NULL; + } + PyObject *ps = (PyObject *)paramspec_alloc( + name, bound, covariant, contravariant, infer_variance, module); + Py_XDECREF(bound); + Py_DECREF(module); + return ps; +} + + +/*[clinic input] +paramspec.__typing_subst__ as paramspec_typing_subst + + arg: object + +[clinic start generated code]*/ + +static PyObject * +paramspec_typing_subst_impl(paramspecobject *self, PyObject *arg) +/*[clinic end generated code: output=803e1ade3f13b57d input=4e0005d24023e896]*/ +{ + PyObject *args[2] = {(PyObject *)self, arg}; + PyObject *result = call_typing_func_object("_paramspec_subst", args, 2); + return result; +} + +/*[clinic input] +paramspec.__typing_prepare_subst__ as paramspec_typing_prepare_subst + + alias: object + args: object + +[clinic start generated code]*/ + +static PyObject * +paramspec_typing_prepare_subst_impl(paramspecobject *self, PyObject *alias, + PyObject *args) +/*[clinic end generated code: output=95449d630a2adb9a input=4375e2ffcb2ad635]*/ +{ + PyObject *args_array[3] = {(PyObject *)self, alias, args}; + PyObject *result = call_typing_func_object( + "_paramspec_prepare_subst", args_array, 3); + return result; +} + +/*[clinic input] +paramspec.__reduce__ as paramspec_reduce + +[clinic start generated code]*/ + +static PyObject * +paramspec_reduce_impl(paramspecobject *self) +/*[clinic end generated code: output=b83398674416db27 input=5bf349f0d5dd426c]*/ +{ + return Py_NewRef(self->name); +} + +static PyObject * +paramspec_mro_entries(PyObject *self, PyObject *args) +{ + PyErr_SetString(PyExc_TypeError, + "Cannot subclass an instance of ParamSpec"); + return NULL; +} + +static PyMethodDef paramspec_methods[] = { + PARAMSPEC_TYPING_SUBST_METHODDEF + PARAMSPEC_TYPING_PREPARE_SUBST_METHODDEF + PARAMSPEC_REDUCE_METHODDEF + {"__mro_entries__", paramspec_mro_entries, METH_O}, + {0} +}; + +PyDoc_STRVAR(paramspec_doc, +"Parameter specification variable.\n\ +\n\ +The preferred way to construct a parameter specification is via the\n\ +dedicated syntax for generic functions, classes, and type aliases,\n\ +where the use of '**' creates a parameter specification::\n\ +\n\ + type IntFunc[**P] = Callable[P, int]\n\ +\n\ +For compatibility with Python 3.11 and earlier, ParamSpec objects\n\ +can also be created as follows::\n\ +\n\ + P = ParamSpec('P')\n\ +\n\ +Parameter specification variables exist primarily for the benefit of\n\ +static type checkers. They are used to forward the parameter types of\n\ +one callable to another callable, a pattern commonly found in\n\ +higher-order functions and decorators. They are only valid when used\n\ +in ``Concatenate``, or as the first argument to ``Callable``, or as\n\ +parameters for user-defined Generics. See class Generic for more\n\ +information on generic types.\n\ +\n\ +An example for annotating a decorator::\n\ +\n\ + def add_logging[**P, T](f: Callable[P, T]) -> Callable[P, T]:\n\ + '''A type-safe decorator to add logging to a function.'''\n\ + def inner(*args: P.args, **kwargs: P.kwargs) -> T:\n\ + logging.info(f'{f.__name__} was called')\n\ + return f(*args, **kwargs)\n\ + return inner\n\ +\n\ + @add_logging\n\ + def add_two(x: float, y: float) -> float:\n\ + '''Add two numbers together.'''\n\ + return x + y\n\ +\n\ +Parameter specification variables can be introspected. e.g.::\n\ +\n\ + >>> P = ParamSpec(\"P\")\n\ + >>> P.__name__\n\ + 'P'\n\ +\n\ +Note that only parameter specification variables defined in the global\n\ +scope can be pickled.\n\ +"); + +static PyType_Slot paramspec_slots[] = { + {Py_tp_doc, (void *)paramspec_doc}, + {Py_tp_members, paramspec_members}, + {Py_tp_methods, paramspec_methods}, + {Py_tp_getset, paramspec_getset}, + // Unions of ParamSpecs have no defined meaning, but they were allowed + // by the Python implementation, so we allow them here too. + {Py_nb_or, make_union}, + {Py_tp_new, paramspec_new}, + {Py_tp_dealloc, paramspec_dealloc}, + {Py_tp_alloc, PyType_GenericAlloc}, + {Py_tp_free, PyObject_GC_Del}, + {Py_tp_traverse, paramspec_traverse}, + {Py_tp_clear, paramspec_clear}, + {Py_tp_repr, paramspec_repr}, + {0, 0}, +}; + +PyType_Spec paramspec_spec = { + .name = "typing.ParamSpec", + .basicsize = sizeof(paramspecobject), + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE + | Py_TPFLAGS_MANAGED_DICT | Py_TPFLAGS_MANAGED_WEAKREF, + .slots = paramspec_slots, +}; + +static void +typevartuple_dealloc(PyObject *self) +{ + PyTypeObject *tp = Py_TYPE(self); + _PyObject_GC_UNTRACK(self); + typevartupleobject *tvt = (typevartupleobject *)self; + + Py_DECREF(tvt->name); + _PyObject_ClearManagedDict(self); + PyObject_ClearWeakRefs(self); + + Py_TYPE(self)->tp_free(self); + Py_DECREF(tp); +} + +static PyObject * +typevartuple_iter(PyObject *self) +{ + PyObject *unpacked = typevartuple_unpack(self); + if (unpacked == NULL) { + return NULL; + } + PyObject *tuple = PyTuple_Pack(1, unpacked); + if (tuple == NULL) { + Py_DECREF(unpacked); + return NULL; + } + PyObject *result = PyObject_GetIter(tuple); + Py_DECREF(unpacked); + Py_DECREF(tuple); + return result; +} + +static PyObject * +typevartuple_repr(PyObject *self) +{ + typevartupleobject *tvt = (typevartupleobject *)self; + + return Py_NewRef(tvt->name); +} + +static PyMemberDef typevartuple_members[] = { + {"__name__", T_OBJECT, offsetof(typevartupleobject, name), READONLY}, + {0} +}; + +static typevartupleobject * +typevartuple_alloc(PyObject *name, PyObject *module) +{ + PyTypeObject *tp = PyInterpreterState_Get()->cached_objects.typevartuple_type; + typevartupleobject *tvt = PyObject_GC_New(typevartupleobject, tp); + if (tvt == NULL) { + return NULL; + } + tvt->name = Py_NewRef(name); + _PyObject_GC_TRACK(tvt); + if (module != NULL) { + if (PyObject_SetAttrString((PyObject *)tvt, "__module__", module) < 0) { + Py_DECREF(tvt); + return NULL; + } + } + return tvt; +} + +/*[clinic input] +@classmethod +typevartuple.__new__ + + name: object(subclass_of="&PyUnicode_Type") + +Create a new TypeVarTuple with the given name. +[clinic start generated code]*/ + +static PyObject * +typevartuple_impl(PyTypeObject *type, PyObject *name) +/*[clinic end generated code: output=09d417a28f976202 input=00d28abcf1fc96bb]*/ +{ + PyObject *module = caller(); + if (module == NULL) { + return NULL; + } + PyObject *result = (PyObject *)typevartuple_alloc(name, module); + Py_DECREF(module); + return result; +} + +/*[clinic input] +typevartuple.__typing_subst__ as typevartuple_typing_subst + + arg: object + +[clinic start generated code]*/ + +static PyObject * +typevartuple_typing_subst_impl(typevartupleobject *self, PyObject *arg) +/*[clinic end generated code: output=814316519441cd76 input=670c4e0a36e5d8c0]*/ +{ + PyErr_SetString(PyExc_TypeError, "Substitution of bare TypeVarTuple is not supported"); + return NULL; +} + +/*[clinic input] +typevartuple.__typing_prepare_subst__ as typevartuple_typing_prepare_subst + + alias: object + args: object + +[clinic start generated code]*/ + +static PyObject * +typevartuple_typing_prepare_subst_impl(typevartupleobject *self, + PyObject *alias, PyObject *args) +/*[clinic end generated code: output=ff999bc5b02036c1 input=a211b05f2eeb4306]*/ +{ + PyObject *args_array[3] = {(PyObject *)self, alias, args}; + PyObject *result = call_typing_func_object( + "_typevartuple_prepare_subst", args_array, 3); + return result; +} + +/*[clinic input] +typevartuple.__reduce__ as typevartuple_reduce + +[clinic start generated code]*/ + +static PyObject * +typevartuple_reduce_impl(typevartupleobject *self) +/*[clinic end generated code: output=3215bc0477913d20 input=3018a4d66147e807]*/ +{ + return Py_NewRef(self->name); +} + +static PyObject * +typevartuple_mro_entries(PyObject *self, PyObject *args) +{ + PyErr_SetString(PyExc_TypeError, + "Cannot subclass an instance of TypeVarTuple"); + return NULL; +} + +static int +typevartuple_traverse(PyObject *self, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(self)); + _PyObject_VisitManagedDict(self, visit, arg); + return 0; +} + +static int +typevartuple_clear(PyObject *self) +{ + _PyObject_ClearManagedDict(self); + return 0; +} + +static PyMethodDef typevartuple_methods[] = { + TYPEVARTUPLE_TYPING_SUBST_METHODDEF + TYPEVARTUPLE_TYPING_PREPARE_SUBST_METHODDEF + TYPEVARTUPLE_REDUCE_METHODDEF + {"__mro_entries__", typevartuple_mro_entries, METH_O}, + {0} +}; + +PyDoc_STRVAR(typevartuple_doc, +"Type variable tuple. A specialized form of type variable that enables\n\ +variadic generics.\n\ +\n\ +The preferred way to construct a type variable tuple is via the\n\ +dedicated syntax for generic functions, classes, and type aliases,\n\ +where a single '*' indicates a type variable tuple::\n\ +\n\ + def move_first_element_to_last[T, *Ts](tup: tuple[T, *Ts]) -> tuple[*Ts, T]:\n\ + return (*tup[1:], tup[0])\n\ +\n\ +For compatibility with Python 3.11 and earlier, TypeVarTuple objects\n\ +can also be created as follows::\n\ +\n\ + Ts = TypeVarTuple('Ts') # Can be given any name\n\ +\n\ +Just as a TypeVar (type variable) is a placeholder for a single type,\n\ +a TypeVarTuple is a placeholder for an *arbitrary* number of types. For\n\ +example, if we define a generic class using a TypeVarTuple::\n\ +\n\ + class C[*Ts]: ...\n\ +\n\ +Then we can parameterize that class with an arbitrary number of type\n\ +arguments::\n\ +\n\ + C[int] # Fine\n\ + C[int, str] # Also fine\n\ + C[()] # Even this is fine\n\ +\n\ +For more details, see PEP 646.\n\ +\n\ +Note that only TypeVarTuples defined in the global scope can be\n\ +pickled.\n\ +"); + +PyType_Slot typevartuple_slots[] = { + {Py_tp_doc, (void *)typevartuple_doc}, + {Py_tp_members, typevartuple_members}, + {Py_tp_methods, typevartuple_methods}, + {Py_tp_new, typevartuple}, + {Py_tp_iter, typevartuple_iter}, + {Py_tp_repr, typevartuple_repr}, + {Py_tp_dealloc, typevartuple_dealloc}, + {Py_tp_alloc, PyType_GenericAlloc}, + {Py_tp_free, PyObject_GC_Del}, + {Py_tp_traverse, typevartuple_traverse}, + {Py_tp_clear, typevartuple_clear}, + {0, 0}, +}; + +PyType_Spec typevartuple_spec = { + .name = "typing.TypeVarTuple", + .basicsize = sizeof(typevartupleobject), + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_MANAGED_DICT + | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_MANAGED_WEAKREF, + .slots = typevartuple_slots, +}; + +PyObject * +_Py_make_typevar(PyObject *name, PyObject *evaluate_bound, PyObject *evaluate_constraints) +{ + return (PyObject *)typevar_alloc(name, NULL, evaluate_bound, NULL, evaluate_constraints, + false, false, true, NULL); +} + +PyObject * +_Py_make_paramspec(PyThreadState *Py_UNUSED(ignored), PyObject *v) +{ + assert(PyUnicode_Check(v)); + return (PyObject *)paramspec_alloc(v, NULL, false, false, true, NULL); +} + +PyObject * +_Py_make_typevartuple(PyThreadState *Py_UNUSED(ignored), PyObject *v) +{ + assert(PyUnicode_Check(v)); + return (PyObject *)typevartuple_alloc(v, NULL); +} + +static void +typealias_dealloc(PyObject *self) +{ + PyTypeObject *tp = Py_TYPE(self); + _PyObject_GC_UNTRACK(self); + typealiasobject *ta = (typealiasobject *)self; + Py_DECREF(ta->name); + Py_XDECREF(ta->type_params); + Py_XDECREF(ta->compute_value); + Py_XDECREF(ta->value); + Py_XDECREF(ta->module); + Py_TYPE(self)->tp_free(self); + Py_DECREF(tp); +} + +static PyObject * +typealias_get_value(typealiasobject *ta) +{ + if (ta->value != NULL) { + return Py_NewRef(ta->value); + } + PyObject *result = PyObject_CallNoArgs(ta->compute_value); + if (result == NULL) { + return NULL; + } + ta->value = Py_NewRef(result); + return result; +} + +static PyObject * +typealias_repr(PyObject *self) +{ + typealiasobject *ta = (typealiasobject *)self; + return Py_NewRef(ta->name); +} + +static PyMemberDef typealias_members[] = { + {"__name__", T_OBJECT, offsetof(typealiasobject, name), READONLY}, + {0} +}; + +static PyObject * +typealias_value(PyObject *self, void *unused) +{ + typealiasobject *ta = (typealiasobject *)self; + return typealias_get_value(ta); +} + +static PyObject * +typealias_parameters(PyObject *self, void *unused) +{ + typealiasobject *ta = (typealiasobject *)self; + if (ta->type_params == NULL) { + return PyTuple_New(0); + } + return unpack_typevartuples(ta->type_params); +} + +static PyObject * +typealias_type_params(PyObject *self, void *unused) +{ + typealiasobject *ta = (typealiasobject *)self; + if (ta->type_params == NULL) { + return PyTuple_New(0); + } + return Py_NewRef(ta->type_params); +} + +static PyObject * +typealias_module(PyObject *self, void *unused) +{ + typealiasobject *ta = (typealiasobject *)self; + if (ta->module != NULL) { + return Py_NewRef(ta->module); + } + if (ta->compute_value != NULL) { + PyObject* mod = PyFunction_GetModule(ta->compute_value); + if (mod != NULL) { + // PyFunction_GetModule() returns a borrowed reference, + // and it may return NULL (e.g., for functions defined + // in an exec()'ed block). + return Py_NewRef(mod); + } + } + Py_RETURN_NONE; +} + +static PyGetSetDef typealias_getset[] = { + {"__parameters__", typealias_parameters, (setter)NULL, NULL, NULL}, + {"__type_params__", typealias_type_params, (setter)NULL, NULL, NULL}, + {"__value__", typealias_value, (setter)NULL, NULL, NULL}, + {"__module__", typealias_module, (setter)NULL, NULL, NULL}, + {0} +}; + +static typealiasobject * +typealias_alloc(PyObject *name, PyObject *type_params, PyObject *compute_value, + PyObject *value, PyObject *module) +{ + typealiasobject *ta = PyObject_GC_New(typealiasobject, &_PyTypeAlias_Type); + if (ta == NULL) { + return NULL; + } + ta->name = Py_NewRef(name); + ta->type_params = Py_IsNone(type_params) ? NULL : Py_XNewRef(type_params); + ta->compute_value = Py_XNewRef(compute_value); + ta->value = Py_XNewRef(value); + ta->module = Py_XNewRef(module); + _PyObject_GC_TRACK(ta); + return ta; +} + +static int +typealias_traverse(typealiasobject *self, visitproc visit, void *arg) +{ + Py_VISIT(self->type_params); + Py_VISIT(self->compute_value); + Py_VISIT(self->value); + Py_VISIT(self->module); + return 0; +} + +static int +typealias_clear(typealiasobject *self) +{ + Py_CLEAR(self->type_params); + Py_CLEAR(self->compute_value); + Py_CLEAR(self->value); + Py_CLEAR(self->module); + return 0; +} + +/*[clinic input] +typealias.__reduce__ as typealias_reduce + +[clinic start generated code]*/ + +static PyObject * +typealias_reduce_impl(typealiasobject *self) +/*[clinic end generated code: output=913724f92ad3b39b input=4f06fbd9472ec0f1]*/ +{ + return Py_NewRef(self->name); +} + +static PyObject * +typealias_subscript(PyObject *self, PyObject *args) +{ + if (((typealiasobject *)self)->type_params == NULL) { + PyErr_SetString(PyExc_TypeError, + "Only generic type aliases are subscriptable"); + return NULL; + } + return Py_GenericAlias(self, args); +} + +static PyMethodDef typealias_methods[] = { + TYPEALIAS_REDUCE_METHODDEF + {0} +}; + + +/*[clinic input] +@classmethod +typealias.__new__ as typealias_new + + name: object(subclass_of="&PyUnicode_Type") + value: object + * + type_params: object = NULL + +Create a TypeAliasType. +[clinic start generated code]*/ + +static PyObject * +typealias_new_impl(PyTypeObject *type, PyObject *name, PyObject *value, + PyObject *type_params) +/*[clinic end generated code: output=8920ce6bdff86f00 input=df163c34e17e1a35]*/ +{ + if (type_params != NULL && !PyTuple_Check(type_params)) { + PyErr_SetString(PyExc_TypeError, "type_params must be a tuple"); + return NULL; + } + PyObject *module = caller(); + if (module == NULL) { + return NULL; + } + PyObject *ta = (PyObject *)typealias_alloc(name, type_params, NULL, value, + module); + Py_DECREF(module); + return ta; +} + +PyDoc_STRVAR(typealias_doc, +"Type alias.\n\ +\n\ +Type aliases are created through the type statement::\n\ +\n\ + type Alias = int\n\ +\n\ +In this example, Alias and int will be treated equivalently by static\n\ +type checkers.\n\ +\n\ +At runtime, Alias is an instance of TypeAliasType. The __name__\n\ +attribute holds the name of the type alias. The value of the type alias\n\ +is stored in the __value__ attribute. It is evaluated lazily, so the\n\ +value is computed only if the attribute is accessed.\n\ +\n\ +Type aliases can also be generic::\n\ +\n\ + type ListOrSet[T] = list[T] | set[T]\n\ +\n\ +In this case, the type parameters of the alias are stored in the\n\ +__type_params__ attribute.\n\ +\n\ +See PEP 695 for more information.\n\ +"); + +static PyNumberMethods typealias_as_number = { + .nb_or = _Py_union_type_or, +}; + +static PyMappingMethods typealias_as_mapping = { + .mp_subscript = typealias_subscript, +}; + +PyTypeObject _PyTypeAlias_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + .tp_name = "typing.TypeAliasType", + .tp_basicsize = sizeof(typealiasobject), + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_HAVE_GC, + .tp_doc = typealias_doc, + .tp_members = typealias_members, + .tp_methods = typealias_methods, + .tp_getset = typealias_getset, + .tp_alloc = PyType_GenericAlloc, + .tp_dealloc = typealias_dealloc, + .tp_new = typealias_new, + .tp_free = PyObject_GC_Del, + .tp_traverse = (traverseproc)typealias_traverse, + .tp_clear = (inquiry)typealias_clear, + .tp_repr = typealias_repr, + .tp_as_number = &typealias_as_number, + .tp_as_mapping = &typealias_as_mapping, +}; + +PyObject * +_Py_make_typealias(PyThreadState* unused, PyObject *args) +{ + assert(PyTuple_Check(args)); + assert(PyTuple_GET_SIZE(args) == 3); + PyObject *name = PyTuple_GET_ITEM(args, 0); + assert(PyUnicode_Check(name)); + PyObject *type_params = PyTuple_GET_ITEM(args, 1); + PyObject *compute_value = PyTuple_GET_ITEM(args, 2); + assert(PyFunction_Check(compute_value)); + return (PyObject *)typealias_alloc(name, type_params, compute_value, NULL, NULL); +} + +PyDoc_STRVAR(generic_doc, +"Abstract base class for generic types.\n\ +\n\ +On Python 3.12 and newer, generic classes implicitly inherit from\n\ +Generic when they declare a parameter list after the class's name::\n\ +\n\ + class Mapping[KT, VT]:\n\ + def __getitem__(self, key: KT) -> VT:\n\ + ...\n\ + # Etc.\n\ +\n\ +On older versions of Python, however, generic classes have to\n\ +explicitly inherit from Generic.\n\ +\n\ +After a class has been declared to be generic, it can then be used as\n\ +follows::\n\ +\n\ + def lookup_name[KT, VT](mapping: Mapping[KT, VT], key: KT, default: VT) -> VT:\n\ + try:\n\ + return mapping[key]\n\ + except KeyError:\n\ + return default\n\ +"); + +PyDoc_STRVAR(generic_class_getitem_doc, +"Parameterizes a generic class.\n\ +\n\ +At least, parameterizing a generic class is the *main* thing this\n\ +method does. For example, for some generic class `Foo`, this is called\n\ +when we do `Foo[int]` - there, with `cls=Foo` and `params=int`.\n\ +\n\ +However, note that this method is also called when defining generic\n\ +classes in the first place with `class Foo[T]: ...`.\n\ +"); + +static PyObject * +call_typing_args_kwargs(const char *name, PyTypeObject *cls, PyObject *args, PyObject *kwargs) +{ + PyObject *typing = NULL, *func = NULL, *new_args = NULL; + typing = PyImport_ImportModule("typing"); + if (typing == NULL) { + goto error; + } + func = PyObject_GetAttrString(typing, name); + if (func == NULL) { + goto error; + } + assert(PyTuple_Check(args)); + Py_ssize_t nargs = PyTuple_GET_SIZE(args); + new_args = PyTuple_New(nargs + 1); + if (new_args == NULL) { + goto error; + } + PyTuple_SET_ITEM(new_args, 0, Py_NewRef((PyObject *)cls)); + for (Py_ssize_t i = 0; i < nargs; i++) { + PyObject *arg = PyTuple_GET_ITEM(args, i); + PyTuple_SET_ITEM(new_args, i + 1, Py_NewRef(arg)); + } + PyObject *result = PyObject_Call(func, new_args, kwargs); + Py_DECREF(typing); + Py_DECREF(func); + Py_DECREF(new_args); + return result; +error: + Py_XDECREF(typing); + Py_XDECREF(func); + Py_XDECREF(new_args); + return NULL; +} + +static PyObject * +generic_init_subclass(PyTypeObject *cls, PyObject *args, PyObject *kwargs) +{ + return call_typing_args_kwargs("_generic_init_subclass", cls, args, kwargs); +} + +static PyObject * +generic_class_getitem(PyTypeObject *cls, PyObject *args, PyObject *kwargs) +{ + return call_typing_args_kwargs("_generic_class_getitem", cls, args, kwargs); +} + +PyObject * +_Py_subscript_generic(PyThreadState* unused, PyObject *params) +{ + params = unpack_typevartuples(params); + + PyInterpreterState *interp = PyInterpreterState_Get(); + if (interp->cached_objects.generic_type == NULL) { + PyErr_SetString(PyExc_SystemError, "Cannot find Generic type"); + return NULL; + } + PyObject *args[2] = {(PyObject *)interp->cached_objects.generic_type, params}; + PyObject *result = call_typing_func_object("_GenericAlias", args, 2); + Py_DECREF(params); + return result; +} + +static PyMethodDef generic_methods[] = { + {"__class_getitem__", (PyCFunction)(void (*)(void))generic_class_getitem, + METH_VARARGS | METH_KEYWORDS | METH_CLASS, + generic_class_getitem_doc}, + {"__init_subclass__", (PyCFunction)(void (*)(void))generic_init_subclass, + METH_VARARGS | METH_KEYWORDS | METH_CLASS, + PyDoc_STR("Function to initialize subclasses.")}, + {NULL} /* Sentinel */ +}; + +static void +generic_dealloc(PyObject *self) +{ + PyTypeObject *tp = Py_TYPE(self); + _PyObject_GC_UNTRACK(self); + Py_TYPE(self)->tp_free(self); + Py_DECREF(tp); +} + +static int +generic_traverse(PyObject *self, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(self)); + return 0; +} + +static PyType_Slot generic_slots[] = { + {Py_tp_doc, (void *)generic_doc}, + {Py_tp_methods, generic_methods}, + {Py_tp_dealloc, generic_dealloc}, + {Py_tp_alloc, PyType_GenericAlloc}, + {Py_tp_free, PyObject_GC_Del}, + {Py_tp_traverse, generic_traverse}, + {0, NULL}, +}; + +PyType_Spec generic_spec = { + .name = "typing.Generic", + .basicsize = sizeof(PyObject), + .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, + .slots = generic_slots, +}; + +int _Py_initialize_generic(PyInterpreterState *interp) +{ +#define MAKE_TYPE(name) \ + do { \ + PyTypeObject *name ## _type = (PyTypeObject *)PyType_FromSpec(&name ## _spec); \ + if (name ## _type == NULL) { \ + return -1; \ + } \ + interp->cached_objects.name ## _type = name ## _type; \ + } while(0) + + MAKE_TYPE(generic); + MAKE_TYPE(typevar); + MAKE_TYPE(typevartuple); + MAKE_TYPE(paramspec); + MAKE_TYPE(paramspecargs); + MAKE_TYPE(paramspeckwargs); +#undef MAKE_TYPE + return 0; +} + +void _Py_clear_generic_types(PyInterpreterState *interp) +{ + Py_CLEAR(interp->cached_objects.generic_type); + Py_CLEAR(interp->cached_objects.typevar_type); + Py_CLEAR(interp->cached_objects.typevartuple_type); + Py_CLEAR(interp->cached_objects.paramspec_type); + Py_CLEAR(interp->cached_objects.paramspecargs_type); + Py_CLEAR(interp->cached_objects.paramspeckwargs_type); +} diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index a19eaadc..26aa1391 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -54,7 +54,9 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "pycore_pystate.h" // _PyInterpreterState_GET() #include "pycore_ucnhash.h" // _PyUnicode_Name_CAPI #include "pycore_unicodeobject.h" // struct _Py_unicode_state +#include "pycore_unicodeobject_generated.h" // _PyUnicode_InitStaticStrings() #include "stringlib/eq.h" // unicode_eq() +#include <stddef.h> // ptrdiff_t #ifdef MS_WINDOWS #include <windows.h> @@ -115,7 +117,6 @@ extern "C" { (_PyCompactUnicodeObject_CAST(op)->utf8) #define PyUnicode_UTF8(op) \ (assert(_PyUnicode_CHECK(op)), \ - assert(PyUnicode_IS_READY(op)), \ PyUnicode_IS_COMPACT_ASCII(op) ? \ ((char*)(_PyASCIIObject_CAST(op) + 1)) : \ _PyUnicode_UTF8(op)) @@ -123,21 +124,10 @@ extern "C" { (_PyCompactUnicodeObject_CAST(op)->utf8_length) #define PyUnicode_UTF8_LENGTH(op) \ (assert(_PyUnicode_CHECK(op)), \ - assert(PyUnicode_IS_READY(op)), \ PyUnicode_IS_COMPACT_ASCII(op) ? \ _PyASCIIObject_CAST(op)->length : \ _PyUnicode_UTF8_LENGTH(op)) -#define _PyUnicode_WSTR(op) \ - (_PyASCIIObject_CAST(op)->wstr) - -/* Don't use deprecated macro of unicodeobject.h */ -#undef PyUnicode_WSTR_LENGTH -#define PyUnicode_WSTR_LENGTH(op) \ - (PyUnicode_IS_COMPACT_ASCII(op) ? \ - _PyASCIIObject_CAST(op)->length : \ - _PyCompactUnicodeObject_CAST(op)->wstr_length) -#define _PyUnicode_WSTR_LENGTH(op) \ - (_PyCompactUnicodeObject_CAST(op)->wstr_length) + #define _PyUnicode_LENGTH(op) \ (_PyASCIIObject_CAST(op)->length) #define _PyUnicode_STATE(op) \ @@ -153,20 +143,10 @@ extern "C" { #define _PyUnicode_DATA_ANY(op) \ (_PyUnicodeObject_CAST(op)->data.any) -#undef PyUnicode_READY -#define PyUnicode_READY(op) \ - (assert(_PyUnicode_CHECK(op)), \ - (PyUnicode_IS_READY(op) ? \ - 0 : \ - _PyUnicode_Ready(op))) - #define _PyUnicode_SHARE_UTF8(op) \ (assert(_PyUnicode_CHECK(op)), \ assert(!PyUnicode_IS_COMPACT_ASCII(op)), \ (_PyUnicode_UTF8(op) == PyUnicode_DATA(op))) -#define _PyUnicode_SHARE_WSTR(op) \ - (assert(_PyUnicode_CHECK(op)), \ - (_PyUnicode_WSTR(unicode) == PyUnicode_DATA(op))) /* true if the Unicode object has an allocated UTF-8 memory block (not shared with other data) */ @@ -175,13 +155,6 @@ extern "C" { && _PyUnicode_UTF8(op) \ && _PyUnicode_UTF8(op) != PyUnicode_DATA(op))) -/* true if the Unicode object has an allocated wstr memory block - (not shared with other data) */ -#define _PyUnicode_HAS_WSTR_MEMORY(op) \ - ((_PyUnicode_WSTR(op) && \ - (!PyUnicode_IS_READY(op) || \ - _PyUnicode_WSTR(op) != PyUnicode_DATA(op)))) - /* Generic helper macro to convert characters of different types. from_type and to_type have to be valid type names, begin and end are pointers to the source characters which should be of type @@ -219,16 +192,6 @@ extern "C" { # define OVERALLOCATE_FACTOR 4 #endif -/* This dictionary holds all interned unicode strings. Note that references - to strings in this dictionary are *not* counted in the string's ob_refcnt. - When the interned string reaches a refcnt of 0 the string deallocation - function will delete the reference from this dictionary. - - Another way to look at this is that to say that the actual reference - count of a string is: s->ob_refcnt + (s->state ? 2 : 0) -*/ -static PyObject *interned = NULL; - /* Forward declaration */ static inline int _PyUnicodeWriter_WriteCharInline(_PyUnicodeWriter *writer, Py_UCS4 ch); @@ -259,8 +222,46 @@ static inline PyObject* unicode_get_empty(void) static inline PyObject* unicode_new_empty(void) { PyObject *empty = unicode_get_empty(); - Py_INCREF(empty); - return empty; + return Py_NewRef(empty); +} + +/* This dictionary holds all interned unicode strings. Note that references + to strings in this dictionary are *not* counted in the string's ob_refcnt. + When the interned string reaches a refcnt of 0 the string deallocation + function will delete the reference from this dictionary. +*/ +static inline PyObject *get_interned_dict(PyInterpreterState *interp) +{ + return _Py_INTERP_CACHED_OBJECT(interp, interned_strings); +} + +Py_ssize_t +_PyUnicode_InternedSize(void) +{ + return PyObject_Length(get_interned_dict(_PyInterpreterState_GET())); +} + +static int +init_interned_dict(PyInterpreterState *interp) +{ + assert(get_interned_dict(interp) == NULL); + PyObject *interned = interned = PyDict_New(); + if (interned == NULL) { + return -1; + } + _Py_INTERP_CACHED_OBJECT(interp, interned_strings) = interned; + return 0; +} + +static void +clear_interned_dict(PyInterpreterState *interp) +{ + PyObject *interned = get_interned_dict(interp); + if (interned != NULL) { + PyDict_Clear(interned); + Py_DECREF(interned); + _Py_INTERP_CACHED_OBJECT(interp, interned_strings) = NULL; + } } #define _Py_RETURN_UNICODE_EMPTY() \ @@ -269,11 +270,10 @@ static inline PyObject* unicode_new_empty(void) } while (0) static inline void -unicode_fill(enum PyUnicode_Kind kind, void *data, Py_UCS4 value, +unicode_fill(int kind, void *data, Py_UCS4 value, Py_ssize_t start, Py_ssize_t length) { assert(0 <= start); - assert(kind != PyUnicode_WCHAR_KIND); switch (kind) { case PyUnicode_1BYTE_KIND: { assert(value <= 0xff); @@ -335,7 +335,6 @@ const unsigned char _Py_ascii_whitespace[] = { }; /* forward */ -static PyUnicodeObject *_PyUnicode_New(Py_ssize_t length); static PyObject* get_latin1_char(unsigned char ch); static int unicode_modifiable(PyObject *unicode); @@ -478,7 +477,14 @@ unicode_check_encoding_errors(const char *encoding, const char *errors) return 0; } - if (encoding != NULL) { + if (encoding != NULL + // Fast path for the most common built-in encodings. Even if the codec + // is cached, _PyCodec_Lookup() decodes the bytes string from UTF-8 to + // create a temporary Unicode string (the key in the cache). + && strcmp(encoding, "utf-8") != 0 + && strcmp(encoding, "utf8") != 0 + && strcmp(encoding, "ascii") != 0) + { PyObject *handler = _PyCodec_Lookup(encoding); if (handler == NULL) { return -1; @@ -486,7 +492,14 @@ unicode_check_encoding_errors(const char *encoding, const char *errors) Py_DECREF(handler); } - if (errors != NULL) { + if (errors != NULL + // Fast path for the most common built-in error handlers. + && strcmp(errors, "strict") != 0 + && strcmp(errors, "ignore") != 0 + && strcmp(errors, "replace") != 0 + && strcmp(errors, "surrogateescape") != 0 + && strcmp(errors, "surrogatepass") != 0) + { PyObject *handler = PyCodec_LookupError(errors); if (handler == NULL) { return -1; @@ -507,11 +520,10 @@ _PyUnicode_CheckConsistency(PyObject *op, int check_content) CHECK(PyUnicode_Check(op)); PyASCIIObject *ascii = _PyASCIIObject_CAST(op); - unsigned int kind = ascii->state.kind; + int kind = ascii->state.kind; if (ascii->state.ascii == 1 && ascii->state.compact == 1) { CHECK(kind == PyUnicode_1BYTE_KIND); - CHECK(ascii->state.ready == 1); } else { PyCompactUnicodeObject *compact = _PyCompactUnicodeObject_CAST(op); @@ -523,62 +535,32 @@ _PyUnicode_CheckConsistency(PyObject *op, int check_content) || kind == PyUnicode_2BYTE_KIND || kind == PyUnicode_4BYTE_KIND); CHECK(ascii->state.ascii == 0); - CHECK(ascii->state.ready == 1); CHECK(compact->utf8 != data); } else { PyUnicodeObject *unicode = _PyUnicodeObject_CAST(op); data = unicode->data.any; - if (kind == PyUnicode_WCHAR_KIND) { - CHECK(ascii->length == 0); - CHECK(ascii->hash == -1); - CHECK(ascii->state.compact == 0); - CHECK(ascii->state.ascii == 0); - CHECK(ascii->state.ready == 0); - CHECK(ascii->state.interned == SSTATE_NOT_INTERNED); - CHECK(ascii->wstr != NULL); - CHECK(data == NULL); - CHECK(compact->utf8 == NULL); + CHECK(kind == PyUnicode_1BYTE_KIND + || kind == PyUnicode_2BYTE_KIND + || kind == PyUnicode_4BYTE_KIND); + CHECK(ascii->state.compact == 0); + CHECK(data != NULL); + if (ascii->state.ascii) { + CHECK(compact->utf8 == data); + CHECK(compact->utf8_length == ascii->length); } else { - CHECK(kind == PyUnicode_1BYTE_KIND - || kind == PyUnicode_2BYTE_KIND - || kind == PyUnicode_4BYTE_KIND); - CHECK(ascii->state.compact == 0); - CHECK(ascii->state.ready == 1); - CHECK(data != NULL); - if (ascii->state.ascii) { - CHECK(compact->utf8 == data); - CHECK(compact->utf8_length == ascii->length); - } - else - CHECK(compact->utf8 != data); + CHECK(compact->utf8 != data); } } - if (kind != PyUnicode_WCHAR_KIND) { - if ( -#if SIZEOF_WCHAR_T == 2 - kind == PyUnicode_2BYTE_KIND -#else - kind == PyUnicode_4BYTE_KIND -#endif - ) - { - CHECK(ascii->wstr == data); - CHECK(compact->wstr_length == ascii->length); - } else - CHECK(ascii->wstr != data); - } if (compact->utf8 == NULL) CHECK(compact->utf8_length == 0); - if (ascii->wstr == NULL) - CHECK(compact->wstr_length == 0); } /* check that the best kind is used: O(n) operation */ - if (check_content && kind != PyUnicode_WCHAR_KIND) { + if (check_content) { Py_ssize_t i; Py_UCS4 maxchar = 0; const void *data; @@ -614,47 +596,12 @@ _PyUnicode_CheckConsistency(PyObject *op, int check_content) #undef CHECK } - static PyObject* -unicode_result_wchar(PyObject *unicode) -{ -#ifndef Py_DEBUG - Py_ssize_t len; - - len = _PyUnicode_WSTR_LENGTH(unicode); - if (len == 0) { - Py_DECREF(unicode); - _Py_RETURN_UNICODE_EMPTY(); - } - - if (len == 1) { - wchar_t ch = _PyUnicode_WSTR(unicode)[0]; - if ((Py_UCS4)ch < 256) { - Py_DECREF(unicode); - return get_latin1_char((unsigned char)ch); - } - } - - if (_PyUnicode_Ready(unicode) < 0) { - Py_DECREF(unicode); - return NULL; - } -#else - assert(Py_REFCNT(unicode) == 1); - - /* don't make the result ready in debug mode to ensure that the caller - makes the string ready before using it */ - assert(_PyUnicode_CheckConsistency(unicode, 1)); -#endif - return unicode; -} - -static PyObject* -unicode_result_ready(PyObject *unicode) +unicode_result(PyObject *unicode) { - Py_ssize_t length; + assert(_PyUnicode_CHECK(unicode)); - length = PyUnicode_GET_LENGTH(unicode); + Py_ssize_t length = PyUnicode_GET_LENGTH(unicode); if (length == 0) { PyObject *empty = unicode_get_empty(); if (unicode != empty) { @@ -682,24 +629,11 @@ unicode_result_ready(PyObject *unicode) return unicode; } -static PyObject* -unicode_result(PyObject *unicode) -{ - assert(_PyUnicode_CHECK(unicode)); - if (PyUnicode_IS_READY(unicode)) - return unicode_result_ready(unicode); - else - return unicode_result_wchar(unicode); -} - static PyObject* unicode_result_unchanged(PyObject *unicode) { if (PyUnicode_CheckExact(unicode)) { - if (PyUnicode_READY(unicode) == -1) - return NULL; - Py_INCREF(unicode); - return unicode; + return Py_NewRef(unicode); } else /* Subtype -- return genuine unicode string with the same value. */ @@ -714,10 +648,9 @@ backslashreplace(_PyBytesWriter *writer, char *str, { Py_ssize_t size, i; Py_UCS4 ch; - enum PyUnicode_Kind kind; + int kind; const void *data; - assert(PyUnicode_IS_READY(unicode)); kind = PyUnicode_KIND(unicode); data = PyUnicode_DATA(unicode); @@ -781,10 +714,9 @@ xmlcharrefreplace(_PyBytesWriter *writer, char *str, { Py_ssize_t size, i; Py_UCS4 ch; - enum PyUnicode_Kind kind; + int kind; const void *data; - assert(PyUnicode_IS_READY(unicode)); kind = PyUnicode_KIND(unicode); data = PyUnicode_DATA(unicode); @@ -908,7 +840,7 @@ ensure_unicode(PyObject *obj) Py_TYPE(obj)->tp_name); return -1; } - return PyUnicode_READY(obj); + return 0; } /* Compilation of templated routines */ @@ -954,15 +886,6 @@ ensure_unicode(PyObject *obj) #include "stringlib/find_max_char.h" #include "stringlib/undef.h" -_Py_COMP_DIAG_PUSH -_Py_COMP_DIAG_IGNORE_DEPR_DECLS -#include "stringlib/unicodedefs.h" -#include "stringlib/fastsearch.h" -#include "stringlib/count.h" -#include "stringlib/find.h" -#include "stringlib/undef.h" -_Py_COMP_DIAG_POP - #undef STRINGLIB_GET_EMPTY /* --- Unicode Object ----------------------------------------------------- */ @@ -1022,14 +945,12 @@ resize_compact(PyObject *unicode, Py_ssize_t length) Py_ssize_t char_size; Py_ssize_t struct_size; Py_ssize_t new_size; - int share_wstr; PyObject *new_unicode; #ifdef Py_DEBUG Py_ssize_t old_length = _PyUnicode_LENGTH(unicode); #endif assert(unicode_modifiable(unicode)); - assert(PyUnicode_IS_READY(unicode)); assert(PyUnicode_IS_COMPACT(unicode)); char_size = PyUnicode_KIND(unicode); @@ -1037,7 +958,6 @@ resize_compact(PyObject *unicode, Py_ssize_t length) struct_size = sizeof(PyASCIIObject); else struct_size = sizeof(PyCompactUnicodeObject); - share_wstr = _PyUnicode_SHARE_WSTR(unicode); if (length > ((PY_SSIZE_T_MAX - struct_size) / char_size - 1)) { PyErr_NoMemory(); @@ -1050,34 +970,20 @@ resize_compact(PyObject *unicode, Py_ssize_t length) _PyUnicode_UTF8(unicode) = NULL; _PyUnicode_UTF8_LENGTH(unicode) = 0; } -#ifdef Py_REF_DEBUG - _Py_RefTotal--; -#endif #ifdef Py_TRACE_REFS _Py_ForgetReference(unicode); #endif new_unicode = (PyObject *)PyObject_Realloc(unicode, new_size); if (new_unicode == NULL) { - _Py_NewReference(unicode); + _Py_NewReferenceNoTotal(unicode); PyErr_NoMemory(); return NULL; } unicode = new_unicode; - _Py_NewReference(unicode); + _Py_NewReferenceNoTotal(unicode); _PyUnicode_LENGTH(unicode) = length; - if (share_wstr) { - _PyUnicode_WSTR(unicode) = PyUnicode_DATA(unicode); - if (!PyUnicode_IS_ASCII(unicode)) - _PyUnicode_WSTR_LENGTH(unicode) = length; - } - else if (_PyUnicode_HAS_WSTR_MEMORY(unicode)) { - PyObject_Free(_PyUnicode_WSTR(unicode)); - _PyUnicode_WSTR(unicode) = NULL; - if (!PyUnicode_IS_ASCII(unicode)) - _PyUnicode_WSTR_LENGTH(unicode) = 0; - } #ifdef Py_DEBUG unicode_fill_invalid(unicode, old_length); #endif @@ -1090,78 +996,55 @@ resize_compact(PyObject *unicode, Py_ssize_t length) static int resize_inplace(PyObject *unicode, Py_ssize_t length) { - wchar_t *wstr; - Py_ssize_t new_size; assert(!PyUnicode_IS_COMPACT(unicode)); assert(Py_REFCNT(unicode) == 1); - if (PyUnicode_IS_READY(unicode)) { - Py_ssize_t char_size; - int share_wstr, share_utf8; - void *data; + Py_ssize_t new_size; + Py_ssize_t char_size; + int share_utf8; + void *data; #ifdef Py_DEBUG - Py_ssize_t old_length = _PyUnicode_LENGTH(unicode); + Py_ssize_t old_length = _PyUnicode_LENGTH(unicode); #endif - data = _PyUnicode_DATA_ANY(unicode); - char_size = PyUnicode_KIND(unicode); - share_wstr = _PyUnicode_SHARE_WSTR(unicode); - share_utf8 = _PyUnicode_SHARE_UTF8(unicode); + data = _PyUnicode_DATA_ANY(unicode); + char_size = PyUnicode_KIND(unicode); + share_utf8 = _PyUnicode_SHARE_UTF8(unicode); - if (length > (PY_SSIZE_T_MAX / char_size - 1)) { - PyErr_NoMemory(); - return -1; - } - new_size = (length + 1) * char_size; + if (length > (PY_SSIZE_T_MAX / char_size - 1)) { + PyErr_NoMemory(); + return -1; + } + new_size = (length + 1) * char_size; - if (!share_utf8 && _PyUnicode_HAS_UTF8_MEMORY(unicode)) - { - PyObject_Free(_PyUnicode_UTF8(unicode)); - _PyUnicode_UTF8(unicode) = NULL; - _PyUnicode_UTF8_LENGTH(unicode) = 0; - } + if (!share_utf8 && _PyUnicode_HAS_UTF8_MEMORY(unicode)) + { + PyObject_Free(_PyUnicode_UTF8(unicode)); + _PyUnicode_UTF8(unicode) = NULL; + _PyUnicode_UTF8_LENGTH(unicode) = 0; + } - data = (PyObject *)PyObject_Realloc(data, new_size); - if (data == NULL) { - PyErr_NoMemory(); - return -1; - } - _PyUnicode_DATA_ANY(unicode) = data; - if (share_wstr) { - _PyUnicode_WSTR(unicode) = data; - _PyUnicode_WSTR_LENGTH(unicode) = length; - } - if (share_utf8) { - _PyUnicode_UTF8(unicode) = data; - _PyUnicode_UTF8_LENGTH(unicode) = length; - } - _PyUnicode_LENGTH(unicode) = length; - PyUnicode_WRITE(PyUnicode_KIND(unicode), data, length, 0); + data = (PyObject *)PyObject_Realloc(data, new_size); + if (data == NULL) { + PyErr_NoMemory(); + return -1; + } + _PyUnicode_DATA_ANY(unicode) = data; + if (share_utf8) { + _PyUnicode_UTF8(unicode) = data; + _PyUnicode_UTF8_LENGTH(unicode) = length; + } + _PyUnicode_LENGTH(unicode) = length; + PyUnicode_WRITE(PyUnicode_KIND(unicode), data, length, 0); #ifdef Py_DEBUG - unicode_fill_invalid(unicode, old_length); + unicode_fill_invalid(unicode, old_length); #endif - if (share_wstr || _PyUnicode_WSTR(unicode) == NULL) { - assert(_PyUnicode_CheckConsistency(unicode, 0)); - return 0; - } - } - assert(_PyUnicode_WSTR(unicode) != NULL); /* check for integer overflow */ if (length > PY_SSIZE_T_MAX / (Py_ssize_t)sizeof(wchar_t) - 1) { PyErr_NoMemory(); return -1; } - new_size = sizeof(wchar_t) * (length + 1); - wstr = _PyUnicode_WSTR(unicode); - wstr = PyObject_Realloc(wstr, new_size); - if (!wstr) { - PyErr_NoMemory(); - return -1; - } - _PyUnicode_WSTR(unicode) = wstr; - _PyUnicode_WSTR(unicode)[length] = 0; - _PyUnicode_WSTR_LENGTH(unicode) = length; assert(_PyUnicode_CheckConsistency(unicode, 0)); return 0; } @@ -1170,99 +1053,15 @@ static PyObject* resize_copy(PyObject *unicode, Py_ssize_t length) { Py_ssize_t copy_length; - if (_PyUnicode_KIND(unicode) != PyUnicode_WCHAR_KIND) { - PyObject *copy; - - assert(PyUnicode_IS_READY(unicode)); - - copy = PyUnicode_New(length, PyUnicode_MAX_CHAR_VALUE(unicode)); - if (copy == NULL) - return NULL; - - copy_length = Py_MIN(length, PyUnicode_GET_LENGTH(unicode)); - _PyUnicode_FastCopyCharacters(copy, 0, unicode, 0, copy_length); - return copy; - } - else { - PyObject *w; - - w = (PyObject*)_PyUnicode_New(length); - if (w == NULL) - return NULL; - copy_length = _PyUnicode_WSTR_LENGTH(unicode); - copy_length = Py_MIN(copy_length, length); - memcpy(_PyUnicode_WSTR(w), _PyUnicode_WSTR(unicode), - copy_length * sizeof(wchar_t)); - return w; - } -} - -/* We allocate one more byte to make sure the string is - Ux0000 terminated; some code (e.g. new_identifier) - relies on that. - - XXX This allocator could further be enhanced by assuring that the - free list never reduces its size below 1. - -*/ - -static PyUnicodeObject * -_PyUnicode_New(Py_ssize_t length) -{ - PyUnicodeObject *unicode; - size_t new_size; - - /* Optimization for empty strings */ - if (length == 0) { - return (PyUnicodeObject *)unicode_new_empty(); - } - - /* Ensure we won't overflow the size. */ - if (length > ((PY_SSIZE_T_MAX / (Py_ssize_t)sizeof(Py_UNICODE)) - 1)) { - return (PyUnicodeObject *)PyErr_NoMemory(); - } - if (length < 0) { - PyErr_SetString(PyExc_SystemError, - "Negative size passed to _PyUnicode_New"); - return NULL; - } - - unicode = PyObject_New(PyUnicodeObject, &PyUnicode_Type); - if (unicode == NULL) - return NULL; - new_size = sizeof(Py_UNICODE) * ((size_t)length + 1); + PyObject *copy; - _PyUnicode_WSTR_LENGTH(unicode) = length; - _PyUnicode_HASH(unicode) = -1; - _PyUnicode_STATE(unicode).interned = 0; - _PyUnicode_STATE(unicode).kind = 0; - _PyUnicode_STATE(unicode).compact = 0; - _PyUnicode_STATE(unicode).ready = 0; - _PyUnicode_STATE(unicode).ascii = 0; - _PyUnicode_DATA_ANY(unicode) = NULL; - _PyUnicode_LENGTH(unicode) = 0; - _PyUnicode_UTF8(unicode) = NULL; - _PyUnicode_UTF8_LENGTH(unicode) = 0; - - _PyUnicode_WSTR(unicode) = (Py_UNICODE*) PyObject_Malloc(new_size); - if (!_PyUnicode_WSTR(unicode)) { - Py_DECREF(unicode); - PyErr_NoMemory(); + copy = PyUnicode_New(length, PyUnicode_MAX_CHAR_VALUE(unicode)); + if (copy == NULL) return NULL; - } - /* Initialize the first element to guard against cases where - * the caller fails before initializing str -- unicode_resize() - * reads str[0], and the Keep-Alive optimization can keep memory - * allocated for str alive across a call to unicode_dealloc(unicode). - * We don't want unicode_resize to read uninitialized memory in - * that case. - */ - _PyUnicode_WSTR(unicode)[0] = 0; - _PyUnicode_WSTR(unicode)[length] = 0; - - assert(_PyUnicode_CheckConsistency((PyObject *)unicode, 0)); - return unicode; + copy_length = Py_MIN(length, PyUnicode_GET_LENGTH(unicode)); + _PyUnicode_FastCopyCharacters(copy, 0, unicode, 0, copy_length); + return copy; } static const char* @@ -1272,8 +1071,6 @@ unicode_kind_name(PyObject *unicode) _PyUnicode_Dump() */ if (!PyUnicode_IS_COMPACT(unicode)) { - if (!PyUnicode_IS_READY(unicode)) - return "wstr"; switch (PyUnicode_KIND(unicode)) { case PyUnicode_1BYTE_KIND: @@ -1289,7 +1086,6 @@ unicode_kind_name(PyObject *unicode) return "<legacy invalid kind>"; } } - assert(PyUnicode_IS_READY(unicode)); switch (PyUnicode_KIND(unicode)) { case PyUnicode_1BYTE_KIND: if (PyUnicode_IS_ASCII(unicode)) @@ -1346,15 +1142,7 @@ _PyUnicode_Dump(PyObject *op) data = unicode->data.any; printf("%s: len=%zu, ", unicode_kind_name(op), ascii->length); - if (ascii->wstr == data) - printf("shared "); - printf("wstr=%p", (void *)ascii->wstr); - - if (!(ascii->state.ascii == 1 && ascii->state.compact == 1)) { - printf(" (%zu), ", compact->wstr_length); - if (!ascii->state.compact && compact->utf8 == unicode->data.any) { - printf("shared "); - } + if (!ascii->state.ascii) { printf("utf8=%p (%zu)", (void *)compact->utf8, compact->utf8_length); } printf(", data=%p\n", data); @@ -1373,13 +1161,12 @@ PyUnicode_New(Py_ssize_t size, Py_UCS4 maxchar) PyObject *obj; PyCompactUnicodeObject *unicode; void *data; - enum PyUnicode_Kind kind; - int is_sharing, is_ascii; + int kind; + int is_ascii; Py_ssize_t char_size; Py_ssize_t struct_size; is_ascii = 0; - is_sharing = 0; struct_size = sizeof(PyCompactUnicodeObject); if (maxchar < 128) { kind = PyUnicode_1BYTE_KIND; @@ -1394,8 +1181,6 @@ PyUnicode_New(Py_ssize_t size, Py_UCS4 maxchar) else if (maxchar < 65536) { kind = PyUnicode_2BYTE_KIND; char_size = 2; - if (sizeof(wchar_t) == 2) - is_sharing = 1; } else { if (maxchar > MAX_UNICODE) { @@ -1405,8 +1190,6 @@ PyUnicode_New(Py_ssize_t size, Py_UCS4 maxchar) } kind = PyUnicode_4BYTE_KIND; char_size = 4; - if (sizeof(wchar_t) == 4) - is_sharing = 1; } /* Ensure we won't overflow the size. */ @@ -1438,16 +1221,12 @@ PyUnicode_New(Py_ssize_t size, Py_UCS4 maxchar) _PyUnicode_STATE(unicode).interned = 0; _PyUnicode_STATE(unicode).kind = kind; _PyUnicode_STATE(unicode).compact = 1; - _PyUnicode_STATE(unicode).ready = 1; _PyUnicode_STATE(unicode).ascii = is_ascii; if (is_ascii) { ((char*)data)[size] = 0; - _PyUnicode_WSTR(unicode) = NULL; } else if (kind == PyUnicode_1BYTE_KIND) { ((char*)data)[size] = 0; - _PyUnicode_WSTR(unicode) = NULL; - _PyUnicode_WSTR_LENGTH(unicode) = 0; unicode->utf8 = NULL; unicode->utf8_length = 0; } @@ -1458,14 +1237,6 @@ PyUnicode_New(Py_ssize_t size, Py_UCS4 maxchar) ((Py_UCS2*)data)[size] = 0; else /* kind == PyUnicode_4BYTE_KIND */ ((Py_UCS4*)data)[size] = 0; - if (is_sharing) { - _PyUnicode_WSTR_LENGTH(unicode) = size; - _PyUnicode_WSTR(unicode) = (wchar_t *)data; - } - else { - _PyUnicode_WSTR_LENGTH(unicode) = 0; - _PyUnicode_WSTR(unicode) = NULL; - } } #ifdef Py_DEBUG unicode_fill_invalid((PyObject*)unicode, 0); @@ -1530,7 +1301,7 @@ _copy_characters(PyObject *to, Py_ssize_t to_start, PyObject *from, Py_ssize_t from_start, Py_ssize_t how_many, int check_maxchar) { - unsigned int from_kind, to_kind; + int from_kind, to_kind; const void *from_data; void *to_data; @@ -1538,11 +1309,9 @@ _copy_characters(PyObject *to, Py_ssize_t to_start, assert(0 <= from_start); assert(0 <= to_start); assert(PyUnicode_Check(from)); - assert(PyUnicode_IS_READY(from)); assert(from_start + how_many <= PyUnicode_GET_LENGTH(from)); assert(PyUnicode_Check(to)); - assert(PyUnicode_IS_READY(to)); assert(to_start + how_many <= PyUnicode_GET_LENGTH(to)); if (how_many == 0) @@ -1687,11 +1456,6 @@ PyUnicode_CopyCharacters(PyObject *to, Py_ssize_t to_start, return -1; } - if (PyUnicode_READY(from) == -1) - return -1; - if (PyUnicode_READY(to) == -1) - return -1; - if ((size_t)from_start > (size_t)PyUnicode_GET_LENGTH(from)) { PyErr_SetString(PyExc_IndexError, "string index out of range"); return -1; @@ -1776,135 +1540,6 @@ find_maxchar_surrogates(const wchar_t *begin, const wchar_t *end, return 0; } -int -_PyUnicode_Ready(PyObject *unicode) -{ - wchar_t *end; - Py_UCS4 maxchar = 0; - Py_ssize_t num_surrogates; -#if SIZEOF_WCHAR_T == 2 - Py_ssize_t length_wo_surrogates; -#endif - - /* _PyUnicode_Ready() is only intended for old-style API usage where - strings were created using _PyObject_New() and where no canonical - representation (the str field) has been set yet aka strings - which are not yet ready. */ - assert(_PyUnicode_CHECK(unicode)); - assert(_PyUnicode_KIND(unicode) == PyUnicode_WCHAR_KIND); - assert(_PyUnicode_WSTR(unicode) != NULL); - assert(_PyUnicode_DATA_ANY(unicode) == NULL); - assert(_PyUnicode_UTF8(unicode) == NULL); - /* Actually, it should neither be interned nor be anything else: */ - assert(_PyUnicode_STATE(unicode).interned == SSTATE_NOT_INTERNED); - - end = _PyUnicode_WSTR(unicode) + _PyUnicode_WSTR_LENGTH(unicode); - if (find_maxchar_surrogates(_PyUnicode_WSTR(unicode), end, - &maxchar, &num_surrogates) == -1) - return -1; - - if (maxchar < 256) { - _PyUnicode_DATA_ANY(unicode) = PyObject_Malloc(_PyUnicode_WSTR_LENGTH(unicode) + 1); - if (!_PyUnicode_DATA_ANY(unicode)) { - PyErr_NoMemory(); - return -1; - } - _PyUnicode_CONVERT_BYTES(wchar_t, unsigned char, - _PyUnicode_WSTR(unicode), end, - PyUnicode_1BYTE_DATA(unicode)); - PyUnicode_1BYTE_DATA(unicode)[_PyUnicode_WSTR_LENGTH(unicode)] = '\0'; - _PyUnicode_LENGTH(unicode) = _PyUnicode_WSTR_LENGTH(unicode); - _PyUnicode_STATE(unicode).kind = PyUnicode_1BYTE_KIND; - if (maxchar < 128) { - _PyUnicode_STATE(unicode).ascii = 1; - _PyUnicode_UTF8(unicode) = _PyUnicode_DATA_ANY(unicode); - _PyUnicode_UTF8_LENGTH(unicode) = _PyUnicode_WSTR_LENGTH(unicode); - } - else { - _PyUnicode_STATE(unicode).ascii = 0; - _PyUnicode_UTF8(unicode) = NULL; - _PyUnicode_UTF8_LENGTH(unicode) = 0; - } - PyObject_Free(_PyUnicode_WSTR(unicode)); - _PyUnicode_WSTR(unicode) = NULL; - _PyUnicode_WSTR_LENGTH(unicode) = 0; - } - /* In this case we might have to convert down from 4-byte native - wchar_t to 2-byte unicode. */ - else if (maxchar < 65536) { - assert(num_surrogates == 0 && - "FindMaxCharAndNumSurrogatePairs() messed up"); - -#if SIZEOF_WCHAR_T == 2 - /* We can share representations and are done. */ - _PyUnicode_DATA_ANY(unicode) = _PyUnicode_WSTR(unicode); - PyUnicode_2BYTE_DATA(unicode)[_PyUnicode_WSTR_LENGTH(unicode)] = '\0'; - _PyUnicode_LENGTH(unicode) = _PyUnicode_WSTR_LENGTH(unicode); - _PyUnicode_STATE(unicode).kind = PyUnicode_2BYTE_KIND; - _PyUnicode_UTF8(unicode) = NULL; - _PyUnicode_UTF8_LENGTH(unicode) = 0; -#else - /* sizeof(wchar_t) == 4 */ - _PyUnicode_DATA_ANY(unicode) = PyObject_Malloc( - 2 * (_PyUnicode_WSTR_LENGTH(unicode) + 1)); - if (!_PyUnicode_DATA_ANY(unicode)) { - PyErr_NoMemory(); - return -1; - } - _PyUnicode_CONVERT_BYTES(wchar_t, Py_UCS2, - _PyUnicode_WSTR(unicode), end, - PyUnicode_2BYTE_DATA(unicode)); - PyUnicode_2BYTE_DATA(unicode)[_PyUnicode_WSTR_LENGTH(unicode)] = '\0'; - _PyUnicode_LENGTH(unicode) = _PyUnicode_WSTR_LENGTH(unicode); - _PyUnicode_STATE(unicode).kind = PyUnicode_2BYTE_KIND; - _PyUnicode_UTF8(unicode) = NULL; - _PyUnicode_UTF8_LENGTH(unicode) = 0; - PyObject_Free(_PyUnicode_WSTR(unicode)); - _PyUnicode_WSTR(unicode) = NULL; - _PyUnicode_WSTR_LENGTH(unicode) = 0; -#endif - } - /* maxchar exceeds 16 bit, wee need 4 bytes for unicode characters */ - else { -#if SIZEOF_WCHAR_T == 2 - /* in case the native representation is 2-bytes, we need to allocate a - new normalized 4-byte version. */ - length_wo_surrogates = _PyUnicode_WSTR_LENGTH(unicode) - num_surrogates; - if (length_wo_surrogates > PY_SSIZE_T_MAX / 4 - 1) { - PyErr_NoMemory(); - return -1; - } - _PyUnicode_DATA_ANY(unicode) = PyObject_Malloc(4 * (length_wo_surrogates + 1)); - if (!_PyUnicode_DATA_ANY(unicode)) { - PyErr_NoMemory(); - return -1; - } - _PyUnicode_LENGTH(unicode) = length_wo_surrogates; - _PyUnicode_STATE(unicode).kind = PyUnicode_4BYTE_KIND; - _PyUnicode_UTF8(unicode) = NULL; - _PyUnicode_UTF8_LENGTH(unicode) = 0; - /* unicode_convert_wchar_to_ucs4() requires a ready string */ - _PyUnicode_STATE(unicode).ready = 1; - unicode_convert_wchar_to_ucs4(_PyUnicode_WSTR(unicode), end, unicode); - PyObject_Free(_PyUnicode_WSTR(unicode)); - _PyUnicode_WSTR(unicode) = NULL; - _PyUnicode_WSTR_LENGTH(unicode) = 0; -#else - assert(num_surrogates == 0); - - _PyUnicode_DATA_ANY(unicode) = _PyUnicode_WSTR(unicode); - _PyUnicode_LENGTH(unicode) = _PyUnicode_WSTR_LENGTH(unicode); - _PyUnicode_UTF8(unicode) = NULL; - _PyUnicode_UTF8_LENGTH(unicode) = 0; - _PyUnicode_STATE(unicode).kind = PyUnicode_4BYTE_KIND; -#endif - PyUnicode_4BYTE_DATA(unicode)[_PyUnicode_LENGTH(unicode)] = '\0'; - } - _PyUnicode_STATE(unicode).ready = 1; - assert(_PyUnicode_CheckConsistency(unicode, 1)); - return 0; -} - static void unicode_dealloc(PyObject *unicode) { @@ -1913,38 +1548,13 @@ unicode_dealloc(PyObject *unicode) _Py_FatalRefcountError("deallocating an Unicode singleton"); } #endif - - switch (PyUnicode_CHECK_INTERNED(unicode)) { - case SSTATE_NOT_INTERNED: - break; - case SSTATE_INTERNED_MORTAL: - { - /* Revive the dead object temporarily. PyDict_DelItem() removes two - references (key and value) which were ignored by - PyUnicode_InternInPlace(). Use refcnt=3 rather than refcnt=2 - to prevent calling unicode_dealloc() again. Adjust refcnt after - PyDict_DelItem(). */ - assert(Py_REFCNT(unicode) == 0); - Py_SET_REFCNT(unicode, 3); - if (PyDict_DelItem(interned, unicode) != 0) { - _PyErr_WriteUnraisableMsg("deletion of interned string failed", - NULL); - } - assert(Py_REFCNT(unicode) == 1); - Py_SET_REFCNT(unicode, 0); - break; - } - - case SSTATE_INTERNED_IMMORTAL: - _PyObject_ASSERT_FAILED_MSG(unicode, "Immortal interned string died"); - break; - - default: - Py_UNREACHABLE(); - } - - if (_PyUnicode_HAS_WSTR_MEMORY(unicode)) { - PyObject_Free(_PyUnicode_WSTR(unicode)); + /* This should never get called, but we also don't want to SEGV if + * we accidentally decref an immortal string out of existence. Since + * the string is an immortal object, just re-set the reference count. + */ + if (PyUnicode_CHECK_INTERNED(unicode)) { + _Py_SetImmortal(unicode); + return; } if (_PyUnicode_HAS_UTF8_MEMORY(unicode)) { PyObject_Free(_PyUnicode_UTF8(unicode)); @@ -1965,7 +1575,7 @@ unicode_is_singleton(PyObject *unicode) } PyASCIIObject *ascii = _PyASCIIObject_CAST(unicode); - if (ascii->state.kind != PyUnicode_WCHAR_KIND && ascii->length == 1) { + if (ascii->length == 1) { Py_UCS4 ch = PyUnicode_READ_CHAR(unicode, 0); if (ch < 256 && LATIN1(ch) == unicode) { return 1; @@ -2007,10 +1617,7 @@ unicode_resize(PyObject **p_unicode, Py_ssize_t length) assert(PyUnicode_Check(unicode)); assert(0 <= length); - if (_PyUnicode_KIND(unicode) == PyUnicode_WCHAR_KIND) - old_length = PyUnicode_WSTR_LENGTH(unicode); - else - old_length = PyUnicode_GET_LENGTH(unicode); + old_length = PyUnicode_GET_LENGTH(unicode); if (old_length == length) return 0; @@ -2064,7 +1671,7 @@ static void unicode_write_cstr(PyObject *unicode, Py_ssize_t index, const char *str, Py_ssize_t len) { - enum PyUnicode_Kind kind = PyUnicode_KIND(unicode); + int kind = PyUnicode_KIND(unicode); const void *data = PyUnicode_DATA(unicode); const char *end = str + len; @@ -2139,28 +1746,6 @@ unicode_char(Py_UCS4 ch) return unicode; } -PyObject * -PyUnicode_FromUnicode(const Py_UNICODE *u, Py_ssize_t size) -{ - if (u == NULL) { - if (size > 0) { - if (PyErr_WarnEx(PyExc_DeprecationWarning, - "PyUnicode_FromUnicode(NULL, size) is deprecated; " - "use PyUnicode_New() instead", 1) < 0) { - return NULL; - } - } - return (PyObject*)_PyUnicode_New(size); - } - - if (size < 0) { - PyErr_BadInternalCall(); - return NULL; - } - - return PyUnicode_FromWideChar(u, size); -} - PyObject * PyUnicode_FromWideChar(const wchar_t *u, Py_ssize_t size) { @@ -2254,16 +1839,12 @@ PyUnicode_FromStringAndSize(const char *u, Py_ssize_t size) if (u != NULL) { return PyUnicode_DecodeUTF8Stateful(u, size, NULL, NULL); } - else { - if (size > 0) { - if (PyErr_WarnEx(PyExc_DeprecationWarning, - "PyUnicode_FromStringAndSize(NULL, size) is deprecated; " - "use PyUnicode_New() instead", 1) < 0) { - return NULL; - } - } - return (PyObject *)_PyUnicode_New(size); + if (size > 0) { + PyErr_SetString(PyExc_SystemError, + "NULL string with positive size with NULL passed to PyUnicode_FromStringAndSize"); + return NULL; } + return unicode_new_empty(); } PyObject * @@ -2286,7 +1867,7 @@ _PyUnicode_FromId(_Py_Identifier *id) Py_ssize_t index = _Py_atomic_size_get(&id->index); if (index < 0) { - struct _Py_unicode_runtime_ids *rt_ids = &interp->runtime->unicode_ids; + struct _Py_unicode_runtime_ids *rt_ids = &interp->runtime->unicode_state.ids; PyThread_acquire_lock(rt_ids->lock, WAIT_LOCK); // Check again to detect concurrent access. Another thread can have @@ -2377,7 +1958,7 @@ _PyUnicode_FromASCII(const char *buffer, Py_ssize_t size) } static Py_UCS4 -kind_maxchar_limit(unsigned int kind) +kind_maxchar_limit(int kind) { switch (kind) { case PyUnicode_1BYTE_KIND: @@ -2491,10 +2072,9 @@ PyUnicode_FromKindAndData(int kind, const void *buffer, Py_ssize_t size) Py_UCS4 _PyUnicode_FindMaxChar(PyObject *unicode, Py_ssize_t start, Py_ssize_t end) { - enum PyUnicode_Kind kind; + int kind; const void *startptr, *endptr; - assert(PyUnicode_IS_READY(unicode)); assert(0 <= start); assert(end <= PyUnicode_GET_LENGTH(unicode)); assert(start <= end); @@ -2533,11 +2113,10 @@ unicode_adjust_maxchar(PyObject **p_unicode) PyObject *unicode, *copy; Py_UCS4 max_char; Py_ssize_t len; - unsigned int kind; + int kind; assert(p_unicode != NULL); unicode = *p_unicode; - assert(PyUnicode_IS_READY(unicode)); if (PyUnicode_IS_ASCII(unicode)) return; @@ -2581,8 +2160,6 @@ _PyUnicode_Copy(PyObject *unicode) PyErr_BadInternalCall(); return NULL; } - if (PyUnicode_READY(unicode) == -1) - return NULL; length = PyUnicode_GET_LENGTH(unicode); copy = PyUnicode_New(length, PyUnicode_MAX_CHAR_VALUE(unicode)); @@ -2601,7 +2178,7 @@ _PyUnicode_Copy(PyObject *unicode) character. Return NULL on error. */ static void* -unicode_askind(unsigned int skind, void const *data, Py_ssize_t len, unsigned int kind) +unicode_askind(int skind, void const *data, Py_ssize_t len, int kind) { void *result; @@ -2651,8 +2228,6 @@ as_ucs4(PyObject *string, Py_UCS4 *target, Py_ssize_t targetsize, int kind; const void *data; Py_ssize_t len, targetlen; - if (PyUnicode_READY(string) == -1) - return NULL; kind = PyUnicode_KIND(string); data = PyUnicode_DATA(string); len = PyUnicode_GET_LENGTH(string); @@ -2711,21 +2286,19 @@ PyUnicode_AsUCS4Copy(PyObject *string) return as_ucs4(string, NULL, 0, 1); } -/* maximum number of characters required for output of %lld or %p. - We need at most ceil(log10(256)*SIZEOF_LONG_LONG) digits, - plus 1 for the sign. 53/22 is an upper bound for log10(256). */ -#define MAX_LONG_LONG_CHARS (2 + (SIZEOF_LONG_LONG*53-1) / 22) +/* maximum number of characters required for output of %jo or %jd or %p. + We need at most ceil(log8(256)*sizeof(intmax_t)) digits, + plus 1 for the sign, plus 2 for the 0x prefix (for %p), + plus 1 for the terminal NUL. */ +#define MAX_INTMAX_CHARS (5 + (sizeof(intmax_t)*8-1) / 3) static int unicode_fromformat_write_str(_PyUnicodeWriter *writer, PyObject *str, - Py_ssize_t width, Py_ssize_t precision) + Py_ssize_t width, Py_ssize_t precision, int flags) { Py_ssize_t length, fill, arglen; Py_UCS4 maxchar; - if (PyUnicode_READY(str) == -1) - return -1; - length = PyUnicode_GET_LENGTH(str); if ((precision == -1 || precision >= length) && width <= length) @@ -2743,8 +2316,8 @@ unicode_fromformat_write_str(_PyUnicodeWriter *writer, PyObject *str, if (_PyUnicodeWriter_Prepare(writer, arglen, maxchar) == -1) return -1; - if (width > length) { - fill = width - length; + fill = Py_MAX(width - length, 0); + if (fill && !(flags & F_LJUST)) { if (PyUnicode_Fill(writer->buffer, writer->pos, fill, ' ') == -1) return -1; writer->pos += fill; @@ -2753,12 +2326,19 @@ unicode_fromformat_write_str(_PyUnicodeWriter *writer, PyObject *str, _PyUnicode_FastCopyCharacters(writer->buffer, writer->pos, str, 0, length); writer->pos += length; + + if (fill && (flags & F_LJUST)) { + if (PyUnicode_Fill(writer->buffer, writer->pos, fill, ' ') == -1) + return -1; + writer->pos += fill; + } + return 0; } static int unicode_fromformat_write_cstr(_PyUnicodeWriter *writer, const char *str, - Py_ssize_t width, Py_ssize_t precision) + Py_ssize_t width, Py_ssize_t precision, int flags) { /* UTF-8 */ Py_ssize_t length; @@ -2778,36 +2358,93 @@ unicode_fromformat_write_cstr(_PyUnicodeWriter *writer, const char *str, if (unicode == NULL) return -1; - res = unicode_fromformat_write_str(writer, unicode, width, -1); + res = unicode_fromformat_write_str(writer, unicode, width, -1, flags); + Py_DECREF(unicode); + return res; +} + +static int +unicode_fromformat_write_wcstr(_PyUnicodeWriter *writer, const wchar_t *str, + Py_ssize_t width, Py_ssize_t precision, int flags) +{ + /* UTF-8 */ + Py_ssize_t length; + PyObject *unicode; + int res; + + if (precision == -1) { + length = wcslen(str); + } + else { + length = 0; + while (length < precision && str[length]) { + length++; + } + } + unicode = PyUnicode_FromWideChar(str, length); + if (unicode == NULL) + return -1; + + res = unicode_fromformat_write_str(writer, unicode, width, -1, flags); Py_DECREF(unicode); return res; } +#define F_LONG 1 +#define F_LONGLONG 2 +#define F_SIZE 3 +#define F_PTRDIFF 4 +#define F_INTMAX 5 +static const char * const formats[] = {"%d", "%ld", "%lld", "%zd", "%td", "%jd"}; +static const char * const formats_o[] = {"%o", "%lo", "%llo", "%zo", "%to", "%jo"}; +static const char * const formats_u[] = {"%u", "%lu", "%llu", "%zu", "%tu", "%ju"}; +static const char * const formats_x[] = {"%x", "%lx", "%llx", "%zx", "%tx", "%jx"}; +static const char * const formats_X[] = {"%X", "%lX", "%llX", "%zX", "%tX", "%jX"}; + static const char* unicode_fromformat_arg(_PyUnicodeWriter *writer, const char *f, va_list *vargs) { const char *p; Py_ssize_t len; - int zeropad; + int flags = 0; Py_ssize_t width; Py_ssize_t precision; - int longflag; - int longlongflag; - int size_tflag; - Py_ssize_t fill; p = f; f++; - zeropad = 0; - if (*f == '0') { - zeropad = 1; + if (*f == '%') { + if (_PyUnicodeWriter_WriteCharInline(writer, '%') < 0) + return NULL; f++; + return f; + } + + /* Parse flags. Example: "%-i" => flags=F_LJUST. */ + /* Flags '+', ' ' and '#' are not particularly useful. + * They are not worth the implementation and maintenance costs. + * In addition, '#' should add "0" for "o" conversions for compatibility + * with printf, but it would confuse Python users. */ + while (1) { + switch (*f++) { + case '-': flags |= F_LJUST; continue; + case '0': flags |= F_ZERO; continue; + } + f--; + break; } /* parse the width.precision part, e.g. "%2.5s" => width=2, precision=5 */ width = -1; - if (Py_ISDIGIT((unsigned)*f)) { + if (*f == '*') { + width = va_arg(*vargs, int); + if (width < 0) { + flags |= F_LJUST; + width = -width; + } + f++; + } + else if (Py_ISDIGIT((unsigned)*f)) { width = *f - '0'; f++; while (Py_ISDIGIT((unsigned)*f)) { @@ -2823,7 +2460,14 @@ unicode_fromformat_arg(_PyUnicodeWriter *writer, precision = -1; if (*f == '.') { f++; - if (Py_ISDIGIT((unsigned)*f)) { + if (*f == '*') { + precision = va_arg(*vargs, int); + if (precision < 0) { + precision = -2; + } + f++; + } + else if (Py_ISDIGIT((unsigned)*f)) { precision = (*f - '0'); f++; while (Py_ISDIGIT((unsigned)*f)) { @@ -2836,40 +2480,49 @@ unicode_fromformat_arg(_PyUnicodeWriter *writer, f++; } } - if (*f == '%') { - /* "%.3%s" => f points to "3" */ - f--; - } - } - if (*f == '\0') { - /* bogus format "%.123" => go backward, f points to "3" */ - f--; } - /* Handle %ld, %lu, %lld and %llu. */ - longflag = 0; - longlongflag = 0; - size_tflag = 0; + int sizemod = 0; if (*f == 'l') { - if (f[1] == 'd' || f[1] == 'u' || f[1] == 'i') { - longflag = 1; - ++f; - } - else if (f[1] == 'l' && - (f[2] == 'd' || f[2] == 'u' || f[2] == 'i')) { - longlongflag = 1; + if (f[1] == 'l') { + sizemod = F_LONGLONG; f += 2; } + else { + sizemod = F_LONG; + ++f; + } } - /* handle the size_t flag. */ - else if (*f == 'z' && (f[1] == 'd' || f[1] == 'u' || f[1] == 'i')) { - size_tflag = 1; + else if (*f == 'z') { + sizemod = F_SIZE; ++f; } - - if (f[1] == '\0') + else if (*f == 't') { + sizemod = F_PTRDIFF; + ++f; + } + else if (*f == 'j') { + sizemod = F_INTMAX; + ++f; + } + if (f[0] != '\0' && f[1] == '\0') writer->overallocate = 0; + switch (*f) { + case 'd': case 'i': case 'o': case 'u': case 'x': case 'X': + break; + case 'c': case 'p': + if (sizemod || width >= 0 || precision >= 0) goto invalid_format; + break; + case 's': + case 'V': + if (sizemod && sizemod != F_LONG) goto invalid_format; + break; + default: + if (sizemod) goto invalid_format; + break; + } + switch (*f) { case 'c': { @@ -2884,78 +2537,98 @@ unicode_fromformat_arg(_PyUnicodeWriter *writer, break; } - case 'i': - case 'd': - case 'u': - case 'x': + case 'd': case 'i': + case 'o': case 'u': case 'x': case 'X': { /* used by sprintf */ - char buffer[MAX_LONG_LONG_CHARS]; - Py_ssize_t arglen; - - if (*f == 'u') { - if (longflag) { - len = sprintf(buffer, "%lu", va_arg(*vargs, unsigned long)); - } - else if (longlongflag) { - len = sprintf(buffer, "%llu", va_arg(*vargs, unsigned long long)); - } - else if (size_tflag) { - len = sprintf(buffer, "%zu", va_arg(*vargs, size_t)); - } - else { - len = sprintf(buffer, "%u", va_arg(*vargs, unsigned int)); - } - } - else if (*f == 'x') { - len = sprintf(buffer, "%x", va_arg(*vargs, int)); - } - else { - if (longflag) { - len = sprintf(buffer, "%li", va_arg(*vargs, long)); - } - else if (longlongflag) { - len = sprintf(buffer, "%lli", va_arg(*vargs, long long)); - } - else if (size_tflag) { - len = sprintf(buffer, "%zi", va_arg(*vargs, Py_ssize_t)); - } - else { - len = sprintf(buffer, "%i", va_arg(*vargs, int)); - } + char buffer[MAX_INTMAX_CHARS]; + const char *fmt = NULL; + switch (*f) { + case 'o': fmt = formats_o[sizemod]; break; + case 'u': fmt = formats_u[sizemod]; break; + case 'x': fmt = formats_x[sizemod]; break; + case 'X': fmt = formats_X[sizemod]; break; + default: fmt = formats[sizemod]; break; + } + int issigned = (*f == 'd' || *f == 'i'); + switch (sizemod) { + case F_LONG: + len = issigned ? + sprintf(buffer, fmt, va_arg(*vargs, long)) : + sprintf(buffer, fmt, va_arg(*vargs, unsigned long)); + break; + case F_LONGLONG: + len = issigned ? + sprintf(buffer, fmt, va_arg(*vargs, long long)) : + sprintf(buffer, fmt, va_arg(*vargs, unsigned long long)); + break; + case F_SIZE: + len = issigned ? + sprintf(buffer, fmt, va_arg(*vargs, Py_ssize_t)) : + sprintf(buffer, fmt, va_arg(*vargs, size_t)); + break; + case F_PTRDIFF: + len = sprintf(buffer, fmt, va_arg(*vargs, ptrdiff_t)); + break; + case F_INTMAX: + len = issigned ? + sprintf(buffer, fmt, va_arg(*vargs, intmax_t)) : + sprintf(buffer, fmt, va_arg(*vargs, uintmax_t)); + break; + default: + len = issigned ? + sprintf(buffer, fmt, va_arg(*vargs, int)) : + sprintf(buffer, fmt, va_arg(*vargs, unsigned int)); + break; } assert(len >= 0); - if (precision < len) - precision = len; + int sign = (buffer[0] == '-'); + len -= sign; + + precision = Py_MAX(precision, len); + width = Py_MAX(width, precision + sign); + if ((flags & F_ZERO) && !(flags & F_LJUST)) { + precision = width - sign; + } + + Py_ssize_t spacepad = Py_MAX(width - precision - sign, 0); + Py_ssize_t zeropad = Py_MAX(precision - len, 0); - arglen = Py_MAX(precision, width); - if (_PyUnicodeWriter_Prepare(writer, arglen, 127) == -1) + if (_PyUnicodeWriter_Prepare(writer, width, 127) == -1) return NULL; - if (width > precision) { - Py_UCS4 fillchar; - fill = width - precision; - fillchar = zeropad?'0':' '; - if (PyUnicode_Fill(writer->buffer, writer->pos, fill, fillchar) == -1) + if (spacepad && !(flags & F_LJUST)) { + if (PyUnicode_Fill(writer->buffer, writer->pos, spacepad, ' ') == -1) return NULL; - writer->pos += fill; + writer->pos += spacepad; } - if (precision > len) { - fill = precision - len; - if (PyUnicode_Fill(writer->buffer, writer->pos, fill, '0') == -1) + + if (sign) { + if (_PyUnicodeWriter_WriteChar(writer, '-') == -1) + return NULL; + } + + if (zeropad) { + if (PyUnicode_Fill(writer->buffer, writer->pos, zeropad, '0') == -1) return NULL; - writer->pos += fill; + writer->pos += zeropad; } - if (_PyUnicodeWriter_WriteASCIIString(writer, buffer, len) < 0) + if (_PyUnicodeWriter_WriteASCIIString(writer, &buffer[sign], len) < 0) return NULL; + + if (spacepad && (flags & F_LJUST)) { + if (PyUnicode_Fill(writer->buffer, writer->pos, spacepad, ' ') == -1) + return NULL; + writer->pos += spacepad; + } break; } case 'p': { - char number[MAX_LONG_LONG_CHARS]; + char number[MAX_INTMAX_CHARS]; len = sprintf(number, "%p", va_arg(*vargs, void*)); assert(len >= 0); @@ -2978,10 +2651,17 @@ unicode_fromformat_arg(_PyUnicodeWriter *writer, case 's': { - /* UTF-8 */ - const char *s = va_arg(*vargs, const char*); - if (unicode_fromformat_write_cstr(writer, s, width, precision) < 0) - return NULL; + if (sizemod) { + const wchar_t *s = va_arg(*vargs, const wchar_t*); + if (unicode_fromformat_write_wcstr(writer, s, width, precision, flags) < 0) + return NULL; + } + else { + /* UTF-8 */ + const char *s = va_arg(*vargs, const char*); + if (unicode_fromformat_write_cstr(writer, s, width, precision, flags) < 0) + return NULL; + } break; } @@ -2990,7 +2670,7 @@ unicode_fromformat_arg(_PyUnicodeWriter *writer, PyObject *obj = va_arg(*vargs, PyObject *); assert(obj && _PyUnicode_CHECK(obj)); - if (unicode_fromformat_write_str(writer, obj, width, precision) == -1) + if (unicode_fromformat_write_str(writer, obj, width, precision, flags) == -1) return NULL; break; } @@ -2998,15 +2678,27 @@ unicode_fromformat_arg(_PyUnicodeWriter *writer, case 'V': { PyObject *obj = va_arg(*vargs, PyObject *); - const char *str = va_arg(*vargs, const char *); + const char *str; + const wchar_t *wstr; + if (sizemod) { + wstr = va_arg(*vargs, const wchar_t*); + } + else { + str = va_arg(*vargs, const char *); + } if (obj) { assert(_PyUnicode_CHECK(obj)); - if (unicode_fromformat_write_str(writer, obj, width, precision) == -1) + if (unicode_fromformat_write_str(writer, obj, width, precision, flags) == -1) + return NULL; + } + else if (sizemod) { + assert(wstr != NULL); + if (unicode_fromformat_write_wcstr(writer, wstr, width, precision, flags) < 0) return NULL; } else { assert(str != NULL); - if (unicode_fromformat_write_cstr(writer, str, width, precision) < 0) + if (unicode_fromformat_write_cstr(writer, str, width, precision, flags) < 0) return NULL; } break; @@ -3020,7 +2712,7 @@ unicode_fromformat_arg(_PyUnicodeWriter *writer, str = PyObject_Str(obj); if (!str) return NULL; - if (unicode_fromformat_write_str(writer, str, width, precision) == -1) { + if (unicode_fromformat_write_str(writer, str, width, precision, flags) == -1) { Py_DECREF(str); return NULL; } @@ -3036,7 +2728,7 @@ unicode_fromformat_arg(_PyUnicodeWriter *writer, repr = PyObject_Repr(obj); if (!repr) return NULL; - if (unicode_fromformat_write_str(writer, repr, width, precision) == -1) { + if (unicode_fromformat_write_str(writer, repr, width, precision, flags) == -1) { Py_DECREF(repr); return NULL; } @@ -3052,7 +2744,7 @@ unicode_fromformat_arg(_PyUnicodeWriter *writer, ascii = PyObject_ASCII(obj); if (!ascii) return NULL; - if (unicode_fromformat_write_str(writer, ascii, width, precision) == -1) { + if (unicode_fromformat_write_str(writer, ascii, width, precision, flags) == -1) { Py_DECREF(ascii); return NULL; } @@ -3060,21 +2752,10 @@ unicode_fromformat_arg(_PyUnicodeWriter *writer, break; } - case '%': - if (_PyUnicodeWriter_WriteCharInline(writer, '%') < 0) - return NULL; - break; - - default: - /* if we stumble upon an unknown formatting code, copy the rest - of the format string to the output string. (we cannot just - skip the code, since there's no way to know what's in the - argument list) */ - len = strlen(p); - if (_PyUnicodeWriter_WriteLatin1String(writer, p, len) == -1) - return NULL; - f = p+len; - return f; + default: + invalid_format: + PyErr_Format(PyExc_SystemError, "invalid format string: %s", p); + return NULL; } f++; @@ -3144,11 +2825,7 @@ PyUnicode_FromFormat(const char *format, ...) PyObject* ret; va_list vargs; -#ifdef HAVE_STDARG_PROTOTYPES va_start(vargs, format); -#else - va_start(vargs); -#endif ret = PyUnicode_FromFormatV(format, vargs); va_end(vargs); return ret; @@ -3162,13 +2839,6 @@ unicode_get_widechar_size(PyObject *unicode) assert(unicode != NULL); assert(_PyUnicode_CHECK(unicode)); -#if USE_UNICODE_WCHAR_CACHE - if (_PyUnicode_WSTR(unicode) != NULL) { - return PyUnicode_WSTR_LENGTH(unicode); - } -#endif /* USE_UNICODE_WCHAR_CACHE */ - assert(PyUnicode_IS_READY(unicode)); - res = _PyUnicode_LENGTH(unicode); #if SIZEOF_WCHAR_T == 2 if (PyUnicode_KIND(unicode) == PyUnicode_4BYTE_KIND) { @@ -3190,19 +2860,10 @@ unicode_copy_as_widechar(PyObject *unicode, wchar_t *w, Py_ssize_t size) assert(unicode != NULL); assert(_PyUnicode_CHECK(unicode)); -#if USE_UNICODE_WCHAR_CACHE - const wchar_t *wstr = _PyUnicode_WSTR(unicode); - if (wstr != NULL) { - memcpy(w, wstr, size * sizeof(wchar_t)); - return; - } -#else /* USE_UNICODE_WCHAR_CACHE */ if (PyUnicode_KIND(unicode) == sizeof(wchar_t)) { memcpy(w, PyUnicode_DATA(unicode), size * sizeof(wchar_t)); return; } -#endif /* USE_UNICODE_WCHAR_CACHE */ - assert(PyUnicode_IS_READY(unicode)); if (PyUnicode_KIND(unicode) == PyUnicode_1BYTE_KIND) { const Py_UCS1 *s = PyUnicode_1BYTE_DATA(unicode); @@ -3307,7 +2968,7 @@ PyUnicode_AsWideCharString(PyObject *unicode, } buflen = unicode_get_widechar_size(unicode); - buffer = (wchar_t *) PyMem_NEW(wchar_t, (buflen + 1)); + buffer = (wchar_t *) PyMem_New(wchar_t, (buflen + 1)); if (buffer == NULL) { PyErr_NoMemory(); return NULL; @@ -3343,26 +3004,16 @@ _PyUnicode_WideCharString_Converter(PyObject *obj, void *ptr) { wchar_t **p = (wchar_t **)ptr; if (obj == NULL) { -#if !USE_UNICODE_WCHAR_CACHE PyMem_Free(*p); -#endif /* USE_UNICODE_WCHAR_CACHE */ *p = NULL; return 1; } if (PyUnicode_Check(obj)) { -#if USE_UNICODE_WCHAR_CACHE - *p = (wchar_t *)_PyUnicode_AsUnicode(obj); - if (*p == NULL) { - return 0; - } - return 1; -#else /* USE_UNICODE_WCHAR_CACHE */ *p = PyUnicode_AsWideCharString(obj, NULL); if (*p == NULL) { return 0; } return Py_CLEANUP_SUPPORTED; -#endif /* USE_UNICODE_WCHAR_CACHE */ } PyErr_Format(PyExc_TypeError, "argument must be str, not %.50s", @@ -3375,9 +3026,7 @@ _PyUnicode_WideCharString_Opt_Converter(PyObject *obj, void *ptr) { wchar_t **p = (wchar_t **)ptr; if (obj == NULL) { -#if !USE_UNICODE_WCHAR_CACHE PyMem_Free(*p); -#endif /* USE_UNICODE_WCHAR_CACHE */ *p = NULL; return 1; } @@ -3386,19 +3035,11 @@ _PyUnicode_WideCharString_Opt_Converter(PyObject *obj, void *ptr) return 1; } if (PyUnicode_Check(obj)) { -#if USE_UNICODE_WCHAR_CACHE - *p = (wchar_t *)_PyUnicode_AsUnicode(obj); - if (*p == NULL) { - return 0; - } - return 1; -#else /* USE_UNICODE_WCHAR_CACHE */ *p = PyUnicode_AsWideCharString(obj, NULL); if (*p == NULL) { return 0; } return Py_CLEANUP_SUPPORTED; -#endif /* USE_UNICODE_WCHAR_CACHE */ } PyErr_Format(PyExc_TypeError, "argument must be str or None, not %.50s", @@ -3424,10 +3065,7 @@ PyUnicode_FromObject(PyObject *obj) /* XXX Perhaps we should make this API an alias of PyObject_Str() instead ?! */ if (PyUnicode_CheckExact(obj)) { - if (PyUnicode_READY(obj) == -1) - return NULL; - Py_INCREF(obj); - return obj; + return Py_NewRef(obj); } if (PyUnicode_Check(obj)) { /* For a Unicode subtype that's not a Unicode object, @@ -4098,48 +3736,25 @@ PyUnicode_FSConverter(PyObject* arg, void* addr) int PyUnicode_FSDecoder(PyObject* arg, void* addr) { - int is_buffer = 0; - PyObject *path = NULL; - PyObject *output = NULL; if (arg == NULL) { Py_DECREF(*(PyObject**)addr); *(PyObject**)addr = NULL; return 1; } - is_buffer = PyObject_CheckBuffer(arg); - if (!is_buffer) { - path = PyOS_FSPath(arg); - if (path == NULL) { - return 0; - } - } - else { - path = arg; - Py_INCREF(arg); + PyObject *path = PyOS_FSPath(arg); + if (path == NULL) { + return 0; } + PyObject *output = NULL; if (PyUnicode_Check(path)) { output = path; } - else if (PyBytes_Check(path) || is_buffer) { - PyObject *path_bytes = NULL; - - if (!PyBytes_Check(path) && - PyErr_WarnFormat(PyExc_DeprecationWarning, 1, - "path should be string, bytes, or os.PathLike, not %.200s", - Py_TYPE(arg)->tp_name)) { - Py_DECREF(path); - return 0; - } - path_bytes = PyBytes_FromObject(path); + else if (PyBytes_Check(path)) { + output = PyUnicode_DecodeFSDefaultAndSize(PyBytes_AS_STRING(path), + PyBytes_GET_SIZE(path)); Py_DECREF(path); - if (!path_bytes) { - return 0; - } - output = PyUnicode_DecodeFSDefaultAndSize(PyBytes_AS_STRING(path_bytes), - PyBytes_GET_SIZE(path_bytes)); - Py_DECREF(path_bytes); if (!output) { return 0; } @@ -4151,10 +3766,7 @@ PyUnicode_FSDecoder(PyObject* arg, void* addr) Py_DECREF(path); return 0; } - if (PyUnicode_READY(output) == -1) { - Py_DECREF(output); - return 0; - } + if (findchar(PyUnicode_DATA(output), PyUnicode_KIND(output), PyUnicode_GET_LENGTH(output), 0, 1) >= 0) { PyErr_SetString(PyExc_ValueError, "embedded null character"); @@ -4175,8 +3787,6 @@ PyUnicode_AsUTF8AndSize(PyObject *unicode, Py_ssize_t *psize) PyErr_BadArgument(); return NULL; } - if (PyUnicode_READY(unicode) == -1) - return NULL; if (PyUnicode_UTF8(unicode) == NULL) { if (unicode_fill_utf8(unicode) == -1) { @@ -4195,85 +3805,22 @@ PyUnicode_AsUTF8(PyObject *unicode) return PyUnicode_AsUTF8AndSize(unicode, NULL); } -Py_UNICODE * -PyUnicode_AsUnicodeAndSize(PyObject *unicode, Py_ssize_t *size) -{ - if (!PyUnicode_Check(unicode)) { - PyErr_BadArgument(); - return NULL; - } - Py_UNICODE *w = _PyUnicode_WSTR(unicode); - if (w == NULL) { - /* Non-ASCII compact unicode object */ - assert(_PyUnicode_KIND(unicode) != PyUnicode_WCHAR_KIND); - assert(PyUnicode_IS_READY(unicode)); - - Py_ssize_t wlen = unicode_get_widechar_size(unicode); - if ((size_t)wlen > PY_SSIZE_T_MAX / sizeof(wchar_t) - 1) { - PyErr_NoMemory(); - return NULL; - } - w = (wchar_t *) PyObject_Malloc(sizeof(wchar_t) * (wlen + 1)); - if (w == NULL) { - PyErr_NoMemory(); - return NULL; - } - unicode_copy_as_widechar(unicode, w, wlen + 1); - _PyUnicode_WSTR(unicode) = w; - if (!PyUnicode_IS_COMPACT_ASCII(unicode)) { - _PyUnicode_WSTR_LENGTH(unicode) = wlen; - } - } - if (size != NULL) - *size = PyUnicode_WSTR_LENGTH(unicode); - return w; -} - -/* Deprecated APIs */ - -_Py_COMP_DIAG_PUSH -_Py_COMP_DIAG_IGNORE_DEPR_DECLS - -Py_UNICODE * -PyUnicode_AsUnicode(PyObject *unicode) -{ - return PyUnicode_AsUnicodeAndSize(unicode, NULL); -} - -const Py_UNICODE * -_PyUnicode_AsUnicode(PyObject *unicode) -{ - Py_ssize_t size; - const Py_UNICODE *wstr; - - wstr = PyUnicode_AsUnicodeAndSize(unicode, &size); - if (wstr && wcslen(wstr) != (size_t)size) { - PyErr_SetString(PyExc_ValueError, "embedded null character"); - return NULL; - } - return wstr; -} - +/* +PyUnicode_GetSize() has been deprecated since Python 3.3 +because it returned length of Py_UNICODE. -Py_ssize_t +But this function is part of stable abi, because it don't +include Py_UNICODE in signature and it was not excluded from +stable abi in PEP 384. +*/ +PyAPI_FUNC(Py_ssize_t) PyUnicode_GetSize(PyObject *unicode) { - if (!PyUnicode_Check(unicode)) { - PyErr_BadArgument(); - goto onError; - } - if (_PyUnicode_WSTR(unicode) == NULL) { - if (PyUnicode_AsUnicode(unicode) == NULL) - goto onError; - } - return PyUnicode_WSTR_LENGTH(unicode); - - onError: + PyErr_SetString(PyExc_RuntimeError, + "PyUnicode_GetSize has been removed."); return -1; } -_Py_COMP_DIAG_POP - Py_ssize_t PyUnicode_GetLength(PyObject *unicode) { @@ -4281,8 +3828,6 @@ PyUnicode_GetLength(PyObject *unicode) PyErr_BadArgument(); return -1; } - if (PyUnicode_READY(unicode) == -1) - return -1; return PyUnicode_GET_LENGTH(unicode); } @@ -4296,9 +3841,6 @@ PyUnicode_ReadChar(PyObject *unicode, Py_ssize_t index) PyErr_BadArgument(); return (Py_UCS4)-1; } - if (PyUnicode_READY(unicode) == -1) { - return (Py_UCS4)-1; - } if (index < 0 || index >= PyUnicode_GET_LENGTH(unicode)) { PyErr_SetString(PyExc_IndexError, "string index out of range"); return (Py_UCS4)-1; @@ -4315,7 +3857,6 @@ PyUnicode_WriteChar(PyObject *unicode, Py_ssize_t index, Py_UCS4 ch) PyErr_BadArgument(); return -1; } - assert(PyUnicode_IS_READY(unicode)); if (index < 0 || index >= PyUnicode_GET_LENGTH(unicode)) { PyErr_SetString(PyExc_IndexError, "string index out of range"); return -1; @@ -4448,19 +3989,10 @@ unicode_decode_call_errorhandler_wchar( goto onError; } -#if USE_UNICODE_WCHAR_CACHE -_Py_COMP_DIAG_PUSH -_Py_COMP_DIAG_IGNORE_DEPR_DECLS - repwlen = PyUnicode_GetSize(repunicode); - if (repwlen < 0) - goto onError; -_Py_COMP_DIAG_POP -#else /* USE_UNICODE_WCHAR_CACHE */ repwlen = PyUnicode_AsWideChar(repunicode, NULL, 0); if (repwlen < 0) goto onError; repwlen--; -#endif /* USE_UNICODE_WCHAR_CACHE */ /* need more space? (at least enough for what we have+the replacement+the rest of the string (starting at the new input position), so we won't have to check space @@ -4910,8 +4442,6 @@ _PyUnicode_EncodeUTF7(PyObject *str, char * out; const char * start; - if (PyUnicode_READY(str) == -1) - return NULL; kind = PyUnicode_KIND(str); data = PyUnicode_DATA(str); len = PyUnicode_GET_LENGTH(str); @@ -5120,6 +4650,9 @@ unicode_decode_utf8(const char *s, Py_ssize_t size, } s += ascii_decode(s, end, PyUnicode_1BYTE_DATA(u)); if (s == end) { + if (consumed) { + *consumed = size; + } return u; } @@ -5540,14 +5073,11 @@ unicode_encode_utf8(PyObject *unicode, _Py_error_handler error_handler, return NULL; } - if (PyUnicode_READY(unicode) == -1) - return NULL; - if (PyUnicode_UTF8(unicode)) return PyBytes_FromStringAndSize(PyUnicode_UTF8(unicode), PyUnicode_UTF8_LENGTH(unicode)); - enum PyUnicode_Kind kind = PyUnicode_KIND(unicode); + int kind = PyUnicode_KIND(unicode); const void *data = PyUnicode_DATA(unicode); Py_ssize_t size = PyUnicode_GET_LENGTH(unicode); @@ -5583,7 +5113,7 @@ unicode_fill_utf8(PyObject *unicode) /* the string cannot be ASCII, or PyUnicode_UTF8() would be set */ assert(!PyUnicode_IS_ASCII(unicode)); - enum PyUnicode_Kind kind = PyUnicode_KIND(unicode); + int kind = PyUnicode_KIND(unicode); const void *data = PyUnicode_DATA(unicode); Py_ssize_t size = PyUnicode_GET_LENGTH(unicode); @@ -5718,7 +5248,7 @@ PyUnicode_DecodeUTF32Stateful(const char *s, Py_UCS4 maxch = PyUnicode_MAX_CHAR_VALUE(writer.buffer); if (e - q >= 4) { - enum PyUnicode_Kind kind = writer.kind; + int kind = writer.kind; void *data = writer.data; const unsigned char *last = e - 4; Py_ssize_t pos = writer.pos; @@ -5803,7 +5333,7 @@ _PyUnicode_EncodeUTF32(PyObject *str, const char *errors, int byteorder) { - enum PyUnicode_Kind kind; + int kind; const void *data; Py_ssize_t len; PyObject *v; @@ -5823,8 +5353,6 @@ _PyUnicode_EncodeUTF32(PyObject *str, PyErr_BadArgument(); return NULL; } - if (PyUnicode_READY(str) == -1) - return NULL; kind = PyUnicode_KIND(str); data = PyUnicode_DATA(str); len = PyUnicode_GET_LENGTH(str); @@ -5891,8 +5419,6 @@ _PyUnicode_EncodeUTF32(PyObject *str, } else { assert(PyUnicode_Check(rep)); - if (PyUnicode_READY(rep) < 0) - goto error; moreunits = repsize = PyUnicode_GET_LENGTH(rep); if (!PyUnicode_IS_ASCII(rep)) { raise_encode_exception(&exc, encoding, @@ -6124,7 +5650,7 @@ _PyUnicode_EncodeUTF16(PyObject *str, const char *errors, int byteorder) { - enum PyUnicode_Kind kind; + int kind; const void *data; Py_ssize_t len; PyObject *v; @@ -6145,8 +5671,6 @@ _PyUnicode_EncodeUTF16(PyObject *str, PyErr_BadArgument(); return NULL; } - if (PyUnicode_READY(str) == -1) - return NULL; kind = PyUnicode_KIND(str); data = PyUnicode_DATA(str); len = PyUnicode_GET_LENGTH(str); @@ -6230,8 +5754,6 @@ _PyUnicode_EncodeUTF16(PyObject *str, } else { assert(PyUnicode_Check(rep)); - if (PyUnicode_READY(rep) < 0) - goto error; moreunits = repsize = PyUnicode_GET_LENGTH(rep); if (!PyUnicode_IS_ASCII(rep)) { raise_encode_exception(&exc, encoding, @@ -6295,8 +5817,6 @@ PyUnicode_AsUTF16String(PyObject *unicode) /* --- Unicode Escape Codec ----------------------------------------------- */ -static _PyUnicode_Name_CAPI *ucnhash_capi = NULL; - PyObject * _PyUnicode_DecodeUnicodeEscapeInternal(const char *s, Py_ssize_t size, @@ -6309,6 +5829,8 @@ _PyUnicode_DecodeUnicodeEscapeInternal(const char *s, const char *end; PyObject *errorHandler = NULL; PyObject *exc = NULL; + _PyUnicode_Name_CAPI *ucnhash_capi; + PyInterpreterState *interp = _PyInterpreterState_Get(); // so we can remember if we've seen an invalid escape char or not *first_invalid_escape = NULL; @@ -6456,6 +5978,7 @@ _PyUnicode_DecodeUnicodeEscapeInternal(const char *s, /* \N{name} */ case 'N': + ucnhash_capi = interp->unicode.ucnhash_capi; if (ucnhash_capi == NULL) { /* load the unicode data module */ ucnhash_capi = (_PyUnicode_Name_CAPI *)PyCapsule_Import( @@ -6467,6 +5990,7 @@ _PyUnicode_DecodeUnicodeEscapeInternal(const char *s, ); goto onError; } + interp->unicode.ucnhash_capi = ucnhash_capi; } message = "malformed \\N character escape"; @@ -6593,7 +6117,7 @@ PyUnicode_AsUnicodeEscapeString(PyObject *unicode) Py_ssize_t i, len; PyObject *repr; char *p; - enum PyUnicode_Kind kind; + int kind; const void *data; Py_ssize_t expandsize; @@ -6609,9 +6133,6 @@ PyUnicode_AsUnicodeEscapeString(PyObject *unicode) PyErr_BadArgument(); return NULL; } - if (PyUnicode_READY(unicode) == -1) { - return NULL; - } len = PyUnicode_GET_LENGTH(unicode); if (len == 0) { @@ -6866,9 +6387,6 @@ PyUnicode_AsRawUnicodeEscapeString(PyObject *unicode) PyErr_BadArgument(); return NULL; } - if (PyUnicode_READY(unicode) == -1) { - return NULL; - } kind = PyUnicode_KIND(unicode); data = PyUnicode_DATA(unicode); len = PyUnicode_GET_LENGTH(unicode); @@ -7005,8 +6523,6 @@ unicode_encode_call_errorhandler(const char *errors, return NULL; } - if (PyUnicode_READY(unicode) == -1) - return NULL; len = PyUnicode_GET_LENGTH(unicode); make_encode_exception(exceptionObject, @@ -7064,8 +6580,6 @@ unicode_encode_ucs1(PyObject *unicode, /* output object */ _PyBytesWriter writer; - if (PyUnicode_READY(unicode) == -1) - return NULL; size = PyUnicode_GET_LENGTH(unicode); kind = PyUnicode_KIND(unicode); data = PyUnicode_DATA(unicode); @@ -7184,9 +6698,6 @@ unicode_encode_ucs1(PyObject *unicode, else { assert(PyUnicode_Check(rep)); - if (PyUnicode_READY(rep) < 0) - goto onError; - if (limit == 256 ? PyUnicode_KIND(rep) != PyUnicode_1BYTE_KIND : !PyUnicode_IS_ASCII(rep)) @@ -7233,8 +6744,6 @@ _PyUnicode_AsLatin1String(PyObject *unicode, const char *errors) PyErr_BadArgument(); return NULL; } - if (PyUnicode_READY(unicode) == -1) - return NULL; /* Fast path: if it is a one-byte string, construct bytes object directly. */ if (PyUnicode_KIND(unicode) == PyUnicode_1BYTE_KIND) @@ -7359,8 +6868,6 @@ _PyUnicode_AsASCIIString(PyObject *unicode, const char *errors) PyErr_BadArgument(); return NULL; } - if (PyUnicode_READY(unicode) == -1) - return NULL; /* Fast path: if it is an ASCII-only string, construct bytes object directly. Else defer to above function to raise the exception. */ if (PyUnicode_IS_ASCII(unicode)) @@ -7553,7 +7060,7 @@ decode_code_page_errors(UINT code_page, if (err != ERROR_NO_UNICODE_TRANSLATION && err != ERROR_INSUFFICIENT_BUFFER) { - PyErr_SetFromWindowsErr(0); + PyErr_SetFromWindowsErr(err); goto error; } insize++; @@ -7748,22 +7255,11 @@ encode_code_page_strict(UINT code_page, PyObject **outbytes, substring = PyUnicode_Substring(unicode, offset, offset+len); if (substring == NULL) return -1; -#if USE_UNICODE_WCHAR_CACHE -_Py_COMP_DIAG_PUSH -_Py_COMP_DIAG_IGNORE_DEPR_DECLS - p = PyUnicode_AsUnicodeAndSize(substring, &size); - if (p == NULL) { - Py_DECREF(substring); - return -1; - } -_Py_COMP_DIAG_POP -#else /* USE_UNICODE_WCHAR_CACHE */ p = PyUnicode_AsWideCharString(substring, &size); Py_CLEAR(substring); if (p == NULL) { return -1; } -#endif /* USE_UNICODE_WCHAR_CACHE */ assert(size <= INT_MAX); /* First get the size of the result */ @@ -7814,11 +7310,7 @@ _Py_COMP_DIAG_POP ret = 0; done: -#if USE_UNICODE_WCHAR_CACHE - Py_DECREF(substring); -#else /* USE_UNICODE_WCHAR_CACHE */ PyMem_Free(p); -#endif /* USE_UNICODE_WCHAR_CACHE */ return ret; error: @@ -7968,14 +7460,9 @@ encode_code_page_errors(UINT code_page, PyObject **outbytes, } else { Py_ssize_t i; - enum PyUnicode_Kind kind; + int kind; const void *data; - if (PyUnicode_READY(rep) == -1) { - Py_DECREF(rep); - goto error; - } - outsize = PyUnicode_GET_LENGTH(rep); morebytes += outsize; if (morebytes > 0) { @@ -8036,8 +7523,6 @@ encode_code_page(int code_page, return NULL; } - if (PyUnicode_READY(unicode) == -1) - return NULL; len = PyUnicode_GET_LENGTH(unicode); if (code_page < 0) { @@ -8114,14 +7599,11 @@ charmap_decode_string(const char *s, Py_ssize_t startinpos, endinpos; PyObject *errorHandler = NULL, *exc = NULL; Py_ssize_t maplen; - enum PyUnicode_Kind mapkind; + int mapkind; const void *mapdata; Py_UCS4 x; unsigned char ch; - if (PyUnicode_READY(mapping) == -1) - return -1; - maplen = PyUnicode_GET_LENGTH(mapping); mapdata = PyUnicode_DATA(mapping); mapkind = PyUnicode_KIND(mapping); @@ -8155,7 +7637,7 @@ charmap_decode_string(const char *s, while (s < e) { if (mapkind == PyUnicode_2BYTE_KIND && maplen >= 256) { - enum PyUnicode_Kind outkind = writer->kind; + int outkind = writer->kind; const Py_UCS2 *mapdata_ucs2 = (const Py_UCS2 *)mapdata; if (outkind == PyUnicode_1BYTE_KIND) { Py_UCS1 *outdata = (Py_UCS1 *)writer->data; @@ -8274,8 +7756,6 @@ charmap_decode_mapping(const char *s, goto onError; } else if (PyUnicode_Check(item)) { - if (PyUnicode_READY(item) == -1) - goto onError; if (PyUnicode_GET_LENGTH(item) == 1) { Py_UCS4 value = PyUnicode_READ_CHAR(item, 0); if (value == 0xFFFE) @@ -8454,25 +7934,30 @@ PyUnicode_BuildEncodingMap(PyObject* string) if (need_dict) { PyObject *result = PyDict_New(); - PyObject *key, *value; if (!result) return NULL; for (i = 0; i < length; i++) { - key = PyLong_FromLong(PyUnicode_READ(kind, data, i)); - value = PyLong_FromLong(i); - if (!key || !value) - goto failed1; - if (PyDict_SetItem(result, key, value) == -1) - goto failed1; + Py_UCS4 c = PyUnicode_READ(kind, data, i); + PyObject *key = PyLong_FromLong(c); + if (key == NULL) { + Py_DECREF(result); + return NULL; + } + PyObject *value = PyLong_FromLong(i); + if (value == NULL) { + Py_DECREF(key); + Py_DECREF(result); + return NULL; + } + int rc = PyDict_SetItem(result, key, value); Py_DECREF(key); Py_DECREF(value); + if (rc < 0) { + Py_DECREF(result); + return NULL; + } } return result; - failed1: - Py_XDECREF(key); - Py_XDECREF(value); - Py_DECREF(result); - return NULL; } /* Create a three-level trie */ @@ -8676,7 +8161,7 @@ charmap_encoding_error( PyObject *repunicode = NULL; /* initialize to prevent gcc warning */ Py_ssize_t size, repsize; Py_ssize_t newpos; - enum PyUnicode_Kind kind; + int kind; const void *data; Py_ssize_t index; /* startpos for collecting unencodable chars */ @@ -8689,8 +8174,6 @@ charmap_encoding_error( Py_UCS4 ch; int val; - if (PyUnicode_READY(unicode) == -1) - return -1; size = PyUnicode_GET_LENGTH(unicode); /* find all unencodable characters */ while (collendpos < size) { @@ -8786,10 +8269,6 @@ charmap_encoding_error( break; } /* generate replacement */ - if (PyUnicode_READY(repunicode) == -1) { - Py_DECREF(repunicode); - return -1; - } repsize = PyUnicode_GET_LENGTH(repunicode); data = PyUnicode_DATA(repunicode); kind = PyUnicode_KIND(repunicode); @@ -8830,8 +8309,6 @@ _PyUnicode_EncodeCharmap(PyObject *unicode, const void *data; int kind; - if (PyUnicode_READY(unicode) == -1) - return NULL; size = PyUnicode_GET_LENGTH(unicode); data = PyUnicode_DATA(unicode); kind = PyUnicode_KIND(unicode); @@ -9110,10 +8587,6 @@ unicode_fast_translate_lookup(PyObject *mapping, Py_UCS1 ch, else if (PyUnicode_Check(item)) { Py_UCS4 replace; - if (PyUnicode_READY(item) == -1) { - Py_DECREF(item); - return -1; - } if (PyUnicode_GET_LENGTH(item) != 1) goto exit; @@ -9210,8 +8683,6 @@ _PyUnicode_TranslateCharmap(PyObject *input, return NULL; } - if (PyUnicode_READY(input) == -1) - return NULL; data = PyUnicode_DATA(input); kind = PyUnicode_KIND(input); size = PyUnicode_GET_LENGTH(input); @@ -9227,8 +8698,6 @@ _PyUnicode_TranslateCharmap(PyObject *input, ignore = (errors != NULL && strcmp(errors, "ignore") == 0); - if (PyUnicode_READY(input) == -1) - return NULL; if (PyUnicode_IS_ASCII(input)) { res = unicode_fast_translate(input, mapping, &writer, ignore, &i); if (res < 0) { @@ -9324,12 +8793,9 @@ _PyUnicode_TransformDecimalAndSpaceToASCII(PyObject *unicode) PyErr_BadInternalCall(); return NULL; } - if (PyUnicode_READY(unicode) == -1) - return NULL; if (PyUnicode_IS_ASCII(unicode)) { /* If the string is already ASCII, just return the same string */ - Py_INCREF(unicode); - return unicode; + return Py_NewRef(unicode); } Py_ssize_t len = PyUnicode_GET_LENGTH(unicode); @@ -9517,15 +8983,6 @@ _PyUnicode_InsertThousandsGrouping( assert(0 <= n_digits); assert(grouping != NULL); - if (digits != NULL) { - if (PyUnicode_READY(digits) == -1) { - return -1; - } - } - if (PyUnicode_READY(thousands_sep) == -1) { - return -1; - } - Py_ssize_t count = 0; Py_ssize_t n_zeros; int loop_broken = 0; @@ -9611,21 +9068,20 @@ _PyUnicode_InsertThousandsGrouping( return count; } - -Py_ssize_t -PyUnicode_Count(PyObject *str, - PyObject *substr, - Py_ssize_t start, - Py_ssize_t end) +static Py_ssize_t +unicode_count_impl(PyObject *str, + PyObject *substr, + Py_ssize_t start, + Py_ssize_t end) { + assert(PyUnicode_Check(str)); + assert(PyUnicode_Check(substr)); + Py_ssize_t result; int kind1, kind2; const void *buf1 = NULL, *buf2 = NULL; Py_ssize_t len1, len2; - if (ensure_unicode(str) < 0 || ensure_unicode(substr) < 0) - return -1; - kind1 = PyUnicode_KIND(str); kind2 = PyUnicode_KIND(substr); if (kind1 < kind2) @@ -9645,18 +9101,13 @@ PyUnicode_Count(PyObject *str, goto onError; } + // We don't reuse `anylib_count` here because of the explicit casts. switch (kind1) { case PyUnicode_1BYTE_KIND: - if (PyUnicode_IS_ASCII(str) && PyUnicode_IS_ASCII(substr)) - result = asciilib_count( - ((const Py_UCS1*)buf1) + start, end - start, - buf2, len2, PY_SSIZE_T_MAX - ); - else - result = ucs1lib_count( - ((const Py_UCS1*)buf1) + start, end - start, - buf2, len2, PY_SSIZE_T_MAX - ); + result = ucs1lib_count( + ((const Py_UCS1*)buf1) + start, end - start, + buf2, len2, PY_SSIZE_T_MAX + ); break; case PyUnicode_2BYTE_KIND: result = ucs2lib_count( @@ -9686,6 +9137,18 @@ PyUnicode_Count(PyObject *str, return -1; } +Py_ssize_t +PyUnicode_Count(PyObject *str, + PyObject *substr, + Py_ssize_t start, + Py_ssize_t end) +{ + if (ensure_unicode(str) < 0 || ensure_unicode(substr) < 0) + return -1; + + return unicode_count_impl(str, substr, start, end); +} + Py_ssize_t PyUnicode_Find(PyObject *str, PyObject *substr, @@ -9706,8 +9169,6 @@ PyUnicode_FindChar(PyObject *str, Py_UCS4 ch, { int kind; Py_ssize_t len, result; - if (PyUnicode_READY(str) == -1) - return -2; len = PyUnicode_GET_LENGTH(str); ADJUST_INDICES(start, end, len); if (end - start < 1) @@ -9736,10 +9197,6 @@ tailmatch(PyObject *self, Py_ssize_t i; Py_ssize_t end_sub; - if (PyUnicode_READY(self) == -1 || - PyUnicode_READY(substring) == -1) - return -1; - ADJUST_INDICES(start, end, PyUnicode_GET_LENGTH(self)); end -= PyUnicode_GET_LENGTH(substring); if (end < start) @@ -9998,8 +9455,6 @@ case_operation(PyObject *self, void *outdata; Py_UCS4 maxchar = 0, *tmp, *tmpend; - assert(PyUnicode_IS_READY(self)); - kind = PyUnicode_KIND(self); data = PyUnicode_DATA(self); length = PyUnicode_GET_LENGTH(self); @@ -10072,7 +9527,7 @@ _PyUnicode_JoinArray(PyObject *separator, PyObject *const *items, Py_ssize_t seq int use_memcpy; unsigned char *res_data = NULL, *sep_data = NULL; PyObject *last_obj; - unsigned int kind = 0; + int kind = 0; /* If empty sequence, return u"". */ if (seqlen == 0) { @@ -10084,8 +9539,7 @@ _PyUnicode_JoinArray(PyObject *separator, PyObject *const *items, Py_ssize_t seq if (seqlen == 1) { if (PyUnicode_CheckExact(items[0])) { res = items[0]; - Py_INCREF(res); - return res; + return Py_NewRef(res); } seplen = 0; maxchar = 0; @@ -10108,8 +9562,6 @@ _PyUnicode_JoinArray(PyObject *separator, PyObject *const *items, Py_ssize_t seq Py_TYPE(separator)->tp_name); goto onError; } - if (PyUnicode_READY(separator)) - goto onError; sep = separator; seplen = PyUnicode_GET_LENGTH(separator); maxchar = PyUnicode_MAX_CHAR_VALUE(separator); @@ -10141,8 +9593,6 @@ _PyUnicode_JoinArray(PyObject *separator, PyObject *const *items, Py_ssize_t seq i, Py_TYPE(item)->tp_name); goto onError; } - if (PyUnicode_READY(item) == -1) - goto onError; add_sz = PyUnicode_GET_LENGTH(item); item_maxchar = PyUnicode_MAX_CHAR_VALUE(item); maxchar = Py_MAX(maxchar, item_maxchar); @@ -10235,9 +9685,8 @@ void _PyUnicode_FastFill(PyObject *unicode, Py_ssize_t start, Py_ssize_t length, Py_UCS4 fill_char) { - const enum PyUnicode_Kind kind = PyUnicode_KIND(unicode); + const int kind = PyUnicode_KIND(unicode); void *data = PyUnicode_DATA(unicode); - assert(PyUnicode_IS_READY(unicode)); assert(unicode_modifiable(unicode)); assert(fill_char <= PyUnicode_MAX_CHAR_VALUE(unicode)); assert(start >= 0); @@ -10255,8 +9704,6 @@ PyUnicode_Fill(PyObject *unicode, Py_ssize_t start, Py_ssize_t length, PyErr_BadInternalCall(); return -1; } - if (PyUnicode_READY(unicode) == -1) - return -1; if (unicode_check_modifiable(unicode)) return -1; @@ -10365,53 +9812,53 @@ split(PyObject *self, const void *buf1, *buf2; Py_ssize_t len1, len2; PyObject* out; + len1 = PyUnicode_GET_LENGTH(self); + kind1 = PyUnicode_KIND(self); - if (maxcount < 0) - maxcount = PY_SSIZE_T_MAX; - - if (PyUnicode_READY(self) == -1) - return NULL; - - if (substring == NULL) - switch (PyUnicode_KIND(self)) { + if (substring == NULL) { + if (maxcount < 0) { + maxcount = (len1 - 1) / 2 + 1; + } + switch (kind1) { case PyUnicode_1BYTE_KIND: if (PyUnicode_IS_ASCII(self)) return asciilib_split_whitespace( self, PyUnicode_1BYTE_DATA(self), - PyUnicode_GET_LENGTH(self), maxcount + len1, maxcount ); else return ucs1lib_split_whitespace( self, PyUnicode_1BYTE_DATA(self), - PyUnicode_GET_LENGTH(self), maxcount + len1, maxcount ); case PyUnicode_2BYTE_KIND: return ucs2lib_split_whitespace( self, PyUnicode_2BYTE_DATA(self), - PyUnicode_GET_LENGTH(self), maxcount + len1, maxcount ); case PyUnicode_4BYTE_KIND: return ucs4lib_split_whitespace( self, PyUnicode_4BYTE_DATA(self), - PyUnicode_GET_LENGTH(self), maxcount + len1, maxcount ); default: Py_UNREACHABLE(); } + } - if (PyUnicode_READY(substring) == -1) - return NULL; - - kind1 = PyUnicode_KIND(self); kind2 = PyUnicode_KIND(substring); - len1 = PyUnicode_GET_LENGTH(self); len2 = PyUnicode_GET_LENGTH(substring); + if (maxcount < 0) { + // if len2 == 0, it will raise ValueError. + maxcount = len2 == 0 ? 0 : (len1 / len2) + 1; + // handle expected overflow case: (Py_SSIZE_T_MAX / 1) + 1 + maxcount = maxcount < 0 ? len1 : maxcount; + } if (kind1 < kind2 || len1 < len2) { out = PyList_New(1); if (out == NULL) return NULL; - Py_INCREF(self); - PyList_SET_ITEM(out, 0, self); + PyList_SET_ITEM(out, 0, Py_NewRef(self)); return out; } buf1 = PyUnicode_DATA(self); @@ -10458,52 +9905,52 @@ rsplit(PyObject *self, Py_ssize_t len1, len2; PyObject* out; - if (maxcount < 0) - maxcount = PY_SSIZE_T_MAX; - - if (PyUnicode_READY(self) == -1) - return NULL; + len1 = PyUnicode_GET_LENGTH(self); + kind1 = PyUnicode_KIND(self); - if (substring == NULL) - switch (PyUnicode_KIND(self)) { + if (substring == NULL) { + if (maxcount < 0) { + maxcount = (len1 - 1) / 2 + 1; + } + switch (kind1) { case PyUnicode_1BYTE_KIND: if (PyUnicode_IS_ASCII(self)) return asciilib_rsplit_whitespace( self, PyUnicode_1BYTE_DATA(self), - PyUnicode_GET_LENGTH(self), maxcount + len1, maxcount ); else return ucs1lib_rsplit_whitespace( self, PyUnicode_1BYTE_DATA(self), - PyUnicode_GET_LENGTH(self), maxcount + len1, maxcount ); case PyUnicode_2BYTE_KIND: return ucs2lib_rsplit_whitespace( self, PyUnicode_2BYTE_DATA(self), - PyUnicode_GET_LENGTH(self), maxcount + len1, maxcount ); case PyUnicode_4BYTE_KIND: return ucs4lib_rsplit_whitespace( self, PyUnicode_4BYTE_DATA(self), - PyUnicode_GET_LENGTH(self), maxcount + len1, maxcount ); default: Py_UNREACHABLE(); } - - if (PyUnicode_READY(substring) == -1) - return NULL; - - kind1 = PyUnicode_KIND(self); + } kind2 = PyUnicode_KIND(substring); - len1 = PyUnicode_GET_LENGTH(self); len2 = PyUnicode_GET_LENGTH(substring); + if (maxcount < 0) { + // if len2 == 0, it will raise ValueError. + maxcount = len2 == 0 ? 0 : (len1 / len2) + 1; + // handle expected overflow case: (Py_SSIZE_T_MAX / 1) + 1 + maxcount = maxcount < 0 ? len1 : maxcount; + } if (kind1 < kind2 || len1 < len2) { out = PyList_New(1); if (out == NULL) return NULL; - Py_INCREF(self); - PyList_SET_ITEM(out, 0, self); + PyList_SET_ITEM(out, 0, Py_NewRef(self)); return out; } buf1 = PyUnicode_DATA(self); @@ -10564,10 +10011,7 @@ anylib_count(int kind, PyObject *sstr, const void* sbuf, Py_ssize_t slen, { switch (kind) { case PyUnicode_1BYTE_KIND: - if (PyUnicode_IS_ASCII(sstr) && PyUnicode_IS_ASCII(str1)) - return asciilib_count(sbuf, slen, buf1, len1, maxcount); - else - return ucs1lib_count(sbuf, slen, buf1, len1, maxcount); + return ucs1lib_count(sbuf, slen, buf1, len1, maxcount); case PyUnicode_2BYTE_KIND: return ucs2lib_count(sbuf, slen, buf1, len1, maxcount); case PyUnicode_4BYTE_KIND: @@ -10895,8 +10339,6 @@ static PyObject * unicode_title_impl(PyObject *self) /*[clinic end generated code: output=c75ae03809574902 input=fa945d669b26e683]*/ { - if (PyUnicode_READY(self) == -1) - return NULL; return case_operation(self, do_title); } @@ -10913,8 +10355,6 @@ static PyObject * unicode_capitalize_impl(PyObject *self) /*[clinic end generated code: output=e49a4c333cdb7667 input=f4cbf1016938da6d]*/ { - if (PyUnicode_READY(self) == -1) - return NULL; if (PyUnicode_GET_LENGTH(self) == 0) return unicode_result_unchanged(self); return case_operation(self, do_capitalize); @@ -10930,8 +10370,6 @@ static PyObject * unicode_casefold_impl(PyObject *self) /*[clinic end generated code: output=0120daf657ca40af input=384d66cc2ae30daf]*/ { - if (PyUnicode_READY(self) == -1) - return NULL; if (PyUnicode_IS_ASCII(self)) return ascii_upper_or_lower(self, 1); return case_operation(self, do_casefold); @@ -10951,8 +10389,6 @@ convert_uc(PyObject *obj, void *addr) "not %.100s", Py_TYPE(obj)->tp_name); return 0; } - if (PyUnicode_READY(obj) < 0) - return 0; if (PyUnicode_GET_LENGTH(obj) != 1) { PyErr_SetString(PyExc_TypeError, "The fill character must be exactly one character long"); @@ -10980,9 +10416,6 @@ unicode_center_impl(PyObject *self, Py_ssize_t width, Py_UCS4 fillchar) { Py_ssize_t marg, left; - if (PyUnicode_READY(self) == -1) - return NULL; - if (PyUnicode_GET_LENGTH(self) >= width) return unicode_result_unchanged(self); @@ -11139,9 +10572,6 @@ _PyUnicode_Equal(PyObject *str1, PyObject *str2) if (str1 == str2) { return 1; } - if (PyUnicode_READY(str1) || PyUnicode_READY(str2)) { - return -1; - } return unicode_compare_eq(str1, str2); } @@ -11150,10 +10580,6 @@ int PyUnicode_Compare(PyObject *left, PyObject *right) { if (PyUnicode_Check(left) && PyUnicode_Check(right)) { - if (PyUnicode_READY(left) == -1 || - PyUnicode_READY(right) == -1) - return -1; - /* a string is equal to itself */ if (left == right) return 0; @@ -11173,24 +10599,8 @@ PyUnicode_CompareWithASCIIString(PyObject* uni, const char* str) Py_ssize_t i; int kind; Py_UCS4 chr; - const unsigned char *ustr = (const unsigned char *)str; assert(_PyUnicode_CHECK(uni)); - if (!PyUnicode_IS_READY(uni)) { - const wchar_t *ws = _PyUnicode_WSTR(uni); - /* Compare Unicode string and source character set string */ - for (i = 0; (chr = ws[i]) && ustr[i]; i++) { - if (chr != ustr[i]) - return (chr < ustr[i]) ? -1 : 1; - } - /* This check keeps Python strings that end in '\0' from comparing equal - to C strings identical up to that point. */ - if (_PyUnicode_WSTR_LENGTH(uni) != i || chr) - return 1; /* uni is longer */ - if (ustr[i]) - return -1; /* str is longer */ - return 0; - } kind = PyUnicode_KIND(uni); if (kind == PyUnicode_1BYTE_KIND) { const void *data = PyUnicode_1BYTE_DATA(uni); @@ -11228,24 +10638,6 @@ PyUnicode_CompareWithASCIIString(PyObject* uni, const char* str) } } -static int -non_ready_unicode_equal_to_ascii_string(PyObject *unicode, const char *str) -{ - size_t i, len; - const wchar_t *p; - len = (size_t)_PyUnicode_WSTR_LENGTH(unicode); - if (strlen(str) != len) - return 0; - p = _PyUnicode_WSTR(unicode); - assert(p); - for (i = 0; i < len; i++) { - unsigned char c = (unsigned char)str[i]; - if (c >= 128 || p[i] != (wchar_t)c) - return 0; - } - return 1; -} - int _PyUnicode_EqualToASCIIString(PyObject *unicode, const char *str) { @@ -11257,11 +10649,6 @@ _PyUnicode_EqualToASCIIString(PyObject *unicode, const char *str) assert((unsigned char)*p < 128); } #endif - if (PyUnicode_READY(unicode) == -1) { - /* Memory error or bad data */ - PyErr_Clear(); - return non_ready_unicode_equal_to_ascii_string(unicode, str); - } if (!PyUnicode_IS_ASCII(unicode)) return 0; len = (size_t)PyUnicode_GET_LENGTH(unicode); @@ -11282,12 +10669,6 @@ _PyUnicode_EqualToASCIIId(PyObject *left, _Py_Identifier *right) } #endif - if (PyUnicode_READY(left) == -1) { - /* memory error or bad data */ - PyErr_Clear(); - return non_ready_unicode_equal_to_ascii_string(left, right->string); - } - if (!PyUnicode_IS_ASCII(left)) return 0; @@ -11321,10 +10702,6 @@ PyUnicode_RichCompare(PyObject *left, PyObject *right, int op) if (!PyUnicode_Check(left) || !PyUnicode_Check(right)) Py_RETURN_NOTIMPLEMENTED; - if (PyUnicode_READY(left) == -1 || - PyUnicode_READY(right) == -1) - return NULL; - if (left == right) { switch (op) { case Py_EQ: @@ -11372,8 +10749,6 @@ PyUnicode_Contains(PyObject *str, PyObject *substr) Py_TYPE(substr)->tp_name); return -1; } - if (PyUnicode_READY(substr) == -1) - return -1; if (ensure_unicode(str) < 0) return -1; @@ -11437,8 +10812,6 @@ PyUnicode_Concat(PyObject *left, PyObject *right) Py_TYPE(right)->tp_name); return NULL; } - if (PyUnicode_READY(right) < 0) - return NULL; /* Shortcuts */ PyObject *empty = unicode_get_empty(); // Borrowed reference @@ -11492,17 +10865,11 @@ PyUnicode_Append(PyObject **p_left, PyObject *right) goto error; } - if (PyUnicode_READY(left) == -1) - goto error; - if (PyUnicode_READY(right) == -1) - goto error; - /* Shortcuts */ PyObject *empty = unicode_get_empty(); // Borrowed reference if (left == empty) { Py_DECREF(left); - Py_INCREF(right); - *p_left = right; + *p_left = Py_NewRef(right); return; } if (right == empty) { @@ -11563,7 +10930,7 @@ PyUnicode_AppendAndDel(PyObject **pleft, PyObject *right) } /* -Wraps stringlib_parse_args_finds() and additionally ensures that the +Wraps asciilib_parse_args_finds() and additionally ensures that the first argument is a unicode object. */ @@ -11572,8 +10939,7 @@ parse_args_finds_unicode(const char * function_name, PyObject *args, PyObject **substring, Py_ssize_t *start, Py_ssize_t *end) { - if(stringlib_parse_args_finds(function_name, args, substring, - start, end)) { + if (asciilib_parse_args_finds(function_name, args, substring, start, end)) { if (ensure_unicode(*substring) < 0) return 0; return 1; @@ -11594,62 +10960,16 @@ unicode_count(PyObject *self, PyObject *args) PyObject *substring = NULL; /* initialize to fix a compiler warning */ Py_ssize_t start = 0; Py_ssize_t end = PY_SSIZE_T_MAX; - PyObject *result; - int kind1, kind2; - const void *buf1, *buf2; - Py_ssize_t len1, len2, iresult; + Py_ssize_t result; if (!parse_args_finds_unicode("count", args, &substring, &start, &end)) return NULL; - kind1 = PyUnicode_KIND(self); - kind2 = PyUnicode_KIND(substring); - if (kind1 < kind2) - return PyLong_FromLong(0); - - len1 = PyUnicode_GET_LENGTH(self); - len2 = PyUnicode_GET_LENGTH(substring); - ADJUST_INDICES(start, end, len1); - if (end - start < len2) - return PyLong_FromLong(0); - - buf1 = PyUnicode_DATA(self); - buf2 = PyUnicode_DATA(substring); - if (kind2 != kind1) { - buf2 = unicode_askind(kind2, buf2, len2, kind1); - if (!buf2) - return NULL; - } - switch (kind1) { - case PyUnicode_1BYTE_KIND: - iresult = ucs1lib_count( - ((const Py_UCS1*)buf1) + start, end - start, - buf2, len2, PY_SSIZE_T_MAX - ); - break; - case PyUnicode_2BYTE_KIND: - iresult = ucs2lib_count( - ((const Py_UCS2*)buf1) + start, end - start, - buf2, len2, PY_SSIZE_T_MAX - ); - break; - case PyUnicode_4BYTE_KIND: - iresult = ucs4lib_count( - ((const Py_UCS4*)buf1) + start, end - start, - buf2, len2, PY_SSIZE_T_MAX - ); - break; - default: - Py_UNREACHABLE(); - } - - result = PyLong_FromSsize_t(iresult); - - assert((kind2 == kind1) == (buf2 == PyUnicode_DATA(substring))); - if (kind2 != kind1) - PyMem_Free((void *)buf2); + result = unicode_count_impl(self, substring, start, end); + if (result == -1) + return NULL; - return result; + return PyLong_FromSsize_t(result); } /*[clinic input] @@ -11696,9 +11016,6 @@ unicode_expandtabs_impl(PyObject *self, int tabsize) int kind; int found; - if (PyUnicode_READY(self) == -1) - return NULL; - /* First pass: determine size of output string */ src_len = PyUnicode_GET_LENGTH(self); i = j = line_pos = 0; @@ -11784,9 +11101,6 @@ unicode_find(PyObject *self, PyObject *args) if (!parse_args_finds_unicode("find", args, &substring, &start, &end)) return NULL; - if (PyUnicode_READY(self) == -1) - return NULL; - result = any_find_slice(self, substring, start, end, 1); if (result == -2) @@ -11799,16 +11113,13 @@ static PyObject * unicode_getitem(PyObject *self, Py_ssize_t index) { const void *data; - enum PyUnicode_Kind kind; + int kind; Py_UCS4 ch; if (!PyUnicode_Check(self)) { PyErr_BadArgument(); return NULL; } - if (PyUnicode_READY(self) == -1) { - return NULL; - } if (index < 0 || index >= PyUnicode_GET_LENGTH(self)) { PyErr_SetString(PyExc_IndexError, "string index out of range"); return NULL; @@ -11831,8 +11142,6 @@ unicode_hash(PyObject *self) #endif if (_PyUnicode_HASH(self) != -1) return _PyUnicode_HASH(self); - if (PyUnicode_READY(self) == -1) - return -1; x = _Py_HashBytes(PyUnicode_DATA(self), PyUnicode_GET_LENGTH(self) * PyUnicode_KIND(self)); @@ -11861,9 +11170,6 @@ unicode_index(PyObject *self, PyObject *args) if (!parse_args_finds_unicode("index", args, &substring, &start, &end)) return NULL; - if (PyUnicode_READY(self) == -1) - return NULL; - result = any_find_slice(self, substring, start, end, 1); if (result == -2) @@ -11890,9 +11196,6 @@ static PyObject * unicode_isascii_impl(PyObject *self) /*[clinic end generated code: output=c5910d64b5a8003f input=5a43cbc6399621d5]*/ { - if (PyUnicode_READY(self) == -1) { - return NULL; - } return PyBool_FromLong(PyUnicode_IS_ASCII(self)); } @@ -11914,8 +11217,6 @@ unicode_islower_impl(PyObject *self) const void *data; int cased; - if (PyUnicode_READY(self) == -1) - return NULL; length = PyUnicode_GET_LENGTH(self); kind = PyUnicode_KIND(self); data = PyUnicode_DATA(self); @@ -11959,8 +11260,6 @@ unicode_isupper_impl(PyObject *self) const void *data; int cased; - if (PyUnicode_READY(self) == -1) - return NULL; length = PyUnicode_GET_LENGTH(self); kind = PyUnicode_KIND(self); data = PyUnicode_DATA(self); @@ -12004,8 +11303,6 @@ unicode_istitle_impl(PyObject *self) const void *data; int cased, previous_is_cased; - if (PyUnicode_READY(self) == -1) - return NULL; length = PyUnicode_GET_LENGTH(self); kind = PyUnicode_KIND(self); data = PyUnicode_DATA(self); @@ -12061,8 +11358,6 @@ unicode_isspace_impl(PyObject *self) int kind; const void *data; - if (PyUnicode_READY(self) == -1) - return NULL; length = PyUnicode_GET_LENGTH(self); kind = PyUnicode_KIND(self); data = PyUnicode_DATA(self); @@ -12101,8 +11396,6 @@ unicode_isalpha_impl(PyObject *self) int kind; const void *data; - if (PyUnicode_READY(self) == -1) - return NULL; length = PyUnicode_GET_LENGTH(self); kind = PyUnicode_KIND(self); data = PyUnicode_DATA(self); @@ -12140,9 +11433,6 @@ unicode_isalnum_impl(PyObject *self) const void *data; Py_ssize_t len, i; - if (PyUnicode_READY(self) == -1) - return NULL; - kind = PyUnicode_KIND(self); data = PyUnicode_DATA(self); len = PyUnicode_GET_LENGTH(self); @@ -12182,8 +11472,6 @@ unicode_isdecimal_impl(PyObject *self) int kind; const void *data; - if (PyUnicode_READY(self) == -1) - return NULL; length = PyUnicode_GET_LENGTH(self); kind = PyUnicode_KIND(self); data = PyUnicode_DATA(self); @@ -12221,8 +11509,6 @@ unicode_isdigit_impl(PyObject *self) int kind; const void *data; - if (PyUnicode_READY(self) == -1) - return NULL; length = PyUnicode_GET_LENGTH(self); kind = PyUnicode_KIND(self); data = PyUnicode_DATA(self); @@ -12261,8 +11547,6 @@ unicode_isnumeric_impl(PyObject *self) int kind; const void *data; - if (PyUnicode_READY(self) == -1) - return NULL; length = PyUnicode_GET_LENGTH(self); kind = PyUnicode_KIND(self); data = PyUnicode_DATA(self); @@ -12287,9 +11571,6 @@ Py_ssize_t _PyUnicode_ScanIdentifier(PyObject *self) { Py_ssize_t i; - if (PyUnicode_READY(self) == -1) - return -1; - Py_ssize_t len = PyUnicode_GET_LENGTH(self); if (len == 0) { /* an empty string is not a valid identifier */ @@ -12323,54 +11604,10 @@ _PyUnicode_ScanIdentifier(PyObject *self) int PyUnicode_IsIdentifier(PyObject *self) { - if (PyUnicode_IS_READY(self)) { - Py_ssize_t i = _PyUnicode_ScanIdentifier(self); - Py_ssize_t len = PyUnicode_GET_LENGTH(self); - /* an empty string is not a valid identifier */ - return len && i == len; - } - else { -_Py_COMP_DIAG_PUSH -_Py_COMP_DIAG_IGNORE_DEPR_DECLS - Py_ssize_t i = 0, len = PyUnicode_GET_SIZE(self); - if (len == 0) { - /* an empty string is not a valid identifier */ - return 0; - } - - const wchar_t *wstr = _PyUnicode_WSTR(self); - Py_UCS4 ch = wstr[i++]; -#if SIZEOF_WCHAR_T == 2 - if (Py_UNICODE_IS_HIGH_SURROGATE(ch) - && i < len - && Py_UNICODE_IS_LOW_SURROGATE(wstr[i])) - { - ch = Py_UNICODE_JOIN_SURROGATES(ch, wstr[i]); - i++; - } -#endif - if (!_PyUnicode_IsXidStart(ch) && ch != 0x5F /* LOW LINE */) { - return 0; - } - - while (i < len) { - ch = wstr[i++]; -#if SIZEOF_WCHAR_T == 2 - if (Py_UNICODE_IS_HIGH_SURROGATE(ch) - && i < len - && Py_UNICODE_IS_LOW_SURROGATE(wstr[i])) - { - ch = Py_UNICODE_JOIN_SURROGATES(ch, wstr[i]); - i++; - } -#endif - if (!_PyUnicode_IsXidContinue(ch)) { - return 0; - } - } - return 1; -_Py_COMP_DIAG_POP - } + Py_ssize_t i = _PyUnicode_ScanIdentifier(self); + Py_ssize_t len = PyUnicode_GET_LENGTH(self); + /* an empty string is not a valid identifier */ + return len && i == len; } /*[clinic input] @@ -12406,8 +11643,6 @@ unicode_isprintable_impl(PyObject *self) int kind; const void *data; - if (PyUnicode_READY(self) == -1) - return NULL; length = PyUnicode_GET_LENGTH(self); kind = PyUnicode_KIND(self); data = PyUnicode_DATA(self); @@ -12449,8 +11684,6 @@ unicode_join(PyObject *self, PyObject *iterable) static Py_ssize_t unicode_length(PyObject *self) { - if (PyUnicode_READY(self) == -1) - return -1; return PyUnicode_GET_LENGTH(self); } @@ -12470,9 +11703,6 @@ static PyObject * unicode_ljust_impl(PyObject *self, Py_ssize_t width, Py_UCS4 fillchar) /*[clinic end generated code: output=1cce0e0e0a0b84b3 input=3ab599e335e60a32]*/ { - if (PyUnicode_READY(self) == -1) - return NULL; - if (PyUnicode_GET_LENGTH(self) >= width) return unicode_result_unchanged(self); @@ -12489,8 +11719,6 @@ static PyObject * unicode_lower_impl(PyObject *self) /*[clinic end generated code: output=84ef9ed42efad663 input=60a2984b8beff23a]*/ { - if (PyUnicode_READY(self) == -1) - return NULL; if (PyUnicode_IS_ASCII(self)) return ascii_upper_or_lower(self, 1); return case_operation(self, do_lower); @@ -12515,9 +11743,6 @@ _PyUnicode_XStrip(PyObject *self, int striptype, PyObject *sepobj) BLOOM_MASK sepmask; Py_ssize_t seplen; - if (PyUnicode_READY(self) == -1 || PyUnicode_READY(sepobj) == -1) - return NULL; - kind = PyUnicode_KIND(self); data = PyUnicode_DATA(self); len = PyUnicode_GET_LENGTH(self); @@ -12563,9 +11788,6 @@ PyUnicode_Substring(PyObject *self, Py_ssize_t start, Py_ssize_t end) int kind; Py_ssize_t length; - if (PyUnicode_READY(self) == -1) - return NULL; - length = PyUnicode_GET_LENGTH(self); end = Py_MIN(end, length); @@ -12598,9 +11820,6 @@ do_strip(PyObject *self, int striptype) { Py_ssize_t len, i, j; - if (PyUnicode_READY(self) == -1) - return NULL; - len = PyUnicode_GET_LENGTH(self); if (PyUnicode_IS_ASCII(self)) { @@ -12747,9 +11966,6 @@ unicode_repeat(PyObject *str, Py_ssize_t len) if (len == 1) return unicode_result_unchanged(str); - if (PyUnicode_READY(str) == -1) - return NULL; - if (PyUnicode_GET_LENGTH(str) > PY_SSIZE_T_MAX / len) { PyErr_SetString(PyExc_OverflowError, "repeated string is too long"); @@ -12824,8 +12040,6 @@ unicode_replace_impl(PyObject *self, PyObject *old, PyObject *new, Py_ssize_t count) /*[clinic end generated code: output=b63f1a8b5eebf448 input=147d12206276ebeb]*/ { - if (PyUnicode_READY(self) == -1) - return NULL; return replace(self, old, new, count); } @@ -12895,9 +12109,6 @@ unicode_repr(PyObject *unicode) const void *idata; void *odata; - if (PyUnicode_READY(unicode) == -1) - return NULL; - isize = PyUnicode_GET_LENGTH(unicode); idata = PyUnicode_DATA(unicode); @@ -13070,9 +12281,6 @@ unicode_rfind(PyObject *self, PyObject *args) if (!parse_args_finds_unicode("rfind", args, &substring, &start, &end)) return NULL; - if (PyUnicode_READY(self) == -1) - return NULL; - result = any_find_slice(self, substring, start, end, -1); if (result == -2) @@ -13102,9 +12310,6 @@ unicode_rindex(PyObject *self, PyObject *args) if (!parse_args_finds_unicode("rindex", args, &substring, &start, &end)) return NULL; - if (PyUnicode_READY(self) == -1) - return NULL; - result = any_find_slice(self, substring, start, end, -1); if (result == -2) @@ -13134,9 +12339,6 @@ static PyObject * unicode_rjust_impl(PyObject *self, Py_ssize_t width, Py_UCS4 fillchar) /*[clinic end generated code: output=804a1a57fbe8d5cf input=d05f550b5beb1f72]*/ { - if (PyUnicode_READY(self) == -1) - return NULL; - if (PyUnicode_GET_LENGTH(self) >= width) return unicode_result_unchanged(self); @@ -13159,7 +12361,7 @@ str.split as unicode_split The separator used to split the string. When set to None (the default value), will split on any whitespace - character (including \\n \\r \\t \\f and spaces) and will discard + character (including \n \r \t \f and spaces) and will discard empty strings from the result. maxsplit: Py_ssize_t = -1 Maximum number of splits (starting from the left). @@ -13175,7 +12377,7 @@ the regular expression module. static PyObject * unicode_split_impl(PyObject *self, PyObject *sep, Py_ssize_t maxsplit) -/*[clinic end generated code: output=3a65b1db356948dc input=906d953b44efc43b]*/ +/*[clinic end generated code: output=3a65b1db356948dc input=07b9040d98c5fe8d]*/ { if (sep == Py_None) return split(self, NULL, maxsplit); @@ -13369,7 +12571,7 @@ unicode_rsplit_impl(PyObject *self, PyObject *sep, Py_ssize_t maxsplit) /*[clinic input] str.splitlines as unicode_splitlines - keepends: bool(accept={int}) = False + keepends: bool = False Return a list of the lines in the string, breaking at line boundaries. @@ -13379,7 +12581,7 @@ true. static PyObject * unicode_splitlines_impl(PyObject *self, int keepends) -/*[clinic end generated code: output=f664dcdad153ec40 input=b508e180459bdd8b]*/ +/*[clinic end generated code: output=f664dcdad153ec40 input=ba6ad05ee85d2b55]*/ { return PyUnicode_Splitlines(self, keepends); } @@ -13400,8 +12602,6 @@ static PyObject * unicode_swapcase_impl(PyObject *self) /*[clinic end generated code: output=5d28966bf6d7b2af input=3f3ef96d5798a7bb]*/ { - if (PyUnicode_READY(self) == -1) - return NULL; return case_operation(self, do_swapcase); } @@ -13567,8 +12767,6 @@ static PyObject * unicode_upper_impl(PyObject *self) /*[clinic end generated code: output=1b7ddd16bbcdc092 input=db3d55682dfe2e6c]*/ { - if (PyUnicode_READY(self) == -1) - return NULL; if (PyUnicode_IS_ASCII(self)) return ascii_upper_or_lower(self, 0); return case_operation(self, do_upper); @@ -13595,9 +12793,6 @@ unicode_zfill_impl(PyObject *self, Py_ssize_t width) const void *data; Py_UCS4 chr; - if (PyUnicode_READY(self) == -1) - return NULL; - if (PyUnicode_GET_LENGTH(self) >= width) return unicode_result_unchanged(self); @@ -13640,7 +12835,7 @@ unicode_startswith(PyObject *self, Py_ssize_t end = PY_SSIZE_T_MAX; int result; - if (!stringlib_parse_args_finds("startswith", args, &subobj, &start, &end)) + if (!asciilib_parse_args_finds("startswith", args, &subobj, &start, &end)) return NULL; if (PyTuple_Check(subobj)) { Py_ssize_t i; @@ -13694,7 +12889,7 @@ unicode_endswith(PyObject *self, Py_ssize_t end = PY_SSIZE_T_MAX; int result; - if (!stringlib_parse_args_finds("endswith", args, &subobj, &start, &end)) + if (!asciilib_parse_args_finds("endswith", args, &subobj, &start, &end)) return NULL; if (PyTuple_Check(subobj)) { Py_ssize_t i; @@ -13741,7 +12936,7 @@ _PyUnicodeWriter_Update(_PyUnicodeWriter *writer) else { /* use a value smaller than PyUnicode_1BYTE_KIND() so _PyUnicodeWriter_PrepareKind() will copy the buffer. */ - writer->kind = PyUnicode_WCHAR_KIND; + writer->kind = 0; assert(writer->kind <= PyUnicode_1BYTE_KIND); /* Copy-on-write mode: set buffer size to 0 so @@ -13761,7 +12956,7 @@ _PyUnicodeWriter_Init(_PyUnicodeWriter *writer) /* use a value smaller than PyUnicode_1BYTE_KIND() so _PyUnicodeWriter_PrepareKind() will copy the buffer. */ - writer->kind = PyUnicode_WCHAR_KIND; + writer->kind = 0; assert(writer->kind <= PyUnicode_1BYTE_KIND); } @@ -13854,7 +13049,7 @@ _PyUnicodeWriter_PrepareInternal(_PyUnicodeWriter *writer, int _PyUnicodeWriter_PrepareKindInternal(_PyUnicodeWriter *writer, - enum PyUnicode_Kind kind) + int kind) { Py_UCS4 maxchar; @@ -13896,8 +13091,6 @@ _PyUnicodeWriter_WriteStr(_PyUnicodeWriter *writer, PyObject *str) Py_UCS4 maxchar; Py_ssize_t len; - if (PyUnicode_READY(str) == -1) - return -1; len = PyUnicode_GET_LENGTH(str); if (len == 0) return 0; @@ -13906,8 +13099,7 @@ _PyUnicodeWriter_WriteStr(_PyUnicodeWriter *writer, PyObject *str) if (writer->buffer == NULL && !writer->overallocate) { assert(_PyUnicode_CheckConsistency(str, 1)); writer->readonly = 1; - Py_INCREF(str); - writer->buffer = str; + writer->buffer = Py_NewRef(str); _PyUnicodeWriter_Update(writer); writer->pos += len; return 0; @@ -13928,9 +13120,6 @@ _PyUnicodeWriter_WriteSubstring(_PyUnicodeWriter *writer, PyObject *str, Py_UCS4 maxchar; Py_ssize_t len; - if (PyUnicode_READY(str) == -1) - return -1; - assert(0 <= start); assert(end <= PyUnicode_GET_LENGTH(str)); assert(start <= end); @@ -14059,7 +13248,7 @@ _PyUnicodeWriter_Finish(_PyUnicodeWriter *writer) } assert(_PyUnicode_CheckConsistency(str, 1)); - return unicode_result_ready(str); + return unicode_result(str); } void @@ -14098,8 +13287,6 @@ unicode___format___impl(PyObject *self, PyObject *format_spec) _PyUnicodeWriter writer; int ret; - if (PyUnicode_READY(self) == -1) - return NULL; _PyUnicodeWriter_Init(&writer); ret = _PyUnicode_FormatAdvancedWriter(&writer, self, format_spec, 0, @@ -14125,11 +13312,13 @@ unicode_sizeof_impl(PyObject *self) /* If it's a compact object, account for base structure + character data. */ - if (PyUnicode_IS_COMPACT_ASCII(self)) + if (PyUnicode_IS_COMPACT_ASCII(self)) { size = sizeof(PyASCIIObject) + PyUnicode_GET_LENGTH(self) + 1; - else if (PyUnicode_IS_COMPACT(self)) + } + else if (PyUnicode_IS_COMPACT(self)) { size = sizeof(PyCompactUnicodeObject) + (PyUnicode_GET_LENGTH(self) + 1) * PyUnicode_KIND(self); + } else { /* If it is a two-block object, account for base object, and for character block if present. */ @@ -14138,10 +13327,6 @@ unicode_sizeof_impl(PyObject *self) size += (PyUnicode_GET_LENGTH(self) + 1) * PyUnicode_KIND(self); } - /* If the wstr pointer is present, account for it unless it is shared - with the data pointer. Check if the data is not shared. */ - if (_PyUnicode_HAS_WSTR_MEMORY(self)) - size += (PyUnicode_WSTR_LENGTH(self) + 1) * sizeof(wchar_t); if (_PyUnicode_HAS_UTF8_MEMORY(self)) size += PyUnicode_UTF8_LENGTH(self) + 1; @@ -14240,9 +13425,6 @@ static PySequenceMethods unicode_as_sequence = { static PyObject* unicode_subscript(PyObject* self, PyObject* item) { - if (PyUnicode_READY(self) == -1) - return NULL; - if (_PyIndex_Check(item)) { Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); if (i == -1 && PyErr_Occurred()) @@ -14325,7 +13507,7 @@ struct unicode_formatter_t { Py_ssize_t arglen, argidx; PyObject *dict; - enum PyUnicode_Kind fmtkind; + int fmtkind; Py_ssize_t fmtcnt, fmtpos; const void *fmtdata; PyObject *fmtstr; @@ -14385,8 +13567,6 @@ formatfloat(PyObject *v, struct unicode_format_arg_t *arg, if (arg->flags & F_ALT) dtoa_flags |= Py_DTSF_ALT; - if (arg->flags & F_NO_NEG_0) - dtoa_flags |= Py_DTSF_NO_NEG_0; p = PyOS_double_to_string(x, arg->ch, prec, dtoa_flags, NULL); if (p == NULL) return -1; @@ -14466,7 +13646,6 @@ _PyUnicode_FormatLong(PyObject *val, int alt, int prec, int type) return NULL; assert(unicode_modifiable(result)); - assert(PyUnicode_IS_READY(result)); assert(PyUnicode_IS_ASCII(result)); /* To modify the string in-place, there can only be one reference. */ @@ -14521,8 +13700,7 @@ _PyUnicode_FormatLong(PyObject *val, int alt, int prec, int type) for (i = 0; i < numdigits; i++) *b1++ = *buf++; *b1 = '\0'; - Py_DECREF(result); - result = r1; + Py_SETREF(result, r1); buf = PyBytes_AS_STRING(result); len = numnondigits + prec; } @@ -14539,8 +13717,7 @@ _PyUnicode_FormatLong(PyObject *val, int alt, int prec, int type) || buf != PyUnicode_DATA(result)) { PyObject *unicode; unicode = _PyUnicode_FromASCII(buf, len); - Py_DECREF(result); - result = unicode; + Py_SETREF(result, unicode); } else if (len != PyUnicode_GET_LENGTH(result)) { if (PyUnicode_Resize(&result, len) < 0) @@ -14581,8 +13758,7 @@ mainformatlong(PyObject *v, assert(PyLong_Check(iobj)); } else { - iobj = v; - Py_INCREF(iobj); + iobj = Py_NewRef(v); } if (PyLong_CheckExact(v) @@ -14905,8 +14081,7 @@ unicode_format_arg_format(struct unicode_formatter_t *ctx, } if (PyUnicode_CheckExact(v) && arg->ch == 's') { - *p_str = v; - Py_INCREF(*p_str); + *p_str = Py_NewRef(v); } else { if (arg->ch == 's') @@ -14988,7 +14163,7 @@ unicode_format_arg_output(struct unicode_formatter_t *ctx, PyObject *str) { Py_ssize_t len; - enum PyUnicode_Kind kind; + int kind; const void *pbuf; Py_ssize_t pindex; Py_UCS4 signchar; @@ -15002,9 +14177,6 @@ unicode_format_arg_output(struct unicode_formatter_t *ctx, if (arg->sign && arg->flags & F_ZERO) fill = '0'; - if (PyUnicode_READY(str) == -1) - return -1; - len = PyUnicode_GET_LENGTH(str); if ((arg->width == -1 || arg->width <= len) && (arg->prec == -1 || arg->prec >= len) @@ -15306,15 +14478,12 @@ unicode_subtype_new(PyTypeObject *type, PyObject *unicode) { PyObject *self; Py_ssize_t length, char_size; - int share_wstr, share_utf8; - unsigned int kind; + int share_utf8; + int kind; void *data; assert(PyType_IsSubtype(type, &PyUnicode_Type)); assert(_PyUnicode_CHECK(unicode)); - if (PyUnicode_READY(unicode) == -1) { - return NULL; - } self = type->tp_alloc(type, 0); if (self == NULL) { @@ -15333,15 +14502,11 @@ unicode_subtype_new(PyTypeObject *type, PyObject *unicode) _PyUnicode_STATE(self).kind = kind; _PyUnicode_STATE(self).compact = 0; _PyUnicode_STATE(self).ascii = _PyUnicode_STATE(unicode).ascii; - _PyUnicode_STATE(self).ready = 1; - _PyUnicode_WSTR(self) = NULL; _PyUnicode_UTF8_LENGTH(self) = 0; _PyUnicode_UTF8(self) = NULL; - _PyUnicode_WSTR_LENGTH(self) = 0; _PyUnicode_DATA_ANY(self) = NULL; share_utf8 = 0; - share_wstr = 0; if (kind == PyUnicode_1BYTE_KIND) { char_size = 1; if (PyUnicode_MAX_CHAR_VALUE(unicode) < 128) @@ -15349,14 +14514,10 @@ unicode_subtype_new(PyTypeObject *type, PyObject *unicode) } else if (kind == PyUnicode_2BYTE_KIND) { char_size = 2; - if (sizeof(wchar_t) == 2) - share_wstr = 1; } else { assert(kind == PyUnicode_4BYTE_KIND); char_size = 4; - if (sizeof(wchar_t) == 4) - share_wstr = 1; } /* Ensure we won't overflow the length. */ @@ -15375,13 +14536,8 @@ unicode_subtype_new(PyTypeObject *type, PyObject *unicode) _PyUnicode_UTF8_LENGTH(self) = length; _PyUnicode_UTF8(self) = data; } - if (share_wstr) { - _PyUnicode_WSTR_LENGTH(self) = length; - _PyUnicode_WSTR(self) = (wchar_t *)data; - } - memcpy(data, PyUnicode_DATA(unicode), - kind * (length + 1)); + memcpy(data, PyUnicode_DATA(unicode), kind * (length + 1)); assert(_PyUnicode_CheckConsistency(self, 1)); #ifdef Py_DEBUG _PyUnicode_HASH(self) = _PyUnicode_HASH(unicode); @@ -15461,12 +14617,14 @@ PyTypeObject PyUnicode_Type = { /* Initialize the Unicode implementation */ -void -_PyUnicode_InitState(PyInterpreterState *interp) +static void +_init_global_state(void) { - if (!_Py_IsMainInterpreter(interp)) { + static int initialized = 0; + if (initialized) { return; } + initialized = 1; /* initialize the linebreak bloom filter */ const Py_UCS2 linebreak[] = { @@ -15484,21 +14642,42 @@ _PyUnicode_InitState(PyInterpreterState *interp) Py_ARRAY_LENGTH(linebreak)); } +void +_PyUnicode_InitState(PyInterpreterState *interp) +{ + if (!_Py_IsMainInterpreter(interp)) { + return; + } + _init_global_state(); +} + PyStatus _PyUnicode_InitGlobalObjects(PyInterpreterState *interp) { - if (!_Py_IsMainInterpreter(interp)) { - return _PyStatus_OK(); + // Initialize the global interned dict + if (init_interned_dict(interp)) { + PyErr_Clear(); + return _PyStatus_ERR("failed to create interned dict"); } + if (_Py_IsMainInterpreter(interp)) { + /* Intern statically allocated string identifiers and deepfreeze strings. + * This must be done before any module initialization so that statically + * allocated string identifiers are used instead of heap allocated strings. + * Deepfreeze uses the interned identifiers if present to save space + * else generates them and they are interned to speed up dict lookups. + */ + _PyUnicode_InitStaticStrings(interp); + #ifdef Py_DEBUG - assert(_PyUnicode_CheckConsistency(&_Py_STR(empty), 1)); + assert(_PyUnicode_CheckConsistency(&_Py_STR(empty), 1)); - for (int i = 0; i < 256; i++) { - assert(_PyUnicode_CheckConsistency(LATIN1(i), 1)); - } + for (int i = 0; i < 256; i++) { + assert(_PyUnicode_CheckConsistency(LATIN1(i), 1)); + } #endif + } return _PyStatus_OK(); } @@ -15507,17 +14686,13 @@ _PyUnicode_InitGlobalObjects(PyInterpreterState *interp) PyStatus _PyUnicode_InitTypes(PyInterpreterState *interp) { - if (!_Py_IsMainInterpreter(interp)) { - return _PyStatus_OK(); - } - - if (PyType_Ready(&EncodingMapType) < 0) { + if (_PyStaticType_InitBuiltin(interp, &EncodingMapType) < 0) { goto error; } - if (PyType_Ready(&PyFieldNameIter_Type) < 0) { + if (_PyStaticType_InitBuiltin(interp, &PyFieldNameIter_Type) < 0) { goto error; } - if (PyType_Ready(&PyFormatterIter_Type) < 0) { + if (_PyStaticType_InitBuiltin(interp, &PyFormatterIter_Type) < 0) { goto error; } return _PyStatus_OK(); @@ -15528,7 +14703,7 @@ error: void -PyUnicode_InternInPlace(PyObject **p) +_PyUnicode_InternInPlace(PyInterpreterState *interp, PyObject **p) { PyObject *s = *p; #ifdef Py_DEBUG @@ -15550,18 +14725,8 @@ PyUnicode_InternInPlace(PyObject **p) return; } - if (PyUnicode_READY(s) == -1) { - PyErr_Clear(); - return; - } - - if (interned == NULL) { - interned = PyDict_New(); - if (interned == NULL) { - PyErr_Clear(); /* Don't leave an exception */ - return; - } - } + PyObject *interned = get_interned_dict(interp); + assert(interned != NULL); PyObject *t = PyDict_SetDefault(interned, s, s); if (t == NULL) { @@ -15570,35 +14735,42 @@ PyUnicode_InternInPlace(PyObject **p) } if (t != s) { - Py_INCREF(t); - Py_SETREF(*p, t); + Py_SETREF(*p, Py_NewRef(t)); return; } - /* The two references in interned dict (key and value) are not counted by - refcnt. unicode_dealloc() and _PyUnicode_ClearInterned() take care of - this. */ - Py_SET_REFCNT(s, Py_REFCNT(s) - 2); - _PyUnicode_STATE(s).interned = SSTATE_INTERNED_MORTAL; + if (_Py_IsImmortal(s)) { + _PyUnicode_STATE(*p).interned = SSTATE_INTERNED_IMMORTAL_STATIC; + return; + } +#ifdef Py_REF_DEBUG + /* The reference count value excluding the 2 references from the + interned dictionary should be excluded from the RefTotal. The + decrements to these objects will not be registered so they + need to be accounted for in here. */ + for (Py_ssize_t i = 0; i < Py_REFCNT(s) - 2; i++) { + _Py_DecRefTotal(_PyInterpreterState_GET()); + } +#endif + _Py_SetImmortal(s); + _PyUnicode_STATE(*p).interned = SSTATE_INTERNED_IMMORTAL; } void -PyUnicode_InternImmortal(PyObject **p) +PyUnicode_InternInPlace(PyObject **p) { - if (PyErr_WarnEx(PyExc_DeprecationWarning, - "PyUnicode_InternImmortal() is deprecated; " - "use PyUnicode_InternInPlace() instead", 1) < 0) - { - // The function has no return value, the exception cannot - // be reported to the caller, so just log it. - PyErr_WriteUnraisable(NULL); - } + PyInterpreterState *interp = _PyInterpreterState_GET(); + _PyUnicode_InternInPlace(interp, p); +} +// Function kept for the stable ABI. +PyAPI_FUNC(void) PyUnicode_InternImmortal(PyObject **); +void +PyUnicode_InternImmortal(PyObject **p) +{ PyUnicode_InternInPlace(p); - if (PyUnicode_CHECK_INTERNED(*p) != SSTATE_INTERNED_IMMORTAL) { - _PyUnicode_STATE(*p).interned = SSTATE_INTERNED_IMMORTAL; - Py_INCREF(*p); - } + // Leak a reference on purpose + Py_INCREF(*p); } PyObject * @@ -15615,61 +14787,81 @@ PyUnicode_InternFromString(const char *cp) void _PyUnicode_ClearInterned(PyInterpreterState *interp) { - if (!_Py_IsMainInterpreter(interp)) { - // interned dict is shared by all interpreters - return; - } - + PyObject *interned = get_interned_dict(interp); if (interned == NULL) { return; } assert(PyDict_CheckExact(interned)); - /* Interned unicode strings are not forcibly deallocated; rather, we give - them their stolen references back, and then clear and DECREF the - interned dict. */ - + /* TODO: + * Currently, the runtime is not able to guarantee that it can exit without + * allocations that carry over to a future initialization of Python within + * the same process. i.e: + * ./python -X showrefcount -c 'import itertools' + * [237 refs, 237 blocks] + * + * Therefore, this should remain disabled for until there is a strict guarantee + * that no memory will be left after `Py_Finalize`. + */ +#ifdef Py_DEBUG + /* For all non-singleton interned strings, restore the two valid references + to that instance from within the intern string dictionary and let the + normal reference counting process clean up these instances. */ #ifdef INTERNED_STATS fprintf(stderr, "releasing %zd interned strings\n", PyDict_GET_SIZE(interned)); - Py_ssize_t immortal_size = 0, mortal_size = 0; + Py_ssize_t total_length = 0; #endif Py_ssize_t pos = 0; PyObject *s, *ignored_value; while (PyDict_Next(interned, &pos, &s, &ignored_value)) { assert(PyUnicode_IS_READY(s)); - + int shared = 0; switch (PyUnicode_CHECK_INTERNED(s)) { case SSTATE_INTERNED_IMMORTAL: - Py_SET_REFCNT(s, Py_REFCNT(s) + 1); -#ifdef INTERNED_STATS - immortal_size += PyUnicode_GET_LENGTH(s); -#endif - break; - case SSTATE_INTERNED_MORTAL: - // Restore the two references (key and value) ignored + // Skip the Immortal Instance check and restore + // the two references (key and value) ignored // by PyUnicode_InternInPlace(). - Py_SET_REFCNT(s, Py_REFCNT(s) + 2); + s->ob_refcnt = 2; #ifdef INTERNED_STATS - mortal_size += PyUnicode_GET_LENGTH(s); + total_length += PyUnicode_GET_LENGTH(s); #endif break; + case SSTATE_INTERNED_IMMORTAL_STATIC: + /* It is shared between interpreters, so we should unmark it + only when this is the last interpreter in which it's + interned. We immortalize all the statically initialized + strings during startup, so we can rely on the + main interpreter to be the last one. */ + if (!_Py_IsMainInterpreter(interp)) { + shared = 1; + } + break; + case SSTATE_INTERNED_MORTAL: + /* fall through */ case SSTATE_NOT_INTERNED: /* fall through */ default: Py_UNREACHABLE(); } - _PyUnicode_STATE(s).interned = SSTATE_NOT_INTERNED; + if (!shared) { + _PyUnicode_STATE(s).interned = SSTATE_NOT_INTERNED; + } } #ifdef INTERNED_STATS fprintf(stderr, - "total size of all interned strings: %zd/%zd mortal/immortal\n", - mortal_size, immortal_size); + "total length of all interned strings: %zd characters\n", + total_length); #endif - PyDict_Clear(interned); - Py_CLEAR(interned); + struct _Py_unicode_state *state = &interp->unicode; + struct _Py_unicode_ids *ids = &state->ids; + for (Py_ssize_t i=0; i < ids->size; i++) { + Py_XINCREF(ids->array[i]); + } +#endif /* Py_DEBUG */ + clear_interned_dict(interp); } @@ -15757,14 +14949,21 @@ PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list( static PyObject * unicodeiter_reduce(unicodeiterobject *it, PyObject *Py_UNUSED(ignored)) { + PyObject *iter = _PyEval_GetBuiltin(&_Py_ID(iter)); + + /* _PyEval_GetBuiltin can invoke arbitrary code, + * call must be before access of iterator pointers. + * see issue #101765 */ + if (it->it_seq != NULL) { - return Py_BuildValue("N(O)n", _PyEval_GetBuiltin(&_Py_ID(iter)), - it->it_seq, it->it_index); + return Py_BuildValue("N(O)n", iter, it->it_seq, it->it_index); } else { - PyObject *u = (PyObject *)_PyUnicode_New(0); - if (u == NULL) + PyObject *u = unicode_new_empty(); + if (u == NULL) { + Py_XDECREF(iter); return NULL; - return Py_BuildValue("N(N)", _PyEval_GetBuiltin(&_Py_ID(iter)), u); + } + return Py_BuildValue("N(N)", iter, u); } } @@ -15853,8 +15052,6 @@ unicode_iter(PyObject *seq) PyErr_BadInternalCall(); return NULL; } - if (PyUnicode_READY(seq) == -1) - return NULL; if (PyUnicode_IS_COMPACT_ASCII(seq)) { it = PyObject_GC_New(unicodeiterobject, &_PyUnicodeASCIIIter_Type); } @@ -15864,8 +15061,7 @@ unicode_iter(PyObject *seq) if (it == NULL) return NULL; it->it_index = 0; - Py_INCREF(seq); - it->it_seq = seq; + it->it_seq = Py_NewRef(seq); _PyObject_GC_TRACK(it); return (PyObject *)it; } @@ -15992,10 +15188,13 @@ init_fs_codec(PyInterpreterState *interp) /* Set Py_FileSystemDefaultEncoding and Py_FileSystemDefaultEncodeErrors global configuration variables. */ - if (_Py_SetFileSystemEncoding(fs_codec->encoding, - fs_codec->errors) < 0) { - PyErr_NoMemory(); - return -1; + if (_Py_IsMainInterpreter(interp)) { + + if (_Py_SetFileSystemEncoding(fs_codec->encoding, + fs_codec->errors) < 0) { + PyErr_NoMemory(); + return -1; + } } return 0; } @@ -16078,7 +15277,7 @@ _PyUnicode_EnableLegacyWindowsFSEncoding(void) static inline int unicode_is_finalizing(void) { - return (interned == NULL); + return (get_interned_dict(_PyInterpreterState_Main()) == NULL); } #endif @@ -16086,42 +15285,9 @@ unicode_is_finalizing(void) void _PyUnicode_FiniTypes(PyInterpreterState *interp) { - if (!_Py_IsMainInterpreter(interp)) { - return; - } - - _PyStaticType_Dealloc(&EncodingMapType); - _PyStaticType_Dealloc(&PyFieldNameIter_Type); - _PyStaticType_Dealloc(&PyFormatterIter_Type); -} - - -static void unicode_static_dealloc(PyObject *op) -{ - PyASCIIObject *ascii = _PyASCIIObject_CAST(op); - - assert(ascii->state.compact); - - if (ascii->state.ascii) { - if (ascii->wstr) { - PyObject_Free(ascii->wstr); - ascii->wstr = NULL; - } - } - else { - PyCompactUnicodeObject* compact = (PyCompactUnicodeObject*)op; - void* data = (void*)(compact + 1); - if (ascii->wstr && ascii->wstr != data) { - PyObject_Free(ascii->wstr); - ascii->wstr = NULL; - compact->wstr_length = 0; - } - if (compact->utf8) { - PyObject_Free(compact->utf8); - compact->utf8 = NULL; - compact->utf8_length = 0; - } - } + _PyStaticType_Dealloc(interp, &EncodingMapType); + _PyStaticType_Dealloc(interp, &PyFieldNameIter_Type); + _PyStaticType_Dealloc(interp, &PyFormatterIter_Type); } @@ -16130,35 +15296,18 @@ _PyUnicode_Fini(PyInterpreterState *interp) { struct _Py_unicode_state *state = &interp->unicode; - if (_Py_IsMainInterpreter(interp)) { - // _PyUnicode_ClearInterned() must be called before _PyUnicode_Fini() - assert(interned == NULL); - // bpo-47182: force a unicodedata CAPI capsule re-import on - // subsequent initialization of main interpreter. - ucnhash_capi = NULL; - } + // _PyUnicode_ClearInterned() must be called before _PyUnicode_Fini() + assert(get_interned_dict(interp) == NULL); _PyUnicode_FiniEncodings(&state->fs_codec); - unicode_clear_identifiers(state); - - // Clear the single character singletons - for (int i = 0; i < 128; i++) { - unicode_static_dealloc((PyObject*)&_Py_SINGLETON(strings).ascii[i]); - } - for (int i = 0; i < 128; i++) { - unicode_static_dealloc((PyObject*)&_Py_SINGLETON(strings).latin1[i]); - } -} - + // bpo-47182: force a unicodedata CAPI capsule re-import on + // subsequent initialization of interpreter. + interp->unicode.ucnhash_capi = NULL; -void -_PyStaticUnicode_Dealloc(PyObject *op) -{ - unicode_static_dealloc(op); + unicode_clear_identifiers(state); } - /* A _string module, to export formatter_parser and formatter_field_name_split to the string.Formatter class implemented in Python. */ @@ -16170,12 +15319,18 @@ static PyMethodDef _string_methods[] = { {NULL, NULL} }; +static PyModuleDef_Slot module_slots[] = { + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, + {0, NULL} +}; + static struct PyModuleDef _string_module = { PyModuleDef_HEAD_INIT, .m_name = "_string", .m_doc = PyDoc_STR("string helper module"), .m_size = 0, .m_methods = _string_methods, + .m_slots = module_slots, }; PyMODINIT_FUNC diff --git a/Objects/unicodetype_db.h b/Objects/unicodetype_db.h index fb8bb9fc..22f8243e 100644 --- a/Objects/unicodetype_db.h +++ b/Objects/unicodetype_db.h @@ -2,7 +2,6 @@ /* a list of unique character type descriptors */ const _PyUnicode_TypeRecord _PyUnicode_TypeRecords[] = { - {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 32}, {0, 0, 0, 0, 0, 48}, @@ -1783,508 +1782,74 @@ static const unsigned short index1[] = { 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 126, 127, 128, 129, 130, 131, 132, 34, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, - 143, 144, 145, 146, 147, 148, 149, 150, 34, 34, 151, 152, 153, 154, 155, - 156, 157, 158, 159, 160, 161, 162, 163, 143, 164, 165, 166, 167, 168, - 169, 170, 171, 172, 173, 174, 143, 175, 176, 143, 177, 178, 179, 180, - 143, 181, 182, 183, 184, 185, 186, 143, 143, 187, 188, 189, 190, 143, - 191, 143, 192, 34, 34, 34, 34, 34, 34, 34, 193, 194, 34, 195, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 196, 34, 34, 34, 34, 34, 34, 34, 34, 197, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 34, 34, 34, 34, 198, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 34, 34, 34, 34, 199, 200, 201, 202, 143, 143, 143, 143, 203, - 204, 205, 206, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 125, 143, 144, 145, 146, 147, 148, 149, 34, 34, 150, 151, 152, 153, 154, + 155, 156, 157, 158, 159, 160, 161, 162, 125, 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, 173, 125, 174, 175, 125, 176, 177, 178, 179, + 125, 180, 181, 182, 183, 184, 185, 186, 125, 187, 188, 189, 190, 125, + 191, 192, 193, 34, 34, 34, 34, 34, 34, 34, 194, 195, 34, 196, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 197, 34, 34, 34, 34, 34, 34, 34, 34, 198, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 34, 34, 34, 34, 199, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 34, 34, 34, 34, 200, 201, 202, 203, 125, 125, 125, 125, 204, + 205, 206, 207, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 207, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 208, 209, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 210, 34, 34, 211, 34, 34, 212, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 213, 214, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 215, 216, 64, 217, - 218, 219, 220, 221, 222, 143, 223, 224, 225, 226, 227, 228, 229, 230, 64, - 64, 64, 64, 231, 232, 143, 143, 143, 143, 143, 143, 143, 143, 233, 143, - 234, 143, 235, 143, 143, 236, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 237, 34, 238, 239, 143, 143, 143, 143, 143, 240, 241, 242, 143, 243, - 244, 143, 143, 245, 246, 247, 248, 249, 143, 64, 250, 64, 64, 64, 64, 64, - 251, 252, 253, 254, 255, 64, 64, 256, 257, 64, 258, 143, 143, 143, 143, - 143, 143, 143, 143, 259, 260, 261, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 86, 262, 34, 263, 264, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 208, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 209, 210, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 211, 34, 34, 212, 34, 34, 213, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 214, 215, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 216, 217, 64, 218, + 219, 220, 221, 222, 223, 125, 224, 225, 226, 227, 228, 229, 230, 231, 64, + 64, 64, 64, 232, 233, 125, 125, 125, 125, 125, 125, 125, 125, 234, 125, + 235, 236, 237, 125, 125, 238, 125, 125, 125, 239, 125, 125, 125, 125, + 125, 240, 34, 241, 242, 125, 125, 125, 125, 125, 243, 244, 245, 125, 246, + 247, 125, 125, 248, 249, 250, 251, 252, 125, 64, 253, 64, 64, 64, 64, 64, + 254, 255, 256, 257, 258, 64, 64, 259, 260, 64, 261, 125, 125, 125, 125, + 125, 125, 125, 125, 262, 263, 264, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 86, 265, 34, 266, 267, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 265, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 266, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 267, + 34, 34, 34, 34, 34, 34, 268, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 269, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 270, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 268, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 271, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 269, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 272, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 270, 34, 271, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 273, 34, 274, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 272, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 275, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 273, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 34, 265, 34, 34, 274, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 276, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 34, 268, 34, 34, 277, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 278, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 275, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 276, 143, 277, 278, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, 143, - 143, 143, 143, 143, 143, 143, 143, 143, 143, 125, 125, 125, 125, 125, + 34, 34, 34, 34, 34, 34, 279, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, @@ -2321,7 +1886,6 @@ static const unsigned short index1[] = { 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 279, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, @@ -2357,1864 +1921,2320 @@ static const unsigned short index1[] = { 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 279, -}; - -static const unsigned short index2[] = { - 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 3, 3, 3, 2, 4, 5, 5, 5, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 6, 5, - 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 6, 5, 5, 5, 5, 5, 5, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 5, 5, 5, 6, 18, 6, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 5, 5, - 5, 5, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 5, 5, 5, 5, 5, 5, 5, 6, 5, 20, 5, 5, - 21, 5, 6, 5, 5, 22, 23, 6, 24, 5, 25, 6, 26, 20, 5, 27, 27, 27, 5, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 5, 17, 17, 17, 17, 17, 17, 17, 28, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 5, 19, 19, 19, 19, 19, 19, 19, 29, 30, 31, 30, 31, 30, 31, 30, 31, 30, - 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, - 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, - 31, 30, 31, 32, 33, 30, 31, 30, 31, 30, 31, 20, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 34, 30, 31, 30, 31, 30, 31, 30, - 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, - 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, - 31, 30, 31, 35, 30, 31, 30, 31, 30, 31, 36, 37, 38, 30, 31, 30, 31, 39, - 30, 31, 40, 40, 30, 31, 20, 41, 42, 43, 30, 31, 40, 44, 45, 46, 47, 30, - 31, 48, 20, 46, 49, 50, 51, 30, 31, 30, 31, 30, 31, 52, 30, 31, 52, 20, - 20, 30, 31, 52, 30, 31, 53, 53, 30, 31, 30, 31, 54, 30, 31, 20, 55, 30, - 31, 20, 56, 55, 55, 55, 55, 57, 58, 59, 57, 58, 59, 57, 58, 59, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 60, 30, 31, 30, - 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 61, 57, 58, - 59, 30, 31, 62, 63, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, - 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, - 31, 30, 31, 30, 31, 30, 31, 30, 31, 64, 20, 30, 31, 30, 31, 30, 31, 30, - 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 20, 20, 20, 20, 20, 20, 65, - 30, 31, 66, 67, 68, 68, 30, 31, 69, 70, 71, 30, 31, 30, 31, 30, 31, 30, - 31, 30, 31, 72, 73, 74, 75, 76, 20, 77, 77, 20, 78, 20, 79, 80, 20, 20, - 20, 77, 81, 20, 82, 20, 83, 84, 20, 85, 86, 84, 87, 88, 20, 20, 86, 20, - 89, 90, 20, 20, 91, 20, 20, 20, 20, 20, 20, 20, 92, 20, 20, 93, 20, 94, - 93, 20, 20, 20, 95, 93, 96, 97, 97, 98, 20, 20, 20, 20, 20, 99, 20, 55, - 20, 20, 20, 20, 20, 20, 20, 20, 100, 101, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 102, 102, 102, 102, 102, 102, 102, - 102, 102, 103, 103, 103, 103, 103, 103, 103, 102, 102, 6, 6, 6, 6, 103, - 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 102, 102, 102, 102, 102, 6, 6, 6, 6, 6, 6, 6, - 103, 6, 103, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 104, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 30, 31, 30, 31, 103, 6, 30, 31, 0, 0, 105, 50, 50, 50, 5, 106, 0, - 0, 0, 0, 6, 6, 107, 25, 108, 108, 108, 0, 109, 0, 110, 110, 111, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 112, 113, 113, 113, 114, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 115, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 116, 117, 117, 118, 119, 120, 121, 121, 121, 122, 123, - 124, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, - 31, 30, 31, 30, 31, 30, 31, 125, 126, 127, 128, 129, 130, 5, 30, 31, 131, - 30, 31, 20, 64, 64, 64, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 133, - 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, - 133, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, - 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 5, - 25, 25, 25, 25, 25, 6, 6, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 134, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, - 31, 30, 31, 135, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 0, 136, 136, 136, 136, 136, 136, - 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, - 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, - 136, 136, 136, 136, 0, 0, 103, 5, 5, 5, 5, 5, 6, 20, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 138, 20, 5, 5, 0, 0, 5, 5, 5, 0, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 5, 25, 5, 25, 25, 5, 25, 25, 5, 25, 0, 0, 0, - 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 55, 55, - 55, 55, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 21, 21, 21, 21, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 5, - 21, 5, 5, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 103, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 7, 8, 9, 10, 11, 12, - 13, 14, 15, 16, 5, 5, 5, 5, 55, 55, 25, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 5, 55, 25, 25, 25, 25, 25, 25, 25, 21, 5, 25, 25, 25, 25, 25, 25, - 103, 103, 25, 25, 5, 25, 25, 25, 25, 55, 55, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 55, 55, 55, 5, 5, 55, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 0, 21, 55, 25, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 16, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 103, 103, 5, 5, 5, 5, 103, 0, 0, 25, - 5, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 25, 25, 25, 25, 103, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 103, 25, 25, 25, 103, 25, 25, 25, 25, 25, 0, 0, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, 25, 0, 0, - 5, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 6, 55, 55, 55, 55, 55, 55, 0, 21, 21, 0, 0, 0, 0, 0, 0, - 25, 25, 25, 25, 25, 25, 25, 25, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 103, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 21, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 18, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 25, 18, 25, 55, 18, 18, 18, 25, 25, 25, 25, 25, 25, 25, 25, 18, 18, 18, - 18, 25, 18, 18, 55, 25, 25, 25, 25, 25, 25, 25, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 25, 25, 5, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 5, - 103, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 18, - 18, 0, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 55, 55, 0, 0, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 0, 55, 55, 55, 55, 55, 55, 55, 0, 55, 0, 0, 0, 55, 55, 55, 55, 0, 0, - 25, 55, 18, 18, 18, 25, 25, 25, 25, 0, 0, 18, 18, 0, 0, 18, 18, 25, 55, - 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 55, 55, 0, 55, 55, 55, 25, 25, 0, - 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 55, 55, 5, 5, 27, 27, 27, 27, 27, - 27, 5, 5, 55, 5, 25, 0, 0, 25, 25, 18, 0, 55, 55, 55, 55, 55, 55, 0, 0, - 0, 0, 55, 55, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 0, 55, - 55, 0, 55, 55, 0, 55, 55, 0, 0, 25, 0, 18, 18, 18, 25, 25, 0, 0, 0, 0, - 25, 25, 0, 0, 25, 25, 25, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, - 55, 0, 55, 0, 0, 0, 0, 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 25, - 25, 55, 55, 55, 25, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 25, 18, 0, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, - 55, 55, 55, 55, 55, 55, 0, 55, 55, 0, 55, 55, 55, 55, 55, 0, 0, 25, 55, - 18, 18, 18, 25, 25, 25, 25, 25, 0, 25, 25, 18, 0, 18, 18, 25, 0, 0, 55, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 25, 25, 0, 0, 7, 8, - 9, 10, 11, 12, 13, 14, 15, 16, 5, 5, 0, 0, 0, 0, 0, 0, 0, 55, 25, 25, 25, - 25, 25, 25, 0, 25, 18, 18, 0, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 55, - 55, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 0, 55, - 55, 55, 55, 55, 0, 0, 25, 55, 18, 25, 18, 25, 25, 25, 25, 0, 0, 18, 18, - 0, 0, 18, 18, 25, 0, 0, 0, 0, 0, 0, 0, 25, 25, 18, 0, 0, 0, 0, 55, 55, 0, - 55, 55, 55, 25, 25, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 5, 55, 27, - 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 55, 0, 55, 55, 55, - 55, 55, 55, 0, 0, 0, 55, 55, 55, 0, 55, 55, 55, 55, 0, 0, 0, 55, 55, 0, - 55, 0, 55, 55, 0, 0, 0, 55, 55, 0, 0, 0, 55, 55, 55, 0, 0, 0, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 18, 18, 25, 18, 18, 0, 0, - 0, 18, 18, 18, 0, 18, 18, 18, 25, 0, 0, 55, 0, 0, 0, 0, 0, 0, 18, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 27, 27, 27, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 25, 18, 18, 18, 25, - 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 25, - 55, 25, 25, 25, 18, 18, 18, 18, 0, 25, 25, 25, 0, 25, 25, 25, 25, 0, 0, - 0, 0, 0, 0, 0, 25, 25, 0, 55, 55, 55, 0, 0, 55, 0, 0, 55, 55, 25, 25, 0, - 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 0, 5, 27, 27, - 27, 27, 27, 27, 27, 5, 55, 25, 18, 18, 5, 55, 55, 55, 55, 55, 55, 55, 55, - 0, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 0, 55, 55, 55, 55, 55, 0, 0, 25, 55, 18, 25, 18, 18, 18, 18, 18, - 0, 25, 18, 18, 0, 18, 18, 25, 25, 0, 0, 0, 0, 0, 0, 0, 18, 18, 0, 0, 0, - 0, 0, 0, 55, 55, 0, 55, 55, 25, 25, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 0, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 25, 18, 18, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 0, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 25, 25, 55, 18, 18, 18, 25, 25, 25, 25, 0, 18, 18, 18, 0, 18, 18, 18, 25, - 55, 5, 0, 0, 0, 0, 55, 55, 55, 18, 27, 27, 27, 27, 27, 27, 27, 55, 55, - 55, 25, 25, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 5, 55, 55, 55, 55, 55, 55, 0, 25, 18, 18, 0, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 0, - 0, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 25, 0, 0, 0, 0, 18, 18, 18, 25, - 25, 25, 0, 25, 0, 18, 18, 18, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 7, 8, - 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 18, 18, 5, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 55, 139, - 25, 25, 25, 25, 25, 25, 25, 0, 0, 0, 0, 5, 55, 55, 55, 55, 55, 55, 103, - 25, 25, 25, 25, 25, 25, 25, 25, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 0, 55, 0, 55, 55, - 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 0, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 25, 55, 139, 25, 25, 25, 25, 25, 25, 25, 25, 25, 55, 0, - 0, 55, 55, 55, 55, 55, 0, 103, 0, 25, 25, 25, 25, 25, 25, 0, 0, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 0, 0, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 55, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 25, 25, 5, 5, 5, 5, 5, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 5, 25, 5, 25, 5, 25, 5, 5, 5, 5, 18, 18, - 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 18, 25, 25, 25, 25, 25, 5, 25, 25, 55, - 55, 55, 55, 55, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 0, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 0, 5, 5, - 5, 5, 5, 5, 5, 5, 25, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 18, 18, 25, 25, 25, 25, 18, 25, 25, 25, 25, 25, 25, 18, 25, 25, 18, - 18, 25, 25, 55, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 5, 5, 5, 5, 5, 5, - 55, 55, 55, 55, 55, 55, 18, 18, 25, 25, 55, 55, 55, 55, 25, 25, 25, 55, - 18, 18, 18, 55, 55, 18, 18, 18, 18, 18, 18, 18, 55, 55, 55, 25, 25, 25, - 25, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 18, 18, 25, - 25, 18, 18, 18, 18, 18, 18, 25, 55, 18, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 18, 18, 18, 25, 5, 5, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, - 140, 0, 140, 0, 0, 0, 0, 0, 140, 0, 0, 141, 141, 141, 141, 141, 141, 141, - 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, - 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, 141, - 141, 141, 141, 141, 141, 141, 141, 141, 5, 103, 141, 141, 141, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 0, 55, 55, 55, 55, 0, 0, 55, 55, 55, 55, 55, 55, 55, 0, 55, 0, 55, - 55, 55, 55, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 0, 0, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 0, 0, - 55, 55, 55, 55, 55, 55, 55, 0, 55, 0, 55, 55, 55, 55, 0, 0, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, - 55, 55, 55, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, - 25, 25, 25, 5, 5, 5, 5, 5, 5, 5, 5, 5, 142, 143, 144, 145, 146, 147, 148, - 149, 150, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 151, 152, 153, 154, 155, 156, 157, 158, - 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, - 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, - 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, - 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, - 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, - 229, 230, 231, 232, 233, 234, 235, 236, 0, 0, 237, 238, 239, 240, 241, - 242, 0, 0, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 5, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 2, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 5, 5, 0, 0, 0, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 5, 5, 5, 243, 243, 243, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, - 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 25, 25, 25, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, - 18, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, - 0, 25, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, 18, 25, 25, 25, 25, 25, - 25, 25, 18, 18, 18, 18, 18, 18, 18, 18, 25, 18, 18, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 5, 5, 5, 103, 5, 5, 5, 5, 55, 25, 0, 0, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 25, 25, - 25, 21, 25, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 103, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, - 0, 0, 0, 0, 55, 55, 55, 55, 55, 244, 244, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 25, 55, 0, 0, 0, 0, 0, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 25, 25, 25, - 18, 18, 18, 18, 25, 25, 18, 18, 18, 0, 0, 0, 0, 18, 18, 25, 18, 18, 18, - 18, 18, 18, 25, 25, 25, 0, 0, 0, 0, 5, 0, 0, 0, 5, 5, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 16, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, - 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, - 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 142, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 25, 25, 18, 18, 25, 0, 0, 5, 5, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 18, 25, 18, 25, - 25, 25, 25, 25, 25, 25, 0, 25, 18, 25, 18, 18, 25, 25, 25, 25, 25, 25, - 25, 25, 18, 18, 18, 18, 18, 18, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 0, 0, 25, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 103, - 5, 5, 5, 5, 5, 5, 0, 0, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 6, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 25, 25, 25, 25, 18, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, - 18, 25, 25, 25, 25, 25, 18, 25, 18, 18, 18, 18, 18, 25, 18, 18, 55, 55, - 55, 55, 55, 55, 55, 55, 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 25, 25, 18, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 18, 25, 25, 25, 25, 18, 18, 25, 25, - 18, 25, 25, 25, 55, 55, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 25, 18, 25, 25, 18, 18, 18, 25, 18, 25, 25, 25, 18, - 18, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 18, 18, 18, 18, 18, 18, 18, 18, - 25, 25, 25, 25, 25, 25, 25, 25, 18, 18, 25, 25, 0, 0, 0, 5, 5, 5, 5, 5, - 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 55, 55, 55, 7, 8, 9, 10, - 11, 12, 13, 14, 15, 16, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 103, 103, 103, 103, 103, 103, 5, 5, 245, 246, 247, 248, 249, 250, 251, - 252, 253, 0, 0, 0, 0, 0, 0, 0, 254, 254, 254, 254, 254, 254, 254, 254, - 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, - 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, - 254, 254, 254, 254, 254, 254, 254, 0, 0, 254, 254, 254, 5, 5, 5, 5, 5, 5, - 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 25, 25, 25, 5, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 18, 25, 25, 25, 25, 25, 25, 25, 55, 55, 55, 55, - 25, 55, 55, 55, 55, 55, 55, 25, 55, 55, 18, 25, 25, 55, 0, 0, 0, 0, 0, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 102, 102, 102, 102, 102, 102, 102, 102, - 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, - 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, - 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, - 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 102, 255, 20, 20, 20, 256, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 257, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 102, 102, 102, 102, 102, 102, - 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, - 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, - 102, 102, 102, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 258, 259, 260, 261, 262, 263, 20, 20, 264, 20, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 265, 265, 265, 265, 265, 265, 265, 265, 266, 266, 266, 266, 266, - 266, 266, 266, 265, 265, 265, 265, 265, 265, 0, 0, 266, 266, 266, 266, - 266, 266, 0, 0, 265, 265, 265, 265, 265, 265, 265, 265, 266, 266, 266, - 266, 266, 266, 266, 266, 265, 265, 265, 265, 265, 265, 265, 265, 266, - 266, 266, 266, 266, 266, 266, 266, 265, 265, 265, 265, 265, 265, 0, 0, - 266, 266, 266, 266, 266, 266, 0, 0, 267, 265, 268, 265, 269, 265, 270, - 265, 0, 266, 0, 266, 0, 266, 0, 266, 265, 265, 265, 265, 265, 265, 265, - 265, 266, 266, 266, 266, 266, 266, 266, 266, 271, 271, 272, 272, 272, - 272, 273, 273, 274, 274, 275, 275, 276, 276, 0, 0, 277, 278, 279, 280, - 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, - 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, - 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, - 323, 324, 265, 265, 325, 326, 327, 0, 328, 329, 266, 266, 330, 330, 331, - 6, 332, 6, 6, 6, 333, 334, 335, 0, 336, 337, 338, 338, 338, 338, 339, 6, - 6, 6, 265, 265, 340, 341, 0, 0, 342, 343, 266, 266, 344, 344, 0, 6, 6, 6, - 265, 265, 345, 346, 347, 127, 348, 349, 266, 266, 350, 350, 131, 6, 6, 6, - 0, 0, 351, 352, 353, 0, 354, 355, 356, 356, 357, 357, 358, 6, 6, 0, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 21, 21, 21, 21, 21, 5, 5, 5, 5, 5, 5, 5, 5, 6, - 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 5, 5, 6, 3, 3, 21, 21, 21, 21, 21, 2, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 18, 18, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 18, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, - 21, 21, 21, 21, 21, 0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 359, 102, - 0, 0, 360, 361, 362, 363, 364, 365, 5, 5, 5, 5, 5, 102, 359, 26, 22, 23, - 360, 361, 362, 363, 364, 365, 5, 5, 5, 5, 5, 0, 102, 102, 102, 102, 102, - 102, 102, 102, 102, 102, 102, 102, 102, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 6, 6, 6, 6, 25, 6, 6, 6, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 5, 5, 121, 5, 5, 5, 5, 121, 5, 5, 20, 121, 121, 121, 20, 20, 121, 121, - 121, 20, 5, 121, 5, 5, 366, 121, 121, 121, 121, 121, 5, 5, 5, 5, 5, 5, - 121, 5, 367, 5, 121, 5, 368, 369, 121, 121, 366, 20, 121, 121, 370, 121, - 20, 55, 55, 55, 55, 20, 5, 5, 20, 20, 121, 121, 5, 5, 5, 5, 5, 121, 20, - 20, 20, 20, 5, 5, 5, 5, 371, 5, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, - 372, 372, 372, 372, 372, 372, 373, 373, 373, 373, 373, 373, 373, 373, - 373, 373, 373, 373, 373, 373, 373, 373, 243, 243, 243, 30, 31, 243, 243, - 243, 243, 27, 5, 5, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 22, 23, 360, 361, 362, 363, 364, 365, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 26, 22, 23, 360, 361, 362, - 363, 364, 365, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 26, 22, 23, - 360, 361, 362, 363, 364, 365, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, - 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 375, - 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, - 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, 359, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 26, 22, 23, 360, 361, 362, 363, 364, 365, 27, - 359, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 26, - 22, 23, 360, 361, 362, 363, 364, 365, 27, 26, 22, 23, 360, 361, 362, 363, - 364, 365, 27, 26, 22, 23, 360, 361, 362, 363, 364, 365, 27, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, - 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, - 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, - 136, 136, 136, 136, 136, 136, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 30, 31, 376, - 377, 378, 379, 380, 30, 31, 30, 31, 30, 31, 381, 382, 383, 384, 20, 30, - 31, 20, 30, 31, 20, 20, 20, 20, 20, 102, 102, 385, 385, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 20, 5, 5, 5, 5, 5, 5, 30, 31, 30, 31, 25, 25, 25, - 30, 31, 0, 0, 0, 0, 0, 5, 5, 5, 5, 27, 5, 5, 386, 386, 386, 386, 386, - 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, - 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, 386, - 386, 386, 386, 386, 386, 0, 386, 0, 0, 0, 0, 0, 386, 0, 0, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, - 0, 0, 0, 0, 0, 103, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 0, - 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, - 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, - 55, 0, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 0, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 387, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 2, 5, 5, 5, 5, 103, - 55, 243, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 243, 243, 243, 243, 243, 243, 243, 243, 243, 25, 25, 25, 25, - 18, 18, 5, 103, 103, 103, 103, 103, 5, 5, 243, 243, 243, 103, 55, 5, 5, - 5, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 25, 25, - 6, 6, 103, 103, 55, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 5, 103, 103, 103, 55, 0, 0, 0, 0, 0, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 5, 5, 27, 27, 27, 27, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 27, 27, 27, 27, 27, 27, 27, 27, 5, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 388, 55, 55, 388, 55, 55, 55, 388, 55, 388, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, - 55, 55, 55, 55, 55, 388, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 388, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 388, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 388, 55, 388, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 388, 55, 388, 388, 388, 55, 55, 55, 55, 55, 55, 388, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 388, 388, 388, 388, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 388, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 388, 388, 388, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, - 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 103, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 103, 103, 103, 103, 103, 103, 5, 5, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 103, 5, 5, 5, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 16, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, - 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, - 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 55, 25, 6, 6, 6, 5, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 5, 103, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 102, 102, 25, 25, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 25, 25, - 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 103, 103, 103, 103, 103, 103, 103, - 103, 103, 6, 6, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 20, 20, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 102, 20, 20, 20, 20, 20, 20, 20, - 20, 30, 31, 30, 31, 389, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 103, 6, - 6, 30, 31, 390, 20, 55, 30, 31, 30, 31, 391, 20, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 392, 393, 394, - 395, 392, 20, 396, 397, 398, 399, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, - 30, 31, 30, 31, 30, 31, 400, 401, 402, 30, 31, 30, 31, 0, 0, 0, 0, 0, 30, - 31, 0, 20, 0, 20, 30, 31, 30, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 103, 103, 103, 30, 31, 55, 102, 102, 20, - 55, 55, 55, 55, 55, 55, 55, 25, 55, 55, 55, 25, 55, 55, 55, 55, 25, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 18, 18, 25, 25, 18, 5, 5, 5, 5, 25, 0, 0, 0, 27, 27, 27, - 27, 27, 27, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 18, - 18, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 25, 25, 0, 0, 0, 0, - 0, 0, 0, 0, 5, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 55, 55, 55, 55, 55, 55, 5, 5, 5, 55, 5, 55, 55, 25, 7, 8, 9, 10, 11, 12, - 13, 14, 15, 16, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, 25, 25, - 25, 25, 25, 25, 5, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 25, 25, 25, 18, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 25, 18, 18, 25, 25, 25, 25, 18, 18, 25, 25, 18, - 18, 18, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 103, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 16, 0, 0, 0, 0, 5, 5, 55, 55, 55, 55, 55, 25, 103, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 55, - 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, 25, 25, 25, 25, 18, 18, - 25, 25, 18, 18, 25, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 25, 55, - 55, 55, 55, 55, 55, 55, 55, 25, 18, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 0, 0, 5, 5, 5, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 103, 55, 55, 55, 55, 55, 55, 5, 5, 5, 55, 18, 25, 18, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 55, 25, 25, 25, - 55, 55, 25, 25, 55, 55, 55, 55, 55, 25, 25, 55, 25, 55, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 103, 5, 5, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 18, 25, 25, 18, 18, 5, 5, 55, - 103, 103, 18, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, - 0, 0, 55, 55, 55, 55, 55, 55, 0, 0, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, - 0, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 403, 20, 20, 20, 20, 20, 20, 20, 6, 102, 102, 102, 102, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 103, 6, 6, 0, 0, 0, 0, 404, 405, 406, 407, 408, 409, - 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, - 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, - 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, - 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, - 480, 481, 482, 483, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 18, 18, 25, 18, 18, 25, 18, 18, 5, 18, 25, 0, 0, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, - 55, 55, 388, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 388, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 484, 485, 486, 487, 488, 489, - 490, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 491, 492, 493, 494, 495, 0, 0, - 0, 0, 0, 55, 25, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 5, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 0, 55, 0, - 55, 55, 0, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 496, 496, 496, 496, 496, 496, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 496, 496, 5, 5, 5, 5, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, - 0, 0, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 5, - 5, 5, 18, 18, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 18, 18, 18, 5, 5, 6, 0, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 0, 0, 0, 0, 496, 55, 496, 55, 496, 0, - 496, 55, 496, 55, 496, 55, 496, 55, 496, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 21, 0, 5, 5, 5, 5, 5, 5, 6, - 5, 5, 5, 5, 5, 5, 6, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 6, 5, 5, 5, - 5, 5, 5, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 5, 5, 5, 6, 18, 6, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 103, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 497, 497, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 55, 55, 55, 55, - 55, 55, 0, 0, 55, 55, 55, 55, 55, 55, 0, 0, 55, 55, 55, 55, 55, 55, 0, 0, - 55, 55, 55, 0, 0, 0, 5, 5, 5, 6, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 21, 5, 5, 0, 0, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, - 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, - 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 0, 0, 0, 0, 0, 5, 5, 5, 0, 0, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 27, 27, 27, 27, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 27, 27, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 243, 55, 55, 55, - 55, 55, 55, 55, 55, 243, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, 25, 25, 25, 0, 0, - 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 5, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, - 55, 55, 55, 55, 55, 55, 55, 55, 5, 243, 243, 243, 243, 243, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 498, 498, 498, 498, 498, 498, - 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, - 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, - 498, 498, 498, 498, 498, 498, 499, 499, 499, 499, 499, 499, 499, 499, - 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, - 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, - 499, 499, 499, 499, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 7, 8, 9, 10, 11, 12, - 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 498, 498, 498, 498, 498, 498, 498, 498, - 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, - 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 0, - 0, 0, 0, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, - 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, - 499, 499, 499, 499, 499, 499, 499, 499, 499, 0, 0, 0, 0, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 500, 500, 500, 500, - 500, 500, 500, 500, 500, 500, 500, 0, 500, 500, 500, 500, 500, 500, 500, - 500, 500, 500, 500, 500, 500, 500, 500, 0, 500, 500, 500, 500, 500, 500, - 500, 0, 500, 500, 0, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, - 501, 0, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, - 501, 501, 0, 501, 501, 501, 501, 501, 501, 501, 0, 501, 501, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, - 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 102, 103, 103, 102, 102, 102, 0, 102, 102, 102, 102, 102, 102, 102, - 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, - 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, - 102, 102, 102, 102, 102, 102, 102, 0, 102, 102, 102, 102, 102, 102, 102, - 102, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 55, 55, 55, 55, 55, 55, 0, 0, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, - 55, 55, 0, 0, 0, 55, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 5, 27, 27, 27, 27, 27, - 27, 27, 27, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 5, 5, 27, 27, 27, 27, 27, 27, 27, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 0, 0, 0, 0, 0, 27, 27, 27, 27, - 27, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 27, 27, 27, 27, 27, 27, 0, 0, 0, 5, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 0, 0, 0, 0, 27, 27, 55, 55, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 55, 25, 25, 25, 0, 25, 25, 0, 0, 0, 0, 0, 25, 25, 25, 25, 55, 55, - 55, 55, 0, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, - 25, 25, 25, 0, 0, 0, 0, 25, 26, 22, 23, 360, 27, 27, 27, 27, 27, 0, 0, 0, - 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 27, 27, 5, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, - 55, 55, 55, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, 0, 0, 0, - 0, 27, 27, 27, 27, 27, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 27, 27, 27, 27, 27, 27, - 27, 27, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 0, 0, 0, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, - 0, 0, 0, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 27, 27, 27, - 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 109, - 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, - 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, - 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, 109, - 109, 109, 109, 109, 109, 109, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, - 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, - 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, - 116, 116, 116, 116, 116, 116, 116, 116, 116, 0, 0, 0, 0, 0, 0, 0, 27, 27, - 27, 27, 27, 27, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 25, 25, 25, 25, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 26, 22, 23, 360, 361, 362, 363, 364, 365, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 0, 25, 25, 5, 0, 0, 55, 55, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 55, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 27, 27, 27, 27, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, 25, 25, 5, 5, 5, - 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 27, 27, 27, 27, - 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 25, 18, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, - 0, 26, 22, 23, 360, 361, 362, 363, 364, 365, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 25, 55, 55, 25, 25, - 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 25, 25, 18, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 18, 18, 18, 25, 25, 25, 25, 18, 18, 25, 25, 5, 5, 21, 5, 5, - 5, 5, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 0, 0, 0, 0, 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, - 0, 0, 25, 25, 25, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 25, 25, 25, 25, 25, 18, 25, 25, 25, 25, 25, 25, 25, 25, - 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 5, 5, 5, 5, 55, 18, 18, 55, 0, 0, - 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 25, 5, 5, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 25, 18, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 18, 18, 18, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 18, 18, 55, 55, 55, 55, 5, 5, 5, 5, 25, 25, 25, 25, 5, - 18, 25, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 55, 5, 55, 5, 5, 5, 0, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 18, - 18, 18, 25, 25, 25, 18, 18, 25, 18, 25, 25, 5, 5, 5, 5, 5, 5, 25, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, - 0, 55, 0, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 5, 0, 0, 0, 0, - 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 18, 18, 18, 25, 25, - 25, 25, 25, 25, 25, 25, 0, 0, 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 0, 0, 0, 0, 0, 0, 25, 25, 18, 18, 0, 55, 55, 55, 55, 55, 55, 55, 55, - 0, 0, 55, 55, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 0, 55, - 55, 0, 55, 55, 55, 55, 55, 0, 25, 25, 55, 18, 18, 25, 18, 18, 18, 18, 0, - 0, 18, 18, 0, 0, 18, 18, 18, 0, 0, 55, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, - 0, 55, 55, 55, 55, 55, 18, 18, 0, 0, 25, 25, 25, 25, 25, 25, 25, 0, 0, 0, - 25, 25, 25, 25, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 18, 18, 18, 25, 25, 25, - 25, 25, 25, 25, 25, 18, 18, 25, 25, 25, 18, 25, 55, 55, 55, 55, 5, 5, 5, - 5, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 5, 5, 0, 5, 25, 55, 55, 55, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 18, 18, - 18, 25, 25, 25, 25, 25, 25, 18, 25, 18, 18, 18, 18, 25, 25, 18, 25, 25, - 55, 55, 5, 55, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 18, 18, 18, 25, 25, 25, 25, 0, 0, 18, 18, 18, 18, 25, 25, - 18, 25, 25, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 55, 55, 55, 55, 25, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 18, 18, 18, 25, 25, 25, 25, 25, - 25, 25, 25, 18, 18, 25, 18, 25, 25, 5, 5, 5, 55, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 18, 25, 18, 18, 25, 25, - 25, 25, 25, 25, 18, 25, 55, 5, 0, 0, 0, 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 25, - 25, 25, 18, 18, 25, 25, 25, 25, 18, 25, 25, 25, 25, 25, 0, 0, 0, 0, 7, 8, - 9, 10, 11, 12, 13, 14, 15, 16, 27, 27, 5, 5, 5, 5, 55, 55, 55, 55, 55, - 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 18, 18, - 18, 25, 25, 25, 25, 25, 25, 25, 25, 25, 18, 25, 25, 5, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, - 55, 55, 55, 55, 55, 55, 55, 0, 0, 55, 0, 0, 55, 55, 55, 55, 55, 55, 55, - 55, 0, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 18, 18, 18, 18, 18, 18, 0, 18, - 18, 0, 0, 25, 25, 18, 25, 55, 18, 55, 18, 25, 5, 5, 5, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 0, - 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 18, 18, 18, 25, 25, 25, 25, 0, 0, 25, 25, 18, 18, 18, 18, - 25, 55, 5, 55, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 25, 25, 25, 25, 25, 25, 18, 55, 25, 25, 25, 25, 5, 5, 5, - 5, 5, 5, 5, 5, 25, 0, 0, 0, 0, 0, 0, 0, 0, 55, 25, 25, 25, 25, 25, 25, - 18, 18, 25, 25, 25, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 18, 25, 25, 5, 5, 5, 55, 5, 5, 5, - 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 18, 25, 25, 25, 25, 25, 25, 25, - 0, 25, 25, 25, 25, 25, 25, 18, 25, 55, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 5, 5, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 0, 18, - 25, 25, 25, 25, 25, 25, 25, 18, 25, 25, 18, 25, 25, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, - 55, 55, 0, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 25, 25, 25, 25, 25, 25, 0, 0, 0, 25, 0, 25, - 25, 0, 25, 25, 25, 25, 25, 25, 25, 55, 25, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, - 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, - 0, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 18, - 18, 18, 18, 18, 0, 25, 25, 0, 18, 18, 25, 18, 25, 55, 0, 0, 0, 0, 0, 0, - 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 25, 25, 18, 18, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 5, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 0, 5, 5, - 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 5, 5, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 5, 5, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 0, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 25, 25, 25, 25, 25, - 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 25, 25, 25, 25, 25, 25, 25, 5, 5, 5, 5, 5, 5, 5, 5, 5, 103, 103, - 103, 103, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 16, 0, 27, 27, 27, 27, 27, 27, 27, 0, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 25, 55, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 0, 0, 0, 0, 0, 0, 0, 25, 25, 25, 25, 103, 103, 103, 103, 103, 103, - 103, 103, 103, 103, 103, 103, 103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 103, 103, 5, 103, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 18, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 103, 103, 103, 103, 0, 103, 103, 103, 103, 103, 103, 103, - 0, 103, 103, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, - 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, - 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 5, 25, 25, 5, - 21, 21, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 0, 0, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 18, 18, 25, 25, 25, 5, 5, 5, 18, 18, 18, 18, 18, 18, 21, 21, - 21, 21, 21, 21, 21, 21, 25, 25, 25, 25, 25, 25, 25, 25, 5, 5, 25, 25, 25, - 25, 25, 25, 25, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 25, 25, 25, 25, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 25, 25, 25, - 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 20, 20, 20, - 20, 20, 20, 20, 0, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 121, 0, 121, 121, 0, 0, 121, 0, - 0, 121, 121, 0, 0, 121, 121, 121, 121, 0, 121, 121, 121, 121, 121, 121, - 121, 121, 20, 20, 20, 20, 0, 20, 0, 20, 20, 20, 20, 20, 20, 20, 0, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 121, 121, 0, - 121, 121, 121, 121, 0, 0, 121, 121, 121, 121, 121, 121, 121, 121, 0, 121, - 121, 121, 121, 121, 121, 121, 0, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 121, 121, - 0, 121, 121, 121, 121, 0, 121, 121, 121, 121, 121, 0, 121, 0, 0, 0, 121, - 121, 121, 121, 121, 121, 121, 0, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 5, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 5, 20, 20, 20, 20, - 20, 20, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 5, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 5, 20, 20, 20, 20, 20, 20, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 5, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 5, 20, 20, - 20, 20, 20, 20, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 5, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 5, 20, 20, 20, 20, 20, 20, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 5, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 5, 20, 20, 20, 20, 20, 20, 121, 20, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 5, 5, 5, 5, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 5, 5, 5, 5, 5, 5, 5, 5, 25, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 25, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 25, 25, 25, 25, 25, 0, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 55, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 25, 25, 25, 25, 25, 25, 25, 0, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 0, 0, 25, 25, 25, 25, 25, 25, - 25, 0, 25, 25, 0, 25, 25, 25, 25, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 25, 25, 25, 25, 25, 25, - 25, 103, 103, 103, 103, 103, 103, 103, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 0, 0, 0, 0, 55, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 25, 25, - 25, 25, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 0, 0, 0, 5, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, - 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 0, 55, 55, 0, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 25, 25, 25, 25, 25, 25, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, - 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, - 502, 502, 502, 502, 502, 502, 502, 503, 503, 503, 503, 503, 503, 503, - 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, - 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 25, 25, - 25, 25, 25, 25, 25, 103, 0, 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 0, 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 5, 27, 27, 27, 5, 27, 27, 27, 27, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 5, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 0, 55, 55, 0, 55, 0, 0, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 0, 55, 55, 55, 55, 0, 55, 0, 55, 0, 0, 0, 0, 0, 0, 55, 0, 0, 0, 0, - 55, 0, 55, 0, 55, 0, 55, 55, 55, 0, 55, 55, 0, 55, 0, 0, 55, 0, 55, 0, - 55, 0, 55, 0, 55, 0, 55, 55, 0, 55, 0, 0, 55, 55, 55, 55, 0, 55, 55, 55, - 55, 55, 55, 55, 0, 55, 55, 55, 55, 0, 55, 55, 55, 55, 0, 55, 0, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 55, 55, 55, 0, 55, 55, 55, - 55, 55, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 359, 359, 26, 22, 23, 360, 361, - 362, 363, 364, 365, 27, 27, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 504, 504, - 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, - 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 5, 5, 5, 5, 5, 5, 504, - 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, - 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 5, 5, 5, 5, 5, 5, - 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, - 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, - 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, - 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, - 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, - 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 5, 5, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 5, 5, 5, 5, 5, 0, - 0, 0, 5, 5, 5, 5, 5, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, - 0, 0, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, - 0, 0, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, - 0, 0, 0, 0, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, - 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 388, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 280, 125, 281, 282, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, +}; + +static const unsigned short index2[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 2, 2, 1, 3, 4, 4, 4, 4, 4, 4, 5, 4, 4, 4, 4, 4, 4, 5, 4, + 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 5, 4, 4, 4, 4, 4, 4, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 4, 4, 4, 5, 17, 5, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 4, 4, + 4, 4, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 4, 4, 4, 4, 4, 4, 5, 4, 19, 4, 4, + 20, 4, 5, 4, 4, 21, 22, 5, 23, 4, 24, 5, 25, 19, 4, 26, 26, 26, 4, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 4, 16, 16, 16, 16, 16, 16, 16, 27, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 4, 18, 18, 18, 18, 18, 18, 18, 28, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 31, 32, 29, 30, 29, 30, 29, 30, 19, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 33, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 34, 29, 30, 29, 30, 29, 30, 35, 36, 37, 29, 30, 29, 30, 38, + 29, 30, 39, 39, 29, 30, 19, 40, 41, 42, 29, 30, 39, 43, 44, 45, 46, 29, + 30, 47, 19, 45, 48, 49, 50, 29, 30, 29, 30, 29, 30, 51, 29, 30, 51, 19, + 19, 29, 30, 51, 29, 30, 52, 52, 29, 30, 29, 30, 53, 29, 30, 19, 54, 29, + 30, 19, 55, 54, 54, 54, 54, 56, 57, 58, 56, 57, 58, 56, 57, 58, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 59, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 60, 56, 57, + 58, 29, 30, 61, 62, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 63, 19, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 19, 19, 19, 19, 19, 19, 64, + 29, 30, 65, 66, 67, 67, 29, 30, 68, 69, 70, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 71, 72, 73, 74, 75, 19, 76, 76, 19, 77, 19, 78, 79, 19, 19, + 19, 76, 80, 19, 81, 19, 82, 83, 19, 84, 85, 83, 86, 87, 19, 19, 85, 19, + 88, 89, 19, 19, 90, 19, 19, 19, 19, 19, 19, 19, 91, 19, 19, 92, 19, 93, + 92, 19, 19, 19, 94, 92, 95, 96, 96, 97, 19, 19, 19, 19, 19, 98, 19, 54, + 19, 19, 19, 19, 19, 19, 19, 19, 99, 100, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 102, 102, 102, 102, 102, 102, 102, 101, 101, 5, 5, 5, 5, 102, + 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 101, 101, 101, 101, 101, 5, 5, 5, 5, 5, 5, 5, + 102, 5, 102, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 103, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 29, 30, 29, 30, 102, 5, 29, 30, 0, 0, 104, 49, 49, 49, 4, 105, 0, + 0, 0, 0, 5, 5, 106, 24, 107, 107, 107, 0, 108, 0, 109, 109, 110, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 111, 112, 112, 112, 113, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 114, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 115, 116, 116, 117, 118, 119, 120, 120, 120, 121, 122, + 123, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 124, 125, 126, 127, 128, 129, 4, 29, 30, 130, + 29, 30, 19, 63, 63, 63, 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 132, + 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 4, + 24, 24, 24, 24, 24, 5, 5, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 133, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 134, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 0, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 0, 0, 102, 4, 4, 4, 4, 4, 5, 19, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 137, 19, 4, 4, 0, 0, 4, 4, 4, 0, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 4, 24, 4, 24, 24, 4, 24, 24, 4, 24, 0, 0, 0, + 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 54, 54, + 54, 54, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 20, 20, 20, 20, 20, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 4, + 20, 4, 4, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 102, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 4, 4, 4, 4, 54, 54, 24, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 4, 54, 24, 24, 24, 24, 24, 24, 24, 20, 4, 24, 24, 24, 24, 24, 24, + 102, 102, 24, 24, 4, 24, 24, 24, 24, 54, 54, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 54, 54, 54, 4, 4, 54, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 0, 20, 54, 24, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 102, 102, 4, 4, 4, 4, 102, 0, 0, 24, 4, + 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 24, 24, 24, 24, 102, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 102, 24, 24, 24, 102, 24, 24, 24, 24, 24, 0, 0, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, 24, 24, 0, 0, + 4, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 5, 54, 54, 54, 54, 54, 54, 0, 20, 20, 0, 0, 0, 0, 0, 0, + 24, 24, 24, 24, 24, 24, 24, 24, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 102, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 20, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 17, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 24, 17, 24, 54, 17, 17, 17, 24, 24, 24, 24, 24, 24, 24, 24, 17, 17, 17, + 17, 24, 17, 17, 54, 24, 24, 24, 24, 24, 24, 24, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 24, 24, 4, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 4, 102, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, 17, 17, + 0, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 54, 54, 0, 0, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 0, 54, 54, 54, 54, 54, 54, 54, 0, 54, 0, 0, 0, 54, 54, 54, 54, 0, 0, 24, + 54, 17, 17, 17, 24, 24, 24, 24, 0, 0, 17, 17, 0, 0, 17, 17, 24, 54, 0, 0, + 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 54, 54, 0, 54, 54, 54, 24, 24, 0, 0, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 54, 54, 4, 4, 26, 26, 26, 26, 26, 26, 4, + 4, 54, 4, 24, 0, 0, 24, 24, 17, 0, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, + 54, 54, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 0, + 54, 54, 0, 54, 54, 0, 0, 24, 0, 17, 17, 17, 24, 24, 0, 0, 0, 0, 24, 24, + 0, 0, 24, 24, 24, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 0, + 54, 0, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 24, 24, 54, + 54, 54, 24, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 24, 17, 0, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, + 54, 54, 54, 54, 0, 54, 54, 0, 54, 54, 54, 54, 54, 0, 0, 24, 54, 17, 17, + 17, 24, 24, 24, 24, 24, 0, 24, 24, 17, 0, 17, 17, 24, 0, 0, 54, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 24, 24, 0, 0, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 4, 4, 0, 0, 0, 0, 0, 0, 0, 54, 24, 24, 24, 24, 24, + 24, 0, 24, 17, 17, 0, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 54, 54, 0, 0, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 0, 54, 54, 54, + 54, 54, 0, 0, 24, 54, 17, 24, 17, 24, 24, 24, 24, 0, 0, 17, 17, 0, 0, 17, + 17, 24, 0, 0, 0, 0, 0, 0, 0, 24, 24, 17, 0, 0, 0, 0, 54, 54, 0, 54, 54, + 54, 24, 24, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 4, 54, 26, 26, 26, + 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 54, 0, 54, 54, 54, 54, 54, + 54, 0, 0, 0, 54, 54, 54, 0, 54, 54, 54, 54, 0, 0, 0, 54, 54, 0, 54, 0, + 54, 54, 0, 0, 0, 54, 54, 0, 0, 0, 54, 54, 54, 0, 0, 0, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 17, 17, 24, 17, 17, 0, 0, 0, + 17, 17, 17, 0, 17, 17, 17, 24, 0, 0, 54, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 26, + 26, 26, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 24, 17, 17, 17, 24, 54, + 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 24, 54, + 24, 24, 24, 17, 17, 17, 17, 0, 24, 24, 24, 0, 24, 24, 24, 24, 0, 0, 0, 0, + 0, 0, 0, 24, 24, 0, 54, 54, 54, 0, 0, 54, 0, 0, 54, 54, 24, 24, 0, 0, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 4, 26, 26, 26, 26, + 26, 26, 26, 4, 54, 24, 17, 17, 4, 54, 54, 54, 54, 54, 54, 54, 54, 0, 54, + 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 0, 54, 54, 54, 54, 54, 0, 0, 24, 54, 17, 24, 17, 17, 17, 17, 17, 0, + 24, 17, 17, 0, 17, 17, 24, 24, 0, 0, 0, 0, 0, 0, 0, 17, 17, 0, 0, 0, 0, + 0, 0, 54, 54, 0, 54, 54, 24, 24, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 0, 54, 54, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 24, 17, 17, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, 0, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 24, 24, 54, 17, 17, 17, 24, 24, 24, 24, 0, 17, 17, 17, 0, 17, 17, 17, 24, + 54, 4, 0, 0, 0, 0, 54, 54, 54, 17, 26, 26, 26, 26, 26, 26, 26, 54, 54, + 54, 24, 24, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 4, 54, 54, 54, 54, 54, 54, 0, 24, 17, 17, 0, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 54, 0, 0, + 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 24, 0, 0, 0, 0, 17, 17, 17, 24, 24, + 24, 0, 24, 0, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 0, 0, 17, 17, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, 54, 138, 24, 24, + 24, 24, 24, 24, 24, 0, 0, 0, 0, 4, 54, 54, 54, 54, 54, 54, 102, 24, 24, + 24, 24, 24, 24, 24, 24, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 4, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 0, 54, 0, 54, 54, 54, 54, 54, + 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 0, 54, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 24, 54, 138, 24, 24, 24, 24, 24, 24, 24, 24, 24, 54, 0, 0, 54, 54, + 54, 54, 54, 0, 102, 0, 24, 24, 24, 24, 24, 24, 24, 0, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 0, 0, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 24, 24, 4, 4, + 4, 4, 4, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 4, 24, 4, 24, 4, 24, 4, 4, 4, 4, 17, 17, 54, 54, 54, 54, + 54, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 0, 0, 0, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 17, 24, 24, 24, 24, 24, 4, 24, 24, 54, 54, 54, 54, 54, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 4, 4, 4, 4, 4, 4, 4, + 4, 24, 4, 4, 4, 4, 4, 4, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 17, 17, 24, + 24, 24, 24, 17, 24, 24, 24, 24, 24, 24, 17, 24, 24, 17, 17, 24, 24, 54, + 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 4, 4, 4, 4, 4, 4, 54, 54, 54, 54, 54, + 54, 17, 17, 24, 24, 54, 54, 54, 54, 24, 24, 24, 54, 17, 17, 17, 54, 54, + 17, 17, 17, 17, 17, 17, 17, 54, 54, 54, 24, 24, 24, 24, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, 17, 17, 24, 24, 17, 17, 17, 17, + 17, 17, 24, 54, 17, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 17, 17, 17, 24, + 4, 4, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, + 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, + 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, 0, 139, 0, 0, 0, + 0, 0, 139, 0, 0, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 4, 101, 140, 140, 140, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, + 54, 0, 0, 54, 54, 54, 54, 54, 54, 54, 0, 54, 0, 54, 54, 54, 54, 0, 0, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 0, 54, 54, 54, 54, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, 54, 0, 0, 54, 54, 54, 54, 54, + 54, 54, 0, 54, 0, 54, 54, 54, 54, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, 54, 0, 0, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 24, 24, 24, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 141, 142, 143, 144, 145, 146, 147, 148, 149, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, + 0, 0, 0, 0, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, + 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, + 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, + 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, + 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, + 232, 233, 234, 235, 0, 0, 236, 237, 238, 239, 240, 241, 0, 0, 4, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 4, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 1, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 4, 4, 0, 0, 0, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 4, 4, 4, + 242, 242, 242, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, + 24, 24, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, 24, 17, 4, 4, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 24, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, 0, 24, 24, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 24, 24, 17, 24, 24, 24, 24, 24, 24, 24, 17, 17, 17, + 17, 17, 17, 17, 17, 24, 17, 17, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 4, 4, 4, 102, 4, 4, 4, 4, 54, 24, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, + 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 24, 24, 24, 20, 24, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 102, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, + 54, 54, 243, 243, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 24, 54, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 0, 24, 24, 24, 17, 17, 17, 17, 24, 24, + 17, 17, 17, 0, 0, 0, 0, 17, 17, 24, 17, 17, 17, 17, 17, 17, 24, 24, 24, + 0, 0, 0, 0, 4, 0, 0, 0, 4, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 54, 54, 54, 54, 54, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 141, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 24, 24, 17, 17, 24, 0, 0, 4, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 17, 24, 17, 24, 24, 24, 24, 24, 24, 24, 0, + 24, 17, 24, 17, 17, 24, 24, 24, 24, 24, 24, 24, 24, 17, 17, 17, 17, 17, + 17, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, 24, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, + 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 102, 4, 4, 4, 4, 4, 4, 0, 0, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 5, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 24, 24, 24, 17, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, 17, 24, 24, 24, 24, 24, 17, 24, + 17, 17, 17, 17, 17, 24, 17, 17, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, + 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 24, 24, 24, 24, 24, 24, 24, 24, 24, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 0, 24, 24, 17, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 17, 24, 24, 24, 24, 17, 17, 24, 24, 17, 24, 24, 24, 54, 54, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, 17, 24, + 24, 17, 17, 17, 24, 17, 24, 24, 24, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, + 4, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 17, 17, 17, 17, 17, 17, 17, 17, 24, 24, 24, 24, 24, 24, 24, 24, 17, + 17, 24, 24, 0, 0, 0, 4, 4, 4, 4, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 0, 0, 0, 54, 54, 54, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 102, 102, 102, 102, 102, 102, 4, 4, 244, + 245, 246, 247, 248, 249, 250, 251, 252, 0, 0, 0, 0, 0, 0, 0, 253, 253, + 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, + 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, + 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 0, 0, + 253, 253, 253, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 24, 24, + 24, 4, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 17, 24, 24, + 24, 24, 24, 24, 24, 54, 54, 54, 54, 24, 54, 54, 54, 54, 54, 54, 24, 54, + 54, 17, 24, 24, 54, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 101, 254, 19, 19, 19, 255, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 256, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 257, 258, 259, 260, 261, 262, 19, + 19, 263, 19, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 264, 264, 264, 264, 264, 264, 264, + 264, 265, 265, 265, 265, 265, 265, 265, 265, 264, 264, 264, 264, 264, + 264, 0, 0, 265, 265, 265, 265, 265, 265, 0, 0, 264, 264, 264, 264, 264, + 264, 264, 264, 265, 265, 265, 265, 265, 265, 265, 265, 264, 264, 264, + 264, 264, 264, 264, 264, 265, 265, 265, 265, 265, 265, 265, 265, 264, + 264, 264, 264, 264, 264, 0, 0, 265, 265, 265, 265, 265, 265, 0, 0, 266, + 264, 267, 264, 268, 264, 269, 264, 0, 265, 0, 265, 0, 265, 0, 265, 264, + 264, 264, 264, 264, 264, 264, 264, 265, 265, 265, 265, 265, 265, 265, + 265, 270, 270, 271, 271, 271, 271, 272, 272, 273, 273, 274, 274, 275, + 275, 0, 0, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, + 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, + 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, + 316, 317, 318, 319, 320, 321, 322, 323, 264, 264, 324, 325, 326, 0, 327, + 328, 265, 265, 329, 329, 330, 5, 331, 5, 5, 5, 332, 333, 334, 0, 335, + 336, 337, 337, 337, 337, 338, 5, 5, 5, 264, 264, 339, 340, 0, 0, 341, + 342, 265, 265, 343, 343, 0, 5, 5, 5, 264, 264, 344, 345, 346, 126, 347, + 348, 265, 265, 349, 349, 130, 5, 5, 5, 0, 0, 350, 351, 352, 0, 353, 354, + 355, 355, 356, 356, 357, 5, 5, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 20, + 20, 20, 20, 20, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 5, 4, 4, 5, 2, 2, 20, 20, 20, 20, 20, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 17, 17, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 17, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 20, 20, 20, 20, 20, 0, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 358, 101, 0, 0, 359, 360, 361, 362, 363, + 364, 4, 4, 4, 4, 4, 101, 358, 25, 21, 22, 359, 360, 361, 362, 363, 364, + 4, 4, 4, 4, 4, 0, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 5, + 5, 5, 5, 24, 5, 5, 5, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 120, 4, 4, 4, 4, 120, 4, + 4, 19, 120, 120, 120, 19, 19, 120, 120, 120, 19, 4, 120, 4, 4, 365, 120, + 120, 120, 120, 120, 4, 4, 4, 4, 4, 4, 120, 4, 366, 4, 120, 4, 367, 368, + 120, 120, 365, 19, 120, 120, 369, 120, 19, 54, 54, 54, 54, 19, 4, 4, 19, + 19, 120, 120, 4, 4, 4, 4, 4, 120, 19, 19, 19, 19, 4, 4, 4, 4, 370, 4, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 371, 371, + 371, 371, 371, 371, 371, 371, 371, 371, 371, 371, 371, 371, 371, 371, + 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, + 372, 372, 242, 242, 242, 29, 30, 242, 242, 242, 242, 26, 4, 4, 0, 0, 0, + 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 25, 21, 22, 359, 360, 361, 362, 363, 364, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 25, 21, 22, 359, 360, 361, 362, 363, 364, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 25, 21, 22, 359, 360, 361, 362, 363, 364, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 373, 373, 373, 373, 373, + 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, + 373, 373, 373, 373, 373, 373, 373, 374, 374, 374, 374, 374, 374, 374, + 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, + 374, 374, 374, 374, 374, 358, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 25, + 21, 22, 359, 360, 361, 362, 363, 364, 26, 358, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 25, 21, 22, 359, 360, 361, 362, + 363, 364, 26, 25, 21, 22, 359, 360, 361, 362, 363, 364, 26, 25, 21, 22, + 359, 360, 361, 362, 363, 364, 26, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 135, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 29, 30, 375, 376, 377, 378, 379, 29, + 30, 29, 30, 29, 30, 380, 381, 382, 383, 19, 29, 30, 19, 29, 30, 19, 19, + 19, 19, 19, 101, 101, 384, 384, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 19, 4, 4, 4, 4, 4, 4, 29, 30, 29, 30, 24, 24, 24, 29, 30, 0, 0, 0, 0, 0, + 4, 4, 4, 4, 26, 4, 4, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, + 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, + 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 0, + 385, 0, 0, 0, 0, 0, 385, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 102, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, + 54, 0, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, 0, 54, + 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, 54, + 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, 0, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 386, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 0, 0, 0, 0, 1, 4, 4, 4, 4, 102, 54, 242, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 242, 242, 242, + 242, 242, 242, 242, 242, 242, 24, 24, 24, 24, 17, 17, 4, 102, 102, 102, + 102, 102, 4, 4, 242, 242, 242, 102, 54, 4, 4, 4, 0, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 24, 24, 5, 5, 102, 102, 54, 4, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 4, 102, 102, 102, 54, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 0, 4, 4, 26, 26, 26, 26, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 26, 26, 26, 26, 26, 26, + 26, 26, 4, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 54, 54, + 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 387, 54, 54, 387, 54, 54, 54, 387, + 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 387, 54, 387, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 387, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 387, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 387, 54, + 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 387, 387, 387, + 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 387, + 387, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, + 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 387, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 387, 387, 54, 387, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 387, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, + 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 102, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, + 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 102, + 102, 102, 102, 102, 102, 4, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 102, 4, 4, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 54, 54, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, + 29, 30, 54, 24, 5, 5, 5, 4, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 4, + 102, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 101, 101, 24, 24, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 242, 242, 242, 242, + 242, 242, 242, 242, 242, 242, 24, 24, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, + 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 102, 102, 102, 102, 102, 102, 102, 102, 102, 5, 5, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 19, 19, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 101, 19, 19, 19, 19, 19, 19, 19, 19, 29, 30, 29, 30, 388, 29, 30, 29, + 30, 29, 30, 29, 30, 29, 30, 102, 5, 5, 29, 30, 389, 19, 54, 29, 30, 29, + 30, 390, 19, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, + 30, 29, 30, 29, 30, 391, 392, 393, 394, 391, 19, 395, 396, 397, 398, 29, + 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 399, 400, + 401, 29, 30, 29, 30, 0, 0, 0, 0, 0, 29, 30, 0, 19, 0, 19, 29, 30, 29, 30, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 101, 101, 101, 29, 30, 54, 101, 101, 19, 54, 54, 54, 54, 54, 54, 54, 24, + 54, 54, 54, 24, 54, 54, 54, 54, 24, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 17, 17, 24, 24, + 17, 4, 4, 4, 4, 24, 0, 0, 0, 26, 26, 26, 26, 26, 26, 4, 4, 4, 4, 0, 0, 0, + 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 24, 24, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 54, 54, 54, 54, 54, 54, 4, 4, 4, 54, + 4, 54, 54, 24, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 24, 24, 24, 24, 24, 24, 24, 24, 4, 4, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 17, 17, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 24, + 24, 24, 17, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, 17, 17, 24, + 24, 24, 24, 17, 17, 24, 24, 17, 17, 17, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 0, 102, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 4, 4, 54, + 54, 54, 54, 54, 24, 102, 54, 54, 54, 54, 54, 54, 54, 54, 54, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 54, 54, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, + 24, 24, 24, 24, 24, 17, 17, 24, 24, 17, 17, 24, 24, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 54, 54, 54, 24, 54, 54, 54, 54, 54, 54, 54, 54, 24, 17, 0, 0, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 4, 4, 4, 4, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 102, 54, 54, 54, 54, 54, 54, 4, + 4, 4, 54, 17, 24, 17, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 24, 54, 24, 24, 24, 54, 54, 24, 24, 54, 54, 54, 54, 54, 24, 24, 54, + 24, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 54, 54, 102, 4, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 17, + 24, 24, 17, 17, 4, 4, 54, 102, 102, 17, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 54, 54, 54, 54, 54, 0, 0, 54, 54, 54, 54, 54, 54, 0, 0, 54, 54, 54, + 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 0, 54, + 54, 54, 54, 54, 54, 54, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 402, 19, 19, 19, 19, 19, 19, 19, 5, 101, 101, + 101, 101, 19, 19, 19, 19, 19, 19, 19, 19, 19, 101, 5, 5, 0, 0, 0, 0, 403, + 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, + 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, + 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, + 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, + 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, + 474, 475, 476, 477, 478, 479, 480, 481, 482, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 17, 17, 24, 17, 17, 24, 17, 17, + 4, 17, 24, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 387, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 387, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 483, 484, 485, 486, 487, 488, 489, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 490, 491, 492, 493, 494, 0, 0, 0, 0, 0, 54, 24, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 0, 54, 54, 54, 54, 54, 0, 54, 0, 54, 54, 0, 54, 54, 0, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 495, + 495, 495, 495, 495, 495, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 4, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 495, 495, + 4, 4, 4, 4, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 4, 4, 4, 5, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 4, 4, 4, 17, 17, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 17, 17, 17, + 4, 4, 5, 0, 4, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, + 4, 4, 4, 4, 0, 0, 0, 0, 495, 54, 495, 54, 495, 0, 495, 54, 495, 54, 495, + 54, 495, 54, 495, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 0, 0, 20, 0, 4, 4, 4, 4, 4, 4, 5, 4, 4, 4, 4, 4, 4, 5, 4, + 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 5, 4, 4, 4, 4, 4, 4, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 4, 4, 4, 5, 17, 5, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 102, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 496, 496, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 0, 0, 0, 54, 54, 54, 54, 54, 54, 0, 0, 54, 54, + 54, 54, 54, 54, 0, 0, 54, 54, 54, 54, 54, 54, 0, 0, 54, 54, 54, 0, 0, 0, + 4, 4, 4, 5, 4, 4, 4, 0, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 20, 20, 20, 4, 4, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 0, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 4, 4, + 4, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, + 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, + 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, + 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 26, + 26, 26, 26, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 26, 26, 4, + 4, 4, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 4, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 24, 0, 0, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 242, 54, 54, 54, 54, 54, 54, 54, 54, 242, 0, 0, 0, 0, 0, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, + 24, 24, 24, 24, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 0, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 4, 242, 242, 242, + 242, 242, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 497, 497, + 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, + 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, + 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 498, 498, 498, 498, + 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, + 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, + 498, 498, 498, 498, 498, 498, 498, 498, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 497, 497, 497, 497, + 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, + 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, 497, + 497, 497, 497, 497, 0, 0, 0, 0, 498, 498, 498, 498, 498, 498, 498, 498, + 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, + 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, 0, + 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 4, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 0, 499, 499, + 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 0, 499, + 499, 499, 499, 499, 499, 499, 0, 499, 499, 0, 500, 500, 500, 500, 500, + 500, 500, 500, 500, 500, 500, 0, 500, 500, 500, 500, 500, 500, 500, 500, + 500, 500, 500, 500, 500, 500, 500, 0, 500, 500, 500, 500, 500, 500, 500, + 0, 500, 500, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 101, 102, 102, 101, 101, 101, 0, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 0, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 0, 0, 54, 0, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 0, 54, 54, 0, 0, 0, 54, 0, 0, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 4, + 26, 26, 26, 26, 26, 26, 26, 26, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 4, 4, 26, 26, 26, 26, + 26, 26, 26, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, + 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 0, 0, + 0, 0, 0, 26, 26, 26, 26, 26, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 26, 26, 26, 26, 26, 26, 0, 0, + 0, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 26, 26, 54, 54, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 54, 24, 24, 24, 0, 24, 24, 0, 0, 0, 0, 0, 24, + 24, 24, 24, 54, 54, 54, 54, 0, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 0, 0, 24, 24, 24, 0, 0, 0, 0, 24, 25, 21, 22, 359, 26, + 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, + 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 26, 26, 4, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 54, 54, 54, 54, 54, 54, 54, 54, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 24, 24, 0, 0, 0, 0, 26, 26, 26, 26, 26, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 26, 26, + 26, 26, 26, 26, 26, 26, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, + 26, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, + 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, + 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, + 108, 108, 108, 108, 108, 108, 108, 108, 108, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 0, 0, 0, 0, 0, 0, + 0, 26, 26, 26, 26, 26, 26, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 24, 24, 24, 24, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 25, 21, 22, 359, 360, 361, 362, 363, 364, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 24, 24, 4, 0, 0, 54, 54, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 24, 24, 24, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 54, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 26, 26, 26, 26, 4, 4, 4, 4, 4, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, 24, + 24, 24, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 24, + 17, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 4, 4, 4, 4, + 4, 4, 4, 0, 0, 0, 0, 25, 21, 22, 359, 360, 361, 362, 363, 364, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 24, 54, 54, 24, 24, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 24, 24, 17, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 17, 17, 17, 24, 24, 24, 24, 17, 17, 24, + 24, 4, 4, 20, 4, 4, 4, 4, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 0, 0, 0, 0, 0, 0, 24, 24, 24, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, 24, 24, 24, 24, 17, 24, 24, 24, + 24, 24, 24, 24, 24, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 4, 4, 4, 4, + 54, 17, 17, 54, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, 4, 4, 54, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 24, 24, 17, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 17, 17, + 17, 24, 24, 24, 24, 24, 24, 24, 24, 24, 17, 17, 54, 54, 54, 54, 4, 4, 4, + 4, 24, 24, 24, 24, 4, 17, 24, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 54, 4, + 54, 4, 4, 4, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 17, 17, 17, 24, 24, 24, 17, 17, 24, 17, 24, 24, 4, 4, 4, + 4, 4, 4, 24, 54, 54, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, + 54, 54, 54, 54, 54, 0, 54, 0, 54, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 4, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 24, 17, 17, 17, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, 0, 0, 0, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 24, 24, 17, 17, 0, 54, 54, + 54, 54, 54, 54, 54, 54, 0, 0, 54, 54, 0, 0, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, + 54, 54, 54, 54, 54, 0, 54, 54, 0, 54, 54, 54, 54, 54, 0, 24, 24, 54, 17, + 17, 24, 17, 17, 17, 17, 0, 0, 17, 17, 0, 0, 17, 17, 17, 0, 0, 54, 0, 0, + 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 17, 17, 0, 0, 24, 24, + 24, 24, 24, 24, 24, 0, 0, 0, 24, 24, 24, 24, 24, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 17, 17, 17, 24, 24, 24, 24, 24, 24, 24, 24, 17, 17, 24, 24, 24, 17, + 24, 54, 54, 54, 54, 4, 4, 4, 4, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 4, + 4, 0, 4, 24, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 17, 17, 17, 24, 24, 24, 24, 24, 24, 17, 24, 17, 17, 17, + 17, 24, 24, 17, 24, 24, 54, 54, 4, 54, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 17, 17, 17, 24, 24, 24, 24, 0, 0, + 17, 17, 17, 17, 24, 24, 17, 24, 24, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 54, 54, 54, 54, 24, 24, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 17, 17, + 17, 24, 24, 24, 24, 24, 24, 24, 24, 17, 17, 24, 17, 24, 24, 4, 4, 4, 54, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, + 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, + 17, 24, 17, 17, 24, 24, 24, 24, 24, 24, 17, 24, 54, 4, 0, 0, 0, 0, 0, 0, + 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 0, 0, 24, 24, 24, 17, 17, 24, 24, 24, 24, 17, 24, 24, 24, + 24, 24, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 26, 26, 4, 4, 4, + 4, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 17, 17, 17, 24, 24, 24, 24, 24, 24, 24, 24, 24, 17, 24, + 24, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 54, 0, 0, 54, 54, + 54, 54, 54, 54, 54, 54, 0, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 17, 17, 17, + 17, 17, 17, 0, 17, 17, 0, 0, 24, 24, 17, 24, 54, 17, 54, 17, 24, 4, 4, 4, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, + 54, 54, 54, 54, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 17, 17, 17, 24, 24, 24, 24, 0, 0, 24, 24, + 17, 17, 17, 17, 24, 54, 4, 54, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 24, 24, 24, 24, 24, 24, 17, 54, 24, 24, 24, + 24, 4, 4, 4, 4, 4, 4, 4, 4, 24, 0, 0, 0, 0, 0, 0, 0, 0, 54, 24, 24, 24, + 24, 24, 24, 17, 17, 24, 24, 24, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 17, 24, 24, 4, 4, 4, + 54, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, + 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 17, 24, 24, 24, 24, 24, 24, 24, 0, 24, 24, 24, 24, 24, 24, 17, 24, + 54, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 0, 0, 0, 4, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 0, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 0, 17, 24, 24, 24, 24, 24, 24, 24, 17, 24, + 24, 17, 24, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 0, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, + 24, 24, 24, 24, 24, 0, 0, 0, 24, 0, 24, 24, 0, 24, 24, 24, 24, 24, 24, + 24, 54, 24, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 0, 54, 54, 0, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 17, 17, 17, 17, 17, 0, 24, 24, 0, + 17, 17, 24, 17, 24, 54, 0, 0, 0, 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, 24, 17, 17, 4, 4, + 0, 0, 0, 0, 0, 0, 0, 24, 24, 54, 17, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 17, 17, 24, 24, 24, 24, 24, 0, 0, 0, 17, 17, 24, 17, 24, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 242, 242, + 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, + 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, + 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, + 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, + 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, + 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, + 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, + 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 0, 4, 4, 4, 4, 4, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 4, 4, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 24, + 54, 54, 54, 54, 54, 54, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, + 0, 0, 4, 4, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 0, 0, 24, 24, 24, 24, 24, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, 24, 24, 24, 24, 24, 24, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 102, 102, 102, 102, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 26, 26, 26, 26, 26, 26, 26, 0, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 0, 0, 0, 0, 24, 54, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 24, 24, 24, 24, 102, + 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 102, 102, 4, 102, 24, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 102, 102, 102, 102, 0, 102, + 102, 102, 102, 102, 102, 102, 0, 102, 102, 0, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 0, 0, 54, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 0, 0, 4, 24, 24, 4, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 17, 17, 24, 24, 24, 4, 4, 4, 17, 17, + 17, 17, 17, 17, 20, 20, 20, 20, 20, 20, 20, 20, 24, 24, 24, 24, 24, 24, + 24, 24, 4, 4, 24, 24, 24, 24, 24, 24, 24, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 24, 24, 24, + 24, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 24, 24, 24, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 0, 0, 0, 0, 0, 0, 0, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 19, 19, 19, 19, 19, 19, 19, 0, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 120, 0, 120, 120, 0, 0, 120, 0, 0, 120, 120, 0, 0, 120, 120, 120, + 120, 0, 120, 120, 120, 120, 120, 120, 120, 120, 19, 19, 19, 19, 0, 19, 0, + 19, 19, 19, 19, 19, 19, 19, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 120, 120, 0, 120, 120, 120, 120, 0, 0, 120, 120, 120, + 120, 120, 120, 120, 120, 0, 120, 120, 120, 120, 120, 120, 120, 0, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 120, 120, 0, 120, 120, 120, 120, 0, 120, 120, + 120, 120, 120, 0, 120, 0, 0, 0, 120, 120, 120, 120, 120, 120, 120, 0, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 0, 0, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 4, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 4, 19, 19, 19, 19, 19, 19, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 4, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 4, 19, 19, 19, 19, 19, 19, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 4, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 4, 19, 19, 19, 19, 19, 19, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 4, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 4, 19, 19, 19, 19, 19, 19, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 4, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 4, 19, 19, 19, 19, + 19, 19, 120, 19, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 4, 4, 4, + 4, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 4, 4, 4, 4, + 4, 4, 4, 4, 24, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 24, 4, 4, 4, 4, + 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 24, 24, 24, 24, + 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 54, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 0, 0, + 0, 0, 0, 0, 19, 19, 19, 19, 19, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 24, 24, 24, 24, 24, 24, 24, 0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 0, 0, 24, 24, 24, 24, 24, 24, 24, 0, 24, 24, + 0, 24, 24, 24, 24, 24, 0, 0, 0, 0, 0, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, + 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 24, 24, 24, 24, 24, 24, 24, 102, + 102, 102, 102, 102, 102, 102, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 0, 0, 0, 0, 54, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 24, 24, 24, 24, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 102, 24, 24, 24, 24, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 0, 54, + 54, 54, 54, 0, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 0, 0, 26, 26, 26, 26, 26, 26, 26, 26, 26, 24, 24, 24, 24, 24, 24, 24, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 501, 501, 501, 501, + 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, + 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, + 501, 501, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, + 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, + 502, 502, 502, 502, 502, 502, 502, 502, 24, 24, 24, 24, 24, 24, 24, 102, + 0, 0, 0, 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 4, 4, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 4, 26, 26, 26, 4, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 4, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, + 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 0, 54, 0, + 0, 54, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, 54, 0, + 54, 0, 54, 0, 0, 0, 0, 0, 0, 54, 0, 0, 0, 0, 54, 0, 54, 0, 54, 0, 54, 54, + 54, 0, 54, 54, 0, 54, 0, 0, 54, 0, 54, 0, 54, 0, 54, 0, 54, 0, 54, 54, 0, + 54, 0, 0, 54, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, 54, 0, 54, 54, 54, + 54, 0, 54, 54, 54, 54, 0, 54, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, + 0, 0, 0, 0, 54, 54, 54, 0, 54, 54, 54, 54, 54, 0, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 358, 358, 25, 21, 22, 359, 360, 361, 362, 363, 364, 26, 26, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 503, 503, 503, 503, 503, 503, 503, 503, 503, + 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, + 503, 503, 503, 4, 4, 4, 4, 4, 4, 503, 503, 503, 503, 503, 503, 503, 503, + 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, + 503, 503, 503, 503, 4, 4, 4, 4, 4, 4, 503, 503, 503, 503, 503, 503, 503, + 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, + 503, 503, 503, 503, 503, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, + 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 0, 0, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, + 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, + 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 54, 387, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 387, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 387, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, + 0, 0, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, }; /* Returns the numeric value as double for Unicode characters @@ -4291,10 +4311,12 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x11C50: case 0x11D50: case 0x11DA0: + case 0x11F50: case 0x16A60: case 0x16AC0: case 0x16B50: case 0x16E80: + case 0x1D2C0: case 0x1D2E0: case 0x1D7CE: case 0x1D7D8: @@ -4303,6 +4325,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x1D7F6: case 0x1E140: case 0x1E2F0: + case 0x1E4F0: case 0x1E950: case 0x1F100: case 0x1F101: @@ -4420,6 +4443,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x11C5A: case 0x11D51: case 0x11DA1: + case 0x11F51: case 0x12415: case 0x1241E: case 0x1242C: @@ -4431,6 +4455,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x16B51: case 0x16E81: case 0x16E94: + case 0x1D2C1: case 0x1D2E1: case 0x1D360: case 0x1D372: @@ -4442,6 +4467,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x1D7F7: case 0x1E141: case 0x1E2F1: + case 0x1E4F1: case 0x1E8C7: case 0x1E951: case 0x1EC71: @@ -4599,6 +4625,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x11C63: case 0x16B5B: case 0x16E8A: + case 0x1D2CA: case 0x1D2EA: case 0x1D369: case 0x1EC7A: @@ -4706,6 +4733,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x2492: case 0x24EB: case 0x16E8B: + case 0x1D2CB: case 0x1D2EB: return (double) 11.0; case 0x109BC: @@ -4719,6 +4747,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x2493: case 0x24EC: case 0x16E8C: + case 0x1D2CC: case 0x1D2EC: return (double) 12.0; case 0x246C: @@ -4726,6 +4755,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x2494: case 0x24ED: case 0x16E8D: + case 0x1D2CD: case 0x1D2ED: return (double) 13.0; case 0x0F30: @@ -4735,6 +4765,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x2495: case 0x24EE: case 0x16E8E: + case 0x1D2CE: case 0x1D2EE: return (double) 14.0; case 0x246E: @@ -4742,6 +4773,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x2496: case 0x24EF: case 0x16E8F: + case 0x1D2CF: case 0x1D2EF: return (double) 15.0; case 0x0F31: @@ -4752,6 +4784,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x2497: case 0x24F0: case 0x16E90: + case 0x1D2D0: case 0x1D2F0: return (double) 16.0; case 0x16EE: @@ -4760,6 +4793,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x2498: case 0x24F1: case 0x16E91: + case 0x1D2D1: case 0x1D2F1: return (double) 17.0; case 0x0F32: @@ -4770,6 +4804,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x2499: case 0x24F2: case 0x16E92: + case 0x1D2D2: case 0x1D2F2: return (double) 18.0; case 0x16F0: @@ -4778,6 +4813,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x249A: case 0x24F3: case 0x16E93: + case 0x1D2D3: case 0x1D2F3: return (double) 19.0; case 0x0032: @@ -4885,6 +4921,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x11C5B: case 0x11D52: case 0x11DA2: + case 0x11F52: case 0x12400: case 0x12416: case 0x1241F: @@ -4900,6 +4937,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x16B52: case 0x16E82: case 0x16E95: + case 0x1D2C2: case 0x1D2E2: case 0x1D361: case 0x1D373: @@ -4910,6 +4948,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x1D7F8: case 0x1E142: case 0x1E2F2: + case 0x1E4F2: case 0x1E8C8: case 0x1E952: case 0x1EC72: @@ -5111,6 +5150,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x11C5C: case 0x11D53: case 0x11DA3: + case 0x11F53: case 0x12401: case 0x12408: case 0x12417: @@ -5131,6 +5171,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x16B53: case 0x16E83: case 0x16E96: + case 0x1D2C3: case 0x1D2E3: case 0x1D362: case 0x1D374: @@ -5141,6 +5182,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x1D7F9: case 0x1E143: case 0x1E2F3: + case 0x1E4F3: case 0x1E8C9: case 0x1E953: case 0x1EC73: @@ -5334,6 +5376,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x11C5D: case 0x11D54: case 0x11DA4: + case 0x11F54: case 0x12402: case 0x12409: case 0x1240F: @@ -5354,6 +5397,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x16AC4: case 0x16B54: case 0x16E84: + case 0x1D2C4: case 0x1D2E4: case 0x1D363: case 0x1D375: @@ -5364,6 +5408,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x1D7FA: case 0x1E144: case 0x1E2F4: + case 0x1E4F4: case 0x1E8CA: case 0x1E954: case 0x1EC74: @@ -5533,6 +5578,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x11C5E: case 0x11D55: case 0x11DA5: + case 0x11F55: case 0x12403: case 0x1240A: case 0x12410: @@ -5549,6 +5595,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x16AC5: case 0x16B55: case 0x16E85: + case 0x1D2C5: case 0x1D2E5: case 0x1D364: case 0x1D376: @@ -5560,6 +5607,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x1D7FB: case 0x1E145: case 0x1E2F5: + case 0x1E4F5: case 0x1E8CB: case 0x1E955: case 0x1EC75: @@ -5729,6 +5777,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x11C5F: case 0x11D56: case 0x11DA6: + case 0x11F56: case 0x12404: case 0x1240B: case 0x12411: @@ -5741,6 +5790,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x16AC6: case 0x16B56: case 0x16E86: + case 0x1D2C6: case 0x1D2E6: case 0x1D365: case 0x1D7D4: @@ -5750,6 +5800,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x1D7FC: case 0x1E146: case 0x1E2F6: + case 0x1E4F6: case 0x1E8CC: case 0x1E956: case 0x1EC76: @@ -5878,6 +5929,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x11C60: case 0x11D57: case 0x11DA7: + case 0x11F57: case 0x12405: case 0x1240C: case 0x12412: @@ -5891,6 +5943,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x16AC7: case 0x16B57: case 0x16E87: + case 0x1D2C7: case 0x1D2E7: case 0x1D366: case 0x1D7D5: @@ -5900,6 +5953,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x1D7FD: case 0x1E147: case 0x1E2F7: + case 0x1E4F7: case 0x1E8CD: case 0x1E957: case 0x1EC77: @@ -6029,6 +6083,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x11C61: case 0x11D58: case 0x11DA8: + case 0x11F58: case 0x12406: case 0x1240D: case 0x12413: @@ -6041,6 +6096,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x16AC8: case 0x16B58: case 0x16E88: + case 0x1D2C8: case 0x1D2E8: case 0x1D367: case 0x1D7D6: @@ -6050,6 +6106,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x1D7FE: case 0x1E148: case 0x1E2F8: + case 0x1E4F8: case 0x1E8CE: case 0x1E958: case 0x1EC78: @@ -6174,6 +6231,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x11C62: case 0x11D59: case 0x11DA9: + case 0x11F59: case 0x12407: case 0x1240E: case 0x12414: @@ -6188,6 +6246,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x16AC9: case 0x16B59: case 0x16E89: + case 0x1D2C9: case 0x1D2E9: case 0x1D368: case 0x1D7D7: @@ -6197,6 +6256,7 @@ double _PyUnicode_ToNumeric(Py_UCS4 ch) case 0x1D7FF: case 0x1E149: case 0x1E2F9: + case 0x1E4F9: case 0x1E8CF: case 0x1E959: case 0x1EC79: diff --git a/Objects/unionobject.c b/Objects/unionobject.c index 5eee27c0..f509a161 100644 --- a/Objects/unionobject.c +++ b/Objects/unionobject.c @@ -1,6 +1,7 @@ // types.UnionType -- used to represent e.g. Union[int, str], int | str #include "Python.h" #include "pycore_object.h" // _PyObject_GC_TRACK/UNTRACK +#include "pycore_typevarobject.h" // _PyTypeAlias_Type #include "pycore_unionobject.h" #include "structmember.h" @@ -114,12 +115,10 @@ merge(PyObject **items1, Py_ssize_t size1, } for (; pos < size1; pos++) { PyObject *a = items1[pos]; - Py_INCREF(a); - PyTuple_SET_ITEM(tuple, pos, a); + PyTuple_SET_ITEM(tuple, pos, Py_NewRef(a)); } } - Py_INCREF(arg); - PyTuple_SET_ITEM(tuple, pos, arg); + PyTuple_SET_ITEM(tuple, pos, Py_NewRef(arg)); pos++; } @@ -149,10 +148,14 @@ get_types(PyObject **obj, Py_ssize_t *size) static int is_unionable(PyObject *obj) { - return (obj == Py_None || + if (obj == Py_None || PyType_Check(obj) || _PyGenericAlias_Check(obj) || - _PyUnion_Check(obj)); + _PyUnion_Check(obj) || + Py_IS_TYPE(obj, &_PyTypeAlias_Type)) { + return 1; + } + return 0; } PyObject * @@ -170,8 +173,7 @@ _Py_union_type_or(PyObject* self, PyObject* other) if (PyErr_Occurred()) { return NULL; } - Py_INCREF(self); - return self; + return Py_NewRef(self); } PyObject *new_union = make_union(tuple); @@ -298,8 +300,7 @@ union_getitem(PyObject *self, PyObject *item) res = make_union(newargs); } else { - res = PyTuple_GET_ITEM(newargs, 0); - Py_INCREF(res); + res = Py_NewRef(PyTuple_GET_ITEM(newargs, 0)); for (Py_ssize_t iarg = 1; iarg < nargs; iarg++) { PyObject *arg = PyTuple_GET_ITEM(newargs, iarg); Py_SETREF(res, PyNumber_Or(res, arg)); @@ -326,8 +327,7 @@ union_parameters(PyObject *self, void *Py_UNUSED(unused)) return NULL; } } - Py_INCREF(alias->parameters); - return alias->parameters; + return Py_NewRef(alias->parameters); } static PyGetSetDef union_properties[] = { @@ -400,9 +400,8 @@ make_union(PyObject *args) return NULL; } - Py_INCREF(args); result->parameters = NULL; - result->args = args; + result->args = Py_NewRef(args); _PyObject_GC_TRACK(result); return (PyObject*)result; } diff --git a/Objects/weakrefobject.c b/Objects/weakrefobject.c index d26fc9e8..aee79fc1 100644 --- a/Objects/weakrefobject.c +++ b/Objects/weakrefobject.c @@ -170,10 +170,7 @@ weakref_repr(PyWeakReference *self) } Py_INCREF(obj); - if (_PyObject_LookupAttr(obj, &_Py_ID(__name__), &name) < 0) { - Py_DECREF(obj); - return NULL; - } + name = _PyObject_LookupSpecial(obj, &_Py_ID(__name__)); if (name == NULL || !PyUnicode_Check(name)) { repr = PyUnicode_FromFormat( "<weakref at %p; to '%s' at %p>", @@ -311,8 +308,7 @@ weakref___new__(PyTypeObject *type, PyObject *args, PyObject *kwargs) if (callback == NULL && type == &_PyWeakref_RefType) { if (ref != NULL) { /* We can re-use an existing reference. */ - Py_INCREF(ref); - return (PyObject *)ref; + return Py_NewRef(ref); } } /* We have to create a new reference. */ @@ -825,9 +821,7 @@ PyWeakref_NewRef(PyObject *ob, PyObject *callback) during GC. Return that one instead of this one to avoid violating the invariants of the list of weakrefs for ob. */ - Py_DECREF(result); - Py_INCREF(ref); - result = ref; + Py_SETREF(result, (PyWeakReference*)Py_NewRef(ref)); } } else { @@ -890,9 +884,7 @@ PyWeakref_NewProxy(PyObject *ob, PyObject *callback) during GC. Return that one instead of this one to avoid violating the invariants of the list of weakrefs for ob. */ - Py_DECREF(result); - result = proxy; - Py_INCREF(result); + Py_SETREF(result, (PyWeakReference*)Py_NewRef(proxy)); goto skip_insert; } prev = ref; @@ -964,9 +956,8 @@ PyObject_ClearWeakRefs(PyObject *object) if (*list != NULL) { PyWeakReference *current = *list; Py_ssize_t count = _PyWeakref_GetWeakrefCount(current); - PyObject *err_type, *err_value, *err_tb; + PyObject *exc = PyErr_GetRaisedException(); - PyErr_Fetch(&err_type, &err_value, &err_tb); if (count == 1) { PyObject *callback = current->wr_callback; @@ -985,7 +976,7 @@ PyObject_ClearWeakRefs(PyObject *object) tuple = PyTuple_New(count * 2); if (tuple == NULL) { - _PyErr_ChainExceptions(err_type, err_value, err_tb); + _PyErr_ChainExceptions1(exc); return; } @@ -993,8 +984,7 @@ PyObject_ClearWeakRefs(PyObject *object) PyWeakReference *next = current->wr_next; if (Py_REFCNT((PyObject *)current) > 0) { - Py_INCREF(current); - PyTuple_SET_ITEM(tuple, i * 2, (PyObject *) current); + PyTuple_SET_ITEM(tuple, i * 2, Py_NewRef(current)); PyTuple_SET_ITEM(tuple, i * 2 + 1, current->wr_callback); } else { @@ -1016,6 +1006,25 @@ PyObject_ClearWeakRefs(PyObject *object) Py_DECREF(tuple); } assert(!PyErr_Occurred()); - PyErr_Restore(err_type, err_value, err_tb); + PyErr_SetRaisedException(exc); + } +} + +/* This function is called by _PyStaticType_Dealloc() to clear weak references. + * + * This is called at the end of runtime finalization, so we can just + * wipe out the type's weaklist. We don't bother with callbacks + * or anything else. + */ +void +_PyStaticType_ClearWeakRefs(PyInterpreterState *interp, PyTypeObject *type) +{ + static_builtin_state *state = _PyStaticType_GetState(interp, type); + PyObject **list = _PyStaticType_GET_WEAKREFS_LISTPTR(state); + while (*list != NULL) { + /* Note that clear_weakref() pops the first ref off the type's + weaklist before clearing its wr_object and wr_callback. + That is how we're able to loop over the list. */ + clear_weakref((PyWeakReference *)*list); } } diff --git a/PC/_msi.c b/PC/_msi.c index 3d4e4ef2..b104e3c6 100644 --- a/PC/_msi.c +++ b/PC/_msi.c @@ -172,9 +172,7 @@ static FNFCIGETTEMPFILE(cb_gettempfile) static FNFCISTATUS(cb_status) { if (pv) { - _Py_IDENTIFIER(status); - - PyObject *result = _PyObject_CallMethodId(pv, &PyId_status, "iii", typeStatus, cb1, cb2); + PyObject *result = PyObject_CallMethod(pv, "status", "iii", typeStatus, cb1, cb2); if (result == NULL) return -1; Py_DECREF(result); @@ -185,9 +183,7 @@ static FNFCISTATUS(cb_status) static FNFCIGETNEXTCABINET(cb_getnextcabinet) { if (pv) { - _Py_IDENTIFIER(getnextcabinet); - - PyObject *result = _PyObject_CallMethodId(pv, &PyId_getnextcabinet, "i", pccab->iCab); + PyObject *result = PyObject_CallMethod(pv, "getnextcabinet", "i", pccab->iCab); if (result == NULL) return -1; if (!PyBytes_Check(result)) { @@ -705,8 +701,7 @@ _msi_SummaryInformation_GetProperty_impl(msiobj *self, int field) result = PyBytes_FromStringAndSize(sval, ssize); break; case VT_EMPTY: - Py_INCREF(Py_None); - result = Py_None; + result = Py_NewRef(Py_None); break; default: PyErr_Format(PyExc_NotImplementedError, "result of type %d", type); @@ -757,19 +752,13 @@ _msi_SummaryInformation_SetProperty_impl(msiobj *self, int field, int status; if (PyUnicode_Check(data)) { -#if USE_UNICODE_WCHAR_CACHE - const WCHAR *value = _PyUnicode_AsUnicode(data); -#else /* USE_UNICODE_WCHAR_CACHE */ WCHAR *value = PyUnicode_AsWideCharString(data, NULL); -#endif /* USE_UNICODE_WCHAR_CACHE */ if (value == NULL) { return NULL; } status = MsiSummaryInfoSetPropertyW(self->h, field, VT_LPSTR, 0, NULL, value); -#if !USE_UNICODE_WCHAR_CACHE PyMem_Free(value); -#endif /* USE_UNICODE_WCHAR_CACHE */ } else if (PyLong_CheckExact(data)) { long value = PyLong_AsLong(data); if (value == -1 && PyErr_Occurred()) { diff --git a/PC/_testconsole.c b/PC/_testconsole.c index a8308835..3221b985 100644 --- a/PC/_testconsole.c +++ b/PC/_testconsole.c @@ -10,7 +10,7 @@ #ifdef MS_WINDOWS #include "pycore_fileutils.h" // _Py_get_osfhandle() -#include "..\modules\_io\_iomodule.h" +#include "pycore_runtime.h" // _Py_ID() #define WIN32_LEAN_AND_MEAN #include <windows.h> @@ -31,6 +31,7 @@ static int execfunc(PyObject *m) PyModuleDef_Slot testconsole_slots[] = { {Py_mod_exec, execfunc}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL}, }; @@ -51,7 +52,14 @@ _testconsole_write_input_impl(PyObject *module, PyObject *file, { INPUT_RECORD *rec = NULL; - if (!PyWindowsConsoleIO_Check(file)) { + PyTypeObject *winconsoleio_type = (PyTypeObject *)_PyImport_GetModuleAttr( + &_Py_ID(_io), &_Py_ID(_WindowsConsoleIO)); + if (winconsoleio_type == NULL) { + return NULL; + } + int is_subclass = PyObject_TypeCheck(file, winconsoleio_type); + Py_DECREF(winconsoleio_type); + if (!is_subclass) { PyErr_SetString(PyExc_TypeError, "expected raw console object"); return NULL; } diff --git a/PC/_wmimodule.cpp b/PC/_wmimodule.cpp new file mode 100644 index 00000000..310aa86d --- /dev/null +++ b/PC/_wmimodule.cpp @@ -0,0 +1,323 @@ +// +// Helper library for querying WMI using its COM-based query API. +// +// Copyright (c) Microsoft Corporation +// Licensed to PSF under a contributor agreement +// + +// Version history +// 2022-08: Initial contribution (Steve Dower) + +#define _WIN32_DCOM +#include <Windows.h> +#include <comdef.h> +#include <Wbemidl.h> +#include <propvarutil.h> + +#include <Python.h> + + +#if _MSVC_LANG >= 202002L +// We can use clinic directly when the C++ compiler supports C++20 +#include "clinic/_wmimodule.cpp.h" +#else +// Cannot use clinic because of missing C++20 support, so create a simpler +// API instead. This won't impact releases, so fine to omit the docstring. +static PyObject *_wmi_exec_query_impl(PyObject *module, PyObject *query); +#define _WMI_EXEC_QUERY_METHODDEF {"exec_query", _wmi_exec_query_impl, METH_O, NULL}, +#endif + + +/*[clinic input] +module _wmi +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=7ca95dad1453d10d]*/ + + + +struct _query_data { + LPCWSTR query; + HANDLE writePipe; + HANDLE readPipe; +}; + + +static DWORD WINAPI +_query_thread(LPVOID param) +{ + IWbemLocator *locator = NULL; + IWbemServices *services = NULL; + IEnumWbemClassObject* enumerator = NULL; + BSTR bstrQuery = NULL; + struct _query_data *data = (struct _query_data*)param; + + HRESULT hr = CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); + if (FAILED(hr)) { + CloseHandle(data->writePipe); + return (DWORD)hr; + } + + hr = CoInitializeSecurity( + NULL, -1, NULL, NULL, + RPC_C_AUTHN_LEVEL_DEFAULT, + RPC_C_IMP_LEVEL_IMPERSONATE, + NULL, EOAC_NONE, NULL + ); + // gh-96684: CoInitializeSecurity will fail if another part of the app has + // already called it. Hopefully they passed lenient enough settings that we + // can complete the WMI query, so keep going. + if (hr == RPC_E_TOO_LATE) { + hr = 0; + } + if (SUCCEEDED(hr)) { + hr = CoCreateInstance( + CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, + IID_IWbemLocator, (LPVOID *)&locator + ); + } + if (SUCCEEDED(hr)) { + hr = locator->ConnectServer( + bstr_t(L"ROOT\\CIMV2"), + NULL, NULL, 0, NULL, 0, 0, &services + ); + } + if (SUCCEEDED(hr)) { + hr = CoSetProxyBlanket( + services, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, + RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, + NULL, EOAC_NONE + ); + } + if (SUCCEEDED(hr)) { + bstrQuery = SysAllocString(data->query); + if (!bstrQuery) { + hr = HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY); + } + } + if (SUCCEEDED(hr)) { + hr = services->ExecQuery( + bstr_t("WQL"), + bstrQuery, + WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, + NULL, + &enumerator + ); + } + + // Okay, after all that, at this stage we should have an enumerator + // to the query results and can start writing them to the pipe! + IWbemClassObject *value = NULL; + int startOfEnum = TRUE; + int endOfEnum = FALSE; + while (SUCCEEDED(hr) && !endOfEnum) { + ULONG got = 0; + DWORD written; + hr = enumerator->Next(WBEM_INFINITE, 1, &value, &got); + if (hr == WBEM_S_FALSE) { + // Could be at the end, but still got a result this time + endOfEnum = TRUE; + hr = 0; + break; + } + if (FAILED(hr) || got != 1 || !value) { + continue; + } + if (!startOfEnum && !WriteFile(data->writePipe, (LPVOID)L"\0", 2, &written, NULL)) { + hr = HRESULT_FROM_WIN32(GetLastError()); + break; + } + startOfEnum = FALSE; + // Okay, now we have each resulting object it's time to + // enumerate its members + hr = value->BeginEnumeration(0); + if (FAILED(hr)) { + value->Release(); + break; + } + while (SUCCEEDED(hr)) { + BSTR propName; + VARIANT propValue; + long flavor; + hr = value->Next(0, &propName, &propValue, NULL, &flavor); + if (hr == WBEM_S_NO_MORE_DATA) { + hr = 0; + break; + } + if (SUCCEEDED(hr) && (flavor & WBEM_FLAVOR_MASK_ORIGIN) != WBEM_FLAVOR_ORIGIN_SYSTEM) { + WCHAR propStr[8192]; + hr = VariantToString(propValue, propStr, sizeof(propStr) / sizeof(propStr[0])); + if (SUCCEEDED(hr)) { + DWORD cbStr1, cbStr2; + cbStr1 = (DWORD)(wcslen(propName) * sizeof(propName[0])); + cbStr2 = (DWORD)(wcslen(propStr) * sizeof(propStr[0])); + if (!WriteFile(data->writePipe, propName, cbStr1, &written, NULL) || + !WriteFile(data->writePipe, (LPVOID)L"=", 2, &written, NULL) || + !WriteFile(data->writePipe, propStr, cbStr2, &written, NULL) || + !WriteFile(data->writePipe, (LPVOID)L"\0", 2, &written, NULL) + ) { + hr = HRESULT_FROM_WIN32(GetLastError()); + } + } + VariantClear(&propValue); + SysFreeString(propName); + } + } + value->EndEnumeration(); + value->Release(); + } + + if (bstrQuery) { + SysFreeString(bstrQuery); + } + if (enumerator) { + enumerator->Release(); + } + if (services) { + services->Release(); + } + if (locator) { + locator->Release(); + } + CoUninitialize(); + CloseHandle(data->writePipe); + return (DWORD)hr; +} + + +/*[clinic input] +_wmi.exec_query + + query: unicode + +Runs a WMI query against the local machine. + +This returns a single string with 'name=value' pairs in a flat array separated +by null characters. +[clinic start generated code]*/ + +static PyObject * +_wmi_exec_query_impl(PyObject *module, PyObject *query) +/*[clinic end generated code: output=a62303d5bb5e003f input=48d2d0a1e1a7e3c2]*/ + +/*[clinic end generated code]*/ +{ + PyObject *result = NULL; + HANDLE hThread = NULL; + int err = 0; + WCHAR buffer[8192]; + DWORD offset = 0; + DWORD bytesRead; + struct _query_data data = {0}; + + if (PySys_Audit("_wmi.exec_query", "O", query) < 0) { + return NULL; + } + + data.query = PyUnicode_AsWideCharString(query, NULL); + if (!data.query) { + return NULL; + } + + if (0 != _wcsnicmp(data.query, L"select ", 7)) { + PyMem_Free((void *)data.query); + PyErr_SetString(PyExc_ValueError, "only SELECT queries are supported"); + return NULL; + } + + Py_BEGIN_ALLOW_THREADS + + if (!CreatePipe(&data.readPipe, &data.writePipe, NULL, 0)) { + err = GetLastError(); + } else { + hThread = CreateThread(NULL, 0, _query_thread, (LPVOID*)&data, 0, NULL); + if (!hThread) { + err = GetLastError(); + // Normally the thread proc closes this handle, but since we never started + // we need to close it here. + CloseHandle(data.writePipe); + } + } + + while (!err) { + if (ReadFile( + data.readPipe, + (LPVOID)&buffer[offset / sizeof(buffer[0])], + sizeof(buffer) - offset, + &bytesRead, + NULL + )) { + offset += bytesRead; + if (offset >= sizeof(buffer)) { + err = ERROR_MORE_DATA; + } + } else { + err = GetLastError(); + } + } + + if (data.readPipe) { + CloseHandle(data.readPipe); + } + + // Allow the thread some time to clean up + switch (WaitForSingleObject(hThread, 1000)) { + case WAIT_OBJECT_0: + // Thread ended cleanly + if (!GetExitCodeThread(hThread, (LPDWORD)&err)) { + err = GetLastError(); + } + break; + case WAIT_TIMEOUT: + // Probably stuck - there's not much we can do, unfortunately + if (err == 0 || err == ERROR_BROKEN_PIPE) { + err = WAIT_TIMEOUT; + } + break; + default: + if (err == 0 || err == ERROR_BROKEN_PIPE) { + err = GetLastError(); + } + break; + } + + CloseHandle(hThread); + hThread = NULL; + + Py_END_ALLOW_THREADS + + PyMem_Free((void *)data.query); + + if (err == ERROR_MORE_DATA) { + PyErr_Format(PyExc_OSError, "Query returns more than %zd characters", Py_ARRAY_LENGTH(buffer)); + return NULL; + } else if (err) { + PyErr_SetFromWindowsErr(err); + return NULL; + } + + if (!offset) { + return PyUnicode_FromStringAndSize(NULL, 0); + } + return PyUnicode_FromWideChar(buffer, offset / sizeof(buffer[0]) - 1); +} + + +static PyMethodDef wmi_functions[] = { + _WMI_EXEC_QUERY_METHODDEF + { NULL, NULL, 0, NULL } +}; + +static PyModuleDef wmi_def = { + PyModuleDef_HEAD_INIT, + "_wmi", + NULL, // doc + 0, // m_size + wmi_functions +}; + +extern "C" { + PyMODINIT_FUNC PyInit__wmi(void) + { + return PyModuleDef_Init(&wmi_def); + } +} diff --git a/PC/clinic/_msi.c.h b/PC/clinic/_msi.c.h index b717192b..c77f0703 100644 --- a/PC/clinic/_msi.c.h +++ b/PC/clinic/_msi.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_msi_UuidCreate__doc__, "UuidCreate($module, /)\n" "--\n" @@ -208,11 +214,7 @@ _msi_Record_SetString(msiobj *self, PyObject *const *args, Py_ssize_t nargs) _PyArg_BadArgument("SetString", "argument 2", "str", args[1]); goto exit; } - #if USE_UNICODE_WCHAR_CACHE - value = _PyUnicode_AsUnicode(args[1]); - #else /* USE_UNICODE_WCHAR_CACHE */ value = PyUnicode_AsWideCharString(args[1], NULL); - #endif /* USE_UNICODE_WCHAR_CACHE */ if (value == NULL) { goto exit; } @@ -220,9 +222,7 @@ _msi_Record_SetString(msiobj *self, PyObject *const *args, Py_ssize_t nargs) exit: /* Cleanup for value */ - #if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *)value); - #endif /* USE_UNICODE_WCHAR_CACHE */ return return_value; } @@ -257,11 +257,7 @@ _msi_Record_SetStream(msiobj *self, PyObject *const *args, Py_ssize_t nargs) _PyArg_BadArgument("SetStream", "argument 2", "str", args[1]); goto exit; } - #if USE_UNICODE_WCHAR_CACHE - value = _PyUnicode_AsUnicode(args[1]); - #else /* USE_UNICODE_WCHAR_CACHE */ value = PyUnicode_AsWideCharString(args[1], NULL); - #endif /* USE_UNICODE_WCHAR_CACHE */ if (value == NULL) { goto exit; } @@ -269,9 +265,7 @@ _msi_Record_SetStream(msiobj *self, PyObject *const *args, Py_ssize_t nargs) exit: /* Cleanup for value */ - #if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *)value); - #endif /* USE_UNICODE_WCHAR_CACHE */ return return_value; } @@ -561,11 +555,7 @@ _msi_Database_OpenView(msiobj *self, PyObject *arg) _PyArg_BadArgument("OpenView", "argument", "str", arg); goto exit; } - #if USE_UNICODE_WCHAR_CACHE - sql = _PyUnicode_AsUnicode(arg); - #else /* USE_UNICODE_WCHAR_CACHE */ sql = PyUnicode_AsWideCharString(arg, NULL); - #endif /* USE_UNICODE_WCHAR_CACHE */ if (sql == NULL) { goto exit; } @@ -573,9 +563,7 @@ _msi_Database_OpenView(msiobj *self, PyObject *arg) exit: /* Cleanup for sql */ - #if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *)sql); - #endif /* USE_UNICODE_WCHAR_CACHE */ return return_value; } @@ -660,11 +648,7 @@ _msi_OpenDatabase(PyObject *module, PyObject *const *args, Py_ssize_t nargs) _PyArg_BadArgument("OpenDatabase", "argument 1", "str", args[0]); goto exit; } - #if USE_UNICODE_WCHAR_CACHE - path = _PyUnicode_AsUnicode(args[0]); - #else /* USE_UNICODE_WCHAR_CACHE */ path = PyUnicode_AsWideCharString(args[0], NULL); - #endif /* USE_UNICODE_WCHAR_CACHE */ if (path == NULL) { goto exit; } @@ -676,9 +660,7 @@ _msi_OpenDatabase(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: /* Cleanup for path */ - #if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *)path); - #endif /* USE_UNICODE_WCHAR_CACHE */ return return_value; } @@ -713,4 +695,4 @@ _msi_CreateRecord(PyObject *module, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=276175d60fbfc956 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=7d083c61679eed83 input=a9049054013a1b77]*/ diff --git a/PC/clinic/_testconsole.c.h b/PC/clinic/_testconsole.c.h index b2fd515e..b2f3b4ce 100644 --- a/PC/clinic/_testconsole.c.h +++ b/PC/clinic/_testconsole.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + #if defined(MS_WINDOWS) PyDoc_STRVAR(_testconsole_write_input__doc__, @@ -21,8 +27,31 @@ static PyObject * _testconsole_write_input(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(file), &_Py_ID(s), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"file", "s", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "write_input", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "write_input", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject *file; PyBytesObject *s; @@ -63,8 +92,31 @@ static PyObject * _testconsole_read_output(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(file), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"file", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "read_output", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "read_output", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *file; @@ -88,4 +140,4 @@ exit: #ifndef _TESTCONSOLE_READ_OUTPUT_METHODDEF #define _TESTCONSOLE_READ_OUTPUT_METHODDEF #endif /* !defined(_TESTCONSOLE_READ_OUTPUT_METHODDEF) */ -/*[clinic end generated code: output=6e9f8b0766eb5a0e input=a9049054013a1b77]*/ +/*[clinic end generated code: output=208c72e2c873555b input=a9049054013a1b77]*/ diff --git a/PC/clinic/_wmimodule.cpp.h b/PC/clinic/_wmimodule.cpp.h new file mode 100644 index 00000000..e2b947f3 --- /dev/null +++ b/PC/clinic/_wmimodule.cpp.h @@ -0,0 +1,75 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + +PyDoc_STRVAR(_wmi_exec_query__doc__, +"exec_query($module, /, query)\n" +"--\n" +"\n" +"Runs a WMI query against the local machine.\n" +"\n" +"This returns a single string with \'name=value\' pairs in a flat array separated\n" +"by null characters."); + +#define _WMI_EXEC_QUERY_METHODDEF \ + {"exec_query", _PyCFunction_CAST(_wmi_exec_query), METH_FASTCALL|METH_KEYWORDS, _wmi_exec_query__doc__}, + +static PyObject * +_wmi_exec_query_impl(PyObject *module, PyObject *query); + +static PyObject * +_wmi_exec_query(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(query), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"query", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "exec_query", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + PyObject *query; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!PyUnicode_Check(args[0])) { + _PyArg_BadArgument("exec_query", "argument 'query'", "str", args[0]); + goto exit; + } + if (PyUnicode_READY(args[0]) == -1) { + goto exit; + } + query = args[0]; + return_value = _wmi_exec_query_impl(module, query); + +exit: + return return_value; +} +/*[clinic end generated code: output=7fdf0c0579ddb566 input=a9049054013a1b77]*/ diff --git a/PC/clinic/msvcrtmodule.c.h b/PC/clinic/msvcrtmodule.c.h index ea958975..b708c6cd 100644 --- a/PC/clinic/msvcrtmodule.c.h +++ b/PC/clinic/msvcrtmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(msvcrt_heapmin__doc__, "heapmin($module, /)\n" "--\n" @@ -141,8 +147,15 @@ msvcrt_open_osfhandle(PyObject *module, PyObject *const *args, Py_ssize_t nargs) int flags; long _return_value; - if (!_PyArg_ParseStack(args, nargs, ""_Py_PARSE_UINTPTR"i:open_osfhandle", - &handle, &flags)) { + if (!_PyArg_CheckPositional("open_osfhandle", nargs, 2, 2)) { + goto exit; + } + handle = PyLong_AsVoidPtr(args[0]); + if (!handle && PyErr_Occurred()) { + goto exit; + } + flags = _PyLong_AsInt(args[1]); + if (flags == -1 && PyErr_Occurred()) { goto exit; } _return_value = msvcrt_open_osfhandle_impl(module, handle, flags); @@ -248,6 +261,8 @@ msvcrt_getch(PyObject *module, PyObject *Py_UNUSED(ignored)) return return_value; } +#if defined(MS_WINDOWS_DESKTOP) + PyDoc_STRVAR(msvcrt_getwch__doc__, "getwch($module, /)\n" "--\n" @@ -272,6 +287,8 @@ msvcrt_getwch(PyObject *module, PyObject *Py_UNUSED(ignored)) return return_value; } +#endif /* defined(MS_WINDOWS_DESKTOP) */ + PyDoc_STRVAR(msvcrt_getche__doc__, "getche($module, /)\n" "--\n" @@ -296,6 +313,8 @@ msvcrt_getche(PyObject *module, PyObject *Py_UNUSED(ignored)) return return_value; } +#if defined(MS_WINDOWS_DESKTOP) + PyDoc_STRVAR(msvcrt_getwche__doc__, "getwche($module, /)\n" "--\n" @@ -320,6 +339,8 @@ msvcrt_getwche(PyObject *module, PyObject *Py_UNUSED(ignored)) return return_value; } +#endif /* defined(MS_WINDOWS_DESKTOP) */ + PyDoc_STRVAR(msvcrt_putch__doc__, "putch($module, char, /)\n" "--\n" @@ -354,6 +375,8 @@ exit: return return_value; } +#if defined(MS_WINDOWS_DESKTOP) + PyDoc_STRVAR(msvcrt_putwch__doc__, "putwch($module, unicode_char, /)\n" "--\n" @@ -390,6 +413,8 @@ exit: return return_value; } +#endif /* defined(MS_WINDOWS_DESKTOP) */ + PyDoc_STRVAR(msvcrt_ungetch__doc__, "ungetch($module, char, /)\n" "--\n" @@ -428,6 +453,8 @@ exit: return return_value; } +#if defined(MS_WINDOWS_DESKTOP) + PyDoc_STRVAR(msvcrt_ungetwch__doc__, "ungetwch($module, unicode_char, /)\n" "--\n" @@ -464,6 +491,8 @@ exit: return return_value; } +#endif /* defined(MS_WINDOWS_DESKTOP) */ + #if defined(_DEBUG) PyDoc_STRVAR(msvcrt_CrtSetReportFile__doc__, @@ -488,8 +517,15 @@ msvcrt_CrtSetReportFile(PyObject *module, PyObject *const *args, Py_ssize_t narg void *file; void *_return_value; - if (!_PyArg_ParseStack(args, nargs, "i"_Py_PARSE_UINTPTR":CrtSetReportFile", - &type, &file)) { + if (!_PyArg_CheckPositional("CrtSetReportFile", nargs, 2, 2)) { + goto exit; + } + type = _PyLong_AsInt(args[0]); + if (type == -1 && PyErr_Occurred()) { + goto exit; + } + file = PyLong_AsVoidPtr(args[1]); + if (!file && PyErr_Occurred()) { goto exit; } _return_value = msvcrt_CrtSetReportFile_impl(module, type, file); @@ -590,6 +626,8 @@ exit: #endif /* defined(_DEBUG) */ +#if (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_APP) || defined(MS_WINDOWS_SYSTEM)) + PyDoc_STRVAR(msvcrt_GetErrorMode__doc__, "GetErrorMode($module, /)\n" "--\n" @@ -608,6 +646,8 @@ msvcrt_GetErrorMode(PyObject *module, PyObject *Py_UNUSED(ignored)) return msvcrt_GetErrorMode_impl(module); } +#endif /* (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_APP) || defined(MS_WINDOWS_SYSTEM)) */ + PyDoc_STRVAR(msvcrt_SetErrorMode__doc__, "SetErrorMode($module, mode, /)\n" "--\n" @@ -636,6 +676,22 @@ exit: return return_value; } +#ifndef MSVCRT_GETWCH_METHODDEF + #define MSVCRT_GETWCH_METHODDEF +#endif /* !defined(MSVCRT_GETWCH_METHODDEF) */ + +#ifndef MSVCRT_GETWCHE_METHODDEF + #define MSVCRT_GETWCHE_METHODDEF +#endif /* !defined(MSVCRT_GETWCHE_METHODDEF) */ + +#ifndef MSVCRT_PUTWCH_METHODDEF + #define MSVCRT_PUTWCH_METHODDEF +#endif /* !defined(MSVCRT_PUTWCH_METHODDEF) */ + +#ifndef MSVCRT_UNGETWCH_METHODDEF + #define MSVCRT_UNGETWCH_METHODDEF +#endif /* !defined(MSVCRT_UNGETWCH_METHODDEF) */ + #ifndef MSVCRT_CRTSETREPORTFILE_METHODDEF #define MSVCRT_CRTSETREPORTFILE_METHODDEF #endif /* !defined(MSVCRT_CRTSETREPORTFILE_METHODDEF) */ @@ -647,4 +703,8 @@ exit: #ifndef MSVCRT_SET_ERROR_MODE_METHODDEF #define MSVCRT_SET_ERROR_MODE_METHODDEF #endif /* !defined(MSVCRT_SET_ERROR_MODE_METHODDEF) */ -/*[clinic end generated code: output=b543933cad520f2b input=a9049054013a1b77]*/ + +#ifndef MSVCRT_GETERRORMODE_METHODDEF + #define MSVCRT_GETERRORMODE_METHODDEF +#endif /* !defined(MSVCRT_GETERRORMODE_METHODDEF) */ +/*[clinic end generated code: output=2db6197608a6aab3 input=a9049054013a1b77]*/ diff --git a/PC/clinic/winreg.c.h b/PC/clinic/winreg.c.h index a413dec5..4109c852 100644 --- a/PC/clinic/winreg.c.h +++ b/PC/clinic/winreg.c.h @@ -2,6 +2,14 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + +#if (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES)) + PyDoc_STRVAR(winreg_HKEYType_Close__doc__, "Close($self, /)\n" "--\n" @@ -22,6 +30,10 @@ winreg_HKEYType_Close(PyHKEYObject *self, PyObject *Py_UNUSED(ignored)) return winreg_HKEYType_Close_impl(self); } +#endif /* (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES)) */ + +#if (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES)) + PyDoc_STRVAR(winreg_HKEYType_Detach__doc__, "Detach($self, /)\n" "--\n" @@ -48,6 +60,10 @@ winreg_HKEYType_Detach(PyHKEYObject *self, PyObject *Py_UNUSED(ignored)) return winreg_HKEYType_Detach_impl(self); } +#endif /* (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES)) */ + +#if (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES)) + PyDoc_STRVAR(winreg_HKEYType___enter____doc__, "__enter__($self, /)\n" "--\n" @@ -71,6 +87,10 @@ winreg_HKEYType___enter__(PyHKEYObject *self, PyObject *Py_UNUSED(ignored)) return return_value; } +#endif /* (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES)) */ + +#if (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES)) + PyDoc_STRVAR(winreg_HKEYType___exit____doc__, "__exit__($self, /, exc_type, exc_value, traceback)\n" "--\n" @@ -87,8 +107,31 @@ static PyObject * winreg_HKEYType___exit__(PyHKEYObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(exc_type), &_Py_ID(exc_value), &_Py_ID(traceback), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"exc_type", "exc_value", "traceback", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "__exit__", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "__exit__", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; PyObject *exc_type; PyObject *exc_value; @@ -107,6 +150,10 @@ exit: return return_value; } +#endif /* (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES)) */ + +#if (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES)) + PyDoc_STRVAR(winreg_CloseKey__doc__, "CloseKey($module, hkey, /)\n" "--\n" @@ -122,6 +169,10 @@ PyDoc_STRVAR(winreg_CloseKey__doc__, #define WINREG_CLOSEKEY_METHODDEF \ {"CloseKey", (PyCFunction)winreg_CloseKey, METH_O, winreg_CloseKey__doc__}, +#endif /* (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES)) */ + +#if (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES)) && (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM)) + PyDoc_STRVAR(winreg_ConnectRegistry__doc__, "ConnectRegistry($module, computer_name, key, /)\n" "--\n" @@ -159,11 +210,7 @@ winreg_ConnectRegistry(PyObject *module, PyObject *const *args, Py_ssize_t nargs computer_name = NULL; } else if (PyUnicode_Check(args[0])) { - #if USE_UNICODE_WCHAR_CACHE - computer_name = _PyUnicode_AsUnicode(args[0]); - #else /* USE_UNICODE_WCHAR_CACHE */ computer_name = PyUnicode_AsWideCharString(args[0], NULL); - #endif /* USE_UNICODE_WCHAR_CACHE */ if (computer_name == NULL) { goto exit; } @@ -172,24 +219,26 @@ winreg_ConnectRegistry(PyObject *module, PyObject *const *args, Py_ssize_t nargs _PyArg_BadArgument("ConnectRegistry", "argument 1", "str or None", args[0]); goto exit; } - if (!clinic_HKEY_converter(args[1], &key)) { + if (!clinic_HKEY_converter(_PyModule_GetState(module), args[1], &key)) { goto exit; } _return_value = winreg_ConnectRegistry_impl(module, computer_name, key); if (_return_value == NULL) { goto exit; } - return_value = PyHKEY_FromHKEY(_return_value); + return_value = PyHKEY_FromHKEY(_PyModule_GetState(module), _return_value); exit: /* Cleanup for computer_name */ - #if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *)computer_name); - #endif /* USE_UNICODE_WCHAR_CACHE */ return return_value; } +#endif /* (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES)) && (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM)) */ + +#if (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES)) + PyDoc_STRVAR(winreg_CreateKey__doc__, "CreateKey($module, key, sub_key, /)\n" "--\n" @@ -226,18 +275,14 @@ winreg_CreateKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("CreateKey", nargs, 2, 2)) { goto exit; } - if (!clinic_HKEY_converter(args[0], &key)) { + if (!clinic_HKEY_converter(_PyModule_GetState(module), args[0], &key)) { goto exit; } if (args[1] == Py_None) { sub_key = NULL; } else if (PyUnicode_Check(args[1])) { - #if USE_UNICODE_WCHAR_CACHE - sub_key = _PyUnicode_AsUnicode(args[1]); - #else /* USE_UNICODE_WCHAR_CACHE */ sub_key = PyUnicode_AsWideCharString(args[1], NULL); - #endif /* USE_UNICODE_WCHAR_CACHE */ if (sub_key == NULL) { goto exit; } @@ -250,17 +295,19 @@ winreg_CreateKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (_return_value == NULL) { goto exit; } - return_value = PyHKEY_FromHKEY(_return_value); + return_value = PyHKEY_FromHKEY(_PyModule_GetState(module), _return_value); exit: /* Cleanup for sub_key */ - #if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *)sub_key); - #endif /* USE_UNICODE_WCHAR_CACHE */ return return_value; } +#endif /* (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES)) */ + +#if (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES)) + PyDoc_STRVAR(winreg_CreateKeyEx__doc__, "CreateKeyEx($module, /, key, sub_key, reserved=0,\n" " access=winreg.KEY_WRITE)\n" @@ -298,33 +345,93 @@ static PyObject * winreg_CreateKeyEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(key), &_Py_ID(sub_key), &_Py_ID(reserved), &_Py_ID(access), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"key", "sub_key", "reserved", "access", NULL}; - static _PyArg_Parser _parser = {"O&O&|ii:CreateKeyEx", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "CreateKeyEx", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[4]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; HKEY key; const Py_UNICODE *sub_key = NULL; int reserved = 0; REGSAM access = KEY_WRITE; HKEY _return_value; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - clinic_HKEY_converter, &key, _PyUnicode_WideCharString_Opt_Converter, &sub_key, &reserved, &access)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 4, 0, argsbuf); + if (!args) { goto exit; } + if (!clinic_HKEY_converter(_PyModule_GetState(module), args[0], &key)) { + goto exit; + } + if (args[1] == Py_None) { + sub_key = NULL; + } + else if (PyUnicode_Check(args[1])) { + sub_key = PyUnicode_AsWideCharString(args[1], NULL); + if (sub_key == NULL) { + goto exit; + } + } + else { + _PyArg_BadArgument("CreateKeyEx", "argument 'sub_key'", "str or None", args[1]); + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[2]) { + reserved = _PyLong_AsInt(args[2]); + if (reserved == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + access = _PyLong_AsInt(args[3]); + if (access == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional_pos: _return_value = winreg_CreateKeyEx_impl(module, key, sub_key, reserved, access); if (_return_value == NULL) { goto exit; } - return_value = PyHKEY_FromHKEY(_return_value); + return_value = PyHKEY_FromHKEY(_PyModule_GetState(module), _return_value); exit: /* Cleanup for sub_key */ - #if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *)sub_key); - #endif /* USE_UNICODE_WCHAR_CACHE */ return return_value; } +#endif /* (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES)) */ + +#if (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES)) + PyDoc_STRVAR(winreg_DeleteKey__doc__, "DeleteKey($module, key, sub_key, /)\n" "--\n" @@ -359,18 +466,14 @@ winreg_DeleteKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("DeleteKey", nargs, 2, 2)) { goto exit; } - if (!clinic_HKEY_converter(args[0], &key)) { + if (!clinic_HKEY_converter(_PyModule_GetState(module), args[0], &key)) { goto exit; } if (!PyUnicode_Check(args[1])) { _PyArg_BadArgument("DeleteKey", "argument 2", "str", args[1]); goto exit; } - #if USE_UNICODE_WCHAR_CACHE - sub_key = _PyUnicode_AsUnicode(args[1]); - #else /* USE_UNICODE_WCHAR_CACHE */ sub_key = PyUnicode_AsWideCharString(args[1], NULL); - #endif /* USE_UNICODE_WCHAR_CACHE */ if (sub_key == NULL) { goto exit; } @@ -378,13 +481,15 @@ winreg_DeleteKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: /* Cleanup for sub_key */ - #if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *)sub_key); - #endif /* USE_UNICODE_WCHAR_CACHE */ return return_value; } +#endif /* (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES)) */ + +#if (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES)) + PyDoc_STRVAR(winreg_DeleteKeyEx__doc__, "DeleteKeyEx($module, /, key, sub_key, access=winreg.KEY_WOW64_64KEY,\n" " reserved=0)\n" @@ -425,28 +530,83 @@ static PyObject * winreg_DeleteKeyEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(key), &_Py_ID(sub_key), &_Py_ID(access), &_Py_ID(reserved), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"key", "sub_key", "access", "reserved", NULL}; - static _PyArg_Parser _parser = {"O&O&|ii:DeleteKeyEx", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "DeleteKeyEx", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[4]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; HKEY key; const Py_UNICODE *sub_key = NULL; REGSAM access = KEY_WOW64_64KEY; int reserved = 0; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - clinic_HKEY_converter, &key, _PyUnicode_WideCharString_Converter, &sub_key, &access, &reserved)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 4, 0, argsbuf); + if (!args) { + goto exit; + } + if (!clinic_HKEY_converter(_PyModule_GetState(module), args[0], &key)) { + goto exit; + } + if (!PyUnicode_Check(args[1])) { + _PyArg_BadArgument("DeleteKeyEx", "argument 'sub_key'", "str", args[1]); goto exit; } + sub_key = PyUnicode_AsWideCharString(args[1], NULL); + if (sub_key == NULL) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[2]) { + access = _PyLong_AsInt(args[2]); + if (access == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + reserved = _PyLong_AsInt(args[3]); + if (reserved == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional_pos: return_value = winreg_DeleteKeyEx_impl(module, key, sub_key, access, reserved); exit: /* Cleanup for sub_key */ - #if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *)sub_key); - #endif /* USE_UNICODE_WCHAR_CACHE */ return return_value; } +#endif /* (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES)) */ + +#if (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES)) + PyDoc_STRVAR(winreg_DeleteValue__doc__, "DeleteValue($module, key, value, /)\n" "--\n" @@ -474,18 +634,14 @@ winreg_DeleteValue(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("DeleteValue", nargs, 2, 2)) { goto exit; } - if (!clinic_HKEY_converter(args[0], &key)) { + if (!clinic_HKEY_converter(_PyModule_GetState(module), args[0], &key)) { goto exit; } if (args[1] == Py_None) { value = NULL; } else if (PyUnicode_Check(args[1])) { - #if USE_UNICODE_WCHAR_CACHE - value = _PyUnicode_AsUnicode(args[1]); - #else /* USE_UNICODE_WCHAR_CACHE */ value = PyUnicode_AsWideCharString(args[1], NULL); - #endif /* USE_UNICODE_WCHAR_CACHE */ if (value == NULL) { goto exit; } @@ -498,13 +654,15 @@ winreg_DeleteValue(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: /* Cleanup for value */ - #if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *)value); - #endif /* USE_UNICODE_WCHAR_CACHE */ return return_value; } +#endif /* (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES)) */ + +#if (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES)) + PyDoc_STRVAR(winreg_EnumKey__doc__, "EnumKey($module, key, index, /)\n" "--\n" @@ -536,7 +694,7 @@ winreg_EnumKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("EnumKey", nargs, 2, 2)) { goto exit; } - if (!clinic_HKEY_converter(args[0], &key)) { + if (!clinic_HKEY_converter(_PyModule_GetState(module), args[0], &key)) { goto exit; } index = _PyLong_AsInt(args[1]); @@ -549,6 +707,10 @@ exit: return return_value; } +#endif /* (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES)) */ + +#if (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES)) + PyDoc_STRVAR(winreg_EnumValue__doc__, "EnumValue($module, key, index, /)\n" "--\n" @@ -589,7 +751,7 @@ winreg_EnumValue(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("EnumValue", nargs, 2, 2)) { goto exit; } - if (!clinic_HKEY_converter(args[0], &key)) { + if (!clinic_HKEY_converter(_PyModule_GetState(module), args[0], &key)) { goto exit; } index = _PyLong_AsInt(args[1]); @@ -602,6 +764,10 @@ exit: return return_value; } +#endif /* (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES)) */ + +#if (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES)) + PyDoc_STRVAR(winreg_ExpandEnvironmentStrings__doc__, "ExpandEnvironmentStrings($module, string, /)\n" "--\n" @@ -625,11 +791,7 @@ winreg_ExpandEnvironmentStrings(PyObject *module, PyObject *arg) _PyArg_BadArgument("ExpandEnvironmentStrings", "argument", "str", arg); goto exit; } - #if USE_UNICODE_WCHAR_CACHE - string = _PyUnicode_AsUnicode(arg); - #else /* USE_UNICODE_WCHAR_CACHE */ string = PyUnicode_AsWideCharString(arg, NULL); - #endif /* USE_UNICODE_WCHAR_CACHE */ if (string == NULL) { goto exit; } @@ -637,13 +799,15 @@ winreg_ExpandEnvironmentStrings(PyObject *module, PyObject *arg) exit: /* Cleanup for string */ - #if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *)string); - #endif /* USE_UNICODE_WCHAR_CACHE */ return return_value; } +#endif /* (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES)) */ + +#if (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES)) && (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM)) + PyDoc_STRVAR(winreg_FlushKey__doc__, "FlushKey($module, key, /)\n" "--\n" @@ -675,7 +839,7 @@ winreg_FlushKey(PyObject *module, PyObject *arg) PyObject *return_value = NULL; HKEY key; - if (!clinic_HKEY_converter(arg, &key)) { + if (!clinic_HKEY_converter(_PyModule_GetState(module), arg, &key)) { goto exit; } return_value = winreg_FlushKey_impl(module, key); @@ -684,6 +848,10 @@ exit: return return_value; } +#endif /* (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES)) && (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM)) */ + +#if (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES)) && (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM)) + PyDoc_STRVAR(winreg_LoadKey__doc__, "LoadKey($module, key, sub_key, file_name, /)\n" "--\n" @@ -730,18 +898,14 @@ winreg_LoadKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("LoadKey", nargs, 3, 3)) { goto exit; } - if (!clinic_HKEY_converter(args[0], &key)) { + if (!clinic_HKEY_converter(_PyModule_GetState(module), args[0], &key)) { goto exit; } if (!PyUnicode_Check(args[1])) { _PyArg_BadArgument("LoadKey", "argument 2", "str", args[1]); goto exit; } - #if USE_UNICODE_WCHAR_CACHE - sub_key = _PyUnicode_AsUnicode(args[1]); - #else /* USE_UNICODE_WCHAR_CACHE */ sub_key = PyUnicode_AsWideCharString(args[1], NULL); - #endif /* USE_UNICODE_WCHAR_CACHE */ if (sub_key == NULL) { goto exit; } @@ -749,11 +913,7 @@ winreg_LoadKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs) _PyArg_BadArgument("LoadKey", "argument 3", "str", args[2]); goto exit; } - #if USE_UNICODE_WCHAR_CACHE - file_name = _PyUnicode_AsUnicode(args[2]); - #else /* USE_UNICODE_WCHAR_CACHE */ file_name = PyUnicode_AsWideCharString(args[2], NULL); - #endif /* USE_UNICODE_WCHAR_CACHE */ if (file_name == NULL) { goto exit; } @@ -761,17 +921,17 @@ winreg_LoadKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: /* Cleanup for sub_key */ - #if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *)sub_key); - #endif /* USE_UNICODE_WCHAR_CACHE */ /* Cleanup for file_name */ - #if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *)file_name); - #endif /* USE_UNICODE_WCHAR_CACHE */ return return_value; } +#endif /* (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES)) && (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM)) */ + +#if (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES)) + PyDoc_STRVAR(winreg_OpenKey__doc__, "OpenKey($module, /, key, sub_key, reserved=0, access=winreg.KEY_READ)\n" "--\n" @@ -802,33 +962,93 @@ static PyObject * winreg_OpenKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(key), &_Py_ID(sub_key), &_Py_ID(reserved), &_Py_ID(access), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"key", "sub_key", "reserved", "access", NULL}; - static _PyArg_Parser _parser = {"O&O&|ii:OpenKey", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "OpenKey", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[4]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; HKEY key; const Py_UNICODE *sub_key = NULL; int reserved = 0; REGSAM access = KEY_READ; HKEY _return_value; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - clinic_HKEY_converter, &key, _PyUnicode_WideCharString_Opt_Converter, &sub_key, &reserved, &access)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 4, 0, argsbuf); + if (!args) { + goto exit; + } + if (!clinic_HKEY_converter(_PyModule_GetState(module), args[0], &key)) { goto exit; } + if (args[1] == Py_None) { + sub_key = NULL; + } + else if (PyUnicode_Check(args[1])) { + sub_key = PyUnicode_AsWideCharString(args[1], NULL); + if (sub_key == NULL) { + goto exit; + } + } + else { + _PyArg_BadArgument("OpenKey", "argument 'sub_key'", "str or None", args[1]); + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[2]) { + reserved = _PyLong_AsInt(args[2]); + if (reserved == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + access = _PyLong_AsInt(args[3]); + if (access == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional_pos: _return_value = winreg_OpenKey_impl(module, key, sub_key, reserved, access); if (_return_value == NULL) { goto exit; } - return_value = PyHKEY_FromHKEY(_return_value); + return_value = PyHKEY_FromHKEY(_PyModule_GetState(module), _return_value); exit: /* Cleanup for sub_key */ - #if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *)sub_key); - #endif /* USE_UNICODE_WCHAR_CACHE */ return return_value; } +#endif /* (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES)) */ + +#if (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES)) + PyDoc_STRVAR(winreg_OpenKeyEx__doc__, "OpenKeyEx($module, /, key, sub_key, reserved=0, access=winreg.KEY_READ)\n" "--\n" @@ -859,33 +1079,93 @@ static PyObject * winreg_OpenKeyEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(key), &_Py_ID(sub_key), &_Py_ID(reserved), &_Py_ID(access), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"key", "sub_key", "reserved", "access", NULL}; - static _PyArg_Parser _parser = {"O&O&|ii:OpenKeyEx", _keywords, 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "OpenKeyEx", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[4]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; HKEY key; const Py_UNICODE *sub_key = NULL; int reserved = 0; REGSAM access = KEY_READ; HKEY _return_value; - if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, - clinic_HKEY_converter, &key, _PyUnicode_WideCharString_Opt_Converter, &sub_key, &reserved, &access)) { + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 4, 0, argsbuf); + if (!args) { + goto exit; + } + if (!clinic_HKEY_converter(_PyModule_GetState(module), args[0], &key)) { + goto exit; + } + if (args[1] == Py_None) { + sub_key = NULL; + } + else if (PyUnicode_Check(args[1])) { + sub_key = PyUnicode_AsWideCharString(args[1], NULL); + if (sub_key == NULL) { + goto exit; + } + } + else { + _PyArg_BadArgument("OpenKeyEx", "argument 'sub_key'", "str or None", args[1]); goto exit; } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[2]) { + reserved = _PyLong_AsInt(args[2]); + if (reserved == -1 && PyErr_Occurred()) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_pos; + } + } + access = _PyLong_AsInt(args[3]); + if (access == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional_pos: _return_value = winreg_OpenKeyEx_impl(module, key, sub_key, reserved, access); if (_return_value == NULL) { goto exit; } - return_value = PyHKEY_FromHKEY(_return_value); + return_value = PyHKEY_FromHKEY(_PyModule_GetState(module), _return_value); exit: /* Cleanup for sub_key */ - #if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *)sub_key); - #endif /* USE_UNICODE_WCHAR_CACHE */ return return_value; } +#endif /* (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES)) */ + +#if (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES)) + PyDoc_STRVAR(winreg_QueryInfoKey__doc__, "QueryInfoKey($module, key, /)\n" "--\n" @@ -913,7 +1193,7 @@ winreg_QueryInfoKey(PyObject *module, PyObject *arg) PyObject *return_value = NULL; HKEY key; - if (!clinic_HKEY_converter(arg, &key)) { + if (!clinic_HKEY_converter(_PyModule_GetState(module), arg, &key)) { goto exit; } return_value = winreg_QueryInfoKey_impl(module, key); @@ -922,6 +1202,10 @@ exit: return return_value; } +#endif /* (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES)) */ + +#if (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES)) + PyDoc_STRVAR(winreg_QueryValue__doc__, "QueryValue($module, key, sub_key, /)\n" "--\n" @@ -958,18 +1242,14 @@ winreg_QueryValue(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("QueryValue", nargs, 2, 2)) { goto exit; } - if (!clinic_HKEY_converter(args[0], &key)) { + if (!clinic_HKEY_converter(_PyModule_GetState(module), args[0], &key)) { goto exit; } if (args[1] == Py_None) { sub_key = NULL; } else if (PyUnicode_Check(args[1])) { - #if USE_UNICODE_WCHAR_CACHE - sub_key = _PyUnicode_AsUnicode(args[1]); - #else /* USE_UNICODE_WCHAR_CACHE */ sub_key = PyUnicode_AsWideCharString(args[1], NULL); - #endif /* USE_UNICODE_WCHAR_CACHE */ if (sub_key == NULL) { goto exit; } @@ -982,13 +1262,15 @@ winreg_QueryValue(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: /* Cleanup for sub_key */ - #if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *)sub_key); - #endif /* USE_UNICODE_WCHAR_CACHE */ return return_value; } +#endif /* (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES)) */ + +#if (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES)) + PyDoc_STRVAR(winreg_QueryValueEx__doc__, "QueryValueEx($module, key, name, /)\n" "--\n" @@ -1021,18 +1303,14 @@ winreg_QueryValueEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("QueryValueEx", nargs, 2, 2)) { goto exit; } - if (!clinic_HKEY_converter(args[0], &key)) { + if (!clinic_HKEY_converter(_PyModule_GetState(module), args[0], &key)) { goto exit; } if (args[1] == Py_None) { name = NULL; } else if (PyUnicode_Check(args[1])) { - #if USE_UNICODE_WCHAR_CACHE - name = _PyUnicode_AsUnicode(args[1]); - #else /* USE_UNICODE_WCHAR_CACHE */ name = PyUnicode_AsWideCharString(args[1], NULL); - #endif /* USE_UNICODE_WCHAR_CACHE */ if (name == NULL) { goto exit; } @@ -1045,13 +1323,15 @@ winreg_QueryValueEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: /* Cleanup for name */ - #if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *)name); - #endif /* USE_UNICODE_WCHAR_CACHE */ return return_value; } +#endif /* (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES)) */ + +#if (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES)) && (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM)) + PyDoc_STRVAR(winreg_SaveKey__doc__, "SaveKey($module, key, file_name, /)\n" "--\n" @@ -1089,18 +1369,14 @@ winreg_SaveKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs) if (!_PyArg_CheckPositional("SaveKey", nargs, 2, 2)) { goto exit; } - if (!clinic_HKEY_converter(args[0], &key)) { + if (!clinic_HKEY_converter(_PyModule_GetState(module), args[0], &key)) { goto exit; } if (!PyUnicode_Check(args[1])) { _PyArg_BadArgument("SaveKey", "argument 2", "str", args[1]); goto exit; } - #if USE_UNICODE_WCHAR_CACHE - file_name = _PyUnicode_AsUnicode(args[1]); - #else /* USE_UNICODE_WCHAR_CACHE */ file_name = PyUnicode_AsWideCharString(args[1], NULL); - #endif /* USE_UNICODE_WCHAR_CACHE */ if (file_name == NULL) { goto exit; } @@ -1108,13 +1384,15 @@ winreg_SaveKey(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: /* Cleanup for file_name */ - #if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *)file_name); - #endif /* USE_UNICODE_WCHAR_CACHE */ return return_value; } +#endif /* (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES)) && (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM)) */ + +#if (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES)) + PyDoc_STRVAR(winreg_SetValue__doc__, "SetValue($module, key, sub_key, type, value, /)\n" "--\n" @@ -1157,21 +1435,49 @@ winreg_SetValue(PyObject *module, PyObject *const *args, Py_ssize_t nargs) DWORD type; PyObject *value_obj; - if (!_PyArg_ParseStack(args, nargs, "O&O&kU:SetValue", - clinic_HKEY_converter, &key, _PyUnicode_WideCharString_Opt_Converter, &sub_key, &type, &value_obj)) { + if (!_PyArg_CheckPositional("SetValue", nargs, 4, 4)) { + goto exit; + } + if (!clinic_HKEY_converter(_PyModule_GetState(module), args[0], &key)) { + goto exit; + } + if (args[1] == Py_None) { + sub_key = NULL; + } + else if (PyUnicode_Check(args[1])) { + sub_key = PyUnicode_AsWideCharString(args[1], NULL); + if (sub_key == NULL) { + goto exit; + } + } + else { + _PyArg_BadArgument("SetValue", "argument 2", "str or None", args[1]); + goto exit; + } + if (!_PyLong_UnsignedLong_Converter(args[2], &type)) { + goto exit; + } + if (!PyUnicode_Check(args[3])) { + _PyArg_BadArgument("SetValue", "argument 4", "str", args[3]); goto exit; } + if (PyUnicode_READY(args[3]) == -1) { + goto exit; + } + value_obj = args[3]; return_value = winreg_SetValue_impl(module, key, sub_key, type, value_obj); exit: /* Cleanup for sub_key */ - #if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *)sub_key); - #endif /* USE_UNICODE_WCHAR_CACHE */ return return_value; } +#endif /* (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES)) */ + +#if (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES)) + PyDoc_STRVAR(winreg_SetValueEx__doc__, "SetValueEx($module, key, value_name, reserved, type, value, /)\n" "--\n" @@ -1233,21 +1539,43 @@ winreg_SetValueEx(PyObject *module, PyObject *const *args, Py_ssize_t nargs) DWORD type; PyObject *value; - if (!_PyArg_ParseStack(args, nargs, "O&O&OkO:SetValueEx", - clinic_HKEY_converter, &key, _PyUnicode_WideCharString_Opt_Converter, &value_name, &reserved, &type, &value)) { + if (!_PyArg_CheckPositional("SetValueEx", nargs, 5, 5)) { + goto exit; + } + if (!clinic_HKEY_converter(_PyModule_GetState(module), args[0], &key)) { + goto exit; + } + if (args[1] == Py_None) { + value_name = NULL; + } + else if (PyUnicode_Check(args[1])) { + value_name = PyUnicode_AsWideCharString(args[1], NULL); + if (value_name == NULL) { + goto exit; + } + } + else { + _PyArg_BadArgument("SetValueEx", "argument 2", "str or None", args[1]); + goto exit; + } + reserved = args[2]; + if (!_PyLong_UnsignedLong_Converter(args[3], &type)) { goto exit; } + value = args[4]; return_value = winreg_SetValueEx_impl(module, key, value_name, reserved, type, value); exit: /* Cleanup for value_name */ - #if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *)value_name); - #endif /* USE_UNICODE_WCHAR_CACHE */ return return_value; } +#endif /* (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES)) */ + +#if (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES)) && (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM)) + PyDoc_STRVAR(winreg_DisableReflectionKey__doc__, "DisableReflectionKey($module, key, /)\n" "--\n" @@ -1275,7 +1603,7 @@ winreg_DisableReflectionKey(PyObject *module, PyObject *arg) PyObject *return_value = NULL; HKEY key; - if (!clinic_HKEY_converter(arg, &key)) { + if (!clinic_HKEY_converter(_PyModule_GetState(module), arg, &key)) { goto exit; } return_value = winreg_DisableReflectionKey_impl(module, key); @@ -1284,6 +1612,10 @@ exit: return return_value; } +#endif /* (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES)) && (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM)) */ + +#if (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES)) && (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM)) + PyDoc_STRVAR(winreg_EnableReflectionKey__doc__, "EnableReflectionKey($module, key, /)\n" "--\n" @@ -1309,7 +1641,7 @@ winreg_EnableReflectionKey(PyObject *module, PyObject *arg) PyObject *return_value = NULL; HKEY key; - if (!clinic_HKEY_converter(arg, &key)) { + if (!clinic_HKEY_converter(_PyModule_GetState(module), arg, &key)) { goto exit; } return_value = winreg_EnableReflectionKey_impl(module, key); @@ -1318,6 +1650,10 @@ exit: return return_value; } +#endif /* (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES)) && (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM)) */ + +#if (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES)) && (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM)) + PyDoc_STRVAR(winreg_QueryReflectionKey__doc__, "QueryReflectionKey($module, key, /)\n" "--\n" @@ -1341,7 +1677,7 @@ winreg_QueryReflectionKey(PyObject *module, PyObject *arg) PyObject *return_value = NULL; HKEY key; - if (!clinic_HKEY_converter(arg, &key)) { + if (!clinic_HKEY_converter(_PyModule_GetState(module), arg, &key)) { goto exit; } return_value = winreg_QueryReflectionKey_impl(module, key); @@ -1349,4 +1685,114 @@ winreg_QueryReflectionKey(PyObject *module, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=e83bdaabb4fa2167 input=a9049054013a1b77]*/ + +#endif /* (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES)) && (defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM)) */ + +#ifndef WINREG_HKEYTYPE_CLOSE_METHODDEF + #define WINREG_HKEYTYPE_CLOSE_METHODDEF +#endif /* !defined(WINREG_HKEYTYPE_CLOSE_METHODDEF) */ + +#ifndef WINREG_HKEYTYPE_DETACH_METHODDEF + #define WINREG_HKEYTYPE_DETACH_METHODDEF +#endif /* !defined(WINREG_HKEYTYPE_DETACH_METHODDEF) */ + +#ifndef WINREG_HKEYTYPE___ENTER___METHODDEF + #define WINREG_HKEYTYPE___ENTER___METHODDEF +#endif /* !defined(WINREG_HKEYTYPE___ENTER___METHODDEF) */ + +#ifndef WINREG_HKEYTYPE___EXIT___METHODDEF + #define WINREG_HKEYTYPE___EXIT___METHODDEF +#endif /* !defined(WINREG_HKEYTYPE___EXIT___METHODDEF) */ + +#ifndef WINREG_CLOSEKEY_METHODDEF + #define WINREG_CLOSEKEY_METHODDEF +#endif /* !defined(WINREG_CLOSEKEY_METHODDEF) */ + +#ifndef WINREG_CONNECTREGISTRY_METHODDEF + #define WINREG_CONNECTREGISTRY_METHODDEF +#endif /* !defined(WINREG_CONNECTREGISTRY_METHODDEF) */ + +#ifndef WINREG_CREATEKEY_METHODDEF + #define WINREG_CREATEKEY_METHODDEF +#endif /* !defined(WINREG_CREATEKEY_METHODDEF) */ + +#ifndef WINREG_CREATEKEYEX_METHODDEF + #define WINREG_CREATEKEYEX_METHODDEF +#endif /* !defined(WINREG_CREATEKEYEX_METHODDEF) */ + +#ifndef WINREG_DELETEKEY_METHODDEF + #define WINREG_DELETEKEY_METHODDEF +#endif /* !defined(WINREG_DELETEKEY_METHODDEF) */ + +#ifndef WINREG_DELETEKEYEX_METHODDEF + #define WINREG_DELETEKEYEX_METHODDEF +#endif /* !defined(WINREG_DELETEKEYEX_METHODDEF) */ + +#ifndef WINREG_DELETEVALUE_METHODDEF + #define WINREG_DELETEVALUE_METHODDEF +#endif /* !defined(WINREG_DELETEVALUE_METHODDEF) */ + +#ifndef WINREG_ENUMKEY_METHODDEF + #define WINREG_ENUMKEY_METHODDEF +#endif /* !defined(WINREG_ENUMKEY_METHODDEF) */ + +#ifndef WINREG_ENUMVALUE_METHODDEF + #define WINREG_ENUMVALUE_METHODDEF +#endif /* !defined(WINREG_ENUMVALUE_METHODDEF) */ + +#ifndef WINREG_EXPANDENVIRONMENTSTRINGS_METHODDEF + #define WINREG_EXPANDENVIRONMENTSTRINGS_METHODDEF +#endif /* !defined(WINREG_EXPANDENVIRONMENTSTRINGS_METHODDEF) */ + +#ifndef WINREG_FLUSHKEY_METHODDEF + #define WINREG_FLUSHKEY_METHODDEF +#endif /* !defined(WINREG_FLUSHKEY_METHODDEF) */ + +#ifndef WINREG_LOADKEY_METHODDEF + #define WINREG_LOADKEY_METHODDEF +#endif /* !defined(WINREG_LOADKEY_METHODDEF) */ + +#ifndef WINREG_OPENKEY_METHODDEF + #define WINREG_OPENKEY_METHODDEF +#endif /* !defined(WINREG_OPENKEY_METHODDEF) */ + +#ifndef WINREG_OPENKEYEX_METHODDEF + #define WINREG_OPENKEYEX_METHODDEF +#endif /* !defined(WINREG_OPENKEYEX_METHODDEF) */ + +#ifndef WINREG_QUERYINFOKEY_METHODDEF + #define WINREG_QUERYINFOKEY_METHODDEF +#endif /* !defined(WINREG_QUERYINFOKEY_METHODDEF) */ + +#ifndef WINREG_QUERYVALUE_METHODDEF + #define WINREG_QUERYVALUE_METHODDEF +#endif /* !defined(WINREG_QUERYVALUE_METHODDEF) */ + +#ifndef WINREG_QUERYVALUEEX_METHODDEF + #define WINREG_QUERYVALUEEX_METHODDEF +#endif /* !defined(WINREG_QUERYVALUEEX_METHODDEF) */ + +#ifndef WINREG_SAVEKEY_METHODDEF + #define WINREG_SAVEKEY_METHODDEF +#endif /* !defined(WINREG_SAVEKEY_METHODDEF) */ + +#ifndef WINREG_SETVALUE_METHODDEF + #define WINREG_SETVALUE_METHODDEF +#endif /* !defined(WINREG_SETVALUE_METHODDEF) */ + +#ifndef WINREG_SETVALUEEX_METHODDEF + #define WINREG_SETVALUEEX_METHODDEF +#endif /* !defined(WINREG_SETVALUEEX_METHODDEF) */ + +#ifndef WINREG_DISABLEREFLECTIONKEY_METHODDEF + #define WINREG_DISABLEREFLECTIONKEY_METHODDEF +#endif /* !defined(WINREG_DISABLEREFLECTIONKEY_METHODDEF) */ + +#ifndef WINREG_ENABLEREFLECTIONKEY_METHODDEF + #define WINREG_ENABLEREFLECTIONKEY_METHODDEF +#endif /* !defined(WINREG_ENABLEREFLECTIONKEY_METHODDEF) */ + +#ifndef WINREG_QUERYREFLECTIONKEY_METHODDEF + #define WINREG_QUERYREFLECTIONKEY_METHODDEF +#endif /* !defined(WINREG_QUERYREFLECTIONKEY_METHODDEF) */ +/*[clinic end generated code: output=15dc2e6c4d4e2ad5 input=a9049054013a1b77]*/ diff --git a/PC/clinic/winsound.c.h b/PC/clinic/winsound.c.h index 9f99b8e4..241d547c 100644 --- a/PC/clinic/winsound.c.h +++ b/PC/clinic/winsound.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(winsound_PlaySound__doc__, "PlaySound($module, /, sound, flags)\n" "--\n" @@ -23,8 +29,31 @@ static PyObject * winsound_PlaySound(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(sound), &_Py_ID(flags), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"sound", "flags", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "PlaySound", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "PlaySound", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; PyObject *sound; int flags; @@ -66,8 +95,31 @@ static PyObject * winsound_Beep(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(frequency), &_Py_ID(duration), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"frequency", "duration", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "Beep", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "Beep", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; int frequency; int duration; @@ -108,8 +160,31 @@ static PyObject * winsound_MessageBeep(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(type), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"type", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "MessageBeep", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "MessageBeep", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; int type = MB_OK; @@ -131,4 +206,4 @@ skip_optional_pos: exit: return return_value; } -/*[clinic end generated code: output=b7e53fab4f26aeaf input=a9049054013a1b77]*/ +/*[clinic end generated code: output=f70b7730127208d8 input=a9049054013a1b77]*/ diff --git a/PC/config.c b/PC/config.c index 9d900c78..9d0fe6f8 100644 --- a/PC/config.c +++ b/PC/config.c @@ -20,8 +20,7 @@ extern PyObject* PyInit_nt(void); extern PyObject* PyInit__operator(void); extern PyObject* PyInit__signal(void); extern PyObject* PyInit__sha1(void); -extern PyObject* PyInit__sha256(void); -extern PyObject* PyInit__sha512(void); +extern PyObject* PyInit__sha2(void); extern PyObject* PyInit__sha3(void); extern PyObject* PyInit__statistics(void); extern PyObject* PyInit__typing(void); @@ -37,16 +36,21 @@ extern PyObject* PyInit__weakref(void); /* XXX: These two should really be extracted to standalone extensions. */ extern PyObject* PyInit_xxsubtype(void); extern PyObject* PyInit__xxsubinterpreters(void); +extern PyObject* PyInit__xxinterpchannels(void); extern PyObject* PyInit__random(void); extern PyObject* PyInit_itertools(void); extern PyObject* PyInit__collections(void); extern PyObject* PyInit__heapq(void); extern PyObject* PyInit__bisect(void); extern PyObject* PyInit__symtable(void); +#if defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_GAMES) extern PyObject* PyInit_mmap(void); +#endif extern PyObject* PyInit__csv(void); extern PyObject* PyInit__sre(void); +#if defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES) extern PyObject* PyInit_winreg(void); +#endif extern PyObject* PyInit__struct(void); extern PyObject* PyInit__datetime(void); extern PyObject* PyInit__functools(void); @@ -97,8 +101,7 @@ struct _inittab _PyImport_Inittab[] = { {"_signal", PyInit__signal}, {"_md5", PyInit__md5}, {"_sha1", PyInit__sha1}, - {"_sha256", PyInit__sha256}, - {"_sha512", PyInit__sha512}, + {"_sha2", PyInit__sha2}, {"_sha3", PyInit__sha3}, {"_blake2", PyInit__blake2}, {"time", PyInit_time}, @@ -123,10 +126,14 @@ struct _inittab _PyImport_Inittab[] = { {"itertools", PyInit_itertools}, {"_collections", PyInit__collections}, {"_symtable", PyInit__symtable}, +#if defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_GAMES) {"mmap", PyInit_mmap}, +#endif {"_csv", PyInit__csv}, {"_sre", PyInit__sre}, +#if defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES) {"winreg", PyInit_winreg}, +#endif {"_struct", PyInit__struct}, {"_datetime", PyInit__datetime}, {"_functools", PyInit__functools}, @@ -134,6 +141,7 @@ struct _inittab _PyImport_Inittab[] = { {"xxsubtype", PyInit_xxsubtype}, {"_xxsubinterpreters", PyInit__xxsubinterpreters}, + {"_xxinterpchannels", PyInit__xxinterpchannels}, #ifdef _Py_HAVE_ZLIB {"zlib", PyInit_zlib}, #endif diff --git a/PC/config_minimal.c b/PC/config_minimal.c index 928a4efd..9a66ea1d 100644 --- a/PC/config_minimal.c +++ b/PC/config_minimal.c @@ -5,8 +5,10 @@ #include "Python.h" +#ifdef Py_ENABLE_SHARED /* Define extern variables omitted from minimal builds */ void *PyWin_DLLhModule = NULL; +#endif extern PyObject* PyInit_faulthandler(void); @@ -14,7 +16,9 @@ extern PyObject* PyInit__tracemalloc(void); extern PyObject* PyInit_gc(void); extern PyObject* PyInit_nt(void); extern PyObject* PyInit__signal(void); +#if defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES) extern PyObject* PyInit_winreg(void); +#endif extern PyObject* PyInit__ast(void); extern PyObject* PyInit__io(void); @@ -35,7 +39,9 @@ struct _inittab _PyImport_Inittab[] = { {"_tokenize", PyInit__tokenize}, {"_tracemalloc", PyInit__tracemalloc}, +#if defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES) {"winreg", PyInit_winreg}, +#endif /* This module "lives in" with marshal.c */ {"marshal", PyMarshal_Init}, diff --git a/PC/empty.c b/PC/empty.c deleted file mode 100644 index 846b4d0d..00000000 --- a/PC/empty.c +++ /dev/null @@ -1,6 +0,0 @@ -#include <windows.h> -int __stdcall -WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) -{ - return 0; -} \ No newline at end of file diff --git a/PC/launcher.c b/PC/launcher.c index da566a18..dc265533 100644 --- a/PC/launcher.c +++ b/PC/launcher.c @@ -449,7 +449,7 @@ locate_pythons_for_key(HKEY root, REGSAM flags) } static void -locate_store_pythons() +locate_store_pythons(void) { #if defined(_M_X64) /* 64bit process, so look in native registry */ @@ -466,7 +466,7 @@ locate_store_pythons() } static void -locate_venv_python() +locate_venv_python(void) { static wchar_t venv_python[MAX_PATH]; INSTALLED_PYTHON * ip; @@ -495,7 +495,7 @@ locate_venv_python() } static void -locate_all_pythons() +locate_all_pythons(void) { /* venv Python is highest priority */ locate_venv_python(); @@ -694,7 +694,7 @@ static wchar_t wrapped_script_path[MAX_PATH]; * valid wrapped script file. */ static void -locate_wrapped_script() +locate_wrapped_script(void) { wchar_t * p; size_t plen; @@ -770,8 +770,7 @@ run_child(wchar_t * cmdline) window, or fetching a message). As this launcher doesn't do this directly, that cursor remains even after the child process does these things. We avoid that by doing a simple post+get message. - See http://bugs.python.org/issue17290 and - https://bitbucket.org/vinay.sajip/pylauncher/issue/20/busy-cursor-for-a-long-time-when-running + See http://bugs.python.org/issue17290 */ MSG msg; @@ -1035,7 +1034,7 @@ read_config_file(wchar_t * config_path) } } -static void read_commands() +static void read_commands(void) { if (launcher_ini_path[0]) read_config_file(launcher_ini_path); @@ -1685,7 +1684,7 @@ wcsdup_pad(const wchar_t *s, int padding, int *newlen) } static wchar_t * -get_process_name() +get_process_name(void) { DWORD bufferLen = MAX_PATH; DWORD len = bufferLen; diff --git a/PC/launcher2.c b/PC/launcher2.c index 50685a0e..bb500d4b 100644 --- a/PC/launcher2.c +++ b/PC/launcher2.c @@ -132,7 +132,7 @@ typedef BOOL (*PIsWow64Process2)(HANDLE, USHORT*, USHORT*); USHORT -_getNativeMachine() +_getNativeMachine(void) { static USHORT _nativeMachine = IMAGE_FILE_MACHINE_UNKNOWN; if (_nativeMachine == IMAGE_FILE_MACHINE_UNKNOWN) { @@ -163,14 +163,14 @@ _getNativeMachine() bool -isAMD64Host() +isAMD64Host(void) { return _getNativeMachine() == IMAGE_FILE_MACHINE_AMD64; } bool -isARM64Host() +isARM64Host(void) { return _getNativeMachine() == IMAGE_FILE_MACHINE_ARM64; } @@ -492,10 +492,14 @@ dumpSearchInfo(SearchInfo *search) return; } -#define DEBUGNAME(s) L"SearchInfo." ## s -#define DEBUG(s) debug(DEBUGNAME(#s) L": %s\n", (search->s) ? (search->s) : L"(null)") -#define DEBUG_2(s, sl) _debugStringAndLength((search->s), (search->sl), DEBUGNAME(#s)) -#define DEBUG_BOOL(s) debug(DEBUGNAME(#s) L": %s\n", (search->s) ? L"True" : L"False") +#ifdef __clang__ +#define DEBUGNAME(s) L # s +#else +#define DEBUGNAME(s) # s +#endif +#define DEBUG(s) debug(L"SearchInfo." DEBUGNAME(s) L": %s\n", (search->s) ? (search->s) : L"(null)") +#define DEBUG_2(s, sl) _debugStringAndLength((search->s), (search->sl), L"SearchInfo." DEBUGNAME(s)) +#define DEBUG_BOOL(s) debug(L"SearchInfo." DEBUGNAME(s) L": %s\n", (search->s) ? L"True" : L"False") DEBUG(originalCmdLine); DEBUG(restOfCmdLine); DEBUG(executablePath); @@ -2469,8 +2473,7 @@ launchEnvironment(const SearchInfo *search, const EnvironmentInfo *launch, wchar window, or fetching a message). As this launcher doesn't do this directly, that cursor remains even after the child process does these things. We avoid that by doing a simple post+get message. - See http://bugs.python.org/issue17290 and - https://bitbucket.org/vinay.sajip/pylauncher/issue/20/busy-cursor-for-a-long-time-when-running + See http://bugs.python.org/issue17290 */ MSG msg; diff --git a/PC/layout/main.py b/PC/layout/main.py index 8e69ecc2..c9246007 100644 --- a/PC/layout/main.py +++ b/PC/layout/main.py @@ -8,11 +8,8 @@ __author__ = "Steve Dower <steve.dower@python.org>" __version__ = "3.8" import argparse -import functools import os -import re import shutil -import subprocess import sys import tempfile import zipfile @@ -38,7 +35,7 @@ TEST_DIRS_ONLY = FileNameSet("test", "tests") IDLE_DIRS_ONLY = FileNameSet("idlelib") -TCLTK_PYDS_ONLY = FileStemSet("tcl*", "tk*", "_tkinter") +TCLTK_PYDS_ONLY = FileStemSet("tcl*", "tk*", "_tkinter", "zlib1") TCLTK_DIRS_ONLY = FileNameSet("tkinter", "turtledemo") TCLTK_FILES_ONLY = FileNameSet("turtle.py") @@ -61,7 +58,7 @@ CDF_FILES = FileSuffixSet(".cdf") DATA_DIRS = FileNameSet("data") -TOOLS_DIRS = FileNameSet("scripts", "i18n", "demo", "parser") +TOOLS_DIRS = FileNameSet("scripts", "i18n", "parser") TOOLS_FILES = FileSuffixSet(".py", ".pyw", ".txt") diff --git a/PC/layout/support/appxmanifest.py b/PC/layout/support/appxmanifest.py index 427a36f3..1fb03380 100644 --- a/PC/layout/support/appxmanifest.py +++ b/PC/layout/support/appxmanifest.py @@ -6,13 +6,11 @@ __author__ = "Steve Dower <steve.dower@python.org>" __version__ = "3.8" -import collections import ctypes import io import os -import sys -from pathlib import Path, PureWindowsPath +from pathlib import PureWindowsPath from xml.etree import ElementTree as ET from .constants import * @@ -88,7 +86,8 @@ APPXMANIFEST_NS = { } APPXMANIFEST_TEMPLATE = """<?xml version="1.0" encoding="utf-8"?> -<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" +<Package IgnorableNamespaces="desktop4 desktop6" + xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities" xmlns:rescap4="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities/4" diff --git a/PC/layout/support/catalog.py b/PC/layout/support/catalog.py index 43121187..c9d87cb8 100644 --- a/PC/layout/support/catalog.py +++ b/PC/layout/support/catalog.py @@ -6,8 +6,6 @@ __author__ = "Steve Dower <steve.dower@python.org>" __version__ = "3.8" -import sys - __all__ = ["PYTHON_CAT_NAME", "PYTHON_CDF_NAME"] diff --git a/PC/layout/support/constants.py b/PC/layout/support/constants.py index 6efd8bcd..8195c3dc 100644 --- a/PC/layout/support/constants.py +++ b/PC/layout/support/constants.py @@ -6,7 +6,6 @@ __author__ = "Steve Dower <steve.dower@python.org>" __version__ = "3.8" import os -import re import struct import sys diff --git a/PC/layout/support/options.py b/PC/layout/support/options.py index e8310293..60256fb3 100644 --- a/PC/layout/support/options.py +++ b/PC/layout/support/options.py @@ -18,7 +18,6 @@ OPTIONS = { "stable": {"help": "stable ABI stub"}, "pip": {"help": "pip"}, "pip-user": {"help": "pip.ini file for default --user"}, - "distutils": {"help": "distutils"}, "tcltk": {"help": "Tcl, Tk and tkinter"}, "idle": {"help": "Idle"}, "tests": {"help": "test suite"}, @@ -42,8 +41,6 @@ PRESETS = { "options": [ "stable", "pip", - "pip-user", - "distutils", "tcltk", "idle", "venv", @@ -57,10 +54,8 @@ PRESETS = { "help": "nuget package", "options": [ "dev", - "tools", "pip", "stable", - "distutils", "venv", "props", "nuspec", @@ -72,11 +67,9 @@ PRESETS = { "options": [ "stable", "pip", - "distutils", "tcltk", "idle", "tests", - "tools", "venv", "dev", "symbols", diff --git a/PC/layout/support/pip.py b/PC/layout/support/pip.py index c54acb25..0a6582ac 100644 --- a/PC/layout/support/pip.py +++ b/PC/layout/support/pip.py @@ -67,7 +67,6 @@ def extract_pip_files(ns): "--no-color", "install", "pip", - "setuptools", "--upgrade", "--target", str(dest), diff --git a/PC/layout/support/props.py b/PC/layout/support/props.py index 1eb9b7c0..c7a7a0ce 100644 --- a/PC/layout/support/props.py +++ b/PC/layout/support/props.py @@ -36,7 +36,6 @@ PROPS_TEMPLATE = r"""<?xml version="1.0" encoding="utf-8"?> <PythonVersion>{PYTHON_VERSION}</PythonVersion> <IncludePythonExe Condition="$(IncludePythonExe) == ''">true</IncludePythonExe> - <IncludeDistutils Condition="$(IncludeDistutils) == ''">false</IncludeDistutils> <IncludeLib2To3 Condition="$(IncludeLib2To3) == ''">false</IncludeLib2To3> <IncludeVEnv Condition="$(IncludeVEnv) == ''">false</IncludeVEnv> @@ -68,7 +67,6 @@ PROPS_TEMPLATE = r"""<?xml version="1.0" encoding="utf-8"?> <Link>DLLs\%(Filename)%(Extension)</Link> </_PythonRuntimeDlls> <_PythonRuntimeLib Include="$(PythonHome)\Lib\**\*" Exclude="$(PythonHome)\Lib\**\*.pyc;$(PythonHome)\Lib\site-packages\**\*" /> - <_PythonRuntimeLib Remove="$(PythonHome)\Lib\distutils\**\*" Condition="$(IncludeDistutils) != 'true'" /> <_PythonRuntimeLib Remove="$(PythonHome)\Lib\lib2to3\**\*" Condition="$(IncludeLib2To3) != 'true'" /> <_PythonRuntimeLib Remove="$(PythonHome)\Lib\ensurepip\**\*" Condition="$(IncludeVEnv) != 'true'" /> <_PythonRuntimeLib Remove="$(PythonHome)\Lib\venv\**\*" Condition="$(IncludeVEnv) != 'true'" /> diff --git a/PC/layout/support/python.props b/PC/layout/support/python.props index b5ef67b2..e46891aa 100644 --- a/PC/layout/support/python.props +++ b/PC/layout/support/python.props @@ -1,56 +1,54 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <PropertyGroup Condition="$(Platform) == '$$PYTHON_PLATFORM$$'"> - <PythonHome>$(MSBuildThisFileDirectory)\..\..\tools</PythonHome> - <PythonInclude>$(PythonHome)\include</PythonInclude> - <PythonLibs>$(PythonHome)\libs</PythonLibs> - <PythonTag>$$PYTHON_TAG$$</PythonTag> - <PythonVersion>$$PYTHON_VERSION$$</PythonVersion> - - <IncludePythonExe Condition="$(IncludePythonExe) == ''">true</IncludePythonExe> - <IncludeDistutils Condition="$(IncludeDistutils) == ''">false</IncludeDistutils> - <IncludeLib2To3 Condition="$(IncludeLib2To3) == ''">false</IncludeLib2To3> - <IncludeVEnv Condition="$(IncludeVEnv) == ''">false</IncludeVEnv> - - <GetPythonRuntimeFilesDependsOn>$$PYTHON_TARGET$$;$(GetPythonRuntimeFilesDependsOn)</GetPythonRuntimeFilesDependsOn> - </PropertyGroup> - - <ItemDefinitionGroup Condition="$(Platform) == '$$PYTHON_PLATFORM$$'"> - <ClCompile> - <AdditionalIncludeDirectories>$(PythonInclude);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> - </ClCompile> - <Link> - <AdditionalLibraryDirectories>$(PythonLibs);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> - </Link> - </ItemDefinitionGroup> - - <Target Name="GetPythonRuntimeFiles" Returns="@(PythonRuntime)" DependsOnTargets="$(GetPythonRuntimeFilesDependsOn)" /> - - <Target Name="$$PYTHON_TARGET$$" Returns="@(PythonRuntime)"> - <ItemGroup> - <_PythonRuntimeExe Include="$(PythonHome)\python*.dll" /> - <_PythonRuntimeExe Include="$(PythonHome)\vcruntime140.dll" /> - <_PythonRuntimeExe Include="$(PythonHome)\python*.exe" Condition="$(IncludePythonExe) == 'true'" /> - <_PythonRuntimeExe> - <Link>%(Filename)%(Extension)</Link> - </_PythonRuntimeExe> - <_PythonRuntimeDlls Include="$(PythonHome)\DLLs\*.pyd" /> - <_PythonRuntimeDlls Include="$(PythonHome)\DLLs\*.dll" /> - <_PythonRuntimeDlls> - <Link>DLLs\%(Filename)%(Extension)</Link> - </_PythonRuntimeDlls> - <_PythonRuntimeLib Include="$(PythonHome)\Lib\**\*" Exclude="$(PythonHome)\Lib\**\*.pyc;$(PythonHome)\Lib\site-packages\**\*" /> - <_PythonRuntimeLib Remove="$(PythonHome)\Lib\distutils\**\*" Condition="$(IncludeDistutils) != 'true'" /> - <_PythonRuntimeLib Remove="$(PythonHome)\Lib\lib2to3\**\*" Condition="$(IncludeLib2To3) != 'true'" /> - <_PythonRuntimeLib Remove="$(PythonHome)\Lib\ensurepip\**\*" Condition="$(IncludeVEnv) != 'true'" /> - <_PythonRuntimeLib Remove="$(PythonHome)\Lib\venv\**\*" Condition="$(IncludeVEnv) != 'true'" /> - <_PythonRuntimeLib> - <Link>Lib\%(RecursiveDir)%(Filename)%(Extension)</Link> - </_PythonRuntimeLib> - <PythonRuntime Include="@(_PythonRuntimeExe);@(_PythonRuntimeDlls);@(_PythonRuntimeLib)" /> - </ItemGroup> - - <Message Importance="low" Text="Collected Python runtime from $(PythonHome):%0D%0A@(PythonRuntime->' %(Link)','%0D%0A')" /> - </Target> -</Project> +<?xml version="1.0" encoding="utf-8"?> +<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup Condition="$(Platform) == '$$PYTHON_PLATFORM$$'"> + <PythonHome>$(MSBuildThisFileDirectory)\..\..\tools</PythonHome> + <PythonInclude>$(PythonHome)\include</PythonInclude> + <PythonLibs>$(PythonHome)\libs</PythonLibs> + <PythonTag>$$PYTHON_TAG$$</PythonTag> + <PythonVersion>$$PYTHON_VERSION$$</PythonVersion> + + <IncludePythonExe Condition="$(IncludePythonExe) == ''">true</IncludePythonExe> + <IncludeLib2To3 Condition="$(IncludeLib2To3) == ''">false</IncludeLib2To3> + <IncludeVEnv Condition="$(IncludeVEnv) == ''">false</IncludeVEnv> + + <GetPythonRuntimeFilesDependsOn>$$PYTHON_TARGET$$;$(GetPythonRuntimeFilesDependsOn)</GetPythonRuntimeFilesDependsOn> + </PropertyGroup> + + <ItemDefinitionGroup Condition="$(Platform) == '$$PYTHON_PLATFORM$$'"> + <ClCompile> + <AdditionalIncludeDirectories>$(PythonInclude);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + </ClCompile> + <Link> + <AdditionalLibraryDirectories>$(PythonLibs);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + </Link> + </ItemDefinitionGroup> + + <Target Name="GetPythonRuntimeFiles" Returns="@(PythonRuntime)" DependsOnTargets="$(GetPythonRuntimeFilesDependsOn)" /> + + <Target Name="$$PYTHON_TARGET$$" Returns="@(PythonRuntime)"> + <ItemGroup> + <_PythonRuntimeExe Include="$(PythonHome)\python*.dll" /> + <_PythonRuntimeExe Include="$(PythonHome)\vcruntime140.dll" /> + <_PythonRuntimeExe Include="$(PythonHome)\python*.exe" Condition="$(IncludePythonExe) == 'true'" /> + <_PythonRuntimeExe> + <Link>%(Filename)%(Extension)</Link> + </_PythonRuntimeExe> + <_PythonRuntimeDlls Include="$(PythonHome)\DLLs\*.pyd" /> + <_PythonRuntimeDlls Include="$(PythonHome)\DLLs\*.dll" /> + <_PythonRuntimeDlls> + <Link>DLLs\%(Filename)%(Extension)</Link> + </_PythonRuntimeDlls> + <_PythonRuntimeLib Include="$(PythonHome)\Lib\**\*" Exclude="$(PythonHome)\Lib\**\*.pyc;$(PythonHome)\Lib\site-packages\**\*" /> + <_PythonRuntimeLib Remove="$(PythonHome)\Lib\lib2to3\**\*" Condition="$(IncludeLib2To3) != 'true'" /> + <_PythonRuntimeLib Remove="$(PythonHome)\Lib\ensurepip\**\*" Condition="$(IncludeVEnv) != 'true'" /> + <_PythonRuntimeLib Remove="$(PythonHome)\Lib\venv\**\*" Condition="$(IncludeVEnv) != 'true'" /> + <_PythonRuntimeLib> + <Link>Lib\%(RecursiveDir)%(Filename)%(Extension)</Link> + </_PythonRuntimeLib> + <PythonRuntime Include="@(_PythonRuntimeExe);@(_PythonRuntimeDlls);@(_PythonRuntimeLib)" /> + </ItemGroup> + + <Message Importance="low" Text="Collected Python runtime from $(PythonHome):%0D%0A@(PythonRuntime->' %(Link)','%0D%0A')" /> + </Target> +</Project> diff --git a/PC/msvcrtmodule.c b/PC/msvcrtmodule.c index 1f78d99c..53ef26b7 100644 --- a/PC/msvcrtmodule.c +++ b/PC/msvcrtmodule.c @@ -38,6 +38,14 @@ class HANDLE_converter(CConverter): type = 'void *' format_unit = '"_Py_PARSE_UINTPTR"' + def parse_arg(self, argname, displayname): + return """ + {paramname} = PyLong_AsVoidPtr({argname}); + if (!{paramname} && PyErr_Occurred()) {{{{ + goto exit; + }}}} + """.format(argname=argname, paramname=self.parser_name) + class HANDLE_return_converter(CReturnConverter): type = 'void *' @@ -66,7 +74,7 @@ class wchar_t_return_converter(CReturnConverter): data.return_conversion.append( 'return_value = PyUnicode_FromOrdinal(_return_value);\n') [python start generated code]*/ -/*[python end generated code: output=da39a3ee5e6b4b0d input=d102511df3cda2eb]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=1e8e9fa3538ec08f]*/ /*[clinic input] module msvcrt @@ -245,6 +253,8 @@ msvcrt_getch_impl(PyObject *module) return ch; } +#ifdef MS_WINDOWS_DESKTOP + /*[clinic input] msvcrt.getwch -> wchar_t @@ -263,6 +273,8 @@ msvcrt_getwch_impl(PyObject *module) return ch; } +#endif /* MS_WINDOWS_DESKTOP */ + /*[clinic input] msvcrt.getche -> byte_char @@ -281,6 +293,8 @@ msvcrt_getche_impl(PyObject *module) return ch; } +#ifdef MS_WINDOWS_DESKTOP + /*[clinic input] msvcrt.getwche -> wchar_t @@ -299,6 +313,8 @@ msvcrt_getwche_impl(PyObject *module) return ch; } +#endif /* MS_WINDOWS_DESKTOP */ + /*[clinic input] msvcrt.putch @@ -318,6 +334,8 @@ msvcrt_putch_impl(PyObject *module, char char_value) Py_RETURN_NONE; } +#ifdef MS_WINDOWS_DESKTOP + /*[clinic input] msvcrt.putwch @@ -338,6 +356,8 @@ msvcrt_putwch_impl(PyObject *module, int unicode_char) } +#endif /* MS_WINDOWS_DESKTOP */ + /*[clinic input] msvcrt.ungetch @@ -366,6 +386,8 @@ msvcrt_ungetch_impl(PyObject *module, char char_value) Py_RETURN_NONE; } +#ifdef MS_WINDOWS_DESKTOP + /*[clinic input] msvcrt.ungetwch @@ -390,6 +412,8 @@ msvcrt_ungetwch_impl(PyObject *module, int unicode_char) Py_RETURN_NONE; } +#endif /* MS_WINDOWS_DESKTOP */ + #ifdef _DEBUG /*[clinic input] msvcrt.CrtSetReportFile -> HANDLE @@ -467,6 +491,8 @@ msvcrt_set_error_mode_impl(PyObject *module, int mode) } #endif /* _DEBUG */ +#if defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_APP) || defined(MS_WINDOWS_SYSTEM) + /*[clinic input] msvcrt.GetErrorMode @@ -486,6 +512,8 @@ msvcrt_GetErrorMode_impl(PyObject *module) return PyLong_FromUnsignedLong(res); } +#endif /* MS_WINDOWS_APP || MS_WINDOWS_SYSTEM */ + /*[clinic input] msvcrt.SetErrorMode @@ -536,108 +564,116 @@ static struct PyMethodDef msvcrt_functions[] = { {NULL, NULL} }; - -static struct PyModuleDef msvcrtmodule = { - PyModuleDef_HEAD_INIT, - "msvcrt", - NULL, - -1, - msvcrt_functions, - NULL, - NULL, - NULL, - NULL -}; - -static void -insertint(PyObject *d, char *name, int value) -{ - PyObject *v = PyLong_FromLong((long) value); - if (v == NULL) { - /* Don't bother reporting this error */ - PyErr_Clear(); - } - else { - PyDict_SetItemString(d, name, v); - Py_DECREF(v); - } -} - -static void -insertptr(PyObject *d, char *name, void *value) +static int +insertptr(PyObject *mod, char *name, void *value) { PyObject *v = PyLong_FromVoidPtr(value); if (v == NULL) { - /* Don't bother reporting this error */ - PyErr_Clear(); - } - else { - PyDict_SetItemString(d, name, v); - Py_DECREF(v); + return -1; } + int rc = PyModule_AddObjectRef(mod, name, v); + Py_DECREF(v); + return rc; } -PyMODINIT_FUNC -PyInit_msvcrt(void) -{ - int st; - PyObject *d, *version; - PyObject *m = PyModule_Create(&msvcrtmodule); - if (m == NULL) - return NULL; - d = PyModule_GetDict(m); +#define INSERTINT(MOD, NAME, VAL) do { \ + if (PyModule_AddIntConstant(MOD, NAME, VAL) < 0) { \ + return -1; \ + } \ +} while (0) +#define INSERTPTR(MOD, NAME, PTR) do { \ + if (insertptr(MOD, NAME, PTR) < 0) { \ + return -1; \ + } \ +} while (0) + +#define INSERTSTR(MOD, NAME, CONST) do { \ + if (PyModule_AddStringConstant(MOD, NAME, CONST) < 0) { \ + return -1; \ + } \ +} while (0) + +static int +exec_module(PyObject* m) +{ /* constants for the locking() function's mode argument */ - insertint(d, "LK_LOCK", _LK_LOCK); - insertint(d, "LK_NBLCK", _LK_NBLCK); - insertint(d, "LK_NBRLCK", _LK_NBRLCK); - insertint(d, "LK_RLCK", _LK_RLCK); - insertint(d, "LK_UNLCK", _LK_UNLCK); - insertint(d, "SEM_FAILCRITICALERRORS", SEM_FAILCRITICALERRORS); - insertint(d, "SEM_NOALIGNMENTFAULTEXCEPT", SEM_NOALIGNMENTFAULTEXCEPT); - insertint(d, "SEM_NOGPFAULTERRORBOX", SEM_NOGPFAULTERRORBOX); - insertint(d, "SEM_NOOPENFILEERRORBOX", SEM_NOOPENFILEERRORBOX); + INSERTINT(m, "LK_LOCK", _LK_LOCK); + INSERTINT(m, "LK_NBLCK", _LK_NBLCK); + INSERTINT(m, "LK_NBRLCK", _LK_NBRLCK); + INSERTINT(m, "LK_RLCK", _LK_RLCK); + INSERTINT(m, "LK_UNLCK", _LK_UNLCK); +#ifdef MS_WINDOWS_DESKTOP + INSERTINT(m, "SEM_FAILCRITICALERRORS", SEM_FAILCRITICALERRORS); + INSERTINT(m, "SEM_NOALIGNMENTFAULTEXCEPT", SEM_NOALIGNMENTFAULTEXCEPT); + INSERTINT(m, "SEM_NOGPFAULTERRORBOX", SEM_NOGPFAULTERRORBOX); + INSERTINT(m, "SEM_NOOPENFILEERRORBOX", SEM_NOOPENFILEERRORBOX); +#endif #ifdef _DEBUG - insertint(d, "CRT_WARN", _CRT_WARN); - insertint(d, "CRT_ERROR", _CRT_ERROR); - insertint(d, "CRT_ASSERT", _CRT_ASSERT); - insertint(d, "CRTDBG_MODE_DEBUG", _CRTDBG_MODE_DEBUG); - insertint(d, "CRTDBG_MODE_FILE", _CRTDBG_MODE_FILE); - insertint(d, "CRTDBG_MODE_WNDW", _CRTDBG_MODE_WNDW); - insertint(d, "CRTDBG_REPORT_MODE", _CRTDBG_REPORT_MODE); - insertptr(d, "CRTDBG_FILE_STDERR", _CRTDBG_FILE_STDERR); - insertptr(d, "CRTDBG_FILE_STDOUT", _CRTDBG_FILE_STDOUT); - insertptr(d, "CRTDBG_REPORT_FILE", _CRTDBG_REPORT_FILE); + INSERTINT(m, "CRT_WARN", _CRT_WARN); + INSERTINT(m, "CRT_ERROR", _CRT_ERROR); + INSERTINT(m, "CRT_ASSERT", _CRT_ASSERT); + INSERTINT(m, "CRTDBG_MODE_DEBUG", _CRTDBG_MODE_DEBUG); + INSERTINT(m, "CRTDBG_MODE_FILE", _CRTDBG_MODE_FILE); + INSERTINT(m, "CRTDBG_MODE_WNDW", _CRTDBG_MODE_WNDW); + INSERTINT(m, "CRTDBG_REPORT_MODE", _CRTDBG_REPORT_MODE); + INSERTPTR(m, "CRTDBG_FILE_STDERR", _CRTDBG_FILE_STDERR); + INSERTPTR(m, "CRTDBG_FILE_STDOUT", _CRTDBG_FILE_STDOUT); + INSERTPTR(m, "CRTDBG_REPORT_FILE", _CRTDBG_REPORT_FILE); #endif +#undef INSERTINT +#undef INSERTPTR + /* constants for the crt versions */ #ifdef _VC_ASSEMBLY_PUBLICKEYTOKEN - st = PyModule_AddStringConstant(m, "VC_ASSEMBLY_PUBLICKEYTOKEN", - _VC_ASSEMBLY_PUBLICKEYTOKEN); - if (st < 0) return NULL; + INSERTSTR(m, "VC_ASSEMBLY_PUBLICKEYTOKEN", _VC_ASSEMBLY_PUBLICKEYTOKEN); #endif #ifdef _CRT_ASSEMBLY_VERSION - st = PyModule_AddStringConstant(m, "CRT_ASSEMBLY_VERSION", - _CRT_ASSEMBLY_VERSION); - if (st < 0) return NULL; + INSERTSTR(m, "CRT_ASSEMBLY_VERSION", _CRT_ASSEMBLY_VERSION); #endif #ifdef __LIBRARIES_ASSEMBLY_NAME_PREFIX - st = PyModule_AddStringConstant(m, "LIBRARIES_ASSEMBLY_NAME_PREFIX", - __LIBRARIES_ASSEMBLY_NAME_PREFIX); - if (st < 0) return NULL; + INSERTSTR(m, "LIBRARIES_ASSEMBLY_NAME_PREFIX", + __LIBRARIES_ASSEMBLY_NAME_PREFIX); #endif +#undef INSERTSTR + /* constants for the 2010 crt versions */ #if defined(_VC_CRT_MAJOR_VERSION) && defined (_VC_CRT_MINOR_VERSION) && defined(_VC_CRT_BUILD_VERSION) && defined(_VC_CRT_RBUILD_VERSION) - version = PyUnicode_FromFormat("%d.%d.%d.%d", _VC_CRT_MAJOR_VERSION, - _VC_CRT_MINOR_VERSION, - _VC_CRT_BUILD_VERSION, - _VC_CRT_RBUILD_VERSION); - st = PyModule_AddObject(m, "CRT_ASSEMBLY_VERSION", version); - if (st < 0) return NULL; + PyObject *version = PyUnicode_FromFormat("%d.%d.%d.%d", + _VC_CRT_MAJOR_VERSION, + _VC_CRT_MINOR_VERSION, + _VC_CRT_BUILD_VERSION, + _VC_CRT_RBUILD_VERSION); + if (version == NULL) { + return -1; + } + int st = PyModule_AddObjectRef(m, "CRT_ASSEMBLY_VERSION", version); + Py_DECREF(version); + if (st < 0) { + return -1; + } #endif - /* make compiler warning quiet if st is unused */ - (void)st; - return m; + return 0; +} + +static PyModuleDef_Slot msvcrt_slots[] = { + {Py_mod_exec, exec_module}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, + {0, NULL} +}; + +static struct PyModuleDef msvcrtmodule = { + .m_base = PyModuleDef_HEAD_INIT, + .m_name = "msvcrt", + .m_methods = msvcrt_functions, + .m_slots = msvcrt_slots, +}; + +PyMODINIT_FUNC +PyInit_msvcrt(void) +{ + return PyModuleDef_Init(&msvcrtmodule); } diff --git a/PC/pyconfig.h b/PC/pyconfig.h index 959b851d..3415efe2 100644 --- a/PC/pyconfig.h +++ b/PC/pyconfig.h @@ -72,34 +72,51 @@ WIN32 is still required for the locale module. #define USE_SOCKET #endif +#if defined(Py_BUILD_CORE) || defined(Py_BUILD_CORE_BUILTIN) || defined(Py_BUILD_CORE_MODULE) +#include <winapifamily.h> + +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) +#define MS_WINDOWS_DESKTOP +#endif +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) +#define MS_WINDOWS_APP +#endif +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_SYSTEM) +#define MS_WINDOWS_SYSTEM +#endif +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_GAMES) +#define MS_WINDOWS_GAMES +#endif + +/* Define to 1 if you support windows console io */ +#if defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_APP) || defined(MS_WINDOWS_SYSTEM) +#define HAVE_WINDOWS_CONSOLE_IO 1 +#endif +#endif /* Py_BUILD_CORE || Py_BUILD_CORE_BUILTIN || Py_BUILD_CORE_MODULE */ /* Compiler specific defines */ /* ------------------------------------------------------------------------*/ -/* Microsoft C defines _MSC_VER */ +/* Microsoft C defines _MSC_VER, as does clang-cl.exe */ #ifdef _MSC_VER /* We want COMPILER to expand to a string containing _MSC_VER's *value*. * This is horridly tricky, because the stringization operator only works * on macro arguments, and doesn't evaluate macros passed *as* arguments. - * Attempts simpler than the following appear doomed to produce "_MSC_VER" - * literally in the string. */ #define _Py_PASTE_VERSION(SUFFIX) \ ("[MSC v." _Py_STRINGIZE(_MSC_VER) " " SUFFIX "]") /* e.g., this produces, after compile-time string catenation, - * ("[MSC v.1200 32 bit (Intel)]") + * ("[MSC v.1900 64 bit (Intel)]") * * _Py_STRINGIZE(_MSC_VER) expands to - * _Py_STRINGIZE1((_MSC_VER)) expands to - * _Py_STRINGIZE2(_MSC_VER) but as this call is the result of token-pasting - * it's scanned again for macros and so further expands to (under MSVC 6) - * _Py_STRINGIZE2(1200) which then expands to - * "1200" + * _Py_STRINGIZE1(_MSC_VER) and this second macro call is scanned + * again for macros and so further expands to + * _Py_STRINGIZE1(1900) which then expands to + * "1900" */ -#define _Py_STRINGIZE(X) _Py_STRINGIZE1((X)) -#define _Py_STRINGIZE1(X) _Py_STRINGIZE2 ## X -#define _Py_STRINGIZE2(X) #X +#define _Py_STRINGIZE(X) _Py_STRINGIZE1(X) +#define _Py_STRINGIZE1(X) #X /* MSVC defines _WINxx to differentiate the windows platform types @@ -122,13 +139,16 @@ WIN32 is still required for the locale module. */ #ifdef MS_WIN64 #if defined(_M_X64) || defined(_M_AMD64) -#if defined(__INTEL_COMPILER) +#if defined(__clang__) +#define COMPILER ("[Clang " __clang_version__ "] 64 bit (AMD64) with MSC v." _Py_STRINGIZE(_MSC_VER) " CRT]") +#define PY_SUPPORT_TIER 0 +#elif defined(__INTEL_COMPILER) #define COMPILER ("[ICC v." _Py_STRINGIZE(__INTEL_COMPILER) " 64 bit (amd64) with MSC v." _Py_STRINGIZE(_MSC_VER) " CRT]") #define PY_SUPPORT_TIER 0 #else #define COMPILER _Py_PASTE_VERSION("64 bit (AMD64)") #define PY_SUPPORT_TIER 1 -#endif /* __INTEL_COMPILER */ +#endif /* __clang__ */ #define PYD_PLATFORM_TAG "win_amd64" #elif defined(_M_ARM64) #define COMPILER _Py_PASTE_VERSION("64 bit (ARM64)") @@ -181,13 +201,16 @@ typedef _W64 int Py_ssize_t; #if defined(MS_WIN32) && !defined(MS_WIN64) #if defined(_M_IX86) -#if defined(__INTEL_COMPILER) +#if defined(__clang__) +#define COMPILER ("[Clang " __clang_version__ "] 32 bit (Intel) with MSC v." _Py_STRINGIZE(_MSC_VER) " CRT]") +#define PY_SUPPORT_TIER 0 +#elif defined(__INTEL_COMPILER) #define COMPILER ("[ICC v." _Py_STRINGIZE(__INTEL_COMPILER) " 32 bit (Intel) with MSC v." _Py_STRINGIZE(_MSC_VER) " CRT]") #define PY_SUPPORT_TIER 0 #else #define COMPILER _Py_PASTE_VERSION("32 bit (Intel)") #define PY_SUPPORT_TIER 1 -#endif /* __INTEL_COMPILER */ +#endif /* __clang__ */ #define PYD_PLATFORM_TAG "win32" #elif defined(_M_ARM) #define COMPILER _Py_PASTE_VERSION("32 bit (ARM)") @@ -209,6 +232,16 @@ typedef int pid_t; #endif /* _MSC_VER */ +/* ------------------------------------------------------------------------*/ +/* mingw and mingw-w64 define __MINGW32__ */ +#ifdef __MINGW32__ + +#ifdef _WIN64 +#define MS_WIN64 +#endif + +#endif /* __MINGW32__*/ + /* ------------------------------------------------------------------------*/ /* egcs/gnu-win32 defines __GNUC__ and _WIN32 */ #if defined(__GNUC__) && defined(_WIN32) @@ -275,17 +308,17 @@ Py_NO_ENABLE_SHARED to find out. Also support MS_NO_COREDLL for b/w compat */ file in their Makefile (other compilers are generally taken care of by distutils.) */ # if defined(_DEBUG) -# pragma comment(lib,"python311_d.lib") +# pragma comment(lib,"python312_d.lib") # elif defined(Py_LIMITED_API) # pragma comment(lib,"python3.lib") # else -# pragma comment(lib,"python311.lib") +# pragma comment(lib,"python312.lib") # endif /* _DEBUG */ # endif /* _MSC_VER */ # endif /* Py_BUILD_CORE */ #endif /* MS_COREDLL */ -#if defined(MS_WIN64) +#ifdef MS_WIN64 /* maintain "win32" sys.platform for backward compatibility of Python code, the Win64 API should be close enough to the Win32 API to make this preferable */ @@ -297,6 +330,7 @@ Py_NO_ENABLE_SHARED to find out. Also support MS_NO_COREDLL for b/w compat */ # define SIZEOF_HKEY 8 # define SIZEOF_SIZE_T 8 # define ALIGNOF_SIZE_T 8 +# define ALIGNOF_MAX_ALIGN_T 8 /* configure.ac defines HAVE_LARGEFILE_SUPPORT iff sizeof(off_t) > sizeof(long), and sizeof(long long) >= sizeof(off_t). On Win64 the second condition is not true, but if fpos_t replaces off_t @@ -318,6 +352,7 @@ Py_NO_ENABLE_SHARED to find out. Also support MS_NO_COREDLL for b/w compat */ # else # define SIZEOF_TIME_T 4 # endif +# define ALIGNOF_MAX_ALIGN_T 8 #endif #ifdef _DEBUG @@ -583,9 +618,6 @@ Py_NO_ENABLE_SHARED to find out. Also support MS_NO_COREDLL for b/w compat */ /* Define to 1 if you have the <signal.h> header file. */ #define HAVE_SIGNAL_H 1 -/* Define if you have the <stdarg.h> prototypes. */ -#define HAVE_STDARG_PROTOTYPES - /* Define if you have the <stddef.h> header file. */ #define HAVE_STDDEF_H 1 diff --git a/PC/python3dll.c b/PC/python3dll.c index 50e7a960..505feef4 100755 --- a/PC/python3dll.c +++ b/PC/python3dll.c @@ -1,7 +1,6 @@ - /* Re-export stable Python ABI */ -/* Generated by Tools/scripts/stable_abi.py */ +/* Generated by Tools/build/stable_abi.py */ #ifdef _M_IX86 #define DECORATE "_" @@ -192,12 +191,14 @@ EXPORT_FUNC(PyErr_BadInternalCall) EXPORT_FUNC(PyErr_CheckSignals) EXPORT_FUNC(PyErr_Clear) EXPORT_FUNC(PyErr_Display) +EXPORT_FUNC(PyErr_DisplayException) EXPORT_FUNC(PyErr_ExceptionMatches) EXPORT_FUNC(PyErr_Fetch) EXPORT_FUNC(PyErr_Format) EXPORT_FUNC(PyErr_FormatV) EXPORT_FUNC(PyErr_GetExcInfo) EXPORT_FUNC(PyErr_GetHandledException) +EXPORT_FUNC(PyErr_GetRaisedException) EXPORT_FUNC(PyErr_GivenExceptionMatches) EXPORT_FUNC(PyErr_NewException) EXPORT_FUNC(PyErr_NewExceptionWithDoc) @@ -227,6 +228,7 @@ EXPORT_FUNC(PyErr_SetInterrupt) EXPORT_FUNC(PyErr_SetInterruptEx) EXPORT_FUNC(PyErr_SetNone) EXPORT_FUNC(PyErr_SetObject) +EXPORT_FUNC(PyErr_SetRaisedException) EXPORT_FUNC(PyErr_SetString) EXPORT_FUNC(PyErr_SyntaxLocation) EXPORT_FUNC(PyErr_SyntaxLocationEx) @@ -255,9 +257,11 @@ EXPORT_FUNC(PyEval_ReleaseThread) EXPORT_FUNC(PyEval_RestoreThread) EXPORT_FUNC(PyEval_SaveThread) EXPORT_FUNC(PyEval_ThreadsInitialized) +EXPORT_FUNC(PyException_GetArgs) EXPORT_FUNC(PyException_GetCause) EXPORT_FUNC(PyException_GetContext) EXPORT_FUNC(PyException_GetTraceback) +EXPORT_FUNC(PyException_SetArgs) EXPORT_FUNC(PyException_SetCause) EXPORT_FUNC(PyException_SetContext) EXPORT_FUNC(PyException_SetTraceback) @@ -462,6 +466,7 @@ EXPORT_FUNC(PyObject_GetAttrString) EXPORT_FUNC(PyObject_GetBuffer) EXPORT_FUNC(PyObject_GetItem) EXPORT_FUNC(PyObject_GetIter) +EXPORT_FUNC(PyObject_GetTypeData) EXPORT_FUNC(PyObject_HasAttr) EXPORT_FUNC(PyObject_HasAttrString) EXPORT_FUNC(PyObject_Hash) @@ -485,6 +490,8 @@ EXPORT_FUNC(PyObject_SetItem) EXPORT_FUNC(PyObject_Size) EXPORT_FUNC(PyObject_Str) EXPORT_FUNC(PyObject_Type) +EXPORT_FUNC(PyObject_Vectorcall) +EXPORT_FUNC(PyObject_VectorcallMethod) EXPORT_FUNC(PyOS_CheckStack) EXPORT_FUNC(PyOS_double_to_string) EXPORT_FUNC(PyOS_FSPath) @@ -599,6 +606,7 @@ EXPORT_FUNC(PyTuple_Pack) EXPORT_FUNC(PyTuple_SetItem) EXPORT_FUNC(PyTuple_Size) EXPORT_FUNC(PyType_ClearCache) +EXPORT_FUNC(PyType_FromMetaclass) EXPORT_FUNC(PyType_FromModuleAndSpec) EXPORT_FUNC(PyType_FromSpec) EXPORT_FUNC(PyType_FromSpecWithBases) @@ -610,6 +618,7 @@ EXPORT_FUNC(PyType_GetModuleState) EXPORT_FUNC(PyType_GetName) EXPORT_FUNC(PyType_GetQualName) EXPORT_FUNC(PyType_GetSlot) +EXPORT_FUNC(PyType_GetTypeDataSize) EXPORT_FUNC(PyType_IsSubtype) EXPORT_FUNC(PyType_Modified) EXPORT_FUNC(PyType_Ready) @@ -722,6 +731,8 @@ EXPORT_FUNC(PyUnicodeTranslateError_GetStart) EXPORT_FUNC(PyUnicodeTranslateError_SetEnd) EXPORT_FUNC(PyUnicodeTranslateError_SetReason) EXPORT_FUNC(PyUnicodeTranslateError_SetStart) +EXPORT_FUNC(PyVectorcall_Call) +EXPORT_FUNC(PyVectorcall_NARGS) EXPORT_FUNC(PyWeakref_GetObject) EXPORT_FUNC(PyWeakref_NewProxy) EXPORT_FUNC(PyWeakref_NewRef) diff --git a/PC/readme.txt b/PC/readme.txt index e1af101f..a917a72c 100644 --- a/PC/readme.txt +++ b/PC/readme.txt @@ -1,81 +1,70 @@ -Welcome to the "PC" subdirectory of the Python distribution -*********************************************************** - -This "PC" subdirectory contains complete project files to make -several older PC ports of Python, as well as all the PC-specific -Python source files. It should be located in the root of the -Python distribution, and there should be directories "Modules", -"Objects", "Python", etc. in the parent directory of this "PC" -subdirectory. Be sure to read the documentation in the Python -distribution. - -Python requires library files such as string.py to be available in -one or more library directories. The search path of libraries is -set up when Python starts. To see the current Python library search -path, start Python and enter "import sys" and "print sys.path". - -All PC ports use this scheme to try to set up a module search path: - - 1) The script location; the current directory without script. - 2) The PYTHONPATH variable, if set. - 3) Paths specified in the Registry. - 4) Default directories lib, lib/win, lib/test, lib/tkinter; - these are searched relative to the environment variable - PYTHONHOME, if set, or relative to the executable and its - ancestors, if a landmark file (Lib/string.py) is found , - or the current directory (not useful). - 5) The directory containing the executable. - -The best installation strategy is to put the Python executable and -DLL in some convenient directory such as -C:/python, and copy all library files and subdirectories (using XCOPY) -to C:/python/lib. Then you don't need to set PYTHONPATH. Otherwise, -set the environment variable PYTHONPATH to your Python search path. -For example, - set PYTHONPATH=.;d:\python\lib;d:\python\lib\win;d:\python\lib\dos-8x3 - -There are several add-in modules to build Python programs which use -the native Windows operating environment. The ports here just make -"QuickWin" and DOS Python versions which support a character-mode -(console) environment. Look in www.python.org for Tkinter, PythonWin, -WPY and wxPython. - -To make a Python port, start the Integrated Development Environment -(IDE) of your compiler, and read in the native "project file" -(or makefile) provided. This will enable you to change any source -files or build settings so you can make custom builds. - -pyconfig.h An important configuration file specific to PC's. - -config.c The list of C modules to include in the Python PC - version. Manually edit this file to add or - remove Python modules. - -testpy.py A Python test program. Run this to test your - Python port. It should produce copious output, - ending in a report on how many tests were OK, how many - failed, and how many were skipped. Don't worry about - skipped tests (these test unavailable optional features). - - -Additional files and subdirectories for 32-bit Windows -====================================================== - -python_nt.rc Resource compiler input for python15.dll. - -dl_nt.c - Additional sources used for 32-bit Windows features. - -getpathp.c Default sys.path calculations (for all PC platforms). - -dllbase_nt.txt A (manually maintained) list of base addresses for - various DLLs, to avoid run-time relocation. - - -Note for Windows 3.x and DOS users -================================== - -Neither Windows 3.x nor DOS is supported any more. The last Python -version that supported these was Python 1.5.2; the support files were -present in Python 2.0 but weren't updated, and it is not our intention -to support these platforms for Python 2.x. +Welcome to the "PC" subdirectory of the Python distribution +*********************************************************** + +This "PC" subdirectory contains complete project files to make +several older PC ports of Python, as well as all the PC-specific +Python source files. It should be located in the root of the +Python distribution, and there should be directories "Modules", +"Objects", "Python", etc. in the parent directory of this "PC" +subdirectory. Be sure to read the documentation in the Python +distribution. + +Python requires library files such as string.py to be available in +one or more library directories. The search path of libraries is +set up when Python starts. To see the current Python library search +path, start Python and enter "import sys" and "print sys.path". + +All PC ports use this scheme to try to set up a module search path: + + 1) The script location; the current directory without script. + 2) The PYTHONPATH variable, if set. + 3) Paths specified in the Registry. + 4) Default directories lib, lib/win, lib/test, lib/tkinter; + these are searched relative to the environment variable + PYTHONHOME, if set, or relative to the executable and its + ancestors, if a landmark file (Lib/string.py) is found , + or the current directory (not useful). + 5) The directory containing the executable. + +The best installation strategy is to put the Python executable and +DLL in some convenient directory such as +C:/python, and copy all library files and subdirectories (using XCOPY) +to C:/python/lib. Then you don't need to set PYTHONPATH. Otherwise, +set the environment variable PYTHONPATH to your Python search path. +For example, + set PYTHONPATH=.;d:\python\lib;d:\python\lib\win;d:\python\lib\dos-8x3 + +There are several add-in modules to build Python programs which use +the native Windows operating environment. The ports here just make +"QuickWin" and DOS Python versions which support a character-mode +(console) environment. Look in www.python.org for Tkinter, PythonWin, +WPY and wxPython. + +To make a Python port, start the Integrated Development Environment +(IDE) of your compiler, and read in the native "project file" +(or makefile) provided. This will enable you to change any source +files or build settings so you can make custom builds. + +pyconfig.h An important configuration file specific to PC's. + +config.c The list of C modules to include in the Python PC + version. Manually edit this file to add or + remove Python modules. + + +Additional files and subdirectories for 32-bit Windows +====================================================== + +python_nt.rc Resource compiler input for python15.dll. + +dl_nt.c + Additional sources used for 32-bit Windows features. + + +Note for Windows 3.x and DOS users +================================== + +Neither Windows 3.x nor DOS is supported any more. The last Python +version that supported these was Python 1.5.2; the support files were +present in Python 2.0 but weren't updated, and it is not our intention +to support these platforms for Python 2.x. diff --git a/PC/testpy.py b/PC/testpy.py deleted file mode 100644 index 709f35c4..00000000 --- a/PC/testpy.py +++ /dev/null @@ -1,30 +0,0 @@ -import sys - -# This is a test module for Python. It looks in the standard -# places for various *.py files. If these are moved, you must -# change this module too. - -try: - import os -except: - print("""Could not import the standard "os" module. - Please check your PYTHONPATH environment variable.""") - sys.exit(1) - -try: - import symbol -except: - print("""Could not import the standard "symbol" module. If this is - a PC, you should add the dos_8x3 directory to your PYTHONPATH.""") - sys.exit(1) - -for dir in sys.path: - file = os.path.join(dir, "os.py") - if os.path.isfile(file): - test = os.path.join(dir, "test") - if os.path.isdir(test): - # Add the "test" directory to PYTHONPATH. - sys.path = sys.path + [test] - -import libregrtest # Standard Python tester. -libregrtest.main() diff --git a/PC/winreg.c b/PC/winreg.c index f668cf3c..e2d5322f 100644 --- a/PC/winreg.c +++ b/PC/winreg.c @@ -15,13 +15,22 @@ #define PY_SSIZE_T_CLEAN #include "Python.h" #include "pycore_object.h" // _PyObject_Init() +#include "pycore_moduleobject.h" #include "structmember.h" // PyMemberDef #include <windows.h> -static BOOL PyHKEY_AsHKEY(PyObject *ob, HKEY *pRes, BOOL bNoneOK); -static BOOL clinic_HKEY_converter(PyObject *ob, void *p); -static PyObject *PyHKEY_FromHKEY(HKEY h); -static BOOL PyHKEY_Close(PyObject *obHandle); +#if defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) || defined(MS_WINDOWS_GAMES) + +typedef struct { + PyTypeObject *PyHKEY_Type; +} winreg_state; + +/* Forward declares */ + +static BOOL PyHKEY_AsHKEY(winreg_state *st, PyObject *ob, HKEY *pRes, BOOL bNoneOK); +static BOOL clinic_HKEY_converter(winreg_state *st, PyObject *ob, void *p); +static PyObject *PyHKEY_FromHKEY(winreg_state *st, HKEY h); +static BOOL PyHKEY_Close(winreg_state *st, PyObject *obHandle); static char errNotAHandle[] = "Object is not a handle"; @@ -33,8 +42,6 @@ static char errNotAHandle[] = "Object is not a handle"; #define PyErr_SetFromWindowsErrWithFunction(rc, fnname) \ PyErr_SetFromWindowsErr(rc) -/* Forward declares */ - /* Doc strings */ PyDoc_STRVAR(module_doc, "This module provides access to the Windows registry API.\n" @@ -112,7 +119,7 @@ typedef struct { HKEY hkey; } PyHKEYObject; -#define PyHKEY_Check(op) Py_IS_TYPE(op, &PyHKEY_Type) +#define PyHKEY_Check(st, op) Py_IS_TYPE(op, st->PyHKEY_Type) static char *failMsg = "bad operand type"; @@ -145,7 +152,18 @@ PyHKEY_deallocFunc(PyObject *ob) PyHKEYObject *obkey = (PyHKEYObject *)ob; if (obkey->hkey) RegCloseKey((HKEY)obkey->hkey); - PyObject_Free(ob); + + PyTypeObject *tp = Py_TYPE(ob); + PyObject_GC_UnTrack(ob); + PyObject_GC_Del(ob); + Py_DECREF(tp); +} + +static int +PyHKEY_traverseFunc(PyHKEYObject *self, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(self)); + return 0; } static int @@ -187,29 +205,6 @@ PyHKEY_hashFunc(PyObject *ob) } -static PyNumberMethods PyHKEY_NumberMethods = -{ - PyHKEY_binaryFailureFunc, /* nb_add */ - PyHKEY_binaryFailureFunc, /* nb_subtract */ - PyHKEY_binaryFailureFunc, /* nb_multiply */ - PyHKEY_binaryFailureFunc, /* nb_remainder */ - PyHKEY_binaryFailureFunc, /* nb_divmod */ - PyHKEY_ternaryFailureFunc, /* nb_power */ - PyHKEY_unaryFailureFunc, /* nb_negative */ - PyHKEY_unaryFailureFunc, /* nb_positive */ - PyHKEY_unaryFailureFunc, /* nb_absolute */ - PyHKEY_boolFunc, /* nb_bool */ - PyHKEY_unaryFailureFunc, /* nb_invert */ - PyHKEY_binaryFailureFunc, /* nb_lshift */ - PyHKEY_binaryFailureFunc, /* nb_rshift */ - PyHKEY_binaryFailureFunc, /* nb_and */ - PyHKEY_binaryFailureFunc, /* nb_xor */ - PyHKEY_binaryFailureFunc, /* nb_or */ - PyHKEY_intFunc, /* nb_int */ - 0, /* nb_reserved */ - PyHKEY_unaryFailureFunc, /* nb_float */ -}; - /*[clinic input] module winreg class winreg.HKEYType "PyHKEYObject *" "&PyHKEY_Type" @@ -217,18 +212,24 @@ class winreg.HKEYType "PyHKEYObject *" "&PyHKEY_Type" /*[clinic end generated code: output=da39a3ee5e6b4b0d input=4c964eba3bf914d6]*/ /*[python input] -class REGSAM_converter(CConverter): +class REGSAM_converter(int_converter): type = 'REGSAM' - format_unit = 'i' -class DWORD_converter(CConverter): +class DWORD_converter(unsigned_long_converter): type = 'DWORD' - format_unit = 'k' class HKEY_converter(CConverter): type = 'HKEY' converter = 'clinic_HKEY_converter' + def parse_arg(self, argname, displayname): + return """ + if (!{converter}(_PyModule_GetState(module), {argname}, &{paramname})) {{{{ + goto exit; + }}}} + """.format(argname=argname, paramname=self.parser_name, + converter=self.converter) + class HKEY_return_converter(CReturnConverter): type = 'HKEY' @@ -236,7 +237,7 @@ class HKEY_return_converter(CReturnConverter): self.declare(data) self.err_occurred_if_null_pointer("_return_value", data) data.return_conversion.append( - 'return_value = PyHKEY_FromHKEY(_return_value);\n') + 'return_value = PyHKEY_FromHKEY(_PyModule_GetState(module), _return_value);\n') # HACK: this only works for PyHKEYObjects, nothing else. # Should this be generalized and enshrined in clinic.py, @@ -249,7 +250,7 @@ class self_return_converter(CReturnConverter): data.return_conversion.append( 'return_value = (PyObject *)_return_value;\n') [python start generated code]*/ -/*[python end generated code: output=da39a3ee5e6b4b0d input=22f7aedc6d68e80e]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=17e645060c7b8ae1]*/ #include "clinic/winreg.c.h" @@ -270,8 +271,11 @@ static PyObject * winreg_HKEYType_Close_impl(PyHKEYObject *self) /*[clinic end generated code: output=fced3a624fb0c344 input=6786ac75f6b89de6]*/ { - if (!PyHKEY_Close((PyObject *)self)) + winreg_state *st = _PyType_GetModuleState(Py_TYPE(self)); + assert(st != NULL); + if (!PyHKEY_Close(st, (PyObject *)self)) { return NULL; + } Py_RETURN_NONE; } @@ -310,8 +314,7 @@ static PyHKEYObject * winreg_HKEYType___enter___impl(PyHKEYObject *self) /*[clinic end generated code: output=52c34986dab28990 input=c40fab1f0690a8e2]*/ { - Py_XINCREF(self); - return self; + return (PyHKEYObject*)Py_XNewRef(self); } @@ -328,8 +331,11 @@ winreg_HKEYType___exit___impl(PyHKEYObject *self, PyObject *exc_type, PyObject *exc_value, PyObject *traceback) /*[clinic end generated code: output=923ebe7389e6a263 input=fb32489ee92403c7]*/ { - if (!PyHKEY_Close((PyObject *)self)) + winreg_state *st = _PyType_GetModuleState(Py_TYPE(self)); + assert(st != NULL); + if (!PyHKEY_Close(st, (PyObject *)self)) { return NULL; + } Py_RETURN_NONE; } @@ -351,62 +357,71 @@ static PyMemberDef PyHKEY_memberlist[] = { {NULL} /* Sentinel */ }; -/* The type itself */ -PyTypeObject PyHKEY_Type = -{ - PyVarObject_HEAD_INIT(0, 0) /* fill in type at module init */ - "PyHKEY", - sizeof(PyHKEYObject), - 0, - PyHKEY_deallocFunc, /* tp_dealloc */ - 0, /* tp_vectorcall_offset */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_as_async */ - 0, /* tp_repr */ - &PyHKEY_NumberMethods, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - PyHKEY_hashFunc, /* tp_hash */ - 0, /* tp_call */ - PyHKEY_strFunc, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - 0, /* tp_flags */ - PyHKEY_doc, /* tp_doc */ - 0, /*tp_traverse*/ - 0, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - PyHKEY_methods, /*tp_methods*/ - PyHKEY_memberlist, /*tp_members*/ +static PyType_Slot pyhkey_type_slots[] = { + {Py_tp_dealloc, PyHKEY_deallocFunc}, + {Py_tp_members, PyHKEY_memberlist}, + {Py_tp_methods, PyHKEY_methods}, + {Py_tp_doc, (char *)PyHKEY_doc}, + {Py_tp_traverse, PyHKEY_traverseFunc}, + {Py_tp_hash, PyHKEY_hashFunc}, + {Py_tp_str, PyHKEY_strFunc}, + + // Number protocol + {Py_nb_add, PyHKEY_binaryFailureFunc}, + {Py_nb_subtract, PyHKEY_binaryFailureFunc}, + {Py_nb_multiply, PyHKEY_binaryFailureFunc}, + {Py_nb_remainder, PyHKEY_binaryFailureFunc}, + {Py_nb_divmod, PyHKEY_binaryFailureFunc}, + {Py_nb_power, PyHKEY_ternaryFailureFunc}, + {Py_nb_negative, PyHKEY_unaryFailureFunc}, + {Py_nb_positive, PyHKEY_unaryFailureFunc}, + {Py_nb_absolute, PyHKEY_unaryFailureFunc}, + {Py_nb_bool, PyHKEY_boolFunc}, + {Py_nb_invert, PyHKEY_unaryFailureFunc}, + {Py_nb_lshift, PyHKEY_binaryFailureFunc}, + {Py_nb_rshift, PyHKEY_binaryFailureFunc}, + {Py_nb_and, PyHKEY_binaryFailureFunc}, + {Py_nb_xor, PyHKEY_binaryFailureFunc}, + {Py_nb_or, PyHKEY_binaryFailureFunc}, + {Py_nb_int, PyHKEY_intFunc}, + {Py_nb_float, PyHKEY_unaryFailureFunc}, + {0, NULL}, +}; + +static PyType_Spec pyhkey_type_spec = { + .name = "winreg.PyHKEY", + .basicsize = sizeof(PyHKEYObject), + .flags = (Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE | + Py_TPFLAGS_DISALLOW_INSTANTIATION), + .slots = pyhkey_type_slots, }; /************************************************************************ The public PyHKEY API (well, not public yet :-) ************************************************************************/ PyObject * -PyHKEY_New(HKEY hInit) +PyHKEY_New(PyObject *m, HKEY hInit) { - PyHKEYObject *key = PyObject_New(PyHKEYObject, &PyHKEY_Type); - if (key) - key->hkey = hInit; + winreg_state *st = _PyModule_GetState(m); + PyHKEYObject *key = PyObject_GC_New(PyHKEYObject, st->PyHKEY_Type); + if (key == NULL) { + return NULL; + } + key->hkey = hInit; + PyObject_GC_Track(key); return (PyObject *)key; } BOOL -PyHKEY_Close(PyObject *ob_handle) +PyHKEY_Close(winreg_state *st, PyObject *ob_handle) { LONG rc; HKEY key; - if (!PyHKEY_AsHKEY(ob_handle, &key, TRUE)) { + if (!PyHKEY_AsHKEY(st, ob_handle, &key, TRUE)) { return FALSE; } - if (PyHKEY_Check(ob_handle)) { + if (PyHKEY_Check(st, ob_handle)) { ((PyHKEYObject*)ob_handle)->hkey = 0; } rc = key ? RegCloseKey(key) : ERROR_SUCCESS; @@ -416,7 +431,7 @@ PyHKEY_Close(PyObject *ob_handle) } BOOL -PyHKEY_AsHKEY(PyObject *ob, HKEY *pHANDLE, BOOL bNoneOK) +PyHKEY_AsHKEY(winreg_state *st, PyObject *ob, HKEY *pHANDLE, BOOL bNoneOK) { if (ob == Py_None) { if (!bNoneOK) { @@ -427,7 +442,7 @@ PyHKEY_AsHKEY(PyObject *ob, HKEY *pHANDLE, BOOL bNoneOK) } *pHANDLE = (HKEY)0; } - else if (PyHKEY_Check(ob)) { + else if (PyHKEY_Check(st ,ob)) { PyHKEYObject *pH = (PyHKEYObject *)ob; *pHANDLE = pH->hkey; } @@ -448,23 +463,24 @@ PyHKEY_AsHKEY(PyObject *ob, HKEY *pHANDLE, BOOL bNoneOK) } BOOL -clinic_HKEY_converter(PyObject *ob, void *p) +clinic_HKEY_converter(winreg_state *st, PyObject *ob, void *p) { - if (!PyHKEY_AsHKEY(ob, (HKEY *)p, FALSE)) + if (!PyHKEY_AsHKEY(st, ob, (HKEY *)p, FALSE)) { return FALSE; + } return TRUE; } PyObject * -PyHKEY_FromHKEY(HKEY h) +PyHKEY_FromHKEY(winreg_state *st, HKEY h) { - /* Inline PyObject_New */ - PyHKEYObject *op = (PyHKEYObject *) PyObject_Malloc(sizeof(PyHKEYObject)); + PyHKEYObject *op = (PyHKEYObject *)PyObject_GC_New(PyHKEYObject, + st->PyHKEY_Type); if (op == NULL) { - return PyErr_NoMemory(); + return NULL; } - _PyObject_Init((PyObject*)op, &PyHKEY_Type); op->hkey = h; + PyObject_GC_Track(op); return (PyObject *)op; } @@ -473,11 +489,11 @@ PyHKEY_FromHKEY(HKEY h) The module methods ************************************************************************/ BOOL -PyWinObject_CloseHKEY(PyObject *obHandle) +PyWinObject_CloseHKEY(winreg_state *st, PyObject *obHandle) { BOOL ok; - if (PyHKEY_Check(obHandle)) { - ok = PyHKEY_Close(obHandle); + if (PyHKEY_Check(st, obHandle)) { + ok = PyHKEY_Close(st, obHandle); } #if SIZEOF_LONG >= SIZEOF_HKEY else if (PyLong_Check(obHandle)) { @@ -564,7 +580,7 @@ Py2Reg(PyObject *value, DWORD typ, BYTE **retDataBuf, DWORD *retDataSize) { Py_ssize_t i,j; switch (typ) { - case REG_DWORD: + case REG_DWORD: { if (value != Py_None && !PyLong_Check(value)) { return FALSE; @@ -588,7 +604,7 @@ Py2Reg(PyObject *value, DWORD typ, BYTE **retDataBuf, DWORD *retDataSize) *retDataSize = sizeof(DWORD); break; } - case REG_QWORD: + case REG_QWORD: { if (value != Py_None && !PyLong_Check(value)) { return FALSE; @@ -657,19 +673,9 @@ Py2Reg(PyObject *value, DWORD typ, BYTE **retDataBuf, DWORD *retDataSize) t = PyList_GET_ITEM(value, j); if (!PyUnicode_Check(t)) return FALSE; -#if USE_UNICODE_WCHAR_CACHE -_Py_COMP_DIAG_PUSH -_Py_COMP_DIAG_IGNORE_DEPR_DECLS - len = PyUnicode_GetSize(t); - if (len < 0) - return FALSE; - len++; -_Py_COMP_DIAG_POP -#else /* USE_UNICODE_WCHAR_CACHE */ len = PyUnicode_AsWideChar(t, NULL, 0); if (len < 0) return FALSE; -#endif /* USE_UNICODE_WCHAR_CACHE */ size += Py_SAFE_DOWNCAST(len * sizeof(wchar_t), size_t, DWORD); } @@ -808,8 +814,7 @@ Reg2Py(BYTE *retDataBuf, DWORD retDataSize, DWORD typ) support it natively, we should handle the bits. */ default: if (retDataSize == 0) { - Py_INCREF(Py_None); - obData = Py_None; + obData = Py_NewRef(Py_None); } else obData = PyBytes_FromStringAndSize( @@ -838,11 +843,14 @@ static PyObject * winreg_CloseKey(PyObject *module, PyObject *hkey) /*[clinic end generated code: output=a4fa537019a80d15 input=5b1aac65ba5127ad]*/ { - if (!PyHKEY_Close(hkey)) + if (!PyHKEY_Close(_PyModule_GetState(module), hkey)) { return NULL; + } Py_RETURN_NONE; } +#if defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) + /*[clinic input] winreg.ConnectRegistry -> HKEY @@ -880,6 +888,8 @@ winreg_ConnectRegistry_impl(PyObject *module, return retKey; } +#endif /* MS_WINDOWS_DESKTOP || MS_WINDOWS_SYSTEM */ + /*[clinic input] winreg.CreateKey -> HKEY @@ -1286,6 +1296,8 @@ winreg_ExpandEnvironmentStrings_impl(PyObject *module, return o; } +#if defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) + /*[clinic input] winreg.FlushKey @@ -1319,6 +1331,9 @@ winreg_FlushKey_impl(PyObject *module, HKEY key) Py_RETURN_NONE; } +#endif /* MS_WINDOWS_DESKTOP || MS_WINDOWS_SYSTEM */ + +#if defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) /*[clinic input] winreg.LoadKey @@ -1368,6 +1383,8 @@ winreg_LoadKey_impl(PyObject *module, HKEY key, const Py_UNICODE *sub_key, Py_RETURN_NONE; } +#endif /* MS_WINDOWS_DESKTOP || MS_WINDOWS_SYSTEM */ + /*[clinic input] winreg.OpenKey -> HKEY @@ -1477,6 +1494,7 @@ winreg_QueryInfoKey_impl(PyObject *module, HKEY key) return ret; } + /*[clinic input] winreg.QueryValue @@ -1502,53 +1520,77 @@ static PyObject * winreg_QueryValue_impl(PyObject *module, HKEY key, const Py_UNICODE *sub_key) /*[clinic end generated code: output=c655810ae50c63a9 input=41cafbbf423b21d6]*/ { - long rc; - PyObject *retStr; - wchar_t *retBuf; - DWORD bufSize = 0; - DWORD retSize = 0; - wchar_t *tmp; + LONG rc; + HKEY childKey = key; + WCHAR buf[256], *pbuf = buf; + DWORD size = sizeof(buf); + DWORD type; + Py_ssize_t length; + PyObject *result = NULL; if (PySys_Audit("winreg.QueryValue", "nuu", - (Py_ssize_t)key, sub_key, NULL) < 0) { + (Py_ssize_t)key, sub_key, NULL) < 0) + { return NULL; } - rc = RegQueryValueW(key, sub_key, NULL, &retSize); - if (rc == ERROR_MORE_DATA) - retSize = 256; - else if (rc != ERROR_SUCCESS) - return PyErr_SetFromWindowsErrWithFunction(rc, + + if (key == HKEY_PERFORMANCE_DATA) { + return PyErr_SetFromWindowsErrWithFunction(ERROR_INVALID_HANDLE, "RegQueryValue"); + } - bufSize = retSize; - retBuf = (wchar_t *) PyMem_Malloc(bufSize); - if (retBuf == NULL) - return PyErr_NoMemory(); + if (sub_key && sub_key[0]) { + Py_BEGIN_ALLOW_THREADS + rc = RegOpenKeyExW(key, sub_key, 0, KEY_QUERY_VALUE, &childKey); + Py_END_ALLOW_THREADS + if (rc != ERROR_SUCCESS) { + return PyErr_SetFromWindowsErrWithFunction(rc, "RegOpenKeyEx"); + } + } while (1) { - retSize = bufSize; - rc = RegQueryValueW(key, sub_key, retBuf, &retSize); - if (rc != ERROR_MORE_DATA) + Py_BEGIN_ALLOW_THREADS + rc = RegQueryValueExW(childKey, NULL, NULL, &type, (LPBYTE)pbuf, + &size); + Py_END_ALLOW_THREADS + if (rc != ERROR_MORE_DATA) { break; - - bufSize *= 2; - tmp = (wchar_t *) PyMem_Realloc(retBuf, bufSize); + } + void *tmp = PyMem_Realloc(pbuf != buf ? pbuf : NULL, size); if (tmp == NULL) { - PyMem_Free(retBuf); - return PyErr_NoMemory(); + PyErr_NoMemory(); + goto exit; } - retBuf = tmp; + pbuf = tmp; } - if (rc != ERROR_SUCCESS) { - PyMem_Free(retBuf); - return PyErr_SetFromWindowsErrWithFunction(rc, - "RegQueryValue"); + if (rc == ERROR_SUCCESS) { + if (type != REG_SZ) { + PyErr_SetFromWindowsErrWithFunction(ERROR_INVALID_DATA, + "RegQueryValue"); + goto exit; + } + length = wcsnlen(pbuf, size / sizeof(WCHAR)); + } + else if (rc == ERROR_FILE_NOT_FOUND) { + // Return an empty string if there's no default value. + length = 0; + } + else { + PyErr_SetFromWindowsErrWithFunction(rc, "RegQueryValueEx"); + goto exit; } - retStr = PyUnicode_FromWideChar(retBuf, wcslen(retBuf)); - PyMem_Free(retBuf); - return retStr; + result = PyUnicode_FromWideChar(pbuf, length); + +exit: + if (pbuf != buf) { + PyMem_Free(pbuf); + } + if (childKey != key) { + RegCloseKey(childKey); + } + return result; } @@ -1624,6 +1666,8 @@ winreg_QueryValueEx_impl(PyObject *module, HKEY key, const Py_UNICODE *name) return result; } +#if defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) + /*[clinic input] winreg.SaveKey @@ -1669,6 +1713,8 @@ winreg_SaveKey_impl(PyObject *module, HKEY key, const Py_UNICODE *file_name) Py_RETURN_NONE; } +#endif /* MS_WINDOWS_DESKTOP || MS_WINDOWS_SYSTEM */ + /*[clinic input] winreg.SetValue @@ -1701,53 +1747,72 @@ winreg_SetValue_impl(PyObject *module, HKEY key, const Py_UNICODE *sub_key, DWORD type, PyObject *value_obj) /*[clinic end generated code: output=d4773dc9c372311a input=bf088494ae2d24fd]*/ { - Py_ssize_t value_length; - long rc; + LONG rc; + HKEY childKey = key; + LPWSTR value; + Py_ssize_t size; + Py_ssize_t length; + PyObject *result = NULL; if (type != REG_SZ) { PyErr_SetString(PyExc_TypeError, "type must be winreg.REG_SZ"); return NULL; } -#if USE_UNICODE_WCHAR_CACHE -_Py_COMP_DIAG_PUSH -_Py_COMP_DIAG_IGNORE_DEPR_DECLS - const wchar_t *value = PyUnicode_AsUnicodeAndSize(value_obj, &value_length); -_Py_COMP_DIAG_POP -#else /* USE_UNICODE_WCHAR_CACHE */ - wchar_t *value = PyUnicode_AsWideCharString(value_obj, &value_length); -#endif /* USE_UNICODE_WCHAR_CACHE */ + value = PyUnicode_AsWideCharString(value_obj, &length); if (value == NULL) { return NULL; } - if ((Py_ssize_t)(DWORD)value_length != value_length) { + + size = (length + 1) * sizeof(WCHAR); + if ((Py_ssize_t)(DWORD)size != size) { PyErr_SetString(PyExc_OverflowError, "value is too long"); -#if !USE_UNICODE_WCHAR_CACHE - PyMem_Free(value); -#endif /* USE_UNICODE_WCHAR_CACHE */ - return NULL; + goto exit; } if (PySys_Audit("winreg.SetValue", "nunu#", (Py_ssize_t)key, sub_key, (Py_ssize_t)type, - value, value_length) < 0) { -#if !USE_UNICODE_WCHAR_CACHE - PyMem_Free(value); -#endif /* USE_UNICODE_WCHAR_CACHE */ - return NULL; + value, length) < 0) + { + goto exit; + } + + if (key == HKEY_PERFORMANCE_DATA) { + PyErr_SetFromWindowsErrWithFunction(ERROR_INVALID_HANDLE, + "RegSetValue"); + goto exit; + } + + if (sub_key && sub_key[0]) { + Py_BEGIN_ALLOW_THREADS + rc = RegCreateKeyExW(key, sub_key, 0, NULL, 0, KEY_SET_VALUE, NULL, + &childKey, NULL); + Py_END_ALLOW_THREADS + if (rc != ERROR_SUCCESS) { + PyErr_SetFromWindowsErrWithFunction(rc, "RegCreateKeyEx"); + goto exit; + } } Py_BEGIN_ALLOW_THREADS - rc = RegSetValueW(key, sub_key, REG_SZ, value, (DWORD)(value_length + 1)); + rc = RegSetValueExW(childKey, NULL, 0, REG_SZ, (LPBYTE)value, (DWORD)size); Py_END_ALLOW_THREADS -#if !USE_UNICODE_WCHAR_CACHE + if (rc == ERROR_SUCCESS) { + result = Py_NewRef(Py_None); + } + else { + PyErr_SetFromWindowsErrWithFunction(rc, "RegSetValueEx"); + } + +exit: PyMem_Free(value); -#endif /* USE_UNICODE_WCHAR_CACHE */ - if (rc != ERROR_SUCCESS) - return PyErr_SetFromWindowsErrWithFunction(rc, "RegSetValue"); - Py_RETURN_NONE; + if (childKey != key) { + RegCloseKey(childKey); + } + return result; } + /*[clinic input] winreg.SetValueEx @@ -1798,34 +1863,43 @@ winreg_SetValueEx_impl(PyObject *module, HKEY key, DWORD type, PyObject *value) /*[clinic end generated code: output=811b769a66ae11b7 input=900a9e3990bfb196]*/ { - BYTE *data; - DWORD len; - LONG rc; + BYTE *data = NULL; + DWORD size; + PyObject *result = NULL; - if (!Py2Reg(value, type, &data, &len)) + if (!Py2Reg(value, type, &data, &size)) { - if (!PyErr_Occurred()) + if (!PyErr_Occurred()) { PyErr_SetString(PyExc_ValueError, "Could not convert the data to the specified type."); + } return NULL; } if (PySys_Audit("winreg.SetValue", "nunO", (Py_ssize_t)key, value_name, (Py_ssize_t)type, - value) < 0) { - PyMem_Free(data); - return NULL; + value) < 0) + { + goto exit; } + Py_BEGIN_ALLOW_THREADS - rc = RegSetValueExW(key, value_name, 0, type, data, len); + rc = RegSetValueExW(key, value_name, 0, type, data, size); Py_END_ALLOW_THREADS + if (rc == ERROR_SUCCESS) { + result = Py_NewRef(Py_None); + } + else { + PyErr_SetFromWindowsErrWithFunction(rc, "RegSetValueEx"); + } + +exit: PyMem_Free(data); - if (rc != ERROR_SUCCESS) - return PyErr_SetFromWindowsErrWithFunction(rc, - "RegSetValueEx"); - Py_RETURN_NONE; + return result; } +#if defined(MS_WINDOWS_DESKTOP) || defined(MS_WINDOWS_SYSTEM) + /*[clinic input] winreg.DisableReflectionKey @@ -1974,6 +2048,8 @@ winreg_QueryReflectionKey_impl(PyObject *module, HKEY key) return PyBool_FromLong(result); } +#endif /* MS_WINDOWS_DESKTOP || MS_WINDOWS_SYSTEM */ + static struct PyMethodDef winreg_methods[] = { WINREG_CLOSEKEY_METHODDEF WINREG_CONNECTREGISTRY_METHODDEF @@ -2001,57 +2077,46 @@ static struct PyMethodDef winreg_methods[] = { NULL, }; -static void -insint(PyObject * d, char * name, long value) -{ - PyObject *v = PyLong_FromLong(value); - if (!v || PyDict_SetItemString(d, name, v)) - PyErr_Clear(); - Py_XDECREF(v); -} - -#define ADD_INT(val) insint(d, #val, val) +#define ADD_INT(VAL) do { \ + if (PyModule_AddIntConstant(m, #VAL, VAL) < 0) { \ + return -1; \ + } \ +} while (0) -static void -inskey(PyObject * d, char * name, HKEY key) +static int +inskey(PyObject *mod, char *name, HKEY key) { PyObject *v = PyLong_FromVoidPtr(key); - if (!v || PyDict_SetItemString(d, name, v)) - PyErr_Clear(); - Py_XDECREF(v); + if (v == NULL) { + return -1; + } + int rc = PyModule_AddObjectRef(mod, name, v); + Py_DECREF(v); + return rc; } -#define ADD_KEY(val) inskey(d, #val, val) - - -static struct PyModuleDef winregmodule = { - PyModuleDef_HEAD_INIT, - "winreg", - module_doc, - -1, - winreg_methods, - NULL, - NULL, - NULL, - NULL -}; +#define ADD_KEY(VAL) do { \ + if (inskey(m, #VAL, VAL) < 0) { \ + return -1; \ + } \ +} while (0) -PyMODINIT_FUNC PyInit_winreg(void) +static int +exec_module(PyObject *m) { - PyObject *m, *d; - m = PyModule_Create(&winregmodule); - if (m == NULL) - return NULL; - d = PyModule_GetDict(m); - PyHKEY_Type.tp_doc = PyHKEY_doc; - if (PyType_Ready(&PyHKEY_Type) < 0) - return NULL; - if (PyDict_SetItemString(d, "HKEYType", - (PyObject *)&PyHKEY_Type) != 0) - return NULL; - if (PyDict_SetItemString(d, "error", - PyExc_OSError) != 0) - return NULL; + winreg_state *st = (winreg_state *)_PyModule_GetState(m); + + st->PyHKEY_Type = (PyTypeObject *) + PyType_FromModuleAndSpec(m, &pyhkey_type_spec, NULL); + if (st->PyHKEY_Type == NULL) { + return -1; + } + if (PyModule_AddObjectRef(m, "HKEYType", (PyObject *)st->PyHKEY_Type) < 0) { + return -1; + } + if (PyModule_AddObjectRef(m, "error", PyExc_OSError) < 0) { + return -1; + } /* Add the relevant constants */ ADD_KEY(HKEY_CLASSES_ROOT); @@ -2112,5 +2177,47 @@ PyMODINIT_FUNC PyInit_winreg(void) ADD_INT(REG_RESOURCE_LIST); ADD_INT(REG_FULL_RESOURCE_DESCRIPTOR); ADD_INT(REG_RESOURCE_REQUIREMENTS_LIST); - return m; + +#undef ADD_INT + return 0; +} + +static PyModuleDef_Slot winreg_slots[] = { + {Py_mod_exec, exec_module}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, + {0, NULL} +}; + +static int +winreg_traverse(PyObject *module, visitproc visit, void *arg) +{ + winreg_state *state = _PyModule_GetState(module); + Py_VISIT(state->PyHKEY_Type); + return 0; } + +static int +winreg_clear(PyObject *module) +{ + winreg_state *state = _PyModule_GetState(module); + Py_CLEAR(state->PyHKEY_Type); + return 0; +} + +static struct PyModuleDef winregmodule = { + .m_base = PyModuleDef_HEAD_INIT, + .m_name = "winreg", + .m_doc = module_doc, + .m_size = sizeof(winreg_state), + .m_methods = winreg_methods, + .m_slots = winreg_slots, + .m_traverse = winreg_traverse, + .m_clear = winreg_clear, +}; + +PyMODINIT_FUNC PyInit_winreg(void) +{ + return PyModuleDef_Init(&winregmodule); +} + +#endif /* MS_WINDOWS_DESKTOP || MS_WINDOWS_SYSTEM || MS_WINDOWS_GAMES */ diff --git a/PC/winsound.c b/PC/winsound.c index fd04e1e5..68a91781 100644 --- a/PC/winsound.c +++ b/PC/winsound.c @@ -94,17 +94,25 @@ winsound_PlaySound_impl(PyObject *module, PyObject *sound, int flags) return NULL; } wsound = (wchar_t *)view.buf; + } else if (PyBytes_Check(sound)) { + PyErr_Format(PyExc_TypeError, + "'sound' must be str, os.PathLike, or None, not '%s'", + Py_TYPE(sound)->tp_name); + return NULL; } else { - if (!PyUnicode_Check(sound)) { + PyObject *obj = PyOS_FSPath(sound); + // Either <obj> is unicode/bytes/NULL, or a helpful message + // has been surfaced to the user about how they gave a non-path. + if (obj == NULL) return NULL; + if (PyBytes_Check(obj)) { PyErr_Format(PyExc_TypeError, - "'sound' must be str or None, not '%s'", - Py_TYPE(sound)->tp_name); - return NULL; - } - wsound = PyUnicode_AsWideCharString(sound, NULL); - if (wsound == NULL) { + "'sound' must resolve to str, not bytes"); + Py_DECREF(obj); return NULL; } + wsound = PyUnicode_AsWideCharString(obj, NULL); + Py_DECREF(obj); + if (wsound == NULL) return NULL; } @@ -194,42 +202,15 @@ static struct PyMethodDef sound_methods[] = {NULL, NULL} }; -static void -add_define(PyObject *dict, const char *key, long value) -{ - PyObject *k = PyUnicode_FromString(key); - PyObject *v = PyLong_FromLong(value); - if (v && k) { - PyDict_SetItem(dict, k, v); - } - Py_XDECREF(k); - Py_XDECREF(v); -} - -#define ADD_DEFINE(tok) add_define(dict,#tok,tok) +#define ADD_DEFINE(CONST) do { \ + if (PyModule_AddIntConstant(module, #CONST, CONST) < 0) { \ + return -1; \ + } \ +} while (0) - -static struct PyModuleDef winsoundmodule = { - PyModuleDef_HEAD_INIT, - "winsound", - sound_module_doc, - -1, - sound_methods, - NULL, - NULL, - NULL, - NULL -}; - -PyMODINIT_FUNC -PyInit_winsound(void) +static int +exec_module(PyObject *module) { - PyObject *dict; - PyObject *module = PyModule_Create(&winsoundmodule); - if (module == NULL) - return NULL; - dict = PyModule_GetDict(module); - ADD_DEFINE(SND_ASYNC); ADD_DEFINE(SND_NODEFAULT); ADD_DEFINE(SND_NOSTOP); @@ -246,5 +227,28 @@ PyInit_winsound(void) ADD_DEFINE(MB_ICONEXCLAMATION); ADD_DEFINE(MB_ICONHAND); ADD_DEFINE(MB_ICONQUESTION); - return module; + +#undef ADD_DEFINE + + return 0; +} + +static PyModuleDef_Slot sound_slots[] = { + {Py_mod_exec, exec_module}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, + {0, NULL} +}; + +static struct PyModuleDef winsoundmodule = { + .m_base = PyModuleDef_HEAD_INIT, + .m_name = "winsound", + .m_doc = sound_module_doc, + .m_methods = sound_methods, + .m_slots = sound_slots, +}; + +PyMODINIT_FUNC +PyInit_winsound(void) +{ + return PyModuleDef_Init(&winsoundmodule); } diff --git a/PCbuild/Directory.Build.props b/PCbuild/Directory.Build.props index 4464f465..3d2fe550 100644 --- a/PCbuild/Directory.Build.props +++ b/PCbuild/Directory.Build.props @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <!-- This is intentionally left blank but exists to avoid being imported from some directory above --> -</Project> +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <!-- This is intentionally left blank but exists to avoid being imported from some directory above --> +</Project> diff --git a/PCbuild/_asyncio.vcxproj b/PCbuild/_asyncio.vcxproj index 937d491a..ed1e1bc0 100644 --- a/PCbuild/_asyncio.vcxproj +++ b/PCbuild/_asyncio.vcxproj @@ -1,109 +1,109 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|ARM"> - <Configuration>Debug</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|ARM64"> - <Configuration>Debug</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM64"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|Win32"> - <Configuration>PGInstrument</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|x64"> - <Configuration>PGInstrument</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM64"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|Win32"> - <Configuration>PGUpdate</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|x64"> - <Configuration>PGUpdate</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM"> - <Configuration>Release</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM64"> - <Configuration>Release</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectGuid>{384C224A-7474-476E-A01B-750EA7DE918C}</ProjectGuid> - <RootNamespace>_asyncio</RootNamespace> - <Keyword>Win32Proj</Keyword> - </PropertyGroup> - <Import Project="python.props" /> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>NotSet</CharacterSet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <PropertyGroup> - <TargetExt>.pyd</TargetExt> - </PropertyGroup> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="pyproject.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup> - <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> - </PropertyGroup> - <ItemGroup> - <ClCompile Include="..\Modules\_asynciomodule.c" /> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\python_nt.rc" /> - </ItemGroup> - <ItemGroup> - <ProjectReference Include="pythoncore.vcxproj"> - <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> - <ReferenceOutputAssembly>false</ReferenceOutputAssembly> - </ProjectReference> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> -</Project> +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|ARM"> + <Configuration>Debug</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|ARM64"> + <Configuration>Debug</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM64"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|Win32"> + <Configuration>PGInstrument</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|x64"> + <Configuration>PGInstrument</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM64"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|Win32"> + <Configuration>PGUpdate</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|x64"> + <Configuration>PGUpdate</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM"> + <Configuration>Release</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM64"> + <Configuration>Release</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{384C224A-7474-476E-A01B-750EA7DE918C}</ProjectGuid> + <RootNamespace>_asyncio</RootNamespace> + <Keyword>Win32Proj</Keyword> + </PropertyGroup> + <Import Project="python.props" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <CharacterSet>NotSet</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <PropertyGroup> + <TargetExt>.pyd</TargetExt> + </PropertyGroup> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="pyproject.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> + </PropertyGroup> + <ItemGroup> + <ClCompile Include="..\Modules\_asynciomodule.c" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_nt.rc" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="pythoncore.vcxproj"> + <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> diff --git a/PCbuild/_asyncio.vcxproj.filters b/PCbuild/_asyncio.vcxproj.filters index 8f4160ca..a09ae928 100644 --- a/PCbuild/_asyncio.vcxproj.filters +++ b/PCbuild/_asyncio.vcxproj.filters @@ -1,21 +1,21 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <Filter Include="Source Files"> - <UniqueIdentifier>{2422278e-eeeb-4241-8182-433e2bc5a7fc}</UniqueIdentifier> - </Filter> - <Filter Include="Resource Files"> - <UniqueIdentifier>{41f1cd52-b682-46aa-a7fd-7bdf81a18010}</UniqueIdentifier> - </Filter> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\Modules\_asynciomodule.c"> - <Filter>Source Files</Filter> - </ClCompile> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\python_nt.rc"> - <Filter>Resource Files</Filter> - </ResourceCompile> - </ItemGroup> +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{2422278e-eeeb-4241-8182-433e2bc5a7fc}</UniqueIdentifier> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{41f1cd52-b682-46aa-a7fd-7bdf81a18010}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\Modules\_asynciomodule.c"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_nt.rc"> + <Filter>Resource Files</Filter> + </ResourceCompile> + </ItemGroup> </Project> \ No newline at end of file diff --git a/PCbuild/_bz2.vcxproj b/PCbuild/_bz2.vcxproj index f9162279..3fe95fbf 100644 --- a/PCbuild/_bz2.vcxproj +++ b/PCbuild/_bz2.vcxproj @@ -1,128 +1,128 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|ARM"> - <Configuration>Debug</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|ARM64"> - <Configuration>Debug</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM64"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|Win32"> - <Configuration>PGInstrument</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|x64"> - <Configuration>PGInstrument</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM64"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|Win32"> - <Configuration>PGUpdate</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|x64"> - <Configuration>PGUpdate</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM"> - <Configuration>Release</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM64"> - <Configuration>Release</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectGuid>{73FCD2BD-F133-46B7-8EC1-144CD82A59D5}</ProjectGuid> - <RootNamespace>bz2</RootNamespace> - <Keyword>Win32Proj</Keyword> - </PropertyGroup> - <Import Project="python.props" /> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>NotSet</CharacterSet> - </PropertyGroup> - <PropertyGroup Label="Configuration" /> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <PropertyGroup> - <TargetExt>.pyd</TargetExt> - </PropertyGroup> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="pyproject.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup> - <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> - </PropertyGroup> - <ItemDefinitionGroup> - <ClCompile> - <AdditionalIncludeDirectories>$(bz2Dir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>WIN32;_FILE_OFFSET_BITS=64;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <DisableSpecificWarnings>4244;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings> - </ClCompile> - </ItemDefinitionGroup> - <ItemGroup> - <ClCompile Include="..\Modules\_bz2module.c" /> - <ClCompile Include="$(bz2Dir)\blocksort.c" /> - <ClCompile Include="$(bz2Dir)\bzlib.c" /> - <ClCompile Include="$(bz2Dir)\compress.c" /> - <ClCompile Include="$(bz2Dir)\crctable.c" /> - <ClCompile Include="$(bz2Dir)\decompress.c" /> - <ClCompile Include="$(bz2Dir)\huffman.c" /> - <ClCompile Include="$(bz2Dir)\randtable.c" /> - </ItemGroup> - <ItemGroup> - <ClInclude Include="$(bz2Dir)\bzlib.h" /> - <ClInclude Include="$(bz2Dir)\bzlib_private.h" /> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\python_nt.rc" /> - </ItemGroup> - <ItemGroup> - <ProjectReference Include="pythoncore.vcxproj"> - <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> - <ReferenceOutputAssembly>false</ReferenceOutputAssembly> - </ProjectReference> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|ARM"> + <Configuration>Debug</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|ARM64"> + <Configuration>Debug</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM64"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|Win32"> + <Configuration>PGInstrument</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|x64"> + <Configuration>PGInstrument</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM64"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|Win32"> + <Configuration>PGUpdate</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|x64"> + <Configuration>PGUpdate</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM"> + <Configuration>Release</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM64"> + <Configuration>Release</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{73FCD2BD-F133-46B7-8EC1-144CD82A59D5}</ProjectGuid> + <RootNamespace>bz2</RootNamespace> + <Keyword>Win32Proj</Keyword> + </PropertyGroup> + <Import Project="python.props" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <CharacterSet>NotSet</CharacterSet> + </PropertyGroup> + <PropertyGroup Label="Configuration" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <PropertyGroup> + <TargetExt>.pyd</TargetExt> + </PropertyGroup> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="pyproject.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> + </PropertyGroup> + <ItemDefinitionGroup> + <ClCompile> + <AdditionalIncludeDirectories>$(bz2Dir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_FILE_OFFSET_BITS=64;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <DisableSpecificWarnings>4244;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings> + </ClCompile> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\Modules\_bz2module.c" /> + <ClCompile Include="$(bz2Dir)\blocksort.c" /> + <ClCompile Include="$(bz2Dir)\bzlib.c" /> + <ClCompile Include="$(bz2Dir)\compress.c" /> + <ClCompile Include="$(bz2Dir)\crctable.c" /> + <ClCompile Include="$(bz2Dir)\decompress.c" /> + <ClCompile Include="$(bz2Dir)\huffman.c" /> + <ClCompile Include="$(bz2Dir)\randtable.c" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="$(bz2Dir)\bzlib.h" /> + <ClInclude Include="$(bz2Dir)\bzlib_private.h" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_nt.rc" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="pythoncore.vcxproj"> + <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> </Project> \ No newline at end of file diff --git a/PCbuild/_bz2.vcxproj.filters b/PCbuild/_bz2.vcxproj.filters index ce2e24e3..7c0b5162 100644 --- a/PCbuild/_bz2.vcxproj.filters +++ b/PCbuild/_bz2.vcxproj.filters @@ -1,59 +1,59 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <Filter Include="Source Files"> - <UniqueIdentifier>{f53a859d-dad2-4d5b-ae41-f28d8b571f5a}</UniqueIdentifier> - </Filter> - <Filter Include="Resource Files"> - <UniqueIdentifier>{b90c3cee-7700-4e87-bf85-0801866e8d0d}</UniqueIdentifier> - </Filter> - <Filter Include="Header Files"> - <UniqueIdentifier>{7e0bed05-ae33-43b7-8797-656455bbb7f3}</UniqueIdentifier> - </Filter> - <Filter Include="Header Files\bzip2"> - <UniqueIdentifier>{b53f67d8-fdf0-4e10-a987-e44475ff434a}</UniqueIdentifier> - </Filter> - <Filter Include="Source Files\bzip2"> - <UniqueIdentifier>{ed574b89-6983-4cdf-9f98-fe7048d9e89c}</UniqueIdentifier> - </Filter> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\Modules\_bz2module.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(bz2Dir)\blocksort.c"> - <Filter>Source Files\bzip2</Filter> - </ClCompile> - <ClCompile Include="$(bz2Dir)\bzlib.c"> - <Filter>Source Files\bzip2</Filter> - </ClCompile> - <ClCompile Include="$(bz2Dir)\compress.c"> - <Filter>Source Files\bzip2</Filter> - </ClCompile> - <ClCompile Include="$(bz2Dir)\crctable.c"> - <Filter>Source Files\bzip2</Filter> - </ClCompile> - <ClCompile Include="$(bz2Dir)\decompress.c"> - <Filter>Source Files\bzip2</Filter> - </ClCompile> - <ClCompile Include="$(bz2Dir)\huffman.c"> - <Filter>Source Files\bzip2</Filter> - </ClCompile> - <ClCompile Include="$(bz2Dir)\randtable.c"> - <Filter>Source Files\bzip2</Filter> - </ClCompile> - </ItemGroup> - <ItemGroup> - <ClInclude Include="$(bz2Dir)\bzlib_private.h"> - <Filter>Header Files\bzip2</Filter> - </ClInclude> - <ClInclude Include="$(bz2Dir)\bzlib.h"> - <Filter>Header Files\bzip2</Filter> - </ClInclude> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\python_nt.rc"> - <Filter>Resource Files</Filter> - </ResourceCompile> - </ItemGroup> +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{f53a859d-dad2-4d5b-ae41-f28d8b571f5a}</UniqueIdentifier> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{b90c3cee-7700-4e87-bf85-0801866e8d0d}</UniqueIdentifier> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{7e0bed05-ae33-43b7-8797-656455bbb7f3}</UniqueIdentifier> + </Filter> + <Filter Include="Header Files\bzip2"> + <UniqueIdentifier>{b53f67d8-fdf0-4e10-a987-e44475ff434a}</UniqueIdentifier> + </Filter> + <Filter Include="Source Files\bzip2"> + <UniqueIdentifier>{ed574b89-6983-4cdf-9f98-fe7048d9e89c}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\Modules\_bz2module.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(bz2Dir)\blocksort.c"> + <Filter>Source Files\bzip2</Filter> + </ClCompile> + <ClCompile Include="$(bz2Dir)\bzlib.c"> + <Filter>Source Files\bzip2</Filter> + </ClCompile> + <ClCompile Include="$(bz2Dir)\compress.c"> + <Filter>Source Files\bzip2</Filter> + </ClCompile> + <ClCompile Include="$(bz2Dir)\crctable.c"> + <Filter>Source Files\bzip2</Filter> + </ClCompile> + <ClCompile Include="$(bz2Dir)\decompress.c"> + <Filter>Source Files\bzip2</Filter> + </ClCompile> + <ClCompile Include="$(bz2Dir)\huffman.c"> + <Filter>Source Files\bzip2</Filter> + </ClCompile> + <ClCompile Include="$(bz2Dir)\randtable.c"> + <Filter>Source Files\bzip2</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="$(bz2Dir)\bzlib_private.h"> + <Filter>Header Files\bzip2</Filter> + </ClInclude> + <ClInclude Include="$(bz2Dir)\bzlib.h"> + <Filter>Header Files\bzip2</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_nt.rc"> + <Filter>Resource Files</Filter> + </ResourceCompile> + </ItemGroup> </Project> \ No newline at end of file diff --git a/PCbuild/_ctypes.vcxproj b/PCbuild/_ctypes.vcxproj index 8b4c4565..253da31e 100644 --- a/PCbuild/_ctypes.vcxproj +++ b/PCbuild/_ctypes.vcxproj @@ -1,124 +1,123 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|ARM"> - <Configuration>Debug</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|ARM64"> - <Configuration>Debug</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM64"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|Win32"> - <Configuration>PGInstrument</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|x64"> - <Configuration>PGInstrument</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM64"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|Win32"> - <Configuration>PGUpdate</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|x64"> - <Configuration>PGUpdate</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM"> - <Configuration>Release</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM64"> - <Configuration>Release</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectGuid>{0E9791DB-593A-465F-98BC-681011311618}</ProjectGuid> - <RootNamespace>_ctypes</RootNamespace> - <Keyword>Win32Proj</Keyword> - </PropertyGroup> - <Import Project="python.props" /> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>NotSet</CharacterSet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <PropertyGroup> - <TargetExt>.pyd</TargetExt> - </PropertyGroup> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="pyproject.props" /> - <Import Project="libffi.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup> - <_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion> - </PropertyGroup> - <ItemDefinitionGroup> - <ClCompile> - <PreprocessorDefinitions>USING_MALLOC_CLOSURE_DOT_C=1;%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <Link> - <AdditionalOptions>/EXPORT:DllGetClassObject,PRIVATE /EXPORT:DllCanUnloadNow,PRIVATE %(AdditionalOptions)</AdditionalOptions> - </Link> - </ItemDefinitionGroup> - <ItemGroup> - <ClInclude Include="..\Modules\_ctypes\ctypes.h" /> - <ClInclude Include="..\Modules\_ctypes\ctypes_dlfcn.h" /> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\Modules\_ctypes\_ctypes.c" /> - <ClCompile Include="..\Modules\_ctypes\callbacks.c" /> - <ClCompile Include="..\Modules\_ctypes\callproc.c" /> - <ClCompile Include="..\Modules\_ctypes\cfield.c" /> - <ClCompile Include="..\Modules\_ctypes\malloc_closure.c" /> - <ClCompile Include="..\Modules\_ctypes\stgdict.c" /> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\python_nt.rc" /> - </ItemGroup> - <ItemGroup> - <ProjectReference Include="pythoncore.vcxproj"> - <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> - </ProjectReference> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> -</Project> +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|ARM"> + <Configuration>Debug</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|ARM64"> + <Configuration>Debug</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM64"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|Win32"> + <Configuration>PGInstrument</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|x64"> + <Configuration>PGInstrument</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM64"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|Win32"> + <Configuration>PGUpdate</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|x64"> + <Configuration>PGUpdate</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM"> + <Configuration>Release</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM64"> + <Configuration>Release</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{0E9791DB-593A-465F-98BC-681011311618}</ProjectGuid> + <RootNamespace>_ctypes</RootNamespace> + <Keyword>Win32Proj</Keyword> + </PropertyGroup> + <Import Project="python.props" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <CharacterSet>NotSet</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <PropertyGroup> + <TargetExt>.pyd</TargetExt> + </PropertyGroup> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="pyproject.props" /> + <Import Project="libffi.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion> + </PropertyGroup> + <ItemDefinitionGroup> + <ClCompile> + <PreprocessorDefinitions>USING_MALLOC_CLOSURE_DOT_C=1;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <Link> + <AdditionalOptions>/EXPORT:DllGetClassObject,PRIVATE /EXPORT:DllCanUnloadNow,PRIVATE %(AdditionalOptions)</AdditionalOptions> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClInclude Include="..\Modules\_ctypes\ctypes.h" /> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\Modules\_ctypes\_ctypes.c" /> + <ClCompile Include="..\Modules\_ctypes\callbacks.c" /> + <ClCompile Include="..\Modules\_ctypes\callproc.c" /> + <ClCompile Include="..\Modules\_ctypes\cfield.c" /> + <ClCompile Include="..\Modules\_ctypes\malloc_closure.c" /> + <ClCompile Include="..\Modules\_ctypes\stgdict.c" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_nt.rc" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="pythoncore.vcxproj"> + <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> +</Project> diff --git a/PCbuild/_ctypes.vcxproj.filters b/PCbuild/_ctypes.vcxproj.filters index 1155ef5d..a38473e3 100644 --- a/PCbuild/_ctypes.vcxproj.filters +++ b/PCbuild/_ctypes.vcxproj.filters @@ -1,47 +1,44 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <Filter Include="Header Files"> - <UniqueIdentifier>{806081ee-2af0-48d0-a83e-ee02a74baa0f}</UniqueIdentifier> - </Filter> - <Filter Include="Source Files"> - <UniqueIdentifier>{dbdea1f2-ad8b-44ca-b782-fcf65d91559b}</UniqueIdentifier> - </Filter> - <Filter Include="Resource Files"> - <UniqueIdentifier>{31a37bb4-c384-41ff-9ec1-8ad98d482e22}</UniqueIdentifier> - </Filter> - </ItemGroup> - <ItemGroup> - <ClInclude Include="..\Modules\_ctypes\ctypes.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\Modules\_ctypes\ctypes_dlfcn.h"> - <Filter>Header Files</Filter> - </ClInclude> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\Modules\_ctypes\_ctypes.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_ctypes\callbacks.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_ctypes\callproc.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_ctypes\cfield.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_ctypes\malloc_closure.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_ctypes\stgdict.c"> - <Filter>Source Files</Filter> - </ClCompile> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\python_nt.rc"> - <Filter>Resource Files</Filter> - </ResourceCompile> - </ItemGroup> +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Header Files"> + <UniqueIdentifier>{806081ee-2af0-48d0-a83e-ee02a74baa0f}</UniqueIdentifier> + </Filter> + <Filter Include="Source Files"> + <UniqueIdentifier>{dbdea1f2-ad8b-44ca-b782-fcf65d91559b}</UniqueIdentifier> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{31a37bb4-c384-41ff-9ec1-8ad98d482e22}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\Modules\_ctypes\ctypes.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\Modules\_ctypes\_ctypes.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_ctypes\callbacks.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_ctypes\callproc.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_ctypes\cfield.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_ctypes\malloc_closure.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_ctypes\stgdict.c"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_nt.rc"> + <Filter>Resource Files</Filter> + </ResourceCompile> + </ItemGroup> </Project> \ No newline at end of file diff --git a/PCbuild/_ctypes_test.vcxproj b/PCbuild/_ctypes_test.vcxproj index 92c782e4..8a01e743 100644 --- a/PCbuild/_ctypes_test.vcxproj +++ b/PCbuild/_ctypes_test.vcxproj @@ -1,112 +1,112 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|ARM"> - <Configuration>Debug</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|ARM64"> - <Configuration>Debug</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM64"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|Win32"> - <Configuration>PGInstrument</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|x64"> - <Configuration>PGInstrument</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM64"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|Win32"> - <Configuration>PGUpdate</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|x64"> - <Configuration>PGUpdate</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM"> - <Configuration>Release</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM64"> - <Configuration>Release</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectGuid>{9EC7190A-249F-4180-A900-548FDCF3055F}</ProjectGuid> - <RootNamespace>_ctypes_test</RootNamespace> - <Keyword>Win32Proj</Keyword> - <SupportPGO>false</SupportPGO> - </PropertyGroup> - <Import Project="python.props" /> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>NotSet</CharacterSet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <PropertyGroup> - <TargetExt>.pyd</TargetExt> - </PropertyGroup> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="pyproject.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup> - <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> - </PropertyGroup> - <ItemGroup> - <ClInclude Include="..\Modules\_ctypes\_ctypes_test.h" /> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\Modules\_ctypes\_ctypes_test.c" /> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\python_nt.rc" /> - </ItemGroup> - <ItemGroup> - <ProjectReference Include="pythoncore.vcxproj"> - <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> - </ProjectReference> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|ARM"> + <Configuration>Debug</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|ARM64"> + <Configuration>Debug</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM64"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|Win32"> + <Configuration>PGInstrument</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|x64"> + <Configuration>PGInstrument</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM64"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|Win32"> + <Configuration>PGUpdate</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|x64"> + <Configuration>PGUpdate</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM"> + <Configuration>Release</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM64"> + <Configuration>Release</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{9EC7190A-249F-4180-A900-548FDCF3055F}</ProjectGuid> + <RootNamespace>_ctypes_test</RootNamespace> + <Keyword>Win32Proj</Keyword> + <SupportPGO>false</SupportPGO> + </PropertyGroup> + <Import Project="python.props" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <CharacterSet>NotSet</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <PropertyGroup> + <TargetExt>.pyd</TargetExt> + </PropertyGroup> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="pyproject.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> + </PropertyGroup> + <ItemGroup> + <ClInclude Include="..\Modules\_ctypes\_ctypes_test.h" /> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\Modules\_ctypes\_ctypes_test.c" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_nt.rc" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="pythoncore.vcxproj"> + <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> </Project> \ No newline at end of file diff --git a/PCbuild/_ctypes_test.vcxproj.filters b/PCbuild/_ctypes_test.vcxproj.filters index 5e395fe0..5174196c 100644 --- a/PCbuild/_ctypes_test.vcxproj.filters +++ b/PCbuild/_ctypes_test.vcxproj.filters @@ -1,29 +1,29 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <Filter Include="Header Files"> - <UniqueIdentifier>{8fd70119-5481-4e5d-b187-d0b14eb27e38}</UniqueIdentifier> - </Filter> - <Filter Include="Source Files"> - <UniqueIdentifier>{38abc486-e143-49dc-8cf0-8aefab0e0d3d}</UniqueIdentifier> - </Filter> - <Filter Include="Resource Files"> - <UniqueIdentifier>{5030ff8f-daf5-4bc8-b1dd-e8b59d34c511}</UniqueIdentifier> - </Filter> - </ItemGroup> - <ItemGroup> - <ClInclude Include="..\Modules\_ctypes\_ctypes_test.h"> - <Filter>Header Files</Filter> - </ClInclude> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\Modules\_ctypes\_ctypes_test.c"> - <Filter>Source Files</Filter> - </ClCompile> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\python_nt.rc"> - <Filter>Resource Files</Filter> - </ResourceCompile> - </ItemGroup> +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Header Files"> + <UniqueIdentifier>{8fd70119-5481-4e5d-b187-d0b14eb27e38}</UniqueIdentifier> + </Filter> + <Filter Include="Source Files"> + <UniqueIdentifier>{38abc486-e143-49dc-8cf0-8aefab0e0d3d}</UniqueIdentifier> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{5030ff8f-daf5-4bc8-b1dd-e8b59d34c511}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\Modules\_ctypes\_ctypes_test.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\Modules\_ctypes\_ctypes_test.c"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_nt.rc"> + <Filter>Resource Files</Filter> + </ResourceCompile> + </ItemGroup> </Project> \ No newline at end of file diff --git a/PCbuild/_decimal.vcxproj b/PCbuild/_decimal.vcxproj index dede9c13..0916f1a2 100644 --- a/PCbuild/_decimal.vcxproj +++ b/PCbuild/_decimal.vcxproj @@ -1,159 +1,159 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|ARM"> - <Configuration>Debug</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|ARM64"> - <Configuration>Debug</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM64"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|Win32"> - <Configuration>PGInstrument</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|x64"> - <Configuration>PGInstrument</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM64"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|Win32"> - <Configuration>PGUpdate</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|x64"> - <Configuration>PGUpdate</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM"> - <Configuration>Release</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM64"> - <Configuration>Release</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectGuid>{0E9791DB-593A-465F-98BC-681011311617}</ProjectGuid> - <RootNamespace>_decimal</RootNamespace> - <Keyword>Win32Proj</Keyword> - </PropertyGroup> - <Import Project="python.props" /> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>NotSet</CharacterSet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <PropertyGroup> - <TargetExt>.pyd</TargetExt> - </PropertyGroup> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="pyproject.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup> - <_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion> - </PropertyGroup> - <ItemDefinitionGroup> - <ClCompile> - <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <PreprocessorDefinitions Condition="'$(Platform)' == 'Win32'">CONFIG_32;PPRO;MASM;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <PreprocessorDefinitions Condition="'$(Platform)'=='ARM'">CONFIG_32;ANSI;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <PreprocessorDefinitions Condition="'$(Platform)'=='ARM64'">CONFIG_64;ANSI;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <PreprocessorDefinitions Condition="'$(Platform)' == 'x64'">CONFIG_64;MASM;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories>..\Modules\_decimal;..\Modules\_decimal\libmpdec;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - </ClCompile> - </ItemDefinitionGroup> - <ItemGroup> - <ClInclude Include="..\Modules\_decimal\libmpdec\basearith.h" /> - <ClInclude Include="..\Modules\_decimal\libmpdec\bits.h" /> - <ClInclude Include="..\Modules\_decimal\libmpdec\constants.h" /> - <ClInclude Include="..\Modules\_decimal\libmpdec\convolute.h" /> - <ClInclude Include="..\Modules\_decimal\libmpdec\crt.h" /> - <ClInclude Include="..\Modules\_decimal\libmpdec\difradix2.h" /> - <ClInclude Include="..\Modules\_decimal\docstrings.h" /> - <ClInclude Include="..\Modules\_decimal\libmpdec\fnt.h" /> - <ClInclude Include="..\Modules\_decimal\libmpdec\fourstep.h" /> - <ClInclude Include="..\Modules\_decimal\libmpdec\mpdecimal.h" /> - <ClInclude Include="..\Modules\_decimal\libmpdec\numbertheory.h" /> - <ClInclude Include="..\Modules\_decimal\libmpdec\sixstep.h" /> - <ClInclude Include="..\Modules\_decimal\libmpdec\transpose.h" /> - <ClInclude Include="..\Modules\_decimal\libmpdec\typearith.h" /> - <ClInclude Include="..\Modules\_decimal\libmpdec\umodarith.h" /> - <ClInclude Include="..\Modules\_decimal\libmpdec\vccompat.h" /> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\Modules\_decimal\_decimal.c" /> - <ClCompile Include="..\Modules\_decimal\libmpdec\basearith.c" /> - <ClCompile Include="..\Modules\_decimal\libmpdec\constants.c" /> - <ClCompile Include="..\Modules\_decimal\libmpdec\context.c" /> - <ClCompile Include="..\Modules\_decimal\libmpdec\convolute.c" /> - <ClCompile Include="..\Modules\_decimal\libmpdec\crt.c" /> - <ClCompile Include="..\Modules\_decimal\libmpdec\difradix2.c" /> - <ClCompile Include="..\Modules\_decimal\libmpdec\fnt.c" /> - <ClCompile Include="..\Modules\_decimal\libmpdec\fourstep.c" /> - <ClCompile Include="..\Modules\_decimal\libmpdec\io.c" /> - <ClCompile Include="..\Modules\_decimal\libmpdec\mpalloc.c" /> - <ClCompile Include="..\Modules\_decimal\libmpdec\mpdecimal.c" /> - <ClCompile Include="..\Modules\_decimal\libmpdec\numbertheory.c" /> - <ClCompile Include="..\Modules\_decimal\libmpdec\sixstep.c" /> - <ClCompile Include="..\Modules\_decimal\libmpdec\transpose.c" /> - </ItemGroup> - <ItemGroup> - <CustomBuild Include="..\Modules\_decimal\libmpdec\vcdiv64.asm"> - <ExcludedFromBuild Condition="'$(Platform)'=='Win32'">true</ExcludedFromBuild> - <ExcludedFromBuild Condition="'$(Platform)'=='ARM'">true</ExcludedFromBuild> - <ExcludedFromBuild Condition="'$(Platform)'=='ARM64'">true</ExcludedFromBuild> - <Command>ml64 /nologo /c /Zi /Fo "$(IntDir)vcdiv64.obj" "%(FullPath)"</Command> - <Outputs>$(IntDir)vcdiv64.obj;%(Outputs)</Outputs> - </CustomBuild> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\python_nt.rc" /> - </ItemGroup> - <ItemGroup> - <ProjectReference Include="pythoncore.vcxproj"> - <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> - </ProjectReference> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> -</Project> +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|ARM"> + <Configuration>Debug</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|ARM64"> + <Configuration>Debug</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM64"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|Win32"> + <Configuration>PGInstrument</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|x64"> + <Configuration>PGInstrument</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM64"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|Win32"> + <Configuration>PGUpdate</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|x64"> + <Configuration>PGUpdate</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM"> + <Configuration>Release</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM64"> + <Configuration>Release</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{0E9791DB-593A-465F-98BC-681011311617}</ProjectGuid> + <RootNamespace>_decimal</RootNamespace> + <Keyword>Win32Proj</Keyword> + </PropertyGroup> + <Import Project="python.props" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <CharacterSet>NotSet</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <PropertyGroup> + <TargetExt>.pyd</TargetExt> + </PropertyGroup> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="pyproject.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion> + </PropertyGroup> + <ItemDefinitionGroup> + <ClCompile> + <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions Condition="'$(Platform)' == 'Win32'">CONFIG_32;PPRO;MASM;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions Condition="'$(Platform)'=='ARM'">CONFIG_32;ANSI;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions Condition="'$(Platform)'=='ARM64'">CONFIG_64;ANSI;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions Condition="'$(Platform)' == 'x64'">CONFIG_64;MASM;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>..\Modules\_decimal;..\Modules\_decimal\libmpdec;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </ClCompile> + </ItemDefinitionGroup> + <ItemGroup> + <ClInclude Include="..\Modules\_decimal\libmpdec\basearith.h" /> + <ClInclude Include="..\Modules\_decimal\libmpdec\bits.h" /> + <ClInclude Include="..\Modules\_decimal\libmpdec\constants.h" /> + <ClInclude Include="..\Modules\_decimal\libmpdec\convolute.h" /> + <ClInclude Include="..\Modules\_decimal\libmpdec\crt.h" /> + <ClInclude Include="..\Modules\_decimal\libmpdec\difradix2.h" /> + <ClInclude Include="..\Modules\_decimal\docstrings.h" /> + <ClInclude Include="..\Modules\_decimal\libmpdec\fnt.h" /> + <ClInclude Include="..\Modules\_decimal\libmpdec\fourstep.h" /> + <ClInclude Include="..\Modules\_decimal\libmpdec\mpdecimal.h" /> + <ClInclude Include="..\Modules\_decimal\libmpdec\numbertheory.h" /> + <ClInclude Include="..\Modules\_decimal\libmpdec\sixstep.h" /> + <ClInclude Include="..\Modules\_decimal\libmpdec\transpose.h" /> + <ClInclude Include="..\Modules\_decimal\libmpdec\typearith.h" /> + <ClInclude Include="..\Modules\_decimal\libmpdec\umodarith.h" /> + <ClInclude Include="..\Modules\_decimal\libmpdec\vccompat.h" /> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\Modules\_decimal\_decimal.c" /> + <ClCompile Include="..\Modules\_decimal\libmpdec\basearith.c" /> + <ClCompile Include="..\Modules\_decimal\libmpdec\constants.c" /> + <ClCompile Include="..\Modules\_decimal\libmpdec\context.c" /> + <ClCompile Include="..\Modules\_decimal\libmpdec\convolute.c" /> + <ClCompile Include="..\Modules\_decimal\libmpdec\crt.c" /> + <ClCompile Include="..\Modules\_decimal\libmpdec\difradix2.c" /> + <ClCompile Include="..\Modules\_decimal\libmpdec\fnt.c" /> + <ClCompile Include="..\Modules\_decimal\libmpdec\fourstep.c" /> + <ClCompile Include="..\Modules\_decimal\libmpdec\io.c" /> + <ClCompile Include="..\Modules\_decimal\libmpdec\mpalloc.c" /> + <ClCompile Include="..\Modules\_decimal\libmpdec\mpdecimal.c" /> + <ClCompile Include="..\Modules\_decimal\libmpdec\numbertheory.c" /> + <ClCompile Include="..\Modules\_decimal\libmpdec\sixstep.c" /> + <ClCompile Include="..\Modules\_decimal\libmpdec\transpose.c" /> + </ItemGroup> + <ItemGroup> + <CustomBuild Include="..\Modules\_decimal\libmpdec\vcdiv64.asm"> + <ExcludedFromBuild Condition="'$(Platform)'=='Win32'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Platform)'=='ARM'">true</ExcludedFromBuild> + <ExcludedFromBuild Condition="'$(Platform)'=='ARM64'">true</ExcludedFromBuild> + <Command>ml64 /nologo /c /Zi /Fo "$(IntDir)vcdiv64.obj" "%(FullPath)"</Command> + <Outputs>$(IntDir)vcdiv64.obj;%(Outputs)</Outputs> + </CustomBuild> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_nt.rc" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="pythoncore.vcxproj"> + <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> diff --git a/PCbuild/_decimal.vcxproj.filters b/PCbuild/_decimal.vcxproj.filters index eba4ec95..0cbd3d07 100644 --- a/PCbuild/_decimal.vcxproj.filters +++ b/PCbuild/_decimal.vcxproj.filters @@ -1,127 +1,127 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <Filter Include="Header Files"> - <UniqueIdentifier>{f35a78a6-3ef0-4e36-bd8b-afaef22fbb7c}</UniqueIdentifier> - </Filter> - <Filter Include="Source Files"> - <UniqueIdentifier>{138089f8-faba-494f-b6ed-051f31fbaf2d}</UniqueIdentifier> - </Filter> - <Filter Include="Resource Files"> - <UniqueIdentifier>{632b24a3-0844-4e57-ad34-b0e4cef886dd}</UniqueIdentifier> - </Filter> - <Filter Include="Source Files\libmpdec"> - <UniqueIdentifier>{322d127c-1105-4a31-aed2-e29cdececc77}</UniqueIdentifier> - </Filter> - <Filter Include="Header Files\libmpdec"> - <UniqueIdentifier>{780c3b7a-7817-4e89-a2f2-fc522f2c5966}</UniqueIdentifier> - </Filter> - </ItemGroup> - <ItemGroup> - <ClInclude Include="..\Modules\_decimal\docstrings.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\Modules\_decimal\libmpdec\basearith.h"> - <Filter>Header Files\libmpdec</Filter> - </ClInclude> - <ClInclude Include="..\Modules\_decimal\libmpdec\bits.h"> - <Filter>Header Files\libmpdec</Filter> - </ClInclude> - <ClInclude Include="..\Modules\_decimal\libmpdec\constants.h"> - <Filter>Header Files\libmpdec</Filter> - </ClInclude> - <ClInclude Include="..\Modules\_decimal\libmpdec\convolute.h"> - <Filter>Header Files\libmpdec</Filter> - </ClInclude> - <ClInclude Include="..\Modules\_decimal\libmpdec\crt.h"> - <Filter>Header Files\libmpdec</Filter> - </ClInclude> - <ClInclude Include="..\Modules\_decimal\libmpdec\difradix2.h"> - <Filter>Header Files\libmpdec</Filter> - </ClInclude> - <ClInclude Include="..\Modules\_decimal\libmpdec\fnt.h"> - <Filter>Header Files\libmpdec</Filter> - </ClInclude> - <ClInclude Include="..\Modules\_decimal\libmpdec\fourstep.h"> - <Filter>Header Files\libmpdec</Filter> - </ClInclude> - <ClInclude Include="..\Modules\_decimal\libmpdec\mpdecimal.h"> - <Filter>Header Files\libmpdec</Filter> - </ClInclude> - <ClInclude Include="..\Modules\_decimal\libmpdec\numbertheory.h"> - <Filter>Header Files\libmpdec</Filter> - </ClInclude> - <ClInclude Include="..\Modules\_decimal\libmpdec\sixstep.h"> - <Filter>Header Files\libmpdec</Filter> - </ClInclude> - <ClInclude Include="..\Modules\_decimal\libmpdec\transpose.h"> - <Filter>Header Files\libmpdec</Filter> - </ClInclude> - <ClInclude Include="..\Modules\_decimal\libmpdec\typearith.h"> - <Filter>Header Files\libmpdec</Filter> - </ClInclude> - <ClInclude Include="..\Modules\_decimal\libmpdec\umodarith.h"> - <Filter>Header Files\libmpdec</Filter> - </ClInclude> - <ClInclude Include="..\Modules\_decimal\libmpdec\vccompat.h"> - <Filter>Header Files\libmpdec</Filter> - </ClInclude> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\Modules\_decimal\_decimal.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_decimal\libmpdec\basearith.c"> - <Filter>Source Files\libmpdec</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_decimal\libmpdec\constants.c"> - <Filter>Source Files\libmpdec</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_decimal\libmpdec\context.c"> - <Filter>Source Files\libmpdec</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_decimal\libmpdec\convolute.c"> - <Filter>Source Files\libmpdec</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_decimal\libmpdec\crt.c"> - <Filter>Source Files\libmpdec</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_decimal\libmpdec\difradix2.c"> - <Filter>Source Files\libmpdec</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_decimal\libmpdec\fnt.c"> - <Filter>Source Files\libmpdec</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_decimal\libmpdec\fourstep.c"> - <Filter>Source Files\libmpdec</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_decimal\libmpdec\io.c"> - <Filter>Source Files\libmpdec</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_decimal\libmpdec\mpalloc.c"> - <Filter>Source Files\libmpdec</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_decimal\libmpdec\mpdecimal.c"> - <Filter>Source Files\libmpdec</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_decimal\libmpdec\numbertheory.c"> - <Filter>Source Files\libmpdec</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_decimal\libmpdec\sixstep.c"> - <Filter>Source Files\libmpdec</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_decimal\libmpdec\transpose.c"> - <Filter>Source Files\libmpdec</Filter> - </ClCompile> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\python_nt.rc"> - <Filter>Resource Files</Filter> - </ResourceCompile> - </ItemGroup> - <ItemGroup> - <CustomBuild Include="..\Modules\_decimal\libmpdec\vcdiv64.asm"> - <Filter>Source Files\libmpdec</Filter> - </CustomBuild> - </ItemGroup> +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Header Files"> + <UniqueIdentifier>{f35a78a6-3ef0-4e36-bd8b-afaef22fbb7c}</UniqueIdentifier> + </Filter> + <Filter Include="Source Files"> + <UniqueIdentifier>{138089f8-faba-494f-b6ed-051f31fbaf2d}</UniqueIdentifier> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{632b24a3-0844-4e57-ad34-b0e4cef886dd}</UniqueIdentifier> + </Filter> + <Filter Include="Source Files\libmpdec"> + <UniqueIdentifier>{322d127c-1105-4a31-aed2-e29cdececc77}</UniqueIdentifier> + </Filter> + <Filter Include="Header Files\libmpdec"> + <UniqueIdentifier>{780c3b7a-7817-4e89-a2f2-fc522f2c5966}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\Modules\_decimal\docstrings.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\Modules\_decimal\libmpdec\basearith.h"> + <Filter>Header Files\libmpdec</Filter> + </ClInclude> + <ClInclude Include="..\Modules\_decimal\libmpdec\bits.h"> + <Filter>Header Files\libmpdec</Filter> + </ClInclude> + <ClInclude Include="..\Modules\_decimal\libmpdec\constants.h"> + <Filter>Header Files\libmpdec</Filter> + </ClInclude> + <ClInclude Include="..\Modules\_decimal\libmpdec\convolute.h"> + <Filter>Header Files\libmpdec</Filter> + </ClInclude> + <ClInclude Include="..\Modules\_decimal\libmpdec\crt.h"> + <Filter>Header Files\libmpdec</Filter> + </ClInclude> + <ClInclude Include="..\Modules\_decimal\libmpdec\difradix2.h"> + <Filter>Header Files\libmpdec</Filter> + </ClInclude> + <ClInclude Include="..\Modules\_decimal\libmpdec\fnt.h"> + <Filter>Header Files\libmpdec</Filter> + </ClInclude> + <ClInclude Include="..\Modules\_decimal\libmpdec\fourstep.h"> + <Filter>Header Files\libmpdec</Filter> + </ClInclude> + <ClInclude Include="..\Modules\_decimal\libmpdec\mpdecimal.h"> + <Filter>Header Files\libmpdec</Filter> + </ClInclude> + <ClInclude Include="..\Modules\_decimal\libmpdec\numbertheory.h"> + <Filter>Header Files\libmpdec</Filter> + </ClInclude> + <ClInclude Include="..\Modules\_decimal\libmpdec\sixstep.h"> + <Filter>Header Files\libmpdec</Filter> + </ClInclude> + <ClInclude Include="..\Modules\_decimal\libmpdec\transpose.h"> + <Filter>Header Files\libmpdec</Filter> + </ClInclude> + <ClInclude Include="..\Modules\_decimal\libmpdec\typearith.h"> + <Filter>Header Files\libmpdec</Filter> + </ClInclude> + <ClInclude Include="..\Modules\_decimal\libmpdec\umodarith.h"> + <Filter>Header Files\libmpdec</Filter> + </ClInclude> + <ClInclude Include="..\Modules\_decimal\libmpdec\vccompat.h"> + <Filter>Header Files\libmpdec</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\Modules\_decimal\_decimal.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_decimal\libmpdec\basearith.c"> + <Filter>Source Files\libmpdec</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_decimal\libmpdec\constants.c"> + <Filter>Source Files\libmpdec</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_decimal\libmpdec\context.c"> + <Filter>Source Files\libmpdec</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_decimal\libmpdec\convolute.c"> + <Filter>Source Files\libmpdec</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_decimal\libmpdec\crt.c"> + <Filter>Source Files\libmpdec</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_decimal\libmpdec\difradix2.c"> + <Filter>Source Files\libmpdec</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_decimal\libmpdec\fnt.c"> + <Filter>Source Files\libmpdec</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_decimal\libmpdec\fourstep.c"> + <Filter>Source Files\libmpdec</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_decimal\libmpdec\io.c"> + <Filter>Source Files\libmpdec</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_decimal\libmpdec\mpalloc.c"> + <Filter>Source Files\libmpdec</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_decimal\libmpdec\mpdecimal.c"> + <Filter>Source Files\libmpdec</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_decimal\libmpdec\numbertheory.c"> + <Filter>Source Files\libmpdec</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_decimal\libmpdec\sixstep.c"> + <Filter>Source Files\libmpdec</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_decimal\libmpdec\transpose.c"> + <Filter>Source Files\libmpdec</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_nt.rc"> + <Filter>Resource Files</Filter> + </ResourceCompile> + </ItemGroup> + <ItemGroup> + <CustomBuild Include="..\Modules\_decimal\libmpdec\vcdiv64.asm"> + <Filter>Source Files\libmpdec</Filter> + </CustomBuild> + </ItemGroup> </Project> \ No newline at end of file diff --git a/PCbuild/_elementtree.vcxproj b/PCbuild/_elementtree.vcxproj index 2eca3f93..8da5244b 100644 --- a/PCbuild/_elementtree.vcxproj +++ b/PCbuild/_elementtree.vcxproj @@ -1,135 +1,135 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|ARM"> - <Configuration>Debug</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|ARM64"> - <Configuration>Debug</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM64"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|Win32"> - <Configuration>PGInstrument</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|x64"> - <Configuration>PGInstrument</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM64"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|Win32"> - <Configuration>PGUpdate</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|x64"> - <Configuration>PGUpdate</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM"> - <Configuration>Release</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM64"> - <Configuration>Release</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectGuid>{17E1E049-C309-4D79-843F-AE483C264AEA}</ProjectGuid> - <RootNamespace>_elementtree</RootNamespace> - <Keyword>Win32Proj</Keyword> - </PropertyGroup> - <Import Project="python.props" /> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>NotSet</CharacterSet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <PropertyGroup> - <TargetExt>.pyd</TargetExt> - </PropertyGroup> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="pyproject.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup> - <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> - </PropertyGroup> - <ItemDefinitionGroup> - <ClCompile> - <AdditionalIncludeDirectories>..\Modules\expat;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;XML_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - </ItemDefinitionGroup> - <ItemGroup> - <ClInclude Include="..\Modules\expat\ascii.h" /> - <ClInclude Include="..\Modules\expat\asciitab.h" /> - <ClInclude Include="..\Modules\expat\expat.h" /> - <ClInclude Include="..\Modules\expat\expat_config.h" /> - <ClInclude Include="..\Modules\expat\expat_external.h" /> - <ClInclude Include="..\Modules\expat\iasciitab.h" /> - <ClInclude Include="..\Modules\expat\internal.h" /> - <ClInclude Include="..\Modules\expat\latin1tab.h" /> - <ClInclude Include="..\Modules\expat\macconfig.h" /> - <ClInclude Include="..\Modules\expat\nametab.h" /> - <ClInclude Include="..\Modules\expat\pyexpatns.h" /> - <ClInclude Include="..\Modules\expat\utf8tab.h" /> - <ClInclude Include="..\Modules\expat\winconfig.h" /> - <ClInclude Include="..\Modules\expat\xmlrole.h" /> - <ClInclude Include="..\Modules\expat\xmltok.h" /> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\Modules\_elementtree.c" /> - <ClCompile Include="..\Modules\expat\xmlparse.c" /> - <ClCompile Include="..\Modules\expat\xmlrole.c" /> - <ClCompile Include="..\Modules\expat\xmltok.c" /> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\python_nt.rc" /> - </ItemGroup> - <ItemGroup> - <ProjectReference Include="pythoncore.vcxproj"> - <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> - <ReferenceOutputAssembly>false</ReferenceOutputAssembly> - </ProjectReference> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> -</Project> +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|ARM"> + <Configuration>Debug</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|ARM64"> + <Configuration>Debug</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM64"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|Win32"> + <Configuration>PGInstrument</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|x64"> + <Configuration>PGInstrument</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM64"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|Win32"> + <Configuration>PGUpdate</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|x64"> + <Configuration>PGUpdate</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM"> + <Configuration>Release</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM64"> + <Configuration>Release</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{17E1E049-C309-4D79-843F-AE483C264AEA}</ProjectGuid> + <RootNamespace>_elementtree</RootNamespace> + <Keyword>Win32Proj</Keyword> + </PropertyGroup> + <Import Project="python.props" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <CharacterSet>NotSet</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <PropertyGroup> + <TargetExt>.pyd</TargetExt> + </PropertyGroup> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="pyproject.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> + </PropertyGroup> + <ItemDefinitionGroup> + <ClCompile> + <AdditionalIncludeDirectories>..\Modules\expat;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;XML_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + </ItemDefinitionGroup> + <ItemGroup> + <ClInclude Include="..\Modules\expat\ascii.h" /> + <ClInclude Include="..\Modules\expat\asciitab.h" /> + <ClInclude Include="..\Modules\expat\expat.h" /> + <ClInclude Include="..\Modules\expat\expat_config.h" /> + <ClInclude Include="..\Modules\expat\expat_external.h" /> + <ClInclude Include="..\Modules\expat\iasciitab.h" /> + <ClInclude Include="..\Modules\expat\internal.h" /> + <ClInclude Include="..\Modules\expat\latin1tab.h" /> + <ClInclude Include="..\Modules\expat\macconfig.h" /> + <ClInclude Include="..\Modules\expat\nametab.h" /> + <ClInclude Include="..\Modules\expat\pyexpatns.h" /> + <ClInclude Include="..\Modules\expat\utf8tab.h" /> + <ClInclude Include="..\Modules\expat\winconfig.h" /> + <ClInclude Include="..\Modules\expat\xmlrole.h" /> + <ClInclude Include="..\Modules\expat\xmltok.h" /> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\Modules\_elementtree.c" /> + <ClCompile Include="..\Modules\expat\xmlparse.c" /> + <ClCompile Include="..\Modules\expat\xmlrole.c" /> + <ClCompile Include="..\Modules\expat\xmltok.c" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_nt.rc" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="pythoncore.vcxproj"> + <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> diff --git a/PCbuild/_elementtree.vcxproj.filters b/PCbuild/_elementtree.vcxproj.filters index 8da2e80f..bc14e31f 100644 --- a/PCbuild/_elementtree.vcxproj.filters +++ b/PCbuild/_elementtree.vcxproj.filters @@ -1,86 +1,86 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <Filter Include="Header Files"> - <UniqueIdentifier>{643d8607-d024-40fe-8583-1823c96430f0}</UniqueIdentifier> - </Filter> - <Filter Include="Source Files"> - <UniqueIdentifier>{7b5335ad-059f-486f-85e4-f4757e26a9bf}</UniqueIdentifier> - </Filter> - <Filter Include="Resource Files"> - <UniqueIdentifier>{37d3ef0a-1ea6-492d-bba7-b83865198caa}</UniqueIdentifier> - </Filter> - <Filter Include="Header Files\expat"> - <UniqueIdentifier>{6099ed72-6668-4779-adb2-a2362e5da3b9}</UniqueIdentifier> - </Filter> - <Filter Include="Source Files\expat"> - <UniqueIdentifier>{f99990ba-cd06-40cc-8f28-d2d424ec13be}</UniqueIdentifier> - </Filter> - </ItemGroup> - <ItemGroup> - <ClInclude Include="..\Modules\expat\ascii.h"> - <Filter>Header Files\expat</Filter> - </ClInclude> - <ClInclude Include="..\Modules\expat\asciitab.h"> - <Filter>Header Files\expat</Filter> - </ClInclude> - <ClInclude Include="..\Modules\expat\expat.h"> - <Filter>Header Files\expat</Filter> - </ClInclude> - <ClInclude Include="..\Modules\expat\expat_config.h"> - <Filter>Header Files\expat</Filter> - </ClInclude> - <ClInclude Include="..\Modules\expat\expat_external.h"> - <Filter>Header Files\expat</Filter> - </ClInclude> - <ClInclude Include="..\Modules\expat\iasciitab.h"> - <Filter>Header Files\expat</Filter> - </ClInclude> - <ClInclude Include="..\Modules\expat\internal.h"> - <Filter>Header Files\expat</Filter> - </ClInclude> - <ClInclude Include="..\Modules\expat\latin1tab.h"> - <Filter>Header Files\expat</Filter> - </ClInclude> - <ClInclude Include="..\Modules\expat\macconfig.h"> - <Filter>Header Files\expat</Filter> - </ClInclude> - <ClInclude Include="..\Modules\expat\nametab.h"> - <Filter>Header Files\expat</Filter> - </ClInclude> - <ClInclude Include="..\Modules\expat\pyexpatns.h"> - <Filter>Header Files\expat</Filter> - </ClInclude> - <ClInclude Include="..\Modules\expat\utf8tab.h"> - <Filter>Header Files\expat</Filter> - </ClInclude> - <ClInclude Include="..\Modules\expat\winconfig.h"> - <Filter>Header Files\expat</Filter> - </ClInclude> - <ClInclude Include="..\Modules\expat\xmlrole.h"> - <Filter>Header Files\expat</Filter> - </ClInclude> - <ClInclude Include="..\Modules\expat\xmltok.h"> - <Filter>Header Files\expat</Filter> - </ClInclude> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\Modules\_elementtree.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Modules\expat\xmlparse.c"> - <Filter>Source Files\expat</Filter> - </ClCompile> - <ClCompile Include="..\Modules\expat\xmlrole.c"> - <Filter>Source Files\expat</Filter> - </ClCompile> - <ClCompile Include="..\Modules\expat\xmltok.c"> - <Filter>Source Files\expat</Filter> - </ClCompile> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\python_nt.rc"> - <Filter>Resource Files</Filter> - </ResourceCompile> - </ItemGroup> +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Header Files"> + <UniqueIdentifier>{643d8607-d024-40fe-8583-1823c96430f0}</UniqueIdentifier> + </Filter> + <Filter Include="Source Files"> + <UniqueIdentifier>{7b5335ad-059f-486f-85e4-f4757e26a9bf}</UniqueIdentifier> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{37d3ef0a-1ea6-492d-bba7-b83865198caa}</UniqueIdentifier> + </Filter> + <Filter Include="Header Files\expat"> + <UniqueIdentifier>{6099ed72-6668-4779-adb2-a2362e5da3b9}</UniqueIdentifier> + </Filter> + <Filter Include="Source Files\expat"> + <UniqueIdentifier>{f99990ba-cd06-40cc-8f28-d2d424ec13be}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\Modules\expat\ascii.h"> + <Filter>Header Files\expat</Filter> + </ClInclude> + <ClInclude Include="..\Modules\expat\asciitab.h"> + <Filter>Header Files\expat</Filter> + </ClInclude> + <ClInclude Include="..\Modules\expat\expat.h"> + <Filter>Header Files\expat</Filter> + </ClInclude> + <ClInclude Include="..\Modules\expat\expat_config.h"> + <Filter>Header Files\expat</Filter> + </ClInclude> + <ClInclude Include="..\Modules\expat\expat_external.h"> + <Filter>Header Files\expat</Filter> + </ClInclude> + <ClInclude Include="..\Modules\expat\iasciitab.h"> + <Filter>Header Files\expat</Filter> + </ClInclude> + <ClInclude Include="..\Modules\expat\internal.h"> + <Filter>Header Files\expat</Filter> + </ClInclude> + <ClInclude Include="..\Modules\expat\latin1tab.h"> + <Filter>Header Files\expat</Filter> + </ClInclude> + <ClInclude Include="..\Modules\expat\macconfig.h"> + <Filter>Header Files\expat</Filter> + </ClInclude> + <ClInclude Include="..\Modules\expat\nametab.h"> + <Filter>Header Files\expat</Filter> + </ClInclude> + <ClInclude Include="..\Modules\expat\pyexpatns.h"> + <Filter>Header Files\expat</Filter> + </ClInclude> + <ClInclude Include="..\Modules\expat\utf8tab.h"> + <Filter>Header Files\expat</Filter> + </ClInclude> + <ClInclude Include="..\Modules\expat\winconfig.h"> + <Filter>Header Files\expat</Filter> + </ClInclude> + <ClInclude Include="..\Modules\expat\xmlrole.h"> + <Filter>Header Files\expat</Filter> + </ClInclude> + <ClInclude Include="..\Modules\expat\xmltok.h"> + <Filter>Header Files\expat</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\Modules\_elementtree.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Modules\expat\xmlparse.c"> + <Filter>Source Files\expat</Filter> + </ClCompile> + <ClCompile Include="..\Modules\expat\xmlrole.c"> + <Filter>Source Files\expat</Filter> + </ClCompile> + <ClCompile Include="..\Modules\expat\xmltok.c"> + <Filter>Source Files\expat</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_nt.rc"> + <Filter>Resource Files</Filter> + </ResourceCompile> + </ItemGroup> </Project> \ No newline at end of file diff --git a/PCbuild/_freeze_module.vcxproj b/PCbuild/_freeze_module.vcxproj index 7d342325..3df0a072 100644 --- a/PCbuild/_freeze_module.vcxproj +++ b/PCbuild/_freeze_module.vcxproj @@ -1,433 +1,442 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|ARM"> - <Configuration>Debug</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|ARM64"> - <Configuration>Debug</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM64"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|Win32"> - <Configuration>PGInstrument</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|x64"> - <Configuration>PGInstrument</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM64"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|Win32"> - <Configuration>PGUpdate</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|x64"> - <Configuration>PGUpdate</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM"> - <Configuration>Release</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM64"> - <Configuration>Release</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectGuid>{19C0C13F-47CA-4432-AFF3-799A296A4DDC}</ProjectGuid> - <Keyword>Win32Proj</Keyword> - <RootNamespace>_freeze_module</RootNamespace> - <SupportPGO>false</SupportPGO> - </PropertyGroup> - <Import Project="python.props" /> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="pyproject.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <ItemDefinitionGroup> - <ClCompile> - <PreprocessorDefinitions>Py_NO_ENABLE_SHARED;Py_BUILD_CORE;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <Optimization>Disabled</Optimization> - <WholeProgramOptimization>false</WholeProgramOptimization> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <AdditionalDependencies>version.lib;ws2_32.lib;pathcch.lib;bcrypt.lib;%(AdditionalDependencies)</AdditionalDependencies> - <LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration> - </Link> - </ItemDefinitionGroup> - <ItemGroup> - <ClCompile Include="..\Programs\_freeze_module.c" /> - <ClCompile Include="..\PC\config_minimal.c" /> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\Modules\atexitmodule.c" /> - <ClCompile Include="..\Modules\faulthandler.c" /> - <ClCompile Include="..\Modules\gcmodule.c" /> - <ClCompile Include="..\Modules\getbuildinfo.c" /> - <ClCompile Include="..\Modules\getpath_noop.c" /> - <ClCompile Include="..\Modules\posixmodule.c" /> - <ClCompile Include="..\Modules\signalmodule.c" /> - <ClCompile Include="..\Modules\_tracemalloc.c" /> - <ClCompile Include="..\Modules\_io\_iomodule.c" /> - <ClCompile Include="..\Modules\_io\bufferedio.c" /> - <ClCompile Include="..\Modules\_io\bytesio.c" /> - <ClCompile Include="..\Modules\_io\fileio.c" /> - <ClCompile Include="..\Modules\_io\iobase.c" /> - <ClCompile Include="..\Modules\_io\stringio.c" /> - <ClCompile Include="..\Modules\_io\textio.c" /> - <ClCompile Include="..\Modules\_io\winconsoleio.c" /> - <ClCompile Include="..\Objects\abstract.c" /> - <ClCompile Include="..\Objects\accu.c" /> - <ClCompile Include="..\Objects\boolobject.c" /> - <ClCompile Include="..\Objects\bytearrayobject.c" /> - <ClCompile Include="..\Objects\bytes_methods.c" /> - <ClCompile Include="..\Objects\bytesobject.c" /> - <ClCompile Include="..\Objects\call.c" /> - <ClCompile Include="..\Objects\capsule.c" /> - <ClCompile Include="..\Objects\cellobject.c" /> - <ClCompile Include="..\Objects\classobject.c" /> - <ClCompile Include="..\Objects\codeobject.c" /> - <ClCompile Include="..\Objects\complexobject.c" /> - <ClCompile Include="..\Objects\descrobject.c" /> - <ClCompile Include="..\Objects\dictobject.c" /> - <ClCompile Include="..\Objects\enumobject.c" /> - <ClCompile Include="..\Objects\exceptions.c" /> - <ClCompile Include="..\Objects\fileobject.c" /> - <ClCompile Include="..\Objects\floatobject.c" /> - <ClCompile Include="..\Objects\frameobject.c" /> - <ClCompile Include="..\Objects\funcobject.c" /> - <ClCompile Include="..\Objects\genericaliasobject.c" /> - <ClCompile Include="..\Objects\genobject.c" /> - <ClCompile Include="..\Objects\interpreteridobject.c" /> - <ClCompile Include="..\Objects\iterobject.c" /> - <ClCompile Include="..\Objects\listobject.c" /> - <ClCompile Include="..\Objects\longobject.c" /> - <ClCompile Include="..\Objects\memoryobject.c" /> - <ClCompile Include="..\Objects\methodobject.c" /> - <ClCompile Include="..\Objects\moduleobject.c" /> - <ClCompile Include="..\Objects\namespaceobject.c" /> - <ClCompile Include="..\Objects\object.c" /> - <ClCompile Include="..\Objects\obmalloc.c" /> - <ClCompile Include="..\Objects\odictobject.c" /> - <ClCompile Include="..\Objects\picklebufobject.c" /> - <ClCompile Include="..\Objects\rangeobject.c" /> - <ClCompile Include="..\Objects\setobject.c" /> - <ClCompile Include="..\Objects\sliceobject.c" /> - <ClCompile Include="..\Objects\structseq.c" /> - <ClCompile Include="..\Objects\tupleobject.c" /> - <ClCompile Include="..\Objects\typeobject.c" /> - <ClCompile Include="..\Objects\unicodectype.c" /> - <ClCompile Include="..\Objects\unicodeobject.c" /> - <ClCompile Include="..\Objects\unionobject.c" /> - <ClCompile Include="..\Objects\weakrefobject.c" /> - <ClCompile Include="..\Parser\myreadline.c" /> - <ClCompile Include="..\Parser\parser.c" /> - <ClCompile Include="..\Parser\peg_api.c" /> - <ClCompile Include="..\Parser\pegen.c" /> - <ClCompile Include="..\Parser\pegen_errors.c" /> - <ClCompile Include="..\Parser\action_helpers.c" /> - <ClCompile Include="..\Parser\string_parser.c" /> - <ClCompile Include="..\Parser\token.c" /> - <ClCompile Include="..\Parser\tokenizer.c" /> - <ClCompile Include="..\PC\invalid_parameter_handler.c" /> - <ClCompile Include="..\PC\msvcrtmodule.c" /> - <ClCompile Include="..\PC\winreg.c" /> - <ClCompile Include="..\Python\_warnings.c" /> - <ClCompile Include="..\Python\asdl.c" /> - <ClCompile Include="..\Python\ast.c" /> - <ClCompile Include="..\Python\ast_opt.c" /> - <ClCompile Include="..\Python\ast_unparse.c" /> - <ClCompile Include="..\Python\bltinmodule.c" /> - <ClCompile Include="..\Python\bootstrap_hash.c" /> - <ClCompile Include="..\Python\ceval.c" /> - <ClCompile Include="..\Python\codecs.c" /> - <ClCompile Include="..\Python\compile.c" /> - <ClCompile Include="..\Python\context.c" /> - <ClCompile Include="..\Python\dtoa.c" /> - <ClCompile Include="..\Python\dynamic_annotations.c" /> - <ClCompile Include="..\Python\dynload_win.c" /> - <ClCompile Include="..\Python\errors.c" /> - <ClCompile Include="..\Python\fileutils.c" /> - <ClCompile Include="..\Python\formatter_unicode.c" /> - <ClCompile Include="..\Python\frame.c" /> - <ClCompile Include="..\Python\future.c" /> - <ClCompile Include="..\Python\getargs.c" /> - <ClCompile Include="..\Python\getcompiler.c" /> - <ClCompile Include="..\Python\getcopyright.c" /> - <ClCompile Include="..\Python\getopt.c" /> - <ClCompile Include="..\Python\getplatform.c" /> - <ClCompile Include="..\Python\getversion.c" /> - <ClCompile Include="..\Python\hamt.c" /> - <ClCompile Include="..\Python\hashtable.c" /> - <ClCompile Include="..\Python\import.c" /> - <ClCompile Include="..\Python\importdl.c" /> - <ClCompile Include="..\Python\initconfig.c" /> - <ClCompile Include="..\Python\marshal.c" /> - <ClCompile Include="..\Python\modsupport.c" /> - <ClCompile Include="..\Python\mysnprintf.c" /> - <ClCompile Include="..\Python\mystrtoul.c" /> - <ClCompile Include="..\Python\pathconfig.c" /> - <ClCompile Include="..\Python\preconfig.c" /> - <ClCompile Include="..\Python\pyarena.c" /> - <ClCompile Include="..\Python\pyctype.c" /> - <ClCompile Include="..\Python\pyfpe.c" /> - <ClCompile Include="..\Python\pyhash.c" /> - <ClCompile Include="..\Python\pylifecycle.c" /> - <ClCompile Include="..\Python\pymath.c" /> - <ClCompile Include="..\Python\pystate.c" /> - <ClCompile Include="..\Python\pystrcmp.c" /> - <ClCompile Include="..\Python\pystrhex.c" /> - <ClCompile Include="..\Python\pystrtod.c" /> - <ClCompile Include="..\Python\Python-ast.c" /> - <ClCompile Include="..\Python\pythonrun.c" /> - <ClCompile Include="..\Python\Python-tokenize.c" /> - <ClCompile Include="..\Python\pytime.c" /> - <ClCompile Include="..\Python\specialize.c" /> - <ClCompile Include="..\Python\structmember.c" /> - <ClCompile Include="..\Python\suggestions.c" /> - <ClCompile Include="..\Python\symtable.c" /> - <ClCompile Include="..\Python\sysmodule.c"> - <PreprocessorDefinitions>VPATH="$(PyVPath)";%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\Python\thread.c" /> - <ClCompile Include="..\Python\traceback.c" /> - </ItemGroup> - <ItemGroup> - <!-- BEGIN frozen modules --> - <None Include="..\Lib\importlib\_bootstrap.py"> - <ModName>importlib._bootstrap</ModName> - <IntFile>$(IntDir)importlib._bootstrap.g.h</IntFile> - <OutFile>$(PySourcePath)Python\frozen_modules\importlib._bootstrap.h</OutFile> - </None> - <None Include="..\Lib\importlib\_bootstrap_external.py"> - <ModName>importlib._bootstrap_external</ModName> - <IntFile>$(IntDir)importlib._bootstrap_external.g.h</IntFile> - <OutFile>$(PySourcePath)Python\frozen_modules\importlib._bootstrap_external.h</OutFile> - </None> - <None Include="..\Lib\zipimport.py"> - <ModName>zipimport</ModName> - <IntFile>$(IntDir)zipimport.g.h</IntFile> - <OutFile>$(PySourcePath)Python\frozen_modules\zipimport.h</OutFile> - </None> - <None Include="..\Lib\abc.py"> - <ModName>abc</ModName> - <IntFile>$(IntDir)abc.g.h</IntFile> - <OutFile>$(PySourcePath)Python\frozen_modules\abc.h</OutFile> - </None> - <None Include="..\Lib\codecs.py"> - <ModName>codecs</ModName> - <IntFile>$(IntDir)codecs.g.h</IntFile> - <OutFile>$(PySourcePath)Python\frozen_modules\codecs.h</OutFile> - </None> - <None Include="..\Lib\io.py"> - <ModName>io</ModName> - <IntFile>$(IntDir)io.g.h</IntFile> - <OutFile>$(PySourcePath)Python\frozen_modules\io.h</OutFile> - </None> - <None Include="..\Lib\_collections_abc.py"> - <ModName>_collections_abc</ModName> - <IntFile>$(IntDir)_collections_abc.g.h</IntFile> - <OutFile>$(PySourcePath)Python\frozen_modules\_collections_abc.h</OutFile> - </None> - <None Include="..\Lib\_sitebuiltins.py"> - <ModName>_sitebuiltins</ModName> - <IntFile>$(IntDir)_sitebuiltins.g.h</IntFile> - <OutFile>$(PySourcePath)Python\frozen_modules\_sitebuiltins.h</OutFile> - </None> - <None Include="..\Lib\genericpath.py"> - <ModName>genericpath</ModName> - <IntFile>$(IntDir)genericpath.g.h</IntFile> - <OutFile>$(PySourcePath)Python\frozen_modules\genericpath.h</OutFile> - </None> - <None Include="..\Lib\ntpath.py"> - <ModName>ntpath</ModName> - <IntFile>$(IntDir)ntpath.g.h</IntFile> - <OutFile>$(PySourcePath)Python\frozen_modules\ntpath.h</OutFile> - </None> - <None Include="..\Lib\posixpath.py"> - <ModName>posixpath</ModName> - <IntFile>$(IntDir)posixpath.g.h</IntFile> - <OutFile>$(PySourcePath)Python\frozen_modules\posixpath.h</OutFile> - </None> - <None Include="..\Lib\os.py"> - <ModName>os</ModName> - <IntFile>$(IntDir)os.g.h</IntFile> - <OutFile>$(PySourcePath)Python\frozen_modules\os.h</OutFile> - </None> - <None Include="..\Lib\site.py"> - <ModName>site</ModName> - <IntFile>$(IntDir)site.g.h</IntFile> - <OutFile>$(PySourcePath)Python\frozen_modules\site.h</OutFile> - </None> - <None Include="..\Lib\stat.py"> - <ModName>stat</ModName> - <IntFile>$(IntDir)stat.g.h</IntFile> - <OutFile>$(PySourcePath)Python\frozen_modules\stat.h</OutFile> - </None> - <None Include="..\Lib\importlib\util.py"> - <ModName>importlib.util</ModName> - <IntFile>$(IntDir)importlib.util.g.h</IntFile> - <OutFile>$(PySourcePath)Python\frozen_modules\importlib.util.h</OutFile> - </None> - <None Include="..\Lib\importlib\machinery.py"> - <ModName>importlib.machinery</ModName> - <IntFile>$(IntDir)importlib.machinery.g.h</IntFile> - <OutFile>$(PySourcePath)Python\frozen_modules\importlib.machinery.h</OutFile> - </None> - <None Include="..\Lib\runpy.py"> - <ModName>runpy</ModName> - <IntFile>$(IntDir)runpy.g.h</IntFile> - <OutFile>$(PySourcePath)Python\frozen_modules\runpy.h</OutFile> - </None> - <None Include="..\Lib\__hello__.py"> - <ModName>__hello__</ModName> - <IntFile>$(IntDir)__hello__.g.h</IntFile> - <OutFile>$(PySourcePath)Python\frozen_modules\__hello__.h</OutFile> - </None> - <None Include="..\Lib\__phello__\__init__.py"> - <ModName>__phello__</ModName> - <IntFile>$(IntDir)__phello__.g.h</IntFile> - <OutFile>$(PySourcePath)Python\frozen_modules\__phello__.h</OutFile> - </None> - <None Include="..\Lib\__phello__\ham\__init__.py"> - <ModName>__phello__.ham</ModName> - <IntFile>$(IntDir)__phello__.ham.g.h</IntFile> - <OutFile>$(PySourcePath)Python\frozen_modules\__phello__.ham.h</OutFile> - </None> - <None Include="..\Lib\__phello__\ham\eggs.py"> - <ModName>__phello__.ham.eggs</ModName> - <IntFile>$(IntDir)__phello__.ham.eggs.g.h</IntFile> - <OutFile>$(PySourcePath)Python\frozen_modules\__phello__.ham.eggs.h</OutFile> - </None> - <None Include="..\Lib\__phello__\spam.py"> - <ModName>__phello__.spam</ModName> - <IntFile>$(IntDir)__phello__.spam.g.h</IntFile> - <OutFile>$(PySourcePath)Python\frozen_modules\__phello__.spam.h</OutFile> - </None> - <None Include="..\Tools\freeze\flag.py"> - <ModName>frozen_only</ModName> - <IntFile>$(IntDir)frozen_only.g.h</IntFile> - <OutFile>$(PySourcePath)Python\frozen_modules\frozen_only.h</OutFile> - </None> - <!-- END frozen modules --> - </ItemGroup> - <ItemGroup> - <!-- We manually freeze getpath.py rather than through freeze_modules --> - <GetPath Include="..\Modules\getpath.py"> - <ModName>getpath</ModName> - <IntFile>$(IntDir)getpath.g.h</IntFile> - <OutFile>$(PySourcePath)Python\frozen_modules\getpath.h</OutFile> - </GetPath> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> - <Target Name="_RebuildGetPath" AfterTargets="_RebuildFrozen" Condition="$(Configuration) != 'PGUpdate'"> - <Exec Command='"$(TargetPath)" "%(GetPath.ModName)" "%(GetPath.FullPath)" "%(GetPath.IntFile)"' /> - - <Copy SourceFiles="%(GetPath.IntFile)" - DestinationFiles="%(GetPath.OutFile)" - Condition="!Exists(%(GetPath.OutFile)) or (Exists(%(GetPath.IntFile)) and '$([System.IO.File]::ReadAllText(%(GetPath.OutFile)).Replace(` `, ` `))' != '$([System.IO.File]::ReadAllText(%(GetPath.IntFile)).Replace(` `, ` `))')"> - <Output TaskParameter="CopiedFiles" ItemName="_UpdatedGetPath" /> - </Copy> - - <Message Text="Updated files: @(_UpdatedGetPath->'%(Filename)%(Extension)',', ')" - Condition="'@(_UpdatedGetPath)' != ''" Importance="high" /> - </Target> - <Target Name="_RebuildFrozen" AfterTargets="AfterBuild" Condition="$(Configuration) != 'PGUpdate'"> - <Exec Command='"$(TargetPath)" "%(None.ModName)" "%(None.FullPath)" "%(None.IntFile)"' /> - - <Copy SourceFiles="%(None.IntFile)" - DestinationFiles="%(None.OutFile)" - Condition="!Exists(%(None.OutFile)) or (Exists(%(None.IntFile)) and '$([System.IO.File]::ReadAllText(%(None.OutFile)).Replace(` `, ` `))' != '$([System.IO.File]::ReadAllText(%(None.IntFile)).Replace(` `, ` `))')"> - <Output TaskParameter="CopiedFiles" ItemName="_Updated" /> - </Copy> - - <Message Text="Updated files: @(_Updated->'%(Filename)%(Extension)',', ')" - Condition="'@(_Updated)' != ''" Importance="high" /> - </Target> - <Target Name="_RebuildDeepFrozen" - AfterTargets="_RebuildFrozen" - DependsOnTargets="FindPythonForBuild" - Condition="$(Configuration) != 'PGUpdate'"> - <!-- BEGIN deepfreeze rule --> - <Exec Command='$(PythonForBuild) "$(PySourcePath)Tools\scripts\deepfreeze.py" ^ - "$(PySourcePath)Python\frozen_modules\importlib._bootstrap.h:importlib._bootstrap" ^ - "$(PySourcePath)Python\frozen_modules\importlib._bootstrap_external.h:importlib._bootstrap_external" ^ - "$(PySourcePath)Python\frozen_modules\zipimport.h:zipimport" ^ - "$(PySourcePath)Python\frozen_modules\abc.h:abc" ^ - "$(PySourcePath)Python\frozen_modules\codecs.h:codecs" ^ - "$(PySourcePath)Python\frozen_modules\io.h:io" ^ - "$(PySourcePath)Python\frozen_modules\_collections_abc.h:_collections_abc" ^ - "$(PySourcePath)Python\frozen_modules\_sitebuiltins.h:_sitebuiltins" ^ - "$(PySourcePath)Python\frozen_modules\genericpath.h:genericpath" ^ - "$(PySourcePath)Python\frozen_modules\ntpath.h:ntpath" ^ - "$(PySourcePath)Python\frozen_modules\posixpath.h:posixpath" ^ - "$(PySourcePath)Python\frozen_modules\os.h:os" ^ - "$(PySourcePath)Python\frozen_modules\site.h:site" ^ - "$(PySourcePath)Python\frozen_modules\stat.h:stat" ^ - "$(PySourcePath)Python\frozen_modules\importlib.util.h:importlib.util" ^ - "$(PySourcePath)Python\frozen_modules\importlib.machinery.h:importlib.machinery" ^ - "$(PySourcePath)Python\frozen_modules\runpy.h:runpy" ^ - "$(PySourcePath)Python\frozen_modules\__hello__.h:__hello__" ^ - "$(PySourcePath)Python\frozen_modules\__phello__.h:__phello__" ^ - "$(PySourcePath)Python\frozen_modules\__phello__.ham.h:__phello__.ham" ^ - "$(PySourcePath)Python\frozen_modules\__phello__.ham.eggs.h:__phello__.ham.eggs" ^ - "$(PySourcePath)Python\frozen_modules\__phello__.spam.h:__phello__.spam" ^ - "$(PySourcePath)Python\frozen_modules\frozen_only.h:frozen_only" ^ - "-o" "$(PySourcePath)Python\deepfreeze\deepfreeze.c"'/> - <!-- END deepfreeze rule --> - </Target> - <Target Name="_CleanFrozen" BeforeTargets="CoreClean" Condition="$(Configuration) != 'PGUpdate'"> - <ItemGroup> - <Clean Include="%(None.IntFile)" /> - <Clean Include="%(None.OutFile)" /> - <Clean Include="%(GetPath.IntFile)" /> - <Clean Include="%(GetPath.OutFile)" /> - <Clean Include="$(PySourcePath)Python\deepfreeze\deepfreeze.c" /> - </ItemGroup> - </Target> -</Project> +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|ARM"> + <Configuration>Debug</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|ARM64"> + <Configuration>Debug</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM64"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|Win32"> + <Configuration>PGInstrument</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|x64"> + <Configuration>PGInstrument</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM64"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|Win32"> + <Configuration>PGUpdate</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|x64"> + <Configuration>PGUpdate</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM"> + <Configuration>Release</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM64"> + <Configuration>Release</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{19C0C13F-47CA-4432-AFF3-799A296A4DDC}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>_freeze_module</RootNamespace> + <SupportPGO>false</SupportPGO> + </PropertyGroup> + <Import Project="python.props" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="pyproject.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <ItemDefinitionGroup> + <ClCompile> + <PreprocessorDefinitions>Py_NO_ENABLE_SHARED;Py_BUILD_CORE;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <Optimization>Disabled</Optimization> + <WholeProgramOptimization>false</WholeProgramOptimization> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <AdditionalDependencies>version.lib;ws2_32.lib;pathcch.lib;bcrypt.lib;%(AdditionalDependencies)</AdditionalDependencies> + <LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\Programs\_freeze_module.c" /> + <ClCompile Include="..\PC\config_minimal.c" /> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\Modules\atexitmodule.c" /> + <ClCompile Include="..\Modules\faulthandler.c" /> + <ClCompile Include="..\Modules\gcmodule.c" /> + <ClCompile Include="..\Modules\getbuildinfo.c" /> + <ClCompile Include="..\Modules\getpath_noop.c" /> + <ClCompile Include="..\Modules\posixmodule.c" /> + <ClCompile Include="..\Modules\signalmodule.c" /> + <ClCompile Include="..\Modules\timemodule.c" /> + <ClCompile Include="..\Modules\_tracemalloc.c" /> + <ClCompile Include="..\Modules\_io\_iomodule.c" /> + <ClCompile Include="..\Modules\_io\bufferedio.c" /> + <ClCompile Include="..\Modules\_io\bytesio.c" /> + <ClCompile Include="..\Modules\_io\fileio.c" /> + <ClCompile Include="..\Modules\_io\iobase.c" /> + <ClCompile Include="..\Modules\_io\stringio.c" /> + <ClCompile Include="..\Modules\_io\textio.c" /> + <ClCompile Include="..\Modules\_io\winconsoleio.c" /> + <ClCompile Include="..\Objects\abstract.c" /> + <ClCompile Include="..\Objects\boolobject.c" /> + <ClCompile Include="..\Objects\bytearrayobject.c" /> + <ClCompile Include="..\Objects\bytes_methods.c" /> + <ClCompile Include="..\Objects\bytesobject.c" /> + <ClCompile Include="..\Objects\call.c" /> + <ClCompile Include="..\Objects\capsule.c" /> + <ClCompile Include="..\Objects\cellobject.c" /> + <ClCompile Include="..\Objects\classobject.c" /> + <ClCompile Include="..\Objects\codeobject.c" /> + <ClCompile Include="..\Objects\complexobject.c" /> + <ClCompile Include="..\Objects\descrobject.c" /> + <ClCompile Include="..\Objects\dictobject.c" /> + <ClCompile Include="..\Objects\enumobject.c" /> + <ClCompile Include="..\Objects\exceptions.c" /> + <ClCompile Include="..\Objects\fileobject.c" /> + <ClCompile Include="..\Objects\floatobject.c" /> + <ClCompile Include="..\Objects\frameobject.c" /> + <ClCompile Include="..\Objects\funcobject.c" /> + <ClCompile Include="..\Objects\genericaliasobject.c" /> + <ClCompile Include="..\Objects\genobject.c" /> + <ClCompile Include="..\Objects\interpreteridobject.c" /> + <ClCompile Include="..\Objects\iterobject.c" /> + <ClCompile Include="..\Objects\listobject.c" /> + <ClCompile Include="..\Objects\longobject.c" /> + <ClCompile Include="..\Objects\memoryobject.c" /> + <ClCompile Include="..\Objects\methodobject.c" /> + <ClCompile Include="..\Objects\moduleobject.c" /> + <ClCompile Include="..\Objects\namespaceobject.c" /> + <ClCompile Include="..\Objects\object.c" /> + <ClCompile Include="..\Objects\obmalloc.c" /> + <ClCompile Include="..\Objects\odictobject.c" /> + <ClCompile Include="..\Objects\picklebufobject.c" /> + <ClCompile Include="..\Objects\rangeobject.c" /> + <ClCompile Include="..\Objects\setobject.c" /> + <ClCompile Include="..\Objects\sliceobject.c" /> + <ClCompile Include="..\Objects\structseq.c" /> + <ClCompile Include="..\Objects\tupleobject.c" /> + <ClCompile Include="..\Objects\typeobject.c" /> + <ClCompile Include="..\Objects\typevarobject.c" /> + <ClCompile Include="..\Objects\unicodectype.c" /> + <ClCompile Include="..\Objects\unicodeobject.c" /> + <ClCompile Include="..\Objects\unionobject.c" /> + <ClCompile Include="..\Objects\weakrefobject.c" /> + <ClCompile Include="..\Parser\myreadline.c" /> + <ClCompile Include="..\Parser\parser.c" /> + <ClCompile Include="..\Parser\peg_api.c" /> + <ClCompile Include="..\Parser\pegen.c" /> + <ClCompile Include="..\Parser\pegen_errors.c" /> + <ClCompile Include="..\Parser\action_helpers.c" /> + <ClCompile Include="..\Parser\string_parser.c" /> + <ClCompile Include="..\Parser\token.c" /> + <ClCompile Include="..\Parser\tokenizer.c" /> + <ClCompile Include="..\PC\invalid_parameter_handler.c" /> + <ClCompile Include="..\PC\msvcrtmodule.c" /> + <ClCompile Include="..\PC\winreg.c" /> + <ClCompile Include="..\Python\_warnings.c" /> + <ClCompile Include="..\Python\asdl.c" /> + <ClCompile Include="..\Python\assemble.c" /> + <ClCompile Include="..\Python\ast.c" /> + <ClCompile Include="..\Python\ast_opt.c" /> + <ClCompile Include="..\Python\ast_unparse.c" /> + <ClCompile Include="..\Python\bltinmodule.c" /> + <ClCompile Include="..\Python\bootstrap_hash.c" /> + <ClCompile Include="..\Python\ceval.c" /> + <ClCompile Include="..\Python\codecs.c" /> + <ClCompile Include="..\Python\compile.c" /> + <ClCompile Include="..\Python\context.c" /> + <ClCompile Include="..\Python\dtoa.c" /> + <ClCompile Include="..\Python\dynamic_annotations.c" /> + <ClCompile Include="..\Python\dynload_win.c" /> + <ClCompile Include="..\Python\errors.c" /> + <ClCompile Include="..\Python\fileutils.c" /> + <ClCompile Include="..\Python\flowgraph.c" /> + <ClCompile Include="..\Python\formatter_unicode.c" /> + <ClCompile Include="..\Python\frame.c" /> + <ClCompile Include="..\Python\future.c" /> + <ClCompile Include="..\Python\getargs.c" /> + <ClCompile Include="..\Python\getcompiler.c" /> + <ClCompile Include="..\Python\getcopyright.c" /> + <ClCompile Include="..\Python\getopt.c" /> + <ClCompile Include="..\Python\getplatform.c" /> + <ClCompile Include="..\Python\getversion.c" /> + <ClCompile Include="..\Python\ceval_gil.c" /> + <ClCompile Include="..\Python\hamt.c" /> + <ClCompile Include="..\Python\hashtable.c" /> + <ClCompile Include="..\Python\import.c" /> + <ClCompile Include="..\Python\importdl.c" /> + <ClCompile Include="..\Python\initconfig.c" /> + <ClCompile Include="..\Python\intrinsics.c" /> + <ClCompile Include="..\Python\instrumentation.c" /> + <ClCompile Include="..\Python\legacy_tracing.c" /> + <ClCompile Include="..\Python\marshal.c" /> + <ClCompile Include="..\Python\modsupport.c" /> + <ClCompile Include="..\Python\mysnprintf.c" /> + <ClCompile Include="..\Python\mystrtoul.c" /> + <ClCompile Include="..\Python\pathconfig.c" /> + <ClCompile Include="..\Python\perf_trampoline.c" /> + <ClCompile Include="..\Python\preconfig.c" /> + <ClCompile Include="..\Python\pyarena.c" /> + <ClCompile Include="..\Python\pyctype.c" /> + <ClCompile Include="..\Python\pyfpe.c" /> + <ClCompile Include="..\Python\pyhash.c" /> + <ClCompile Include="..\Python\pylifecycle.c" /> + <ClCompile Include="..\Python\pymath.c" /> + <ClCompile Include="..\Python\pystate.c" /> + <ClCompile Include="..\Python\pystrcmp.c" /> + <ClCompile Include="..\Python\pystrhex.c" /> + <ClCompile Include="..\Python\pystrtod.c" /> + <ClCompile Include="..\Python\Python-ast.c" /> + <ClCompile Include="..\Python\pythonrun.c" /> + <ClCompile Include="..\Python\Python-tokenize.c" /> + <ClCompile Include="..\Python\pytime.c" /> + <ClCompile Include="..\Python\specialize.c" /> + <ClCompile Include="..\Python\structmember.c" /> + <ClCompile Include="..\Python\suggestions.c" /> + <ClCompile Include="..\Python\symtable.c" /> + <ClCompile Include="..\Python\sysmodule.c"> + <PreprocessorDefinitions>VPATH="$(PyVPath)";%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <ClCompile Include="..\Python\thread.c" /> + <ClCompile Include="..\Python\traceback.c" /> + <ClCompile Include="..\Python\tracemalloc.c" /> + </ItemGroup> + <ItemGroup> + <!-- BEGIN frozen modules --> + <None Include="..\Lib\importlib\_bootstrap.py"> + <ModName>importlib._bootstrap</ModName> + <IntFile>$(IntDir)importlib._bootstrap.g.h</IntFile> + <OutFile>$(PySourcePath)Python\frozen_modules\importlib._bootstrap.h</OutFile> + </None> + <None Include="..\Lib\importlib\_bootstrap_external.py"> + <ModName>importlib._bootstrap_external</ModName> + <IntFile>$(IntDir)importlib._bootstrap_external.g.h</IntFile> + <OutFile>$(PySourcePath)Python\frozen_modules\importlib._bootstrap_external.h</OutFile> + </None> + <None Include="..\Lib\zipimport.py"> + <ModName>zipimport</ModName> + <IntFile>$(IntDir)zipimport.g.h</IntFile> + <OutFile>$(PySourcePath)Python\frozen_modules\zipimport.h</OutFile> + </None> + <None Include="..\Lib\abc.py"> + <ModName>abc</ModName> + <IntFile>$(IntDir)abc.g.h</IntFile> + <OutFile>$(PySourcePath)Python\frozen_modules\abc.h</OutFile> + </None> + <None Include="..\Lib\codecs.py"> + <ModName>codecs</ModName> + <IntFile>$(IntDir)codecs.g.h</IntFile> + <OutFile>$(PySourcePath)Python\frozen_modules\codecs.h</OutFile> + </None> + <None Include="..\Lib\io.py"> + <ModName>io</ModName> + <IntFile>$(IntDir)io.g.h</IntFile> + <OutFile>$(PySourcePath)Python\frozen_modules\io.h</OutFile> + </None> + <None Include="..\Lib\_collections_abc.py"> + <ModName>_collections_abc</ModName> + <IntFile>$(IntDir)_collections_abc.g.h</IntFile> + <OutFile>$(PySourcePath)Python\frozen_modules\_collections_abc.h</OutFile> + </None> + <None Include="..\Lib\_sitebuiltins.py"> + <ModName>_sitebuiltins</ModName> + <IntFile>$(IntDir)_sitebuiltins.g.h</IntFile> + <OutFile>$(PySourcePath)Python\frozen_modules\_sitebuiltins.h</OutFile> + </None> + <None Include="..\Lib\genericpath.py"> + <ModName>genericpath</ModName> + <IntFile>$(IntDir)genericpath.g.h</IntFile> + <OutFile>$(PySourcePath)Python\frozen_modules\genericpath.h</OutFile> + </None> + <None Include="..\Lib\ntpath.py"> + <ModName>ntpath</ModName> + <IntFile>$(IntDir)ntpath.g.h</IntFile> + <OutFile>$(PySourcePath)Python\frozen_modules\ntpath.h</OutFile> + </None> + <None Include="..\Lib\posixpath.py"> + <ModName>posixpath</ModName> + <IntFile>$(IntDir)posixpath.g.h</IntFile> + <OutFile>$(PySourcePath)Python\frozen_modules\posixpath.h</OutFile> + </None> + <None Include="..\Lib\os.py"> + <ModName>os</ModName> + <IntFile>$(IntDir)os.g.h</IntFile> + <OutFile>$(PySourcePath)Python\frozen_modules\os.h</OutFile> + </None> + <None Include="..\Lib\site.py"> + <ModName>site</ModName> + <IntFile>$(IntDir)site.g.h</IntFile> + <OutFile>$(PySourcePath)Python\frozen_modules\site.h</OutFile> + </None> + <None Include="..\Lib\stat.py"> + <ModName>stat</ModName> + <IntFile>$(IntDir)stat.g.h</IntFile> + <OutFile>$(PySourcePath)Python\frozen_modules\stat.h</OutFile> + </None> + <None Include="..\Lib\importlib\util.py"> + <ModName>importlib.util</ModName> + <IntFile>$(IntDir)importlib.util.g.h</IntFile> + <OutFile>$(PySourcePath)Python\frozen_modules\importlib.util.h</OutFile> + </None> + <None Include="..\Lib\importlib\machinery.py"> + <ModName>importlib.machinery</ModName> + <IntFile>$(IntDir)importlib.machinery.g.h</IntFile> + <OutFile>$(PySourcePath)Python\frozen_modules\importlib.machinery.h</OutFile> + </None> + <None Include="..\Lib\runpy.py"> + <ModName>runpy</ModName> + <IntFile>$(IntDir)runpy.g.h</IntFile> + <OutFile>$(PySourcePath)Python\frozen_modules\runpy.h</OutFile> + </None> + <None Include="..\Lib\__hello__.py"> + <ModName>__hello__</ModName> + <IntFile>$(IntDir)__hello__.g.h</IntFile> + <OutFile>$(PySourcePath)Python\frozen_modules\__hello__.h</OutFile> + </None> + <None Include="..\Lib\__phello__\__init__.py"> + <ModName>__phello__</ModName> + <IntFile>$(IntDir)__phello__.g.h</IntFile> + <OutFile>$(PySourcePath)Python\frozen_modules\__phello__.h</OutFile> + </None> + <None Include="..\Lib\__phello__\ham\__init__.py"> + <ModName>__phello__.ham</ModName> + <IntFile>$(IntDir)__phello__.ham.g.h</IntFile> + <OutFile>$(PySourcePath)Python\frozen_modules\__phello__.ham.h</OutFile> + </None> + <None Include="..\Lib\__phello__\ham\eggs.py"> + <ModName>__phello__.ham.eggs</ModName> + <IntFile>$(IntDir)__phello__.ham.eggs.g.h</IntFile> + <OutFile>$(PySourcePath)Python\frozen_modules\__phello__.ham.eggs.h</OutFile> + </None> + <None Include="..\Lib\__phello__\spam.py"> + <ModName>__phello__.spam</ModName> + <IntFile>$(IntDir)__phello__.spam.g.h</IntFile> + <OutFile>$(PySourcePath)Python\frozen_modules\__phello__.spam.h</OutFile> + </None> + <None Include="..\Tools\freeze\flag.py"> + <ModName>frozen_only</ModName> + <IntFile>$(IntDir)frozen_only.g.h</IntFile> + <OutFile>$(PySourcePath)Python\frozen_modules\frozen_only.h</OutFile> + </None> + <!-- END frozen modules --> + </ItemGroup> + <ItemGroup> + <!-- We manually freeze getpath.py rather than through freeze_modules --> + <GetPath Include="..\Modules\getpath.py"> + <ModName>getpath</ModName> + <IntFile>$(IntDir)getpath.g.h</IntFile> + <OutFile>$(PySourcePath)Python\frozen_modules\getpath.h</OutFile> + </GetPath> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> + <Target Name="_RebuildGetPath" AfterTargets="_RebuildFrozen" Condition="$(Configuration) != 'PGUpdate'"> + <Exec Command='"$(TargetPath)" "%(GetPath.ModName)" "%(GetPath.FullPath)" "%(GetPath.IntFile)"' /> + + <Copy SourceFiles="%(GetPath.IntFile)" + DestinationFiles="%(GetPath.OutFile)" + Condition="!Exists(%(GetPath.OutFile)) or (Exists(%(GetPath.IntFile)) and '$([System.IO.File]::ReadAllText(%(GetPath.OutFile)).Replace(` `, ` `))' != '$([System.IO.File]::ReadAllText(%(GetPath.IntFile)).Replace(` `, ` `))')"> + <Output TaskParameter="CopiedFiles" ItemName="_UpdatedGetPath" /> + </Copy> + + <Message Text="Updated files: @(_UpdatedGetPath->'%(Filename)%(Extension)',', ')" + Condition="'@(_UpdatedGetPath)' != ''" Importance="high" /> + </Target> + <Target Name="_RebuildFrozen" AfterTargets="AfterBuild" Condition="$(Configuration) != 'PGUpdate'"> + <Exec Command='"$(TargetPath)" "%(None.ModName)" "%(None.FullPath)" "%(None.IntFile)"' /> + + <Copy SourceFiles="%(None.IntFile)" + DestinationFiles="%(None.OutFile)" + Condition="!Exists(%(None.OutFile)) or (Exists(%(None.IntFile)) and '$([System.IO.File]::ReadAllText(%(None.OutFile)).Replace(` `, ` `))' != '$([System.IO.File]::ReadAllText(%(None.IntFile)).Replace(` `, ` `))')"> + <Output TaskParameter="CopiedFiles" ItemName="_Updated" /> + </Copy> + + <Message Text="Updated files: @(_Updated->'%(Filename)%(Extension)',', ')" + Condition="'@(_Updated)' != ''" Importance="high" /> + </Target> + <Target Name="_RebuildDeepFrozen" + AfterTargets="_RebuildFrozen" + DependsOnTargets="FindPythonForBuild" + Condition="$(Configuration) != 'PGUpdate'"> + <!-- BEGIN deepfreeze rule --> + <Exec Command='$(PythonForBuild) "$(PySourcePath)Tools\build\deepfreeze.py" ^ + "$(PySourcePath)Python\frozen_modules\importlib._bootstrap.h:importlib._bootstrap" ^ + "$(PySourcePath)Python\frozen_modules\importlib._bootstrap_external.h:importlib._bootstrap_external" ^ + "$(PySourcePath)Python\frozen_modules\zipimport.h:zipimport" ^ + "$(PySourcePath)Python\frozen_modules\abc.h:abc" ^ + "$(PySourcePath)Python\frozen_modules\codecs.h:codecs" ^ + "$(PySourcePath)Python\frozen_modules\io.h:io" ^ + "$(PySourcePath)Python\frozen_modules\_collections_abc.h:_collections_abc" ^ + "$(PySourcePath)Python\frozen_modules\_sitebuiltins.h:_sitebuiltins" ^ + "$(PySourcePath)Python\frozen_modules\genericpath.h:genericpath" ^ + "$(PySourcePath)Python\frozen_modules\ntpath.h:ntpath" ^ + "$(PySourcePath)Python\frozen_modules\posixpath.h:posixpath" ^ + "$(PySourcePath)Python\frozen_modules\os.h:os" ^ + "$(PySourcePath)Python\frozen_modules\site.h:site" ^ + "$(PySourcePath)Python\frozen_modules\stat.h:stat" ^ + "$(PySourcePath)Python\frozen_modules\importlib.util.h:importlib.util" ^ + "$(PySourcePath)Python\frozen_modules\importlib.machinery.h:importlib.machinery" ^ + "$(PySourcePath)Python\frozen_modules\runpy.h:runpy" ^ + "$(PySourcePath)Python\frozen_modules\__hello__.h:__hello__" ^ + "$(PySourcePath)Python\frozen_modules\__phello__.h:__phello__" ^ + "$(PySourcePath)Python\frozen_modules\__phello__.ham.h:__phello__.ham" ^ + "$(PySourcePath)Python\frozen_modules\__phello__.ham.eggs.h:__phello__.ham.eggs" ^ + "$(PySourcePath)Python\frozen_modules\__phello__.spam.h:__phello__.spam" ^ + "$(PySourcePath)Python\frozen_modules\frozen_only.h:frozen_only" ^ + "-o" "$(PySourcePath)Python\deepfreeze\deepfreeze.c"'/> + <!-- END deepfreeze rule --> + </Target> + <Target Name="_CleanFrozen" BeforeTargets="CoreClean" Condition="$(Configuration) != 'PGUpdate'"> + <ItemGroup> + <Clean Include="%(None.IntFile)" /> + <Clean Include="%(None.OutFile)" /> + <Clean Include="%(GetPath.IntFile)" /> + <Clean Include="%(GetPath.OutFile)" /> + <Clean Include="$(PySourcePath)Python\deepfreeze\deepfreeze.c" /> + </ItemGroup> + </Target> +</Project> diff --git a/PCbuild/_freeze_module.vcxproj.filters b/PCbuild/_freeze_module.vcxproj.filters index 13ed9b3c..d98a4c5a 100644 --- a/PCbuild/_freeze_module.vcxproj.filters +++ b/PCbuild/_freeze_module.vcxproj.filters @@ -1,479 +1,503 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <Filter Include="Source Files"> - <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> - <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> - </Filter> - <Filter Include="Python Files"> - <UniqueIdentifier>{eb238244-ace1-48fc-97a4-16ff886f8642}</UniqueIdentifier> - </Filter> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\Programs\_freeze_module.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_io\_iomodule.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_tracemalloc.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Python\_warnings.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Objects\abstract.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Objects\accu.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Python\asdl.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Python\ast.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Python\ast_opt.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Python\ast_unparse.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Modules\atexitmodule.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Python\bltinmodule.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Objects\boolobject.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Python\bootstrap_hash.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_io\bufferedio.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Objects\bytearrayobject.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Objects\bytes_methods.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_io\bytesio.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Objects\bytesobject.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Objects\call.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Objects\capsule.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Objects\cellobject.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Python\ceval.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Objects\classobject.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Python\codecs.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Objects\codeobject.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Python\compile.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Objects\complexobject.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\PC\config_minimal.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Python\context.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Objects\descrobject.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Objects\dictobject.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Python\dtoa.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Python\dynamic_annotations.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Python\dynload_win.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Objects\enumobject.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Python\errors.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Objects\exceptions.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Modules\faulthandler.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_io\fileio.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Objects\fileobject.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Python\fileutils.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Objects\floatobject.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Python\formatter_unicode.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Python\frame.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Objects\frameobject.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Objects\funcobject.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Python\future.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Modules\gcmodule.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Objects\genericaliasobject.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Objects\genobject.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Python\getargs.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Modules\getbuildinfo.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Python\getcompiler.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Python\getcopyright.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Python\getopt.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Modules\getpath_noop.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Python\getplatform.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Python\getversion.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Python\hamt.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Python\hashtable.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Python\import.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Python\importdl.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Python\initconfig.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Objects\interpreteridobject.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\PC\invalid_parameter_handler.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_io\iobase.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Objects\iterobject.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Objects\listobject.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Objects\longobject.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Python\marshal.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Objects\memoryobject.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Objects\methodobject.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Python\modsupport.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Objects\moduleobject.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\PC\msvcrtmodule.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Parser\myreadline.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Python\mysnprintf.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Python\mystrtoul.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Objects\namespaceobject.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Objects\object.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Objects\obmalloc.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Objects\odictobject.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Parser\parser.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Python\pathconfig.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Parser\peg_api.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Parser\pegen.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Objects\picklebufobject.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Modules\posixmodule.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Python\preconfig.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Python\pyarena.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Python\pyctype.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Python\pyfpe.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Python\pyhash.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Python\pylifecycle.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Python\pymath.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Python\pystate.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Python\pystrcmp.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Python\pystrhex.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Python\pystrtod.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Python\Python-ast.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Python\pythonrun.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Python\Python-tokenize.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Python\pytime.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Objects\rangeobject.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Objects\setobject.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Modules\signalmodule.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Objects\sliceobject.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Python\specialize.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Parser\string_parser.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_io\stringio.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Python\structmember.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Objects\structseq.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Python\suggestions.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Python\symtable.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Python\sysmodule.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_io\textio.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Python\thread.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Parser\token.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Parser\tokenizer.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Python\traceback.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Objects\tupleobject.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Objects\typeobject.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Objects\unicodectype.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Objects\unicodeobject.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Objects\unionobject.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Objects\weakrefobject.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_io\winconsoleio.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\PC\winreg.c"> - <Filter>Source Files</Filter> - </ClCompile> - </ItemGroup> - <ItemGroup> - <None Include="..\Modules\getpath.py"> - <Filter>Python Files</Filter> - </None> - </ItemGroup> - <ItemGroup> - <!-- BEGIN frozen modules --> - <None Include="..\Lib\importlib\_bootstrap.py"> - <Filter>Python Files</Filter> - </None> - <None Include="..\Lib\importlib\_bootstrap_external.py"> - <Filter>Python Files</Filter> - </None> - <None Include="..\Lib\zipimport.py"> - <Filter>Python Files</Filter> - </None> - <None Include="..\Lib\abc.py"> - <Filter>Python Files</Filter> - </None> - <None Include="..\Lib\codecs.py"> - <Filter>Python Files</Filter> - </None> - <None Include="..\Lib\io.py"> - <Filter>Python Files</Filter> - </None> - <None Include="..\Lib\_collections_abc.py"> - <Filter>Python Files</Filter> - </None> - <None Include="..\Lib\_sitebuiltins.py"> - <Filter>Python Files</Filter> - </None> - <None Include="..\Lib\genericpath.py"> - <Filter>Python Files</Filter> - </None> - <None Include="..\Lib\ntpath.py"> - <Filter>Python Files</Filter> - </None> - <None Include="..\Lib\posixpath.py"> - <Filter>Python Files</Filter> - </None> - <None Include="..\Lib\os.py"> - <Filter>Python Files</Filter> - </None> - <None Include="..\Lib\site.py"> - <Filter>Python Files</Filter> - </None> - <None Include="..\Lib\stat.py"> - <Filter>Python Files</Filter> - </None> - <None Include="..\Lib\importlib\util.py"> - <Filter>Python Files</Filter> - </None> - <None Include="..\Lib\importlib\machinery.py"> - <Filter>Python Files</Filter> - </None> - <None Include="..\Lib\runpy.py"> - <Filter>Python Files</Filter> - </None> - <None Include="..\Lib\__hello__.py"> - <Filter>Python Files</Filter> - </None> - <None Include="..\Lib\__phello__\__init__.py"> - <Filter>Python Files</Filter> - </None> - <None Include="..\Lib\__phello__\ham\__init__.py"> - <Filter>Python Files</Filter> - </None> - <None Include="..\Lib\__phello__\ham\eggs.py"> - <Filter>Python Files</Filter> - </None> - <None Include="..\Lib\__phello__\spam.py"> - <Filter>Python Files</Filter> - </None> - <None Include="..\Tools\freeze\flag.py"> - <Filter>Python Files</Filter> - </None> - <!-- END frozen modules --> - </ItemGroup> -</Project> \ No newline at end of file +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Python Files"> + <UniqueIdentifier>{eb238244-ace1-48fc-97a4-16ff886f8642}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\Programs\_freeze_module.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_io\_iomodule.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_tracemalloc.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Python\_warnings.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Objects\abstract.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Python\asdl.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Python\assemble.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Python\ast.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Python\ast_opt.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Python\ast_unparse.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Modules\atexitmodule.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Python\bltinmodule.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Objects\boolobject.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Python\bootstrap_hash.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_io\bufferedio.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Objects\bytearrayobject.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Objects\bytes_methods.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_io\bytesio.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Objects\bytesobject.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Objects\call.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Objects\capsule.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Objects\cellobject.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Python\ceval.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Objects\classobject.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Python\codecs.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Objects\codeobject.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Python\perf_trampoline.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Python\compile.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Objects\complexobject.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\PC\config_minimal.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Python\context.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Objects\descrobject.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Objects\dictobject.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Python\dtoa.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Python\dynamic_annotations.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Python\dynload_win.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Objects\enumobject.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Python\errors.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Objects\exceptions.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Modules\faulthandler.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_io\fileio.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Objects\fileobject.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Python\fileutils.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Objects\floatobject.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Python\flowgraph.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Python\formatter_unicode.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Python\frame.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Objects\frameobject.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Objects\funcobject.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Python\future.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Modules\gcmodule.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Objects\genericaliasobject.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Objects\genobject.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Python\getargs.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Modules\getbuildinfo.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Python\getcompiler.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Python\getcopyright.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Python\getopt.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Modules\getpath_noop.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Python\getplatform.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Python\getversion.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Python\ceval_gil.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Python\hamt.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Python\hashtable.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Python\import.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Python\importdl.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Python\initconfig.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Python\intrinsics.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Python\instrumentation.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Python\legacy_tracing.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Objects\interpreteridobject.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\PC\invalid_parameter_handler.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_io\iobase.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Objects\iterobject.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Objects\listobject.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Objects\longobject.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Python\marshal.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Objects\memoryobject.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Objects\methodobject.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Python\modsupport.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Objects\moduleobject.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\PC\msvcrtmodule.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Parser\myreadline.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Python\mysnprintf.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Python\mystrtoul.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Objects\namespaceobject.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Objects\object.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Objects\obmalloc.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Objects\odictobject.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Parser\parser.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Python\pathconfig.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Parser\peg_api.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Parser\pegen.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Objects\picklebufobject.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Modules\posixmodule.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Python\preconfig.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Python\pyarena.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Python\pyctype.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Python\pyfpe.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Python\pyhash.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Python\pylifecycle.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Python\pymath.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Python\pystate.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Python\pystrcmp.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Python\pystrhex.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Python\pystrtod.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Python\Python-ast.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Python\pythonrun.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Python\Python-tokenize.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Python\pytime.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Objects\rangeobject.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Objects\setobject.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Modules\signalmodule.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Objects\sliceobject.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Python\specialize.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Parser\string_parser.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_io\stringio.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Python\structmember.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Objects\structseq.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Python\suggestions.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Python\symtable.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Python\sysmodule.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_io\textio.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Python\thread.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Modules\timemodule.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Parser\token.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Parser\tokenizer.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Python\traceback.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Python\tracemalloc.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Objects\tupleobject.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Objects\typeobject.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Objects\unicodectype.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Objects\unicodeobject.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Objects\unionobject.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Objects\weakrefobject.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_io\winconsoleio.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\PC\winreg.c"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <None Include="..\Modules\getpath.py"> + <Filter>Python Files</Filter> + </None> + </ItemGroup> + <ItemGroup> + <!-- BEGIN frozen modules --> + <None Include="..\Lib\importlib\_bootstrap.py"> + <Filter>Python Files</Filter> + </None> + <None Include="..\Lib\importlib\_bootstrap_external.py"> + <Filter>Python Files</Filter> + </None> + <None Include="..\Lib\zipimport.py"> + <Filter>Python Files</Filter> + </None> + <None Include="..\Lib\abc.py"> + <Filter>Python Files</Filter> + </None> + <None Include="..\Lib\codecs.py"> + <Filter>Python Files</Filter> + </None> + <None Include="..\Lib\io.py"> + <Filter>Python Files</Filter> + </None> + <None Include="..\Lib\_collections_abc.py"> + <Filter>Python Files</Filter> + </None> + <None Include="..\Lib\_sitebuiltins.py"> + <Filter>Python Files</Filter> + </None> + <None Include="..\Lib\genericpath.py"> + <Filter>Python Files</Filter> + </None> + <None Include="..\Lib\ntpath.py"> + <Filter>Python Files</Filter> + </None> + <None Include="..\Lib\posixpath.py"> + <Filter>Python Files</Filter> + </None> + <None Include="..\Lib\os.py"> + <Filter>Python Files</Filter> + </None> + <None Include="..\Lib\site.py"> + <Filter>Python Files</Filter> + </None> + <None Include="..\Lib\stat.py"> + <Filter>Python Files</Filter> + </None> + <None Include="..\Lib\importlib\util.py"> + <Filter>Python Files</Filter> + </None> + <None Include="..\Lib\importlib\machinery.py"> + <Filter>Python Files</Filter> + </None> + <None Include="..\Lib\runpy.py"> + <Filter>Python Files</Filter> + </None> + <None Include="..\Lib\__hello__.py"> + <Filter>Python Files</Filter> + </None> + <None Include="..\Lib\__phello__\__init__.py"> + <Filter>Python Files</Filter> + </None> + <None Include="..\Lib\__phello__\ham\__init__.py"> + <Filter>Python Files</Filter> + </None> + <None Include="..\Lib\__phello__\ham\eggs.py"> + <Filter>Python Files</Filter> + </None> + <None Include="..\Lib\__phello__\spam.py"> + <Filter>Python Files</Filter> + </None> + <None Include="..\Tools\freeze\flag.py"> + <Filter>Python Files</Filter> + </None> + <!-- END frozen modules --> + </ItemGroup> +</Project> diff --git a/PCbuild/_hashlib.vcxproj b/PCbuild/_hashlib.vcxproj index 93255433..6dad8183 100644 --- a/PCbuild/_hashlib.vcxproj +++ b/PCbuild/_hashlib.vcxproj @@ -1,115 +1,115 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|ARM"> - <Configuration>Debug</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|ARM64"> - <Configuration>Debug</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM64"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|Win32"> - <Configuration>PGInstrument</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|x64"> - <Configuration>PGInstrument</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM64"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|Win32"> - <Configuration>PGUpdate</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|x64"> - <Configuration>PGUpdate</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM"> - <Configuration>Release</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM64"> - <Configuration>Release</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectGuid>{447F05A8-F581-4CAC-A466-5AC7936E207E}</ProjectGuid> - <RootNamespace>_hashlib</RootNamespace> - <Keyword>Win32Proj</Keyword> - </PropertyGroup> - <Import Project="python.props" /> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>NotSet</CharacterSet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <PropertyGroup> - <TargetExt>.pyd</TargetExt> - </PropertyGroup> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="pyproject.props" /> - <Import Project="openssl.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup> - <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> - </PropertyGroup> - <ItemDefinitionGroup> - <Link> - <AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies> - </Link> - </ItemDefinitionGroup> - <ItemGroup> - <ClCompile Include="..\Modules\_hashopenssl.c" /> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\python_nt.rc" /> - </ItemGroup> - <ItemGroup> - <ProjectReference Include="pythoncore.vcxproj"> - <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> - <ReferenceOutputAssembly>false</ReferenceOutputAssembly> - </ProjectReference> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> -</Project> +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|ARM"> + <Configuration>Debug</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|ARM64"> + <Configuration>Debug</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM64"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|Win32"> + <Configuration>PGInstrument</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|x64"> + <Configuration>PGInstrument</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM64"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|Win32"> + <Configuration>PGUpdate</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|x64"> + <Configuration>PGUpdate</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM"> + <Configuration>Release</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM64"> + <Configuration>Release</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{447F05A8-F581-4CAC-A466-5AC7936E207E}</ProjectGuid> + <RootNamespace>_hashlib</RootNamespace> + <Keyword>Win32Proj</Keyword> + </PropertyGroup> + <Import Project="python.props" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <CharacterSet>NotSet</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <PropertyGroup> + <TargetExt>.pyd</TargetExt> + </PropertyGroup> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="pyproject.props" /> + <Import Project="openssl.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> + </PropertyGroup> + <ItemDefinitionGroup> + <Link> + <AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\Modules\_hashopenssl.c" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_nt.rc" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="pythoncore.vcxproj"> + <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> diff --git a/PCbuild/_hashlib.vcxproj.filters b/PCbuild/_hashlib.vcxproj.filters index c88430fe..7a0700c0 100644 --- a/PCbuild/_hashlib.vcxproj.filters +++ b/PCbuild/_hashlib.vcxproj.filters @@ -1,21 +1,21 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <Filter Include="Source Files"> - <UniqueIdentifier>{cc45963d-bd25-4eb8-bdba-a5507090bca4}</UniqueIdentifier> - </Filter> - <Filter Include="Resource Files"> - <UniqueIdentifier>{67630fa4-76e4-4035-bced-043a6df1e2e0}</UniqueIdentifier> - </Filter> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\Modules\_hashopenssl.c"> - <Filter>Source Files</Filter> - </ClCompile> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\python_nt.rc"> - <Filter>Resource Files</Filter> - </ResourceCompile> - </ItemGroup> +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{cc45963d-bd25-4eb8-bdba-a5507090bca4}</UniqueIdentifier> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67630fa4-76e4-4035-bced-043a6df1e2e0}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\Modules\_hashopenssl.c"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_nt.rc"> + <Filter>Resource Files</Filter> + </ResourceCompile> + </ItemGroup> </Project> \ No newline at end of file diff --git a/PCbuild/_lzma.vcxproj b/PCbuild/_lzma.vcxproj index 7bd5b04b..fe076a6f 100644 --- a/PCbuild/_lzma.vcxproj +++ b/PCbuild/_lzma.vcxproj @@ -1,122 +1,122 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|ARM"> - <Configuration>Debug</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|ARM64"> - <Configuration>Debug</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM64"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|Win32"> - <Configuration>PGInstrument</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|x64"> - <Configuration>PGInstrument</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM64"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|Win32"> - <Configuration>PGUpdate</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|x64"> - <Configuration>PGUpdate</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM"> - <Configuration>Release</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM64"> - <Configuration>Release</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectGuid>{F9D71780-F393-11E0-BE50-0800200C9A66}</ProjectGuid> - <RootNamespace>lzma</RootNamespace> - <Keyword>Win32Proj</Keyword> - </PropertyGroup> - <Import Project="python.props" /> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>NotSet</CharacterSet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <PropertyGroup> - <TargetExt>.pyd</TargetExt> - </PropertyGroup> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="pyproject.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup> - <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> - </PropertyGroup> - <ItemDefinitionGroup> - <ClCompile> - <AdditionalIncludeDirectories>$(lzmaDir)src/liblzma/api;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>WIN32;_FILE_OFFSET_BITS=64;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;LZMA_API_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <Link> - <AdditionalDependencies>$(OutDir)liblzma$(PyDebugExt).lib;%(AdditionalDependencies)</AdditionalDependencies> - </Link> - </ItemDefinitionGroup> - <ItemGroup> - <ClCompile Include="..\Modules\_lzmamodule.c" /> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\python_nt.rc" /> - </ItemGroup> - <ItemGroup> - <ProjectReference Include="pythoncore.vcxproj"> - <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> - <ReferenceOutputAssembly>false</ReferenceOutputAssembly> - </ProjectReference> - <ProjectReference Include="liblzma.vcxproj"> - <Project>{12728250-16eC-4dc6-94d7-e21dd88947f8}</Project> - <ReferenceOutputAssembly>false</ReferenceOutputAssembly> - </ProjectReference> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> -</Project> +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|ARM"> + <Configuration>Debug</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|ARM64"> + <Configuration>Debug</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM64"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|Win32"> + <Configuration>PGInstrument</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|x64"> + <Configuration>PGInstrument</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM64"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|Win32"> + <Configuration>PGUpdate</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|x64"> + <Configuration>PGUpdate</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM"> + <Configuration>Release</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM64"> + <Configuration>Release</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{F9D71780-F393-11E0-BE50-0800200C9A66}</ProjectGuid> + <RootNamespace>lzma</RootNamespace> + <Keyword>Win32Proj</Keyword> + </PropertyGroup> + <Import Project="python.props" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <CharacterSet>NotSet</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <PropertyGroup> + <TargetExt>.pyd</TargetExt> + </PropertyGroup> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="pyproject.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> + </PropertyGroup> + <ItemDefinitionGroup> + <ClCompile> + <AdditionalIncludeDirectories>$(lzmaDir)src/liblzma/api;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;_FILE_OFFSET_BITS=64;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;LZMA_API_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <Link> + <AdditionalDependencies>$(OutDir)liblzma$(PyDebugExt).lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\Modules\_lzmamodule.c" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_nt.rc" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="pythoncore.vcxproj"> + <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + <ProjectReference Include="liblzma.vcxproj"> + <Project>{12728250-16eC-4dc6-94d7-e21dd88947f8}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> diff --git a/PCbuild/_lzma.vcxproj.filters b/PCbuild/_lzma.vcxproj.filters index b29e8708..e23e5399 100644 --- a/PCbuild/_lzma.vcxproj.filters +++ b/PCbuild/_lzma.vcxproj.filters @@ -1,21 +1,21 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <Filter Include="Source Files"> - <UniqueIdentifier>{53e68eda-39fc-4336-a658-dc5f5d598760}</UniqueIdentifier> - </Filter> - <Filter Include="Resource Files"> - <UniqueIdentifier>{9e5ecf81-2940-4dd5-af98-58e98810d030}</UniqueIdentifier> - </Filter> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\Modules\_lzmamodule.c"> - <Filter>Source Files</Filter> - </ClCompile> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\python_nt.rc"> - <Filter>Resource Files</Filter> - </ResourceCompile> - </ItemGroup> +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{53e68eda-39fc-4336-a658-dc5f5d598760}</UniqueIdentifier> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{9e5ecf81-2940-4dd5-af98-58e98810d030}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\Modules\_lzmamodule.c"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_nt.rc"> + <Filter>Resource Files</Filter> + </ResourceCompile> + </ItemGroup> </Project> \ No newline at end of file diff --git a/PCbuild/_msi.vcxproj b/PCbuild/_msi.vcxproj index 53ed6eb3..720eb293 100644 --- a/PCbuild/_msi.vcxproj +++ b/PCbuild/_msi.vcxproj @@ -1,115 +1,115 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|ARM"> - <Configuration>Debug</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|ARM64"> - <Configuration>Debug</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM64"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM4</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|Win32"> - <Configuration>PGInstrument</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|x64"> - <Configuration>PGInstrument</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM64"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|Win32"> - <Configuration>PGUpdate</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|x64"> - <Configuration>PGUpdate</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM"> - <Configuration>Release</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM64"> - <Configuration>Release</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectGuid>{31FFC478-7B4A-43E8-9954-8D03E2187E9C}</ProjectGuid> - <RootNamespace>_msi</RootNamespace> - <Keyword>Win32Proj</Keyword> - <SupportPGO>false</SupportPGO> - </PropertyGroup> - <Import Project="python.props" /> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>NotSet</CharacterSet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <PropertyGroup> - <TargetExt>.pyd</TargetExt> - </PropertyGroup> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="pyproject.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup> - <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> - </PropertyGroup> - <ItemDefinitionGroup> - <Link> - <AdditionalDependencies>cabinet.lib;msi.lib;rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies> - </Link> - </ItemDefinitionGroup> - <ItemGroup> - <ClCompile Include="..\PC\_msi.c" /> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\python_nt.rc" /> - </ItemGroup> - <ItemGroup> - <ProjectReference Include="pythoncore.vcxproj"> - <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> - <ReferenceOutputAssembly>false</ReferenceOutputAssembly> - </ProjectReference> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|ARM"> + <Configuration>Debug</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|ARM64"> + <Configuration>Debug</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM64"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM4</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|Win32"> + <Configuration>PGInstrument</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|x64"> + <Configuration>PGInstrument</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM64"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|Win32"> + <Configuration>PGUpdate</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|x64"> + <Configuration>PGUpdate</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM"> + <Configuration>Release</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM64"> + <Configuration>Release</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{31FFC478-7B4A-43E8-9954-8D03E2187E9C}</ProjectGuid> + <RootNamespace>_msi</RootNamespace> + <Keyword>Win32Proj</Keyword> + <SupportPGO>false</SupportPGO> + </PropertyGroup> + <Import Project="python.props" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <CharacterSet>NotSet</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <PropertyGroup> + <TargetExt>.pyd</TargetExt> + </PropertyGroup> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="pyproject.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> + </PropertyGroup> + <ItemDefinitionGroup> + <Link> + <AdditionalDependencies>cabinet.lib;msi.lib;rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\PC\_msi.c" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_nt.rc" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="pythoncore.vcxproj"> + <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> </Project> \ No newline at end of file diff --git a/PCbuild/_msi.vcxproj.filters b/PCbuild/_msi.vcxproj.filters index 1e36e257..a94fb18e 100644 --- a/PCbuild/_msi.vcxproj.filters +++ b/PCbuild/_msi.vcxproj.filters @@ -1,21 +1,21 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <Filter Include="Source Files"> - <UniqueIdentifier>{bdef7710-e433-4ac0-84e0-14f34454bd3e}</UniqueIdentifier> - </Filter> - <Filter Include="Resource Files"> - <UniqueIdentifier>{8513f324-7c13-4657-b463-5d686a8a5371}</UniqueIdentifier> - </Filter> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\PC\_msi.c"> - <Filter>Source Files</Filter> - </ClCompile> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\python_nt.rc"> - <Filter>Resource Files</Filter> - </ResourceCompile> - </ItemGroup> +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{bdef7710-e433-4ac0-84e0-14f34454bd3e}</UniqueIdentifier> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{8513f324-7c13-4657-b463-5d686a8a5371}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\PC\_msi.c"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_nt.rc"> + <Filter>Resource Files</Filter> + </ResourceCompile> + </ItemGroup> </Project> \ No newline at end of file diff --git a/PCbuild/_multiprocessing.vcxproj b/PCbuild/_multiprocessing.vcxproj index e65eefd7..77b6bfc8 100644 --- a/PCbuild/_multiprocessing.vcxproj +++ b/PCbuild/_multiprocessing.vcxproj @@ -1,118 +1,118 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|ARM"> - <Configuration>Debug</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|ARM64"> - <Configuration>Debug</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM64"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|Win32"> - <Configuration>PGInstrument</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|x64"> - <Configuration>PGInstrument</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM64"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|Win32"> - <Configuration>PGUpdate</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|x64"> - <Configuration>PGUpdate</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM"> - <Configuration>Release</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM64"> - <Configuration>Release</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectGuid>{9E48B300-37D1-11DD-8C41-005056C00008}</ProjectGuid> - <RootNamespace>_multiprocessing</RootNamespace> - <Keyword>Win32Proj</Keyword> - </PropertyGroup> - <Import Project="python.props" /> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>NotSet</CharacterSet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <PropertyGroup> - <TargetExt>.pyd</TargetExt> - </PropertyGroup> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="pyproject.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup> - <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> - </PropertyGroup> - <ItemDefinitionGroup> - <Link> - <AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies> - </Link> - </ItemDefinitionGroup> - <ItemGroup> - <ClInclude Include="..\Modules\_multiprocessing\multiprocessing.h" /> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\Modules\_multiprocessing\multiprocessing.c" /> - <ClCompile Include="..\Modules\_multiprocessing\semaphore.c" /> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\python_nt.rc" /> - </ItemGroup> - <ItemGroup> - <ProjectReference Include="pythoncore.vcxproj"> - <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> - <ReferenceOutputAssembly>false</ReferenceOutputAssembly> - </ProjectReference> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|ARM"> + <Configuration>Debug</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|ARM64"> + <Configuration>Debug</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM64"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|Win32"> + <Configuration>PGInstrument</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|x64"> + <Configuration>PGInstrument</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM64"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|Win32"> + <Configuration>PGUpdate</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|x64"> + <Configuration>PGUpdate</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM"> + <Configuration>Release</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM64"> + <Configuration>Release</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{9E48B300-37D1-11DD-8C41-005056C00008}</ProjectGuid> + <RootNamespace>_multiprocessing</RootNamespace> + <Keyword>Win32Proj</Keyword> + </PropertyGroup> + <Import Project="python.props" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <CharacterSet>NotSet</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <PropertyGroup> + <TargetExt>.pyd</TargetExt> + </PropertyGroup> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="pyproject.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> + </PropertyGroup> + <ItemDefinitionGroup> + <Link> + <AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClInclude Include="..\Modules\_multiprocessing\multiprocessing.h" /> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\Modules\_multiprocessing\multiprocessing.c" /> + <ClCompile Include="..\Modules\_multiprocessing\semaphore.c" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_nt.rc" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="pythoncore.vcxproj"> + <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> </Project> \ No newline at end of file diff --git a/PCbuild/_multiprocessing.vcxproj.filters b/PCbuild/_multiprocessing.vcxproj.filters index 26903429..85caddb1 100644 --- a/PCbuild/_multiprocessing.vcxproj.filters +++ b/PCbuild/_multiprocessing.vcxproj.filters @@ -1,32 +1,32 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <Filter Include="Header Files"> - <UniqueIdentifier>{623c956c-1893-43d9-a7dc-96e4fef20f93}</UniqueIdentifier> - </Filter> - <Filter Include="Source Files"> - <UniqueIdentifier>{34615a62-f999-4659-83f5-19d17a644530}</UniqueIdentifier> - </Filter> - <Filter Include="Resource Files"> - <UniqueIdentifier>{1dcf6347-2248-42e1-ab3c-1b19f4f6f647}</UniqueIdentifier> - </Filter> - </ItemGroup> - <ItemGroup> - <ClInclude Include="..\Modules\_multiprocessing\multiprocessing.h"> - <Filter>Header Files</Filter> - </ClInclude> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\Modules\_multiprocessing\multiprocessing.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_multiprocessing\semaphore.c"> - <Filter>Source Files</Filter> - </ClCompile> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\python_nt.rc"> - <Filter>Resource Files</Filter> - </ResourceCompile> - </ItemGroup> +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Header Files"> + <UniqueIdentifier>{623c956c-1893-43d9-a7dc-96e4fef20f93}</UniqueIdentifier> + </Filter> + <Filter Include="Source Files"> + <UniqueIdentifier>{34615a62-f999-4659-83f5-19d17a644530}</UniqueIdentifier> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{1dcf6347-2248-42e1-ab3c-1b19f4f6f647}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\Modules\_multiprocessing\multiprocessing.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\Modules\_multiprocessing\multiprocessing.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_multiprocessing\semaphore.c"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_nt.rc"> + <Filter>Resource Files</Filter> + </ResourceCompile> + </ItemGroup> </Project> \ No newline at end of file diff --git a/PCbuild/_overlapped.vcxproj b/PCbuild/_overlapped.vcxproj index ad52fb36..9e60d3b5 100644 --- a/PCbuild/_overlapped.vcxproj +++ b/PCbuild/_overlapped.vcxproj @@ -1,114 +1,114 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|ARM"> - <Configuration>Debug</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|ARM64"> - <Configuration>Debug</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM64"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|Win32"> - <Configuration>PGInstrument</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|x64"> - <Configuration>PGInstrument</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM64"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|Win32"> - <Configuration>PGUpdate</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|x64"> - <Configuration>PGUpdate</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM"> - <Configuration>Release</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM64"> - <Configuration>Release</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectGuid>{EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}</ProjectGuid> - <RootNamespace>_overlapped</RootNamespace> - <Keyword>Win32Proj</Keyword> - </PropertyGroup> - <Import Project="python.props" /> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>NotSet</CharacterSet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <PropertyGroup> - <TargetExt>.pyd</TargetExt> - </PropertyGroup> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="pyproject.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup> - <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> - </PropertyGroup> - <ItemDefinitionGroup> - <Link> - <AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies> - </Link> - </ItemDefinitionGroup> - <ItemGroup> - <ClCompile Include="..\Modules\overlapped.c" /> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\python_nt.rc" /> - </ItemGroup> - <ItemGroup> - <ProjectReference Include="pythoncore.vcxproj"> - <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> - <ReferenceOutputAssembly>false</ReferenceOutputAssembly> - </ProjectReference> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|ARM"> + <Configuration>Debug</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|ARM64"> + <Configuration>Debug</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM64"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|Win32"> + <Configuration>PGInstrument</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|x64"> + <Configuration>PGInstrument</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM64"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|Win32"> + <Configuration>PGUpdate</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|x64"> + <Configuration>PGUpdate</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM"> + <Configuration>Release</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM64"> + <Configuration>Release</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}</ProjectGuid> + <RootNamespace>_overlapped</RootNamespace> + <Keyword>Win32Proj</Keyword> + </PropertyGroup> + <Import Project="python.props" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <CharacterSet>NotSet</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <PropertyGroup> + <TargetExt>.pyd</TargetExt> + </PropertyGroup> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="pyproject.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> + </PropertyGroup> + <ItemDefinitionGroup> + <Link> + <AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\Modules\overlapped.c" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_nt.rc" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="pythoncore.vcxproj"> + <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> </Project> \ No newline at end of file diff --git a/PCbuild/_overlapped.vcxproj.filters b/PCbuild/_overlapped.vcxproj.filters index b39385d6..29a9b777 100644 --- a/PCbuild/_overlapped.vcxproj.filters +++ b/PCbuild/_overlapped.vcxproj.filters @@ -1,21 +1,21 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <Filter Include="Source Files"> - <UniqueIdentifier>{6f67c8db-7de7-4714-a967-2b0d4bc71f2e}</UniqueIdentifier> - </Filter> - <Filter Include="Resource Files"> - <UniqueIdentifier>{83fe502d-eca2-4505-b626-eddec9b6ea9f}</UniqueIdentifier> - </Filter> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\Modules\overlapped.c"> - <Filter>Source Files</Filter> - </ClCompile> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\python_nt.rc"> - <Filter>Resource Files</Filter> - </ResourceCompile> - </ItemGroup> +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{6f67c8db-7de7-4714-a967-2b0d4bc71f2e}</UniqueIdentifier> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{83fe502d-eca2-4505-b626-eddec9b6ea9f}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\Modules\overlapped.c"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_nt.rc"> + <Filter>Resource Files</Filter> + </ResourceCompile> + </ItemGroup> </Project> \ No newline at end of file diff --git a/PCbuild/_queue.vcxproj b/PCbuild/_queue.vcxproj index 305d63a5..8065b235 100644 --- a/PCbuild/_queue.vcxproj +++ b/PCbuild/_queue.vcxproj @@ -1,109 +1,109 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|ARM"> - <Configuration>Debug</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|ARM64"> - <Configuration>Debug</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM64"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|Win32"> - <Configuration>PGInstrument</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|x64"> - <Configuration>PGInstrument</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM64"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|Win32"> - <Configuration>PGUpdate</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|x64"> - <Configuration>PGUpdate</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM"> - <Configuration>Release</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM64"> - <Configuration>Release</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectGuid>{78D80A15-BD8C-44E2-B49E-1F05B0A0A687}</ProjectGuid> - <RootNamespace>_queue</RootNamespace> - <Keyword>Win32Proj</Keyword> - </PropertyGroup> - <Import Project="python.props" /> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>NotSet</CharacterSet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <PropertyGroup> - <TargetExt>.pyd</TargetExt> - </PropertyGroup> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="pyproject.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup> - <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> - </PropertyGroup> - <ItemGroup> - <ClCompile Include="..\Modules\_queuemodule.c" /> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\python_nt.rc" /> - </ItemGroup> - <ItemGroup> - <ProjectReference Include="pythoncore.vcxproj"> - <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> - <ReferenceOutputAssembly>false</ReferenceOutputAssembly> - </ProjectReference> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> -</Project> +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|ARM"> + <Configuration>Debug</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|ARM64"> + <Configuration>Debug</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM64"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|Win32"> + <Configuration>PGInstrument</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|x64"> + <Configuration>PGInstrument</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM64"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|Win32"> + <Configuration>PGUpdate</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|x64"> + <Configuration>PGUpdate</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM"> + <Configuration>Release</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM64"> + <Configuration>Release</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{78D80A15-BD8C-44E2-B49E-1F05B0A0A687}</ProjectGuid> + <RootNamespace>_queue</RootNamespace> + <Keyword>Win32Proj</Keyword> + </PropertyGroup> + <Import Project="python.props" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <CharacterSet>NotSet</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <PropertyGroup> + <TargetExt>.pyd</TargetExt> + </PropertyGroup> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="pyproject.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> + </PropertyGroup> + <ItemGroup> + <ClCompile Include="..\Modules\_queuemodule.c" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_nt.rc" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="pythoncore.vcxproj"> + <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> diff --git a/PCbuild/_queue.vcxproj.filters b/PCbuild/_queue.vcxproj.filters index 4ce767c8..ec48e9d3 100644 --- a/PCbuild/_queue.vcxproj.filters +++ b/PCbuild/_queue.vcxproj.filters @@ -1,21 +1,21 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <Filter Include="Source Files"> - <UniqueIdentifier>{c56a5dd3-7838-48e9-a781-855d8be7370f}</UniqueIdentifier> - </Filter> - <Filter Include="Resource Files"> - <UniqueIdentifier>{bc5dc97e-11b8-435a-82e7-2ef3c9b44f5e}</UniqueIdentifier> - </Filter> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\Modules\_queuemodule.c"> - <Filter>Source Files</Filter> - </ClCompile> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\python_nt.rc"> - <Filter>Resource Files</Filter> - </ResourceCompile> - </ItemGroup> +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{c56a5dd3-7838-48e9-a781-855d8be7370f}</UniqueIdentifier> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{bc5dc97e-11b8-435a-82e7-2ef3c9b44f5e}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\Modules\_queuemodule.c"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_nt.rc"> + <Filter>Resource Files</Filter> + </ResourceCompile> + </ItemGroup> </Project> \ No newline at end of file diff --git a/PCbuild/_socket.vcxproj b/PCbuild/_socket.vcxproj index b58e3e3b..78fa4d67 100644 --- a/PCbuild/_socket.vcxproj +++ b/PCbuild/_socket.vcxproj @@ -1,117 +1,117 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|ARM"> - <Configuration>Debug</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|ARM64"> - <Configuration>Debug</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM64"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|Win32"> - <Configuration>PGInstrument</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|x64"> - <Configuration>PGInstrument</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM64"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|Win32"> - <Configuration>PGUpdate</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|x64"> - <Configuration>PGUpdate</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM"> - <Configuration>Release</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM64"> - <Configuration>Release</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectGuid>{86937F53-C189-40EF-8CE8-8759D8E7D480}</ProjectGuid> - <RootNamespace>_socket</RootNamespace> - <Keyword>Win32Proj</Keyword> - </PropertyGroup> - <Import Project="python.props" /> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>NotSet</CharacterSet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <PropertyGroup> - <TargetExt>.pyd</TargetExt> - </PropertyGroup> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="pyproject.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup> - <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> - </PropertyGroup> - <ItemDefinitionGroup> - <Link> - <AdditionalDependencies>ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies)</AdditionalDependencies> - </Link> - </ItemDefinitionGroup> - <ItemGroup> - <ClInclude Include="..\Modules\socketmodule.h" /> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\Modules\socketmodule.c" /> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\python_nt.rc" /> - </ItemGroup> - <ItemGroup> - <ProjectReference Include="pythoncore.vcxproj"> - <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> - <ReferenceOutputAssembly>false</ReferenceOutputAssembly> - </ProjectReference> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|ARM"> + <Configuration>Debug</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|ARM64"> + <Configuration>Debug</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM64"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|Win32"> + <Configuration>PGInstrument</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|x64"> + <Configuration>PGInstrument</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM64"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|Win32"> + <Configuration>PGUpdate</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|x64"> + <Configuration>PGUpdate</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM"> + <Configuration>Release</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM64"> + <Configuration>Release</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{86937F53-C189-40EF-8CE8-8759D8E7D480}</ProjectGuid> + <RootNamespace>_socket</RootNamespace> + <Keyword>Win32Proj</Keyword> + </PropertyGroup> + <Import Project="python.props" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <CharacterSet>NotSet</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <PropertyGroup> + <TargetExt>.pyd</TargetExt> + </PropertyGroup> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="pyproject.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> + </PropertyGroup> + <ItemDefinitionGroup> + <Link> + <AdditionalDependencies>ws2_32.lib;iphlpapi.lib;Rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClInclude Include="..\Modules\socketmodule.h" /> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\Modules\socketmodule.c" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_nt.rc" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="pythoncore.vcxproj"> + <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> </Project> \ No newline at end of file diff --git a/PCbuild/_socket.vcxproj.filters b/PCbuild/_socket.vcxproj.filters index 94e094ec..453175c6 100644 --- a/PCbuild/_socket.vcxproj.filters +++ b/PCbuild/_socket.vcxproj.filters @@ -1,29 +1,29 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <Filter Include="Header Files"> - <UniqueIdentifier>{1452207f-707c-4e84-b532-307193a0fd85}</UniqueIdentifier> - </Filter> - <Filter Include="Source Files"> - <UniqueIdentifier>{1edfe0d0-7b9d-4dc8-a335-b21fef7cc77a}</UniqueIdentifier> - </Filter> - <Filter Include="Resource Files"> - <UniqueIdentifier>{f8efff18-28ed-4c6b-8e8d-fa816d9a81a8}</UniqueIdentifier> - </Filter> - </ItemGroup> - <ItemGroup> - <ClInclude Include="..\Modules\socketmodule.h"> - <Filter>Header Files</Filter> - </ClInclude> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\Modules\socketmodule.c"> - <Filter>Source Files</Filter> - </ClCompile> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\python_nt.rc"> - <Filter>Resource Files</Filter> - </ResourceCompile> - </ItemGroup> +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Header Files"> + <UniqueIdentifier>{1452207f-707c-4e84-b532-307193a0fd85}</UniqueIdentifier> + </Filter> + <Filter Include="Source Files"> + <UniqueIdentifier>{1edfe0d0-7b9d-4dc8-a335-b21fef7cc77a}</UniqueIdentifier> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{f8efff18-28ed-4c6b-8e8d-fa816d9a81a8}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\Modules\socketmodule.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\Modules\socketmodule.c"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_nt.rc"> + <Filter>Resource Files</Filter> + </ResourceCompile> + </ItemGroup> </Project> \ No newline at end of file diff --git a/PCbuild/_sqlite3.vcxproj b/PCbuild/_sqlite3.vcxproj index f2d4a4e4..57c74136 100644 --- a/PCbuild/_sqlite3.vcxproj +++ b/PCbuild/_sqlite3.vcxproj @@ -1,138 +1,138 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|ARM"> - <Configuration>Debug</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|ARM64"> - <Configuration>Debug</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM64"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|Win32"> - <Configuration>PGInstrument</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|x64"> - <Configuration>PGInstrument</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM64"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|Win32"> - <Configuration>PGUpdate</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|x64"> - <Configuration>PGUpdate</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM"> - <Configuration>Release</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM64"> - <Configuration>Release</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectGuid>{13CECB97-4119-4316-9D42-8534019A5A44}</ProjectGuid> - <RootNamespace>_sqlite3</RootNamespace> - <Keyword>Win32Proj</Keyword> - </PropertyGroup> - <Import Project="python.props" /> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>NotSet</CharacterSet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <PropertyGroup> - <TargetExt>.pyd</TargetExt> - </PropertyGroup> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="pyproject.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup> - <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> - </PropertyGroup> - <ItemDefinitionGroup> - <ClCompile> - <AdditionalIncludeDirectories>$(sqlite3Dir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>PY_SQLITE_HAVE_SERIALIZE;PY_SQLITE_ENABLE_LOAD_EXTENSION;%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - </ItemDefinitionGroup> - <ItemGroup> - <ClInclude Include="..\Modules\_sqlite\connection.h" /> - <ClInclude Include="..\Modules\_sqlite\cursor.h" /> - <ClInclude Include="..\Modules\_sqlite\microprotocols.h" /> - <ClInclude Include="..\Modules\_sqlite\module.h" /> - <ClInclude Include="..\Modules\_sqlite\prepare_protocol.h" /> - <ClInclude Include="..\Modules\_sqlite\row.h" /> - <ClInclude Include="..\Modules\_sqlite\statement.h" /> - <ClInclude Include="..\Modules\_sqlite\util.h" /> - <ClInclude Include="..\Modules\_sqlite\blob.h" /> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\Modules\_sqlite\connection.c" /> - <ClCompile Include="..\Modules\_sqlite\cursor.c" /> - <ClCompile Include="..\Modules\_sqlite\microprotocols.c" /> - <ClCompile Include="..\Modules\_sqlite\module.c" /> - <ClCompile Include="..\Modules\_sqlite\prepare_protocol.c" /> - <ClCompile Include="..\Modules\_sqlite\row.c" /> - <ClCompile Include="..\Modules\_sqlite\statement.c" /> - <ClCompile Include="..\Modules\_sqlite\util.c" /> - <ClCompile Include="..\Modules\_sqlite\blob.c" /> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\python_nt.rc" /> - </ItemGroup> - <ItemGroup> - <ProjectReference Include="pythoncore.vcxproj"> - <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> - <ReferenceOutputAssembly>false</ReferenceOutputAssembly> - </ProjectReference> - <ProjectReference Include="sqlite3.vcxproj"> - <Project>{a1a295e5-463c-437f-81ca-1f32367685da}</Project> - <ReferenceOutputAssembly>false</ReferenceOutputAssembly> - </ProjectReference> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|ARM"> + <Configuration>Debug</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|ARM64"> + <Configuration>Debug</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM64"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|Win32"> + <Configuration>PGInstrument</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|x64"> + <Configuration>PGInstrument</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM64"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|Win32"> + <Configuration>PGUpdate</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|x64"> + <Configuration>PGUpdate</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM"> + <Configuration>Release</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM64"> + <Configuration>Release</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{13CECB97-4119-4316-9D42-8534019A5A44}</ProjectGuid> + <RootNamespace>_sqlite3</RootNamespace> + <Keyword>Win32Proj</Keyword> + </PropertyGroup> + <Import Project="python.props" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <CharacterSet>NotSet</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <PropertyGroup> + <TargetExt>.pyd</TargetExt> + </PropertyGroup> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="pyproject.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> + </PropertyGroup> + <ItemDefinitionGroup> + <ClCompile> + <AdditionalIncludeDirectories>$(sqlite3Dir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>PY_SQLITE_HAVE_SERIALIZE;PY_SQLITE_ENABLE_LOAD_EXTENSION;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + </ItemDefinitionGroup> + <ItemGroup> + <ClInclude Include="..\Modules\_sqlite\connection.h" /> + <ClInclude Include="..\Modules\_sqlite\cursor.h" /> + <ClInclude Include="..\Modules\_sqlite\microprotocols.h" /> + <ClInclude Include="..\Modules\_sqlite\module.h" /> + <ClInclude Include="..\Modules\_sqlite\prepare_protocol.h" /> + <ClInclude Include="..\Modules\_sqlite\row.h" /> + <ClInclude Include="..\Modules\_sqlite\statement.h" /> + <ClInclude Include="..\Modules\_sqlite\util.h" /> + <ClInclude Include="..\Modules\_sqlite\blob.h" /> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\Modules\_sqlite\connection.c" /> + <ClCompile Include="..\Modules\_sqlite\cursor.c" /> + <ClCompile Include="..\Modules\_sqlite\microprotocols.c" /> + <ClCompile Include="..\Modules\_sqlite\module.c" /> + <ClCompile Include="..\Modules\_sqlite\prepare_protocol.c" /> + <ClCompile Include="..\Modules\_sqlite\row.c" /> + <ClCompile Include="..\Modules\_sqlite\statement.c" /> + <ClCompile Include="..\Modules\_sqlite\util.c" /> + <ClCompile Include="..\Modules\_sqlite\blob.c" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_nt.rc" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="pythoncore.vcxproj"> + <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + <ProjectReference Include="sqlite3.vcxproj"> + <Project>{a1a295e5-463c-437f-81ca-1f32367685da}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> </Project> \ No newline at end of file diff --git a/PCbuild/_sqlite3.vcxproj.filters b/PCbuild/_sqlite3.vcxproj.filters index 7883af48..f4a265eb 100644 --- a/PCbuild/_sqlite3.vcxproj.filters +++ b/PCbuild/_sqlite3.vcxproj.filters @@ -1,77 +1,77 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <Filter Include="Header Files"> - <UniqueIdentifier>{dac8ab3b-ce16-4bef-bef9-76463a01f5c4}</UniqueIdentifier> - </Filter> - <Filter Include="Source Files"> - <UniqueIdentifier>{814b187d-44ad-4f2b-baa7-18ca8a8a6a77}</UniqueIdentifier> - </Filter> - <Filter Include="Resource Files"> - <UniqueIdentifier>{225f58de-2bad-4e4d-bc0b-fe74ed6bf5f1}</UniqueIdentifier> - </Filter> - </ItemGroup> - <ItemGroup> - <ClInclude Include="..\Modules\_sqlite\connection.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\Modules\_sqlite\cursor.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\Modules\_sqlite\microprotocols.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\Modules\_sqlite\module.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\Modules\_sqlite\prepare_protocol.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\Modules\_sqlite\row.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\Modules\_sqlite\statement.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\Modules\_sqlite\util.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\Modules\_sqlite\blob.h"> - <Filter>Header Files</Filter> - </ClInclude> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\Modules\_sqlite\connection.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_sqlite\cursor.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_sqlite\microprotocols.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_sqlite\module.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_sqlite\prepare_protocol.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_sqlite\row.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_sqlite\statement.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_sqlite\util.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_sqlite\blob.c"> - <Filter>Source Files</Filter> - </ClCompile> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\python_nt.rc"> - <Filter>Resource Files</Filter> - </ResourceCompile> - </ItemGroup> +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Header Files"> + <UniqueIdentifier>{dac8ab3b-ce16-4bef-bef9-76463a01f5c4}</UniqueIdentifier> + </Filter> + <Filter Include="Source Files"> + <UniqueIdentifier>{814b187d-44ad-4f2b-baa7-18ca8a8a6a77}</UniqueIdentifier> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{225f58de-2bad-4e4d-bc0b-fe74ed6bf5f1}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\Modules\_sqlite\connection.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\Modules\_sqlite\cursor.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\Modules\_sqlite\microprotocols.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\Modules\_sqlite\module.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\Modules\_sqlite\prepare_protocol.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\Modules\_sqlite\row.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\Modules\_sqlite\statement.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\Modules\_sqlite\util.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\Modules\_sqlite\blob.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\Modules\_sqlite\connection.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_sqlite\cursor.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_sqlite\microprotocols.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_sqlite\module.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_sqlite\prepare_protocol.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_sqlite\row.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_sqlite\statement.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_sqlite\util.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_sqlite\blob.c"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_nt.rc"> + <Filter>Resource Files</Filter> + </ResourceCompile> + </ItemGroup> </Project> \ No newline at end of file diff --git a/PCbuild/_ssl.vcxproj b/PCbuild/_ssl.vcxproj index 7a514cfc..226ff506 100644 --- a/PCbuild/_ssl.vcxproj +++ b/PCbuild/_ssl.vcxproj @@ -1,122 +1,122 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|ARM"> - <Configuration>Debug</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|ARM64"> - <Configuration>Debug</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM64"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|Win32"> - <Configuration>PGInstrument</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|x64"> - <Configuration>PGInstrument</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM64"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|Win32"> - <Configuration>PGUpdate</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|x64"> - <Configuration>PGUpdate</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM"> - <Configuration>Release</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM64"> - <Configuration>Release</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectGuid>{C6E20F84-3247-4AD6-B051-B073268F73BA}</ProjectGuid> - <RootNamespace>_ssl</RootNamespace> - <Keyword>Win32Proj</Keyword> - </PropertyGroup> - <Import Project="python.props" /> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>NotSet</CharacterSet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <PropertyGroup> - <TargetExt>.pyd</TargetExt> - </PropertyGroup> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="pyproject.props" /> - <Import Project="openssl.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup> - <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> - </PropertyGroup> - <ItemDefinitionGroup> - <Link> - <AdditionalDependencies>ws2_32.lib;crypt32.lib;%(AdditionalDependencies)</AdditionalDependencies> - </Link> - </ItemDefinitionGroup> - <ItemGroup> - <ClCompile Include="..\Modules\_ssl.c" /> - <ClCompile Include="$(opensslIncludeDir)\applink.c"> - <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;$(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\python_nt.rc" /> - </ItemGroup> - <ItemGroup> - <ProjectReference Include="pythoncore.vcxproj"> - <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> - <ReferenceOutputAssembly>false</ReferenceOutputAssembly> - </ProjectReference> - <ProjectReference Include="_socket.vcxproj"> - <Project>{86937f53-c189-40ef-8ce8-8759d8e7d480}</Project> - <ReferenceOutputAssembly>false</ReferenceOutputAssembly> - </ProjectReference> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> -</Project> \ No newline at end of file +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|ARM"> + <Configuration>Debug</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|ARM64"> + <Configuration>Debug</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM64"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|Win32"> + <Configuration>PGInstrument</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|x64"> + <Configuration>PGInstrument</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM64"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|Win32"> + <Configuration>PGUpdate</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|x64"> + <Configuration>PGUpdate</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM"> + <Configuration>Release</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM64"> + <Configuration>Release</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{C6E20F84-3247-4AD6-B051-B073268F73BA}</ProjectGuid> + <RootNamespace>_ssl</RootNamespace> + <Keyword>Win32Proj</Keyword> + </PropertyGroup> + <Import Project="python.props" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <CharacterSet>NotSet</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <PropertyGroup> + <TargetExt>.pyd</TargetExt> + </PropertyGroup> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="pyproject.props" /> + <Import Project="openssl.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> + </PropertyGroup> + <ItemDefinitionGroup> + <Link> + <AdditionalDependencies>ws2_32.lib;crypt32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\Modules\_ssl.c" /> + <ClCompile Include="$(opensslIncludeDir)\applink.c"> + <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;$(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_nt.rc" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="pythoncore.vcxproj"> + <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + <ProjectReference Include="_socket.vcxproj"> + <Project>{86937f53-c189-40ef-8ce8-8759d8e7d480}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> diff --git a/PCbuild/_ssl.vcxproj.filters b/PCbuild/_ssl.vcxproj.filters index 7179034d..716a69a4 100644 --- a/PCbuild/_ssl.vcxproj.filters +++ b/PCbuild/_ssl.vcxproj.filters @@ -1,24 +1,24 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <Filter Include="Source Files"> - <UniqueIdentifier>{695348f7-e9f6-4fe1-bc03-5f08ffc8095b}</UniqueIdentifier> - </Filter> - <Filter Include="Resource Files"> - <UniqueIdentifier>{1b18a2e6-040d-46c7-a9ac-ac2ec64fb5d6}</UniqueIdentifier> - </Filter> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\Modules\_ssl.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(opensslIncludeDir)\applink.c"> - <Filter>Source Files</Filter> - </ClCompile> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\python_nt.rc"> - <Filter>Resource Files</Filter> - </ResourceCompile> - </ItemGroup> +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{695348f7-e9f6-4fe1-bc03-5f08ffc8095b}</UniqueIdentifier> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{1b18a2e6-040d-46c7-a9ac-ac2ec64fb5d6}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\Modules\_ssl.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(opensslIncludeDir)\applink.c"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_nt.rc"> + <Filter>Resource Files</Filter> + </ResourceCompile> + </ItemGroup> </Project> \ No newline at end of file diff --git a/PCbuild/_testbuffer.vcxproj b/PCbuild/_testbuffer.vcxproj index 54d7b91f..917d7ae5 100644 --- a/PCbuild/_testbuffer.vcxproj +++ b/PCbuild/_testbuffer.vcxproj @@ -1,109 +1,109 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|ARM"> - <Configuration>Debug</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|ARM64"> - <Configuration>Debug</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM64"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|Win32"> - <Configuration>PGInstrument</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|x64"> - <Configuration>PGInstrument</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM64"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|Win32"> - <Configuration>PGUpdate</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|x64"> - <Configuration>PGUpdate</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM"> - <Configuration>Release</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM64"> - <Configuration>Release</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectGuid>{A2697BD3-28C1-4AEC-9106-8B748639FD16}</ProjectGuid> - <RootNamespace>_testbuffer</RootNamespace> - <Keyword>Win32Proj</Keyword> - <SupportPGO>false</SupportPGO> - </PropertyGroup> - <Import Project="python.props" /> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>NotSet</CharacterSet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <PropertyGroup> - <TargetExt>.pyd</TargetExt> - </PropertyGroup> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="pyproject.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup> - <_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion> - </PropertyGroup> - <ItemGroup> - <ClCompile Include="..\Modules\_testbuffer.c" /> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\python_nt.rc" /> - </ItemGroup> - <ItemGroup> - <ProjectReference Include="pythoncore.vcxproj"> - <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> - </ProjectReference> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|ARM"> + <Configuration>Debug</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|ARM64"> + <Configuration>Debug</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM64"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|Win32"> + <Configuration>PGInstrument</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|x64"> + <Configuration>PGInstrument</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM64"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|Win32"> + <Configuration>PGUpdate</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|x64"> + <Configuration>PGUpdate</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM"> + <Configuration>Release</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM64"> + <Configuration>Release</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{A2697BD3-28C1-4AEC-9106-8B748639FD16}</ProjectGuid> + <RootNamespace>_testbuffer</RootNamespace> + <Keyword>Win32Proj</Keyword> + <SupportPGO>false</SupportPGO> + </PropertyGroup> + <Import Project="python.props" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <CharacterSet>NotSet</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <PropertyGroup> + <TargetExt>.pyd</TargetExt> + </PropertyGroup> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="pyproject.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion> + </PropertyGroup> + <ItemGroup> + <ClCompile Include="..\Modules\_testbuffer.c" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_nt.rc" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="pythoncore.vcxproj"> + <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> </Project> \ No newline at end of file diff --git a/PCbuild/_testbuffer.vcxproj.filters b/PCbuild/_testbuffer.vcxproj.filters index ab95c64e..bea4260b 100644 --- a/PCbuild/_testbuffer.vcxproj.filters +++ b/PCbuild/_testbuffer.vcxproj.filters @@ -1,21 +1,21 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <Filter Include="Source Files"> - <UniqueIdentifier>{8d232240-921a-4bc2-87c3-93ffd3462f0a}</UniqueIdentifier> - </Filter> - <Filter Include="Resource Files"> - <UniqueIdentifier>{1e73201a-cca4-4b45-9484-262709cafee7}</UniqueIdentifier> - </Filter> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\Modules\_testbuffer.c"> - <Filter>Source Files</Filter> - </ClCompile> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\python_nt.rc"> - <Filter>Resource Files</Filter> - </ResourceCompile> - </ItemGroup> +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{8d232240-921a-4bc2-87c3-93ffd3462f0a}</UniqueIdentifier> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{1e73201a-cca4-4b45-9484-262709cafee7}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\Modules\_testbuffer.c"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_nt.rc"> + <Filter>Resource Files</Filter> + </ResourceCompile> + </ItemGroup> </Project> \ No newline at end of file diff --git a/PCbuild/_testcapi.vcxproj b/PCbuild/_testcapi.vcxproj index f0ea4fbe..1843b58d 100644 --- a/PCbuild/_testcapi.vcxproj +++ b/PCbuild/_testcapi.vcxproj @@ -1,110 +1,136 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|ARM"> - <Configuration>Debug</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|ARM64"> - <Configuration>Debug</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM64"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|Win32"> - <Configuration>PGInstrument</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|x64"> - <Configuration>PGInstrument</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM64"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|Win32"> - <Configuration>PGUpdate</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|x64"> - <Configuration>PGUpdate</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM"> - <Configuration>Release</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM64"> - <Configuration>Release</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectGuid>{6901D91C-6E48-4BB7-9FEC-700C8131DF1D}</ProjectGuid> - <RootNamespace>_testcapi</RootNamespace> - <Keyword>Win32Proj</Keyword> - <SupportPGO>false</SupportPGO> - </PropertyGroup> - <Import Project="python.props" /> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>NotSet</CharacterSet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <PropertyGroup> - <TargetExt>.pyd</TargetExt> - </PropertyGroup> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="pyproject.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup> - <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> - </PropertyGroup> - <ItemGroup> - <ClCompile Include="..\Modules\_testcapimodule.c" /> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\python_nt.rc" /> - </ItemGroup> - <ItemGroup> - <ProjectReference Include="pythoncore.vcxproj"> - <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> - <ReferenceOutputAssembly>false</ReferenceOutputAssembly> - </ProjectReference> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> -</Project> \ No newline at end of file +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|ARM"> + <Configuration>Debug</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|ARM64"> + <Configuration>Debug</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM64"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|Win32"> + <Configuration>PGInstrument</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|x64"> + <Configuration>PGInstrument</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM64"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|Win32"> + <Configuration>PGUpdate</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|x64"> + <Configuration>PGUpdate</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM"> + <Configuration>Release</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM64"> + <Configuration>Release</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{6901D91C-6E48-4BB7-9FEC-700C8131DF1D}</ProjectGuid> + <RootNamespace>_testcapi</RootNamespace> + <Keyword>Win32Proj</Keyword> + <SupportPGO>false</SupportPGO> + </PropertyGroup> + <Import Project="python.props" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <CharacterSet>NotSet</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <PropertyGroup> + <TargetExt>.pyd</TargetExt> + </PropertyGroup> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="pyproject.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> + </PropertyGroup> + <ItemGroup> + <ClCompile Include="..\Modules\_testcapimodule.c" /> + <ClCompile Include="..\Modules\_testcapi\getargs.c" /> + <ClCompile Include="..\Modules\_testcapi\vectorcall.c" /> + <ClCompile Include="..\Modules\_testcapi\vectorcall_limited.c" /> + <ClCompile Include="..\Modules\_testcapi\heaptype.c" /> + <ClCompile Include="..\Modules\_testcapi\heaptype_relative.c" /> + <ClCompile Include="..\Modules\_testcapi\abstract.c" /> + <ClCompile Include="..\Modules\_testcapi\unicode.c" /> + <ClCompile Include="..\Modules\_testcapi\dict.c" /> + <ClCompile Include="..\Modules\_testcapi\pytime.c" /> + <ClCompile Include="..\Modules\_testcapi\datetime.c" /> + <ClCompile Include="..\Modules\_testcapi\docstring.c" /> + <ClCompile Include="..\Modules\_testcapi\mem.c" /> + <ClCompile Include="..\Modules\_testcapi\watchers.c" /> + <ClCompile Include="..\Modules\_testcapi\float.c" /> + <ClCompile Include="..\Modules\_testcapi\long.c" /> + <ClCompile Include="..\Modules\_testcapi\structmember.c" /> + <ClCompile Include="..\Modules\_testcapi\exceptions.c" /> + <ClCompile Include="..\Modules\_testcapi\code.c" /> + <ClCompile Include="..\Modules\_testcapi\buffer.c" /> + <ClCompile Include="..\Modules\_testcapi\pyos.c" /> + <ClCompile Include="..\Modules\_testcapi\immortal.c" /> + <ClCompile Include="..\Modules\_testcapi\gc.c" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_nt.rc" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="pythoncore.vcxproj"> + <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + <ProjectReference Include="python3dll.vcxproj"> + <Project>{885d4898-d08d-4091-9c40-c700cfe3fc5a}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> diff --git a/PCbuild/_testcapi.vcxproj.filters b/PCbuild/_testcapi.vcxproj.filters index c6b87109..61322332 100644 --- a/PCbuild/_testcapi.vcxproj.filters +++ b/PCbuild/_testcapi.vcxproj.filters @@ -1,21 +1,84 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <Filter Include="Source Files"> - <UniqueIdentifier>{a76a90d8-8e8b-4c36-8f58-8bd46abe9f5e}</UniqueIdentifier> - </Filter> - <Filter Include="Resource Files"> - <UniqueIdentifier>{071b2ff4-e5a1-4e79-b0c5-cf46b0094a80}</UniqueIdentifier> - </Filter> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\Modules\_testcapimodule.c"> - <Filter>Source Files</Filter> - </ClCompile> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\python_nt.rc"> - <Filter>Resource Files</Filter> - </ResourceCompile> - </ItemGroup> -</Project> \ No newline at end of file +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{a76a90d8-8e8b-4c36-8f58-8bd46abe9f5e}</UniqueIdentifier> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{071b2ff4-e5a1-4e79-b0c5-cf46b0094a80}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\Modules\_testcapimodule.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_testcapi\getargs.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_testcapi\vectorcall.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_testcapi\vectorcall_limited.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_testcapi\heaptype.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_testcapi\heaptype_relative.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_testcapi\abstract.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_testcapi\unicode.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_testcapi\dict.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_testcapi\pytime.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_testcapi\datetime.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_testcapi\docstring.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_testcapi\mem.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_testcapi\watchers.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_testcapi\float.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_testcapi\long.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_testcapi\structmember.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_testcapi\exceptions.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_testcapi\code.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_testcapi\buffer.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_testcapi\pyos.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_testcapi\gc.c"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_nt.rc"> + <Filter>Resource Files</Filter> + </ResourceCompile> + </ItemGroup> +</Project> diff --git a/PCbuild/_testclinic.vcxproj b/PCbuild/_testclinic.vcxproj new file mode 100644 index 00000000..e319b3c0 --- /dev/null +++ b/PCbuild/_testclinic.vcxproj @@ -0,0 +1,110 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|ARM"> + <Configuration>Debug</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|ARM64"> + <Configuration>Debug</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM64"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|Win32"> + <Configuration>PGInstrument</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|x64"> + <Configuration>PGInstrument</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM64"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|Win32"> + <Configuration>PGUpdate</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|x64"> + <Configuration>PGUpdate</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM"> + <Configuration>Release</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM64"> + <Configuration>Release</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{A840DDFB-ED50-484B-B527-B32E7CF90FD5}</ProjectGuid> + <RootNamespace>_testclinic</RootNamespace> + <Keyword>Win32Proj</Keyword> + <SupportPGO>false</SupportPGO> + </PropertyGroup> + <Import Project="python.props" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <CharacterSet>NotSet</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <PropertyGroup> + <TargetExt>.pyd</TargetExt> + </PropertyGroup> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="pyproject.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> + </PropertyGroup> + <ItemGroup> + <ClCompile Include="..\Modules\_testclinic.c" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_nt.rc" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="pythoncore.vcxproj"> + <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/PCbuild/_testclinic.vcxproj.filters b/PCbuild/_testclinic.vcxproj.filters new file mode 100644 index 00000000..4a2987eb --- /dev/null +++ b/PCbuild/_testclinic.vcxproj.filters @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{5b0a9282-a01c-4b83-9fd4-6deb6c558f9c}</UniqueIdentifier> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{6a89c8a9-5b51-4525-ac5c-7d0a22f9657e}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\Modules\_testclinic.c"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_nt.rc"> + <Filter>Resource Files</Filter> + </ResourceCompile> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/PCbuild/_testconsole.vcxproj b/PCbuild/_testconsole.vcxproj index 81f3f34a..5d7e14ef 100644 --- a/PCbuild/_testconsole.vcxproj +++ b/PCbuild/_testconsole.vcxproj @@ -1,115 +1,115 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|ARM"> - <Configuration>Debug</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|ARM64"> - <Configuration>Debug</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM64"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|Win32"> - <Configuration>PGInstrument</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|x64"> - <Configuration>PGInstrument</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM64"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|Win32"> - <Configuration>PGUpdate</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|x64"> - <Configuration>PGUpdate</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM"> - <Configuration>Release</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM64"> - <Configuration>Release</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectGuid>{B244E787-C445-441C-BDF4-5A4F1A3A1E51}</ProjectGuid> - <Keyword>Win32Proj</Keyword> - <RootNamespace>_testconsole</RootNamespace> - <SupportPGO>false</SupportPGO> - </PropertyGroup> - <Import Project="python.props" /> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>NotSet</CharacterSet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <PropertyGroup> - <TargetExt>.pyd</TargetExt> - </PropertyGroup> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="pyproject.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <ItemDefinitionGroup> - <ClCompile> - <PreprocessorDefinitions>_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - </Link> - </ItemDefinitionGroup> - <ItemGroup> - <ClCompile Include="..\PC\_testconsole.c" /> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\python_nt.rc" /> - </ItemGroup> - <ItemGroup> - <ProjectReference Include="pythoncore.vcxproj"> - <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> - <ReferenceOutputAssembly>false</ReferenceOutputAssembly> - </ProjectReference> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|ARM"> + <Configuration>Debug</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|ARM64"> + <Configuration>Debug</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM64"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|Win32"> + <Configuration>PGInstrument</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|x64"> + <Configuration>PGInstrument</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM64"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|Win32"> + <Configuration>PGUpdate</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|x64"> + <Configuration>PGUpdate</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM"> + <Configuration>Release</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM64"> + <Configuration>Release</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{B244E787-C445-441C-BDF4-5A4F1A3A1E51}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>_testconsole</RootNamespace> + <SupportPGO>false</SupportPGO> + </PropertyGroup> + <Import Project="python.props" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <CharacterSet>NotSet</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <PropertyGroup> + <TargetExt>.pyd</TargetExt> + </PropertyGroup> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="pyproject.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <ItemDefinitionGroup> + <ClCompile> + <PreprocessorDefinitions>_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\PC\_testconsole.c" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_nt.rc" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="pythoncore.vcxproj"> + <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> </Project> \ No newline at end of file diff --git a/PCbuild/_testconsole.vcxproj.filters b/PCbuild/_testconsole.vcxproj.filters index 7a2b7e5f..321e1778 100644 --- a/PCbuild/_testconsole.vcxproj.filters +++ b/PCbuild/_testconsole.vcxproj.filters @@ -1,23 +1,23 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <Filter Include="Source Files"> - <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> - <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> - </Filter> - <Filter Include="Resource Files"> - <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> - <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> - </Filter> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\PC\_testconsole.c"> - <Filter>Source Files</Filter> - </ClCompile> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\python_nt.rc"> - <Filter>Resource Files</Filter> - </ResourceCompile> - </ItemGroup> +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\PC\_testconsole.c"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_nt.rc"> + <Filter>Resource Files</Filter> + </ResourceCompile> + </ItemGroup> </Project> \ No newline at end of file diff --git a/PCbuild/_testembed.vcxproj b/PCbuild/_testembed.vcxproj index ebed0cf7..a7ea8787 100644 --- a/PCbuild/_testembed.vcxproj +++ b/PCbuild/_testembed.vcxproj @@ -1,112 +1,112 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|ARM"> - <Configuration>Debug</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|ARM64"> - <Configuration>Debug</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM64"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|Win32"> - <Configuration>PGInstrument</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|x64"> - <Configuration>PGInstrument</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM64"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|Win32"> - <Configuration>PGUpdate</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|x64"> - <Configuration>PGUpdate</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM"> - <Configuration>Release</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM64"> - <Configuration>Release</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectGuid>{6DAC66D9-E703-4624-BE03-49112AB5AA62}</ProjectGuid> - <Keyword>Win32Proj</Keyword> - <RootNamespace>_testembed</RootNamespace> - <SupportPGO>false</SupportPGO> - </PropertyGroup> - <Import Project="python.props" /> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="pyproject.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <ItemDefinitionGroup> - <ClCompile> - <PreprocessorDefinitions>_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - </Link> - </ItemDefinitionGroup> - <ItemGroup> - <ClCompile Include="..\Programs\_testembed.c" /> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\python_nt.rc" /> - </ItemGroup> - <ItemGroup> - <ProjectReference Include="pythoncore.vcxproj"> - <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> - <ReferenceOutputAssembly>false</ReferenceOutputAssembly> - </ProjectReference> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|ARM"> + <Configuration>Debug</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|ARM64"> + <Configuration>Debug</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM64"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|Win32"> + <Configuration>PGInstrument</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|x64"> + <Configuration>PGInstrument</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM64"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|Win32"> + <Configuration>PGUpdate</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|x64"> + <Configuration>PGUpdate</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM"> + <Configuration>Release</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM64"> + <Configuration>Release</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{6DAC66D9-E703-4624-BE03-49112AB5AA62}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>_testembed</RootNamespace> + <SupportPGO>false</SupportPGO> + </PropertyGroup> + <Import Project="python.props" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="pyproject.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <ItemDefinitionGroup> + <ClCompile> + <PreprocessorDefinitions>_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\Programs\_testembed.c" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_nt.rc" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="pythoncore.vcxproj"> + <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> </Project> \ No newline at end of file diff --git a/PCbuild/_testembed.vcxproj.filters b/PCbuild/_testembed.vcxproj.filters index c8ac25b7..b90fd85f 100644 --- a/PCbuild/_testembed.vcxproj.filters +++ b/PCbuild/_testembed.vcxproj.filters @@ -1,23 +1,23 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <Filter Include="Source Files"> - <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> - <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> - </Filter> - <Filter Include="Resource Files"> - <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> - <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> - </Filter> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\Programs\_testembed.c"> - <Filter>Source Files</Filter> - </ClCompile> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\python_nt.rc"> - <Filter>Resource Files</Filter> - </ResourceCompile> - </ItemGroup> +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\Programs\_testembed.c"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_nt.rc"> + <Filter>Resource Files</Filter> + </ResourceCompile> + </ItemGroup> </Project> \ No newline at end of file diff --git a/PCbuild/_testimportmultiple.vcxproj b/PCbuild/_testimportmultiple.vcxproj index 91f21e0e..6d80d577 100644 --- a/PCbuild/_testimportmultiple.vcxproj +++ b/PCbuild/_testimportmultiple.vcxproj @@ -1,110 +1,110 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|ARM"> - <Configuration>Debug</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|ARM64"> - <Configuration>Debug</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM64"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|Win32"> - <Configuration>PGInstrument</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|x64"> - <Configuration>PGInstrument</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM64"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|Win32"> - <Configuration>PGUpdate</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|x64"> - <Configuration>PGUpdate</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM"> - <Configuration>Release</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM64"> - <Configuration>Release</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectGuid>{36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}</ProjectGuid> - <RootNamespace>_testimportmultiple</RootNamespace> - <Keyword>Win32Proj</Keyword> - <SupportPGO>false</SupportPGO> - </PropertyGroup> - <Import Project="python.props" /> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>NotSet</CharacterSet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <PropertyGroup> - <TargetExt>.pyd</TargetExt> - </PropertyGroup> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="pyproject.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup> - <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> - </PropertyGroup> - <ItemGroup> - <ClCompile Include="..\Modules\_testimportmultiple.c" /> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\python_nt.rc" /> - </ItemGroup> - <ItemGroup> - <ProjectReference Include="pythoncore.vcxproj"> - <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> - <ReferenceOutputAssembly>false</ReferenceOutputAssembly> - </ProjectReference> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> -</Project> +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|ARM"> + <Configuration>Debug</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|ARM64"> + <Configuration>Debug</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM64"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|Win32"> + <Configuration>PGInstrument</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|x64"> + <Configuration>PGInstrument</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM64"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|Win32"> + <Configuration>PGUpdate</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|x64"> + <Configuration>PGUpdate</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM"> + <Configuration>Release</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM64"> + <Configuration>Release</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}</ProjectGuid> + <RootNamespace>_testimportmultiple</RootNamespace> + <Keyword>Win32Proj</Keyword> + <SupportPGO>false</SupportPGO> + </PropertyGroup> + <Import Project="python.props" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <CharacterSet>NotSet</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <PropertyGroup> + <TargetExt>.pyd</TargetExt> + </PropertyGroup> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="pyproject.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> + </PropertyGroup> + <ItemGroup> + <ClCompile Include="..\Modules\_testimportmultiple.c" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_nt.rc" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="pythoncore.vcxproj"> + <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> diff --git a/PCbuild/_testimportmultiple.vcxproj.filters b/PCbuild/_testimportmultiple.vcxproj.filters index 96acc2b2..8f63d134 100644 --- a/PCbuild/_testimportmultiple.vcxproj.filters +++ b/PCbuild/_testimportmultiple.vcxproj.filters @@ -1,21 +1,21 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <Filter Include="Source Files"> - <UniqueIdentifier>{1ec38ad9-1abf-4b80-8628-ac43ccba324b}</UniqueIdentifier> - </Filter> - <Filter Include="Resource Files"> - <UniqueIdentifier>{0ff128a6-7814-4f8e-826e-860a858104ee}</UniqueIdentifier> - </Filter> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\Modules\_testimportmultiple.c"> - <Filter>Source Files</Filter> - </ClCompile> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\python_nt.rc"> - <Filter>Resource Files</Filter> - </ResourceCompile> - </ItemGroup> +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{1ec38ad9-1abf-4b80-8628-ac43ccba324b}</UniqueIdentifier> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{0ff128a6-7814-4f8e-826e-860a858104ee}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\Modules\_testimportmultiple.c"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_nt.rc"> + <Filter>Resource Files</Filter> + </ResourceCompile> + </ItemGroup> </Project> \ No newline at end of file diff --git a/PCbuild/_testinternalcapi.vcxproj b/PCbuild/_testinternalcapi.vcxproj index 58251ef6..6c5b12cd 100644 --- a/PCbuild/_testinternalcapi.vcxproj +++ b/PCbuild/_testinternalcapi.vcxproj @@ -1,110 +1,110 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|ARM"> - <Configuration>Debug</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|ARM64"> - <Configuration>Debug</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM64"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|Win32"> - <Configuration>PGInstrument</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|x64"> - <Configuration>PGInstrument</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM64"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|Win32"> - <Configuration>PGUpdate</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|x64"> - <Configuration>PGUpdate</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM"> - <Configuration>Release</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM64"> - <Configuration>Release</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectGuid>{900342D7-516A-4469-B1AD-59A66E49A25F}</ProjectGuid> - <RootNamespace>_testinternalcapi</RootNamespace> - <Keyword>Win32Proj</Keyword> - <SupportPGO>false</SupportPGO> - </PropertyGroup> - <Import Project="python.props" /> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>NotSet</CharacterSet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <PropertyGroup> - <TargetExt>.pyd</TargetExt> - </PropertyGroup> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="pyproject.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup> - <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> - </PropertyGroup> - <ItemGroup> - <ClCompile Include="..\Modules\_testinternalcapi.c" /> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\python_nt.rc" /> - </ItemGroup> - <ItemGroup> - <ProjectReference Include="pythoncore.vcxproj"> - <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> - <ReferenceOutputAssembly>false</ReferenceOutputAssembly> - </ProjectReference> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> -</Project> +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|ARM"> + <Configuration>Debug</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|ARM64"> + <Configuration>Debug</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM64"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|Win32"> + <Configuration>PGInstrument</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|x64"> + <Configuration>PGInstrument</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM64"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|Win32"> + <Configuration>PGUpdate</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|x64"> + <Configuration>PGUpdate</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM"> + <Configuration>Release</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM64"> + <Configuration>Release</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{900342D7-516A-4469-B1AD-59A66E49A25F}</ProjectGuid> + <RootNamespace>_testinternalcapi</RootNamespace> + <Keyword>Win32Proj</Keyword> + <SupportPGO>false</SupportPGO> + </PropertyGroup> + <Import Project="python.props" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <CharacterSet>NotSet</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <PropertyGroup> + <TargetExt>.pyd</TargetExt> + </PropertyGroup> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="pyproject.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> + </PropertyGroup> + <ItemGroup> + <ClCompile Include="..\Modules\_testinternalcapi.c" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_nt.rc" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="pythoncore.vcxproj"> + <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> diff --git a/PCbuild/_testinternalcapi.vcxproj.filters b/PCbuild/_testinternalcapi.vcxproj.filters index 7db27fe7..7734da0b 100644 --- a/PCbuild/_testinternalcapi.vcxproj.filters +++ b/PCbuild/_testinternalcapi.vcxproj.filters @@ -1,21 +1,21 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <Filter Include="Source Files"> - <UniqueIdentifier>{136fc5eb-7fe4-4486-8c6d-b49f37a00199}</UniqueIdentifier> - </Filter> - <Filter Include="Resource Files"> - <UniqueIdentifier>{acecc890-f8dd-4942-b6d2-1fd8f73a5d6c}</UniqueIdentifier> - </Filter> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\Modules\_testinternalcapi.c"> - <Filter>Source Files</Filter> - </ClCompile> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\python_nt.rc"> - <Filter>Resource Files</Filter> - </ResourceCompile> - </ItemGroup> +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{136fc5eb-7fe4-4486-8c6d-b49f37a00199}</UniqueIdentifier> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{acecc890-f8dd-4942-b6d2-1fd8f73a5d6c}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\Modules\_testinternalcapi.c"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_nt.rc"> + <Filter>Resource Files</Filter> + </ResourceCompile> + </ItemGroup> </Project> \ No newline at end of file diff --git a/PCbuild/_testmultiphase.vcxproj b/PCbuild/_testmultiphase.vcxproj index 3b517383..430eb528 100644 --- a/PCbuild/_testmultiphase.vcxproj +++ b/PCbuild/_testmultiphase.vcxproj @@ -1,115 +1,115 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|ARM"> - <Configuration>Debug</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|ARM64"> - <Configuration>Debug</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM64"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|Win32"> - <Configuration>PGInstrument</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|x64"> - <Configuration>PGInstrument</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM64"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|Win32"> - <Configuration>PGUpdate</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|x64"> - <Configuration>PGUpdate</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM"> - <Configuration>Release</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM64"> - <Configuration>Release</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectGuid>{16BFE6F0-22EF-40B5-B831-7E937119EF10}</ProjectGuid> - <Keyword>Win32Proj</Keyword> - <RootNamespace>_testmultiphase</RootNamespace> - <SupportPGO>false</SupportPGO> - </PropertyGroup> - <Import Project="python.props" /> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>NotSet</CharacterSet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <PropertyGroup> - <TargetExt>.pyd</TargetExt> - </PropertyGroup> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="pyproject.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <ItemDefinitionGroup> - <ClCompile> - <PreprocessorDefinitions>_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - </Link> - </ItemDefinitionGroup> - <ItemGroup> - <ClCompile Include="..\Modules\_testmultiphase.c" /> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\python_nt.rc" /> - </ItemGroup> - <ItemGroup> - <ProjectReference Include="pythoncore.vcxproj"> - <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> - <ReferenceOutputAssembly>false</ReferenceOutputAssembly> - </ProjectReference> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|ARM"> + <Configuration>Debug</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|ARM64"> + <Configuration>Debug</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM64"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|Win32"> + <Configuration>PGInstrument</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|x64"> + <Configuration>PGInstrument</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM64"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|Win32"> + <Configuration>PGUpdate</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|x64"> + <Configuration>PGUpdate</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM"> + <Configuration>Release</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM64"> + <Configuration>Release</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{16BFE6F0-22EF-40B5-B831-7E937119EF10}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>_testmultiphase</RootNamespace> + <SupportPGO>false</SupportPGO> + </PropertyGroup> + <Import Project="python.props" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <CharacterSet>NotSet</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <PropertyGroup> + <TargetExt>.pyd</TargetExt> + </PropertyGroup> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="pyproject.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <ItemDefinitionGroup> + <ClCompile> + <PreprocessorDefinitions>_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\Modules\_testmultiphase.c" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_nt.rc" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="pythoncore.vcxproj"> + <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> </Project> \ No newline at end of file diff --git a/PCbuild/_testmultiphase.vcxproj.filters b/PCbuild/_testmultiphase.vcxproj.filters index a0f9ee9d..8df0a42e 100644 --- a/PCbuild/_testmultiphase.vcxproj.filters +++ b/PCbuild/_testmultiphase.vcxproj.filters @@ -1,23 +1,23 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <Filter Include="Source Files"> - <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> - <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> - </Filter> - <Filter Include="Resource Files"> - <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> - <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> - </Filter> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\Modules\_testmultiphase.c"> - <Filter>Source Files</Filter> - </ClCompile> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\python_nt.rc"> - <Filter>Resource Files</Filter> - </ResourceCompile> - </ItemGroup> +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\Modules\_testmultiphase.c"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_nt.rc"> + <Filter>Resource Files</Filter> + </ResourceCompile> + </ItemGroup> </Project> \ No newline at end of file diff --git a/PCbuild/_testsinglephase.vcxproj b/PCbuild/_testsinglephase.vcxproj new file mode 100644 index 00000000..fb4bcd95 --- /dev/null +++ b/PCbuild/_testsinglephase.vcxproj @@ -0,0 +1,115 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|ARM"> + <Configuration>Debug</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|ARM64"> + <Configuration>Debug</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM64"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|Win32"> + <Configuration>PGInstrument</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|x64"> + <Configuration>PGInstrument</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM64"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|Win32"> + <Configuration>PGUpdate</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|x64"> + <Configuration>PGUpdate</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM"> + <Configuration>Release</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM64"> + <Configuration>Release</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{2097F1C1-597C-4167-93E3-656A7D6339B2}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>_testsinglephase</RootNamespace> + <SupportPGO>false</SupportPGO> + </PropertyGroup> + <Import Project="python.props" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <CharacterSet>NotSet</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <PropertyGroup> + <TargetExt>.pyd</TargetExt> + </PropertyGroup> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="pyproject.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <ItemDefinitionGroup> + <ClCompile> + <PreprocessorDefinitions>_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\Modules\_testsinglephase.c" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_nt.rc" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="pythoncore.vcxproj"> + <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> diff --git a/PCbuild/_testsinglephase.vcxproj.filters b/PCbuild/_testsinglephase.vcxproj.filters new file mode 100644 index 00000000..2a0e0ef6 --- /dev/null +++ b/PCbuild/_testsinglephase.vcxproj.filters @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\Modules\_testsinglephase.c"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_nt.rc"> + <Filter>Resource Files</Filter> + </ResourceCompile> + </ItemGroup> +</Project> diff --git a/PCbuild/_tkinter.vcxproj b/PCbuild/_tkinter.vcxproj index 8cbc654b..30cedcbb 100644 --- a/PCbuild/_tkinter.vcxproj +++ b/PCbuild/_tkinter.vcxproj @@ -1,136 +1,137 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|ARM"> - <Configuration>Debug</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|ARM64"> - <Configuration>Debug</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM64"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|Win32"> - <Configuration>PGInstrument</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|x64"> - <Configuration>PGInstrument</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM64"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|Win32"> - <Configuration>PGUpdate</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|x64"> - <Configuration>PGUpdate</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM"> - <Configuration>Release</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM64"> - <Configuration>Release</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectGuid>{4946ECAC-2E69-4BF8-A90A-F5136F5094DF}</ProjectGuid> - <RootNamespace>_tkinter</RootNamespace> - <Keyword>Win32Proj</Keyword> - </PropertyGroup> - <Import Project="python.props" /> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>NotSet</CharacterSet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <PropertyGroup> - <TargetExt>.pyd</TargetExt> - </PropertyGroup> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="tcltk.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup> - <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> - </PropertyGroup> - <ItemDefinitionGroup> - <ClCompile> - <AdditionalIncludeDirectories>$(tcltkDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>WITH_APPINIT;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <PreprocessorDefinitions Condition="'$(BuildForRelease)' != 'true'">Py_TCLTK_DIR="$(tcltkDir.TrimEnd('\').Replace('\', '\\'))";%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <Link> - <AdditionalDependencies>$(tcltkLib);%(AdditionalDependencies)</AdditionalDependencies> - </Link> - </ItemDefinitionGroup> - <ItemGroup> - <ClCompile Include="..\Modules\_tkinter.c" /> - <ClCompile Include="..\Modules\tkappinit.c" /> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\python_nt.rc" /> - </ItemGroup> - <ItemGroup> - <_TclTkDLL Include="$(tcltkdir)\bin\$(tclDllName)" /> - <_TclTkDLL Include="$(tcltkdir)\bin\$(tkDllName)" /> - </ItemGroup> - <ItemGroup> - <ProjectReference Include="pythoncore.vcxproj"> - <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> - <ReferenceOutputAssembly>false</ReferenceOutputAssembly> - </ProjectReference> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> - <Target Name="_CopyTclTkDLL" Inputs="@(_TclTkDLL)" Outputs="@(_TclTkDLL->'$(OutDir)%(Filename)%(Extension)')" AfterTargets="Build"> - <Copy SourceFiles="@(_TclTkDLL)" DestinationFolder="$(OutDir)" UseHardlinksIfPossible="true" /> - </Target> - <Target Name="_CleanTclTkDLL" BeforeTargets="Clean"> - <Delete Files="@(_TclTkDLL->'$(OutDir)%(Filename)%(Extension)')" /> - </Target> - <Target Name="_WriteTCL_LIBRARY" Outputs="$(OutDir)TCL_LIBRARY.env" AfterTargets="Build"> - <WriteLinesToFile File="$(OutDir)TCL_LIBRARY.env" Lines="$(tcltkdir)\lib\tcl$(TclMajorVersion).$(TclMinorVersion)" Encoding="utf-8" Overwrite="true" /> - </Target> - <Target Name="_CleanTCL_LIBRARY" BeforeTargets="Clean"> - <Delete Files="$(OutDir)TCL_LIBRARY.env" /> - </Target> +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|ARM"> + <Configuration>Debug</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|ARM64"> + <Configuration>Debug</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM64"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|Win32"> + <Configuration>PGInstrument</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|x64"> + <Configuration>PGInstrument</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM64"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|Win32"> + <Configuration>PGUpdate</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|x64"> + <Configuration>PGUpdate</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM"> + <Configuration>Release</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM64"> + <Configuration>Release</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{4946ECAC-2E69-4BF8-A90A-F5136F5094DF}</ProjectGuid> + <RootNamespace>_tkinter</RootNamespace> + <Keyword>Win32Proj</Keyword> + </PropertyGroup> + <Import Project="python.props" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <CharacterSet>NotSet</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <PropertyGroup> + <TargetExt>.pyd</TargetExt> + </PropertyGroup> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="tcltk.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> + </PropertyGroup> + <ItemDefinitionGroup> + <ClCompile> + <AdditionalIncludeDirectories>$(tcltkDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WITH_APPINIT;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions Condition="'$(BuildForRelease)' != 'true'">Py_TCLTK_DIR="$(tcltkDir.TrimEnd('\').Replace('\', '\\'))";%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <Link> + <AdditionalDependencies>$(tcltkLib);%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\Modules\_tkinter.c" /> + <ClCompile Include="..\Modules\tkappinit.c" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_nt.rc" /> + </ItemGroup> + <ItemGroup> + <_TclTkDLL Include="$(tcltkdir)\bin\$(tclDllName)" /> + <_TclTkDLL Include="$(tcltkdir)\bin\$(tkDllName)" /> + <_TclTkDLL Include="$(tcltkdir)\bin\$(tclZlibDllName)" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="pythoncore.vcxproj"> + <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> + <Target Name="_CopyTclTkDLL" Inputs="@(_TclTkDLL)" Outputs="@(_TclTkDLL->'$(OutDir)%(Filename)%(Extension)')" AfterTargets="Build"> + <Copy SourceFiles="@(_TclTkDLL)" DestinationFolder="$(OutDir)" UseHardlinksIfPossible="true" /> + </Target> + <Target Name="_CleanTclTkDLL" BeforeTargets="Clean"> + <Delete Files="@(_TclTkDLL->'$(OutDir)%(Filename)%(Extension)')" /> + </Target> + <Target Name="_WriteTCL_LIBRARY" Outputs="$(OutDir)TCL_LIBRARY.env" AfterTargets="Build"> + <WriteLinesToFile File="$(OutDir)TCL_LIBRARY.env" Lines="$(tcltkdir)\lib\tcl$(TclMajorVersion).$(TclMinorVersion)" Encoding="utf-8" Overwrite="true" /> + </Target> + <Target Name="_CleanTCL_LIBRARY" BeforeTargets="Clean"> + <Delete Files="$(OutDir)TCL_LIBRARY.env" /> + </Target> </Project> \ No newline at end of file diff --git a/PCbuild/_tkinter.vcxproj.filters b/PCbuild/_tkinter.vcxproj.filters index cf624fcf..0d919439 100644 --- a/PCbuild/_tkinter.vcxproj.filters +++ b/PCbuild/_tkinter.vcxproj.filters @@ -1,24 +1,24 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <Filter Include="Source Files"> - <UniqueIdentifier>{b9ce64dd-cb95-472d-bbe8-5583b2cd375b}</UniqueIdentifier> - </Filter> - <Filter Include="Resource Files"> - <UniqueIdentifier>{2bd3a90c-5b2e-45fb-9b2a-fbf1a4faf5f9}</UniqueIdentifier> - </Filter> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\Modules\_tkinter.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Modules\tkappinit.c"> - <Filter>Source Files</Filter> - </ClCompile> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\python_nt.rc"> - <Filter>Resource Files</Filter> - </ResourceCompile> - </ItemGroup> +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{b9ce64dd-cb95-472d-bbe8-5583b2cd375b}</UniqueIdentifier> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{2bd3a90c-5b2e-45fb-9b2a-fbf1a4faf5f9}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\Modules\_tkinter.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Modules\tkappinit.c"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_nt.rc"> + <Filter>Resource Files</Filter> + </ResourceCompile> + </ItemGroup> </Project> \ No newline at end of file diff --git a/PCbuild/_uuid.vcxproj b/PCbuild/_uuid.vcxproj index accfffa1..2437b7eb 100644 --- a/PCbuild/_uuid.vcxproj +++ b/PCbuild/_uuid.vcxproj @@ -1,115 +1,115 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|ARM"> - <Configuration>Debug</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|ARM64"> - <Configuration>Debug</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM64"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|Win32"> - <Configuration>PGInstrument</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|x64"> - <Configuration>PGInstrument</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM64"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|Win32"> - <Configuration>PGUpdate</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|x64"> - <Configuration>PGUpdate</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM"> - <Configuration>Release</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM64"> - <Configuration>Release</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectGuid>{CB435430-EBB1-478B-8F4E-C256F6838F55}</ProjectGuid> - <RootNamespace>_uuid</RootNamespace> - <Keyword>Win32Proj</Keyword> - <SupportPGO>false</SupportPGO> - </PropertyGroup> - <Import Project="python.props" /> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>NotSet</CharacterSet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <PropertyGroup> - <TargetExt>.pyd</TargetExt> - </PropertyGroup> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="pyproject.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup> - <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> - </PropertyGroup> - <ItemDefinitionGroup> - <Link> - <AdditionalDependencies>rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies> - </Link> - </ItemDefinitionGroup> - <ItemGroup> - <ClCompile Include="..\Modules\_uuidmodule.c" /> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\python_nt.rc" /> - </ItemGroup> - <ItemGroup> - <ProjectReference Include="pythoncore.vcxproj"> - <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> - <ReferenceOutputAssembly>false</ReferenceOutputAssembly> - </ProjectReference> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|ARM"> + <Configuration>Debug</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|ARM64"> + <Configuration>Debug</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM64"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|Win32"> + <Configuration>PGInstrument</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|x64"> + <Configuration>PGInstrument</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM64"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|Win32"> + <Configuration>PGUpdate</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|x64"> + <Configuration>PGUpdate</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM"> + <Configuration>Release</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM64"> + <Configuration>Release</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{CB435430-EBB1-478B-8F4E-C256F6838F55}</ProjectGuid> + <RootNamespace>_uuid</RootNamespace> + <Keyword>Win32Proj</Keyword> + <SupportPGO>false</SupportPGO> + </PropertyGroup> + <Import Project="python.props" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <CharacterSet>NotSet</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <PropertyGroup> + <TargetExt>.pyd</TargetExt> + </PropertyGroup> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="pyproject.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> + </PropertyGroup> + <ItemDefinitionGroup> + <Link> + <AdditionalDependencies>rpcrt4.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\Modules\_uuidmodule.c" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_nt.rc" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="pythoncore.vcxproj"> + <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> </Project> \ No newline at end of file diff --git a/PCbuild/_uuid.vcxproj.filters b/PCbuild/_uuid.vcxproj.filters index f0351414..705902ff 100644 --- a/PCbuild/_uuid.vcxproj.filters +++ b/PCbuild/_uuid.vcxproj.filters @@ -1,22 +1,22 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <Filter Include="Source Files"> - <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> - <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> - </Filter> - <Filter Include="Resource Files"> - <UniqueIdentifier>{4fa4dbfa-e069-4ab4-86a6-ad389b2ec407}</UniqueIdentifier> - </Filter> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\Modules\_uuidmodule.c"> - <Filter>Source Files</Filter> - </ClCompile> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\python_nt.rc"> - <Filter>Resource Files</Filter> - </ResourceCompile> - </ItemGroup> +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{4fa4dbfa-e069-4ab4-86a6-ad389b2ec407}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\Modules\_uuidmodule.c"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_nt.rc"> + <Filter>Resource Files</Filter> + </ResourceCompile> + </ItemGroup> </Project> \ No newline at end of file diff --git a/PCbuild/_wmi.vcxproj b/PCbuild/_wmi.vcxproj new file mode 100644 index 00000000..c1914a3f --- /dev/null +++ b/PCbuild/_wmi.vcxproj @@ -0,0 +1,119 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|ARM"> + <Configuration>Debug</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|ARM64"> + <Configuration>Debug</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM64"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|Win32"> + <Configuration>PGInstrument</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|x64"> + <Configuration>PGInstrument</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM64"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|Win32"> + <Configuration>PGUpdate</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|x64"> + <Configuration>PGUpdate</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM"> + <Configuration>Release</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM64"> + <Configuration>Release</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{54B1431F-B86B-4ACB-B28C-88BCF93191D8}</ProjectGuid> + <RootNamespace>_wmi</RootNamespace> + <Keyword>Win32Proj</Keyword> + <SupportPGO>false</SupportPGO> + </PropertyGroup> + <Import Project="python.props" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <CharacterSet>NotSet</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <PropertyGroup> + <TargetExt>.pyd</TargetExt> + </PropertyGroup> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="pyproject.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> + </PropertyGroup> + <ItemDefinitionGroup> + <ClCompile> + <AdditionalOptions>/std:c++20 %(AdditionalOptions)</AdditionalOptions> + </ClCompile> + <Link> + <AdditionalDependencies>wbemuuid.lib;propsys.lib;%(AdditionalDependencies)</AdditionalDependencies> + <DelayLoadDLLs>ole32.dll</DelayLoadDLLs> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\PC\_wmimodule.cpp" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_nt.rc" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="pythoncore.vcxproj"> + <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file diff --git a/PCbuild/_wmi.vcxproj.filters b/PCbuild/_wmi.vcxproj.filters new file mode 100644 index 00000000..fa804623 --- /dev/null +++ b/PCbuild/_wmi.vcxproj.filters @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{4fa4dbfa-e069-4ab4-86a6-ad389b2ec407}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\PC\_wmimodule.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_nt.rc"> + <Filter>Resource Files</Filter> + </ResourceCompile> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/PCbuild/_zoneinfo.vcxproj b/PCbuild/_zoneinfo.vcxproj index 7f3a56bd..6e6389c3 100644 --- a/PCbuild/_zoneinfo.vcxproj +++ b/PCbuild/_zoneinfo.vcxproj @@ -1,109 +1,109 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|ARM"> - <Configuration>Debug</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|ARM64"> - <Configuration>Debug</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM64"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|Win32"> - <Configuration>PGInstrument</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|x64"> - <Configuration>PGInstrument</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM64"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|Win32"> - <Configuration>PGUpdate</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|x64"> - <Configuration>PGUpdate</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM"> - <Configuration>Release</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM64"> - <Configuration>Release</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectGuid>{FCBE1EF2-E0F0-40B1-88B5-00A35D378742}</ProjectGuid> - <RootNamespace>_zoneinfo</RootNamespace> - <Keyword>Win32Proj</Keyword> - </PropertyGroup> - <Import Project="python.props" /> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>NotSet</CharacterSet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <PropertyGroup> - <TargetExt>.pyd</TargetExt> - </PropertyGroup> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="pyproject.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup> - <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> - </PropertyGroup> - <ItemGroup> - <ClCompile Include="..\Modules\_zoneinfo.c" /> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\python_nt.rc" /> - </ItemGroup> - <ItemGroup> - <ProjectReference Include="pythoncore.vcxproj"> - <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> - <ReferenceOutputAssembly>false</ReferenceOutputAssembly> - </ProjectReference> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> -</Project> +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|ARM"> + <Configuration>Debug</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|ARM64"> + <Configuration>Debug</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM64"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|Win32"> + <Configuration>PGInstrument</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|x64"> + <Configuration>PGInstrument</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM64"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|Win32"> + <Configuration>PGUpdate</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|x64"> + <Configuration>PGUpdate</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM"> + <Configuration>Release</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM64"> + <Configuration>Release</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{FCBE1EF2-E0F0-40B1-88B5-00A35D378742}</ProjectGuid> + <RootNamespace>_zoneinfo</RootNamespace> + <Keyword>Win32Proj</Keyword> + </PropertyGroup> + <Import Project="python.props" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <CharacterSet>NotSet</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <PropertyGroup> + <TargetExt>.pyd</TargetExt> + </PropertyGroup> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="pyproject.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> + </PropertyGroup> + <ItemGroup> + <ClCompile Include="..\Modules\_zoneinfo.c" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_nt.rc" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="pythoncore.vcxproj"> + <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> diff --git a/PCbuild/_zoneinfo.vcxproj.filters b/PCbuild/_zoneinfo.vcxproj.filters index e67fb5a3..57f31e05 100644 --- a/PCbuild/_zoneinfo.vcxproj.filters +++ b/PCbuild/_zoneinfo.vcxproj.filters @@ -1,21 +1,21 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <Filter Include="Source Files"> - <UniqueIdentifier>{2422278e-eeeb-4241-8182-433e2bc5a7fc}</UniqueIdentifier> - </Filter> - <Filter Include="Resource Files"> - <UniqueIdentifier>{0616fb85-7891-4790-83c2-005f906cf555}</UniqueIdentifier> - </Filter> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\Modules\_zoneinfo.c"> - <Filter>Source Files</Filter> - </ClCompile> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\python_nt.rc"> - <Filter>Resource Files</Filter> - </ResourceCompile> - </ItemGroup> +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{2422278e-eeeb-4241-8182-433e2bc5a7fc}</UniqueIdentifier> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{0616fb85-7891-4790-83c2-005f906cf555}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\Modules\_zoneinfo.c"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_nt.rc"> + <Filter>Resource Files</Filter> + </ResourceCompile> + </ItemGroup> </Project> \ No newline at end of file diff --git a/PCbuild/blurb.bat b/PCbuild/blurb.bat index d975165c..0be228a2 100644 --- a/PCbuild/blurb.bat +++ b/PCbuild/blurb.bat @@ -1,28 +1,28 @@ -@echo off -rem -rem Runs the blurb tool. If necessary, will install Python and/or blurb. -rem -rem Pass "--update"/"-U" as the first argument to update blurb. -rem - -call "%~dp0find_python.bat" %PYTHON% -if ERRORLEVEL 1 (echo Cannot locate python.exe on PATH or as PYTHON variable & exit /b 3) - -if "%1" EQU "--update" (%PYTHON% -m pip install -U blurb && shift) -if "%1" EQU "-U" (%PYTHON% -m pip install -U blurb && shift) - -%PYTHON% -m blurb %1 %2 %3 %4 %5 %6 %7 %8 %9 -if ERRORLEVEL 1 goto :install_and_retry -exit /B 0 - -:install_and_retry -rem Before reporting the error, make sure that blurb is actually installed. -rem If not, install it first and try again. -set _ERR=%ERRORLEVEL% -%PYTHON% -c "import blurb" -if NOT ERRORLEVEL 1 exit /B %_ERR% -echo Installing blurb... -%PYTHON% -m pip install blurb -if ERRORLEVEL 1 exit /B %ERRORLEVEL% -%PYTHON% -m blurb %* -exit /B +@echo off +rem +rem Runs the blurb tool. If necessary, will install Python and/or blurb. +rem +rem Pass "--update"/"-U" as the first argument to update blurb. +rem + +call "%~dp0find_python.bat" %PYTHON% +if ERRORLEVEL 1 (echo Cannot locate python.exe on PATH or as PYTHON variable & exit /b 3) + +if "%1" EQU "--update" (%PYTHON% -m pip install -U blurb && shift) +if "%1" EQU "-U" (%PYTHON% -m pip install -U blurb && shift) + +%PYTHON% -m blurb %1 %2 %3 %4 %5 %6 %7 %8 %9 +if ERRORLEVEL 1 goto :install_and_retry +exit /B 0 + +:install_and_retry +rem Before reporting the error, make sure that blurb is actually installed. +rem If not, install it first and try again. +set _ERR=%ERRORLEVEL% +%PYTHON% -c "import blurb" +if NOT ERRORLEVEL 1 exit /B %_ERR% +echo Installing blurb... +%PYTHON% -m pip install blurb +if ERRORLEVEL 1 exit /B %ERRORLEVEL% +%PYTHON% -m blurb %* +exit /B diff --git a/PCbuild/build.bat b/PCbuild/build.bat index bac39852..d333ceab 100644 --- a/PCbuild/build.bat +++ b/PCbuild/build.bat @@ -1,186 +1,186 @@ -@echo off -goto Run -:Usage -echo.%~nx0 [flags and arguments] [quoted MSBuild options] -echo. -echo.Build CPython from the command line. Requires the appropriate -echo.version(s) of Microsoft Visual Studio to be installed (see readme.txt). -echo. -echo.After the flags recognized by this script, up to 9 arguments to be passed -echo.directly to MSBuild may be passed. If the argument contains an '=', the -echo.entire argument must be quoted (e.g. `%~nx0 "/p:PlatformToolset=v100"`). -echo.Alternatively you can put extra flags for MSBuild in a file named -echo.`msbuild.rsp` in the `PCbuild` directory, one flag per line. This file -echo.will be picked automatically by MSBuild. Flags put in this file does not -echo.need to be quoted. You can still use environment variables inside the -echo.response file. -echo. -echo.Available flags: -echo. -h Display this help message -echo. -V Display version information for the current build -echo. -r Target Rebuild instead of Build -echo. -d Set the configuration to Debug -echo. -E Don't fetch or build external libraries. Extension modules that -echo. depend on external libraries will not attempt to build if this flag -echo. is present; -e is also accepted to explicitly enable fetching and -echo. building externals. -echo. -m Enable parallel build (enabled by default) -echo. -M Disable parallel build -echo. -v Increased output messages -echo. -vv Verbose output messages -echo. -q Quiet output messages (errors and warnings only) -echo. -k Attempt to kill any running Pythons before building (usually done -echo. automatically by the pythoncore project) -echo. --pgo Build with Profile-Guided Optimization. This flag -echo. overrides -c and -d -echo. --test-marker Enable the test marker within the build. -echo. --regen Regenerate all opcodes, grammar and tokens. -echo. -echo.Available flags to avoid building certain modules. -echo.These flags have no effect if '-e' is not given: -echo. --no-ctypes Do not attempt to build _ctypes -echo. --no-ssl Do not attempt to build _ssl -echo. --no-tkinter Do not attempt to build Tkinter -echo. -echo.Available arguments: -echo. -c Release ^| Debug ^| PGInstrument ^| PGUpdate -echo. Set the configuration (default: Release) -echo. -p x64 ^| Win32 ^| ARM ^| ARM64 -echo. Set the platform (default: x64) -echo. -t Build ^| Rebuild ^| Clean ^| CleanAll -echo. Set the target manually -echo. --pgo-job The job to use for PGO training; implies --pgo -echo. (default: "-m test --pgo") -exit /b 127 - -:Run -setlocal -set platf=x64 -set conf=Release -set target=Build -set dir=%~dp0 -set parallel=/m -set verbose=/nologo /v:m /clp:summary -set kill= -set do_pgo= -set pgo_job=-m test --pgo - -:CheckOpts -if "%~1"=="-h" goto Usage -if "%~1"=="-c" (set conf=%2) & shift & shift & goto CheckOpts -if "%~1"=="-p" (set platf=%2) & shift & shift & goto CheckOpts -if "%~1"=="-r" (set target=Rebuild) & shift & goto CheckOpts -if "%~1"=="-t" (set target=%2) & shift & shift & goto CheckOpts -if "%~1"=="-d" (set conf=Debug) & shift & goto CheckOpts -if "%~1"=="-m" (set parallel=/m) & shift & goto CheckOpts -if "%~1"=="-M" (set parallel=) & shift & goto CheckOpts -if "%~1"=="-v" (set verbose=/v:n) & shift & goto CheckOpts -if "%~1"=="-vv" (set verbose=/v:d /ds) & shift & goto CheckOpts -if "%~1"=="-q" (set verbose=/v:q /nologo /clp:summary) & shift & goto CheckOpts -if "%~1"=="-k" (set kill=true) & shift & goto CheckOpts -if "%~1"=="--pgo" (set do_pgo=true) & shift & goto CheckOpts -if "%~1"=="--pgo-job" (set do_pgo=true) & (set pgo_job=%~2) & shift & shift & goto CheckOpts -if "%~1"=="--test-marker" (set UseTestMarker=true) & shift & goto CheckOpts -if "%~1"=="-V" shift & goto Version -if "%~1"=="--regen" (set Regen=true) & shift & goto CheckOpts -rem These use the actual property names used by MSBuild. We could just let -rem them in through the environment, but we specify them on the command line -rem anyway for visibility so set defaults after this -if "%~1"=="-e" (set IncludeExternals=true) & shift & goto CheckOpts -if "%~1"=="-E" (set IncludeExternals=false) & shift & goto CheckOpts -if "%~1"=="--no-ctypes" (set IncludeCTypes=false) & shift & goto CheckOpts -if "%~1"=="--no-ssl" (set IncludeSSL=false) & shift & goto CheckOpts -if "%~1"=="--no-tkinter" (set IncludeTkinter=false) & shift & goto CheckOpts - -if "%IncludeExternals%"=="" set IncludeExternals=true -if "%IncludeCTypes%"=="" set IncludeCTypes=true -if "%IncludeSSL%"=="" set IncludeSSL=true -if "%IncludeTkinter%"=="" set IncludeTkinter=true - -if "%IncludeExternals%"=="true" call "%dir%get_externals.bat" - -if "%do_pgo%" EQU "true" if "%platf%" EQU "x64" ( - if "%PROCESSOR_ARCHITEW6432%" NEQ "AMD64" if "%PROCESSOR_ARCHITECTURE%" NEQ "AMD64" ( - echo.ERROR: Cannot cross-compile with PGO - echo. 32bit operating system detected. Ensure your PROCESSOR_ARCHITECTURE - echo. and PROCESSOR_ARCHITEW6432 environment variables are correct. - exit /b 1 - ) -) - -if not exist "%GIT%" where git > "%TEMP%\git.loc" 2> nul && set /P GIT= < "%TEMP%\git.loc" & del "%TEMP%\git.loc" -if exist "%GIT%" set GITProperty=/p:GIT="%GIT%" -if not exist "%GIT%" echo Cannot find Git on PATH & set GITProperty= - -rem Setup the environment -call "%dir%find_msbuild.bat" %MSBUILD% -if ERRORLEVEL 1 (echo Cannot locate MSBuild.exe on PATH or as MSBUILD variable & exit /b 2) - -call "%dir%find_python.bat" %PYTHON% -if ERRORLEVEL 1 (echo Cannot locate python.exe on PATH or as PYTHON variable & exit /b 3) -set PythonForBuild=%PYTHON% - -if "%kill%"=="true" call :Kill -if ERRORLEVEL 1 exit /B %ERRORLEVEL% - -if "%regen%"=="true" goto :Regen - -if "%do_pgo%"=="true" ( - set conf=PGInstrument - call :Build %1 %2 %3 %4 %5 %6 %7 %8 %9 -) -rem %VARS% are evaluated eagerly, which would lose the ERRORLEVEL -rem value if we didn't split it out here. -if "%do_pgo%"=="true" if ERRORLEVEL 1 exit /B %ERRORLEVEL% -if "%do_pgo%"=="true" ( - del /s "%dir%\*.pgc" - del /s "%dir%\..\Lib\*.pyc" - echo on - call "%dir%\..\python.bat" %pgo_job% - @echo off - call :Kill - set conf=PGUpdate - set target=Build -) -goto :Build - -:Kill -echo on -%MSBUILD% "%dir%\pythoncore.vcxproj" /t:KillPython %verbose%^ - /p:Configuration=%conf% /p:Platform=%platf%^ - /p:KillPython=true - -@echo off -exit /B %ERRORLEVEL% - -:Regen -echo on -%MSBUILD% "%dir%\pythoncore.vcxproj" /t:Regen %verbose%^ - /p:Configuration=%conf% /p:Platform=%platf%^ - /p:ForceRegen=true - -@echo off -exit /B %ERRORLEVEL% - -:Build -rem Call on MSBuild to do the work, echo the command. -rem Passing %1-9 is not the preferred option, but argument parsing in -rem batch is, shall we say, "lackluster" -echo on -%MSBUILD% "%dir%pcbuild.proj" /t:%target% %parallel% %verbose%^ - /p:Configuration=%conf% /p:Platform=%platf%^ - /p:IncludeExternals=%IncludeExternals%^ - /p:IncludeCTypes=%IncludeCTypes%^ - /p:IncludeSSL=%IncludeSSL% /p:IncludeTkinter=%IncludeTkinter%^ - /p:UseTestMarker=%UseTestMarker% %GITProperty%^ - %1 %2 %3 %4 %5 %6 %7 %8 %9 - -@echo off -exit /b %ERRORLEVEL% - -:Version -rem Display the current build version information -call "%dir%find_msbuild.bat" %MSBUILD% -if ERRORLEVEL 1 (echo Cannot locate MSBuild.exe on PATH or as MSBUILD variable & exit /b 2) -%MSBUILD% "%dir%pythoncore.vcxproj" /t:ShowVersionInfo /v:m /nologo %1 %2 %3 %4 %5 %6 %7 %8 %9 +@echo off +goto Run +:Usage +echo.%~nx0 [flags and arguments] [quoted MSBuild options] +echo. +echo.Build CPython from the command line. Requires the appropriate +echo.version(s) of Microsoft Visual Studio to be installed (see readme.txt). +echo. +echo.After the flags recognized by this script, up to 9 arguments to be passed +echo.directly to MSBuild may be passed. If the argument contains an '=', the +echo.entire argument must be quoted (e.g. `%~nx0 "/p:PlatformToolset=v100"`). +echo.Alternatively you can put extra flags for MSBuild in a file named +echo.`msbuild.rsp` in the `PCbuild` directory, one flag per line. This file +echo.will be picked automatically by MSBuild. Flags put in this file does not +echo.need to be quoted. You can still use environment variables inside the +echo.response file. +echo. +echo.Available flags: +echo. -h Display this help message +echo. -V Display version information for the current build +echo. -r Target Rebuild instead of Build +echo. -d Set the configuration to Debug +echo. -E Don't fetch or build external libraries. Extension modules that +echo. depend on external libraries will not attempt to build if this flag +echo. is present; -e is also accepted to explicitly enable fetching and +echo. building externals. +echo. -m Enable parallel build (enabled by default) +echo. -M Disable parallel build +echo. -v Increased output messages +echo. -vv Verbose output messages +echo. -q Quiet output messages (errors and warnings only) +echo. -k Attempt to kill any running Pythons before building (usually done +echo. automatically by the pythoncore project) +echo. --pgo Build with Profile-Guided Optimization. This flag +echo. overrides -c and -d +echo. --test-marker Enable the test marker within the build. +echo. --regen Regenerate all opcodes, grammar and tokens. +echo. +echo.Available flags to avoid building certain modules. +echo.These flags have no effect if '-e' is not given: +echo. --no-ctypes Do not attempt to build _ctypes +echo. --no-ssl Do not attempt to build _ssl +echo. --no-tkinter Do not attempt to build Tkinter +echo. +echo.Available arguments: +echo. -c Release ^| Debug ^| PGInstrument ^| PGUpdate +echo. Set the configuration (default: Release) +echo. -p x64 ^| Win32 ^| ARM ^| ARM64 +echo. Set the platform (default: x64) +echo. -t Build ^| Rebuild ^| Clean ^| CleanAll +echo. Set the target manually +echo. --pgo-job The job to use for PGO training; implies --pgo +echo. (default: "-m test --pgo") +exit /b 127 + +:Run +setlocal +set platf=x64 +set conf=Release +set target=Build +set dir=%~dp0 +set parallel=/m +set verbose=/nologo /v:m /clp:summary +set kill= +set do_pgo= +set pgo_job=-m test --pgo + +:CheckOpts +if "%~1"=="-h" goto Usage +if "%~1"=="-c" (set conf=%2) & shift & shift & goto CheckOpts +if "%~1"=="-p" (set platf=%2) & shift & shift & goto CheckOpts +if "%~1"=="-r" (set target=Rebuild) & shift & goto CheckOpts +if "%~1"=="-t" (set target=%2) & shift & shift & goto CheckOpts +if "%~1"=="-d" (set conf=Debug) & shift & goto CheckOpts +if "%~1"=="-m" (set parallel=/m) & shift & goto CheckOpts +if "%~1"=="-M" (set parallel=) & shift & goto CheckOpts +if "%~1"=="-v" (set verbose=/v:n) & shift & goto CheckOpts +if "%~1"=="-vv" (set verbose=/v:d /ds) & shift & goto CheckOpts +if "%~1"=="-q" (set verbose=/v:q /nologo /clp:summary) & shift & goto CheckOpts +if "%~1"=="-k" (set kill=true) & shift & goto CheckOpts +if "%~1"=="--pgo" (set do_pgo=true) & shift & goto CheckOpts +if "%~1"=="--pgo-job" (set do_pgo=true) & (set pgo_job=%~2) & shift & shift & goto CheckOpts +if "%~1"=="--test-marker" (set UseTestMarker=true) & shift & goto CheckOpts +if "%~1"=="-V" shift & goto Version +if "%~1"=="--regen" (set Regen=true) & shift & goto CheckOpts +rem These use the actual property names used by MSBuild. We could just let +rem them in through the environment, but we specify them on the command line +rem anyway for visibility so set defaults after this +if "%~1"=="-e" (set IncludeExternals=true) & shift & goto CheckOpts +if "%~1"=="-E" (set IncludeExternals=false) & shift & goto CheckOpts +if "%~1"=="--no-ctypes" (set IncludeCTypes=false) & shift & goto CheckOpts +if "%~1"=="--no-ssl" (set IncludeSSL=false) & shift & goto CheckOpts +if "%~1"=="--no-tkinter" (set IncludeTkinter=false) & shift & goto CheckOpts + +if "%IncludeExternals%"=="" set IncludeExternals=true +if "%IncludeCTypes%"=="" set IncludeCTypes=true +if "%IncludeSSL%"=="" set IncludeSSL=true +if "%IncludeTkinter%"=="" set IncludeTkinter=true + +if "%IncludeExternals%"=="true" call "%dir%get_externals.bat" + +if "%do_pgo%" EQU "true" if "%platf%" EQU "x64" ( + if "%PROCESSOR_ARCHITEW6432%" NEQ "AMD64" if "%PROCESSOR_ARCHITECTURE%" NEQ "AMD64" ( + echo.ERROR: Cannot cross-compile with PGO + echo. 32bit operating system detected. Ensure your PROCESSOR_ARCHITECTURE + echo. and PROCESSOR_ARCHITEW6432 environment variables are correct. + exit /b 1 + ) +) + +if not exist "%GIT%" where git > "%TEMP%\git.loc" 2> nul && set /P GIT= < "%TEMP%\git.loc" & del "%TEMP%\git.loc" +if exist "%GIT%" set GITProperty=/p:GIT="%GIT%" +if not exist "%GIT%" echo Cannot find Git on PATH & set GITProperty= + +rem Setup the environment +call "%dir%find_msbuild.bat" %MSBUILD% +if ERRORLEVEL 1 (echo Cannot locate MSBuild.exe on PATH or as MSBUILD variable & exit /b 2) + +call "%dir%find_python.bat" %PYTHON% +if ERRORLEVEL 1 (echo Cannot locate python.exe on PATH or as PYTHON variable & exit /b 3) +set PythonForBuild=%PYTHON% + +if "%kill%"=="true" call :Kill +if ERRORLEVEL 1 exit /B %ERRORLEVEL% + +if "%regen%"=="true" goto :Regen + +if "%do_pgo%"=="true" ( + set conf=PGInstrument + call :Build %1 %2 %3 %4 %5 %6 %7 %8 %9 +) +rem %VARS% are evaluated eagerly, which would lose the ERRORLEVEL +rem value if we didn't split it out here. +if "%do_pgo%"=="true" if ERRORLEVEL 1 exit /B %ERRORLEVEL% +if "%do_pgo%"=="true" ( + del /s "%dir%\*.pgc" + del /s "%dir%\..\Lib\*.pyc" + echo on + call "%dir%\..\python.bat" %pgo_job% + @echo off + call :Kill + set conf=PGUpdate + set target=Build +) +goto :Build + +:Kill +echo on +%MSBUILD% "%dir%\pythoncore.vcxproj" /t:KillPython %verbose%^ + /p:Configuration=%conf% /p:Platform=%platf%^ + /p:KillPython=true + +@echo off +exit /B %ERRORLEVEL% + +:Regen +echo on +%MSBUILD% "%dir%\pythoncore.vcxproj" /t:Regen %verbose%^ + /p:Configuration=%conf% /p:Platform=%platf%^ + /p:ForceRegen=true + +@echo off +exit /B %ERRORLEVEL% + +:Build +rem Call on MSBuild to do the work, echo the command. +rem Passing %1-9 is not the preferred option, but argument parsing in +rem batch is, shall we say, "lackluster" +echo on +%MSBUILD% "%dir%pcbuild.proj" /t:%target% %parallel% %verbose%^ + /p:Configuration=%conf% /p:Platform=%platf%^ + /p:IncludeExternals=%IncludeExternals%^ + /p:IncludeCTypes=%IncludeCTypes%^ + /p:IncludeSSL=%IncludeSSL% /p:IncludeTkinter=%IncludeTkinter%^ + /p:UseTestMarker=%UseTestMarker% %GITProperty%^ + %1 %2 %3 %4 %5 %6 %7 %8 %9 + +@echo off +exit /b %ERRORLEVEL% + +:Version +rem Display the current build version information +call "%dir%find_msbuild.bat" %MSBUILD% +if ERRORLEVEL 1 (echo Cannot locate MSBuild.exe on PATH or as MSBUILD variable & exit /b 2) +%MSBUILD% "%dir%pythoncore.vcxproj" /t:ShowVersionInfo /v:m /nologo %1 %2 %3 %4 %5 %6 %7 %8 %9 if ERRORLEVEL 1 exit /b 3 \ No newline at end of file diff --git a/PCbuild/build_env.bat b/PCbuild/build_env.bat index 01024cff..4c67ae3a 100644 --- a/PCbuild/build_env.bat +++ b/PCbuild/build_env.bat @@ -1 +1 @@ -@%comspec% /k env.bat %* +@%comspec% /k env.bat %* diff --git a/PCbuild/clean.bat b/PCbuild/clean.bat index 6c0a1a0f..d75198ae 100644 --- a/PCbuild/clean.bat +++ b/PCbuild/clean.bat @@ -1,5 +1,5 @@ -@echo off -rem A batch program to clean a particular configuration, -rem just for convenience. - -call "%~dp0build.bat" -t Clean %* +@echo off +rem A batch program to clean a particular configuration, +rem just for convenience. + +call "%~dp0build.bat" -t Clean %* diff --git a/PCbuild/env.bat b/PCbuild/env.bat index 31c67d4d..2820e304 100644 --- a/PCbuild/env.bat +++ b/PCbuild/env.bat @@ -1,27 +1,27 @@ -@echo off -rem This script adds the latest available tools to the path for the current -rem command window. However, most builds of Python will ignore the version -rem of the tools on PATH and use PlatformToolset instead. Ideally, both sets of -rem tools should be the same version to avoid potential conflicts. -rem -rem To build Python with an earlier toolset, pass "/p:PlatformToolset=v100" (or -rem 'v110', 'v120' or 'v140') to the build script. - -echo Build environments: x86, amd64, x86_amd64 -echo. -set _ARGS=%* -if NOT DEFINED _ARGS set _ARGS=amd64 - -if not exist "%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" goto :skip_vswhere -set VSTOOLS= -for /F "tokens=*" %%i in ('"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -property installationPath -latest -prerelease -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64') DO @(set VSTOOLS=%%i\VC\Auxiliary\Build\vcvarsall.bat) -if not defined VSTOOLS goto :skip_vswhere -call "%VSTOOLS%" %_ARGS% -exit /B 0 - -:skip_vswhere -if not defined VSTOOLS set VSTOOLS=%VS140COMNTOOLS% -if not defined VSTOOLS set VSTOOLS=%VS120COMNTOOLS% -if not defined VSTOOLS set VSTOOLS=%VS110COMNTOOLS% -if not defined VSTOOLS set VSTOOLS=%VS100COMNTOOLS% -call "%VSTOOLS%..\..\VC\vcvarsall.bat" %_ARGS% +@echo off +rem This script adds the latest available tools to the path for the current +rem command window. However, most builds of Python will ignore the version +rem of the tools on PATH and use PlatformToolset instead. Ideally, both sets of +rem tools should be the same version to avoid potential conflicts. +rem +rem To build Python with an earlier toolset, pass "/p:PlatformToolset=v100" (or +rem 'v110', 'v120' or 'v140') to the build script. + +echo Build environments: x86, amd64, x86_amd64 +echo. +set _ARGS=%* +if NOT DEFINED _ARGS set _ARGS=amd64 + +if not exist "%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" goto :skip_vswhere +set VSTOOLS= +for /F "tokens=*" %%i in ('"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -property installationPath -latest -prerelease -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64') DO @(set VSTOOLS=%%i\VC\Auxiliary\Build\vcvarsall.bat) +if not defined VSTOOLS goto :skip_vswhere +call "%VSTOOLS%" %_ARGS% +exit /B 0 + +:skip_vswhere +if not defined VSTOOLS set VSTOOLS=%VS140COMNTOOLS% +if not defined VSTOOLS set VSTOOLS=%VS120COMNTOOLS% +if not defined VSTOOLS set VSTOOLS=%VS110COMNTOOLS% +if not defined VSTOOLS set VSTOOLS=%VS100COMNTOOLS% +call "%VSTOOLS%..\..\VC\vcvarsall.bat" %_ARGS% diff --git a/PCbuild/env.ps1 b/PCbuild/env.ps1 index 8ba1fa4c..19d7ada4 100644 --- a/PCbuild/env.ps1 +++ b/PCbuild/env.ps1 @@ -1,2 +1,2 @@ -$pcbuild = $script:MyInvocation.MyCommand.Path | Split-Path -parent; -& cmd /K "$pcbuild\env.bat" $args +$pcbuild = $script:MyInvocation.MyCommand.Path | Split-Path -parent; +& cmd /K "$pcbuild\env.bat" $args diff --git a/PCbuild/find_msbuild.bat b/PCbuild/find_msbuild.bat index 61e61358..ce7e71ef 100644 --- a/PCbuild/find_msbuild.bat +++ b/PCbuild/find_msbuild.bat @@ -1,63 +1,63 @@ -@rem -@rem Searches for MSBuild.exe. This is the only tool we need to initiate -@rem a build, so we no longer search for the full VC toolset. -@rem -@rem This file is supposed to modify the state of the caller (specifically -@rem the MSBUILD variable), so we do not use setlocal or echo, and avoid -@rem changing any other persistent state. -@rem - -@rem No arguments provided means do full search -@if '%1' EQU '' goto :begin_search - -@rem One argument may be the full path. Use a goto so we don't try to -@rem parse the next if statement - incorrect quoting in the multi-arg -@rem case can cause us to break immediately. -@if '%2' EQU '' goto :one_arg - -@rem Entire command line may represent the full path if quoting failed. -@if exist "%*" (set MSBUILD="%*") & (set _Py_MSBuild_Source=environment) & goto :found -@goto :begin_search - -:one_arg -@if exist "%~1" (set MSBUILD="%~1") & (set _Py_MSBuild_Source=environment) & goto :found - -:begin_search -@set MSBUILD= - -@rem If msbuild.exe is on the PATH, assume that the user wants that one. -@where msbuild > "%TEMP%\msbuild.loc" 2> nul && set /P MSBUILD= < "%TEMP%\msbuild.loc" & del "%TEMP%\msbuild.loc" -@if exist "%MSBUILD%" set MSBUILD="%MSBUILD%" & (set _Py_MSBuild_Source=PATH) & goto :found - -@rem VS 2017 and later provide vswhere.exe, which can be used -@if not exist "%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" goto :skip_vswhere -@set _Py_MSBuild_Root= -@for /F "tokens=*" %%i in ('"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -property installationPath -latest -prerelease -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64') DO @(set _Py_MSBuild_Root=%%i\MSBuild) -@if not defined _Py_MSBuild_Root goto :skip_vswhere -@for %%j in (Current 15.0) DO @if exist "%_Py_MSBuild_Root%\%%j\Bin\msbuild.exe" (set MSBUILD="%_Py_MSBuild_Root%\%%j\Bin\msbuild.exe") -@set _Py_MSBuild_Root= -@if defined MSBUILD @if exist %MSBUILD% (set _Py_MSBuild_Source=Visual Studio installation) & goto :found -:skip_vswhere - -@rem VS 2015 and earlier register MSBuild separately, so we can find it. -@reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSBuild\ToolsVersions\14.0" /v MSBuildToolsPath /reg:32 >nul 2>nul -@if NOT ERRORLEVEL 1 @for /F "tokens=1,2*" %%i in ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSBuild\ToolsVersions\14.0" /v MSBuildToolsPath /reg:32') DO @( - @if "%%i"=="MSBuildToolsPath" @if exist "%%k\msbuild.exe" @(set MSBUILD="%%k\msbuild.exe") -) -@if exist %MSBUILD% (set _Py_MSBuild_Source=registry) & goto :found - - -@exit /b 1 - -:found -@pushd %MSBUILD% >nul 2>nul -@if not ERRORLEVEL 1 @( - @if exist msbuild.exe @(set MSBUILD="%CD%\msbuild.exe") else @(set MSBUILD=) - @popd -) - -@if defined MSBUILD @echo Using %MSBUILD% (found in the %_Py_MSBuild_Source%) -@if not defined MSBUILD @echo Failed to find MSBuild -@set _Py_MSBuild_Source= -@if not defined MSBUILD @exit /b 1 -@exit /b 0 +@rem +@rem Searches for MSBuild.exe. This is the only tool we need to initiate +@rem a build, so we no longer search for the full VC toolset. +@rem +@rem This file is supposed to modify the state of the caller (specifically +@rem the MSBUILD variable), so we do not use setlocal or echo, and avoid +@rem changing any other persistent state. +@rem + +@rem No arguments provided means do full search +@if '%1' EQU '' goto :begin_search + +@rem One argument may be the full path. Use a goto so we don't try to +@rem parse the next if statement - incorrect quoting in the multi-arg +@rem case can cause us to break immediately. +@if '%2' EQU '' goto :one_arg + +@rem Entire command line may represent the full path if quoting failed. +@if exist "%*" (set MSBUILD="%*") & (set _Py_MSBuild_Source=environment) & goto :found +@goto :begin_search + +:one_arg +@if exist "%~1" (set MSBUILD="%~1") & (set _Py_MSBuild_Source=environment) & goto :found + +:begin_search +@set MSBUILD= + +@rem If msbuild.exe is on the PATH, assume that the user wants that one. +@where msbuild > "%TEMP%\msbuild.loc" 2> nul && set /P MSBUILD= < "%TEMP%\msbuild.loc" & del "%TEMP%\msbuild.loc" +@if exist "%MSBUILD%" set MSBUILD="%MSBUILD%" & (set _Py_MSBuild_Source=PATH) & goto :found + +@rem VS 2017 and later provide vswhere.exe, which can be used +@if not exist "%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" goto :skip_vswhere +@set _Py_MSBuild_Root= +@for /F "tokens=*" %%i in ('"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -property installationPath -latest -prerelease -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64') DO @(set _Py_MSBuild_Root=%%i\MSBuild) +@if not defined _Py_MSBuild_Root goto :skip_vswhere +@for %%j in (Current 15.0) DO @if exist "%_Py_MSBuild_Root%\%%j\Bin\msbuild.exe" (set MSBUILD="%_Py_MSBuild_Root%\%%j\Bin\msbuild.exe") +@set _Py_MSBuild_Root= +@if defined MSBUILD @if exist %MSBUILD% (set _Py_MSBuild_Source=Visual Studio installation) & goto :found +:skip_vswhere + +@rem VS 2015 and earlier register MSBuild separately, so we can find it. +@reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSBuild\ToolsVersions\14.0" /v MSBuildToolsPath /reg:32 >nul 2>nul +@if NOT ERRORLEVEL 1 @for /F "tokens=1,2*" %%i in ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSBuild\ToolsVersions\14.0" /v MSBuildToolsPath /reg:32') DO @( + @if "%%i"=="MSBuildToolsPath" @if exist "%%k\msbuild.exe" @(set MSBUILD="%%k\msbuild.exe") +) +@if exist %MSBUILD% (set _Py_MSBuild_Source=registry) & goto :found + + +@exit /b 1 + +:found +@pushd %MSBUILD% >nul 2>nul +@if not ERRORLEVEL 1 @( + @if exist msbuild.exe @(set MSBUILD="%CD%\msbuild.exe") else @(set MSBUILD=) + @popd +) + +@if defined MSBUILD @echo Using %MSBUILD% (found in the %_Py_MSBuild_Source%) +@if not defined MSBUILD @echo Failed to find MSBuild +@set _Py_MSBuild_Source= +@if not defined MSBUILD @exit /b 1 +@exit /b 0 diff --git a/PCbuild/find_python.bat b/PCbuild/find_python.bat index acb81a21..d3f62c93 100644 --- a/PCbuild/find_python.bat +++ b/PCbuild/find_python.bat @@ -1,89 +1,93 @@ -@rem -@rem Searches for python.exe and may download a private copy from nuget. -@rem -@rem This file is supposed to modify the state of the caller (specifically -@rem the MSBUILD variable), so we do not use setlocal or echo, and avoid -@rem changing any other persistent state. -@rem - -@set _Py_D=%~dp0 - -@rem First argument -q means only show the command in output -@if '%1' EQU '-q' (shift && set _Py_Quiet=1) - -@rem No arguments provided means do full search -@if '%1' EQU '' goto :begin_search - -@rem One argument may be the full path. Use a goto so we don't try to -@rem parse the next if statement - incorrect quoting in the multi-arg -@rem case can cause us to break immediately. -@if '%2' EQU '' goto :one_arg - -@rem Entire command line may represent the full path if quoting failed. -@if exist "%*" (set PYTHON="%*") & (set _Py_Python_Source=from environment) & goto :found -@goto :begin_search - -:one_arg -@if exist "%~1" (set PYTHON="%~1") & (set _Py_Python_Source=from environment) & goto :found - -:begin_search -@set PYTHON= - -@rem If there is an active virtual env, use that one -@if NOT "%VIRTUAL_ENV%"=="" (set PYTHON="%VIRTUAL_ENV%\Scripts\python.exe") & (set _Py_Python_Source=found in virtual env) & goto :found - -@set _Py_EXTERNALS_DIR=%EXTERNALS_DIR% -@if "%_Py_EXTERNALS_DIR%"=="" (set _Py_EXTERNALS_DIR=%_Py_D%\..\externals) - -@rem If we have Python in externals, use that one -@if exist "%_Py_EXTERNALS_DIR%\pythonx86\tools\python.exe" ("%_Py_EXTERNALS_DIR%\pythonx86\tools\python.exe" -Ec "import sys; assert sys.version_info[:2] >= (3, 8)" >nul 2>nul) && (set PYTHON="%_Py_EXTERNALS_DIR%\pythonx86\tools\python.exe") && (set _Py_Python_Source=found in externals directory) && goto :found || rmdir /Q /S "%_Py_EXTERNALS_DIR%\pythonx86" - -@rem If HOST_PYTHON is recent enough, use that -@if NOT "%HOST_PYTHON%"=="" @%HOST_PYTHON% -Ec "import sys; assert sys.version_info[:2] >= (3, 9)" >nul 2>nul && (set PYTHON="%HOST_PYTHON%") && (set _Py_Python_Source=found as HOST_PYTHON) && goto :found - -@rem If py.exe finds a recent enough version, use that one -@for %%p in (3.10 3.9) do @py -%%p -EV >nul 2>&1 && (set PYTHON=py -%%p) && (set _Py_Python_Source=found %%p with py.exe) && goto :found - -@if NOT exist "%_Py_EXTERNALS_DIR%" mkdir "%_Py_EXTERNALS_DIR%" -@set _Py_NUGET=%NUGET% -@set _Py_NUGET_URL=%NUGET_URL% -@set _Py_HOST_PYTHON=%HOST_PYTHON% -@if "%_Py_HOST_PYTHON%"=="" set _Py_HOST_PYTHON=py -@if "%_Py_NUGET%"=="" (set _Py_NUGET=%_Py_EXTERNALS_DIR%\nuget.exe) -@if "%_Py_NUGET_URL%"=="" (set _Py_NUGET_URL=https://aka.ms/nugetclidl) -@if NOT exist "%_Py_NUGET%" ( - @echo Downloading nuget... - @rem NB: Must use single quotes around NUGET here, NOT double! - @rem Otherwise, a space in the path would break things - @rem If it fails, retry with any available copy of Python - @powershell.exe -Command Invoke-WebRequest %_Py_NUGET_URL% -OutFile '%_Py_NUGET%' - @if errorlevel 1 ( - @%_Py_HOST_PYTHON% -E "%_Py_D%\urlretrieve.py" "%_Py_NUGET_URL%" "%_Py_NUGET%" - ) -) - -@if not "%_Py_Quiet%"=="1" @echo Installing Python via nuget... -@"%_Py_NUGET%" install pythonx86 -ExcludeVersion -OutputDirectory "%_Py_EXTERNALS_DIR%" -@rem Quote it here; it's not quoted later because "py -x.y" wouldn't work -@if not errorlevel 1 (set PYTHON="%_Py_EXTERNALS_DIR%\pythonx86\tools\python.exe") & (set _Py_Python_Source=found on nuget.org) & goto :found - - -@set _Py_D= -@set _Py_Quiet= -@set _Py_Python_Source= -@set _Py_EXTERNALS_DIR= -@set _Py_NUGET= -@set _Py_NUGET_URL= -@set _Py_HOST_PYTHON= -@exit /b 1 - -:found -@if "%_Py_Quiet%"=="1" (@echo %PYTHON%) else @echo Using %PYTHON% (%_Py_Python_Source%) - -@set _Py_D= -@set _Py_Quiet= -@set _Py_Python_Source= -@set _Py_EXTERNALS_DIR= -@set _Py_NUGET= -@set _Py_NUGET_URL= -@set _Py_HOST_PYTHON= +@rem +@rem Searches for python.exe and may download a private copy from nuget. +@rem +@rem This file is supposed to modify the state of the caller (specifically +@rem the MSBUILD variable), so we do not use setlocal or echo, and avoid +@rem changing any other persistent state. +@rem + +@set _Py_D=%~dp0 + +@rem First argument -q means only show the command in output +@if '%1' EQU '-q' (shift && set _Py_Quiet=1) + +@rem No arguments provided means do full search +@if '%1' EQU '' goto :begin_search + +@rem One argument may be the full path. Use a goto so we don't try to +@rem parse the next if statement - incorrect quoting in the multi-arg +@rem case can cause us to break immediately. +@if '%2' EQU '' goto :one_arg + +@rem Entire command line may represent the full path if quoting failed. +@if exist "%*" (set PYTHON="%*") & (set _Py_Python_Source=from environment) & goto :found +@goto :begin_search + +:one_arg +@if exist "%~1" (set PYTHON="%~1") & (set _Py_Python_Source=from environment) & goto :found + +:begin_search +@set PYTHON= + +@rem If there is an active virtual env, use that one +@if NOT "%VIRTUAL_ENV%"=="" (set PYTHON="%VIRTUAL_ENV%\Scripts\python.exe") & (set _Py_Python_Source=found in virtual env) & goto :found + +@set _Py_EXTERNALS_DIR=%EXTERNALS_DIR% +@if "%_Py_EXTERNALS_DIR%"=="" (set _Py_EXTERNALS_DIR=%_Py_D%\..\externals) + +@rem If we have Python in externals, use that one +@if exist "%_Py_EXTERNALS_DIR%\pythonx86\tools\python.exe" ("%_Py_EXTERNALS_DIR%\pythonx86\tools\python.exe" -Ec "import sys; assert sys.version_info[:2] >= (3, 8)" >nul 2>nul) && (set PYTHON="%_Py_EXTERNALS_DIR%\pythonx86\tools\python.exe") && (set _Py_Python_Source=found in externals directory) && goto :found || rmdir /Q /S "%_Py_EXTERNALS_DIR%\pythonx86" + +@rem If HOST_PYTHON is recent enough, use that +@if NOT "%HOST_PYTHON%"=="" @%HOST_PYTHON% -Ec "import sys; assert sys.version_info[:2] >= (3, 9)" >nul 2>nul && (set PYTHON="%HOST_PYTHON%") && (set _Py_Python_Source=found as HOST_PYTHON) && goto :found + +@rem If py.exe finds a recent enough version, use that one +@for %%p in (3.11 3.10 3.9) do @py -%%p -EV >nul 2>&1 && (set PYTHON=py -%%p) && (set _Py_Python_Source=found %%p with py.exe) && goto :found + +@if NOT exist "%_Py_EXTERNALS_DIR%" mkdir "%_Py_EXTERNALS_DIR%" +@set _Py_NUGET=%NUGET% +@set _Py_NUGET_URL=%NUGET_URL% +@set _Py_HOST_PYTHON=%HOST_PYTHON% +@if "%_Py_HOST_PYTHON%"=="" set _Py_HOST_PYTHON=py +@if "%_Py_NUGET%"=="" (set _Py_NUGET=%_Py_EXTERNALS_DIR%\nuget.exe) +@if "%_Py_NUGET_URL%"=="" (set _Py_NUGET_URL=https://aka.ms/nugetclidl) +@if NOT exist "%_Py_NUGET%" ( + @if not "%_Py_Quiet%"=="1" @echo Downloading nuget... + @rem NB: Must use single quotes around NUGET here, NOT double! + @rem Otherwise, a space in the path would break things + @rem If it fails, retry with any available copy of Python + @powershell.exe -Command Invoke-WebRequest %_Py_NUGET_URL% -OutFile '%_Py_NUGET%' + @if errorlevel 1 ( + @%_Py_HOST_PYTHON% -E "%_Py_D%\urlretrieve.py" "%_Py_NUGET_URL%" "%_Py_NUGET%" + ) +) + +@if not "%_Py_Quiet%"=="1" @echo Installing Python via nuget... +@if not "%_Py_Quiet%"=="1" ( + @"%_Py_NUGET%" install pythonx86 -ExcludeVersion -OutputDirectory "%_Py_EXTERNALS_DIR%" +) else ( + @"%_Py_NUGET%" install pythonx86 -Verbosity quiet -ExcludeVersion -OutputDirectory "%_Py_EXTERNALS_DIR%" +) +@rem Quote it here; it's not quoted later because "py -x.y" wouldn't work +@if not errorlevel 1 (set PYTHON="%_Py_EXTERNALS_DIR%\pythonx86\tools\python.exe") & (set _Py_Python_Source=found on nuget.org) & goto :found + + +@set _Py_D= +@set _Py_Quiet= +@set _Py_Python_Source= +@set _Py_EXTERNALS_DIR= +@set _Py_NUGET= +@set _Py_NUGET_URL= +@set _Py_HOST_PYTHON= +@exit /b 1 + +:found +@if "%_Py_Quiet%"=="1" (@echo %PYTHON%) else @echo Using %PYTHON% (%_Py_Python_Source%) + +@set _Py_D= +@set _Py_Quiet= +@set _Py_Python_Source= +@set _Py_EXTERNALS_DIR= +@set _Py_NUGET= +@set _Py_NUGET_URL= +@set _Py_HOST_PYTHON= diff --git a/PCbuild/get_externals.bat b/PCbuild/get_externals.bat index 923ad22c..181ddfb6 100644 --- a/PCbuild/get_externals.bat +++ b/PCbuild/get_externals.bat @@ -1,117 +1,117 @@ -@echo off -setlocal -rem Simple script to fetch source for external libraries - -if NOT DEFINED PCBUILD (set PCBUILD=%~dp0) -if NOT DEFINED EXTERNALS_DIR (set EXTERNALS_DIR=%PCBUILD%\..\externals) - -set DO_FETCH=true -set DO_CLEAN=false -set IncludeLibffiSrc=false -set IncludeTkinterSrc=false -set IncludeSSLSrc=false - -:CheckOpts -if "%~1"=="--no-tkinter" (set IncludeTkinter=false) & shift & goto CheckOpts -if "%~1"=="--no-openssl" (set IncludeSSL=false) & shift & goto CheckOpts -if "%~1"=="--no-libffi" (set IncludeLibffi=false) & shift & goto CheckOpts -if "%~1"=="--tkinter-src" (set IncludeTkinterSrc=true) & shift & goto CheckOpts -if "%~1"=="--openssl-src" (set IncludeSSLSrc=true) & shift & goto CheckOpts -if "%~1"=="--libffi-src" (set IncludeLibffiSrc=true) & shift & goto CheckOpts -if "%~1"=="--python" (set PYTHON=%2) & shift & shift & goto CheckOpts -if "%~1"=="--organization" (set ORG=%2) & shift & shift & goto CheckOpts -if "%~1"=="-c" (set DO_CLEAN=true) & shift & goto CheckOpts -if "%~1"=="--clean" (set DO_CLEAN=true) & shift & goto CheckOpts -if "%~1"=="--clean-only" (set DO_FETCH=false) & goto clean - -rem Include old options for compatibility -if "%~1"=="--no-tkinter" shift & goto CheckOpts -if "%~1"=="--no-openssl" shift & goto CheckOpts - -if "x%~1" NEQ "x" goto usage - -if "%DO_CLEAN%"=="false" goto fetch -:clean -echo.Cleaning up external libraries. -if exist "%EXTERNALS_DIR%" ( - rem Sometimes this fails the first time; try it twice - rmdir /s /q "%EXTERNALS_DIR%" || rmdir /s /q "%EXTERNALS_DIR%" -) - -if "%DO_FETCH%"=="false" goto end -:fetch - -if "%ORG%"=="" (set ORG=python) -call "%PCBUILD%\find_python.bat" "%PYTHON%" - -if NOT DEFINED PYTHON ( - where /Q git || echo Python 3.6 could not be found or installed, and git.exe is not on your PATH && exit /B 1 -) - -echo.Fetching external libraries... - -set libraries= -set libraries=%libraries% bzip2-1.0.8 -if NOT "%IncludeLibffiSrc%"=="false" set libraries=%libraries% libffi-3.4.3 -if NOT "%IncludeSSLSrc%"=="false" set libraries=%libraries% openssl-1.1.1s -set libraries=%libraries% sqlite-3.39.4.0 -if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tcl-core-8.6.12.1 -if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tk-8.6.12.1 -if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tix-8.4.3.6 -set libraries=%libraries% xz-5.2.5 -set libraries=%libraries% zlib-1.2.13 - -for %%e in (%libraries%) do ( - if exist "%EXTERNALS_DIR%\%%e" ( - echo.%%e already exists, skipping. - ) else if NOT DEFINED PYTHON ( - echo.Fetching %%e with git... - git clone --depth 1 https://github.com/%ORG%/cpython-source-deps --branch %%e "%EXTERNALS_DIR%\%%e" - ) else ( - echo.Fetching %%e... - %PYTHON% -E "%PCBUILD%\get_external.py" -O %ORG% -e "%EXTERNALS_DIR%" %%e - ) -) - -echo.Fetching external binaries... - -set binaries= -if NOT "%IncludeLibffi%"=="false" set binaries=%binaries% libffi-3.4.3 -if NOT "%IncludeSSL%"=="false" set binaries=%binaries% openssl-bin-1.1.1s -if NOT "%IncludeTkinter%"=="false" set binaries=%binaries% tcltk-8.6.12.1 -if NOT "%IncludeSSLSrc%"=="false" set binaries=%binaries% nasm-2.11.06 - -for %%b in (%binaries%) do ( - if exist "%EXTERNALS_DIR%\%%b" ( - echo.%%b already exists, skipping. - ) else if NOT DEFINED PYTHON ( - echo.Fetching %%b with git... - git clone --depth 1 https://github.com/%ORG%/cpython-bin-deps --branch %%b "%EXTERNALS_DIR%\%%b" - ) else ( - echo.Fetching %%b... - %PYTHON% -E "%PCBUILD%\get_external.py" -b -O %ORG% -e "%EXTERNALS_DIR%" %%b - ) -) - -echo Finished. -goto end - -:usage -echo.Valid options: -c, --clean, --clean-only, --organization, --python, -echo.--no-tkinter, --no-openssl -echo. -echo.Pull all sources and binaries necessary for compiling optional extension -echo.modules that rely on external libraries. -echo. -echo.The --organization option determines which github organization to download -echo.from, the --python option determines which Python 3.6+ interpreter to use -echo.with PCbuild\get_external.py. -echo. -echo.Use the -c or --clean option to remove the entire externals directory. -echo. -echo.Use the --clean-only option to do the same cleaning, without pulling in -echo.anything new. -echo. -exit /b -1 - -:end +@echo off +setlocal +rem Simple script to fetch source for external libraries + +if NOT DEFINED PCBUILD (set PCBUILD=%~dp0) +if NOT DEFINED EXTERNALS_DIR (set EXTERNALS_DIR=%PCBUILD%\..\externals) + +set DO_FETCH=true +set DO_CLEAN=false +set IncludeLibffiSrc=false +set IncludeTkinterSrc=false +set IncludeSSLSrc=false + +:CheckOpts +if "%~1"=="--no-tkinter" (set IncludeTkinter=false) & shift & goto CheckOpts +if "%~1"=="--no-openssl" (set IncludeSSL=false) & shift & goto CheckOpts +if "%~1"=="--no-libffi" (set IncludeLibffi=false) & shift & goto CheckOpts +if "%~1"=="--tkinter-src" (set IncludeTkinterSrc=true) & shift & goto CheckOpts +if "%~1"=="--openssl-src" (set IncludeSSLSrc=true) & shift & goto CheckOpts +if "%~1"=="--libffi-src" (set IncludeLibffiSrc=true) & shift & goto CheckOpts +if "%~1"=="--python" (set PYTHON=%2) & shift & shift & goto CheckOpts +if "%~1"=="--organization" (set ORG=%2) & shift & shift & goto CheckOpts +if "%~1"=="-c" (set DO_CLEAN=true) & shift & goto CheckOpts +if "%~1"=="--clean" (set DO_CLEAN=true) & shift & goto CheckOpts +if "%~1"=="--clean-only" (set DO_FETCH=false) & goto clean + +rem Include old options for compatibility +if "%~1"=="--no-tkinter" shift & goto CheckOpts +if "%~1"=="--no-openssl" shift & goto CheckOpts + +if "x%~1" NEQ "x" goto usage + +if "%DO_CLEAN%"=="false" goto fetch +:clean +echo.Cleaning up external libraries. +if exist "%EXTERNALS_DIR%" ( + rem Sometimes this fails the first time; try it twice + rmdir /s /q "%EXTERNALS_DIR%" || rmdir /s /q "%EXTERNALS_DIR%" +) + +if "%DO_FETCH%"=="false" goto end +:fetch + +if "%ORG%"=="" (set ORG=python) +call "%PCBUILD%\find_python.bat" "%PYTHON%" + +if NOT DEFINED PYTHON ( + where /Q git || echo Python 3.6 could not be found or installed, and git.exe is not on your PATH && exit /B 1 +) + +echo.Fetching external libraries... + +set libraries= +set libraries=%libraries% bzip2-1.0.8 +if NOT "%IncludeLibffiSrc%"=="false" set libraries=%libraries% libffi-3.4.4 +if NOT "%IncludeSSLSrc%"=="false" set libraries=%libraries% openssl-3.0.11 +set libraries=%libraries% sqlite-3.42.0.0 +if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tcl-core-8.6.13.0 +if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tk-8.6.13.0 +if NOT "%IncludeTkinterSrc%"=="false" set libraries=%libraries% tix-8.4.3.6 +set libraries=%libraries% xz-5.2.5 +set libraries=%libraries% zlib-1.2.13 + +for %%e in (%libraries%) do ( + if exist "%EXTERNALS_DIR%\%%e" ( + echo.%%e already exists, skipping. + ) else if NOT DEFINED PYTHON ( + echo.Fetching %%e with git... + git clone --depth 1 https://github.com/%ORG%/cpython-source-deps --branch %%e "%EXTERNALS_DIR%\%%e" + ) else ( + echo.Fetching %%e... + %PYTHON% -E "%PCBUILD%\get_external.py" -O %ORG% -e "%EXTERNALS_DIR%" %%e + ) +) + +echo.Fetching external binaries... + +set binaries= +if NOT "%IncludeLibffi%"=="false" set binaries=%binaries% libffi-3.4.4 +if NOT "%IncludeSSL%"=="false" set binaries=%binaries% openssl-bin-3.0.11 +if NOT "%IncludeTkinter%"=="false" set binaries=%binaries% tcltk-8.6.13.0 +if NOT "%IncludeSSLSrc%"=="false" set binaries=%binaries% nasm-2.11.06 + +for %%b in (%binaries%) do ( + if exist "%EXTERNALS_DIR%\%%b" ( + echo.%%b already exists, skipping. + ) else if NOT DEFINED PYTHON ( + echo.Fetching %%b with git... + git clone --depth 1 https://github.com/%ORG%/cpython-bin-deps --branch %%b "%EXTERNALS_DIR%\%%b" + ) else ( + echo.Fetching %%b... + %PYTHON% -E "%PCBUILD%\get_external.py" -b -O %ORG% -e "%EXTERNALS_DIR%" %%b + ) +) + +echo Finished. +goto end + +:usage +echo.Valid options: -c, --clean, --clean-only, --organization, --python, +echo.--no-tkinter, --no-openssl +echo. +echo.Pull all sources and binaries necessary for compiling optional extension +echo.modules that rely on external libraries. +echo. +echo.The --organization option determines which github organization to download +echo.from, the --python option determines which Python 3.6+ interpreter to use +echo.with PCbuild\get_external.py. +echo. +echo.Use the -c or --clean option to remove the entire externals directory. +echo. +echo.Use the --clean-only option to do the same cleaning, without pulling in +echo.anything new. +echo. +exit /b -1 + +:end diff --git a/PCbuild/idle.bat b/PCbuild/idle.bat index 73eff5e4..70f3817f 100644 --- a/PCbuild/idle.bat +++ b/PCbuild/idle.bat @@ -1,27 +1,27 @@ -@echo off -rem start idle -rem Usage: idle [-d] -rem -d Run Debug build (python_d.exe). Else release build. - -setlocal -set PCBUILD=%~dp0 -set exedir=%PCBUILD%\amd64 -set exe=python -PATH %PATH%;..\externals\tcltk\bin - -:CheckOpts -if "%1"=="-d" (set exe=%exe%_d) & shift & goto :CheckOpts -if "%1"=="-p" (call :SetExeDir %2) & shift & shift & goto :CheckOpts - -set cmd=%exedir%\%exe% %PCBUILD%\..\Lib\idlelib\idle.py %1 %2 %3 %4 %5 %6 %7 %8 %9 - -echo on -%cmd% -exit /B %LASTERRORCODE% - -:SetExeDir -if /I %1 EQU Win32 (set exedir=%PCBUILD%\win32) -if /I %1 EQU x64 (set exedir=%PCBUILD%\amd64) -if /I %1 EQU ARM (set exedir=%PCBUILD%\arm32) -if /I %1 EQU ARM64 (set exedir=%PCBUILD%\arm64) -exit /B 0 +@echo off +rem start idle +rem Usage: idle [-d] +rem -d Run Debug build (python_d.exe). Else release build. + +setlocal +set PCBUILD=%~dp0 +set exedir=%PCBUILD%\amd64 +set exe=python +PATH %PATH%;..\externals\tcltk\bin + +:CheckOpts +if "%1"=="-d" (set exe=%exe%_d) & shift & goto :CheckOpts +if "%1"=="-p" (call :SetExeDir %2) & shift & shift & goto :CheckOpts + +set cmd=%exedir%\%exe% %PCBUILD%\..\Lib\idlelib\idle.py %1 %2 %3 %4 %5 %6 %7 %8 %9 + +echo on +%cmd% +exit /B %LASTERRORCODE% + +:SetExeDir +if /I %1 EQU Win32 (set exedir=%PCBUILD%\win32) +if /I %1 EQU x64 (set exedir=%PCBUILD%\amd64) +if /I %1 EQU ARM (set exedir=%PCBUILD%\arm32) +if /I %1 EQU ARM64 (set exedir=%PCBUILD%\arm64) +exit /B 0 diff --git a/PCbuild/lib.pyproj b/PCbuild/lib.pyproj deleted file mode 100644 index 43c570f1..00000000 --- a/PCbuild/lib.pyproj +++ /dev/null @@ -1,1830 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build"> - <PropertyGroup> - <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> - <SchemaVersion>2.0</SchemaVersion> - <ProjectGuid>{cb12a4c2-3757-4e67-8f51-c533876cefd1}</ProjectGuid> - <ProjectHome>..\Lib\</ProjectHome> - <StartupFile>abc.py</StartupFile> - <SearchPath /> - <WorkingDirectory>.</WorkingDirectory> - <OutputPath>.</OutputPath> - <ProjectTypeGuids>{888888a0-9f3d-457c-b088-3a5042f75d52}</ProjectTypeGuids> - <LaunchProvider>Standard Python launcher</LaunchProvider> - <InterpreterId /> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)' == 'Debug'" /> - <PropertyGroup Condition="'$(Configuration)' == 'Release'" /> - <PropertyGroup> - <VisualStudioVersion Condition=" '$(VisualStudioVersion)' == '' ">10.0</VisualStudioVersion> - </PropertyGroup> - <ItemGroup> - <Compile Include="abc.py" /> - <Compile Include="aifc.py" /> - <Compile Include="antigravity.py" /> - <Compile Include="argparse.py" /> - <Compile Include="ast.py" /> - <Compile Include="asynchat.py" /> - <Compile Include="asyncio\base_events.py" /> - <Compile Include="asyncio\base_futures.py" /> - <Compile Include="asyncio\base_subprocess.py" /> - <Compile Include="asyncio\base_tasks.py" /> - <Compile Include="asyncio\compat.py" /> - <Compile Include="asyncio\constants.py" /> - <Compile Include="asyncio\coroutines.py" /> - <Compile Include="asyncio\events.py" /> - <Compile Include="asyncio\futures.py" /> - <Compile Include="asyncio\locks.py" /> - <Compile Include="asyncio\log.py" /> - <Compile Include="asyncio\proactor_events.py" /> - <Compile Include="asyncio\protocols.py" /> - <Compile Include="asyncio\queues.py" /> - <Compile Include="asyncio\selector_events.py" /> - <Compile Include="asyncio\sslproto.py" /> - <Compile Include="asyncio\streams.py" /> - <Compile Include="asyncio\subprocess.py" /> - <Compile Include="asyncio\tasks.py" /> - <Compile Include="asyncio\test_utils.py" /> - <Compile Include="asyncio\transports.py" /> - <Compile Include="asyncio\unix_events.py" /> - <Compile Include="asyncio\windows_events.py" /> - <Compile Include="asyncio\windows_utils.py" /> - <Compile Include="asyncio\__init__.py" /> - <Compile Include="asyncore.py" /> - <Compile Include="base64.py" /> - <Compile Include="bdb.py" /> - <Compile Include="bisect.py" /> - <Compile Include="bz2.py" /> - <Compile Include="calendar.py" /> - <Compile Include="cgi.py" /> - <Compile Include="cgitb.py" /> - <Compile Include="chunk.py" /> - <Compile Include="cmd.py" /> - <Compile Include="code.py" /> - <Compile Include="codecs.py" /> - <Compile Include="codeop.py" /> - <Compile Include="collections\abc.py" /> - <Compile Include="collections\__init__.py" /> - <Compile Include="colorsys.py" /> - <Compile Include="compileall.py" /> - <Compile Include="concurrent\futures\process.py" /> - <Compile Include="concurrent\futures\thread.py" /> - <Compile Include="concurrent\futures\_base.py" /> - <Compile Include="concurrent\futures\__init__.py" /> - <Compile Include="concurrent\__init__.py" /> - <Compile Include="configparser.py" /> - <Compile Include="contextlib.py" /> - <Compile Include="copy.py" /> - <Compile Include="copyreg.py" /> - <Compile Include="cProfile.py" /> - <Compile Include="crypt.py" /> - <Compile Include="csv.py" /> - <Compile Include="ctypes\macholib\dyld.py" /> - <Compile Include="ctypes\macholib\dylib.py" /> - <Compile Include="ctypes\macholib\framework.py" /> - <Compile Include="ctypes\macholib\__init__.py" /> - <Compile Include="ctypes\test\test_anon.py" /> - <Compile Include="ctypes\test\test_arrays.py" /> - <Compile Include="ctypes\test\test_array_in_pointer.py" /> - <Compile Include="ctypes\test\test_as_parameter.py" /> - <Compile Include="ctypes\test\test_bitfields.py" /> - <Compile Include="ctypes\test\test_buffers.py" /> - <Compile Include="ctypes\test\test_bytes.py" /> - <Compile Include="ctypes\test\test_byteswap.py" /> - <Compile Include="ctypes\test\test_callbacks.py" /> - <Compile Include="ctypes\test\test_cast.py" /> - <Compile Include="ctypes\test\test_cfuncs.py" /> - <Compile Include="ctypes\test\test_checkretval.py" /> - <Compile Include="ctypes\test\test_delattr.py" /> - <Compile Include="ctypes\test\test_errno.py" /> - <Compile Include="ctypes\test\test_find.py" /> - <Compile Include="ctypes\test\test_frombuffer.py" /> - <Compile Include="ctypes\test\test_funcptr.py" /> - <Compile Include="ctypes\test\test_functions.py" /> - <Compile Include="ctypes\test\test_incomplete.py" /> - <Compile Include="ctypes\test\test_init.py" /> - <Compile Include="ctypes\test\test_internals.py" /> - <Compile Include="ctypes\test\test_keeprefs.py" /> - <Compile Include="ctypes\test\test_libc.py" /> - <Compile Include="ctypes\test\test_loading.py" /> - <Compile Include="ctypes\test\test_macholib.py" /> - <Compile Include="ctypes\test\test_memfunctions.py" /> - <Compile Include="ctypes\test\test_numbers.py" /> - <Compile Include="ctypes\test\test_objects.py" /> - <Compile Include="ctypes\test\test_parameters.py" /> - <Compile Include="ctypes\test\test_pep3118.py" /> - <Compile Include="ctypes\test\test_pickling.py" /> - <Compile Include="ctypes\test\test_pointers.py" /> - <Compile Include="ctypes\test\test_prototypes.py" /> - <Compile Include="ctypes\test\test_python_api.py" /> - <Compile Include="ctypes\test\test_random_things.py" /> - <Compile Include="ctypes\test\test_refcounts.py" /> - <Compile Include="ctypes\test\test_repr.py" /> - <Compile Include="ctypes\test\test_returnfuncptrs.py" /> - <Compile Include="ctypes\test\test_simplesubclasses.py" /> - <Compile Include="ctypes\test\test_sizes.py" /> - <Compile Include="ctypes\test\test_slicing.py" /> - <Compile Include="ctypes\test\test_stringptr.py" /> - <Compile Include="ctypes\test\test_strings.py" /> - <Compile Include="ctypes\test\test_structures.py" /> - <Compile Include="ctypes\test\test_struct_fields.py" /> - <Compile Include="ctypes\test\test_unaligned_structures.py" /> - <Compile Include="ctypes\test\test_unicode.py" /> - <Compile Include="ctypes\test\test_values.py" /> - <Compile Include="ctypes\test\test_varsize_struct.py" /> - <Compile Include="ctypes\test\test_win32.py" /> - <Compile Include="ctypes\test\test_wintypes.py" /> - <Compile Include="ctypes\test\__init__.py" /> - <Compile Include="ctypes\test\__main__.py" /> - <Compile Include="ctypes\util.py" /> - <Compile Include="ctypes\wintypes.py" /> - <Compile Include="ctypes\_endian.py" /> - <Compile Include="ctypes\__init__.py" /> - <Compile Include="curses\ascii.py" /> - <Compile Include="curses\has_key.py" /> - <Compile Include="curses\panel.py" /> - <Compile Include="curses\textpad.py" /> - <Compile Include="curses\__init__.py" /> - <Compile Include="datetime.py" /> - <Compile Include="dbm\dumb.py" /> - <Compile Include="dbm\gnu.py" /> - <Compile Include="dbm\ndbm.py" /> - <Compile Include="dbm\__init__.py" /> - <Compile Include="decimal.py" /> - <Compile Include="difflib.py" /> - <Compile Include="dis.py" /> - <Compile Include="distutils\archive_util.py" /> - <Compile Include="distutils\bcppcompiler.py" /> - <Compile Include="distutils\ccompiler.py" /> - <Compile Include="distutils\cmd.py" /> - <Compile Include="distutils\command\bdist.py" /> - <Compile Include="distutils\command\bdist_dumb.py" /> - <Compile Include="distutils\command\bdist_rpm.py" /> - <Compile Include="distutils\command\build.py" /> - <Compile Include="distutils\command\build_clib.py" /> - <Compile Include="distutils\command\build_ext.py" /> - <Compile Include="distutils\command\build_py.py" /> - <Compile Include="distutils\command\build_scripts.py" /> - <Compile Include="distutils\command\check.py" /> - <Compile Include="distutils\command\clean.py" /> - <Compile Include="distutils\command\config.py" /> - <Compile Include="distutils\command\install.py" /> - <Compile Include="distutils\command\install_data.py" /> - <Compile Include="distutils\command\install_egg_info.py" /> - <Compile Include="distutils\command\install_headers.py" /> - <Compile Include="distutils\command\install_lib.py" /> - <Compile Include="distutils\command\install_scripts.py" /> - <Compile Include="distutils\command\register.py" /> - <Compile Include="distutils\command\sdist.py" /> - <Compile Include="distutils\command\upload.py" /> - <Compile Include="distutils\command\__init__.py" /> - <Compile Include="distutils\config.py" /> - <Compile Include="distutils\core.py" /> - <Compile Include="distutils\cygwinccompiler.py" /> - <Compile Include="distutils\debug.py" /> - <Compile Include="distutils\dep_util.py" /> - <Compile Include="distutils\dir_util.py" /> - <Compile Include="distutils\dist.py" /> - <Compile Include="distutils\errors.py" /> - <Compile Include="distutils\extension.py" /> - <Compile Include="distutils\fancy_getopt.py" /> - <Compile Include="distutils\filelist.py" /> - <Compile Include="distutils\file_util.py" /> - <Compile Include="distutils\log.py" /> - <Compile Include="distutils\msvc9compiler.py" /> - <Compile Include="distutils\msvccompiler.py" /> - <Compile Include="distutils\spawn.py" /> - <Compile Include="distutils\sysconfig.py" /> - <Compile Include="distutils\tests\support.py" /> - <Compile Include="distutils\tests\test_archive_util.py" /> - <Compile Include="distutils\tests\test_bdist.py" /> - <Compile Include="distutils\tests\test_bdist_dumb.py" /> - <Compile Include="distutils\tests\test_bdist_rpm.py" /> - <Compile Include="distutils\tests\test_build.py" /> - <Compile Include="distutils\tests\test_build_clib.py" /> - <Compile Include="distutils\tests\test_build_ext.py" /> - <Compile Include="distutils\tests\test_build_py.py" /> - <Compile Include="distutils\tests\test_build_scripts.py" /> - <Compile Include="distutils\tests\test_check.py" /> - <Compile Include="distutils\tests\test_clean.py" /> - <Compile Include="distutils\tests\test_cmd.py" /> - <Compile Include="distutils\tests\test_config.py" /> - <Compile Include="distutils\tests\test_config_cmd.py" /> - <Compile Include="distutils\tests\test_core.py" /> - <Compile Include="distutils\tests\test_cygwinccompiler.py" /> - <Compile Include="distutils\tests\test_dep_util.py" /> - <Compile Include="distutils\tests\test_dir_util.py" /> - <Compile Include="distutils\tests\test_dist.py" /> - <Compile Include="distutils\tests\test_extension.py" /> - <Compile Include="distutils\tests\test_filelist.py" /> - <Compile Include="distutils\tests\test_file_util.py" /> - <Compile Include="distutils\tests\test_install.py" /> - <Compile Include="distutils\tests\test_install_data.py" /> - <Compile Include="distutils\tests\test_install_headers.py" /> - <Compile Include="distutils\tests\test_install_lib.py" /> - <Compile Include="distutils\tests\test_install_scripts.py" /> - <Compile Include="distutils\tests\test_log.py" /> - <Compile Include="distutils\tests\test_msvc9compiler.py" /> - <Compile Include="distutils\tests\test_msvccompiler.py" /> - <Compile Include="distutils\tests\test_register.py" /> - <Compile Include="distutils\tests\test_sdist.py" /> - <Compile Include="distutils\tests\test_spawn.py" /> - <Compile Include="distutils\tests\test_sysconfig.py" /> - <Compile Include="distutils\tests\test_text_file.py" /> - <Compile Include="distutils\tests\test_unixccompiler.py" /> - <Compile Include="distutils\tests\test_upload.py" /> - <Compile Include="distutils\tests\test_util.py" /> - <Compile Include="distutils\tests\test_version.py" /> - <Compile Include="distutils\tests\test_versionpredicate.py" /> - <Compile Include="distutils\tests\__init__.py" /> - <Compile Include="distutils\text_file.py" /> - <Compile Include="distutils\unixccompiler.py" /> - <Compile Include="distutils\util.py" /> - <Compile Include="distutils\version.py" /> - <Compile Include="distutils\versionpredicate.py" /> - <Compile Include="distutils\_msvccompiler.py" /> - <Compile Include="distutils\__init__.py" /> - <Compile Include="doctest.py" /> - <Compile Include="email\base64mime.py" /> - <Compile Include="email\charset.py" /> - <Compile Include="email\contentmanager.py" /> - <Compile Include="email\encoders.py" /> - <Compile Include="email\errors.py" /> - <Compile Include="email\feedparser.py" /> - <Compile Include="email\generator.py" /> - <Compile Include="email\header.py" /> - <Compile Include="email\headerregistry.py" /> - <Compile Include="email\iterators.py" /> - <Compile Include="email\message.py" /> - <Compile Include="email\mime\application.py" /> - <Compile Include="email\mime\audio.py" /> - <Compile Include="email\mime\base.py" /> - <Compile Include="email\mime\image.py" /> - <Compile Include="email\mime\message.py" /> - <Compile Include="email\mime\multipart.py" /> - <Compile Include="email\mime\nonmultipart.py" /> - <Compile Include="email\mime\text.py" /> - <Compile Include="email\mime\__init__.py" /> - <Compile Include="email\parser.py" /> - <Compile Include="email\policy.py" /> - <Compile Include="email\quoprimime.py" /> - <Compile Include="email\utils.py" /> - <Compile Include="email\_encoded_words.py" /> - <Compile Include="email\_header_value_parser.py" /> - <Compile Include="email\_parseaddr.py" /> - <Compile Include="email\_policybase.py" /> - <Compile Include="email\__init__.py" /> - <Compile Include="encodings\aliases.py" /> - <Compile Include="encodings\ascii.py" /> - <Compile Include="encodings\base64_codec.py" /> - <Compile Include="encodings\big5.py" /> - <Compile Include="encodings\big5hkscs.py" /> - <Compile Include="encodings\bz2_codec.py" /> - <Compile Include="encodings\charmap.py" /> - <Compile Include="encodings\cp037.py" /> - <Compile Include="encodings\cp1006.py" /> - <Compile Include="encodings\cp1026.py" /> - <Compile Include="encodings\cp1125.py" /> - <Compile Include="encodings\cp1140.py" /> - <Compile Include="encodings\cp1250.py" /> - <Compile Include="encodings\cp1251.py" /> - <Compile Include="encodings\cp1252.py" /> - <Compile Include="encodings\cp1253.py" /> - <Compile Include="encodings\cp1254.py" /> - <Compile Include="encodings\cp1255.py" /> - <Compile Include="encodings\cp1256.py" /> - <Compile Include="encodings\cp1257.py" /> - <Compile Include="encodings\cp1258.py" /> - <Compile Include="encodings\cp273.py" /> - <Compile Include="encodings\cp424.py" /> - <Compile Include="encodings\cp437.py" /> - <Compile Include="encodings\cp500.py" /> - <Compile Include="encodings\cp65001.py" /> - <Compile Include="encodings\cp720.py" /> - <Compile Include="encodings\cp737.py" /> - <Compile Include="encodings\cp775.py" /> - <Compile Include="encodings\cp850.py" /> - <Compile Include="encodings\cp852.py" /> - <Compile Include="encodings\cp855.py" /> - <Compile Include="encodings\cp856.py" /> - <Compile Include="encodings\cp857.py" /> - <Compile Include="encodings\cp858.py" /> - <Compile Include="encodings\cp860.py" /> - <Compile Include="encodings\cp861.py" /> - <Compile Include="encodings\cp862.py" /> - <Compile Include="encodings\cp863.py" /> - <Compile Include="encodings\cp864.py" /> - <Compile Include="encodings\cp865.py" /> - <Compile Include="encodings\cp866.py" /> - <Compile Include="encodings\cp869.py" /> - <Compile Include="encodings\cp874.py" /> - <Compile Include="encodings\cp875.py" /> - <Compile Include="encodings\cp932.py" /> - <Compile Include="encodings\cp949.py" /> - <Compile Include="encodings\cp950.py" /> - <Compile Include="encodings\euc_jisx0213.py" /> - <Compile Include="encodings\euc_jis_2004.py" /> - <Compile Include="encodings\euc_jp.py" /> - <Compile Include="encodings\euc_kr.py" /> - <Compile Include="encodings\gb18030.py" /> - <Compile Include="encodings\gb2312.py" /> - <Compile Include="encodings\gbk.py" /> - <Compile Include="encodings\hex_codec.py" /> - <Compile Include="encodings\hp_roman8.py" /> - <Compile Include="encodings\hz.py" /> - <Compile Include="encodings\idna.py" /> - <Compile Include="encodings\iso2022_jp.py" /> - <Compile Include="encodings\iso2022_jp_1.py" /> - <Compile Include="encodings\iso2022_jp_2.py" /> - <Compile Include="encodings\iso2022_jp_2004.py" /> - <Compile Include="encodings\iso2022_jp_3.py" /> - <Compile Include="encodings\iso2022_jp_ext.py" /> - <Compile Include="encodings\iso2022_kr.py" /> - <Compile Include="encodings\iso8859_1.py" /> - <Compile Include="encodings\iso8859_10.py" /> - <Compile Include="encodings\iso8859_11.py" /> - <Compile Include="encodings\iso8859_13.py" /> - <Compile Include="encodings\iso8859_14.py" /> - <Compile Include="encodings\iso8859_15.py" /> - <Compile Include="encodings\iso8859_16.py" /> - <Compile Include="encodings\iso8859_2.py" /> - <Compile Include="encodings\iso8859_3.py" /> - <Compile Include="encodings\iso8859_4.py" /> - <Compile Include="encodings\iso8859_5.py" /> - <Compile Include="encodings\iso8859_6.py" /> - <Compile Include="encodings\iso8859_7.py" /> - <Compile Include="encodings\iso8859_8.py" /> - <Compile Include="encodings\iso8859_9.py" /> - <Compile Include="encodings\johab.py" /> - <Compile Include="encodings\koi8_r.py" /> - <Compile Include="encodings\koi8_t.py" /> - <Compile Include="encodings\koi8_u.py" /> - <Compile Include="encodings\kz1048.py" /> - <Compile Include="encodings\latin_1.py" /> - <Compile Include="encodings\mac_arabic.py" /> - <Compile Include="encodings\mac_centeuro.py" /> - <Compile Include="encodings\mac_croatian.py" /> - <Compile Include="encodings\mac_cyrillic.py" /> - <Compile Include="encodings\mac_farsi.py" /> - <Compile Include="encodings\mac_greek.py" /> - <Compile Include="encodings\mac_iceland.py" /> - <Compile Include="encodings\mac_latin2.py" /> - <Compile Include="encodings\mac_roman.py" /> - <Compile Include="encodings\mac_romanian.py" /> - <Compile Include="encodings\mac_turkish.py" /> - <Compile Include="encodings\mbcs.py" /> - <Compile Include="encodings\oem.py" /> - <Compile Include="encodings\palmos.py" /> - <Compile Include="encodings\ptcp154.py" /> - <Compile Include="encodings\punycode.py" /> - <Compile Include="encodings\quopri_codec.py" /> - <Compile Include="encodings\raw_unicode_escape.py" /> - <Compile Include="encodings\rot_13.py" /> - <Compile Include="encodings\shift_jis.py" /> - <Compile Include="encodings\shift_jisx0213.py" /> - <Compile Include="encodings\shift_jis_2004.py" /> - <Compile Include="encodings\tis_620.py" /> - <Compile Include="encodings\undefined.py" /> - <Compile Include="encodings\unicode_escape.py" /> - <Compile Include="encodings\utf_16.py" /> - <Compile Include="encodings\utf_16_be.py" /> - <Compile Include="encodings\utf_16_le.py" /> - <Compile Include="encodings\utf_32.py" /> - <Compile Include="encodings\utf_32_be.py" /> - <Compile Include="encodings\utf_32_le.py" /> - <Compile Include="encodings\utf_7.py" /> - <Compile Include="encodings\utf_8.py" /> - <Compile Include="encodings\utf_8_sig.py" /> - <Compile Include="encodings\uu_codec.py" /> - <Compile Include="encodings\zlib_codec.py" /> - <Compile Include="encodings\__init__.py" /> - <Compile Include="ensurepip\_uninstall.py" /> - <Compile Include="ensurepip\__init__.py" /> - <Compile Include="ensurepip\__main__.py" /> - <Compile Include="enum.py" /> - <Compile Include="filecmp.py" /> - <Compile Include="fileinput.py" /> - <Compile Include="fnmatch.py" /> - <Compile Include="formatter.py" /> - <Compile Include="fractions.py" /> - <Compile Include="ftplib.py" /> - <Compile Include="functools.py" /> - <Compile Include="genericpath.py" /> - <Compile Include="getopt.py" /> - <Compile Include="getpass.py" /> - <Compile Include="gettext.py" /> - <Compile Include="glob.py" /> - <Compile Include="graphlib.py" /> - <Compile Include="gzip.py" /> - <Compile Include="hashlib.py" /> - <Compile Include="heapq.py" /> - <Compile Include="hmac.py" /> - <Compile Include="html\entities.py" /> - <Compile Include="html\parser.py" /> - <Compile Include="html\__init__.py" /> - <Compile Include="http\client.py" /> - <Compile Include="http\cookiejar.py" /> - <Compile Include="http\cookies.py" /> - <Compile Include="http\server.py" /> - <Compile Include="http\__init__.py" /> - <Compile Include="idlelib\autocomplete.py" /> - <Compile Include="idlelib\autocomplete_w.py" /> - <Compile Include="idlelib\autoexpand.py" /> - <Compile Include="idlelib\browser.py" /> - <Compile Include="idlelib\calltips.py" /> - <Compile Include="idlelib\calltip_w.py" /> - <Compile Include="idlelib\codecontext.py" /> - <Compile Include="idlelib\colorizer.py" /> - <Compile Include="idlelib\config.py" /> - <Compile Include="idlelib\configdialog.py" /> - <Compile Include="idlelib\config_key.py" /> - <Compile Include="idlelib\debugger.py" /> - <Compile Include="idlelib\debugger_r.py" /> - <Compile Include="idlelib\debugobj.py" /> - <Compile Include="idlelib\debugobj_r.py" /> - <Compile Include="idlelib\delegator.py" /> - <Compile Include="idlelib\dynoption.py" /> - <Compile Include="idlelib\editor.py" /> - <Compile Include="idlelib\filelist.py" /> - <Compile Include="idlelib\grep.py" /> - <Compile Include="idlelib\help.py" /> - <Compile Include="idlelib\help_about.py" /> - <Compile Include="idlelib\history.py" /> - <Compile Include="idlelib\hyperparser.py" /> - <Compile Include="idlelib\idle.py" /> - <Compile Include="idlelib\idle.pyw" /> - <Compile Include="idlelib\idle_test\htest.py" /> - <Compile Include="idlelib\idle_test\mock_idle.py" /> - <Compile Include="idlelib\idle_test\mock_tk.py" /> - <Compile Include="idlelib\idle_test\test_autocomplete.py" /> - <Compile Include="idlelib\idle_test\test_autoexpand.py" /> - <Compile Include="idlelib\idle_test\test_calltips.py" /> - <Compile Include="idlelib\idle_test\test_colorizer.py" /> - <Compile Include="idlelib\idle_test\test_config.py" /> - <Compile Include="idlelib\idle_test\test_configdialog.py" /> - <Compile Include="idlelib\idle_test\test_config_key.py" /> - <Compile Include="idlelib\idle_test\test_debugger.py" /> - <Compile Include="idlelib\idle_test\test_delegator.py" /> - <Compile Include="idlelib\idle_test\test_editmenu.py" /> - <Compile Include="idlelib\idle_test\test_editor.py" /> - <Compile Include="idlelib\idle_test\test_grep.py" /> - <Compile Include="idlelib\idle_test\test_help.py" /> - <Compile Include="idlelib\idle_test\test_help_about.py" /> - <Compile Include="idlelib\idle_test\test_history.py" /> - <Compile Include="idlelib\idle_test\test_hyperparser.py" /> - <Compile Include="idlelib\idle_test\test_iomenu.py" /> - <Compile Include="idlelib\idle_test\test_macosx.py" /> - <Compile Include="idlelib\idle_test\test_paragraph.py" /> - <Compile Include="idlelib\idle_test\test_parenmatch.py" /> - <Compile Include="idlelib\idle_test\test_pathbrowser.py" /> - <Compile Include="idlelib\idle_test\test_percolator.py" /> - <Compile Include="idlelib\idle_test\test_query.py" /> - <Compile Include="idlelib\idle_test\test_redirector.py" /> - <Compile Include="idlelib\idle_test\test_replace.py" /> - <Compile Include="idlelib\idle_test\test_rstrip.py" /> - <Compile Include="idlelib\idle_test\test_scrolledlist.py" /> - <Compile Include="idlelib\idle_test\test_search.py" /> - <Compile Include="idlelib\idle_test\test_searchbase.py" /> - <Compile Include="idlelib\idle_test\test_searchengine.py" /> - <Compile Include="idlelib\idle_test\test_text.py" /> - <Compile Include="idlelib\idle_test\test_textview.py" /> - <Compile Include="idlelib\idle_test\test_tree.py" /> - <Compile Include="idlelib\idle_test\test_undo.py" /> - <Compile Include="idlelib\idle_test\test_warning.py" /> - <Compile Include="idlelib\idle_test\__init__.py" /> - <Compile Include="idlelib\iomenu.py" /> - <Compile Include="idlelib\macosx.py" /> - <Compile Include="idlelib\mainmenu.py" /> - <Compile Include="idlelib\multicall.py" /> - <Compile Include="idlelib\outwin.py" /> - <Compile Include="idlelib\paragraph.py" /> - <Compile Include="idlelib\parenmatch.py" /> - <Compile Include="idlelib\pathbrowser.py" /> - <Compile Include="idlelib\percolator.py" /> - <Compile Include="idlelib\pyparse.py" /> - <Compile Include="idlelib\pyshell.py" /> - <Compile Include="idlelib\query.py" /> - <Compile Include="idlelib\redirector.py" /> - <Compile Include="idlelib\replace.py" /> - <Compile Include="idlelib\rpc.py" /> - <Compile Include="idlelib\rstrip.py" /> - <Compile Include="idlelib\run.py" /> - <Compile Include="idlelib\runscript.py" /> - <Compile Include="idlelib\scrolledlist.py" /> - <Compile Include="idlelib\search.py" /> - <Compile Include="idlelib\searchbase.py" /> - <Compile Include="idlelib\searchengine.py" /> - <Compile Include="idlelib\stackviewer.py" /> - <Compile Include="idlelib\statusbar.py" /> - <Compile Include="idlelib\tabbedpages.py" /> - <Compile Include="idlelib\textview.py" /> - <Compile Include="idlelib\tooltip.py" /> - <Compile Include="idlelib\tree.py" /> - <Compile Include="idlelib\undo.py" /> - <Compile Include="idlelib\windows.py" /> - <Compile Include="idlelib\zoomheight.py" /> - <Compile Include="idlelib\__init__.py" /> - <Compile Include="idlelib\__main__.py" /> - <Compile Include="imaplib.py" /> - <Compile Include="imghdr.py" /> - <Compile Include="imp.py" /> - <Compile Include="importlib\abc.py" /> - <Compile Include="importlib\machinery.py" /> - <Compile Include="importlib\util.py" /> - <Compile Include="importlib\_bootstrap.py" /> - <Compile Include="importlib\_bootstrap_external.py" /> - <Compile Include="importlib\__init__.py" /> - <Compile Include="inspect.py" /> - <Compile Include="io.py" /> - <Compile Include="ipaddress.py" /> - <Compile Include="json\decoder.py" /> - <Compile Include="json\encoder.py" /> - <Compile Include="json\scanner.py" /> - <Compile Include="json\tool.py" /> - <Compile Include="json\__init__.py" /> - <Compile Include="keyword.py" /> - <Compile Include="lib2to3\btm_matcher.py" /> - <Compile Include="lib2to3\btm_utils.py" /> - <Compile Include="lib2to3\fixer_base.py" /> - <Compile Include="lib2to3\fixer_util.py" /> - <Compile Include="lib2to3\fixes\fix_apply.py" /> - <Compile Include="lib2to3\fixes\fix_asserts.py" /> - <Compile Include="lib2to3\fixes\fix_basestring.py" /> - <Compile Include="lib2to3\fixes\fix_buffer.py" /> - <Compile Include="lib2to3\fixes\fix_dict.py" /> - <Compile Include="lib2to3\fixes\fix_except.py" /> - <Compile Include="lib2to3\fixes\fix_exec.py" /> - <Compile Include="lib2to3\fixes\fix_execfile.py" /> - <Compile Include="lib2to3\fixes\fix_exitfunc.py" /> - <Compile Include="lib2to3\fixes\fix_filter.py" /> - <Compile Include="lib2to3\fixes\fix_funcattrs.py" /> - <Compile Include="lib2to3\fixes\fix_future.py" /> - <Compile Include="lib2to3\fixes\fix_getcwdu.py" /> - <Compile Include="lib2to3\fixes\fix_has_key.py" /> - <Compile Include="lib2to3\fixes\fix_idioms.py" /> - <Compile Include="lib2to3\fixes\fix_import.py" /> - <Compile Include="lib2to3\fixes\fix_imports.py" /> - <Compile Include="lib2to3\fixes\fix_imports2.py" /> - <Compile Include="lib2to3\fixes\fix_input.py" /> - <Compile Include="lib2to3\fixes\fix_intern.py" /> - <Compile Include="lib2to3\fixes\fix_isinstance.py" /> - <Compile Include="lib2to3\fixes\fix_itertools.py" /> - <Compile Include="lib2to3\fixes\fix_itertools_imports.py" /> - <Compile Include="lib2to3\fixes\fix_long.py" /> - <Compile Include="lib2to3\fixes\fix_map.py" /> - <Compile Include="lib2to3\fixes\fix_metaclass.py" /> - <Compile Include="lib2to3\fixes\fix_methodattrs.py" /> - <Compile Include="lib2to3\fixes\fix_ne.py" /> - <Compile Include="lib2to3\fixes\fix_next.py" /> - <Compile Include="lib2to3\fixes\fix_nonzero.py" /> - <Compile Include="lib2to3\fixes\fix_numliterals.py" /> - <Compile Include="lib2to3\fixes\fix_operator.py" /> - <Compile Include="lib2to3\fixes\fix_paren.py" /> - <Compile Include="lib2to3\fixes\fix_print.py" /> - <Compile Include="lib2to3\fixes\fix_raise.py" /> - <Compile Include="lib2to3\fixes\fix_raw_input.py" /> - <Compile Include="lib2to3\fixes\fix_reduce.py" /> - <Compile Include="lib2to3\fixes\fix_reload.py" /> - <Compile Include="lib2to3\fixes\fix_renames.py" /> - <Compile Include="lib2to3\fixes\fix_repr.py" /> - <Compile Include="lib2to3\fixes\fix_set_literal.py" /> - <Compile Include="lib2to3\fixes\fix_standarderror.py" /> - <Compile Include="lib2to3\fixes\fix_sys_exc.py" /> - <Compile Include="lib2to3\fixes\fix_throw.py" /> - <Compile Include="lib2to3\fixes\fix_tuple_params.py" /> - <Compile Include="lib2to3\fixes\fix_types.py" /> - <Compile Include="lib2to3\fixes\fix_unicode.py" /> - <Compile Include="lib2to3\fixes\fix_urllib.py" /> - <Compile Include="lib2to3\fixes\fix_ws_comma.py" /> - <Compile Include="lib2to3\fixes\fix_xrange.py" /> - <Compile Include="lib2to3\fixes\fix_xreadlines.py" /> - <Compile Include="lib2to3\fixes\fix_zip.py" /> - <Compile Include="lib2to3\fixes\__init__.py" /> - <Compile Include="lib2to3\main.py" /> - <Compile Include="lib2to3\patcomp.py" /> - <Compile Include="lib2to3\pgen2\conv.py" /> - <Compile Include="lib2to3\pgen2\driver.py" /> - <Compile Include="lib2to3\pgen2\grammar.py" /> - <Compile Include="lib2to3\pgen2\literals.py" /> - <Compile Include="lib2to3\pgen2\parse.py" /> - <Compile Include="lib2to3\pgen2\pgen.py" /> - <Compile Include="lib2to3\pgen2\token.py" /> - <Compile Include="lib2to3\pgen2\tokenize.py" /> - <Compile Include="lib2to3\pgen2\__init__.py" /> - <Compile Include="lib2to3\pygram.py" /> - <Compile Include="lib2to3\pytree.py" /> - <Compile Include="lib2to3\refactor.py" /> - <Compile Include="lib2to3\tests\data\bom.py" /> - <Compile Include="lib2to3\tests\data\crlf.py" /> - <Compile Include="lib2to3\tests\data\different_encoding.py" /> - <Compile Include="lib2to3\tests\data\false_encoding.py" /> - <Compile Include="lib2to3\tests\data\fixers\bad_order.py" /> - <Compile Include="lib2to3\tests\data\fixers\myfixes\fix_explicit.py" /> - <Compile Include="lib2to3\tests\data\fixers\myfixes\fix_first.py" /> - <Compile Include="lib2to3\tests\data\fixers\myfixes\fix_last.py" /> - <Compile Include="lib2to3\tests\data\fixers\myfixes\fix_parrot.py" /> - <Compile Include="lib2to3\tests\data\fixers\myfixes\fix_preorder.py" /> - <Compile Include="lib2to3\tests\data\fixers\myfixes\__init__.py" /> - <Compile Include="lib2to3\tests\data\fixers\no_fixer_cls.py" /> - <Compile Include="lib2to3\tests\data\fixers\parrot_example.py" /> - <Compile Include="lib2to3\tests\data\infinite_recursion.py" /> - <Compile Include="lib2to3\tests\data\py2_test_grammar.py" /> - <Compile Include="lib2to3\tests\data\py3_test_grammar.py" /> - <Compile Include="lib2to3\tests\pytree_idempotency.py" /> - <Compile Include="lib2to3\tests\support.py" /> - <Compile Include="lib2to3\tests\test_all_fixers.py" /> - <Compile Include="lib2to3\tests\test_fixers.py" /> - <Compile Include="lib2to3\tests\test_main.py" /> - <Compile Include="lib2to3\tests\test_parser.py" /> - <Compile Include="lib2to3\tests\test_pytree.py" /> - <Compile Include="lib2to3\tests\test_refactor.py" /> - <Compile Include="lib2to3\tests\test_util.py" /> - <Compile Include="lib2to3\tests\__init__.py" /> - <Compile Include="lib2to3\tests\__main__.py" /> - <Compile Include="lib2to3\__init__.py" /> - <Compile Include="lib2to3\__main__.py" /> - <Compile Include="linecache.py" /> - <Compile Include="locale.py" /> - <Compile Include="logging\config.py" /> - <Compile Include="logging\handlers.py" /> - <Compile Include="logging\__init__.py" /> - <Compile Include="lzma.py" /> - <Compile Include="mailbox.py" /> - <Compile Include="mailcap.py" /> - <Compile Include="mimetypes.py" /> - <Compile Include="modulefinder.py" /> - <Compile Include="msilib\schema.py" /> - <Compile Include="msilib\sequence.py" /> - <Compile Include="msilib\text.py" /> - <Compile Include="msilib\__init__.py" /> - <Compile Include="multiprocessing\connection.py" /> - <Compile Include="multiprocessing\context.py" /> - <Compile Include="multiprocessing\dummy\connection.py" /> - <Compile Include="multiprocessing\dummy\__init__.py" /> - <Compile Include="multiprocessing\forkserver.py" /> - <Compile Include="multiprocessing\heap.py" /> - <Compile Include="multiprocessing\managers.py" /> - <Compile Include="multiprocessing\pool.py" /> - <Compile Include="multiprocessing\popen_fork.py" /> - <Compile Include="multiprocessing\popen_forkserver.py" /> - <Compile Include="multiprocessing\popen_spawn_posix.py" /> - <Compile Include="multiprocessing\popen_spawn_win32.py" /> - <Compile Include="multiprocessing\process.py" /> - <Compile Include="multiprocessing\queues.py" /> - <Compile Include="multiprocessing\reduction.py" /> - <Compile Include="multiprocessing\resource_sharer.py" /> - <Compile Include="multiprocessing\resource_tracker.py" /> - <Compile Include="multiprocessing\sharedctypes.py" /> - <Compile Include="multiprocessing\spawn.py" /> - <Compile Include="multiprocessing\synchronize.py" /> - <Compile Include="multiprocessing\util.py" /> - <Compile Include="multiprocessing\__init__.py" /> - <Compile Include="netrc.py" /> - <Compile Include="nntplib.py" /> - <Compile Include="ntpath.py" /> - <Compile Include="nturl2path.py" /> - <Compile Include="numbers.py" /> - <Compile Include="opcode.py" /> - <Compile Include="operator.py" /> - <Compile Include="optparse.py" /> - <Compile Include="os.py" /> - <Compile Include="pathlib.py" /> - <Compile Include="pdb.py" /> - <Compile Include="pickle.py" /> - <Compile Include="pickletools.py" /> - <Compile Include="pipes.py" /> - <Compile Include="pkgutil.py" /> - <Compile Include="platform.py" /> - <Compile Include="plistlib.py" /> - <Compile Include="poplib.py" /> - <Compile Include="posixpath.py" /> - <Compile Include="pprint.py" /> - <Compile Include="profile.py" /> - <Compile Include="pstats.py" /> - <Compile Include="pty.py" /> - <Compile Include="pyclbr.py" /> - <Compile Include="pydoc.py" /> - <Compile Include="pydoc_data\topics.py" /> - <Compile Include="pydoc_data\__init__.py" /> - <Compile Include="py_compile.py" /> - <Compile Include="queue.py" /> - <Compile Include="quopri.py" /> - <Compile Include="random.py" /> - <Compile Include="re.py" /> - <Compile Include="reprlib.py" /> - <Compile Include="rlcompleter.py" /> - <Compile Include="runpy.py" /> - <Compile Include="sched.py" /> - <Compile Include="secrets.py" /> - <Compile Include="selectors.py" /> - <Compile Include="shelve.py" /> - <Compile Include="shlex.py" /> - <Compile Include="shutil.py" /> - <Compile Include="signal.py" /> - <Compile Include="site.py" /> - <Compile Include="smtpd.py" /> - <Compile Include="smtplib.py" /> - <Compile Include="sndhdr.py" /> - <Compile Include="socket.py" /> - <Compile Include="socketserver.py" /> - <Compile Include="sqlite3\dbapi2.py" /> - <Compile Include="sqlite3\dump.py" /> - <Compile Include="sqlite3\test\dbapi.py" /> - <Compile Include="sqlite3\test\dump.py" /> - <Compile Include="sqlite3\test\factory.py" /> - <Compile Include="sqlite3\test\hooks.py" /> - <Compile Include="sqlite3\test\regression.py" /> - <Compile Include="sqlite3\test\transactions.py" /> - <Compile Include="sqlite3\test\types.py" /> - <Compile Include="sqlite3\test\userfunctions.py" /> - <Compile Include="sqlite3\test\__init__.py" /> - <Compile Include="sqlite3\__init__.py" /> - <Compile Include="sre_compile.py" /> - <Compile Include="sre_constants.py" /> - <Compile Include="sre_parse.py" /> - <Compile Include="ssl.py" /> - <Compile Include="stat.py" /> - <Compile Include="statistics.py" /> - <Compile Include="string.py" /> - <Compile Include="stringprep.py" /> - <Compile Include="struct.py" /> - <Compile Include="subprocess.py" /> - <Compile Include="sunau.py" /> - <Compile Include="symbol.py" /> - <Compile Include="symtable.py" /> - <Compile Include="sysconfig.py" /> - <Compile Include="tabnanny.py" /> - <Compile Include="tarfile.py" /> - <Compile Include="telnetlib.py" /> - <Compile Include="tempfile.py" /> - <Compile Include="test\ann_module.py" /> - <Compile Include="test\ann_module2.py" /> - <Compile Include="test\ann_module3.py" /> - <Compile Include="test\audiotests.py" /> - <Compile Include="test\autotest.py" /> - <Compile Include="test\badsyntax_3131.py" /> - <Compile Include="test\badsyntax_future10.py" /> - <Compile Include="test\badsyntax_future3.py" /> - <Compile Include="test\badsyntax_future4.py" /> - <Compile Include="test\badsyntax_future5.py" /> - <Compile Include="test\badsyntax_future6.py" /> - <Compile Include="test\badsyntax_future7.py" /> - <Compile Include="test\badsyntax_future8.py" /> - <Compile Include="test\badsyntax_future9.py" /> - <Compile Include="test\badsyntax_pep3120.py" /> - <Compile Include="test\bad_coding.py" /> - <Compile Include="test\bad_coding2.py" /> - <Compile Include="test\bytecode_helper.py" /> - <Compile Include="test\coding20731.py" /> - <Compile Include="test\crashers\bogus_code_obj.py" /> - <Compile Include="test\crashers\gc_inspection.py" /> - <Compile Include="test\crashers\infinite_loop_re.py" /> - <Compile Include="test\crashers\mutation_inside_cyclegc.py" /> - <Compile Include="test\crashers\recursive_call.py" /> - <Compile Include="test\crashers\trace_at_recursion_limit.py" /> - <Compile Include="test\crashers\underlying_dict.py" /> - <Compile Include="test\curses_tests.py" /> - <Compile Include="test\datetimetester.py" /> - <Compile Include="test\dis_module.py" /> - <Compile Include="test\doctest_aliases.py" /> - <Compile Include="test\double_const.py" /> - <Compile Include="test\dtracedata\call_stack.py" /> - <Compile Include="test\dtracedata\gc.py" /> - <Compile Include="test\dtracedata\instance.py" /> - <Compile Include="test\dtracedata\line.py" /> - <Compile Include="test\eintrdata\eintr_tester.py" /> - <Compile Include="test\encoded_modules\module_iso_8859_1.py" /> - <Compile Include="test\encoded_modules\module_koi8_r.py" /> - <Compile Include="test\encoded_modules\__init__.py" /> - <Compile Include="test\final_a.py" /> - <Compile Include="test\final_b.py" /> - <Compile Include="test\fork_wait.py" /> - <Compile Include="test\future_test1.py" /> - <Compile Include="test\future_test2.py" /> - <Compile Include="test\gdb_sample.py" /> - <Compile Include="test\imp_dummy.py" /> - <Compile Include="test\inspect_fodder.py" /> - <Compile Include="test\inspect_fodder2.py" /> - <Compile Include="test\leakers\test_ctypes.py" /> - <Compile Include="test\leakers\test_selftype.py" /> - <Compile Include="test\leakers\__init__.py" /> - <Compile Include="test\libregrtest\cmdline.py" /> - <Compile Include="test\libregrtest\main.py" /> - <Compile Include="test\libregrtest\refleak.py" /> - <Compile Include="test\libregrtest\runtest.py" /> - <Compile Include="test\libregrtest\runtest_mp.py" /> - <Compile Include="test\libregrtest\save_env.py" /> - <Compile Include="test\libregrtest\setup.py" /> - <Compile Include="test\libregrtest\__init__.py" /> - <Compile Include="test\list_tests.py" /> - <Compile Include="test\lock_tests.py" /> - <Compile Include="test\make_ssl_certs.py" /> - <Compile Include="test\mapping_tests.py" /> - <Compile Include="test\memory_watchdog.py" /> - <Compile Include="test\mock_socket.py" /> - <Compile Include="test\mod_generics_cache.py" /> - <Compile Include="test\mp_fork_bomb.py" /> - <Compile Include="test\mp_preload.py" /> - <Compile Include="test\multibytecodec_support.py" /> - <Compile Include="test\pickletester.py" /> - <Compile Include="test\profilee.py" /> - <Compile Include="test\pyclbr_input.py" /> - <Compile Include="test\pydocfodder.py" /> - <Compile Include="test\pydoc_mod.py" /> - <Compile Include="test\regrtest.py" /> - <Compile Include="test\relimport.py" /> - <Compile Include="test\reperf.py" /> - <Compile Include="test\re_tests.py" /> - <Compile Include="test\sample_doctest.py" /> - <Compile Include="test\sample_doctest_no_docstrings.py" /> - <Compile Include="test\sample_doctest_no_doctests.py" /> - <Compile Include="test\seq_tests.py" /> - <Compile Include="test\signalinterproctester.py" /> - <Compile Include="test\sortperf.py" /> - <Compile Include="test\ssltests.py" /> - <Compile Include="test\ssl_servers.py" /> - <Compile Include="test\string_tests.py" /> - <Compile Include="test\subprocessdata\fd_status.py" /> - <Compile Include="test\subprocessdata\input_reader.py" /> - <Compile Include="test\subprocessdata\qcat.py" /> - <Compile Include="test\subprocessdata\qgrep.py" /> - <Compile Include="test\subprocessdata\sigchild_ignore.py" /> - <Compile Include="test\support\script_helper.py" /> - <Compile Include="test\support\__init__.py" /> - <Compile Include="test\testcodec.py" /> - <Compile Include="test\test_abc.py" /> - <Compile Include="test\test_abstract_numbers.py" /> - <Compile Include="test\test_aifc.py" /> - <Compile Include="test\test_argparse.py" /> - <Compile Include="test\test_array.py" /> - <Compile Include="test\test_asdl_parser.py" /> - <Compile Include="test\test_ast.py" /> - <Compile Include="test\test_asyncgen.py" /> - <Compile Include="test\test_asynchat.py" /> - <Compile Include="test\test_asyncio\echo.py" /> - <Compile Include="test\test_asyncio\echo2.py" /> - <Compile Include="test\test_asyncio\echo3.py" /> - <Compile Include="test\test_asyncio\test_base_events.py" /> - <Compile Include="test\test_asyncio\test_events.py" /> - <Compile Include="test\test_asyncio\test_futures.py" /> - <Compile Include="test\test_asyncio\test_locks.py" /> - <Compile Include="test\test_asyncio\test_pep492.py" /> - <Compile Include="test\test_asyncio\test_proactor_events.py" /> - <Compile Include="test\test_asyncio\test_queues.py" /> - <Compile Include="test\test_asyncio\test_selector_events.py" /> - <Compile Include="test\test_asyncio\test_sslproto.py" /> - <Compile Include="test\test_asyncio\test_streams.py" /> - <Compile Include="test\test_asyncio\test_subprocess.py" /> - <Compile Include="test\test_asyncio\test_tasks.py" /> - <Compile Include="test\test_asyncio\test_transports.py" /> - <Compile Include="test\test_asyncio\test_unix_events.py" /> - <Compile Include="test\test_asyncio\test_windows_events.py" /> - <Compile Include="test\test_asyncio\test_windows_utils.py" /> - <Compile Include="test\test_asyncio\__init__.py" /> - <Compile Include="test\test_asyncio\__main__.py" /> - <Compile Include="test\test_asyncore.py" /> - <Compile Include="test\test_atexit.py" /> - <Compile Include="test\test_audioop.py" /> - <Compile Include="test\test_augassign.py" /> - <Compile Include="test\test_base64.py" /> - <Compile Include="test\test_baseexception.py" /> - <Compile Include="test\test_bigaddrspace.py" /> - <Compile Include="test\test_bigmem.py" /> - <Compile Include="test\test_binascii.py" /> - <Compile Include="test\test_binop.py" /> - <Compile Include="test\test_bisect.py" /> - <Compile Include="test\test_bool.py" /> - <Compile Include="test\test_buffer.py" /> - <Compile Include="test\test_bufio.py" /> - <Compile Include="test\test_builtin.py" /> - <Compile Include="test\test_bytes.py" /> - <Compile Include="test\test_bz2.py" /> - <Compile Include="test\test_calendar.py" /> - <Compile Include="test\test_call.py" /> - <Compile Include="test\test_capi.py" /> - <Compile Include="test\test_cgi.py" /> - <Compile Include="test\test_cgitb.py" /> - <Compile Include="test\test_charmapcodec.py" /> - <Compile Include="test\test_class.py" /> - <Compile Include="test\test_cmath.py" /> - <Compile Include="test\test_cmd.py" /> - <Compile Include="test\test_cmd_line.py" /> - <Compile Include="test\test_cmd_line_script.py" /> - <Compile Include="test\test_code.py" /> - <Compile Include="test\test_codeccallbacks.py" /> - <Compile Include="test\test_codecencodings_cn.py" /> - <Compile Include="test\test_codecencodings_hk.py" /> - <Compile Include="test\test_codecencodings_iso2022.py" /> - <Compile Include="test\test_codecencodings_jp.py" /> - <Compile Include="test\test_codecencodings_kr.py" /> - <Compile Include="test\test_codecencodings_tw.py" /> - <Compile Include="test\test_codecmaps_cn.py" /> - <Compile Include="test\test_codecmaps_hk.py" /> - <Compile Include="test\test_codecmaps_jp.py" /> - <Compile Include="test\test_codecmaps_kr.py" /> - <Compile Include="test\test_codecmaps_tw.py" /> - <Compile Include="test\test_codecs.py" /> - <Compile Include="test\test_codeop.py" /> - <Compile Include="test\test_code_module.py" /> - <Compile Include="test\test_collections.py" /> - <Compile Include="test\test_colorsys.py" /> - <Compile Include="test\test_compare.py" /> - <Compile Include="test\test_compile.py" /> - <Compile Include="test\test_compileall.py" /> - <Compile Include="test\test_complex.py" /> - <Compile Include="test\test_concurrent_futures.py" /> - <Compile Include="test\test_configparser.py" /> - <Compile Include="test\test_contains.py" /> - <Compile Include="test\test_contextlib.py" /> - <Compile Include="test\test_contextlib_async.py" /> - <Compile Include="test\test_copy.py" /> - <Compile Include="test\test_copyreg.py" /> - <Compile Include="test\test_coroutines.py" /> - <Compile Include="test\test_cprofile.py" /> - <Compile Include="test\test_crashers.py" /> - <Compile Include="test\test_crypt.py" /> - <Compile Include="test\test_csv.py" /> - <Compile Include="test\test_ctypes.py" /> - <Compile Include="test\test_curses.py" /> - <Compile Include="test\test_datetime.py" /> - <Compile Include="test\test_dbm.py" /> - <Compile Include="test\test_dbm_dumb.py" /> - <Compile Include="test\test_dbm_gnu.py" /> - <Compile Include="test\test_dbm_ndbm.py" /> - <Compile Include="test\test_decimal.py" /> - <Compile Include="test\test_decorators.py" /> - <Compile Include="test\test_defaultdict.py" /> - <Compile Include="test\test_deque.py" /> - <Compile Include="test\test_descr.py" /> - <Compile Include="test\test_descrtut.py" /> - <Compile Include="test\test_devpoll.py" /> - <Compile Include="test\test_dict.py" /> - <Compile Include="test\test_dictcomps.py" /> - <Compile Include="test\test_dictviews.py" /> - <Compile Include="test\test_dict_version.py" /> - <Compile Include="test\test_difflib.py" /> - <Compile Include="test\test_dis.py" /> - <Compile Include="test\test_distutils.py" /> - <Compile Include="test\test_doctest.py" /> - <Compile Include="test\test_doctest2.py" /> - <Compile Include="test\test_docxmlrpc.py" /> - <Compile Include="test\test_dtrace.py" /> - <Compile Include="test\test_dynamic.py" /> - <Compile Include="test\test_dynamicclassattribute.py" /> - <Compile Include="test\test_eintr.py" /> - <Compile Include="test\test_email\test_asian_codecs.py" /> - <Compile Include="test\test_email\test_contentmanager.py" /> - <Compile Include="test\test_email\test_defect_handling.py" /> - <Compile Include="test\test_email\test_email.py" /> - <Compile Include="test\test_email\test_generator.py" /> - <Compile Include="test\test_email\test_headerregistry.py" /> - <Compile Include="test\test_email\test_inversion.py" /> - <Compile Include="test\test_email\test_message.py" /> - <Compile Include="test\test_email\test_parser.py" /> - <Compile Include="test\test_email\test_pickleable.py" /> - <Compile Include="test\test_email\test_policy.py" /> - <Compile Include="test\test_email\test_utils.py" /> - <Compile Include="test\test_email\test__encoded_words.py" /> - <Compile Include="test\test_email\test__header_value_parser.py" /> - <Compile Include="test\test_email\torture_test.py" /> - <Compile Include="test\test_email\__init__.py" /> - <Compile Include="test\test_email\__main__.py" /> - <Compile Include="test\test_ensurepip.py" /> - <Compile Include="test\test_enum.py" /> - <Compile Include="test\test_enumerate.py" /> - <Compile Include="test\test_eof.py" /> - <Compile Include="test\test_epoll.py" /> - <Compile Include="test\test_errno.py" /> - <Compile Include="test\test_exceptions.py" /> - <Compile Include="test\test_exception_hierarchy.py" /> - <Compile Include="test\test_exception_variations.py" /> - <Compile Include="test\test_extcall.py" /> - <Compile Include="test\test_faulthandler.py" /> - <Compile Include="test\test_fcntl.py" /> - <Compile Include="test\test_file.py" /> - <Compile Include="test\test_filecmp.py" /> - <Compile Include="test\test_fileinput.py" /> - <Compile Include="test\test_fileio.py" /> - <Compile Include="test\test_file_eintr.py" /> - <Compile Include="test\test_finalization.py" /> - <Compile Include="test\test_float.py" /> - <Compile Include="test\test_flufl.py" /> - <Compile Include="test\test_fnmatch.py" /> - <Compile Include="test\test_fork1.py" /> - <Compile Include="test\test_format.py" /> - <Compile Include="test\test_fractions.py" /> - <Compile Include="test\test_frame.py" /> - <Compile Include="test\test_fstring.py" /> - <Compile Include="test\test_ftplib.py" /> - <Compile Include="test\test_funcattrs.py" /> - <Compile Include="test\test_functools.py" /> - <Compile Include="test\test_future.py" /> - <Compile Include="test\test_future3.py" /> - <Compile Include="test\test_future4.py" /> - <Compile Include="test\test_future5.py" /> - <Compile Include="test\test_gc.py" /> - <Compile Include="test\test_gdb.py" /> - <Compile Include="test\test_generators.py" /> - <Compile Include="test\test_generator_stop.py" /> - <Compile Include="test\test_genericpath.py" /> - <Compile Include="test\test_genexps.py" /> - <Compile Include="test\test_getargs2.py" /> - <Compile Include="test\test_getopt.py" /> - <Compile Include="test\test_getpass.py" /> - <Compile Include="test\test_gettext.py" /> - <Compile Include="test\test_glob.py" /> - <Compile Include="test\test_global.py" /> - <Compile Include="test\test_grammar.py" /> - <Compile Include="test\test_grp.py" /> - <Compile Include="test\test_gzip.py" /> - <Compile Include="test\test_hash.py" /> - <Compile Include="test\test_hashlib.py" /> - <Compile Include="test\test_heapq.py" /> - <Compile Include="test\test_hmac.py" /> - <Compile Include="test\test_html.py" /> - <Compile Include="test\test_htmlparser.py" /> - <Compile Include="test\test_httplib.py" /> - <Compile Include="test\test_httpservers.py" /> - <Compile Include="test\test_http_cookiejar.py" /> - <Compile Include="test\test_http_cookies.py" /> - <Compile Include="test\test_idle.py" /> - <Compile Include="test\test_imaplib.py" /> - <Compile Include="test\test_imghdr.py" /> - <Compile Include="test\test_imp.py" /> - <Compile Include="test\test_importlib\abc.py" /> - <Compile Include="test\test_importlib\builtin\test_finder.py" /> - <Compile Include="test\test_importlib\builtin\test_loader.py" /> - <Compile Include="test\test_importlib\builtin\__init__.py" /> - <Compile Include="test\test_importlib\builtin\__main__.py" /> - <Compile Include="test\test_importlib\extension\test_case_sensitivity.py" /> - <Compile Include="test\test_importlib\extension\test_finder.py" /> - <Compile Include="test\test_importlib\extension\test_loader.py" /> - <Compile Include="test\test_importlib\extension\test_path_hook.py" /> - <Compile Include="test\test_importlib\extension\__init__.py" /> - <Compile Include="test\test_importlib\extension\__main__.py" /> - <Compile Include="test\test_importlib\frozen\test_finder.py" /> - <Compile Include="test\test_importlib\frozen\test_loader.py" /> - <Compile Include="test\test_importlib\frozen\__init__.py" /> - <Compile Include="test\test_importlib\frozen\__main__.py" /> - <Compile Include="test\test_importlib\import_\test_api.py" /> - <Compile Include="test\test_importlib\import_\test_caching.py" /> - <Compile Include="test\test_importlib\import_\test_fromlist.py" /> - <Compile Include="test\test_importlib\import_\test_meta_path.py" /> - <Compile Include="test\test_importlib\import_\test_packages.py" /> - <Compile Include="test\test_importlib\import_\test_path.py" /> - <Compile Include="test\test_importlib\import_\test_relative_imports.py" /> - <Compile Include="test\test_importlib\import_\test___loader__.py" /> - <Compile Include="test\test_importlib\import_\test___package__.py" /> - <Compile Include="test\test_importlib\import_\__init__.py" /> - <Compile Include="test\test_importlib\import_\__main__.py" /> - <Compile Include="test\test_importlib\namespace_pkgs\both_portions\foo\one.py" /> - <Compile Include="test\test_importlib\namespace_pkgs\both_portions\foo\two.py" /> - <Compile Include="test\test_importlib\namespace_pkgs\module_and_namespace_package\a_test.py" /> - <Compile Include="test\test_importlib\namespace_pkgs\not_a_namespace_pkg\foo\one.py" /> - <Compile Include="test\test_importlib\namespace_pkgs\not_a_namespace_pkg\foo\__init__.py" /> - <Compile Include="test\test_importlib\namespace_pkgs\portion1\foo\one.py" /> - <Compile Include="test\test_importlib\namespace_pkgs\portion2\foo\two.py" /> - <Compile Include="test\test_importlib\namespace_pkgs\project1\parent\child\one.py" /> - <Compile Include="test\test_importlib\namespace_pkgs\project2\parent\child\two.py" /> - <Compile Include="test\test_importlib\namespace_pkgs\project3\parent\child\three.py" /> - <Compile Include="test\test_importlib\source\test_case_sensitivity.py" /> - <Compile Include="test\test_importlib\source\test_file_loader.py" /> - <Compile Include="test\test_importlib\source\test_finder.py" /> - <Compile Include="test\test_importlib\source\test_path_hook.py" /> - <Compile Include="test\test_importlib\source\test_source_encoding.py" /> - <Compile Include="test\test_importlib\source\__init__.py" /> - <Compile Include="test\test_importlib\source\__main__.py" /> - <Compile Include="test\test_importlib\test_abc.py" /> - <Compile Include="test\test_importlib\test_api.py" /> - <Compile Include="test\test_importlib\test_lazy.py" /> - <Compile Include="test\test_importlib\test_locks.py" /> - <Compile Include="test\test_importlib\test_namespace_pkgs.py" /> - <Compile Include="test\test_importlib\test_spec.py" /> - <Compile Include="test\test_importlib\test_util.py" /> - <Compile Include="test\test_importlib\test_windows.py" /> - <Compile Include="test\test_importlib\util.py" /> - <Compile Include="test\test_importlib\__init__.py" /> - <Compile Include="test\test_importlib\__main__.py" /> - <Compile Include="test\test_import\data\circular_imports\basic.py" /> - <Compile Include="test\test_import\data\circular_imports\basic2.py" /> - <Compile Include="test\test_import\data\circular_imports\binding.py" /> - <Compile Include="test\test_import\data\circular_imports\binding2.py" /> - <Compile Include="test\test_import\data\circular_imports\indirect.py" /> - <Compile Include="test\test_import\data\circular_imports\rebinding.py" /> - <Compile Include="test\test_import\data\circular_imports\rebinding2.py" /> - <Compile Include="test\test_import\data\circular_imports\subpackage.py" /> - <Compile Include="test\test_import\data\circular_imports\subpkg\subpackage2.py" /> - <Compile Include="test\test_import\data\circular_imports\subpkg\util.py" /> - <Compile Include="test\test_import\data\circular_imports\util.py" /> - <Compile Include="test\test_import\data\package\__init__.py" /> - <Compile Include="test\test_import\data\package\submodule.py" /> - <Compile Include="test\test_import\data\package2\submodule1.py" /> - <Compile Include="test\test_import\data\package2\submodule2.py" /> - <Compile Include="test\test_import\data\unwritable\__init__.py" /> - <Compile Include="test\test_import\data\unwritable\x.py" /> - <Compile Include="test\test_import\__init__.py" /> - <Compile Include="test\test_import\__main__.py" /> - <Compile Include="test\test_index.py" /> - <Compile Include="test\test_inspect.py" /> - <Compile Include="test\test_int.py" /> - <Compile Include="test\test_int_literal.py" /> - <Compile Include="test\test_io.py" /> - <Compile Include="test\test_ioctl.py" /> - <Compile Include="test\test_ipaddress.py" /> - <Compile Include="test\test_isinstance.py" /> - <Compile Include="test\test_iter.py" /> - <Compile Include="test\test_iterlen.py" /> - <Compile Include="test\test_itertools.py" /> - <Compile Include="test\test_json\test_decode.py" /> - <Compile Include="test\test_json\test_default.py" /> - <Compile Include="test\test_json\test_dump.py" /> - <Compile Include="test\test_json\test_encode_basestring_ascii.py" /> - <Compile Include="test\test_json\test_enum.py" /> - <Compile Include="test\test_json\test_fail.py" /> - <Compile Include="test\test_json\test_float.py" /> - <Compile Include="test\test_json\test_indent.py" /> - <Compile Include="test\test_json\test_pass1.py" /> - <Compile Include="test\test_json\test_pass2.py" /> - <Compile Include="test\test_json\test_pass3.py" /> - <Compile Include="test\test_json\test_recursion.py" /> - <Compile Include="test\test_json\test_scanstring.py" /> - <Compile Include="test\test_json\test_separators.py" /> - <Compile Include="test\test_json\test_speedups.py" /> - <Compile Include="test\test_json\test_tool.py" /> - <Compile Include="test\test_json\test_unicode.py" /> - <Compile Include="test\test_json\__init__.py" /> - <Compile Include="test\test_json\__main__.py" /> - <Compile Include="test\test_keyword.py" /> - <Compile Include="test\test_keywordonlyarg.py" /> - <Compile Include="test\test_kqueue.py" /> - <Compile Include="test\test_largefile.py" /> - <Compile Include="test\test_lib2to3.py" /> - <Compile Include="test\test_linecache.py" /> - <Compile Include="test\test_list.py" /> - <Compile Include="test\test_listcomps.py" /> - <Compile Include="test\test_locale.py" /> - <Compile Include="test\test_logging.py" /> - <Compile Include="test\test_long.py" /> - <Compile Include="test\test_longexp.py" /> - <Compile Include="test\test_lzma.py" /> - <Compile Include="test\test_mailbox.py" /> - <Compile Include="test\test_mailcap.py" /> - <Compile Include="test\test_marshal.py" /> - <Compile Include="test\test_math.py" /> - <Compile Include="test\test_memoryio.py" /> - <Compile Include="test\test_memoryview.py" /> - <Compile Include="test\test_metaclass.py" /> - <Compile Include="test\test_mimetypes.py" /> - <Compile Include="test\test_minidom.py" /> - <Compile Include="test\test_mmap.py" /> - <Compile Include="test\test_module.py" /> - <Compile Include="test\test_modulefinder.py" /> - <Compile Include="test\test_multibytecodec.py" /> - <Compile Include="test\test_multiprocessing_fork.py" /> - <Compile Include="test\test_multiprocessing_forkserver.py" /> - <Compile Include="test\test_multiprocessing_main_handling.py" /> - <Compile Include="test\test_multiprocessing_spawn.py" /> - <Compile Include="test\test_netrc.py" /> - <Compile Include="test\test_nis.py" /> - <Compile Include="test\test_nntplib.py" /> - <Compile Include="test\test_ntpath.py" /> - <Compile Include="test\test_numeric_tower.py" /> - <Compile Include="test\test_opcache.py" /> - <Compile Include="test\test_opcodes.py" /> - <Compile Include="test\test_openpty.py" /> - <Compile Include="test\test_operator.py" /> - <Compile Include="test\test_optparse.py" /> - <Compile Include="test\test_ordered_dict.py" /> - <Compile Include="test\test_os.py" /> - <Compile Include="test\test_ossaudiodev.py" /> - <Compile Include="test\test_osx_env.py" /> - <Compile Include="test\test_parser.py" /> - <Compile Include="test\test_pathlib.py" /> - <Compile Include="test\test_pdb.py" /> - <Compile Include="test\test_peepholer.py" /> - <Compile Include="test\test_peg_generator\__init__.py" /> - <Compile Include="test\test_peg_generator\__main__.py" /> - <Compile Include="test\test_peg_generator\ast_dump.py" /> - <Compile Include="test\test_peg_generator\test_c_parser.py" /> - <Compile Include="test\test_peg_generator\test_first_sets.py" /> - <Compile Include="test\test_peg_generator\test_pegen.py" /> - <Compile Include="test\test_pickle.py" /> - <Compile Include="test\test_pickletools.py" /> - <Compile Include="test\test_pipes.py" /> - <Compile Include="test\test_pkg.py" /> - <Compile Include="test\test_pkgimport.py" /> - <Compile Include="test\test_pkgutil.py" /> - <Compile Include="test\test_platform.py" /> - <Compile Include="test\test_plistlib.py" /> - <Compile Include="test\test_poll.py" /> - <Compile Include="test\test_popen.py" /> - <Compile Include="test\test_poplib.py" /> - <Compile Include="test\test_posix.py" /> - <Compile Include="test\test_posixpath.py" /> - <Compile Include="test\test_pow.py" /> - <Compile Include="test\test_pprint.py" /> - <Compile Include="test\test_print.py" /> - <Compile Include="test\test_profile.py" /> - <Compile Include="test\test_property.py" /> - <Compile Include="test\test_pstats.py" /> - <Compile Include="test\test_pty.py" /> - <Compile Include="test\test_pulldom.py" /> - <Compile Include="test\test_pwd.py" /> - <Compile Include="test\test_pyclbr.py" /> - <Compile Include="test\test_pydoc.py" /> - <Compile Include="test\test_pyexpat.py" /> - <Compile Include="test\test_py_compile.py" /> - <Compile Include="test\test_queue.py" /> - <Compile Include="test\test_quopri.py" /> - <Compile Include="test\test_raise.py" /> - <Compile Include="test\test_random.py" /> - <Compile Include="test\test_range.py" /> - <Compile Include="test\test_re.py" /> - <Compile Include="test\test_readline.py" /> - <Compile Include="test\test_regrtest.py" /> - <Compile Include="test\test_reprlib.py" /> - <Compile Include="test\test_resource.py" /> - <Compile Include="test\test_richcmp.py" /> - <Compile Include="test\test_rlcompleter.py" /> - <Compile Include="test\test_robotparser.py" /> - <Compile Include="test\test_runpy.py" /> - <Compile Include="test\test_sax.py" /> - <Compile Include="test\test_sched.py" /> - <Compile Include="test\test_scope.py" /> - <Compile Include="test\test_script_helper.py" /> - <Compile Include="test\test_secrets.py" /> - <Compile Include="test\test_select.py" /> - <Compile Include="test\test_selectors.py" /> - <Compile Include="test\test_set.py" /> - <Compile Include="test\test_setcomps.py" /> - <Compile Include="test\test_shelve.py" /> - <Compile Include="test\test_shlex.py" /> - <Compile Include="test\test_shutil.py" /> - <Compile Include="test\test_signal.py" /> - <Compile Include="test\test_site.py" /> - <Compile Include="test\test_slice.py" /> - <Compile Include="test\test_smtpd.py" /> - <Compile Include="test\test_smtplib.py" /> - <Compile Include="test\test_smtpnet.py" /> - <Compile Include="test\test_sndhdr.py" /> - <Compile Include="test\test_socket.py" /> - <Compile Include="test\test_socketserver.py" /> - <Compile Include="test\test_sort.py" /> - <Compile Include="test\test_source_encoding.py" /> - <Compile Include="test\test_spwd.py" /> - <Compile Include="test\test_sqlite3" /> - <Compile Include="test\test_sqlite3\__init__.py" /> - <Compile Include="test\test_sqlite3\test_backup.py" /> - <Compile Include="test\test_sqlite3\test_dbapi.py" /> - <Compile Include="test\test_sqlite3\test_dump.py" /> - <Compile Include="test\test_sqlite3\test_factory.py" /> - <Compile Include="test\test_sqlite3\test_hooks.py" /> - <Compile Include="test\test_sqlite3\test_regression.py" /> - <Compile Include="test\test_sqlite3\test_transactions.py" /> - <Compile Include="test\test_sqlite3\test_types.py" /> - <Compile Include="test\test_sqlite3\test_userfunctions.py" /> - <Compile Include="test\test_ssl.py" /> - <Compile Include="test\test_startfile.py" /> - <Compile Include="test\test_stat.py" /> - <Compile Include="test\test_statistics.py" /> - <Compile Include="test\test_strftime.py" /> - <Compile Include="test\test_string.py" /> - <Compile Include="test\test_stringprep.py" /> - <Compile Include="test\test_string_literals.py" /> - <Compile Include="test\test_strptime.py" /> - <Compile Include="test\test_strtod.py" /> - <Compile Include="test\test_struct.py" /> - <Compile Include="test\test_structmembers.py" /> - <Compile Include="test\test_structseq.py" /> - <Compile Include="test\test_subclassinit.py" /> - <Compile Include="test\test_subprocess.py" /> - <Compile Include="test\test_sunau.py" /> - <Compile Include="test\test_sundry.py" /> - <Compile Include="test\test_super.py" /> - <Compile Include="test\test_support.py" /> - <Compile Include="test\test_symbol.py" /> - <Compile Include="test\test_symtable.py" /> - <Compile Include="test\test_syntax.py" /> - <Compile Include="test\test_sys.py" /> - <Compile Include="test\test_sysconfig.py" /> - <Compile Include="test\test_syslog.py" /> - <Compile Include="test\test_sys_setprofile.py" /> - <Compile Include="test\test_sys_settrace.py" /> - <Compile Include="test\test_tarfile.py" /> - <Compile Include="test\test_tcl.py" /> - <Compile Include="test\test_telnetlib.py" /> - <Compile Include="test\test_tempfile.py" /> - <Compile Include="test\test_textwrap.py" /> - <Compile Include="test\test_thread.py" /> - <Compile Include="test\test_threadedtempfile.py" /> - <Compile Include="test\test_threaded_import.py" /> - <Compile Include="test\test_threading.py" /> - <Compile Include="test\test_threading_local.py" /> - <Compile Include="test\test_threadsignals.py" /> - <Compile Include="test\test_time.py" /> - <Compile Include="test\test_timeit.py" /> - <Compile Include="test\test_timeout.py" /> - <Compile Include="test\test_tix.py" /> - <Compile Include="test\test_tk.py" /> - <Compile Include="test\test_tokenize.py" /> - <Compile Include="test\test_tools\test_fixcid.py" /> - <Compile Include="test\test_tools\test_gprof2html.py" /> - <Compile Include="test\test_tools\test_i18n.py" /> - <Compile Include="test\test_tools\test_md5sum.py" /> - <Compile Include="test\test_tools\test_pdeps.py" /> - <Compile Include="test\test_tools\test_pindent.py" /> - <Compile Include="test\test_tools\test_reindent.py" /> - <Compile Include="test\test_tools\test_sundry.py" /> - <Compile Include="test\test_tools\test_unparse.py" /> - <Compile Include="test\test_tools\__init__.py" /> - <Compile Include="test\test_tools\__main__.py" /> - <Compile Include="test\test_trace.py" /> - <Compile Include="test\test_traceback.py" /> - <Compile Include="test\test_tracemalloc.py" /> - <Compile Include="test\test_ttk_guionly.py" /> - <Compile Include="test\test_ttk_textonly.py" /> - <Compile Include="test\test_tuple.py" /> - <Compile Include="test\test_turtle.py" /> - <Compile Include="test\test_typechecks.py" /> - <Compile Include="test\test_types.py" /> - <Compile Include="test\test_typing.py" /> - <Compile Include="test\test_ucn.py" /> - <Compile Include="test\test_unary.py" /> - <Compile Include="test\test_unicode.py" /> - <Compile Include="test\test_unicodedata.py" /> - <Compile Include="test\test_unicode_file.py" /> - <Compile Include="test\test_unicode_file_functions.py" /> - <Compile Include="test\test_unicode_identifiers.py" /> - <Compile Include="test\test_unittest.py" /> - <Compile Include="test\test_univnewlines.py" /> - <Compile Include="test\test_unpack.py" /> - <Compile Include="test\test_unpack_ex.py" /> - <Compile Include="test\test_urllib.py" /> - <Compile Include="test\test_urllib2.py" /> - <Compile Include="test\test_urllib2net.py" /> - <Compile Include="test\test_urllib2_localnet.py" /> - <Compile Include="test\test_urllibnet.py" /> - <Compile Include="test\test_urllib_response.py" /> - <Compile Include="test\test_urlparse.py" /> - <Compile Include="test\test_userdict.py" /> - <Compile Include="test\test_userlist.py" /> - <Compile Include="test\test_userstring.py" /> - <Compile Include="test\test_utf8source.py" /> - <Compile Include="test\test_uu.py" /> - <Compile Include="test\test_uuid.py" /> - <Compile Include="test\test_venv.py" /> - <Compile Include="test\test_wait3.py" /> - <Compile Include="test\test_wait4.py" /> - <Compile Include="test\test_warnings\data\import_warning.py" /> - <Compile Include="test\test_warnings\data\stacklevel.py" /> - <Compile Include="test\test_warnings\__init__.py" /> - <Compile Include="test\test_warnings\__main__.py" /> - <Compile Include="test\test_wave.py" /> - <Compile Include="test\test_weakref.py" /> - <Compile Include="test\test_weakset.py" /> - <Compile Include="test\test_webbrowser.py" /> - <Compile Include="test\test_winconsoleio.py" /> - <Compile Include="test\test_winreg.py" /> - <Compile Include="test\test_winsound.py" /> - <Compile Include="test\test_with.py" /> - <Compile Include="test\test_wsgiref.py" /> - <Compile Include="test\test_xdrlib.py" /> - <Compile Include="test\test_xmlrpc.py" /> - <Compile Include="test\test_xmlrpc_net.py" /> - <Compile Include="test\test_xml_dom_minicompat.py" /> - <Compile Include="test\test_xml_etree.py" /> - <Compile Include="test\test_xml_etree_c.py" /> - <Compile Include="test\test_yield_from.py" /> - <Compile Include="test\test_zipapp.py" /> - <Compile Include="test\test_zipfile.py" /> - <Compile Include="test\test_zipfile64.py" /> - <Compile Include="test\test_zipimport.py" /> - <Compile Include="test\test_zipimport_support.py" /> - <Compile Include="test\test_zlib.py" /> - <Compile Include="test\test_zoneinfo\__init__.py" /> - <Compile Include="test\test_zoneinfo\__main__.py" /> - <Compile Include="test\test_zoneinfo\_support.py" /> - <Compile Include="test\test_zoneinfo\test_zoneinfo.py" /> - <Compile Include="test\test__locale.py" /> - <Compile Include="test\test__opcode.py" /> - <Compile Include="test\test__osx_support.py" /> - <Compile Include="test\test___all__.py" /> - <Compile Include="test\test___future__.py" /> - <Compile Include="test\tf_inherit_check.py" /> - <Compile Include="test\threaded_import_hangers.py" /> - <Compile Include="test\time_hashlib.py" /> - <Compile Include="test\tracedmodules\testmod.py" /> - <Compile Include="test\tracedmodules\__init__.py" /> - <Compile Include="test\win_console_handler.py" /> - <Compile Include="test\xmltests.py" /> - <Compile Include="test\_test_multiprocessing.py" /> - <Compile Include="test\__init__.py" /> - <Compile Include="test\__main__.py" /> - <Compile Include="textwrap.py" /> - <Compile Include="this.py" /> - <Compile Include="threading.py" /> - <Compile Include="timeit.py" /> - <Compile Include="tkinter\colorchooser.py" /> - <Compile Include="tkinter\commondialog.py" /> - <Compile Include="tkinter\constants.py" /> - <Compile Include="tkinter\dialog.py" /> - <Compile Include="tkinter\dnd.py" /> - <Compile Include="tkinter\filedialog.py" /> - <Compile Include="tkinter\font.py" /> - <Compile Include="tkinter\messagebox.py" /> - <Compile Include="tkinter\scrolledtext.py" /> - <Compile Include="tkinter\simpledialog.py" /> - <Compile Include="tkinter\test\support.py" /> - <Compile Include="tkinter\test\test_tkinter\test_font.py" /> - <Compile Include="tkinter\test\test_tkinter\test_geometry_managers.py" /> - <Compile Include="tkinter\test\test_tkinter\test_images.py" /> - <Compile Include="tkinter\test\test_tkinter\test_loadtk.py" /> - <Compile Include="tkinter\test\test_tkinter\test_misc.py" /> - <Compile Include="tkinter\test\test_tkinter\test_text.py" /> - <Compile Include="tkinter\test\test_tkinter\test_variables.py" /> - <Compile Include="tkinter\test\test_tkinter\test_widgets.py" /> - <Compile Include="tkinter\test\test_tkinter\__init__.py" /> - <Compile Include="tkinter\test\test_ttk\test_extensions.py" /> - <Compile Include="tkinter\test\test_ttk\test_style.py" /> - <Compile Include="tkinter\test\test_ttk\test_widgets.py" /> - <Compile Include="tkinter\test\test_ttk\__init__.py" /> - <Compile Include="tkinter\test\widget_tests.py" /> - <Compile Include="tkinter\test\__init__.py" /> - <Compile Include="tkinter\tix.py" /> - <Compile Include="tkinter\ttk.py" /> - <Compile Include="tkinter\__init__.py" /> - <Compile Include="tkinter\__main__.py" /> - <Compile Include="token.py" /> - <Compile Include="tokenize.py" /> - <Compile Include="trace.py" /> - <Compile Include="traceback.py" /> - <Compile Include="tracemalloc.py" /> - <Compile Include="tty.py" /> - <Compile Include="turtle.py" /> - <Compile Include="turtledemo\bytedesign.py" /> - <Compile Include="turtledemo\chaos.py" /> - <Compile Include="turtledemo\clock.py" /> - <Compile Include="turtledemo\colormixer.py" /> - <Compile Include="turtledemo\forest.py" /> - <Compile Include="turtledemo\fractalcurves.py" /> - <Compile Include="turtledemo\lindenmayer.py" /> - <Compile Include="turtledemo\minimal_hanoi.py" /> - <Compile Include="turtledemo\nim.py" /> - <Compile Include="turtledemo\paint.py" /> - <Compile Include="turtledemo\peace.py" /> - <Compile Include="turtledemo\penrose.py" /> - <Compile Include="turtledemo\planet_and_moon.py" /> - <Compile Include="turtledemo\round_dance.py" /> - <Compile Include="turtledemo\sorting_animate.py" /> - <Compile Include="turtledemo\tree.py" /> - <Compile Include="turtledemo\two_canvases.py" /> - <Compile Include="turtledemo\wikipedia.py" /> - <Compile Include="turtledemo\yinyang.py" /> - <Compile Include="turtledemo\__init__.py" /> - <Compile Include="turtledemo\__main__.py" /> - <Compile Include="types.py" /> - <Compile Include="typing.py" /> - <Compile Include="unittest\case.py" /> - <Compile Include="unittest\loader.py" /> - <Compile Include="unittest\main.py" /> - <Compile Include="unittest\mock.py" /> - <Compile Include="unittest\result.py" /> - <Compile Include="unittest\runner.py" /> - <Compile Include="unittest\signals.py" /> - <Compile Include="unittest\suite.py" /> - <Compile Include="unittest\test\dummy.py" /> - <Compile Include="unittest\test\support.py" /> - <Compile Include="unittest\test\testmock\support.py" /> - <Compile Include="unittest\test\testmock\testcallable.py" /> - <Compile Include="unittest\test\testmock\testhelpers.py" /> - <Compile Include="unittest\test\testmock\testmagicmethods.py" /> - <Compile Include="unittest\test\testmock\testmock.py" /> - <Compile Include="unittest\test\testmock\testpatch.py" /> - <Compile Include="unittest\test\testmock\testsentinel.py" /> - <Compile Include="unittest\test\testmock\testwith.py" /> - <Compile Include="unittest\test\testmock\__init__.py" /> - <Compile Include="unittest\test\testmock\__main__.py" /> - <Compile Include="unittest\test\test_assertions.py" /> - <Compile Include="unittest\test\test_break.py" /> - <Compile Include="unittest\test\test_case.py" /> - <Compile Include="unittest\test\test_discovery.py" /> - <Compile Include="unittest\test\test_functiontestcase.py" /> - <Compile Include="unittest\test\test_loader.py" /> - <Compile Include="unittest\test\test_program.py" /> - <Compile Include="unittest\test\test_result.py" /> - <Compile Include="unittest\test\test_runner.py" /> - <Compile Include="unittest\test\test_setups.py" /> - <Compile Include="unittest\test\test_skipping.py" /> - <Compile Include="unittest\test\test_suite.py" /> - <Compile Include="unittest\test\_test_warnings.py" /> - <Compile Include="unittest\test\__init__.py" /> - <Compile Include="unittest\test\__main__.py" /> - <Compile Include="unittest\util.py" /> - <Compile Include="unittest\__init__.py" /> - <Compile Include="unittest\__main__.py" /> - <Compile Include="urllib\error.py" /> - <Compile Include="urllib\parse.py" /> - <Compile Include="urllib\request.py" /> - <Compile Include="urllib\response.py" /> - <Compile Include="urllib\robotparser.py" /> - <Compile Include="urllib\__init__.py" /> - <Compile Include="uu.py" /> - <Compile Include="uuid.py" /> - <Compile Include="venv\__init__.py" /> - <Compile Include="venv\__main__.py" /> - <Compile Include="warnings.py" /> - <Compile Include="wave.py" /> - <Compile Include="weakref.py" /> - <Compile Include="webbrowser.py" /> - <Compile Include="wsgiref\handlers.py" /> - <Compile Include="wsgiref\headers.py" /> - <Compile Include="wsgiref\simple_server.py" /> - <Compile Include="wsgiref\util.py" /> - <Compile Include="wsgiref\validate.py" /> - <Compile Include="wsgiref\__init__.py" /> - <Compile Include="xdrlib.py" /> - <Compile Include="xmlrpc\client.py" /> - <Compile Include="xmlrpc\server.py" /> - <Compile Include="xmlrpc\__init__.py" /> - <Compile Include="xml\dom\domreg.py" /> - <Compile Include="xml\dom\expatbuilder.py" /> - <Compile Include="xml\dom\minicompat.py" /> - <Compile Include="xml\dom\minidom.py" /> - <Compile Include="xml\dom\NodeFilter.py" /> - <Compile Include="xml\dom\pulldom.py" /> - <Compile Include="xml\dom\xmlbuilder.py" /> - <Compile Include="xml\dom\__init__.py" /> - <Compile Include="xml\etree\cElementTree.py" /> - <Compile Include="xml\etree\ElementInclude.py" /> - <Compile Include="xml\etree\ElementPath.py" /> - <Compile Include="xml\etree\ElementTree.py" /> - <Compile Include="xml\etree\__init__.py" /> - <Compile Include="xml\parsers\expat.py" /> - <Compile Include="xml\parsers\__init__.py" /> - <Compile Include="xml\sax\expatreader.py" /> - <Compile Include="xml\sax\handler.py" /> - <Compile Include="xml\sax\saxutils.py" /> - <Compile Include="xml\sax\xmlreader.py" /> - <Compile Include="xml\sax\_exceptions.py" /> - <Compile Include="xml\sax\__init__.py" /> - <Compile Include="xml\__init__.py" /> - <Compile Include="zipapp.py" /> - <Compile Include="zipfile.py" /> - <Compile Include="zoneinfo\_common.py" /> - <Compile Include="zoneinfo\__init__.py" /> - <Compile Include="zoneinfo\_tzpath.py" /> - <Compile Include="zoneinfo\_zoneinfo.py" /> - <Compile Include="_collections_abc.py" /> - <Compile Include="_compat_pickle.py" /> - <Compile Include="_compression.py" /> - <Compile Include="_markupbase.py" /> - <Compile Include="_osx_support.py" /> - <Compile Include="_pydecimal.py" /> - <Compile Include="_pyio.py" /> - <Compile Include="_sitebuiltins.py" /> - <Compile Include="_strptime.py" /> - <Compile Include="_threading_local.py" /> - <Compile Include="_weakrefset.py" /> - <Compile Include="__future__.py" /> - <Compile Include="__phello__.foo.py" /> - </ItemGroup> - <ItemGroup> - <Content Include="idlelib\CREDITS.txt" /> - <Content Include="idlelib\extend.txt" /> - <Content Include="idlelib\help.html" /> - <Content Include="idlelib\HISTORY.txt" /> - <Content Include="idlelib\Icons\folder.gif" /> - <Content Include="idlelib\Icons\idle.ico" /> - <Content Include="idlelib\Icons\idle_16.gif" /> - <Content Include="idlelib\Icons\idle_16.png" /> - <Content Include="idlelib\Icons\idle_32.gif" /> - <Content Include="idlelib\Icons\idle_32.png" /> - <Content Include="idlelib\Icons\idle_48.gif" /> - <Content Include="idlelib\Icons\idle_48.png" /> - <Content Include="idlelib\Icons\idle_256.png" /> - <Content Include="idlelib\Icons\minusnode.gif" /> - <Content Include="idlelib\Icons\openfolder.gif" /> - <Content Include="idlelib\Icons\plusnode.gif" /> - <Content Include="idlelib\Icons\python.gif" /> - <Content Include="idlelib\Icons\tk.gif" /> - <Content Include="idlelib\idle_test\README.txt" /> - <Content Include="idlelib\NEWS.txt" /> - <Content Include="idlelib\NEWS2x.txt" /> - <Content Include="idlelib\README.txt" /> - <Content Include="idlelib\TODO.txt" /> - <Content Include="lib2to3\Grammar.txt" /> - <Content Include="lib2to3\PatternGrammar.txt" /> - <Content Include="pydoc_data\_pydoc.css" /> - <Content Include="site-packages\README.txt" /> - <Content Include="test\cjkencodings\big5-utf8.txt" /> - <Content Include="test\cjkencodings\big5.txt" /> - <Content Include="test\cjkencodings\big5hkscs-utf8.txt" /> - <Content Include="test\cjkencodings\big5hkscs.txt" /> - <Content Include="test\cjkencodings\cp949-utf8.txt" /> - <Content Include="test\cjkencodings\cp949.txt" /> - <Content Include="test\cjkencodings\euc_jisx0213-utf8.txt" /> - <Content Include="test\cjkencodings\euc_jisx0213.txt" /> - <Content Include="test\cjkencodings\euc_jp-utf8.txt" /> - <Content Include="test\cjkencodings\euc_jp.txt" /> - <Content Include="test\cjkencodings\euc_kr-utf8.txt" /> - <Content Include="test\cjkencodings\euc_kr.txt" /> - <Content Include="test\cjkencodings\gb18030-utf8.txt" /> - <Content Include="test\cjkencodings\gb18030.txt" /> - <Content Include="test\cjkencodings\gb2312-utf8.txt" /> - <Content Include="test\cjkencodings\gb2312.txt" /> - <Content Include="test\cjkencodings\gbk-utf8.txt" /> - <Content Include="test\cjkencodings\gbk.txt" /> - <Content Include="test\cjkencodings\hz-utf8.txt" /> - <Content Include="test\cjkencodings\hz.txt" /> - <Content Include="test\cjkencodings\iso2022_jp-utf8.txt" /> - <Content Include="test\cjkencodings\iso2022_jp.txt" /> - <Content Include="test\cjkencodings\iso2022_kr-utf8.txt" /> - <Content Include="test\cjkencodings\iso2022_kr.txt" /> - <Content Include="test\cjkencodings\johab-utf8.txt" /> - <Content Include="test\cjkencodings\johab.txt" /> - <Content Include="test\cjkencodings\shift_jis-utf8.txt" /> - <Content Include="test\cjkencodings\shift_jis.txt" /> - <Content Include="test\cjkencodings\shift_jisx0213-utf8.txt" /> - <Content Include="test\cjkencodings\shift_jisx0213.txt" /> - <Content Include="test\cmath_testcases.txt" /> - <Content Include="test\exception_hierarchy.txt" /> - <Content Include="test\floating_points.txt" /> - <Content Include="test\formatfloat_testcases.txt" /> - <Content Include="test\ieee754.txt" /> - <Content Include="test\imghdrdata\python.bmp" /> - <Content Include="test\imghdrdata\python.gif" /> - <Content Include="test\imghdrdata\python.jpg" /> - <Content Include="test\imghdrdata\python.png" /> - <Content Include="test\leakers\README.txt" /> - <Content Include="test\mailcap.txt" /> - <Content Include="test\math_testcases.txt" /> - <Content Include="test\sgml_input.html" /> - <Content Include="test\test_difflib_expect.html" /> - <Content Include="test\test_doctest.txt" /> - <Content Include="test\test_doctest2.txt" /> - <Content Include="test\test_doctest3.txt" /> - <Content Include="test\test_doctest4.txt" /> - <Content Include="test\test_email\data\msg_01.txt" /> - <Content Include="test\test_email\data\msg_02.txt" /> - <Content Include="test\test_email\data\msg_03.txt" /> - <Content Include="test\test_email\data\msg_04.txt" /> - <Content Include="test\test_email\data\msg_05.txt" /> - <Content Include="test\test_email\data\msg_06.txt" /> - <Content Include="test\test_email\data\msg_07.txt" /> - <Content Include="test\test_email\data\msg_08.txt" /> - <Content Include="test\test_email\data\msg_09.txt" /> - <Content Include="test\test_email\data\msg_10.txt" /> - <Content Include="test\test_email\data\msg_11.txt" /> - <Content Include="test\test_email\data\msg_12.txt" /> - <Content Include="test\test_email\data\msg_12a.txt" /> - <Content Include="test\test_email\data\msg_13.txt" /> - <Content Include="test\test_email\data\msg_14.txt" /> - <Content Include="test\test_email\data\msg_15.txt" /> - <Content Include="test\test_email\data\msg_16.txt" /> - <Content Include="test\test_email\data\msg_17.txt" /> - <Content Include="test\test_email\data\msg_18.txt" /> - <Content Include="test\test_email\data\msg_19.txt" /> - <Content Include="test\test_email\data\msg_20.txt" /> - <Content Include="test\test_email\data\msg_21.txt" /> - <Content Include="test\test_email\data\msg_22.txt" /> - <Content Include="test\test_email\data\msg_23.txt" /> - <Content Include="test\test_email\data\msg_24.txt" /> - <Content Include="test\test_email\data\msg_25.txt" /> - <Content Include="test\test_email\data\msg_26.txt" /> - <Content Include="test\test_email\data\msg_27.txt" /> - <Content Include="test\test_email\data\msg_28.txt" /> - <Content Include="test\test_email\data\msg_29.txt" /> - <Content Include="test\test_email\data\msg_30.txt" /> - <Content Include="test\test_email\data\msg_31.txt" /> - <Content Include="test\test_email\data\msg_32.txt" /> - <Content Include="test\test_email\data\msg_33.txt" /> - <Content Include="test\test_email\data\msg_34.txt" /> - <Content Include="test\test_email\data\msg_35.txt" /> - <Content Include="test\test_email\data\msg_36.txt" /> - <Content Include="test\test_email\data\msg_37.txt" /> - <Content Include="test\test_email\data\msg_38.txt" /> - <Content Include="test\test_email\data\msg_39.txt" /> - <Content Include="test\test_email\data\msg_40.txt" /> - <Content Include="test\test_email\data\msg_41.txt" /> - <Content Include="test\test_email\data\msg_42.txt" /> - <Content Include="test\test_email\data\msg_43.txt" /> - <Content Include="test\test_email\data\msg_44.txt" /> - <Content Include="test\test_email\data\msg_45.txt" /> - <Content Include="test\test_email\data\msg_46.txt" /> - <Content Include="test\test_email\data\PyBanner048.gif" /> - <Content Include="test\tokenize_tests-latin1-coding-cookie-and-utf8-bom-sig.txt" /> - <Content Include="test\tokenize_tests-no-coding-cookie-and-utf8-bom-sig-only.txt" /> - <Content Include="test\tokenize_tests-utf8-coding-cookie-and-no-utf8-bom-sig.txt" /> - <Content Include="test\tokenize_tests-utf8-coding-cookie-and-utf8-bom-sig.txt" /> - <Content Include="test\tokenize_tests.txt" /> - </ItemGroup> - <ItemGroup> - <Folder Include="asyncio" /> - <Folder Include="collections" /> - <Folder Include="concurrent" /> - <Folder Include="concurrent\futures" /> - <Folder Include="ctypes" /> - <Folder Include="ctypes\macholib" /> - <Folder Include="ctypes\test" /> - <Folder Include="curses" /> - <Folder Include="dbm" /> - <Folder Include="distutils" /> - <Folder Include="distutils\command" /> - <Folder Include="distutils\tests" /> - <Folder Include="email" /> - <Folder Include="email\mime" /> - <Folder Include="encodings" /> - <Folder Include="ensurepip" /> - <Folder Include="html" /> - <Folder Include="http" /> - <Folder Include="idlelib" /> - <Folder Include="idlelib\Icons" /> - <Folder Include="idlelib\idle_test" /> - <Folder Include="importlib" /> - <Folder Include="json" /> - <Folder Include="lib2to3" /> - <Folder Include="lib2to3\fixes" /> - <Folder Include="lib2to3\pgen2" /> - <Folder Include="lib2to3\tests" /> - <Folder Include="lib2to3\tests\data" /> - <Folder Include="lib2to3\tests\data\fixers" /> - <Folder Include="lib2to3\tests\data\fixers\myfixes" /> - <Folder Include="logging" /> - <Folder Include="msilib" /> - <Folder Include="multiprocessing" /> - <Folder Include="multiprocessing\dummy" /> - <Folder Include="pydoc_data" /> - <Folder Include="site-packages" /> - <Folder Include="sqlite3" /> - <Folder Include="sqlite3\test" /> - <Folder Include="test" /> - <Folder Include="test\cjkencodings" /> - <Folder Include="test\crashers" /> - <Folder Include="test\dtracedata" /> - <Folder Include="test\eintrdata" /> - <Folder Include="test\encoded_modules" /> - <Folder Include="test\imghdrdata" /> - <Folder Include="test\leakers" /> - <Folder Include="test\libregrtest" /> - <Folder Include="test\subprocessdata" /> - <Folder Include="test\support" /> - <Folder Include="test\test_asyncio" /> - <Folder Include="test\test_email" /> - <Folder Include="test\test_email\data" /> - <Folder Include="test\test_import" /> - <Folder Include="test\test_importlib" /> - <Folder Include="test\test_importlib\builtin" /> - <Folder Include="test\test_importlib\extension" /> - <Folder Include="test\test_importlib\frozen" /> - <Folder Include="test\test_importlib\import_" /> - <Folder Include="test\test_importlib\namespace_pkgs\" /> - <Folder Include="test\test_importlib\namespace_pkgs\both_portions\" /> - <Folder Include="test\test_importlib\namespace_pkgs\both_portions\foo" /> - <Folder Include="test\test_importlib\namespace_pkgs\module_and_namespace_package" /> - <Folder Include="test\test_importlib\namespace_pkgs\not_a_namespace_pkg\" /> - <Folder Include="test\test_importlib\namespace_pkgs\not_a_namespace_pkg\foo" /> - <Folder Include="test\test_importlib\namespace_pkgs\portion1\" /> - <Folder Include="test\test_importlib\namespace_pkgs\portion1\foo" /> - <Folder Include="test\test_importlib\namespace_pkgs\portion2\" /> - <Folder Include="test\test_importlib\namespace_pkgs\portion2\foo" /> - <Folder Include="test\test_importlib\namespace_pkgs\project1\" /> - <Folder Include="test\test_importlib\namespace_pkgs\project1\parent\" /> - <Folder Include="test\test_importlib\namespace_pkgs\project1\parent\child" /> - <Folder Include="test\test_importlib\namespace_pkgs\project2\" /> - <Folder Include="test\test_importlib\namespace_pkgs\project2\parent\" /> - <Folder Include="test\test_importlib\namespace_pkgs\project2\parent\child" /> - <Folder Include="test\test_importlib\namespace_pkgs\project3\" /> - <Folder Include="test\test_importlib\namespace_pkgs\project3\parent\" /> - <Folder Include="test\test_importlib\namespace_pkgs\project3\parent\child" /> - <Folder Include="test\test_importlib\source" /> - <Folder Include="test\test_import\data\" /> - <Folder Include="test\test_import\data\circular_imports" /> - <Folder Include="test\test_import\data\circular_imports\subpkg" /> - <Folder Include="test\test_import\data\package" /> - <Folder Include="test\test_import\data\package2" /> - <Folder Include="test\test_json" /> - <Folder Include="test\test_peg_generator" /> - <Folder Include="test\test_tools" /> - <Folder Include="test\test_warnings" /> - <Folder Include="test\test_warnings\data" /> - <Folder Include="test\tracedmodules" /> - <Folder Include="tkinter" /> - <Folder Include="tkinter\test" /> - <Folder Include="tkinter\test\test_tkinter" /> - <Folder Include="tkinter\test\test_ttk" /> - <Folder Include="turtledemo" /> - <Folder Include="unittest" /> - <Folder Include="unittest\test" /> - <Folder Include="unittest\test\testmock" /> - <Folder Include="urllib" /> - <Folder Include="venv" /> - <Folder Include="wsgiref" /> - <Folder Include="xml" /> - <Folder Include="xmlrpc" /> - <Folder Include="xml\dom" /> - <Folder Include="xml\etree" /> - <Folder Include="xml\parsers" /> - <Folder Include="xml\sax" /> - </ItemGroup> - <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Python Tools\Microsoft.PythonTools.targets" /> -</Project> diff --git a/PCbuild/libffi.props b/PCbuild/libffi.props index c14ff064..22c9550e 100644 --- a/PCbuild/libffi.props +++ b/PCbuild/libffi.props @@ -1,21 +1,21 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemDefinitionGroup> - <ClCompile> - <AdditionalIncludeDirectories>$(libffiIncludeDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - </ClCompile> - <Link> - <AdditionalLibraryDirectories>$(libffiOutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> - <AdditionalDependencies>libffi-8.lib;%(AdditionalDependencies)</AdditionalDependencies> - </Link> - </ItemDefinitionGroup> - <ItemGroup> - <_LIBFFIDLL Include="$(libffiOutDir)\libffi-8.dll" /> - </ItemGroup> - <Target Name="_CopyLIBFFIDLL" Inputs="@(_LIBFFIDLL)" Outputs="@(_LIBFFIDLL->'$(OutDir)%(Filename)%(Extension)')" AfterTargets="Build"> - <Copy SourceFiles="@(_LIBFFIDLL)" DestinationFolder="$(OutDir)" /> - </Target> - <Target Name="_CleanLIBFFIDLL" BeforeTargets="Clean"> - <Delete Files="@(_LIBFFIDLL->'$(OutDir)%(Filename)%(Extension)')" TreatErrorsAsWarnings="true" /> - </Target> +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemDefinitionGroup> + <ClCompile> + <AdditionalIncludeDirectories>$(libffiIncludeDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <AdditionalLibraryDirectories>$(libffiOutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + <AdditionalDependencies>libffi-8.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <_LIBFFIDLL Include="$(libffiOutDir)\libffi-8.dll" /> + </ItemGroup> + <Target Name="_CopyLIBFFIDLL" Inputs="@(_LIBFFIDLL)" Outputs="@(_LIBFFIDLL->'$(OutDir)%(Filename)%(Extension)')" AfterTargets="Build"> + <Copy SourceFiles="@(_LIBFFIDLL)" DestinationFolder="$(OutDir)" /> + </Target> + <Target Name="_CleanLIBFFIDLL" BeforeTargets="Clean"> + <Delete Files="@(_LIBFFIDLL->'$(OutDir)%(Filename)%(Extension)')" TreatErrorsAsWarnings="true" /> + </Target> </Project> \ No newline at end of file diff --git a/PCbuild/liblzma.vcxproj b/PCbuild/liblzma.vcxproj index fb1e37d1..4dd42ab9 100644 --- a/PCbuild/liblzma.vcxproj +++ b/PCbuild/liblzma.vcxproj @@ -1,246 +1,246 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|ARM"> - <Configuration>Debug</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|ARM64"> - <Configuration>Debug</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM"> - <Configuration>Release</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM64"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM64"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM64"> - <Configuration>Release</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|Win32"> - <Configuration>PGInstrument</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|x64"> - <Configuration>PGInstrument</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|Win32"> - <Configuration>PGUpdate</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|x64"> - <Configuration>PGUpdate</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectGuid>{12728250-16EC-4DC6-94D7-E21DD88947F8}</ProjectGuid> - <RootNamespace>liblzma</RootNamespace> - <SupportPGO>true</SupportPGO> - </PropertyGroup> - - <Import Project="python.props" /> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - - <PropertyGroup Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="pyproject.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup> - <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> - </PropertyGroup> - <ItemDefinitionGroup> - <ClCompile> - <PreprocessorDefinitions>WIN32;HAVE_CONFIG_H;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories>$(lzmaDir)windows/vs2019;$(lzmaDir)src/liblzma/common;$(lzmaDir)src/common;$(lzmaDir)src/liblzma/api;$(lzmaDir)src/liblzma/check;$(lzmaDir)src/liblzma/delta;$(lzmaDir)src/liblzma/lz;$(lzmaDir)src/liblzma/lzma;$(lzmaDir)src/liblzma/rangecoder;$(lzmaDir)src/liblzma/simple;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <DisableSpecificWarnings>4028;4113;4133;4244;4267;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings> - </ClCompile> - </ItemDefinitionGroup> - <ItemGroup> - <ClCompile Include="$(lzmaDir)src\common\tuklib_cpucores.c" /> - <ClCompile Include="$(lzmaDir)src\common\tuklib_physmem.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\check\check.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\check\crc32_fast.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\check\crc32_table.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\check\crc64_fast.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\check\crc64_table.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\check\sha256.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\common\alone_decoder.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\common\alone_encoder.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\common\auto_decoder.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\common\block_buffer_decoder.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\common\block_buffer_encoder.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\common\block_decoder.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\common\block_encoder.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\common\block_header_decoder.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\common\block_header_encoder.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\common\block_util.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\common\common.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\common\easy_buffer_encoder.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\common\easy_decoder_memusage.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\common\easy_encoder.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\common\easy_encoder_memusage.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\common\easy_preset.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\common\filter_buffer_decoder.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\common\filter_buffer_encoder.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\common\filter_common.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\common\filter_decoder.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\common\filter_encoder.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\common\filter_flags_decoder.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\common\filter_flags_encoder.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\common\hardware_cputhreads.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\common\hardware_physmem.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\common\index.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\common\index_decoder.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\common\index_encoder.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\common\index_hash.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\common\outqueue.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\common\stream_buffer_decoder.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\common\stream_buffer_encoder.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\common\stream_decoder.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\common\stream_encoder.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\common\stream_encoder_mt.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\common\stream_flags_common.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\common\stream_flags_decoder.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\common\stream_flags_encoder.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\common\vli_decoder.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\common\vli_encoder.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\common\vli_size.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\delta\delta_common.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\delta\delta_decoder.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\delta\delta_encoder.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\lzma\fastpos_table.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\lzma\lzma2_decoder.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\lzma\lzma2_encoder.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\lzma\lzma_decoder.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\lzma\lzma_encoder.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\lzma\lzma_encoder_optimum_fast.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\lzma\lzma_encoder_optimum_normal.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\lzma\lzma_encoder_presets.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\lz\lz_decoder.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\lz\lz_encoder.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\lz\lz_encoder_mf.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\rangecoder\price_table.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\simple\arm.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\simple\armthumb.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\simple\ia64.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\simple\powerpc.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\simple\simple_coder.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\simple\simple_decoder.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\simple\simple_encoder.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\simple\sparc.c" /> - <ClCompile Include="$(lzmaDir)src\liblzma\simple\x86.c" /> - </ItemGroup> - <ItemGroup> - <ClInclude Include="$(lzmaDir)src\common\mythread.h" /> - <ClInclude Include="$(lzmaDir)src\common\sysdefs.h" /> - <ClInclude Include="$(lzmaDir)src\common\tuklib_common.h" /> - <ClInclude Include="$(lzmaDir)src\common\tuklib_config.h" /> - <ClInclude Include="$(lzmaDir)src\common\tuklib_cpucores.h" /> - <ClInclude Include="$(lzmaDir)src\common\tuklib_integer.h" /> - <ClInclude Include="$(lzmaDir)src\common\tuklib_physmem.h" /> - <ClInclude Include="$(lzmaDir)src\liblzma\api\lzma.h" /> - <ClInclude Include="$(lzmaDir)src\liblzma\api\lzma\base.h" /> - <ClInclude Include="$(lzmaDir)src\liblzma\api\lzma\bcj.h" /> - <ClInclude Include="$(lzmaDir)src\liblzma\api\lzma\block.h" /> - <ClInclude Include="$(lzmaDir)src\liblzma\api\lzma\check.h" /> - <ClInclude Include="$(lzmaDir)src\liblzma\api\lzma\container.h" /> - <ClInclude Include="$(lzmaDir)src\liblzma\api\lzma\delta.h" /> - <ClInclude Include="$(lzmaDir)src\liblzma\api\lzma\filter.h" /> - <ClInclude Include="$(lzmaDir)src\liblzma\api\lzma\hardware.h" /> - <ClInclude Include="$(lzmaDir)src\liblzma\api\lzma\index.h" /> - <ClInclude Include="$(lzmaDir)src\liblzma\api\lzma\index_hash.h" /> - <ClInclude Include="$(lzmaDir)src\liblzma\api\lzma\lzma12.h" /> - <ClInclude Include="$(lzmaDir)src\liblzma\api\lzma\stream_flags.h" /> - <ClInclude Include="$(lzmaDir)src\liblzma\api\lzma\version.h" /> - <ClInclude Include="$(lzmaDir)src\liblzma\api\lzma\vli.h" /> - <ClInclude Include="$(lzmaDir)src\liblzma\check\check.h" /> - <ClInclude Include="$(lzmaDir)src\liblzma\check\crc32_table_be.h" /> - <ClInclude Include="$(lzmaDir)src\liblzma\check\crc32_table_le.h" /> - <ClInclude Include="$(lzmaDir)src\liblzma\check\crc64_table_be.h" /> - <ClInclude Include="$(lzmaDir)src\liblzma\check\crc64_table_le.h" /> - <ClInclude Include="$(lzmaDir)src\liblzma\check\crc_macros.h" /> - <ClInclude Include="$(lzmaDir)src\liblzma\common\alone_decoder.h" /> - <ClInclude Include="$(lzmaDir)src\liblzma\common\block_buffer_encoder.h" /> - <ClInclude Include="$(lzmaDir)src\liblzma\common\block_decoder.h" /> - <ClInclude Include="$(lzmaDir)src\liblzma\common\block_encoder.h" /> - <ClInclude Include="$(lzmaDir)src\liblzma\common\common.h" /> - <ClInclude Include="$(lzmaDir)src\liblzma\common\easy_preset.h" /> - <ClInclude Include="$(lzmaDir)src\liblzma\common\filter_common.h" /> - <ClInclude Include="$(lzmaDir)src\liblzma\common\filter_decoder.h" /> - <ClInclude Include="$(lzmaDir)src\liblzma\common\filter_encoder.h" /> - <ClInclude Include="$(lzmaDir)src\liblzma\common\index.h" /> - <ClInclude Include="$(lzmaDir)src\liblzma\common\index_encoder.h" /> - <ClInclude Include="$(lzmaDir)src\liblzma\common\memcmplen.h" /> - <ClInclude Include="$(lzmaDir)src\liblzma\common\outqueue.h" /> - <ClInclude Include="$(lzmaDir)src\liblzma\common\stream_decoder.h" /> - <ClInclude Include="$(lzmaDir)src\liblzma\common\stream_flags_common.h" /> - <ClInclude Include="$(lzmaDir)src\liblzma\delta\delta_common.h" /> - <ClInclude Include="$(lzmaDir)src\liblzma\delta\delta_decoder.h" /> - <ClInclude Include="$(lzmaDir)src\liblzma\delta\delta_encoder.h" /> - <ClInclude Include="$(lzmaDir)src\liblzma\delta\delta_private.h" /> - <ClInclude Include="$(lzmaDir)src\liblzma\lzma\fastpos.h" /> - <ClInclude Include="$(lzmaDir)src\liblzma\lzma\lzma2_decoder.h" /> - <ClInclude Include="$(lzmaDir)src\liblzma\lzma\lzma2_encoder.h" /> - <ClInclude Include="$(lzmaDir)src\liblzma\lzma\lzma_common.h" /> - <ClInclude Include="$(lzmaDir)src\liblzma\lzma\lzma_decoder.h" /> - <ClInclude Include="$(lzmaDir)src\liblzma\lzma\lzma_encoder.h" /> - <ClInclude Include="$(lzmaDir)src\liblzma\lzma\lzma_encoder_private.h" /> - <ClInclude Include="$(lzmaDir)src\liblzma\lz\lz_decoder.h" /> - <ClInclude Include="$(lzmaDir)src\liblzma\lz\lz_encoder.h" /> - <ClInclude Include="$(lzmaDir)src\liblzma\lz\lz_encoder_hash.h" /> - <ClInclude Include="$(lzmaDir)src\liblzma\lz\lz_encoder_hash_table.h" /> - <ClInclude Include="$(lzmaDir)src\liblzma\rangecoder\price.h" /> - <ClInclude Include="$(lzmaDir)src\liblzma\rangecoder\range_common.h" /> - <ClInclude Include="$(lzmaDir)src\liblzma\rangecoder\range_decoder.h" /> - <ClInclude Include="$(lzmaDir)src\liblzma\rangecoder\range_encoder.h" /> - <ClInclude Include="$(lzmaDir)src\liblzma\simple\simple_coder.h" /> - <ClInclude Include="$(lzmaDir)src\liblzma\simple\simple_decoder.h" /> - <ClInclude Include="$(lzmaDir)src\liblzma\simple\simple_encoder.h" /> - <ClInclude Include="$(lzmaDir)src\liblzma\simple\simple_private.h" /> - <ClInclude Include="$(lzmaDir)windows\vs2019\config.h" /> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> -</Project> +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|ARM"> + <Configuration>Debug</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|ARM64"> + <Configuration>Debug</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM"> + <Configuration>Release</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM64"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM64"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM64"> + <Configuration>Release</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|Win32"> + <Configuration>PGInstrument</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|x64"> + <Configuration>PGInstrument</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|Win32"> + <Configuration>PGUpdate</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|x64"> + <Configuration>PGUpdate</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{12728250-16EC-4DC6-94D7-E21DD88947F8}</ProjectGuid> + <RootNamespace>liblzma</RootNamespace> + <SupportPGO>true</SupportPGO> + </PropertyGroup> + + <Import Project="python.props" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + + <PropertyGroup Label="Configuration"> + <ConfigurationType>StaticLibrary</ConfigurationType> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="pyproject.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> + </PropertyGroup> + <ItemDefinitionGroup> + <ClCompile> + <PreprocessorDefinitions>WIN32;HAVE_CONFIG_H;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(lzmaDir)windows/vs2019;$(lzmaDir)src/liblzma/common;$(lzmaDir)src/common;$(lzmaDir)src/liblzma/api;$(lzmaDir)src/liblzma/check;$(lzmaDir)src/liblzma/delta;$(lzmaDir)src/liblzma/lz;$(lzmaDir)src/liblzma/lzma;$(lzmaDir)src/liblzma/rangecoder;$(lzmaDir)src/liblzma/simple;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <DisableSpecificWarnings>4028;4113;4133;4244;4267;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings> + </ClCompile> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="$(lzmaDir)src\common\tuklib_cpucores.c" /> + <ClCompile Include="$(lzmaDir)src\common\tuklib_physmem.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\check\check.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\check\crc32_fast.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\check\crc32_table.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\check\crc64_fast.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\check\crc64_table.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\check\sha256.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\common\alone_decoder.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\common\alone_encoder.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\common\auto_decoder.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\common\block_buffer_decoder.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\common\block_buffer_encoder.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\common\block_decoder.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\common\block_encoder.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\common\block_header_decoder.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\common\block_header_encoder.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\common\block_util.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\common\common.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\common\easy_buffer_encoder.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\common\easy_decoder_memusage.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\common\easy_encoder.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\common\easy_encoder_memusage.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\common\easy_preset.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\common\filter_buffer_decoder.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\common\filter_buffer_encoder.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\common\filter_common.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\common\filter_decoder.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\common\filter_encoder.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\common\filter_flags_decoder.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\common\filter_flags_encoder.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\common\hardware_cputhreads.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\common\hardware_physmem.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\common\index.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\common\index_decoder.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\common\index_encoder.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\common\index_hash.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\common\outqueue.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\common\stream_buffer_decoder.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\common\stream_buffer_encoder.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\common\stream_decoder.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\common\stream_encoder.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\common\stream_encoder_mt.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\common\stream_flags_common.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\common\stream_flags_decoder.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\common\stream_flags_encoder.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\common\vli_decoder.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\common\vli_encoder.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\common\vli_size.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\delta\delta_common.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\delta\delta_decoder.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\delta\delta_encoder.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\lzma\fastpos_table.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\lzma\lzma2_decoder.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\lzma\lzma2_encoder.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\lzma\lzma_decoder.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\lzma\lzma_encoder.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\lzma\lzma_encoder_optimum_fast.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\lzma\lzma_encoder_optimum_normal.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\lzma\lzma_encoder_presets.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\lz\lz_decoder.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\lz\lz_encoder.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\lz\lz_encoder_mf.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\rangecoder\price_table.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\simple\arm.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\simple\armthumb.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\simple\ia64.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\simple\powerpc.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\simple\simple_coder.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\simple\simple_decoder.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\simple\simple_encoder.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\simple\sparc.c" /> + <ClCompile Include="$(lzmaDir)src\liblzma\simple\x86.c" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="$(lzmaDir)src\common\mythread.h" /> + <ClInclude Include="$(lzmaDir)src\common\sysdefs.h" /> + <ClInclude Include="$(lzmaDir)src\common\tuklib_common.h" /> + <ClInclude Include="$(lzmaDir)src\common\tuklib_config.h" /> + <ClInclude Include="$(lzmaDir)src\common\tuklib_cpucores.h" /> + <ClInclude Include="$(lzmaDir)src\common\tuklib_integer.h" /> + <ClInclude Include="$(lzmaDir)src\common\tuklib_physmem.h" /> + <ClInclude Include="$(lzmaDir)src\liblzma\api\lzma.h" /> + <ClInclude Include="$(lzmaDir)src\liblzma\api\lzma\base.h" /> + <ClInclude Include="$(lzmaDir)src\liblzma\api\lzma\bcj.h" /> + <ClInclude Include="$(lzmaDir)src\liblzma\api\lzma\block.h" /> + <ClInclude Include="$(lzmaDir)src\liblzma\api\lzma\check.h" /> + <ClInclude Include="$(lzmaDir)src\liblzma\api\lzma\container.h" /> + <ClInclude Include="$(lzmaDir)src\liblzma\api\lzma\delta.h" /> + <ClInclude Include="$(lzmaDir)src\liblzma\api\lzma\filter.h" /> + <ClInclude Include="$(lzmaDir)src\liblzma\api\lzma\hardware.h" /> + <ClInclude Include="$(lzmaDir)src\liblzma\api\lzma\index.h" /> + <ClInclude Include="$(lzmaDir)src\liblzma\api\lzma\index_hash.h" /> + <ClInclude Include="$(lzmaDir)src\liblzma\api\lzma\lzma12.h" /> + <ClInclude Include="$(lzmaDir)src\liblzma\api\lzma\stream_flags.h" /> + <ClInclude Include="$(lzmaDir)src\liblzma\api\lzma\version.h" /> + <ClInclude Include="$(lzmaDir)src\liblzma\api\lzma\vli.h" /> + <ClInclude Include="$(lzmaDir)src\liblzma\check\check.h" /> + <ClInclude Include="$(lzmaDir)src\liblzma\check\crc32_table_be.h" /> + <ClInclude Include="$(lzmaDir)src\liblzma\check\crc32_table_le.h" /> + <ClInclude Include="$(lzmaDir)src\liblzma\check\crc64_table_be.h" /> + <ClInclude Include="$(lzmaDir)src\liblzma\check\crc64_table_le.h" /> + <ClInclude Include="$(lzmaDir)src\liblzma\check\crc_macros.h" /> + <ClInclude Include="$(lzmaDir)src\liblzma\common\alone_decoder.h" /> + <ClInclude Include="$(lzmaDir)src\liblzma\common\block_buffer_encoder.h" /> + <ClInclude Include="$(lzmaDir)src\liblzma\common\block_decoder.h" /> + <ClInclude Include="$(lzmaDir)src\liblzma\common\block_encoder.h" /> + <ClInclude Include="$(lzmaDir)src\liblzma\common\common.h" /> + <ClInclude Include="$(lzmaDir)src\liblzma\common\easy_preset.h" /> + <ClInclude Include="$(lzmaDir)src\liblzma\common\filter_common.h" /> + <ClInclude Include="$(lzmaDir)src\liblzma\common\filter_decoder.h" /> + <ClInclude Include="$(lzmaDir)src\liblzma\common\filter_encoder.h" /> + <ClInclude Include="$(lzmaDir)src\liblzma\common\index.h" /> + <ClInclude Include="$(lzmaDir)src\liblzma\common\index_encoder.h" /> + <ClInclude Include="$(lzmaDir)src\liblzma\common\memcmplen.h" /> + <ClInclude Include="$(lzmaDir)src\liblzma\common\outqueue.h" /> + <ClInclude Include="$(lzmaDir)src\liblzma\common\stream_decoder.h" /> + <ClInclude Include="$(lzmaDir)src\liblzma\common\stream_flags_common.h" /> + <ClInclude Include="$(lzmaDir)src\liblzma\delta\delta_common.h" /> + <ClInclude Include="$(lzmaDir)src\liblzma\delta\delta_decoder.h" /> + <ClInclude Include="$(lzmaDir)src\liblzma\delta\delta_encoder.h" /> + <ClInclude Include="$(lzmaDir)src\liblzma\delta\delta_private.h" /> + <ClInclude Include="$(lzmaDir)src\liblzma\lzma\fastpos.h" /> + <ClInclude Include="$(lzmaDir)src\liblzma\lzma\lzma2_decoder.h" /> + <ClInclude Include="$(lzmaDir)src\liblzma\lzma\lzma2_encoder.h" /> + <ClInclude Include="$(lzmaDir)src\liblzma\lzma\lzma_common.h" /> + <ClInclude Include="$(lzmaDir)src\liblzma\lzma\lzma_decoder.h" /> + <ClInclude Include="$(lzmaDir)src\liblzma\lzma\lzma_encoder.h" /> + <ClInclude Include="$(lzmaDir)src\liblzma\lzma\lzma_encoder_private.h" /> + <ClInclude Include="$(lzmaDir)src\liblzma\lz\lz_decoder.h" /> + <ClInclude Include="$(lzmaDir)src\liblzma\lz\lz_encoder.h" /> + <ClInclude Include="$(lzmaDir)src\liblzma\lz\lz_encoder_hash.h" /> + <ClInclude Include="$(lzmaDir)src\liblzma\lz\lz_encoder_hash_table.h" /> + <ClInclude Include="$(lzmaDir)src\liblzma\rangecoder\price.h" /> + <ClInclude Include="$(lzmaDir)src\liblzma\rangecoder\range_common.h" /> + <ClInclude Include="$(lzmaDir)src\liblzma\rangecoder\range_decoder.h" /> + <ClInclude Include="$(lzmaDir)src\liblzma\rangecoder\range_encoder.h" /> + <ClInclude Include="$(lzmaDir)src\liblzma\simple\simple_coder.h" /> + <ClInclude Include="$(lzmaDir)src\liblzma\simple\simple_decoder.h" /> + <ClInclude Include="$(lzmaDir)src\liblzma\simple\simple_encoder.h" /> + <ClInclude Include="$(lzmaDir)src\liblzma\simple\simple_private.h" /> + <ClInclude Include="$(lzmaDir)windows\vs2019\config.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> diff --git a/PCbuild/liblzma.vcxproj.filters b/PCbuild/liblzma.vcxproj.filters index 4a2d1886..ebe2a7d5 100644 --- a/PCbuild/liblzma.vcxproj.filters +++ b/PCbuild/liblzma.vcxproj.filters @@ -1,435 +1,435 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <Filter Include="Source Files"> - <UniqueIdentifier>{cb1870af-3c7e-48ba-bd7f-3e87468f8ed7}</UniqueIdentifier> - </Filter> - <Filter Include="Header Files"> - <UniqueIdentifier>{58761ffe-2af0-42a8-9f93-4e57e1954c36}</UniqueIdentifier> - </Filter> - </ItemGroup> - <ItemGroup> - <ClCompile Include="$(lzmaDir)src\liblzma\common\alone_decoder.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\common\alone_encoder.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\simple\arm.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\simple\armthumb.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\common\auto_decoder.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\common\block_buffer_decoder.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\common\block_buffer_encoder.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\common\block_decoder.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\common\block_encoder.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\common\block_header_decoder.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\common\block_header_encoder.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\check\check.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\common\common.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\common\block_util.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\check\crc32_fast.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\check\crc32_table.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\check\crc64_fast.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\check\crc64_table.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\delta\delta_common.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\delta\delta_decoder.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\delta\delta_encoder.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\common\easy_buffer_encoder.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\common\easy_decoder_memusage.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\common\easy_encoder.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\common\easy_preset.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\common\easy_encoder_memusage.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\lzma\fastpos_table.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\common\filter_buffer_encoder.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\common\filter_buffer_decoder.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\common\filter_common.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\common\filter_decoder.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\common\filter_encoder.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\common\filter_flags_decoder.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\common\filter_flags_encoder.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\common\hardware_cputhreads.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\common\hardware_physmem.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\common\index.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\common\index_decoder.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\common\index_encoder.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\common\index_hash.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\lz\lz_decoder.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\lz\lz_encoder.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\lz\lz_encoder_mf.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\simple\ia64.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\lzma\lzma_decoder.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\lzma\lzma_encoder.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\lzma\lzma_encoder_optimum_fast.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\lzma\lzma_encoder_optimum_normal.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\lzma\lzma_encoder_presets.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\lzma\lzma2_decoder.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\simple\x86.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\common\vli_size.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\common\vli_decoder.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\common\vli_encoder.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\common\tuklib_physmem.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\common\tuklib_cpucores.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\common\stream_flags_encoder.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\common\stream_flags_decoder.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\common\stream_flags_common.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\common\stream_encoder_mt.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\common\stream_encoder.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\common\stream_decoder.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\common\stream_buffer_decoder.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\common\stream_buffer_encoder.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\simple\sparc.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\simple\simple_encoder.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\simple\simple_decoder.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\simple\simple_coder.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\check\sha256.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\rangecoder\price_table.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\simple\powerpc.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\common\outqueue.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="$(lzmaDir)src\liblzma\lzma\lzma2_encoder.c"> - <Filter>Source Files</Filter> - </ClCompile> - </ItemGroup> - <ItemGroup> - <ClInclude Include="$(lzmaDir)src\common\mythread.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="$(lzmaDir)src\common\sysdefs.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="$(lzmaDir)src\common\tuklib_common.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="$(lzmaDir)src\common\tuklib_config.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="$(lzmaDir)src\common\tuklib_cpucores.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="$(lzmaDir)src\common\tuklib_integer.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="$(lzmaDir)src\common\tuklib_physmem.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="$(lzmaDir)src\liblzma\api\lzma.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="$(lzmaDir)src\liblzma\api\lzma\base.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="$(lzmaDir)src\liblzma\api\lzma\bcj.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="$(lzmaDir)src\liblzma\api\lzma\block.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="$(lzmaDir)src\liblzma\api\lzma\check.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="$(lzmaDir)src\liblzma\api\lzma\container.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="$(lzmaDir)src\liblzma\api\lzma\delta.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="$(lzmaDir)src\liblzma\api\lzma\filter.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="$(lzmaDir)src\liblzma\api\lzma\hardware.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="$(lzmaDir)src\liblzma\api\lzma\index_hash.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="$(lzmaDir)src\liblzma\api\lzma\index.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="$(lzmaDir)src\liblzma\api\lzma\lzma12.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="$(lzmaDir)src\liblzma\api\lzma\stream_flags.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="$(lzmaDir)src\liblzma\api\lzma\version.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="$(lzmaDir)src\liblzma\api\lzma\vli.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="$(lzmaDir)src\liblzma\check\check.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="$(lzmaDir)src\liblzma\check\crc_macros.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="$(lzmaDir)src\liblzma\check\crc32_table_be.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="$(lzmaDir)src\liblzma\check\crc32_table_le.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="$(lzmaDir)src\liblzma\check\crc64_table_be.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="$(lzmaDir)src\liblzma\check\crc64_table_le.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="$(lzmaDir)src\liblzma\common\alone_decoder.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="$(lzmaDir)src\liblzma\common\block_buffer_encoder.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="$(lzmaDir)src\liblzma\common\block_decoder.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="$(lzmaDir)src\liblzma\common\block_encoder.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="$(lzmaDir)src\liblzma\common\common.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="$(lzmaDir)src\liblzma\common\easy_preset.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="$(lzmaDir)src\liblzma\common\filter_common.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="$(lzmaDir)src\liblzma\common\filter_decoder.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="$(lzmaDir)src\liblzma\common\filter_encoder.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="$(lzmaDir)src\liblzma\common\index_encoder.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="$(lzmaDir)src\liblzma\common\index.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="$(lzmaDir)src\liblzma\common\memcmplen.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="$(lzmaDir)src\liblzma\common\outqueue.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="$(lzmaDir)src\liblzma\common\stream_decoder.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="$(lzmaDir)src\liblzma\common\stream_flags_common.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="$(lzmaDir)src\liblzma\delta\delta_common.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="$(lzmaDir)src\liblzma\delta\delta_decoder.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="$(lzmaDir)src\liblzma\delta\delta_encoder.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="$(lzmaDir)src\liblzma\delta\delta_private.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="$(lzmaDir)src\liblzma\lz\lz_decoder.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="$(lzmaDir)src\liblzma\lz\lz_encoder_hash_table.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="$(lzmaDir)src\liblzma\lz\lz_encoder_hash.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="$(lzmaDir)src\liblzma\lz\lz_encoder.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="$(lzmaDir)src\liblzma\lzma\fastpos.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="$(lzmaDir)src\liblzma\lzma\lzma_common.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="$(lzmaDir)src\liblzma\lzma\lzma_decoder.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="$(lzmaDir)src\liblzma\lzma\lzma_encoder_private.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="$(lzmaDir)src\liblzma\lzma\lzma_encoder.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="$(lzmaDir)src\liblzma\lzma\lzma2_decoder.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="$(lzmaDir)src\liblzma\lzma\lzma2_encoder.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="$(lzmaDir)src\liblzma\rangecoder\price.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="$(lzmaDir)src\liblzma\rangecoder\range_common.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="$(lzmaDir)src\liblzma\rangecoder\range_decoder.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="$(lzmaDir)src\liblzma\rangecoder\range_encoder.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="$(lzmaDir)src\liblzma\simple\simple_coder.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="$(lzmaDir)src\liblzma\simple\simple_decoder.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="$(lzmaDir)src\liblzma\simple\simple_encoder.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="$(lzmaDir)src\liblzma\simple\simple_private.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="$(lzmaDir)windows\vs2019\config.h"> - <Filter>Header Files</Filter> - </ClInclude> - </ItemGroup> +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{cb1870af-3c7e-48ba-bd7f-3e87468f8ed7}</UniqueIdentifier> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{58761ffe-2af0-42a8-9f93-4e57e1954c36}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="$(lzmaDir)src\liblzma\common\alone_decoder.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\common\alone_encoder.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\simple\arm.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\simple\armthumb.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\common\auto_decoder.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\common\block_buffer_decoder.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\common\block_buffer_encoder.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\common\block_decoder.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\common\block_encoder.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\common\block_header_decoder.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\common\block_header_encoder.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\check\check.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\common\common.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\common\block_util.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\check\crc32_fast.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\check\crc32_table.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\check\crc64_fast.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\check\crc64_table.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\delta\delta_common.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\delta\delta_decoder.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\delta\delta_encoder.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\common\easy_buffer_encoder.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\common\easy_decoder_memusage.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\common\easy_encoder.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\common\easy_preset.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\common\easy_encoder_memusage.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\lzma\fastpos_table.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\common\filter_buffer_encoder.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\common\filter_buffer_decoder.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\common\filter_common.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\common\filter_decoder.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\common\filter_encoder.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\common\filter_flags_decoder.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\common\filter_flags_encoder.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\common\hardware_cputhreads.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\common\hardware_physmem.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\common\index.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\common\index_decoder.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\common\index_encoder.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\common\index_hash.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\lz\lz_decoder.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\lz\lz_encoder.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\lz\lz_encoder_mf.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\simple\ia64.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\lzma\lzma_decoder.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\lzma\lzma_encoder.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\lzma\lzma_encoder_optimum_fast.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\lzma\lzma_encoder_optimum_normal.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\lzma\lzma_encoder_presets.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\lzma\lzma2_decoder.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\simple\x86.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\common\vli_size.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\common\vli_decoder.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\common\vli_encoder.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\common\tuklib_physmem.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\common\tuklib_cpucores.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\common\stream_flags_encoder.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\common\stream_flags_decoder.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\common\stream_flags_common.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\common\stream_encoder_mt.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\common\stream_encoder.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\common\stream_decoder.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\common\stream_buffer_decoder.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\common\stream_buffer_encoder.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\simple\sparc.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\simple\simple_encoder.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\simple\simple_decoder.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\simple\simple_coder.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\check\sha256.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\rangecoder\price_table.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\simple\powerpc.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\common\outqueue.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="$(lzmaDir)src\liblzma\lzma\lzma2_encoder.c"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="$(lzmaDir)src\common\mythread.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="$(lzmaDir)src\common\sysdefs.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="$(lzmaDir)src\common\tuklib_common.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="$(lzmaDir)src\common\tuklib_config.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="$(lzmaDir)src\common\tuklib_cpucores.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="$(lzmaDir)src\common\tuklib_integer.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="$(lzmaDir)src\common\tuklib_physmem.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="$(lzmaDir)src\liblzma\api\lzma.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="$(lzmaDir)src\liblzma\api\lzma\base.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="$(lzmaDir)src\liblzma\api\lzma\bcj.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="$(lzmaDir)src\liblzma\api\lzma\block.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="$(lzmaDir)src\liblzma\api\lzma\check.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="$(lzmaDir)src\liblzma\api\lzma\container.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="$(lzmaDir)src\liblzma\api\lzma\delta.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="$(lzmaDir)src\liblzma\api\lzma\filter.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="$(lzmaDir)src\liblzma\api\lzma\hardware.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="$(lzmaDir)src\liblzma\api\lzma\index_hash.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="$(lzmaDir)src\liblzma\api\lzma\index.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="$(lzmaDir)src\liblzma\api\lzma\lzma12.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="$(lzmaDir)src\liblzma\api\lzma\stream_flags.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="$(lzmaDir)src\liblzma\api\lzma\version.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="$(lzmaDir)src\liblzma\api\lzma\vli.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="$(lzmaDir)src\liblzma\check\check.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="$(lzmaDir)src\liblzma\check\crc_macros.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="$(lzmaDir)src\liblzma\check\crc32_table_be.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="$(lzmaDir)src\liblzma\check\crc32_table_le.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="$(lzmaDir)src\liblzma\check\crc64_table_be.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="$(lzmaDir)src\liblzma\check\crc64_table_le.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="$(lzmaDir)src\liblzma\common\alone_decoder.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="$(lzmaDir)src\liblzma\common\block_buffer_encoder.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="$(lzmaDir)src\liblzma\common\block_decoder.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="$(lzmaDir)src\liblzma\common\block_encoder.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="$(lzmaDir)src\liblzma\common\common.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="$(lzmaDir)src\liblzma\common\easy_preset.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="$(lzmaDir)src\liblzma\common\filter_common.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="$(lzmaDir)src\liblzma\common\filter_decoder.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="$(lzmaDir)src\liblzma\common\filter_encoder.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="$(lzmaDir)src\liblzma\common\index_encoder.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="$(lzmaDir)src\liblzma\common\index.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="$(lzmaDir)src\liblzma\common\memcmplen.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="$(lzmaDir)src\liblzma\common\outqueue.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="$(lzmaDir)src\liblzma\common\stream_decoder.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="$(lzmaDir)src\liblzma\common\stream_flags_common.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="$(lzmaDir)src\liblzma\delta\delta_common.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="$(lzmaDir)src\liblzma\delta\delta_decoder.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="$(lzmaDir)src\liblzma\delta\delta_encoder.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="$(lzmaDir)src\liblzma\delta\delta_private.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="$(lzmaDir)src\liblzma\lz\lz_decoder.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="$(lzmaDir)src\liblzma\lz\lz_encoder_hash_table.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="$(lzmaDir)src\liblzma\lz\lz_encoder_hash.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="$(lzmaDir)src\liblzma\lz\lz_encoder.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="$(lzmaDir)src\liblzma\lzma\fastpos.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="$(lzmaDir)src\liblzma\lzma\lzma_common.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="$(lzmaDir)src\liblzma\lzma\lzma_decoder.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="$(lzmaDir)src\liblzma\lzma\lzma_encoder_private.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="$(lzmaDir)src\liblzma\lzma\lzma_encoder.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="$(lzmaDir)src\liblzma\lzma\lzma2_decoder.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="$(lzmaDir)src\liblzma\lzma\lzma2_encoder.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="$(lzmaDir)src\liblzma\rangecoder\price.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="$(lzmaDir)src\liblzma\rangecoder\range_common.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="$(lzmaDir)src\liblzma\rangecoder\range_decoder.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="$(lzmaDir)src\liblzma\rangecoder\range_encoder.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="$(lzmaDir)src\liblzma\simple\simple_coder.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="$(lzmaDir)src\liblzma\simple\simple_decoder.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="$(lzmaDir)src\liblzma\simple\simple_encoder.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="$(lzmaDir)src\liblzma\simple\simple_private.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="$(lzmaDir)windows\vs2019\config.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> </Project> \ No newline at end of file diff --git a/PCbuild/openssl.props b/PCbuild/openssl.props index 3c0e394d..5fd708b2 100644 --- a/PCbuild/openssl.props +++ b/PCbuild/openssl.props @@ -1,34 +1,34 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemDefinitionGroup> - <ClCompile> - <AdditionalIncludeDirectories>$(opensslIncludeDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - </ClCompile> - <Link> - <AdditionalLibraryDirectories>$(opensslOutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> - <AdditionalDependencies>ws2_32.lib;libcrypto.lib;libssl.lib;%(AdditionalDependencies)</AdditionalDependencies> - </Link> - </ItemDefinitionGroup> - <PropertyGroup> - <_DLLSuffix>-1_1</_DLLSuffix> - <_DLLSuffix Condition="$(Platform) == 'ARM'">$(_DLLSuffix)-arm</_DLLSuffix> - <_DLLSuffix Condition="$(Platform) == 'ARM64'">$(_DLLSuffix)-arm64</_DLLSuffix> - <OpenSSLDLLSuffix>$(_DLLSuffix)</OpenSSLDLLSuffix> - </PropertyGroup> - <ItemGroup> - <_SSLDLL Include="$(opensslOutDir)\libcrypto$(_DLLSuffix).dll" /> - <_SSLDLL Include="$(opensslOutDir)\libcrypto$(_DLLSuffix).pdb" /> - <_SSLDLL Include="$(opensslOutDir)\libssl$(_DLLSuffix).dll" /> - <_SSLDLL Include="$(opensslOutDir)\libssl$(_DLLSuffix).pdb" /> - </ItemGroup> - <Target Name="_CopySSLDLL" - Inputs="@(_SSLDLL)" - Outputs="@(_SSLDLL->'$(OutDir)%(Filename)%(Extension)')" - Condition="$(SkipCopySSLDLL) == ''" - AfterTargets="Build"> - <Copy SourceFiles="@(_SSLDLL)" DestinationFolder="$(OutDir)" /> - </Target> - <Target Name="_CleanSSLDLL" Condition="$(SkipCopySSLDLL) == ''" BeforeTargets="Clean"> - <Delete Files="@(_SSLDLL->'$(OutDir)%(Filename)%(Extension)')" TreatErrorsAsWarnings="true" /> - </Target> -</Project> \ No newline at end of file +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemDefinitionGroup> + <ClCompile> + <AdditionalIncludeDirectories>$(opensslIncludeDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <AdditionalLibraryDirectories>$(opensslOutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + <AdditionalDependencies>ws2_32.lib;libcrypto.lib;libssl.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <PropertyGroup> + <_DLLSuffix>-3</_DLLSuffix> + <_DLLSuffix Condition="$(Platform) == 'ARM'">$(_DLLSuffix)-arm</_DLLSuffix> + <_DLLSuffix Condition="$(Platform) == 'ARM64'">$(_DLLSuffix)-arm64</_DLLSuffix> + <OpenSSLDLLSuffix Condition="$(OpenSSLDLLSuffix) == ''">$(_DLLSuffix)</OpenSSLDLLSuffix> + </PropertyGroup> + <ItemGroup> + <_SSLDLL Include="$(opensslOutDir)\libcrypto$(_DLLSuffix).dll" /> + <_SSLDLL Include="$(opensslOutDir)\libcrypto$(_DLLSuffix).pdb" /> + <_SSLDLL Include="$(opensslOutDir)\libssl$(_DLLSuffix).dll" /> + <_SSLDLL Include="$(opensslOutDir)\libssl$(_DLLSuffix).pdb" /> + </ItemGroup> + <Target Name="_CopySSLDLL" + Inputs="@(_SSLDLL)" + Outputs="@(_SSLDLL->'$(OutDir)%(Filename)%(Extension)')" + Condition="$(SkipCopySSLDLL) == ''" + AfterTargets="Build"> + <Copy SourceFiles="@(_SSLDLL)" DestinationFolder="$(OutDir)" /> + </Target> + <Target Name="_CleanSSLDLL" Condition="$(SkipCopySSLDLL) == ''" BeforeTargets="Clean"> + <Delete Files="@(_SSLDLL->'$(OutDir)%(Filename)%(Extension)')" TreatErrorsAsWarnings="true" /> + </Target> +</Project> diff --git a/PCbuild/openssl.vcxproj b/PCbuild/openssl.vcxproj index 27515ec8..0da6f674 100644 --- a/PCbuild/openssl.vcxproj +++ b/PCbuild/openssl.vcxproj @@ -1,139 +1,139 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM"> - <Configuration>Release</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM64"> - <Configuration>Release</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectGuid>{B5FD6F1D-129E-4BFF-9340-03606FAC7283}</ProjectGuid> - </PropertyGroup> - - <Import Project="python.props" /> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - - <PropertyGroup Label="Configuration" Condition="$(Platform) == 'Win32'"> - <ConfigurationType>Makefile</ConfigurationType> - <Bitness>32</Bitness> - <ArchName>x86</ArchName> - <OpenSSLPlatform>VC-WIN32</OpenSSLPlatform> - <SupportSigning>true</SupportSigning> - </PropertyGroup> - - <PropertyGroup Label="Configuration" Condition="$(Platform) == 'x64'"> - <ConfigurationType>Makefile</ConfigurationType> - <Bitness>64</Bitness> - <ArchName>amd64</ArchName> - <OpenSSLPlatform>VC-WIN64A-masm</OpenSSLPlatform> - <SupportSigning>true</SupportSigning> - </PropertyGroup> - - <PropertyGroup Label="Configuration" Condition="$(Platform) == 'ARM'"> - <ConfigurationType>Makefile</ConfigurationType> - <Bitness>ARM</Bitness> - <ArchName>ARM</ArchName> - <OpenSSLPlatform>VC-WIN32-ARM</OpenSSLPlatform> - <SupportSigning>true</SupportSigning> - </PropertyGroup> - - <PropertyGroup Label="Configuration" Condition="$(Platform) == 'ARM64'"> - <ConfigurationType>Makefile</ConfigurationType> - <Bitness>ARM64</Bitness> - <ArchName>ARM64</ArchName> - <OpenSSLPlatform>VC-WIN64-ARM</OpenSSLPlatform> - <SupportSigning>true</SupportSigning> - </PropertyGroup> - - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <Import Project="pyproject.props" /> - - <PropertyGroup> - <IntDir>$(opensslDir)\tmp$(Bitness)dll</IntDir> - <OutDir>$(opensslOutDir)</OutDir> - <NMakeBuildCommandLine>setlocal -set VCINSTALLDIR=$(VCInstallDir) -if not exist "$(IntDir.TrimEnd('\'))" mkdir "$(IntDir.TrimEnd('\'))" -cd /D "$(IntDir.TrimEnd('\'))" -$(Perl) "$(opensslDir)\configure" $(OpenSSLPlatform) no-asm -nmake -</NMakeBuildCommandLine> - </PropertyGroup> - - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - - <Target Name="_PatchUplink" BeforeTargets="Build"> - <PropertyGroup> - <Uplink>$(opensslDir)\ms\uplink.c</Uplink> - <BeforePatch>((h = GetModuleHandle(NULL)) == NULL)</BeforePatch> - <AfterPatch>((h = GetModuleHandleA("_ssl.pyd")) == NULL) if ((h = GetModuleHandleA("_ssl_d.pyd")) == NULL) if ((h = GetModuleHandle(NULL)) == NULL /*patched*/)</AfterPatch> - </PropertyGroup> - <Error Text="Cannot find $(Uplink)" Condition="!Exists($(Uplink))" /> - <PropertyGroup> - <_Original>$([System.IO.File]::ReadAllText($(Uplink)))</_Original> - <_Patched>$(_Original.Replace($(BeforePatch), $(AfterPatch)))</_Patched> - <IsPatched>false</IsPatched> - <IsPatched Condition="$(_Patched) == $(_Original)">true</IsPatched> - </PropertyGroup> - <Message Text="$(Uplink) is already patched" Importance="normal" Condition="$(IsPatched)" /> - <Message Text="Patching $(Uplink)" Importance="high" Condition="!$(IsPatched)" /> - <WriteLinesToFile File="$(Uplink)" - Lines="$(_Patched)" - Overwrite="true" - Encoding="ASCII" - Condition="!$(IsPatched)" /> - </Target> - - <Target Name="_CopyToOutput" AfterTargets="Build"> - <ItemGroup> - <_Built Include="$(opensslDir)\LICENSE" /> - <_Built Include="$(IntDir)\libcrypto.lib;$(IntDir)\libcrypto-*.dll;$(IntDir)\libcrypto-*.pdb" /> - <_Built Include="$(IntDir)\libssl.lib;$(IntDir)\libssl-*.dll;$(IntDir)\libssl-*.pdb" /> - <_AppLink Include="$(opensslDir)\ms\applink.c" /> - <_Include Include="$(opensslDir)\Include\openssl\*.h" /> - <_Include Include="$(IntDir)\include\openssl\*.h" /> - </ItemGroup> - <MakeDir Directories="$(opensslOutDir)\include\openssl" /> - <Copy SourceFiles="@(_Built)" DestinationFolder="$(opensslOutDir)" /> - <Copy SourceFiles="@(_AppLink)" DestinationFolder="$(opensslOutDir)\include" /> - <Copy SourceFiles="@(_Include)" DestinationFolder="$(opensslOutDir)\include\openssl" /> - </Target> - - <Target Name="SignFiles" AfterTargets="Build" Condition="$(_SignCommand) != ''"> - <ItemGroup> - <FilesToSign Include="$(opensslOutDir)\lib*.dll" /> - </ItemGroup> - <Exec Command="$(_SignCommand) %(FilesToSign.FullPath)" ContinueOnError="true" /> - </Target> - - <Target Name="Clean" /> - <Target Name="CleanAll"> - <Delete Files="$(TargetPath);$(BuildPath)$(tclDLLName)" /> - <RemoveDir Directories="$(IntDir)" /> - </Target> - - <Target Name="LocateNMake"> - <PropertyGroup> - <OutputFilename Condition="$(OutputFilename) == ''">$(Temp)\nmake.loc</OutputFilename> - </PropertyGroup> - <ItemGroup> - <_NMakeExe Include="$(VC_ExecutablePath_x86_x86)\nmake.exe" Condition="$(VC_ExecutablePath_x86_x86) != ''" /> - </ItemGroup> - <MakeDir Directories="$([System.IO.Path]::GetDirectoryName($(OutputFilename)))" /> - <WriteLinesToFile File="$(OutputFilename)" Lines="@(_NMakeExe)" /> - </Target> - - <Target Name="ResolveAssemblyReferences" /> +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM"> + <Configuration>Release</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM64"> + <Configuration>Release</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{B5FD6F1D-129E-4BFF-9340-03606FAC7283}</ProjectGuid> + </PropertyGroup> + + <Import Project="python.props" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + + <PropertyGroup Label="Configuration" Condition="$(Platform) == 'Win32'"> + <ConfigurationType>Makefile</ConfigurationType> + <Bitness>32</Bitness> + <ArchName>x86</ArchName> + <OpenSSLPlatform>VC-WIN32</OpenSSLPlatform> + <SupportSigning>true</SupportSigning> + </PropertyGroup> + + <PropertyGroup Label="Configuration" Condition="$(Platform) == 'x64'"> + <ConfigurationType>Makefile</ConfigurationType> + <Bitness>64</Bitness> + <ArchName>amd64</ArchName> + <OpenSSLPlatform>VC-WIN64A-masm</OpenSSLPlatform> + <SupportSigning>true</SupportSigning> + </PropertyGroup> + + <PropertyGroup Label="Configuration" Condition="$(Platform) == 'ARM'"> + <ConfigurationType>Makefile</ConfigurationType> + <Bitness>ARM</Bitness> + <ArchName>ARM</ArchName> + <OpenSSLPlatform>VC-WIN32-ARM</OpenSSLPlatform> + <SupportSigning>true</SupportSigning> + </PropertyGroup> + + <PropertyGroup Label="Configuration" Condition="$(Platform) == 'ARM64'"> + <ConfigurationType>Makefile</ConfigurationType> + <Bitness>ARM64</Bitness> + <ArchName>ARM64</ArchName> + <OpenSSLPlatform>VC-WIN64-ARM</OpenSSLPlatform> + <SupportSigning>true</SupportSigning> + </PropertyGroup> + + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <Import Project="pyproject.props" /> + + <PropertyGroup> + <IntDir>$(opensslDir)\tmp$(Bitness)dll</IntDir> + <OutDir>$(opensslOutDir)</OutDir> + <NMakeBuildCommandLine>setlocal +set VCINSTALLDIR=$(VCInstallDir) +if not exist "$(IntDir.TrimEnd('\'))" mkdir "$(IntDir.TrimEnd('\'))" +cd /D "$(IntDir.TrimEnd('\'))" +$(Perl) "$(opensslDir)\configure" $(OpenSSLPlatform) no-asm +nmake +</NMakeBuildCommandLine> + </PropertyGroup> + + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + + <Target Name="_PatchUplink" BeforeTargets="Build"> + <PropertyGroup> + <Uplink>$(opensslDir)\ms\uplink.c</Uplink> + <BeforePatch>((h = GetModuleHandle(NULL)) == NULL)</BeforePatch> + <AfterPatch>((h = GetModuleHandleA("_ssl.pyd")) == NULL) if ((h = GetModuleHandleA("_ssl_d.pyd")) == NULL) if ((h = GetModuleHandle(NULL)) == NULL /*patched*/)</AfterPatch> + </PropertyGroup> + <Error Text="Cannot find $(Uplink)" Condition="!Exists($(Uplink))" /> + <PropertyGroup> + <_Original>$([System.IO.File]::ReadAllText($(Uplink)))</_Original> + <_Patched>$(_Original.Replace($(BeforePatch), $(AfterPatch)))</_Patched> + <IsPatched>false</IsPatched> + <IsPatched Condition="$(_Patched) == $(_Original)">true</IsPatched> + </PropertyGroup> + <Message Text="$(Uplink) is already patched" Importance="normal" Condition="$(IsPatched)" /> + <Message Text="Patching $(Uplink)" Importance="high" Condition="!$(IsPatched)" /> + <WriteLinesToFile File="$(Uplink)" + Lines="$(_Patched)" + Overwrite="true" + Encoding="ASCII" + Condition="!$(IsPatched)" /> + </Target> + + <Target Name="_CopyToOutput" AfterTargets="Build"> + <ItemGroup> + <_Built Include="$(opensslDir)\LICENSE" /> + <_Built Include="$(IntDir)\libcrypto.lib;$(IntDir)\libcrypto-*.dll;$(IntDir)\libcrypto-*.pdb" /> + <_Built Include="$(IntDir)\libssl.lib;$(IntDir)\libssl-*.dll;$(IntDir)\libssl-*.pdb" /> + <_AppLink Include="$(opensslDir)\ms\applink.c" /> + <_Include Include="$(opensslDir)\Include\openssl\*.h" /> + <_Include Include="$(IntDir)\include\openssl\*.h" /> + </ItemGroup> + <MakeDir Directories="$(opensslOutDir)\include\openssl" /> + <Copy SourceFiles="@(_Built)" DestinationFolder="$(opensslOutDir)" /> + <Copy SourceFiles="@(_AppLink)" DestinationFolder="$(opensslOutDir)\include" /> + <Copy SourceFiles="@(_Include)" DestinationFolder="$(opensslOutDir)\include\openssl" /> + </Target> + + <Target Name="SignFiles" AfterTargets="Build" Condition="$(_SignCommand) != ''"> + <ItemGroup> + <FilesToSign Include="$(opensslOutDir)\lib*.dll" /> + </ItemGroup> + <Exec Command="$(_SignCommand) %(FilesToSign.FullPath)" ContinueOnError="true" /> + </Target> + + <Target Name="Clean" /> + <Target Name="CleanAll"> + <Delete Files="$(TargetPath);$(BuildPath)$(tclDLLName)" /> + <RemoveDir Directories="$(IntDir)" /> + </Target> + + <Target Name="LocateNMake"> + <PropertyGroup> + <OutputFilename Condition="$(OutputFilename) == ''">$(Temp)\nmake.loc</OutputFilename> + </PropertyGroup> + <ItemGroup> + <_NMakeExe Include="$(VC_ExecutablePath_x86_x86)\nmake.exe" Condition="$(VC_ExecutablePath_x86_x86) != ''" /> + </ItemGroup> + <MakeDir Directories="$([System.IO.Path]::GetDirectoryName($(OutputFilename)))" /> + <WriteLinesToFile File="$(OutputFilename)" Lines="@(_NMakeExe)" /> + </Target> + + <Target Name="ResolveAssemblyReferences" /> </Project> \ No newline at end of file diff --git a/PCbuild/pcbuild.proj b/PCbuild/pcbuild.proj index 3c7e5de1..28269f08 100644 --- a/PCbuild/pcbuild.proj +++ b/PCbuild/pcbuild.proj @@ -1,159 +1,159 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props"/> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props"/> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/> - <PropertyGroup Label="Globals"> - <ProjectGuid>{CC9B93A2-439D-4058-9D29-6DCF43774405}</ProjectGuid> - <Platform Condition="'$(Platform)' == ''">Win32</Platform> - <Configuration Condition="'$(Configuration)' == ''">Release</Configuration> - <IncludeExtensions Condition="'$(IncludeExtensions)' == ''">true</IncludeExtensions> - <IncludeExternals Condition="'$(IncludeExternals)' == ''">true</IncludeExternals> - <IncludeTests Condition="'$(IncludeTest)' == ''">true</IncludeTests> - <IncludeCTypes Condition="'$(IncludeCTypes)' == ''">true</IncludeCTypes> - <IncludeSSL Condition="'$(IncludeSSL)' == ''">true</IncludeSSL> - <IncludeTkinter Condition="'$(IncludeTkinter)' == ''">true</IncludeTkinter> - <IncludeUwp Condition="'$(IncludeUwp)' == ''">false</IncludeUwp> - </PropertyGroup> - - <ItemDefinitionGroup> - <FreezeProjects> - <Platform>$(PreferredToolArchitecture)</Platform> - <Configuration>$(Configuration)</Configuration> - <Configuration Condition="$(Configuration) == 'PGInstrument'">Release</Configuration> - <Properties></Properties> - <BuildTarget>Build</BuildTarget> - <CleanTarget>Clean</CleanTarget> - <CleanAllTarget>CleanAll</CleanAllTarget> - <BuildInParallel>false</BuildInParallel> - </FreezeProjects> - <Projects> - <Platform>$(Platform)</Platform> - <Configuration>$(Configuration)</Configuration> - <Properties></Properties> - <BuildTarget>Build</BuildTarget> - <CleanTarget>Clean</CleanTarget> - <CleanAllTarget>CleanAll</CleanAllTarget> - <BuildInParallel>true</BuildInParallel> - </Projects> - <Projects2> - <Platform>$(Platform)</Platform> - <Configuration>$(Configuration)</Configuration> - <Properties></Properties> - <BuildTarget>Build</BuildTarget> - <CleanTarget>Clean</CleanTarget> - <CleanAllTarget>CleanAll</CleanAllTarget> - <BuildInParallel>false</BuildInParallel> - </Projects2> - </ItemDefinitionGroup> - <ItemGroup> - <!-- pythonXY.dll --> - <!-- - Parallel build is explicitly disabled for this project because it - causes many conflicts between pythoncore and projects that depend - on pythoncore. Once the core DLL has been built, subsequent - projects will be built in parallel. - --> - <Projects Include="pythoncore.vcxproj"> - <BuildInParallel>false</BuildInParallel> - </Projects> - <!-- python3.dll --> - <Projects Include="python3dll.vcxproj" /> - <!-- py[w].exe --> - <Projects Include="pylauncher.vcxproj;pywlauncher.vcxproj" /> - <!-- pyshellext.dll --> - <Projects Include="pyshellext.vcxproj" /> - <!-- Extension modules --> - <ExtensionModules Include="_asyncio;_zoneinfo;_decimal;_elementtree;_msi;_multiprocessing;_overlapped;pyexpat;_queue;select;unicodedata;winsound;_uuid" /> - <ExtensionModules Include="_ctypes" Condition="$(IncludeCTypes)" /> - <!-- Extension modules that require external sources --> - <ExternalModules Include="_bz2;_lzma;_sqlite3" /> - <!-- venv launchers --> - <Projects Include="venvlauncher.vcxproj;venvwlauncher.vcxproj" /> - <!-- _ssl will build _socket as well, which may cause conflicts in parallel builds --> - <ExtensionModules Include="_socket" Condition="!$(IncludeSSL) or !$(IncludeExternals)" /> - <ExternalModules Include="_ssl;_hashlib" Condition="$(IncludeSSL)" /> - <ExternalModules Include="_tkinter" Condition="$(IncludeTkinter)" /> - <ExtensionModules Include="@(ExternalModules->'%(Identity)')" Condition="$(IncludeExternals)" /> - <Projects Include="@(ExtensionModules->'%(Identity).vcxproj')" Condition="$(IncludeExtensions)" /> - <!-- Test modules --> - <TestModules Include="_ctypes_test;_testbuffer;_testcapi;_testinternalcapi;_testembed;_testimportmultiple;_testmultiphase;_testconsole" /> - <TestModules Include="xxlimited" Condition="'$(Configuration)' == 'Release'" /> - <TestModules Include="xxlimited_35" Condition="'$(Configuration)' == 'Release'" /> - <Projects Include="@(TestModules->'%(Identity).vcxproj')" Condition="$(IncludeTests)"> - <!-- Disable parallel build for test modules --> - <BuildInParallel>false</BuildInParallel> - </Projects> - - <!-- _freeze_module --> - <FreezeProjects Include="_freeze_module.vcxproj" /> - <!-- python[w].exe --> - <Projects2 Include="python.vcxproj;pythonw.vcxproj" /> - <Projects2 Include="python_uwp.vcxproj;pythonw_uwp.vcxproj" Condition="$(IncludeUwp)" /> - <!-- venv[w]launcher.exe --> - <Projects2 Include="venvlauncher.vcxproj;venvwlauncher.vcxproj" /> - </ItemGroup> - - <Target Name="Build"> - <MSBuild Projects="@(FreezeProjects)" - Properties="Configuration=%(Configuration);Platform=%(Platform);%(Properties)" - BuildInParallel="%(BuildInParallel)" - StopOnFirstFailure="true" - Targets="%(BuildTarget)" /> - <MSBuild Projects="@(Projects)" - Properties="Configuration=%(Configuration);Platform=%(Platform);%(Properties)" - BuildInParallel="%(BuildInParallel)" - StopOnFirstFailure="true" - Targets="%(BuildTarget)" /> - <MSBuild Projects="@(Projects2)" - Properties="Configuration=%(Configuration);Platform=%(Platform);%(Properties)" - BuildInParallel="%(BuildInParallel)" - StopOnFirstFailure="true" - Targets="%(BuildTarget)" /> - </Target> - - <Target Name="Clean"> - <MSBuild Projects="@(Projects2)" - Properties="Configuration=%(Configuration);Platform=%(Platform);%(Properties)" - BuildInParallel="%(BuildInParallel)" - StopOnFirstFailure="false" - Condition="%(CleanTarget) != ''" - Targets="%(CleanTarget)" /> - <MSBuild Projects="@(Projects)" - Properties="Configuration=%(Configuration);Platform=%(Platform);%(Properties)" - BuildInParallel="%(BuildInParallel)" - StopOnFirstFailure="false" - Condition="%(CleanTarget) != ''" - Targets="%(CleanTarget)" /> - <MSBuild Projects="@(FreezeProjects)" - Properties="Configuration=%(Configuration);Platform=%(Platform);%(Properties)" - BuildInParallel="%(BuildInParallel)" - StopOnFirstFailure="false" - Condition="%(CleanTarget) != ''" - Targets="%(CleanTarget)" /> - </Target> - - <Target Name="CleanAll"> - <MSBuild Projects="@(Projects2)" - Properties="Configuration=%(Configuration);Platform=%(Platform);%(Properties)" - BuildInParallel="%(BuildInParallel)" - StopOnFirstFailure="false" - Condition="%(CleanAllTarget) != ''" - Targets="%(CleanAllTarget)" /> - <MSBuild Projects="@(Projects)" - Properties="Configuration=%(Configuration);Platform=%(Platform);%(Properties)" - BuildInParallel="%(BuildInParallel)" - StopOnFirstFailure="false" - Condition="%(CleanAllTarget) != ''" - Targets="%(CleanAllTarget)" /> - <MSBuild Projects="@(FreezeProjects)" - Properties="Configuration=%(Configuration);Platform=%(Platform);%(Properties)" - BuildInParallel="%(BuildInParallel)" - StopOnFirstFailure="false" - Condition="%(CleanTarget) != ''" - Targets="%(CleanTarget)" /> - </Target> - - <Target Name="Rebuild" DependsOnTargets="Clean;Build" /> - <Target Name="RebuildAll" DependsOnTargets="CleanAll;Build" /> -</Project> +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props"/> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props"/> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/> + <PropertyGroup Label="Globals"> + <ProjectGuid>{CC9B93A2-439D-4058-9D29-6DCF43774405}</ProjectGuid> + <Platform Condition="'$(Platform)' == ''">Win32</Platform> + <Configuration Condition="'$(Configuration)' == ''">Release</Configuration> + <IncludeExtensions Condition="'$(IncludeExtensions)' == ''">true</IncludeExtensions> + <IncludeExternals Condition="'$(IncludeExternals)' == ''">true</IncludeExternals> + <IncludeTests Condition="'$(IncludeTest)' == ''">true</IncludeTests> + <IncludeCTypes Condition="'$(IncludeCTypes)' == ''">true</IncludeCTypes> + <IncludeSSL Condition="'$(IncludeSSL)' == ''">true</IncludeSSL> + <IncludeTkinter Condition="'$(IncludeTkinter)' == ''">true</IncludeTkinter> + <IncludeUwp Condition="'$(IncludeUwp)' == ''">false</IncludeUwp> + </PropertyGroup> + + <ItemDefinitionGroup> + <FreezeProjects> + <Platform>$(PreferredToolArchitecture)</Platform> + <Configuration>$(Configuration)</Configuration> + <Configuration Condition="$(Configuration) == 'PGInstrument'">Release</Configuration> + <Properties></Properties> + <BuildTarget>Build</BuildTarget> + <CleanTarget>Clean</CleanTarget> + <CleanAllTarget>CleanAll</CleanAllTarget> + <BuildInParallel>false</BuildInParallel> + </FreezeProjects> + <Projects> + <Platform>$(Platform)</Platform> + <Configuration>$(Configuration)</Configuration> + <Properties></Properties> + <BuildTarget>Build</BuildTarget> + <CleanTarget>Clean</CleanTarget> + <CleanAllTarget>CleanAll</CleanAllTarget> + <BuildInParallel>true</BuildInParallel> + </Projects> + <Projects2> + <Platform>$(Platform)</Platform> + <Configuration>$(Configuration)</Configuration> + <Properties></Properties> + <BuildTarget>Build</BuildTarget> + <CleanTarget>Clean</CleanTarget> + <CleanAllTarget>CleanAll</CleanAllTarget> + <BuildInParallel>false</BuildInParallel> + </Projects2> + </ItemDefinitionGroup> + <ItemGroup> + <!-- pythonXY.dll --> + <!-- + Parallel build is explicitly disabled for this project because it + causes many conflicts between pythoncore and projects that depend + on pythoncore. Once the core DLL has been built, subsequent + projects will be built in parallel. + --> + <Projects Include="pythoncore.vcxproj"> + <BuildInParallel>false</BuildInParallel> + </Projects> + <!-- python3.dll --> + <Projects Include="python3dll.vcxproj" /> + <!-- py[w].exe --> + <Projects Include="pylauncher.vcxproj;pywlauncher.vcxproj" /> + <!-- pyshellext.dll --> + <Projects Include="pyshellext.vcxproj" /> + <!-- Extension modules --> + <ExtensionModules Include="_asyncio;_zoneinfo;_decimal;_elementtree;_msi;_multiprocessing;_overlapped;pyexpat;_queue;select;unicodedata;winsound;_uuid;_wmi" /> + <ExtensionModules Include="_ctypes" Condition="$(IncludeCTypes)" /> + <!-- Extension modules that require external sources --> + <ExternalModules Include="_bz2;_lzma;_sqlite3" /> + <!-- venv launchers --> + <Projects Include="venvlauncher.vcxproj;venvwlauncher.vcxproj" /> + <!-- _ssl will build _socket as well, which may cause conflicts in parallel builds --> + <ExtensionModules Include="_socket" Condition="!$(IncludeSSL) or !$(IncludeExternals)" /> + <ExternalModules Include="_ssl;_hashlib" Condition="$(IncludeSSL)" /> + <ExternalModules Include="_tkinter" Condition="$(IncludeTkinter)" /> + <ExtensionModules Include="@(ExternalModules->'%(Identity)')" Condition="$(IncludeExternals)" /> + <Projects Include="@(ExtensionModules->'%(Identity).vcxproj')" Condition="$(IncludeExtensions)" /> + <!-- Test modules --> + <TestModules Include="_ctypes_test;_testbuffer;_testcapi;_testinternalcapi;_testembed;_testimportmultiple;_testmultiphase;_testsinglephase;_testconsole;_testclinic" /> + <TestModules Include="xxlimited" Condition="'$(Configuration)' == 'Release'" /> + <TestModules Include="xxlimited_35" Condition="'$(Configuration)' == 'Release'" /> + <Projects Include="@(TestModules->'%(Identity).vcxproj')" Condition="$(IncludeTests)"> + <!-- Disable parallel build for test modules --> + <BuildInParallel>false</BuildInParallel> + </Projects> + + <!-- _freeze_module --> + <FreezeProjects Include="_freeze_module.vcxproj" /> + <!-- python[w].exe --> + <Projects2 Include="python.vcxproj;pythonw.vcxproj" /> + <Projects2 Include="python_uwp.vcxproj;pythonw_uwp.vcxproj" Condition="$(IncludeUwp)" /> + <!-- venv[w]launcher.exe --> + <Projects2 Include="venvlauncher.vcxproj;venvwlauncher.vcxproj" /> + </ItemGroup> + + <Target Name="Build"> + <MSBuild Projects="@(FreezeProjects)" + Properties="Configuration=%(Configuration);Platform=%(Platform);%(Properties)" + BuildInParallel="%(BuildInParallel)" + StopOnFirstFailure="true" + Targets="%(BuildTarget)" /> + <MSBuild Projects="@(Projects)" + Properties="Configuration=%(Configuration);Platform=%(Platform);%(Properties)" + BuildInParallel="%(BuildInParallel)" + StopOnFirstFailure="true" + Targets="%(BuildTarget)" /> + <MSBuild Projects="@(Projects2)" + Properties="Configuration=%(Configuration);Platform=%(Platform);%(Properties)" + BuildInParallel="%(BuildInParallel)" + StopOnFirstFailure="true" + Targets="%(BuildTarget)" /> + </Target> + + <Target Name="Clean"> + <MSBuild Projects="@(Projects2)" + Properties="Configuration=%(Configuration);Platform=%(Platform);%(Properties)" + BuildInParallel="%(BuildInParallel)" + StopOnFirstFailure="false" + Condition="%(CleanTarget) != ''" + Targets="%(CleanTarget)" /> + <MSBuild Projects="@(Projects)" + Properties="Configuration=%(Configuration);Platform=%(Platform);%(Properties)" + BuildInParallel="%(BuildInParallel)" + StopOnFirstFailure="false" + Condition="%(CleanTarget) != ''" + Targets="%(CleanTarget)" /> + <MSBuild Projects="@(FreezeProjects)" + Properties="Configuration=%(Configuration);Platform=%(Platform);%(Properties)" + BuildInParallel="%(BuildInParallel)" + StopOnFirstFailure="false" + Condition="%(CleanTarget) != ''" + Targets="%(CleanTarget)" /> + </Target> + + <Target Name="CleanAll"> + <MSBuild Projects="@(Projects2)" + Properties="Configuration=%(Configuration);Platform=%(Platform);%(Properties)" + BuildInParallel="%(BuildInParallel)" + StopOnFirstFailure="false" + Condition="%(CleanAllTarget) != ''" + Targets="%(CleanAllTarget)" /> + <MSBuild Projects="@(Projects)" + Properties="Configuration=%(Configuration);Platform=%(Platform);%(Properties)" + BuildInParallel="%(BuildInParallel)" + StopOnFirstFailure="false" + Condition="%(CleanAllTarget) != ''" + Targets="%(CleanAllTarget)" /> + <MSBuild Projects="@(FreezeProjects)" + Properties="Configuration=%(Configuration);Platform=%(Platform);%(Properties)" + BuildInParallel="%(BuildInParallel)" + StopOnFirstFailure="false" + Condition="%(CleanTarget) != ''" + Targets="%(CleanTarget)" /> + </Target> + + <Target Name="Rebuild" DependsOnTargets="Clean;Build" /> + <Target Name="RebuildAll" DependsOnTargets="CleanAll;Build" /> +</Project> diff --git a/PCbuild/pcbuild.sln b/PCbuild/pcbuild.sln index 4d391650..bdddec60 100644 --- a/PCbuild/pcbuild.sln +++ b/PCbuild/pcbuild.sln @@ -1,1513 +1,1658 @@ -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.30028.174 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{553EC33E-9816-4996-A660-5D6186A0B0B3}" - ProjectSection(SolutionItems) = preProject - ..\Modules\getbuildinfo.c = ..\Modules\getbuildinfo.c - readme.txt = readme.txt - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "python", "python.vcxproj", "{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}" - ProjectSection(ProjectDependencies) = postProject - {0E9791DB-593A-465F-98BC-681011311618} = {0E9791DB-593A-465F-98BC-681011311618} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pythoncore", "pythoncore.vcxproj", "{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}" - ProjectSection(ProjectDependencies) = postProject - {19C0C13F-47CA-4432-AFF3-799A296A4DDC} = {19C0C13F-47CA-4432-AFF3-799A296A4DDC} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pythonw", "pythonw.vcxproj", "{F4229CC3-873C-49AE-9729-DD308ED4CD4A}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "winsound", "winsound.vcxproj", "{28B5D777-DDF2-4B6B-B34F-31D938813856}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_decimal", "_decimal.vcxproj", "{0E9791DB-593A-465F-98BC-681011311617}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_ctypes", "_ctypes.vcxproj", "{0E9791DB-593A-465F-98BC-681011311618}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_ctypes_test", "_ctypes_test.vcxproj", "{9EC7190A-249F-4180-A900-548FDCF3055F}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_elementtree", "_elementtree.vcxproj", "{17E1E049-C309-4D79-843F-AE483C264AEA}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_msi", "_msi.vcxproj", "{31FFC478-7B4A-43E8-9954-8D03E2187E9C}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_socket", "_socket.vcxproj", "{86937F53-C189-40EF-8CE8-8759D8E7D480}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_sqlite3", "_sqlite3.vcxproj", "{13CECB97-4119-4316-9D42-8534019A5A44}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_ssl", "_ssl.vcxproj", "{C6E20F84-3247-4AD6-B051-B073268F73BA}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testcapi", "_testcapi.vcxproj", "{6901D91C-6E48-4BB7-9FEC-700C8131DF1D}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testinternalcapi", "_testinternalcapi.vcxproj", "{900342D7-516A-4469-B1AD-59A66E49A25F}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testimportmultiple", "_testimportmultiple.vcxproj", "{36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_tkinter", "_tkinter.vcxproj", "{4946ECAC-2E69-4BF8-A90A-F5136F5094DF}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_bz2", "_bz2.vcxproj", "{73FCD2BD-F133-46B7-8EC1-144CD82A59D5}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "select", "select.vcxproj", "{18CAE28C-B454-46C1-87A0-493D91D97F03}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_lzma", "_lzma.vcxproj", "{F9D71780-F393-11E0-BE50-0800200C9A66}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unicodedata", "unicodedata.vcxproj", "{ECC7CEAC-A5E5-458E-BB9E-2413CC847881}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pyexpat", "pyexpat.vcxproj", "{D06B6426-4762-44CC-8BAD-D79052507F2F}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_hashlib", "_hashlib.vcxproj", "{447F05A8-F581-4CAC-A466-5AC7936E207E}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sqlite3", "sqlite3.vcxproj", "{A1A295E5-463C-437F-81CA-1F32367685DA}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_multiprocessing", "_multiprocessing.vcxproj", "{9E48B300-37D1-11DD-8C41-005056C00008}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "python3dll", "python3dll.vcxproj", "{885D4898-D08D-4091-9C40-C700CFE3FC5A}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xxlimited", "xxlimited.vcxproj", "{F749B822-B489-4CA5-A3AD-CE078F5F338A}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testbuffer", "_testbuffer.vcxproj", "{A2697BD3-28C1-4AEC-9106-8B748639FD16}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pylauncher", "pylauncher.vcxproj", "{7B2727B5-5A3F-40EE-A866-43A13CD31446}" - ProjectSection(ProjectDependencies) = postProject - {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782} = {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pywlauncher", "pywlauncher.vcxproj", "{1D4B18D3-7C12-4ECB-9179-8531FF876CE6}" - ProjectSection(ProjectDependencies) = postProject - {7B2727B5-5A3F-40EE-A866-43A13CD31446} = {7B2727B5-5A3F-40EE-A866-43A13CD31446} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_freeze_module", "_freeze_module.vcxproj", "{19C0C13F-47CA-4432-AFF3-799A296A4DDC}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_overlapped", "_overlapped.vcxproj", "{EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testembed", "_testembed.vcxproj", "{6DAC66D9-E703-4624-BE03-49112AB5AA62}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testmultiphase", "_testmultiphase.vcxproj", "{16BFE6F0-22EF-40B5-B831-7E937119EF10}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pyshellext", "pyshellext.vcxproj", "{0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testconsole", "_testconsole.vcxproj", "{B244E787-C445-441C-BDF4-5A4F1A3A1E51}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_asyncio", "_asyncio.vcxproj", "{384C224A-7474-476E-A01B-750EA7DE918C}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_zoneinfo", "_zoneinfo.vcxproj", "{FCBE1EF2-E0F0-40B1-88B5-00A35D378742}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_queue", "_queue.vcxproj", "{78D80A15-BD8C-44E2-B49E-1F05B0A0A687}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "liblzma", "liblzma.vcxproj", "{12728250-16EC-4DC6-94D7-E21DD88947F8}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "python_uwp", "python_uwp.vcxproj", "{9DE9E23D-C8D4-4817-92A9-920A8B1FE5FF}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "venvlauncher", "venvlauncher.vcxproj", "{494BAC80-A60C-43A9-99E7-ACB691CE2C4D}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "venvwlauncher", "venvwlauncher.vcxproj", "{FDB84CBB-2FB6-47C8-A2D6-091E0833239D}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pythonw_uwp", "pythonw_uwp.vcxproj", "{AB603547-1E2A-45B3-9E09-B04596006393}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_uuid", "_uuid.vcxproj", "{CB435430-EBB1-478B-8F4E-C256F6838F55}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|ARM = Debug|ARM - Debug|ARM64 = Debug|ARM64 - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - PGInstrument|ARM = PGInstrument|ARM - PGInstrument|ARM64 = PGInstrument|ARM64 - PGInstrument|Win32 = PGInstrument|Win32 - PGInstrument|x64 = PGInstrument|x64 - PGUpdate|ARM = PGUpdate|ARM - PGUpdate|ARM64 = PGUpdate|ARM64 - PGUpdate|Win32 = PGUpdate|Win32 - PGUpdate|x64 = PGUpdate|x64 - Release|ARM = Release|ARM - Release|ARM64 = Release|ARM64 - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Debug|ARM.ActiveCfg = Debug|ARM - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Debug|ARM.Build.0 = Debug|ARM - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Debug|ARM64.Build.0 = Debug|ARM64 - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Debug|Win32.ActiveCfg = Debug|Win32 - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Debug|Win32.Build.0 = Debug|Win32 - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Debug|x64.ActiveCfg = Debug|x64 - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Debug|x64.Build.0 = Debug|x64 - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGInstrument|ARM.Build.0 = PGInstrument|ARM - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGUpdate|ARM.Build.0 = PGUpdate|ARM - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Release|ARM.ActiveCfg = Release|ARM - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Release|ARM.Build.0 = Release|ARM - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Release|ARM64.ActiveCfg = Release|ARM64 - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Release|ARM64.Build.0 = Release|ARM64 - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Release|Win32.ActiveCfg = Release|Win32 - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Release|Win32.Build.0 = Release|Win32 - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Release|x64.ActiveCfg = Release|x64 - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Release|x64.Build.0 = Release|x64 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Debug|ARM.ActiveCfg = Debug|ARM - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Debug|ARM.Build.0 = Debug|ARM - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Debug|ARM64.Build.0 = Debug|ARM64 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Debug|Win32.ActiveCfg = Debug|Win32 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Debug|Win32.Build.0 = Debug|Win32 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Debug|x64.ActiveCfg = Debug|x64 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Debug|x64.Build.0 = Debug|x64 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGInstrument|ARM.Build.0 = PGInstrument|ARM - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGUpdate|ARM.Build.0 = PGUpdate|ARM - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Release|ARM.ActiveCfg = Release|ARM - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Release|ARM.Build.0 = Release|ARM - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Release|ARM64.ActiveCfg = Release|ARM64 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Release|ARM64.Build.0 = Release|ARM64 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Release|Win32.ActiveCfg = Release|Win32 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Release|Win32.Build.0 = Release|Win32 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Release|x64.ActiveCfg = Release|x64 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Release|x64.Build.0 = Release|x64 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Debug|ARM.ActiveCfg = Debug|ARM - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Debug|ARM.Build.0 = Debug|ARM - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Debug|ARM64.Build.0 = Debug|ARM64 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Debug|Win32.ActiveCfg = Debug|Win32 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Debug|Win32.Build.0 = Debug|Win32 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Debug|x64.ActiveCfg = Debug|x64 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Debug|x64.Build.0 = Debug|x64 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGInstrument|ARM.Build.0 = PGInstrument|ARM - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGInstrument|Win32.ActiveCfg = Release|Win32 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGInstrument|Win32.Build.0 = Release|Win32 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGInstrument|x64.ActiveCfg = Release|x64 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGInstrument|x64.Build.0 = Release|x64 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGUpdate|ARM.Build.0 = PGUpdate|ARM - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGUpdate|Win32.ActiveCfg = Release|Win32 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGUpdate|Win32.Build.0 = Release|Win32 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGUpdate|x64.ActiveCfg = Release|x64 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGUpdate|x64.Build.0 = Release|x64 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Release|ARM.ActiveCfg = Release|ARM - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Release|ARM.Build.0 = Release|ARM - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Release|ARM64.ActiveCfg = Release|ARM64 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Release|ARM64.Build.0 = Release|ARM64 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Release|Win32.ActiveCfg = Release|Win32 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Release|Win32.Build.0 = Release|Win32 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Release|x64.ActiveCfg = Release|x64 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Release|x64.Build.0 = Release|x64 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.Debug|ARM.ActiveCfg = Debug|ARM - {28B5D777-DDF2-4B6B-B34F-31D938813856}.Debug|ARM.Build.0 = Debug|ARM - {28B5D777-DDF2-4B6B-B34F-31D938813856}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.Debug|ARM64.Build.0 = Debug|ARM64 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.Debug|Win32.ActiveCfg = Debug|Win32 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.Debug|Win32.Build.0 = Debug|Win32 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.Debug|x64.ActiveCfg = Debug|x64 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.Debug|x64.Build.0 = Debug|x64 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM - {28B5D777-DDF2-4B6B-B34F-31D938813856}.PGInstrument|ARM.Build.0 = PGInstrument|ARM - {28B5D777-DDF2-4B6B-B34F-31D938813856}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM - {28B5D777-DDF2-4B6B-B34F-31D938813856}.PGUpdate|ARM.Build.0 = PGUpdate|ARM - {28B5D777-DDF2-4B6B-B34F-31D938813856}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.Release|ARM.ActiveCfg = Release|ARM - {28B5D777-DDF2-4B6B-B34F-31D938813856}.Release|ARM.Build.0 = Release|ARM - {28B5D777-DDF2-4B6B-B34F-31D938813856}.Release|ARM64.ActiveCfg = Release|ARM64 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.Release|ARM64.Build.0 = Release|ARM64 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.Release|Win32.ActiveCfg = Release|Win32 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.Release|Win32.Build.0 = Release|Win32 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.Release|x64.ActiveCfg = Release|x64 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.Release|x64.Build.0 = Release|x64 - {0E9791DB-593A-465F-98BC-681011311617}.Debug|ARM.ActiveCfg = Debug|ARM - {0E9791DB-593A-465F-98BC-681011311617}.Debug|ARM.Build.0 = Debug|ARM - {0E9791DB-593A-465F-98BC-681011311617}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {0E9791DB-593A-465F-98BC-681011311617}.Debug|ARM64.Build.0 = Debug|ARM64 - {0E9791DB-593A-465F-98BC-681011311617}.Debug|Win32.ActiveCfg = Debug|Win32 - {0E9791DB-593A-465F-98BC-681011311617}.Debug|Win32.Build.0 = Debug|Win32 - {0E9791DB-593A-465F-98BC-681011311617}.Debug|x64.ActiveCfg = Debug|x64 - {0E9791DB-593A-465F-98BC-681011311617}.Debug|x64.Build.0 = Debug|x64 - {0E9791DB-593A-465F-98BC-681011311617}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM - {0E9791DB-593A-465F-98BC-681011311617}.PGInstrument|ARM.Build.0 = PGInstrument|ARM - {0E9791DB-593A-465F-98BC-681011311617}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 - {0E9791DB-593A-465F-98BC-681011311617}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 - {0E9791DB-593A-465F-98BC-681011311617}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {0E9791DB-593A-465F-98BC-681011311617}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {0E9791DB-593A-465F-98BC-681011311617}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {0E9791DB-593A-465F-98BC-681011311617}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {0E9791DB-593A-465F-98BC-681011311617}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM - {0E9791DB-593A-465F-98BC-681011311617}.PGUpdate|ARM.Build.0 = PGUpdate|ARM - {0E9791DB-593A-465F-98BC-681011311617}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 - {0E9791DB-593A-465F-98BC-681011311617}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 - {0E9791DB-593A-465F-98BC-681011311617}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {0E9791DB-593A-465F-98BC-681011311617}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {0E9791DB-593A-465F-98BC-681011311617}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {0E9791DB-593A-465F-98BC-681011311617}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {0E9791DB-593A-465F-98BC-681011311617}.Release|ARM.ActiveCfg = Release|ARM - {0E9791DB-593A-465F-98BC-681011311617}.Release|ARM.Build.0 = Release|ARM - {0E9791DB-593A-465F-98BC-681011311617}.Release|ARM64.ActiveCfg = Release|ARM64 - {0E9791DB-593A-465F-98BC-681011311617}.Release|ARM64.Build.0 = Release|ARM64 - {0E9791DB-593A-465F-98BC-681011311617}.Release|Win32.ActiveCfg = Release|Win32 - {0E9791DB-593A-465F-98BC-681011311617}.Release|Win32.Build.0 = Release|Win32 - {0E9791DB-593A-465F-98BC-681011311617}.Release|x64.ActiveCfg = Release|x64 - {0E9791DB-593A-465F-98BC-681011311617}.Release|x64.Build.0 = Release|x64 - {0E9791DB-593A-465F-98BC-681011311618}.Debug|ARM.ActiveCfg = Debug|ARM - {0E9791DB-593A-465F-98BC-681011311618}.Debug|ARM.Build.0 = Debug|ARM - {0E9791DB-593A-465F-98BC-681011311618}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {0E9791DB-593A-465F-98BC-681011311618}.Debug|ARM64.Build.0 = Debug|ARM64 - {0E9791DB-593A-465F-98BC-681011311618}.Debug|Win32.ActiveCfg = Debug|Win32 - {0E9791DB-593A-465F-98BC-681011311618}.Debug|Win32.Build.0 = Debug|Win32 - {0E9791DB-593A-465F-98BC-681011311618}.Debug|x64.ActiveCfg = Debug|x64 - {0E9791DB-593A-465F-98BC-681011311618}.Debug|x64.Build.0 = Debug|x64 - {0E9791DB-593A-465F-98BC-681011311618}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM - {0E9791DB-593A-465F-98BC-681011311618}.PGInstrument|ARM.Build.0 = PGInstrument|ARM - {0E9791DB-593A-465F-98BC-681011311618}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 - {0E9791DB-593A-465F-98BC-681011311618}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 - {0E9791DB-593A-465F-98BC-681011311618}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {0E9791DB-593A-465F-98BC-681011311618}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {0E9791DB-593A-465F-98BC-681011311618}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {0E9791DB-593A-465F-98BC-681011311618}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {0E9791DB-593A-465F-98BC-681011311618}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM - {0E9791DB-593A-465F-98BC-681011311618}.PGUpdate|ARM.Build.0 = PGUpdate|ARM - {0E9791DB-593A-465F-98BC-681011311618}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 - {0E9791DB-593A-465F-98BC-681011311618}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 - {0E9791DB-593A-465F-98BC-681011311618}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {0E9791DB-593A-465F-98BC-681011311618}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {0E9791DB-593A-465F-98BC-681011311618}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {0E9791DB-593A-465F-98BC-681011311618}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {0E9791DB-593A-465F-98BC-681011311618}.Release|ARM.ActiveCfg = Release|ARM - {0E9791DB-593A-465F-98BC-681011311618}.Release|ARM.Build.0 = Release|ARM - {0E9791DB-593A-465F-98BC-681011311618}.Release|ARM64.ActiveCfg = Release|ARM64 - {0E9791DB-593A-465F-98BC-681011311618}.Release|ARM64.Build.0 = Release|ARM64 - {0E9791DB-593A-465F-98BC-681011311618}.Release|Win32.ActiveCfg = Release|Win32 - {0E9791DB-593A-465F-98BC-681011311618}.Release|Win32.Build.0 = Release|Win32 - {0E9791DB-593A-465F-98BC-681011311618}.Release|x64.ActiveCfg = Release|x64 - {0E9791DB-593A-465F-98BC-681011311618}.Release|x64.Build.0 = Release|x64 - {9EC7190A-249F-4180-A900-548FDCF3055F}.Debug|ARM.ActiveCfg = Debug|ARM - {9EC7190A-249F-4180-A900-548FDCF3055F}.Debug|ARM.Build.0 = Debug|ARM - {9EC7190A-249F-4180-A900-548FDCF3055F}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {9EC7190A-249F-4180-A900-548FDCF3055F}.Debug|ARM64.Build.0 = Debug|ARM64 - {9EC7190A-249F-4180-A900-548FDCF3055F}.Debug|Win32.ActiveCfg = Debug|Win32 - {9EC7190A-249F-4180-A900-548FDCF3055F}.Debug|Win32.Build.0 = Debug|Win32 - {9EC7190A-249F-4180-A900-548FDCF3055F}.Debug|x64.ActiveCfg = Debug|x64 - {9EC7190A-249F-4180-A900-548FDCF3055F}.Debug|x64.Build.0 = Debug|x64 - {9EC7190A-249F-4180-A900-548FDCF3055F}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM - {9EC7190A-249F-4180-A900-548FDCF3055F}.PGInstrument|ARM.Build.0 = PGInstrument|ARM - {9EC7190A-249F-4180-A900-548FDCF3055F}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 - {9EC7190A-249F-4180-A900-548FDCF3055F}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 - {9EC7190A-249F-4180-A900-548FDCF3055F}.PGInstrument|Win32.ActiveCfg = Release|Win32 - {9EC7190A-249F-4180-A900-548FDCF3055F}.PGInstrument|Win32.Build.0 = Release|Win32 - {9EC7190A-249F-4180-A900-548FDCF3055F}.PGInstrument|x64.ActiveCfg = Release|x64 - {9EC7190A-249F-4180-A900-548FDCF3055F}.PGInstrument|x64.Build.0 = Release|x64 - {9EC7190A-249F-4180-A900-548FDCF3055F}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM - {9EC7190A-249F-4180-A900-548FDCF3055F}.PGUpdate|ARM.Build.0 = PGUpdate|ARM - {9EC7190A-249F-4180-A900-548FDCF3055F}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 - {9EC7190A-249F-4180-A900-548FDCF3055F}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 - {9EC7190A-249F-4180-A900-548FDCF3055F}.PGUpdate|Win32.ActiveCfg = Release|Win32 - {9EC7190A-249F-4180-A900-548FDCF3055F}.PGUpdate|Win32.Build.0 = Release|Win32 - {9EC7190A-249F-4180-A900-548FDCF3055F}.PGUpdate|x64.ActiveCfg = Release|x64 - {9EC7190A-249F-4180-A900-548FDCF3055F}.PGUpdate|x64.Build.0 = Release|x64 - {9EC7190A-249F-4180-A900-548FDCF3055F}.Release|ARM.ActiveCfg = Release|ARM - {9EC7190A-249F-4180-A900-548FDCF3055F}.Release|ARM.Build.0 = Release|ARM - {9EC7190A-249F-4180-A900-548FDCF3055F}.Release|ARM64.ActiveCfg = Release|ARM64 - {9EC7190A-249F-4180-A900-548FDCF3055F}.Release|ARM64.Build.0 = Release|ARM64 - {9EC7190A-249F-4180-A900-548FDCF3055F}.Release|Win32.ActiveCfg = Release|Win32 - {9EC7190A-249F-4180-A900-548FDCF3055F}.Release|Win32.Build.0 = Release|Win32 - {9EC7190A-249F-4180-A900-548FDCF3055F}.Release|x64.ActiveCfg = Release|x64 - {9EC7190A-249F-4180-A900-548FDCF3055F}.Release|x64.Build.0 = Release|x64 - {17E1E049-C309-4D79-843F-AE483C264AEA}.Debug|ARM.ActiveCfg = Debug|ARM - {17E1E049-C309-4D79-843F-AE483C264AEA}.Debug|ARM.Build.0 = Debug|ARM - {17E1E049-C309-4D79-843F-AE483C264AEA}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {17E1E049-C309-4D79-843F-AE483C264AEA}.Debug|ARM64.Build.0 = Debug|ARM64 - {17E1E049-C309-4D79-843F-AE483C264AEA}.Debug|Win32.ActiveCfg = Debug|Win32 - {17E1E049-C309-4D79-843F-AE483C264AEA}.Debug|Win32.Build.0 = Debug|Win32 - {17E1E049-C309-4D79-843F-AE483C264AEA}.Debug|x64.ActiveCfg = Debug|x64 - {17E1E049-C309-4D79-843F-AE483C264AEA}.Debug|x64.Build.0 = Debug|x64 - {17E1E049-C309-4D79-843F-AE483C264AEA}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM - {17E1E049-C309-4D79-843F-AE483C264AEA}.PGInstrument|ARM.Build.0 = PGInstrument|ARM - {17E1E049-C309-4D79-843F-AE483C264AEA}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 - {17E1E049-C309-4D79-843F-AE483C264AEA}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 - {17E1E049-C309-4D79-843F-AE483C264AEA}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {17E1E049-C309-4D79-843F-AE483C264AEA}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {17E1E049-C309-4D79-843F-AE483C264AEA}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {17E1E049-C309-4D79-843F-AE483C264AEA}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {17E1E049-C309-4D79-843F-AE483C264AEA}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM - {17E1E049-C309-4D79-843F-AE483C264AEA}.PGUpdate|ARM.Build.0 = PGUpdate|ARM - {17E1E049-C309-4D79-843F-AE483C264AEA}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 - {17E1E049-C309-4D79-843F-AE483C264AEA}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 - {17E1E049-C309-4D79-843F-AE483C264AEA}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {17E1E049-C309-4D79-843F-AE483C264AEA}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {17E1E049-C309-4D79-843F-AE483C264AEA}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {17E1E049-C309-4D79-843F-AE483C264AEA}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {17E1E049-C309-4D79-843F-AE483C264AEA}.Release|ARM.ActiveCfg = Release|ARM - {17E1E049-C309-4D79-843F-AE483C264AEA}.Release|ARM.Build.0 = Release|ARM - {17E1E049-C309-4D79-843F-AE483C264AEA}.Release|ARM64.ActiveCfg = Release|ARM64 - {17E1E049-C309-4D79-843F-AE483C264AEA}.Release|ARM64.Build.0 = Release|ARM64 - {17E1E049-C309-4D79-843F-AE483C264AEA}.Release|Win32.ActiveCfg = Release|Win32 - {17E1E049-C309-4D79-843F-AE483C264AEA}.Release|Win32.Build.0 = Release|Win32 - {17E1E049-C309-4D79-843F-AE483C264AEA}.Release|x64.ActiveCfg = Release|x64 - {17E1E049-C309-4D79-843F-AE483C264AEA}.Release|x64.Build.0 = Release|x64 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Debug|ARM.ActiveCfg = Debug|ARM - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Debug|ARM.Build.0 = Debug|ARM - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Debug|ARM64.Build.0 = Debug|ARM64 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Debug|Win32.ActiveCfg = Debug|Win32 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Debug|Win32.Build.0 = Debug|Win32 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Debug|x64.ActiveCfg = Debug|x64 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Debug|x64.Build.0 = Debug|x64 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGInstrument|ARM.Build.0 = PGInstrument|ARM - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGUpdate|ARM.Build.0 = PGUpdate|ARM - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Release|ARM.ActiveCfg = Release|ARM - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Release|ARM.Build.0 = Release|ARM - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Release|ARM64.ActiveCfg = Release|ARM64 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Release|ARM64.Build.0 = Release|ARM64 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Release|Win32.ActiveCfg = Release|Win32 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Release|Win32.Build.0 = Release|Win32 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Release|x64.ActiveCfg = Release|x64 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Release|x64.Build.0 = Release|x64 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.Debug|ARM.ActiveCfg = Debug|ARM - {86937F53-C189-40EF-8CE8-8759D8E7D480}.Debug|ARM.Build.0 = Debug|ARM - {86937F53-C189-40EF-8CE8-8759D8E7D480}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.Debug|ARM64.Build.0 = Debug|ARM64 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.Debug|Win32.ActiveCfg = Debug|Win32 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.Debug|Win32.Build.0 = Debug|Win32 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.Debug|x64.ActiveCfg = Debug|x64 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.Debug|x64.Build.0 = Debug|x64 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM - {86937F53-C189-40EF-8CE8-8759D8E7D480}.PGInstrument|ARM.Build.0 = PGInstrument|ARM - {86937F53-C189-40EF-8CE8-8759D8E7D480}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM - {86937F53-C189-40EF-8CE8-8759D8E7D480}.PGUpdate|ARM.Build.0 = PGUpdate|ARM - {86937F53-C189-40EF-8CE8-8759D8E7D480}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.Release|ARM.ActiveCfg = Release|ARM - {86937F53-C189-40EF-8CE8-8759D8E7D480}.Release|ARM.Build.0 = Release|ARM - {86937F53-C189-40EF-8CE8-8759D8E7D480}.Release|ARM64.ActiveCfg = Release|ARM64 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.Release|ARM64.Build.0 = Release|ARM64 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.Release|Win32.ActiveCfg = Release|Win32 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.Release|Win32.Build.0 = Release|Win32 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.Release|x64.ActiveCfg = Release|x64 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.Release|x64.Build.0 = Release|x64 - {13CECB97-4119-4316-9D42-8534019A5A44}.Debug|ARM.ActiveCfg = Debug|ARM - {13CECB97-4119-4316-9D42-8534019A5A44}.Debug|ARM.Build.0 = Debug|ARM - {13CECB97-4119-4316-9D42-8534019A5A44}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {13CECB97-4119-4316-9D42-8534019A5A44}.Debug|ARM64.Build.0 = Debug|ARM64 - {13CECB97-4119-4316-9D42-8534019A5A44}.Debug|Win32.ActiveCfg = Debug|Win32 - {13CECB97-4119-4316-9D42-8534019A5A44}.Debug|Win32.Build.0 = Debug|Win32 - {13CECB97-4119-4316-9D42-8534019A5A44}.Debug|x64.ActiveCfg = Debug|x64 - {13CECB97-4119-4316-9D42-8534019A5A44}.Debug|x64.Build.0 = Debug|x64 - {13CECB97-4119-4316-9D42-8534019A5A44}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM - {13CECB97-4119-4316-9D42-8534019A5A44}.PGInstrument|ARM.Build.0 = PGInstrument|ARM - {13CECB97-4119-4316-9D42-8534019A5A44}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 - {13CECB97-4119-4316-9D42-8534019A5A44}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 - {13CECB97-4119-4316-9D42-8534019A5A44}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {13CECB97-4119-4316-9D42-8534019A5A44}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {13CECB97-4119-4316-9D42-8534019A5A44}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {13CECB97-4119-4316-9D42-8534019A5A44}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {13CECB97-4119-4316-9D42-8534019A5A44}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM - {13CECB97-4119-4316-9D42-8534019A5A44}.PGUpdate|ARM.Build.0 = PGUpdate|ARM - {13CECB97-4119-4316-9D42-8534019A5A44}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 - {13CECB97-4119-4316-9D42-8534019A5A44}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 - {13CECB97-4119-4316-9D42-8534019A5A44}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {13CECB97-4119-4316-9D42-8534019A5A44}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {13CECB97-4119-4316-9D42-8534019A5A44}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {13CECB97-4119-4316-9D42-8534019A5A44}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {13CECB97-4119-4316-9D42-8534019A5A44}.Release|ARM.ActiveCfg = Release|ARM - {13CECB97-4119-4316-9D42-8534019A5A44}.Release|ARM.Build.0 = Release|ARM - {13CECB97-4119-4316-9D42-8534019A5A44}.Release|ARM64.ActiveCfg = Release|ARM64 - {13CECB97-4119-4316-9D42-8534019A5A44}.Release|ARM64.Build.0 = Release|ARM64 - {13CECB97-4119-4316-9D42-8534019A5A44}.Release|Win32.ActiveCfg = Release|Win32 - {13CECB97-4119-4316-9D42-8534019A5A44}.Release|Win32.Build.0 = Release|Win32 - {13CECB97-4119-4316-9D42-8534019A5A44}.Release|x64.ActiveCfg = Release|x64 - {13CECB97-4119-4316-9D42-8534019A5A44}.Release|x64.Build.0 = Release|x64 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.Debug|ARM.ActiveCfg = Debug|ARM - {C6E20F84-3247-4AD6-B051-B073268F73BA}.Debug|ARM.Build.0 = Debug|ARM - {C6E20F84-3247-4AD6-B051-B073268F73BA}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.Debug|ARM64.Build.0 = Debug|ARM64 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.Debug|Win32.ActiveCfg = Debug|Win32 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.Debug|Win32.Build.0 = Debug|Win32 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.Debug|x64.ActiveCfg = Debug|x64 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.Debug|x64.Build.0 = Debug|x64 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM - {C6E20F84-3247-4AD6-B051-B073268F73BA}.PGInstrument|ARM.Build.0 = PGInstrument|ARM - {C6E20F84-3247-4AD6-B051-B073268F73BA}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM - {C6E20F84-3247-4AD6-B051-B073268F73BA}.PGUpdate|ARM.Build.0 = PGUpdate|ARM - {C6E20F84-3247-4AD6-B051-B073268F73BA}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.Release|ARM.ActiveCfg = Release|ARM - {C6E20F84-3247-4AD6-B051-B073268F73BA}.Release|ARM.Build.0 = Release|ARM - {C6E20F84-3247-4AD6-B051-B073268F73BA}.Release|ARM64.ActiveCfg = Release|ARM64 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.Release|ARM64.Build.0 = Release|ARM64 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.Release|Win32.ActiveCfg = Release|Win32 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.Release|Win32.Build.0 = Release|Win32 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.Release|x64.ActiveCfg = Release|x64 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.Release|x64.Build.0 = Release|x64 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Debug|ARM.ActiveCfg = Debug|ARM - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Debug|ARM.Build.0 = Debug|ARM - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Debug|ARM64.Build.0 = Debug|ARM64 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Debug|Win32.ActiveCfg = Debug|Win32 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Debug|Win32.Build.0 = Debug|Win32 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Debug|x64.ActiveCfg = Debug|x64 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Debug|x64.Build.0 = Debug|x64 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGInstrument|ARM.Build.0 = PGInstrument|ARM - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGUpdate|ARM.Build.0 = PGUpdate|ARM - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Release|ARM.ActiveCfg = Release|ARM - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Release|ARM.Build.0 = Release|ARM - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Release|ARM64.ActiveCfg = Release|ARM64 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Release|ARM64.Build.0 = Release|ARM64 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Release|Win32.ActiveCfg = Release|Win32 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Release|Win32.Build.0 = Release|Win32 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Release|x64.ActiveCfg = Release|x64 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Release|x64.Build.0 = Release|x64 - {900342D7-516A-4469-B1AD-59A66E49A25F}.Debug|ARM.ActiveCfg = Debug|ARM - {900342D7-516A-4469-B1AD-59A66E49A25F}.Debug|ARM.Build.0 = Debug|ARM - {900342D7-516A-4469-B1AD-59A66E49A25F}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {900342D7-516A-4469-B1AD-59A66E49A25F}.Debug|ARM64.Build.0 = Debug|ARM64 - {900342D7-516A-4469-B1AD-59A66E49A25F}.Debug|Win32.ActiveCfg = Debug|Win32 - {900342D7-516A-4469-B1AD-59A66E49A25F}.Debug|Win32.Build.0 = Debug|Win32 - {900342D7-516A-4469-B1AD-59A66E49A25F}.Debug|x64.ActiveCfg = Debug|x64 - {900342D7-516A-4469-B1AD-59A66E49A25F}.Debug|x64.Build.0 = Debug|x64 - {900342D7-516A-4469-B1AD-59A66E49A25F}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM - {900342D7-516A-4469-B1AD-59A66E49A25F}.PGInstrument|ARM.Build.0 = PGInstrument|ARM - {900342D7-516A-4469-B1AD-59A66E49A25F}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 - {900342D7-516A-4469-B1AD-59A66E49A25F}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 - {900342D7-516A-4469-B1AD-59A66E49A25F}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {900342D7-516A-4469-B1AD-59A66E49A25F}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {900342D7-516A-4469-B1AD-59A66E49A25F}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {900342D7-516A-4469-B1AD-59A66E49A25F}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {900342D7-516A-4469-B1AD-59A66E49A25F}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM - {900342D7-516A-4469-B1AD-59A66E49A25F}.PGUpdate|ARM.Build.0 = PGUpdate|ARM - {900342D7-516A-4469-B1AD-59A66E49A25F}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 - {900342D7-516A-4469-B1AD-59A66E49A25F}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 - {900342D7-516A-4469-B1AD-59A66E49A25F}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {900342D7-516A-4469-B1AD-59A66E49A25F}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {900342D7-516A-4469-B1AD-59A66E49A25F}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {900342D7-516A-4469-B1AD-59A66E49A25F}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {900342D7-516A-4469-B1AD-59A66E49A25F}.Release|ARM.ActiveCfg = Release|ARM - {900342D7-516A-4469-B1AD-59A66E49A25F}.Release|ARM.Build.0 = Release|ARM - {900342D7-516A-4469-B1AD-59A66E49A25F}.Release|ARM64.ActiveCfg = Release|ARM64 - {900342D7-516A-4469-B1AD-59A66E49A25F}.Release|ARM64.Build.0 = Release|ARM64 - {900342D7-516A-4469-B1AD-59A66E49A25F}.Release|Win32.ActiveCfg = Release|Win32 - {900342D7-516A-4469-B1AD-59A66E49A25F}.Release|Win32.Build.0 = Release|Win32 - {900342D7-516A-4469-B1AD-59A66E49A25F}.Release|x64.ActiveCfg = Release|x64 - {900342D7-516A-4469-B1AD-59A66E49A25F}.Release|x64.Build.0 = Release|x64 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Debug|ARM.ActiveCfg = Debug|ARM - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Debug|ARM.Build.0 = Debug|ARM - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Debug|ARM64.Build.0 = Debug|ARM64 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Debug|Win32.ActiveCfg = Debug|Win32 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Debug|Win32.Build.0 = Debug|Win32 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Debug|x64.ActiveCfg = Debug|x64 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Debug|x64.Build.0 = Debug|x64 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGInstrument|ARM.Build.0 = PGInstrument|ARM - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGInstrument|Win32.ActiveCfg = Release|Win32 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGInstrument|Win32.Build.0 = Release|Win32 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGInstrument|x64.ActiveCfg = Release|x64 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGInstrument|x64.Build.0 = Release|x64 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGUpdate|ARM.Build.0 = PGUpdate|ARM - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGUpdate|Win32.ActiveCfg = Release|Win32 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGUpdate|Win32.Build.0 = Release|Win32 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGUpdate|x64.ActiveCfg = Release|x64 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGUpdate|x64.Build.0 = Release|x64 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Release|ARM.ActiveCfg = Release|ARM - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Release|ARM.Build.0 = Release|ARM - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Release|ARM64.ActiveCfg = Release|ARM64 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Release|ARM64.Build.0 = Release|ARM64 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Release|Win32.ActiveCfg = Release|Win32 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Release|Win32.Build.0 = Release|Win32 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Release|x64.ActiveCfg = Release|x64 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Release|x64.Build.0 = Release|x64 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Debug|ARM.ActiveCfg = Debug|ARM - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Debug|Win32.ActiveCfg = Debug|Win32 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Debug|Win32.Build.0 = Debug|Win32 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Debug|x64.ActiveCfg = Debug|x64 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Debug|x64.Build.0 = Debug|x64 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGInstrument|ARM.Build.0 = PGInstrument|ARM - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGUpdate|ARM.Build.0 = PGUpdate|ARM - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Release|ARM.ActiveCfg = Release|ARM - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Release|ARM64.ActiveCfg = Release|ARM64 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Release|Win32.ActiveCfg = Release|Win32 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Release|Win32.Build.0 = Release|Win32 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Release|x64.ActiveCfg = Release|x64 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Release|x64.Build.0 = Release|x64 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Debug|ARM.ActiveCfg = Debug|ARM - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Debug|ARM.Build.0 = Debug|ARM - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Debug|ARM64.Build.0 = Debug|ARM64 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Debug|Win32.ActiveCfg = Debug|Win32 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Debug|Win32.Build.0 = Debug|Win32 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Debug|x64.ActiveCfg = Debug|x64 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Debug|x64.Build.0 = Debug|x64 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGInstrument|ARM.Build.0 = PGInstrument|ARM - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGUpdate|ARM.Build.0 = PGUpdate|ARM - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Release|ARM.ActiveCfg = Release|ARM - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Release|ARM.Build.0 = Release|ARM - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Release|ARM64.ActiveCfg = Release|ARM64 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Release|ARM64.Build.0 = Release|ARM64 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Release|Win32.ActiveCfg = Release|Win32 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Release|Win32.Build.0 = Release|Win32 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Release|x64.ActiveCfg = Release|x64 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Release|x64.Build.0 = Release|x64 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.Debug|ARM.ActiveCfg = Debug|ARM - {18CAE28C-B454-46C1-87A0-493D91D97F03}.Debug|ARM.Build.0 = Debug|ARM - {18CAE28C-B454-46C1-87A0-493D91D97F03}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.Debug|ARM64.Build.0 = Debug|ARM64 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.Debug|Win32.ActiveCfg = Debug|Win32 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.Debug|Win32.Build.0 = Debug|Win32 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.Debug|x64.ActiveCfg = Debug|x64 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.Debug|x64.Build.0 = Debug|x64 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM - {18CAE28C-B454-46C1-87A0-493D91D97F03}.PGInstrument|ARM.Build.0 = PGInstrument|ARM - {18CAE28C-B454-46C1-87A0-493D91D97F03}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM - {18CAE28C-B454-46C1-87A0-493D91D97F03}.PGUpdate|ARM.Build.0 = PGUpdate|ARM - {18CAE28C-B454-46C1-87A0-493D91D97F03}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.Release|ARM.ActiveCfg = Release|ARM - {18CAE28C-B454-46C1-87A0-493D91D97F03}.Release|ARM.Build.0 = Release|ARM - {18CAE28C-B454-46C1-87A0-493D91D97F03}.Release|ARM64.ActiveCfg = Release|ARM64 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.Release|ARM64.Build.0 = Release|ARM64 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.Release|Win32.ActiveCfg = Release|Win32 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.Release|Win32.Build.0 = Release|Win32 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.Release|x64.ActiveCfg = Release|x64 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.Release|x64.Build.0 = Release|x64 - {F9D71780-F393-11E0-BE50-0800200C9A66}.Debug|ARM.ActiveCfg = Debug|ARM - {F9D71780-F393-11E0-BE50-0800200C9A66}.Debug|ARM.Build.0 = Debug|ARM - {F9D71780-F393-11E0-BE50-0800200C9A66}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {F9D71780-F393-11E0-BE50-0800200C9A66}.Debug|ARM64.Build.0 = Debug|ARM64 - {F9D71780-F393-11E0-BE50-0800200C9A66}.Debug|Win32.ActiveCfg = Debug|Win32 - {F9D71780-F393-11E0-BE50-0800200C9A66}.Debug|Win32.Build.0 = Debug|Win32 - {F9D71780-F393-11E0-BE50-0800200C9A66}.Debug|x64.ActiveCfg = Debug|x64 - {F9D71780-F393-11E0-BE50-0800200C9A66}.Debug|x64.Build.0 = Debug|x64 - {F9D71780-F393-11E0-BE50-0800200C9A66}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM - {F9D71780-F393-11E0-BE50-0800200C9A66}.PGInstrument|ARM.Build.0 = PGInstrument|ARM - {F9D71780-F393-11E0-BE50-0800200C9A66}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 - {F9D71780-F393-11E0-BE50-0800200C9A66}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 - {F9D71780-F393-11E0-BE50-0800200C9A66}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {F9D71780-F393-11E0-BE50-0800200C9A66}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {F9D71780-F393-11E0-BE50-0800200C9A66}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {F9D71780-F393-11E0-BE50-0800200C9A66}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {F9D71780-F393-11E0-BE50-0800200C9A66}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM - {F9D71780-F393-11E0-BE50-0800200C9A66}.PGUpdate|ARM.Build.0 = PGUpdate|ARM - {F9D71780-F393-11E0-BE50-0800200C9A66}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 - {F9D71780-F393-11E0-BE50-0800200C9A66}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 - {F9D71780-F393-11E0-BE50-0800200C9A66}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {F9D71780-F393-11E0-BE50-0800200C9A66}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {F9D71780-F393-11E0-BE50-0800200C9A66}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {F9D71780-F393-11E0-BE50-0800200C9A66}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {F9D71780-F393-11E0-BE50-0800200C9A66}.Release|ARM.ActiveCfg = Release|ARM - {F9D71780-F393-11E0-BE50-0800200C9A66}.Release|ARM.Build.0 = Release|ARM - {F9D71780-F393-11E0-BE50-0800200C9A66}.Release|ARM64.ActiveCfg = Release|ARM64 - {F9D71780-F393-11E0-BE50-0800200C9A66}.Release|ARM64.Build.0 = Release|ARM64 - {F9D71780-F393-11E0-BE50-0800200C9A66}.Release|Win32.ActiveCfg = Release|Win32 - {F9D71780-F393-11E0-BE50-0800200C9A66}.Release|Win32.Build.0 = Release|Win32 - {F9D71780-F393-11E0-BE50-0800200C9A66}.Release|x64.ActiveCfg = Release|x64 - {F9D71780-F393-11E0-BE50-0800200C9A66}.Release|x64.Build.0 = Release|x64 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Debug|ARM.ActiveCfg = Debug|ARM - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Debug|ARM.Build.0 = Debug|ARM - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Debug|ARM64.Build.0 = Debug|ARM64 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Debug|Win32.ActiveCfg = Debug|Win32 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Debug|Win32.Build.0 = Debug|Win32 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Debug|x64.ActiveCfg = Debug|x64 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Debug|x64.Build.0 = Debug|x64 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGInstrument|ARM.Build.0 = PGInstrument|ARM - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGUpdate|ARM.Build.0 = PGUpdate|ARM - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Release|ARM.ActiveCfg = Release|ARM - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Release|ARM.Build.0 = Release|ARM - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Release|ARM64.ActiveCfg = Release|ARM64 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Release|ARM64.Build.0 = Release|ARM64 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Release|Win32.ActiveCfg = Release|Win32 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Release|Win32.Build.0 = Release|Win32 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Release|x64.ActiveCfg = Release|x64 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Release|x64.Build.0 = Release|x64 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.Debug|ARM.ActiveCfg = Debug|ARM - {D06B6426-4762-44CC-8BAD-D79052507F2F}.Debug|ARM.Build.0 = Debug|ARM - {D06B6426-4762-44CC-8BAD-D79052507F2F}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.Debug|ARM64.Build.0 = Debug|ARM64 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.Debug|Win32.ActiveCfg = Debug|Win32 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.Debug|Win32.Build.0 = Debug|Win32 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.Debug|x64.ActiveCfg = Debug|x64 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.Debug|x64.Build.0 = Debug|x64 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM - {D06B6426-4762-44CC-8BAD-D79052507F2F}.PGInstrument|ARM.Build.0 = PGInstrument|ARM - {D06B6426-4762-44CC-8BAD-D79052507F2F}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM - {D06B6426-4762-44CC-8BAD-D79052507F2F}.PGUpdate|ARM.Build.0 = PGUpdate|ARM - {D06B6426-4762-44CC-8BAD-D79052507F2F}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.Release|ARM.ActiveCfg = Release|ARM - {D06B6426-4762-44CC-8BAD-D79052507F2F}.Release|ARM.Build.0 = Release|ARM - {D06B6426-4762-44CC-8BAD-D79052507F2F}.Release|ARM64.ActiveCfg = Release|ARM64 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.Release|ARM64.Build.0 = Release|ARM64 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.Release|Win32.ActiveCfg = Release|Win32 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.Release|Win32.Build.0 = Release|Win32 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.Release|x64.ActiveCfg = Release|x64 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.Release|x64.Build.0 = Release|x64 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.Debug|ARM.ActiveCfg = Debug|ARM - {447F05A8-F581-4CAC-A466-5AC7936E207E}.Debug|ARM.Build.0 = Debug|ARM - {447F05A8-F581-4CAC-A466-5AC7936E207E}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.Debug|ARM64.Build.0 = Debug|ARM64 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.Debug|Win32.ActiveCfg = Debug|Win32 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.Debug|Win32.Build.0 = Debug|Win32 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.Debug|x64.ActiveCfg = Debug|x64 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.Debug|x64.Build.0 = Debug|x64 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM - {447F05A8-F581-4CAC-A466-5AC7936E207E}.PGInstrument|ARM.Build.0 = PGInstrument|ARM - {447F05A8-F581-4CAC-A466-5AC7936E207E}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM - {447F05A8-F581-4CAC-A466-5AC7936E207E}.PGUpdate|ARM.Build.0 = PGUpdate|ARM - {447F05A8-F581-4CAC-A466-5AC7936E207E}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.Release|ARM.ActiveCfg = Release|ARM - {447F05A8-F581-4CAC-A466-5AC7936E207E}.Release|ARM.Build.0 = Release|ARM - {447F05A8-F581-4CAC-A466-5AC7936E207E}.Release|ARM64.ActiveCfg = Release|ARM64 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.Release|ARM64.Build.0 = Release|ARM64 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.Release|Win32.ActiveCfg = Release|Win32 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.Release|Win32.Build.0 = Release|Win32 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.Release|x64.ActiveCfg = Release|x64 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.Release|x64.Build.0 = Release|x64 - {A1A295E5-463C-437F-81CA-1F32367685DA}.Debug|ARM.ActiveCfg = Debug|ARM - {A1A295E5-463C-437F-81CA-1F32367685DA}.Debug|ARM.Build.0 = Debug|ARM - {A1A295E5-463C-437F-81CA-1F32367685DA}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {A1A295E5-463C-437F-81CA-1F32367685DA}.Debug|ARM64.Build.0 = Debug|ARM64 - {A1A295E5-463C-437F-81CA-1F32367685DA}.Debug|Win32.ActiveCfg = Debug|Win32 - {A1A295E5-463C-437F-81CA-1F32367685DA}.Debug|Win32.Build.0 = Debug|Win32 - {A1A295E5-463C-437F-81CA-1F32367685DA}.Debug|x64.ActiveCfg = Debug|x64 - {A1A295E5-463C-437F-81CA-1F32367685DA}.Debug|x64.Build.0 = Debug|x64 - {A1A295E5-463C-437F-81CA-1F32367685DA}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM - {A1A295E5-463C-437F-81CA-1F32367685DA}.PGInstrument|ARM.Build.0 = PGInstrument|ARM - {A1A295E5-463C-437F-81CA-1F32367685DA}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 - {A1A295E5-463C-437F-81CA-1F32367685DA}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 - {A1A295E5-463C-437F-81CA-1F32367685DA}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {A1A295E5-463C-437F-81CA-1F32367685DA}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {A1A295E5-463C-437F-81CA-1F32367685DA}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {A1A295E5-463C-437F-81CA-1F32367685DA}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {A1A295E5-463C-437F-81CA-1F32367685DA}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM - {A1A295E5-463C-437F-81CA-1F32367685DA}.PGUpdate|ARM.Build.0 = PGUpdate|ARM - {A1A295E5-463C-437F-81CA-1F32367685DA}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 - {A1A295E5-463C-437F-81CA-1F32367685DA}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 - {A1A295E5-463C-437F-81CA-1F32367685DA}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {A1A295E5-463C-437F-81CA-1F32367685DA}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {A1A295E5-463C-437F-81CA-1F32367685DA}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {A1A295E5-463C-437F-81CA-1F32367685DA}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {A1A295E5-463C-437F-81CA-1F32367685DA}.Release|ARM.ActiveCfg = Release|ARM - {A1A295E5-463C-437F-81CA-1F32367685DA}.Release|ARM.Build.0 = Release|ARM - {A1A295E5-463C-437F-81CA-1F32367685DA}.Release|ARM64.ActiveCfg = Release|ARM64 - {A1A295E5-463C-437F-81CA-1F32367685DA}.Release|ARM64.Build.0 = Release|ARM64 - {A1A295E5-463C-437F-81CA-1F32367685DA}.Release|Win32.ActiveCfg = Release|Win32 - {A1A295E5-463C-437F-81CA-1F32367685DA}.Release|Win32.Build.0 = Release|Win32 - {A1A295E5-463C-437F-81CA-1F32367685DA}.Release|x64.ActiveCfg = Release|x64 - {A1A295E5-463C-437F-81CA-1F32367685DA}.Release|x64.Build.0 = Release|x64 - {9E48B300-37D1-11DD-8C41-005056C00008}.Debug|ARM.ActiveCfg = Debug|ARM - {9E48B300-37D1-11DD-8C41-005056C00008}.Debug|ARM.Build.0 = Debug|ARM - {9E48B300-37D1-11DD-8C41-005056C00008}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {9E48B300-37D1-11DD-8C41-005056C00008}.Debug|ARM64.Build.0 = Debug|ARM64 - {9E48B300-37D1-11DD-8C41-005056C00008}.Debug|Win32.ActiveCfg = Debug|Win32 - {9E48B300-37D1-11DD-8C41-005056C00008}.Debug|Win32.Build.0 = Debug|Win32 - {9E48B300-37D1-11DD-8C41-005056C00008}.Debug|x64.ActiveCfg = Debug|x64 - {9E48B300-37D1-11DD-8C41-005056C00008}.Debug|x64.Build.0 = Debug|x64 - {9E48B300-37D1-11DD-8C41-005056C00008}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM - {9E48B300-37D1-11DD-8C41-005056C00008}.PGInstrument|ARM.Build.0 = PGInstrument|ARM - {9E48B300-37D1-11DD-8C41-005056C00008}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 - {9E48B300-37D1-11DD-8C41-005056C00008}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 - {9E48B300-37D1-11DD-8C41-005056C00008}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {9E48B300-37D1-11DD-8C41-005056C00008}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {9E48B300-37D1-11DD-8C41-005056C00008}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {9E48B300-37D1-11DD-8C41-005056C00008}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {9E48B300-37D1-11DD-8C41-005056C00008}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM - {9E48B300-37D1-11DD-8C41-005056C00008}.PGUpdate|ARM.Build.0 = PGUpdate|ARM - {9E48B300-37D1-11DD-8C41-005056C00008}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 - {9E48B300-37D1-11DD-8C41-005056C00008}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 - {9E48B300-37D1-11DD-8C41-005056C00008}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {9E48B300-37D1-11DD-8C41-005056C00008}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {9E48B300-37D1-11DD-8C41-005056C00008}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {9E48B300-37D1-11DD-8C41-005056C00008}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {9E48B300-37D1-11DD-8C41-005056C00008}.Release|ARM.ActiveCfg = Release|ARM - {9E48B300-37D1-11DD-8C41-005056C00008}.Release|ARM.Build.0 = Release|ARM - {9E48B300-37D1-11DD-8C41-005056C00008}.Release|ARM64.ActiveCfg = Release|ARM64 - {9E48B300-37D1-11DD-8C41-005056C00008}.Release|ARM64.Build.0 = Release|ARM64 - {9E48B300-37D1-11DD-8C41-005056C00008}.Release|Win32.ActiveCfg = Release|Win32 - {9E48B300-37D1-11DD-8C41-005056C00008}.Release|Win32.Build.0 = Release|Win32 - {9E48B300-37D1-11DD-8C41-005056C00008}.Release|x64.ActiveCfg = Release|x64 - {9E48B300-37D1-11DD-8C41-005056C00008}.Release|x64.Build.0 = Release|x64 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Debug|ARM.ActiveCfg = Debug|ARM - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Debug|ARM.Build.0 = Debug|ARM - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Debug|ARM64.Build.0 = Debug|ARM64 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Debug|Win32.ActiveCfg = Debug|Win32 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Debug|Win32.Build.0 = Debug|Win32 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Debug|x64.ActiveCfg = Debug|x64 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Debug|x64.Build.0 = Debug|x64 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|ARM.Build.0 = PGInstrument|ARM - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|Win32.ActiveCfg = Debug|Win32 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|Win32.Build.0 = Debug|Win32 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|x64.ActiveCfg = Debug|x64 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|x64.Build.0 = Debug|x64 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|ARM.Build.0 = PGUpdate|ARM - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|Win32.ActiveCfg = Debug|Win32 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|Win32.Build.0 = Debug|Win32 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|x64.ActiveCfg = Debug|x64 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|x64.Build.0 = Debug|x64 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Release|ARM.ActiveCfg = Release|ARM - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Release|ARM.Build.0 = Release|ARM - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Release|ARM64.ActiveCfg = Release|ARM64 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Release|ARM64.Build.0 = Release|ARM64 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Release|Win32.ActiveCfg = Release|Win32 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Release|Win32.Build.0 = Release|Win32 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Release|x64.ActiveCfg = Release|x64 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Release|x64.Build.0 = Release|x64 - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.Debug|ARM.ActiveCfg = Debug|ARM - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.Debug|Win32.ActiveCfg = Release|Win32 - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.Debug|x64.ActiveCfg = Release|x64 - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGInstrument|ARM.Build.0 = PGInstrument|ARM - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGUpdate|ARM.Build.0 = PGUpdate|ARM - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGUpdate|x64.ActiveCfg = Release|x64 - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGUpdate|x64.Build.0 = Release|x64 - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.Release|ARM.ActiveCfg = Release|ARM - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.Release|ARM64.ActiveCfg = Release|ARM64 - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.Release|Win32.ActiveCfg = Release|Win32 - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.Release|Win32.Build.0 = Release|Win32 - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.Release|x64.ActiveCfg = Release|x64 - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.Release|x64.Build.0 = Release|x64 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Debug|ARM.ActiveCfg = Debug|ARM - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Debug|ARM.Build.0 = Debug|ARM - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Debug|ARM64.Build.0 = Debug|ARM64 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Debug|Win32.ActiveCfg = Debug|Win32 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Debug|Win32.Build.0 = Debug|Win32 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Debug|x64.ActiveCfg = Debug|x64 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Debug|x64.Build.0 = Debug|x64 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGInstrument|ARM.Build.0 = PGInstrument|ARM - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGInstrument|Win32.ActiveCfg = Release|Win32 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGInstrument|Win32.Build.0 = Release|Win32 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGInstrument|x64.ActiveCfg = Release|x64 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGInstrument|x64.Build.0 = Release|x64 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGUpdate|ARM.Build.0 = PGUpdate|ARM - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGUpdate|Win32.ActiveCfg = Release|Win32 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGUpdate|Win32.Build.0 = Release|Win32 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGUpdate|x64.ActiveCfg = Release|x64 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGUpdate|x64.Build.0 = Release|x64 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Release|ARM.ActiveCfg = Release|ARM - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Release|ARM.Build.0 = Release|ARM - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Release|ARM64.ActiveCfg = Release|ARM64 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Release|ARM64.Build.0 = Release|ARM64 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Release|Win32.ActiveCfg = Release|Win32 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Release|Win32.Build.0 = Release|Win32 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Release|x64.ActiveCfg = Release|x64 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Release|x64.Build.0 = Release|x64 - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Debug|ARM.ActiveCfg = Debug|ARM - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Debug|ARM.Build.0 = Debug|ARM - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Debug|ARM64.Build.0 = Debug|ARM64 - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Debug|Win32.ActiveCfg = Debug|Win32 - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Debug|Win32.Build.0 = Debug|Win32 - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Debug|x64.ActiveCfg = Debug|x64 - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Debug|x64.Build.0 = Debug|x64 - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGInstrument|ARM.Build.0 = PGInstrument|ARM - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGInstrument|Win32.ActiveCfg = Release|Win32 - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGInstrument|Win32.Build.0 = Release|Win32 - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGInstrument|x64.ActiveCfg = Release|x64 - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGInstrument|x64.Build.0 = Release|x64 - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGUpdate|ARM.Build.0 = PGUpdate|ARM - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGUpdate|Win32.ActiveCfg = Release|Win32 - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGUpdate|Win32.Build.0 = Release|Win32 - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGUpdate|x64.ActiveCfg = Release|x64 - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGUpdate|x64.Build.0 = Release|x64 - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Release|ARM.ActiveCfg = Release|ARM - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Release|ARM.Build.0 = Release|ARM - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Release|ARM64.ActiveCfg = Release|ARM64 - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Release|ARM64.Build.0 = Release|ARM64 - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Release|Win32.ActiveCfg = Release|Win32 - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Release|Win32.Build.0 = Release|Win32 - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Release|x64.ActiveCfg = Release|x64 - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Release|x64.Build.0 = Release|x64 - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Debug|ARM.ActiveCfg = Debug|ARM - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Debug|ARM.Build.0 = Debug|ARM - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Debug|ARM64.Build.0 = Debug|ARM64 - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Debug|Win32.ActiveCfg = Debug|Win32 - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Debug|Win32.Build.0 = Debug|Win32 - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Debug|x64.ActiveCfg = Debug|x64 - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Debug|x64.Build.0 = Debug|x64 - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGInstrument|ARM.Build.0 = PGInstrument|ARM - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGInstrument|Win32.ActiveCfg = Release|Win32 - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGInstrument|Win32.Build.0 = Release|Win32 - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGInstrument|x64.ActiveCfg = Release|x64 - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGInstrument|x64.Build.0 = Release|x64 - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGUpdate|ARM.Build.0 = PGUpdate|ARM - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGUpdate|Win32.ActiveCfg = Release|Win32 - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGUpdate|Win32.Build.0 = Release|Win32 - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGUpdate|x64.ActiveCfg = Release|x64 - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGUpdate|x64.Build.0 = Release|x64 - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Release|ARM.ActiveCfg = Release|ARM - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Release|ARM.Build.0 = Release|ARM - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Release|ARM64.ActiveCfg = Release|ARM64 - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Release|ARM64.Build.0 = Release|ARM64 - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Release|Win32.ActiveCfg = Release|Win32 - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Release|Win32.Build.0 = Release|Win32 - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Release|x64.ActiveCfg = Release|x64 - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Release|x64.Build.0 = Release|x64 - {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Debug|ARM.ActiveCfg = Debug|Win32 - {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Debug|ARM.Build.0 = Debug|Win32 - {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Debug|ARM64.ActiveCfg = Debug|x64 - {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Debug|ARM64.Build.0 = Debug|x64 - {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Debug|Win32.ActiveCfg = Debug|Win32 - {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Debug|Win32.Build.0 = Debug|Win32 - {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Debug|x64.ActiveCfg = Debug|x64 - {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Debug|x64.Build.0 = Debug|x64 - {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.PGInstrument|ARM.ActiveCfg = Release|Win32 - {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.PGInstrument|ARM.Build.0 = Release|Win32 - {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.PGInstrument|ARM64.ActiveCfg = Release|x64 - {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.PGInstrument|ARM64.Build.0 = Release|x64 - {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.PGInstrument|Win32.ActiveCfg = Release|Win32 - {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.PGInstrument|Win32.Build.0 = Release|Win32 - {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.PGInstrument|x64.ActiveCfg = Release|x64 - {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.PGInstrument|x64.Build.0 = Release|x64 - {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.PGUpdate|ARM.ActiveCfg = Release|Win32 - {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.PGUpdate|ARM64.ActiveCfg = Release|x64 - {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.PGUpdate|Win32.ActiveCfg = Release|Win32 - {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.PGUpdate|x64.ActiveCfg = Release|x64 - {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Release|ARM.ActiveCfg = Release|Win32 - {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Release|ARM.Build.0 = Release|Win32 - {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Release|ARM64.ActiveCfg = Release|x64 - {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Release|ARM64.Build.0 = Release|x64 - {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Release|Win32.ActiveCfg = Release|Win32 - {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Release|Win32.Build.0 = Release|Win32 - {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Release|x64.ActiveCfg = Release|x64 - {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Release|x64.Build.0 = Release|x64 - {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.Debug|ARM.ActiveCfg = Debug|ARM - {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.Debug|ARM.Build.0 = Debug|ARM - {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.Debug|ARM64.Build.0 = Debug|ARM64 - {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.Debug|Win32.ActiveCfg = Debug|Win32 - {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.Debug|Win32.Build.0 = Debug|Win32 - {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.Debug|x64.ActiveCfg = Debug|x64 - {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.Debug|x64.Build.0 = Debug|x64 - {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM - {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.PGInstrument|ARM.Build.0 = PGInstrument|ARM - {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 - {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 - {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM - {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.PGUpdate|ARM.Build.0 = PGUpdate|ARM - {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 - {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 - {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.Release|ARM.ActiveCfg = Release|ARM - {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.Release|ARM.Build.0 = Release|ARM - {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.Release|ARM64.ActiveCfg = Release|ARM64 - {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.Release|ARM64.Build.0 = Release|ARM64 - {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.Release|Win32.ActiveCfg = Release|Win32 - {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.Release|Win32.Build.0 = Release|Win32 - {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.Release|x64.ActiveCfg = Release|x64 - {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.Release|x64.Build.0 = Release|x64 - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Debug|ARM.ActiveCfg = Debug|ARM - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Debug|ARM.Build.0 = Debug|ARM - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Debug|ARM64.Build.0 = Debug|ARM64 - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Debug|Win32.ActiveCfg = Debug|Win32 - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Debug|Win32.Build.0 = Debug|Win32 - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Debug|x64.ActiveCfg = Debug|x64 - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Debug|x64.Build.0 = Debug|x64 - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.PGInstrument|ARM.Build.0 = PGInstrument|ARM - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.PGInstrument|Win32.ActiveCfg = Release|Win32 - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.PGInstrument|x64.ActiveCfg = Release|x64 - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.PGUpdate|ARM.Build.0 = PGUpdate|ARM - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.PGUpdate|Win32.ActiveCfg = Release|Win32 - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.PGUpdate|Win32.Build.0 = Release|Win32 - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.PGUpdate|x64.ActiveCfg = Release|x64 - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.PGUpdate|x64.Build.0 = Release|x64 - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Release|ARM.ActiveCfg = Release|ARM - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Release|ARM.Build.0 = Release|ARM - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Release|ARM64.ActiveCfg = Release|ARM64 - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Release|ARM64.Build.0 = Release|ARM64 - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Release|Win32.ActiveCfg = Release|Win32 - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Release|Win32.Build.0 = Release|Win32 - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Release|x64.ActiveCfg = Release|x64 - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Release|x64.Build.0 = Release|x64 - {16BFE6F0-22EF-40B5-B831-7E937119EF10}.Debug|ARM.ActiveCfg = Debug|ARM - {16BFE6F0-22EF-40B5-B831-7E937119EF10}.Debug|ARM.Build.0 = Debug|ARM - {16BFE6F0-22EF-40B5-B831-7E937119EF10}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {16BFE6F0-22EF-40B5-B831-7E937119EF10}.Debug|ARM64.Build.0 = Debug|ARM64 - {16BFE6F0-22EF-40B5-B831-7E937119EF10}.Debug|Win32.ActiveCfg = Debug|Win32 - {16BFE6F0-22EF-40B5-B831-7E937119EF10}.Debug|Win32.Build.0 = Debug|Win32 - {16BFE6F0-22EF-40B5-B831-7E937119EF10}.Debug|x64.ActiveCfg = Debug|x64 - {16BFE6F0-22EF-40B5-B831-7E937119EF10}.Debug|x64.Build.0 = Debug|x64 - {16BFE6F0-22EF-40B5-B831-7E937119EF10}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM - {16BFE6F0-22EF-40B5-B831-7E937119EF10}.PGInstrument|ARM.Build.0 = PGInstrument|ARM - {16BFE6F0-22EF-40B5-B831-7E937119EF10}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 - {16BFE6F0-22EF-40B5-B831-7E937119EF10}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 - {16BFE6F0-22EF-40B5-B831-7E937119EF10}.PGInstrument|Win32.ActiveCfg = Release|Win32 - {16BFE6F0-22EF-40B5-B831-7E937119EF10}.PGInstrument|x64.ActiveCfg = Release|x64 - {16BFE6F0-22EF-40B5-B831-7E937119EF10}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM - {16BFE6F0-22EF-40B5-B831-7E937119EF10}.PGUpdate|ARM.Build.0 = PGUpdate|ARM - {16BFE6F0-22EF-40B5-B831-7E937119EF10}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 - {16BFE6F0-22EF-40B5-B831-7E937119EF10}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 - {16BFE6F0-22EF-40B5-B831-7E937119EF10}.PGUpdate|Win32.ActiveCfg = Release|Win32 - {16BFE6F0-22EF-40B5-B831-7E937119EF10}.PGUpdate|Win32.Build.0 = Release|Win32 - {16BFE6F0-22EF-40B5-B831-7E937119EF10}.PGUpdate|x64.ActiveCfg = Release|x64 - {16BFE6F0-22EF-40B5-B831-7E937119EF10}.PGUpdate|x64.Build.0 = Release|x64 - {16BFE6F0-22EF-40B5-B831-7E937119EF10}.Release|ARM.ActiveCfg = Release|ARM - {16BFE6F0-22EF-40B5-B831-7E937119EF10}.Release|ARM.Build.0 = Release|ARM - {16BFE6F0-22EF-40B5-B831-7E937119EF10}.Release|ARM64.ActiveCfg = Release|ARM64 - {16BFE6F0-22EF-40B5-B831-7E937119EF10}.Release|ARM64.Build.0 = Release|ARM64 - {16BFE6F0-22EF-40B5-B831-7E937119EF10}.Release|Win32.ActiveCfg = Release|Win32 - {16BFE6F0-22EF-40B5-B831-7E937119EF10}.Release|Win32.Build.0 = Release|Win32 - {16BFE6F0-22EF-40B5-B831-7E937119EF10}.Release|x64.ActiveCfg = Release|x64 - {16BFE6F0-22EF-40B5-B831-7E937119EF10}.Release|x64.Build.0 = Release|x64 - {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Debug|ARM.ActiveCfg = Debug|ARM - {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Debug|ARM.Build.0 = Debug|ARM - {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Debug|ARM64.Build.0 = Debug|ARM64 - {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Debug|Win32.ActiveCfg = Debug|Win32 - {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Debug|Win32.Build.0 = Debug|Win32 - {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Debug|x64.ActiveCfg = Debug|x64 - {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Debug|x64.Build.0 = Debug|x64 - {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM - {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGInstrument|ARM.Build.0 = PGInstrument|ARM - {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 - {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 - {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM - {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGUpdate|ARM.Build.0 = PGUpdate|ARM - {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 - {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 - {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Release|ARM.ActiveCfg = Release|ARM - {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Release|ARM.Build.0 = Release|ARM - {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Release|ARM64.ActiveCfg = Release|ARM64 - {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Release|ARM64.Build.0 = Release|ARM64 - {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Release|Win32.ActiveCfg = Release|Win32 - {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Release|Win32.Build.0 = Release|Win32 - {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Release|x64.ActiveCfg = Release|x64 - {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Release|x64.Build.0 = Release|x64 - {B244E787-C445-441C-BDF4-5A4F1A3A1E51}.Debug|ARM.ActiveCfg = Debug|ARM - {B244E787-C445-441C-BDF4-5A4F1A3A1E51}.Debug|ARM.Build.0 = Debug|ARM - {B244E787-C445-441C-BDF4-5A4F1A3A1E51}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {B244E787-C445-441C-BDF4-5A4F1A3A1E51}.Debug|ARM64.Build.0 = Debug|ARM64 - {B244E787-C445-441C-BDF4-5A4F1A3A1E51}.Debug|Win32.ActiveCfg = Debug|Win32 - {B244E787-C445-441C-BDF4-5A4F1A3A1E51}.Debug|Win32.Build.0 = Debug|Win32 - {B244E787-C445-441C-BDF4-5A4F1A3A1E51}.Debug|x64.ActiveCfg = Debug|x64 - {B244E787-C445-441C-BDF4-5A4F1A3A1E51}.Debug|x64.Build.0 = Debug|x64 - {B244E787-C445-441C-BDF4-5A4F1A3A1E51}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM - {B244E787-C445-441C-BDF4-5A4F1A3A1E51}.PGInstrument|ARM.Build.0 = PGInstrument|ARM - {B244E787-C445-441C-BDF4-5A4F1A3A1E51}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 - {B244E787-C445-441C-BDF4-5A4F1A3A1E51}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 - {B244E787-C445-441C-BDF4-5A4F1A3A1E51}.PGInstrument|Win32.ActiveCfg = Release|Win32 - {B244E787-C445-441C-BDF4-5A4F1A3A1E51}.PGInstrument|Win32.Build.0 = Release|Win32 - {B244E787-C445-441C-BDF4-5A4F1A3A1E51}.PGInstrument|x64.ActiveCfg = Release|x64 - {B244E787-C445-441C-BDF4-5A4F1A3A1E51}.PGInstrument|x64.Build.0 = Release|x64 - {B244E787-C445-441C-BDF4-5A4F1A3A1E51}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM - {B244E787-C445-441C-BDF4-5A4F1A3A1E51}.PGUpdate|ARM.Build.0 = PGUpdate|ARM - {B244E787-C445-441C-BDF4-5A4F1A3A1E51}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 - {B244E787-C445-441C-BDF4-5A4F1A3A1E51}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 - {B244E787-C445-441C-BDF4-5A4F1A3A1E51}.PGUpdate|Win32.ActiveCfg = Release|Win32 - {B244E787-C445-441C-BDF4-5A4F1A3A1E51}.PGUpdate|Win32.Build.0 = Release|Win32 - {B244E787-C445-441C-BDF4-5A4F1A3A1E51}.PGUpdate|x64.ActiveCfg = Release|x64 - {B244E787-C445-441C-BDF4-5A4F1A3A1E51}.PGUpdate|x64.Build.0 = Release|x64 - {B244E787-C445-441C-BDF4-5A4F1A3A1E51}.Release|ARM.ActiveCfg = Release|ARM - {B244E787-C445-441C-BDF4-5A4F1A3A1E51}.Release|ARM.Build.0 = Release|ARM - {B244E787-C445-441C-BDF4-5A4F1A3A1E51}.Release|ARM64.ActiveCfg = Release|ARM64 - {B244E787-C445-441C-BDF4-5A4F1A3A1E51}.Release|ARM64.Build.0 = Release|ARM64 - {B244E787-C445-441C-BDF4-5A4F1A3A1E51}.Release|Win32.ActiveCfg = Release|Win32 - {B244E787-C445-441C-BDF4-5A4F1A3A1E51}.Release|Win32.Build.0 = Release|Win32 - {B244E787-C445-441C-BDF4-5A4F1A3A1E51}.Release|x64.ActiveCfg = Release|x64 - {B244E787-C445-441C-BDF4-5A4F1A3A1E51}.Release|x64.Build.0 = Release|x64 - {384C224A-7474-476E-A01B-750EA7DE918C}.Debug|ARM.ActiveCfg = Debug|ARM - {384C224A-7474-476E-A01B-750EA7DE918C}.Debug|ARM.Build.0 = Debug|ARM - {384C224A-7474-476E-A01B-750EA7DE918C}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {384C224A-7474-476E-A01B-750EA7DE918C}.Debug|ARM64.Build.0 = Debug|ARM64 - {384C224A-7474-476E-A01B-750EA7DE918C}.Debug|Win32.ActiveCfg = Debug|Win32 - {384C224A-7474-476E-A01B-750EA7DE918C}.Debug|Win32.Build.0 = Debug|Win32 - {384C224A-7474-476E-A01B-750EA7DE918C}.Debug|x64.ActiveCfg = Debug|x64 - {384C224A-7474-476E-A01B-750EA7DE918C}.Debug|x64.Build.0 = Debug|x64 - {384C224A-7474-476E-A01B-750EA7DE918C}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM - {384C224A-7474-476E-A01B-750EA7DE918C}.PGInstrument|ARM.Build.0 = PGInstrument|ARM - {384C224A-7474-476E-A01B-750EA7DE918C}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 - {384C224A-7474-476E-A01B-750EA7DE918C}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 - {384C224A-7474-476E-A01B-750EA7DE918C}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {384C224A-7474-476E-A01B-750EA7DE918C}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {384C224A-7474-476E-A01B-750EA7DE918C}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {384C224A-7474-476E-A01B-750EA7DE918C}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {384C224A-7474-476E-A01B-750EA7DE918C}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM - {384C224A-7474-476E-A01B-750EA7DE918C}.PGUpdate|ARM.Build.0 = PGUpdate|ARM - {384C224A-7474-476E-A01B-750EA7DE918C}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 - {384C224A-7474-476E-A01B-750EA7DE918C}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 - {384C224A-7474-476E-A01B-750EA7DE918C}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {384C224A-7474-476E-A01B-750EA7DE918C}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {384C224A-7474-476E-A01B-750EA7DE918C}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {384C224A-7474-476E-A01B-750EA7DE918C}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {384C224A-7474-476E-A01B-750EA7DE918C}.Release|ARM.ActiveCfg = Release|ARM - {384C224A-7474-476E-A01B-750EA7DE918C}.Release|ARM.Build.0 = Release|ARM - {384C224A-7474-476E-A01B-750EA7DE918C}.Release|ARM64.ActiveCfg = Release|ARM64 - {384C224A-7474-476E-A01B-750EA7DE918C}.Release|ARM64.Build.0 = Release|ARM64 - {384C224A-7474-476E-A01B-750EA7DE918C}.Release|Win32.ActiveCfg = Release|Win32 - {384C224A-7474-476E-A01B-750EA7DE918C}.Release|Win32.Build.0 = Release|Win32 - {384C224A-7474-476E-A01B-750EA7DE918C}.Release|x64.ActiveCfg = Release|x64 - {384C224A-7474-476E-A01B-750EA7DE918C}.Release|x64.Build.0 = Release|x64 - {FCBE1EF2-E0F0-40B1-88B5-00A35D378742}.Debug|ARM.ActiveCfg = Debug|ARM - {FCBE1EF2-E0F0-40B1-88B5-00A35D378742}.Debug|ARM.Build.0 = Debug|ARM - {FCBE1EF2-E0F0-40B1-88B5-00A35D378742}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {FCBE1EF2-E0F0-40B1-88B5-00A35D378742}.Debug|ARM64.Build.0 = Debug|ARM64 - {FCBE1EF2-E0F0-40B1-88B5-00A35D378742}.Debug|Win32.ActiveCfg = Debug|Win32 - {FCBE1EF2-E0F0-40B1-88B5-00A35D378742}.Debug|Win32.Build.0 = Debug|Win32 - {FCBE1EF2-E0F0-40B1-88B5-00A35D378742}.Debug|x64.ActiveCfg = Debug|x64 - {FCBE1EF2-E0F0-40B1-88B5-00A35D378742}.Debug|x64.Build.0 = Debug|x64 - {FCBE1EF2-E0F0-40B1-88B5-00A35D378742}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM - {FCBE1EF2-E0F0-40B1-88B5-00A35D378742}.PGInstrument|ARM.Build.0 = PGInstrument|ARM - {FCBE1EF2-E0F0-40B1-88B5-00A35D378742}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 - {FCBE1EF2-E0F0-40B1-88B5-00A35D378742}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 - {FCBE1EF2-E0F0-40B1-88B5-00A35D378742}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {FCBE1EF2-E0F0-40B1-88B5-00A35D378742}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {FCBE1EF2-E0F0-40B1-88B5-00A35D378742}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {FCBE1EF2-E0F0-40B1-88B5-00A35D378742}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {FCBE1EF2-E0F0-40B1-88B5-00A35D378742}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM - {FCBE1EF2-E0F0-40B1-88B5-00A35D378742}.PGUpdate|ARM.Build.0 = PGUpdate|ARM - {FCBE1EF2-E0F0-40B1-88B5-00A35D378742}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 - {FCBE1EF2-E0F0-40B1-88B5-00A35D378742}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 - {FCBE1EF2-E0F0-40B1-88B5-00A35D378742}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {FCBE1EF2-E0F0-40B1-88B5-00A35D378742}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {FCBE1EF2-E0F0-40B1-88B5-00A35D378742}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {FCBE1EF2-E0F0-40B1-88B5-00A35D378742}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {FCBE1EF2-E0F0-40B1-88B5-00A35D378742}.Release|ARM.ActiveCfg = Release|ARM - {FCBE1EF2-E0F0-40B1-88B5-00A35D378742}.Release|ARM.Build.0 = Release|ARM - {FCBE1EF2-E0F0-40B1-88B5-00A35D378742}.Release|ARM64.ActiveCfg = Release|ARM64 - {FCBE1EF2-E0F0-40B1-88B5-00A35D378742}.Release|ARM64.Build.0 = Release|ARM64 - {FCBE1EF2-E0F0-40B1-88B5-00A35D378742}.Release|Win32.ActiveCfg = Release|Win32 - {FCBE1EF2-E0F0-40B1-88B5-00A35D378742}.Release|Win32.Build.0 = Release|Win32 - {FCBE1EF2-E0F0-40B1-88B5-00A35D378742}.Release|x64.ActiveCfg = Release|x64 - {FCBE1EF2-E0F0-40B1-88B5-00A35D378742}.Release|x64.Build.0 = Release|x64 - {78D80A15-BD8C-44E2-B49E-1F05B0A0A687}.Debug|ARM.ActiveCfg = Debug|ARM - {78D80A15-BD8C-44E2-B49E-1F05B0A0A687}.Debug|ARM.Build.0 = Debug|ARM - {78D80A15-BD8C-44E2-B49E-1F05B0A0A687}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {78D80A15-BD8C-44E2-B49E-1F05B0A0A687}.Debug|ARM64.Build.0 = Debug|ARM64 - {78D80A15-BD8C-44E2-B49E-1F05B0A0A687}.Debug|Win32.ActiveCfg = Debug|Win32 - {78D80A15-BD8C-44E2-B49E-1F05B0A0A687}.Debug|Win32.Build.0 = Debug|Win32 - {78D80A15-BD8C-44E2-B49E-1F05B0A0A687}.Debug|x64.ActiveCfg = Debug|x64 - {78D80A15-BD8C-44E2-B49E-1F05B0A0A687}.Debug|x64.Build.0 = Debug|x64 - {78D80A15-BD8C-44E2-B49E-1F05B0A0A687}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM - {78D80A15-BD8C-44E2-B49E-1F05B0A0A687}.PGInstrument|ARM.Build.0 = PGInstrument|ARM - {78D80A15-BD8C-44E2-B49E-1F05B0A0A687}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 - {78D80A15-BD8C-44E2-B49E-1F05B0A0A687}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 - {78D80A15-BD8C-44E2-B49E-1F05B0A0A687}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {78D80A15-BD8C-44E2-B49E-1F05B0A0A687}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {78D80A15-BD8C-44E2-B49E-1F05B0A0A687}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {78D80A15-BD8C-44E2-B49E-1F05B0A0A687}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {78D80A15-BD8C-44E2-B49E-1F05B0A0A687}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM - {78D80A15-BD8C-44E2-B49E-1F05B0A0A687}.PGUpdate|ARM.Build.0 = PGUpdate|ARM - {78D80A15-BD8C-44E2-B49E-1F05B0A0A687}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 - {78D80A15-BD8C-44E2-B49E-1F05B0A0A687}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 - {78D80A15-BD8C-44E2-B49E-1F05B0A0A687}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {78D80A15-BD8C-44E2-B49E-1F05B0A0A687}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {78D80A15-BD8C-44E2-B49E-1F05B0A0A687}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {78D80A15-BD8C-44E2-B49E-1F05B0A0A687}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {78D80A15-BD8C-44E2-B49E-1F05B0A0A687}.Release|ARM.ActiveCfg = Release|ARM - {78D80A15-BD8C-44E2-B49E-1F05B0A0A687}.Release|ARM.Build.0 = Release|ARM - {78D80A15-BD8C-44E2-B49E-1F05B0A0A687}.Release|ARM64.ActiveCfg = Release|ARM64 - {78D80A15-BD8C-44E2-B49E-1F05B0A0A687}.Release|ARM64.Build.0 = Release|ARM64 - {78D80A15-BD8C-44E2-B49E-1F05B0A0A687}.Release|Win32.ActiveCfg = Release|Win32 - {78D80A15-BD8C-44E2-B49E-1F05B0A0A687}.Release|Win32.Build.0 = Release|Win32 - {78D80A15-BD8C-44E2-B49E-1F05B0A0A687}.Release|x64.ActiveCfg = Release|x64 - {78D80A15-BD8C-44E2-B49E-1F05B0A0A687}.Release|x64.Build.0 = Release|x64 - {12728250-16EC-4DC6-94D7-E21DD88947F8}.Debug|ARM.ActiveCfg = Debug|ARM - {12728250-16EC-4DC6-94D7-E21DD88947F8}.Debug|ARM.Build.0 = Debug|ARM - {12728250-16EC-4DC6-94D7-E21DD88947F8}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {12728250-16EC-4DC6-94D7-E21DD88947F8}.Debug|ARM64.Build.0 = Debug|ARM64 - {12728250-16EC-4DC6-94D7-E21DD88947F8}.Debug|Win32.ActiveCfg = Debug|Win32 - {12728250-16EC-4DC6-94D7-E21DD88947F8}.Debug|Win32.Build.0 = Debug|Win32 - {12728250-16EC-4DC6-94D7-E21DD88947F8}.Debug|x64.ActiveCfg = Debug|x64 - {12728250-16EC-4DC6-94D7-E21DD88947F8}.Debug|x64.Build.0 = Debug|x64 - {12728250-16EC-4DC6-94D7-E21DD88947F8}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM - {12728250-16EC-4DC6-94D7-E21DD88947F8}.PGInstrument|ARM.Build.0 = PGInstrument|ARM - {12728250-16EC-4DC6-94D7-E21DD88947F8}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 - {12728250-16EC-4DC6-94D7-E21DD88947F8}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 - {12728250-16EC-4DC6-94D7-E21DD88947F8}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {12728250-16EC-4DC6-94D7-E21DD88947F8}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {12728250-16EC-4DC6-94D7-E21DD88947F8}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {12728250-16EC-4DC6-94D7-E21DD88947F8}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {12728250-16EC-4DC6-94D7-E21DD88947F8}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM - {12728250-16EC-4DC6-94D7-E21DD88947F8}.PGUpdate|ARM.Build.0 = PGUpdate|ARM - {12728250-16EC-4DC6-94D7-E21DD88947F8}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 - {12728250-16EC-4DC6-94D7-E21DD88947F8}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 - {12728250-16EC-4DC6-94D7-E21DD88947F8}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {12728250-16EC-4DC6-94D7-E21DD88947F8}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {12728250-16EC-4DC6-94D7-E21DD88947F8}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {12728250-16EC-4DC6-94D7-E21DD88947F8}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {12728250-16EC-4DC6-94D7-E21DD88947F8}.Release|ARM.ActiveCfg = Release|ARM - {12728250-16EC-4DC6-94D7-E21DD88947F8}.Release|ARM.Build.0 = Release|ARM - {12728250-16EC-4DC6-94D7-E21DD88947F8}.Release|ARM64.ActiveCfg = Release|ARM64 - {12728250-16EC-4DC6-94D7-E21DD88947F8}.Release|ARM64.Build.0 = Release|ARM64 - {12728250-16EC-4DC6-94D7-E21DD88947F8}.Release|Win32.ActiveCfg = Release|Win32 - {12728250-16EC-4DC6-94D7-E21DD88947F8}.Release|Win32.Build.0 = Release|Win32 - {12728250-16EC-4DC6-94D7-E21DD88947F8}.Release|x64.ActiveCfg = Release|x64 - {12728250-16EC-4DC6-94D7-E21DD88947F8}.Release|x64.Build.0 = Release|x64 - {9DE9E23D-C8D4-4817-92A9-920A8B1FE5FF}.Debug|ARM.ActiveCfg = Debug|Win32 - {9DE9E23D-C8D4-4817-92A9-920A8B1FE5FF}.Debug|ARM64.ActiveCfg = Debug|Win32 - {9DE9E23D-C8D4-4817-92A9-920A8B1FE5FF}.Debug|Win32.ActiveCfg = Debug|Win32 - {9DE9E23D-C8D4-4817-92A9-920A8B1FE5FF}.Debug|Win32.Build.0 = Debug|Win32 - {9DE9E23D-C8D4-4817-92A9-920A8B1FE5FF}.Debug|x64.ActiveCfg = Debug|x64 - {9DE9E23D-C8D4-4817-92A9-920A8B1FE5FF}.Debug|x64.Build.0 = Debug|x64 - {9DE9E23D-C8D4-4817-92A9-920A8B1FE5FF}.PGInstrument|ARM.ActiveCfg = PGInstrument|Win32 - {9DE9E23D-C8D4-4817-92A9-920A8B1FE5FF}.PGInstrument|ARM64.ActiveCfg = PGInstrument|Win32 - {9DE9E23D-C8D4-4817-92A9-920A8B1FE5FF}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {9DE9E23D-C8D4-4817-92A9-920A8B1FE5FF}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {9DE9E23D-C8D4-4817-92A9-920A8B1FE5FF}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {9DE9E23D-C8D4-4817-92A9-920A8B1FE5FF}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {9DE9E23D-C8D4-4817-92A9-920A8B1FE5FF}.PGUpdate|ARM.ActiveCfg = PGUpdate|Win32 - {9DE9E23D-C8D4-4817-92A9-920A8B1FE5FF}.PGUpdate|ARM64.ActiveCfg = PGUpdate|Win32 - {9DE9E23D-C8D4-4817-92A9-920A8B1FE5FF}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {9DE9E23D-C8D4-4817-92A9-920A8B1FE5FF}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {9DE9E23D-C8D4-4817-92A9-920A8B1FE5FF}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {9DE9E23D-C8D4-4817-92A9-920A8B1FE5FF}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {9DE9E23D-C8D4-4817-92A9-920A8B1FE5FF}.Release|ARM.ActiveCfg = Release|Win32 - {9DE9E23D-C8D4-4817-92A9-920A8B1FE5FF}.Release|ARM64.ActiveCfg = Release|Win32 - {9DE9E23D-C8D4-4817-92A9-920A8B1FE5FF}.Release|Win32.ActiveCfg = Release|Win32 - {9DE9E23D-C8D4-4817-92A9-920A8B1FE5FF}.Release|Win32.Build.0 = Release|Win32 - {9DE9E23D-C8D4-4817-92A9-920A8B1FE5FF}.Release|x64.ActiveCfg = Release|x64 - {9DE9E23D-C8D4-4817-92A9-920A8B1FE5FF}.Release|x64.Build.0 = Release|x64 - {494BAC80-A60C-43A9-99E7-ACB691CE2C4D}.Debug|ARM.ActiveCfg = Debug|ARM - {494BAC80-A60C-43A9-99E7-ACB691CE2C4D}.Debug|ARM.Build.0 = Debug|ARM - {494BAC80-A60C-43A9-99E7-ACB691CE2C4D}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {494BAC80-A60C-43A9-99E7-ACB691CE2C4D}.Debug|ARM64.Build.0 = Debug|ARM64 - {494BAC80-A60C-43A9-99E7-ACB691CE2C4D}.Debug|Win32.ActiveCfg = Debug|Win32 - {494BAC80-A60C-43A9-99E7-ACB691CE2C4D}.Debug|Win32.Build.0 = Debug|Win32 - {494BAC80-A60C-43A9-99E7-ACB691CE2C4D}.Debug|x64.ActiveCfg = Debug|x64 - {494BAC80-A60C-43A9-99E7-ACB691CE2C4D}.Debug|x64.Build.0 = Debug|x64 - {494BAC80-A60C-43A9-99E7-ACB691CE2C4D}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM - {494BAC80-A60C-43A9-99E7-ACB691CE2C4D}.PGInstrument|ARM.Build.0 = PGInstrument|ARM - {494BAC80-A60C-43A9-99E7-ACB691CE2C4D}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 - {494BAC80-A60C-43A9-99E7-ACB691CE2C4D}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 - {494BAC80-A60C-43A9-99E7-ACB691CE2C4D}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {494BAC80-A60C-43A9-99E7-ACB691CE2C4D}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {494BAC80-A60C-43A9-99E7-ACB691CE2C4D}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {494BAC80-A60C-43A9-99E7-ACB691CE2C4D}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {494BAC80-A60C-43A9-99E7-ACB691CE2C4D}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM - {494BAC80-A60C-43A9-99E7-ACB691CE2C4D}.PGUpdate|ARM.Build.0 = PGUpdate|ARM - {494BAC80-A60C-43A9-99E7-ACB691CE2C4D}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 - {494BAC80-A60C-43A9-99E7-ACB691CE2C4D}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 - {494BAC80-A60C-43A9-99E7-ACB691CE2C4D}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {494BAC80-A60C-43A9-99E7-ACB691CE2C4D}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {494BAC80-A60C-43A9-99E7-ACB691CE2C4D}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {494BAC80-A60C-43A9-99E7-ACB691CE2C4D}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {494BAC80-A60C-43A9-99E7-ACB691CE2C4D}.Release|ARM.ActiveCfg = Release|ARM - {494BAC80-A60C-43A9-99E7-ACB691CE2C4D}.Release|ARM.Build.0 = Release|ARM - {494BAC80-A60C-43A9-99E7-ACB691CE2C4D}.Release|ARM64.ActiveCfg = Release|ARM64 - {494BAC80-A60C-43A9-99E7-ACB691CE2C4D}.Release|ARM64.Build.0 = Release|ARM64 - {494BAC80-A60C-43A9-99E7-ACB691CE2C4D}.Release|Win32.ActiveCfg = Release|Win32 - {494BAC80-A60C-43A9-99E7-ACB691CE2C4D}.Release|Win32.Build.0 = Release|Win32 - {494BAC80-A60C-43A9-99E7-ACB691CE2C4D}.Release|x64.ActiveCfg = Release|x64 - {494BAC80-A60C-43A9-99E7-ACB691CE2C4D}.Release|x64.Build.0 = Release|x64 - {FDB84CBB-2FB6-47C8-A2D6-091E0833239D}.Debug|ARM.ActiveCfg = Debug|ARM - {FDB84CBB-2FB6-47C8-A2D6-091E0833239D}.Debug|ARM.Build.0 = Debug|ARM - {FDB84CBB-2FB6-47C8-A2D6-091E0833239D}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {FDB84CBB-2FB6-47C8-A2D6-091E0833239D}.Debug|ARM64.Build.0 = Debug|ARM64 - {FDB84CBB-2FB6-47C8-A2D6-091E0833239D}.Debug|Win32.ActiveCfg = Debug|Win32 - {FDB84CBB-2FB6-47C8-A2D6-091E0833239D}.Debug|Win32.Build.0 = Debug|Win32 - {FDB84CBB-2FB6-47C8-A2D6-091E0833239D}.Debug|x64.ActiveCfg = Debug|x64 - {FDB84CBB-2FB6-47C8-A2D6-091E0833239D}.Debug|x64.Build.0 = Debug|x64 - {FDB84CBB-2FB6-47C8-A2D6-091E0833239D}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM - {FDB84CBB-2FB6-47C8-A2D6-091E0833239D}.PGInstrument|ARM.Build.0 = PGInstrument|ARM - {FDB84CBB-2FB6-47C8-A2D6-091E0833239D}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 - {FDB84CBB-2FB6-47C8-A2D6-091E0833239D}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 - {FDB84CBB-2FB6-47C8-A2D6-091E0833239D}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {FDB84CBB-2FB6-47C8-A2D6-091E0833239D}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {FDB84CBB-2FB6-47C8-A2D6-091E0833239D}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {FDB84CBB-2FB6-47C8-A2D6-091E0833239D}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {FDB84CBB-2FB6-47C8-A2D6-091E0833239D}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM - {FDB84CBB-2FB6-47C8-A2D6-091E0833239D}.PGUpdate|ARM.Build.0 = PGUpdate|ARM - {FDB84CBB-2FB6-47C8-A2D6-091E0833239D}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 - {FDB84CBB-2FB6-47C8-A2D6-091E0833239D}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 - {FDB84CBB-2FB6-47C8-A2D6-091E0833239D}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {FDB84CBB-2FB6-47C8-A2D6-091E0833239D}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {FDB84CBB-2FB6-47C8-A2D6-091E0833239D}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {FDB84CBB-2FB6-47C8-A2D6-091E0833239D}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {FDB84CBB-2FB6-47C8-A2D6-091E0833239D}.Release|ARM.ActiveCfg = Release|ARM - {FDB84CBB-2FB6-47C8-A2D6-091E0833239D}.Release|ARM.Build.0 = Release|ARM - {FDB84CBB-2FB6-47C8-A2D6-091E0833239D}.Release|ARM64.ActiveCfg = Release|ARM64 - {FDB84CBB-2FB6-47C8-A2D6-091E0833239D}.Release|ARM64.Build.0 = Release|ARM64 - {FDB84CBB-2FB6-47C8-A2D6-091E0833239D}.Release|Win32.ActiveCfg = Release|Win32 - {FDB84CBB-2FB6-47C8-A2D6-091E0833239D}.Release|Win32.Build.0 = Release|Win32 - {FDB84CBB-2FB6-47C8-A2D6-091E0833239D}.Release|x64.ActiveCfg = Release|x64 - {FDB84CBB-2FB6-47C8-A2D6-091E0833239D}.Release|x64.Build.0 = Release|x64 - {AB603547-1E2A-45B3-9E09-B04596006393}.Debug|ARM.ActiveCfg = Debug|Win32 - {AB603547-1E2A-45B3-9E09-B04596006393}.Debug|ARM.Build.0 = Debug|Win32 - {AB603547-1E2A-45B3-9E09-B04596006393}.Debug|ARM64.ActiveCfg = Debug|Win32 - {AB603547-1E2A-45B3-9E09-B04596006393}.Debug|Win32.ActiveCfg = Debug|Win32 - {AB603547-1E2A-45B3-9E09-B04596006393}.Debug|Win32.Build.0 = Debug|Win32 - {AB603547-1E2A-45B3-9E09-B04596006393}.Debug|x64.ActiveCfg = Debug|x64 - {AB603547-1E2A-45B3-9E09-B04596006393}.Debug|x64.Build.0 = Debug|x64 - {AB603547-1E2A-45B3-9E09-B04596006393}.PGInstrument|ARM.ActiveCfg = PGInstrument|Win32 - {AB603547-1E2A-45B3-9E09-B04596006393}.PGInstrument|ARM64.ActiveCfg = PGInstrument|Win32 - {AB603547-1E2A-45B3-9E09-B04596006393}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {AB603547-1E2A-45B3-9E09-B04596006393}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {AB603547-1E2A-45B3-9E09-B04596006393}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {AB603547-1E2A-45B3-9E09-B04596006393}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {AB603547-1E2A-45B3-9E09-B04596006393}.PGUpdate|ARM.ActiveCfg = PGUpdate|Win32 - {AB603547-1E2A-45B3-9E09-B04596006393}.PGUpdate|ARM64.ActiveCfg = PGUpdate|Win32 - {AB603547-1E2A-45B3-9E09-B04596006393}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {AB603547-1E2A-45B3-9E09-B04596006393}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {AB603547-1E2A-45B3-9E09-B04596006393}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {AB603547-1E2A-45B3-9E09-B04596006393}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {AB603547-1E2A-45B3-9E09-B04596006393}.Release|ARM.ActiveCfg = Release|Win32 - {AB603547-1E2A-45B3-9E09-B04596006393}.Release|ARM64.ActiveCfg = Release|Win32 - {AB603547-1E2A-45B3-9E09-B04596006393}.Release|Win32.ActiveCfg = Release|Win32 - {AB603547-1E2A-45B3-9E09-B04596006393}.Release|Win32.Build.0 = Release|Win32 - {AB603547-1E2A-45B3-9E09-B04596006393}.Release|x64.ActiveCfg = Release|x64 - {AB603547-1E2A-45B3-9E09-B04596006393}.Release|x64.Build.0 = Release|x64 - {CB435430-EBB1-478B-8F4E-C256F6838F55}.Debug|ARM.ActiveCfg = Debug|ARM - {CB435430-EBB1-478B-8F4E-C256F6838F55}.Debug|ARM.Build.0 = Debug|ARM - {CB435430-EBB1-478B-8F4E-C256F6838F55}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {CB435430-EBB1-478B-8F4E-C256F6838F55}.Debug|ARM64.Build.0 = Debug|ARM64 - {CB435430-EBB1-478B-8F4E-C256F6838F55}.Debug|Win32.ActiveCfg = Debug|Win32 - {CB435430-EBB1-478B-8F4E-C256F6838F55}.Debug|Win32.Build.0 = Debug|Win32 - {CB435430-EBB1-478B-8F4E-C256F6838F55}.Debug|x64.ActiveCfg = Debug|x64 - {CB435430-EBB1-478B-8F4E-C256F6838F55}.Debug|x64.Build.0 = Debug|x64 - {CB435430-EBB1-478B-8F4E-C256F6838F55}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM - {CB435430-EBB1-478B-8F4E-C256F6838F55}.PGInstrument|ARM.Build.0 = PGInstrument|ARM - {CB435430-EBB1-478B-8F4E-C256F6838F55}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 - {CB435430-EBB1-478B-8F4E-C256F6838F55}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 - {CB435430-EBB1-478B-8F4E-C256F6838F55}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {CB435430-EBB1-478B-8F4E-C256F6838F55}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {CB435430-EBB1-478B-8F4E-C256F6838F55}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {CB435430-EBB1-478B-8F4E-C256F6838F55}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {CB435430-EBB1-478B-8F4E-C256F6838F55}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM - {CB435430-EBB1-478B-8F4E-C256F6838F55}.PGUpdate|ARM.Build.0 = PGUpdate|ARM - {CB435430-EBB1-478B-8F4E-C256F6838F55}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 - {CB435430-EBB1-478B-8F4E-C256F6838F55}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 - {CB435430-EBB1-478B-8F4E-C256F6838F55}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {CB435430-EBB1-478B-8F4E-C256F6838F55}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {CB435430-EBB1-478B-8F4E-C256F6838F55}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {CB435430-EBB1-478B-8F4E-C256F6838F55}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {CB435430-EBB1-478B-8F4E-C256F6838F55}.Release|ARM.ActiveCfg = Release|ARM - {CB435430-EBB1-478B-8F4E-C256F6838F55}.Release|ARM.Build.0 = Release|ARM - {CB435430-EBB1-478B-8F4E-C256F6838F55}.Release|ARM64.ActiveCfg = Release|ARM64 - {CB435430-EBB1-478B-8F4E-C256F6838F55}.Release|ARM64.Build.0 = Release|ARM64 - {CB435430-EBB1-478B-8F4E-C256F6838F55}.Release|Win32.ActiveCfg = Release|Win32 - {CB435430-EBB1-478B-8F4E-C256F6838F55}.Release|Win32.Build.0 = Release|Win32 - {CB435430-EBB1-478B-8F4E-C256F6838F55}.Release|x64.ActiveCfg = Release|x64 - {CB435430-EBB1-478B-8F4E-C256F6838F55}.Release|x64.Build.0 = Release|x64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {5C33FFD3-C8DC-4A54-B842-8BA9846BDFFE} - EndGlobalSection -EndGlobal +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30028.174 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{553EC33E-9816-4996-A660-5D6186A0B0B3}" + ProjectSection(SolutionItems) = preProject + ..\Modules\getbuildinfo.c = ..\Modules\getbuildinfo.c + readme.txt = readme.txt + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "python", "python.vcxproj", "{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}" + ProjectSection(ProjectDependencies) = postProject + {9E48B300-37D1-11DD-8C41-005056C00008} = {9E48B300-37D1-11DD-8C41-005056C00008} + {9EC7190A-249F-4180-A900-548FDCF3055F} = {9EC7190A-249F-4180-A900-548FDCF3055F} + {78D80A15-BD8C-44E2-B49E-1F05B0A0A687} = {78D80A15-BD8C-44E2-B49E-1F05B0A0A687} + {6901D91C-6E48-4BB7-9FEC-700C8131DF1D} = {6901D91C-6E48-4BB7-9FEC-700C8131DF1D} + {54B1431F-B86B-4ACB-B28C-88BCF93191D8} = {54B1431F-B86B-4ACB-B28C-88BCF93191D8} + {F749B822-B489-4CA5-A3AD-CE078F5F338A} = {F749B822-B489-4CA5-A3AD-CE078F5F338A} + {D06B6426-4762-44CC-8BAD-D79052507F2F} = {D06B6426-4762-44CC-8BAD-D79052507F2F} + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781} = {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781} + {CB435430-EBB1-478B-8F4E-C256F6838F55} = {CB435430-EBB1-478B-8F4E-C256F6838F55} + {17E1E049-C309-4D79-843F-AE483C264AEA} = {17E1E049-C309-4D79-843F-AE483C264AEA} + {384C224A-7474-476E-A01B-750EA7DE918C} = {384C224A-7474-476E-A01B-750EA7DE918C} + {12728250-16EC-4DC6-94D7-E21DD88947F8} = {12728250-16EC-4DC6-94D7-E21DD88947F8} + {86937F53-C189-40EF-8CE8-8759D8E7D480} = {86937F53-C189-40EF-8CE8-8759D8E7D480} + {28B5D777-DDF2-4B6B-B34F-31D938813856} = {28B5D777-DDF2-4B6B-B34F-31D938813856} + {31FFC478-7B4A-43E8-9954-8D03E2187E9C} = {31FFC478-7B4A-43E8-9954-8D03E2187E9C} + {F9D71780-F393-11E0-BE50-0800200C9A66} = {F9D71780-F393-11E0-BE50-0800200C9A66} + {494BAC80-A60C-43A9-99E7-ACB691CE2C4D} = {494BAC80-A60C-43A9-99E7-ACB691CE2C4D} + {C6E20F84-3247-4AD6-B051-B073268F73BA} = {C6E20F84-3247-4AD6-B051-B073268F73BA} + {B244E787-C445-441C-BDF4-5A4F1A3A1E51} = {B244E787-C445-441C-BDF4-5A4F1A3A1E51} + {18CAE28C-B454-46C1-87A0-493D91D97F03} = {18CAE28C-B454-46C1-87A0-493D91D97F03} + {13CECB97-4119-4316-9D42-8534019A5A44} = {13CECB97-4119-4316-9D42-8534019A5A44} + {885D4898-D08D-4091-9C40-C700CFE3FC5A} = {885D4898-D08D-4091-9C40-C700CFE3FC5A} + {447F05A8-F581-4CAC-A466-5AC7936E207E} = {447F05A8-F581-4CAC-A466-5AC7936E207E} + {ECC7CEAC-A5E5-458E-BB9E-2413CC847881} = {ECC7CEAC-A5E5-458E-BB9E-2413CC847881} + {4946ECAC-2E69-4BF8-A90A-F5136F5094DF} = {4946ECAC-2E69-4BF8-A90A-F5136F5094DF} + {FDB84CBB-2FB6-47C8-A2D6-091E0833239D} = {FDB84CBB-2FB6-47C8-A2D6-091E0833239D} + {73FCD2BD-F133-46B7-8EC1-144CD82A59D5} = {73FCD2BD-F133-46B7-8EC1-144CD82A59D5} + {2097F1C1-597C-4167-93E3-656A7D6339B2} = {2097F1C1-597C-4167-93E3-656A7D6339B2} + {A2697BD3-28C1-4AEC-9106-8B748639FD16} = {A2697BD3-28C1-4AEC-9106-8B748639FD16} + {900342D7-516A-4469-B1AD-59A66E49A25F} = {900342D7-516A-4469-B1AD-59A66E49A25F} + {6DAC66D9-E703-4624-BE03-49112AB5AA62} = {6DAC66D9-E703-4624-BE03-49112AB5AA62} + {0E9791DB-593A-465F-98BC-681011311617} = {0E9791DB-593A-465F-98BC-681011311617} + {0E9791DB-593A-465F-98BC-681011311618} = {0E9791DB-593A-465F-98BC-681011311618} + {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E} = {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E} + {16BFE6F0-22EF-40B5-B831-7E937119EF10} = {16BFE6F0-22EF-40B5-B831-7E937119EF10} + {FCBE1EF2-E0F0-40B1-88B5-00A35D378742} = {FCBE1EF2-E0F0-40B1-88B5-00A35D378742} + {A840DDFB-ED50-484B-B527-B32E7CF90FD5} = {A840DDFB-ED50-484B-B527-B32E7CF90FD5} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pythoncore", "pythoncore.vcxproj", "{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}" + ProjectSection(ProjectDependencies) = postProject + {19C0C13F-47CA-4432-AFF3-799A296A4DDC} = {19C0C13F-47CA-4432-AFF3-799A296A4DDC} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pythonw", "pythonw.vcxproj", "{F4229CC3-873C-49AE-9729-DD308ED4CD4A}" + ProjectSection(ProjectDependencies) = postProject + {B11D750F-CD1F-4A96-85CE-E69A5C5259F9} = {B11D750F-CD1F-4A96-85CE-E69A5C5259F9} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "winsound", "winsound.vcxproj", "{28B5D777-DDF2-4B6B-B34F-31D938813856}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_decimal", "_decimal.vcxproj", "{0E9791DB-593A-465F-98BC-681011311617}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_ctypes", "_ctypes.vcxproj", "{0E9791DB-593A-465F-98BC-681011311618}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_ctypes_test", "_ctypes_test.vcxproj", "{9EC7190A-249F-4180-A900-548FDCF3055F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_elementtree", "_elementtree.vcxproj", "{17E1E049-C309-4D79-843F-AE483C264AEA}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_msi", "_msi.vcxproj", "{31FFC478-7B4A-43E8-9954-8D03E2187E9C}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_socket", "_socket.vcxproj", "{86937F53-C189-40EF-8CE8-8759D8E7D480}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_sqlite3", "_sqlite3.vcxproj", "{13CECB97-4119-4316-9D42-8534019A5A44}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_ssl", "_ssl.vcxproj", "{C6E20F84-3247-4AD6-B051-B073268F73BA}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testcapi", "_testcapi.vcxproj", "{6901D91C-6E48-4BB7-9FEC-700C8131DF1D}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testclinic", "_testclinic.vcxproj", "{A840DDFB-ED50-484B-B527-B32E7CF90FD5}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testinternalcapi", "_testinternalcapi.vcxproj", "{900342D7-516A-4469-B1AD-59A66E49A25F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testimportmultiple", "_testimportmultiple.vcxproj", "{36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_tkinter", "_tkinter.vcxproj", "{4946ECAC-2E69-4BF8-A90A-F5136F5094DF}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_bz2", "_bz2.vcxproj", "{73FCD2BD-F133-46B7-8EC1-144CD82A59D5}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "select", "select.vcxproj", "{18CAE28C-B454-46C1-87A0-493D91D97F03}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_lzma", "_lzma.vcxproj", "{F9D71780-F393-11E0-BE50-0800200C9A66}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unicodedata", "unicodedata.vcxproj", "{ECC7CEAC-A5E5-458E-BB9E-2413CC847881}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pyexpat", "pyexpat.vcxproj", "{D06B6426-4762-44CC-8BAD-D79052507F2F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_hashlib", "_hashlib.vcxproj", "{447F05A8-F581-4CAC-A466-5AC7936E207E}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sqlite3", "sqlite3.vcxproj", "{A1A295E5-463C-437F-81CA-1F32367685DA}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_multiprocessing", "_multiprocessing.vcxproj", "{9E48B300-37D1-11DD-8C41-005056C00008}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "python3dll", "python3dll.vcxproj", "{885D4898-D08D-4091-9C40-C700CFE3FC5A}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xxlimited", "xxlimited.vcxproj", "{F749B822-B489-4CA5-A3AD-CE078F5F338A}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testbuffer", "_testbuffer.vcxproj", "{A2697BD3-28C1-4AEC-9106-8B748639FD16}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pylauncher", "pylauncher.vcxproj", "{7B2727B5-5A3F-40EE-A866-43A13CD31446}" + ProjectSection(ProjectDependencies) = postProject + {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782} = {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pywlauncher", "pywlauncher.vcxproj", "{1D4B18D3-7C12-4ECB-9179-8531FF876CE6}" + ProjectSection(ProjectDependencies) = postProject + {7B2727B5-5A3F-40EE-A866-43A13CD31446} = {7B2727B5-5A3F-40EE-A866-43A13CD31446} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_freeze_module", "_freeze_module.vcxproj", "{19C0C13F-47CA-4432-AFF3-799A296A4DDC}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_overlapped", "_overlapped.vcxproj", "{EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testembed", "_testembed.vcxproj", "{6DAC66D9-E703-4624-BE03-49112AB5AA62}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testmultiphase", "_testmultiphase.vcxproj", "{16BFE6F0-22EF-40B5-B831-7E937119EF10}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testsinglephase", "_testsinglephase.vcxproj", "{2097F1C1-597C-4167-93E3-656A7D6339B2}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pyshellext", "pyshellext.vcxproj", "{0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testconsole", "_testconsole.vcxproj", "{B244E787-C445-441C-BDF4-5A4F1A3A1E51}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_asyncio", "_asyncio.vcxproj", "{384C224A-7474-476E-A01B-750EA7DE918C}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_zoneinfo", "_zoneinfo.vcxproj", "{FCBE1EF2-E0F0-40B1-88B5-00A35D378742}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_queue", "_queue.vcxproj", "{78D80A15-BD8C-44E2-B49E-1F05B0A0A687}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "liblzma", "liblzma.vcxproj", "{12728250-16EC-4DC6-94D7-E21DD88947F8}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "python_uwp", "python_uwp.vcxproj", "{9DE9E23D-C8D4-4817-92A9-920A8B1FE5FF}" + ProjectSection(ProjectDependencies) = postProject + {B11D750F-CD1F-4A96-85CE-E69A5C5259F9} = {B11D750F-CD1F-4A96-85CE-E69A5C5259F9} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "venvlauncher", "venvlauncher.vcxproj", "{494BAC80-A60C-43A9-99E7-ACB691CE2C4D}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "venvwlauncher", "venvwlauncher.vcxproj", "{FDB84CBB-2FB6-47C8-A2D6-091E0833239D}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pythonw_uwp", "pythonw_uwp.vcxproj", "{AB603547-1E2A-45B3-9E09-B04596006393}" + ProjectSection(ProjectDependencies) = postProject + {F4229CC3-873C-49AE-9729-DD308ED4CD4A} = {F4229CC3-873C-49AE-9729-DD308ED4CD4A} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_uuid", "_uuid.vcxproj", "{CB435430-EBB1-478B-8F4E-C256F6838F55}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_wmi", "_wmi.vcxproj", "{54B1431F-B86B-4ACB-B28C-88BCF93191D8}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|ARM = Debug|ARM + Debug|ARM64 = Debug|ARM64 + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + PGInstrument|ARM = PGInstrument|ARM + PGInstrument|ARM64 = PGInstrument|ARM64 + PGInstrument|Win32 = PGInstrument|Win32 + PGInstrument|x64 = PGInstrument|x64 + PGUpdate|ARM = PGUpdate|ARM + PGUpdate|ARM64 = PGUpdate|ARM64 + PGUpdate|Win32 = PGUpdate|Win32 + PGUpdate|x64 = PGUpdate|x64 + Release|ARM = Release|ARM + Release|ARM64 = Release|ARM64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Debug|ARM.ActiveCfg = Debug|ARM + {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Debug|ARM.Build.0 = Debug|ARM + {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Debug|ARM64.Build.0 = Debug|ARM64 + {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Debug|Win32.ActiveCfg = Debug|Win32 + {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Debug|Win32.Build.0 = Debug|Win32 + {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Debug|x64.ActiveCfg = Debug|x64 + {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Debug|x64.Build.0 = Debug|x64 + {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM + {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGInstrument|ARM.Build.0 = PGInstrument|ARM + {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 + {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 + {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 + {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 + {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 + {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGInstrument|x64.Build.0 = PGInstrument|x64 + {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM + {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGUpdate|ARM.Build.0 = PGUpdate|ARM + {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 + {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 + {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 + {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 + {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 + {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Release|ARM.ActiveCfg = Release|ARM + {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Release|ARM.Build.0 = Release|ARM + {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Release|ARM64.ActiveCfg = Release|ARM64 + {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Release|ARM64.Build.0 = Release|ARM64 + {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Release|Win32.ActiveCfg = Release|Win32 + {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Release|Win32.Build.0 = Release|Win32 + {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Release|x64.ActiveCfg = Release|x64 + {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Release|x64.Build.0 = Release|x64 + {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Debug|ARM.ActiveCfg = Debug|ARM + {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Debug|ARM.Build.0 = Debug|ARM + {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Debug|ARM64.Build.0 = Debug|ARM64 + {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Debug|Win32.ActiveCfg = Debug|Win32 + {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Debug|Win32.Build.0 = Debug|Win32 + {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Debug|x64.ActiveCfg = Debug|x64 + {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Debug|x64.Build.0 = Debug|x64 + {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM + {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGInstrument|ARM.Build.0 = PGInstrument|ARM + {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 + {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 + {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 + {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 + {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 + {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGInstrument|x64.Build.0 = PGInstrument|x64 + {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM + {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGUpdate|ARM.Build.0 = PGUpdate|ARM + {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 + {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 + {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 + {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 + {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 + {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Release|ARM.ActiveCfg = Release|ARM + {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Release|ARM.Build.0 = Release|ARM + {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Release|ARM64.ActiveCfg = Release|ARM64 + {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Release|ARM64.Build.0 = Release|ARM64 + {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Release|Win32.ActiveCfg = Release|Win32 + {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Release|Win32.Build.0 = Release|Win32 + {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Release|x64.ActiveCfg = Release|x64 + {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Release|x64.Build.0 = Release|x64 + {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Debug|ARM.ActiveCfg = Debug|ARM + {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Debug|ARM.Build.0 = Debug|ARM + {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Debug|ARM64.Build.0 = Debug|ARM64 + {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Debug|Win32.ActiveCfg = Debug|Win32 + {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Debug|Win32.Build.0 = Debug|Win32 + {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Debug|x64.ActiveCfg = Debug|x64 + {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Debug|x64.Build.0 = Debug|x64 + {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM + {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGInstrument|ARM.Build.0 = PGInstrument|ARM + {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 + {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 + {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGInstrument|Win32.ActiveCfg = Release|Win32 + {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGInstrument|Win32.Build.0 = Release|Win32 + {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGInstrument|x64.ActiveCfg = Release|x64 + {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGInstrument|x64.Build.0 = Release|x64 + {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM + {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGUpdate|ARM.Build.0 = PGUpdate|ARM + {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 + {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 + {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGUpdate|Win32.ActiveCfg = Release|Win32 + {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGUpdate|Win32.Build.0 = Release|Win32 + {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGUpdate|x64.ActiveCfg = Release|x64 + {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGUpdate|x64.Build.0 = Release|x64 + {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Release|ARM.ActiveCfg = Release|ARM + {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Release|ARM.Build.0 = Release|ARM + {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Release|ARM64.ActiveCfg = Release|ARM64 + {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Release|ARM64.Build.0 = Release|ARM64 + {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Release|Win32.ActiveCfg = Release|Win32 + {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Release|Win32.Build.0 = Release|Win32 + {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Release|x64.ActiveCfg = Release|x64 + {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Release|x64.Build.0 = Release|x64 + {28B5D777-DDF2-4B6B-B34F-31D938813856}.Debug|ARM.ActiveCfg = Debug|ARM + {28B5D777-DDF2-4B6B-B34F-31D938813856}.Debug|ARM.Build.0 = Debug|ARM + {28B5D777-DDF2-4B6B-B34F-31D938813856}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {28B5D777-DDF2-4B6B-B34F-31D938813856}.Debug|ARM64.Build.0 = Debug|ARM64 + {28B5D777-DDF2-4B6B-B34F-31D938813856}.Debug|Win32.ActiveCfg = Debug|Win32 + {28B5D777-DDF2-4B6B-B34F-31D938813856}.Debug|Win32.Build.0 = Debug|Win32 + {28B5D777-DDF2-4B6B-B34F-31D938813856}.Debug|x64.ActiveCfg = Debug|x64 + {28B5D777-DDF2-4B6B-B34F-31D938813856}.Debug|x64.Build.0 = Debug|x64 + {28B5D777-DDF2-4B6B-B34F-31D938813856}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM + {28B5D777-DDF2-4B6B-B34F-31D938813856}.PGInstrument|ARM.Build.0 = PGInstrument|ARM + {28B5D777-DDF2-4B6B-B34F-31D938813856}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 + {28B5D777-DDF2-4B6B-B34F-31D938813856}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 + {28B5D777-DDF2-4B6B-B34F-31D938813856}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 + {28B5D777-DDF2-4B6B-B34F-31D938813856}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 + {28B5D777-DDF2-4B6B-B34F-31D938813856}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 + {28B5D777-DDF2-4B6B-B34F-31D938813856}.PGInstrument|x64.Build.0 = PGInstrument|x64 + {28B5D777-DDF2-4B6B-B34F-31D938813856}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM + {28B5D777-DDF2-4B6B-B34F-31D938813856}.PGUpdate|ARM.Build.0 = PGUpdate|ARM + {28B5D777-DDF2-4B6B-B34F-31D938813856}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 + {28B5D777-DDF2-4B6B-B34F-31D938813856}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 + {28B5D777-DDF2-4B6B-B34F-31D938813856}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 + {28B5D777-DDF2-4B6B-B34F-31D938813856}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 + {28B5D777-DDF2-4B6B-B34F-31D938813856}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 + {28B5D777-DDF2-4B6B-B34F-31D938813856}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {28B5D777-DDF2-4B6B-B34F-31D938813856}.Release|ARM.ActiveCfg = Release|ARM + {28B5D777-DDF2-4B6B-B34F-31D938813856}.Release|ARM.Build.0 = Release|ARM + {28B5D777-DDF2-4B6B-B34F-31D938813856}.Release|ARM64.ActiveCfg = Release|ARM64 + {28B5D777-DDF2-4B6B-B34F-31D938813856}.Release|ARM64.Build.0 = Release|ARM64 + {28B5D777-DDF2-4B6B-B34F-31D938813856}.Release|Win32.ActiveCfg = Release|Win32 + {28B5D777-DDF2-4B6B-B34F-31D938813856}.Release|Win32.Build.0 = Release|Win32 + {28B5D777-DDF2-4B6B-B34F-31D938813856}.Release|x64.ActiveCfg = Release|x64 + {28B5D777-DDF2-4B6B-B34F-31D938813856}.Release|x64.Build.0 = Release|x64 + {0E9791DB-593A-465F-98BC-681011311617}.Debug|ARM.ActiveCfg = Debug|ARM + {0E9791DB-593A-465F-98BC-681011311617}.Debug|ARM.Build.0 = Debug|ARM + {0E9791DB-593A-465F-98BC-681011311617}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {0E9791DB-593A-465F-98BC-681011311617}.Debug|ARM64.Build.0 = Debug|ARM64 + {0E9791DB-593A-465F-98BC-681011311617}.Debug|Win32.ActiveCfg = Debug|Win32 + {0E9791DB-593A-465F-98BC-681011311617}.Debug|Win32.Build.0 = Debug|Win32 + {0E9791DB-593A-465F-98BC-681011311617}.Debug|x64.ActiveCfg = Debug|x64 + {0E9791DB-593A-465F-98BC-681011311617}.Debug|x64.Build.0 = Debug|x64 + {0E9791DB-593A-465F-98BC-681011311617}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM + {0E9791DB-593A-465F-98BC-681011311617}.PGInstrument|ARM.Build.0 = PGInstrument|ARM + {0E9791DB-593A-465F-98BC-681011311617}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 + {0E9791DB-593A-465F-98BC-681011311617}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 + {0E9791DB-593A-465F-98BC-681011311617}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 + {0E9791DB-593A-465F-98BC-681011311617}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 + {0E9791DB-593A-465F-98BC-681011311617}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 + {0E9791DB-593A-465F-98BC-681011311617}.PGInstrument|x64.Build.0 = PGInstrument|x64 + {0E9791DB-593A-465F-98BC-681011311617}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM + {0E9791DB-593A-465F-98BC-681011311617}.PGUpdate|ARM.Build.0 = PGUpdate|ARM + {0E9791DB-593A-465F-98BC-681011311617}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 + {0E9791DB-593A-465F-98BC-681011311617}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 + {0E9791DB-593A-465F-98BC-681011311617}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 + {0E9791DB-593A-465F-98BC-681011311617}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 + {0E9791DB-593A-465F-98BC-681011311617}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 + {0E9791DB-593A-465F-98BC-681011311617}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {0E9791DB-593A-465F-98BC-681011311617}.Release|ARM.ActiveCfg = Release|ARM + {0E9791DB-593A-465F-98BC-681011311617}.Release|ARM.Build.0 = Release|ARM + {0E9791DB-593A-465F-98BC-681011311617}.Release|ARM64.ActiveCfg = Release|ARM64 + {0E9791DB-593A-465F-98BC-681011311617}.Release|ARM64.Build.0 = Release|ARM64 + {0E9791DB-593A-465F-98BC-681011311617}.Release|Win32.ActiveCfg = Release|Win32 + {0E9791DB-593A-465F-98BC-681011311617}.Release|Win32.Build.0 = Release|Win32 + {0E9791DB-593A-465F-98BC-681011311617}.Release|x64.ActiveCfg = Release|x64 + {0E9791DB-593A-465F-98BC-681011311617}.Release|x64.Build.0 = Release|x64 + {0E9791DB-593A-465F-98BC-681011311618}.Debug|ARM.ActiveCfg = Debug|ARM + {0E9791DB-593A-465F-98BC-681011311618}.Debug|ARM.Build.0 = Debug|ARM + {0E9791DB-593A-465F-98BC-681011311618}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {0E9791DB-593A-465F-98BC-681011311618}.Debug|ARM64.Build.0 = Debug|ARM64 + {0E9791DB-593A-465F-98BC-681011311618}.Debug|Win32.ActiveCfg = Debug|Win32 + {0E9791DB-593A-465F-98BC-681011311618}.Debug|Win32.Build.0 = Debug|Win32 + {0E9791DB-593A-465F-98BC-681011311618}.Debug|x64.ActiveCfg = Debug|x64 + {0E9791DB-593A-465F-98BC-681011311618}.Debug|x64.Build.0 = Debug|x64 + {0E9791DB-593A-465F-98BC-681011311618}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM + {0E9791DB-593A-465F-98BC-681011311618}.PGInstrument|ARM.Build.0 = PGInstrument|ARM + {0E9791DB-593A-465F-98BC-681011311618}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 + {0E9791DB-593A-465F-98BC-681011311618}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 + {0E9791DB-593A-465F-98BC-681011311618}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 + {0E9791DB-593A-465F-98BC-681011311618}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 + {0E9791DB-593A-465F-98BC-681011311618}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 + {0E9791DB-593A-465F-98BC-681011311618}.PGInstrument|x64.Build.0 = PGInstrument|x64 + {0E9791DB-593A-465F-98BC-681011311618}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM + {0E9791DB-593A-465F-98BC-681011311618}.PGUpdate|ARM.Build.0 = PGUpdate|ARM + {0E9791DB-593A-465F-98BC-681011311618}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 + {0E9791DB-593A-465F-98BC-681011311618}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 + {0E9791DB-593A-465F-98BC-681011311618}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 + {0E9791DB-593A-465F-98BC-681011311618}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 + {0E9791DB-593A-465F-98BC-681011311618}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 + {0E9791DB-593A-465F-98BC-681011311618}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {0E9791DB-593A-465F-98BC-681011311618}.Release|ARM.ActiveCfg = Release|ARM + {0E9791DB-593A-465F-98BC-681011311618}.Release|ARM.Build.0 = Release|ARM + {0E9791DB-593A-465F-98BC-681011311618}.Release|ARM64.ActiveCfg = Release|ARM64 + {0E9791DB-593A-465F-98BC-681011311618}.Release|ARM64.Build.0 = Release|ARM64 + {0E9791DB-593A-465F-98BC-681011311618}.Release|Win32.ActiveCfg = Release|Win32 + {0E9791DB-593A-465F-98BC-681011311618}.Release|Win32.Build.0 = Release|Win32 + {0E9791DB-593A-465F-98BC-681011311618}.Release|x64.ActiveCfg = Release|x64 + {0E9791DB-593A-465F-98BC-681011311618}.Release|x64.Build.0 = Release|x64 + {9EC7190A-249F-4180-A900-548FDCF3055F}.Debug|ARM.ActiveCfg = Debug|ARM + {9EC7190A-249F-4180-A900-548FDCF3055F}.Debug|ARM.Build.0 = Debug|ARM + {9EC7190A-249F-4180-A900-548FDCF3055F}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {9EC7190A-249F-4180-A900-548FDCF3055F}.Debug|ARM64.Build.0 = Debug|ARM64 + {9EC7190A-249F-4180-A900-548FDCF3055F}.Debug|Win32.ActiveCfg = Debug|Win32 + {9EC7190A-249F-4180-A900-548FDCF3055F}.Debug|Win32.Build.0 = Debug|Win32 + {9EC7190A-249F-4180-A900-548FDCF3055F}.Debug|x64.ActiveCfg = Debug|x64 + {9EC7190A-249F-4180-A900-548FDCF3055F}.Debug|x64.Build.0 = Debug|x64 + {9EC7190A-249F-4180-A900-548FDCF3055F}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM + {9EC7190A-249F-4180-A900-548FDCF3055F}.PGInstrument|ARM.Build.0 = PGInstrument|ARM + {9EC7190A-249F-4180-A900-548FDCF3055F}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 + {9EC7190A-249F-4180-A900-548FDCF3055F}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 + {9EC7190A-249F-4180-A900-548FDCF3055F}.PGInstrument|Win32.ActiveCfg = Release|Win32 + {9EC7190A-249F-4180-A900-548FDCF3055F}.PGInstrument|Win32.Build.0 = Release|Win32 + {9EC7190A-249F-4180-A900-548FDCF3055F}.PGInstrument|x64.ActiveCfg = Release|x64 + {9EC7190A-249F-4180-A900-548FDCF3055F}.PGInstrument|x64.Build.0 = Release|x64 + {9EC7190A-249F-4180-A900-548FDCF3055F}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM + {9EC7190A-249F-4180-A900-548FDCF3055F}.PGUpdate|ARM.Build.0 = PGUpdate|ARM + {9EC7190A-249F-4180-A900-548FDCF3055F}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 + {9EC7190A-249F-4180-A900-548FDCF3055F}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 + {9EC7190A-249F-4180-A900-548FDCF3055F}.PGUpdate|Win32.ActiveCfg = Release|Win32 + {9EC7190A-249F-4180-A900-548FDCF3055F}.PGUpdate|Win32.Build.0 = Release|Win32 + {9EC7190A-249F-4180-A900-548FDCF3055F}.PGUpdate|x64.ActiveCfg = Release|x64 + {9EC7190A-249F-4180-A900-548FDCF3055F}.PGUpdate|x64.Build.0 = Release|x64 + {9EC7190A-249F-4180-A900-548FDCF3055F}.Release|ARM.ActiveCfg = Release|ARM + {9EC7190A-249F-4180-A900-548FDCF3055F}.Release|ARM.Build.0 = Release|ARM + {9EC7190A-249F-4180-A900-548FDCF3055F}.Release|ARM64.ActiveCfg = Release|ARM64 + {9EC7190A-249F-4180-A900-548FDCF3055F}.Release|ARM64.Build.0 = Release|ARM64 + {9EC7190A-249F-4180-A900-548FDCF3055F}.Release|Win32.ActiveCfg = Release|Win32 + {9EC7190A-249F-4180-A900-548FDCF3055F}.Release|Win32.Build.0 = Release|Win32 + {9EC7190A-249F-4180-A900-548FDCF3055F}.Release|x64.ActiveCfg = Release|x64 + {9EC7190A-249F-4180-A900-548FDCF3055F}.Release|x64.Build.0 = Release|x64 + {17E1E049-C309-4D79-843F-AE483C264AEA}.Debug|ARM.ActiveCfg = Debug|ARM + {17E1E049-C309-4D79-843F-AE483C264AEA}.Debug|ARM.Build.0 = Debug|ARM + {17E1E049-C309-4D79-843F-AE483C264AEA}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {17E1E049-C309-4D79-843F-AE483C264AEA}.Debug|ARM64.Build.0 = Debug|ARM64 + {17E1E049-C309-4D79-843F-AE483C264AEA}.Debug|Win32.ActiveCfg = Debug|Win32 + {17E1E049-C309-4D79-843F-AE483C264AEA}.Debug|Win32.Build.0 = Debug|Win32 + {17E1E049-C309-4D79-843F-AE483C264AEA}.Debug|x64.ActiveCfg = Debug|x64 + {17E1E049-C309-4D79-843F-AE483C264AEA}.Debug|x64.Build.0 = Debug|x64 + {17E1E049-C309-4D79-843F-AE483C264AEA}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM + {17E1E049-C309-4D79-843F-AE483C264AEA}.PGInstrument|ARM.Build.0 = PGInstrument|ARM + {17E1E049-C309-4D79-843F-AE483C264AEA}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 + {17E1E049-C309-4D79-843F-AE483C264AEA}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 + {17E1E049-C309-4D79-843F-AE483C264AEA}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 + {17E1E049-C309-4D79-843F-AE483C264AEA}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 + {17E1E049-C309-4D79-843F-AE483C264AEA}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 + {17E1E049-C309-4D79-843F-AE483C264AEA}.PGInstrument|x64.Build.0 = PGInstrument|x64 + {17E1E049-C309-4D79-843F-AE483C264AEA}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM + {17E1E049-C309-4D79-843F-AE483C264AEA}.PGUpdate|ARM.Build.0 = PGUpdate|ARM + {17E1E049-C309-4D79-843F-AE483C264AEA}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 + {17E1E049-C309-4D79-843F-AE483C264AEA}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 + {17E1E049-C309-4D79-843F-AE483C264AEA}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 + {17E1E049-C309-4D79-843F-AE483C264AEA}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 + {17E1E049-C309-4D79-843F-AE483C264AEA}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 + {17E1E049-C309-4D79-843F-AE483C264AEA}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {17E1E049-C309-4D79-843F-AE483C264AEA}.Release|ARM.ActiveCfg = Release|ARM + {17E1E049-C309-4D79-843F-AE483C264AEA}.Release|ARM.Build.0 = Release|ARM + {17E1E049-C309-4D79-843F-AE483C264AEA}.Release|ARM64.ActiveCfg = Release|ARM64 + {17E1E049-C309-4D79-843F-AE483C264AEA}.Release|ARM64.Build.0 = Release|ARM64 + {17E1E049-C309-4D79-843F-AE483C264AEA}.Release|Win32.ActiveCfg = Release|Win32 + {17E1E049-C309-4D79-843F-AE483C264AEA}.Release|Win32.Build.0 = Release|Win32 + {17E1E049-C309-4D79-843F-AE483C264AEA}.Release|x64.ActiveCfg = Release|x64 + {17E1E049-C309-4D79-843F-AE483C264AEA}.Release|x64.Build.0 = Release|x64 + {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Debug|ARM.ActiveCfg = Debug|ARM + {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Debug|ARM.Build.0 = Debug|ARM + {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Debug|ARM64.Build.0 = Debug|ARM64 + {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Debug|Win32.ActiveCfg = Debug|Win32 + {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Debug|Win32.Build.0 = Debug|Win32 + {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Debug|x64.ActiveCfg = Debug|x64 + {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Debug|x64.Build.0 = Debug|x64 + {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM + {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGInstrument|ARM.Build.0 = PGInstrument|ARM + {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 + {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 + {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 + {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 + {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 + {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGInstrument|x64.Build.0 = PGInstrument|x64 + {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM + {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGUpdate|ARM.Build.0 = PGUpdate|ARM + {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 + {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 + {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 + {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 + {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 + {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Release|ARM.ActiveCfg = Release|ARM + {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Release|ARM.Build.0 = Release|ARM + {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Release|ARM64.ActiveCfg = Release|ARM64 + {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Release|ARM64.Build.0 = Release|ARM64 + {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Release|Win32.ActiveCfg = Release|Win32 + {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Release|Win32.Build.0 = Release|Win32 + {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Release|x64.ActiveCfg = Release|x64 + {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Release|x64.Build.0 = Release|x64 + {86937F53-C189-40EF-8CE8-8759D8E7D480}.Debug|ARM.ActiveCfg = Debug|ARM + {86937F53-C189-40EF-8CE8-8759D8E7D480}.Debug|ARM.Build.0 = Debug|ARM + {86937F53-C189-40EF-8CE8-8759D8E7D480}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {86937F53-C189-40EF-8CE8-8759D8E7D480}.Debug|ARM64.Build.0 = Debug|ARM64 + {86937F53-C189-40EF-8CE8-8759D8E7D480}.Debug|Win32.ActiveCfg = Debug|Win32 + {86937F53-C189-40EF-8CE8-8759D8E7D480}.Debug|Win32.Build.0 = Debug|Win32 + {86937F53-C189-40EF-8CE8-8759D8E7D480}.Debug|x64.ActiveCfg = Debug|x64 + {86937F53-C189-40EF-8CE8-8759D8E7D480}.Debug|x64.Build.0 = Debug|x64 + {86937F53-C189-40EF-8CE8-8759D8E7D480}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM + {86937F53-C189-40EF-8CE8-8759D8E7D480}.PGInstrument|ARM.Build.0 = PGInstrument|ARM + {86937F53-C189-40EF-8CE8-8759D8E7D480}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 + {86937F53-C189-40EF-8CE8-8759D8E7D480}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 + {86937F53-C189-40EF-8CE8-8759D8E7D480}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 + {86937F53-C189-40EF-8CE8-8759D8E7D480}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 + {86937F53-C189-40EF-8CE8-8759D8E7D480}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 + {86937F53-C189-40EF-8CE8-8759D8E7D480}.PGInstrument|x64.Build.0 = PGInstrument|x64 + {86937F53-C189-40EF-8CE8-8759D8E7D480}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM + {86937F53-C189-40EF-8CE8-8759D8E7D480}.PGUpdate|ARM.Build.0 = PGUpdate|ARM + {86937F53-C189-40EF-8CE8-8759D8E7D480}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 + {86937F53-C189-40EF-8CE8-8759D8E7D480}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 + {86937F53-C189-40EF-8CE8-8759D8E7D480}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 + {86937F53-C189-40EF-8CE8-8759D8E7D480}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 + {86937F53-C189-40EF-8CE8-8759D8E7D480}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 + {86937F53-C189-40EF-8CE8-8759D8E7D480}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {86937F53-C189-40EF-8CE8-8759D8E7D480}.Release|ARM.ActiveCfg = Release|ARM + {86937F53-C189-40EF-8CE8-8759D8E7D480}.Release|ARM.Build.0 = Release|ARM + {86937F53-C189-40EF-8CE8-8759D8E7D480}.Release|ARM64.ActiveCfg = Release|ARM64 + {86937F53-C189-40EF-8CE8-8759D8E7D480}.Release|ARM64.Build.0 = Release|ARM64 + {86937F53-C189-40EF-8CE8-8759D8E7D480}.Release|Win32.ActiveCfg = Release|Win32 + {86937F53-C189-40EF-8CE8-8759D8E7D480}.Release|Win32.Build.0 = Release|Win32 + {86937F53-C189-40EF-8CE8-8759D8E7D480}.Release|x64.ActiveCfg = Release|x64 + {86937F53-C189-40EF-8CE8-8759D8E7D480}.Release|x64.Build.0 = Release|x64 + {13CECB97-4119-4316-9D42-8534019A5A44}.Debug|ARM.ActiveCfg = Debug|ARM + {13CECB97-4119-4316-9D42-8534019A5A44}.Debug|ARM.Build.0 = Debug|ARM + {13CECB97-4119-4316-9D42-8534019A5A44}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {13CECB97-4119-4316-9D42-8534019A5A44}.Debug|ARM64.Build.0 = Debug|ARM64 + {13CECB97-4119-4316-9D42-8534019A5A44}.Debug|Win32.ActiveCfg = Debug|Win32 + {13CECB97-4119-4316-9D42-8534019A5A44}.Debug|Win32.Build.0 = Debug|Win32 + {13CECB97-4119-4316-9D42-8534019A5A44}.Debug|x64.ActiveCfg = Debug|x64 + {13CECB97-4119-4316-9D42-8534019A5A44}.Debug|x64.Build.0 = Debug|x64 + {13CECB97-4119-4316-9D42-8534019A5A44}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM + {13CECB97-4119-4316-9D42-8534019A5A44}.PGInstrument|ARM.Build.0 = PGInstrument|ARM + {13CECB97-4119-4316-9D42-8534019A5A44}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 + {13CECB97-4119-4316-9D42-8534019A5A44}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 + {13CECB97-4119-4316-9D42-8534019A5A44}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 + {13CECB97-4119-4316-9D42-8534019A5A44}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 + {13CECB97-4119-4316-9D42-8534019A5A44}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 + {13CECB97-4119-4316-9D42-8534019A5A44}.PGInstrument|x64.Build.0 = PGInstrument|x64 + {13CECB97-4119-4316-9D42-8534019A5A44}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM + {13CECB97-4119-4316-9D42-8534019A5A44}.PGUpdate|ARM.Build.0 = PGUpdate|ARM + {13CECB97-4119-4316-9D42-8534019A5A44}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 + {13CECB97-4119-4316-9D42-8534019A5A44}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 + {13CECB97-4119-4316-9D42-8534019A5A44}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 + {13CECB97-4119-4316-9D42-8534019A5A44}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 + {13CECB97-4119-4316-9D42-8534019A5A44}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 + {13CECB97-4119-4316-9D42-8534019A5A44}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {13CECB97-4119-4316-9D42-8534019A5A44}.Release|ARM.ActiveCfg = Release|ARM + {13CECB97-4119-4316-9D42-8534019A5A44}.Release|ARM.Build.0 = Release|ARM + {13CECB97-4119-4316-9D42-8534019A5A44}.Release|ARM64.ActiveCfg = Release|ARM64 + {13CECB97-4119-4316-9D42-8534019A5A44}.Release|ARM64.Build.0 = Release|ARM64 + {13CECB97-4119-4316-9D42-8534019A5A44}.Release|Win32.ActiveCfg = Release|Win32 + {13CECB97-4119-4316-9D42-8534019A5A44}.Release|Win32.Build.0 = Release|Win32 + {13CECB97-4119-4316-9D42-8534019A5A44}.Release|x64.ActiveCfg = Release|x64 + {13CECB97-4119-4316-9D42-8534019A5A44}.Release|x64.Build.0 = Release|x64 + {C6E20F84-3247-4AD6-B051-B073268F73BA}.Debug|ARM.ActiveCfg = Debug|ARM + {C6E20F84-3247-4AD6-B051-B073268F73BA}.Debug|ARM.Build.0 = Debug|ARM + {C6E20F84-3247-4AD6-B051-B073268F73BA}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {C6E20F84-3247-4AD6-B051-B073268F73BA}.Debug|ARM64.Build.0 = Debug|ARM64 + {C6E20F84-3247-4AD6-B051-B073268F73BA}.Debug|Win32.ActiveCfg = Debug|Win32 + {C6E20F84-3247-4AD6-B051-B073268F73BA}.Debug|Win32.Build.0 = Debug|Win32 + {C6E20F84-3247-4AD6-B051-B073268F73BA}.Debug|x64.ActiveCfg = Debug|x64 + {C6E20F84-3247-4AD6-B051-B073268F73BA}.Debug|x64.Build.0 = Debug|x64 + {C6E20F84-3247-4AD6-B051-B073268F73BA}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM + {C6E20F84-3247-4AD6-B051-B073268F73BA}.PGInstrument|ARM.Build.0 = PGInstrument|ARM + {C6E20F84-3247-4AD6-B051-B073268F73BA}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 + {C6E20F84-3247-4AD6-B051-B073268F73BA}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 + {C6E20F84-3247-4AD6-B051-B073268F73BA}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 + {C6E20F84-3247-4AD6-B051-B073268F73BA}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 + {C6E20F84-3247-4AD6-B051-B073268F73BA}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 + {C6E20F84-3247-4AD6-B051-B073268F73BA}.PGInstrument|x64.Build.0 = PGInstrument|x64 + {C6E20F84-3247-4AD6-B051-B073268F73BA}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM + {C6E20F84-3247-4AD6-B051-B073268F73BA}.PGUpdate|ARM.Build.0 = PGUpdate|ARM + {C6E20F84-3247-4AD6-B051-B073268F73BA}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 + {C6E20F84-3247-4AD6-B051-B073268F73BA}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 + {C6E20F84-3247-4AD6-B051-B073268F73BA}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 + {C6E20F84-3247-4AD6-B051-B073268F73BA}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 + {C6E20F84-3247-4AD6-B051-B073268F73BA}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 + {C6E20F84-3247-4AD6-B051-B073268F73BA}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {C6E20F84-3247-4AD6-B051-B073268F73BA}.Release|ARM.ActiveCfg = Release|ARM + {C6E20F84-3247-4AD6-B051-B073268F73BA}.Release|ARM.Build.0 = Release|ARM + {C6E20F84-3247-4AD6-B051-B073268F73BA}.Release|ARM64.ActiveCfg = Release|ARM64 + {C6E20F84-3247-4AD6-B051-B073268F73BA}.Release|ARM64.Build.0 = Release|ARM64 + {C6E20F84-3247-4AD6-B051-B073268F73BA}.Release|Win32.ActiveCfg = Release|Win32 + {C6E20F84-3247-4AD6-B051-B073268F73BA}.Release|Win32.Build.0 = Release|Win32 + {C6E20F84-3247-4AD6-B051-B073268F73BA}.Release|x64.ActiveCfg = Release|x64 + {C6E20F84-3247-4AD6-B051-B073268F73BA}.Release|x64.Build.0 = Release|x64 + {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Debug|ARM.ActiveCfg = Debug|ARM + {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Debug|ARM.Build.0 = Debug|ARM + {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Debug|ARM64.Build.0 = Debug|ARM64 + {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Debug|Win32.ActiveCfg = Debug|Win32 + {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Debug|Win32.Build.0 = Debug|Win32 + {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Debug|x64.ActiveCfg = Debug|x64 + {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Debug|x64.Build.0 = Debug|x64 + {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM + {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGInstrument|ARM.Build.0 = PGInstrument|ARM + {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 + {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 + {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 + {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 + {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 + {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGInstrument|x64.Build.0 = PGInstrument|x64 + {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM + {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGUpdate|ARM.Build.0 = PGUpdate|ARM + {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 + {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 + {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 + {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 + {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 + {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Release|ARM.ActiveCfg = Release|ARM + {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Release|ARM.Build.0 = Release|ARM + {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Release|ARM64.ActiveCfg = Release|ARM64 + {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Release|ARM64.Build.0 = Release|ARM64 + {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Release|Win32.ActiveCfg = Release|Win32 + {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Release|Win32.Build.0 = Release|Win32 + {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Release|x64.ActiveCfg = Release|x64 + {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Release|x64.Build.0 = Release|x64 + {A840DDFB-ED50-484B-B527-B32E7CF90FD5}.Debug|ARM.ActiveCfg = Debug|ARM + {A840DDFB-ED50-484B-B527-B32E7CF90FD5}.Debug|ARM.Build.0 = Debug|ARM + {A840DDFB-ED50-484B-B527-B32E7CF90FD5}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {A840DDFB-ED50-484B-B527-B32E7CF90FD5}.Debug|ARM64.Build.0 = Debug|ARM64 + {A840DDFB-ED50-484B-B527-B32E7CF90FD5}.Debug|Win32.ActiveCfg = Debug|Win32 + {A840DDFB-ED50-484B-B527-B32E7CF90FD5}.Debug|Win32.Build.0 = Debug|Win32 + {A840DDFB-ED50-484B-B527-B32E7CF90FD5}.Debug|x64.ActiveCfg = Debug|x64 + {A840DDFB-ED50-484B-B527-B32E7CF90FD5}.Debug|x64.Build.0 = Debug|x64 + {A840DDFB-ED50-484B-B527-B32E7CF90FD5}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM + {A840DDFB-ED50-484B-B527-B32E7CF90FD5}.PGInstrument|ARM.Build.0 = PGInstrument|ARM + {A840DDFB-ED50-484B-B527-B32E7CF90FD5}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 + {A840DDFB-ED50-484B-B527-B32E7CF90FD5}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 + {A840DDFB-ED50-484B-B527-B32E7CF90FD5}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 + {A840DDFB-ED50-484B-B527-B32E7CF90FD5}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 + {A840DDFB-ED50-484B-B527-B32E7CF90FD5}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 + {A840DDFB-ED50-484B-B527-B32E7CF90FD5}.PGInstrument|x64.Build.0 = PGInstrument|x64 + {A840DDFB-ED50-484B-B527-B32E7CF90FD5}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM + {A840DDFB-ED50-484B-B527-B32E7CF90FD5}.PGUpdate|ARM.Build.0 = PGUpdate|ARM + {A840DDFB-ED50-484B-B527-B32E7CF90FD5}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 + {A840DDFB-ED50-484B-B527-B32E7CF90FD5}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 + {A840DDFB-ED50-484B-B527-B32E7CF90FD5}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 + {A840DDFB-ED50-484B-B527-B32E7CF90FD5}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 + {A840DDFB-ED50-484B-B527-B32E7CF90FD5}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 + {A840DDFB-ED50-484B-B527-B32E7CF90FD5}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {A840DDFB-ED50-484B-B527-B32E7CF90FD5}.Release|ARM.ActiveCfg = Release|ARM + {A840DDFB-ED50-484B-B527-B32E7CF90FD5}.Release|ARM.Build.0 = Release|ARM + {A840DDFB-ED50-484B-B527-B32E7CF90FD5}.Release|ARM64.ActiveCfg = Release|ARM64 + {A840DDFB-ED50-484B-B527-B32E7CF90FD5}.Release|ARM64.Build.0 = Release|ARM64 + {A840DDFB-ED50-484B-B527-B32E7CF90FD5}.Release|Win32.ActiveCfg = Release|Win32 + {A840DDFB-ED50-484B-B527-B32E7CF90FD5}.Release|Win32.Build.0 = Release|Win32 + {A840DDFB-ED50-484B-B527-B32E7CF90FD5}.Release|x64.ActiveCfg = Release|x64 + {A840DDFB-ED50-484B-B527-B32E7CF90FD5}.Release|x64.Build.0 = Release|x64 + {900342D7-516A-4469-B1AD-59A66E49A25F}.Debug|ARM.ActiveCfg = Debug|ARM + {900342D7-516A-4469-B1AD-59A66E49A25F}.Debug|ARM.Build.0 = Debug|ARM + {900342D7-516A-4469-B1AD-59A66E49A25F}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {900342D7-516A-4469-B1AD-59A66E49A25F}.Debug|ARM64.Build.0 = Debug|ARM64 + {900342D7-516A-4469-B1AD-59A66E49A25F}.Debug|Win32.ActiveCfg = Debug|Win32 + {900342D7-516A-4469-B1AD-59A66E49A25F}.Debug|Win32.Build.0 = Debug|Win32 + {900342D7-516A-4469-B1AD-59A66E49A25F}.Debug|x64.ActiveCfg = Debug|x64 + {900342D7-516A-4469-B1AD-59A66E49A25F}.Debug|x64.Build.0 = Debug|x64 + {900342D7-516A-4469-B1AD-59A66E49A25F}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM + {900342D7-516A-4469-B1AD-59A66E49A25F}.PGInstrument|ARM.Build.0 = PGInstrument|ARM + {900342D7-516A-4469-B1AD-59A66E49A25F}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 + {900342D7-516A-4469-B1AD-59A66E49A25F}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 + {900342D7-516A-4469-B1AD-59A66E49A25F}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 + {900342D7-516A-4469-B1AD-59A66E49A25F}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 + {900342D7-516A-4469-B1AD-59A66E49A25F}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 + {900342D7-516A-4469-B1AD-59A66E49A25F}.PGInstrument|x64.Build.0 = PGInstrument|x64 + {900342D7-516A-4469-B1AD-59A66E49A25F}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM + {900342D7-516A-4469-B1AD-59A66E49A25F}.PGUpdate|ARM.Build.0 = PGUpdate|ARM + {900342D7-516A-4469-B1AD-59A66E49A25F}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 + {900342D7-516A-4469-B1AD-59A66E49A25F}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 + {900342D7-516A-4469-B1AD-59A66E49A25F}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 + {900342D7-516A-4469-B1AD-59A66E49A25F}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 + {900342D7-516A-4469-B1AD-59A66E49A25F}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 + {900342D7-516A-4469-B1AD-59A66E49A25F}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {900342D7-516A-4469-B1AD-59A66E49A25F}.Release|ARM.ActiveCfg = Release|ARM + {900342D7-516A-4469-B1AD-59A66E49A25F}.Release|ARM.Build.0 = Release|ARM + {900342D7-516A-4469-B1AD-59A66E49A25F}.Release|ARM64.ActiveCfg = Release|ARM64 + {900342D7-516A-4469-B1AD-59A66E49A25F}.Release|ARM64.Build.0 = Release|ARM64 + {900342D7-516A-4469-B1AD-59A66E49A25F}.Release|Win32.ActiveCfg = Release|Win32 + {900342D7-516A-4469-B1AD-59A66E49A25F}.Release|Win32.Build.0 = Release|Win32 + {900342D7-516A-4469-B1AD-59A66E49A25F}.Release|x64.ActiveCfg = Release|x64 + {900342D7-516A-4469-B1AD-59A66E49A25F}.Release|x64.Build.0 = Release|x64 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Debug|ARM.ActiveCfg = Debug|ARM + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Debug|ARM.Build.0 = Debug|ARM + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Debug|ARM64.Build.0 = Debug|ARM64 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Debug|Win32.ActiveCfg = Debug|Win32 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Debug|Win32.Build.0 = Debug|Win32 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Debug|x64.ActiveCfg = Debug|x64 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Debug|x64.Build.0 = Debug|x64 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGInstrument|ARM.Build.0 = PGInstrument|ARM + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGInstrument|Win32.ActiveCfg = Release|Win32 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGInstrument|Win32.Build.0 = Release|Win32 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGInstrument|x64.ActiveCfg = Release|x64 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGInstrument|x64.Build.0 = Release|x64 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGUpdate|ARM.Build.0 = PGUpdate|ARM + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGUpdate|Win32.ActiveCfg = Release|Win32 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGUpdate|Win32.Build.0 = Release|Win32 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGUpdate|x64.ActiveCfg = Release|x64 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGUpdate|x64.Build.0 = Release|x64 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Release|ARM.ActiveCfg = Release|ARM + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Release|ARM.Build.0 = Release|ARM + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Release|ARM64.ActiveCfg = Release|ARM64 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Release|ARM64.Build.0 = Release|ARM64 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Release|Win32.ActiveCfg = Release|Win32 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Release|Win32.Build.0 = Release|Win32 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Release|x64.ActiveCfg = Release|x64 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Release|x64.Build.0 = Release|x64 + {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Debug|ARM.ActiveCfg = Debug|ARM + {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Debug|Win32.ActiveCfg = Debug|Win32 + {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Debug|Win32.Build.0 = Debug|Win32 + {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Debug|x64.ActiveCfg = Debug|x64 + {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Debug|x64.Build.0 = Debug|x64 + {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM + {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGInstrument|ARM.Build.0 = PGInstrument|ARM + {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 + {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 + {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 + {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 + {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 + {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGInstrument|x64.Build.0 = PGInstrument|x64 + {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM + {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGUpdate|ARM.Build.0 = PGUpdate|ARM + {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 + {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 + {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 + {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 + {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 + {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Release|ARM.ActiveCfg = Release|ARM + {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Release|ARM64.ActiveCfg = Release|ARM64 + {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Release|Win32.ActiveCfg = Release|Win32 + {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Release|Win32.Build.0 = Release|Win32 + {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Release|x64.ActiveCfg = Release|x64 + {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Release|x64.Build.0 = Release|x64 + {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Debug|ARM.ActiveCfg = Debug|ARM + {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Debug|ARM.Build.0 = Debug|ARM + {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Debug|ARM64.Build.0 = Debug|ARM64 + {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Debug|Win32.ActiveCfg = Debug|Win32 + {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Debug|Win32.Build.0 = Debug|Win32 + {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Debug|x64.ActiveCfg = Debug|x64 + {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Debug|x64.Build.0 = Debug|x64 + {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM + {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGInstrument|ARM.Build.0 = PGInstrument|ARM + {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 + {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 + {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 + {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 + {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 + {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGInstrument|x64.Build.0 = PGInstrument|x64 + {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM + {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGUpdate|ARM.Build.0 = PGUpdate|ARM + {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 + {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 + {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 + {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 + {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 + {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Release|ARM.ActiveCfg = Release|ARM + {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Release|ARM.Build.0 = Release|ARM + {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Release|ARM64.ActiveCfg = Release|ARM64 + {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Release|ARM64.Build.0 = Release|ARM64 + {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Release|Win32.ActiveCfg = Release|Win32 + {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Release|Win32.Build.0 = Release|Win32 + {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Release|x64.ActiveCfg = Release|x64 + {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Release|x64.Build.0 = Release|x64 + {18CAE28C-B454-46C1-87A0-493D91D97F03}.Debug|ARM.ActiveCfg = Debug|ARM + {18CAE28C-B454-46C1-87A0-493D91D97F03}.Debug|ARM.Build.0 = Debug|ARM + {18CAE28C-B454-46C1-87A0-493D91D97F03}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {18CAE28C-B454-46C1-87A0-493D91D97F03}.Debug|ARM64.Build.0 = Debug|ARM64 + {18CAE28C-B454-46C1-87A0-493D91D97F03}.Debug|Win32.ActiveCfg = Debug|Win32 + {18CAE28C-B454-46C1-87A0-493D91D97F03}.Debug|Win32.Build.0 = Debug|Win32 + {18CAE28C-B454-46C1-87A0-493D91D97F03}.Debug|x64.ActiveCfg = Debug|x64 + {18CAE28C-B454-46C1-87A0-493D91D97F03}.Debug|x64.Build.0 = Debug|x64 + {18CAE28C-B454-46C1-87A0-493D91D97F03}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM + {18CAE28C-B454-46C1-87A0-493D91D97F03}.PGInstrument|ARM.Build.0 = PGInstrument|ARM + {18CAE28C-B454-46C1-87A0-493D91D97F03}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 + {18CAE28C-B454-46C1-87A0-493D91D97F03}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 + {18CAE28C-B454-46C1-87A0-493D91D97F03}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 + {18CAE28C-B454-46C1-87A0-493D91D97F03}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 + {18CAE28C-B454-46C1-87A0-493D91D97F03}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 + {18CAE28C-B454-46C1-87A0-493D91D97F03}.PGInstrument|x64.Build.0 = PGInstrument|x64 + {18CAE28C-B454-46C1-87A0-493D91D97F03}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM + {18CAE28C-B454-46C1-87A0-493D91D97F03}.PGUpdate|ARM.Build.0 = PGUpdate|ARM + {18CAE28C-B454-46C1-87A0-493D91D97F03}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 + {18CAE28C-B454-46C1-87A0-493D91D97F03}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 + {18CAE28C-B454-46C1-87A0-493D91D97F03}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 + {18CAE28C-B454-46C1-87A0-493D91D97F03}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 + {18CAE28C-B454-46C1-87A0-493D91D97F03}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 + {18CAE28C-B454-46C1-87A0-493D91D97F03}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {18CAE28C-B454-46C1-87A0-493D91D97F03}.Release|ARM.ActiveCfg = Release|ARM + {18CAE28C-B454-46C1-87A0-493D91D97F03}.Release|ARM.Build.0 = Release|ARM + {18CAE28C-B454-46C1-87A0-493D91D97F03}.Release|ARM64.ActiveCfg = Release|ARM64 + {18CAE28C-B454-46C1-87A0-493D91D97F03}.Release|ARM64.Build.0 = Release|ARM64 + {18CAE28C-B454-46C1-87A0-493D91D97F03}.Release|Win32.ActiveCfg = Release|Win32 + {18CAE28C-B454-46C1-87A0-493D91D97F03}.Release|Win32.Build.0 = Release|Win32 + {18CAE28C-B454-46C1-87A0-493D91D97F03}.Release|x64.ActiveCfg = Release|x64 + {18CAE28C-B454-46C1-87A0-493D91D97F03}.Release|x64.Build.0 = Release|x64 + {F9D71780-F393-11E0-BE50-0800200C9A66}.Debug|ARM.ActiveCfg = Debug|ARM + {F9D71780-F393-11E0-BE50-0800200C9A66}.Debug|ARM.Build.0 = Debug|ARM + {F9D71780-F393-11E0-BE50-0800200C9A66}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {F9D71780-F393-11E0-BE50-0800200C9A66}.Debug|ARM64.Build.0 = Debug|ARM64 + {F9D71780-F393-11E0-BE50-0800200C9A66}.Debug|Win32.ActiveCfg = Debug|Win32 + {F9D71780-F393-11E0-BE50-0800200C9A66}.Debug|Win32.Build.0 = Debug|Win32 + {F9D71780-F393-11E0-BE50-0800200C9A66}.Debug|x64.ActiveCfg = Debug|x64 + {F9D71780-F393-11E0-BE50-0800200C9A66}.Debug|x64.Build.0 = Debug|x64 + {F9D71780-F393-11E0-BE50-0800200C9A66}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM + {F9D71780-F393-11E0-BE50-0800200C9A66}.PGInstrument|ARM.Build.0 = PGInstrument|ARM + {F9D71780-F393-11E0-BE50-0800200C9A66}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 + {F9D71780-F393-11E0-BE50-0800200C9A66}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 + {F9D71780-F393-11E0-BE50-0800200C9A66}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 + {F9D71780-F393-11E0-BE50-0800200C9A66}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 + {F9D71780-F393-11E0-BE50-0800200C9A66}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 + {F9D71780-F393-11E0-BE50-0800200C9A66}.PGInstrument|x64.Build.0 = PGInstrument|x64 + {F9D71780-F393-11E0-BE50-0800200C9A66}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM + {F9D71780-F393-11E0-BE50-0800200C9A66}.PGUpdate|ARM.Build.0 = PGUpdate|ARM + {F9D71780-F393-11E0-BE50-0800200C9A66}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 + {F9D71780-F393-11E0-BE50-0800200C9A66}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 + {F9D71780-F393-11E0-BE50-0800200C9A66}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 + {F9D71780-F393-11E0-BE50-0800200C9A66}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 + {F9D71780-F393-11E0-BE50-0800200C9A66}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 + {F9D71780-F393-11E0-BE50-0800200C9A66}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {F9D71780-F393-11E0-BE50-0800200C9A66}.Release|ARM.ActiveCfg = Release|ARM + {F9D71780-F393-11E0-BE50-0800200C9A66}.Release|ARM.Build.0 = Release|ARM + {F9D71780-F393-11E0-BE50-0800200C9A66}.Release|ARM64.ActiveCfg = Release|ARM64 + {F9D71780-F393-11E0-BE50-0800200C9A66}.Release|ARM64.Build.0 = Release|ARM64 + {F9D71780-F393-11E0-BE50-0800200C9A66}.Release|Win32.ActiveCfg = Release|Win32 + {F9D71780-F393-11E0-BE50-0800200C9A66}.Release|Win32.Build.0 = Release|Win32 + {F9D71780-F393-11E0-BE50-0800200C9A66}.Release|x64.ActiveCfg = Release|x64 + {F9D71780-F393-11E0-BE50-0800200C9A66}.Release|x64.Build.0 = Release|x64 + {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Debug|ARM.ActiveCfg = Debug|ARM + {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Debug|ARM.Build.0 = Debug|ARM + {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Debug|ARM64.Build.0 = Debug|ARM64 + {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Debug|Win32.ActiveCfg = Debug|Win32 + {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Debug|Win32.Build.0 = Debug|Win32 + {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Debug|x64.ActiveCfg = Debug|x64 + {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Debug|x64.Build.0 = Debug|x64 + {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM + {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGInstrument|ARM.Build.0 = PGInstrument|ARM + {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 + {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 + {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 + {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 + {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 + {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGInstrument|x64.Build.0 = PGInstrument|x64 + {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM + {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGUpdate|ARM.Build.0 = PGUpdate|ARM + {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 + {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 + {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 + {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 + {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 + {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Release|ARM.ActiveCfg = Release|ARM + {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Release|ARM.Build.0 = Release|ARM + {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Release|ARM64.ActiveCfg = Release|ARM64 + {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Release|ARM64.Build.0 = Release|ARM64 + {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Release|Win32.ActiveCfg = Release|Win32 + {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Release|Win32.Build.0 = Release|Win32 + {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Release|x64.ActiveCfg = Release|x64 + {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Release|x64.Build.0 = Release|x64 + {D06B6426-4762-44CC-8BAD-D79052507F2F}.Debug|ARM.ActiveCfg = Debug|ARM + {D06B6426-4762-44CC-8BAD-D79052507F2F}.Debug|ARM.Build.0 = Debug|ARM + {D06B6426-4762-44CC-8BAD-D79052507F2F}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {D06B6426-4762-44CC-8BAD-D79052507F2F}.Debug|ARM64.Build.0 = Debug|ARM64 + {D06B6426-4762-44CC-8BAD-D79052507F2F}.Debug|Win32.ActiveCfg = Debug|Win32 + {D06B6426-4762-44CC-8BAD-D79052507F2F}.Debug|Win32.Build.0 = Debug|Win32 + {D06B6426-4762-44CC-8BAD-D79052507F2F}.Debug|x64.ActiveCfg = Debug|x64 + {D06B6426-4762-44CC-8BAD-D79052507F2F}.Debug|x64.Build.0 = Debug|x64 + {D06B6426-4762-44CC-8BAD-D79052507F2F}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM + {D06B6426-4762-44CC-8BAD-D79052507F2F}.PGInstrument|ARM.Build.0 = PGInstrument|ARM + {D06B6426-4762-44CC-8BAD-D79052507F2F}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 + {D06B6426-4762-44CC-8BAD-D79052507F2F}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 + {D06B6426-4762-44CC-8BAD-D79052507F2F}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 + {D06B6426-4762-44CC-8BAD-D79052507F2F}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 + {D06B6426-4762-44CC-8BAD-D79052507F2F}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 + {D06B6426-4762-44CC-8BAD-D79052507F2F}.PGInstrument|x64.Build.0 = PGInstrument|x64 + {D06B6426-4762-44CC-8BAD-D79052507F2F}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM + {D06B6426-4762-44CC-8BAD-D79052507F2F}.PGUpdate|ARM.Build.0 = PGUpdate|ARM + {D06B6426-4762-44CC-8BAD-D79052507F2F}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 + {D06B6426-4762-44CC-8BAD-D79052507F2F}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 + {D06B6426-4762-44CC-8BAD-D79052507F2F}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 + {D06B6426-4762-44CC-8BAD-D79052507F2F}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 + {D06B6426-4762-44CC-8BAD-D79052507F2F}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 + {D06B6426-4762-44CC-8BAD-D79052507F2F}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {D06B6426-4762-44CC-8BAD-D79052507F2F}.Release|ARM.ActiveCfg = Release|ARM + {D06B6426-4762-44CC-8BAD-D79052507F2F}.Release|ARM.Build.0 = Release|ARM + {D06B6426-4762-44CC-8BAD-D79052507F2F}.Release|ARM64.ActiveCfg = Release|ARM64 + {D06B6426-4762-44CC-8BAD-D79052507F2F}.Release|ARM64.Build.0 = Release|ARM64 + {D06B6426-4762-44CC-8BAD-D79052507F2F}.Release|Win32.ActiveCfg = Release|Win32 + {D06B6426-4762-44CC-8BAD-D79052507F2F}.Release|Win32.Build.0 = Release|Win32 + {D06B6426-4762-44CC-8BAD-D79052507F2F}.Release|x64.ActiveCfg = Release|x64 + {D06B6426-4762-44CC-8BAD-D79052507F2F}.Release|x64.Build.0 = Release|x64 + {447F05A8-F581-4CAC-A466-5AC7936E207E}.Debug|ARM.ActiveCfg = Debug|ARM + {447F05A8-F581-4CAC-A466-5AC7936E207E}.Debug|ARM.Build.0 = Debug|ARM + {447F05A8-F581-4CAC-A466-5AC7936E207E}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {447F05A8-F581-4CAC-A466-5AC7936E207E}.Debug|ARM64.Build.0 = Debug|ARM64 + {447F05A8-F581-4CAC-A466-5AC7936E207E}.Debug|Win32.ActiveCfg = Debug|Win32 + {447F05A8-F581-4CAC-A466-5AC7936E207E}.Debug|Win32.Build.0 = Debug|Win32 + {447F05A8-F581-4CAC-A466-5AC7936E207E}.Debug|x64.ActiveCfg = Debug|x64 + {447F05A8-F581-4CAC-A466-5AC7936E207E}.Debug|x64.Build.0 = Debug|x64 + {447F05A8-F581-4CAC-A466-5AC7936E207E}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM + {447F05A8-F581-4CAC-A466-5AC7936E207E}.PGInstrument|ARM.Build.0 = PGInstrument|ARM + {447F05A8-F581-4CAC-A466-5AC7936E207E}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 + {447F05A8-F581-4CAC-A466-5AC7936E207E}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 + {447F05A8-F581-4CAC-A466-5AC7936E207E}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 + {447F05A8-F581-4CAC-A466-5AC7936E207E}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 + {447F05A8-F581-4CAC-A466-5AC7936E207E}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 + {447F05A8-F581-4CAC-A466-5AC7936E207E}.PGInstrument|x64.Build.0 = PGInstrument|x64 + {447F05A8-F581-4CAC-A466-5AC7936E207E}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM + {447F05A8-F581-4CAC-A466-5AC7936E207E}.PGUpdate|ARM.Build.0 = PGUpdate|ARM + {447F05A8-F581-4CAC-A466-5AC7936E207E}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 + {447F05A8-F581-4CAC-A466-5AC7936E207E}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 + {447F05A8-F581-4CAC-A466-5AC7936E207E}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 + {447F05A8-F581-4CAC-A466-5AC7936E207E}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 + {447F05A8-F581-4CAC-A466-5AC7936E207E}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 + {447F05A8-F581-4CAC-A466-5AC7936E207E}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {447F05A8-F581-4CAC-A466-5AC7936E207E}.Release|ARM.ActiveCfg = Release|ARM + {447F05A8-F581-4CAC-A466-5AC7936E207E}.Release|ARM.Build.0 = Release|ARM + {447F05A8-F581-4CAC-A466-5AC7936E207E}.Release|ARM64.ActiveCfg = Release|ARM64 + {447F05A8-F581-4CAC-A466-5AC7936E207E}.Release|ARM64.Build.0 = Release|ARM64 + {447F05A8-F581-4CAC-A466-5AC7936E207E}.Release|Win32.ActiveCfg = Release|Win32 + {447F05A8-F581-4CAC-A466-5AC7936E207E}.Release|Win32.Build.0 = Release|Win32 + {447F05A8-F581-4CAC-A466-5AC7936E207E}.Release|x64.ActiveCfg = Release|x64 + {447F05A8-F581-4CAC-A466-5AC7936E207E}.Release|x64.Build.0 = Release|x64 + {A1A295E5-463C-437F-81CA-1F32367685DA}.Debug|ARM.ActiveCfg = Debug|ARM + {A1A295E5-463C-437F-81CA-1F32367685DA}.Debug|ARM.Build.0 = Debug|ARM + {A1A295E5-463C-437F-81CA-1F32367685DA}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {A1A295E5-463C-437F-81CA-1F32367685DA}.Debug|ARM64.Build.0 = Debug|ARM64 + {A1A295E5-463C-437F-81CA-1F32367685DA}.Debug|Win32.ActiveCfg = Debug|Win32 + {A1A295E5-463C-437F-81CA-1F32367685DA}.Debug|Win32.Build.0 = Debug|Win32 + {A1A295E5-463C-437F-81CA-1F32367685DA}.Debug|x64.ActiveCfg = Debug|x64 + {A1A295E5-463C-437F-81CA-1F32367685DA}.Debug|x64.Build.0 = Debug|x64 + {A1A295E5-463C-437F-81CA-1F32367685DA}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM + {A1A295E5-463C-437F-81CA-1F32367685DA}.PGInstrument|ARM.Build.0 = PGInstrument|ARM + {A1A295E5-463C-437F-81CA-1F32367685DA}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 + {A1A295E5-463C-437F-81CA-1F32367685DA}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 + {A1A295E5-463C-437F-81CA-1F32367685DA}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 + {A1A295E5-463C-437F-81CA-1F32367685DA}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 + {A1A295E5-463C-437F-81CA-1F32367685DA}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 + {A1A295E5-463C-437F-81CA-1F32367685DA}.PGInstrument|x64.Build.0 = PGInstrument|x64 + {A1A295E5-463C-437F-81CA-1F32367685DA}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM + {A1A295E5-463C-437F-81CA-1F32367685DA}.PGUpdate|ARM.Build.0 = PGUpdate|ARM + {A1A295E5-463C-437F-81CA-1F32367685DA}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 + {A1A295E5-463C-437F-81CA-1F32367685DA}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 + {A1A295E5-463C-437F-81CA-1F32367685DA}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 + {A1A295E5-463C-437F-81CA-1F32367685DA}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 + {A1A295E5-463C-437F-81CA-1F32367685DA}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 + {A1A295E5-463C-437F-81CA-1F32367685DA}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {A1A295E5-463C-437F-81CA-1F32367685DA}.Release|ARM.ActiveCfg = Release|ARM + {A1A295E5-463C-437F-81CA-1F32367685DA}.Release|ARM.Build.0 = Release|ARM + {A1A295E5-463C-437F-81CA-1F32367685DA}.Release|ARM64.ActiveCfg = Release|ARM64 + {A1A295E5-463C-437F-81CA-1F32367685DA}.Release|ARM64.Build.0 = Release|ARM64 + {A1A295E5-463C-437F-81CA-1F32367685DA}.Release|Win32.ActiveCfg = Release|Win32 + {A1A295E5-463C-437F-81CA-1F32367685DA}.Release|Win32.Build.0 = Release|Win32 + {A1A295E5-463C-437F-81CA-1F32367685DA}.Release|x64.ActiveCfg = Release|x64 + {A1A295E5-463C-437F-81CA-1F32367685DA}.Release|x64.Build.0 = Release|x64 + {9E48B300-37D1-11DD-8C41-005056C00008}.Debug|ARM.ActiveCfg = Debug|ARM + {9E48B300-37D1-11DD-8C41-005056C00008}.Debug|ARM.Build.0 = Debug|ARM + {9E48B300-37D1-11DD-8C41-005056C00008}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {9E48B300-37D1-11DD-8C41-005056C00008}.Debug|ARM64.Build.0 = Debug|ARM64 + {9E48B300-37D1-11DD-8C41-005056C00008}.Debug|Win32.ActiveCfg = Debug|Win32 + {9E48B300-37D1-11DD-8C41-005056C00008}.Debug|Win32.Build.0 = Debug|Win32 + {9E48B300-37D1-11DD-8C41-005056C00008}.Debug|x64.ActiveCfg = Debug|x64 + {9E48B300-37D1-11DD-8C41-005056C00008}.Debug|x64.Build.0 = Debug|x64 + {9E48B300-37D1-11DD-8C41-005056C00008}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM + {9E48B300-37D1-11DD-8C41-005056C00008}.PGInstrument|ARM.Build.0 = PGInstrument|ARM + {9E48B300-37D1-11DD-8C41-005056C00008}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 + {9E48B300-37D1-11DD-8C41-005056C00008}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 + {9E48B300-37D1-11DD-8C41-005056C00008}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 + {9E48B300-37D1-11DD-8C41-005056C00008}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 + {9E48B300-37D1-11DD-8C41-005056C00008}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 + {9E48B300-37D1-11DD-8C41-005056C00008}.PGInstrument|x64.Build.0 = PGInstrument|x64 + {9E48B300-37D1-11DD-8C41-005056C00008}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM + {9E48B300-37D1-11DD-8C41-005056C00008}.PGUpdate|ARM.Build.0 = PGUpdate|ARM + {9E48B300-37D1-11DD-8C41-005056C00008}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 + {9E48B300-37D1-11DD-8C41-005056C00008}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 + {9E48B300-37D1-11DD-8C41-005056C00008}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 + {9E48B300-37D1-11DD-8C41-005056C00008}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 + {9E48B300-37D1-11DD-8C41-005056C00008}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 + {9E48B300-37D1-11DD-8C41-005056C00008}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {9E48B300-37D1-11DD-8C41-005056C00008}.Release|ARM.ActiveCfg = Release|ARM + {9E48B300-37D1-11DD-8C41-005056C00008}.Release|ARM.Build.0 = Release|ARM + {9E48B300-37D1-11DD-8C41-005056C00008}.Release|ARM64.ActiveCfg = Release|ARM64 + {9E48B300-37D1-11DD-8C41-005056C00008}.Release|ARM64.Build.0 = Release|ARM64 + {9E48B300-37D1-11DD-8C41-005056C00008}.Release|Win32.ActiveCfg = Release|Win32 + {9E48B300-37D1-11DD-8C41-005056C00008}.Release|Win32.Build.0 = Release|Win32 + {9E48B300-37D1-11DD-8C41-005056C00008}.Release|x64.ActiveCfg = Release|x64 + {9E48B300-37D1-11DD-8C41-005056C00008}.Release|x64.Build.0 = Release|x64 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Debug|ARM.ActiveCfg = Debug|ARM + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Debug|ARM.Build.0 = Debug|ARM + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Debug|ARM64.Build.0 = Debug|ARM64 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Debug|Win32.ActiveCfg = Debug|Win32 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Debug|Win32.Build.0 = Debug|Win32 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Debug|x64.ActiveCfg = Debug|x64 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Debug|x64.Build.0 = Debug|x64 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|ARM.Build.0 = PGInstrument|ARM + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|Win32.ActiveCfg = Debug|Win32 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|Win32.Build.0 = Debug|Win32 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|x64.ActiveCfg = Debug|x64 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|x64.Build.0 = Debug|x64 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|ARM.Build.0 = PGUpdate|ARM + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|Win32.ActiveCfg = Debug|Win32 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|Win32.Build.0 = Debug|Win32 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|x64.ActiveCfg = Debug|x64 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|x64.Build.0 = Debug|x64 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Release|ARM.ActiveCfg = Release|ARM + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Release|ARM.Build.0 = Release|ARM + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Release|ARM64.ActiveCfg = Release|ARM64 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Release|ARM64.Build.0 = Release|ARM64 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Release|Win32.ActiveCfg = Release|Win32 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Release|Win32.Build.0 = Release|Win32 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Release|x64.ActiveCfg = Release|x64 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Release|x64.Build.0 = Release|x64 + {F749B822-B489-4CA5-A3AD-CE078F5F338A}.Debug|ARM.ActiveCfg = Debug|ARM + {F749B822-B489-4CA5-A3AD-CE078F5F338A}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {F749B822-B489-4CA5-A3AD-CE078F5F338A}.Debug|Win32.ActiveCfg = Release|Win32 + {F749B822-B489-4CA5-A3AD-CE078F5F338A}.Debug|x64.ActiveCfg = Release|x64 + {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM + {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGInstrument|ARM.Build.0 = PGInstrument|ARM + {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 + {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 + {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 + {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 + {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 + {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGInstrument|x64.Build.0 = PGInstrument|x64 + {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM + {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGUpdate|ARM.Build.0 = PGUpdate|ARM + {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 + {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 + {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 + {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 + {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGUpdate|x64.ActiveCfg = Release|x64 + {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGUpdate|x64.Build.0 = Release|x64 + {F749B822-B489-4CA5-A3AD-CE078F5F338A}.Release|ARM.ActiveCfg = Release|ARM + {F749B822-B489-4CA5-A3AD-CE078F5F338A}.Release|ARM64.ActiveCfg = Release|ARM64 + {F749B822-B489-4CA5-A3AD-CE078F5F338A}.Release|Win32.ActiveCfg = Release|Win32 + {F749B822-B489-4CA5-A3AD-CE078F5F338A}.Release|Win32.Build.0 = Release|Win32 + {F749B822-B489-4CA5-A3AD-CE078F5F338A}.Release|x64.ActiveCfg = Release|x64 + {F749B822-B489-4CA5-A3AD-CE078F5F338A}.Release|x64.Build.0 = Release|x64 + {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Debug|ARM.ActiveCfg = Debug|ARM + {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Debug|ARM.Build.0 = Debug|ARM + {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Debug|ARM64.Build.0 = Debug|ARM64 + {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Debug|Win32.ActiveCfg = Debug|Win32 + {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Debug|Win32.Build.0 = Debug|Win32 + {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Debug|x64.ActiveCfg = Debug|x64 + {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Debug|x64.Build.0 = Debug|x64 + {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM + {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGInstrument|ARM.Build.0 = PGInstrument|ARM + {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 + {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 + {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGInstrument|Win32.ActiveCfg = Release|Win32 + {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGInstrument|Win32.Build.0 = Release|Win32 + {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGInstrument|x64.ActiveCfg = Release|x64 + {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGInstrument|x64.Build.0 = Release|x64 + {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM + {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGUpdate|ARM.Build.0 = PGUpdate|ARM + {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 + {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 + {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGUpdate|Win32.ActiveCfg = Release|Win32 + {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGUpdate|Win32.Build.0 = Release|Win32 + {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGUpdate|x64.ActiveCfg = Release|x64 + {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGUpdate|x64.Build.0 = Release|x64 + {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Release|ARM.ActiveCfg = Release|ARM + {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Release|ARM.Build.0 = Release|ARM + {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Release|ARM64.ActiveCfg = Release|ARM64 + {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Release|ARM64.Build.0 = Release|ARM64 + {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Release|Win32.ActiveCfg = Release|Win32 + {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Release|Win32.Build.0 = Release|Win32 + {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Release|x64.ActiveCfg = Release|x64 + {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Release|x64.Build.0 = Release|x64 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Debug|ARM.ActiveCfg = Debug|ARM + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Debug|ARM.Build.0 = Debug|ARM + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Debug|ARM64.Build.0 = Debug|ARM64 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Debug|Win32.ActiveCfg = Debug|Win32 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Debug|Win32.Build.0 = Debug|Win32 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Debug|x64.ActiveCfg = Debug|x64 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Debug|x64.Build.0 = Debug|x64 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGInstrument|ARM.Build.0 = PGInstrument|ARM + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGInstrument|Win32.ActiveCfg = Release|Win32 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGInstrument|Win32.Build.0 = Release|Win32 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGInstrument|x64.ActiveCfg = Release|x64 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGInstrument|x64.Build.0 = Release|x64 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGUpdate|ARM.Build.0 = PGUpdate|ARM + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGUpdate|Win32.ActiveCfg = Release|Win32 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGUpdate|Win32.Build.0 = Release|Win32 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGUpdate|x64.ActiveCfg = Release|x64 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGUpdate|x64.Build.0 = Release|x64 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Release|ARM.ActiveCfg = Release|ARM + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Release|ARM.Build.0 = Release|ARM + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Release|ARM64.ActiveCfg = Release|ARM64 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Release|ARM64.Build.0 = Release|ARM64 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Release|Win32.ActiveCfg = Release|Win32 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Release|Win32.Build.0 = Release|Win32 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Release|x64.ActiveCfg = Release|x64 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Release|x64.Build.0 = Release|x64 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Debug|ARM.ActiveCfg = Debug|ARM + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Debug|ARM.Build.0 = Debug|ARM + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Debug|ARM64.Build.0 = Debug|ARM64 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Debug|Win32.ActiveCfg = Debug|Win32 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Debug|Win32.Build.0 = Debug|Win32 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Debug|x64.ActiveCfg = Debug|x64 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Debug|x64.Build.0 = Debug|x64 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGInstrument|ARM.Build.0 = PGInstrument|ARM + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGInstrument|Win32.ActiveCfg = Release|Win32 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGInstrument|Win32.Build.0 = Release|Win32 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGInstrument|x64.ActiveCfg = Release|x64 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGInstrument|x64.Build.0 = Release|x64 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGUpdate|ARM.Build.0 = PGUpdate|ARM + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGUpdate|Win32.ActiveCfg = Release|Win32 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGUpdate|Win32.Build.0 = Release|Win32 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGUpdate|x64.ActiveCfg = Release|x64 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGUpdate|x64.Build.0 = Release|x64 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Release|ARM.ActiveCfg = Release|ARM + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Release|ARM.Build.0 = Release|ARM + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Release|ARM64.ActiveCfg = Release|ARM64 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Release|ARM64.Build.0 = Release|ARM64 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Release|Win32.ActiveCfg = Release|Win32 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Release|Win32.Build.0 = Release|Win32 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Release|x64.ActiveCfg = Release|x64 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Release|x64.Build.0 = Release|x64 + {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Debug|ARM.ActiveCfg = Debug|Win32 + {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Debug|ARM.Build.0 = Debug|Win32 + {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Debug|ARM64.ActiveCfg = Debug|x64 + {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Debug|ARM64.Build.0 = Debug|x64 + {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Debug|Win32.ActiveCfg = Debug|Win32 + {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Debug|Win32.Build.0 = Debug|Win32 + {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Debug|x64.ActiveCfg = Debug|x64 + {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Debug|x64.Build.0 = Debug|x64 + {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.PGInstrument|ARM.ActiveCfg = Release|Win32 + {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.PGInstrument|ARM.Build.0 = Release|Win32 + {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.PGInstrument|ARM64.ActiveCfg = Release|x64 + {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.PGInstrument|ARM64.Build.0 = Release|x64 + {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.PGInstrument|Win32.ActiveCfg = Release|Win32 + {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.PGInstrument|Win32.Build.0 = Release|Win32 + {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.PGInstrument|x64.ActiveCfg = Release|x64 + {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.PGInstrument|x64.Build.0 = Release|x64 + {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.PGUpdate|ARM.ActiveCfg = Release|Win32 + {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.PGUpdate|ARM64.ActiveCfg = Release|x64 + {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.PGUpdate|Win32.ActiveCfg = Release|Win32 + {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.PGUpdate|x64.ActiveCfg = Release|x64 + {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Release|ARM.ActiveCfg = Release|Win32 + {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Release|ARM.Build.0 = Release|Win32 + {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Release|ARM64.ActiveCfg = Release|x64 + {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Release|ARM64.Build.0 = Release|x64 + {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Release|Win32.ActiveCfg = Release|Win32 + {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Release|Win32.Build.0 = Release|Win32 + {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Release|x64.ActiveCfg = Release|x64 + {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Release|x64.Build.0 = Release|x64 + {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.Debug|ARM.ActiveCfg = Debug|ARM + {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.Debug|ARM.Build.0 = Debug|ARM + {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.Debug|ARM64.Build.0 = Debug|ARM64 + {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.Debug|Win32.ActiveCfg = Debug|Win32 + {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.Debug|Win32.Build.0 = Debug|Win32 + {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.Debug|x64.ActiveCfg = Debug|x64 + {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.Debug|x64.Build.0 = Debug|x64 + {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM + {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.PGInstrument|ARM.Build.0 = PGInstrument|ARM + {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 + {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 + {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 + {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 + {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 + {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.PGInstrument|x64.Build.0 = PGInstrument|x64 + {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM + {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.PGUpdate|ARM.Build.0 = PGUpdate|ARM + {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 + {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 + {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 + {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 + {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 + {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.Release|ARM.ActiveCfg = Release|ARM + {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.Release|ARM.Build.0 = Release|ARM + {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.Release|ARM64.ActiveCfg = Release|ARM64 + {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.Release|ARM64.Build.0 = Release|ARM64 + {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.Release|Win32.ActiveCfg = Release|Win32 + {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.Release|Win32.Build.0 = Release|Win32 + {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.Release|x64.ActiveCfg = Release|x64 + {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.Release|x64.Build.0 = Release|x64 + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Debug|ARM.ActiveCfg = Debug|ARM + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Debug|ARM.Build.0 = Debug|ARM + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Debug|ARM64.Build.0 = Debug|ARM64 + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Debug|Win32.ActiveCfg = Debug|Win32 + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Debug|Win32.Build.0 = Debug|Win32 + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Debug|x64.ActiveCfg = Debug|x64 + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Debug|x64.Build.0 = Debug|x64 + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.PGInstrument|ARM.Build.0 = PGInstrument|ARM + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.PGInstrument|Win32.ActiveCfg = Release|Win32 + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.PGInstrument|x64.ActiveCfg = Release|x64 + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.PGUpdate|ARM.Build.0 = PGUpdate|ARM + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.PGUpdate|Win32.ActiveCfg = Release|Win32 + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.PGUpdate|Win32.Build.0 = Release|Win32 + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.PGUpdate|x64.ActiveCfg = Release|x64 + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.PGUpdate|x64.Build.0 = Release|x64 + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Release|ARM.ActiveCfg = Release|ARM + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Release|ARM.Build.0 = Release|ARM + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Release|ARM64.ActiveCfg = Release|ARM64 + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Release|ARM64.Build.0 = Release|ARM64 + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Release|Win32.ActiveCfg = Release|Win32 + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Release|Win32.Build.0 = Release|Win32 + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Release|x64.ActiveCfg = Release|x64 + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Release|x64.Build.0 = Release|x64 + {16BFE6F0-22EF-40B5-B831-7E937119EF10}.Debug|ARM.ActiveCfg = Debug|ARM + {16BFE6F0-22EF-40B5-B831-7E937119EF10}.Debug|ARM.Build.0 = Debug|ARM + {16BFE6F0-22EF-40B5-B831-7E937119EF10}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {16BFE6F0-22EF-40B5-B831-7E937119EF10}.Debug|ARM64.Build.0 = Debug|ARM64 + {16BFE6F0-22EF-40B5-B831-7E937119EF10}.Debug|Win32.ActiveCfg = Debug|Win32 + {16BFE6F0-22EF-40B5-B831-7E937119EF10}.Debug|Win32.Build.0 = Debug|Win32 + {16BFE6F0-22EF-40B5-B831-7E937119EF10}.Debug|x64.ActiveCfg = Debug|x64 + {16BFE6F0-22EF-40B5-B831-7E937119EF10}.Debug|x64.Build.0 = Debug|x64 + {16BFE6F0-22EF-40B5-B831-7E937119EF10}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM + {16BFE6F0-22EF-40B5-B831-7E937119EF10}.PGInstrument|ARM.Build.0 = PGInstrument|ARM + {16BFE6F0-22EF-40B5-B831-7E937119EF10}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 + {16BFE6F0-22EF-40B5-B831-7E937119EF10}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 + {16BFE6F0-22EF-40B5-B831-7E937119EF10}.PGInstrument|Win32.ActiveCfg = Release|Win32 + {16BFE6F0-22EF-40B5-B831-7E937119EF10}.PGInstrument|x64.ActiveCfg = Release|x64 + {16BFE6F0-22EF-40B5-B831-7E937119EF10}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM + {16BFE6F0-22EF-40B5-B831-7E937119EF10}.PGUpdate|ARM.Build.0 = PGUpdate|ARM + {16BFE6F0-22EF-40B5-B831-7E937119EF10}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 + {16BFE6F0-22EF-40B5-B831-7E937119EF10}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 + {16BFE6F0-22EF-40B5-B831-7E937119EF10}.PGUpdate|Win32.ActiveCfg = Release|Win32 + {16BFE6F0-22EF-40B5-B831-7E937119EF10}.PGUpdate|Win32.Build.0 = Release|Win32 + {16BFE6F0-22EF-40B5-B831-7E937119EF10}.PGUpdate|x64.ActiveCfg = Release|x64 + {16BFE6F0-22EF-40B5-B831-7E937119EF10}.PGUpdate|x64.Build.0 = Release|x64 + {16BFE6F0-22EF-40B5-B831-7E937119EF10}.Release|ARM.ActiveCfg = Release|ARM + {16BFE6F0-22EF-40B5-B831-7E937119EF10}.Release|ARM.Build.0 = Release|ARM + {16BFE6F0-22EF-40B5-B831-7E937119EF10}.Release|ARM64.ActiveCfg = Release|ARM64 + {16BFE6F0-22EF-40B5-B831-7E937119EF10}.Release|ARM64.Build.0 = Release|ARM64 + {16BFE6F0-22EF-40B5-B831-7E937119EF10}.Release|Win32.ActiveCfg = Release|Win32 + {16BFE6F0-22EF-40B5-B831-7E937119EF10}.Release|Win32.Build.0 = Release|Win32 + {16BFE6F0-22EF-40B5-B831-7E937119EF10}.Release|x64.ActiveCfg = Release|x64 + {16BFE6F0-22EF-40B5-B831-7E937119EF10}.Release|x64.Build.0 = Release|x64 + {2097F1C1-597C-4167-93E3-656A7D6339B2}.Debug|ARM.ActiveCfg = Debug|ARM + {2097F1C1-597C-4167-93E3-656A7D6339B2}.Debug|ARM.Build.0 = Debug|ARM + {2097F1C1-597C-4167-93E3-656A7D6339B2}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {2097F1C1-597C-4167-93E3-656A7D6339B2}.Debug|ARM64.Build.0 = Debug|ARM64 + {2097F1C1-597C-4167-93E3-656A7D6339B2}.Debug|Win32.ActiveCfg = Debug|Win32 + {2097F1C1-597C-4167-93E3-656A7D6339B2}.Debug|Win32.Build.0 = Debug|Win32 + {2097F1C1-597C-4167-93E3-656A7D6339B2}.Debug|x64.ActiveCfg = Debug|x64 + {2097F1C1-597C-4167-93E3-656A7D6339B2}.Debug|x64.Build.0 = Debug|x64 + {2097F1C1-597C-4167-93E3-656A7D6339B2}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM + {2097F1C1-597C-4167-93E3-656A7D6339B2}.PGInstrument|ARM.Build.0 = PGInstrument|ARM + {2097F1C1-597C-4167-93E3-656A7D6339B2}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 + {2097F1C1-597C-4167-93E3-656A7D6339B2}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 + {2097F1C1-597C-4167-93E3-656A7D6339B2}.PGInstrument|Win32.ActiveCfg = Release|Win32 + {2097F1C1-597C-4167-93E3-656A7D6339B2}.PGInstrument|x64.ActiveCfg = Release|x64 + {2097F1C1-597C-4167-93E3-656A7D6339B2}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM + {2097F1C1-597C-4167-93E3-656A7D6339B2}.PGUpdate|ARM.Build.0 = PGUpdate|ARM + {2097F1C1-597C-4167-93E3-656A7D6339B2}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 + {2097F1C1-597C-4167-93E3-656A7D6339B2}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 + {2097F1C1-597C-4167-93E3-656A7D6339B2}.PGUpdate|Win32.ActiveCfg = Release|Win32 + {2097F1C1-597C-4167-93E3-656A7D6339B2}.PGUpdate|Win32.Build.0 = Release|Win32 + {2097F1C1-597C-4167-93E3-656A7D6339B2}.PGUpdate|x64.ActiveCfg = Release|x64 + {2097F1C1-597C-4167-93E3-656A7D6339B2}.PGUpdate|x64.Build.0 = Release|x64 + {2097F1C1-597C-4167-93E3-656A7D6339B2}.Release|ARM.ActiveCfg = Release|ARM + {2097F1C1-597C-4167-93E3-656A7D6339B2}.Release|ARM.Build.0 = Release|ARM + {2097F1C1-597C-4167-93E3-656A7D6339B2}.Release|ARM64.ActiveCfg = Release|ARM64 + {2097F1C1-597C-4167-93E3-656A7D6339B2}.Release|ARM64.Build.0 = Release|ARM64 + {2097F1C1-597C-4167-93E3-656A7D6339B2}.Release|Win32.ActiveCfg = Release|Win32 + {2097F1C1-597C-4167-93E3-656A7D6339B2}.Release|Win32.Build.0 = Release|Win32 + {2097F1C1-597C-4167-93E3-656A7D6339B2}.Release|x64.ActiveCfg = Release|x64 + {2097F1C1-597C-4167-93E3-656A7D6339B2}.Release|x64.Build.0 = Release|x64 + {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Debug|ARM.ActiveCfg = Debug|ARM + {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Debug|ARM.Build.0 = Debug|ARM + {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Debug|ARM64.Build.0 = Debug|ARM64 + {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Debug|Win32.ActiveCfg = Debug|Win32 + {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Debug|Win32.Build.0 = Debug|Win32 + {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Debug|x64.ActiveCfg = Debug|x64 + {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Debug|x64.Build.0 = Debug|x64 + {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM + {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGInstrument|ARM.Build.0 = PGInstrument|ARM + {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 + {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 + {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 + {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 + {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 + {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGInstrument|x64.Build.0 = PGInstrument|x64 + {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM + {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGUpdate|ARM.Build.0 = PGUpdate|ARM + {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 + {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 + {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 + {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 + {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 + {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Release|ARM.ActiveCfg = Release|ARM + {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Release|ARM.Build.0 = Release|ARM + {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Release|ARM64.ActiveCfg = Release|ARM64 + {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Release|ARM64.Build.0 = Release|ARM64 + {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Release|Win32.ActiveCfg = Release|Win32 + {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Release|Win32.Build.0 = Release|Win32 + {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Release|x64.ActiveCfg = Release|x64 + {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Release|x64.Build.0 = Release|x64 + {B244E787-C445-441C-BDF4-5A4F1A3A1E51}.Debug|ARM.ActiveCfg = Debug|ARM + {B244E787-C445-441C-BDF4-5A4F1A3A1E51}.Debug|ARM.Build.0 = Debug|ARM + {B244E787-C445-441C-BDF4-5A4F1A3A1E51}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {B244E787-C445-441C-BDF4-5A4F1A3A1E51}.Debug|ARM64.Build.0 = Debug|ARM64 + {B244E787-C445-441C-BDF4-5A4F1A3A1E51}.Debug|Win32.ActiveCfg = Debug|Win32 + {B244E787-C445-441C-BDF4-5A4F1A3A1E51}.Debug|Win32.Build.0 = Debug|Win32 + {B244E787-C445-441C-BDF4-5A4F1A3A1E51}.Debug|x64.ActiveCfg = Debug|x64 + {B244E787-C445-441C-BDF4-5A4F1A3A1E51}.Debug|x64.Build.0 = Debug|x64 + {B244E787-C445-441C-BDF4-5A4F1A3A1E51}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM + {B244E787-C445-441C-BDF4-5A4F1A3A1E51}.PGInstrument|ARM.Build.0 = PGInstrument|ARM + {B244E787-C445-441C-BDF4-5A4F1A3A1E51}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 + {B244E787-C445-441C-BDF4-5A4F1A3A1E51}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 + {B244E787-C445-441C-BDF4-5A4F1A3A1E51}.PGInstrument|Win32.ActiveCfg = Release|Win32 + {B244E787-C445-441C-BDF4-5A4F1A3A1E51}.PGInstrument|Win32.Build.0 = Release|Win32 + {B244E787-C445-441C-BDF4-5A4F1A3A1E51}.PGInstrument|x64.ActiveCfg = Release|x64 + {B244E787-C445-441C-BDF4-5A4F1A3A1E51}.PGInstrument|x64.Build.0 = Release|x64 + {B244E787-C445-441C-BDF4-5A4F1A3A1E51}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM + {B244E787-C445-441C-BDF4-5A4F1A3A1E51}.PGUpdate|ARM.Build.0 = PGUpdate|ARM + {B244E787-C445-441C-BDF4-5A4F1A3A1E51}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 + {B244E787-C445-441C-BDF4-5A4F1A3A1E51}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 + {B244E787-C445-441C-BDF4-5A4F1A3A1E51}.PGUpdate|Win32.ActiveCfg = Release|Win32 + {B244E787-C445-441C-BDF4-5A4F1A3A1E51}.PGUpdate|Win32.Build.0 = Release|Win32 + {B244E787-C445-441C-BDF4-5A4F1A3A1E51}.PGUpdate|x64.ActiveCfg = Release|x64 + {B244E787-C445-441C-BDF4-5A4F1A3A1E51}.PGUpdate|x64.Build.0 = Release|x64 + {B244E787-C445-441C-BDF4-5A4F1A3A1E51}.Release|ARM.ActiveCfg = Release|ARM + {B244E787-C445-441C-BDF4-5A4F1A3A1E51}.Release|ARM.Build.0 = Release|ARM + {B244E787-C445-441C-BDF4-5A4F1A3A1E51}.Release|ARM64.ActiveCfg = Release|ARM64 + {B244E787-C445-441C-BDF4-5A4F1A3A1E51}.Release|ARM64.Build.0 = Release|ARM64 + {B244E787-C445-441C-BDF4-5A4F1A3A1E51}.Release|Win32.ActiveCfg = Release|Win32 + {B244E787-C445-441C-BDF4-5A4F1A3A1E51}.Release|Win32.Build.0 = Release|Win32 + {B244E787-C445-441C-BDF4-5A4F1A3A1E51}.Release|x64.ActiveCfg = Release|x64 + {B244E787-C445-441C-BDF4-5A4F1A3A1E51}.Release|x64.Build.0 = Release|x64 + {384C224A-7474-476E-A01B-750EA7DE918C}.Debug|ARM.ActiveCfg = Debug|ARM + {384C224A-7474-476E-A01B-750EA7DE918C}.Debug|ARM.Build.0 = Debug|ARM + {384C224A-7474-476E-A01B-750EA7DE918C}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {384C224A-7474-476E-A01B-750EA7DE918C}.Debug|ARM64.Build.0 = Debug|ARM64 + {384C224A-7474-476E-A01B-750EA7DE918C}.Debug|Win32.ActiveCfg = Debug|Win32 + {384C224A-7474-476E-A01B-750EA7DE918C}.Debug|Win32.Build.0 = Debug|Win32 + {384C224A-7474-476E-A01B-750EA7DE918C}.Debug|x64.ActiveCfg = Debug|x64 + {384C224A-7474-476E-A01B-750EA7DE918C}.Debug|x64.Build.0 = Debug|x64 + {384C224A-7474-476E-A01B-750EA7DE918C}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM + {384C224A-7474-476E-A01B-750EA7DE918C}.PGInstrument|ARM.Build.0 = PGInstrument|ARM + {384C224A-7474-476E-A01B-750EA7DE918C}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 + {384C224A-7474-476E-A01B-750EA7DE918C}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 + {384C224A-7474-476E-A01B-750EA7DE918C}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 + {384C224A-7474-476E-A01B-750EA7DE918C}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 + {384C224A-7474-476E-A01B-750EA7DE918C}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 + {384C224A-7474-476E-A01B-750EA7DE918C}.PGInstrument|x64.Build.0 = PGInstrument|x64 + {384C224A-7474-476E-A01B-750EA7DE918C}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM + {384C224A-7474-476E-A01B-750EA7DE918C}.PGUpdate|ARM.Build.0 = PGUpdate|ARM + {384C224A-7474-476E-A01B-750EA7DE918C}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 + {384C224A-7474-476E-A01B-750EA7DE918C}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 + {384C224A-7474-476E-A01B-750EA7DE918C}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 + {384C224A-7474-476E-A01B-750EA7DE918C}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 + {384C224A-7474-476E-A01B-750EA7DE918C}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 + {384C224A-7474-476E-A01B-750EA7DE918C}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {384C224A-7474-476E-A01B-750EA7DE918C}.Release|ARM.ActiveCfg = Release|ARM + {384C224A-7474-476E-A01B-750EA7DE918C}.Release|ARM.Build.0 = Release|ARM + {384C224A-7474-476E-A01B-750EA7DE918C}.Release|ARM64.ActiveCfg = Release|ARM64 + {384C224A-7474-476E-A01B-750EA7DE918C}.Release|ARM64.Build.0 = Release|ARM64 + {384C224A-7474-476E-A01B-750EA7DE918C}.Release|Win32.ActiveCfg = Release|Win32 + {384C224A-7474-476E-A01B-750EA7DE918C}.Release|Win32.Build.0 = Release|Win32 + {384C224A-7474-476E-A01B-750EA7DE918C}.Release|x64.ActiveCfg = Release|x64 + {384C224A-7474-476E-A01B-750EA7DE918C}.Release|x64.Build.0 = Release|x64 + {FCBE1EF2-E0F0-40B1-88B5-00A35D378742}.Debug|ARM.ActiveCfg = Debug|ARM + {FCBE1EF2-E0F0-40B1-88B5-00A35D378742}.Debug|ARM.Build.0 = Debug|ARM + {FCBE1EF2-E0F0-40B1-88B5-00A35D378742}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {FCBE1EF2-E0F0-40B1-88B5-00A35D378742}.Debug|ARM64.Build.0 = Debug|ARM64 + {FCBE1EF2-E0F0-40B1-88B5-00A35D378742}.Debug|Win32.ActiveCfg = Debug|Win32 + {FCBE1EF2-E0F0-40B1-88B5-00A35D378742}.Debug|Win32.Build.0 = Debug|Win32 + {FCBE1EF2-E0F0-40B1-88B5-00A35D378742}.Debug|x64.ActiveCfg = Debug|x64 + {FCBE1EF2-E0F0-40B1-88B5-00A35D378742}.Debug|x64.Build.0 = Debug|x64 + {FCBE1EF2-E0F0-40B1-88B5-00A35D378742}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM + {FCBE1EF2-E0F0-40B1-88B5-00A35D378742}.PGInstrument|ARM.Build.0 = PGInstrument|ARM + {FCBE1EF2-E0F0-40B1-88B5-00A35D378742}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 + {FCBE1EF2-E0F0-40B1-88B5-00A35D378742}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 + {FCBE1EF2-E0F0-40B1-88B5-00A35D378742}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 + {FCBE1EF2-E0F0-40B1-88B5-00A35D378742}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 + {FCBE1EF2-E0F0-40B1-88B5-00A35D378742}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 + {FCBE1EF2-E0F0-40B1-88B5-00A35D378742}.PGInstrument|x64.Build.0 = PGInstrument|x64 + {FCBE1EF2-E0F0-40B1-88B5-00A35D378742}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM + {FCBE1EF2-E0F0-40B1-88B5-00A35D378742}.PGUpdate|ARM.Build.0 = PGUpdate|ARM + {FCBE1EF2-E0F0-40B1-88B5-00A35D378742}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 + {FCBE1EF2-E0F0-40B1-88B5-00A35D378742}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 + {FCBE1EF2-E0F0-40B1-88B5-00A35D378742}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 + {FCBE1EF2-E0F0-40B1-88B5-00A35D378742}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 + {FCBE1EF2-E0F0-40B1-88B5-00A35D378742}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 + {FCBE1EF2-E0F0-40B1-88B5-00A35D378742}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {FCBE1EF2-E0F0-40B1-88B5-00A35D378742}.Release|ARM.ActiveCfg = Release|ARM + {FCBE1EF2-E0F0-40B1-88B5-00A35D378742}.Release|ARM.Build.0 = Release|ARM + {FCBE1EF2-E0F0-40B1-88B5-00A35D378742}.Release|ARM64.ActiveCfg = Release|ARM64 + {FCBE1EF2-E0F0-40B1-88B5-00A35D378742}.Release|ARM64.Build.0 = Release|ARM64 + {FCBE1EF2-E0F0-40B1-88B5-00A35D378742}.Release|Win32.ActiveCfg = Release|Win32 + {FCBE1EF2-E0F0-40B1-88B5-00A35D378742}.Release|Win32.Build.0 = Release|Win32 + {FCBE1EF2-E0F0-40B1-88B5-00A35D378742}.Release|x64.ActiveCfg = Release|x64 + {FCBE1EF2-E0F0-40B1-88B5-00A35D378742}.Release|x64.Build.0 = Release|x64 + {78D80A15-BD8C-44E2-B49E-1F05B0A0A687}.Debug|ARM.ActiveCfg = Debug|ARM + {78D80A15-BD8C-44E2-B49E-1F05B0A0A687}.Debug|ARM.Build.0 = Debug|ARM + {78D80A15-BD8C-44E2-B49E-1F05B0A0A687}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {78D80A15-BD8C-44E2-B49E-1F05B0A0A687}.Debug|ARM64.Build.0 = Debug|ARM64 + {78D80A15-BD8C-44E2-B49E-1F05B0A0A687}.Debug|Win32.ActiveCfg = Debug|Win32 + {78D80A15-BD8C-44E2-B49E-1F05B0A0A687}.Debug|Win32.Build.0 = Debug|Win32 + {78D80A15-BD8C-44E2-B49E-1F05B0A0A687}.Debug|x64.ActiveCfg = Debug|x64 + {78D80A15-BD8C-44E2-B49E-1F05B0A0A687}.Debug|x64.Build.0 = Debug|x64 + {78D80A15-BD8C-44E2-B49E-1F05B0A0A687}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM + {78D80A15-BD8C-44E2-B49E-1F05B0A0A687}.PGInstrument|ARM.Build.0 = PGInstrument|ARM + {78D80A15-BD8C-44E2-B49E-1F05B0A0A687}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 + {78D80A15-BD8C-44E2-B49E-1F05B0A0A687}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 + {78D80A15-BD8C-44E2-B49E-1F05B0A0A687}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 + {78D80A15-BD8C-44E2-B49E-1F05B0A0A687}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 + {78D80A15-BD8C-44E2-B49E-1F05B0A0A687}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 + {78D80A15-BD8C-44E2-B49E-1F05B0A0A687}.PGInstrument|x64.Build.0 = PGInstrument|x64 + {78D80A15-BD8C-44E2-B49E-1F05B0A0A687}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM + {78D80A15-BD8C-44E2-B49E-1F05B0A0A687}.PGUpdate|ARM.Build.0 = PGUpdate|ARM + {78D80A15-BD8C-44E2-B49E-1F05B0A0A687}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 + {78D80A15-BD8C-44E2-B49E-1F05B0A0A687}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 + {78D80A15-BD8C-44E2-B49E-1F05B0A0A687}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 + {78D80A15-BD8C-44E2-B49E-1F05B0A0A687}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 + {78D80A15-BD8C-44E2-B49E-1F05B0A0A687}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 + {78D80A15-BD8C-44E2-B49E-1F05B0A0A687}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {78D80A15-BD8C-44E2-B49E-1F05B0A0A687}.Release|ARM.ActiveCfg = Release|ARM + {78D80A15-BD8C-44E2-B49E-1F05B0A0A687}.Release|ARM.Build.0 = Release|ARM + {78D80A15-BD8C-44E2-B49E-1F05B0A0A687}.Release|ARM64.ActiveCfg = Release|ARM64 + {78D80A15-BD8C-44E2-B49E-1F05B0A0A687}.Release|ARM64.Build.0 = Release|ARM64 + {78D80A15-BD8C-44E2-B49E-1F05B0A0A687}.Release|Win32.ActiveCfg = Release|Win32 + {78D80A15-BD8C-44E2-B49E-1F05B0A0A687}.Release|Win32.Build.0 = Release|Win32 + {78D80A15-BD8C-44E2-B49E-1F05B0A0A687}.Release|x64.ActiveCfg = Release|x64 + {78D80A15-BD8C-44E2-B49E-1F05B0A0A687}.Release|x64.Build.0 = Release|x64 + {12728250-16EC-4DC6-94D7-E21DD88947F8}.Debug|ARM.ActiveCfg = Debug|ARM + {12728250-16EC-4DC6-94D7-E21DD88947F8}.Debug|ARM.Build.0 = Debug|ARM + {12728250-16EC-4DC6-94D7-E21DD88947F8}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {12728250-16EC-4DC6-94D7-E21DD88947F8}.Debug|ARM64.Build.0 = Debug|ARM64 + {12728250-16EC-4DC6-94D7-E21DD88947F8}.Debug|Win32.ActiveCfg = Debug|Win32 + {12728250-16EC-4DC6-94D7-E21DD88947F8}.Debug|Win32.Build.0 = Debug|Win32 + {12728250-16EC-4DC6-94D7-E21DD88947F8}.Debug|x64.ActiveCfg = Debug|x64 + {12728250-16EC-4DC6-94D7-E21DD88947F8}.Debug|x64.Build.0 = Debug|x64 + {12728250-16EC-4DC6-94D7-E21DD88947F8}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM + {12728250-16EC-4DC6-94D7-E21DD88947F8}.PGInstrument|ARM.Build.0 = PGInstrument|ARM + {12728250-16EC-4DC6-94D7-E21DD88947F8}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 + {12728250-16EC-4DC6-94D7-E21DD88947F8}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 + {12728250-16EC-4DC6-94D7-E21DD88947F8}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 + {12728250-16EC-4DC6-94D7-E21DD88947F8}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 + {12728250-16EC-4DC6-94D7-E21DD88947F8}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 + {12728250-16EC-4DC6-94D7-E21DD88947F8}.PGInstrument|x64.Build.0 = PGInstrument|x64 + {12728250-16EC-4DC6-94D7-E21DD88947F8}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM + {12728250-16EC-4DC6-94D7-E21DD88947F8}.PGUpdate|ARM.Build.0 = PGUpdate|ARM + {12728250-16EC-4DC6-94D7-E21DD88947F8}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 + {12728250-16EC-4DC6-94D7-E21DD88947F8}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 + {12728250-16EC-4DC6-94D7-E21DD88947F8}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 + {12728250-16EC-4DC6-94D7-E21DD88947F8}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 + {12728250-16EC-4DC6-94D7-E21DD88947F8}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 + {12728250-16EC-4DC6-94D7-E21DD88947F8}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {12728250-16EC-4DC6-94D7-E21DD88947F8}.Release|ARM.ActiveCfg = Release|ARM + {12728250-16EC-4DC6-94D7-E21DD88947F8}.Release|ARM.Build.0 = Release|ARM + {12728250-16EC-4DC6-94D7-E21DD88947F8}.Release|ARM64.ActiveCfg = Release|ARM64 + {12728250-16EC-4DC6-94D7-E21DD88947F8}.Release|ARM64.Build.0 = Release|ARM64 + {12728250-16EC-4DC6-94D7-E21DD88947F8}.Release|Win32.ActiveCfg = Release|Win32 + {12728250-16EC-4DC6-94D7-E21DD88947F8}.Release|Win32.Build.0 = Release|Win32 + {12728250-16EC-4DC6-94D7-E21DD88947F8}.Release|x64.ActiveCfg = Release|x64 + {12728250-16EC-4DC6-94D7-E21DD88947F8}.Release|x64.Build.0 = Release|x64 + {9DE9E23D-C8D4-4817-92A9-920A8B1FE5FF}.Debug|ARM.ActiveCfg = Debug|Win32 + {9DE9E23D-C8D4-4817-92A9-920A8B1FE5FF}.Debug|ARM64.ActiveCfg = Debug|Win32 + {9DE9E23D-C8D4-4817-92A9-920A8B1FE5FF}.Debug|Win32.ActiveCfg = Debug|Win32 + {9DE9E23D-C8D4-4817-92A9-920A8B1FE5FF}.Debug|Win32.Build.0 = Debug|Win32 + {9DE9E23D-C8D4-4817-92A9-920A8B1FE5FF}.Debug|x64.ActiveCfg = Debug|x64 + {9DE9E23D-C8D4-4817-92A9-920A8B1FE5FF}.Debug|x64.Build.0 = Debug|x64 + {9DE9E23D-C8D4-4817-92A9-920A8B1FE5FF}.PGInstrument|ARM.ActiveCfg = PGInstrument|Win32 + {9DE9E23D-C8D4-4817-92A9-920A8B1FE5FF}.PGInstrument|ARM64.ActiveCfg = PGInstrument|Win32 + {9DE9E23D-C8D4-4817-92A9-920A8B1FE5FF}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 + {9DE9E23D-C8D4-4817-92A9-920A8B1FE5FF}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 + {9DE9E23D-C8D4-4817-92A9-920A8B1FE5FF}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 + {9DE9E23D-C8D4-4817-92A9-920A8B1FE5FF}.PGInstrument|x64.Build.0 = PGInstrument|x64 + {9DE9E23D-C8D4-4817-92A9-920A8B1FE5FF}.PGUpdate|ARM.ActiveCfg = PGUpdate|Win32 + {9DE9E23D-C8D4-4817-92A9-920A8B1FE5FF}.PGUpdate|ARM64.ActiveCfg = PGUpdate|Win32 + {9DE9E23D-C8D4-4817-92A9-920A8B1FE5FF}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 + {9DE9E23D-C8D4-4817-92A9-920A8B1FE5FF}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 + {9DE9E23D-C8D4-4817-92A9-920A8B1FE5FF}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 + {9DE9E23D-C8D4-4817-92A9-920A8B1FE5FF}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {9DE9E23D-C8D4-4817-92A9-920A8B1FE5FF}.Release|ARM.ActiveCfg = Release|Win32 + {9DE9E23D-C8D4-4817-92A9-920A8B1FE5FF}.Release|ARM64.ActiveCfg = Release|Win32 + {9DE9E23D-C8D4-4817-92A9-920A8B1FE5FF}.Release|Win32.ActiveCfg = Release|Win32 + {9DE9E23D-C8D4-4817-92A9-920A8B1FE5FF}.Release|Win32.Build.0 = Release|Win32 + {9DE9E23D-C8D4-4817-92A9-920A8B1FE5FF}.Release|x64.ActiveCfg = Release|x64 + {9DE9E23D-C8D4-4817-92A9-920A8B1FE5FF}.Release|x64.Build.0 = Release|x64 + {494BAC80-A60C-43A9-99E7-ACB691CE2C4D}.Debug|ARM.ActiveCfg = Debug|ARM + {494BAC80-A60C-43A9-99E7-ACB691CE2C4D}.Debug|ARM.Build.0 = Debug|ARM + {494BAC80-A60C-43A9-99E7-ACB691CE2C4D}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {494BAC80-A60C-43A9-99E7-ACB691CE2C4D}.Debug|ARM64.Build.0 = Debug|ARM64 + {494BAC80-A60C-43A9-99E7-ACB691CE2C4D}.Debug|Win32.ActiveCfg = Debug|Win32 + {494BAC80-A60C-43A9-99E7-ACB691CE2C4D}.Debug|Win32.Build.0 = Debug|Win32 + {494BAC80-A60C-43A9-99E7-ACB691CE2C4D}.Debug|x64.ActiveCfg = Debug|x64 + {494BAC80-A60C-43A9-99E7-ACB691CE2C4D}.Debug|x64.Build.0 = Debug|x64 + {494BAC80-A60C-43A9-99E7-ACB691CE2C4D}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM + {494BAC80-A60C-43A9-99E7-ACB691CE2C4D}.PGInstrument|ARM.Build.0 = PGInstrument|ARM + {494BAC80-A60C-43A9-99E7-ACB691CE2C4D}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 + {494BAC80-A60C-43A9-99E7-ACB691CE2C4D}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 + {494BAC80-A60C-43A9-99E7-ACB691CE2C4D}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 + {494BAC80-A60C-43A9-99E7-ACB691CE2C4D}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 + {494BAC80-A60C-43A9-99E7-ACB691CE2C4D}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 + {494BAC80-A60C-43A9-99E7-ACB691CE2C4D}.PGInstrument|x64.Build.0 = PGInstrument|x64 + {494BAC80-A60C-43A9-99E7-ACB691CE2C4D}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM + {494BAC80-A60C-43A9-99E7-ACB691CE2C4D}.PGUpdate|ARM.Build.0 = PGUpdate|ARM + {494BAC80-A60C-43A9-99E7-ACB691CE2C4D}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 + {494BAC80-A60C-43A9-99E7-ACB691CE2C4D}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 + {494BAC80-A60C-43A9-99E7-ACB691CE2C4D}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 + {494BAC80-A60C-43A9-99E7-ACB691CE2C4D}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 + {494BAC80-A60C-43A9-99E7-ACB691CE2C4D}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 + {494BAC80-A60C-43A9-99E7-ACB691CE2C4D}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {494BAC80-A60C-43A9-99E7-ACB691CE2C4D}.Release|ARM.ActiveCfg = Release|ARM + {494BAC80-A60C-43A9-99E7-ACB691CE2C4D}.Release|ARM.Build.0 = Release|ARM + {494BAC80-A60C-43A9-99E7-ACB691CE2C4D}.Release|ARM64.ActiveCfg = Release|ARM64 + {494BAC80-A60C-43A9-99E7-ACB691CE2C4D}.Release|ARM64.Build.0 = Release|ARM64 + {494BAC80-A60C-43A9-99E7-ACB691CE2C4D}.Release|Win32.ActiveCfg = Release|Win32 + {494BAC80-A60C-43A9-99E7-ACB691CE2C4D}.Release|Win32.Build.0 = Release|Win32 + {494BAC80-A60C-43A9-99E7-ACB691CE2C4D}.Release|x64.ActiveCfg = Release|x64 + {494BAC80-A60C-43A9-99E7-ACB691CE2C4D}.Release|x64.Build.0 = Release|x64 + {FDB84CBB-2FB6-47C8-A2D6-091E0833239D}.Debug|ARM.ActiveCfg = Debug|ARM + {FDB84CBB-2FB6-47C8-A2D6-091E0833239D}.Debug|ARM.Build.0 = Debug|ARM + {FDB84CBB-2FB6-47C8-A2D6-091E0833239D}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {FDB84CBB-2FB6-47C8-A2D6-091E0833239D}.Debug|ARM64.Build.0 = Debug|ARM64 + {FDB84CBB-2FB6-47C8-A2D6-091E0833239D}.Debug|Win32.ActiveCfg = Debug|Win32 + {FDB84CBB-2FB6-47C8-A2D6-091E0833239D}.Debug|Win32.Build.0 = Debug|Win32 + {FDB84CBB-2FB6-47C8-A2D6-091E0833239D}.Debug|x64.ActiveCfg = Debug|x64 + {FDB84CBB-2FB6-47C8-A2D6-091E0833239D}.Debug|x64.Build.0 = Debug|x64 + {FDB84CBB-2FB6-47C8-A2D6-091E0833239D}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM + {FDB84CBB-2FB6-47C8-A2D6-091E0833239D}.PGInstrument|ARM.Build.0 = PGInstrument|ARM + {FDB84CBB-2FB6-47C8-A2D6-091E0833239D}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 + {FDB84CBB-2FB6-47C8-A2D6-091E0833239D}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 + {FDB84CBB-2FB6-47C8-A2D6-091E0833239D}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 + {FDB84CBB-2FB6-47C8-A2D6-091E0833239D}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 + {FDB84CBB-2FB6-47C8-A2D6-091E0833239D}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 + {FDB84CBB-2FB6-47C8-A2D6-091E0833239D}.PGInstrument|x64.Build.0 = PGInstrument|x64 + {FDB84CBB-2FB6-47C8-A2D6-091E0833239D}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM + {FDB84CBB-2FB6-47C8-A2D6-091E0833239D}.PGUpdate|ARM.Build.0 = PGUpdate|ARM + {FDB84CBB-2FB6-47C8-A2D6-091E0833239D}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 + {FDB84CBB-2FB6-47C8-A2D6-091E0833239D}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 + {FDB84CBB-2FB6-47C8-A2D6-091E0833239D}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 + {FDB84CBB-2FB6-47C8-A2D6-091E0833239D}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 + {FDB84CBB-2FB6-47C8-A2D6-091E0833239D}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 + {FDB84CBB-2FB6-47C8-A2D6-091E0833239D}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {FDB84CBB-2FB6-47C8-A2D6-091E0833239D}.Release|ARM.ActiveCfg = Release|ARM + {FDB84CBB-2FB6-47C8-A2D6-091E0833239D}.Release|ARM.Build.0 = Release|ARM + {FDB84CBB-2FB6-47C8-A2D6-091E0833239D}.Release|ARM64.ActiveCfg = Release|ARM64 + {FDB84CBB-2FB6-47C8-A2D6-091E0833239D}.Release|ARM64.Build.0 = Release|ARM64 + {FDB84CBB-2FB6-47C8-A2D6-091E0833239D}.Release|Win32.ActiveCfg = Release|Win32 + {FDB84CBB-2FB6-47C8-A2D6-091E0833239D}.Release|Win32.Build.0 = Release|Win32 + {FDB84CBB-2FB6-47C8-A2D6-091E0833239D}.Release|x64.ActiveCfg = Release|x64 + {FDB84CBB-2FB6-47C8-A2D6-091E0833239D}.Release|x64.Build.0 = Release|x64 + {AB603547-1E2A-45B3-9E09-B04596006393}.Debug|ARM.ActiveCfg = Debug|Win32 + {AB603547-1E2A-45B3-9E09-B04596006393}.Debug|ARM.Build.0 = Debug|Win32 + {AB603547-1E2A-45B3-9E09-B04596006393}.Debug|ARM64.ActiveCfg = Debug|Win32 + {AB603547-1E2A-45B3-9E09-B04596006393}.Debug|Win32.ActiveCfg = Debug|Win32 + {AB603547-1E2A-45B3-9E09-B04596006393}.Debug|Win32.Build.0 = Debug|Win32 + {AB603547-1E2A-45B3-9E09-B04596006393}.Debug|x64.ActiveCfg = Debug|x64 + {AB603547-1E2A-45B3-9E09-B04596006393}.Debug|x64.Build.0 = Debug|x64 + {AB603547-1E2A-45B3-9E09-B04596006393}.PGInstrument|ARM.ActiveCfg = PGInstrument|Win32 + {AB603547-1E2A-45B3-9E09-B04596006393}.PGInstrument|ARM64.ActiveCfg = PGInstrument|Win32 + {AB603547-1E2A-45B3-9E09-B04596006393}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 + {AB603547-1E2A-45B3-9E09-B04596006393}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 + {AB603547-1E2A-45B3-9E09-B04596006393}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 + {AB603547-1E2A-45B3-9E09-B04596006393}.PGInstrument|x64.Build.0 = PGInstrument|x64 + {AB603547-1E2A-45B3-9E09-B04596006393}.PGUpdate|ARM.ActiveCfg = PGUpdate|Win32 + {AB603547-1E2A-45B3-9E09-B04596006393}.PGUpdate|ARM64.ActiveCfg = PGUpdate|Win32 + {AB603547-1E2A-45B3-9E09-B04596006393}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 + {AB603547-1E2A-45B3-9E09-B04596006393}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 + {AB603547-1E2A-45B3-9E09-B04596006393}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 + {AB603547-1E2A-45B3-9E09-B04596006393}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {AB603547-1E2A-45B3-9E09-B04596006393}.Release|ARM.ActiveCfg = Release|Win32 + {AB603547-1E2A-45B3-9E09-B04596006393}.Release|ARM64.ActiveCfg = Release|Win32 + {AB603547-1E2A-45B3-9E09-B04596006393}.Release|Win32.ActiveCfg = Release|Win32 + {AB603547-1E2A-45B3-9E09-B04596006393}.Release|Win32.Build.0 = Release|Win32 + {AB603547-1E2A-45B3-9E09-B04596006393}.Release|x64.ActiveCfg = Release|x64 + {AB603547-1E2A-45B3-9E09-B04596006393}.Release|x64.Build.0 = Release|x64 + {CB435430-EBB1-478B-8F4E-C256F6838F55}.Debug|ARM.ActiveCfg = Debug|ARM + {CB435430-EBB1-478B-8F4E-C256F6838F55}.Debug|ARM.Build.0 = Debug|ARM + {CB435430-EBB1-478B-8F4E-C256F6838F55}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {CB435430-EBB1-478B-8F4E-C256F6838F55}.Debug|ARM64.Build.0 = Debug|ARM64 + {CB435430-EBB1-478B-8F4E-C256F6838F55}.Debug|Win32.ActiveCfg = Debug|Win32 + {CB435430-EBB1-478B-8F4E-C256F6838F55}.Debug|Win32.Build.0 = Debug|Win32 + {CB435430-EBB1-478B-8F4E-C256F6838F55}.Debug|x64.ActiveCfg = Debug|x64 + {CB435430-EBB1-478B-8F4E-C256F6838F55}.Debug|x64.Build.0 = Debug|x64 + {CB435430-EBB1-478B-8F4E-C256F6838F55}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM + {CB435430-EBB1-478B-8F4E-C256F6838F55}.PGInstrument|ARM.Build.0 = PGInstrument|ARM + {CB435430-EBB1-478B-8F4E-C256F6838F55}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 + {CB435430-EBB1-478B-8F4E-C256F6838F55}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 + {CB435430-EBB1-478B-8F4E-C256F6838F55}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 + {CB435430-EBB1-478B-8F4E-C256F6838F55}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 + {CB435430-EBB1-478B-8F4E-C256F6838F55}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 + {CB435430-EBB1-478B-8F4E-C256F6838F55}.PGInstrument|x64.Build.0 = PGInstrument|x64 + {CB435430-EBB1-478B-8F4E-C256F6838F55}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM + {CB435430-EBB1-478B-8F4E-C256F6838F55}.PGUpdate|ARM.Build.0 = PGUpdate|ARM + {CB435430-EBB1-478B-8F4E-C256F6838F55}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 + {CB435430-EBB1-478B-8F4E-C256F6838F55}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 + {CB435430-EBB1-478B-8F4E-C256F6838F55}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 + {CB435430-EBB1-478B-8F4E-C256F6838F55}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 + {CB435430-EBB1-478B-8F4E-C256F6838F55}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 + {CB435430-EBB1-478B-8F4E-C256F6838F55}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {CB435430-EBB1-478B-8F4E-C256F6838F55}.Release|ARM.ActiveCfg = Release|ARM + {CB435430-EBB1-478B-8F4E-C256F6838F55}.Release|ARM.Build.0 = Release|ARM + {CB435430-EBB1-478B-8F4E-C256F6838F55}.Release|ARM64.ActiveCfg = Release|ARM64 + {CB435430-EBB1-478B-8F4E-C256F6838F55}.Release|ARM64.Build.0 = Release|ARM64 + {CB435430-EBB1-478B-8F4E-C256F6838F55}.Release|Win32.ActiveCfg = Release|Win32 + {CB435430-EBB1-478B-8F4E-C256F6838F55}.Release|Win32.Build.0 = Release|Win32 + {CB435430-EBB1-478B-8F4E-C256F6838F55}.Release|x64.ActiveCfg = Release|x64 + {CB435430-EBB1-478B-8F4E-C256F6838F55}.Release|x64.Build.0 = Release|x64 + {54B1431F-B86B-4ACB-B28C-88BCF93191D8}.Debug|ARM.ActiveCfg = Debug|ARM + {54B1431F-B86B-4ACB-B28C-88BCF93191D8}.Debug|ARM.Build.0 = Debug|ARM + {54B1431F-B86B-4ACB-B28C-88BCF93191D8}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {54B1431F-B86B-4ACB-B28C-88BCF93191D8}.Debug|ARM64.Build.0 = Debug|ARM64 + {54B1431F-B86B-4ACB-B28C-88BCF93191D8}.Debug|Win32.ActiveCfg = Debug|Win32 + {54B1431F-B86B-4ACB-B28C-88BCF93191D8}.Debug|Win32.Build.0 = Debug|Win32 + {54B1431F-B86B-4ACB-B28C-88BCF93191D8}.Debug|x64.ActiveCfg = Debug|x64 + {54B1431F-B86B-4ACB-B28C-88BCF93191D8}.Debug|x64.Build.0 = Debug|x64 + {54B1431F-B86B-4ACB-B28C-88BCF93191D8}.PGInstrument|ARM.ActiveCfg = PGInstrument|ARM + {54B1431F-B86B-4ACB-B28C-88BCF93191D8}.PGInstrument|ARM.Build.0 = PGInstrument|ARM + {54B1431F-B86B-4ACB-B28C-88BCF93191D8}.PGInstrument|ARM64.ActiveCfg = PGInstrument|ARM64 + {54B1431F-B86B-4ACB-B28C-88BCF93191D8}.PGInstrument|ARM64.Build.0 = PGInstrument|ARM64 + {54B1431F-B86B-4ACB-B28C-88BCF93191D8}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 + {54B1431F-B86B-4ACB-B28C-88BCF93191D8}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 + {54B1431F-B86B-4ACB-B28C-88BCF93191D8}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 + {54B1431F-B86B-4ACB-B28C-88BCF93191D8}.PGInstrument|x64.Build.0 = PGInstrument|x64 + {54B1431F-B86B-4ACB-B28C-88BCF93191D8}.PGUpdate|ARM.ActiveCfg = PGUpdate|ARM + {54B1431F-B86B-4ACB-B28C-88BCF93191D8}.PGUpdate|ARM.Build.0 = PGUpdate|ARM + {54B1431F-B86B-4ACB-B28C-88BCF93191D8}.PGUpdate|ARM64.ActiveCfg = PGUpdate|ARM64 + {54B1431F-B86B-4ACB-B28C-88BCF93191D8}.PGUpdate|ARM64.Build.0 = PGUpdate|ARM64 + {54B1431F-B86B-4ACB-B28C-88BCF93191D8}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 + {54B1431F-B86B-4ACB-B28C-88BCF93191D8}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 + {54B1431F-B86B-4ACB-B28C-88BCF93191D8}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 + {54B1431F-B86B-4ACB-B28C-88BCF93191D8}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {54B1431F-B86B-4ACB-B28C-88BCF93191D8}.Release|ARM.ActiveCfg = Release|ARM + {54B1431F-B86B-4ACB-B28C-88BCF93191D8}.Release|ARM.Build.0 = Release|ARM + {54B1431F-B86B-4ACB-B28C-88BCF93191D8}.Release|ARM64.ActiveCfg = Release|ARM64 + {54B1431F-B86B-4ACB-B28C-88BCF93191D8}.Release|ARM64.Build.0 = Release|ARM64 + {54B1431F-B86B-4ACB-B28C-88BCF93191D8}.Release|Win32.ActiveCfg = Release|Win32 + {54B1431F-B86B-4ACB-B28C-88BCF93191D8}.Release|Win32.Build.0 = Release|Win32 + {54B1431F-B86B-4ACB-B28C-88BCF93191D8}.Release|x64.ActiveCfg = Release|x64 + {54B1431F-B86B-4ACB-B28C-88BCF93191D8}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {5C33FFD3-C8DC-4A54-B842-8BA9846BDFFE} + EndGlobalSection +EndGlobal diff --git a/PCbuild/prepare_libffi.bat b/PCbuild/prepare_libffi.bat index 002ac6a4..ef36c36e 100644 --- a/PCbuild/prepare_libffi.bat +++ b/PCbuild/prepare_libffi.bat @@ -1,212 +1,212 @@ -@echo off -goto :Run - -:Usage -echo. -echo Before running prepare_libffi.bat -echo LIBFFI_SOURCE environment variable must be set to the location of -echo of python-source-deps clone of libffi branch -echo VCVARSALL must be set to location of vcvarsall.bat -echo cygwin must be installed (see below) -echo SH environment variable must be set to the location of sh.exe -echo. -echo Tested with cygwin-x86 from https://www.cygwin.com/install.html -echo Select http://mirrors.kernel.org as the download site -echo Include the following cygwin packages in cygwin configuration: -echo make, autoconf, automake, libtool, dejagnu -echo. -echo NOTE: dejagnu is only required for running tests. -echo set LIBFFI_TEST=1 to run tests (optional) -echo. -echo Based on https://github.com/libffi/libffi/blob/master/.appveyor.yml -echo. -echo. -echo.Available flags: -echo. -x64 enable x64 build -echo. -x86 enable x86 build -echo. -arm32 enable arm32 build -echo. -arm64 enable arm64 build -echo. -? this help -echo. --install-cygwin install cygwin to c:\cygwin -exit /b 127 - -:Run - -set BUILD_X64= -set BUILD_X86= -set BUILD_ARM32= -set BUILD_ARM64= -set BUILD_PDB= -set BUILD_NOOPT= -set COPY_LICENSE= -set INSTALL_CYGWIN= - -:CheckOpts -if "%1"=="" goto :CheckOptsDone -if /I "%1"=="-x64" (set BUILD_X64=1) & shift & goto :CheckOpts -if /I "%1"=="-x86" (set BUILD_X86=1) & shift & goto :CheckOpts -if /I "%1"=="-win32" (set BUILD_X86=1) & shift & goto :CheckOpts -if /I "%1"=="-arm32" (set BUILD_ARM32=1) & shift & goto :CheckOpts -if /I "%1"=="-arm64" (set BUILD_ARM64=1) & shift & goto :CheckOpts -if /I "%1"=="-pdb" (set BUILD_PDB=-g) & shift & goto :CheckOpts -if /I "%1"=="-noopt" (set BUILD_NOOPT=CFLAGS='-Od -warn all') & shift & goto :CheckOpts -if /I "%1"=="-license" (set COPY_LICENSE=1) & shift & goto :CheckOpts -if /I "%1"=="-?" goto :Usage -if /I "%1"=="--install-cygwin" (set INSTALL_CYGWIN=1) & shift & goto :CheckOpts -goto :Usage - -:CheckOptsDone - -if NOT DEFINED BUILD_X64 if NOT DEFINED BUILD_X86 if NOT DEFINED BUILD_ARM32 if NOT DEFINED BUILD_ARM64 ( - set BUILD_X64=1 - set BUILD_X86=1 - set BUILD_ARM32=1 - set BUILD_ARM64=1 - set COPY_LICENSE=1 -) - -if "%INSTALL_CYGWIN%"=="1" call :InstallCygwin - -setlocal -if NOT DEFINED SH if exist c:\cygwin\bin\sh.exe set SH=c:\cygwin\bin\sh.exe - -if NOT DEFINED VCVARSALL ( - for /F "tokens=*" %%i in ('"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -property installationPath -latest -prerelease -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64') DO @(set VCVARSALL="%%i\VC\Auxiliary\Build\vcvarsall.bat") -) -if ^%VCVARSALL:~0,1% NEQ ^" SET VCVARSALL="%VCVARSALL%" - -if NOT DEFINED LIBFFI_SOURCE echo.&&echo ERROR LIBFFI_SOURCE environment variable not set && goto :Usage -if NOT DEFINED SH echo ERROR SH environment variable not set && goto :Usage - -if not exist %SH% echo ERROR %SH% does not exist && goto :Usage -if not exist %LIBFFI_SOURCE% echo ERROR %LIBFFI_SOURCE% does not exist && goto :Usage - -set OLDPWD=%LIBFFI_SOURCE% -pushd %LIBFFI_SOURCE% - -%SH% --login -lc "cygcheck -dc cygwin" -set GET_MSVCC=%SH% -lc "cd $OLDPWD; export MSVCC=`/usr/bin/find $PWD -name msvcc.sh`; echo ${MSVCC};" -FOR /F "usebackq delims==" %%i IN (`%GET_MSVCC%`) do @set MSVCC=%%i - -echo. -echo VCVARSALL : %VCVARSALL% -echo SH : %SH% -echo LIBFFI_SOURCE: %LIBFFI_SOURCE% -echo MSVCC : %MSVCC% -echo. - -if not exist Makefile.in ( - %SH% -lc "(cd $LIBFFI_SOURCE; ./autogen.sh;)" - if errorlevel 1 exit /B 1 -) - -if "%BUILD_X64%"=="1" call :BuildOne x64 x86_64-w64-cygwin x86_64-w64-cygwin -if errorlevel 1 exit /B %ERRORLEVEL% -if "%BUILD_X86%"=="1" call :BuildOne x86 i686-pc-cygwin i686-pc-cygwin -if errorlevel 1 exit /B %ERRORLEVEL% -if "%BUILD_ARM32%"=="1" call :BuildOne x86_arm i686-pc-cygwin arm-w32-cygwin -if errorlevel 1 exit /B %ERRORLEVEL% -if "%BUILD_ARM64%"=="1" call :BuildOne x86_arm64 i686-pc-cygwin aarch64-w64-cygwin -if errorlevel 1 exit /B %ERRORLEVEL% -if "%COPY_LICENSE%"=="1" copy /y "%LIBFFI_SOURCE%\LICENSE" "%LIBFFI_OUT%\LICENSE" - -popd -endlocal -exit /b 0 -REM all done - - -REM this subroutine is called once for each architecture -:BuildOne - -setlocal - -REM Initialize variables -set VCVARS_PLATFORM=%1 -set BUILD=%2 -set HOST=%3 -set ASSEMBLER= -set SRC_ARCHITECTURE=x86 - -if NOT DEFINED VCVARS_PLATFORM echo ERROR bad VCVARS_PLATFORM&&exit /b 123 - -if /I "%VCVARS_PLATFORM%" EQU "x64" ( - set ARCH=amd64 - set ARTIFACTS=%LIBFFI_SOURCE%\x86_64-w64-cygwin - set ASSEMBLER=-m64 - set SRC_ARCHITECTURE=x86 -) -if /I "%VCVARS_PLATFORM%" EQU "x86" ( - set ARCH=win32 - set ARTIFACTS=%LIBFFI_SOURCE%\i686-pc-cygwin - set ASSEMBLER= - set SRC_ARCHITECTURE=x86 -) -if /I "%VCVARS_PLATFORM%" EQU "x86_arm" ( - set ARCH=arm32 - set ARTIFACTS=%LIBFFI_SOURCE%\arm-w32-cygwin - set ASSEMBLER=-marm - set SRC_ARCHITECTURE=ARM -) -if /I "%VCVARS_PLATFORM%" EQU "x86_arm64" ( - set ARCH=arm64 - set ARTIFACTS=%LIBFFI_SOURCE%\aarch64-w64-cygwin - set ASSEMBLER=-marm64 - set SRC_ARCHITECTURE=aarch64 -) - -if NOT DEFINED LIBFFI_OUT set LIBFFI_OUT=%~dp0\..\externals\libffi -set _LIBFFI_OUT=%LIBFFI_OUT%\%ARCH% - -echo get VS build environment -call %VCVARSALL% %VCVARS_PLATFORM% - -echo clean %_LIBFFI_OUT% -if exist %_LIBFFI_OUT% (rd %_LIBFFI_OUT% /s/q) - -echo ================================================================ -echo Configure the build to generate fficonfig.h and ffi.h -echo ================================================================ -%SH% -lc "(cd $OLDPWD; ./configure CC='%MSVCC% %ASSEMBLER% %BUILD_PDB%' CXX='%MSVCC% %ASSEMBLER% %BUILD_PDB%' LD='link' CPP='cl -nologo -EP' CXXCPP='cl -nologo -EP' CPPFLAGS='-DFFI_BUILDING_DLL' %BUILD_NOOPT% NM='dumpbin -symbols' STRIP=':' --build=$BUILD --host=$HOST;)" -if errorlevel 1 exit /B %ERRORLEVEL% - -echo ================================================================ -echo Building libffi -echo ================================================================ -%SH% -lc "(cd $OLDPWD; export PATH=/usr/bin:$PATH; cp src/%SRC_ARCHITECTURE%/ffitarget.h include; make; find .;)" -if errorlevel 1 exit /B %ERRORLEVEL% - -REM Tests are not needed to produce artifacts -if "%LIBFFI_TEST%" EQU "1" ( - echo "Running tests..." - %SH% -lc "(cd $OLDPWD; export PATH=/usr/bin:$PATH; cp `find $PWD -name 'libffi-?.dll'` $HOST/testsuite/; make check; cat `find ./ -name libffi.log`)" -) else ( - echo "Not running tests" -) - - -echo copying files to %_LIBFFI_OUT% -if not exist %_LIBFFI_OUT%\include (md %_LIBFFI_OUT%\include) -copy %ARTIFACTS%\.libs\libffi-*.dll %_LIBFFI_OUT% || exit /B 1 -copy %ARTIFACTS%\.libs\libffi-*.lib %_LIBFFI_OUT% || exit /B 1 -copy %ARTIFACTS%\.libs\libffi-*.pdb %_LIBFFI_OUT% -copy %ARTIFACTS%\fficonfig.h %_LIBFFI_OUT%\include || exit /B 1 -copy %ARTIFACTS%\include\*.h %_LIBFFI_OUT%\include || exit /B 1 - -endlocal -exit /b - -:InstallCygwin -setlocal - -if NOT DEFINED CYG_ROOT (set CYG_ROOT=c:/cygwin) -if NOT DEFINED CYG_CACHE (set CYG_CACHE=C:/cygwin/var/cache/setup) -if NOT DEFINED CYG_MIRROR (set CYG_MIRROR=http://mirrors.kernel.org/sourceware/cygwin/) - -powershell -c "md $env:CYG_ROOT -ErrorAction SilentlyContinue" -powershell -c "$setup = $env:CYG_ROOT+'/setup.exe'; if (!(Test-Path $setup)){invoke-webrequest https://cygwin.com/setup-x86.exe -outfile $setup} -%CYG_ROOT%/setup.exe -qnNdO -R "%CYG_ROOT%" -s "%CYG_MIRROR%" -l "%CYG_CACHE%" -P make -P autoconf -P automake -P libtool -P dejagnu - -endlocal -exit /b - +@echo off +goto :Run + +:Usage +echo. +echo Before running prepare_libffi.bat +echo LIBFFI_SOURCE environment variable must be set to the location of +echo of python-source-deps clone of libffi branch +echo VCVARSALL must be set to location of vcvarsall.bat +echo cygwin must be installed (see below) +echo SH environment variable must be set to the location of sh.exe +echo. +echo Tested with cygwin-x86 from https://www.cygwin.com/install.html +echo Select http://mirrors.kernel.org as the download site +echo Include the following cygwin packages in cygwin configuration: +echo make, autoconf, automake, libtool, dejagnu +echo. +echo NOTE: dejagnu is only required for running tests. +echo set LIBFFI_TEST=1 to run tests (optional) +echo. +echo Based on https://github.com/libffi/libffi/blob/master/.appveyor.yml +echo. +echo. +echo.Available flags: +echo. -x64 enable x64 build +echo. -x86 enable x86 build +echo. -arm32 enable arm32 build +echo. -arm64 enable arm64 build +echo. -? this help +echo. --install-cygwin install cygwin to c:\cygwin +exit /b 127 + +:Run + +set BUILD_X64= +set BUILD_X86= +set BUILD_ARM32= +set BUILD_ARM64= +set BUILD_PDB= +set BUILD_NOOPT= +set COPY_LICENSE= +set INSTALL_CYGWIN= + +:CheckOpts +if "%1"=="" goto :CheckOptsDone +if /I "%1"=="-x64" (set BUILD_X64=1) & shift & goto :CheckOpts +if /I "%1"=="-x86" (set BUILD_X86=1) & shift & goto :CheckOpts +if /I "%1"=="-win32" (set BUILD_X86=1) & shift & goto :CheckOpts +if /I "%1"=="-arm32" (set BUILD_ARM32=1) & shift & goto :CheckOpts +if /I "%1"=="-arm64" (set BUILD_ARM64=1) & shift & goto :CheckOpts +if /I "%1"=="-pdb" (set BUILD_PDB=-g) & shift & goto :CheckOpts +if /I "%1"=="-noopt" (set BUILD_NOOPT=CFLAGS='-Od -warn all') & shift & goto :CheckOpts +if /I "%1"=="-license" (set COPY_LICENSE=1) & shift & goto :CheckOpts +if /I "%1"=="-?" goto :Usage +if /I "%1"=="--install-cygwin" (set INSTALL_CYGWIN=1) & shift & goto :CheckOpts +goto :Usage + +:CheckOptsDone + +if NOT DEFINED BUILD_X64 if NOT DEFINED BUILD_X86 if NOT DEFINED BUILD_ARM32 if NOT DEFINED BUILD_ARM64 ( + set BUILD_X64=1 + set BUILD_X86=1 + set BUILD_ARM32=0 + set BUILD_ARM64=1 + set COPY_LICENSE=1 +) + +if "%INSTALL_CYGWIN%"=="1" call :InstallCygwin + +setlocal +if NOT DEFINED SH if exist c:\cygwin\bin\sh.exe set SH=c:\cygwin\bin\sh.exe + +if NOT DEFINED VCVARSALL ( + for /F "tokens=*" %%i in ('"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -property installationPath -latest -prerelease -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64') DO @(set VCVARSALL="%%i\VC\Auxiliary\Build\vcvarsall.bat") +) +if ^%VCVARSALL:~0,1% NEQ ^" SET VCVARSALL="%VCVARSALL%" + +if NOT DEFINED LIBFFI_SOURCE echo.&&echo ERROR LIBFFI_SOURCE environment variable not set && goto :Usage +if NOT DEFINED SH echo ERROR SH environment variable not set && goto :Usage + +if not exist %SH% echo ERROR %SH% does not exist && goto :Usage +if not exist %LIBFFI_SOURCE% echo ERROR %LIBFFI_SOURCE% does not exist && goto :Usage + +set OLDPWD=%LIBFFI_SOURCE% +pushd %LIBFFI_SOURCE% + +%SH% --login -lc "cygcheck -dc cygwin" +set GET_MSVCC=%SH% -lc "cd $OLDPWD; export MSVCC=`/usr/bin/find $PWD -name msvcc.sh`; echo ${MSVCC};" +FOR /F "usebackq delims==" %%i IN (`%GET_MSVCC%`) do @set MSVCC=%%i + +echo. +echo VCVARSALL : %VCVARSALL% +echo SH : %SH% +echo LIBFFI_SOURCE: %LIBFFI_SOURCE% +echo MSVCC : %MSVCC% +echo. + +if not exist Makefile.in ( + %SH% -lc "(cd $LIBFFI_SOURCE; ./autogen.sh;)" + if errorlevel 1 exit /B 1 +) + +if "%BUILD_X64%"=="1" call :BuildOne x64 x86_64-w64-cygwin x86_64-w64-cygwin +if errorlevel 1 exit /B %ERRORLEVEL% +if "%BUILD_X86%"=="1" call :BuildOne x86 i686-pc-cygwin i686-pc-cygwin +if errorlevel 1 exit /B %ERRORLEVEL% +if "%BUILD_ARM32%"=="1" call :BuildOne x86_arm i686-pc-cygwin arm-w32-cygwin +if errorlevel 1 exit /B %ERRORLEVEL% +if "%BUILD_ARM64%"=="1" call :BuildOne x86_arm64 i686-pc-cygwin aarch64-w64-cygwin +if errorlevel 1 exit /B %ERRORLEVEL% +if "%COPY_LICENSE%"=="1" copy /y "%LIBFFI_SOURCE%\LICENSE" "%LIBFFI_OUT%\LICENSE" + +popd +endlocal +exit /b 0 +REM all done + + +REM this subroutine is called once for each architecture +:BuildOne + +setlocal + +REM Initialize variables +set VCVARS_PLATFORM=%1 +set BUILD=%2 +set HOST=%3 +set ASSEMBLER= +set SRC_ARCHITECTURE=x86 + +if NOT DEFINED VCVARS_PLATFORM echo ERROR bad VCVARS_PLATFORM&&exit /b 123 + +if /I "%VCVARS_PLATFORM%" EQU "x64" ( + set ARCH=amd64 + set ARTIFACTS=%LIBFFI_SOURCE%\x86_64-w64-cygwin + set ASSEMBLER=-m64 + set SRC_ARCHITECTURE=x86 +) +if /I "%VCVARS_PLATFORM%" EQU "x86" ( + set ARCH=win32 + set ARTIFACTS=%LIBFFI_SOURCE%\i686-pc-cygwin + set ASSEMBLER= + set SRC_ARCHITECTURE=x86 +) +if /I "%VCVARS_PLATFORM%" EQU "x86_arm" ( + set ARCH=arm32 + set ARTIFACTS=%LIBFFI_SOURCE%\arm-w32-cygwin + set ASSEMBLER=-marm + set SRC_ARCHITECTURE=ARM +) +if /I "%VCVARS_PLATFORM%" EQU "x86_arm64" ( + set ARCH=arm64 + set ARTIFACTS=%LIBFFI_SOURCE%\aarch64-w64-cygwin + set ASSEMBLER=-marm64 + set SRC_ARCHITECTURE=aarch64 +) + +if NOT DEFINED LIBFFI_OUT set LIBFFI_OUT=%~dp0\..\externals\libffi +set _LIBFFI_OUT=%LIBFFI_OUT%\%ARCH% + +echo get VS build environment +call %VCVARSALL% %VCVARS_PLATFORM% + +echo clean %_LIBFFI_OUT% +if exist %_LIBFFI_OUT% (rd %_LIBFFI_OUT% /s/q) + +echo ================================================================ +echo Configure the build to generate fficonfig.h and ffi.h +echo ================================================================ +%SH% -lc "(cd $OLDPWD; ./configure CC='%MSVCC% %ASSEMBLER% %BUILD_PDB%' CXX='%MSVCC% %ASSEMBLER% %BUILD_PDB%' LD='link' CPP='cl -nologo -EP' CXXCPP='cl -nologo -EP' CPPFLAGS='-DFFI_BUILDING_DLL' %BUILD_NOOPT% NM='dumpbin -symbols' STRIP=':' --build=$BUILD --host=$HOST;)" +if errorlevel 1 exit /B %ERRORLEVEL% + +echo ================================================================ +echo Building libffi +echo ================================================================ +%SH% -lc "(cd $OLDPWD; export PATH=/usr/bin:$PATH; cp src/%SRC_ARCHITECTURE%/ffitarget.h include; make; find .;)" +if errorlevel 1 exit /B %ERRORLEVEL% + +REM Tests are not needed to produce artifacts +if "%LIBFFI_TEST%" EQU "1" ( + echo "Running tests..." + %SH% -lc "(cd $OLDPWD; export PATH=/usr/bin:$PATH; cp `find $PWD -name 'libffi-?.dll'` $HOST/testsuite/; make check; cat `find ./ -name libffi.log`)" +) else ( + echo "Not running tests" +) + + +echo copying files to %_LIBFFI_OUT% +if not exist %_LIBFFI_OUT%\include (md %_LIBFFI_OUT%\include) +copy %ARTIFACTS%\.libs\libffi-*.dll %_LIBFFI_OUT% || exit /B 1 +copy %ARTIFACTS%\.libs\libffi-*.lib %_LIBFFI_OUT% || exit /B 1 +copy %ARTIFACTS%\.libs\libffi-*.pdb %_LIBFFI_OUT% +copy %ARTIFACTS%\fficonfig.h %_LIBFFI_OUT%\include || exit /B 1 +copy %ARTIFACTS%\include\*.h %_LIBFFI_OUT%\include || exit /B 1 + +endlocal +exit /b + +:InstallCygwin +setlocal + +if NOT DEFINED CYG_ROOT (set CYG_ROOT=c:/cygwin) +if NOT DEFINED CYG_CACHE (set CYG_CACHE=C:/cygwin/var/cache/setup) +if NOT DEFINED CYG_MIRROR (set CYG_MIRROR=http://mirrors.kernel.org/sourceware/cygwin/) + +powershell -c "md $env:CYG_ROOT -ErrorAction SilentlyContinue" +powershell -c "$setup = $env:CYG_ROOT+'/setup.exe'; if (!(Test-Path $setup)){invoke-webrequest https://cygwin.com/setup-x86_64.exe -outfile $setup} +%CYG_ROOT%/setup.exe -qnNdO -R "%CYG_ROOT%" -s "%CYG_MIRROR%" -l "%CYG_CACHE%" -P make -P autoconf -P automake -P libtool -P dejagnu + +endlocal +exit /b + diff --git a/PCbuild/prepare_ssl.bat b/PCbuild/prepare_ssl.bat index 145c4e15..88fd0225 100644 --- a/PCbuild/prepare_ssl.bat +++ b/PCbuild/prepare_ssl.bat @@ -1,58 +1,58 @@ -@echo off -rem Downloads and build sources for libraries we depend upon - -goto Run -:Usage -echo.%~nx0 [flags and arguments] -echo. -echo.Download and build OpenSSL. This should only be performed in order to -echo.update the binaries kept online - in most cases, the files downloaded -echo.by the get_externals.bat script are sufficient for building CPython. -echo. -echo.Available flags: -echo. -h Display this help message -echo. -echo.Available arguments: -echo. --certificate (-c) The signing certificate to use for binaries. -echo. --organization The github organization to obtain sources from. -echo. -exit /b 127 - -:Run -setlocal -if "%PCBUILD%"=="" (set PCBUILD=%~dp0) -if "%EXTERNALS_DIR%"=="" (set EXTERNALS_DIR=%PCBUILD%\..\externals) - -set ORG_SETTING= - -:CheckOpts -if "%~1"=="-h" shift & goto Usage -if "%~1"=="--certificate" (set SigningCertificate=%~2) && shift && shift & goto CheckOpts -if "%~1"=="-c" (set SigningCertificate=%~2) && shift && shift & goto CheckOpts -if "%~1"=="--organization" (set ORG_SETTING=--organization "%~2") && shift && shift && goto CheckOpts - -if "%~1"=="" goto Build -echo Unrecognized option: %1 -goto Usage - -:Build -call "%PCBUILD%\find_msbuild.bat" %MSBUILD% -if ERRORLEVEL 1 (echo Cannot locate MSBuild.exe on PATH or as MSBUILD variable & exit /b 2) - -call "%PCBUILD%\find_python.bat" "%PYTHON%" -if ERRORLEVEL 1 (echo Cannot locate python.exe on PATH or as PYTHON variable & exit /b 3) - -call "%PCBUILD%\get_externals.bat" --openssl-src --no-openssl %ORG_SETTING% - -if "%PERL%" == "" where perl > "%TEMP%\perl.loc" 2> nul && set /P PERL= <"%TEMP%\perl.loc" & del "%TEMP%\perl.loc" -if "%PERL%" == "" (echo Cannot locate perl.exe on PATH or as PERL variable & exit /b 4) - -%MSBUILD% "%PCBUILD%\openssl.vcxproj" /p:Configuration=Release /p:Platform=Win32 -if errorlevel 1 exit /b -%MSBUILD% "%PCBUILD%\openssl.vcxproj" /p:Configuration=Release /p:Platform=x64 -if errorlevel 1 exit /b -%MSBUILD% "%PCBUILD%\openssl.vcxproj" /p:Configuration=Release /p:Platform=ARM -if errorlevel 1 exit /b -%MSBUILD% "%PCBUILD%\openssl.vcxproj" /p:Configuration=Release /p:Platform=ARM64 -if errorlevel 1 exit /b - +@echo off +rem Downloads and build sources for libraries we depend upon + +goto Run +:Usage +echo.%~nx0 [flags and arguments] +echo. +echo.Download and build OpenSSL. This should only be performed in order to +echo.update the binaries kept online - in most cases, the files downloaded +echo.by the get_externals.bat script are sufficient for building CPython. +echo. +echo.Available flags: +echo. -h Display this help message +echo. +echo.Available arguments: +echo. --certificate (-c) The signing certificate to use for binaries. +echo. --organization The github organization to obtain sources from. +echo. +exit /b 127 + +:Run +setlocal +if "%PCBUILD%"=="" (set PCBUILD=%~dp0) +if "%EXTERNALS_DIR%"=="" (set EXTERNALS_DIR=%PCBUILD%\..\externals) + +set ORG_SETTING= + +:CheckOpts +if "%~1"=="-h" shift & goto Usage +if "%~1"=="--certificate" (set SigningCertificate=%~2) && shift && shift & goto CheckOpts +if "%~1"=="-c" (set SigningCertificate=%~2) && shift && shift & goto CheckOpts +if "%~1"=="--organization" (set ORG_SETTING=--organization "%~2") && shift && shift && goto CheckOpts + +if "%~1"=="" goto Build +echo Unrecognized option: %1 +goto Usage + +:Build +call "%PCBUILD%\find_msbuild.bat" %MSBUILD% +if ERRORLEVEL 1 (echo Cannot locate MSBuild.exe on PATH or as MSBUILD variable & exit /b 2) + +call "%PCBUILD%\find_python.bat" "%PYTHON%" +if ERRORLEVEL 1 (echo Cannot locate python.exe on PATH or as PYTHON variable & exit /b 3) + +call "%PCBUILD%\get_externals.bat" --openssl-src --no-openssl %ORG_SETTING% + +if "%PERL%" == "" where perl > "%TEMP%\perl.loc" 2> nul && set /P PERL= <"%TEMP%\perl.loc" & del "%TEMP%\perl.loc" +if "%PERL%" == "" (echo Cannot locate perl.exe on PATH or as PERL variable & exit /b 4) + +%MSBUILD% "%PCBUILD%\openssl.vcxproj" /p:Configuration=Release /p:Platform=Win32 +if errorlevel 1 exit /b +%MSBUILD% "%PCBUILD%\openssl.vcxproj" /p:Configuration=Release /p:Platform=x64 +if errorlevel 1 exit /b +%MSBUILD% "%PCBUILD%\openssl.vcxproj" /p:Configuration=Release /p:Platform=ARM +if errorlevel 1 exit /b +%MSBUILD% "%PCBUILD%\openssl.vcxproj" /p:Configuration=Release /p:Platform=ARM64 +if errorlevel 1 exit /b + diff --git a/PCbuild/prepare_tcltk.bat b/PCbuild/prepare_tcltk.bat index b240b465..4a43ed15 100644 --- a/PCbuild/prepare_tcltk.bat +++ b/PCbuild/prepare_tcltk.bat @@ -1,59 +1,59 @@ -@echo off -rem Downloads and build sources for libraries we depend upon - -goto Run -:Usage -echo.%~nx0 [flags and arguments] -echo. -echo.Download and build Tcl/Tk. This should only be performed in order to -echo.update the binaries kept online - in most cases, the files downloaded -echo.by the get_externals.bat script are sufficient for building CPython. -echo. -echo.Available flags: -echo. -h Display this help message -echo. -echo.Available arguments: -echo. --certificate (-c) The signing certificate to use for binaries. -echo. --organization The github organization to obtain sources from. -echo. -exit /b 127 - -:Run -setlocal - -if "%PCBUILD%"=="" (set PCBUILD=%~dp0) -if "%EXTERNALS_DIR%"=="" (set EXTERNALS_DIR=%PCBUILD%\..\externals) - -set CERT_SETTING= -set ORG_SETTING= - -:CheckOpts -if "%~1"=="-h" shift & goto Usage -if "%~1"=="--certificate" (set SigningCertificate=%~2) && shift && shift & goto CheckOpts -if "%~1"=="-c" (set SigningCertificate=%~2) && shift && shift & goto CheckOpts -if "%~1"=="--organization" (set ORG_SETTING=--organization "%~2") && shift && shift && goto CheckOpts - -if "%~1"=="" goto Build -echo Unrecognized option: %1 -goto Usage - -:Build -call "%PCBUILD%\find_msbuild.bat" %MSBUILD% -if ERRORLEVEL 1 (echo Cannot locate MSBuild.exe on PATH or as MSBUILD variable & exit /b 2) - -rem call "%PCBUILD%\find_python.bat" "%PYTHON%" -rem if ERRORLEVEL 1 (echo Cannot locate python.exe on PATH or as PYTHON variable & exit /b 3) - -call "%PCBUILD%\get_externals.bat" --tkinter-src %ORG_SETTING% - -%MSBUILD% "%PCBUILD%\tcl.vcxproj" /p:Configuration=Release /p:Platform=Win32 -%MSBUILD% "%PCBUILD%\tk.vcxproj" /p:Configuration=Release /p:Platform=Win32 -%MSBUILD% "%PCBUILD%\tix.vcxproj" /p:Configuration=Release /p:Platform=Win32 - -%MSBUILD% "%PCBUILD%\tcl.vcxproj" /p:Configuration=Release /p:Platform=x64 -%MSBUILD% "%PCBUILD%\tk.vcxproj" /p:Configuration=Release /p:Platform=x64 -%MSBUILD% "%PCBUILD%\tix.vcxproj" /p:Configuration=Release /p:Platform=x64 - -%MSBUILD% "%PCBUILD%\tcl.vcxproj" /p:Configuration=Release /p:Platform=ARM64 -%MSBUILD% "%PCBUILD%\tk.vcxproj" /p:Configuration=Release /p:Platform=ARM64 -%MSBUILD% "%PCBUILD%\tix.vcxproj" /p:Configuration=Release /p:Platform=ARM64 +@echo off +rem Downloads and build sources for libraries we depend upon + +goto Run +:Usage +echo.%~nx0 [flags and arguments] +echo. +echo.Download and build Tcl/Tk. This should only be performed in order to +echo.update the binaries kept online - in most cases, the files downloaded +echo.by the get_externals.bat script are sufficient for building CPython. +echo. +echo.Available flags: +echo. -h Display this help message +echo. +echo.Available arguments: +echo. --certificate (-c) The signing certificate to use for binaries. +echo. --organization The github organization to obtain sources from. +echo. +exit /b 127 + +:Run +setlocal + +if "%PCBUILD%"=="" (set PCBUILD=%~dp0) +if "%EXTERNALS_DIR%"=="" (set EXTERNALS_DIR=%PCBUILD%\..\externals) + +set CERT_SETTING= +set ORG_SETTING= + +:CheckOpts +if "%~1"=="-h" shift & goto Usage +if "%~1"=="--certificate" (set SigningCertificate=%~2) && shift && shift & goto CheckOpts +if "%~1"=="-c" (set SigningCertificate=%~2) && shift && shift & goto CheckOpts +if "%~1"=="--organization" (set ORG_SETTING=--organization "%~2") && shift && shift && goto CheckOpts + +if "%~1"=="" goto Build +echo Unrecognized option: %1 +goto Usage + +:Build +call "%PCBUILD%\find_msbuild.bat" %MSBUILD% +if ERRORLEVEL 1 (echo Cannot locate MSBuild.exe on PATH or as MSBUILD variable & exit /b 2) + +rem call "%PCBUILD%\find_python.bat" "%PYTHON%" +rem if ERRORLEVEL 1 (echo Cannot locate python.exe on PATH or as PYTHON variable & exit /b 3) + +call "%PCBUILD%\get_externals.bat" --tkinter-src %ORG_SETTING% + +%MSBUILD% "%PCBUILD%\tcl.vcxproj" /p:Configuration=Release /p:Platform=Win32 +%MSBUILD% "%PCBUILD%\tk.vcxproj" /p:Configuration=Release /p:Platform=Win32 +%MSBUILD% "%PCBUILD%\tix.vcxproj" /p:Configuration=Release /p:Platform=Win32 + +%MSBUILD% "%PCBUILD%\tcl.vcxproj" /p:Configuration=Release /p:Platform=x64 +%MSBUILD% "%PCBUILD%\tk.vcxproj" /p:Configuration=Release /p:Platform=x64 +%MSBUILD% "%PCBUILD%\tix.vcxproj" /p:Configuration=Release /p:Platform=x64 + +%MSBUILD% "%PCBUILD%\tcl.vcxproj" /p:Configuration=Release /p:Platform=ARM64 +%MSBUILD% "%PCBUILD%\tk.vcxproj" /p:Configuration=Release /p:Platform=ARM64 +%MSBUILD% "%PCBUILD%\tix.vcxproj" /p:Configuration=Release /p:Platform=ARM64 diff --git a/PCbuild/pyexpat.vcxproj b/PCbuild/pyexpat.vcxproj index d5c2b06a..001f8afd 100644 --- a/PCbuild/pyexpat.vcxproj +++ b/PCbuild/pyexpat.vcxproj @@ -1,119 +1,119 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|ARM"> - <Configuration>Debug</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|ARM64"> - <Configuration>Debug</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM64"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|Win32"> - <Configuration>PGInstrument</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|x64"> - <Configuration>PGInstrument</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM64"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|Win32"> - <Configuration>PGUpdate</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|x64"> - <Configuration>PGUpdate</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM"> - <Configuration>Release</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM64"> - <Configuration>Release</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> - <ProjectGuid>{D06B6426-4762-44CC-8BAD-D79052507F2F}</ProjectGuid> - <RootNamespace>pyexpat</RootNamespace> - </PropertyGroup> - <Import Project="python.props" /> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>NotSet</CharacterSet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <PropertyGroup> - <TargetExt>.pyd</TargetExt> - </PropertyGroup> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="pyproject.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <ItemDefinitionGroup> - <ClCompile> - <AdditionalIncludeDirectories>$(PySourcePath)Modules\expat;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;PYEXPAT_EXPORTS;XML_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - </ItemDefinitionGroup> - <ItemGroup> - <ClInclude Include="..\Modules\expat\xmlrole.h" /> - <ClInclude Include="..\Modules\expat\xmltok.h" /> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\Modules\pyexpat.c" /> - <ClCompile Include="..\Modules\expat\xmlparse.c" /> - <ClCompile Include="..\Modules\expat\xmlrole.c" /> - <ClCompile Include="..\Modules\expat\xmltok.c" /> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\python_nt.rc" /> - </ItemGroup> - <ItemGroup> - <ProjectReference Include="pythoncore.vcxproj"> - <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> - <ReferenceOutputAssembly>false</ReferenceOutputAssembly> - </ProjectReference> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> -</Project> +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|ARM"> + <Configuration>Debug</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|ARM64"> + <Configuration>Debug</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM64"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|Win32"> + <Configuration>PGInstrument</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|x64"> + <Configuration>PGInstrument</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM64"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|Win32"> + <Configuration>PGUpdate</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|x64"> + <Configuration>PGUpdate</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM"> + <Configuration>Release</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM64"> + <Configuration>Release</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> + <ProjectGuid>{D06B6426-4762-44CC-8BAD-D79052507F2F}</ProjectGuid> + <RootNamespace>pyexpat</RootNamespace> + </PropertyGroup> + <Import Project="python.props" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <CharacterSet>NotSet</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <PropertyGroup> + <TargetExt>.pyd</TargetExt> + </PropertyGroup> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="pyproject.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <ItemDefinitionGroup> + <ClCompile> + <AdditionalIncludeDirectories>$(PySourcePath)Modules\expat;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;PYEXPAT_EXPORTS;XML_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + </ItemDefinitionGroup> + <ItemGroup> + <ClInclude Include="..\Modules\expat\xmlrole.h" /> + <ClInclude Include="..\Modules\expat\xmltok.h" /> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\Modules\pyexpat.c" /> + <ClCompile Include="..\Modules\expat\xmlparse.c" /> + <ClCompile Include="..\Modules\expat\xmlrole.c" /> + <ClCompile Include="..\Modules\expat\xmltok.c" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_nt.rc" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="pythoncore.vcxproj"> + <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> diff --git a/PCbuild/pyexpat.vcxproj.filters b/PCbuild/pyexpat.vcxproj.filters index d61c037e..fd22fc8c 100644 --- a/PCbuild/pyexpat.vcxproj.filters +++ b/PCbuild/pyexpat.vcxproj.filters @@ -1,41 +1,41 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <Filter Include="Header Files"> - <UniqueIdentifier>{ddae77a6-7ca0-4a1b-b71c-deea5f4025de}</UniqueIdentifier> - </Filter> - <Filter Include="Source Files"> - <UniqueIdentifier>{5af9d40c-fc46-4640-ad84-3d1dd34a71d7}</UniqueIdentifier> - </Filter> - <Filter Include="Resource Files"> - <UniqueIdentifier>{f1dbbdb5-41e5-4a88-bf8e-13da010c0ce4}</UniqueIdentifier> - </Filter> - </ItemGroup> - <ItemGroup> - <ClInclude Include="..\Modules\expat\xmlrole.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\Modules\expat\xmltok.h"> - <Filter>Header Files</Filter> - </ClInclude> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\Modules\pyexpat.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Modules\expat\xmlparse.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Modules\expat\xmlrole.c"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\Modules\expat\xmltok.c"> - <Filter>Source Files</Filter> - </ClCompile> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\python_nt.rc"> - <Filter>Resource Files</Filter> - </ResourceCompile> - </ItemGroup> +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Header Files"> + <UniqueIdentifier>{ddae77a6-7ca0-4a1b-b71c-deea5f4025de}</UniqueIdentifier> + </Filter> + <Filter Include="Source Files"> + <UniqueIdentifier>{5af9d40c-fc46-4640-ad84-3d1dd34a71d7}</UniqueIdentifier> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{f1dbbdb5-41e5-4a88-bf8e-13da010c0ce4}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\Modules\expat\xmlrole.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\Modules\expat\xmltok.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\Modules\pyexpat.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Modules\expat\xmlparse.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Modules\expat\xmlrole.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Modules\expat\xmltok.c"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_nt.rc"> + <Filter>Resource Files</Filter> + </ResourceCompile> + </ItemGroup> </Project> \ No newline at end of file diff --git a/PCbuild/pylauncher.vcxproj b/PCbuild/pylauncher.vcxproj index 7416a57d..35f2f7e5 100644 --- a/PCbuild/pylauncher.vcxproj +++ b/PCbuild/pylauncher.vcxproj @@ -1,114 +1,114 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|ARM"> - <Configuration>Debug</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|ARM64"> - <Configuration>Debug</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM64"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|Win32"> - <Configuration>PGInstrument</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|x64"> - <Configuration>PGInstrument</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM64"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|Win32"> - <Configuration>PGUpdate</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|x64"> - <Configuration>PGUpdate</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM"> - <Configuration>Release</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM64"> - <Configuration>Release</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectGuid>{7B2727B5-5A3F-40EE-A866-43A13CD31446}</ProjectGuid> - <RootNamespace>pylauncher</RootNamespace> - <TargetName>py</TargetName> - <SupportPGO>false</SupportPGO> - </PropertyGroup> - <Import Project="python.props" /> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <PropertyGroup> - <MakeVersionInfoBeforeTarget>ClCompile</MakeVersionInfoBeforeTarget> - </PropertyGroup> - <ImportGroup Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="pyproject.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <ItemDefinitionGroup> - <ClCompile> - <PreprocessorDefinitions>_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - </ClCompile> - <Link> - <AdditionalDependencies>shell32.lib;pathcch.lib;%(AdditionalDependencies)</AdditionalDependencies> - <SubSystem>Console</SubSystem> - </Link> - </ItemDefinitionGroup> - <ItemGroup> - <ClCompile Include="..\PC\launcher2.c" /> - </ItemGroup> - <ItemGroup> - <None Include="..\PC\launcher.ico" /> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\pylauncher.rc" /> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> -</Project> +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|ARM"> + <Configuration>Debug</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|ARM64"> + <Configuration>Debug</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM64"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|Win32"> + <Configuration>PGInstrument</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|x64"> + <Configuration>PGInstrument</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM64"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|Win32"> + <Configuration>PGUpdate</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|x64"> + <Configuration>PGUpdate</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM"> + <Configuration>Release</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM64"> + <Configuration>Release</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{7B2727B5-5A3F-40EE-A866-43A13CD31446}</ProjectGuid> + <RootNamespace>pylauncher</RootNamespace> + <TargetName>py</TargetName> + <SupportPGO>false</SupportPGO> + </PropertyGroup> + <Import Project="python.props" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <PropertyGroup> + <MakeVersionInfoBeforeTarget>ClCompile</MakeVersionInfoBeforeTarget> + </PropertyGroup> + <ImportGroup Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="pyproject.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <ItemDefinitionGroup> + <ClCompile> + <PreprocessorDefinitions>_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <AdditionalDependencies>shell32.lib;pathcch.lib;%(AdditionalDependencies)</AdditionalDependencies> + <SubSystem>Console</SubSystem> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\PC\launcher2.c" /> + </ItemGroup> + <ItemGroup> + <None Include="..\PC\launcher.ico" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\pylauncher.rc" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> diff --git a/PCbuild/pylauncher.vcxproj.filters b/PCbuild/pylauncher.vcxproj.filters index 39a8f2fd..17d0389c 100644 --- a/PCbuild/pylauncher.vcxproj.filters +++ b/PCbuild/pylauncher.vcxproj.filters @@ -1,28 +1,28 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <Filter Include="Source Files"> - <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> - <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> - </Filter> - <Filter Include="Resource Files"> - <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> - <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> - </Filter> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\PC\launcher.c"> - <Filter>Source Files</Filter> - </ClCompile> - </ItemGroup> - <ItemGroup> - <None Include="..\PC\launcher.ico"> - <Filter>Resource Files</Filter> - </None> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\pylauncher.rc"> - <Filter>Resource Files</Filter> - </ResourceCompile> - </ItemGroup> +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\PC\launcher.c"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <None Include="..\PC\launcher.ico"> + <Filter>Resource Files</Filter> + </None> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\pylauncher.rc"> + <Filter>Resource Files</Filter> + </ResourceCompile> + </ItemGroup> </Project> \ No newline at end of file diff --git a/PCbuild/pyproject.props b/PCbuild/pyproject.props index 6841ece6..fd928caf 100644 --- a/PCbuild/pyproject.props +++ b/PCbuild/pyproject.props @@ -1,243 +1,255 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" TreatAsLocalProperty="Py_IntDir"> - <Import Project="python.props" Condition="$(__Python_Props_Imported) != 'true'" /> - <PropertyGroup Label="Globals"> - <__PyProject_Props_Imported>true</__PyProject_Props_Imported> - <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> - <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion> - <OutDir>$(BuildPath)</OutDir> - <OutDir Condition="!HasTrailingSlash($(OutDir))">$(OutDir)\</OutDir> - <Py_IntDir Condition="'$(Py_IntDir)' == ''">$(MSBuildThisFileDirectory)obj\</Py_IntDir> - <IntDir>$(Py_IntDir)\$(MajorVersionNumber)$(MinorVersionNumber)$(ArchName)_$(Configuration)\$(ProjectName)\</IntDir> - <IntDir>$(IntDir.Replace(`\\`, `\`))</IntDir> - <TargetName Condition="'$(TargetName)' == ''">$(ProjectName)</TargetName> - <TargetName>$(TargetName)$(PyDebugExt)</TargetName> - <GenerateManifest>false</GenerateManifest> - <EmbedManifest>false</EmbedManifest> - <SupportPGO Condition="'$(SupportPGO)' == ''">true</SupportPGO> - <SupportSigning Condition="'$(SupportSigning)' == ''">true</SupportSigning> - <SupportSigning Condition="'$(Configuration)' == 'Debug'">false</SupportSigning> - <SupportSigning Condition="'$(ConfigurationType)' == 'StaticLibrary'">false</SupportSigning> - <LinkIncremental Condition="$(Configuration) != 'Debug'">false</LinkIncremental> - </PropertyGroup> - - <PropertyGroup> - <_DebugPreprocessorDefinition>NDEBUG;</_DebugPreprocessorDefinition> - <_DebugPreprocessorDefinition Condition="$(Configuration) == 'Debug'">_DEBUG;</_DebugPreprocessorDefinition> - <_PlatformPreprocessorDefinition>_WIN32;</_PlatformPreprocessorDefinition> - <_PlatformPreprocessorDefinition Condition="$(Platform) == 'x64'">_WIN64;_M_X64;</_PlatformPreprocessorDefinition> - <_Py3NamePreprocessorDefinition>PY3_DLLNAME=L"$(Py3DllName)";</_Py3NamePreprocessorDefinition> - </PropertyGroup> - <ItemDefinitionGroup> - <ClCompile> - <AdditionalIncludeDirectories>$(PySourcePath)Include;$(PySourcePath)Include\internal;$(PySourcePath)PC;$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>WIN32;$(_Py3NamePreprocessorDefinition);$(_PlatformPreprocessorDefinition)$(_DebugPreprocessorDefinition)$(_PydPreprocessorDefinition)%(PreprocessorDefinitions)</PreprocessorDefinitions> - - <Optimization>MaxSpeed</Optimization> - <IntrinsicFunctions>true</IntrinsicFunctions> - <StringPooling>true</StringPooling> - <ExceptionHandling></ExceptionHandling> - <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> - <FunctionLevelLinking>true</FunctionLevelLinking> - <WarningLevel>Level3</WarningLevel> - <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> - <CompileAs>Default</CompileAs> - <SuppressStartupBanner>true</SuppressStartupBanner> - <WholeProgramOptimization>true</WholeProgramOptimization> - <ControlFlowGuard Condition="$(EnableControlFlowGuard) != ''">$(EnableControlFlowGuard)</ControlFlowGuard> - <AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions> - <MultiProcessorCompilation>true</MultiProcessorCompilation> - </ClCompile> - <ClCompile Condition="$(Configuration) == 'Debug'"> - <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> - <Optimization>Disabled</Optimization> - <WholeProgramOptimization>false</WholeProgramOptimization> - <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> - </ClCompile> - <ClCompile Condition="$(ICCBuild) == 'true'"> - <FloatingPointModel>Strict</FloatingPointModel> - </ClCompile> - <Link> - <AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> - <GenerateDebugInformation>true</GenerateDebugInformation> - <ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile> - <SubSystem>Windows</SubSystem> - <RandomizedBaseAddress>true</RandomizedBaseAddress> - <DataExecutionPrevention>true</DataExecutionPrevention> - <SuppressStartupBanner>true</SuppressStartupBanner> - <IgnoreSpecificDefaultLibraries>LIBC;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries> - <TargetMachine>MachineX86</TargetMachine> - <TargetMachine Condition="'$(Platform)' == 'x64'">MachineX64</TargetMachine> - <TargetMachine Condition="'$(Platform)'=='ARM'">MachineARM</TargetMachine> - <TargetMachine Condition="'$(Platform)'=='ARM64'">MachineARM64</TargetMachine> - <ProfileGuidedDatabase Condition="$(SupportPGO)">$(OutDir)$(TargetName).pgd</ProfileGuidedDatabase> - <LinkTimeCodeGeneration Condition="$(Configuration) == 'Release'">UseLinkTimeCodeGeneration</LinkTimeCodeGeneration> - <LinkTimeCodeGeneration Condition="$(SupportPGO) and $(Configuration) == 'PGInstrument'">PGInstrument</LinkTimeCodeGeneration> - <LinkTimeCodeGeneration Condition="$(SupportPGO) and $(Configuration) == 'PGUpdate'">PGUpdate</LinkTimeCodeGeneration> - <AdditionalDependencies>advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;%(AdditionalDependencies)</AdditionalDependencies> - <AdditionalOptions Condition="$(Configuration) != 'Debug'">/OPT:REF,NOICF %(AdditionalOptions)</AdditionalOptions> - </Link> - <Lib> - <LinkTimeCodeGeneration Condition="$(Configuration) == 'Release'">true</LinkTimeCodeGeneration> - <LinkTimeCodeGeneration Condition="$(SupportPGO) and $(Configuration) == 'PGInstrument'">true</LinkTimeCodeGeneration> - <LinkTimeCodeGeneration Condition="$(SupportPGO) and $(Configuration) == 'PGUpdate'">true</LinkTimeCodeGeneration> - </Lib> - <ResourceCompile> - <AdditionalIncludeDirectories>$(PySourcePath)PC;$(PySourcePath)Include;$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>ORIGINAL_FILENAME=\"$(TargetName)$(TargetExt)\";FIELD3=$(Field3Value);$(_DebugPreprocessorDefinition)%(PreprocessorDefinitions)</PreprocessorDefinitions> - <Culture>0x0409</Culture> - </ResourceCompile> - <Midl> - <PreprocessorDefinitions>$(_DebugPreprocessorDefinition)%(PreprocessorDefinitions)</PreprocessorDefinitions> - <MkTypLibCompatible>true</MkTypLibCompatible> - <SuppressStartupBanner>true</SuppressStartupBanner> - <TargetEnvironment>Win32</TargetEnvironment> - <TargetEnvironment Condition="'$(Platform)' == 'x64'">X64</TargetEnvironment> - <OutputDirectory>$(IntDir)</OutputDirectory> - <InterfaceIdentifierFileName>$(MSBuildProjectName)_i.c</InterfaceIdentifierFileName> - <ProxyFileName>$(MSBuildProjectName)_p.c</ProxyFileName> - </Midl> - </ItemDefinitionGroup> - - <UsingTask TaskName="KillPython" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll"> - <ParameterGroup> - <FileName Required="true" /> - </ParameterGroup> - <Task> - <Using Namespace="System.Diagnostics"/> - <Using Namespace="System.IO"/> - <Using Namespace="System.Runtime.InteropServices"/> - <Using Namespace="System.Text"/> - <Code Type="Method" Language="cs"> -<![CDATA[ -[DllImport("kernel32.dll", SetLastError=true, CharSet=CharSet.Unicode)] -public static extern bool QueryFullProcessImageName([In]IntPtr hProcess, [In]int dwFlags, - [Out]StringBuilder lpExeName, ref int lpdwSize); -public override bool Execute() { - string fullPath = Path.GetFullPath(FileName); - Log.LogMessage("Looking for " + fullPath, MessageImportance.Normal); - foreach (Process p in Process.GetProcesses()) { - try { - int pathLength = 32768; - StringBuilder pathBuilder = new StringBuilder(pathLength); - if (QueryFullProcessImageName(p.Handle, 0, pathBuilder, ref pathLength)) { - string exeName = Path.GetFullPath(pathBuilder.ToString()); - Log.LogMessage("Found running process: " + exeName, MessageImportance.Low); - if (fullPath.Equals(exeName, StringComparison.OrdinalIgnoreCase)) { - Log.LogMessage("Terminating " + exeName, MessageImportance.High); - p.Kill(); - } - } - } catch { - } - } - return true; -} -]]> - </Code> - </Task> - </UsingTask> - - <Target Name="KillPython" BeforeTargets="PrepareForBuild" Condition="'$(KillPython)' == 'true'"> - <Message Text="Killing any running python$(PyDebugExt)$(PyTestExt).exe instances..." Importance="high" /> - <KillPython FileName="$(OutDir)python$(PyDebugExt)$(PyTestExt).exe" /> - </Target> - - <!-- - A default target to handle msbuild pcbuild.proj /t:CleanAll. - - Some externals projects don't respond to /t:Clean, so we invoke - CleanAll on them when we really want to clean up. - --> - <Target Name="CleanAll" DependsOnTargets="Clean"> - <MSBuild Projects="@(ProjectReference->'%(FullPath)')" - Properties="Configuration=$(Configuration);Platform=$(Platform)" - BuildInParallel="true" - StopOnFirstFailure="false" - Condition="Exists(%(FullPath))" - Targets="CleanAll" /> - </Target> - - <Target Name="CopyPGCFiles" BeforeTargets="PrepareForBuild" Condition="$(Configuration) == 'PGUpdate'"> - <ItemGroup> - <_PGCFiles Include="$(OutDir)instrumented\$(TargetName)!*.pgc" /> - <_PGDFile Include="$(OutDir)instrumented\$(TargetName).pgd" /> - <_CopyFiles Include="@(_PGCFiles);@(_PGDFile)" Condition="Exists(%(FullPath))" /> - </ItemGroup> - <Delete Files="@(_CopyFiles->'$(OutDir)%(Filename)%(Extension)')" /> - <Error Text="PGO run did not succeed (no $(TargetName)!*.pgc files) and there is no data to merge" - Condition="$(RequirePGCFiles) == 'true' and @(_PGCFiles) == ''" /> - <Copy SourceFiles="@(_CopyFiles)" - DestinationFolder="$(OutDir)" - UseHardLinksIfPossible="true" - OverwriteReadOnlyFiles="true" /> - </Target> - - <PropertyGroup> - <SdkBinPath Condition="'$(SdkBinPath)' == '' or !Exists($(SdkBinPath))">$(registry:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows Kits\Installed Roots@KitsRoot10)\bin\$(DefaultWindowsSDKVersion)\x86</SdkBinPath> - <SdkBinPath Condition="!Exists($(SdkBinPath))">$(registry:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows Kits\Installed Roots@KitsRoot10)\bin\x86</SdkBinPath> - <SdkBinPath Condition="!Exists($(SdkBinPath))">$(registry:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows Kits\Installed Roots@KitsRoot81)\bin\x86</SdkBinPath> - <SdkBinPath Condition="!Exists($(SdkBinPath))">$(registry:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows Kits\Installed Roots@KitsRoot)\bin\x86</SdkBinPath> - <SdkBinPath Condition="!Exists($(SdkBinPath))">$(registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v7.1A@InstallationFolder)\Bin\</SdkBinPath> - <_SignCommand Condition="Exists($(SdkBinPath)) and '$(SigningCertificate)' != '' and $(SupportSigning)">"$(SdkBinPath)\signtool.exe" sign /a /n "$(SigningCertificate)" /fd sha256 /tr http://timestamp.digicert.com/ /td sha256 /d "Python $(PythonVersion)"</_SignCommand> - <_SignCommand Condition="Exists($(SdkBinPath)) and '$(SigningCertificateSha1)' != '' and $(SupportSigning)">"$(SdkBinPath)\signtool.exe" sign /a /sha1 "$(SigningCertificateSha1)" /fd sha256 /tr http://timestamp.digicert.com/ /td sha256 /d "Python $(PythonVersion)"</_SignCommand> - <_MakeCatCommand Condition="Exists($(SdkBinPath))">"$(SdkBinPath)\makecat.exe"</_MakeCatCommand> - </PropertyGroup> - - <Target Name="_SignBuild" AfterTargets="AfterBuild" Condition="'$(_SignCommand)' != '' and $(SupportSigning)"> - <Error Text="Unable to locate signtool.exe. Set /p:SignToolPath and rebuild" Condition="'$(_SignCommand)' == ''" /> - <Exec Command='$(_SignCommand) "$(TargetPath)" || $(_SignCommand) "$(TargetPath)" || $(_SignCommand) "$(TargetPath)"' ContinueOnError="false" /> - </Target> - - - <Target Name="FindVCRedistDir"> - <!-- Hard coded path for VS 2015 --> - <PropertyGroup Condition="$(PlatformToolset) == 'v140'"> - <VCRedistDir>$(VCInstallDir)\redist\</VCRedistDir> - </PropertyGroup> - - <!-- Search for version number in some broken Build Tools installs --> - <ItemGroup Condition="$(VCRedistDir) == '' and $(VCToolsRedistVersion) == ''"> - <_RedistFiles Include="$(VCInstallDir)\Redist\MSVC\*\*.*" /> - </ItemGroup> - <PropertyGroup Condition="$(VCRedistDir) == '' and $(VCToolsRedistVersion) == ''"> - <_RedistDir>%(_RedistFiles.Directory)</_RedistDir> - <VCToolsRedistVersion>$([System.IO.Path]::GetFileName($(_RedistDir.Trim(`\`))))</VCToolsRedistVersion> - </PropertyGroup> - - <!-- Use correct path for VS 2017 and later --> - <PropertyGroup Condition="$(VCRedistDir) == ''"> - <VCRedistDir>$(VCInstallDir)\Redist\MSVC\$(VCToolsRedistVersion)\</VCRedistDir> - </PropertyGroup> - - <PropertyGroup> - <VCRedistDir Condition="$(Platform) == 'Win32'">$(VCRedistDir)x86\</VCRedistDir> - <VCRedistDir Condition="$(Platform) != 'Win32'">$(VCRedistDir)$(Platform)\</VCRedistDir> - </PropertyGroup> - - <Message Text="VC Redist Directory: $(VCRedistDir)" /> - <Message Text="VC Redist Version: $(VCToolsRedistVersion)" /> - </Target> - - <Target Name="FindVCRuntime" Returns="VCRuntimeDLL" DependsOnTargets="FindVCRedistDir"> - <ItemGroup Condition="$(VCInstallDir) != ''"> - <VCRuntimeDLL Include="$(VCRedistDir)\Microsoft.VC*.CRT\vcruntime*.dll" /> - </ItemGroup> - - <Warning Text="vcruntime*.dll not found under $(VCRedistDir)." Condition="@(VCRuntimeDLL) == ''" /> - <Message Text="VC Runtime DLL(s):%0A- @(VCRuntimeDLL,'%0A- ')" /> - </Target> - - <Target Name="FindPythonForBuild" Condition="$(PythonForBuild) == ''"> - <Exec Command=""$(MSBuildThisFileDirectory)\find_python.bat" -q" - EchoOff="true" - ConsoleToMsBuild="true"> - <Output TaskParameter="ConsoleOutput" ItemName="_CmdExeLines" /> - </Exec> - <PropertyGroup> - <PythonForBuild>@(_CmdExeLines)</PythonForBuild> - </PropertyGroup> - <Error Text="Failed to locate suitable Python runtime for building from source." Condition="$(PythonForBuild)==''" /> - <Message Text="Using PythonForBuild=$(PythonForBuild)" Importance="high" /> - </Target> -</Project> +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" TreatAsLocalProperty="Py_IntDir"> + <Import Project="python.props" Condition="$(__Python_Props_Imported) != 'true'" /> + <PropertyGroup Label="Globals"> + <__PyProject_Props_Imported>true</__PyProject_Props_Imported> + <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> + <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion> + <OutDir>$(BuildPath)</OutDir> + <OutDir Condition="!HasTrailingSlash($(OutDir))">$(OutDir)\</OutDir> + <Py_IntDir Condition="'$(Py_IntDir)' == ''">$(MSBuildThisFileDirectory)obj\</Py_IntDir> + <IntDir>$(Py_IntDir)\$(MajorVersionNumber)$(MinorVersionNumber)$(ArchName)_$(Configuration)\$(ProjectName)\</IntDir> + <IntDir>$(IntDir.Replace(`\\`, `\`))</IntDir> + <TargetName Condition="'$(TargetName)' == ''">$(ProjectName)</TargetName> + <TargetName>$(TargetName)$(PyDebugExt)</TargetName> + <GenerateManifest>false</GenerateManifest> + <EmbedManifest>false</EmbedManifest> + <SupportPGO Condition="'$(SupportPGO)' == ''">true</SupportPGO> + <SupportSigning Condition="'$(SupportSigning)' == ''">true</SupportSigning> + <SupportSigning Condition="'$(Configuration)' == 'Debug'">false</SupportSigning> + <SupportSigning Condition="'$(ConfigurationType)' == 'StaticLibrary'">false</SupportSigning> + <LinkIncremental Condition="$(Configuration) != 'Debug'">false</LinkIncremental> + </PropertyGroup> + + <PropertyGroup Label="MSVC Bug Workarounds" Condition="$(VCToolsVersion) != ''"> + <_VCToolsVersion>$([System.Version]::Parse(`$(VCToolsVersion)`).Major).$([System.Version]::Parse(`$(VCToolsVersion)`).Minor)</_VCToolsVersion> + + <!-- See https://developercommunity.visualstudio.com/t/Regression-in-MSVC-1433-1434-ARM64-co/10224361 --> + <MSVCHasBrokenARM64Clamping Condition="$(_VCToolsVersion) == '14.34' or $(_VCToolsVersion) == '14.35'">true</MSVCHasBrokenARM64Clamping> + </PropertyGroup> + + <PropertyGroup> + <_DebugPreprocessorDefinition>NDEBUG;</_DebugPreprocessorDefinition> + <_DebugPreprocessorDefinition Condition="$(Configuration) == 'Debug'">_DEBUG;</_DebugPreprocessorDefinition> + <_PlatformPreprocessorDefinition>_WIN32;</_PlatformPreprocessorDefinition> + <_PlatformPreprocessorDefinition Condition="$(Platform) == 'x64'">_WIN64;</_PlatformPreprocessorDefinition> + <_PlatformPreprocessorDefinition Condition="$(Platform) == 'x64' and $(PlatformToolset) != 'ClangCL'">_M_X64;$(_PlatformPreprocessorDefinition)</_PlatformPreprocessorDefinition> + <_Py3NamePreprocessorDefinition>PY3_DLLNAME=L"$(Py3DllName)";</_Py3NamePreprocessorDefinition> + </PropertyGroup> + <ItemDefinitionGroup> + <ClCompile> + <AdditionalIncludeDirectories>$(PySourcePath)Include;$(PySourcePath)Include\internal;$(PySourcePath)PC;$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;$(_Py3NamePreprocessorDefinition);$(_PlatformPreprocessorDefinition)$(_DebugPreprocessorDefinition)$(_PydPreprocessorDefinition)%(PreprocessorDefinitions)</PreprocessorDefinitions> + + <Optimization>MaxSpeed</Optimization> + <IntrinsicFunctions>true</IntrinsicFunctions> + <StringPooling>true</StringPooling> + <ExceptionHandling></ExceptionHandling> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <FunctionLevelLinking>true</FunctionLevelLinking> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + <CompileAs>Default</CompileAs> + <SuppressStartupBanner>true</SuppressStartupBanner> + <WholeProgramOptimization>true</WholeProgramOptimization> + <ControlFlowGuard Condition="$(EnableControlFlowGuard) != ''">$(EnableControlFlowGuard)</ControlFlowGuard> + <MultiProcessorCompilation>true</MultiProcessorCompilation> + <AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions> + <AdditionalOptions Condition="$(PlatformToolset) == 'ClangCL'">-Wno-deprecated-non-prototype -Wno-unused-label -Wno-pointer-sign -Wno-incompatible-pointer-types-discards-qualifiers -Wno-unused-function %(AdditionalOptions)</AdditionalOptions> + <AdditionalOptions Condition="$(Configuration) != 'Debug' and $(PlatformToolset) == 'ClangCL'">-flto %(AdditionalOptions)</AdditionalOptions> + <AdditionalOptions Condition="$(MSVCHasBrokenARM64Clamping) == 'true' and $(Platform) == 'ARM64'">-d2pattern-opt-disable:-932189325 %(AdditionalOptions)</AdditionalOptions> + </ClCompile> + <ClCompile Condition="$(Configuration) == 'Debug'"> + <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion> + <Optimization>Disabled</Optimization> + <WholeProgramOptimization>false</WholeProgramOptimization> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + </ClCompile> + <ClCompile Condition="$(ICCBuild) == 'true'"> + <FloatingPointModel>Strict</FloatingPointModel> + </ClCompile> + <Link> + <AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + <GenerateDebugInformation>true</GenerateDebugInformation> + <ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile> + <SubSystem>Windows</SubSystem> + <RandomizedBaseAddress>true</RandomizedBaseAddress> + <DataExecutionPrevention>true</DataExecutionPrevention> + <SuppressStartupBanner>true</SuppressStartupBanner> + <IgnoreSpecificDefaultLibraries>LIBC;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries> + <TargetMachine>MachineX86</TargetMachine> + <TargetMachine Condition="'$(Platform)' == 'x64'">MachineX64</TargetMachine> + <TargetMachine Condition="'$(Platform)'=='ARM'">MachineARM</TargetMachine> + <TargetMachine Condition="'$(Platform)'=='ARM64'">MachineARM64</TargetMachine> + <ProfileGuidedDatabase Condition="$(SupportPGO)">$(OutDir)$(TargetName).pgd</ProfileGuidedDatabase> + <LinkTimeCodeGeneration Condition="$(Configuration) == 'Release'">UseLinkTimeCodeGeneration</LinkTimeCodeGeneration> + <LinkTimeCodeGeneration Condition="$(SupportPGO) and $(Configuration) == 'PGInstrument'">PGInstrument</LinkTimeCodeGeneration> + <LinkTimeCodeGeneration Condition="$(SupportPGO) and $(Configuration) == 'PGUpdate'">PGUpdate</LinkTimeCodeGeneration> + <AdditionalDependencies>advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalOptions Condition="$(Configuration) != 'Debug'">/OPT:REF,NOICF %(AdditionalOptions)</AdditionalOptions> + <AdditionalOptions Condition="$(MSVCHasBrokenARM64Clamping) == 'true' and $(Platform) == 'ARM64'">-d2:-pattern-opt-disable:-932189325 %(AdditionalOptions)</AdditionalOptions> + </Link> + <Lib> + <LinkTimeCodeGeneration Condition="$(Configuration) == 'Release'">true</LinkTimeCodeGeneration> + <LinkTimeCodeGeneration Condition="$(SupportPGO) and $(Configuration) == 'PGInstrument'">true</LinkTimeCodeGeneration> + <LinkTimeCodeGeneration Condition="$(SupportPGO) and $(Configuration) == 'PGUpdate'">true</LinkTimeCodeGeneration> + </Lib> + <ResourceCompile> + <AdditionalIncludeDirectories>$(PySourcePath)PC;$(PySourcePath)Include;$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>ORIGINAL_FILENAME=\"$(TargetName)$(TargetExt)\";FIELD3=$(Field3Value);$(_DebugPreprocessorDefinition)%(PreprocessorDefinitions)</PreprocessorDefinitions> + <Culture>0x0409</Culture> + </ResourceCompile> + <Midl> + <PreprocessorDefinitions>$(_DebugPreprocessorDefinition)%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MkTypLibCompatible>true</MkTypLibCompatible> + <SuppressStartupBanner>true</SuppressStartupBanner> + <TargetEnvironment>Win32</TargetEnvironment> + <TargetEnvironment Condition="'$(Platform)' == 'x64'">X64</TargetEnvironment> + <OutputDirectory>$(IntDir)</OutputDirectory> + <InterfaceIdentifierFileName>$(MSBuildProjectName)_i.c</InterfaceIdentifierFileName> + <ProxyFileName>$(MSBuildProjectName)_p.c</ProxyFileName> + </Midl> + </ItemDefinitionGroup> + + <UsingTask TaskName="KillPython" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll"> + <ParameterGroup> + <FileName Required="true" /> + </ParameterGroup> + <Task> + <Using Namespace="System.Diagnostics"/> + <Using Namespace="System.IO"/> + <Using Namespace="System.Runtime.InteropServices"/> + <Using Namespace="System.Text"/> + <Code Type="Method" Language="cs"> +<![CDATA[ +[DllImport("kernel32.dll", SetLastError=true, CharSet=CharSet.Unicode)] +public static extern bool QueryFullProcessImageName([In]IntPtr hProcess, [In]int dwFlags, + [Out]StringBuilder lpExeName, ref int lpdwSize); +public override bool Execute() { + string fullPath = Path.GetFullPath(FileName); + Log.LogMessage("Looking for " + fullPath, MessageImportance.Normal); + foreach (Process p in Process.GetProcesses()) { + try { + int pathLength = 32768; + StringBuilder pathBuilder = new StringBuilder(pathLength); + if (QueryFullProcessImageName(p.Handle, 0, pathBuilder, ref pathLength)) { + string exeName = Path.GetFullPath(pathBuilder.ToString()); + Log.LogMessage("Found running process: " + exeName, MessageImportance.Low); + if (fullPath.Equals(exeName, StringComparison.OrdinalIgnoreCase)) { + Log.LogMessage("Terminating " + exeName, MessageImportance.High); + p.Kill(); + } + } + } catch { + } + } + return true; +} +]]> + </Code> + </Task> + </UsingTask> + + <Target Name="KillPython" BeforeTargets="PrepareForBuild" Condition="'$(KillPython)' == 'true'"> + <Message Text="Killing any running python$(PyDebugExt)$(PyTestExt).exe instances..." Importance="high" /> + <KillPython FileName="$(OutDir)python$(PyDebugExt)$(PyTestExt).exe" /> + </Target> + + <!-- + A default target to handle msbuild pcbuild.proj /t:CleanAll. + + Some externals projects don't respond to /t:Clean, so we invoke + CleanAll on them when we really want to clean up. + --> + <Target Name="CleanAll" DependsOnTargets="Clean"> + <MSBuild Projects="@(ProjectReference->'%(FullPath)')" + Properties="Configuration=$(Configuration);Platform=$(Platform)" + BuildInParallel="true" + StopOnFirstFailure="false" + Condition="Exists(%(FullPath))" + Targets="CleanAll" /> + </Target> + + <Target Name="CopyPGCFiles" BeforeTargets="PrepareForBuild" Condition="$(Configuration) == 'PGUpdate'"> + <ItemGroup> + <_PGCFiles Include="$(OutDir)instrumented\$(TargetName)!*.pgc" /> + <_PGDFile Include="$(OutDir)instrumented\$(TargetName).pgd" /> + <_CopyFiles Include="@(_PGCFiles);@(_PGDFile)" Condition="Exists(%(FullPath))" /> + </ItemGroup> + <Delete Files="@(_CopyFiles->'$(OutDir)%(Filename)%(Extension)')" /> + <Error Text="PGO run did not succeed (no $(TargetName)!*.pgc files) and there is no data to merge" + Condition="$(RequirePGCFiles) == 'true' and @(_PGCFiles) == ''" /> + <Copy SourceFiles="@(_CopyFiles)" + DestinationFolder="$(OutDir)" + UseHardLinksIfPossible="true" + OverwriteReadOnlyFiles="true" /> + </Target> + + <PropertyGroup> + <SdkBinPath Condition="'$(SdkBinPath)' == '' or !Exists($(SdkBinPath))">$(registry:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows Kits\Installed Roots@KitsRoot10)\bin\$(DefaultWindowsSDKVersion)\x86</SdkBinPath> + <SdkBinPath Condition="!Exists($(SdkBinPath))">$(registry:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows Kits\Installed Roots@KitsRoot10)\bin\x86</SdkBinPath> + <SdkBinPath Condition="!Exists($(SdkBinPath))">$(registry:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows Kits\Installed Roots@KitsRoot81)\bin\x86</SdkBinPath> + <SdkBinPath Condition="!Exists($(SdkBinPath))">$(registry:HKEY_LOCAL_MACHINE\Software\Microsoft\Windows Kits\Installed Roots@KitsRoot)\bin\x86</SdkBinPath> + <SdkBinPath Condition="!Exists($(SdkBinPath))">$(registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v7.1A@InstallationFolder)\Bin\</SdkBinPath> + <_SignCommand Condition="Exists($(SdkBinPath)) and '$(SigningCertificate)' != '' and $(SupportSigning)">"$(SdkBinPath)\signtool.exe" sign /a /n "$(SigningCertificate)" /fd sha256 /tr http://timestamp.digicert.com/ /td sha256 /d "Python $(PythonVersion)"</_SignCommand> + <_SignCommand Condition="Exists($(SdkBinPath)) and '$(SigningCertificateSha1)' != '' and $(SupportSigning)">"$(SdkBinPath)\signtool.exe" sign /a /sha1 "$(SigningCertificateSha1)" /fd sha256 /tr http://timestamp.digicert.com/ /td sha256 /d "Python $(PythonVersion)"</_SignCommand> + <_MakeCatCommand Condition="Exists($(SdkBinPath))">"$(SdkBinPath)\makecat.exe"</_MakeCatCommand> + </PropertyGroup> + + <Target Name="_SignBuild" AfterTargets="AfterBuild" Condition="'$(_SignCommand)' != '' and $(SupportSigning)"> + <Error Text="Unable to locate signtool.exe. Set /p:SignToolPath and rebuild" Condition="'$(_SignCommand)' == ''" /> + <Exec Command='$(_SignCommand) "$(TargetPath)" || $(_SignCommand) "$(TargetPath)" || $(_SignCommand) "$(TargetPath)"' ContinueOnError="false" /> + </Target> + + + <Target Name="FindVCRedistDir"> + <!-- Hard coded path for VS 2015 --> + <PropertyGroup Condition="$(PlatformToolset) == 'v140'"> + <VCRedistDir>$(VCInstallDir)\redist\</VCRedistDir> + </PropertyGroup> + + <!-- Search for version number in some broken Build Tools installs --> + <ItemGroup Condition="$(VCRedistDir) == '' and $(VCToolsRedistVersion) == ''"> + <_RedistFiles Include="$(VCInstallDir)\Redist\MSVC\*\*.*" /> + </ItemGroup> + <PropertyGroup Condition="$(VCRedistDir) == '' and $(VCToolsRedistVersion) == ''"> + <_RedistDir>%(_RedistFiles.Directory)</_RedistDir> + <VCToolsRedistVersion>$([System.IO.Path]::GetFileName($(_RedistDir.Trim(`\`))))</VCToolsRedistVersion> + </PropertyGroup> + + <!-- Use correct path for VS 2017 and later --> + <PropertyGroup Condition="$(VCRedistDir) == ''"> + <VCRedistDir>$(VCInstallDir)\Redist\MSVC\$(VCToolsRedistVersion)\</VCRedistDir> + </PropertyGroup> + + <PropertyGroup> + <VCRedistDir Condition="$(Platform) == 'Win32'">$(VCRedistDir)x86\</VCRedistDir> + <VCRedistDir Condition="$(Platform) != 'Win32'">$(VCRedistDir)$(Platform)\</VCRedistDir> + </PropertyGroup> + + <Message Text="VC Redist Directory: $(VCRedistDir)" /> + <Message Text="VC Redist Version: $(VCToolsRedistVersion)" /> + </Target> + + <Target Name="FindVCRuntime" Returns="VCRuntimeDLL" DependsOnTargets="FindVCRedistDir"> + <ItemGroup Condition="$(VCInstallDir) != ''"> + <VCRuntimeDLL Include="$(VCRedistDir)\Microsoft.VC*.CRT\vcruntime*.dll" /> + </ItemGroup> + + <Warning Text="vcruntime*.dll not found under $(VCRedistDir)." Condition="@(VCRuntimeDLL) == ''" /> + <Message Text="VC Runtime DLL(s):%0A- @(VCRuntimeDLL,'%0A- ')" /> + </Target> + + <Target Name="FindPythonForBuild" Condition="$(PythonForBuild) == ''"> + <Exec Command=""$(MSBuildThisFileDirectory)\find_python.bat" -q" + EchoOff="true" + ConsoleToMsBuild="true"> + <Output TaskParameter="ConsoleOutput" ItemName="_CmdExeLines" /> + </Exec> + <PropertyGroup> + <PythonForBuild>@(_CmdExeLines)</PythonForBuild> + </PropertyGroup> + <Error Text="Failed to locate suitable Python runtime for building from source." Condition="$(PythonForBuild)==''" /> + <Message Text="Using PythonForBuild=$(PythonForBuild)" Importance="high" /> + </Target> +</Project> diff --git a/PCbuild/pyshellext.vcxproj b/PCbuild/pyshellext.vcxproj index 18ea9119..ea432d6b 100644 --- a/PCbuild/pyshellext.vcxproj +++ b/PCbuild/pyshellext.vcxproj @@ -1,117 +1,117 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|ARM"> - <Configuration>Debug</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|ARM64"> - <Configuration>Debug</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM64"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|Win32"> - <Configuration>PGInstrument</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|x64"> - <Configuration>PGInstrument</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM64"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|Win32"> - <Configuration>PGUpdate</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|x64"> - <Configuration>PGUpdate</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM"> - <Configuration>Release</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM64"> - <Configuration>Release</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectGuid>{0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}</ProjectGuid> - <RootNamespace>pyshellext</RootNamespace> - <TargetName>pyshellext</TargetName> - <SupportPGO>false</SupportPGO> - </PropertyGroup> - <Import Project="python.props" /> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <PropertyGroup> - <MakeVersionInfoBeforeTarget>ClCompile</MakeVersionInfoBeforeTarget> - </PropertyGroup> - <ImportGroup Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="pyproject.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <ItemDefinitionGroup> - <ClCompile> - <PreprocessorDefinitions>_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <Link> - <AdditionalDependencies>version.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies> - <SubSystem>Console</SubSystem> - <ModuleDefinitionFile>..\PC\pyshellext.def</ModuleDefinitionFile> - </Link> - <Midl> - <CompileInterface>true</CompileInterface> - </Midl> - </ItemDefinitionGroup> - <ItemGroup> - <ClCompile Include="..\PC\pyshellext.cpp" /> - </ItemGroup> - <ItemGroup> - <None Include="..\PC\pyshellext.def" /> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\pyshellext.rc" /> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|ARM"> + <Configuration>Debug</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|ARM64"> + <Configuration>Debug</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM64"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|Win32"> + <Configuration>PGInstrument</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|x64"> + <Configuration>PGInstrument</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM64"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|Win32"> + <Configuration>PGUpdate</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|x64"> + <Configuration>PGUpdate</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM"> + <Configuration>Release</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM64"> + <Configuration>Release</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}</ProjectGuid> + <RootNamespace>pyshellext</RootNamespace> + <TargetName>pyshellext</TargetName> + <SupportPGO>false</SupportPGO> + </PropertyGroup> + <Import Project="python.props" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <PropertyGroup> + <MakeVersionInfoBeforeTarget>ClCompile</MakeVersionInfoBeforeTarget> + </PropertyGroup> + <ImportGroup Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="pyproject.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <ItemDefinitionGroup> + <ClCompile> + <PreprocessorDefinitions>_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <Link> + <AdditionalDependencies>version.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies> + <SubSystem>Console</SubSystem> + <ModuleDefinitionFile>..\PC\pyshellext.def</ModuleDefinitionFile> + </Link> + <Midl> + <CompileInterface>true</CompileInterface> + </Midl> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\PC\pyshellext.cpp" /> + </ItemGroup> + <ItemGroup> + <None Include="..\PC\pyshellext.def" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\pyshellext.rc" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> </Project> \ No newline at end of file diff --git a/PCbuild/pyshellext.vcxproj.filters b/PCbuild/pyshellext.vcxproj.filters index e00aec99..77cd3060 100644 --- a/PCbuild/pyshellext.vcxproj.filters +++ b/PCbuild/pyshellext.vcxproj.filters @@ -1,28 +1,28 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <Filter Include="Source Files"> - <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> - <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> - </Filter> - <Filter Include="Resource Files"> - <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> - <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> - </Filter> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\PC\pyshellext.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\pyshellext.rc"> - <Filter>Resource Files</Filter> - </ResourceCompile> - </ItemGroup> - <ItemGroup> - <None Include="..\PC\pyshellext.def"> - <Filter>Source Files</Filter> - </None> - </ItemGroup> +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\PC\pyshellext.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\pyshellext.rc"> + <Filter>Resource Files</Filter> + </ResourceCompile> + </ItemGroup> + <ItemGroup> + <None Include="..\PC\pyshellext.def"> + <Filter>Source Files</Filter> + </None> + </ItemGroup> </Project> \ No newline at end of file diff --git a/PCbuild/python.props b/PCbuild/python.props index 80430c02..35c6e92b 100644 --- a/PCbuild/python.props +++ b/PCbuild/python.props @@ -1,253 +1,253 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <PropertyGroup> - <__Python_Props_Imported>true</__Python_Props_Imported> - <Platform Condition="'$(Platform)' == ''">Win32</Platform> - <Configuration Condition="'$(Configuration)' == ''">Release</Configuration> - <!-- - Use the latest available version of Visual Studio to build. To override - this and build with an earlier version, pass "/p:PlatformToolset=v100" - (for example) when building. - - We set BasePlatformToolset for ICC's benefit, it's otherwise ignored. - --> - <BasePlatformToolset Condition="'$(BasePlatformToolset)' == '' and '$(VisualStudioVersion)' == '17.0'">v143</BasePlatformToolset> - <BasePlatformToolset Condition="'$(BasePlatformToolset)' == '' and '$(VisualStudioVersion)' == '16.0'">v142</BasePlatformToolset> - <BasePlatformToolset Condition="'$(BasePlatformToolset)' == '' and ('$(MSBuildToolsVersion)' == '15.0' or '$(VisualStudioVersion)' == '15.0')">v141</BasePlatformToolset> - <BasePlatformToolset Condition="'$(BasePlatformToolset)' == '' and '$(VCTargetsPath14)' != ''">v140</BasePlatformToolset> - <BasePlatformToolset Condition="'$(BasePlatformToolset)' == '' and '$(VCTargetsPath12)' != ''">v120</BasePlatformToolset> - <BasePlatformToolset Condition="'$(BasePlatformToolset)' == '' and '$(VCTargetsPath11)' != ''">v110</BasePlatformToolset> - <BasePlatformToolset Condition="'$(BasePlatformToolset)' == '' and '$(VCTargetsPath10)' != ''">v100</BasePlatformToolset> - - <PlatformToolset Condition="'$(PlatformToolset)' == ''">$(BasePlatformToolset)</PlatformToolset> - <ICCBuild>false</ICCBuild> - <ICCBuild Condition="$(PlatformToolset.StartsWith(`Intel C++ Compiler`))">true</ICCBuild> - - <!-- - Convincing MSVC/MSBuild to prefer our platform names is too difficult, - so we define our own constant ArchName and use wherever we need it. - --> - <ArchName Condition="'$(ArchName)' == '' and $(Platform) == 'x64'">amd64</ArchName> - <ArchName Condition="'$(ArchName)' == '' and $(Platform) == 'ARM'">arm32</ArchName> - <ArchName Condition="'$(ArchName)' == '' and $(Platform) == 'ARM64'">arm64</ArchName> - <ArchName Condition="'$(ArchName)' == ''">win32</ArchName> - - <!-- Root directory of the repository --> - <PySourcePath Condition="'$(PySourcePath)' == ''">$([System.IO.Path]::GetFullPath($(MSBuildThisFileDirectory)\..\))</PySourcePath> - <PySourcePath Condition="!HasTrailingSlash($(PySourcePath))">$(PySourcePath)\</PySourcePath> - - <!-- Directory where build outputs are put --> - <BuildPath32 Condition="'$(Py_OutDir)' == ''">$(PySourcePath)PCbuild\win32\</BuildPath32> - <BuildPath32 Condition="'$(Py_OutDir)' != ''">$(Py_OutDir)\win32\</BuildPath32> - <BuildPath64 Condition="'$(Py_OutDir)' == ''">$(PySourcePath)PCbuild\amd64\</BuildPath64> - <BuildPath64 Condition="'$(Py_OutDir)' != ''">$(Py_OutDir)\amd64\</BuildPath64> - <BuildPathArm32 Condition="'$(Py_OutDir)' == ''">$(PySourcePath)PCbuild\arm32\</BuildPathArm32> - <BuildPathArm32 Condition="'$(Py_OutDir)' != ''">$(Py_OutDir)\arm32\</BuildPathArm32> - <BuildPathArm64 Condition="'$(Py_OutDir)' == ''">$(PySourcePath)PCbuild\arm64\</BuildPathArm64> - <BuildPathArm64 Condition="'$(Py_OutDir)' != ''">$(Py_OutDir)\arm64\</BuildPathArm64> - <BuildPath Condition="'$(ArchName)' == 'win32'">$(BuildPath32)</BuildPath> - <BuildPath Condition="'$(ArchName)' == 'amd64'">$(BuildPath64)</BuildPath> - <BuildPath Condition="'$(ArchName)' == 'arm32'">$(BuildPathArm32)</BuildPath> - <BuildPath Condition="'$(ArchName)' == 'arm64'">$(BuildPathArm64)</BuildPath> - <BuildPath Condition="'$(BuildPath)' == ''">$(PySourcePath)PCbuild\$(ArchName)\</BuildPath> - <BuildPath Condition="!HasTrailingSlash($(BuildPath))">$(BuildPath)\</BuildPath> - <BuildPath Condition="$(Configuration) == 'PGInstrument'">$(BuildPath)instrumented\</BuildPath> - - <!-- VPATH definition (escaped) --> - <PyVPath Condition="$(Configuration) != 'PGInstrument'">..\\..</PyVPath> - <PyVPath Condition="$(Configuration) == 'PGInstrument'">..\\..\\..</PyVPath> - </PropertyGroup> - - <!-- Directories of external projects. tcltk is handled in tcltk.props --> - <PropertyGroup> - <ExternalsDir Condition="$(ExternalsDir) == ''">$(EXTERNALS_DIR)</ExternalsDir> - <ExternalsDir Condition="$(ExternalsDir) == ''">$([System.IO.Path]::GetFullPath(`$(PySourcePath)externals`))</ExternalsDir> - <ExternalsDir Condition="!HasTrailingSlash($(ExternalsDir))">$(ExternalsDir)\</ExternalsDir> - </PropertyGroup> - - <Import Project="$(ExternalProps)" Condition="$(ExternalProps) != '' and Exists('$(ExternalProps)')" /> - - <PropertyGroup> - <sqlite3Dir Condition="$(sqlite3Dir) == ''">$(ExternalsDir)sqlite-3.39.4.0\</sqlite3Dir> - <bz2Dir Condition="$(bz2Dir) == ''">$(ExternalsDir)bzip2-1.0.8\</bz2Dir> - <lzmaDir Condition="$(lzmaDir) == ''">$(ExternalsDir)xz-5.2.5\</lzmaDir> - <libffiDir Condition="$(libffiDir) == ''">$(ExternalsDir)libffi-3.4.3\</libffiDir> - <libffiOutDir Condition="$(libffiOutDir) == ''">$(libffiDir)$(ArchName)\</libffiOutDir> - <libffiIncludeDir Condition="$(libffiIncludeDir) == ''">$(libffiOutDir)include</libffiIncludeDir> - <opensslDir Condition="$(opensslDir) == ''">$(ExternalsDir)openssl-1.1.1s\</opensslDir> - <opensslOutDir Condition="$(opensslOutDir) == ''">$(ExternalsDir)openssl-bin-1.1.1s\$(ArchName)\</opensslOutDir> - <opensslIncludeDir Condition="$(opensslIncludeDir) == ''">$(opensslOutDir)include</opensslIncludeDir> - <nasmDir Condition="$(nasmDir) == ''">$(ExternalsDir)\nasm-2.11.06\</nasmDir> - <zlibDir Condition="$(zlibDir) == ''">$(ExternalsDir)\zlib-1.2.13\</zlibDir> - </PropertyGroup> - - <PropertyGroup> - <!-- Suffix for all binaries when building for debug --> - <PyDebugExt Condition="'$(PyDebugExt)' == '' and $(Configuration) == 'Debug'">_d</PyDebugExt> - - <!-- Suffix for versions/keys when building with test markers --> - <PyTestExt Condition="$(UseTestMarker) == 'true'">-test</PyTestExt> - - <!-- Suffix for versions/keys when building for particular platforms --> - <PyArchExt Condition="'$(ArchName)' == 'win32'">-32</PyArchExt> - <PyArchExt Condition="'$(ArchName)' == 'arm32'">-arm32</PyArchExt> - <PyArchExt Condition="'$(ArchName)' == 'arm64'">-arm64</PyArchExt> - - <!-- Full path of the resulting python.exe binary --> - <PythonExe Condition="'$(PythonExe)' == ''">$(BuildPath)python$(PyDebugExt).exe</PythonExe> - - <!-- Include Tkinter by default --> - <IncludeTkinter Condition="'$(IncludeTkinter)' == ''">true</IncludeTkinter> - </PropertyGroup> - - <PropertyGroup Condition="'$(Platform)'=='ARM'" Label="ArmConfiguration"> - <WindowsSDKDesktopARMSupport>true</WindowsSDKDesktopARMSupport> - </PropertyGroup> - - <PropertyGroup Condition="'$(Platform)'=='ARM64'" Label="Arm64Configuration"> - <WindowsSDKDesktopARMSupport>true</WindowsSDKDesktopARMSupport> - </PropertyGroup> - - <PropertyGroup Condition="$(DefaultWindowsSDKVersion) == ''"> - <!-- - Attempt to select the latest installed WinSDK. If we don't find any, then we will - let the MSBuild targets determine which one it wants to use (typically the earliest - possible version). Since we limit WINVER to Windows 7 anyway, it doesn't really - matter which WinSDK version we use. - --> - <_RegistryVersion>$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v10.0@ProductVersion)</_RegistryVersion> - <_RegistryVersion Condition="$(_RegistryVersion) == ''">$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Microsoft SDKs\Windows\v10.0@ProductVersion)</_RegistryVersion> - <!-- Sometimes the version in the registry has to .0 suffix, and sometimes it doesn't. Check and add it --> - <_RegistryVersion Condition="$(_RegistryVersion) != '' and !$(_RegistryVersion.EndsWith('.0'))">$(_RegistryVersion).0</_RegistryVersion> - - <!-- The minimum allowed SDK version to use for building --> - <DefaultWindowsSDKVersion>10.0.10586.0</DefaultWindowsSDKVersion> - <DefaultWindowsSDKVersion Condition="$(_RegistryVersion) != '' and $([System.Version]::Parse($(_RegistryVersion))) > $([System.Version]::Parse($(DefaultWindowsSDKVersion)))">$(_RegistryVersion)</DefaultWindowsSDKVersion> - </PropertyGroup> - - <Target Name="_CheckWindowsSDKFound" BeforeTargets="_CheckWindowsSDKInstalled" Condition="$(_RegistryVersion) == ''"> - <PropertyGroup> - <_Message>Failed to locate a Windows SDK installation.</_Message> - <_Message>$(_Message) If the build fails, please use the Visual Studio Installer to install the Windows SDK.</_Message> - <_Message>$(_Message) (Ignore the version number specified in the error message and select the latest.)</_Message> - </PropertyGroup> - <Warning Text="$(_Message)" /> - </Target> - - <PropertyGroup Condition="$(WindowsTargetPlatformVersion) == ''"> - <WindowsTargetPlatformVersion>$(DefaultWindowsSDKVersion)</WindowsTargetPlatformVersion> - </PropertyGroup> - - <PropertyGroup Condition="'$(OverrideVersion)' == ''"> - <!-- - Read version information from Include\patchlevel.h. The following properties are set: - - MajorVersionNumber - the '3' in '3.5.2a1' - MinorVersionNumber - the '5' in '3.5.2a1' - MicroVersionNumber - the '2' in '3.5.2a1' - ReleaseSerial - the '1' in '3.5.2a1' - ReleaseLevelName - the 'a1' in '3.5.2a1' - PythonVersionNumber - '3.5.2' for '3.5.2a1' - PythonVersion - '3.5.2a1' - PythonVersionHex - 0x030502a1 for '3.5.2a1' - ReleaseLevelNumber - 10 for alpha, 11 for beta, 12 for RC (gamma), and 15 for final - Field3Value - 2101 for '3.5.2a1' (== 1000*2 + 10*10 ('a') + 1) - --> - <_PatchLevelContent>$([System.IO.File]::ReadAllText(`$(PySourcePath)Include\patchlevel.h`))</_PatchLevelContent> - <MajorVersionNumber>$([System.Text.RegularExpressions.Regex]::Match($(_PatchLevelContent), `define\s+PY_MAJOR_VERSION\s+(\d+)`).Groups[1].Value)</MajorVersionNumber> - <MinorVersionNumber>$([System.Text.RegularExpressions.Regex]::Match($(_PatchLevelContent), `define\s+PY_MINOR_VERSION\s+(\d+)`).Groups[1].Value)</MinorVersionNumber> - <MicroVersionNumber>$([System.Text.RegularExpressions.Regex]::Match($(_PatchLevelContent), `define\s+PY_MICRO_VERSION\s+(\d+)`).Groups[1].Value)</MicroVersionNumber> - <_ReleaseLevel>$([System.Text.RegularExpressions.Regex]::Match($(_PatchLevelContent), `define\s+PY_RELEASE_LEVEL\s+PY_RELEASE_LEVEL_(\w+)`).Groups[1].Value)</_ReleaseLevel> - <ReleaseSerial>$([System.Text.RegularExpressions.Regex]::Match($(_PatchLevelContent), `define\s+PY_RELEASE_SERIAL\s+(\d+)`).Groups[1].Value)</ReleaseSerial> - <ReleaseLevelNumber>15</ReleaseLevelNumber> - <ReleaseLevelNumber Condition="$(_ReleaseLevel) == 'ALPHA'">10</ReleaseLevelNumber> - <ReleaseLevelNumber Condition="$(_ReleaseLevel) == 'BETA'">11</ReleaseLevelNumber> - <ReleaseLevelNumber Condition="$(_ReleaseLevel) == 'GAMMA'">12</ReleaseLevelNumber> - <ReleaseLevelName Condition="$(_ReleaseLevel) == 'ALPHA'">a$(ReleaseSerial)</ReleaseLevelName> - <ReleaseLevelName Condition="$(_ReleaseLevel) == 'BETA'">b$(ReleaseSerial)</ReleaseLevelName> - <ReleaseLevelName Condition="$(_ReleaseLevel) == 'GAMMA'">rc$(ReleaseSerial)</ReleaseLevelName> - </PropertyGroup> - - <PropertyGroup Condition="'$(OverrideVersion)' != ''"> - <!-- - Override the version number when building by specifying OverrideVersion. - For example: - - PCbuild\build.bat "/p:OverrideVersion=3.5.2a1" - - Use the -V option to check your version is valid: - - PCbuild\build.bat -V "/p:OverrideVersion=3.5.2a1" - PythonVersionNumber: 3.5.2 - PythonVersion: 3.5.2a1 - PythonVersionHex: 0x030502A1 - Field3Value: 2101 - - Note that this only affects the version numbers embedded in resources and - installers, but not sys.version. - --> - <MajorVersionNumber>$([System.Text.RegularExpressions.Regex]::Match($(OverrideVersion), `(\d+)\.(\d+)\.(\d+)((a|b|rc)(\d))?`).Groups[1].Value)</MajorVersionNumber> - <MinorVersionNumber>$([System.Text.RegularExpressions.Regex]::Match($(OverrideVersion), `(\d+)\.(\d+)\.(\d+)((a|b|rc)(\d))?`).Groups[2].Value)</MinorVersionNumber> - <MicroVersionNumber>$([System.Text.RegularExpressions.Regex]::Match($(OverrideVersion), `(\d+)\.(\d+)\.(\d+)((a|b|rc)(\d))?`).Groups[3].Value)</MicroVersionNumber> - <ReleaseLevelName>$([System.Text.RegularExpressions.Regex]::Match($(OverrideVersion), `(\d+)\.(\d+)\.(\d+)((a|b|rc)(\d))?`).Groups[4].Value)</ReleaseLevelName> - <_ReleaseLevel>$([System.Text.RegularExpressions.Regex]::Match($(OverrideVersion), `(\d+)\.(\d+)\.(\d+)((a|b|rc)(\d))?`).Groups[5].Value)</_ReleaseLevel> - <ReleaseSerial>$([System.Text.RegularExpressions.Regex]::Match($(OverrideVersion), `(\d+)\.(\d+)\.(\d+)((a|b|rc)(\d))?`).Groups[6].Value)</ReleaseSerial> - <ReleaseSerial Condition="'$(ReleaseSerial)' == ''">0</ReleaseSerial> - <ReleaseLevelNumber>15</ReleaseLevelNumber> - <ReleaseLevelNumber Condition="$(_ReleaseLevel) == 'a'">10</ReleaseLevelNumber> - <ReleaseLevelNumber Condition="$(_ReleaseLevel) == 'b'">11</ReleaseLevelNumber> - <ReleaseLevelNumber Condition="$(_ReleaseLevel) == 'rc'">12</ReleaseLevelNumber> - </PropertyGroup> - - <PropertyGroup> - <PythonVersionNumber>$(MajorVersionNumber).$(MinorVersionNumber).$(MicroVersionNumber)</PythonVersionNumber> - <PythonVersion>$(MajorVersionNumber).$(MinorVersionNumber).$(MicroVersionNumber)$(ReleaseLevelName)</PythonVersion> - <PythonVersionHex>$([msbuild]::BitwiseOr( - $([msbuild]::Multiply($(MajorVersionNumber), 16777216)), - $([msbuild]::BitwiseOr( - $([msbuild]::Multiply($(MinorVersionNumber), 65536)), - $([msbuild]::BitwiseOr( - $([msbuild]::Multiply($(MicroVersionNumber), 256)), - $([msbuild]::BitwiseOr( - $([msbuild]::Multiply($(ReleaseLevelNumber), 16)), - $(ReleaseSerial) - )) - )) - )) - ))</PythonVersionHex> - <Field3Value>$([msbuild]::Add( - $(ReleaseSerial), - $([msbuild]::Add( - $([msbuild]::Multiply($(ReleaseLevelNumber), 10)), - $([msbuild]::Multiply($(MicroVersionNumber), 1000)) - )) - ))</Field3Value> - <Field3Value Condition="$(UseTestMarker) == 'true'">$([msbuild]::Add($(Field3Value), 9000))</Field3Value> - - <!-- The name of the resulting pythonXY.dll (without the extension) --> - <PyDllName>python$(MajorVersionNumber)$(MinorVersionNumber)$(PyDebugExt)</PyDllName> - <!-- The name of the resulting pythonX.dll (without the extension) --> - <Py3DllName>python3$(PyDebugExt)</Py3DllName> - - <!-- The version and platform tag to include in .pyd filenames --> - <PydTag Condition="$(ArchName) == 'win32'">.cp$(MajorVersionNumber)$(MinorVersionNumber)-win32</PydTag> - <PydTag Condition="$(ArchName) == 'arm32'">.cp$(MajorVersionNumber)$(MinorVersionNumber)-win_arm32</PydTag> - <PydTag Condition="$(ArchName) == 'arm64'">.cp$(MajorVersionNumber)$(MinorVersionNumber)-win_arm64</PydTag> - <PydTag Condition="$(ArchName) == 'amd64'">.cp$(MajorVersionNumber)$(MinorVersionNumber)-win_amd64</PydTag> - - <!-- The version number for sys.winver --> - <SysWinVer>$(MajorVersionNumber).$(MinorVersionNumber)$(PyArchExt)$(PyTestExt)</SysWinVer> - </PropertyGroup> - - <!-- Displays the calculated version info --> - <Target Name="ShowVersionInfo"> - <Message Importance="high" Text="PythonVersionNumber: $(PythonVersionNumber)" /> - <Message Importance="high" Text="PythonVersion: $(PythonVersion)" /> - <Message Importance="high" Text="PythonVersionHex: 0x$([System.UInt32]::Parse($(PythonVersionHex)).ToString(`X08`))" /> - <Message Importance="high" Text="PythonVersionUnique: $(MajorVersionNumber).$(MinorVersionNumber).$(Field3Value)" /> - <Message Importance="high" Text="Field3Value: $(Field3Value)" /> - <Message Importance="high" Text="SysWinVer: $(SysWinVer)" /> - <Message Importance="high" Text="PyDllName: $(PyDllName)" /> - <Message Importance="high" Text="WindowsSdkVersion: $(TargetPlatformVersion)" /> - </Target> -</Project> +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup> + <__Python_Props_Imported>true</__Python_Props_Imported> + <Platform Condition="'$(Platform)' == ''">Win32</Platform> + <Configuration Condition="'$(Configuration)' == ''">Release</Configuration> + <!-- + Use the latest available version of Visual Studio to build. To override + this and build with an earlier version, pass "/p:PlatformToolset=v100" + (for example) when building. + + We set BasePlatformToolset for ICC's benefit, it's otherwise ignored. + --> + <BasePlatformToolset Condition="'$(BasePlatformToolset)' == '' and '$(VisualStudioVersion)' == '17.0'">v143</BasePlatformToolset> + <BasePlatformToolset Condition="'$(BasePlatformToolset)' == '' and '$(VisualStudioVersion)' == '16.0'">v142</BasePlatformToolset> + <BasePlatformToolset Condition="'$(BasePlatformToolset)' == '' and ('$(MSBuildToolsVersion)' == '15.0' or '$(VisualStudioVersion)' == '15.0')">v141</BasePlatformToolset> + <BasePlatformToolset Condition="'$(BasePlatformToolset)' == '' and '$(VCTargetsPath14)' != ''">v140</BasePlatformToolset> + <BasePlatformToolset Condition="'$(BasePlatformToolset)' == '' and '$(VCTargetsPath12)' != ''">v120</BasePlatformToolset> + <BasePlatformToolset Condition="'$(BasePlatformToolset)' == '' and '$(VCTargetsPath11)' != ''">v110</BasePlatformToolset> + <BasePlatformToolset Condition="'$(BasePlatformToolset)' == '' and '$(VCTargetsPath10)' != ''">v100</BasePlatformToolset> + + <PlatformToolset Condition="'$(PlatformToolset)' == ''">$(BasePlatformToolset)</PlatformToolset> + <ICCBuild>false</ICCBuild> + <ICCBuild Condition="$(PlatformToolset.StartsWith(`Intel C++ Compiler`))">true</ICCBuild> + + <!-- + Convincing MSVC/MSBuild to prefer our platform names is too difficult, + so we define our own constant ArchName and use wherever we need it. + --> + <ArchName Condition="'$(ArchName)' == '' and $(Platform) == 'x64'">amd64</ArchName> + <ArchName Condition="'$(ArchName)' == '' and $(Platform) == 'ARM'">arm32</ArchName> + <ArchName Condition="'$(ArchName)' == '' and $(Platform) == 'ARM64'">arm64</ArchName> + <ArchName Condition="'$(ArchName)' == ''">win32</ArchName> + + <!-- Root directory of the repository --> + <PySourcePath Condition="'$(PySourcePath)' == ''">$([System.IO.Path]::GetFullPath($(MSBuildThisFileDirectory)\..\))</PySourcePath> + <PySourcePath Condition="!HasTrailingSlash($(PySourcePath))">$(PySourcePath)\</PySourcePath> + + <!-- Directory where build outputs are put --> + <BuildPath32 Condition="'$(Py_OutDir)' == ''">$(PySourcePath)PCbuild\win32\</BuildPath32> + <BuildPath32 Condition="'$(Py_OutDir)' != ''">$(Py_OutDir)\win32\</BuildPath32> + <BuildPath64 Condition="'$(Py_OutDir)' == ''">$(PySourcePath)PCbuild\amd64\</BuildPath64> + <BuildPath64 Condition="'$(Py_OutDir)' != ''">$(Py_OutDir)\amd64\</BuildPath64> + <BuildPathArm32 Condition="'$(Py_OutDir)' == ''">$(PySourcePath)PCbuild\arm32\</BuildPathArm32> + <BuildPathArm32 Condition="'$(Py_OutDir)' != ''">$(Py_OutDir)\arm32\</BuildPathArm32> + <BuildPathArm64 Condition="'$(Py_OutDir)' == ''">$(PySourcePath)PCbuild\arm64\</BuildPathArm64> + <BuildPathArm64 Condition="'$(Py_OutDir)' != ''">$(Py_OutDir)\arm64\</BuildPathArm64> + <BuildPath Condition="'$(ArchName)' == 'win32'">$(BuildPath32)</BuildPath> + <BuildPath Condition="'$(ArchName)' == 'amd64'">$(BuildPath64)</BuildPath> + <BuildPath Condition="'$(ArchName)' == 'arm32'">$(BuildPathArm32)</BuildPath> + <BuildPath Condition="'$(ArchName)' == 'arm64'">$(BuildPathArm64)</BuildPath> + <BuildPath Condition="'$(BuildPath)' == ''">$(PySourcePath)PCbuild\$(ArchName)\</BuildPath> + <BuildPath Condition="!HasTrailingSlash($(BuildPath))">$(BuildPath)\</BuildPath> + <BuildPath Condition="$(Configuration) == 'PGInstrument'">$(BuildPath)instrumented\</BuildPath> + + <!-- VPATH definition (escaped) --> + <PyVPath Condition="$(Configuration) != 'PGInstrument'">..\\..</PyVPath> + <PyVPath Condition="$(Configuration) == 'PGInstrument'">..\\..\\..</PyVPath> + </PropertyGroup> + + <!-- Directories of external projects. tcltk is handled in tcltk.props --> + <PropertyGroup> + <ExternalsDir Condition="$(ExternalsDir) == ''">$(EXTERNALS_DIR)</ExternalsDir> + <ExternalsDir Condition="$(ExternalsDir) == ''">$([System.IO.Path]::GetFullPath(`$(PySourcePath)externals`))</ExternalsDir> + <ExternalsDir Condition="!HasTrailingSlash($(ExternalsDir))">$(ExternalsDir)\</ExternalsDir> + </PropertyGroup> + + <Import Project="$(ExternalProps)" Condition="$(ExternalProps) != '' and Exists('$(ExternalProps)')" /> + + <PropertyGroup> + <sqlite3Dir Condition="$(sqlite3Dir) == ''">$(ExternalsDir)sqlite-3.42.0.0\</sqlite3Dir> + <bz2Dir Condition="$(bz2Dir) == ''">$(ExternalsDir)bzip2-1.0.8\</bz2Dir> + <lzmaDir Condition="$(lzmaDir) == ''">$(ExternalsDir)xz-5.2.5\</lzmaDir> + <libffiDir Condition="$(libffiDir) == ''">$(ExternalsDir)libffi-3.4.4\</libffiDir> + <libffiOutDir Condition="$(libffiOutDir) == ''">$(libffiDir)$(ArchName)\</libffiOutDir> + <libffiIncludeDir Condition="$(libffiIncludeDir) == ''">$(libffiOutDir)include</libffiIncludeDir> + <opensslDir Condition="$(opensslDir) == ''">$(ExternalsDir)openssl-3.0.11\</opensslDir> + <opensslOutDir Condition="$(opensslOutDir) == ''">$(ExternalsDir)openssl-bin-3.0.11\$(ArchName)\</opensslOutDir> + <opensslIncludeDir Condition="$(opensslIncludeDir) == ''">$(opensslOutDir)include</opensslIncludeDir> + <nasmDir Condition="$(nasmDir) == ''">$(ExternalsDir)\nasm-2.11.06\</nasmDir> + <zlibDir Condition="$(zlibDir) == ''">$(ExternalsDir)\zlib-1.2.13\</zlibDir> + </PropertyGroup> + + <PropertyGroup> + <!-- Suffix for all binaries when building for debug --> + <PyDebugExt Condition="'$(PyDebugExt)' == '' and $(Configuration) == 'Debug'">_d</PyDebugExt> + + <!-- Suffix for versions/keys when building with test markers --> + <PyTestExt Condition="$(UseTestMarker) == 'true'">-test</PyTestExt> + + <!-- Suffix for versions/keys when building for particular platforms --> + <PyArchExt Condition="'$(ArchName)' == 'win32'">-32</PyArchExt> + <PyArchExt Condition="'$(ArchName)' == 'arm32'">-arm32</PyArchExt> + <PyArchExt Condition="'$(ArchName)' == 'arm64'">-arm64</PyArchExt> + + <!-- Full path of the resulting python.exe binary --> + <PythonExe Condition="'$(PythonExe)' == ''">$(BuildPath)python$(PyDebugExt).exe</PythonExe> + + <!-- Include Tkinter by default --> + <IncludeTkinter Condition="'$(IncludeTkinter)' == ''">true</IncludeTkinter> + </PropertyGroup> + + <PropertyGroup Condition="'$(Platform)'=='ARM'" Label="ArmConfiguration"> + <WindowsSDKDesktopARMSupport>true</WindowsSDKDesktopARMSupport> + </PropertyGroup> + + <PropertyGroup Condition="'$(Platform)'=='ARM64'" Label="Arm64Configuration"> + <WindowsSDKDesktopARMSupport>true</WindowsSDKDesktopARMSupport> + </PropertyGroup> + + <PropertyGroup Condition="$(DefaultWindowsSDKVersion) == ''"> + <!-- + Attempt to select the latest installed WinSDK. If we don't find any, then we will + let the MSBuild targets determine which one it wants to use (typically the earliest + possible version). Since we limit WINVER to Windows 7 anyway, it doesn't really + matter which WinSDK version we use. + --> + <_RegistryVersion>$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v10.0@ProductVersion)</_RegistryVersion> + <_RegistryVersion Condition="$(_RegistryVersion) == ''">$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Microsoft SDKs\Windows\v10.0@ProductVersion)</_RegistryVersion> + <!-- Sometimes the version in the registry has to .0 suffix, and sometimes it doesn't. Check and add it --> + <_RegistryVersion Condition="$(_RegistryVersion) != '' and !$(_RegistryVersion.EndsWith('.0'))">$(_RegistryVersion).0</_RegistryVersion> + + <!-- The minimum allowed SDK version to use for building --> + <DefaultWindowsSDKVersion>10.0.10586.0</DefaultWindowsSDKVersion> + <DefaultWindowsSDKVersion Condition="$(_RegistryVersion) != '' and $([System.Version]::Parse($(_RegistryVersion))) > $([System.Version]::Parse($(DefaultWindowsSDKVersion)))">$(_RegistryVersion)</DefaultWindowsSDKVersion> + </PropertyGroup> + + <Target Name="_CheckWindowsSDKFound" BeforeTargets="_CheckWindowsSDKInstalled" Condition="$(_RegistryVersion) == ''"> + <PropertyGroup> + <_Message>Failed to locate a Windows SDK installation.</_Message> + <_Message>$(_Message) If the build fails, please use the Visual Studio Installer to install the Windows SDK.</_Message> + <_Message>$(_Message) (Ignore the version number specified in the error message and select the latest.)</_Message> + </PropertyGroup> + <Warning Text="$(_Message)" /> + </Target> + + <PropertyGroup Condition="$(WindowsTargetPlatformVersion) == ''"> + <WindowsTargetPlatformVersion>$(DefaultWindowsSDKVersion)</WindowsTargetPlatformVersion> + </PropertyGroup> + + <PropertyGroup Condition="'$(OverrideVersion)' == ''"> + <!-- + Read version information from Include\patchlevel.h. The following properties are set: + + MajorVersionNumber - the '3' in '3.5.2a1' + MinorVersionNumber - the '5' in '3.5.2a1' + MicroVersionNumber - the '2' in '3.5.2a1' + ReleaseSerial - the '1' in '3.5.2a1' + ReleaseLevelName - the 'a1' in '3.5.2a1' + PythonVersionNumber - '3.5.2' for '3.5.2a1' + PythonVersion - '3.5.2a1' + PythonVersionHex - 0x030502a1 for '3.5.2a1' + ReleaseLevelNumber - 10 for alpha, 11 for beta, 12 for RC (gamma), and 15 for final + Field3Value - 2101 for '3.5.2a1' (== 1000*2 + 10*10 ('a') + 1) + --> + <_PatchLevelContent>$([System.IO.File]::ReadAllText(`$(PySourcePath)Include\patchlevel.h`))</_PatchLevelContent> + <MajorVersionNumber>$([System.Text.RegularExpressions.Regex]::Match($(_PatchLevelContent), `define\s+PY_MAJOR_VERSION\s+(\d+)`).Groups[1].Value)</MajorVersionNumber> + <MinorVersionNumber>$([System.Text.RegularExpressions.Regex]::Match($(_PatchLevelContent), `define\s+PY_MINOR_VERSION\s+(\d+)`).Groups[1].Value)</MinorVersionNumber> + <MicroVersionNumber>$([System.Text.RegularExpressions.Regex]::Match($(_PatchLevelContent), `define\s+PY_MICRO_VERSION\s+(\d+)`).Groups[1].Value)</MicroVersionNumber> + <_ReleaseLevel>$([System.Text.RegularExpressions.Regex]::Match($(_PatchLevelContent), `define\s+PY_RELEASE_LEVEL\s+PY_RELEASE_LEVEL_(\w+)`).Groups[1].Value)</_ReleaseLevel> + <ReleaseSerial>$([System.Text.RegularExpressions.Regex]::Match($(_PatchLevelContent), `define\s+PY_RELEASE_SERIAL\s+(\d+)`).Groups[1].Value)</ReleaseSerial> + <ReleaseLevelNumber>15</ReleaseLevelNumber> + <ReleaseLevelNumber Condition="$(_ReleaseLevel) == 'ALPHA'">10</ReleaseLevelNumber> + <ReleaseLevelNumber Condition="$(_ReleaseLevel) == 'BETA'">11</ReleaseLevelNumber> + <ReleaseLevelNumber Condition="$(_ReleaseLevel) == 'GAMMA'">12</ReleaseLevelNumber> + <ReleaseLevelName Condition="$(_ReleaseLevel) == 'ALPHA'">a$(ReleaseSerial)</ReleaseLevelName> + <ReleaseLevelName Condition="$(_ReleaseLevel) == 'BETA'">b$(ReleaseSerial)</ReleaseLevelName> + <ReleaseLevelName Condition="$(_ReleaseLevel) == 'GAMMA'">rc$(ReleaseSerial)</ReleaseLevelName> + </PropertyGroup> + + <PropertyGroup Condition="'$(OverrideVersion)' != ''"> + <!-- + Override the version number when building by specifying OverrideVersion. + For example: + + PCbuild\build.bat "/p:OverrideVersion=3.5.2a1" + + Use the -V option to check your version is valid: + + PCbuild\build.bat -V "/p:OverrideVersion=3.5.2a1" + PythonVersionNumber: 3.5.2 + PythonVersion: 3.5.2a1 + PythonVersionHex: 0x030502A1 + Field3Value: 2101 + + Note that this only affects the version numbers embedded in resources and + installers, but not sys.version. + --> + <MajorVersionNumber>$([System.Text.RegularExpressions.Regex]::Match($(OverrideVersion), `(\d+)\.(\d+)\.(\d+)((a|b|rc)(\d))?`).Groups[1].Value)</MajorVersionNumber> + <MinorVersionNumber>$([System.Text.RegularExpressions.Regex]::Match($(OverrideVersion), `(\d+)\.(\d+)\.(\d+)((a|b|rc)(\d))?`).Groups[2].Value)</MinorVersionNumber> + <MicroVersionNumber>$([System.Text.RegularExpressions.Regex]::Match($(OverrideVersion), `(\d+)\.(\d+)\.(\d+)((a|b|rc)(\d))?`).Groups[3].Value)</MicroVersionNumber> + <ReleaseLevelName>$([System.Text.RegularExpressions.Regex]::Match($(OverrideVersion), `(\d+)\.(\d+)\.(\d+)((a|b|rc)(\d))?`).Groups[4].Value)</ReleaseLevelName> + <_ReleaseLevel>$([System.Text.RegularExpressions.Regex]::Match($(OverrideVersion), `(\d+)\.(\d+)\.(\d+)((a|b|rc)(\d))?`).Groups[5].Value)</_ReleaseLevel> + <ReleaseSerial>$([System.Text.RegularExpressions.Regex]::Match($(OverrideVersion), `(\d+)\.(\d+)\.(\d+)((a|b|rc)(\d))?`).Groups[6].Value)</ReleaseSerial> + <ReleaseSerial Condition="'$(ReleaseSerial)' == ''">0</ReleaseSerial> + <ReleaseLevelNumber>15</ReleaseLevelNumber> + <ReleaseLevelNumber Condition="$(_ReleaseLevel) == 'a'">10</ReleaseLevelNumber> + <ReleaseLevelNumber Condition="$(_ReleaseLevel) == 'b'">11</ReleaseLevelNumber> + <ReleaseLevelNumber Condition="$(_ReleaseLevel) == 'rc'">12</ReleaseLevelNumber> + </PropertyGroup> + + <PropertyGroup> + <PythonVersionNumber>$(MajorVersionNumber).$(MinorVersionNumber).$(MicroVersionNumber)</PythonVersionNumber> + <PythonVersion>$(MajorVersionNumber).$(MinorVersionNumber).$(MicroVersionNumber)$(ReleaseLevelName)</PythonVersion> + <PythonVersionHex>$([msbuild]::BitwiseOr( + $([msbuild]::Multiply($(MajorVersionNumber), 16777216)), + $([msbuild]::BitwiseOr( + $([msbuild]::Multiply($(MinorVersionNumber), 65536)), + $([msbuild]::BitwiseOr( + $([msbuild]::Multiply($(MicroVersionNumber), 256)), + $([msbuild]::BitwiseOr( + $([msbuild]::Multiply($(ReleaseLevelNumber), 16)), + $(ReleaseSerial) + )) + )) + )) + ))</PythonVersionHex> + <Field3Value>$([msbuild]::Add( + $(ReleaseSerial), + $([msbuild]::Add( + $([msbuild]::Multiply($(ReleaseLevelNumber), 10)), + $([msbuild]::Multiply($(MicroVersionNumber), 1000)) + )) + ))</Field3Value> + <Field3Value Condition="$(UseTestMarker) == 'true'">$([msbuild]::Add($(Field3Value), 9000))</Field3Value> + + <!-- The name of the resulting pythonXY.dll (without the extension) --> + <PyDllName>python$(MajorVersionNumber)$(MinorVersionNumber)$(PyDebugExt)</PyDllName> + <!-- The name of the resulting pythonX.dll (without the extension) --> + <Py3DllName>python3$(PyDebugExt)</Py3DllName> + + <!-- The version and platform tag to include in .pyd filenames --> + <PydTag Condition="$(ArchName) == 'win32'">.cp$(MajorVersionNumber)$(MinorVersionNumber)-win32</PydTag> + <PydTag Condition="$(ArchName) == 'arm32'">.cp$(MajorVersionNumber)$(MinorVersionNumber)-win_arm32</PydTag> + <PydTag Condition="$(ArchName) == 'arm64'">.cp$(MajorVersionNumber)$(MinorVersionNumber)-win_arm64</PydTag> + <PydTag Condition="$(ArchName) == 'amd64'">.cp$(MajorVersionNumber)$(MinorVersionNumber)-win_amd64</PydTag> + + <!-- The version number for sys.winver --> + <SysWinVer>$(MajorVersionNumber).$(MinorVersionNumber)$(PyArchExt)$(PyTestExt)</SysWinVer> + </PropertyGroup> + + <!-- Displays the calculated version info --> + <Target Name="ShowVersionInfo"> + <Message Importance="high" Text="PythonVersionNumber: $(PythonVersionNumber)" /> + <Message Importance="high" Text="PythonVersion: $(PythonVersion)" /> + <Message Importance="high" Text="PythonVersionHex: 0x$([System.UInt32]::Parse($(PythonVersionHex)).ToString(`X08`))" /> + <Message Importance="high" Text="PythonVersionUnique: $(MajorVersionNumber).$(MinorVersionNumber).$(Field3Value)" /> + <Message Importance="high" Text="Field3Value: $(Field3Value)" /> + <Message Importance="high" Text="SysWinVer: $(SysWinVer)" /> + <Message Importance="high" Text="PyDllName: $(PyDllName)" /> + <Message Importance="high" Text="WindowsSdkVersion: $(TargetPlatformVersion)" /> + </Target> +</Project> diff --git a/PCbuild/python.vcxproj b/PCbuild/python.vcxproj index 37378f4e..f4640454 100644 --- a/PCbuild/python.vcxproj +++ b/PCbuild/python.vcxproj @@ -1,162 +1,162 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|ARM"> - <Configuration>Debug</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|ARM64"> - <Configuration>Debug</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM64"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|Win32"> - <Configuration>PGInstrument</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|x64"> - <Configuration>PGInstrument</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM64"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|Win32"> - <Configuration>PGUpdate</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|x64"> - <Configuration>PGUpdate</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM"> - <Configuration>Release</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM64"> - <Configuration>Release</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectGuid>{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}</ProjectGuid> - </PropertyGroup> - <Import Project="python.props" /> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseOfMfc>false</UseOfMfc> - <CharacterSet>MultiByte</CharacterSet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="pyproject.props" /> - <Import Project="tcltk.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup> - <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> - </PropertyGroup> - <ItemDefinitionGroup> - <ClCompile> - <PreprocessorDefinitions>Py_BUILD_CORE;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <StackReserveSize Condition="$(Configuration) != 'Debug'">2000000</StackReserveSize> - <StackReserveSize Condition="$(Configuration) == 'Debug'">4000000</StackReserveSize> - </Link> - </ItemDefinitionGroup> - <ItemGroup> - <None Include="..\PC\pycon.ico" /> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\python_exe.rc" /> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\Programs\python.c" /> - </ItemGroup> - <ItemGroup> - <ProjectReference Include="pythoncore.vcxproj"> - <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> - <ReferenceOutputAssembly>false</ReferenceOutputAssembly> - </ProjectReference> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - <Import Project="regen.targets" /> - </ImportGroup> - <Target Name="_TriggerPostRegen" AfterTargets="Build" DependsOnTargets="PostBuildRegen" /> - <Target Name="GeneratePyBuildDirTxt" AfterTargets="Link"> - <Message Text="Generating $(OutDir)pybuilddir.txt" /> - <WriteLinesToFile File="$(OutDir)pybuilddir.txt" Lines="%0D%0A" Overwrite="true" /> - </Target> - <Target Name="ValidateUcrtbase" AfterTargets="AfterBuild" Condition="$(Configuration) != 'PGInstrument' and $(Platform) != 'ARM' and $(Platform) != 'ARM64'"> - <PropertyGroup> - <UcrtName>ucrtbase</UcrtName> - <UcrtName Condition="'$(Configuration)' == 'Debug'">ucrtbased</UcrtName> - </PropertyGroup> - <Exec Command='setlocal -set PYTHONPATH=$(PySourcePath)Lib -"$(OutDir)python$(PyDebugExt).exe" "$(PySourcePath)PC\validate_ucrtbase.py" $(UcrtName)' ContinueOnError="true" /> - </Target> - <Target Name="GeneratePythonBat" AfterTargets="AfterBuild"> - <PropertyGroup> - <_Content>@rem This script invokes the most recently built Python with all arguments -@rem passed through to the interpreter. This file is generated by the -@rem build process and any changes *will* be thrown away by the next -@rem rebuild. -@rem This is only meant as a convenience for developing CPython -@rem and using it outside of that context is ill-advised. -@echo Running $(Configuration)^|$(Platform) interpreter... -@setlocal -@set PYTHONHOME=$(PySourcePath) -@"$(OutDir)python$(PyDebugExt).exe" %* -</_Content> - <_ExistingContent Condition="Exists('$(PySourcePath)python.bat')">$([System.IO.File]::ReadAllText('$(PySourcePath)python.bat'))</_ExistingContent> - </PropertyGroup> - <WriteLinesToFile File="$(PySourcePath)python.bat" Lines="$(_Content)" Overwrite="true" Condition="'$(_Content)' != '$(_ExistingContent)'" /> - </Target> - <Target Name="CopyPGORT" AfterTargets="Link" Condition="$(Configuration) == 'PGInstrument'"> - <ItemGroup> - <_PGORT Include="$(VCToolsInstallDir)bin\Hostx86\x86\pgort140.dll" Condition="$(Platform) == 'Win32'" /> - <_PGORT Include="$(VCToolsInstallDir)bin\Hostx64\x64\pgort140.dll" Condition="$(Platform) == 'x64'" /> - <_PGORT Include="$(VCToolsInstallDir)bin\arm64\pgort140.dll" Condition="$(Platform) == 'ARM64'" /> - </ItemGroup> - <Warning Text="Unable to locate pgort140.dll for $(Platform)." Condition="@(_PGORT) == '' or !Exists(@(_PGORT))" /> - <Copy SourceFiles="@(_PGORT)" DestinationFolder="$(OutDir)"> - <Output TaskParameter="CopiedFiles" ItemName="FileWrites" /> - </Copy> - </Target> -</Project> +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|ARM"> + <Configuration>Debug</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|ARM64"> + <Configuration>Debug</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM64"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|Win32"> + <Configuration>PGInstrument</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|x64"> + <Configuration>PGInstrument</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM64"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|Win32"> + <Configuration>PGUpdate</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|x64"> + <Configuration>PGUpdate</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM"> + <Configuration>Release</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM64"> + <Configuration>Release</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}</ProjectGuid> + </PropertyGroup> + <Import Project="python.props" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="pyproject.props" /> + <Import Project="tcltk.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> + </PropertyGroup> + <ItemDefinitionGroup> + <ClCompile> + <PreprocessorDefinitions>Py_BUILD_CORE;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <StackReserveSize Condition="$(Configuration) != 'Debug'">2000000</StackReserveSize> + <StackReserveSize Condition="$(Configuration) == 'Debug'">8000000</StackReserveSize> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <None Include="..\PC\pycon.ico" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_exe.rc" /> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\Programs\python.c" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="pythoncore.vcxproj"> + <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + <Import Project="regen.targets" /> + </ImportGroup> + <Target Name="_TriggerPostRegen" AfterTargets="Build" DependsOnTargets="PostBuildRegen" /> + <Target Name="GeneratePyBuildDirTxt" AfterTargets="Link"> + <Message Text="Generating $(OutDir)pybuilddir.txt" /> + <WriteLinesToFile File="$(OutDir)pybuilddir.txt" Lines="%0D%0A" Overwrite="true" /> + </Target> + <Target Name="ValidateUcrtbase" AfterTargets="AfterBuild" Condition="$(Configuration) != 'PGInstrument' and $(Platform) != 'ARM' and $(Platform) != 'ARM64'"> + <PropertyGroup> + <UcrtName>ucrtbase</UcrtName> + <UcrtName Condition="'$(Configuration)' == 'Debug'">ucrtbased</UcrtName> + </PropertyGroup> + <Exec Command='setlocal +set PYTHONPATH=$(PySourcePath)Lib +"$(OutDir)python$(PyDebugExt).exe" "$(PySourcePath)PC\validate_ucrtbase.py" $(UcrtName)' ContinueOnError="true" /> + </Target> + <Target Name="GeneratePythonBat" AfterTargets="AfterBuild"> + <PropertyGroup> + <_Content>@rem This script invokes the most recently built Python with all arguments +@rem passed through to the interpreter. This file is generated by the +@rem build process and any changes *will* be thrown away by the next +@rem rebuild. +@rem This is only meant as a convenience for developing CPython +@rem and using it outside of that context is ill-advised. +@echo Running $(Configuration)^|$(Platform) interpreter... +@setlocal +@set PYTHONHOME=$(PySourcePath) +@"$(OutDir)python$(PyDebugExt).exe" %* +</_Content> + <_ExistingContent Condition="Exists('$(PySourcePath)python.bat')">$([System.IO.File]::ReadAllText('$(PySourcePath)python.bat'))</_ExistingContent> + </PropertyGroup> + <WriteLinesToFile File="$(PySourcePath)python.bat" Lines="$(_Content)" Overwrite="true" Condition="'$(_Content)' != '$(_ExistingContent)'" /> + </Target> + <Target Name="CopyPGORT" AfterTargets="Link" Condition="$(Configuration) == 'PGInstrument'"> + <ItemGroup> + <_PGORT Include="$(VCToolsInstallDir)bin\Hostx86\x86\pgort140.dll" Condition="$(Platform) == 'Win32'" /> + <_PGORT Include="$(VCToolsInstallDir)bin\Hostx64\x64\pgort140.dll" Condition="$(Platform) == 'x64'" /> + <_PGORT Include="$(VCToolsInstallDir)bin\arm64\pgort140.dll" Condition="$(Platform) == 'ARM64'" /> + </ItemGroup> + <Warning Text="Unable to locate pgort140.dll for $(Platform)." Condition="@(_PGORT) == '' or !Exists(@(_PGORT))" /> + <Copy SourceFiles="@(_PGORT)" DestinationFolder="$(OutDir)"> + <Output TaskParameter="CopiedFiles" ItemName="FileWrites" /> + </Copy> + </Target> +</Project> diff --git a/PCbuild/python.vcxproj.filters b/PCbuild/python.vcxproj.filters index 958eee09..0662a4e7 100644 --- a/PCbuild/python.vcxproj.filters +++ b/PCbuild/python.vcxproj.filters @@ -1,26 +1,26 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <Filter Include="Resource Files"> - <UniqueIdentifier>{2d690795-de83-4a33-8235-3c5dafe45efa}</UniqueIdentifier> - </Filter> - <Filter Include="Source Files"> - <UniqueIdentifier>{8b010a19-5b29-45f1-a8a0-f672e2bbb11a}</UniqueIdentifier> - </Filter> - </ItemGroup> - <ItemGroup> - <None Include="..\PC\pycon.ico"> - <Filter>Resource Files</Filter> - </None> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\python_exe.rc"> - <Filter>Resource Files</Filter> - </ResourceCompile> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\Programs\python.c"> - <Filter>Source Files</Filter> - </ClCompile> - </ItemGroup> -</Project> +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Resource Files"> + <UniqueIdentifier>{2d690795-de83-4a33-8235-3c5dafe45efa}</UniqueIdentifier> + </Filter> + <Filter Include="Source Files"> + <UniqueIdentifier>{8b010a19-5b29-45f1-a8a0-f672e2bbb11a}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <None Include="..\PC\pycon.ico"> + <Filter>Resource Files</Filter> + </None> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_exe.rc"> + <Filter>Resource Files</Filter> + </ResourceCompile> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\Programs\python.c"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> +</Project> diff --git a/PCbuild/python3dll.vcxproj b/PCbuild/python3dll.vcxproj index f4427b7a..ec22e6fc 100644 --- a/PCbuild/python3dll.vcxproj +++ b/PCbuild/python3dll.vcxproj @@ -1,110 +1,110 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|ARM"> - <Configuration>Debug</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|ARM64"> - <Configuration>Debug</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM64"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|Win32"> - <Configuration>PGInstrument</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|x64"> - <Configuration>PGInstrument</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM64"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|Win32"> - <Configuration>PGUpdate</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|x64"> - <Configuration>PGUpdate</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM"> - <Configuration>Release</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM64"> - <Configuration>Release</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectGuid>{885D4898-D08D-4091-9C40-C700CFE3FC5A}</ProjectGuid> - <RootNamespace>python3dll</RootNamespace> - <Keyword>Win32Proj</Keyword> - <TargetName>python3</TargetName> - <SupportPGO>false</SupportPGO> - </PropertyGroup> - <Import Project="python.props" /> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="pyproject.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup> - <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> - </PropertyGroup> - <ItemDefinitionGroup> - <ClCompile> - <PreprocessorDefinitions>PYTHON_DLL_NAME="$(PyDllName)";%(PreprocessorDefinitions)</PreprocessorDefinitions> - <BufferSecurityCheck>false</BufferSecurityCheck> - </ClCompile> - <Link> - <NoEntryPoint>true</NoEntryPoint> - </Link> - </ItemDefinitionGroup> - <ItemGroup> - <ClCompile Include="..\PC\python3dll.c" /> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\python_nt.rc" /> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|ARM"> + <Configuration>Debug</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|ARM64"> + <Configuration>Debug</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM64"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|Win32"> + <Configuration>PGInstrument</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|x64"> + <Configuration>PGInstrument</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM64"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|Win32"> + <Configuration>PGUpdate</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|x64"> + <Configuration>PGUpdate</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM"> + <Configuration>Release</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM64"> + <Configuration>Release</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{885D4898-D08D-4091-9C40-C700CFE3FC5A}</ProjectGuid> + <RootNamespace>python3dll</RootNamespace> + <Keyword>Win32Proj</Keyword> + <TargetName>python3</TargetName> + <SupportPGO>false</SupportPGO> + </PropertyGroup> + <Import Project="python.props" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="pyproject.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> + </PropertyGroup> + <ItemDefinitionGroup> + <ClCompile> + <PreprocessorDefinitions>PYTHON_DLL_NAME="$(PyDllName)";%(PreprocessorDefinitions)</PreprocessorDefinitions> + <BufferSecurityCheck>false</BufferSecurityCheck> + </ClCompile> + <Link> + <NoEntryPoint>true</NoEntryPoint> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\PC\python3dll.c" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_nt.rc" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> </Project> \ No newline at end of file diff --git a/PCbuild/python3dll.vcxproj.filters b/PCbuild/python3dll.vcxproj.filters index 0dcdf0bb..ba562dfa 100644 --- a/PCbuild/python3dll.vcxproj.filters +++ b/PCbuild/python3dll.vcxproj.filters @@ -1,23 +1,23 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <Filter Include="Source Files"> - <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> - <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> - </Filter> - <Filter Include="Resource Files"> - <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> - <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions> - </Filter> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\PC\python3dll.c"> - <Filter>Source Files</Filter> - </ClCompile> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\python_nt.rc"> - <Filter>Resource Files</Filter> - </ResourceCompile> - </ItemGroup> +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\PC\python3dll.c"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_nt.rc"> + <Filter>Resource Files</Filter> + </ResourceCompile> + </ItemGroup> </Project> \ No newline at end of file diff --git a/PCbuild/python_uwp.vcxproj b/PCbuild/python_uwp.vcxproj index a7352747..fb27e9e7 100644 --- a/PCbuild/python_uwp.vcxproj +++ b/PCbuild/python_uwp.vcxproj @@ -1,128 +1,128 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|ARM"> - <Configuration>Debug</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|ARM64"> - <Configuration>Debug</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM64"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|Win32"> - <Configuration>PGInstrument</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|x64"> - <Configuration>PGInstrument</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM64"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|Win32"> - <Configuration>PGUpdate</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|x64"> - <Configuration>PGUpdate</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM"> - <Configuration>Release</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM64"> - <Configuration>Release</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectGuid>{9DE9E23D-C8D4-4817-92A9-920A8B1FE5FF}</ProjectGuid> - </PropertyGroup> - <Import Project="python.props" /> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseOfMfc>false</UseOfMfc> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="pyproject.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup> - <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> - </PropertyGroup> - <ItemDefinitionGroup> - <ClCompile> - <PreprocessorDefinitions>%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalOptions>/EHsc /std:c++17 %(AdditionalOptions)</AdditionalOptions> - </ClCompile> - <Link> - <AdditionalDependencies>windowsapp.lib;%(AdditionalDependencies)</AdditionalDependencies> - <SubSystem>Console</SubSystem> - <StackReserveSize>2000000</StackReserveSize> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="$(Configuration) != 'Debug'"> - <ClCompile> - <RuntimeLibrary>Multithreaded</RuntimeLibrary> - </ClCompile> - <Link> - <AdditionalDependencies>ucrt.lib;%(AdditionalDependencies)</AdditionalDependencies> - <IgnoreSpecificDefaultLibraries>libucrt;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries> - </Link> - </ItemDefinitionGroup> - <ItemGroup> - <None Include="..\PC\pycon.ico" /> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\python_exe.rc" /> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\PC\python_uwp.cpp" /> - </ItemGroup> - <ItemGroup> - <ProjectReference Include="pythoncore.vcxproj"> - <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> - <ReferenceOutputAssembly>false</ReferenceOutputAssembly> - </ProjectReference> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> -</Project> +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|ARM"> + <Configuration>Debug</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|ARM64"> + <Configuration>Debug</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM64"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|Win32"> + <Configuration>PGInstrument</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|x64"> + <Configuration>PGInstrument</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM64"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|Win32"> + <Configuration>PGUpdate</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|x64"> + <Configuration>PGUpdate</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM"> + <Configuration>Release</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM64"> + <Configuration>Release</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{9DE9E23D-C8D4-4817-92A9-920A8B1FE5FF}</ProjectGuid> + </PropertyGroup> + <Import Project="python.props" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="pyproject.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> + </PropertyGroup> + <ItemDefinitionGroup> + <ClCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalOptions>/EHsc /std:c++17 %(AdditionalOptions)</AdditionalOptions> + </ClCompile> + <Link> + <AdditionalDependencies>windowsapp.lib;%(AdditionalDependencies)</AdditionalDependencies> + <SubSystem>Console</SubSystem> + <StackReserveSize>2000000</StackReserveSize> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="$(Configuration) != 'Debug'"> + <ClCompile> + <RuntimeLibrary>Multithreaded</RuntimeLibrary> + </ClCompile> + <Link> + <AdditionalDependencies>ucrt.lib;%(AdditionalDependencies)</AdditionalDependencies> + <IgnoreSpecificDefaultLibraries>libucrt;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <None Include="..\PC\pycon.ico" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_exe.rc" /> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\PC\python_uwp.cpp" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="pythoncore.vcxproj"> + <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> diff --git a/PCbuild/python_uwp.vcxproj.filters b/PCbuild/python_uwp.vcxproj.filters index 84e31f98..79e87461 100644 --- a/PCbuild/python_uwp.vcxproj.filters +++ b/PCbuild/python_uwp.vcxproj.filters @@ -1,26 +1,26 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <Filter Include="Resource Files"> - <UniqueIdentifier>{fd8bf000-0bbe-4fd4-ac49-29036e5a5c5a}</UniqueIdentifier> - </Filter> - <Filter Include="Source Files"> - <UniqueIdentifier>{a0d4ce0b-a7b5-4a77-b6c2-d2ddb9bd49b8}</UniqueIdentifier> - </Filter> - </ItemGroup> - <ItemGroup> - <None Include="..\PC\pycon.ico"> - <Filter>Resource Files</Filter> - </None> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\python_exe.rc"> - <Filter>Resource Files</Filter> - </ResourceCompile> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\PC\python_uwp.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - </ItemGroup> +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Resource Files"> + <UniqueIdentifier>{fd8bf000-0bbe-4fd4-ac49-29036e5a5c5a}</UniqueIdentifier> + </Filter> + <Filter Include="Source Files"> + <UniqueIdentifier>{a0d4ce0b-a7b5-4a77-b6c2-d2ddb9bd49b8}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <None Include="..\PC\pycon.ico"> + <Filter>Resource Files</Filter> + </None> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_exe.rc"> + <Filter>Resource Files</Filter> + </ResourceCompile> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\PC\python_uwp.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> </Project> \ No newline at end of file diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj index 84d898f2..b265264d 100644 --- a/PCbuild/pythoncore.vcxproj +++ b/PCbuild/pythoncore.vcxproj @@ -1,612 +1,647 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|ARM"> - <Configuration>Debug</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|ARM64"> - <Configuration>Debug</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM64"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|Win32"> - <Configuration>PGInstrument</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|x64"> - <Configuration>PGInstrument</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM64"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|Win32"> - <Configuration>PGUpdate</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|x64"> - <Configuration>PGUpdate</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM"> - <Configuration>Release</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM64"> - <Configuration>Release</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectGuid>{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}</ProjectGuid> - <RootNamespace>pythoncore</RootNamespace> - </PropertyGroup> - <Import Project="python.props" /> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <UseOfMfc>false</UseOfMfc> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <PropertyGroup> - <KillPython>true</KillPython> - <RequirePGCFiles>true</RequirePGCFiles> - <IncludeExternals Condition="$(IncludeExternals) == '' and Exists('$(zlibDir)\zlib.h')">true</IncludeExternals> - <IncludeExternals Condition="$(IncludeExternals) == ''">false</IncludeExternals> - </PropertyGroup> - <ImportGroup Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="pyproject.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup> - <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> - <TargetName>$(PyDllName)</TargetName> - </PropertyGroup> - <PropertyGroup> - <CustomBuildBeforeTargets>Link</CustomBuildBeforeTargets> - </PropertyGroup> - <ItemDefinitionGroup> - <ClCompile> - <AdditionalOptions>/Zm200 %(AdditionalOptions)</AdditionalOptions> - <AdditionalIncludeDirectories>$(PySourcePath)Python;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <AdditionalIncludeDirectories Condition="$(IncludeExternals)">$(zlibDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>_USRDLL;Py_BUILD_CORE;Py_BUILD_CORE_BUILTIN;Py_ENABLE_SHARED;MS_DLL_ID="$(SysWinVer)";%(PreprocessorDefinitions)</PreprocessorDefinitions> - <PreprocessorDefinitions Condition="$(IncludeExternals)">_Py_HAVE_ZLIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <Link> - <AdditionalDependencies>version.lib;ws2_32.lib;pathcch.lib;bcrypt.lib;%(AdditionalDependencies)</AdditionalDependencies> - </Link> - </ItemDefinitionGroup> - <ItemGroup> - <ClCompile Include="..\Modules\getpath.c"> - <PreprocessorDefinitions> - PREFIX=NULL; - EXEC_PREFIX=NULL; - VERSION=NULL; - VPATH="$(PyVPath)"; - PYDEBUGEXT="$(PyDebugExt)"; - PLATLIBDIR="DLLs"; - %(PreprocessorDefinitions) - </PreprocessorDefinitions> - </ClCompile> - </ItemGroup> - <ItemGroup> - <ClInclude Include="..\Include\Python.h" /> - <ClInclude Include="..\Include\abstract.h" /> - <ClInclude Include="..\Include\boolobject.h" /> - <ClInclude Include="..\Include\bytearrayobject.h" /> - <ClInclude Include="..\Include\bytesobject.h" /> - <ClInclude Include="..\Include\ceval.h" /> - <ClInclude Include="..\Include\codecs.h" /> - <ClInclude Include="..\Include\compile.h" /> - <ClInclude Include="..\Include\complexobject.h" /> - <ClInclude Include="..\Include\cpython\abstract.h" /> - <ClInclude Include="..\Include\cpython\bytearrayobject.h" /> - <ClInclude Include="..\Include\cpython\bytesobject.h" /> - <ClInclude Include="..\Include\cpython\cellobject.h" /> - <ClInclude Include="..\Include\cpython\ceval.h" /> - <ClInclude Include="..\Include\cpython\classobject.h" /> - <ClInclude Include="..\Include\cpython\code.h" /> - <ClInclude Include="..\Include\cpython\compile.h" /> - <ClInclude Include="..\Include\cpython\complexobject.h" /> - <ClInclude Include="..\Include\cpython\context.h" /> - <ClInclude Include="..\Include\cpython\descrobject.h" /> - <ClInclude Include="..\Include\cpython\dictobject.h" /> - <ClInclude Include="..\Include\cpython\fileobject.h" /> - <ClInclude Include="..\Include\cpython\fileutils.h" /> - <ClInclude Include="..\Include\cpython\floatobject.h" /> - <ClInclude Include="..\Include\cpython\frameobject.h" /> - <ClInclude Include="..\Include\cpython\funcobject.h" /> - <ClInclude Include="..\Include\cpython\genobject.h" /> - <ClInclude Include="..\Include\cpython\import.h" /> - <ClInclude Include="..\Include\cpython\initconfig.h" /> - <ClInclude Include="..\Include\cpython\listobject.h" /> - <ClInclude Include="..\Include\cpython\longintrepr.h" /> - <ClInclude Include="..\Include\cpython\longobject.h" /> - <ClInclude Include="..\Include\cpython\methodobject.h" /> - <ClInclude Include="..\Include\cpython\modsupport.h" /> - <ClInclude Include="..\Include\cpython\object.h" /> - <ClInclude Include="..\Include\cpython\objimpl.h" /> - <ClInclude Include="..\Include\cpython\odictobject.h" /> - <ClInclude Include="..\Include\cpython\parser_interface.h" /> - <ClInclude Include="..\Include\cpython\picklebufobject.h" /> - <ClInclude Include="..\Include\cpython\pyarena.h" /> - <ClInclude Include="..\Include\cpython\pyctype.h" /> - <ClInclude Include="..\Include\cpython\pydebug.h" /> - <ClInclude Include="..\Include\cpython\pyerrors.h" /> - <ClInclude Include="..\Include\cpython\pyfpe.h" /> - <ClInclude Include="..\Include\cpython\pyframe.h" /> - <ClInclude Include="..\Include\cpython\pylifecycle.h" /> - <ClInclude Include="..\Include\cpython\pymem.h" /> - <ClInclude Include="..\Include\cpython\pystate.h" /> - <ClInclude Include="..\Include\cpython\pythonrun.h" /> - <ClInclude Include="..\Include\cpython\pythread.h" /> - <ClInclude Include="..\Include\cpython\pytime.h" /> - <ClInclude Include="..\Include\cpython\setobject.h" /> - <ClInclude Include="..\Include\cpython\sysmodule.h" /> - <ClInclude Include="..\Include\cpython\traceback.h" /> - <ClInclude Include="..\Include\cpython\tupleobject.h" /> - <ClInclude Include="..\Include\cpython\unicodeobject.h" /> - <ClInclude Include="..\Include\cpython\warnings.h" /> - <ClInclude Include="..\Include\cpython\weakrefobject.h" /> - <ClInclude Include="..\Include\datetime.h" /> - <ClInclude Include="..\Include\descrobject.h" /> - <ClInclude Include="..\Include\dictobject.h" /> - <ClInclude Include="..\Include\dynamic_annotations.h" /> - <ClInclude Include="..\Include\enumobject.h" /> - <ClInclude Include="..\Include\errcode.h" /> - <ClInclude Include="..\Include\fileobject.h" /> - <ClInclude Include="..\Include\fileutils.h" /> - <ClInclude Include="..\Include\floatobject.h" /> - <ClInclude Include="..\Include\frameobject.h" /> - <ClInclude Include="..\Include\import.h" /> - <ClInclude Include="..\Include\internal\pycore_abstract.h" /> - <ClInclude Include="..\Include\internal\pycore_accu.h" /> - <ClInclude Include="..\Include\internal\pycore_asdl.h" /> - <ClInclude Include="..\Include\internal\pycore_ast.h" /> - <ClInclude Include="..\Include\internal\pycore_ast_state.h" /> - <ClInclude Include="..\Include\internal\pycore_atomic.h" /> - <ClInclude Include="..\Include\internal\pycore_atomic_funcs.h" /> - <ClInclude Include="..\Include\internal\pycore_bitutils.h" /> - <ClInclude Include="..\Include\internal\pycore_bytes_methods.h" /> - <ClInclude Include="..\Include\internal\pycore_bytesobject.h" /> - <ClInclude Include="..\Include\internal\pycore_call.h" /> - <ClInclude Include="..\Include\internal\pycore_ceval.h" /> - <ClInclude Include="..\Include\internal\pycore_code.h" /> - <ClInclude Include="..\Include\internal\pycore_compile.h" /> - <ClInclude Include="..\Include\internal\pycore_condvar.h" /> - <ClInclude Include="..\Include\internal\pycore_context.h" /> - <ClInclude Include="..\Include\internal\pycore_dtoa.h" /> - <ClInclude Include="..\Include\internal\pycore_exceptions.h" /> - <ClInclude Include="..\Include\internal\pycore_fileutils.h" /> - <ClInclude Include="..\Include\internal\pycore_floatobject.h" /> - <ClInclude Include="..\Include\internal\pycore_format.h" /> - <ClInclude Include="..\Include\internal\pycore_function.h" /> - <ClInclude Include="..\Include\internal\pycore_gc.h" /> - <ClInclude Include="..\Include\internal\pycore_genobject.h" /> - <ClInclude Include="..\Include\internal\pycore_getopt.h" /> - <ClInclude Include="..\Include\internal\pycore_gil.h" /> - <ClInclude Include="..\Include\internal\pycore_global_objects.h" /> - <ClInclude Include="..\Include\internal\pycore_hamt.h" /> - <ClInclude Include="..\Include\internal\pycore_hashtable.h" /> - <ClInclude Include="..\Include\internal\pycore_import.h" /> - <ClInclude Include="..\Include\internal\pycore_initconfig.h" /> - <ClInclude Include="..\Include\internal\pycore_interp.h" /> - <ClInclude Include="..\Include\internal\pycore_interpreteridobject.h" /> - <ClInclude Include="..\Include\internal\pycore_list.h" /> - <ClInclude Include="..\Include\internal\pycore_long.h" /> - <ClInclude Include="..\Include\internal\pycore_moduleobject.h" /> - <ClInclude Include="..\Include\internal\pycore_namespace.h" /> - <ClInclude Include="..\Include\internal\pycore_object.h" /> - <ClInclude Include="..\Include\internal\pycore_pathconfig.h" /> - <ClInclude Include="..\Include\internal\pycore_pyarena.h" /> - <ClInclude Include="..\Include\internal\pycore_pyerrors.h" /> - <ClInclude Include="..\Include\internal\pycore_pyhash.h" /> - <ClInclude Include="..\Include\internal\pycore_pylifecycle.h" /> - <ClInclude Include="..\Include\internal\pycore_pymem.h" /> - <ClInclude Include="..\Include\internal\pycore_pystate.h" /> - <ClInclude Include="..\Include\internal\pycore_runtime.h" /> - <ClInclude Include="..\Include\internal\pycore_runtime_init.h" /> - <ClInclude Include="..\Include\internal\pycore_signal.h" /> - <ClInclude Include="..\Include\internal\pycore_sliceobject.h" /> - <ClInclude Include="..\Include\internal\pycore_strhex.h" /> - <ClInclude Include="..\Include\internal\pycore_structseq.h" /> - <ClInclude Include="..\Include\internal\pycore_sysmodule.h" /> - <ClInclude Include="..\Include\internal\pycore_symtable.h" /> - <ClInclude Include="..\Include\internal\pycore_traceback.h" /> - <ClInclude Include="..\Include\internal\pycore_tuple.h" /> - <ClInclude Include="..\Include\internal\pycore_typeobject.h" /> - <ClInclude Include="..\Include\internal\pycore_ucnhash.h" /> - <ClInclude Include="..\Include\internal\pycore_unionobject.h" /> - <ClInclude Include="..\Include\internal\pycore_unicodeobject.h" /> - <ClInclude Include="..\Include\internal\pycore_warnings.h" /> - <ClInclude Include="..\Include\intrcheck.h" /> - <ClInclude Include="..\Include\iterobject.h" /> - <ClInclude Include="..\Include\listobject.h" /> - <ClInclude Include="..\Include\longobject.h" /> - <ClInclude Include="..\Include\marshal.h" /> - <ClInclude Include="..\Include\memoryobject.h" /> - <ClInclude Include="..\Include\methodobject.h" /> - <ClInclude Include="..\Include\modsupport.h" /> - <ClInclude Include="..\Include\moduleobject.h" /> - <ClInclude Include="..\Include\object.h" /> - <ClInclude Include="..\Include\objimpl.h" /> - <ClInclude Include="..\Include\opcode.h" /> - <ClInclude Include="..\Include\osdefs.h" /> - <ClInclude Include="..\Include\osmodule.h" /> - <ClInclude Include="..\Include\patchlevel.h" /> - <ClInclude Include="..\Include\py_curses.h" /> - <ClInclude Include="..\Include\pybuffer.h" /> - <ClInclude Include="..\Include\pycapsule.h" /> - <ClInclude Include="..\Include\pyerrors.h" /> - <ClInclude Include="..\Include\pyexpat.h" /> - <ClInclude Include="..\Include\pyframe.h" /> - <ClInclude Include="..\Include\pyhash.h" /> - <ClInclude Include="..\Include\pylifecycle.h" /> - <ClInclude Include="..\Include\pymacro.h" /> - <ClInclude Include="..\Include\pymath.h" /> - <ClInclude Include="..\Include\pymem.h" /> - <ClInclude Include="..\Include\pyport.h" /> - <ClInclude Include="..\Include\pystate.h" /> - <ClInclude Include="..\Include\pystrcmp.h" /> - <ClInclude Include="..\Include\pystrtod.h" /> - <ClInclude Include="..\Include\pythonrun.h" /> - <ClInclude Include="..\Include\pythread.h" /> - <ClInclude Include="..\Include\pytypedefs.h" /> - <ClInclude Include="..\Include\rangeobject.h" /> - <ClInclude Include="..\Include\setobject.h" /> - <ClInclude Include="..\Include\sliceobject.h" /> - <ClInclude Include="..\Include\structmember.h" /> - <ClInclude Include="..\Include\structseq.h" /> - <ClInclude Include="..\Include\symtable.h" /> - <ClInclude Include="..\Include\sysmodule.h" /> - <ClInclude Include="..\Include\token.h" /> - <ClInclude Include="..\Include\traceback.h" /> - <ClInclude Include="..\Include\tracemalloc.h" /> - <ClInclude Include="..\Include\tupleobject.h" /> - <ClInclude Include="..\Include\unicodeobject.h" /> - <ClInclude Include="..\Include\weakrefobject.h" /> - <ClInclude Include="..\Modules\_math.h" /> - <ClInclude Include="..\Modules\hashtable.h" /> - <ClInclude Include="..\Modules\rotatingtree.h" /> - <ClInclude Include="..\Modules\_io\_iomodule.h" /> - <ClInclude Include="..\Modules\cjkcodecs\alg_jisx0201.h" /> - <ClInclude Include="..\Modules\cjkcodecs\cjkcodecs.h" /> - <ClInclude Include="..\Modules\cjkcodecs\emu_jisx0213_2000.h" /> - <ClInclude Include="..\Modules\cjkcodecs\mappings_cn.h" /> - <ClInclude Include="..\Modules\cjkcodecs\mappings_hk.h" /> - <ClInclude Include="..\Modules\cjkcodecs\mappings_jisx0213_pair.h" /> - <ClInclude Include="..\Modules\cjkcodecs\mappings_jp.h" /> - <ClInclude Include="..\Modules\cjkcodecs\mappings_kr.h" /> - <ClInclude Include="..\Modules\cjkcodecs\mappings_tw.h" /> - <ClInclude Include="..\Modules\cjkcodecs\multibytecodec.h" /> - <ClInclude Include="..\Objects\stringlib\count.h" /> - <ClInclude Include="..\Objects\stringlib\fastsearch.h" /> - <ClInclude Include="..\Objects\stringlib\find.h" /> - <ClInclude Include="..\Objects\stringlib\partition.h" /> - <ClInclude Include="..\Objects\stringlib\replace.h" /> - <ClInclude Include="..\Objects\stringlib\split.h" /> - <ClInclude Include="..\Objects\unicodetype_db.h" /> - <ClInclude Include="..\Parser\tokenizer.h" /> - <ClInclude Include="..\Parser\string_parser.h" /> - <ClInclude Include="..\Parser\pegen.h" /> - <ClInclude Include="..\PC\errmap.h" /> - <ClInclude Include="..\PC\pyconfig.h" /> - <ClInclude Include="..\Python\ceval_gil.h" /> - <ClInclude Include="..\Python\condvar.h" /> - <ClInclude Include="..\Python\importdl.h" /> - <ClInclude Include="..\Python\stdlib_module_names.h" /> - <ClInclude Include="..\Python\thread_nt.h" /> - </ItemGroup> - <ItemGroup Condition="$(IncludeExternals)"> - <ClInclude Include="$(zlibDir)\crc32.h" /> - <ClInclude Include="$(zlibDir)\deflate.h" /> - <ClInclude Include="$(zlibDir)\inffast.h" /> - <ClInclude Include="$(zlibDir)\inffixed.h" /> - <ClInclude Include="$(zlibDir)\inflate.h" /> - <ClInclude Include="$(zlibDir)\inftrees.h" /> - <ClInclude Include="$(zlibDir)\trees.h" /> - <ClInclude Include="$(zlibDir)\zconf.h" /> - <ClInclude Include="$(zlibDir)\zconf.in.h" /> - <ClInclude Include="$(zlibDir)\zlib.h" /> - <ClInclude Include="$(zlibDir)\zutil.h" /> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\Modules\_abc.c" /> - <ClCompile Include="..\Modules\_bisectmodule.c" /> - <ClCompile Include="..\Modules\_blake2\blake2module.c" /> - <ClCompile Include="..\Modules\_blake2\blake2b_impl.c" /> - <ClCompile Include="..\Modules\_blake2\blake2s_impl.c" /> - <ClCompile Include="..\Modules\_codecsmodule.c" /> - <ClCompile Include="..\Modules\_collectionsmodule.c" /> - <ClCompile Include="..\Modules\_contextvarsmodule.c" /> - <ClCompile Include="..\Modules\_csv.c" /> - <ClCompile Include="..\Modules\_functoolsmodule.c" /> - <ClCompile Include="..\Modules\_heapqmodule.c" /> - <ClCompile Include="..\Modules\_json.c" /> - <ClCompile Include="..\Modules\_localemodule.c" /> - <ClCompile Include="..\Modules\_lsprof.c" /> - <ClCompile Include="..\Modules\_pickle.c" /> - <ClCompile Include="..\Modules\_randommodule.c" /> - <ClCompile Include="..\Modules\_sha3\sha3module.c" /> - <ClCompile Include="..\Modules\_sre\sre.c" /> - <ClInclude Include="..\Modules\_sre\sre.h" /> - <ClInclude Include="..\Modules\_sre\sre_constants.h" /> - <ClInclude Include="..\Modules\_sre\sre_lib.h" /> - <ClCompile Include="..\Modules\_stat.c" /> - <ClCompile Include="..\Modules\_struct.c" /> - <ClCompile Include="..\Modules\_weakref.c" /> - <ClCompile Include="..\Modules\arraymodule.c" /> - <ClCompile Include="..\Modules\atexitmodule.c" /> - <ClCompile Include="..\Modules\audioop.c" /> - <ClCompile Include="..\Modules\binascii.c"> - <PreprocessorDefinitions>USE_ZLIB_CRC32;%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\Modules\cmathmodule.c" /> - <ClCompile Include="..\Modules\_datetimemodule.c" /> - <ClCompile Include="..\Modules\errnomodule.c" /> - <ClCompile Include="..\Modules\faulthandler.c" /> - <ClCompile Include="..\Modules\gcmodule.c" /> - <ClCompile Include="..\Modules\getbuildinfo.c" /> - <ClCompile Include="..\Modules\itertoolsmodule.c" /> - <ClCompile Include="..\Modules\main.c" /> - <ClCompile Include="..\Modules\mathmodule.c" /> - <ClCompile Include="..\Modules\md5module.c" /> - <ClCompile Include="..\Modules\mmapmodule.c" /> - <ClCompile Include="..\Modules\_opcode.c" /> - <ClCompile Include="..\Modules\_operator.c" /> - <ClCompile Include="..\Modules\posixmodule.c" /> - <ClCompile Include="..\Modules\rotatingtree.c" /> - <ClCompile Include="..\Modules\sha1module.c" /> - <ClCompile Include="..\Modules\sha256module.c" /> - <ClCompile Include="..\Modules\sha512module.c" /> - <ClCompile Include="..\Modules\signalmodule.c" /> - <ClCompile Include="..\Modules\_statisticsmodule.c" /> - <ClCompile Include="..\Modules\symtablemodule.c" /> - <ClCompile Include="..\Modules\_threadmodule.c" /> - <ClCompile Include="..\Modules\_tracemalloc.c" /> - <ClCompile Include="..\Modules\_typingmodule.c" /> - <ClCompile Include="..\Modules\timemodule.c" /> - <ClCompile Include="..\Modules\xxsubtype.c" /> - <ClCompile Include="..\Modules\_xxsubinterpretersmodule.c" /> - <ClCompile Include="..\Modules\_io\fileio.c" /> - <ClCompile Include="..\Modules\_io\bytesio.c" /> - <ClCompile Include="..\Modules\_io\stringio.c" /> - <ClCompile Include="..\Modules\_io\bufferedio.c" /> - <ClCompile Include="..\Modules\_io\iobase.c" /> - <ClCompile Include="..\Modules\_io\textio.c" /> - <ClCompile Include="..\Modules\_io\winconsoleio.c" /> - <ClCompile Include="..\Modules\_io\_iomodule.c" /> - <ClCompile Include="..\Modules\cjkcodecs\_codecs_cn.c" /> - <ClCompile Include="..\Modules\cjkcodecs\_codecs_hk.c" /> - <ClCompile Include="..\Modules\cjkcodecs\_codecs_iso2022.c" /> - <ClCompile Include="..\Modules\cjkcodecs\_codecs_jp.c" /> - <ClCompile Include="..\Modules\cjkcodecs\_codecs_kr.c" /> - <ClCompile Include="..\Modules\cjkcodecs\_codecs_tw.c" /> - <ClCompile Include="..\Modules\cjkcodecs\multibytecodec.c" /> - <ClCompile Include="..\Modules\_winapi.c" /> - <ClCompile Include="..\Objects\abstract.c" /> - <ClCompile Include="..\Objects\accu.c" /> - <ClCompile Include="..\Objects\boolobject.c" /> - <ClCompile Include="..\Objects\bytearrayobject.c" /> - <ClCompile Include="..\Objects\bytes_methods.c" /> - <ClCompile Include="..\Objects\bytesobject.c" /> - <ClCompile Include="..\Objects\call.c" /> - <ClCompile Include="..\Objects\capsule.c" /> - <ClCompile Include="..\Objects\cellobject.c" /> - <ClCompile Include="..\Objects\classobject.c" /> - <ClCompile Include="..\Objects\codeobject.c" /> - <ClCompile Include="..\Objects\complexobject.c" /> - <ClCompile Include="..\Objects\descrobject.c" /> - <ClCompile Include="..\Objects\dictobject.c" /> - <ClCompile Include="..\Objects\enumobject.c" /> - <ClCompile Include="..\Objects\exceptions.c" /> - <ClCompile Include="..\Objects\fileobject.c" /> - <ClCompile Include="..\Objects\floatobject.c" /> - <ClCompile Include="..\Objects\frameobject.c" /> - <ClCompile Include="..\Objects\funcobject.c" /> - <ClCompile Include="..\Objects\genericaliasobject.c" /> - <ClCompile Include="..\Objects\genobject.c" /> - <ClCompile Include="..\Objects\interpreteridobject.c" /> - <ClCompile Include="..\Objects\iterobject.c" /> - <ClCompile Include="..\Objects\listobject.c" /> - <ClCompile Include="..\Objects\longobject.c" /> - <ClCompile Include="..\Objects\memoryobject.c" /> - <ClCompile Include="..\Objects\methodobject.c" /> - <ClCompile Include="..\Objects\moduleobject.c" /> - <ClCompile Include="..\Objects\namespaceobject.c" /> - <ClCompile Include="..\Objects\object.c" /> - <ClCompile Include="..\Objects\obmalloc.c" /> - <ClCompile Include="..\Objects\odictobject.c" /> - <ClCompile Include="..\Objects\picklebufobject.c" /> - <ClCompile Include="..\Objects\rangeobject.c" /> - <ClCompile Include="..\Objects\setobject.c" /> - <ClCompile Include="..\Objects\sliceobject.c" /> - <ClCompile Include="..\Objects\structseq.c" /> - <ClCompile Include="..\Objects\tupleobject.c" /> - <ClCompile Include="..\Objects\typeobject.c" /> - <ClCompile Include="..\Objects\unicodectype.c" /> - <ClCompile Include="..\Objects\unicodeobject.c" /> - <ClCompile Include="..\Objects\unionobject.c" /> - <ClCompile Include="..\Objects\weakrefobject.c" /> - <ClCompile Include="..\Parser\myreadline.c" /> - <ClCompile Include="..\Parser\tokenizer.c" /> - <ClCompile Include="..\Parser\token.c" /> - <ClCompile Include="..\Parser\pegen.c" /> - <ClCompile Include="..\Parser\pegen_errors.c" /> - <ClCompile Include="..\Parser\action_helpers.c" /> - <ClCompile Include="..\Parser\parser.c" /> - <ClCompile Include="..\Parser\string_parser.c" /> - <ClCompile Include="..\Parser\peg_api.c" /> - <ClCompile Include="..\PC\invalid_parameter_handler.c" /> - <ClCompile Include="..\PC\winreg.c" /> - <ClCompile Include="..\PC\config.c" /> - <ClCompile Include="..\PC\msvcrtmodule.c" /> - <ClCompile Include="..\Python\pyhash.c" /> - <ClCompile Include="..\Python\_warnings.c" /> - <ClCompile Include="..\Python\asdl.c" /> - <ClCompile Include="..\Python\ast.c" /> - <ClCompile Include="..\Python\ast_opt.c" /> - <ClCompile Include="..\Python\ast_unparse.c" /> - <ClCompile Include="..\Python\bltinmodule.c" /> - <ClCompile Include="..\Python\bootstrap_hash.c" /> - <ClCompile Include="..\Python\ceval.c" /> - <ClCompile Include="..\Python\codecs.c" /> - <ClCompile Include="..\Python\compile.c" /> - <ClCompile Include="..\Python\context.c" /> - <ClCompile Include="..\Python\dynamic_annotations.c" /> - <ClCompile Include="..\Python\dynload_win.c" /> - <ClCompile Include="..\Python\errors.c" /> - <ClCompile Include="..\Python\fileutils.c" /> - <ClCompile Include="..\Python\formatter_unicode.c" /> - <ClCompile Include="..\Python\frame.c" /> - <ClCompile Include="..\Python\frozen.c" /> - <ClCompile Include="..\Python\future.c" /> - <ClCompile Include="..\Python\getargs.c" /> - <ClCompile Include="..\Python\getcompiler.c" /> - <ClCompile Include="..\Python\getcopyright.c" /> - <ClCompile Include="..\Python\getopt.c" /> - <ClCompile Include="..\Python\getplatform.c" /> - <ClCompile Include="..\Python\getversion.c" /> - <ClCompile Include="..\Python\hamt.c" /> - <ClCompile Include="..\Python\hashtable.c" /> - <ClCompile Include="..\Python\import.c" /> - <ClCompile Include="..\Python\importdl.c" /> - <ClCompile Include="..\Python\initconfig.c" /> - <ClCompile Include="..\Python\marshal.c" /> - <ClCompile Include="..\Python\modsupport.c" /> - <ClCompile Include="..\Python\mysnprintf.c" /> - <ClCompile Include="..\Python\mystrtoul.c" /> - <ClCompile Include="..\Python\pathconfig.c" /> - <ClCompile Include="..\Python\preconfig.c" /> - <ClCompile Include="..\Python\pyarena.c" /> - <ClCompile Include="..\Python\pyctype.c" /> - <ClCompile Include="..\Python\pyfpe.c" /> - <ClCompile Include="..\Python\pylifecycle.c" /> - <ClCompile Include="..\Python\pymath.c" /> - <ClCompile Include="..\Python\pytime.c" /> - <ClCompile Include="..\Python\pystate.c" /> - <ClCompile Include="..\Python\pystrcmp.c" /> - <ClCompile Include="..\Python\pystrhex.c" /> - <ClCompile Include="..\Python\pystrtod.c" /> - <ClCompile Include="..\Python\dtoa.c" /> - <ClCompile Include="..\Python\Python-ast.c" /> - <ClCompile Include="..\Python\Python-tokenize.c" /> - <ClCompile Include="..\Python\pythonrun.c" /> - <ClCompile Include="..\Python\specialize.c" /> - <ClCompile Include="..\Python\suggestions.c" /> - <ClCompile Include="..\Python\structmember.c" /> - <ClCompile Include="..\Python\symtable.c" /> - <ClCompile Include="..\Python\sysmodule.c"> - <PreprocessorDefinitions>VPATH="$(PyVPath)";%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <ClCompile Include="..\Python\thread.c" /> - <ClCompile Include="..\Python\traceback.c" /> - </ItemGroup> - <ItemGroup> - <!-- BEGIN deepfreeze --> - <ClCompile Include="..\Python\deepfreeze\deepfreeze.c" /> - <!-- END deepfreeze --> - </ItemGroup> - <ItemGroup Condition="$(IncludeExternals)"> - <ClCompile Include="..\Modules\zlibmodule.c" /> - <ClCompile Include="$(zlibDir)\adler32.c" /> - <ClCompile Include="$(zlibDir)\compress.c" /> - <ClCompile Include="$(zlibDir)\crc32.c" /> - <ClCompile Include="$(zlibDir)\deflate.c"> - <DisableSpecificWarnings>4244</DisableSpecificWarnings> - </ClCompile> - <ClCompile Include="$(zlibDir)\infback.c" /> - <ClCompile Include="$(zlibDir)\inffast.c" /> - <ClCompile Include="$(zlibDir)\inflate.c" /> - <ClCompile Include="$(zlibDir)\inftrees.c" /> - <ClCompile Include="$(zlibDir)\trees.c" /> - <ClCompile Include="$(zlibDir)\uncompr.c" /> - <ClCompile Include="$(zlibDir)\zutil.c" /> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\PC\dl_nt.c" /> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\python_nt.rc" /> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - <Import Project="regen.targets" /> - </ImportGroup> - <Target Name="_TriggerRegen" BeforeTargets="PrepareForBuild" DependsOnTargets="Regen" /> - <Target Name="_GetBuildInfo" BeforeTargets="PrepareForBuild"> - <PropertyGroup> - <GIT Condition="$(GIT) == ''">git</GIT> - <_GIT>$(GIT)</_GIT> - <_GIT Condition="$(GIT.Contains(` `))">"$(GIT)"</_GIT> - </PropertyGroup> - <Message Text="Getting build info from $(_GIT)" Importance="high" /> - <MakeDir Directories="$(IntDir)" Condition="!Exists($(IntDir))" /> - <Exec Command="$(_GIT) name-rev --name-only HEAD > "$(IntDir)gitbranch.txt"" ContinueOnError="true" /> - <Exec Command="$(_GIT) rev-parse --short HEAD > "$(IntDir)gitversion.txt"" ContinueOnError="true" /> - <Exec Command="$(_GIT) describe --all --always --dirty > "$(IntDir)gittag.txt"" ContinueOnError="true" /> - <PropertyGroup> - <GitBranch Condition="Exists('$(IntDir)gitbranch.txt')">$([System.IO.File]::ReadAllText('$(IntDir)gitbranch.txt').Trim())</GitBranch> - <GitVersion Condition="Exists('$(IntDir)gitversion.txt')">$([System.IO.File]::ReadAllText('$(IntDir)gitversion.txt').Trim())</GitVersion> - <GitTag Condition="Exists('$(IntDir)gittag.txt')">$([System.IO.File]::ReadAllText('$(IntDir)gittag.txt').Trim())</GitTag> - </PropertyGroup> - <Message Text="Building $(GitTag):$(GitVersion) $(GitBranch)" Importance="high" /> - <ItemGroup> - <ClCompile Condition="%(Filename) == 'getbuildinfo'"> - <PreprocessorDefinitions>GITVERSION="$(GitVersion)";GITTAG="$(GitTag)";GITBRANCH="$(GitBranch)";%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - </ItemGroup> - </Target> - <Target Name="_WarnAboutToolset" BeforeTargets="PrepareForBuild" Condition="$(PlatformToolset) != 'v140' and $(PlatformToolset) != 'v141' and $(PlatformToolset) != 'v142' and $(PlatformToolset) != 'v143'"> - <Warning Text="Toolset $(PlatformToolset) is not used for official builds. Your build may have errors or incompatibilities." /> - </Target> - <Target Name="_WarnAboutZlib" BeforeTargets="PrepareForBuild" Condition="!$(IncludeExternals)"> - <Warning Text="Not including zlib is not a supported configuration." /> - </Target> - - <Target Name="_CopyVCRuntime" AfterTargets="Build" Inputs="@(VCRuntimeDLL)" Outputs="$(OutDir)%(Filename)%(Extension)" DependsOnTargets="FindVCRuntime"> - <!-- bpo-38597: When we switch to another VCRuntime DLL, include vcruntime140.dll as well --> - <Warning Text="A copy of vcruntime140.dll is also required" Condition="!$(VCToolsRedistVersion.StartsWith(`14.`))" /> - <Copy SourceFiles="%(VCRuntimeDLL.FullPath)" DestinationFolder="$(OutDir)" /> - </Target> - <Target Name="_CleanVCRuntime" AfterTargets="Clean"> - <Delete Files="@(VCRuntimeDLL->'$(OutDir)%(Filename)%(Extension)')" /> - </Target> - - <Target Name="_DeletePyBuildDirTxt" BeforeTargets="PrepareForBuild"> - <Delete Files="$(OutDir)pybuilddir.txt" /> - </Target> -</Project> +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|ARM"> + <Configuration>Debug</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|ARM64"> + <Configuration>Debug</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM64"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|Win32"> + <Configuration>PGInstrument</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|x64"> + <Configuration>PGInstrument</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM64"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|Win32"> + <Configuration>PGUpdate</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|x64"> + <Configuration>PGUpdate</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM"> + <Configuration>Release</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM64"> + <Configuration>Release</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}</ProjectGuid> + <RootNamespace>pythoncore</RootNamespace> + </PropertyGroup> + <Import Project="python.props" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <PropertyGroup> + <KillPython>true</KillPython> + <RequirePGCFiles>true</RequirePGCFiles> + <IncludeExternals Condition="$(IncludeExternals) == '' and Exists('$(zlibDir)\zlib.h')">true</IncludeExternals> + <IncludeExternals Condition="$(IncludeExternals) == ''">false</IncludeExternals> + </PropertyGroup> + <ImportGroup Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="pyproject.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> + <TargetName>$(PyDllName)</TargetName> + </PropertyGroup> + <PropertyGroup> + <CustomBuildBeforeTargets>Link</CustomBuildBeforeTargets> + </PropertyGroup> + <ItemDefinitionGroup> + <ClCompile> + <AdditionalOptions>/Zm200 %(AdditionalOptions)</AdditionalOptions> + <AdditionalIncludeDirectories>$(PySourcePath)Modules\_hacl\include;$(PySourcePath)Modules\_hacl\internal;$(PySourcePath)Python;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <AdditionalIncludeDirectories Condition="$(IncludeExternals)">$(zlibDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_USRDLL;Py_BUILD_CORE;Py_BUILD_CORE_BUILTIN;Py_ENABLE_SHARED;MS_DLL_ID="$(SysWinVer)";%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions Condition="$(IncludeExternals)">_Py_HAVE_ZLIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <Link> + <AdditionalDependencies>version.lib;ws2_32.lib;pathcch.lib;bcrypt.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\Modules\getpath.c"> + <PreprocessorDefinitions> + PREFIX=NULL; + EXEC_PREFIX=NULL; + VERSION=NULL; + VPATH="$(PyVPath)"; + PYDEBUGEXT="$(PyDebugExt)"; + PLATLIBDIR="DLLs"; + %(PreprocessorDefinitions) + </PreprocessorDefinitions> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\Include\Python.h" /> + <ClInclude Include="..\Include\abstract.h" /> + <ClInclude Include="..\Include\boolobject.h" /> + <ClInclude Include="..\Include\bytearrayobject.h" /> + <ClInclude Include="..\Include\bytesobject.h" /> + <ClInclude Include="..\Include\ceval.h" /> + <ClInclude Include="..\Include\codecs.h" /> + <ClInclude Include="..\Include\compile.h" /> + <ClInclude Include="..\Include\complexobject.h" /> + <ClInclude Include="..\Include\cpython\abstract.h" /> + <ClInclude Include="..\Include\cpython\bytearrayobject.h" /> + <ClInclude Include="..\Include\cpython\bytesobject.h" /> + <ClInclude Include="..\Include\cpython\cellobject.h" /> + <ClInclude Include="..\Include\cpython\ceval.h" /> + <ClInclude Include="..\Include\cpython\classobject.h" /> + <ClInclude Include="..\Include\cpython\code.h" /> + <ClInclude Include="..\Include\cpython\compile.h" /> + <ClInclude Include="..\Include\cpython\complexobject.h" /> + <ClInclude Include="..\Include\cpython\context.h" /> + <ClInclude Include="..\Include\cpython\descrobject.h" /> + <ClInclude Include="..\Include\cpython\dictobject.h" /> + <ClInclude Include="..\Include\cpython\fileobject.h" /> + <ClInclude Include="..\Include\cpython\fileutils.h" /> + <ClInclude Include="..\Include\cpython\floatobject.h" /> + <ClInclude Include="..\Include\cpython\frameobject.h" /> + <ClInclude Include="..\Include\cpython\funcobject.h" /> + <ClInclude Include="..\Include\cpython\genobject.h" /> + <ClInclude Include="..\Include\cpython\import.h" /> + <ClInclude Include="..\Include\cpython\initconfig.h" /> + <ClInclude Include="..\Include\cpython\interpreteridobject.h" /> + <ClInclude Include="..\Include\cpython\listobject.h" /> + <ClInclude Include="..\Include\cpython\longintrepr.h" /> + <ClInclude Include="..\Include\cpython\longobject.h" /> + <ClInclude Include="..\Include\cpython\memoryobject.h" /> + <ClInclude Include="..\Include\cpython\methodobject.h" /> + <ClInclude Include="..\Include\cpython\modsupport.h" /> + <ClInclude Include="..\Include\cpython\object.h" /> + <ClInclude Include="..\Include\cpython\objimpl.h" /> + <ClInclude Include="..\Include\cpython\odictobject.h" /> + <ClInclude Include="..\Include\cpython\parser_interface.h" /> + <ClInclude Include="..\Include\cpython\picklebufobject.h" /> + <ClInclude Include="..\Include\cpython\pyarena.h" /> + <ClInclude Include="..\Include\cpython\pyctype.h" /> + <ClInclude Include="..\Include\cpython\pydebug.h" /> + <ClInclude Include="..\Include\cpython\pyerrors.h" /> + <ClInclude Include="..\Include\cpython\pyfpe.h" /> + <ClInclude Include="..\Include\cpython\pyframe.h" /> + <ClInclude Include="..\Include\cpython\pylifecycle.h" /> + <ClInclude Include="..\Include\cpython\pymem.h" /> + <ClInclude Include="..\Include\cpython\pystate.h" /> + <ClInclude Include="..\Include\cpython\pythonrun.h" /> + <ClInclude Include="..\Include\cpython\pythread.h" /> + <ClInclude Include="..\Include\cpython\pytime.h" /> + <ClInclude Include="..\Include\cpython\setobject.h" /> + <ClInclude Include="..\Include\cpython\sysmodule.h" /> + <ClInclude Include="..\Include\cpython\traceback.h" /> + <ClInclude Include="..\Include\cpython\tupleobject.h" /> + <ClInclude Include="..\Include\cpython\unicodeobject.h" /> + <ClInclude Include="..\Include\cpython\warnings.h" /> + <ClInclude Include="..\Include\cpython\weakrefobject.h" /> + <ClInclude Include="..\Include\datetime.h" /> + <ClInclude Include="..\Include\descrobject.h" /> + <ClInclude Include="..\Include\dictobject.h" /> + <ClInclude Include="..\Include\dynamic_annotations.h" /> + <ClInclude Include="..\Include\enumobject.h" /> + <ClInclude Include="..\Include\errcode.h" /> + <ClInclude Include="..\Include\fileobject.h" /> + <ClInclude Include="..\Include\fileutils.h" /> + <ClInclude Include="..\Include\floatobject.h" /> + <ClInclude Include="..\Include\frameobject.h" /> + <ClInclude Include="..\Include\import.h" /> + <ClInclude Include="..\Include\internal\pycore_abstract.h" /> + <ClInclude Include="..\Include\internal\pycore_asdl.h" /> + <ClInclude Include="..\Include\internal\pycore_ast.h" /> + <ClInclude Include="..\Include\internal\pycore_ast_state.h" /> + <ClInclude Include="..\Include\internal\pycore_atexit.h" /> + <ClInclude Include="..\Include\internal\pycore_atomic.h" /> + <ClInclude Include="..\Include\internal\pycore_atomic_funcs.h" /> + <ClInclude Include="..\Include\internal\pycore_bitutils.h" /> + <ClInclude Include="..\Include\internal\pycore_bytes_methods.h" /> + <ClInclude Include="..\Include\internal\pycore_bytesobject.h" /> + <ClInclude Include="..\Include\internal\pycore_call.h" /> + <ClInclude Include="..\Include\internal\pycore_ceval.h" /> + <ClInclude Include="..\Include\internal\pycore_ceval_state.h" /> + <ClInclude Include="..\Include\internal\pycore_cfg.h" /> + <ClInclude Include="..\Include\internal\pycore_code.h" /> + <ClInclude Include="..\Include\internal\pycore_compile.h" /> + <ClInclude Include="..\Include\internal\pycore_condvar.h" /> + <ClInclude Include="..\Include\internal\pycore_context.h" /> + <ClInclude Include="..\Include\internal\pycore_descrobject.h" /> + <ClInclude Include="..\Include\internal\pycore_dict.h" /> + <ClInclude Include="..\Include\internal\pycore_dict_state.h" /> + <ClInclude Include="..\Include\internal\pycore_dtoa.h" /> + <ClInclude Include="..\Include\internal\pycore_exceptions.h" /> + <ClInclude Include="..\Include\internal\pycore_faulthandler.h" /> + <ClInclude Include="..\Include\internal\pycore_fileutils.h" /> + <ClInclude Include="..\Include\internal\pycore_fileutils_windows.h" /> + <ClInclude Include="..\Include\internal\pycore_floatobject.h" /> + <ClInclude Include="..\Include\internal\pycore_format.h" /> + <ClInclude Include="..\Include\internal\pycore_frame.h" /> + <ClInclude Include="..\Include\internal\pycore_function.h" /> + <ClInclude Include="..\Include\internal\pycore_gc.h" /> + <ClInclude Include="..\Include\internal\pycore_genobject.h" /> + <ClInclude Include="..\Include\internal\pycore_getopt.h" /> + <ClInclude Include="..\Include\internal\pycore_gil.h" /> + <ClInclude Include="..\Include\internal\pycore_global_objects.h" /> + <ClInclude Include="..\Include\internal\pycore_global_objects_fini_generated.h" /> + <ClInclude Include="..\Include\internal\pycore_hamt.h" /> + <ClInclude Include="..\Include\internal\pycore_hashtable.h" /> + <ClInclude Include="..\Include\internal\pycore_import.h" /> + <ClInclude Include="..\Include\internal\pycore_initconfig.h" /> + <ClInclude Include="..\Include\internal\pycore_interp.h" /> + <ClInclude Include="..\Include\internal\pycore_intrinsics.h" /> + <ClInclude Include="..\Include\internal\pycore_list.h" /> + <ClInclude Include="..\Include\internal\pycore_long.h" /> + <ClInclude Include="..\Include\internal\pycore_moduleobject.h" /> + <ClInclude Include="..\Include\internal\pycore_namespace.h" /> + <ClInclude Include="..\Include\internal\pycore_object.h" /> + <ClInclude Include="..\Include\internal\pycore_object_state.h" /> + <ClInclude Include="..\Include\internal\pycore_obmalloc.h" /> + <ClInclude Include="..\Include\internal\pycore_obmalloc_init.h" /> + <ClInclude Include="..\Include\internal\pycore_pathconfig.h" /> + <ClInclude Include="..\Include\internal\pycore_pyarena.h" /> + <ClInclude Include="..\Include\internal\pycore_pyerrors.h" /> + <ClInclude Include="..\Include\internal\pycore_pyhash.h" /> + <ClInclude Include="..\Include\internal\pycore_pylifecycle.h" /> + <ClInclude Include="..\Include\internal\pycore_pymem.h" /> + <ClInclude Include="..\Include\internal\pycore_pymem_init.h" /> + <ClInclude Include="..\Include\internal\pycore_pystate.h" /> + <ClInclude Include="..\Include\internal\pycore_pythread.h" /> + <ClInclude Include="..\Include\internal\pycore_range.h" /> + <ClInclude Include="..\Include\internal\pycore_runtime.h" /> + <ClInclude Include="..\Include\internal\pycore_runtime_init.h" /> + <ClInclude Include="..\Include\internal\pycore_runtime_init_generated.h" /> + <ClInclude Include="..\Include\internal\pycore_signal.h" /> + <ClInclude Include="..\Include\internal\pycore_sliceobject.h" /> + <ClInclude Include="..\Include\internal\pycore_strhex.h" /> + <ClInclude Include="..\Include\internal\pycore_structseq.h" /> + <ClInclude Include="..\Include\internal\pycore_sysmodule.h" /> + <ClInclude Include="..\Include\internal\pycore_symtable.h" /> + <ClInclude Include="..\Include\internal\pycore_time.h" /> + <ClInclude Include="..\Include\internal\pycore_token.h" /> + <ClInclude Include="..\Include\internal\pycore_traceback.h" /> + <ClInclude Include="..\Include\internal\pycore_tracemalloc.h" /> + <ClInclude Include="..\Include\internal\pycore_tuple.h" /> + <ClInclude Include="..\Include\internal\pycore_typeobject.h" /> + <ClInclude Include="..\Include\internal\pycore_typevarobject.h" /> + <ClInclude Include="..\Include\internal\pycore_ucnhash.h" /> + <ClInclude Include="..\Include\internal\pycore_unionobject.h" /> + <ClInclude Include="..\Include\internal\pycore_unicodeobject.h" /> + <ClInclude Include="..\Include\internal\pycore_unicodeobject_generated.h" /> + <ClInclude Include="..\Include\internal\pycore_warnings.h" /> + <ClInclude Include="..\Include\interpreteridobject.h" /> + <ClInclude Include="..\Include\intrcheck.h" /> + <ClInclude Include="..\Include\iterobject.h" /> + <ClInclude Include="..\Include\listobject.h" /> + <ClInclude Include="..\Include\longobject.h" /> + <ClInclude Include="..\Include\marshal.h" /> + <ClInclude Include="..\Include\memoryobject.h" /> + <ClInclude Include="..\Include\methodobject.h" /> + <ClInclude Include="..\Include\modsupport.h" /> + <ClInclude Include="..\Include\moduleobject.h" /> + <ClInclude Include="..\Include\object.h" /> + <ClInclude Include="..\Include\objimpl.h" /> + <ClInclude Include="..\Include\opcode.h" /> + <ClInclude Include="..\Include\osdefs.h" /> + <ClInclude Include="..\Include\osmodule.h" /> + <ClInclude Include="..\Include\patchlevel.h" /> + <ClInclude Include="..\Include\py_curses.h" /> + <ClInclude Include="..\Include\pybuffer.h" /> + <ClInclude Include="..\Include\pycapsule.h" /> + <ClInclude Include="..\Include\pyerrors.h" /> + <ClInclude Include="..\Include\pyexpat.h" /> + <ClInclude Include="..\Include\pyframe.h" /> + <ClInclude Include="..\Include\pyhash.h" /> + <ClInclude Include="..\Include\pylifecycle.h" /> + <ClInclude Include="..\Include\pymacro.h" /> + <ClInclude Include="..\Include\pymath.h" /> + <ClInclude Include="..\Include\pymem.h" /> + <ClInclude Include="..\Include\pyport.h" /> + <ClInclude Include="..\Include\pystate.h" /> + <ClInclude Include="..\Include\pystats.h" /> + <ClInclude Include="..\Include\pystrcmp.h" /> + <ClInclude Include="..\Include\pystrtod.h" /> + <ClInclude Include="..\Include\pythonrun.h" /> + <ClInclude Include="..\Include\pythread.h" /> + <ClInclude Include="..\Include\pytypedefs.h" /> + <ClInclude Include="..\Include\rangeobject.h" /> + <ClInclude Include="..\Include\setobject.h" /> + <ClInclude Include="..\Include\sliceobject.h" /> + <ClInclude Include="..\Include\structmember.h" /> + <ClInclude Include="..\Include\structseq.h" /> + <ClInclude Include="..\Include\symtable.h" /> + <ClInclude Include="..\Include\sysmodule.h" /> + <ClInclude Include="..\Include\traceback.h" /> + <ClInclude Include="..\Include\tracemalloc.h" /> + <ClInclude Include="..\Include\tupleobject.h" /> + <ClInclude Include="..\Include\unicodeobject.h" /> + <ClInclude Include="..\Include\weakrefobject.h" /> + <ClInclude Include="..\Modules\_math.h" /> + <ClInclude Include="..\Modules\hashtable.h" /> + <ClInclude Include="..\Modules\rotatingtree.h" /> + <ClInclude Include="..\Modules\_io\_iomodule.h" /> + <ClInclude Include="..\Modules\cjkcodecs\alg_jisx0201.h" /> + <ClInclude Include="..\Modules\cjkcodecs\cjkcodecs.h" /> + <ClInclude Include="..\Modules\cjkcodecs\emu_jisx0213_2000.h" /> + <ClInclude Include="..\Modules\cjkcodecs\mappings_cn.h" /> + <ClInclude Include="..\Modules\cjkcodecs\mappings_hk.h" /> + <ClInclude Include="..\Modules\cjkcodecs\mappings_jisx0213_pair.h" /> + <ClInclude Include="..\Modules\cjkcodecs\mappings_jp.h" /> + <ClInclude Include="..\Modules\cjkcodecs\mappings_kr.h" /> + <ClInclude Include="..\Modules\cjkcodecs\mappings_tw.h" /> + <ClInclude Include="..\Modules\cjkcodecs\multibytecodec.h" /> + <ClInclude Include="..\Objects\stringlib\count.h" /> + <ClInclude Include="..\Objects\stringlib\fastsearch.h" /> + <ClInclude Include="..\Objects\stringlib\find.h" /> + <ClInclude Include="..\Objects\stringlib\partition.h" /> + <ClInclude Include="..\Objects\stringlib\replace.h" /> + <ClInclude Include="..\Objects\stringlib\split.h" /> + <ClInclude Include="..\Objects\unicodetype_db.h" /> + <ClInclude Include="..\Parser\tokenizer.h" /> + <ClInclude Include="..\Parser\string_parser.h" /> + <ClInclude Include="..\Parser\pegen.h" /> + <ClInclude Include="..\PC\errmap.h" /> + <ClInclude Include="..\PC\pyconfig.h" /> + <ClInclude Include="..\Python\condvar.h" /> + <ClInclude Include="..\Python\importdl.h" /> + <ClInclude Include="..\Python\stdlib_module_names.h" /> + <ClInclude Include="..\Python\thread_nt.h" /> + </ItemGroup> + <ItemGroup Condition="$(IncludeExternals)"> + <ClInclude Include="$(zlibDir)\crc32.h" /> + <ClInclude Include="$(zlibDir)\deflate.h" /> + <ClInclude Include="$(zlibDir)\inffast.h" /> + <ClInclude Include="$(zlibDir)\inffixed.h" /> + <ClInclude Include="$(zlibDir)\inflate.h" /> + <ClInclude Include="$(zlibDir)\inftrees.h" /> + <ClInclude Include="$(zlibDir)\trees.h" /> + <ClInclude Include="$(zlibDir)\zconf.h" /> + <ClInclude Include="$(zlibDir)\zconf.in.h" /> + <ClInclude Include="$(zlibDir)\zlib.h" /> + <ClInclude Include="$(zlibDir)\zutil.h" /> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\Modules\_abc.c" /> + <ClCompile Include="..\Modules\_bisectmodule.c" /> + <ClCompile Include="..\Modules\_blake2\blake2module.c" /> + <ClCompile Include="..\Modules\_blake2\blake2b_impl.c" /> + <ClCompile Include="..\Modules\_blake2\blake2s_impl.c" /> + <ClCompile Include="..\Modules\_codecsmodule.c" /> + <ClCompile Include="..\Modules\_collectionsmodule.c" /> + <ClCompile Include="..\Modules\_contextvarsmodule.c" /> + <ClCompile Include="..\Modules\_csv.c" /> + <ClCompile Include="..\Modules\_functoolsmodule.c" /> + <ClCompile Include="..\Modules\_hacl\Hacl_Hash_MD5.c" /> + <ClCompile Include="..\Modules\_hacl\Hacl_Hash_SHA1.c" /> + <ClCompile Include="..\Modules\_hacl\Hacl_Hash_SHA2.c" /> + <ClCompile Include="..\Modules\_hacl\Hacl_Hash_SHA3.c" /> + <ClCompile Include="..\Modules\_heapqmodule.c" /> + <ClCompile Include="..\Modules\_json.c" /> + <ClCompile Include="..\Modules\_localemodule.c" /> + <ClCompile Include="..\Modules\_lsprof.c" /> + <ClCompile Include="..\Modules\_pickle.c" /> + <ClCompile Include="..\Modules\_randommodule.c" /> + <ClCompile Include="..\Modules\_sre\sre.c" /> + <ClInclude Include="..\Modules\_sre\sre.h" /> + <ClInclude Include="..\Modules\_sre\sre_constants.h" /> + <ClInclude Include="..\Modules\_sre\sre_lib.h" /> + <ClCompile Include="..\Modules\_stat.c" /> + <ClCompile Include="..\Modules\_struct.c" /> + <ClCompile Include="..\Modules\_weakref.c" /> + <ClCompile Include="..\Modules\arraymodule.c" /> + <ClCompile Include="..\Modules\atexitmodule.c" /> + <ClCompile Include="..\Modules\audioop.c" /> + <ClCompile Include="..\Modules\binascii.c"> + <PreprocessorDefinitions>USE_ZLIB_CRC32;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <ClCompile Include="..\Modules\cmathmodule.c" /> + <ClCompile Include="..\Modules\_datetimemodule.c" /> + <ClCompile Include="..\Modules\errnomodule.c" /> + <ClCompile Include="..\Modules\faulthandler.c" /> + <ClCompile Include="..\Modules\gcmodule.c" /> + <ClCompile Include="..\Modules\getbuildinfo.c" /> + <ClCompile Include="..\Modules\itertoolsmodule.c" /> + <ClCompile Include="..\Modules\main.c" /> + <ClCompile Include="..\Modules\mathmodule.c" /> + <ClCompile Include="..\Modules\md5module.c" /> + <ClCompile Include="..\Modules\mmapmodule.c" /> + <ClCompile Include="..\Modules\_opcode.c" /> + <ClCompile Include="..\Modules\_operator.c" /> + <ClCompile Include="..\Modules\posixmodule.c" /> + <ClCompile Include="..\Modules\rotatingtree.c" /> + <ClCompile Include="..\Modules\sha1module.c" /> + <ClCompile Include="..\Modules\sha2module.c" /> + <ClCompile Include="..\Modules\sha3module.c" /> + <ClCompile Include="..\Modules\signalmodule.c" /> + <ClCompile Include="..\Modules\_statisticsmodule.c" /> + <ClCompile Include="..\Modules\symtablemodule.c" /> + <ClCompile Include="..\Modules\_threadmodule.c" /> + <ClCompile Include="..\Modules\_tracemalloc.c" /> + <ClCompile Include="..\Modules\_typingmodule.c" /> + <ClCompile Include="..\Modules\timemodule.c" /> + <ClCompile Include="..\Modules\xxsubtype.c" /> + <ClCompile Include="..\Modules\_xxsubinterpretersmodule.c" /> + <ClCompile Include="..\Modules\_xxinterpchannelsmodule.c" /> + <ClCompile Include="..\Modules\_io\fileio.c" /> + <ClCompile Include="..\Modules\_io\bytesio.c" /> + <ClCompile Include="..\Modules\_io\stringio.c" /> + <ClCompile Include="..\Modules\_io\bufferedio.c" /> + <ClCompile Include="..\Modules\_io\iobase.c" /> + <ClCompile Include="..\Modules\_io\textio.c" /> + <ClCompile Include="..\Modules\_io\winconsoleio.c" /> + <ClCompile Include="..\Modules\_io\_iomodule.c" /> + <ClCompile Include="..\Modules\cjkcodecs\_codecs_cn.c" /> + <ClCompile Include="..\Modules\cjkcodecs\_codecs_hk.c" /> + <ClCompile Include="..\Modules\cjkcodecs\_codecs_iso2022.c" /> + <ClCompile Include="..\Modules\cjkcodecs\_codecs_jp.c" /> + <ClCompile Include="..\Modules\cjkcodecs\_codecs_kr.c" /> + <ClCompile Include="..\Modules\cjkcodecs\_codecs_tw.c" /> + <ClCompile Include="..\Modules\cjkcodecs\multibytecodec.c" /> + <ClCompile Include="..\Modules\_winapi.c" /> + <ClCompile Include="..\Objects\abstract.c" /> + <ClCompile Include="..\Objects\boolobject.c" /> + <ClCompile Include="..\Objects\bytearrayobject.c" /> + <ClCompile Include="..\Objects\bytes_methods.c" /> + <ClCompile Include="..\Objects\bytesobject.c" /> + <ClCompile Include="..\Objects\call.c" /> + <ClCompile Include="..\Objects\capsule.c" /> + <ClCompile Include="..\Objects\cellobject.c" /> + <ClCompile Include="..\Objects\classobject.c" /> + <ClCompile Include="..\Objects\codeobject.c" /> + <ClCompile Include="..\Objects\complexobject.c" /> + <ClCompile Include="..\Objects\descrobject.c" /> + <ClCompile Include="..\Objects\dictobject.c" /> + <ClCompile Include="..\Objects\enumobject.c" /> + <ClCompile Include="..\Objects\exceptions.c" /> + <ClCompile Include="..\Objects\fileobject.c" /> + <ClCompile Include="..\Objects\floatobject.c" /> + <ClCompile Include="..\Objects\frameobject.c" /> + <ClCompile Include="..\Objects\funcobject.c" /> + <ClCompile Include="..\Objects\genericaliasobject.c" /> + <ClCompile Include="..\Objects\genobject.c" /> + <ClCompile Include="..\Objects\interpreteridobject.c" /> + <ClCompile Include="..\Objects\iterobject.c" /> + <ClCompile Include="..\Objects\listobject.c" /> + <ClCompile Include="..\Objects\longobject.c" /> + <ClCompile Include="..\Objects\memoryobject.c" /> + <ClCompile Include="..\Objects\methodobject.c" /> + <ClCompile Include="..\Objects\moduleobject.c" /> + <ClCompile Include="..\Objects\namespaceobject.c" /> + <ClCompile Include="..\Objects\object.c" /> + <ClCompile Include="..\Objects\obmalloc.c" /> + <ClCompile Include="..\Objects\odictobject.c" /> + <ClCompile Include="..\Objects\picklebufobject.c" /> + <ClCompile Include="..\Objects\rangeobject.c" /> + <ClCompile Include="..\Objects\setobject.c" /> + <ClCompile Include="..\Objects\sliceobject.c" /> + <ClCompile Include="..\Objects\structseq.c" /> + <ClCompile Include="..\Objects\tupleobject.c" /> + <ClCompile Include="..\Objects\typeobject.c" /> + <ClCompile Include="..\Objects\typevarobject.c" /> + <ClCompile Include="..\Objects\unicodectype.c" /> + <ClCompile Include="..\Objects\unicodeobject.c" /> + <ClCompile Include="..\Objects\unionobject.c" /> + <ClCompile Include="..\Objects\weakrefobject.c" /> + <ClCompile Include="..\Parser\myreadline.c" /> + <ClCompile Include="..\Parser\tokenizer.c" /> + <ClCompile Include="..\Parser\token.c" /> + <ClCompile Include="..\Parser\pegen.c" /> + <ClCompile Include="..\Parser\pegen_errors.c" /> + <ClCompile Include="..\Parser\action_helpers.c" /> + <ClCompile Include="..\Parser\parser.c" /> + <ClCompile Include="..\Parser\string_parser.c" /> + <ClCompile Include="..\Parser\peg_api.c" /> + <ClCompile Include="..\PC\invalid_parameter_handler.c" /> + <ClCompile Include="..\PC\winreg.c" /> + <ClCompile Include="..\PC\config.c" /> + <ClCompile Include="..\PC\msvcrtmodule.c" /> + <ClCompile Include="..\Python\pyhash.c" /> + <ClCompile Include="..\Python\_warnings.c" /> + <ClCompile Include="..\Python\asdl.c" /> + <ClCompile Include="..\Python\assemble.c" /> + <ClCompile Include="..\Python\ast.c" /> + <ClCompile Include="..\Python\ast_opt.c" /> + <ClCompile Include="..\Python\ast_unparse.c" /> + <ClCompile Include="..\Python\bltinmodule.c" /> + <ClCompile Include="..\Python\bootstrap_hash.c" /> + <ClCompile Include="..\Python\ceval.c" /> + <ClCompile Include="..\Python\codecs.c" /> + <ClCompile Include="..\Python\compile.c" /> + <ClCompile Include="..\Python\context.c" /> + <ClCompile Include="..\Python\dynamic_annotations.c" /> + <ClCompile Include="..\Python\dynload_win.c" /> + <ClCompile Include="..\Python\errors.c" /> + <ClCompile Include="..\Python\fileutils.c" /> + <ClCompile Include="..\Python\flowgraph.c" /> + <ClCompile Include="..\Python\formatter_unicode.c" /> + <ClCompile Include="..\Python\frame.c" /> + <ClCompile Include="..\Python\frozen.c" /> + <ClCompile Include="..\Python\future.c" /> + <ClCompile Include="..\Python\getargs.c" /> + <ClCompile Include="..\Python\getcompiler.c" /> + <ClCompile Include="..\Python\getcopyright.c" /> + <ClCompile Include="..\Python\getopt.c" /> + <ClCompile Include="..\Python\getplatform.c" /> + <ClCompile Include="..\Python\getversion.c" /> + <ClCompile Include="..\Python\ceval_gil.c" /> + <ClCompile Include="..\Python\hamt.c" /> + <ClCompile Include="..\Python\hashtable.c" /> + <ClCompile Include="..\Python\import.c" /> + <ClCompile Include="..\Python\importdl.c" /> + <ClCompile Include="..\Python\initconfig.c" /> + <ClCompile Include="..\Python\intrinsics.c" /> + <ClCompile Include="..\Python\instrumentation.c" /> + <ClCompile Include="..\Python\legacy_tracing.c" /> + <ClCompile Include="..\Python\marshal.c" /> + <ClCompile Include="..\Python\modsupport.c" /> + <ClCompile Include="..\Python\mysnprintf.c" /> + <ClCompile Include="..\Python\mystrtoul.c" /> + <ClCompile Include="..\Python\pathconfig.c" /> + <ClCompile Include="..\Python\perf_trampoline.c" /> + <ClCompile Include="..\Python\preconfig.c" /> + <ClCompile Include="..\Python\pyarena.c" /> + <ClCompile Include="..\Python\pyctype.c" /> + <ClCompile Include="..\Python\pyfpe.c" /> + <ClCompile Include="..\Python\pylifecycle.c" /> + <ClCompile Include="..\Python\pymath.c" /> + <ClCompile Include="..\Python\pytime.c" /> + <ClCompile Include="..\Python\pystate.c" /> + <ClCompile Include="..\Python\pystrcmp.c" /> + <ClCompile Include="..\Python\pystrhex.c" /> + <ClCompile Include="..\Python\pystrtod.c" /> + <ClCompile Include="..\Python\dtoa.c" /> + <ClCompile Include="..\Python\Python-ast.c" /> + <ClCompile Include="..\Python\Python-tokenize.c" /> + <ClCompile Include="..\Python\pythonrun.c" /> + <ClCompile Include="..\Python\specialize.c" /> + <ClCompile Include="..\Python\suggestions.c" /> + <ClCompile Include="..\Python\structmember.c" /> + <ClCompile Include="..\Python\symtable.c" /> + <ClCompile Include="..\Python\sysmodule.c"> + <PreprocessorDefinitions>VPATH="$(PyVPath)";%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <ClCompile Include="..\Python\thread.c" /> + <ClCompile Include="..\Python\traceback.c" /> + <ClCompile Include="..\Python\tracemalloc.c" /> + </ItemGroup> + <ItemGroup> + <!-- BEGIN deepfreeze --> + <ClCompile Include="..\Python\deepfreeze\deepfreeze.c" /> + <!-- END deepfreeze --> + </ItemGroup> + <ItemGroup Condition="$(IncludeExternals)"> + <ClCompile Include="..\Modules\zlibmodule.c" /> + <ClCompile Include="$(zlibDir)\adler32.c" /> + <ClCompile Include="$(zlibDir)\compress.c" /> + <ClCompile Include="$(zlibDir)\crc32.c" /> + <ClCompile Include="$(zlibDir)\deflate.c"> + <DisableSpecificWarnings>4244</DisableSpecificWarnings> + </ClCompile> + <ClCompile Include="$(zlibDir)\infback.c" /> + <ClCompile Include="$(zlibDir)\inffast.c" /> + <ClCompile Include="$(zlibDir)\inflate.c" /> + <ClCompile Include="$(zlibDir)\inftrees.c" /> + <ClCompile Include="$(zlibDir)\trees.c" /> + <ClCompile Include="$(zlibDir)\uncompr.c" /> + <ClCompile Include="$(zlibDir)\zutil.c" /> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\PC\dl_nt.c" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_nt.rc" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + <Import Project="regen.targets" /> + </ImportGroup> + <Target Name="_TriggerRegen" BeforeTargets="PrepareForBuild" DependsOnTargets="Regen" /> + <Target Name="_GetBuildInfo" BeforeTargets="PrepareForBuild"> + <PropertyGroup> + <GIT Condition="$(GIT) == ''">git</GIT> + <_GIT>$(GIT)</_GIT> + <_GIT Condition="$(GIT.Contains(` `))">"$(GIT)"</_GIT> + </PropertyGroup> + <Message Text="Getting build info from $(_GIT)" Importance="high" /> + <MakeDir Directories="$(IntDir)" Condition="!Exists($(IntDir))" /> + <Exec Command="$(_GIT) name-rev --name-only HEAD > "$(IntDir)gitbranch.txt"" ContinueOnError="true" /> + <Exec Command="$(_GIT) rev-parse --short HEAD > "$(IntDir)gitversion.txt"" ContinueOnError="true" /> + <Exec Command="$(_GIT) describe --all --always --dirty > "$(IntDir)gittag.txt"" ContinueOnError="true" /> + <PropertyGroup> + <GitBranch Condition="Exists('$(IntDir)gitbranch.txt')">$([System.IO.File]::ReadAllText('$(IntDir)gitbranch.txt').Trim())</GitBranch> + <GitVersion Condition="Exists('$(IntDir)gitversion.txt')">$([System.IO.File]::ReadAllText('$(IntDir)gitversion.txt').Trim())</GitVersion> + <GitTag Condition="Exists('$(IntDir)gittag.txt')">$([System.IO.File]::ReadAllText('$(IntDir)gittag.txt').Trim())</GitTag> + </PropertyGroup> + <Message Text="Building $(GitTag):$(GitVersion) $(GitBranch)" Importance="high" /> + <ItemGroup> + <ClCompile Condition="%(Filename) == 'getbuildinfo'"> + <PreprocessorDefinitions>GITVERSION="$(GitVersion)";GITTAG="$(GitTag)";GITBRANCH="$(GitBranch)";%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + </ItemGroup> + </Target> + <Target Name="_WarnAboutToolset" BeforeTargets="PrepareForBuild" Condition="$(PlatformToolset) != 'v140' and $(PlatformToolset) != 'v141' and $(PlatformToolset) != 'v142' and $(PlatformToolset) != 'v143'"> + <Warning Text="Toolset $(PlatformToolset) is not used for official builds. Your build may have errors or incompatibilities." /> + </Target> + <Target Name="_WarnAboutZlib" BeforeTargets="PrepareForBuild" Condition="!$(IncludeExternals)"> + <Warning Text="Not including zlib is not a supported configuration." /> + </Target> + + <Target Name="_CopyVCRuntime" AfterTargets="Build" Inputs="@(VCRuntimeDLL)" Outputs="$(OutDir)%(Filename)%(Extension)" DependsOnTargets="FindVCRuntime"> + <!-- bpo-38597: When we switch to another VCRuntime DLL, include vcruntime140.dll as well --> + <Warning Text="A copy of vcruntime140.dll is also required" Condition="!$(VCToolsRedistVersion.StartsWith(`14.`))" /> + <Copy SourceFiles="%(VCRuntimeDLL.FullPath)" DestinationFolder="$(OutDir)" /> + </Target> + <Target Name="_CleanVCRuntime" AfterTargets="Clean"> + <Delete Files="@(VCRuntimeDLL->'$(OutDir)%(Filename)%(Extension)')" /> + </Target> + + <Target Name="_DeletePyBuildDirTxt" BeforeTargets="PrepareForBuild"> + <Delete Files="$(OutDir)pybuilddir.txt" /> + </Target> +</Project> diff --git a/PCbuild/pythoncore.vcxproj.filters b/PCbuild/pythoncore.vcxproj.filters index 206cf808..67a32f65 100644 --- a/PCbuild/pythoncore.vcxproj.filters +++ b/PCbuild/pythoncore.vcxproj.filters @@ -1,1298 +1,1403 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <Filter Include="Include"> - <UniqueIdentifier>{086b0afb-270c-4603-a02a-63d46f0b2b92}</UniqueIdentifier> - </Filter> - <Filter Include="Modules"> - <UniqueIdentifier>{8e81609f-13ca-4eae-9fdb-f8af20c710c7}</UniqueIdentifier> - </Filter> - <Filter Include="Modules\_io"> - <UniqueIdentifier>{8787c5bb-bab6-4586-a42e-4a27c7b3ffb6}</UniqueIdentifier> - </Filter> - <Filter Include="Modules\zlib"> - <UniqueIdentifier>{5d6d2d6c-9e61-4a1d-b0b2-5cc2f446d69e}</UniqueIdentifier> - </Filter> - <Filter Include="Modules\cjkcodecs"> - <UniqueIdentifier>{9f12c4b1-322e-431e-abf1-e02550f50032}</UniqueIdentifier> - </Filter> - <Filter Include="Objects"> - <UniqueIdentifier>{ab29a558-143d-4fe7-a039-b431fb429856}</UniqueIdentifier> - </Filter> - <Filter Include="Parser"> - <UniqueIdentifier>{97349fee-0abf-48b0-a8f5-771bf39b8aee}</UniqueIdentifier> - </Filter> - <Filter Include="PC"> - <UniqueIdentifier>{ea21fc98-de89-4746-a979-c5616964329a}</UniqueIdentifier> - </Filter> - <Filter Include="Python"> - <UniqueIdentifier>{f2696406-14bc-48bd-90c5-e93ab82a21ac}</UniqueIdentifier> - </Filter> - <Filter Include="Resource Files"> - <UniqueIdentifier>{c3e03a5c-56c7-45fd-8543-e5d2326b907d}</UniqueIdentifier> - </Filter> - <Filter Include="Include\internal"> - <UniqueIdentifier>{86ffb5eb-c423-43aa-b736-a8850d3277df}</UniqueIdentifier> - </Filter> - <Filter Include="Include\cpython"> - <UniqueIdentifier>{875bf4f2-ac42-46bd-b703-8371a824ec32}</UniqueIdentifier> - </Filter> - </ItemGroup> - <ItemGroup> - <ClInclude Include="..\Include\abstract.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\boolobject.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\bytearrayobject.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\bytesobject.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\ceval.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\code.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\codecs.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\compile.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\complexobject.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\datetime.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\descrobject.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\dictobject.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\dynamic_annotations.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\enumobject.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\errcode.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\fileobject.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\fileutils.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\floatobject.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\frameobject.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\import.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\intrcheck.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\iterobject.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\listobject.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\longobject.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\marshal.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\memoryobject.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\methodobject.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\modsupport.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\moduleobject.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\object.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\objimpl.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\osdefs.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\osmodule.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\patchlevel.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\py_curses.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\pybuffer.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\pycapsule.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\pyerrors.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\pyexpat.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\pylifecycle.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\pymath.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\pymacro.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\pymem.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\pyport.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\pystate.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\pystrcmp.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\pystrtod.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\Python.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\pythonrun.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\pythread.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\pytypedefs.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\rangeobject.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\setobject.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\sliceobject.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\structmember.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\structseq.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\symtable.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\sysmodule.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\token.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\traceback.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\tracemalloc.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\tupleobject.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\unicodeobject.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\weakrefobject.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Modules\_math.h"> - <Filter>Modules</Filter> - </ClInclude> - <ClInclude Include="..\Modules\rotatingtree.h"> - <Filter>Modules</Filter> - </ClInclude> - <ClInclude Include="..\Modules\_io\_iomodule.h"> - <Filter>Modules\_io</Filter> - </ClInclude> - <ClInclude Include="..\Modules\cjkcodecs\alg_jisx0201.h"> - <Filter>Modules\cjkcodecs</Filter> - </ClInclude> - <ClInclude Include="..\Modules\cjkcodecs\cjkcodecs.h"> - <Filter>Modules\cjkcodecs</Filter> - </ClInclude> - <ClInclude Include="..\Modules\cjkcodecs\emu_jisx0213_2000.h"> - <Filter>Modules\cjkcodecs</Filter> - </ClInclude> - <ClInclude Include="..\Modules\cjkcodecs\mappings_cn.h"> - <Filter>Modules\cjkcodecs</Filter> - </ClInclude> - <ClInclude Include="..\Modules\cjkcodecs\mappings_hk.h"> - <Filter>Modules\cjkcodecs</Filter> - </ClInclude> - <ClInclude Include="..\Modules\cjkcodecs\mappings_jisx0213_pair.h"> - <Filter>Modules\cjkcodecs</Filter> - </ClInclude> - <ClInclude Include="..\Modules\cjkcodecs\mappings_jp.h"> - <Filter>Modules\cjkcodecs</Filter> - </ClInclude> - <ClInclude Include="..\Modules\cjkcodecs\mappings_kr.h"> - <Filter>Modules\cjkcodecs</Filter> - </ClInclude> - <ClInclude Include="..\Modules\cjkcodecs\mappings_tw.h"> - <Filter>Modules\cjkcodecs</Filter> - </ClInclude> - <ClInclude Include="..\Modules\cjkcodecs\multibytecodec.h"> - <Filter>Modules\cjkcodecs</Filter> - </ClInclude> - <ClInclude Include="..\Objects\stringlib\count.h"> - <Filter>Objects</Filter> - </ClInclude> - <ClInclude Include="..\Objects\stringlib\fastsearch.h"> - <Filter>Objects</Filter> - </ClInclude> - <ClInclude Include="..\Objects\stringlib\find.h"> - <Filter>Objects</Filter> - </ClInclude> - <ClInclude Include="..\Objects\stringlib\partition.h"> - <Filter>Objects</Filter> - </ClInclude> - <ClInclude Include="..\Objects\stringlib\replace.h"> - <Filter>Objects</Filter> - </ClInclude> - <ClInclude Include="..\Objects\stringlib\split.h"> - <Filter>Objects</Filter> - </ClInclude> - <ClInclude Include="..\Objects\unicodetype_db.h"> - <Filter>Objects</Filter> - </ClInclude> - <ClInclude Include="..\Parser\tokenizer.h"> - <Filter>Parser</Filter> - </ClInclude> - <ClInclude Include="..\PC\errmap.h"> - <Filter>PC</Filter> - </ClInclude> - <ClInclude Include="..\PC\pyconfig.h"> - <Filter>PC</Filter> - </ClInclude> - <ClInclude Include="..\Python\importdl.h"> - <Filter>Python</Filter> - </ClInclude> - <ClInclude Include="..\Python\stdlib_module_names.h"> - <Filter>Python</Filter> - </ClInclude> - <ClInclude Include="..\Python\thread_nt.h"> - <Filter>Python</Filter> - </ClInclude> - <ClInclude Include="..\Python\condvar.h"> - <Filter>Python</Filter> - </ClInclude> - <ClInclude Include="..\Python\ceval_gil.h"> - <Filter>Python</Filter> - </ClInclude> - <ClInclude Include="..\Include\pyhash.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Modules\hashtable.h"> - <Filter>Modules</Filter> - </ClInclude> - <ClInclude Include="..\Parser\pegen.h"> - <Filter>Parser</Filter> - </ClInclude> - <ClInclude Include="..\Parser\string_parser.h"> - <Filter>Parser</Filter> - </ClInclude> - <ClInclude Include="..\Include\pyframe.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\cpython\abstract.h"> - <Filter>Include\cpython</Filter> - </ClInclude> - <ClInclude Include="..\Include\cpython\bytearrayobject.h"> - <Filter>Include\cpython</Filter> - </ClInclude> - <ClInclude Include="..\Include\cpython\bytesobject.h"> - <Filter>Include\cpython</Filter> - </ClInclude> - <ClInclude Include="..\Include\cpython\cellobject.h"> - <Filter>Include\cpython</Filter> - </ClInclude> - <ClInclude Include="..\Include\cpython\ceval.h"> - <Filter>Include\cpython</Filter> - </ClInclude> - <ClInclude Include="..\Include\cpython\classobject.h"> - <Filter>Include\cpython</Filter> - </ClInclude> - <ClInclude Include="..\Include\cpython\code.h"> - <Filter>Include\cpython</Filter> - </ClInclude> - <ClInclude Include="..\Include\cpython\compile.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\cpython\complexobject.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\cpython\context.h"> - <Filter>Include\cpython</Filter> - </ClInclude> - <ClInclude Include="..\Include\cpython\descrobject.h"> - <Filter>Include\cpython</Filter> - </ClInclude> - <ClInclude Include="..\Include\cpython\dictobject.h"> - <Filter>Include\cpython</Filter> - </ClInclude> - <ClInclude Include="..\Include\cpython\fileobject.h"> - <Filter>Include\cpython</Filter> - </ClInclude> - <ClInclude Include="..\Include\cpython\fileutils.h"> - <Filter>Include\cpython</Filter> - </ClInclude> - <ClInclude Include="..\Include\cpython\floatobject.h"> - <Filter>Include\cpython</Filter> - </ClInclude> - <ClInclude Include="..\Include\cpython\import.h"> - <Filter>Include\cpython</Filter> - </ClInclude> - <ClInclude Include="..\Include\cpython\listobject.h"> - <Filter>Include\cpython</Filter> - </ClInclude> - <ClInclude Include="..\Include\cpython\longintrepr.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\cpython\longobject.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\cpython\odictobject.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\cpython\unicodeobject.h"> - <Filter>Include\cpython</Filter> - </ClInclude> - <ClInclude Include="..\Include\cpython\warnings.h"> - <Filter>Include\cpython</Filter> - </ClInclude> - <ClInclude Include="..\Include\cpython\weakrefobject.h"> - <Filter>Include\cpython</Filter> - </ClInclude> - <ClInclude Include="..\Include\cpython\methodobject.h"> - <Filter>Include\cpython</Filter> - </ClInclude> - <ClInclude Include="..\Include\cpython\modsupport.h"> - <Filter>Include\cpython</Filter> - </ClInclude> - <ClInclude Include="..\Include\cpython\objimpl.h"> - <Filter>Include\cpython</Filter> - </ClInclude> - <ClInclude Include="..\Include\cpython\object.h"> - <Filter>Include\cpython</Filter> - </ClInclude> - <ClInclude Include="..\Include\cpython\parser_interface.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\cpython\picklebufobject.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\cpython\pyarena.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\cpython\pyctype.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\cpython\pydebug.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\cpython\pyerrors.h"> - <Filter>Include\cpython</Filter> - </ClInclude> - <ClInclude Include="..\Include\cpython\pyfpe.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\cpython\pymem.h"> - <Filter>Include\cpython</Filter> - </ClInclude> - <ClInclude Include="..\Include\cpython\pyframe.h"> - <Filter>Include\cpython</Filter> - </ClInclude> - <ClInclude Include="..\Include\cpython\pylifecycle.h"> - <Filter>Include\cpython</Filter> - </ClInclude> - <ClInclude Include="..\Include\cpython\pytime.h"> - <Filter>Include\cpython</Filter> - </ClInclude> - <ClInclude Include="..\Include\cpython\tupleobject.h"> - <Filter>Include\cpython</Filter> - </ClInclude> - <ClInclude Include="..\Include\cpython\traceback.h"> - <Filter>Include\cpython</Filter> - </ClInclude> - <ClInclude Include="..\Include\cpython\frameobject.h"> - <Filter>Include\cpython</Filter> - </ClInclude> - <ClInclude Include="..\Include\cpython\funcobject.h"> - <Filter>Include\cpython</Filter> - </ClInclude> - <ClInclude Include="..\Include\cpython\genobject.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\cpython\pythonrun.h"> - <Filter>Include\cpython</Filter> - </ClInclude> - <ClInclude Include="..\Include\cpython\pythread.h"> - <Filter>Include\cpython</Filter> - </ClInclude> - <ClInclude Include="..\Include\cpython\setobject.h"> - <Filter>Include\cpython</Filter> - </ClInclude> - <ClInclude Include="..\Include\cpython\sysmodule.h"> - <Filter>Include\cpython</Filter> - </ClInclude> - <ClInclude Include="..\Include\cpython\pystate.h"> - <Filter>Include\cpython</Filter> - </ClInclude> - <ClInclude Include="..\Include\cpython\initconfig.h"> - <Filter>Include\cpython</Filter> - </ClInclude> - <ClInclude Include="..\Include\internal\pycore_unicodeobject.h"> - <Filter>Include\internal</Filter> - </ClInclude> - <ClInclude Include="..\Include\internal\pycore_warnings.h"> - <Filter>Include\internal</Filter> - </ClInclude> - <ClInclude Include="..\Include\internal\pycore_abstract.h"> - <Filter>Include\internal</Filter> - </ClInclude> - <ClInclude Include="..\Include\internal\pycore_accu.h"> - <Filter>Include\internal</Filter> - </ClInclude> - <ClInclude Include="..\Include\internal\pycore_asdl.h"> - <Filter>Include\internal</Filter> - </ClInclude> - <ClInclude Include="..\Include\internal\pycore_ast.h"> - <Filter>Include\internal</Filter> - </ClInclude> - <ClInclude Include="..\Include\internal\pycore_ast_state.h"> - <Filter>Include\internal</Filter> - </ClInclude> - <ClInclude Include="..\Include\internal\pycore_atomic.h"> - <Filter>Include\internal</Filter> - </ClInclude> - <ClInclude Include="..\Include\internal\pycore_atomic_funcs.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\internal\pycore_bitutils.h"> - <Filter>Include\internal</Filter> - </ClInclude> - <ClInclude Include="..\Include\internal\pycore_bytes_methods.h"> - <Filter>Include\internal</Filter> - </ClInclude> - <ClInclude Include="..\Include\internal\pycore_bytesobject.h"> - <Filter>Include\internal</Filter> - </ClInclude> - <ClInclude Include="..\Include\internal\pycore_call.h"> - <Filter>Include\internal</Filter> - </ClInclude> - <ClInclude Include="..\Include\internal\pycore_ceval.h"> - <Filter>Include\internal</Filter> - </ClInclude> - <ClInclude Include="..\Include\internal\pycore_code.h"> - <Filter>Include\internal</Filter> - </ClInclude> - <ClInclude Include="..\Include\internal\pycore_compile.h"> - <Filter>Include\internal</Filter> - </ClInclude> - <ClInclude Include="..\Include\internal\pycore_condvar.h"> - <Filter>Include\internal</Filter> - </ClInclude> - <ClInclude Include="..\Include\internal\pycore_context.h"> - <Filter>Include\internal</Filter> - </ClInclude> - <ClInclude Include="..\Include\internal\pycore_dtoa.h"> - <Filter>Include\internal</Filter> - </ClInclude> - <ClInclude Include="..\Include\internal\pycore_exceptions.h"> - <Filter>Include\internal</Filter> - </ClInclude> - <ClInclude Include="..\Include\internal\pycore_fileutils.h"> - <Filter>Include\internal</Filter> - </ClInclude> - <ClInclude Include="..\Include\internal\pycore_floatobject.h"> - <Filter>Include\internal</Filter> - </ClInclude> - <ClInclude Include="..\Include\internal\pycore_format.h"> - <Filter>Include\internal</Filter> - </ClInclude> - <ClInclude Include="..\Include\internal\pycore_gc.h"> - <Filter>Include\internal</Filter> - </ClInclude> - <ClInclude Include="..\Include\internal\pycore_genobject.h"> - <Filter>Include\internal</Filter> - </ClInclude> - <ClInclude Include="..\Include\internal\pycore_getopt.h"> - <Filter>Include\internal</Filter> - </ClInclude> - <ClInclude Include="..\Include\internal\pycore_gil.h"> - <Filter>Include\internal</Filter> - </ClInclude> - <ClInclude Include="..\Include\internal\pycore_global_objects.h"> - <Filter>Include\internal</Filter> - </ClInclude> - <ClInclude Include="..\Include\internal\pycore_hamt.h"> - <Filter>Include\internal</Filter> - </ClInclude> - <ClInclude Include="..\Include\internal\pycore_hashtable.h"> - <Filter>Include\internal</Filter> - </ClInclude> - <ClInclude Include="..\Include\internal\pycore_import.h"> - <Filter>Include\internal</Filter> - </ClInclude> - <ClInclude Include="..\Include\internal\pycore_initconfig.h"> - <Filter>Include\internal</Filter> - </ClInclude> - <ClInclude Include="..\Include\internal\pycore_interp.h"> - <Filter>Include\internal</Filter> - </ClInclude> - <ClInclude Include="..\Include\internal\pycore_interpreteridobject.h"> - <Filter>Include\cpython</Filter> - </ClInclude> - <ClInclude Include="..\Include\internal\pycore_list.h"> - <Filter>Include\internal</Filter> - </ClInclude> - <ClInclude Include="..\Include\internal\pycore_long.h"> - <Filter>Include\internal</Filter> - </ClInclude> - <ClInclude Include="..\Include\internal\pycore_moduleobject.h"> - <Filter>Include\internal</Filter> - </ClInclude> - <ClInclude Include="..\Include\internal\pycore_namespace.h"> - <Filter>Include</Filter> - </ClInclude> - <ClInclude Include="..\Include\internal\pycore_object.h"> - <Filter>Include\internal</Filter> - </ClInclude> - <ClInclude Include="..\Include\internal\pycore_pathconfig.h"> - <Filter>Include\internal</Filter> - </ClInclude> - <ClInclude Include="..\Include\internal\pycore_pyarena.h"> - <Filter>Include\internal</Filter> - </ClInclude> - <ClInclude Include="..\Include\internal\pycore_pyerrors.h"> - <Filter>Include\internal</Filter> - </ClInclude> - <ClInclude Include="..\Include\internal\pycore_pyhash.h"> - <Filter>Include\internal</Filter> - </ClInclude> - <ClInclude Include="..\Include\internal\pycore_pylifecycle.h"> - <Filter>Include\internal</Filter> - </ClInclude> - <ClInclude Include="..\Include\internal\pycore_pymem.h"> - <Filter>Include\internal</Filter> - </ClInclude> - <ClInclude Include="..\Include\internal\pycore_pystate.h"> - <Filter>Include\internal</Filter> - </ClInclude> - <ClInclude Include="..\Include\internal\pycore_runtime.h"> - <Filter>Include\internal</Filter> - </ClInclude> - <ClInclude Include="..\Include\internal\pycore_runtime_init.h"> - <Filter>Include\internal</Filter> - </ClInclude> - <ClInclude Include="..\Include\internal\pycore_signal.h"> - <Filter>Include\internal</Filter> - </ClInclude> - <ClInclude Include="..\Include\internal\pycore_sliceobject.h"> - <Filter>Include\internal</Filter> - </ClInclude> - <ClInclude Include="..\Include\internal\pycore_strhex.h"> - <Filter>Include\internal</Filter> - </ClInclude> - <ClInclude Include="..\Include\internal\pycore_sysmodule.h"> - <Filter>Include\internal</Filter> - </ClInclude> - <ClInclude Include="..\Include\internal\pycore_symtable.h"> - <Filter>Include\internal</Filter> - </ClInclude> - <ClInclude Include="..\Include\internal\pycore_traceback.h"> - <Filter>Include\internal</Filter> - </ClInclude> - <ClInclude Include="..\Include\internal\pycore_tuple.h"> - <Filter>Include\internal</Filter> - </ClInclude> - <ClInclude Include="..\Include\internal\pycore_typeobject.h"> - <Filter>Include\internal</Filter> - </ClInclude> - <ClInclude Include="..\Include\internal\pycore_ucnhash.h"> - <Filter>Include\internal</Filter> - </ClInclude> - <ClInclude Include="..\Include\internal\pycore_unionobject.h"> - <Filter>Include\internal</Filter> - </ClInclude> - <ClInclude Include="$(zlibDir)\crc32.h"> - <Filter>Modules\zlib</Filter> - </ClInclude> - <ClInclude Include="$(zlibDir)\deflate.h"> - <Filter>Modules\zlib</Filter> - </ClInclude> - <ClInclude Include="$(zlibDir)\inffast.h"> - <Filter>Modules\zlib</Filter> - </ClInclude> - <ClInclude Include="$(zlibDir)\inffixed.h"> - <Filter>Modules\zlib</Filter> - </ClInclude> - <ClInclude Include="$(zlibDir)\inflate.h"> - <Filter>Modules\zlib</Filter> - </ClInclude> - <ClInclude Include="$(zlibDir)\inftrees.h"> - <Filter>Modules\zlib</Filter> - </ClInclude> - <ClInclude Include="$(zlibDir)\trees.h"> - <Filter>Modules\zlib</Filter> - </ClInclude> - <ClInclude Include="$(zlibDir)\zconf.h"> - <Filter>Modules\zlib</Filter> - </ClInclude> - <ClInclude Include="$(zlibDir)\zconf.in.h"> - <Filter>Modules\zlib</Filter> - </ClInclude> - <ClInclude Include="$(zlibDir)\zlib.h"> - <Filter>Modules\zlib</Filter> - </ClInclude> - <ClInclude Include="$(zlibDir)\zutil.h"> - <Filter>Modules\zlib</Filter> - </ClInclude> - <ClInclude Include="..\Include\internal\pycore_structseq.h"> - <Filter>Include\internal</Filter> - </ClInclude> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\Modules\_abc.c"> - <Filter>Modules</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_bisectmodule.c"> - <Filter>Modules</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_blake2\blake2module.c"> - <Filter>Modules</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_blake2\blake2b_impl.c"> - <Filter>Modules</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_blake2\blake2s_impl.c"> - <Filter>Modules</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_codecsmodule.c"> - <Filter>Modules</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_collectionsmodule.c"> - <Filter>Modules</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_csv.c"> - <Filter>Modules</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_functoolsmodule.c"> - <Filter>Modules</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_heapqmodule.c"> - <Filter>Modules</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_json.c"> - <Filter>Modules</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_localemodule.c"> - <Filter>Modules</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_lsprof.c"> - <Filter>Modules</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_pickle.c"> - <Filter>Modules</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_randommodule.c"> - <Filter>Modules</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_sha3\sha3module.c"> - <Filter>Modules</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_sre\sre.c"> - <Filter>Modules</Filter> - </ClCompile> - <ClInclude Include="..\Modules\_sre\sre.h"> - <Filter>Modules</Filter> - </ClInclude> - <ClInclude Include="..\Modules\_sre\sre_constants.h"> - <Filter>Modules</Filter> - </ClInclude> - <ClInclude Include="..\Modules\_sre\sre_lib.h"> - <Filter>Modules</Filter> - </ClInclude> - <ClCompile Include="..\Modules\_statisticsmodule.c"> - <Filter>Modules</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_typingmodule.c"> - <Filter>Modules</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_struct.c"> - <Filter>Modules</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_weakref.c"> - <Filter>Modules</Filter> - </ClCompile> - <ClCompile Include="..\Modules\arraymodule.c"> - <Filter>Modules</Filter> - </ClCompile> - <ClCompile Include="..\Modules\atexitmodule.c"> - <Filter>Modules</Filter> - </ClCompile> - <ClCompile Include="..\Modules\audioop.c"> - <Filter>Modules</Filter> - </ClCompile> - <ClCompile Include="..\Modules\binascii.c"> - <Filter>Modules</Filter> - </ClCompile> - <ClCompile Include="..\Modules\cmathmodule.c"> - <Filter>Modules</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_datetimemodule.c"> - <Filter>Modules</Filter> - </ClCompile> - <ClCompile Include="..\Modules\errnomodule.c"> - <Filter>Modules</Filter> - </ClCompile> - <ClCompile Include="..\Modules\faulthandler.c"> - <Filter>Modules</Filter> - </ClCompile> - <ClCompile Include="..\Modules\gcmodule.c"> - <Filter>Modules</Filter> - </ClCompile> - <ClCompile Include="..\Modules\itertoolsmodule.c"> - <Filter>Modules</Filter> - </ClCompile> - <ClCompile Include="..\Modules\main.c"> - <Filter>Modules</Filter> - </ClCompile> - <ClCompile Include="..\Modules\mathmodule.c"> - <Filter>Modules</Filter> - </ClCompile> - <ClCompile Include="..\Modules\md5module.c"> - <Filter>Modules</Filter> - </ClCompile> - <ClCompile Include="..\Modules\mmapmodule.c"> - <Filter>Modules</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_operator.c"> - <Filter>Modules</Filter> - </ClCompile> - <ClCompile Include="..\Modules\posixmodule.c"> - <Filter>Modules</Filter> - </ClCompile> - <ClCompile Include="..\Modules\rotatingtree.c"> - <Filter>Modules</Filter> - </ClCompile> - <ClCompile Include="..\Modules\sha1module.c"> - <Filter>Modules</Filter> - </ClCompile> - <ClCompile Include="..\Modules\sha256module.c"> - <Filter>Modules</Filter> - </ClCompile> - <ClCompile Include="..\Modules\sha512module.c"> - <Filter>Modules</Filter> - </ClCompile> - <ClCompile Include="..\Modules\signalmodule.c"> - <Filter>Modules</Filter> - </ClCompile> - <ClCompile Include="..\Modules\symtablemodule.c"> - <Filter>Modules</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_threadmodule.c"> - <Filter>Modules</Filter> - </ClCompile> - <ClCompile Include="..\Modules\timemodule.c"> - <Filter>Modules</Filter> - </ClCompile> - <ClCompile Include="..\Modules\xxsubtype.c"> - <Filter>Modules</Filter> - </ClCompile> - <ClCompile Include="..\Modules\zlibmodule.c"> - <Filter>Modules</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_io\fileio.c"> - <Filter>Modules\_io</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_io\bytesio.c"> - <Filter>Modules\_io</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_io\stringio.c"> - <Filter>Modules\_io</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_io\bufferedio.c"> - <Filter>Modules\_io</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_io\iobase.c"> - <Filter>Modules\_io</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_io\textio.c"> - <Filter>Modules\_io</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_io\winconsoleio.c"> - <Filter>Modules\_io</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_io\_iomodule.c"> - <Filter>Modules\_io</Filter> - </ClCompile> - <ClCompile Include="..\Modules\cjkcodecs\_codecs_cn.c"> - <Filter>Modules\cjkcodecs</Filter> - </ClCompile> - <ClCompile Include="..\Modules\cjkcodecs\_codecs_hk.c"> - <Filter>Modules\cjkcodecs</Filter> - </ClCompile> - <ClCompile Include="..\Modules\cjkcodecs\_codecs_iso2022.c"> - <Filter>Modules\cjkcodecs</Filter> - </ClCompile> - <ClCompile Include="..\Modules\cjkcodecs\_codecs_jp.c"> - <Filter>Modules\cjkcodecs</Filter> - </ClCompile> - <ClCompile Include="..\Modules\cjkcodecs\_codecs_kr.c"> - <Filter>Modules\cjkcodecs</Filter> - </ClCompile> - <ClCompile Include="..\Modules\cjkcodecs\_codecs_tw.c"> - <Filter>Modules\cjkcodecs</Filter> - </ClCompile> - <ClCompile Include="..\Modules\cjkcodecs\multibytecodec.c"> - <Filter>Modules\cjkcodecs</Filter> - </ClCompile> - <ClCompile Include="..\Objects\abstract.c"> - <Filter>Objects</Filter> - </ClCompile> - <ClCompile Include="..\Objects\accu.c"> - <Filter>Objects</Filter> - </ClCompile> - <ClCompile Include="..\Objects\boolobject.c"> - <Filter>Objects</Filter> - </ClCompile> - <ClCompile Include="..\Objects\bytes_methods.c"> - <Filter>Objects</Filter> - </ClCompile> - <ClCompile Include="..\Objects\bytearrayobject.c"> - <Filter>Objects</Filter> - </ClCompile> - <ClCompile Include="..\Objects\bytesobject.c"> - <Filter>Objects</Filter> - </ClCompile> - <ClCompile Include="..\Objects\call.c"> - <Filter>Objects</Filter> - </ClCompile> - <ClCompile Include="..\Objects\capsule.c"> - <Filter>Objects</Filter> - </ClCompile> - <ClCompile Include="..\Objects\cellobject.c"> - <Filter>Objects</Filter> - </ClCompile> - <ClCompile Include="..\Objects\classobject.c"> - <Filter>Objects</Filter> - </ClCompile> - <ClCompile Include="..\Objects\codeobject.c"> - <Filter>Objects</Filter> - </ClCompile> - <ClCompile Include="..\Objects\complexobject.c"> - <Filter>Objects</Filter> - </ClCompile> - <ClCompile Include="..\Objects\descrobject.c"> - <Filter>Objects</Filter> - </ClCompile> - <ClCompile Include="..\Objects\dictobject.c"> - <Filter>Objects</Filter> - </ClCompile> - <ClCompile Include="..\Objects\enumobject.c"> - <Filter>Objects</Filter> - </ClCompile> - <ClCompile Include="..\Objects\exceptions.c"> - <Filter>Objects</Filter> - </ClCompile> - <ClCompile Include="..\Objects\fileobject.c"> - <Filter>Objects</Filter> - </ClCompile> - <ClCompile Include="..\Objects\floatobject.c"> - <Filter>Objects</Filter> - </ClCompile> - <ClCompile Include="..\Objects\frameobject.c"> - <Filter>Objects</Filter> - </ClCompile> - <ClCompile Include="..\Objects\funcobject.c"> - <Filter>Objects</Filter> - </ClCompile> - <ClCompile Include="..\Objects\genobject.c"> - <Filter>Objects</Filter> - </ClCompile> - <ClCompile Include="..\Objects\iterobject.c"> - <Filter>Objects</Filter> - </ClCompile> - <ClCompile Include="..\Objects\listobject.c"> - <Filter>Objects</Filter> - </ClCompile> - <ClCompile Include="..\Objects\longobject.c"> - <Filter>Objects</Filter> - </ClCompile> - <ClCompile Include="..\Objects\memoryobject.c"> - <Filter>Objects</Filter> - </ClCompile> - <ClCompile Include="..\Objects\methodobject.c"> - <Filter>Objects</Filter> - </ClCompile> - <ClCompile Include="..\Objects\moduleobject.c"> - <Filter>Objects</Filter> - </ClCompile> - <ClCompile Include="..\Objects\object.c"> - <Filter>Objects</Filter> - </ClCompile> - <ClCompile Include="..\Objects\obmalloc.c"> - <Filter>Objects</Filter> - </ClCompile> - <ClCompile Include="..\Objects\picklebufobject.c"> - <Filter>Objects</Filter> - </ClCompile> - <ClCompile Include="..\Objects\rangeobject.c"> - <Filter>Objects</Filter> - </ClCompile> - <ClCompile Include="..\Objects\setobject.c"> - <Filter>Objects</Filter> - </ClCompile> - <ClCompile Include="..\Objects\sliceobject.c"> - <Filter>Objects</Filter> - </ClCompile> - <ClCompile Include="..\Objects\structseq.c"> - <Filter>Objects</Filter> - </ClCompile> - <ClCompile Include="..\Objects\tupleobject.c"> - <Filter>Objects</Filter> - </ClCompile> - <ClCompile Include="..\Objects\typeobject.c"> - <Filter>Objects</Filter> - </ClCompile> - <ClCompile Include="..\Objects\unicodectype.c"> - <Filter>Objects</Filter> - </ClCompile> - <ClCompile Include="..\Objects\unicodeobject.c"> - <Filter>Objects</Filter> - </ClCompile> - <ClCompile Include="..\Objects\weakrefobject.c"> - <Filter>Objects</Filter> - </ClCompile> - <ClCompile Include="..\Parser\myreadline.c"> - <Filter>Parser</Filter> - </ClCompile> - <ClCompile Include="..\Parser\tokenizer.c"> - <Filter>Parser</Filter> - </ClCompile> - <ClCompile Include="..\Parser\token.c"> - <Filter>Parser</Filter> - </ClCompile> - <ClCompile Include="..\PC\winreg.c"> - <Filter>PC</Filter> - </ClCompile> - <ClCompile Include="..\PC\config.c"> - <Filter>PC</Filter> - </ClCompile> - <ClCompile Include="..\PC\dl_nt.c"> - <Filter>PC</Filter> - </ClCompile> - <ClCompile Include="..\PC\msvcrtmodule.c"> - <Filter>PC</Filter> - </ClCompile> - <ClCompile Include="..\Python\_warnings.c"> - <Filter>Python</Filter> - </ClCompile> - <ClCompile Include="..\Python\asdl.c"> - <Filter>Python</Filter> - </ClCompile> - <ClCompile Include="..\Python\ast.c"> - <Filter>Python</Filter> - </ClCompile> - <ClCompile Include="..\Python\ast_opt.c"> - <Filter>Python</Filter> - </ClCompile> - <ClCompile Include="..\Python\ast_unparse.c"> - <Filter>Python</Filter> - </ClCompile> - <ClCompile Include="..\Python\bltinmodule.c"> - <Filter>Python</Filter> - </ClCompile> - <ClCompile Include="..\Python\ceval.c"> - <Filter>Python</Filter> - </ClCompile> - <ClCompile Include="..\Python\codecs.c"> - <Filter>Python</Filter> - </ClCompile> - <ClCompile Include="..\Python\compile.c"> - <Filter>Python</Filter> - </ClCompile> - <ClCompile Include="..\Python\dynamic_annotations.c"> - <Filter>Python</Filter> - </ClCompile> - <ClCompile Include="..\Python\dynload_win.c"> - <Filter>Python</Filter> - </ClCompile> - <ClCompile Include="..\Python\errors.c"> - <Filter>Python</Filter> - </ClCompile> - <ClCompile Include="..\Python\fileutils.c"> - <Filter>Python</Filter> - </ClCompile> - <ClCompile Include="..\Python\formatter_unicode.c"> - <Filter>Python</Filter> - </ClCompile> - <ClCompile Include="..\Python\frozen.c"> - <Filter>Python</Filter> - </ClCompile> - <ClCompile Include="..\Python\future.c"> - <Filter>Python</Filter> - </ClCompile> - <ClCompile Include="..\Python\getargs.c"> - <Filter>Python</Filter> - </ClCompile> - <ClCompile Include="..\Python\getcompiler.c"> - <Filter>Python</Filter> - </ClCompile> - <ClCompile Include="..\Python\getcopyright.c"> - <Filter>Python</Filter> - </ClCompile> - <ClCompile Include="..\Python\getopt.c"> - <Filter>Python</Filter> - </ClCompile> - <ClCompile Include="..\Python\getplatform.c"> - <Filter>Python</Filter> - </ClCompile> - <ClCompile Include="..\Python\getversion.c"> - <Filter>Python</Filter> - </ClCompile> - <ClCompile Include="..\Python\hashtable.c"> - <Filter>Modules</Filter> - </ClCompile> - <ClCompile Include="..\Python\import.c"> - <Filter>Python</Filter> - </ClCompile> - <ClCompile Include="..\Python\importdl.c"> - <Filter>Python</Filter> - </ClCompile> - <ClCompile Include="..\Python\initconfig.c"> - <Filter>Python</Filter> - </ClCompile> - <ClCompile Include="..\Python\marshal.c"> - <Filter>Python</Filter> - </ClCompile> - <ClCompile Include="..\Python\modsupport.c"> - <Filter>Python</Filter> - </ClCompile> - <ClCompile Include="..\Python\mysnprintf.c"> - <Filter>Python</Filter> - </ClCompile> - <ClCompile Include="..\Python\mystrtoul.c"> - <Filter>Python</Filter> - </ClCompile> - <ClCompile Include="..\Python\pathconfig.c"> - <Filter>Python</Filter> - </ClCompile> - <ClCompile Include="..\Python\preconfig.c"> - <Filter>Python</Filter> - </ClCompile> - <ClCompile Include="..\Python\pyarena.c"> - <Filter>Python</Filter> - </ClCompile> - <ClCompile Include="..\Python\pyctype.c"> - <Filter>Python</Filter> - </ClCompile> - <ClCompile Include="..\Python\pyfpe.c"> - <Filter>Python</Filter> - </ClCompile> - <ClCompile Include="..\Python\pylifecycle.c"> - <Filter>Python</Filter> - </ClCompile> - <ClCompile Include="..\Python\pymath.c"> - <Filter>Python</Filter> - </ClCompile> - <ClCompile Include="..\Python\pytime.c"> - <Filter>Python</Filter> - </ClCompile> - <ClCompile Include="..\Python\pystate.c"> - <Filter>Python</Filter> - </ClCompile> - <ClCompile Include="..\Python\pystrcmp.c"> - <Filter>Python</Filter> - </ClCompile> - <ClCompile Include="..\Python\pystrhex.c"> - <Filter>Python</Filter> - </ClCompile> - <ClCompile Include="..\Python\pystrtod.c"> - <Filter>Python</Filter> - </ClCompile> - <ClCompile Include="..\Python\dtoa.c"> - <Filter>Python</Filter> - </ClCompile> - <ClCompile Include="..\Python\Python-ast.c"> - <Filter>Python</Filter> - </ClCompile> - <ClCompile Include="..\Python\pythonrun.c"> - <Filter>Python</Filter> - </ClCompile> - <ClCompile Include="..\Python\specialize.c"> - <Filter>Python</Filter> - </ClCompile> - <ClCompile Include="..\Python\structmember.c"> - <Filter>Python</Filter> - </ClCompile> - <ClCompile Include="..\Python\symtable.c"> - <Filter>Python</Filter> - </ClCompile> - <ClCompile Include="..\Python\sysmodule.c"> - <Filter>Python</Filter> - </ClCompile> - <ClCompile Include="..\Python\thread.c"> - <Filter>Python</Filter> - </ClCompile> - <ClCompile Include="..\Python\traceback.c"> - <Filter>Python</Filter> - </ClCompile> - <ClCompile Include="..\Python\bootstrap_hash.c"> - <Filter>Python</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_winapi.c"> - <Filter>PC</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_stat.c"> - <Filter>Modules</Filter> - </ClCompile> - <ClCompile Include="..\Python\pyhash.c"> - <Filter>Python</Filter> - </ClCompile> - <ClCompile Include="..\Objects\namespaceobject.c"> - <Filter>Objects</Filter> - </ClCompile> - <ClCompile Include="..\Objects\interpreteridobject.c"> - <Filter>Objects</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_opcode.c"> - <Filter>Modules</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_tracemalloc.c"> - <Filter>Modules</Filter> - </ClCompile> - <ClCompile Include="..\PC\invalid_parameter_handler.c"> - <Filter>PC</Filter> - </ClCompile> - <ClCompile Include="..\Objects\odictobject.c"> - <Filter>Objects</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_contextvarsmodule.c"> - <Filter>Modules</Filter> - </ClCompile> - <ClCompile Include="$(zlibDir)\adler32.c"> - <Filter>Modules\zlib</Filter> - </ClCompile> - <ClCompile Include="$(zlibDir)\compress.c"> - <Filter>Modules\zlib</Filter> - </ClCompile> - <ClCompile Include="$(zlibDir)\crc32.c"> - <Filter>Modules\zlib</Filter> - </ClCompile> - <ClCompile Include="$(zlibDir)\deflate.c"> - <Filter>Modules\zlib</Filter> - </ClCompile> - <ClCompile Include="$(zlibDir)\infback.c"> - <Filter>Modules\zlib</Filter> - </ClCompile> - <ClCompile Include="$(zlibDir)\inffast.c"> - <Filter>Modules\zlib</Filter> - </ClCompile> - <ClCompile Include="$(zlibDir)\inflate.c"> - <Filter>Modules\zlib</Filter> - </ClCompile> - <ClCompile Include="$(zlibDir)\inftrees.c"> - <Filter>Modules\zlib</Filter> - </ClCompile> - <ClCompile Include="$(zlibDir)\trees.c"> - <Filter>Modules\zlib</Filter> - </ClCompile> - <ClCompile Include="$(zlibDir)\uncompr.c"> - <Filter>Modules\zlib</Filter> - </ClCompile> - <ClCompile Include="$(zlibDir)\zutil.c"> - <Filter>Modules\zlib</Filter> - </ClCompile> - <ClCompile Include="..\Python\hamt.c"> - <Filter>Python</Filter> - </ClCompile> - <ClCompile Include="..\Parser\parser.c"> - <Filter>Parser</Filter> - </ClCompile> - <ClCompile Include="..\Parser\pegen.c"> - <Filter>Parser</Filter> - </ClCompile> - <ClCompile Include="..\Parser\pegen_errors.c"> - <Filter>Parser</Filter> - </ClCompile> - <ClCompile Include="..\Parser\action_helpers.c"> - <Filter>Parser</Filter> - </ClCompile> - <ClCompile Include="..\Parser\peg_api.c"> - <Filter>Parser</Filter> - </ClCompile> - <ClCompile Include="..\Modules\_xxsubinterpretersmodule.c"> - <Filter>Modules</Filter> - </ClCompile> - <ClCompile Include="..\Parser\string_parser.c"> - <Filter>Parser</Filter> - </ClCompile> - <ClCompile Include="..\Python\context.c"> - <Filter>Python</Filter> - </ClCompile> - <ClCompile Include="..\Objects\genericaliasobject.c"> - <Filter>Objects</Filter> - </ClCompile> - <ClCompile Include="..\Objects\unionobject.c"> - <Filter>Objects</Filter> - </ClCompile> - <ClCompile Include="..\Python\frame.c"> - <Filter>Python</Filter> - </ClCompile> - <ClCompile Include="..\Modules\getpath.c"> - <Filter>Modules</Filter> - </ClCompile> - <ClCompile Include="..\Python\suggestions.c"> - <Filter>Python</Filter> - </ClCompile> - <ClCompile Include="..\Python\Python-tokenize.c"> - <Filter>Python</Filter> - </ClCompile> - <ClCompile Include="..\Modules\getbuildinfo.c"> - <Filter>Modules</Filter> - </ClCompile> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\python_nt.rc"> - <Filter>Resource Files</Filter> - </ResourceCompile> - </ItemGroup> -</Project> +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Include"> + <UniqueIdentifier>{086b0afb-270c-4603-a02a-63d46f0b2b92}</UniqueIdentifier> + </Filter> + <Filter Include="Modules"> + <UniqueIdentifier>{8e81609f-13ca-4eae-9fdb-f8af20c710c7}</UniqueIdentifier> + </Filter> + <Filter Include="Modules\_io"> + <UniqueIdentifier>{8787c5bb-bab6-4586-a42e-4a27c7b3ffb6}</UniqueIdentifier> + </Filter> + <Filter Include="Modules\zlib"> + <UniqueIdentifier>{5d6d2d6c-9e61-4a1d-b0b2-5cc2f446d69e}</UniqueIdentifier> + </Filter> + <Filter Include="Modules\cjkcodecs"> + <UniqueIdentifier>{9f12c4b1-322e-431e-abf1-e02550f50032}</UniqueIdentifier> + </Filter> + <Filter Include="Objects"> + <UniqueIdentifier>{ab29a558-143d-4fe7-a039-b431fb429856}</UniqueIdentifier> + </Filter> + <Filter Include="Parser"> + <UniqueIdentifier>{97349fee-0abf-48b0-a8f5-771bf39b8aee}</UniqueIdentifier> + </Filter> + <Filter Include="PC"> + <UniqueIdentifier>{ea21fc98-de89-4746-a979-c5616964329a}</UniqueIdentifier> + </Filter> + <Filter Include="Python"> + <UniqueIdentifier>{f2696406-14bc-48bd-90c5-e93ab82a21ac}</UniqueIdentifier> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{c3e03a5c-56c7-45fd-8543-e5d2326b907d}</UniqueIdentifier> + </Filter> + <Filter Include="Include\internal"> + <UniqueIdentifier>{86ffb5eb-c423-43aa-b736-a8850d3277df}</UniqueIdentifier> + </Filter> + <Filter Include="Include\cpython"> + <UniqueIdentifier>{875bf4f2-ac42-46bd-b703-8371a824ec32}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\Include\abstract.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\boolobject.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\bytearrayobject.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\bytesobject.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\ceval.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\code.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\codecs.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\compile.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\complexobject.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\datetime.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\descrobject.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\dictobject.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\dynamic_annotations.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\enumobject.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\errcode.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\fileobject.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\fileutils.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\floatobject.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\frameobject.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\import.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\intrcheck.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\iterobject.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\listobject.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\longobject.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\marshal.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\memoryobject.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\methodobject.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\modsupport.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\moduleobject.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\object.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\objimpl.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\osdefs.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\osmodule.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\patchlevel.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\py_curses.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\pybuffer.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\pycapsule.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\pyerrors.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\pyexpat.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\pylifecycle.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\pymath.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\pymacro.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\pymem.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\pyport.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\pystate.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\pystats.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\pystrcmp.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\pystrtod.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\Python.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\pythonrun.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\pythread.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\pytypedefs.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\rangeobject.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\setobject.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\sliceobject.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\structmember.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\structseq.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\symtable.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\sysmodule.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\traceback.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\tracemalloc.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\tupleobject.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\unicodeobject.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\weakrefobject.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Modules\_math.h"> + <Filter>Modules</Filter> + </ClInclude> + <ClInclude Include="..\Modules\rotatingtree.h"> + <Filter>Modules</Filter> + </ClInclude> + <ClInclude Include="..\Modules\_io\_iomodule.h"> + <Filter>Modules\_io</Filter> + </ClInclude> + <ClInclude Include="..\Modules\cjkcodecs\alg_jisx0201.h"> + <Filter>Modules\cjkcodecs</Filter> + </ClInclude> + <ClInclude Include="..\Modules\cjkcodecs\cjkcodecs.h"> + <Filter>Modules\cjkcodecs</Filter> + </ClInclude> + <ClInclude Include="..\Modules\cjkcodecs\emu_jisx0213_2000.h"> + <Filter>Modules\cjkcodecs</Filter> + </ClInclude> + <ClInclude Include="..\Modules\cjkcodecs\mappings_cn.h"> + <Filter>Modules\cjkcodecs</Filter> + </ClInclude> + <ClInclude Include="..\Modules\cjkcodecs\mappings_hk.h"> + <Filter>Modules\cjkcodecs</Filter> + </ClInclude> + <ClInclude Include="..\Modules\cjkcodecs\mappings_jisx0213_pair.h"> + <Filter>Modules\cjkcodecs</Filter> + </ClInclude> + <ClInclude Include="..\Modules\cjkcodecs\mappings_jp.h"> + <Filter>Modules\cjkcodecs</Filter> + </ClInclude> + <ClInclude Include="..\Modules\cjkcodecs\mappings_kr.h"> + <Filter>Modules\cjkcodecs</Filter> + </ClInclude> + <ClInclude Include="..\Modules\cjkcodecs\mappings_tw.h"> + <Filter>Modules\cjkcodecs</Filter> + </ClInclude> + <ClInclude Include="..\Modules\cjkcodecs\multibytecodec.h"> + <Filter>Modules\cjkcodecs</Filter> + </ClInclude> + <ClInclude Include="..\Objects\stringlib\count.h"> + <Filter>Objects</Filter> + </ClInclude> + <ClInclude Include="..\Objects\stringlib\fastsearch.h"> + <Filter>Objects</Filter> + </ClInclude> + <ClInclude Include="..\Objects\stringlib\find.h"> + <Filter>Objects</Filter> + </ClInclude> + <ClInclude Include="..\Objects\stringlib\partition.h"> + <Filter>Objects</Filter> + </ClInclude> + <ClInclude Include="..\Objects\stringlib\replace.h"> + <Filter>Objects</Filter> + </ClInclude> + <ClInclude Include="..\Objects\stringlib\split.h"> + <Filter>Objects</Filter> + </ClInclude> + <ClInclude Include="..\Objects\unicodetype_db.h"> + <Filter>Objects</Filter> + </ClInclude> + <ClInclude Include="..\Parser\tokenizer.h"> + <Filter>Parser</Filter> + </ClInclude> + <ClInclude Include="..\PC\errmap.h"> + <Filter>PC</Filter> + </ClInclude> + <ClInclude Include="..\PC\pyconfig.h"> + <Filter>PC</Filter> + </ClInclude> + <ClInclude Include="..\Python\importdl.h"> + <Filter>Python</Filter> + </ClInclude> + <ClInclude Include="..\Python\stdlib_module_names.h"> + <Filter>Python</Filter> + </ClInclude> + <ClInclude Include="..\Python\thread_nt.h"> + <Filter>Python</Filter> + </ClInclude> + <ClInclude Include="..\Python\condvar.h"> + <Filter>Python</Filter> + </ClInclude> + <ClInclude Include="..\Include\pyhash.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\interpreteridobject.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Modules\hashtable.h"> + <Filter>Modules</Filter> + </ClInclude> + <ClInclude Include="..\Parser\pegen.h"> + <Filter>Parser</Filter> + </ClInclude> + <ClInclude Include="..\Parser\string_parser.h"> + <Filter>Parser</Filter> + </ClInclude> + <ClInclude Include="..\Include\pyframe.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\cpython\abstract.h"> + <Filter>Include\cpython</Filter> + </ClInclude> + <ClInclude Include="..\Include\cpython\bytearrayobject.h"> + <Filter>Include\cpython</Filter> + </ClInclude> + <ClInclude Include="..\Include\cpython\bytesobject.h"> + <Filter>Include\cpython</Filter> + </ClInclude> + <ClInclude Include="..\Include\cpython\cellobject.h"> + <Filter>Include\cpython</Filter> + </ClInclude> + <ClInclude Include="..\Include\cpython\ceval.h"> + <Filter>Include\cpython</Filter> + </ClInclude> + <ClInclude Include="..\Include\cpython\classobject.h"> + <Filter>Include\cpython</Filter> + </ClInclude> + <ClInclude Include="..\Include\cpython\code.h"> + <Filter>Include\cpython</Filter> + </ClInclude> + <ClInclude Include="..\Include\cpython\compile.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\cpython\complexobject.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\cpython\context.h"> + <Filter>Include\cpython</Filter> + </ClInclude> + <ClInclude Include="..\Include\cpython\descrobject.h"> + <Filter>Include\cpython</Filter> + </ClInclude> + <ClInclude Include="..\Include\cpython\dictobject.h"> + <Filter>Include\cpython</Filter> + </ClInclude> + <ClInclude Include="..\Include\cpython\fileobject.h"> + <Filter>Include\cpython</Filter> + </ClInclude> + <ClInclude Include="..\Include\cpython\fileutils.h"> + <Filter>Include\cpython</Filter> + </ClInclude> + <ClInclude Include="..\Include\cpython\floatobject.h"> + <Filter>Include\cpython</Filter> + </ClInclude> + <ClInclude Include="..\Include\cpython\import.h"> + <Filter>Include\cpython</Filter> + </ClInclude> + <ClInclude Include="..\Include\cpython\listobject.h"> + <Filter>Include\cpython</Filter> + </ClInclude> + <ClInclude Include="..\Include\cpython\longintrepr.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\cpython\longobject.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\cpython\memoryobject.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\cpython\odictobject.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\cpython\unicodeobject.h"> + <Filter>Include\cpython</Filter> + </ClInclude> + <ClInclude Include="..\Include\cpython\warnings.h"> + <Filter>Include\cpython</Filter> + </ClInclude> + <ClInclude Include="..\Include\cpython\weakrefobject.h"> + <Filter>Include\cpython</Filter> + </ClInclude> + <ClInclude Include="..\Include\cpython\methodobject.h"> + <Filter>Include\cpython</Filter> + </ClInclude> + <ClInclude Include="..\Include\cpython\modsupport.h"> + <Filter>Include\cpython</Filter> + </ClInclude> + <ClInclude Include="..\Include\cpython\objimpl.h"> + <Filter>Include\cpython</Filter> + </ClInclude> + <ClInclude Include="..\Include\cpython\object.h"> + <Filter>Include\cpython</Filter> + </ClInclude> + <ClInclude Include="..\Include\cpython\parser_interface.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\cpython\picklebufobject.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\cpython\pyarena.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\cpython\pyctype.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\cpython\pydebug.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\cpython\pyerrors.h"> + <Filter>Include\cpython</Filter> + </ClInclude> + <ClInclude Include="..\Include\cpython\pyfpe.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\cpython\pymem.h"> + <Filter>Include\cpython</Filter> + </ClInclude> + <ClInclude Include="..\Include\cpython\pyframe.h"> + <Filter>Include\cpython</Filter> + </ClInclude> + <ClInclude Include="..\Include\cpython\pylifecycle.h"> + <Filter>Include\cpython</Filter> + </ClInclude> + <ClInclude Include="..\Include\cpython\pytime.h"> + <Filter>Include\cpython</Filter> + </ClInclude> + <ClInclude Include="..\Include\cpython\tupleobject.h"> + <Filter>Include\cpython</Filter> + </ClInclude> + <ClInclude Include="..\Include\cpython\traceback.h"> + <Filter>Include\cpython</Filter> + </ClInclude> + <ClInclude Include="..\Include\cpython\frameobject.h"> + <Filter>Include\cpython</Filter> + </ClInclude> + <ClInclude Include="..\Include\cpython\funcobject.h"> + <Filter>Include\cpython</Filter> + </ClInclude> + <ClInclude Include="..\Include\cpython\genobject.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\cpython\interpreteridobject.h"> + <Filter>Include\cpython</Filter> + </ClInclude> + <ClInclude Include="..\Include\cpython\pythonrun.h"> + <Filter>Include\cpython</Filter> + </ClInclude> + <ClInclude Include="..\Include\cpython\pythread.h"> + <Filter>Include\cpython</Filter> + </ClInclude> + <ClInclude Include="..\Include\cpython\setobject.h"> + <Filter>Include\cpython</Filter> + </ClInclude> + <ClInclude Include="..\Include\cpython\sysmodule.h"> + <Filter>Include\cpython</Filter> + </ClInclude> + <ClInclude Include="..\Include\cpython\pystate.h"> + <Filter>Include\cpython</Filter> + </ClInclude> + <ClInclude Include="..\Include\cpython\initconfig.h"> + <Filter>Include\cpython</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_unicodeobject.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_unicodeobject_generated.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_warnings.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_abstract.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_asdl.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_ast.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_ast_state.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_atexit.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_atomic.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_atomic_funcs.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_bitutils.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_bytes_methods.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_bytesobject.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_call.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_ceval.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_ceval_state.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_code.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_compile.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_condvar.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_context.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_descrobject.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_dict.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_dict_state.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_dtoa.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_exceptions.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_faulthandler.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_fileutils.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_fileutils_windows.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_floatobject.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_format.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_function.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_gc.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_genobject.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_getopt.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_gil.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_global_objects.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_global_objects_fini_generated.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_hamt.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_hashtable.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_import.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_initconfig.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_interp.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_intrinsics.h"> + <Filter>Include\cpython</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_list.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_long.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_moduleobject.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_namespace.h"> + <Filter>Include</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_object.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_object_state.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_obmalloc.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_obmalloc_init.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_pathconfig.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_pyarena.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_pyerrors.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_pyhash.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_pylifecycle.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_pymem.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_pymem_init.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_pystate.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_pythread.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_range.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_runtime.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_runtime_init.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_runtime_init_generated.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_signal.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_sliceobject.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_strhex.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_sysmodule.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_symtable.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_time.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_token.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_traceback.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_tracemalloc.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_tuple.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_typeobject.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_typevarobject.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_ucnhash.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_unionobject.h"> + <Filter>Include\internal</Filter> + </ClInclude> + <ClInclude Include="$(zlibDir)\crc32.h"> + <Filter>Modules\zlib</Filter> + </ClInclude> + <ClInclude Include="$(zlibDir)\deflate.h"> + <Filter>Modules\zlib</Filter> + </ClInclude> + <ClInclude Include="$(zlibDir)\inffast.h"> + <Filter>Modules\zlib</Filter> + </ClInclude> + <ClInclude Include="$(zlibDir)\inffixed.h"> + <Filter>Modules\zlib</Filter> + </ClInclude> + <ClInclude Include="$(zlibDir)\inflate.h"> + <Filter>Modules\zlib</Filter> + </ClInclude> + <ClInclude Include="$(zlibDir)\inftrees.h"> + <Filter>Modules\zlib</Filter> + </ClInclude> + <ClInclude Include="$(zlibDir)\trees.h"> + <Filter>Modules\zlib</Filter> + </ClInclude> + <ClInclude Include="$(zlibDir)\zconf.h"> + <Filter>Modules\zlib</Filter> + </ClInclude> + <ClInclude Include="$(zlibDir)\zconf.in.h"> + <Filter>Modules\zlib</Filter> + </ClInclude> + <ClInclude Include="$(zlibDir)\zlib.h"> + <Filter>Modules\zlib</Filter> + </ClInclude> + <ClInclude Include="$(zlibDir)\zutil.h"> + <Filter>Modules\zlib</Filter> + </ClInclude> + <ClInclude Include="..\Include\internal\pycore_structseq.h"> + <Filter>Include\internal</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\Modules\_abc.c"> + <Filter>Modules</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_bisectmodule.c"> + <Filter>Modules</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_blake2\blake2module.c"> + <Filter>Modules</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_blake2\blake2b_impl.c"> + <Filter>Modules</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_blake2\blake2s_impl.c"> + <Filter>Modules</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_codecsmodule.c"> + <Filter>Modules</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_collectionsmodule.c"> + <Filter>Modules</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_csv.c"> + <Filter>Modules</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_functoolsmodule.c"> + <Filter>Modules</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_hacl\Hacl_Hash_SHA1.c"> + <Filter>Modules</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_hacl\Hacl_Hash_SHA2.c"> + <Filter>Modules</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_hacl\Hacl_Hash_SHA3.c"> + <Filter>Modules</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_heapqmodule.c"> + <Filter>Modules</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_json.c"> + <Filter>Modules</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_localemodule.c"> + <Filter>Modules</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_lsprof.c"> + <Filter>Modules</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_pickle.c"> + <Filter>Modules</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_randommodule.c"> + <Filter>Modules</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_sre\sre.c"> + <Filter>Modules</Filter> + </ClCompile> + <ClInclude Include="..\Modules\_sre\sre.h"> + <Filter>Modules</Filter> + </ClInclude> + <ClInclude Include="..\Modules\_sre\sre_constants.h"> + <Filter>Modules</Filter> + </ClInclude> + <ClInclude Include="..\Modules\_sre\sre_lib.h"> + <Filter>Modules</Filter> + </ClInclude> + <ClCompile Include="..\Modules\_statisticsmodule.c"> + <Filter>Modules</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_typingmodule.c"> + <Filter>Modules</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_struct.c"> + <Filter>Modules</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_weakref.c"> + <Filter>Modules</Filter> + </ClCompile> + <ClCompile Include="..\Modules\arraymodule.c"> + <Filter>Modules</Filter> + </ClCompile> + <ClCompile Include="..\Modules\atexitmodule.c"> + <Filter>Modules</Filter> + </ClCompile> + <ClCompile Include="..\Modules\audioop.c"> + <Filter>Modules</Filter> + </ClCompile> + <ClCompile Include="..\Modules\binascii.c"> + <Filter>Modules</Filter> + </ClCompile> + <ClCompile Include="..\Modules\cmathmodule.c"> + <Filter>Modules</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_datetimemodule.c"> + <Filter>Modules</Filter> + </ClCompile> + <ClCompile Include="..\Modules\errnomodule.c"> + <Filter>Modules</Filter> + </ClCompile> + <ClCompile Include="..\Modules\faulthandler.c"> + <Filter>Modules</Filter> + </ClCompile> + <ClCompile Include="..\Modules\gcmodule.c"> + <Filter>Modules</Filter> + </ClCompile> + <ClCompile Include="..\Modules\itertoolsmodule.c"> + <Filter>Modules</Filter> + </ClCompile> + <ClCompile Include="..\Modules\main.c"> + <Filter>Modules</Filter> + </ClCompile> + <ClCompile Include="..\Modules\mathmodule.c"> + <Filter>Modules</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_hacl\Hacl_Hash_MD5.c"> + <Filter>Modules</Filter> + </ClCompile> + <ClCompile Include="..\Modules\md5module.c"> + <Filter>Modules</Filter> + </ClCompile> + <ClCompile Include="..\Modules\mmapmodule.c"> + <Filter>Modules</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_operator.c"> + <Filter>Modules</Filter> + </ClCompile> + <ClCompile Include="..\Modules\posixmodule.c"> + <Filter>Modules</Filter> + </ClCompile> + <ClCompile Include="..\Modules\rotatingtree.c"> + <Filter>Modules</Filter> + </ClCompile> + <ClCompile Include="..\Modules\sha1module.c"> + <Filter>Modules</Filter> + </ClCompile> + <ClCompile Include="..\Modules\sha2module.c"> + <Filter>Modules</Filter> + </ClCompile> + <ClCompile Include="..\Modules\sha3module.c"> + <Filter>Modules</Filter> + </ClCompile> + <ClCompile Include="..\Modules\signalmodule.c"> + <Filter>Modules</Filter> + </ClCompile> + <ClCompile Include="..\Modules\symtablemodule.c"> + <Filter>Modules</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_threadmodule.c"> + <Filter>Modules</Filter> + </ClCompile> + <ClCompile Include="..\Modules\timemodule.c"> + <Filter>Modules</Filter> + </ClCompile> + <ClCompile Include="..\Modules\xxsubtype.c"> + <Filter>Modules</Filter> + </ClCompile> + <ClCompile Include="..\Modules\zlibmodule.c"> + <Filter>Modules</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_io\fileio.c"> + <Filter>Modules\_io</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_io\bytesio.c"> + <Filter>Modules\_io</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_io\stringio.c"> + <Filter>Modules\_io</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_io\bufferedio.c"> + <Filter>Modules\_io</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_io\iobase.c"> + <Filter>Modules\_io</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_io\textio.c"> + <Filter>Modules\_io</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_io\winconsoleio.c"> + <Filter>Modules\_io</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_io\_iomodule.c"> + <Filter>Modules\_io</Filter> + </ClCompile> + <ClCompile Include="..\Modules\cjkcodecs\_codecs_cn.c"> + <Filter>Modules\cjkcodecs</Filter> + </ClCompile> + <ClCompile Include="..\Modules\cjkcodecs\_codecs_hk.c"> + <Filter>Modules\cjkcodecs</Filter> + </ClCompile> + <ClCompile Include="..\Modules\cjkcodecs\_codecs_iso2022.c"> + <Filter>Modules\cjkcodecs</Filter> + </ClCompile> + <ClCompile Include="..\Modules\cjkcodecs\_codecs_jp.c"> + <Filter>Modules\cjkcodecs</Filter> + </ClCompile> + <ClCompile Include="..\Modules\cjkcodecs\_codecs_kr.c"> + <Filter>Modules\cjkcodecs</Filter> + </ClCompile> + <ClCompile Include="..\Modules\cjkcodecs\_codecs_tw.c"> + <Filter>Modules\cjkcodecs</Filter> + </ClCompile> + <ClCompile Include="..\Modules\cjkcodecs\multibytecodec.c"> + <Filter>Modules\cjkcodecs</Filter> + </ClCompile> + <ClCompile Include="..\Objects\abstract.c"> + <Filter>Objects</Filter> + </ClCompile> + <ClCompile Include="..\Objects\accu.c"> + <Filter>Objects</Filter> + </ClCompile> + <ClCompile Include="..\Objects\boolobject.c"> + <Filter>Objects</Filter> + </ClCompile> + <ClCompile Include="..\Objects\bytes_methods.c"> + <Filter>Objects</Filter> + </ClCompile> + <ClCompile Include="..\Objects\bytearrayobject.c"> + <Filter>Objects</Filter> + </ClCompile> + <ClCompile Include="..\Objects\bytesobject.c"> + <Filter>Objects</Filter> + </ClCompile> + <ClCompile Include="..\Objects\call.c"> + <Filter>Objects</Filter> + </ClCompile> + <ClCompile Include="..\Objects\capsule.c"> + <Filter>Objects</Filter> + </ClCompile> + <ClCompile Include="..\Objects\cellobject.c"> + <Filter>Objects</Filter> + </ClCompile> + <ClCompile Include="..\Objects\classobject.c"> + <Filter>Objects</Filter> + </ClCompile> + <ClCompile Include="..\Objects\codeobject.c"> + <Filter>Objects</Filter> + </ClCompile> + <ClCompile Include="..\Objects\complexobject.c"> + <Filter>Objects</Filter> + </ClCompile> + <ClCompile Include="..\Objects\descrobject.c"> + <Filter>Objects</Filter> + </ClCompile> + <ClCompile Include="..\Objects\dictobject.c"> + <Filter>Objects</Filter> + </ClCompile> + <ClCompile Include="..\Objects\enumobject.c"> + <Filter>Objects</Filter> + </ClCompile> + <ClCompile Include="..\Objects\exceptions.c"> + <Filter>Objects</Filter> + </ClCompile> + <ClCompile Include="..\Objects\fileobject.c"> + <Filter>Objects</Filter> + </ClCompile> + <ClCompile Include="..\Objects\floatobject.c"> + <Filter>Objects</Filter> + </ClCompile> + <ClCompile Include="..\Objects\frameobject.c"> + <Filter>Objects</Filter> + </ClCompile> + <ClCompile Include="..\Objects\funcobject.c"> + <Filter>Objects</Filter> + </ClCompile> + <ClCompile Include="..\Objects\genobject.c"> + <Filter>Objects</Filter> + </ClCompile> + <ClCompile Include="..\Objects\iterobject.c"> + <Filter>Objects</Filter> + </ClCompile> + <ClCompile Include="..\Objects\listobject.c"> + <Filter>Objects</Filter> + </ClCompile> + <ClCompile Include="..\Objects\longobject.c"> + <Filter>Objects</Filter> + </ClCompile> + <ClCompile Include="..\Objects\memoryobject.c"> + <Filter>Objects</Filter> + </ClCompile> + <ClCompile Include="..\Objects\methodobject.c"> + <Filter>Objects</Filter> + </ClCompile> + <ClCompile Include="..\Objects\moduleobject.c"> + <Filter>Objects</Filter> + </ClCompile> + <ClCompile Include="..\Objects\object.c"> + <Filter>Objects</Filter> + </ClCompile> + <ClCompile Include="..\Objects\obmalloc.c"> + <Filter>Objects</Filter> + </ClCompile> + <ClCompile Include="..\Objects\picklebufobject.c"> + <Filter>Objects</Filter> + </ClCompile> + <ClCompile Include="..\Objects\rangeobject.c"> + <Filter>Objects</Filter> + </ClCompile> + <ClCompile Include="..\Objects\setobject.c"> + <Filter>Objects</Filter> + </ClCompile> + <ClCompile Include="..\Objects\sliceobject.c"> + <Filter>Objects</Filter> + </ClCompile> + <ClCompile Include="..\Objects\structseq.c"> + <Filter>Objects</Filter> + </ClCompile> + <ClCompile Include="..\Objects\tupleobject.c"> + <Filter>Objects</Filter> + </ClCompile> + <ClCompile Include="..\Objects\typeobject.c"> + <Filter>Objects</Filter> + </ClCompile> + <ClCompile Include="..\Objects\unicodectype.c"> + <Filter>Objects</Filter> + </ClCompile> + <ClCompile Include="..\Objects\unicodeobject.c"> + <Filter>Objects</Filter> + </ClCompile> + <ClCompile Include="..\Objects\weakrefobject.c"> + <Filter>Objects</Filter> + </ClCompile> + <ClCompile Include="..\Parser\myreadline.c"> + <Filter>Parser</Filter> + </ClCompile> + <ClCompile Include="..\Parser\tokenizer.c"> + <Filter>Parser</Filter> + </ClCompile> + <ClCompile Include="..\Parser\token.c"> + <Filter>Parser</Filter> + </ClCompile> + <ClCompile Include="..\PC\winreg.c"> + <Filter>PC</Filter> + </ClCompile> + <ClCompile Include="..\PC\config.c"> + <Filter>PC</Filter> + </ClCompile> + <ClCompile Include="..\PC\dl_nt.c"> + <Filter>PC</Filter> + </ClCompile> + <ClCompile Include="..\PC\msvcrtmodule.c"> + <Filter>PC</Filter> + </ClCompile> + <ClCompile Include="..\Python\_warnings.c"> + <Filter>Python</Filter> + </ClCompile> + <ClCompile Include="..\Python\asdl.c"> + <Filter>Python</Filter> + </ClCompile> + <ClCompile Include="..\Python\assemble.c"> + <Filter>Python</Filter> + </ClCompile> + <ClCompile Include="..\Python\ast.c"> + <Filter>Python</Filter> + </ClCompile> + <ClCompile Include="..\Python\ast_opt.c"> + <Filter>Python</Filter> + </ClCompile> + <ClCompile Include="..\Python\ast_unparse.c"> + <Filter>Python</Filter> + </ClCompile> + <ClCompile Include="..\Python\bltinmodule.c"> + <Filter>Python</Filter> + </ClCompile> + <ClCompile Include="..\Python\ceval.c"> + <Filter>Python</Filter> + </ClCompile> + <ClCompile Include="..\Python\codecs.c"> + <Filter>Python</Filter> + </ClCompile> + <ClCompile Include="..\Python\compile.c"> + <Filter>Python</Filter> + </ClCompile> + <ClCompile Include="..\Python\dynamic_annotations.c"> + <Filter>Python</Filter> + </ClCompile> + <ClCompile Include="..\Python\dynload_win.c"> + <Filter>Python</Filter> + </ClCompile> + <ClCompile Include="..\Python\errors.c"> + <Filter>Python</Filter> + </ClCompile> + <ClCompile Include="..\Python\fileutils.c"> + <Filter>Python</Filter> + </ClCompile> + <ClCompile Include="..\Python\flowgraph.c"> + <Filter>Python</Filter> + </ClCompile> + <ClCompile Include="..\Python\formatter_unicode.c"> + <Filter>Python</Filter> + </ClCompile> + <ClCompile Include="..\Python\frozen.c"> + <Filter>Python</Filter> + </ClCompile> + <ClCompile Include="..\Python\future.c"> + <Filter>Python</Filter> + </ClCompile> + <ClCompile Include="..\Python\getargs.c"> + <Filter>Python</Filter> + </ClCompile> + <ClCompile Include="..\Python\getcompiler.c"> + <Filter>Python</Filter> + </ClCompile> + <ClCompile Include="..\Python\getcopyright.c"> + <Filter>Python</Filter> + </ClCompile> + <ClCompile Include="..\Python\getopt.c"> + <Filter>Python</Filter> + </ClCompile> + <ClCompile Include="..\Python\getplatform.c"> + <Filter>Python</Filter> + </ClCompile> + <ClCompile Include="..\Python\getversion.c"> + <Filter>Python</Filter> + </ClCompile> + <ClCompile Include="..\Python\ceval_gil.c"> + <Filter>Python</Filter> + </ClCompile> + <ClCompile Include="..\Python\hashtable.c"> + <Filter>Modules</Filter> + </ClCompile> + <ClCompile Include="..\Python\import.c"> + <Filter>Python</Filter> + </ClCompile> + <ClCompile Include="..\Python\importdl.c"> + <Filter>Python</Filter> + </ClCompile> + <ClCompile Include="..\Python\initconfig.c"> + <Filter>Python</Filter> + </ClCompile> + <ClCompile Include="..\Python\intrinsics.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Python\instrumentation.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Python\legacy_tracing.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\Python\marshal.c"> + <Filter>Python</Filter> + </ClCompile> + <ClCompile Include="..\Python\modsupport.c"> + <Filter>Python</Filter> + </ClCompile> + <ClCompile Include="..\Python\mysnprintf.c"> + <Filter>Python</Filter> + </ClCompile> + <ClCompile Include="..\Python\mystrtoul.c"> + <Filter>Python</Filter> + </ClCompile> + <ClCompile Include="..\Python\pathconfig.c"> + <Filter>Python</Filter> + </ClCompile> + <ClCompile Include="..\Python\perf_trampoline.c"> + <Filter>Python</Filter> + </ClCompile> + <ClCompile Include="..\Python\preconfig.c"> + <Filter>Python</Filter> + </ClCompile> + <ClCompile Include="..\Python\pyarena.c"> + <Filter>Python</Filter> + </ClCompile> + <ClCompile Include="..\Python\pyctype.c"> + <Filter>Python</Filter> + </ClCompile> + <ClCompile Include="..\Python\pyfpe.c"> + <Filter>Python</Filter> + </ClCompile> + <ClCompile Include="..\Python\pylifecycle.c"> + <Filter>Python</Filter> + </ClCompile> + <ClCompile Include="..\Python\pymath.c"> + <Filter>Python</Filter> + </ClCompile> + <ClCompile Include="..\Python\pytime.c"> + <Filter>Python</Filter> + </ClCompile> + <ClCompile Include="..\Python\pystate.c"> + <Filter>Python</Filter> + </ClCompile> + <ClCompile Include="..\Python\pystrcmp.c"> + <Filter>Python</Filter> + </ClCompile> + <ClCompile Include="..\Python\pystrhex.c"> + <Filter>Python</Filter> + </ClCompile> + <ClCompile Include="..\Python\pystrtod.c"> + <Filter>Python</Filter> + </ClCompile> + <ClCompile Include="..\Python\dtoa.c"> + <Filter>Python</Filter> + </ClCompile> + <ClCompile Include="..\Python\Python-ast.c"> + <Filter>Python</Filter> + </ClCompile> + <ClCompile Include="..\Python\pythonrun.c"> + <Filter>Python</Filter> + </ClCompile> + <ClCompile Include="..\Python\specialize.c"> + <Filter>Python</Filter> + </ClCompile> + <ClCompile Include="..\Python\structmember.c"> + <Filter>Python</Filter> + </ClCompile> + <ClCompile Include="..\Python\symtable.c"> + <Filter>Python</Filter> + </ClCompile> + <ClCompile Include="..\Python\sysmodule.c"> + <Filter>Python</Filter> + </ClCompile> + <ClCompile Include="..\Python\thread.c"> + <Filter>Python</Filter> + </ClCompile> + <ClCompile Include="..\Python\traceback.c"> + <Filter>Python</Filter> + </ClCompile> + <ClCompile Include="..\Python\tracemalloc.c"> + <Filter>Python</Filter> + </ClCompile> + <ClCompile Include="..\Python\bootstrap_hash.c"> + <Filter>Python</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_winapi.c"> + <Filter>PC</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_stat.c"> + <Filter>Modules</Filter> + </ClCompile> + <ClCompile Include="..\Python\pyhash.c"> + <Filter>Python</Filter> + </ClCompile> + <ClCompile Include="..\Objects\namespaceobject.c"> + <Filter>Objects</Filter> + </ClCompile> + <ClCompile Include="..\Objects\interpreteridobject.c"> + <Filter>Objects</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_opcode.c"> + <Filter>Modules</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_tracemalloc.c"> + <Filter>Modules</Filter> + </ClCompile> + <ClCompile Include="..\PC\invalid_parameter_handler.c"> + <Filter>PC</Filter> + </ClCompile> + <ClCompile Include="..\Objects\odictobject.c"> + <Filter>Objects</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_contextvarsmodule.c"> + <Filter>Modules</Filter> + </ClCompile> + <ClCompile Include="$(zlibDir)\adler32.c"> + <Filter>Modules\zlib</Filter> + </ClCompile> + <ClCompile Include="$(zlibDir)\compress.c"> + <Filter>Modules\zlib</Filter> + </ClCompile> + <ClCompile Include="$(zlibDir)\crc32.c"> + <Filter>Modules\zlib</Filter> + </ClCompile> + <ClCompile Include="$(zlibDir)\deflate.c"> + <Filter>Modules\zlib</Filter> + </ClCompile> + <ClCompile Include="$(zlibDir)\infback.c"> + <Filter>Modules\zlib</Filter> + </ClCompile> + <ClCompile Include="$(zlibDir)\inffast.c"> + <Filter>Modules\zlib</Filter> + </ClCompile> + <ClCompile Include="$(zlibDir)\inflate.c"> + <Filter>Modules\zlib</Filter> + </ClCompile> + <ClCompile Include="$(zlibDir)\inftrees.c"> + <Filter>Modules\zlib</Filter> + </ClCompile> + <ClCompile Include="$(zlibDir)\trees.c"> + <Filter>Modules\zlib</Filter> + </ClCompile> + <ClCompile Include="$(zlibDir)\uncompr.c"> + <Filter>Modules\zlib</Filter> + </ClCompile> + <ClCompile Include="$(zlibDir)\zutil.c"> + <Filter>Modules\zlib</Filter> + </ClCompile> + <ClCompile Include="..\Python\hamt.c"> + <Filter>Python</Filter> + </ClCompile> + <ClCompile Include="..\Parser\parser.c"> + <Filter>Parser</Filter> + </ClCompile> + <ClCompile Include="..\Parser\pegen.c"> + <Filter>Parser</Filter> + </ClCompile> + <ClCompile Include="..\Parser\pegen_errors.c"> + <Filter>Parser</Filter> + </ClCompile> + <ClCompile Include="..\Parser\action_helpers.c"> + <Filter>Parser</Filter> + </ClCompile> + <ClCompile Include="..\Parser\peg_api.c"> + <Filter>Parser</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_xxsubinterpretersmodule.c"> + <Filter>Modules</Filter> + </ClCompile> + <ClCompile Include="..\Modules\_xxinterpchannelsmodule.c"> + <Filter>Modules</Filter> + </ClCompile> + <ClCompile Include="..\Parser\string_parser.c"> + <Filter>Parser</Filter> + </ClCompile> + <ClCompile Include="..\Python\context.c"> + <Filter>Python</Filter> + </ClCompile> + <ClCompile Include="..\Objects\genericaliasobject.c"> + <Filter>Objects</Filter> + </ClCompile> + <ClCompile Include="..\Objects\typevarobject.c"> + <Filter>Objects</Filter> + </ClCompile> + <ClCompile Include="..\Objects\unionobject.c"> + <Filter>Objects</Filter> + </ClCompile> + <ClCompile Include="..\Python\frame.c"> + <Filter>Python</Filter> + </ClCompile> + <ClCompile Include="..\Modules\getpath.c"> + <Filter>Modules</Filter> + </ClCompile> + <ClCompile Include="..\Python\suggestions.c"> + <Filter>Python</Filter> + </ClCompile> + <ClCompile Include="..\Python\Python-tokenize.c"> + <Filter>Python</Filter> + </ClCompile> + <ClCompile Include="..\Modules\getbuildinfo.c"> + <Filter>Modules</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_nt.rc"> + <Filter>Resource Files</Filter> + </ResourceCompile> + </ItemGroup> +</Project> diff --git a/PCbuild/pythonw.vcxproj b/PCbuild/pythonw.vcxproj index 871d250e..e23635e5 100644 --- a/PCbuild/pythonw.vcxproj +++ b/PCbuild/pythonw.vcxproj @@ -1,110 +1,111 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|ARM"> - <Configuration>Debug</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|ARM64"> - <Configuration>Debug</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM64"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|Win32"> - <Configuration>PGInstrument</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|x64"> - <Configuration>PGInstrument</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM64"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|Win32"> - <Configuration>PGUpdate</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|x64"> - <Configuration>PGUpdate</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM"> - <Configuration>Release</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM64"> - <Configuration>Release</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectGuid>{F4229CC3-873C-49AE-9729-DD308ED4CD4A}</ProjectGuid> - <SupportPGO>false</SupportPGO> - </PropertyGroup> - <Import Project="python.props" /> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseOfMfc>false</UseOfMfc> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="pyproject.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup> - <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> - </PropertyGroup> - <ItemDefinitionGroup> - <Link> - <StackReserveSize>2000000</StackReserveSize> - </Link> - </ItemDefinitionGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\pythonw_exe.rc" /> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\PC\WinMain.c" /> - </ItemGroup> - <ItemGroup> - <ProjectReference Include="pythoncore.vcxproj"> - <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> - <ReferenceOutputAssembly>false</ReferenceOutputAssembly> - </ProjectReference> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|ARM"> + <Configuration>Debug</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|ARM64"> + <Configuration>Debug</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM64"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|Win32"> + <Configuration>PGInstrument</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|x64"> + <Configuration>PGInstrument</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM64"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|Win32"> + <Configuration>PGUpdate</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|x64"> + <Configuration>PGUpdate</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM"> + <Configuration>Release</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM64"> + <Configuration>Release</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{F4229CC3-873C-49AE-9729-DD308ED4CD4A}</ProjectGuid> + <SupportPGO>false</SupportPGO> + </PropertyGroup> + <Import Project="python.props" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="pyproject.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> + </PropertyGroup> + <ItemDefinitionGroup> + <Link> + <StackReserveSize Condition="$(Configuration) != 'Debug'">2000000</StackReserveSize> + <StackReserveSize Condition="$(Configuration) == 'Debug'">8000000</StackReserveSize> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\pythonw_exe.rc" /> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\PC\WinMain.c" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="pythoncore.vcxproj"> + <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> </Project> \ No newline at end of file diff --git a/PCbuild/pythonw.vcxproj.filters b/PCbuild/pythonw.vcxproj.filters index b7408da3..20d87051 100644 --- a/PCbuild/pythonw.vcxproj.filters +++ b/PCbuild/pythonw.vcxproj.filters @@ -1,21 +1,21 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <Filter Include="Resource Files"> - <UniqueIdentifier>{0434cf11-a311-4a92-8a6c-4164aa79a7f2}</UniqueIdentifier> - </Filter> - <Filter Include="Source Files"> - <UniqueIdentifier>{e1d8ea6b-c65d-42f4-9eed-6010846ed378}</UniqueIdentifier> - </Filter> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\PC\WinMain.c"> - <Filter>Source Files</Filter> - </ClCompile> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\pythonw_exe.rc"> - <Filter>Resource Files</Filter> - </ResourceCompile> - </ItemGroup> +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Resource Files"> + <UniqueIdentifier>{0434cf11-a311-4a92-8a6c-4164aa79a7f2}</UniqueIdentifier> + </Filter> + <Filter Include="Source Files"> + <UniqueIdentifier>{e1d8ea6b-c65d-42f4-9eed-6010846ed378}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\PC\WinMain.c"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\pythonw_exe.rc"> + <Filter>Resource Files</Filter> + </ResourceCompile> + </ItemGroup> </Project> \ No newline at end of file diff --git a/PCbuild/pythonw_uwp.vcxproj b/PCbuild/pythonw_uwp.vcxproj index 7f4d3142..e21e46a1 100644 --- a/PCbuild/pythonw_uwp.vcxproj +++ b/PCbuild/pythonw_uwp.vcxproj @@ -1,128 +1,128 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|ARM"> - <Configuration>Debug</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|ARM64"> - <Configuration>Debug</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM64"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|Win32"> - <Configuration>PGInstrument</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|x64"> - <Configuration>PGInstrument</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM64"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|Win32"> - <Configuration>PGUpdate</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|x64"> - <Configuration>PGUpdate</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM"> - <Configuration>Release</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM64"> - <Configuration>Release</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectGuid>{AB603547-1E2A-45B3-9E09-B04596006393}</ProjectGuid> - </PropertyGroup> - <Import Project="python.props" /> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseOfMfc>false</UseOfMfc> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="pyproject.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup> - <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> - </PropertyGroup> - <ItemDefinitionGroup> - <ClCompile> - <PreprocessorDefinitions>PYTHONW;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalOptions>/EHsc /std:c++17 %(AdditionalOptions)</AdditionalOptions> - </ClCompile> - <Link> - <AdditionalDependencies>windowsapp.lib;%(AdditionalDependencies)</AdditionalDependencies> - <SubSystem>Windows</SubSystem> - <StackReserveSize>2000000</StackReserveSize> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="$(Configuration) != 'Debug'"> - <ClCompile> - <RuntimeLibrary>Multithreaded</RuntimeLibrary> - </ClCompile> - <Link> - <AdditionalDependencies>ucrt.lib;%(AdditionalDependencies)</AdditionalDependencies> - <IgnoreSpecificDefaultLibraries>libucrt;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries> - </Link> - </ItemDefinitionGroup> - <ItemGroup> - <None Include="..\PC\pyconw.ico" /> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\pythonw_exe.rc" /> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\PC\python_uwp.cpp" /> - </ItemGroup> - <ItemGroup> - <ProjectReference Include="pythoncore.vcxproj"> - <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> - <ReferenceOutputAssembly>false</ReferenceOutputAssembly> - </ProjectReference> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> -</Project> +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|ARM"> + <Configuration>Debug</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|ARM64"> + <Configuration>Debug</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM64"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|Win32"> + <Configuration>PGInstrument</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|x64"> + <Configuration>PGInstrument</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM64"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|Win32"> + <Configuration>PGUpdate</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|x64"> + <Configuration>PGUpdate</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM"> + <Configuration>Release</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM64"> + <Configuration>Release</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{AB603547-1E2A-45B3-9E09-B04596006393}</ProjectGuid> + </PropertyGroup> + <Import Project="python.props" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseOfMfc>false</UseOfMfc> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="pyproject.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> + </PropertyGroup> + <ItemDefinitionGroup> + <ClCompile> + <PreprocessorDefinitions>PYTHONW;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalOptions>/EHsc /std:c++17 %(AdditionalOptions)</AdditionalOptions> + </ClCompile> + <Link> + <AdditionalDependencies>windowsapp.lib;%(AdditionalDependencies)</AdditionalDependencies> + <SubSystem>Windows</SubSystem> + <StackReserveSize>2000000</StackReserveSize> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="$(Configuration) != 'Debug'"> + <ClCompile> + <RuntimeLibrary>Multithreaded</RuntimeLibrary> + </ClCompile> + <Link> + <AdditionalDependencies>ucrt.lib;%(AdditionalDependencies)</AdditionalDependencies> + <IgnoreSpecificDefaultLibraries>libucrt;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <None Include="..\PC\pyconw.ico" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\pythonw_exe.rc" /> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\PC\python_uwp.cpp" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="pythoncore.vcxproj"> + <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> diff --git a/PCbuild/pythonw_uwp.vcxproj.filters b/PCbuild/pythonw_uwp.vcxproj.filters index 04710527..2f39bdea 100644 --- a/PCbuild/pythonw_uwp.vcxproj.filters +++ b/PCbuild/pythonw_uwp.vcxproj.filters @@ -1,26 +1,26 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <Filter Include="Resource Files"> - <UniqueIdentifier>{de05f656-4dcb-4fe7-9946-5c325ea2d842}</UniqueIdentifier> - </Filter> - <Filter Include="Source Files"> - <UniqueIdentifier>{4102e199-3e5c-42d0-b37b-d42394b20d9e}</UniqueIdentifier> - </Filter> - </ItemGroup> - <ItemGroup> - <None Include="..\PC\pyconw.ico"> - <Filter>Resource Files</Filter> - </None> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\pythonw_exe.rc"> - <Filter>Resource Files</Filter> - </ResourceCompile> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\PC\python_uwp.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - </ItemGroup> +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Resource Files"> + <UniqueIdentifier>{de05f656-4dcb-4fe7-9946-5c325ea2d842}</UniqueIdentifier> + </Filter> + <Filter Include="Source Files"> + <UniqueIdentifier>{4102e199-3e5c-42d0-b37b-d42394b20d9e}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <None Include="..\PC\pyconw.ico"> + <Filter>Resource Files</Filter> + </None> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\pythonw_exe.rc"> + <Filter>Resource Files</Filter> + </ResourceCompile> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\PC\python_uwp.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> </Project> \ No newline at end of file diff --git a/PCbuild/pywlauncher.vcxproj b/PCbuild/pywlauncher.vcxproj index 2f371a48..e50b69ae 100644 --- a/PCbuild/pywlauncher.vcxproj +++ b/PCbuild/pywlauncher.vcxproj @@ -1,114 +1,114 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|ARM"> - <Configuration>Debug</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|ARM64"> - <Configuration>Debug</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM64"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|Win32"> - <Configuration>PGInstrument</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|x64"> - <Configuration>PGInstrument</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM64"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|Win32"> - <Configuration>PGUpdate</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|x64"> - <Configuration>PGUpdate</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM"> - <Configuration>Release</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM64"> - <Configuration>Release</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectGuid>{1D4B18D3-7C12-4ECB-9179-8531FF876CE6}</ProjectGuid> - <RootNamespace>pywlauncher</RootNamespace> - <TargetName>pyw</TargetName> - <SupportPGO>false</SupportPGO> - </PropertyGroup> - <Import Project="python.props" /> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <PropertyGroup> - <MakeVersionInfoBeforeTarget>ClCompile</MakeVersionInfoBeforeTarget> - </PropertyGroup> - <ImportGroup Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="pyproject.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <ItemDefinitionGroup> - <ClCompile> - <PreprocessorDefinitions>_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - </ClCompile> - <Link> - <AdditionalDependencies>shell32.lib;pathcch.lib;%(AdditionalDependencies)</AdditionalDependencies> - <SubSystem>Windows</SubSystem> - </Link> - </ItemDefinitionGroup> - <ItemGroup> - <ClCompile Include="..\PC\launcher2.c" /> - </ItemGroup> - <ItemGroup> - <None Include="..\PC\launcher.ico" /> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\pylauncher.rc" /> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|ARM"> + <Configuration>Debug</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|ARM64"> + <Configuration>Debug</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM64"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|Win32"> + <Configuration>PGInstrument</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|x64"> + <Configuration>PGInstrument</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM64"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|Win32"> + <Configuration>PGUpdate</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|x64"> + <Configuration>PGUpdate</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM"> + <Configuration>Release</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM64"> + <Configuration>Release</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{1D4B18D3-7C12-4ECB-9179-8531FF876CE6}</ProjectGuid> + <RootNamespace>pywlauncher</RootNamespace> + <TargetName>pyw</TargetName> + <SupportPGO>false</SupportPGO> + </PropertyGroup> + <Import Project="python.props" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <PropertyGroup> + <MakeVersionInfoBeforeTarget>ClCompile</MakeVersionInfoBeforeTarget> + </PropertyGroup> + <ImportGroup Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="pyproject.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <ItemDefinitionGroup> + <ClCompile> + <PreprocessorDefinitions>_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <AdditionalDependencies>shell32.lib;pathcch.lib;%(AdditionalDependencies)</AdditionalDependencies> + <SubSystem>Windows</SubSystem> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\PC\launcher2.c" /> + </ItemGroup> + <ItemGroup> + <None Include="..\PC\launcher.ico" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\pylauncher.rc" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> </Project> \ No newline at end of file diff --git a/PCbuild/pywlauncher.vcxproj.filters b/PCbuild/pywlauncher.vcxproj.filters index 39a8f2fd..17d0389c 100644 --- a/PCbuild/pywlauncher.vcxproj.filters +++ b/PCbuild/pywlauncher.vcxproj.filters @@ -1,28 +1,28 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <Filter Include="Source Files"> - <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> - <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> - </Filter> - <Filter Include="Resource Files"> - <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> - <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> - </Filter> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\PC\launcher.c"> - <Filter>Source Files</Filter> - </ClCompile> - </ItemGroup> - <ItemGroup> - <None Include="..\PC\launcher.ico"> - <Filter>Resource Files</Filter> - </None> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\pylauncher.rc"> - <Filter>Resource Files</Filter> - </ResourceCompile> - </ItemGroup> +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\PC\launcher.c"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <None Include="..\PC\launcher.ico"> + <Filter>Resource Files</Filter> + </None> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\pylauncher.rc"> + <Filter>Resource Files</Filter> + </ResourceCompile> + </ItemGroup> </Project> \ No newline at end of file diff --git a/PCbuild/readme.txt b/PCbuild/readme.txt index d5e08c17..5c682a28 100644 --- a/PCbuild/readme.txt +++ b/PCbuild/readme.txt @@ -1,291 +1,295 @@ -Quick Start Guide ------------------ - -1. Install Microsoft Visual Studio 2017 with Python workload and - Python native development component. -1a. Optionally install Python 3.6 or later. If not installed, - get_externals.bat (via build.bat) will download and use Python via - NuGet. -2. Run "build.bat" to build Python in 32-bit Release configuration. -3. (Optional, but recommended) Run the test suite with "rt.bat -q". - - -Building Python using Microsoft Visual C++ ------------------------------------------- - -This directory is used to build CPython for Microsoft Windows on 32- and 64- -bit platforms. Using this directory requires an installation of -Microsoft Visual Studio (MSVC) with the *Python workload* and -its optional *Python native development* component selected. - -Building from the command line is recommended in order to obtain any -external dependencies. To build, simply run the "build.bat" script without -any arguments. After this succeeds, you can open the "pcbuild.sln" -solution in Visual Studio to continue development. - -To build an installer package, refer to the README in the Tools/msi folder. - -The solution currently supports two platforms. The Win32 platform is -used to build standard x86-compatible 32-bit binaries, output into the -win32 sub-directory. The x64 platform is used for building 64-bit AMD64 -(aka x86_64 or EM64T) binaries, output into the amd64 sub-directory. -The Itanium (IA-64) platform is no longer supported. - -Four configuration options are supported by the solution: -Debug - Used to build Python with extra debugging capabilities, equivalent - to using ./configure --with-pydebug on UNIX. All binaries built - using this configuration have "_d" added to their name: - python310_d.dll, python_d.exe, parser_d.pyd, and so on. Both the - build and rt (run test) batch files in this directory accept a -d - option for debug builds. If you are building Python to help with - development of CPython, you will most likely use this configuration. -PGInstrument, PGUpdate - Used to build Python in Release configuration using PGO, which - requires Premium Edition of Visual Studio. See the "Profile - Guided Optimization" section below for more information. Build - output from each of these configurations lands in its own - sub-directory of this directory. The official Python releases may - be built using these configurations. -Release - Used to build Python as it is meant to be used in production - settings, though without PGO. - - -Building Python using the build.bat script ----------------------------------------------- - -In this directory you can find build.bat, a script designed to make -building Python on Windows simpler. This script will use the env.bat -script to detect either Visual Studio 2017 or 2015, either of -which may be used to build Python. Currently Visual Studio 2017 is -officially supported. - -By default, build.bat will build Python in Release configuration for -the 32-bit Win32 platform. It accepts several arguments to change -this behavior, try `build.bat -h` to learn more. - - -C Runtime ---------- - -Visual Studio 2017 uses version 14.0 of the C runtime (vcruntime140). -The executables no longer use the "Side by Side" assemblies used in -previous versions of the compiler. This simplifies distribution of -applications. - -The run time libraries are available under the redist folder of your -Visual Studio distribution. For more info, see the Readme in the -redist folder. - - -Sub-Projects ------------- - -The CPython project is split up into several smaller sub-projects which -are managed by the pcbuild.sln solution file. Each sub-project is -represented by a .vcxproj and a .vcxproj.filters file starting with the -name of the sub-project. These sub-projects fall into a few general -categories: - -The following sub-projects represent the bare minimum required to build -a functioning CPython interpreter. If nothing else builds but these, -you'll have a very limited but usable python.exe: -pythoncore - .dll and .lib -python - .exe - -These sub-projects provide extra executables that are useful for running -CPython in different ways: -pythonw - pythonw.exe, a variant of python.exe that doesn't open a Command - Prompt window -pylauncher - py.exe, the Python Launcher for Windows, see - https://docs.python.org/3/using/windows.html#launcher -pywlauncher - pyw.exe, a variant of py.exe that doesn't open a Command Prompt - window -_testembed - _testembed.exe, a small program that embeds Python for testing - purposes, used by test_capi.py - -These are miscellaneous sub-projects that don't really fit the other -categories: -_freeze_module - _freeze_module.exe, used to regenerate frozen modules in Python - after changes have been made to the corresponding source files - (e.g. Lib\importlib\_bootstrap.py). -pyshellext - pyshellext.dll, the shell extension deployed with the launcher -python3dll - python3.dll, the PEP 384 Stable ABI dll -xxlimited - builds an example module that makes use of the PEP 384 Stable ABI, - see Modules\xxlimited.c -xxlimited_35 - ditto for testing the Python 3.5 stable ABI, see - Modules\xxlimited_35.c - -The following sub-projects are for individual modules of the standard -library which are implemented in C; each one builds a DLL (renamed to -.pyd) of the same name as the project: -_asyncio -_ctypes -_ctypes_test -_zoneinfo -_decimal -_elementtree -_hashlib -_msi -_multiprocessing -_overlapped -_socket -_testbuffer -_testcapi -_testconsole -_testimportmultiple -_testmultiphase -_tkinter -pyexpat -select -unicodedata -winsound - -The following Python-controlled sub-projects wrap external projects. -Note that these external libraries are not necessary for a working -interpreter, but they do implement several major features. See the -"Getting External Sources" section below for additional information -about getting the source for building these libraries. The sub-projects -are: -_bz2 - Python wrapper for version 1.0.8 of the libbzip2 compression library - Homepage: - http://www.bzip.org/ -_lzma - Python wrapper for version 5.2.2 of the liblzma compression library - Homepage: - https://tukaani.org/xz/ -_ssl - Python wrapper for version 1.1.1q of the OpenSSL secure sockets - library, which is downloaded from our binaries repository at - https://github.com/python/cpython-bin-deps. - - Homepage: - https://www.openssl.org/ - - Building OpenSSL requires Perl on your path, and can be performed by - running PCbuild\prepare_ssl.bat. This will retrieve the version of - the sources matched to the current commit from the OpenSSL branch - in our source repository at - https://github.com/python/cpython-source-deps. - - To use an alternative build of OpenSSL completely, you should replace - the files in the externals/openssl-bin-<version> folder with your own. - As long as this folder exists, its contents will not be downloaded - again when building. - -_sqlite3 - Wraps SQLite 3.39.4, which is itself built by sqlite3.vcxproj - Homepage: - https://www.sqlite.org/ -_tkinter - Wraps version 8.6.6 of the Tk windowing system, which is downloaded - from our binaries repository at - https://github.com/python/cpython-bin-deps. - - Homepage: - https://www.tcl.tk/ - - Building Tcl and Tk can be performed by running - PCbuild\prepare_tcltk.bat. This will retrieve the version of the - sources matched to the current commit from the Tcl and Tk branches - in our source repository at - https://github.com/python/cpython-source-deps. - - The two projects install their respective components in a - directory alongside the source directories called "tcltk" on - Win32 and "tcltk64" on x64. They also copy the Tcl and Tk DLLs - into the current output directory, which should ensure that Tkinter - is able to load Tcl/Tk without having to change your PATH. - - -Getting External Sources ------------------------- - -The last category of sub-projects listed above wrap external projects -Python doesn't control, and as such a little more work is required in -order to download the relevant source files for each project before they -can be built. However, a simple script is provided to make this as -painless as possible, called "get_externals.bat" and located in this -directory. This script extracts all the external sub-projects from - https://github.com/python/cpython-source-deps -and - https://github.com/python/cpython-bin-deps -via a Python script called "get_external.py", located in this directory. -If Python 3.6 or later is not available via the "py.exe" launcher, the -path or command to use for Python can be provided in the PYTHON_FOR_BUILD -environment variable, or get_externals.bat will download the latest -version of NuGet and use it to download the latest "pythonx86" package -for use with get_external.py. Everything downloaded by these scripts is -stored in ..\externals (relative to this directory). - -It is also possible to download sources from each project's homepage, -though you may have to change folder names or pass the names to MSBuild -as the values of certain properties in order for the build solution to -find them. This is an advanced topic and not necessarily fully -supported. - -The get_externals.bat script is called automatically by build.bat -unless you pass the '-E' option. - - -Profile Guided Optimization ---------------------------- - -The solution has two configurations for PGO. The PGInstrument -configuration must be built first. The PGInstrument binaries are linked -against a profiling library and contain extra debug information. The -PGUpdate configuration takes the profiling data and generates optimized -binaries. - -The build_pgo.bat script automates the creation of optimized binaries. -It creates the PGI files, runs the unit test suite or PyBench with the -PGI python, and finally creates the optimized files. - -See - https://docs.microsoft.com/en-us/cpp/build/profile-guided-optimizations -for more on this topic. - - -Static library --------------- - -The solution has no configuration for static libraries. However it is -easy to build a static library instead of a DLL. You simply have to set -the "Configuration Type" to "Static Library (.lib)" and alter the -preprocessor macro "Py_ENABLE_SHARED" to "Py_NO_ENABLE_SHARED". You may -also have to change the "Runtime Library" from "Multi-threaded DLL -(/MD)" to "Multi-threaded (/MT)". - - -Visual Studio properties ------------------------- - -The PCbuild solution makes use of Visual Studio property files (*.props) -to simplify each project. The properties can be viewed in the Property -Manager (View -> Other Windows -> Property Manager) but should be -carefully modified by hand. - -The property files used are: - * python (versions, directories and build names) - * pyproject (base settings for all projects) - * openssl (used by projects dependent upon OpenSSL) - * tcltk (used by _tkinter, tcl, tk and tix projects) - -The pyproject property file defines all of the build settings for each -project, with some projects overriding certain specific values. The GUI -doesn't always reflect the correct settings and may confuse the user -with false information, especially for settings that automatically adapt -for different configurations. +Quick Start Guide +----------------- + +1. Install Microsoft Visual Studio 2017 or later with Python workload and + Python native development component. +1a. Optionally install Python 3.6 or later. If not installed, + get_externals.bat (via build.bat) will download and use Python via + NuGet. +2. Run "build.bat" to build Python in 32-bit Release configuration. +3. (Optional, but recommended) Run the test suite with "rt.bat -q". + + +Building Python using Microsoft Visual C++ +------------------------------------------ + +This directory is used to build CPython for Microsoft Windows on 32- and 64- +bit platforms. Using this directory requires an installation of +Microsoft Visual Studio (MSVC) with the *Python workload* and +its optional *Python native development* component selected. + +Building from the command line is recommended in order to obtain any +external dependencies. To build, simply run the "build.bat" script without +any arguments. After this succeeds, you can open the "pcbuild.sln" +solution in Visual Studio to continue development. + +To build an installer package, refer to the README in the Tools/msi folder. + +The solution currently supports two platforms. The Win32 platform is +used to build standard x86-compatible 32-bit binaries, output into the +win32 sub-directory. The x64 platform is used for building 64-bit AMD64 +(aka x86_64 or EM64T) binaries, output into the amd64 sub-directory. +The Itanium (IA-64) platform is no longer supported. + +Four configuration options are supported by the solution: +Debug + Used to build Python with extra debugging capabilities, equivalent + to using ./configure --with-pydebug on UNIX. All binaries built + using this configuration have "_d" added to their name: + python310_d.dll, python_d.exe, parser_d.pyd, and so on. Both the + build and rt (run test) batch files in this directory accept a -d + option for debug builds. If you are building Python to help with + development of CPython, you will most likely use this configuration. +PGInstrument, PGUpdate + Used to build Python in Release configuration using PGO, which + requires Premium Edition of Visual Studio. See the "Profile + Guided Optimization" section below for more information. Build + output from each of these configurations lands in its own + sub-directory of this directory. The official Python releases may + be built using these configurations. +Release + Used to build Python as it is meant to be used in production + settings, though without PGO. + + +Building Python using the build.bat script +---------------------------------------------- + +In this directory you can find build.bat, a script designed to make +building Python on Windows simpler. This script will use the env.bat +script to detect either Visual Studio 2017 or 2015, either of +which may be used to build Python. Currently Visual Studio 2017 is +officially supported. + +By default, build.bat will build Python in Release configuration for +the 32-bit Win32 platform. It accepts several arguments to change +this behavior, try `build.bat -h` to learn more. + + +C Runtime +--------- + +Visual Studio 2017 uses version 14.0 of the C runtime (vcruntime140). +The executables no longer use the "Side by Side" assemblies used in +previous versions of the compiler. This simplifies distribution of +applications. + +The run time libraries are available under the redist folder of your +Visual Studio distribution. For more info, see the Readme in the +redist folder. + + +Sub-Projects +------------ + +The CPython project is split up into several smaller sub-projects which +are managed by the pcbuild.sln solution file. Each sub-project is +represented by a .vcxproj and a .vcxproj.filters file starting with the +name of the sub-project. These sub-projects fall into a few general +categories: + +The following sub-projects represent the bare minimum required to build +a functioning CPython interpreter. If nothing else builds but these, +you'll have a very limited but usable python.exe: +pythoncore + .dll and .lib +python + .exe + +These sub-projects provide extra executables that are useful for running +CPython in different ways: +pythonw + pythonw.exe, a variant of python.exe that doesn't open a Command + Prompt window +pylauncher + py.exe, the Python Launcher for Windows, see + https://docs.python.org/3/using/windows.html#launcher +pywlauncher + pyw.exe, a variant of py.exe that doesn't open a Command Prompt + window +_testembed + _testembed.exe, a small program that embeds Python for testing + purposes, used by test_capi.py + +These are miscellaneous sub-projects that don't really fit the other +categories: +_freeze_module + _freeze_module.exe, used to regenerate frozen modules in Python + after changes have been made to the corresponding source files + (e.g. Lib\importlib\_bootstrap.py). +pyshellext + pyshellext.dll, the shell extension deployed with the launcher +python3dll + python3.dll, the PEP 384 Stable ABI dll +xxlimited + builds an example module that makes use of the PEP 384 Stable ABI, + see Modules\xxlimited.c +xxlimited_35 + ditto for testing the Python 3.5 stable ABI, see + Modules\xxlimited_35.c + +The following sub-projects are for individual modules of the standard +library which are implemented in C; each one builds a DLL (renamed to +.pyd) of the same name as the project: +_asyncio +_ctypes +_ctypes_test +_zoneinfo +_decimal +_elementtree +_hashlib +_msi +_multiprocessing +_overlapped +_socket +_testbuffer +_testcapi +_testclinic +_testconsole +_testimportmultiple +_testmultiphase +_testsinglephase +_tkinter +pyexpat +select +unicodedata +winsound + +The following Python-controlled sub-projects wrap external projects. +Note that these external libraries are not necessary for a working +interpreter, but they do implement several major features. See the +"Getting External Sources" section below for additional information +about getting the source for building these libraries. The sub-projects +are: +_bz2 + Python wrapper for version 1.0.8 of the libbzip2 compression library + Homepage: + http://www.bzip.org/ +_lzma + Python wrapper for version 5.2.2 of the liblzma compression library + Homepage: + https://tukaani.org/xz/ +_ssl + Python wrapper for version 3.0 of the OpenSSL secure sockets + library, which is downloaded from our binaries repository at + https://github.com/python/cpython-bin-deps. + + Homepage: + https://www.openssl.org/ + + Building OpenSSL requires Perl on your path, and can be performed by + running PCbuild\prepare_ssl.bat. This will retrieve the version of + the sources matched to the current commit from the OpenSSL branch + in our source repository at + https://github.com/python/cpython-source-deps. + + To use an alternative build of OpenSSL completely, you should replace + the files in the externals/openssl-bin-<version> folder with your own. + As long as this folder exists, its contents will not be downloaded + again when building. + +_sqlite3 + Wraps SQLite 3.42.0, which is itself built by sqlite3.vcxproj + Homepage: + https://www.sqlite.org/ +_tkinter + Wraps version 8.6.6 of the Tk windowing system, which is downloaded + from our binaries repository at + https://github.com/python/cpython-bin-deps. + + Homepage: + https://www.tcl.tk/ + + Building Tcl and Tk can be performed by running + PCbuild\prepare_tcltk.bat. This will retrieve the version of the + sources matched to the current commit from the Tcl and Tk branches + in our source repository at + https://github.com/python/cpython-source-deps. + + The two projects install their respective components in a + directory alongside the source directories called "tcltk" on + Win32 and "tcltk64" on x64. They also copy the Tcl and Tk DLLs + into the current output directory, which should ensure that Tkinter + is able to load Tcl/Tk without having to change your PATH. + + +Getting External Sources +------------------------ + +The last category of sub-projects listed above wrap external projects +Python doesn't control, and as such a little more work is required in +order to download the relevant source files for each project before they +can be built. However, a simple script is provided to make this as +painless as possible, called "get_externals.bat" and located in this +directory. This script extracts all the external sub-projects from + https://github.com/python/cpython-source-deps +and + https://github.com/python/cpython-bin-deps +via a Python script called "get_external.py", located in this directory. +If Python 3.6 or later is not available via the "py.exe" launcher, the +path or command to use for Python can be provided in the PYTHON_FOR_BUILD +environment variable, or get_externals.bat will download the latest +version of NuGet and use it to download the latest "pythonx86" package +for use with get_external.py. Everything downloaded by these scripts is +stored in ..\externals (relative to this directory). + +It is also possible to download sources from each project's homepage, +though you may have to change folder names or pass the names to MSBuild +as the values of certain properties in order for the build solution to +find them. This is an advanced topic and not necessarily fully +supported. + +The get_externals.bat script is called automatically by build.bat +unless you pass the '-E' option. + + +Profile Guided Optimization +--------------------------- + +The solution has two configurations for PGO. The PGInstrument +configuration must be built first. The PGInstrument binaries are linked +against a profiling library and contain extra debug information. The +PGUpdate configuration takes the profiling data and generates optimized +binaries. + +The build.bat script has an argument `--pgo` that automate the creation +of optimized binaries. +It creates the PGI files, runs the unit test suite with the PGI python, +and finally creates the optimized files. +You can customize the job for profiling with `--pgo-job <job>` option. + +See + https://docs.microsoft.com/en-us/cpp/build/profile-guided-optimizations +for more on this topic. + + +Static library +-------------- + +The solution has no configuration for static libraries. However it is +easy to build a static library instead of a DLL. You simply have to set +the "Configuration Type" to "Static Library (.lib)" and alter the +preprocessor macro "Py_ENABLE_SHARED" to "Py_NO_ENABLE_SHARED". You may +also have to change the "Runtime Library" from "Multi-threaded DLL +(/MD)" to "Multi-threaded (/MT)". + + +Visual Studio properties +------------------------ + +The PCbuild solution makes use of Visual Studio property files (*.props) +to simplify each project. The properties can be viewed in the Property +Manager (View -> Other Windows -> Property Manager) but should be +carefully modified by hand. + +The property files used are: + * python (versions, directories and build names) + * pyproject (base settings for all projects) + * openssl (used by projects dependent upon OpenSSL) + * tcltk (used by _tkinter, tcl, tk and tix projects) + +The pyproject property file defines all of the build settings for each +project, with some projects overriding certain specific values. The GUI +doesn't always reflect the correct settings and may confuse the user +with false information, especially for settings that automatically adapt +for different configurations. diff --git a/PCbuild/regen.targets b/PCbuild/regen.targets index 24b5ced1..af07adec 100644 --- a/PCbuild/regen.targets +++ b/PCbuild/regen.targets @@ -13,13 +13,13 @@ <_ASTOutputs Include="$(PySourcePath)Python\Python-ast.c"> <Argument>-C</Argument> </_ASTOutputs> - <_OpcodeSources Include="$(PySourcePath)Tools\scripts\generate_opcode_h.py;$(PySourcePath)Lib\opcode.py" /> + <_OpcodeSources Include="$(PySourcePath)Tools\build\generate_opcode_h.py;$(PySourcePath)Lib\opcode.py" /> <_OpcodeOutputs Include="$(PySourcePath)Include\opcode.h;$(PySourcePath)Include\internal\pycore_opcode.h;$(PySourcePath)Python\opcode_targets.h" /> <_TokenSources Include="$(PySourcePath)Grammar\Tokens" /> <_TokenOutputs Include="$(PySourcePath)Doc\library\token-list.inc"> <Format>rst</Format> </_TokenOutputs> - <_TokenOutputs Include="$(PySourcePath)Include\token.h"> + <_TokenOutputs Include="$(PySourcePath)Include\internal\pycore_token.h"> <Format>h</Format> </_TokenOutputs> <_TokenOutputs Include="$(PySourcePath)Parser\token.c"> @@ -59,7 +59,7 @@ Inputs="@(_OpcodeSources)" Outputs="@(_OpcodeOutputs)" DependsOnTargets="FindPythonForBuild"> <Message Text="Regenerate @(_OpcodeOutputs->'%(Filename)%(Extension)',' ')" Importance="high" /> - <Exec Command="$(PythonForBuild) Tools\scripts\generate_opcode_h.py Lib\opcode.py Include\opcode.h Include\internal\pycore_opcode.h" + <Exec Command="$(PythonForBuild) Tools\build\generate_opcode_h.py Lib\opcode.py Include\opcode.h Include\internal\pycore_opcode.h Include\internal\pycore_intrinsics.h" WorkingDirectory="$(PySourcePath)" /> <Exec Command="$(PythonForBuild) Python\makeopcodetargets.py Python\opcode_targets.h" WorkingDirectory="$(PySourcePath)" /> @@ -69,7 +69,7 @@ Inputs="@(_TokenSources)" Outputs="@(_TokenOutputs)" DependsOnTargets="FindPythonForBuild"> <Message Text="Regenerate @(_TokenOutputs->'%(Filename)%(Extension)',' ')" Importance="high" /> - <Exec Command="$(PythonForBuild) Tools\scripts\generate_token.py %(_TokenOutputs.Format) Grammar\Tokens "%(_TokenOutputs.Identity)"" + <Exec Command="$(PythonForBuild) Tools\build\generate_token.py %(_TokenOutputs.Format) Grammar\Tokens "%(_TokenOutputs.Identity)"" WorkingDirectory="$(PySourcePath)" /> <Touch Files="@(_TokenOutputs)" /> </Target> @@ -82,9 +82,16 @@ WorkingDirectory="$(PySourcePath)" /> </Target> + <Target Name="_RegenGlobalObjects" + DependsOnTargets="FindPythonForBuild"> + <Message Text="Regenerate Global Objects" Importance="high" /> + <Exec Command="$(PythonForBuild) Tools\build\generate_global_objects.py" + WorkingDirectory="$(PySourcePath)" /> + </Target> + <Target Name="Regen" Condition="$(Configuration) != 'PGUpdate'" - DependsOnTargets="_TouchRegenSources;_RegenPegen;_RegenAST_H;_RegenOpcodes;_RegenTokens;_RegenKeywords"> + DependsOnTargets="_TouchRegenSources;_RegenPegen;_RegenAST_H;_RegenOpcodes;_RegenTokens;_RegenKeywords;_RegenGlobalObjects"> <Message Text="Generated sources are up to date" Importance="high" /> </Target> @@ -97,8 +104,9 @@ <_LicenseSources Include="$(PySourcePath)LICENSE; $(PySourcePath)PC\crtlicense.txt; $(bz2Dir)LICENSE; - $(opensslOutDir)LICENSE; $(libffiDir)LICENSE;" /> + <_LicenseSources Include="$(opensslOutDir)LICENSE.txt" Condition="Exists('$(opensslOutDir)LICENSE.txt')" /> + <_LicenseSources Include="$(opensslOutDir)LICENSE" Condition="!Exists('$(opensslOutDir)LICENSE.txt')" /> <_LicenseSources Include="$(tcltkDir)tcllicense.terms; $(tcltkDir)tklicense.terms; $(tcltkDir)tixlicense.terms" Condition="$(IncludeTkinter)" /> diff --git a/PCbuild/rt.bat b/PCbuild/rt.bat index f15e3e23..29813c5a 100644 --- a/PCbuild/rt.bat +++ b/PCbuild/rt.bat @@ -1,78 +1,78 @@ -@echo off -rem Run Tests. Run the regression test suite. -rem Usage: rt [-d] [-O] [-q] [-x64] regrtest_args -rem -d Run Debug build (python_d.exe). Else release build. -rem -O Run python.exe or python_d.exe (see -d) with -O. -rem -q "quick" -- normally the tests are run twice, the first time -rem after deleting all the .pyc files reachable from Lib/. -rem -q runs the tests just once, and without deleting .pyc files. -rem -p <Win32|x64|ARM|ARM64> or -win32, -x64, -arm32, -arm64 -rem Run the specified architecture of python (or python_d if -d -rem was specified). If omitted, uses %PREFIX% if set or 64-bit. -rem All leading instances of these switches are shifted off, and -rem whatever remains (up to 9 arguments) is passed to regrtest.py. -rem For example, -rem rt -O -d -x test_thread -rem runs -rem python_d -O ../lib/test/regrtest.py -x test_thread -rem twice, and -rem rt -q -g test_binascii -rem runs -rem python_d ../lib/test/regrtest.py -g test_binascii -rem to generate the expected-output file for binascii quickly. -rem -rem Confusing: if you want to pass a comma-separated list, like -rem -u network,largefile -rem then you have to quote it on the rt line, like -rem rt -u "network,largefile" - -setlocal - -set pcbuild=%~dp0 -set suffix= -set qmode= -set dashO= -set regrtestargs= -set exe= - -:CheckOpts -if "%1"=="-O" (set dashO=-O) & shift & goto CheckOpts -if "%1"=="-q" (set qmode=yes) & shift & goto CheckOpts -if "%1"=="-d" (set suffix=_d) & shift & goto CheckOpts -if "%1"=="-win32" (set prefix=%pcbuild%win32) & shift & goto CheckOpts -if "%1"=="-x64" (set prefix=%pcbuild%amd64) & shift & goto CheckOpts -if "%1"=="-arm64" (set prefix=%pcbuild%arm64) & shift & goto CheckOpts -if "%1"=="-arm32" (set prefix=%pcbuild%arm32) & shift & goto CheckOpts -if "%1"=="-p" (call :SetPlatform %~2) & shift & shift & goto CheckOpts -if NOT "%1"=="" (set regrtestargs=%regrtestargs% %1) & shift & goto CheckOpts - -if not defined prefix set prefix=%pcbuild%amd64 -set exe=%prefix%\python%suffix%.exe -set cmd="%exe%" %dashO% -u -Wd -E -bb -m test %regrtestargs% -if defined qmode goto Qmode - -echo Deleting .pyc files ... -"%exe%" "%pcbuild%rmpyc.py" - -echo Cleaning _pth files ... -if exist %prefix%\*._pth del %prefix%\*._pth - -echo on -%cmd% -@echo off - -echo About to run again without deleting .pyc first: -pause -goto Qmode - -:SetPlatform -if /I %1 EQU Win32 (set prefix=%pcbuild%win32) & exit /B 0 -if /I %1 EQU x64 (set prefix=%pcbuild%amd64) & exit /B 0 -if /I %1 EQU ARM64 (set prefix=%pcbuild%arm64) & exit /B 0 -if /I %1 EQU ARM (set prefix=%pcbuild%arm32) & exit /B 0 -echo Invalid platform "%1" -exit /B 1 - -:Qmode -echo on -%cmd% +@echo off +rem Run Tests. Run the regression test suite. +rem Usage: rt [-d] [-O] [-q] [-x64] regrtest_args +rem -d Run Debug build (python_d.exe). Else release build. +rem -O Run python.exe or python_d.exe (see -d) with -O. +rem -q "quick" -- normally the tests are run twice, the first time +rem after deleting all the .pyc files reachable from Lib/. +rem -q runs the tests just once, and without deleting .pyc files. +rem -p <Win32|x64|ARM|ARM64> or -win32, -x64, -arm32, -arm64 +rem Run the specified architecture of python (or python_d if -d +rem was specified). If omitted, uses %PREFIX% if set or 64-bit. +rem All leading instances of these switches are shifted off, and +rem whatever remains (up to 9 arguments) is passed to regrtest.py. +rem For example, +rem rt -O -d -x test_thread +rem runs +rem python_d -O ../lib/test/regrtest.py -x test_thread +rem twice, and +rem rt -q -g test_binascii +rem runs +rem python_d ../lib/test/regrtest.py -g test_binascii +rem to generate the expected-output file for binascii quickly. +rem +rem Confusing: if you want to pass a comma-separated list, like +rem -u network,largefile +rem then you have to quote it on the rt line, like +rem rt -u "network,largefile" + +setlocal + +set pcbuild=%~dp0 +set suffix= +set qmode= +set dashO= +set regrtestargs= +set exe= + +:CheckOpts +if "%1"=="-O" (set dashO=-O) & shift & goto CheckOpts +if "%1"=="-q" (set qmode=yes) & shift & goto CheckOpts +if "%1"=="-d" (set suffix=_d) & shift & goto CheckOpts +if "%1"=="-win32" (set prefix=%pcbuild%win32) & shift & goto CheckOpts +if "%1"=="-x64" (set prefix=%pcbuild%amd64) & shift & goto CheckOpts +if "%1"=="-arm64" (set prefix=%pcbuild%arm64) & shift & goto CheckOpts +if "%1"=="-arm32" (set prefix=%pcbuild%arm32) & shift & goto CheckOpts +if "%1"=="-p" (call :SetPlatform %~2) & shift & shift & goto CheckOpts +if NOT "%1"=="" (set regrtestargs=%regrtestargs% %1) & shift & goto CheckOpts + +if not defined prefix set prefix=%pcbuild%amd64 +set exe=%prefix%\python%suffix%.exe +set cmd="%exe%" %dashO% -u -Wd -E -bb -m test %regrtestargs% +if defined qmode goto Qmode + +echo Deleting .pyc files ... +"%exe%" "%pcbuild%rmpyc.py" + +echo Cleaning _pth files ... +if exist %prefix%\*._pth del %prefix%\*._pth + +echo on +%cmd% +@echo off + +echo About to run again without deleting .pyc first: +pause +goto Qmode + +:SetPlatform +if /I %1 EQU Win32 (set prefix=%pcbuild%win32) & exit /B 0 +if /I %1 EQU x64 (set prefix=%pcbuild%amd64) & exit /B 0 +if /I %1 EQU ARM64 (set prefix=%pcbuild%arm64) & exit /B 0 +if /I %1 EQU ARM (set prefix=%pcbuild%arm32) & exit /B 0 +echo Invalid platform "%1" +exit /B 1 + +:Qmode +echo on +%cmd% diff --git a/PCbuild/select.vcxproj b/PCbuild/select.vcxproj index 65297ac3..750a7139 100644 --- a/PCbuild/select.vcxproj +++ b/PCbuild/select.vcxproj @@ -1,113 +1,113 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|ARM"> - <Configuration>Debug</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|ARM64"> - <Configuration>Debug</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM64"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|Win32"> - <Configuration>PGInstrument</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|x64"> - <Configuration>PGInstrument</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM64"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|Win32"> - <Configuration>PGUpdate</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|x64"> - <Configuration>PGUpdate</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM"> - <Configuration>Release</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM64"> - <Configuration>Release</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectGuid>{18CAE28C-B454-46C1-87A0-493D91D97F03}</ProjectGuid> - <RootNamespace>select</RootNamespace> - </PropertyGroup> - <Import Project="python.props" /> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>NotSet</CharacterSet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <PropertyGroup> - <TargetExt>.pyd</TargetExt> - </PropertyGroup> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="pyproject.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup> - <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> - </PropertyGroup> - <ItemDefinitionGroup> - <Link> - <AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies> - </Link> - </ItemDefinitionGroup> - <ItemGroup> - <ClCompile Include="..\Modules\selectmodule.c" /> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\python_nt.rc" /> - </ItemGroup> - <ItemGroup> - <ProjectReference Include="pythoncore.vcxproj"> - <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> - <ReferenceOutputAssembly>false</ReferenceOutputAssembly> - </ProjectReference> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|ARM"> + <Configuration>Debug</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|ARM64"> + <Configuration>Debug</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM64"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|Win32"> + <Configuration>PGInstrument</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|x64"> + <Configuration>PGInstrument</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM64"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|Win32"> + <Configuration>PGUpdate</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|x64"> + <Configuration>PGUpdate</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM"> + <Configuration>Release</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM64"> + <Configuration>Release</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{18CAE28C-B454-46C1-87A0-493D91D97F03}</ProjectGuid> + <RootNamespace>select</RootNamespace> + </PropertyGroup> + <Import Project="python.props" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <CharacterSet>NotSet</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <PropertyGroup> + <TargetExt>.pyd</TargetExt> + </PropertyGroup> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="pyproject.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> + </PropertyGroup> + <ItemDefinitionGroup> + <Link> + <AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\Modules\selectmodule.c" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_nt.rc" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="pythoncore.vcxproj"> + <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> </Project> \ No newline at end of file diff --git a/PCbuild/select.vcxproj.filters b/PCbuild/select.vcxproj.filters index ae7799a0..5354820d 100644 --- a/PCbuild/select.vcxproj.filters +++ b/PCbuild/select.vcxproj.filters @@ -1,21 +1,21 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <Filter Include="Source Files"> - <UniqueIdentifier>{98346077-900c-4c7a-852f-a23470e37b40}</UniqueIdentifier> - </Filter> - <Filter Include="Resource Files"> - <UniqueIdentifier>{b47a8e6c-47c0-4490-aa91-1a3624a0905c}</UniqueIdentifier> - </Filter> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\Modules\selectmodule.c"> - <Filter>Source Files</Filter> - </ClCompile> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\python_nt.rc"> - <Filter>Resource Files</Filter> - </ResourceCompile> - </ItemGroup> +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{98346077-900c-4c7a-852f-a23470e37b40}</UniqueIdentifier> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{b47a8e6c-47c0-4490-aa91-1a3624a0905c}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\Modules\selectmodule.c"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_nt.rc"> + <Filter>Resource Files</Filter> + </ResourceCompile> + </ItemGroup> </Project> \ No newline at end of file diff --git a/PCbuild/sqlite3.vcxproj b/PCbuild/sqlite3.vcxproj index 5a42b981..c502d518 100644 --- a/PCbuild/sqlite3.vcxproj +++ b/PCbuild/sqlite3.vcxproj @@ -1,121 +1,121 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|ARM"> - <Configuration>Debug</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|ARM64"> - <Configuration>Debug</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM64"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|Win32"> - <Configuration>PGInstrument</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|x64"> - <Configuration>PGInstrument</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM64"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|Win32"> - <Configuration>PGUpdate</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|x64"> - <Configuration>PGUpdate</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM"> - <Configuration>Release</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM64"> - <Configuration>Release</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectGuid>{A1A295E5-463C-437F-81CA-1F32367685DA}</ProjectGuid> - <RootNamespace>sqlite3</RootNamespace> - <TargetExt>.pyd</TargetExt> - <SupportPGO>false</SupportPGO> - </PropertyGroup> - <Import Project="python.props" /> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>NotSet</CharacterSet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="pyproject.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup> - <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> - <_SqliteVersion>$([System.Text.RegularExpressions.Regex]::Match(`$(sqlite3Dir)`, `((\d+)\.(\d+)\.(\d+)\.(\d+))\\?$`).Groups)</_SqliteVersion> - <SqliteVersion>$(_SqliteVersion.Split(`;`)[1])</SqliteVersion> - <SqliteMajorVersion>$(_SqliteVersion.Split(`;`)[2])</SqliteMajorVersion> - <SqliteMinorVersion>$(_SqliteVersion.Split(`;`)[3])</SqliteMinorVersion> - <SqliteMicroVersion>$(_SqliteVersion.Split(`;`)[4])</SqliteMicroVersion> - <SqlitePatchVersion>$(_SqliteVersion.Split(`;`)[5])</SqlitePatchVersion> - </PropertyGroup> - <ItemDefinitionGroup> - <ClCompile> - <AdditionalIncludeDirectories>$(sqlite3Dir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>SQLITE_ENABLE_MATH_FUNCTIONS;SQLITE_ENABLE_FTS4;SQLITE_ENABLE_FTS5;SQLITE_ENABLE_RTREE;SQLITE_OMIT_AUTOINIT;SQLITE_API=__declspec(dllexport);%(PreprocessorDefinitions)</PreprocessorDefinitions> - <WarningLevel>Level1</WarningLevel> - </ClCompile> - <ResourceCompile> - <PreprocessorDefinitions>SQLITE_VERSION=$(SqliteVersion);SQLITE_MAJOR_VERSION=$(SqliteMajorVersion);SQLITE_MINOR_VERSION=$(SqliteMinorVersion);SQLITE_MICRO_VERSION=$(SqliteMicroVersion);SQLITE_PATCH_VERSION=$(SqlitePatchVersion);%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ResourceCompile> - </ItemDefinitionGroup> - <ItemGroup> - <ClInclude Include="$(sqlite3Dir)\sqlite3.h" /> - <ClInclude Include="$(sqlite3Dir)\sqlite3ext.h" /> - </ItemGroup> - <ItemGroup> - <ClCompile Include="$(sqlite3Dir)\sqlite3.c" /> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\sqlite3.rc" /> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> -</Project> +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|ARM"> + <Configuration>Debug</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|ARM64"> + <Configuration>Debug</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM64"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|Win32"> + <Configuration>PGInstrument</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|x64"> + <Configuration>PGInstrument</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM64"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|Win32"> + <Configuration>PGUpdate</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|x64"> + <Configuration>PGUpdate</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM"> + <Configuration>Release</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM64"> + <Configuration>Release</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{A1A295E5-463C-437F-81CA-1F32367685DA}</ProjectGuid> + <RootNamespace>sqlite3</RootNamespace> + <TargetExt>.pyd</TargetExt> + <SupportPGO>false</SupportPGO> + </PropertyGroup> + <Import Project="python.props" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <CharacterSet>NotSet</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="pyproject.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> + <_SqliteVersion>$([System.Text.RegularExpressions.Regex]::Match(`$(sqlite3Dir)`, `((\d+)\.(\d+)\.(\d+)\.(\d+))\\?$`).Groups)</_SqliteVersion> + <SqliteVersion>$(_SqliteVersion.Split(`;`)[1])</SqliteVersion> + <SqliteMajorVersion>$(_SqliteVersion.Split(`;`)[2])</SqliteMajorVersion> + <SqliteMinorVersion>$(_SqliteVersion.Split(`;`)[3])</SqliteMinorVersion> + <SqliteMicroVersion>$(_SqliteVersion.Split(`;`)[4])</SqliteMicroVersion> + <SqlitePatchVersion>$(_SqliteVersion.Split(`;`)[5])</SqlitePatchVersion> + </PropertyGroup> + <ItemDefinitionGroup> + <ClCompile> + <AdditionalIncludeDirectories>$(sqlite3Dir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>SQLITE_ENABLE_MATH_FUNCTIONS;SQLITE_ENABLE_FTS4;SQLITE_ENABLE_FTS5;SQLITE_ENABLE_RTREE;SQLITE_OMIT_AUTOINIT;SQLITE_API=__declspec(dllexport);%(PreprocessorDefinitions)</PreprocessorDefinitions> + <WarningLevel>Level1</WarningLevel> + </ClCompile> + <ResourceCompile> + <PreprocessorDefinitions>SQLITE_VERSION=$(SqliteVersion);SQLITE_MAJOR_VERSION=$(SqliteMajorVersion);SQLITE_MINOR_VERSION=$(SqliteMinorVersion);SQLITE_MICRO_VERSION=$(SqliteMicroVersion);SQLITE_PATCH_VERSION=$(SqlitePatchVersion);%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + </ItemDefinitionGroup> + <ItemGroup> + <ClInclude Include="$(sqlite3Dir)\sqlite3.h" /> + <ClInclude Include="$(sqlite3Dir)\sqlite3ext.h" /> + </ItemGroup> + <ItemGroup> + <ClCompile Include="$(sqlite3Dir)\sqlite3.c" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\sqlite3.rc" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> diff --git a/PCbuild/sqlite3.vcxproj.filters b/PCbuild/sqlite3.vcxproj.filters index 5c1ea71f..76662ed6 100644 --- a/PCbuild/sqlite3.vcxproj.filters +++ b/PCbuild/sqlite3.vcxproj.filters @@ -1,32 +1,32 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <Filter Include="Header Files"> - <UniqueIdentifier>{ce5b649d-a6f7-4459-9425-c883795d79df}</UniqueIdentifier> - </Filter> - <Filter Include="Source Files"> - <UniqueIdentifier>{0e842fe2-176b-4e83-9d1f-0ad13a859efd}</UniqueIdentifier> - </Filter> - <Filter Include="Resource Files"> - <UniqueIdentifier>{0248795a-00c9-4090-ad61-55ae23438598}</UniqueIdentifier> - </Filter> - </ItemGroup> - <ItemGroup> - <ClInclude Include="$(sqlite3Dir)\sqlite3.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="$(sqlite3Dir)\sqlite3ext.h"> - <Filter>Header Files</Filter> - </ClInclude> - </ItemGroup> - <ItemGroup> - <ClCompile Include="$(sqlite3Dir)\sqlite3.c"> - <Filter>Source Files</Filter> - </ClCompile> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\sqlite3.rc"> - <Filter>Resource Files</Filter> - </ResourceCompile> - </ItemGroup> +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Header Files"> + <UniqueIdentifier>{ce5b649d-a6f7-4459-9425-c883795d79df}</UniqueIdentifier> + </Filter> + <Filter Include="Source Files"> + <UniqueIdentifier>{0e842fe2-176b-4e83-9d1f-0ad13a859efd}</UniqueIdentifier> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{0248795a-00c9-4090-ad61-55ae23438598}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClInclude Include="$(sqlite3Dir)\sqlite3.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="$(sqlite3Dir)\sqlite3ext.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <ClCompile Include="$(sqlite3Dir)\sqlite3.c"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\sqlite3.rc"> + <Filter>Resource Files</Filter> + </ResourceCompile> + </ItemGroup> </Project> \ No newline at end of file diff --git a/PCbuild/tcl.vcxproj b/PCbuild/tcl.vcxproj index 3b1f0f53..ab68db92 100644 --- a/PCbuild/tcl.vcxproj +++ b/PCbuild/tcl.vcxproj @@ -1,77 +1,77 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|Win32"> - <Configuration>PGInstrument</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|x64"> - <Configuration>PGInstrument</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|Win32"> - <Configuration>PGUpdate</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|x64"> - <Configuration>PGUpdate</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM64"> - <Configuration>Release</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectGuid>{B5FD6F1D-129E-4BFF-9340-03606FAC7283}</ProjectGuid> - </PropertyGroup> - - <Import Project="python.props" /> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <Import Project="tcltk.props" /> - - <PropertyGroup Label="Configuration"> - <ConfigurationType>Makefile</ConfigurationType> - <OutDir>$(tcltkDir)</OutDir> - <TargetPath>$(OutDir)bin\$(tclDLLName)</TargetPath> - </PropertyGroup> - - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - - <PropertyGroup> - <TclOpts>msvcrt</TclOpts> - <TclOpts Condition="$(Configuration) == 'Debug'">symbols,msvcrt</TclOpts> - <TclDirs>BUILDDIRTOP="$(BuildDirTop)" INSTALLDIR="$(OutDir.TrimEnd(`\`))" INSTALL_DIR="$(OutDir.TrimEnd(`\`))"</TclDirs> - <DebugFlags Condition="'$(Configuration)' == 'Debug'">DEBUGFLAGS="-wd4456 -wd4457 -wd4458 -wd4459 -wd4996"</DebugFlags> - <WarningsFlags>WARNINGS="-W3 -wd4311 -wd4312"</WarningsFlags> - <NMakeBuildCommandLine>setlocal -set VCINSTALLDIR=$(VCInstallDir) -cd /D "$(tclDir)win" -nmake -f makefile.vc MACHINE=$(TclMachine) OPTS=$(TclOpts) $(TclDirs) $(DebugFlags) $(WarningsFlags) TCLSH_NATIVE="$(tclWin32Exe)" core shell dlls -nmake -f makefile.vc MACHINE=$(TclMachine) OPTS=$(TclOpts) $(TclDirs) $(DebugFlags) $(WarningsFlags) TCLSH_NATIVE="$(tclWin32Exe)" install-binaries install-libraries -copy /Y ..\license.terms "$(OutDir)\tcllicense.terms" -</NMakeBuildCommandLine> - </PropertyGroup> - - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - - <Target Name="Clean" /> - - <Target Name="ResolveAssemblyReferences" /> +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|Win32"> + <Configuration>PGInstrument</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|x64"> + <Configuration>PGInstrument</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|Win32"> + <Configuration>PGUpdate</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|x64"> + <Configuration>PGUpdate</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM64"> + <Configuration>Release</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{B5FD6F1D-129E-4BFF-9340-03606FAC7283}</ProjectGuid> + </PropertyGroup> + + <Import Project="python.props" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <Import Project="tcltk.props" /> + + <PropertyGroup Label="Configuration"> + <ConfigurationType>Makefile</ConfigurationType> + <OutDir>$(tcltkDir)</OutDir> + <TargetPath>$(OutDir)bin\$(tclDLLName)</TargetPath> + </PropertyGroup> + + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + + <PropertyGroup> + <TclOpts>msvcrt</TclOpts> + <TclOpts Condition="$(Configuration) == 'Debug'">symbols,msvcrt</TclOpts> + <TclDirs>BUILDDIRTOP="$(BuildDirTop)" INSTALLDIR="$(OutDir.TrimEnd(`\`))" INSTALL_DIR="$(OutDir.TrimEnd(`\`))"</TclDirs> + <DebugFlags Condition="'$(Configuration)' == 'Debug'">DEBUGFLAGS="-wd4456 -wd4457 -wd4458 -wd4459 -wd4996"</DebugFlags> + <WarningsFlags>WARNINGS="-W3 -wd4311 -wd4312"</WarningsFlags> + <NMakeBuildCommandLine>setlocal +set VCINSTALLDIR=$(VCInstallDir) +cd /D "$(tclDir)win" +nmake -f makefile.vc MACHINE=$(TclMachine) OPTS=$(TclOpts) $(TclDirs) $(DebugFlags) $(WarningsFlags) TCLSH_NATIVE="$(tclWin32Exe)" core shell dlls +nmake -f makefile.vc MACHINE=$(TclMachine) OPTS=$(TclOpts) $(TclDirs) $(DebugFlags) $(WarningsFlags) TCLSH_NATIVE="$(tclWin32Exe)" install-binaries install-libraries +copy /Y ..\license.terms "$(OutDir)\tcllicense.terms" +</NMakeBuildCommandLine> + </PropertyGroup> + + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + + <Target Name="Clean" /> + + <Target Name="ResolveAssemblyReferences" /> </Project> \ No newline at end of file diff --git a/PCbuild/tcltk.props b/PCbuild/tcltk.props index 399fadfe..9d5189b3 100644 --- a/PCbuild/tcltk.props +++ b/PCbuild/tcltk.props @@ -1,66 +1,67 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <Import Project="pyproject.props" Condition="$(__PyProject_Props_Imported) != 'true'" /> - <PropertyGroup> - <TclVersion Condition="$(TclVersion) == ''">8.6.12.1</TclVersion> - <TkVersion Condition="$(TkVersion) == ''">$(TclVersion)</TkVersion> - <TixVersion Condition="$(TixVersion) == ''">8.4.3.6</TixVersion> - <TclMajorVersion>$([System.Version]::Parse($(TclVersion)).Major)</TclMajorVersion> - <TclMinorVersion>$([System.Version]::Parse($(TclVersion)).Minor)</TclMinorVersion> - <TclPatchLevel>$([System.Version]::Parse($(TclVersion)).Build)</TclPatchLevel> - <TclRevision>$([System.Version]::Parse($(TclVersion)).Revision)</TclRevision> - <TkMajorVersion>$([System.Version]::Parse($(TkVersion)).Major)</TkMajorVersion> - <TkMinorVersion>$([System.Version]::Parse($(TkVersion)).Minor)</TkMinorVersion> - <TkPatchLevel>$([System.Version]::Parse($(TkVersion)).Build)</TkPatchLevel> - <TkRevision>$([System.Version]::Parse($(TkVersion)).Revision)</TkRevision> - <TixMajorVersion>$([System.Version]::Parse($(TixVersion)).Major)</TixMajorVersion> - <TixMinorVersion>$([System.Version]::Parse($(TixVersion)).Minor)</TixMinorVersion> - <TixPatchLevel>$([System.Version]::Parse($(TixVersion)).Build)</TixPatchLevel> - <TixRevision>$([System.Version]::Parse($(TixVersion)).Revision)</TixRevision> - <tclDir Condition="$(tclDir) == ''">$(ExternalsDir)tcl-core-$(TclVersion)\</tclDir> - <tkDir Condition="$(tkDir) == ''">$(ExternalsDir)tk-$(TkVersion)\</tkDir> - <tixDir Condition="$(tixDir) == ''">$(ExternalsDir)tix-$(TixVersion)\</tixDir> - <tcltkDir Condition="$(tcltkDir) == ''">$(ExternalsDir)tcltk-$(TclVersion)\$(ArchName)\</tcltkDir> - <tclWin32Exe Condition="$(Platform) == 'Win32'">$(tcltkDir)\bin\tclsh$(TclMajorVersion)$(TclMinorVersion)t.exe</tclWin32Exe> - <tclWin32Exe Condition="$(Platform) != 'Win32'">$(tcltkDir)\..\win32\bin\tclsh$(TclMajorVersion)$(TclMinorVersion)t.exe</tclWin32Exe> - - <!--<TclDebugExt Condition="'$(Configuration)' == 'Debug'">g</TclDebugExt>--> - <tclDLLName>tcl$(TclMajorVersion)$(TclMinorVersion)t$(TclDebugExt).dll</tclDLLName> - <tclLibName>tcl$(TclMajorVersion)$(TclMinorVersion)t$(TclDebugExt).lib</tclLibName> - <tclShExeName>tclsh$(TclMajorVersion)$(TclMinorVersion)t$(TclDebugExt).exe</tclShExeName> - <tkDLLName>tk$(TkMajorVersion)$(TkMinorVersion)t$(TclDebugExt).dll</tkDLLName> - <tkLibName>tk$(TkMajorVersion)$(TkMinorVersion)t$(TclDebugExt).lib</tkLibName> - <tixDLLName>tix$(TixMajorVersion)$(TixMinorVersion)$(TclDebugExt).dll</tixDLLName> - <tixDLLPath>$(tcltkDir)lib\tix$(TixMajorVersion).$(TixMinorVersion).$(TixPatchLevel)\$(tixDLLName)</tixDLLPath> - <tcltkLib>$(tcltkDir)lib\tcl$(TclMajorVersion)$(TclMinorVersion)t$(TclDebugExt).lib;$(tcltkDir)lib\tk$(TkMajorVersion)$(TkMinorVersion)t$(TclDebugExt).lib</tcltkLib> - <TclMachine>IX86</TclMachine> - <TclMachine Condition="'$(Platform)' == 'x64'">AMD64</TclMachine> - <TclMachine Condition="'$(Platform)' == 'ARM64'">ARM64</TclMachine> - <TclVersions>TCL_MAJOR_VERSION=$(TclMajorVersion) TCL_MINOR_VERSION=$(TclMinorVersion) TCL_PATCH_LEVEL=$(TclPatchLevel)</TclVersions> - <TclShortVersions>TCL_MAJOR=$(TclMajorVersion) TCL_MINOR=$(TclMinorVersion) TCL_PATCH=$(TclPatchLevel)</TclShortVersions> - <TkVersions>TK_MAJOR_VERSION=$(TkMajorVersion) TK_MINOR_VERSION=$(TkMinorVersion) TK_PATCH_LEVEL=$(TkPatchLevel)</TkVersions> - - <BuildDirTop>Release</BuildDirTop> - <BuildDirTop Condition="$(Configuration) == 'Debug'">Debug</BuildDirTop> - <BuildDirTop Condition="$(TclMachine) != 'IX86'">$(BuildDirTop)_$(TclMachine)</BuildDirTop> - <BuildDirTop Condition="$(PlatformToolset.StartsWith('v14'))">$(BuildDirTop)_VC13</BuildDirTop> - <BuildDirTop Condition="$(PlatformToolset) == 'v120'">$(BuildDirTop)_VC12</BuildDirTop> - <BuildDirTop Condition="$(PlatformToolset) == 'v110'">$(BuildDirTop)_VC11</BuildDirTop> - <BuildDirTop Condition="$(PlatformToolset) == 'v100'">$(BuildDirTop)_VC10</BuildDirTop> - </PropertyGroup> - - <!-- - Helper target for copying the lib to a specific directory. - - Using "msbuild tcltk.props /t:CopyTclTkLib /p:OutDir=..." is generally - easier than trying to extract the value of $(tcltkdir). - --> - <Target Name="CopyTclTkLib"> - <ItemGroup> - <_TclTkLib Include="$(tcltkdir)\lib\**\*" /> - </ItemGroup> - <Copy SourceFiles="@(_TclTkLib)" - DestinationFiles="$(OutDir)\%(RecursiveDir)\%(Filename)%(Extension)" - UseHardlinksIfPossible="true" /> - </Target> -</Project> +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="pyproject.props" Condition="$(__PyProject_Props_Imported) != 'true'" /> + <PropertyGroup> + <TclVersion Condition="$(TclVersion) == ''">8.6.13.0</TclVersion> + <TkVersion Condition="$(TkVersion) == ''">$(TclVersion)</TkVersion> + <TixVersion Condition="$(TixVersion) == ''">8.4.3.6</TixVersion> + <TclMajorVersion>$([System.Version]::Parse($(TclVersion)).Major)</TclMajorVersion> + <TclMinorVersion>$([System.Version]::Parse($(TclVersion)).Minor)</TclMinorVersion> + <TclPatchLevel>$([System.Version]::Parse($(TclVersion)).Build)</TclPatchLevel> + <TclRevision>$([System.Version]::Parse($(TclVersion)).Revision)</TclRevision> + <TkMajorVersion>$([System.Version]::Parse($(TkVersion)).Major)</TkMajorVersion> + <TkMinorVersion>$([System.Version]::Parse($(TkVersion)).Minor)</TkMinorVersion> + <TkPatchLevel>$([System.Version]::Parse($(TkVersion)).Build)</TkPatchLevel> + <TkRevision>$([System.Version]::Parse($(TkVersion)).Revision)</TkRevision> + <TixMajorVersion>$([System.Version]::Parse($(TixVersion)).Major)</TixMajorVersion> + <TixMinorVersion>$([System.Version]::Parse($(TixVersion)).Minor)</TixMinorVersion> + <TixPatchLevel>$([System.Version]::Parse($(TixVersion)).Build)</TixPatchLevel> + <TixRevision>$([System.Version]::Parse($(TixVersion)).Revision)</TixRevision> + <tclDir Condition="$(tclDir) == ''">$(ExternalsDir)tcl-core-$(TclVersion)\</tclDir> + <tkDir Condition="$(tkDir) == ''">$(ExternalsDir)tk-$(TkVersion)\</tkDir> + <tixDir Condition="$(tixDir) == ''">$(ExternalsDir)tix-$(TixVersion)\</tixDir> + <tcltkDir Condition="$(tcltkDir) == ''">$(ExternalsDir)tcltk-$(TclVersion)\$(ArchName)\</tcltkDir> + <tclWin32Exe Condition="$(Platform) == 'Win32'">$(tcltkDir)\bin\tclsh$(TclMajorVersion)$(TclMinorVersion)t.exe</tclWin32Exe> + <tclWin32Exe Condition="$(Platform) != 'Win32'">$(tcltkDir)\..\win32\bin\tclsh$(TclMajorVersion)$(TclMinorVersion)t.exe</tclWin32Exe> + + <!--<TclDebugExt Condition="'$(Configuration)' == 'Debug'">g</TclDebugExt>--> + <tclDLLName>tcl$(TclMajorVersion)$(TclMinorVersion)t$(TclDebugExt).dll</tclDLLName> + <tclLibName>tcl$(TclMajorVersion)$(TclMinorVersion)t$(TclDebugExt).lib</tclLibName> + <tclShExeName>tclsh$(TclMajorVersion)$(TclMinorVersion)t$(TclDebugExt).exe</tclShExeName> + <tkDLLName>tk$(TkMajorVersion)$(TkMinorVersion)t$(TclDebugExt).dll</tkDLLName> + <tkLibName>tk$(TkMajorVersion)$(TkMinorVersion)t$(TclDebugExt).lib</tkLibName> + <tclZlibDLLName>zlib1.dll</tclZlibDLLName> + <tixDLLName>tix$(TixMajorVersion)$(TixMinorVersion)$(TclDebugExt).dll</tixDLLName> + <tixDLLPath>$(tcltkDir)lib\tix$(TixMajorVersion).$(TixMinorVersion).$(TixPatchLevel)\$(tixDLLName)</tixDLLPath> + <tcltkLib>$(tcltkDir)lib\tcl$(TclMajorVersion)$(TclMinorVersion)t$(TclDebugExt).lib;$(tcltkDir)lib\tk$(TkMajorVersion)$(TkMinorVersion)t$(TclDebugExt).lib</tcltkLib> + <TclMachine>IX86</TclMachine> + <TclMachine Condition="'$(Platform)' == 'x64'">AMD64</TclMachine> + <TclMachine Condition="'$(Platform)' == 'ARM64'">ARM64</TclMachine> + <TclVersions>TCL_MAJOR_VERSION=$(TclMajorVersion) TCL_MINOR_VERSION=$(TclMinorVersion) TCL_PATCH_LEVEL=$(TclPatchLevel)</TclVersions> + <TclShortVersions>TCL_MAJOR=$(TclMajorVersion) TCL_MINOR=$(TclMinorVersion) TCL_PATCH=$(TclPatchLevel)</TclShortVersions> + <TkVersions>TK_MAJOR_VERSION=$(TkMajorVersion) TK_MINOR_VERSION=$(TkMinorVersion) TK_PATCH_LEVEL=$(TkPatchLevel)</TkVersions> + + <BuildDirTop>Release</BuildDirTop> + <BuildDirTop Condition="$(Configuration) == 'Debug'">Debug</BuildDirTop> + <BuildDirTop Condition="$(TclMachine) != 'IX86'">$(BuildDirTop)_$(TclMachine)</BuildDirTop> + <BuildDirTop Condition="$(PlatformToolset.StartsWith('v14'))">$(BuildDirTop)_VC13</BuildDirTop> + <BuildDirTop Condition="$(PlatformToolset) == 'v120'">$(BuildDirTop)_VC12</BuildDirTop> + <BuildDirTop Condition="$(PlatformToolset) == 'v110'">$(BuildDirTop)_VC11</BuildDirTop> + <BuildDirTop Condition="$(PlatformToolset) == 'v100'">$(BuildDirTop)_VC10</BuildDirTop> + </PropertyGroup> + + <!-- + Helper target for copying the lib to a specific directory. + + Using "msbuild tcltk.props /t:CopyTclTkLib /p:OutDir=..." is generally + easier than trying to extract the value of $(tcltkdir). + --> + <Target Name="CopyTclTkLib"> + <ItemGroup> + <_TclTkLib Include="$(tcltkdir)\lib\**\*" /> + </ItemGroup> + <Copy SourceFiles="@(_TclTkLib)" + DestinationFiles="$(OutDir)\%(RecursiveDir)\%(Filename)%(Extension)" + UseHardlinksIfPossible="true" /> + </Target> +</Project> diff --git a/PCbuild/tix.vcxproj b/PCbuild/tix.vcxproj index ae26a64e..48abcd27 100644 --- a/PCbuild/tix.vcxproj +++ b/PCbuild/tix.vcxproj @@ -1,101 +1,101 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|Win32"> - <Configuration>PGInstrument</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|x64"> - <Configuration>PGInstrument</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|Win32"> - <Configuration>PGUpdate</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|x64"> - <Configuration>PGUpdate</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM64"> - <Configuration>Release</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectGuid>{C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}</ProjectGuid> - <RootNamespace>tix</RootNamespace> - <SupportSigning>true</SupportSigning> - </PropertyGroup> - - <Import Project="python.props" /> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <Import Project="tcltk.props" /> - - <PropertyGroup Label="Configuration"> - <ConfigurationType>Makefile</ConfigurationType> - <OutDir>$(tcltkDir)</OutDir> - <TargetPath>$(tixDLLPath)</TargetPath> - </PropertyGroup> - - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - - <PropertyGroup> - <TixDirs>BUILDDIRTOP="$(BuildDirTop)" TCL_DIR="$(tclDir.TrimEnd(`\`))" TK_DIR="$(tkDir.TrimEnd(`\`))" INSTALL_DIR="$(OutDir.TrimEnd(`\`))" TCLSH_EXE="$(tclWin32Exe)"</TixDirs> - <DebugFlags Condition="'$(Configuration)' == 'Debug'">DEBUG=1 NODEBUG=0 TCL_DBGX=g TK_DBGX=g</DebugFlags> - <DebugFlags Condition="'$(Configuration)' != 'Debug'">DEBUG=0 NODEBUG=1</DebugFlags> - <CFlags>-c -W3 -nologo -MD -wd4028 -wd4090 -wd4244 -wd4267 -wd4312</CFlags> - <NMakeBuildCommandLine>setlocal -set VCINSTALLDIR=$(VCInstallDir) -cd /D "$(tixDir)win" -nmake /nologo -f makefile.vc MACHINE=$(TclMachine) cflags="$(CFlags)" $(DebugFlags) $(TclShortVersions) $(TixDirs) all install -copy /Y ..\license.terms "$(OutDir)\tixlicense.terms" -</NMakeBuildCommandLine> - <NMakeCleanCommandLine>rmdir /q/s "$(OutDir.TrimEnd(`\`))"</NMakeCleanCommandLine> - </PropertyGroup> - - <Target Name="SignFiles" AfterTargets="Build" Condition="$(_SignCommand) != ''"> - <ItemGroup> - <FilesToSign Include="$(OutDir)\bin\*.exe" /> - <FilesToSign Include="$(OutDir)\bin\*.dll" /> - </ItemGroup> - <Exec Command="$(_SignCommand) "%(FilesToSign.FullPath)"" ContinueOnError="true" /> - </Target> - - <ItemGroup> - <ProjectReference Include="tcl.vcxproj"> - <Project>{b5fd6f1d-129e-4bff-9340-03606fac7283}</Project> - <ReferenceOutputAssembly>false</ReferenceOutputAssembly> - </ProjectReference> - <ProjectReference Include="tk.vcxproj"> - <Project>{7e85eccf-a72c-4da4-9e52-884508e80ba1}</Project> - <ReferenceOutputAssembly>false</ReferenceOutputAssembly> - </ProjectReference> - </ItemGroup> - - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - - <Target Name="Clean" /> - <Target Name="CleanAll"> - <RemoveDir Directories="$(OutDir)" /> - <RemoveDir Directories="$(IntDir)" /> - </Target> - - <Target Name="ResolveAssemblyReferences" /> +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|Win32"> + <Configuration>PGInstrument</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|x64"> + <Configuration>PGInstrument</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|Win32"> + <Configuration>PGUpdate</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|x64"> + <Configuration>PGUpdate</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM64"> + <Configuration>Release</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}</ProjectGuid> + <RootNamespace>tix</RootNamespace> + <SupportSigning>true</SupportSigning> + </PropertyGroup> + + <Import Project="python.props" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <Import Project="tcltk.props" /> + + <PropertyGroup Label="Configuration"> + <ConfigurationType>Makefile</ConfigurationType> + <OutDir>$(tcltkDir)</OutDir> + <TargetPath>$(tixDLLPath)</TargetPath> + </PropertyGroup> + + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + + <PropertyGroup> + <TixDirs>BUILDDIRTOP="$(BuildDirTop)" TCL_DIR="$(tclDir.TrimEnd(`\`))" TK_DIR="$(tkDir.TrimEnd(`\`))" INSTALL_DIR="$(OutDir.TrimEnd(`\`))" TCLSH_EXE="$(tclWin32Exe)"</TixDirs> + <DebugFlags Condition="'$(Configuration)' == 'Debug'">DEBUG=1 NODEBUG=0 TCL_DBGX=g TK_DBGX=g</DebugFlags> + <DebugFlags Condition="'$(Configuration)' != 'Debug'">DEBUG=0 NODEBUG=1</DebugFlags> + <CFlags>-c -W3 -nologo -MD -wd4028 -wd4090 -wd4244 -wd4267 -wd4312</CFlags> + <NMakeBuildCommandLine>setlocal +set VCINSTALLDIR=$(VCInstallDir) +cd /D "$(tixDir)win" +nmake /nologo -f makefile.vc MACHINE=$(TclMachine) cflags="$(CFlags)" $(DebugFlags) $(TclShortVersions) $(TixDirs) all install +copy /Y ..\license.terms "$(OutDir)\tixlicense.terms" +</NMakeBuildCommandLine> + <NMakeCleanCommandLine>rmdir /q/s "$(OutDir.TrimEnd(`\`))"</NMakeCleanCommandLine> + </PropertyGroup> + + <Target Name="SignFiles" AfterTargets="Build" Condition="$(_SignCommand) != ''"> + <ItemGroup> + <FilesToSign Include="$(OutDir)\bin\*.exe" /> + <FilesToSign Include="$(OutDir)\bin\*.dll" /> + </ItemGroup> + <Exec Command="$(_SignCommand) "%(FilesToSign.FullPath)"" ContinueOnError="true" /> + </Target> + + <ItemGroup> + <ProjectReference Include="tcl.vcxproj"> + <Project>{b5fd6f1d-129e-4bff-9340-03606fac7283}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + <ProjectReference Include="tk.vcxproj"> + <Project>{7e85eccf-a72c-4da4-9e52-884508e80ba1}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + </ItemGroup> + + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + + <Target Name="Clean" /> + <Target Name="CleanAll"> + <RemoveDir Directories="$(OutDir)" /> + <RemoveDir Directories="$(IntDir)" /> + </Target> + + <Target Name="ResolveAssemblyReferences" /> </Project> \ No newline at end of file diff --git a/PCbuild/tk.vcxproj b/PCbuild/tk.vcxproj index 4ee3588e..b111969c 100644 --- a/PCbuild/tk.vcxproj +++ b/PCbuild/tk.vcxproj @@ -1,83 +1,83 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|Win32"> - <Configuration>PGInstrument</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|x64"> - <Configuration>PGInstrument</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|Win32"> - <Configuration>PGUpdate</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|x64"> - <Configuration>PGUpdate</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM64"> - <Configuration>Release</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectGuid>{7E85ECCF-A72C-4DA4-9E52-884508E80BA1}</ProjectGuid> - <RootNamespace>tk</RootNamespace> - </PropertyGroup> - - <Import Project="python.props" /> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <Import Project="tcltk.props" /> - - <PropertyGroup Label="Configuration"> - <ConfigurationType>Makefile</ConfigurationType> - <OutDir>$(tcltkDir)</OutDir> - <TargetPath>$(OutDir)bin\$(tkDLLName)</TargetPath> - </PropertyGroup> - - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - - <PropertyGroup> - <TkOpts>msvcrt</TkOpts> - <TkOpts Condition="$(Configuration) == 'Debug'">symbols,msvcrt</TkOpts> - <TkDirs>BUILDDIRTOP="$(BuildDirTop)" TCLDIR="$(tclDir.TrimEnd(`\`))" INSTALLDIR="$(OutDir.TrimEnd(`\`))"</TkDirs> - <DebugFlags Condition="'$(Configuration)' == 'Debug'">DEBUGFLAGS="-wd4456 -wd4457 -wd4458 -wd4459 -wd4996"</DebugFlags> - <WarningsFlags>WARNINGS="-W3 -wd4244 -wd4267 -wd4311 -wd4312 -wd4334"</WarningsFlags> - <NMakeBuildCommandLine>setlocal -set VCINSTALLDIR=$(VCInstallDir) -cd /D "$(tkDir)win" -nmake /nologo -f makefile.vc RC=rc MACHINE=$(TclMachine) OPTS=$(TkOpts) $(TkDirs) $(DebugFlags) $(WarningsFlags) TCLSH_NATIVE="$(tclWin32Exe)" all -nmake /nologo -f makefile.vc RC=rc MACHINE=$(TclMachine) OPTS=$(TkOpts) $(TkDirs) $(DebugFlags) $(WarningsFlags) TCLSH_NATIVE="$(tclWin32Exe)" install-binaries install-libraries -copy /Y ..\license.terms "$(OutDir)\tklicense.terms" -</NMakeBuildCommandLine> - </PropertyGroup> - <ItemGroup> - <ProjectReference Include="tcl.vcxproj"> - <Project>{b5fd6f1d-129e-4bff-9340-03606fac7283}</Project> - <ReferenceOutputAssembly>false</ReferenceOutputAssembly> - </ProjectReference> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - - <Target Name="Clean" /> - - <Target Name="ResolveAssemblyReferences" /> +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|Win32"> + <Configuration>PGInstrument</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|x64"> + <Configuration>PGInstrument</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|Win32"> + <Configuration>PGUpdate</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|x64"> + <Configuration>PGUpdate</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM64"> + <Configuration>Release</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{7E85ECCF-A72C-4DA4-9E52-884508E80BA1}</ProjectGuid> + <RootNamespace>tk</RootNamespace> + </PropertyGroup> + + <Import Project="python.props" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <Import Project="tcltk.props" /> + + <PropertyGroup Label="Configuration"> + <ConfigurationType>Makefile</ConfigurationType> + <OutDir>$(tcltkDir)</OutDir> + <TargetPath>$(OutDir)bin\$(tkDLLName)</TargetPath> + </PropertyGroup> + + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + + <PropertyGroup> + <TkOpts>msvcrt</TkOpts> + <TkOpts Condition="$(Configuration) == 'Debug'">symbols,msvcrt</TkOpts> + <TkDirs>BUILDDIRTOP="$(BuildDirTop)" TCLDIR="$(tclDir.TrimEnd(`\`))" INSTALLDIR="$(OutDir.TrimEnd(`\`))"</TkDirs> + <DebugFlags Condition="'$(Configuration)' == 'Debug'">DEBUGFLAGS="-wd4456 -wd4457 -wd4458 -wd4459 -wd4996"</DebugFlags> + <WarningsFlags>WARNINGS="-W3 -wd4244 -wd4267 -wd4311 -wd4312 -wd4334"</WarningsFlags> + <NMakeBuildCommandLine>setlocal +set VCINSTALLDIR=$(VCInstallDir) +cd /D "$(tkDir)win" +nmake /nologo -f makefile.vc RC=rc MACHINE=$(TclMachine) OPTS=$(TkOpts) $(TkDirs) $(DebugFlags) $(WarningsFlags) TCLSH_NATIVE="$(tclWin32Exe)" all +nmake /nologo -f makefile.vc RC=rc MACHINE=$(TclMachine) OPTS=$(TkOpts) $(TkDirs) $(DebugFlags) $(WarningsFlags) TCLSH_NATIVE="$(tclWin32Exe)" install-binaries install-libraries +copy /Y ..\license.terms "$(OutDir)\tklicense.terms" +</NMakeBuildCommandLine> + </PropertyGroup> + <ItemGroup> + <ProjectReference Include="tcl.vcxproj"> + <Project>{b5fd6f1d-129e-4bff-9340-03606fac7283}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + + <Target Name="Clean" /> + + <Target Name="ResolveAssemblyReferences" /> </Project> \ No newline at end of file diff --git a/PCbuild/unicodedata.vcxproj b/PCbuild/unicodedata.vcxproj index 9e53d4b1..addef753 100644 --- a/PCbuild/unicodedata.vcxproj +++ b/PCbuild/unicodedata.vcxproj @@ -1,113 +1,113 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|ARM"> - <Configuration>Debug</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|ARM64"> - <Configuration>Debug</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM64"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|Win32"> - <Configuration>PGInstrument</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|x64"> - <Configuration>PGInstrument</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM64"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|Win32"> - <Configuration>PGUpdate</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|x64"> - <Configuration>PGUpdate</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM"> - <Configuration>Release</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM64"> - <Configuration>Release</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectGuid>{ECC7CEAC-A5E5-458E-BB9E-2413CC847881}</ProjectGuid> - <RootNamespace>unicodedata</RootNamespace> - <Keyword>Win32Proj</Keyword> - </PropertyGroup> - <Import Project="python.props" /> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>NotSet</CharacterSet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <PropertyGroup> - <TargetExt>.pyd</TargetExt> - </PropertyGroup> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="pyproject.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup> - <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> - </PropertyGroup> - <ItemGroup> - <ClInclude Include="..\Modules\unicodedata_db.h" /> - <ClInclude Include="..\Modules\unicodename_db.h" /> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\Modules\unicodedata.c" /> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\python_nt.rc" /> - </ItemGroup> - <ItemGroup> - <ProjectReference Include="pythoncore.vcxproj"> - <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> - <ReferenceOutputAssembly>false</ReferenceOutputAssembly> - </ProjectReference> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|ARM"> + <Configuration>Debug</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|ARM64"> + <Configuration>Debug</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM64"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|Win32"> + <Configuration>PGInstrument</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|x64"> + <Configuration>PGInstrument</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM64"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|Win32"> + <Configuration>PGUpdate</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|x64"> + <Configuration>PGUpdate</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM"> + <Configuration>Release</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM64"> + <Configuration>Release</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{ECC7CEAC-A5E5-458E-BB9E-2413CC847881}</ProjectGuid> + <RootNamespace>unicodedata</RootNamespace> + <Keyword>Win32Proj</Keyword> + </PropertyGroup> + <Import Project="python.props" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <CharacterSet>NotSet</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <PropertyGroup> + <TargetExt>.pyd</TargetExt> + </PropertyGroup> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="pyproject.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> + </PropertyGroup> + <ItemGroup> + <ClInclude Include="..\Modules\unicodedata_db.h" /> + <ClInclude Include="..\Modules\unicodename_db.h" /> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\Modules\unicodedata.c" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_nt.rc" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="pythoncore.vcxproj"> + <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> </Project> \ No newline at end of file diff --git a/PCbuild/unicodedata.vcxproj.filters b/PCbuild/unicodedata.vcxproj.filters index 8498c03d..7ff97835 100644 --- a/PCbuild/unicodedata.vcxproj.filters +++ b/PCbuild/unicodedata.vcxproj.filters @@ -1,32 +1,32 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <Filter Include="Header Files"> - <UniqueIdentifier>{b939a8f1-ccd7-420a-974a-243606dccd74}</UniqueIdentifier> - </Filter> - <Filter Include="Source Files"> - <UniqueIdentifier>{e2c055bb-ec62-4bbc-aa1c-d88da4d4ad1c}</UniqueIdentifier> - </Filter> - <Filter Include="Resource Files"> - <UniqueIdentifier>{d04f3447-67b0-42aa-b84f-9fc0029d5af7}</UniqueIdentifier> - </Filter> - </ItemGroup> - <ItemGroup> - <ClInclude Include="..\Modules\unicodedata_db.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\Modules\unicodename_db.h"> - <Filter>Header Files</Filter> - </ClInclude> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\Modules\unicodedata.c"> - <Filter>Source Files</Filter> - </ClCompile> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\python_nt.rc"> - <Filter>Resource Files</Filter> - </ResourceCompile> - </ItemGroup> +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Header Files"> + <UniqueIdentifier>{b939a8f1-ccd7-420a-974a-243606dccd74}</UniqueIdentifier> + </Filter> + <Filter Include="Source Files"> + <UniqueIdentifier>{e2c055bb-ec62-4bbc-aa1c-d88da4d4ad1c}</UniqueIdentifier> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{d04f3447-67b0-42aa-b84f-9fc0029d5af7}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\Modules\unicodedata_db.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\Modules\unicodename_db.h"> + <Filter>Header Files</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\Modules\unicodedata.c"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_nt.rc"> + <Filter>Resource Files</Filter> + </ResourceCompile> + </ItemGroup> </Project> \ No newline at end of file diff --git a/PCbuild/venvlauncher.vcxproj b/PCbuild/venvlauncher.vcxproj index 183df740..123e84ec 100644 --- a/PCbuild/venvlauncher.vcxproj +++ b/PCbuild/venvlauncher.vcxproj @@ -1,117 +1,117 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|ARM"> - <Configuration>Debug</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|ARM64"> - <Configuration>Debug</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM64"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|Win32"> - <Configuration>PGInstrument</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|x64"> - <Configuration>PGInstrument</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM64"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|Win32"> - <Configuration>PGUpdate</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|x64"> - <Configuration>PGUpdate</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM"> - <Configuration>Release</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM64"> - <Configuration>Release</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectGuid>{494BAC80-A60C-43A9-99E7-ACB691CE2C4D}</ProjectGuid> - <RootNamespace>venvlauncher</RootNamespace> - <TargetName>venvlauncher</TargetName> - <SupportPGO>false</SupportPGO> - </PropertyGroup> - <Import Project="python.props" /> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <CharacterSet>MultiByte</CharacterSet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <PropertyGroup> - <MakeVersionInfoBeforeTarget>ClCompile</MakeVersionInfoBeforeTarget> - </PropertyGroup> - <ImportGroup Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="pyproject.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <ItemDefinitionGroup> - <ClCompile> - <PreprocessorDefinitions>_CONSOLE;VENV_REDIRECT;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - </ClCompile> - <ResourceCompile> - <PreprocessorDefinitions>PY_ICON;%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ResourceCompile> - <Link> - <AdditionalDependencies>version.lib;%(AdditionalDependencies)</AdditionalDependencies> - <SubSystem>Console</SubSystem> - </Link> - </ItemDefinitionGroup> - <ItemGroup> - <ClCompile Include="..\PC\launcher.c" /> - </ItemGroup> - <ItemGroup> - <None Include="..\PC\launcher.ico" /> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\pylauncher.rc" /> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> -</Project> +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|ARM"> + <Configuration>Debug</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|ARM64"> + <Configuration>Debug</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM64"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|Win32"> + <Configuration>PGInstrument</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|x64"> + <Configuration>PGInstrument</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM64"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|Win32"> + <Configuration>PGUpdate</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|x64"> + <Configuration>PGUpdate</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM"> + <Configuration>Release</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM64"> + <Configuration>Release</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{494BAC80-A60C-43A9-99E7-ACB691CE2C4D}</ProjectGuid> + <RootNamespace>venvlauncher</RootNamespace> + <TargetName>venvlauncher</TargetName> + <SupportPGO>false</SupportPGO> + </PropertyGroup> + <Import Project="python.props" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <PropertyGroup> + <MakeVersionInfoBeforeTarget>ClCompile</MakeVersionInfoBeforeTarget> + </PropertyGroup> + <ImportGroup Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="pyproject.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <ItemDefinitionGroup> + <ClCompile> + <PreprocessorDefinitions>_CONSOLE;VENV_REDIRECT;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <ResourceCompile> + <PreprocessorDefinitions>PY_ICON;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Link> + <AdditionalDependencies>version.lib;%(AdditionalDependencies)</AdditionalDependencies> + <SubSystem>Console</SubSystem> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\PC\launcher.c" /> + </ItemGroup> + <ItemGroup> + <None Include="..\PC\launcher.ico" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\pylauncher.rc" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> diff --git a/PCbuild/venvlauncher.vcxproj.filters b/PCbuild/venvlauncher.vcxproj.filters index b61b81e2..ec13936b 100644 --- a/PCbuild/venvlauncher.vcxproj.filters +++ b/PCbuild/venvlauncher.vcxproj.filters @@ -1,26 +1,26 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <Filter Include="Resource Files"> - <UniqueIdentifier>{8f3ab79e-3cba-4e6d-82b2-559ce946de58}</UniqueIdentifier> - </Filter> - <Filter Include="Source Files"> - <UniqueIdentifier>{4a2423af-e5d1-4c88-b308-d71b768977df}</UniqueIdentifier> - </Filter> - </ItemGroup> - <ItemGroup> - <None Include="..\PC\launcher.ico"> - <Filter>Resource Files</Filter> - </None> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\pylauncher.rc"> - <Filter>Resource Files</Filter> - </ResourceCompile> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\PC\launcher.c"> - <Filter>Source Files</Filter> - </ClCompile> - </ItemGroup> +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Resource Files"> + <UniqueIdentifier>{8f3ab79e-3cba-4e6d-82b2-559ce946de58}</UniqueIdentifier> + </Filter> + <Filter Include="Source Files"> + <UniqueIdentifier>{4a2423af-e5d1-4c88-b308-d71b768977df}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <None Include="..\PC\launcher.ico"> + <Filter>Resource Files</Filter> + </None> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\pylauncher.rc"> + <Filter>Resource Files</Filter> + </ResourceCompile> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\PC\launcher.c"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> </Project> \ No newline at end of file diff --git a/PCbuild/venvwlauncher.vcxproj b/PCbuild/venvwlauncher.vcxproj index 2f2f0039..b8504d5d 100644 --- a/PCbuild/venvwlauncher.vcxproj +++ b/PCbuild/venvwlauncher.vcxproj @@ -1,117 +1,117 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|ARM"> - <Configuration>Debug</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|ARM64"> - <Configuration>Debug</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM64"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|Win32"> - <Configuration>PGInstrument</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|x64"> - <Configuration>PGInstrument</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM64"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|Win32"> - <Configuration>PGUpdate</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|x64"> - <Configuration>PGUpdate</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM"> - <Configuration>Release</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM64"> - <Configuration>Release</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectGuid>{FDB84CBB-2FB6-47C8-A2D6-091E0833239D}</ProjectGuid> - <RootNamespace>venvwlauncher</RootNamespace> - <TargetName>venvwlauncher</TargetName> - <SupportPGO>false</SupportPGO> - </PropertyGroup> - <Import Project="python.props" /> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <CharacterSet>MultiByte</CharacterSet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <PropertyGroup> - <MakeVersionInfoBeforeTarget>ClCompile</MakeVersionInfoBeforeTarget> - </PropertyGroup> - <ImportGroup Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="pyproject.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <ItemDefinitionGroup> - <ClCompile> - <PreprocessorDefinitions>_WINDOWS;VENV_REDIRECT;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - </ClCompile> - <ResourceCompile> - <PreprocessorDefinitions>PYW_ICON;%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ResourceCompile> - <Link> - <AdditionalDependencies>version.lib;%(AdditionalDependencies)</AdditionalDependencies> - <SubSystem>Windows</SubSystem> - </Link> - </ItemDefinitionGroup> - <ItemGroup> - <ClCompile Include="..\PC\launcher.c" /> - </ItemGroup> - <ItemGroup> - <None Include="..\PC\launcher.ico" /> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\pylauncher.rc" /> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> -</Project> +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|ARM"> + <Configuration>Debug</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|ARM64"> + <Configuration>Debug</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM64"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|Win32"> + <Configuration>PGInstrument</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|x64"> + <Configuration>PGInstrument</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM64"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|Win32"> + <Configuration>PGUpdate</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|x64"> + <Configuration>PGUpdate</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM"> + <Configuration>Release</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM64"> + <Configuration>Release</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{FDB84CBB-2FB6-47C8-A2D6-091E0833239D}</ProjectGuid> + <RootNamespace>venvwlauncher</RootNamespace> + <TargetName>venvwlauncher</TargetName> + <SupportPGO>false</SupportPGO> + </PropertyGroup> + <Import Project="python.props" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <PropertyGroup> + <MakeVersionInfoBeforeTarget>ClCompile</MakeVersionInfoBeforeTarget> + </PropertyGroup> + <ImportGroup Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="pyproject.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <ItemDefinitionGroup> + <ClCompile> + <PreprocessorDefinitions>_WINDOWS;VENV_REDIRECT;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <ResourceCompile> + <PreprocessorDefinitions>PYW_ICON;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Link> + <AdditionalDependencies>version.lib;%(AdditionalDependencies)</AdditionalDependencies> + <SubSystem>Windows</SubSystem> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\PC\launcher.c" /> + </ItemGroup> + <ItemGroup> + <None Include="..\PC\launcher.ico" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\pylauncher.rc" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> diff --git a/PCbuild/venvwlauncher.vcxproj.filters b/PCbuild/venvwlauncher.vcxproj.filters index 94e96dac..8addc13e 100644 --- a/PCbuild/venvwlauncher.vcxproj.filters +++ b/PCbuild/venvwlauncher.vcxproj.filters @@ -1,26 +1,26 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <Filter Include="Resource Files"> - <UniqueIdentifier>{7683f248-9c32-4e72-a329-5bd84993f63a}</UniqueIdentifier> - </Filter> - <Filter Include="Source Files"> - <UniqueIdentifier>{61b34b26-ce53-405d-a743-b370ff505887}</UniqueIdentifier> - </Filter> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\PC\launcher.c"> - <Filter>Source Files</Filter> - </ClCompile> - </ItemGroup> - <ItemGroup> - <None Include="..\PC\launcher.ico"> - <Filter>Resource Files</Filter> - </None> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\pylauncher.rc"> - <Filter>Resource Files</Filter> - </ResourceCompile> - </ItemGroup> +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Resource Files"> + <UniqueIdentifier>{7683f248-9c32-4e72-a329-5bd84993f63a}</UniqueIdentifier> + </Filter> + <Filter Include="Source Files"> + <UniqueIdentifier>{61b34b26-ce53-405d-a743-b370ff505887}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\PC\launcher.c"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <None Include="..\PC\launcher.ico"> + <Filter>Resource Files</Filter> + </None> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\pylauncher.rc"> + <Filter>Resource Files</Filter> + </ResourceCompile> + </ItemGroup> </Project> \ No newline at end of file diff --git a/PCbuild/winsound.vcxproj b/PCbuild/winsound.vcxproj index bcd4d3e0..32cedc9b 100644 --- a/PCbuild/winsound.vcxproj +++ b/PCbuild/winsound.vcxproj @@ -1,115 +1,115 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|ARM"> - <Configuration>Debug</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|ARM64"> - <Configuration>Debug</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM64"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|Win32"> - <Configuration>PGInstrument</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|x64"> - <Configuration>PGInstrument</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM64"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|Win32"> - <Configuration>PGUpdate</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|x64"> - <Configuration>PGUpdate</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM"> - <Configuration>Release</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM64"> - <Configuration>Release</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectGuid>{28B5D777-DDF2-4B6B-B34F-31D938813856}</ProjectGuid> - <RootNamespace>winsound</RootNamespace> - <Keyword>Win32Proj</Keyword> - <SupportPGO>false</SupportPGO> - </PropertyGroup> - <Import Project="python.props" /> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>NotSet</CharacterSet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <PropertyGroup> - <TargetExt>.pyd</TargetExt> - </PropertyGroup> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="pyproject.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup> - <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> - </PropertyGroup> - <ItemDefinitionGroup> - <Link> - <AdditionalDependencies>winmm.lib;%(AdditionalDependencies)</AdditionalDependencies> - </Link> - </ItemDefinitionGroup> - <ItemGroup> - <ClCompile Include="..\PC\winsound.c" /> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\python_nt.rc" /> - </ItemGroup> - <ItemGroup> - <ProjectReference Include="pythoncore.vcxproj"> - <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> - <ReferenceOutputAssembly>false</ReferenceOutputAssembly> - </ProjectReference> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|ARM"> + <Configuration>Debug</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|ARM64"> + <Configuration>Debug</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM64"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|Win32"> + <Configuration>PGInstrument</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|x64"> + <Configuration>PGInstrument</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM64"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|Win32"> + <Configuration>PGUpdate</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|x64"> + <Configuration>PGUpdate</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM"> + <Configuration>Release</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM64"> + <Configuration>Release</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{28B5D777-DDF2-4B6B-B34F-31D938813856}</ProjectGuid> + <RootNamespace>winsound</RootNamespace> + <Keyword>Win32Proj</Keyword> + <SupportPGO>false</SupportPGO> + </PropertyGroup> + <Import Project="python.props" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <CharacterSet>NotSet</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <PropertyGroup> + <TargetExt>.pyd</TargetExt> + </PropertyGroup> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="pyproject.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> + </PropertyGroup> + <ItemDefinitionGroup> + <Link> + <AdditionalDependencies>winmm.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\PC\winsound.c" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_nt.rc" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="pythoncore.vcxproj"> + <Project>{cf7ac3d1-e2df-41d2-bea6-1e2556cdea26}</Project> + <ReferenceOutputAssembly>false</ReferenceOutputAssembly> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> </Project> \ No newline at end of file diff --git a/PCbuild/winsound.vcxproj.filters b/PCbuild/winsound.vcxproj.filters index d8c845dd..67758026 100644 --- a/PCbuild/winsound.vcxproj.filters +++ b/PCbuild/winsound.vcxproj.filters @@ -1,22 +1,22 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <Filter Include="Source Files"> - <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> - <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> - </Filter> - <Filter Include="Resource Files"> - <UniqueIdentifier>{6be42502-398f-4bec-8677-8809a2da0eef}</UniqueIdentifier> - </Filter> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\PC\winsound.c"> - <Filter>Source Files</Filter> - </ClCompile> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\PC\python_nt.rc"> - <Filter>Resource Files</Filter> - </ResourceCompile> - </ItemGroup> +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{6be42502-398f-4bec-8677-8809a2da0eef}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\PC\winsound.c"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="..\PC\python_nt.rc"> + <Filter>Resource Files</Filter> + </ResourceCompile> + </ItemGroup> </Project> \ No newline at end of file diff --git a/PCbuild/xxlimited.vcxproj b/PCbuild/xxlimited.vcxproj index a61eb74f..1c776fb0 100644 --- a/PCbuild/xxlimited.vcxproj +++ b/PCbuild/xxlimited.vcxproj @@ -1,111 +1,111 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|ARM"> - <Configuration>Debug</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|ARM64"> - <Configuration>Debug</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM64"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|Win32"> - <Configuration>PGInstrument</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|x64"> - <Configuration>PGInstrument</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM64"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|Win32"> - <Configuration>PGUpdate</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|x64"> - <Configuration>PGUpdate</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM"> - <Configuration>Release</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM64"> - <Configuration>Release</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectGuid>{F749B822-B489-4CA5-A3AD-CE078F5F338A}</ProjectGuid> - <RootNamespace>xxlimited</RootNamespace> - <Keyword>Win32Proj</Keyword> - </PropertyGroup> - <Import Project="python.props" /> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>NotSet</CharacterSet> - <SupportPGO>false</SupportPGO> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <PropertyGroup> - <TargetExt>.pyd</TargetExt> - </PropertyGroup> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="pyproject.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup> - <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> - </PropertyGroup> - <ItemDefinitionGroup> - <Link> - <AdditionalDependencies>wsock32.lib;%(AdditionalDependencies)</AdditionalDependencies> - </Link> - </ItemDefinitionGroup> - <ItemGroup> - <ClCompile Include="..\Modules\xxlimited.c" /> - </ItemGroup> - <ItemGroup> - <ProjectReference Include="python3dll.vcxproj"> - <Project>{885d4898-d08d-4091-9c40-c700cfe3fc5a}</Project> - </ProjectReference> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> -</Project> +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|ARM"> + <Configuration>Debug</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|ARM64"> + <Configuration>Debug</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM64"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|Win32"> + <Configuration>PGInstrument</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|x64"> + <Configuration>PGInstrument</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM64"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|Win32"> + <Configuration>PGUpdate</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|x64"> + <Configuration>PGUpdate</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM"> + <Configuration>Release</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM64"> + <Configuration>Release</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{F749B822-B489-4CA5-A3AD-CE078F5F338A}</ProjectGuid> + <RootNamespace>xxlimited</RootNamespace> + <Keyword>Win32Proj</Keyword> + </PropertyGroup> + <Import Project="python.props" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <CharacterSet>NotSet</CharacterSet> + <SupportPGO>false</SupportPGO> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <PropertyGroup> + <TargetExt>.pyd</TargetExt> + </PropertyGroup> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="pyproject.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> + </PropertyGroup> + <ItemDefinitionGroup> + <Link> + <AdditionalDependencies>wsock32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\Modules\xxlimited.c" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="python3dll.vcxproj"> + <Project>{885d4898-d08d-4091-9c40-c700cfe3fc5a}</Project> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> diff --git a/PCbuild/xxlimited.vcxproj.filters b/PCbuild/xxlimited.vcxproj.filters index 807279a4..21db4680 100644 --- a/PCbuild/xxlimited.vcxproj.filters +++ b/PCbuild/xxlimited.vcxproj.filters @@ -1,13 +1,13 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <Filter Include="Source Files"> - <UniqueIdentifier>{eb5eebc7-3787-4f8f-b282-204db2962cc3}</UniqueIdentifier> - </Filter> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\Modules\xxlimited.c"> - <Filter>Source Files</Filter> - </ClCompile> - </ItemGroup> +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{eb5eebc7-3787-4f8f-b282-204db2962cc3}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\Modules\xxlimited.c"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> </Project> \ No newline at end of file diff --git a/PCbuild/xxlimited_35.vcxproj b/PCbuild/xxlimited_35.vcxproj index fa8aaea9..dd830b3b 100644 --- a/PCbuild/xxlimited_35.vcxproj +++ b/PCbuild/xxlimited_35.vcxproj @@ -1,111 +1,111 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|ARM"> - <Configuration>Debug</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|ARM64"> - <Configuration>Debug</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|ARM64"> - <Configuration>PGInstrument</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|Win32"> - <Configuration>PGInstrument</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGInstrument|x64"> - <Configuration>PGInstrument</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|ARM64"> - <Configuration>PGUpdate</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|Win32"> - <Configuration>PGUpdate</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="PGUpdate|x64"> - <Configuration>PGUpdate</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM"> - <Configuration>Release</Configuration> - <Platform>ARM</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|ARM64"> - <Configuration>Release</Configuration> - <Platform>ARM64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectGuid>{fb868ea7-f93a-4d9b-be78-ca4e9ba14fff}</ProjectGuid> - <RootNamespace>xxlimited_35</RootNamespace> - <Keyword>Win32Proj</Keyword> - </PropertyGroup> - <Import Project="python.props" /> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>NotSet</CharacterSet> - <SupportPGO>false</SupportPGO> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <PropertyGroup> - <TargetExt>.pyd</TargetExt> - </PropertyGroup> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="pyproject.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup> - <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> - </PropertyGroup> - <ItemDefinitionGroup> - <Link> - <AdditionalDependencies>wsock32.lib;%(AdditionalDependencies)</AdditionalDependencies> - </Link> - </ItemDefinitionGroup> - <ItemGroup> - <ClCompile Include="..\Modules\xxlimited_35.c" /> - </ItemGroup> - <ItemGroup> - <ProjectReference Include="python3dll.vcxproj"> - <Project>{885d4898-d08d-4091-9c40-c700cfe3fc5a}</Project> - </ProjectReference> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> -</Project> +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|ARM"> + <Configuration>Debug</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|ARM64"> + <Configuration>Debug</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|ARM64"> + <Configuration>PGInstrument</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|Win32"> + <Configuration>PGInstrument</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGInstrument|x64"> + <Configuration>PGInstrument</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|ARM64"> + <Configuration>PGUpdate</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|Win32"> + <Configuration>PGUpdate</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="PGUpdate|x64"> + <Configuration>PGUpdate</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM"> + <Configuration>Release</Configuration> + <Platform>ARM</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|ARM64"> + <Configuration>Release</Configuration> + <Platform>ARM64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{fb868ea7-f93a-4d9b-be78-ca4e9ba14fff}</ProjectGuid> + <RootNamespace>xxlimited_35</RootNamespace> + <Keyword>Win32Proj</Keyword> + </PropertyGroup> + <Import Project="python.props" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <CharacterSet>NotSet</CharacterSet> + <SupportPGO>false</SupportPGO> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <PropertyGroup> + <TargetExt>.pyd</TargetExt> + </PropertyGroup> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="pyproject.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup> + <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> + </PropertyGroup> + <ItemDefinitionGroup> + <Link> + <AdditionalDependencies>wsock32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\Modules\xxlimited_35.c" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="python3dll.vcxproj"> + <Project>{885d4898-d08d-4091-9c40-c700cfe3fc5a}</Project> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> diff --git a/PCbuild/xxlimited_35.vcxproj.filters b/PCbuild/xxlimited_35.vcxproj.filters index f25a6720..35bfb05c 100644 --- a/PCbuild/xxlimited_35.vcxproj.filters +++ b/PCbuild/xxlimited_35.vcxproj.filters @@ -1,13 +1,13 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <Filter Include="Source Files"> - <UniqueIdentifier>{5be27194-6530-452d-8d86-3767b991fa83}</UniqueIdentifier> - </Filter> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\Modules\xxlimited_35.c"> - <Filter>Source Files</Filter> - </ClCompile> - </ItemGroup> -</Project> +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{5be27194-6530-452d-8d86-3767b991fa83}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\Modules\xxlimited_35.c"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> +</Project> diff --git a/Parser/Python.asdl b/Parser/Python.asdl index e9423a7c..0d154867 100644 --- a/Parser/Python.asdl +++ b/Parser/Python.asdl @@ -10,20 +10,22 @@ module Python stmt = FunctionDef(identifier name, arguments args, stmt* body, expr* decorator_list, expr? returns, - string? type_comment) + string? type_comment, type_param* type_params) | AsyncFunctionDef(identifier name, arguments args, stmt* body, expr* decorator_list, expr? returns, - string? type_comment) + string? type_comment, type_param* type_params) | ClassDef(identifier name, expr* bases, keyword* keywords, stmt* body, - expr* decorator_list) + expr* decorator_list, + type_param* type_params) | Return(expr? value) | Delete(expr* targets) | Assign(expr* targets, expr value, string? type_comment) + | TypeAlias(expr name, type_param* type_params, expr value) | AugAssign(expr target, operator op, expr value) -- 'simple' indicates that we annotate simple name without parens | AnnAssign(expr target, expr annotation, expr? value, int simple) @@ -142,4 +144,9 @@ module Python attributes (int lineno, int col_offset, int end_lineno, int end_col_offset) type_ignore = TypeIgnore(int lineno, string tag) + + type_param = TypeVar(identifier name, expr? bound) + | ParamSpec(identifier name) + | TypeVarTuple(identifier name) + attributes (int lineno, int col_offset, int end_lineno, int end_col_offset) } diff --git a/Parser/action_helpers.c b/Parser/action_helpers.c index d1be679a..e68a9cac 100644 --- a/Parser/action_helpers.c +++ b/Parser/action_helpers.c @@ -1,29 +1,14 @@ #include <Python.h> #include "pegen.h" +#include "tokenizer.h" #include "string_parser.h" - -static PyObject * -_create_dummy_identifier(Parser *p) -{ - return _PyPegen_new_identifier(p, ""); -} +#include "pycore_runtime.h" // _PyRuntime void * _PyPegen_dummy_name(Parser *p, ...) { - static void *cache = NULL; - - if (cache != NULL) { - return cache; - } - - PyObject *id = _create_dummy_identifier(p); - if (!id) { - return NULL; - } - cache = _PyAST_Name(id, Load, 1, 0, 1, 0, p->arena); - return cache; + return &_PyRuntime.parser.dummy_name; } /* Creates a single-element asdl_seq* that contains a */ @@ -767,20 +752,25 @@ _PyPegen_function_def_decorators(Parser *p, asdl_expr_seq *decorators, stmt_ty f assert(function_def != NULL); if (function_def->kind == AsyncFunctionDef_kind) { return _PyAST_AsyncFunctionDef( - function_def->v.FunctionDef.name, function_def->v.FunctionDef.args, - function_def->v.FunctionDef.body, decorators, function_def->v.FunctionDef.returns, - function_def->v.FunctionDef.type_comment, function_def->lineno, - function_def->col_offset, function_def->end_lineno, function_def->end_col_offset, - p->arena); + function_def->v.AsyncFunctionDef.name, + function_def->v.AsyncFunctionDef.args, + function_def->v.AsyncFunctionDef.body, decorators, + function_def->v.AsyncFunctionDef.returns, + function_def->v.AsyncFunctionDef.type_comment, + function_def->v.AsyncFunctionDef.type_params, + function_def->lineno, function_def->col_offset, + function_def->end_lineno, function_def->end_col_offset, p->arena); } return _PyAST_FunctionDef( - function_def->v.FunctionDef.name, function_def->v.FunctionDef.args, + function_def->v.FunctionDef.name, + function_def->v.FunctionDef.args, function_def->v.FunctionDef.body, decorators, function_def->v.FunctionDef.returns, - function_def->v.FunctionDef.type_comment, function_def->lineno, - function_def->col_offset, function_def->end_lineno, - function_def->end_col_offset, p->arena); + function_def->v.FunctionDef.type_comment, + function_def->v.FunctionDef.type_params, + function_def->lineno, function_def->col_offset, + function_def->end_lineno, function_def->end_col_offset, p->arena); } /* Construct a ClassDef equivalent to class_def, but with decorators */ @@ -789,8 +779,10 @@ _PyPegen_class_def_decorators(Parser *p, asdl_expr_seq *decorators, stmt_ty clas { assert(class_def != NULL); return _PyAST_ClassDef( - class_def->v.ClassDef.name, class_def->v.ClassDef.bases, - class_def->v.ClassDef.keywords, class_def->v.ClassDef.body, decorators, + class_def->v.ClassDef.name, + class_def->v.ClassDef.bases, class_def->v.ClassDef.keywords, + class_def->v.ClassDef.body, decorators, + class_def->v.ClassDef.type_params, class_def->lineno, class_def->col_offset, class_def->end_lineno, class_def->end_col_offset, p->arena); } @@ -869,96 +861,6 @@ _PyPegen_seq_delete_starred_exprs(Parser *p, asdl_seq *kwargs) return new_seq; } -expr_ty -_PyPegen_concatenate_strings(Parser *p, asdl_seq *strings) -{ - Py_ssize_t len = asdl_seq_LEN(strings); - assert(len > 0); - - Token *first = asdl_seq_GET_UNTYPED(strings, 0); - Token *last = asdl_seq_GET_UNTYPED(strings, len - 1); - - int bytesmode = 0; - PyObject *bytes_str = NULL; - - FstringParser state; - _PyPegen_FstringParser_Init(&state); - - for (Py_ssize_t i = 0; i < len; i++) { - Token *t = asdl_seq_GET_UNTYPED(strings, i); - - int this_bytesmode; - int this_rawmode; - PyObject *s; - const char *fstr; - Py_ssize_t fstrlen = -1; - - if (_PyPegen_parsestr(p, &this_bytesmode, &this_rawmode, &s, &fstr, &fstrlen, t) != 0) { - goto error; - } - - /* Check that we are not mixing bytes with unicode. */ - if (i != 0 && bytesmode != this_bytesmode) { - RAISE_SYNTAX_ERROR("cannot mix bytes and nonbytes literals"); - Py_XDECREF(s); - goto error; - } - bytesmode = this_bytesmode; - - if (fstr != NULL) { - assert(s == NULL && !bytesmode); - - int result = _PyPegen_FstringParser_ConcatFstring(p, &state, &fstr, fstr + fstrlen, - this_rawmode, 0, first, t, last); - if (result < 0) { - goto error; - } - } - else { - /* String or byte string. */ - assert(s != NULL && fstr == NULL); - assert(bytesmode ? PyBytes_CheckExact(s) : PyUnicode_CheckExact(s)); - - if (bytesmode) { - if (i == 0) { - bytes_str = s; - } - else { - PyBytes_ConcatAndDel(&bytes_str, s); - if (!bytes_str) { - goto error; - } - } - } - else { - /* This is a regular string. Concatenate it. */ - if (_PyPegen_FstringParser_ConcatAndDel(&state, s) < 0) { - goto error; - } - } - } - } - - if (bytesmode) { - if (_PyArena_AddPyObject(p->arena, bytes_str) < 0) { - goto error; - } - return _PyAST_Constant(bytes_str, NULL, first->lineno, - first->col_offset, last->end_lineno, - last->end_col_offset, p->arena); - } - - return _PyPegen_FstringParser_Finish(p, &state, first, last); - -error: - Py_XDECREF(bytes_str); - _PyPegen_FstringParser_Dealloc(&state); - if (PyErr_Occurred()) { - _Pypegen_raise_decode_error(p); - } - return NULL; -} - expr_ty _PyPegen_ensure_imaginary(Parser *p, expr_ty exp) { @@ -1070,6 +972,56 @@ _PyPegen_check_legacy_stmt(Parser *p, expr_ty name) { return 0; } +static ResultTokenWithMetadata * +result_token_with_metadata(Parser *p, void *result, PyObject *metadata) +{ + ResultTokenWithMetadata *res = _PyArena_Malloc(p->arena, sizeof(ResultTokenWithMetadata)); + if (res == NULL) { + return NULL; + } + res->metadata = metadata; + res->result = result; + return res; +} + +ResultTokenWithMetadata * +_PyPegen_check_fstring_conversion(Parser *p, Token* conv_token, expr_ty conv) +{ + if (conv_token->lineno != conv->lineno || conv_token->end_col_offset != conv->col_offset) { + return RAISE_SYNTAX_ERROR_KNOWN_RANGE( + conv_token, conv, + "f-string: conversion type must come right after the exclamanation mark" + ); + } + return result_token_with_metadata(p, conv, conv_token->metadata); +} + +ResultTokenWithMetadata * +_PyPegen_setup_full_format_spec(Parser *p, Token *colon, asdl_expr_seq *spec, int lineno, int col_offset, + int end_lineno, int end_col_offset, PyArena *arena) +{ + if (!spec) { + return NULL; + } + + // This is needed to keep compatibility with 3.11, where an empty format spec is parsed + // as an *empty* JoinedStr node, instead of having an empty constant in it. + if (asdl_seq_LEN(spec) == 1) { + expr_ty e = asdl_seq_GET(spec, 0); + if (e->kind == Constant_kind + && PyUnicode_Check(e->v.Constant.value) + && PyUnicode_GetLength(e->v.Constant.value) == 0) { + spec = _Py_asdl_expr_seq_new(0, arena); + } + } + + expr_ty res = _PyAST_JoinedStr(spec, lineno, col_offset, end_lineno, end_col_offset, p->arena); + if (!res) { + return NULL; + } + return result_token_with_metadata(p, res, colon->metadata); +} + const char * _PyPegen_get_expr_name(expr_ty e) { @@ -1286,4 +1238,443 @@ _PyPegen_nonparen_genexp_in_call(Parser *p, expr_ty args, asdl_comprehension_seq _PyPegen_get_last_comprehension_item(last_comprehension), "Generator expression must be parenthesized" ); -} \ No newline at end of file +} + +// Fstring stuff + +static expr_ty +_PyPegen_decode_fstring_part(Parser* p, int is_raw, expr_ty constant, Token* token) { + assert(PyUnicode_CheckExact(constant->v.Constant.value)); + + const char* bstr = PyUnicode_AsUTF8(constant->v.Constant.value); + if (bstr == NULL) { + return NULL; + } + + size_t len; + if (strcmp(bstr, "{{") == 0 || strcmp(bstr, "}}") == 0) { + len = 1; + } else { + len = strlen(bstr); + } + + is_raw = is_raw || strchr(bstr, '\\') == NULL; + PyObject *str = _PyPegen_decode_string(p, is_raw, bstr, len, token); + if (str == NULL) { + _Pypegen_raise_decode_error(p); + return NULL; + } + if (_PyArena_AddPyObject(p->arena, str) < 0) { + Py_DECREF(str); + return NULL; + } + return _PyAST_Constant(str, NULL, constant->lineno, constant->col_offset, + constant->end_lineno, constant->end_col_offset, + p->arena); +} + +static asdl_expr_seq * +unpack_top_level_joined_strs(Parser *p, asdl_expr_seq *raw_expressions) +{ + /* The parser might put multiple f-string values into an individual + * JoinedStr node at the top level due to stuff like f-string debugging + * expressions. This function flattens those and promotes them to the + * upper level. Only simplifies AST, but the compiler already takes care + * of the regular output, so this is not necessary if you are not going + * to expose the output AST to Python level. */ + + Py_ssize_t i, req_size, raw_size; + + req_size = raw_size = asdl_seq_LEN(raw_expressions); + expr_ty expr; + for (i = 0; i < raw_size; i++) { + expr = asdl_seq_GET(raw_expressions, i); + if (expr->kind == JoinedStr_kind) { + req_size += asdl_seq_LEN(expr->v.JoinedStr.values) - 1; + } + } + + asdl_expr_seq *expressions = _Py_asdl_expr_seq_new(req_size, p->arena); + + Py_ssize_t raw_index, req_index = 0; + for (raw_index = 0; raw_index < raw_size; raw_index++) { + expr = asdl_seq_GET(raw_expressions, raw_index); + if (expr->kind == JoinedStr_kind) { + asdl_expr_seq *values = expr->v.JoinedStr.values; + for (Py_ssize_t n = 0; n < asdl_seq_LEN(values); n++) { + asdl_seq_SET(expressions, req_index, asdl_seq_GET(values, n)); + req_index++; + } + } else { + asdl_seq_SET(expressions, req_index, expr); + req_index++; + } + } + return expressions; +} + +expr_ty +_PyPegen_joined_str(Parser *p, Token* a, asdl_expr_seq* raw_expressions, Token*b) { + asdl_expr_seq *expr = unpack_top_level_joined_strs(p, raw_expressions); + Py_ssize_t n_items = asdl_seq_LEN(expr); + + const char* quote_str = PyBytes_AsString(a->bytes); + if (quote_str == NULL) { + return NULL; + } + int is_raw = strpbrk(quote_str, "rR") != NULL; + + asdl_expr_seq *seq = _Py_asdl_expr_seq_new(n_items, p->arena); + if (seq == NULL) { + return NULL; + } + + Py_ssize_t index = 0; + for (Py_ssize_t i = 0; i < n_items; i++) { + expr_ty item = asdl_seq_GET(expr, i); + if (item->kind == Constant_kind) { + item = _PyPegen_decode_fstring_part(p, is_raw, item, b); + if (item == NULL) { + return NULL; + } + + /* Tokenizer emits string parts even when the underlying string + might become an empty value (e.g. FSTRING_MIDDLE with the value \\n) + so we need to check for them and simplify it here. */ + if (PyUnicode_CheckExact(item->v.Constant.value) + && PyUnicode_GET_LENGTH(item->v.Constant.value) == 0) { + continue; + } + } + asdl_seq_SET(seq, index++, item); + } + + asdl_expr_seq *resized_exprs; + if (index != n_items) { + resized_exprs = _Py_asdl_expr_seq_new(index, p->arena); + if (resized_exprs == NULL) { + return NULL; + } + for (Py_ssize_t i = 0; i < index; i++) { + asdl_seq_SET(resized_exprs, i, asdl_seq_GET(seq, i)); + } + } + else { + resized_exprs = seq; + } + + return _PyAST_JoinedStr(resized_exprs, a->lineno, a->col_offset, + b->end_lineno, b->end_col_offset, + p->arena); +} + +expr_ty _PyPegen_decoded_constant_from_token(Parser* p, Token* tok) { + Py_ssize_t bsize; + char* bstr; + if (PyBytes_AsStringAndSize(tok->bytes, &bstr, &bsize) == -1) { + return NULL; + } + PyObject* str = _PyPegen_decode_string(p, 0, bstr, bsize, tok); + if (str == NULL) { + return NULL; + } + if (_PyArena_AddPyObject(p->arena, str) < 0) { + Py_DECREF(str); + return NULL; + } + return _PyAST_Constant(str, NULL, tok->lineno, tok->col_offset, + tok->end_lineno, tok->end_col_offset, + p->arena); +} + +expr_ty _PyPegen_constant_from_token(Parser* p, Token* tok) { + char* bstr = PyBytes_AsString(tok->bytes); + if (bstr == NULL) { + return NULL; + } + PyObject* str = PyUnicode_FromString(bstr); + if (str == NULL) { + return NULL; + } + if (_PyArena_AddPyObject(p->arena, str) < 0) { + Py_DECREF(str); + return NULL; + } + return _PyAST_Constant(str, NULL, tok->lineno, tok->col_offset, + tok->end_lineno, tok->end_col_offset, + p->arena); +} + +expr_ty _PyPegen_constant_from_string(Parser* p, Token* tok) { + char* the_str = PyBytes_AsString(tok->bytes); + if (the_str == NULL) { + return NULL; + } + PyObject *s = _PyPegen_parse_string(p, tok); + if (s == NULL) { + _Pypegen_raise_decode_error(p); + return NULL; + } + if (_PyArena_AddPyObject(p->arena, s) < 0) { + Py_DECREF(s); + return NULL; + } + PyObject *kind = NULL; + if (the_str && the_str[0] == 'u') { + kind = _PyPegen_new_identifier(p, "u"); + if (kind == NULL) { + return NULL; + } + } + return _PyAST_Constant(s, kind, tok->lineno, tok->col_offset, tok->end_lineno, tok->end_col_offset, p->arena); +} + +expr_ty _PyPegen_formatted_value(Parser *p, expr_ty expression, Token *debug, ResultTokenWithMetadata *conversion, + ResultTokenWithMetadata *format, Token *closing_brace, int lineno, int col_offset, + int end_lineno, int end_col_offset, PyArena *arena) { + int conversion_val = -1; + if (conversion != NULL) { + expr_ty conversion_expr = (expr_ty) conversion->result; + assert(conversion_expr->kind == Name_kind); + Py_UCS4 first = PyUnicode_READ_CHAR(conversion_expr->v.Name.id, 0); + + if (PyUnicode_GET_LENGTH(conversion_expr->v.Name.id) > 1 || + !(first == 's' || first == 'r' || first == 'a')) { + RAISE_SYNTAX_ERROR_KNOWN_LOCATION(conversion_expr, + "f-string: invalid conversion character %R: expected 's', 'r', or 'a'", + conversion_expr->v.Name.id); + return NULL; + } + + conversion_val = Py_SAFE_DOWNCAST(first, Py_UCS4, int); + } + else if (debug && !format) { + /* If no conversion is specified, use !r for debug expressions */ + conversion_val = (int)'r'; + } + + expr_ty formatted_value = _PyAST_FormattedValue( + expression, conversion_val, format ? (expr_ty) format->result : NULL, + lineno, col_offset, end_lineno, + end_col_offset, arena + ); + + if (debug) { + /* Find the non whitespace token after the "=" */ + int debug_end_line, debug_end_offset; + PyObject *debug_metadata; + + if (conversion) { + debug_end_line = ((expr_ty) conversion->result)->lineno; + debug_end_offset = ((expr_ty) conversion->result)->col_offset; + debug_metadata = conversion->metadata; + } + else if (format) { + debug_end_line = ((expr_ty) format->result)->lineno; + debug_end_offset = ((expr_ty) format->result)->col_offset + 1; + debug_metadata = format->metadata; + } + else { + debug_end_line = end_lineno; + debug_end_offset = end_col_offset; + debug_metadata = closing_brace->metadata; + } + + expr_ty debug_text = _PyAST_Constant(debug_metadata, NULL, lineno, col_offset + 1, debug_end_line, + debug_end_offset - 1, p->arena); + if (!debug_text) { + return NULL; + } + + asdl_expr_seq *values = _Py_asdl_expr_seq_new(2, arena); + asdl_seq_SET(values, 0, debug_text); + asdl_seq_SET(values, 1, formatted_value); + return _PyAST_JoinedStr(values, lineno, col_offset, debug_end_line, debug_end_offset, p->arena); + } + else { + return formatted_value; + } +} + +expr_ty +_PyPegen_concatenate_strings(Parser *p, asdl_expr_seq *strings, + int lineno, int col_offset, int end_lineno, + int end_col_offset, PyArena *arena) +{ + Py_ssize_t len = asdl_seq_LEN(strings); + assert(len > 0); + + int f_string_found = 0; + int unicode_string_found = 0; + int bytes_found = 0; + + Py_ssize_t i = 0; + Py_ssize_t n_flattened_elements = 0; + for (i = 0; i < len; i++) { + expr_ty elem = asdl_seq_GET(strings, i); + if (elem->kind == Constant_kind) { + if (PyBytes_CheckExact(elem->v.Constant.value)) { + bytes_found = 1; + } else { + unicode_string_found = 1; + } + n_flattened_elements++; + } else { + n_flattened_elements += asdl_seq_LEN(elem->v.JoinedStr.values); + f_string_found = 1; + } + } + + if ((unicode_string_found || f_string_found) && bytes_found) { + RAISE_SYNTAX_ERROR("cannot mix bytes and nonbytes literals"); + return NULL; + } + + if (bytes_found) { + PyObject* res = PyBytes_FromString(""); + + /* Bytes literals never get a kind, but just for consistency + since they are represented as Constant nodes, we'll mirror + the same behavior as unicode strings for determining the + kind. */ + PyObject* kind = asdl_seq_GET(strings, 0)->v.Constant.kind; + for (i = 0; i < len; i++) { + expr_ty elem = asdl_seq_GET(strings, i); + PyBytes_Concat(&res, elem->v.Constant.value); + } + if (!res || _PyArena_AddPyObject(arena, res) < 0) { + Py_XDECREF(res); + return NULL; + } + return _PyAST_Constant(res, kind, lineno, col_offset, end_lineno, end_col_offset, p->arena); + } + + if (!f_string_found && len == 1) { + return asdl_seq_GET(strings, 0); + } + + asdl_expr_seq* flattened = _Py_asdl_expr_seq_new(n_flattened_elements, p->arena); + if (flattened == NULL) { + return NULL; + } + + /* build flattened list */ + Py_ssize_t current_pos = 0; + Py_ssize_t j = 0; + for (i = 0; i < len; i++) { + expr_ty elem = asdl_seq_GET(strings, i); + if (elem->kind == Constant_kind) { + asdl_seq_SET(flattened, current_pos++, elem); + } else { + for (j = 0; j < asdl_seq_LEN(elem->v.JoinedStr.values); j++) { + expr_ty subvalue = asdl_seq_GET(elem->v.JoinedStr.values, j); + if (subvalue == NULL) { + return NULL; + } + asdl_seq_SET(flattened, current_pos++, subvalue); + } + } + } + + /* calculate folded element count */ + Py_ssize_t n_elements = 0; + int prev_is_constant = 0; + for (i = 0; i < n_flattened_elements; i++) { + expr_ty elem = asdl_seq_GET(flattened, i); + + /* The concatenation of a FormattedValue and an empty Contant should + lead to the FormattedValue itself. Thus, we will not take any empty + constants into account, just as in `_PyPegen_joined_str` */ + if (f_string_found && elem->kind == Constant_kind && + PyUnicode_CheckExact(elem->v.Constant.value) && + PyUnicode_GET_LENGTH(elem->v.Constant.value) == 0) + continue; + + if (!prev_is_constant || elem->kind != Constant_kind) { + n_elements++; + } + prev_is_constant = elem->kind == Constant_kind; + } + + asdl_expr_seq* values = _Py_asdl_expr_seq_new(n_elements, p->arena); + if (values == NULL) { + return NULL; + } + + /* build folded list */ + _PyUnicodeWriter writer; + current_pos = 0; + for (i = 0; i < n_flattened_elements; i++) { + expr_ty elem = asdl_seq_GET(flattened, i); + + /* if the current elem and the following are constants, + fold them and all consequent constants */ + if (elem->kind == Constant_kind) { + if (i + 1 < n_flattened_elements && + asdl_seq_GET(flattened, i + 1)->kind == Constant_kind) { + expr_ty first_elem = elem; + + /* When a string is getting concatenated, the kind of the string + is determined by the first string in the concatenation + sequence. + + u"abc" "def" -> u"abcdef" + "abc" u"abc" -> "abcabc" */ + PyObject *kind = elem->v.Constant.kind; + + _PyUnicodeWriter_Init(&writer); + expr_ty last_elem = elem; + for (j = i; j < n_flattened_elements; j++) { + expr_ty current_elem = asdl_seq_GET(flattened, j); + if (current_elem->kind == Constant_kind) { + if (_PyUnicodeWriter_WriteStr( + &writer, current_elem->v.Constant.value)) { + _PyUnicodeWriter_Dealloc(&writer); + return NULL; + } + last_elem = current_elem; + } else { + break; + } + } + i = j - 1; + + PyObject *concat_str = _PyUnicodeWriter_Finish(&writer); + if (concat_str == NULL) { + _PyUnicodeWriter_Dealloc(&writer); + return NULL; + } + if (_PyArena_AddPyObject(p->arena, concat_str) < 0) { + Py_DECREF(concat_str); + return NULL; + } + elem = _PyAST_Constant(concat_str, kind, first_elem->lineno, + first_elem->col_offset, + last_elem->end_lineno, + last_elem->end_col_offset, p->arena); + if (elem == NULL) { + return NULL; + } + } + + /* Drop all empty contanst strings */ + if (f_string_found && + PyUnicode_CheckExact(elem->v.Constant.value) && + PyUnicode_GET_LENGTH(elem->v.Constant.value) == 0) { + continue; + } + } + + asdl_seq_SET(values, current_pos++, elem); + } + + if (!f_string_found) { + assert(n_elements == 1); + expr_ty elem = asdl_seq_GET(values, 0); + assert(elem->kind == Constant_kind); + return elem; + } + + assert(current_pos == n_elements); + return _PyAST_JoinedStr(values, lineno, col_offset, end_lineno, end_col_offset, p->arena); +} diff --git a/Parser/asdl_c.py b/Parser/asdl_c.py index ec8b5335..aa093b30 100755 --- a/Parser/asdl_c.py +++ b/Parser/asdl_c.py @@ -1,7 +1,6 @@ #! /usr/bin/env python """Generate C code from an ASDL description.""" -import os import sys import textwrap import types @@ -74,7 +73,7 @@ def reflow_c_string(s, depth): def is_simple(sum_type): """Return True if a sum is a simple. - A sum is simple if it's types have no fields and itself + A sum is simple if its types have no fields and itself doesn't have any attributes. Instances of these types are cached at C level, and they act like singletons when propagating parser generated nodes into Python level, e.g. @@ -353,7 +352,7 @@ class PrototypeVisitor(EmitVisitor): self.visit(t, name, sum.attributes) def get_args(self, fields): - """Return list of C argument into, one for each field. + """Return list of C argument info, one for each field. Argument info is 3-tuple of a C type, variable name, and flag that is true if type can be NULL. @@ -602,6 +601,7 @@ class Obj2ModVisitor(PickleVisitor): args = [f.name for f in prod.fields] args.extend([a.name for a in prod.attributes]) self.emit("*out = %s(%s);" % (ast_func_name(name), self.buildArgs(args)), 1) + self.emit("if (*out == NULL) goto failed;", 1) self.emit("return 0;", 1) self.emit("failed:", 0) self.emit("Py_XDECREF(tmp);", 1) @@ -633,29 +633,38 @@ class Obj2ModVisitor(PickleVisitor): self.emit(line % field.name, depth) self.emit("return 1;", depth+1) self.emit("}", depth) - if not field.opt: + if field.seq: self.emit("if (tmp == NULL) {", depth) - message = "required field \\\"%s\\\" missing from %s" % (field.name, name) - format = "PyErr_SetString(PyExc_TypeError, \"%s\");" - self.emit(format % message, depth+1, reflow=False) - self.emit("return 1;", depth+1) + self.emit("tmp = PyList_New(0);", depth+1) + self.emit("if (tmp == NULL) {", depth+1) + self.emit("return 1;", depth+2) + self.emit("}", depth+1) + self.emit("}", depth) + self.emit("{", depth) else: - self.emit("if (tmp == NULL || tmp == Py_None) {", depth) - self.emit("Py_CLEAR(tmp);", depth+1) - if self.isNumeric(field): - if field.name in self.attribute_special_defaults: - self.emit( - "%s = %s;" % (field.name, self.attribute_special_defaults[field.name]), - depth+1, - ) - else: - self.emit("%s = 0;" % field.name, depth+1) - elif not self.isSimpleType(field): - self.emit("%s = NULL;" % field.name, depth+1) + if not field.opt: + self.emit("if (tmp == NULL) {", depth) + message = "required field \\\"%s\\\" missing from %s" % (field.name, name) + format = "PyErr_SetString(PyExc_TypeError, \"%s\");" + self.emit(format % message, depth+1, reflow=False) + self.emit("return 1;", depth+1) else: - raise TypeError("could not determine the default value for %s" % field.name) - self.emit("}", depth) - self.emit("else {", depth) + self.emit("if (tmp == NULL || tmp == Py_None) {", depth) + self.emit("Py_CLEAR(tmp);", depth+1) + if self.isNumeric(field): + if field.name in self.attribute_special_defaults: + self.emit( + "%s = %s;" % (field.name, self.attribute_special_defaults[field.name]), + depth+1, + ) + else: + self.emit("%s = 0;" % field.name, depth+1) + elif not self.isSimpleType(field): + self.emit("%s = NULL;" % field.name, depth+1) + else: + raise TypeError("could not determine the default value for %s" % field.name) + self.emit("}", depth) + self.emit("else {", depth) self.emit("int res;", depth+1) if field.seq: @@ -676,8 +685,7 @@ class Obj2ModVisitor(PickleVisitor): self.emit("if (%s == NULL) goto failed;" % field.name, depth+1) self.emit("for (i = 0; i < len; i++) {", depth+1) self.emit("%s val;" % ctype, depth+2) - self.emit("PyObject *tmp2 = PyList_GET_ITEM(tmp, i);", depth+2) - self.emit("Py_INCREF(tmp2);", depth+2) + self.emit("PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));", depth+2) with self.recursive_call(name, depth+2): self.emit("res = obj2ast_%s(state, tmp2, &val, arena);" % field.type, depth+2, reflow=False) @@ -996,10 +1004,11 @@ static PyObject* ast2obj_list(struct ast_state *state, asdl_seq *seq, PyObject* static PyObject* ast2obj_object(struct ast_state *Py_UNUSED(state), void *o) { - if (!o) - o = Py_None; - Py_INCREF((PyObject*)o); - return (PyObject*)o; + PyObject *op = (PyObject*)o; + if (!op) { + op = Py_None; + } + return Py_NewRef(op); } #define ast2obj_constant ast2obj_object #define ast2obj_identifier ast2obj_object @@ -1021,9 +1030,11 @@ static int obj2ast_object(struct ast_state *Py_UNUSED(state), PyObject* obj, PyO *out = NULL; return -1; } - Py_INCREF(obj); + *out = Py_NewRef(obj); + } + else { + *out = NULL; } - *out = obj; return 0; } @@ -1033,8 +1044,7 @@ static int obj2ast_constant(struct ast_state *Py_UNUSED(state), PyObject* obj, P *out = NULL; return -1; } - Py_INCREF(obj); - *out = obj; + *out = Py_NewRef(obj); return 0; } @@ -1206,6 +1216,7 @@ class ASTModuleVisitor(PickleVisitor): self.emit(""" static PyModuleDef_Slot astmodule_slots[] = { {Py_mod_exec, astmodule_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; @@ -1302,8 +1313,7 @@ class ObjVisitor(PickleVisitor): self.emit("switch(o) {", 1) for t in sum.types: self.emit("case %s:" % t.name, 2) - self.emit("Py_INCREF(state->%s_singleton);" % t.name, 3) - self.emit("return state->%s_singleton;" % t.name, 3) + self.emit("return Py_NewRef(state->%s_singleton);" % t.name, 3) self.emit("}", 1) self.emit("Py_UNREACHABLE();", 1); self.emit("}", 0) @@ -1381,19 +1391,16 @@ PyObject* PyAST_mod2obj(mod_ty t) return NULL; } - int recursion_limit = Py_GetRecursionLimit(); int starting_recursion_depth; /* Be careful here to prevent overflow. */ - int COMPILER_STACK_FRAME_SCALE = 3; + int COMPILER_STACK_FRAME_SCALE = 2; PyThreadState *tstate = _PyThreadState_GET(); if (!tstate) { return 0; } - state->recursion_limit = (recursion_limit < INT_MAX / COMPILER_STACK_FRAME_SCALE) ? - recursion_limit * COMPILER_STACK_FRAME_SCALE : recursion_limit; - int recursion_depth = tstate->recursion_limit - tstate->recursion_remaining; - starting_recursion_depth = (recursion_depth < INT_MAX / COMPILER_STACK_FRAME_SCALE) ? - recursion_depth * COMPILER_STACK_FRAME_SCALE : recursion_depth; + state->recursion_limit = C_RECURSION_LIMIT * COMPILER_STACK_FRAME_SCALE; + int recursion_depth = C_RECURSION_LIMIT - tstate->c_recursion_remaining; + starting_recursion_depth = recursion_depth * COMPILER_STACK_FRAME_SCALE; state->recursion_depth = starting_recursion_depth; PyObject *result = ast2obj_mod(state, t); @@ -1488,6 +1495,8 @@ def generate_ast_fini(module_state, f): for s in module_state: f.write(" Py_CLEAR(state->" + s + ');\n') f.write(textwrap.dedent(""" + Py_CLEAR(_Py_INTERP_CACHED_OBJECT(interp, str_replace_inf)); + #if !defined(NDEBUG) state->initialized = -1; #else diff --git a/Parser/myreadline.c b/Parser/myreadline.c index b10d3062..7074aba7 100644 --- a/Parser/myreadline.c +++ b/Parser/myreadline.c @@ -13,7 +13,9 @@ #include "pycore_fileutils.h" // _Py_BEGIN_SUPPRESS_IPH #include "pycore_pystate.h" // _PyThreadState_GET() #ifdef MS_WINDOWS +# ifndef WIN32_LEAN_AND_MEAN # define WIN32_LEAN_AND_MEAN +# endif # include "windows.h" #endif /* MS_WINDOWS */ @@ -43,7 +45,10 @@ my_fgets(PyThreadState* tstate, char *buf, int len, FILE *fp) #endif while (1) { - if (PyOS_InputHook != NULL) { + if (PyOS_InputHook != NULL && + // GH-104668: See PyOS_ReadlineFunctionPointer's comment below... + _Py_IsMainInterpreter(tstate->interp)) + { (void)(PyOS_InputHook)(); } @@ -108,7 +113,7 @@ my_fgets(PyThreadState* tstate, char *buf, int len, FILE *fp) /* NOTREACHED */ } -#ifdef MS_WINDOWS +#ifdef HAVE_WINDOWS_CONSOLE_IO /* Readline implementation using ReadConsoleW */ extern char _get_console_type(HANDLE handle); @@ -129,7 +134,10 @@ _PyOS_WindowsConsoleReadline(PyThreadState *tstate, HANDLE hStdIn) wbuf = wbuf_local; wbuflen = sizeof(wbuf_local) / sizeof(wbuf_local[0]) - 1; while (1) { - if (PyOS_InputHook != NULL) { + if (PyOS_InputHook != NULL && + // GH-104668: See PyOS_ReadlineFunctionPointer's comment below... + _Py_IsMainInterpreter(tstate->interp)) + { (void)(PyOS_InputHook)(); } if (!ReadConsoleW(hStdIn, &wbuf[total_read], wbuflen - total_read, &n_read, NULL)) { @@ -233,7 +241,7 @@ exit: return buf; } -#endif +#endif /* HAVE_WINDOWS_CONSOLE_IO */ /* Readline implementation using fgets() */ @@ -246,8 +254,9 @@ PyOS_StdioReadline(FILE *sys_stdin, FILE *sys_stdout, const char *prompt) PyThreadState *tstate = _PyOS_ReadlineTState; assert(tstate != NULL); -#ifdef MS_WINDOWS - if (!Py_LegacyWindowsStdioFlag && sys_stdin == stdin) { +#ifdef HAVE_WINDOWS_CONSOLE_IO + const PyConfig *config = _PyInterpreterState_GetConfig(tstate->interp); + if (!config->legacy_windows_stdio && sys_stdin == stdin) { HANDLE hStdIn, hStdErr; hStdIn = _Py_get_osfhandle_noraise(fileno(sys_stdin)); @@ -386,11 +395,23 @@ PyOS_Readline(FILE *sys_stdin, FILE *sys_stdout, const char *prompt) * a tty. This can happen, for example if python is run like * this: python -i < test1.py */ - if (!isatty (fileno (sys_stdin)) || !isatty (fileno (sys_stdout))) - rv = PyOS_StdioReadline (sys_stdin, sys_stdout, prompt); - else - rv = (*PyOS_ReadlineFunctionPointer)(sys_stdin, sys_stdout, - prompt); + if (!isatty(fileno(sys_stdin)) || !isatty(fileno(sys_stdout)) || + // GH-104668: Don't call global callbacks like PyOS_InputHook or + // PyOS_ReadlineFunctionPointer from subinterpreters, since it seems + // like there's no good way for users (like readline and tkinter) to + // avoid using global state to manage them. Plus, we generally don't + // want to cause trouble for libraries that don't know/care about + // subinterpreter support. If libraries really need better APIs that + // work per-interpreter and have ways to access module state, we can + // certainly add them later (but for now we'll cross our fingers and + // hope that nobody actually cares): + !_Py_IsMainInterpreter(tstate->interp)) + { + rv = PyOS_StdioReadline(sys_stdin, sys_stdout, prompt); + } + else { + rv = (*PyOS_ReadlineFunctionPointer)(sys_stdin, sys_stdout, prompt); + } Py_END_ALLOW_THREADS PyThread_release_lock(_PyOS_ReadlineLock); diff --git a/Parser/parser.c b/Parser/parser.c index f5aecbc4..5d2adf74 100644 --- a/Parser/parser.c +++ b/Parser/parser.c @@ -2,7 +2,7 @@ #include "pegen.h" #if defined(Py_DEBUG) && defined(Py_BUILD_CORE) -# define D(x) if (Py_DebugFlag) x; +# define D(x) if (p->debug) { x; } #else # define D(x) #endif @@ -17,52 +17,52 @@ static KeywordToken *reserved_keywords[] = { (KeywordToken[]) {{NULL, -1}}, (KeywordToken[]) {{NULL, -1}}, (KeywordToken[]) { - {"if", 639}, - {"as", 637}, - {"in", 648}, + {"if", 642}, + {"as", 640}, + {"in", 651}, {"or", 574}, {"is", 582}, {NULL, -1}, }, (KeywordToken[]) { - {"del", 603}, - {"def", 649}, - {"for", 647}, - {"try", 621}, + {"del", 604}, + {"def", 652}, + {"for", 650}, + {"try", 624}, {"and", 575}, {"not", 581}, {NULL, -1}, }, (KeywordToken[]) { - {"from", 572}, + {"from", 608}, {"pass", 504}, - {"with", 612}, - {"elif", 641}, - {"else", 642}, - {"None", 601}, - {"True", 600}, + {"with", 615}, + {"elif", 644}, + {"else", 645}, + {"None", 602}, + {"True", 601}, {NULL, -1}, }, (KeywordToken[]) { {"raise", 522}, {"yield", 573}, {"break", 508}, - {"class", 651}, - {"while", 644}, - {"False", 602}, + {"class", 654}, + {"while", 647}, + {"False", 603}, {NULL, -1}, }, (KeywordToken[]) { {"return", 519}, - {"import", 531}, + {"import", 607}, {"assert", 526}, {"global", 523}, - {"except", 634}, - {"lambda", 586}, + {"except", 637}, + {"lambda", 600}, {NULL, -1}, }, (KeywordToken[]) { - {"finally", 630}, + {"finally", 633}, {NULL, -1}, }, (KeywordToken[]) { @@ -75,6 +75,7 @@ static char *soft_keywords[] = { "_", "case", "match", + "type", NULL, }; #define file_type 1000 @@ -175,386 +176,427 @@ static char *soft_keywords[] = { #define positional_patterns_type 1095 #define keyword_patterns_type 1096 #define keyword_pattern_type 1097 -#define expressions_type 1098 -#define expression_type 1099 -#define yield_expr_type 1100 -#define star_expressions_type 1101 -#define star_expression_type 1102 -#define star_named_expressions_type 1103 -#define star_named_expression_type 1104 -#define assignment_expression_type 1105 -#define named_expression_type 1106 -#define disjunction_type 1107 -#define conjunction_type 1108 -#define inversion_type 1109 -#define comparison_type 1110 -#define compare_op_bitwise_or_pair_type 1111 -#define eq_bitwise_or_type 1112 -#define noteq_bitwise_or_type 1113 -#define lte_bitwise_or_type 1114 -#define lt_bitwise_or_type 1115 -#define gte_bitwise_or_type 1116 -#define gt_bitwise_or_type 1117 -#define notin_bitwise_or_type 1118 -#define in_bitwise_or_type 1119 -#define isnot_bitwise_or_type 1120 -#define is_bitwise_or_type 1121 -#define bitwise_or_type 1122 // Left-recursive -#define bitwise_xor_type 1123 // Left-recursive -#define bitwise_and_type 1124 // Left-recursive -#define shift_expr_type 1125 // Left-recursive -#define sum_type 1126 // Left-recursive -#define term_type 1127 // Left-recursive -#define factor_type 1128 -#define power_type 1129 -#define await_primary_type 1130 -#define primary_type 1131 // Left-recursive -#define slices_type 1132 -#define slice_type 1133 -#define atom_type 1134 -#define group_type 1135 -#define lambdef_type 1136 -#define lambda_params_type 1137 -#define lambda_parameters_type 1138 -#define lambda_slash_no_default_type 1139 -#define lambda_slash_with_default_type 1140 -#define lambda_star_etc_type 1141 -#define lambda_kwds_type 1142 -#define lambda_param_no_default_type 1143 -#define lambda_param_with_default_type 1144 -#define lambda_param_maybe_default_type 1145 -#define lambda_param_type 1146 -#define strings_type 1147 -#define list_type 1148 -#define tuple_type 1149 -#define set_type 1150 -#define dict_type 1151 -#define double_starred_kvpairs_type 1152 -#define double_starred_kvpair_type 1153 -#define kvpair_type 1154 -#define for_if_clauses_type 1155 -#define for_if_clause_type 1156 -#define listcomp_type 1157 -#define setcomp_type 1158 -#define genexp_type 1159 -#define dictcomp_type 1160 -#define arguments_type 1161 -#define args_type 1162 -#define kwargs_type 1163 -#define starred_expression_type 1164 -#define kwarg_or_starred_type 1165 -#define kwarg_or_double_starred_type 1166 -#define star_targets_type 1167 -#define star_targets_list_seq_type 1168 -#define star_targets_tuple_seq_type 1169 -#define star_target_type 1170 -#define target_with_star_atom_type 1171 -#define star_atom_type 1172 -#define single_target_type 1173 -#define single_subscript_attribute_target_type 1174 -#define t_primary_type 1175 // Left-recursive -#define t_lookahead_type 1176 -#define del_targets_type 1177 -#define del_target_type 1178 -#define del_t_atom_type 1179 -#define type_expressions_type 1180 -#define func_type_comment_type 1181 -#define invalid_arguments_type 1182 -#define invalid_kwarg_type 1183 -#define expression_without_invalid_type 1184 -#define invalid_legacy_expression_type 1185 -#define invalid_expression_type 1186 -#define invalid_named_expression_type 1187 -#define invalid_assignment_type 1188 -#define invalid_ann_assign_target_type 1189 -#define invalid_del_stmt_type 1190 -#define invalid_block_type 1191 -#define invalid_comprehension_type 1192 -#define invalid_dict_comprehension_type 1193 -#define invalid_parameters_type 1194 -#define invalid_default_type 1195 -#define invalid_star_etc_type 1196 -#define invalid_kwds_type 1197 -#define invalid_parameters_helper_type 1198 -#define invalid_lambda_parameters_type 1199 -#define invalid_lambda_parameters_helper_type 1200 -#define invalid_lambda_star_etc_type 1201 -#define invalid_lambda_kwds_type 1202 -#define invalid_double_type_comments_type 1203 -#define invalid_with_item_type 1204 -#define invalid_for_target_type 1205 -#define invalid_group_type 1206 -#define invalid_import_from_targets_type 1207 -#define invalid_with_stmt_type 1208 -#define invalid_with_stmt_indent_type 1209 -#define invalid_try_stmt_type 1210 -#define invalid_except_stmt_type 1211 -#define invalid_finally_stmt_type 1212 -#define invalid_except_stmt_indent_type 1213 -#define invalid_except_star_stmt_indent_type 1214 -#define invalid_match_stmt_type 1215 -#define invalid_case_block_type 1216 -#define invalid_as_pattern_type 1217 -#define invalid_class_pattern_type 1218 -#define invalid_class_argument_pattern_type 1219 -#define invalid_if_stmt_type 1220 -#define invalid_elif_stmt_type 1221 -#define invalid_else_stmt_type 1222 -#define invalid_while_stmt_type 1223 -#define invalid_for_stmt_type 1224 -#define invalid_def_raw_type 1225 -#define invalid_class_def_raw_type 1226 -#define invalid_double_starred_kvpairs_type 1227 -#define invalid_kvpair_type 1228 -#define _loop0_1_type 1229 -#define _loop0_2_type 1230 -#define _loop1_3_type 1231 -#define _loop0_5_type 1232 -#define _gather_4_type 1233 -#define _tmp_6_type 1234 -#define _tmp_7_type 1235 -#define _tmp_8_type 1236 -#define _tmp_9_type 1237 -#define _tmp_10_type 1238 -#define _tmp_11_type 1239 -#define _tmp_12_type 1240 -#define _tmp_13_type 1241 -#define _loop1_14_type 1242 -#define _tmp_15_type 1243 -#define _tmp_16_type 1244 -#define _tmp_17_type 1245 -#define _loop0_19_type 1246 -#define _gather_18_type 1247 -#define _loop0_21_type 1248 -#define _gather_20_type 1249 -#define _tmp_22_type 1250 -#define _tmp_23_type 1251 -#define _loop0_24_type 1252 -#define _loop1_25_type 1253 -#define _loop0_27_type 1254 -#define _gather_26_type 1255 -#define _tmp_28_type 1256 -#define _loop0_30_type 1257 -#define _gather_29_type 1258 -#define _tmp_31_type 1259 -#define _loop1_32_type 1260 -#define _tmp_33_type 1261 -#define _tmp_34_type 1262 -#define _tmp_35_type 1263 -#define _loop0_36_type 1264 -#define _loop0_37_type 1265 -#define _loop0_38_type 1266 -#define _loop1_39_type 1267 -#define _loop0_40_type 1268 -#define _loop1_41_type 1269 -#define _loop1_42_type 1270 -#define _loop1_43_type 1271 -#define _loop0_44_type 1272 -#define _loop1_45_type 1273 -#define _loop0_46_type 1274 -#define _loop1_47_type 1275 -#define _loop0_48_type 1276 -#define _loop0_49_type 1277 -#define _loop1_50_type 1278 -#define _loop0_52_type 1279 -#define _gather_51_type 1280 -#define _loop0_54_type 1281 -#define _gather_53_type 1282 -#define _loop0_56_type 1283 -#define _gather_55_type 1284 -#define _loop0_58_type 1285 -#define _gather_57_type 1286 -#define _tmp_59_type 1287 -#define _loop1_60_type 1288 -#define _loop1_61_type 1289 -#define _tmp_62_type 1290 -#define _tmp_63_type 1291 -#define _loop1_64_type 1292 -#define _loop0_66_type 1293 -#define _gather_65_type 1294 -#define _tmp_67_type 1295 -#define _tmp_68_type 1296 -#define _tmp_69_type 1297 -#define _tmp_70_type 1298 -#define _loop0_72_type 1299 -#define _gather_71_type 1300 -#define _loop0_74_type 1301 -#define _gather_73_type 1302 -#define _tmp_75_type 1303 -#define _loop0_77_type 1304 -#define _gather_76_type 1305 -#define _loop0_79_type 1306 -#define _gather_78_type 1307 -#define _loop1_80_type 1308 -#define _loop1_81_type 1309 -#define _loop0_83_type 1310 -#define _gather_82_type 1311 -#define _loop1_84_type 1312 -#define _loop1_85_type 1313 -#define _loop1_86_type 1314 -#define _tmp_87_type 1315 -#define _loop0_89_type 1316 -#define _gather_88_type 1317 -#define _tmp_90_type 1318 -#define _tmp_91_type 1319 -#define _tmp_92_type 1320 -#define _tmp_93_type 1321 -#define _tmp_94_type 1322 -#define _loop0_95_type 1323 -#define _loop0_96_type 1324 -#define _loop0_97_type 1325 -#define _loop1_98_type 1326 -#define _loop0_99_type 1327 -#define _loop1_100_type 1328 -#define _loop1_101_type 1329 -#define _loop1_102_type 1330 -#define _loop0_103_type 1331 -#define _loop1_104_type 1332 -#define _loop0_105_type 1333 -#define _loop1_106_type 1334 -#define _loop0_107_type 1335 -#define _loop1_108_type 1336 -#define _loop1_109_type 1337 -#define _tmp_110_type 1338 -#define _loop0_112_type 1339 -#define _gather_111_type 1340 -#define _loop1_113_type 1341 -#define _loop0_114_type 1342 -#define _loop0_115_type 1343 -#define _tmp_116_type 1344 -#define _loop0_118_type 1345 -#define _gather_117_type 1346 -#define _tmp_119_type 1347 -#define _loop0_121_type 1348 -#define _gather_120_type 1349 -#define _loop0_123_type 1350 -#define _gather_122_type 1351 -#define _loop0_125_type 1352 -#define _gather_124_type 1353 -#define _loop0_127_type 1354 -#define _gather_126_type 1355 -#define _loop0_128_type 1356 -#define _loop0_130_type 1357 -#define _gather_129_type 1358 -#define _loop1_131_type 1359 -#define _tmp_132_type 1360 -#define _loop0_134_type 1361 -#define _gather_133_type 1362 -#define _loop0_136_type 1363 -#define _gather_135_type 1364 -#define _loop0_138_type 1365 -#define _gather_137_type 1366 -#define _loop0_140_type 1367 -#define _gather_139_type 1368 -#define _loop0_142_type 1369 -#define _gather_141_type 1370 -#define _tmp_143_type 1371 -#define _tmp_144_type 1372 -#define _tmp_145_type 1373 -#define _tmp_146_type 1374 -#define _tmp_147_type 1375 -#define _tmp_148_type 1376 -#define _tmp_149_type 1377 -#define _tmp_150_type 1378 -#define _tmp_151_type 1379 -#define _loop0_152_type 1380 -#define _loop0_153_type 1381 -#define _loop0_154_type 1382 -#define _tmp_155_type 1383 -#define _tmp_156_type 1384 -#define _tmp_157_type 1385 -#define _tmp_158_type 1386 -#define _loop0_159_type 1387 -#define _loop0_160_type 1388 -#define _loop1_161_type 1389 -#define _tmp_162_type 1390 -#define _loop0_163_type 1391 -#define _tmp_164_type 1392 -#define _loop0_165_type 1393 -#define _tmp_166_type 1394 -#define _loop0_167_type 1395 -#define _loop1_168_type 1396 -#define _tmp_169_type 1397 -#define _tmp_170_type 1398 -#define _tmp_171_type 1399 -#define _loop0_172_type 1400 -#define _tmp_173_type 1401 -#define _tmp_174_type 1402 -#define _loop1_175_type 1403 -#define _loop0_176_type 1404 -#define _loop0_177_type 1405 -#define _loop0_179_type 1406 -#define _gather_178_type 1407 -#define _tmp_180_type 1408 -#define _loop0_181_type 1409 -#define _tmp_182_type 1410 -#define _loop0_183_type 1411 -#define _tmp_184_type 1412 -#define _loop0_185_type 1413 -#define _loop1_186_type 1414 -#define _loop1_187_type 1415 -#define _tmp_188_type 1416 -#define _tmp_189_type 1417 -#define _loop0_190_type 1418 -#define _tmp_191_type 1419 -#define _tmp_192_type 1420 -#define _tmp_193_type 1421 -#define _loop0_195_type 1422 -#define _gather_194_type 1423 -#define _loop0_197_type 1424 -#define _gather_196_type 1425 -#define _loop0_199_type 1426 -#define _gather_198_type 1427 -#define _loop0_201_type 1428 -#define _gather_200_type 1429 -#define _tmp_202_type 1430 -#define _loop0_203_type 1431 -#define _loop1_204_type 1432 -#define _tmp_205_type 1433 -#define _loop0_206_type 1434 -#define _loop1_207_type 1435 -#define _tmp_208_type 1436 -#define _tmp_209_type 1437 -#define _tmp_210_type 1438 -#define _tmp_211_type 1439 -#define _tmp_212_type 1440 -#define _tmp_213_type 1441 -#define _tmp_214_type 1442 -#define _tmp_215_type 1443 -#define _tmp_216_type 1444 -#define _tmp_217_type 1445 -#define _loop0_219_type 1446 -#define _gather_218_type 1447 -#define _tmp_220_type 1448 -#define _tmp_221_type 1449 -#define _tmp_222_type 1450 -#define _tmp_223_type 1451 -#define _tmp_224_type 1452 -#define _tmp_225_type 1453 -#define _tmp_226_type 1454 -#define _tmp_227_type 1455 -#define _tmp_228_type 1456 -#define _tmp_229_type 1457 -#define _tmp_230_type 1458 -#define _tmp_231_type 1459 -#define _tmp_232_type 1460 -#define _tmp_233_type 1461 -#define _tmp_234_type 1462 -#define _tmp_235_type 1463 -#define _tmp_236_type 1464 -#define _tmp_237_type 1465 -#define _tmp_238_type 1466 -#define _tmp_239_type 1467 -#define _tmp_240_type 1468 -#define _tmp_241_type 1469 -#define _tmp_242_type 1470 -#define _tmp_243_type 1471 -#define _tmp_244_type 1472 -#define _tmp_245_type 1473 -#define _tmp_246_type 1474 -#define _tmp_247_type 1475 -#define _tmp_248_type 1476 -#define _tmp_249_type 1477 +#define type_alias_type 1098 +#define type_params_type 1099 +#define type_param_seq_type 1100 +#define type_param_type 1101 +#define type_param_bound_type 1102 +#define expressions_type 1103 +#define expression_type 1104 +#define yield_expr_type 1105 +#define star_expressions_type 1106 +#define star_expression_type 1107 +#define star_named_expressions_type 1108 +#define star_named_expression_type 1109 +#define assignment_expression_type 1110 +#define named_expression_type 1111 +#define disjunction_type 1112 +#define conjunction_type 1113 +#define inversion_type 1114 +#define comparison_type 1115 +#define compare_op_bitwise_or_pair_type 1116 +#define eq_bitwise_or_type 1117 +#define noteq_bitwise_or_type 1118 +#define lte_bitwise_or_type 1119 +#define lt_bitwise_or_type 1120 +#define gte_bitwise_or_type 1121 +#define gt_bitwise_or_type 1122 +#define notin_bitwise_or_type 1123 +#define in_bitwise_or_type 1124 +#define isnot_bitwise_or_type 1125 +#define is_bitwise_or_type 1126 +#define bitwise_or_type 1127 // Left-recursive +#define bitwise_xor_type 1128 // Left-recursive +#define bitwise_and_type 1129 // Left-recursive +#define shift_expr_type 1130 // Left-recursive +#define sum_type 1131 // Left-recursive +#define term_type 1132 // Left-recursive +#define factor_type 1133 +#define power_type 1134 +#define await_primary_type 1135 +#define primary_type 1136 // Left-recursive +#define slices_type 1137 +#define slice_type 1138 +#define atom_type 1139 +#define group_type 1140 +#define lambdef_type 1141 +#define lambda_params_type 1142 +#define lambda_parameters_type 1143 +#define lambda_slash_no_default_type 1144 +#define lambda_slash_with_default_type 1145 +#define lambda_star_etc_type 1146 +#define lambda_kwds_type 1147 +#define lambda_param_no_default_type 1148 +#define lambda_param_with_default_type 1149 +#define lambda_param_maybe_default_type 1150 +#define lambda_param_type 1151 +#define fstring_middle_type 1152 +#define fstring_replacement_field_type 1153 +#define fstring_conversion_type 1154 +#define fstring_full_format_spec_type 1155 +#define fstring_format_spec_type 1156 +#define string_type 1157 +#define strings_type 1158 +#define list_type 1159 +#define tuple_type 1160 +#define set_type 1161 +#define dict_type 1162 +#define double_starred_kvpairs_type 1163 +#define double_starred_kvpair_type 1164 +#define kvpair_type 1165 +#define for_if_clauses_type 1166 +#define for_if_clause_type 1167 +#define listcomp_type 1168 +#define setcomp_type 1169 +#define genexp_type 1170 +#define dictcomp_type 1171 +#define arguments_type 1172 +#define args_type 1173 +#define kwargs_type 1174 +#define starred_expression_type 1175 +#define kwarg_or_starred_type 1176 +#define kwarg_or_double_starred_type 1177 +#define star_targets_type 1178 +#define star_targets_list_seq_type 1179 +#define star_targets_tuple_seq_type 1180 +#define star_target_type 1181 +#define target_with_star_atom_type 1182 +#define star_atom_type 1183 +#define single_target_type 1184 +#define single_subscript_attribute_target_type 1185 +#define t_primary_type 1186 // Left-recursive +#define t_lookahead_type 1187 +#define del_targets_type 1188 +#define del_target_type 1189 +#define del_t_atom_type 1190 +#define type_expressions_type 1191 +#define func_type_comment_type 1192 +#define invalid_arguments_type 1193 +#define invalid_kwarg_type 1194 +#define expression_without_invalid_type 1195 +#define invalid_legacy_expression_type 1196 +#define invalid_expression_type 1197 +#define invalid_named_expression_type 1198 +#define invalid_assignment_type 1199 +#define invalid_ann_assign_target_type 1200 +#define invalid_del_stmt_type 1201 +#define invalid_block_type 1202 +#define invalid_comprehension_type 1203 +#define invalid_dict_comprehension_type 1204 +#define invalid_parameters_type 1205 +#define invalid_default_type 1206 +#define invalid_star_etc_type 1207 +#define invalid_kwds_type 1208 +#define invalid_parameters_helper_type 1209 +#define invalid_lambda_parameters_type 1210 +#define invalid_lambda_parameters_helper_type 1211 +#define invalid_lambda_star_etc_type 1212 +#define invalid_lambda_kwds_type 1213 +#define invalid_double_type_comments_type 1214 +#define invalid_with_item_type 1215 +#define invalid_for_target_type 1216 +#define invalid_group_type 1217 +#define invalid_import_type 1218 +#define invalid_import_from_targets_type 1219 +#define invalid_with_stmt_type 1220 +#define invalid_with_stmt_indent_type 1221 +#define invalid_try_stmt_type 1222 +#define invalid_except_stmt_type 1223 +#define invalid_finally_stmt_type 1224 +#define invalid_except_stmt_indent_type 1225 +#define invalid_except_star_stmt_indent_type 1226 +#define invalid_match_stmt_type 1227 +#define invalid_case_block_type 1228 +#define invalid_as_pattern_type 1229 +#define invalid_class_pattern_type 1230 +#define invalid_class_argument_pattern_type 1231 +#define invalid_if_stmt_type 1232 +#define invalid_elif_stmt_type 1233 +#define invalid_else_stmt_type 1234 +#define invalid_while_stmt_type 1235 +#define invalid_for_stmt_type 1236 +#define invalid_def_raw_type 1237 +#define invalid_class_def_raw_type 1238 +#define invalid_double_starred_kvpairs_type 1239 +#define invalid_kvpair_type 1240 +#define invalid_starred_expression_type 1241 +#define invalid_replacement_field_type 1242 +#define invalid_conversion_character_type 1243 +#define _loop0_1_type 1244 +#define _loop0_2_type 1245 +#define _loop0_3_type 1246 +#define _loop1_4_type 1247 +#define _loop0_6_type 1248 +#define _gather_5_type 1249 +#define _tmp_7_type 1250 +#define _tmp_8_type 1251 +#define _tmp_9_type 1252 +#define _tmp_10_type 1253 +#define _tmp_11_type 1254 +#define _tmp_12_type 1255 +#define _tmp_13_type 1256 +#define _tmp_14_type 1257 +#define _loop1_15_type 1258 +#define _tmp_16_type 1259 +#define _tmp_17_type 1260 +#define _tmp_18_type 1261 +#define _loop0_20_type 1262 +#define _gather_19_type 1263 +#define _loop0_22_type 1264 +#define _gather_21_type 1265 +#define _tmp_23_type 1266 +#define _tmp_24_type 1267 +#define _loop0_25_type 1268 +#define _loop1_26_type 1269 +#define _loop0_28_type 1270 +#define _gather_27_type 1271 +#define _tmp_29_type 1272 +#define _loop0_31_type 1273 +#define _gather_30_type 1274 +#define _tmp_32_type 1275 +#define _loop1_33_type 1276 +#define _tmp_34_type 1277 +#define _tmp_35_type 1278 +#define _tmp_36_type 1279 +#define _loop0_37_type 1280 +#define _loop0_38_type 1281 +#define _loop0_39_type 1282 +#define _loop1_40_type 1283 +#define _loop0_41_type 1284 +#define _loop1_42_type 1285 +#define _loop1_43_type 1286 +#define _loop1_44_type 1287 +#define _loop0_45_type 1288 +#define _loop1_46_type 1289 +#define _loop0_47_type 1290 +#define _loop1_48_type 1291 +#define _loop0_49_type 1292 +#define _loop0_50_type 1293 +#define _loop1_51_type 1294 +#define _loop0_53_type 1295 +#define _gather_52_type 1296 +#define _loop0_55_type 1297 +#define _gather_54_type 1298 +#define _loop0_57_type 1299 +#define _gather_56_type 1300 +#define _loop0_59_type 1301 +#define _gather_58_type 1302 +#define _tmp_60_type 1303 +#define _loop1_61_type 1304 +#define _loop1_62_type 1305 +#define _tmp_63_type 1306 +#define _tmp_64_type 1307 +#define _loop1_65_type 1308 +#define _loop0_67_type 1309 +#define _gather_66_type 1310 +#define _tmp_68_type 1311 +#define _tmp_69_type 1312 +#define _tmp_70_type 1313 +#define _tmp_71_type 1314 +#define _loop0_73_type 1315 +#define _gather_72_type 1316 +#define _loop0_75_type 1317 +#define _gather_74_type 1318 +#define _tmp_76_type 1319 +#define _loop0_78_type 1320 +#define _gather_77_type 1321 +#define _loop0_80_type 1322 +#define _gather_79_type 1323 +#define _loop0_82_type 1324 +#define _gather_81_type 1325 +#define _loop1_83_type 1326 +#define _loop1_84_type 1327 +#define _loop0_86_type 1328 +#define _gather_85_type 1329 +#define _loop1_87_type 1330 +#define _loop1_88_type 1331 +#define _loop1_89_type 1332 +#define _tmp_90_type 1333 +#define _loop0_92_type 1334 +#define _gather_91_type 1335 +#define _tmp_93_type 1336 +#define _tmp_94_type 1337 +#define _tmp_95_type 1338 +#define _tmp_96_type 1339 +#define _tmp_97_type 1340 +#define _tmp_98_type 1341 +#define _loop0_99_type 1342 +#define _loop0_100_type 1343 +#define _loop0_101_type 1344 +#define _loop1_102_type 1345 +#define _loop0_103_type 1346 +#define _loop1_104_type 1347 +#define _loop1_105_type 1348 +#define _loop1_106_type 1349 +#define _loop0_107_type 1350 +#define _loop1_108_type 1351 +#define _loop0_109_type 1352 +#define _loop1_110_type 1353 +#define _loop0_111_type 1354 +#define _loop1_112_type 1355 +#define _tmp_113_type 1356 +#define _loop0_114_type 1357 +#define _loop1_115_type 1358 +#define _tmp_116_type 1359 +#define _loop0_118_type 1360 +#define _gather_117_type 1361 +#define _loop1_119_type 1362 +#define _loop0_120_type 1363 +#define _loop0_121_type 1364 +#define _tmp_122_type 1365 +#define _loop0_124_type 1366 +#define _gather_123_type 1367 +#define _tmp_125_type 1368 +#define _loop0_127_type 1369 +#define _gather_126_type 1370 +#define _loop0_129_type 1371 +#define _gather_128_type 1372 +#define _loop0_131_type 1373 +#define _gather_130_type 1374 +#define _loop0_133_type 1375 +#define _gather_132_type 1376 +#define _loop0_134_type 1377 +#define _loop0_136_type 1378 +#define _gather_135_type 1379 +#define _loop1_137_type 1380 +#define _tmp_138_type 1381 +#define _loop0_140_type 1382 +#define _gather_139_type 1383 +#define _loop0_142_type 1384 +#define _gather_141_type 1385 +#define _loop0_144_type 1386 +#define _gather_143_type 1387 +#define _loop0_146_type 1388 +#define _gather_145_type 1389 +#define _loop0_148_type 1390 +#define _gather_147_type 1391 +#define _tmp_149_type 1392 +#define _tmp_150_type 1393 +#define _tmp_151_type 1394 +#define _tmp_152_type 1395 +#define _tmp_153_type 1396 +#define _tmp_154_type 1397 +#define _tmp_155_type 1398 +#define _tmp_156_type 1399 +#define _tmp_157_type 1400 +#define _tmp_158_type 1401 +#define _tmp_159_type 1402 +#define _loop0_160_type 1403 +#define _loop0_161_type 1404 +#define _loop0_162_type 1405 +#define _tmp_163_type 1406 +#define _tmp_164_type 1407 +#define _tmp_165_type 1408 +#define _tmp_166_type 1409 +#define _tmp_167_type 1410 +#define _loop0_168_type 1411 +#define _loop0_169_type 1412 +#define _loop0_170_type 1413 +#define _loop1_171_type 1414 +#define _tmp_172_type 1415 +#define _loop0_173_type 1416 +#define _tmp_174_type 1417 +#define _loop0_175_type 1418 +#define _loop1_176_type 1419 +#define _tmp_177_type 1420 +#define _tmp_178_type 1421 +#define _tmp_179_type 1422 +#define _loop0_180_type 1423 +#define _tmp_181_type 1424 +#define _tmp_182_type 1425 +#define _loop1_183_type 1426 +#define _tmp_184_type 1427 +#define _loop0_185_type 1428 +#define _loop0_186_type 1429 +#define _loop0_187_type 1430 +#define _loop0_189_type 1431 +#define _gather_188_type 1432 +#define _tmp_190_type 1433 +#define _loop0_191_type 1434 +#define _tmp_192_type 1435 +#define _loop0_193_type 1436 +#define _loop1_194_type 1437 +#define _loop1_195_type 1438 +#define _tmp_196_type 1439 +#define _tmp_197_type 1440 +#define _loop0_198_type 1441 +#define _tmp_199_type 1442 +#define _tmp_200_type 1443 +#define _tmp_201_type 1444 +#define _loop0_203_type 1445 +#define _gather_202_type 1446 +#define _loop0_205_type 1447 +#define _gather_204_type 1448 +#define _loop0_207_type 1449 +#define _gather_206_type 1450 +#define _loop0_209_type 1451 +#define _gather_208_type 1452 +#define _loop0_211_type 1453 +#define _gather_210_type 1454 +#define _tmp_212_type 1455 +#define _loop0_213_type 1456 +#define _loop1_214_type 1457 +#define _tmp_215_type 1458 +#define _loop0_216_type 1459 +#define _loop1_217_type 1460 +#define _tmp_218_type 1461 +#define _tmp_219_type 1462 +#define _tmp_220_type 1463 +#define _tmp_221_type 1464 +#define _tmp_222_type 1465 +#define _tmp_223_type 1466 +#define _tmp_224_type 1467 +#define _tmp_225_type 1468 +#define _tmp_226_type 1469 +#define _tmp_227_type 1470 +#define _loop0_229_type 1471 +#define _gather_228_type 1472 +#define _tmp_230_type 1473 +#define _tmp_231_type 1474 +#define _tmp_232_type 1475 +#define _tmp_233_type 1476 +#define _tmp_234_type 1477 +#define _tmp_235_type 1478 +#define _tmp_236_type 1479 +#define _tmp_237_type 1480 +#define _tmp_238_type 1481 +#define _tmp_239_type 1482 +#define _tmp_240_type 1483 +#define _tmp_241_type 1484 +#define _tmp_242_type 1485 +#define _loop0_243_type 1486 +#define _tmp_244_type 1487 +#define _tmp_245_type 1488 +#define _tmp_246_type 1489 +#define _tmp_247_type 1490 +#define _tmp_248_type 1491 +#define _tmp_249_type 1492 +#define _tmp_250_type 1493 +#define _tmp_251_type 1494 +#define _tmp_252_type 1495 +#define _tmp_253_type 1496 +#define _tmp_254_type 1497 +#define _tmp_255_type 1498 +#define _tmp_256_type 1499 +#define _tmp_257_type 1500 +#define _tmp_258_type 1501 +#define _tmp_259_type 1502 +#define _tmp_260_type 1503 +#define _tmp_261_type 1504 +#define _tmp_262_type 1505 +#define _tmp_263_type 1506 +#define _tmp_264_type 1507 +#define _tmp_265_type 1508 +#define _tmp_266_type 1509 +#define _tmp_267_type 1510 +#define _tmp_268_type 1511 +#define _tmp_269_type 1512 +#define _tmp_270_type 1513 +#define _tmp_271_type 1514 +#define _tmp_272_type 1515 +#define _tmp_273_type 1516 +#define _tmp_274_type 1517 +#define _tmp_275_type 1518 static mod_ty file_rule(Parser *p); static mod_ty interactive_rule(Parser *p); @@ -654,6 +696,11 @@ static pattern_ty class_pattern_rule(Parser *p); static asdl_pattern_seq* positional_patterns_rule(Parser *p); static asdl_seq* keyword_patterns_rule(Parser *p); static KeyPatternPair* keyword_pattern_rule(Parser *p); +static stmt_ty type_alias_rule(Parser *p); +static asdl_type_param_seq* type_params_rule(Parser *p); +static asdl_type_param_seq* type_param_seq_rule(Parser *p); +static type_param_ty type_param_rule(Parser *p); +static expr_ty type_param_bound_rule(Parser *p); static expr_ty expressions_rule(Parser *p); static expr_ty expression_rule(Parser *p); static expr_ty yield_expr_rule(Parser *p); @@ -703,6 +750,12 @@ static arg_ty lambda_param_no_default_rule(Parser *p); static NameDefaultPair* lambda_param_with_default_rule(Parser *p); static NameDefaultPair* lambda_param_maybe_default_rule(Parser *p); static arg_ty lambda_param_rule(Parser *p); +static expr_ty fstring_middle_rule(Parser *p); +static expr_ty fstring_replacement_field_rule(Parser *p); +static ResultTokenWithMetadata* fstring_conversion_rule(Parser *p); +static ResultTokenWithMetadata* fstring_full_format_spec_rule(Parser *p); +static expr_ty fstring_format_spec_rule(Parser *p); +static expr_ty string_rule(Parser *p); static expr_ty strings_rule(Parser *p); static expr_ty list_rule(Parser *p); static expr_ty tuple_rule(Parser *p); @@ -763,6 +816,7 @@ static void *invalid_double_type_comments_rule(Parser *p); static void *invalid_with_item_rule(Parser *p); static void *invalid_for_target_rule(Parser *p); static void *invalid_group_rule(Parser *p); +static void *invalid_import_rule(Parser *p); static void *invalid_import_from_targets_rule(Parser *p); static void *invalid_with_stmt_rule(Parser *p); static void *invalid_with_stmt_indent_rule(Parser *p); @@ -785,12 +839,15 @@ static void *invalid_def_raw_rule(Parser *p); static void *invalid_class_def_raw_rule(Parser *p); static void *invalid_double_starred_kvpairs_rule(Parser *p); static void *invalid_kvpair_rule(Parser *p); +static void *invalid_starred_expression_rule(Parser *p); +static void *invalid_replacement_field_rule(Parser *p); +static void *invalid_conversion_character_rule(Parser *p); static asdl_seq *_loop0_1_rule(Parser *p); static asdl_seq *_loop0_2_rule(Parser *p); -static asdl_seq *_loop1_3_rule(Parser *p); -static asdl_seq *_loop0_5_rule(Parser *p); -static asdl_seq *_gather_4_rule(Parser *p); -static void *_tmp_6_rule(Parser *p); +static asdl_seq *_loop0_3_rule(Parser *p); +static asdl_seq *_loop1_4_rule(Parser *p); +static asdl_seq *_loop0_6_rule(Parser *p); +static asdl_seq *_gather_5_rule(Parser *p); static void *_tmp_7_rule(Parser *p); static void *_tmp_8_rule(Parser *p); static void *_tmp_9_rule(Parser *p); @@ -798,212 +855,212 @@ static void *_tmp_10_rule(Parser *p); static void *_tmp_11_rule(Parser *p); static void *_tmp_12_rule(Parser *p); static void *_tmp_13_rule(Parser *p); -static asdl_seq *_loop1_14_rule(Parser *p); -static void *_tmp_15_rule(Parser *p); +static void *_tmp_14_rule(Parser *p); +static asdl_seq *_loop1_15_rule(Parser *p); static void *_tmp_16_rule(Parser *p); static void *_tmp_17_rule(Parser *p); -static asdl_seq *_loop0_19_rule(Parser *p); -static asdl_seq *_gather_18_rule(Parser *p); -static asdl_seq *_loop0_21_rule(Parser *p); -static asdl_seq *_gather_20_rule(Parser *p); -static void *_tmp_22_rule(Parser *p); +static void *_tmp_18_rule(Parser *p); +static asdl_seq *_loop0_20_rule(Parser *p); +static asdl_seq *_gather_19_rule(Parser *p); +static asdl_seq *_loop0_22_rule(Parser *p); +static asdl_seq *_gather_21_rule(Parser *p); static void *_tmp_23_rule(Parser *p); -static asdl_seq *_loop0_24_rule(Parser *p); -static asdl_seq *_loop1_25_rule(Parser *p); -static asdl_seq *_loop0_27_rule(Parser *p); -static asdl_seq *_gather_26_rule(Parser *p); -static void *_tmp_28_rule(Parser *p); -static asdl_seq *_loop0_30_rule(Parser *p); -static asdl_seq *_gather_29_rule(Parser *p); -static void *_tmp_31_rule(Parser *p); -static asdl_seq *_loop1_32_rule(Parser *p); -static void *_tmp_33_rule(Parser *p); +static void *_tmp_24_rule(Parser *p); +static asdl_seq *_loop0_25_rule(Parser *p); +static asdl_seq *_loop1_26_rule(Parser *p); +static asdl_seq *_loop0_28_rule(Parser *p); +static asdl_seq *_gather_27_rule(Parser *p); +static void *_tmp_29_rule(Parser *p); +static asdl_seq *_loop0_31_rule(Parser *p); +static asdl_seq *_gather_30_rule(Parser *p); +static void *_tmp_32_rule(Parser *p); +static asdl_seq *_loop1_33_rule(Parser *p); static void *_tmp_34_rule(Parser *p); static void *_tmp_35_rule(Parser *p); -static asdl_seq *_loop0_36_rule(Parser *p); +static void *_tmp_36_rule(Parser *p); static asdl_seq *_loop0_37_rule(Parser *p); static asdl_seq *_loop0_38_rule(Parser *p); -static asdl_seq *_loop1_39_rule(Parser *p); -static asdl_seq *_loop0_40_rule(Parser *p); -static asdl_seq *_loop1_41_rule(Parser *p); +static asdl_seq *_loop0_39_rule(Parser *p); +static asdl_seq *_loop1_40_rule(Parser *p); +static asdl_seq *_loop0_41_rule(Parser *p); static asdl_seq *_loop1_42_rule(Parser *p); static asdl_seq *_loop1_43_rule(Parser *p); -static asdl_seq *_loop0_44_rule(Parser *p); -static asdl_seq *_loop1_45_rule(Parser *p); -static asdl_seq *_loop0_46_rule(Parser *p); -static asdl_seq *_loop1_47_rule(Parser *p); -static asdl_seq *_loop0_48_rule(Parser *p); +static asdl_seq *_loop1_44_rule(Parser *p); +static asdl_seq *_loop0_45_rule(Parser *p); +static asdl_seq *_loop1_46_rule(Parser *p); +static asdl_seq *_loop0_47_rule(Parser *p); +static asdl_seq *_loop1_48_rule(Parser *p); static asdl_seq *_loop0_49_rule(Parser *p); -static asdl_seq *_loop1_50_rule(Parser *p); -static asdl_seq *_loop0_52_rule(Parser *p); -static asdl_seq *_gather_51_rule(Parser *p); -static asdl_seq *_loop0_54_rule(Parser *p); -static asdl_seq *_gather_53_rule(Parser *p); -static asdl_seq *_loop0_56_rule(Parser *p); -static asdl_seq *_gather_55_rule(Parser *p); -static asdl_seq *_loop0_58_rule(Parser *p); -static asdl_seq *_gather_57_rule(Parser *p); -static void *_tmp_59_rule(Parser *p); -static asdl_seq *_loop1_60_rule(Parser *p); +static asdl_seq *_loop0_50_rule(Parser *p); +static asdl_seq *_loop1_51_rule(Parser *p); +static asdl_seq *_loop0_53_rule(Parser *p); +static asdl_seq *_gather_52_rule(Parser *p); +static asdl_seq *_loop0_55_rule(Parser *p); +static asdl_seq *_gather_54_rule(Parser *p); +static asdl_seq *_loop0_57_rule(Parser *p); +static asdl_seq *_gather_56_rule(Parser *p); +static asdl_seq *_loop0_59_rule(Parser *p); +static asdl_seq *_gather_58_rule(Parser *p); +static void *_tmp_60_rule(Parser *p); static asdl_seq *_loop1_61_rule(Parser *p); -static void *_tmp_62_rule(Parser *p); +static asdl_seq *_loop1_62_rule(Parser *p); static void *_tmp_63_rule(Parser *p); -static asdl_seq *_loop1_64_rule(Parser *p); -static asdl_seq *_loop0_66_rule(Parser *p); -static asdl_seq *_gather_65_rule(Parser *p); -static void *_tmp_67_rule(Parser *p); +static void *_tmp_64_rule(Parser *p); +static asdl_seq *_loop1_65_rule(Parser *p); +static asdl_seq *_loop0_67_rule(Parser *p); +static asdl_seq *_gather_66_rule(Parser *p); static void *_tmp_68_rule(Parser *p); static void *_tmp_69_rule(Parser *p); static void *_tmp_70_rule(Parser *p); -static asdl_seq *_loop0_72_rule(Parser *p); -static asdl_seq *_gather_71_rule(Parser *p); -static asdl_seq *_loop0_74_rule(Parser *p); -static asdl_seq *_gather_73_rule(Parser *p); -static void *_tmp_75_rule(Parser *p); -static asdl_seq *_loop0_77_rule(Parser *p); -static asdl_seq *_gather_76_rule(Parser *p); -static asdl_seq *_loop0_79_rule(Parser *p); -static asdl_seq *_gather_78_rule(Parser *p); -static asdl_seq *_loop1_80_rule(Parser *p); -static asdl_seq *_loop1_81_rule(Parser *p); -static asdl_seq *_loop0_83_rule(Parser *p); -static asdl_seq *_gather_82_rule(Parser *p); +static void *_tmp_71_rule(Parser *p); +static asdl_seq *_loop0_73_rule(Parser *p); +static asdl_seq *_gather_72_rule(Parser *p); +static asdl_seq *_loop0_75_rule(Parser *p); +static asdl_seq *_gather_74_rule(Parser *p); +static void *_tmp_76_rule(Parser *p); +static asdl_seq *_loop0_78_rule(Parser *p); +static asdl_seq *_gather_77_rule(Parser *p); +static asdl_seq *_loop0_80_rule(Parser *p); +static asdl_seq *_gather_79_rule(Parser *p); +static asdl_seq *_loop0_82_rule(Parser *p); +static asdl_seq *_gather_81_rule(Parser *p); +static asdl_seq *_loop1_83_rule(Parser *p); static asdl_seq *_loop1_84_rule(Parser *p); -static asdl_seq *_loop1_85_rule(Parser *p); -static asdl_seq *_loop1_86_rule(Parser *p); -static void *_tmp_87_rule(Parser *p); -static asdl_seq *_loop0_89_rule(Parser *p); -static asdl_seq *_gather_88_rule(Parser *p); +static asdl_seq *_loop0_86_rule(Parser *p); +static asdl_seq *_gather_85_rule(Parser *p); +static asdl_seq *_loop1_87_rule(Parser *p); +static asdl_seq *_loop1_88_rule(Parser *p); +static asdl_seq *_loop1_89_rule(Parser *p); static void *_tmp_90_rule(Parser *p); -static void *_tmp_91_rule(Parser *p); -static void *_tmp_92_rule(Parser *p); +static asdl_seq *_loop0_92_rule(Parser *p); +static asdl_seq *_gather_91_rule(Parser *p); static void *_tmp_93_rule(Parser *p); static void *_tmp_94_rule(Parser *p); -static asdl_seq *_loop0_95_rule(Parser *p); -static asdl_seq *_loop0_96_rule(Parser *p); -static asdl_seq *_loop0_97_rule(Parser *p); -static asdl_seq *_loop1_98_rule(Parser *p); +static void *_tmp_95_rule(Parser *p); +static void *_tmp_96_rule(Parser *p); +static void *_tmp_97_rule(Parser *p); +static void *_tmp_98_rule(Parser *p); static asdl_seq *_loop0_99_rule(Parser *p); -static asdl_seq *_loop1_100_rule(Parser *p); -static asdl_seq *_loop1_101_rule(Parser *p); +static asdl_seq *_loop0_100_rule(Parser *p); +static asdl_seq *_loop0_101_rule(Parser *p); static asdl_seq *_loop1_102_rule(Parser *p); static asdl_seq *_loop0_103_rule(Parser *p); static asdl_seq *_loop1_104_rule(Parser *p); -static asdl_seq *_loop0_105_rule(Parser *p); +static asdl_seq *_loop1_105_rule(Parser *p); static asdl_seq *_loop1_106_rule(Parser *p); static asdl_seq *_loop0_107_rule(Parser *p); static asdl_seq *_loop1_108_rule(Parser *p); -static asdl_seq *_loop1_109_rule(Parser *p); -static void *_tmp_110_rule(Parser *p); -static asdl_seq *_loop0_112_rule(Parser *p); -static asdl_seq *_gather_111_rule(Parser *p); -static asdl_seq *_loop1_113_rule(Parser *p); +static asdl_seq *_loop0_109_rule(Parser *p); +static asdl_seq *_loop1_110_rule(Parser *p); +static asdl_seq *_loop0_111_rule(Parser *p); +static asdl_seq *_loop1_112_rule(Parser *p); +static void *_tmp_113_rule(Parser *p); static asdl_seq *_loop0_114_rule(Parser *p); -static asdl_seq *_loop0_115_rule(Parser *p); +static asdl_seq *_loop1_115_rule(Parser *p); static void *_tmp_116_rule(Parser *p); static asdl_seq *_loop0_118_rule(Parser *p); static asdl_seq *_gather_117_rule(Parser *p); -static void *_tmp_119_rule(Parser *p); +static asdl_seq *_loop1_119_rule(Parser *p); +static asdl_seq *_loop0_120_rule(Parser *p); static asdl_seq *_loop0_121_rule(Parser *p); -static asdl_seq *_gather_120_rule(Parser *p); -static asdl_seq *_loop0_123_rule(Parser *p); -static asdl_seq *_gather_122_rule(Parser *p); -static asdl_seq *_loop0_125_rule(Parser *p); -static asdl_seq *_gather_124_rule(Parser *p); +static void *_tmp_122_rule(Parser *p); +static asdl_seq *_loop0_124_rule(Parser *p); +static asdl_seq *_gather_123_rule(Parser *p); +static void *_tmp_125_rule(Parser *p); static asdl_seq *_loop0_127_rule(Parser *p); static asdl_seq *_gather_126_rule(Parser *p); -static asdl_seq *_loop0_128_rule(Parser *p); -static asdl_seq *_loop0_130_rule(Parser *p); -static asdl_seq *_gather_129_rule(Parser *p); -static asdl_seq *_loop1_131_rule(Parser *p); -static void *_tmp_132_rule(Parser *p); +static asdl_seq *_loop0_129_rule(Parser *p); +static asdl_seq *_gather_128_rule(Parser *p); +static asdl_seq *_loop0_131_rule(Parser *p); +static asdl_seq *_gather_130_rule(Parser *p); +static asdl_seq *_loop0_133_rule(Parser *p); +static asdl_seq *_gather_132_rule(Parser *p); static asdl_seq *_loop0_134_rule(Parser *p); -static asdl_seq *_gather_133_rule(Parser *p); static asdl_seq *_loop0_136_rule(Parser *p); static asdl_seq *_gather_135_rule(Parser *p); -static asdl_seq *_loop0_138_rule(Parser *p); -static asdl_seq *_gather_137_rule(Parser *p); +static asdl_seq *_loop1_137_rule(Parser *p); +static void *_tmp_138_rule(Parser *p); static asdl_seq *_loop0_140_rule(Parser *p); static asdl_seq *_gather_139_rule(Parser *p); static asdl_seq *_loop0_142_rule(Parser *p); static asdl_seq *_gather_141_rule(Parser *p); -static void *_tmp_143_rule(Parser *p); -static void *_tmp_144_rule(Parser *p); -static void *_tmp_145_rule(Parser *p); -static void *_tmp_146_rule(Parser *p); -static void *_tmp_147_rule(Parser *p); -static void *_tmp_148_rule(Parser *p); +static asdl_seq *_loop0_144_rule(Parser *p); +static asdl_seq *_gather_143_rule(Parser *p); +static asdl_seq *_loop0_146_rule(Parser *p); +static asdl_seq *_gather_145_rule(Parser *p); +static asdl_seq *_loop0_148_rule(Parser *p); +static asdl_seq *_gather_147_rule(Parser *p); static void *_tmp_149_rule(Parser *p); static void *_tmp_150_rule(Parser *p); static void *_tmp_151_rule(Parser *p); -static asdl_seq *_loop0_152_rule(Parser *p); -static asdl_seq *_loop0_153_rule(Parser *p); -static asdl_seq *_loop0_154_rule(Parser *p); +static void *_tmp_152_rule(Parser *p); +static void *_tmp_153_rule(Parser *p); +static void *_tmp_154_rule(Parser *p); static void *_tmp_155_rule(Parser *p); static void *_tmp_156_rule(Parser *p); static void *_tmp_157_rule(Parser *p); static void *_tmp_158_rule(Parser *p); -static asdl_seq *_loop0_159_rule(Parser *p); +static void *_tmp_159_rule(Parser *p); static asdl_seq *_loop0_160_rule(Parser *p); -static asdl_seq *_loop1_161_rule(Parser *p); -static void *_tmp_162_rule(Parser *p); -static asdl_seq *_loop0_163_rule(Parser *p); +static asdl_seq *_loop0_161_rule(Parser *p); +static asdl_seq *_loop0_162_rule(Parser *p); +static void *_tmp_163_rule(Parser *p); static void *_tmp_164_rule(Parser *p); -static asdl_seq *_loop0_165_rule(Parser *p); +static void *_tmp_165_rule(Parser *p); static void *_tmp_166_rule(Parser *p); -static asdl_seq *_loop0_167_rule(Parser *p); -static asdl_seq *_loop1_168_rule(Parser *p); -static void *_tmp_169_rule(Parser *p); -static void *_tmp_170_rule(Parser *p); -static void *_tmp_171_rule(Parser *p); -static asdl_seq *_loop0_172_rule(Parser *p); -static void *_tmp_173_rule(Parser *p); +static void *_tmp_167_rule(Parser *p); +static asdl_seq *_loop0_168_rule(Parser *p); +static asdl_seq *_loop0_169_rule(Parser *p); +static asdl_seq *_loop0_170_rule(Parser *p); +static asdl_seq *_loop1_171_rule(Parser *p); +static void *_tmp_172_rule(Parser *p); +static asdl_seq *_loop0_173_rule(Parser *p); static void *_tmp_174_rule(Parser *p); -static asdl_seq *_loop1_175_rule(Parser *p); -static asdl_seq *_loop0_176_rule(Parser *p); -static asdl_seq *_loop0_177_rule(Parser *p); -static asdl_seq *_loop0_179_rule(Parser *p); -static asdl_seq *_gather_178_rule(Parser *p); -static void *_tmp_180_rule(Parser *p); -static asdl_seq *_loop0_181_rule(Parser *p); +static asdl_seq *_loop0_175_rule(Parser *p); +static asdl_seq *_loop1_176_rule(Parser *p); +static void *_tmp_177_rule(Parser *p); +static void *_tmp_178_rule(Parser *p); +static void *_tmp_179_rule(Parser *p); +static asdl_seq *_loop0_180_rule(Parser *p); +static void *_tmp_181_rule(Parser *p); static void *_tmp_182_rule(Parser *p); -static asdl_seq *_loop0_183_rule(Parser *p); +static asdl_seq *_loop1_183_rule(Parser *p); static void *_tmp_184_rule(Parser *p); static asdl_seq *_loop0_185_rule(Parser *p); -static asdl_seq *_loop1_186_rule(Parser *p); -static asdl_seq *_loop1_187_rule(Parser *p); -static void *_tmp_188_rule(Parser *p); -static void *_tmp_189_rule(Parser *p); -static asdl_seq *_loop0_190_rule(Parser *p); -static void *_tmp_191_rule(Parser *p); +static asdl_seq *_loop0_186_rule(Parser *p); +static asdl_seq *_loop0_187_rule(Parser *p); +static asdl_seq *_loop0_189_rule(Parser *p); +static asdl_seq *_gather_188_rule(Parser *p); +static void *_tmp_190_rule(Parser *p); +static asdl_seq *_loop0_191_rule(Parser *p); static void *_tmp_192_rule(Parser *p); -static void *_tmp_193_rule(Parser *p); -static asdl_seq *_loop0_195_rule(Parser *p); -static asdl_seq *_gather_194_rule(Parser *p); -static asdl_seq *_loop0_197_rule(Parser *p); -static asdl_seq *_gather_196_rule(Parser *p); -static asdl_seq *_loop0_199_rule(Parser *p); -static asdl_seq *_gather_198_rule(Parser *p); -static asdl_seq *_loop0_201_rule(Parser *p); -static asdl_seq *_gather_200_rule(Parser *p); -static void *_tmp_202_rule(Parser *p); +static asdl_seq *_loop0_193_rule(Parser *p); +static asdl_seq *_loop1_194_rule(Parser *p); +static asdl_seq *_loop1_195_rule(Parser *p); +static void *_tmp_196_rule(Parser *p); +static void *_tmp_197_rule(Parser *p); +static asdl_seq *_loop0_198_rule(Parser *p); +static void *_tmp_199_rule(Parser *p); +static void *_tmp_200_rule(Parser *p); +static void *_tmp_201_rule(Parser *p); static asdl_seq *_loop0_203_rule(Parser *p); -static asdl_seq *_loop1_204_rule(Parser *p); -static void *_tmp_205_rule(Parser *p); -static asdl_seq *_loop0_206_rule(Parser *p); -static asdl_seq *_loop1_207_rule(Parser *p); -static void *_tmp_208_rule(Parser *p); -static void *_tmp_209_rule(Parser *p); -static void *_tmp_210_rule(Parser *p); -static void *_tmp_211_rule(Parser *p); +static asdl_seq *_gather_202_rule(Parser *p); +static asdl_seq *_loop0_205_rule(Parser *p); +static asdl_seq *_gather_204_rule(Parser *p); +static asdl_seq *_loop0_207_rule(Parser *p); +static asdl_seq *_gather_206_rule(Parser *p); +static asdl_seq *_loop0_209_rule(Parser *p); +static asdl_seq *_gather_208_rule(Parser *p); +static asdl_seq *_loop0_211_rule(Parser *p); +static asdl_seq *_gather_210_rule(Parser *p); static void *_tmp_212_rule(Parser *p); -static void *_tmp_213_rule(Parser *p); -static void *_tmp_214_rule(Parser *p); +static asdl_seq *_loop0_213_rule(Parser *p); +static asdl_seq *_loop1_214_rule(Parser *p); static void *_tmp_215_rule(Parser *p); -static void *_tmp_216_rule(Parser *p); -static void *_tmp_217_rule(Parser *p); -static asdl_seq *_loop0_219_rule(Parser *p); -static asdl_seq *_gather_218_rule(Parser *p); +static asdl_seq *_loop0_216_rule(Parser *p); +static asdl_seq *_loop1_217_rule(Parser *p); +static void *_tmp_218_rule(Parser *p); +static void *_tmp_219_rule(Parser *p); static void *_tmp_220_rule(Parser *p); static void *_tmp_221_rule(Parser *p); static void *_tmp_222_rule(Parser *p); @@ -1012,8 +1069,8 @@ static void *_tmp_224_rule(Parser *p); static void *_tmp_225_rule(Parser *p); static void *_tmp_226_rule(Parser *p); static void *_tmp_227_rule(Parser *p); -static void *_tmp_228_rule(Parser *p); -static void *_tmp_229_rule(Parser *p); +static asdl_seq *_loop0_229_rule(Parser *p); +static asdl_seq *_gather_228_rule(Parser *p); static void *_tmp_230_rule(Parser *p); static void *_tmp_231_rule(Parser *p); static void *_tmp_232_rule(Parser *p); @@ -1027,13 +1084,39 @@ static void *_tmp_239_rule(Parser *p); static void *_tmp_240_rule(Parser *p); static void *_tmp_241_rule(Parser *p); static void *_tmp_242_rule(Parser *p); -static void *_tmp_243_rule(Parser *p); +static asdl_seq *_loop0_243_rule(Parser *p); static void *_tmp_244_rule(Parser *p); static void *_tmp_245_rule(Parser *p); static void *_tmp_246_rule(Parser *p); static void *_tmp_247_rule(Parser *p); static void *_tmp_248_rule(Parser *p); static void *_tmp_249_rule(Parser *p); +static void *_tmp_250_rule(Parser *p); +static void *_tmp_251_rule(Parser *p); +static void *_tmp_252_rule(Parser *p); +static void *_tmp_253_rule(Parser *p); +static void *_tmp_254_rule(Parser *p); +static void *_tmp_255_rule(Parser *p); +static void *_tmp_256_rule(Parser *p); +static void *_tmp_257_rule(Parser *p); +static void *_tmp_258_rule(Parser *p); +static void *_tmp_259_rule(Parser *p); +static void *_tmp_260_rule(Parser *p); +static void *_tmp_261_rule(Parser *p); +static void *_tmp_262_rule(Parser *p); +static void *_tmp_263_rule(Parser *p); +static void *_tmp_264_rule(Parser *p); +static void *_tmp_265_rule(Parser *p); +static void *_tmp_266_rule(Parser *p); +static void *_tmp_267_rule(Parser *p); +static void *_tmp_268_rule(Parser *p); +static void *_tmp_269_rule(Parser *p); +static void *_tmp_270_rule(Parser *p); +static void *_tmp_271_rule(Parser *p); +static void *_tmp_272_rule(Parser *p); +static void *_tmp_273_rule(Parser *p); +static void *_tmp_274_rule(Parser *p); +static void *_tmp_275_rule(Parser *p); // file: statements? $ @@ -1041,8 +1124,7 @@ static mod_ty file_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -1088,8 +1170,7 @@ static mod_ty interactive_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -1132,8 +1213,7 @@ static mod_ty eval_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -1182,8 +1262,7 @@ static mod_ty func_type_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -1239,13 +1318,12 @@ func_type_rule(Parser *p) return _res; } -// fstring: star_expressions +// fstring: FSTRING_START fstring_middle* FSTRING_END static expr_ty fstring_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -1253,24 +1331,35 @@ fstring_rule(Parser *p) } expr_ty _res = NULL; int _mark = p->mark; - { // star_expressions + { // FSTRING_START fstring_middle* FSTRING_END if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> fstring[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); - expr_ty star_expressions_var; + D(fprintf(stderr, "%*c> fstring[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "FSTRING_START fstring_middle* FSTRING_END")); + Token * a; + asdl_seq * b; + Token * c; if ( - (star_expressions_var = star_expressions_rule(p)) // star_expressions + (a = _PyPegen_expect_token(p, FSTRING_START)) // token='FSTRING_START' + && + (b = _loop0_3_rule(p)) // fstring_middle* + && + (c = _PyPegen_expect_token(p, FSTRING_END)) // token='FSTRING_END' ) { - D(fprintf(stderr, "%*c+ fstring[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); - _res = star_expressions_var; + D(fprintf(stderr, "%*c+ fstring[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "FSTRING_START fstring_middle* FSTRING_END")); + _res = _PyPegen_joined_str ( p , a , ( asdl_expr_seq* ) b , c ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } goto done; } p->mark = _mark; D(fprintf(stderr, "%*c%s fstring[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "FSTRING_START fstring_middle* FSTRING_END")); } _res = NULL; done: @@ -1283,8 +1372,7 @@ static asdl_stmt_seq* statements_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -1300,7 +1388,7 @@ statements_rule(Parser *p) D(fprintf(stderr, "%*c> statements[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "statement+")); asdl_seq * a; if ( - (a = _loop1_3_rule(p)) // statement+ + (a = _loop1_4_rule(p)) // statement+ ) { D(fprintf(stderr, "%*c+ statements[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "statement+")); @@ -1327,8 +1415,7 @@ static asdl_stmt_seq* statement_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -1395,8 +1482,7 @@ static asdl_stmt_seq* statement_newline_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -1527,8 +1613,7 @@ static asdl_stmt_seq* simple_stmts_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -1576,7 +1661,7 @@ simple_stmts_rule(Parser *p) asdl_stmt_seq* a; Token * newline_var; if ( - (a = (asdl_stmt_seq*)_gather_4_rule(p)) // ';'.simple_stmt+ + (a = (asdl_stmt_seq*)_gather_5_rule(p)) // ';'.simple_stmt+ && (_opt_var = _PyPegen_expect_token(p, 13), !p->error_indicator) // ';'? && @@ -1604,6 +1689,7 @@ simple_stmts_rule(Parser *p) // simple_stmt: // | assignment +// | &"type" type_alias // | star_expressions // | &'return' return_stmt // | &('import' | 'from') import_stmt @@ -1620,8 +1706,7 @@ static stmt_ty simple_stmt_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -1661,6 +1746,27 @@ simple_stmt_rule(Parser *p) D(fprintf(stderr, "%*c%s simple_stmt[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "assignment")); } + { // &"type" type_alias + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> simple_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&\"type\" type_alias")); + stmt_ty type_alias_var; + if ( + _PyPegen_lookahead_with_string(1, _PyPegen_expect_soft_keyword, p, "type") + && + (type_alias_var = type_alias_rule(p)) // type_alias + ) + { + D(fprintf(stderr, "%*c+ simple_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "&\"type\" type_alias")); + _res = type_alias_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s simple_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "&\"type\" type_alias")); + } { // star_expressions if (p->error_indicator) { p->level--; @@ -1723,7 +1829,7 @@ simple_stmt_rule(Parser *p) D(fprintf(stderr, "%*c> simple_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&('import' | 'from') import_stmt")); stmt_ty import_stmt_var; if ( - _PyPegen_lookahead(1, _tmp_6_rule, p) + _PyPegen_lookahead(1, _tmp_7_rule, p) && (import_stmt_var = import_stmt_rule(p)) // import_stmt ) @@ -1798,7 +1904,7 @@ simple_stmt_rule(Parser *p) D(fprintf(stderr, "%*c> simple_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'del' del_stmt")); stmt_ty del_stmt_var; if ( - _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 603) // token='del' + _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 604) // token='del' && (del_stmt_var = del_stmt_rule(p)) // del_stmt ) @@ -1981,8 +2087,7 @@ static stmt_ty compound_stmt_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -1998,7 +2103,7 @@ compound_stmt_rule(Parser *p) D(fprintf(stderr, "%*c> compound_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&('def' | '@' | ASYNC) function_def")); stmt_ty function_def_var; if ( - _PyPegen_lookahead(1, _tmp_7_rule, p) + _PyPegen_lookahead(1, _tmp_8_rule, p) && (function_def_var = function_def_rule(p)) // function_def ) @@ -2019,7 +2124,7 @@ compound_stmt_rule(Parser *p) D(fprintf(stderr, "%*c> compound_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'if' if_stmt")); stmt_ty if_stmt_var; if ( - _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 639) // token='if' + _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 642) // token='if' && (if_stmt_var = if_stmt_rule(p)) // if_stmt ) @@ -2040,7 +2145,7 @@ compound_stmt_rule(Parser *p) D(fprintf(stderr, "%*c> compound_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&('class' | '@') class_def")); stmt_ty class_def_var; if ( - _PyPegen_lookahead(1, _tmp_8_rule, p) + _PyPegen_lookahead(1, _tmp_9_rule, p) && (class_def_var = class_def_rule(p)) // class_def ) @@ -2061,7 +2166,7 @@ compound_stmt_rule(Parser *p) D(fprintf(stderr, "%*c> compound_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&('with' | ASYNC) with_stmt")); stmt_ty with_stmt_var; if ( - _PyPegen_lookahead(1, _tmp_9_rule, p) + _PyPegen_lookahead(1, _tmp_10_rule, p) && (with_stmt_var = with_stmt_rule(p)) // with_stmt ) @@ -2082,7 +2187,7 @@ compound_stmt_rule(Parser *p) D(fprintf(stderr, "%*c> compound_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&('for' | ASYNC) for_stmt")); stmt_ty for_stmt_var; if ( - _PyPegen_lookahead(1, _tmp_10_rule, p) + _PyPegen_lookahead(1, _tmp_11_rule, p) && (for_stmt_var = for_stmt_rule(p)) // for_stmt ) @@ -2103,7 +2208,7 @@ compound_stmt_rule(Parser *p) D(fprintf(stderr, "%*c> compound_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'try' try_stmt")); stmt_ty try_stmt_var; if ( - _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 621) // token='try' + _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 624) // token='try' && (try_stmt_var = try_stmt_rule(p)) // try_stmt ) @@ -2124,7 +2229,7 @@ compound_stmt_rule(Parser *p) D(fprintf(stderr, "%*c> compound_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'while' while_stmt")); stmt_ty while_stmt_var; if ( - _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 644) // token='while' + _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 647) // token='while' && (while_stmt_var = while_stmt_rule(p)) // while_stmt ) @@ -2172,8 +2277,7 @@ static stmt_ty assignment_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -2207,7 +2311,7 @@ assignment_rule(Parser *p) && (b = expression_rule(p)) // expression && - (c = _tmp_11_rule(p), !p->error_indicator) // ['=' annotated_rhs] + (c = _tmp_12_rule(p), !p->error_indicator) // ['=' annotated_rhs] ) { D(fprintf(stderr, "%*c+ assignment[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME ':' expression ['=' annotated_rhs]")); @@ -2243,13 +2347,13 @@ assignment_rule(Parser *p) expr_ty b; void *c; if ( - (a = _tmp_12_rule(p)) // '(' single_target ')' | single_subscript_attribute_target + (a = _tmp_13_rule(p)) // '(' single_target ')' | single_subscript_attribute_target && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && (b = expression_rule(p)) // expression && - (c = _tmp_13_rule(p), !p->error_indicator) // ['=' annotated_rhs] + (c = _tmp_14_rule(p), !p->error_indicator) // ['=' annotated_rhs] ) { D(fprintf(stderr, "%*c+ assignment[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "('(' single_target ')' | single_subscript_attribute_target) ':' expression ['=' annotated_rhs]")); @@ -2284,9 +2388,9 @@ assignment_rule(Parser *p) void *b; void *tc; if ( - (a = (asdl_expr_seq*)_loop1_14_rule(p)) // ((star_targets '='))+ + (a = (asdl_expr_seq*)_loop1_15_rule(p)) // ((star_targets '='))+ && - (b = _tmp_15_rule(p)) // yield_expr | star_expressions + (b = _tmp_16_rule(p)) // yield_expr | star_expressions && _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 22) // token='=' && @@ -2332,7 +2436,7 @@ assignment_rule(Parser *p) && (_cut_var = 1) && - (c = _tmp_16_rule(p)) // yield_expr | star_expressions + (c = _tmp_17_rule(p)) // yield_expr | star_expressions ) { D(fprintf(stderr, "%*c+ assignment[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "single_target augassign ~ (yield_expr | star_expressions)")); @@ -2391,8 +2495,7 @@ static expr_ty annotated_rhs_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -2462,8 +2565,7 @@ static AugOperator* augassign_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -2794,8 +2896,7 @@ static stmt_ty return_stmt_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -2859,8 +2960,7 @@ static stmt_ty raise_stmt_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -2891,7 +2991,7 @@ raise_stmt_rule(Parser *p) && (a = expression_rule(p)) // expression && - (b = _tmp_17_rule(p), !p->error_indicator) // ['from' expression] + (b = _tmp_18_rule(p), !p->error_indicator) // ['from' expression] ) { D(fprintf(stderr, "%*c+ raise_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'raise' expression ['from' expression]")); @@ -2960,8 +3060,7 @@ static stmt_ty global_stmt_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -2989,7 +3088,7 @@ global_stmt_rule(Parser *p) if ( (_keyword = _PyPegen_expect_token(p, 523)) // token='global' && - (a = (asdl_expr_seq*)_gather_18_rule(p)) // ','.NAME+ + (a = (asdl_expr_seq*)_gather_19_rule(p)) // ','.NAME+ ) { D(fprintf(stderr, "%*c+ global_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'global' ','.NAME+")); @@ -3025,8 +3124,7 @@ static stmt_ty nonlocal_stmt_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -3054,7 +3152,7 @@ nonlocal_stmt_rule(Parser *p) if ( (_keyword = _PyPegen_expect_token(p, 524)) // token='nonlocal' && - (a = (asdl_expr_seq*)_gather_20_rule(p)) // ','.NAME+ + (a = (asdl_expr_seq*)_gather_21_rule(p)) // ','.NAME+ ) { D(fprintf(stderr, "%*c+ nonlocal_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'nonlocal' ','.NAME+")); @@ -3090,8 +3188,7 @@ static stmt_ty del_stmt_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -3117,11 +3214,11 @@ del_stmt_rule(Parser *p) Token * _keyword; asdl_expr_seq* a; if ( - (_keyword = _PyPegen_expect_token(p, 603)) // token='del' + (_keyword = _PyPegen_expect_token(p, 604)) // token='del' && (a = del_targets_rule(p)) // del_targets && - _PyPegen_lookahead(1, _tmp_22_rule, p) + _PyPegen_lookahead(1, _tmp_23_rule, p) ) { D(fprintf(stderr, "%*c+ del_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'del' del_targets &(';' | NEWLINE)")); @@ -3176,8 +3273,7 @@ static stmt_ty yield_stmt_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -3238,8 +3334,7 @@ static stmt_ty assert_stmt_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -3270,7 +3365,7 @@ assert_stmt_rule(Parser *p) && (a = expression_rule(p)) // expression && - (b = _tmp_23_rule(p), !p->error_indicator) // [',' expression] + (b = _tmp_24_rule(p), !p->error_indicator) // [',' expression] ) { D(fprintf(stderr, "%*c+ assert_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'assert' expression [',' expression]")); @@ -3301,13 +3396,12 @@ assert_stmt_rule(Parser *p) return _res; } -// import_stmt: import_name | import_from +// import_stmt: invalid_import | import_name | import_from static stmt_ty import_stmt_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -3315,6 +3409,25 @@ import_stmt_rule(Parser *p) } stmt_ty _res = NULL; int _mark = p->mark; + if (p->call_invalid_rules) { // invalid_import + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> import_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_import")); + void *invalid_import_var; + if ( + (invalid_import_var = invalid_import_rule(p)) // invalid_import + ) + { + D(fprintf(stderr, "%*c+ import_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_import")); + _res = invalid_import_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s import_stmt[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_import")); + } { // import_name if (p->error_indicator) { p->level--; @@ -3364,8 +3477,7 @@ static stmt_ty import_name_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -3391,7 +3503,7 @@ import_name_rule(Parser *p) Token * _keyword; asdl_alias_seq* a; if ( - (_keyword = _PyPegen_expect_token(p, 531)) // token='import' + (_keyword = _PyPegen_expect_token(p, 607)) // token='import' && (a = dotted_as_names_rule(p)) // dotted_as_names ) @@ -3431,8 +3543,7 @@ static stmt_ty import_from_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -3461,13 +3572,13 @@ import_from_rule(Parser *p) expr_ty b; asdl_alias_seq* c; if ( - (_keyword = _PyPegen_expect_token(p, 572)) // token='from' + (_keyword = _PyPegen_expect_token(p, 608)) // token='from' && - (a = _loop0_24_rule(p)) // (('.' | '...'))* + (a = _loop0_25_rule(p)) // (('.' | '...'))* && (b = dotted_name_rule(p)) // dotted_name && - (_keyword_1 = _PyPegen_expect_token(p, 531)) // token='import' + (_keyword_1 = _PyPegen_expect_token(p, 607)) // token='import' && (c = import_from_targets_rule(p)) // import_from_targets ) @@ -3505,11 +3616,11 @@ import_from_rule(Parser *p) asdl_seq * a; asdl_alias_seq* b; if ( - (_keyword = _PyPegen_expect_token(p, 572)) // token='from' + (_keyword = _PyPegen_expect_token(p, 608)) // token='from' && - (a = _loop1_25_rule(p)) // (('.' | '...'))+ + (a = _loop1_26_rule(p)) // (('.' | '...'))+ && - (_keyword_1 = _PyPegen_expect_token(p, 531)) // token='import' + (_keyword_1 = _PyPegen_expect_token(p, 607)) // token='import' && (b = import_from_targets_rule(p)) // import_from_targets ) @@ -3551,8 +3662,7 @@ static asdl_alias_seq* import_from_targets_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -3687,8 +3797,7 @@ static asdl_alias_seq* import_from_as_names_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -3704,7 +3813,7 @@ import_from_as_names_rule(Parser *p) D(fprintf(stderr, "%*c> import_from_as_names[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.import_from_as_name+")); asdl_alias_seq* a; if ( - (a = (asdl_alias_seq*)_gather_26_rule(p)) // ','.import_from_as_name+ + (a = (asdl_alias_seq*)_gather_27_rule(p)) // ','.import_from_as_name+ ) { D(fprintf(stderr, "%*c+ import_from_as_names[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.import_from_as_name+")); @@ -3731,8 +3840,7 @@ static alias_ty import_from_as_name_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -3760,7 +3868,7 @@ import_from_as_name_rule(Parser *p) if ( (a = _PyPegen_name_token(p)) // NAME && - (b = _tmp_28_rule(p), !p->error_indicator) // ['as' NAME] + (b = _tmp_29_rule(p), !p->error_indicator) // ['as' NAME] ) { D(fprintf(stderr, "%*c+ import_from_as_name[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME ['as' NAME]")); @@ -3796,8 +3904,7 @@ static asdl_alias_seq* dotted_as_names_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -3813,7 +3920,7 @@ dotted_as_names_rule(Parser *p) D(fprintf(stderr, "%*c> dotted_as_names[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.dotted_as_name+")); asdl_alias_seq* a; if ( - (a = (asdl_alias_seq*)_gather_29_rule(p)) // ','.dotted_as_name+ + (a = (asdl_alias_seq*)_gather_30_rule(p)) // ','.dotted_as_name+ ) { D(fprintf(stderr, "%*c+ dotted_as_names[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.dotted_as_name+")); @@ -3840,8 +3947,7 @@ static alias_ty dotted_as_name_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -3869,7 +3975,7 @@ dotted_as_name_rule(Parser *p) if ( (a = dotted_name_rule(p)) // dotted_name && - (b = _tmp_31_rule(p), !p->error_indicator) // ['as' NAME] + (b = _tmp_32_rule(p), !p->error_indicator) // ['as' NAME] ) { D(fprintf(stderr, "%*c+ dotted_as_name[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "dotted_name ['as' NAME]")); @@ -3907,8 +4013,7 @@ static expr_ty dotted_name_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } expr_ty _res = NULL; if (_PyPegen_is_memoized(p, dotted_name_type, &_res)) { @@ -3942,8 +4047,7 @@ static expr_ty dotted_name_raw(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -4011,8 +4115,7 @@ static asdl_stmt_seq* block_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -4107,8 +4210,7 @@ static asdl_expr_seq* decorators_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -4124,7 +4226,7 @@ decorators_rule(Parser *p) D(fprintf(stderr, "%*c> decorators[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(('@' named_expression NEWLINE))+")); asdl_expr_seq* a; if ( - (a = (asdl_expr_seq*)_loop1_32_rule(p)) // (('@' named_expression NEWLINE))+ + (a = (asdl_expr_seq*)_loop1_33_rule(p)) // (('@' named_expression NEWLINE))+ ) { D(fprintf(stderr, "%*c+ decorators[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(('@' named_expression NEWLINE))+")); @@ -4151,8 +4253,7 @@ static stmt_ty class_def_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -4212,13 +4313,14 @@ class_def_rule(Parser *p) return _res; } -// class_def_raw: invalid_class_def_raw | 'class' NAME ['(' arguments? ')'] ':' block +// class_def_raw: +// | invalid_class_def_raw +// | 'class' NAME type_params? ['(' arguments? ')'] ':' block static stmt_ty class_def_raw_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -4254,30 +4356,33 @@ class_def_raw_rule(Parser *p) D(fprintf(stderr, "%*c%s class_def_raw[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_class_def_raw")); } - { // 'class' NAME ['(' arguments? ')'] ':' block + { // 'class' NAME type_params? ['(' arguments? ')'] ':' block if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> class_def_raw[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'class' NAME ['(' arguments? ')'] ':' block")); + D(fprintf(stderr, "%*c> class_def_raw[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'class' NAME type_params? ['(' arguments? ')'] ':' block")); Token * _keyword; Token * _literal; expr_ty a; void *b; asdl_stmt_seq* c; + void *t; if ( - (_keyword = _PyPegen_expect_token(p, 651)) // token='class' + (_keyword = _PyPegen_expect_token(p, 654)) // token='class' && (a = _PyPegen_name_token(p)) // NAME && - (b = _tmp_33_rule(p), !p->error_indicator) // ['(' arguments? ')'] + (t = type_params_rule(p), !p->error_indicator) // type_params? + && + (b = _tmp_34_rule(p), !p->error_indicator) // ['(' arguments? ')'] && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && (c = block_rule(p)) // block ) { - D(fprintf(stderr, "%*c+ class_def_raw[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'class' NAME ['(' arguments? ')'] ':' block")); + D(fprintf(stderr, "%*c+ class_def_raw[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'class' NAME type_params? ['(' arguments? ')'] ':' block")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { p->level--; @@ -4287,7 +4392,7 @@ class_def_raw_rule(Parser *p) UNUSED(_end_lineno); // Only used by EXTRA macro int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro - _res = _PyAST_ClassDef ( a -> v . Name . id , ( b ) ? ( ( expr_ty ) b ) -> v . Call . args : NULL , ( b ) ? ( ( expr_ty ) b ) -> v . Call . keywords : NULL , c , NULL , EXTRA ); + _res = _PyAST_ClassDef ( a -> v . Name . id , ( b ) ? ( ( expr_ty ) b ) -> v . Call . args : NULL , ( b ) ? ( ( expr_ty ) b ) -> v . Call . keywords : NULL , c , NULL , t , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; p->level--; @@ -4297,7 +4402,7 @@ class_def_raw_rule(Parser *p) } p->mark = _mark; D(fprintf(stderr, "%*c%s class_def_raw[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'class' NAME ['(' arguments? ')'] ':' block")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'class' NAME type_params? ['(' arguments? ')'] ':' block")); } _res = NULL; done: @@ -4310,8 +4415,7 @@ static stmt_ty function_def_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -4373,14 +4477,13 @@ function_def_rule(Parser *p) // function_def_raw: // | invalid_def_raw -// | 'def' NAME &&'(' params? ')' ['->' expression] &&':' func_type_comment? block -// | ASYNC 'def' NAME &&'(' params? ')' ['->' expression] &&':' func_type_comment? block +// | 'def' NAME type_params? &&'(' params? ')' ['->' expression] &&':' func_type_comment? block +// | ASYNC 'def' NAME type_params? &&'(' params? ')' ['->' expression] &&':' func_type_comment? block static stmt_ty function_def_raw_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -4416,12 +4519,12 @@ function_def_raw_rule(Parser *p) D(fprintf(stderr, "%*c%s function_def_raw[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_def_raw")); } - { // 'def' NAME &&'(' params? ')' ['->' expression] &&':' func_type_comment? block + { // 'def' NAME type_params? &&'(' params? ')' ['->' expression] &&':' func_type_comment? block if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> function_def_raw[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'def' NAME &&'(' params? ')' ['->' expression] &&':' func_type_comment? block")); + D(fprintf(stderr, "%*c> function_def_raw[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'def' NAME type_params? &&'(' params? ')' ['->' expression] &&':' func_type_comment? block")); Token * _keyword; Token * _literal; Token * _literal_1; @@ -4430,19 +4533,22 @@ function_def_raw_rule(Parser *p) asdl_stmt_seq* b; expr_ty n; void *params; + void *t; void *tc; if ( - (_keyword = _PyPegen_expect_token(p, 649)) // token='def' + (_keyword = _PyPegen_expect_token(p, 652)) // token='def' && (n = _PyPegen_name_token(p)) // NAME && + (t = type_params_rule(p), !p->error_indicator) // type_params? + && (_literal = _PyPegen_expect_forced_token(p, 7, "(")) // forced_token='(' && (params = params_rule(p), !p->error_indicator) // params? && (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' && - (a = _tmp_34_rule(p), !p->error_indicator) // ['->' expression] + (a = _tmp_35_rule(p), !p->error_indicator) // ['->' expression] && (_literal_2 = _PyPegen_expect_forced_token(p, 11, ":")) // forced_token=':' && @@ -4451,7 +4557,7 @@ function_def_raw_rule(Parser *p) (b = block_rule(p)) // block ) { - D(fprintf(stderr, "%*c+ function_def_raw[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'def' NAME &&'(' params? ')' ['->' expression] &&':' func_type_comment? block")); + D(fprintf(stderr, "%*c+ function_def_raw[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'def' NAME type_params? &&'(' params? ')' ['->' expression] &&':' func_type_comment? block")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { p->level--; @@ -4461,7 +4567,7 @@ function_def_raw_rule(Parser *p) UNUSED(_end_lineno); // Only used by EXTRA macro int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro - _res = _PyAST_FunctionDef ( n -> v . Name . id , ( params ) ? params : CHECK ( arguments_ty , _PyPegen_empty_arguments ( p ) ) , b , NULL , a , NEW_TYPE_COMMENT ( p , tc ) , EXTRA ); + _res = _PyAST_FunctionDef ( n -> v . Name . id , ( params ) ? params : CHECK ( arguments_ty , _PyPegen_empty_arguments ( p ) ) , b , NULL , a , NEW_TYPE_COMMENT ( p , tc ) , t , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; p->level--; @@ -4471,14 +4577,14 @@ function_def_raw_rule(Parser *p) } p->mark = _mark; D(fprintf(stderr, "%*c%s function_def_raw[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'def' NAME &&'(' params? ')' ['->' expression] &&':' func_type_comment? block")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'def' NAME type_params? &&'(' params? ')' ['->' expression] &&':' func_type_comment? block")); } - { // ASYNC 'def' NAME &&'(' params? ')' ['->' expression] &&':' func_type_comment? block + { // ASYNC 'def' NAME type_params? &&'(' params? ')' ['->' expression] &&':' func_type_comment? block if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> function_def_raw[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC 'def' NAME &&'(' params? ')' ['->' expression] &&':' func_type_comment? block")); + D(fprintf(stderr, "%*c> function_def_raw[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC 'def' NAME type_params? &&'(' params? ')' ['->' expression] &&':' func_type_comment? block")); Token * _keyword; Token * _literal; Token * _literal_1; @@ -4488,21 +4594,24 @@ function_def_raw_rule(Parser *p) asdl_stmt_seq* b; expr_ty n; void *params; + void *t; void *tc; if ( (async_var = _PyPegen_expect_token(p, ASYNC)) // token='ASYNC' && - (_keyword = _PyPegen_expect_token(p, 649)) // token='def' + (_keyword = _PyPegen_expect_token(p, 652)) // token='def' && (n = _PyPegen_name_token(p)) // NAME && + (t = type_params_rule(p), !p->error_indicator) // type_params? + && (_literal = _PyPegen_expect_forced_token(p, 7, "(")) // forced_token='(' && (params = params_rule(p), !p->error_indicator) // params? && (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' && - (a = _tmp_35_rule(p), !p->error_indicator) // ['->' expression] + (a = _tmp_36_rule(p), !p->error_indicator) // ['->' expression] && (_literal_2 = _PyPegen_expect_forced_token(p, 11, ":")) // forced_token=':' && @@ -4511,7 +4620,7 @@ function_def_raw_rule(Parser *p) (b = block_rule(p)) // block ) { - D(fprintf(stderr, "%*c+ function_def_raw[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "ASYNC 'def' NAME &&'(' params? ')' ['->' expression] &&':' func_type_comment? block")); + D(fprintf(stderr, "%*c+ function_def_raw[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "ASYNC 'def' NAME type_params? &&'(' params? ')' ['->' expression] &&':' func_type_comment? block")); Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); if (_token == NULL) { p->level--; @@ -4521,7 +4630,7 @@ function_def_raw_rule(Parser *p) UNUSED(_end_lineno); // Only used by EXTRA macro int _end_col_offset = _token->end_col_offset; UNUSED(_end_col_offset); // Only used by EXTRA macro - _res = CHECK_VERSION ( stmt_ty , 5 , "Async functions are" , _PyAST_AsyncFunctionDef ( n -> v . Name . id , ( params ) ? params : CHECK ( arguments_ty , _PyPegen_empty_arguments ( p ) ) , b , NULL , a , NEW_TYPE_COMMENT ( p , tc ) , EXTRA ) ); + _res = CHECK_VERSION ( stmt_ty , 5 , "Async functions are" , _PyAST_AsyncFunctionDef ( n -> v . Name . id , ( params ) ? params : CHECK ( arguments_ty , _PyPegen_empty_arguments ( p ) ) , b , NULL , a , NEW_TYPE_COMMENT ( p , tc ) , t , EXTRA ) ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; p->level--; @@ -4531,7 +4640,7 @@ function_def_raw_rule(Parser *p) } p->mark = _mark; D(fprintf(stderr, "%*c%s function_def_raw[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "ASYNC 'def' NAME &&'(' params? ')' ['->' expression] &&':' func_type_comment? block")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "ASYNC 'def' NAME type_params? &&'(' params? ')' ['->' expression] &&':' func_type_comment? block")); } _res = NULL; done: @@ -4544,8 +4653,7 @@ static arguments_ty params_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -4607,8 +4715,7 @@ static arguments_ty parameters_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -4629,9 +4736,9 @@ parameters_rule(Parser *p) if ( (a = slash_no_default_rule(p)) // slash_no_default && - (b = (asdl_arg_seq*)_loop0_36_rule(p)) // param_no_default* + (b = (asdl_arg_seq*)_loop0_37_rule(p)) // param_no_default* && - (c = _loop0_37_rule(p)) // param_with_default* + (c = _loop0_38_rule(p)) // param_with_default* && (d = star_etc_rule(p), !p->error_indicator) // star_etc? ) @@ -4661,7 +4768,7 @@ parameters_rule(Parser *p) if ( (a = slash_with_default_rule(p)) // slash_with_default && - (b = _loop0_38_rule(p)) // param_with_default* + (b = _loop0_39_rule(p)) // param_with_default* && (c = star_etc_rule(p), !p->error_indicator) // star_etc? ) @@ -4689,9 +4796,9 @@ parameters_rule(Parser *p) asdl_seq * b; void *c; if ( - (a = (asdl_arg_seq*)_loop1_39_rule(p)) // param_no_default+ + (a = (asdl_arg_seq*)_loop1_40_rule(p)) // param_no_default+ && - (b = _loop0_40_rule(p)) // param_with_default* + (b = _loop0_41_rule(p)) // param_with_default* && (c = star_etc_rule(p), !p->error_indicator) // star_etc? ) @@ -4718,7 +4825,7 @@ parameters_rule(Parser *p) asdl_seq * a; void *b; if ( - (a = _loop1_41_rule(p)) // param_with_default+ + (a = _loop1_42_rule(p)) // param_with_default+ && (b = star_etc_rule(p), !p->error_indicator) // star_etc? ) @@ -4771,8 +4878,7 @@ static asdl_arg_seq* slash_no_default_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -4790,7 +4896,7 @@ slash_no_default_rule(Parser *p) Token * _literal_1; asdl_arg_seq* a; if ( - (a = (asdl_arg_seq*)_loop1_42_rule(p)) // param_no_default+ + (a = (asdl_arg_seq*)_loop1_43_rule(p)) // param_no_default+ && (_literal = _PyPegen_expect_token(p, 17)) // token='/' && @@ -4819,7 +4925,7 @@ slash_no_default_rule(Parser *p) Token * _literal; asdl_arg_seq* a; if ( - (a = (asdl_arg_seq*)_loop1_43_rule(p)) // param_no_default+ + (a = (asdl_arg_seq*)_loop1_44_rule(p)) // param_no_default+ && (_literal = _PyPegen_expect_token(p, 17)) // token='/' && @@ -4852,8 +4958,7 @@ static SlashWithDefault* slash_with_default_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -4872,9 +4977,9 @@ slash_with_default_rule(Parser *p) asdl_seq * a; asdl_seq * b; if ( - (a = _loop0_44_rule(p)) // param_no_default* + (a = _loop0_45_rule(p)) // param_no_default* && - (b = _loop1_45_rule(p)) // param_with_default+ + (b = _loop1_46_rule(p)) // param_with_default+ && (_literal = _PyPegen_expect_token(p, 17)) // token='/' && @@ -4904,9 +5009,9 @@ slash_with_default_rule(Parser *p) asdl_seq * a; asdl_seq * b; if ( - (a = _loop0_46_rule(p)) // param_no_default* + (a = _loop0_47_rule(p)) // param_no_default* && - (b = _loop1_47_rule(p)) // param_with_default+ + (b = _loop1_48_rule(p)) // param_with_default+ && (_literal = _PyPegen_expect_token(p, 17)) // token='/' && @@ -4942,8 +5047,7 @@ static StarEtc* star_etc_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -4985,7 +5089,7 @@ star_etc_rule(Parser *p) && (a = param_no_default_rule(p)) // param_no_default && - (b = _loop0_48_rule(p)) // param_maybe_default* + (b = _loop0_49_rule(p)) // param_maybe_default* && (c = kwds_rule(p), !p->error_indicator) // kwds? ) @@ -5018,7 +5122,7 @@ star_etc_rule(Parser *p) && (a = param_no_default_star_annotation_rule(p)) // param_no_default_star_annotation && - (b = _loop0_49_rule(p)) // param_maybe_default* + (b = _loop0_50_rule(p)) // param_maybe_default* && (c = kwds_rule(p), !p->error_indicator) // kwds? ) @@ -5051,7 +5155,7 @@ star_etc_rule(Parser *p) && (_literal_1 = _PyPegen_expect_token(p, 12)) // token=',' && - (b = _loop1_50_rule(p)) // param_maybe_default+ + (b = _loop1_51_rule(p)) // param_maybe_default+ && (c = kwds_rule(p), !p->error_indicator) // kwds? ) @@ -5104,8 +5208,7 @@ static arg_ty kwds_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -5170,8 +5273,7 @@ static arg_ty param_no_default_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -5251,8 +5353,7 @@ static arg_ty param_no_default_star_annotation_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -5330,8 +5431,7 @@ static NameDefaultPair* param_with_default_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -5417,8 +5517,7 @@ static NameDefaultPair* param_maybe_default_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -5502,8 +5601,7 @@ static arg_ty param_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -5567,8 +5665,7 @@ static arg_ty param_star_annotation_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -5632,8 +5729,7 @@ static expr_ty annotation_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -5679,8 +5775,7 @@ static expr_ty star_annotation_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -5726,8 +5821,7 @@ static expr_ty default_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -5795,8 +5889,7 @@ static stmt_ty if_stmt_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -5844,7 +5937,7 @@ if_stmt_rule(Parser *p) asdl_stmt_seq* b; stmt_ty c; if ( - (_keyword = _PyPegen_expect_token(p, 639)) // token='if' + (_keyword = _PyPegen_expect_token(p, 642)) // token='if' && (a = named_expression_rule(p)) // named_expression && @@ -5889,7 +5982,7 @@ if_stmt_rule(Parser *p) asdl_stmt_seq* b; void *c; if ( - (_keyword = _PyPegen_expect_token(p, 639)) // token='if' + (_keyword = _PyPegen_expect_token(p, 642)) // token='if' && (a = named_expression_rule(p)) // named_expression && @@ -5936,8 +6029,7 @@ static stmt_ty elif_stmt_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -5985,7 +6077,7 @@ elif_stmt_rule(Parser *p) asdl_stmt_seq* b; stmt_ty c; if ( - (_keyword = _PyPegen_expect_token(p, 641)) // token='elif' + (_keyword = _PyPegen_expect_token(p, 644)) // token='elif' && (a = named_expression_rule(p)) // named_expression && @@ -6030,7 +6122,7 @@ elif_stmt_rule(Parser *p) asdl_stmt_seq* b; void *c; if ( - (_keyword = _PyPegen_expect_token(p, 641)) // token='elif' + (_keyword = _PyPegen_expect_token(p, 644)) // token='elif' && (a = named_expression_rule(p)) // named_expression && @@ -6074,8 +6166,7 @@ static asdl_stmt_seq* else_block_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -6112,7 +6203,7 @@ else_block_rule(Parser *p) Token * _literal; asdl_stmt_seq* b; if ( - (_keyword = _PyPegen_expect_token(p, 642)) // token='else' + (_keyword = _PyPegen_expect_token(p, 645)) // token='else' && (_literal = _PyPegen_expect_forced_token(p, 11, ":")) // forced_token=':' && @@ -6143,8 +6234,7 @@ static stmt_ty while_stmt_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -6192,7 +6282,7 @@ while_stmt_rule(Parser *p) asdl_stmt_seq* b; void *c; if ( - (_keyword = _PyPegen_expect_token(p, 644)) // token='while' + (_keyword = _PyPegen_expect_token(p, 647)) // token='while' && (a = named_expression_rule(p)) // named_expression && @@ -6240,8 +6330,7 @@ static stmt_ty for_stmt_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -6293,11 +6382,11 @@ for_stmt_rule(Parser *p) expr_ty t; void *tc; if ( - (_keyword = _PyPegen_expect_token(p, 647)) // token='for' + (_keyword = _PyPegen_expect_token(p, 650)) // token='for' && (t = star_targets_rule(p)) // star_targets && - (_keyword_1 = _PyPegen_expect_token(p, 648)) // token='in' + (_keyword_1 = _PyPegen_expect_token(p, 651)) // token='in' && (_cut_var = 1) && @@ -6357,11 +6446,11 @@ for_stmt_rule(Parser *p) if ( (async_var = _PyPegen_expect_token(p, ASYNC)) // token='ASYNC' && - (_keyword = _PyPegen_expect_token(p, 647)) // token='for' + (_keyword = _PyPegen_expect_token(p, 650)) // token='for' && (t = star_targets_rule(p)) // star_targets && - (_keyword_1 = _PyPegen_expect_token(p, 648)) // token='in' + (_keyword_1 = _PyPegen_expect_token(p, 651)) // token='in' && (_cut_var = 1) && @@ -6438,8 +6527,7 @@ static stmt_ty with_stmt_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -6490,11 +6578,11 @@ with_stmt_rule(Parser *p) asdl_withitem_seq* a; asdl_stmt_seq* b; if ( - (_keyword = _PyPegen_expect_token(p, 612)) // token='with' + (_keyword = _PyPegen_expect_token(p, 615)) // token='with' && (_literal = _PyPegen_expect_token(p, 7)) // token='(' && - (a = (asdl_withitem_seq*)_gather_51_rule(p)) // ','.with_item+ + (a = (asdl_withitem_seq*)_gather_52_rule(p)) // ','.with_item+ && (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? && @@ -6539,9 +6627,9 @@ with_stmt_rule(Parser *p) asdl_stmt_seq* b; void *tc; if ( - (_keyword = _PyPegen_expect_token(p, 612)) // token='with' + (_keyword = _PyPegen_expect_token(p, 615)) // token='with' && - (a = (asdl_withitem_seq*)_gather_53_rule(p)) // ','.with_item+ + (a = (asdl_withitem_seq*)_gather_54_rule(p)) // ','.with_item+ && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -6590,11 +6678,11 @@ with_stmt_rule(Parser *p) if ( (async_var = _PyPegen_expect_token(p, ASYNC)) // token='ASYNC' && - (_keyword = _PyPegen_expect_token(p, 612)) // token='with' + (_keyword = _PyPegen_expect_token(p, 615)) // token='with' && (_literal = _PyPegen_expect_token(p, 7)) // token='(' && - (a = (asdl_withitem_seq*)_gather_55_rule(p)) // ','.with_item+ + (a = (asdl_withitem_seq*)_gather_56_rule(p)) // ','.with_item+ && (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? && @@ -6642,9 +6730,9 @@ with_stmt_rule(Parser *p) if ( (async_var = _PyPegen_expect_token(p, ASYNC)) // token='ASYNC' && - (_keyword = _PyPegen_expect_token(p, 612)) // token='with' + (_keyword = _PyPegen_expect_token(p, 615)) // token='with' && - (a = (asdl_withitem_seq*)_gather_57_rule(p)) // ','.with_item+ + (a = (asdl_withitem_seq*)_gather_58_rule(p)) // ','.with_item+ && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -6708,8 +6796,7 @@ static withitem_ty with_item_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -6729,11 +6816,11 @@ with_item_rule(Parser *p) if ( (e = expression_rule(p)) // expression && - (_keyword = _PyPegen_expect_token(p, 637)) // token='as' + (_keyword = _PyPegen_expect_token(p, 640)) // token='as' && (t = star_target_rule(p)) // star_target && - _PyPegen_lookahead(1, _tmp_59_rule, p) + _PyPegen_lookahead(1, _tmp_60_rule, p) ) { D(fprintf(stderr, "%*c+ with_item[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression 'as' star_target &(',' | ')' | ':')")); @@ -6807,8 +6894,7 @@ static stmt_ty try_stmt_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -6855,7 +6941,7 @@ try_stmt_rule(Parser *p) asdl_stmt_seq* b; asdl_stmt_seq* f; if ( - (_keyword = _PyPegen_expect_token(p, 621)) // token='try' + (_keyword = _PyPegen_expect_token(p, 624)) // token='try' && (_literal = _PyPegen_expect_forced_token(p, 11, ":")) // forced_token=':' && @@ -6899,13 +6985,13 @@ try_stmt_rule(Parser *p) asdl_excepthandler_seq* ex; void *f; if ( - (_keyword = _PyPegen_expect_token(p, 621)) // token='try' + (_keyword = _PyPegen_expect_token(p, 624)) // token='try' && (_literal = _PyPegen_expect_forced_token(p, 11, ":")) // forced_token=':' && (b = block_rule(p)) // block && - (ex = (asdl_excepthandler_seq*)_loop1_60_rule(p)) // except_block+ + (ex = (asdl_excepthandler_seq*)_loop1_61_rule(p)) // except_block+ && (el = else_block_rule(p), !p->error_indicator) // else_block? && @@ -6947,13 +7033,13 @@ try_stmt_rule(Parser *p) asdl_excepthandler_seq* ex; void *f; if ( - (_keyword = _PyPegen_expect_token(p, 621)) // token='try' + (_keyword = _PyPegen_expect_token(p, 624)) // token='try' && (_literal = _PyPegen_expect_forced_token(p, 11, ":")) // forced_token=':' && (b = block_rule(p)) // block && - (ex = (asdl_excepthandler_seq*)_loop1_61_rule(p)) // except_star_block+ + (ex = (asdl_excepthandler_seq*)_loop1_62_rule(p)) // except_star_block+ && (el = else_block_rule(p), !p->error_indicator) // else_block? && @@ -6997,8 +7083,7 @@ static excepthandler_ty except_block_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -7046,11 +7131,11 @@ except_block_rule(Parser *p) expr_ty e; void *t; if ( - (_keyword = _PyPegen_expect_token(p, 634)) // token='except' + (_keyword = _PyPegen_expect_token(p, 637)) // token='except' && (e = expression_rule(p)) // expression && - (t = _tmp_62_rule(p), !p->error_indicator) // ['as' NAME] + (t = _tmp_63_rule(p), !p->error_indicator) // ['as' NAME] && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -7089,7 +7174,7 @@ except_block_rule(Parser *p) Token * _literal; asdl_stmt_seq* b; if ( - (_keyword = _PyPegen_expect_token(p, 634)) // token='except' + (_keyword = _PyPegen_expect_token(p, 637)) // token='except' && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -7151,8 +7236,7 @@ static excepthandler_ty except_star_block_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -7201,13 +7285,13 @@ except_star_block_rule(Parser *p) expr_ty e; void *t; if ( - (_keyword = _PyPegen_expect_token(p, 634)) // token='except' + (_keyword = _PyPegen_expect_token(p, 637)) // token='except' && (_literal = _PyPegen_expect_token(p, 16)) // token='*' && (e = expression_rule(p)) // expression && - (t = _tmp_63_rule(p), !p->error_indicator) // ['as' NAME] + (t = _tmp_64_rule(p), !p->error_indicator) // ['as' NAME] && (_literal_1 = _PyPegen_expect_token(p, 11)) // token=':' && @@ -7266,8 +7350,7 @@ static asdl_stmt_seq* finally_block_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -7304,7 +7387,7 @@ finally_block_rule(Parser *p) Token * _literal; asdl_stmt_seq* a; if ( - (_keyword = _PyPegen_expect_token(p, 630)) // token='finally' + (_keyword = _PyPegen_expect_token(p, 633)) // token='finally' && (_literal = _PyPegen_expect_forced_token(p, 11, ":")) // forced_token=':' && @@ -7337,8 +7420,7 @@ static stmt_ty match_stmt_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -7379,7 +7461,7 @@ match_stmt_rule(Parser *p) && (indent_var = _PyPegen_expect_token(p, INDENT)) // token='INDENT' && - (cases = (asdl_match_case_seq*)_loop1_64_rule(p)) // case_block+ + (cases = (asdl_match_case_seq*)_loop1_65_rule(p)) // case_block+ && (dedent_var = _PyPegen_expect_token(p, DEDENT)) // token='DEDENT' ) @@ -7436,8 +7518,7 @@ static expr_ty subject_expr_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -7523,8 +7604,7 @@ static match_case_ty case_block_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -7598,8 +7678,7 @@ static expr_ty guard_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -7616,7 +7695,7 @@ guard_rule(Parser *p) Token * _keyword; expr_ty guard; if ( - (_keyword = _PyPegen_expect_token(p, 639)) // token='if' + (_keyword = _PyPegen_expect_token(p, 642)) // token='if' && (guard = named_expression_rule(p)) // named_expression ) @@ -7645,8 +7724,7 @@ static pattern_ty patterns_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -7726,8 +7804,7 @@ static pattern_ty pattern_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -7784,8 +7861,7 @@ static pattern_ty as_pattern_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -7814,7 +7890,7 @@ as_pattern_rule(Parser *p) if ( (pattern = or_pattern_rule(p)) // or_pattern && - (_keyword = _PyPegen_expect_token(p, 637)) // token='as' + (_keyword = _PyPegen_expect_token(p, 640)) // token='as' && (target = pattern_capture_target_rule(p)) // pattern_capture_target ) @@ -7871,8 +7947,7 @@ static pattern_ty or_pattern_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -7897,7 +7972,7 @@ or_pattern_rule(Parser *p) D(fprintf(stderr, "%*c> or_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'|'.closed_pattern+")); asdl_pattern_seq* patterns; if ( - (patterns = (asdl_pattern_seq*)_gather_65_rule(p)) // '|'.closed_pattern+ + (patterns = (asdl_pattern_seq*)_gather_66_rule(p)) // '|'.closed_pattern+ ) { D(fprintf(stderr, "%*c+ or_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'|'.closed_pattern+")); @@ -7941,8 +8016,7 @@ static pattern_ty closed_pattern_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -8124,8 +8198,7 @@ static pattern_ty literal_pattern_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -8152,7 +8225,7 @@ literal_pattern_rule(Parser *p) if ( (value = signed_number_rule(p)) // signed_number && - _PyPegen_lookahead(0, _tmp_67_rule, p) + _PyPegen_lookahead(0, _tmp_68_rule, p) ) { D(fprintf(stderr, "%*c+ literal_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "signed_number !('+' | '-')")); @@ -8251,7 +8324,7 @@ literal_pattern_rule(Parser *p) D(fprintf(stderr, "%*c> literal_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'None'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 601)) // token='None' + (_keyword = _PyPegen_expect_token(p, 602)) // token='None' ) { D(fprintf(stderr, "%*c+ literal_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'None'")); @@ -8284,7 +8357,7 @@ literal_pattern_rule(Parser *p) D(fprintf(stderr, "%*c> literal_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'True'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 600)) // token='True' + (_keyword = _PyPegen_expect_token(p, 601)) // token='True' ) { D(fprintf(stderr, "%*c+ literal_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'True'")); @@ -8317,7 +8390,7 @@ literal_pattern_rule(Parser *p) D(fprintf(stderr, "%*c> literal_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'False'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 602)) // token='False' + (_keyword = _PyPegen_expect_token(p, 603)) // token='False' ) { D(fprintf(stderr, "%*c+ literal_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'False'")); @@ -8359,8 +8432,7 @@ static expr_ty literal_expr_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -8387,7 +8459,7 @@ literal_expr_rule(Parser *p) if ( (signed_number_var = signed_number_rule(p)) // signed_number && - _PyPegen_lookahead(0, _tmp_68_rule, p) + _PyPegen_lookahead(0, _tmp_69_rule, p) ) { D(fprintf(stderr, "%*c+ literal_expr[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "signed_number !('+' | '-')")); @@ -8444,7 +8516,7 @@ literal_expr_rule(Parser *p) D(fprintf(stderr, "%*c> literal_expr[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'None'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 601)) // token='None' + (_keyword = _PyPegen_expect_token(p, 602)) // token='None' ) { D(fprintf(stderr, "%*c+ literal_expr[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'None'")); @@ -8477,7 +8549,7 @@ literal_expr_rule(Parser *p) D(fprintf(stderr, "%*c> literal_expr[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'True'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 600)) // token='True' + (_keyword = _PyPegen_expect_token(p, 601)) // token='True' ) { D(fprintf(stderr, "%*c+ literal_expr[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'True'")); @@ -8510,7 +8582,7 @@ literal_expr_rule(Parser *p) D(fprintf(stderr, "%*c> literal_expr[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'False'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 602)) // token='False' + (_keyword = _PyPegen_expect_token(p, 603)) // token='False' ) { D(fprintf(stderr, "%*c+ literal_expr[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'False'")); @@ -8548,8 +8620,7 @@ static expr_ty complex_number_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -8655,8 +8726,7 @@ static expr_ty signed_number_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -8739,8 +8809,7 @@ static expr_ty signed_real_number_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -8823,8 +8892,7 @@ static expr_ty real_number_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -8867,8 +8935,7 @@ static expr_ty imaginary_number_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -8911,8 +8978,7 @@ static pattern_ty capture_pattern_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -8973,8 +9039,7 @@ static expr_ty pattern_capture_target_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -8994,7 +9059,7 @@ pattern_capture_target_rule(Parser *p) && (name = _PyPegen_name_token(p)) // NAME && - _PyPegen_lookahead(0, _tmp_69_rule, p) + _PyPegen_lookahead(0, _tmp_70_rule, p) ) { D(fprintf(stderr, "%*c+ pattern_capture_target[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "!\"_\" NAME !('.' | '(' | '=')")); @@ -9021,8 +9086,7 @@ static pattern_ty wildcard_pattern_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -9083,8 +9147,7 @@ static pattern_ty value_pattern_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -9111,7 +9174,7 @@ value_pattern_rule(Parser *p) if ( (attr = attr_rule(p)) // attr && - _PyPegen_lookahead(0, _tmp_70_rule, p) + _PyPegen_lookahead(0, _tmp_71_rule, p) ) { D(fprintf(stderr, "%*c+ value_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "attr !('.' | '(' | '=')")); @@ -9149,8 +9212,7 @@ static expr_ty attr_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } expr_ty _res = NULL; if (_PyPegen_is_memoized(p, attr_type, &_res)) { @@ -9184,8 +9246,7 @@ static expr_ty attr_raw(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -9253,8 +9314,7 @@ static expr_ty name_or_attr_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -9311,8 +9371,7 @@ static pattern_ty group_pattern_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -9361,8 +9420,7 @@ static pattern_ty sequence_pattern_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -9468,8 +9526,7 @@ static asdl_seq* open_sequence_pattern_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -9518,8 +9575,7 @@ static asdl_seq* maybe_sequence_pattern_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -9537,7 +9593,7 @@ maybe_sequence_pattern_rule(Parser *p) UNUSED(_opt_var); // Silence compiler warnings asdl_seq * patterns; if ( - (patterns = _gather_71_rule(p)) // ','.maybe_star_pattern+ + (patterns = _gather_72_rule(p)) // ','.maybe_star_pattern+ && (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? ) @@ -9566,8 +9622,7 @@ static pattern_ty maybe_star_pattern_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -9624,8 +9679,7 @@ static pattern_ty star_pattern_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -9734,8 +9788,7 @@ static pattern_ty mapping_pattern_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -9934,8 +9987,7 @@ static asdl_seq* items_pattern_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -9949,13 +10001,13 @@ items_pattern_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> items_pattern[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.key_value_pattern+")); - asdl_seq * _gather_73_var; + asdl_seq * _gather_74_var; if ( - (_gather_73_var = _gather_73_rule(p)) // ','.key_value_pattern+ + (_gather_74_var = _gather_74_rule(p)) // ','.key_value_pattern+ ) { D(fprintf(stderr, "%*c+ items_pattern[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.key_value_pattern+")); - _res = _gather_73_var; + _res = _gather_74_var; goto done; } p->mark = _mark; @@ -9973,8 +10025,7 @@ static KeyPatternPair* key_value_pattern_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -9992,7 +10043,7 @@ key_value_pattern_rule(Parser *p) void *key; pattern_ty pattern; if ( - (key = _tmp_75_rule(p)) // literal_expr | attr + (key = _tmp_76_rule(p)) // literal_expr | attr && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -10023,8 +10074,7 @@ static expr_ty double_star_pattern_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -10075,8 +10125,7 @@ static pattern_ty class_pattern_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -10306,8 +10355,7 @@ static asdl_pattern_seq* positional_patterns_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -10323,7 +10371,7 @@ positional_patterns_rule(Parser *p) D(fprintf(stderr, "%*c> positional_patterns[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.pattern+")); asdl_pattern_seq* args; if ( - (args = (asdl_pattern_seq*)_gather_76_rule(p)) // ','.pattern+ + (args = (asdl_pattern_seq*)_gather_77_rule(p)) // ','.pattern+ ) { D(fprintf(stderr, "%*c+ positional_patterns[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.pattern+")); @@ -10350,8 +10398,7 @@ static asdl_seq* keyword_patterns_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -10365,13 +10412,13 @@ keyword_patterns_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> keyword_patterns[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.keyword_pattern+")); - asdl_seq * _gather_78_var; + asdl_seq * _gather_79_var; if ( - (_gather_78_var = _gather_78_rule(p)) // ','.keyword_pattern+ + (_gather_79_var = _gather_79_rule(p)) // ','.keyword_pattern+ ) { D(fprintf(stderr, "%*c+ keyword_patterns[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.keyword_pattern+")); - _res = _gather_78_var; + _res = _gather_79_var; goto done; } p->mark = _mark; @@ -10389,8 +10436,7 @@ static KeyPatternPair* keyword_pattern_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -10434,13 +10480,439 @@ keyword_pattern_rule(Parser *p) return _res; } +// type_alias: "type" NAME type_params? '=' expression +static stmt_ty +type_alias_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + stmt_ty _res = NULL; + int _mark = p->mark; + if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { + p->error_indicator = 1; + p->level--; + return NULL; + } + int _start_lineno = p->tokens[_mark]->lineno; + UNUSED(_start_lineno); // Only used by EXTRA macro + int _start_col_offset = p->tokens[_mark]->col_offset; + UNUSED(_start_col_offset); // Only used by EXTRA macro + { // "type" NAME type_params? '=' expression + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> type_alias[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "\"type\" NAME type_params? '=' expression")); + expr_ty _keyword; + Token * _literal; + expr_ty b; + expr_ty n; + void *t; + if ( + (_keyword = _PyPegen_expect_soft_keyword(p, "type")) // soft_keyword='"type"' + && + (n = _PyPegen_name_token(p)) // NAME + && + (t = type_params_rule(p), !p->error_indicator) // type_params? + && + (_literal = _PyPegen_expect_token(p, 22)) // token='=' + && + (b = expression_rule(p)) // expression + ) + { + D(fprintf(stderr, "%*c+ type_alias[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "\"type\" NAME type_params? '=' expression")); + Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); + if (_token == NULL) { + p->level--; + return NULL; + } + int _end_lineno = _token->end_lineno; + UNUSED(_end_lineno); // Only used by EXTRA macro + int _end_col_offset = _token->end_col_offset; + UNUSED(_end_col_offset); // Only used by EXTRA macro + _res = CHECK_VERSION ( stmt_ty , 12 , "Type statement is" , _PyAST_TypeAlias ( CHECK ( expr_ty , _PyPegen_set_expr_context ( p , n , Store ) ) , t , b , EXTRA ) ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s type_alias[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "\"type\" NAME type_params? '=' expression")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// type_params: '[' type_param_seq ']' +static asdl_type_param_seq* +type_params_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_type_param_seq* _res = NULL; + int _mark = p->mark; + { // '[' type_param_seq ']' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> type_params[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'[' type_param_seq ']'")); + Token * _literal; + Token * _literal_1; + asdl_type_param_seq* t; + if ( + (_literal = _PyPegen_expect_token(p, 9)) // token='[' + && + (t = type_param_seq_rule(p)) // type_param_seq + && + (_literal_1 = _PyPegen_expect_token(p, 10)) // token=']' + ) + { + D(fprintf(stderr, "%*c+ type_params[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'[' type_param_seq ']'")); + _res = CHECK_VERSION ( asdl_type_param_seq* , 12 , "Type parameter lists are" , t ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s type_params[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'[' type_param_seq ']'")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// type_param_seq: ','.type_param+ ','? +static asdl_type_param_seq* +type_param_seq_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_type_param_seq* _res = NULL; + int _mark = p->mark; + { // ','.type_param+ ','? + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> type_param_seq[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.type_param+ ','?")); + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + asdl_type_param_seq* a; + if ( + (a = (asdl_type_param_seq*)_gather_81_rule(p)) // ','.type_param+ + && + (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? + ) + { + D(fprintf(stderr, "%*c+ type_param_seq[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.type_param+ ','?")); + _res = a; + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s type_param_seq[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','.type_param+ ','?")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// type_param: +// | NAME type_param_bound? +// | '*' NAME ":" expression +// | '*' NAME +// | '**' NAME ":" expression +// | '**' NAME +static type_param_ty +type_param_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + type_param_ty _res = NULL; + if (_PyPegen_is_memoized(p, type_param_type, &_res)) { + p->level--; + return _res; + } + int _mark = p->mark; + if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { + p->error_indicator = 1; + p->level--; + return NULL; + } + int _start_lineno = p->tokens[_mark]->lineno; + UNUSED(_start_lineno); // Only used by EXTRA macro + int _start_col_offset = p->tokens[_mark]->col_offset; + UNUSED(_start_col_offset); // Only used by EXTRA macro + { // NAME type_param_bound? + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> type_param[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME type_param_bound?")); + expr_ty a; + void *b; + if ( + (a = _PyPegen_name_token(p)) // NAME + && + (b = type_param_bound_rule(p), !p->error_indicator) // type_param_bound? + ) + { + D(fprintf(stderr, "%*c+ type_param[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME type_param_bound?")); + Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); + if (_token == NULL) { + p->level--; + return NULL; + } + int _end_lineno = _token->end_lineno; + UNUSED(_end_lineno); // Only used by EXTRA macro + int _end_col_offset = _token->end_col_offset; + UNUSED(_end_col_offset); // Only used by EXTRA macro + _res = _PyAST_TypeVar ( a -> v . Name . id , b , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s type_param[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NAME type_param_bound?")); + } + { // '*' NAME ":" expression + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> type_param[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' NAME \":\" expression")); + Token * _literal; + expr_ty a; + Token * colon; + expr_ty e; + if ( + (_literal = _PyPegen_expect_token(p, 16)) // token='*' + && + (a = _PyPegen_name_token(p)) // NAME + && + (colon = _PyPegen_expect_token(p, 11)) // token=':' + && + (e = expression_rule(p)) // expression + ) + { + D(fprintf(stderr, "%*c+ type_param[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' NAME \":\" expression")); + _res = RAISE_SYNTAX_ERROR_STARTING_FROM ( colon , e -> kind == Tuple_kind ? "cannot use constraints with TypeVarTuple" : "cannot use bound with TypeVarTuple" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s type_param[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*' NAME \":\" expression")); + } + { // '*' NAME + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> type_param[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' NAME")); + Token * _literal; + expr_ty a; + if ( + (_literal = _PyPegen_expect_token(p, 16)) // token='*' + && + (a = _PyPegen_name_token(p)) // NAME + ) + { + D(fprintf(stderr, "%*c+ type_param[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' NAME")); + Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); + if (_token == NULL) { + p->level--; + return NULL; + } + int _end_lineno = _token->end_lineno; + UNUSED(_end_lineno); // Only used by EXTRA macro + int _end_col_offset = _token->end_col_offset; + UNUSED(_end_col_offset); // Only used by EXTRA macro + _res = _PyAST_TypeVarTuple ( a -> v . Name . id , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s type_param[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*' NAME")); + } + { // '**' NAME ":" expression + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> type_param[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**' NAME \":\" expression")); + Token * _literal; + expr_ty a; + Token * colon; + expr_ty e; + if ( + (_literal = _PyPegen_expect_token(p, 35)) // token='**' + && + (a = _PyPegen_name_token(p)) // NAME + && + (colon = _PyPegen_expect_token(p, 11)) // token=':' + && + (e = expression_rule(p)) // expression + ) + { + D(fprintf(stderr, "%*c+ type_param[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**' NAME \":\" expression")); + _res = RAISE_SYNTAX_ERROR_STARTING_FROM ( colon , e -> kind == Tuple_kind ? "cannot use constraints with ParamSpec" : "cannot use bound with ParamSpec" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s type_param[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**' NAME \":\" expression")); + } + { // '**' NAME + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> type_param[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**' NAME")); + Token * _literal; + expr_ty a; + if ( + (_literal = _PyPegen_expect_token(p, 35)) // token='**' + && + (a = _PyPegen_name_token(p)) // NAME + ) + { + D(fprintf(stderr, "%*c+ type_param[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**' NAME")); + Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); + if (_token == NULL) { + p->level--; + return NULL; + } + int _end_lineno = _token->end_lineno; + UNUSED(_end_lineno); // Only used by EXTRA macro + int _end_col_offset = _token->end_col_offset; + UNUSED(_end_col_offset); // Only used by EXTRA macro + _res = _PyAST_ParamSpec ( a -> v . Name . id , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s type_param[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**' NAME")); + } + _res = NULL; + done: + _PyPegen_insert_memo(p, _mark, type_param_type, _res); + p->level--; + return _res; +} + +// type_param_bound: ":" expression +static expr_ty +type_param_bound_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + expr_ty _res = NULL; + int _mark = p->mark; + { // ":" expression + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> type_param_bound[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "\":\" expression")); + Token * _literal; + expr_ty e; + if ( + (_literal = _PyPegen_expect_token(p, 11)) // token=':' + && + (e = expression_rule(p)) // expression + ) + { + D(fprintf(stderr, "%*c+ type_param_bound[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "\":\" expression")); + _res = e; + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s type_param_bound[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "\":\" expression")); + } + _res = NULL; + done: + p->level--; + return _res; +} + // expressions: expression ((',' expression))+ ','? | expression ',' | expression static expr_ty expressions_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -10470,7 +10942,7 @@ expressions_rule(Parser *p) if ( (a = expression_rule(p)) // expression && - (b = _loop1_80_rule(p)) // ((',' expression))+ + (b = _loop1_83_rule(p)) // ((',' expression))+ && (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? ) @@ -10568,8 +11040,7 @@ static expr_ty expression_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -10642,11 +11113,11 @@ expression_rule(Parser *p) if ( (a = disjunction_rule(p)) // disjunction && - (_keyword = _PyPegen_expect_token(p, 639)) // token='if' + (_keyword = _PyPegen_expect_token(p, 642)) // token='if' && (b = disjunction_rule(p)) // disjunction && - (_keyword_1 = _PyPegen_expect_token(p, 642)) // token='else' + (_keyword_1 = _PyPegen_expect_token(p, 645)) // token='else' && (c = expression_rule(p)) // expression ) @@ -10723,8 +11194,7 @@ static expr_ty yield_expr_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -10753,7 +11223,7 @@ yield_expr_rule(Parser *p) if ( (_keyword = _PyPegen_expect_token(p, 573)) // token='yield' && - (_keyword_1 = _PyPegen_expect_token(p, 572)) // token='from' + (_keyword_1 = _PyPegen_expect_token(p, 608)) // token='from' && (a = expression_rule(p)) // expression ) @@ -10830,8 +11300,7 @@ static expr_ty star_expressions_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -10861,7 +11330,7 @@ star_expressions_rule(Parser *p) if ( (a = star_expression_rule(p)) // star_expression && - (b = _loop1_81_rule(p)) // ((',' star_expression))+ + (b = _loop1_84_rule(p)) // ((',' star_expression))+ && (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? ) @@ -10954,8 +11423,7 @@ static expr_ty star_expression_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -11043,8 +11511,7 @@ static asdl_expr_seq* star_named_expressions_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -11062,7 +11529,7 @@ star_named_expressions_rule(Parser *p) UNUSED(_opt_var); // Silence compiler warnings asdl_expr_seq* a; if ( - (a = (asdl_expr_seq*)_gather_82_rule(p)) // ','.star_named_expression+ + (a = (asdl_expr_seq*)_gather_85_rule(p)) // ','.star_named_expression+ && (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? ) @@ -11091,8 +11558,7 @@ static expr_ty star_named_expression_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -11175,8 +11641,7 @@ static expr_ty assignment_expression_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -11250,8 +11715,7 @@ static expr_ty named_expression_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -11329,8 +11793,7 @@ static expr_ty disjunction_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -11362,7 +11825,7 @@ disjunction_rule(Parser *p) if ( (a = conjunction_rule(p)) // conjunction && - (b = _loop1_84_rule(p)) // (('or' conjunction))+ + (b = _loop1_87_rule(p)) // (('or' conjunction))+ ) { D(fprintf(stderr, "%*c+ disjunction[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "conjunction (('or' conjunction))+")); @@ -11418,8 +11881,7 @@ static expr_ty conjunction_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -11451,7 +11913,7 @@ conjunction_rule(Parser *p) if ( (a = inversion_rule(p)) // inversion && - (b = _loop1_85_rule(p)) // (('and' inversion))+ + (b = _loop1_88_rule(p)) // (('and' inversion))+ ) { D(fprintf(stderr, "%*c+ conjunction[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "inversion (('and' inversion))+")); @@ -11507,8 +11969,7 @@ static expr_ty inversion_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -11596,8 +12057,7 @@ static expr_ty comparison_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -11625,7 +12085,7 @@ comparison_rule(Parser *p) if ( (a = bitwise_or_rule(p)) // bitwise_or && - (b = _loop1_86_rule(p)) // compare_op_bitwise_or_pair+ + (b = _loop1_89_rule(p)) // compare_op_bitwise_or_pair+ ) { D(fprintf(stderr, "%*c+ comparison[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "bitwise_or compare_op_bitwise_or_pair+")); @@ -11690,8 +12150,7 @@ static CmpopExprPair* compare_op_bitwise_or_pair_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -11900,8 +12359,7 @@ static CmpopExprPair* eq_bitwise_or_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -11947,8 +12405,7 @@ static CmpopExprPair* noteq_bitwise_or_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -11962,10 +12419,10 @@ noteq_bitwise_or_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> noteq_bitwise_or[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('!=') bitwise_or")); - void *_tmp_87_var; + void *_tmp_90_var; expr_ty a; if ( - (_tmp_87_var = _tmp_87_rule(p)) // '!=' + (_tmp_90_var = _tmp_90_rule(p)) // '!=' && (a = bitwise_or_rule(p)) // bitwise_or ) @@ -11994,8 +12451,7 @@ static CmpopExprPair* lte_bitwise_or_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -12041,8 +12497,7 @@ static CmpopExprPair* lt_bitwise_or_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -12088,8 +12543,7 @@ static CmpopExprPair* gte_bitwise_or_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -12135,8 +12589,7 @@ static CmpopExprPair* gt_bitwise_or_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -12182,8 +12635,7 @@ static CmpopExprPair* notin_bitwise_or_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -12203,7 +12655,7 @@ notin_bitwise_or_rule(Parser *p) if ( (_keyword = _PyPegen_expect_token(p, 581)) // token='not' && - (_keyword_1 = _PyPegen_expect_token(p, 648)) // token='in' + (_keyword_1 = _PyPegen_expect_token(p, 651)) // token='in' && (a = bitwise_or_rule(p)) // bitwise_or ) @@ -12232,8 +12684,7 @@ static CmpopExprPair* in_bitwise_or_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -12250,7 +12701,7 @@ in_bitwise_or_rule(Parser *p) Token * _keyword; expr_ty a; if ( - (_keyword = _PyPegen_expect_token(p, 648)) // token='in' + (_keyword = _PyPegen_expect_token(p, 651)) // token='in' && (a = bitwise_or_rule(p)) // bitwise_or ) @@ -12279,8 +12730,7 @@ static CmpopExprPair* isnot_bitwise_or_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -12329,8 +12779,7 @@ static CmpopExprPair* is_bitwise_or_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -12378,8 +12827,7 @@ static expr_ty bitwise_or_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } expr_ty _res = NULL; if (_PyPegen_is_memoized(p, bitwise_or_type, &_res)) { @@ -12413,8 +12861,7 @@ static expr_ty bitwise_or_raw(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -12502,8 +12949,7 @@ static expr_ty bitwise_xor_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } expr_ty _res = NULL; if (_PyPegen_is_memoized(p, bitwise_xor_type, &_res)) { @@ -12537,8 +12983,7 @@ static expr_ty bitwise_xor_raw(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -12626,8 +13071,7 @@ static expr_ty bitwise_and_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } expr_ty _res = NULL; if (_PyPegen_is_memoized(p, bitwise_and_type, &_res)) { @@ -12661,8 +13105,7 @@ static expr_ty bitwise_and_raw(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -12750,8 +13193,7 @@ static expr_ty shift_expr_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } expr_ty _res = NULL; if (_PyPegen_is_memoized(p, shift_expr_type, &_res)) { @@ -12785,8 +13227,7 @@ static expr_ty shift_expr_raw(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -12913,8 +13354,7 @@ static expr_ty sum_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } expr_ty _res = NULL; if (_PyPegen_is_memoized(p, sum_type, &_res)) { @@ -12948,8 +13388,7 @@ static expr_ty sum_raw(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -13082,8 +13521,7 @@ static expr_ty term_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } expr_ty _res = NULL; if (_PyPegen_is_memoized(p, term_type, &_res)) { @@ -13117,8 +13555,7 @@ static expr_ty term_raw(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -13360,8 +13797,7 @@ static expr_ty factor_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -13521,8 +13957,7 @@ static expr_ty power_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -13608,8 +14043,7 @@ static expr_ty await_primary_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -13704,8 +14138,7 @@ static expr_ty primary_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } expr_ty _res = NULL; if (_PyPegen_is_memoized(p, primary_type, &_res)) { @@ -13739,8 +14172,7 @@ static expr_ty primary_raw(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -13946,8 +14378,7 @@ static expr_ty slices_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -14000,7 +14431,7 @@ slices_rule(Parser *p) UNUSED(_opt_var); // Silence compiler warnings asdl_expr_seq* a; if ( - (a = (asdl_expr_seq*)_gather_88_rule(p)) // ','.(slice | starred_expression)+ + (a = (asdl_expr_seq*)_gather_91_rule(p)) // ','.(slice | starred_expression)+ && (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? ) @@ -14038,8 +14469,7 @@ static expr_ty slice_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -14073,7 +14503,7 @@ slice_rule(Parser *p) && (b = expression_rule(p), !p->error_indicator) // expression? && - (c = _tmp_90_rule(p), !p->error_indicator) // [':' expression?] + (c = _tmp_93_rule(p), !p->error_indicator) // [':' expression?] ) { D(fprintf(stderr, "%*c+ slice[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression? ':' expression? [':' expression?]")); @@ -14133,7 +14563,7 @@ slice_rule(Parser *p) // | 'True' // | 'False' // | 'None' -// | &STRING strings +// | &(STRING | FSTRING_START) strings // | NUMBER // | &'(' (tuple | group | genexp) // | &'[' (list | listcomp) @@ -14143,8 +14573,7 @@ static expr_ty atom_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -14188,7 +14617,7 @@ atom_rule(Parser *p) D(fprintf(stderr, "%*c> atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'True'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 600)) // token='True' + (_keyword = _PyPegen_expect_token(p, 601)) // token='True' ) { D(fprintf(stderr, "%*c+ atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'True'")); @@ -14221,7 +14650,7 @@ atom_rule(Parser *p) D(fprintf(stderr, "%*c> atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'False'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 602)) // token='False' + (_keyword = _PyPegen_expect_token(p, 603)) // token='False' ) { D(fprintf(stderr, "%*c+ atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'False'")); @@ -14254,7 +14683,7 @@ atom_rule(Parser *p) D(fprintf(stderr, "%*c> atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'None'")); Token * _keyword; if ( - (_keyword = _PyPegen_expect_token(p, 601)) // token='None' + (_keyword = _PyPegen_expect_token(p, 602)) // token='None' ) { D(fprintf(stderr, "%*c+ atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'None'")); @@ -14279,26 +14708,26 @@ atom_rule(Parser *p) D(fprintf(stderr, "%*c%s atom[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'None'")); } - { // &STRING strings + { // &(STRING | FSTRING_START) strings if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&STRING strings")); + D(fprintf(stderr, "%*c> atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&(STRING | FSTRING_START) strings")); expr_ty strings_var; if ( - _PyPegen_lookahead(1, _PyPegen_string_token, p) + _PyPegen_lookahead(1, _tmp_94_rule, p) && (strings_var = strings_rule(p)) // strings ) { - D(fprintf(stderr, "%*c+ atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "&STRING strings")); + D(fprintf(stderr, "%*c+ atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "&(STRING | FSTRING_START) strings")); _res = strings_var; goto done; } p->mark = _mark; D(fprintf(stderr, "%*c%s atom[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "&STRING strings")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "&(STRING | FSTRING_START) strings")); } { // NUMBER if (p->error_indicator) { @@ -14325,15 +14754,15 @@ atom_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'(' (tuple | group | genexp)")); - void *_tmp_91_var; + void *_tmp_95_var; if ( _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 7) // token='(' && - (_tmp_91_var = _tmp_91_rule(p)) // tuple | group | genexp + (_tmp_95_var = _tmp_95_rule(p)) // tuple | group | genexp ) { D(fprintf(stderr, "%*c+ atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "&'(' (tuple | group | genexp)")); - _res = _tmp_91_var; + _res = _tmp_95_var; goto done; } p->mark = _mark; @@ -14346,15 +14775,15 @@ atom_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'[' (list | listcomp)")); - void *_tmp_92_var; + void *_tmp_96_var; if ( _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 9) // token='[' && - (_tmp_92_var = _tmp_92_rule(p)) // list | listcomp + (_tmp_96_var = _tmp_96_rule(p)) // list | listcomp ) { D(fprintf(stderr, "%*c+ atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "&'[' (list | listcomp)")); - _res = _tmp_92_var; + _res = _tmp_96_var; goto done; } p->mark = _mark; @@ -14367,15 +14796,15 @@ atom_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'{' (dict | set | dictcomp | setcomp)")); - void *_tmp_93_var; + void *_tmp_97_var; if ( _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 25) // token='{' && - (_tmp_93_var = _tmp_93_rule(p)) // dict | set | dictcomp | setcomp + (_tmp_97_var = _tmp_97_rule(p)) // dict | set | dictcomp | setcomp ) { D(fprintf(stderr, "%*c+ atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "&'{' (dict | set | dictcomp | setcomp)")); - _res = _tmp_93_var; + _res = _tmp_97_var; goto done; } p->mark = _mark; @@ -14426,8 +14855,7 @@ static expr_ty group_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -14447,7 +14875,7 @@ group_rule(Parser *p) if ( (_literal = _PyPegen_expect_token(p, 7)) // token='(' && - (a = _tmp_94_rule(p)) // yield_expr | named_expression + (a = _tmp_98_rule(p)) // yield_expr | named_expression && (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' ) @@ -14495,8 +14923,7 @@ static expr_ty lambdef_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -14524,7 +14951,7 @@ lambdef_rule(Parser *p) void *a; expr_ty b; if ( - (_keyword = _PyPegen_expect_token(p, 586)) // token='lambda' + (_keyword = _PyPegen_expect_token(p, 600)) // token='lambda' && (a = lambda_params_rule(p), !p->error_indicator) // lambda_params? && @@ -14566,8 +14993,7 @@ static arguments_ty lambda_params_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -14629,8 +15055,7 @@ static arguments_ty lambda_parameters_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -14651,9 +15076,9 @@ lambda_parameters_rule(Parser *p) if ( (a = lambda_slash_no_default_rule(p)) // lambda_slash_no_default && - (b = (asdl_arg_seq*)_loop0_95_rule(p)) // lambda_param_no_default* + (b = (asdl_arg_seq*)_loop0_99_rule(p)) // lambda_param_no_default* && - (c = _loop0_96_rule(p)) // lambda_param_with_default* + (c = _loop0_100_rule(p)) // lambda_param_with_default* && (d = lambda_star_etc_rule(p), !p->error_indicator) // lambda_star_etc? ) @@ -14683,7 +15108,7 @@ lambda_parameters_rule(Parser *p) if ( (a = lambda_slash_with_default_rule(p)) // lambda_slash_with_default && - (b = _loop0_97_rule(p)) // lambda_param_with_default* + (b = _loop0_101_rule(p)) // lambda_param_with_default* && (c = lambda_star_etc_rule(p), !p->error_indicator) // lambda_star_etc? ) @@ -14711,9 +15136,9 @@ lambda_parameters_rule(Parser *p) asdl_seq * b; void *c; if ( - (a = (asdl_arg_seq*)_loop1_98_rule(p)) // lambda_param_no_default+ + (a = (asdl_arg_seq*)_loop1_102_rule(p)) // lambda_param_no_default+ && - (b = _loop0_99_rule(p)) // lambda_param_with_default* + (b = _loop0_103_rule(p)) // lambda_param_with_default* && (c = lambda_star_etc_rule(p), !p->error_indicator) // lambda_star_etc? ) @@ -14740,7 +15165,7 @@ lambda_parameters_rule(Parser *p) asdl_seq * a; void *b; if ( - (a = _loop1_100_rule(p)) // lambda_param_with_default+ + (a = _loop1_104_rule(p)) // lambda_param_with_default+ && (b = lambda_star_etc_rule(p), !p->error_indicator) // lambda_star_etc? ) @@ -14795,8 +15220,7 @@ static asdl_arg_seq* lambda_slash_no_default_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -14814,7 +15238,7 @@ lambda_slash_no_default_rule(Parser *p) Token * _literal_1; asdl_arg_seq* a; if ( - (a = (asdl_arg_seq*)_loop1_101_rule(p)) // lambda_param_no_default+ + (a = (asdl_arg_seq*)_loop1_105_rule(p)) // lambda_param_no_default+ && (_literal = _PyPegen_expect_token(p, 17)) // token='/' && @@ -14843,7 +15267,7 @@ lambda_slash_no_default_rule(Parser *p) Token * _literal; asdl_arg_seq* a; if ( - (a = (asdl_arg_seq*)_loop1_102_rule(p)) // lambda_param_no_default+ + (a = (asdl_arg_seq*)_loop1_106_rule(p)) // lambda_param_no_default+ && (_literal = _PyPegen_expect_token(p, 17)) // token='/' && @@ -14876,8 +15300,7 @@ static SlashWithDefault* lambda_slash_with_default_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -14896,9 +15319,9 @@ lambda_slash_with_default_rule(Parser *p) asdl_seq * a; asdl_seq * b; if ( - (a = _loop0_103_rule(p)) // lambda_param_no_default* + (a = _loop0_107_rule(p)) // lambda_param_no_default* && - (b = _loop1_104_rule(p)) // lambda_param_with_default+ + (b = _loop1_108_rule(p)) // lambda_param_with_default+ && (_literal = _PyPegen_expect_token(p, 17)) // token='/' && @@ -14928,9 +15351,9 @@ lambda_slash_with_default_rule(Parser *p) asdl_seq * a; asdl_seq * b; if ( - (a = _loop0_105_rule(p)) // lambda_param_no_default* + (a = _loop0_109_rule(p)) // lambda_param_no_default* && - (b = _loop1_106_rule(p)) // lambda_param_with_default+ + (b = _loop1_110_rule(p)) // lambda_param_with_default+ && (_literal = _PyPegen_expect_token(p, 17)) // token='/' && @@ -14965,8 +15388,7 @@ static StarEtc* lambda_star_etc_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -15008,7 +15430,7 @@ lambda_star_etc_rule(Parser *p) && (a = lambda_param_no_default_rule(p)) // lambda_param_no_default && - (b = _loop0_107_rule(p)) // lambda_param_maybe_default* + (b = _loop0_111_rule(p)) // lambda_param_maybe_default* && (c = lambda_kwds_rule(p), !p->error_indicator) // lambda_kwds? ) @@ -15041,7 +15463,7 @@ lambda_star_etc_rule(Parser *p) && (_literal_1 = _PyPegen_expect_token(p, 12)) // token=',' && - (b = _loop1_108_rule(p)) // lambda_param_maybe_default+ + (b = _loop1_112_rule(p)) // lambda_param_maybe_default+ && (c = lambda_kwds_rule(p), !p->error_indicator) // lambda_kwds? ) @@ -15094,8 +15516,7 @@ static arg_ty lambda_kwds_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -15160,8 +15581,7 @@ static arg_ty lambda_param_no_default_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -15233,8 +15653,7 @@ static NameDefaultPair* lambda_param_with_default_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -15312,8 +15731,7 @@ static NameDefaultPair* lambda_param_maybe_default_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -15391,8 +15809,7 @@ static arg_ty lambda_param_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -15448,13 +15865,386 @@ lambda_param_rule(Parser *p) return _res; } -// strings: STRING+ +// fstring_middle: fstring_replacement_field | FSTRING_MIDDLE static expr_ty -strings_rule(Parser *p) +fstring_middle_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + expr_ty _res = NULL; + int _mark = p->mark; + { // fstring_replacement_field + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> fstring_middle[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "fstring_replacement_field")); + expr_ty fstring_replacement_field_var; + if ( + (fstring_replacement_field_var = fstring_replacement_field_rule(p)) // fstring_replacement_field + ) + { + D(fprintf(stderr, "%*c+ fstring_middle[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "fstring_replacement_field")); + _res = fstring_replacement_field_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s fstring_middle[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "fstring_replacement_field")); + } + { // FSTRING_MIDDLE + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> fstring_middle[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "FSTRING_MIDDLE")); + Token * t; + if ( + (t = _PyPegen_expect_token(p, FSTRING_MIDDLE)) // token='FSTRING_MIDDLE' + ) + { + D(fprintf(stderr, "%*c+ fstring_middle[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "FSTRING_MIDDLE")); + _res = _PyPegen_constant_from_token ( p , t ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s fstring_middle[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "FSTRING_MIDDLE")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// fstring_replacement_field: +// | '{' (yield_expr | star_expressions) "="? fstring_conversion? fstring_full_format_spec? '}' +// | invalid_replacement_field +static expr_ty +fstring_replacement_field_rule(Parser *p) { if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + expr_ty _res = NULL; + int _mark = p->mark; + if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { p->error_indicator = 1; - PyErr_NoMemory(); + p->level--; + return NULL; + } + int _start_lineno = p->tokens[_mark]->lineno; + UNUSED(_start_lineno); // Only used by EXTRA macro + int _start_col_offset = p->tokens[_mark]->col_offset; + UNUSED(_start_col_offset); // Only used by EXTRA macro + { // '{' (yield_expr | star_expressions) "="? fstring_conversion? fstring_full_format_spec? '}' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> fstring_replacement_field[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{' (yield_expr | star_expressions) \"=\"? fstring_conversion? fstring_full_format_spec? '}'")); + Token * _literal; + void *a; + void *conversion; + void *debug_expr; + void *format; + Token * rbrace; + if ( + (_literal = _PyPegen_expect_token(p, 25)) // token='{' + && + (a = _tmp_113_rule(p)) // yield_expr | star_expressions + && + (debug_expr = _PyPegen_expect_token(p, 22), !p->error_indicator) // "="? + && + (conversion = fstring_conversion_rule(p), !p->error_indicator) // fstring_conversion? + && + (format = fstring_full_format_spec_rule(p), !p->error_indicator) // fstring_full_format_spec? + && + (rbrace = _PyPegen_expect_token(p, 26)) // token='}' + ) + { + D(fprintf(stderr, "%*c+ fstring_replacement_field[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' (yield_expr | star_expressions) \"=\"? fstring_conversion? fstring_full_format_spec? '}'")); + Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); + if (_token == NULL) { + p->level--; + return NULL; + } + int _end_lineno = _token->end_lineno; + UNUSED(_end_lineno); // Only used by EXTRA macro + int _end_col_offset = _token->end_col_offset; + UNUSED(_end_col_offset); // Only used by EXTRA macro + _res = _PyPegen_formatted_value ( p , a , debug_expr , conversion , format , rbrace , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s fstring_replacement_field[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'{' (yield_expr | star_expressions) \"=\"? fstring_conversion? fstring_full_format_spec? '}'")); + } + if (p->call_invalid_rules) { // invalid_replacement_field + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> fstring_replacement_field[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_replacement_field")); + void *invalid_replacement_field_var; + if ( + (invalid_replacement_field_var = invalid_replacement_field_rule(p)) // invalid_replacement_field + ) + { + D(fprintf(stderr, "%*c+ fstring_replacement_field[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_replacement_field")); + _res = invalid_replacement_field_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s fstring_replacement_field[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_replacement_field")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// fstring_conversion: "!" NAME +static ResultTokenWithMetadata* +fstring_conversion_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + ResultTokenWithMetadata* _res = NULL; + int _mark = p->mark; + { // "!" NAME + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> fstring_conversion[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "\"!\" NAME")); + expr_ty conv; + Token * conv_token; + if ( + (conv_token = _PyPegen_expect_token(p, 54)) // token='!' + && + (conv = _PyPegen_name_token(p)) // NAME + ) + { + D(fprintf(stderr, "%*c+ fstring_conversion[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "\"!\" NAME")); + _res = _PyPegen_check_fstring_conversion ( p , conv_token , conv ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s fstring_conversion[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "\"!\" NAME")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// fstring_full_format_spec: ':' fstring_format_spec* +static ResultTokenWithMetadata* +fstring_full_format_spec_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + ResultTokenWithMetadata* _res = NULL; + int _mark = p->mark; + if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { + p->error_indicator = 1; + p->level--; + return NULL; + } + int _start_lineno = p->tokens[_mark]->lineno; + UNUSED(_start_lineno); // Only used by EXTRA macro + int _start_col_offset = p->tokens[_mark]->col_offset; + UNUSED(_start_col_offset); // Only used by EXTRA macro + { // ':' fstring_format_spec* + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> fstring_full_format_spec[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':' fstring_format_spec*")); + Token * colon; + asdl_seq * spec; + if ( + (colon = _PyPegen_expect_token(p, 11)) // token=':' + && + (spec = _loop0_114_rule(p)) // fstring_format_spec* + ) + { + D(fprintf(stderr, "%*c+ fstring_full_format_spec[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':' fstring_format_spec*")); + Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); + if (_token == NULL) { + p->level--; + return NULL; + } + int _end_lineno = _token->end_lineno; + UNUSED(_end_lineno); // Only used by EXTRA macro + int _end_col_offset = _token->end_col_offset; + UNUSED(_end_col_offset); // Only used by EXTRA macro + _res = _PyPegen_setup_full_format_spec ( p , colon , ( asdl_expr_seq* ) spec , EXTRA ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s fstring_full_format_spec[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':' fstring_format_spec*")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// fstring_format_spec: FSTRING_MIDDLE | fstring_replacement_field +static expr_ty +fstring_format_spec_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + expr_ty _res = NULL; + int _mark = p->mark; + { // FSTRING_MIDDLE + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> fstring_format_spec[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "FSTRING_MIDDLE")); + Token * t; + if ( + (t = _PyPegen_expect_token(p, FSTRING_MIDDLE)) // token='FSTRING_MIDDLE' + ) + { + D(fprintf(stderr, "%*c+ fstring_format_spec[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "FSTRING_MIDDLE")); + _res = _PyPegen_decoded_constant_from_token ( p , t ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s fstring_format_spec[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "FSTRING_MIDDLE")); + } + { // fstring_replacement_field + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> fstring_format_spec[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "fstring_replacement_field")); + expr_ty fstring_replacement_field_var; + if ( + (fstring_replacement_field_var = fstring_replacement_field_rule(p)) // fstring_replacement_field + ) + { + D(fprintf(stderr, "%*c+ fstring_format_spec[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "fstring_replacement_field")); + _res = fstring_replacement_field_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s fstring_format_spec[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "fstring_replacement_field")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// string: STRING +static expr_ty +string_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + expr_ty _res = NULL; + int _mark = p->mark; + { // STRING + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> string[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "STRING")); + Token* s; + if ( + (s = (Token*)_PyPegen_string_token(p)) // STRING + ) + { + D(fprintf(stderr, "%*c+ string[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "STRING")); + _res = _PyPegen_constant_from_string ( p , s ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s string[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "STRING")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// strings: ((fstring | string))+ +static expr_ty +strings_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -15466,19 +16256,37 @@ strings_rule(Parser *p) return _res; } int _mark = p->mark; - { // STRING+ + if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) { + p->error_indicator = 1; + p->level--; + return NULL; + } + int _start_lineno = p->tokens[_mark]->lineno; + UNUSED(_start_lineno); // Only used by EXTRA macro + int _start_col_offset = p->tokens[_mark]->col_offset; + UNUSED(_start_col_offset); // Only used by EXTRA macro + { // ((fstring | string))+ if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> strings[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "STRING+")); - asdl_seq * a; + D(fprintf(stderr, "%*c> strings[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "((fstring | string))+")); + asdl_expr_seq* a; if ( - (a = _loop1_109_rule(p)) // STRING+ + (a = (asdl_expr_seq*)_loop1_115_rule(p)) // ((fstring | string))+ ) { - D(fprintf(stderr, "%*c+ strings[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "STRING+")); - _res = _PyPegen_concatenate_strings ( p , a ); + D(fprintf(stderr, "%*c+ strings[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "((fstring | string))+")); + Token *_token = _PyPegen_get_last_nonnwhitespace_token(p); + if (_token == NULL) { + p->level--; + return NULL; + } + int _end_lineno = _token->end_lineno; + UNUSED(_end_lineno); // Only used by EXTRA macro + int _end_col_offset = _token->end_col_offset; + UNUSED(_end_col_offset); // Only used by EXTRA macro + _res = _PyPegen_concatenate_strings ( p , a , EXTRA ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; p->level--; @@ -15488,7 +16296,7 @@ strings_rule(Parser *p) } p->mark = _mark; D(fprintf(stderr, "%*c%s strings[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "STRING+")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "((fstring | string))+")); } _res = NULL; done: @@ -15502,8 +16310,7 @@ static expr_ty list_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -15570,8 +16377,7 @@ static expr_ty tuple_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -15600,7 +16406,7 @@ tuple_rule(Parser *p) if ( (_literal = _PyPegen_expect_token(p, 7)) // token='(' && - (a = _tmp_110_rule(p), !p->error_indicator) // [star_named_expression ',' star_named_expressions?] + (a = _tmp_116_rule(p), !p->error_indicator) // [star_named_expression ',' star_named_expressions?] && (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' ) @@ -15638,8 +16444,7 @@ static expr_ty set_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -15706,8 +16511,7 @@ static expr_ty dict_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -15799,8 +16603,7 @@ static asdl_seq* double_starred_kvpairs_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -15818,7 +16621,7 @@ double_starred_kvpairs_rule(Parser *p) UNUSED(_opt_var); // Silence compiler warnings asdl_seq * a; if ( - (a = _gather_111_rule(p)) // ','.double_starred_kvpair+ + (a = _gather_117_rule(p)) // ','.double_starred_kvpair+ && (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? ) @@ -15847,8 +16650,7 @@ static KeyValuePair* double_starred_kvpair_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -15913,8 +16715,7 @@ static KeyValuePair* kvpair_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -15963,8 +16764,7 @@ static asdl_comprehension_seq* for_if_clauses_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -15980,7 +16780,7 @@ for_if_clauses_rule(Parser *p) D(fprintf(stderr, "%*c> for_if_clauses[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "for_if_clause+")); asdl_comprehension_seq* a; if ( - (a = (asdl_comprehension_seq*)_loop1_113_rule(p)) // for_if_clause+ + (a = (asdl_comprehension_seq*)_loop1_119_rule(p)) // for_if_clause+ ) { D(fprintf(stderr, "%*c+ for_if_clauses[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "for_if_clause+")); @@ -16010,8 +16810,7 @@ static comprehension_ty for_if_clause_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -16035,17 +16834,17 @@ for_if_clause_rule(Parser *p) if ( (async_var = _PyPegen_expect_token(p, ASYNC)) // token='ASYNC' && - (_keyword = _PyPegen_expect_token(p, 647)) // token='for' + (_keyword = _PyPegen_expect_token(p, 650)) // token='for' && (a = star_targets_rule(p)) // star_targets && - (_keyword_1 = _PyPegen_expect_token(p, 648)) // token='in' + (_keyword_1 = _PyPegen_expect_token(p, 651)) // token='in' && (_cut_var = 1) && (b = disjunction_rule(p)) // disjunction && - (c = (asdl_expr_seq*)_loop0_114_rule(p)) // (('if' disjunction))* + (c = (asdl_expr_seq*)_loop0_120_rule(p)) // (('if' disjunction))* ) { D(fprintf(stderr, "%*c+ for_if_clause[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "ASYNC 'for' star_targets 'in' ~ disjunction (('if' disjunction))*")); @@ -16078,17 +16877,17 @@ for_if_clause_rule(Parser *p) expr_ty b; asdl_expr_seq* c; if ( - (_keyword = _PyPegen_expect_token(p, 647)) // token='for' + (_keyword = _PyPegen_expect_token(p, 650)) // token='for' && (a = star_targets_rule(p)) // star_targets && - (_keyword_1 = _PyPegen_expect_token(p, 648)) // token='in' + (_keyword_1 = _PyPegen_expect_token(p, 651)) // token='in' && (_cut_var = 1) && (b = disjunction_rule(p)) // disjunction && - (c = (asdl_expr_seq*)_loop0_115_rule(p)) // (('if' disjunction))* + (c = (asdl_expr_seq*)_loop0_121_rule(p)) // (('if' disjunction))* ) { D(fprintf(stderr, "%*c+ for_if_clause[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'for' star_targets 'in' ~ disjunction (('if' disjunction))*")); @@ -16138,8 +16937,7 @@ static expr_ty listcomp_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -16228,8 +17026,7 @@ static expr_ty setcomp_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -16320,8 +17117,7 @@ static expr_ty genexp_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -16351,7 +17147,7 @@ genexp_rule(Parser *p) if ( (_literal = _PyPegen_expect_token(p, 7)) // token='(' && - (a = _tmp_116_rule(p)) // assignment_expression | expression !':=' + (a = _tmp_122_rule(p)) // assignment_expression | expression !':=' && (b = for_if_clauses_rule(p)) // for_if_clauses && @@ -16410,8 +17206,7 @@ static expr_ty dictcomp_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -16500,8 +17295,7 @@ static expr_ty arguments_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -16576,8 +17370,7 @@ static expr_ty args_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -16603,9 +17396,9 @@ args_rule(Parser *p) asdl_expr_seq* a; void *b; if ( - (a = (asdl_expr_seq*)_gather_117_rule(p)) // ','.(starred_expression | (assignment_expression | expression !':=') !'=')+ + (a = (asdl_expr_seq*)_gather_123_rule(p)) // ','.(starred_expression | (assignment_expression | expression !':=') !'=')+ && - (b = _tmp_119_rule(p), !p->error_indicator) // [',' kwargs] + (b = _tmp_125_rule(p), !p->error_indicator) // [',' kwargs] ) { D(fprintf(stderr, "%*c+ args[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.(starred_expression | (assignment_expression | expression !':=') !'=')+ [',' kwargs]")); @@ -16677,8 +17470,7 @@ static asdl_seq* kwargs_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -16696,11 +17488,11 @@ kwargs_rule(Parser *p) asdl_seq * a; asdl_seq * b; if ( - (a = _gather_120_rule(p)) // ','.kwarg_or_starred+ + (a = _gather_126_rule(p)) // ','.kwarg_or_starred+ && (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (b = _gather_122_rule(p)) // ','.kwarg_or_double_starred+ + (b = _gather_128_rule(p)) // ','.kwarg_or_double_starred+ ) { D(fprintf(stderr, "%*c+ kwargs[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.kwarg_or_starred+ ',' ','.kwarg_or_double_starred+")); @@ -16722,13 +17514,13 @@ kwargs_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> kwargs[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.kwarg_or_starred+")); - asdl_seq * _gather_124_var; + asdl_seq * _gather_130_var; if ( - (_gather_124_var = _gather_124_rule(p)) // ','.kwarg_or_starred+ + (_gather_130_var = _gather_130_rule(p)) // ','.kwarg_or_starred+ ) { D(fprintf(stderr, "%*c+ kwargs[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.kwarg_or_starred+")); - _res = _gather_124_var; + _res = _gather_130_var; goto done; } p->mark = _mark; @@ -16741,13 +17533,13 @@ kwargs_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> kwargs[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.kwarg_or_double_starred+")); - asdl_seq * _gather_126_var; + asdl_seq * _gather_132_var; if ( - (_gather_126_var = _gather_126_rule(p)) // ','.kwarg_or_double_starred+ + (_gather_132_var = _gather_132_rule(p)) // ','.kwarg_or_double_starred+ ) { D(fprintf(stderr, "%*c+ kwargs[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.kwarg_or_double_starred+")); - _res = _gather_126_var; + _res = _gather_132_var; goto done; } p->mark = _mark; @@ -16760,13 +17552,12 @@ kwargs_rule(Parser *p) return _res; } -// starred_expression: '*' expression +// starred_expression: invalid_starred_expression | '*' expression static expr_ty starred_expression_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -16783,6 +17574,25 @@ starred_expression_rule(Parser *p) UNUSED(_start_lineno); // Only used by EXTRA macro int _start_col_offset = p->tokens[_mark]->col_offset; UNUSED(_start_col_offset); // Only used by EXTRA macro + if (p->call_invalid_rules) { // invalid_starred_expression + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> starred_expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "invalid_starred_expression")); + void *invalid_starred_expression_var; + if ( + (invalid_starred_expression_var = invalid_starred_expression_rule(p)) // invalid_starred_expression + ) + { + D(fprintf(stderr, "%*c+ starred_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "invalid_starred_expression")); + _res = invalid_starred_expression_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s starred_expression[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_starred_expression")); + } { // '*' expression if (p->error_indicator) { p->level--; @@ -16830,8 +17640,7 @@ static KeywordOrStarred* kwarg_or_starred_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -16941,8 +17750,7 @@ static KeywordOrStarred* kwarg_or_double_starred_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -17064,8 +17872,7 @@ static expr_ty star_targets_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -17121,7 +17928,7 @@ star_targets_rule(Parser *p) if ( (a = star_target_rule(p)) // star_target && - (b = _loop0_128_rule(p)) // ((',' star_target))* + (b = _loop0_134_rule(p)) // ((',' star_target))* && (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? ) @@ -17159,8 +17966,7 @@ static asdl_expr_seq* star_targets_list_seq_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -17178,7 +17984,7 @@ star_targets_list_seq_rule(Parser *p) UNUSED(_opt_var); // Silence compiler warnings asdl_expr_seq* a; if ( - (a = (asdl_expr_seq*)_gather_129_rule(p)) // ','.star_target+ + (a = (asdl_expr_seq*)_gather_135_rule(p)) // ','.star_target+ && (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? ) @@ -17207,8 +18013,7 @@ static asdl_expr_seq* star_targets_tuple_seq_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -17229,7 +18034,7 @@ star_targets_tuple_seq_rule(Parser *p) if ( (a = star_target_rule(p)) // star_target && - (b = _loop1_131_rule(p)) // ((',' star_target))+ + (b = _loop1_137_rule(p)) // ((',' star_target))+ && (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? ) @@ -17285,8 +18090,7 @@ static expr_ty star_target_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -17318,7 +18122,7 @@ star_target_rule(Parser *p) if ( (_literal = _PyPegen_expect_token(p, 16)) // token='*' && - (a = _tmp_132_rule(p)) // !'*' star_target + (a = _tmp_138_rule(p)) // !'*' star_target ) { D(fprintf(stderr, "%*c+ star_target[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' (!'*' star_target)")); @@ -17377,8 +18181,7 @@ static expr_ty target_with_star_atom_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -17519,8 +18322,7 @@ static expr_ty star_atom_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -17680,8 +18482,7 @@ static expr_ty single_target_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -17775,8 +18576,7 @@ static expr_ty single_subscript_attribute_target_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -17896,8 +18696,7 @@ static expr_ty t_primary_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } expr_ty _res = NULL; if (_PyPegen_is_memoized(p, t_primary_type, &_res)) { @@ -17931,8 +18730,7 @@ static expr_ty t_primary_raw(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -18153,8 +18951,7 @@ static void * t_lookahead_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -18230,8 +19027,7 @@ static asdl_expr_seq* del_targets_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -18249,7 +19045,7 @@ del_targets_rule(Parser *p) UNUSED(_opt_var); // Silence compiler warnings asdl_expr_seq* a; if ( - (a = (asdl_expr_seq*)_gather_133_rule(p)) // ','.del_target+ + (a = (asdl_expr_seq*)_gather_139_rule(p)) // ','.del_target+ && (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? ) @@ -18281,8 +19077,7 @@ static expr_ty del_target_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -18419,8 +19214,7 @@ static expr_ty del_t_atom_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -18587,8 +19381,7 @@ static asdl_expr_seq* type_expressions_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -18610,7 +19403,7 @@ type_expressions_rule(Parser *p) expr_ty b; expr_ty c; if ( - (a = _gather_135_rule(p)) // ','.expression+ + (a = _gather_141_rule(p)) // ','.expression+ && (_literal = _PyPegen_expect_token(p, 12)) // token=',' && @@ -18649,7 +19442,7 @@ type_expressions_rule(Parser *p) asdl_seq * a; expr_ty b; if ( - (a = _gather_137_rule(p)) // ','.expression+ + (a = _gather_143_rule(p)) // ','.expression+ && (_literal = _PyPegen_expect_token(p, 12)) // token=',' && @@ -18682,7 +19475,7 @@ type_expressions_rule(Parser *p) asdl_seq * a; expr_ty b; if ( - (a = _gather_139_rule(p)) // ','.expression+ + (a = _gather_145_rule(p)) // ','.expression+ && (_literal = _PyPegen_expect_token(p, 12)) // token=',' && @@ -18802,7 +19595,7 @@ type_expressions_rule(Parser *p) D(fprintf(stderr, "%*c> type_expressions[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.expression+")); asdl_expr_seq* a; if ( - (a = (asdl_expr_seq*)_gather_141_rule(p)) // ','.expression+ + (a = (asdl_expr_seq*)_gather_147_rule(p)) // ','.expression+ ) { D(fprintf(stderr, "%*c+ type_expressions[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.expression+")); @@ -18832,8 +19625,7 @@ static Token* func_type_comment_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -18854,7 +19646,7 @@ func_type_comment_rule(Parser *p) && (t = _PyPegen_expect_token(p, TYPE_COMMENT)) // token='TYPE_COMMENT' && - _PyPegen_lookahead(1, _tmp_143_rule, p) + _PyPegen_lookahead(1, _tmp_149_rule, p) ) { D(fprintf(stderr, "%*c+ func_type_comment[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NEWLINE TYPE_COMMENT &(NEWLINE INDENT)")); @@ -18918,6 +19710,7 @@ func_type_comment_rule(Parser *p) // | args ',' '*' // | expression for_if_clauses ',' [args | expression for_if_clauses] // | NAME '=' expression for_if_clauses +// | [(args ',')] NAME '=' &(',' | ')') // | args for_if_clauses // | args ',' expression for_if_clauses // | args ',' args @@ -18925,8 +19718,7 @@ static void * invalid_arguments_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -18982,7 +19774,7 @@ invalid_arguments_rule(Parser *p) && (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (_opt_var = _tmp_144_rule(p), !p->error_indicator) // [args | expression for_if_clauses] + (_opt_var = _tmp_150_rule(p), !p->error_indicator) // [args | expression for_if_clauses] ) { D(fprintf(stderr, "%*c+ invalid_arguments[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression for_if_clauses ',' [args | expression for_if_clauses]")); @@ -19031,6 +19823,39 @@ invalid_arguments_rule(Parser *p) D(fprintf(stderr, "%*c%s invalid_arguments[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NAME '=' expression for_if_clauses")); } + { // [(args ',')] NAME '=' &(',' | ')') + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_arguments[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "[(args ',')] NAME '=' &(',' | ')')")); + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + expr_ty a; + Token * b; + if ( + (_opt_var = _tmp_151_rule(p), !p->error_indicator) // [(args ',')] + && + (a = _PyPegen_name_token(p)) // NAME + && + (b = _PyPegen_expect_token(p, 22)) // token='=' + && + _PyPegen_lookahead(1, _tmp_152_rule, p) + ) + { + D(fprintf(stderr, "%*c+ invalid_arguments[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "[(args ',')] NAME '=' &(',' | ')')")); + _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "expected argument value expression" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_arguments[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "[(args ',')] NAME '=' &(',' | ')')")); + } { // args for_if_clauses if (p->error_indicator) { p->level--; @@ -19131,12 +19956,12 @@ invalid_arguments_rule(Parser *p) // | ('True' | 'False' | 'None') '=' // | NAME '=' expression for_if_clauses // | !(NAME '=') expression '=' +// | '**' expression '=' expression static void * invalid_kwarg_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -19153,7 +19978,7 @@ invalid_kwarg_rule(Parser *p) Token* a; Token * b; if ( - (a = (Token*)_tmp_145_rule(p)) // 'True' | 'False' | 'None' + (a = (Token*)_tmp_153_rule(p)) // 'True' | 'False' | 'None' && (b = _PyPegen_expect_token(p, 22)) // token='=' ) @@ -19213,7 +20038,7 @@ invalid_kwarg_rule(Parser *p) expr_ty a; Token * b; if ( - _PyPegen_lookahead(0, _tmp_146_rule, p) + _PyPegen_lookahead(0, _tmp_154_rule, p) && (a = expression_rule(p)) // expression && @@ -19233,6 +20058,39 @@ invalid_kwarg_rule(Parser *p) D(fprintf(stderr, "%*c%s invalid_kwarg[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "!(NAME '=') expression '='")); } + { // '**' expression '=' expression + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_kwarg[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**' expression '=' expression")); + Token * _literal; + Token * a; + expr_ty b; + expr_ty expression_var; + if ( + (a = _PyPegen_expect_token(p, 35)) // token='**' + && + (expression_var = expression_rule(p)) // expression + && + (_literal = _PyPegen_expect_token(p, 22)) // token='=' + && + (b = expression_rule(p)) // expression + ) + { + D(fprintf(stderr, "%*c+ invalid_kwarg[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**' expression '=' expression")); + _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "cannot assign to keyword argument unpacking" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_kwarg[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**' expression '=' expression")); + } _res = NULL; done: p->level--; @@ -19249,8 +20107,7 @@ expression_without_invalid_rule(Parser *p) int _prev_call_invalid = p->call_invalid_rules; p->call_invalid_rules = 0; if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->call_invalid_rules = _prev_call_invalid; @@ -19284,11 +20141,11 @@ expression_without_invalid_rule(Parser *p) if ( (a = disjunction_rule(p)) // disjunction && - (_keyword = _PyPegen_expect_token(p, 639)) // token='if' + (_keyword = _PyPegen_expect_token(p, 642)) // token='if' && (b = disjunction_rule(p)) // disjunction && - (_keyword_1 = _PyPegen_expect_token(p, 642)) // token='else' + (_keyword_1 = _PyPegen_expect_token(p, 645)) // token='else' && (c = expression_rule(p)) // expression ) @@ -19369,8 +20226,7 @@ static void * invalid_legacy_expression_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -19416,12 +20272,12 @@ invalid_legacy_expression_rule(Parser *p) // invalid_expression: // | !(NAME STRING | SOFT_KEYWORD) disjunction expression_without_invalid // | disjunction 'if' disjunction !('else' | ':') +// | 'lambda' lambda_params? ':' &FSTRING_MIDDLE static void * invalid_expression_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -19438,7 +20294,7 @@ invalid_expression_rule(Parser *p) expr_ty a; expr_ty b; if ( - _PyPegen_lookahead(0, _tmp_147_rule, p) + _PyPegen_lookahead(0, _tmp_155_rule, p) && (a = disjunction_rule(p)) // disjunction && @@ -19470,11 +20326,11 @@ invalid_expression_rule(Parser *p) if ( (a = disjunction_rule(p)) // disjunction && - (_keyword = _PyPegen_expect_token(p, 639)) // token='if' + (_keyword = _PyPegen_expect_token(p, 642)) // token='if' && (b = disjunction_rule(p)) // disjunction && - _PyPegen_lookahead(0, _tmp_148_rule, p) + _PyPegen_lookahead(0, _tmp_156_rule, p) ) { D(fprintf(stderr, "%*c+ invalid_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "disjunction 'if' disjunction !('else' | ':')")); @@ -19490,6 +20346,39 @@ invalid_expression_rule(Parser *p) D(fprintf(stderr, "%*c%s invalid_expression[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "disjunction 'if' disjunction !('else' | ':')")); } + { // 'lambda' lambda_params? ':' &FSTRING_MIDDLE + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'lambda' lambda_params? ':' &FSTRING_MIDDLE")); + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + Token * a; + Token * b; + if ( + (a = _PyPegen_expect_token(p, 600)) // token='lambda' + && + (_opt_var = lambda_params_rule(p), !p->error_indicator) // lambda_params? + && + (b = _PyPegen_expect_token(p, 11)) // token=':' + && + _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, FSTRING_MIDDLE) // token=FSTRING_MIDDLE + ) + { + D(fprintf(stderr, "%*c+ invalid_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'lambda' lambda_params? ':' &FSTRING_MIDDLE")); + _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "f-string: lambda expressions are not allowed without parentheses" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_expression[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'lambda' lambda_params? ':' &FSTRING_MIDDLE")); + } _res = NULL; done: p->level--; @@ -19504,8 +20393,7 @@ static void * invalid_named_expression_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -19563,7 +20451,7 @@ invalid_named_expression_rule(Parser *p) && (b = bitwise_or_rule(p)) // bitwise_or && - _PyPegen_lookahead(0, _tmp_149_rule, p) + _PyPegen_lookahead(0, _tmp_157_rule, p) ) { D(fprintf(stderr, "%*c+ invalid_named_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME '=' bitwise_or !('=' | ':=')")); @@ -19589,7 +20477,7 @@ invalid_named_expression_rule(Parser *p) Token * b; expr_ty bitwise_or_var; if ( - _PyPegen_lookahead(0, _tmp_150_rule, p) + _PyPegen_lookahead(0, _tmp_158_rule, p) && (a = bitwise_or_rule(p)) // bitwise_or && @@ -19597,7 +20485,7 @@ invalid_named_expression_rule(Parser *p) && (bitwise_or_var = bitwise_or_rule(p)) // bitwise_or && - _PyPegen_lookahead(0, _tmp_151_rule, p) + _PyPegen_lookahead(0, _tmp_159_rule, p) ) { D(fprintf(stderr, "%*c+ invalid_named_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "!(list | tuple | genexp | 'True' | 'None' | 'False') bitwise_or '=' bitwise_or !('=' | ':=')")); @@ -19631,8 +20519,7 @@ static void * invalid_assignment_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -19678,7 +20565,7 @@ invalid_assignment_rule(Parser *p) D(fprintf(stderr, "%*c> invalid_assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_named_expression ',' star_named_expressions* ':' expression")); Token * _literal; Token * _literal_1; - asdl_seq * _loop0_152_var; + asdl_seq * _loop0_160_var; expr_ty a; expr_ty expression_var; if ( @@ -19686,7 +20573,7 @@ invalid_assignment_rule(Parser *p) && (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (_loop0_152_var = _loop0_152_rule(p)) // star_named_expressions* + (_loop0_160_var = _loop0_160_rule(p)) // star_named_expressions* && (_literal_1 = _PyPegen_expect_token(p, 11)) // token=':' && @@ -19743,10 +20630,10 @@ invalid_assignment_rule(Parser *p) } D(fprintf(stderr, "%*c> invalid_assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "((star_targets '='))* star_expressions '='")); Token * _literal; - asdl_seq * _loop0_153_var; + asdl_seq * _loop0_161_var; expr_ty a; if ( - (_loop0_153_var = _loop0_153_rule(p)) // ((star_targets '='))* + (_loop0_161_var = _loop0_161_rule(p)) // ((star_targets '='))* && (a = star_expressions_rule(p)) // star_expressions && @@ -19773,10 +20660,10 @@ invalid_assignment_rule(Parser *p) } D(fprintf(stderr, "%*c> invalid_assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "((star_targets '='))* yield_expr '='")); Token * _literal; - asdl_seq * _loop0_154_var; + asdl_seq * _loop0_162_var; expr_ty a; if ( - (_loop0_154_var = _loop0_154_rule(p)) // ((star_targets '='))* + (_loop0_162_var = _loop0_162_rule(p)) // ((star_targets '='))* && (a = yield_expr_rule(p)) // yield_expr && @@ -19802,7 +20689,7 @@ invalid_assignment_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions augassign (yield_expr | star_expressions)")); - void *_tmp_155_var; + void *_tmp_163_var; expr_ty a; AugOperator* augassign_var; if ( @@ -19810,7 +20697,7 @@ invalid_assignment_rule(Parser *p) && (augassign_var = augassign_rule(p)) // augassign && - (_tmp_155_var = _tmp_155_rule(p)) // yield_expr | star_expressions + (_tmp_163_var = _tmp_163_rule(p)) // yield_expr | star_expressions ) { D(fprintf(stderr, "%*c+ invalid_assignment[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions augassign (yield_expr | star_expressions)")); @@ -19837,8 +20724,7 @@ static expr_ty invalid_ann_assign_target_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -19925,8 +20811,7 @@ static void * invalid_del_stmt_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -19943,7 +20828,7 @@ invalid_del_stmt_rule(Parser *p) Token * _keyword; expr_ty a; if ( - (_keyword = _PyPegen_expect_token(p, 603)) // token='del' + (_keyword = _PyPegen_expect_token(p, 604)) // token='del' && (a = star_expressions_rule(p)) // star_expressions ) @@ -19972,8 +20857,7 @@ static void * invalid_block_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -20021,8 +20905,7 @@ static void * invalid_comprehension_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -20036,11 +20919,11 @@ invalid_comprehension_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_comprehension[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('[' | '(' | '{') starred_expression for_if_clauses")); - void *_tmp_156_var; + void *_tmp_164_var; expr_ty a; asdl_comprehension_seq* for_if_clauses_var; if ( - (_tmp_156_var = _tmp_156_rule(p)) // '[' | '(' | '{' + (_tmp_164_var = _tmp_164_rule(p)) // '[' | '(' | '{' && (a = starred_expression_rule(p)) // starred_expression && @@ -20067,12 +20950,12 @@ invalid_comprehension_rule(Parser *p) } D(fprintf(stderr, "%*c> invalid_comprehension[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('[' | '{') star_named_expression ',' star_named_expressions for_if_clauses")); Token * _literal; - void *_tmp_157_var; + void *_tmp_165_var; expr_ty a; asdl_expr_seq* b; asdl_comprehension_seq* for_if_clauses_var; if ( - (_tmp_157_var = _tmp_157_rule(p)) // '[' | '{' + (_tmp_165_var = _tmp_165_rule(p)) // '[' | '{' && (a = star_named_expression_rule(p)) // star_named_expression && @@ -20102,12 +20985,12 @@ invalid_comprehension_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_comprehension[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('[' | '{') star_named_expression ',' for_if_clauses")); - void *_tmp_158_var; + void *_tmp_166_var; expr_ty a; Token * b; asdl_comprehension_seq* for_if_clauses_var; if ( - (_tmp_158_var = _tmp_158_rule(p)) // '[' | '{' + (_tmp_166_var = _tmp_166_rule(p)) // '[' | '{' && (a = star_named_expression_rule(p)) // star_named_expression && @@ -20140,8 +21023,7 @@ static void * invalid_dict_comprehension_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -20192,18 +21074,17 @@ invalid_dict_comprehension_rule(Parser *p) } // invalid_parameters: -// | param_no_default* invalid_parameters_helper param_no_default -// | param_no_default* '(' param_no_default+ ','? ')' // | "/" ',' // | (slash_no_default | slash_with_default) param_maybe_default* '/' +// | slash_no_default? param_no_default* invalid_parameters_helper param_no_default +// | param_no_default* '(' param_no_default+ ','? ')' // | [(slash_no_default | slash_with_default)] param_maybe_default* '*' (',' | param_no_default) param_maybe_default* '/' // | param_maybe_default+ '/' '*' static void * invalid_parameters_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -20211,25 +21092,22 @@ invalid_parameters_rule(Parser *p) } void * _res = NULL; int _mark = p->mark; - { // param_no_default* invalid_parameters_helper param_no_default + { // "/" ',' if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> invalid_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default* invalid_parameters_helper param_no_default")); - asdl_seq * _loop0_159_var; - arg_ty a; - void *invalid_parameters_helper_var; + D(fprintf(stderr, "%*c> invalid_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "\"/\" ','")); + Token * _literal; + Token * a; if ( - (_loop0_159_var = _loop0_159_rule(p)) // param_no_default* - && - (invalid_parameters_helper_var = invalid_parameters_helper_rule(p)) // invalid_parameters_helper + (a = _PyPegen_expect_token(p, 17)) // token='/' && - (a = param_no_default_rule(p)) // param_no_default + (_literal = _PyPegen_expect_token(p, 12)) // token=',' ) { - D(fprintf(stderr, "%*c+ invalid_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_no_default* invalid_parameters_helper param_no_default")); - _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "non-default argument follows default argument" ); + D(fprintf(stderr, "%*c+ invalid_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "\"/\" ','")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "at least one argument must precede /" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; p->level--; @@ -20239,34 +21117,27 @@ invalid_parameters_rule(Parser *p) } p->mark = _mark; D(fprintf(stderr, "%*c%s invalid_parameters[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default* invalid_parameters_helper param_no_default")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "\"/\" ','")); } - { // param_no_default* '(' param_no_default+ ','? ')' + { // (slash_no_default | slash_with_default) param_maybe_default* '/' if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> invalid_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default* '(' param_no_default+ ','? ')'")); - asdl_seq * _loop0_160_var; - asdl_seq * _loop1_161_var; - void *_opt_var; - UNUSED(_opt_var); // Silence compiler warnings + D(fprintf(stderr, "%*c> invalid_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(slash_no_default | slash_with_default) param_maybe_default* '/'")); + asdl_seq * _loop0_168_var; + void *_tmp_167_var; Token * a; - Token * b; if ( - (_loop0_160_var = _loop0_160_rule(p)) // param_no_default* + (_tmp_167_var = _tmp_167_rule(p)) // slash_no_default | slash_with_default && - (a = _PyPegen_expect_token(p, 7)) // token='(' + (_loop0_168_var = _loop0_168_rule(p)) // param_maybe_default* && - (_loop1_161_var = _loop1_161_rule(p)) // param_no_default+ - && - (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? - && - (b = _PyPegen_expect_token(p, 8)) // token=')' + (a = _PyPegen_expect_token(p, 17)) // token='/' ) { - D(fprintf(stderr, "%*c+ invalid_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_no_default* '(' param_no_default+ ','? ')'")); - _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "Function parameters cannot be parenthesized" ); + D(fprintf(stderr, "%*c+ invalid_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(slash_no_default | slash_with_default) param_maybe_default* '/'")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "/ may appear only once" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; p->level--; @@ -20276,24 +21147,31 @@ invalid_parameters_rule(Parser *p) } p->mark = _mark; D(fprintf(stderr, "%*c%s invalid_parameters[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default* '(' param_no_default+ ','? ')'")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(slash_no_default | slash_with_default) param_maybe_default* '/'")); } - { // "/" ',' + { // slash_no_default? param_no_default* invalid_parameters_helper param_no_default if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> invalid_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "\"/\" ','")); - Token * _literal; - Token * a; + D(fprintf(stderr, "%*c> invalid_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_no_default? param_no_default* invalid_parameters_helper param_no_default")); + asdl_seq * _loop0_169_var; + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + arg_ty a; + void *invalid_parameters_helper_var; if ( - (a = _PyPegen_expect_token(p, 17)) // token='/' + (_opt_var = slash_no_default_rule(p), !p->error_indicator) // slash_no_default? && - (_literal = _PyPegen_expect_token(p, 12)) // token=',' + (_loop0_169_var = _loop0_169_rule(p)) // param_no_default* + && + (invalid_parameters_helper_var = invalid_parameters_helper_rule(p)) // invalid_parameters_helper + && + (a = param_no_default_rule(p)) // param_no_default ) { - D(fprintf(stderr, "%*c+ invalid_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "\"/\" ','")); - _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "at least one argument must precede /" ); + D(fprintf(stderr, "%*c+ invalid_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_no_default? param_no_default* invalid_parameters_helper param_no_default")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "parameter without a default follows parameter with a default" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; p->level--; @@ -20303,27 +21181,34 @@ invalid_parameters_rule(Parser *p) } p->mark = _mark; D(fprintf(stderr, "%*c%s invalid_parameters[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "\"/\" ','")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "slash_no_default? param_no_default* invalid_parameters_helper param_no_default")); } - { // (slash_no_default | slash_with_default) param_maybe_default* '/' + { // param_no_default* '(' param_no_default+ ','? ')' if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> invalid_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(slash_no_default | slash_with_default) param_maybe_default* '/'")); - asdl_seq * _loop0_163_var; - void *_tmp_162_var; + D(fprintf(stderr, "%*c> invalid_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default* '(' param_no_default+ ','? ')'")); + asdl_seq * _loop0_170_var; + asdl_seq * _loop1_171_var; + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings Token * a; + Token * b; if ( - (_tmp_162_var = _tmp_162_rule(p)) // slash_no_default | slash_with_default + (_loop0_170_var = _loop0_170_rule(p)) // param_no_default* + && + (a = _PyPegen_expect_token(p, 7)) // token='(' && - (_loop0_163_var = _loop0_163_rule(p)) // param_maybe_default* + (_loop1_171_var = _loop1_171_rule(p)) // param_no_default+ && - (a = _PyPegen_expect_token(p, 17)) // token='/' + (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? + && + (b = _PyPegen_expect_token(p, 8)) // token=')' ) { - D(fprintf(stderr, "%*c+ invalid_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(slash_no_default | slash_with_default) param_maybe_default* '/'")); - _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "/ may appear only once" ); + D(fprintf(stderr, "%*c+ invalid_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_no_default* '(' param_no_default+ ','? ')'")); + _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "Function parameters cannot be parenthesized" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; p->level--; @@ -20333,7 +21218,7 @@ invalid_parameters_rule(Parser *p) } p->mark = _mark; D(fprintf(stderr, "%*c%s invalid_parameters[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(slash_no_default | slash_with_default) param_maybe_default* '/'")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default* '(' param_no_default+ ','? ')'")); } { // [(slash_no_default | slash_with_default)] param_maybe_default* '*' (',' | param_no_default) param_maybe_default* '/' if (p->error_indicator) { @@ -20342,22 +21227,22 @@ invalid_parameters_rule(Parser *p) } D(fprintf(stderr, "%*c> invalid_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "[(slash_no_default | slash_with_default)] param_maybe_default* '*' (',' | param_no_default) param_maybe_default* '/'")); Token * _literal; - asdl_seq * _loop0_165_var; - asdl_seq * _loop0_167_var; + asdl_seq * _loop0_173_var; + asdl_seq * _loop0_175_var; void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings - void *_tmp_166_var; + void *_tmp_174_var; Token * a; if ( - (_opt_var = _tmp_164_rule(p), !p->error_indicator) // [(slash_no_default | slash_with_default)] + (_opt_var = _tmp_172_rule(p), !p->error_indicator) // [(slash_no_default | slash_with_default)] && - (_loop0_165_var = _loop0_165_rule(p)) // param_maybe_default* + (_loop0_173_var = _loop0_173_rule(p)) // param_maybe_default* && (_literal = _PyPegen_expect_token(p, 16)) // token='*' && - (_tmp_166_var = _tmp_166_rule(p)) // ',' | param_no_default + (_tmp_174_var = _tmp_174_rule(p)) // ',' | param_no_default && - (_loop0_167_var = _loop0_167_rule(p)) // param_maybe_default* + (_loop0_175_var = _loop0_175_rule(p)) // param_maybe_default* && (a = _PyPegen_expect_token(p, 17)) // token='/' ) @@ -20382,10 +21267,10 @@ invalid_parameters_rule(Parser *p) } D(fprintf(stderr, "%*c> invalid_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default+ '/' '*'")); Token * _literal; - asdl_seq * _loop1_168_var; + asdl_seq * _loop1_176_var; Token * a; if ( - (_loop1_168_var = _loop1_168_rule(p)) // param_maybe_default+ + (_loop1_176_var = _loop1_176_rule(p)) // param_maybe_default+ && (_literal = _PyPegen_expect_token(p, 17)) // token='/' && @@ -20416,8 +21301,7 @@ static void * invalid_default_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -20435,7 +21319,7 @@ invalid_default_rule(Parser *p) if ( (a = _PyPegen_expect_token(p, 22)) // token='=' && - _PyPegen_lookahead(1, _tmp_169_rule, p) + _PyPegen_lookahead(1, _tmp_177_rule, p) ) { D(fprintf(stderr, "%*c+ invalid_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'=' &(')' | ',')")); @@ -20466,8 +21350,7 @@ static void * invalid_star_etc_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -20481,12 +21364,12 @@ invalid_star_etc_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' (')' | ',' (')' | '**'))")); - void *_tmp_170_var; + void *_tmp_178_var; Token * a; if ( (a = _PyPegen_expect_token(p, 16)) // token='*' && - (_tmp_170_var = _tmp_170_rule(p)) // ')' | ',' (')' | '**') + (_tmp_178_var = _tmp_178_rule(p)) // ')' | ',' (')' | '**') ) { D(fprintf(stderr, "%*c+ invalid_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' (')' | ',' (')' | '**'))")); @@ -20569,20 +21452,20 @@ invalid_star_etc_rule(Parser *p) } D(fprintf(stderr, "%*c> invalid_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' (param_no_default | ',') param_maybe_default* '*' (param_no_default | ',')")); Token * _literal; - asdl_seq * _loop0_172_var; - void *_tmp_171_var; - void *_tmp_173_var; + asdl_seq * _loop0_180_var; + void *_tmp_179_var; + void *_tmp_181_var; Token * a; if ( (_literal = _PyPegen_expect_token(p, 16)) // token='*' && - (_tmp_171_var = _tmp_171_rule(p)) // param_no_default | ',' + (_tmp_179_var = _tmp_179_rule(p)) // param_no_default | ',' && - (_loop0_172_var = _loop0_172_rule(p)) // param_maybe_default* + (_loop0_180_var = _loop0_180_rule(p)) // param_maybe_default* && (a = _PyPegen_expect_token(p, 16)) // token='*' && - (_tmp_173_var = _tmp_173_rule(p)) // param_no_default | ',' + (_tmp_181_var = _tmp_181_rule(p)) // param_no_default | ',' ) { D(fprintf(stderr, "%*c+ invalid_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' (param_no_default | ',') param_maybe_default* '*' (param_no_default | ',')")); @@ -20609,8 +21492,7 @@ static void * invalid_kwds_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -20698,7 +21580,7 @@ invalid_kwds_rule(Parser *p) && (_literal_1 = _PyPegen_expect_token(p, 12)) // token=',' && - (a = (Token*)_tmp_174_rule(p)) // '*' | '**' | '/' + (a = (Token*)_tmp_182_rule(p)) // '*' | '**' | '/' ) { D(fprintf(stderr, "%*c+ invalid_kwds[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**' param ',' ('*' | '**' | '/')")); @@ -20725,8 +21607,7 @@ static void * invalid_parameters_helper_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -20764,13 +21645,13 @@ invalid_parameters_helper_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_parameters_helper[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default+")); - asdl_seq * _loop1_175_var; + asdl_seq * _loop1_183_var; if ( - (_loop1_175_var = _loop1_175_rule(p)) // param_with_default+ + (_loop1_183_var = _loop1_183_rule(p)) // param_with_default+ ) { D(fprintf(stderr, "%*c+ invalid_parameters_helper[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_with_default+")); - _res = _loop1_175_var; + _res = _loop1_183_var; goto done; } p->mark = _mark; @@ -20784,18 +21665,17 @@ invalid_parameters_helper_rule(Parser *p) } // invalid_lambda_parameters: -// | lambda_param_no_default* invalid_lambda_parameters_helper lambda_param_no_default -// | lambda_param_no_default* '(' ','.lambda_param+ ','? ')' // | "/" ',' // | (lambda_slash_no_default | lambda_slash_with_default) lambda_param_maybe_default* '/' +// | lambda_slash_no_default? lambda_param_no_default* invalid_lambda_parameters_helper lambda_param_no_default +// | lambda_param_no_default* '(' ','.lambda_param+ ','? ')' // | [(lambda_slash_no_default | lambda_slash_with_default)] lambda_param_maybe_default* '*' (',' | lambda_param_no_default) lambda_param_maybe_default* '/' // | lambda_param_maybe_default+ '/' '*' static void * invalid_lambda_parameters_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -20803,25 +21683,22 @@ invalid_lambda_parameters_rule(Parser *p) } void * _res = NULL; int _mark = p->mark; - { // lambda_param_no_default* invalid_lambda_parameters_helper lambda_param_no_default + { // "/" ',' if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> invalid_lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default* invalid_lambda_parameters_helper lambda_param_no_default")); - asdl_seq * _loop0_176_var; - arg_ty a; - void *invalid_lambda_parameters_helper_var; + D(fprintf(stderr, "%*c> invalid_lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "\"/\" ','")); + Token * _literal; + Token * a; if ( - (_loop0_176_var = _loop0_176_rule(p)) // lambda_param_no_default* - && - (invalid_lambda_parameters_helper_var = invalid_lambda_parameters_helper_rule(p)) // invalid_lambda_parameters_helper + (a = _PyPegen_expect_token(p, 17)) // token='/' && - (a = lambda_param_no_default_rule(p)) // lambda_param_no_default + (_literal = _PyPegen_expect_token(p, 12)) // token=',' ) { - D(fprintf(stderr, "%*c+ invalid_lambda_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default* invalid_lambda_parameters_helper lambda_param_no_default")); - _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "non-default argument follows default argument" ); + D(fprintf(stderr, "%*c+ invalid_lambda_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "\"/\" ','")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "at least one argument must precede /" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; p->level--; @@ -20831,34 +21708,27 @@ invalid_lambda_parameters_rule(Parser *p) } p->mark = _mark; D(fprintf(stderr, "%*c%s invalid_lambda_parameters[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default* invalid_lambda_parameters_helper lambda_param_no_default")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "\"/\" ','")); } - { // lambda_param_no_default* '(' ','.lambda_param+ ','? ')' + { // (lambda_slash_no_default | lambda_slash_with_default) lambda_param_maybe_default* '/' if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> invalid_lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default* '(' ','.lambda_param+ ','? ')'")); - asdl_seq * _gather_178_var; - asdl_seq * _loop0_177_var; - void *_opt_var; - UNUSED(_opt_var); // Silence compiler warnings + D(fprintf(stderr, "%*c> invalid_lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(lambda_slash_no_default | lambda_slash_with_default) lambda_param_maybe_default* '/'")); + asdl_seq * _loop0_185_var; + void *_tmp_184_var; Token * a; - Token * b; if ( - (_loop0_177_var = _loop0_177_rule(p)) // lambda_param_no_default* - && - (a = _PyPegen_expect_token(p, 7)) // token='(' - && - (_gather_178_var = _gather_178_rule(p)) // ','.lambda_param+ + (_tmp_184_var = _tmp_184_rule(p)) // lambda_slash_no_default | lambda_slash_with_default && - (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? + (_loop0_185_var = _loop0_185_rule(p)) // lambda_param_maybe_default* && - (b = _PyPegen_expect_token(p, 8)) // token=')' + (a = _PyPegen_expect_token(p, 17)) // token='/' ) { - D(fprintf(stderr, "%*c+ invalid_lambda_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default* '(' ','.lambda_param+ ','? ')'")); - _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "Lambda expression parameters cannot be parenthesized" ); + D(fprintf(stderr, "%*c+ invalid_lambda_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(lambda_slash_no_default | lambda_slash_with_default) lambda_param_maybe_default* '/'")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "/ may appear only once" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; p->level--; @@ -20868,24 +21738,31 @@ invalid_lambda_parameters_rule(Parser *p) } p->mark = _mark; D(fprintf(stderr, "%*c%s invalid_lambda_parameters[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default* '(' ','.lambda_param+ ','? ')'")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(lambda_slash_no_default | lambda_slash_with_default) lambda_param_maybe_default* '/'")); } - { // "/" ',' + { // lambda_slash_no_default? lambda_param_no_default* invalid_lambda_parameters_helper lambda_param_no_default if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> invalid_lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "\"/\" ','")); - Token * _literal; - Token * a; + D(fprintf(stderr, "%*c> invalid_lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default? lambda_param_no_default* invalid_lambda_parameters_helper lambda_param_no_default")); + asdl_seq * _loop0_186_var; + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + arg_ty a; + void *invalid_lambda_parameters_helper_var; if ( - (a = _PyPegen_expect_token(p, 17)) // token='/' + (_opt_var = lambda_slash_no_default_rule(p), !p->error_indicator) // lambda_slash_no_default? && - (_literal = _PyPegen_expect_token(p, 12)) // token=',' + (_loop0_186_var = _loop0_186_rule(p)) // lambda_param_no_default* + && + (invalid_lambda_parameters_helper_var = invalid_lambda_parameters_helper_rule(p)) // invalid_lambda_parameters_helper + && + (a = lambda_param_no_default_rule(p)) // lambda_param_no_default ) { - D(fprintf(stderr, "%*c+ invalid_lambda_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "\"/\" ','")); - _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "at least one argument must precede /" ); + D(fprintf(stderr, "%*c+ invalid_lambda_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default? lambda_param_no_default* invalid_lambda_parameters_helper lambda_param_no_default")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "parameter without a default follows parameter with a default" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; p->level--; @@ -20895,27 +21772,34 @@ invalid_lambda_parameters_rule(Parser *p) } p->mark = _mark; D(fprintf(stderr, "%*c%s invalid_lambda_parameters[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "\"/\" ','")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_slash_no_default? lambda_param_no_default* invalid_lambda_parameters_helper lambda_param_no_default")); } - { // (lambda_slash_no_default | lambda_slash_with_default) lambda_param_maybe_default* '/' + { // lambda_param_no_default* '(' ','.lambda_param+ ','? ')' if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> invalid_lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(lambda_slash_no_default | lambda_slash_with_default) lambda_param_maybe_default* '/'")); - asdl_seq * _loop0_181_var; - void *_tmp_180_var; + D(fprintf(stderr, "%*c> invalid_lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default* '(' ','.lambda_param+ ','? ')'")); + asdl_seq * _gather_188_var; + asdl_seq * _loop0_187_var; + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings Token * a; + Token * b; if ( - (_tmp_180_var = _tmp_180_rule(p)) // lambda_slash_no_default | lambda_slash_with_default + (_loop0_187_var = _loop0_187_rule(p)) // lambda_param_no_default* && - (_loop0_181_var = _loop0_181_rule(p)) // lambda_param_maybe_default* + (a = _PyPegen_expect_token(p, 7)) // token='(' && - (a = _PyPegen_expect_token(p, 17)) // token='/' + (_gather_188_var = _gather_188_rule(p)) // ','.lambda_param+ + && + (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? + && + (b = _PyPegen_expect_token(p, 8)) // token=')' ) { - D(fprintf(stderr, "%*c+ invalid_lambda_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(lambda_slash_no_default | lambda_slash_with_default) lambda_param_maybe_default* '/'")); - _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "/ may appear only once" ); + D(fprintf(stderr, "%*c+ invalid_lambda_parameters[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default* '(' ','.lambda_param+ ','? ')'")); + _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "Lambda expression parameters cannot be parenthesized" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; p->level--; @@ -20925,7 +21809,7 @@ invalid_lambda_parameters_rule(Parser *p) } p->mark = _mark; D(fprintf(stderr, "%*c%s invalid_lambda_parameters[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(lambda_slash_no_default | lambda_slash_with_default) lambda_param_maybe_default* '/'")); + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default* '(' ','.lambda_param+ ','? ')'")); } { // [(lambda_slash_no_default | lambda_slash_with_default)] lambda_param_maybe_default* '*' (',' | lambda_param_no_default) lambda_param_maybe_default* '/' if (p->error_indicator) { @@ -20934,22 +21818,22 @@ invalid_lambda_parameters_rule(Parser *p) } D(fprintf(stderr, "%*c> invalid_lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "[(lambda_slash_no_default | lambda_slash_with_default)] lambda_param_maybe_default* '*' (',' | lambda_param_no_default) lambda_param_maybe_default* '/'")); Token * _literal; - asdl_seq * _loop0_183_var; - asdl_seq * _loop0_185_var; + asdl_seq * _loop0_191_var; + asdl_seq * _loop0_193_var; void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings - void *_tmp_184_var; + void *_tmp_192_var; Token * a; if ( - (_opt_var = _tmp_182_rule(p), !p->error_indicator) // [(lambda_slash_no_default | lambda_slash_with_default)] + (_opt_var = _tmp_190_rule(p), !p->error_indicator) // [(lambda_slash_no_default | lambda_slash_with_default)] && - (_loop0_183_var = _loop0_183_rule(p)) // lambda_param_maybe_default* + (_loop0_191_var = _loop0_191_rule(p)) // lambda_param_maybe_default* && (_literal = _PyPegen_expect_token(p, 16)) // token='*' && - (_tmp_184_var = _tmp_184_rule(p)) // ',' | lambda_param_no_default + (_tmp_192_var = _tmp_192_rule(p)) // ',' | lambda_param_no_default && - (_loop0_185_var = _loop0_185_rule(p)) // lambda_param_maybe_default* + (_loop0_193_var = _loop0_193_rule(p)) // lambda_param_maybe_default* && (a = _PyPegen_expect_token(p, 17)) // token='/' ) @@ -20974,10 +21858,10 @@ invalid_lambda_parameters_rule(Parser *p) } D(fprintf(stderr, "%*c> invalid_lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default+ '/' '*'")); Token * _literal; - asdl_seq * _loop1_186_var; + asdl_seq * _loop1_194_var; Token * a; if ( - (_loop1_186_var = _loop1_186_rule(p)) // lambda_param_maybe_default+ + (_loop1_194_var = _loop1_194_rule(p)) // lambda_param_maybe_default+ && (_literal = _PyPegen_expect_token(p, 17)) // token='/' && @@ -21010,8 +21894,7 @@ static void * invalid_lambda_parameters_helper_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -21049,13 +21932,13 @@ invalid_lambda_parameters_helper_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_lambda_parameters_helper[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default+")); - asdl_seq * _loop1_187_var; + asdl_seq * _loop1_195_var; if ( - (_loop1_187_var = _loop1_187_rule(p)) // lambda_param_with_default+ + (_loop1_195_var = _loop1_195_rule(p)) // lambda_param_with_default+ ) { D(fprintf(stderr, "%*c+ invalid_lambda_parameters_helper[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default+")); - _res = _loop1_187_var; + _res = _loop1_195_var; goto done; } p->mark = _mark; @@ -21076,8 +21959,7 @@ static void * invalid_lambda_star_etc_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -21092,11 +21974,11 @@ invalid_lambda_star_etc_rule(Parser *p) } D(fprintf(stderr, "%*c> invalid_lambda_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' (':' | ',' (':' | '**'))")); Token * _literal; - void *_tmp_188_var; + void *_tmp_196_var; if ( (_literal = _PyPegen_expect_token(p, 16)) // token='*' && - (_tmp_188_var = _tmp_188_rule(p)) // ':' | ',' (':' | '**') + (_tmp_196_var = _tmp_196_rule(p)) // ':' | ',' (':' | '**') ) { D(fprintf(stderr, "%*c+ invalid_lambda_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' (':' | ',' (':' | '**'))")); @@ -21149,20 +22031,20 @@ invalid_lambda_star_etc_rule(Parser *p) } D(fprintf(stderr, "%*c> invalid_lambda_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' (lambda_param_no_default | ',') lambda_param_maybe_default* '*' (lambda_param_no_default | ',')")); Token * _literal; - asdl_seq * _loop0_190_var; - void *_tmp_189_var; - void *_tmp_191_var; + asdl_seq * _loop0_198_var; + void *_tmp_197_var; + void *_tmp_199_var; Token * a; if ( (_literal = _PyPegen_expect_token(p, 16)) // token='*' && - (_tmp_189_var = _tmp_189_rule(p)) // lambda_param_no_default | ',' + (_tmp_197_var = _tmp_197_rule(p)) // lambda_param_no_default | ',' && - (_loop0_190_var = _loop0_190_rule(p)) // lambda_param_maybe_default* + (_loop0_198_var = _loop0_198_rule(p)) // lambda_param_maybe_default* && (a = _PyPegen_expect_token(p, 16)) // token='*' && - (_tmp_191_var = _tmp_191_rule(p)) // lambda_param_no_default | ',' + (_tmp_199_var = _tmp_199_rule(p)) // lambda_param_no_default | ',' ) { D(fprintf(stderr, "%*c+ invalid_lambda_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' (lambda_param_no_default | ',') lambda_param_maybe_default* '*' (lambda_param_no_default | ',')")); @@ -21192,8 +22074,7 @@ static void * invalid_lambda_kwds_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -21281,7 +22162,7 @@ invalid_lambda_kwds_rule(Parser *p) && (_literal_1 = _PyPegen_expect_token(p, 12)) // token=',' && - (a = (Token*)_tmp_192_rule(p)) // '*' | '**' | '/' + (a = (Token*)_tmp_200_rule(p)) // '*' | '**' | '/' ) { D(fprintf(stderr, "%*c+ invalid_lambda_kwds[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**' lambda_param ',' ('*' | '**' | '/')")); @@ -21308,8 +22189,7 @@ static void * invalid_double_type_comments_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -21364,8 +22244,7 @@ static void * invalid_with_item_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -21385,11 +22264,11 @@ invalid_with_item_rule(Parser *p) if ( (expression_var = expression_rule(p)) // expression && - (_keyword = _PyPegen_expect_token(p, 637)) // token='as' + (_keyword = _PyPegen_expect_token(p, 640)) // token='as' && (a = expression_rule(p)) // expression && - _PyPegen_lookahead(1, _tmp_193_rule, p) + _PyPegen_lookahead(1, _tmp_201_rule, p) ) { D(fprintf(stderr, "%*c+ invalid_with_item[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression 'as' expression &(',' | ')' | ':')")); @@ -21416,8 +22295,7 @@ static void * invalid_for_target_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -21438,7 +22316,7 @@ invalid_for_target_rule(Parser *p) if ( (_opt_var = _PyPegen_expect_token(p, ASYNC), !p->error_indicator) // ASYNC? && - (_keyword = _PyPegen_expect_token(p, 647)) // token='for' + (_keyword = _PyPegen_expect_token(p, 650)) // token='for' && (a = star_expressions_rule(p)) // star_expressions ) @@ -21467,8 +22345,7 @@ static void * invalid_group_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -21545,13 +22422,64 @@ invalid_group_rule(Parser *p) return _res; } +// invalid_import: 'import' ','.dotted_name+ 'from' dotted_name +static void * +invalid_import_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // 'import' ','.dotted_name+ 'from' dotted_name + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> invalid_import[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'import' ','.dotted_name+ 'from' dotted_name")); + asdl_seq * _gather_202_var; + Token * _keyword; + Token * a; + expr_ty dotted_name_var; + if ( + (a = _PyPegen_expect_token(p, 607)) // token='import' + && + (_gather_202_var = _gather_202_rule(p)) // ','.dotted_name+ + && + (_keyword = _PyPegen_expect_token(p, 608)) // token='from' + && + (dotted_name_var = dotted_name_rule(p)) // dotted_name + ) + { + D(fprintf(stderr, "%*c+ invalid_import[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'import' ','.dotted_name+ 'from' dotted_name")); + _res = RAISE_SYNTAX_ERROR_STARTING_FROM ( a , "Did you mean to use 'from ... import ...' instead?" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_import[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'import' ','.dotted_name+ 'from' dotted_name")); + } + _res = NULL; + done: + p->level--; + return _res; +} + // invalid_import_from_targets: import_from_as_names ',' NEWLINE static void * invalid_import_from_targets_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -21602,8 +22530,7 @@ static void * invalid_with_stmt_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -21617,7 +22544,7 @@ invalid_with_stmt_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_with_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC? 'with' ','.(expression ['as' star_target])+ NEWLINE")); - asdl_seq * _gather_194_var; + asdl_seq * _gather_204_var; Token * _keyword; void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings @@ -21625,9 +22552,9 @@ invalid_with_stmt_rule(Parser *p) if ( (_opt_var = _PyPegen_expect_token(p, ASYNC), !p->error_indicator) // ASYNC? && - (_keyword = _PyPegen_expect_token(p, 612)) // token='with' + (_keyword = _PyPegen_expect_token(p, 615)) // token='with' && - (_gather_194_var = _gather_194_rule(p)) // ','.(expression ['as' star_target])+ + (_gather_204_var = _gather_204_rule(p)) // ','.(expression ['as' star_target])+ && (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' ) @@ -21651,7 +22578,7 @@ invalid_with_stmt_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_with_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC? 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' NEWLINE")); - asdl_seq * _gather_196_var; + asdl_seq * _gather_206_var; Token * _keyword; Token * _literal; Token * _literal_1; @@ -21663,11 +22590,11 @@ invalid_with_stmt_rule(Parser *p) if ( (_opt_var = _PyPegen_expect_token(p, ASYNC), !p->error_indicator) // ASYNC? && - (_keyword = _PyPegen_expect_token(p, 612)) // token='with' + (_keyword = _PyPegen_expect_token(p, 615)) // token='with' && (_literal = _PyPegen_expect_token(p, 7)) // token='(' && - (_gather_196_var = _gather_196_rule(p)) // ','.(expressions ['as' star_target])+ + (_gather_206_var = _gather_206_rule(p)) // ','.(expressions ['as' star_target])+ && (_opt_var_1 = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? && @@ -21702,8 +22629,7 @@ static void * invalid_with_stmt_indent_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -21717,7 +22643,7 @@ invalid_with_stmt_indent_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_with_stmt_indent[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC? 'with' ','.(expression ['as' star_target])+ ':' NEWLINE !INDENT")); - asdl_seq * _gather_198_var; + asdl_seq * _gather_208_var; Token * _literal; void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings @@ -21726,9 +22652,9 @@ invalid_with_stmt_indent_rule(Parser *p) if ( (_opt_var = _PyPegen_expect_token(p, ASYNC), !p->error_indicator) // ASYNC? && - (a = _PyPegen_expect_token(p, 612)) // token='with' + (a = _PyPegen_expect_token(p, 615)) // token='with' && - (_gather_198_var = _gather_198_rule(p)) // ','.(expression ['as' star_target])+ + (_gather_208_var = _gather_208_rule(p)) // ','.(expression ['as' star_target])+ && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -21756,7 +22682,7 @@ invalid_with_stmt_indent_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_with_stmt_indent[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC? 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' ':' NEWLINE !INDENT")); - asdl_seq * _gather_200_var; + asdl_seq * _gather_210_var; Token * _literal; Token * _literal_1; Token * _literal_2; @@ -21769,11 +22695,11 @@ invalid_with_stmt_indent_rule(Parser *p) if ( (_opt_var = _PyPegen_expect_token(p, ASYNC), !p->error_indicator) // ASYNC? && - (a = _PyPegen_expect_token(p, 612)) // token='with' + (a = _PyPegen_expect_token(p, 615)) // token='with' && (_literal = _PyPegen_expect_token(p, 7)) // token='(' && - (_gather_200_var = _gather_200_rule(p)) // ','.(expressions ['as' star_target])+ + (_gather_210_var = _gather_210_rule(p)) // ','.(expressions ['as' star_target])+ && (_opt_var_1 = _PyPegen_expect_token(p, 12), !p->error_indicator) // ','? && @@ -21814,8 +22740,7 @@ static void * invalid_try_stmt_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -21833,7 +22758,7 @@ invalid_try_stmt_rule(Parser *p) Token * a; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 621)) // token='try' + (a = _PyPegen_expect_token(p, 624)) // token='try' && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -21865,13 +22790,13 @@ invalid_try_stmt_rule(Parser *p) Token * _literal; asdl_stmt_seq* block_var; if ( - (_keyword = _PyPegen_expect_token(p, 621)) // token='try' + (_keyword = _PyPegen_expect_token(p, 624)) // token='try' && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && (block_var = block_rule(p)) // block && - _PyPegen_lookahead(0, _tmp_202_rule, p) + _PyPegen_lookahead(0, _tmp_212_rule, p) ) { D(fprintf(stderr, "%*c+ invalid_try_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'try' ':' block !('except' | 'finally')")); @@ -21896,29 +22821,29 @@ invalid_try_stmt_rule(Parser *p) Token * _keyword; Token * _literal; Token * _literal_1; - asdl_seq * _loop0_203_var; - asdl_seq * _loop1_204_var; + asdl_seq * _loop0_213_var; + asdl_seq * _loop1_214_var; void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings Token * a; Token * b; expr_ty expression_var; if ( - (_keyword = _PyPegen_expect_token(p, 621)) // token='try' + (_keyword = _PyPegen_expect_token(p, 624)) // token='try' && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && - (_loop0_203_var = _loop0_203_rule(p)) // block* + (_loop0_213_var = _loop0_213_rule(p)) // block* && - (_loop1_204_var = _loop1_204_rule(p)) // except_block+ + (_loop1_214_var = _loop1_214_rule(p)) // except_block+ && - (a = _PyPegen_expect_token(p, 634)) // token='except' + (a = _PyPegen_expect_token(p, 637)) // token='except' && (b = _PyPegen_expect_token(p, 16)) // token='*' && (expression_var = expression_rule(p)) // expression && - (_opt_var = _tmp_205_rule(p), !p->error_indicator) // ['as' NAME] + (_opt_var = _tmp_215_rule(p), !p->error_indicator) // ['as' NAME] && (_literal_1 = _PyPegen_expect_token(p, 11)) // token=':' ) @@ -21945,23 +22870,23 @@ invalid_try_stmt_rule(Parser *p) Token * _keyword; Token * _literal; Token * _literal_1; - asdl_seq * _loop0_206_var; - asdl_seq * _loop1_207_var; + asdl_seq * _loop0_216_var; + asdl_seq * _loop1_217_var; void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings Token * a; if ( - (_keyword = _PyPegen_expect_token(p, 621)) // token='try' + (_keyword = _PyPegen_expect_token(p, 624)) // token='try' && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && - (_loop0_206_var = _loop0_206_rule(p)) // block* + (_loop0_216_var = _loop0_216_rule(p)) // block* && - (_loop1_207_var = _loop1_207_rule(p)) // except_star_block+ + (_loop1_217_var = _loop1_217_rule(p)) // except_star_block+ && - (a = _PyPegen_expect_token(p, 634)) // token='except' + (a = _PyPegen_expect_token(p, 637)) // token='except' && - (_opt_var = _tmp_208_rule(p), !p->error_indicator) // [expression ['as' NAME]] + (_opt_var = _tmp_218_rule(p), !p->error_indicator) // [expression ['as' NAME]] && (_literal_1 = _PyPegen_expect_token(p, 11)) // token=':' ) @@ -21994,8 +22919,7 @@ static void * invalid_except_stmt_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -22019,7 +22943,7 @@ invalid_except_stmt_rule(Parser *p) expr_ty a; expr_ty expressions_var; if ( - (_keyword = _PyPegen_expect_token(p, 634)) // token='except' + (_keyword = _PyPegen_expect_token(p, 637)) // token='except' && (_opt_var = _PyPegen_expect_token(p, 16), !p->error_indicator) // '*'? && @@ -22029,7 +22953,7 @@ invalid_except_stmt_rule(Parser *p) && (expressions_var = expressions_rule(p)) // expressions && - (_opt_var_1 = _tmp_209_rule(p), !p->error_indicator) // ['as' NAME] + (_opt_var_1 = _tmp_219_rule(p), !p->error_indicator) // ['as' NAME] && (_literal_1 = _PyPegen_expect_token(p, 11)) // token=':' ) @@ -22061,13 +22985,13 @@ invalid_except_stmt_rule(Parser *p) expr_ty expression_var; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 634)) // token='except' + (a = _PyPegen_expect_token(p, 637)) // token='except' && (_opt_var = _PyPegen_expect_token(p, 16), !p->error_indicator) // '*'? && (expression_var = expression_rule(p)) // expression && - (_opt_var_1 = _tmp_210_rule(p), !p->error_indicator) // ['as' NAME] + (_opt_var_1 = _tmp_220_rule(p), !p->error_indicator) // ['as' NAME] && (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' ) @@ -22094,7 +23018,7 @@ invalid_except_stmt_rule(Parser *p) Token * a; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 634)) // token='except' + (a = _PyPegen_expect_token(p, 637)) // token='except' && (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' ) @@ -22119,14 +23043,14 @@ invalid_except_stmt_rule(Parser *p) } D(fprintf(stderr, "%*c> invalid_except_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'except' '*' (NEWLINE | ':')")); Token * _literal; - void *_tmp_211_var; + void *_tmp_221_var; Token * a; if ( - (a = _PyPegen_expect_token(p, 634)) // token='except' + (a = _PyPegen_expect_token(p, 637)) // token='except' && (_literal = _PyPegen_expect_token(p, 16)) // token='*' && - (_tmp_211_var = _tmp_211_rule(p)) // NEWLINE | ':' + (_tmp_221_var = _tmp_221_rule(p)) // NEWLINE | ':' ) { D(fprintf(stderr, "%*c+ invalid_except_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'except' '*' (NEWLINE | ':')")); @@ -22153,8 +23077,7 @@ static void * invalid_finally_stmt_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -22172,7 +23095,7 @@ invalid_finally_stmt_rule(Parser *p) Token * a; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 630)) // token='finally' + (a = _PyPegen_expect_token(p, 633)) // token='finally' && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -22207,8 +23130,7 @@ static void * invalid_except_stmt_indent_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -22229,11 +23151,11 @@ invalid_except_stmt_indent_rule(Parser *p) expr_ty expression_var; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 634)) // token='except' + (a = _PyPegen_expect_token(p, 637)) // token='except' && (expression_var = expression_rule(p)) // expression && - (_opt_var = _tmp_212_rule(p), !p->error_indicator) // ['as' NAME] + (_opt_var = _tmp_222_rule(p), !p->error_indicator) // ['as' NAME] && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -22265,7 +23187,7 @@ invalid_except_stmt_indent_rule(Parser *p) Token * a; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 634)) // token='except' + (a = _PyPegen_expect_token(p, 637)) // token='except' && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -22299,8 +23221,7 @@ static void * invalid_except_star_stmt_indent_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -22322,13 +23243,13 @@ invalid_except_star_stmt_indent_rule(Parser *p) expr_ty expression_var; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 634)) // token='except' + (a = _PyPegen_expect_token(p, 637)) // token='except' && (_literal = _PyPegen_expect_token(p, 16)) // token='*' && (expression_var = expression_rule(p)) // expression && - (_opt_var = _tmp_213_rule(p), !p->error_indicator) // ['as' NAME] + (_opt_var = _tmp_223_rule(p), !p->error_indicator) // ['as' NAME] && (_literal_1 = _PyPegen_expect_token(p, 11)) // token=':' && @@ -22363,8 +23284,7 @@ static void * invalid_match_stmt_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -22450,8 +23370,7 @@ static void * invalid_case_block_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -22543,8 +23462,7 @@ static void * invalid_as_pattern_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -22564,7 +23482,7 @@ invalid_as_pattern_rule(Parser *p) if ( (or_pattern_var = or_pattern_rule(p)) // or_pattern && - (_keyword = _PyPegen_expect_token(p, 637)) // token='as' + (_keyword = _PyPegen_expect_token(p, 640)) // token='as' && (a = _PyPegen_expect_soft_keyword(p, "_")) // soft_keyword='"_"' ) @@ -22594,7 +23512,7 @@ invalid_as_pattern_rule(Parser *p) if ( (or_pattern_var = or_pattern_rule(p)) // or_pattern && - (_keyword = _PyPegen_expect_token(p, 637)) // token='as' + (_keyword = _PyPegen_expect_token(p, 640)) // token='as' && _PyPegen_lookahead_with_name(0, _PyPegen_name_token, p) && @@ -22625,8 +23543,7 @@ static void * invalid_class_pattern_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -22676,8 +23593,7 @@ static asdl_pattern_seq* invalid_class_argument_pattern_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -22697,7 +23613,7 @@ invalid_class_argument_pattern_rule(Parser *p) asdl_pattern_seq* a; asdl_seq* keyword_patterns_var; if ( - (_opt_var = _tmp_214_rule(p), !p->error_indicator) // [positional_patterns ','] + (_opt_var = _tmp_224_rule(p), !p->error_indicator) // [positional_patterns ','] && (keyword_patterns_var = keyword_patterns_rule(p)) // keyword_patterns && @@ -22732,8 +23648,7 @@ static void * invalid_if_stmt_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -22751,7 +23666,7 @@ invalid_if_stmt_rule(Parser *p) expr_ty named_expression_var; Token * newline_var; if ( - (_keyword = _PyPegen_expect_token(p, 639)) // token='if' + (_keyword = _PyPegen_expect_token(p, 642)) // token='if' && (named_expression_var = named_expression_rule(p)) // named_expression && @@ -22782,7 +23697,7 @@ invalid_if_stmt_rule(Parser *p) expr_ty a_1; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 639)) // token='if' + (a = _PyPegen_expect_token(p, 642)) // token='if' && (a_1 = named_expression_rule(p)) // named_expression && @@ -22819,8 +23734,7 @@ static void * invalid_elif_stmt_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -22838,7 +23752,7 @@ invalid_elif_stmt_rule(Parser *p) expr_ty named_expression_var; Token * newline_var; if ( - (_keyword = _PyPegen_expect_token(p, 641)) // token='elif' + (_keyword = _PyPegen_expect_token(p, 644)) // token='elif' && (named_expression_var = named_expression_rule(p)) // named_expression && @@ -22869,7 +23783,7 @@ invalid_elif_stmt_rule(Parser *p) expr_ty named_expression_var; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 641)) // token='elif' + (a = _PyPegen_expect_token(p, 644)) // token='elif' && (named_expression_var = named_expression_rule(p)) // named_expression && @@ -22904,8 +23818,7 @@ static void * invalid_else_stmt_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -22923,7 +23836,7 @@ invalid_else_stmt_rule(Parser *p) Token * a; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 642)) // token='else' + (a = _PyPegen_expect_token(p, 645)) // token='else' && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -22958,8 +23871,7 @@ static void * invalid_while_stmt_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -22977,7 +23889,7 @@ invalid_while_stmt_rule(Parser *p) expr_ty named_expression_var; Token * newline_var; if ( - (_keyword = _PyPegen_expect_token(p, 644)) // token='while' + (_keyword = _PyPegen_expect_token(p, 647)) // token='while' && (named_expression_var = named_expression_rule(p)) // named_expression && @@ -23008,7 +23920,7 @@ invalid_while_stmt_rule(Parser *p) expr_ty named_expression_var; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 644)) // token='while' + (a = _PyPegen_expect_token(p, 647)) // token='while' && (named_expression_var = named_expression_rule(p)) // named_expression && @@ -23045,8 +23957,7 @@ static void * invalid_for_stmt_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -23070,11 +23981,11 @@ invalid_for_stmt_rule(Parser *p) if ( (_opt_var = _PyPegen_expect_token(p, ASYNC), !p->error_indicator) // ASYNC? && - (_keyword = _PyPegen_expect_token(p, 647)) // token='for' + (_keyword = _PyPegen_expect_token(p, 650)) // token='for' && (star_targets_var = star_targets_rule(p)) // star_targets && - (_keyword_1 = _PyPegen_expect_token(p, 648)) // token='in' + (_keyword_1 = _PyPegen_expect_token(p, 651)) // token='in' && (star_expressions_var = star_expressions_rule(p)) // star_expressions && @@ -23111,11 +24022,11 @@ invalid_for_stmt_rule(Parser *p) if ( (_opt_var = _PyPegen_expect_token(p, ASYNC), !p->error_indicator) // ASYNC? && - (a = _PyPegen_expect_token(p, 647)) // token='for' + (a = _PyPegen_expect_token(p, 650)) // token='for' && (star_targets_var = star_targets_rule(p)) // star_targets && - (_keyword = _PyPegen_expect_token(p, 648)) // token='in' + (_keyword = _PyPegen_expect_token(p, 651)) // token='in' && (star_expressions_var = star_expressions_rule(p)) // star_expressions && @@ -23151,8 +24062,7 @@ static void * invalid_def_raw_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -23181,7 +24091,7 @@ invalid_def_raw_rule(Parser *p) if ( (_opt_var = _PyPegen_expect_token(p, ASYNC), !p->error_indicator) // ASYNC? && - (a = _PyPegen_expect_token(p, 649)) // token='def' + (a = _PyPegen_expect_token(p, 652)) // token='def' && (name_var = _PyPegen_name_token(p)) // NAME && @@ -23191,7 +24101,7 @@ invalid_def_raw_rule(Parser *p) && (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' && - (_opt_var_2 = _tmp_215_rule(p), !p->error_indicator) // ['->' expression] + (_opt_var_2 = _tmp_225_rule(p), !p->error_indicator) // ['->' expression] && (_literal_2 = _PyPegen_expect_token(p, 11)) // token=':' && @@ -23226,8 +24136,7 @@ static void * invalid_class_def_raw_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -23247,11 +24156,11 @@ invalid_class_def_raw_rule(Parser *p) expr_ty name_var; Token * newline_var; if ( - (_keyword = _PyPegen_expect_token(p, 651)) // token='class' + (_keyword = _PyPegen_expect_token(p, 654)) // token='class' && (name_var = _PyPegen_name_token(p)) // NAME && - (_opt_var = _tmp_216_rule(p), !p->error_indicator) // ['(' arguments? ')'] + (_opt_var = _tmp_226_rule(p), !p->error_indicator) // ['(' arguments? ')'] && (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' ) @@ -23282,11 +24191,11 @@ invalid_class_def_raw_rule(Parser *p) expr_ty name_var; Token * newline_var; if ( - (a = _PyPegen_expect_token(p, 651)) // token='class' + (a = _PyPegen_expect_token(p, 654)) // token='class' && (name_var = _PyPegen_name_token(p)) // NAME && - (_opt_var = _tmp_217_rule(p), !p->error_indicator) // ['(' arguments? ')'] + (_opt_var = _tmp_227_rule(p), !p->error_indicator) // ['(' arguments? ')'] && (_literal = _PyPegen_expect_token(p, 11)) // token=':' && @@ -23322,8 +24231,7 @@ static void * invalid_double_starred_kvpairs_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -23337,11 +24245,11 @@ invalid_double_starred_kvpairs_rule(Parser *p) return NULL; } D(fprintf(stderr, "%*c> invalid_double_starred_kvpairs[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.double_starred_kvpair+ ',' invalid_kvpair")); - asdl_seq * _gather_218_var; + asdl_seq * _gather_228_var; Token * _literal; void *invalid_kvpair_var; if ( - (_gather_218_var = _gather_218_rule(p)) // ','.double_starred_kvpair+ + (_gather_228_var = _gather_228_rule(p)) // ','.double_starred_kvpair+ && (_literal = _PyPegen_expect_token(p, 12)) // token=',' && @@ -23349,7 +24257,7 @@ invalid_double_starred_kvpairs_rule(Parser *p) ) { D(fprintf(stderr, "%*c+ invalid_double_starred_kvpairs[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.double_starred_kvpair+ ',' invalid_kvpair")); - _res = _PyPegen_dummy_name(p, _gather_218_var, _literal, invalid_kvpair_var); + _res = _PyPegen_dummy_name(p, _gather_228_var, _literal, invalid_kvpair_var); goto done; } p->mark = _mark; @@ -23402,7 +24310,7 @@ invalid_double_starred_kvpairs_rule(Parser *p) && (a = _PyPegen_expect_token(p, 11)) // token=':' && - _PyPegen_lookahead(1, _tmp_220_rule, p) + _PyPegen_lookahead(1, _tmp_230_rule, p) ) { D(fprintf(stderr, "%*c+ invalid_double_starred_kvpairs[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ':' &('}' | ',')")); @@ -23432,8 +24340,7 @@ static void * invalid_kvpair_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -23513,7 +24420,7 @@ invalid_kvpair_rule(Parser *p) && (a = _PyPegen_expect_token(p, 11)) // token=':' && - _PyPegen_lookahead(1, _tmp_221_rule, p) + _PyPegen_lookahead(1, _tmp_231_rule, p) ) { D(fprintf(stderr, "%*c+ invalid_kvpair[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ':' &('}' | ',')")); @@ -23535,528 +24442,422 @@ invalid_kvpair_rule(Parser *p) return _res; } -// _loop0_1: NEWLINE -static asdl_seq * -_loop0_1_rule(Parser *p) +// invalid_starred_expression: '*' expression '=' expression +static void * +invalid_starred_expression_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; return NULL; } - void *_res = NULL; + void * _res = NULL; int _mark = p->mark; - int _start_mark = p->mark; - void **_children = PyMem_Malloc(sizeof(void *)); - if (!_children) { - p->error_indicator = 1; - PyErr_NoMemory(); - p->level--; - return NULL; - } - Py_ssize_t _children_capacity = 1; - Py_ssize_t _n = 0; - { // NEWLINE + { // '*' expression '=' expression if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_1[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NEWLINE")); - Token * newline_var; - while ( - (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' + D(fprintf(stderr, "%*c> invalid_starred_expression[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' expression '=' expression")); + Token * _literal; + Token * a; + expr_ty b; + expr_ty expression_var; + if ( + (a = _PyPegen_expect_token(p, 16)) // token='*' + && + (expression_var = expression_rule(p)) // expression + && + (_literal = _PyPegen_expect_token(p, 22)) // token='=' + && + (b = expression_rule(p)) // expression ) { - _res = newline_var; - if (_n == _children_capacity) { - _children_capacity *= 2; - void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); - if (!_new_children) { - PyMem_Free(_children); - p->error_indicator = 1; - PyErr_NoMemory(); - p->level--; - return NULL; - } - _children = _new_children; + D(fprintf(stderr, "%*c+ invalid_starred_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' expression '=' expression")); + _res = RAISE_SYNTAX_ERROR_KNOWN_RANGE ( a , b , "cannot assign to iterable argument unpacking" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; } - _children[_n++] = _res; - _mark = p->mark; + goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_1[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NEWLINE")); - } - asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); - if (!_seq) { - PyMem_Free(_children); - p->error_indicator = 1; - PyErr_NoMemory(); - p->level--; - return NULL; + D(fprintf(stderr, "%*c%s invalid_starred_expression[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*' expression '=' expression")); } - for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_1_type, _seq); + _res = NULL; + done: p->level--; - return _seq; + return _res; } -// _loop0_2: NEWLINE -static asdl_seq * -_loop0_2_rule(Parser *p) +// invalid_replacement_field: +// | '{' '=' +// | '{' '!' +// | '{' ':' +// | '{' '}' +// | '{' !(yield_expr | star_expressions) +// | '{' (yield_expr | star_expressions) !('=' | '!' | ':' | '}') +// | '{' (yield_expr | star_expressions) '=' !('!' | ':' | '}') +// | '{' (yield_expr | star_expressions) '='? invalid_conversion_character +// | '{' (yield_expr | star_expressions) '='? ['!' NAME] !(':' | '}') +// | '{' (yield_expr | star_expressions) '='? ['!' NAME] ':' fstring_format_spec* !'}' +// | '{' (yield_expr | star_expressions) '='? ['!' NAME] !'}' +static void * +invalid_replacement_field_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; return NULL; } - void *_res = NULL; + void * _res = NULL; int _mark = p->mark; - int _start_mark = p->mark; - void **_children = PyMem_Malloc(sizeof(void *)); - if (!_children) { - p->error_indicator = 1; - PyErr_NoMemory(); - p->level--; - return NULL; - } - Py_ssize_t _children_capacity = 1; - Py_ssize_t _n = 0; - { // NEWLINE + { // '{' '=' if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_2[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NEWLINE")); - Token * newline_var; - while ( - (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' + D(fprintf(stderr, "%*c> invalid_replacement_field[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{' '='")); + Token * _literal; + Token * a; + if ( + (_literal = _PyPegen_expect_token(p, 25)) // token='{' + && + (a = _PyPegen_expect_token(p, 22)) // token='=' ) { - _res = newline_var; - if (_n == _children_capacity) { - _children_capacity *= 2; - void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); - if (!_new_children) { - PyMem_Free(_children); - p->error_indicator = 1; - PyErr_NoMemory(); - p->level--; - return NULL; - } - _children = _new_children; + D(fprintf(stderr, "%*c+ invalid_replacement_field[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' '='")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "f-string: valid expression required before '='" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; } - _children[_n++] = _res; - _mark = p->mark; + goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_2[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NEWLINE")); - } - asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); - if (!_seq) { - PyMem_Free(_children); - p->error_indicator = 1; - PyErr_NoMemory(); - p->level--; - return NULL; - } - for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_2_type, _seq); - p->level--; - return _seq; -} - -// _loop1_3: statement -static asdl_seq * -_loop1_3_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - void *_res = NULL; - int _mark = p->mark; - int _start_mark = p->mark; - void **_children = PyMem_Malloc(sizeof(void *)); - if (!_children) { - p->error_indicator = 1; - PyErr_NoMemory(); - p->level--; - return NULL; + D(fprintf(stderr, "%*c%s invalid_replacement_field[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'{' '='")); } - Py_ssize_t _children_capacity = 1; - Py_ssize_t _n = 0; - { // statement + { // '{' '!' if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_3[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "statement")); - asdl_stmt_seq* statement_var; - while ( - (statement_var = statement_rule(p)) // statement + D(fprintf(stderr, "%*c> invalid_replacement_field[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{' '!'")); + Token * _literal; + Token * a; + if ( + (_literal = _PyPegen_expect_token(p, 25)) // token='{' + && + (a = _PyPegen_expect_token(p, 54)) // token='!' ) { - _res = statement_var; - if (_n == _children_capacity) { - _children_capacity *= 2; - void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); - if (!_new_children) { - PyMem_Free(_children); - p->error_indicator = 1; - PyErr_NoMemory(); - p->level--; - return NULL; - } - _children = _new_children; + D(fprintf(stderr, "%*c+ invalid_replacement_field[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' '!'")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "f-string: valid expression required before '!'" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; } - _children[_n++] = _res; - _mark = p->mark; + goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_3[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "statement")); - } - if (_n == 0 || p->error_indicator) { - PyMem_Free(_children); - p->level--; - return NULL; - } - asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); - if (!_seq) { - PyMem_Free(_children); - p->error_indicator = 1; - PyErr_NoMemory(); - p->level--; - return NULL; - } - for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_3_type, _seq); - p->level--; - return _seq; -} - -// _loop0_5: ';' simple_stmt -static asdl_seq * -_loop0_5_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - void *_res = NULL; - int _mark = p->mark; - int _start_mark = p->mark; - void **_children = PyMem_Malloc(sizeof(void *)); - if (!_children) { - p->error_indicator = 1; - PyErr_NoMemory(); - p->level--; - return NULL; + D(fprintf(stderr, "%*c%s invalid_replacement_field[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'{' '!'")); } - Py_ssize_t _children_capacity = 1; - Py_ssize_t _n = 0; - { // ';' simple_stmt + { // '{' ':' if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_5[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "';' simple_stmt")); + D(fprintf(stderr, "%*c> invalid_replacement_field[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{' ':'")); Token * _literal; - stmt_ty elem; - while ( - (_literal = _PyPegen_expect_token(p, 13)) // token=';' + Token * a; + if ( + (_literal = _PyPegen_expect_token(p, 25)) // token='{' && - (elem = simple_stmt_rule(p)) // simple_stmt + (a = _PyPegen_expect_token(p, 11)) // token=':' ) { - _res = elem; + D(fprintf(stderr, "%*c+ invalid_replacement_field[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' ':'")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "f-string: valid expression required before ':'" ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - PyMem_Free(_children); p->level--; return NULL; } - if (_n == _children_capacity) { - _children_capacity *= 2; - void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); - if (!_new_children) { - PyMem_Free(_children); - p->error_indicator = 1; - PyErr_NoMemory(); - p->level--; - return NULL; - } - _children = _new_children; - } - _children[_n++] = _res; - _mark = p->mark; + goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_5[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "';' simple_stmt")); - } - asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); - if (!_seq) { - PyMem_Free(_children); - p->error_indicator = 1; - PyErr_NoMemory(); - p->level--; - return NULL; - } - for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_5_type, _seq); - p->level--; - return _seq; -} - -// _gather_4: simple_stmt _loop0_5 -static asdl_seq * -_gather_4_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; + D(fprintf(stderr, "%*c%s invalid_replacement_field[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'{' ':'")); } - asdl_seq * _res = NULL; - int _mark = p->mark; - { // simple_stmt _loop0_5 + { // '{' '}' if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_4[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "simple_stmt _loop0_5")); - stmt_ty elem; - asdl_seq * seq; + D(fprintf(stderr, "%*c> invalid_replacement_field[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{' '}'")); + Token * _literal; + Token * a; if ( - (elem = simple_stmt_rule(p)) // simple_stmt + (_literal = _PyPegen_expect_token(p, 25)) // token='{' && - (seq = _loop0_5_rule(p)) // _loop0_5 + (a = _PyPegen_expect_token(p, 26)) // token='}' ) { - D(fprintf(stderr, "%*c+ _gather_4[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "simple_stmt _loop0_5")); - _res = _PyPegen_seq_insert_in_front(p, elem, seq); + D(fprintf(stderr, "%*c+ invalid_replacement_field[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' '}'")); + _res = RAISE_SYNTAX_ERROR_KNOWN_LOCATION ( a , "f-string: valid expression required before '}'" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_4[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "simple_stmt _loop0_5")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _tmp_6: 'import' | 'from' -static void * -_tmp_6_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; + D(fprintf(stderr, "%*c%s invalid_replacement_field[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'{' '}'")); } - void * _res = NULL; - int _mark = p->mark; - { // 'import' + { // '{' !(yield_expr | star_expressions) if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_6[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'import'")); - Token * _keyword; + D(fprintf(stderr, "%*c> invalid_replacement_field[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{' !(yield_expr | star_expressions)")); + Token * _literal; if ( - (_keyword = _PyPegen_expect_token(p, 531)) // token='import' + (_literal = _PyPegen_expect_token(p, 25)) // token='{' + && + _PyPegen_lookahead(0, _tmp_232_rule, p) ) { - D(fprintf(stderr, "%*c+ _tmp_6[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'import'")); - _res = _keyword; + D(fprintf(stderr, "%*c+ invalid_replacement_field[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' !(yield_expr | star_expressions)")); + _res = RAISE_SYNTAX_ERROR_ON_NEXT_TOKEN ( "f-string: expecting a valid expression after '{'" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_6[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'import'")); + D(fprintf(stderr, "%*c%s invalid_replacement_field[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'{' !(yield_expr | star_expressions)")); } - { // 'from' + { // '{' (yield_expr | star_expressions) !('=' | '!' | ':' | '}') if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_6[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'from'")); - Token * _keyword; + D(fprintf(stderr, "%*c> invalid_replacement_field[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{' (yield_expr | star_expressions) !('=' | '!' | ':' | '}')")); + Token * _literal; + void *_tmp_233_var; if ( - (_keyword = _PyPegen_expect_token(p, 572)) // token='from' + (_literal = _PyPegen_expect_token(p, 25)) // token='{' + && + (_tmp_233_var = _tmp_233_rule(p)) // yield_expr | star_expressions + && + _PyPegen_lookahead(0, _tmp_234_rule, p) ) { - D(fprintf(stderr, "%*c+ _tmp_6[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'from'")); - _res = _keyword; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_6[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'from'")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _tmp_7: 'def' | '@' | ASYNC -static void * -_tmp_7_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; + D(fprintf(stderr, "%*c+ invalid_replacement_field[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' (yield_expr | star_expressions) !('=' | '!' | ':' | '}')")); + _res = PyErr_Occurred ( ) ? NULL : RAISE_SYNTAX_ERROR_ON_NEXT_TOKEN ( "f-string: expecting '=', or '!', or ':', or '}'" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s invalid_replacement_field[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'{' (yield_expr | star_expressions) !('=' | '!' | ':' | '}')")); } - void * _res = NULL; - int _mark = p->mark; - { // 'def' + { // '{' (yield_expr | star_expressions) '=' !('!' | ':' | '}') if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_7[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'def'")); - Token * _keyword; + D(fprintf(stderr, "%*c> invalid_replacement_field[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{' (yield_expr | star_expressions) '=' !('!' | ':' | '}')")); + Token * _literal; + Token * _literal_1; + void *_tmp_235_var; if ( - (_keyword = _PyPegen_expect_token(p, 649)) // token='def' + (_literal = _PyPegen_expect_token(p, 25)) // token='{' + && + (_tmp_235_var = _tmp_235_rule(p)) // yield_expr | star_expressions + && + (_literal_1 = _PyPegen_expect_token(p, 22)) // token='=' + && + _PyPegen_lookahead(0, _tmp_236_rule, p) ) { - D(fprintf(stderr, "%*c+ _tmp_7[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'def'")); - _res = _keyword; + D(fprintf(stderr, "%*c+ invalid_replacement_field[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' (yield_expr | star_expressions) '=' !('!' | ':' | '}')")); + _res = PyErr_Occurred ( ) ? NULL : RAISE_SYNTAX_ERROR_ON_NEXT_TOKEN ( "f-string: expecting '!', or ':', or '}'" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_7[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'def'")); + D(fprintf(stderr, "%*c%s invalid_replacement_field[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'{' (yield_expr | star_expressions) '=' !('!' | ':' | '}')")); } - { // '@' + { // '{' (yield_expr | star_expressions) '='? invalid_conversion_character if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_7[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'@'")); + D(fprintf(stderr, "%*c> invalid_replacement_field[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{' (yield_expr | star_expressions) '='? invalid_conversion_character")); Token * _literal; + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + void *_tmp_237_var; + void *invalid_conversion_character_var; if ( - (_literal = _PyPegen_expect_token(p, 49)) // token='@' + (_literal = _PyPegen_expect_token(p, 25)) // token='{' + && + (_tmp_237_var = _tmp_237_rule(p)) // yield_expr | star_expressions + && + (_opt_var = _PyPegen_expect_token(p, 22), !p->error_indicator) // '='? + && + (invalid_conversion_character_var = invalid_conversion_character_rule(p)) // invalid_conversion_character ) { - D(fprintf(stderr, "%*c+ _tmp_7[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'@'")); - _res = _literal; + D(fprintf(stderr, "%*c+ invalid_replacement_field[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' (yield_expr | star_expressions) '='? invalid_conversion_character")); + _res = _PyPegen_dummy_name(p, _literal, _tmp_237_var, _opt_var, invalid_conversion_character_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_7[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'@'")); + D(fprintf(stderr, "%*c%s invalid_replacement_field[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'{' (yield_expr | star_expressions) '='? invalid_conversion_character")); } - { // ASYNC + { // '{' (yield_expr | star_expressions) '='? ['!' NAME] !(':' | '}') if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_7[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC")); - Token * async_var; + D(fprintf(stderr, "%*c> invalid_replacement_field[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{' (yield_expr | star_expressions) '='? ['!' NAME] !(':' | '}')")); + Token * _literal; + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + void *_opt_var_1; + UNUSED(_opt_var_1); // Silence compiler warnings + void *_tmp_238_var; if ( - (async_var = _PyPegen_expect_token(p, ASYNC)) // token='ASYNC' + (_literal = _PyPegen_expect_token(p, 25)) // token='{' + && + (_tmp_238_var = _tmp_238_rule(p)) // yield_expr | star_expressions + && + (_opt_var = _PyPegen_expect_token(p, 22), !p->error_indicator) // '='? + && + (_opt_var_1 = _tmp_239_rule(p), !p->error_indicator) // ['!' NAME] + && + _PyPegen_lookahead(0, _tmp_240_rule, p) ) { - D(fprintf(stderr, "%*c+ _tmp_7[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "ASYNC")); - _res = async_var; + D(fprintf(stderr, "%*c+ invalid_replacement_field[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' (yield_expr | star_expressions) '='? ['!' NAME] !(':' | '}')")); + _res = PyErr_Occurred ( ) ? NULL : RAISE_SYNTAX_ERROR_ON_NEXT_TOKEN ( "f-string: expecting ':' or '}'" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_7[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "ASYNC")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _tmp_8: 'class' | '@' -static void * -_tmp_8_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; + D(fprintf(stderr, "%*c%s invalid_replacement_field[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'{' (yield_expr | star_expressions) '='? ['!' NAME] !(':' | '}')")); } - void * _res = NULL; - int _mark = p->mark; - { // 'class' + { // '{' (yield_expr | star_expressions) '='? ['!' NAME] ':' fstring_format_spec* !'}' if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_8[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'class'")); - Token * _keyword; + D(fprintf(stderr, "%*c> invalid_replacement_field[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{' (yield_expr | star_expressions) '='? ['!' NAME] ':' fstring_format_spec* !'}'")); + Token * _literal; + Token * _literal_1; + asdl_seq * _loop0_243_var; + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + void *_opt_var_1; + UNUSED(_opt_var_1); // Silence compiler warnings + void *_tmp_241_var; if ( - (_keyword = _PyPegen_expect_token(p, 651)) // token='class' + (_literal = _PyPegen_expect_token(p, 25)) // token='{' + && + (_tmp_241_var = _tmp_241_rule(p)) // yield_expr | star_expressions + && + (_opt_var = _PyPegen_expect_token(p, 22), !p->error_indicator) // '='? + && + (_opt_var_1 = _tmp_242_rule(p), !p->error_indicator) // ['!' NAME] + && + (_literal_1 = _PyPegen_expect_token(p, 11)) // token=':' + && + (_loop0_243_var = _loop0_243_rule(p)) // fstring_format_spec* + && + _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 26) // token='}' ) { - D(fprintf(stderr, "%*c+ _tmp_8[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'class'")); - _res = _keyword; + D(fprintf(stderr, "%*c+ invalid_replacement_field[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' (yield_expr | star_expressions) '='? ['!' NAME] ':' fstring_format_spec* !'}'")); + _res = PyErr_Occurred ( ) ? NULL : RAISE_SYNTAX_ERROR_ON_NEXT_TOKEN ( "f-string: expecting '}', or format specs" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_8[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'class'")); + D(fprintf(stderr, "%*c%s invalid_replacement_field[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'{' (yield_expr | star_expressions) '='? ['!' NAME] ':' fstring_format_spec* !'}'")); } - { // '@' + { // '{' (yield_expr | star_expressions) '='? ['!' NAME] !'}' if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_8[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'@'")); + D(fprintf(stderr, "%*c> invalid_replacement_field[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{' (yield_expr | star_expressions) '='? ['!' NAME] !'}'")); Token * _literal; + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + void *_opt_var_1; + UNUSED(_opt_var_1); // Silence compiler warnings + void *_tmp_244_var; if ( - (_literal = _PyPegen_expect_token(p, 49)) // token='@' + (_literal = _PyPegen_expect_token(p, 25)) // token='{' + && + (_tmp_244_var = _tmp_244_rule(p)) // yield_expr | star_expressions + && + (_opt_var = _PyPegen_expect_token(p, 22), !p->error_indicator) // '='? + && + (_opt_var_1 = _tmp_245_rule(p), !p->error_indicator) // ['!' NAME] + && + _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 26) // token='}' ) { - D(fprintf(stderr, "%*c+ _tmp_8[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'@'")); - _res = _literal; + D(fprintf(stderr, "%*c+ invalid_replacement_field[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' (yield_expr | star_expressions) '='? ['!' NAME] !'}'")); + _res = PyErr_Occurred ( ) ? NULL : RAISE_SYNTAX_ERROR_ON_NEXT_TOKEN ( "f-string: expecting '}'" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_8[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'@'")); + D(fprintf(stderr, "%*c%s invalid_replacement_field[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'{' (yield_expr | star_expressions) '='? ['!' NAME] !'}'")); } _res = NULL; done: @@ -24064,13 +24865,12 @@ _tmp_8_rule(Parser *p) return _res; } -// _tmp_9: 'with' | ASYNC +// invalid_conversion_character: '!' &(':' | '}') | '!' !NAME static void * -_tmp_9_rule(Parser *p) +invalid_conversion_character_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -24078,43 +24878,57 @@ _tmp_9_rule(Parser *p) } void * _res = NULL; int _mark = p->mark; - { // 'with' + { // '!' &(':' | '}') if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_9[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'with'")); - Token * _keyword; + D(fprintf(stderr, "%*c> invalid_conversion_character[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'!' &(':' | '}')")); + Token * _literal; if ( - (_keyword = _PyPegen_expect_token(p, 612)) // token='with' + (_literal = _PyPegen_expect_token(p, 54)) // token='!' + && + _PyPegen_lookahead(1, _tmp_246_rule, p) ) { - D(fprintf(stderr, "%*c+ _tmp_9[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'with'")); - _res = _keyword; + D(fprintf(stderr, "%*c+ invalid_conversion_character[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'!' &(':' | '}')")); + _res = RAISE_SYNTAX_ERROR_ON_NEXT_TOKEN ( "f-string: missing conversion character" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_9[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'with'")); + D(fprintf(stderr, "%*c%s invalid_conversion_character[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'!' &(':' | '}')")); } - { // ASYNC + { // '!' !NAME if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_9[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC")); - Token * async_var; + D(fprintf(stderr, "%*c> invalid_conversion_character[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'!' !NAME")); + Token * _literal; if ( - (async_var = _PyPegen_expect_token(p, ASYNC)) // token='ASYNC' + (_literal = _PyPegen_expect_token(p, 54)) // token='!' + && + _PyPegen_lookahead_with_name(0, _PyPegen_name_token, p) ) { - D(fprintf(stderr, "%*c+ _tmp_9[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "ASYNC")); - _res = async_var; + D(fprintf(stderr, "%*c+ invalid_conversion_character[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'!' !NAME")); + _res = RAISE_SYNTAX_ERROR_ON_NEXT_TOKEN ( "f-string: invalid conversion character" ); + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_9[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "ASYNC")); + D(fprintf(stderr, "%*c%s invalid_conversion_character[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'!' !NAME")); } _res = NULL; done: @@ -24122,234 +24936,285 @@ _tmp_9_rule(Parser *p) return _res; } -// _tmp_10: 'for' | ASYNC -static void * -_tmp_10_rule(Parser *p) +// _loop0_1: NEWLINE +static asdl_seq * +_loop0_1_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; return NULL; } - void * _res = NULL; + void *_res = NULL; int _mark = p->mark; - { // 'for' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_10[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'for'")); - Token * _keyword; - if ( - (_keyword = _PyPegen_expect_token(p, 647)) // token='for' - ) - { - D(fprintf(stderr, "%*c+ _tmp_10[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'for'")); - _res = _keyword; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_10[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'for'")); + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; } - { // ASYNC + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // NEWLINE if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_10[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC")); - Token * async_var; - if ( - (async_var = _PyPegen_expect_token(p, ASYNC)) // token='ASYNC' + D(fprintf(stderr, "%*c> _loop0_1[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NEWLINE")); + Token * newline_var; + while ( + (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' ) { - D(fprintf(stderr, "%*c+ _tmp_10[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "ASYNC")); - _res = async_var; - goto done; + _res = newline_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + _children = _new_children; + } + _children[_n++] = _res; + _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_10[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "ASYNC")); + D(fprintf(stderr, "%*c%s _loop0_1[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NEWLINE")); } - _res = NULL; - done: + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); + PyMem_Free(_children); p->level--; - return _res; + return _seq; } -// _tmp_11: '=' annotated_rhs -static void * -_tmp_11_rule(Parser *p) +// _loop0_2: NEWLINE +static asdl_seq * +_loop0_2_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; return NULL; } - void * _res = NULL; + void *_res = NULL; int _mark = p->mark; - { // '=' annotated_rhs + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // NEWLINE if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_11[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'=' annotated_rhs")); - Token * _literal; - expr_ty d; - if ( - (_literal = _PyPegen_expect_token(p, 22)) // token='=' - && - (d = annotated_rhs_rule(p)) // annotated_rhs + D(fprintf(stderr, "%*c> _loop0_2[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NEWLINE")); + Token * newline_var; + while ( + (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' ) { - D(fprintf(stderr, "%*c+ _tmp_11[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'=' annotated_rhs")); - _res = d; - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; + _res = newline_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + _children = _new_children; } - goto done; + _children[_n++] = _res; + _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_11[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'=' annotated_rhs")); + D(fprintf(stderr, "%*c%s _loop0_2[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NEWLINE")); } - _res = NULL; - done: + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); + PyMem_Free(_children); p->level--; - return _res; + return _seq; } -// _tmp_12: '(' single_target ')' | single_subscript_attribute_target -static void * -_tmp_12_rule(Parser *p) +// _loop0_3: fstring_middle +static asdl_seq * +_loop0_3_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; return NULL; } - void * _res = NULL; + void *_res = NULL; int _mark = p->mark; - { // '(' single_target ')' + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // fstring_middle if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_12[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' single_target ')'")); - Token * _literal; - Token * _literal_1; - expr_ty b; - if ( - (_literal = _PyPegen_expect_token(p, 7)) // token='(' - && - (b = single_target_rule(p)) // single_target - && - (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' + D(fprintf(stderr, "%*c> _loop0_3[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "fstring_middle")); + expr_ty fstring_middle_var; + while ( + (fstring_middle_var = fstring_middle_rule(p)) // fstring_middle ) { - D(fprintf(stderr, "%*c+ _tmp_12[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' single_target ')'")); - _res = b; - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; + _res = fstring_middle_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + _children = _new_children; } - goto done; + _children[_n++] = _res; + _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_12[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'(' single_target ')'")); + D(fprintf(stderr, "%*c%s _loop0_3[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "fstring_middle")); } - { // single_subscript_attribute_target - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_12[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "single_subscript_attribute_target")); - expr_ty single_subscript_attribute_target_var; - if ( - (single_subscript_attribute_target_var = single_subscript_attribute_target_rule(p)) // single_subscript_attribute_target - ) - { - D(fprintf(stderr, "%*c+ _tmp_12[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "single_subscript_attribute_target")); - _res = single_subscript_attribute_target_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_12[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "single_subscript_attribute_target")); + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; } - _res = NULL; - done: + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); + PyMem_Free(_children); p->level--; - return _res; + return _seq; } -// _tmp_13: '=' annotated_rhs -static void * -_tmp_13_rule(Parser *p) +// _loop1_4: statement +static asdl_seq * +_loop1_4_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; return NULL; } - void * _res = NULL; + void *_res = NULL; int _mark = p->mark; - { // '=' annotated_rhs + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // statement if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_13[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'=' annotated_rhs")); - Token * _literal; - expr_ty d; - if ( - (_literal = _PyPegen_expect_token(p, 22)) // token='=' - && - (d = annotated_rhs_rule(p)) // annotated_rhs + D(fprintf(stderr, "%*c> _loop1_4[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "statement")); + asdl_stmt_seq* statement_var; + while ( + (statement_var = statement_rule(p)) // statement ) { - D(fprintf(stderr, "%*c+ _tmp_13[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'=' annotated_rhs")); - _res = d; - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - p->level--; - return NULL; + _res = statement_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + _children = _new_children; } - goto done; + _children[_n++] = _res; + _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_13[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'=' annotated_rhs")); + D(fprintf(stderr, "%*c%s _loop1_4[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "statement")); } - _res = NULL; - done: + if (_n == 0 || p->error_indicator) { + PyMem_Free(_children); + p->level--; + return NULL; + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); + PyMem_Free(_children); p->level--; - return _res; + return _seq; } -// _loop1_14: (star_targets '=') +// _loop0_6: ';' simple_stmt static asdl_seq * -_loop1_14_rule(Parser *p) +_loop0_6_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -24357,7 +25222,6 @@ _loop1_14_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -24367,18 +25231,27 @@ _loop1_14_rule(Parser *p) } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; - { // (star_targets '=') + { // ';' simple_stmt if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_14[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')")); - void *_tmp_222_var; + D(fprintf(stderr, "%*c> _loop0_6[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "';' simple_stmt")); + Token * _literal; + stmt_ty elem; while ( - (_tmp_222_var = _tmp_222_rule(p)) // star_targets '=' + (_literal = _PyPegen_expect_token(p, 13)) // token=';' + && + (elem = simple_stmt_rule(p)) // simple_stmt ) { - _res = _tmp_222_var; + _res = elem; + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + PyMem_Free(_children); + p->level--; + return NULL; + } if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -24395,13 +25268,8 @@ _loop1_14_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_14[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(star_targets '=')")); - } - if (_n == 0 || p->error_indicator) { - PyMem_Free(_children); - p->level--; - return NULL; + D(fprintf(stderr, "%*c%s _loop0_6[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "';' simple_stmt")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { @@ -24413,62 +25281,101 @@ _loop1_14_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_14_type, _seq); p->level--; return _seq; } -// _tmp_15: yield_expr | star_expressions -static void * -_tmp_15_rule(Parser *p) +// _gather_5: simple_stmt _loop0_6 +static asdl_seq * +_gather_5_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; return NULL; } - void * _res = NULL; + asdl_seq * _res = NULL; int _mark = p->mark; - { // yield_expr + { // simple_stmt _loop0_6 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_15[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); - expr_ty yield_expr_var; + D(fprintf(stderr, "%*c> _gather_5[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "simple_stmt _loop0_6")); + stmt_ty elem; + asdl_seq * seq; if ( - (yield_expr_var = yield_expr_rule(p)) // yield_expr + (elem = simple_stmt_rule(p)) // simple_stmt + && + (seq = _loop0_6_rule(p)) // _loop0_6 ) { - D(fprintf(stderr, "%*c+ _tmp_15[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); - _res = yield_expr_var; + D(fprintf(stderr, "%*c+ _gather_5[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "simple_stmt _loop0_6")); + _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_15[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "yield_expr")); + D(fprintf(stderr, "%*c%s _gather_5[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "simple_stmt _loop0_6")); } - { // star_expressions - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_15[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); - expr_ty star_expressions_var; - if ( - (star_expressions_var = star_expressions_rule(p)) // star_expressions - ) + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_7: 'import' | 'from' +static void * +_tmp_7_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // 'import' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_7[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'import'")); + Token * _keyword; + if ( + (_keyword = _PyPegen_expect_token(p, 607)) // token='import' + ) { - D(fprintf(stderr, "%*c+ _tmp_15[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); - _res = star_expressions_var; + D(fprintf(stderr, "%*c+ _tmp_7[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'import'")); + _res = _keyword; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_15[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions")); + D(fprintf(stderr, "%*c%s _tmp_7[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'import'")); + } + { // 'from' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_7[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'from'")); + Token * _keyword; + if ( + (_keyword = _PyPegen_expect_token(p, 608)) // token='from' + ) + { + D(fprintf(stderr, "%*c+ _tmp_7[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'from'")); + _res = _keyword; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_7[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'from'")); } _res = NULL; done: @@ -24476,13 +25383,12 @@ _tmp_15_rule(Parser *p) return _res; } -// _tmp_16: yield_expr | star_expressions +// _tmp_8: 'def' | '@' | ASYNC static void * -_tmp_16_rule(Parser *p) +_tmp_8_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -24490,43 +25396,62 @@ _tmp_16_rule(Parser *p) } void * _res = NULL; int _mark = p->mark; - { // yield_expr + { // 'def' if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_16[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); - expr_ty yield_expr_var; + D(fprintf(stderr, "%*c> _tmp_8[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'def'")); + Token * _keyword; if ( - (yield_expr_var = yield_expr_rule(p)) // yield_expr + (_keyword = _PyPegen_expect_token(p, 652)) // token='def' ) { - D(fprintf(stderr, "%*c+ _tmp_16[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); - _res = yield_expr_var; + D(fprintf(stderr, "%*c+ _tmp_8[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'def'")); + _res = _keyword; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_16[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "yield_expr")); + D(fprintf(stderr, "%*c%s _tmp_8[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'def'")); } - { // star_expressions + { // '@' if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_16[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); - expr_ty star_expressions_var; + D(fprintf(stderr, "%*c> _tmp_8[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'@'")); + Token * _literal; if ( - (star_expressions_var = star_expressions_rule(p)) // star_expressions + (_literal = _PyPegen_expect_token(p, 49)) // token='@' ) { - D(fprintf(stderr, "%*c+ _tmp_16[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); - _res = star_expressions_var; + D(fprintf(stderr, "%*c+ _tmp_8[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'@'")); + _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_16[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions")); + D(fprintf(stderr, "%*c%s _tmp_8[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'@'")); + } + { // ASYNC + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_8[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC")); + Token * async_var; + if ( + (async_var = _PyPegen_expect_token(p, ASYNC)) // token='ASYNC' + ) + { + D(fprintf(stderr, "%*c+ _tmp_8[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "ASYNC")); + _res = async_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_8[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "ASYNC")); } _res = NULL; done: @@ -24534,13 +25459,12 @@ _tmp_16_rule(Parser *p) return _res; } -// _tmp_17: 'from' expression +// _tmp_9: 'class' | '@' static void * -_tmp_17_rule(Parser *p) +_tmp_9_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -24548,22 +25472,193 @@ _tmp_17_rule(Parser *p) } void * _res = NULL; int _mark = p->mark; - { // 'from' expression + { // 'class' if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_17[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'from' expression")); + D(fprintf(stderr, "%*c> _tmp_9[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'class'")); Token * _keyword; - expr_ty z; if ( - (_keyword = _PyPegen_expect_token(p, 572)) // token='from' + (_keyword = _PyPegen_expect_token(p, 654)) // token='class' + ) + { + D(fprintf(stderr, "%*c+ _tmp_9[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'class'")); + _res = _keyword; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_9[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'class'")); + } + { // '@' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_9[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'@'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 49)) // token='@' + ) + { + D(fprintf(stderr, "%*c+ _tmp_9[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'@'")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_9[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'@'")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_10: 'with' | ASYNC +static void * +_tmp_10_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // 'with' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_10[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'with'")); + Token * _keyword; + if ( + (_keyword = _PyPegen_expect_token(p, 615)) // token='with' + ) + { + D(fprintf(stderr, "%*c+ _tmp_10[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'with'")); + _res = _keyword; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_10[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'with'")); + } + { // ASYNC + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_10[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC")); + Token * async_var; + if ( + (async_var = _PyPegen_expect_token(p, ASYNC)) // token='ASYNC' + ) + { + D(fprintf(stderr, "%*c+ _tmp_10[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "ASYNC")); + _res = async_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_10[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "ASYNC")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_11: 'for' | ASYNC +static void * +_tmp_11_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // 'for' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_11[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'for'")); + Token * _keyword; + if ( + (_keyword = _PyPegen_expect_token(p, 650)) // token='for' + ) + { + D(fprintf(stderr, "%*c+ _tmp_11[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'for'")); + _res = _keyword; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_11[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'for'")); + } + { // ASYNC + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_11[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC")); + Token * async_var; + if ( + (async_var = _PyPegen_expect_token(p, ASYNC)) // token='ASYNC' + ) + { + D(fprintf(stderr, "%*c+ _tmp_11[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "ASYNC")); + _res = async_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_11[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "ASYNC")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_12: '=' annotated_rhs +static void * +_tmp_12_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // '=' annotated_rhs + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_12[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'=' annotated_rhs")); + Token * _literal; + expr_ty d; + if ( + (_literal = _PyPegen_expect_token(p, 22)) // token='=' && - (z = expression_rule(p)) // expression + (d = annotated_rhs_rule(p)) // annotated_rhs ) { - D(fprintf(stderr, "%*c+ _tmp_17[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'from' expression")); - _res = z; + D(fprintf(stderr, "%*c+ _tmp_12[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'=' annotated_rhs")); + _res = d; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; p->level--; @@ -24572,8 +25667,8 @@ _tmp_17_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_17[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'from' expression")); + D(fprintf(stderr, "%*c%s _tmp_12[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'=' annotated_rhs")); } _res = NULL; done: @@ -24581,120 +25676,113 @@ _tmp_17_rule(Parser *p) return _res; } -// _loop0_19: ',' NAME -static asdl_seq * -_loop0_19_rule(Parser *p) +// _tmp_13: '(' single_target ')' | single_subscript_attribute_target +static void * +_tmp_13_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; return NULL; } - void *_res = NULL; + void * _res = NULL; int _mark = p->mark; - int _start_mark = p->mark; - void **_children = PyMem_Malloc(sizeof(void *)); - if (!_children) { - p->error_indicator = 1; - PyErr_NoMemory(); - p->level--; - return NULL; - } - Py_ssize_t _children_capacity = 1; - Py_ssize_t _n = 0; - { // ',' NAME + { // '(' single_target ')' if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_19[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' NAME")); + D(fprintf(stderr, "%*c> _tmp_13[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' single_target ')'")); Token * _literal; - expr_ty elem; - while ( - (_literal = _PyPegen_expect_token(p, 12)) // token=',' + Token * _literal_1; + expr_ty b; + if ( + (_literal = _PyPegen_expect_token(p, 7)) // token='(' && - (elem = _PyPegen_name_token(p)) // NAME + (b = single_target_rule(p)) // single_target + && + (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' ) { - _res = elem; + D(fprintf(stderr, "%*c+ _tmp_13[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' single_target ')'")); + _res = b; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; - PyMem_Free(_children); p->level--; return NULL; } - if (_n == _children_capacity) { - _children_capacity *= 2; - void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); - if (!_new_children) { - PyMem_Free(_children); - p->error_indicator = 1; - PyErr_NoMemory(); - p->level--; - return NULL; - } - _children = _new_children; - } - _children[_n++] = _res; - _mark = p->mark; + goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_19[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' NAME")); + D(fprintf(stderr, "%*c%s _tmp_13[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'(' single_target ')'")); } - asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); - if (!_seq) { - PyMem_Free(_children); - p->error_indicator = 1; - PyErr_NoMemory(); - p->level--; - return NULL; + { // single_subscript_attribute_target + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_13[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "single_subscript_attribute_target")); + expr_ty single_subscript_attribute_target_var; + if ( + (single_subscript_attribute_target_var = single_subscript_attribute_target_rule(p)) // single_subscript_attribute_target + ) + { + D(fprintf(stderr, "%*c+ _tmp_13[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "single_subscript_attribute_target")); + _res = single_subscript_attribute_target_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_13[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "single_subscript_attribute_target")); } - for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_19_type, _seq); + _res = NULL; + done: p->level--; - return _seq; + return _res; } -// _gather_18: NAME _loop0_19 -static asdl_seq * -_gather_18_rule(Parser *p) +// _tmp_14: '=' annotated_rhs +static void * +_tmp_14_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; return NULL; } - asdl_seq * _res = NULL; + void * _res = NULL; int _mark = p->mark; - { // NAME _loop0_19 + { // '=' annotated_rhs if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_18[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME _loop0_19")); - expr_ty elem; - asdl_seq * seq; + D(fprintf(stderr, "%*c> _tmp_14[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'=' annotated_rhs")); + Token * _literal; + expr_ty d; if ( - (elem = _PyPegen_name_token(p)) // NAME + (_literal = _PyPegen_expect_token(p, 22)) // token='=' && - (seq = _loop0_19_rule(p)) // _loop0_19 + (d = annotated_rhs_rule(p)) // annotated_rhs ) { - D(fprintf(stderr, "%*c+ _gather_18[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME _loop0_19")); - _res = _PyPegen_seq_insert_in_front(p, elem, seq); + D(fprintf(stderr, "%*c+ _tmp_14[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'=' annotated_rhs")); + _res = d; + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_18[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NAME _loop0_19")); + D(fprintf(stderr, "%*c%s _tmp_14[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'=' annotated_rhs")); } _res = NULL; done: @@ -24702,13 +25790,12 @@ _gather_18_rule(Parser *p) return _res; } -// _loop0_21: ',' NAME +// _loop1_15: (star_targets '=') static asdl_seq * -_loop0_21_rule(Parser *p) +_loop1_15_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -24716,7 +25803,6 @@ _loop0_21_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -24726,27 +25812,18 @@ _loop0_21_rule(Parser *p) } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; - { // ',' NAME + { // (star_targets '=') if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_21[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' NAME")); - Token * _literal; - expr_ty elem; + D(fprintf(stderr, "%*c> _loop1_15[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')")); + void *_tmp_247_var; while ( - (_literal = _PyPegen_expect_token(p, 12)) // token=',' - && - (elem = _PyPegen_name_token(p)) // NAME + (_tmp_247_var = _tmp_247_rule(p)) // star_targets '=' ) { - _res = elem; - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - PyMem_Free(_children); - p->level--; - return NULL; - } + _res = _tmp_247_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -24763,8 +25840,13 @@ _loop0_21_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_21[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' NAME")); + D(fprintf(stderr, "%*c%s _loop1_15[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(star_targets '=')")); + } + if (_n == 0 || p->error_indicator) { + PyMem_Free(_children); + p->level--; + return NULL; } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { @@ -24776,46 +25858,60 @@ _loop0_21_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_21_type, _seq); p->level--; return _seq; } -// _gather_20: NAME _loop0_21 -static asdl_seq * -_gather_20_rule(Parser *p) +// _tmp_16: yield_expr | star_expressions +static void * +_tmp_16_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; return NULL; } - asdl_seq * _res = NULL; + void * _res = NULL; int _mark = p->mark; - { // NAME _loop0_21 + { // yield_expr if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_20[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME _loop0_21")); - expr_ty elem; - asdl_seq * seq; + D(fprintf(stderr, "%*c> _tmp_16[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); + expr_ty yield_expr_var; if ( - (elem = _PyPegen_name_token(p)) // NAME - && - (seq = _loop0_21_rule(p)) // _loop0_21 + (yield_expr_var = yield_expr_rule(p)) // yield_expr ) { - D(fprintf(stderr, "%*c+ _gather_20[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME _loop0_21")); - _res = _PyPegen_seq_insert_in_front(p, elem, seq); + D(fprintf(stderr, "%*c+ _tmp_16[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); + _res = yield_expr_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_16[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "yield_expr")); + } + { // star_expressions + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_16[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); + expr_ty star_expressions_var; + if ( + (star_expressions_var = star_expressions_rule(p)) // star_expressions + ) + { + D(fprintf(stderr, "%*c+ _tmp_16[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); + _res = star_expressions_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_20[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NAME _loop0_21")); + D(fprintf(stderr, "%*c%s _tmp_16[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions")); } _res = NULL; done: @@ -24823,13 +25919,12 @@ _gather_20_rule(Parser *p) return _res; } -// _tmp_22: ';' | NEWLINE +// _tmp_17: yield_expr | star_expressions static void * -_tmp_22_rule(Parser *p) +_tmp_17_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -24837,43 +25932,43 @@ _tmp_22_rule(Parser *p) } void * _res = NULL; int _mark = p->mark; - { // ';' + { // yield_expr if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_22[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "';'")); - Token * _literal; + D(fprintf(stderr, "%*c> _tmp_17[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); + expr_ty yield_expr_var; if ( - (_literal = _PyPegen_expect_token(p, 13)) // token=';' + (yield_expr_var = yield_expr_rule(p)) // yield_expr ) { - D(fprintf(stderr, "%*c+ _tmp_22[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "';'")); - _res = _literal; + D(fprintf(stderr, "%*c+ _tmp_17[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); + _res = yield_expr_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_22[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "';'")); + D(fprintf(stderr, "%*c%s _tmp_17[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "yield_expr")); } - { // NEWLINE + { // star_expressions if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_22[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NEWLINE")); - Token * newline_var; + D(fprintf(stderr, "%*c> _tmp_17[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); + expr_ty star_expressions_var; if ( - (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' + (star_expressions_var = star_expressions_rule(p)) // star_expressions ) { - D(fprintf(stderr, "%*c+ _tmp_22[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NEWLINE")); - _res = newline_var; + D(fprintf(stderr, "%*c+ _tmp_17[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); + _res = star_expressions_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_22[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NEWLINE")); + D(fprintf(stderr, "%*c%s _tmp_17[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions")); } _res = NULL; done: @@ -24881,13 +25976,12 @@ _tmp_22_rule(Parser *p) return _res; } -// _tmp_23: ',' expression +// _tmp_18: 'from' expression static void * -_tmp_23_rule(Parser *p) +_tmp_18_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -24895,21 +25989,21 @@ _tmp_23_rule(Parser *p) } void * _res = NULL; int _mark = p->mark; - { // ',' expression + { // 'from' expression if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_23[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression")); - Token * _literal; + D(fprintf(stderr, "%*c> _tmp_18[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'from' expression")); + Token * _keyword; expr_ty z; if ( - (_literal = _PyPegen_expect_token(p, 12)) // token=',' + (_keyword = _PyPegen_expect_token(p, 608)) // token='from' && (z = expression_rule(p)) // expression ) { - D(fprintf(stderr, "%*c+ _tmp_23[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' expression")); + D(fprintf(stderr, "%*c+ _tmp_18[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'from' expression")); _res = z; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -24919,8 +26013,8 @@ _tmp_23_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_23[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' expression")); + D(fprintf(stderr, "%*c%s _tmp_18[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'from' expression")); } _res = NULL; done: @@ -24928,13 +26022,12 @@ _tmp_23_rule(Parser *p) return _res; } -// _loop0_24: ('.' | '...') +// _loop0_20: ',' NAME static asdl_seq * -_loop0_24_rule(Parser *p) +_loop0_20_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -24942,7 +26035,6 @@ _loop0_24_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -24952,18 +26044,27 @@ _loop0_24_rule(Parser *p) } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; - { // ('.' | '...') + { // ',' NAME if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_24[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('.' | '...')")); - void *_tmp_223_var; + D(fprintf(stderr, "%*c> _loop0_20[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' NAME")); + Token * _literal; + expr_ty elem; while ( - (_tmp_223_var = _tmp_223_rule(p)) // '.' | '...' + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (elem = _PyPegen_name_token(p)) // NAME ) { - _res = _tmp_223_var; + _res = elem; + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + PyMem_Free(_children); + p->level--; + return NULL; + } if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -24980,8 +26081,8 @@ _loop0_24_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_24[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "('.' | '...')")); + D(fprintf(stderr, "%*c%s _loop0_20[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' NAME")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { @@ -24993,55 +26094,102 @@ _loop0_24_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_24_type, _seq); p->level--; return _seq; } -// _loop1_25: ('.' | '...') +// _gather_19: NAME _loop0_20 static asdl_seq * -_loop1_25_rule(Parser *p) +_gather_19_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; return NULL; } - void *_res = NULL; + asdl_seq * _res = NULL; int _mark = p->mark; - int _start_mark = p->mark; - void **_children = PyMem_Malloc(sizeof(void *)); - if (!_children) { - p->error_indicator = 1; - PyErr_NoMemory(); - p->level--; - return NULL; - } - Py_ssize_t _children_capacity = 1; - Py_ssize_t _n = 0; - { // ('.' | '...') + { // NAME _loop0_20 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_25[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('.' | '...')")); - void *_tmp_224_var; - while ( - (_tmp_224_var = _tmp_224_rule(p)) // '.' | '...' + D(fprintf(stderr, "%*c> _gather_19[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME _loop0_20")); + expr_ty elem; + asdl_seq * seq; + if ( + (elem = _PyPegen_name_token(p)) // NAME + && + (seq = _loop0_20_rule(p)) // _loop0_20 ) { - _res = _tmp_224_var; - if (_n == _children_capacity) { - _children_capacity *= 2; - void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); - if (!_new_children) { - PyMem_Free(_children); - p->error_indicator = 1; - PyErr_NoMemory(); - p->level--; + D(fprintf(stderr, "%*c+ _gather_19[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME _loop0_20")); + _res = _PyPegen_seq_insert_in_front(p, elem, seq); + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _gather_19[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NAME _loop0_20")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop0_22: ',' NAME +static asdl_seq * +_loop0_22_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void *_res = NULL; + int _mark = p->mark; + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // ',' NAME + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_22[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' NAME")); + Token * _literal; + expr_ty elem; + while ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (elem = _PyPegen_name_token(p)) // NAME + ) + { + _res = elem; + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + PyMem_Free(_children); + p->level--; + return NULL; + } + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; return NULL; } _children = _new_children; @@ -25050,14 +26198,220 @@ _loop1_25_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_25[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "('.' | '...')")); + D(fprintf(stderr, "%*c%s _loop0_22[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' NAME")); } - if (_n == 0 || p->error_indicator) { + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); + if (!_seq) { PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); + PyMem_Free(_children); + p->level--; + return _seq; +} + +// _gather_21: NAME _loop0_22 +static asdl_seq * +_gather_21_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_seq * _res = NULL; + int _mark = p->mark; + { // NAME _loop0_22 + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _gather_21[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME _loop0_22")); + expr_ty elem; + asdl_seq * seq; + if ( + (elem = _PyPegen_name_token(p)) // NAME + && + (seq = _loop0_22_rule(p)) // _loop0_22 + ) + { + D(fprintf(stderr, "%*c+ _gather_21[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME _loop0_22")); + _res = _PyPegen_seq_insert_in_front(p, elem, seq); + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _gather_21[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NAME _loop0_22")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_23: ';' | NEWLINE +static void * +_tmp_23_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // ';' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_23[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "';'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 13)) // token=';' + ) + { + D(fprintf(stderr, "%*c+ _tmp_23[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "';'")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_23[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "';'")); + } + { // NEWLINE + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_23[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NEWLINE")); + Token * newline_var; + if ( + (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' + ) + { + D(fprintf(stderr, "%*c+ _tmp_23[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NEWLINE")); + _res = newline_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_23[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NEWLINE")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_24: ',' expression +static void * +_tmp_24_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // ',' expression + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_24[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression")); + Token * _literal; + expr_ty z; + if ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (z = expression_rule(p)) // expression + ) + { + D(fprintf(stderr, "%*c+ _tmp_24[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' expression")); + _res = z; + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + p->level--; + return NULL; + } + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_24[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' expression")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop0_25: ('.' | '...') +static asdl_seq * +_loop0_25_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void *_res = NULL; + int _mark = p->mark; + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { + p->error_indicator = 1; + PyErr_NoMemory(); p->level--; return NULL; } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // ('.' | '...') + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_25[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('.' | '...')")); + void *_tmp_248_var; + while ( + (_tmp_248_var = _tmp_248_rule(p)) // '.' | '...' + ) + { + _res = _tmp_248_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + _children = _new_children; + } + _children[_n++] = _res; + _mark = p->mark; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _loop0_25[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "('.' | '...')")); + } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { PyMem_Free(_children); @@ -25068,18 +26422,88 @@ _loop1_25_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_25_type, _seq); p->level--; return _seq; } -// _loop0_27: ',' import_from_as_name +// _loop1_26: ('.' | '...') static asdl_seq * -_loop0_27_rule(Parser *p) +_loop1_26_rule(Parser *p) { if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void *_res = NULL; + int _mark = p->mark; + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); + p->level--; + return NULL; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // ('.' | '...') + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop1_26[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('.' | '...')")); + void *_tmp_249_var; + while ( + (_tmp_249_var = _tmp_249_rule(p)) // '.' | '...' + ) + { + _res = _tmp_249_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + _children = _new_children; + } + _children[_n++] = _res; + _mark = p->mark; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _loop1_26[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "('.' | '...')")); + } + if (_n == 0 || p->error_indicator) { + PyMem_Free(_children); + p->level--; + return NULL; + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); + PyMem_Free(_children); + p->level--; + return _seq; +} + +// _loop0_28: ',' import_from_as_name +static asdl_seq * +_loop0_28_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -25087,7 +26511,6 @@ _loop0_27_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -25102,7 +26525,7 @@ _loop0_27_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_27[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' import_from_as_name")); + D(fprintf(stderr, "%*c> _loop0_28[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' import_from_as_name")); Token * _literal; alias_ty elem; while ( @@ -25134,7 +26557,7 @@ _loop0_27_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_27[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_28[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' import_from_as_name")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -25147,18 +26570,16 @@ _loop0_27_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_27_type, _seq); p->level--; return _seq; } -// _gather_26: import_from_as_name _loop0_27 +// _gather_27: import_from_as_name _loop0_28 static asdl_seq * -_gather_26_rule(Parser *p) +_gather_27_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -25166,27 +26587,27 @@ _gather_26_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // import_from_as_name _loop0_27 + { // import_from_as_name _loop0_28 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_26[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "import_from_as_name _loop0_27")); + D(fprintf(stderr, "%*c> _gather_27[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "import_from_as_name _loop0_28")); alias_ty elem; asdl_seq * seq; if ( (elem = import_from_as_name_rule(p)) // import_from_as_name && - (seq = _loop0_27_rule(p)) // _loop0_27 + (seq = _loop0_28_rule(p)) // _loop0_28 ) { - D(fprintf(stderr, "%*c+ _gather_26[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "import_from_as_name _loop0_27")); + D(fprintf(stderr, "%*c+ _gather_27[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "import_from_as_name _loop0_28")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_26[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "import_from_as_name _loop0_27")); + D(fprintf(stderr, "%*c%s _gather_27[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "import_from_as_name _loop0_28")); } _res = NULL; done: @@ -25194,13 +26615,12 @@ _gather_26_rule(Parser *p) return _res; } -// _tmp_28: 'as' NAME +// _tmp_29: 'as' NAME static void * -_tmp_28_rule(Parser *p) +_tmp_29_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -25213,16 +26633,16 @@ _tmp_28_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_28[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c> _tmp_29[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); Token * _keyword; expr_ty z; if ( - (_keyword = _PyPegen_expect_token(p, 637)) // token='as' + (_keyword = _PyPegen_expect_token(p, 640)) // token='as' && (z = _PyPegen_name_token(p)) // NAME ) { - D(fprintf(stderr, "%*c+ _tmp_28[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c+ _tmp_29[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); _res = z; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -25232,7 +26652,7 @@ _tmp_28_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_28[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_29[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); } _res = NULL; @@ -25241,13 +26661,12 @@ _tmp_28_rule(Parser *p) return _res; } -// _loop0_30: ',' dotted_as_name +// _loop0_31: ',' dotted_as_name static asdl_seq * -_loop0_30_rule(Parser *p) +_loop0_31_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -25255,7 +26674,6 @@ _loop0_30_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -25270,7 +26688,7 @@ _loop0_30_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_30[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' dotted_as_name")); + D(fprintf(stderr, "%*c> _loop0_31[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' dotted_as_name")); Token * _literal; alias_ty elem; while ( @@ -25302,7 +26720,7 @@ _loop0_30_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_30[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_31[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' dotted_as_name")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -25315,18 +26733,16 @@ _loop0_30_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_30_type, _seq); p->level--; return _seq; } -// _gather_29: dotted_as_name _loop0_30 +// _gather_30: dotted_as_name _loop0_31 static asdl_seq * -_gather_29_rule(Parser *p) +_gather_30_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -25334,27 +26750,27 @@ _gather_29_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // dotted_as_name _loop0_30 + { // dotted_as_name _loop0_31 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_29[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "dotted_as_name _loop0_30")); + D(fprintf(stderr, "%*c> _gather_30[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "dotted_as_name _loop0_31")); alias_ty elem; asdl_seq * seq; if ( (elem = dotted_as_name_rule(p)) // dotted_as_name && - (seq = _loop0_30_rule(p)) // _loop0_30 + (seq = _loop0_31_rule(p)) // _loop0_31 ) { - D(fprintf(stderr, "%*c+ _gather_29[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "dotted_as_name _loop0_30")); + D(fprintf(stderr, "%*c+ _gather_30[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "dotted_as_name _loop0_31")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_29[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "dotted_as_name _loop0_30")); + D(fprintf(stderr, "%*c%s _gather_30[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "dotted_as_name _loop0_31")); } _res = NULL; done: @@ -25362,13 +26778,12 @@ _gather_29_rule(Parser *p) return _res; } -// _tmp_31: 'as' NAME +// _tmp_32: 'as' NAME static void * -_tmp_31_rule(Parser *p) +_tmp_32_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -25381,16 +26796,16 @@ _tmp_31_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_31[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c> _tmp_32[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); Token * _keyword; expr_ty z; if ( - (_keyword = _PyPegen_expect_token(p, 637)) // token='as' + (_keyword = _PyPegen_expect_token(p, 640)) // token='as' && (z = _PyPegen_name_token(p)) // NAME ) { - D(fprintf(stderr, "%*c+ _tmp_31[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c+ _tmp_32[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); _res = z; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -25400,7 +26815,7 @@ _tmp_31_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_31[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_32[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); } _res = NULL; @@ -25409,13 +26824,12 @@ _tmp_31_rule(Parser *p) return _res; } -// _loop1_32: ('@' named_expression NEWLINE) +// _loop1_33: ('@' named_expression NEWLINE) static asdl_seq * -_loop1_32_rule(Parser *p) +_loop1_33_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -25423,7 +26837,6 @@ _loop1_32_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -25438,13 +26851,13 @@ _loop1_32_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_32[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('@' named_expression NEWLINE)")); - void *_tmp_225_var; + D(fprintf(stderr, "%*c> _loop1_33[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('@' named_expression NEWLINE)")); + void *_tmp_250_var; while ( - (_tmp_225_var = _tmp_225_rule(p)) // '@' named_expression NEWLINE + (_tmp_250_var = _tmp_250_rule(p)) // '@' named_expression NEWLINE ) { - _res = _tmp_225_var; + _res = _tmp_250_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -25461,7 +26874,7 @@ _loop1_32_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_32[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_33[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "('@' named_expression NEWLINE)")); } if (_n == 0 || p->error_indicator) { @@ -25479,18 +26892,16 @@ _loop1_32_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_32_type, _seq); p->level--; return _seq; } -// _tmp_33: '(' arguments? ')' +// _tmp_34: '(' arguments? ')' static void * -_tmp_33_rule(Parser *p) +_tmp_34_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -25503,7 +26914,7 @@ _tmp_33_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_33[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'")); + D(fprintf(stderr, "%*c> _tmp_34[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'")); Token * _literal; Token * _literal_1; void *z; @@ -25515,7 +26926,7 @@ _tmp_33_rule(Parser *p) (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' ) { - D(fprintf(stderr, "%*c+ _tmp_33[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'")); + D(fprintf(stderr, "%*c+ _tmp_34[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'")); _res = z; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -25525,7 +26936,7 @@ _tmp_33_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_33[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_34[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'(' arguments? ')'")); } _res = NULL; @@ -25534,13 +26945,12 @@ _tmp_33_rule(Parser *p) return _res; } -// _tmp_34: '->' expression +// _tmp_35: '->' expression static void * -_tmp_34_rule(Parser *p) +_tmp_35_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -25553,7 +26963,7 @@ _tmp_34_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_34[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'->' expression")); + D(fprintf(stderr, "%*c> _tmp_35[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'->' expression")); Token * _literal; expr_ty z; if ( @@ -25562,7 +26972,7 @@ _tmp_34_rule(Parser *p) (z = expression_rule(p)) // expression ) { - D(fprintf(stderr, "%*c+ _tmp_34[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'->' expression")); + D(fprintf(stderr, "%*c+ _tmp_35[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'->' expression")); _res = z; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -25572,7 +26982,7 @@ _tmp_34_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_34[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_35[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'->' expression")); } _res = NULL; @@ -25581,13 +26991,12 @@ _tmp_34_rule(Parser *p) return _res; } -// _tmp_35: '->' expression +// _tmp_36: '->' expression static void * -_tmp_35_rule(Parser *p) +_tmp_36_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -25600,7 +27009,7 @@ _tmp_35_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_35[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'->' expression")); + D(fprintf(stderr, "%*c> _tmp_36[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'->' expression")); Token * _literal; expr_ty z; if ( @@ -25609,7 +27018,7 @@ _tmp_35_rule(Parser *p) (z = expression_rule(p)) // expression ) { - D(fprintf(stderr, "%*c+ _tmp_35[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'->' expression")); + D(fprintf(stderr, "%*c+ _tmp_36[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'->' expression")); _res = z; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -25619,7 +27028,7 @@ _tmp_35_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_35[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_36[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'->' expression")); } _res = NULL; @@ -25628,13 +27037,12 @@ _tmp_35_rule(Parser *p) return _res; } -// _loop0_36: param_no_default +// _loop0_37: param_no_default static asdl_seq * -_loop0_36_rule(Parser *p) +_loop0_37_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -25642,7 +27050,6 @@ _loop0_36_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -25657,7 +27064,7 @@ _loop0_36_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_36[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); + D(fprintf(stderr, "%*c> _loop0_37[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); arg_ty param_no_default_var; while ( (param_no_default_var = param_no_default_rule(p)) // param_no_default @@ -25680,7 +27087,7 @@ _loop0_36_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_36[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_37[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -25693,18 +27100,16 @@ _loop0_36_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_36_type, _seq); p->level--; return _seq; } -// _loop0_37: param_with_default +// _loop0_38: param_with_default static asdl_seq * -_loop0_37_rule(Parser *p) +_loop0_38_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -25712,7 +27117,6 @@ _loop0_37_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -25727,7 +27131,7 @@ _loop0_37_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_37[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default")); + D(fprintf(stderr, "%*c> _loop0_38[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default")); NameDefaultPair* param_with_default_var; while ( (param_with_default_var = param_with_default_rule(p)) // param_with_default @@ -25750,7 +27154,7 @@ _loop0_37_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_37[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_38[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_with_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -25763,18 +27167,16 @@ _loop0_37_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_37_type, _seq); p->level--; return _seq; } -// _loop0_38: param_with_default +// _loop0_39: param_with_default static asdl_seq * -_loop0_38_rule(Parser *p) +_loop0_39_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -25782,7 +27184,6 @@ _loop0_38_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -25797,7 +27198,7 @@ _loop0_38_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_38[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default")); + D(fprintf(stderr, "%*c> _loop0_39[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default")); NameDefaultPair* param_with_default_var; while ( (param_with_default_var = param_with_default_rule(p)) // param_with_default @@ -25820,7 +27221,7 @@ _loop0_38_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_38[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_39[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_with_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -25833,18 +27234,16 @@ _loop0_38_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_38_type, _seq); p->level--; return _seq; } -// _loop1_39: param_no_default +// _loop1_40: param_no_default static asdl_seq * -_loop1_39_rule(Parser *p) +_loop1_40_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -25852,7 +27251,6 @@ _loop1_39_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -25867,7 +27265,7 @@ _loop1_39_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_39[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); + D(fprintf(stderr, "%*c> _loop1_40[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); arg_ty param_no_default_var; while ( (param_no_default_var = param_no_default_rule(p)) // param_no_default @@ -25890,7 +27288,7 @@ _loop1_39_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_39[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_40[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); } if (_n == 0 || p->error_indicator) { @@ -25908,18 +27306,16 @@ _loop1_39_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_39_type, _seq); p->level--; return _seq; } -// _loop0_40: param_with_default +// _loop0_41: param_with_default static asdl_seq * -_loop0_40_rule(Parser *p) +_loop0_41_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -25927,7 +27323,6 @@ _loop0_40_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -25942,7 +27337,7 @@ _loop0_40_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_40[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default")); + D(fprintf(stderr, "%*c> _loop0_41[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default")); NameDefaultPair* param_with_default_var; while ( (param_with_default_var = param_with_default_rule(p)) // param_with_default @@ -25965,7 +27360,7 @@ _loop0_40_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_40[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_41[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_with_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -25978,18 +27373,16 @@ _loop0_40_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_40_type, _seq); p->level--; return _seq; } -// _loop1_41: param_with_default +// _loop1_42: param_with_default static asdl_seq * -_loop1_41_rule(Parser *p) +_loop1_42_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -25997,7 +27390,6 @@ _loop1_41_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -26012,7 +27404,7 @@ _loop1_41_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_41[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default")); + D(fprintf(stderr, "%*c> _loop1_42[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default")); NameDefaultPair* param_with_default_var; while ( (param_with_default_var = param_with_default_rule(p)) // param_with_default @@ -26035,7 +27427,7 @@ _loop1_41_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_41[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_42[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_with_default")); } if (_n == 0 || p->error_indicator) { @@ -26053,18 +27445,16 @@ _loop1_41_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_41_type, _seq); p->level--; return _seq; } -// _loop1_42: param_no_default +// _loop1_43: param_no_default static asdl_seq * -_loop1_42_rule(Parser *p) +_loop1_43_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -26072,7 +27462,6 @@ _loop1_42_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -26087,7 +27476,7 @@ _loop1_42_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_42[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); + D(fprintf(stderr, "%*c> _loop1_43[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); arg_ty param_no_default_var; while ( (param_no_default_var = param_no_default_rule(p)) // param_no_default @@ -26110,7 +27499,7 @@ _loop1_42_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_42[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_43[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); } if (_n == 0 || p->error_indicator) { @@ -26128,18 +27517,16 @@ _loop1_42_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_42_type, _seq); p->level--; return _seq; } -// _loop1_43: param_no_default +// _loop1_44: param_no_default static asdl_seq * -_loop1_43_rule(Parser *p) +_loop1_44_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -26147,7 +27534,6 @@ _loop1_43_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -26162,7 +27548,7 @@ _loop1_43_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_43[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); + D(fprintf(stderr, "%*c> _loop1_44[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); arg_ty param_no_default_var; while ( (param_no_default_var = param_no_default_rule(p)) // param_no_default @@ -26185,7 +27571,7 @@ _loop1_43_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_43[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_44[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); } if (_n == 0 || p->error_indicator) { @@ -26203,18 +27589,16 @@ _loop1_43_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_43_type, _seq); p->level--; return _seq; } -// _loop0_44: param_no_default +// _loop0_45: param_no_default static asdl_seq * -_loop0_44_rule(Parser *p) +_loop0_45_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -26222,7 +27606,6 @@ _loop0_44_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -26237,7 +27620,7 @@ _loop0_44_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_44[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); + D(fprintf(stderr, "%*c> _loop0_45[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); arg_ty param_no_default_var; while ( (param_no_default_var = param_no_default_rule(p)) // param_no_default @@ -26260,7 +27643,7 @@ _loop0_44_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_44[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_45[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -26273,18 +27656,16 @@ _loop0_44_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_44_type, _seq); p->level--; return _seq; } -// _loop1_45: param_with_default +// _loop1_46: param_with_default static asdl_seq * -_loop1_45_rule(Parser *p) +_loop1_46_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -26292,7 +27673,6 @@ _loop1_45_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -26307,7 +27687,7 @@ _loop1_45_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_45[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default")); + D(fprintf(stderr, "%*c> _loop1_46[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default")); NameDefaultPair* param_with_default_var; while ( (param_with_default_var = param_with_default_rule(p)) // param_with_default @@ -26330,7 +27710,7 @@ _loop1_45_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_45[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_46[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_with_default")); } if (_n == 0 || p->error_indicator) { @@ -26348,18 +27728,16 @@ _loop1_45_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_45_type, _seq); p->level--; return _seq; } -// _loop0_46: param_no_default +// _loop0_47: param_no_default static asdl_seq * -_loop0_46_rule(Parser *p) +_loop0_47_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -26367,7 +27745,6 @@ _loop0_46_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -26382,7 +27759,7 @@ _loop0_46_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_46[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); + D(fprintf(stderr, "%*c> _loop0_47[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); arg_ty param_no_default_var; while ( (param_no_default_var = param_no_default_rule(p)) // param_no_default @@ -26405,7 +27782,7 @@ _loop0_46_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_46[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_47[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -26418,18 +27795,16 @@ _loop0_46_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_46_type, _seq); p->level--; return _seq; } -// _loop1_47: param_with_default +// _loop1_48: param_with_default static asdl_seq * -_loop1_47_rule(Parser *p) +_loop1_48_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -26437,7 +27812,6 @@ _loop1_47_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -26452,7 +27826,7 @@ _loop1_47_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_47[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default")); + D(fprintf(stderr, "%*c> _loop1_48[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default")); NameDefaultPair* param_with_default_var; while ( (param_with_default_var = param_with_default_rule(p)) // param_with_default @@ -26475,7 +27849,7 @@ _loop1_47_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_47[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_48[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_with_default")); } if (_n == 0 || p->error_indicator) { @@ -26493,18 +27867,16 @@ _loop1_47_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_47_type, _seq); p->level--; return _seq; } -// _loop0_48: param_maybe_default +// _loop0_49: param_maybe_default static asdl_seq * -_loop0_48_rule(Parser *p) +_loop0_49_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -26512,7 +27884,6 @@ _loop0_48_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -26527,7 +27898,7 @@ _loop0_48_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_48[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); + D(fprintf(stderr, "%*c> _loop0_49[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); NameDefaultPair* param_maybe_default_var; while ( (param_maybe_default_var = param_maybe_default_rule(p)) // param_maybe_default @@ -26550,7 +27921,7 @@ _loop0_48_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_48[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_49[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_maybe_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -26563,18 +27934,16 @@ _loop0_48_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_48_type, _seq); p->level--; return _seq; } -// _loop0_49: param_maybe_default +// _loop0_50: param_maybe_default static asdl_seq * -_loop0_49_rule(Parser *p) +_loop0_50_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -26582,7 +27951,6 @@ _loop0_49_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -26597,7 +27965,7 @@ _loop0_49_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_49[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); + D(fprintf(stderr, "%*c> _loop0_50[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); NameDefaultPair* param_maybe_default_var; while ( (param_maybe_default_var = param_maybe_default_rule(p)) // param_maybe_default @@ -26620,7 +27988,7 @@ _loop0_49_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_49[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_50[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_maybe_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -26633,18 +28001,16 @@ _loop0_49_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_49_type, _seq); p->level--; return _seq; } -// _loop1_50: param_maybe_default +// _loop1_51: param_maybe_default static asdl_seq * -_loop1_50_rule(Parser *p) +_loop1_51_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -26652,7 +28018,6 @@ _loop1_50_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -26667,7 +28032,7 @@ _loop1_50_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_50[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); + D(fprintf(stderr, "%*c> _loop1_51[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); NameDefaultPair* param_maybe_default_var; while ( (param_maybe_default_var = param_maybe_default_rule(p)) // param_maybe_default @@ -26690,7 +28055,7 @@ _loop1_50_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_50[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_51[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_maybe_default")); } if (_n == 0 || p->error_indicator) { @@ -26708,18 +28073,16 @@ _loop1_50_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_50_type, _seq); p->level--; return _seq; } -// _loop0_52: ',' with_item +// _loop0_53: ',' with_item static asdl_seq * -_loop0_52_rule(Parser *p) +_loop0_53_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -26727,7 +28090,6 @@ _loop0_52_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -26742,7 +28104,7 @@ _loop0_52_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_52[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' with_item")); + D(fprintf(stderr, "%*c> _loop0_53[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' with_item")); Token * _literal; withitem_ty elem; while ( @@ -26774,7 +28136,7 @@ _loop0_52_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_52[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_53[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' with_item")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -26787,18 +28149,16 @@ _loop0_52_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_52_type, _seq); p->level--; return _seq; } -// _gather_51: with_item _loop0_52 +// _gather_52: with_item _loop0_53 static asdl_seq * -_gather_51_rule(Parser *p) +_gather_52_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -26806,27 +28166,27 @@ _gather_51_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // with_item _loop0_52 + { // with_item _loop0_53 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_51[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "with_item _loop0_52")); + D(fprintf(stderr, "%*c> _gather_52[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "with_item _loop0_53")); withitem_ty elem; asdl_seq * seq; if ( (elem = with_item_rule(p)) // with_item && - (seq = _loop0_52_rule(p)) // _loop0_52 + (seq = _loop0_53_rule(p)) // _loop0_53 ) { - D(fprintf(stderr, "%*c+ _gather_51[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "with_item _loop0_52")); + D(fprintf(stderr, "%*c+ _gather_52[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "with_item _loop0_53")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_51[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "with_item _loop0_52")); + D(fprintf(stderr, "%*c%s _gather_52[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "with_item _loop0_53")); } _res = NULL; done: @@ -26834,13 +28194,12 @@ _gather_51_rule(Parser *p) return _res; } -// _loop0_54: ',' with_item +// _loop0_55: ',' with_item static asdl_seq * -_loop0_54_rule(Parser *p) +_loop0_55_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -26848,7 +28207,6 @@ _loop0_54_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -26863,7 +28221,7 @@ _loop0_54_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_54[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' with_item")); + D(fprintf(stderr, "%*c> _loop0_55[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' with_item")); Token * _literal; withitem_ty elem; while ( @@ -26895,7 +28253,7 @@ _loop0_54_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_54[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_55[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' with_item")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -26908,18 +28266,16 @@ _loop0_54_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_54_type, _seq); p->level--; return _seq; } -// _gather_53: with_item _loop0_54 +// _gather_54: with_item _loop0_55 static asdl_seq * -_gather_53_rule(Parser *p) +_gather_54_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -26927,27 +28283,27 @@ _gather_53_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // with_item _loop0_54 + { // with_item _loop0_55 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_53[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "with_item _loop0_54")); + D(fprintf(stderr, "%*c> _gather_54[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "with_item _loop0_55")); withitem_ty elem; asdl_seq * seq; if ( (elem = with_item_rule(p)) // with_item && - (seq = _loop0_54_rule(p)) // _loop0_54 + (seq = _loop0_55_rule(p)) // _loop0_55 ) { - D(fprintf(stderr, "%*c+ _gather_53[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "with_item _loop0_54")); + D(fprintf(stderr, "%*c+ _gather_54[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "with_item _loop0_55")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_53[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "with_item _loop0_54")); + D(fprintf(stderr, "%*c%s _gather_54[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "with_item _loop0_55")); } _res = NULL; done: @@ -26955,13 +28311,12 @@ _gather_53_rule(Parser *p) return _res; } -// _loop0_56: ',' with_item +// _loop0_57: ',' with_item static asdl_seq * -_loop0_56_rule(Parser *p) +_loop0_57_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -26969,7 +28324,6 @@ _loop0_56_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -26984,7 +28338,7 @@ _loop0_56_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_56[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' with_item")); + D(fprintf(stderr, "%*c> _loop0_57[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' with_item")); Token * _literal; withitem_ty elem; while ( @@ -27016,7 +28370,7 @@ _loop0_56_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_56[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_57[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' with_item")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -27029,18 +28383,16 @@ _loop0_56_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_56_type, _seq); p->level--; return _seq; } -// _gather_55: with_item _loop0_56 +// _gather_56: with_item _loop0_57 static asdl_seq * -_gather_55_rule(Parser *p) +_gather_56_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -27048,27 +28400,27 @@ _gather_55_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // with_item _loop0_56 + { // with_item _loop0_57 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_55[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "with_item _loop0_56")); + D(fprintf(stderr, "%*c> _gather_56[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "with_item _loop0_57")); withitem_ty elem; asdl_seq * seq; if ( (elem = with_item_rule(p)) // with_item && - (seq = _loop0_56_rule(p)) // _loop0_56 + (seq = _loop0_57_rule(p)) // _loop0_57 ) { - D(fprintf(stderr, "%*c+ _gather_55[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "with_item _loop0_56")); + D(fprintf(stderr, "%*c+ _gather_56[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "with_item _loop0_57")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_55[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "with_item _loop0_56")); + D(fprintf(stderr, "%*c%s _gather_56[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "with_item _loop0_57")); } _res = NULL; done: @@ -27076,13 +28428,12 @@ _gather_55_rule(Parser *p) return _res; } -// _loop0_58: ',' with_item +// _loop0_59: ',' with_item static asdl_seq * -_loop0_58_rule(Parser *p) +_loop0_59_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -27090,7 +28441,6 @@ _loop0_58_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -27105,7 +28455,7 @@ _loop0_58_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_58[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' with_item")); + D(fprintf(stderr, "%*c> _loop0_59[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' with_item")); Token * _literal; withitem_ty elem; while ( @@ -27137,7 +28487,7 @@ _loop0_58_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_58[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_59[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' with_item")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -27150,18 +28500,16 @@ _loop0_58_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_58_type, _seq); p->level--; return _seq; } -// _gather_57: with_item _loop0_58 +// _gather_58: with_item _loop0_59 static asdl_seq * -_gather_57_rule(Parser *p) +_gather_58_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -27169,27 +28517,27 @@ _gather_57_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // with_item _loop0_58 + { // with_item _loop0_59 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_57[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "with_item _loop0_58")); + D(fprintf(stderr, "%*c> _gather_58[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "with_item _loop0_59")); withitem_ty elem; asdl_seq * seq; if ( (elem = with_item_rule(p)) // with_item && - (seq = _loop0_58_rule(p)) // _loop0_58 + (seq = _loop0_59_rule(p)) // _loop0_59 ) { - D(fprintf(stderr, "%*c+ _gather_57[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "with_item _loop0_58")); + D(fprintf(stderr, "%*c+ _gather_58[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "with_item _loop0_59")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_57[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "with_item _loop0_58")); + D(fprintf(stderr, "%*c%s _gather_58[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "with_item _loop0_59")); } _res = NULL; done: @@ -27197,13 +28545,12 @@ _gather_57_rule(Parser *p) return _res; } -// _tmp_59: ',' | ')' | ':' +// _tmp_60: ',' | ')' | ':' static void * -_tmp_59_rule(Parser *p) +_tmp_60_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -27216,18 +28563,18 @@ _tmp_59_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_59[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c> _tmp_60[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' ) { - D(fprintf(stderr, "%*c+ _tmp_59[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c+ _tmp_60[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_59[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_60[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); } { // ')' @@ -27235,18 +28582,18 @@ _tmp_59_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_59[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c> _tmp_60[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 8)) // token=')' ) { - D(fprintf(stderr, "%*c+ _tmp_59[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c+ _tmp_60[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_59[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_60[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "')'")); } { // ':' @@ -27254,18 +28601,18 @@ _tmp_59_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_59[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c> _tmp_60[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 11)) // token=':' ) { - D(fprintf(stderr, "%*c+ _tmp_59[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c+ _tmp_60[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_59[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_60[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); } _res = NULL; @@ -27274,13 +28621,12 @@ _tmp_59_rule(Parser *p) return _res; } -// _loop1_60: except_block +// _loop1_61: except_block static asdl_seq * -_loop1_60_rule(Parser *p) +_loop1_61_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -27288,7 +28634,6 @@ _loop1_60_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -27303,7 +28648,7 @@ _loop1_60_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_60[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "except_block")); + D(fprintf(stderr, "%*c> _loop1_61[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "except_block")); excepthandler_ty except_block_var; while ( (except_block_var = except_block_rule(p)) // except_block @@ -27326,7 +28671,7 @@ _loop1_60_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_60[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_61[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "except_block")); } if (_n == 0 || p->error_indicator) { @@ -27344,18 +28689,16 @@ _loop1_60_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_60_type, _seq); p->level--; return _seq; } -// _loop1_61: except_star_block +// _loop1_62: except_star_block static asdl_seq * -_loop1_61_rule(Parser *p) +_loop1_62_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -27363,7 +28706,6 @@ _loop1_61_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -27378,7 +28720,7 @@ _loop1_61_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_61[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "except_star_block")); + D(fprintf(stderr, "%*c> _loop1_62[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "except_star_block")); excepthandler_ty except_star_block_var; while ( (except_star_block_var = except_star_block_rule(p)) // except_star_block @@ -27401,7 +28743,7 @@ _loop1_61_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_61[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_62[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "except_star_block")); } if (_n == 0 || p->error_indicator) { @@ -27419,18 +28761,16 @@ _loop1_61_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_61_type, _seq); p->level--; return _seq; } -// _tmp_62: 'as' NAME +// _tmp_63: 'as' NAME static void * -_tmp_62_rule(Parser *p) +_tmp_63_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -27443,16 +28783,16 @@ _tmp_62_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_62[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c> _tmp_63[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); Token * _keyword; expr_ty z; if ( - (_keyword = _PyPegen_expect_token(p, 637)) // token='as' + (_keyword = _PyPegen_expect_token(p, 640)) // token='as' && (z = _PyPegen_name_token(p)) // NAME ) { - D(fprintf(stderr, "%*c+ _tmp_62[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c+ _tmp_63[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); _res = z; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -27462,7 +28802,7 @@ _tmp_62_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_62[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_63[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); } _res = NULL; @@ -27471,13 +28811,12 @@ _tmp_62_rule(Parser *p) return _res; } -// _tmp_63: 'as' NAME +// _tmp_64: 'as' NAME static void * -_tmp_63_rule(Parser *p) +_tmp_64_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -27490,16 +28829,16 @@ _tmp_63_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_63[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c> _tmp_64[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); Token * _keyword; expr_ty z; if ( - (_keyword = _PyPegen_expect_token(p, 637)) // token='as' + (_keyword = _PyPegen_expect_token(p, 640)) // token='as' && (z = _PyPegen_name_token(p)) // NAME ) { - D(fprintf(stderr, "%*c+ _tmp_63[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c+ _tmp_64[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); _res = z; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -27509,7 +28848,7 @@ _tmp_63_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_63[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_64[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); } _res = NULL; @@ -27518,13 +28857,12 @@ _tmp_63_rule(Parser *p) return _res; } -// _loop1_64: case_block +// _loop1_65: case_block static asdl_seq * -_loop1_64_rule(Parser *p) +_loop1_65_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -27532,7 +28870,6 @@ _loop1_64_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -27547,7 +28884,7 @@ _loop1_64_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_64[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "case_block")); + D(fprintf(stderr, "%*c> _loop1_65[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "case_block")); match_case_ty case_block_var; while ( (case_block_var = case_block_rule(p)) // case_block @@ -27570,7 +28907,7 @@ _loop1_64_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_64[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_65[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "case_block")); } if (_n == 0 || p->error_indicator) { @@ -27588,18 +28925,16 @@ _loop1_64_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_64_type, _seq); p->level--; return _seq; } -// _loop0_66: '|' closed_pattern +// _loop0_67: '|' closed_pattern static asdl_seq * -_loop0_66_rule(Parser *p) +_loop0_67_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -27607,7 +28942,6 @@ _loop0_66_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -27622,7 +28956,7 @@ _loop0_66_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_66[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'|' closed_pattern")); + D(fprintf(stderr, "%*c> _loop0_67[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'|' closed_pattern")); Token * _literal; pattern_ty elem; while ( @@ -27654,7 +28988,7 @@ _loop0_66_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_66[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_67[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'|' closed_pattern")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -27667,18 +29001,16 @@ _loop0_66_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_66_type, _seq); p->level--; return _seq; } -// _gather_65: closed_pattern _loop0_66 +// _gather_66: closed_pattern _loop0_67 static asdl_seq * -_gather_65_rule(Parser *p) +_gather_66_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -27686,27 +29018,27 @@ _gather_65_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // closed_pattern _loop0_66 + { // closed_pattern _loop0_67 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_65[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "closed_pattern _loop0_66")); + D(fprintf(stderr, "%*c> _gather_66[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "closed_pattern _loop0_67")); pattern_ty elem; asdl_seq * seq; if ( (elem = closed_pattern_rule(p)) // closed_pattern && - (seq = _loop0_66_rule(p)) // _loop0_66 + (seq = _loop0_67_rule(p)) // _loop0_67 ) { - D(fprintf(stderr, "%*c+ _gather_65[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "closed_pattern _loop0_66")); + D(fprintf(stderr, "%*c+ _gather_66[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "closed_pattern _loop0_67")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_65[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "closed_pattern _loop0_66")); + D(fprintf(stderr, "%*c%s _gather_66[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "closed_pattern _loop0_67")); } _res = NULL; done: @@ -27714,13 +29046,12 @@ _gather_65_rule(Parser *p) return _res; } -// _tmp_67: '+' | '-' +// _tmp_68: '+' | '-' static void * -_tmp_67_rule(Parser *p) +_tmp_68_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -27733,18 +29064,18 @@ _tmp_67_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_67[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'+'")); + D(fprintf(stderr, "%*c> _tmp_68[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'+'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 14)) // token='+' ) { - D(fprintf(stderr, "%*c+ _tmp_67[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'+'")); + D(fprintf(stderr, "%*c+ _tmp_68[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'+'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_67[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_68[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'+'")); } { // '-' @@ -27752,18 +29083,18 @@ _tmp_67_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_67[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'-'")); + D(fprintf(stderr, "%*c> _tmp_68[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'-'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 15)) // token='-' ) { - D(fprintf(stderr, "%*c+ _tmp_67[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'-'")); + D(fprintf(stderr, "%*c+ _tmp_68[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'-'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_67[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_68[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'-'")); } _res = NULL; @@ -27772,13 +29103,12 @@ _tmp_67_rule(Parser *p) return _res; } -// _tmp_68: '+' | '-' +// _tmp_69: '+' | '-' static void * -_tmp_68_rule(Parser *p) +_tmp_69_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -27791,18 +29121,18 @@ _tmp_68_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_68[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'+'")); + D(fprintf(stderr, "%*c> _tmp_69[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'+'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 14)) // token='+' ) { - D(fprintf(stderr, "%*c+ _tmp_68[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'+'")); + D(fprintf(stderr, "%*c+ _tmp_69[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'+'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_68[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_69[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'+'")); } { // '-' @@ -27810,18 +29140,18 @@ _tmp_68_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_68[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'-'")); + D(fprintf(stderr, "%*c> _tmp_69[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'-'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 15)) // token='-' ) { - D(fprintf(stderr, "%*c+ _tmp_68[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'-'")); + D(fprintf(stderr, "%*c+ _tmp_69[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'-'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_68[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_69[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'-'")); } _res = NULL; @@ -27830,13 +29160,12 @@ _tmp_68_rule(Parser *p) return _res; } -// _tmp_69: '.' | '(' | '=' +// _tmp_70: '.' | '(' | '=' static void * -_tmp_69_rule(Parser *p) +_tmp_70_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -27849,18 +29178,18 @@ _tmp_69_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_69[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'")); + D(fprintf(stderr, "%*c> _tmp_70[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 23)) // token='.' ) { - D(fprintf(stderr, "%*c+ _tmp_69[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'")); + D(fprintf(stderr, "%*c+ _tmp_70[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_69[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_70[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'.'")); } { // '(' @@ -27868,18 +29197,18 @@ _tmp_69_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_69[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'('")); + D(fprintf(stderr, "%*c> _tmp_70[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'('")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 7)) // token='(' ) { - D(fprintf(stderr, "%*c+ _tmp_69[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'('")); + D(fprintf(stderr, "%*c+ _tmp_70[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'('")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_69[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_70[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'('")); } { // '=' @@ -27887,18 +29216,18 @@ _tmp_69_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_69[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'='")); + D(fprintf(stderr, "%*c> _tmp_70[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'='")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 22)) // token='=' ) { - D(fprintf(stderr, "%*c+ _tmp_69[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'='")); + D(fprintf(stderr, "%*c+ _tmp_70[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'='")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_69[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_70[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'='")); } _res = NULL; @@ -27907,13 +29236,12 @@ _tmp_69_rule(Parser *p) return _res; } -// _tmp_70: '.' | '(' | '=' +// _tmp_71: '.' | '(' | '=' static void * -_tmp_70_rule(Parser *p) +_tmp_71_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -27926,18 +29254,18 @@ _tmp_70_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_70[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'")); + D(fprintf(stderr, "%*c> _tmp_71[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 23)) // token='.' ) { - D(fprintf(stderr, "%*c+ _tmp_70[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'")); + D(fprintf(stderr, "%*c+ _tmp_71[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_70[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_71[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'.'")); } { // '(' @@ -27945,18 +29273,18 @@ _tmp_70_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_70[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'('")); + D(fprintf(stderr, "%*c> _tmp_71[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'('")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 7)) // token='(' ) { - D(fprintf(stderr, "%*c+ _tmp_70[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'('")); + D(fprintf(stderr, "%*c+ _tmp_71[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'('")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_70[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_71[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'('")); } { // '=' @@ -27964,18 +29292,18 @@ _tmp_70_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_70[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'='")); + D(fprintf(stderr, "%*c> _tmp_71[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'='")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 22)) // token='=' ) { - D(fprintf(stderr, "%*c+ _tmp_70[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'='")); + D(fprintf(stderr, "%*c+ _tmp_71[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'='")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_70[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_71[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'='")); } _res = NULL; @@ -27984,13 +29312,12 @@ _tmp_70_rule(Parser *p) return _res; } -// _loop0_72: ',' maybe_star_pattern +// _loop0_73: ',' maybe_star_pattern static asdl_seq * -_loop0_72_rule(Parser *p) +_loop0_73_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -27998,7 +29325,6 @@ _loop0_72_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -28013,7 +29339,7 @@ _loop0_72_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_72[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' maybe_star_pattern")); + D(fprintf(stderr, "%*c> _loop0_73[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' maybe_star_pattern")); Token * _literal; pattern_ty elem; while ( @@ -28045,7 +29371,7 @@ _loop0_72_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_72[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_73[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' maybe_star_pattern")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -28058,18 +29384,16 @@ _loop0_72_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_72_type, _seq); p->level--; return _seq; } -// _gather_71: maybe_star_pattern _loop0_72 +// _gather_72: maybe_star_pattern _loop0_73 static asdl_seq * -_gather_71_rule(Parser *p) +_gather_72_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -28077,27 +29401,27 @@ _gather_71_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // maybe_star_pattern _loop0_72 + { // maybe_star_pattern _loop0_73 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_71[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "maybe_star_pattern _loop0_72")); + D(fprintf(stderr, "%*c> _gather_72[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "maybe_star_pattern _loop0_73")); pattern_ty elem; asdl_seq * seq; if ( (elem = maybe_star_pattern_rule(p)) // maybe_star_pattern && - (seq = _loop0_72_rule(p)) // _loop0_72 + (seq = _loop0_73_rule(p)) // _loop0_73 ) { - D(fprintf(stderr, "%*c+ _gather_71[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "maybe_star_pattern _loop0_72")); + D(fprintf(stderr, "%*c+ _gather_72[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "maybe_star_pattern _loop0_73")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_71[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "maybe_star_pattern _loop0_72")); + D(fprintf(stderr, "%*c%s _gather_72[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "maybe_star_pattern _loop0_73")); } _res = NULL; done: @@ -28105,13 +29429,12 @@ _gather_71_rule(Parser *p) return _res; } -// _loop0_74: ',' key_value_pattern +// _loop0_75: ',' key_value_pattern static asdl_seq * -_loop0_74_rule(Parser *p) +_loop0_75_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -28119,7 +29442,6 @@ _loop0_74_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -28134,7 +29456,7 @@ _loop0_74_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_74[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' key_value_pattern")); + D(fprintf(stderr, "%*c> _loop0_75[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' key_value_pattern")); Token * _literal; KeyPatternPair* elem; while ( @@ -28166,7 +29488,7 @@ _loop0_74_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_74[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_75[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' key_value_pattern")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -28179,18 +29501,16 @@ _loop0_74_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_74_type, _seq); p->level--; return _seq; } -// _gather_73: key_value_pattern _loop0_74 +// _gather_74: key_value_pattern _loop0_75 static asdl_seq * -_gather_73_rule(Parser *p) +_gather_74_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -28198,27 +29518,27 @@ _gather_73_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // key_value_pattern _loop0_74 + { // key_value_pattern _loop0_75 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_73[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "key_value_pattern _loop0_74")); + D(fprintf(stderr, "%*c> _gather_74[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "key_value_pattern _loop0_75")); KeyPatternPair* elem; asdl_seq * seq; if ( (elem = key_value_pattern_rule(p)) // key_value_pattern && - (seq = _loop0_74_rule(p)) // _loop0_74 + (seq = _loop0_75_rule(p)) // _loop0_75 ) { - D(fprintf(stderr, "%*c+ _gather_73[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "key_value_pattern _loop0_74")); + D(fprintf(stderr, "%*c+ _gather_74[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "key_value_pattern _loop0_75")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_73[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "key_value_pattern _loop0_74")); + D(fprintf(stderr, "%*c%s _gather_74[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "key_value_pattern _loop0_75")); } _res = NULL; done: @@ -28226,13 +29546,12 @@ _gather_73_rule(Parser *p) return _res; } -// _tmp_75: literal_expr | attr +// _tmp_76: literal_expr | attr static void * -_tmp_75_rule(Parser *p) +_tmp_76_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -28245,18 +29564,18 @@ _tmp_75_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_75[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "literal_expr")); + D(fprintf(stderr, "%*c> _tmp_76[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "literal_expr")); expr_ty literal_expr_var; if ( (literal_expr_var = literal_expr_rule(p)) // literal_expr ) { - D(fprintf(stderr, "%*c+ _tmp_75[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "literal_expr")); + D(fprintf(stderr, "%*c+ _tmp_76[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "literal_expr")); _res = literal_expr_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_75[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_76[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "literal_expr")); } { // attr @@ -28264,18 +29583,18 @@ _tmp_75_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_75[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "attr")); + D(fprintf(stderr, "%*c> _tmp_76[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "attr")); expr_ty attr_var; if ( (attr_var = attr_rule(p)) // attr ) { - D(fprintf(stderr, "%*c+ _tmp_75[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "attr")); + D(fprintf(stderr, "%*c+ _tmp_76[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "attr")); _res = attr_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_75[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_76[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "attr")); } _res = NULL; @@ -28284,13 +29603,12 @@ _tmp_75_rule(Parser *p) return _res; } -// _loop0_77: ',' pattern +// _loop0_78: ',' pattern static asdl_seq * -_loop0_77_rule(Parser *p) +_loop0_78_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -28298,7 +29616,6 @@ _loop0_77_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -28313,7 +29630,7 @@ _loop0_77_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_77[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' pattern")); + D(fprintf(stderr, "%*c> _loop0_78[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' pattern")); Token * _literal; pattern_ty elem; while ( @@ -28345,7 +29662,7 @@ _loop0_77_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_77[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_78[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' pattern")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -28358,18 +29675,16 @@ _loop0_77_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_77_type, _seq); p->level--; return _seq; } -// _gather_76: pattern _loop0_77 +// _gather_77: pattern _loop0_78 static asdl_seq * -_gather_76_rule(Parser *p) +_gather_77_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -28377,27 +29692,27 @@ _gather_76_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // pattern _loop0_77 + { // pattern _loop0_78 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_76[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "pattern _loop0_77")); + D(fprintf(stderr, "%*c> _gather_77[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "pattern _loop0_78")); pattern_ty elem; asdl_seq * seq; if ( (elem = pattern_rule(p)) // pattern && - (seq = _loop0_77_rule(p)) // _loop0_77 + (seq = _loop0_78_rule(p)) // _loop0_78 ) { - D(fprintf(stderr, "%*c+ _gather_76[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "pattern _loop0_77")); + D(fprintf(stderr, "%*c+ _gather_77[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "pattern _loop0_78")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_76[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "pattern _loop0_77")); + D(fprintf(stderr, "%*c%s _gather_77[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "pattern _loop0_78")); } _res = NULL; done: @@ -28405,13 +29720,12 @@ _gather_76_rule(Parser *p) return _res; } -// _loop0_79: ',' keyword_pattern +// _loop0_80: ',' keyword_pattern static asdl_seq * -_loop0_79_rule(Parser *p) +_loop0_80_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -28419,7 +29733,6 @@ _loop0_79_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -28434,7 +29747,7 @@ _loop0_79_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_79[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' keyword_pattern")); + D(fprintf(stderr, "%*c> _loop0_80[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' keyword_pattern")); Token * _literal; KeyPatternPair* elem; while ( @@ -28466,7 +29779,7 @@ _loop0_79_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_79[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_80[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' keyword_pattern")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -28479,18 +29792,16 @@ _loop0_79_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_79_type, _seq); p->level--; return _seq; } -// _gather_78: keyword_pattern _loop0_79 +// _gather_79: keyword_pattern _loop0_80 static asdl_seq * -_gather_78_rule(Parser *p) +_gather_79_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -28498,27 +29809,27 @@ _gather_78_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // keyword_pattern _loop0_79 + { // keyword_pattern _loop0_80 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_78[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "keyword_pattern _loop0_79")); + D(fprintf(stderr, "%*c> _gather_79[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "keyword_pattern _loop0_80")); KeyPatternPair* elem; asdl_seq * seq; if ( (elem = keyword_pattern_rule(p)) // keyword_pattern && - (seq = _loop0_79_rule(p)) // _loop0_79 + (seq = _loop0_80_rule(p)) // _loop0_80 ) { - D(fprintf(stderr, "%*c+ _gather_78[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "keyword_pattern _loop0_79")); + D(fprintf(stderr, "%*c+ _gather_79[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "keyword_pattern _loop0_80")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_78[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "keyword_pattern _loop0_79")); + D(fprintf(stderr, "%*c%s _gather_79[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "keyword_pattern _loop0_80")); } _res = NULL; done: @@ -28526,13 +29837,129 @@ _gather_78_rule(Parser *p) return _res; } -// _loop1_80: (',' expression) +// _loop0_82: ',' type_param static asdl_seq * -_loop1_80_rule(Parser *p) +_loop0_82_rule(Parser *p) { if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void *_res = NULL; + int _mark = p->mark; + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // ',' type_param + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_82[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' type_param")); + Token * _literal; + type_param_ty elem; + while ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (elem = type_param_rule(p)) // type_param + ) + { + _res = elem; + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + PyMem_Free(_children); + p->level--; + return NULL; + } + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + _children = _new_children; + } + _children[_n++] = _res; + _mark = p->mark; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _loop0_82[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' type_param")); + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); + p->level--; + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); + PyMem_Free(_children); + p->level--; + return _seq; +} + +// _gather_81: type_param _loop0_82 +static asdl_seq * +_gather_81_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_seq * _res = NULL; + int _mark = p->mark; + { // type_param _loop0_82 + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _gather_81[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "type_param _loop0_82")); + type_param_ty elem; + asdl_seq * seq; + if ( + (elem = type_param_rule(p)) // type_param + && + (seq = _loop0_82_rule(p)) // _loop0_82 + ) + { + D(fprintf(stderr, "%*c+ _gather_81[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "type_param _loop0_82")); + _res = _PyPegen_seq_insert_in_front(p, elem, seq); + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _gather_81[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "type_param _loop0_82")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop1_83: (',' expression) +static asdl_seq * +_loop1_83_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -28540,7 +29967,6 @@ _loop1_80_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -28555,13 +29981,13 @@ _loop1_80_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_80[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' expression)")); - void *_tmp_226_var; + D(fprintf(stderr, "%*c> _loop1_83[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' expression)")); + void *_tmp_251_var; while ( - (_tmp_226_var = _tmp_226_rule(p)) // ',' expression + (_tmp_251_var = _tmp_251_rule(p)) // ',' expression ) { - _res = _tmp_226_var; + _res = _tmp_251_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -28578,7 +30004,7 @@ _loop1_80_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_80[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_83[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(',' expression)")); } if (_n == 0 || p->error_indicator) { @@ -28596,18 +30022,16 @@ _loop1_80_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_80_type, _seq); p->level--; return _seq; } -// _loop1_81: (',' star_expression) +// _loop1_84: (',' star_expression) static asdl_seq * -_loop1_81_rule(Parser *p) +_loop1_84_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -28615,7 +30039,6 @@ _loop1_81_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -28630,13 +30053,13 @@ _loop1_81_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_81[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' star_expression)")); - void *_tmp_227_var; + D(fprintf(stderr, "%*c> _loop1_84[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' star_expression)")); + void *_tmp_252_var; while ( - (_tmp_227_var = _tmp_227_rule(p)) // ',' star_expression + (_tmp_252_var = _tmp_252_rule(p)) // ',' star_expression ) { - _res = _tmp_227_var; + _res = _tmp_252_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -28653,7 +30076,7 @@ _loop1_81_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_81[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_84[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(',' star_expression)")); } if (_n == 0 || p->error_indicator) { @@ -28671,18 +30094,16 @@ _loop1_81_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_81_type, _seq); p->level--; return _seq; } -// _loop0_83: ',' star_named_expression +// _loop0_86: ',' star_named_expression static asdl_seq * -_loop0_83_rule(Parser *p) +_loop0_86_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -28690,7 +30111,6 @@ _loop0_83_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -28705,7 +30125,7 @@ _loop0_83_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_83[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_named_expression")); + D(fprintf(stderr, "%*c> _loop0_86[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_named_expression")); Token * _literal; expr_ty elem; while ( @@ -28737,7 +30157,7 @@ _loop0_83_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_83[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_86[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' star_named_expression")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -28750,18 +30170,16 @@ _loop0_83_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_83_type, _seq); p->level--; return _seq; } -// _gather_82: star_named_expression _loop0_83 +// _gather_85: star_named_expression _loop0_86 static asdl_seq * -_gather_82_rule(Parser *p) +_gather_85_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -28769,27 +30187,27 @@ _gather_82_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // star_named_expression _loop0_83 + { // star_named_expression _loop0_86 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_82[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_named_expression _loop0_83")); + D(fprintf(stderr, "%*c> _gather_85[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_named_expression _loop0_86")); expr_ty elem; asdl_seq * seq; if ( (elem = star_named_expression_rule(p)) // star_named_expression && - (seq = _loop0_83_rule(p)) // _loop0_83 + (seq = _loop0_86_rule(p)) // _loop0_86 ) { - D(fprintf(stderr, "%*c+ _gather_82[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_named_expression _loop0_83")); + D(fprintf(stderr, "%*c+ _gather_85[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_named_expression _loop0_86")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_82[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_named_expression _loop0_83")); + D(fprintf(stderr, "%*c%s _gather_85[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_named_expression _loop0_86")); } _res = NULL; done: @@ -28797,13 +30215,12 @@ _gather_82_rule(Parser *p) return _res; } -// _loop1_84: ('or' conjunction) +// _loop1_87: ('or' conjunction) static asdl_seq * -_loop1_84_rule(Parser *p) +_loop1_87_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -28811,7 +30228,6 @@ _loop1_84_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -28826,13 +30242,13 @@ _loop1_84_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_84[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('or' conjunction)")); - void *_tmp_228_var; + D(fprintf(stderr, "%*c> _loop1_87[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('or' conjunction)")); + void *_tmp_253_var; while ( - (_tmp_228_var = _tmp_228_rule(p)) // 'or' conjunction + (_tmp_253_var = _tmp_253_rule(p)) // 'or' conjunction ) { - _res = _tmp_228_var; + _res = _tmp_253_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -28849,7 +30265,7 @@ _loop1_84_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_84[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_87[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "('or' conjunction)")); } if (_n == 0 || p->error_indicator) { @@ -28867,18 +30283,16 @@ _loop1_84_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_84_type, _seq); p->level--; return _seq; } -// _loop1_85: ('and' inversion) +// _loop1_88: ('and' inversion) static asdl_seq * -_loop1_85_rule(Parser *p) +_loop1_88_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -28886,7 +30300,6 @@ _loop1_85_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -28901,13 +30314,13 @@ _loop1_85_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_85[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('and' inversion)")); - void *_tmp_229_var; + D(fprintf(stderr, "%*c> _loop1_88[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('and' inversion)")); + void *_tmp_254_var; while ( - (_tmp_229_var = _tmp_229_rule(p)) // 'and' inversion + (_tmp_254_var = _tmp_254_rule(p)) // 'and' inversion ) { - _res = _tmp_229_var; + _res = _tmp_254_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -28924,7 +30337,7 @@ _loop1_85_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_85[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_88[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "('and' inversion)")); } if (_n == 0 || p->error_indicator) { @@ -28942,18 +30355,16 @@ _loop1_85_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_85_type, _seq); p->level--; return _seq; } -// _loop1_86: compare_op_bitwise_or_pair +// _loop1_89: compare_op_bitwise_or_pair static asdl_seq * -_loop1_86_rule(Parser *p) +_loop1_89_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -28961,7 +30372,6 @@ _loop1_86_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -28976,7 +30386,7 @@ _loop1_86_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_86[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "compare_op_bitwise_or_pair")); + D(fprintf(stderr, "%*c> _loop1_89[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "compare_op_bitwise_or_pair")); CmpopExprPair* compare_op_bitwise_or_pair_var; while ( (compare_op_bitwise_or_pair_var = compare_op_bitwise_or_pair_rule(p)) // compare_op_bitwise_or_pair @@ -28999,7 +30409,7 @@ _loop1_86_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_86[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_89[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "compare_op_bitwise_or_pair")); } if (_n == 0 || p->error_indicator) { @@ -29017,18 +30427,16 @@ _loop1_86_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_86_type, _seq); p->level--; return _seq; } -// _tmp_87: '!=' +// _tmp_90: '!=' static void * -_tmp_87_rule(Parser *p) +_tmp_90_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -29041,13 +30449,13 @@ _tmp_87_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_87[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'!='")); + D(fprintf(stderr, "%*c> _tmp_90[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'!='")); Token * tok; if ( (tok = _PyPegen_expect_token(p, 28)) // token='!=' ) { - D(fprintf(stderr, "%*c+ _tmp_87[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'!='")); + D(fprintf(stderr, "%*c+ _tmp_90[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'!='")); _res = _PyPegen_check_barry_as_flufl ( p , tok ) ? NULL : tok; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -29057,7 +30465,7 @@ _tmp_87_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_87[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_90[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'!='")); } _res = NULL; @@ -29066,13 +30474,12 @@ _tmp_87_rule(Parser *p) return _res; } -// _loop0_89: ',' (slice | starred_expression) +// _loop0_92: ',' (slice | starred_expression) static asdl_seq * -_loop0_89_rule(Parser *p) +_loop0_92_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -29080,7 +30487,6 @@ _loop0_89_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -29095,13 +30501,13 @@ _loop0_89_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_89[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (slice | starred_expression)")); + D(fprintf(stderr, "%*c> _loop0_92[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (slice | starred_expression)")); Token * _literal; void *elem; while ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (elem = _tmp_230_rule(p)) // slice | starred_expression + (elem = _tmp_255_rule(p)) // slice | starred_expression ) { _res = elem; @@ -29127,7 +30533,7 @@ _loop0_89_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_89[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_92[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (slice | starred_expression)")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -29140,18 +30546,16 @@ _loop0_89_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_89_type, _seq); p->level--; return _seq; } -// _gather_88: (slice | starred_expression) _loop0_89 +// _gather_91: (slice | starred_expression) _loop0_92 static asdl_seq * -_gather_88_rule(Parser *p) +_gather_91_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -29159,27 +30563,27 @@ _gather_88_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // (slice | starred_expression) _loop0_89 + { // (slice | starred_expression) _loop0_92 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_88[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(slice | starred_expression) _loop0_89")); + D(fprintf(stderr, "%*c> _gather_91[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(slice | starred_expression) _loop0_92")); void *elem; asdl_seq * seq; if ( - (elem = _tmp_230_rule(p)) // slice | starred_expression + (elem = _tmp_255_rule(p)) // slice | starred_expression && - (seq = _loop0_89_rule(p)) // _loop0_89 + (seq = _loop0_92_rule(p)) // _loop0_92 ) { - D(fprintf(stderr, "%*c+ _gather_88[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(slice | starred_expression) _loop0_89")); + D(fprintf(stderr, "%*c+ _gather_91[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(slice | starred_expression) _loop0_92")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_88[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(slice | starred_expression) _loop0_89")); + D(fprintf(stderr, "%*c%s _gather_91[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(slice | starred_expression) _loop0_92")); } _res = NULL; done: @@ -29187,13 +30591,12 @@ _gather_88_rule(Parser *p) return _res; } -// _tmp_90: ':' expression? +// _tmp_93: ':' expression? static void * -_tmp_90_rule(Parser *p) +_tmp_93_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -29206,7 +30609,7 @@ _tmp_90_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_90[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':' expression?")); + D(fprintf(stderr, "%*c> _tmp_93[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':' expression?")); Token * _literal; void *d; if ( @@ -29215,7 +30618,7 @@ _tmp_90_rule(Parser *p) (d = expression_rule(p), !p->error_indicator) // expression? ) { - D(fprintf(stderr, "%*c+ _tmp_90[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':' expression?")); + D(fprintf(stderr, "%*c+ _tmp_93[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':' expression?")); _res = d; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -29225,7 +30628,7 @@ _tmp_90_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_90[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_93[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':' expression?")); } _res = NULL; @@ -29234,13 +30637,69 @@ _tmp_90_rule(Parser *p) return _res; } -// _tmp_91: tuple | group | genexp +// _tmp_94: STRING | FSTRING_START static void * -_tmp_91_rule(Parser *p) +_tmp_94_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // STRING + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_94[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "STRING")); + expr_ty string_var; + if ( + (string_var = _PyPegen_string_token(p)) // STRING + ) + { + D(fprintf(stderr, "%*c+ _tmp_94[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "STRING")); + _res = string_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_94[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "STRING")); + } + { // FSTRING_START + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_94[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "FSTRING_START")); + Token * fstring_start_var; + if ( + (fstring_start_var = _PyPegen_expect_token(p, FSTRING_START)) // token='FSTRING_START' + ) + { + D(fprintf(stderr, "%*c+ _tmp_94[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "FSTRING_START")); + _res = fstring_start_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_94[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "FSTRING_START")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_95: tuple | group | genexp +static void * +_tmp_95_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -29253,18 +30712,18 @@ _tmp_91_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_91[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "tuple")); + D(fprintf(stderr, "%*c> _tmp_95[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "tuple")); expr_ty tuple_var; if ( (tuple_var = tuple_rule(p)) // tuple ) { - D(fprintf(stderr, "%*c+ _tmp_91[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "tuple")); + D(fprintf(stderr, "%*c+ _tmp_95[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "tuple")); _res = tuple_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_91[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_95[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "tuple")); } { // group @@ -29272,18 +30731,18 @@ _tmp_91_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_91[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "group")); + D(fprintf(stderr, "%*c> _tmp_95[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "group")); expr_ty group_var; if ( (group_var = group_rule(p)) // group ) { - D(fprintf(stderr, "%*c+ _tmp_91[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "group")); + D(fprintf(stderr, "%*c+ _tmp_95[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "group")); _res = group_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_91[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_95[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "group")); } { // genexp @@ -29291,18 +30750,18 @@ _tmp_91_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_91[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "genexp")); + D(fprintf(stderr, "%*c> _tmp_95[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "genexp")); expr_ty genexp_var; if ( (genexp_var = genexp_rule(p)) // genexp ) { - D(fprintf(stderr, "%*c+ _tmp_91[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "genexp")); + D(fprintf(stderr, "%*c+ _tmp_95[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "genexp")); _res = genexp_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_91[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_95[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "genexp")); } _res = NULL; @@ -29311,13 +30770,12 @@ _tmp_91_rule(Parser *p) return _res; } -// _tmp_92: list | listcomp +// _tmp_96: list | listcomp static void * -_tmp_92_rule(Parser *p) +_tmp_96_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -29330,18 +30788,18 @@ _tmp_92_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_92[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "list")); + D(fprintf(stderr, "%*c> _tmp_96[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "list")); expr_ty list_var; if ( (list_var = list_rule(p)) // list ) { - D(fprintf(stderr, "%*c+ _tmp_92[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "list")); + D(fprintf(stderr, "%*c+ _tmp_96[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "list")); _res = list_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_92[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_96[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "list")); } { // listcomp @@ -29349,18 +30807,18 @@ _tmp_92_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_92[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "listcomp")); + D(fprintf(stderr, "%*c> _tmp_96[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "listcomp")); expr_ty listcomp_var; if ( (listcomp_var = listcomp_rule(p)) // listcomp ) { - D(fprintf(stderr, "%*c+ _tmp_92[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "listcomp")); + D(fprintf(stderr, "%*c+ _tmp_96[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "listcomp")); _res = listcomp_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_92[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_96[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "listcomp")); } _res = NULL; @@ -29369,13 +30827,12 @@ _tmp_92_rule(Parser *p) return _res; } -// _tmp_93: dict | set | dictcomp | setcomp +// _tmp_97: dict | set | dictcomp | setcomp static void * -_tmp_93_rule(Parser *p) +_tmp_97_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -29388,18 +30845,18 @@ _tmp_93_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_93[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "dict")); + D(fprintf(stderr, "%*c> _tmp_97[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "dict")); expr_ty dict_var; if ( (dict_var = dict_rule(p)) // dict ) { - D(fprintf(stderr, "%*c+ _tmp_93[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "dict")); + D(fprintf(stderr, "%*c+ _tmp_97[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "dict")); _res = dict_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_93[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_97[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "dict")); } { // set @@ -29407,18 +30864,18 @@ _tmp_93_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_93[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "set")); + D(fprintf(stderr, "%*c> _tmp_97[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "set")); expr_ty set_var; if ( (set_var = set_rule(p)) // set ) { - D(fprintf(stderr, "%*c+ _tmp_93[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "set")); + D(fprintf(stderr, "%*c+ _tmp_97[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "set")); _res = set_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_93[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_97[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "set")); } { // dictcomp @@ -29426,18 +30883,18 @@ _tmp_93_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_93[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "dictcomp")); + D(fprintf(stderr, "%*c> _tmp_97[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "dictcomp")); expr_ty dictcomp_var; if ( (dictcomp_var = dictcomp_rule(p)) // dictcomp ) { - D(fprintf(stderr, "%*c+ _tmp_93[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "dictcomp")); + D(fprintf(stderr, "%*c+ _tmp_97[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "dictcomp")); _res = dictcomp_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_93[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_97[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "dictcomp")); } { // setcomp @@ -29445,18 +30902,18 @@ _tmp_93_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_93[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "setcomp")); + D(fprintf(stderr, "%*c> _tmp_97[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "setcomp")); expr_ty setcomp_var; if ( (setcomp_var = setcomp_rule(p)) // setcomp ) { - D(fprintf(stderr, "%*c+ _tmp_93[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "setcomp")); + D(fprintf(stderr, "%*c+ _tmp_97[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "setcomp")); _res = setcomp_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_93[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_97[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "setcomp")); } _res = NULL; @@ -29465,13 +30922,12 @@ _tmp_93_rule(Parser *p) return _res; } -// _tmp_94: yield_expr | named_expression +// _tmp_98: yield_expr | named_expression static void * -_tmp_94_rule(Parser *p) +_tmp_98_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -29484,18 +30940,18 @@ _tmp_94_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_94[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); + D(fprintf(stderr, "%*c> _tmp_98[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); expr_ty yield_expr_var; if ( (yield_expr_var = yield_expr_rule(p)) // yield_expr ) { - D(fprintf(stderr, "%*c+ _tmp_94[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); + D(fprintf(stderr, "%*c+ _tmp_98[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); _res = yield_expr_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_94[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_98[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "yield_expr")); } { // named_expression @@ -29503,18 +30959,18 @@ _tmp_94_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_94[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "named_expression")); + D(fprintf(stderr, "%*c> _tmp_98[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "named_expression")); expr_ty named_expression_var; if ( (named_expression_var = named_expression_rule(p)) // named_expression ) { - D(fprintf(stderr, "%*c+ _tmp_94[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "named_expression")); + D(fprintf(stderr, "%*c+ _tmp_98[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "named_expression")); _res = named_expression_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_94[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_98[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "named_expression")); } _res = NULL; @@ -29523,13 +30979,12 @@ _tmp_94_rule(Parser *p) return _res; } -// _loop0_95: lambda_param_no_default +// _loop0_99: lambda_param_no_default static asdl_seq * -_loop0_95_rule(Parser *p) +_loop0_99_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -29537,7 +30992,6 @@ _loop0_95_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -29552,7 +31006,7 @@ _loop0_95_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_95[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + D(fprintf(stderr, "%*c> _loop0_99[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); arg_ty lambda_param_no_default_var; while ( (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default @@ -29575,7 +31029,7 @@ _loop0_95_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_95[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_99[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -29588,18 +31042,16 @@ _loop0_95_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_95_type, _seq); p->level--; return _seq; } -// _loop0_96: lambda_param_with_default +// _loop0_100: lambda_param_with_default static asdl_seq * -_loop0_96_rule(Parser *p) +_loop0_100_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -29607,7 +31059,6 @@ _loop0_96_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -29622,7 +31073,7 @@ _loop0_96_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_96[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default")); + D(fprintf(stderr, "%*c> _loop0_100[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default")); NameDefaultPair* lambda_param_with_default_var; while ( (lambda_param_with_default_var = lambda_param_with_default_rule(p)) // lambda_param_with_default @@ -29645,7 +31096,7 @@ _loop0_96_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_96[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_100[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_with_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -29658,18 +31109,16 @@ _loop0_96_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_96_type, _seq); p->level--; return _seq; } -// _loop0_97: lambda_param_with_default +// _loop0_101: lambda_param_with_default static asdl_seq * -_loop0_97_rule(Parser *p) +_loop0_101_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -29677,7 +31126,6 @@ _loop0_97_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -29692,7 +31140,7 @@ _loop0_97_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_97[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default")); + D(fprintf(stderr, "%*c> _loop0_101[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default")); NameDefaultPair* lambda_param_with_default_var; while ( (lambda_param_with_default_var = lambda_param_with_default_rule(p)) // lambda_param_with_default @@ -29715,7 +31163,7 @@ _loop0_97_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_97[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_101[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_with_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -29728,18 +31176,16 @@ _loop0_97_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_97_type, _seq); p->level--; return _seq; } -// _loop1_98: lambda_param_no_default +// _loop1_102: lambda_param_no_default static asdl_seq * -_loop1_98_rule(Parser *p) +_loop1_102_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -29747,7 +31193,6 @@ _loop1_98_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -29762,7 +31207,7 @@ _loop1_98_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_98[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + D(fprintf(stderr, "%*c> _loop1_102[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); arg_ty lambda_param_no_default_var; while ( (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default @@ -29785,7 +31230,7 @@ _loop1_98_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_98[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_102[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); } if (_n == 0 || p->error_indicator) { @@ -29803,18 +31248,16 @@ _loop1_98_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_98_type, _seq); p->level--; return _seq; } -// _loop0_99: lambda_param_with_default +// _loop0_103: lambda_param_with_default static asdl_seq * -_loop0_99_rule(Parser *p) +_loop0_103_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -29822,7 +31265,6 @@ _loop0_99_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -29837,7 +31279,7 @@ _loop0_99_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_99[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default")); + D(fprintf(stderr, "%*c> _loop0_103[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default")); NameDefaultPair* lambda_param_with_default_var; while ( (lambda_param_with_default_var = lambda_param_with_default_rule(p)) // lambda_param_with_default @@ -29860,7 +31302,7 @@ _loop0_99_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_99[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_103[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_with_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -29873,18 +31315,16 @@ _loop0_99_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_99_type, _seq); p->level--; return _seq; } -// _loop1_100: lambda_param_with_default +// _loop1_104: lambda_param_with_default static asdl_seq * -_loop1_100_rule(Parser *p) +_loop1_104_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -29892,7 +31332,6 @@ _loop1_100_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -29907,7 +31346,7 @@ _loop1_100_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_100[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default")); + D(fprintf(stderr, "%*c> _loop1_104[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default")); NameDefaultPair* lambda_param_with_default_var; while ( (lambda_param_with_default_var = lambda_param_with_default_rule(p)) // lambda_param_with_default @@ -29930,7 +31369,7 @@ _loop1_100_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_100[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_104[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_with_default")); } if (_n == 0 || p->error_indicator) { @@ -29948,18 +31387,16 @@ _loop1_100_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_100_type, _seq); p->level--; return _seq; } -// _loop1_101: lambda_param_no_default +// _loop1_105: lambda_param_no_default static asdl_seq * -_loop1_101_rule(Parser *p) +_loop1_105_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -29967,7 +31404,6 @@ _loop1_101_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -29982,7 +31418,7 @@ _loop1_101_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_101[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + D(fprintf(stderr, "%*c> _loop1_105[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); arg_ty lambda_param_no_default_var; while ( (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default @@ -30005,7 +31441,7 @@ _loop1_101_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_101[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_105[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); } if (_n == 0 || p->error_indicator) { @@ -30023,18 +31459,16 @@ _loop1_101_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_101_type, _seq); p->level--; return _seq; } -// _loop1_102: lambda_param_no_default +// _loop1_106: lambda_param_no_default static asdl_seq * -_loop1_102_rule(Parser *p) +_loop1_106_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -30042,7 +31476,6 @@ _loop1_102_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -30057,7 +31490,7 @@ _loop1_102_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_102[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + D(fprintf(stderr, "%*c> _loop1_106[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); arg_ty lambda_param_no_default_var; while ( (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default @@ -30080,7 +31513,7 @@ _loop1_102_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_102[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_106[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); } if (_n == 0 || p->error_indicator) { @@ -30098,18 +31531,155 @@ _loop1_102_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_102_type, _seq); p->level--; return _seq; } -// _loop0_103: lambda_param_no_default +// _loop0_107: lambda_param_no_default static asdl_seq * -_loop0_103_rule(Parser *p) +_loop0_107_rule(Parser *p) { if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void *_res = NULL; + int _mark = p->mark; + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // lambda_param_no_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_107[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + arg_ty lambda_param_no_default_var; + while ( + (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default + ) + { + _res = lambda_param_no_default_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + _children = _new_children; + } + _children[_n++] = _res; + _mark = p->mark; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _loop0_107[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); + PyMem_Free(_children); + p->level--; + return _seq; +} + +// _loop1_108: lambda_param_with_default +static asdl_seq * +_loop1_108_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void *_res = NULL; + int _mark = p->mark; + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { p->error_indicator = 1; PyErr_NoMemory(); + p->level--; + return NULL; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // lambda_param_with_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop1_108[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default")); + NameDefaultPair* lambda_param_with_default_var; + while ( + (lambda_param_with_default_var = lambda_param_with_default_rule(p)) // lambda_param_with_default + ) + { + _res = lambda_param_with_default_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + _children = _new_children; + } + _children[_n++] = _res; + _mark = p->mark; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _loop1_108[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_with_default")); + } + if (_n == 0 || p->error_indicator) { + PyMem_Free(_children); + p->level--; + return NULL; + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); + PyMem_Free(_children); + p->level--; + return _seq; +} + +// _loop0_109: lambda_param_no_default +static asdl_seq * +_loop0_109_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -30117,7 +31687,6 @@ _loop0_103_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -30132,7 +31701,7 @@ _loop0_103_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_103[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + D(fprintf(stderr, "%*c> _loop0_109[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); arg_ty lambda_param_no_default_var; while ( (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default @@ -30155,7 +31724,7 @@ _loop0_103_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_103[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_109[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -30168,18 +31737,16 @@ _loop0_103_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_103_type, _seq); p->level--; return _seq; } -// _loop1_104: lambda_param_with_default +// _loop1_110: lambda_param_with_default static asdl_seq * -_loop1_104_rule(Parser *p) +_loop1_110_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -30187,7 +31754,6 @@ _loop1_104_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -30202,7 +31768,7 @@ _loop1_104_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_104[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default")); + D(fprintf(stderr, "%*c> _loop1_110[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default")); NameDefaultPair* lambda_param_with_default_var; while ( (lambda_param_with_default_var = lambda_param_with_default_rule(p)) // lambda_param_with_default @@ -30225,7 +31791,7 @@ _loop1_104_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_104[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_110[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_with_default")); } if (_n == 0 || p->error_indicator) { @@ -30243,18 +31809,16 @@ _loop1_104_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_104_type, _seq); p->level--; return _seq; } -// _loop0_105: lambda_param_no_default +// _loop0_111: lambda_param_maybe_default static asdl_seq * -_loop0_105_rule(Parser *p) +_loop0_111_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -30262,7 +31826,6 @@ _loop0_105_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -30272,18 +31835,18 @@ _loop0_105_rule(Parser *p) } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; - { // lambda_param_no_default + { // lambda_param_maybe_default if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_105[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); - arg_ty lambda_param_no_default_var; + D(fprintf(stderr, "%*c> _loop0_111[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); + NameDefaultPair* lambda_param_maybe_default_var; while ( - (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default + (lambda_param_maybe_default_var = lambda_param_maybe_default_rule(p)) // lambda_param_maybe_default ) { - _res = lambda_param_no_default_var; + _res = lambda_param_maybe_default_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -30300,8 +31863,8 @@ _loop0_105_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_105[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); + D(fprintf(stderr, "%*c%s _loop0_111[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_maybe_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { @@ -30313,18 +31876,16 @@ _loop0_105_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_105_type, _seq); p->level--; return _seq; } -// _loop1_106: lambda_param_with_default +// _loop1_112: lambda_param_maybe_default static asdl_seq * -_loop1_106_rule(Parser *p) +_loop1_112_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -30332,7 +31893,6 @@ _loop1_106_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -30342,18 +31902,18 @@ _loop1_106_rule(Parser *p) } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; - { // lambda_param_with_default + { // lambda_param_maybe_default if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_106[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default")); - NameDefaultPair* lambda_param_with_default_var; + D(fprintf(stderr, "%*c> _loop1_112[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); + NameDefaultPair* lambda_param_maybe_default_var; while ( - (lambda_param_with_default_var = lambda_param_with_default_rule(p)) // lambda_param_with_default + (lambda_param_maybe_default_var = lambda_param_maybe_default_rule(p)) // lambda_param_maybe_default ) { - _res = lambda_param_with_default_var; + _res = lambda_param_maybe_default_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -30370,8 +31930,8 @@ _loop1_106_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_106[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_with_default")); + D(fprintf(stderr, "%*c%s _loop1_112[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_maybe_default")); } if (_n == 0 || p->error_indicator) { PyMem_Free(_children); @@ -30388,88 +31948,73 @@ _loop1_106_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_106_type, _seq); p->level--; return _seq; } -// _loop0_107: lambda_param_maybe_default -static asdl_seq * -_loop0_107_rule(Parser *p) +// _tmp_113: yield_expr | star_expressions +static void * +_tmp_113_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; return NULL; } - void *_res = NULL; + void * _res = NULL; int _mark = p->mark; - int _start_mark = p->mark; - void **_children = PyMem_Malloc(sizeof(void *)); - if (!_children) { - p->error_indicator = 1; - PyErr_NoMemory(); - p->level--; - return NULL; - } - Py_ssize_t _children_capacity = 1; - Py_ssize_t _n = 0; - { // lambda_param_maybe_default + { // yield_expr if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_107[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); - NameDefaultPair* lambda_param_maybe_default_var; - while ( - (lambda_param_maybe_default_var = lambda_param_maybe_default_rule(p)) // lambda_param_maybe_default + D(fprintf(stderr, "%*c> _tmp_113[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); + expr_ty yield_expr_var; + if ( + (yield_expr_var = yield_expr_rule(p)) // yield_expr ) { - _res = lambda_param_maybe_default_var; - if (_n == _children_capacity) { - _children_capacity *= 2; - void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); - if (!_new_children) { - PyMem_Free(_children); - p->error_indicator = 1; - PyErr_NoMemory(); - p->level--; - return NULL; - } - _children = _new_children; - } - _children[_n++] = _res; - _mark = p->mark; + D(fprintf(stderr, "%*c+ _tmp_113[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); + _res = yield_expr_var; + goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_107[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_maybe_default")); + D(fprintf(stderr, "%*c%s _tmp_113[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "yield_expr")); } - asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); - if (!_seq) { - PyMem_Free(_children); - p->error_indicator = 1; - PyErr_NoMemory(); - p->level--; - return NULL; + { // star_expressions + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_113[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); + expr_ty star_expressions_var; + if ( + (star_expressions_var = star_expressions_rule(p)) // star_expressions + ) + { + D(fprintf(stderr, "%*c+ _tmp_113[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); + _res = star_expressions_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_113[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions")); } - for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_107_type, _seq); + _res = NULL; + done: p->level--; - return _seq; + return _res; } -// _loop1_108: lambda_param_maybe_default +// _loop0_114: fstring_format_spec static asdl_seq * -_loop1_108_rule(Parser *p) +_loop0_114_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -30477,7 +32022,6 @@ _loop1_108_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -30487,18 +32031,18 @@ _loop1_108_rule(Parser *p) } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; - { // lambda_param_maybe_default + { // fstring_format_spec if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_108[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); - NameDefaultPair* lambda_param_maybe_default_var; + D(fprintf(stderr, "%*c> _loop0_114[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "fstring_format_spec")); + expr_ty fstring_format_spec_var; while ( - (lambda_param_maybe_default_var = lambda_param_maybe_default_rule(p)) // lambda_param_maybe_default + (fstring_format_spec_var = fstring_format_spec_rule(p)) // fstring_format_spec ) { - _res = lambda_param_maybe_default_var; + _res = fstring_format_spec_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -30515,13 +32059,8 @@ _loop1_108_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_108[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_maybe_default")); - } - if (_n == 0 || p->error_indicator) { - PyMem_Free(_children); - p->level--; - return NULL; + D(fprintf(stderr, "%*c%s _loop0_114[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "fstring_format_spec")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { @@ -30533,18 +32072,16 @@ _loop1_108_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_108_type, _seq); p->level--; return _seq; } -// _loop1_109: STRING +// _loop1_115: (fstring | string) static asdl_seq * -_loop1_109_rule(Parser *p) +_loop1_115_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -30552,7 +32089,6 @@ _loop1_109_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -30562,18 +32098,18 @@ _loop1_109_rule(Parser *p) } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; - { // STRING + { // (fstring | string) if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_109[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "STRING")); - expr_ty string_var; + D(fprintf(stderr, "%*c> _loop1_115[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(fstring | string)")); + void *_tmp_256_var; while ( - (string_var = _PyPegen_string_token(p)) // STRING + (_tmp_256_var = _tmp_256_rule(p)) // fstring | string ) { - _res = string_var; + _res = _tmp_256_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -30590,8 +32126,8 @@ _loop1_109_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_109[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "STRING")); + D(fprintf(stderr, "%*c%s _loop1_115[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(fstring | string)")); } if (_n == 0 || p->error_indicator) { PyMem_Free(_children); @@ -30608,18 +32144,16 @@ _loop1_109_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_109_type, _seq); p->level--; return _seq; } -// _tmp_110: star_named_expression ',' star_named_expressions? +// _tmp_116: star_named_expression ',' star_named_expressions? static void * -_tmp_110_rule(Parser *p) +_tmp_116_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -30632,7 +32166,7 @@ _tmp_110_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_110[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_named_expression ',' star_named_expressions?")); + D(fprintf(stderr, "%*c> _tmp_116[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_named_expression ',' star_named_expressions?")); Token * _literal; expr_ty y; void *z; @@ -30644,7 +32178,7 @@ _tmp_110_rule(Parser *p) (z = star_named_expressions_rule(p), !p->error_indicator) // star_named_expressions? ) { - D(fprintf(stderr, "%*c+ _tmp_110[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_named_expression ',' star_named_expressions?")); + D(fprintf(stderr, "%*c+ _tmp_116[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_named_expression ',' star_named_expressions?")); _res = _PyPegen_seq_insert_in_front ( p , y , z ); if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -30654,7 +32188,7 @@ _tmp_110_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_110[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_116[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_named_expression ',' star_named_expressions?")); } _res = NULL; @@ -30663,13 +32197,12 @@ _tmp_110_rule(Parser *p) return _res; } -// _loop0_112: ',' double_starred_kvpair +// _loop0_118: ',' double_starred_kvpair static asdl_seq * -_loop0_112_rule(Parser *p) +_loop0_118_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -30677,7 +32210,6 @@ _loop0_112_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -30692,7 +32224,7 @@ _loop0_112_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_112[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' double_starred_kvpair")); + D(fprintf(stderr, "%*c> _loop0_118[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' double_starred_kvpair")); Token * _literal; KeyValuePair* elem; while ( @@ -30724,7 +32256,7 @@ _loop0_112_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_112[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_118[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' double_starred_kvpair")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -30737,18 +32269,16 @@ _loop0_112_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_112_type, _seq); p->level--; return _seq; } -// _gather_111: double_starred_kvpair _loop0_112 +// _gather_117: double_starred_kvpair _loop0_118 static asdl_seq * -_gather_111_rule(Parser *p) +_gather_117_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -30756,27 +32286,27 @@ _gather_111_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // double_starred_kvpair _loop0_112 + { // double_starred_kvpair _loop0_118 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_111[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "double_starred_kvpair _loop0_112")); + D(fprintf(stderr, "%*c> _gather_117[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "double_starred_kvpair _loop0_118")); KeyValuePair* elem; asdl_seq * seq; if ( (elem = double_starred_kvpair_rule(p)) // double_starred_kvpair && - (seq = _loop0_112_rule(p)) // _loop0_112 + (seq = _loop0_118_rule(p)) // _loop0_118 ) { - D(fprintf(stderr, "%*c+ _gather_111[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "double_starred_kvpair _loop0_112")); + D(fprintf(stderr, "%*c+ _gather_117[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "double_starred_kvpair _loop0_118")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_111[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "double_starred_kvpair _loop0_112")); + D(fprintf(stderr, "%*c%s _gather_117[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "double_starred_kvpair _loop0_118")); } _res = NULL; done: @@ -30784,13 +32314,12 @@ _gather_111_rule(Parser *p) return _res; } -// _loop1_113: for_if_clause +// _loop1_119: for_if_clause static asdl_seq * -_loop1_113_rule(Parser *p) +_loop1_119_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -30798,7 +32327,6 @@ _loop1_113_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -30813,7 +32341,7 @@ _loop1_113_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_113[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "for_if_clause")); + D(fprintf(stderr, "%*c> _loop1_119[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "for_if_clause")); comprehension_ty for_if_clause_var; while ( (for_if_clause_var = for_if_clause_rule(p)) // for_if_clause @@ -30836,7 +32364,7 @@ _loop1_113_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_113[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_119[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "for_if_clause")); } if (_n == 0 || p->error_indicator) { @@ -30854,18 +32382,16 @@ _loop1_113_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_113_type, _seq); p->level--; return _seq; } -// _loop0_114: ('if' disjunction) +// _loop0_120: ('if' disjunction) static asdl_seq * -_loop0_114_rule(Parser *p) +_loop0_120_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -30873,7 +32399,6 @@ _loop0_114_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -30888,13 +32413,13 @@ _loop0_114_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_114[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('if' disjunction)")); - void *_tmp_231_var; + D(fprintf(stderr, "%*c> _loop0_120[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('if' disjunction)")); + void *_tmp_257_var; while ( - (_tmp_231_var = _tmp_231_rule(p)) // 'if' disjunction + (_tmp_257_var = _tmp_257_rule(p)) // 'if' disjunction ) { - _res = _tmp_231_var; + _res = _tmp_257_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -30911,7 +32436,7 @@ _loop0_114_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_114[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_120[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "('if' disjunction)")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -30924,18 +32449,16 @@ _loop0_114_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_114_type, _seq); p->level--; return _seq; } -// _loop0_115: ('if' disjunction) +// _loop0_121: ('if' disjunction) static asdl_seq * -_loop0_115_rule(Parser *p) +_loop0_121_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -30943,7 +32466,6 @@ _loop0_115_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -30958,13 +32480,13 @@ _loop0_115_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_115[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('if' disjunction)")); - void *_tmp_232_var; + D(fprintf(stderr, "%*c> _loop0_121[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('if' disjunction)")); + void *_tmp_258_var; while ( - (_tmp_232_var = _tmp_232_rule(p)) // 'if' disjunction + (_tmp_258_var = _tmp_258_rule(p)) // 'if' disjunction ) { - _res = _tmp_232_var; + _res = _tmp_258_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -30981,7 +32503,7 @@ _loop0_115_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_115[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_121[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "('if' disjunction)")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -30994,18 +32516,16 @@ _loop0_115_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_115_type, _seq); p->level--; return _seq; } -// _tmp_116: assignment_expression | expression !':=' +// _tmp_122: assignment_expression | expression !':=' static void * -_tmp_116_rule(Parser *p) +_tmp_122_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -31018,18 +32538,18 @@ _tmp_116_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_116[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "assignment_expression")); + D(fprintf(stderr, "%*c> _tmp_122[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "assignment_expression")); expr_ty assignment_expression_var; if ( (assignment_expression_var = assignment_expression_rule(p)) // assignment_expression ) { - D(fprintf(stderr, "%*c+ _tmp_116[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "assignment_expression")); + D(fprintf(stderr, "%*c+ _tmp_122[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "assignment_expression")); _res = assignment_expression_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_116[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_122[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "assignment_expression")); } { // expression !':=' @@ -31037,7 +32557,7 @@ _tmp_116_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_116[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression !':='")); + D(fprintf(stderr, "%*c> _tmp_122[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression !':='")); expr_ty expression_var; if ( (expression_var = expression_rule(p)) // expression @@ -31045,12 +32565,12 @@ _tmp_116_rule(Parser *p) _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 53) // token=':=' ) { - D(fprintf(stderr, "%*c+ _tmp_116[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression !':='")); + D(fprintf(stderr, "%*c+ _tmp_122[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression !':='")); _res = expression_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_116[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_122[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression !':='")); } _res = NULL; @@ -31059,13 +32579,12 @@ _tmp_116_rule(Parser *p) return _res; } -// _loop0_118: ',' (starred_expression | (assignment_expression | expression !':=') !'=') +// _loop0_124: ',' (starred_expression | (assignment_expression | expression !':=') !'=') static asdl_seq * -_loop0_118_rule(Parser *p) +_loop0_124_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -31073,7 +32592,6 @@ _loop0_118_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -31088,13 +32606,13 @@ _loop0_118_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_118[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (starred_expression | (assignment_expression | expression !':=') !'=')")); + D(fprintf(stderr, "%*c> _loop0_124[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (starred_expression | (assignment_expression | expression !':=') !'=')")); Token * _literal; void *elem; while ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (elem = _tmp_233_rule(p)) // starred_expression | (assignment_expression | expression !':=') !'=' + (elem = _tmp_259_rule(p)) // starred_expression | (assignment_expression | expression !':=') !'=' ) { _res = elem; @@ -31120,7 +32638,7 @@ _loop0_118_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_118[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_124[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (starred_expression | (assignment_expression | expression !':=') !'=')")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -31133,19 +32651,17 @@ _loop0_118_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_118_type, _seq); p->level--; return _seq; } -// _gather_117: -// | (starred_expression | (assignment_expression | expression !':=') !'=') _loop0_118 +// _gather_123: +// | (starred_expression | (assignment_expression | expression !':=') !'=') _loop0_124 static asdl_seq * -_gather_117_rule(Parser *p) +_gather_123_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -31153,27 +32669,27 @@ _gather_117_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // (starred_expression | (assignment_expression | expression !':=') !'=') _loop0_118 + { // (starred_expression | (assignment_expression | expression !':=') !'=') _loop0_124 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_117[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(starred_expression | (assignment_expression | expression !':=') !'=') _loop0_118")); + D(fprintf(stderr, "%*c> _gather_123[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(starred_expression | (assignment_expression | expression !':=') !'=') _loop0_124")); void *elem; asdl_seq * seq; if ( - (elem = _tmp_233_rule(p)) // starred_expression | (assignment_expression | expression !':=') !'=' + (elem = _tmp_259_rule(p)) // starred_expression | (assignment_expression | expression !':=') !'=' && - (seq = _loop0_118_rule(p)) // _loop0_118 + (seq = _loop0_124_rule(p)) // _loop0_124 ) { - D(fprintf(stderr, "%*c+ _gather_117[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(starred_expression | (assignment_expression | expression !':=') !'=') _loop0_118")); + D(fprintf(stderr, "%*c+ _gather_123[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(starred_expression | (assignment_expression | expression !':=') !'=') _loop0_124")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_117[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(starred_expression | (assignment_expression | expression !':=') !'=') _loop0_118")); + D(fprintf(stderr, "%*c%s _gather_123[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(starred_expression | (assignment_expression | expression !':=') !'=') _loop0_124")); } _res = NULL; done: @@ -31181,13 +32697,12 @@ _gather_117_rule(Parser *p) return _res; } -// _tmp_119: ',' kwargs +// _tmp_125: ',' kwargs static void * -_tmp_119_rule(Parser *p) +_tmp_125_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -31200,7 +32715,7 @@ _tmp_119_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_119[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' kwargs")); + D(fprintf(stderr, "%*c> _tmp_125[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' kwargs")); Token * _literal; asdl_seq* k; if ( @@ -31209,7 +32724,7 @@ _tmp_119_rule(Parser *p) (k = kwargs_rule(p)) // kwargs ) { - D(fprintf(stderr, "%*c+ _tmp_119[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' kwargs")); + D(fprintf(stderr, "%*c+ _tmp_125[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' kwargs")); _res = k; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -31219,7 +32734,7 @@ _tmp_119_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_119[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_125[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' kwargs")); } _res = NULL; @@ -31228,13 +32743,12 @@ _tmp_119_rule(Parser *p) return _res; } -// _loop0_121: ',' kwarg_or_starred +// _loop0_127: ',' kwarg_or_starred static asdl_seq * -_loop0_121_rule(Parser *p) +_loop0_127_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -31242,7 +32756,6 @@ _loop0_121_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -31257,7 +32770,7 @@ _loop0_121_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_121[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' kwarg_or_starred")); + D(fprintf(stderr, "%*c> _loop0_127[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' kwarg_or_starred")); Token * _literal; KeywordOrStarred* elem; while ( @@ -31289,7 +32802,7 @@ _loop0_121_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_121[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_127[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' kwarg_or_starred")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -31302,18 +32815,16 @@ _loop0_121_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_121_type, _seq); p->level--; return _seq; } -// _gather_120: kwarg_or_starred _loop0_121 +// _gather_126: kwarg_or_starred _loop0_127 static asdl_seq * -_gather_120_rule(Parser *p) +_gather_126_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -31321,27 +32832,27 @@ _gather_120_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // kwarg_or_starred _loop0_121 + { // kwarg_or_starred _loop0_127 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_120[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "kwarg_or_starred _loop0_121")); + D(fprintf(stderr, "%*c> _gather_126[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "kwarg_or_starred _loop0_127")); KeywordOrStarred* elem; asdl_seq * seq; if ( (elem = kwarg_or_starred_rule(p)) // kwarg_or_starred && - (seq = _loop0_121_rule(p)) // _loop0_121 + (seq = _loop0_127_rule(p)) // _loop0_127 ) { - D(fprintf(stderr, "%*c+ _gather_120[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "kwarg_or_starred _loop0_121")); + D(fprintf(stderr, "%*c+ _gather_126[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "kwarg_or_starred _loop0_127")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_120[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "kwarg_or_starred _loop0_121")); + D(fprintf(stderr, "%*c%s _gather_126[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "kwarg_or_starred _loop0_127")); } _res = NULL; done: @@ -31349,13 +32860,12 @@ _gather_120_rule(Parser *p) return _res; } -// _loop0_123: ',' kwarg_or_double_starred +// _loop0_129: ',' kwarg_or_double_starred static asdl_seq * -_loop0_123_rule(Parser *p) +_loop0_129_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -31363,7 +32873,6 @@ _loop0_123_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -31378,7 +32887,7 @@ _loop0_123_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_123[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' kwarg_or_double_starred")); + D(fprintf(stderr, "%*c> _loop0_129[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' kwarg_or_double_starred")); Token * _literal; KeywordOrStarred* elem; while ( @@ -31410,7 +32919,7 @@ _loop0_123_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_123[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_129[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' kwarg_or_double_starred")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -31423,18 +32932,16 @@ _loop0_123_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_123_type, _seq); p->level--; return _seq; } -// _gather_122: kwarg_or_double_starred _loop0_123 +// _gather_128: kwarg_or_double_starred _loop0_129 static asdl_seq * -_gather_122_rule(Parser *p) +_gather_128_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -31442,27 +32949,27 @@ _gather_122_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // kwarg_or_double_starred _loop0_123 + { // kwarg_or_double_starred _loop0_129 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_122[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "kwarg_or_double_starred _loop0_123")); + D(fprintf(stderr, "%*c> _gather_128[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "kwarg_or_double_starred _loop0_129")); KeywordOrStarred* elem; asdl_seq * seq; if ( (elem = kwarg_or_double_starred_rule(p)) // kwarg_or_double_starred && - (seq = _loop0_123_rule(p)) // _loop0_123 + (seq = _loop0_129_rule(p)) // _loop0_129 ) { - D(fprintf(stderr, "%*c+ _gather_122[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "kwarg_or_double_starred _loop0_123")); + D(fprintf(stderr, "%*c+ _gather_128[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "kwarg_or_double_starred _loop0_129")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_122[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "kwarg_or_double_starred _loop0_123")); + D(fprintf(stderr, "%*c%s _gather_128[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "kwarg_or_double_starred _loop0_129")); } _res = NULL; done: @@ -31470,13 +32977,12 @@ _gather_122_rule(Parser *p) return _res; } -// _loop0_125: ',' kwarg_or_starred +// _loop0_131: ',' kwarg_or_starred static asdl_seq * -_loop0_125_rule(Parser *p) +_loop0_131_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -31484,7 +32990,6 @@ _loop0_125_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -31499,7 +33004,7 @@ _loop0_125_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_125[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' kwarg_or_starred")); + D(fprintf(stderr, "%*c> _loop0_131[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' kwarg_or_starred")); Token * _literal; KeywordOrStarred* elem; while ( @@ -31531,7 +33036,7 @@ _loop0_125_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_125[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_131[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' kwarg_or_starred")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -31544,18 +33049,16 @@ _loop0_125_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_125_type, _seq); p->level--; return _seq; } -// _gather_124: kwarg_or_starred _loop0_125 +// _gather_130: kwarg_or_starred _loop0_131 static asdl_seq * -_gather_124_rule(Parser *p) +_gather_130_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -31563,27 +33066,27 @@ _gather_124_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // kwarg_or_starred _loop0_125 + { // kwarg_or_starred _loop0_131 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_124[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "kwarg_or_starred _loop0_125")); + D(fprintf(stderr, "%*c> _gather_130[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "kwarg_or_starred _loop0_131")); KeywordOrStarred* elem; asdl_seq * seq; if ( (elem = kwarg_or_starred_rule(p)) // kwarg_or_starred && - (seq = _loop0_125_rule(p)) // _loop0_125 + (seq = _loop0_131_rule(p)) // _loop0_131 ) { - D(fprintf(stderr, "%*c+ _gather_124[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "kwarg_or_starred _loop0_125")); + D(fprintf(stderr, "%*c+ _gather_130[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "kwarg_or_starred _loop0_131")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_124[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "kwarg_or_starred _loop0_125")); + D(fprintf(stderr, "%*c%s _gather_130[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "kwarg_or_starred _loop0_131")); } _res = NULL; done: @@ -31591,13 +33094,12 @@ _gather_124_rule(Parser *p) return _res; } -// _loop0_127: ',' kwarg_or_double_starred +// _loop0_133: ',' kwarg_or_double_starred static asdl_seq * -_loop0_127_rule(Parser *p) +_loop0_133_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -31605,7 +33107,6 @@ _loop0_127_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -31620,7 +33121,7 @@ _loop0_127_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_127[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' kwarg_or_double_starred")); + D(fprintf(stderr, "%*c> _loop0_133[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' kwarg_or_double_starred")); Token * _literal; KeywordOrStarred* elem; while ( @@ -31652,7 +33153,7 @@ _loop0_127_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_127[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_133[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' kwarg_or_double_starred")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -31665,18 +33166,16 @@ _loop0_127_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_127_type, _seq); p->level--; return _seq; } -// _gather_126: kwarg_or_double_starred _loop0_127 +// _gather_132: kwarg_or_double_starred _loop0_133 static asdl_seq * -_gather_126_rule(Parser *p) +_gather_132_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -31684,27 +33183,27 @@ _gather_126_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // kwarg_or_double_starred _loop0_127 + { // kwarg_or_double_starred _loop0_133 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_126[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "kwarg_or_double_starred _loop0_127")); + D(fprintf(stderr, "%*c> _gather_132[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "kwarg_or_double_starred _loop0_133")); KeywordOrStarred* elem; asdl_seq * seq; if ( (elem = kwarg_or_double_starred_rule(p)) // kwarg_or_double_starred && - (seq = _loop0_127_rule(p)) // _loop0_127 + (seq = _loop0_133_rule(p)) // _loop0_133 ) { - D(fprintf(stderr, "%*c+ _gather_126[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "kwarg_or_double_starred _loop0_127")); + D(fprintf(stderr, "%*c+ _gather_132[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "kwarg_or_double_starred _loop0_133")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_126[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "kwarg_or_double_starred _loop0_127")); + D(fprintf(stderr, "%*c%s _gather_132[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "kwarg_or_double_starred _loop0_133")); } _res = NULL; done: @@ -31712,13 +33211,12 @@ _gather_126_rule(Parser *p) return _res; } -// _loop0_128: (',' star_target) +// _loop0_134: (',' star_target) static asdl_seq * -_loop0_128_rule(Parser *p) +_loop0_134_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -31726,7 +33224,6 @@ _loop0_128_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -31741,13 +33238,13 @@ _loop0_128_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_128[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' star_target)")); - void *_tmp_234_var; + D(fprintf(stderr, "%*c> _loop0_134[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' star_target)")); + void *_tmp_260_var; while ( - (_tmp_234_var = _tmp_234_rule(p)) // ',' star_target + (_tmp_260_var = _tmp_260_rule(p)) // ',' star_target ) { - _res = _tmp_234_var; + _res = _tmp_260_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -31764,7 +33261,7 @@ _loop0_128_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_128[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_134[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(',' star_target)")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -31777,18 +33274,16 @@ _loop0_128_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_128_type, _seq); p->level--; return _seq; } -// _loop0_130: ',' star_target +// _loop0_136: ',' star_target static asdl_seq * -_loop0_130_rule(Parser *p) +_loop0_136_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -31796,7 +33291,6 @@ _loop0_130_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -31811,7 +33305,7 @@ _loop0_130_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_130[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_target")); + D(fprintf(stderr, "%*c> _loop0_136[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_target")); Token * _literal; expr_ty elem; while ( @@ -31843,7 +33337,7 @@ _loop0_130_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_130[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_136[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' star_target")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -31856,18 +33350,16 @@ _loop0_130_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_130_type, _seq); p->level--; return _seq; } -// _gather_129: star_target _loop0_130 +// _gather_135: star_target _loop0_136 static asdl_seq * -_gather_129_rule(Parser *p) +_gather_135_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -31875,27 +33367,27 @@ _gather_129_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // star_target _loop0_130 + { // star_target _loop0_136 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_129[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_target _loop0_130")); + D(fprintf(stderr, "%*c> _gather_135[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_target _loop0_136")); expr_ty elem; asdl_seq * seq; if ( (elem = star_target_rule(p)) // star_target && - (seq = _loop0_130_rule(p)) // _loop0_130 + (seq = _loop0_136_rule(p)) // _loop0_136 ) { - D(fprintf(stderr, "%*c+ _gather_129[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_target _loop0_130")); + D(fprintf(stderr, "%*c+ _gather_135[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_target _loop0_136")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_129[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_target _loop0_130")); + D(fprintf(stderr, "%*c%s _gather_135[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_target _loop0_136")); } _res = NULL; done: @@ -31903,13 +33395,12 @@ _gather_129_rule(Parser *p) return _res; } -// _loop1_131: (',' star_target) +// _loop1_137: (',' star_target) static asdl_seq * -_loop1_131_rule(Parser *p) +_loop1_137_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -31917,7 +33408,6 @@ _loop1_131_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -31932,13 +33422,13 @@ _loop1_131_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_131[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' star_target)")); - void *_tmp_235_var; + D(fprintf(stderr, "%*c> _loop1_137[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' star_target)")); + void *_tmp_261_var; while ( - (_tmp_235_var = _tmp_235_rule(p)) // ',' star_target + (_tmp_261_var = _tmp_261_rule(p)) // ',' star_target ) { - _res = _tmp_235_var; + _res = _tmp_261_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -31955,7 +33445,7 @@ _loop1_131_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_131[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop1_137[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(',' star_target)")); } if (_n == 0 || p->error_indicator) { @@ -31973,18 +33463,16 @@ _loop1_131_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_131_type, _seq); p->level--; return _seq; } -// _tmp_132: !'*' star_target +// _tmp_138: !'*' star_target static void * -_tmp_132_rule(Parser *p) +_tmp_138_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -31997,7 +33485,7 @@ _tmp_132_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_132[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "!'*' star_target")); + D(fprintf(stderr, "%*c> _tmp_138[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "!'*' star_target")); expr_ty star_target_var; if ( _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 16) // token='*' @@ -32005,12 +33493,12 @@ _tmp_132_rule(Parser *p) (star_target_var = star_target_rule(p)) // star_target ) { - D(fprintf(stderr, "%*c+ _tmp_132[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "!'*' star_target")); + D(fprintf(stderr, "%*c+ _tmp_138[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "!'*' star_target")); _res = star_target_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_132[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_138[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "!'*' star_target")); } _res = NULL; @@ -32019,13 +33507,12 @@ _tmp_132_rule(Parser *p) return _res; } -// _loop0_134: ',' del_target +// _loop0_140: ',' del_target static asdl_seq * -_loop0_134_rule(Parser *p) +_loop0_140_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -32033,7 +33520,6 @@ _loop0_134_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -32048,7 +33534,7 @@ _loop0_134_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_134[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' del_target")); + D(fprintf(stderr, "%*c> _loop0_140[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' del_target")); Token * _literal; expr_ty elem; while ( @@ -32080,7 +33566,7 @@ _loop0_134_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_134[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_140[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' del_target")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -32093,18 +33579,16 @@ _loop0_134_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_134_type, _seq); p->level--; return _seq; } -// _gather_133: del_target _loop0_134 +// _gather_139: del_target _loop0_140 static asdl_seq * -_gather_133_rule(Parser *p) +_gather_139_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -32112,27 +33596,27 @@ _gather_133_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // del_target _loop0_134 + { // del_target _loop0_140 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_133[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "del_target _loop0_134")); + D(fprintf(stderr, "%*c> _gather_139[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "del_target _loop0_140")); expr_ty elem; asdl_seq * seq; if ( (elem = del_target_rule(p)) // del_target && - (seq = _loop0_134_rule(p)) // _loop0_134 + (seq = _loop0_140_rule(p)) // _loop0_140 ) { - D(fprintf(stderr, "%*c+ _gather_133[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "del_target _loop0_134")); + D(fprintf(stderr, "%*c+ _gather_139[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "del_target _loop0_140")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_133[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "del_target _loop0_134")); + D(fprintf(stderr, "%*c%s _gather_139[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "del_target _loop0_140")); } _res = NULL; done: @@ -32140,13 +33624,12 @@ _gather_133_rule(Parser *p) return _res; } -// _loop0_136: ',' expression +// _loop0_142: ',' expression static asdl_seq * -_loop0_136_rule(Parser *p) +_loop0_142_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -32154,7 +33637,6 @@ _loop0_136_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -32169,7 +33651,7 @@ _loop0_136_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_136[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression")); + D(fprintf(stderr, "%*c> _loop0_142[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression")); Token * _literal; expr_ty elem; while ( @@ -32201,7 +33683,7 @@ _loop0_136_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_136[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_142[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' expression")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -32214,18 +33696,16 @@ _loop0_136_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_136_type, _seq); p->level--; return _seq; } -// _gather_135: expression _loop0_136 +// _gather_141: expression _loop0_142 static asdl_seq * -_gather_135_rule(Parser *p) +_gather_141_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -32233,27 +33713,27 @@ _gather_135_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // expression _loop0_136 + { // expression _loop0_142 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_135[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression _loop0_136")); + D(fprintf(stderr, "%*c> _gather_141[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression _loop0_142")); expr_ty elem; asdl_seq * seq; if ( (elem = expression_rule(p)) // expression && - (seq = _loop0_136_rule(p)) // _loop0_136 + (seq = _loop0_142_rule(p)) // _loop0_142 ) { - D(fprintf(stderr, "%*c+ _gather_135[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression _loop0_136")); + D(fprintf(stderr, "%*c+ _gather_141[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression _loop0_142")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_135[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression _loop0_136")); + D(fprintf(stderr, "%*c%s _gather_141[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression _loop0_142")); } _res = NULL; done: @@ -32261,13 +33741,12 @@ _gather_135_rule(Parser *p) return _res; } -// _loop0_138: ',' expression +// _loop0_144: ',' expression static asdl_seq * -_loop0_138_rule(Parser *p) +_loop0_144_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -32275,7 +33754,6 @@ _loop0_138_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -32290,7 +33768,7 @@ _loop0_138_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_138[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression")); + D(fprintf(stderr, "%*c> _loop0_144[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression")); Token * _literal; expr_ty elem; while ( @@ -32322,7 +33800,7 @@ _loop0_138_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_138[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_144[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' expression")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -32335,18 +33813,16 @@ _loop0_138_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_138_type, _seq); p->level--; return _seq; } -// _gather_137: expression _loop0_138 +// _gather_143: expression _loop0_144 static asdl_seq * -_gather_137_rule(Parser *p) +_gather_143_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -32354,27 +33830,27 @@ _gather_137_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // expression _loop0_138 + { // expression _loop0_144 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_137[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression _loop0_138")); + D(fprintf(stderr, "%*c> _gather_143[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression _loop0_144")); expr_ty elem; asdl_seq * seq; if ( (elem = expression_rule(p)) // expression && - (seq = _loop0_138_rule(p)) // _loop0_138 + (seq = _loop0_144_rule(p)) // _loop0_144 ) { - D(fprintf(stderr, "%*c+ _gather_137[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression _loop0_138")); + D(fprintf(stderr, "%*c+ _gather_143[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression _loop0_144")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_137[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression _loop0_138")); + D(fprintf(stderr, "%*c%s _gather_143[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression _loop0_144")); } _res = NULL; done: @@ -32382,13 +33858,12 @@ _gather_137_rule(Parser *p) return _res; } -// _loop0_140: ',' expression +// _loop0_146: ',' expression static asdl_seq * -_loop0_140_rule(Parser *p) +_loop0_146_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -32396,7 +33871,6 @@ _loop0_140_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -32411,7 +33885,7 @@ _loop0_140_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_140[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression")); + D(fprintf(stderr, "%*c> _loop0_146[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression")); Token * _literal; expr_ty elem; while ( @@ -32443,7 +33917,7 @@ _loop0_140_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_140[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_146[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' expression")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -32456,18 +33930,16 @@ _loop0_140_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_140_type, _seq); p->level--; return _seq; } -// _gather_139: expression _loop0_140 +// _gather_145: expression _loop0_146 static asdl_seq * -_gather_139_rule(Parser *p) +_gather_145_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -32475,27 +33947,27 @@ _gather_139_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // expression _loop0_140 + { // expression _loop0_146 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_139[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression _loop0_140")); + D(fprintf(stderr, "%*c> _gather_145[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression _loop0_146")); expr_ty elem; asdl_seq * seq; if ( (elem = expression_rule(p)) // expression && - (seq = _loop0_140_rule(p)) // _loop0_140 + (seq = _loop0_146_rule(p)) // _loop0_146 ) { - D(fprintf(stderr, "%*c+ _gather_139[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression _loop0_140")); + D(fprintf(stderr, "%*c+ _gather_145[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression _loop0_146")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_139[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression _loop0_140")); + D(fprintf(stderr, "%*c%s _gather_145[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression _loop0_146")); } _res = NULL; done: @@ -32503,13 +33975,12 @@ _gather_139_rule(Parser *p) return _res; } -// _loop0_142: ',' expression +// _loop0_148: ',' expression static asdl_seq * -_loop0_142_rule(Parser *p) +_loop0_148_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -32517,7 +33988,6 @@ _loop0_142_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -32532,7 +34002,7 @@ _loop0_142_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_142[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression")); + D(fprintf(stderr, "%*c> _loop0_148[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression")); Token * _literal; expr_ty elem; while ( @@ -32564,7 +34034,7 @@ _loop0_142_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_142[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _loop0_148[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' expression")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); @@ -32577,18 +34047,16 @@ _loop0_142_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_142_type, _seq); p->level--; return _seq; } -// _gather_141: expression _loop0_142 +// _gather_147: expression _loop0_148 static asdl_seq * -_gather_141_rule(Parser *p) +_gather_147_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -32596,27 +34064,27 @@ _gather_141_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // expression _loop0_142 + { // expression _loop0_148 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_141[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression _loop0_142")); + D(fprintf(stderr, "%*c> _gather_147[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression _loop0_148")); expr_ty elem; asdl_seq * seq; if ( (elem = expression_rule(p)) // expression && - (seq = _loop0_142_rule(p)) // _loop0_142 + (seq = _loop0_148_rule(p)) // _loop0_148 ) { - D(fprintf(stderr, "%*c+ _gather_141[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression _loop0_142")); + D(fprintf(stderr, "%*c+ _gather_147[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression _loop0_148")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_141[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression _loop0_142")); + D(fprintf(stderr, "%*c%s _gather_147[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression _loop0_148")); } _res = NULL; done: @@ -32624,13 +34092,12 @@ _gather_141_rule(Parser *p) return _res; } -// _tmp_143: NEWLINE INDENT +// _tmp_149: NEWLINE INDENT static void * -_tmp_143_rule(Parser *p) +_tmp_149_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -32643,7 +34110,7 @@ _tmp_143_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_143[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NEWLINE INDENT")); + D(fprintf(stderr, "%*c> _tmp_149[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NEWLINE INDENT")); Token * indent_var; Token * newline_var; if ( @@ -32652,12 +34119,12 @@ _tmp_143_rule(Parser *p) (indent_var = _PyPegen_expect_token(p, INDENT)) // token='INDENT' ) { - D(fprintf(stderr, "%*c+ _tmp_143[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NEWLINE INDENT")); + D(fprintf(stderr, "%*c+ _tmp_149[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NEWLINE INDENT")); _res = _PyPegen_dummy_name(p, newline_var, indent_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_143[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_149[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NEWLINE INDENT")); } _res = NULL; @@ -32666,13 +34133,12 @@ _tmp_143_rule(Parser *p) return _res; } -// _tmp_144: args | expression for_if_clauses +// _tmp_150: args | expression for_if_clauses static void * -_tmp_144_rule(Parser *p) +_tmp_150_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -32685,18 +34151,18 @@ _tmp_144_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_144[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "args")); + D(fprintf(stderr, "%*c> _tmp_150[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "args")); expr_ty args_var; if ( (args_var = args_rule(p)) // args ) { - D(fprintf(stderr, "%*c+ _tmp_144[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "args")); + D(fprintf(stderr, "%*c+ _tmp_150[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "args")); _res = args_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_144[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_150[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "args")); } { // expression for_if_clauses @@ -32704,7 +34170,7 @@ _tmp_144_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_144[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression for_if_clauses")); + D(fprintf(stderr, "%*c> _tmp_150[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression for_if_clauses")); expr_ty expression_var; asdl_comprehension_seq* for_if_clauses_var; if ( @@ -32713,27 +34179,806 @@ _tmp_144_rule(Parser *p) (for_if_clauses_var = for_if_clauses_rule(p)) // for_if_clauses ) { - D(fprintf(stderr, "%*c+ _tmp_144[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression for_if_clauses")); + D(fprintf(stderr, "%*c+ _tmp_150[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression for_if_clauses")); _res = _PyPegen_dummy_name(p, expression_var, for_if_clauses_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_144[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_150[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression for_if_clauses")); } - _res = NULL; - done: + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_151: args ',' +static void * +_tmp_151_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // args ',' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_151[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "args ','")); + Token * _literal; + expr_ty args_var; + if ( + (args_var = args_rule(p)) // args + && + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + ) + { + D(fprintf(stderr, "%*c+ _tmp_151[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "args ','")); + _res = _PyPegen_dummy_name(p, args_var, _literal); + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_151[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "args ','")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_152: ',' | ')' +static void * +_tmp_152_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // ',' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_152[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + ) + { + D(fprintf(stderr, "%*c+ _tmp_152[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_152[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); + } + { // ')' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_152[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 8)) // token=')' + ) + { + D(fprintf(stderr, "%*c+ _tmp_152[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_152[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "')'")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_153: 'True' | 'False' | 'None' +static void * +_tmp_153_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // 'True' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_153[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'True'")); + Token * _keyword; + if ( + (_keyword = _PyPegen_expect_token(p, 601)) // token='True' + ) + { + D(fprintf(stderr, "%*c+ _tmp_153[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'True'")); + _res = _keyword; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_153[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'True'")); + } + { // 'False' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_153[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'False'")); + Token * _keyword; + if ( + (_keyword = _PyPegen_expect_token(p, 603)) // token='False' + ) + { + D(fprintf(stderr, "%*c+ _tmp_153[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'False'")); + _res = _keyword; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_153[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'False'")); + } + { // 'None' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_153[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'None'")); + Token * _keyword; + if ( + (_keyword = _PyPegen_expect_token(p, 602)) // token='None' + ) + { + D(fprintf(stderr, "%*c+ _tmp_153[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'None'")); + _res = _keyword; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_153[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'None'")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_154: NAME '=' +static void * +_tmp_154_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // NAME '=' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_154[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME '='")); + Token * _literal; + expr_ty name_var; + if ( + (name_var = _PyPegen_name_token(p)) // NAME + && + (_literal = _PyPegen_expect_token(p, 22)) // token='=' + ) + { + D(fprintf(stderr, "%*c+ _tmp_154[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME '='")); + _res = _PyPegen_dummy_name(p, name_var, _literal); + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_154[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NAME '='")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_155: NAME STRING | SOFT_KEYWORD +static void * +_tmp_155_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // NAME STRING + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_155[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME STRING")); + expr_ty name_var; + expr_ty string_var; + if ( + (name_var = _PyPegen_name_token(p)) // NAME + && + (string_var = _PyPegen_string_token(p)) // STRING + ) + { + D(fprintf(stderr, "%*c+ _tmp_155[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME STRING")); + _res = _PyPegen_dummy_name(p, name_var, string_var); + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_155[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NAME STRING")); + } + { // SOFT_KEYWORD + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_155[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "SOFT_KEYWORD")); + expr_ty soft_keyword_var; + if ( + (soft_keyword_var = _PyPegen_soft_keyword_token(p)) // SOFT_KEYWORD + ) + { + D(fprintf(stderr, "%*c+ _tmp_155[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "SOFT_KEYWORD")); + _res = soft_keyword_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_155[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "SOFT_KEYWORD")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_156: 'else' | ':' +static void * +_tmp_156_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // 'else' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_156[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'else'")); + Token * _keyword; + if ( + (_keyword = _PyPegen_expect_token(p, 645)) // token='else' + ) + { + D(fprintf(stderr, "%*c+ _tmp_156[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'else'")); + _res = _keyword; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_156[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'else'")); + } + { // ':' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_156[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 11)) // token=':' + ) + { + D(fprintf(stderr, "%*c+ _tmp_156[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_156[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_157: '=' | ':=' +static void * +_tmp_157_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // '=' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_157[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'='")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 22)) // token='=' + ) + { + D(fprintf(stderr, "%*c+ _tmp_157[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'='")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_157[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'='")); + } + { // ':=' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_157[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':='")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 53)) // token=':=' + ) + { + D(fprintf(stderr, "%*c+ _tmp_157[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':='")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_157[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':='")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_158: list | tuple | genexp | 'True' | 'None' | 'False' +static void * +_tmp_158_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // list + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_158[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "list")); + expr_ty list_var; + if ( + (list_var = list_rule(p)) // list + ) + { + D(fprintf(stderr, "%*c+ _tmp_158[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "list")); + _res = list_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_158[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "list")); + } + { // tuple + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_158[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "tuple")); + expr_ty tuple_var; + if ( + (tuple_var = tuple_rule(p)) // tuple + ) + { + D(fprintf(stderr, "%*c+ _tmp_158[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "tuple")); + _res = tuple_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_158[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "tuple")); + } + { // genexp + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_158[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "genexp")); + expr_ty genexp_var; + if ( + (genexp_var = genexp_rule(p)) // genexp + ) + { + D(fprintf(stderr, "%*c+ _tmp_158[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "genexp")); + _res = genexp_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_158[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "genexp")); + } + { // 'True' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_158[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'True'")); + Token * _keyword; + if ( + (_keyword = _PyPegen_expect_token(p, 601)) // token='True' + ) + { + D(fprintf(stderr, "%*c+ _tmp_158[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'True'")); + _res = _keyword; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_158[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'True'")); + } + { // 'None' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_158[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'None'")); + Token * _keyword; + if ( + (_keyword = _PyPegen_expect_token(p, 602)) // token='None' + ) + { + D(fprintf(stderr, "%*c+ _tmp_158[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'None'")); + _res = _keyword; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_158[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'None'")); + } + { // 'False' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_158[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'False'")); + Token * _keyword; + if ( + (_keyword = _PyPegen_expect_token(p, 603)) // token='False' + ) + { + D(fprintf(stderr, "%*c+ _tmp_158[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'False'")); + _res = _keyword; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_158[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'False'")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_159: '=' | ':=' +static void * +_tmp_159_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // '=' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_159[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'='")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 22)) // token='=' + ) + { + D(fprintf(stderr, "%*c+ _tmp_159[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'='")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_159[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'='")); + } + { // ':=' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_159[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':='")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 53)) // token=':=' + ) + { + D(fprintf(stderr, "%*c+ _tmp_159[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':='")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_159[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':='")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop0_160: star_named_expressions +static asdl_seq * +_loop0_160_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void *_res = NULL; + int _mark = p->mark; + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // star_named_expressions + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_160[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_named_expressions")); + asdl_expr_seq* star_named_expressions_var; + while ( + (star_named_expressions_var = star_named_expressions_rule(p)) // star_named_expressions + ) + { + _res = star_named_expressions_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + _children = _new_children; + } + _children[_n++] = _res; + _mark = p->mark; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _loop0_160[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_named_expressions")); + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); + PyMem_Free(_children); + p->level--; + return _seq; +} + +// _loop0_161: (star_targets '=') +static asdl_seq * +_loop0_161_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void *_res = NULL; + int _mark = p->mark; + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // (star_targets '=') + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_161[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')")); + void *_tmp_262_var; + while ( + (_tmp_262_var = _tmp_262_rule(p)) // star_targets '=' + ) + { + _res = _tmp_262_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + _children = _new_children; + } + _children[_n++] = _res; + _mark = p->mark; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _loop0_161[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(star_targets '=')")); + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); + PyMem_Free(_children); + p->level--; + return _seq; +} + +// _loop0_162: (star_targets '=') +static asdl_seq * +_loop0_162_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void *_res = NULL; + int _mark = p->mark; + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // (star_targets '=') + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_162[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')")); + void *_tmp_263_var; + while ( + (_tmp_263_var = _tmp_263_rule(p)) // star_targets '=' + ) + { + _res = _tmp_263_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + _children = _new_children; + } + _children[_n++] = _res; + _mark = p->mark; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _loop0_162[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(star_targets '=')")); + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); + PyMem_Free(_children); p->level--; - return _res; + return _seq; } -// _tmp_145: 'True' | 'False' | 'None' +// _tmp_163: yield_expr | star_expressions static void * -_tmp_145_rule(Parser *p) +_tmp_163_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -32741,62 +34986,43 @@ _tmp_145_rule(Parser *p) } void * _res = NULL; int _mark = p->mark; - { // 'True' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_145[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'True'")); - Token * _keyword; - if ( - (_keyword = _PyPegen_expect_token(p, 600)) // token='True' - ) - { - D(fprintf(stderr, "%*c+ _tmp_145[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'True'")); - _res = _keyword; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_145[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'True'")); - } - { // 'False' + { // yield_expr if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_145[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'False'")); - Token * _keyword; + D(fprintf(stderr, "%*c> _tmp_163[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); + expr_ty yield_expr_var; if ( - (_keyword = _PyPegen_expect_token(p, 602)) // token='False' + (yield_expr_var = yield_expr_rule(p)) // yield_expr ) { - D(fprintf(stderr, "%*c+ _tmp_145[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'False'")); - _res = _keyword; + D(fprintf(stderr, "%*c+ _tmp_163[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); + _res = yield_expr_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_145[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'False'")); + D(fprintf(stderr, "%*c%s _tmp_163[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "yield_expr")); } - { // 'None' + { // star_expressions if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_145[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'None'")); - Token * _keyword; + D(fprintf(stderr, "%*c> _tmp_163[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); + expr_ty star_expressions_var; if ( - (_keyword = _PyPegen_expect_token(p, 601)) // token='None' + (star_expressions_var = star_expressions_rule(p)) // star_expressions ) { - D(fprintf(stderr, "%*c+ _tmp_145[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'None'")); - _res = _keyword; + D(fprintf(stderr, "%*c+ _tmp_163[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); + _res = star_expressions_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_145[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'None'")); + D(fprintf(stderr, "%*c%s _tmp_163[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions")); } _res = NULL; done: @@ -32804,13 +35030,12 @@ _tmp_145_rule(Parser *p) return _res; } -// _tmp_146: NAME '=' +// _tmp_164: '[' | '(' | '{' static void * -_tmp_146_rule(Parser *p) +_tmp_164_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -32818,88 +35043,62 @@ _tmp_146_rule(Parser *p) } void * _res = NULL; int _mark = p->mark; - { // NAME '=' + { // '[' if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_146[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME '='")); + D(fprintf(stderr, "%*c> _tmp_164[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'['")); Token * _literal; - expr_ty name_var; if ( - (name_var = _PyPegen_name_token(p)) // NAME - && - (_literal = _PyPegen_expect_token(p, 22)) // token='=' + (_literal = _PyPegen_expect_token(p, 9)) // token='[' ) { - D(fprintf(stderr, "%*c+ _tmp_146[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME '='")); - _res = _PyPegen_dummy_name(p, name_var, _literal); + D(fprintf(stderr, "%*c+ _tmp_164[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'['")); + _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_146[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NAME '='")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _tmp_147: NAME STRING | SOFT_KEYWORD -static void * -_tmp_147_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; + D(fprintf(stderr, "%*c%s _tmp_164[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'['")); } - void * _res = NULL; - int _mark = p->mark; - { // NAME STRING + { // '(' if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_147[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME STRING")); - expr_ty name_var; - expr_ty string_var; + D(fprintf(stderr, "%*c> _tmp_164[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'('")); + Token * _literal; if ( - (name_var = _PyPegen_name_token(p)) // NAME - && - (string_var = _PyPegen_string_token(p)) // STRING + (_literal = _PyPegen_expect_token(p, 7)) // token='(' ) { - D(fprintf(stderr, "%*c+ _tmp_147[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME STRING")); - _res = _PyPegen_dummy_name(p, name_var, string_var); + D(fprintf(stderr, "%*c+ _tmp_164[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'('")); + _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_147[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NAME STRING")); + D(fprintf(stderr, "%*c%s _tmp_164[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'('")); } - { // SOFT_KEYWORD + { // '{' if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_147[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "SOFT_KEYWORD")); - expr_ty soft_keyword_var; + D(fprintf(stderr, "%*c> _tmp_164[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{'")); + Token * _literal; if ( - (soft_keyword_var = _PyPegen_soft_keyword_token(p)) // SOFT_KEYWORD + (_literal = _PyPegen_expect_token(p, 25)) // token='{' ) { - D(fprintf(stderr, "%*c+ _tmp_147[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "SOFT_KEYWORD")); - _res = soft_keyword_var; + D(fprintf(stderr, "%*c+ _tmp_164[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{'")); + _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_147[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "SOFT_KEYWORD")); + D(fprintf(stderr, "%*c%s _tmp_164[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'{'")); } _res = NULL; done: @@ -32907,13 +35106,12 @@ _tmp_147_rule(Parser *p) return _res; } -// _tmp_148: 'else' | ':' +// _tmp_165: '[' | '{' static void * -_tmp_148_rule(Parser *p) +_tmp_165_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -32921,43 +35119,43 @@ _tmp_148_rule(Parser *p) } void * _res = NULL; int _mark = p->mark; - { // 'else' + { // '[' if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_148[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'else'")); - Token * _keyword; + D(fprintf(stderr, "%*c> _tmp_165[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'['")); + Token * _literal; if ( - (_keyword = _PyPegen_expect_token(p, 642)) // token='else' + (_literal = _PyPegen_expect_token(p, 9)) // token='[' ) { - D(fprintf(stderr, "%*c+ _tmp_148[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'else'")); - _res = _keyword; + D(fprintf(stderr, "%*c+ _tmp_165[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'['")); + _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_148[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'else'")); + D(fprintf(stderr, "%*c%s _tmp_165[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'['")); } - { // ':' + { // '{' if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_148[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c> _tmp_165[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{'")); Token * _literal; if ( - (_literal = _PyPegen_expect_token(p, 11)) // token=':' + (_literal = _PyPegen_expect_token(p, 25)) // token='{' ) { - D(fprintf(stderr, "%*c+ _tmp_148[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c+ _tmp_165[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_148[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c%s _tmp_165[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'{'")); } _res = NULL; done: @@ -32965,13 +35163,12 @@ _tmp_148_rule(Parser *p) return _res; } -// _tmp_149: '=' | ':=' +// _tmp_166: '[' | '{' static void * -_tmp_149_rule(Parser *p) +_tmp_166_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -32979,43 +35176,43 @@ _tmp_149_rule(Parser *p) } void * _res = NULL; int _mark = p->mark; - { // '=' + { // '[' if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_149[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'='")); + D(fprintf(stderr, "%*c> _tmp_166[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'['")); Token * _literal; if ( - (_literal = _PyPegen_expect_token(p, 22)) // token='=' + (_literal = _PyPegen_expect_token(p, 9)) // token='[' ) { - D(fprintf(stderr, "%*c+ _tmp_149[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'='")); + D(fprintf(stderr, "%*c+ _tmp_166[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'['")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_149[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'='")); + D(fprintf(stderr, "%*c%s _tmp_166[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'['")); } - { // ':=' + { // '{' if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_149[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':='")); + D(fprintf(stderr, "%*c> _tmp_166[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{'")); Token * _literal; if ( - (_literal = _PyPegen_expect_token(p, 53)) // token=':=' + (_literal = _PyPegen_expect_token(p, 25)) // token='{' ) { - D(fprintf(stderr, "%*c+ _tmp_149[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':='")); + D(fprintf(stderr, "%*c+ _tmp_166[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_149[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':='")); + D(fprintf(stderr, "%*c%s _tmp_166[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'{'")); } _res = NULL; done: @@ -33023,13 +35220,12 @@ _tmp_149_rule(Parser *p) return _res; } -// _tmp_150: list | tuple | genexp | 'True' | 'None' | 'False' +// _tmp_167: slash_no_default | slash_with_default static void * -_tmp_150_rule(Parser *p) +_tmp_167_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -33037,133 +35233,329 @@ _tmp_150_rule(Parser *p) } void * _res = NULL; int _mark = p->mark; - { // list + { // slash_no_default if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_150[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "list")); - expr_ty list_var; + D(fprintf(stderr, "%*c> _tmp_167[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_no_default")); + asdl_arg_seq* slash_no_default_var; if ( - (list_var = list_rule(p)) // list + (slash_no_default_var = slash_no_default_rule(p)) // slash_no_default ) { - D(fprintf(stderr, "%*c+ _tmp_150[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "list")); - _res = list_var; + D(fprintf(stderr, "%*c+ _tmp_167[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_no_default")); + _res = slash_no_default_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_150[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "list")); + D(fprintf(stderr, "%*c%s _tmp_167[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "slash_no_default")); } - { // tuple + { // slash_with_default if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_150[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "tuple")); - expr_ty tuple_var; + D(fprintf(stderr, "%*c> _tmp_167[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_with_default")); + SlashWithDefault* slash_with_default_var; if ( - (tuple_var = tuple_rule(p)) // tuple + (slash_with_default_var = slash_with_default_rule(p)) // slash_with_default ) { - D(fprintf(stderr, "%*c+ _tmp_150[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "tuple")); - _res = tuple_var; + D(fprintf(stderr, "%*c+ _tmp_167[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_with_default")); + _res = slash_with_default_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_150[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "tuple")); + D(fprintf(stderr, "%*c%s _tmp_167[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "slash_with_default")); } - { // genexp + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop0_168: param_maybe_default +static asdl_seq * +_loop0_168_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void *_res = NULL; + int _mark = p->mark; + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // param_maybe_default if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_150[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "genexp")); - expr_ty genexp_var; - if ( - (genexp_var = genexp_rule(p)) // genexp + D(fprintf(stderr, "%*c> _loop0_168[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); + NameDefaultPair* param_maybe_default_var; + while ( + (param_maybe_default_var = param_maybe_default_rule(p)) // param_maybe_default ) { - D(fprintf(stderr, "%*c+ _tmp_150[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "genexp")); - _res = genexp_var; - goto done; + _res = param_maybe_default_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + _children = _new_children; + } + _children[_n++] = _res; + _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_150[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "genexp")); + D(fprintf(stderr, "%*c%s _loop0_168[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_maybe_default")); } - { // 'True' + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); + PyMem_Free(_children); + p->level--; + return _seq; +} + +// _loop0_169: param_no_default +static asdl_seq * +_loop0_169_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void *_res = NULL; + int _mark = p->mark; + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // param_no_default if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_150[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'True'")); - Token * _keyword; - if ( - (_keyword = _PyPegen_expect_token(p, 600)) // token='True' + D(fprintf(stderr, "%*c> _loop0_169[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); + arg_ty param_no_default_var; + while ( + (param_no_default_var = param_no_default_rule(p)) // param_no_default ) { - D(fprintf(stderr, "%*c+ _tmp_150[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'True'")); - _res = _keyword; - goto done; + _res = param_no_default_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + _children = _new_children; + } + _children[_n++] = _res; + _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_150[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'True'")); + D(fprintf(stderr, "%*c%s _loop0_169[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); } - { // 'None' + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); + PyMem_Free(_children); + p->level--; + return _seq; +} + +// _loop0_170: param_no_default +static asdl_seq * +_loop0_170_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void *_res = NULL; + int _mark = p->mark; + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // param_no_default if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_150[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'None'")); - Token * _keyword; - if ( - (_keyword = _PyPegen_expect_token(p, 601)) // token='None' + D(fprintf(stderr, "%*c> _loop0_170[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); + arg_ty param_no_default_var; + while ( + (param_no_default_var = param_no_default_rule(p)) // param_no_default ) { - D(fprintf(stderr, "%*c+ _tmp_150[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'None'")); - _res = _keyword; - goto done; + _res = param_no_default_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + _children = _new_children; + } + _children[_n++] = _res; + _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_150[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'None'")); + D(fprintf(stderr, "%*c%s _loop0_170[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); } - { // 'False' + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); + PyMem_Free(_children); + p->level--; + return _seq; +} + +// _loop1_171: param_no_default +static asdl_seq * +_loop1_171_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void *_res = NULL; + int _mark = p->mark; + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // param_no_default if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_150[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'False'")); - Token * _keyword; - if ( - (_keyword = _PyPegen_expect_token(p, 602)) // token='False' + D(fprintf(stderr, "%*c> _loop1_171[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); + arg_ty param_no_default_var; + while ( + (param_no_default_var = param_no_default_rule(p)) // param_no_default ) { - D(fprintf(stderr, "%*c+ _tmp_150[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'False'")); - _res = _keyword; - goto done; + _res = param_no_default_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + _children = _new_children; + } + _children[_n++] = _res; + _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_150[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'False'")); + D(fprintf(stderr, "%*c%s _loop1_171[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); } - _res = NULL; - done: + if (_n == 0 || p->error_indicator) { + PyMem_Free(_children); + p->level--; + return NULL; + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); + PyMem_Free(_children); p->level--; - return _res; + return _seq; } -// _tmp_151: '=' | ':=' +// _tmp_172: slash_no_default | slash_with_default static void * -_tmp_151_rule(Parser *p) +_tmp_172_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -33171,43 +35563,43 @@ _tmp_151_rule(Parser *p) } void * _res = NULL; int _mark = p->mark; - { // '=' + { // slash_no_default if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_151[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'='")); - Token * _literal; + D(fprintf(stderr, "%*c> _tmp_172[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_no_default")); + asdl_arg_seq* slash_no_default_var; if ( - (_literal = _PyPegen_expect_token(p, 22)) // token='=' + (slash_no_default_var = slash_no_default_rule(p)) // slash_no_default ) { - D(fprintf(stderr, "%*c+ _tmp_151[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'='")); - _res = _literal; + D(fprintf(stderr, "%*c+ _tmp_172[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_no_default")); + _res = slash_no_default_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_151[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'='")); + D(fprintf(stderr, "%*c%s _tmp_172[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "slash_no_default")); } - { // ':=' + { // slash_with_default if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_151[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':='")); - Token * _literal; + D(fprintf(stderr, "%*c> _tmp_172[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_with_default")); + SlashWithDefault* slash_with_default_var; if ( - (_literal = _PyPegen_expect_token(p, 53)) // token=':=' + (slash_with_default_var = slash_with_default_rule(p)) // slash_with_default ) { - D(fprintf(stderr, "%*c+ _tmp_151[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':='")); - _res = _literal; + D(fprintf(stderr, "%*c+ _tmp_172[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_with_default")); + _res = slash_with_default_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_151[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':='")); + D(fprintf(stderr, "%*c%s _tmp_172[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "slash_with_default")); } _res = NULL; done: @@ -33215,13 +35607,12 @@ _tmp_151_rule(Parser *p) return _res; } -// _loop0_152: star_named_expressions +// _loop0_173: param_maybe_default static asdl_seq * -_loop0_152_rule(Parser *p) +_loop0_173_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -33229,7 +35620,6 @@ _loop0_152_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -33239,18 +35629,18 @@ _loop0_152_rule(Parser *p) } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; - { // star_named_expressions + { // param_maybe_default if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_152[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_named_expressions")); - asdl_expr_seq* star_named_expressions_var; + D(fprintf(stderr, "%*c> _loop0_173[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); + NameDefaultPair* param_maybe_default_var; while ( - (star_named_expressions_var = star_named_expressions_rule(p)) // star_named_expressions + (param_maybe_default_var = param_maybe_default_rule(p)) // param_maybe_default ) { - _res = star_named_expressions_var; + _res = param_maybe_default_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -33267,31 +35657,86 @@ _loop0_152_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_152[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_named_expressions")); - } - asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); - if (!_seq) { - PyMem_Free(_children); - p->error_indicator = 1; - PyErr_NoMemory(); - p->level--; - return NULL; + D(fprintf(stderr, "%*c%s _loop0_173[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_maybe_default")); + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); + PyMem_Free(_children); + p->level--; + return _seq; +} + +// _tmp_174: ',' | param_no_default +static void * +_tmp_174_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // ',' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_174[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + ) + { + D(fprintf(stderr, "%*c+ _tmp_174[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_174[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); + } + { // param_no_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_174[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); + arg_ty param_no_default_var; + if ( + (param_no_default_var = param_no_default_rule(p)) // param_no_default + ) + { + D(fprintf(stderr, "%*c+ _tmp_174[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_no_default")); + _res = param_no_default_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_174[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); } - for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_152_type, _seq); + _res = NULL; + done: p->level--; - return _seq; + return _res; } -// _loop0_153: (star_targets '=') +// _loop0_175: param_maybe_default static asdl_seq * -_loop0_153_rule(Parser *p) +_loop0_175_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -33299,7 +35744,6 @@ _loop0_153_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -33309,18 +35753,18 @@ _loop0_153_rule(Parser *p) } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; - { // (star_targets '=') + { // param_maybe_default if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_153[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')")); - void *_tmp_236_var; + D(fprintf(stderr, "%*c> _loop0_175[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); + NameDefaultPair* param_maybe_default_var; while ( - (_tmp_236_var = _tmp_236_rule(p)) // star_targets '=' + (param_maybe_default_var = param_maybe_default_rule(p)) // param_maybe_default ) { - _res = _tmp_236_var; + _res = param_maybe_default_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -33337,8 +35781,8 @@ _loop0_153_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_153[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(star_targets '=')")); + D(fprintf(stderr, "%*c%s _loop0_175[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_maybe_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { @@ -33350,18 +35794,16 @@ _loop0_153_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_153_type, _seq); p->level--; return _seq; } -// _loop0_154: (star_targets '=') +// _loop1_176: param_maybe_default static asdl_seq * -_loop0_154_rule(Parser *p) +_loop1_176_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -33369,7 +35811,6 @@ _loop0_154_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -33379,18 +35820,18 @@ _loop0_154_rule(Parser *p) } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; - { // (star_targets '=') + { // param_maybe_default if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_154[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')")); - void *_tmp_237_var; + D(fprintf(stderr, "%*c> _loop1_176[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); + NameDefaultPair* param_maybe_default_var; while ( - (_tmp_237_var = _tmp_237_rule(p)) // star_targets '=' + (param_maybe_default_var = param_maybe_default_rule(p)) // param_maybe_default ) { - _res = _tmp_237_var; + _res = param_maybe_default_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -33407,8 +35848,13 @@ _loop0_154_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_154[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(star_targets '=')")); + D(fprintf(stderr, "%*c%s _loop1_176[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_maybe_default")); + } + if (_n == 0 || p->error_indicator) { + PyMem_Free(_children); + p->level--; + return NULL; } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { @@ -33420,18 +35866,16 @@ _loop0_154_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_154_type, _seq); p->level--; return _seq; } -// _tmp_155: yield_expr | star_expressions +// _tmp_177: ')' | ',' static void * -_tmp_155_rule(Parser *p) +_tmp_177_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -33439,43 +35883,43 @@ _tmp_155_rule(Parser *p) } void * _res = NULL; int _mark = p->mark; - { // yield_expr + { // ')' if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_155[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); - expr_ty yield_expr_var; + D(fprintf(stderr, "%*c> _tmp_177[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); + Token * _literal; if ( - (yield_expr_var = yield_expr_rule(p)) // yield_expr + (_literal = _PyPegen_expect_token(p, 8)) // token=')' ) { - D(fprintf(stderr, "%*c+ _tmp_155[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); - _res = yield_expr_var; + D(fprintf(stderr, "%*c+ _tmp_177[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); + _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_155[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "yield_expr")); + D(fprintf(stderr, "%*c%s _tmp_177[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "')'")); } - { // star_expressions + { // ',' if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_155[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); - expr_ty star_expressions_var; + D(fprintf(stderr, "%*c> _tmp_177[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + Token * _literal; if ( - (star_expressions_var = star_expressions_rule(p)) // star_expressions + (_literal = _PyPegen_expect_token(p, 12)) // token=',' ) { - D(fprintf(stderr, "%*c+ _tmp_155[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); - _res = star_expressions_var; + D(fprintf(stderr, "%*c+ _tmp_177[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_155[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions")); + D(fprintf(stderr, "%*c%s _tmp_177[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); } _res = NULL; done: @@ -33483,13 +35927,12 @@ _tmp_155_rule(Parser *p) return _res; } -// _tmp_156: '[' | '(' | '{' +// _tmp_178: ')' | ',' (')' | '**') static void * -_tmp_156_rule(Parser *p) +_tmp_178_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -33497,62 +35940,103 @@ _tmp_156_rule(Parser *p) } void * _res = NULL; int _mark = p->mark; - { // '[' + { // ')' if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_156[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'['")); + D(fprintf(stderr, "%*c> _tmp_178[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); Token * _literal; if ( - (_literal = _PyPegen_expect_token(p, 9)) // token='[' + (_literal = _PyPegen_expect_token(p, 8)) // token=')' ) { - D(fprintf(stderr, "%*c+ _tmp_156[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'['")); + D(fprintf(stderr, "%*c+ _tmp_178[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_156[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'['")); + D(fprintf(stderr, "%*c%s _tmp_178[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "')'")); } - { // '(' + { // ',' (')' | '**') if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_156[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'('")); + D(fprintf(stderr, "%*c> _tmp_178[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (')' | '**')")); Token * _literal; + void *_tmp_264_var; if ( - (_literal = _PyPegen_expect_token(p, 7)) // token='(' + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (_tmp_264_var = _tmp_264_rule(p)) // ')' | '**' ) { - D(fprintf(stderr, "%*c+ _tmp_156[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'('")); - _res = _literal; + D(fprintf(stderr, "%*c+ _tmp_178[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' (')' | '**')")); + _res = _PyPegen_dummy_name(p, _literal, _tmp_264_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_156[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'('")); + D(fprintf(stderr, "%*c%s _tmp_178[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (')' | '**')")); } - { // '{' + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_179: param_no_default | ',' +static void * +_tmp_179_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // param_no_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_179[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); + arg_ty param_no_default_var; + if ( + (param_no_default_var = param_no_default_rule(p)) // param_no_default + ) + { + D(fprintf(stderr, "%*c+ _tmp_179[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_no_default")); + _res = param_no_default_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_179[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); + } + { // ',' if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_156[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{'")); + D(fprintf(stderr, "%*c> _tmp_179[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); Token * _literal; if ( - (_literal = _PyPegen_expect_token(p, 25)) // token='{' + (_literal = _PyPegen_expect_token(p, 12)) // token=',' ) { - D(fprintf(stderr, "%*c+ _tmp_156[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{'")); + D(fprintf(stderr, "%*c+ _tmp_179[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_156[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'{'")); + D(fprintf(stderr, "%*c%s _tmp_179[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); } _res = NULL; done: @@ -33560,13 +36044,79 @@ _tmp_156_rule(Parser *p) return _res; } -// _tmp_157: '[' | '{' -static void * -_tmp_157_rule(Parser *p) +// _loop0_180: param_maybe_default +static asdl_seq * +_loop0_180_rule(Parser *p) { if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void *_res = NULL; + int _mark = p->mark; + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // param_maybe_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _loop0_180[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); + NameDefaultPair* param_maybe_default_var; + while ( + (param_maybe_default_var = param_maybe_default_rule(p)) // param_maybe_default + ) + { + _res = param_maybe_default_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + _children = _new_children; + } + _children[_n++] = _res; + _mark = p->mark; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _loop0_180[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_maybe_default")); + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); p->error_indicator = 1; PyErr_NoMemory(); + p->level--; + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); + PyMem_Free(_children); + p->level--; + return _seq; +} + +// _tmp_181: param_no_default | ',' +static void * +_tmp_181_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -33574,43 +36124,43 @@ _tmp_157_rule(Parser *p) } void * _res = NULL; int _mark = p->mark; - { // '[' + { // param_no_default if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_157[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'['")); - Token * _literal; + D(fprintf(stderr, "%*c> _tmp_181[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); + arg_ty param_no_default_var; if ( - (_literal = _PyPegen_expect_token(p, 9)) // token='[' + (param_no_default_var = param_no_default_rule(p)) // param_no_default ) { - D(fprintf(stderr, "%*c+ _tmp_157[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'['")); - _res = _literal; + D(fprintf(stderr, "%*c+ _tmp_181[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_no_default")); + _res = param_no_default_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_157[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'['")); + D(fprintf(stderr, "%*c%s _tmp_181[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); } - { // '{' + { // ',' if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_157[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{'")); + D(fprintf(stderr, "%*c> _tmp_181[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); Token * _literal; if ( - (_literal = _PyPegen_expect_token(p, 25)) // token='{' + (_literal = _PyPegen_expect_token(p, 12)) // token=',' ) { - D(fprintf(stderr, "%*c+ _tmp_157[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{'")); + D(fprintf(stderr, "%*c+ _tmp_181[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_157[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'{'")); + D(fprintf(stderr, "%*c%s _tmp_181[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); } _res = NULL; done: @@ -33618,13 +36168,12 @@ _tmp_157_rule(Parser *p) return _res; } -// _tmp_158: '[' | '{' +// _tmp_182: '*' | '**' | '/' static void * -_tmp_158_rule(Parser *p) +_tmp_182_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -33632,43 +36181,62 @@ _tmp_158_rule(Parser *p) } void * _res = NULL; int _mark = p->mark; - { // '[' + { // '*' if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_158[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'['")); + D(fprintf(stderr, "%*c> _tmp_182[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*'")); Token * _literal; if ( - (_literal = _PyPegen_expect_token(p, 9)) // token='[' + (_literal = _PyPegen_expect_token(p, 16)) // token='*' ) { - D(fprintf(stderr, "%*c+ _tmp_158[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'['")); + D(fprintf(stderr, "%*c+ _tmp_182[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_158[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'['")); + D(fprintf(stderr, "%*c%s _tmp_182[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*'")); } - { // '{' + { // '**' if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_158[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{'")); + D(fprintf(stderr, "%*c> _tmp_182[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); Token * _literal; if ( - (_literal = _PyPegen_expect_token(p, 25)) // token='{' + (_literal = _PyPegen_expect_token(p, 35)) // token='**' ) { - D(fprintf(stderr, "%*c+ _tmp_158[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{'")); + D(fprintf(stderr, "%*c+ _tmp_182[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_158[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'{'")); + D(fprintf(stderr, "%*c%s _tmp_182[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**'")); + } + { // '/' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_182[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'/'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 17)) // token='/' + ) + { + D(fprintf(stderr, "%*c+ _tmp_182[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'/'")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_182[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'/'")); } _res = NULL; done: @@ -33676,13 +36244,12 @@ _tmp_158_rule(Parser *p) return _res; } -// _loop0_159: param_no_default +// _loop1_183: param_with_default static asdl_seq * -_loop0_159_rule(Parser *p) +_loop1_183_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -33690,7 +36257,6 @@ _loop0_159_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -33700,18 +36266,18 @@ _loop0_159_rule(Parser *p) } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; - { // param_no_default + { // param_with_default if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_159[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); - arg_ty param_no_default_var; + D(fprintf(stderr, "%*c> _loop1_183[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default")); + NameDefaultPair* param_with_default_var; while ( - (param_no_default_var = param_no_default_rule(p)) // param_no_default + (param_with_default_var = param_with_default_rule(p)) // param_with_default ) { - _res = param_no_default_var; + _res = param_with_default_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -33728,8 +36294,13 @@ _loop0_159_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_159[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); + D(fprintf(stderr, "%*c%s _loop1_183[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_with_default")); + } + if (_n == 0 || p->error_indicator) { + PyMem_Free(_children); + p->level--; + return NULL; } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { @@ -33741,18 +36312,73 @@ _loop0_159_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_159_type, _seq); p->level--; return _seq; } -// _loop0_160: param_no_default +// _tmp_184: lambda_slash_no_default | lambda_slash_with_default +static void * +_tmp_184_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // lambda_slash_no_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_184[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default")); + asdl_arg_seq* lambda_slash_no_default_var; + if ( + (lambda_slash_no_default_var = lambda_slash_no_default_rule(p)) // lambda_slash_no_default + ) + { + D(fprintf(stderr, "%*c+ _tmp_184[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default")); + _res = lambda_slash_no_default_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_184[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_slash_no_default")); + } + { // lambda_slash_with_default + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_184[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default")); + SlashWithDefault* lambda_slash_with_default_var; + if ( + (lambda_slash_with_default_var = lambda_slash_with_default_rule(p)) // lambda_slash_with_default + ) + { + D(fprintf(stderr, "%*c+ _tmp_184[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default")); + _res = lambda_slash_with_default_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_184[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_slash_with_default")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop0_185: lambda_param_maybe_default static asdl_seq * -_loop0_160_rule(Parser *p) +_loop0_185_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -33760,7 +36386,6 @@ _loop0_160_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -33770,18 +36395,18 @@ _loop0_160_rule(Parser *p) } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; - { // param_no_default + { // lambda_param_maybe_default if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_160[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); - arg_ty param_no_default_var; + D(fprintf(stderr, "%*c> _loop0_185[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); + NameDefaultPair* lambda_param_maybe_default_var; while ( - (param_no_default_var = param_no_default_rule(p)) // param_no_default + (lambda_param_maybe_default_var = lambda_param_maybe_default_rule(p)) // lambda_param_maybe_default ) { - _res = param_no_default_var; + _res = lambda_param_maybe_default_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -33798,8 +36423,8 @@ _loop0_160_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_160[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); + D(fprintf(stderr, "%*c%s _loop0_185[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_maybe_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { @@ -33811,18 +36436,16 @@ _loop0_160_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_160_type, _seq); p->level--; return _seq; } -// _loop1_161: param_no_default +// _loop0_186: lambda_param_no_default static asdl_seq * -_loop1_161_rule(Parser *p) +_loop0_186_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -33830,7 +36453,6 @@ _loop1_161_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -33840,18 +36462,18 @@ _loop1_161_rule(Parser *p) } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; - { // param_no_default + { // lambda_param_no_default if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_161[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); - arg_ty param_no_default_var; + D(fprintf(stderr, "%*c> _loop0_186[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + arg_ty lambda_param_no_default_var; while ( - (param_no_default_var = param_no_default_rule(p)) // param_no_default + (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default ) { - _res = param_no_default_var; + _res = lambda_param_no_default_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -33868,13 +36490,8 @@ _loop1_161_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_161[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); - } - if (_n == 0 || p->error_indicator) { - PyMem_Free(_children); - p->level--; - return NULL; + D(fprintf(stderr, "%*c%s _loop0_186[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { @@ -33886,76 +36503,83 @@ _loop1_161_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_161_type, _seq); p->level--; return _seq; } -// _tmp_162: slash_no_default | slash_with_default -static void * -_tmp_162_rule(Parser *p) +// _loop0_187: lambda_param_no_default +static asdl_seq * +_loop0_187_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; return NULL; } - void * _res = NULL; + void *_res = NULL; int _mark = p->mark; - { // slash_no_default - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_162[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_no_default")); - asdl_arg_seq* slash_no_default_var; - if ( - (slash_no_default_var = slash_no_default_rule(p)) // slash_no_default - ) - { - D(fprintf(stderr, "%*c+ _tmp_162[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_no_default")); - _res = slash_no_default_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_162[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "slash_no_default")); + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; } - { // slash_with_default + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // lambda_param_no_default if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_162[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_with_default")); - SlashWithDefault* slash_with_default_var; - if ( - (slash_with_default_var = slash_with_default_rule(p)) // slash_with_default + D(fprintf(stderr, "%*c> _loop0_187[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + arg_ty lambda_param_no_default_var; + while ( + (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default ) { - D(fprintf(stderr, "%*c+ _tmp_162[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_with_default")); - _res = slash_with_default_var; - goto done; + _res = lambda_param_no_default_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + _children = _new_children; + } + _children[_n++] = _res; + _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_162[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "slash_with_default")); + D(fprintf(stderr, "%*c%s _loop0_187[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); } - _res = NULL; - done: + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); + PyMem_Free(_children); p->level--; - return _res; + return _seq; } -// _loop0_163: param_maybe_default +// _loop0_189: ',' lambda_param static asdl_seq * -_loop0_163_rule(Parser *p) +_loop0_189_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -33963,7 +36587,6 @@ _loop0_163_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -33973,18 +36596,27 @@ _loop0_163_rule(Parser *p) } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; - { // param_maybe_default + { // ',' lambda_param if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_163[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); - NameDefaultPair* param_maybe_default_var; + D(fprintf(stderr, "%*c> _loop0_189[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' lambda_param")); + Token * _literal; + arg_ty elem; while ( - (param_maybe_default_var = param_maybe_default_rule(p)) // param_maybe_default + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (elem = lambda_param_rule(p)) // lambda_param ) { - _res = param_maybe_default_var; + _res = elem; + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + PyMem_Free(_children); + p->level--; + return NULL; + } if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -34001,8 +36633,8 @@ _loop0_163_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_163[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_maybe_default")); + D(fprintf(stderr, "%*c%s _loop0_189[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' lambda_param")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { @@ -34014,18 +36646,57 @@ _loop0_163_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_163_type, _seq); p->level--; return _seq; } -// _tmp_164: slash_no_default | slash_with_default +// _gather_188: lambda_param _loop0_189 +static asdl_seq * +_gather_188_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_seq * _res = NULL; + int _mark = p->mark; + { // lambda_param _loop0_189 + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _gather_188[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param _loop0_189")); + arg_ty elem; + asdl_seq * seq; + if ( + (elem = lambda_param_rule(p)) // lambda_param + && + (seq = _loop0_189_rule(p)) // _loop0_189 + ) + { + D(fprintf(stderr, "%*c+ _gather_188[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param _loop0_189")); + _res = _PyPegen_seq_insert_in_front(p, elem, seq); + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _gather_188[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param _loop0_189")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_190: lambda_slash_no_default | lambda_slash_with_default static void * -_tmp_164_rule(Parser *p) +_tmp_190_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -34033,43 +36704,43 @@ _tmp_164_rule(Parser *p) } void * _res = NULL; int _mark = p->mark; - { // slash_no_default + { // lambda_slash_no_default if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_164[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_no_default")); - asdl_arg_seq* slash_no_default_var; + D(fprintf(stderr, "%*c> _tmp_190[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default")); + asdl_arg_seq* lambda_slash_no_default_var; if ( - (slash_no_default_var = slash_no_default_rule(p)) // slash_no_default + (lambda_slash_no_default_var = lambda_slash_no_default_rule(p)) // lambda_slash_no_default ) { - D(fprintf(stderr, "%*c+ _tmp_164[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_no_default")); - _res = slash_no_default_var; + D(fprintf(stderr, "%*c+ _tmp_190[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default")); + _res = lambda_slash_no_default_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_164[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "slash_no_default")); + D(fprintf(stderr, "%*c%s _tmp_190[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_slash_no_default")); } - { // slash_with_default + { // lambda_slash_with_default if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_164[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_with_default")); - SlashWithDefault* slash_with_default_var; + D(fprintf(stderr, "%*c> _tmp_190[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default")); + SlashWithDefault* lambda_slash_with_default_var; if ( - (slash_with_default_var = slash_with_default_rule(p)) // slash_with_default + (lambda_slash_with_default_var = lambda_slash_with_default_rule(p)) // lambda_slash_with_default ) { - D(fprintf(stderr, "%*c+ _tmp_164[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_with_default")); - _res = slash_with_default_var; + D(fprintf(stderr, "%*c+ _tmp_190[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default")); + _res = lambda_slash_with_default_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_164[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "slash_with_default")); + D(fprintf(stderr, "%*c%s _tmp_190[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_slash_with_default")); } _res = NULL; done: @@ -34077,13 +36748,12 @@ _tmp_164_rule(Parser *p) return _res; } -// _loop0_165: param_maybe_default +// _loop0_191: lambda_param_maybe_default static asdl_seq * -_loop0_165_rule(Parser *p) +_loop0_191_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -34091,7 +36761,6 @@ _loop0_165_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -34101,18 +36770,18 @@ _loop0_165_rule(Parser *p) } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; - { // param_maybe_default + { // lambda_param_maybe_default if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_165[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); - NameDefaultPair* param_maybe_default_var; + D(fprintf(stderr, "%*c> _loop0_191[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); + NameDefaultPair* lambda_param_maybe_default_var; while ( - (param_maybe_default_var = param_maybe_default_rule(p)) // param_maybe_default + (lambda_param_maybe_default_var = lambda_param_maybe_default_rule(p)) // lambda_param_maybe_default ) { - _res = param_maybe_default_var; + _res = lambda_param_maybe_default_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -34129,8 +36798,8 @@ _loop0_165_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_165[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_maybe_default")); + D(fprintf(stderr, "%*c%s _loop0_191[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_maybe_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { @@ -34142,18 +36811,16 @@ _loop0_165_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_165_type, _seq); p->level--; return _seq; } -// _tmp_166: ',' | param_no_default +// _tmp_192: ',' | lambda_param_no_default static void * -_tmp_166_rule(Parser *p) +_tmp_192_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -34166,38 +36833,38 @@ _tmp_166_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_166[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c> _tmp_192[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' ) { - D(fprintf(stderr, "%*c+ _tmp_166[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c+ _tmp_192[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_166[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_192[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); } - { // param_no_default + { // lambda_param_no_default if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_166[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); - arg_ty param_no_default_var; + D(fprintf(stderr, "%*c> _tmp_192[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + arg_ty lambda_param_no_default_var; if ( - (param_no_default_var = param_no_default_rule(p)) // param_no_default + (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default ) { - D(fprintf(stderr, "%*c+ _tmp_166[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_no_default")); - _res = param_no_default_var; + D(fprintf(stderr, "%*c+ _tmp_192[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + _res = lambda_param_no_default_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_166[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); + D(fprintf(stderr, "%*c%s _tmp_192[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); } _res = NULL; done: @@ -34205,13 +36872,12 @@ _tmp_166_rule(Parser *p) return _res; } -// _loop0_167: param_maybe_default +// _loop0_193: lambda_param_maybe_default static asdl_seq * -_loop0_167_rule(Parser *p) +_loop0_193_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -34219,7 +36885,6 @@ _loop0_167_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -34229,18 +36894,18 @@ _loop0_167_rule(Parser *p) } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; - { // param_maybe_default + { // lambda_param_maybe_default if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_167[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); - NameDefaultPair* param_maybe_default_var; + D(fprintf(stderr, "%*c> _loop0_193[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); + NameDefaultPair* lambda_param_maybe_default_var; while ( - (param_maybe_default_var = param_maybe_default_rule(p)) // param_maybe_default + (lambda_param_maybe_default_var = lambda_param_maybe_default_rule(p)) // lambda_param_maybe_default ) { - _res = param_maybe_default_var; + _res = lambda_param_maybe_default_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -34257,8 +36922,8 @@ _loop0_167_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_167[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_maybe_default")); + D(fprintf(stderr, "%*c%s _loop0_193[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_maybe_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { @@ -34270,18 +36935,16 @@ _loop0_167_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_167_type, _seq); p->level--; return _seq; } -// _loop1_168: param_maybe_default +// _loop1_194: lambda_param_maybe_default static asdl_seq * -_loop1_168_rule(Parser *p) +_loop1_194_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -34289,7 +36952,6 @@ _loop1_168_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -34299,18 +36961,18 @@ _loop1_168_rule(Parser *p) } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; - { // param_maybe_default + { // lambda_param_maybe_default if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_168[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); - NameDefaultPair* param_maybe_default_var; + D(fprintf(stderr, "%*c> _loop1_194[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); + NameDefaultPair* lambda_param_maybe_default_var; while ( - (param_maybe_default_var = param_maybe_default_rule(p)) // param_maybe_default + (lambda_param_maybe_default_var = lambda_param_maybe_default_rule(p)) // lambda_param_maybe_default ) { - _res = param_maybe_default_var; + _res = lambda_param_maybe_default_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -34327,8 +36989,8 @@ _loop1_168_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_168[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_maybe_default")); + D(fprintf(stderr, "%*c%s _loop1_194[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_maybe_default")); } if (_n == 0 || p->error_indicator) { PyMem_Free(_children); @@ -34345,76 +37007,88 @@ _loop1_168_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_168_type, _seq); p->level--; return _seq; } -// _tmp_169: ')' | ',' -static void * -_tmp_169_rule(Parser *p) +// _loop1_195: lambda_param_with_default +static asdl_seq * +_loop1_195_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; return NULL; } - void * _res = NULL; + void *_res = NULL; int _mark = p->mark; - { // ')' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_169[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); - Token * _literal; - if ( - (_literal = _PyPegen_expect_token(p, 8)) // token=')' - ) - { - D(fprintf(stderr, "%*c+ _tmp_169[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); - _res = _literal; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_169[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "')'")); + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; } - { // ',' + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // lambda_param_with_default if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_169[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); - Token * _literal; - if ( - (_literal = _PyPegen_expect_token(p, 12)) // token=',' + D(fprintf(stderr, "%*c> _loop1_195[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default")); + NameDefaultPair* lambda_param_with_default_var; + while ( + (lambda_param_with_default_var = lambda_param_with_default_rule(p)) // lambda_param_with_default ) { - D(fprintf(stderr, "%*c+ _tmp_169[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); - _res = _literal; - goto done; + _res = lambda_param_with_default_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + _children = _new_children; + } + _children[_n++] = _res; + _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_169[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); + D(fprintf(stderr, "%*c%s _loop1_195[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_with_default")); } - _res = NULL; - done: + if (_n == 0 || p->error_indicator) { + PyMem_Free(_children); + p->level--; + return NULL; + } + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); + PyMem_Free(_children); p->level--; - return _res; + return _seq; } -// _tmp_170: ')' | ',' (')' | '**') +// _tmp_196: ':' | ',' (':' | '**') static void * -_tmp_170_rule(Parser *p) +_tmp_196_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -34422,46 +37096,46 @@ _tmp_170_rule(Parser *p) } void * _res = NULL; int _mark = p->mark; - { // ')' + { // ':' if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_170[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c> _tmp_196[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); Token * _literal; if ( - (_literal = _PyPegen_expect_token(p, 8)) // token=')' + (_literal = _PyPegen_expect_token(p, 11)) // token=':' ) { - D(fprintf(stderr, "%*c+ _tmp_170[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c+ _tmp_196[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_170[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c%s _tmp_196[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); } - { // ',' (')' | '**') + { // ',' (':' | '**') if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_170[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (')' | '**')")); + D(fprintf(stderr, "%*c> _tmp_196[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (':' | '**')")); Token * _literal; - void *_tmp_238_var; + void *_tmp_265_var; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (_tmp_238_var = _tmp_238_rule(p)) // ')' | '**' + (_tmp_265_var = _tmp_265_rule(p)) // ':' | '**' ) { - D(fprintf(stderr, "%*c+ _tmp_170[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' (')' | '**')")); - _res = _PyPegen_dummy_name(p, _literal, _tmp_238_var); + D(fprintf(stderr, "%*c+ _tmp_196[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' (':' | '**')")); + _res = _PyPegen_dummy_name(p, _literal, _tmp_265_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_170[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (')' | '**')")); + D(fprintf(stderr, "%*c%s _tmp_196[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (':' | '**')")); } _res = NULL; done: @@ -34469,13 +37143,12 @@ _tmp_170_rule(Parser *p) return _res; } -// _tmp_171: param_no_default | ',' +// _tmp_197: lambda_param_no_default | ',' static void * -_tmp_171_rule(Parser *p) +_tmp_197_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -34483,42 +37156,42 @@ _tmp_171_rule(Parser *p) } void * _res = NULL; int _mark = p->mark; - { // param_no_default + { // lambda_param_no_default if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_171[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); - arg_ty param_no_default_var; + D(fprintf(stderr, "%*c> _tmp_197[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + arg_ty lambda_param_no_default_var; if ( - (param_no_default_var = param_no_default_rule(p)) // param_no_default + (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default ) { - D(fprintf(stderr, "%*c+ _tmp_171[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_no_default")); - _res = param_no_default_var; + D(fprintf(stderr, "%*c+ _tmp_197[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + _res = lambda_param_no_default_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_171[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); + D(fprintf(stderr, "%*c%s _tmp_197[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); } { // ',' if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_171[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c> _tmp_197[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' ) { - D(fprintf(stderr, "%*c+ _tmp_171[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c+ _tmp_197[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_171[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_197[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); } _res = NULL; @@ -34527,13 +37200,12 @@ _tmp_171_rule(Parser *p) return _res; } -// _loop0_172: param_maybe_default +// _loop0_198: lambda_param_maybe_default static asdl_seq * -_loop0_172_rule(Parser *p) +_loop0_198_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -34541,7 +37213,6 @@ _loop0_172_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -34551,18 +37222,18 @@ _loop0_172_rule(Parser *p) } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; - { // param_maybe_default + { // lambda_param_maybe_default if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_172[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default")); - NameDefaultPair* param_maybe_default_var; + D(fprintf(stderr, "%*c> _loop0_198[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); + NameDefaultPair* lambda_param_maybe_default_var; while ( - (param_maybe_default_var = param_maybe_default_rule(p)) // param_maybe_default + (lambda_param_maybe_default_var = lambda_param_maybe_default_rule(p)) // lambda_param_maybe_default ) { - _res = param_maybe_default_var; + _res = lambda_param_maybe_default_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -34579,8 +37250,8 @@ _loop0_172_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_172[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_maybe_default")); + D(fprintf(stderr, "%*c%s _loop0_198[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_maybe_default")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { @@ -34592,18 +37263,16 @@ _loop0_172_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_172_type, _seq); p->level--; return _seq; } -// _tmp_173: param_no_default | ',' +// _tmp_199: lambda_param_no_default | ',' static void * -_tmp_173_rule(Parser *p) +_tmp_199_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -34611,42 +37280,42 @@ _tmp_173_rule(Parser *p) } void * _res = NULL; int _mark = p->mark; - { // param_no_default + { // lambda_param_no_default if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_173[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default")); - arg_ty param_no_default_var; + D(fprintf(stderr, "%*c> _tmp_199[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + arg_ty lambda_param_no_default_var; if ( - (param_no_default_var = param_no_default_rule(p)) // param_no_default + (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default ) { - D(fprintf(stderr, "%*c+ _tmp_173[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_no_default")); - _res = param_no_default_var; + D(fprintf(stderr, "%*c+ _tmp_199[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); + _res = lambda_param_no_default_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_173[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default")); + D(fprintf(stderr, "%*c%s _tmp_199[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); } { // ',' if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_173[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c> _tmp_199[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' ) { - D(fprintf(stderr, "%*c+ _tmp_173[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c+ _tmp_199[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_173[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_199[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); } _res = NULL; @@ -34655,13 +37324,12 @@ _tmp_173_rule(Parser *p) return _res; } -// _tmp_174: '*' | '**' | '/' +// _tmp_200: '*' | '**' | '/' static void * -_tmp_174_rule(Parser *p) +_tmp_200_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -34674,18 +37342,18 @@ _tmp_174_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_174[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*'")); + D(fprintf(stderr, "%*c> _tmp_200[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 16)) // token='*' ) { - D(fprintf(stderr, "%*c+ _tmp_174[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*'")); + D(fprintf(stderr, "%*c+ _tmp_200[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_174[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_200[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*'")); } { // '**' @@ -34693,18 +37361,18 @@ _tmp_174_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_174[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); + D(fprintf(stderr, "%*c> _tmp_200[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 35)) // token='**' ) { - D(fprintf(stderr, "%*c+ _tmp_174[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); + D(fprintf(stderr, "%*c+ _tmp_200[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_174[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_200[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**'")); } { // '/' @@ -34712,18 +37380,18 @@ _tmp_174_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_174[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'/'")); + D(fprintf(stderr, "%*c> _tmp_200[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'/'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 17)) // token='/' ) { - D(fprintf(stderr, "%*c+ _tmp_174[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'/'")); + D(fprintf(stderr, "%*c+ _tmp_200[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'/'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_174[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_200[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'/'")); } _res = NULL; @@ -34732,88 +37400,88 @@ _tmp_174_rule(Parser *p) return _res; } -// _loop1_175: param_with_default -static asdl_seq * -_loop1_175_rule(Parser *p) +// _tmp_201: ',' | ')' | ':' +static void * +_tmp_201_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; return NULL; } - void *_res = NULL; + void * _res = NULL; int _mark = p->mark; - int _start_mark = p->mark; - void **_children = PyMem_Malloc(sizeof(void *)); - if (!_children) { - p->error_indicator = 1; - PyErr_NoMemory(); - p->level--; - return NULL; - } - Py_ssize_t _children_capacity = 1; - Py_ssize_t _n = 0; - { // param_with_default + { // ',' if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_175[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default")); - NameDefaultPair* param_with_default_var; - while ( - (param_with_default_var = param_with_default_rule(p)) // param_with_default + D(fprintf(stderr, "%*c> _tmp_201[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' ) { - _res = param_with_default_var; - if (_n == _children_capacity) { - _children_capacity *= 2; - void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); - if (!_new_children) { - PyMem_Free(_children); - p->error_indicator = 1; - PyErr_NoMemory(); - p->level--; - return NULL; - } - _children = _new_children; - } - _children[_n++] = _res; - _mark = p->mark; + D(fprintf(stderr, "%*c+ _tmp_201[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + _res = _literal; + goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_175[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_with_default")); + D(fprintf(stderr, "%*c%s _tmp_201[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); } - if (_n == 0 || p->error_indicator) { - PyMem_Free(_children); - p->level--; - return NULL; + { // ')' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_201[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 8)) // token=')' + ) + { + D(fprintf(stderr, "%*c+ _tmp_201[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_201[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "')'")); } - asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); - if (!_seq) { - PyMem_Free(_children); - p->error_indicator = 1; - PyErr_NoMemory(); - p->level--; - return NULL; + { // ':' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_201[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 11)) // token=':' + ) + { + D(fprintf(stderr, "%*c+ _tmp_201[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_201[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); } - for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_175_type, _seq); + _res = NULL; + done: p->level--; - return _seq; + return _res; } -// _loop0_176: lambda_param_no_default +// _loop0_203: ',' dotted_name static asdl_seq * -_loop0_176_rule(Parser *p) +_loop0_203_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -34821,7 +37489,6 @@ _loop0_176_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -34831,18 +37498,27 @@ _loop0_176_rule(Parser *p) } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; - { // lambda_param_no_default + { // ',' dotted_name if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_176[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); - arg_ty lambda_param_no_default_var; + D(fprintf(stderr, "%*c> _loop0_203[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' dotted_name")); + Token * _literal; + expr_ty elem; while ( - (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (elem = dotted_name_rule(p)) // dotted_name ) { - _res = lambda_param_no_default_var; + _res = elem; + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + PyMem_Free(_children); + p->level--; + return NULL; + } if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -34859,8 +37535,8 @@ _loop0_176_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_176[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); + D(fprintf(stderr, "%*c%s _loop0_203[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' dotted_name")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { @@ -34872,18 +37548,57 @@ _loop0_176_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_176_type, _seq); p->level--; return _seq; } -// _loop0_177: lambda_param_no_default +// _gather_202: dotted_name _loop0_203 static asdl_seq * -_loop0_177_rule(Parser *p) +_gather_202_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_seq * _res = NULL; + int _mark = p->mark; + { // dotted_name _loop0_203 + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _gather_202[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "dotted_name _loop0_203")); + expr_ty elem; + asdl_seq * seq; + if ( + (elem = dotted_name_rule(p)) // dotted_name + && + (seq = _loop0_203_rule(p)) // _loop0_203 + ) + { + D(fprintf(stderr, "%*c+ _gather_202[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "dotted_name _loop0_203")); + _res = _PyPegen_seq_insert_in_front(p, elem, seq); + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _gather_202[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "dotted_name _loop0_203")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop0_205: ',' (expression ['as' star_target]) +static asdl_seq * +_loop0_205_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -34891,7 +37606,6 @@ _loop0_177_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -34901,18 +37615,27 @@ _loop0_177_rule(Parser *p) } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; - { // lambda_param_no_default + { // ',' (expression ['as' star_target]) if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_177[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); - arg_ty lambda_param_no_default_var; + D(fprintf(stderr, "%*c> _loop0_205[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expression ['as' star_target])")); + Token * _literal; + void *elem; while ( - (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (elem = _tmp_266_rule(p)) // expression ['as' star_target] ) { - _res = lambda_param_no_default_var; + _res = elem; + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + PyMem_Free(_children); + p->level--; + return NULL; + } if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -34929,8 +37652,8 @@ _loop0_177_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_177[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); + D(fprintf(stderr, "%*c%s _loop0_205[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (expression ['as' star_target])")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { @@ -34942,18 +37665,57 @@ _loop0_177_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_177_type, _seq); p->level--; return _seq; } -// _loop0_179: ',' lambda_param +// _gather_204: (expression ['as' star_target]) _loop0_205 static asdl_seq * -_loop0_179_rule(Parser *p) +_gather_204_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + asdl_seq * _res = NULL; + int _mark = p->mark; + { // (expression ['as' star_target]) _loop0_205 + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _gather_204[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_205")); + void *elem; + asdl_seq * seq; + if ( + (elem = _tmp_266_rule(p)) // expression ['as' star_target] + && + (seq = _loop0_205_rule(p)) // _loop0_205 + ) + { + D(fprintf(stderr, "%*c+ _gather_204[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_205")); + _res = _PyPegen_seq_insert_in_front(p, elem, seq); + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _gather_204[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expression ['as' star_target]) _loop0_205")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _loop0_207: ',' (expressions ['as' star_target]) +static asdl_seq * +_loop0_207_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -34961,7 +37723,6 @@ _loop0_179_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -34971,18 +37732,18 @@ _loop0_179_rule(Parser *p) } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; - { // ',' lambda_param + { // ',' (expressions ['as' star_target]) if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_179[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' lambda_param")); + D(fprintf(stderr, "%*c> _loop0_207[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expressions ['as' star_target])")); Token * _literal; - arg_ty elem; + void *elem; while ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (elem = lambda_param_rule(p)) // lambda_param + (elem = _tmp_267_rule(p)) // expressions ['as' star_target] ) { _res = elem; @@ -35008,8 +37769,8 @@ _loop0_179_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_179[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' lambda_param")); + D(fprintf(stderr, "%*c%s _loop0_207[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (expressions ['as' star_target])")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { @@ -35021,18 +37782,16 @@ _loop0_179_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_179_type, _seq); p->level--; return _seq; } -// _gather_178: lambda_param _loop0_179 +// _gather_206: (expressions ['as' star_target]) _loop0_207 static asdl_seq * -_gather_178_rule(Parser *p) +_gather_206_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -35040,85 +37799,27 @@ _gather_178_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // lambda_param _loop0_179 + { // (expressions ['as' star_target]) _loop0_207 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_178[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param _loop0_179")); - arg_ty elem; + D(fprintf(stderr, "%*c> _gather_206[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_207")); + void *elem; asdl_seq * seq; if ( - (elem = lambda_param_rule(p)) // lambda_param + (elem = _tmp_267_rule(p)) // expressions ['as' star_target] && - (seq = _loop0_179_rule(p)) // _loop0_179 + (seq = _loop0_207_rule(p)) // _loop0_207 ) { - D(fprintf(stderr, "%*c+ _gather_178[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param _loop0_179")); + D(fprintf(stderr, "%*c+ _gather_206[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_207")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_178[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param _loop0_179")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _tmp_180: lambda_slash_no_default | lambda_slash_with_default -static void * -_tmp_180_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - void * _res = NULL; - int _mark = p->mark; - { // lambda_slash_no_default - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_180[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default")); - asdl_arg_seq* lambda_slash_no_default_var; - if ( - (lambda_slash_no_default_var = lambda_slash_no_default_rule(p)) // lambda_slash_no_default - ) - { - D(fprintf(stderr, "%*c+ _tmp_180[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default")); - _res = lambda_slash_no_default_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_180[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_slash_no_default")); - } - { // lambda_slash_with_default - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_180[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default")); - SlashWithDefault* lambda_slash_with_default_var; - if ( - (lambda_slash_with_default_var = lambda_slash_with_default_rule(p)) // lambda_slash_with_default - ) - { - D(fprintf(stderr, "%*c+ _tmp_180[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default")); - _res = lambda_slash_with_default_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_180[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_slash_with_default")); + D(fprintf(stderr, "%*c%s _gather_206[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expressions ['as' star_target]) _loop0_207")); } _res = NULL; done: @@ -35126,13 +37827,12 @@ _tmp_180_rule(Parser *p) return _res; } -// _loop0_181: lambda_param_maybe_default +// _loop0_209: ',' (expression ['as' star_target]) static asdl_seq * -_loop0_181_rule(Parser *p) +_loop0_209_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -35140,7 +37840,6 @@ _loop0_181_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -35150,18 +37849,27 @@ _loop0_181_rule(Parser *p) } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; - { // lambda_param_maybe_default + { // ',' (expression ['as' star_target]) if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_181[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); - NameDefaultPair* lambda_param_maybe_default_var; + D(fprintf(stderr, "%*c> _loop0_209[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expression ['as' star_target])")); + Token * _literal; + void *elem; while ( - (lambda_param_maybe_default_var = lambda_param_maybe_default_rule(p)) // lambda_param_maybe_default + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (elem = _tmp_268_rule(p)) // expression ['as' star_target] ) { - _res = lambda_param_maybe_default_var; + _res = elem; + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + PyMem_Free(_children); + p->level--; + return NULL; + } if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -35178,8 +37886,8 @@ _loop0_181_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_181[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_maybe_default")); + D(fprintf(stderr, "%*c%s _loop0_209[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (expression ['as' star_target])")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { @@ -35191,62 +37899,44 @@ _loop0_181_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_181_type, _seq); p->level--; return _seq; } -// _tmp_182: lambda_slash_no_default | lambda_slash_with_default -static void * -_tmp_182_rule(Parser *p) +// _gather_208: (expression ['as' star_target]) _loop0_209 +static asdl_seq * +_gather_208_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; return NULL; } - void * _res = NULL; + asdl_seq * _res = NULL; int _mark = p->mark; - { // lambda_slash_no_default + { // (expression ['as' star_target]) _loop0_209 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_182[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default")); - asdl_arg_seq* lambda_slash_no_default_var; - if ( - (lambda_slash_no_default_var = lambda_slash_no_default_rule(p)) // lambda_slash_no_default - ) - { - D(fprintf(stderr, "%*c+ _tmp_182[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default")); - _res = lambda_slash_no_default_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_182[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_slash_no_default")); - } - { // lambda_slash_with_default - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_182[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default")); - SlashWithDefault* lambda_slash_with_default_var; + D(fprintf(stderr, "%*c> _gather_208[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_209")); + void *elem; + asdl_seq * seq; if ( - (lambda_slash_with_default_var = lambda_slash_with_default_rule(p)) // lambda_slash_with_default + (elem = _tmp_268_rule(p)) // expression ['as' star_target] + && + (seq = _loop0_209_rule(p)) // _loop0_209 ) { - D(fprintf(stderr, "%*c+ _tmp_182[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default")); - _res = lambda_slash_with_default_var; + D(fprintf(stderr, "%*c+ _gather_208[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_209")); + _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_182[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_slash_with_default")); + D(fprintf(stderr, "%*c%s _gather_208[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expression ['as' star_target]) _loop0_209")); } _res = NULL; done: @@ -35254,13 +37944,12 @@ _tmp_182_rule(Parser *p) return _res; } -// _loop0_183: lambda_param_maybe_default +// _loop0_211: ',' (expressions ['as' star_target]) static asdl_seq * -_loop0_183_rule(Parser *p) +_loop0_211_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -35268,7 +37957,6 @@ _loop0_183_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -35278,18 +37966,27 @@ _loop0_183_rule(Parser *p) } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; - { // lambda_param_maybe_default + { // ',' (expressions ['as' star_target]) if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_183[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); - NameDefaultPair* lambda_param_maybe_default_var; + D(fprintf(stderr, "%*c> _loop0_211[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expressions ['as' star_target])")); + Token * _literal; + void *elem; while ( - (lambda_param_maybe_default_var = lambda_param_maybe_default_rule(p)) // lambda_param_maybe_default + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + && + (elem = _tmp_269_rule(p)) // expressions ['as' star_target] ) { - _res = lambda_param_maybe_default_var; + _res = elem; + if (_res == NULL && PyErr_Occurred()) { + p->error_indicator = 1; + PyMem_Free(_children); + p->level--; + return NULL; + } if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -35306,8 +38003,8 @@ _loop0_183_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_183[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_maybe_default")); + D(fprintf(stderr, "%*c%s _loop0_211[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (expressions ['as' star_target])")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { @@ -35319,62 +38016,44 @@ _loop0_183_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_183_type, _seq); p->level--; return _seq; } -// _tmp_184: ',' | lambda_param_no_default -static void * -_tmp_184_rule(Parser *p) +// _gather_210: (expressions ['as' star_target]) _loop0_211 +static asdl_seq * +_gather_210_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; return NULL; } - void * _res = NULL; + asdl_seq * _res = NULL; int _mark = p->mark; - { // ',' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_184[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); - Token * _literal; - if ( - (_literal = _PyPegen_expect_token(p, 12)) // token=',' - ) - { - D(fprintf(stderr, "%*c+ _tmp_184[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); - _res = _literal; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_184[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); - } - { // lambda_param_no_default + { // (expressions ['as' star_target]) _loop0_211 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_184[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); - arg_ty lambda_param_no_default_var; + D(fprintf(stderr, "%*c> _gather_210[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_211")); + void *elem; + asdl_seq * seq; if ( - (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default + (elem = _tmp_269_rule(p)) // expressions ['as' star_target] + && + (seq = _loop0_211_rule(p)) // _loop0_211 ) { - D(fprintf(stderr, "%*c+ _tmp_184[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); - _res = lambda_param_no_default_var; + D(fprintf(stderr, "%*c+ _gather_210[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_211")); + _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_184[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); + D(fprintf(stderr, "%*c%s _gather_210[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expressions ['as' star_target]) _loop0_211")); } _res = NULL; done: @@ -35382,83 +38061,69 @@ _tmp_184_rule(Parser *p) return _res; } -// _loop0_185: lambda_param_maybe_default -static asdl_seq * -_loop0_185_rule(Parser *p) +// _tmp_212: 'except' | 'finally' +static void * +_tmp_212_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; return NULL; } - void *_res = NULL; + void * _res = NULL; int _mark = p->mark; - int _start_mark = p->mark; - void **_children = PyMem_Malloc(sizeof(void *)); - if (!_children) { - p->error_indicator = 1; - PyErr_NoMemory(); - p->level--; - return NULL; - } - Py_ssize_t _children_capacity = 1; - Py_ssize_t _n = 0; - { // lambda_param_maybe_default + { // 'except' if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_185[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); - NameDefaultPair* lambda_param_maybe_default_var; - while ( - (lambda_param_maybe_default_var = lambda_param_maybe_default_rule(p)) // lambda_param_maybe_default + D(fprintf(stderr, "%*c> _tmp_212[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'except'")); + Token * _keyword; + if ( + (_keyword = _PyPegen_expect_token(p, 637)) // token='except' ) { - _res = lambda_param_maybe_default_var; - if (_n == _children_capacity) { - _children_capacity *= 2; - void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); - if (!_new_children) { - PyMem_Free(_children); - p->error_indicator = 1; - PyErr_NoMemory(); - p->level--; - return NULL; - } - _children = _new_children; - } - _children[_n++] = _res; - _mark = p->mark; + D(fprintf(stderr, "%*c+ _tmp_212[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'except'")); + _res = _keyword; + goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_185[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_maybe_default")); + D(fprintf(stderr, "%*c%s _tmp_212[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'except'")); } - asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); - if (!_seq) { - PyMem_Free(_children); - p->error_indicator = 1; - PyErr_NoMemory(); - p->level--; - return NULL; + { // 'finally' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_212[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'finally'")); + Token * _keyword; + if ( + (_keyword = _PyPegen_expect_token(p, 633)) // token='finally' + ) + { + D(fprintf(stderr, "%*c+ _tmp_212[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'finally'")); + _res = _keyword; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_212[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'finally'")); } - for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_185_type, _seq); + _res = NULL; + done: p->level--; - return _seq; + return _res; } -// _loop1_186: lambda_param_maybe_default +// _loop0_213: block static asdl_seq * -_loop1_186_rule(Parser *p) +_loop0_213_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -35466,7 +38131,6 @@ _loop1_186_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -35476,18 +38140,18 @@ _loop1_186_rule(Parser *p) } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; - { // lambda_param_maybe_default + { // block if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_186[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); - NameDefaultPair* lambda_param_maybe_default_var; + D(fprintf(stderr, "%*c> _loop0_213[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "block")); + asdl_stmt_seq* block_var; while ( - (lambda_param_maybe_default_var = lambda_param_maybe_default_rule(p)) // lambda_param_maybe_default + (block_var = block_rule(p)) // block ) { - _res = lambda_param_maybe_default_var; + _res = block_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -35504,13 +38168,8 @@ _loop1_186_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_186[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_maybe_default")); - } - if (_n == 0 || p->error_indicator) { - PyMem_Free(_children); - p->level--; - return NULL; + D(fprintf(stderr, "%*c%s _loop0_213[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "block")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { @@ -35522,18 +38181,16 @@ _loop1_186_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_186_type, _seq); p->level--; return _seq; } -// _loop1_187: lambda_param_with_default +// _loop1_214: except_block static asdl_seq * -_loop1_187_rule(Parser *p) +_loop1_214_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -35541,7 +38198,6 @@ _loop1_187_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -35551,18 +38207,18 @@ _loop1_187_rule(Parser *p) } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; - { // lambda_param_with_default + { // except_block if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_187[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default")); - NameDefaultPair* lambda_param_with_default_var; + D(fprintf(stderr, "%*c> _loop1_214[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "except_block")); + excepthandler_ty except_block_var; while ( - (lambda_param_with_default_var = lambda_param_with_default_rule(p)) // lambda_param_with_default + (except_block_var = except_block_rule(p)) // except_block ) { - _res = lambda_param_with_default_var; + _res = except_block_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -35579,8 +38235,8 @@ _loop1_187_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_187[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_with_default")); + D(fprintf(stderr, "%*c%s _loop1_214[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "except_block")); } if (_n == 0 || p->error_indicator) { PyMem_Free(_children); @@ -35597,18 +38253,16 @@ _loop1_187_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_187_type, _seq); p->level--; return _seq; } -// _tmp_188: ':' | ',' (':' | '**') +// _tmp_215: 'as' NAME static void * -_tmp_188_rule(Parser *p) +_tmp_215_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -35616,46 +38270,27 @@ _tmp_188_rule(Parser *p) } void * _res = NULL; int _mark = p->mark; - { // ':' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_188[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); - Token * _literal; - if ( - (_literal = _PyPegen_expect_token(p, 11)) // token=':' - ) - { - D(fprintf(stderr, "%*c+ _tmp_188[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); - _res = _literal; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_188[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); - } - { // ',' (':' | '**') + { // 'as' NAME if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_188[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (':' | '**')")); - Token * _literal; - void *_tmp_239_var; + D(fprintf(stderr, "%*c> _tmp_215[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + Token * _keyword; + expr_ty name_var; if ( - (_literal = _PyPegen_expect_token(p, 12)) // token=',' + (_keyword = _PyPegen_expect_token(p, 640)) // token='as' && - (_tmp_239_var = _tmp_239_rule(p)) // ':' | '**' + (name_var = _PyPegen_name_token(p)) // NAME ) { - D(fprintf(stderr, "%*c+ _tmp_188[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' (':' | '**')")); - _res = _PyPegen_dummy_name(p, _literal, _tmp_239_var); + D(fprintf(stderr, "%*c+ _tmp_215[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + _res = _PyPegen_dummy_name(p, _keyword, name_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_188[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (':' | '**')")); + D(fprintf(stderr, "%*c%s _tmp_215[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); } _res = NULL; done: @@ -35663,71 +38298,79 @@ _tmp_188_rule(Parser *p) return _res; } -// _tmp_189: lambda_param_no_default | ',' -static void * -_tmp_189_rule(Parser *p) +// _loop0_216: block +static asdl_seq * +_loop0_216_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; return NULL; } - void * _res = NULL; + void *_res = NULL; int _mark = p->mark; - { // lambda_param_no_default - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_189[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); - arg_ty lambda_param_no_default_var; - if ( - (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default - ) - { - D(fprintf(stderr, "%*c+ _tmp_189[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); - _res = lambda_param_no_default_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_189[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); + void **_children = PyMem_Malloc(sizeof(void *)); + if (!_children) { + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; } - { // ',' + Py_ssize_t _children_capacity = 1; + Py_ssize_t _n = 0; + { // block if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_189[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); - Token * _literal; - if ( - (_literal = _PyPegen_expect_token(p, 12)) // token=',' + D(fprintf(stderr, "%*c> _loop0_216[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "block")); + asdl_stmt_seq* block_var; + while ( + (block_var = block_rule(p)) // block ) { - D(fprintf(stderr, "%*c+ _tmp_189[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); - _res = _literal; - goto done; + _res = block_var; + if (_n == _children_capacity) { + _children_capacity *= 2; + void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); + if (!_new_children) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + _children = _new_children; + } + _children[_n++] = _res; + _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_189[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); + D(fprintf(stderr, "%*c%s _loop0_216[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "block")); } - _res = NULL; - done: + asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); + if (!_seq) { + PyMem_Free(_children); + p->error_indicator = 1; + PyErr_NoMemory(); + p->level--; + return NULL; + } + for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); + PyMem_Free(_children); p->level--; - return _res; + return _seq; } -// _loop0_190: lambda_param_maybe_default +// _loop1_217: except_star_block static asdl_seq * -_loop0_190_rule(Parser *p) +_loop1_217_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -35735,7 +38378,6 @@ _loop0_190_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -35745,18 +38387,18 @@ _loop0_190_rule(Parser *p) } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; - { // lambda_param_maybe_default + { // except_star_block if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_190[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default")); - NameDefaultPair* lambda_param_maybe_default_var; + D(fprintf(stderr, "%*c> _loop1_217[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "except_star_block")); + excepthandler_ty except_star_block_var; while ( - (lambda_param_maybe_default_var = lambda_param_maybe_default_rule(p)) // lambda_param_maybe_default + (except_star_block_var = except_star_block_rule(p)) // except_star_block ) { - _res = lambda_param_maybe_default_var; + _res = except_star_block_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -35773,8 +38415,13 @@ _loop0_190_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_190[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_maybe_default")); + D(fprintf(stderr, "%*c%s _loop1_217[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "except_star_block")); + } + if (_n == 0 || p->error_indicator) { + PyMem_Free(_children); + p->level--; + return NULL; } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { @@ -35786,18 +38433,16 @@ _loop0_190_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_190_type, _seq); p->level--; return _seq; } -// _tmp_191: lambda_param_no_default | ',' +// _tmp_218: expression ['as' NAME] static void * -_tmp_191_rule(Parser *p) +_tmp_218_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -35805,43 +38450,28 @@ _tmp_191_rule(Parser *p) } void * _res = NULL; int _mark = p->mark; - { // lambda_param_no_default - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_191[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); - arg_ty lambda_param_no_default_var; - if ( - (lambda_param_no_default_var = lambda_param_no_default_rule(p)) // lambda_param_no_default - ) - { - D(fprintf(stderr, "%*c+ _tmp_191[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default")); - _res = lambda_param_no_default_var; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_191[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default")); - } - { // ',' + { // expression ['as' NAME] if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_191[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); - Token * _literal; + D(fprintf(stderr, "%*c> _tmp_218[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ['as' NAME]")); + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + expr_ty expression_var; if ( - (_literal = _PyPegen_expect_token(p, 12)) // token=',' + (expression_var = expression_rule(p)) // expression + && + (_opt_var = _tmp_270_rule(p), !p->error_indicator) // ['as' NAME] ) { - D(fprintf(stderr, "%*c+ _tmp_191[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); - _res = _literal; + D(fprintf(stderr, "%*c+ _tmp_218[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ['as' NAME]")); + _res = _PyPegen_dummy_name(p, expression_var, _opt_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_191[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); + D(fprintf(stderr, "%*c%s _tmp_218[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression ['as' NAME]")); } _res = NULL; done: @@ -35849,13 +38479,12 @@ _tmp_191_rule(Parser *p) return _res; } -// _tmp_192: '*' | '**' | '/' +// _tmp_219: 'as' NAME static void * -_tmp_192_rule(Parser *p) +_tmp_219_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -35863,62 +38492,68 @@ _tmp_192_rule(Parser *p) } void * _res = NULL; int _mark = p->mark; - { // '*' + { // 'as' NAME if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_192[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*'")); - Token * _literal; + D(fprintf(stderr, "%*c> _tmp_219[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + Token * _keyword; + expr_ty name_var; if ( - (_literal = _PyPegen_expect_token(p, 16)) // token='*' + (_keyword = _PyPegen_expect_token(p, 640)) // token='as' + && + (name_var = _PyPegen_name_token(p)) // NAME ) { - D(fprintf(stderr, "%*c+ _tmp_192[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*'")); - _res = _literal; + D(fprintf(stderr, "%*c+ _tmp_219[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + _res = _PyPegen_dummy_name(p, _keyword, name_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_192[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*'")); + D(fprintf(stderr, "%*c%s _tmp_219[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); } - { // '**' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_192[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); - Token * _literal; - if ( - (_literal = _PyPegen_expect_token(p, 35)) // token='**' - ) - { - D(fprintf(stderr, "%*c+ _tmp_192[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); - _res = _literal; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_192[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**'")); + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_220: 'as' NAME +static void * +_tmp_220_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); } - { // '/' + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // 'as' NAME if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_192[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'/'")); - Token * _literal; + D(fprintf(stderr, "%*c> _tmp_220[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + Token * _keyword; + expr_ty name_var; if ( - (_literal = _PyPegen_expect_token(p, 17)) // token='/' + (_keyword = _PyPegen_expect_token(p, 640)) // token='as' + && + (name_var = _PyPegen_name_token(p)) // NAME ) { - D(fprintf(stderr, "%*c+ _tmp_192[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'/'")); - _res = _literal; + D(fprintf(stderr, "%*c+ _tmp_220[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + _res = _PyPegen_dummy_name(p, _keyword, name_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_192[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'/'")); + D(fprintf(stderr, "%*c%s _tmp_220[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); } _res = NULL; done: @@ -35926,13 +38561,12 @@ _tmp_192_rule(Parser *p) return _res; } -// _tmp_193: ',' | ')' | ':' +// _tmp_221: NEWLINE | ':' static void * -_tmp_193_rule(Parser *p) +_tmp_221_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -35940,61 +38574,42 @@ _tmp_193_rule(Parser *p) } void * _res = NULL; int _mark = p->mark; - { // ',' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_193[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); - Token * _literal; - if ( - (_literal = _PyPegen_expect_token(p, 12)) // token=',' - ) - { - D(fprintf(stderr, "%*c+ _tmp_193[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); - _res = _literal; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_193[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); - } - { // ')' + { // NEWLINE if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_193[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); - Token * _literal; + D(fprintf(stderr, "%*c> _tmp_221[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NEWLINE")); + Token * newline_var; if ( - (_literal = _PyPegen_expect_token(p, 8)) // token=')' + (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' ) { - D(fprintf(stderr, "%*c+ _tmp_193[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); - _res = _literal; + D(fprintf(stderr, "%*c+ _tmp_221[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NEWLINE")); + _res = newline_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_193[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c%s _tmp_221[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NEWLINE")); } { // ':' if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_193[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c> _tmp_221[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 11)) // token=':' ) { - D(fprintf(stderr, "%*c+ _tmp_193[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c+ _tmp_221[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_193[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_221[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); } _res = NULL; @@ -36003,120 +38618,81 @@ _tmp_193_rule(Parser *p) return _res; } -// _loop0_195: ',' (expression ['as' star_target]) -static asdl_seq * -_loop0_195_rule(Parser *p) +// _tmp_222: 'as' NAME +static void * +_tmp_222_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; return NULL; } - void *_res = NULL; + void * _res = NULL; int _mark = p->mark; - int _start_mark = p->mark; - void **_children = PyMem_Malloc(sizeof(void *)); - if (!_children) { - p->error_indicator = 1; - PyErr_NoMemory(); - p->level--; - return NULL; - } - Py_ssize_t _children_capacity = 1; - Py_ssize_t _n = 0; - { // ',' (expression ['as' star_target]) + { // 'as' NAME if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_195[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expression ['as' star_target])")); - Token * _literal; - void *elem; - while ( - (_literal = _PyPegen_expect_token(p, 12)) // token=',' + D(fprintf(stderr, "%*c> _tmp_222[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + Token * _keyword; + expr_ty name_var; + if ( + (_keyword = _PyPegen_expect_token(p, 640)) // token='as' && - (elem = _tmp_240_rule(p)) // expression ['as' star_target] + (name_var = _PyPegen_name_token(p)) // NAME ) { - _res = elem; - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - PyMem_Free(_children); - p->level--; - return NULL; - } - if (_n == _children_capacity) { - _children_capacity *= 2; - void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); - if (!_new_children) { - PyMem_Free(_children); - p->error_indicator = 1; - PyErr_NoMemory(); - p->level--; - return NULL; - } - _children = _new_children; - } - _children[_n++] = _res; - _mark = p->mark; + D(fprintf(stderr, "%*c+ _tmp_222[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + _res = _PyPegen_dummy_name(p, _keyword, name_var); + goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_195[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (expression ['as' star_target])")); - } - asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); - if (!_seq) { - PyMem_Free(_children); - p->error_indicator = 1; - PyErr_NoMemory(); - p->level--; - return NULL; + D(fprintf(stderr, "%*c%s _tmp_222[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); } - for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_195_type, _seq); + _res = NULL; + done: p->level--; - return _seq; + return _res; } -// _gather_194: (expression ['as' star_target]) _loop0_195 -static asdl_seq * -_gather_194_rule(Parser *p) +// _tmp_223: 'as' NAME +static void * +_tmp_223_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; return NULL; } - asdl_seq * _res = NULL; + void * _res = NULL; int _mark = p->mark; - { // (expression ['as' star_target]) _loop0_195 + { // 'as' NAME if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_194[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_195")); - void *elem; - asdl_seq * seq; + D(fprintf(stderr, "%*c> _tmp_223[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + Token * _keyword; + expr_ty name_var; if ( - (elem = _tmp_240_rule(p)) // expression ['as' star_target] + (_keyword = _PyPegen_expect_token(p, 640)) // token='as' && - (seq = _loop0_195_rule(p)) // _loop0_195 + (name_var = _PyPegen_name_token(p)) // NAME ) { - D(fprintf(stderr, "%*c+ _gather_194[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_195")); - _res = _PyPegen_seq_insert_in_front(p, elem, seq); + D(fprintf(stderr, "%*c+ _tmp_223[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + _res = _PyPegen_dummy_name(p, _keyword, name_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_194[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expression ['as' star_target]) _loop0_195")); + D(fprintf(stderr, "%*c%s _tmp_223[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); } _res = NULL; done: @@ -36124,120 +38700,81 @@ _gather_194_rule(Parser *p) return _res; } -// _loop0_197: ',' (expressions ['as' star_target]) -static asdl_seq * -_loop0_197_rule(Parser *p) +// _tmp_224: positional_patterns ',' +static void * +_tmp_224_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; return NULL; } - void *_res = NULL; + void * _res = NULL; int _mark = p->mark; - int _start_mark = p->mark; - void **_children = PyMem_Malloc(sizeof(void *)); - if (!_children) { - p->error_indicator = 1; - PyErr_NoMemory(); - p->level--; - return NULL; - } - Py_ssize_t _children_capacity = 1; - Py_ssize_t _n = 0; - { // ',' (expressions ['as' star_target]) + { // positional_patterns ',' if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_197[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expressions ['as' star_target])")); + D(fprintf(stderr, "%*c> _tmp_224[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "positional_patterns ','")); Token * _literal; - void *elem; - while ( - (_literal = _PyPegen_expect_token(p, 12)) // token=',' + asdl_pattern_seq* positional_patterns_var; + if ( + (positional_patterns_var = positional_patterns_rule(p)) // positional_patterns && - (elem = _tmp_241_rule(p)) // expressions ['as' star_target] - ) - { - _res = elem; - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - PyMem_Free(_children); - p->level--; - return NULL; - } - if (_n == _children_capacity) { - _children_capacity *= 2; - void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); - if (!_new_children) { - PyMem_Free(_children); - p->error_indicator = 1; - PyErr_NoMemory(); - p->level--; - return NULL; - } - _children = _new_children; - } - _children[_n++] = _res; - _mark = p->mark; + (_literal = _PyPegen_expect_token(p, 12)) // token=',' + ) + { + D(fprintf(stderr, "%*c+ _tmp_224[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "positional_patterns ','")); + _res = _PyPegen_dummy_name(p, positional_patterns_var, _literal); + goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_197[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (expressions ['as' star_target])")); - } - asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); - if (!_seq) { - PyMem_Free(_children); - p->error_indicator = 1; - PyErr_NoMemory(); - p->level--; - return NULL; + D(fprintf(stderr, "%*c%s _tmp_224[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "positional_patterns ','")); } - for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_197_type, _seq); + _res = NULL; + done: p->level--; - return _seq; + return _res; } -// _gather_196: (expressions ['as' star_target]) _loop0_197 -static asdl_seq * -_gather_196_rule(Parser *p) +// _tmp_225: '->' expression +static void * +_tmp_225_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; return NULL; } - asdl_seq * _res = NULL; + void * _res = NULL; int _mark = p->mark; - { // (expressions ['as' star_target]) _loop0_197 + { // '->' expression if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_196[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_197")); - void *elem; - asdl_seq * seq; + D(fprintf(stderr, "%*c> _tmp_225[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'->' expression")); + Token * _literal; + expr_ty expression_var; if ( - (elem = _tmp_241_rule(p)) // expressions ['as' star_target] + (_literal = _PyPegen_expect_token(p, 51)) // token='->' && - (seq = _loop0_197_rule(p)) // _loop0_197 + (expression_var = expression_rule(p)) // expression ) { - D(fprintf(stderr, "%*c+ _gather_196[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_197")); - _res = _PyPegen_seq_insert_in_front(p, elem, seq); + D(fprintf(stderr, "%*c+ _tmp_225[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'->' expression")); + _res = _PyPegen_dummy_name(p, _literal, expression_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_196[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expressions ['as' star_target]) _loop0_197")); + D(fprintf(stderr, "%*c%s _tmp_225[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'->' expression")); } _res = NULL; done: @@ -36245,120 +38782,89 @@ _gather_196_rule(Parser *p) return _res; } -// _loop0_199: ',' (expression ['as' star_target]) -static asdl_seq * -_loop0_199_rule(Parser *p) +// _tmp_226: '(' arguments? ')' +static void * +_tmp_226_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; return NULL; } - void *_res = NULL; + void * _res = NULL; int _mark = p->mark; - int _start_mark = p->mark; - void **_children = PyMem_Malloc(sizeof(void *)); - if (!_children) { - p->error_indicator = 1; - PyErr_NoMemory(); - p->level--; - return NULL; - } - Py_ssize_t _children_capacity = 1; - Py_ssize_t _n = 0; - { // ',' (expression ['as' star_target]) + { // '(' arguments? ')' if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_199[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expression ['as' star_target])")); + D(fprintf(stderr, "%*c> _tmp_226[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'")); Token * _literal; - void *elem; - while ( - (_literal = _PyPegen_expect_token(p, 12)) // token=',' + Token * _literal_1; + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings + if ( + (_literal = _PyPegen_expect_token(p, 7)) // token='(' + && + (_opt_var = arguments_rule(p), !p->error_indicator) // arguments? && - (elem = _tmp_242_rule(p)) // expression ['as' star_target] + (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' ) { - _res = elem; - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - PyMem_Free(_children); - p->level--; - return NULL; - } - if (_n == _children_capacity) { - _children_capacity *= 2; - void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); - if (!_new_children) { - PyMem_Free(_children); - p->error_indicator = 1; - PyErr_NoMemory(); - p->level--; - return NULL; - } - _children = _new_children; - } - _children[_n++] = _res; - _mark = p->mark; + D(fprintf(stderr, "%*c+ _tmp_226[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'")); + _res = _PyPegen_dummy_name(p, _literal, _opt_var, _literal_1); + goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_199[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (expression ['as' star_target])")); - } - asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); - if (!_seq) { - PyMem_Free(_children); - p->error_indicator = 1; - PyErr_NoMemory(); - p->level--; - return NULL; + D(fprintf(stderr, "%*c%s _tmp_226[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'(' arguments? ')'")); } - for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_199_type, _seq); + _res = NULL; + done: p->level--; - return _seq; + return _res; } -// _gather_198: (expression ['as' star_target]) _loop0_199 -static asdl_seq * -_gather_198_rule(Parser *p) +// _tmp_227: '(' arguments? ')' +static void * +_tmp_227_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; return NULL; } - asdl_seq * _res = NULL; + void * _res = NULL; int _mark = p->mark; - { // (expression ['as' star_target]) _loop0_199 + { // '(' arguments? ')' if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_198[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_199")); - void *elem; - asdl_seq * seq; + D(fprintf(stderr, "%*c> _tmp_227[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'")); + Token * _literal; + Token * _literal_1; + void *_opt_var; + UNUSED(_opt_var); // Silence compiler warnings if ( - (elem = _tmp_242_rule(p)) // expression ['as' star_target] + (_literal = _PyPegen_expect_token(p, 7)) // token='(' && - (seq = _loop0_199_rule(p)) // _loop0_199 + (_opt_var = arguments_rule(p), !p->error_indicator) // arguments? + && + (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' ) { - D(fprintf(stderr, "%*c+ _gather_198[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_199")); - _res = _PyPegen_seq_insert_in_front(p, elem, seq); + D(fprintf(stderr, "%*c+ _tmp_227[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'")); + _res = _PyPegen_dummy_name(p, _literal, _opt_var, _literal_1); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_198[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expression ['as' star_target]) _loop0_199")); + D(fprintf(stderr, "%*c%s _tmp_227[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'(' arguments? ')'")); } _res = NULL; done: @@ -36366,13 +38872,12 @@ _gather_198_rule(Parser *p) return _res; } -// _loop0_201: ',' (expressions ['as' star_target]) +// _loop0_229: ',' double_starred_kvpair static asdl_seq * -_loop0_201_rule(Parser *p) +_loop0_229_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -36380,7 +38885,6 @@ _loop0_201_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -36390,18 +38894,18 @@ _loop0_201_rule(Parser *p) } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; - { // ',' (expressions ['as' star_target]) + { // ',' double_starred_kvpair if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_201[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expressions ['as' star_target])")); + D(fprintf(stderr, "%*c> _loop0_229[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' double_starred_kvpair")); Token * _literal; - void *elem; + KeyValuePair* elem; while ( (_literal = _PyPegen_expect_token(p, 12)) // token=',' && - (elem = _tmp_243_rule(p)) // expressions ['as' star_target] + (elem = double_starred_kvpair_rule(p)) // double_starred_kvpair ) { _res = elem; @@ -36427,8 +38931,8 @@ _loop0_201_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_201[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (expressions ['as' star_target])")); + D(fprintf(stderr, "%*c%s _loop0_229[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' double_starred_kvpair")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { @@ -36440,18 +38944,16 @@ _loop0_201_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_201_type, _seq); p->level--; return _seq; } -// _gather_200: (expressions ['as' star_target]) _loop0_201 +// _gather_228: double_starred_kvpair _loop0_229 static asdl_seq * -_gather_200_rule(Parser *p) +_gather_228_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -36459,27 +38961,27 @@ _gather_200_rule(Parser *p) } asdl_seq * _res = NULL; int _mark = p->mark; - { // (expressions ['as' star_target]) _loop0_201 + { // double_starred_kvpair _loop0_229 if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_200[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_201")); - void *elem; + D(fprintf(stderr, "%*c> _gather_228[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "double_starred_kvpair _loop0_229")); + KeyValuePair* elem; asdl_seq * seq; if ( - (elem = _tmp_243_rule(p)) // expressions ['as' star_target] + (elem = double_starred_kvpair_rule(p)) // double_starred_kvpair && - (seq = _loop0_201_rule(p)) // _loop0_201 + (seq = _loop0_229_rule(p)) // _loop0_229 ) { - D(fprintf(stderr, "%*c+ _gather_200[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_201")); + D(fprintf(stderr, "%*c+ _gather_228[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "double_starred_kvpair _loop0_229")); _res = _PyPegen_seq_insert_in_front(p, elem, seq); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_200[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expressions ['as' star_target]) _loop0_201")); + D(fprintf(stderr, "%*c%s _gather_228[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "double_starred_kvpair _loop0_229")); } _res = NULL; done: @@ -36487,13 +38989,12 @@ _gather_200_rule(Parser *p) return _res; } -// _tmp_202: 'except' | 'finally' +// _tmp_230: '}' | ',' static void * -_tmp_202_rule(Parser *p) +_tmp_230_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -36501,43 +39002,43 @@ _tmp_202_rule(Parser *p) } void * _res = NULL; int _mark = p->mark; - { // 'except' + { // '}' if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_202[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'except'")); - Token * _keyword; + D(fprintf(stderr, "%*c> _tmp_230[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'}'")); + Token * _literal; if ( - (_keyword = _PyPegen_expect_token(p, 634)) // token='except' + (_literal = _PyPegen_expect_token(p, 26)) // token='}' ) { - D(fprintf(stderr, "%*c+ _tmp_202[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'except'")); - _res = _keyword; + D(fprintf(stderr, "%*c+ _tmp_230[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'}'")); + _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_202[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'except'")); + D(fprintf(stderr, "%*c%s _tmp_230[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'}'")); } - { // 'finally' + { // ',' if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_202[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'finally'")); - Token * _keyword; + D(fprintf(stderr, "%*c> _tmp_230[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + Token * _literal; if ( - (_keyword = _PyPegen_expect_token(p, 630)) // token='finally' + (_literal = _PyPegen_expect_token(p, 12)) // token=',' ) { - D(fprintf(stderr, "%*c+ _tmp_202[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'finally'")); - _res = _keyword; + D(fprintf(stderr, "%*c+ _tmp_230[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_202[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'finally'")); + D(fprintf(stderr, "%*c%s _tmp_230[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); } _res = NULL; done: @@ -36545,158 +39046,69 @@ _tmp_202_rule(Parser *p) return _res; } -// _loop0_203: block -static asdl_seq * -_loop0_203_rule(Parser *p) +// _tmp_231: '}' | ',' +static void * +_tmp_231_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; return NULL; } - void *_res = NULL; + void * _res = NULL; int _mark = p->mark; - int _start_mark = p->mark; - void **_children = PyMem_Malloc(sizeof(void *)); - if (!_children) { - p->error_indicator = 1; - PyErr_NoMemory(); - p->level--; - return NULL; - } - Py_ssize_t _children_capacity = 1; - Py_ssize_t _n = 0; - { // block + { // '}' if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_203[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "block")); - asdl_stmt_seq* block_var; - while ( - (block_var = block_rule(p)) // block + D(fprintf(stderr, "%*c> _tmp_231[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'}'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 26)) // token='}' ) { - _res = block_var; - if (_n == _children_capacity) { - _children_capacity *= 2; - void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); - if (!_new_children) { - PyMem_Free(_children); - p->error_indicator = 1; - PyErr_NoMemory(); - p->level--; - return NULL; - } - _children = _new_children; - } - _children[_n++] = _res; - _mark = p->mark; + D(fprintf(stderr, "%*c+ _tmp_231[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'}'")); + _res = _literal; + goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_203[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "block")); - } - asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); - if (!_seq) { - PyMem_Free(_children); - p->error_indicator = 1; - PyErr_NoMemory(); - p->level--; - return NULL; - } - for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_203_type, _seq); - p->level--; - return _seq; -} - -// _loop1_204: except_block -static asdl_seq * -_loop1_204_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; - } - void *_res = NULL; - int _mark = p->mark; - int _start_mark = p->mark; - void **_children = PyMem_Malloc(sizeof(void *)); - if (!_children) { - p->error_indicator = 1; - PyErr_NoMemory(); - p->level--; - return NULL; + D(fprintf(stderr, "%*c%s _tmp_231[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'}'")); } - Py_ssize_t _children_capacity = 1; - Py_ssize_t _n = 0; - { // except_block + { // ',' if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_204[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "except_block")); - excepthandler_ty except_block_var; - while ( - (except_block_var = except_block_rule(p)) // except_block + D(fprintf(stderr, "%*c> _tmp_231[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 12)) // token=',' ) { - _res = except_block_var; - if (_n == _children_capacity) { - _children_capacity *= 2; - void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); - if (!_new_children) { - PyMem_Free(_children); - p->error_indicator = 1; - PyErr_NoMemory(); - p->level--; - return NULL; - } - _children = _new_children; - } - _children[_n++] = _res; - _mark = p->mark; + D(fprintf(stderr, "%*c+ _tmp_231[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + _res = _literal; + goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_204[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "except_block")); - } - if (_n == 0 || p->error_indicator) { - PyMem_Free(_children); - p->level--; - return NULL; - } - asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); - if (!_seq) { - PyMem_Free(_children); - p->error_indicator = 1; - PyErr_NoMemory(); - p->level--; - return NULL; + D(fprintf(stderr, "%*c%s _tmp_231[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); } - for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_204_type, _seq); + _res = NULL; + done: p->level--; - return _seq; + return _res; } -// _tmp_205: 'as' NAME +// _tmp_232: yield_expr | star_expressions static void * -_tmp_205_rule(Parser *p) +_tmp_232_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -36704,27 +39116,43 @@ _tmp_205_rule(Parser *p) } void * _res = NULL; int _mark = p->mark; - { // 'as' NAME + { // yield_expr if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_205[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); - Token * _keyword; - expr_ty name_var; + D(fprintf(stderr, "%*c> _tmp_232[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); + expr_ty yield_expr_var; if ( - (_keyword = _PyPegen_expect_token(p, 637)) // token='as' - && - (name_var = _PyPegen_name_token(p)) // NAME + (yield_expr_var = yield_expr_rule(p)) // yield_expr ) { - D(fprintf(stderr, "%*c+ _tmp_205[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); - _res = _PyPegen_dummy_name(p, _keyword, name_var); + D(fprintf(stderr, "%*c+ _tmp_232[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); + _res = yield_expr_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_205[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c%s _tmp_232[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "yield_expr")); + } + { // star_expressions + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_232[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); + expr_ty star_expressions_var; + if ( + (star_expressions_var = star_expressions_rule(p)) // star_expressions + ) + { + D(fprintf(stderr, "%*c+ _tmp_232[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); + _res = star_expressions_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_232[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions")); } _res = NULL; done: @@ -36732,187 +39160,151 @@ _tmp_205_rule(Parser *p) return _res; } -// _loop0_206: block -static asdl_seq * -_loop0_206_rule(Parser *p) +// _tmp_233: yield_expr | star_expressions +static void * +_tmp_233_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; return NULL; } - void *_res = NULL; + void * _res = NULL; int _mark = p->mark; - int _start_mark = p->mark; - void **_children = PyMem_Malloc(sizeof(void *)); - if (!_children) { - p->error_indicator = 1; - PyErr_NoMemory(); - p->level--; - return NULL; - } - Py_ssize_t _children_capacity = 1; - Py_ssize_t _n = 0; - { // block + { // yield_expr if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_206[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "block")); - asdl_stmt_seq* block_var; - while ( - (block_var = block_rule(p)) // block + D(fprintf(stderr, "%*c> _tmp_233[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); + expr_ty yield_expr_var; + if ( + (yield_expr_var = yield_expr_rule(p)) // yield_expr ) { - _res = block_var; - if (_n == _children_capacity) { - _children_capacity *= 2; - void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); - if (!_new_children) { - PyMem_Free(_children); - p->error_indicator = 1; - PyErr_NoMemory(); - p->level--; - return NULL; - } - _children = _new_children; - } - _children[_n++] = _res; - _mark = p->mark; + D(fprintf(stderr, "%*c+ _tmp_233[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); + _res = yield_expr_var; + goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_206[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "block")); + D(fprintf(stderr, "%*c%s _tmp_233[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "yield_expr")); } - asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); - if (!_seq) { - PyMem_Free(_children); - p->error_indicator = 1; - PyErr_NoMemory(); - p->level--; - return NULL; + { // star_expressions + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_233[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); + expr_ty star_expressions_var; + if ( + (star_expressions_var = star_expressions_rule(p)) // star_expressions + ) + { + D(fprintf(stderr, "%*c+ _tmp_233[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); + _res = star_expressions_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_233[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions")); } - for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_206_type, _seq); + _res = NULL; + done: p->level--; - return _seq; + return _res; } -// _loop1_207: except_star_block -static asdl_seq * -_loop1_207_rule(Parser *p) +// _tmp_234: '=' | '!' | ':' | '}' +static void * +_tmp_234_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; return NULL; } - void *_res = NULL; + void * _res = NULL; int _mark = p->mark; - int _start_mark = p->mark; - void **_children = PyMem_Malloc(sizeof(void *)); - if (!_children) { - p->error_indicator = 1; - PyErr_NoMemory(); - p->level--; - return NULL; - } - Py_ssize_t _children_capacity = 1; - Py_ssize_t _n = 0; - { // except_star_block + { // '=' if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop1_207[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "except_star_block")); - excepthandler_ty except_star_block_var; - while ( - (except_star_block_var = except_star_block_rule(p)) // except_star_block + D(fprintf(stderr, "%*c> _tmp_234[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'='")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 22)) // token='=' ) { - _res = except_star_block_var; - if (_n == _children_capacity) { - _children_capacity *= 2; - void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); - if (!_new_children) { - PyMem_Free(_children); - p->error_indicator = 1; - PyErr_NoMemory(); - p->level--; - return NULL; - } - _children = _new_children; - } - _children[_n++] = _res; - _mark = p->mark; + D(fprintf(stderr, "%*c+ _tmp_234[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'='")); + _res = _literal; + goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop1_207[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "except_star_block")); - } - if (_n == 0 || p->error_indicator) { - PyMem_Free(_children); - p->level--; - return NULL; - } - asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); - if (!_seq) { - PyMem_Free(_children); - p->error_indicator = 1; - PyErr_NoMemory(); - p->level--; - return NULL; + D(fprintf(stderr, "%*c%s _tmp_234[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'='")); } - for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); - PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop1_207_type, _seq); - p->level--; - return _seq; -} - -// _tmp_208: expression ['as' NAME] -static void * -_tmp_208_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + { // '!' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_234[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'!'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 54)) // token='!' + ) + { + D(fprintf(stderr, "%*c+ _tmp_234[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'!'")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_234[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'!'")); } - if (p->error_indicator) { - p->level--; - return NULL; + { // ':' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_234[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 11)) // token=':' + ) + { + D(fprintf(stderr, "%*c+ _tmp_234[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_234[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); } - void * _res = NULL; - int _mark = p->mark; - { // expression ['as' NAME] + { // '}' if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_208[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ['as' NAME]")); - void *_opt_var; - UNUSED(_opt_var); // Silence compiler warnings - expr_ty expression_var; + D(fprintf(stderr, "%*c> _tmp_234[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'}'")); + Token * _literal; if ( - (expression_var = expression_rule(p)) // expression - && - (_opt_var = _tmp_244_rule(p), !p->error_indicator) // ['as' NAME] + (_literal = _PyPegen_expect_token(p, 26)) // token='}' ) { - D(fprintf(stderr, "%*c+ _tmp_208[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ['as' NAME]")); - _res = _PyPegen_dummy_name(p, expression_var, _opt_var); + D(fprintf(stderr, "%*c+ _tmp_234[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'}'")); + _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_208[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression ['as' NAME]")); + D(fprintf(stderr, "%*c%s _tmp_234[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'}'")); } _res = NULL; done: @@ -36920,13 +39312,12 @@ _tmp_208_rule(Parser *p) return _res; } -// _tmp_209: 'as' NAME +// _tmp_235: yield_expr | star_expressions static void * -_tmp_209_rule(Parser *p) +_tmp_235_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -36934,69 +39325,43 @@ _tmp_209_rule(Parser *p) } void * _res = NULL; int _mark = p->mark; - { // 'as' NAME + { // yield_expr if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_209[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); - Token * _keyword; - expr_ty name_var; + D(fprintf(stderr, "%*c> _tmp_235[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); + expr_ty yield_expr_var; if ( - (_keyword = _PyPegen_expect_token(p, 637)) // token='as' - && - (name_var = _PyPegen_name_token(p)) // NAME + (yield_expr_var = yield_expr_rule(p)) // yield_expr ) { - D(fprintf(stderr, "%*c+ _tmp_209[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); - _res = _PyPegen_dummy_name(p, _keyword, name_var); + D(fprintf(stderr, "%*c+ _tmp_235[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); + _res = yield_expr_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_209[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); - } - _res = NULL; - done: - p->level--; - return _res; -} - -// _tmp_210: 'as' NAME -static void * -_tmp_210_rule(Parser *p) -{ - if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); - } - if (p->error_indicator) { - p->level--; - return NULL; + D(fprintf(stderr, "%*c%s _tmp_235[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "yield_expr")); } - void * _res = NULL; - int _mark = p->mark; - { // 'as' NAME + { // star_expressions if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_210[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); - Token * _keyword; - expr_ty name_var; + D(fprintf(stderr, "%*c> _tmp_235[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); + expr_ty star_expressions_var; if ( - (_keyword = _PyPegen_expect_token(p, 637)) // token='as' - && - (name_var = _PyPegen_name_token(p)) // NAME + (star_expressions_var = star_expressions_rule(p)) // star_expressions ) { - D(fprintf(stderr, "%*c+ _tmp_210[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); - _res = _PyPegen_dummy_name(p, _keyword, name_var); + D(fprintf(stderr, "%*c+ _tmp_235[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); + _res = star_expressions_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_210[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c%s _tmp_235[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions")); } _res = NULL; done: @@ -37004,13 +39369,12 @@ _tmp_210_rule(Parser *p) return _res; } -// _tmp_211: NEWLINE | ':' +// _tmp_236: '!' | ':' | '}' static void * -_tmp_211_rule(Parser *p) +_tmp_236_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -37018,57 +39382,75 @@ _tmp_211_rule(Parser *p) } void * _res = NULL; int _mark = p->mark; - { // NEWLINE + { // '!' if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_211[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NEWLINE")); - Token * newline_var; + D(fprintf(stderr, "%*c> _tmp_236[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'!'")); + Token * _literal; if ( - (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' + (_literal = _PyPegen_expect_token(p, 54)) // token='!' ) { - D(fprintf(stderr, "%*c+ _tmp_211[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NEWLINE")); - _res = newline_var; + D(fprintf(stderr, "%*c+ _tmp_236[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'!'")); + _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_211[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NEWLINE")); + D(fprintf(stderr, "%*c%s _tmp_236[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'!'")); } { // ':' if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_211[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c> _tmp_236[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 11)) // token=':' ) { - D(fprintf(stderr, "%*c+ _tmp_211[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c+ _tmp_236[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_211[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_236[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); } + { // '}' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_236[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'}'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 26)) // token='}' + ) + { + D(fprintf(stderr, "%*c+ _tmp_236[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'}'")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_236[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'}'")); + } _res = NULL; done: p->level--; return _res; } -// _tmp_212: 'as' NAME +// _tmp_237: yield_expr | star_expressions static void * -_tmp_212_rule(Parser *p) +_tmp_237_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -37076,27 +39458,43 @@ _tmp_212_rule(Parser *p) } void * _res = NULL; int _mark = p->mark; - { // 'as' NAME + { // yield_expr if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_212[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); - Token * _keyword; - expr_ty name_var; + D(fprintf(stderr, "%*c> _tmp_237[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); + expr_ty yield_expr_var; if ( - (_keyword = _PyPegen_expect_token(p, 637)) // token='as' - && - (name_var = _PyPegen_name_token(p)) // NAME + (yield_expr_var = yield_expr_rule(p)) // yield_expr ) { - D(fprintf(stderr, "%*c+ _tmp_212[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); - _res = _PyPegen_dummy_name(p, _keyword, name_var); + D(fprintf(stderr, "%*c+ _tmp_237[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); + _res = yield_expr_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_212[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c%s _tmp_237[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "yield_expr")); + } + { // star_expressions + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_237[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); + expr_ty star_expressions_var; + if ( + (star_expressions_var = star_expressions_rule(p)) // star_expressions + ) + { + D(fprintf(stderr, "%*c+ _tmp_237[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); + _res = star_expressions_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_237[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions")); } _res = NULL; done: @@ -37104,13 +39502,12 @@ _tmp_212_rule(Parser *p) return _res; } -// _tmp_213: 'as' NAME +// _tmp_238: yield_expr | star_expressions static void * -_tmp_213_rule(Parser *p) +_tmp_238_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -37118,27 +39515,43 @@ _tmp_213_rule(Parser *p) } void * _res = NULL; int _mark = p->mark; - { // 'as' NAME + { // yield_expr if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_213[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); - Token * _keyword; - expr_ty name_var; + D(fprintf(stderr, "%*c> _tmp_238[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); + expr_ty yield_expr_var; if ( - (_keyword = _PyPegen_expect_token(p, 637)) // token='as' - && - (name_var = _PyPegen_name_token(p)) // NAME + (yield_expr_var = yield_expr_rule(p)) // yield_expr ) { - D(fprintf(stderr, "%*c+ _tmp_213[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); - _res = _PyPegen_dummy_name(p, _keyword, name_var); + D(fprintf(stderr, "%*c+ _tmp_238[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); + _res = yield_expr_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_213[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c%s _tmp_238[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "yield_expr")); + } + { // star_expressions + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_238[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); + expr_ty star_expressions_var; + if ( + (star_expressions_var = star_expressions_rule(p)) // star_expressions + ) + { + D(fprintf(stderr, "%*c+ _tmp_238[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); + _res = star_expressions_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_238[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions")); } _res = NULL; done: @@ -37146,13 +39559,12 @@ _tmp_213_rule(Parser *p) return _res; } -// _tmp_214: positional_patterns ',' +// _tmp_239: '!' NAME static void * -_tmp_214_rule(Parser *p) +_tmp_239_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -37160,27 +39572,27 @@ _tmp_214_rule(Parser *p) } void * _res = NULL; int _mark = p->mark; - { // positional_patterns ',' + { // '!' NAME if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_214[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "positional_patterns ','")); + D(fprintf(stderr, "%*c> _tmp_239[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'!' NAME")); Token * _literal; - asdl_pattern_seq* positional_patterns_var; + expr_ty name_var; if ( - (positional_patterns_var = positional_patterns_rule(p)) // positional_patterns + (_literal = _PyPegen_expect_token(p, 54)) // token='!' && - (_literal = _PyPegen_expect_token(p, 12)) // token=',' + (name_var = _PyPegen_name_token(p)) // NAME ) { - D(fprintf(stderr, "%*c+ _tmp_214[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "positional_patterns ','")); - _res = _PyPegen_dummy_name(p, positional_patterns_var, _literal); + D(fprintf(stderr, "%*c+ _tmp_239[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'!' NAME")); + _res = _PyPegen_dummy_name(p, _literal, name_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_214[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "positional_patterns ','")); + D(fprintf(stderr, "%*c%s _tmp_239[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'!' NAME")); } _res = NULL; done: @@ -37188,13 +39600,12 @@ _tmp_214_rule(Parser *p) return _res; } -// _tmp_215: '->' expression +// _tmp_240: ':' | '}' static void * -_tmp_215_rule(Parser *p) +_tmp_240_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -37202,27 +39613,43 @@ _tmp_215_rule(Parser *p) } void * _res = NULL; int _mark = p->mark; - { // '->' expression + { // ':' if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_215[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'->' expression")); + D(fprintf(stderr, "%*c> _tmp_240[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); Token * _literal; - expr_ty expression_var; if ( - (_literal = _PyPegen_expect_token(p, 51)) // token='->' - && - (expression_var = expression_rule(p)) // expression + (_literal = _PyPegen_expect_token(p, 11)) // token=':' ) { - D(fprintf(stderr, "%*c+ _tmp_215[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'->' expression")); - _res = _PyPegen_dummy_name(p, _literal, expression_var); + D(fprintf(stderr, "%*c+ _tmp_240[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); + _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_215[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'->' expression")); + D(fprintf(stderr, "%*c%s _tmp_240[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); + } + { // '}' + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_240[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'}'")); + Token * _literal; + if ( + (_literal = _PyPegen_expect_token(p, 26)) // token='}' + ) + { + D(fprintf(stderr, "%*c+ _tmp_240[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'}'")); + _res = _literal; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_240[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'}'")); } _res = NULL; done: @@ -37230,13 +39657,12 @@ _tmp_215_rule(Parser *p) return _res; } -// _tmp_216: '(' arguments? ')' +// _tmp_241: yield_expr | star_expressions static void * -_tmp_216_rule(Parser *p) +_tmp_241_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -37244,31 +39670,43 @@ _tmp_216_rule(Parser *p) } void * _res = NULL; int _mark = p->mark; - { // '(' arguments? ')' + { // yield_expr if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_216[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'")); - Token * _literal; - Token * _literal_1; - void *_opt_var; - UNUSED(_opt_var); // Silence compiler warnings + D(fprintf(stderr, "%*c> _tmp_241[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); + expr_ty yield_expr_var; if ( - (_literal = _PyPegen_expect_token(p, 7)) // token='(' - && - (_opt_var = arguments_rule(p), !p->error_indicator) // arguments? - && - (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' + (yield_expr_var = yield_expr_rule(p)) // yield_expr ) { - D(fprintf(stderr, "%*c+ _tmp_216[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'")); - _res = _PyPegen_dummy_name(p, _literal, _opt_var, _literal_1); + D(fprintf(stderr, "%*c+ _tmp_241[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); + _res = yield_expr_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_216[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'(' arguments? ')'")); + D(fprintf(stderr, "%*c%s _tmp_241[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "yield_expr")); + } + { // star_expressions + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_241[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); + expr_ty star_expressions_var; + if ( + (star_expressions_var = star_expressions_rule(p)) // star_expressions + ) + { + D(fprintf(stderr, "%*c+ _tmp_241[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); + _res = star_expressions_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_241[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions")); } _res = NULL; done: @@ -37276,13 +39714,12 @@ _tmp_216_rule(Parser *p) return _res; } -// _tmp_217: '(' arguments? ')' +// _tmp_242: '!' NAME static void * -_tmp_217_rule(Parser *p) +_tmp_242_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -37290,31 +39727,27 @@ _tmp_217_rule(Parser *p) } void * _res = NULL; int _mark = p->mark; - { // '(' arguments? ')' + { // '!' NAME if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_217[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'")); + D(fprintf(stderr, "%*c> _tmp_242[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'!' NAME")); Token * _literal; - Token * _literal_1; - void *_opt_var; - UNUSED(_opt_var); // Silence compiler warnings + expr_ty name_var; if ( - (_literal = _PyPegen_expect_token(p, 7)) // token='(' - && - (_opt_var = arguments_rule(p), !p->error_indicator) // arguments? + (_literal = _PyPegen_expect_token(p, 54)) // token='!' && - (_literal_1 = _PyPegen_expect_token(p, 8)) // token=')' + (name_var = _PyPegen_name_token(p)) // NAME ) { - D(fprintf(stderr, "%*c+ _tmp_217[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'")); - _res = _PyPegen_dummy_name(p, _literal, _opt_var, _literal_1); + D(fprintf(stderr, "%*c+ _tmp_242[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'!' NAME")); + _res = _PyPegen_dummy_name(p, _literal, name_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_217[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'(' arguments? ')'")); + D(fprintf(stderr, "%*c%s _tmp_242[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'!' NAME")); } _res = NULL; done: @@ -37322,13 +39755,12 @@ _tmp_217_rule(Parser *p) return _res; } -// _loop0_219: ',' double_starred_kvpair +// _loop0_243: fstring_format_spec static asdl_seq * -_loop0_219_rule(Parser *p) +_loop0_243_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -37336,7 +39768,6 @@ _loop0_219_rule(Parser *p) } void *_res = NULL; int _mark = p->mark; - int _start_mark = p->mark; void **_children = PyMem_Malloc(sizeof(void *)); if (!_children) { p->error_indicator = 1; @@ -37346,27 +39777,18 @@ _loop0_219_rule(Parser *p) } Py_ssize_t _children_capacity = 1; Py_ssize_t _n = 0; - { // ',' double_starred_kvpair + { // fstring_format_spec if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _loop0_219[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' double_starred_kvpair")); - Token * _literal; - KeyValuePair* elem; + D(fprintf(stderr, "%*c> _loop0_243[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "fstring_format_spec")); + expr_ty fstring_format_spec_var; while ( - (_literal = _PyPegen_expect_token(p, 12)) // token=',' - && - (elem = double_starred_kvpair_rule(p)) // double_starred_kvpair + (fstring_format_spec_var = fstring_format_spec_rule(p)) // fstring_format_spec ) { - _res = elem; - if (_res == NULL && PyErr_Occurred()) { - p->error_indicator = 1; - PyMem_Free(_children); - p->level--; - return NULL; - } + _res = fstring_format_spec_var; if (_n == _children_capacity) { _children_capacity *= 2; void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *)); @@ -37383,8 +39805,8 @@ _loop0_219_rule(Parser *p) _mark = p->mark; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _loop0_219[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' double_starred_kvpair")); + D(fprintf(stderr, "%*c%s _loop0_243[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "fstring_format_spec")); } asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena); if (!_seq) { @@ -37396,46 +39818,60 @@ _loop0_219_rule(Parser *p) } for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]); PyMem_Free(_children); - _PyPegen_insert_memo(p, _start_mark, _loop0_219_type, _seq); p->level--; return _seq; } -// _gather_218: double_starred_kvpair _loop0_219 -static asdl_seq * -_gather_218_rule(Parser *p) +// _tmp_244: yield_expr | star_expressions +static void * +_tmp_244_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; return NULL; } - asdl_seq * _res = NULL; + void * _res = NULL; int _mark = p->mark; - { // double_starred_kvpair _loop0_219 + { // yield_expr if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _gather_218[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "double_starred_kvpair _loop0_219")); - KeyValuePair* elem; - asdl_seq * seq; + D(fprintf(stderr, "%*c> _tmp_244[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr")); + expr_ty yield_expr_var; if ( - (elem = double_starred_kvpair_rule(p)) // double_starred_kvpair - && - (seq = _loop0_219_rule(p)) // _loop0_219 + (yield_expr_var = yield_expr_rule(p)) // yield_expr ) { - D(fprintf(stderr, "%*c+ _gather_218[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "double_starred_kvpair _loop0_219")); - _res = _PyPegen_seq_insert_in_front(p, elem, seq); + D(fprintf(stderr, "%*c+ _tmp_244[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr")); + _res = yield_expr_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_244[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "yield_expr")); + } + { // star_expressions + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_244[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions")); + expr_ty star_expressions_var; + if ( + (star_expressions_var = star_expressions_rule(p)) // star_expressions + ) + { + D(fprintf(stderr, "%*c+ _tmp_244[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions")); + _res = star_expressions_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _gather_218[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "double_starred_kvpair _loop0_219")); + D(fprintf(stderr, "%*c%s _tmp_244[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions")); } _res = NULL; done: @@ -37443,13 +39879,12 @@ _gather_218_rule(Parser *p) return _res; } -// _tmp_220: '}' | ',' +// _tmp_245: '!' NAME static void * -_tmp_220_rule(Parser *p) +_tmp_245_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -37457,43 +39892,27 @@ _tmp_220_rule(Parser *p) } void * _res = NULL; int _mark = p->mark; - { // '}' - if (p->error_indicator) { - p->level--; - return NULL; - } - D(fprintf(stderr, "%*c> _tmp_220[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'}'")); - Token * _literal; - if ( - (_literal = _PyPegen_expect_token(p, 26)) // token='}' - ) - { - D(fprintf(stderr, "%*c+ _tmp_220[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'}'")); - _res = _literal; - goto done; - } - p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_220[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'}'")); - } - { // ',' + { // '!' NAME if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_220[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c> _tmp_245[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'!' NAME")); Token * _literal; + expr_ty name_var; if ( - (_literal = _PyPegen_expect_token(p, 12)) // token=',' + (_literal = _PyPegen_expect_token(p, 54)) // token='!' + && + (name_var = _PyPegen_name_token(p)) // NAME ) { - D(fprintf(stderr, "%*c+ _tmp_220[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); - _res = _literal; + D(fprintf(stderr, "%*c+ _tmp_245[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'!' NAME")); + _res = _PyPegen_dummy_name(p, _literal, name_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_220[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); + D(fprintf(stderr, "%*c%s _tmp_245[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'!' NAME")); } _res = NULL; done: @@ -37501,13 +39920,12 @@ _tmp_220_rule(Parser *p) return _res; } -// _tmp_221: '}' | ',' +// _tmp_246: ':' | '}' static void * -_tmp_221_rule(Parser *p) +_tmp_246_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -37515,43 +39933,43 @@ _tmp_221_rule(Parser *p) } void * _res = NULL; int _mark = p->mark; - { // '}' + { // ':' if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_221[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'}'")); + D(fprintf(stderr, "%*c> _tmp_246[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); Token * _literal; if ( - (_literal = _PyPegen_expect_token(p, 26)) // token='}' + (_literal = _PyPegen_expect_token(p, 11)) // token=':' ) { - D(fprintf(stderr, "%*c+ _tmp_221[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'}'")); + D(fprintf(stderr, "%*c+ _tmp_246[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_221[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'}'")); + D(fprintf(stderr, "%*c%s _tmp_246[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); } - { // ',' + { // '}' if (p->error_indicator) { p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_221[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c> _tmp_246[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'}'")); Token * _literal; if ( - (_literal = _PyPegen_expect_token(p, 12)) // token=',' + (_literal = _PyPegen_expect_token(p, 26)) // token='}' ) { - D(fprintf(stderr, "%*c+ _tmp_221[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','")); + D(fprintf(stderr, "%*c+ _tmp_246[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'}'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_221[%d-%d]: %s failed!\n", p->level, ' ', - p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','")); + D(fprintf(stderr, "%*c%s _tmp_246[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'}'")); } _res = NULL; done: @@ -37559,13 +39977,12 @@ _tmp_221_rule(Parser *p) return _res; } -// _tmp_222: star_targets '=' +// _tmp_247: star_targets '=' static void * -_tmp_222_rule(Parser *p) +_tmp_247_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -37578,7 +39995,7 @@ _tmp_222_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_222[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + D(fprintf(stderr, "%*c> _tmp_247[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); Token * _literal; expr_ty z; if ( @@ -37587,7 +40004,7 @@ _tmp_222_rule(Parser *p) (_literal = _PyPegen_expect_token(p, 22)) // token='=' ) { - D(fprintf(stderr, "%*c+ _tmp_222[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + D(fprintf(stderr, "%*c+ _tmp_247[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='")); _res = z; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -37597,7 +40014,7 @@ _tmp_222_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_222[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_247[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_targets '='")); } _res = NULL; @@ -37606,13 +40023,12 @@ _tmp_222_rule(Parser *p) return _res; } -// _tmp_223: '.' | '...' +// _tmp_248: '.' | '...' static void * -_tmp_223_rule(Parser *p) +_tmp_248_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -37625,18 +40041,18 @@ _tmp_223_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_223[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'")); + D(fprintf(stderr, "%*c> _tmp_248[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 23)) // token='.' ) { - D(fprintf(stderr, "%*c+ _tmp_223[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'")); + D(fprintf(stderr, "%*c+ _tmp_248[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_223[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_248[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'.'")); } { // '...' @@ -37644,18 +40060,18 @@ _tmp_223_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_223[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'...'")); + D(fprintf(stderr, "%*c> _tmp_248[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'...'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 52)) // token='...' ) { - D(fprintf(stderr, "%*c+ _tmp_223[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'...'")); + D(fprintf(stderr, "%*c+ _tmp_248[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'...'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_223[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_248[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'...'")); } _res = NULL; @@ -37664,13 +40080,12 @@ _tmp_223_rule(Parser *p) return _res; } -// _tmp_224: '.' | '...' +// _tmp_249: '.' | '...' static void * -_tmp_224_rule(Parser *p) +_tmp_249_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -37683,18 +40098,18 @@ _tmp_224_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_224[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'")); + D(fprintf(stderr, "%*c> _tmp_249[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 23)) // token='.' ) { - D(fprintf(stderr, "%*c+ _tmp_224[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'")); + D(fprintf(stderr, "%*c+ _tmp_249[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_224[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_249[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'.'")); } { // '...' @@ -37702,18 +40117,18 @@ _tmp_224_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_224[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'...'")); + D(fprintf(stderr, "%*c> _tmp_249[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'...'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 52)) // token='...' ) { - D(fprintf(stderr, "%*c+ _tmp_224[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'...'")); + D(fprintf(stderr, "%*c+ _tmp_249[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'...'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_224[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_249[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'...'")); } _res = NULL; @@ -37722,13 +40137,12 @@ _tmp_224_rule(Parser *p) return _res; } -// _tmp_225: '@' named_expression NEWLINE +// _tmp_250: '@' named_expression NEWLINE static void * -_tmp_225_rule(Parser *p) +_tmp_250_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -37741,7 +40155,7 @@ _tmp_225_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_225[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'@' named_expression NEWLINE")); + D(fprintf(stderr, "%*c> _tmp_250[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'@' named_expression NEWLINE")); Token * _literal; expr_ty f; Token * newline_var; @@ -37753,7 +40167,7 @@ _tmp_225_rule(Parser *p) (newline_var = _PyPegen_expect_token(p, NEWLINE)) // token='NEWLINE' ) { - D(fprintf(stderr, "%*c+ _tmp_225[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'@' named_expression NEWLINE")); + D(fprintf(stderr, "%*c+ _tmp_250[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'@' named_expression NEWLINE")); _res = f; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -37763,7 +40177,7 @@ _tmp_225_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_225[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_250[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'@' named_expression NEWLINE")); } _res = NULL; @@ -37772,13 +40186,12 @@ _tmp_225_rule(Parser *p) return _res; } -// _tmp_226: ',' expression +// _tmp_251: ',' expression static void * -_tmp_226_rule(Parser *p) +_tmp_251_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -37791,7 +40204,7 @@ _tmp_226_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_226[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression")); + D(fprintf(stderr, "%*c> _tmp_251[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression")); Token * _literal; expr_ty c; if ( @@ -37800,7 +40213,7 @@ _tmp_226_rule(Parser *p) (c = expression_rule(p)) // expression ) { - D(fprintf(stderr, "%*c+ _tmp_226[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' expression")); + D(fprintf(stderr, "%*c+ _tmp_251[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' expression")); _res = c; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -37810,7 +40223,7 @@ _tmp_226_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_226[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_251[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' expression")); } _res = NULL; @@ -37819,13 +40232,12 @@ _tmp_226_rule(Parser *p) return _res; } -// _tmp_227: ',' star_expression +// _tmp_252: ',' star_expression static void * -_tmp_227_rule(Parser *p) +_tmp_252_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -37838,7 +40250,7 @@ _tmp_227_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_227[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_expression")); + D(fprintf(stderr, "%*c> _tmp_252[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_expression")); Token * _literal; expr_ty c; if ( @@ -37847,7 +40259,7 @@ _tmp_227_rule(Parser *p) (c = star_expression_rule(p)) // star_expression ) { - D(fprintf(stderr, "%*c+ _tmp_227[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_expression")); + D(fprintf(stderr, "%*c+ _tmp_252[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_expression")); _res = c; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -37857,7 +40269,7 @@ _tmp_227_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_227[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_252[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' star_expression")); } _res = NULL; @@ -37866,13 +40278,12 @@ _tmp_227_rule(Parser *p) return _res; } -// _tmp_228: 'or' conjunction +// _tmp_253: 'or' conjunction static void * -_tmp_228_rule(Parser *p) +_tmp_253_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -37885,7 +40296,7 @@ _tmp_228_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_228[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'or' conjunction")); + D(fprintf(stderr, "%*c> _tmp_253[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'or' conjunction")); Token * _keyword; expr_ty c; if ( @@ -37894,7 +40305,7 @@ _tmp_228_rule(Parser *p) (c = conjunction_rule(p)) // conjunction ) { - D(fprintf(stderr, "%*c+ _tmp_228[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'or' conjunction")); + D(fprintf(stderr, "%*c+ _tmp_253[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'or' conjunction")); _res = c; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -37904,7 +40315,7 @@ _tmp_228_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_228[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_253[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'or' conjunction")); } _res = NULL; @@ -37913,13 +40324,12 @@ _tmp_228_rule(Parser *p) return _res; } -// _tmp_229: 'and' inversion +// _tmp_254: 'and' inversion static void * -_tmp_229_rule(Parser *p) +_tmp_254_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -37932,7 +40342,7 @@ _tmp_229_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_229[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'and' inversion")); + D(fprintf(stderr, "%*c> _tmp_254[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'and' inversion")); Token * _keyword; expr_ty c; if ( @@ -37941,7 +40351,7 @@ _tmp_229_rule(Parser *p) (c = inversion_rule(p)) // inversion ) { - D(fprintf(stderr, "%*c+ _tmp_229[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'and' inversion")); + D(fprintf(stderr, "%*c+ _tmp_254[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'and' inversion")); _res = c; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -37951,7 +40361,7 @@ _tmp_229_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_229[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_254[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'and' inversion")); } _res = NULL; @@ -37960,13 +40370,12 @@ _tmp_229_rule(Parser *p) return _res; } -// _tmp_230: slice | starred_expression +// _tmp_255: slice | starred_expression static void * -_tmp_230_rule(Parser *p) +_tmp_255_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -37979,18 +40388,18 @@ _tmp_230_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_230[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slice")); + D(fprintf(stderr, "%*c> _tmp_255[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slice")); expr_ty slice_var; if ( (slice_var = slice_rule(p)) // slice ) { - D(fprintf(stderr, "%*c+ _tmp_230[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slice")); + D(fprintf(stderr, "%*c+ _tmp_255[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slice")); _res = slice_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_230[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_255[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "slice")); } { // starred_expression @@ -37998,18 +40407,18 @@ _tmp_230_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_230[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "starred_expression")); + D(fprintf(stderr, "%*c> _tmp_255[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "starred_expression")); expr_ty starred_expression_var; if ( (starred_expression_var = starred_expression_rule(p)) // starred_expression ) { - D(fprintf(stderr, "%*c+ _tmp_230[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "starred_expression")); + D(fprintf(stderr, "%*c+ _tmp_255[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "starred_expression")); _res = starred_expression_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_230[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_255[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "starred_expression")); } _res = NULL; @@ -38018,13 +40427,69 @@ _tmp_230_rule(Parser *p) return _res; } -// _tmp_231: 'if' disjunction +// _tmp_256: fstring | string static void * -_tmp_231_rule(Parser *p) +_tmp_256_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); + } + if (p->error_indicator) { + p->level--; + return NULL; + } + void * _res = NULL; + int _mark = p->mark; + { // fstring + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_256[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "fstring")); + expr_ty fstring_var; + if ( + (fstring_var = fstring_rule(p)) // fstring + ) + { + D(fprintf(stderr, "%*c+ _tmp_256[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "fstring")); + _res = fstring_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_256[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "fstring")); + } + { // string + if (p->error_indicator) { + p->level--; + return NULL; + } + D(fprintf(stderr, "%*c> _tmp_256[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "string")); + expr_ty string_var; + if ( + (string_var = string_rule(p)) // string + ) + { + D(fprintf(stderr, "%*c+ _tmp_256[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "string")); + _res = string_var; + goto done; + } + p->mark = _mark; + D(fprintf(stderr, "%*c%s _tmp_256[%d-%d]: %s failed!\n", p->level, ' ', + p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "string")); + } + _res = NULL; + done: + p->level--; + return _res; +} + +// _tmp_257: 'if' disjunction +static void * +_tmp_257_rule(Parser *p) +{ + if (p->level++ == MAXSTACK) { + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -38037,16 +40502,16 @@ _tmp_231_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_231[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); + D(fprintf(stderr, "%*c> _tmp_257[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); Token * _keyword; expr_ty z; if ( - (_keyword = _PyPegen_expect_token(p, 639)) // token='if' + (_keyword = _PyPegen_expect_token(p, 642)) // token='if' && (z = disjunction_rule(p)) // disjunction ) { - D(fprintf(stderr, "%*c+ _tmp_231[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); + D(fprintf(stderr, "%*c+ _tmp_257[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); _res = z; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -38056,7 +40521,7 @@ _tmp_231_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_231[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_257[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'if' disjunction")); } _res = NULL; @@ -38065,13 +40530,12 @@ _tmp_231_rule(Parser *p) return _res; } -// _tmp_232: 'if' disjunction +// _tmp_258: 'if' disjunction static void * -_tmp_232_rule(Parser *p) +_tmp_258_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -38084,16 +40548,16 @@ _tmp_232_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_232[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); + D(fprintf(stderr, "%*c> _tmp_258[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); Token * _keyword; expr_ty z; if ( - (_keyword = _PyPegen_expect_token(p, 639)) // token='if' + (_keyword = _PyPegen_expect_token(p, 642)) // token='if' && (z = disjunction_rule(p)) // disjunction ) { - D(fprintf(stderr, "%*c+ _tmp_232[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); + D(fprintf(stderr, "%*c+ _tmp_258[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' disjunction")); _res = z; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -38103,7 +40567,7 @@ _tmp_232_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_232[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_258[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'if' disjunction")); } _res = NULL; @@ -38112,13 +40576,12 @@ _tmp_232_rule(Parser *p) return _res; } -// _tmp_233: starred_expression | (assignment_expression | expression !':=') !'=' +// _tmp_259: starred_expression | (assignment_expression | expression !':=') !'=' static void * -_tmp_233_rule(Parser *p) +_tmp_259_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -38131,18 +40594,18 @@ _tmp_233_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_233[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "starred_expression")); + D(fprintf(stderr, "%*c> _tmp_259[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "starred_expression")); expr_ty starred_expression_var; if ( (starred_expression_var = starred_expression_rule(p)) // starred_expression ) { - D(fprintf(stderr, "%*c+ _tmp_233[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "starred_expression")); + D(fprintf(stderr, "%*c+ _tmp_259[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "starred_expression")); _res = starred_expression_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_233[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_259[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "starred_expression")); } { // (assignment_expression | expression !':=') !'=' @@ -38150,20 +40613,20 @@ _tmp_233_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_233[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(assignment_expression | expression !':=') !'='")); - void *_tmp_245_var; + D(fprintf(stderr, "%*c> _tmp_259[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(assignment_expression | expression !':=') !'='")); + void *_tmp_271_var; if ( - (_tmp_245_var = _tmp_245_rule(p)) // assignment_expression | expression !':=' + (_tmp_271_var = _tmp_271_rule(p)) // assignment_expression | expression !':=' && _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 22) // token='=' ) { - D(fprintf(stderr, "%*c+ _tmp_233[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(assignment_expression | expression !':=') !'='")); - _res = _tmp_245_var; + D(fprintf(stderr, "%*c+ _tmp_259[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(assignment_expression | expression !':=') !'='")); + _res = _tmp_271_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_233[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_259[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(assignment_expression | expression !':=') !'='")); } _res = NULL; @@ -38172,13 +40635,12 @@ _tmp_233_rule(Parser *p) return _res; } -// _tmp_234: ',' star_target +// _tmp_260: ',' star_target static void * -_tmp_234_rule(Parser *p) +_tmp_260_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -38191,7 +40653,7 @@ _tmp_234_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_234[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_target")); + D(fprintf(stderr, "%*c> _tmp_260[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_target")); Token * _literal; expr_ty c; if ( @@ -38200,7 +40662,7 @@ _tmp_234_rule(Parser *p) (c = star_target_rule(p)) // star_target ) { - D(fprintf(stderr, "%*c+ _tmp_234[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_target")); + D(fprintf(stderr, "%*c+ _tmp_260[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_target")); _res = c; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -38210,7 +40672,7 @@ _tmp_234_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_234[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_260[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' star_target")); } _res = NULL; @@ -38219,13 +40681,12 @@ _tmp_234_rule(Parser *p) return _res; } -// _tmp_235: ',' star_target +// _tmp_261: ',' star_target static void * -_tmp_235_rule(Parser *p) +_tmp_261_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -38238,7 +40699,7 @@ _tmp_235_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_235[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_target")); + D(fprintf(stderr, "%*c> _tmp_261[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_target")); Token * _literal; expr_ty c; if ( @@ -38247,7 +40708,7 @@ _tmp_235_rule(Parser *p) (c = star_target_rule(p)) // star_target ) { - D(fprintf(stderr, "%*c+ _tmp_235[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_target")); + D(fprintf(stderr, "%*c+ _tmp_261[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_target")); _res = c; if (_res == NULL && PyErr_Occurred()) { p->error_indicator = 1; @@ -38257,7 +40718,7 @@ _tmp_235_rule(Parser *p) goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_235[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_261[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' star_target")); } _res = NULL; @@ -38266,13 +40727,12 @@ _tmp_235_rule(Parser *p) return _res; } -// _tmp_236: star_targets '=' +// _tmp_262: star_targets '=' static void * -_tmp_236_rule(Parser *p) +_tmp_262_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -38285,7 +40745,7 @@ _tmp_236_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_236[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + D(fprintf(stderr, "%*c> _tmp_262[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); Token * _literal; expr_ty star_targets_var; if ( @@ -38294,12 +40754,12 @@ _tmp_236_rule(Parser *p) (_literal = _PyPegen_expect_token(p, 22)) // token='=' ) { - D(fprintf(stderr, "%*c+ _tmp_236[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + D(fprintf(stderr, "%*c+ _tmp_262[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='")); _res = _PyPegen_dummy_name(p, star_targets_var, _literal); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_236[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_262[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_targets '='")); } _res = NULL; @@ -38308,13 +40768,12 @@ _tmp_236_rule(Parser *p) return _res; } -// _tmp_237: star_targets '=' +// _tmp_263: star_targets '=' static void * -_tmp_237_rule(Parser *p) +_tmp_263_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -38327,7 +40786,7 @@ _tmp_237_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_237[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + D(fprintf(stderr, "%*c> _tmp_263[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='")); Token * _literal; expr_ty star_targets_var; if ( @@ -38336,12 +40795,12 @@ _tmp_237_rule(Parser *p) (_literal = _PyPegen_expect_token(p, 22)) // token='=' ) { - D(fprintf(stderr, "%*c+ _tmp_237[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='")); + D(fprintf(stderr, "%*c+ _tmp_263[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='")); _res = _PyPegen_dummy_name(p, star_targets_var, _literal); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_237[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_263[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_targets '='")); } _res = NULL; @@ -38350,13 +40809,12 @@ _tmp_237_rule(Parser *p) return _res; } -// _tmp_238: ')' | '**' +// _tmp_264: ')' | '**' static void * -_tmp_238_rule(Parser *p) +_tmp_264_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -38369,18 +40827,18 @@ _tmp_238_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_238[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c> _tmp_264[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 8)) // token=')' ) { - D(fprintf(stderr, "%*c+ _tmp_238[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); + D(fprintf(stderr, "%*c+ _tmp_264[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_238[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_264[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "')'")); } { // '**' @@ -38388,18 +40846,18 @@ _tmp_238_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_238[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); + D(fprintf(stderr, "%*c> _tmp_264[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 35)) // token='**' ) { - D(fprintf(stderr, "%*c+ _tmp_238[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); + D(fprintf(stderr, "%*c+ _tmp_264[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_238[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_264[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**'")); } _res = NULL; @@ -38408,13 +40866,12 @@ _tmp_238_rule(Parser *p) return _res; } -// _tmp_239: ':' | '**' +// _tmp_265: ':' | '**' static void * -_tmp_239_rule(Parser *p) +_tmp_265_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -38427,18 +40884,18 @@ _tmp_239_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_239[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c> _tmp_265[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 11)) // token=':' ) { - D(fprintf(stderr, "%*c+ _tmp_239[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); + D(fprintf(stderr, "%*c+ _tmp_265[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_239[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_265[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'")); } { // '**' @@ -38446,18 +40903,18 @@ _tmp_239_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_239[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); + D(fprintf(stderr, "%*c> _tmp_265[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'")); Token * _literal; if ( (_literal = _PyPegen_expect_token(p, 35)) // token='**' ) { - D(fprintf(stderr, "%*c+ _tmp_239[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); + D(fprintf(stderr, "%*c+ _tmp_265[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'")); _res = _literal; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_239[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_265[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**'")); } _res = NULL; @@ -38466,13 +40923,12 @@ _tmp_239_rule(Parser *p) return _res; } -// _tmp_240: expression ['as' star_target] +// _tmp_266: expression ['as' star_target] static void * -_tmp_240_rule(Parser *p) +_tmp_266_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -38485,22 +40941,22 @@ _tmp_240_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_240[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ['as' star_target]")); + D(fprintf(stderr, "%*c> _tmp_266[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ['as' star_target]")); void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings expr_ty expression_var; if ( (expression_var = expression_rule(p)) // expression && - (_opt_var = _tmp_246_rule(p), !p->error_indicator) // ['as' star_target] + (_opt_var = _tmp_272_rule(p), !p->error_indicator) // ['as' star_target] ) { - D(fprintf(stderr, "%*c+ _tmp_240[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ['as' star_target]")); + D(fprintf(stderr, "%*c+ _tmp_266[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ['as' star_target]")); _res = _PyPegen_dummy_name(p, expression_var, _opt_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_240[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_266[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression ['as' star_target]")); } _res = NULL; @@ -38509,13 +40965,12 @@ _tmp_240_rule(Parser *p) return _res; } -// _tmp_241: expressions ['as' star_target] +// _tmp_267: expressions ['as' star_target] static void * -_tmp_241_rule(Parser *p) +_tmp_267_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -38528,22 +40983,22 @@ _tmp_241_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_241[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expressions ['as' star_target]")); + D(fprintf(stderr, "%*c> _tmp_267[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expressions ['as' star_target]")); void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings expr_ty expressions_var; if ( (expressions_var = expressions_rule(p)) // expressions && - (_opt_var = _tmp_247_rule(p), !p->error_indicator) // ['as' star_target] + (_opt_var = _tmp_273_rule(p), !p->error_indicator) // ['as' star_target] ) { - D(fprintf(stderr, "%*c+ _tmp_241[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expressions ['as' star_target]")); + D(fprintf(stderr, "%*c+ _tmp_267[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expressions ['as' star_target]")); _res = _PyPegen_dummy_name(p, expressions_var, _opt_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_241[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_267[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expressions ['as' star_target]")); } _res = NULL; @@ -38552,13 +41007,12 @@ _tmp_241_rule(Parser *p) return _res; } -// _tmp_242: expression ['as' star_target] +// _tmp_268: expression ['as' star_target] static void * -_tmp_242_rule(Parser *p) +_tmp_268_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -38571,22 +41025,22 @@ _tmp_242_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_242[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ['as' star_target]")); + D(fprintf(stderr, "%*c> _tmp_268[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ['as' star_target]")); void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings expr_ty expression_var; if ( (expression_var = expression_rule(p)) // expression && - (_opt_var = _tmp_248_rule(p), !p->error_indicator) // ['as' star_target] + (_opt_var = _tmp_274_rule(p), !p->error_indicator) // ['as' star_target] ) { - D(fprintf(stderr, "%*c+ _tmp_242[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ['as' star_target]")); + D(fprintf(stderr, "%*c+ _tmp_268[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ['as' star_target]")); _res = _PyPegen_dummy_name(p, expression_var, _opt_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_242[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_268[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression ['as' star_target]")); } _res = NULL; @@ -38595,13 +41049,12 @@ _tmp_242_rule(Parser *p) return _res; } -// _tmp_243: expressions ['as' star_target] +// _tmp_269: expressions ['as' star_target] static void * -_tmp_243_rule(Parser *p) +_tmp_269_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -38614,22 +41067,22 @@ _tmp_243_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_243[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expressions ['as' star_target]")); + D(fprintf(stderr, "%*c> _tmp_269[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expressions ['as' star_target]")); void *_opt_var; UNUSED(_opt_var); // Silence compiler warnings expr_ty expressions_var; if ( (expressions_var = expressions_rule(p)) // expressions && - (_opt_var = _tmp_249_rule(p), !p->error_indicator) // ['as' star_target] + (_opt_var = _tmp_275_rule(p), !p->error_indicator) // ['as' star_target] ) { - D(fprintf(stderr, "%*c+ _tmp_243[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expressions ['as' star_target]")); + D(fprintf(stderr, "%*c+ _tmp_269[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expressions ['as' star_target]")); _res = _PyPegen_dummy_name(p, expressions_var, _opt_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_243[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_269[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expressions ['as' star_target]")); } _res = NULL; @@ -38638,13 +41091,12 @@ _tmp_243_rule(Parser *p) return _res; } -// _tmp_244: 'as' NAME +// _tmp_270: 'as' NAME static void * -_tmp_244_rule(Parser *p) +_tmp_270_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -38657,21 +41109,21 @@ _tmp_244_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_244[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c> _tmp_270[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME")); Token * _keyword; expr_ty name_var; if ( - (_keyword = _PyPegen_expect_token(p, 637)) // token='as' + (_keyword = _PyPegen_expect_token(p, 640)) // token='as' && (name_var = _PyPegen_name_token(p)) // NAME ) { - D(fprintf(stderr, "%*c+ _tmp_244[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); + D(fprintf(stderr, "%*c+ _tmp_270[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME")); _res = _PyPegen_dummy_name(p, _keyword, name_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_244[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_270[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME")); } _res = NULL; @@ -38680,13 +41132,12 @@ _tmp_244_rule(Parser *p) return _res; } -// _tmp_245: assignment_expression | expression !':=' +// _tmp_271: assignment_expression | expression !':=' static void * -_tmp_245_rule(Parser *p) +_tmp_271_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -38699,18 +41150,18 @@ _tmp_245_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_245[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "assignment_expression")); + D(fprintf(stderr, "%*c> _tmp_271[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "assignment_expression")); expr_ty assignment_expression_var; if ( (assignment_expression_var = assignment_expression_rule(p)) // assignment_expression ) { - D(fprintf(stderr, "%*c+ _tmp_245[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "assignment_expression")); + D(fprintf(stderr, "%*c+ _tmp_271[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "assignment_expression")); _res = assignment_expression_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_245[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_271[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "assignment_expression")); } { // expression !':=' @@ -38718,7 +41169,7 @@ _tmp_245_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_245[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression !':='")); + D(fprintf(stderr, "%*c> _tmp_271[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression !':='")); expr_ty expression_var; if ( (expression_var = expression_rule(p)) // expression @@ -38726,12 +41177,12 @@ _tmp_245_rule(Parser *p) _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 53) // token=':=' ) { - D(fprintf(stderr, "%*c+ _tmp_245[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression !':='")); + D(fprintf(stderr, "%*c+ _tmp_271[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression !':='")); _res = expression_var; goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_245[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_271[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression !':='")); } _res = NULL; @@ -38740,13 +41191,12 @@ _tmp_245_rule(Parser *p) return _res; } -// _tmp_246: 'as' star_target +// _tmp_272: 'as' star_target static void * -_tmp_246_rule(Parser *p) +_tmp_272_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -38759,21 +41209,21 @@ _tmp_246_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_246[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target")); + D(fprintf(stderr, "%*c> _tmp_272[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target")); Token * _keyword; expr_ty star_target_var; if ( - (_keyword = _PyPegen_expect_token(p, 637)) // token='as' + (_keyword = _PyPegen_expect_token(p, 640)) // token='as' && (star_target_var = star_target_rule(p)) // star_target ) { - D(fprintf(stderr, "%*c+ _tmp_246[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' star_target")); + D(fprintf(stderr, "%*c+ _tmp_272[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' star_target")); _res = _PyPegen_dummy_name(p, _keyword, star_target_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_246[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_272[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' star_target")); } _res = NULL; @@ -38782,13 +41232,12 @@ _tmp_246_rule(Parser *p) return _res; } -// _tmp_247: 'as' star_target +// _tmp_273: 'as' star_target static void * -_tmp_247_rule(Parser *p) +_tmp_273_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -38801,21 +41250,21 @@ _tmp_247_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_247[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target")); + D(fprintf(stderr, "%*c> _tmp_273[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target")); Token * _keyword; expr_ty star_target_var; if ( - (_keyword = _PyPegen_expect_token(p, 637)) // token='as' + (_keyword = _PyPegen_expect_token(p, 640)) // token='as' && (star_target_var = star_target_rule(p)) // star_target ) { - D(fprintf(stderr, "%*c+ _tmp_247[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' star_target")); + D(fprintf(stderr, "%*c+ _tmp_273[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' star_target")); _res = _PyPegen_dummy_name(p, _keyword, star_target_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_247[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_273[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' star_target")); } _res = NULL; @@ -38824,13 +41273,12 @@ _tmp_247_rule(Parser *p) return _res; } -// _tmp_248: 'as' star_target +// _tmp_274: 'as' star_target static void * -_tmp_248_rule(Parser *p) +_tmp_274_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -38843,21 +41291,21 @@ _tmp_248_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_248[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target")); + D(fprintf(stderr, "%*c> _tmp_274[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target")); Token * _keyword; expr_ty star_target_var; if ( - (_keyword = _PyPegen_expect_token(p, 637)) // token='as' + (_keyword = _PyPegen_expect_token(p, 640)) // token='as' && (star_target_var = star_target_rule(p)) // star_target ) { - D(fprintf(stderr, "%*c+ _tmp_248[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' star_target")); + D(fprintf(stderr, "%*c+ _tmp_274[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' star_target")); _res = _PyPegen_dummy_name(p, _keyword, star_target_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_248[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_274[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' star_target")); } _res = NULL; @@ -38866,13 +41314,12 @@ _tmp_248_rule(Parser *p) return _res; } -// _tmp_249: 'as' star_target +// _tmp_275: 'as' star_target static void * -_tmp_249_rule(Parser *p) +_tmp_275_rule(Parser *p) { if (p->level++ == MAXSTACK) { - p->error_indicator = 1; - PyErr_NoMemory(); + _Pypegen_stack_overflow(p); } if (p->error_indicator) { p->level--; @@ -38885,21 +41332,21 @@ _tmp_249_rule(Parser *p) p->level--; return NULL; } - D(fprintf(stderr, "%*c> _tmp_249[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target")); + D(fprintf(stderr, "%*c> _tmp_275[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target")); Token * _keyword; expr_ty star_target_var; if ( - (_keyword = _PyPegen_expect_token(p, 637)) // token='as' + (_keyword = _PyPegen_expect_token(p, 640)) // token='as' && (star_target_var = star_target_rule(p)) // star_target ) { - D(fprintf(stderr, "%*c+ _tmp_249[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' star_target")); + D(fprintf(stderr, "%*c+ _tmp_275[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' star_target")); _res = _PyPegen_dummy_name(p, _keyword, star_target_var); goto done; } p->mark = _mark; - D(fprintf(stderr, "%*c%s _tmp_249[%d-%d]: %s failed!\n", p->level, ' ', + D(fprintf(stderr, "%*c%s _tmp_275[%d-%d]: %s failed!\n", p->level, ' ', p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' star_target")); } _res = NULL; diff --git a/Parser/pegen.c b/Parser/pegen.c index 556e50a1..b9894dd0 100644 --- a/Parser/pegen.c +++ b/Parser/pegen.c @@ -78,13 +78,7 @@ init_normalization(Parser *p) if (p->normalize) { return 1; } - PyObject *m = PyImport_ImportModule("unicodedata"); - if (!m) - { - return 0; - } - p->normalize = PyObject_GetAttrString(m, "normalize"); - Py_DECREF(m); + p->normalize = _PyImport_GetModuleAttrString("unicodedata", "normalize"); if (!p->normalize) { return 0; @@ -129,16 +123,18 @@ growable_comment_array_deallocate(growable_comment_array *arr) { } static int -_get_keyword_or_name_type(Parser *p, const char *name, int name_len) +_get_keyword_or_name_type(Parser *p, struct token *new_token) { + int name_len = new_token->end_col_offset - new_token->col_offset; assert(name_len > 0); + if (name_len >= p->n_keyword_lists || p->keywords[name_len] == NULL || p->keywords[name_len]->type == -1) { return NAME; } for (KeywordToken *k = p->keywords[name_len]; k != NULL && k->type != -1; k++) { - if (strncmp(k->str, name, name_len) == 0) { + if (strncmp(k->str, new_token->start, name_len) == 0) { return k->type; } } @@ -146,33 +142,36 @@ _get_keyword_or_name_type(Parser *p, const char *name, int name_len) } static int -initialize_token(Parser *p, Token *token, const char *start, const char *end, int token_type) { - assert(token != NULL); +initialize_token(Parser *p, Token *parser_token, struct token *new_token, int token_type) { + assert(parser_token != NULL); - token->type = (token_type == NAME) ? _get_keyword_or_name_type(p, start, (int)(end - start)) : token_type; - token->bytes = PyBytes_FromStringAndSize(start, end - start); - if (token->bytes == NULL) { + parser_token->type = (token_type == NAME) ? _get_keyword_or_name_type(p, new_token) : token_type; + parser_token->bytes = PyBytes_FromStringAndSize(new_token->start, new_token->end - new_token->start); + if (parser_token->bytes == NULL) { return -1; } - - if (_PyArena_AddPyObject(p->arena, token->bytes) < 0) { - Py_DECREF(token->bytes); + if (_PyArena_AddPyObject(p->arena, parser_token->bytes) < 0) { + Py_DECREF(parser_token->bytes); return -1; } - token->level = p->tok->level; - - const char *line_start = token_type == STRING ? p->tok->multi_line_start : p->tok->line_start; - int lineno = token_type == STRING ? p->tok->first_lineno : p->tok->lineno; - int end_lineno = p->tok->lineno; - - int col_offset = (start != NULL && start >= line_start) ? (int)(start - line_start) : -1; - int end_col_offset = (end != NULL && end >= p->tok->line_start) ? (int)(end - p->tok->line_start) : -1; + parser_token->metadata = NULL; + if (new_token->metadata != NULL) { + if (_PyArena_AddPyObject(p->arena, new_token->metadata) < 0) { + Py_DECREF(parser_token->metadata); + return -1; + } + parser_token->metadata = new_token->metadata; + new_token->metadata = NULL; + } - token->lineno = lineno; - token->col_offset = p->tok->lineno == p->starting_lineno ? p->starting_col_offset + col_offset : col_offset; - token->end_lineno = end_lineno; - token->end_col_offset = p->tok->lineno == p->starting_lineno ? p->starting_col_offset + end_col_offset : end_col_offset; + parser_token->level = new_token->level; + parser_token->lineno = new_token->lineno; + parser_token->col_offset = p->tok->lineno == p->starting_lineno ? p->starting_col_offset + new_token->col_offset + : new_token->col_offset; + parser_token->end_lineno = new_token->end_lineno; + parser_token->end_col_offset = p->tok->lineno == p->starting_lineno ? p->starting_col_offset + new_token->end_col_offset + : new_token->end_col_offset; p->fill += 1; @@ -208,26 +207,26 @@ _resize_tokens_array(Parser *p) { int _PyPegen_fill_token(Parser *p) { - const char *start; - const char *end; - int type = _PyTokenizer_Get(p->tok, &start, &end); + struct token new_token; + _PyToken_Init(&new_token); + int type = _PyTokenizer_Get(p->tok, &new_token); // Record and skip '# type: ignore' comments while (type == TYPE_IGNORE) { - Py_ssize_t len = end - start; + Py_ssize_t len = new_token.end_col_offset - new_token.col_offset; char *tag = PyMem_Malloc(len + 1); if (tag == NULL) { PyErr_NoMemory(); - return -1; + goto error; } - strncpy(tag, start, len); + strncpy(tag, new_token.start, len); tag[len] = '\0'; // Ownership of tag passes to the growable array if (!growable_comment_array_add(&p->type_ignore_comments, p->tok->lineno, tag)) { PyErr_NoMemory(); - return -1; + goto error; } - type = _PyTokenizer_Get(p->tok, &start, &end); + type = _PyTokenizer_Get(p->tok, &new_token); } // If we have reached the end and we are in single input mode we need to insert a newline and reset the parsing @@ -246,11 +245,14 @@ _PyPegen_fill_token(Parser *p) // Check if we are at the limit of the token array capacity and resize if needed if ((p->fill == p->size) && (_resize_tokens_array(p) != 0)) { - return -1; + goto error; } Token *t = p->tokens[p->fill]; - return initialize_token(p, t, start, end, type); + return initialize_token(p, t, &new_token, type); +error: + _PyToken_Free(&new_token); + return -1; } #if defined(Py_DEBUG) @@ -258,11 +260,11 @@ _PyPegen_fill_token(Parser *p) // The array counts the number of tokens skipped by memoization, // indexed by type. -#define NSTATISTICS 2000 -static long memo_statistics[NSTATISTICS]; +#define NSTATISTICS _PYPEGEN_NSTATISTICS +#define memo_statistics _PyRuntime.parser.memo_statistics void -_PyPegen_clear_memo_statistics() +_PyPegen_clear_memo_statistics(void) { for (int i = 0; i < NSTATISTICS; i++) { memo_statistics[i] = 0; @@ -270,7 +272,7 @@ _PyPegen_clear_memo_statistics() } PyObject * -_PyPegen_get_memo_statistics() +_PyPegen_get_memo_statistics(void) { PyObject *ret = PyList_New(NSTATISTICS); if (ret == NULL) { @@ -371,7 +373,7 @@ _PyPegen_expect_token(Parser *p, int type) } Token *t = p->tokens[p->mark]; if (t->type != type) { - return NULL; + return NULL; } p->mark += 1; return t; @@ -655,13 +657,10 @@ _PyPegen_number_token(Parser *p) PyThreadState *tstate = _PyThreadState_GET(); // The only way a ValueError should happen in _this_ code is via // PyLong_FromString hitting a length limit. - if (tstate->curexc_type == PyExc_ValueError && - tstate->curexc_value != NULL) { - PyObject *type, *value, *tb; - // This acts as PyErr_Clear() as we're replacing curexc. - PyErr_Fetch(&type, &value, &tb); - Py_XDECREF(tb); - Py_DECREF(type); + if (tstate->current_exception != NULL && + Py_TYPE(tstate->current_exception) == (PyTypeObject *)PyExc_ValueError + ) { + PyObject *exc = PyErr_GetRaisedException(); /* Intentionally omitting columns to avoid a wall of 1000s of '^'s * on the error message. Nobody is going to overlook their huge * numeric literal once given the line. */ @@ -671,8 +670,8 @@ _PyPegen_number_token(Parser *p) t->end_lineno, -1 /* end_col_offset */, "%S - Consider hexadecimal for huge integer literals " "to avoid decimal conversion limits.", - value); - Py_DECREF(value); + exc); + Py_DECREF(exc); } return NULL; } @@ -797,6 +796,9 @@ _PyPegen_Parser_New(struct tok_state *tok, int start_rule, int flags, p->known_err_token = NULL; p->level = 0; p->call_invalid_rules = 0; +#ifdef Py_DEBUG + p->debug = _Py_GetConfig()->parser_debug; +#endif return p; } @@ -894,8 +896,7 @@ _PyPegen_run_parser_from_file_pointer(FILE *fp, int start_rule, PyObject *filena tok->fp_interactive = 1; } // This transfers the ownership to the tokenizer - tok->filename = filename_ob; - Py_INCREF(filename_ob); + tok->filename = Py_NewRef(filename_ob); // From here on we need to clean up even if there's an error mod_ty result = NULL; @@ -923,9 +924,9 @@ _PyPegen_run_parser_from_string(const char *str, int start_rule, PyObject *filen struct tok_state *tok; if (flags != NULL && flags->cf_flags & PyCF_IGNORE_COOKIE) { - tok = _PyTokenizer_FromUTF8(str, exec_input); + tok = _PyTokenizer_FromUTF8(str, exec_input, 0); } else { - tok = _PyTokenizer_FromString(str, exec_input); + tok = _PyTokenizer_FromString(str, exec_input, 0); } if (tok == NULL) { if (PyErr_Occurred()) { @@ -934,8 +935,7 @@ _PyPegen_run_parser_from_string(const char *str, int start_rule, PyObject *filen return NULL; } // This transfers the ownership to the tokenizer - tok->filename = filename_ob; - Py_INCREF(filename_ob); + tok->filename = Py_NewRef(filename_ob); // We need to clear up from here on mod_ty result = NULL; diff --git a/Parser/pegen.h b/Parser/pegen.h index fe0c327b..a8bfa786 100644 --- a/Parser/pegen.h +++ b/Parser/pegen.h @@ -3,8 +3,8 @@ #define PY_SSIZE_T_CLEAN #include <Python.h> -#include <token.h> #include <pycore_ast.h> +#include <pycore_token.h> #if 0 #define PyPARSE_YIELD_IS_KEYWORD 0x0001 @@ -39,10 +39,11 @@ typedef struct { int level; int lineno, col_offset, end_lineno, end_col_offset; Memo *memo; + PyObject *metadata; } Token; typedef struct { - char *str; + const char *str; int type; } KeywordToken; @@ -78,6 +79,7 @@ typedef struct { Token *known_err_token; int level; int call_invalid_rules; + int debug; } Parser; typedef struct { @@ -117,6 +119,11 @@ typedef struct { int is_keyword; } KeywordOrStarred; +typedef struct { + void *result; + PyObject *metadata; +} ResultTokenWithMetadata; + // Internal parser functions #if defined(Py_DEBUG) void _PyPegen_clear_memo_statistics(void); @@ -137,6 +144,7 @@ void* _PyPegen_expect_forced_result(Parser *p, void* result, const char* expecte Token *_PyPegen_expect_forced_token(Parser *p, int type, const char* expected); expr_ty _PyPegen_expect_soft_keyword(Parser *p, const char *keyword); expr_ty _PyPegen_soft_keyword_token(Parser *p); +expr_ty _PyPegen_fstring_middle_token(Parser* p); Token *_PyPegen_get_last_nonnwhitespace_token(Parser *); int _PyPegen_fill_token(Parser *p); expr_ty _PyPegen_name_token(Parser *p); @@ -154,12 +162,14 @@ typedef enum { int _Pypegen_raise_decode_error(Parser *p); void _PyPegen_raise_tokenizer_init_error(PyObject *filename); int _Pypegen_tokenizer_error(Parser *p); -void *_PyPegen_raise_error(Parser *p, PyObject *errtype, const char *errmsg, ...); +void *_PyPegen_raise_error(Parser *p, PyObject *errtype, int use_mark, const char *errmsg, ...); void *_PyPegen_raise_error_known_location(Parser *p, PyObject *errtype, Py_ssize_t lineno, Py_ssize_t col_offset, Py_ssize_t end_lineno, Py_ssize_t end_col_offset, const char *errmsg, va_list va); void _Pypegen_set_syntax_error(Parser* p, Token* last_token); +void _Pypegen_stack_overflow(Parser *p); + Py_LOCAL_INLINE(void *) RAISE_ERROR_KNOWN_LOCATION(Parser *p, PyObject *errtype, Py_ssize_t lineno, Py_ssize_t col_offset, @@ -174,8 +184,9 @@ RAISE_ERROR_KNOWN_LOCATION(Parser *p, PyObject *errtype, va_end(va); return NULL; } -#define RAISE_SYNTAX_ERROR(msg, ...) _PyPegen_raise_error(p, PyExc_SyntaxError, msg, ##__VA_ARGS__) -#define RAISE_INDENTATION_ERROR(msg, ...) _PyPegen_raise_error(p, PyExc_IndentationError, msg, ##__VA_ARGS__) +#define RAISE_SYNTAX_ERROR(msg, ...) _PyPegen_raise_error(p, PyExc_SyntaxError, 0, msg, ##__VA_ARGS__) +#define RAISE_INDENTATION_ERROR(msg, ...) _PyPegen_raise_error(p, PyExc_IndentationError, 0, msg, ##__VA_ARGS__) +#define RAISE_SYNTAX_ERROR_ON_NEXT_TOKEN(msg, ...) _PyPegen_raise_error(p, PyExc_SyntaxError, 1, msg, ##__VA_ARGS__) #define RAISE_SYNTAX_ERROR_KNOWN_RANGE(a, b, msg, ...) \ RAISE_ERROR_KNOWN_LOCATION(p, PyExc_SyntaxError, (a)->lineno, (a)->col_offset, (b)->end_lineno, (b)->end_col_offset, msg, ##__VA_ARGS__) #define RAISE_SYNTAX_ERROR_KNOWN_LOCATION(a, msg, ...) \ @@ -307,6 +318,8 @@ StarEtc *_PyPegen_star_etc(Parser *, arg_ty, asdl_seq *, arg_ty); arguments_ty _PyPegen_make_arguments(Parser *, asdl_arg_seq *, SlashWithDefault *, asdl_arg_seq *, asdl_seq *, StarEtc *); arguments_ty _PyPegen_empty_arguments(Parser *); +expr_ty _PyPegen_formatted_value(Parser *, expr_ty, Token *, ResultTokenWithMetadata *, ResultTokenWithMetadata *, Token *, + int, int, int, int, PyArena *); AugOperator *_PyPegen_augoperator(Parser*, operator_ty type); stmt_ty _PyPegen_function_def_decorators(Parser *, asdl_expr_seq *, stmt_ty); stmt_ty _PyPegen_class_def_decorators(Parser *, asdl_expr_seq *, stmt_ty); @@ -316,12 +329,19 @@ asdl_keyword_seq *_PyPegen_seq_delete_starred_exprs(Parser *, asdl_seq *); expr_ty _PyPegen_collect_call_seqs(Parser *, asdl_expr_seq *, asdl_seq *, int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena); -expr_ty _PyPegen_concatenate_strings(Parser *p, asdl_seq *); +expr_ty _PyPegen_constant_from_token(Parser* p, Token* tok); +expr_ty _PyPegen_decoded_constant_from_token(Parser* p, Token* tok); +expr_ty _PyPegen_constant_from_string(Parser* p, Token* tok); +expr_ty _PyPegen_concatenate_strings(Parser *p, asdl_expr_seq *, int, int, int, int, PyArena *); +expr_ty _PyPegen_FetchRawForm(Parser *p, int, int, int, int); expr_ty _PyPegen_ensure_imaginary(Parser *p, expr_ty); expr_ty _PyPegen_ensure_real(Parser *p, expr_ty); asdl_seq *_PyPegen_join_sequences(Parser *, asdl_seq *, asdl_seq *); int _PyPegen_check_barry_as_flufl(Parser *, Token *); int _PyPegen_check_legacy_stmt(Parser *p, expr_ty t); +ResultTokenWithMetadata *_PyPegen_check_fstring_conversion(Parser *p, Token *, expr_ty t); +ResultTokenWithMetadata *_PyPegen_setup_full_format_spec(Parser *, Token *, asdl_expr_seq *, int, int, + int, int, PyArena *); mod_ty _PyPegen_make_module(Parser *, asdl_stmt_seq *); void *_PyPegen_arguments_parsing_error(Parser *, expr_ty); expr_ty _PyPegen_get_last_comprehension_item(comprehension_ty comprehension); @@ -337,6 +357,9 @@ void *_PyPegen_run_parser(Parser *); mod_ty _PyPegen_run_parser_from_string(const char *, int, PyObject *, PyCompilerFlags *, PyArena *); asdl_stmt_seq *_PyPegen_interactive_exit(Parser *); +// TODO: move to the correct place in this file +expr_ty _PyPegen_joined_str(Parser *p, Token* a, asdl_expr_seq* expr, Token*b); + // Generated function in parse.c - function definition in python.gram void *_PyPegen_parse(Parser *); diff --git a/Parser/pegen_errors.c b/Parser/pegen_errors.c index 3d8cccb0..b2fca019 100644 --- a/Parser/pegen_errors.c +++ b/Parser/pegen_errors.c @@ -164,11 +164,11 @@ _PyPegen_tokenize_full_source_to_check_for_errors(Parser *p) { Py_ssize_t current_err_line = current_token->lineno; int ret = 0; + struct token new_token; + _PyToken_Init(&new_token); for (;;) { - const char *start; - const char *end; - switch (_PyTokenizer_Get(p->tok, &start, &end)) { + switch (_PyTokenizer_Get(p->tok, &new_token)) { case ERRORTOKEN: if (PyErr_Occurred()) { ret = -1; @@ -193,7 +193,11 @@ _PyPegen_tokenize_full_source_to_check_for_errors(Parser *p) { exit: - if (PyErr_Occurred()) { + _PyToken_Free(&new_token); + // If we're in an f-string, we want the syntax error in the expression part + // to propagate, so that tokenizer errors (like expecting '}') that happen afterwards + // do not swallow it. + if (PyErr_Occurred() && p->tok->tok_mode_stack_index <= 0) { Py_XDECREF(value); Py_XDECREF(type); Py_XDECREF(traceback); @@ -206,7 +210,7 @@ exit: // PARSER ERRORS void * -_PyPegen_raise_error(Parser *p, PyObject *errtype, const char *errmsg, ...) +_PyPegen_raise_error(Parser *p, PyObject *errtype, int use_mark, const char *errmsg, ...) { if (p->fill == 0) { va_list va; @@ -215,8 +219,13 @@ _PyPegen_raise_error(Parser *p, PyObject *errtype, const char *errmsg, ...) va_end(va); return NULL; } - - Token *t = p->known_err_token != NULL ? p->known_err_token : p->tokens[p->fill - 1]; + if (use_mark && p->mark == p->fill && _PyPegen_fill_token(p) < 0) { + p->error_indicator = 1; + return NULL; + } + Token *t = p->known_err_token != NULL + ? p->known_err_token + : p->tokens[use_mark ? p->mark : p->fill - 1]; Py_ssize_t col_offset; Py_ssize_t end_col_offset = -1; if (t->col_offset == -1) { @@ -249,7 +258,7 @@ get_error_line_from_tokenizer_buffers(Parser *p, Py_ssize_t lineno) * (multi-line) statement are stored in p->tok->interactive_src_start. * If not, we're parsing from a string, which means that the whole source * is stored in p->tok->str. */ - assert((p->tok->fp == NULL && p->tok->str != NULL) || p->tok->fp == stdin); + assert((p->tok->fp == NULL && p->tok->str != NULL) || p->tok->fp != NULL); char *cur_line = p->tok->fp_interactive ? p->tok->interactive_src_start : p->tok->str; if (cur_line == NULL) { @@ -444,3 +453,11 @@ _Pypegen_set_syntax_error(Parser* p, Token* last_token) { // generic SyntaxError we just raised if errors are found. _PyPegen_tokenize_full_source_to_check_for_errors(p); } + +void +_Pypegen_stack_overflow(Parser *p) +{ + p->error_indicator = 1; + PyErr_SetString(PyExc_MemoryError, + "Parser stack overflowed - Python source too complex to parse"); +} diff --git a/Parser/string_parser.c b/Parser/string_parser.c index 4f3f0466..20459e89 100644 --- a/Parser/string_parser.c +++ b/Parser/string_parser.c @@ -12,6 +12,11 @@ static int warn_invalid_escape_sequence(Parser *p, const char *first_invalid_escape, Token *t) { unsigned char c = *first_invalid_escape; + if ((t->type == FSTRING_MIDDLE || t->type == FSTRING_END) && (c == '{' || c == '}')) { // in this case the tokenizer has already emitted a warning, + // see tokenizer.c:warn_invalid_escape_sequence + return 0; + } + int octal = ('4' <= c && c <= '7'); PyObject *msg = octal @@ -21,10 +26,17 @@ warn_invalid_escape_sequence(Parser *p, const char *first_invalid_escape, Token if (msg == NULL) { return -1; } - if (PyErr_WarnExplicitObject(PyExc_DeprecationWarning, msg, p->tok->filename, + PyObject *category; + if (p->feature_version >= 12) { + category = PyExc_SyntaxWarning; + } + else { + category = PyExc_DeprecationWarning; + } + if (PyErr_WarnExplicitObject(category, msg, p->tok->filename, t->lineno, NULL, NULL) < 0) { - if (PyErr_ExceptionMatches(PyExc_DeprecationWarning)) { - /* Replace the DeprecationWarning exception with a SyntaxError + if (PyErr_ExceptionMatches(category)) { + /* Replace the Syntax/DeprecationWarning exception with a SyntaxError to get a more accurate error report */ PyErr_Clear(); @@ -128,7 +140,9 @@ decode_unicode_with_escapes(Parser *parser, const char *s, size_t len, Token *t) const char *first_invalid_escape; v = _PyUnicode_DecodeUnicodeEscapeInternal(s, len, NULL, NULL, &first_invalid_escape); - if (v != NULL && first_invalid_escape != NULL) { + // HACK: later we can simply pass the line no, since we don't preserve the tokens + // when we are decoding the string but we preserve the line numbers. + if (v != NULL && first_invalid_escape != NULL && t != NULL) { if (warn_invalid_escape_sequence(parser, first_invalid_escape, t) < 0) { /* We have not decref u before because first_invalid_escape points inside u. */ @@ -159,43 +173,43 @@ decode_bytes_with_escapes(Parser *p, const char *s, Py_ssize_t len, Token *t) return result; } -/* s must include the bracketing quote characters, and r, b, u, - &/or f prefixes (if any), and embedded escape sequences (if any). - _PyPegen_parsestr parses it, and sets *result to decoded Python string object. - If the string is an f-string, set *fstr and *fstrlen to the unparsed - string object. Return 0 if no errors occurred. */ -int -_PyPegen_parsestr(Parser *p, int *bytesmode, int *rawmode, PyObject **result, - const char **fstr, Py_ssize_t *fstrlen, Token *t) +PyObject * +_PyPegen_decode_string(Parser *p, int raw, const char *s, size_t len, Token *t) +{ + if (raw) { + return PyUnicode_DecodeUTF8Stateful(s, len, NULL, NULL); + } + return decode_unicode_with_escapes(p, s, len, t); +} + +/* s must include the bracketing quote characters, and r, b &/or f prefixes + (if any), and embedded escape sequences (if any). (f-strings are handled by the parser) + _PyPegen_parse_string parses it, and returns the decoded Python string object. */ +PyObject * +_PyPegen_parse_string(Parser *p, Token *t) { const char *s = PyBytes_AsString(t->bytes); if (s == NULL) { - return -1; + return NULL; } size_t len; int quote = Py_CHARMASK(*s); - int fmode = 0; - *bytesmode = 0; - *rawmode = 0; - *result = NULL; - *fstr = NULL; + int bytesmode = 0; + int rawmode = 0; + if (Py_ISALPHA(quote)) { - while (!*bytesmode || !*rawmode) { + while (!bytesmode || !rawmode) { if (quote == 'b' || quote == 'B') { quote =(unsigned char)*++s; - *bytesmode = 1; + bytesmode = 1; } else if (quote == 'u' || quote == 'U') { quote = (unsigned char)*++s; } else if (quote == 'r' || quote == 'R') { quote = (unsigned char)*++s; - *rawmode = 1; - } - else if (quote == 'f' || quote == 'F') { - quote = (unsigned char)*++s; - fmode = 1; + rawmode = 1; } else { break; @@ -203,32 +217,21 @@ _PyPegen_parsestr(Parser *p, int *bytesmode, int *rawmode, PyObject **result, } } - /* fstrings are only allowed in Python 3.6 and greater */ - if (fmode && p->feature_version < 6) { - p->error_indicator = 1; - RAISE_SYNTAX_ERROR("Format strings are only supported in Python 3.6 and greater"); - return -1; - } - - if (fmode && *bytesmode) { - PyErr_BadInternalCall(); - return -1; - } if (quote != '\'' && quote != '\"') { PyErr_BadInternalCall(); - return -1; + return NULL; } /* Skip the leading quote char. */ s++; len = strlen(s); if (len > INT_MAX) { PyErr_SetString(PyExc_OverflowError, "string to parse is too long"); - return -1; + return NULL; } if (s[--len] != quote) { /* Last quote char must match the first. */ PyErr_BadInternalCall(); - return -1; + return NULL; } if (len >= 4 && s[0] == quote && s[1] == quote) { /* A triple quoted string. We've already skipped one quote at @@ -239,1023 +242,28 @@ _PyPegen_parsestr(Parser *p, int *bytesmode, int *rawmode, PyObject **result, /* And check that the last two match. */ if (s[--len] != quote || s[--len] != quote) { PyErr_BadInternalCall(); - return -1; + return NULL; } } - if (fmode) { - /* Just return the bytes. The caller will parse the resulting - string. */ - *fstr = s; - *fstrlen = len; - return 0; - } - - /* Not an f-string. */ /* Avoid invoking escape decoding routines if possible. */ - *rawmode = *rawmode || strchr(s, '\\') == NULL; - if (*bytesmode) { + rawmode = rawmode || strchr(s, '\\') == NULL; + if (bytesmode) { /* Disallow non-ASCII characters. */ const char *ch; for (ch = s; *ch; ch++) { if (Py_CHARMASK(*ch) >= 0x80) { - RAISE_SYNTAX_ERROR( + RAISE_SYNTAX_ERROR_KNOWN_LOCATION( + t, "bytes can only contain ASCII " "literal characters"); - return -1; - } - } - if (*rawmode) { - *result = PyBytes_FromStringAndSize(s, len); - } - else { - *result = decode_bytes_with_escapes(p, s, len, t); - } - } - else { - if (*rawmode) { - *result = PyUnicode_DecodeUTF8Stateful(s, len, NULL, NULL); - } - else { - *result = decode_unicode_with_escapes(p, s, len, t); - } - } - return *result == NULL ? -1 : 0; -} - - - -// FSTRING STUFF - -/* Fix locations for the given node and its children. - - `parent` is the enclosing node. - `expr_start` is the starting position of the expression (pointing to the open brace). - `n` is the node which locations are going to be fixed relative to parent. - `expr_str` is the child node's string representation, including braces. -*/ -static bool -fstring_find_expr_location(Token *parent, const char* expr_start, char *expr_str, int *p_lines, int *p_cols) -{ - *p_lines = 0; - *p_cols = 0; - assert(expr_start != NULL && *expr_start == '{'); - if (parent && parent->bytes) { - const char *parent_str = PyBytes_AsString(parent->bytes); - if (!parent_str) { - return false; - } - // The following is needed, in order to correctly shift the column - // offset, in the case that (disregarding any whitespace) a newline - // immediately follows the opening curly brace of the fstring expression. - bool newline_after_brace = 1; - const char *start = expr_start + 1; - while (start && *start != '}' && *start != '\n') { - if (*start != ' ' && *start != '\t' && *start != '\f') { - newline_after_brace = 0; - break; - } - start++; - } - - // Account for the characters from the last newline character to our - // left until the beginning of expr_start. - if (!newline_after_brace) { - start = expr_start; - while (start > parent_str && *start != '\n') { - start--; - } - *p_cols += (int)(expr_start - start); - if (*start == '\n') { - *p_cols -= 1; - } - } - /* adjust the start based on the number of newlines encountered - before the f-string expression */ - for (const char *p = parent_str; p < expr_start; p++) { - if (*p == '\n') { - (*p_lines)++; - } - } - } - return true; -} - - -/* Compile this expression in to an expr_ty. Add parens around the - expression, in order to allow leading spaces in the expression. */ -static expr_ty -fstring_compile_expr(Parser *p, const char *expr_start, const char *expr_end, - Token *t) -{ - expr_ty expr = NULL; - char *str; - Py_ssize_t len; - const char *s; - expr_ty result = NULL; - - assert(expr_end >= expr_start); - assert(*(expr_start-1) == '{'); - assert(*expr_end == '}' || *expr_end == '!' || *expr_end == ':' || - *expr_end == '='); - - /* If the substring is all whitespace, it's an error. We need to catch this - here, and not when we call PyParser_SimpleParseStringFlagsFilename, - because turning the expression '' in to '()' would go from being invalid - to valid. */ - for (s = expr_start; s != expr_end; s++) { - char c = *s; - /* The Python parser ignores only the following whitespace - characters (\r already is converted to \n). */ - if (!(c == ' ' || c == '\t' || c == '\n' || c == '\f')) { - break; - } - } - - if (s == expr_end) { - if (*expr_end == '!' || *expr_end == ':' || *expr_end == '=') { - RAISE_SYNTAX_ERROR("f-string: expression required before '%c'", *expr_end); - return NULL; - } - RAISE_SYNTAX_ERROR("f-string: empty expression not allowed"); - return NULL; - } - - len = expr_end - expr_start; - /* Allocate 3 extra bytes: open paren, close paren, null byte. */ - str = PyMem_Calloc(len + 3, sizeof(char)); - if (str == NULL) { - PyErr_NoMemory(); - return NULL; - } - - // The call to fstring_find_expr_location is responsible for finding the column offset - // the generated AST nodes need to be shifted to the right, which is equal to the number - // of the f-string characters before the expression starts. - memcpy(str+1, expr_start, len); - int lines, cols; - if (!fstring_find_expr_location(t, expr_start-1, str+1, &lines, &cols)) { - PyMem_Free(str); - return NULL; - } - - // The parentheses are needed in order to allow for leading whitespace within - // the f-string expression. This consequently gets parsed as a group (see the - // group rule in python.gram). - str[0] = '('; - str[len+1] = ')'; - - struct tok_state* tok = _PyTokenizer_FromString(str, 1); - if (tok == NULL) { - PyMem_Free(str); - return NULL; - } - Py_INCREF(p->tok->filename); - - tok->filename = p->tok->filename; - tok->lineno = t->lineno + lines - 1; - - Parser *p2 = _PyPegen_Parser_New(tok, Py_fstring_input, p->flags, p->feature_version, - NULL, p->arena); - - p2->starting_lineno = t->lineno + lines; - p2->starting_col_offset = lines != 0 ? cols : t->col_offset + cols; - - expr = _PyPegen_run_parser(p2); - - if (expr == NULL) { - goto exit; - } - result = expr; - -exit: - PyMem_Free(str); - _PyPegen_Parser_Free(p2); - _PyTokenizer_Free(tok); - return result; -} - -/* Return -1 on error. - - Return 0 if we reached the end of the literal. - - Return 1 if we haven't reached the end of the literal, but we want - the caller to process the literal up to this point. Used for - doubled braces. -*/ -static int -fstring_find_literal(Parser *p, const char **str, const char *end, int raw, - PyObject **literal, int recurse_lvl, Token *t) -{ - /* Get any literal string. It ends when we hit an un-doubled left - brace (which isn't part of a unicode name escape such as - "\N{EULER CONSTANT}"), or the end of the string. */ - - const char *s = *str; - const char *literal_start = s; - int result = 0; - - assert(*literal == NULL); - while (s < end) { - char ch = *s++; - if (!raw && ch == '\\' && s < end) { - ch = *s++; - if (ch == 'N') { - /* We need to look at and skip matching braces for "\N{name}" - sequences because otherwise we'll think the opening '{' - starts an expression, which is not the case with "\N". - Keep looking for either a matched '{' '}' pair, or the end - of the string. */ - - if (s < end && *s++ == '{') { - while (s < end && *s++ != '}') { - } - continue; - } - - /* This is an invalid "\N" sequence, since it's a "\N" not - followed by a "{". Just keep parsing this literal. This - error will be caught later by - decode_unicode_with_escapes(). */ - continue; - } - if (ch == '{' && warn_invalid_escape_sequence(p, s-1, t) < 0) { - return -1; - } - } - if (ch == '{' || ch == '}') { - /* Check for doubled braces, but only at the top level. If - we checked at every level, then f'{0:{3}}' would fail - with the two closing braces. */ - if (recurse_lvl == 0) { - if (s < end && *s == ch) { - /* We're going to tell the caller that the literal ends - here, but that they should continue scanning. But also - skip over the second brace when we resume scanning. */ - *str = s + 1; - result = 1; - goto done; - } - - /* Where a single '{' is the start of a new expression, a - single '}' is not allowed. */ - if (ch == '}') { - *str = s - 1; - RAISE_SYNTAX_ERROR("f-string: single '}' is not allowed"); - return -1; - } - } - /* We're either at a '{', which means we're starting another - expression; or a '}', which means we're at the end of this - f-string (for a nested format_spec). */ - s--; - break; - } - } - *str = s; - assert(s <= end); - assert(s == end || *s == '{' || *s == '}'); -done: - if (literal_start != s) { - if (raw) { - *literal = PyUnicode_DecodeUTF8Stateful(literal_start, - s - literal_start, - NULL, NULL); - } - else { - *literal = decode_unicode_with_escapes(p, literal_start, - s - literal_start, t); - } - if (!*literal) { - return -1; - } - } - return result; -} - -/* Forward declaration because parsing is recursive. */ -static expr_ty -fstring_parse(Parser *p, const char **str, const char *end, int raw, int recurse_lvl, - Token *first_token, Token* t, Token *last_token); - -/* Parse the f-string at *str, ending at end. We know *str starts an - expression (so it must be a '{'). Returns the FormattedValue node, which - includes the expression, conversion character, format_spec expression, and - optionally the text of the expression (if = is used). - - Note that I don't do a perfect job here: I don't make sure that a - closing brace doesn't match an opening paren, for example. It - doesn't need to error on all invalid expressions, just correctly - find the end of all valid ones. Any errors inside the expression - will be caught when we parse it later. - - *expression is set to the expression. For an '=' "debug" expression, - *expr_text is set to the debug text (the original text of the expression, - including the '=' and any whitespace around it, as a string object). If - not a debug expression, *expr_text set to NULL. */ -static int -fstring_find_expr(Parser *p, const char **str, const char *end, int raw, int recurse_lvl, - PyObject **expr_text, expr_ty *expression, Token *first_token, - Token *t, Token *last_token) -{ - /* Return -1 on error, else 0. */ - - const char *expr_start; - const char *expr_end; - expr_ty simple_expression; - expr_ty format_spec = NULL; /* Optional format specifier. */ - int conversion = -1; /* The conversion char. Use default if not - specified, or !r if using = and no format - spec. */ - - /* 0 if we're not in a string, else the quote char we're trying to - match (single or double quote). */ - char quote_char = 0; - - /* If we're inside a string, 1=normal, 3=triple-quoted. */ - int string_type = 0; - - /* Keep track of nesting level for braces/parens/brackets in - expressions. */ - Py_ssize_t nested_depth = 0; - char parenstack[MAXLEVEL]; - - *expr_text = NULL; - - /* Can only nest one level deep. */ - if (recurse_lvl >= 2) { - RAISE_SYNTAX_ERROR("f-string: expressions nested too deeply"); - goto error; - } - - /* The first char must be a left brace, or we wouldn't have gotten - here. Skip over it. */ - assert(**str == '{'); - *str += 1; - - expr_start = *str; - for (; *str < end; (*str)++) { - char ch; - - /* Loop invariants. */ - assert(nested_depth >= 0); - assert(*str >= expr_start && *str < end); - if (quote_char) { - assert(string_type == 1 || string_type == 3); - } else { - assert(string_type == 0); - } - - ch = **str; - /* Nowhere inside an expression is a backslash allowed. */ - if (ch == '\\') { - /* Error: can't include a backslash character, inside - parens or strings or not. */ - RAISE_SYNTAX_ERROR( - "f-string expression part " - "cannot include a backslash"); - goto error; - } - if (quote_char) { - /* We're inside a string. See if we're at the end. */ - /* This code needs to implement the same non-error logic - as tok_get from tokenizer.c, at the letter_quote - label. To actually share that code would be a - nightmare. But, it's unlikely to change and is small, - so duplicate it here. Note we don't need to catch all - of the errors, since they'll be caught when parsing the - expression. We just need to match the non-error - cases. Thus we can ignore \n in single-quoted strings, - for example. Or non-terminated strings. */ - if (ch == quote_char) { - /* Does this match the string_type (single or triple - quoted)? */ - if (string_type == 3) { - if (*str+2 < end && *(*str+1) == ch && *(*str+2) == ch) { - /* We're at the end of a triple quoted string. */ - *str += 2; - string_type = 0; - quote_char = 0; - continue; - } - } else { - /* We're at the end of a normal string. */ - quote_char = 0; - string_type = 0; - continue; - } - } - } else if (ch == '\'' || ch == '"') { - /* Is this a triple quoted string? */ - if (*str+2 < end && *(*str+1) == ch && *(*str+2) == ch) { - string_type = 3; - *str += 2; - } else { - /* Start of a normal string. */ - string_type = 1; - } - /* Start looking for the end of the string. */ - quote_char = ch; - } else if (ch == '[' || ch == '{' || ch == '(') { - if (nested_depth >= MAXLEVEL) { - RAISE_SYNTAX_ERROR("f-string: too many nested parenthesis"); - goto error; - } - parenstack[nested_depth] = ch; - nested_depth++; - } else if (ch == '#') { - /* Error: can't include a comment character, inside parens - or not. */ - RAISE_SYNTAX_ERROR("f-string expression part cannot include '#'"); - goto error; - } else if (nested_depth == 0 && - (ch == '!' || ch == ':' || ch == '}' || - ch == '=' || ch == '>' || ch == '<')) { - /* See if there's a next character. */ - if (*str+1 < end) { - char next = *(*str+1); - - /* For "!=". since '=' is not an allowed conversion character, - nothing is lost in this test. */ - if ((ch == '!' && next == '=') || /* != */ - (ch == '=' && next == '=') || /* == */ - (ch == '<' && next == '=') || /* <= */ - (ch == '>' && next == '=') /* >= */ - ) { - *str += 1; - continue; - } - } - /* Don't get out of the loop for these, if they're single - chars (not part of 2-char tokens). If by themselves, they - don't end an expression (unlike say '!'). */ - if (ch == '>' || ch == '<') { - continue; - } - - /* Normal way out of this loop. */ - break; - } else if (ch == ']' || ch == '}' || ch == ')') { - if (!nested_depth) { - RAISE_SYNTAX_ERROR("f-string: unmatched '%c'", ch); - goto error; - } - nested_depth--; - int opening = (unsigned char)parenstack[nested_depth]; - if (!((opening == '(' && ch == ')') || - (opening == '[' && ch == ']') || - (opening == '{' && ch == '}'))) - { - RAISE_SYNTAX_ERROR( - "f-string: closing parenthesis '%c' " - "does not match opening parenthesis '%c'", - ch, opening); - goto error; - } - } else { - /* Just consume this char and loop around. */ - } - } - expr_end = *str; - /* If we leave the above loop in a string or with mismatched parens, we - don't really care. We'll get a syntax error when compiling the - expression. But, we can produce a better error message, so let's just - do that.*/ - if (quote_char) { - RAISE_SYNTAX_ERROR("f-string: unterminated string"); - goto error; - } - if (nested_depth) { - int opening = (unsigned char)parenstack[nested_depth - 1]; - RAISE_SYNTAX_ERROR("f-string: unmatched '%c'", opening); - goto error; - } - - if (*str >= end) { - goto unexpected_end_of_string; - } - - /* Compile the expression as soon as possible, so we show errors - related to the expression before errors related to the - conversion or format_spec. */ - simple_expression = fstring_compile_expr(p, expr_start, expr_end, t); - if (!simple_expression) { - goto error; - } - - /* Check for =, which puts the text value of the expression in - expr_text. */ - if (**str == '=') { - if (p->feature_version < 8) { - RAISE_SYNTAX_ERROR("f-string: self documenting expressions are " - "only supported in Python 3.8 and greater"); - goto error; - } - *str += 1; - - /* Skip over ASCII whitespace. No need to test for end of string - here, since we know there's at least a trailing quote somewhere - ahead. */ - while (Py_ISSPACE(**str)) { - *str += 1; - } - if (*str >= end) { - goto unexpected_end_of_string; - } - /* Set *expr_text to the text of the expression. */ - *expr_text = PyUnicode_FromStringAndSize(expr_start, *str-expr_start); - if (!*expr_text) { - goto error; - } - } - - /* Check for a conversion char, if present. */ - if (**str == '!') { - *str += 1; - if (*str >= end) { - goto unexpected_end_of_string; - } - - conversion = (unsigned char)**str; - *str += 1; - - /* Validate the conversion. */ - if (!(conversion == 's' || conversion == 'r' || conversion == 'a')) { - RAISE_SYNTAX_ERROR( - "f-string: invalid conversion character: " - "expected 's', 'r', or 'a'"); - goto error; - } - - } - - /* Check for the format spec, if present. */ - if (*str >= end) { - goto unexpected_end_of_string; - } - if (**str == ':') { - *str += 1; - if (*str >= end) { - goto unexpected_end_of_string; - } - - /* Parse the format spec. */ - format_spec = fstring_parse(p, str, end, raw, recurse_lvl+1, - first_token, t, last_token); - if (!format_spec) { - goto error; - } - } - - if (*str >= end || **str != '}') { - goto unexpected_end_of_string; - } - - /* We're at a right brace. Consume it. */ - assert(*str < end); - assert(**str == '}'); - *str += 1; - - /* If we're in = mode (detected by non-NULL expr_text), and have no format - spec and no explicit conversion, set the conversion to 'r'. */ - if (*expr_text && format_spec == NULL && conversion == -1) { - conversion = 'r'; - } - - /* And now create the FormattedValue node that represents this - entire expression with the conversion and format spec. */ - //TODO: Fix this - *expression = _PyAST_FormattedValue(simple_expression, conversion, - format_spec, first_token->lineno, - first_token->col_offset, - last_token->end_lineno, - last_token->end_col_offset, p->arena); - if (!*expression) { - goto error; - } - - return 0; - -unexpected_end_of_string: - RAISE_SYNTAX_ERROR("f-string: expecting '}'"); - /* Falls through to error. */ - -error: - Py_XDECREF(*expr_text); - return -1; - -} - -/* Return -1 on error. - - Return 0 if we have a literal (possible zero length) and an - expression (zero length if at the end of the string. - - Return 1 if we have a literal, but no expression, and we want the - caller to call us again. This is used to deal with doubled - braces. - - When called multiple times on the string 'a{{b{0}c', this function - will return: - - 1. the literal 'a{' with no expression, and a return value - of 1. Despite the fact that there's no expression, the return - value of 1 means we're not finished yet. - - 2. the literal 'b' and the expression '0', with a return value of - 0. The fact that there's an expression means we're not finished. - - 3. literal 'c' with no expression and a return value of 0. The - combination of the return value of 0 with no expression means - we're finished. -*/ -static int -fstring_find_literal_and_expr(Parser *p, const char **str, const char *end, int raw, - int recurse_lvl, PyObject **literal, - PyObject **expr_text, expr_ty *expression, - Token *first_token, Token *t, Token *last_token) -{ - int result; - - assert(*literal == NULL && *expression == NULL); - - /* Get any literal string. */ - result = fstring_find_literal(p, str, end, raw, literal, recurse_lvl, t); - if (result < 0) { - goto error; - } - - assert(result == 0 || result == 1); - - if (result == 1) { - /* We have a literal, but don't look at the expression. */ - return 1; - } - - if (*str >= end || **str == '}') { - /* We're at the end of the string or the end of a nested - f-string: no expression. The top-level error case where we - expect to be at the end of the string but we're at a '}' is - handled later. */ - return 0; - } - - /* We must now be the start of an expression, on a '{'. */ - assert(**str == '{'); - - if (fstring_find_expr(p, str, end, raw, recurse_lvl, expr_text, - expression, first_token, t, last_token) < 0) { - goto error; - } - - return 0; - -error: - Py_CLEAR(*literal); - return -1; -} - -#ifdef NDEBUG -#define ExprList_check_invariants(l) -#else -static void -ExprList_check_invariants(ExprList *l) -{ - /* Check our invariants. Make sure this object is "live", and - hasn't been deallocated. */ - assert(l->size >= 0); - assert(l->p != NULL); - if (l->size <= EXPRLIST_N_CACHED) { - assert(l->data == l->p); - } -} -#endif - -static void -ExprList_Init(ExprList *l) -{ - l->allocated = EXPRLIST_N_CACHED; - l->size = 0; - - /* Until we start allocating dynamically, p points to data. */ - l->p = l->data; - - ExprList_check_invariants(l); -} - -static int -ExprList_Append(ExprList *l, expr_ty exp) -{ - ExprList_check_invariants(l); - if (l->size >= l->allocated) { - /* We need to alloc (or realloc) the memory. */ - Py_ssize_t new_size = l->allocated * 2; - - /* See if we've ever allocated anything dynamically. */ - if (l->p == l->data) { - Py_ssize_t i; - /* We're still using the cached data. Switch to - alloc-ing. */ - l->p = PyMem_Malloc(sizeof(expr_ty) * new_size); - if (!l->p) { - return -1; - } - /* Copy the cached data into the new buffer. */ - for (i = 0; i < l->size; i++) { - l->p[i] = l->data[i]; - } - } else { - /* Just realloc. */ - expr_ty *tmp = PyMem_Realloc(l->p, sizeof(expr_ty) * new_size); - if (!tmp) { - PyMem_Free(l->p); - l->p = NULL; - return -1; - } - l->p = tmp; - } - - l->allocated = new_size; - assert(l->allocated == 2 * l->size); - } - - l->p[l->size++] = exp; - - ExprList_check_invariants(l); - return 0; -} - -static void -ExprList_Dealloc(ExprList *l) -{ - ExprList_check_invariants(l); - - /* If there's been an error, or we've never dynamically allocated, - do nothing. */ - if (!l->p || l->p == l->data) { - /* Do nothing. */ - } else { - /* We have dynamically allocated. Free the memory. */ - PyMem_Free(l->p); - } - l->p = NULL; - l->size = -1; -} - -static asdl_expr_seq * -ExprList_Finish(ExprList *l, PyArena *arena) -{ - asdl_expr_seq *seq; - - ExprList_check_invariants(l); - - /* Allocate the asdl_seq and copy the expressions in to it. */ - seq = _Py_asdl_expr_seq_new(l->size, arena); - if (seq) { - Py_ssize_t i; - for (i = 0; i < l->size; i++) { - asdl_seq_SET(seq, i, l->p[i]); - } - } - ExprList_Dealloc(l); - return seq; -} - -#ifdef NDEBUG -#define FstringParser_check_invariants(state) -#else -static void -FstringParser_check_invariants(FstringParser *state) -{ - if (state->last_str) { - assert(PyUnicode_CheckExact(state->last_str)); - } - ExprList_check_invariants(&state->expr_list); -} -#endif - -void -_PyPegen_FstringParser_Init(FstringParser *state) -{ - state->last_str = NULL; - state->fmode = 0; - ExprList_Init(&state->expr_list); - FstringParser_check_invariants(state); -} - -void -_PyPegen_FstringParser_Dealloc(FstringParser *state) -{ - FstringParser_check_invariants(state); - - Py_XDECREF(state->last_str); - ExprList_Dealloc(&state->expr_list); -} - -/* Make a Constant node, but decref the PyUnicode object being added. */ -static expr_ty -make_str_node_and_del(Parser *p, PyObject **str, Token* first_token, Token *last_token) -{ - PyObject *s = *str; - PyObject *kind = NULL; - *str = NULL; - assert(PyUnicode_CheckExact(s)); - if (_PyArena_AddPyObject(p->arena, s) < 0) { - Py_DECREF(s); - return NULL; - } - const char* the_str = PyBytes_AsString(first_token->bytes); - if (the_str && the_str[0] == 'u') { - kind = _PyPegen_new_identifier(p, "u"); - } - - if (kind == NULL && PyErr_Occurred()) { - return NULL; - } - - return _PyAST_Constant(s, kind, first_token->lineno, first_token->col_offset, - last_token->end_lineno, last_token->end_col_offset, - p->arena); - -} - - -/* Add a non-f-string (that is, a regular literal string). str is - decref'd. */ -int -_PyPegen_FstringParser_ConcatAndDel(FstringParser *state, PyObject *str) -{ - FstringParser_check_invariants(state); - - assert(PyUnicode_CheckExact(str)); - - if (PyUnicode_GET_LENGTH(str) == 0) { - Py_DECREF(str); - return 0; - } - - if (!state->last_str) { - /* We didn't have a string before, so just remember this one. */ - state->last_str = str; - } else { - /* Concatenate this with the previous string. */ - PyUnicode_AppendAndDel(&state->last_str, str); - if (!state->last_str) { - return -1; - } - } - FstringParser_check_invariants(state); - return 0; -} - -/* Parse an f-string. The f-string is in *str to end, with no - 'f' or quotes. */ -int -_PyPegen_FstringParser_ConcatFstring(Parser *p, FstringParser *state, const char **str, - const char *end, int raw, int recurse_lvl, - Token *first_token, Token* t, Token *last_token) -{ - FstringParser_check_invariants(state); - state->fmode = 1; - - /* Parse the f-string. */ - while (1) { - PyObject *literal = NULL; - PyObject *expr_text = NULL; - expr_ty expression = NULL; - - /* If there's a zero length literal in front of the - expression, literal will be NULL. If we're at the end of - the f-string, expression will be NULL (unless result == 1, - see below). */ - int result = fstring_find_literal_and_expr(p, str, end, raw, recurse_lvl, - &literal, &expr_text, - &expression, first_token, t, last_token); - if (result < 0) { - return -1; - } - - /* Add the literal, if any. */ - if (literal && _PyPegen_FstringParser_ConcatAndDel(state, literal) < 0) { - Py_XDECREF(expr_text); - return -1; - } - /* Add the expr_text, if any. */ - if (expr_text && _PyPegen_FstringParser_ConcatAndDel(state, expr_text) < 0) { - return -1; - } - - /* We've dealt with the literal and expr_text, their ownership has - been transferred to the state object. Don't look at them again. */ - - /* See if we should just loop around to get the next literal - and expression, while ignoring the expression this - time. This is used for un-doubling braces, as an - optimization. */ - if (result == 1) { - continue; - } - - if (!expression) { - /* We're done with this f-string. */ - break; - } - - /* We know we have an expression. Convert any existing string - to a Constant node. */ - if (state->last_str) { - /* Convert the existing last_str literal to a Constant node. */ - expr_ty last_str = make_str_node_and_del(p, &state->last_str, first_token, last_token); - if (!last_str || ExprList_Append(&state->expr_list, last_str) < 0) { - return -1; - } - } - - if (ExprList_Append(&state->expr_list, expression) < 0) { - return -1; - } - } - - /* If recurse_lvl is zero, then we must be at the end of the - string. Otherwise, we must be at a right brace. */ - - if (recurse_lvl == 0 && *str < end-1) { - RAISE_SYNTAX_ERROR("f-string: unexpected end of string"); - return -1; - } - if (recurse_lvl != 0 && **str != '}') { - RAISE_SYNTAX_ERROR("f-string: expecting '}'"); - return -1; - } - - FstringParser_check_invariants(state); - return 0; -} - -/* Convert the partial state reflected in last_str and expr_list to an - expr_ty. The expr_ty can be a Constant, or a JoinedStr. */ -expr_ty -_PyPegen_FstringParser_Finish(Parser *p, FstringParser *state, Token* first_token, - Token *last_token) -{ - asdl_expr_seq *seq; - - FstringParser_check_invariants(state); - - /* If we're just a constant string with no expressions, return - that. */ - if (!state->fmode) { - assert(!state->expr_list.size); - if (!state->last_str) { - /* Create a zero length string. */ - state->last_str = PyUnicode_FromStringAndSize(NULL, 0); - if (!state->last_str) { - goto error; + return NULL; } } - return make_str_node_and_del(p, &state->last_str, first_token, last_token); - } - - /* Create a Constant node out of last_str, if needed. It will be the - last node in our expression list. */ - if (state->last_str) { - expr_ty str = make_str_node_and_del(p, &state->last_str, first_token, last_token); - if (!str || ExprList_Append(&state->expr_list, str) < 0) { - goto error; + if (rawmode) { + return PyBytes_FromStringAndSize(s, len); } + return decode_bytes_with_escapes(p, s, len, t); } - /* This has already been freed. */ - assert(state->last_str == NULL); - - seq = ExprList_Finish(&state->expr_list, p->arena); - if (!seq) { - goto error; - } - - return _PyAST_JoinedStr(seq, first_token->lineno, first_token->col_offset, - last_token->end_lineno, last_token->end_col_offset, - p->arena); - -error: - _PyPegen_FstringParser_Dealloc(state); - return NULL; -} - -/* Given an f-string (with no 'f' or quotes) that's in *str and ends - at end, parse it into an expr_ty. Return NULL on error. Adjust - str to point past the parsed portion. */ -static expr_ty -fstring_parse(Parser *p, const char **str, const char *end, int raw, - int recurse_lvl, Token *first_token, Token* t, Token *last_token) -{ - FstringParser state; - - _PyPegen_FstringParser_Init(&state); - if (_PyPegen_FstringParser_ConcatFstring(p, &state, str, end, raw, recurse_lvl, - first_token, t, last_token) < 0) { - _PyPegen_FstringParser_Dealloc(&state); - return NULL; - } - - return _PyPegen_FstringParser_Finish(p, &state, t, t); + return _PyPegen_decode_string(p, rawmode, s, len, t); } diff --git a/Parser/string_parser.h b/Parser/string_parser.h index 4a22f3d3..0b34de1b 100644 --- a/Parser/string_parser.h +++ b/Parser/string_parser.h @@ -5,42 +5,7 @@ #include <pycore_ast.h> #include "pegen.h" -#define EXPRLIST_N_CACHED 64 - -typedef struct { - /* Incrementally build an array of expr_ty, so be used in an - asdl_seq. Cache some small but reasonably sized number of - expr_ty's, and then after that start dynamically allocating, - doubling the number allocated each time. Note that the f-string - f'{0}a{1}' contains 3 expr_ty's: 2 FormattedValue's, and one - Constant for the literal 'a'. So you add expr_ty's about twice as - fast as you add expressions in an f-string. */ - - Py_ssize_t allocated; /* Number we've allocated. */ - Py_ssize_t size; /* Number we've used. */ - expr_ty *p; /* Pointer to the memory we're actually - using. Will point to 'data' until we - start dynamically allocating. */ - expr_ty data[EXPRLIST_N_CACHED]; -} ExprList; - -/* The FstringParser is designed to add a mix of strings and - f-strings, and concat them together as needed. Ultimately, it - generates an expr_ty. */ -typedef struct { - PyObject *last_str; - ExprList expr_list; - int fmode; -} FstringParser; - -void _PyPegen_FstringParser_Init(FstringParser *); -int _PyPegen_parsestr(Parser *, int *, int *, PyObject **, - const char **, Py_ssize_t *, Token *); -int _PyPegen_FstringParser_ConcatFstring(Parser *, FstringParser *, const char **, - const char *, int, int, Token *, Token *, - Token *); -int _PyPegen_FstringParser_ConcatAndDel(FstringParser *, PyObject *); -expr_ty _PyPegen_FstringParser_Finish(Parser *, FstringParser *, Token *, Token *); -void _PyPegen_FstringParser_Dealloc(FstringParser *); +PyObject *_PyPegen_parse_string(Parser *, Token *); +PyObject *_PyPegen_decode_string(Parser *, int, const char *, size_t, Token *); #endif diff --git a/Parser/token.c b/Parser/token.c index 74bca0ef..2bc963a9 100644 --- a/Parser/token.c +++ b/Parser/token.c @@ -1,7 +1,7 @@ -/* Auto-generated by Tools/scripts/generate_token.py */ +/* Auto-generated by Tools/build/generate_token.py */ #include "Python.h" -#include "token.h" +#include "pycore_token.h" /* Token names */ @@ -60,15 +60,19 @@ const char * const _PyParser_TokenNames[] = { "RARROW", "ELLIPSIS", "COLONEQUAL", + "EXCLAMATION", "OP", "AWAIT", "ASYNC", "TYPE_IGNORE", "TYPE_COMMENT", "SOFT_KEYWORD", + "FSTRING_START", + "FSTRING_MIDDLE", + "FSTRING_END", + "COMMENT", + "NL", "<ERRORTOKEN>", - "<COMMENT>", - "<NL>", "<ENCODING>", "<N_TOKENS>", }; @@ -76,9 +80,10 @@ const char * const _PyParser_TokenNames[] = { /* Return the token corresponding to a single character */ int -PyToken_OneChar(int c1) +_PyToken_OneChar(int c1) { switch (c1) { + case '!': return EXCLAMATION; case '%': return PERCENT; case '&': return AMPER; case '(': return LPAR; @@ -107,7 +112,7 @@ PyToken_OneChar(int c1) } int -PyToken_TwoChars(int c1, int c2) +_PyToken_TwoChars(int c1, int c2) { switch (c1) { case '!': @@ -191,7 +196,7 @@ PyToken_TwoChars(int c1, int c2) } int -PyToken_ThreeChars(int c1, int c2, int c3) +_PyToken_ThreeChars(int c1, int c2, int c3) { switch (c1) { case '*': diff --git a/Parser/tokenizer.c b/Parser/tokenizer.c index ca11c7be..c4c345e4 100644 --- a/Parser/tokenizer.c +++ b/Parser/tokenizer.c @@ -11,11 +11,6 @@ #include "tokenizer.h" #include "errcode.h" -#include "unicodeobject.h" -#include "bytesobject.h" -#include "fileobject.h" -#include "abstract.h" - /* Alternate tab spacing */ #define ALTTABSIZE 1 @@ -36,6 +31,31 @@ /* Don't ever change this -- it would break the portability of Python code */ #define TABSIZE 8 +#define MAKE_TOKEN(token_type) token_setup(tok, token, token_type, p_start, p_end) +#define MAKE_TYPE_COMMENT_TOKEN(token_type, col_offset, end_col_offset) (\ + type_comment_token_setup(tok, token, token_type, col_offset, end_col_offset, p_start, p_end)) +#define ADVANCE_LINENO() \ + tok->lineno++; \ + tok->col_offset = 0; + +#define INSIDE_FSTRING(tok) (tok->tok_mode_stack_index > 0) +#define INSIDE_FSTRING_EXPR(tok) (tok->curly_bracket_expr_start_depth >= 0) +#ifdef Py_DEBUG +static inline tokenizer_mode* TOK_GET_MODE(struct tok_state* tok) { + assert(tok->tok_mode_stack_index >= 0); + assert(tok->tok_mode_stack_index < MAXFSTRINGLEVEL); + return &(tok->tok_mode_stack[tok->tok_mode_stack_index]); +} +static inline tokenizer_mode* TOK_NEXT_MODE(struct tok_state* tok) { + assert(tok->tok_mode_stack_index >= 0); + assert(tok->tok_mode_stack_index + 1 < MAXFSTRINGLEVEL); + return &(tok->tok_mode_stack[++tok->tok_mode_stack_index]); +} +#else +#define TOK_GET_MODE(tok) (&(tok->tok_mode_stack[tok->tok_mode_stack_index])) +#define TOK_NEXT_MODE(tok) (&(tok->tok_mode_stack[++tok->tok_mode_stack_index])) +#endif + /* Forward */ static struct tok_state *tok_new(void); static int tok_nextc(struct tok_state *tok); @@ -71,6 +91,8 @@ tok_new(void) tok->pendin = 0; tok->prompt = tok->nextprompt = NULL; tok->lineno = 0; + tok->starting_col_offset = -1; + tok->col_offset = -1; tok->level = 0; tok->altindstack[0] = 0; tok->decoding_state = STATE_INIT; @@ -81,6 +103,7 @@ tok_new(void) tok->filename = NULL; tok->decoding_readline = NULL; tok->decoding_buffer = NULL; + tok->readline = NULL; tok->type_comments = 0; tok->async_hacks = 0; tok->async_def = 0; @@ -89,6 +112,14 @@ tok_new(void) tok->interactive_underflow = IUNDERFLOW_NORMAL; tok->str = NULL; tok->report_warnings = 1; + tok->tok_extra_tokens = 0; + tok->comment_newline = 0; + tok->implicit_newline = 0; + tok->tok_mode_stack[0] = (tokenizer_mode){.kind =TOK_REGULAR_MODE, .f_string_quote='\0', .f_string_quote_size = 0, .f_string_debug=0}; + tok->tok_mode_stack_index = 0; +#ifdef Py_DEBUG + tok->debug = _Py_GetConfig()->parser_debug; +#endif return tok; } @@ -109,8 +140,9 @@ static char * error_ret(struct tok_state *tok) /* XXX */ { tok->decoding_erred = 1; - if (tok->fp != NULL && tok->buf != NULL) /* see _PyTokenizer_Free */ + if ((tok->fp != NULL || tok->readline != NULL) && tok->buf != NULL) {/* see _PyTokenizer_Free */ PyMem_Free(tok->buf); + } tok->buf = tok->cur = tok->inp = NULL; tok->start = NULL; tok->end = NULL; @@ -323,16 +355,138 @@ tok_concatenate_interactive_new_line(struct tok_state *tok, const char *line) { return -1; } strcpy(new_str + current_size, line); + tok->implicit_newline = 0; if (last_char != '\n') { /* Last line does not end in \n, fake one */ new_str[current_size + line_size - 1] = '\n'; new_str[current_size + line_size] = '\0'; + tok->implicit_newline = 1; } tok->interactive_src_start = new_str; tok->interactive_src_end = new_str + current_size + line_size; return 0; } +/* Traverse and remember all f-string buffers, in order to be able to restore + them after reallocating tok->buf */ +static void +remember_fstring_buffers(struct tok_state *tok) +{ + int index; + tokenizer_mode *mode; + + for (index = tok->tok_mode_stack_index; index >= 0; --index) { + mode = &(tok->tok_mode_stack[index]); + mode->f_string_start_offset = mode->f_string_start - tok->buf; + mode->f_string_multi_line_start_offset = mode->f_string_multi_line_start - tok->buf; + } +} + +/* Traverse and restore all f-string buffers after reallocating tok->buf */ +static void +restore_fstring_buffers(struct tok_state *tok) +{ + int index; + tokenizer_mode *mode; + + for (index = tok->tok_mode_stack_index; index >= 0; --index) { + mode = &(tok->tok_mode_stack[index]); + mode->f_string_start = tok->buf + mode->f_string_start_offset; + mode->f_string_multi_line_start = tok->buf + mode->f_string_multi_line_start_offset; + } +} + +static int +set_fstring_expr(struct tok_state* tok, struct token *token, char c) { + assert(token != NULL); + assert(c == '}' || c == ':' || c == '!'); + tokenizer_mode *tok_mode = TOK_GET_MODE(tok); + + if (!tok_mode->f_string_debug || token->metadata) { + return 0; + } + + PyObject *res = PyUnicode_DecodeUTF8( + tok_mode->last_expr_buffer, + tok_mode->last_expr_size - tok_mode->last_expr_end, + NULL + ); + if (!res) { + return -1; + } + token->metadata = res; + return 0; +} + +static int +update_fstring_expr(struct tok_state *tok, char cur) +{ + assert(tok->cur != NULL); + + Py_ssize_t size = strlen(tok->cur); + tokenizer_mode *tok_mode = TOK_GET_MODE(tok); + + switch (cur) { + case 0: + if (!tok_mode->last_expr_buffer || tok_mode->last_expr_end >= 0) { + return 1; + } + char *new_buffer = PyMem_Realloc( + tok_mode->last_expr_buffer, + tok_mode->last_expr_size + size + ); + if (new_buffer == NULL) { + PyMem_Free(tok_mode->last_expr_buffer); + goto error; + } + tok_mode->last_expr_buffer = new_buffer; + strncpy(tok_mode->last_expr_buffer + tok_mode->last_expr_size, tok->cur, size); + tok_mode->last_expr_size += size; + break; + case '{': + if (tok_mode->last_expr_buffer != NULL) { + PyMem_Free(tok_mode->last_expr_buffer); + } + tok_mode->last_expr_buffer = PyMem_Malloc(size); + if (tok_mode->last_expr_buffer == NULL) { + goto error; + } + tok_mode->last_expr_size = size; + tok_mode->last_expr_end = -1; + strncpy(tok_mode->last_expr_buffer, tok->cur, size); + break; + case '}': + case '!': + case ':': + if (tok_mode->last_expr_end == -1) { + tok_mode->last_expr_end = strlen(tok->start); + } + break; + default: + Py_UNREACHABLE(); + } + return 1; +error: + tok->done = E_NOMEM; + return 0; +} + +static void +free_fstring_expressions(struct tok_state *tok) +{ + int index; + tokenizer_mode *mode; + + for (index = tok->tok_mode_stack_index; index >= 0; --index) { + mode = &(tok->tok_mode_stack[index]); + if (mode->last_expr_buffer != NULL) { + PyMem_Free(mode->last_expr_buffer); + mode->last_expr_buffer = NULL; + mode->last_expr_size = 0; + mode->last_expr_end = -1; + } + } +} /* Read a line of text from TOK into S, using the stream in TOK. Return NULL on failure, else S. @@ -360,6 +514,7 @@ tok_reserve_buf(struct tok_state *tok, Py_ssize_t size) Py_ssize_t start = tok->start == NULL ? -1 : tok->start - tok->buf; Py_ssize_t line_start = tok->start == NULL ? -1 : tok->line_start - tok->buf; Py_ssize_t multi_line_start = tok->multi_line_start - tok->buf; + remember_fstring_buffers(tok); newbuf = (char *)PyMem_Realloc(newbuf, newsize); if (newbuf == NULL) { tok->done = E_NOMEM; @@ -372,10 +527,16 @@ tok_reserve_buf(struct tok_state *tok, Py_ssize_t size) tok->start = start < 0 ? NULL : tok->buf + start; tok->line_start = line_start < 0 ? NULL : tok->buf + line_start; tok->multi_line_start = multi_line_start < 0 ? NULL : tok->buf + multi_line_start; + restore_fstring_buffers(tok); } return 1; } +static inline int +contains_null_bytes(const char* str, size_t size) { + return memchr(str, 0, size) != NULL; +} + static int tok_readline_recode(struct tok_state *tok) { PyObject *line; @@ -431,7 +592,7 @@ error: static int fp_setreadl(struct tok_state *tok, const char* enc) { - PyObject *readline, *io, *stream; + PyObject *readline, *open, *stream; int fd; long pos; @@ -448,13 +609,13 @@ fp_setreadl(struct tok_state *tok, const char* enc) return 0; } - io = PyImport_ImportModule("io"); - if (io == NULL) { + open = _PyImport_GetModuleAttrString("io", "open"); + if (open == NULL) { return 0; } - stream = _PyObject_CallMethod(io, &_Py_ID(open), "isisOOO", + stream = PyObject_CallFunction(open, "isisOOO", fd, "r", -1, enc, Py_None, Py_None, Py_False); - Py_DECREF(io); + Py_DECREF(open); if (stream == NULL) { return 0; } @@ -615,7 +776,8 @@ translate_into_utf8(const char* str, const char* enc) { static char * -translate_newlines(const char *s, int exec_input, struct tok_state *tok) { +translate_newlines(const char *s, int exec_input, int preserve_crlf, + struct tok_state *tok) { int skip_next_lf = 0; size_t needed_length = strlen(s) + 2, final_length; char *buf, *current; @@ -635,7 +797,7 @@ translate_newlines(const char *s, int exec_input, struct tok_state *tok) { break; } } - if (c == '\r') { + if (!preserve_crlf && c == '\r') { skip_next_lf = 1; c = '\n'; } @@ -643,7 +805,7 @@ translate_newlines(const char *s, int exec_input, struct tok_state *tok) { } /* If this is exec input, add a newline to the end of the string if there isn't one already. */ - if (exec_input && c != '\n') { + if (exec_input && c != '\n' && c != '\0') { *current = '\n'; current++; } @@ -665,14 +827,14 @@ translate_newlines(const char *s, int exec_input, struct tok_state *tok) { inside TOK. */ static char * -decode_str(const char *input, int single, struct tok_state *tok) +decode_str(const char *input, int single, struct tok_state *tok, int preserve_crlf) { PyObject* utf8 = NULL; char *str; const char *s; const char *newl[2] = {NULL, NULL}; int lineno = 0; - tok->input = str = translate_newlines(input, single, tok); + tok->input = str = translate_newlines(input, single, preserve_crlf, tok); if (str == NULL) return NULL; tok->enc = NULL; @@ -724,14 +886,14 @@ decode_str(const char *input, int single, struct tok_state *tok) /* Set up tokenizer for string */ struct tok_state * -_PyTokenizer_FromString(const char *str, int exec_input) +_PyTokenizer_FromString(const char *str, int exec_input, int preserve_crlf) { struct tok_state *tok = tok_new(); char *decoded; if (tok == NULL) return NULL; - decoded = decode_str(str, exec_input, tok); + decoded = decode_str(str, exec_input, tok, preserve_crlf); if (decoded == NULL) { _PyTokenizer_Free(tok); return NULL; @@ -742,16 +904,43 @@ _PyTokenizer_FromString(const char *str, int exec_input) return tok; } +struct tok_state * +_PyTokenizer_FromReadline(PyObject* readline, const char* enc, + int exec_input, int preserve_crlf) +{ + struct tok_state *tok = tok_new(); + if (tok == NULL) + return NULL; + if ((tok->buf = (char *)PyMem_Malloc(BUFSIZ)) == NULL) { + _PyTokenizer_Free(tok); + return NULL; + } + tok->cur = tok->inp = tok->buf; + tok->end = tok->buf + BUFSIZ; + tok->fp = NULL; + if (enc != NULL) { + tok->encoding = new_string(enc, strlen(enc), tok); + if (!tok->encoding) { + _PyTokenizer_Free(tok); + return NULL; + } + } + tok->decoding_state = STATE_NORMAL; + Py_INCREF(readline); + tok->readline = readline; + return tok; +} + /* Set up tokenizer for UTF-8 string */ struct tok_state * -_PyTokenizer_FromUTF8(const char *str, int exec_input) +_PyTokenizer_FromUTF8(const char *str, int exec_input, int preserve_crlf) { struct tok_state *tok = tok_new(); char *translated; if (tok == NULL) return NULL; - tok->input = translated = translate_newlines(str, exec_input, tok); + tok->input = translated = translate_newlines(str, exec_input, preserve_crlf, tok); if (translated == NULL) { _PyTokenizer_Free(tok); return NULL; @@ -811,8 +1000,9 @@ _PyTokenizer_Free(struct tok_state *tok) } Py_XDECREF(tok->decoding_readline); Py_XDECREF(tok->decoding_buffer); + Py_XDECREF(tok->readline); Py_XDECREF(tok->filename); - if (tok->fp != NULL && tok->buf != NULL) { + if ((tok->readline != NULL || tok->fp != NULL ) && tok->buf != NULL) { PyMem_Free(tok->buf); } if (tok->input) { @@ -821,9 +1011,20 @@ _PyTokenizer_Free(struct tok_state *tok) if (tok->interactive_src_start != NULL) { PyMem_Free(tok->interactive_src_start); } + free_fstring_expressions(tok); PyMem_Free(tok); } +void +_PyToken_Free(struct token *token) { + Py_XDECREF(token->metadata); +} + +void +_PyToken_Init(struct token *token) { + token->metadata = NULL; +} + static int tok_readline_raw(struct tok_state *tok) { @@ -831,9 +1032,9 @@ tok_readline_raw(struct tok_state *tok) if (!tok_reserve_buf(tok, BUFSIZ)) { return 0; } - char *line = Py_UniversalNewlineFgets(tok->inp, - (int)(tok->end - tok->inp), - tok->fp, NULL); + int n_chars = (int)(tok->end - tok->inp); + size_t line_size = 0; + char *line = _Py_UniversalNewlineFgetsWithSize(tok->inp, n_chars, tok->fp, NULL, &line_size); if (line == NULL) { return 1; } @@ -841,7 +1042,7 @@ tok_readline_raw(struct tok_state *tok) tok_concatenate_interactive_new_line(tok, line) == -1) { return 0; } - tok->inp = strchr(tok->inp, '\0'); + tok->inp += line_size; if (tok->inp == tok->buf) { return 0; } @@ -849,6 +1050,67 @@ tok_readline_raw(struct tok_state *tok) return 1; } +static int +tok_readline_string(struct tok_state* tok) { + PyObject* line = NULL; + PyObject* raw_line = PyObject_CallNoArgs(tok->readline); + if (raw_line == NULL) { + if (PyErr_ExceptionMatches(PyExc_StopIteration)) { + PyErr_Clear(); + return 1; + } + error_ret(tok); + goto error; + } + if(tok->encoding != NULL) { + if (!PyBytes_Check(raw_line)) { + PyErr_Format(PyExc_TypeError, "readline() returned a non-bytes object"); + error_ret(tok); + goto error; + } + line = PyUnicode_Decode(PyBytes_AS_STRING(raw_line), PyBytes_GET_SIZE(raw_line), + tok->encoding, "replace"); + Py_CLEAR(raw_line); + if (line == NULL) { + error_ret(tok); + goto error; + } + } else { + if(!PyUnicode_Check(raw_line)) { + PyErr_Format(PyExc_TypeError, "readline() returned a non-string object"); + error_ret(tok); + goto error; + } + line = raw_line; + raw_line = NULL; + } + Py_ssize_t buflen; + const char* buf = PyUnicode_AsUTF8AndSize(line, &buflen); + if (buf == NULL) { + error_ret(tok); + goto error; + } + + // Make room for the null terminator *and* potentially + // an extra newline character that we may need to artificially + // add. + size_t buffer_size = buflen + 2; + if (!tok_reserve_buf(tok, buffer_size)) { + goto error; + } + memcpy(tok->inp, buf, buflen); + tok->inp += buflen; + *tok->inp = '\0'; + + tok->line_start = tok->cur; + Py_DECREF(line); + return 1; +error: + Py_XDECREF(raw_line); + Py_XDECREF(line); + return 0; +} + static int tok_underflow_string(struct tok_state *tok) { char *end = strchr(tok->inp, '\n'); @@ -866,7 +1128,7 @@ tok_underflow_string(struct tok_state *tok) { tok->buf = tok->cur; } tok->line_start = tok->cur; - tok->lineno++; + ADVANCE_LINENO(); tok->inp = end; return 1; } @@ -879,7 +1141,7 @@ tok_underflow_interactive(struct tok_state *tok) { } char *newtok = PyOS_Readline(tok->fp ? tok->fp : stdin, stdout, tok->prompt); if (newtok != NULL) { - char *translated = translate_newlines(newtok, 0, tok); + char *translated = translate_newlines(newtok, 0, 0, tok); PyMem_Free(newtok); if (translated == NULL) { return 0; @@ -924,8 +1186,9 @@ tok_underflow_interactive(struct tok_state *tok) { } else if (tok->start != NULL) { Py_ssize_t cur_multi_line_start = tok->multi_line_start - tok->buf; + remember_fstring_buffers(tok); size_t size = strlen(newtok); - tok->lineno++; + ADVANCE_LINENO(); if (!tok_reserve_buf(tok, size + 1)) { PyMem_Free(tok->buf); tok->buf = NULL; @@ -936,15 +1199,18 @@ tok_underflow_interactive(struct tok_state *tok) { PyMem_Free(newtok); tok->inp += size; tok->multi_line_start = tok->buf + cur_multi_line_start; + restore_fstring_buffers(tok); } else { - tok->lineno++; + remember_fstring_buffers(tok); + ADVANCE_LINENO(); PyMem_Free(tok->buf); tok->buf = newtok; tok->cur = tok->buf; tok->line_start = tok->buf; tok->inp = strchr(tok->buf, '\0'); tok->end = tok->inp + 1; + restore_fstring_buffers(tok); } if (tok->done != E_OK) { if (tok->prompt != NULL) { @@ -952,12 +1218,16 @@ tok_underflow_interactive(struct tok_state *tok) { } return 0; } + + if (tok->tok_mode_stack_index && !update_fstring_expr(tok, 0)) { + return 0; + } return 1; } static int tok_underflow_file(struct tok_state *tok) { - if (tok->start == NULL) { + if (tok->start == NULL && !INSIDE_FSTRING(tok)) { tok->cur = tok->inp = tok->buf; } if (tok->decoding_state == STATE_INIT) { @@ -987,14 +1257,20 @@ tok_underflow_file(struct tok_state *tok) { tok->done = E_EOF; return 0; } + tok->implicit_newline = 0; if (tok->inp[-1] != '\n') { assert(tok->inp + 1 < tok->end); /* Last line does not end in \n, fake one */ *tok->inp++ = '\n'; *tok->inp = '\0'; + tok->implicit_newline = 1; } - tok->lineno++; + if (tok->tok_mode_stack_index && !update_fstring_expr(tok, 0)) { + return 0; + } + + ADVANCE_LINENO(); if (tok->decoding_state != STATE_NORMAL) { if (tok->lineno > 2) { tok->decoding_state = STATE_NORMAL; @@ -1015,6 +1291,44 @@ tok_underflow_file(struct tok_state *tok) { return tok->done == E_OK; } +static int +tok_underflow_readline(struct tok_state* tok) { + assert(tok->decoding_state == STATE_NORMAL); + assert(tok->fp == NULL && tok->input == NULL && tok->decoding_readline == NULL); + if (tok->start == NULL && !INSIDE_FSTRING(tok)) { + tok->cur = tok->inp = tok->buf; + } + if (!tok_readline_string(tok)) { + return 0; + } + if (tok->inp == tok->cur) { + tok->done = E_EOF; + return 0; + } + tok->implicit_newline = 0; + if (tok->inp[-1] != '\n') { + assert(tok->inp + 1 < tok->end); + /* Last line does not end in \n, fake one */ + *tok->inp++ = '\n'; + *tok->inp = '\0'; + tok->implicit_newline = 1; + } + + if (tok->tok_mode_stack_index && !update_fstring_expr(tok, 0)) { + return 0; + } + + ADVANCE_LINENO(); + /* The default encoding is UTF-8, so make sure we don't have any + non-UTF-8 sequences in it. */ + if (!tok->encoding && !ensure_utf8(tok->cur, tok)) { + error_ret(tok); + return 0; + } + assert(tok->done == E_OK); + return tok->done == E_OK; +} + #if defined(Py_DEBUG) static void print_escape(FILE *f, const char *s, Py_ssize_t size) @@ -1052,12 +1366,16 @@ tok_nextc(struct tok_state *tok) int rc; for (;;) { if (tok->cur != tok->inp) { + tok->col_offset++; return Py_CHARMASK(*tok->cur++); /* Fast path */ } if (tok->done != E_OK) { - return EOF; + return EOF; + } + if (tok->readline) { + rc = tok_underflow_readline(tok); } - if (tok->fp == NULL) { + else if (tok->fp == NULL) { rc = tok_underflow_string(tok); } else if (tok->prompt != NULL) { @@ -1067,7 +1385,7 @@ tok_nextc(struct tok_state *tok) rc = tok_underflow_file(tok); } #if defined(Py_DEBUG) - if (Py_DebugFlag) { + if (tok->debug) { fprintf(stderr, "line[%d] = ", tok->lineno); print_escape(stderr, tok->cur, tok->inp - tok->cur); fprintf(stderr, " tok->done = %d\n", tok->done); @@ -1078,6 +1396,12 @@ tok_nextc(struct tok_state *tok) return EOF; } tok->line_start = tok->cur; + + if (contains_null_bytes(tok->line_start, tok->inp - tok->line_start)) { + syntaxerror(tok, "source code cannot contain null bytes"); + tok->cur = tok->inp; + return EOF; + } } Py_UNREACHABLE(); } @@ -1091,9 +1415,10 @@ tok_backup(struct tok_state *tok, int c) if (--tok->cur < tok->buf) { Py_FatalError("tokenizer beginning of buffer"); } - if ((int)(unsigned char)*tok->cur != c) { + if ((int)(unsigned char)*tok->cur != Py_CHARMASK(c)) { Py_FatalError("tok_backup: wrong character"); } + tok->col_offset--; } } @@ -1102,6 +1427,12 @@ _syntaxerror_range(struct tok_state *tok, const char *format, int col_offset, int end_col_offset, va_list vargs) { + // In release builds, we don't want to overwrite a previous error, but in debug builds we + // want to fail if we are not doing it so we can fix it. + assert(tok->done != E_ERROR); + if (tok->done == E_ERROR) { + return ERRORTOKEN; + } PyObject *errmsg, *errtext, *args; errmsg = PyUnicode_FromFormatV(format, vargs); if (!errmsg) { @@ -1147,12 +1478,9 @@ error: static int syntaxerror(struct tok_state *tok, const char *format, ...) { + // This errors are cleaned on startup. Todo: Fix it. va_list vargs; -#ifdef HAVE_STDARG_PROTOTYPES va_start(vargs, format); -#else - va_start(vargs); -#endif int ret = _syntaxerror_range(tok, format, -1, -1, vargs); va_end(vargs); return ret; @@ -1164,18 +1492,12 @@ syntaxerror_known_range(struct tok_state *tok, const char *format, ...) { va_list vargs; -#ifdef HAVE_STDARG_PROTOTYPES va_start(vargs, format); -#else - va_start(vargs); -#endif int ret = _syntaxerror_range(tok, format, col_offset, end_col_offset, vargs); va_end(vargs); return ret; } - - static int indenterror(struct tok_state *tok) { @@ -1193,11 +1515,7 @@ parser_warn(struct tok_state *tok, PyObject *category, const char *format, ...) PyObject *errmsg; va_list vargs; -#ifdef HAVE_STDARG_PROTOTYPES va_start(vargs, format); -#else - va_start(vargs); -#endif errmsg = PyUnicode_FromFormatV(format, vargs); va_end(vargs); if (!errmsg) { @@ -1223,6 +1541,40 @@ error: return -1; } +static int +warn_invalid_escape_sequence(struct tok_state *tok, int first_invalid_escape_char) +{ + if (!tok->report_warnings) { + return 0; + } + + PyObject *msg = PyUnicode_FromFormat( + "invalid escape sequence '\\%c'", + (char) first_invalid_escape_char + ); + + if (msg == NULL) { + return -1; + } + + if (PyErr_WarnExplicitObject(PyExc_SyntaxWarning, msg, tok->filename, + tok->lineno, NULL, NULL) < 0) { + Py_DECREF(msg); + + if (PyErr_ExceptionMatches(PyExc_SyntaxWarning)) { + /* Replace the SyntaxWarning exception with a SyntaxError + to get a more accurate error report */ + PyErr_Clear(); + return syntaxerror(tok, "invalid escape sequence '\\%c'", (char) first_invalid_escape_char); + } + + return -1; + } + + Py_DECREF(msg); + return 0; +} + static int lookahead(struct tok_state *tok, const char *test) { @@ -1247,8 +1599,12 @@ lookahead(struct tok_state *tok, const char *test) } static int -verify_end_of_number(struct tok_state *tok, int c, const char *kind) -{ +verify_end_of_number(struct tok_state *tok, int c, const char *kind) { + if (tok->tok_extra_tokens) { + // When we are parsing extra tokens, we don't want to emit warnings + // about invalid literals, because we want to be a bit more liberal. + return 1; + } /* Emit a deprecation warning only if the numeric literal is immediately * followed by one of keywords which can occur after a numeric literal * in valid code: "and", "else", "for", "if", "in", "is" and "or". @@ -1306,6 +1662,9 @@ verify_end_of_number(struct tok_state *tok, int c, const char *kind) static int verify_identifier(struct tok_state *tok) { + if (tok->tok_extra_tokens) { + return 1; + } PyObject *s; if (tok->decoding_erred) return 0; @@ -1341,14 +1700,11 @@ verify_identifier(struct tok_state *tok) tok->cur = (char *)tok->start + PyBytes_GET_SIZE(s); } Py_DECREF(s); - // PyUnicode_FromFormatV() does not support %X - char hex[9]; - (void)PyOS_snprintf(hex, sizeof(hex), "%04X", ch); if (Py_UNICODE_ISPRINTABLE(ch)) { - syntaxerror(tok, "invalid character '%c' (U+%s)", ch, hex); + syntaxerror(tok, "invalid character '%c' (U+%04X)", ch, ch); } else { - syntaxerror(tok, "invalid non-printable character U+%s", hex); + syntaxerror(tok, "invalid non-printable character U+%04X", ch); } return 0; } @@ -1378,11 +1734,13 @@ tok_decimal_tail(struct tok_state *tok) return c; } -/* Get next token, after space stripping etc. */ static inline int tok_continuation_line(struct tok_state *tok) { int c = tok_nextc(tok); + if (c == '\r') { + c = tok_nextc(tok); + } if (c != '\n') { tok->done = E_LINECONT; return -1; @@ -1399,16 +1757,56 @@ tok_continuation_line(struct tok_state *tok) { } static int -tok_get(struct tok_state *tok, const char **p_start, const char **p_end) +type_comment_token_setup(struct tok_state *tok, struct token *token, int type, int col_offset, + int end_col_offset, const char *start, const char *end) +{ + token->level = tok->level; + token->lineno = token->end_lineno = tok->lineno; + token->col_offset = col_offset; + token->end_col_offset = end_col_offset; + token->start = start; + token->end = end; + return type; +} + +static int +token_setup(struct tok_state *tok, struct token *token, int type, const char *start, const char *end) +{ + assert((start == NULL && end == NULL) || (start != NULL && end != NULL)); + token->level = tok->level; + if (ISSTRINGLIT(type)) { + token->lineno = tok->first_lineno; + } + else { + token->lineno = tok->lineno; + } + token->end_lineno = tok->lineno; + token->col_offset = token->end_col_offset = -1; + token->start = start; + token->end = end; + + if (start != NULL && end != NULL) { + token->col_offset = tok->starting_col_offset; + token->end_col_offset = tok->col_offset; + } + return type; +} + + +static int +tok_get_normal_mode(struct tok_state *tok, tokenizer_mode* current_tok, struct token *token) { int c; int blankline, nonascii; - *p_start = *p_end = NULL; + const char *p_start = NULL; + const char *p_end = NULL; nextline: tok->start = NULL; + tok->starting_col_offset = -1; blankline = 0; + /* Get indentation level */ if (tok->atbol) { int col = 0; @@ -1434,7 +1832,7 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) // the level of indentation of whatever comes next. cont_line_col = cont_line_col ? cont_line_col : col; if ((c = tok_continuation_line(tok)) == -1) { - return ERRORTOKEN; + return MAKE_TOKEN(ERRORTOKEN); } } else { @@ -1442,7 +1840,7 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) } } tok_backup(tok, c); - if (c == '#' || c == '\n') { + if (c == '#' || c == '\n' || c == '\r') { /* Lines with only whitespace and/or comments shouldn't affect the indentation and are not passed to the parser as NEWLINE tokens, @@ -1469,7 +1867,7 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) if (col == tok->indstack[tok->indent]) { /* No change */ if (altcol != tok->altindstack[tok->indent]) { - return indenterror(tok); + return MAKE_TOKEN(indenterror(tok)); } } else if (col > tok->indstack[tok->indent]) { @@ -1477,10 +1875,10 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) if (tok->indent+1 >= MAXINDENT) { tok->done = E_TOODEEP; tok->cur = tok->inp; - return ERRORTOKEN; + return MAKE_TOKEN(ERRORTOKEN); } if (altcol <= tok->altindstack[tok->indent]) { - return indenterror(tok); + return MAKE_TOKEN(indenterror(tok)); } tok->pendin++; tok->indstack[++tok->indent] = col; @@ -1496,26 +1894,35 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) if (col != tok->indstack[tok->indent]) { tok->done = E_DEDENT; tok->cur = tok->inp; - return ERRORTOKEN; + return MAKE_TOKEN(ERRORTOKEN); } if (altcol != tok->altindstack[tok->indent]) { - return indenterror(tok); + return MAKE_TOKEN(indenterror(tok)); } } } } tok->start = tok->cur; + tok->starting_col_offset = tok->col_offset; /* Return pending indents/dedents */ - if (tok->pendin != 0) { + if (tok->pendin != 0) { if (tok->pendin < 0) { + if (tok->tok_extra_tokens) { + p_start = tok->cur; + p_end = tok->cur; + } tok->pendin++; - return DEDENT; + return MAKE_TOKEN(DEDENT); } else { + if (tok->tok_extra_tokens) { + p_start = tok->buf; + p_end = tok->cur; + } tok->pendin--; - return INDENT; + return MAKE_TOKEN(INDENT); } } @@ -1553,25 +1960,36 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) /* Set start of current token */ tok->start = tok->cur == NULL ? NULL : tok->cur - 1; + tok->starting_col_offset = tok->col_offset - 1; /* Skip comment, unless it's a type comment */ if (c == '#') { - const char *prefix, *p, *type_start; - while (c != EOF && c != '\n') { + const char* p = NULL; + const char *prefix, *type_start; + int current_starting_col_offset; + + while (c != EOF && c != '\n' && c != '\r') { c = tok_nextc(tok); } + if (tok->tok_extra_tokens) { + p = tok->start; + } + if (tok->type_comments) { p = tok->start; + current_starting_col_offset = tok->starting_col_offset; prefix = type_comment_prefix; while (*prefix && p < tok->cur) { if (*prefix == ' ') { while (*p == ' ' || *p == '\t') { p++; + current_starting_col_offset++; } } else if (*prefix == *p) { p++; + current_starting_col_offset++; } else { break; } @@ -1582,7 +2000,9 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) /* This is a type comment if we matched all of type_comment_prefix. */ if (!*prefix) { int is_type_ignore = 1; + // +6 in order to skip the word 'ignore' const char *ignore_end = p + 6; + const int ignore_end_col_offset = current_starting_col_offset + 6; tok_backup(tok, c); /* don't eat the newline or EOF */ type_start = p; @@ -1595,34 +2015,41 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) && ((unsigned char)ignore_end[0] >= 128 || Py_ISALNUM(ignore_end[0])))); if (is_type_ignore) { - *p_start = ignore_end; - *p_end = tok->cur; + p_start = ignore_end; + p_end = tok->cur; /* If this type ignore is the only thing on the line, consume the newline also. */ if (blankline) { tok_nextc(tok); tok->atbol = 1; } - return TYPE_IGNORE; + return MAKE_TYPE_COMMENT_TOKEN(TYPE_IGNORE, ignore_end_col_offset, tok->col_offset); } else { - *p_start = type_start; /* after type_comment_prefix */ - *p_end = tok->cur; - return TYPE_COMMENT; + p_start = type_start; + p_end = tok->cur; + return MAKE_TYPE_COMMENT_TOKEN(TYPE_COMMENT, current_starting_col_offset, tok->col_offset); } } } + if (tok->tok_extra_tokens) { + tok_backup(tok, c); /* don't eat the newline or EOF */ + p_start = p; + p_end = tok->cur; + tok->comment_newline = blankline; + return MAKE_TOKEN(COMMENT); + } } if (tok->done == E_INTERACT_STOP) { - return ENDMARKER; + return MAKE_TOKEN(ENDMARKER); } /* Check for EOF and errors now */ if (c == EOF) { if (tok->level) { - return ERRORTOKEN; + return MAKE_TOKEN(ERRORTOKEN); } - return tok->done == E_EOF ? ENDMARKER : ERRORTOKEN; + return MAKE_TOKEN(tok->done == E_EOF ? ENDMARKER : ERRORTOKEN); } /* Identifier (most frequent token!) */ @@ -1651,6 +2078,9 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) } c = tok_nextc(tok); if (c == '"' || c == '\'') { + if (saw_f) { + goto f_string_quote; + } goto letter_quote; } } @@ -1662,11 +2092,11 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) } tok_backup(tok, c); if (nonascii && !verify_identifier(tok)) { - return ERRORTOKEN; + return MAKE_TOKEN(ERRORTOKEN); } - *p_start = tok->start; - *p_end = tok->cur; + p_start = tok->start; + p_end = tok->cur; /* async/await parsing block. */ if (tok->cur - tok->start == 5 && tok->start[0] == 'a') { @@ -1681,10 +2111,10 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) if (!tok->async_hacks || tok->async_def) { /* Always recognize the keywords. */ if (memcmp(tok->start, "async", 5) == 0) { - return ASYNC; + return MAKE_TOKEN(ASYNC); } if (memcmp(tok->start, "await", 5) == 0) { - return AWAIT; + return MAKE_TOKEN(AWAIT); } } else if (memcmp(tok->start, "async", 5) == 0) { @@ -1692,13 +2122,14 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) Look ahead one token to see if that is 'def'. */ struct tok_state ahead_tok; - const char *ahead_tok_start = NULL; - const char *ahead_tok_end = NULL; + struct token ahead_token; + _PyToken_Init(&ahead_token); int ahead_tok_kind; memcpy(&ahead_tok, tok, sizeof(ahead_tok)); - ahead_tok_kind = tok_get(&ahead_tok, &ahead_tok_start, - &ahead_tok_end); + ahead_tok_kind = tok_get_normal_mode(&ahead_tok, + current_tok, + &ahead_token); if (ahead_tok_kind == NAME && ahead_tok.cur - ahead_tok.start == 3 @@ -1708,29 +2139,49 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) returning a plain NAME token, return ASYNC. */ tok->async_def_indent = tok->indent; tok->async_def = 1; - return ASYNC; + _PyToken_Free(&ahead_token); + return MAKE_TOKEN(ASYNC); } + _PyToken_Free(&ahead_token); } } - return NAME; + return MAKE_TOKEN(NAME); + } + + if (c == '\r') { + c = tok_nextc(tok); } /* Newline */ if (c == '\n') { tok->atbol = 1; if (blankline || tok->level > 0) { + if (tok->tok_extra_tokens) { + if (tok->comment_newline) { + tok->comment_newline = 0; + } + p_start = tok->start; + p_end = tok->cur; + return MAKE_TOKEN(NL); + } goto nextline; } - *p_start = tok->start; - *p_end = tok->cur - 1; /* Leave '\n' out of the string */ + if (tok->comment_newline && tok->tok_extra_tokens) { + tok->comment_newline = 0; + p_start = tok->start; + p_end = tok->cur; + return MAKE_TOKEN(NL); + } + p_start = tok->start; + p_end = tok->cur - 1; /* Leave '\n' out of the string */ tok->cont_line = 0; if (tok->async_def) { /* We're somewhere inside an 'async def' function, and we've encountered a NEWLINE after its signature. */ tok->async_def_nl = 1; } - return NEWLINE; + return MAKE_TOKEN(NEWLINE); } /* Period or number starting with period? */ @@ -1741,9 +2192,9 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) } else if (c == '.') { c = tok_nextc(tok); if (c == '.') { - *p_start = tok->start; - *p_end = tok->cur; - return ELLIPSIS; + p_start = tok->start; + p_end = tok->cur; + return MAKE_TOKEN(ELLIPSIS); } else { tok_backup(tok, c); @@ -1753,9 +2204,9 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) else { tok_backup(tok, c); } - *p_start = tok->start; - *p_end = tok->cur; - return DOT; + p_start = tok->start; + p_end = tok->cur; + return MAKE_TOKEN(DOT); } /* Number */ @@ -1772,14 +2223,14 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) } if (!isxdigit(c)) { tok_backup(tok, c); - return syntaxerror(tok, "invalid hexadecimal literal"); + return MAKE_TOKEN(syntaxerror(tok, "invalid hexadecimal literal")); } do { c = tok_nextc(tok); } while (isxdigit(c)); } while (c == '_'); if (!verify_end_of_number(tok, c, "hexadecimal")) { - return ERRORTOKEN; + return MAKE_TOKEN(ERRORTOKEN); } } else if (c == 'o' || c == 'O') { @@ -1791,12 +2242,12 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) } if (c < '0' || c >= '8') { if (isdigit(c)) { - return syntaxerror(tok, - "invalid digit '%c' in octal literal", c); + return MAKE_TOKEN(syntaxerror(tok, + "invalid digit '%c' in octal literal", c)); } else { tok_backup(tok, c); - return syntaxerror(tok, "invalid octal literal"); + return MAKE_TOKEN(syntaxerror(tok, "invalid octal literal")); } } do { @@ -1804,11 +2255,11 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) } while ('0' <= c && c < '8'); } while (c == '_'); if (isdigit(c)) { - return syntaxerror(tok, - "invalid digit '%c' in octal literal", c); + return MAKE_TOKEN(syntaxerror(tok, + "invalid digit '%c' in octal literal", c)); } if (!verify_end_of_number(tok, c, "octal")) { - return ERRORTOKEN; + return MAKE_TOKEN(ERRORTOKEN); } } else if (c == 'b' || c == 'B') { @@ -1820,12 +2271,11 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) } if (c != '0' && c != '1') { if (isdigit(c)) { - return syntaxerror(tok, - "invalid digit '%c' in binary literal", c); + return MAKE_TOKEN(syntaxerror(tok, "invalid digit '%c' in binary literal", c)); } else { tok_backup(tok, c); - return syntaxerror(tok, "invalid binary literal"); + return MAKE_TOKEN(syntaxerror(tok, "invalid binary literal")); } } do { @@ -1833,11 +2283,10 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) } while (c == '0' || c == '1'); } while (c == '_'); if (isdigit(c)) { - return syntaxerror(tok, - "invalid digit '%c' in binary literal", c); + return MAKE_TOKEN(syntaxerror(tok, "invalid digit '%c' in binary literal", c)); } if (!verify_end_of_number(tok, c, "binary")) { - return ERRORTOKEN; + return MAKE_TOKEN(ERRORTOKEN); } } else { @@ -1849,7 +2298,7 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) c = tok_nextc(tok); if (!isdigit(c)) { tok_backup(tok, c); - return syntaxerror(tok, "invalid decimal literal"); + return MAKE_TOKEN(syntaxerror(tok, "invalid decimal literal")); } } if (c != '0') { @@ -1862,7 +2311,7 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) nonzero = 1; c = tok_decimal_tail(tok); if (c == 0) { - return ERRORTOKEN; + return MAKE_TOKEN(ERRORTOKEN); } } if (c == '.') { @@ -1875,18 +2324,18 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) else if (c == 'j' || c == 'J') { goto imaginary; } - else if (nonzero) { + else if (nonzero && !tok->tok_extra_tokens) { /* Old-style octal: now disallowed. */ tok_backup(tok, c); - return syntaxerror_known_range( + return MAKE_TOKEN(syntaxerror_known_range( tok, (int)(tok->start + 1 - tok->line_start), (int)(zeros_end - tok->line_start), "leading zeros in decimal integer " "literals are not permitted; " - "use an 0o prefix for octal integers"); + "use an 0o prefix for octal integers")); } if (!verify_end_of_number(tok, c, "decimal")) { - return ERRORTOKEN; + return MAKE_TOKEN(ERRORTOKEN); } } } @@ -1894,7 +2343,7 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) /* Decimal */ c = tok_decimal_tail(tok); if (c == 0) { - return ERRORTOKEN; + return MAKE_TOKEN(ERRORTOKEN); } { /* Accept floating point numbers. */ @@ -1905,7 +2354,7 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) if (isdigit(c)) { c = tok_decimal_tail(tok); if (c == 0) { - return ERRORTOKEN; + return MAKE_TOKEN(ERRORTOKEN); } } } @@ -1919,21 +2368,21 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) c = tok_nextc(tok); if (!isdigit(c)) { tok_backup(tok, c); - return syntaxerror(tok, "invalid decimal literal"); + return MAKE_TOKEN(syntaxerror(tok, "invalid decimal literal")); } } else if (!isdigit(c)) { tok_backup(tok, c); if (!verify_end_of_number(tok, e, "decimal")) { - return ERRORTOKEN; + return MAKE_TOKEN(ERRORTOKEN); } tok_backup(tok, e); - *p_start = tok->start; - *p_end = tok->cur; - return NUMBER; + p_start = tok->start; + p_end = tok->cur; + return MAKE_TOKEN(NUMBER); } c = tok_decimal_tail(tok); if (c == 0) { - return ERRORTOKEN; + return MAKE_TOKEN(ERRORTOKEN); } } if (c == 'j' || c == 'J') { @@ -1941,18 +2390,85 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) imaginary: c = tok_nextc(tok); if (!verify_end_of_number(tok, c, "imaginary")) { - return ERRORTOKEN; + return MAKE_TOKEN(ERRORTOKEN); } } else if (!verify_end_of_number(tok, c, "decimal")) { - return ERRORTOKEN; + return MAKE_TOKEN(ERRORTOKEN); } } } tok_backup(tok, c); - *p_start = tok->start; - *p_end = tok->cur; - return NUMBER; + p_start = tok->start; + p_end = tok->cur; + return MAKE_TOKEN(NUMBER); + } + + f_string_quote: + if (((tolower(*tok->start) == 'f' || tolower(*tok->start) == 'r') && (c == '\'' || c == '"'))) { + int quote = c; + int quote_size = 1; /* 1 or 3 */ + + /* Nodes of type STRING, especially multi line strings + must be handled differently in order to get both + the starting line number and the column offset right. + (cf. issue 16806) */ + tok->first_lineno = tok->lineno; + tok->multi_line_start = tok->line_start; + + /* Find the quote size and start of string */ + int after_quote = tok_nextc(tok); + if (after_quote == quote) { + int after_after_quote = tok_nextc(tok); + if (after_after_quote == quote) { + quote_size = 3; + } + else { + // TODO: Check this + tok_backup(tok, after_after_quote); + tok_backup(tok, after_quote); + } + } + if (after_quote != quote) { + tok_backup(tok, after_quote); + } + + + p_start = tok->start; + p_end = tok->cur; + if (tok->tok_mode_stack_index + 1 >= MAXFSTRINGLEVEL) { + return MAKE_TOKEN(syntaxerror(tok, "too many nested f-strings")); + } + tokenizer_mode *the_current_tok = TOK_NEXT_MODE(tok); + the_current_tok->kind = TOK_FSTRING_MODE; + the_current_tok->f_string_quote = quote; + the_current_tok->f_string_quote_size = quote_size; + the_current_tok->f_string_start = tok->start; + the_current_tok->f_string_multi_line_start = tok->line_start; + the_current_tok->f_string_line_start = tok->lineno; + the_current_tok->f_string_start_offset = -1; + the_current_tok->f_string_multi_line_start_offset = -1; + the_current_tok->last_expr_buffer = NULL; + the_current_tok->last_expr_size = 0; + the_current_tok->last_expr_end = -1; + the_current_tok->f_string_debug = 0; + + switch (*tok->start) { + case 'F': + case 'f': + the_current_tok->f_string_raw = tolower(*(tok->start + 1)) == 'r'; + break; + case 'R': + case 'r': + the_current_tok->f_string_raw = 1; + break; + default: + Py_UNREACHABLE(); + } + + the_current_tok->curly_bracket_depth = 0; + the_current_tok->curly_bracket_expr_start_depth = -1; + return MAKE_TOKEN(FSTRING_START); } letter_quote: @@ -1987,8 +2503,12 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) /* Get rest of string */ while (end_quote_size != quote_size) { c = tok_nextc(tok); - if (tok->done == E_DECODE) + if (tok->done == E_ERROR) { + return MAKE_TOKEN(ERRORTOKEN); + } + if (tok->done == E_DECODE) { break; + } if (c == EOF || (quote_size == 1 && c == '\n')) { assert(tok->multi_line_start != NULL); // shift the tok_state's location into @@ -1999,13 +2519,27 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) tok->line_start = tok->multi_line_start; int start = tok->lineno; tok->lineno = tok->first_lineno; + + if (INSIDE_FSTRING(tok)) { + /* When we are in an f-string, before raising the + * unterminated string literal error, check whether + * does the initial quote matches with f-strings quotes + * and if it is, then this must be a missing '}' token + * so raise the proper error */ + tokenizer_mode *the_current_tok = TOK_GET_MODE(tok); + if (the_current_tok->f_string_quote == quote && + the_current_tok->f_string_quote_size == quote_size) { + return MAKE_TOKEN(syntaxerror(tok, "f-string: expecting '}'", start)); + } + } + if (quote_size == 3) { syntaxerror(tok, "unterminated triple-quoted string literal" " (detected at line %d)", start); if (c != '\n') { tok->done = E_EOFS; } - return ERRORTOKEN; + return MAKE_TOKEN(ERRORTOKEN); } else { syntaxerror(tok, "unterminated string literal (detected at" @@ -2013,7 +2547,7 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) if (c != '\n') { tok->done = E_EOLS; } - return ERRORTOKEN; + return MAKE_TOKEN(ERRORTOKEN); } } if (c == quote) { @@ -2022,41 +2556,66 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) else { end_quote_size = 0; if (c == '\\') { - tok_nextc(tok); /* skip escaped char */ + c = tok_nextc(tok); /* skip escaped char */ + if (c == '\r') { + c = tok_nextc(tok); + } } } } - *p_start = tok->start; - *p_end = tok->cur; - return STRING; + p_start = tok->start; + p_end = tok->cur; + return MAKE_TOKEN(STRING); } /* Line continuation */ if (c == '\\') { if ((c = tok_continuation_line(tok)) == -1) { - return ERRORTOKEN; + return MAKE_TOKEN(ERRORTOKEN); } tok->cont_line = 1; goto again; /* Read next line */ } + /* Punctuation character */ + int is_punctuation = (c == ':' || c == '}' || c == '!' || c == '{'); + if (is_punctuation && INSIDE_FSTRING(tok) && INSIDE_FSTRING_EXPR(current_tok)) { + /* This code block gets executed before the curly_bracket_depth is incremented + * by the `{` case, so for ensuring that we are on the 0th level, we need + * to adjust it manually */ + int cursor = current_tok->curly_bracket_depth - (c != '{'); + if (cursor == 0 && !update_fstring_expr(tok, c)) { + return MAKE_TOKEN(ENDMARKER); + } + if (cursor == 0 && c != '{' && set_fstring_expr(tok, token, c)) { + return MAKE_TOKEN(ERRORTOKEN); + } + + if (c == ':' && cursor == current_tok->curly_bracket_expr_start_depth) { + current_tok->kind = TOK_FSTRING_MODE; + p_start = tok->start; + p_end = tok->cur; + return MAKE_TOKEN(_PyToken_OneChar(c)); + } + } + /* Check for two-character token */ { int c2 = tok_nextc(tok); - int token = PyToken_TwoChars(c, c2); - if (token != OP) { + int current_token = _PyToken_TwoChars(c, c2); + if (current_token != OP) { int c3 = tok_nextc(tok); - int token3 = PyToken_ThreeChars(c, c2, c3); - if (token3 != OP) { - token = token3; + int current_token3 = _PyToken_ThreeChars(c, c2, c3); + if (current_token3 != OP) { + current_token = current_token3; } else { tok_backup(tok, c3); } - *p_start = tok->start; - *p_end = tok->cur; - return token; + p_start = tok->start; + p_end = tok->cur; + return MAKE_TOKEN(current_token); } tok_backup(tok, c2); } @@ -2067,58 +2626,289 @@ tok_get(struct tok_state *tok, const char **p_start, const char **p_end) case '[': case '{': if (tok->level >= MAXLEVEL) { - return syntaxerror(tok, "too many nested parentheses"); + return MAKE_TOKEN(syntaxerror(tok, "too many nested parentheses")); } tok->parenstack[tok->level] = c; tok->parenlinenostack[tok->level] = tok->lineno; tok->parencolstack[tok->level] = (int)(tok->start - tok->line_start); tok->level++; + if (INSIDE_FSTRING(tok)) { + current_tok->curly_bracket_depth++; + } break; case ')': case ']': case '}': - if (!tok->level) { - return syntaxerror(tok, "unmatched '%c'", c); - } - tok->level--; - int opening = tok->parenstack[tok->level]; - if (!((opening == '(' && c == ')') || - (opening == '[' && c == ']') || - (opening == '{' && c == '}'))) - { - if (tok->parenlinenostack[tok->level] != tok->lineno) { - return syntaxerror(tok, - "closing parenthesis '%c' does not match " - "opening parenthesis '%c' on line %d", - c, opening, tok->parenlinenostack[tok->level]); + if (INSIDE_FSTRING(tok) && !current_tok->curly_bracket_depth && c == '}') { + return MAKE_TOKEN(syntaxerror(tok, "f-string: single '}' is not allowed")); + } + if (!tok->tok_extra_tokens && !tok->level) { + return MAKE_TOKEN(syntaxerror(tok, "unmatched '%c'", c)); + } + if (tok->level > 0) { + tok->level--; + int opening = tok->parenstack[tok->level]; + if (!tok->tok_extra_tokens && !((opening == '(' && c == ')') || + (opening == '[' && c == ']') || + (opening == '{' && c == '}'))) { + /* If the opening bracket belongs to an f-string's expression + part (e.g. f"{)}") and the closing bracket is an arbitrary + nested expression, then instead of matching a different + syntactical construct with it; we'll throw an unmatched + parentheses error. */ + if (INSIDE_FSTRING(tok) && opening == '{') { + assert(current_tok->curly_bracket_depth >= 0); + int previous_bracket = current_tok->curly_bracket_depth - 1; + if (previous_bracket == current_tok->curly_bracket_expr_start_depth) { + return MAKE_TOKEN(syntaxerror(tok, "f-string: unmatched '%c'", c)); + } + } + if (tok->parenlinenostack[tok->level] != tok->lineno) { + return MAKE_TOKEN(syntaxerror(tok, + "closing parenthesis '%c' does not match " + "opening parenthesis '%c' on line %d", + c, opening, tok->parenlinenostack[tok->level])); + } + else { + return MAKE_TOKEN(syntaxerror(tok, + "closing parenthesis '%c' does not match " + "opening parenthesis '%c'", + c, opening)); + } } - else { - return syntaxerror(tok, - "closing parenthesis '%c' does not match " - "opening parenthesis '%c'", - c, opening); + } + + if (INSIDE_FSTRING(tok)) { + current_tok->curly_bracket_depth--; + if (c == '}' && current_tok->curly_bracket_depth == current_tok->curly_bracket_expr_start_depth) { + current_tok->curly_bracket_expr_start_depth--; + current_tok->kind = TOK_FSTRING_MODE; + current_tok->f_string_debug = 0; } } break; + default: + break; } if (!Py_UNICODE_ISPRINTABLE(c)) { - char hex[9]; - (void)PyOS_snprintf(hex, sizeof(hex), "%04X", c); - return syntaxerror(tok, "invalid non-printable character U+%s", hex); + return MAKE_TOKEN(syntaxerror(tok, "invalid non-printable character U+%04X", c)); + } + + if( c == '=' && INSIDE_FSTRING_EXPR(current_tok)) { + current_tok->f_string_debug = 1; } /* Punctuation character */ - *p_start = tok->start; - *p_end = tok->cur; - return PyToken_OneChar(c); + p_start = tok->start; + p_end = tok->cur; + return MAKE_TOKEN(_PyToken_OneChar(c)); +} + +static int +tok_get_fstring_mode(struct tok_state *tok, tokenizer_mode* current_tok, struct token *token) +{ + const char *p_start = NULL; + const char *p_end = NULL; + int end_quote_size = 0; + int unicode_escape = 0; + + tok->start = tok->cur; + tok->first_lineno = tok->lineno; + tok->starting_col_offset = tok->col_offset; + + // If we start with a bracket, we defer to the normal mode as there is nothing for us to tokenize + // before it. + int start_char = tok_nextc(tok); + if (start_char == '{') { + int peek1 = tok_nextc(tok); + tok_backup(tok, peek1); + tok_backup(tok, start_char); + if (peek1 != '{') { + current_tok->curly_bracket_expr_start_depth++; + if (current_tok->curly_bracket_expr_start_depth >= MAX_EXPR_NESTING) { + return MAKE_TOKEN(syntaxerror(tok, "f-string: expressions nested too deeply")); + } + TOK_GET_MODE(tok)->kind = TOK_REGULAR_MODE; + return tok_get_normal_mode(tok, current_tok, token); + } + } + else { + tok_backup(tok, start_char); + } + + // Check if we are at the end of the string + for (int i = 0; i < current_tok->f_string_quote_size; i++) { + int quote = tok_nextc(tok); + if (quote != current_tok->f_string_quote) { + tok_backup(tok, quote); + goto f_string_middle; + } + } + + if (current_tok->last_expr_buffer != NULL) { + PyMem_Free(current_tok->last_expr_buffer); + current_tok->last_expr_buffer = NULL; + current_tok->last_expr_size = 0; + current_tok->last_expr_end = -1; + } + + p_start = tok->start; + p_end = tok->cur; + tok->tok_mode_stack_index--; + return MAKE_TOKEN(FSTRING_END); + +f_string_middle: + + // TODO: This is a bit of a hack, but it works for now. We need to find a better way to handle + // this. + tok->multi_line_start = tok->line_start; + while (end_quote_size != current_tok->f_string_quote_size) { + int c = tok_nextc(tok); + if (tok->done == E_ERROR) { + return MAKE_TOKEN(ERRORTOKEN); + } + if (c == EOF || (current_tok->f_string_quote_size == 1 && c == '\n')) { + if (tok->decoding_erred) { + return MAKE_TOKEN(ERRORTOKEN); + } + + assert(tok->multi_line_start != NULL); + // shift the tok_state's location into + // the start of string, and report the error + // from the initial quote character + tok->cur = (char *)current_tok->f_string_start; + tok->cur++; + tok->line_start = current_tok->f_string_multi_line_start; + int start = tok->lineno; + + tokenizer_mode *the_current_tok = TOK_GET_MODE(tok); + tok->lineno = the_current_tok->f_string_line_start; + + if (current_tok->f_string_quote_size == 3) { + return MAKE_TOKEN(syntaxerror(tok, + "unterminated triple-quoted f-string literal" + " (detected at line %d)", start)); + } + else { + return MAKE_TOKEN(syntaxerror(tok, + "unterminated f-string literal (detected at" + " line %d)", start)); + } + } + + if (c == current_tok->f_string_quote) { + end_quote_size += 1; + continue; + } else { + end_quote_size = 0; + } + + int in_format_spec = ( + current_tok->last_expr_end != -1 + && + INSIDE_FSTRING_EXPR(current_tok) + ); + if (c == '{') { + int peek = tok_nextc(tok); + if (peek != '{' || in_format_spec) { + tok_backup(tok, peek); + tok_backup(tok, c); + current_tok->curly_bracket_expr_start_depth++; + if (current_tok->curly_bracket_expr_start_depth >= MAX_EXPR_NESTING) { + return MAKE_TOKEN(syntaxerror(tok, "f-string: expressions nested too deeply")); + } + TOK_GET_MODE(tok)->kind = TOK_REGULAR_MODE; + p_start = tok->start; + p_end = tok->cur; + } else { + p_start = tok->start; + p_end = tok->cur - 1; + } + return MAKE_TOKEN(FSTRING_MIDDLE); + } else if (c == '}') { + if (unicode_escape) { + p_start = tok->start; + p_end = tok->cur; + return MAKE_TOKEN(FSTRING_MIDDLE); + } + int peek = tok_nextc(tok); + + // The tokenizer can only be in the format spec if we have already completed the expression + // scanning (indicated by the end of the expression being set) and we are not at the top level + // of the bracket stack (-1 is the top level). Since format specifiers can't legally use double + // brackets, we can bypass it here. + if (peek == '}' && !in_format_spec) { + p_start = tok->start; + p_end = tok->cur - 1; + } else { + tok_backup(tok, peek); + tok_backup(tok, c); + TOK_GET_MODE(tok)->kind = TOK_REGULAR_MODE; + p_start = tok->start; + p_end = tok->cur; + } + return MAKE_TOKEN(FSTRING_MIDDLE); + } else if (c == '\\') { + int peek = tok_nextc(tok); + if (peek == '\r') { + peek = tok_nextc(tok); + } + // Special case when the backslash is right before a curly + // brace. We have to restore and return the control back + // to the loop for the next iteration. + if (peek == '{' || peek == '}') { + if (!current_tok->f_string_raw) { + if (warn_invalid_escape_sequence(tok, peek)) { + return MAKE_TOKEN(ERRORTOKEN); + } + } + tok_backup(tok, peek); + continue; + } + + if (!current_tok->f_string_raw) { + if (peek == 'N') { + /* Handle named unicode escapes (\N{BULLET}) */ + peek = tok_nextc(tok); + if (peek == '{') { + unicode_escape = 1; + } else { + tok_backup(tok, peek); + } + } + } /* else { + skip the escaped character + }*/ + } + } + + // Backup the f-string quotes to emit a final FSTRING_MIDDLE and + // add the quotes to the FSTRING_END in the next tokenizer iteration. + for (int i = 0; i < current_tok->f_string_quote_size; i++) { + tok_backup(tok, current_tok->f_string_quote); + } + p_start = tok->start; + p_end = tok->cur; + return MAKE_TOKEN(FSTRING_MIDDLE); +} + + +static int +tok_get(struct tok_state *tok, struct token *token) +{ + tokenizer_mode *current_tok = TOK_GET_MODE(tok); + if (current_tok->kind == TOK_REGULAR_MODE) { + return tok_get_normal_mode(tok, current_tok, token); + } else { + return tok_get_fstring_mode(tok, current_tok, token); + } } int -_PyTokenizer_Get(struct tok_state *tok, - const char **p_start, const char **p_end) +_PyTokenizer_Get(struct tok_state *tok, struct token *token) { - int result = tok_get(tok, p_start, p_end); + int result = tok_get(tok, token); if (tok->decoding_erred) { result = ERRORTOKEN; tok->done = E_DECODE; @@ -2174,8 +2964,6 @@ _PyTokenizer_FindEncodingFilename(int fd, PyObject *filename) { struct tok_state *tok; FILE *fp; - const char *p_start = NULL; - const char *p_end = NULL; char *encoding = NULL; fp = fdopen_borrow(fd); @@ -2188,8 +2976,7 @@ _PyTokenizer_FindEncodingFilename(int fd, PyObject *filename) return NULL; } if (filename != NULL) { - Py_INCREF(filename); - tok->filename = filename; + tok->filename = Py_NewRef(filename); } else { tok->filename = PyUnicode_FromString("<string>"); @@ -2199,11 +2986,14 @@ _PyTokenizer_FindEncodingFilename(int fd, PyObject *filename) return encoding; } } + struct token token; // We don't want to report warnings here because it could cause infinite recursion // if fetching the encoding shows a warning. tok->report_warnings = 0; while (tok->lineno < 2 && tok->done == E_OK) { - _PyTokenizer_Get(tok, &p_start, &p_end); + _PyToken_Init(&token); + _PyTokenizer_Get(tok, &token); + _PyToken_Free(&token); } fclose(fp); if (tok->encoding) { diff --git a/Parser/tokenizer.h b/Parser/tokenizer.h index d9a5f457..1e1daa36 100644 --- a/Parser/tokenizer.h +++ b/Parser/tokenizer.h @@ -8,10 +8,11 @@ extern "C" { /* Tokenizer interface */ -#include "token.h" /* For token types */ +#include "pycore_token.h" /* For token types */ -#define MAXINDENT 100 /* Max indentation level */ -#define MAXLEVEL 200 /* Max parentheses level */ +#define MAXINDENT 100 /* Max indentation level */ +#define MAXLEVEL 200 /* Max parentheses level */ +#define MAXFSTRINGLEVEL 150 /* Max f-string nesting level */ enum decoding_state { STATE_INIT, @@ -20,18 +21,54 @@ enum decoding_state { }; enum interactive_underflow_t { - /* Normal mode of operation: return a new token when asked in interactie mode */ + /* Normal mode of operation: return a new token when asked in interactive mode */ IUNDERFLOW_NORMAL, /* Forcefully return ENDMARKER when asked for a new token in interactive mode. This * can be used to prevent the tokenizer to prompt the user for new tokens */ IUNDERFLOW_STOP, }; +struct token { + int level; + int lineno, col_offset, end_lineno, end_col_offset; + const char *start, *end; + PyObject *metadata; +}; + +enum tokenizer_mode_kind_t { + TOK_REGULAR_MODE, + TOK_FSTRING_MODE, +}; + +#define MAX_EXPR_NESTING 3 + +typedef struct _tokenizer_mode { + enum tokenizer_mode_kind_t kind; + + int curly_bracket_depth; + int curly_bracket_expr_start_depth; + + char f_string_quote; + int f_string_quote_size; + int f_string_raw; + const char* f_string_start; + const char* f_string_multi_line_start; + int f_string_line_start; + + Py_ssize_t f_string_start_offset; + Py_ssize_t f_string_multi_line_start_offset; + + Py_ssize_t last_expr_size; + Py_ssize_t last_expr_end; + char* last_expr_buffer; + int f_string_debug; +} tokenizer_mode; + /* Tokenizer state */ struct tok_state { /* Input state; buf <= cur <= inp <= end */ /* NB an entire line is held in the buffer */ - char *buf; /* Input buffer, or NULL; malloc'ed if fp != NULL */ + char *buf; /* Input buffer, or NULL; malloc'ed if fp != NULL or readline != NULL */ char *cur; /* Next character in buffer */ char *inp; /* End of data in buffer */ int fp_interactive; /* If the file descriptor is interactive */ @@ -51,6 +88,8 @@ struct tok_state { int lineno; /* Current line number */ int first_lineno; /* First line of a single line or multi line string expression (cf. issue 16806) */ + int starting_col_offset; /* The column offset at the beginning of a token */ + int col_offset; /* Current col offset */ int level; /* () [] {} Parentheses nesting level */ /* Used to allow free continuations inside them */ char parenstack[MAXLEVEL]; @@ -70,6 +109,7 @@ struct tok_state { expression (cf. issue 16806) */ PyObject *decoding_readline; /* open(...).readline */ PyObject *decoding_buffer; + PyObject *readline; /* readline() function */ const char* enc; /* Encoding for the current str. */ char* str; /* Source string being tokenized (if tokenizing from a string)*/ char* input; /* Tokenizer's newline translated copy of the string. */ @@ -85,14 +125,26 @@ struct tok_state { /* How to proceed when asked for a new token in interactive mode */ enum interactive_underflow_t interactive_underflow; int report_warnings; + // TODO: Factor this into its own thing + tokenizer_mode tok_mode_stack[MAXFSTRINGLEVEL]; + int tok_mode_stack_index; + int tok_extra_tokens; + int comment_newline; + int implicit_newline; +#ifdef Py_DEBUG + int debug; +#endif }; -extern struct tok_state *_PyTokenizer_FromString(const char *, int); -extern struct tok_state *_PyTokenizer_FromUTF8(const char *, int); +extern struct tok_state *_PyTokenizer_FromString(const char *, int, int); +extern struct tok_state *_PyTokenizer_FromUTF8(const char *, int, int); +extern struct tok_state *_PyTokenizer_FromReadline(PyObject*, const char*, int, int); extern struct tok_state *_PyTokenizer_FromFile(FILE *, const char*, const char *, const char *); extern void _PyTokenizer_Free(struct tok_state *); -extern int _PyTokenizer_Get(struct tok_state *, const char **, const char **); +extern void _PyToken_Free(struct token *); +extern void _PyToken_Init(struct token *); +extern int _PyTokenizer_Get(struct tok_state *, struct token *); #define tok_dump _Py_tok_dump diff --git a/Programs/_bootstrap_python.c b/Programs/_bootstrap_python.c index 6ecbf0c7..6c388fc7 100644 --- a/Programs/_bootstrap_python.c +++ b/Programs/_bootstrap_python.c @@ -2,7 +2,7 @@ /* Frozen modules bootstrap * * Limited and restricted Python interpreter to run - * "Tools/scripts/deepfreeze.py" on systems with no or older Python + * "Tools/build/deepfreeze.py" on systems with no or older Python * interpreter. */ @@ -12,8 +12,11 @@ /* Includes for frozen modules: */ #include "Python/frozen_modules/importlib._bootstrap.h" #include "Python/frozen_modules/importlib._bootstrap_external.h" +#include "Python/frozen_modules/zipimport.h" /* End includes */ +uint32_t _Py_next_func_version = 1; + /* Empty initializer for deepfrozen modules */ int _Py_Deepfreeze_Init(void) { @@ -30,6 +33,7 @@ _Py_Deepfreeze_Fini(void) static const struct _frozen bootstrap_modules[] = { {"_frozen_importlib", _Py_M__importlib__bootstrap, (int)sizeof(_Py_M__importlib__bootstrap)}, {"_frozen_importlib_external", _Py_M__importlib__bootstrap_external, (int)sizeof(_Py_M__importlib__bootstrap_external)}, + {"zipimport", _Py_M__zipimport, (int)sizeof(_Py_M__zipimport)}, {0, 0, 0} /* bootstrap sentinel */ }; static const struct _frozen stdlib_modules[] = { diff --git a/Programs/_freeze_module.c b/Programs/_freeze_module.c index 7c4d60a5..e55f1d56 100644 --- a/Programs/_freeze_module.c +++ b/Programs/_freeze_module.c @@ -1,14 +1,14 @@ /* This is built as a stand-alone executable by the Makefile, and helps turn - modules into frozen modules (like Lib/importlib/_bootstrap.py - into Python/importlib.h). + modules into frozen modules. - This is used directly by Tools/scripts/freeze_modules.py, and indirectly by "make regen-frozen". + This is used directly by Tools/build/freeze_modules.py, and indirectly by "make regen-frozen". See Python/frozen.c for more info. Keep this file in sync with Programs/_freeze_module.py. */ + #include <Python.h> #include <marshal.h> #include "pycore_fileutils.h" // _Py_stat_struct @@ -22,6 +22,8 @@ #include <unistd.h> #endif +uint32_t _Py_next_func_version = 1; + /* Empty initializer for deepfrozen modules */ int _Py_Deepfreeze_Init(void) { diff --git a/Programs/_testembed.c b/Programs/_testembed.c index 13eae178..f78ba41f 100644 --- a/Programs/_testembed.c +++ b/Programs/_testembed.c @@ -1,7 +1,6 @@ #ifndef Py_BUILD_CORE_MODULE # define Py_BUILD_CORE_MODULE #endif -#define NEEDS_PY_IDENTIFIER /* Always enable assertion (even in release mode) */ #undef NDEBUG @@ -10,7 +9,6 @@ #include "pycore_initconfig.h" // _PyConfig_InitCompatConfig() #include "pycore_runtime.h" // _PyRuntime #include "pycore_import.h" // _PyImport_FrozenBootstrap -#include <Python.h> #include <inttypes.h> #include <stdio.h> #include <stdlib.h> // putenv() @@ -704,7 +702,8 @@ static int test_init_from_config(void) config.safe_path = 1; - config._isolated_interpreter = 1; + putenv("PYTHONINTMAXSTRDIGITS=6666"); + config.int_max_str_digits = 31337; init_from_config_clear(&config); @@ -771,6 +770,7 @@ static void set_most_env_vars(void) putenv("PYTHONIOENCODING=iso8859-1:replace"); putenv("PYTHONPLATLIBDIR=env_platlibdir"); putenv("PYTHONSAFEPATH=1"); + putenv("PYTHONINTMAXSTRDIGITS=4567"); } @@ -1889,7 +1889,14 @@ static int test_unicode_id_init(void) { // bpo-42882: Test that _PyUnicode_FromId() works // when Python is initialized multiples times. - _Py_IDENTIFIER(test_unicode_id_init); + + // This is equivalent to `_Py_IDENTIFIER(test_unicode_id_init)` + // but since `_Py_IDENTIFIER` is disabled when `Py_BUILD_CORE` + // is defined, it is manually expanded here. + static _Py_Identifier PyId_test_unicode_id_init = { + .string = "test_unicode_id_init", + .index = -1, + }; // Initialize Python once without using the identifier _testembed_Py_InitializeFromConfig(); @@ -1904,14 +1911,13 @@ static int test_unicode_id_init(void) str1 = _PyUnicode_FromId(&PyId_test_unicode_id_init); assert(str1 != NULL); - assert(Py_REFCNT(str1) == 1); + assert(_Py_IsImmortal(str1)); str2 = PyUnicode_FromString("test_unicode_id_init"); assert(str2 != NULL); assert(PyUnicode_Compare(str1, str2) == 0); - // str1 is a borrowed reference Py_DECREF(str2); Py_Finalize(); @@ -1920,6 +1926,18 @@ static int test_unicode_id_init(void) } +static int test_init_main_interpreter_settings(void) +{ + _testembed_Py_Initialize(); + (void) PyRun_SimpleStringFlags( + "import _testinternalcapi, json; " + "print(json.dumps(_testinternalcapi.get_interp_settings(0)))", + 0); + Py_Finalize(); + return 0; +} + + #ifndef MS_WINDOWS #include "test_frozenmain.h" // M_test_frozenmain @@ -2107,6 +2125,7 @@ static struct TestCase TestCases[] = { {"test_run_main_loop", test_run_main_loop}, {"test_get_argc_argv", test_get_argc_argv}, {"test_init_use_frozen_modules", test_init_use_frozen_modules}, + {"test_init_main_interpreter_settings", test_init_main_interpreter_settings}, // Audit {"test_open_code_hook", test_open_code_hook}, diff --git a/Programs/test_frozenmain.h b/Programs/test_frozenmain.h index 0b658000..cd9d1032 100644 --- a/Programs/test_frozenmain.h +++ b/Programs/test_frozenmain.h @@ -1,42 +1,38 @@ // Auto-generated by Programs/freeze_test_frozenmain.py unsigned char M_test_frozenmain[] = { 227,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0, - 0,0,0,0,0,243,176,0,0,0,151,0,100,0,100,1, + 0,0,0,0,0,243,162,0,0,0,151,0,100,0,100,1, 108,0,90,0,100,0,100,1,108,1,90,1,2,0,101,2, - 100,2,166,1,0,0,171,1,0,0,0,0,0,0,0,0, - 1,0,2,0,101,2,100,3,101,0,106,3,0,0,0,0, - 0,0,0,0,166,2,0,0,171,2,0,0,0,0,0,0, - 0,0,1,0,2,0,101,1,106,4,0,0,0,0,0,0, - 0,0,166,0,0,0,171,0,0,0,0,0,0,0,0,0, - 100,4,25,0,0,0,0,0,0,0,0,0,90,5,100,5, - 68,0,93,25,90,6,2,0,101,2,100,6,101,6,155,0, - 100,7,101,5,101,6,25,0,0,0,0,0,0,0,0,0, - 155,0,157,4,166,1,0,0,171,1,0,0,0,0,0,0, - 0,0,1,0,140,26,100,1,83,0,41,8,233,0,0,0, - 0,78,122,18,70,114,111,122,101,110,32,72,101,108,108,111, - 32,87,111,114,108,100,122,8,115,121,115,46,97,114,103,118, - 218,6,99,111,110,102,105,103,41,5,218,12,112,114,111,103, - 114,97,109,95,110,97,109,101,218,10,101,120,101,99,117,116, - 97,98,108,101,218,15,117,115,101,95,101,110,118,105,114,111, - 110,109,101,110,116,218,17,99,111,110,102,105,103,117,114,101, - 95,99,95,115,116,100,105,111,218,14,98,117,102,102,101,114, - 101,100,95,115,116,100,105,111,122,7,99,111,110,102,105,103, - 32,122,2,58,32,41,7,218,3,115,121,115,218,17,95,116, - 101,115,116,105,110,116,101,114,110,97,108,99,97,112,105,218, - 5,112,114,105,110,116,218,4,97,114,103,118,218,11,103,101, - 116,95,99,111,110,102,105,103,115,114,3,0,0,0,218,3, - 107,101,121,169,0,243,0,0,0,0,250,18,116,101,115,116, - 95,102,114,111,122,101,110,109,97,105,110,46,112,121,250,8, - 60,109,111,100,117,108,101,62,114,18,0,0,0,1,0,0, - 0,115,156,0,0,0,240,3,1,1,1,240,8,0,1,11, - 128,10,128,10,128,10,216,0,24,208,0,24,208,0,24,208, - 0,24,224,0,5,128,5,208,6,26,209,0,27,212,0,27, - 208,0,27,216,0,5,128,5,128,106,144,35,148,40,209,0, - 27,212,0,27,208,0,27,216,9,38,208,9,26,212,9,38, - 209,9,40,212,9,40,168,24,212,9,50,128,6,240,2,6, - 12,2,240,0,7,1,42,240,0,7,1,42,128,67,240,14, - 0,5,10,128,69,208,10,40,144,67,208,10,40,208,10,40, - 152,54,160,35,156,59,208,10,40,208,10,40,209,4,41,212, - 4,41,208,4,41,208,4,41,240,15,7,1,42,240,0,7, - 1,42,114,16,0,0,0, + 100,2,171,1,0,0,0,0,0,0,1,0,2,0,101,2, + 100,3,101,0,106,6,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,171,2,0,0,0,0,0,0, + 1,0,2,0,101,1,106,8,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,171,0,0,0,0,0, + 0,0,100,4,25,0,0,0,90,5,100,5,68,0,93,19, + 0,0,90,6,2,0,101,2,100,6,101,6,155,0,100,7, + 101,5,101,6,25,0,0,0,155,0,157,4,171,1,0,0, + 0,0,0,0,1,0,140,21,4,0,121,1,41,8,233,0, + 0,0,0,78,122,18,70,114,111,122,101,110,32,72,101,108, + 108,111,32,87,111,114,108,100,122,8,115,121,115,46,97,114, + 103,118,218,6,99,111,110,102,105,103,41,5,218,12,112,114, + 111,103,114,97,109,95,110,97,109,101,218,10,101,120,101,99, + 117,116,97,98,108,101,218,15,117,115,101,95,101,110,118,105, + 114,111,110,109,101,110,116,218,17,99,111,110,102,105,103,117, + 114,101,95,99,95,115,116,100,105,111,218,14,98,117,102,102, + 101,114,101,100,95,115,116,100,105,111,122,7,99,111,110,102, + 105,103,32,122,2,58,32,41,7,218,3,115,121,115,218,17, + 95,116,101,115,116,105,110,116,101,114,110,97,108,99,97,112, + 105,218,5,112,114,105,110,116,218,4,97,114,103,118,218,11, + 103,101,116,95,99,111,110,102,105,103,115,114,3,0,0,0, + 218,3,107,101,121,169,0,243,0,0,0,0,250,18,116,101, + 115,116,95,102,114,111,122,101,110,109,97,105,110,46,112,121, + 250,8,60,109,111,100,117,108,101,62,114,18,0,0,0,1, + 0,0,0,115,102,0,0,0,240,3,1,1,1,243,8,0, + 1,11,219,0,24,225,0,5,208,6,26,212,0,27,217,0, + 5,128,106,144,35,151,40,145,40,212,0,27,216,9,38,208, + 9,26,215,9,38,209,9,38,211,9,40,168,24,209,9,50, + 128,6,240,2,6,12,2,242,0,7,1,42,128,67,241,14, + 0,5,10,136,71,144,67,144,53,152,2,152,54,160,35,153, + 59,152,45,208,10,40,213,4,41,241,15,7,1,42,114,16, + 0,0,0, }; diff --git a/Python/Python-ast.c b/Python/Python-ast.c index f485af67..f8bb6124 100644 --- a/Python/Python-ast.c +++ b/Python/Python-ast.c @@ -131,6 +131,7 @@ void _PyAST_Fini(PyInterpreterState *interp) Py_CLEAR(state->Not_type); Py_CLEAR(state->Or_singleton); Py_CLEAR(state->Or_type); + Py_CLEAR(state->ParamSpec_type); Py_CLEAR(state->Pass_type); Py_CLEAR(state->Pow_singleton); Py_CLEAR(state->Pow_type); @@ -150,7 +151,10 @@ void _PyAST_Fini(PyInterpreterState *interp) Py_CLEAR(state->TryStar_type); Py_CLEAR(state->Try_type); Py_CLEAR(state->Tuple_type); + Py_CLEAR(state->TypeAlias_type); Py_CLEAR(state->TypeIgnore_type); + Py_CLEAR(state->TypeVarTuple_type); + Py_CLEAR(state->TypeVar_type); Py_CLEAR(state->UAdd_singleton); Py_CLEAR(state->UAdd_type); Py_CLEAR(state->USub_singleton); @@ -179,6 +183,7 @@ void _PyAST_Fini(PyInterpreterState *interp) Py_CLEAR(state->bases); Py_CLEAR(state->body); Py_CLEAR(state->boolop_type); + Py_CLEAR(state->bound); Py_CLEAR(state->cases); Py_CLEAR(state->cause); Py_CLEAR(state->cls); @@ -256,6 +261,8 @@ void _PyAST_Fini(PyInterpreterState *interp) Py_CLEAR(state->type_comment); Py_CLEAR(state->type_ignore_type); Py_CLEAR(state->type_ignores); + Py_CLEAR(state->type_param_type); + Py_CLEAR(state->type_params); Py_CLEAR(state->unaryop_type); Py_CLEAR(state->upper); Py_CLEAR(state->value); @@ -263,6 +270,8 @@ void _PyAST_Fini(PyInterpreterState *interp) Py_CLEAR(state->vararg); Py_CLEAR(state->withitem_type); + Py_CLEAR(_Py_INTERP_CACHED_OBJECT(interp, str_replace_inf)); + #if !defined(NDEBUG) state->initialized = -1; #else @@ -287,6 +296,7 @@ static int init_identifiers(struct ast_state *state) if ((state->attr = PyUnicode_InternFromString("attr")) == NULL) return 0; if ((state->bases = PyUnicode_InternFromString("bases")) == NULL) return 0; if ((state->body = PyUnicode_InternFromString("body")) == NULL) return 0; + if ((state->bound = PyUnicode_InternFromString("bound")) == NULL) return 0; if ((state->cases = PyUnicode_InternFromString("cases")) == NULL) return 0; if ((state->cause = PyUnicode_InternFromString("cause")) == NULL) return 0; if ((state->cls = PyUnicode_InternFromString("cls")) == NULL) return 0; @@ -352,6 +362,7 @@ static int init_identifiers(struct ast_state *state) if ((state->type = PyUnicode_InternFromString("type")) == NULL) return 0; if ((state->type_comment = PyUnicode_InternFromString("type_comment")) == NULL) return 0; if ((state->type_ignores = PyUnicode_InternFromString("type_ignores")) == NULL) return 0; + if ((state->type_params = PyUnicode_InternFromString("type_params")) == NULL) return 0; if ((state->upper = PyUnicode_InternFromString("upper")) == NULL) return 0; if ((state->value = PyUnicode_InternFromString("value")) == NULL) return 0; if ((state->values = PyUnicode_InternFromString("values")) == NULL) return 0; @@ -372,6 +383,7 @@ GENERATE_ASDL_SEQ_CONSTRUCTOR(withitem, withitem_ty) GENERATE_ASDL_SEQ_CONSTRUCTOR(match_case, match_case_ty) GENERATE_ASDL_SEQ_CONSTRUCTOR(pattern, pattern_ty) GENERATE_ASDL_SEQ_CONSTRUCTOR(type_ignore, type_ignore_ty) +GENERATE_ASDL_SEQ_CONSTRUCTOR(type_param, type_param_ty) static PyObject* ast2obj_mod(struct ast_state *state, void*); static const char * const Module_fields[]={ @@ -402,6 +414,7 @@ static const char * const FunctionDef_fields[]={ "decorator_list", "returns", "type_comment", + "type_params", }; static const char * const AsyncFunctionDef_fields[]={ "name", @@ -410,6 +423,7 @@ static const char * const AsyncFunctionDef_fields[]={ "decorator_list", "returns", "type_comment", + "type_params", }; static const char * const ClassDef_fields[]={ "name", @@ -417,6 +431,7 @@ static const char * const ClassDef_fields[]={ "keywords", "body", "decorator_list", + "type_params", }; static const char * const Return_fields[]={ "value", @@ -429,6 +444,11 @@ static const char * const Assign_fields[]={ "value", "type_comment", }; +static const char * const TypeAlias_fields[]={ + "name", + "type_params", + "value", +}; static const char * const AugAssign_fields[]={ "target", "op", @@ -755,6 +775,23 @@ static const char * const TypeIgnore_fields[]={ "lineno", "tag", }; +static const char * const type_param_attributes[] = { + "lineno", + "col_offset", + "end_lineno", + "end_col_offset", +}; +static PyObject* ast2obj_type_param(struct ast_state *state, void*); +static const char * const TypeVar_fields[]={ + "name", + "bound", +}; +static const char * const ParamSpec_fields[]={ + "name", +}; +static const char * const TypeVarTuple_fields[]={ + "name", +}; @@ -993,10 +1030,11 @@ static PyObject* ast2obj_list(struct ast_state *state, asdl_seq *seq, PyObject* static PyObject* ast2obj_object(struct ast_state *Py_UNUSED(state), void *o) { - if (!o) - o = Py_None; - Py_INCREF((PyObject*)o); - return (PyObject*)o; + PyObject *op = (PyObject*)o; + if (!op) { + op = Py_None; + } + return Py_NewRef(op); } #define ast2obj_constant ast2obj_object #define ast2obj_identifier ast2obj_object @@ -1018,9 +1056,11 @@ static int obj2ast_object(struct ast_state *Py_UNUSED(state), PyObject* obj, PyO *out = NULL; return -1; } - Py_INCREF(obj); + *out = Py_NewRef(obj); + } + else { + *out = NULL; } - *out = obj; return 0; } @@ -1030,8 +1070,7 @@ static int obj2ast_constant(struct ast_state *Py_UNUSED(state), PyObject* obj, P *out = NULL; return -1; } - Py_INCREF(obj); - *out = obj; + *out = Py_NewRef(obj); return 0; } @@ -1130,12 +1169,13 @@ init_types(struct ast_state *state) "FunctionType(expr* argtypes, expr returns)"); if (!state->FunctionType_type) return 0; state->stmt_type = make_type(state, "stmt", state->AST_type, NULL, 0, - "stmt = FunctionDef(identifier name, arguments args, stmt* body, expr* decorator_list, expr? returns, string? type_comment)\n" - " | AsyncFunctionDef(identifier name, arguments args, stmt* body, expr* decorator_list, expr? returns, string? type_comment)\n" - " | ClassDef(identifier name, expr* bases, keyword* keywords, stmt* body, expr* decorator_list)\n" + "stmt = FunctionDef(identifier name, arguments args, stmt* body, expr* decorator_list, expr? returns, string? type_comment, type_param* type_params)\n" + " | AsyncFunctionDef(identifier name, arguments args, stmt* body, expr* decorator_list, expr? returns, string? type_comment, type_param* type_params)\n" + " | ClassDef(identifier name, expr* bases, keyword* keywords, stmt* body, expr* decorator_list, type_param* type_params)\n" " | Return(expr? value)\n" " | Delete(expr* targets)\n" " | Assign(expr* targets, expr value, string? type_comment)\n" + " | TypeAlias(expr name, type_param* type_params, expr value)\n" " | AugAssign(expr target, operator op, expr value)\n" " | AnnAssign(expr target, expr annotation, expr? value, int simple)\n" " | For(expr target, expr iter, stmt* body, stmt* orelse, string? type_comment)\n" @@ -1165,8 +1205,8 @@ init_types(struct ast_state *state) -1) return 0; state->FunctionDef_type = make_type(state, "FunctionDef", state->stmt_type, - FunctionDef_fields, 6, - "FunctionDef(identifier name, arguments args, stmt* body, expr* decorator_list, expr? returns, string? type_comment)"); + FunctionDef_fields, 7, + "FunctionDef(identifier name, arguments args, stmt* body, expr* decorator_list, expr? returns, string? type_comment, type_param* type_params)"); if (!state->FunctionDef_type) return 0; if (PyObject_SetAttr(state->FunctionDef_type, state->returns, Py_None) == -1) @@ -1176,8 +1216,8 @@ init_types(struct ast_state *state) return 0; state->AsyncFunctionDef_type = make_type(state, "AsyncFunctionDef", state->stmt_type, - AsyncFunctionDef_fields, 6, - "AsyncFunctionDef(identifier name, arguments args, stmt* body, expr* decorator_list, expr? returns, string? type_comment)"); + AsyncFunctionDef_fields, 7, + "AsyncFunctionDef(identifier name, arguments args, stmt* body, expr* decorator_list, expr? returns, string? type_comment, type_param* type_params)"); if (!state->AsyncFunctionDef_type) return 0; if (PyObject_SetAttr(state->AsyncFunctionDef_type, state->returns, Py_None) == -1) @@ -1186,8 +1226,8 @@ init_types(struct ast_state *state) Py_None) == -1) return 0; state->ClassDef_type = make_type(state, "ClassDef", state->stmt_type, - ClassDef_fields, 5, - "ClassDef(identifier name, expr* bases, keyword* keywords, stmt* body, expr* decorator_list)"); + ClassDef_fields, 6, + "ClassDef(identifier name, expr* bases, keyword* keywords, stmt* body, expr* decorator_list, type_param* type_params)"); if (!state->ClassDef_type) return 0; state->Return_type = make_type(state, "Return", state->stmt_type, Return_fields, 1, @@ -1206,6 +1246,10 @@ init_types(struct ast_state *state) if (PyObject_SetAttr(state->Assign_type, state->type_comment, Py_None) == -1) return 0; + state->TypeAlias_type = make_type(state, "TypeAlias", state->stmt_type, + TypeAlias_fields, 3, + "TypeAlias(expr name, type_param* type_params, expr value)"); + if (!state->TypeAlias_type) return 0; state->AugAssign_type = make_type(state, "AugAssign", state->stmt_type, AugAssign_fields, 3, "AugAssign(expr target, operator op, expr value)"); @@ -1850,6 +1894,30 @@ init_types(struct ast_state *state) TypeIgnore_fields, 2, "TypeIgnore(int lineno, string tag)"); if (!state->TypeIgnore_type) return 0; + state->type_param_type = make_type(state, "type_param", state->AST_type, + NULL, 0, + "type_param = TypeVar(identifier name, expr? bound)\n" + " | ParamSpec(identifier name)\n" + " | TypeVarTuple(identifier name)"); + if (!state->type_param_type) return 0; + if (!add_attributes(state, state->type_param_type, type_param_attributes, + 4)) return 0; + state->TypeVar_type = make_type(state, "TypeVar", state->type_param_type, + TypeVar_fields, 2, + "TypeVar(identifier name, expr? bound)"); + if (!state->TypeVar_type) return 0; + if (PyObject_SetAttr(state->TypeVar_type, state->bound, Py_None) == -1) + return 0; + state->ParamSpec_type = make_type(state, "ParamSpec", + state->type_param_type, ParamSpec_fields, + 1, + "ParamSpec(identifier name)"); + if (!state->ParamSpec_type) return 0; + state->TypeVarTuple_type = make_type(state, "TypeVarTuple", + state->type_param_type, + TypeVarTuple_fields, 1, + "TypeVarTuple(identifier name)"); + if (!state->TypeVarTuple_type) return 0; state->recursion_depth = 0; state->recursion_limit = 0; @@ -1893,6 +1961,8 @@ static int obj2ast_pattern(struct ast_state *state, PyObject* obj, pattern_ty* out, PyArena* arena); static int obj2ast_type_ignore(struct ast_state *state, PyObject* obj, type_ignore_ty* out, PyArena* arena); +static int obj2ast_type_param(struct ast_state *state, PyObject* obj, + type_param_ty* out, PyArena* arena); mod_ty _PyAST_Module(asdl_stmt_seq * body, asdl_type_ignore_seq * type_ignores, @@ -1958,8 +2028,9 @@ _PyAST_FunctionType(asdl_expr_seq * argtypes, expr_ty returns, PyArena *arena) stmt_ty _PyAST_FunctionDef(identifier name, arguments_ty args, asdl_stmt_seq * body, asdl_expr_seq * decorator_list, expr_ty returns, string - type_comment, int lineno, int col_offset, int end_lineno, - int end_col_offset, PyArena *arena) + type_comment, asdl_type_param_seq * type_params, int lineno, + int col_offset, int end_lineno, int end_col_offset, PyArena + *arena) { stmt_ty p; if (!name) { @@ -1982,6 +2053,7 @@ _PyAST_FunctionDef(identifier name, arguments_ty args, asdl_stmt_seq * body, p->v.FunctionDef.decorator_list = decorator_list; p->v.FunctionDef.returns = returns; p->v.FunctionDef.type_comment = type_comment; + p->v.FunctionDef.type_params = type_params; p->lineno = lineno; p->col_offset = col_offset; p->end_lineno = end_lineno; @@ -1992,8 +2064,9 @@ _PyAST_FunctionDef(identifier name, arguments_ty args, asdl_stmt_seq * body, stmt_ty _PyAST_AsyncFunctionDef(identifier name, arguments_ty args, asdl_stmt_seq * body, asdl_expr_seq * decorator_list, expr_ty returns, - string type_comment, int lineno, int col_offset, int - end_lineno, int end_col_offset, PyArena *arena) + string type_comment, asdl_type_param_seq * type_params, + int lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena) { stmt_ty p; if (!name) { @@ -2016,6 +2089,7 @@ _PyAST_AsyncFunctionDef(identifier name, arguments_ty args, asdl_stmt_seq * p->v.AsyncFunctionDef.decorator_list = decorator_list; p->v.AsyncFunctionDef.returns = returns; p->v.AsyncFunctionDef.type_comment = type_comment; + p->v.AsyncFunctionDef.type_params = type_params; p->lineno = lineno; p->col_offset = col_offset; p->end_lineno = end_lineno; @@ -2026,8 +2100,8 @@ _PyAST_AsyncFunctionDef(identifier name, arguments_ty args, asdl_stmt_seq * stmt_ty _PyAST_ClassDef(identifier name, asdl_expr_seq * bases, asdl_keyword_seq * keywords, asdl_stmt_seq * body, asdl_expr_seq * decorator_list, - int lineno, int col_offset, int end_lineno, int end_col_offset, - PyArena *arena) + asdl_type_param_seq * type_params, int lineno, int col_offset, + int end_lineno, int end_col_offset, PyArena *arena) { stmt_ty p; if (!name) { @@ -2044,6 +2118,7 @@ _PyAST_ClassDef(identifier name, asdl_expr_seq * bases, asdl_keyword_seq * p->v.ClassDef.keywords = keywords; p->v.ClassDef.body = body; p->v.ClassDef.decorator_list = decorator_list; + p->v.ClassDef.type_params = type_params; p->lineno = lineno; p->col_offset = col_offset; p->end_lineno = end_lineno; @@ -2110,6 +2185,36 @@ _PyAST_Assign(asdl_expr_seq * targets, expr_ty value, string type_comment, int return p; } +stmt_ty +_PyAST_TypeAlias(expr_ty name, asdl_type_param_seq * type_params, expr_ty + value, int lineno, int col_offset, int end_lineno, int + end_col_offset, PyArena *arena) +{ + stmt_ty p; + if (!name) { + PyErr_SetString(PyExc_ValueError, + "field 'name' is required for TypeAlias"); + return NULL; + } + if (!value) { + PyErr_SetString(PyExc_ValueError, + "field 'value' is required for TypeAlias"); + return NULL; + } + p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = TypeAlias_kind; + p->v.TypeAlias.name = name; + p->v.TypeAlias.type_params = type_params; + p->v.TypeAlias.value = value; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; + return p; +} + stmt_ty _PyAST_AugAssign(expr_ty target, operator_ty op, expr_ty value, int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena) @@ -3602,6 +3707,73 @@ _PyAST_TypeIgnore(int lineno, string tag, PyArena *arena) return p; } +type_param_ty +_PyAST_TypeVar(identifier name, expr_ty bound, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena) +{ + type_param_ty p; + if (!name) { + PyErr_SetString(PyExc_ValueError, + "field 'name' is required for TypeVar"); + return NULL; + } + p = (type_param_ty)_PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = TypeVar_kind; + p->v.TypeVar.name = name; + p->v.TypeVar.bound = bound; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; + return p; +} + +type_param_ty +_PyAST_ParamSpec(identifier name, int lineno, int col_offset, int end_lineno, + int end_col_offset, PyArena *arena) +{ + type_param_ty p; + if (!name) { + PyErr_SetString(PyExc_ValueError, + "field 'name' is required for ParamSpec"); + return NULL; + } + p = (type_param_ty)_PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = ParamSpec_kind; + p->v.ParamSpec.name = name; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; + return p; +} + +type_param_ty +_PyAST_TypeVarTuple(identifier name, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena) +{ + type_param_ty p; + if (!name) { + PyErr_SetString(PyExc_ValueError, + "field 'name' is required for TypeVarTuple"); + return NULL; + } + p = (type_param_ty)_PyArena_Malloc(arena, sizeof(*p)); + if (!p) + return NULL; + p->kind = TypeVarTuple_kind; + p->v.TypeVarTuple.name = name; + p->lineno = lineno; + p->col_offset = col_offset; + p->end_lineno = end_lineno; + p->end_col_offset = end_col_offset; + return p; +} + PyObject* ast2obj_mod(struct ast_state *state, void* _o) @@ -3731,6 +3903,12 @@ ast2obj_stmt(struct ast_state *state, void* _o) if (PyObject_SetAttr(result, state->type_comment, value) == -1) goto failed; Py_DECREF(value); + value = ast2obj_list(state, (asdl_seq*)o->v.FunctionDef.type_params, + ast2obj_type_param); + if (!value) goto failed; + if (PyObject_SetAttr(result, state->type_params, value) == -1) + goto failed; + Py_DECREF(value); break; case AsyncFunctionDef_kind: tp = (PyTypeObject *)state->AsyncFunctionDef_type; @@ -3769,6 +3947,13 @@ ast2obj_stmt(struct ast_state *state, void* _o) if (PyObject_SetAttr(result, state->type_comment, value) == -1) goto failed; Py_DECREF(value); + value = ast2obj_list(state, + (asdl_seq*)o->v.AsyncFunctionDef.type_params, + ast2obj_type_param); + if (!value) goto failed; + if (PyObject_SetAttr(result, state->type_params, value) == -1) + goto failed; + Py_DECREF(value); break; case ClassDef_kind: tp = (PyTypeObject *)state->ClassDef_type; @@ -3803,6 +3988,12 @@ ast2obj_stmt(struct ast_state *state, void* _o) if (PyObject_SetAttr(result, state->decorator_list, value) == -1) goto failed; Py_DECREF(value); + value = ast2obj_list(state, (asdl_seq*)o->v.ClassDef.type_params, + ast2obj_type_param); + if (!value) goto failed; + if (PyObject_SetAttr(result, state->type_params, value) == -1) + goto failed; + Py_DECREF(value); break; case Return_kind: tp = (PyTypeObject *)state->Return_type; @@ -3846,6 +4037,27 @@ ast2obj_stmt(struct ast_state *state, void* _o) goto failed; Py_DECREF(value); break; + case TypeAlias_kind: + tp = (PyTypeObject *)state->TypeAlias_type; + result = PyType_GenericNew(tp, NULL, NULL); + if (!result) goto failed; + value = ast2obj_expr(state, o->v.TypeAlias.name); + if (!value) goto failed; + if (PyObject_SetAttr(result, state->name, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_list(state, (asdl_seq*)o->v.TypeAlias.type_params, + ast2obj_type_param); + if (!value) goto failed; + if (PyObject_SetAttr(result, state->type_params, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_expr(state, o->v.TypeAlias.value); + if (!value) goto failed; + if (PyObject_SetAttr(result, state->value, value) == -1) + goto failed; + Py_DECREF(value); + break; case AugAssign_kind: tp = (PyTypeObject *)state->AugAssign_type; result = PyType_GenericNew(tp, NULL, NULL); @@ -4732,14 +4944,11 @@ PyObject* ast2obj_expr_context(struct ast_state *state, expr_context_ty o) { switch(o) { case Load: - Py_INCREF(state->Load_singleton); - return state->Load_singleton; + return Py_NewRef(state->Load_singleton); case Store: - Py_INCREF(state->Store_singleton); - return state->Store_singleton; + return Py_NewRef(state->Store_singleton); case Del: - Py_INCREF(state->Del_singleton); - return state->Del_singleton; + return Py_NewRef(state->Del_singleton); } Py_UNREACHABLE(); } @@ -4747,11 +4956,9 @@ PyObject* ast2obj_boolop(struct ast_state *state, boolop_ty o) { switch(o) { case And: - Py_INCREF(state->And_singleton); - return state->And_singleton; + return Py_NewRef(state->And_singleton); case Or: - Py_INCREF(state->Or_singleton); - return state->Or_singleton; + return Py_NewRef(state->Or_singleton); } Py_UNREACHABLE(); } @@ -4759,44 +4966,31 @@ PyObject* ast2obj_operator(struct ast_state *state, operator_ty o) { switch(o) { case Add: - Py_INCREF(state->Add_singleton); - return state->Add_singleton; + return Py_NewRef(state->Add_singleton); case Sub: - Py_INCREF(state->Sub_singleton); - return state->Sub_singleton; + return Py_NewRef(state->Sub_singleton); case Mult: - Py_INCREF(state->Mult_singleton); - return state->Mult_singleton; + return Py_NewRef(state->Mult_singleton); case MatMult: - Py_INCREF(state->MatMult_singleton); - return state->MatMult_singleton; + return Py_NewRef(state->MatMult_singleton); case Div: - Py_INCREF(state->Div_singleton); - return state->Div_singleton; + return Py_NewRef(state->Div_singleton); case Mod: - Py_INCREF(state->Mod_singleton); - return state->Mod_singleton; + return Py_NewRef(state->Mod_singleton); case Pow: - Py_INCREF(state->Pow_singleton); - return state->Pow_singleton; + return Py_NewRef(state->Pow_singleton); case LShift: - Py_INCREF(state->LShift_singleton); - return state->LShift_singleton; + return Py_NewRef(state->LShift_singleton); case RShift: - Py_INCREF(state->RShift_singleton); - return state->RShift_singleton; + return Py_NewRef(state->RShift_singleton); case BitOr: - Py_INCREF(state->BitOr_singleton); - return state->BitOr_singleton; + return Py_NewRef(state->BitOr_singleton); case BitXor: - Py_INCREF(state->BitXor_singleton); - return state->BitXor_singleton; + return Py_NewRef(state->BitXor_singleton); case BitAnd: - Py_INCREF(state->BitAnd_singleton); - return state->BitAnd_singleton; + return Py_NewRef(state->BitAnd_singleton); case FloorDiv: - Py_INCREF(state->FloorDiv_singleton); - return state->FloorDiv_singleton; + return Py_NewRef(state->FloorDiv_singleton); } Py_UNREACHABLE(); } @@ -4804,17 +4998,13 @@ PyObject* ast2obj_unaryop(struct ast_state *state, unaryop_ty o) { switch(o) { case Invert: - Py_INCREF(state->Invert_singleton); - return state->Invert_singleton; + return Py_NewRef(state->Invert_singleton); case Not: - Py_INCREF(state->Not_singleton); - return state->Not_singleton; + return Py_NewRef(state->Not_singleton); case UAdd: - Py_INCREF(state->UAdd_singleton); - return state->UAdd_singleton; + return Py_NewRef(state->UAdd_singleton); case USub: - Py_INCREF(state->USub_singleton); - return state->USub_singleton; + return Py_NewRef(state->USub_singleton); } Py_UNREACHABLE(); } @@ -4822,35 +5012,25 @@ PyObject* ast2obj_cmpop(struct ast_state *state, cmpop_ty o) { switch(o) { case Eq: - Py_INCREF(state->Eq_singleton); - return state->Eq_singleton; + return Py_NewRef(state->Eq_singleton); case NotEq: - Py_INCREF(state->NotEq_singleton); - return state->NotEq_singleton; + return Py_NewRef(state->NotEq_singleton); case Lt: - Py_INCREF(state->Lt_singleton); - return state->Lt_singleton; + return Py_NewRef(state->Lt_singleton); case LtE: - Py_INCREF(state->LtE_singleton); - return state->LtE_singleton; + return Py_NewRef(state->LtE_singleton); case Gt: - Py_INCREF(state->Gt_singleton); - return state->Gt_singleton; + return Py_NewRef(state->Gt_singleton); case GtE: - Py_INCREF(state->GtE_singleton); - return state->GtE_singleton; + return Py_NewRef(state->GtE_singleton); case Is: - Py_INCREF(state->Is_singleton); - return state->Is_singleton; + return Py_NewRef(state->Is_singleton); case IsNot: - Py_INCREF(state->IsNot_singleton); - return state->IsNot_singleton; + return Py_NewRef(state->IsNot_singleton); case In: - Py_INCREF(state->In_singleton); - return state->In_singleton; + return Py_NewRef(state->In_singleton); case NotIn: - Py_INCREF(state->NotIn_singleton); - return state->NotIn_singleton; + return Py_NewRef(state->NotIn_singleton); } Py_UNREACHABLE(); } @@ -5469,6 +5649,85 @@ failed: return NULL; } +PyObject* +ast2obj_type_param(struct ast_state *state, void* _o) +{ + type_param_ty o = (type_param_ty)_o; + PyObject *result = NULL, *value = NULL; + PyTypeObject *tp; + if (!o) { + Py_RETURN_NONE; + } + if (++state->recursion_depth > state->recursion_limit) { + PyErr_SetString(PyExc_RecursionError, + "maximum recursion depth exceeded during ast construction"); + return 0; + } + switch (o->kind) { + case TypeVar_kind: + tp = (PyTypeObject *)state->TypeVar_type; + result = PyType_GenericNew(tp, NULL, NULL); + if (!result) goto failed; + value = ast2obj_identifier(state, o->v.TypeVar.name); + if (!value) goto failed; + if (PyObject_SetAttr(result, state->name, value) == -1) + goto failed; + Py_DECREF(value); + value = ast2obj_expr(state, o->v.TypeVar.bound); + if (!value) goto failed; + if (PyObject_SetAttr(result, state->bound, value) == -1) + goto failed; + Py_DECREF(value); + break; + case ParamSpec_kind: + tp = (PyTypeObject *)state->ParamSpec_type; + result = PyType_GenericNew(tp, NULL, NULL); + if (!result) goto failed; + value = ast2obj_identifier(state, o->v.ParamSpec.name); + if (!value) goto failed; + if (PyObject_SetAttr(result, state->name, value) == -1) + goto failed; + Py_DECREF(value); + break; + case TypeVarTuple_kind: + tp = (PyTypeObject *)state->TypeVarTuple_type; + result = PyType_GenericNew(tp, NULL, NULL); + if (!result) goto failed; + value = ast2obj_identifier(state, o->v.TypeVarTuple.name); + if (!value) goto failed; + if (PyObject_SetAttr(result, state->name, value) == -1) + goto failed; + Py_DECREF(value); + break; + } + value = ast2obj_int(state, o->lineno); + if (!value) goto failed; + if (PyObject_SetAttr(result, state->lineno, value) < 0) + goto failed; + Py_DECREF(value); + value = ast2obj_int(state, o->col_offset); + if (!value) goto failed; + if (PyObject_SetAttr(result, state->col_offset, value) < 0) + goto failed; + Py_DECREF(value); + value = ast2obj_int(state, o->end_lineno); + if (!value) goto failed; + if (PyObject_SetAttr(result, state->end_lineno, value) < 0) + goto failed; + Py_DECREF(value); + value = ast2obj_int(state, o->end_col_offset); + if (!value) goto failed; + if (PyObject_SetAttr(result, state->end_col_offset, value) < 0) + goto failed; + Py_DECREF(value); + state->recursion_depth--; + return result; +failed: + Py_XDECREF(value); + Py_XDECREF(result); + return NULL; +} + int obj2ast_mod(struct ast_state *state, PyObject* obj, mod_ty* out, PyArena* arena) @@ -5495,10 +5754,12 @@ obj2ast_mod(struct ast_state *state, PyObject* obj, mod_ty* out, PyArena* arena) return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from Module"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -5511,8 +5772,7 @@ obj2ast_mod(struct ast_state *state, PyObject* obj, mod_ty* out, PyArena* arena) if (body == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'Module' node")) { goto failed; } @@ -5532,10 +5792,12 @@ obj2ast_mod(struct ast_state *state, PyObject* obj, mod_ty* out, PyArena* arena) return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"type_ignores\" missing from Module"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -5548,8 +5810,7 @@ obj2ast_mod(struct ast_state *state, PyObject* obj, mod_ty* out, PyArena* arena) if (type_ignores == NULL) goto failed; for (i = 0; i < len; i++) { type_ignore_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'Module' node")) { goto failed; } @@ -5581,10 +5842,12 @@ obj2ast_mod(struct ast_state *state, PyObject* obj, mod_ty* out, PyArena* arena) return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from Interactive"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -5597,8 +5860,7 @@ obj2ast_mod(struct ast_state *state, PyObject* obj, mod_ty* out, PyArena* arena) if (body == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'Interactive' node")) { goto failed; } @@ -5660,10 +5922,12 @@ obj2ast_mod(struct ast_state *state, PyObject* obj, mod_ty* out, PyArena* arena) return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"argtypes\" missing from FunctionType"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -5676,8 +5940,7 @@ obj2ast_mod(struct ast_state *state, PyObject* obj, mod_ty* out, PyArena* arena) if (argtypes == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'FunctionType' node")) { goto failed; } @@ -5818,6 +6081,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* asdl_expr_seq* decorator_list; expr_ty returns; string type_comment; + asdl_type_param_seq* type_params; if (_PyObject_LookupAttr(obj, state->name, &tmp) < 0) { return 1; @@ -5857,10 +6121,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from FunctionDef"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -5873,8 +6139,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (body == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'FunctionDef' node")) { goto failed; } @@ -5894,10 +6159,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"decorator_list\" missing from FunctionDef"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -5910,8 +6177,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (decorator_list == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'FunctionDef' node")) { goto failed; } @@ -5961,9 +6227,48 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (res != 0) goto failed; Py_CLEAR(tmp); } + if (_PyObject_LookupAttr(obj, state->type_params, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } + } + { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "FunctionDef field \"type_params\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); + goto failed; + } + len = PyList_GET_SIZE(tmp); + type_params = _Py_asdl_type_param_seq_new(len, arena); + if (type_params == NULL) goto failed; + for (i = 0; i < len; i++) { + type_param_ty val; + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'FunctionDef' node")) { + goto failed; + } + res = obj2ast_type_param(state, tmp2, &val, arena); + _Py_LeaveRecursiveCall(); + Py_DECREF(tmp2); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "FunctionDef field \"type_params\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(type_params, i, val); + } + Py_CLEAR(tmp); + } *out = _PyAST_FunctionDef(name, args, body, decorator_list, returns, - type_comment, lineno, col_offset, end_lineno, - end_col_offset, arena); + type_comment, type_params, lineno, + col_offset, end_lineno, end_col_offset, + arena); if (*out == NULL) goto failed; return 0; } @@ -5979,6 +6284,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* asdl_expr_seq* decorator_list; expr_ty returns; string type_comment; + asdl_type_param_seq* type_params; if (_PyObject_LookupAttr(obj, state->name, &tmp) < 0) { return 1; @@ -6018,10 +6324,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from AsyncFunctionDef"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -6034,8 +6342,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (body == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'AsyncFunctionDef' node")) { goto failed; } @@ -6055,10 +6362,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"decorator_list\" missing from AsyncFunctionDef"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -6071,8 +6380,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (decorator_list == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'AsyncFunctionDef' node")) { goto failed; } @@ -6122,31 +6430,70 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (res != 0) goto failed; Py_CLEAR(tmp); } - *out = _PyAST_AsyncFunctionDef(name, args, body, decorator_list, - returns, type_comment, lineno, - col_offset, end_lineno, end_col_offset, - arena); - if (*out == NULL) goto failed; - return 0; - } - tp = state->ClassDef_type; - isinstance = PyObject_IsInstance(obj, tp); - if (isinstance == -1) { - return 1; - } - if (isinstance) { - identifier name; - asdl_expr_seq* bases; - asdl_keyword_seq* keywords; - asdl_stmt_seq* body; - asdl_expr_seq* decorator_list; - - if (_PyObject_LookupAttr(obj, state->name, &tmp) < 0) { + if (_PyObject_LookupAttr(obj, state->type_params, &tmp) < 0) { return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"name\" missing from ClassDef"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } + } + { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "AsyncFunctionDef field \"type_params\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); + goto failed; + } + len = PyList_GET_SIZE(tmp); + type_params = _Py_asdl_type_param_seq_new(len, arena); + if (type_params == NULL) goto failed; + for (i = 0; i < len; i++) { + type_param_ty val; + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'AsyncFunctionDef' node")) { + goto failed; + } + res = obj2ast_type_param(state, tmp2, &val, arena); + _Py_LeaveRecursiveCall(); + Py_DECREF(tmp2); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "AsyncFunctionDef field \"type_params\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(type_params, i, val); + } + Py_CLEAR(tmp); + } + *out = _PyAST_AsyncFunctionDef(name, args, body, decorator_list, + returns, type_comment, type_params, + lineno, col_offset, end_lineno, + end_col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + tp = state->ClassDef_type; + isinstance = PyObject_IsInstance(obj, tp); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + identifier name; + asdl_expr_seq* bases; + asdl_keyword_seq* keywords; + asdl_stmt_seq* body; + asdl_expr_seq* decorator_list; + asdl_type_param_seq* type_params; + + if (_PyObject_LookupAttr(obj, state->name, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"name\" missing from ClassDef"); + return 1; } else { int res; @@ -6162,10 +6509,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"bases\" missing from ClassDef"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -6178,8 +6527,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (bases == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'ClassDef' node")) { goto failed; } @@ -6199,10 +6547,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"keywords\" missing from ClassDef"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -6215,8 +6565,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (keywords == NULL) goto failed; for (i = 0; i < len; i++) { keyword_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'ClassDef' node")) { goto failed; } @@ -6236,10 +6585,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from ClassDef"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -6252,8 +6603,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (body == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'ClassDef' node")) { goto failed; } @@ -6273,10 +6623,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"decorator_list\" missing from ClassDef"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -6289,8 +6641,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (decorator_list == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'ClassDef' node")) { goto failed; } @@ -6306,9 +6657,47 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* } Py_CLEAR(tmp); } + if (_PyObject_LookupAttr(obj, state->type_params, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } + } + { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "ClassDef field \"type_params\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); + goto failed; + } + len = PyList_GET_SIZE(tmp); + type_params = _Py_asdl_type_param_seq_new(len, arena); + if (type_params == NULL) goto failed; + for (i = 0; i < len; i++) { + type_param_ty val; + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'ClassDef' node")) { + goto failed; + } + res = obj2ast_type_param(state, tmp2, &val, arena); + _Py_LeaveRecursiveCall(); + Py_DECREF(tmp2); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "ClassDef field \"type_params\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(type_params, i, val); + } + Py_CLEAR(tmp); + } *out = _PyAST_ClassDef(name, bases, keywords, body, decorator_list, - lineno, col_offset, end_lineno, end_col_offset, - arena); + type_params, lineno, col_offset, end_lineno, + end_col_offset, arena); if (*out == NULL) goto failed; return 0; } @@ -6354,10 +6743,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"targets\" missing from Delete"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -6370,8 +6761,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (targets == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'Delete' node")) { goto failed; } @@ -6406,10 +6796,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"targets\" missing from Assign"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -6422,8 +6814,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (targets == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'Assign' node")) { goto failed; } @@ -6478,6 +6869,93 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (*out == NULL) goto failed; return 0; } + tp = state->TypeAlias_type; + isinstance = PyObject_IsInstance(obj, tp); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + expr_ty name; + asdl_type_param_seq* type_params; + expr_ty value; + + if (_PyObject_LookupAttr(obj, state->name, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"name\" missing from TypeAlias"); + return 1; + } + else { + int res; + if (_Py_EnterRecursiveCall(" while traversing 'TypeAlias' node")) { + goto failed; + } + res = obj2ast_expr(state, tmp, &name, arena); + _Py_LeaveRecursiveCall(); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttr(obj, state->type_params, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } + } + { + int res; + Py_ssize_t len; + Py_ssize_t i; + if (!PyList_Check(tmp)) { + PyErr_Format(PyExc_TypeError, "TypeAlias field \"type_params\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp))); + goto failed; + } + len = PyList_GET_SIZE(tmp); + type_params = _Py_asdl_type_param_seq_new(len, arena); + if (type_params == NULL) goto failed; + for (i = 0; i < len; i++) { + type_param_ty val; + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); + if (_Py_EnterRecursiveCall(" while traversing 'TypeAlias' node")) { + goto failed; + } + res = obj2ast_type_param(state, tmp2, &val, arena); + _Py_LeaveRecursiveCall(); + Py_DECREF(tmp2); + if (res != 0) goto failed; + if (len != PyList_GET_SIZE(tmp)) { + PyErr_SetString(PyExc_RuntimeError, "TypeAlias field \"type_params\" changed size during iteration"); + goto failed; + } + asdl_seq_SET(type_params, i, val); + } + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttr(obj, state->value, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from TypeAlias"); + return 1; + } + else { + int res; + if (_Py_EnterRecursiveCall(" while traversing 'TypeAlias' node")) { + goto failed; + } + res = obj2ast_expr(state, tmp, &value, arena); + _Py_LeaveRecursiveCall(); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + *out = _PyAST_TypeAlias(name, type_params, value, lineno, col_offset, + end_lineno, end_col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } tp = state->AugAssign_type; isinstance = PyObject_IsInstance(obj, tp); if (isinstance == -1) { @@ -6678,10 +7156,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from For"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -6694,8 +7174,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (body == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'For' node")) { goto failed; } @@ -6715,10 +7194,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"orelse\" missing from For"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -6731,8 +7212,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (orelse == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'For' node")) { goto failed; } @@ -6820,10 +7300,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from AsyncFor"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -6836,8 +7318,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (body == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'AsyncFor' node")) { goto failed; } @@ -6857,10 +7338,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"orelse\" missing from AsyncFor"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -6873,8 +7356,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (orelse == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'AsyncFor' node")) { goto failed; } @@ -6944,10 +7426,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from While"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -6960,8 +7444,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (body == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'While' node")) { goto failed; } @@ -6981,10 +7464,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"orelse\" missing from While"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -6997,8 +7482,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (orelse == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'While' node")) { goto failed; } @@ -7050,10 +7534,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from If"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -7066,8 +7552,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (body == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'If' node")) { goto failed; } @@ -7087,10 +7572,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"orelse\" missing from If"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -7103,8 +7590,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (orelse == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'If' node")) { goto failed; } @@ -7139,10 +7625,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"items\" missing from With"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -7155,8 +7643,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (items == NULL) goto failed; for (i = 0; i < len; i++) { withitem_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'With' node")) { goto failed; } @@ -7176,10 +7663,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from With"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -7192,8 +7681,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (body == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'With' node")) { goto failed; } @@ -7245,10 +7733,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"items\" missing from AsyncWith"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -7261,8 +7751,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (items == NULL) goto failed; for (i = 0; i < len; i++) { withitem_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'AsyncWith' node")) { goto failed; } @@ -7282,10 +7771,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from AsyncWith"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -7298,8 +7789,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (body == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'AsyncWith' node")) { goto failed; } @@ -7367,10 +7857,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"cases\" missing from Match"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -7383,8 +7875,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (cases == NULL) goto failed; for (i = 0; i < len; i++) { match_case_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'Match' node")) { goto failed; } @@ -7468,10 +7959,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from Try"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -7484,8 +7977,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (body == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'Try' node")) { goto failed; } @@ -7505,10 +7997,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"handlers\" missing from Try"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -7521,8 +8015,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (handlers == NULL) goto failed; for (i = 0; i < len; i++) { excepthandler_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'Try' node")) { goto failed; } @@ -7542,10 +8035,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"orelse\" missing from Try"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -7558,8 +8053,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (orelse == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'Try' node")) { goto failed; } @@ -7579,10 +8073,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"finalbody\" missing from Try"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -7595,8 +8091,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (finalbody == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'Try' node")) { goto failed; } @@ -7632,10 +8127,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from TryStar"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -7648,8 +8145,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (body == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'TryStar' node")) { goto failed; } @@ -7669,10 +8165,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"handlers\" missing from TryStar"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -7685,8 +8183,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (handlers == NULL) goto failed; for (i = 0; i < len; i++) { excepthandler_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'TryStar' node")) { goto failed; } @@ -7706,10 +8203,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"orelse\" missing from TryStar"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -7722,8 +8221,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (orelse == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'TryStar' node")) { goto failed; } @@ -7743,10 +8241,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"finalbody\" missing from TryStar"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -7759,8 +8259,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (finalbody == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'TryStar' node")) { goto failed; } @@ -7841,10 +8340,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"names\" missing from Import"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -7857,8 +8358,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (names == NULL) goto failed; for (i = 0; i < len; i++) { alias_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'Import' node")) { goto failed; } @@ -7910,10 +8410,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"names\" missing from ImportFrom"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -7926,8 +8428,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (names == NULL) goto failed; for (i = 0; i < len; i++) { alias_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'ImportFrom' node")) { goto failed; } @@ -7977,10 +8478,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"names\" missing from Global"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -7993,8 +8496,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (names == NULL) goto failed; for (i = 0; i < len; i++) { identifier val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'Global' node")) { goto failed; } @@ -8027,10 +8529,12 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"names\" missing from Nonlocal"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -8043,8 +8547,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena* if (names == NULL) goto failed; for (i = 0; i < len; i++) { identifier val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'Nonlocal' node")) { goto failed; } @@ -8253,10 +8756,12 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"values\" missing from BoolOp"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -8269,8 +8774,7 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* if (values == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'BoolOp' node")) { goto failed; } @@ -8580,10 +9084,12 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"keys\" missing from Dict"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -8596,8 +9102,7 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* if (keys == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'Dict' node")) { goto failed; } @@ -8617,10 +9122,12 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"values\" missing from Dict"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -8633,8 +9140,7 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* if (values == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'Dict' node")) { goto failed; } @@ -8667,10 +9173,12 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"elts\" missing from Set"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -8683,8 +9191,7 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* if (elts == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'Set' node")) { goto failed; } @@ -8735,10 +9242,12 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"generators\" missing from ListComp"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -8751,8 +9260,7 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* if (generators == NULL) goto failed; for (i = 0; i < len; i++) { comprehension_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'ListComp' node")) { goto failed; } @@ -8803,10 +9311,12 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"generators\" missing from SetComp"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -8819,8 +9329,7 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* if (generators == NULL) goto failed; for (i = 0; i < len; i++) { comprehension_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'SetComp' node")) { goto failed; } @@ -8889,10 +9398,12 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"generators\" missing from DictComp"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -8905,8 +9416,7 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* if (generators == NULL) goto failed; for (i = 0; i < len; i++) { comprehension_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'DictComp' node")) { goto failed; } @@ -8957,10 +9467,12 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"generators\" missing from GeneratorExp"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -8973,8 +9485,7 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* if (generators == NULL) goto failed; for (i = 0; i < len; i++) { comprehension_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'GeneratorExp' node")) { goto failed; } @@ -9116,10 +9627,12 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"ops\" missing from Compare"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -9132,8 +9645,7 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* if (ops == NULL) goto failed; for (i = 0; i < len; i++) { cmpop_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'Compare' node")) { goto failed; } @@ -9153,10 +9665,12 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"comparators\" missing from Compare"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -9169,8 +9683,7 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* if (comparators == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'Compare' node")) { goto failed; } @@ -9222,10 +9735,12 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"args\" missing from Call"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -9238,8 +9753,7 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* if (args == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'Call' node")) { goto failed; } @@ -9259,10 +9773,12 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"keywords\" missing from Call"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -9275,8 +9791,7 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* if (keywords == NULL) goto failed; for (i = 0; i < len; i++) { keyword_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'Call' node")) { goto failed; } @@ -9376,10 +9891,12 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"values\" missing from JoinedStr"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -9392,8 +9909,7 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* if (values == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'JoinedStr' node")) { goto failed; } @@ -9703,10 +10219,12 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"elts\" missing from List"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -9719,8 +10237,7 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* if (elts == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'List' node")) { goto failed; } @@ -9771,10 +10288,12 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"elts\" missing from Tuple"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -9787,8 +10306,7 @@ obj2ast_expr(struct ast_state *state, PyObject* obj, expr_ty* out, PyArena* if (elts == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'Tuple' node")) { goto failed; } @@ -10258,10 +10776,12 @@ obj2ast_comprehension(struct ast_state *state, PyObject* obj, comprehension_ty* return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"ifs\" missing from comprehension"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -10274,8 +10794,7 @@ obj2ast_comprehension(struct ast_state *state, PyObject* obj, comprehension_ty* if (ifs == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'comprehension' node")) { goto failed; } @@ -10309,6 +10828,7 @@ obj2ast_comprehension(struct ast_state *state, PyObject* obj, comprehension_ty* Py_CLEAR(tmp); } *out = _PyAST_comprehension(target, iter, ifs, is_async, arena); + if (*out == NULL) goto failed; return 0; failed: Py_XDECREF(tmp); @@ -10448,10 +10968,12 @@ obj2ast_excepthandler(struct ast_state *state, PyObject* obj, excepthandler_ty* return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from ExceptHandler"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -10464,8 +10986,7 @@ obj2ast_excepthandler(struct ast_state *state, PyObject* obj, excepthandler_ty* if (body == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'ExceptHandler' node")) { goto failed; } @@ -10510,10 +11031,12 @@ obj2ast_arguments(struct ast_state *state, PyObject* obj, arguments_ty* out, return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"posonlyargs\" missing from arguments"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -10526,8 +11049,7 @@ obj2ast_arguments(struct ast_state *state, PyObject* obj, arguments_ty* out, if (posonlyargs == NULL) goto failed; for (i = 0; i < len; i++) { arg_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'arguments' node")) { goto failed; } @@ -10547,10 +11069,12 @@ obj2ast_arguments(struct ast_state *state, PyObject* obj, arguments_ty* out, return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"args\" missing from arguments"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -10563,8 +11087,7 @@ obj2ast_arguments(struct ast_state *state, PyObject* obj, arguments_ty* out, if (args == NULL) goto failed; for (i = 0; i < len; i++) { arg_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'arguments' node")) { goto failed; } @@ -10601,10 +11124,12 @@ obj2ast_arguments(struct ast_state *state, PyObject* obj, arguments_ty* out, return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"kwonlyargs\" missing from arguments"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -10617,8 +11142,7 @@ obj2ast_arguments(struct ast_state *state, PyObject* obj, arguments_ty* out, if (kwonlyargs == NULL) goto failed; for (i = 0; i < len; i++) { arg_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'arguments' node")) { goto failed; } @@ -10638,10 +11162,12 @@ obj2ast_arguments(struct ast_state *state, PyObject* obj, arguments_ty* out, return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"kw_defaults\" missing from arguments"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -10654,8 +11180,7 @@ obj2ast_arguments(struct ast_state *state, PyObject* obj, arguments_ty* out, if (kw_defaults == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'arguments' node")) { goto failed; } @@ -10692,10 +11217,12 @@ obj2ast_arguments(struct ast_state *state, PyObject* obj, arguments_ty* out, return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"defaults\" missing from arguments"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -10708,8 +11235,7 @@ obj2ast_arguments(struct ast_state *state, PyObject* obj, arguments_ty* out, if (defaults == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'arguments' node")) { goto failed; } @@ -10727,6 +11253,7 @@ obj2ast_arguments(struct ast_state *state, PyObject* obj, arguments_ty* out, } *out = _PyAST_arguments(posonlyargs, args, vararg, kwonlyargs, kw_defaults, kwarg, defaults, arena); + if (*out == NULL) goto failed; return 0; failed: Py_XDECREF(tmp); @@ -10866,6 +11393,7 @@ obj2ast_arg(struct ast_state *state, PyObject* obj, arg_ty* out, PyArena* arena) } *out = _PyAST_arg(arg, annotation, type_comment, lineno, col_offset, end_lineno, end_col_offset, arena); + if (*out == NULL) goto failed; return 0; failed: Py_XDECREF(tmp); @@ -10988,6 +11516,7 @@ obj2ast_keyword(struct ast_state *state, PyObject* obj, keyword_ty* out, } *out = _PyAST_keyword(arg, value, lineno, col_offset, end_lineno, end_col_offset, arena); + if (*out == NULL) goto failed; return 0; failed: Py_XDECREF(tmp); @@ -11110,6 +11639,7 @@ obj2ast_alias(struct ast_state *state, PyObject* obj, alias_ty* out, PyArena* } *out = _PyAST_alias(name, asname, lineno, col_offset, end_lineno, end_col_offset, arena); + if (*out == NULL) goto failed; return 0; failed: Py_XDECREF(tmp); @@ -11159,6 +11689,7 @@ obj2ast_withitem(struct ast_state *state, PyObject* obj, withitem_ty* out, Py_CLEAR(tmp); } *out = _PyAST_withitem(context_expr, optional_vars, arena); + if (*out == NULL) goto failed; return 0; failed: Py_XDECREF(tmp); @@ -11212,10 +11743,12 @@ obj2ast_match_case(struct ast_state *state, PyObject* obj, match_case_ty* out, return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"body\" missing from match_case"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -11228,8 +11761,7 @@ obj2ast_match_case(struct ast_state *state, PyObject* obj, match_case_ty* out, if (body == NULL) goto failed; for (i = 0; i < len; i++) { stmt_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'match_case' node")) { goto failed; } @@ -11246,6 +11778,7 @@ obj2ast_match_case(struct ast_state *state, PyObject* obj, match_case_ty* out, Py_CLEAR(tmp); } *out = _PyAST_match_case(pattern, guard, body, arena); + if (*out == NULL) goto failed; return 0; failed: Py_XDECREF(tmp); @@ -11409,10 +11942,12 @@ obj2ast_pattern(struct ast_state *state, PyObject* obj, pattern_ty* out, return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"patterns\" missing from MatchSequence"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -11425,8 +11960,7 @@ obj2ast_pattern(struct ast_state *state, PyObject* obj, pattern_ty* out, if (patterns == NULL) goto failed; for (i = 0; i < len; i++) { pattern_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'MatchSequence' node")) { goto failed; } @@ -11461,10 +11995,12 @@ obj2ast_pattern(struct ast_state *state, PyObject* obj, pattern_ty* out, return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"keys\" missing from MatchMapping"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -11477,8 +12013,7 @@ obj2ast_pattern(struct ast_state *state, PyObject* obj, pattern_ty* out, if (keys == NULL) goto failed; for (i = 0; i < len; i++) { expr_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'MatchMapping' node")) { goto failed; } @@ -11498,10 +12033,12 @@ obj2ast_pattern(struct ast_state *state, PyObject* obj, pattern_ty* out, return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"patterns\" missing from MatchMapping"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -11514,8 +12051,7 @@ obj2ast_pattern(struct ast_state *state, PyObject* obj, pattern_ty* out, if (patterns == NULL) goto failed; for (i = 0; i < len; i++) { pattern_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'MatchMapping' node")) { goto failed; } @@ -11585,10 +12121,12 @@ obj2ast_pattern(struct ast_state *state, PyObject* obj, pattern_ty* out, return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"patterns\" missing from MatchClass"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -11601,8 +12139,7 @@ obj2ast_pattern(struct ast_state *state, PyObject* obj, pattern_ty* out, if (patterns == NULL) goto failed; for (i = 0; i < len; i++) { pattern_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'MatchClass' node")) { goto failed; } @@ -11622,10 +12159,12 @@ obj2ast_pattern(struct ast_state *state, PyObject* obj, pattern_ty* out, return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"kwd_attrs\" missing from MatchClass"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -11638,8 +12177,7 @@ obj2ast_pattern(struct ast_state *state, PyObject* obj, pattern_ty* out, if (kwd_attrs == NULL) goto failed; for (i = 0; i < len; i++) { identifier val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'MatchClass' node")) { goto failed; } @@ -11659,10 +12197,12 @@ obj2ast_pattern(struct ast_state *state, PyObject* obj, pattern_ty* out, return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"kwd_patterns\" missing from MatchClass"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -11675,8 +12215,7 @@ obj2ast_pattern(struct ast_state *state, PyObject* obj, pattern_ty* out, if (kwd_patterns == NULL) goto failed; for (i = 0; i < len; i++) { pattern_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'MatchClass' node")) { goto failed; } @@ -11788,10 +12327,12 @@ obj2ast_pattern(struct ast_state *state, PyObject* obj, pattern_ty* out, return 1; } if (tmp == NULL) { - PyErr_SetString(PyExc_TypeError, "required field \"patterns\" missing from MatchOr"); - return 1; + tmp = PyList_New(0); + if (tmp == NULL) { + return 1; + } } - else { + { int res; Py_ssize_t len; Py_ssize_t i; @@ -11804,8 +12345,7 @@ obj2ast_pattern(struct ast_state *state, PyObject* obj, pattern_ty* out, if (patterns == NULL) goto failed; for (i = 0; i < len; i++) { pattern_ty val; - PyObject *tmp2 = PyList_GET_ITEM(tmp, i); - Py_INCREF(tmp2); + PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i)); if (_Py_EnterRecursiveCall(" while traversing 'MatchOr' node")) { goto failed; } @@ -11900,6 +12440,206 @@ obj2ast_type_ignore(struct ast_state *state, PyObject* obj, type_ignore_ty* return 1; } +int +obj2ast_type_param(struct ast_state *state, PyObject* obj, type_param_ty* out, + PyArena* arena) +{ + int isinstance; + + PyObject *tmp = NULL; + PyObject *tp; + int lineno; + int col_offset; + int end_lineno; + int end_col_offset; + + if (obj == Py_None) { + *out = NULL; + return 0; + } + if (_PyObject_LookupAttr(obj, state->lineno, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"lineno\" missing from type_param"); + return 1; + } + else { + int res; + if (_Py_EnterRecursiveCall(" while traversing 'type_param' node")) { + goto failed; + } + res = obj2ast_int(state, tmp, &lineno, arena); + _Py_LeaveRecursiveCall(); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttr(obj, state->col_offset, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"col_offset\" missing from type_param"); + return 1; + } + else { + int res; + if (_Py_EnterRecursiveCall(" while traversing 'type_param' node")) { + goto failed; + } + res = obj2ast_int(state, tmp, &col_offset, arena); + _Py_LeaveRecursiveCall(); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttr(obj, state->end_lineno, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"end_lineno\" missing from type_param"); + return 1; + } + else { + int res; + if (_Py_EnterRecursiveCall(" while traversing 'type_param' node")) { + goto failed; + } + res = obj2ast_int(state, tmp, &end_lineno, arena); + _Py_LeaveRecursiveCall(); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttr(obj, state->end_col_offset, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"end_col_offset\" missing from type_param"); + return 1; + } + else { + int res; + if (_Py_EnterRecursiveCall(" while traversing 'type_param' node")) { + goto failed; + } + res = obj2ast_int(state, tmp, &end_col_offset, arena); + _Py_LeaveRecursiveCall(); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + tp = state->TypeVar_type; + isinstance = PyObject_IsInstance(obj, tp); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + identifier name; + expr_ty bound; + + if (_PyObject_LookupAttr(obj, state->name, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"name\" missing from TypeVar"); + return 1; + } + else { + int res; + if (_Py_EnterRecursiveCall(" while traversing 'TypeVar' node")) { + goto failed; + } + res = obj2ast_identifier(state, tmp, &name, arena); + _Py_LeaveRecursiveCall(); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + if (_PyObject_LookupAttr(obj, state->bound, &tmp) < 0) { + return 1; + } + if (tmp == NULL || tmp == Py_None) { + Py_CLEAR(tmp); + bound = NULL; + } + else { + int res; + if (_Py_EnterRecursiveCall(" while traversing 'TypeVar' node")) { + goto failed; + } + res = obj2ast_expr(state, tmp, &bound, arena); + _Py_LeaveRecursiveCall(); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + *out = _PyAST_TypeVar(name, bound, lineno, col_offset, end_lineno, + end_col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + tp = state->ParamSpec_type; + isinstance = PyObject_IsInstance(obj, tp); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + identifier name; + + if (_PyObject_LookupAttr(obj, state->name, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"name\" missing from ParamSpec"); + return 1; + } + else { + int res; + if (_Py_EnterRecursiveCall(" while traversing 'ParamSpec' node")) { + goto failed; + } + res = obj2ast_identifier(state, tmp, &name, arena); + _Py_LeaveRecursiveCall(); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + *out = _PyAST_ParamSpec(name, lineno, col_offset, end_lineno, + end_col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + tp = state->TypeVarTuple_type; + isinstance = PyObject_IsInstance(obj, tp); + if (isinstance == -1) { + return 1; + } + if (isinstance) { + identifier name; + + if (_PyObject_LookupAttr(obj, state->name, &tmp) < 0) { + return 1; + } + if (tmp == NULL) { + PyErr_SetString(PyExc_TypeError, "required field \"name\" missing from TypeVarTuple"); + return 1; + } + else { + int res; + if (_Py_EnterRecursiveCall(" while traversing 'TypeVarTuple' node")) { + goto failed; + } + res = obj2ast_identifier(state, tmp, &name, arena); + _Py_LeaveRecursiveCall(); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } + *out = _PyAST_TypeVarTuple(name, lineno, col_offset, end_lineno, + end_col_offset, arena); + if (*out == NULL) goto failed; + return 0; + } + + PyErr_Format(PyExc_TypeError, "expected some sort of type_param, but got %R", obj); + failed: + Py_XDECREF(tmp); + return 1; +} + static int astmodule_exec(PyObject *m) @@ -11958,6 +12698,9 @@ astmodule_exec(PyObject *m) if (PyModule_AddObjectRef(m, "Assign", state->Assign_type) < 0) { return -1; } + if (PyModule_AddObjectRef(m, "TypeAlias", state->TypeAlias_type) < 0) { + return -1; + } if (PyModule_AddObjectRef(m, "AugAssign", state->AugAssign_type) < 0) { return -1; } @@ -12285,11 +13028,25 @@ astmodule_exec(PyObject *m) if (PyModule_AddObjectRef(m, "TypeIgnore", state->TypeIgnore_type) < 0) { return -1; } + if (PyModule_AddObjectRef(m, "type_param", state->type_param_type) < 0) { + return -1; + } + if (PyModule_AddObjectRef(m, "TypeVar", state->TypeVar_type) < 0) { + return -1; + } + if (PyModule_AddObjectRef(m, "ParamSpec", state->ParamSpec_type) < 0) { + return -1; + } + if (PyModule_AddObjectRef(m, "TypeVarTuple", state->TypeVarTuple_type) < 0) + { + return -1; + } return 0; } static PyModuleDef_Slot astmodule_slots[] = { {Py_mod_exec, astmodule_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; @@ -12315,19 +13072,16 @@ PyObject* PyAST_mod2obj(mod_ty t) return NULL; } - int recursion_limit = Py_GetRecursionLimit(); int starting_recursion_depth; /* Be careful here to prevent overflow. */ - int COMPILER_STACK_FRAME_SCALE = 3; + int COMPILER_STACK_FRAME_SCALE = 2; PyThreadState *tstate = _PyThreadState_GET(); if (!tstate) { return 0; } - state->recursion_limit = (recursion_limit < INT_MAX / COMPILER_STACK_FRAME_SCALE) ? - recursion_limit * COMPILER_STACK_FRAME_SCALE : recursion_limit; - int recursion_depth = tstate->recursion_limit - tstate->recursion_remaining; - starting_recursion_depth = (recursion_depth < INT_MAX / COMPILER_STACK_FRAME_SCALE) ? - recursion_depth * COMPILER_STACK_FRAME_SCALE : recursion_depth; + state->recursion_limit = C_RECURSION_LIMIT * COMPILER_STACK_FRAME_SCALE; + int recursion_depth = C_RECURSION_LIMIT - tstate->c_recursion_remaining; + starting_recursion_depth = recursion_depth * COMPILER_STACK_FRAME_SCALE; state->recursion_depth = starting_recursion_depth; PyObject *result = ast2obj_mod(state, t); diff --git a/Python/Python-tokenize.c b/Python/Python-tokenize.c index 6acfc2a7..19385627 100644 --- a/Python/Python-tokenize.c +++ b/Python/Python-tokenize.c @@ -1,5 +1,8 @@ #include "Python.h" +#include "errcode.h" #include "../Parser/tokenizer.h" +#include "../Parser/pegen.h" // _PyPegen_byte_offset_to_character_offset() +#include "../Parser/pegen.h" // _PyPegen_byte_offset_to_character_offset() static struct PyModuleDef _tokenizemodule; @@ -15,6 +18,7 @@ get_tokenize_state(PyObject *module) { #define _tokenize_get_state_by_type(type) \ get_tokenize_state(PyType_GetModuleByDef(type, &_tokenizemodule)) +#include "pycore_runtime.h" #include "clinic/Python-tokenize.c.h" /*[clinic input] @@ -26,18 +30,24 @@ class _tokenizer.tokenizeriter "tokenizeriterobject *" "_tokenize_get_state_by_t typedef struct { PyObject_HEAD struct tok_state *tok; + int done; } tokenizeriterobject; /*[clinic input] @classmethod _tokenizer.tokenizeriter.__new__ as tokenizeriter_new - source: str + readline: object + / + * + extra_tokens: bool + encoding: str(c_default="NULL") = 'utf-8' [clinic start generated code]*/ static PyObject * -tokenizeriter_new_impl(PyTypeObject *type, const char *source) -/*[clinic end generated code: output=7fd9f46cf9263cbb input=4384b368407375c6]*/ +tokenizeriter_new_impl(PyTypeObject *type, PyObject *readline, + int extra_tokens, const char *encoding) +/*[clinic end generated code: output=7501a1211683ce16 input=f7dddf8a613ae8bd]*/ { tokenizeriterobject *self = (tokenizeriterobject *)type->tp_alloc(type, 0); if (self == NULL) { @@ -47,58 +57,220 @@ tokenizeriter_new_impl(PyTypeObject *type, const char *source) if (filename == NULL) { return NULL; } - self->tok = _PyTokenizer_FromUTF8(source, 1); + self->tok = _PyTokenizer_FromReadline(readline, encoding, 1, 1); if (self->tok == NULL) { Py_DECREF(filename); return NULL; } self->tok->filename = filename; + if (extra_tokens) { + self->tok->tok_extra_tokens = 1; + } + self->done = 0; return (PyObject *)self; } +static int +_tokenizer_error(struct tok_state *tok) +{ + if (PyErr_Occurred()) { + return -1; + } + + const char *msg = NULL; + PyObject* errtype = PyExc_SyntaxError; + switch (tok->done) { + case E_TOKEN: + msg = "invalid token"; + break; + case E_EOF: + PyErr_SetString(PyExc_SyntaxError, "unexpected EOF in multi-line statement"); + PyErr_SyntaxLocationObject(tok->filename, tok->lineno, + tok->inp - tok->buf < 0 ? 0 : (int)(tok->inp - tok->buf)); + return -1; + case E_DEDENT: + msg = "unindent does not match any outer indentation level"; + errtype = PyExc_IndentationError; + break; + case E_INTR: + if (!PyErr_Occurred()) { + PyErr_SetNone(PyExc_KeyboardInterrupt); + } + return -1; + case E_NOMEM: + PyErr_NoMemory(); + return -1; + case E_TABSPACE: + errtype = PyExc_TabError; + msg = "inconsistent use of tabs and spaces in indentation"; + break; + case E_TOODEEP: + errtype = PyExc_IndentationError; + msg = "too many levels of indentation"; + break; + case E_LINECONT: { + msg = "unexpected character after line continuation character"; + break; + } + default: + msg = "unknown tokenization error"; + } + + PyObject* errstr = NULL; + PyObject* error_line = NULL; + PyObject* tmp = NULL; + PyObject* value = NULL; + int result = 0; + + Py_ssize_t size = tok->inp - tok->buf; + assert(tok->buf[size-1] == '\n'); + size -= 1; // Remove the newline character from the end of the line + error_line = PyUnicode_DecodeUTF8(tok->buf, size, "replace"); + if (!error_line) { + result = -1; + goto exit; + } + + Py_ssize_t offset = _PyPegen_byte_offset_to_character_offset(error_line, tok->inp - tok->buf); + if (offset == -1) { + result = -1; + goto exit; + } + tmp = Py_BuildValue("(OnnOOO)", tok->filename, tok->lineno, offset, error_line, Py_None, Py_None); + if (!tmp) { + result = -1; + goto exit; + } + + errstr = PyUnicode_FromString(msg); + if (!errstr) { + result = -1; + goto exit; + } + + value = PyTuple_Pack(2, errstr, tmp); + if (!value) { + result = -1; + goto exit; + } + + PyErr_SetObject(errtype, value); + +exit: + Py_XDECREF(errstr); + Py_XDECREF(error_line); + Py_XDECREF(tmp); + Py_XDECREF(value); + return result; +} + static PyObject * tokenizeriter_next(tokenizeriterobject *it) { - const char *start; - const char *end; - int type = _PyTokenizer_Get(it->tok, &start, &end); - if (type == ERRORTOKEN && PyErr_Occurred()) { - return NULL; + PyObject* result = NULL; + struct token token; + _PyToken_Init(&token); + + int type = _PyTokenizer_Get(it->tok, &token); + if (type == ERRORTOKEN) { + if(!PyErr_Occurred()) { + _tokenizer_error(it->tok); + assert(PyErr_Occurred()); + } + goto exit; } - if (type == ERRORTOKEN || type == ENDMARKER) { + if (it->done || type == ERRORTOKEN) { PyErr_SetString(PyExc_StopIteration, "EOF"); - return NULL; + it->done = 1; + goto exit; } PyObject *str = NULL; - if (start == NULL || end == NULL) { + if (token.start == NULL || token.end == NULL) { str = PyUnicode_FromString(""); } else { - str = PyUnicode_FromStringAndSize(start, end - start); + str = PyUnicode_FromStringAndSize(token.start, token.end - token.start); } if (str == NULL) { - return NULL; + goto exit; } - Py_ssize_t size = it->tok->inp - it->tok->buf; - PyObject *line = PyUnicode_DecodeUTF8(it->tok->buf, size, "replace"); + int is_trailing_token = 0; + if (type == ENDMARKER || (type == DEDENT && it->tok->done == E_EOF)) { + is_trailing_token = 1; + } + + const char *line_start = ISSTRINGLIT(type) ? it->tok->multi_line_start : it->tok->line_start; + PyObject* line = NULL; + if (it->tok->tok_extra_tokens && is_trailing_token) { + line = PyUnicode_FromString(""); + } else { + Py_ssize_t size = it->tok->inp - line_start; + if (size >= 1 && it->tok->implicit_newline) { + size -= 1; + } + line = PyUnicode_DecodeUTF8(line_start, size, "replace"); + } if (line == NULL) { Py_DECREF(str); - return NULL; + goto exit; + } + + Py_ssize_t lineno = ISSTRINGLIT(type) ? it->tok->first_lineno : it->tok->lineno; + Py_ssize_t end_lineno = it->tok->lineno; + Py_ssize_t col_offset = -1; + Py_ssize_t end_col_offset = -1; + if (token.start != NULL && token.start >= line_start) { + col_offset = _PyPegen_byte_offset_to_character_offset(line, token.start - line_start); } - const char *line_start = type == STRING ? it->tok->multi_line_start : it->tok->line_start; - int lineno = type == STRING ? it->tok->first_lineno : it->tok->lineno; - int end_lineno = it->tok->lineno; - int col_offset = -1; - int end_col_offset = -1; - if (start != NULL && start >= line_start) { - col_offset = (int)(start - line_start); + if (token.end != NULL && token.end >= it->tok->line_start) { + end_col_offset = _PyPegen_byte_offset_to_character_offset(line, token.end - it->tok->line_start); } - if (end != NULL && end >= it->tok->line_start) { - end_col_offset = (int)(end - it->tok->line_start); + + if (it->tok->tok_extra_tokens) { + if (is_trailing_token) { + lineno = end_lineno = lineno + 1; + col_offset = end_col_offset = 0; + } + // Necessary adjustments to match the original Python tokenize + // implementation + if (type > DEDENT && type < OP) { + type = OP; + } + else if (type == ASYNC || type == AWAIT) { + type = NAME; + } + else if (type == NEWLINE) { + Py_DECREF(str); + if (!it->tok->implicit_newline) { + if (it->tok->start[0] == '\r') { + str = PyUnicode_FromString("\r\n"); + } else { + str = PyUnicode_FromString("\n"); + } + } + end_col_offset++; + } + else if (type == NL) { + if (it->tok->implicit_newline) { + Py_DECREF(str); + str = PyUnicode_FromString(""); + } + } + + if (str == NULL) { + Py_DECREF(line); + goto exit; + } } - return Py_BuildValue("(NiiiiiN)", str, type, lineno, end_lineno, col_offset, end_col_offset, line); + result = Py_BuildValue("(iN(nn)(nn)N)", type, str, lineno, col_offset, end_lineno, end_col_offset, line); +exit: + _PyToken_Free(&token); + if (type == ENDMARKER) { + it->done = 1; + } + return result; } static void @@ -151,6 +323,7 @@ static PyMethodDef tokenize_methods[] = { static PyModuleDef_Slot tokenizemodule_slots[] = { {Py_mod_exec, tokenizemodule_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; diff --git a/Python/_warnings.c b/Python/_warnings.c index 4e224000..1f91edbf 100644 --- a/Python/_warnings.c +++ b/Python/_warnings.c @@ -198,7 +198,7 @@ get_warnings_attr(PyInterpreterState *interp, PyObject *attr, int try_import) PyObject *warnings_module, *obj; /* don't try to import after the start of the Python finallization */ - if (try_import && !_Py_IsFinalizing()) { + if (try_import && !_Py_IsInterpreterFinalizing(interp)) { warnings_module = PyImport_Import(&_Py_ID(warnings)); if (warnings_module == NULL) { /* Fallback to the C implementation if we cannot get @@ -214,7 +214,7 @@ get_warnings_attr(PyInterpreterState *interp, PyObject *attr, int try_import) gone, then we can't even use PyImport_GetModule without triggering an interpreter abort. */ - if (!interp->modules) { + if (!_PyImport_GetModules(interp)) { return NULL; } warnings_module = PyImport_GetModule(&_Py_ID(warnings)); @@ -382,8 +382,7 @@ get_filter(PyInterpreterState *interp, PyObject *category, action = get_default_action(interp); if (action != NULL) { - Py_INCREF(Py_None); - *item = Py_None; + *item = Py_NewRef(Py_None); return action; } @@ -468,8 +467,7 @@ normalize_module(PyObject *filename) module = PyUnicode_Substring(filename, 0, len-3); } else { - module = filename; - Py_INCREF(module); + module = Py_NewRef(filename); } return module; } @@ -751,8 +749,7 @@ warn_explicit(PyThreadState *tstate, PyObject *category, PyObject *message, goto cleanup; return_none: - result = Py_None; - Py_INCREF(result); + result = Py_NewRef(Py_None); cleanup: Py_XDECREF(item); @@ -764,57 +761,99 @@ warn_explicit(PyThreadState *tstate, PyObject *category, PyObject *message, return result; /* Py_None or NULL. */ } -static int -is_internal_frame(PyFrameObject *frame) +static PyObject * +get_frame_filename(PyFrameObject *frame) { - if (frame == NULL) { - return 0; - } - PyCodeObject *code = PyFrame_GetCode(frame); PyObject *filename = code->co_filename; Py_DECREF(code); + return filename; +} - if (filename == NULL) { - return 0; - } +static bool +is_internal_filename(PyObject *filename) +{ if (!PyUnicode_Check(filename)) { - return 0; + return false; } int contains = PyUnicode_Contains(filename, &_Py_ID(importlib)); if (contains < 0) { - return 0; + return false; } else if (contains > 0) { contains = PyUnicode_Contains(filename, &_Py_ID(_bootstrap)); if (contains < 0) { - return 0; + return false; } else if (contains > 0) { - return 1; + return true; } } - return 0; + return false; +} + +static bool +is_filename_to_skip(PyObject *filename, PyTupleObject *skip_file_prefixes) +{ + if (skip_file_prefixes) { + if (!PyUnicode_Check(filename)) { + return false; + } + + Py_ssize_t prefixes = PyTuple_GET_SIZE(skip_file_prefixes); + for (Py_ssize_t idx = 0; idx < prefixes; ++idx) + { + PyObject *prefix = PyTuple_GET_ITEM(skip_file_prefixes, idx); + Py_ssize_t found = PyUnicode_Tailmatch(filename, prefix, 0, -1, -1); + if (found == 1) { + return true; + } + if (found < 0) { + return false; + } + } + } + return false; +} + +static bool +is_internal_frame(PyFrameObject *frame) +{ + if (frame == NULL) { + return false; + } + + PyObject *filename = get_frame_filename(frame); + if (filename == NULL) { + return false; + } + + return is_internal_filename(filename); } static PyFrameObject * -next_external_frame(PyFrameObject *frame) +next_external_frame(PyFrameObject *frame, PyTupleObject *skip_file_prefixes) { + PyObject *frame_filename; do { PyFrameObject *back = PyFrame_GetBack(frame); - Py_DECREF(frame); - frame = back; - } while (frame != NULL && is_internal_frame(frame)); + Py_SETREF(frame, back); + } while (frame != NULL && (frame_filename = get_frame_filename(frame)) && + (is_internal_filename(frame_filename) || + is_filename_to_skip(frame_filename, skip_file_prefixes))); return frame; } /* filename, module, and registry are new refs, globals is borrowed */ +/* skip_file_prefixes is either NULL or a tuple of strs. */ /* Returns 0 on error (no new refs), 1 on success */ static int -setup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno, +setup_context(Py_ssize_t stack_level, + PyTupleObject *skip_file_prefixes, + PyObject **filename, int *lineno, PyObject **module, PyObject **registry) { PyObject *globals; @@ -824,6 +863,21 @@ setup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno, if (tstate == NULL) { return 0; } + if (skip_file_prefixes) { + /* Type check our data structure up front. Later code that uses it + * isn't structured to report errors. */ + Py_ssize_t prefixes = PyTuple_GET_SIZE(skip_file_prefixes); + for (Py_ssize_t idx = 0; idx < prefixes; ++idx) + { + PyObject *prefix = PyTuple_GET_ITEM(skip_file_prefixes, idx); + if (!PyUnicode_Check(prefix)) { + PyErr_Format(PyExc_TypeError, + "Found non-str '%s' in skip_file_prefixes.", + Py_TYPE(prefix)->tp_name); + return 0; + } + } + } PyInterpreterState *interp = tstate->interp; PyFrameObject *f = PyThreadState_GetFrame(tstate); // Stack level comparisons to Python code is off by one as there is no @@ -831,13 +885,12 @@ setup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno, if (stack_level <= 0 || is_internal_frame(f)) { while (--stack_level > 0 && f != NULL) { PyFrameObject *back = PyFrame_GetBack(f); - Py_DECREF(f); - f = back; + Py_SETREF(f, back); } } else { while (--stack_level > 0 && f != NULL) { - f = next_external_frame(f); + f = next_external_frame(f, skip_file_prefixes); } } @@ -848,8 +901,7 @@ setup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno, } else { globals = f->f_frame->f_globals; - *filename = f->f_frame->f_code->co_filename; - Py_INCREF(*filename); + *filename = Py_NewRef(f->f_frame->f_code->co_filename); *lineno = PyFrame_GetLineNumber(f); Py_DECREF(f); } @@ -931,7 +983,7 @@ get_category(PyObject *message, PyObject *category) static PyObject * do_warn(PyObject *message, PyObject *category, Py_ssize_t stack_level, - PyObject *source) + PyObject *source, PyTupleObject *skip_file_prefixes) { PyObject *filename, *module, *registry, *res; int lineno; @@ -941,7 +993,8 @@ do_warn(PyObject *message, PyObject *category, Py_ssize_t stack_level, return NULL; } - if (!setup_context(stack_level, &filename, &lineno, &module, ®istry)) + if (!setup_context(stack_level, skip_file_prefixes, + &filename, &lineno, &module, ®istry)) return NULL; res = warn_explicit(tstate, category, message, filename, lineno, module, registry, @@ -956,22 +1009,42 @@ do_warn(PyObject *message, PyObject *category, Py_ssize_t stack_level, warn as warnings_warn message: object + Text of the warning message. category: object = None + The Warning category subclass. Defaults to UserWarning. stacklevel: Py_ssize_t = 1 + How far up the call stack to make this warning appear. A value of 2 for + example attributes the warning to the caller of the code calling warn(). source: object = None + If supplied, the destroyed object which emitted a ResourceWarning + * + skip_file_prefixes: object(type='PyTupleObject *', subclass_of='&PyTuple_Type') = NULL + An optional tuple of module filename prefixes indicating frames to skip + during stacklevel computations for stack frame attribution. Issue a warning, or maybe ignore it or raise an exception. [clinic start generated code]*/ static PyObject * warnings_warn_impl(PyObject *module, PyObject *message, PyObject *category, - Py_ssize_t stacklevel, PyObject *source) -/*[clinic end generated code: output=31ed5ab7d8d760b2 input=bfdf5cf99f6c4edd]*/ + Py_ssize_t stacklevel, PyObject *source, + PyTupleObject *skip_file_prefixes) +/*[clinic end generated code: output=a68e0f6906c65f80 input=eb37c6a18bec4ea1]*/ { category = get_category(message, category); if (category == NULL) return NULL; - return do_warn(message, category, stacklevel, source); + if (skip_file_prefixes) { + if (PyTuple_GET_SIZE(skip_file_prefixes) > 0) { + if (stacklevel < 2) { + stacklevel = 2; + } + } else { + Py_DECREF((PyObject *)skip_file_prefixes); + skip_file_prefixes = NULL; + } + } + return do_warn(message, category, stacklevel, source, skip_file_prefixes); } static PyObject * @@ -984,12 +1057,12 @@ get_source_line(PyInterpreterState *interp, PyObject *module_globals, int lineno PyObject *source_list; PyObject *source_line; - /* Check/get the requisite pieces needed for the loader. */ - loader = _PyDict_GetItemWithError(module_globals, &_Py_ID(__loader__)); + /* stolen from import.c */ + loader = _PyImport_BlessMyLoader(interp, module_globals); if (loader == NULL) { return NULL; } - Py_INCREF(loader); + module_name = _PyDict_GetItemWithError(module_globals, &_Py_ID(__name__)); if (!module_name) { Py_DECREF(loader); @@ -1030,28 +1103,31 @@ get_source_line(PyInterpreterState *interp, PyObject *module_globals, int lineno return source_line; } +/*[clinic input] +warn_explicit as warnings_warn_explicit + + message: object + category: object + filename: unicode + lineno: int + module as mod: object = NULL + registry: object = None + module_globals: object = None + source as sourceobj: object = None + +Issue a warning, or maybe ignore it or raise an exception. +[clinic start generated code]*/ + static PyObject * -warnings_warn_explicit(PyObject *self, PyObject *args, PyObject *kwds) +warnings_warn_explicit_impl(PyObject *module, PyObject *message, + PyObject *category, PyObject *filename, + int lineno, PyObject *mod, PyObject *registry, + PyObject *module_globals, PyObject *sourceobj) +/*[clinic end generated code: output=c49c62b15a49a186 input=df6eeb8b45e712f1]*/ { - static char *kwd_list[] = {"message", "category", "filename", "lineno", - "module", "registry", "module_globals", - "source", 0}; - PyObject *message; - PyObject *category; - PyObject *filename; - int lineno; - PyObject *module = NULL; - PyObject *registry = NULL; - PyObject *module_globals = NULL; - PyObject *sourceobj = NULL; PyObject *source_line = NULL; PyObject *returned; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOUi|OOOO:warn_explicit", - kwd_list, &message, &category, &filename, &lineno, &module, - ®istry, &module_globals, &sourceobj)) - return NULL; - PyThreadState *tstate = get_current_tstate(); if (tstate == NULL) { return NULL; @@ -1070,14 +1146,20 @@ warnings_warn_explicit(PyObject *self, PyObject *args, PyObject *kwds) return NULL; } } - returned = warn_explicit(tstate, category, message, filename, lineno, module, - registry, source_line, sourceobj); + returned = warn_explicit(tstate, category, message, filename, lineno, + mod, registry, source_line, sourceobj); Py_XDECREF(source_line); return returned; } +/*[clinic input] +_filters_mutated as warnings_filters_mutated + +[clinic start generated code]*/ + static PyObject * -warnings_filters_mutated(PyObject *self, PyObject *Py_UNUSED(args)) +warnings_filters_mutated_impl(PyObject *module) +/*[clinic end generated code: output=8ce517abd12b88f4 input=35ecbf08ee2491b2]*/ { PyInterpreterState *interp = get_current_interp(); if (interp == NULL) { @@ -1103,7 +1185,7 @@ warn_unicode(PyObject *category, PyObject *message, if (category == NULL) category = PyExc_RuntimeWarning; - res = do_warn(message, category, stack_level, source); + res = do_warn(message, category, stack_level, source, NULL); if (res == NULL) return -1; Py_DECREF(res); @@ -1135,11 +1217,7 @@ PyErr_WarnFormat(PyObject *category, Py_ssize_t stack_level, int res; va_list vargs; -#ifdef HAVE_STDARG_PROTOTYPES va_start(vargs, format); -#else - va_start(vargs); -#endif res = _PyErr_WarnFormatV(NULL, category, stack_level, format, vargs); va_end(vargs); return res; @@ -1152,11 +1230,7 @@ _PyErr_WarnFormat(PyObject *source, PyObject *category, Py_ssize_t stack_level, int res; va_list vargs; -#ifdef HAVE_STDARG_PROTOTYPES va_start(vargs, format); -#else - va_start(vargs); -#endif res = _PyErr_WarnFormatV(source, category, stack_level, format, vargs); va_end(vargs); return res; @@ -1169,11 +1243,7 @@ PyErr_ResourceWarning(PyObject *source, Py_ssize_t stack_level, int res; va_list vargs; -#ifdef HAVE_STDARG_PROTOTYPES va_start(vargs, format); -#else - va_start(vargs); -#endif res = _PyErr_WarnFormatV(source, PyExc_ResourceWarning, stack_level, format, vargs); va_end(vargs); @@ -1231,25 +1301,29 @@ PyErr_WarnExplicit(PyObject *category, const char *text, const char *module_str, PyObject *registry) { PyObject *message = PyUnicode_FromString(text); + if (message == NULL) { + return -1; + } PyObject *filename = PyUnicode_DecodeFSDefault(filename_str); + if (filename == NULL) { + Py_DECREF(message); + return -1; + } PyObject *module = NULL; - int ret = -1; - - if (message == NULL || filename == NULL) - goto exit; if (module_str != NULL) { module = PyUnicode_FromString(module_str); - if (module == NULL) - goto exit; + if (module == NULL) { + Py_DECREF(filename); + Py_DECREF(message); + return -1; + } } - ret = PyErr_WarnExplicitObject(category, message, filename, lineno, - module, registry); - - exit: - Py_XDECREF(message); + int ret = PyErr_WarnExplicitObject(category, message, filename, lineno, + module, registry); Py_XDECREF(module); - Py_XDECREF(filename); + Py_DECREF(filename); + Py_DECREF(message); return ret; } @@ -1273,11 +1347,7 @@ PyErr_WarnExplicitFormat(PyObject *category, goto exit; } -#ifdef HAVE_STDARG_PROTOTYPES va_start(vargs, format); -#else - va_start(vargs); -#endif message = PyUnicode_FromFormatV(format, vargs); if (message != NULL) { PyObject *res; @@ -1347,15 +1417,10 @@ _PyErr_WarnUnawaitedCoroutine(PyObject *coro) } } -PyDoc_STRVAR(warn_explicit_doc, -"Low-level interface to warnings functionality."); - static PyMethodDef warnings_functions[] = { WARNINGS_WARN_METHODDEF - {"warn_explicit", _PyCFunction_CAST(warnings_warn_explicit), - METH_VARARGS | METH_KEYWORDS, warn_explicit_doc}, - {"_filters_mutated", _PyCFunction_CAST(warnings_filters_mutated), METH_NOARGS, - NULL}, + WARNINGS_WARN_EXPLICIT_METHODDEF + WARNINGS_FILTERS_MUTATED_METHODDEF /* XXX(brett.cannon): add showwarning? */ /* XXX(brett.cannon): Reasonable to add formatwarning? */ {NULL, NULL} /* sentinel */ @@ -1388,6 +1453,7 @@ warnings_module_exec(PyObject *module) static PyModuleDef_Slot warnings_slots[] = { {Py_mod_exec, warnings_module_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; diff --git a/Python/adaptive.md b/Python/adaptive.md index e8161bcd..d978c089 100644 --- a/Python/adaptive.md +++ b/Python/adaptive.md @@ -11,7 +11,7 @@ A family of instructions has the following fundamental properties: generated by the bytecode compiler. * It has a single adaptive instruction that records an execution count and, at regular intervals, attempts to specialize itself. If not specializing, - it executes the non-adaptive instruction. + it executes the base implementation. * It has at least one specialized form of the instruction that is tailored for a particular value or set of values at runtime. * All members of the family must have the same number of inline cache entries, @@ -22,19 +22,18 @@ A family of instructions has the following fundamental properties: The current implementation also requires the following, although these are not fundamental and may change: -* All families uses one or more inline cache entries, +* All families use one or more inline cache entries, the first entry is always the counter. -* All instruction names should start with the name of the non-adaptive +* All instruction names should start with the name of the adaptive instruction. -* The adaptive instruction should end in `_ADAPTIVE`. * Specialized forms should have names describing their specialization. ## Example family -The `LOAD_GLOBAL` instruction (in Python/ceval.c) already has an adaptive +The `LOAD_GLOBAL` instruction (in Python/bytecodes.c) already has an adaptive family that serves as a relatively simple example. -The `LOAD_GLOBAL_ADAPTIVE` instruction performs adaptive specialization, +The `LOAD_GLOBAL` instruction performs adaptive specialization, calling `_Py_Specialize_LoadGlobal()` when the counter reaches zero. There are two specialized instructions in the family, `LOAD_GLOBAL_MODULE` @@ -138,5 +137,5 @@ to eliminate the branches. Finally, take care that stats are gather correctly. After the last `DEOPT_IF` has passed, a hit should be recorded with `STAT_INC(BASE_INSTRUCTION, hit)`. -After a optimization has been deferred in the `ADAPTIVE` form, +After an optimization has been deferred in the adaptive instruction, that should be recorded with `STAT_INC(BASE_INSTRUCTION, deferred)`. diff --git a/Python/asm_trampoline.S b/Python/asm_trampoline.S new file mode 100644 index 00000000..46070771 --- /dev/null +++ b/Python/asm_trampoline.S @@ -0,0 +1,28 @@ + .text + .globl _Py_trampoline_func_start +# The following assembly is equivalent to: +# PyObject * +# trampoline(PyThreadState *ts, _PyInterpreterFrame *f, +# int throwflag, py_evaluator evaluator) +# { +# return evaluator(ts, f, throwflag); +# } +_Py_trampoline_func_start: +#ifdef __x86_64__ + sub $8, %rsp + call *%rcx + add $8, %rsp + ret +#endif // __x86_64__ +#if defined(__aarch64__) && defined(__AARCH64EL__) && !defined(__ILP32__) + // ARM64 little endian, 64bit ABI + // generate with aarch64-linux-gnu-gcc 12.1 + stp x29, x30, [sp, -16]! + mov x29, sp + blr x3 + ldp x29, x30, [sp], 16 + ret +#endif + .globl _Py_trampoline_func_end +_Py_trampoline_func_end: + .section .note.GNU-stack,"",@progbits diff --git a/Python/assemble.c b/Python/assemble.c new file mode 100644 index 00000000..8789d8ef --- /dev/null +++ b/Python/assemble.c @@ -0,0 +1,603 @@ +#include <stdbool.h> + +#include "Python.h" +#include "pycore_code.h" // write_location_entry_start() +#include "pycore_compile.h" +#include "pycore_opcode.h" // _PyOpcode_Caches[] and opcode category macros +#include "pycore_pymem.h" // _PyMem_IsPtrFreed() + + +#define DEFAULT_CODE_SIZE 128 +#define DEFAULT_LNOTAB_SIZE 16 +#define DEFAULT_CNOTAB_SIZE 32 + +#undef SUCCESS +#undef ERROR +#define SUCCESS 0 +#define ERROR -1 + +#define RETURN_IF_ERROR(X) \ + if ((X) == -1) { \ + return ERROR; \ + } + +typedef _PyCompilerSrcLocation location; +typedef _PyCompile_Instruction instruction; +typedef _PyCompile_InstructionSequence instr_sequence; + +static inline bool +same_location(location a, location b) +{ + return a.lineno == b.lineno && + a.end_lineno == b.end_lineno && + a.col_offset == b.col_offset && + a.end_col_offset == b.end_col_offset; +} + +struct assembler { + PyObject *a_bytecode; /* bytes containing bytecode */ + int a_offset; /* offset into bytecode */ + PyObject *a_except_table; /* bytes containing exception table */ + int a_except_table_off; /* offset into exception table */ + /* Location Info */ + int a_lineno; /* lineno of last emitted instruction */ + PyObject* a_linetable; /* bytes containing location info */ + int a_location_off; /* offset of last written location info frame */ +}; + +static int +assemble_init(struct assembler *a, int firstlineno) +{ + memset(a, 0, sizeof(struct assembler)); + a->a_lineno = firstlineno; + a->a_linetable = NULL; + a->a_location_off = 0; + a->a_except_table = NULL; + a->a_bytecode = PyBytes_FromStringAndSize(NULL, DEFAULT_CODE_SIZE); + if (a->a_bytecode == NULL) { + goto error; + } + a->a_linetable = PyBytes_FromStringAndSize(NULL, DEFAULT_CNOTAB_SIZE); + if (a->a_linetable == NULL) { + goto error; + } + a->a_except_table = PyBytes_FromStringAndSize(NULL, DEFAULT_LNOTAB_SIZE); + if (a->a_except_table == NULL) { + goto error; + } + return SUCCESS; +error: + Py_XDECREF(a->a_bytecode); + Py_XDECREF(a->a_linetable); + Py_XDECREF(a->a_except_table); + return ERROR; +} + +static void +assemble_free(struct assembler *a) +{ + Py_XDECREF(a->a_bytecode); + Py_XDECREF(a->a_linetable); + Py_XDECREF(a->a_except_table); +} + +static inline void +write_except_byte(struct assembler *a, int byte) { + unsigned char *p = (unsigned char *) PyBytes_AS_STRING(a->a_except_table); + p[a->a_except_table_off++] = byte; +} + +#define CONTINUATION_BIT 64 + +static void +assemble_emit_exception_table_item(struct assembler *a, int value, int msb) +{ + assert ((msb | 128) == 128); + assert(value >= 0 && value < (1 << 30)); + if (value >= 1 << 24) { + write_except_byte(a, (value >> 24) | CONTINUATION_BIT | msb); + msb = 0; + } + if (value >= 1 << 18) { + write_except_byte(a, ((value >> 18)&0x3f) | CONTINUATION_BIT | msb); + msb = 0; + } + if (value >= 1 << 12) { + write_except_byte(a, ((value >> 12)&0x3f) | CONTINUATION_BIT | msb); + msb = 0; + } + if (value >= 1 << 6) { + write_except_byte(a, ((value >> 6)&0x3f) | CONTINUATION_BIT | msb); + msb = 0; + } + write_except_byte(a, (value&0x3f) | msb); +} + +/* See Objects/exception_handling_notes.txt for details of layout */ +#define MAX_SIZE_OF_ENTRY 20 + +static int +assemble_emit_exception_table_entry(struct assembler *a, int start, int end, + _PyCompile_ExceptHandlerInfo *handler) +{ + Py_ssize_t len = PyBytes_GET_SIZE(a->a_except_table); + if (a->a_except_table_off + MAX_SIZE_OF_ENTRY >= len) { + RETURN_IF_ERROR(_PyBytes_Resize(&a->a_except_table, len * 2)); + } + int size = end-start; + assert(end > start); + int target = handler->h_offset; + int depth = handler->h_startdepth - 1; + if (handler->h_preserve_lasti > 0) { + depth -= 1; + } + assert(depth >= 0); + int depth_lasti = (depth<<1) | handler->h_preserve_lasti; + assemble_emit_exception_table_item(a, start, (1<<7)); + assemble_emit_exception_table_item(a, size, 0); + assemble_emit_exception_table_item(a, target, 0); + assemble_emit_exception_table_item(a, depth_lasti, 0); + return SUCCESS; +} + +static int +assemble_exception_table(struct assembler *a, instr_sequence *instrs) +{ + int ioffset = 0; + _PyCompile_ExceptHandlerInfo handler; + handler.h_offset = -1; + handler.h_preserve_lasti = -1; + int start = -1; + for (int i = 0; i < instrs->s_used; i++) { + instruction *instr = &instrs->s_instrs[i]; + if (instr->i_except_handler_info.h_offset != handler.h_offset) { + if (handler.h_offset >= 0) { + RETURN_IF_ERROR( + assemble_emit_exception_table_entry(a, start, ioffset, &handler)); + } + start = ioffset; + handler = instr->i_except_handler_info; + } + ioffset += _PyCompile_InstrSize(instr->i_opcode, instr->i_oparg); + } + if (handler.h_offset >= 0) { + RETURN_IF_ERROR(assemble_emit_exception_table_entry(a, start, ioffset, &handler)); + } + return SUCCESS; +} + + +/* Code location emitting code. See locations.md for a description of the format. */ + +#define MSB 0x80 + +static void +write_location_byte(struct assembler* a, int val) +{ + PyBytes_AS_STRING(a->a_linetable)[a->a_location_off] = val&255; + a->a_location_off++; +} + + +static uint8_t * +location_pointer(struct assembler* a) +{ + return (uint8_t *)PyBytes_AS_STRING(a->a_linetable) + + a->a_location_off; +} + +static void +write_location_first_byte(struct assembler* a, int code, int length) +{ + a->a_location_off += write_location_entry_start( + location_pointer(a), code, length); +} + +static void +write_location_varint(struct assembler* a, unsigned int val) +{ + uint8_t *ptr = location_pointer(a); + a->a_location_off += write_varint(ptr, val); +} + + +static void +write_location_signed_varint(struct assembler* a, int val) +{ + uint8_t *ptr = location_pointer(a); + a->a_location_off += write_signed_varint(ptr, val); +} + +static void +write_location_info_short_form(struct assembler* a, int length, int column, int end_column) +{ + assert(length > 0 && length <= 8); + int column_low_bits = column & 7; + int column_group = column >> 3; + assert(column < 80); + assert(end_column >= column); + assert(end_column - column < 16); + write_location_first_byte(a, PY_CODE_LOCATION_INFO_SHORT0 + column_group, length); + write_location_byte(a, (column_low_bits << 4) | (end_column - column)); +} + +static void +write_location_info_oneline_form(struct assembler* a, int length, int line_delta, int column, int end_column) +{ + assert(length > 0 && length <= 8); + assert(line_delta >= 0 && line_delta < 3); + assert(column < 128); + assert(end_column < 128); + write_location_first_byte(a, PY_CODE_LOCATION_INFO_ONE_LINE0 + line_delta, length); + write_location_byte(a, column); + write_location_byte(a, end_column); +} + +static void +write_location_info_long_form(struct assembler* a, location loc, int length) +{ + assert(length > 0 && length <= 8); + write_location_first_byte(a, PY_CODE_LOCATION_INFO_LONG, length); + write_location_signed_varint(a, loc.lineno - a->a_lineno); + assert(loc.end_lineno >= loc.lineno); + write_location_varint(a, loc.end_lineno - loc.lineno); + write_location_varint(a, loc.col_offset + 1); + write_location_varint(a, loc.end_col_offset + 1); +} + +static void +write_location_info_none(struct assembler* a, int length) +{ + write_location_first_byte(a, PY_CODE_LOCATION_INFO_NONE, length); +} + +static void +write_location_info_no_column(struct assembler* a, int length, int line_delta) +{ + write_location_first_byte(a, PY_CODE_LOCATION_INFO_NO_COLUMNS, length); + write_location_signed_varint(a, line_delta); +} + +#define THEORETICAL_MAX_ENTRY_SIZE 25 /* 1 + 6 + 6 + 6 + 6 */ + + +static int +write_location_info_entry(struct assembler* a, location loc, int isize) +{ + Py_ssize_t len = PyBytes_GET_SIZE(a->a_linetable); + if (a->a_location_off + THEORETICAL_MAX_ENTRY_SIZE >= len) { + assert(len > THEORETICAL_MAX_ENTRY_SIZE); + RETURN_IF_ERROR(_PyBytes_Resize(&a->a_linetable, len*2)); + } + if (loc.lineno < 0) { + write_location_info_none(a, isize); + return SUCCESS; + } + int line_delta = loc.lineno - a->a_lineno; + int column = loc.col_offset; + int end_column = loc.end_col_offset; + assert(column >= -1); + assert(end_column >= -1); + if (column < 0 || end_column < 0) { + if (loc.end_lineno == loc.lineno || loc.end_lineno == -1) { + write_location_info_no_column(a, isize, line_delta); + a->a_lineno = loc.lineno; + return SUCCESS; + } + } + else if (loc.end_lineno == loc.lineno) { + if (line_delta == 0 && column < 80 && end_column - column < 16 && end_column >= column) { + write_location_info_short_form(a, isize, column, end_column); + return SUCCESS; + } + if (line_delta >= 0 && line_delta < 3 && column < 128 && end_column < 128) { + write_location_info_oneline_form(a, isize, line_delta, column, end_column); + a->a_lineno = loc.lineno; + return SUCCESS; + } + } + write_location_info_long_form(a, loc, isize); + a->a_lineno = loc.lineno; + return SUCCESS; +} + +static int +assemble_emit_location(struct assembler* a, location loc, int isize) +{ + if (isize == 0) { + return SUCCESS; + } + while (isize > 8) { + RETURN_IF_ERROR(write_location_info_entry(a, loc, 8)); + isize -= 8; + } + return write_location_info_entry(a, loc, isize); +} + +static int +assemble_location_info(struct assembler *a, instr_sequence *instrs, + int firstlineno) +{ + a->a_lineno = firstlineno; + location loc = NO_LOCATION; + int size = 0; + for (int i = 0; i < instrs->s_used; i++) { + instruction *instr = &instrs->s_instrs[i]; + if (!same_location(loc, instr->i_loc)) { + RETURN_IF_ERROR(assemble_emit_location(a, loc, size)); + loc = instr->i_loc; + size = 0; + } + size += _PyCompile_InstrSize(instr->i_opcode, instr->i_oparg); + } + RETURN_IF_ERROR(assemble_emit_location(a, loc, size)); + return SUCCESS; +} + +static void +write_instr(_Py_CODEUNIT *codestr, instruction *instr, int ilen) +{ + int opcode = instr->i_opcode; + assert(!IS_PSEUDO_OPCODE(opcode)); + int oparg = instr->i_oparg; + assert(HAS_ARG(opcode) || oparg == 0); + int caches = _PyOpcode_Caches[opcode]; + switch (ilen - caches) { + case 4: + codestr->op.code = EXTENDED_ARG; + codestr->op.arg = (oparg >> 24) & 0xFF; + codestr++; + /* fall through */ + case 3: + codestr->op.code = EXTENDED_ARG; + codestr->op.arg = (oparg >> 16) & 0xFF; + codestr++; + /* fall through */ + case 2: + codestr->op.code = EXTENDED_ARG; + codestr->op.arg = (oparg >> 8) & 0xFF; + codestr++; + /* fall through */ + case 1: + codestr->op.code = opcode; + codestr->op.arg = oparg & 0xFF; + codestr++; + break; + default: + Py_UNREACHABLE(); + } + while (caches--) { + codestr->op.code = CACHE; + codestr->op.arg = 0; + codestr++; + } +} + +/* assemble_emit_instr() + Extend the bytecode with a new instruction. + Update lnotab if necessary. +*/ + +static int +assemble_emit_instr(struct assembler *a, instruction *instr) +{ + Py_ssize_t len = PyBytes_GET_SIZE(a->a_bytecode); + _Py_CODEUNIT *code; + + int size = _PyCompile_InstrSize(instr->i_opcode, instr->i_oparg); + if (a->a_offset + size >= len / (int)sizeof(_Py_CODEUNIT)) { + if (len > PY_SSIZE_T_MAX / 2) { + return ERROR; + } + RETURN_IF_ERROR(_PyBytes_Resize(&a->a_bytecode, len * 2)); + } + code = (_Py_CODEUNIT *)PyBytes_AS_STRING(a->a_bytecode) + a->a_offset; + a->a_offset += size; + write_instr(code, instr, size); + return SUCCESS; +} + +static int +assemble_emit(struct assembler *a, instr_sequence *instrs, + int first_lineno, PyObject *const_cache) +{ + RETURN_IF_ERROR(assemble_init(a, first_lineno)); + + for (int i = 0; i < instrs->s_used; i++) { + instruction *instr = &instrs->s_instrs[i]; + RETURN_IF_ERROR(assemble_emit_instr(a, instr)); + } + + RETURN_IF_ERROR(assemble_location_info(a, instrs, a->a_lineno)); + + RETURN_IF_ERROR(assemble_exception_table(a, instrs)); + + RETURN_IF_ERROR(_PyBytes_Resize(&a->a_except_table, a->a_except_table_off)); + RETURN_IF_ERROR(_PyCompile_ConstCacheMergeOne(const_cache, &a->a_except_table)); + + RETURN_IF_ERROR(_PyBytes_Resize(&a->a_linetable, a->a_location_off)); + RETURN_IF_ERROR(_PyCompile_ConstCacheMergeOne(const_cache, &a->a_linetable)); + + RETURN_IF_ERROR(_PyBytes_Resize(&a->a_bytecode, a->a_offset * sizeof(_Py_CODEUNIT))); + RETURN_IF_ERROR(_PyCompile_ConstCacheMergeOne(const_cache, &a->a_bytecode)); + return SUCCESS; +} + +static PyObject * +dict_keys_inorder(PyObject *dict, Py_ssize_t offset) +{ + PyObject *tuple, *k, *v; + Py_ssize_t i, pos = 0, size = PyDict_GET_SIZE(dict); + + tuple = PyTuple_New(size); + if (tuple == NULL) + return NULL; + while (PyDict_Next(dict, &pos, &k, &v)) { + i = PyLong_AS_LONG(v); + assert((i - offset) < size); + assert((i - offset) >= 0); + PyTuple_SET_ITEM(tuple, i - offset, Py_NewRef(k)); + } + return tuple; +} + +// This is in codeobject.c. +extern void _Py_set_localsplus_info(int, PyObject *, unsigned char, + PyObject *, PyObject *); + +static void +compute_localsplus_info(_PyCompile_CodeUnitMetadata *umd, int nlocalsplus, + PyObject *names, PyObject *kinds) +{ + PyObject *k, *v; + Py_ssize_t pos = 0; + while (PyDict_Next(umd->u_varnames, &pos, &k, &v)) { + int offset = (int)PyLong_AS_LONG(v); + assert(offset >= 0); + assert(offset < nlocalsplus); + // For now we do not distinguish arg kinds. + _PyLocals_Kind kind = CO_FAST_LOCAL; + if (PyDict_Contains(umd->u_fasthidden, k)) { + kind |= CO_FAST_HIDDEN; + } + if (PyDict_GetItem(umd->u_cellvars, k) != NULL) { + kind |= CO_FAST_CELL; + } + _Py_set_localsplus_info(offset, k, kind, names, kinds); + } + int nlocals = (int)PyDict_GET_SIZE(umd->u_varnames); + + // This counter mirrors the fix done in fix_cell_offsets(). + int numdropped = 0; + pos = 0; + while (PyDict_Next(umd->u_cellvars, &pos, &k, &v)) { + if (PyDict_GetItem(umd->u_varnames, k) != NULL) { + // Skip cells that are already covered by locals. + numdropped += 1; + continue; + } + int offset = (int)PyLong_AS_LONG(v); + assert(offset >= 0); + offset += nlocals - numdropped; + assert(offset < nlocalsplus); + _Py_set_localsplus_info(offset, k, CO_FAST_CELL, names, kinds); + } + + pos = 0; + while (PyDict_Next(umd->u_freevars, &pos, &k, &v)) { + int offset = (int)PyLong_AS_LONG(v); + assert(offset >= 0); + offset += nlocals - numdropped; + assert(offset < nlocalsplus); + _Py_set_localsplus_info(offset, k, CO_FAST_FREE, names, kinds); + } +} + +static PyCodeObject * +makecode(_PyCompile_CodeUnitMetadata *umd, struct assembler *a, PyObject *const_cache, + PyObject *constslist, int maxdepth, int nlocalsplus, int code_flags, + PyObject *filename) +{ + PyCodeObject *co = NULL; + PyObject *names = NULL; + PyObject *consts = NULL; + PyObject *localsplusnames = NULL; + PyObject *localspluskinds = NULL; + names = dict_keys_inorder(umd->u_names, 0); + if (!names) { + goto error; + } + if (_PyCompile_ConstCacheMergeOne(const_cache, &names) < 0) { + goto error; + } + + consts = PyList_AsTuple(constslist); /* PyCode_New requires a tuple */ + if (consts == NULL) { + goto error; + } + if (_PyCompile_ConstCacheMergeOne(const_cache, &consts) < 0) { + goto error; + } + + assert(umd->u_posonlyargcount < INT_MAX); + assert(umd->u_argcount < INT_MAX); + assert(umd->u_kwonlyargcount < INT_MAX); + int posonlyargcount = (int)umd->u_posonlyargcount; + int posorkwargcount = (int)umd->u_argcount; + assert(INT_MAX - posonlyargcount - posorkwargcount > 0); + int kwonlyargcount = (int)umd->u_kwonlyargcount; + + localsplusnames = PyTuple_New(nlocalsplus); + if (localsplusnames == NULL) { + goto error; + } + localspluskinds = PyBytes_FromStringAndSize(NULL, nlocalsplus); + if (localspluskinds == NULL) { + goto error; + } + compute_localsplus_info(umd, nlocalsplus, localsplusnames, localspluskinds); + + struct _PyCodeConstructor con = { + .filename = filename, + .name = umd->u_name, + .qualname = umd->u_qualname ? umd->u_qualname : umd->u_name, + .flags = code_flags, + + .code = a->a_bytecode, + .firstlineno = umd->u_firstlineno, + .linetable = a->a_linetable, + + .consts = consts, + .names = names, + + .localsplusnames = localsplusnames, + .localspluskinds = localspluskinds, + + .argcount = posonlyargcount + posorkwargcount, + .posonlyargcount = posonlyargcount, + .kwonlyargcount = kwonlyargcount, + + .stacksize = maxdepth, + + .exceptiontable = a->a_except_table, + }; + + if (_PyCode_Validate(&con) < 0) { + goto error; + } + + if (_PyCompile_ConstCacheMergeOne(const_cache, &localsplusnames) < 0) { + goto error; + } + con.localsplusnames = localsplusnames; + + co = _PyCode_New(&con); + if (co == NULL) { + goto error; + } + +error: + Py_XDECREF(names); + Py_XDECREF(consts); + Py_XDECREF(localsplusnames); + Py_XDECREF(localspluskinds); + return co; +} + + +PyCodeObject * +_PyAssemble_MakeCodeObject(_PyCompile_CodeUnitMetadata *umd, PyObject *const_cache, + PyObject *consts, int maxdepth, instr_sequence *instrs, + int nlocalsplus, int code_flags, PyObject *filename) +{ + PyCodeObject *co = NULL; + + struct assembler a; + int res = assemble_emit(&a, instrs, umd->u_firstlineno, const_cache); + if (res == SUCCESS) { + co = makecode(umd, &a, const_cache, consts, maxdepth, nlocalsplus, + code_flags, filename); + } + assemble_free(&a); + return co; +} diff --git a/Python/ast.c b/Python/ast.c index a0321b58..a3acf78a 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -17,10 +17,12 @@ struct validator { static int validate_stmts(struct validator *, asdl_stmt_seq *); static int validate_exprs(struct validator *, asdl_expr_seq *, expr_context_ty, int); static int validate_patterns(struct validator *, asdl_pattern_seq *, int); +static int validate_type_params(struct validator *, asdl_type_param_seq *); static int _validate_nonempty_seq(asdl_seq *, const char *, const char *); static int validate_stmt(struct validator *, stmt_ty); static int validate_expr(struct validator *, expr_ty, expr_context_ty); static int validate_pattern(struct validator *, pattern_ty, int); +static int validate_typeparam(struct validator *, type_param_ty); #define VALIDATE_POSITIONS(node) \ if (node->lineno > node->end_lineno) { \ @@ -46,6 +48,7 @@ static int validate_pattern(struct validator *, pattern_ty, int); static int validate_name(PyObject *name) { + assert(!PyErr_Occurred()); assert(PyUnicode_Check(name)); static const char * const forbidden[] = { "None", @@ -65,12 +68,12 @@ validate_name(PyObject *name) static int validate_comprehension(struct validator *state, asdl_comprehension_seq *gens) { - Py_ssize_t i; + assert(!PyErr_Occurred()); if (!asdl_seq_LEN(gens)) { PyErr_SetString(PyExc_ValueError, "comprehension with no generators"); return 0; } - for (i = 0; i < asdl_seq_LEN(gens); i++) { + for (Py_ssize_t i = 0; i < asdl_seq_LEN(gens); i++) { comprehension_ty comp = asdl_seq_GET(gens, i); if (!validate_expr(state, comp->target, Store) || !validate_expr(state, comp->iter, Load) || @@ -83,8 +86,8 @@ validate_comprehension(struct validator *state, asdl_comprehension_seq *gens) static int validate_keywords(struct validator *state, asdl_keyword_seq *keywords) { - Py_ssize_t i; - for (i = 0; i < asdl_seq_LEN(keywords); i++) + assert(!PyErr_Occurred()); + for (Py_ssize_t i = 0; i < asdl_seq_LEN(keywords); i++) if (!validate_expr(state, (asdl_seq_GET(keywords, i))->value, Load)) return 0; return 1; @@ -93,8 +96,8 @@ validate_keywords(struct validator *state, asdl_keyword_seq *keywords) static int validate_args(struct validator *state, asdl_arg_seq *args) { - Py_ssize_t i; - for (i = 0; i < asdl_seq_LEN(args); i++) { + assert(!PyErr_Occurred()); + for (Py_ssize_t i = 0; i < asdl_seq_LEN(args); i++) { arg_ty arg = asdl_seq_GET(args, i); VALIDATE_POSITIONS(arg); if (arg->annotation && !validate_expr(state, arg->annotation, Load)) @@ -121,6 +124,7 @@ expr_context_name(expr_context_ty ctx) static int validate_arguments(struct validator *state, arguments_ty args) { + assert(!PyErr_Occurred()); if (!validate_args(state, args->posonlyargs) || !validate_args(state, args->args)) { return 0; } @@ -149,6 +153,7 @@ validate_arguments(struct validator *state, arguments_ty args) static int validate_constant(struct validator *state, PyObject *value) { + assert(!PyErr_Occurred()); if (value == Py_None || value == Py_Ellipsis) return 1; @@ -205,6 +210,7 @@ validate_constant(struct validator *state, PyObject *value) static int validate_expr(struct validator *state, expr_ty exp, expr_context_ty ctx) { + assert(!PyErr_Occurred()); VALIDATE_POSITIONS(exp); int ret = -1; if (++state->recursion_depth > state->recursion_limit) { @@ -465,6 +471,7 @@ ensure_literal_complex(expr_ty exp) static int validate_pattern_match_value(struct validator *state, expr_ty exp) { + assert(!PyErr_Occurred()); if (!validate_expr(state, exp, Load)) { return 0; } @@ -518,6 +525,7 @@ validate_pattern_match_value(struct validator *state, expr_ty exp) static int validate_capture(PyObject *name) { + assert(!PyErr_Occurred()); if (_PyUnicode_EqualToASCIIString(name, "_")) { PyErr_Format(PyExc_ValueError, "can't capture name '_' in patterns"); return 0; @@ -528,6 +536,7 @@ validate_capture(PyObject *name) static int validate_pattern(struct validator *state, pattern_ty p, int star_ok) { + assert(!PyErr_Occurred()); VALIDATE_POSITIONS(p); int ret = -1; if (++state->recursion_depth > state->recursion_limit) { @@ -580,7 +589,9 @@ validate_pattern(struct validator *state, pattern_ty p, int star_ok) break; } } - + if (ret == 0) { + break; + } ret = validate_patterns(state, p->v.MatchMapping.patterns, /*star_ok=*/0); break; case MatchClass_kind: @@ -611,6 +622,9 @@ validate_pattern(struct validator *state, pattern_ty p, int star_ok) break; } } + if (ret == 0) { + break; + } for (Py_ssize_t i = 0; i < asdl_seq_LEN(p->v.MatchClass.kwd_attrs); i++) { PyObject *identifier = asdl_seq_GET(p->v.MatchClass.kwd_attrs, i); @@ -619,6 +633,9 @@ validate_pattern(struct validator *state, pattern_ty p, int star_ok) break; } } + if (ret == 0) { + break; + } if (!validate_patterns(state, p->v.MatchClass.patterns, /*star_ok=*/0)) { ret = 0; @@ -685,6 +702,7 @@ _validate_nonempty_seq(asdl_seq *seq, const char *what, const char *owner) static int validate_assignlist(struct validator *state, asdl_expr_seq *targets, expr_context_ty ctx) { + assert(!PyErr_Occurred()); return validate_nonempty_seq(targets, "targets", ctx == Del ? "Delete" : "Assign") && validate_exprs(state, targets, ctx, 0); } @@ -692,15 +710,16 @@ validate_assignlist(struct validator *state, asdl_expr_seq *targets, expr_contex static int validate_body(struct validator *state, asdl_stmt_seq *body, const char *owner) { + assert(!PyErr_Occurred()); return validate_nonempty_seq(body, "body", owner) && validate_stmts(state, body); } static int validate_stmt(struct validator *state, stmt_ty stmt) { + assert(!PyErr_Occurred()); VALIDATE_POSITIONS(stmt); int ret = -1; - Py_ssize_t i; if (++state->recursion_depth > state->recursion_limit) { PyErr_SetString(PyExc_RecursionError, "maximum recursion depth exceeded during compilation"); @@ -709,6 +728,7 @@ validate_stmt(struct validator *state, stmt_ty stmt) switch (stmt->kind) { case FunctionDef_kind: ret = validate_body(state, stmt->v.FunctionDef.body, "FunctionDef") && + validate_type_params(state, stmt->v.FunctionDef.type_params) && validate_arguments(state, stmt->v.FunctionDef.args) && validate_exprs(state, stmt->v.FunctionDef.decorator_list, Load, 0) && (!stmt->v.FunctionDef.returns || @@ -716,6 +736,7 @@ validate_stmt(struct validator *state, stmt_ty stmt) break; case ClassDef_kind: ret = validate_body(state, stmt->v.ClassDef.body, "ClassDef") && + validate_type_params(state, stmt->v.ClassDef.type_params) && validate_exprs(state, stmt->v.ClassDef.bases, Load, 0) && validate_keywords(state, stmt->v.ClassDef.keywords) && validate_exprs(state, stmt->v.ClassDef.decorator_list, Load, 0); @@ -746,6 +767,16 @@ validate_stmt(struct validator *state, stmt_ty stmt) validate_expr(state, stmt->v.AnnAssign.value, Load)) && validate_expr(state, stmt->v.AnnAssign.annotation, Load); break; + case TypeAlias_kind: + if (stmt->v.TypeAlias.name->kind != Name_kind) { + PyErr_SetString(PyExc_TypeError, + "TypeAlias with non-Name name"); + return 0; + } + ret = validate_expr(state, stmt->v.TypeAlias.name, Store) && + validate_type_params(state, stmt->v.TypeAlias.type_params) && + validate_expr(state, stmt->v.TypeAlias.value, Load); + break; case For_kind: ret = validate_expr(state, stmt->v.For.target, Store) && validate_expr(state, stmt->v.For.iter, Load) && @@ -771,7 +802,7 @@ validate_stmt(struct validator *state, stmt_ty stmt) case With_kind: if (!validate_nonempty_seq(stmt->v.With.items, "items", "With")) return 0; - for (i = 0; i < asdl_seq_LEN(stmt->v.With.items); i++) { + for (Py_ssize_t i = 0; i < asdl_seq_LEN(stmt->v.With.items); i++) { withitem_ty item = asdl_seq_GET(stmt->v.With.items, i); if (!validate_expr(state, item->context_expr, Load) || (item->optional_vars && !validate_expr(state, item->optional_vars, Store))) @@ -782,7 +813,7 @@ validate_stmt(struct validator *state, stmt_ty stmt) case AsyncWith_kind: if (!validate_nonempty_seq(stmt->v.AsyncWith.items, "items", "AsyncWith")) return 0; - for (i = 0; i < asdl_seq_LEN(stmt->v.AsyncWith.items); i++) { + for (Py_ssize_t i = 0; i < asdl_seq_LEN(stmt->v.AsyncWith.items); i++) { withitem_ty item = asdl_seq_GET(stmt->v.AsyncWith.items, i); if (!validate_expr(state, item->context_expr, Load) || (item->optional_vars && !validate_expr(state, item->optional_vars, Store))) @@ -795,7 +826,7 @@ validate_stmt(struct validator *state, stmt_ty stmt) || !validate_nonempty_seq(stmt->v.Match.cases, "cases", "Match")) { return 0; } - for (i = 0; i < asdl_seq_LEN(stmt->v.Match.cases); i++) { + for (Py_ssize_t i = 0; i < asdl_seq_LEN(stmt->v.Match.cases); i++) { match_case_ty m = asdl_seq_GET(stmt->v.Match.cases, i); if (!validate_pattern(state, m->pattern, /*star_ok=*/0) || (m->guard && !validate_expr(state, m->guard, Load)) @@ -830,7 +861,7 @@ validate_stmt(struct validator *state, stmt_ty stmt) PyErr_SetString(PyExc_ValueError, "Try has orelse but no except handlers"); return 0; } - for (i = 0; i < asdl_seq_LEN(stmt->v.Try.handlers); i++) { + for (Py_ssize_t i = 0; i < asdl_seq_LEN(stmt->v.Try.handlers); i++) { excepthandler_ty handler = asdl_seq_GET(stmt->v.Try.handlers, i); VALIDATE_POSITIONS(handler); if ((handler->v.ExceptHandler.type && @@ -856,7 +887,7 @@ validate_stmt(struct validator *state, stmt_ty stmt) PyErr_SetString(PyExc_ValueError, "TryStar has orelse but no except handlers"); return 0; } - for (i = 0; i < asdl_seq_LEN(stmt->v.TryStar.handlers); i++) { + for (Py_ssize_t i = 0; i < asdl_seq_LEN(stmt->v.TryStar.handlers); i++) { excepthandler_ty handler = asdl_seq_GET(stmt->v.TryStar.handlers, i); if ((handler->v.ExceptHandler.type && !validate_expr(state, handler->v.ExceptHandler.type, Load)) || @@ -893,6 +924,7 @@ validate_stmt(struct validator *state, stmt_ty stmt) break; case AsyncFunctionDef_kind: ret = validate_body(state, stmt->v.AsyncFunctionDef.body, "AsyncFunctionDef") && + validate_type_params(state, stmt->v.AsyncFunctionDef.type_params) && validate_arguments(state, stmt->v.AsyncFunctionDef.args) && validate_exprs(state, stmt->v.AsyncFunctionDef.decorator_list, Load, 0) && (!stmt->v.AsyncFunctionDef.returns || @@ -916,8 +948,8 @@ validate_stmt(struct validator *state, stmt_ty stmt) static int validate_stmts(struct validator *state, asdl_stmt_seq *seq) { - Py_ssize_t i; - for (i = 0; i < asdl_seq_LEN(seq); i++) { + assert(!PyErr_Occurred()); + for (Py_ssize_t i = 0; i < asdl_seq_LEN(seq); i++) { stmt_ty stmt = asdl_seq_GET(seq, i); if (stmt) { if (!validate_stmt(state, stmt)) @@ -935,8 +967,8 @@ validate_stmts(struct validator *state, asdl_stmt_seq *seq) static int validate_exprs(struct validator *state, asdl_expr_seq *exprs, expr_context_ty ctx, int null_ok) { - Py_ssize_t i; - for (i = 0; i < asdl_seq_LEN(exprs); i++) { + assert(!PyErr_Occurred()); + for (Py_ssize_t i = 0; i < asdl_seq_LEN(exprs); i++) { expr_ty expr = asdl_seq_GET(exprs, i); if (expr) { if (!validate_expr(state, expr, ctx)) @@ -955,8 +987,8 @@ validate_exprs(struct validator *state, asdl_expr_seq *exprs, expr_context_ty ct static int validate_patterns(struct validator *state, asdl_pattern_seq *patterns, int star_ok) { - Py_ssize_t i; - for (i = 0; i < asdl_seq_LEN(patterns); i++) { + assert(!PyErr_Occurred()); + for (Py_ssize_t i = 0; i < asdl_seq_LEN(patterns); i++) { pattern_ty pattern = asdl_seq_GET(patterns, i); if (!validate_pattern(state, pattern, star_ok)) { return 0; @@ -965,17 +997,52 @@ validate_patterns(struct validator *state, asdl_pattern_seq *patterns, int star_ return 1; } +static int +validate_typeparam(struct validator *state, type_param_ty tp) +{ + VALIDATE_POSITIONS(tp); + int ret = -1; + switch (tp->kind) { + case TypeVar_kind: + ret = validate_name(tp->v.TypeVar.name) && + (!tp->v.TypeVar.bound || + validate_expr(state, tp->v.TypeVar.bound, Load)); + break; + case ParamSpec_kind: + ret = validate_name(tp->v.ParamSpec.name); + break; + case TypeVarTuple_kind: + ret = validate_name(tp->v.TypeVarTuple.name); + break; + } + return ret; +} + +static int +validate_type_params(struct validator *state, asdl_type_param_seq *tps) +{ + Py_ssize_t i; + for (i = 0; i < asdl_seq_LEN(tps); i++) { + type_param_ty tp = asdl_seq_GET(tps, i); + if (tp) { + if (!validate_typeparam(state, tp)) + return 0; + } + } + return 1; +} + /* See comments in symtable.c. */ -#define COMPILER_STACK_FRAME_SCALE 3 +#define COMPILER_STACK_FRAME_SCALE 2 int _PyAST_Validate(mod_ty mod) { + assert(!PyErr_Occurred()); int res = -1; struct validator state; PyThreadState *tstate; - int recursion_limit = Py_GetRecursionLimit(); int starting_recursion_depth; /* Setup recursion depth check counters */ @@ -984,12 +1051,10 @@ _PyAST_Validate(mod_ty mod) return 0; } /* Be careful here to prevent overflow. */ - int recursion_depth = tstate->recursion_limit - tstate->recursion_remaining; - starting_recursion_depth = (recursion_depth< INT_MAX / COMPILER_STACK_FRAME_SCALE) ? - recursion_depth * COMPILER_STACK_FRAME_SCALE : recursion_depth; + int recursion_depth = C_RECURSION_LIMIT - tstate->c_recursion_remaining; + starting_recursion_depth = recursion_depth * COMPILER_STACK_FRAME_SCALE; state.recursion_depth = starting_recursion_depth; - state.recursion_limit = (recursion_limit < INT_MAX / COMPILER_STACK_FRAME_SCALE) ? - recursion_limit * COMPILER_STACK_FRAME_SCALE : recursion_limit; + state.recursion_limit = C_RECURSION_LIMIT * COMPILER_STACK_FRAME_SCALE; switch (mod->kind) { case Module_kind: diff --git a/Python/ast_opt.c b/Python/ast_opt.c index b1d807bc..f8c4a951 100644 --- a/Python/ast_opt.c +++ b/Python/ast_opt.c @@ -2,6 +2,7 @@ #include "Python.h" #include "pycore_ast.h" // _PyAST_GetDocString() #include "pycore_compile.h" // _PyASTOptimizeState +#include "pycore_long.h" // _PyLong #include "pycore_pystate.h" // _PyThreadState_GET() #include "pycore_format.h" // F_LJUST @@ -152,7 +153,9 @@ check_complexity(PyObject *obj, Py_ssize_t limit) static PyObject * safe_multiply(PyObject *v, PyObject *w) { - if (PyLong_Check(v) && PyLong_Check(w) && Py_SIZE(v) && Py_SIZE(w)) { + if (PyLong_Check(v) && PyLong_Check(w) && + !_PyLong_IsZero((PyLongObject *)v) && !_PyLong_IsZero((PyLongObject *)w) + ) { size_t vbits = _PyLong_NumBits(v); size_t wbits = _PyLong_NumBits(w); if (vbits == (size_t)-1 || wbits == (size_t)-1) { @@ -198,7 +201,9 @@ safe_multiply(PyObject *v, PyObject *w) static PyObject * safe_power(PyObject *v, PyObject *w) { - if (PyLong_Check(v) && PyLong_Check(w) && Py_SIZE(v) && Py_SIZE(w) > 0) { + if (PyLong_Check(v) && PyLong_Check(w) && + !_PyLong_IsZero((PyLongObject *)v) && _PyLong_IsPositive((PyLongObject *)w) + ) { size_t vbits = _PyLong_NumBits(v); size_t wbits = PyLong_AsSize_t(w); if (vbits == (size_t)-1 || wbits == (size_t)-1) { @@ -215,7 +220,9 @@ safe_power(PyObject *v, PyObject *w) static PyObject * safe_lshift(PyObject *v, PyObject *w) { - if (PyLong_Check(v) && PyLong_Check(w) && Py_SIZE(v) && Py_SIZE(w)) { + if (PyLong_Check(v) && PyLong_Check(w) && + !_PyLong_IsZero((PyLongObject *)v) && !_PyLong_IsZero((PyLongObject *)w) + ) { size_t vbits = _PyLong_NumBits(v); size_t wbits = PyLong_AsSize_t(w); if (vbits == (size_t)-1 || wbits == (size_t)-1) { @@ -310,7 +317,6 @@ simple_format_arg_parse(PyObject *fmt, Py_ssize_t *ppos, case ' ': *flags |= F_BLANK; continue; case '#': *flags |= F_ALT; continue; case '0': *flags |= F_ZERO; continue; - case 'z': *flags |= F_NO_NEG_0; continue; } break; } @@ -533,8 +539,7 @@ make_const_tuple(asdl_expr_seq *elts) for (int i = 0; i < asdl_seq_LEN(elts); i++) { expr_ty e = (expr_ty)asdl_seq_GET(elts, i); PyObject *v = e->v.Constant.value; - Py_INCREF(v); - PyTuple_SET_ITEM(newval, i, v); + PyTuple_SET_ITEM(newval, i, Py_NewRef(v)); } return newval; } @@ -637,6 +642,7 @@ static int astfold_withitem(withitem_ty node_, PyArena *ctx_, _PyASTOptimizeStat static int astfold_excepthandler(excepthandler_ty node_, PyArena *ctx_, _PyASTOptimizeState *state); static int astfold_match_case(match_case_ty node_, PyArena *ctx_, _PyASTOptimizeState *state); static int astfold_pattern(pattern_ty node_, PyArena *ctx_, _PyASTOptimizeState *state); +static int astfold_type_param(type_param_ty node_, PyArena *ctx_, _PyASTOptimizeState *state); #define CALL(FUNC, TYPE, ARG) \ if (!FUNC((ARG), ctx_, state)) \ @@ -875,6 +881,7 @@ astfold_stmt(stmt_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) } switch (node_->kind) { case FunctionDef_kind: + CALL_SEQ(astfold_type_param, type_param, node_->v.FunctionDef.type_params); CALL(astfold_arguments, arguments_ty, node_->v.FunctionDef.args); CALL(astfold_body, asdl_seq, node_->v.FunctionDef.body); CALL_SEQ(astfold_expr, expr, node_->v.FunctionDef.decorator_list); @@ -883,6 +890,7 @@ astfold_stmt(stmt_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) } break; case AsyncFunctionDef_kind: + CALL_SEQ(astfold_type_param, type_param, node_->v.AsyncFunctionDef.type_params); CALL(astfold_arguments, arguments_ty, node_->v.AsyncFunctionDef.args); CALL(astfold_body, asdl_seq, node_->v.AsyncFunctionDef.body); CALL_SEQ(astfold_expr, expr, node_->v.AsyncFunctionDef.decorator_list); @@ -891,6 +899,7 @@ astfold_stmt(stmt_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) } break; case ClassDef_kind: + CALL_SEQ(astfold_type_param, type_param, node_->v.ClassDef.type_params); CALL_SEQ(astfold_expr, expr, node_->v.ClassDef.bases); CALL_SEQ(astfold_keyword, keyword, node_->v.ClassDef.keywords); CALL(astfold_body, asdl_seq, node_->v.ClassDef.body); @@ -917,6 +926,11 @@ astfold_stmt(stmt_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) } CALL_OPT(astfold_expr, expr_ty, node_->v.AnnAssign.value); break; + case TypeAlias_kind: + CALL(astfold_expr, expr_ty, node_->v.TypeAlias.name); + CALL_SEQ(astfold_type_param, type_param, node_->v.TypeAlias.type_params); + CALL(astfold_expr, expr_ty, node_->v.TypeAlias.value); + break; case For_kind: CALL(astfold_expr, expr_ty, node_->v.For.target); CALL(astfold_expr, expr_ty, node_->v.For.iter); @@ -1069,18 +1083,32 @@ astfold_match_case(match_case_ty node_, PyArena *ctx_, _PyASTOptimizeState *stat return 1; } +static int +astfold_type_param(type_param_ty node_, PyArena *ctx_, _PyASTOptimizeState *state) +{ + switch (node_->kind) { + case TypeVar_kind: + CALL_OPT(astfold_expr, expr_ty, node_->v.TypeVar.bound); + break; + case ParamSpec_kind: + break; + case TypeVarTuple_kind: + break; + } + return 1; +} + #undef CALL #undef CALL_OPT #undef CALL_SEQ /* See comments in symtable.c. */ -#define COMPILER_STACK_FRAME_SCALE 3 +#define COMPILER_STACK_FRAME_SCALE 2 int _PyAST_Optimize(mod_ty mod, PyArena *arena, _PyASTOptimizeState *state) { PyThreadState *tstate; - int recursion_limit = Py_GetRecursionLimit(); int starting_recursion_depth; /* Setup recursion depth check counters */ @@ -1089,12 +1117,10 @@ _PyAST_Optimize(mod_ty mod, PyArena *arena, _PyASTOptimizeState *state) return 0; } /* Be careful here to prevent overflow. */ - int recursion_depth = tstate->recursion_limit - tstate->recursion_remaining; - starting_recursion_depth = (recursion_depth < INT_MAX / COMPILER_STACK_FRAME_SCALE) ? - recursion_depth * COMPILER_STACK_FRAME_SCALE : recursion_depth; + int recursion_depth = C_RECURSION_LIMIT - tstate->c_recursion_remaining; + starting_recursion_depth = recursion_depth * COMPILER_STACK_FRAME_SCALE; state->recursion_depth = starting_recursion_depth; - state->recursion_limit = (recursion_limit < INT_MAX / COMPILER_STACK_FRAME_SCALE) ? - recursion_limit * COMPILER_STACK_FRAME_SCALE : recursion_limit; + state->recursion_limit = C_RECURSION_LIMIT * COMPILER_STACK_FRAME_SCALE; int ret = astfold_mod(mod, arena, state); assert(ret || PyErr_Occurred()); diff --git a/Python/ast_unparse.c b/Python/ast_unparse.c index 6565b6b3..8aff0451 100644 --- a/Python/ast_unparse.c +++ b/Python/ast_unparse.c @@ -1,5 +1,6 @@ #include "Python.h" #include "pycore_ast.h" // expr_ty +#include "pycore_pystate.h" // _PyInterpreterState_GET() #include "pycore_runtime.h" // _Py_ID() #include <float.h> // DBL_MAX_10_EXP #include <stdbool.h> @@ -13,7 +14,10 @@ _Py_DECLARE_STR(open_br, "{"); _Py_DECLARE_STR(dbl_open_br, "{{"); _Py_DECLARE_STR(close_br, "}"); _Py_DECLARE_STR(dbl_close_br, "}}"); -static PyObject *_str_replace_inf; + +/* We would statically initialize this if doing so were simple enough. */ +#define _str_replace_inf(interp) \ + _Py_INTERP_CACHED_OBJECT(interp, str_replace_inf) /* Forward declarations for recursion via helper functions. */ static PyObject * @@ -78,10 +82,11 @@ append_repr(_PyUnicodeWriter *writer, PyObject *obj) if ((PyFloat_CheckExact(obj) && Py_IS_INFINITY(PyFloat_AS_DOUBLE(obj))) || PyComplex_CheckExact(obj)) { + PyInterpreterState *interp = _PyInterpreterState_GET(); PyObject *new_repr = PyUnicode_Replace( repr, &_Py_ID(inf), - _str_replace_inf, + _str_replace_inf(interp), -1 ); Py_DECREF(repr); @@ -916,9 +921,13 @@ append_ast_expr(_PyUnicodeWriter *writer, expr_ty e, int level) static int maybe_init_static_strings(void) { - if (!_str_replace_inf && - !(_str_replace_inf = PyUnicode_FromFormat("1e%d", 1 + DBL_MAX_10_EXP))) { - return -1; + PyInterpreterState *interp = _PyInterpreterState_GET(); + if (_str_replace_inf(interp) == NULL) { + PyObject *tmp = PyUnicode_FromFormat("1e%d", 1 + DBL_MAX_10_EXP); + if (tmp == NULL) { + return -1; + } + _str_replace_inf(interp) = tmp; } return 0; } diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index a3fdb394..7f366b43 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -5,6 +5,7 @@ #include "pycore_ast.h" // _PyAST_Validate() #include "pycore_call.h" // _PyObject_CallNoArgs() #include "pycore_compile.h" // _PyAST_Compile() +#include "pycore_long.h" // _PyLong_CompactValue #include "pycore_object.h" // _Py_AddToAllObjects() #include "pycore_pyerrors.h" // _PyErr_NoMemory() #include "pycore_pystate.h" // _PyThreadState_GET() @@ -63,8 +64,7 @@ update_bases(PyObject *bases, PyObject *const *args, Py_ssize_t nargs) } for (j = 0; j < i; j++) { base = args[j]; - PyList_SET_ITEM(new_bases, j, base); - Py_INCREF(base); + PyList_SET_ITEM(new_bases, j, Py_NewRef(base)); } } j = PyList_GET_SIZE(new_bases); @@ -169,9 +169,7 @@ builtin___build_class__(PyObject *self, PyObject *const *args, Py_ssize_t nargs, goto error; } if (winner != meta) { - Py_DECREF(meta); - meta = winner; - Py_INCREF(meta); + Py_SETREF(meta, Py_NewRef(winner)); } } /* else: meta is not a class, so we cannot do the metaclass @@ -198,6 +196,7 @@ builtin___build_class__(PyObject *self, PyObject *const *args, Py_ssize_t nargs, goto error; } PyThreadState *tstate = _PyThreadState_GET(); + EVAL_CALL_STAT_INC(EVAL_CALL_BUILD_CLASS); cell = _PyEval_Vector(tstate, (PyFunctionObject *)func, ns, NULL, 0, NULL); if (cell != NULL) { if (bases != orig_bases) { @@ -220,8 +219,7 @@ builtin___build_class__(PyObject *self, PyObject *const *args, Py_ssize_t nargs, "__class__ set to %.200R defining %.200R as %.200R"; PyErr_Format(PyExc_TypeError, msg, cell_cls, name, cls); } - Py_DECREF(cls); - cls = NULL; + Py_SETREF(cls, NULL); goto error; } } @@ -556,9 +554,11 @@ static void filter_dealloc(filterobject *lz) { PyObject_GC_UnTrack(lz); + Py_TRASHCAN_BEGIN(lz, filter_dealloc) Py_XDECREF(lz->func); Py_XDECREF(lz->it); Py_TYPE(lz)->tp_free(lz); + Py_TRASHCAN_END } static int @@ -676,16 +676,19 @@ format as builtin_format format_spec: unicode(c_default="NULL") = '' / -Return value.__format__(format_spec) +Return type(value).__format__(value, format_spec) + +Many built-in types implement format_spec according to the +Format Specification Mini-language. See help('FORMATTING'). -format_spec defaults to the empty string. -See the Format Specification Mini-Language section of help('FORMATTING') for -details. +If type(value) does not supply a method named __format__ +and format_spec is empty, then str(value) is returned. +See also help('SPECIALMETHODS'). [clinic start generated code]*/ static PyObject * builtin_format_impl(PyObject *module, PyObject *value, PyObject *format_spec) -/*[clinic end generated code: output=2f40bdfa4954b077 input=88339c93ea522b33]*/ +/*[clinic end generated code: output=2f40bdfa4954b077 input=45ef3934b86d5624]*/ { return PyObject_Format(value, format_spec); } @@ -714,7 +717,7 @@ compile as builtin_compile filename: object(converter="PyUnicode_FSDecoder") mode: str flags: int = 0 - dont_inherit: bool(accept={int}) = False + dont_inherit: bool = False optimize: int = -1 * _feature_version as feature_version: int = -1 @@ -737,7 +740,7 @@ static PyObject * builtin_compile_impl(PyObject *module, PyObject *source, PyObject *filename, const char *mode, int flags, int dont_inherit, int optimize, int feature_version) -/*[clinic end generated code: output=b0c09c84f116d3d7 input=40171fb92c1d580d]*/ +/*[clinic end generated code: output=b0c09c84f116d3d7 input=cc78e20e7c7682ba]*/ { PyObject *source_copy; const char *str; @@ -800,8 +803,7 @@ builtin_compile_impl(PyObject *module, PyObject *source, PyObject *filename, goto error; if (is_ast) { if (flags & PyCF_ONLY_AST) { - Py_INCREF(source); - result = source; + result = Py_NewRef(source); } else { PyArena *arena; @@ -838,31 +840,33 @@ finally: return result; } -/* AC: cannot convert yet, as needs PEP 457 group support in inspect */ +/*[clinic input] +dir as builtin_dir + + arg: object = NULL + / + +Show attributes of an object. + +If called without an argument, return the names in the current scope. +Else, return an alphabetized list of names comprising (some of) the attributes +of the given object, and of attributes reachable from it. +If the object supplies a method named __dir__, it will be used; otherwise +the default dir() logic is used and returns: + for a module object: the module's attributes. + for a class object: its attributes, and recursively the attributes + of its bases. + for any other object: its attributes, its class's attributes, and + recursively the attributes of its class's base classes. +[clinic start generated code]*/ + static PyObject * -builtin_dir(PyObject *self, PyObject *args) +builtin_dir_impl(PyObject *module, PyObject *arg) +/*[clinic end generated code: output=24f2c7a52c1e3b08 input=ed6d6ccb13d52251]*/ { - PyObject *arg = NULL; - - if (!PyArg_UnpackTuple(args, "dir", 0, 1, &arg)) - return NULL; return PyObject_Dir(arg); } -PyDoc_STRVAR(dir_doc, -"dir([object]) -> list of strings\n" -"\n" -"If called without an argument, return the names in the current scope.\n" -"Else, return an alphabetized list of names comprising (some of) the attributes\n" -"of the given object, and of attributes reachable from it.\n" -"If the object supplies a method named __dir__, it will be used; otherwise\n" -"the default dir() logic is used and returns:\n" -" for a module object: the module's attributes.\n" -" for a class object: its attributes, and recursively the attributes\n" -" of its bases.\n" -" for any other object: its attributes, its class's attributes, and\n" -" recursively the attributes of its class's base classes."); - /*[clinic input] divmod as builtin_divmod @@ -903,7 +907,7 @@ builtin_eval_impl(PyObject *module, PyObject *source, PyObject *globals, PyObject *locals) /*[clinic end generated code: output=0a0824aa70093116 input=11ee718a8640e527]*/ { - PyObject *result, *source_copy; + PyObject *result = NULL, *source_copy; const char *str; if (locals != Py_None && !PyMapping_Check(locals)) { @@ -919,19 +923,25 @@ builtin_eval_impl(PyObject *module, PyObject *source, PyObject *globals, if (globals == Py_None) { globals = PyEval_GetGlobals(); if (locals == Py_None) { - locals = PyEval_GetLocals(); + locals = _PyEval_GetFrameLocals(); if (locals == NULL) return NULL; } + else { + Py_INCREF(locals); + } } else if (locals == Py_None) - locals = globals; + locals = Py_NewRef(globals); + else { + Py_INCREF(locals); + } if (globals == NULL || locals == NULL) { PyErr_SetString(PyExc_TypeError, "eval must be given globals and locals " "when called without a frame"); - return NULL; + goto error; } int r = PyDict_Contains(globals, &_Py_ID(__builtins__)); @@ -939,34 +949,38 @@ builtin_eval_impl(PyObject *module, PyObject *source, PyObject *globals, r = PyDict_SetItem(globals, &_Py_ID(__builtins__), PyEval_GetBuiltins()); } if (r < 0) { - return NULL; + goto error; } if (PyCode_Check(source)) { if (PySys_Audit("exec", "O", source) < 0) { - return NULL; + goto error; } if (PyCode_GetNumFree((PyCodeObject *)source) > 0) { PyErr_SetString(PyExc_TypeError, "code object passed to eval() may not contain free variables"); - return NULL; + goto error; } - return PyEval_EvalCode(source, globals, locals); + result = PyEval_EvalCode(source, globals, locals); } + else { + PyCompilerFlags cf = _PyCompilerFlags_INIT; + cf.cf_flags = PyCF_SOURCE_IS_UTF8; + str = _Py_SourceAsString(source, "eval", "string, bytes or code", &cf, &source_copy); + if (str == NULL) + goto error; - PyCompilerFlags cf = _PyCompilerFlags_INIT; - cf.cf_flags = PyCF_SOURCE_IS_UTF8; - str = _Py_SourceAsString(source, "eval", "string, bytes or code", &cf, &source_copy); - if (str == NULL) - return NULL; + while (*str == ' ' || *str == '\t') + str++; - while (*str == ' ' || *str == '\t') - str++; + (void)PyEval_MergeCompilerFlags(&cf); + result = PyRun_StringFlags(str, Py_eval_input, globals, locals, &cf); + Py_XDECREF(source_copy); + } - (void)PyEval_MergeCompilerFlags(&cf); - result = PyRun_StringFlags(str, Py_eval_input, globals, locals, &cf); - Py_XDECREF(source_copy); + error: + Py_XDECREF(locals); return result; } @@ -1001,36 +1015,43 @@ builtin_exec_impl(PyObject *module, PyObject *source, PyObject *globals, if (globals == Py_None) { globals = PyEval_GetGlobals(); if (locals == Py_None) { - locals = PyEval_GetLocals(); + locals = _PyEval_GetFrameLocals(); if (locals == NULL) return NULL; } + else { + Py_INCREF(locals); + } if (!globals || !locals) { PyErr_SetString(PyExc_SystemError, "globals and locals cannot be NULL"); return NULL; } } - else if (locals == Py_None) - locals = globals; + else if (locals == Py_None) { + locals = Py_NewRef(globals); + } + else { + Py_INCREF(locals); + } if (!PyDict_Check(globals)) { PyErr_Format(PyExc_TypeError, "exec() globals must be a dict, not %.100s", Py_TYPE(globals)->tp_name); - return NULL; + goto error; } if (!PyMapping_Check(locals)) { PyErr_Format(PyExc_TypeError, "locals must be a mapping or None, not %.100s", Py_TYPE(locals)->tp_name); - return NULL; + goto error; } int r = PyDict_Contains(globals, &_Py_ID(__builtins__)); if (r == 0) { r = PyDict_SetItem(globals, &_Py_ID(__builtins__), PyEval_GetBuiltins()); } if (r < 0) { - return NULL; + goto error; } if (closure == Py_None) { @@ -1043,7 +1064,7 @@ builtin_exec_impl(PyObject *module, PyObject *source, PyObject *globals, if (closure) { PyErr_SetString(PyExc_TypeError, "cannot use a closure with this code object"); - return NULL; + goto error; } } else { int closure_is_ok = @@ -1063,12 +1084,12 @@ builtin_exec_impl(PyObject *module, PyObject *source, PyObject *globals, PyErr_Format(PyExc_TypeError, "code object requires a closure of exactly length %zd", num_free); - return NULL; + goto error; } } if (PySys_Audit("exec", "O", source) < 0) { - return NULL; + goto error; } if (!closure) { @@ -1095,7 +1116,7 @@ builtin_exec_impl(PyObject *module, PyObject *source, PyObject *globals, "string, bytes or code", &cf, &source_copy); if (str == NULL) - return NULL; + goto error; if (PyEval_MergeCompilerFlags(&cf)) v = PyRun_StringFlags(str, Py_file_input, globals, locals, &cf); @@ -1104,43 +1125,50 @@ builtin_exec_impl(PyObject *module, PyObject *source, PyObject *globals, Py_XDECREF(source_copy); } if (v == NULL) - return NULL; + goto error; + Py_DECREF(locals); Py_DECREF(v); Py_RETURN_NONE; + + error: + Py_XDECREF(locals); + return NULL; } -/* AC: cannot convert yet, as needs PEP 457 group support in inspect */ +/*[clinic input] +getattr as builtin_getattr + + object: object + name: object + default: object = NULL + / + +Get a named attribute from an object. + +getattr(x, 'y') is equivalent to x.y +When a default argument is given, it is returned when the attribute doesn't +exist; without it, an exception is raised in that case. +[clinic start generated code]*/ + static PyObject * -builtin_getattr(PyObject *self, PyObject *const *args, Py_ssize_t nargs) +builtin_getattr_impl(PyObject *module, PyObject *object, PyObject *name, + PyObject *default_value) +/*[clinic end generated code: output=74ad0e225e3f701c input=d7562cd4c3556171]*/ { - PyObject *v, *name, *result; - - if (!_PyArg_CheckPositional("getattr", nargs, 2, 3)) - return NULL; + PyObject *result; - v = args[0]; - name = args[1]; - if (nargs > 2) { - if (_PyObject_LookupAttr(v, name, &result) == 0) { - PyObject *dflt = args[2]; - Py_INCREF(dflt); - return dflt; + if (default_value != NULL) { + if (_PyObject_LookupAttr(object, name, &result) == 0) { + return Py_NewRef(default_value); } } else { - result = PyObject_GetAttr(v, name); + result = PyObject_GetAttr(object, name); } return result; } -PyDoc_STRVAR(getattr_doc, -"getattr(object, name[, default]) -> value\n\ -\n\ -Get a named attribute from an object; getattr(x, 'y') is equivalent to x.y.\n\ -When a default argument is given, it is returned when the attribute doesn't\n\ -exist; without it, an exception is raised in that case."); - /*[clinic input] globals as builtin_globals @@ -1158,8 +1186,7 @@ builtin_globals_impl(PyObject *module) PyObject *d; d = PyEval_GetGlobals(); - Py_XINCREF(d); - return d; + return Py_XNewRef(d); } @@ -1386,12 +1413,10 @@ map_reduce(mapobject *lz, PyObject *Py_UNUSED(ignored)) Py_ssize_t i; if (args == NULL) return NULL; - Py_INCREF(lz->func); - PyTuple_SET_ITEM(args, 0, lz->func); + PyTuple_SET_ITEM(args, 0, Py_NewRef(lz->func)); for (i = 0; i<numargs; i++){ PyObject *it = PyTuple_GET_ITEM(lz->iters, i); - Py_INCREF(it); - PyTuple_SET_ITEM(args, i+1, it); + PyTuple_SET_ITEM(args, i+1, Py_NewRef(it)); } return Py_BuildValue("ON", Py_TYPE(lz), args); @@ -1455,35 +1480,43 @@ PyTypeObject PyMap_Type = { }; -/* AC: cannot convert yet, as needs PEP 457 group support in inspect */ +/*[clinic input] +next as builtin_next + + iterator: object + default: object = NULL + / + +Return the next item from the iterator. + +If default is given and the iterator is exhausted, +it is returned instead of raising StopIteration. +[clinic start generated code]*/ + static PyObject * -builtin_next(PyObject *self, PyObject *const *args, Py_ssize_t nargs) +builtin_next_impl(PyObject *module, PyObject *iterator, + PyObject *default_value) +/*[clinic end generated code: output=a38a94eeb447fef9 input=180f9984f182020f]*/ { - PyObject *it, *res; - - if (!_PyArg_CheckPositional("next", nargs, 1, 2)) - return NULL; + PyObject *res; - it = args[0]; - if (!PyIter_Check(it)) { + if (!PyIter_Check(iterator)) { PyErr_Format(PyExc_TypeError, "'%.200s' object is not an iterator", - Py_TYPE(it)->tp_name); + Py_TYPE(iterator)->tp_name); return NULL; } - res = (*Py_TYPE(it)->tp_iternext)(it); + res = (*Py_TYPE(iterator)->tp_iternext)(iterator); if (res != NULL) { return res; - } else if (nargs > 1) { - PyObject *def = args[1]; + } else if (default_value != NULL) { if (PyErr_Occurred()) { if(!PyErr_ExceptionMatches(PyExc_StopIteration)) return NULL; PyErr_Clear(); } - Py_INCREF(def); - return def; + return Py_NewRef(default_value); } else if (PyErr_Occurred()) { return NULL; } else { @@ -1492,12 +1525,6 @@ builtin_next(PyObject *self, PyObject *const *args, Py_ssize_t nargs) } } -PyDoc_STRVAR(next_doc, -"next(iterator[, default])\n\ -\n\ -Return the next item from the iterator. If default is given and the iterator\n\ -is exhausted, it is returned instead of raising StopIteration."); - /*[clinic input] setattr as builtin_setattr @@ -1590,34 +1617,33 @@ builtin_hex(PyObject *module, PyObject *number) } -/* AC: cannot convert yet, as needs PEP 457 group support in inspect */ +/*[clinic input] +iter as builtin_iter + + object: object + sentinel: object = NULL + / + +Get an iterator from an object. + +In the first form, the argument must supply its own iterator, or be a sequence. +In the second form, the callable is called until it returns the sentinel. +[clinic start generated code]*/ + static PyObject * -builtin_iter(PyObject *self, PyObject *const *args, Py_ssize_t nargs) +builtin_iter_impl(PyObject *module, PyObject *object, PyObject *sentinel) +/*[clinic end generated code: output=12cf64203c195a94 input=a5d64d9d81880ba6]*/ { - PyObject *v; - - if (!_PyArg_CheckPositional("iter", nargs, 1, 2)) - return NULL; - v = args[0]; - if (nargs == 1) - return PyObject_GetIter(v); - if (!PyCallable_Check(v)) { + if (sentinel == NULL) + return PyObject_GetIter(object); + if (!PyCallable_Check(object)) { PyErr_SetString(PyExc_TypeError, - "iter(v, w): v must be callable"); + "iter(object, sentinel): object must be callable"); return NULL; } - PyObject *sentinel = args[1]; - return PyCallIter_New(v, sentinel); + return PyCallIter_New(object, sentinel); } -PyDoc_STRVAR(iter_doc, -"iter(iterable) -> iterator\n\ -iter(callable, sentinel) -> iterator\n\ -\n\ -Get an iterator from an object. In the first form, the argument must\n\ -supply its own iterator, or be a sequence.\n\ -In the second form, the callable is called until it returns the sentinel."); - /*[clinic input] aiter as builtin_aiter @@ -1716,11 +1742,7 @@ static PyObject * builtin_locals_impl(PyObject *module) /*[clinic end generated code: output=b46c94015ce11448 input=7874018d478d5c4b]*/ { - PyObject *d; - - d = PyEval_GetLocals(); - Py_XINCREF(d); - return d; + return _PyEval_GetFrameLocals(); } @@ -1781,8 +1803,7 @@ min_max(PyObject *args, PyObject *kwds, int op) } /* no key function; the value is the item */ else { - val = item; - Py_INCREF(val); + val = Py_NewRef(item); } /* maximum value and item are unset; set them */ @@ -1812,11 +1833,10 @@ min_max(PyObject *args, PyObject *kwds, int op) if (maxval == NULL) { assert(maxitem == NULL); if (defaultval != NULL) { - Py_INCREF(defaultval); - maxitem = defaultval; + maxitem = Py_NewRef(defaultval); } else { PyErr_Format(PyExc_ValueError, - "%s() arg is an empty sequence", name); + "%s() iterable argument is empty", name); } } else @@ -2163,17 +2183,29 @@ builtin_input_impl(PyObject *module, PyObject *prompt) /* stdin is a text stream, so it must have an encoding. */ stdin_encoding = PyObject_GetAttr(fin, &_Py_ID(encoding)); + if (stdin_encoding == NULL) { + tty = 0; + goto _readline_errors; + } stdin_errors = PyObject_GetAttr(fin, &_Py_ID(errors)); - if (!stdin_encoding || !stdin_errors || - !PyUnicode_Check(stdin_encoding) || - !PyUnicode_Check(stdin_errors)) { + if (stdin_errors == NULL) { + tty = 0; + goto _readline_errors; + } + if (!PyUnicode_Check(stdin_encoding) || + !PyUnicode_Check(stdin_errors)) + { tty = 0; goto _readline_errors; } stdin_encoding_str = PyUnicode_AsUTF8(stdin_encoding); + if (stdin_encoding_str == NULL) { + goto _readline_errors; + } stdin_errors_str = PyUnicode_AsUTF8(stdin_errors); - if (!stdin_encoding_str || !stdin_errors_str) + if (stdin_errors_str == NULL) { goto _readline_errors; + } tmp = PyObject_CallMethodNoArgs(fout, &_Py_ID(flush)); if (tmp == NULL) PyErr_Clear(); @@ -2184,17 +2216,29 @@ builtin_input_impl(PyObject *module, PyObject *prompt) const char *stdout_encoding_str, *stdout_errors_str; PyObject *stringpo; stdout_encoding = PyObject_GetAttr(fout, &_Py_ID(encoding)); + if (stdout_encoding == NULL) { + tty = 0; + goto _readline_errors; + } stdout_errors = PyObject_GetAttr(fout, &_Py_ID(errors)); - if (!stdout_encoding || !stdout_errors || - !PyUnicode_Check(stdout_encoding) || - !PyUnicode_Check(stdout_errors)) { + if (stdout_errors == NULL) { + tty = 0; + goto _readline_errors; + } + if (!PyUnicode_Check(stdout_encoding) || + !PyUnicode_Check(stdout_errors)) + { tty = 0; goto _readline_errors; } stdout_encoding_str = PyUnicode_AsUTF8(stdout_encoding); + if (stdout_encoding_str == NULL) { + goto _readline_errors; + } stdout_errors_str = PyUnicode_AsUTF8(stdout_errors); - if (!stdout_encoding_str || !stdout_errors_str) + if (stdout_errors_str == NULL) { goto _readline_errors; + } stringpo = PyObject_Str(prompt); if (stringpo == NULL) goto _readline_errors; @@ -2315,7 +2359,7 @@ builtin_round_impl(PyObject *module, PyObject *number, PyObject *ndigits) { PyObject *round, *result; - if (Py_TYPE(number)->tp_dict == NULL) { + if (!_PyType_IsReady(Py_TYPE(number))) { if (PyType_Ready(Py_TYPE(number)) < 0) return NULL; } @@ -2399,21 +2443,29 @@ builtin_sorted(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject } -/* AC: cannot convert yet, as needs PEP 457 group support in inspect */ +/*[clinic input] +vars as builtin_vars + + object: object = NULL + / + +Show vars. + +Without arguments, equivalent to locals(). +With an argument, equivalent to object.__dict__. +[clinic start generated code]*/ + static PyObject * -builtin_vars(PyObject *self, PyObject *args) +builtin_vars_impl(PyObject *module, PyObject *object) +/*[clinic end generated code: output=840a7f64007a3e0a input=80cbdef9182c4ba3]*/ { - PyObject *v = NULL; PyObject *d; - if (!PyArg_UnpackTuple(args, "vars", 0, 1, &v)) - return NULL; - if (v == NULL) { - d = PyEval_GetLocals(); - Py_XINCREF(d); + if (object == NULL) { + d = _PyEval_GetFrameLocals(); } else { - if (_PyObject_LookupAttr(v, &_Py_ID(__dict__), &d) == 0) { + if (_PyObject_LookupAttr(object, &_Py_ID(__dict__), &d) == 0) { PyErr_SetString(PyExc_TypeError, "vars() argument must have __dict__ attribute"); } @@ -2421,12 +2473,6 @@ builtin_vars(PyObject *self, PyObject *args) return d; } -PyDoc_STRVAR(vars_doc, -"vars([object]) -> dictionary\n\ -\n\ -Without arguments, equivalent to locals().\n\ -With an argument, equivalent to object.__dict__."); - /*[clinic input] sum as builtin_sum @@ -2489,11 +2535,10 @@ builtin_sum_impl(PyObject *module, PyObject *iterable, PyObject *start) */ if (PyLong_CheckExact(result)) { int overflow; - long i_result = PyLong_AsLongAndOverflow(result, &overflow); + Py_ssize_t i_result = PyLong_AsLongAndOverflow(result, &overflow); /* If this already overflowed, don't even enter the loop. */ if (overflow == 0) { - Py_DECREF(result); - result = NULL; + Py_SETREF(result, NULL); } while(result == NULL) { item = PyIter_Next(iter); @@ -2501,18 +2546,17 @@ builtin_sum_impl(PyObject *module, PyObject *iterable, PyObject *start) Py_DECREF(iter); if (PyErr_Occurred()) return NULL; - return PyLong_FromLong(i_result); + return PyLong_FromSsize_t(i_result); } if (PyLong_CheckExact(item) || PyBool_Check(item)) { - long b; + Py_ssize_t b; overflow = 0; /* Single digits are common, fast, and cannot overflow on unpacking. */ - switch (Py_SIZE(item)) { - case -1: b = -(sdigit) ((PyLongObject*)item)->ob_digit[0]; break; - // Note: the continue goes to the top of the "while" loop that iterates over the elements - case 0: Py_DECREF(item); continue; - case 1: b = ((PyLongObject*)item)->ob_digit[0]; break; - default: b = PyLong_AsLongAndOverflow(item, &overflow); break; + if (_PyLong_IsCompact((PyLongObject *)item)) { + b = _PyLong_CompactValue((PyLongObject *)item); + } + else { + b = PyLong_AsLongAndOverflow(item, &overflow); } if (overflow == 0 && (i_result >= 0 ? (b <= LONG_MAX - i_result) @@ -2524,7 +2568,7 @@ builtin_sum_impl(PyObject *module, PyObject *iterable, PyObject *start) } } /* Either overflowed or is not an int. Restore real objects and process normally */ - result = PyLong_FromLong(i_result); + result = PyLong_FromSsize_t(i_result); if (result == NULL) { Py_DECREF(item); Py_DECREF(iter); @@ -2543,18 +2587,33 @@ builtin_sum_impl(PyObject *module, PyObject *iterable, PyObject *start) if (PyFloat_CheckExact(result)) { double f_result = PyFloat_AS_DOUBLE(result); - Py_DECREF(result); - result = NULL; + double c = 0.0; + Py_SETREF(result, NULL); while(result == NULL) { item = PyIter_Next(iter); if (item == NULL) { Py_DECREF(iter); if (PyErr_Occurred()) return NULL; + /* Avoid losing the sign on a negative result, + and don't let adding the compensation convert + an infinite or overflowed sum to a NaN. */ + if (c && Py_IS_FINITE(c)) { + f_result += c; + } return PyFloat_FromDouble(f_result); } if (PyFloat_CheckExact(item)) { - f_result += PyFloat_AS_DOUBLE(item); + // Improved Kahan–BabuÅ¡ka algorithm by Arnold Neumaier + // https://www.mat.univie.ac.at/~neum/scan/01.pdf + double x = PyFloat_AS_DOUBLE(item); + double t = f_result + x; + if (fabs(f_result) >= fabs(x)) { + c += (f_result - t) + x; + } else { + c += (x - t) + f_result; + } + f_result = t; _Py_DECREF_SPECIALIZED(item, _PyFloat_ExactDealloc); continue; } @@ -2568,6 +2627,9 @@ builtin_sum_impl(PyObject *module, PyObject *iterable, PyObject *start) continue; } } + if (c && Py_IS_FINITE(c)) { + f_result += c; + } result = PyFloat_FromDouble(f_result); if (result == NULL) { Py_DECREF(item); @@ -2591,8 +2653,7 @@ builtin_sum_impl(PyObject *module, PyObject *iterable, PyObject *start) if (item == NULL) { /* error, or end-of-sequence */ if (PyErr_Occurred()) { - Py_DECREF(result); - result = NULL; + Py_SETREF(result, NULL); } break; } @@ -2733,8 +2794,7 @@ zip_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return NULL; } for (i=0 ; i < tuplesize ; i++) { - Py_INCREF(Py_None); - PyTuple_SET_ITEM(result, i, Py_None); + PyTuple_SET_ITEM(result, i, Py_NewRef(Py_None)); } /* create zipobject structure */ @@ -2961,12 +3021,12 @@ static PyMethodDef builtin_methods[] = { BUILTIN_CHR_METHODDEF BUILTIN_COMPILE_METHODDEF BUILTIN_DELATTR_METHODDEF - {"dir", builtin_dir, METH_VARARGS, dir_doc}, + BUILTIN_DIR_METHODDEF BUILTIN_DIVMOD_METHODDEF BUILTIN_EVAL_METHODDEF BUILTIN_EXEC_METHODDEF BUILTIN_FORMAT_METHODDEF - {"getattr", _PyCFunction_CAST(builtin_getattr), METH_FASTCALL, getattr_doc}, + BUILTIN_GETATTR_METHODDEF BUILTIN_GLOBALS_METHODDEF BUILTIN_HASATTR_METHODDEF BUILTIN_HASH_METHODDEF @@ -2975,13 +3035,13 @@ static PyMethodDef builtin_methods[] = { BUILTIN_INPUT_METHODDEF BUILTIN_ISINSTANCE_METHODDEF BUILTIN_ISSUBCLASS_METHODDEF - {"iter", _PyCFunction_CAST(builtin_iter), METH_FASTCALL, iter_doc}, + BUILTIN_ITER_METHODDEF BUILTIN_AITER_METHODDEF BUILTIN_LEN_METHODDEF BUILTIN_LOCALS_METHODDEF {"max", _PyCFunction_CAST(builtin_max), METH_VARARGS | METH_KEYWORDS, max_doc}, {"min", _PyCFunction_CAST(builtin_min), METH_VARARGS | METH_KEYWORDS, min_doc}, - {"next", _PyCFunction_CAST(builtin_next), METH_FASTCALL, next_doc}, + BUILTIN_NEXT_METHODDEF BUILTIN_ANEXT_METHODDEF BUILTIN_OCT_METHODDEF BUILTIN_ORD_METHODDEF @@ -2992,14 +3052,21 @@ static PyMethodDef builtin_methods[] = { BUILTIN_SETATTR_METHODDEF BUILTIN_SORTED_METHODDEF BUILTIN_SUM_METHODDEF - {"vars", builtin_vars, METH_VARARGS, vars_doc}, + BUILTIN_VARS_METHODDEF {NULL, NULL}, }; PyDoc_STRVAR(builtin_doc, -"Built-in functions, exceptions, and other objects.\n\ +"Built-in functions, types, exceptions, and other objects.\n\ +\n\ +This module provides direct access to all 'built-in'\n\ +identifiers of Python; for example, builtins.len is\n\ +the full name for the built-in function len().\n\ \n\ -Noteworthy: None is the `nil' object; Ellipsis represents `...' in slices."); +This module is not normally accessed explicitly by most\n\ +applications, but can be useful in modules that provide\n\ +objects with the same name as a built-in value, but in\n\ +which the built-in of that name is also needed."); static struct PyModuleDef builtinsmodule = { PyModuleDef_HEAD_INIT, diff --git a/Python/bootstrap_hash.c b/Python/bootstrap_hash.c index 3a2a7318..587063ef 100644 --- a/Python/bootstrap_hash.c +++ b/Python/bootstrap_hash.c @@ -1,6 +1,7 @@ #include "Python.h" #include "pycore_initconfig.h" #include "pycore_fileutils.h" // _Py_fstat_noraise() +#include "pycore_runtime.h" // _PyRuntime #ifdef MS_WINDOWS # include <windows.h> @@ -263,11 +264,7 @@ py_getentropy(char *buffer, Py_ssize_t size, int raise) #endif /* defined(HAVE_GETENTROPY) && !(defined(__sun) && defined(__SVR4)) */ -static struct { - int fd; - dev_t st_dev; - ino_t st_ino; -} urandom_cache = { -1 }; +#define urandom_cache (_PyRuntime.pyhash_state.urandom_cache) /* Read random bytes from the /dev/urandom device: @@ -402,6 +399,9 @@ dev_urandom_close(void) urandom_cache.fd = -1; } } + +#undef urandom_cache + #endif /* !MS_WINDOWS */ diff --git a/Python/bytecodes.c b/Python/bytecodes.c new file mode 100644 index 00000000..dfebaaa3 --- /dev/null +++ b/Python/bytecodes.c @@ -0,0 +1,3506 @@ +// This file contains instruction definitions. +// It is read by Tools/cases_generator/generate_cases.py +// to generate Python/generated_cases.c.h. +// Note that there is some dummy C code at the top and bottom of the file +// to fool text editors like VS Code into believing this is valid C code. +// The actual instruction definitions start at // BEGIN BYTECODES //. +// See Tools/cases_generator/README.md for more information. + +#include "Python.h" +#include "pycore_abstract.h" // _PyIndex_Check() +#include "pycore_call.h" // _PyObject_FastCallDictTstate() +#include "pycore_ceval.h" // _PyEval_SignalAsyncExc() +#include "pycore_code.h" +#include "pycore_function.h" +#include "pycore_intrinsics.h" +#include "pycore_long.h" // _PyLong_GetZero() +#include "pycore_instruments.h" +#include "pycore_object.h" // _PyObject_GC_TRACK() +#include "pycore_moduleobject.h" // PyModuleObject +#include "pycore_opcode.h" // EXTRA_CASES +#include "pycore_pyerrors.h" // _PyErr_GetRaisedException() +#include "pycore_pymem.h" // _PyMem_IsPtrFreed() +#include "pycore_pystate.h" // _PyInterpreterState_GET() +#include "pycore_range.h" // _PyRangeIterObject +#include "pycore_sliceobject.h" // _PyBuildSlice_ConsumeRefs +#include "pycore_sysmodule.h" // _PySys_Audit() +#include "pycore_tuple.h" // _PyTuple_ITEMS() +#include "pycore_typeobject.h" // _PySuper_Lookup() +#include "pycore_emscripten_signal.h" // _Py_CHECK_EMSCRIPTEN_SIGNALS + +#include "pycore_dict.h" +#include "dictobject.h" +#include "pycore_frame.h" +#include "opcode.h" +#include "pydtrace.h" +#include "setobject.h" +#include "structmember.h" // struct PyMemberDef, T_OFFSET_EX + +#define USE_COMPUTED_GOTOS 0 +#include "ceval_macros.h" + +/* Flow control macros */ +#define DEOPT_IF(cond, instname) ((void)0) +#define ERROR_IF(cond, labelname) ((void)0) +#define GO_TO_INSTRUCTION(instname) ((void)0) +#define PREDICT(opname) ((void)0) + +#define inst(name, ...) case name: +#define op(name, ...) /* NAME is ignored */ +#define macro(name) static int MACRO_##name +#define super(name) static int SUPER_##name +#define family(name, ...) static int family_##name + +// Dummy variables for stack effects. +static PyObject *value, *value1, *value2, *left, *right, *res, *sum, *prod, *sub; +static PyObject *container, *start, *stop, *v, *lhs, *rhs, *res2; +static PyObject *list, *tuple, *dict, *owner, *set, *str, *tup, *map, *keys; +static PyObject *exit_func, *lasti, *val, *retval, *obj, *iter; +static PyObject *aiter, *awaitable, *iterable, *w, *exc_value, *bc, *locals; +static PyObject *orig, *excs, *update, *b, *fromlist, *level, *from; +static PyObject **pieces, **values; +static size_t jump; +// Dummy variables for cache effects +static uint16_t invert, counter, index, hint; +static uint32_t type_version; + +static PyObject * +dummy_func( + PyThreadState *tstate, + _PyInterpreterFrame *frame, + unsigned char opcode, + unsigned int oparg, + _PyCFrame cframe, + _Py_CODEUNIT *next_instr, + PyObject **stack_pointer, + PyObject *kwnames, + int throwflag, + binaryfunc binary_ops[], + PyObject *args[] +) +{ + // Dummy labels. + pop_1_error: + // Dummy locals. + PyObject *annotations; + PyObject *attrs; + PyObject *bottom; + PyObject *callable; + PyObject *callargs; + PyObject *closure; + PyObject *codeobj; + PyObject *cond; + PyObject *defaults; + PyObject *descr; + _PyInterpreterFrame entry_frame; + PyObject *exc; + PyObject *exit; + PyObject *fget; + PyObject *fmt_spec; + PyObject *func; + uint32_t func_version; + PyObject *getattribute; + PyObject *kwargs; + PyObject *kwdefaults; + PyObject *len_o; + PyObject *match; + PyObject *match_type; + PyObject *method; + PyObject *mgr; + Py_ssize_t min_args; + PyObject *names; + PyObject *new_exc; + PyObject *next; + PyObject *none; + PyObject *null; + PyObject *prev_exc; + PyObject *receiver; + PyObject *rest; + int result; + PyObject *self; + PyObject *seq; + PyObject *slice; + PyObject *step; + PyObject *subject; + PyObject *top; + PyObject *type; + PyObject *typevars; + int values_or_none; + + switch (opcode) { + +// BEGIN BYTECODES // + inst(NOP, (--)) { + } + + inst(RESUME, (--)) { + assert(tstate->cframe == &cframe); + assert(frame == cframe.current_frame); + /* Possibly combine this with eval breaker */ + if (frame->f_code->_co_instrumentation_version != tstate->interp->monitoring_version) { + int err = _Py_Instrument(frame->f_code, tstate->interp); + ERROR_IF(err, error); + next_instr--; + } + else if (_Py_atomic_load_relaxed_int32(&tstate->interp->ceval.eval_breaker) && oparg < 2) { + goto handle_eval_breaker; + } + } + + inst(INSTRUMENTED_RESUME, (--)) { + /* Possible performance enhancement: + * We need to check the eval breaker anyway, can we + * combine the instrument verison check and the eval breaker test? + */ + if (frame->f_code->_co_instrumentation_version != tstate->interp->monitoring_version) { + if (_Py_Instrument(frame->f_code, tstate->interp)) { + goto error; + } + next_instr--; + } + else { + _PyFrame_SetStackPointer(frame, stack_pointer); + int err = _Py_call_instrumentation( + tstate, oparg > 0, frame, next_instr-1); + stack_pointer = _PyFrame_GetStackPointer(frame); + ERROR_IF(err, error); + if (frame->prev_instr != next_instr-1) { + /* Instrumentation has jumped */ + next_instr = frame->prev_instr; + DISPATCH(); + } + if (_Py_atomic_load_relaxed_int32(&tstate->interp->ceval.eval_breaker) && oparg < 2) { + goto handle_eval_breaker; + } + } + } + + inst(LOAD_CLOSURE, (-- value)) { + /* We keep LOAD_CLOSURE so that the bytecode stays more readable. */ + value = GETLOCAL(oparg); + ERROR_IF(value == NULL, unbound_local_error); + Py_INCREF(value); + } + + inst(LOAD_FAST_CHECK, (-- value)) { + value = GETLOCAL(oparg); + ERROR_IF(value == NULL, unbound_local_error); + Py_INCREF(value); + } + + inst(LOAD_FAST, (-- value)) { + value = GETLOCAL(oparg); + assert(value != NULL); + Py_INCREF(value); + } + + inst(LOAD_FAST_AND_CLEAR, (-- value)) { + value = GETLOCAL(oparg); + // do not use SETLOCAL here, it decrefs the old value + GETLOCAL(oparg) = NULL; + } + + inst(LOAD_CONST, (-- value)) { + value = GETITEM(frame->f_code->co_consts, oparg); + Py_INCREF(value); + } + + inst(STORE_FAST, (value --)) { + SETLOCAL(oparg, value); + } + + super(LOAD_FAST__LOAD_FAST) = LOAD_FAST + LOAD_FAST; + super(LOAD_FAST__LOAD_CONST) = LOAD_FAST + LOAD_CONST; + super(STORE_FAST__LOAD_FAST) = STORE_FAST + LOAD_FAST; + super(STORE_FAST__STORE_FAST) = STORE_FAST + STORE_FAST; + super(LOAD_CONST__LOAD_FAST) = LOAD_CONST + LOAD_FAST; + + inst(POP_TOP, (value --)) { + DECREF_INPUTS(); + } + + inst(PUSH_NULL, (-- res)) { + res = NULL; + } + + macro(END_FOR) = POP_TOP + POP_TOP; + + inst(INSTRUMENTED_END_FOR, (receiver, value --)) { + /* Need to create a fake StopIteration error here, + * to conform to PEP 380 */ + if (PyGen_Check(receiver)) { + PyErr_SetObject(PyExc_StopIteration, value); + if (monitor_stop_iteration(tstate, frame, next_instr-1)) { + goto error; + } + PyErr_SetRaisedException(NULL); + } + DECREF_INPUTS(); + } + + inst(END_SEND, (receiver, value -- value)) { + Py_DECREF(receiver); + } + + inst(INSTRUMENTED_END_SEND, (receiver, value -- value)) { + if (PyGen_Check(receiver) || PyCoro_CheckExact(receiver)) { + PyErr_SetObject(PyExc_StopIteration, value); + if (monitor_stop_iteration(tstate, frame, next_instr-1)) { + goto error; + } + PyErr_SetRaisedException(NULL); + } + Py_DECREF(receiver); + } + + inst(UNARY_NEGATIVE, (value -- res)) { + res = PyNumber_Negative(value); + DECREF_INPUTS(); + ERROR_IF(res == NULL, error); + } + + inst(UNARY_NOT, (value -- res)) { + int err = PyObject_IsTrue(value); + DECREF_INPUTS(); + ERROR_IF(err < 0, error); + if (err == 0) { + res = Py_True; + } + else { + res = Py_False; + } + } + + inst(UNARY_INVERT, (value -- res)) { + res = PyNumber_Invert(value); + DECREF_INPUTS(); + ERROR_IF(res == NULL, error); + } + + family(binary_op, INLINE_CACHE_ENTRIES_BINARY_OP) = { + BINARY_OP, + BINARY_OP_ADD_FLOAT, + BINARY_OP_ADD_INT, + BINARY_OP_ADD_UNICODE, + // BINARY_OP_INPLACE_ADD_UNICODE, // This is an odd duck. + BINARY_OP_MULTIPLY_FLOAT, + BINARY_OP_MULTIPLY_INT, + BINARY_OP_SUBTRACT_FLOAT, + BINARY_OP_SUBTRACT_INT, + }; + + + inst(BINARY_OP_MULTIPLY_INT, (unused/1, left, right -- prod)) { + DEOPT_IF(!PyLong_CheckExact(left), BINARY_OP); + DEOPT_IF(!PyLong_CheckExact(right), BINARY_OP); + STAT_INC(BINARY_OP, hit); + prod = _PyLong_Multiply((PyLongObject *)left, (PyLongObject *)right); + _Py_DECREF_SPECIALIZED(right, (destructor)PyObject_Free); + _Py_DECREF_SPECIALIZED(left, (destructor)PyObject_Free); + ERROR_IF(prod == NULL, error); + } + + inst(BINARY_OP_MULTIPLY_FLOAT, (unused/1, left, right -- prod)) { + DEOPT_IF(!PyFloat_CheckExact(left), BINARY_OP); + DEOPT_IF(!PyFloat_CheckExact(right), BINARY_OP); + STAT_INC(BINARY_OP, hit); + double dprod = ((PyFloatObject *)left)->ob_fval * + ((PyFloatObject *)right)->ob_fval; + DECREF_INPUTS_AND_REUSE_FLOAT(left, right, dprod, prod); + } + + inst(BINARY_OP_SUBTRACT_INT, (unused/1, left, right -- sub)) { + DEOPT_IF(!PyLong_CheckExact(left), BINARY_OP); + DEOPT_IF(!PyLong_CheckExact(right), BINARY_OP); + STAT_INC(BINARY_OP, hit); + sub = _PyLong_Subtract((PyLongObject *)left, (PyLongObject *)right); + _Py_DECREF_SPECIALIZED(right, (destructor)PyObject_Free); + _Py_DECREF_SPECIALIZED(left, (destructor)PyObject_Free); + ERROR_IF(sub == NULL, error); + } + + inst(BINARY_OP_SUBTRACT_FLOAT, (unused/1, left, right -- sub)) { + DEOPT_IF(!PyFloat_CheckExact(left), BINARY_OP); + DEOPT_IF(!PyFloat_CheckExact(right), BINARY_OP); + STAT_INC(BINARY_OP, hit); + double dsub = ((PyFloatObject *)left)->ob_fval - ((PyFloatObject *)right)->ob_fval; + DECREF_INPUTS_AND_REUSE_FLOAT(left, right, dsub, sub); + } + + inst(BINARY_OP_ADD_UNICODE, (unused/1, left, right -- res)) { + DEOPT_IF(!PyUnicode_CheckExact(left), BINARY_OP); + DEOPT_IF(Py_TYPE(right) != Py_TYPE(left), BINARY_OP); + STAT_INC(BINARY_OP, hit); + res = PyUnicode_Concat(left, right); + _Py_DECREF_SPECIALIZED(left, _PyUnicode_ExactDealloc); + _Py_DECREF_SPECIALIZED(right, _PyUnicode_ExactDealloc); + ERROR_IF(res == NULL, error); + } + + // This is a subtle one. It's a super-instruction for + // BINARY_OP_ADD_UNICODE followed by STORE_FAST + // where the store goes into the left argument. + // So the inputs are the same as for all BINARY_OP + // specializations, but there is no output. + // At the end we just skip over the STORE_FAST. + inst(BINARY_OP_INPLACE_ADD_UNICODE, (left, right --)) { + DEOPT_IF(!PyUnicode_CheckExact(left), BINARY_OP); + DEOPT_IF(Py_TYPE(right) != Py_TYPE(left), BINARY_OP); + _Py_CODEUNIT true_next = next_instr[INLINE_CACHE_ENTRIES_BINARY_OP]; + assert(true_next.op.code == STORE_FAST || + true_next.op.code == STORE_FAST__LOAD_FAST); + PyObject **target_local = &GETLOCAL(true_next.op.arg); + DEOPT_IF(*target_local != left, BINARY_OP); + STAT_INC(BINARY_OP, hit); + /* Handle `left = left + right` or `left += right` for str. + * + * When possible, extend `left` in place rather than + * allocating a new PyUnicodeObject. This attempts to avoid + * quadratic behavior when one neglects to use str.join(). + * + * If `left` has only two references remaining (one from + * the stack, one in the locals), DECREFing `left` leaves + * only the locals reference, so PyUnicode_Append knows + * that the string is safe to mutate. + */ + assert(Py_REFCNT(left) >= 2); + _Py_DECREF_NO_DEALLOC(left); + PyUnicode_Append(target_local, right); + _Py_DECREF_SPECIALIZED(right, _PyUnicode_ExactDealloc); + ERROR_IF(*target_local == NULL, error); + // The STORE_FAST is already done. + JUMPBY(INLINE_CACHE_ENTRIES_BINARY_OP + 1); + } + + inst(BINARY_OP_ADD_FLOAT, (unused/1, left, right -- sum)) { + DEOPT_IF(!PyFloat_CheckExact(left), BINARY_OP); + DEOPT_IF(Py_TYPE(right) != Py_TYPE(left), BINARY_OP); + STAT_INC(BINARY_OP, hit); + double dsum = ((PyFloatObject *)left)->ob_fval + + ((PyFloatObject *)right)->ob_fval; + DECREF_INPUTS_AND_REUSE_FLOAT(left, right, dsum, sum); + } + + inst(BINARY_OP_ADD_INT, (unused/1, left, right -- sum)) { + DEOPT_IF(!PyLong_CheckExact(left), BINARY_OP); + DEOPT_IF(Py_TYPE(right) != Py_TYPE(left), BINARY_OP); + STAT_INC(BINARY_OP, hit); + sum = _PyLong_Add((PyLongObject *)left, (PyLongObject *)right); + _Py_DECREF_SPECIALIZED(right, (destructor)PyObject_Free); + _Py_DECREF_SPECIALIZED(left, (destructor)PyObject_Free); + ERROR_IF(sum == NULL, error); + } + + family(binary_subscr, INLINE_CACHE_ENTRIES_BINARY_SUBSCR) = { + BINARY_SUBSCR, + BINARY_SUBSCR_DICT, + BINARY_SUBSCR_GETITEM, + BINARY_SUBSCR_LIST_INT, + BINARY_SUBSCR_TUPLE_INT, + }; + + inst(BINARY_SUBSCR, (unused/1, container, sub -- res)) { + #if ENABLE_SPECIALIZATION + _PyBinarySubscrCache *cache = (_PyBinarySubscrCache *)next_instr; + if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { + next_instr--; + _Py_Specialize_BinarySubscr(container, sub, next_instr); + DISPATCH_SAME_OPARG(); + } + STAT_INC(BINARY_SUBSCR, deferred); + DECREMENT_ADAPTIVE_COUNTER(cache->counter); + #endif /* ENABLE_SPECIALIZATION */ + res = PyObject_GetItem(container, sub); + DECREF_INPUTS(); + ERROR_IF(res == NULL, error); + } + + inst(BINARY_SLICE, (container, start, stop -- res)) { + PyObject *slice = _PyBuildSlice_ConsumeRefs(start, stop); + // Can't use ERROR_IF() here, because we haven't + // DECREF'ed container yet, and we still own slice. + if (slice == NULL) { + res = NULL; + } + else { + res = PyObject_GetItem(container, slice); + Py_DECREF(slice); + } + Py_DECREF(container); + ERROR_IF(res == NULL, error); + } + + inst(STORE_SLICE, (v, container, start, stop -- )) { + PyObject *slice = _PyBuildSlice_ConsumeRefs(start, stop); + int err; + if (slice == NULL) { + err = 1; + } + else { + err = PyObject_SetItem(container, slice, v); + Py_DECREF(slice); + } + Py_DECREF(v); + Py_DECREF(container); + ERROR_IF(err, error); + } + + inst(BINARY_SUBSCR_LIST_INT, (unused/1, list, sub -- res)) { + DEOPT_IF(!PyLong_CheckExact(sub), BINARY_SUBSCR); + DEOPT_IF(!PyList_CheckExact(list), BINARY_SUBSCR); + + // Deopt unless 0 <= sub < PyList_Size(list) + DEOPT_IF(!_PyLong_IsNonNegativeCompact((PyLongObject *)sub), BINARY_SUBSCR); + Py_ssize_t index = ((PyLongObject*)sub)->long_value.ob_digit[0]; + DEOPT_IF(index >= PyList_GET_SIZE(list), BINARY_SUBSCR); + STAT_INC(BINARY_SUBSCR, hit); + res = PyList_GET_ITEM(list, index); + assert(res != NULL); + Py_INCREF(res); + _Py_DECREF_SPECIALIZED(sub, (destructor)PyObject_Free); + Py_DECREF(list); + } + + inst(BINARY_SUBSCR_TUPLE_INT, (unused/1, tuple, sub -- res)) { + DEOPT_IF(!PyLong_CheckExact(sub), BINARY_SUBSCR); + DEOPT_IF(!PyTuple_CheckExact(tuple), BINARY_SUBSCR); + + // Deopt unless 0 <= sub < PyTuple_Size(list) + DEOPT_IF(!_PyLong_IsNonNegativeCompact((PyLongObject *)sub), BINARY_SUBSCR); + Py_ssize_t index = ((PyLongObject*)sub)->long_value.ob_digit[0]; + DEOPT_IF(index >= PyTuple_GET_SIZE(tuple), BINARY_SUBSCR); + STAT_INC(BINARY_SUBSCR, hit); + res = PyTuple_GET_ITEM(tuple, index); + assert(res != NULL); + Py_INCREF(res); + _Py_DECREF_SPECIALIZED(sub, (destructor)PyObject_Free); + Py_DECREF(tuple); + } + + inst(BINARY_SUBSCR_DICT, (unused/1, dict, sub -- res)) { + DEOPT_IF(!PyDict_CheckExact(dict), BINARY_SUBSCR); + STAT_INC(BINARY_SUBSCR, hit); + res = PyDict_GetItemWithError(dict, sub); + if (res == NULL) { + if (!_PyErr_Occurred(tstate)) { + _PyErr_SetKeyError(sub); + } + DECREF_INPUTS(); + ERROR_IF(true, error); + } + Py_INCREF(res); // Do this before DECREF'ing dict, sub + DECREF_INPUTS(); + } + + inst(BINARY_SUBSCR_GETITEM, (unused/1, container, sub -- unused)) { + DEOPT_IF(tstate->interp->eval_frame, BINARY_SUBSCR); + PyTypeObject *tp = Py_TYPE(container); + DEOPT_IF(!PyType_HasFeature(tp, Py_TPFLAGS_HEAPTYPE), BINARY_SUBSCR); + PyHeapTypeObject *ht = (PyHeapTypeObject *)tp; + PyObject *cached = ht->_spec_cache.getitem; + DEOPT_IF(cached == NULL, BINARY_SUBSCR); + assert(PyFunction_Check(cached)); + PyFunctionObject *getitem = (PyFunctionObject *)cached; + uint32_t cached_version = ht->_spec_cache.getitem_version; + DEOPT_IF(getitem->func_version != cached_version, BINARY_SUBSCR); + PyCodeObject *code = (PyCodeObject *)getitem->func_code; + assert(code->co_argcount == 2); + DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), BINARY_SUBSCR); + STAT_INC(BINARY_SUBSCR, hit); + Py_INCREF(getitem); + _PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, getitem, 2); + STACK_SHRINK(2); + new_frame->localsplus[0] = container; + new_frame->localsplus[1] = sub; + JUMPBY(INLINE_CACHE_ENTRIES_BINARY_SUBSCR); + frame->return_offset = 0; + DISPATCH_INLINED(new_frame); + } + + inst(LIST_APPEND, (list, unused[oparg-1], v -- list, unused[oparg-1])) { + ERROR_IF(_PyList_AppendTakeRef((PyListObject *)list, v) < 0, error); + PREDICT(JUMP_BACKWARD); + } + + inst(SET_ADD, (set, unused[oparg-1], v -- set, unused[oparg-1])) { + int err = PySet_Add(set, v); + DECREF_INPUTS(); + ERROR_IF(err, error); + PREDICT(JUMP_BACKWARD); + } + + family(store_subscr, INLINE_CACHE_ENTRIES_STORE_SUBSCR) = { + STORE_SUBSCR, + STORE_SUBSCR_DICT, + STORE_SUBSCR_LIST_INT, + }; + + inst(STORE_SUBSCR, (counter/1, v, container, sub -- )) { + #if ENABLE_SPECIALIZATION + if (ADAPTIVE_COUNTER_IS_ZERO(counter)) { + next_instr--; + _Py_Specialize_StoreSubscr(container, sub, next_instr); + DISPATCH_SAME_OPARG(); + } + STAT_INC(STORE_SUBSCR, deferred); + _PyStoreSubscrCache *cache = (_PyStoreSubscrCache *)next_instr; + DECREMENT_ADAPTIVE_COUNTER(cache->counter); + #else + (void)counter; // Unused. + #endif /* ENABLE_SPECIALIZATION */ + /* container[sub] = v */ + int err = PyObject_SetItem(container, sub, v); + DECREF_INPUTS(); + ERROR_IF(err, error); + } + + inst(STORE_SUBSCR_LIST_INT, (unused/1, value, list, sub -- )) { + DEOPT_IF(!PyLong_CheckExact(sub), STORE_SUBSCR); + DEOPT_IF(!PyList_CheckExact(list), STORE_SUBSCR); + + // Ensure nonnegative, zero-or-one-digit ints. + DEOPT_IF(!_PyLong_IsNonNegativeCompact((PyLongObject *)sub), STORE_SUBSCR); + Py_ssize_t index = ((PyLongObject*)sub)->long_value.ob_digit[0]; + // Ensure index < len(list) + DEOPT_IF(index >= PyList_GET_SIZE(list), STORE_SUBSCR); + STAT_INC(STORE_SUBSCR, hit); + + PyObject *old_value = PyList_GET_ITEM(list, index); + PyList_SET_ITEM(list, index, value); + assert(old_value != NULL); + Py_DECREF(old_value); + _Py_DECREF_SPECIALIZED(sub, (destructor)PyObject_Free); + Py_DECREF(list); + } + + inst(STORE_SUBSCR_DICT, (unused/1, value, dict, sub -- )) { + DEOPT_IF(!PyDict_CheckExact(dict), STORE_SUBSCR); + STAT_INC(STORE_SUBSCR, hit); + int err = _PyDict_SetItem_Take2((PyDictObject *)dict, sub, value); + Py_DECREF(dict); + ERROR_IF(err, error); + } + + inst(DELETE_SUBSCR, (container, sub --)) { + /* del container[sub] */ + int err = PyObject_DelItem(container, sub); + DECREF_INPUTS(); + ERROR_IF(err, error); + } + + inst(CALL_INTRINSIC_1, (value -- res)) { + assert(oparg <= MAX_INTRINSIC_1); + res = _PyIntrinsics_UnaryFunctions[oparg](tstate, value); + DECREF_INPUTS(); + ERROR_IF(res == NULL, error); + } + + inst(CALL_INTRINSIC_2, (value2, value1 -- res)) { + assert(oparg <= MAX_INTRINSIC_2); + res = _PyIntrinsics_BinaryFunctions[oparg](tstate, value2, value1); + DECREF_INPUTS(); + ERROR_IF(res == NULL, error); + } + + inst(RAISE_VARARGS, (args[oparg] -- )) { + PyObject *cause = NULL, *exc = NULL; + switch (oparg) { + case 2: + cause = args[1]; + /* fall through */ + case 1: + exc = args[0]; + /* fall through */ + case 0: + if (do_raise(tstate, exc, cause)) { + assert(oparg == 0); + monitor_reraise(tstate, frame, next_instr-1); + goto exception_unwind; + } + break; + default: + _PyErr_SetString(tstate, PyExc_SystemError, + "bad RAISE_VARARGS oparg"); + break; + } + ERROR_IF(true, error); + } + + inst(INTERPRETER_EXIT, (retval --)) { + assert(frame == &entry_frame); + assert(_PyFrame_IsIncomplete(frame)); + STACK_SHRINK(1); // Since we're not going to DISPATCH() + assert(EMPTY()); + /* Restore previous cframe and return. */ + tstate->cframe = cframe.previous; + assert(tstate->cframe->current_frame == frame->previous); + assert(!_PyErr_Occurred(tstate)); + tstate->c_recursion_remaining += PY_EVAL_C_STACK_UNITS; + return retval; + } + + inst(RETURN_VALUE, (retval --)) { + STACK_SHRINK(1); + assert(EMPTY()); + _PyFrame_SetStackPointer(frame, stack_pointer); + _Py_LeaveRecursiveCallPy(tstate); + assert(frame != &entry_frame); + // GH-99729: We need to unlink the frame *before* clearing it: + _PyInterpreterFrame *dying = frame; + frame = cframe.current_frame = dying->previous; + _PyEvalFrameClearAndPop(tstate, dying); + frame->prev_instr += frame->return_offset; + _PyFrame_StackPush(frame, retval); + goto resume_frame; + } + + inst(INSTRUMENTED_RETURN_VALUE, (retval --)) { + int err = _Py_call_instrumentation_arg( + tstate, PY_MONITORING_EVENT_PY_RETURN, + frame, next_instr-1, retval); + if (err) goto error; + STACK_SHRINK(1); + assert(EMPTY()); + _PyFrame_SetStackPointer(frame, stack_pointer); + _Py_LeaveRecursiveCallPy(tstate); + assert(frame != &entry_frame); + // GH-99729: We need to unlink the frame *before* clearing it: + _PyInterpreterFrame *dying = frame; + frame = cframe.current_frame = dying->previous; + _PyEvalFrameClearAndPop(tstate, dying); + frame->prev_instr += frame->return_offset; + _PyFrame_StackPush(frame, retval); + goto resume_frame; + } + + inst(RETURN_CONST, (--)) { + PyObject *retval = GETITEM(frame->f_code->co_consts, oparg); + Py_INCREF(retval); + assert(EMPTY()); + _PyFrame_SetStackPointer(frame, stack_pointer); + _Py_LeaveRecursiveCallPy(tstate); + assert(frame != &entry_frame); + // GH-99729: We need to unlink the frame *before* clearing it: + _PyInterpreterFrame *dying = frame; + frame = cframe.current_frame = dying->previous; + _PyEvalFrameClearAndPop(tstate, dying); + frame->prev_instr += frame->return_offset; + _PyFrame_StackPush(frame, retval); + goto resume_frame; + } + + inst(INSTRUMENTED_RETURN_CONST, (--)) { + PyObject *retval = GETITEM(frame->f_code->co_consts, oparg); + int err = _Py_call_instrumentation_arg( + tstate, PY_MONITORING_EVENT_PY_RETURN, + frame, next_instr-1, retval); + if (err) goto error; + Py_INCREF(retval); + assert(EMPTY()); + _PyFrame_SetStackPointer(frame, stack_pointer); + _Py_LeaveRecursiveCallPy(tstate); + assert(frame != &entry_frame); + // GH-99729: We need to unlink the frame *before* clearing it: + _PyInterpreterFrame *dying = frame; + frame = cframe.current_frame = dying->previous; + _PyEvalFrameClearAndPop(tstate, dying); + frame->prev_instr += frame->return_offset; + _PyFrame_StackPush(frame, retval); + goto resume_frame; + } + + inst(GET_AITER, (obj -- iter)) { + unaryfunc getter = NULL; + PyTypeObject *type = Py_TYPE(obj); + + if (type->tp_as_async != NULL) { + getter = type->tp_as_async->am_aiter; + } + + if (getter == NULL) { + _PyErr_Format(tstate, PyExc_TypeError, + "'async for' requires an object with " + "__aiter__ method, got %.100s", + type->tp_name); + DECREF_INPUTS(); + ERROR_IF(true, error); + } + + iter = (*getter)(obj); + DECREF_INPUTS(); + ERROR_IF(iter == NULL, error); + + if (Py_TYPE(iter)->tp_as_async == NULL || + Py_TYPE(iter)->tp_as_async->am_anext == NULL) { + + _PyErr_Format(tstate, PyExc_TypeError, + "'async for' received an object from __aiter__ " + "that does not implement __anext__: %.100s", + Py_TYPE(iter)->tp_name); + Py_DECREF(iter); + ERROR_IF(true, error); + } + } + + inst(GET_ANEXT, (aiter -- aiter, awaitable)) { + unaryfunc getter = NULL; + PyObject *next_iter = NULL; + PyTypeObject *type = Py_TYPE(aiter); + + if (PyAsyncGen_CheckExact(aiter)) { + awaitable = type->tp_as_async->am_anext(aiter); + if (awaitable == NULL) { + goto error; + } + } else { + if (type->tp_as_async != NULL){ + getter = type->tp_as_async->am_anext; + } + + if (getter != NULL) { + next_iter = (*getter)(aiter); + if (next_iter == NULL) { + goto error; + } + } + else { + _PyErr_Format(tstate, PyExc_TypeError, + "'async for' requires an iterator with " + "__anext__ method, got %.100s", + type->tp_name); + goto error; + } + + awaitable = _PyCoro_GetAwaitableIter(next_iter); + if (awaitable == NULL) { + _PyErr_FormatFromCause( + PyExc_TypeError, + "'async for' received an invalid object " + "from __anext__: %.100s", + Py_TYPE(next_iter)->tp_name); + + Py_DECREF(next_iter); + goto error; + } else { + Py_DECREF(next_iter); + } + } + + PREDICT(LOAD_CONST); + } + + inst(GET_AWAITABLE, (iterable -- iter)) { + iter = _PyCoro_GetAwaitableIter(iterable); + + if (iter == NULL) { + format_awaitable_error(tstate, Py_TYPE(iterable), oparg); + } + + DECREF_INPUTS(); + + if (iter != NULL && PyCoro_CheckExact(iter)) { + PyObject *yf = _PyGen_yf((PyGenObject*)iter); + if (yf != NULL) { + /* `iter` is a coroutine object that is being + awaited, `yf` is a pointer to the current awaitable + being awaited on. */ + Py_DECREF(yf); + Py_CLEAR(iter); + _PyErr_SetString(tstate, PyExc_RuntimeError, + "coroutine is being awaited already"); + /* The code below jumps to `error` if `iter` is NULL. */ + } + } + + ERROR_IF(iter == NULL, error); + + PREDICT(LOAD_CONST); + } + + family(send, INLINE_CACHE_ENTRIES_SEND) = { + SEND, + SEND_GEN, + }; + + inst(SEND, (unused/1, receiver, v -- receiver, retval)) { + #if ENABLE_SPECIALIZATION + _PySendCache *cache = (_PySendCache *)next_instr; + if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { + next_instr--; + _Py_Specialize_Send(receiver, next_instr); + DISPATCH_SAME_OPARG(); + } + STAT_INC(SEND, deferred); + DECREMENT_ADAPTIVE_COUNTER(cache->counter); + #endif /* ENABLE_SPECIALIZATION */ + assert(frame != &entry_frame); + if ((tstate->interp->eval_frame == NULL) && + (Py_TYPE(receiver) == &PyGen_Type || Py_TYPE(receiver) == &PyCoro_Type) && + ((PyGenObject *)receiver)->gi_frame_state < FRAME_EXECUTING) + { + PyGenObject *gen = (PyGenObject *)receiver; + _PyInterpreterFrame *gen_frame = (_PyInterpreterFrame *)gen->gi_iframe; + frame->return_offset = oparg; + STACK_SHRINK(1); + _PyFrame_StackPush(gen_frame, v); + gen->gi_frame_state = FRAME_EXECUTING; + gen->gi_exc_state.previous_item = tstate->exc_info; + tstate->exc_info = &gen->gi_exc_state; + JUMPBY(INLINE_CACHE_ENTRIES_SEND); + DISPATCH_INLINED(gen_frame); + } + if (Py_IsNone(v) && PyIter_Check(receiver)) { + retval = Py_TYPE(receiver)->tp_iternext(receiver); + } + else { + retval = PyObject_CallMethodOneArg(receiver, &_Py_ID(send), v); + } + if (retval == NULL) { + if (_PyErr_ExceptionMatches(tstate, PyExc_StopIteration) + ) { + monitor_raise(tstate, frame, next_instr-1); + } + if (_PyGen_FetchStopIterationValue(&retval) == 0) { + assert(retval != NULL); + JUMPBY(oparg); + } + else { + goto error; + } + } + Py_DECREF(v); + } + + inst(SEND_GEN, (unused/1, receiver, v -- receiver, unused)) { + DEOPT_IF(tstate->interp->eval_frame, SEND); + PyGenObject *gen = (PyGenObject *)receiver; + DEOPT_IF(Py_TYPE(gen) != &PyGen_Type && + Py_TYPE(gen) != &PyCoro_Type, SEND); + DEOPT_IF(gen->gi_frame_state >= FRAME_EXECUTING, SEND); + STAT_INC(SEND, hit); + _PyInterpreterFrame *gen_frame = (_PyInterpreterFrame *)gen->gi_iframe; + frame->return_offset = oparg; + STACK_SHRINK(1); + _PyFrame_StackPush(gen_frame, v); + gen->gi_frame_state = FRAME_EXECUTING; + gen->gi_exc_state.previous_item = tstate->exc_info; + tstate->exc_info = &gen->gi_exc_state; + JUMPBY(INLINE_CACHE_ENTRIES_SEND); + DISPATCH_INLINED(gen_frame); + } + + inst(INSTRUMENTED_YIELD_VALUE, (retval -- unused)) { + assert(frame != &entry_frame); + PyGenObject *gen = _PyFrame_GetGenerator(frame); + gen->gi_frame_state = FRAME_SUSPENDED; + _PyFrame_SetStackPointer(frame, stack_pointer - 1); + int err = _Py_call_instrumentation_arg( + tstate, PY_MONITORING_EVENT_PY_YIELD, + frame, next_instr-1, retval); + if (err) goto error; + tstate->exc_info = gen->gi_exc_state.previous_item; + gen->gi_exc_state.previous_item = NULL; + _Py_LeaveRecursiveCallPy(tstate); + _PyInterpreterFrame *gen_frame = frame; + frame = cframe.current_frame = frame->previous; + gen_frame->previous = NULL; + _PyFrame_StackPush(frame, retval); + goto resume_frame; + } + + inst(YIELD_VALUE, (retval -- unused)) { + // NOTE: It's important that YIELD_VALUE never raises an exception! + // The compiler treats any exception raised here as a failed close() + // or throw() call. + assert(frame != &entry_frame); + PyGenObject *gen = _PyFrame_GetGenerator(frame); + gen->gi_frame_state = FRAME_SUSPENDED; + _PyFrame_SetStackPointer(frame, stack_pointer - 1); + tstate->exc_info = gen->gi_exc_state.previous_item; + gen->gi_exc_state.previous_item = NULL; + _Py_LeaveRecursiveCallPy(tstate); + _PyInterpreterFrame *gen_frame = frame; + frame = cframe.current_frame = frame->previous; + gen_frame->previous = NULL; + _PyFrame_StackPush(frame, retval); + goto resume_frame; + } + + inst(POP_EXCEPT, (exc_value -- )) { + _PyErr_StackItem *exc_info = tstate->exc_info; + Py_XSETREF(exc_info->exc_value, exc_value); + } + + inst(RERAISE, (values[oparg], exc -- values[oparg])) { + assert(oparg >= 0 && oparg <= 2); + if (oparg) { + PyObject *lasti = values[0]; + if (PyLong_Check(lasti)) { + frame->prev_instr = _PyCode_CODE(frame->f_code) + PyLong_AsLong(lasti); + assert(!_PyErr_Occurred(tstate)); + } + else { + assert(PyLong_Check(lasti)); + _PyErr_SetString(tstate, PyExc_SystemError, "lasti is not an int"); + goto error; + } + } + assert(exc && PyExceptionInstance_Check(exc)); + Py_INCREF(exc); + _PyErr_SetRaisedException(tstate, exc); + monitor_reraise(tstate, frame, next_instr-1); + goto exception_unwind; + } + + inst(END_ASYNC_FOR, (awaitable, exc -- )) { + assert(exc && PyExceptionInstance_Check(exc)); + if (PyErr_GivenExceptionMatches(exc, PyExc_StopAsyncIteration)) { + DECREF_INPUTS(); + } + else { + Py_INCREF(exc); + _PyErr_SetRaisedException(tstate, exc); + monitor_reraise(tstate, frame, next_instr-1); + goto exception_unwind; + } + } + + inst(CLEANUP_THROW, (sub_iter, last_sent_val, exc_value -- none, value)) { + assert(throwflag); + assert(exc_value && PyExceptionInstance_Check(exc_value)); + if (PyErr_GivenExceptionMatches(exc_value, PyExc_StopIteration)) { + value = Py_NewRef(((PyStopIterationObject *)exc_value)->value); + DECREF_INPUTS(); + none = Py_None; + } + else { + _PyErr_SetRaisedException(tstate, Py_NewRef(exc_value)); + monitor_reraise(tstate, frame, next_instr-1); + goto exception_unwind; + } + } + + inst(LOAD_ASSERTION_ERROR, ( -- value)) { + value = Py_NewRef(PyExc_AssertionError); + } + + inst(LOAD_BUILD_CLASS, ( -- bc)) { + if (PyDict_CheckExact(BUILTINS())) { + bc = _PyDict_GetItemWithError(BUILTINS(), + &_Py_ID(__build_class__)); + if (bc == NULL) { + if (!_PyErr_Occurred(tstate)) { + _PyErr_SetString(tstate, PyExc_NameError, + "__build_class__ not found"); + } + ERROR_IF(true, error); + } + Py_INCREF(bc); + } + else { + bc = PyObject_GetItem(BUILTINS(), &_Py_ID(__build_class__)); + if (bc == NULL) { + if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) + _PyErr_SetString(tstate, PyExc_NameError, + "__build_class__ not found"); + ERROR_IF(true, error); + } + } + } + + + inst(STORE_NAME, (v -- )) { + PyObject *name = GETITEM(frame->f_code->co_names, oparg); + PyObject *ns = LOCALS(); + int err; + if (ns == NULL) { + _PyErr_Format(tstate, PyExc_SystemError, + "no locals found when storing %R", name); + DECREF_INPUTS(); + ERROR_IF(true, error); + } + if (PyDict_CheckExact(ns)) + err = PyDict_SetItem(ns, name, v); + else + err = PyObject_SetItem(ns, name, v); + DECREF_INPUTS(); + ERROR_IF(err, error); + } + + inst(DELETE_NAME, (--)) { + PyObject *name = GETITEM(frame->f_code->co_names, oparg); + PyObject *ns = LOCALS(); + int err; + if (ns == NULL) { + _PyErr_Format(tstate, PyExc_SystemError, + "no locals when deleting %R", name); + goto error; + } + err = PyObject_DelItem(ns, name); + // Can't use ERROR_IF here. + if (err != 0) { + format_exc_check_arg(tstate, PyExc_NameError, + NAME_ERROR_MSG, + name); + goto error; + } + } + + family(unpack_sequence, INLINE_CACHE_ENTRIES_UNPACK_SEQUENCE) = { + UNPACK_SEQUENCE, + UNPACK_SEQUENCE_TWO_TUPLE, + UNPACK_SEQUENCE_TUPLE, + UNPACK_SEQUENCE_LIST, + }; + + inst(UNPACK_SEQUENCE, (unused/1, seq -- unused[oparg])) { + #if ENABLE_SPECIALIZATION + _PyUnpackSequenceCache *cache = (_PyUnpackSequenceCache *)next_instr; + if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { + next_instr--; + _Py_Specialize_UnpackSequence(seq, next_instr, oparg); + DISPATCH_SAME_OPARG(); + } + STAT_INC(UNPACK_SEQUENCE, deferred); + DECREMENT_ADAPTIVE_COUNTER(cache->counter); + #endif /* ENABLE_SPECIALIZATION */ + PyObject **top = stack_pointer + oparg - 1; + int res = unpack_iterable(tstate, seq, oparg, -1, top); + DECREF_INPUTS(); + ERROR_IF(res == 0, error); + } + + inst(UNPACK_SEQUENCE_TWO_TUPLE, (unused/1, seq -- values[oparg])) { + DEOPT_IF(!PyTuple_CheckExact(seq), UNPACK_SEQUENCE); + DEOPT_IF(PyTuple_GET_SIZE(seq) != 2, UNPACK_SEQUENCE); + assert(oparg == 2); + STAT_INC(UNPACK_SEQUENCE, hit); + values[0] = Py_NewRef(PyTuple_GET_ITEM(seq, 1)); + values[1] = Py_NewRef(PyTuple_GET_ITEM(seq, 0)); + DECREF_INPUTS(); + } + + inst(UNPACK_SEQUENCE_TUPLE, (unused/1, seq -- values[oparg])) { + DEOPT_IF(!PyTuple_CheckExact(seq), UNPACK_SEQUENCE); + DEOPT_IF(PyTuple_GET_SIZE(seq) != oparg, UNPACK_SEQUENCE); + STAT_INC(UNPACK_SEQUENCE, hit); + PyObject **items = _PyTuple_ITEMS(seq); + for (int i = oparg; --i >= 0; ) { + *values++ = Py_NewRef(items[i]); + } + DECREF_INPUTS(); + } + + inst(UNPACK_SEQUENCE_LIST, (unused/1, seq -- values[oparg])) { + DEOPT_IF(!PyList_CheckExact(seq), UNPACK_SEQUENCE); + DEOPT_IF(PyList_GET_SIZE(seq) != oparg, UNPACK_SEQUENCE); + STAT_INC(UNPACK_SEQUENCE, hit); + PyObject **items = _PyList_ITEMS(seq); + for (int i = oparg; --i >= 0; ) { + *values++ = Py_NewRef(items[i]); + } + DECREF_INPUTS(); + } + + inst(UNPACK_EX, (seq -- unused[oparg & 0xFF], unused, unused[oparg >> 8])) { + int totalargs = 1 + (oparg & 0xFF) + (oparg >> 8); + PyObject **top = stack_pointer + totalargs - 1; + int res = unpack_iterable(tstate, seq, oparg & 0xFF, oparg >> 8, top); + DECREF_INPUTS(); + ERROR_IF(res == 0, error); + } + + family(store_attr, INLINE_CACHE_ENTRIES_STORE_ATTR) = { + STORE_ATTR, + STORE_ATTR_INSTANCE_VALUE, + STORE_ATTR_SLOT, + STORE_ATTR_WITH_HINT, + }; + + inst(STORE_ATTR, (counter/1, unused/3, v, owner --)) { + #if ENABLE_SPECIALIZATION + if (ADAPTIVE_COUNTER_IS_ZERO(counter)) { + PyObject *name = GETITEM(frame->f_code->co_names, oparg); + next_instr--; + _Py_Specialize_StoreAttr(owner, next_instr, name); + DISPATCH_SAME_OPARG(); + } + STAT_INC(STORE_ATTR, deferred); + _PyAttrCache *cache = (_PyAttrCache *)next_instr; + DECREMENT_ADAPTIVE_COUNTER(cache->counter); + #else + (void)counter; // Unused. + #endif /* ENABLE_SPECIALIZATION */ + PyObject *name = GETITEM(frame->f_code->co_names, oparg); + int err = PyObject_SetAttr(owner, name, v); + DECREF_INPUTS(); + ERROR_IF(err, error); + } + + inst(DELETE_ATTR, (owner --)) { + PyObject *name = GETITEM(frame->f_code->co_names, oparg); + int err = PyObject_SetAttr(owner, name, (PyObject *)NULL); + DECREF_INPUTS(); + ERROR_IF(err, error); + } + + inst(STORE_GLOBAL, (v --)) { + PyObject *name = GETITEM(frame->f_code->co_names, oparg); + int err = PyDict_SetItem(GLOBALS(), name, v); + DECREF_INPUTS(); + ERROR_IF(err, error); + } + + inst(DELETE_GLOBAL, (--)) { + PyObject *name = GETITEM(frame->f_code->co_names, oparg); + int err; + err = PyDict_DelItem(GLOBALS(), name); + // Can't use ERROR_IF here. + if (err != 0) { + if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { + format_exc_check_arg(tstate, PyExc_NameError, + NAME_ERROR_MSG, name); + } + goto error; + } + } + + inst(LOAD_LOCALS, ( -- locals)) { + locals = LOCALS(); + if (locals == NULL) { + _PyErr_SetString(tstate, PyExc_SystemError, + "no locals found"); + ERROR_IF(true, error); + } + Py_INCREF(locals); + } + + inst(LOAD_FROM_DICT_OR_GLOBALS, (mod_or_class_dict -- v)) { + PyObject *name = GETITEM(frame->f_code->co_names, oparg); + if (PyDict_CheckExact(mod_or_class_dict)) { + v = PyDict_GetItemWithError(mod_or_class_dict, name); + if (v != NULL) { + Py_INCREF(v); + } + else if (_PyErr_Occurred(tstate)) { + goto error; + } + } + else { + v = PyObject_GetItem(mod_or_class_dict, name); + if (v == NULL) { + if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { + goto error; + } + _PyErr_Clear(tstate); + } + } + if (v == NULL) { + v = PyDict_GetItemWithError(GLOBALS(), name); + if (v != NULL) { + Py_INCREF(v); + } + else if (_PyErr_Occurred(tstate)) { + goto error; + } + else { + if (PyDict_CheckExact(BUILTINS())) { + v = PyDict_GetItemWithError(BUILTINS(), name); + if (v == NULL) { + if (!_PyErr_Occurred(tstate)) { + format_exc_check_arg( + tstate, PyExc_NameError, + NAME_ERROR_MSG, name); + } + goto error; + } + Py_INCREF(v); + } + else { + v = PyObject_GetItem(BUILTINS(), name); + if (v == NULL) { + if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { + format_exc_check_arg( + tstate, PyExc_NameError, + NAME_ERROR_MSG, name); + } + goto error; + } + } + } + } + DECREF_INPUTS(); + } + + inst(LOAD_NAME, (-- v)) { + PyObject *mod_or_class_dict = LOCALS(); + if (mod_or_class_dict == NULL) { + _PyErr_SetString(tstate, PyExc_SystemError, + "no locals found"); + ERROR_IF(true, error); + } + PyObject *name = GETITEM(frame->f_code->co_names, oparg); + if (PyDict_CheckExact(mod_or_class_dict)) { + v = PyDict_GetItemWithError(mod_or_class_dict, name); + if (v != NULL) { + Py_INCREF(v); + } + else if (_PyErr_Occurred(tstate)) { + goto error; + } + } + else { + v = PyObject_GetItem(mod_or_class_dict, name); + if (v == NULL) { + if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { + goto error; + } + _PyErr_Clear(tstate); + } + } + if (v == NULL) { + v = PyDict_GetItemWithError(GLOBALS(), name); + if (v != NULL) { + Py_INCREF(v); + } + else if (_PyErr_Occurred(tstate)) { + goto error; + } + else { + if (PyDict_CheckExact(BUILTINS())) { + v = PyDict_GetItemWithError(BUILTINS(), name); + if (v == NULL) { + if (!_PyErr_Occurred(tstate)) { + format_exc_check_arg( + tstate, PyExc_NameError, + NAME_ERROR_MSG, name); + } + goto error; + } + Py_INCREF(v); + } + else { + v = PyObject_GetItem(BUILTINS(), name); + if (v == NULL) { + if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { + format_exc_check_arg( + tstate, PyExc_NameError, + NAME_ERROR_MSG, name); + } + goto error; + } + } + } + } + } + + family(load_global, INLINE_CACHE_ENTRIES_LOAD_GLOBAL) = { + LOAD_GLOBAL, + LOAD_GLOBAL_MODULE, + LOAD_GLOBAL_BUILTIN, + }; + + inst(LOAD_GLOBAL, (unused/1, unused/1, unused/1, unused/1 -- null if (oparg & 1), v)) { + #if ENABLE_SPECIALIZATION + _PyLoadGlobalCache *cache = (_PyLoadGlobalCache *)next_instr; + if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { + PyObject *name = GETITEM(frame->f_code->co_names, oparg>>1); + next_instr--; + _Py_Specialize_LoadGlobal(GLOBALS(), BUILTINS(), next_instr, name); + DISPATCH_SAME_OPARG(); + } + STAT_INC(LOAD_GLOBAL, deferred); + DECREMENT_ADAPTIVE_COUNTER(cache->counter); + #endif /* ENABLE_SPECIALIZATION */ + PyObject *name = GETITEM(frame->f_code->co_names, oparg>>1); + if (PyDict_CheckExact(GLOBALS()) + && PyDict_CheckExact(BUILTINS())) + { + v = _PyDict_LoadGlobal((PyDictObject *)GLOBALS(), + (PyDictObject *)BUILTINS(), + name); + if (v == NULL) { + if (!_PyErr_Occurred(tstate)) { + /* _PyDict_LoadGlobal() returns NULL without raising + * an exception if the key doesn't exist */ + format_exc_check_arg(tstate, PyExc_NameError, + NAME_ERROR_MSG, name); + } + ERROR_IF(true, error); + } + Py_INCREF(v); + } + else { + /* Slow-path if globals or builtins is not a dict */ + + /* namespace 1: globals */ + v = PyObject_GetItem(GLOBALS(), name); + if (v == NULL) { + ERROR_IF(!_PyErr_ExceptionMatches(tstate, PyExc_KeyError), error); + _PyErr_Clear(tstate); + + /* namespace 2: builtins */ + v = PyObject_GetItem(BUILTINS(), name); + if (v == NULL) { + if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { + format_exc_check_arg( + tstate, PyExc_NameError, + NAME_ERROR_MSG, name); + } + ERROR_IF(true, error); + } + } + } + null = NULL; + } + + inst(LOAD_GLOBAL_MODULE, (unused/1, index/1, version/1, unused/1 -- null if (oparg & 1), res)) { + DEOPT_IF(!PyDict_CheckExact(GLOBALS()), LOAD_GLOBAL); + PyDictObject *dict = (PyDictObject *)GLOBALS(); + DEOPT_IF(dict->ma_keys->dk_version != version, LOAD_GLOBAL); + assert(DK_IS_UNICODE(dict->ma_keys)); + PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(dict->ma_keys); + res = entries[index].me_value; + DEOPT_IF(res == NULL, LOAD_GLOBAL); + Py_INCREF(res); + STAT_INC(LOAD_GLOBAL, hit); + null = NULL; + } + + inst(LOAD_GLOBAL_BUILTIN, (unused/1, index/1, mod_version/1, bltn_version/1 -- null if (oparg & 1), res)) { + DEOPT_IF(!PyDict_CheckExact(GLOBALS()), LOAD_GLOBAL); + DEOPT_IF(!PyDict_CheckExact(BUILTINS()), LOAD_GLOBAL); + PyDictObject *mdict = (PyDictObject *)GLOBALS(); + PyDictObject *bdict = (PyDictObject *)BUILTINS(); + assert(opcode == LOAD_GLOBAL_BUILTIN); + DEOPT_IF(mdict->ma_keys->dk_version != mod_version, LOAD_GLOBAL); + DEOPT_IF(bdict->ma_keys->dk_version != bltn_version, LOAD_GLOBAL); + assert(DK_IS_UNICODE(bdict->ma_keys)); + PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(bdict->ma_keys); + res = entries[index].me_value; + DEOPT_IF(res == NULL, LOAD_GLOBAL); + Py_INCREF(res); + STAT_INC(LOAD_GLOBAL, hit); + null = NULL; + } + + inst(DELETE_FAST, (--)) { + PyObject *v = GETLOCAL(oparg); + ERROR_IF(v == NULL, unbound_local_error); + SETLOCAL(oparg, NULL); + } + + inst(MAKE_CELL, (--)) { + // "initial" is probably NULL but not if it's an arg (or set + // via PyFrame_LocalsToFast() before MAKE_CELL has run). + PyObject *initial = GETLOCAL(oparg); + PyObject *cell = PyCell_New(initial); + if (cell == NULL) { + goto resume_with_error; + } + SETLOCAL(oparg, cell); + } + + inst(DELETE_DEREF, (--)) { + PyObject *cell = GETLOCAL(oparg); + PyObject *oldobj = PyCell_GET(cell); + // Can't use ERROR_IF here. + // Fortunately we don't need its superpower. + if (oldobj == NULL) { + format_exc_unbound(tstate, frame->f_code, oparg); + goto error; + } + PyCell_SET(cell, NULL); + Py_DECREF(oldobj); + } + + inst(LOAD_FROM_DICT_OR_DEREF, (class_dict -- value)) { + PyObject *name; + assert(class_dict); + assert(oparg >= 0 && oparg < frame->f_code->co_nlocalsplus); + name = PyTuple_GET_ITEM(frame->f_code->co_localsplusnames, oparg); + if (PyDict_CheckExact(class_dict)) { + value = PyDict_GetItemWithError(class_dict, name); + if (value != NULL) { + Py_INCREF(value); + } + else if (_PyErr_Occurred(tstate)) { + Py_DECREF(class_dict); + goto error; + } + } + else { + value = PyObject_GetItem(class_dict, name); + if (value == NULL) { + if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { + Py_DECREF(class_dict); + goto error; + } + _PyErr_Clear(tstate); + } + } + Py_DECREF(class_dict); + if (!value) { + PyObject *cell = GETLOCAL(oparg); + value = PyCell_GET(cell); + if (value == NULL) { + format_exc_unbound(tstate, frame->f_code, oparg); + goto error; + } + Py_INCREF(value); + } + } + + inst(LOAD_DEREF, ( -- value)) { + PyObject *cell = GETLOCAL(oparg); + value = PyCell_GET(cell); + if (value == NULL) { + format_exc_unbound(tstate, frame->f_code, oparg); + ERROR_IF(true, error); + } + Py_INCREF(value); + } + + inst(STORE_DEREF, (v --)) { + PyObject *cell = GETLOCAL(oparg); + PyObject *oldobj = PyCell_GET(cell); + PyCell_SET(cell, v); + Py_XDECREF(oldobj); + } + + inst(COPY_FREE_VARS, (--)) { + /* Copy closure variables to free variables */ + PyCodeObject *co = frame->f_code; + assert(PyFunction_Check(frame->f_funcobj)); + PyObject *closure = ((PyFunctionObject *)frame->f_funcobj)->func_closure; + assert(oparg == co->co_nfreevars); + int offset = co->co_nlocalsplus - oparg; + for (int i = 0; i < oparg; ++i) { + PyObject *o = PyTuple_GET_ITEM(closure, i); + frame->localsplus[offset + i] = Py_NewRef(o); + } + } + + inst(BUILD_STRING, (pieces[oparg] -- str)) { + str = _PyUnicode_JoinArray(&_Py_STR(empty), pieces, oparg); + DECREF_INPUTS(); + ERROR_IF(str == NULL, error); + } + + inst(BUILD_TUPLE, (values[oparg] -- tup)) { + tup = _PyTuple_FromArraySteal(values, oparg); + ERROR_IF(tup == NULL, error); + } + + inst(BUILD_LIST, (values[oparg] -- list)) { + list = _PyList_FromArraySteal(values, oparg); + ERROR_IF(list == NULL, error); + } + + inst(LIST_EXTEND, (list, unused[oparg-1], iterable -- list, unused[oparg-1])) { + PyObject *none_val = _PyList_Extend((PyListObject *)list, iterable); + if (none_val == NULL) { + if (_PyErr_ExceptionMatches(tstate, PyExc_TypeError) && + (Py_TYPE(iterable)->tp_iter == NULL && !PySequence_Check(iterable))) + { + _PyErr_Clear(tstate); + _PyErr_Format(tstate, PyExc_TypeError, + "Value after * must be an iterable, not %.200s", + Py_TYPE(iterable)->tp_name); + } + DECREF_INPUTS(); + ERROR_IF(true, error); + } + assert(Py_IsNone(none_val)); + DECREF_INPUTS(); + } + + inst(SET_UPDATE, (set, unused[oparg-1], iterable -- set, unused[oparg-1])) { + int err = _PySet_Update(set, iterable); + DECREF_INPUTS(); + ERROR_IF(err < 0, error); + } + + inst(BUILD_SET, (values[oparg] -- set)) { + set = PySet_New(NULL); + if (set == NULL) + goto error; + int err = 0; + for (int i = 0; i < oparg; i++) { + PyObject *item = values[i]; + if (err == 0) + err = PySet_Add(set, item); + Py_DECREF(item); + } + if (err != 0) { + Py_DECREF(set); + ERROR_IF(true, error); + } + } + + inst(BUILD_MAP, (values[oparg*2] -- map)) { + map = _PyDict_FromItems( + values, 2, + values+1, 2, + oparg); + if (map == NULL) + goto error; + + DECREF_INPUTS(); + ERROR_IF(map == NULL, error); + } + + inst(SETUP_ANNOTATIONS, (--)) { + int err; + PyObject *ann_dict; + if (LOCALS() == NULL) { + _PyErr_Format(tstate, PyExc_SystemError, + "no locals found when setting up annotations"); + ERROR_IF(true, error); + } + /* check if __annotations__ in locals()... */ + if (PyDict_CheckExact(LOCALS())) { + ann_dict = _PyDict_GetItemWithError(LOCALS(), + &_Py_ID(__annotations__)); + if (ann_dict == NULL) { + ERROR_IF(_PyErr_Occurred(tstate), error); + /* ...if not, create a new one */ + ann_dict = PyDict_New(); + ERROR_IF(ann_dict == NULL, error); + err = PyDict_SetItem(LOCALS(), &_Py_ID(__annotations__), + ann_dict); + Py_DECREF(ann_dict); + ERROR_IF(err, error); + } + } + else { + /* do the same if locals() is not a dict */ + ann_dict = PyObject_GetItem(LOCALS(), &_Py_ID(__annotations__)); + if (ann_dict == NULL) { + ERROR_IF(!_PyErr_ExceptionMatches(tstate, PyExc_KeyError), error); + _PyErr_Clear(tstate); + ann_dict = PyDict_New(); + ERROR_IF(ann_dict == NULL, error); + err = PyObject_SetItem(LOCALS(), &_Py_ID(__annotations__), + ann_dict); + Py_DECREF(ann_dict); + ERROR_IF(err, error); + } + else { + Py_DECREF(ann_dict); + } + } + } + + inst(BUILD_CONST_KEY_MAP, (values[oparg], keys -- map)) { + if (!PyTuple_CheckExact(keys) || + PyTuple_GET_SIZE(keys) != (Py_ssize_t)oparg) { + _PyErr_SetString(tstate, PyExc_SystemError, + "bad BUILD_CONST_KEY_MAP keys argument"); + goto error; // Pop the keys and values. + } + map = _PyDict_FromItems( + &PyTuple_GET_ITEM(keys, 0), 1, + values, 1, oparg); + DECREF_INPUTS(); + ERROR_IF(map == NULL, error); + } + + inst(DICT_UPDATE, (update --)) { + PyObject *dict = PEEK(oparg + 1); // update is still on the stack + if (PyDict_Update(dict, update) < 0) { + if (_PyErr_ExceptionMatches(tstate, PyExc_AttributeError)) { + _PyErr_Format(tstate, PyExc_TypeError, + "'%.200s' object is not a mapping", + Py_TYPE(update)->tp_name); + } + DECREF_INPUTS(); + ERROR_IF(true, error); + } + DECREF_INPUTS(); + } + + inst(DICT_MERGE, (update --)) { + PyObject *dict = PEEK(oparg + 1); // update is still on the stack + + if (_PyDict_MergeEx(dict, update, 2) < 0) { + format_kwargs_error(tstate, PEEK(3 + oparg), update); + DECREF_INPUTS(); + ERROR_IF(true, error); + } + DECREF_INPUTS(); + PREDICT(CALL_FUNCTION_EX); + } + + inst(MAP_ADD, (key, value --)) { + PyObject *dict = PEEK(oparg + 2); // key, value are still on the stack + assert(PyDict_CheckExact(dict)); + /* dict[key] = value */ + // Do not DECREF INPUTS because the function steals the references + ERROR_IF(_PyDict_SetItem_Take2((PyDictObject *)dict, key, value) != 0, error); + PREDICT(JUMP_BACKWARD); + } + + inst(INSTRUMENTED_LOAD_SUPER_ATTR, (unused/9, unused, unused, unused -- unused if (oparg & 1), unused)) { + _PySuperAttrCache *cache = (_PySuperAttrCache *)next_instr; + // cancel out the decrement that will happen in LOAD_SUPER_ATTR; we + // don't want to specialize instrumented instructions + INCREMENT_ADAPTIVE_COUNTER(cache->counter); + GO_TO_INSTRUCTION(LOAD_SUPER_ATTR); + } + + family(load_super_attr, INLINE_CACHE_ENTRIES_LOAD_SUPER_ATTR) = { + LOAD_SUPER_ATTR, + LOAD_SUPER_ATTR_ATTR, + LOAD_SUPER_ATTR_METHOD, + }; + + inst(LOAD_SUPER_ATTR, (unused/1, global_super, class, self -- res2 if (oparg & 1), res)) { + PyObject *name = GETITEM(frame->f_code->co_names, oparg >> 2); + int load_method = oparg & 1; + #if ENABLE_SPECIALIZATION + _PySuperAttrCache *cache = (_PySuperAttrCache *)next_instr; + if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { + next_instr--; + _Py_Specialize_LoadSuperAttr(global_super, class, next_instr, load_method); + DISPATCH_SAME_OPARG(); + } + STAT_INC(LOAD_SUPER_ATTR, deferred); + DECREMENT_ADAPTIVE_COUNTER(cache->counter); + #endif /* ENABLE_SPECIALIZATION */ + + if (opcode == INSTRUMENTED_LOAD_SUPER_ATTR) { + PyObject *arg = oparg & 2 ? class : &_PyInstrumentation_MISSING; + int err = _Py_call_instrumentation_2args( + tstate, PY_MONITORING_EVENT_CALL, + frame, next_instr-1, global_super, arg); + ERROR_IF(err, error); + } + + // we make no attempt to optimize here; specializations should + // handle any case whose performance we care about + PyObject *stack[] = {class, self}; + PyObject *super = PyObject_Vectorcall(global_super, stack, oparg & 2, NULL); + if (opcode == INSTRUMENTED_LOAD_SUPER_ATTR) { + PyObject *arg = oparg & 2 ? class : &_PyInstrumentation_MISSING; + if (super == NULL) { + _Py_call_instrumentation_exc2( + tstate, PY_MONITORING_EVENT_C_RAISE, + frame, next_instr-1, global_super, arg); + } + else { + int err = _Py_call_instrumentation_2args( + tstate, PY_MONITORING_EVENT_C_RETURN, + frame, next_instr-1, global_super, arg); + if (err < 0) { + Py_CLEAR(super); + } + } + } + DECREF_INPUTS(); + ERROR_IF(super == NULL, error); + res = PyObject_GetAttr(super, name); + Py_DECREF(super); + ERROR_IF(res == NULL, error); + } + + inst(LOAD_SUPER_ATTR_ATTR, (unused/1, global_super, class, self -- res2 if (oparg & 1), res)) { + assert(!(oparg & 1)); + DEOPT_IF(global_super != (PyObject *)&PySuper_Type, LOAD_SUPER_ATTR); + DEOPT_IF(!PyType_Check(class), LOAD_SUPER_ATTR); + STAT_INC(LOAD_SUPER_ATTR, hit); + PyObject *name = GETITEM(frame->f_code->co_names, oparg >> 2); + res = _PySuper_Lookup((PyTypeObject *)class, self, name, NULL); + DECREF_INPUTS(); + ERROR_IF(res == NULL, error); + } + + inst(LOAD_SUPER_ATTR_METHOD, (unused/1, global_super, class, self -- res2, res)) { + assert(oparg & 1); + DEOPT_IF(global_super != (PyObject *)&PySuper_Type, LOAD_SUPER_ATTR); + DEOPT_IF(!PyType_Check(class), LOAD_SUPER_ATTR); + STAT_INC(LOAD_SUPER_ATTR, hit); + PyObject *name = GETITEM(frame->f_code->co_names, oparg >> 2); + PyTypeObject *cls = (PyTypeObject *)class; + int method_found = 0; + res2 = _PySuper_Lookup(cls, self, name, + Py_TYPE(self)->tp_getattro == PyObject_GenericGetAttr ? &method_found : NULL); + Py_DECREF(global_super); + Py_DECREF(class); + if (res2 == NULL) { + Py_DECREF(self); + ERROR_IF(true, error); + } + if (method_found) { + res = self; // transfer ownership + } else { + Py_DECREF(self); + res = res2; + res2 = NULL; + } + } + + family(load_attr, INLINE_CACHE_ENTRIES_LOAD_ATTR) = { + LOAD_ATTR, + LOAD_ATTR_INSTANCE_VALUE, + LOAD_ATTR_MODULE, + LOAD_ATTR_WITH_HINT, + LOAD_ATTR_SLOT, + LOAD_ATTR_CLASS, + LOAD_ATTR_PROPERTY, + LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN, + LOAD_ATTR_METHOD_WITH_VALUES, + LOAD_ATTR_METHOD_NO_DICT, + LOAD_ATTR_METHOD_LAZY_DICT, + }; + + inst(LOAD_ATTR, (unused/9, owner -- res2 if (oparg & 1), res)) { + #if ENABLE_SPECIALIZATION + _PyAttrCache *cache = (_PyAttrCache *)next_instr; + if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { + PyObject *name = GETITEM(frame->f_code->co_names, oparg>>1); + next_instr--; + _Py_Specialize_LoadAttr(owner, next_instr, name); + DISPATCH_SAME_OPARG(); + } + STAT_INC(LOAD_ATTR, deferred); + DECREMENT_ADAPTIVE_COUNTER(cache->counter); + #endif /* ENABLE_SPECIALIZATION */ + PyObject *name = GETITEM(frame->f_code->co_names, oparg >> 1); + if (oparg & 1) { + /* Designed to work in tandem with CALL, pushes two values. */ + PyObject* meth = NULL; + if (_PyObject_GetMethod(owner, name, &meth)) { + /* We can bypass temporary bound method object. + meth is unbound method and obj is self. + + meth | self | arg1 | ... | argN + */ + assert(meth != NULL); // No errors on this branch + res2 = meth; + res = owner; // Transfer ownership + } + else { + /* meth is not an unbound method (but a regular attr, or + something was returned by a descriptor protocol). Set + the second element of the stack to NULL, to signal + CALL that it's not a method call. + + NULL | meth | arg1 | ... | argN + */ + DECREF_INPUTS(); + ERROR_IF(meth == NULL, error); + res2 = NULL; + res = meth; + } + } + else { + /* Classic, pushes one value. */ + res = PyObject_GetAttr(owner, name); + DECREF_INPUTS(); + ERROR_IF(res == NULL, error); + } + } + + inst(LOAD_ATTR_INSTANCE_VALUE, (unused/1, type_version/2, index/1, unused/5, owner -- res2 if (oparg & 1), res)) { + PyTypeObject *tp = Py_TYPE(owner); + assert(type_version != 0); + DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR); + assert(tp->tp_dictoffset < 0); + assert(tp->tp_flags & Py_TPFLAGS_MANAGED_DICT); + PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); + DEOPT_IF(!_PyDictOrValues_IsValues(dorv), LOAD_ATTR); + res = _PyDictOrValues_GetValues(dorv)->values[index]; + DEOPT_IF(res == NULL, LOAD_ATTR); + STAT_INC(LOAD_ATTR, hit); + Py_INCREF(res); + res2 = NULL; + DECREF_INPUTS(); + } + + inst(LOAD_ATTR_MODULE, (unused/1, type_version/2, index/1, unused/5, owner -- res2 if (oparg & 1), res)) { + DEOPT_IF(!PyModule_CheckExact(owner), LOAD_ATTR); + PyDictObject *dict = (PyDictObject *)((PyModuleObject *)owner)->md_dict; + assert(dict != NULL); + DEOPT_IF(dict->ma_keys->dk_version != type_version, LOAD_ATTR); + assert(dict->ma_keys->dk_kind == DICT_KEYS_UNICODE); + assert(index < dict->ma_keys->dk_nentries); + PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(dict->ma_keys) + index; + res = ep->me_value; + DEOPT_IF(res == NULL, LOAD_ATTR); + STAT_INC(LOAD_ATTR, hit); + Py_INCREF(res); + res2 = NULL; + DECREF_INPUTS(); + } + + inst(LOAD_ATTR_WITH_HINT, (unused/1, type_version/2, index/1, unused/5, owner -- res2 if (oparg & 1), res)) { + PyTypeObject *tp = Py_TYPE(owner); + assert(type_version != 0); + DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR); + assert(tp->tp_flags & Py_TPFLAGS_MANAGED_DICT); + PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); + DEOPT_IF(_PyDictOrValues_IsValues(dorv), LOAD_ATTR); + PyDictObject *dict = (PyDictObject *)_PyDictOrValues_GetDict(dorv); + DEOPT_IF(dict == NULL, LOAD_ATTR); + assert(PyDict_CheckExact((PyObject *)dict)); + PyObject *name = GETITEM(frame->f_code->co_names, oparg>>1); + uint16_t hint = index; + DEOPT_IF(hint >= (size_t)dict->ma_keys->dk_nentries, LOAD_ATTR); + if (DK_IS_UNICODE(dict->ma_keys)) { + PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(dict->ma_keys) + hint; + DEOPT_IF(ep->me_key != name, LOAD_ATTR); + res = ep->me_value; + } + else { + PyDictKeyEntry *ep = DK_ENTRIES(dict->ma_keys) + hint; + DEOPT_IF(ep->me_key != name, LOAD_ATTR); + res = ep->me_value; + } + DEOPT_IF(res == NULL, LOAD_ATTR); + STAT_INC(LOAD_ATTR, hit); + Py_INCREF(res); + res2 = NULL; + DECREF_INPUTS(); + } + + inst(LOAD_ATTR_SLOT, (unused/1, type_version/2, index/1, unused/5, owner -- res2 if (oparg & 1), res)) { + PyTypeObject *tp = Py_TYPE(owner); + assert(type_version != 0); + DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR); + char *addr = (char *)owner + index; + res = *(PyObject **)addr; + DEOPT_IF(res == NULL, LOAD_ATTR); + STAT_INC(LOAD_ATTR, hit); + Py_INCREF(res); + res2 = NULL; + DECREF_INPUTS(); + } + + inst(LOAD_ATTR_CLASS, (unused/1, type_version/2, unused/2, descr/4, cls -- res2 if (oparg & 1), res)) { + + DEOPT_IF(!PyType_Check(cls), LOAD_ATTR); + DEOPT_IF(((PyTypeObject *)cls)->tp_version_tag != type_version, + LOAD_ATTR); + assert(type_version != 0); + + STAT_INC(LOAD_ATTR, hit); + res2 = NULL; + res = descr; + assert(res != NULL); + Py_INCREF(res); + DECREF_INPUTS(); + } + + inst(LOAD_ATTR_PROPERTY, (unused/1, type_version/2, func_version/2, fget/4, owner -- unused if (oparg & 1), unused)) { + DEOPT_IF(tstate->interp->eval_frame, LOAD_ATTR); + + PyTypeObject *cls = Py_TYPE(owner); + DEOPT_IF(cls->tp_version_tag != type_version, LOAD_ATTR); + assert(type_version != 0); + assert(Py_IS_TYPE(fget, &PyFunction_Type)); + PyFunctionObject *f = (PyFunctionObject *)fget; + assert(func_version != 0); + DEOPT_IF(f->func_version != func_version, LOAD_ATTR); + PyCodeObject *code = (PyCodeObject *)f->func_code; + assert(code->co_argcount == 1); + DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), LOAD_ATTR); + STAT_INC(LOAD_ATTR, hit); + Py_INCREF(fget); + _PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, f, 1); + // Manipulate stack directly because we exit with DISPATCH_INLINED(). + SET_TOP(NULL); + int shrink_stack = !(oparg & 1); + STACK_SHRINK(shrink_stack); + new_frame->localsplus[0] = owner; + JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); + frame->return_offset = 0; + DISPATCH_INLINED(new_frame); + } + + inst(LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN, (unused/1, type_version/2, func_version/2, getattribute/4, owner -- unused if (oparg & 1), unused)) { + DEOPT_IF(tstate->interp->eval_frame, LOAD_ATTR); + PyTypeObject *cls = Py_TYPE(owner); + DEOPT_IF(cls->tp_version_tag != type_version, LOAD_ATTR); + assert(type_version != 0); + assert(Py_IS_TYPE(getattribute, &PyFunction_Type)); + PyFunctionObject *f = (PyFunctionObject *)getattribute; + assert(func_version != 0); + DEOPT_IF(f->func_version != func_version, LOAD_ATTR); + PyCodeObject *code = (PyCodeObject *)f->func_code; + assert(code->co_argcount == 2); + DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), LOAD_ATTR); + STAT_INC(LOAD_ATTR, hit); + + PyObject *name = GETITEM(frame->f_code->co_names, oparg >> 1); + Py_INCREF(f); + _PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, f, 2); + // Manipulate stack directly because we exit with DISPATCH_INLINED(). + SET_TOP(NULL); + int shrink_stack = !(oparg & 1); + STACK_SHRINK(shrink_stack); + new_frame->localsplus[0] = owner; + new_frame->localsplus[1] = Py_NewRef(name); + JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); + frame->return_offset = 0; + DISPATCH_INLINED(new_frame); + } + + inst(STORE_ATTR_INSTANCE_VALUE, (unused/1, type_version/2, index/1, value, owner --)) { + PyTypeObject *tp = Py_TYPE(owner); + assert(type_version != 0); + DEOPT_IF(tp->tp_version_tag != type_version, STORE_ATTR); + assert(tp->tp_flags & Py_TPFLAGS_MANAGED_DICT); + PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); + DEOPT_IF(!_PyDictOrValues_IsValues(dorv), STORE_ATTR); + STAT_INC(STORE_ATTR, hit); + PyDictValues *values = _PyDictOrValues_GetValues(dorv); + PyObject *old_value = values->values[index]; + values->values[index] = value; + if (old_value == NULL) { + _PyDictValues_AddToInsertionOrder(values, index); + } + else { + Py_DECREF(old_value); + } + Py_DECREF(owner); + } + + inst(STORE_ATTR_WITH_HINT, (unused/1, type_version/2, hint/1, value, owner --)) { + PyTypeObject *tp = Py_TYPE(owner); + assert(type_version != 0); + DEOPT_IF(tp->tp_version_tag != type_version, STORE_ATTR); + assert(tp->tp_flags & Py_TPFLAGS_MANAGED_DICT); + PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); + DEOPT_IF(_PyDictOrValues_IsValues(dorv), STORE_ATTR); + PyDictObject *dict = (PyDictObject *)_PyDictOrValues_GetDict(dorv); + DEOPT_IF(dict == NULL, STORE_ATTR); + assert(PyDict_CheckExact((PyObject *)dict)); + PyObject *name = GETITEM(frame->f_code->co_names, oparg); + DEOPT_IF(hint >= (size_t)dict->ma_keys->dk_nentries, STORE_ATTR); + PyObject *old_value; + uint64_t new_version; + if (DK_IS_UNICODE(dict->ma_keys)) { + PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(dict->ma_keys) + hint; + DEOPT_IF(ep->me_key != name, STORE_ATTR); + old_value = ep->me_value; + DEOPT_IF(old_value == NULL, STORE_ATTR); + new_version = _PyDict_NotifyEvent(tstate->interp, PyDict_EVENT_MODIFIED, dict, name, value); + ep->me_value = value; + } + else { + PyDictKeyEntry *ep = DK_ENTRIES(dict->ma_keys) + hint; + DEOPT_IF(ep->me_key != name, STORE_ATTR); + old_value = ep->me_value; + DEOPT_IF(old_value == NULL, STORE_ATTR); + new_version = _PyDict_NotifyEvent(tstate->interp, PyDict_EVENT_MODIFIED, dict, name, value); + ep->me_value = value; + } + Py_DECREF(old_value); + STAT_INC(STORE_ATTR, hit); + /* Ensure dict is GC tracked if it needs to be */ + if (!_PyObject_GC_IS_TRACKED(dict) && _PyObject_GC_MAY_BE_TRACKED(value)) { + _PyObject_GC_TRACK(dict); + } + /* PEP 509 */ + dict->ma_version_tag = new_version; + Py_DECREF(owner); + } + + inst(STORE_ATTR_SLOT, (unused/1, type_version/2, index/1, value, owner --)) { + PyTypeObject *tp = Py_TYPE(owner); + assert(type_version != 0); + DEOPT_IF(tp->tp_version_tag != type_version, STORE_ATTR); + char *addr = (char *)owner + index; + STAT_INC(STORE_ATTR, hit); + PyObject *old_value = *(PyObject **)addr; + *(PyObject **)addr = value; + Py_XDECREF(old_value); + Py_DECREF(owner); + } + + family(compare_op, INLINE_CACHE_ENTRIES_COMPARE_OP) = { + COMPARE_OP, + COMPARE_OP_FLOAT, + COMPARE_OP_INT, + COMPARE_OP_STR, + }; + + inst(COMPARE_OP, (unused/1, left, right -- res)) { + #if ENABLE_SPECIALIZATION + _PyCompareOpCache *cache = (_PyCompareOpCache *)next_instr; + if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { + next_instr--; + _Py_Specialize_CompareOp(left, right, next_instr, oparg); + DISPATCH_SAME_OPARG(); + } + STAT_INC(COMPARE_OP, deferred); + DECREMENT_ADAPTIVE_COUNTER(cache->counter); + #endif /* ENABLE_SPECIALIZATION */ + assert((oparg >> 4) <= Py_GE); + res = PyObject_RichCompare(left, right, oparg>>4); + DECREF_INPUTS(); + ERROR_IF(res == NULL, error); + } + + inst(COMPARE_OP_FLOAT, (unused/1, left, right -- res)) { + DEOPT_IF(!PyFloat_CheckExact(left), COMPARE_OP); + DEOPT_IF(!PyFloat_CheckExact(right), COMPARE_OP); + STAT_INC(COMPARE_OP, hit); + double dleft = PyFloat_AS_DOUBLE(left); + double dright = PyFloat_AS_DOUBLE(right); + // 1 if NaN, 2 if <, 4 if >, 8 if ==; this matches low four bits of the oparg + int sign_ish = COMPARISON_BIT(dleft, dright); + _Py_DECREF_SPECIALIZED(left, _PyFloat_ExactDealloc); + _Py_DECREF_SPECIALIZED(right, _PyFloat_ExactDealloc); + res = (sign_ish & oparg) ? Py_True : Py_False; + } + + // Similar to COMPARE_OP_FLOAT + inst(COMPARE_OP_INT, (unused/1, left, right -- res)) { + DEOPT_IF(!PyLong_CheckExact(left), COMPARE_OP); + DEOPT_IF(!PyLong_CheckExact(right), COMPARE_OP); + DEOPT_IF(!_PyLong_IsCompact((PyLongObject *)left), COMPARE_OP); + DEOPT_IF(!_PyLong_IsCompact((PyLongObject *)right), COMPARE_OP); + STAT_INC(COMPARE_OP, hit); + assert(_PyLong_DigitCount((PyLongObject *)left) <= 1 && + _PyLong_DigitCount((PyLongObject *)right) <= 1); + Py_ssize_t ileft = _PyLong_CompactValue((PyLongObject *)left); + Py_ssize_t iright = _PyLong_CompactValue((PyLongObject *)right); + // 2 if <, 4 if >, 8 if ==; this matches the low 4 bits of the oparg + int sign_ish = COMPARISON_BIT(ileft, iright); + _Py_DECREF_SPECIALIZED(left, (destructor)PyObject_Free); + _Py_DECREF_SPECIALIZED(right, (destructor)PyObject_Free); + res = (sign_ish & oparg) ? Py_True : Py_False; + } + + // Similar to COMPARE_OP_FLOAT, but for ==, != only + inst(COMPARE_OP_STR, (unused/1, left, right -- res)) { + DEOPT_IF(!PyUnicode_CheckExact(left), COMPARE_OP); + DEOPT_IF(!PyUnicode_CheckExact(right), COMPARE_OP); + STAT_INC(COMPARE_OP, hit); + int eq = _PyUnicode_Equal(left, right); + assert((oparg >>4) == Py_EQ || (oparg >>4) == Py_NE); + _Py_DECREF_SPECIALIZED(left, _PyUnicode_ExactDealloc); + _Py_DECREF_SPECIALIZED(right, _PyUnicode_ExactDealloc); + assert(eq == 0 || eq == 1); + assert((oparg & 0xf) == COMPARISON_NOT_EQUALS || (oparg & 0xf) == COMPARISON_EQUALS); + assert(COMPARISON_NOT_EQUALS + 1 == COMPARISON_EQUALS); + res = ((COMPARISON_NOT_EQUALS + eq) & oparg) ? Py_True : Py_False; + } + + inst(IS_OP, (left, right -- b)) { + int res = Py_Is(left, right) ^ oparg; + DECREF_INPUTS(); + b = res ? Py_True : Py_False; + } + + inst(CONTAINS_OP, (left, right -- b)) { + int res = PySequence_Contains(right, left); + DECREF_INPUTS(); + ERROR_IF(res < 0, error); + b = (res ^ oparg) ? Py_True : Py_False; + } + + inst(CHECK_EG_MATCH, (exc_value, match_type -- rest, match)) { + if (check_except_star_type_valid(tstate, match_type) < 0) { + DECREF_INPUTS(); + ERROR_IF(true, error); + } + + match = NULL; + rest = NULL; + int res = exception_group_match(exc_value, match_type, + &match, &rest); + DECREF_INPUTS(); + ERROR_IF(res < 0, error); + + assert((match == NULL) == (rest == NULL)); + ERROR_IF(match == NULL, error); + + if (!Py_IsNone(match)) { + PyErr_SetHandledException(match); + } + } + + inst(CHECK_EXC_MATCH, (left, right -- left, b)) { + assert(PyExceptionInstance_Check(left)); + if (check_except_type_valid(tstate, right) < 0) { + DECREF_INPUTS(); + ERROR_IF(true, error); + } + + int res = PyErr_GivenExceptionMatches(left, right); + DECREF_INPUTS(); + b = res ? Py_True : Py_False; + } + + inst(IMPORT_NAME, (level, fromlist -- res)) { + PyObject *name = GETITEM(frame->f_code->co_names, oparg); + res = import_name(tstate, frame, name, fromlist, level); + DECREF_INPUTS(); + ERROR_IF(res == NULL, error); + } + + inst(IMPORT_FROM, (from -- from, res)) { + PyObject *name = GETITEM(frame->f_code->co_names, oparg); + res = import_from(tstate, from, name); + ERROR_IF(res == NULL, error); + } + + inst(JUMP_FORWARD, (--)) { + JUMPBY(oparg); + } + + inst(JUMP_BACKWARD, (--)) { + assert(oparg < INSTR_OFFSET()); + JUMPBY(-oparg); + CHECK_EVAL_BREAKER(); + } + + inst(POP_JUMP_IF_FALSE, (cond -- )) { + if (Py_IsFalse(cond)) { + JUMPBY(oparg); + } + else if (!Py_IsTrue(cond)) { + int err = PyObject_IsTrue(cond); + DECREF_INPUTS(); + if (err == 0) { + JUMPBY(oparg); + } + else { + ERROR_IF(err < 0, error); + } + } + } + + inst(POP_JUMP_IF_TRUE, (cond -- )) { + if (Py_IsTrue(cond)) { + JUMPBY(oparg); + } + else if (!Py_IsFalse(cond)) { + int err = PyObject_IsTrue(cond); + DECREF_INPUTS(); + if (err > 0) { + JUMPBY(oparg); + } + else { + ERROR_IF(err < 0, error); + } + } + } + + inst(POP_JUMP_IF_NOT_NONE, (value -- )) { + if (!Py_IsNone(value)) { + DECREF_INPUTS(); + JUMPBY(oparg); + } + } + + inst(POP_JUMP_IF_NONE, (value -- )) { + if (Py_IsNone(value)) { + JUMPBY(oparg); + } + else { + DECREF_INPUTS(); + } + } + + inst(JUMP_BACKWARD_NO_INTERRUPT, (--)) { + /* This bytecode is used in the `yield from` or `await` loop. + * If there is an interrupt, we want it handled in the innermost + * generator or coroutine, so we deliberately do not check it here. + * (see bpo-30039). + */ + JUMPBY(-oparg); + } + + inst(GET_LEN, (obj -- obj, len_o)) { + // PUSH(len(TOS)) + Py_ssize_t len_i = PyObject_Length(obj); + ERROR_IF(len_i < 0, error); + len_o = PyLong_FromSsize_t(len_i); + ERROR_IF(len_o == NULL, error); + } + + inst(MATCH_CLASS, (subject, type, names -- attrs)) { + // Pop TOS and TOS1. Set TOS to a tuple of attributes on success, or + // None on failure. + assert(PyTuple_CheckExact(names)); + attrs = match_class(tstate, subject, type, oparg, names); + DECREF_INPUTS(); + if (attrs) { + assert(PyTuple_CheckExact(attrs)); // Success! + } + else { + ERROR_IF(_PyErr_Occurred(tstate), error); // Error! + attrs = Py_None; // Failure! + } + } + + inst(MATCH_MAPPING, (subject -- subject, res)) { + int match = Py_TYPE(subject)->tp_flags & Py_TPFLAGS_MAPPING; + res = match ? Py_True : Py_False; + PREDICT(POP_JUMP_IF_FALSE); + } + + inst(MATCH_SEQUENCE, (subject -- subject, res)) { + int match = Py_TYPE(subject)->tp_flags & Py_TPFLAGS_SEQUENCE; + res = match ? Py_True : Py_False; + PREDICT(POP_JUMP_IF_FALSE); + } + + inst(MATCH_KEYS, (subject, keys -- subject, keys, values_or_none)) { + // On successful match, PUSH(values). Otherwise, PUSH(None). + values_or_none = match_keys(tstate, subject, keys); + ERROR_IF(values_or_none == NULL, error); + } + + inst(GET_ITER, (iterable -- iter)) { + /* before: [obj]; after [getiter(obj)] */ + iter = PyObject_GetIter(iterable); + DECREF_INPUTS(); + ERROR_IF(iter == NULL, error); + } + + inst(GET_YIELD_FROM_ITER, (iterable -- iter)) { + /* before: [obj]; after [getiter(obj)] */ + if (PyCoro_CheckExact(iterable)) { + /* `iterable` is a coroutine */ + if (!(frame->f_code->co_flags & (CO_COROUTINE | CO_ITERABLE_COROUTINE))) { + /* and it is used in a 'yield from' expression of a + regular generator. */ + _PyErr_SetString(tstate, PyExc_TypeError, + "cannot 'yield from' a coroutine object " + "in a non-coroutine generator"); + goto error; + } + iter = iterable; + } + else if (PyGen_CheckExact(iterable)) { + iter = iterable; + } + else { + /* `iterable` is not a generator. */ + iter = PyObject_GetIter(iterable); + if (iter == NULL) { + goto error; + } + DECREF_INPUTS(); + } + PREDICT(LOAD_CONST); + } + + // Most members of this family are "secretly" super-instructions. + // When the loop is exhausted, they jump, and the jump target is + // always END_FOR, which pops two values off the stack. + // This is optimized by skipping that instruction and combining + // its effect (popping 'iter' instead of pushing 'next'.) + + family(for_iter, INLINE_CACHE_ENTRIES_FOR_ITER) = { + FOR_ITER, + FOR_ITER_LIST, + FOR_ITER_TUPLE, + FOR_ITER_RANGE, + FOR_ITER_GEN, + }; + + inst(FOR_ITER, (unused/1, iter -- iter, next)) { + #if ENABLE_SPECIALIZATION + _PyForIterCache *cache = (_PyForIterCache *)next_instr; + if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { + next_instr--; + _Py_Specialize_ForIter(iter, next_instr, oparg); + DISPATCH_SAME_OPARG(); + } + STAT_INC(FOR_ITER, deferred); + DECREMENT_ADAPTIVE_COUNTER(cache->counter); + #endif /* ENABLE_SPECIALIZATION */ + /* before: [iter]; after: [iter, iter()] *or* [] (and jump over END_FOR.) */ + next = (*Py_TYPE(iter)->tp_iternext)(iter); + if (next == NULL) { + if (_PyErr_Occurred(tstate)) { + if (!_PyErr_ExceptionMatches(tstate, PyExc_StopIteration)) { + goto error; + } + monitor_raise(tstate, frame, next_instr-1); + _PyErr_Clear(tstate); + } + /* iterator ended normally */ + assert(next_instr[INLINE_CACHE_ENTRIES_FOR_ITER + oparg].op.code == END_FOR || + next_instr[INLINE_CACHE_ENTRIES_FOR_ITER + oparg].op.code == INSTRUMENTED_END_FOR); + Py_DECREF(iter); + STACK_SHRINK(1); + /* Jump forward oparg, then skip following END_FOR instruction */ + JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + oparg + 1); + DISPATCH(); + } + // Common case: no jump, leave it to the code generator + } + + inst(INSTRUMENTED_FOR_ITER, ( -- )) { + _Py_CODEUNIT *here = next_instr-1; + _Py_CODEUNIT *target; + PyObject *iter = TOP(); + PyObject *next = (*Py_TYPE(iter)->tp_iternext)(iter); + if (next != NULL) { + PUSH(next); + target = next_instr + INLINE_CACHE_ENTRIES_FOR_ITER; + } + else { + if (_PyErr_Occurred(tstate)) { + if (!_PyErr_ExceptionMatches(tstate, PyExc_StopIteration)) { + goto error; + } + monitor_raise(tstate, frame, here); + _PyErr_Clear(tstate); + } + /* iterator ended normally */ + assert(next_instr[INLINE_CACHE_ENTRIES_FOR_ITER + oparg].op.code == END_FOR || + next_instr[INLINE_CACHE_ENTRIES_FOR_ITER + oparg].op.code == INSTRUMENTED_END_FOR); + STACK_SHRINK(1); + Py_DECREF(iter); + /* Skip END_FOR */ + target = next_instr + INLINE_CACHE_ENTRIES_FOR_ITER + oparg + 1; + } + INSTRUMENTED_JUMP(here, target, PY_MONITORING_EVENT_BRANCH); + } + + inst(FOR_ITER_LIST, (unused/1, iter -- iter, next)) { + DEOPT_IF(Py_TYPE(iter) != &PyListIter_Type, FOR_ITER); + _PyListIterObject *it = (_PyListIterObject *)iter; + STAT_INC(FOR_ITER, hit); + PyListObject *seq = it->it_seq; + if (seq) { + if (it->it_index < PyList_GET_SIZE(seq)) { + next = Py_NewRef(PyList_GET_ITEM(seq, it->it_index++)); + goto end_for_iter_list; // End of this instruction + } + it->it_seq = NULL; + Py_DECREF(seq); + } + Py_DECREF(iter); + STACK_SHRINK(1); + /* Jump forward oparg, then skip following END_FOR instruction */ + JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + oparg + 1); + DISPATCH(); + end_for_iter_list: + // Common case: no jump, leave it to the code generator + } + + inst(FOR_ITER_TUPLE, (unused/1, iter -- iter, next)) { + _PyTupleIterObject *it = (_PyTupleIterObject *)iter; + DEOPT_IF(Py_TYPE(it) != &PyTupleIter_Type, FOR_ITER); + STAT_INC(FOR_ITER, hit); + PyTupleObject *seq = it->it_seq; + if (seq) { + if (it->it_index < PyTuple_GET_SIZE(seq)) { + next = Py_NewRef(PyTuple_GET_ITEM(seq, it->it_index++)); + goto end_for_iter_tuple; // End of this instruction + } + it->it_seq = NULL; + Py_DECREF(seq); + } + Py_DECREF(iter); + STACK_SHRINK(1); + /* Jump forward oparg, then skip following END_FOR instruction */ + JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + oparg + 1); + DISPATCH(); + end_for_iter_tuple: + // Common case: no jump, leave it to the code generator + } + + inst(FOR_ITER_RANGE, (unused/1, iter -- iter, next)) { + _PyRangeIterObject *r = (_PyRangeIterObject *)iter; + DEOPT_IF(Py_TYPE(r) != &PyRangeIter_Type, FOR_ITER); + STAT_INC(FOR_ITER, hit); + if (r->len <= 0) { + STACK_SHRINK(1); + Py_DECREF(r); + // Jump over END_FOR instruction. + JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + oparg + 1); + DISPATCH(); + } + long value = r->start; + r->start = value + r->step; + r->len--; + next = PyLong_FromLong(value); + if (next == NULL) { + goto error; + } + } + + inst(FOR_ITER_GEN, (unused/1, iter -- iter, unused)) { + DEOPT_IF(tstate->interp->eval_frame, FOR_ITER); + PyGenObject *gen = (PyGenObject *)iter; + DEOPT_IF(Py_TYPE(gen) != &PyGen_Type, FOR_ITER); + DEOPT_IF(gen->gi_frame_state >= FRAME_EXECUTING, FOR_ITER); + STAT_INC(FOR_ITER, hit); + _PyInterpreterFrame *gen_frame = (_PyInterpreterFrame *)gen->gi_iframe; + frame->return_offset = oparg; + _PyFrame_StackPush(gen_frame, Py_None); + gen->gi_frame_state = FRAME_EXECUTING; + gen->gi_exc_state.previous_item = tstate->exc_info; + tstate->exc_info = &gen->gi_exc_state; + JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER); + assert(next_instr[oparg].op.code == END_FOR || + next_instr[oparg].op.code == INSTRUMENTED_END_FOR); + DISPATCH_INLINED(gen_frame); + } + + inst(BEFORE_ASYNC_WITH, (mgr -- exit, res)) { + PyObject *enter = _PyObject_LookupSpecial(mgr, &_Py_ID(__aenter__)); + if (enter == NULL) { + if (!_PyErr_Occurred(tstate)) { + _PyErr_Format(tstate, PyExc_TypeError, + "'%.200s' object does not support the " + "asynchronous context manager protocol", + Py_TYPE(mgr)->tp_name); + } + goto error; + } + exit = _PyObject_LookupSpecial(mgr, &_Py_ID(__aexit__)); + if (exit == NULL) { + if (!_PyErr_Occurred(tstate)) { + _PyErr_Format(tstate, PyExc_TypeError, + "'%.200s' object does not support the " + "asynchronous context manager protocol " + "(missed __aexit__ method)", + Py_TYPE(mgr)->tp_name); + } + Py_DECREF(enter); + goto error; + } + DECREF_INPUTS(); + res = _PyObject_CallNoArgs(enter); + Py_DECREF(enter); + if (res == NULL) { + Py_DECREF(exit); + ERROR_IF(true, error); + } + PREDICT(GET_AWAITABLE); + } + + inst(BEFORE_WITH, (mgr -- exit, res)) { + /* pop the context manager, push its __exit__ and the + * value returned from calling its __enter__ + */ + PyObject *enter = _PyObject_LookupSpecial(mgr, &_Py_ID(__enter__)); + if (enter == NULL) { + if (!_PyErr_Occurred(tstate)) { + _PyErr_Format(tstate, PyExc_TypeError, + "'%.200s' object does not support the " + "context manager protocol", + Py_TYPE(mgr)->tp_name); + } + goto error; + } + exit = _PyObject_LookupSpecial(mgr, &_Py_ID(__exit__)); + if (exit == NULL) { + if (!_PyErr_Occurred(tstate)) { + _PyErr_Format(tstate, PyExc_TypeError, + "'%.200s' object does not support the " + "context manager protocol " + "(missed __exit__ method)", + Py_TYPE(mgr)->tp_name); + } + Py_DECREF(enter); + goto error; + } + DECREF_INPUTS(); + res = _PyObject_CallNoArgs(enter); + Py_DECREF(enter); + if (res == NULL) { + Py_DECREF(exit); + ERROR_IF(true, error); + } + } + + inst(WITH_EXCEPT_START, (exit_func, lasti, unused, val -- exit_func, lasti, unused, val, res)) { + /* At the top of the stack are 4 values: + - val: TOP = exc_info() + - unused: SECOND = previous exception + - lasti: THIRD = lasti of exception in exc_info() + - exit_func: FOURTH = the context.__exit__ bound method + We call FOURTH(type(TOP), TOP, GetTraceback(TOP)). + Then we push the __exit__ return value. + */ + PyObject *exc, *tb; + + assert(val && PyExceptionInstance_Check(val)); + exc = PyExceptionInstance_Class(val); + tb = PyException_GetTraceback(val); + if (tb == NULL) { + tb = Py_None; + } + else { + Py_DECREF(tb); + } + assert(PyLong_Check(lasti)); + (void)lasti; // Shut up compiler warning if asserts are off + PyObject *stack[4] = {NULL, exc, val, tb}; + res = PyObject_Vectorcall(exit_func, stack + 1, + 3 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); + ERROR_IF(res == NULL, error); + } + + inst(PUSH_EXC_INFO, (new_exc -- prev_exc, new_exc)) { + _PyErr_StackItem *exc_info = tstate->exc_info; + if (exc_info->exc_value != NULL) { + prev_exc = exc_info->exc_value; + } + else { + prev_exc = Py_None; + } + assert(PyExceptionInstance_Check(new_exc)); + exc_info->exc_value = Py_NewRef(new_exc); + } + + inst(LOAD_ATTR_METHOD_WITH_VALUES, (unused/1, type_version/2, keys_version/2, descr/4, self -- res2 if (oparg & 1), res)) { + /* Cached method object */ + PyTypeObject *self_cls = Py_TYPE(self); + assert(type_version != 0); + DEOPT_IF(self_cls->tp_version_tag != type_version, LOAD_ATTR); + assert(self_cls->tp_flags & Py_TPFLAGS_MANAGED_DICT); + PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(self); + DEOPT_IF(!_PyDictOrValues_IsValues(dorv), LOAD_ATTR); + PyHeapTypeObject *self_heap_type = (PyHeapTypeObject *)self_cls; + DEOPT_IF(self_heap_type->ht_cached_keys->dk_version != + keys_version, LOAD_ATTR); + STAT_INC(LOAD_ATTR, hit); + assert(descr != NULL); + res2 = Py_NewRef(descr); + assert(_PyType_HasFeature(Py_TYPE(res2), Py_TPFLAGS_METHOD_DESCRIPTOR)); + res = self; + assert(oparg & 1); + } + + inst(LOAD_ATTR_METHOD_NO_DICT, (unused/1, type_version/2, unused/2, descr/4, self -- res2 if (oparg & 1), res)) { + PyTypeObject *self_cls = Py_TYPE(self); + DEOPT_IF(self_cls->tp_version_tag != type_version, LOAD_ATTR); + assert(self_cls->tp_dictoffset == 0); + STAT_INC(LOAD_ATTR, hit); + assert(descr != NULL); + assert(_PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_METHOD_DESCRIPTOR)); + res2 = Py_NewRef(descr); + res = self; + assert(oparg & 1); + } + + inst(LOAD_ATTR_METHOD_LAZY_DICT, (unused/1, type_version/2, unused/2, descr/4, self -- res2 if (oparg & 1), res)) { + PyTypeObject *self_cls = Py_TYPE(self); + DEOPT_IF(self_cls->tp_version_tag != type_version, LOAD_ATTR); + Py_ssize_t dictoffset = self_cls->tp_dictoffset; + assert(dictoffset > 0); + PyObject *dict = *(PyObject **)((char *)self + dictoffset); + /* This object has a __dict__, just not yet created */ + DEOPT_IF(dict != NULL, LOAD_ATTR); + STAT_INC(LOAD_ATTR, hit); + assert(descr != NULL); + assert(_PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_METHOD_DESCRIPTOR)); + res2 = Py_NewRef(descr); + res = self; + assert(oparg & 1); + } + + inst(KW_NAMES, (--)) { + assert(kwnames == NULL); + assert(oparg < PyTuple_GET_SIZE(frame->f_code->co_consts)); + kwnames = GETITEM(frame->f_code->co_consts, oparg); + } + + inst(INSTRUMENTED_CALL, ( -- )) { + int is_meth = PEEK(oparg+2) != NULL; + int total_args = oparg + is_meth; + PyObject *function = PEEK(total_args + 1); + PyObject *arg = total_args == 0 ? + &_PyInstrumentation_MISSING : PEEK(total_args); + int err = _Py_call_instrumentation_2args( + tstate, PY_MONITORING_EVENT_CALL, + frame, next_instr-1, function, arg); + ERROR_IF(err, error); + _PyCallCache *cache = (_PyCallCache *)next_instr; + INCREMENT_ADAPTIVE_COUNTER(cache->counter); + GO_TO_INSTRUCTION(CALL); + } + + // Cache layout: counter/1, func_version/2 + // Neither CALL_INTRINSIC_1/2 nor CALL_FUNCTION_EX are members! + family(call, INLINE_CACHE_ENTRIES_CALL) = { + CALL, + CALL_BOUND_METHOD_EXACT_ARGS, + CALL_PY_EXACT_ARGS, + CALL_PY_WITH_DEFAULTS, + CALL_NO_KW_TYPE_1, + CALL_NO_KW_STR_1, + CALL_NO_KW_TUPLE_1, + CALL_BUILTIN_CLASS, + CALL_NO_KW_BUILTIN_O, + CALL_NO_KW_BUILTIN_FAST, + CALL_BUILTIN_FAST_WITH_KEYWORDS, + CALL_NO_KW_LEN, + CALL_NO_KW_ISINSTANCE, + CALL_NO_KW_LIST_APPEND, + CALL_NO_KW_METHOD_DESCRIPTOR_O, + CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS, + CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS, + CALL_NO_KW_METHOD_DESCRIPTOR_FAST, + }; + + // On entry, the stack is either + // [NULL, callable, arg1, arg2, ...] + // or + // [method, self, arg1, arg2, ...] + // (Some args may be keywords, see KW_NAMES, which sets 'kwnames'.) + // On exit, the stack is [result]. + // When calling Python, inline the call using DISPATCH_INLINED(). + inst(CALL, (unused/1, unused/2, method, callable, args[oparg] -- res)) { + int is_meth = method != NULL; + int total_args = oparg; + if (is_meth) { + callable = method; + args--; + total_args++; + } + #if ENABLE_SPECIALIZATION + _PyCallCache *cache = (_PyCallCache *)next_instr; + if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { + next_instr--; + _Py_Specialize_Call(callable, next_instr, total_args, kwnames); + DISPATCH_SAME_OPARG(); + } + STAT_INC(CALL, deferred); + DECREMENT_ADAPTIVE_COUNTER(cache->counter); + #endif /* ENABLE_SPECIALIZATION */ + if (!is_meth && Py_TYPE(callable) == &PyMethod_Type) { + is_meth = 1; // For consistenct; it's dead, though + args--; + total_args++; + PyObject *self = ((PyMethodObject *)callable)->im_self; + args[0] = Py_NewRef(self); + method = ((PyMethodObject *)callable)->im_func; + args[-1] = Py_NewRef(method); + Py_DECREF(callable); + callable = method; + } + int positional_args = total_args - KWNAMES_LEN(); + // Check if the call can be inlined or not + if (Py_TYPE(callable) == &PyFunction_Type && + tstate->interp->eval_frame == NULL && + ((PyFunctionObject *)callable)->vectorcall == _PyFunction_Vectorcall) + { + int code_flags = ((PyCodeObject*)PyFunction_GET_CODE(callable))->co_flags; + PyObject *locals = code_flags & CO_OPTIMIZED ? NULL : Py_NewRef(PyFunction_GET_GLOBALS(callable)); + _PyInterpreterFrame *new_frame = _PyEvalFramePushAndInit( + tstate, (PyFunctionObject *)callable, locals, + args, positional_args, kwnames + ); + kwnames = NULL; + // Manipulate stack directly since we leave using DISPATCH_INLINED(). + STACK_SHRINK(oparg + 2); + // The frame has stolen all the arguments from the stack, + // so there is no need to clean them up. + if (new_frame == NULL) { + goto error; + } + JUMPBY(INLINE_CACHE_ENTRIES_CALL); + frame->return_offset = 0; + DISPATCH_INLINED(new_frame); + } + /* Callable is not a normal Python function */ + res = PyObject_Vectorcall( + callable, args, + positional_args | PY_VECTORCALL_ARGUMENTS_OFFSET, + kwnames); + if (opcode == INSTRUMENTED_CALL) { + PyObject *arg = total_args == 0 ? + &_PyInstrumentation_MISSING : PEEK(total_args); + if (res == NULL) { + _Py_call_instrumentation_exc2( + tstate, PY_MONITORING_EVENT_C_RAISE, + frame, next_instr-1, callable, arg); + } + else { + int err = _Py_call_instrumentation_2args( + tstate, PY_MONITORING_EVENT_C_RETURN, + frame, next_instr-1, callable, arg); + if (err < 0) { + Py_CLEAR(res); + } + } + } + kwnames = NULL; + assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); + Py_DECREF(callable); + for (int i = 0; i < total_args; i++) { + Py_DECREF(args[i]); + } + ERROR_IF(res == NULL, error); + CHECK_EVAL_BREAKER(); + } + + // Start out with [NULL, bound_method, arg1, arg2, ...] + // Transform to [callable, self, arg1, arg2, ...] + // Then fall through to CALL_PY_EXACT_ARGS + inst(CALL_BOUND_METHOD_EXACT_ARGS, (unused/1, unused/2, method, callable, unused[oparg] -- unused)) { + DEOPT_IF(method != NULL, CALL); + DEOPT_IF(Py_TYPE(callable) != &PyMethod_Type, CALL); + STAT_INC(CALL, hit); + PyObject *self = ((PyMethodObject *)callable)->im_self; + PEEK(oparg + 1) = Py_NewRef(self); // callable + PyObject *meth = ((PyMethodObject *)callable)->im_func; + PEEK(oparg + 2) = Py_NewRef(meth); // method + Py_DECREF(callable); + GO_TO_INSTRUCTION(CALL_PY_EXACT_ARGS); + } + + inst(CALL_PY_EXACT_ARGS, (unused/1, func_version/2, method, callable, args[oparg] -- unused)) { + assert(kwnames == NULL); + DEOPT_IF(tstate->interp->eval_frame, CALL); + int is_meth = method != NULL; + int argcount = oparg; + if (is_meth) { + callable = method; + args--; + argcount++; + } + DEOPT_IF(!PyFunction_Check(callable), CALL); + PyFunctionObject *func = (PyFunctionObject *)callable; + DEOPT_IF(func->func_version != func_version, CALL); + PyCodeObject *code = (PyCodeObject *)func->func_code; + DEOPT_IF(code->co_argcount != argcount, CALL); + DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), CALL); + STAT_INC(CALL, hit); + _PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, func, argcount); + for (int i = 0; i < argcount; i++) { + new_frame->localsplus[i] = args[i]; + } + // Manipulate stack directly since we leave using DISPATCH_INLINED(). + STACK_SHRINK(oparg + 2); + JUMPBY(INLINE_CACHE_ENTRIES_CALL); + frame->return_offset = 0; + DISPATCH_INLINED(new_frame); + } + + inst(CALL_PY_WITH_DEFAULTS, (unused/1, func_version/2, method, callable, args[oparg] -- unused)) { + assert(kwnames == NULL); + DEOPT_IF(tstate->interp->eval_frame, CALL); + int is_meth = method != NULL; + int argcount = oparg; + if (is_meth) { + callable = method; + args--; + argcount++; + } + DEOPT_IF(!PyFunction_Check(callable), CALL); + PyFunctionObject *func = (PyFunctionObject *)callable; + DEOPT_IF(func->func_version != func_version, CALL); + PyCodeObject *code = (PyCodeObject *)func->func_code; + assert(func->func_defaults); + assert(PyTuple_CheckExact(func->func_defaults)); + int defcount = (int)PyTuple_GET_SIZE(func->func_defaults); + assert(defcount <= code->co_argcount); + int min_args = code->co_argcount - defcount; + DEOPT_IF(argcount > code->co_argcount, CALL); + DEOPT_IF(argcount < min_args, CALL); + DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), CALL); + STAT_INC(CALL, hit); + _PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, func, code->co_argcount); + for (int i = 0; i < argcount; i++) { + new_frame->localsplus[i] = args[i]; + } + for (int i = argcount; i < code->co_argcount; i++) { + PyObject *def = PyTuple_GET_ITEM(func->func_defaults, i - min_args); + new_frame->localsplus[i] = Py_NewRef(def); + } + // Manipulate stack and cache directly since we leave using DISPATCH_INLINED(). + STACK_SHRINK(oparg + 2); + JUMPBY(INLINE_CACHE_ENTRIES_CALL); + frame->return_offset = 0; + DISPATCH_INLINED(new_frame); + } + + inst(CALL_NO_KW_TYPE_1, (unused/1, unused/2, null, callable, args[oparg] -- res)) { + assert(kwnames == NULL); + assert(oparg == 1); + DEOPT_IF(null != NULL, CALL); + PyObject *obj = args[0]; + DEOPT_IF(callable != (PyObject *)&PyType_Type, CALL); + STAT_INC(CALL, hit); + res = Py_NewRef(Py_TYPE(obj)); + Py_DECREF(obj); + Py_DECREF(&PyType_Type); // I.e., callable + } + + inst(CALL_NO_KW_STR_1, (unused/1, unused/2, null, callable, args[oparg] -- res)) { + assert(kwnames == NULL); + assert(oparg == 1); + DEOPT_IF(null != NULL, CALL); + DEOPT_IF(callable != (PyObject *)&PyUnicode_Type, CALL); + STAT_INC(CALL, hit); + PyObject *arg = args[0]; + res = PyObject_Str(arg); + Py_DECREF(arg); + Py_DECREF(&PyUnicode_Type); // I.e., callable + ERROR_IF(res == NULL, error); + CHECK_EVAL_BREAKER(); + } + + inst(CALL_NO_KW_TUPLE_1, (unused/1, unused/2, null, callable, args[oparg] -- res)) { + assert(kwnames == NULL); + assert(oparg == 1); + DEOPT_IF(null != NULL, CALL); + DEOPT_IF(callable != (PyObject *)&PyTuple_Type, CALL); + STAT_INC(CALL, hit); + PyObject *arg = args[0]; + res = PySequence_Tuple(arg); + Py_DECREF(arg); + Py_DECREF(&PyTuple_Type); // I.e., tuple + ERROR_IF(res == NULL, error); + CHECK_EVAL_BREAKER(); + } + + inst(CALL_BUILTIN_CLASS, (unused/1, unused/2, method, callable, args[oparg] -- res)) { + int is_meth = method != NULL; + int total_args = oparg; + if (is_meth) { + callable = method; + args--; + total_args++; + } + int kwnames_len = KWNAMES_LEN(); + DEOPT_IF(!PyType_Check(callable), CALL); + PyTypeObject *tp = (PyTypeObject *)callable; + DEOPT_IF(tp->tp_vectorcall == NULL, CALL); + STAT_INC(CALL, hit); + res = tp->tp_vectorcall((PyObject *)tp, args, + total_args - kwnames_len, kwnames); + kwnames = NULL; + /* Free the arguments. */ + for (int i = 0; i < total_args; i++) { + Py_DECREF(args[i]); + } + Py_DECREF(tp); + ERROR_IF(res == NULL, error); + CHECK_EVAL_BREAKER(); + } + + inst(CALL_NO_KW_BUILTIN_O, (unused/1, unused/2, method, callable, args[oparg] -- res)) { + /* Builtin METH_O functions */ + assert(kwnames == NULL); + int is_meth = method != NULL; + int total_args = oparg; + if (is_meth) { + callable = method; + args--; + total_args++; + } + DEOPT_IF(total_args != 1, CALL); + DEOPT_IF(!PyCFunction_CheckExact(callable), CALL); + DEOPT_IF(PyCFunction_GET_FLAGS(callable) != METH_O, CALL); + STAT_INC(CALL, hit); + PyCFunction cfunc = PyCFunction_GET_FUNCTION(callable); + // This is slower but CPython promises to check all non-vectorcall + // function calls. + if (_Py_EnterRecursiveCallTstate(tstate, " while calling a Python object")) { + goto error; + } + PyObject *arg = args[0]; + res = _PyCFunction_TrampolineCall(cfunc, PyCFunction_GET_SELF(callable), arg); + _Py_LeaveRecursiveCallTstate(tstate); + assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); + + Py_DECREF(arg); + Py_DECREF(callable); + ERROR_IF(res == NULL, error); + CHECK_EVAL_BREAKER(); + } + + inst(CALL_NO_KW_BUILTIN_FAST, (unused/1, unused/2, method, callable, args[oparg] -- res)) { + /* Builtin METH_FASTCALL functions, without keywords */ + assert(kwnames == NULL); + int is_meth = method != NULL; + int total_args = oparg; + if (is_meth) { + callable = method; + args--; + total_args++; + } + DEOPT_IF(!PyCFunction_CheckExact(callable), CALL); + DEOPT_IF(PyCFunction_GET_FLAGS(callable) != METH_FASTCALL, CALL); + STAT_INC(CALL, hit); + PyCFunction cfunc = PyCFunction_GET_FUNCTION(callable); + /* res = func(self, args, nargs) */ + res = ((_PyCFunctionFast)(void(*)(void))cfunc)( + PyCFunction_GET_SELF(callable), + args, + total_args); + assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); + + /* Free the arguments. */ + for (int i = 0; i < total_args; i++) { + Py_DECREF(args[i]); + } + Py_DECREF(callable); + ERROR_IF(res == NULL, error); + /* Not deopting because this doesn't mean our optimization was + wrong. `res` can be NULL for valid reasons. Eg. getattr(x, + 'invalid'). In those cases an exception is set, so we must + handle it. + */ + CHECK_EVAL_BREAKER(); + } + + inst(CALL_BUILTIN_FAST_WITH_KEYWORDS, (unused/1, unused/2, method, callable, args[oparg] -- res)) { + /* Builtin METH_FASTCALL | METH_KEYWORDS functions */ + int is_meth = method != NULL; + int total_args = oparg; + if (is_meth) { + callable = method; + args--; + total_args++; + } + DEOPT_IF(!PyCFunction_CheckExact(callable), CALL); + DEOPT_IF(PyCFunction_GET_FLAGS(callable) != + (METH_FASTCALL | METH_KEYWORDS), CALL); + STAT_INC(CALL, hit); + /* res = func(self, args, nargs, kwnames) */ + _PyCFunctionFastWithKeywords cfunc = + (_PyCFunctionFastWithKeywords)(void(*)(void)) + PyCFunction_GET_FUNCTION(callable); + res = cfunc( + PyCFunction_GET_SELF(callable), + args, + total_args - KWNAMES_LEN(), + kwnames + ); + assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); + kwnames = NULL; + + /* Free the arguments. */ + for (int i = 0; i < total_args; i++) { + Py_DECREF(args[i]); + } + Py_DECREF(callable); + ERROR_IF(res == NULL, error); + CHECK_EVAL_BREAKER(); + } + + inst(CALL_NO_KW_LEN, (unused/1, unused/2, method, callable, args[oparg] -- res)) { + assert(kwnames == NULL); + /* len(o) */ + int is_meth = method != NULL; + int total_args = oparg; + if (is_meth) { + callable = method; + args--; + total_args++; + } + DEOPT_IF(total_args != 1, CALL); + PyInterpreterState *interp = _PyInterpreterState_GET(); + DEOPT_IF(callable != interp->callable_cache.len, CALL); + STAT_INC(CALL, hit); + PyObject *arg = args[0]; + Py_ssize_t len_i = PyObject_Length(arg); + if (len_i < 0) { + goto error; + } + res = PyLong_FromSsize_t(len_i); + assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); + + Py_DECREF(callable); + Py_DECREF(arg); + ERROR_IF(res == NULL, error); + } + + inst(CALL_NO_KW_ISINSTANCE, (unused/1, unused/2, method, callable, args[oparg] -- res)) { + assert(kwnames == NULL); + /* isinstance(o, o2) */ + int is_meth = method != NULL; + int total_args = oparg; + if (is_meth) { + callable = method; + args--; + total_args++; + } + DEOPT_IF(total_args != 2, CALL); + PyInterpreterState *interp = _PyInterpreterState_GET(); + DEOPT_IF(callable != interp->callable_cache.isinstance, CALL); + STAT_INC(CALL, hit); + PyObject *cls = args[1]; + PyObject *inst = args[0]; + int retval = PyObject_IsInstance(inst, cls); + if (retval < 0) { + goto error; + } + res = PyBool_FromLong(retval); + assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); + + Py_DECREF(inst); + Py_DECREF(cls); + Py_DECREF(callable); + ERROR_IF(res == NULL, error); + } + + // This is secretly a super-instruction + inst(CALL_NO_KW_LIST_APPEND, (unused/1, unused/2, method, self, args[oparg] -- unused)) { + assert(kwnames == NULL); + assert(oparg == 1); + PyInterpreterState *interp = _PyInterpreterState_GET(); + DEOPT_IF(method != interp->callable_cache.list_append, CALL); + assert(self != NULL); + DEOPT_IF(!PyList_Check(self), CALL); + STAT_INC(CALL, hit); + if (_PyList_AppendTakeRef((PyListObject *)self, args[0]) < 0) { + goto pop_1_error; // Since arg is DECREF'ed already + } + Py_DECREF(self); + Py_DECREF(method); + STACK_SHRINK(3); + // CALL + POP_TOP + JUMPBY(INLINE_CACHE_ENTRIES_CALL + 1); + assert(next_instr[-1].op.code == POP_TOP); + DISPATCH(); + } + + inst(CALL_NO_KW_METHOD_DESCRIPTOR_O, (unused/1, unused/2, method, unused, args[oparg] -- res)) { + assert(kwnames == NULL); + int is_meth = method != NULL; + int total_args = oparg; + if (is_meth) { + args--; + total_args++; + } + PyMethodDescrObject *callable = + (PyMethodDescrObject *)PEEK(total_args + 1); + DEOPT_IF(total_args != 2, CALL); + DEOPT_IF(!Py_IS_TYPE(callable, &PyMethodDescr_Type), CALL); + PyMethodDef *meth = callable->d_method; + DEOPT_IF(meth->ml_flags != METH_O, CALL); + PyObject *arg = args[1]; + PyObject *self = args[0]; + DEOPT_IF(!Py_IS_TYPE(self, callable->d_common.d_type), CALL); + STAT_INC(CALL, hit); + PyCFunction cfunc = meth->ml_meth; + // This is slower but CPython promises to check all non-vectorcall + // function calls. + if (_Py_EnterRecursiveCallTstate(tstate, " while calling a Python object")) { + goto error; + } + res = _PyCFunction_TrampolineCall(cfunc, self, arg); + _Py_LeaveRecursiveCallTstate(tstate); + assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); + Py_DECREF(self); + Py_DECREF(arg); + Py_DECREF(callable); + ERROR_IF(res == NULL, error); + CHECK_EVAL_BREAKER(); + } + + inst(CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS, (unused/1, unused/2, method, unused, args[oparg] -- res)) { + int is_meth = method != NULL; + int total_args = oparg; + if (is_meth) { + args--; + total_args++; + } + PyMethodDescrObject *callable = + (PyMethodDescrObject *)PEEK(total_args + 1); + DEOPT_IF(!Py_IS_TYPE(callable, &PyMethodDescr_Type), CALL); + PyMethodDef *meth = callable->d_method; + DEOPT_IF(meth->ml_flags != (METH_FASTCALL|METH_KEYWORDS), CALL); + PyTypeObject *d_type = callable->d_common.d_type; + PyObject *self = args[0]; + DEOPT_IF(!Py_IS_TYPE(self, d_type), CALL); + STAT_INC(CALL, hit); + int nargs = total_args - 1; + _PyCFunctionFastWithKeywords cfunc = + (_PyCFunctionFastWithKeywords)(void(*)(void))meth->ml_meth; + res = cfunc(self, args + 1, nargs - KWNAMES_LEN(), kwnames); + assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); + kwnames = NULL; + + /* Free the arguments. */ + for (int i = 0; i < total_args; i++) { + Py_DECREF(args[i]); + } + Py_DECREF(callable); + ERROR_IF(res == NULL, error); + CHECK_EVAL_BREAKER(); + } + + inst(CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS, (unused/1, unused/2, method, unused, args[oparg] -- res)) { + assert(kwnames == NULL); + assert(oparg == 0 || oparg == 1); + int is_meth = method != NULL; + int total_args = oparg; + if (is_meth) { + args--; + total_args++; + } + DEOPT_IF(total_args != 1, CALL); + PyMethodDescrObject *callable = (PyMethodDescrObject *)SECOND(); + DEOPT_IF(!Py_IS_TYPE(callable, &PyMethodDescr_Type), CALL); + PyMethodDef *meth = callable->d_method; + PyObject *self = args[0]; + DEOPT_IF(!Py_IS_TYPE(self, callable->d_common.d_type), CALL); + DEOPT_IF(meth->ml_flags != METH_NOARGS, CALL); + STAT_INC(CALL, hit); + PyCFunction cfunc = meth->ml_meth; + // This is slower but CPython promises to check all non-vectorcall + // function calls. + if (_Py_EnterRecursiveCallTstate(tstate, " while calling a Python object")) { + goto error; + } + res = _PyCFunction_TrampolineCall(cfunc, self, NULL); + _Py_LeaveRecursiveCallTstate(tstate); + assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); + Py_DECREF(self); + Py_DECREF(callable); + ERROR_IF(res == NULL, error); + CHECK_EVAL_BREAKER(); + } + + inst(CALL_NO_KW_METHOD_DESCRIPTOR_FAST, (unused/1, unused/2, method, unused, args[oparg] -- res)) { + assert(kwnames == NULL); + int is_meth = method != NULL; + int total_args = oparg; + if (is_meth) { + args--; + total_args++; + } + PyMethodDescrObject *callable = + (PyMethodDescrObject *)PEEK(total_args + 1); + /* Builtin METH_FASTCALL methods, without keywords */ + DEOPT_IF(!Py_IS_TYPE(callable, &PyMethodDescr_Type), CALL); + PyMethodDef *meth = callable->d_method; + DEOPT_IF(meth->ml_flags != METH_FASTCALL, CALL); + PyObject *self = args[0]; + DEOPT_IF(!Py_IS_TYPE(self, callable->d_common.d_type), CALL); + STAT_INC(CALL, hit); + _PyCFunctionFast cfunc = + (_PyCFunctionFast)(void(*)(void))meth->ml_meth; + int nargs = total_args - 1; + res = cfunc(self, args + 1, nargs); + assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); + /* Clear the stack of the arguments. */ + for (int i = 0; i < total_args; i++) { + Py_DECREF(args[i]); + } + Py_DECREF(callable); + ERROR_IF(res == NULL, error); + CHECK_EVAL_BREAKER(); + } + + inst(INSTRUMENTED_CALL_FUNCTION_EX, ( -- )) { + GO_TO_INSTRUCTION(CALL_FUNCTION_EX); + } + + inst(CALL_FUNCTION_EX, (unused, func, callargs, kwargs if (oparg & 1) -- result)) { + // DICT_MERGE is called before this opcode if there are kwargs. + // It converts all dict subtypes in kwargs into regular dicts. + assert(kwargs == NULL || PyDict_CheckExact(kwargs)); + if (!PyTuple_CheckExact(callargs)) { + if (check_args_iterable(tstate, func, callargs) < 0) { + goto error; + } + PyObject *tuple = PySequence_Tuple(callargs); + if (tuple == NULL) { + goto error; + } + Py_SETREF(callargs, tuple); + } + assert(PyTuple_CheckExact(callargs)); + EVAL_CALL_STAT_INC_IF_FUNCTION(EVAL_CALL_FUNCTION_EX, func); + if (opcode == INSTRUMENTED_CALL_FUNCTION_EX && + !PyFunction_Check(func) && !PyMethod_Check(func) + ) { + PyObject *arg = PyTuple_GET_SIZE(callargs) > 0 ? + PyTuple_GET_ITEM(callargs, 0) : Py_None; + int err = _Py_call_instrumentation_2args( + tstate, PY_MONITORING_EVENT_CALL, + frame, next_instr-1, func, arg); + if (err) goto error; + result = PyObject_Call(func, callargs, kwargs); + if (result == NULL) { + _Py_call_instrumentation_exc2( + tstate, PY_MONITORING_EVENT_C_RAISE, + frame, next_instr-1, func, arg); + } + else { + int err = _Py_call_instrumentation_2args( + tstate, PY_MONITORING_EVENT_C_RETURN, + frame, next_instr-1, func, arg); + if (err < 0) { + Py_CLEAR(result); + } + } + } + else { + if (Py_TYPE(func) == &PyFunction_Type && + tstate->interp->eval_frame == NULL && + ((PyFunctionObject *)func)->vectorcall == _PyFunction_Vectorcall) { + assert(PyTuple_CheckExact(callargs)); + Py_ssize_t nargs = PyTuple_GET_SIZE(callargs); + int code_flags = ((PyCodeObject *)PyFunction_GET_CODE(func))->co_flags; + PyObject *locals = code_flags & CO_OPTIMIZED ? NULL : Py_NewRef(PyFunction_GET_GLOBALS(func)); + + _PyInterpreterFrame *new_frame = _PyEvalFramePushAndInit_Ex(tstate, + (PyFunctionObject *)func, locals, + nargs, callargs, kwargs); + // Need to manually shrink the stack since we exit with DISPATCH_INLINED. + STACK_SHRINK(oparg + 3); + if (new_frame == NULL) { + goto error; + } + frame->return_offset = 0; + DISPATCH_INLINED(new_frame); + } + result = PyObject_Call(func, callargs, kwargs); + } + DECREF_INPUTS(); + assert(PEEK(3 + (oparg & 1)) == NULL); + ERROR_IF(result == NULL, error); + CHECK_EVAL_BREAKER(); + } + + inst(MAKE_FUNCTION, (defaults if (oparg & 0x01), + kwdefaults if (oparg & 0x02), + annotations if (oparg & 0x04), + closure if (oparg & 0x08), + codeobj -- func)) { + + PyFunctionObject *func_obj = (PyFunctionObject *) + PyFunction_New(codeobj, GLOBALS()); + + Py_DECREF(codeobj); + if (func_obj == NULL) { + goto error; + } + + if (oparg & 0x08) { + assert(PyTuple_CheckExact(closure)); + func_obj->func_closure = closure; + } + if (oparg & 0x04) { + assert(PyTuple_CheckExact(annotations)); + func_obj->func_annotations = annotations; + } + if (oparg & 0x02) { + assert(PyDict_CheckExact(kwdefaults)); + func_obj->func_kwdefaults = kwdefaults; + } + if (oparg & 0x01) { + assert(PyTuple_CheckExact(defaults)); + func_obj->func_defaults = defaults; + } + + func_obj->func_version = ((PyCodeObject *)codeobj)->co_version; + func = (PyObject *)func_obj; + } + + inst(RETURN_GENERATOR, (--)) { + assert(PyFunction_Check(frame->f_funcobj)); + PyFunctionObject *func = (PyFunctionObject *)frame->f_funcobj; + PyGenObject *gen = (PyGenObject *)_Py_MakeCoro(func); + if (gen == NULL) { + goto error; + } + assert(EMPTY()); + _PyFrame_SetStackPointer(frame, stack_pointer); + _PyInterpreterFrame *gen_frame = (_PyInterpreterFrame *)gen->gi_iframe; + _PyFrame_Copy(frame, gen_frame); + assert(frame->frame_obj == NULL); + gen->gi_frame_state = FRAME_CREATED; + gen_frame->owner = FRAME_OWNED_BY_GENERATOR; + _Py_LeaveRecursiveCallPy(tstate); + assert(frame != &entry_frame); + _PyInterpreterFrame *prev = frame->previous; + _PyThreadState_PopFrame(tstate, frame); + frame = cframe.current_frame = prev; + _PyFrame_StackPush(frame, (PyObject *)gen); + goto resume_frame; + } + + inst(BUILD_SLICE, (start, stop, step if (oparg == 3) -- slice)) { + slice = PySlice_New(start, stop, step); + DECREF_INPUTS(); + ERROR_IF(slice == NULL, error); + } + + inst(FORMAT_VALUE, (value, fmt_spec if ((oparg & FVS_MASK) == FVS_HAVE_SPEC) -- result)) { + /* Handles f-string value formatting. */ + PyObject *(*conv_fn)(PyObject *); + int which_conversion = oparg & FVC_MASK; + + /* See if any conversion is specified. */ + switch (which_conversion) { + case FVC_NONE: conv_fn = NULL; break; + case FVC_STR: conv_fn = PyObject_Str; break; + case FVC_REPR: conv_fn = PyObject_Repr; break; + case FVC_ASCII: conv_fn = PyObject_ASCII; break; + default: + _PyErr_Format(tstate, PyExc_SystemError, + "unexpected conversion flag %d", + which_conversion); + goto error; + } + + /* If there's a conversion function, call it and replace + value with that result. Otherwise, just use value, + without conversion. */ + if (conv_fn != NULL) { + result = conv_fn(value); + Py_DECREF(value); + if (result == NULL) { + Py_XDECREF(fmt_spec); + ERROR_IF(true, error); + } + value = result; + } + + result = PyObject_Format(value, fmt_spec); + Py_DECREF(value); + Py_XDECREF(fmt_spec); + ERROR_IF(result == NULL, error); + } + + inst(COPY, (bottom, unused[oparg-1] -- bottom, unused[oparg-1], top)) { + assert(oparg > 0); + top = Py_NewRef(bottom); + } + + inst(BINARY_OP, (unused/1, lhs, rhs -- res)) { + #if ENABLE_SPECIALIZATION + _PyBinaryOpCache *cache = (_PyBinaryOpCache *)next_instr; + if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { + next_instr--; + _Py_Specialize_BinaryOp(lhs, rhs, next_instr, oparg, &GETLOCAL(0)); + DISPATCH_SAME_OPARG(); + } + STAT_INC(BINARY_OP, deferred); + DECREMENT_ADAPTIVE_COUNTER(cache->counter); + #endif /* ENABLE_SPECIALIZATION */ + assert(0 <= oparg); + assert((unsigned)oparg < Py_ARRAY_LENGTH(binary_ops)); + assert(binary_ops[oparg]); + res = binary_ops[oparg](lhs, rhs); + DECREF_INPUTS(); + ERROR_IF(res == NULL, error); + } + + inst(SWAP, (bottom, unused[oparg-2], top -- + top, unused[oparg-2], bottom)) { + assert(oparg >= 2); + } + + inst(INSTRUMENTED_INSTRUCTION, ( -- )) { + int next_opcode = _Py_call_instrumentation_instruction( + tstate, frame, next_instr-1); + ERROR_IF(next_opcode < 0, error); + next_instr--; + if (_PyOpcode_Caches[next_opcode]) { + _PyBinaryOpCache *cache = (_PyBinaryOpCache *)(next_instr+1); + INCREMENT_ADAPTIVE_COUNTER(cache->counter); + } + assert(next_opcode > 0 && next_opcode < 256); + opcode = next_opcode; + DISPATCH_GOTO(); + } + + inst(INSTRUMENTED_JUMP_FORWARD, ( -- )) { + INSTRUMENTED_JUMP(next_instr-1, next_instr+oparg, PY_MONITORING_EVENT_JUMP); + } + + inst(INSTRUMENTED_JUMP_BACKWARD, ( -- )) { + INSTRUMENTED_JUMP(next_instr-1, next_instr-oparg, PY_MONITORING_EVENT_JUMP); + CHECK_EVAL_BREAKER(); + } + + inst(INSTRUMENTED_POP_JUMP_IF_TRUE, ( -- )) { + PyObject *cond = POP(); + int err = PyObject_IsTrue(cond); + Py_DECREF(cond); + ERROR_IF(err < 0, error); + _Py_CODEUNIT *here = next_instr-1; + assert(err == 0 || err == 1); + int offset = err*oparg; + INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH); + } + + inst(INSTRUMENTED_POP_JUMP_IF_FALSE, ( -- )) { + PyObject *cond = POP(); + int err = PyObject_IsTrue(cond); + Py_DECREF(cond); + ERROR_IF(err < 0, error); + _Py_CODEUNIT *here = next_instr-1; + assert(err == 0 || err == 1); + int offset = (1-err)*oparg; + INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH); + } + + inst(INSTRUMENTED_POP_JUMP_IF_NONE, ( -- )) { + PyObject *value = POP(); + _Py_CODEUNIT *here = next_instr-1; + int offset; + if (Py_IsNone(value)) { + offset = oparg; + } + else { + Py_DECREF(value); + offset = 0; + } + INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH); + } + + inst(INSTRUMENTED_POP_JUMP_IF_NOT_NONE, ( -- )) { + PyObject *value = POP(); + _Py_CODEUNIT *here = next_instr-1; + int offset; + if (Py_IsNone(value)) { + offset = 0; + } + else { + Py_DECREF(value); + offset = oparg; + } + INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH); + } + + inst(EXTENDED_ARG, ( -- )) { + assert(oparg); + opcode = next_instr->op.code; + oparg = oparg << 8 | next_instr->op.arg; + PRE_DISPATCH_GOTO(); + DISPATCH_GOTO(); + } + + inst(CACHE, (--)) { + assert(0 && "Executing a cache."); + Py_UNREACHABLE(); + } + + inst(RESERVED, (--)) { + assert(0 && "Executing RESERVED instruction."); + Py_UNREACHABLE(); + } + + +// END BYTECODES // + + } + dispatch_opcode: + error: + exception_unwind: + exit_unwind: + handle_eval_breaker: + resume_frame: + resume_with_error: + start_frame: + unbound_local_error: + ; +} + +// Future families go below this point // + +family(store_fast) = { STORE_FAST, STORE_FAST__LOAD_FAST, STORE_FAST__STORE_FAST }; diff --git a/Python/ceval.c b/Python/ceval.c index 01ac2618..fdb5b72e 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -1,9 +1,6 @@ /* Execute compiled code */ -/* XXX TO DO: - XXX speed up searching for keywords by using a dictionary - XXX document it! - */ +#define _PY_INTERPRETER #include "Python.h" #include "pycore_abstract.h" // _PyIndex_Check() @@ -11,22 +8,26 @@ #include "pycore_ceval.h" // _PyEval_SignalAsyncExc() #include "pycore_code.h" #include "pycore_function.h" -#include "pycore_initconfig.h" // _PyStatus_OK() +#include "pycore_intrinsics.h" #include "pycore_long.h" // _PyLong_GetZero() +#include "pycore_instruments.h" #include "pycore_object.h" // _PyObject_GC_TRACK() #include "pycore_moduleobject.h" // PyModuleObject #include "pycore_opcode.h" // EXTRA_CASES -#include "pycore_pyerrors.h" // _PyErr_Fetch() -#include "pycore_pylifecycle.h" // _PyErr_Print() +#include "pycore_pyerrors.h" // _PyErr_GetRaisedException() #include "pycore_pymem.h" // _PyMem_IsPtrFreed() #include "pycore_pystate.h" // _PyInterpreterState_GET() +#include "pycore_range.h" // _PyRangeIterObject +#include "pycore_sliceobject.h" // _PyBuildSlice_ConsumeRefs #include "pycore_sysmodule.h" // _PySys_Audit() #include "pycore_tuple.h" // _PyTuple_ITEMS() +#include "pycore_typeobject.h" // _PySuper_Lookup() #include "pycore_emscripten_signal.h" // _Py_CHECK_EMSCRIPTEN_SIGNALS #include "pycore_dict.h" #include "dictobject.h" #include "pycore_frame.h" +#include "frameobject.h" // _PyInterpreterFrame_GetLine #include "opcode.h" #include "pydtrace.h" #include "setobject.h" @@ -55,6 +56,10 @@ #define Py_DECREF(arg) \ do { \ PyObject *op = _PyObject_CAST(arg); \ + if (_Py_IsImmortal(op)) { \ + break; \ + } \ + _Py_DECREF_STAT_INC(); \ if (--op->ob_refcnt == 0) { \ destructor dealloc = Py_TYPE(op)->tp_dealloc; \ (*dealloc)(op); \ @@ -78,6 +83,10 @@ #define _Py_DECREF_SPECIALIZED(arg, dealloc) \ do { \ PyObject *op = _PyObject_CAST(arg); \ + if (_Py_IsImmortal(op)) { \ + break; \ + } \ + _Py_DECREF_STAT_INC(); \ if (--op->ob_refcnt == 0) { \ destructor d = (destructor)(dealloc); \ d(op); \ @@ -93,21 +102,12 @@ #endif -/* Forward declarations */ -static PyObject *trace_call_function( - PyThreadState *tstate, PyObject *callable, PyObject **stack, - Py_ssize_t oparg, PyObject *kwnames); -static PyObject * do_call_core( - PyThreadState *tstate, PyObject *func, - PyObject *callargs, PyObject *kwdict, int use_tracing); - #ifdef LLTRACE static void dump_stack(_PyInterpreterFrame *frame, PyObject **stack_pointer) { PyObject **stack_base = _PyFrame_Stackbase(frame); - PyObject *type, *value, *traceback; - PyErr_Fetch(&type, &value, &traceback); + PyObject *exc = PyErr_GetRaisedException(); printf(" stack=["); for (PyObject **ptr = stack_base; ptr < stack_pointer; ptr++) { if (ptr != stack_base) { @@ -121,7 +121,7 @@ dump_stack(_PyInterpreterFrame *frame, PyObject **stack_pointer) } printf("]\n"); fflush(stdout); - PyErr_Restore(type, value, traceback); + PyErr_SetRaisedException(exc); } static void @@ -129,13 +129,16 @@ lltrace_instruction(_PyInterpreterFrame *frame, PyObject **stack_pointer, _Py_CODEUNIT *next_instr) { + /* This dump_stack() operation is risky, since the repr() of some + objects enters the interpreter recursively. It is also slow. + So you might want to comment it out. */ dump_stack(frame, stack_pointer); - int oparg = _Py_OPARG(*next_instr); - int opcode = _Py_OPCODE(*next_instr); + int oparg = next_instr->op.arg; + int opcode = next_instr->op.code; const char *opname = _PyOpcode_OpName[opcode]; assert(opname != NULL); int offset = (int)(next_instr - _PyCode_CODE(frame->f_code)); - if (HAS_ARG(opcode)) { + if (HAS_ARG((int)_PyOpcode_Deopt[opcode])) { printf("%d: %s %d\n", offset * 2, opname, oparg); } else { @@ -146,13 +149,16 @@ lltrace_instruction(_PyInterpreterFrame *frame, static void lltrace_resume_frame(_PyInterpreterFrame *frame) { - PyFunctionObject *f = frame->f_func; - if (f == NULL) { - printf("\nResuming frame."); + PyObject *fobj = frame->f_funcobj; + if (frame->owner == FRAME_OWNED_BY_CSTACK || + fobj == NULL || + !PyFunction_Check(fobj) + ) { + printf("\nResuming frame.\n"); return; } - PyObject *type, *value, *traceback; - PyErr_Fetch(&type, &value, &traceback); + PyFunctionObject *f = (PyFunctionObject *)fobj; + PyObject *exc = PyErr_GetRaisedException(); PyObject *name = f->func_qualname; if (name == NULL) { name = f->func_name; @@ -172,27 +178,32 @@ lltrace_resume_frame(_PyInterpreterFrame *frame) } printf("\n"); fflush(stdout); - PyErr_Restore(type, value, traceback); + PyErr_SetRaisedException(exc); } #endif -static int call_trace(Py_tracefunc, PyObject *, - PyThreadState *, _PyInterpreterFrame *, - int, PyObject *); -static int call_trace_protected(Py_tracefunc, PyObject *, - PyThreadState *, _PyInterpreterFrame *, - int, PyObject *); -static void call_exc_trace(Py_tracefunc, PyObject *, - PyThreadState *, _PyInterpreterFrame *); -static int maybe_call_line_trace(Py_tracefunc, PyObject *, - PyThreadState *, _PyInterpreterFrame *, int); -static void maybe_dtrace_line(_PyInterpreterFrame *, PyTraceInfo *, int); -static void dtrace_function_entry(_PyInterpreterFrame *); -static void dtrace_function_return(_PyInterpreterFrame *); + +static void monitor_raise(PyThreadState *tstate, + _PyInterpreterFrame *frame, + _Py_CODEUNIT *instr); +static void monitor_reraise(PyThreadState *tstate, + _PyInterpreterFrame *frame, + _Py_CODEUNIT *instr); +static int monitor_stop_iteration(PyThreadState *tstate, + _PyInterpreterFrame *frame, + _Py_CODEUNIT *instr); +static void monitor_unwind(PyThreadState *tstate, + _PyInterpreterFrame *frame, + _Py_CODEUNIT *instr); +static int monitor_handled(PyThreadState *tstate, + _PyInterpreterFrame *frame, + _Py_CODEUNIT *instr, PyObject *exc); +static void monitor_throw(PyThreadState *tstate, + _PyInterpreterFrame *frame, + _Py_CODEUNIT *instr); static PyObject * import_name(PyThreadState *, _PyInterpreterFrame *, PyObject *, PyObject *, PyObject *); static PyObject * import_from(PyThreadState *, PyObject *, PyObject *); -static int import_all_from(PyThreadState *, PyObject *, PyObject *); static void format_exc_check_arg(PyThreadState *, PyObject *, const char *, PyObject *); static void format_exc_unbound(PyThreadState *tstate, PyCodeObject *co, int oparg); static int check_args_iterable(PyThreadState *, PyObject *func, PyObject *vararg); @@ -205,5478 +216,663 @@ static _PyInterpreterFrame * _PyEvalFramePushAndInit(PyThreadState *tstate, PyFunctionObject *func, PyObject *locals, PyObject* const* args, size_t argcount, PyObject *kwnames); +static _PyInterpreterFrame * +_PyEvalFramePushAndInit_Ex(PyThreadState *tstate, PyFunctionObject *func, + PyObject *locals, Py_ssize_t nargs, PyObject *callargs, PyObject *kwargs); static void _PyEvalFrameClearAndPop(PyThreadState *tstate, _PyInterpreterFrame *frame); -#define NAME_ERROR_MSG \ - "name '%.200s' is not defined" #define UNBOUNDLOCAL_ERROR_MSG \ "cannot access local variable '%s' where it is not associated with a value" #define UNBOUNDFREE_ERROR_MSG \ "cannot access free variable '%s' where it is not associated with a" \ " value in enclosing scope" -#ifndef NDEBUG -/* Ensure that tstate is valid: sanity check for PyEval_AcquireThread() and - PyEval_RestoreThread(). Detect if tstate memory was freed. It can happen - when a thread continues to run after Python finalization, especially - daemon threads. */ -static int -is_tstate_valid(PyThreadState *tstate) -{ - assert(!_PyMem_IsPtrFreed(tstate)); - assert(!_PyMem_IsPtrFreed(tstate->interp)); - return 1; -} -#endif - - -/* This can set eval_breaker to 0 even though gil_drop_request became - 1. We believe this is all right because the eval loop will release - the GIL eventually anyway. */ -static inline void -COMPUTE_EVAL_BREAKER(PyInterpreterState *interp, - struct _ceval_runtime_state *ceval, - struct _ceval_state *ceval2) -{ - _Py_atomic_store_relaxed(&ceval2->eval_breaker, - _Py_atomic_load_relaxed_int32(&ceval2->gil_drop_request) - | (_Py_atomic_load_relaxed_int32(&ceval->signals_pending) - && _Py_ThreadCanHandleSignals(interp)) - | (_Py_atomic_load_relaxed_int32(&ceval2->pending.calls_to_do) - && _Py_ThreadCanHandlePendingCalls()) - | ceval2->pending.async_exc); -} - - -static inline void -SET_GIL_DROP_REQUEST(PyInterpreterState *interp) -{ - struct _ceval_state *ceval2 = &interp->ceval; - _Py_atomic_store_relaxed(&ceval2->gil_drop_request, 1); - _Py_atomic_store_relaxed(&ceval2->eval_breaker, 1); -} - - -static inline void -RESET_GIL_DROP_REQUEST(PyInterpreterState *interp) -{ - struct _ceval_runtime_state *ceval = &interp->runtime->ceval; - struct _ceval_state *ceval2 = &interp->ceval; - _Py_atomic_store_relaxed(&ceval2->gil_drop_request, 0); - COMPUTE_EVAL_BREAKER(interp, ceval, ceval2); -} - - -static inline void -SIGNAL_PENDING_CALLS(PyInterpreterState *interp) -{ - struct _ceval_runtime_state *ceval = &interp->runtime->ceval; - struct _ceval_state *ceval2 = &interp->ceval; - _Py_atomic_store_relaxed(&ceval2->pending.calls_to_do, 1); - COMPUTE_EVAL_BREAKER(interp, ceval, ceval2); -} - - -static inline void -UNSIGNAL_PENDING_CALLS(PyInterpreterState *interp) -{ - struct _ceval_runtime_state *ceval = &interp->runtime->ceval; - struct _ceval_state *ceval2 = &interp->ceval; - _Py_atomic_store_relaxed(&ceval2->pending.calls_to_do, 0); - COMPUTE_EVAL_BREAKER(interp, ceval, ceval2); -} - - -static inline void -SIGNAL_PENDING_SIGNALS(PyInterpreterState *interp, int force) -{ - struct _ceval_runtime_state *ceval = &interp->runtime->ceval; - struct _ceval_state *ceval2 = &interp->ceval; - _Py_atomic_store_relaxed(&ceval->signals_pending, 1); - if (force) { - _Py_atomic_store_relaxed(&ceval2->eval_breaker, 1); - } - else { - /* eval_breaker is not set to 1 if thread_can_handle_signals() is false */ - COMPUTE_EVAL_BREAKER(interp, ceval, ceval2); - } -} - - -static inline void -UNSIGNAL_PENDING_SIGNALS(PyInterpreterState *interp) -{ - struct _ceval_runtime_state *ceval = &interp->runtime->ceval; - struct _ceval_state *ceval2 = &interp->ceval; - _Py_atomic_store_relaxed(&ceval->signals_pending, 0); - COMPUTE_EVAL_BREAKER(interp, ceval, ceval2); -} - - -static inline void -SIGNAL_ASYNC_EXC(PyInterpreterState *interp) -{ - struct _ceval_state *ceval2 = &interp->ceval; - ceval2->pending.async_exc = 1; - _Py_atomic_store_relaxed(&ceval2->eval_breaker, 1); -} - - -static inline void -UNSIGNAL_ASYNC_EXC(PyInterpreterState *interp) -{ - struct _ceval_runtime_state *ceval = &interp->runtime->ceval; - struct _ceval_state *ceval2 = &interp->ceval; - ceval2->pending.async_exc = 0; - COMPUTE_EVAL_BREAKER(interp, ceval, ceval2); -} - - #ifdef HAVE_ERRNO_H #include <errno.h> #endif -#include "ceval_gil.h" - -void _Py_NO_RETURN -_Py_FatalError_TstateNULL(const char *func) -{ - _Py_FatalErrorFunc(func, - "the function must be called with the GIL held, " - "but the GIL is released " - "(the current Python thread state is NULL)"); -} - -int -_PyEval_ThreadsInitialized(_PyRuntimeState *runtime) -{ - return gil_created(&runtime->ceval.gil); -} int -PyEval_ThreadsInitialized(void) +Py_GetRecursionLimit(void) { - _PyRuntimeState *runtime = &_PyRuntime; - return _PyEval_ThreadsInitialized(runtime); + PyInterpreterState *interp = _PyInterpreterState_GET(); + return interp->ceval.recursion_limit; } -PyStatus -_PyEval_InitGIL(PyThreadState *tstate) +void +Py_SetRecursionLimit(int new_limit) { - if (!_Py_IsMainInterpreter(tstate->interp)) { - /* Currently, the GIL is shared by all interpreters, - and only the main interpreter is responsible to create - and destroy it. */ - return _PyStatus_OK(); + PyInterpreterState *interp = _PyInterpreterState_GET(); + interp->ceval.recursion_limit = new_limit; + for (PyThreadState *p = interp->threads.head; p != NULL; p = p->next) { + int depth = p->py_recursion_limit - p->py_recursion_remaining; + p->py_recursion_limit = new_limit; + p->py_recursion_remaining = new_limit - depth; } - - struct _gil_runtime_state *gil = &tstate->interp->runtime->ceval.gil; - assert(!gil_created(gil)); - - PyThread_init_thread(); - create_gil(gil); - - take_gil(tstate); - - assert(gil_created(gil)); - return _PyStatus_OK(); } -void -_PyEval_FiniGIL(PyInterpreterState *interp) +/* The function _Py_EnterRecursiveCallTstate() only calls _Py_CheckRecursiveCall() + if the recursion_depth reaches recursion_limit. */ +int +_Py_CheckRecursiveCall(PyThreadState *tstate, const char *where) { - if (!_Py_IsMainInterpreter(interp)) { - /* Currently, the GIL is shared by all interpreters, - and only the main interpreter is responsible to create - and destroy it. */ - return; +#ifdef USE_STACKCHECK + if (PyOS_CheckStack()) { + ++tstate->c_recursion_remaining; + _PyErr_SetString(tstate, PyExc_MemoryError, "Stack overflow"); + return -1; } - - struct _gil_runtime_state *gil = &interp->runtime->ceval.gil; - if (!gil_created(gil)) { - /* First Py_InitializeFromConfig() call: the GIL doesn't exist - yet: do nothing. */ - return; +#endif + if (tstate->recursion_headroom) { + if (tstate->c_recursion_remaining < -50) { + /* Overflowing while handling an overflow. Give up. */ + Py_FatalError("Cannot recover from stack overflow."); + } } - - destroy_gil(gil); - assert(!gil_created(gil)); -} - -void -PyEval_InitThreads(void) -{ - /* Do nothing: kept for backward compatibility */ + else { + if (tstate->c_recursion_remaining <= 0) { + tstate->recursion_headroom++; + _PyErr_Format(tstate, PyExc_RecursionError, + "maximum recursion depth exceeded%s", + where); + tstate->recursion_headroom--; + ++tstate->c_recursion_remaining; + return -1; + } + } + return 0; } -void -_PyEval_Fini(void) -{ -#ifdef Py_STATS - _Py_PrintSpecializationStats(1); -#endif -} -void -PyEval_AcquireLock(void) -{ - _PyRuntimeState *runtime = &_PyRuntime; - PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); - _Py_EnsureTstateNotNULL(tstate); +static const binaryfunc binary_ops[] = { + [NB_ADD] = PyNumber_Add, + [NB_AND] = PyNumber_And, + [NB_FLOOR_DIVIDE] = PyNumber_FloorDivide, + [NB_LSHIFT] = PyNumber_Lshift, + [NB_MATRIX_MULTIPLY] = PyNumber_MatrixMultiply, + [NB_MULTIPLY] = PyNumber_Multiply, + [NB_REMAINDER] = PyNumber_Remainder, + [NB_OR] = PyNumber_Or, + [NB_POWER] = _PyNumber_PowerNoMod, + [NB_RSHIFT] = PyNumber_Rshift, + [NB_SUBTRACT] = PyNumber_Subtract, + [NB_TRUE_DIVIDE] = PyNumber_TrueDivide, + [NB_XOR] = PyNumber_Xor, + [NB_INPLACE_ADD] = PyNumber_InPlaceAdd, + [NB_INPLACE_AND] = PyNumber_InPlaceAnd, + [NB_INPLACE_FLOOR_DIVIDE] = PyNumber_InPlaceFloorDivide, + [NB_INPLACE_LSHIFT] = PyNumber_InPlaceLshift, + [NB_INPLACE_MATRIX_MULTIPLY] = PyNumber_InPlaceMatrixMultiply, + [NB_INPLACE_MULTIPLY] = PyNumber_InPlaceMultiply, + [NB_INPLACE_REMAINDER] = PyNumber_InPlaceRemainder, + [NB_INPLACE_OR] = PyNumber_InPlaceOr, + [NB_INPLACE_POWER] = _PyNumber_InPlacePowerNoMod, + [NB_INPLACE_RSHIFT] = PyNumber_InPlaceRshift, + [NB_INPLACE_SUBTRACT] = PyNumber_InPlaceSubtract, + [NB_INPLACE_TRUE_DIVIDE] = PyNumber_InPlaceTrueDivide, + [NB_INPLACE_XOR] = PyNumber_InPlaceXor, +}; - take_gil(tstate); -} -void -PyEval_ReleaseLock(void) -{ - _PyRuntimeState *runtime = &_PyRuntime; - PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); - /* This function must succeed when the current thread state is NULL. - We therefore avoid PyThreadState_Get() which dumps a fatal error - in debug mode. */ - struct _ceval_runtime_state *ceval = &runtime->ceval; - struct _ceval_state *ceval2 = &tstate->interp->ceval; - drop_gil(ceval, ceval2, tstate); -} +// PEP 634: Structural Pattern Matching -void -_PyEval_ReleaseLock(PyThreadState *tstate) -{ - struct _ceval_runtime_state *ceval = &tstate->interp->runtime->ceval; - struct _ceval_state *ceval2 = &tstate->interp->ceval; - drop_gil(ceval, ceval2, tstate); -} -void -PyEval_AcquireThread(PyThreadState *tstate) +// Return a tuple of values corresponding to keys, with error checks for +// duplicate/missing keys. +static PyObject* +match_keys(PyThreadState *tstate, PyObject *map, PyObject *keys) { - _Py_EnsureTstateNotNULL(tstate); - - take_gil(tstate); - - struct _gilstate_runtime_state *gilstate = &tstate->interp->runtime->gilstate; - if (_PyThreadState_Swap(gilstate, tstate) != NULL) { - Py_FatalError("non-NULL old thread state"); + assert(PyTuple_CheckExact(keys)); + Py_ssize_t nkeys = PyTuple_GET_SIZE(keys); + if (!nkeys) { + // No keys means no items. + return PyTuple_New(0); } -} - -void -PyEval_ReleaseThread(PyThreadState *tstate) -{ - assert(is_tstate_valid(tstate)); - - _PyRuntimeState *runtime = tstate->interp->runtime; - PyThreadState *new_tstate = _PyThreadState_Swap(&runtime->gilstate, NULL); - if (new_tstate != tstate) { - Py_FatalError("wrong thread state"); + PyObject *seen = NULL; + PyObject *dummy = NULL; + PyObject *values = NULL; + PyObject *get = NULL; + // We use the two argument form of map.get(key, default) for two reasons: + // - Atomically check for a key and get its value without error handling. + // - Don't cause key creation or resizing in dict subclasses like + // collections.defaultdict that define __missing__ (or similar). + int meth_found = _PyObject_GetMethod(map, &_Py_ID(get), &get); + if (get == NULL) { + goto fail; } - struct _ceval_runtime_state *ceval = &runtime->ceval; - struct _ceval_state *ceval2 = &tstate->interp->ceval; - drop_gil(ceval, ceval2, tstate); -} - -#ifdef HAVE_FORK -/* This function is called from PyOS_AfterFork_Child to destroy all threads - which are not running in the child process, and clear internal locks - which might be held by those threads. */ -PyStatus -_PyEval_ReInitThreads(PyThreadState *tstate) -{ - _PyRuntimeState *runtime = tstate->interp->runtime; - - struct _gil_runtime_state *gil = &runtime->ceval.gil; - if (!gil_created(gil)) { - return _PyStatus_OK(); + seen = PySet_New(NULL); + if (seen == NULL) { + goto fail; } - recreate_gil(gil); - - take_gil(tstate); - - struct _pending_calls *pending = &tstate->interp->ceval.pending; - if (_PyThread_at_fork_reinit(&pending->lock) < 0) { - return _PyStatus_ERR("Can't reinitialize pending calls lock"); + // dummy = object() + dummy = _PyObject_CallNoArgs((PyObject *)&PyBaseObject_Type); + if (dummy == NULL) { + goto fail; } - - /* Destroy all threads except the current one */ - _PyThreadState_DeleteExcept(runtime, tstate); - return _PyStatus_OK(); -} -#endif - -/* This function is used to signal that async exceptions are waiting to be - raised. */ - -void -_PyEval_SignalAsyncExc(PyInterpreterState *interp) -{ - SIGNAL_ASYNC_EXC(interp); + values = PyTuple_New(nkeys); + if (values == NULL) { + goto fail; + } + for (Py_ssize_t i = 0; i < nkeys; i++) { + PyObject *key = PyTuple_GET_ITEM(keys, i); + if (PySet_Contains(seen, key) || PySet_Add(seen, key)) { + if (!_PyErr_Occurred(tstate)) { + // Seen it before! + _PyErr_Format(tstate, PyExc_ValueError, + "mapping pattern checks duplicate key (%R)", key); + } + goto fail; + } + PyObject *args[] = { map, key, dummy }; + PyObject *value = NULL; + if (meth_found) { + value = PyObject_Vectorcall(get, args, 3, NULL); + } + else { + value = PyObject_Vectorcall(get, &args[1], 2, NULL); + } + if (value == NULL) { + goto fail; + } + if (value == dummy) { + // key not in map! + Py_DECREF(value); + Py_DECREF(values); + // Return None: + values = Py_NewRef(Py_None); + goto done; + } + PyTuple_SET_ITEM(values, i, value); + } + // Success: +done: + Py_DECREF(get); + Py_DECREF(seen); + Py_DECREF(dummy); + return values; +fail: + Py_XDECREF(get); + Py_XDECREF(seen); + Py_XDECREF(dummy); + Py_XDECREF(values); + return NULL; } -PyThreadState * -PyEval_SaveThread(void) +// Extract a named attribute from the subject, with additional bookkeeping to +// raise TypeErrors for repeated lookups. On failure, return NULL (with no +// error set). Use _PyErr_Occurred(tstate) to disambiguate. +static PyObject* +match_class_attr(PyThreadState *tstate, PyObject *subject, PyObject *type, + PyObject *name, PyObject *seen) { - _PyRuntimeState *runtime = &_PyRuntime; - PyThreadState *tstate = _PyThreadState_Swap(&runtime->gilstate, NULL); - _Py_EnsureTstateNotNULL(tstate); - - struct _ceval_runtime_state *ceval = &runtime->ceval; - struct _ceval_state *ceval2 = &tstate->interp->ceval; - assert(gil_created(&ceval->gil)); - drop_gil(ceval, ceval2, tstate); - return tstate; -} - -void -PyEval_RestoreThread(PyThreadState *tstate) -{ - _Py_EnsureTstateNotNULL(tstate); - - take_gil(tstate); - - struct _gilstate_runtime_state *gilstate = &tstate->interp->runtime->gilstate; - _PyThreadState_Swap(gilstate, tstate); -} - - -/* Mechanism whereby asynchronously executing callbacks (e.g. UNIX - signal handlers or Mac I/O completion routines) can schedule calls - to a function to be called synchronously. - The synchronous function is called with one void* argument. - It should return 0 for success or -1 for failure -- failure should - be accompanied by an exception. - - If registry succeeds, the registry function returns 0; if it fails - (e.g. due to too many pending calls) it returns -1 (without setting - an exception condition). - - Note that because registry may occur from within signal handlers, - or other asynchronous events, calling malloc() is unsafe! - - Any thread can schedule pending calls, but only the main thread - will execute them. - There is no facility to schedule calls to a particular thread, but - that should be easy to change, should that ever be required. In - that case, the static variables here should go into the python - threadstate. -*/ - -void -_PyEval_SignalReceived(PyInterpreterState *interp) -{ -#ifdef MS_WINDOWS - // bpo-42296: On Windows, _PyEval_SignalReceived() is called from a signal - // handler which can run in a thread different than the Python thread, in - // which case _Py_ThreadCanHandleSignals() is wrong. Ignore - // _Py_ThreadCanHandleSignals() and always set eval_breaker to 1. - // - // The next eval_frame_handle_pending() call will call - // _Py_ThreadCanHandleSignals() to recompute eval_breaker. - int force = 1; -#else - int force = 0; -#endif - /* bpo-30703: Function called when the C signal handler of Python gets a - signal. We cannot queue a callback using _PyEval_AddPendingCall() since - that function is not async-signal-safe. */ - SIGNAL_PENDING_SIGNALS(interp, force); -} - -/* Push one item onto the queue while holding the lock. */ -static int -_push_pending_call(struct _pending_calls *pending, - int (*func)(void *), void *arg) -{ - int i = pending->last; - int j = (i + 1) % NPENDINGCALLS; - if (j == pending->first) { - return -1; /* Queue full */ - } - pending->calls[i].func = func; - pending->calls[i].arg = arg; - pending->last = j; - return 0; -} - -/* Pop one item off the queue while holding the lock. */ -static void -_pop_pending_call(struct _pending_calls *pending, - int (**func)(void *), void **arg) -{ - int i = pending->first; - if (i == pending->last) { - return; /* Queue empty */ - } - - *func = pending->calls[i].func; - *arg = pending->calls[i].arg; - pending->first = (i + 1) % NPENDINGCALLS; -} - -/* This implementation is thread-safe. It allows - scheduling to be made from any thread, and even from an executing - callback. - */ - -int -_PyEval_AddPendingCall(PyInterpreterState *interp, - int (*func)(void *), void *arg) -{ - struct _pending_calls *pending = &interp->ceval.pending; - - /* Ensure that _PyEval_InitPendingCalls() was called - and that _PyEval_FiniPendingCalls() is not called yet. */ - assert(pending->lock != NULL); - - PyThread_acquire_lock(pending->lock, WAIT_LOCK); - int result = _push_pending_call(pending, func, arg); - PyThread_release_lock(pending->lock); - - /* signal main loop */ - SIGNAL_PENDING_CALLS(interp); - return result; -} - -int -Py_AddPendingCall(int (*func)(void *), void *arg) -{ - /* Best-effort to support subinterpreters and calls with the GIL released. - - First attempt _PyThreadState_GET() since it supports subinterpreters. - - If the GIL is released, _PyThreadState_GET() returns NULL . In this - case, use PyGILState_GetThisThreadState() which works even if the GIL - is released. - - Sadly, PyGILState_GetThisThreadState() doesn't support subinterpreters: - see bpo-10915 and bpo-15751. - - Py_AddPendingCall() doesn't require the caller to hold the GIL. */ - PyThreadState *tstate = _PyThreadState_GET(); - if (tstate == NULL) { - tstate = PyGILState_GetThisThreadState(); - } - - PyInterpreterState *interp; - if (tstate != NULL) { - interp = tstate->interp; + assert(PyUnicode_CheckExact(name)); + assert(PySet_CheckExact(seen)); + if (PySet_Contains(seen, name) || PySet_Add(seen, name)) { + if (!_PyErr_Occurred(tstate)) { + // Seen it before! + _PyErr_Format(tstate, PyExc_TypeError, + "%s() got multiple sub-patterns for attribute %R", + ((PyTypeObject*)type)->tp_name, name); + } + return NULL; } - else { - /* Last resort: use the main interpreter */ - interp = _PyInterpreterState_Main(); + PyObject *attr = PyObject_GetAttr(subject, name); + if (attr == NULL && _PyErr_ExceptionMatches(tstate, PyExc_AttributeError)) { + _PyErr_Clear(tstate); } - return _PyEval_AddPendingCall(interp, func, arg); + return attr; } -static int -handle_signals(PyThreadState *tstate) +// On success (match), return a tuple of extracted attributes. On failure (no +// match), return NULL. Use _PyErr_Occurred(tstate) to disambiguate. +static PyObject* +match_class(PyThreadState *tstate, PyObject *subject, PyObject *type, + Py_ssize_t nargs, PyObject *kwargs) { - assert(is_tstate_valid(tstate)); - if (!_Py_ThreadCanHandleSignals(tstate->interp)) { - return 0; + if (!PyType_Check(type)) { + const char *e = "called match pattern must be a class"; + _PyErr_Format(tstate, PyExc_TypeError, e); + return NULL; } - - UNSIGNAL_PENDING_SIGNALS(tstate->interp); - if (_PyErr_CheckSignalsTstate(tstate) < 0) { - /* On failure, re-schedule a call to handle_signals(). */ - SIGNAL_PENDING_SIGNALS(tstate->interp, 0); - return -1; + assert(PyTuple_CheckExact(kwargs)); + // First, an isinstance check: + if (PyObject_IsInstance(subject, type) <= 0) { + return NULL; } - return 0; -} - -static int -make_pending_calls(PyInterpreterState *interp) -{ - /* only execute pending calls on main thread */ - if (!_Py_ThreadCanHandlePendingCalls()) { - return 0; + // So far so good: + PyObject *seen = PySet_New(NULL); + if (seen == NULL) { + return NULL; } - - /* don't perform recursive pending calls */ - static int busy = 0; - if (busy) { - return 0; + PyObject *attrs = PyList_New(0); + if (attrs == NULL) { + Py_DECREF(seen); + return NULL; } - busy = 1; - - /* unsignal before starting to call callbacks, so that any callback - added in-between re-signals */ - UNSIGNAL_PENDING_CALLS(interp); - int res = 0; - - /* perform a bounded number of calls, in case of recursion */ - struct _pending_calls *pending = &interp->ceval.pending; - for (int i=0; i<NPENDINGCALLS; i++) { - int (*func)(void *) = NULL; - void *arg = NULL; - - /* pop one item off the queue while holding the lock */ - PyThread_acquire_lock(pending->lock, WAIT_LOCK); - _pop_pending_call(pending, &func, &arg); - PyThread_release_lock(pending->lock); - - /* having released the lock, perform the callback */ - if (func == NULL) { - break; + // NOTE: From this point on, goto fail on failure: + PyObject *match_args = NULL; + // First, the positional subpatterns: + if (nargs) { + int match_self = 0; + match_args = PyObject_GetAttrString(type, "__match_args__"); + if (match_args) { + if (!PyTuple_CheckExact(match_args)) { + const char *e = "%s.__match_args__ must be a tuple (got %s)"; + _PyErr_Format(tstate, PyExc_TypeError, e, + ((PyTypeObject *)type)->tp_name, + Py_TYPE(match_args)->tp_name); + goto fail; + } } - res = func(arg); - if (res) { - goto error; + else if (_PyErr_ExceptionMatches(tstate, PyExc_AttributeError)) { + _PyErr_Clear(tstate); + // _Py_TPFLAGS_MATCH_SELF is only acknowledged if the type does not + // define __match_args__. This is natural behavior for subclasses: + // it's as if __match_args__ is some "magic" value that is lost as + // soon as they redefine it. + match_args = PyTuple_New(0); + match_self = PyType_HasFeature((PyTypeObject*)type, + _Py_TPFLAGS_MATCH_SELF); + } + else { + goto fail; + } + assert(PyTuple_CheckExact(match_args)); + Py_ssize_t allowed = match_self ? 1 : PyTuple_GET_SIZE(match_args); + if (allowed < nargs) { + const char *plural = (allowed == 1) ? "" : "s"; + _PyErr_Format(tstate, PyExc_TypeError, + "%s() accepts %d positional sub-pattern%s (%d given)", + ((PyTypeObject*)type)->tp_name, + allowed, plural, nargs); + goto fail; + } + if (match_self) { + // Easy. Copy the subject itself, and move on to kwargs. + PyList_Append(attrs, subject); + } + else { + for (Py_ssize_t i = 0; i < nargs; i++) { + PyObject *name = PyTuple_GET_ITEM(match_args, i); + if (!PyUnicode_CheckExact(name)) { + _PyErr_Format(tstate, PyExc_TypeError, + "__match_args__ elements must be strings " + "(got %s)", Py_TYPE(name)->tp_name); + goto fail; + } + PyObject *attr = match_class_attr(tstate, subject, type, name, + seen); + if (attr == NULL) { + goto fail; + } + PyList_Append(attrs, attr); + Py_DECREF(attr); + } } + Py_CLEAR(match_args); } - - busy = 0; - return res; - -error: - busy = 0; - SIGNAL_PENDING_CALLS(interp); - return res; + // Finally, the keyword subpatterns: + for (Py_ssize_t i = 0; i < PyTuple_GET_SIZE(kwargs); i++) { + PyObject *name = PyTuple_GET_ITEM(kwargs, i); + PyObject *attr = match_class_attr(tstate, subject, type, name, seen); + if (attr == NULL) { + goto fail; + } + PyList_Append(attrs, attr); + Py_DECREF(attr); + } + Py_SETREF(attrs, PyList_AsTuple(attrs)); + Py_DECREF(seen); + return attrs; +fail: + // We really don't care whether an error was raised or not... that's our + // caller's problem. All we know is that the match failed. + Py_XDECREF(match_args); + Py_DECREF(seen); + Py_DECREF(attrs); + return NULL; } -void -_Py_FinishPendingCalls(PyThreadState *tstate) -{ - assert(PyGILState_Check()); - assert(is_tstate_valid(tstate)); - struct _pending_calls *pending = &tstate->interp->ceval.pending; - - if (!_Py_atomic_load_relaxed_int32(&(pending->calls_to_do))) { - return; - } +static int do_raise(PyThreadState *tstate, PyObject *exc, PyObject *cause); +static int exception_group_match( + PyObject* exc_value, PyObject *match_type, + PyObject **match, PyObject **rest); - if (make_pending_calls(tstate->interp) < 0) { - PyObject *exc, *val, *tb; - _PyErr_Fetch(tstate, &exc, &val, &tb); - PyErr_BadInternalCall(); - _PyErr_ChainExceptions(exc, val, tb); - _PyErr_Print(tstate); - } -} +static int unpack_iterable(PyThreadState *, PyObject *, int, int, PyObject **); -/* Py_MakePendingCalls() is a simple wrapper for the sake - of backward-compatibility. */ -int -Py_MakePendingCalls(void) +PyObject * +PyEval_EvalCode(PyObject *co, PyObject *globals, PyObject *locals) { - assert(PyGILState_Check()); - PyThreadState *tstate = _PyThreadState_GET(); - assert(is_tstate_valid(tstate)); - - /* Python signal handler doesn't really queue a callback: it only signals - that a signal was received, see _PyEval_SignalReceived(). */ - int res = handle_signals(tstate); - if (res != 0) { - return res; + if (locals == NULL) { + locals = globals; } - - res = make_pending_calls(tstate->interp); - if (res != 0) { - return res; + PyObject *builtins = _PyEval_BuiltinsFromGlobals(tstate, globals); // borrowed ref + if (builtins == NULL) { + return NULL; } - - return 0; -} - -/* The interpreter's recursion limit */ - -void -_PyEval_InitRuntimeState(struct _ceval_runtime_state *ceval) -{ - _gil_initialize(&ceval->gil); + PyFrameConstructor desc = { + .fc_globals = globals, + .fc_builtins = builtins, + .fc_name = ((PyCodeObject *)co)->co_name, + .fc_qualname = ((PyCodeObject *)co)->co_name, + .fc_code = co, + .fc_defaults = NULL, + .fc_kwdefaults = NULL, + .fc_closure = NULL + }; + PyFunctionObject *func = _PyFunction_FromConstructor(&desc); + if (func == NULL) { + return NULL; + } + EVAL_CALL_STAT_INC(EVAL_CALL_LEGACY); + PyObject *res = _PyEval_Vector(tstate, func, locals, NULL, 0, NULL); + Py_DECREF(func); + return res; } -void -_PyEval_InitState(struct _ceval_state *ceval, PyThread_type_lock pending_lock) -{ - struct _pending_calls *pending = &ceval->pending; - assert(pending->lock == NULL); - - pending->lock = pending_lock; -} -void -_PyEval_FiniState(struct _ceval_state *ceval) -{ - struct _pending_calls *pending = &ceval->pending; - if (pending->lock != NULL) { - PyThread_free_lock(pending->lock); - pending->lock = NULL; - } -} +/* Interpreter main loop */ -int -Py_GetRecursionLimit(void) +PyObject * +PyEval_EvalFrame(PyFrameObject *f) { - PyInterpreterState *interp = _PyInterpreterState_GET(); - return interp->ceval.recursion_limit; + /* Function kept for backward compatibility */ + PyThreadState *tstate = _PyThreadState_GET(); + return _PyEval_EvalFrame(tstate, f->f_frame, 0); } -void -Py_SetRecursionLimit(int new_limit) -{ - PyInterpreterState *interp = _PyInterpreterState_GET(); - interp->ceval.recursion_limit = new_limit; - for (PyThreadState *p = interp->threads.head; p != NULL; p = p->next) { - int depth = p->recursion_limit - p->recursion_remaining; - p->recursion_limit = new_limit; - p->recursion_remaining = new_limit - depth; - } -} - -/* The function _Py_EnterRecursiveCallTstate() only calls _Py_CheckRecursiveCall() - if the recursion_depth reaches recursion_limit. */ -int -_Py_CheckRecursiveCall(PyThreadState *tstate, const char *where) -{ - /* Check against global limit first. */ - int depth = tstate->recursion_limit - tstate->recursion_remaining; - if (depth < tstate->interp->ceval.recursion_limit) { - tstate->recursion_limit = tstate->interp->ceval.recursion_limit; - tstate->recursion_remaining = tstate->recursion_limit - depth; - assert(tstate->recursion_remaining > 0); - return 0; - } -#ifdef USE_STACKCHECK - if (PyOS_CheckStack()) { - ++tstate->recursion_remaining; - _PyErr_SetString(tstate, PyExc_MemoryError, "Stack overflow"); - return -1; - } -#endif - if (tstate->recursion_headroom) { - if (tstate->recursion_remaining < -50) { - /* Overflowing while handling an overflow. Give up. */ - Py_FatalError("Cannot recover from stack overflow."); - } - } - else { - if (tstate->recursion_remaining <= 0) { - tstate->recursion_headroom++; - _PyErr_Format(tstate, PyExc_RecursionError, - "maximum recursion depth exceeded%s", - where); - tstate->recursion_headroom--; - ++tstate->recursion_remaining; - return -1; - } - } - return 0; -} - - -static const binaryfunc binary_ops[] = { - [NB_ADD] = PyNumber_Add, - [NB_AND] = PyNumber_And, - [NB_FLOOR_DIVIDE] = PyNumber_FloorDivide, - [NB_LSHIFT] = PyNumber_Lshift, - [NB_MATRIX_MULTIPLY] = PyNumber_MatrixMultiply, - [NB_MULTIPLY] = PyNumber_Multiply, - [NB_REMAINDER] = PyNumber_Remainder, - [NB_OR] = PyNumber_Or, - [NB_POWER] = _PyNumber_PowerNoMod, - [NB_RSHIFT] = PyNumber_Rshift, - [NB_SUBTRACT] = PyNumber_Subtract, - [NB_TRUE_DIVIDE] = PyNumber_TrueDivide, - [NB_XOR] = PyNumber_Xor, - [NB_INPLACE_ADD] = PyNumber_InPlaceAdd, - [NB_INPLACE_AND] = PyNumber_InPlaceAnd, - [NB_INPLACE_FLOOR_DIVIDE] = PyNumber_InPlaceFloorDivide, - [NB_INPLACE_LSHIFT] = PyNumber_InPlaceLshift, - [NB_INPLACE_MATRIX_MULTIPLY] = PyNumber_InPlaceMatrixMultiply, - [NB_INPLACE_MULTIPLY] = PyNumber_InPlaceMultiply, - [NB_INPLACE_REMAINDER] = PyNumber_InPlaceRemainder, - [NB_INPLACE_OR] = PyNumber_InPlaceOr, - [NB_INPLACE_POWER] = _PyNumber_InPlacePowerNoMod, - [NB_INPLACE_RSHIFT] = PyNumber_InPlaceRshift, - [NB_INPLACE_SUBTRACT] = PyNumber_InPlaceSubtract, - [NB_INPLACE_TRUE_DIVIDE] = PyNumber_InPlaceTrueDivide, - [NB_INPLACE_XOR] = PyNumber_InPlaceXor, -}; - - -// PEP 634: Structural Pattern Matching - - -// Return a tuple of values corresponding to keys, with error checks for -// duplicate/missing keys. -static PyObject* -match_keys(PyThreadState *tstate, PyObject *map, PyObject *keys) -{ - assert(PyTuple_CheckExact(keys)); - Py_ssize_t nkeys = PyTuple_GET_SIZE(keys); - if (!nkeys) { - // No keys means no items. - return PyTuple_New(0); - } - PyObject *seen = NULL; - PyObject *dummy = NULL; - PyObject *values = NULL; - PyObject *get = NULL; - // We use the two argument form of map.get(key, default) for two reasons: - // - Atomically check for a key and get its value without error handling. - // - Don't cause key creation or resizing in dict subclasses like - // collections.defaultdict that define __missing__ (or similar). - int meth_found = _PyObject_GetMethod(map, &_Py_ID(get), &get); - if (get == NULL) { - goto fail; - } - seen = PySet_New(NULL); - if (seen == NULL) { - goto fail; - } - // dummy = object() - dummy = _PyObject_CallNoArgs((PyObject *)&PyBaseObject_Type); - if (dummy == NULL) { - goto fail; - } - values = PyTuple_New(nkeys); - if (values == NULL) { - goto fail; - } - for (Py_ssize_t i = 0; i < nkeys; i++) { - PyObject *key = PyTuple_GET_ITEM(keys, i); - if (PySet_Contains(seen, key) || PySet_Add(seen, key)) { - if (!_PyErr_Occurred(tstate)) { - // Seen it before! - _PyErr_Format(tstate, PyExc_ValueError, - "mapping pattern checks duplicate key (%R)", key); - } - goto fail; - } - PyObject *args[] = { map, key, dummy }; - PyObject *value = NULL; - if (meth_found) { - value = PyObject_Vectorcall(get, args, 3, NULL); - } - else { - value = PyObject_Vectorcall(get, &args[1], 2, NULL); - } - if (value == NULL) { - goto fail; - } - if (value == dummy) { - // key not in map! - Py_DECREF(value); - Py_DECREF(values); - // Return None: - Py_INCREF(Py_None); - values = Py_None; - goto done; - } - PyTuple_SET_ITEM(values, i, value); - } - // Success: -done: - Py_DECREF(get); - Py_DECREF(seen); - Py_DECREF(dummy); - return values; -fail: - Py_XDECREF(get); - Py_XDECREF(seen); - Py_XDECREF(dummy); - Py_XDECREF(values); - return NULL; -} - -// Extract a named attribute from the subject, with additional bookkeeping to -// raise TypeErrors for repeated lookups. On failure, return NULL (with no -// error set). Use _PyErr_Occurred(tstate) to disambiguate. -static PyObject* -match_class_attr(PyThreadState *tstate, PyObject *subject, PyObject *type, - PyObject *name, PyObject *seen) -{ - assert(PyUnicode_CheckExact(name)); - assert(PySet_CheckExact(seen)); - if (PySet_Contains(seen, name) || PySet_Add(seen, name)) { - if (!_PyErr_Occurred(tstate)) { - // Seen it before! - _PyErr_Format(tstate, PyExc_TypeError, - "%s() got multiple sub-patterns for attribute %R", - ((PyTypeObject*)type)->tp_name, name); - } - return NULL; - } - PyObject *attr = PyObject_GetAttr(subject, name); - if (attr == NULL && _PyErr_ExceptionMatches(tstate, PyExc_AttributeError)) { - _PyErr_Clear(tstate); - } - return attr; -} - -// On success (match), return a tuple of extracted attributes. On failure (no -// match), return NULL. Use _PyErr_Occurred(tstate) to disambiguate. -static PyObject* -match_class(PyThreadState *tstate, PyObject *subject, PyObject *type, - Py_ssize_t nargs, PyObject *kwargs) -{ - if (!PyType_Check(type)) { - const char *e = "called match pattern must be a type"; - _PyErr_Format(tstate, PyExc_TypeError, e); - return NULL; - } - assert(PyTuple_CheckExact(kwargs)); - // First, an isinstance check: - if (PyObject_IsInstance(subject, type) <= 0) { - return NULL; - } - // So far so good: - PyObject *seen = PySet_New(NULL); - if (seen == NULL) { - return NULL; - } - PyObject *attrs = PyList_New(0); - if (attrs == NULL) { - Py_DECREF(seen); - return NULL; - } - // NOTE: From this point on, goto fail on failure: - PyObject *match_args = NULL; - // First, the positional subpatterns: - if (nargs) { - int match_self = 0; - match_args = PyObject_GetAttrString(type, "__match_args__"); - if (match_args) { - if (!PyTuple_CheckExact(match_args)) { - const char *e = "%s.__match_args__ must be a tuple (got %s)"; - _PyErr_Format(tstate, PyExc_TypeError, e, - ((PyTypeObject *)type)->tp_name, - Py_TYPE(match_args)->tp_name); - goto fail; - } - } - else if (_PyErr_ExceptionMatches(tstate, PyExc_AttributeError)) { - _PyErr_Clear(tstate); - // _Py_TPFLAGS_MATCH_SELF is only acknowledged if the type does not - // define __match_args__. This is natural behavior for subclasses: - // it's as if __match_args__ is some "magic" value that is lost as - // soon as they redefine it. - match_args = PyTuple_New(0); - match_self = PyType_HasFeature((PyTypeObject*)type, - _Py_TPFLAGS_MATCH_SELF); - } - else { - goto fail; - } - assert(PyTuple_CheckExact(match_args)); - Py_ssize_t allowed = match_self ? 1 : PyTuple_GET_SIZE(match_args); - if (allowed < nargs) { - const char *plural = (allowed == 1) ? "" : "s"; - _PyErr_Format(tstate, PyExc_TypeError, - "%s() accepts %d positional sub-pattern%s (%d given)", - ((PyTypeObject*)type)->tp_name, - allowed, plural, nargs); - goto fail; - } - if (match_self) { - // Easy. Copy the subject itself, and move on to kwargs. - PyList_Append(attrs, subject); - } - else { - for (Py_ssize_t i = 0; i < nargs; i++) { - PyObject *name = PyTuple_GET_ITEM(match_args, i); - if (!PyUnicode_CheckExact(name)) { - _PyErr_Format(tstate, PyExc_TypeError, - "__match_args__ elements must be strings " - "(got %s)", Py_TYPE(name)->tp_name); - goto fail; - } - PyObject *attr = match_class_attr(tstate, subject, type, name, - seen); - if (attr == NULL) { - goto fail; - } - PyList_Append(attrs, attr); - Py_DECREF(attr); - } - } - Py_CLEAR(match_args); - } - // Finally, the keyword subpatterns: - for (Py_ssize_t i = 0; i < PyTuple_GET_SIZE(kwargs); i++) { - PyObject *name = PyTuple_GET_ITEM(kwargs, i); - PyObject *attr = match_class_attr(tstate, subject, type, name, seen); - if (attr == NULL) { - goto fail; - } - PyList_Append(attrs, attr); - Py_DECREF(attr); - } - Py_SETREF(attrs, PyList_AsTuple(attrs)); - Py_DECREF(seen); - return attrs; -fail: - // We really don't care whether an error was raised or not... that's our - // caller's problem. All we know is that the match failed. - Py_XDECREF(match_args); - Py_DECREF(seen); - Py_DECREF(attrs); - return NULL; -} - - -static int do_raise(PyThreadState *tstate, PyObject *exc, PyObject *cause); -static int exception_group_match( - PyObject* exc_value, PyObject *match_type, - PyObject **match, PyObject **rest); - -static int unpack_iterable(PyThreadState *, PyObject *, int, int, PyObject **); - -PyObject * -PyEval_EvalCode(PyObject *co, PyObject *globals, PyObject *locals) -{ - PyThreadState *tstate = _PyThreadState_GET(); - if (locals == NULL) { - locals = globals; - } - PyObject *builtins = _PyEval_BuiltinsFromGlobals(tstate, globals); // borrowed ref - if (builtins == NULL) { - return NULL; - } - PyFrameConstructor desc = { - .fc_globals = globals, - .fc_builtins = builtins, - .fc_name = ((PyCodeObject *)co)->co_name, - .fc_qualname = ((PyCodeObject *)co)->co_name, - .fc_code = co, - .fc_defaults = NULL, - .fc_kwdefaults = NULL, - .fc_closure = NULL - }; - PyFunctionObject *func = _PyFunction_FromConstructor(&desc); - if (func == NULL) { - return NULL; - } - PyObject *res = _PyEval_Vector(tstate, func, locals, NULL, 0, NULL); - Py_DECREF(func); - return res; -} - - -/* Interpreter main loop */ - -PyObject * -PyEval_EvalFrame(PyFrameObject *f) -{ - /* Function kept for backward compatibility */ - PyThreadState *tstate = _PyThreadState_GET(); - return _PyEval_EvalFrame(tstate, f->f_frame, 0); -} - -PyObject * -PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) -{ - PyThreadState *tstate = _PyThreadState_GET(); - return _PyEval_EvalFrame(tstate, f->f_frame, throwflag); -} - - -/* Handle signals, pending calls, GIL drop request - and asynchronous exception */ -static int -eval_frame_handle_pending(PyThreadState *tstate) -{ - _PyRuntimeState * const runtime = &_PyRuntime; - struct _ceval_runtime_state *ceval = &runtime->ceval; - - /* Pending signals */ - if (_Py_atomic_load_relaxed_int32(&ceval->signals_pending)) { - if (handle_signals(tstate) != 0) { - return -1; - } - } - - /* Pending calls */ - struct _ceval_state *ceval2 = &tstate->interp->ceval; - if (_Py_atomic_load_relaxed_int32(&ceval2->pending.calls_to_do)) { - if (make_pending_calls(tstate->interp) != 0) { - return -1; - } - } - - /* GIL drop request */ - if (_Py_atomic_load_relaxed_int32(&ceval2->gil_drop_request)) { - /* Give another thread a chance */ - if (_PyThreadState_Swap(&runtime->gilstate, NULL) != tstate) { - Py_FatalError("tstate mix-up"); - } - drop_gil(ceval, ceval2, tstate); - - /* Other threads may run now */ - - take_gil(tstate); - - if (_PyThreadState_Swap(&runtime->gilstate, tstate) != NULL) { - Py_FatalError("orphan tstate"); - } - } - - /* Check for asynchronous exception. */ - if (tstate->async_exc != NULL) { - PyObject *exc = tstate->async_exc; - tstate->async_exc = NULL; - UNSIGNAL_ASYNC_EXC(tstate->interp); - _PyErr_SetNone(tstate, exc); - Py_DECREF(exc); - return -1; - } - -#ifdef MS_WINDOWS - // bpo-42296: On Windows, _PyEval_SignalReceived() can be called in a - // different thread than the Python thread, in which case - // _Py_ThreadCanHandleSignals() is wrong. Recompute eval_breaker in the - // current Python thread with the correct _Py_ThreadCanHandleSignals() - // value. It prevents to interrupt the eval loop at every instruction if - // the current Python thread cannot handle signals (if - // _Py_ThreadCanHandleSignals() is false). - COMPUTE_EVAL_BREAKER(tstate->interp, ceval, ceval2); -#endif - - return 0; -} - - -/* Computed GOTOs, or - the-optimization-commonly-but-improperly-known-as-"threaded code" - using gcc's labels-as-values extension - (http://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html). - - The traditional bytecode evaluation loop uses a "switch" statement, which - decent compilers will optimize as a single indirect branch instruction - combined with a lookup table of jump addresses. However, since the - indirect jump instruction is shared by all opcodes, the CPU will have a - hard time making the right prediction for where to jump next (actually, - it will be always wrong except in the uncommon case of a sequence of - several identical opcodes). - - "Threaded code" in contrast, uses an explicit jump table and an explicit - indirect jump instruction at the end of each opcode. Since the jump - instruction is at a different address for each opcode, the CPU will make a - separate prediction for each of these instructions, which is equivalent to - predicting the second opcode of each opcode pair. These predictions have - a much better chance to turn out valid, especially in small bytecode loops. - - A mispredicted branch on a modern CPU flushes the whole pipeline and - can cost several CPU cycles (depending on the pipeline depth), - and potentially many more instructions (depending on the pipeline width). - A correctly predicted branch, however, is nearly free. - - At the time of this writing, the "threaded code" version is up to 15-20% - faster than the normal "switch" version, depending on the compiler and the - CPU architecture. - - NOTE: care must be taken that the compiler doesn't try to "optimize" the - indirect jumps by sharing them between all opcodes. Such optimizations - can be disabled on gcc by using the -fno-gcse flag (or possibly - -fno-crossjumping). -*/ - -/* Use macros rather than inline functions, to make it as clear as possible - * to the C compiler that the tracing check is a simple test then branch. - * We want to be sure that the compiler knows this before it generates - * the CFG. - */ - -#ifdef WITH_DTRACE -#define OR_DTRACE_LINE | (PyDTrace_LINE_ENABLED() ? 255 : 0) -#else -#define OR_DTRACE_LINE -#endif - -#ifdef HAVE_COMPUTED_GOTOS - #ifndef USE_COMPUTED_GOTOS - #define USE_COMPUTED_GOTOS 1 - #endif -#else - #if defined(USE_COMPUTED_GOTOS) && USE_COMPUTED_GOTOS - #error "Computed gotos are not supported on this compiler." - #endif - #undef USE_COMPUTED_GOTOS - #define USE_COMPUTED_GOTOS 0 -#endif - -#ifdef Py_STATS -#define INSTRUCTION_START(op) \ - do { \ - frame->prev_instr = next_instr++; \ - OPCODE_EXE_INC(op); \ - _py_stats.opcode_stats[lastopcode].pair_count[op]++; \ - lastopcode = op; \ - } while (0) -#else -#define INSTRUCTION_START(op) (frame->prev_instr = next_instr++) -#endif - -#if USE_COMPUTED_GOTOS -#define TARGET(op) TARGET_##op: INSTRUCTION_START(op); -#define DISPATCH_GOTO() goto *opcode_targets[opcode] -#else -#define TARGET(op) case op: INSTRUCTION_START(op); -#define DISPATCH_GOTO() goto dispatch_opcode -#endif - -/* PRE_DISPATCH_GOTO() does lltrace if enabled. Normally a no-op */ -#ifdef LLTRACE -#define PRE_DISPATCH_GOTO() if (lltrace) { \ - lltrace_instruction(frame, stack_pointer, next_instr); } -#else -#define PRE_DISPATCH_GOTO() ((void)0) -#endif - - -/* Do interpreter dispatch accounting for tracing and instrumentation */ -#define DISPATCH() \ - { \ - NEXTOPARG(); \ - PRE_DISPATCH_GOTO(); \ - assert(cframe.use_tracing == 0 || cframe.use_tracing == 255); \ - opcode |= cframe.use_tracing OR_DTRACE_LINE; \ - DISPATCH_GOTO(); \ - } - -#define DISPATCH_SAME_OPARG() \ - { \ - opcode = _Py_OPCODE(*next_instr); \ - PRE_DISPATCH_GOTO(); \ - opcode |= cframe.use_tracing OR_DTRACE_LINE; \ - DISPATCH_GOTO(); \ - } - -#define CHECK_EVAL_BREAKER() \ - _Py_CHECK_EMSCRIPTEN_SIGNALS_PERIODICALLY(); \ - if (_Py_atomic_load_relaxed_int32(eval_breaker)) { \ - goto handle_eval_breaker; \ - } - - -/* Tuple access macros */ - -#ifndef Py_DEBUG -#define GETITEM(v, i) PyTuple_GET_ITEM((PyTupleObject *)(v), (i)) -#else -#define GETITEM(v, i) PyTuple_GetItem((v), (i)) -#endif - -/* Code access macros */ - -/* The integer overflow is checked by an assertion below. */ -#define INSTR_OFFSET() ((int)(next_instr - first_instr)) -#define NEXTOPARG() do { \ - _Py_CODEUNIT word = *next_instr; \ - opcode = _Py_OPCODE(word); \ - oparg = _Py_OPARG(word); \ - } while (0) -#define JUMPTO(x) (next_instr = first_instr + (x)) -#define JUMPBY(x) (next_instr += (x)) - -// Skip from a PRECALL over a CALL to the next instruction: -#define SKIP_CALL() \ - JUMPBY(INLINE_CACHE_ENTRIES_PRECALL + 1 + INLINE_CACHE_ENTRIES_CALL) - -/* Get opcode and oparg from original instructions, not quickened form. */ -#define TRACING_NEXTOPARG() do { \ - NEXTOPARG(); \ - opcode = _PyOpcode_Deopt[opcode]; \ - } while (0) - -/* OpCode prediction macros - Some opcodes tend to come in pairs thus making it possible to - predict the second code when the first is run. For example, - COMPARE_OP is often followed by POP_JUMP_IF_FALSE or POP_JUMP_IF_TRUE. - - Verifying the prediction costs a single high-speed test of a register - variable against a constant. If the pairing was good, then the - processor's own internal branch predication has a high likelihood of - success, resulting in a nearly zero-overhead transition to the - next opcode. A successful prediction saves a trip through the eval-loop - including its unpredictable switch-case branch. Combined with the - processor's internal branch prediction, a successful PREDICT has the - effect of making the two opcodes run as if they were a single new opcode - with the bodies combined. - - If collecting opcode statistics, your choices are to either keep the - predictions turned-on and interpret the results as if some opcodes - had been combined or turn-off predictions so that the opcode frequency - counter updates for both opcodes. - - Opcode prediction is disabled with threaded code, since the latter allows - the CPU to record separate branch prediction information for each - opcode. - -*/ - -#define PREDICT_ID(op) PRED_##op - -#if USE_COMPUTED_GOTOS -#define PREDICT(op) if (0) goto PREDICT_ID(op) -#else -#define PREDICT(op) \ - do { \ - _Py_CODEUNIT word = *next_instr; \ - opcode = _Py_OPCODE(word) | cframe.use_tracing OR_DTRACE_LINE; \ - if (opcode == op) { \ - oparg = _Py_OPARG(word); \ - INSTRUCTION_START(op); \ - goto PREDICT_ID(op); \ - } \ - } while(0) -#endif -#define PREDICTED(op) PREDICT_ID(op): - - -/* Stack manipulation macros */ - -/* The stack can grow at most MAXINT deep, as co_nlocals and - co_stacksize are ints. */ -#define STACK_LEVEL() ((int)(stack_pointer - _PyFrame_Stackbase(frame))) -#define STACK_SIZE() (frame->f_code->co_stacksize) -#define EMPTY() (STACK_LEVEL() == 0) -#define TOP() (stack_pointer[-1]) -#define SECOND() (stack_pointer[-2]) -#define THIRD() (stack_pointer[-3]) -#define FOURTH() (stack_pointer[-4]) -#define PEEK(n) (stack_pointer[-(n)]) -#define SET_TOP(v) (stack_pointer[-1] = (v)) -#define SET_SECOND(v) (stack_pointer[-2] = (v)) -#define BASIC_STACKADJ(n) (stack_pointer += n) -#define BASIC_PUSH(v) (*stack_pointer++ = (v)) -#define BASIC_POP() (*--stack_pointer) - -#ifdef Py_DEBUG -#define PUSH(v) do { \ - BASIC_PUSH(v); \ - assert(STACK_LEVEL() <= STACK_SIZE()); \ - } while (0) -#define POP() (assert(STACK_LEVEL() > 0), BASIC_POP()) -#define STACK_GROW(n) do { \ - assert(n >= 0); \ - BASIC_STACKADJ(n); \ - assert(STACK_LEVEL() <= STACK_SIZE()); \ - } while (0) -#define STACK_SHRINK(n) do { \ - assert(n >= 0); \ - assert(STACK_LEVEL() >= n); \ - BASIC_STACKADJ(-(n)); \ - } while (0) -#else -#define PUSH(v) BASIC_PUSH(v) -#define POP() BASIC_POP() -#define STACK_GROW(n) BASIC_STACKADJ(n) -#define STACK_SHRINK(n) BASIC_STACKADJ(-(n)) -#endif - -/* Local variable macros */ - -#define GETLOCAL(i) (frame->localsplus[i]) - -/* The SETLOCAL() macro must not DECREF the local variable in-place and - then store the new value; it must copy the old value to a temporary - value, then store the new value, and then DECREF the temporary value. - This is because it is possible that during the DECREF the frame is - accessed by other code (e.g. a __del__ method or gc.collect()) and the - variable would be pointing to already-freed memory. */ -#define SETLOCAL(i, value) do { PyObject *tmp = GETLOCAL(i); \ - GETLOCAL(i) = value; \ - Py_XDECREF(tmp); } while (0) - -#define JUMP_TO_INSTRUCTION(op) goto PREDICT_ID(op) - - -#define DEOPT_IF(cond, instname) if (cond) { goto miss; } - - -#define GLOBALS() frame->f_globals -#define BUILTINS() frame->f_builtins -#define LOCALS() frame->f_locals - -/* Shared opcode macros */ - -// shared by LOAD_ATTR_MODULE and LOAD_METHOD_MODULE -#define LOAD_MODULE_ATTR_OR_METHOD(attr_or_method) \ - _PyAttrCache *cache = (_PyAttrCache *)next_instr; \ - DEOPT_IF(!PyModule_CheckExact(owner), LOAD_##attr_or_method); \ - PyDictObject *dict = (PyDictObject *)((PyModuleObject *)owner)->md_dict; \ - assert(dict != NULL); \ - DEOPT_IF(dict->ma_keys->dk_version != read_u32(cache->version), \ - LOAD_##attr_or_method); \ - assert(dict->ma_keys->dk_kind == DICT_KEYS_UNICODE); \ - assert(cache->index < dict->ma_keys->dk_nentries); \ - PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(dict->ma_keys) + cache->index; \ - res = ep->me_value; \ - DEOPT_IF(res == NULL, LOAD_##attr_or_method); \ - STAT_INC(LOAD_##attr_or_method, hit); \ - Py_INCREF(res); - -#define TRACE_FUNCTION_EXIT() \ - if (cframe.use_tracing) { \ - if (trace_function_exit(tstate, frame, retval)) { \ - Py_DECREF(retval); \ - goto exit_unwind; \ - } \ - } - -#define DTRACE_FUNCTION_EXIT() \ - if (PyDTrace_FUNCTION_RETURN_ENABLED()) { \ - dtrace_function_return(frame); \ - } - -#define TRACE_FUNCTION_UNWIND() \ - if (cframe.use_tracing) { \ - /* Since we are already unwinding, \ - * we don't care if this raises */ \ - trace_function_exit(tstate, frame, NULL); \ - } - -#define TRACE_FUNCTION_ENTRY() \ - if (cframe.use_tracing) { \ - _PyFrame_SetStackPointer(frame, stack_pointer); \ - int err = trace_function_entry(tstate, frame); \ - stack_pointer = _PyFrame_GetStackPointer(frame); \ - if (err) { \ - goto error; \ - } \ - } - -#define TRACE_FUNCTION_THROW_ENTRY() \ - if (cframe.use_tracing) { \ - assert(frame->stacktop >= 0); \ - if (trace_function_entry(tstate, frame)) { \ - goto exit_unwind; \ - } \ - } - -#define DTRACE_FUNCTION_ENTRY() \ - if (PyDTrace_FUNCTION_ENTRY_ENABLED()) { \ - dtrace_function_entry(frame); \ - } - -#define ADAPTIVE_COUNTER_IS_ZERO(cache) \ - (cache)->counter < (1<<ADAPTIVE_BACKOFF_BITS) - -#define DECREMENT_ADAPTIVE_COUNTER(cache) \ - (cache)->counter -= (1<<ADAPTIVE_BACKOFF_BITS) - -static int -trace_function_entry(PyThreadState *tstate, _PyInterpreterFrame *frame) -{ - if (tstate->c_tracefunc != NULL) { - /* tstate->c_tracefunc, if defined, is a - function that will be called on *every* entry - to a code block. Its return value, if not - None, is a function that will be called at - the start of each executed line of code. - (Actually, the function must return itself - in order to continue tracing.) The trace - functions are called with three arguments: - a pointer to the current frame, a string - indicating why the function is called, and - an argument which depends on the situation. - The global trace function is also called - whenever an exception is detected. */ - if (call_trace_protected(tstate->c_tracefunc, - tstate->c_traceobj, - tstate, frame, - PyTrace_CALL, Py_None)) { - /* Trace function raised an error */ - return -1; - } - } - if (tstate->c_profilefunc != NULL) { - /* Similar for c_profilefunc, except it needn't - return itself and isn't called for "line" events */ - if (call_trace_protected(tstate->c_profilefunc, - tstate->c_profileobj, - tstate, frame, - PyTrace_CALL, Py_None)) { - /* Profile function raised an error */ - return -1; - } - } - return 0; -} - -static int -trace_function_exit(PyThreadState *tstate, _PyInterpreterFrame *frame, PyObject *retval) -{ - if (tstate->c_tracefunc) { - if (call_trace_protected(tstate->c_tracefunc, tstate->c_traceobj, - tstate, frame, PyTrace_RETURN, retval)) { - return -1; - } - } - if (tstate->c_profilefunc) { - if (call_trace_protected(tstate->c_profilefunc, tstate->c_profileobj, - tstate, frame, PyTrace_RETURN, retval)) { - return -1; - } - } - return 0; -} - -/* It is only between the PRECALL instruction and the following CALL, - * that this has any meaning. - */ -typedef struct { - PyObject *kwnames; -} CallShape; - -// GH-89279: Must be a macro to be sure it's inlined by MSVC. -#define is_method(stack_pointer, args) (PEEK((args)+2) != NULL) - -#define KWNAMES_LEN() \ - (call_shape.kwnames == NULL ? 0 : ((int)PyTuple_GET_SIZE(call_shape.kwnames))) - -PyObject* _Py_HOT_FUNCTION -_PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int throwflag) -{ - _Py_EnsureTstateNotNULL(tstate); - CALL_STAT_INC(pyeval_calls); - -#if USE_COMPUTED_GOTOS -/* Import the static jump table */ -#include "opcode_targets.h" -#endif - -#ifdef Py_STATS - int lastopcode = 0; -#endif - // opcode is an 8-bit value to improve the code generated by MSVC - // for the big switch below (in combination with the EXTRA_CASES macro). - uint8_t opcode; /* Current opcode */ - int oparg; /* Current opcode argument, if any */ - _Py_atomic_int * const eval_breaker = &tstate->interp->ceval.eval_breaker; -#ifdef LLTRACE - int lltrace = 0; -#endif - - _PyCFrame cframe; - CallShape call_shape; - call_shape.kwnames = NULL; // Borrowed reference. Reset by CALL instructions. - - /* WARNING: Because the _PyCFrame lives on the C stack, - * but can be accessed from a heap allocated object (tstate) - * strict stack discipline must be maintained. - */ - _PyCFrame *prev_cframe = tstate->cframe; - cframe.use_tracing = prev_cframe->use_tracing; - cframe.previous = prev_cframe; - tstate->cframe = &cframe; - - frame->is_entry = true; - /* Push frame */ - frame->previous = prev_cframe->current_frame; - cframe.current_frame = frame; - - /* support for generator.throw() */ - if (throwflag) { - if (_Py_EnterRecursiveCallTstate(tstate, "")) { - tstate->recursion_remaining--; - goto exit_unwind; - } - TRACE_FUNCTION_THROW_ENTRY(); - DTRACE_FUNCTION_ENTRY(); - goto resume_with_error; - } - - /* Local "register" variables. - * These are cached values from the frame and code object. */ - - PyObject *names; - PyObject *consts; - _Py_CODEUNIT *first_instr; - _Py_CODEUNIT *next_instr; - PyObject **stack_pointer; - -/* Sets the above local variables from the frame */ -#define SET_LOCALS_FROM_FRAME() \ - { \ - PyCodeObject *co = frame->f_code; \ - names = co->co_names; \ - consts = co->co_consts; \ - first_instr = _PyCode_CODE(co); \ - } \ - assert(_PyInterpreterFrame_LASTI(frame) >= -1); \ - /* Jump back to the last instruction executed... */ \ - next_instr = frame->prev_instr + 1; \ - stack_pointer = _PyFrame_GetStackPointer(frame); \ - /* Set stackdepth to -1. \ - Update when returning or calling trace function. \ - Having stackdepth <= 0 ensures that invalid \ - values are not visible to the cycle GC. \ - We choose -1 rather than 0 to assist debugging. \ - */ \ - frame->stacktop = -1; - - -start_frame: - if (_Py_EnterRecursiveCallTstate(tstate, "")) { - tstate->recursion_remaining--; - goto exit_unwind; - } - -resume_frame: - SET_LOCALS_FROM_FRAME(); - -#ifdef LLTRACE - { - int r = PyDict_Contains(GLOBALS(), &_Py_ID(__lltrace__)); - if (r < 0) { - goto exit_unwind; - } - lltrace = r; - } - if (lltrace) { - lltrace_resume_frame(frame); - } -#endif - -#ifdef Py_DEBUG - /* _PyEval_EvalFrameDefault() must not be called with an exception set, - because it can clear it (directly or indirectly) and so the - caller loses its exception */ - assert(!_PyErr_Occurred(tstate)); -#endif - - DISPATCH(); - -handle_eval_breaker: - - /* Do periodic things, like check for signals and async I/0. - * We need to do reasonably frequently, but not too frequently. - * All loops should include a check of the eval breaker. - * We also check on return from any builtin function. - */ - if (eval_frame_handle_pending(tstate) != 0) { - goto error; - } - DISPATCH(); - - { - /* Start instructions */ -#if USE_COMPUTED_GOTOS - { -#else - dispatch_opcode: - switch (opcode) { -#endif - - /* BEWARE! - It is essential that any operation that fails must goto error - and that all operation that succeed call DISPATCH() ! */ - - TARGET(NOP) { - DISPATCH(); - } - - TARGET(RESUME) { - _PyCode_Warmup(frame->f_code); - JUMP_TO_INSTRUCTION(RESUME_QUICK); - } - - TARGET(RESUME_QUICK) { - PREDICTED(RESUME_QUICK); - assert(tstate->cframe == &cframe); - assert(frame == cframe.current_frame); - if (_Py_atomic_load_relaxed_int32(eval_breaker) && oparg < 2) { - goto handle_eval_breaker; - } - DISPATCH(); - } - - TARGET(LOAD_CLOSURE) { - /* We keep LOAD_CLOSURE so that the bytecode stays more readable. */ - PyObject *value = GETLOCAL(oparg); - if (value == NULL) { - goto unbound_local_error; - } - Py_INCREF(value); - PUSH(value); - DISPATCH(); - } - - TARGET(LOAD_FAST) { - PyObject *value = GETLOCAL(oparg); - if (value == NULL) { - goto unbound_local_error; - } - Py_INCREF(value); - PUSH(value); - DISPATCH(); - } - - TARGET(LOAD_CONST) { - PREDICTED(LOAD_CONST); - PyObject *value = GETITEM(consts, oparg); - Py_INCREF(value); - PUSH(value); - DISPATCH(); - } - - TARGET(STORE_FAST) { - PREDICTED(STORE_FAST); - PyObject *value = POP(); - SETLOCAL(oparg, value); - DISPATCH(); - } - - TARGET(LOAD_FAST__LOAD_FAST) { - PyObject *value = GETLOCAL(oparg); - if (value == NULL) { - goto unbound_local_error; - } - NEXTOPARG(); - next_instr++; - Py_INCREF(value); - PUSH(value); - value = GETLOCAL(oparg); - if (value == NULL) { - goto unbound_local_error; - } - Py_INCREF(value); - PUSH(value); - DISPATCH(); - } - - TARGET(LOAD_FAST__LOAD_CONST) { - PyObject *value = GETLOCAL(oparg); - if (value == NULL) { - goto unbound_local_error; - } - NEXTOPARG(); - next_instr++; - Py_INCREF(value); - PUSH(value); - value = GETITEM(consts, oparg); - Py_INCREF(value); - PUSH(value); - DISPATCH(); - } - - TARGET(STORE_FAST__LOAD_FAST) { - PyObject *value = POP(); - SETLOCAL(oparg, value); - NEXTOPARG(); - next_instr++; - value = GETLOCAL(oparg); - if (value == NULL) { - goto unbound_local_error; - } - Py_INCREF(value); - PUSH(value); - DISPATCH(); - } - - TARGET(STORE_FAST__STORE_FAST) { - PyObject *value = POP(); - SETLOCAL(oparg, value); - NEXTOPARG(); - next_instr++; - value = POP(); - SETLOCAL(oparg, value); - DISPATCH(); - } - - TARGET(LOAD_CONST__LOAD_FAST) { - PyObject *value = GETITEM(consts, oparg); - NEXTOPARG(); - next_instr++; - Py_INCREF(value); - PUSH(value); - value = GETLOCAL(oparg); - if (value == NULL) { - goto unbound_local_error; - } - Py_INCREF(value); - PUSH(value); - DISPATCH(); - } - - TARGET(POP_TOP) { - PyObject *value = POP(); - Py_DECREF(value); - DISPATCH(); - } - - TARGET(PUSH_NULL) { - /* Use BASIC_PUSH as NULL is not a valid object pointer */ - BASIC_PUSH(NULL); - DISPATCH(); - } - - TARGET(UNARY_POSITIVE) { - PyObject *value = TOP(); - PyObject *res = PyNumber_Positive(value); - Py_DECREF(value); - SET_TOP(res); - if (res == NULL) - goto error; - DISPATCH(); - } - - TARGET(UNARY_NEGATIVE) { - PyObject *value = TOP(); - PyObject *res = PyNumber_Negative(value); - Py_DECREF(value); - SET_TOP(res); - if (res == NULL) - goto error; - DISPATCH(); - } - - TARGET(UNARY_NOT) { - PyObject *value = TOP(); - int err = PyObject_IsTrue(value); - Py_DECREF(value); - if (err == 0) { - Py_INCREF(Py_True); - SET_TOP(Py_True); - DISPATCH(); - } - else if (err > 0) { - Py_INCREF(Py_False); - SET_TOP(Py_False); - DISPATCH(); - } - STACK_SHRINK(1); - goto error; - } - - TARGET(UNARY_INVERT) { - PyObject *value = TOP(); - PyObject *res = PyNumber_Invert(value); - Py_DECREF(value); - SET_TOP(res); - if (res == NULL) - goto error; - DISPATCH(); - } - - TARGET(BINARY_OP_MULTIPLY_INT) { - assert(cframe.use_tracing == 0); - PyObject *left = SECOND(); - PyObject *right = TOP(); - DEOPT_IF(!PyLong_CheckExact(left), BINARY_OP); - DEOPT_IF(!PyLong_CheckExact(right), BINARY_OP); - STAT_INC(BINARY_OP, hit); - PyObject *prod = _PyLong_Multiply((PyLongObject *)left, (PyLongObject *)right); - SET_SECOND(prod); - _Py_DECREF_SPECIALIZED(right, (destructor)PyObject_Free); - _Py_DECREF_SPECIALIZED(left, (destructor)PyObject_Free); - STACK_SHRINK(1); - if (prod == NULL) { - goto error; - } - JUMPBY(INLINE_CACHE_ENTRIES_BINARY_OP); - DISPATCH(); - } - - TARGET(BINARY_OP_MULTIPLY_FLOAT) { - assert(cframe.use_tracing == 0); - PyObject *left = SECOND(); - PyObject *right = TOP(); - DEOPT_IF(!PyFloat_CheckExact(left), BINARY_OP); - DEOPT_IF(!PyFloat_CheckExact(right), BINARY_OP); - STAT_INC(BINARY_OP, hit); - double dprod = ((PyFloatObject *)left)->ob_fval * - ((PyFloatObject *)right)->ob_fval; - PyObject *prod = PyFloat_FromDouble(dprod); - SET_SECOND(prod); - _Py_DECREF_SPECIALIZED(right, _PyFloat_ExactDealloc); - _Py_DECREF_SPECIALIZED(left, _PyFloat_ExactDealloc); - STACK_SHRINK(1); - if (prod == NULL) { - goto error; - } - JUMPBY(INLINE_CACHE_ENTRIES_BINARY_OP); - DISPATCH(); - } - - TARGET(BINARY_OP_SUBTRACT_INT) { - assert(cframe.use_tracing == 0); - PyObject *left = SECOND(); - PyObject *right = TOP(); - DEOPT_IF(!PyLong_CheckExact(left), BINARY_OP); - DEOPT_IF(!PyLong_CheckExact(right), BINARY_OP); - STAT_INC(BINARY_OP, hit); - PyObject *sub = _PyLong_Subtract((PyLongObject *)left, (PyLongObject *)right); - SET_SECOND(sub); - _Py_DECREF_SPECIALIZED(right, (destructor)PyObject_Free); - _Py_DECREF_SPECIALIZED(left, (destructor)PyObject_Free); - STACK_SHRINK(1); - if (sub == NULL) { - goto error; - } - JUMPBY(INLINE_CACHE_ENTRIES_BINARY_OP); - DISPATCH(); - } - - TARGET(BINARY_OP_SUBTRACT_FLOAT) { - assert(cframe.use_tracing == 0); - PyObject *left = SECOND(); - PyObject *right = TOP(); - DEOPT_IF(!PyFloat_CheckExact(left), BINARY_OP); - DEOPT_IF(!PyFloat_CheckExact(right), BINARY_OP); - STAT_INC(BINARY_OP, hit); - double dsub = ((PyFloatObject *)left)->ob_fval - ((PyFloatObject *)right)->ob_fval; - PyObject *sub = PyFloat_FromDouble(dsub); - SET_SECOND(sub); - _Py_DECREF_SPECIALIZED(right, _PyFloat_ExactDealloc); - _Py_DECREF_SPECIALIZED(left, _PyFloat_ExactDealloc); - STACK_SHRINK(1); - if (sub == NULL) { - goto error; - } - JUMPBY(INLINE_CACHE_ENTRIES_BINARY_OP); - DISPATCH(); - } - - TARGET(BINARY_OP_ADD_UNICODE) { - assert(cframe.use_tracing == 0); - PyObject *left = SECOND(); - PyObject *right = TOP(); - DEOPT_IF(!PyUnicode_CheckExact(left), BINARY_OP); - DEOPT_IF(Py_TYPE(right) != Py_TYPE(left), BINARY_OP); - STAT_INC(BINARY_OP, hit); - PyObject *res = PyUnicode_Concat(left, right); - STACK_SHRINK(1); - SET_TOP(res); - _Py_DECREF_SPECIALIZED(left, _PyUnicode_ExactDealloc); - _Py_DECREF_SPECIALIZED(right, _PyUnicode_ExactDealloc); - if (TOP() == NULL) { - goto error; - } - JUMPBY(INLINE_CACHE_ENTRIES_BINARY_OP); - DISPATCH(); - } - - TARGET(BINARY_OP_INPLACE_ADD_UNICODE) { - assert(cframe.use_tracing == 0); - PyObject *left = SECOND(); - PyObject *right = TOP(); - DEOPT_IF(!PyUnicode_CheckExact(left), BINARY_OP); - DEOPT_IF(Py_TYPE(right) != Py_TYPE(left), BINARY_OP); - _Py_CODEUNIT true_next = next_instr[INLINE_CACHE_ENTRIES_BINARY_OP]; - assert(_Py_OPCODE(true_next) == STORE_FAST || - _Py_OPCODE(true_next) == STORE_FAST__LOAD_FAST); - PyObject **target_local = &GETLOCAL(_Py_OPARG(true_next)); - DEOPT_IF(*target_local != left, BINARY_OP); - STAT_INC(BINARY_OP, hit); - /* Handle `left = left + right` or `left += right` for str. - * - * When possible, extend `left` in place rather than - * allocating a new PyUnicodeObject. This attempts to avoid - * quadratic behavior when one neglects to use str.join(). - * - * If `left` has only two references remaining (one from - * the stack, one in the locals), DECREFing `left` leaves - * only the locals reference, so PyUnicode_Append knows - * that the string is safe to mutate. - */ - assert(Py_REFCNT(left) >= 2); - _Py_DECREF_NO_DEALLOC(left); - STACK_SHRINK(2); - PyUnicode_Append(target_local, right); - _Py_DECREF_SPECIALIZED(right, _PyUnicode_ExactDealloc); - if (*target_local == NULL) { - goto error; - } - // The STORE_FAST is already done. - JUMPBY(INLINE_CACHE_ENTRIES_BINARY_OP + 1); - DISPATCH(); - } - - TARGET(BINARY_OP_ADD_FLOAT) { - assert(cframe.use_tracing == 0); - PyObject *left = SECOND(); - PyObject *right = TOP(); - DEOPT_IF(!PyFloat_CheckExact(left), BINARY_OP); - DEOPT_IF(Py_TYPE(right) != Py_TYPE(left), BINARY_OP); - STAT_INC(BINARY_OP, hit); - double dsum = ((PyFloatObject *)left)->ob_fval + - ((PyFloatObject *)right)->ob_fval; - PyObject *sum = PyFloat_FromDouble(dsum); - SET_SECOND(sum); - _Py_DECREF_SPECIALIZED(right, _PyFloat_ExactDealloc); - _Py_DECREF_SPECIALIZED(left, _PyFloat_ExactDealloc); - STACK_SHRINK(1); - if (sum == NULL) { - goto error; - } - JUMPBY(INLINE_CACHE_ENTRIES_BINARY_OP); - DISPATCH(); - } - - TARGET(BINARY_OP_ADD_INT) { - assert(cframe.use_tracing == 0); - PyObject *left = SECOND(); - PyObject *right = TOP(); - DEOPT_IF(!PyLong_CheckExact(left), BINARY_OP); - DEOPT_IF(Py_TYPE(right) != Py_TYPE(left), BINARY_OP); - STAT_INC(BINARY_OP, hit); - PyObject *sum = _PyLong_Add((PyLongObject *)left, (PyLongObject *)right); - SET_SECOND(sum); - _Py_DECREF_SPECIALIZED(right, (destructor)PyObject_Free); - _Py_DECREF_SPECIALIZED(left, (destructor)PyObject_Free); - STACK_SHRINK(1); - if (sum == NULL) { - goto error; - } - JUMPBY(INLINE_CACHE_ENTRIES_BINARY_OP); - DISPATCH(); - } - - TARGET(BINARY_SUBSCR) { - PREDICTED(BINARY_SUBSCR); - PyObject *sub = POP(); - PyObject *container = TOP(); - PyObject *res = PyObject_GetItem(container, sub); - Py_DECREF(container); - Py_DECREF(sub); - SET_TOP(res); - if (res == NULL) - goto error; - JUMPBY(INLINE_CACHE_ENTRIES_BINARY_SUBSCR); - DISPATCH(); - } - - TARGET(BINARY_SUBSCR_ADAPTIVE) { - _PyBinarySubscrCache *cache = (_PyBinarySubscrCache *)next_instr; - if (ADAPTIVE_COUNTER_IS_ZERO(cache)) { - PyObject *sub = TOP(); - PyObject *container = SECOND(); - next_instr--; - if (_Py_Specialize_BinarySubscr(container, sub, next_instr) < 0) { - next_instr++; - goto error; - } - DISPATCH_SAME_OPARG(); - } - else { - STAT_INC(BINARY_SUBSCR, deferred); - DECREMENT_ADAPTIVE_COUNTER(cache); - JUMP_TO_INSTRUCTION(BINARY_SUBSCR); - } - } - - TARGET(BINARY_SUBSCR_LIST_INT) { - assert(cframe.use_tracing == 0); - PyObject *sub = TOP(); - PyObject *list = SECOND(); - DEOPT_IF(!PyLong_CheckExact(sub), BINARY_SUBSCR); - DEOPT_IF(!PyList_CheckExact(list), BINARY_SUBSCR); - - // Deopt unless 0 <= sub < PyList_Size(list) - Py_ssize_t signed_magnitude = Py_SIZE(sub); - DEOPT_IF(((size_t)signed_magnitude) > 1, BINARY_SUBSCR); - assert(((PyLongObject *)_PyLong_GetZero())->ob_digit[0] == 0); - Py_ssize_t index = ((PyLongObject*)sub)->ob_digit[0]; - DEOPT_IF(index >= PyList_GET_SIZE(list), BINARY_SUBSCR); - STAT_INC(BINARY_SUBSCR, hit); - PyObject *res = PyList_GET_ITEM(list, index); - assert(res != NULL); - Py_INCREF(res); - STACK_SHRINK(1); - _Py_DECREF_SPECIALIZED(sub, (destructor)PyObject_Free); - SET_TOP(res); - Py_DECREF(list); - JUMPBY(INLINE_CACHE_ENTRIES_BINARY_SUBSCR); - DISPATCH(); - } - - TARGET(BINARY_SUBSCR_TUPLE_INT) { - assert(cframe.use_tracing == 0); - PyObject *sub = TOP(); - PyObject *tuple = SECOND(); - DEOPT_IF(!PyLong_CheckExact(sub), BINARY_SUBSCR); - DEOPT_IF(!PyTuple_CheckExact(tuple), BINARY_SUBSCR); - - // Deopt unless 0 <= sub < PyTuple_Size(list) - Py_ssize_t signed_magnitude = Py_SIZE(sub); - DEOPT_IF(((size_t)signed_magnitude) > 1, BINARY_SUBSCR); - assert(((PyLongObject *)_PyLong_GetZero())->ob_digit[0] == 0); - Py_ssize_t index = ((PyLongObject*)sub)->ob_digit[0]; - DEOPT_IF(index >= PyTuple_GET_SIZE(tuple), BINARY_SUBSCR); - STAT_INC(BINARY_SUBSCR, hit); - PyObject *res = PyTuple_GET_ITEM(tuple, index); - assert(res != NULL); - Py_INCREF(res); - STACK_SHRINK(1); - _Py_DECREF_SPECIALIZED(sub, (destructor)PyObject_Free); - SET_TOP(res); - Py_DECREF(tuple); - JUMPBY(INLINE_CACHE_ENTRIES_BINARY_SUBSCR); - DISPATCH(); - } - - TARGET(BINARY_SUBSCR_DICT) { - assert(cframe.use_tracing == 0); - PyObject *dict = SECOND(); - DEOPT_IF(!PyDict_CheckExact(SECOND()), BINARY_SUBSCR); - STAT_INC(BINARY_SUBSCR, hit); - PyObject *sub = TOP(); - PyObject *res = PyDict_GetItemWithError(dict, sub); - if (res == NULL) { - goto binary_subscr_dict_error; - } - Py_INCREF(res); - STACK_SHRINK(1); - Py_DECREF(sub); - SET_TOP(res); - Py_DECREF(dict); - JUMPBY(INLINE_CACHE_ENTRIES_BINARY_SUBSCR); - DISPATCH(); - } - - TARGET(BINARY_SUBSCR_GETITEM) { - PyObject *sub = TOP(); - PyObject *container = SECOND(); - _PyBinarySubscrCache *cache = (_PyBinarySubscrCache *)next_instr; - uint32_t type_version = read_u32(cache->type_version); - PyTypeObject *tp = Py_TYPE(container); - DEOPT_IF(tp->tp_version_tag != type_version, BINARY_SUBSCR); - assert(tp->tp_flags & Py_TPFLAGS_HEAPTYPE); - PyObject *cached = ((PyHeapTypeObject *)tp)->_spec_cache.getitem; - assert(PyFunction_Check(cached)); - PyFunctionObject *getitem = (PyFunctionObject *)cached; - DEOPT_IF(getitem->func_version != cache->func_version, BINARY_SUBSCR); - PyCodeObject *code = (PyCodeObject *)getitem->func_code; - size_t size = code->co_nlocalsplus + code->co_stacksize + FRAME_SPECIALS_SIZE; - assert(code->co_argcount == 2); - _PyInterpreterFrame *new_frame = _PyThreadState_BumpFramePointer(tstate, size); - if (new_frame == NULL) { - goto error; - } - CALL_STAT_INC(frames_pushed); - Py_INCREF(getitem); - _PyFrame_InitializeSpecials(new_frame, getitem, - NULL, code->co_nlocalsplus); - STACK_SHRINK(2); - new_frame->localsplus[0] = container; - new_frame->localsplus[1] = sub; - for (int i = 2; i < code->co_nlocalsplus; i++) { - new_frame->localsplus[i] = NULL; - } - _PyFrame_SetStackPointer(frame, stack_pointer); - JUMPBY(INLINE_CACHE_ENTRIES_BINARY_SUBSCR); - frame->prev_instr = next_instr - 1; - new_frame->previous = frame; - frame = cframe.current_frame = new_frame; - CALL_STAT_INC(inlined_py_calls); - goto start_frame; - } - - TARGET(LIST_APPEND) { - PyObject *v = POP(); - PyObject *list = PEEK(oparg); - if (_PyList_AppendTakeRef((PyListObject *)list, v) < 0) - goto error; - PREDICT(JUMP_BACKWARD_QUICK); - DISPATCH(); - } - - TARGET(SET_ADD) { - PyObject *v = POP(); - PyObject *set = PEEK(oparg); - int err; - err = PySet_Add(set, v); - Py_DECREF(v); - if (err != 0) - goto error; - PREDICT(JUMP_BACKWARD_QUICK); - DISPATCH(); - } - - TARGET(STORE_SUBSCR) { - PREDICTED(STORE_SUBSCR); - PyObject *sub = TOP(); - PyObject *container = SECOND(); - PyObject *v = THIRD(); - int err; - STACK_SHRINK(3); - /* container[sub] = v */ - err = PyObject_SetItem(container, sub, v); - Py_DECREF(v); - Py_DECREF(container); - Py_DECREF(sub); - if (err != 0) { - goto error; - } - JUMPBY(INLINE_CACHE_ENTRIES_STORE_SUBSCR); - DISPATCH(); - } - - TARGET(STORE_SUBSCR_ADAPTIVE) { - _PyStoreSubscrCache *cache = (_PyStoreSubscrCache *)next_instr; - if (ADAPTIVE_COUNTER_IS_ZERO(cache)) { - PyObject *sub = TOP(); - PyObject *container = SECOND(); - next_instr--; - if (_Py_Specialize_StoreSubscr(container, sub, next_instr) < 0) { - next_instr++; - goto error; - } - DISPATCH_SAME_OPARG(); - } - else { - STAT_INC(STORE_SUBSCR, deferred); - DECREMENT_ADAPTIVE_COUNTER(cache); - JUMP_TO_INSTRUCTION(STORE_SUBSCR); - } - } - - TARGET(STORE_SUBSCR_LIST_INT) { - assert(cframe.use_tracing == 0); - PyObject *sub = TOP(); - PyObject *list = SECOND(); - PyObject *value = THIRD(); - DEOPT_IF(!PyLong_CheckExact(sub), STORE_SUBSCR); - DEOPT_IF(!PyList_CheckExact(list), STORE_SUBSCR); - - // Ensure nonnegative, zero-or-one-digit ints. - DEOPT_IF(((size_t)Py_SIZE(sub)) > 1, STORE_SUBSCR); - Py_ssize_t index = ((PyLongObject*)sub)->ob_digit[0]; - // Ensure index < len(list) - DEOPT_IF(index >= PyList_GET_SIZE(list), STORE_SUBSCR); - STAT_INC(STORE_SUBSCR, hit); - - PyObject *old_value = PyList_GET_ITEM(list, index); - PyList_SET_ITEM(list, index, value); - STACK_SHRINK(3); - assert(old_value != NULL); - Py_DECREF(old_value); - _Py_DECREF_SPECIALIZED(sub, (destructor)PyObject_Free); - Py_DECREF(list); - JUMPBY(INLINE_CACHE_ENTRIES_STORE_SUBSCR); - DISPATCH(); - } - - TARGET(STORE_SUBSCR_DICT) { - assert(cframe.use_tracing == 0); - PyObject *sub = TOP(); - PyObject *dict = SECOND(); - PyObject *value = THIRD(); - DEOPT_IF(!PyDict_CheckExact(dict), STORE_SUBSCR); - STACK_SHRINK(3); - STAT_INC(STORE_SUBSCR, hit); - int err = _PyDict_SetItem_Take2((PyDictObject *)dict, sub, value); - Py_DECREF(dict); - if (err != 0) { - goto error; - } - JUMPBY(INLINE_CACHE_ENTRIES_STORE_SUBSCR); - DISPATCH(); - } - - TARGET(DELETE_SUBSCR) { - PyObject *sub = TOP(); - PyObject *container = SECOND(); - int err; - STACK_SHRINK(2); - /* del container[sub] */ - err = PyObject_DelItem(container, sub); - Py_DECREF(container); - Py_DECREF(sub); - if (err != 0) - goto error; - DISPATCH(); - } - - TARGET(PRINT_EXPR) { - PyObject *value = POP(); - PyObject *hook = _PySys_GetAttr(tstate, &_Py_ID(displayhook)); - PyObject *res; - if (hook == NULL) { - _PyErr_SetString(tstate, PyExc_RuntimeError, - "lost sys.displayhook"); - Py_DECREF(value); - goto error; - } - res = PyObject_CallOneArg(hook, value); - Py_DECREF(value); - if (res == NULL) - goto error; - Py_DECREF(res); - DISPATCH(); - } - - TARGET(RAISE_VARARGS) { - PyObject *cause = NULL, *exc = NULL; - switch (oparg) { - case 2: - cause = POP(); /* cause */ - /* fall through */ - case 1: - exc = POP(); /* exc */ - /* fall through */ - case 0: - if (do_raise(tstate, exc, cause)) { - goto exception_unwind; - } - break; - default: - _PyErr_SetString(tstate, PyExc_SystemError, - "bad RAISE_VARARGS oparg"); - break; - } - goto error; - } - - TARGET(RETURN_VALUE) { - PyObject *retval = POP(); - assert(EMPTY()); - _PyFrame_SetStackPointer(frame, stack_pointer); - TRACE_FUNCTION_EXIT(); - DTRACE_FUNCTION_EXIT(); - _Py_LeaveRecursiveCallTstate(tstate); - if (!frame->is_entry) { - // GH-99729: We need to unlink the frame *before* clearing it: - _PyInterpreterFrame *dying = frame; - frame = cframe.current_frame = dying->previous; - _PyEvalFrameClearAndPop(tstate, dying); - _PyFrame_StackPush(frame, retval); - goto resume_frame; - } - /* Restore previous cframe and return. */ - tstate->cframe = cframe.previous; - tstate->cframe->use_tracing = cframe.use_tracing; - assert(tstate->cframe->current_frame == frame->previous); - assert(!_PyErr_Occurred(tstate)); - return retval; - } - - TARGET(GET_AITER) { - unaryfunc getter = NULL; - PyObject *iter = NULL; - PyObject *obj = TOP(); - PyTypeObject *type = Py_TYPE(obj); - - if (type->tp_as_async != NULL) { - getter = type->tp_as_async->am_aiter; - } - - if (getter != NULL) { - iter = (*getter)(obj); - Py_DECREF(obj); - if (iter == NULL) { - SET_TOP(NULL); - goto error; - } - } - else { - SET_TOP(NULL); - _PyErr_Format(tstate, PyExc_TypeError, - "'async for' requires an object with " - "__aiter__ method, got %.100s", - type->tp_name); - Py_DECREF(obj); - goto error; - } - - if (Py_TYPE(iter)->tp_as_async == NULL || - Py_TYPE(iter)->tp_as_async->am_anext == NULL) { - - SET_TOP(NULL); - _PyErr_Format(tstate, PyExc_TypeError, - "'async for' received an object from __aiter__ " - "that does not implement __anext__: %.100s", - Py_TYPE(iter)->tp_name); - Py_DECREF(iter); - goto error; - } - - SET_TOP(iter); - DISPATCH(); - } - - TARGET(GET_ANEXT) { - unaryfunc getter = NULL; - PyObject *next_iter = NULL; - PyObject *awaitable = NULL; - PyObject *aiter = TOP(); - PyTypeObject *type = Py_TYPE(aiter); - - if (PyAsyncGen_CheckExact(aiter)) { - awaitable = type->tp_as_async->am_anext(aiter); - if (awaitable == NULL) { - goto error; - } - } else { - if (type->tp_as_async != NULL){ - getter = type->tp_as_async->am_anext; - } - - if (getter != NULL) { - next_iter = (*getter)(aiter); - if (next_iter == NULL) { - goto error; - } - } - else { - _PyErr_Format(tstate, PyExc_TypeError, - "'async for' requires an iterator with " - "__anext__ method, got %.100s", - type->tp_name); - goto error; - } - - awaitable = _PyCoro_GetAwaitableIter(next_iter); - if (awaitable == NULL) { - _PyErr_FormatFromCause( - PyExc_TypeError, - "'async for' received an invalid object " - "from __anext__: %.100s", - Py_TYPE(next_iter)->tp_name); - - Py_DECREF(next_iter); - goto error; - } else { - Py_DECREF(next_iter); - } - } - - PUSH(awaitable); - PREDICT(LOAD_CONST); - DISPATCH(); - } - - TARGET(GET_AWAITABLE) { - PREDICTED(GET_AWAITABLE); - PyObject *iterable = TOP(); - PyObject *iter = _PyCoro_GetAwaitableIter(iterable); - - if (iter == NULL) { - format_awaitable_error(tstate, Py_TYPE(iterable), oparg); - } - - Py_DECREF(iterable); - - if (iter != NULL && PyCoro_CheckExact(iter)) { - PyObject *yf = _PyGen_yf((PyGenObject*)iter); - if (yf != NULL) { - /* `iter` is a coroutine object that is being - awaited, `yf` is a pointer to the current awaitable - being awaited on. */ - Py_DECREF(yf); - Py_CLEAR(iter); - _PyErr_SetString(tstate, PyExc_RuntimeError, - "coroutine is being awaited already"); - /* The code below jumps to `error` if `iter` is NULL. */ - } - } - - SET_TOP(iter); /* Even if it's NULL */ - - if (iter == NULL) { - goto error; - } - - PREDICT(LOAD_CONST); - DISPATCH(); - } - - TARGET(SEND) { - assert(frame->is_entry); - assert(STACK_LEVEL() >= 2); - PyObject *v = POP(); - PyObject *receiver = TOP(); - PySendResult gen_status; - PyObject *retval; - if (tstate->c_tracefunc == NULL) { - gen_status = PyIter_Send(receiver, v, &retval); - } else { - if (Py_IsNone(v) && PyIter_Check(receiver)) { - retval = Py_TYPE(receiver)->tp_iternext(receiver); - } - else { - retval = PyObject_CallMethodOneArg(receiver, &_Py_ID(send), v); - } - if (retval == NULL) { - if (tstate->c_tracefunc != NULL - && _PyErr_ExceptionMatches(tstate, PyExc_StopIteration)) - call_exc_trace(tstate->c_tracefunc, tstate->c_traceobj, tstate, frame); - if (_PyGen_FetchStopIterationValue(&retval) == 0) { - gen_status = PYGEN_RETURN; - } - else { - gen_status = PYGEN_ERROR; - } - } - else { - gen_status = PYGEN_NEXT; - } - } - Py_DECREF(v); - if (gen_status == PYGEN_ERROR) { - assert(retval == NULL); - goto error; - } - if (gen_status == PYGEN_RETURN) { - assert(retval != NULL); - Py_DECREF(receiver); - SET_TOP(retval); - JUMPBY(oparg); - DISPATCH(); - } - assert(gen_status == PYGEN_NEXT); - assert(retval != NULL); - PUSH(retval); - DISPATCH(); - } - - TARGET(ASYNC_GEN_WRAP) { - PyObject *v = TOP(); - assert(frame->f_code->co_flags & CO_ASYNC_GENERATOR); - PyObject *w = _PyAsyncGenValueWrapperNew(v); - if (w == NULL) { - goto error; - } - SET_TOP(w); - Py_DECREF(v); - DISPATCH(); - } - - TARGET(YIELD_VALUE) { - assert(frame->is_entry); - PyObject *retval = POP(); - _PyFrame_GetGenerator(frame)->gi_frame_state = FRAME_SUSPENDED; - _PyFrame_SetStackPointer(frame, stack_pointer); - TRACE_FUNCTION_EXIT(); - DTRACE_FUNCTION_EXIT(); - _Py_LeaveRecursiveCallTstate(tstate); - /* Restore previous cframe and return. */ - tstate->cframe = cframe.previous; - tstate->cframe->use_tracing = cframe.use_tracing; - assert(tstate->cframe->current_frame == frame->previous); - assert(!_PyErr_Occurred(tstate)); - return retval; - } - - TARGET(POP_EXCEPT) { - _PyErr_StackItem *exc_info = tstate->exc_info; - PyObject *value = exc_info->exc_value; - exc_info->exc_value = POP(); - Py_XDECREF(value); - DISPATCH(); - } - - TARGET(RERAISE) { - if (oparg) { - PyObject *lasti = PEEK(oparg + 1); - if (PyLong_Check(lasti)) { - frame->prev_instr = first_instr + PyLong_AsLong(lasti); - assert(!_PyErr_Occurred(tstate)); - } - else { - assert(PyLong_Check(lasti)); - _PyErr_SetString(tstate, PyExc_SystemError, "lasti is not an int"); - goto error; - } - } - PyObject *val = POP(); - assert(val && PyExceptionInstance_Check(val)); - PyObject *exc = Py_NewRef(PyExceptionInstance_Class(val)); - PyObject *tb = PyException_GetTraceback(val); - _PyErr_Restore(tstate, exc, val, tb); - goto exception_unwind; - } - - TARGET(PREP_RERAISE_STAR) { - PyObject *excs = POP(); - assert(PyList_Check(excs)); - PyObject *orig = POP(); - - PyObject *val = _PyExc_PrepReraiseStar(orig, excs); - Py_DECREF(excs); - Py_DECREF(orig); - - if (val == NULL) { - goto error; - } - - PUSH(val); - DISPATCH(); - } - - TARGET(END_ASYNC_FOR) { - PyObject *val = POP(); - assert(val && PyExceptionInstance_Check(val)); - if (PyErr_GivenExceptionMatches(val, PyExc_StopAsyncIteration)) { - Py_DECREF(val); - Py_DECREF(POP()); - DISPATCH(); - } - else { - PyObject *exc = Py_NewRef(PyExceptionInstance_Class(val)); - PyObject *tb = PyException_GetTraceback(val); - _PyErr_Restore(tstate, exc, val, tb); - goto exception_unwind; - } - } - - TARGET(LOAD_ASSERTION_ERROR) { - PyObject *value = PyExc_AssertionError; - Py_INCREF(value); - PUSH(value); - DISPATCH(); - } - - TARGET(LOAD_BUILD_CLASS) { - PyObject *bc; - if (PyDict_CheckExact(BUILTINS())) { - bc = _PyDict_GetItemWithError(BUILTINS(), - &_Py_ID(__build_class__)); - if (bc == NULL) { - if (!_PyErr_Occurred(tstate)) { - _PyErr_SetString(tstate, PyExc_NameError, - "__build_class__ not found"); - } - goto error; - } - Py_INCREF(bc); - } - else { - bc = PyObject_GetItem(BUILTINS(), &_Py_ID(__build_class__)); - if (bc == NULL) { - if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) - _PyErr_SetString(tstate, PyExc_NameError, - "__build_class__ not found"); - goto error; - } - } - PUSH(bc); - DISPATCH(); - } - - TARGET(STORE_NAME) { - PyObject *name = GETITEM(names, oparg); - PyObject *v = POP(); - PyObject *ns = LOCALS(); - int err; - if (ns == NULL) { - _PyErr_Format(tstate, PyExc_SystemError, - "no locals found when storing %R", name); - Py_DECREF(v); - goto error; - } - if (PyDict_CheckExact(ns)) - err = PyDict_SetItem(ns, name, v); - else - err = PyObject_SetItem(ns, name, v); - Py_DECREF(v); - if (err != 0) - goto error; - DISPATCH(); - } - - TARGET(DELETE_NAME) { - PyObject *name = GETITEM(names, oparg); - PyObject *ns = LOCALS(); - int err; - if (ns == NULL) { - _PyErr_Format(tstate, PyExc_SystemError, - "no locals when deleting %R", name); - goto error; - } - err = PyObject_DelItem(ns, name); - if (err != 0) { - format_exc_check_arg(tstate, PyExc_NameError, - NAME_ERROR_MSG, - name); - goto error; - } - DISPATCH(); - } - - TARGET(UNPACK_SEQUENCE) { - PREDICTED(UNPACK_SEQUENCE); - PyObject *seq = POP(); - PyObject **top = stack_pointer + oparg; - if (!unpack_iterable(tstate, seq, oparg, -1, top)) { - Py_DECREF(seq); - goto error; - } - STACK_GROW(oparg); - Py_DECREF(seq); - JUMPBY(INLINE_CACHE_ENTRIES_UNPACK_SEQUENCE); - DISPATCH(); - } - - TARGET(UNPACK_SEQUENCE_ADAPTIVE) { - assert(cframe.use_tracing == 0); - _PyUnpackSequenceCache *cache = (_PyUnpackSequenceCache *)next_instr; - if (ADAPTIVE_COUNTER_IS_ZERO(cache)) { - PyObject *seq = TOP(); - next_instr--; - _Py_Specialize_UnpackSequence(seq, next_instr, oparg); - DISPATCH_SAME_OPARG(); - } - else { - STAT_INC(UNPACK_SEQUENCE, deferred); - DECREMENT_ADAPTIVE_COUNTER(cache); - JUMP_TO_INSTRUCTION(UNPACK_SEQUENCE); - } - } - - TARGET(UNPACK_SEQUENCE_TWO_TUPLE) { - PyObject *seq = TOP(); - DEOPT_IF(!PyTuple_CheckExact(seq), UNPACK_SEQUENCE); - DEOPT_IF(PyTuple_GET_SIZE(seq) != 2, UNPACK_SEQUENCE); - STAT_INC(UNPACK_SEQUENCE, hit); - SET_TOP(Py_NewRef(PyTuple_GET_ITEM(seq, 1))); - PUSH(Py_NewRef(PyTuple_GET_ITEM(seq, 0))); - Py_DECREF(seq); - JUMPBY(INLINE_CACHE_ENTRIES_UNPACK_SEQUENCE); - DISPATCH(); - } - - TARGET(UNPACK_SEQUENCE_TUPLE) { - PyObject *seq = TOP(); - DEOPT_IF(!PyTuple_CheckExact(seq), UNPACK_SEQUENCE); - DEOPT_IF(PyTuple_GET_SIZE(seq) != oparg, UNPACK_SEQUENCE); - STAT_INC(UNPACK_SEQUENCE, hit); - STACK_SHRINK(1); - PyObject **items = _PyTuple_ITEMS(seq); - while (oparg--) { - PUSH(Py_NewRef(items[oparg])); - } - Py_DECREF(seq); - JUMPBY(INLINE_CACHE_ENTRIES_UNPACK_SEQUENCE); - DISPATCH(); - } - - TARGET(UNPACK_SEQUENCE_LIST) { - PyObject *seq = TOP(); - DEOPT_IF(!PyList_CheckExact(seq), UNPACK_SEQUENCE); - DEOPT_IF(PyList_GET_SIZE(seq) != oparg, UNPACK_SEQUENCE); - STAT_INC(UNPACK_SEQUENCE, hit); - STACK_SHRINK(1); - PyObject **items = _PyList_ITEMS(seq); - while (oparg--) { - PUSH(Py_NewRef(items[oparg])); - } - Py_DECREF(seq); - JUMPBY(INLINE_CACHE_ENTRIES_UNPACK_SEQUENCE); - DISPATCH(); - } - - TARGET(UNPACK_EX) { - int totalargs = 1 + (oparg & 0xFF) + (oparg >> 8); - PyObject *seq = POP(); - PyObject **top = stack_pointer + totalargs; - if (!unpack_iterable(tstate, seq, oparg & 0xFF, oparg >> 8, top)) { - Py_DECREF(seq); - goto error; - } - STACK_GROW(totalargs); - Py_DECREF(seq); - DISPATCH(); - } - - TARGET(STORE_ATTR) { - PREDICTED(STORE_ATTR); - PyObject *name = GETITEM(names, oparg); - PyObject *owner = TOP(); - PyObject *v = SECOND(); - int err; - STACK_SHRINK(2); - err = PyObject_SetAttr(owner, name, v); - Py_DECREF(v); - Py_DECREF(owner); - if (err != 0) { - goto error; - } - JUMPBY(INLINE_CACHE_ENTRIES_STORE_ATTR); - DISPATCH(); - } - - TARGET(DELETE_ATTR) { - PyObject *name = GETITEM(names, oparg); - PyObject *owner = POP(); - int err; - err = PyObject_SetAttr(owner, name, (PyObject *)NULL); - Py_DECREF(owner); - if (err != 0) - goto error; - DISPATCH(); - } - - TARGET(STORE_GLOBAL) { - PyObject *name = GETITEM(names, oparg); - PyObject *v = POP(); - int err; - err = PyDict_SetItem(GLOBALS(), name, v); - Py_DECREF(v); - if (err != 0) - goto error; - DISPATCH(); - } - - TARGET(DELETE_GLOBAL) { - PyObject *name = GETITEM(names, oparg); - int err; - err = PyDict_DelItem(GLOBALS(), name); - if (err != 0) { - if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { - format_exc_check_arg(tstate, PyExc_NameError, - NAME_ERROR_MSG, name); - } - goto error; - } - DISPATCH(); - } - - TARGET(LOAD_NAME) { - PyObject *name = GETITEM(names, oparg); - PyObject *locals = LOCALS(); - PyObject *v; - if (locals == NULL) { - _PyErr_Format(tstate, PyExc_SystemError, - "no locals when loading %R", name); - goto error; - } - if (PyDict_CheckExact(locals)) { - v = PyDict_GetItemWithError(locals, name); - if (v != NULL) { - Py_INCREF(v); - } - else if (_PyErr_Occurred(tstate)) { - goto error; - } - } - else { - v = PyObject_GetItem(locals, name); - if (v == NULL) { - if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) - goto error; - _PyErr_Clear(tstate); - } - } - if (v == NULL) { - v = PyDict_GetItemWithError(GLOBALS(), name); - if (v != NULL) { - Py_INCREF(v); - } - else if (_PyErr_Occurred(tstate)) { - goto error; - } - else { - if (PyDict_CheckExact(BUILTINS())) { - v = PyDict_GetItemWithError(BUILTINS(), name); - if (v == NULL) { - if (!_PyErr_Occurred(tstate)) { - format_exc_check_arg( - tstate, PyExc_NameError, - NAME_ERROR_MSG, name); - } - goto error; - } - Py_INCREF(v); - } - else { - v = PyObject_GetItem(BUILTINS(), name); - if (v == NULL) { - if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { - format_exc_check_arg( - tstate, PyExc_NameError, - NAME_ERROR_MSG, name); - } - goto error; - } - } - } - } - PUSH(v); - DISPATCH(); - } - - TARGET(LOAD_GLOBAL) { - PREDICTED(LOAD_GLOBAL); - int push_null = oparg & 1; - PEEK(0) = NULL; - PyObject *name = GETITEM(names, oparg>>1); - PyObject *v; - if (PyDict_CheckExact(GLOBALS()) - && PyDict_CheckExact(BUILTINS())) - { - v = _PyDict_LoadGlobal((PyDictObject *)GLOBALS(), - (PyDictObject *)BUILTINS(), - name); - if (v == NULL) { - if (!_PyErr_Occurred(tstate)) { - /* _PyDict_LoadGlobal() returns NULL without raising - * an exception if the key doesn't exist */ - format_exc_check_arg(tstate, PyExc_NameError, - NAME_ERROR_MSG, name); - } - goto error; - } - Py_INCREF(v); - } - else { - /* Slow-path if globals or builtins is not a dict */ - - /* namespace 1: globals */ - v = PyObject_GetItem(GLOBALS(), name); - if (v == NULL) { - if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { - goto error; - } - _PyErr_Clear(tstate); - - /* namespace 2: builtins */ - v = PyObject_GetItem(BUILTINS(), name); - if (v == NULL) { - if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { - format_exc_check_arg( - tstate, PyExc_NameError, - NAME_ERROR_MSG, name); - } - goto error; - } - } - } - /* Skip over inline cache */ - JUMPBY(INLINE_CACHE_ENTRIES_LOAD_GLOBAL); - STACK_GROW(push_null); - PUSH(v); - DISPATCH(); - } - - TARGET(LOAD_GLOBAL_ADAPTIVE) { - assert(cframe.use_tracing == 0); - _PyLoadGlobalCache *cache = (_PyLoadGlobalCache *)next_instr; - if (ADAPTIVE_COUNTER_IS_ZERO(cache)) { - PyObject *name = GETITEM(names, oparg>>1); - next_instr--; - if (_Py_Specialize_LoadGlobal(GLOBALS(), BUILTINS(), next_instr, name) < 0) { - next_instr++; - goto error; - } - DISPATCH_SAME_OPARG(); - } - else { - STAT_INC(LOAD_GLOBAL, deferred); - DECREMENT_ADAPTIVE_COUNTER(cache); - JUMP_TO_INSTRUCTION(LOAD_GLOBAL); - } - } - - TARGET(LOAD_GLOBAL_MODULE) { - assert(cframe.use_tracing == 0); - DEOPT_IF(!PyDict_CheckExact(GLOBALS()), LOAD_GLOBAL); - PyDictObject *dict = (PyDictObject *)GLOBALS(); - _PyLoadGlobalCache *cache = (_PyLoadGlobalCache *)next_instr; - uint32_t version = read_u32(cache->module_keys_version); - DEOPT_IF(dict->ma_keys->dk_version != version, LOAD_GLOBAL); - assert(DK_IS_UNICODE(dict->ma_keys)); - PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(dict->ma_keys); - PyObject *res = entries[cache->index].me_value; - DEOPT_IF(res == NULL, LOAD_GLOBAL); - int push_null = oparg & 1; - PEEK(0) = NULL; - JUMPBY(INLINE_CACHE_ENTRIES_LOAD_GLOBAL); - STAT_INC(LOAD_GLOBAL, hit); - STACK_GROW(push_null+1); - Py_INCREF(res); - SET_TOP(res); - DISPATCH(); - } - - TARGET(LOAD_GLOBAL_BUILTIN) { - assert(cframe.use_tracing == 0); - DEOPT_IF(!PyDict_CheckExact(GLOBALS()), LOAD_GLOBAL); - DEOPT_IF(!PyDict_CheckExact(BUILTINS()), LOAD_GLOBAL); - PyDictObject *mdict = (PyDictObject *)GLOBALS(); - PyDictObject *bdict = (PyDictObject *)BUILTINS(); - _PyLoadGlobalCache *cache = (_PyLoadGlobalCache *)next_instr; - uint32_t mod_version = read_u32(cache->module_keys_version); - uint16_t bltn_version = cache->builtin_keys_version; - DEOPT_IF(mdict->ma_keys->dk_version != mod_version, LOAD_GLOBAL); - DEOPT_IF(bdict->ma_keys->dk_version != bltn_version, LOAD_GLOBAL); - assert(DK_IS_UNICODE(bdict->ma_keys)); - PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(bdict->ma_keys); - PyObject *res = entries[cache->index].me_value; - DEOPT_IF(res == NULL, LOAD_GLOBAL); - int push_null = oparg & 1; - PEEK(0) = NULL; - JUMPBY(INLINE_CACHE_ENTRIES_LOAD_GLOBAL); - STAT_INC(LOAD_GLOBAL, hit); - STACK_GROW(push_null+1); - Py_INCREF(res); - SET_TOP(res); - DISPATCH(); - } - - TARGET(DELETE_FAST) { - PyObject *v = GETLOCAL(oparg); - if (v != NULL) { - SETLOCAL(oparg, NULL); - DISPATCH(); - } - goto unbound_local_error; - } - - TARGET(MAKE_CELL) { - // "initial" is probably NULL but not if it's an arg (or set - // via PyFrame_LocalsToFast() before MAKE_CELL has run). - PyObject *initial = GETLOCAL(oparg); - PyObject *cell = PyCell_New(initial); - if (cell == NULL) { - goto resume_with_error; - } - SETLOCAL(oparg, cell); - DISPATCH(); - } - - TARGET(DELETE_DEREF) { - PyObject *cell = GETLOCAL(oparg); - PyObject *oldobj = PyCell_GET(cell); - if (oldobj != NULL) { - PyCell_SET(cell, NULL); - Py_DECREF(oldobj); - DISPATCH(); - } - format_exc_unbound(tstate, frame->f_code, oparg); - goto error; - } - - TARGET(LOAD_CLASSDEREF) { - PyObject *name, *value, *locals = LOCALS(); - assert(locals); - assert(oparg >= 0 && oparg < frame->f_code->co_nlocalsplus); - name = PyTuple_GET_ITEM(frame->f_code->co_localsplusnames, oparg); - if (PyDict_CheckExact(locals)) { - value = PyDict_GetItemWithError(locals, name); - if (value != NULL) { - Py_INCREF(value); - } - else if (_PyErr_Occurred(tstate)) { - goto error; - } - } - else { - value = PyObject_GetItem(locals, name); - if (value == NULL) { - if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { - goto error; - } - _PyErr_Clear(tstate); - } - } - if (!value) { - PyObject *cell = GETLOCAL(oparg); - value = PyCell_GET(cell); - if (value == NULL) { - format_exc_unbound(tstate, frame->f_code, oparg); - goto error; - } - Py_INCREF(value); - } - PUSH(value); - DISPATCH(); - } - - TARGET(LOAD_DEREF) { - PyObject *cell = GETLOCAL(oparg); - PyObject *value = PyCell_GET(cell); - if (value == NULL) { - format_exc_unbound(tstate, frame->f_code, oparg); - goto error; - } - Py_INCREF(value); - PUSH(value); - DISPATCH(); - } - - TARGET(STORE_DEREF) { - PyObject *v = POP(); - PyObject *cell = GETLOCAL(oparg); - PyObject *oldobj = PyCell_GET(cell); - PyCell_SET(cell, v); - Py_XDECREF(oldobj); - DISPATCH(); - } - - TARGET(COPY_FREE_VARS) { - /* Copy closure variables to free variables */ - PyCodeObject *co = frame->f_code; - PyObject *closure = frame->f_func->func_closure; - int offset = co->co_nlocals + co->co_nplaincellvars; - assert(oparg == co->co_nfreevars); - for (int i = 0; i < oparg; ++i) { - PyObject *o = PyTuple_GET_ITEM(closure, i); - Py_INCREF(o); - frame->localsplus[offset + i] = o; - } - DISPATCH(); - } - - TARGET(BUILD_STRING) { - PyObject *str; - str = _PyUnicode_JoinArray(&_Py_STR(empty), - stack_pointer - oparg, oparg); - if (str == NULL) - goto error; - while (--oparg >= 0) { - PyObject *item = POP(); - Py_DECREF(item); - } - PUSH(str); - DISPATCH(); - } - - TARGET(BUILD_TUPLE) { - PyObject *tup = PyTuple_New(oparg); - if (tup == NULL) - goto error; - while (--oparg >= 0) { - PyObject *item = POP(); - PyTuple_SET_ITEM(tup, oparg, item); - } - PUSH(tup); - DISPATCH(); - } - - TARGET(BUILD_LIST) { - PyObject *list = PyList_New(oparg); - if (list == NULL) - goto error; - while (--oparg >= 0) { - PyObject *item = POP(); - PyList_SET_ITEM(list, oparg, item); - } - PUSH(list); - DISPATCH(); - } - - TARGET(LIST_TO_TUPLE) { - PyObject *list = POP(); - PyObject *tuple = PyList_AsTuple(list); - Py_DECREF(list); - if (tuple == NULL) { - goto error; - } - PUSH(tuple); - DISPATCH(); - } - - TARGET(LIST_EXTEND) { - PyObject *iterable = POP(); - PyObject *list = PEEK(oparg); - PyObject *none_val = _PyList_Extend((PyListObject *)list, iterable); - if (none_val == NULL) { - if (_PyErr_ExceptionMatches(tstate, PyExc_TypeError) && - (Py_TYPE(iterable)->tp_iter == NULL && !PySequence_Check(iterable))) - { - _PyErr_Clear(tstate); - _PyErr_Format(tstate, PyExc_TypeError, - "Value after * must be an iterable, not %.200s", - Py_TYPE(iterable)->tp_name); - } - Py_DECREF(iterable); - goto error; - } - Py_DECREF(none_val); - Py_DECREF(iterable); - DISPATCH(); - } - - TARGET(SET_UPDATE) { - PyObject *iterable = POP(); - PyObject *set = PEEK(oparg); - int err = _PySet_Update(set, iterable); - Py_DECREF(iterable); - if (err < 0) { - goto error; - } - DISPATCH(); - } - - TARGET(BUILD_SET) { - PyObject *set = PySet_New(NULL); - int err = 0; - int i; - if (set == NULL) - goto error; - for (i = oparg; i > 0; i--) { - PyObject *item = PEEK(i); - if (err == 0) - err = PySet_Add(set, item); - Py_DECREF(item); - } - STACK_SHRINK(oparg); - if (err != 0) { - Py_DECREF(set); - goto error; - } - PUSH(set); - DISPATCH(); - } - - TARGET(BUILD_MAP) { - PyObject *map = _PyDict_FromItems( - &PEEK(2*oparg), 2, - &PEEK(2*oparg - 1), 2, - oparg); - if (map == NULL) - goto error; - - while (oparg--) { - Py_DECREF(POP()); - Py_DECREF(POP()); - } - PUSH(map); - DISPATCH(); - } - - TARGET(SETUP_ANNOTATIONS) { - int err; - PyObject *ann_dict; - if (LOCALS() == NULL) { - _PyErr_Format(tstate, PyExc_SystemError, - "no locals found when setting up annotations"); - goto error; - } - /* check if __annotations__ in locals()... */ - if (PyDict_CheckExact(LOCALS())) { - ann_dict = _PyDict_GetItemWithError(LOCALS(), - &_Py_ID(__annotations__)); - if (ann_dict == NULL) { - if (_PyErr_Occurred(tstate)) { - goto error; - } - /* ...if not, create a new one */ - ann_dict = PyDict_New(); - if (ann_dict == NULL) { - goto error; - } - err = PyDict_SetItem(LOCALS(), &_Py_ID(__annotations__), - ann_dict); - Py_DECREF(ann_dict); - if (err != 0) { - goto error; - } - } - } - else { - /* do the same if locals() is not a dict */ - ann_dict = PyObject_GetItem(LOCALS(), &_Py_ID(__annotations__)); - if (ann_dict == NULL) { - if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { - goto error; - } - _PyErr_Clear(tstate); - ann_dict = PyDict_New(); - if (ann_dict == NULL) { - goto error; - } - err = PyObject_SetItem(LOCALS(), &_Py_ID(__annotations__), - ann_dict); - Py_DECREF(ann_dict); - if (err != 0) { - goto error; - } - } - else { - Py_DECREF(ann_dict); - } - } - DISPATCH(); - } - - TARGET(BUILD_CONST_KEY_MAP) { - PyObject *map; - PyObject *keys = TOP(); - if (!PyTuple_CheckExact(keys) || - PyTuple_GET_SIZE(keys) != (Py_ssize_t)oparg) { - _PyErr_SetString(tstate, PyExc_SystemError, - "bad BUILD_CONST_KEY_MAP keys argument"); - goto error; - } - map = _PyDict_FromItems( - &PyTuple_GET_ITEM(keys, 0), 1, - &PEEK(oparg + 1), 1, oparg); - if (map == NULL) { - goto error; - } - - Py_DECREF(POP()); - while (oparg--) { - Py_DECREF(POP()); - } - PUSH(map); - DISPATCH(); - } - - TARGET(DICT_UPDATE) { - PyObject *update = POP(); - PyObject *dict = PEEK(oparg); - if (PyDict_Update(dict, update) < 0) { - if (_PyErr_ExceptionMatches(tstate, PyExc_AttributeError)) { - _PyErr_Format(tstate, PyExc_TypeError, - "'%.200s' object is not a mapping", - Py_TYPE(update)->tp_name); - } - Py_DECREF(update); - goto error; - } - Py_DECREF(update); - DISPATCH(); - } - - TARGET(DICT_MERGE) { - PyObject *update = POP(); - PyObject *dict = PEEK(oparg); - - if (_PyDict_MergeEx(dict, update, 2) < 0) { - format_kwargs_error(tstate, PEEK(2 + oparg), update); - Py_DECREF(update); - goto error; - } - Py_DECREF(update); - PREDICT(CALL_FUNCTION_EX); - DISPATCH(); - } - - TARGET(MAP_ADD) { - PyObject *value = TOP(); - PyObject *key = SECOND(); - PyObject *map; - STACK_SHRINK(2); - map = PEEK(oparg); /* dict */ - assert(PyDict_CheckExact(map)); - /* map[key] = value */ - if (_PyDict_SetItem_Take2((PyDictObject *)map, key, value) != 0) { - goto error; - } - PREDICT(JUMP_BACKWARD_QUICK); - DISPATCH(); - } - - TARGET(LOAD_ATTR) { - PREDICTED(LOAD_ATTR); - PyObject *name = GETITEM(names, oparg); - PyObject *owner = TOP(); - PyObject *res = PyObject_GetAttr(owner, name); - if (res == NULL) { - goto error; - } - Py_DECREF(owner); - SET_TOP(res); - JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); - DISPATCH(); - } - - TARGET(LOAD_ATTR_ADAPTIVE) { - assert(cframe.use_tracing == 0); - _PyAttrCache *cache = (_PyAttrCache *)next_instr; - if (ADAPTIVE_COUNTER_IS_ZERO(cache)) { - PyObject *owner = TOP(); - PyObject *name = GETITEM(names, oparg); - next_instr--; - if (_Py_Specialize_LoadAttr(owner, next_instr, name) < 0) { - next_instr++; - goto error; - } - DISPATCH_SAME_OPARG(); - } - else { - STAT_INC(LOAD_ATTR, deferred); - DECREMENT_ADAPTIVE_COUNTER(cache); - JUMP_TO_INSTRUCTION(LOAD_ATTR); - } - } - - TARGET(LOAD_ATTR_INSTANCE_VALUE) { - assert(cframe.use_tracing == 0); - PyObject *owner = TOP(); - PyObject *res; - PyTypeObject *tp = Py_TYPE(owner); - _PyAttrCache *cache = (_PyAttrCache *)next_instr; - uint32_t type_version = read_u32(cache->version); - assert(type_version != 0); - DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR); - assert(tp->tp_dictoffset < 0); - assert(tp->tp_flags & Py_TPFLAGS_MANAGED_DICT); - PyDictValues *values = *_PyObject_ValuesPointer(owner); - DEOPT_IF(values == NULL, LOAD_ATTR); - res = values->values[cache->index]; - DEOPT_IF(res == NULL, LOAD_ATTR); - STAT_INC(LOAD_ATTR, hit); - Py_INCREF(res); - SET_TOP(res); - Py_DECREF(owner); - JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); - DISPATCH(); - } - - TARGET(LOAD_ATTR_MODULE) { - assert(cframe.use_tracing == 0); - // shared with LOAD_METHOD_MODULE - PyObject *owner = TOP(); - PyObject *res; - LOAD_MODULE_ATTR_OR_METHOD(ATTR); - SET_TOP(res); - Py_DECREF(owner); - JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); - DISPATCH(); - } - - TARGET(LOAD_ATTR_WITH_HINT) { - assert(cframe.use_tracing == 0); - PyObject *owner = TOP(); - PyObject *res; - PyTypeObject *tp = Py_TYPE(owner); - _PyAttrCache *cache = (_PyAttrCache *)next_instr; - uint32_t type_version = read_u32(cache->version); - assert(type_version != 0); - DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR); - assert(tp->tp_flags & Py_TPFLAGS_MANAGED_DICT); - PyDictObject *dict = *(PyDictObject **)_PyObject_ManagedDictPointer(owner); - DEOPT_IF(dict == NULL, LOAD_ATTR); - assert(PyDict_CheckExact((PyObject *)dict)); - PyObject *name = GETITEM(names, oparg); - uint16_t hint = cache->index; - DEOPT_IF(hint >= (size_t)dict->ma_keys->dk_nentries, LOAD_ATTR); - if (DK_IS_UNICODE(dict->ma_keys)) { - PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(dict->ma_keys) + hint; - DEOPT_IF(ep->me_key != name, LOAD_ATTR); - res = ep->me_value; - } - else { - PyDictKeyEntry *ep = DK_ENTRIES(dict->ma_keys) + hint; - DEOPT_IF(ep->me_key != name, LOAD_ATTR); - res = ep->me_value; - } - DEOPT_IF(res == NULL, LOAD_ATTR); - STAT_INC(LOAD_ATTR, hit); - Py_INCREF(res); - SET_TOP(res); - Py_DECREF(owner); - JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); - DISPATCH(); - } - - TARGET(LOAD_ATTR_SLOT) { - assert(cframe.use_tracing == 0); - PyObject *owner = TOP(); - PyObject *res; - PyTypeObject *tp = Py_TYPE(owner); - _PyAttrCache *cache = (_PyAttrCache *)next_instr; - uint32_t type_version = read_u32(cache->version); - assert(type_version != 0); - DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR); - char *addr = (char *)owner + cache->index; - res = *(PyObject **)addr; - DEOPT_IF(res == NULL, LOAD_ATTR); - STAT_INC(LOAD_ATTR, hit); - Py_INCREF(res); - SET_TOP(res); - Py_DECREF(owner); - JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); - DISPATCH(); - } - - TARGET(STORE_ATTR_ADAPTIVE) { - assert(cframe.use_tracing == 0); - _PyAttrCache *cache = (_PyAttrCache *)next_instr; - if (ADAPTIVE_COUNTER_IS_ZERO(cache)) { - PyObject *owner = TOP(); - PyObject *name = GETITEM(names, oparg); - next_instr--; - if (_Py_Specialize_StoreAttr(owner, next_instr, name) < 0) { - next_instr++; - goto error; - } - DISPATCH_SAME_OPARG(); - } - else { - STAT_INC(STORE_ATTR, deferred); - DECREMENT_ADAPTIVE_COUNTER(cache); - JUMP_TO_INSTRUCTION(STORE_ATTR); - } - } - - TARGET(STORE_ATTR_INSTANCE_VALUE) { - assert(cframe.use_tracing == 0); - PyObject *owner = TOP(); - PyTypeObject *tp = Py_TYPE(owner); - _PyAttrCache *cache = (_PyAttrCache *)next_instr; - uint32_t type_version = read_u32(cache->version); - assert(type_version != 0); - DEOPT_IF(tp->tp_version_tag != type_version, STORE_ATTR); - assert(tp->tp_flags & Py_TPFLAGS_MANAGED_DICT); - PyDictValues *values = *_PyObject_ValuesPointer(owner); - DEOPT_IF(values == NULL, STORE_ATTR); - STAT_INC(STORE_ATTR, hit); - Py_ssize_t index = cache->index; - STACK_SHRINK(1); - PyObject *value = POP(); - PyObject *old_value = values->values[index]; - values->values[index] = value; - if (old_value == NULL) { - _PyDictValues_AddToInsertionOrder(values, index); - } - else { - Py_DECREF(old_value); - } - Py_DECREF(owner); - JUMPBY(INLINE_CACHE_ENTRIES_STORE_ATTR); - DISPATCH(); - } - - TARGET(STORE_ATTR_WITH_HINT) { - assert(cframe.use_tracing == 0); - PyObject *owner = TOP(); - PyTypeObject *tp = Py_TYPE(owner); - _PyAttrCache *cache = (_PyAttrCache *)next_instr; - uint32_t type_version = read_u32(cache->version); - assert(type_version != 0); - DEOPT_IF(tp->tp_version_tag != type_version, STORE_ATTR); - assert(tp->tp_flags & Py_TPFLAGS_MANAGED_DICT); - PyDictObject *dict = *(PyDictObject **)_PyObject_ManagedDictPointer(owner); - DEOPT_IF(dict == NULL, STORE_ATTR); - assert(PyDict_CheckExact((PyObject *)dict)); - PyObject *name = GETITEM(names, oparg); - uint16_t hint = cache->index; - DEOPT_IF(hint >= (size_t)dict->ma_keys->dk_nentries, STORE_ATTR); - PyObject *value, *old_value; - if (DK_IS_UNICODE(dict->ma_keys)) { - PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(dict->ma_keys) + hint; - DEOPT_IF(ep->me_key != name, STORE_ATTR); - old_value = ep->me_value; - DEOPT_IF(old_value == NULL, STORE_ATTR); - STACK_SHRINK(1); - value = POP(); - ep->me_value = value; - } - else { - PyDictKeyEntry *ep = DK_ENTRIES(dict->ma_keys) + hint; - DEOPT_IF(ep->me_key != name, STORE_ATTR); - old_value = ep->me_value; - DEOPT_IF(old_value == NULL, STORE_ATTR); - STACK_SHRINK(1); - value = POP(); - ep->me_value = value; - } - Py_DECREF(old_value); - STAT_INC(STORE_ATTR, hit); - /* Ensure dict is GC tracked if it needs to be */ - if (!_PyObject_GC_IS_TRACKED(dict) && _PyObject_GC_MAY_BE_TRACKED(value)) { - _PyObject_GC_TRACK(dict); - } - /* PEP 509 */ - dict->ma_version_tag = DICT_NEXT_VERSION(); - Py_DECREF(owner); - JUMPBY(INLINE_CACHE_ENTRIES_STORE_ATTR); - DISPATCH(); - } - - TARGET(STORE_ATTR_SLOT) { - assert(cframe.use_tracing == 0); - PyObject *owner = TOP(); - PyTypeObject *tp = Py_TYPE(owner); - _PyAttrCache *cache = (_PyAttrCache *)next_instr; - uint32_t type_version = read_u32(cache->version); - assert(type_version != 0); - DEOPT_IF(tp->tp_version_tag != type_version, STORE_ATTR); - char *addr = (char *)owner + cache->index; - STAT_INC(STORE_ATTR, hit); - STACK_SHRINK(1); - PyObject *value = POP(); - PyObject *old_value = *(PyObject **)addr; - *(PyObject **)addr = value; - Py_XDECREF(old_value); - Py_DECREF(owner); - JUMPBY(INLINE_CACHE_ENTRIES_STORE_ATTR); - DISPATCH(); - } - - TARGET(COMPARE_OP) { - PREDICTED(COMPARE_OP); - assert(oparg <= Py_GE); - PyObject *right = POP(); - PyObject *left = TOP(); - PyObject *res = PyObject_RichCompare(left, right, oparg); - SET_TOP(res); - Py_DECREF(left); - Py_DECREF(right); - if (res == NULL) { - goto error; - } - JUMPBY(INLINE_CACHE_ENTRIES_COMPARE_OP); - DISPATCH(); - } - - TARGET(COMPARE_OP_ADAPTIVE) { - assert(cframe.use_tracing == 0); - _PyCompareOpCache *cache = (_PyCompareOpCache *)next_instr; - if (ADAPTIVE_COUNTER_IS_ZERO(cache)) { - PyObject *right = TOP(); - PyObject *left = SECOND(); - next_instr--; - _Py_Specialize_CompareOp(left, right, next_instr, oparg); - DISPATCH_SAME_OPARG(); - } - else { - STAT_INC(COMPARE_OP, deferred); - DECREMENT_ADAPTIVE_COUNTER(cache); - JUMP_TO_INSTRUCTION(COMPARE_OP); - } - } - - TARGET(COMPARE_OP_FLOAT_JUMP) { - assert(cframe.use_tracing == 0); - // Combined: COMPARE_OP (float ? float) + POP_JUMP_(direction)_IF_(true/false) - _PyCompareOpCache *cache = (_PyCompareOpCache *)next_instr; - int when_to_jump_mask = cache->mask; - PyObject *right = TOP(); - PyObject *left = SECOND(); - DEOPT_IF(!PyFloat_CheckExact(left), COMPARE_OP); - DEOPT_IF(!PyFloat_CheckExact(right), COMPARE_OP); - double dleft = PyFloat_AS_DOUBLE(left); - double dright = PyFloat_AS_DOUBLE(right); - int sign = (dleft > dright) - (dleft < dright); - DEOPT_IF(isnan(dleft), COMPARE_OP); - DEOPT_IF(isnan(dright), COMPARE_OP); - STAT_INC(COMPARE_OP, hit); - JUMPBY(INLINE_CACHE_ENTRIES_COMPARE_OP); - NEXTOPARG(); - STACK_SHRINK(2); - _Py_DECREF_SPECIALIZED(left, _PyFloat_ExactDealloc); - _Py_DECREF_SPECIALIZED(right, _PyFloat_ExactDealloc); - assert(opcode == POP_JUMP_FORWARD_IF_FALSE || - opcode == POP_JUMP_BACKWARD_IF_FALSE || - opcode == POP_JUMP_FORWARD_IF_TRUE || - opcode == POP_JUMP_BACKWARD_IF_TRUE); - int jump = (9 << (sign + 1)) & when_to_jump_mask; - if (!jump) { - next_instr++; - } - else if (jump >= 8) { - assert(opcode == POP_JUMP_BACKWARD_IF_TRUE || - opcode == POP_JUMP_BACKWARD_IF_FALSE); - JUMPBY(1 - oparg); - CHECK_EVAL_BREAKER(); - } - else { - assert(opcode == POP_JUMP_FORWARD_IF_TRUE || - opcode == POP_JUMP_FORWARD_IF_FALSE); - JUMPBY(1 + oparg); - } - DISPATCH(); - } - - TARGET(COMPARE_OP_INT_JUMP) { - assert(cframe.use_tracing == 0); - // Combined: COMPARE_OP (int ? int) + POP_JUMP_(direction)_IF_(true/false) - _PyCompareOpCache *cache = (_PyCompareOpCache *)next_instr; - int when_to_jump_mask = cache->mask; - PyObject *right = TOP(); - PyObject *left = SECOND(); - DEOPT_IF(!PyLong_CheckExact(left), COMPARE_OP); - DEOPT_IF(!PyLong_CheckExact(right), COMPARE_OP); - DEOPT_IF((size_t)(Py_SIZE(left) + 1) > 2, COMPARE_OP); - DEOPT_IF((size_t)(Py_SIZE(right) + 1) > 2, COMPARE_OP); - STAT_INC(COMPARE_OP, hit); - assert(Py_ABS(Py_SIZE(left)) <= 1 && Py_ABS(Py_SIZE(right)) <= 1); - Py_ssize_t ileft = Py_SIZE(left) * ((PyLongObject *)left)->ob_digit[0]; - Py_ssize_t iright = Py_SIZE(right) * ((PyLongObject *)right)->ob_digit[0]; - int sign = (ileft > iright) - (ileft < iright); - JUMPBY(INLINE_CACHE_ENTRIES_COMPARE_OP); - NEXTOPARG(); - STACK_SHRINK(2); - _Py_DECREF_SPECIALIZED(left, (destructor)PyObject_Free); - _Py_DECREF_SPECIALIZED(right, (destructor)PyObject_Free); - assert(opcode == POP_JUMP_FORWARD_IF_FALSE || - opcode == POP_JUMP_BACKWARD_IF_FALSE || - opcode == POP_JUMP_FORWARD_IF_TRUE || - opcode == POP_JUMP_BACKWARD_IF_TRUE); - int jump = (9 << (sign + 1)) & when_to_jump_mask; - if (!jump) { - next_instr++; - } - else if (jump >= 8) { - assert(opcode == POP_JUMP_BACKWARD_IF_TRUE || - opcode == POP_JUMP_BACKWARD_IF_FALSE); - JUMPBY(1 - oparg); - CHECK_EVAL_BREAKER(); - } - else { - assert(opcode == POP_JUMP_FORWARD_IF_TRUE || - opcode == POP_JUMP_FORWARD_IF_FALSE); - JUMPBY(1 + oparg); - } - DISPATCH(); - } - - TARGET(COMPARE_OP_STR_JUMP) { - assert(cframe.use_tracing == 0); - // Combined: COMPARE_OP (str == str or str != str) + POP_JUMP_(direction)_IF_(true/false) - _PyCompareOpCache *cache = (_PyCompareOpCache *)next_instr; - int when_to_jump_mask = cache->mask; - PyObject *right = TOP(); - PyObject *left = SECOND(); - DEOPT_IF(!PyUnicode_CheckExact(left), COMPARE_OP); - DEOPT_IF(!PyUnicode_CheckExact(right), COMPARE_OP); - STAT_INC(COMPARE_OP, hit); - int res = _PyUnicode_Equal(left, right); - if (res < 0) { - goto error; - } - assert(oparg == Py_EQ || oparg == Py_NE); - JUMPBY(INLINE_CACHE_ENTRIES_COMPARE_OP); - NEXTOPARG(); - assert(opcode == POP_JUMP_FORWARD_IF_FALSE || - opcode == POP_JUMP_BACKWARD_IF_FALSE || - opcode == POP_JUMP_FORWARD_IF_TRUE || - opcode == POP_JUMP_BACKWARD_IF_TRUE); - STACK_SHRINK(2); - _Py_DECREF_SPECIALIZED(left, _PyUnicode_ExactDealloc); - _Py_DECREF_SPECIALIZED(right, _PyUnicode_ExactDealloc); - assert(res == 0 || res == 1); - int sign = 1 - res; - int jump = (9 << (sign + 1)) & when_to_jump_mask; - if (!jump) { - next_instr++; - } - else if (jump >= 8) { - assert(opcode == POP_JUMP_BACKWARD_IF_TRUE || - opcode == POP_JUMP_BACKWARD_IF_FALSE); - JUMPBY(1 - oparg); - CHECK_EVAL_BREAKER(); - } - else { - assert(opcode == POP_JUMP_FORWARD_IF_TRUE || - opcode == POP_JUMP_FORWARD_IF_FALSE); - JUMPBY(1 + oparg); - } - DISPATCH(); - } - - TARGET(IS_OP) { - PyObject *right = POP(); - PyObject *left = TOP(); - int res = Py_Is(left, right) ^ oparg; - PyObject *b = res ? Py_True : Py_False; - Py_INCREF(b); - SET_TOP(b); - Py_DECREF(left); - Py_DECREF(right); - DISPATCH(); - } - - TARGET(CONTAINS_OP) { - PyObject *right = POP(); - PyObject *left = POP(); - int res = PySequence_Contains(right, left); - Py_DECREF(left); - Py_DECREF(right); - if (res < 0) { - goto error; - } - PyObject *b = (res^oparg) ? Py_True : Py_False; - Py_INCREF(b); - PUSH(b); - DISPATCH(); - } - - TARGET(CHECK_EG_MATCH) { - PyObject *match_type = POP(); - if (check_except_star_type_valid(tstate, match_type) < 0) { - Py_DECREF(match_type); - goto error; - } - - PyObject *exc_value = TOP(); - PyObject *match = NULL, *rest = NULL; - int res = exception_group_match(exc_value, match_type, - &match, &rest); - Py_DECREF(match_type); - if (res < 0) { - goto error; - } - - if (match == NULL || rest == NULL) { - assert(match == NULL); - assert(rest == NULL); - goto error; - } - if (Py_IsNone(match)) { - PUSH(match); - Py_XDECREF(rest); - } - else { - /* Total or partial match - update the stack from - * [val] - * to - * [rest, match] - * (rest can be Py_None) - */ - - SET_TOP(rest); - PUSH(match); - PyErr_SetExcInfo(NULL, Py_NewRef(match), NULL); - Py_DECREF(exc_value); - } - DISPATCH(); - } - - TARGET(CHECK_EXC_MATCH) { - PyObject *right = POP(); - PyObject *left = TOP(); - assert(PyExceptionInstance_Check(left)); - if (check_except_type_valid(tstate, right) < 0) { - Py_DECREF(right); - goto error; - } - - int res = PyErr_GivenExceptionMatches(left, right); - Py_DECREF(right); - PUSH(Py_NewRef(res ? Py_True : Py_False)); - DISPATCH(); - } - - TARGET(IMPORT_NAME) { - PyObject *name = GETITEM(names, oparg); - PyObject *fromlist = POP(); - PyObject *level = TOP(); - PyObject *res; - res = import_name(tstate, frame, name, fromlist, level); - Py_DECREF(level); - Py_DECREF(fromlist); - SET_TOP(res); - if (res == NULL) - goto error; - DISPATCH(); - } - - TARGET(IMPORT_STAR) { - PyObject *from = POP(), *locals; - int err; - if (_PyFrame_FastToLocalsWithError(frame) < 0) { - Py_DECREF(from); - goto error; - } - - locals = LOCALS(); - if (locals == NULL) { - _PyErr_SetString(tstate, PyExc_SystemError, - "no locals found during 'import *'"); - Py_DECREF(from); - goto error; - } - err = import_all_from(tstate, locals, from); - _PyFrame_LocalsToFast(frame, 0); - Py_DECREF(from); - if (err != 0) - goto error; - DISPATCH(); - } - - TARGET(IMPORT_FROM) { - PyObject *name = GETITEM(names, oparg); - PyObject *from = TOP(); - PyObject *res; - res = import_from(tstate, from, name); - PUSH(res); - if (res == NULL) - goto error; - DISPATCH(); - } - - TARGET(JUMP_FORWARD) { - JUMPBY(oparg); - DISPATCH(); - } - - TARGET(JUMP_BACKWARD) { - _PyCode_Warmup(frame->f_code); - JUMP_TO_INSTRUCTION(JUMP_BACKWARD_QUICK); - } - - TARGET(POP_JUMP_BACKWARD_IF_FALSE) { - PREDICTED(POP_JUMP_BACKWARD_IF_FALSE); - PyObject *cond = POP(); - if (Py_IsTrue(cond)) { - _Py_DECREF_NO_DEALLOC(cond); - DISPATCH(); - } - if (Py_IsFalse(cond)) { - _Py_DECREF_NO_DEALLOC(cond); - JUMPBY(-oparg); - CHECK_EVAL_BREAKER(); - DISPATCH(); - } - int err = PyObject_IsTrue(cond); - Py_DECREF(cond); - if (err > 0) - ; - else if (err == 0) { - JUMPBY(-oparg); - CHECK_EVAL_BREAKER(); - } - else - goto error; - DISPATCH(); - } - - TARGET(POP_JUMP_FORWARD_IF_FALSE) { - PREDICTED(POP_JUMP_FORWARD_IF_FALSE); - PyObject *cond = POP(); - if (Py_IsTrue(cond)) { - _Py_DECREF_NO_DEALLOC(cond); - } - else if (Py_IsFalse(cond)) { - _Py_DECREF_NO_DEALLOC(cond); - JUMPBY(oparg); - } - else { - int err = PyObject_IsTrue(cond); - Py_DECREF(cond); - if (err > 0) - ; - else if (err == 0) { - JUMPBY(oparg); - } - else - goto error; - } - DISPATCH(); - } - - TARGET(POP_JUMP_BACKWARD_IF_TRUE) { - PyObject *cond = POP(); - if (Py_IsFalse(cond)) { - _Py_DECREF_NO_DEALLOC(cond); - DISPATCH(); - } - if (Py_IsTrue(cond)) { - _Py_DECREF_NO_DEALLOC(cond); - JUMPBY(-oparg); - CHECK_EVAL_BREAKER(); - DISPATCH(); - } - int err = PyObject_IsTrue(cond); - Py_DECREF(cond); - if (err > 0) { - JUMPBY(-oparg); - CHECK_EVAL_BREAKER(); - } - else if (err == 0) - ; - else - goto error; - DISPATCH(); - } - - TARGET(POP_JUMP_FORWARD_IF_TRUE) { - PyObject *cond = POP(); - if (Py_IsFalse(cond)) { - _Py_DECREF_NO_DEALLOC(cond); - } - else if (Py_IsTrue(cond)) { - _Py_DECREF_NO_DEALLOC(cond); - JUMPBY(oparg); - } - else { - int err = PyObject_IsTrue(cond); - Py_DECREF(cond); - if (err > 0) { - JUMPBY(oparg); - } - else if (err == 0) - ; - else - goto error; - } - DISPATCH(); - } - - TARGET(POP_JUMP_BACKWARD_IF_NOT_NONE) { - PyObject *value = POP(); - if (!Py_IsNone(value)) { - Py_DECREF(value); - JUMPBY(-oparg); - CHECK_EVAL_BREAKER(); - DISPATCH(); - } - _Py_DECREF_NO_DEALLOC(value); - DISPATCH(); - } - - TARGET(POP_JUMP_FORWARD_IF_NOT_NONE) { - PyObject *value = POP(); - if (!Py_IsNone(value)) { - JUMPBY(oparg); - } - Py_DECREF(value); - DISPATCH(); - } - - TARGET(POP_JUMP_BACKWARD_IF_NONE) { - PyObject *value = POP(); - if (Py_IsNone(value)) { - _Py_DECREF_NO_DEALLOC(value); - JUMPBY(-oparg); - CHECK_EVAL_BREAKER(); - } - else { - Py_DECREF(value); - } - DISPATCH(); - } - - TARGET(POP_JUMP_FORWARD_IF_NONE) { - PyObject *value = POP(); - if (Py_IsNone(value)) { - _Py_DECREF_NO_DEALLOC(value); - JUMPBY(oparg); - } - else { - Py_DECREF(value); - } - DISPATCH(); - } - - TARGET(JUMP_IF_FALSE_OR_POP) { - PyObject *cond = TOP(); - int err; - if (Py_IsTrue(cond)) { - STACK_SHRINK(1); - _Py_DECREF_NO_DEALLOC(cond); - DISPATCH(); - } - if (Py_IsFalse(cond)) { - JUMPBY(oparg); - DISPATCH(); - } - err = PyObject_IsTrue(cond); - if (err > 0) { - STACK_SHRINK(1); - Py_DECREF(cond); - } - else if (err == 0) - JUMPBY(oparg); - else - goto error; - DISPATCH(); - } - - TARGET(JUMP_IF_TRUE_OR_POP) { - PyObject *cond = TOP(); - int err; - if (Py_IsFalse(cond)) { - STACK_SHRINK(1); - _Py_DECREF_NO_DEALLOC(cond); - DISPATCH(); - } - if (Py_IsTrue(cond)) { - JUMPBY(oparg); - DISPATCH(); - } - err = PyObject_IsTrue(cond); - if (err > 0) { - JUMPBY(oparg); - } - else if (err == 0) { - STACK_SHRINK(1); - Py_DECREF(cond); - } - else - goto error; - DISPATCH(); - } - - TARGET(JUMP_BACKWARD_NO_INTERRUPT) { - /* This bytecode is used in the `yield from` or `await` loop. - * If there is an interrupt, we want it handled in the innermost - * generator or coroutine, so we deliberately do not check it here. - * (see bpo-30039). - */ - JUMPBY(-oparg); - DISPATCH(); - } - - TARGET(JUMP_BACKWARD_QUICK) { - PREDICTED(JUMP_BACKWARD_QUICK); - assert(oparg < INSTR_OFFSET()); - JUMPBY(-oparg); - CHECK_EVAL_BREAKER(); - DISPATCH(); - } - - TARGET(GET_LEN) { - // PUSH(len(TOS)) - Py_ssize_t len_i = PyObject_Length(TOP()); - if (len_i < 0) { - goto error; - } - PyObject *len_o = PyLong_FromSsize_t(len_i); - if (len_o == NULL) { - goto error; - } - PUSH(len_o); - DISPATCH(); - } - - TARGET(MATCH_CLASS) { - // Pop TOS and TOS1. Set TOS to a tuple of attributes on success, or - // None on failure. - PyObject *names = POP(); - PyObject *type = POP(); - PyObject *subject = TOP(); - assert(PyTuple_CheckExact(names)); - PyObject *attrs = match_class(tstate, subject, type, oparg, names); - Py_DECREF(names); - Py_DECREF(type); - if (attrs) { - // Success! - assert(PyTuple_CheckExact(attrs)); - SET_TOP(attrs); - } - else if (_PyErr_Occurred(tstate)) { - // Error! - goto error; - } - else { - // Failure! - Py_INCREF(Py_None); - SET_TOP(Py_None); - } - Py_DECREF(subject); - DISPATCH(); - } - - TARGET(MATCH_MAPPING) { - PyObject *subject = TOP(); - int match = Py_TYPE(subject)->tp_flags & Py_TPFLAGS_MAPPING; - PyObject *res = match ? Py_True : Py_False; - Py_INCREF(res); - PUSH(res); - PREDICT(POP_JUMP_FORWARD_IF_FALSE); - PREDICT(POP_JUMP_BACKWARD_IF_FALSE); - DISPATCH(); - } - - TARGET(MATCH_SEQUENCE) { - PyObject *subject = TOP(); - int match = Py_TYPE(subject)->tp_flags & Py_TPFLAGS_SEQUENCE; - PyObject *res = match ? Py_True : Py_False; - Py_INCREF(res); - PUSH(res); - PREDICT(POP_JUMP_FORWARD_IF_FALSE); - PREDICT(POP_JUMP_BACKWARD_IF_FALSE); - DISPATCH(); - } - - TARGET(MATCH_KEYS) { - // On successful match, PUSH(values). Otherwise, PUSH(None). - PyObject *keys = TOP(); - PyObject *subject = SECOND(); - PyObject *values_or_none = match_keys(tstate, subject, keys); - if (values_or_none == NULL) { - goto error; - } - PUSH(values_or_none); - DISPATCH(); - } - - TARGET(GET_ITER) { - /* before: [obj]; after [getiter(obj)] */ - PyObject *iterable = TOP(); - PyObject *iter = PyObject_GetIter(iterable); - Py_DECREF(iterable); - SET_TOP(iter); - if (iter == NULL) - goto error; - PREDICT(FOR_ITER); - DISPATCH(); - } - - TARGET(GET_YIELD_FROM_ITER) { - /* before: [obj]; after [getiter(obj)] */ - PyObject *iterable = TOP(); - PyObject *iter; - if (PyCoro_CheckExact(iterable)) { - /* `iterable` is a coroutine */ - if (!(frame->f_code->co_flags & (CO_COROUTINE | CO_ITERABLE_COROUTINE))) { - /* and it is used in a 'yield from' expression of a - regular generator. */ - Py_DECREF(iterable); - SET_TOP(NULL); - _PyErr_SetString(tstate, PyExc_TypeError, - "cannot 'yield from' a coroutine object " - "in a non-coroutine generator"); - goto error; - } - } - else if (!PyGen_CheckExact(iterable)) { - /* `iterable` is not a generator. */ - iter = PyObject_GetIter(iterable); - Py_DECREF(iterable); - SET_TOP(iter); - if (iter == NULL) - goto error; - } - PREDICT(LOAD_CONST); - DISPATCH(); - } - - TARGET(FOR_ITER) { - PREDICTED(FOR_ITER); - /* before: [iter]; after: [iter, iter()] *or* [] */ - PyObject *iter = TOP(); -#ifdef Py_STATS - extern int _PySpecialization_ClassifyIterator(PyObject *); - _py_stats.opcode_stats[FOR_ITER].specialization.failure++; - _py_stats.opcode_stats[FOR_ITER].specialization.failure_kinds[_PySpecialization_ClassifyIterator(iter)]++; -#endif - PyObject *next = (*Py_TYPE(iter)->tp_iternext)(iter); - if (next != NULL) { - PUSH(next); - PREDICT(STORE_FAST); - PREDICT(UNPACK_SEQUENCE); - DISPATCH(); - } - if (_PyErr_Occurred(tstate)) { - if (!_PyErr_ExceptionMatches(tstate, PyExc_StopIteration)) { - goto error; - } - else if (tstate->c_tracefunc != NULL) { - call_exc_trace(tstate->c_tracefunc, tstate->c_traceobj, tstate, frame); - } - _PyErr_Clear(tstate); - } - /* iterator ended normally */ - STACK_SHRINK(1); - Py_DECREF(iter); - JUMPBY(oparg); - DISPATCH(); - } - - TARGET(BEFORE_ASYNC_WITH) { - PyObject *mgr = TOP(); - PyObject *res; - PyObject *enter = _PyObject_LookupSpecial(mgr, &_Py_ID(__aenter__)); - if (enter == NULL) { - if (!_PyErr_Occurred(tstate)) { - _PyErr_Format(tstate, PyExc_TypeError, - "'%.200s' object does not support the " - "asynchronous context manager protocol", - Py_TYPE(mgr)->tp_name); - } - goto error; - } - PyObject *exit = _PyObject_LookupSpecial(mgr, &_Py_ID(__aexit__)); - if (exit == NULL) { - if (!_PyErr_Occurred(tstate)) { - _PyErr_Format(tstate, PyExc_TypeError, - "'%.200s' object does not support the " - "asynchronous context manager protocol " - "(missed __aexit__ method)", - Py_TYPE(mgr)->tp_name); - } - Py_DECREF(enter); - goto error; - } - SET_TOP(exit); - Py_DECREF(mgr); - res = _PyObject_CallNoArgs(enter); - Py_DECREF(enter); - if (res == NULL) - goto error; - PUSH(res); - PREDICT(GET_AWAITABLE); - DISPATCH(); - } - - TARGET(BEFORE_WITH) { - PyObject *mgr = TOP(); - PyObject *res; - PyObject *enter = _PyObject_LookupSpecial(mgr, &_Py_ID(__enter__)); - if (enter == NULL) { - if (!_PyErr_Occurred(tstate)) { - _PyErr_Format(tstate, PyExc_TypeError, - "'%.200s' object does not support the " - "context manager protocol", - Py_TYPE(mgr)->tp_name); - } - goto error; - } - PyObject *exit = _PyObject_LookupSpecial(mgr, &_Py_ID(__exit__)); - if (exit == NULL) { - if (!_PyErr_Occurred(tstate)) { - _PyErr_Format(tstate, PyExc_TypeError, - "'%.200s' object does not support the " - "context manager protocol " - "(missed __exit__ method)", - Py_TYPE(mgr)->tp_name); - } - Py_DECREF(enter); - goto error; - } - SET_TOP(exit); - Py_DECREF(mgr); - res = _PyObject_CallNoArgs(enter); - Py_DECREF(enter); - if (res == NULL) { - goto error; - } - PUSH(res); - DISPATCH(); - } - - TARGET(WITH_EXCEPT_START) { - /* At the top of the stack are 4 values: - - TOP = exc_info() - - SECOND = previous exception - - THIRD: lasti of exception in exc_info() - - FOURTH: the context.__exit__ bound method - We call FOURTH(type(TOP), TOP, GetTraceback(TOP)). - Then we push the __exit__ return value. - */ - PyObject *exit_func; - PyObject *exc, *val, *tb, *res; - - val = TOP(); - assert(val && PyExceptionInstance_Check(val)); - exc = PyExceptionInstance_Class(val); - tb = PyException_GetTraceback(val); - Py_XDECREF(tb); - assert(PyLong_Check(PEEK(3))); - exit_func = PEEK(4); - PyObject *stack[4] = {NULL, exc, val, tb}; - res = PyObject_Vectorcall(exit_func, stack + 1, - 3 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); - if (res == NULL) - goto error; - - PUSH(res); - DISPATCH(); - } - - TARGET(PUSH_EXC_INFO) { - PyObject *value = TOP(); - - _PyErr_StackItem *exc_info = tstate->exc_info; - if (exc_info->exc_value != NULL) { - SET_TOP(exc_info->exc_value); - } - else { - Py_INCREF(Py_None); - SET_TOP(Py_None); - } - - Py_INCREF(value); - PUSH(value); - assert(PyExceptionInstance_Check(value)); - exc_info->exc_value = value; - - DISPATCH(); - } - - TARGET(LOAD_METHOD) { - PREDICTED(LOAD_METHOD); - /* Designed to work in tandem with PRECALL. */ - PyObject *name = GETITEM(names, oparg); - PyObject *obj = TOP(); - PyObject *meth = NULL; - - int meth_found = _PyObject_GetMethod(obj, name, &meth); - - if (meth == NULL) { - /* Most likely attribute wasn't found. */ - goto error; - } - - if (meth_found) { - /* We can bypass temporary bound method object. - meth is unbound method and obj is self. - - meth | self | arg1 | ... | argN - */ - SET_TOP(meth); - PUSH(obj); // self - } - else { - /* meth is not an unbound method (but a regular attr, or - something was returned by a descriptor protocol). Set - the second element of the stack to NULL, to signal - PRECALL that it's not a method call. - - NULL | meth | arg1 | ... | argN - */ - SET_TOP(NULL); - Py_DECREF(obj); - PUSH(meth); - } - JUMPBY(INLINE_CACHE_ENTRIES_LOAD_METHOD); - DISPATCH(); - } - - TARGET(LOAD_METHOD_ADAPTIVE) { - assert(cframe.use_tracing == 0); - _PyLoadMethodCache *cache = (_PyLoadMethodCache *)next_instr; - if (ADAPTIVE_COUNTER_IS_ZERO(cache)) { - PyObject *owner = TOP(); - PyObject *name = GETITEM(names, oparg); - next_instr--; - if (_Py_Specialize_LoadMethod(owner, next_instr, name) < 0) { - next_instr++; - goto error; - } - DISPATCH_SAME_OPARG(); - } - else { - STAT_INC(LOAD_METHOD, deferred); - DECREMENT_ADAPTIVE_COUNTER(cache); - JUMP_TO_INSTRUCTION(LOAD_METHOD); - } - } - - TARGET(LOAD_METHOD_WITH_VALUES) { - /* LOAD_METHOD, with cached method object */ - assert(cframe.use_tracing == 0); - PyObject *self = TOP(); - PyTypeObject *self_cls = Py_TYPE(self); - _PyLoadMethodCache *cache = (_PyLoadMethodCache *)next_instr; - uint32_t type_version = read_u32(cache->type_version); - assert(type_version != 0); - DEOPT_IF(self_cls->tp_version_tag != type_version, LOAD_METHOD); - assert(self_cls->tp_flags & Py_TPFLAGS_MANAGED_DICT); - PyDictObject *dict = *(PyDictObject**)_PyObject_ManagedDictPointer(self); - DEOPT_IF(dict != NULL, LOAD_METHOD); - PyHeapTypeObject *self_heap_type = (PyHeapTypeObject *)self_cls; - DEOPT_IF(self_heap_type->ht_cached_keys->dk_version != - read_u32(cache->keys_version), LOAD_METHOD); - STAT_INC(LOAD_METHOD, hit); - PyObject *res = read_obj(cache->descr); - assert(res != NULL); - assert(_PyType_HasFeature(Py_TYPE(res), Py_TPFLAGS_METHOD_DESCRIPTOR)); - Py_INCREF(res); - SET_TOP(res); - PUSH(self); - JUMPBY(INLINE_CACHE_ENTRIES_LOAD_METHOD); - DISPATCH(); - } - - TARGET(LOAD_METHOD_WITH_DICT) { - /* LOAD_METHOD, with a dict - Can be either a managed dict, or a tp_dictoffset offset.*/ - assert(cframe.use_tracing == 0); - PyObject *self = TOP(); - PyTypeObject *self_cls = Py_TYPE(self); - _PyLoadMethodCache *cache = (_PyLoadMethodCache *)next_instr; - - DEOPT_IF(self_cls->tp_version_tag != read_u32(cache->type_version), - LOAD_METHOD); - /* Treat index as a signed 16 bit value */ - int dictoffset = *(int16_t *)&cache->dict_offset; - PyDictObject **dictptr = (PyDictObject**)(((char *)self)+dictoffset); - assert( - dictoffset == MANAGED_DICT_OFFSET || - (dictoffset == self_cls->tp_dictoffset && dictoffset > 0) - ); - PyDictObject *dict = *dictptr; - DEOPT_IF(dict == NULL, LOAD_METHOD); - DEOPT_IF(dict->ma_keys->dk_version != read_u32(cache->keys_version), - LOAD_METHOD); - STAT_INC(LOAD_METHOD, hit); - PyObject *res = read_obj(cache->descr); - assert(res != NULL); - assert(_PyType_HasFeature(Py_TYPE(res), Py_TPFLAGS_METHOD_DESCRIPTOR)); - Py_INCREF(res); - SET_TOP(res); - PUSH(self); - JUMPBY(INLINE_CACHE_ENTRIES_LOAD_METHOD); - DISPATCH(); - } - - TARGET(LOAD_METHOD_NO_DICT) { - assert(cframe.use_tracing == 0); - PyObject *self = TOP(); - PyTypeObject *self_cls = Py_TYPE(self); - _PyLoadMethodCache *cache = (_PyLoadMethodCache *)next_instr; - uint32_t type_version = read_u32(cache->type_version); - DEOPT_IF(self_cls->tp_version_tag != type_version, LOAD_METHOD); - assert(self_cls->tp_dictoffset == 0); - STAT_INC(LOAD_METHOD, hit); - PyObject *res = read_obj(cache->descr); - assert(res != NULL); - assert(_PyType_HasFeature(Py_TYPE(res), Py_TPFLAGS_METHOD_DESCRIPTOR)); - Py_INCREF(res); - SET_TOP(res); - PUSH(self); - JUMPBY(INLINE_CACHE_ENTRIES_LOAD_METHOD); - DISPATCH(); - } - - TARGET(LOAD_METHOD_MODULE) { - /* LOAD_METHOD, for module methods */ - assert(cframe.use_tracing == 0); - PyObject *owner = TOP(); - PyObject *res; - LOAD_MODULE_ATTR_OR_METHOD(METHOD); - SET_TOP(NULL); - Py_DECREF(owner); - PUSH(res); - JUMPBY(INLINE_CACHE_ENTRIES_LOAD_METHOD); - DISPATCH(); - } - - TARGET(LOAD_METHOD_CLASS) { - /* LOAD_METHOD, for class methods */ - assert(cframe.use_tracing == 0); - _PyLoadMethodCache *cache = (_PyLoadMethodCache *)next_instr; - - PyObject *cls = TOP(); - DEOPT_IF(!PyType_Check(cls), LOAD_METHOD); - uint32_t type_version = read_u32(cache->type_version); - DEOPT_IF(((PyTypeObject *)cls)->tp_version_tag != type_version, - LOAD_METHOD); - assert(type_version != 0); - - STAT_INC(LOAD_METHOD, hit); - PyObject *res = read_obj(cache->descr); - assert(res != NULL); - Py_INCREF(res); - SET_TOP(NULL); - Py_DECREF(cls); - PUSH(res); - JUMPBY(INLINE_CACHE_ENTRIES_LOAD_METHOD); - DISPATCH(); - } - - TARGET(PRECALL) { - PREDICTED(PRECALL); - /* Designed to work in tamdem with LOAD_METHOD. */ - /* `meth` is NULL when LOAD_METHOD thinks that it's not - a method call. - - Stack layout: - - ... | NULL | callable | arg1 | ... | argN - ^- TOP() - ^- (-oparg) - ^- (-oparg-1) - ^- (-oparg-2) - - `callable` will be POPed by call_function. - NULL will will be POPed manually later. - If `meth` isn't NULL, it's a method call. Stack layout: - - ... | method | self | arg1 | ... | argN - ^- TOP() - ^- (-oparg) - ^- (-oparg-1) - ^- (-oparg-2) - - `self` and `method` will be POPed by call_function. - We'll be passing `oparg + 1` to call_function, to - make it accept the `self` as a first argument. - */ - int is_meth = is_method(stack_pointer, oparg); - int nargs = oparg + is_meth; - /* Move ownership of reference from stack to call_shape - * and make sure that NULL is cleared from stack */ - PyObject *function = PEEK(nargs + 1); - if (!is_meth && Py_TYPE(function) == &PyMethod_Type) { - PyObject *meth = ((PyMethodObject *)function)->im_func; - PyObject *self = ((PyMethodObject *)function)->im_self; - Py_INCREF(meth); - Py_INCREF(self); - PEEK(oparg+1) = self; - PEEK(oparg+2) = meth; - Py_DECREF(function); - } - JUMPBY(INLINE_CACHE_ENTRIES_PRECALL); - DISPATCH(); - } - - TARGET(PRECALL_BOUND_METHOD) { - DEOPT_IF(is_method(stack_pointer, oparg), PRECALL); - PyObject *function = PEEK(oparg + 1); - DEOPT_IF(Py_TYPE(function) != &PyMethod_Type, PRECALL); - STAT_INC(PRECALL, hit); - PyObject *meth = ((PyMethodObject *)function)->im_func; - PyObject *self = ((PyMethodObject *)function)->im_self; - Py_INCREF(meth); - Py_INCREF(self); - PEEK(oparg + 1) = self; - PEEK(oparg + 2) = meth; - Py_DECREF(function); - JUMPBY(INLINE_CACHE_ENTRIES_PRECALL); - DISPATCH(); - } - - TARGET(PRECALL_PYFUNC) { - int nargs = oparg + is_method(stack_pointer, oparg); - PyObject *function = PEEK(nargs + 1); - DEOPT_IF(Py_TYPE(function) != &PyFunction_Type, PRECALL); - STAT_INC(PRECALL, hit); - JUMPBY(INLINE_CACHE_ENTRIES_PRECALL); - DISPATCH(); - } - - TARGET(KW_NAMES) { - assert(call_shape.kwnames == NULL); - assert(oparg < PyTuple_GET_SIZE(consts)); - call_shape.kwnames = GETITEM(consts, oparg); - DISPATCH(); - } - - TARGET(CALL) { - int is_meth; - call_function: - is_meth = is_method(stack_pointer, oparg); - int total_args = oparg + is_meth; - PyObject *function = PEEK(total_args + 1); - int positional_args = total_args - KWNAMES_LEN(); - // Check if the call can be inlined or not - if (Py_TYPE(function) == &PyFunction_Type && tstate->interp->eval_frame == NULL) { - int code_flags = ((PyCodeObject*)PyFunction_GET_CODE(function))->co_flags; - PyObject *locals = code_flags & CO_OPTIMIZED ? NULL : PyFunction_GET_GLOBALS(function); - STACK_SHRINK(total_args); - _PyInterpreterFrame *new_frame = _PyEvalFramePushAndInit( - tstate, (PyFunctionObject *)function, locals, - stack_pointer, positional_args, call_shape.kwnames - ); - call_shape.kwnames = NULL; - STACK_SHRINK(2-is_meth); - // The frame has stolen all the arguments from the stack, - // so there is no need to clean them up. - if (new_frame == NULL) { - goto error; - } - _PyFrame_SetStackPointer(frame, stack_pointer); - JUMPBY(INLINE_CACHE_ENTRIES_CALL); - frame->prev_instr = next_instr - 1; - new_frame->previous = frame; - cframe.current_frame = frame = new_frame; - CALL_STAT_INC(inlined_py_calls); - goto start_frame; - } - /* Callable is not a normal Python function */ - PyObject *res; - if (cframe.use_tracing) { - res = trace_call_function( - tstate, function, stack_pointer-total_args, - positional_args, call_shape.kwnames); - } - else { - res = PyObject_Vectorcall( - function, stack_pointer-total_args, - positional_args | PY_VECTORCALL_ARGUMENTS_OFFSET, - call_shape.kwnames); - } - call_shape.kwnames = NULL; - assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); - Py_DECREF(function); - /* Clear the stack */ - STACK_SHRINK(total_args); - for (int i = 0; i < total_args; i++) { - Py_DECREF(stack_pointer[i]); - } - STACK_SHRINK(2-is_meth); - PUSH(res); - if (res == NULL) { - goto error; - } - JUMPBY(INLINE_CACHE_ENTRIES_CALL); - CHECK_EVAL_BREAKER(); - DISPATCH(); - } - - TARGET(PRECALL_ADAPTIVE) { - _PyPrecallCache *cache = (_PyPrecallCache *)next_instr; - if (ADAPTIVE_COUNTER_IS_ZERO(cache)) { - next_instr--; - int is_meth = is_method(stack_pointer, oparg); - int nargs = oparg + is_meth; - PyObject *callable = PEEK(nargs + 1); - int err = _Py_Specialize_Precall(callable, next_instr, nargs, - call_shape.kwnames, oparg); - if (err < 0) { - next_instr++; - goto error; - } - DISPATCH_SAME_OPARG(); - } - else { - STAT_INC(PRECALL, deferred); - DECREMENT_ADAPTIVE_COUNTER(cache); - JUMP_TO_INSTRUCTION(PRECALL); - } - } - - TARGET(CALL_ADAPTIVE) { - _PyCallCache *cache = (_PyCallCache *)next_instr; - if (ADAPTIVE_COUNTER_IS_ZERO(cache)) { - next_instr--; - int is_meth = is_method(stack_pointer, oparg); - int nargs = oparg + is_meth; - PyObject *callable = PEEK(nargs + 1); - int err = _Py_Specialize_Call(callable, next_instr, nargs, - call_shape.kwnames); - if (err < 0) { - next_instr++; - goto error; - } - DISPATCH_SAME_OPARG(); - } - else { - STAT_INC(CALL, deferred); - DECREMENT_ADAPTIVE_COUNTER(cache); - goto call_function; - } - } - - TARGET(CALL_PY_EXACT_ARGS) { - assert(call_shape.kwnames == NULL); - DEOPT_IF(tstate->interp->eval_frame, CALL); - _PyCallCache *cache = (_PyCallCache *)next_instr; - int is_meth = is_method(stack_pointer, oparg); - int argcount = oparg + is_meth; - PyObject *callable = PEEK(argcount + 1); - DEOPT_IF(!PyFunction_Check(callable), CALL); - PyFunctionObject *func = (PyFunctionObject *)callable; - DEOPT_IF(func->func_version != read_u32(cache->func_version), CALL); - PyCodeObject *code = (PyCodeObject *)func->func_code; - DEOPT_IF(code->co_argcount != argcount, CALL); - STAT_INC(CALL, hit); - _PyInterpreterFrame *new_frame = _PyFrame_Push(tstate, func); - if (new_frame == NULL) { - goto error; - } - CALL_STAT_INC(inlined_py_calls); - STACK_SHRINK(argcount); - for (int i = 0; i < argcount; i++) { - new_frame->localsplus[i] = stack_pointer[i]; - } - for (int i = argcount; i < code->co_nlocalsplus; i++) { - new_frame->localsplus[i] = NULL; - } - STACK_SHRINK(2-is_meth); - _PyFrame_SetStackPointer(frame, stack_pointer); - JUMPBY(INLINE_CACHE_ENTRIES_CALL); - frame->prev_instr = next_instr - 1; - new_frame->previous = frame; - frame = cframe.current_frame = new_frame; - goto start_frame; - } - - TARGET(CALL_PY_WITH_DEFAULTS) { - assert(call_shape.kwnames == NULL); - DEOPT_IF(tstate->interp->eval_frame, CALL); - _PyCallCache *cache = (_PyCallCache *)next_instr; - int is_meth = is_method(stack_pointer, oparg); - int argcount = oparg + is_meth; - PyObject *callable = PEEK(argcount + 1); - DEOPT_IF(!PyFunction_Check(callable), CALL); - PyFunctionObject *func = (PyFunctionObject *)callable; - DEOPT_IF(func->func_version != read_u32(cache->func_version), CALL); - PyCodeObject *code = (PyCodeObject *)func->func_code; - DEOPT_IF(argcount > code->co_argcount, CALL); - int minargs = cache->min_args; - DEOPT_IF(argcount < minargs, CALL); - STAT_INC(CALL, hit); - _PyInterpreterFrame *new_frame = _PyFrame_Push(tstate, func); - if (new_frame == NULL) { - goto error; - } - CALL_STAT_INC(inlined_py_calls); - STACK_SHRINK(argcount); - for (int i = 0; i < argcount; i++) { - new_frame->localsplus[i] = stack_pointer[i]; - } - for (int i = argcount; i < code->co_argcount; i++) { - PyObject *def = PyTuple_GET_ITEM(func->func_defaults, - i - minargs); - Py_INCREF(def); - new_frame->localsplus[i] = def; - } - for (int i = code->co_argcount; i < code->co_nlocalsplus; i++) { - new_frame->localsplus[i] = NULL; - } - STACK_SHRINK(2-is_meth); - _PyFrame_SetStackPointer(frame, stack_pointer); - JUMPBY(INLINE_CACHE_ENTRIES_CALL); - frame->prev_instr = next_instr - 1; - new_frame->previous = frame; - frame = cframe.current_frame = new_frame; - goto start_frame; - } - - TARGET(PRECALL_NO_KW_TYPE_1) { - assert(call_shape.kwnames == NULL); - assert(cframe.use_tracing == 0); - assert(oparg == 1); - DEOPT_IF(is_method(stack_pointer, 1), PRECALL); - PyObject *obj = TOP(); - PyObject *callable = SECOND(); - DEOPT_IF(callable != (PyObject *)&PyType_Type, PRECALL); - STAT_INC(PRECALL, hit); - SKIP_CALL(); - PyObject *res = Py_NewRef(Py_TYPE(obj)); - Py_DECREF(callable); - Py_DECREF(obj); - STACK_SHRINK(2); - SET_TOP(res); - DISPATCH(); - } +PyObject * +PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) +{ + PyThreadState *tstate = _PyThreadState_GET(); + return _PyEval_EvalFrame(tstate, f->f_frame, throwflag); +} - TARGET(PRECALL_NO_KW_STR_1) { - assert(call_shape.kwnames == NULL); - assert(cframe.use_tracing == 0); - assert(oparg == 1); - DEOPT_IF(is_method(stack_pointer, 1), PRECALL); - PyObject *callable = PEEK(2); - DEOPT_IF(callable != (PyObject *)&PyUnicode_Type, PRECALL); - STAT_INC(PRECALL, hit); - SKIP_CALL(); - PyObject *arg = TOP(); - PyObject *res = PyObject_Str(arg); - Py_DECREF(arg); - Py_DECREF(&PyUnicode_Type); - STACK_SHRINK(2); - SET_TOP(res); - if (res == NULL) { - goto error; - } - CHECK_EVAL_BREAKER(); - DISPATCH(); - } +#include "ceval_macros.h" - TARGET(PRECALL_NO_KW_TUPLE_1) { - assert(call_shape.kwnames == NULL); - assert(oparg == 1); - DEOPT_IF(is_method(stack_pointer, 1), PRECALL); - PyObject *callable = PEEK(2); - DEOPT_IF(callable != (PyObject *)&PyTuple_Type, PRECALL); - STAT_INC(PRECALL, hit); - SKIP_CALL(); - PyObject *arg = TOP(); - PyObject *res = PySequence_Tuple(arg); - Py_DECREF(arg); - Py_DECREF(&PyTuple_Type); - STACK_SHRINK(2); - SET_TOP(res); - if (res == NULL) { - goto error; - } - CHECK_EVAL_BREAKER(); - DISPATCH(); - } - TARGET(PRECALL_BUILTIN_CLASS) { - int is_meth = is_method(stack_pointer, oparg); - int total_args = oparg + is_meth; - int kwnames_len = KWNAMES_LEN(); - PyObject *callable = PEEK(total_args + 1); - DEOPT_IF(!PyType_Check(callable), PRECALL); - PyTypeObject *tp = (PyTypeObject *)callable; - DEOPT_IF(tp->tp_vectorcall == NULL, PRECALL); - STAT_INC(PRECALL, hit); - SKIP_CALL(); - STACK_SHRINK(total_args); - PyObject *res = tp->tp_vectorcall((PyObject *)tp, stack_pointer, - total_args-kwnames_len, call_shape.kwnames); - call_shape.kwnames = NULL; - /* Free the arguments. */ - for (int i = 0; i < total_args; i++) { - Py_DECREF(stack_pointer[i]); - } - Py_DECREF(tp); - STACK_SHRINK(1-is_meth); - SET_TOP(res); - if (res == NULL) { - goto error; - } - CHECK_EVAL_BREAKER(); - DISPATCH(); +int _Py_CheckRecursiveCallPy( + PyThreadState *tstate) +{ + if (tstate->recursion_headroom) { + if (tstate->py_recursion_remaining < -50) { + /* Overflowing while handling an overflow. Give up. */ + Py_FatalError("Cannot recover from Python stack overflow."); } - - TARGET(PRECALL_NO_KW_BUILTIN_O) { - assert(cframe.use_tracing == 0); - /* Builtin METH_O functions */ - assert(call_shape.kwnames == NULL); - int is_meth = is_method(stack_pointer, oparg); - int total_args = oparg + is_meth; - DEOPT_IF(total_args != 1, PRECALL); - PyObject *callable = PEEK(total_args + 1); - DEOPT_IF(!PyCFunction_CheckExact(callable), PRECALL); - DEOPT_IF(PyCFunction_GET_FLAGS(callable) != METH_O, PRECALL); - STAT_INC(PRECALL, hit); - SKIP_CALL(); - PyCFunction cfunc = PyCFunction_GET_FUNCTION(callable); - // This is slower but CPython promises to check all non-vectorcall - // function calls. - if (_Py_EnterRecursiveCallTstate(tstate, " while calling a Python object")) { - goto error; - } - PyObject *arg = TOP(); - PyObject *res = _PyCFunction_TrampolineCall(cfunc, PyCFunction_GET_SELF(callable), arg); - _Py_LeaveRecursiveCallTstate(tstate); - assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); - - Py_DECREF(arg); - Py_DECREF(callable); - STACK_SHRINK(2-is_meth); - SET_TOP(res); - if (res == NULL) { - goto error; - } - CHECK_EVAL_BREAKER(); - DISPATCH(); + } + else { + if (tstate->py_recursion_remaining <= 0) { + tstate->recursion_headroom++; + _PyErr_Format(tstate, PyExc_RecursionError, + "maximum recursion depth exceeded"); + tstate->recursion_headroom--; + return -1; } + } + return 0; +} - TARGET(PRECALL_NO_KW_BUILTIN_FAST) { - assert(cframe.use_tracing == 0); - /* Builtin METH_FASTCALL functions, without keywords */ - assert(call_shape.kwnames == NULL); - int is_meth = is_method(stack_pointer, oparg); - int total_args = oparg + is_meth; - PyObject *callable = PEEK(total_args + 1); - DEOPT_IF(!PyCFunction_CheckExact(callable), PRECALL); - DEOPT_IF(PyCFunction_GET_FLAGS(callable) != METH_FASTCALL, - PRECALL); - STAT_INC(PRECALL, hit); - SKIP_CALL(); - PyCFunction cfunc = PyCFunction_GET_FUNCTION(callable); - STACK_SHRINK(total_args); - /* res = func(self, args, nargs) */ - PyObject *res = ((_PyCFunctionFast)(void(*)(void))cfunc)( - PyCFunction_GET_SELF(callable), - stack_pointer, - total_args); - assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); - - /* Free the arguments. */ - for (int i = 0; i < total_args; i++) { - Py_DECREF(stack_pointer[i]); - } - STACK_SHRINK(2-is_meth); - PUSH(res); - Py_DECREF(callable); - if (res == NULL) { - /* Not deopting because this doesn't mean our optimization was - wrong. `res` can be NULL for valid reasons. Eg. getattr(x, - 'invalid'). In those cases an exception is set, so we must - handle it. - */ - goto error; - } - CHECK_EVAL_BREAKER(); - DISPATCH(); - } +static inline int _Py_EnterRecursivePy(PyThreadState *tstate) { + return (tstate->py_recursion_remaining-- <= 0) && + _Py_CheckRecursiveCallPy(tstate); +} - TARGET(PRECALL_BUILTIN_FAST_WITH_KEYWORDS) { - assert(cframe.use_tracing == 0); - /* Builtin METH_FASTCALL | METH_KEYWORDS functions */ - int is_meth = is_method(stack_pointer, oparg); - int total_args = oparg + is_meth; - PyObject *callable = PEEK(total_args + 1); - DEOPT_IF(!PyCFunction_CheckExact(callable), PRECALL); - DEOPT_IF(PyCFunction_GET_FLAGS(callable) != - (METH_FASTCALL | METH_KEYWORDS), PRECALL); - STAT_INC(PRECALL, hit); - SKIP_CALL(); - STACK_SHRINK(total_args); - /* res = func(self, args, nargs, kwnames) */ - _PyCFunctionFastWithKeywords cfunc = - (_PyCFunctionFastWithKeywords)(void(*)(void)) - PyCFunction_GET_FUNCTION(callable); - PyObject *res = cfunc( - PyCFunction_GET_SELF(callable), - stack_pointer, - total_args - KWNAMES_LEN(), - call_shape.kwnames - ); - assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); - call_shape.kwnames = NULL; - /* Free the arguments. */ - for (int i = 0; i < total_args; i++) { - Py_DECREF(stack_pointer[i]); - } - STACK_SHRINK(2-is_meth); - PUSH(res); - Py_DECREF(callable); - if (res == NULL) { - goto error; - } - CHECK_EVAL_BREAKER(); - DISPATCH(); - } +static inline void _Py_LeaveRecursiveCallPy(PyThreadState *tstate) { + tstate->py_recursion_remaining++; +} - TARGET(PRECALL_NO_KW_LEN) { - assert(cframe.use_tracing == 0); - assert(call_shape.kwnames == NULL); - /* len(o) */ - int is_meth = is_method(stack_pointer, oparg); - int total_args = oparg + is_meth; - DEOPT_IF(total_args != 1, PRECALL); - PyObject *callable = PEEK(total_args + 1); - PyInterpreterState *interp = _PyInterpreterState_GET(); - DEOPT_IF(callable != interp->callable_cache.len, PRECALL); - STAT_INC(PRECALL, hit); - SKIP_CALL(); - PyObject *arg = TOP(); - Py_ssize_t len_i = PyObject_Length(arg); - if (len_i < 0) { - goto error; - } - PyObject *res = PyLong_FromSsize_t(len_i); - assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); - - STACK_SHRINK(2-is_meth); - SET_TOP(res); - Py_DECREF(callable); - Py_DECREF(arg); - if (res == NULL) { - goto error; - } - DISPATCH(); - } - TARGET(PRECALL_NO_KW_ISINSTANCE) { - assert(cframe.use_tracing == 0); - assert(call_shape.kwnames == NULL); - /* isinstance(o, o2) */ - int is_meth = is_method(stack_pointer, oparg); - int total_args = oparg + is_meth; - PyObject *callable = PEEK(total_args + 1); - DEOPT_IF(total_args != 2, PRECALL); - PyInterpreterState *interp = _PyInterpreterState_GET(); - DEOPT_IF(callable != interp->callable_cache.isinstance, PRECALL); - STAT_INC(PRECALL, hit); - SKIP_CALL(); - PyObject *cls = POP(); - PyObject *inst = TOP(); - int retval = PyObject_IsInstance(inst, cls); - if (retval < 0) { - Py_DECREF(cls); - goto error; - } - PyObject *res = PyBool_FromLong(retval); - assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); - - STACK_SHRINK(2-is_meth); - SET_TOP(res); - Py_DECREF(inst); - Py_DECREF(cls); - Py_DECREF(callable); - if (res == NULL) { - goto error; - } - DISPATCH(); - } +/* Disable unused label warnings. They are handy for debugging, even + if computed gotos aren't used. */ - TARGET(PRECALL_NO_KW_LIST_APPEND) { - assert(cframe.use_tracing == 0); - assert(call_shape.kwnames == NULL); - assert(oparg == 1); - PyObject *callable = PEEK(3); - PyInterpreterState *interp = _PyInterpreterState_GET(); - DEOPT_IF(callable != interp->callable_cache.list_append, PRECALL); - PyObject *list = SECOND(); - DEOPT_IF(!PyList_Check(list), PRECALL); - STAT_INC(PRECALL, hit); - PyObject *arg = POP(); - if (_PyList_AppendTakeRef((PyListObject *)list, arg) < 0) { - goto error; - } - STACK_SHRINK(2); - Py_DECREF(list); - Py_DECREF(callable); - // PRECALL + CALL + POP_TOP - JUMPBY(INLINE_CACHE_ENTRIES_PRECALL + 1 + INLINE_CACHE_ENTRIES_CALL + 1); - assert(_Py_OPCODE(next_instr[-1]) == POP_TOP); - DISPATCH(); - } +/* TBD - what about other compilers? */ +#if defined(__GNUC__) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wunused-label" +#elif defined(_MSC_VER) /* MS_WINDOWS */ +# pragma warning(push) +# pragma warning(disable:4102) +#endif - TARGET(PRECALL_NO_KW_METHOD_DESCRIPTOR_O) { - assert(call_shape.kwnames == NULL); - int is_meth = is_method(stack_pointer, oparg); - int total_args = oparg + is_meth; - PyMethodDescrObject *callable = - (PyMethodDescrObject *)PEEK(total_args + 1); - DEOPT_IF(total_args != 2, PRECALL); - DEOPT_IF(!Py_IS_TYPE(callable, &PyMethodDescr_Type), PRECALL); - PyMethodDef *meth = callable->d_method; - DEOPT_IF(meth->ml_flags != METH_O, PRECALL); - PyObject *arg = TOP(); - PyObject *self = SECOND(); - DEOPT_IF(!Py_IS_TYPE(self, callable->d_common.d_type), PRECALL); - STAT_INC(PRECALL, hit); - SKIP_CALL(); - PyCFunction cfunc = meth->ml_meth; - // This is slower but CPython promises to check all non-vectorcall - // function calls. - if (_Py_EnterRecursiveCallTstate(tstate, " while calling a Python object")) { - goto error; - } - PyObject *res = _PyCFunction_TrampolineCall(cfunc, self, arg); - _Py_LeaveRecursiveCallTstate(tstate); - assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); - Py_DECREF(self); - Py_DECREF(arg); - STACK_SHRINK(oparg + 1); - SET_TOP(res); - Py_DECREF(callable); - if (res == NULL) { - goto error; - } - CHECK_EVAL_BREAKER(); - DISPATCH(); - } - TARGET(PRECALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS) { - int is_meth = is_method(stack_pointer, oparg); - int total_args = oparg + is_meth; - PyMethodDescrObject *callable = - (PyMethodDescrObject *)PEEK(total_args + 1); - DEOPT_IF(!Py_IS_TYPE(callable, &PyMethodDescr_Type), PRECALL); - PyMethodDef *meth = callable->d_method; - DEOPT_IF(meth->ml_flags != (METH_FASTCALL|METH_KEYWORDS), PRECALL); - PyTypeObject *d_type = callable->d_common.d_type; - PyObject *self = PEEK(total_args); - DEOPT_IF(!Py_IS_TYPE(self, d_type), PRECALL); - STAT_INC(PRECALL, hit); - SKIP_CALL(); - int nargs = total_args-1; - STACK_SHRINK(nargs); - _PyCFunctionFastWithKeywords cfunc = - (_PyCFunctionFastWithKeywords)(void(*)(void))meth->ml_meth; - PyObject *res = cfunc(self, stack_pointer, nargs - KWNAMES_LEN(), - call_shape.kwnames); - assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); - call_shape.kwnames = NULL; - - /* Free the arguments. */ - for (int i = 0; i < nargs; i++) { - Py_DECREF(stack_pointer[i]); - } - Py_DECREF(self); - STACK_SHRINK(2-is_meth); - SET_TOP(res); - Py_DECREF(callable); - if (res == NULL) { - goto error; - } - CHECK_EVAL_BREAKER(); - DISPATCH(); - } +/* _PyEval_EvalFrameDefault() is a *big* function, + * so consume 3 units of C stack */ +#define PY_EVAL_C_STACK_UNITS 2 - TARGET(PRECALL_NO_KW_METHOD_DESCRIPTOR_NOARGS) { - assert(call_shape.kwnames == NULL); - assert(oparg == 0 || oparg == 1); - int is_meth = is_method(stack_pointer, oparg); - int total_args = oparg + is_meth; - DEOPT_IF(total_args != 1, PRECALL); - PyMethodDescrObject *callable = (PyMethodDescrObject *)SECOND(); - DEOPT_IF(!Py_IS_TYPE(callable, &PyMethodDescr_Type), PRECALL); - PyMethodDef *meth = callable->d_method; - PyObject *self = TOP(); - DEOPT_IF(!Py_IS_TYPE(self, callable->d_common.d_type), PRECALL); - DEOPT_IF(meth->ml_flags != METH_NOARGS, PRECALL); - STAT_INC(PRECALL, hit); - SKIP_CALL(); - PyCFunction cfunc = meth->ml_meth; - // This is slower but CPython promises to check all non-vectorcall - // function calls. - if (_Py_EnterRecursiveCallTstate(tstate, " while calling a Python object")) { - goto error; - } - PyObject *res = _PyCFunction_TrampolineCall(cfunc, self, NULL); - _Py_LeaveRecursiveCallTstate(tstate); - assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); - Py_DECREF(self); - STACK_SHRINK(oparg + 1); - SET_TOP(res); - Py_DECREF(callable); - if (res == NULL) { - goto error; - } - CHECK_EVAL_BREAKER(); - DISPATCH(); - } +PyObject* _Py_HOT_FUNCTION +_PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int throwflag) +{ + _Py_EnsureTstateNotNULL(tstate); + CALL_STAT_INC(pyeval_calls); - TARGET(PRECALL_NO_KW_METHOD_DESCRIPTOR_FAST) { - assert(call_shape.kwnames == NULL); - int is_meth = is_method(stack_pointer, oparg); - int total_args = oparg + is_meth; - PyMethodDescrObject *callable = - (PyMethodDescrObject *)PEEK(total_args + 1); - /* Builtin METH_FASTCALL methods, without keywords */ - DEOPT_IF(!Py_IS_TYPE(callable, &PyMethodDescr_Type), PRECALL); - PyMethodDef *meth = callable->d_method; - DEOPT_IF(meth->ml_flags != METH_FASTCALL, PRECALL); - PyObject *self = PEEK(total_args); - DEOPT_IF(!Py_IS_TYPE(self, callable->d_common.d_type), PRECALL); - STAT_INC(PRECALL, hit); - SKIP_CALL(); - _PyCFunctionFast cfunc = - (_PyCFunctionFast)(void(*)(void))meth->ml_meth; - int nargs = total_args-1; - STACK_SHRINK(nargs); - PyObject *res = cfunc(self, stack_pointer, nargs); - assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); - /* Clear the stack of the arguments. */ - for (int i = 0; i < nargs; i++) { - Py_DECREF(stack_pointer[i]); - } - Py_DECREF(self); - STACK_SHRINK(2-is_meth); - SET_TOP(res); - Py_DECREF(callable); - if (res == NULL) { - goto error; - } - CHECK_EVAL_BREAKER(); - DISPATCH(); - } +#if USE_COMPUTED_GOTOS +/* Import the static jump table */ +#include "opcode_targets.h" +#endif - TARGET(CALL_FUNCTION_EX) { - PREDICTED(CALL_FUNCTION_EX); - PyObject *func, *callargs, *kwargs = NULL, *result; - if (oparg & 0x01) { - kwargs = POP(); - if (!PyDict_CheckExact(kwargs)) { - PyObject *d = PyDict_New(); - if (d == NULL) - goto error; - if (_PyDict_MergeEx(d, kwargs, 2) < 0) { - Py_DECREF(d); - format_kwargs_error(tstate, SECOND(), kwargs); - Py_DECREF(kwargs); - goto error; - } - Py_DECREF(kwargs); - kwargs = d; - } - assert(PyDict_CheckExact(kwargs)); - } - callargs = POP(); - func = TOP(); - if (!PyTuple_CheckExact(callargs)) { - if (check_args_iterable(tstate, func, callargs) < 0) { - Py_DECREF(callargs); - goto error; - } - Py_SETREF(callargs, PySequence_Tuple(callargs)); - if (callargs == NULL) { - goto error; - } - } - assert(PyTuple_CheckExact(callargs)); +#ifdef Py_STATS + int lastopcode = 0; +#endif + // opcode is an 8-bit value to improve the code generated by MSVC + // for the big switch below (in combination with the EXTRA_CASES macro). + uint8_t opcode; /* Current opcode */ + int oparg; /* Current opcode argument, if any */ +#ifdef LLTRACE + int lltrace = 0; +#endif - result = do_call_core(tstate, func, callargs, kwargs, cframe.use_tracing); - Py_DECREF(func); - Py_DECREF(callargs); - Py_XDECREF(kwargs); - - STACK_SHRINK(1); - assert(TOP() == NULL); - SET_TOP(result); - if (result == NULL) { - goto error; - } - CHECK_EVAL_BREAKER(); - DISPATCH(); - } + _PyCFrame cframe; + _PyInterpreterFrame entry_frame; + PyObject *kwnames = NULL; // Borrowed reference. Reset by CALL instructions. - TARGET(MAKE_FUNCTION) { - PyObject *codeobj = POP(); - PyFunctionObject *func = (PyFunctionObject *) - PyFunction_New(codeobj, GLOBALS()); + /* WARNING: Because the _PyCFrame lives on the C stack, + * but can be accessed from a heap allocated object (tstate) + * strict stack discipline must be maintained. + */ + _PyCFrame *prev_cframe = tstate->cframe; + cframe.previous = prev_cframe; + tstate->cframe = &cframe; - Py_DECREF(codeobj); - if (func == NULL) { - goto error; - } + assert(tstate->interp->interpreter_trampoline != NULL); +#ifdef Py_DEBUG + /* Set these to invalid but identifiable values for debugging. */ + entry_frame.f_funcobj = (PyObject*)0xaaa0; + entry_frame.f_locals = (PyObject*)0xaaa1; + entry_frame.frame_obj = (PyFrameObject*)0xaaa2; + entry_frame.f_globals = (PyObject*)0xaaa3; + entry_frame.f_builtins = (PyObject*)0xaaa4; +#endif + entry_frame.f_code = tstate->interp->interpreter_trampoline; + entry_frame.prev_instr = + _PyCode_CODE(tstate->interp->interpreter_trampoline); + entry_frame.stacktop = 0; + entry_frame.owner = FRAME_OWNED_BY_CSTACK; + entry_frame.return_offset = 0; + /* Push frame */ + entry_frame.previous = prev_cframe->current_frame; + frame->previous = &entry_frame; + cframe.current_frame = frame; - if (oparg & 0x08) { - assert(PyTuple_CheckExact(TOP())); - func->func_closure = POP(); - } - if (oparg & 0x04) { - assert(PyTuple_CheckExact(TOP())); - func->func_annotations = POP(); - } - if (oparg & 0x02) { - assert(PyDict_CheckExact(TOP())); - func->func_kwdefaults = POP(); - } - if (oparg & 0x01) { - assert(PyTuple_CheckExact(TOP())); - func->func_defaults = POP(); - } + tstate->c_recursion_remaining -= (PY_EVAL_C_STACK_UNITS - 1); + if (_Py_EnterRecursiveCallTstate(tstate, "")) { + tstate->c_recursion_remaining--; + tstate->py_recursion_remaining--; + goto exit_unwind; + } - PUSH((PyObject *)func); - DISPATCH(); + /* support for generator.throw() */ + if (throwflag) { + if (_Py_EnterRecursivePy(tstate)) { + goto exit_unwind; } + /* Because this avoids the RESUME, + * we need to update instrumentation */ + _Py_Instrument(frame->f_code, tstate->interp); + monitor_throw(tstate, frame, frame->prev_instr); + /* TO DO -- Monitor throw entry. */ + goto resume_with_error; + } - TARGET(RETURN_GENERATOR) { - PyGenObject *gen = (PyGenObject *)_Py_MakeCoro(frame->f_func); - if (gen == NULL) { - goto error; - } - assert(EMPTY()); - _PyFrame_SetStackPointer(frame, stack_pointer); - _PyInterpreterFrame *gen_frame = (_PyInterpreterFrame *)gen->gi_iframe; - _PyFrame_Copy(frame, gen_frame); - assert(frame->frame_obj == NULL); - gen->gi_frame_state = FRAME_CREATED; - gen_frame->owner = FRAME_OWNED_BY_GENERATOR; - _Py_LeaveRecursiveCallTstate(tstate); - if (!frame->is_entry) { - _PyInterpreterFrame *prev = frame->previous; - _PyThreadState_PopFrame(tstate, frame); - frame = cframe.current_frame = prev; - _PyFrame_StackPush(frame, (PyObject *)gen); - goto resume_frame; - } - /* Make sure that frame is in a valid state */ - frame->stacktop = 0; - frame->f_locals = NULL; - Py_INCREF(frame->f_func); - Py_INCREF(frame->f_code); - /* Restore previous cframe and return. */ - tstate->cframe = cframe.previous; - tstate->cframe->use_tracing = cframe.use_tracing; - assert(tstate->cframe->current_frame == frame->previous); - assert(!_PyErr_Occurred(tstate)); - return (PyObject *)gen; - } + /* Local "register" variables. + * These are cached values from the frame and code object. */ - TARGET(BUILD_SLICE) { - PyObject *start, *stop, *step, *slice; - if (oparg == 3) - step = POP(); - else - step = NULL; - stop = POP(); - start = TOP(); - slice = PySlice_New(start, stop, step); - Py_DECREF(start); - Py_DECREF(stop); - Py_XDECREF(step); - SET_TOP(slice); - if (slice == NULL) - goto error; - DISPATCH(); - } + _Py_CODEUNIT *next_instr; + PyObject **stack_pointer; - TARGET(FORMAT_VALUE) { - /* Handles f-string value formatting. */ - PyObject *result; - PyObject *fmt_spec; - PyObject *value; - PyObject *(*conv_fn)(PyObject *); - int which_conversion = oparg & FVC_MASK; - int have_fmt_spec = (oparg & FVS_MASK) == FVS_HAVE_SPEC; - - fmt_spec = have_fmt_spec ? POP() : NULL; - value = POP(); - - /* See if any conversion is specified. */ - switch (which_conversion) { - case FVC_NONE: conv_fn = NULL; break; - case FVC_STR: conv_fn = PyObject_Str; break; - case FVC_REPR: conv_fn = PyObject_Repr; break; - case FVC_ASCII: conv_fn = PyObject_ASCII; break; - default: - _PyErr_Format(tstate, PyExc_SystemError, - "unexpected conversion flag %d", - which_conversion); - goto error; - } +/* Sets the above local variables from the frame */ +#define SET_LOCALS_FROM_FRAME() \ + assert(_PyInterpreterFrame_LASTI(frame) >= -1); \ + /* Jump back to the last instruction executed... */ \ + next_instr = frame->prev_instr + 1; \ + stack_pointer = _PyFrame_GetStackPointer(frame); - /* If there's a conversion function, call it and replace - value with that result. Otherwise, just use value, - without conversion. */ - if (conv_fn != NULL) { - result = conv_fn(value); - Py_DECREF(value); - if (result == NULL) { - Py_XDECREF(fmt_spec); - goto error; - } - value = result; - } +start_frame: + if (_Py_EnterRecursivePy(tstate)) { + goto exit_unwind; + } - /* If value is a unicode object, and there's no fmt_spec, - then we know the result of format(value) is value - itself. In that case, skip calling format(). I plan to - move this optimization in to PyObject_Format() - itself. */ - if (PyUnicode_CheckExact(value) && fmt_spec == NULL) { - /* Do nothing, just transfer ownership to result. */ - result = value; - } else { - /* Actually call format(). */ - result = PyObject_Format(value, fmt_spec); - Py_DECREF(value); - Py_XDECREF(fmt_spec); - if (result == NULL) { - goto error; - } - } +resume_frame: + SET_LOCALS_FROM_FRAME(); - PUSH(result); - DISPATCH(); +#ifdef LLTRACE + { + if (frame != &entry_frame) { + int r = PyDict_Contains(GLOBALS(), &_Py_ID(__lltrace__)); + if (r < 0) { + goto exit_unwind; + } + lltrace = r; } - - TARGET(COPY) { - assert(oparg != 0); - PyObject *peek = PEEK(oparg); - Py_INCREF(peek); - PUSH(peek); - DISPATCH(); + if (lltrace) { + lltrace_resume_frame(frame); } + } +#endif - TARGET(BINARY_OP) { - PREDICTED(BINARY_OP); - PyObject *rhs = POP(); - PyObject *lhs = TOP(); - assert(0 <= oparg); - assert((unsigned)oparg < Py_ARRAY_LENGTH(binary_ops)); - assert(binary_ops[oparg]); - PyObject *res = binary_ops[oparg](lhs, rhs); - Py_DECREF(lhs); - Py_DECREF(rhs); - SET_TOP(res); - if (res == NULL) { - goto error; - } - JUMPBY(INLINE_CACHE_ENTRIES_BINARY_OP); - DISPATCH(); - } +#ifdef Py_DEBUG + /* _PyEval_EvalFrameDefault() must not be called with an exception set, + because it can clear it (directly or indirectly) and so the + caller loses its exception */ + assert(!_PyErr_Occurred(tstate)); +#endif - TARGET(BINARY_OP_ADAPTIVE) { - assert(cframe.use_tracing == 0); - _PyBinaryOpCache *cache = (_PyBinaryOpCache *)next_instr; - if (ADAPTIVE_COUNTER_IS_ZERO(cache)) { - PyObject *lhs = SECOND(); - PyObject *rhs = TOP(); - next_instr--; - _Py_Specialize_BinaryOp(lhs, rhs, next_instr, oparg, &GETLOCAL(0)); - DISPATCH_SAME_OPARG(); - } - else { - STAT_INC(BINARY_OP, deferred); - DECREMENT_ADAPTIVE_COUNTER(cache); - JUMP_TO_INSTRUCTION(BINARY_OP); - } - } + DISPATCH(); - TARGET(SWAP) { - assert(oparg != 0); - PyObject *top = TOP(); - SET_TOP(PEEK(oparg)); - PEEK(oparg) = top; - DISPATCH(); - } +handle_eval_breaker: - TARGET(EXTENDED_ARG) { - assert(oparg); - oparg <<= 8; - oparg |= _Py_OPARG(*next_instr); - // We might be tracing. To avoid breaking tracing guarantees in - // quickened instructions, always deoptimize the next opcode: - opcode = _PyOpcode_Deopt[_Py_OPCODE(*next_instr)]; - PRE_DISPATCH_GOTO(); - // CPython hasn't traced the following instruction historically - // (DO_TRACING would clobber our extended oparg anyways), so just - // skip our usual cframe.use_tracing check before dispatch. Also, - // make sure the next instruction isn't a RESUME, since that needs - // to trace properly (and shouldn't have an extended arg anyways): - assert(opcode != RESUME); - DISPATCH_GOTO(); - } + /* Do periodic things, like check for signals and async I/0. + * We need to do reasonably frequently, but not too frequently. + * All loops should include a check of the eval breaker. + * We also check on return from any builtin function. + * + * ## More Details ### + * + * The eval loop (this function) normally executes the instructions + * of a code object sequentially. However, the runtime supports a + * number of out-of-band execution scenarios that may pause that + * sequential execution long enough to do that out-of-band work + * in the current thread using the current PyThreadState. + * + * The scenarios include: + * + * - cyclic garbage collection + * - GIL drop requests + * - "async" exceptions + * - "pending calls" (some only in the main thread) + * - signal handling (only in the main thread) + * + * When the need for one of the above is detected, the eval loop + * pauses long enough to handle the detected case. Then, if doing + * so didn't trigger an exception, the eval loop resumes executing + * the sequential instructions. + * + * To make this work, the eval loop periodically checks if any + * of the above needs to happen. The individual checks can be + * expensive if computed each time, so a while back we switched + * to using pre-computed, per-interpreter variables for the checks, + * and later consolidated that to a single "eval breaker" variable + * (now a PyInterpreterState field). + * + * For the longest time, the eval breaker check would happen + * frequently, every 5 or so times through the loop, regardless + * of what instruction ran last or what would run next. Then, in + * early 2021 (gh-18334, commit 4958f5d), we switched to checking + * the eval breaker less frequently, by hard-coding the check to + * specific places in the eval loop (e.g. certain instructions). + * The intent then was to check after returning from calls + * and on the back edges of loops. + * + * In addition to being more efficient, that approach keeps + * the eval loop from running arbitrary code between instructions + * that don't handle that well. (See gh-74174.) + * + * Currently, the eval breaker check happens here at the + * "handle_eval_breaker" label. Some instructions come here + * explicitly (goto) and some indirectly. Notably, the check + * happens on back edges in the control flow graph, which + * pretty much applies to all loops and most calls. + * (See bytecodes.c for exact information.) + * + * One consequence of this approach is that it might not be obvious + * how to force any specific thread to pick up the eval breaker, + * or for any specific thread to not pick it up. Mostly this + * involves judicious uses of locks and careful ordering of code, + * while avoiding code that might trigger the eval breaker + * until so desired. + */ + if (_Py_HandlePending(tstate) != 0) { + goto error; + } + DISPATCH(); - TARGET(EXTENDED_ARG_QUICK) { - assert(cframe.use_tracing == 0); - assert(oparg); - int oldoparg = oparg; - NEXTOPARG(); - oparg |= oldoparg << 8; - DISPATCH_GOTO(); - } + { + /* Start instructions */ +#if !USE_COMPUTED_GOTOS + dispatch_opcode: + switch (opcode) +#endif + { - TARGET(CACHE) { - Py_UNREACHABLE(); - } +#include "generated_cases.c.h" + /* INSTRUMENTED_LINE has to be here, rather than in bytecodes.c, + * because it needs to capture frame->prev_instr before it is updated, + * as happens in the standard instruction prologue. + */ #if USE_COMPUTED_GOTOS - TARGET_DO_TRACING: + TARGET_INSTRUMENTED_LINE: #else - case DO_TRACING: + case INSTRUMENTED_LINE: #endif { - assert(cframe.use_tracing); - assert(tstate->tracing == 0); - if (INSTR_OFFSET() >= frame->f_code->_co_firsttraceable) { - int instr_prev = _PyInterpreterFrame_LASTI(frame); - frame->prev_instr = next_instr; - TRACING_NEXTOPARG(); - if (opcode == RESUME) { - if (oparg < 2) { - CHECK_EVAL_BREAKER(); - } - /* Call tracing */ - TRACE_FUNCTION_ENTRY(); - DTRACE_FUNCTION_ENTRY(); - } - else { - /* line-by-line tracing support */ - if (PyDTrace_LINE_ENABLED()) { - maybe_dtrace_line(frame, &tstate->trace_info, instr_prev); - } - - if (cframe.use_tracing && - tstate->c_tracefunc != NULL && !tstate->tracing) { - int err; - /* see maybe_call_line_trace() - for expository comments */ - _PyFrame_SetStackPointer(frame, stack_pointer); - - err = maybe_call_line_trace(tstate->c_tracefunc, - tstate->c_traceobj, - tstate, frame, instr_prev); - // Reload possibly changed frame fields: - stack_pointer = _PyFrame_GetStackPointer(frame); - frame->stacktop = -1; - // next_instr is only reloaded if tracing *does not* raise. - // This is consistent with the behavior of older Python - // versions. If a trace function sets a new f_lineno and - // *then* raises, we use the *old* location when searching - // for an exception handler, displaying the traceback, and - // so on: - if (err) { - // next_instr wasn't incremented at the start of this - // instruction. Increment it before handling the error, - // so that it looks the same as a "normal" instruction: - next_instr++; - goto error; - } - // Reload next_instr. Don't increment it, though, since - // we're going to re-dispatch to the "true" instruction now: - next_instr = frame->prev_instr; - } - } + _Py_CODEUNIT *prev = frame->prev_instr; + _Py_CODEUNIT *here = frame->prev_instr = next_instr; + _PyFrame_SetStackPointer(frame, stack_pointer); + int original_opcode = _Py_call_instrumentation_line( + tstate, frame, here, prev); + stack_pointer = _PyFrame_GetStackPointer(frame); + if (original_opcode < 0) { + next_instr = here+1; + goto error; } - TRACING_NEXTOPARG(); - PRE_DISPATCH_GOTO(); + next_instr = frame->prev_instr; + if (next_instr != here) { + DISPATCH(); + } + if (_PyOpcode_Caches[original_opcode]) { + _PyBinaryOpCache *cache = (_PyBinaryOpCache *)(next_instr+1); + /* Prevent the underlying instruction from specializing + * and overwriting the instrumentation. */ + INCREMENT_ADAPTIVE_COUNTER(cache->counter); + } + opcode = original_opcode; DISPATCH_GOTO(); } + #if USE_COMPUTED_GOTOS _unknown_opcode: #else @@ -5684,10 +880,12 @@ handle_eval_breaker: #endif /* Tell C compilers not to hold the opcode variable in the loop. next_instr points the current instruction without TARGET(). */ - opcode = _Py_OPCODE(*next_instr); - fprintf(stderr, "XXX lineno: %d, opcode: %d\n", - _PyInterpreterFrame_GetLine(frame), opcode); - _PyErr_SetString(tstate, PyExc_SystemError, "unknown opcode"); + opcode = next_instr->op.code; + _PyErr_Format(tstate, PyExc_SystemError, + "%U:%d: unknown opcode %d", + frame->f_code->co_filename, + PyUnstable_InterpreterFrame_GetLine(frame), + opcode); goto error; } /* End instructions */ @@ -5696,37 +894,6 @@ handle_eval_breaker: or goto error. */ Py_UNREACHABLE(); -/* Specialization misses */ - -miss: - { - STAT_INC(opcode, miss); - opcode = _PyOpcode_Deopt[opcode]; - STAT_INC(opcode, miss); - /* The counter is always the first cache entry: */ - _Py_CODEUNIT *counter = (_Py_CODEUNIT *)next_instr; - *counter -= 1; - if (*counter == 0) { - int adaptive_opcode = _PyOpcode_Adaptive[opcode]; - assert(adaptive_opcode); - _Py_SET_OPCODE(next_instr[-1], adaptive_opcode); - STAT_INC(opcode, deopt); - *counter = adaptive_counter_start(); - } - next_instr--; - DISPATCH_GOTO(); - } - -binary_subscr_dict_error: - { - PyObject *sub = POP(); - if (!_PyErr_Occurred(tstate)) { - _PyErr_SetKeyError(sub); - } - Py_DECREF(sub); - goto error; - } - unbound_local_error: { format_exc_check_arg(tstate, PyExc_UnboundLocalError, @@ -5736,8 +903,16 @@ unbound_local_error: goto error; } +pop_4_error: + STACK_SHRINK(1); +pop_3_error: + STACK_SHRINK(1); +pop_2_error: + STACK_SHRINK(1); +pop_1_error: + STACK_SHRINK(1); error: - call_shape.kwnames = NULL; + kwnames = NULL; /* Double-check exception status. */ #ifdef NDEBUG if (!_PyErr_Occurred(tstate)) { @@ -5749,19 +924,14 @@ error: #endif /* Log traceback info. */ + assert(frame != &entry_frame); if (!_PyFrame_IsIncomplete(frame)) { PyFrameObject *f = _PyFrame_GetFrameObject(frame); if (f != NULL) { PyTraceBack_Here(f); } } - - if (tstate->c_tracefunc != NULL) { - /* Make sure state is set to FRAME_UNWINDING for tracing */ - call_exc_trace(tstate->c_tracefunc, tstate->c_traceobj, - tstate, frame); - } - + monitor_raise(tstate, frame, next_instr-1); exception_unwind: { /* We can't use frame->f_lasti here, as RERAISE may have set it */ @@ -5779,8 +949,7 @@ exception_unwind: } assert(STACK_LEVEL() == 0); _PyFrame_SetStackPointer(frame, stack_pointer); - TRACE_FUNCTION_UNWIND(); - DTRACE_FUNCTION_EXIT(); + monitor_unwind(tstate, frame, next_instr-1); goto exit_unwind; } @@ -5790,7 +959,6 @@ exception_unwind: PyObject *v = POP(); Py_XDECREF(v); } - PyObject *exc, *val, *tb; if (lasti) { int frame_lasti = _PyInterpreterFrame_LASTI(frame); PyObject *lasti = PyLong_FromLong(frame_lasti); @@ -5799,20 +967,17 @@ exception_unwind: } PUSH(lasti); } - _PyErr_Fetch(tstate, &exc, &val, &tb); + /* Make the raw exception data available to the handler, so a program can emulate the Python main loop. */ - _PyErr_NormalizeException(tstate, &exc, &val, &tb); - if (tb != NULL) - PyException_SetTraceback(val, tb); - else - PyException_SetTraceback(val, Py_None); - Py_XDECREF(tb); - Py_XDECREF(exc); - PUSH(val); + PyObject *exc = _PyErr_GetRaisedException(tstate); + PUSH(exc); JUMPTO(handler); + if (monitor_handled(tstate, frame, next_instr, exc) < 0) { + goto exception_unwind; + } /* Resume normal execution */ DISPATCH(); } @@ -5820,24 +985,31 @@ exception_unwind: exit_unwind: assert(_PyErr_Occurred(tstate)); - _Py_LeaveRecursiveCallTstate(tstate); - if (frame->is_entry) { + _Py_LeaveRecursiveCallPy(tstate); + assert(frame != &entry_frame); + // GH-99729: We need to unlink the frame *before* clearing it: + _PyInterpreterFrame *dying = frame; + frame = cframe.current_frame = dying->previous; + _PyEvalFrameClearAndPop(tstate, dying); + frame->return_offset = 0; + if (frame == &entry_frame) { /* Restore previous cframe and exit */ tstate->cframe = cframe.previous; - tstate->cframe->use_tracing = cframe.use_tracing; assert(tstate->cframe->current_frame == frame->previous); + tstate->c_recursion_remaining += PY_EVAL_C_STACK_UNITS; return NULL; } - // GH-99729: We need to unlink the frame *before* clearing it: - _PyInterpreterFrame *dying = frame; - frame = cframe.current_frame = dying->previous; - _PyEvalFrameClearAndPop(tstate, dying); resume_with_error: SET_LOCALS_FROM_FRAME(); goto error; } +#if defined(__GNUC__) +# pragma GCC diagnostic pop +#elif defined(_MSC_VER) /* MS_WINDOWS */ +# pragma warning(pop) +#endif static void format_missing(PyThreadState *tstate, const char *kind, @@ -6006,7 +1178,9 @@ positional_only_passed_as_keyword(PyThreadState *tstate, PyCodeObject *co, { int posonly_conflicts = 0; PyObject* posonly_names = PyList_New(0); - + if (posonly_names == NULL) { + goto fail; + } for(int k=0; k < co->co_posonlyargcount; k++){ PyObject* posonly_name = PyTuple_GET_ITEM(co->co_localsplusnames, k); @@ -6303,8 +1477,7 @@ initialize_locals(PyThreadState *tstate, PyFunctionObject *func, for (; i < defcount; i++) { if (localsplus[m+i] == NULL) { PyObject *def = defs[i]; - Py_INCREF(def); - localsplus[m+i] = def; + localsplus[m+i] = Py_NewRef(def); } } } @@ -6320,8 +1493,7 @@ initialize_locals(PyThreadState *tstate, PyFunctionObject *func, if (func->func_kwdefaults != NULL) { PyObject *def = PyDict_GetItemWithError(func->func_kwdefaults, varname); if (def) { - Py_INCREF(def); - localsplus[i] = def; + localsplus[i] = Py_NewRef(def); continue; } else if (_PyErr_Occurred(tstate)) { @@ -6355,27 +1527,65 @@ fail_post_args: return -1; } -/* Consumes references to func and all the args */ +static void +clear_thread_frame(PyThreadState *tstate, _PyInterpreterFrame * frame) +{ + assert(frame->owner == FRAME_OWNED_BY_THREAD); + // Make sure that this is, indeed, the top frame. We can't check this in + // _PyThreadState_PopFrame, since f_code is already cleared at that point: + assert((PyObject **)frame + frame->f_code->co_framesize == + tstate->datastack_top); + tstate->c_recursion_remaining--; + assert(frame->frame_obj == NULL || frame->frame_obj->f_frame == frame); + _PyFrame_ClearExceptCode(frame); + Py_DECREF(frame->f_code); + tstate->c_recursion_remaining++; + _PyThreadState_PopFrame(tstate, frame); +} + +static void +clear_gen_frame(PyThreadState *tstate, _PyInterpreterFrame * frame) +{ + assert(frame->owner == FRAME_OWNED_BY_GENERATOR); + PyGenObject *gen = _PyFrame_GetGenerator(frame); + gen->gi_frame_state = FRAME_CLEARED; + assert(tstate->exc_info == &gen->gi_exc_state); + tstate->exc_info = gen->gi_exc_state.previous_item; + gen->gi_exc_state.previous_item = NULL; + tstate->c_recursion_remaining--; + assert(frame->frame_obj == NULL || frame->frame_obj->f_frame == frame); + _PyFrame_ClearExceptCode(frame); + tstate->c_recursion_remaining++; + frame->previous = NULL; +} + +static void +_PyEvalFrameClearAndPop(PyThreadState *tstate, _PyInterpreterFrame * frame) +{ + if (frame->owner == FRAME_OWNED_BY_THREAD) { + clear_thread_frame(tstate, frame); + } + else { + clear_gen_frame(tstate, frame); + } +} + +/* Consumes references to func, locals and all the args */ static _PyInterpreterFrame * _PyEvalFramePushAndInit(PyThreadState *tstate, PyFunctionObject *func, PyObject *locals, PyObject* const* args, size_t argcount, PyObject *kwnames) { PyCodeObject * code = (PyCodeObject *)func->func_code; - size_t size = code->co_nlocalsplus + code->co_stacksize + FRAME_SPECIALS_SIZE; CALL_STAT_INC(frames_pushed); - _PyInterpreterFrame *frame = _PyThreadState_BumpFramePointer(tstate, size); + _PyInterpreterFrame *frame = _PyThreadState_PushFrame(tstate, code->co_framesize); if (frame == NULL) { goto fail; } - _PyFrame_InitializeSpecials(frame, func, locals, code->co_nlocalsplus); - PyObject **localsarray = &frame->localsplus[0]; - for (int i = 0; i < code->co_nlocalsplus; i++) { - localsarray[i] = NULL; - } - if (initialize_locals(tstate, func, localsarray, args, argcount, kwnames)) { - assert(frame->owner != FRAME_OWNED_BY_GENERATOR); - _PyEvalFrameClearAndPop(tstate, frame); + _PyFrame_Initialize(frame, func, locals, code, 0); + if (initialize_locals(tstate, func, frame->localsplus, args, argcount, kwnames)) { + assert(frame->owner == FRAME_OWNED_BY_THREAD); + clear_thread_frame(tstate, frame); return NULL; } return frame; @@ -6394,19 +1604,47 @@ fail: return NULL; } -static void -_PyEvalFrameClearAndPop(PyThreadState *tstate, _PyInterpreterFrame * frame) +/* Same as _PyEvalFramePushAndInit but takes an args tuple and kwargs dict. + Steals references to func, callargs and kwargs. +*/ +static _PyInterpreterFrame * +_PyEvalFramePushAndInit_Ex(PyThreadState *tstate, PyFunctionObject *func, + PyObject *locals, Py_ssize_t nargs, PyObject *callargs, PyObject *kwargs) { - // Make sure that this is, indeed, the top frame. We can't check this in - // _PyThreadState_PopFrame, since f_code is already cleared at that point: - assert((PyObject **)frame + frame->f_code->co_nlocalsplus + - frame->f_code->co_stacksize + FRAME_SPECIALS_SIZE == tstate->datastack_top); - tstate->recursion_remaining--; - assert(frame->frame_obj == NULL || frame->frame_obj->f_frame == frame); - assert(frame->owner == FRAME_OWNED_BY_THREAD); - _PyFrame_Clear(frame); - tstate->recursion_remaining++; - _PyThreadState_PopFrame(tstate, frame); + bool has_dict = (kwargs != NULL && PyDict_GET_SIZE(kwargs) > 0); + PyObject *kwnames = NULL; + PyObject *const *newargs; + if (has_dict) { + newargs = _PyStack_UnpackDict(tstate, _PyTuple_ITEMS(callargs), nargs, kwargs, &kwnames); + if (newargs == NULL) { + Py_DECREF(func); + goto error; + } + } + else { + newargs = &PyTuple_GET_ITEM(callargs, 0); + /* We need to incref all our args since the new frame steals the references. */ + for (Py_ssize_t i = 0; i < nargs; ++i) { + Py_INCREF(PyTuple_GET_ITEM(callargs, i)); + } + } + _PyInterpreterFrame *new_frame = _PyEvalFramePushAndInit( + tstate, (PyFunctionObject *)func, locals, + newargs, nargs, kwnames + ); + if (has_dict) { + _PyStack_UnpackDict_FreeNoDecRef(newargs, kwnames); + } + /* No need to decref func here because the reference has been stolen by + _PyEvalFramePushAndInit. + */ + Py_DECREF(callargs); + Py_XDECREF(kwargs); + return new_frame; +error: + Py_DECREF(callargs); + Py_XDECREF(kwargs); + return NULL; } PyObject * @@ -6416,8 +1654,9 @@ _PyEval_Vector(PyThreadState *tstate, PyFunctionObject *func, PyObject *kwnames) { /* _PyEvalFramePushAndInit consumes the references - * to func and all its arguments */ + * to func, locals and all its arguments */ Py_INCREF(func); + Py_XINCREF(locals); for (size_t i = 0; i < argcount; i++) { Py_INCREF(args[i]); } @@ -6432,13 +1671,8 @@ _PyEval_Vector(PyThreadState *tstate, PyFunctionObject *func, if (frame == NULL) { return NULL; } - PyObject *retval = _PyEval_EvalFrame(tstate, frame, 0); - assert( - _PyFrame_GetStackPointer(frame) == _PyFrame_Stackbase(frame) || - _PyFrame_GetStackPointer(frame) == frame->localsplus - ); - _PyEvalFrameClearAndPop(tstate, frame); - return retval; + EVAL_CALL_STAT_INC(EVAL_CALL_VECTOR); + return _PyEval_EvalFrame(tstate, frame, 0); } /* Legacy API */ @@ -6483,8 +1717,7 @@ PyEval_EvalCodeEx(PyObject *_co, PyObject *globals, PyObject *locals, newargs[i] = args[i]; } for (int i = 0; i < kwcount; i++) { - Py_INCREF(kws[2*i]); - PyTuple_SET_ITEM(kwnames, i, kws[2*i]); + PyTuple_SET_ITEM(kwnames, i, Py_NewRef(kws[2*i])); newargs[argcount+i] = kws[2*i+1]; } allargs = newargs; @@ -6503,6 +1736,7 @@ PyEval_EvalCodeEx(PyObject *_co, PyObject *globals, PyObject *locals, if (func == NULL) { goto fail; } + EVAL_CALL_STAT_INC(EVAL_CALL_LEGACY); res = _PyEval_Vector(tstate, func, locals, allargs, argcount, kwnames); @@ -6525,18 +1759,15 @@ do_raise(PyThreadState *tstate, PyObject *exc, PyObject *cause) if (exc == NULL) { /* Reraise */ _PyErr_StackItem *exc_info = _PyErr_GetTopmostException(tstate); - value = exc_info->exc_value; - if (Py_IsNone(value) || value == NULL) { + exc = exc_info->exc_value; + if (Py_IsNone(exc) || exc == NULL) { _PyErr_SetString(tstate, PyExc_RuntimeError, "No active exception to reraise"); return 0; } - assert(PyExceptionInstance_Check(value)); - type = PyExceptionInstance_Class(value); - Py_XINCREF(type); - Py_XINCREF(value); - PyObject *tb = PyException_GetTraceback(value); /* new ref */ - _PyErr_Restore(tstate, type, value, tb); + Py_INCREF(exc); + assert(PyExceptionInstance_Check(exc)); + _PyErr_SetRaisedException(tstate, exc); return 1; } @@ -6668,7 +1899,7 @@ exception_group_match(PyObject* exc_value, PyObject *match_type, } /* no match */ *match = Py_NewRef(Py_None); - *rest = Py_NewRef(Py_None); + *rest = Py_NewRef(exc_value); return 0; } @@ -6772,111 +2003,121 @@ Error: return 0; } -static void -call_exc_trace(Py_tracefunc func, PyObject *self, - PyThreadState *tstate, - _PyInterpreterFrame *f) +static int +do_monitor_exc(PyThreadState *tstate, _PyInterpreterFrame *frame, + _Py_CODEUNIT *instr, int event) { - PyObject *type, *value, *traceback, *orig_traceback, *arg; - int err; - _PyErr_Fetch(tstate, &type, &value, &orig_traceback); - if (value == NULL) { - value = Py_None; - Py_INCREF(value); - } - _PyErr_NormalizeException(tstate, &type, &value, &orig_traceback); - traceback = (orig_traceback != NULL) ? orig_traceback : Py_None; - arg = PyTuple_Pack(3, type, value, traceback); - if (arg == NULL) { - _PyErr_Restore(tstate, type, value, orig_traceback); - return; - } - err = call_trace(func, self, tstate, f, PyTrace_EXCEPTION, arg); - Py_DECREF(arg); + assert(event < _PY_MONITORING_UNGROUPED_EVENTS); + PyObject *exc = PyErr_GetRaisedException(); + assert(exc != NULL); + int err = _Py_call_instrumentation_arg(tstate, event, frame, instr, exc); if (err == 0) { - _PyErr_Restore(tstate, type, value, orig_traceback); + PyErr_SetRaisedException(exc); + } + else { + assert(PyErr_Occurred()); + Py_DECREF(exc); + } + return err; +} + +static inline bool +no_tools_for_global_event(PyThreadState *tstate, int event) +{ + return tstate->interp->monitors.tools[event] == 0; +} + +static inline bool +no_tools_for_local_event(PyThreadState *tstate, _PyInterpreterFrame *frame, int event) +{ + assert(event < _PY_MONITORING_LOCAL_EVENTS); + _PyCoMonitoringData *data = frame->f_code->_co_monitoring; + if (data) { + return data->active_monitors.tools[event] == 0; } else { - Py_XDECREF(type); - Py_XDECREF(value); - Py_XDECREF(orig_traceback); + return no_tools_for_global_event(tstate, event); + } +} + +static void +monitor_raise(PyThreadState *tstate, _PyInterpreterFrame *frame, + _Py_CODEUNIT *instr) +{ + if (no_tools_for_global_event(tstate, PY_MONITORING_EVENT_RAISE)) { + return; + } + do_monitor_exc(tstate, frame, instr, PY_MONITORING_EVENT_RAISE); +} + +static void +monitor_reraise(PyThreadState *tstate, _PyInterpreterFrame *frame, + _Py_CODEUNIT *instr) +{ + if (no_tools_for_global_event(tstate, PY_MONITORING_EVENT_RERAISE)) { + return; } + do_monitor_exc(tstate, frame, instr, PY_MONITORING_EVENT_RERAISE); } static int -call_trace_protected(Py_tracefunc func, PyObject *obj, - PyThreadState *tstate, _PyInterpreterFrame *frame, - int what, PyObject *arg) +monitor_stop_iteration(PyThreadState *tstate, _PyInterpreterFrame *frame, + _Py_CODEUNIT *instr) { - PyObject *type, *value, *traceback; - int err; - _PyErr_Fetch(tstate, &type, &value, &traceback); - err = call_trace(func, obj, tstate, frame, what, arg); - if (err == 0) - { - _PyErr_Restore(tstate, type, value, traceback); + if (no_tools_for_local_event(tstate, frame, PY_MONITORING_EVENT_STOP_ITERATION)) { return 0; } - else { - Py_XDECREF(type); - Py_XDECREF(value); - Py_XDECREF(traceback); - return -1; + return do_monitor_exc(tstate, frame, instr, PY_MONITORING_EVENT_STOP_ITERATION); +} + +static void +monitor_unwind(PyThreadState *tstate, + _PyInterpreterFrame *frame, + _Py_CODEUNIT *instr) +{ + if (no_tools_for_global_event(tstate, PY_MONITORING_EVENT_PY_UNWIND)) { + return; + } + do_monitor_exc(tstate, frame, instr, PY_MONITORING_EVENT_PY_UNWIND); +} + + +static int +monitor_handled(PyThreadState *tstate, + _PyInterpreterFrame *frame, + _Py_CODEUNIT *instr, PyObject *exc) +{ + if (no_tools_for_global_event(tstate, PY_MONITORING_EVENT_EXCEPTION_HANDLED)) { + return 0; } + return _Py_call_instrumentation_arg(tstate, PY_MONITORING_EVENT_EXCEPTION_HANDLED, frame, instr, exc); } static void -initialize_trace_info(PyTraceInfo *trace_info, _PyInterpreterFrame *frame) +monitor_throw(PyThreadState *tstate, + _PyInterpreterFrame *frame, + _Py_CODEUNIT *instr) { - PyCodeObject *code = frame->f_code; - if (trace_info->code != code) { - trace_info->code = code; - _PyCode_InitAddressRange(code, &trace_info->bounds); + if (no_tools_for_global_event(tstate, PY_MONITORING_EVENT_PY_THROW)) { + return; } + do_monitor_exc(tstate, frame, instr, PY_MONITORING_EVENT_PY_THROW); } void PyThreadState_EnterTracing(PyThreadState *tstate) { + assert(tstate->tracing >= 0); tstate->tracing++; - tstate->cframe->use_tracing = 0; } void PyThreadState_LeaveTracing(PyThreadState *tstate) { - assert(tstate->tracing > 0 && tstate->cframe->use_tracing == 0); + assert(tstate->tracing > 0); tstate->tracing--; - _PyThreadState_UpdateTracingState(tstate); } -static int -call_trace(Py_tracefunc func, PyObject *obj, - PyThreadState *tstate, _PyInterpreterFrame *frame, - int what, PyObject *arg) -{ - int result; - if (tstate->tracing) { - return 0; - } - PyFrameObject *f = _PyFrame_GetFrameObject(frame); - if (f == NULL) { - return -1; - } - int old_what = tstate->tracing_what; - tstate->tracing_what = what; - PyThreadState_EnterTracing(tstate); - assert(_PyInterpreterFrame_LASTI(frame) >= 0); - if (_PyCode_InitLineArray(frame->f_code)) { - return -1; - } - f->f_lineno = _PyCode_LineNumberFromArray(frame->f_code, _PyInterpreterFrame_LASTI(frame)); - result = func(obj, f, what, arg); - f->f_lineno = 0; - PyThreadState_LeaveTracing(tstate); - tstate->tracing_what = old_what; - return result; -} PyObject* _PyEval_CallTracing(PyObject *func, PyObject *args) @@ -6884,7 +2125,6 @@ _PyEval_CallTracing(PyObject *func, PyObject *args) // Save and disable tracing PyThreadState *tstate = _PyThreadState_GET(); int save_tracing = tstate->tracing; - int save_use_tracing = tstate->cframe->use_tracing; tstate->tracing = 0; // Call the tracing function @@ -6892,96 +2132,9 @@ _PyEval_CallTracing(PyObject *func, PyObject *args) // Restore tracing tstate->tracing = save_tracing; - tstate->cframe->use_tracing = save_use_tracing; - return result; -} - -/* See Objects/lnotab_notes.txt for a description of how tracing works. */ -static int -maybe_call_line_trace(Py_tracefunc func, PyObject *obj, - PyThreadState *tstate, _PyInterpreterFrame *frame, int instr_prev) -{ - int result = 0; - - /* If the last instruction falls at the start of a line or if it - represents a jump backwards, update the frame's line number and - then call the trace function if we're tracing source lines. - */ - if (_PyCode_InitLineArray(frame->f_code)) { - return -1; - } - int lastline; - if (instr_prev <= frame->f_code->_co_firsttraceable) { - lastline = -1; - } - else { - lastline = _PyCode_LineNumberFromArray(frame->f_code, instr_prev); - } - int line = _PyCode_LineNumberFromArray(frame->f_code, _PyInterpreterFrame_LASTI(frame)); - PyFrameObject *f = _PyFrame_GetFrameObject(frame); - if (f == NULL) { - return -1; - } - if (line != -1 && f->f_trace_lines) { - /* Trace backward edges (except in 'yield from') or if line number has changed */ - int trace = line != lastline || - (_PyInterpreterFrame_LASTI(frame) < instr_prev && - // SEND has no quickened forms, so no need to use _PyOpcode_Deopt - // here: - _Py_OPCODE(*frame->prev_instr) != SEND); - if (trace) { - result = call_trace(func, obj, tstate, frame, PyTrace_LINE, Py_None); - } - } - /* Always emit an opcode event if we're tracing all opcodes. */ - if (f->f_trace_opcodes && result == 0) { - result = call_trace(func, obj, tstate, frame, PyTrace_OPCODE, Py_None); - } return result; } -int -_PyEval_SetProfile(PyThreadState *tstate, Py_tracefunc func, PyObject *arg) -{ - assert(is_tstate_valid(tstate)); - /* The caller must hold the GIL */ - assert(PyGILState_Check()); - - static int reentrant = 0; - if (reentrant) { - _PyErr_SetString(tstate, PyExc_RuntimeError, "Cannot install a profile function " - "while another profile function is being installed"); - reentrant = 0; - return -1; - } - reentrant = 1; - - /* Call _PySys_Audit() in the context of the current thread state, - even if tstate is not the current thread state. */ - PyThreadState *current_tstate = _PyThreadState_GET(); - if (_PySys_Audit(current_tstate, "sys.setprofile", NULL) < 0) { - reentrant = 0; - return -1; - } - - PyObject *profileobj = tstate->c_profileobj; - - tstate->c_profilefunc = NULL; - tstate->c_profileobj = NULL; - /* Must make sure that tracing is not ignored if 'profileobj' is freed */ - _PyThreadState_UpdateTracingState(tstate); - Py_XDECREF(profileobj); - - Py_XINCREF(arg); - tstate->c_profileobj = arg; - tstate->c_profilefunc = func; - - /* Flag that tracing or profiling is turned on */ - _PyThreadState_UpdateTracingState(tstate); - reentrant = 0; - return 0; -} - void PyEval_SetProfile(Py_tracefunc func, PyObject *arg) { @@ -6992,47 +2145,25 @@ PyEval_SetProfile(Py_tracefunc func, PyObject *arg) } } -int -_PyEval_SetTrace(PyThreadState *tstate, Py_tracefunc func, PyObject *arg) +void +PyEval_SetProfileAllThreads(Py_tracefunc func, PyObject *arg) { - assert(is_tstate_valid(tstate)); - /* The caller must hold the GIL */ - assert(PyGILState_Check()); - - static int reentrant = 0; + PyThreadState *this_tstate = _PyThreadState_GET(); + PyInterpreterState* interp = this_tstate->interp; - if (reentrant) { - _PyErr_SetString(tstate, PyExc_RuntimeError, "Cannot install a trace function " - "while another trace function is being installed"); - reentrant = 0; - return -1; - } - reentrant = 1; + _PyRuntimeState *runtime = &_PyRuntime; + HEAD_LOCK(runtime); + PyThreadState* ts = PyInterpreterState_ThreadHead(interp); + HEAD_UNLOCK(runtime); - /* Call _PySys_Audit() in the context of the current thread state, - even if tstate is not the current thread state. */ - PyThreadState *current_tstate = _PyThreadState_GET(); - if (_PySys_Audit(current_tstate, "sys.settrace", NULL) < 0) { - reentrant = 0; - return -1; + while (ts) { + if (_PyEval_SetProfile(ts, func, arg) < 0) { + _PyErr_WriteUnraisableMsg("in PyEval_SetProfileAllThreads", NULL); + } + HEAD_LOCK(runtime); + ts = PyThreadState_Next(ts); + HEAD_UNLOCK(runtime); } - - PyObject *traceobj = tstate->c_traceobj; - - tstate->c_tracefunc = NULL; - tstate->c_traceobj = NULL; - /* Must make sure that profiling is not ignored if 'traceobj' is freed */ - _PyThreadState_UpdateTracingState(tstate); - Py_XINCREF(arg); - Py_XDECREF(traceobj); - tstate->c_traceobj = arg; - tstate->c_tracefunc = func; - - /* Flag that tracing or profiling is turned on */ - _PyThreadState_UpdateTracingState(tstate); - - reentrant = 0; - return 0; } void @@ -7045,6 +2176,26 @@ PyEval_SetTrace(Py_tracefunc func, PyObject *arg) } } +void +PyEval_SetTraceAllThreads(Py_tracefunc func, PyObject *arg) +{ + PyThreadState *this_tstate = _PyThreadState_GET(); + PyInterpreterState* interp = this_tstate->interp; + + _PyRuntimeState *runtime = &_PyRuntime; + HEAD_LOCK(runtime); + PyThreadState* ts = PyInterpreterState_ThreadHead(interp); + HEAD_UNLOCK(runtime); + + while (ts) { + if (_PyEval_SetTrace(ts, func, arg) < 0) { + _PyErr_WriteUnraisableMsg("in PyEval_SetTraceAllThreads", NULL); + } + HEAD_LOCK(runtime); + ts = PyThreadState_Next(ts); + HEAD_UNLOCK(runtime); + } +} int _PyEval_SetCoroutineOriginTrackingDepth(int depth) @@ -7075,8 +2226,7 @@ _PyEval_SetAsyncGenFirstiter(PyObject *firstiter) return -1; } - Py_XINCREF(firstiter); - Py_XSETREF(tstate->async_gen_firstiter, firstiter); + Py_XSETREF(tstate->async_gen_firstiter, Py_XNewRef(firstiter)); return 0; } @@ -7096,8 +2246,7 @@ _PyEval_SetAsyncGenFinalizer(PyObject *finalizer) return -1; } - Py_XINCREF(finalizer); - Py_XSETREF(tstate->async_gen_finalizer, finalizer); + Py_XSETREF(tstate->async_gen_finalizer, Py_XNewRef(finalizer)); return 0; } @@ -7112,16 +2261,13 @@ _PyInterpreterFrame * _PyEval_GetFrame(void) { PyThreadState *tstate = _PyThreadState_GET(); - return tstate->cframe->current_frame; + return _PyThreadState_GetFrame(tstate); } PyFrameObject * PyEval_GetFrame(void) { _PyInterpreterFrame *frame = _PyEval_GetFrame(); - while (frame && _PyFrame_IsIncomplete(frame)) { - frame = frame->previous; - } if (frame == NULL) { return NULL; } @@ -7135,7 +2281,7 @@ PyEval_GetFrame(void) PyObject * _PyEval_GetBuiltins(PyThreadState *tstate) { - _PyInterpreterFrame *frame = tstate->cframe->current_frame; + _PyInterpreterFrame *frame = _PyThreadState_GetFrame(tstate); if (frame != NULL) { return frame->f_builtins; } @@ -7174,7 +2320,7 @@ PyObject * PyEval_GetLocals(void) { PyThreadState *tstate = _PyThreadState_GET(); - _PyInterpreterFrame *current_frame = tstate->cframe->current_frame; + _PyInterpreterFrame *current_frame = _PyThreadState_GetFrame(tstate); if (current_frame == NULL) { _PyErr_SetString(tstate, PyExc_SystemError, "frame does not exist"); return NULL; @@ -7189,11 +2335,24 @@ PyEval_GetLocals(void) return locals; } +PyObject * +_PyEval_GetFrameLocals(void) +{ + PyThreadState *tstate = _PyThreadState_GET(); + _PyInterpreterFrame *current_frame = _PyThreadState_GetFrame(tstate); + if (current_frame == NULL) { + _PyErr_SetString(tstate, PyExc_SystemError, "frame does not exist"); + return NULL; + } + + return _PyFrame_GetLocals(current_frame, 1); +} + PyObject * PyEval_GetGlobals(void) { PyThreadState *tstate = _PyThreadState_GET(); - _PyInterpreterFrame *current_frame = tstate->cframe->current_frame; + _PyInterpreterFrame *current_frame = _PyThreadState_GetFrame(tstate); if (current_frame == NULL) { return NULL; } @@ -7245,114 +2404,6 @@ PyEval_GetFuncDesc(PyObject *func) return " object"; } -#define C_TRACE(x, call) \ -if (use_tracing && tstate->c_profilefunc) { \ - if (call_trace(tstate->c_profilefunc, tstate->c_profileobj, \ - tstate, tstate->cframe->current_frame, \ - PyTrace_C_CALL, func)) { \ - x = NULL; \ - } \ - else { \ - x = call; \ - if (tstate->c_profilefunc != NULL) { \ - if (x == NULL) { \ - call_trace_protected(tstate->c_profilefunc, \ - tstate->c_profileobj, \ - tstate, tstate->cframe->current_frame, \ - PyTrace_C_EXCEPTION, func); \ - /* XXX should pass (type, value, tb) */ \ - } else { \ - if (call_trace(tstate->c_profilefunc, \ - tstate->c_profileobj, \ - tstate, tstate->cframe->current_frame, \ - PyTrace_C_RETURN, func)) { \ - Py_DECREF(x); \ - x = NULL; \ - } \ - } \ - } \ - } \ -} else { \ - x = call; \ - } - - -static PyObject * -trace_call_function(PyThreadState *tstate, - PyObject *func, - PyObject **args, Py_ssize_t nargs, - PyObject *kwnames) -{ - int use_tracing = 1; - PyObject *x; - if (PyCFunction_CheckExact(func) || PyCMethod_CheckExact(func)) { - C_TRACE(x, PyObject_Vectorcall(func, args, nargs, kwnames)); - return x; - } - else if (Py_IS_TYPE(func, &PyMethodDescr_Type) && nargs > 0) { - /* We need to create a temporary bound method as argument - for profiling. - - If nargs == 0, then this cannot work because we have no - "self". In any case, the call itself would raise - TypeError (foo needs an argument), so we just skip - profiling. */ - PyObject *self = args[0]; - func = Py_TYPE(func)->tp_descr_get(func, self, (PyObject*)Py_TYPE(self)); - if (func == NULL) { - return NULL; - } - C_TRACE(x, PyObject_Vectorcall(func, - args+1, nargs-1, - kwnames)); - Py_DECREF(func); - return x; - } - return PyObject_Vectorcall(func, args, nargs | PY_VECTORCALL_ARGUMENTS_OFFSET, kwnames); -} - -static PyObject * -do_call_core(PyThreadState *tstate, - PyObject *func, - PyObject *callargs, - PyObject *kwdict, - int use_tracing - ) -{ - PyObject *result; - - if (PyCFunction_CheckExact(func) || PyCMethod_CheckExact(func)) { - C_TRACE(result, PyObject_Call(func, callargs, kwdict)); - return result; - } - else if (Py_IS_TYPE(func, &PyMethodDescr_Type)) { - Py_ssize_t nargs = PyTuple_GET_SIZE(callargs); - if (nargs > 0 && use_tracing) { - /* We need to create a temporary bound method as argument - for profiling. - - If nargs == 0, then this cannot work because we have no - "self". In any case, the call itself would raise - TypeError (foo needs an argument), so we just skip - profiling. */ - PyObject *self = PyTuple_GET_ITEM(callargs, 0); - func = Py_TYPE(func)->tp_descr_get(func, self, (PyObject*)Py_TYPE(self)); - if (func == NULL) { - return NULL; - } - - C_TRACE(result, _PyObject_FastCallDictTstate( - tstate, func, - &_PyTuple_ITEMS(callargs)[1], - nargs - 1, - kwdict)); - Py_DECREF(func); - return result; - } - } - return PyObject_Call(func, callargs, kwdict); -} - /* Extract a slice index from a PyLong or an object with the nb_index slot defined, and store in *pi. Silently reduce values larger than PY_SSIZE_T_MAX to PY_SSIZE_T_MAX, @@ -7417,7 +2468,7 @@ import_name(PyThreadState *tstate, _PyInterpreterFrame *frame, } PyObject *locals = frame->f_locals; /* Fast path for not overloaded __import__. */ - if (import_func == tstate->interp->import_func) { + if (_PyImport_IsDefaultImportFunc(tstate->interp, import_func)) { int ilevel = _PyLong_AsInt(level); if (ilevel == -1 && _PyErr_Occurred(tstate)) { return NULL; @@ -7494,7 +2545,7 @@ import_from(PyThreadState *tstate, PyObject *v, PyObject *name) name, pkgname_or_unknown ); /* NULL checks for errmsg and pkgname done by PyErr_SetImportError. */ - PyErr_SetImportError(errmsg, pkgname, NULL); + _PyErr_SetImportErrorWithNameFrom(errmsg, pkgname, NULL, name); } else { PyObject *spec = PyObject_GetAttr(v, &_Py_ID(__spec__)); @@ -7507,7 +2558,7 @@ import_from(PyThreadState *tstate, PyObject *v, PyObject *name) errmsg = PyUnicode_FromFormat(fmt, name, pkgname_or_unknown, pkgpath); /* NULL checks for errmsg and pkgname done by PyErr_SetImportError. */ - PyErr_SetImportError(errmsg, pkgname, pkgpath); + _PyErr_SetImportErrorWithNameFrom(errmsg, pkgname, pkgpath, name); } Py_XDECREF(errmsg); @@ -7516,95 +2567,6 @@ import_from(PyThreadState *tstate, PyObject *v, PyObject *name) return NULL; } -static int -import_all_from(PyThreadState *tstate, PyObject *locals, PyObject *v) -{ - PyObject *all, *dict, *name, *value; - int skip_leading_underscores = 0; - int pos, err; - - if (_PyObject_LookupAttr(v, &_Py_ID(__all__), &all) < 0) { - return -1; /* Unexpected error */ - } - if (all == NULL) { - if (_PyObject_LookupAttr(v, &_Py_ID(__dict__), &dict) < 0) { - return -1; - } - if (dict == NULL) { - _PyErr_SetString(tstate, PyExc_ImportError, - "from-import-* object has no __dict__ and no __all__"); - return -1; - } - all = PyMapping_Keys(dict); - Py_DECREF(dict); - if (all == NULL) - return -1; - skip_leading_underscores = 1; - } - - for (pos = 0, err = 0; ; pos++) { - name = PySequence_GetItem(all, pos); - if (name == NULL) { - if (!_PyErr_ExceptionMatches(tstate, PyExc_IndexError)) { - err = -1; - } - else { - _PyErr_Clear(tstate); - } - break; - } - if (!PyUnicode_Check(name)) { - PyObject *modname = PyObject_GetAttr(v, &_Py_ID(__name__)); - if (modname == NULL) { - Py_DECREF(name); - err = -1; - break; - } - if (!PyUnicode_Check(modname)) { - _PyErr_Format(tstate, PyExc_TypeError, - "module __name__ must be a string, not %.100s", - Py_TYPE(modname)->tp_name); - } - else { - _PyErr_Format(tstate, PyExc_TypeError, - "%s in %U.%s must be str, not %.100s", - skip_leading_underscores ? "Key" : "Item", - modname, - skip_leading_underscores ? "__dict__" : "__all__", - Py_TYPE(name)->tp_name); - } - Py_DECREF(modname); - Py_DECREF(name); - err = -1; - break; - } - if (skip_leading_underscores) { - if (PyUnicode_READY(name) == -1) { - Py_DECREF(name); - err = -1; - break; - } - if (PyUnicode_READ_CHAR(name, 0) == '_') { - Py_DECREF(name); - continue; - } - } - value = PyObject_GetAttr(v, name); - if (value == NULL) - err = -1; - else if (PyDict_CheckExact(locals)) - err = PyDict_SetItem(locals, name, value); - else - err = PyObject_SetItem(locals, name, value); - Py_DECREF(name); - Py_XDECREF(value); - if (err != 0) - break; - } - Py_DECREF(all); - return err; -} - #define CANNOT_CATCH_MSG "catching classes that do not inherit from "\ "BaseException is not allowed" @@ -7714,13 +2676,13 @@ format_kwargs_error(PyThreadState *tstate, PyObject *func, PyObject *kwargs) } } else if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { - PyObject *exc, *val, *tb; - _PyErr_Fetch(tstate, &exc, &val, &tb); - if (val && PyTuple_Check(val) && PyTuple_GET_SIZE(val) == 1) { + PyObject *exc = _PyErr_GetRaisedException(tstate); + PyObject *args = ((PyBaseExceptionObject *)exc)->args; + if (exc && PyTuple_Check(args) && PyTuple_GET_SIZE(args) == 1) { _PyErr_Clear(tstate); PyObject *funcstr = _PyObject_FunctionStr(func); if (funcstr != NULL) { - PyObject *key = PyTuple_GET_ITEM(val, 0); + PyObject *key = PyTuple_GET_ITEM(args, 0); _PyErr_Format( tstate, PyExc_TypeError, "%U got multiple values for keyword argument '%S'", @@ -7728,11 +2690,9 @@ format_kwargs_error(PyThreadState *tstate, PyObject *func, PyObject *kwargs) Py_DECREF(funcstr); } Py_XDECREF(exc); - Py_XDECREF(val); - Py_XDECREF(tb); } else { - _PyErr_Restore(tstate, exc, val, tb); + _PyErr_SetRaisedException(tstate, exc); } } } @@ -7754,18 +2714,15 @@ format_exc_check_arg(PyThreadState *tstate, PyObject *exc, if (exc == PyExc_NameError) { // Include the name in the NameError exceptions to offer suggestions later. - PyObject *type, *value, *traceback; - PyErr_Fetch(&type, &value, &traceback); - PyErr_NormalizeException(&type, &value, &traceback); - if (PyErr_GivenExceptionMatches(value, PyExc_NameError)) { - PyNameErrorObject* exc = (PyNameErrorObject*) value; - if (exc->name == NULL) { + PyObject *exc = PyErr_GetRaisedException(); + if (PyErr_GivenExceptionMatches(exc, PyExc_NameError)) { + if (((PyNameErrorObject*)exc)->name == NULL) { // We do not care if this fails because we are going to restore the // NameError anyway. - (void)PyObject_SetAttr(value, &_Py_ID(name), obj); + (void)PyObject_SetAttr(exc, &_Py_ID(name), obj); } } - PyErr_Restore(type, value, traceback); + PyErr_SetRaisedException(exc); } } @@ -7777,7 +2734,7 @@ format_exc_unbound(PyThreadState *tstate, PyCodeObject *co, int oparg) if (_PyErr_Occurred(tstate)) return; name = PyTuple_GET_ITEM(co->co_localsplusnames, oparg); - if (oparg < co->co_nplaincellvars + co->co_nlocals) { + if (oparg < PyCode_GetFirstFree(co)) { format_exc_check_arg(tstate, PyExc_UnboundLocalError, UNBOUNDLOCAL_ERROR_MSG, name); } else { @@ -7805,64 +2762,9 @@ format_awaitable_error(PyThreadState *tstate, PyTypeObject *type, int oparg) } } -#ifdef Py_STATS - -static PyObject * -getarray(uint64_t a[256]) -{ - int i; - PyObject *l = PyList_New(256); - if (l == NULL) return NULL; - for (i = 0; i < 256; i++) { - PyObject *x = PyLong_FromUnsignedLongLong(a[i]); - if (x == NULL) { - Py_DECREF(l); - return NULL; - } - PyList_SET_ITEM(l, i, x); - } - for (i = 0; i < 256; i++) - a[i] = 0; - return l; -} - -PyObject * -_Py_GetDXProfile(PyObject *self, PyObject *args) -{ - int i; - PyObject *l = PyList_New(257); - if (l == NULL) return NULL; - for (i = 0; i < 256; i++) { - PyObject *x = getarray(_py_stats.opcode_stats[i].pair_count); - if (x == NULL) { - Py_DECREF(l); - return NULL; - } - PyList_SET_ITEM(l, i, x); - } - PyObject *counts = PyList_New(256); - if (counts == NULL) { - Py_DECREF(l); - return NULL; - } - for (i = 0; i < 256; i++) { - PyObject *x = PyLong_FromUnsignedLongLong( - _py_stats.opcode_stats[i].execution_count); - if (x == NULL) { - Py_DECREF(counts); - Py_DECREF(l); - return NULL; - } - PyList_SET_ITEM(counts, i, x); - } - PyList_SET_ITEM(l, 256, counts); - return l; -} - -#endif Py_ssize_t -_PyEval_RequestCodeExtraIndex(freefunc free) +PyUnstable_Eval_RequestCodeExtraIndex(freefunc free) { PyInterpreterState *interp = _PyInterpreterState_GET(); Py_ssize_t new_index; @@ -7875,81 +2777,14 @@ _PyEval_RequestCodeExtraIndex(freefunc free) return new_index; } -static void -dtrace_function_entry(_PyInterpreterFrame *frame) -{ - const char *filename; - const char *funcname; - int lineno; - - PyCodeObject *code = frame->f_code; - filename = PyUnicode_AsUTF8(code->co_filename); - funcname = PyUnicode_AsUTF8(code->co_name); - lineno = _PyInterpreterFrame_GetLine(frame); - - PyDTrace_FUNCTION_ENTRY(filename, funcname, lineno); -} - -static void -dtrace_function_return(_PyInterpreterFrame *frame) -{ - const char *filename; - const char *funcname; - int lineno; - - PyCodeObject *code = frame->f_code; - filename = PyUnicode_AsUTF8(code->co_filename); - funcname = PyUnicode_AsUTF8(code->co_name); - lineno = _PyInterpreterFrame_GetLine(frame); - - PyDTrace_FUNCTION_RETURN(filename, funcname, lineno); -} - -/* DTrace equivalent of maybe_call_line_trace. */ -static void -maybe_dtrace_line(_PyInterpreterFrame *frame, - PyTraceInfo *trace_info, - int instr_prev) -{ - const char *co_filename, *co_name; - - /* If the last instruction executed isn't in the current - instruction window, reset the window. - */ - initialize_trace_info(trace_info, frame); - int lastline = _PyCode_CheckLineNumber(instr_prev*sizeof(_Py_CODEUNIT), &trace_info->bounds); - int addr = _PyInterpreterFrame_LASTI(frame) * sizeof(_Py_CODEUNIT); - int line = _PyCode_CheckLineNumber(addr, &trace_info->bounds); - if (line != -1) { - /* Trace backward edges or first instruction of a new line */ - if (_PyInterpreterFrame_LASTI(frame) < instr_prev || - (line != lastline && addr == trace_info->bounds.ar_start)) - { - co_filename = PyUnicode_AsUTF8(frame->f_code->co_filename); - if (!co_filename) { - co_filename = "?"; - } - co_name = PyUnicode_AsUTF8(frame->f_code->co_name); - if (!co_name) { - co_name = "?"; - } - PyDTrace_LINE(co_filename, co_name, line); - } - } -} - /* Implement Py_EnterRecursiveCall() and Py_LeaveRecursiveCall() as functions for the limited API. */ -#undef Py_EnterRecursiveCall - int Py_EnterRecursiveCall(const char *where) { return _Py_EnterRecursiveCall(where); } -#undef Py_LeaveRecursiveCall - void Py_LeaveRecursiveCall(void) { _Py_LeaveRecursiveCall(); diff --git a/Python/ceval_gil.c b/Python/ceval_gil.c new file mode 100644 index 00000000..aacf2b5c --- /dev/null +++ b/Python/ceval_gil.c @@ -0,0 +1,1121 @@ + +#include "Python.h" +#include "pycore_atomic.h" // _Py_atomic_int +#include "pycore_ceval.h" // _PyEval_SignalReceived() +#include "pycore_pyerrors.h" // _PyErr_GetRaisedException() +#include "pycore_pylifecycle.h" // _PyErr_Print() +#include "pycore_initconfig.h" // _PyStatus_OK() +#include "pycore_interp.h" // _Py_RunGC() +#include "pycore_pymem.h" // _PyMem_IsPtrFreed() + +/* + Notes about the implementation: + + - The GIL is just a boolean variable (locked) whose access is protected + by a mutex (gil_mutex), and whose changes are signalled by a condition + variable (gil_cond). gil_mutex is taken for short periods of time, + and therefore mostly uncontended. + + - In the GIL-holding thread, the main loop (PyEval_EvalFrameEx) must be + able to release the GIL on demand by another thread. A volatile boolean + variable (gil_drop_request) is used for that purpose, which is checked + at every turn of the eval loop. That variable is set after a wait of + `interval` microseconds on `gil_cond` has timed out. + + [Actually, another volatile boolean variable (eval_breaker) is used + which ORs several conditions into one. Volatile booleans are + sufficient as inter-thread signalling means since Python is run + on cache-coherent architectures only.] + + - A thread wanting to take the GIL will first let pass a given amount of + time (`interval` microseconds) before setting gil_drop_request. This + encourages a defined switching period, but doesn't enforce it since + opcodes can take an arbitrary time to execute. + + The `interval` value is available for the user to read and modify + using the Python API `sys.{get,set}switchinterval()`. + + - When a thread releases the GIL and gil_drop_request is set, that thread + ensures that another GIL-awaiting thread gets scheduled. + It does so by waiting on a condition variable (switch_cond) until + the value of last_holder is changed to something else than its + own thread state pointer, indicating that another thread was able to + take the GIL. + + This is meant to prohibit the latency-adverse behaviour on multi-core + machines where one thread would speculatively release the GIL, but still + run and end up being the first to re-acquire it, making the "timeslices" + much longer than expected. + (Note: this mechanism is enabled with FORCE_SWITCHING above) +*/ + +// GH-89279: Force inlining by using a macro. +#if defined(_MSC_VER) && SIZEOF_INT == 4 +#define _Py_atomic_load_relaxed_int32(ATOMIC_VAL) (assert(sizeof((ATOMIC_VAL)->_value) == 4), *((volatile int*)&((ATOMIC_VAL)->_value))) +#else +#define _Py_atomic_load_relaxed_int32(ATOMIC_VAL) _Py_atomic_load_relaxed(ATOMIC_VAL) +#endif + +/* This can set eval_breaker to 0 even though gil_drop_request became + 1. We believe this is all right because the eval loop will release + the GIL eventually anyway. */ +static inline void +COMPUTE_EVAL_BREAKER(PyInterpreterState *interp, + struct _ceval_runtime_state *ceval, + struct _ceval_state *ceval2) +{ + _Py_atomic_store_relaxed(&ceval2->eval_breaker, + _Py_atomic_load_relaxed_int32(&ceval2->gil_drop_request) + | (_Py_atomic_load_relaxed_int32(&ceval->signals_pending) + && _Py_ThreadCanHandleSignals(interp)) + | (_Py_atomic_load_relaxed_int32(&ceval2->pending.calls_to_do)) + | (_Py_IsMainThread() && _Py_IsMainInterpreter(interp) + &&_Py_atomic_load_relaxed_int32(&ceval->pending_mainthread.calls_to_do)) + | ceval2->pending.async_exc + | _Py_atomic_load_relaxed_int32(&ceval2->gc_scheduled)); +} + + +static inline void +SET_GIL_DROP_REQUEST(PyInterpreterState *interp) +{ + struct _ceval_state *ceval2 = &interp->ceval; + _Py_atomic_store_relaxed(&ceval2->gil_drop_request, 1); + _Py_atomic_store_relaxed(&ceval2->eval_breaker, 1); +} + + +static inline void +RESET_GIL_DROP_REQUEST(PyInterpreterState *interp) +{ + struct _ceval_runtime_state *ceval = &interp->runtime->ceval; + struct _ceval_state *ceval2 = &interp->ceval; + _Py_atomic_store_relaxed(&ceval2->gil_drop_request, 0); + COMPUTE_EVAL_BREAKER(interp, ceval, ceval2); +} + + +static inline void +SIGNAL_PENDING_CALLS(struct _pending_calls *pending, PyInterpreterState *interp) +{ + struct _ceval_runtime_state *ceval = &interp->runtime->ceval; + struct _ceval_state *ceval2 = &interp->ceval; + _Py_atomic_store_relaxed(&pending->calls_to_do, 1); + COMPUTE_EVAL_BREAKER(interp, ceval, ceval2); +} + + +static inline void +UNSIGNAL_PENDING_CALLS(PyInterpreterState *interp) +{ + struct _ceval_runtime_state *ceval = &interp->runtime->ceval; + struct _ceval_state *ceval2 = &interp->ceval; + if (_Py_IsMainThread() && _Py_IsMainInterpreter(interp)) { + _Py_atomic_store_relaxed(&ceval->pending_mainthread.calls_to_do, 0); + } + _Py_atomic_store_relaxed(&ceval2->pending.calls_to_do, 0); + COMPUTE_EVAL_BREAKER(interp, ceval, ceval2); +} + + +static inline void +SIGNAL_PENDING_SIGNALS(PyInterpreterState *interp, int force) +{ + struct _ceval_runtime_state *ceval = &interp->runtime->ceval; + struct _ceval_state *ceval2 = &interp->ceval; + _Py_atomic_store_relaxed(&ceval->signals_pending, 1); + if (force) { + _Py_atomic_store_relaxed(&ceval2->eval_breaker, 1); + } + else { + /* eval_breaker is not set to 1 if thread_can_handle_signals() is false */ + COMPUTE_EVAL_BREAKER(interp, ceval, ceval2); + } +} + + +static inline void +UNSIGNAL_PENDING_SIGNALS(PyInterpreterState *interp) +{ + struct _ceval_runtime_state *ceval = &interp->runtime->ceval; + struct _ceval_state *ceval2 = &interp->ceval; + _Py_atomic_store_relaxed(&ceval->signals_pending, 0); + COMPUTE_EVAL_BREAKER(interp, ceval, ceval2); +} + + +static inline void +SIGNAL_ASYNC_EXC(PyInterpreterState *interp) +{ + struct _ceval_state *ceval2 = &interp->ceval; + ceval2->pending.async_exc = 1; + _Py_atomic_store_relaxed(&ceval2->eval_breaker, 1); +} + + +static inline void +UNSIGNAL_ASYNC_EXC(PyInterpreterState *interp) +{ + struct _ceval_runtime_state *ceval = &interp->runtime->ceval; + struct _ceval_state *ceval2 = &interp->ceval; + ceval2->pending.async_exc = 0; + COMPUTE_EVAL_BREAKER(interp, ceval, ceval2); +} + +#ifndef NDEBUG +/* Ensure that tstate is valid */ +static int +is_tstate_valid(PyThreadState *tstate) +{ + assert(!_PyMem_IsPtrFreed(tstate)); + assert(!_PyMem_IsPtrFreed(tstate->interp)); + return 1; +} +#endif + +/* + * Implementation of the Global Interpreter Lock (GIL). + */ + +#include <stdlib.h> +#include <errno.h> + +#include "pycore_atomic.h" + + +#include "condvar.h" + +#define MUTEX_INIT(mut) \ + if (PyMUTEX_INIT(&(mut))) { \ + Py_FatalError("PyMUTEX_INIT(" #mut ") failed"); }; +#define MUTEX_FINI(mut) \ + if (PyMUTEX_FINI(&(mut))) { \ + Py_FatalError("PyMUTEX_FINI(" #mut ") failed"); }; +#define MUTEX_LOCK(mut) \ + if (PyMUTEX_LOCK(&(mut))) { \ + Py_FatalError("PyMUTEX_LOCK(" #mut ") failed"); }; +#define MUTEX_UNLOCK(mut) \ + if (PyMUTEX_UNLOCK(&(mut))) { \ + Py_FatalError("PyMUTEX_UNLOCK(" #mut ") failed"); }; + +#define COND_INIT(cond) \ + if (PyCOND_INIT(&(cond))) { \ + Py_FatalError("PyCOND_INIT(" #cond ") failed"); }; +#define COND_FINI(cond) \ + if (PyCOND_FINI(&(cond))) { \ + Py_FatalError("PyCOND_FINI(" #cond ") failed"); }; +#define COND_SIGNAL(cond) \ + if (PyCOND_SIGNAL(&(cond))) { \ + Py_FatalError("PyCOND_SIGNAL(" #cond ") failed"); }; +#define COND_WAIT(cond, mut) \ + if (PyCOND_WAIT(&(cond), &(mut))) { \ + Py_FatalError("PyCOND_WAIT(" #cond ") failed"); }; +#define COND_TIMED_WAIT(cond, mut, microseconds, timeout_result) \ + { \ + int r = PyCOND_TIMEDWAIT(&(cond), &(mut), (microseconds)); \ + if (r < 0) \ + Py_FatalError("PyCOND_WAIT(" #cond ") failed"); \ + if (r) /* 1 == timeout, 2 == impl. can't say, so assume timeout */ \ + timeout_result = 1; \ + else \ + timeout_result = 0; \ + } \ + + +#define DEFAULT_INTERVAL 5000 + +static void _gil_initialize(struct _gil_runtime_state *gil) +{ + _Py_atomic_int uninitialized = {-1}; + gil->locked = uninitialized; + gil->interval = DEFAULT_INTERVAL; +} + +static int gil_created(struct _gil_runtime_state *gil) +{ + if (gil == NULL) { + return 0; + } + return (_Py_atomic_load_explicit(&gil->locked, _Py_memory_order_acquire) >= 0); +} + +static void create_gil(struct _gil_runtime_state *gil) +{ + MUTEX_INIT(gil->mutex); +#ifdef FORCE_SWITCHING + MUTEX_INIT(gil->switch_mutex); +#endif + COND_INIT(gil->cond); +#ifdef FORCE_SWITCHING + COND_INIT(gil->switch_cond); +#endif + _Py_atomic_store_relaxed(&gil->last_holder, 0); + _Py_ANNOTATE_RWLOCK_CREATE(&gil->locked); + _Py_atomic_store_explicit(&gil->locked, 0, _Py_memory_order_release); +} + +static void destroy_gil(struct _gil_runtime_state *gil) +{ + /* some pthread-like implementations tie the mutex to the cond + * and must have the cond destroyed first. + */ + COND_FINI(gil->cond); + MUTEX_FINI(gil->mutex); +#ifdef FORCE_SWITCHING + COND_FINI(gil->switch_cond); + MUTEX_FINI(gil->switch_mutex); +#endif + _Py_atomic_store_explicit(&gil->locked, -1, + _Py_memory_order_release); + _Py_ANNOTATE_RWLOCK_DESTROY(&gil->locked); +} + +#ifdef HAVE_FORK +static void recreate_gil(struct _gil_runtime_state *gil) +{ + _Py_ANNOTATE_RWLOCK_DESTROY(&gil->locked); + /* XXX should we destroy the old OS resources here? */ + create_gil(gil); +} +#endif + +static void +drop_gil(struct _ceval_state *ceval, PyThreadState *tstate) +{ + /* If tstate is NULL, the caller is indicating that we're releasing + the GIL for the last time in this thread. This is particularly + relevant when the current thread state is finalizing or its + interpreter is finalizing (either may be in an inconsistent + state). In that case the current thread will definitely + never try to acquire the GIL again. */ + // XXX It may be more correct to check tstate->_status.finalizing. + // XXX assert(tstate == NULL || !tstate->_status.cleared); + + struct _gil_runtime_state *gil = ceval->gil; + if (!_Py_atomic_load_relaxed(&gil->locked)) { + Py_FatalError("drop_gil: GIL is not locked"); + } + + /* tstate is allowed to be NULL (early interpreter init) */ + if (tstate != NULL) { + /* Sub-interpreter support: threads might have been switched + under our feet using PyThreadState_Swap(). Fix the GIL last + holder variable so that our heuristics work. */ + _Py_atomic_store_relaxed(&gil->last_holder, (uintptr_t)tstate); + } + + MUTEX_LOCK(gil->mutex); + _Py_ANNOTATE_RWLOCK_RELEASED(&gil->locked, /*is_write=*/1); + _Py_atomic_store_relaxed(&gil->locked, 0); + COND_SIGNAL(gil->cond); + MUTEX_UNLOCK(gil->mutex); + +#ifdef FORCE_SWITCHING + /* We check tstate first in case we might be releasing the GIL for + the last time in this thread. In that case there's a possible + race with tstate->interp getting deleted after gil->mutex is + unlocked and before the following code runs, leading to a crash. + We can use (tstate == NULL) to indicate the thread is done with + the GIL, and that's the only time we might delete the + interpreter, so checking tstate first prevents the crash. + See https://github.com/python/cpython/issues/104341. */ + if (tstate != NULL && _Py_atomic_load_relaxed(&ceval->gil_drop_request)) { + MUTEX_LOCK(gil->switch_mutex); + /* Not switched yet => wait */ + if (((PyThreadState*)_Py_atomic_load_relaxed(&gil->last_holder)) == tstate) + { + assert(is_tstate_valid(tstate)); + RESET_GIL_DROP_REQUEST(tstate->interp); + /* NOTE: if COND_WAIT does not atomically start waiting when + releasing the mutex, another thread can run through, take + the GIL and drop it again, and reset the condition + before we even had a chance to wait for it. */ + COND_WAIT(gil->switch_cond, gil->switch_mutex); + } + MUTEX_UNLOCK(gil->switch_mutex); + } +#endif +} + + +/* Check if a Python thread must exit immediately, rather than taking the GIL + if Py_Finalize() has been called. + + When this function is called by a daemon thread after Py_Finalize() has been + called, the GIL does no longer exist. + + tstate must be non-NULL. */ +static inline int +tstate_must_exit(PyThreadState *tstate) +{ + /* bpo-39877: Access _PyRuntime directly rather than using + tstate->interp->runtime to support calls from Python daemon threads. + After Py_Finalize() has been called, tstate can be a dangling pointer: + point to PyThreadState freed memory. */ + PyThreadState *finalizing = _PyRuntimeState_GetFinalizing(&_PyRuntime); + if (finalizing == NULL) { + finalizing = _PyInterpreterState_GetFinalizing(tstate->interp); + } + return (finalizing != NULL && finalizing != tstate); +} + + +/* Take the GIL. + + The function saves errno at entry and restores its value at exit. + + tstate must be non-NULL. */ +static void +take_gil(PyThreadState *tstate) +{ + int err = errno; + + assert(tstate != NULL); + /* We shouldn't be using a thread state that isn't viable any more. */ + // XXX It may be more correct to check tstate->_status.finalizing. + // XXX assert(!tstate->_status.cleared); + + if (tstate_must_exit(tstate)) { + /* bpo-39877: If Py_Finalize() has been called and tstate is not the + thread which called Py_Finalize(), exit immediately the thread. + + This code path can be reached by a daemon thread after Py_Finalize() + completes. In this case, tstate is a dangling pointer: points to + PyThreadState freed memory. */ + PyThread_exit_thread(); + } + + assert(is_tstate_valid(tstate)); + PyInterpreterState *interp = tstate->interp; + struct _ceval_state *ceval = &interp->ceval; + struct _gil_runtime_state *gil = ceval->gil; + + /* Check that _PyEval_InitThreads() was called to create the lock */ + assert(gil_created(gil)); + + MUTEX_LOCK(gil->mutex); + + if (!_Py_atomic_load_relaxed(&gil->locked)) { + goto _ready; + } + + int drop_requested = 0; + while (_Py_atomic_load_relaxed(&gil->locked)) { + unsigned long saved_switchnum = gil->switch_number; + + unsigned long interval = (gil->interval >= 1 ? gil->interval : 1); + int timed_out = 0; + COND_TIMED_WAIT(gil->cond, gil->mutex, interval, timed_out); + + /* If we timed out and no switch occurred in the meantime, it is time + to ask the GIL-holding thread to drop it. */ + if (timed_out && + _Py_atomic_load_relaxed(&gil->locked) && + gil->switch_number == saved_switchnum) + { + if (tstate_must_exit(tstate)) { + MUTEX_UNLOCK(gil->mutex); + // gh-96387: If the loop requested a drop request in a previous + // iteration, reset the request. Otherwise, drop_gil() can + // block forever waiting for the thread which exited. Drop + // requests made by other threads are also reset: these threads + // may have to request again a drop request (iterate one more + // time). + if (drop_requested) { + RESET_GIL_DROP_REQUEST(interp); + } + PyThread_exit_thread(); + } + assert(is_tstate_valid(tstate)); + + SET_GIL_DROP_REQUEST(interp); + drop_requested = 1; + } + } + +_ready: +#ifdef FORCE_SWITCHING + /* This mutex must be taken before modifying gil->last_holder: + see drop_gil(). */ + MUTEX_LOCK(gil->switch_mutex); +#endif + /* We now hold the GIL */ + _Py_atomic_store_relaxed(&gil->locked, 1); + _Py_ANNOTATE_RWLOCK_ACQUIRED(&gil->locked, /*is_write=*/1); + + if (tstate != (PyThreadState*)_Py_atomic_load_relaxed(&gil->last_holder)) { + _Py_atomic_store_relaxed(&gil->last_holder, (uintptr_t)tstate); + ++gil->switch_number; + } + +#ifdef FORCE_SWITCHING + COND_SIGNAL(gil->switch_cond); + MUTEX_UNLOCK(gil->switch_mutex); +#endif + + if (tstate_must_exit(tstate)) { + /* bpo-36475: If Py_Finalize() has been called and tstate is not + the thread which called Py_Finalize(), exit immediately the + thread. + + This code path can be reached by a daemon thread which was waiting + in take_gil() while the main thread called + wait_for_thread_shutdown() from Py_Finalize(). */ + MUTEX_UNLOCK(gil->mutex); + drop_gil(ceval, tstate); + PyThread_exit_thread(); + } + assert(is_tstate_valid(tstate)); + + if (_Py_atomic_load_relaxed(&ceval->gil_drop_request)) { + RESET_GIL_DROP_REQUEST(interp); + } + else { + /* bpo-40010: eval_breaker should be recomputed to be set to 1 if there + is a pending signal: signal received by another thread which cannot + handle signals. + + Note: RESET_GIL_DROP_REQUEST() calls COMPUTE_EVAL_BREAKER(). */ + COMPUTE_EVAL_BREAKER(interp, &_PyRuntime.ceval, ceval); + } + + /* Don't access tstate if the thread must exit */ + if (tstate->async_exc != NULL) { + _PyEval_SignalAsyncExc(tstate->interp); + } + + MUTEX_UNLOCK(gil->mutex); + + errno = err; +} + +void _PyEval_SetSwitchInterval(unsigned long microseconds) +{ + PyInterpreterState *interp = _PyInterpreterState_Get(); + struct _gil_runtime_state *gil = interp->ceval.gil; + assert(gil != NULL); + gil->interval = microseconds; +} + +unsigned long _PyEval_GetSwitchInterval(void) +{ + PyInterpreterState *interp = _PyInterpreterState_Get(); + struct _gil_runtime_state *gil = interp->ceval.gil; + assert(gil != NULL); + return gil->interval; +} + + +int +_PyEval_ThreadsInitialized(void) +{ + /* XXX This is only needed for an assert in PyGILState_Ensure(), + * which currently does not work with subinterpreters. + * Thus we only use the main interpreter. */ + PyInterpreterState *interp = _PyInterpreterState_Main(); + if (interp == NULL) { + return 0; + } + struct _gil_runtime_state *gil = interp->ceval.gil; + return gil_created(gil); +} + +int +PyEval_ThreadsInitialized(void) +{ + return _PyEval_ThreadsInitialized(); +} + +static inline int +current_thread_holds_gil(struct _gil_runtime_state *gil, PyThreadState *tstate) +{ + if (((PyThreadState*)_Py_atomic_load_relaxed(&gil->last_holder)) != tstate) { + return 0; + } + return _Py_atomic_load_relaxed(&gil->locked); +} + +static void +init_shared_gil(PyInterpreterState *interp, struct _gil_runtime_state *gil) +{ + assert(gil_created(gil)); + interp->ceval.gil = gil; + interp->ceval.own_gil = 0; +} + +static void +init_own_gil(PyInterpreterState *interp, struct _gil_runtime_state *gil) +{ + assert(!gil_created(gil)); + create_gil(gil); + assert(gil_created(gil)); + interp->ceval.gil = gil; + interp->ceval.own_gil = 1; +} + +PyStatus +_PyEval_InitGIL(PyThreadState *tstate, int own_gil) +{ + assert(tstate->interp->ceval.gil == NULL); + int locked; + if (!own_gil) { + /* The interpreter will share the main interpreter's instead. */ + PyInterpreterState *main_interp = _PyInterpreterState_Main(); + assert(tstate->interp != main_interp); + struct _gil_runtime_state *gil = main_interp->ceval.gil; + init_shared_gil(tstate->interp, gil); + locked = current_thread_holds_gil(gil, tstate); + } + else { + PyThread_init_thread(); + init_own_gil(tstate->interp, &tstate->interp->_gil); + locked = 0; + } + if (!locked) { + take_gil(tstate); + } + + return _PyStatus_OK(); +} + +void +_PyEval_FiniGIL(PyInterpreterState *interp) +{ + struct _gil_runtime_state *gil = interp->ceval.gil; + if (gil == NULL) { + /* It was already finalized (or hasn't been initialized yet). */ + assert(!interp->ceval.own_gil); + return; + } + else if (!interp->ceval.own_gil) { +#ifdef Py_DEBUG + PyInterpreterState *main_interp = _PyInterpreterState_Main(); + assert(main_interp != NULL && interp != main_interp); + assert(interp->ceval.gil == main_interp->ceval.gil); +#endif + interp->ceval.gil = NULL; + return; + } + + if (!gil_created(gil)) { + /* First Py_InitializeFromConfig() call: the GIL doesn't exist + yet: do nothing. */ + return; + } + + destroy_gil(gil); + assert(!gil_created(gil)); + interp->ceval.gil = NULL; +} + +void +PyEval_InitThreads(void) +{ + /* Do nothing: kept for backward compatibility */ +} + +void +_PyEval_Fini(void) +{ +#ifdef Py_STATS + _Py_PrintSpecializationStats(1); +#endif +} +void +PyEval_AcquireLock(void) +{ + PyThreadState *tstate = _PyThreadState_GET(); + _Py_EnsureTstateNotNULL(tstate); + + take_gil(tstate); +} + +void +PyEval_ReleaseLock(void) +{ + PyThreadState *tstate = _PyThreadState_GET(); + /* This function must succeed when the current thread state is NULL. + We therefore avoid PyThreadState_Get() which dumps a fatal error + in debug mode. */ + struct _ceval_state *ceval = &tstate->interp->ceval; + drop_gil(ceval, tstate); +} + +void +_PyEval_AcquireLock(PyThreadState *tstate) +{ + _Py_EnsureTstateNotNULL(tstate); + take_gil(tstate); +} + +void +_PyEval_ReleaseLock(PyInterpreterState *interp, PyThreadState *tstate) +{ + /* If tstate is NULL then we do not expect the current thread + to acquire the GIL ever again. */ + assert(tstate == NULL || tstate->interp == interp); + struct _ceval_state *ceval = &interp->ceval; + drop_gil(ceval, tstate); +} + +void +PyEval_AcquireThread(PyThreadState *tstate) +{ + _Py_EnsureTstateNotNULL(tstate); + + take_gil(tstate); + + if (_PyThreadState_SwapNoGIL(tstate) != NULL) { + Py_FatalError("non-NULL old thread state"); + } +} + +void +PyEval_ReleaseThread(PyThreadState *tstate) +{ + assert(is_tstate_valid(tstate)); + + PyThreadState *new_tstate = _PyThreadState_SwapNoGIL(NULL); + if (new_tstate != tstate) { + Py_FatalError("wrong thread state"); + } + struct _ceval_state *ceval = &tstate->interp->ceval; + drop_gil(ceval, tstate); +} + +#ifdef HAVE_FORK +/* This function is called from PyOS_AfterFork_Child to destroy all threads + which are not running in the child process, and clear internal locks + which might be held by those threads. */ +PyStatus +_PyEval_ReInitThreads(PyThreadState *tstate) +{ + assert(tstate->interp == _PyInterpreterState_Main()); + + struct _gil_runtime_state *gil = tstate->interp->ceval.gil; + if (!gil_created(gil)) { + return _PyStatus_OK(); + } + recreate_gil(gil); + + take_gil(tstate); + + struct _pending_calls *pending = &tstate->interp->ceval.pending; + if (_PyThread_at_fork_reinit(&pending->lock) < 0) { + return _PyStatus_ERR("Can't reinitialize pending calls lock"); + } + + /* Destroy all threads except the current one */ + _PyThreadState_DeleteExcept(tstate); + return _PyStatus_OK(); +} +#endif + +/* This function is used to signal that async exceptions are waiting to be + raised. */ + +void +_PyEval_SignalAsyncExc(PyInterpreterState *interp) +{ + SIGNAL_ASYNC_EXC(interp); +} + +PyThreadState * +PyEval_SaveThread(void) +{ + PyThreadState *tstate = _PyThreadState_SwapNoGIL(NULL); + _Py_EnsureTstateNotNULL(tstate); + + struct _ceval_state *ceval = &tstate->interp->ceval; + assert(gil_created(ceval->gil)); + drop_gil(ceval, tstate); + return tstate; +} + +void +PyEval_RestoreThread(PyThreadState *tstate) +{ + _Py_EnsureTstateNotNULL(tstate); + + take_gil(tstate); + + _PyThreadState_SwapNoGIL(tstate); +} + + +/* Mechanism whereby asynchronously executing callbacks (e.g. UNIX + signal handlers or Mac I/O completion routines) can schedule calls + to a function to be called synchronously. + The synchronous function is called with one void* argument. + It should return 0 for success or -1 for failure -- failure should + be accompanied by an exception. + + If registry succeeds, the registry function returns 0; if it fails + (e.g. due to too many pending calls) it returns -1 (without setting + an exception condition). + + Note that because registry may occur from within signal handlers, + or other asynchronous events, calling malloc() is unsafe! + + Any thread can schedule pending calls, but only the main thread + will execute them. + There is no facility to schedule calls to a particular thread, but + that should be easy to change, should that ever be required. In + that case, the static variables here should go into the python + threadstate. +*/ + +void +_PyEval_SignalReceived(PyInterpreterState *interp) +{ +#ifdef MS_WINDOWS + // bpo-42296: On Windows, _PyEval_SignalReceived() is called from a signal + // handler which can run in a thread different than the Python thread, in + // which case _Py_ThreadCanHandleSignals() is wrong. Ignore + // _Py_ThreadCanHandleSignals() and always set eval_breaker to 1. + // + // The next eval_frame_handle_pending() call will call + // _Py_ThreadCanHandleSignals() to recompute eval_breaker. + int force = 1; +#else + int force = 0; +#endif + /* bpo-30703: Function called when the C signal handler of Python gets a + signal. We cannot queue a callback using _PyEval_AddPendingCall() since + that function is not async-signal-safe. */ + SIGNAL_PENDING_SIGNALS(interp, force); +} + +/* Push one item onto the queue while holding the lock. */ +static int +_push_pending_call(struct _pending_calls *pending, + int (*func)(void *), void *arg) +{ + int i = pending->last; + int j = (i + 1) % NPENDINGCALLS; + if (j == pending->first) { + return -1; /* Queue full */ + } + pending->calls[i].func = func; + pending->calls[i].arg = arg; + pending->last = j; + return 0; +} + +static int +_next_pending_call(struct _pending_calls *pending, + int (**func)(void *), void **arg) +{ + int i = pending->first; + if (i == pending->last) { + /* Queue empty */ + assert(pending->calls[i].func == NULL); + return -1; + } + *func = pending->calls[i].func; + *arg = pending->calls[i].arg; + return i; +} + +/* Pop one item off the queue while holding the lock. */ +static void +_pop_pending_call(struct _pending_calls *pending, + int (**func)(void *), void **arg) +{ + int i = _next_pending_call(pending, func, arg); + if (i >= 0) { + pending->calls[i] = (struct _pending_call){0}; + pending->first = (i + 1) % NPENDINGCALLS; + } +} + +/* This implementation is thread-safe. It allows + scheduling to be made from any thread, and even from an executing + callback. + */ + +int +_PyEval_AddPendingCall(PyInterpreterState *interp, + int (*func)(void *), void *arg, + int mainthreadonly) +{ + assert(!mainthreadonly || _Py_IsMainInterpreter(interp)); + struct _pending_calls *pending = &interp->ceval.pending; + if (mainthreadonly) { + /* The main thread only exists in the main interpreter. */ + assert(_Py_IsMainInterpreter(interp)); + pending = &_PyRuntime.ceval.pending_mainthread; + } + /* Ensure that _PyEval_InitState() was called + and that _PyEval_FiniState() is not called yet. */ + assert(pending->lock != NULL); + + PyThread_acquire_lock(pending->lock, WAIT_LOCK); + int result = _push_pending_call(pending, func, arg); + PyThread_release_lock(pending->lock); + + /* signal main loop */ + SIGNAL_PENDING_CALLS(pending, interp); + return result; +} + +int +Py_AddPendingCall(int (*func)(void *), void *arg) +{ + /* Legacy users of this API will continue to target the main thread + (of the main interpreter). */ + PyInterpreterState *interp = _PyInterpreterState_Main(); + return _PyEval_AddPendingCall(interp, func, arg, 1); +} + +static int +handle_signals(PyThreadState *tstate) +{ + assert(is_tstate_valid(tstate)); + if (!_Py_ThreadCanHandleSignals(tstate->interp)) { + return 0; + } + + UNSIGNAL_PENDING_SIGNALS(tstate->interp); + if (_PyErr_CheckSignalsTstate(tstate) < 0) { + /* On failure, re-schedule a call to handle_signals(). */ + SIGNAL_PENDING_SIGNALS(tstate->interp, 0); + return -1; + } + return 0; +} + +static inline int +maybe_has_pending_calls(PyInterpreterState *interp) +{ + struct _pending_calls *pending = &interp->ceval.pending; + if (_Py_atomic_load_relaxed_int32(&pending->calls_to_do)) { + return 1; + } + if (!_Py_IsMainThread() || !_Py_IsMainInterpreter(interp)) { + return 0; + } + pending = &_PyRuntime.ceval.pending_mainthread; + return _Py_atomic_load_relaxed_int32(&pending->calls_to_do); +} + +static int +_make_pending_calls(struct _pending_calls *pending) +{ + /* perform a bounded number of calls, in case of recursion */ + for (int i=0; i<NPENDINGCALLS; i++) { + int (*func)(void *) = NULL; + void *arg = NULL; + + /* pop one item off the queue while holding the lock */ + PyThread_acquire_lock(pending->lock, WAIT_LOCK); + _pop_pending_call(pending, &func, &arg); + PyThread_release_lock(pending->lock); + + /* having released the lock, perform the callback */ + if (func == NULL) { + break; + } + if (func(arg) != 0) { + return -1; + } + } + return 0; +} + +static int +make_pending_calls(PyInterpreterState *interp) +{ + struct _pending_calls *pending = &interp->ceval.pending; + struct _pending_calls *pending_main = &_PyRuntime.ceval.pending_mainthread; + + /* Only one thread (per interpreter) may run the pending calls + at once. In the same way, we don't do recursive pending calls. */ + PyThread_acquire_lock(pending->lock, WAIT_LOCK); + if (pending->busy) { + /* A pending call was added after another thread was already + handling the pending calls (and had already "unsignaled"). + Once that thread is done, it may have taken care of all the + pending calls, or there might be some still waiting. + Regardless, this interpreter's pending calls will stay + "signaled" until that first thread has finished. At that + point the next thread to trip the eval breaker will take + care of any remaining pending calls. Until then, though, + all the interpreter's threads will be tripping the eval + breaker every time it's checked. */ + PyThread_release_lock(pending->lock); + return 0; + } + pending->busy = 1; + PyThread_release_lock(pending->lock); + + /* unsignal before starting to call callbacks, so that any callback + added in-between re-signals */ + UNSIGNAL_PENDING_CALLS(interp); + + if (_make_pending_calls(pending) != 0) { + pending->busy = 0; + /* There might not be more calls to make, but we play it safe. */ + SIGNAL_PENDING_CALLS(pending, interp); + return -1; + } + + if (_Py_IsMainThread() && _Py_IsMainInterpreter(interp)) { + if (_make_pending_calls(pending_main) != 0) { + pending->busy = 0; + /* There might not be more calls to make, but we play it safe. */ + SIGNAL_PENDING_CALLS(pending_main, interp); + return -1; + } + } + + pending->busy = 0; + return 0; +} + +void +_Py_FinishPendingCalls(PyThreadState *tstate) +{ + assert(PyGILState_Check()); + assert(is_tstate_valid(tstate)); + + if (make_pending_calls(tstate->interp) < 0) { + PyObject *exc = _PyErr_GetRaisedException(tstate); + PyErr_BadInternalCall(); + _PyErr_ChainExceptions1(exc); + _PyErr_Print(tstate); + } +} + +int +_PyEval_MakePendingCalls(PyThreadState *tstate) +{ + int res; + + if (_Py_IsMainThread() && _Py_IsMainInterpreter(tstate->interp)) { + /* Python signal handler doesn't really queue a callback: + it only signals that a signal was received, + see _PyEval_SignalReceived(). */ + res = handle_signals(tstate); + if (res != 0) { + return res; + } + } + + res = make_pending_calls(tstate->interp); + if (res != 0) { + return res; + } + + return 0; +} + +/* Py_MakePendingCalls() is a simple wrapper for the sake + of backward-compatibility. */ +int +Py_MakePendingCalls(void) +{ + assert(PyGILState_Check()); + + PyThreadState *tstate = _PyThreadState_GET(); + assert(is_tstate_valid(tstate)); + + /* Only execute pending calls on the main thread. */ + if (!_Py_IsMainThread() || !_Py_IsMainInterpreter(tstate->interp)) { + return 0; + } + return _PyEval_MakePendingCalls(tstate); +} + +void +_PyEval_InitState(PyInterpreterState *interp, PyThread_type_lock pending_lock) +{ + _gil_initialize(&interp->_gil); + + struct _pending_calls *pending = &interp->ceval.pending; + assert(pending->lock == NULL); + pending->lock = pending_lock; +} + +void +_PyEval_FiniState(struct _ceval_state *ceval) +{ + struct _pending_calls *pending = &ceval->pending; + if (pending->lock != NULL) { + PyThread_free_lock(pending->lock); + pending->lock = NULL; + } +} + +/* Handle signals, pending calls, GIL drop request + and asynchronous exception */ +int +_Py_HandlePending(PyThreadState *tstate) +{ + _PyRuntimeState * const runtime = &_PyRuntime; + struct _ceval_runtime_state *ceval = &runtime->ceval; + struct _ceval_state *interp_ceval_state = &tstate->interp->ceval; + + /* Pending signals */ + if (_Py_atomic_load_relaxed_int32(&ceval->signals_pending)) { + if (handle_signals(tstate) != 0) { + return -1; + } + } + + /* Pending calls */ + if (maybe_has_pending_calls(tstate->interp)) { + if (make_pending_calls(tstate->interp) != 0) { + return -1; + } + } + + /* GC scheduled to run */ + if (_Py_atomic_load_relaxed_int32(&interp_ceval_state->gc_scheduled)) { + _Py_atomic_store_relaxed(&interp_ceval_state->gc_scheduled, 0); + COMPUTE_EVAL_BREAKER(tstate->interp, ceval, interp_ceval_state); + _Py_RunGC(tstate); + } + + /* GIL drop request */ + if (_Py_atomic_load_relaxed_int32(&interp_ceval_state->gil_drop_request)) { + /* Give another thread a chance */ + if (_PyThreadState_SwapNoGIL(NULL) != tstate) { + Py_FatalError("tstate mix-up"); + } + drop_gil(interp_ceval_state, tstate); + + /* Other threads may run now */ + + take_gil(tstate); + + if (_PyThreadState_SwapNoGIL(tstate) != NULL) { + Py_FatalError("orphan tstate"); + } + } + + /* Check for asynchronous exception. */ + if (tstate->async_exc != NULL) { + PyObject *exc = tstate->async_exc; + tstate->async_exc = NULL; + UNSIGNAL_ASYNC_EXC(tstate->interp); + _PyErr_SetNone(tstate, exc); + Py_DECREF(exc); + return -1; + } + + + // It is possible that some of the conditions that trigger the eval breaker + // are called in a different thread than the Python thread. An example of + // this is bpo-42296: On Windows, _PyEval_SignalReceived() can be called in + // a different thread than the Python thread, in which case + // _Py_ThreadCanHandleSignals() is wrong. Recompute eval_breaker in the + // current Python thread with the correct _Py_ThreadCanHandleSignals() + // value. It prevents to interrupt the eval loop at every instruction if + // the current Python thread cannot handle signals (if + // _Py_ThreadCanHandleSignals() is false). + COMPUTE_EVAL_BREAKER(tstate->interp, ceval, interp_ceval_state); + + return 0; +} + diff --git a/Python/ceval_gil.h b/Python/ceval_gil.h deleted file mode 100644 index 476ed7f1..00000000 --- a/Python/ceval_gil.h +++ /dev/null @@ -1,344 +0,0 @@ -/* - * Implementation of the Global Interpreter Lock (GIL). - */ - -#include <stdlib.h> -#include <errno.h> - -#include "pycore_atomic.h" - - -/* - Notes about the implementation: - - - The GIL is just a boolean variable (locked) whose access is protected - by a mutex (gil_mutex), and whose changes are signalled by a condition - variable (gil_cond). gil_mutex is taken for short periods of time, - and therefore mostly uncontended. - - - In the GIL-holding thread, the main loop (PyEval_EvalFrameEx) must be - able to release the GIL on demand by another thread. A volatile boolean - variable (gil_drop_request) is used for that purpose, which is checked - at every turn of the eval loop. That variable is set after a wait of - `interval` microseconds on `gil_cond` has timed out. - - [Actually, another volatile boolean variable (eval_breaker) is used - which ORs several conditions into one. Volatile booleans are - sufficient as inter-thread signalling means since Python is run - on cache-coherent architectures only.] - - - A thread wanting to take the GIL will first let pass a given amount of - time (`interval` microseconds) before setting gil_drop_request. This - encourages a defined switching period, but doesn't enforce it since - opcodes can take an arbitrary time to execute. - - The `interval` value is available for the user to read and modify - using the Python API `sys.{get,set}switchinterval()`. - - - When a thread releases the GIL and gil_drop_request is set, that thread - ensures that another GIL-awaiting thread gets scheduled. - It does so by waiting on a condition variable (switch_cond) until - the value of last_holder is changed to something else than its - own thread state pointer, indicating that another thread was able to - take the GIL. - - This is meant to prohibit the latency-adverse behaviour on multi-core - machines where one thread would speculatively release the GIL, but still - run and end up being the first to re-acquire it, making the "timeslices" - much longer than expected. - (Note: this mechanism is enabled with FORCE_SWITCHING above) -*/ - -#include "condvar.h" - -#define MUTEX_INIT(mut) \ - if (PyMUTEX_INIT(&(mut))) { \ - Py_FatalError("PyMUTEX_INIT(" #mut ") failed"); }; -#define MUTEX_FINI(mut) \ - if (PyMUTEX_FINI(&(mut))) { \ - Py_FatalError("PyMUTEX_FINI(" #mut ") failed"); }; -#define MUTEX_LOCK(mut) \ - if (PyMUTEX_LOCK(&(mut))) { \ - Py_FatalError("PyMUTEX_LOCK(" #mut ") failed"); }; -#define MUTEX_UNLOCK(mut) \ - if (PyMUTEX_UNLOCK(&(mut))) { \ - Py_FatalError("PyMUTEX_UNLOCK(" #mut ") failed"); }; - -#define COND_INIT(cond) \ - if (PyCOND_INIT(&(cond))) { \ - Py_FatalError("PyCOND_INIT(" #cond ") failed"); }; -#define COND_FINI(cond) \ - if (PyCOND_FINI(&(cond))) { \ - Py_FatalError("PyCOND_FINI(" #cond ") failed"); }; -#define COND_SIGNAL(cond) \ - if (PyCOND_SIGNAL(&(cond))) { \ - Py_FatalError("PyCOND_SIGNAL(" #cond ") failed"); }; -#define COND_WAIT(cond, mut) \ - if (PyCOND_WAIT(&(cond), &(mut))) { \ - Py_FatalError("PyCOND_WAIT(" #cond ") failed"); }; -#define COND_TIMED_WAIT(cond, mut, microseconds, timeout_result) \ - { \ - int r = PyCOND_TIMEDWAIT(&(cond), &(mut), (microseconds)); \ - if (r < 0) \ - Py_FatalError("PyCOND_WAIT(" #cond ") failed"); \ - if (r) /* 1 == timeout, 2 == impl. can't say, so assume timeout */ \ - timeout_result = 1; \ - else \ - timeout_result = 0; \ - } \ - - -#define DEFAULT_INTERVAL 5000 - -static void _gil_initialize(struct _gil_runtime_state *gil) -{ - _Py_atomic_int uninitialized = {-1}; - gil->locked = uninitialized; - gil->interval = DEFAULT_INTERVAL; -} - -static int gil_created(struct _gil_runtime_state *gil) -{ - return (_Py_atomic_load_explicit(&gil->locked, _Py_memory_order_acquire) >= 0); -} - -static void create_gil(struct _gil_runtime_state *gil) -{ - MUTEX_INIT(gil->mutex); -#ifdef FORCE_SWITCHING - MUTEX_INIT(gil->switch_mutex); -#endif - COND_INIT(gil->cond); -#ifdef FORCE_SWITCHING - COND_INIT(gil->switch_cond); -#endif - _Py_atomic_store_relaxed(&gil->last_holder, 0); - _Py_ANNOTATE_RWLOCK_CREATE(&gil->locked); - _Py_atomic_store_explicit(&gil->locked, 0, _Py_memory_order_release); -} - -static void destroy_gil(struct _gil_runtime_state *gil) -{ - /* some pthread-like implementations tie the mutex to the cond - * and must have the cond destroyed first. - */ - COND_FINI(gil->cond); - MUTEX_FINI(gil->mutex); -#ifdef FORCE_SWITCHING - COND_FINI(gil->switch_cond); - MUTEX_FINI(gil->switch_mutex); -#endif - _Py_atomic_store_explicit(&gil->locked, -1, - _Py_memory_order_release); - _Py_ANNOTATE_RWLOCK_DESTROY(&gil->locked); -} - -#ifdef HAVE_FORK -static void recreate_gil(struct _gil_runtime_state *gil) -{ - _Py_ANNOTATE_RWLOCK_DESTROY(&gil->locked); - /* XXX should we destroy the old OS resources here? */ - create_gil(gil); -} -#endif - -static void -drop_gil(struct _ceval_runtime_state *ceval, struct _ceval_state *ceval2, - PyThreadState *tstate) -{ - struct _gil_runtime_state *gil = &ceval->gil; - if (!_Py_atomic_load_relaxed(&gil->locked)) { - Py_FatalError("drop_gil: GIL is not locked"); - } - - /* tstate is allowed to be NULL (early interpreter init) */ - if (tstate != NULL) { - /* Sub-interpreter support: threads might have been switched - under our feet using PyThreadState_Swap(). Fix the GIL last - holder variable so that our heuristics work. */ - _Py_atomic_store_relaxed(&gil->last_holder, (uintptr_t)tstate); - } - - MUTEX_LOCK(gil->mutex); - _Py_ANNOTATE_RWLOCK_RELEASED(&gil->locked, /*is_write=*/1); - _Py_atomic_store_relaxed(&gil->locked, 0); - COND_SIGNAL(gil->cond); - MUTEX_UNLOCK(gil->mutex); - -#ifdef FORCE_SWITCHING - if (_Py_atomic_load_relaxed(&ceval2->gil_drop_request) && tstate != NULL) { - MUTEX_LOCK(gil->switch_mutex); - /* Not switched yet => wait */ - if (((PyThreadState*)_Py_atomic_load_relaxed(&gil->last_holder)) == tstate) - { - assert(is_tstate_valid(tstate)); - RESET_GIL_DROP_REQUEST(tstate->interp); - /* NOTE: if COND_WAIT does not atomically start waiting when - releasing the mutex, another thread can run through, take - the GIL and drop it again, and reset the condition - before we even had a chance to wait for it. */ - COND_WAIT(gil->switch_cond, gil->switch_mutex); - } - MUTEX_UNLOCK(gil->switch_mutex); - } -#endif -} - - -/* Check if a Python thread must exit immediately, rather than taking the GIL - if Py_Finalize() has been called. - - When this function is called by a daemon thread after Py_Finalize() has been - called, the GIL does no longer exist. - - tstate must be non-NULL. */ -static inline int -tstate_must_exit(PyThreadState *tstate) -{ - /* bpo-39877: Access _PyRuntime directly rather than using - tstate->interp->runtime to support calls from Python daemon threads. - After Py_Finalize() has been called, tstate can be a dangling pointer: - point to PyThreadState freed memory. */ - PyThreadState *finalizing = _PyRuntimeState_GetFinalizing(&_PyRuntime); - return (finalizing != NULL && finalizing != tstate); -} - - -/* Take the GIL. - - The function saves errno at entry and restores its value at exit. - - tstate must be non-NULL. */ -static void -take_gil(PyThreadState *tstate) -{ - int err = errno; - - assert(tstate != NULL); - - if (tstate_must_exit(tstate)) { - /* bpo-39877: If Py_Finalize() has been called and tstate is not the - thread which called Py_Finalize(), exit immediately the thread. - - This code path can be reached by a daemon thread after Py_Finalize() - completes. In this case, tstate is a dangling pointer: points to - PyThreadState freed memory. */ - PyThread_exit_thread(); - } - - assert(is_tstate_valid(tstate)); - PyInterpreterState *interp = tstate->interp; - struct _ceval_runtime_state *ceval = &interp->runtime->ceval; - struct _ceval_state *ceval2 = &interp->ceval; - struct _gil_runtime_state *gil = &ceval->gil; - - /* Check that _PyEval_InitThreads() was called to create the lock */ - assert(gil_created(gil)); - - MUTEX_LOCK(gil->mutex); - - if (!_Py_atomic_load_relaxed(&gil->locked)) { - goto _ready; - } - - int drop_requested = 0; - while (_Py_atomic_load_relaxed(&gil->locked)) { - unsigned long saved_switchnum = gil->switch_number; - - unsigned long interval = (gil->interval >= 1 ? gil->interval : 1); - int timed_out = 0; - COND_TIMED_WAIT(gil->cond, gil->mutex, interval, timed_out); - - /* If we timed out and no switch occurred in the meantime, it is time - to ask the GIL-holding thread to drop it. */ - if (timed_out && - _Py_atomic_load_relaxed(&gil->locked) && - gil->switch_number == saved_switchnum) - { - if (tstate_must_exit(tstate)) { - MUTEX_UNLOCK(gil->mutex); - // gh-96387: If the loop requested a drop request in a previous - // iteration, reset the request. Otherwise, drop_gil() can - // block forever waiting for the thread which exited. Drop - // requests made by other threads are also reset: these threads - // may have to request again a drop request (iterate one more - // time). - if (drop_requested) { - RESET_GIL_DROP_REQUEST(interp); - } - PyThread_exit_thread(); - } - assert(is_tstate_valid(tstate)); - - SET_GIL_DROP_REQUEST(interp); - drop_requested = 1; - } - } - -_ready: -#ifdef FORCE_SWITCHING - /* This mutex must be taken before modifying gil->last_holder: - see drop_gil(). */ - MUTEX_LOCK(gil->switch_mutex); -#endif - /* We now hold the GIL */ - _Py_atomic_store_relaxed(&gil->locked, 1); - _Py_ANNOTATE_RWLOCK_ACQUIRED(&gil->locked, /*is_write=*/1); - - if (tstate != (PyThreadState*)_Py_atomic_load_relaxed(&gil->last_holder)) { - _Py_atomic_store_relaxed(&gil->last_holder, (uintptr_t)tstate); - ++gil->switch_number; - } - -#ifdef FORCE_SWITCHING - COND_SIGNAL(gil->switch_cond); - MUTEX_UNLOCK(gil->switch_mutex); -#endif - - if (tstate_must_exit(tstate)) { - /* bpo-36475: If Py_Finalize() has been called and tstate is not - the thread which called Py_Finalize(), exit immediately the - thread. - - This code path can be reached by a daemon thread which was waiting - in take_gil() while the main thread called - wait_for_thread_shutdown() from Py_Finalize(). */ - MUTEX_UNLOCK(gil->mutex); - drop_gil(ceval, ceval2, tstate); - PyThread_exit_thread(); - } - assert(is_tstate_valid(tstate)); - - if (_Py_atomic_load_relaxed(&ceval2->gil_drop_request)) { - RESET_GIL_DROP_REQUEST(interp); - } - else { - /* bpo-40010: eval_breaker should be recomputed to be set to 1 if there - is a pending signal: signal received by another thread which cannot - handle signals. - - Note: RESET_GIL_DROP_REQUEST() calls COMPUTE_EVAL_BREAKER(). */ - COMPUTE_EVAL_BREAKER(interp, ceval, ceval2); - } - - /* Don't access tstate if the thread must exit */ - if (tstate->async_exc != NULL) { - _PyEval_SignalAsyncExc(tstate->interp); - } - - MUTEX_UNLOCK(gil->mutex); - - errno = err; -} - -void _PyEval_SetSwitchInterval(unsigned long microseconds) -{ - struct _gil_runtime_state *gil = &_PyRuntime.ceval.gil; - gil->interval = microseconds; -} - -unsigned long _PyEval_GetSwitchInterval() -{ - struct _gil_runtime_state *gil = &_PyRuntime.ceval.gil; - return gil->interval; -} diff --git a/Python/ceval_macros.h b/Python/ceval_macros.h new file mode 100644 index 00000000..fccf9088 --- /dev/null +++ b/Python/ceval_macros.h @@ -0,0 +1,344 @@ +// Macros needed by ceval.c and bytecodes.c + +/* Computed GOTOs, or + the-optimization-commonly-but-improperly-known-as-"threaded code" + using gcc's labels-as-values extension + (http://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html). + + The traditional bytecode evaluation loop uses a "switch" statement, which + decent compilers will optimize as a single indirect branch instruction + combined with a lookup table of jump addresses. However, since the + indirect jump instruction is shared by all opcodes, the CPU will have a + hard time making the right prediction for where to jump next (actually, + it will be always wrong except in the uncommon case of a sequence of + several identical opcodes). + + "Threaded code" in contrast, uses an explicit jump table and an explicit + indirect jump instruction at the end of each opcode. Since the jump + instruction is at a different address for each opcode, the CPU will make a + separate prediction for each of these instructions, which is equivalent to + predicting the second opcode of each opcode pair. These predictions have + a much better chance to turn out valid, especially in small bytecode loops. + + A mispredicted branch on a modern CPU flushes the whole pipeline and + can cost several CPU cycles (depending on the pipeline depth), + and potentially many more instructions (depending on the pipeline width). + A correctly predicted branch, however, is nearly free. + + At the time of this writing, the "threaded code" version is up to 15-20% + faster than the normal "switch" version, depending on the compiler and the + CPU architecture. + + NOTE: care must be taken that the compiler doesn't try to "optimize" the + indirect jumps by sharing them between all opcodes. Such optimizations + can be disabled on gcc by using the -fno-gcse flag (or possibly + -fno-crossjumping). +*/ + +/* Use macros rather than inline functions, to make it as clear as possible + * to the C compiler that the tracing check is a simple test then branch. + * We want to be sure that the compiler knows this before it generates + * the CFG. + */ + +#ifdef WITH_DTRACE +#define OR_DTRACE_LINE | (PyDTrace_LINE_ENABLED() ? 255 : 0) +#else +#define OR_DTRACE_LINE +#endif + +#ifdef HAVE_COMPUTED_GOTOS + #ifndef USE_COMPUTED_GOTOS + #define USE_COMPUTED_GOTOS 1 + #endif +#else + #if defined(USE_COMPUTED_GOTOS) && USE_COMPUTED_GOTOS + #error "Computed gotos are not supported on this compiler." + #endif + #undef USE_COMPUTED_GOTOS + #define USE_COMPUTED_GOTOS 0 +#endif + +#ifdef Py_STATS +#define INSTRUCTION_START(op) \ + do { \ + frame->prev_instr = next_instr++; \ + OPCODE_EXE_INC(op); \ + if (_py_stats) _py_stats->opcode_stats[lastopcode].pair_count[op]++; \ + lastopcode = op; \ + } while (0) +#else +#define INSTRUCTION_START(op) (frame->prev_instr = next_instr++) +#endif + +#if USE_COMPUTED_GOTOS +# define TARGET(op) TARGET_##op: INSTRUCTION_START(op); +# define DISPATCH_GOTO() goto *opcode_targets[opcode] +#else +# define TARGET(op) case op: TARGET_##op: INSTRUCTION_START(op); +# define DISPATCH_GOTO() goto dispatch_opcode +#endif + +/* PRE_DISPATCH_GOTO() does lltrace if enabled. Normally a no-op */ +#ifdef LLTRACE +#define PRE_DISPATCH_GOTO() if (lltrace) { \ + lltrace_instruction(frame, stack_pointer, next_instr); } +#else +#define PRE_DISPATCH_GOTO() ((void)0) +#endif + + +/* Do interpreter dispatch accounting for tracing and instrumentation */ +#define DISPATCH() \ + { \ + NEXTOPARG(); \ + PRE_DISPATCH_GOTO(); \ + DISPATCH_GOTO(); \ + } + +#define DISPATCH_SAME_OPARG() \ + { \ + opcode = next_instr->op.code; \ + PRE_DISPATCH_GOTO(); \ + DISPATCH_GOTO(); \ + } + +#define DISPATCH_INLINED(NEW_FRAME) \ + do { \ + assert(tstate->interp->eval_frame == NULL); \ + _PyFrame_SetStackPointer(frame, stack_pointer); \ + frame->prev_instr = next_instr - 1; \ + (NEW_FRAME)->previous = frame; \ + frame = cframe.current_frame = (NEW_FRAME); \ + CALL_STAT_INC(inlined_py_calls); \ + goto start_frame; \ + } while (0) + +#define CHECK_EVAL_BREAKER() \ + _Py_CHECK_EMSCRIPTEN_SIGNALS_PERIODICALLY(); \ + if (_Py_atomic_load_relaxed_int32(&tstate->interp->ceval.eval_breaker)) { \ + goto handle_eval_breaker; \ + } + + +/* Tuple access macros */ + +#ifndef Py_DEBUG +#define GETITEM(v, i) PyTuple_GET_ITEM((v), (i)) +#else +static inline PyObject * +GETITEM(PyObject *v, Py_ssize_t i) { + assert(PyTuple_Check(v)); + assert(i >= 0); + assert(i < PyTuple_GET_SIZE(v)); + return PyTuple_GET_ITEM(v, i); +} +#endif + +/* Code access macros */ + +/* The integer overflow is checked by an assertion below. */ +#define INSTR_OFFSET() ((int)(next_instr - _PyCode_CODE(frame->f_code))) +#define NEXTOPARG() do { \ + _Py_CODEUNIT word = *next_instr; \ + opcode = word.op.code; \ + oparg = word.op.arg; \ + } while (0) +#define JUMPTO(x) (next_instr = _PyCode_CODE(frame->f_code) + (x)) +#define JUMPBY(x) (next_instr += (x)) + +/* OpCode prediction macros + Some opcodes tend to come in pairs thus making it possible to + predict the second code when the first is run. For example, + COMPARE_OP is often followed by POP_JUMP_IF_FALSE or POP_JUMP_IF_TRUE. + + Verifying the prediction costs a single high-speed test of a register + variable against a constant. If the pairing was good, then the + processor's own internal branch predication has a high likelihood of + success, resulting in a nearly zero-overhead transition to the + next opcode. A successful prediction saves a trip through the eval-loop + including its unpredictable switch-case branch. Combined with the + processor's internal branch prediction, a successful PREDICT has the + effect of making the two opcodes run as if they were a single new opcode + with the bodies combined. + + If collecting opcode statistics, your choices are to either keep the + predictions turned-on and interpret the results as if some opcodes + had been combined or turn-off predictions so that the opcode frequency + counter updates for both opcodes. + + Opcode prediction is disabled with threaded code, since the latter allows + the CPU to record separate branch prediction information for each + opcode. + +*/ + +#define PREDICT_ID(op) PRED_##op + +#if USE_COMPUTED_GOTOS +#define PREDICT(op) if (0) goto PREDICT_ID(op) +#else +#define PREDICT(next_op) \ + do { \ + _Py_CODEUNIT word = *next_instr; \ + opcode = word.op.code; \ + if (opcode == next_op) { \ + oparg = word.op.arg; \ + INSTRUCTION_START(next_op); \ + goto PREDICT_ID(next_op); \ + } \ + } while(0) +#endif +#define PREDICTED(op) PREDICT_ID(op): + + +/* Stack manipulation macros */ + +/* The stack can grow at most MAXINT deep, as co_nlocals and + co_stacksize are ints. */ +#define STACK_LEVEL() ((int)(stack_pointer - _PyFrame_Stackbase(frame))) +#define STACK_SIZE() (frame->f_code->co_stacksize) +#define EMPTY() (STACK_LEVEL() == 0) +#define TOP() (stack_pointer[-1]) +#define SECOND() (stack_pointer[-2]) +#define THIRD() (stack_pointer[-3]) +#define FOURTH() (stack_pointer[-4]) +#define PEEK(n) (stack_pointer[-(n)]) +#define POKE(n, v) (stack_pointer[-(n)] = (v)) +#define SET_TOP(v) (stack_pointer[-1] = (v)) +#define SET_SECOND(v) (stack_pointer[-2] = (v)) +#define BASIC_STACKADJ(n) (stack_pointer += n) +#define BASIC_PUSH(v) (*stack_pointer++ = (v)) +#define BASIC_POP() (*--stack_pointer) + +#ifdef Py_DEBUG +#define PUSH(v) do { \ + BASIC_PUSH(v); \ + assert(STACK_LEVEL() <= STACK_SIZE()); \ + } while (0) +#define POP() (assert(STACK_LEVEL() > 0), BASIC_POP()) +#define STACK_GROW(n) do { \ + assert(n >= 0); \ + BASIC_STACKADJ(n); \ + assert(STACK_LEVEL() <= STACK_SIZE()); \ + } while (0) +#define STACK_SHRINK(n) do { \ + assert(n >= 0); \ + assert(STACK_LEVEL() >= n); \ + BASIC_STACKADJ(-(n)); \ + } while (0) +#else +#define PUSH(v) BASIC_PUSH(v) +#define POP() BASIC_POP() +#define STACK_GROW(n) BASIC_STACKADJ(n) +#define STACK_SHRINK(n) BASIC_STACKADJ(-(n)) +#endif + +/* Local variable macros */ + +#define GETLOCAL(i) (frame->localsplus[i]) + +/* The SETLOCAL() macro must not DECREF the local variable in-place and + then store the new value; it must copy the old value to a temporary + value, then store the new value, and then DECREF the temporary value. + This is because it is possible that during the DECREF the frame is + accessed by other code (e.g. a __del__ method or gc.collect()) and the + variable would be pointing to already-freed memory. */ +#define SETLOCAL(i, value) do { PyObject *tmp = GETLOCAL(i); \ + GETLOCAL(i) = value; \ + Py_XDECREF(tmp); } while (0) + +#define GO_TO_INSTRUCTION(op) goto PREDICT_ID(op) + +#ifdef Py_STATS +#define UPDATE_MISS_STATS(INSTNAME) \ + do { \ + STAT_INC(opcode, miss); \ + STAT_INC((INSTNAME), miss); \ + /* The counter is always the first cache entry: */ \ + if (ADAPTIVE_COUNTER_IS_ZERO(next_instr->cache)) { \ + STAT_INC((INSTNAME), deopt); \ + } \ + else { \ + /* This is about to be (incorrectly) incremented: */ \ + STAT_DEC((INSTNAME), deferred); \ + } \ + } while (0) +#else +#define UPDATE_MISS_STATS(INSTNAME) ((void)0) +#endif + +#define DEOPT_IF(COND, INSTNAME) \ + if ((COND)) { \ + /* This is only a single jump on release builds! */ \ + UPDATE_MISS_STATS((INSTNAME)); \ + assert(_PyOpcode_Deopt[opcode] == (INSTNAME)); \ + GO_TO_INSTRUCTION(INSTNAME); \ + } + + +#define GLOBALS() frame->f_globals +#define BUILTINS() frame->f_builtins +#define LOCALS() frame->f_locals + +#define DTRACE_FUNCTION_ENTRY() \ + if (PyDTrace_FUNCTION_ENTRY_ENABLED()) { \ + dtrace_function_entry(frame); \ + } + +#define ADAPTIVE_COUNTER_IS_ZERO(COUNTER) \ + (((COUNTER) >> ADAPTIVE_BACKOFF_BITS) == 0) + +#define ADAPTIVE_COUNTER_IS_MAX(COUNTER) \ + (((COUNTER) >> ADAPTIVE_BACKOFF_BITS) == ((1 << MAX_BACKOFF_VALUE) - 1)) + +#define DECREMENT_ADAPTIVE_COUNTER(COUNTER) \ + do { \ + assert(!ADAPTIVE_COUNTER_IS_ZERO((COUNTER))); \ + (COUNTER) -= (1 << ADAPTIVE_BACKOFF_BITS); \ + } while (0); + +#define INCREMENT_ADAPTIVE_COUNTER(COUNTER) \ + do { \ + assert(!ADAPTIVE_COUNTER_IS_MAX((COUNTER))); \ + (COUNTER) += (1 << ADAPTIVE_BACKOFF_BITS); \ + } while (0); + +#define NAME_ERROR_MSG "name '%.200s' is not defined" + +#define KWNAMES_LEN() \ + (kwnames == NULL ? 0 : ((int)PyTuple_GET_SIZE(kwnames))) + +#define DECREF_INPUTS_AND_REUSE_FLOAT(left, right, dval, result) \ +do { \ + if (Py_REFCNT(left) == 1) { \ + ((PyFloatObject *)left)->ob_fval = (dval); \ + _Py_DECREF_SPECIALIZED(right, _PyFloat_ExactDealloc);\ + result = (left); \ + } \ + else if (Py_REFCNT(right) == 1) {\ + ((PyFloatObject *)right)->ob_fval = (dval); \ + _Py_DECREF_NO_DEALLOC(left); \ + result = (right); \ + }\ + else { \ + result = PyFloat_FromDouble(dval); \ + if ((result) == NULL) goto error; \ + _Py_DECREF_NO_DEALLOC(left); \ + _Py_DECREF_NO_DEALLOC(right); \ + } \ +} while (0) + +// If a trace function sets a new f_lineno and +// *then* raises, we use the destination when searching +// for an exception handler, displaying the traceback, and so on +#define INSTRUMENTED_JUMP(src, dest, event) \ +do { \ + _PyFrame_SetStackPointer(frame, stack_pointer); \ + next_instr = _Py_call_instrumentation_jump(tstate, event, frame, src, dest); \ + stack_pointer = _PyFrame_GetStackPointer(frame); \ + if (next_instr == NULL) { \ + next_instr = (dest)+1; \ + goto error; \ + } \ +} while (0); diff --git a/Python/clinic/Python-tokenize.c.h b/Python/clinic/Python-tokenize.c.h index 050b4d49..28f50758 100644 --- a/Python/clinic/Python-tokenize.c.h +++ b/Python/clinic/Python-tokenize.c.h @@ -2,40 +2,82 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + static PyObject * -tokenizeriter_new_impl(PyTypeObject *type, const char *source); +tokenizeriter_new_impl(PyTypeObject *type, PyObject *readline, + int extra_tokens, const char *encoding); static PyObject * tokenizeriter_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; - static const char * const _keywords[] = {"source", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "tokenizeriter", 0}; - PyObject *argsbuf[1]; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(extra_tokens), &_Py_ID(encoding), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"", "extra_tokens", "encoding", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "tokenizeriter", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[3]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); - const char *source; + Py_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 2; + PyObject *readline; + int extra_tokens; + const char *encoding = NULL; - fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 1, 0, argsbuf); + fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 1, 1, argsbuf); if (!fastargs) { goto exit; } - if (!PyUnicode_Check(fastargs[0])) { - _PyArg_BadArgument("tokenizeriter", "argument 'source'", "str", fastargs[0]); + readline = fastargs[0]; + extra_tokens = PyObject_IsTrue(fastargs[1]); + if (extra_tokens < 0) { + goto exit; + } + if (!noptargs) { + goto skip_optional_kwonly; + } + if (!PyUnicode_Check(fastargs[2])) { + _PyArg_BadArgument("tokenizeriter", "argument 'encoding'", "str", fastargs[2]); goto exit; } - Py_ssize_t source_length; - source = PyUnicode_AsUTF8AndSize(fastargs[0], &source_length); - if (source == NULL) { + Py_ssize_t encoding_length; + encoding = PyUnicode_AsUTF8AndSize(fastargs[2], &encoding_length); + if (encoding == NULL) { goto exit; } - if (strlen(source) != (size_t)source_length) { + if (strlen(encoding) != (size_t)encoding_length) { PyErr_SetString(PyExc_ValueError, "embedded null character"); goto exit; } - return_value = tokenizeriter_new_impl(type, source); +skip_optional_kwonly: + return_value = tokenizeriter_new_impl(type, readline, extra_tokens, encoding); exit: return return_value; } -/*[clinic end generated code: output=dfcd64774e01bfe6 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=48be65a2808bdfa6 input=a9049054013a1b77]*/ diff --git a/Python/clinic/_warnings.c.h b/Python/clinic/_warnings.c.h index aa85c2a0..432e554a 100644 --- a/Python/clinic/_warnings.c.h +++ b/Python/clinic/_warnings.c.h @@ -2,31 +2,76 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(warnings_warn__doc__, -"warn($module, /, message, category=None, stacklevel=1, source=None)\n" +"warn($module, /, message, category=None, stacklevel=1, source=None, *,\n" +" skip_file_prefixes=<unrepresentable>)\n" "--\n" "\n" -"Issue a warning, or maybe ignore it or raise an exception."); +"Issue a warning, or maybe ignore it or raise an exception.\n" +"\n" +" message\n" +" Text of the warning message.\n" +" category\n" +" The Warning category subclass. Defaults to UserWarning.\n" +" stacklevel\n" +" How far up the call stack to make this warning appear. A value of 2 for\n" +" example attributes the warning to the caller of the code calling warn().\n" +" source\n" +" If supplied, the destroyed object which emitted a ResourceWarning\n" +" skip_file_prefixes\n" +" An optional tuple of module filename prefixes indicating frames to skip\n" +" during stacklevel computations for stack frame attribution."); #define WARNINGS_WARN_METHODDEF \ {"warn", _PyCFunction_CAST(warnings_warn), METH_FASTCALL|METH_KEYWORDS, warnings_warn__doc__}, static PyObject * warnings_warn_impl(PyObject *module, PyObject *message, PyObject *category, - Py_ssize_t stacklevel, PyObject *source); + Py_ssize_t stacklevel, PyObject *source, + PyTupleObject *skip_file_prefixes); static PyObject * warnings_warn(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; - static const char * const _keywords[] = {"message", "category", "stacklevel", "source", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "warn", 0}; - PyObject *argsbuf[4]; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 5 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(message), &_Py_ID(category), &_Py_ID(stacklevel), &_Py_ID(source), &_Py_ID(skip_file_prefixes), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"message", "category", "stacklevel", "source", "skip_file_prefixes", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "warn", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *message; PyObject *category = Py_None; Py_ssize_t stacklevel = 1; PyObject *source = Py_None; + PyTupleObject *skip_file_prefixes = NULL; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 4, 0, argsbuf); if (!args) { @@ -59,11 +104,146 @@ warnings_warn(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec goto skip_optional_pos; } } - source = args[3]; + if (args[3]) { + source = args[3]; + if (!--noptargs) { + goto skip_optional_pos; + } + } +skip_optional_pos: + if (!noptargs) { + goto skip_optional_kwonly; + } + if (!PyTuple_Check(args[4])) { + _PyArg_BadArgument("warn", "argument 'skip_file_prefixes'", "tuple", args[4]); + goto exit; + } + skip_file_prefixes = (PyTupleObject *)args[4]; +skip_optional_kwonly: + return_value = warnings_warn_impl(module, message, category, stacklevel, source, skip_file_prefixes); + +exit: + return return_value; +} + +PyDoc_STRVAR(warnings_warn_explicit__doc__, +"warn_explicit($module, /, message, category, filename, lineno,\n" +" module=<unrepresentable>, registry=None,\n" +" module_globals=None, source=None)\n" +"--\n" +"\n" +"Issue a warning, or maybe ignore it or raise an exception."); + +#define WARNINGS_WARN_EXPLICIT_METHODDEF \ + {"warn_explicit", _PyCFunction_CAST(warnings_warn_explicit), METH_FASTCALL|METH_KEYWORDS, warnings_warn_explicit__doc__}, + +static PyObject * +warnings_warn_explicit_impl(PyObject *module, PyObject *message, + PyObject *category, PyObject *filename, + int lineno, PyObject *mod, PyObject *registry, + PyObject *module_globals, PyObject *sourceobj); + +static PyObject * +warnings_warn_explicit(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 8 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(message), &_Py_ID(category), &_Py_ID(filename), &_Py_ID(lineno), &_Py_ID(module), &_Py_ID(registry), &_Py_ID(module_globals), &_Py_ID(source), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"message", "category", "filename", "lineno", "module", "registry", "module_globals", "source", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "warn_explicit", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[8]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 4; + PyObject *message; + PyObject *category; + PyObject *filename; + int lineno; + PyObject *mod = NULL; + PyObject *registry = Py_None; + PyObject *module_globals = Py_None; + PyObject *sourceobj = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 4, 8, 0, argsbuf); + if (!args) { + goto exit; + } + message = args[0]; + category = args[1]; + if (!PyUnicode_Check(args[2])) { + _PyArg_BadArgument("warn_explicit", "argument 'filename'", "str", args[2]); + goto exit; + } + if (PyUnicode_READY(args[2]) == -1) { + goto exit; + } + filename = args[2]; + lineno = _PyLong_AsInt(args[3]); + if (lineno == -1 && PyErr_Occurred()) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[4]) { + mod = args[4]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (args[5]) { + registry = args[5]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + if (args[6]) { + module_globals = args[6]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + sourceobj = args[7]; skip_optional_pos: - return_value = warnings_warn_impl(module, message, category, stacklevel, source); + return_value = warnings_warn_explicit_impl(module, message, category, filename, lineno, mod, registry, module_globals, sourceobj); exit: return return_value; } -/*[clinic end generated code: output=0435c68611fa2fe9 input=a9049054013a1b77]*/ + +PyDoc_STRVAR(warnings_filters_mutated__doc__, +"_filters_mutated($module, /)\n" +"--\n" +"\n"); + +#define WARNINGS_FILTERS_MUTATED_METHODDEF \ + {"_filters_mutated", (PyCFunction)warnings_filters_mutated, METH_NOARGS, warnings_filters_mutated__doc__}, + +static PyObject * +warnings_filters_mutated_impl(PyObject *module); + +static PyObject * +warnings_filters_mutated(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return warnings_filters_mutated_impl(module); +} +/*[clinic end generated code: output=20429719d7223bdc input=a9049054013a1b77]*/ diff --git a/Python/clinic/bltinmodule.c.h b/Python/clinic/bltinmodule.c.h index 10cd6c82..b77b4a1e 100644 --- a/Python/clinic/bltinmodule.c.h +++ b/Python/clinic/bltinmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(builtin___import____doc__, "__import__($module, /, name, globals=None, locals=None, fromlist=(),\n" " level=0)\n" @@ -34,8 +40,31 @@ static PyObject * builtin___import__(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 5 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(name), &_Py_ID(globals), &_Py_ID(locals), &_Py_ID(fromlist), &_Py_ID(level), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"name", "globals", "locals", "fromlist", "level", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "__import__", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "__import__", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *name; @@ -154,11 +183,14 @@ PyDoc_STRVAR(builtin_format__doc__, "format($module, value, format_spec=\'\', /)\n" "--\n" "\n" -"Return value.__format__(format_spec)\n" +"Return type(value).__format__(value, format_spec)\n" +"\n" +"Many built-in types implement format_spec according to the\n" +"Format Specification Mini-language. See help(\'FORMATTING\').\n" "\n" -"format_spec defaults to the empty string.\n" -"See the Format Specification Mini-Language section of help(\'FORMATTING\') for\n" -"details."); +"If type(value) does not supply a method named __format__\n" +"and format_spec is empty, then str(value) is returned.\n" +"See also help(\'SPECIALMETHODS\')."); #define BUILTIN_FORMAT_METHODDEF \ {"format", _PyCFunction_CAST(builtin_format), METH_FASTCALL, builtin_format__doc__}, @@ -253,8 +285,31 @@ static PyObject * builtin_compile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 7 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(source), &_Py_ID(filename), &_Py_ID(mode), &_Py_ID(flags), &_Py_ID(dont_inherit), &_Py_ID(optimize), &_Py_ID(_feature_version), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"source", "filename", "mode", "flags", "dont_inherit", "optimize", "_feature_version", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "compile", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "compile", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[7]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3; PyObject *source; @@ -299,8 +354,8 @@ builtin_compile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj } } if (args[4]) { - dont_inherit = _PyLong_AsInt(args[4]); - if (dont_inherit == -1 && PyErr_Occurred()) { + dont_inherit = PyObject_IsTrue(args[4]); + if (dont_inherit < 0) { goto exit; } if (!--noptargs) { @@ -331,6 +386,49 @@ exit: return return_value; } +PyDoc_STRVAR(builtin_dir__doc__, +"dir($module, arg=<unrepresentable>, /)\n" +"--\n" +"\n" +"Show attributes of an object.\n" +"\n" +"If called without an argument, return the names in the current scope.\n" +"Else, return an alphabetized list of names comprising (some of) the attributes\n" +"of the given object, and of attributes reachable from it.\n" +"If the object supplies a method named __dir__, it will be used; otherwise\n" +"the default dir() logic is used and returns:\n" +" for a module object: the module\'s attributes.\n" +" for a class object: its attributes, and recursively the attributes\n" +" of its bases.\n" +" for any other object: its attributes, its class\'s attributes, and\n" +" recursively the attributes of its class\'s base classes."); + +#define BUILTIN_DIR_METHODDEF \ + {"dir", _PyCFunction_CAST(builtin_dir), METH_FASTCALL, builtin_dir__doc__}, + +static PyObject * +builtin_dir_impl(PyObject *module, PyObject *arg); + +static PyObject * +builtin_dir(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *arg = NULL; + + if (!_PyArg_CheckPositional("dir", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + arg = args[0]; +skip_optional: + return_value = builtin_dir_impl(module, arg); + +exit: + return return_value; +} + PyDoc_STRVAR(builtin_divmod__doc__, "divmod($module, x, y, /)\n" "--\n" @@ -432,8 +530,31 @@ static PyObject * builtin_exec(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(closure), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "", "", "closure", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "exec", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "exec", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *source; @@ -468,6 +589,47 @@ exit: return return_value; } +PyDoc_STRVAR(builtin_getattr__doc__, +"getattr($module, object, name, default=<unrepresentable>, /)\n" +"--\n" +"\n" +"Get a named attribute from an object.\n" +"\n" +"getattr(x, \'y\') is equivalent to x.y\n" +"When a default argument is given, it is returned when the attribute doesn\'t\n" +"exist; without it, an exception is raised in that case."); + +#define BUILTIN_GETATTR_METHODDEF \ + {"getattr", _PyCFunction_CAST(builtin_getattr), METH_FASTCALL, builtin_getattr__doc__}, + +static PyObject * +builtin_getattr_impl(PyObject *module, PyObject *object, PyObject *name, + PyObject *default_value); + +static PyObject * +builtin_getattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *object; + PyObject *name; + PyObject *default_value = NULL; + + if (!_PyArg_CheckPositional("getattr", nargs, 2, 3)) { + goto exit; + } + object = args[0]; + name = args[1]; + if (nargs < 3) { + goto skip_optional; + } + default_value = args[2]; +skip_optional: + return_value = builtin_getattr_impl(module, object, name, default_value); + +exit: + return return_value; +} + PyDoc_STRVAR(builtin_globals__doc__, "globals($module, /)\n" "--\n" @@ -533,6 +695,44 @@ PyDoc_STRVAR(builtin_id__doc__, #define BUILTIN_ID_METHODDEF \ {"id", (PyCFunction)builtin_id, METH_O, builtin_id__doc__}, +PyDoc_STRVAR(builtin_next__doc__, +"next($module, iterator, default=<unrepresentable>, /)\n" +"--\n" +"\n" +"Return the next item from the iterator.\n" +"\n" +"If default is given and the iterator is exhausted,\n" +"it is returned instead of raising StopIteration."); + +#define BUILTIN_NEXT_METHODDEF \ + {"next", _PyCFunction_CAST(builtin_next), METH_FASTCALL, builtin_next__doc__}, + +static PyObject * +builtin_next_impl(PyObject *module, PyObject *iterator, + PyObject *default_value); + +static PyObject * +builtin_next(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *iterator; + PyObject *default_value = NULL; + + if (!_PyArg_CheckPositional("next", nargs, 1, 2)) { + goto exit; + } + iterator = args[0]; + if (nargs < 2) { + goto skip_optional; + } + default_value = args[1]; +skip_optional: + return_value = builtin_next_impl(module, iterator, default_value); + +exit: + return return_value; +} + PyDoc_STRVAR(builtin_setattr__doc__, "setattr($module, obj, name, value, /)\n" "--\n" @@ -624,6 +824,43 @@ PyDoc_STRVAR(builtin_hex__doc__, #define BUILTIN_HEX_METHODDEF \ {"hex", (PyCFunction)builtin_hex, METH_O, builtin_hex__doc__}, +PyDoc_STRVAR(builtin_iter__doc__, +"iter($module, object, sentinel=<unrepresentable>, /)\n" +"--\n" +"\n" +"Get an iterator from an object.\n" +"\n" +"In the first form, the argument must supply its own iterator, or be a sequence.\n" +"In the second form, the callable is called until it returns the sentinel."); + +#define BUILTIN_ITER_METHODDEF \ + {"iter", _PyCFunction_CAST(builtin_iter), METH_FASTCALL, builtin_iter__doc__}, + +static PyObject * +builtin_iter_impl(PyObject *module, PyObject *object, PyObject *sentinel); + +static PyObject * +builtin_iter(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *object; + PyObject *sentinel = NULL; + + if (!_PyArg_CheckPositional("iter", nargs, 1, 2)) { + goto exit; + } + object = args[0]; + if (nargs < 2) { + goto skip_optional; + } + sentinel = args[1]; +skip_optional: + return_value = builtin_iter_impl(module, object, sentinel); + +exit: + return return_value; +} + PyDoc_STRVAR(builtin_aiter__doc__, "aiter($module, async_iterable, /)\n" "--\n" @@ -743,8 +980,31 @@ static PyObject * builtin_pow(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(base), &_Py_ID(exp), &_Py_ID(mod), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"base", "exp", "mod", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "pow", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "pow", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[3]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; PyObject *base; @@ -794,8 +1054,31 @@ static PyObject * builtin_print(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(sep), &_Py_ID(end), &_Py_ID(file), &_Py_ID(flush), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"sep", "end", "file", "flush", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "print", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "print", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[5]; Py_ssize_t noptargs = 0 + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *__clinic_args = NULL; @@ -910,8 +1193,31 @@ static PyObject * builtin_round(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(number), &_Py_ID(ndigits), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"number", "ndigits", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "round", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "round", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *number; @@ -933,6 +1239,41 @@ exit: return return_value; } +PyDoc_STRVAR(builtin_vars__doc__, +"vars($module, object=<unrepresentable>, /)\n" +"--\n" +"\n" +"Show vars.\n" +"\n" +"Without arguments, equivalent to locals().\n" +"With an argument, equivalent to object.__dict__."); + +#define BUILTIN_VARS_METHODDEF \ + {"vars", _PyCFunction_CAST(builtin_vars), METH_FASTCALL, builtin_vars__doc__}, + +static PyObject * +builtin_vars_impl(PyObject *module, PyObject *object); + +static PyObject * +builtin_vars(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + PyObject *object = NULL; + + if (!_PyArg_CheckPositional("vars", nargs, 0, 1)) { + goto exit; + } + if (nargs < 1) { + goto skip_optional; + } + object = args[0]; +skip_optional: + return_value = builtin_vars_impl(module, object); + +exit: + return return_value; +} + PyDoc_STRVAR(builtin_sum__doc__, "sum($module, iterable, /, start=0)\n" "--\n" @@ -953,8 +1294,31 @@ static PyObject * builtin_sum(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(start), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "start", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "sum", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "sum", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *iterable; @@ -1045,4 +1409,4 @@ builtin_issubclass(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=c45d5fe414f7a8d7 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=84a04e7446debf58 input=a9049054013a1b77]*/ diff --git a/Python/clinic/context.c.h b/Python/clinic/context.c.h index 292d3f7f..27c37571 100644 --- a/Python/clinic/context.c.h +++ b/Python/clinic/context.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_contextvars_Context_get__doc__, "get($self, key, default=None, /)\n" "--\n" @@ -177,4 +183,4 @@ PyDoc_STRVAR(_contextvars_ContextVar_reset__doc__, #define _CONTEXTVARS_CONTEXTVAR_RESET_METHODDEF \ {"reset", (PyCFunction)_contextvars_ContextVar_reset, METH_O, _contextvars_ContextVar_reset__doc__}, -/*[clinic end generated code: output=2436b16a92452869 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=0c94d4b919500438 input=a9049054013a1b77]*/ diff --git a/Python/clinic/import.c.h b/Python/clinic/import.c.h index 0451d97a..cb74be6a 100644 --- a/Python/clinic/import.c.h +++ b/Python/clinic/import.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(_imp_lock_held__doc__, "lock_held($module, /)\n" "--\n" @@ -193,8 +199,31 @@ static PyObject * _imp_find_frozen(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(withdata), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"", "withdata", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "find_frozen", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "find_frozen", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; PyObject *name; @@ -413,6 +442,37 @@ exit: return return_value; } +PyDoc_STRVAR(_imp__override_multi_interp_extensions_check__doc__, +"_override_multi_interp_extensions_check($module, override, /)\n" +"--\n" +"\n" +"(internal-only) Override PyInterpreterConfig.check_multi_interp_extensions.\n" +"\n" +"(-1: \"never\", 1: \"always\", 0: no override)"); + +#define _IMP__OVERRIDE_MULTI_INTERP_EXTENSIONS_CHECK_METHODDEF \ + {"_override_multi_interp_extensions_check", (PyCFunction)_imp__override_multi_interp_extensions_check, METH_O, _imp__override_multi_interp_extensions_check__doc__}, + +static PyObject * +_imp__override_multi_interp_extensions_check_impl(PyObject *module, + int override); + +static PyObject * +_imp__override_multi_interp_extensions_check(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int override; + + override = _PyLong_AsInt(arg); + if (override == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = _imp__override_multi_interp_extensions_check_impl(module, override); + +exit: + return return_value; +} + #if defined(HAVE_DYNAMIC_LOADING) PyDoc_STRVAR(_imp_create_dynamic__doc__, @@ -526,8 +586,31 @@ static PyObject * _imp_source_hash(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(key), &_Py_ID(source), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"key", "source", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "source_hash", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "source_hash", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[2]; long key; Py_buffer source = {NULL, NULL}; @@ -565,4 +648,4 @@ exit: #ifndef _IMP_EXEC_DYNAMIC_METHODDEF #define _IMP_EXEC_DYNAMIC_METHODDEF #endif /* !defined(_IMP_EXEC_DYNAMIC_METHODDEF) */ -/*[clinic end generated code: output=8d0f4305b1d0714b input=a9049054013a1b77]*/ +/*[clinic end generated code: output=b18d46e0036eff49 input=a9049054013a1b77]*/ diff --git a/Python/clinic/instrumentation.c.h b/Python/clinic/instrumentation.c.h new file mode 100644 index 00000000..cf3984ca --- /dev/null +++ b/Python/clinic/instrumentation.c.h @@ -0,0 +1,311 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + +PyDoc_STRVAR(monitoring_use_tool_id__doc__, +"use_tool_id($module, tool_id, name, /)\n" +"--\n" +"\n"); + +#define MONITORING_USE_TOOL_ID_METHODDEF \ + {"use_tool_id", _PyCFunction_CAST(monitoring_use_tool_id), METH_FASTCALL, monitoring_use_tool_id__doc__}, + +static PyObject * +monitoring_use_tool_id_impl(PyObject *module, int tool_id, PyObject *name); + +static PyObject * +monitoring_use_tool_id(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int tool_id; + PyObject *name; + + if (!_PyArg_CheckPositional("use_tool_id", nargs, 2, 2)) { + goto exit; + } + tool_id = _PyLong_AsInt(args[0]); + if (tool_id == -1 && PyErr_Occurred()) { + goto exit; + } + name = args[1]; + return_value = monitoring_use_tool_id_impl(module, tool_id, name); + +exit: + return return_value; +} + +PyDoc_STRVAR(monitoring_free_tool_id__doc__, +"free_tool_id($module, tool_id, /)\n" +"--\n" +"\n"); + +#define MONITORING_FREE_TOOL_ID_METHODDEF \ + {"free_tool_id", (PyCFunction)monitoring_free_tool_id, METH_O, monitoring_free_tool_id__doc__}, + +static PyObject * +monitoring_free_tool_id_impl(PyObject *module, int tool_id); + +static PyObject * +monitoring_free_tool_id(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int tool_id; + + tool_id = _PyLong_AsInt(arg); + if (tool_id == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = monitoring_free_tool_id_impl(module, tool_id); + +exit: + return return_value; +} + +PyDoc_STRVAR(monitoring_get_tool__doc__, +"get_tool($module, tool_id, /)\n" +"--\n" +"\n"); + +#define MONITORING_GET_TOOL_METHODDEF \ + {"get_tool", (PyCFunction)monitoring_get_tool, METH_O, monitoring_get_tool__doc__}, + +static PyObject * +monitoring_get_tool_impl(PyObject *module, int tool_id); + +static PyObject * +monitoring_get_tool(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int tool_id; + + tool_id = _PyLong_AsInt(arg); + if (tool_id == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = monitoring_get_tool_impl(module, tool_id); + +exit: + return return_value; +} + +PyDoc_STRVAR(monitoring_register_callback__doc__, +"register_callback($module, tool_id, event, func, /)\n" +"--\n" +"\n"); + +#define MONITORING_REGISTER_CALLBACK_METHODDEF \ + {"register_callback", _PyCFunction_CAST(monitoring_register_callback), METH_FASTCALL, monitoring_register_callback__doc__}, + +static PyObject * +monitoring_register_callback_impl(PyObject *module, int tool_id, int event, + PyObject *func); + +static PyObject * +monitoring_register_callback(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int tool_id; + int event; + PyObject *func; + + if (!_PyArg_CheckPositional("register_callback", nargs, 3, 3)) { + goto exit; + } + tool_id = _PyLong_AsInt(args[0]); + if (tool_id == -1 && PyErr_Occurred()) { + goto exit; + } + event = _PyLong_AsInt(args[1]); + if (event == -1 && PyErr_Occurred()) { + goto exit; + } + func = args[2]; + return_value = monitoring_register_callback_impl(module, tool_id, event, func); + +exit: + return return_value; +} + +PyDoc_STRVAR(monitoring_get_events__doc__, +"get_events($module, tool_id, /)\n" +"--\n" +"\n"); + +#define MONITORING_GET_EVENTS_METHODDEF \ + {"get_events", (PyCFunction)monitoring_get_events, METH_O, monitoring_get_events__doc__}, + +static int +monitoring_get_events_impl(PyObject *module, int tool_id); + +static PyObject * +monitoring_get_events(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int tool_id; + int _return_value; + + tool_id = _PyLong_AsInt(arg); + if (tool_id == -1 && PyErr_Occurred()) { + goto exit; + } + _return_value = monitoring_get_events_impl(module, tool_id); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromLong((long)_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(monitoring_set_events__doc__, +"set_events($module, tool_id, event_set, /)\n" +"--\n" +"\n"); + +#define MONITORING_SET_EVENTS_METHODDEF \ + {"set_events", _PyCFunction_CAST(monitoring_set_events), METH_FASTCALL, monitoring_set_events__doc__}, + +static PyObject * +monitoring_set_events_impl(PyObject *module, int tool_id, int event_set); + +static PyObject * +monitoring_set_events(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int tool_id; + int event_set; + + if (!_PyArg_CheckPositional("set_events", nargs, 2, 2)) { + goto exit; + } + tool_id = _PyLong_AsInt(args[0]); + if (tool_id == -1 && PyErr_Occurred()) { + goto exit; + } + event_set = _PyLong_AsInt(args[1]); + if (event_set == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = monitoring_set_events_impl(module, tool_id, event_set); + +exit: + return return_value; +} + +PyDoc_STRVAR(monitoring_get_local_events__doc__, +"get_local_events($module, tool_id, code, /)\n" +"--\n" +"\n"); + +#define MONITORING_GET_LOCAL_EVENTS_METHODDEF \ + {"get_local_events", _PyCFunction_CAST(monitoring_get_local_events), METH_FASTCALL, monitoring_get_local_events__doc__}, + +static int +monitoring_get_local_events_impl(PyObject *module, int tool_id, + PyObject *code); + +static PyObject * +monitoring_get_local_events(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int tool_id; + PyObject *code; + int _return_value; + + if (!_PyArg_CheckPositional("get_local_events", nargs, 2, 2)) { + goto exit; + } + tool_id = _PyLong_AsInt(args[0]); + if (tool_id == -1 && PyErr_Occurred()) { + goto exit; + } + code = args[1]; + _return_value = monitoring_get_local_events_impl(module, tool_id, code); + if ((_return_value == -1) && PyErr_Occurred()) { + goto exit; + } + return_value = PyLong_FromLong((long)_return_value); + +exit: + return return_value; +} + +PyDoc_STRVAR(monitoring_set_local_events__doc__, +"set_local_events($module, tool_id, code, event_set, /)\n" +"--\n" +"\n"); + +#define MONITORING_SET_LOCAL_EVENTS_METHODDEF \ + {"set_local_events", _PyCFunction_CAST(monitoring_set_local_events), METH_FASTCALL, monitoring_set_local_events__doc__}, + +static PyObject * +monitoring_set_local_events_impl(PyObject *module, int tool_id, + PyObject *code, int event_set); + +static PyObject * +monitoring_set_local_events(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int tool_id; + PyObject *code; + int event_set; + + if (!_PyArg_CheckPositional("set_local_events", nargs, 3, 3)) { + goto exit; + } + tool_id = _PyLong_AsInt(args[0]); + if (tool_id == -1 && PyErr_Occurred()) { + goto exit; + } + code = args[1]; + event_set = _PyLong_AsInt(args[2]); + if (event_set == -1 && PyErr_Occurred()) { + goto exit; + } + return_value = monitoring_set_local_events_impl(module, tool_id, code, event_set); + +exit: + return return_value; +} + +PyDoc_STRVAR(monitoring_restart_events__doc__, +"restart_events($module, /)\n" +"--\n" +"\n"); + +#define MONITORING_RESTART_EVENTS_METHODDEF \ + {"restart_events", (PyCFunction)monitoring_restart_events, METH_NOARGS, monitoring_restart_events__doc__}, + +static PyObject * +monitoring_restart_events_impl(PyObject *module); + +static PyObject * +monitoring_restart_events(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return monitoring_restart_events_impl(module); +} + +PyDoc_STRVAR(monitoring__all_events__doc__, +"_all_events($module, /)\n" +"--\n" +"\n"); + +#define MONITORING__ALL_EVENTS_METHODDEF \ + {"_all_events", (PyCFunction)monitoring__all_events, METH_NOARGS, monitoring__all_events__doc__}, + +static PyObject * +monitoring__all_events_impl(PyObject *module); + +static PyObject * +monitoring__all_events(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return monitoring__all_events_impl(module); +} +/*[clinic end generated code: output=11cc0803875b3ffa input=a9049054013a1b77]*/ diff --git a/Python/clinic/marshal.c.h b/Python/clinic/marshal.c.h index 36f2afd5..a593b980 100644 --- a/Python/clinic/marshal.c.h +++ b/Python/clinic/marshal.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(marshal_dump__doc__, "dump($module, value, file, version=version, /)\n" "--\n" @@ -155,4 +161,4 @@ exit: return return_value; } -/*[clinic end generated code: output=b9e838edee43fe87 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=12082d61d2942473 input=a9049054013a1b77]*/ diff --git a/Python/clinic/sysmodule.c.h b/Python/clinic/sysmodule.c.h index 8ca3cd08..7a7c188b 100644 --- a/Python/clinic/sysmodule.c.h +++ b/Python/clinic/sysmodule.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(sys_addaudithook__doc__, "addaudithook($module, /, hook)\n" "--\n" @@ -18,8 +24,31 @@ static PyObject * sys_addaudithook(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(hook), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"hook", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "addaudithook", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "addaudithook", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; PyObject *hook; @@ -263,6 +292,18 @@ exit: return return_value; } +PyDoc_STRVAR(sys__settraceallthreads__doc__, +"_settraceallthreads($module, arg, /)\n" +"--\n" +"\n" +"Set the global debug tracing function in all running threads belonging to the current interpreter.\n" +"\n" +"It will be called on each function call. See the debugger chapter\n" +"in the library manual."); + +#define SYS__SETTRACEALLTHREADS_METHODDEF \ + {"_settraceallthreads", (PyCFunction)sys__settraceallthreads, METH_O, sys__settraceallthreads__doc__}, + PyDoc_STRVAR(sys_gettrace__doc__, "gettrace($module, /)\n" "--\n" @@ -283,6 +324,18 @@ sys_gettrace(PyObject *module, PyObject *Py_UNUSED(ignored)) return sys_gettrace_impl(module); } +PyDoc_STRVAR(sys__setprofileallthreads__doc__, +"_setprofileallthreads($module, arg, /)\n" +"--\n" +"\n" +"Set the profiling function in all running threads belonging to the current interpreter.\n" +"\n" +"It will be called on each function call and return. See the profiler chapter\n" +"in the library manual."); + +#define SYS__SETPROFILEALLTHREADS_METHODDEF \ + {"_setprofileallthreads", (PyCFunction)sys__setprofileallthreads, METH_O, sys__setprofileallthreads__doc__}, + PyDoc_STRVAR(sys_getprofile__doc__, "getprofile($module, /)\n" "--\n" @@ -425,8 +478,31 @@ static PyObject * sys_set_coroutine_origin_tracking_depth(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(depth), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"depth", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "set_coroutine_origin_tracking_depth", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "set_coroutine_origin_tracking_depth", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int depth; @@ -703,8 +779,31 @@ static PyObject * sys_set_int_max_str_digits(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(maxdigits), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"maxdigits", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "set_int_max_str_digits", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "set_int_max_str_digits", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[1]; int maxdigits; @@ -785,24 +884,25 @@ exit: #endif /* defined(Py_REF_DEBUG) */ -PyDoc_STRVAR(sys__getquickenedcount__doc__, -"_getquickenedcount($module, /)\n" +PyDoc_STRVAR(sys_getallocatedblocks__doc__, +"getallocatedblocks($module, /)\n" "--\n" -"\n"); +"\n" +"Return the number of memory blocks currently allocated."); -#define SYS__GETQUICKENEDCOUNT_METHODDEF \ - {"_getquickenedcount", (PyCFunction)sys__getquickenedcount, METH_NOARGS, sys__getquickenedcount__doc__}, +#define SYS_GETALLOCATEDBLOCKS_METHODDEF \ + {"getallocatedblocks", (PyCFunction)sys_getallocatedblocks, METH_NOARGS, sys_getallocatedblocks__doc__}, static Py_ssize_t -sys__getquickenedcount_impl(PyObject *module); +sys_getallocatedblocks_impl(PyObject *module); static PyObject * -sys__getquickenedcount(PyObject *module, PyObject *Py_UNUSED(ignored)) +sys_getallocatedblocks(PyObject *module, PyObject *Py_UNUSED(ignored)) { PyObject *return_value = NULL; Py_ssize_t _return_value; - _return_value = sys__getquickenedcount_impl(module); + _return_value = sys_getallocatedblocks_impl(module); if ((_return_value == -1) && PyErr_Occurred()) { goto exit; } @@ -812,25 +912,25 @@ exit: return return_value; } -PyDoc_STRVAR(sys_getallocatedblocks__doc__, -"getallocatedblocks($module, /)\n" +PyDoc_STRVAR(sys_getunicodeinternedsize__doc__, +"getunicodeinternedsize($module, /)\n" "--\n" "\n" -"Return the number of memory blocks currently allocated."); +"Return the number of elements of the unicode interned dictionary"); -#define SYS_GETALLOCATEDBLOCKS_METHODDEF \ - {"getallocatedblocks", (PyCFunction)sys_getallocatedblocks, METH_NOARGS, sys_getallocatedblocks__doc__}, +#define SYS_GETUNICODEINTERNEDSIZE_METHODDEF \ + {"getunicodeinternedsize", (PyCFunction)sys_getunicodeinternedsize, METH_NOARGS, sys_getunicodeinternedsize__doc__}, static Py_ssize_t -sys_getallocatedblocks_impl(PyObject *module); +sys_getunicodeinternedsize_impl(PyObject *module); static PyObject * -sys_getallocatedblocks(PyObject *module, PyObject *Py_UNUSED(ignored)) +sys_getunicodeinternedsize(PyObject *module, PyObject *Py_UNUSED(ignored)) { PyObject *return_value = NULL; Py_ssize_t _return_value; - _return_value = sys_getallocatedblocks_impl(module); + _return_value = sys_getunicodeinternedsize_impl(module); if ((_return_value == -1) && PyErr_Occurred()) { goto exit; } @@ -1018,6 +1118,94 @@ sys_is_finalizing(PyObject *module, PyObject *Py_UNUSED(ignored)) return sys_is_finalizing_impl(module); } +#if defined(Py_STATS) + +PyDoc_STRVAR(sys__stats_on__doc__, +"_stats_on($module, /)\n" +"--\n" +"\n" +"Turns on stats gathering (stats gathering is on by default)."); + +#define SYS__STATS_ON_METHODDEF \ + {"_stats_on", (PyCFunction)sys__stats_on, METH_NOARGS, sys__stats_on__doc__}, + +static PyObject * +sys__stats_on_impl(PyObject *module); + +static PyObject * +sys__stats_on(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return sys__stats_on_impl(module); +} + +#endif /* defined(Py_STATS) */ + +#if defined(Py_STATS) + +PyDoc_STRVAR(sys__stats_off__doc__, +"_stats_off($module, /)\n" +"--\n" +"\n" +"Turns off stats gathering (stats gathering is on by default)."); + +#define SYS__STATS_OFF_METHODDEF \ + {"_stats_off", (PyCFunction)sys__stats_off, METH_NOARGS, sys__stats_off__doc__}, + +static PyObject * +sys__stats_off_impl(PyObject *module); + +static PyObject * +sys__stats_off(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return sys__stats_off_impl(module); +} + +#endif /* defined(Py_STATS) */ + +#if defined(Py_STATS) + +PyDoc_STRVAR(sys__stats_clear__doc__, +"_stats_clear($module, /)\n" +"--\n" +"\n" +"Clears the stats."); + +#define SYS__STATS_CLEAR_METHODDEF \ + {"_stats_clear", (PyCFunction)sys__stats_clear, METH_NOARGS, sys__stats_clear__doc__}, + +static PyObject * +sys__stats_clear_impl(PyObject *module); + +static PyObject * +sys__stats_clear(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return sys__stats_clear_impl(module); +} + +#endif /* defined(Py_STATS) */ + +#if defined(Py_STATS) + +PyDoc_STRVAR(sys__stats_dump__doc__, +"_stats_dump($module, /)\n" +"--\n" +"\n" +"Dump stats to file, and clears the stats."); + +#define SYS__STATS_DUMP_METHODDEF \ + {"_stats_dump", (PyCFunction)sys__stats_dump, METH_NOARGS, sys__stats_dump__doc__}, + +static PyObject * +sys__stats_dump_impl(PyObject *module); + +static PyObject * +sys__stats_dump(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return sys__stats_dump_impl(module); +} + +#endif /* defined(Py_STATS) */ + #if defined(ANDROID_API_LEVEL) PyDoc_STRVAR(sys_getandroidapilevel__doc__, @@ -1040,6 +1228,150 @@ sys_getandroidapilevel(PyObject *module, PyObject *Py_UNUSED(ignored)) #endif /* defined(ANDROID_API_LEVEL) */ +PyDoc_STRVAR(sys_activate_stack_trampoline__doc__, +"activate_stack_trampoline($module, backend, /)\n" +"--\n" +"\n" +"Activate stack profiler trampoline *backend*."); + +#define SYS_ACTIVATE_STACK_TRAMPOLINE_METHODDEF \ + {"activate_stack_trampoline", (PyCFunction)sys_activate_stack_trampoline, METH_O, sys_activate_stack_trampoline__doc__}, + +static PyObject * +sys_activate_stack_trampoline_impl(PyObject *module, const char *backend); + +static PyObject * +sys_activate_stack_trampoline(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + const char *backend; + + if (!PyUnicode_Check(arg)) { + _PyArg_BadArgument("activate_stack_trampoline", "argument", "str", arg); + goto exit; + } + Py_ssize_t backend_length; + backend = PyUnicode_AsUTF8AndSize(arg, &backend_length); + if (backend == NULL) { + goto exit; + } + if (strlen(backend) != (size_t)backend_length) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto exit; + } + return_value = sys_activate_stack_trampoline_impl(module, backend); + +exit: + return return_value; +} + +PyDoc_STRVAR(sys_deactivate_stack_trampoline__doc__, +"deactivate_stack_trampoline($module, /)\n" +"--\n" +"\n" +"Deactivate the current stack profiler trampoline backend.\n" +"\n" +"If no stack profiler is activated, this function has no effect."); + +#define SYS_DEACTIVATE_STACK_TRAMPOLINE_METHODDEF \ + {"deactivate_stack_trampoline", (PyCFunction)sys_deactivate_stack_trampoline, METH_NOARGS, sys_deactivate_stack_trampoline__doc__}, + +static PyObject * +sys_deactivate_stack_trampoline_impl(PyObject *module); + +static PyObject * +sys_deactivate_stack_trampoline(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return sys_deactivate_stack_trampoline_impl(module); +} + +PyDoc_STRVAR(sys_is_stack_trampoline_active__doc__, +"is_stack_trampoline_active($module, /)\n" +"--\n" +"\n" +"Return *True* if a stack profiler trampoline is active."); + +#define SYS_IS_STACK_TRAMPOLINE_ACTIVE_METHODDEF \ + {"is_stack_trampoline_active", (PyCFunction)sys_is_stack_trampoline_active, METH_NOARGS, sys_is_stack_trampoline_active__doc__}, + +static PyObject * +sys_is_stack_trampoline_active_impl(PyObject *module); + +static PyObject * +sys_is_stack_trampoline_active(PyObject *module, PyObject *Py_UNUSED(ignored)) +{ + return sys_is_stack_trampoline_active_impl(module); +} + +PyDoc_STRVAR(sys__getframemodulename__doc__, +"_getframemodulename($module, /, depth=0)\n" +"--\n" +"\n" +"Return the name of the module for a calling frame.\n" +"\n" +"The default depth returns the module containing the call to this API.\n" +"A more typical use in a library will pass a depth of 1 to get the user\'s\n" +"module rather than the library module.\n" +"\n" +"If no frame, module, or name can be found, returns None."); + +#define SYS__GETFRAMEMODULENAME_METHODDEF \ + {"_getframemodulename", _PyCFunction_CAST(sys__getframemodulename), METH_FASTCALL|METH_KEYWORDS, sys__getframemodulename__doc__}, + +static PyObject * +sys__getframemodulename_impl(PyObject *module, int depth); + +static PyObject * +sys__getframemodulename(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(depth), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"depth", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "_getframemodulename", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + int depth = 0; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + depth = _PyLong_AsInt(args[0]); + if (depth == -1 && PyErr_Occurred()) { + goto exit; + } +skip_optional_pos: + return_value = sys__getframemodulename_impl(module, depth); + +exit: + return return_value; +} + #ifndef SYS_GETWINDOWSVERSION_METHODDEF #define SYS_GETWINDOWSVERSION_METHODDEF #endif /* !defined(SYS_GETWINDOWSVERSION_METHODDEF) */ @@ -1064,7 +1396,23 @@ sys_getandroidapilevel(PyObject *module, PyObject *Py_UNUSED(ignored)) #define SYS_GETTOTALREFCOUNT_METHODDEF #endif /* !defined(SYS_GETTOTALREFCOUNT_METHODDEF) */ +#ifndef SYS__STATS_ON_METHODDEF + #define SYS__STATS_ON_METHODDEF +#endif /* !defined(SYS__STATS_ON_METHODDEF) */ + +#ifndef SYS__STATS_OFF_METHODDEF + #define SYS__STATS_OFF_METHODDEF +#endif /* !defined(SYS__STATS_OFF_METHODDEF) */ + +#ifndef SYS__STATS_CLEAR_METHODDEF + #define SYS__STATS_CLEAR_METHODDEF +#endif /* !defined(SYS__STATS_CLEAR_METHODDEF) */ + +#ifndef SYS__STATS_DUMP_METHODDEF + #define SYS__STATS_DUMP_METHODDEF +#endif /* !defined(SYS__STATS_DUMP_METHODDEF) */ + #ifndef SYS_GETANDROIDAPILEVEL_METHODDEF #define SYS_GETANDROIDAPILEVEL_METHODDEF #endif /* !defined(SYS_GETANDROIDAPILEVEL_METHODDEF) */ -/*[clinic end generated code: output=3cae0e0212d88bcd input=a9049054013a1b77]*/ +/*[clinic end generated code: output=6d598acc26237fbe input=a9049054013a1b77]*/ diff --git a/Python/clinic/traceback.c.h b/Python/clinic/traceback.c.h index 404a0c41..3c344934 100644 --- a/Python/clinic/traceback.c.h +++ b/Python/clinic/traceback.c.h @@ -2,6 +2,12 @@ preserve [clinic start generated code]*/ +#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) +# include "pycore_gc.h" // PyGC_Head +# include "pycore_runtime.h" // _Py_ID() +#endif + + PyDoc_STRVAR(tb_new__doc__, "TracebackType(tb_next, tb_frame, tb_lasti, tb_lineno)\n" "--\n" @@ -16,8 +22,31 @@ static PyObject * tb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 4 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = { &_Py_ID(tb_next), &_Py_ID(tb_frame), &_Py_ID(tb_lasti), &_Py_ID(tb_lineno), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + static const char * const _keywords[] = {"tb_next", "tb_frame", "tb_lasti", "tb_lineno", NULL}; - static _PyArg_Parser _parser = {NULL, _keywords, "TracebackType", 0}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "TracebackType", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE PyObject *argsbuf[4]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); @@ -49,4 +78,4 @@ tb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) exit: return return_value; } -/*[clinic end generated code: output=403778d7af5ebef9 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=7bc9927e362fdfb7 input=a9049054013a1b77]*/ diff --git a/Python/codecs.c b/Python/codecs.c index 33965f88..1983f56b 100644 --- a/Python/codecs.c +++ b/Python/codecs.c @@ -11,6 +11,7 @@ Copyright (c) Corporation for National Research Initiatives. #include "Python.h" #include "pycore_call.h" // _PyObject_CallNoArgs() #include "pycore_interp.h" // PyInterpreterState.codec_search_path +#include "pycore_pyerrors.h" // _PyErr_FormatNote() #include "pycore_pystate.h" // _PyInterpreterState_GET() #include "pycore_ucnhash.h" // _PyUnicode_Name_CAPI #include <ctype.h> @@ -235,8 +236,7 @@ PyObject *args_tuple(PyObject *object, args = PyTuple_New(1 + (errors != NULL)); if (args == NULL) return NULL; - Py_INCREF(object); - PyTuple_SET_ITEM(args,0,object); + PyTuple_SET_ITEM(args, 0, Py_NewRef(object)); if (errors) { PyObject *v; @@ -263,8 +263,7 @@ PyObject *codec_getitem(const char *encoding, int index) return NULL; v = PyTuple_GET_ITEM(codecs, index); Py_DECREF(codecs); - Py_INCREF(v); - return v; + return Py_NewRef(v); } /* Helper functions to create an incremental codec. */ @@ -384,22 +383,6 @@ PyObject *PyCodec_StreamWriter(const char *encoding, return codec_getstreamcodec(encoding, stream, errors, 3); } -/* Helper that tries to ensure the reported exception chain indicates the - * codec that was invoked to trigger the failure without changing the type - * of the exception raised. - */ -static void -wrap_codec_error(const char *operation, - const char *encoding) -{ - /* TrySetFromCause will replace the active exception with a suitably - * updated clone if it can, otherwise it will leave the original - * exception alone. - */ - _PyErr_TrySetFromCause("%s with '%s' codec failed", - operation, encoding); -} - /* Encode an object (e.g. a Unicode object) using the given encoding and return the resulting encoded object (usually a Python string). @@ -420,7 +403,7 @@ _PyCodec_EncodeInternal(PyObject *object, result = PyObject_Call(encoder, args, NULL); if (result == NULL) { - wrap_codec_error("encoding", encoding); + _PyErr_FormatNote("%s with '%s' codec failed", "encoding", encoding); goto onError; } @@ -430,8 +413,7 @@ _PyCodec_EncodeInternal(PyObject *object, "encoder must return a tuple (object, integer)"); goto onError; } - v = PyTuple_GET_ITEM(result,0); - Py_INCREF(v); + v = Py_NewRef(PyTuple_GET_ITEM(result,0)); /* We don't check or use the second (integer) entry. */ Py_DECREF(args); @@ -466,7 +448,7 @@ _PyCodec_DecodeInternal(PyObject *object, result = PyObject_Call(decoder, args, NULL); if (result == NULL) { - wrap_codec_error("decoding", encoding); + _PyErr_FormatNote("%s with '%s' codec failed", "decoding", encoding); goto onError; } if (!PyTuple_Check(result) || @@ -475,8 +457,7 @@ _PyCodec_DecodeInternal(PyObject *object, "decoder must return a tuple (object,integer)"); goto onError; } - v = PyTuple_GET_ITEM(result,0); - Py_INCREF(v); + v = Py_NewRef(PyTuple_GET_ITEM(result,0)); /* We don't check or use the second (integer) entry. */ Py_DECREF(args); @@ -571,8 +552,7 @@ PyObject *codec_getitem_checked(const char *encoding, if (codec == NULL) return NULL; - v = PyTuple_GET_ITEM(codec, index); - Py_INCREF(v); + v = Py_NewRef(PyTuple_GET_ITEM(codec, index)); Py_DECREF(codec); return v; } diff --git a/Python/compile.c b/Python/compile.c index 17d1df2c..ddd7b5c7 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -6,10 +6,10 @@ * object: * 1. Checks for future statements. See future.c * 2. Builds a symbol table. See symtable.c. - * 3. Generate code for basic blocks. See compiler_mod() in this file. - * 4. Assemble the basic blocks into final code. See assemble() in - * this file. - * 5. Optimize the byte code (peephole optimizations). + * 3. Generate an instruction sequence. See compiler_mod() in this file. + * 4. Generate a control flow graph and run optimizations on it. See flowgraph.c. + * 5. Assemble the basic blocks into final code. See optimize_and_assemble() in + * this file, and assembler.c. * * Note that compiler_mod() suggests module, but the module ast type * (mod_ty) has cases for expressions and interactive statements. @@ -23,20 +23,21 @@ #include <stdbool.h> -// Need _PyOpcode_RelativeJump of pycore_opcode.h -#define NEED_OPCODE_TABLES - #include "Python.h" #include "pycore_ast.h" // _PyAST_GetDocString() +#define NEED_OPCODE_TABLES +#include "pycore_opcode_utils.h" +#undef NEED_OPCODE_TABLES +#include "pycore_flowgraph.h" #include "pycore_code.h" // _PyCode_New() -#include "pycore_compile.h" // _PyFuture_FromAST() +#include "pycore_compile.h" +#include "pycore_intrinsics.h" #include "pycore_long.h" // _PyLong_GetZero() -#include "pycore_opcode.h" // _PyOpcode_Caches #include "pycore_pymem.h" // _PyMem_IsPtrFreed() -#include "pycore_symtable.h" // PySTEntryObject +#include "pycore_symtable.h" // PySTEntryObject, _PyFuture_FromAST() +#include "opcode_metadata.h" // _PyOpcode_opcode_metadata, _PyOpcode_num_popped/pushed -#define DEFAULT_BLOCK_SIZE 16 #define DEFAULT_CODE_SIZE 128 #define DEFAULT_LNOTAB_SIZE 16 #define DEFAULT_CNOTAB_SIZE 32 @@ -55,6 +56,16 @@ */ #define STACK_USE_GUIDELINE 30 +#undef SUCCESS +#undef ERROR +#define SUCCESS 0 +#define ERROR -1 + +#define RETURN_IF_ERROR(X) \ + if ((X) == -1) { \ + return ERROR; \ + } + /* If we exceed this limit, it should * be considered a compiler bug. * Currently it should be impossible @@ -70,199 +81,44 @@ */ #define MAX_ALLOWED_STACK_USE (STACK_USE_GUIDELINE * 100) +#define IS_TOP_LEVEL_AWAIT(C) ( \ + ((C)->c_flags.cf_flags & PyCF_ALLOW_TOP_LEVEL_AWAIT) \ + && ((C)->u->u_ste->ste_type == ModuleBlock)) -/* Pseudo-instructions used in the compiler, - * but turned into NOPs or other instructions - * by the assembler. */ -#define SETUP_FINALLY -1 -#define SETUP_CLEANUP -2 -#define SETUP_WITH -3 -#define POP_BLOCK -4 -#define JUMP -5 -#define JUMP_NO_INTERRUPT -6 -#define POP_JUMP_IF_FALSE -7 -#define POP_JUMP_IF_TRUE -8 -#define POP_JUMP_IF_NONE -9 -#define POP_JUMP_IF_NOT_NONE -10 - -#define MIN_VIRTUAL_OPCODE -10 -#define MAX_ALLOWED_OPCODE 254 - -#define IS_WITHIN_OPCODE_RANGE(opcode) \ - ((opcode) >= MIN_VIRTUAL_OPCODE && (opcode) <= MAX_ALLOWED_OPCODE) - -#define IS_VIRTUAL_OPCODE(opcode) ((opcode) < 0) - -#define IS_VIRTUAL_JUMP_OPCODE(opcode) \ - ((opcode) == JUMP || \ - (opcode) == JUMP_NO_INTERRUPT || \ - (opcode) == POP_JUMP_IF_NONE || \ - (opcode) == POP_JUMP_IF_NOT_NONE || \ - (opcode) == POP_JUMP_IF_FALSE || \ - (opcode) == POP_JUMP_IF_TRUE) - -/* opcodes which are not emitted in codegen stage, only by the assembler */ -#define IS_ASSEMBLER_OPCODE(opcode) \ - ((opcode) == JUMP_FORWARD || \ - (opcode) == JUMP_BACKWARD || \ - (opcode) == JUMP_BACKWARD_NO_INTERRUPT || \ - (opcode) == POP_JUMP_FORWARD_IF_NONE || \ - (opcode) == POP_JUMP_BACKWARD_IF_NONE || \ - (opcode) == POP_JUMP_FORWARD_IF_NOT_NONE || \ - (opcode) == POP_JUMP_BACKWARD_IF_NOT_NONE || \ - (opcode) == POP_JUMP_FORWARD_IF_TRUE || \ - (opcode) == POP_JUMP_BACKWARD_IF_TRUE || \ - (opcode) == POP_JUMP_FORWARD_IF_FALSE || \ - (opcode) == POP_JUMP_BACKWARD_IF_FALSE) - - -#define IS_BACKWARDS_JUMP_OPCODE(opcode) \ - ((opcode) == JUMP_BACKWARD || \ - (opcode) == JUMP_BACKWARD_NO_INTERRUPT || \ - (opcode) == POP_JUMP_BACKWARD_IF_NONE || \ - (opcode) == POP_JUMP_BACKWARD_IF_NOT_NONE || \ - (opcode) == POP_JUMP_BACKWARD_IF_TRUE || \ - (opcode) == POP_JUMP_BACKWARD_IF_FALSE) - - -#define IS_TOP_LEVEL_AWAIT(c) ( \ - (c->c_flags->cf_flags & PyCF_ALLOW_TOP_LEVEL_AWAIT) \ - && (c->u->u_ste->ste_type == ModuleBlock)) - -struct instr { - int i_opcode; - int i_oparg; - /* target block (if jump instruction) */ - struct basicblock_ *i_target; - /* target block when exception is raised, should not be set by front-end. */ - struct basicblock_ *i_except; - int i_lineno; - int i_end_lineno; - int i_col_offset; - int i_end_col_offset; -}; +typedef _PyCompilerSrcLocation location; +typedef _PyCfgInstruction cfg_instr; +typedef _PyCfgBasicblock basicblock; +typedef _PyCfgBuilder cfg_builder; -typedef struct excepthandler { - struct instr *setup; - int offset; -} ExceptHandler; +#define LOCATION(LNO, END_LNO, COL, END_COL) \ + ((const _PyCompilerSrcLocation){(LNO), (END_LNO), (COL), (END_COL)}) -typedef struct exceptstack { - struct basicblock_ *handlers[CO_MAXBLOCKS+1]; - int depth; -} ExceptStack; +/* Return true if loc1 starts after loc2 ends. */ +static inline bool +location_is_after(location loc1, location loc2) { + return (loc1.lineno > loc2.end_lineno) || + ((loc1.lineno == loc2.end_lineno) && + (loc1.col_offset > loc2.end_col_offset)); +} -#define LOG_BITS_PER_INT 5 -#define MASK_LOW_LOG_BITS 31 +#define LOC(x) SRC_LOCATION_FROM_AST(x) -static inline int -is_bit_set_in_table(const uint32_t *table, int bitindex) { - /* Is the relevant bit set in the relevant word? */ - /* 256 bits fit into 8 32-bits words. - * Word is indexed by (bitindex>>ln(size of int in bits)). - * Bit within word is the low bits of bitindex. - */ - if (bitindex >= 0 && bitindex < 256) { - uint32_t word = table[bitindex >> LOG_BITS_PER_INT]; - return (word >> (bitindex & MASK_LOW_LOG_BITS)) & 1; - } - else { - return 0; - } -} +typedef _PyCfgJumpTargetLabel jump_target_label; -static inline int -is_relative_jump(struct instr *i) -{ - return is_bit_set_in_table(_PyOpcode_RelativeJump, i->i_opcode); -} +static jump_target_label NO_LABEL = {-1}; -static inline int -is_block_push(struct instr *instr) -{ - int opcode = instr->i_opcode; - return opcode == SETUP_FINALLY || opcode == SETUP_WITH || opcode == SETUP_CLEANUP; -} +#define SAME_LABEL(L1, L2) ((L1).id == (L2).id) +#define IS_LABEL(L) (!SAME_LABEL((L), (NO_LABEL))) -static inline int -is_jump(struct instr *i) -{ - return IS_VIRTUAL_JUMP_OPCODE(i->i_opcode) || - is_bit_set_in_table(_PyOpcode_Jump, i->i_opcode); -} +#define NEW_JUMP_TARGET_LABEL(C, NAME) \ + jump_target_label NAME = instr_sequence_new_label(INSTR_SEQUENCE(C)); \ + if (!IS_LABEL(NAME)) { \ + return ERROR; \ + } -static int -instr_size(struct instr *instruction) -{ - int opcode = instruction->i_opcode; - assert(!IS_VIRTUAL_OPCODE(opcode)); - int oparg = HAS_ARG(opcode) ? instruction->i_oparg : 0; - int extended_args = (0xFFFFFF < oparg) + (0xFFFF < oparg) + (0xFF < oparg); - int caches = _PyOpcode_Caches[opcode]; - return extended_args + 1 + caches; -} +#define USE_LABEL(C, LBL) \ + RETURN_IF_ERROR(instr_sequence_use_label(INSTR_SEQUENCE(C), (LBL).id)) -static void -write_instr(_Py_CODEUNIT *codestr, struct instr *instruction, int ilen) -{ - int opcode = instruction->i_opcode; - assert(!IS_VIRTUAL_OPCODE(opcode)); - int oparg = HAS_ARG(opcode) ? instruction->i_oparg : 0; - int caches = _PyOpcode_Caches[opcode]; - switch (ilen - caches) { - case 4: - *codestr++ = _Py_MAKECODEUNIT(EXTENDED_ARG, (oparg >> 24) & 0xFF); - /* fall through */ - case 3: - *codestr++ = _Py_MAKECODEUNIT(EXTENDED_ARG, (oparg >> 16) & 0xFF); - /* fall through */ - case 2: - *codestr++ = _Py_MAKECODEUNIT(EXTENDED_ARG, (oparg >> 8) & 0xFF); - /* fall through */ - case 1: - *codestr++ = _Py_MAKECODEUNIT(opcode, oparg & 0xFF); - break; - default: - Py_UNREACHABLE(); - } - while (caches--) { - *codestr++ = _Py_MAKECODEUNIT(CACHE, 0); - } -} - -typedef struct basicblock_ { - /* Each basicblock in a compilation unit is linked via b_list in the - reverse order that the block are allocated. b_list points to the next - block, not to be confused with b_next, which is next by control flow. */ - struct basicblock_ *b_list; - /* Exception stack at start of block, used by assembler to create the exception handling table */ - ExceptStack *b_exceptstack; - /* pointer to an array of instructions, initially NULL */ - struct instr *b_instr; - /* If b_next is non-NULL, it is a pointer to the next - block reached by normal control flow. */ - struct basicblock_ *b_next; - /* number of instructions used */ - int b_iused; - /* length of instruction array (b_instr) */ - int b_ialloc; - /* Number of predecssors that a block has. */ - int b_predecessors; - /* depth of stack upon entry of block, computed by stackdepth() */ - int b_startdepth; - /* instruction offset for block, computed by assemble_jump_offsets() */ - int b_offset; - /* Basic block has no fall through (it ends with a return, raise or jump) */ - unsigned b_nofallthrough : 1; - /* Basic block is an exception handler that preserves lasti */ - unsigned b_preserve_lasti : 1; - /* Used by compiler passes to mark whether they have visited a basic block. */ - unsigned b_visited : 1; - /* Basic block exits scope (it ends with a return or raise) */ - unsigned b_exit : 1; - /* b_return is true if a RETURN_VALUE opcode is inserted. */ - unsigned b_return : 1; -} basicblock; /* fblockinfo tracks the current frame block. @@ -277,9 +133,9 @@ enum fblocktype { WHILE_LOOP, FOR_LOOP, TRY_EXCEPT, FINALLY_TRY, FINALLY_END, struct fblockinfo { enum fblocktype fb_type; - basicblock *fb_block; + jump_target_label fb_block; /* (optional) type-specific exit or cleanup block */ - basicblock *fb_exit; + jump_target_label fb_exit; /* (optional) additional information required for unwinding */ void *fb_datum; }; @@ -291,49 +147,252 @@ enum { COMPILER_SCOPE_ASYNC_FUNCTION, COMPILER_SCOPE_LAMBDA, COMPILER_SCOPE_COMPREHENSION, + COMPILER_SCOPE_TYPEPARAMS, }; + +int +_PyCompile_InstrSize(int opcode, int oparg) +{ + assert(!IS_PSEUDO_OPCODE(opcode)); + assert(HAS_ARG(opcode) || oparg == 0); + int extended_args = (0xFFFFFF < oparg) + (0xFFFF < oparg) + (0xFF < oparg); + int caches = _PyOpcode_Caches[opcode]; + return extended_args + 1 + caches; +} + +typedef _PyCompile_Instruction instruction; +typedef _PyCompile_InstructionSequence instr_sequence; + +#define INITIAL_INSTR_SEQUENCE_SIZE 100 +#define INITIAL_INSTR_SEQUENCE_LABELS_MAP_SIZE 10 + +/* + * Resize the array if index is out of range. + * + * idx: the index we want to access + * arr: pointer to the array + * alloc: pointer to the capacity of the array + * default_alloc: initial number of items + * item_size: size of each item + * + */ +int +_PyCompile_EnsureArrayLargeEnough(int idx, void **array, int *alloc, + int default_alloc, size_t item_size) +{ + void *arr = *array; + if (arr == NULL) { + int new_alloc = default_alloc; + if (idx >= new_alloc) { + new_alloc = idx + default_alloc; + } + arr = PyObject_Calloc(new_alloc, item_size); + if (arr == NULL) { + PyErr_NoMemory(); + return ERROR; + } + *alloc = new_alloc; + } + else if (idx >= *alloc) { + size_t oldsize = *alloc * item_size; + int new_alloc = *alloc << 1; + if (idx >= new_alloc) { + new_alloc = idx + default_alloc; + } + size_t newsize = new_alloc * item_size; + + if (oldsize > (SIZE_MAX >> 1)) { + PyErr_NoMemory(); + return ERROR; + } + + assert(newsize > 0); + void *tmp = PyObject_Realloc(arr, newsize); + if (tmp == NULL) { + PyErr_NoMemory(); + return ERROR; + } + *alloc = new_alloc; + arr = tmp; + memset((char *)arr + oldsize, 0, newsize - oldsize); + } + + *array = arr; + return SUCCESS; +} + +static int +instr_sequence_next_inst(instr_sequence *seq) { + assert(seq->s_instrs != NULL || seq->s_used == 0); + + RETURN_IF_ERROR( + _PyCompile_EnsureArrayLargeEnough(seq->s_used + 1, + (void**)&seq->s_instrs, + &seq->s_allocated, + INITIAL_INSTR_SEQUENCE_SIZE, + sizeof(instruction))); + assert(seq->s_allocated >= 0); + assert(seq->s_used < seq->s_allocated); + return seq->s_used++; +} + +static jump_target_label +instr_sequence_new_label(instr_sequence *seq) +{ + jump_target_label lbl = {++seq->s_next_free_label}; + return lbl; +} + +static int +instr_sequence_use_label(instr_sequence *seq, int lbl) { + int old_size = seq->s_labelmap_size; + RETURN_IF_ERROR( + _PyCompile_EnsureArrayLargeEnough(lbl, + (void**)&seq->s_labelmap, + &seq->s_labelmap_size, + INITIAL_INSTR_SEQUENCE_LABELS_MAP_SIZE, + sizeof(int))); + + for(int i = old_size; i < seq->s_labelmap_size; i++) { + seq->s_labelmap[i] = -111; /* something weird, for debugging */ + } + seq->s_labelmap[lbl] = seq->s_used; /* label refers to the next instruction */ + return SUCCESS; +} + +static int +instr_sequence_addop(instr_sequence *seq, int opcode, int oparg, location loc) +{ + assert(IS_WITHIN_OPCODE_RANGE(opcode)); + assert(HAS_ARG(opcode) || HAS_TARGET(opcode) || oparg == 0); + assert(0 <= oparg && oparg < (1 << 30)); + + int idx = instr_sequence_next_inst(seq); + RETURN_IF_ERROR(idx); + instruction *ci = &seq->s_instrs[idx]; + ci->i_opcode = opcode; + ci->i_oparg = oparg; + ci->i_loc = loc; + return SUCCESS; +} + +static int +instr_sequence_insert_instruction(instr_sequence *seq, int pos, + int opcode, int oparg, location loc) +{ + assert(pos >= 0 && pos <= seq->s_used); + int last_idx = instr_sequence_next_inst(seq); + RETURN_IF_ERROR(last_idx); + for (int i=last_idx-1; i >= pos; i--) { + seq->s_instrs[i+1] = seq->s_instrs[i]; + } + instruction *ci = &seq->s_instrs[pos]; + ci->i_opcode = opcode; + ci->i_oparg = oparg; + ci->i_loc = loc; + + /* fix the labels map */ + for(int lbl=0; lbl < seq->s_labelmap_size; lbl++) { + if (seq->s_labelmap[lbl] >= pos) { + seq->s_labelmap[lbl]++; + } + } + return SUCCESS; +} + +static void +instr_sequence_fini(instr_sequence *seq) { + PyObject_Free(seq->s_labelmap); + seq->s_labelmap = NULL; + + PyObject_Free(seq->s_instrs); + seq->s_instrs = NULL; +} + +static int +instr_sequence_to_cfg(instr_sequence *seq, cfg_builder *g) { + memset(g, 0, sizeof(cfg_builder)); + RETURN_IF_ERROR(_PyCfgBuilder_Init(g)); + + /* There can be more than one label for the same offset. The + * offset2lbl maping selects one of them which we use consistently. + */ + + int *offset2lbl = PyMem_Malloc(seq->s_used * sizeof(int)); + if (offset2lbl == NULL) { + PyErr_NoMemory(); + return ERROR; + } + for (int i = 0; i < seq->s_used; i++) { + offset2lbl[i] = -1; + } + for (int lbl=0; lbl < seq->s_labelmap_size; lbl++) { + int offset = seq->s_labelmap[lbl]; + if (offset >= 0) { + assert(offset < seq->s_used); + offset2lbl[offset] = lbl; + } + } + + for (int i = 0; i < seq->s_used; i++) { + int lbl = offset2lbl[i]; + if (lbl >= 0) { + assert (lbl < seq->s_labelmap_size); + jump_target_label lbl_ = {lbl}; + if (_PyCfgBuilder_UseLabel(g, lbl_) < 0) { + goto error; + } + } + instruction *instr = &seq->s_instrs[i]; + int opcode = instr->i_opcode; + int oparg = instr->i_oparg; + if (HAS_TARGET(opcode)) { + int offset = seq->s_labelmap[oparg]; + assert(offset >= 0 && offset < seq->s_used); + int lbl = offset2lbl[offset]; + assert(lbl >= 0 && lbl < seq->s_labelmap_size); + oparg = lbl; + } + if (_PyCfgBuilder_Addop(g, opcode, oparg, instr->i_loc) < 0) { + goto error; + } + } + PyMem_Free(offset2lbl); + + int nblocks = 0; + for (basicblock *b = g->g_block_list; b != NULL; b = b->b_list) { + nblocks++; + } + if ((size_t)nblocks > SIZE_MAX / sizeof(basicblock *)) { + PyErr_NoMemory(); + return ERROR; + } + return SUCCESS; +error: + PyMem_Free(offset2lbl); + return ERROR; +} + + /* The following items change on entry and exit of code blocks. They must be saved and restored when returning to a block. */ struct compiler_unit { PySTEntryObject *u_ste; - PyObject *u_name; - PyObject *u_qualname; /* dot-separated qualified name (lazy) */ int u_scope_type; - /* The following fields are dicts that map objects to - the index of them in co_XXX. The index is used as - the argument for opcodes that refer to those collections. - */ - PyObject *u_consts; /* all constants */ - PyObject *u_names; /* all names */ - PyObject *u_varnames; /* local variables */ - PyObject *u_cellvars; /* cell variables */ - PyObject *u_freevars; /* free variables */ - PyObject *u_private; /* for private name mangling */ - Py_ssize_t u_argcount; /* number of arguments for block */ - Py_ssize_t u_posonlyargcount; /* number of positional only arguments for block */ - Py_ssize_t u_kwonlyargcount; /* number of keyword only arguments for block */ - /* Pointer to the most recently allocated block. By following b_list - members, you can reach all early allocated blocks. */ - basicblock *u_blocks; - basicblock *u_curblock; /* pointer to current block */ + instr_sequence u_instr_sequence; /* codegen output */ int u_nfblocks; - struct fblockinfo u_fblock[CO_MAXBLOCKS]; + int u_in_inlined_comp; - int u_firstlineno; /* the first lineno of the block */ - int u_lineno; /* the lineno for the current stmt */ - int u_col_offset; /* the offset of the current stmt */ - int u_end_lineno; /* the end line of the current stmt */ - int u_end_col_offset; /* the end offset of the current stmt */ + struct fblockinfo u_fblock[CO_MAXBLOCKS]; - /* true if we need to create an implicit basicblock before the next instr */ - int u_need_new_implicit_block; + _PyCompile_CodeUnitMetadata u_metadata; }; /* This struct captures the global state of a compilation. @@ -351,8 +410,8 @@ handled by the symbol analysis pass. struct compiler { PyObject *c_filename; struct symtable *c_st; - PyFutureFeatures *c_future; /* pointer to module's __future__ */ - PyCompilerFlags *c_flags; + PyFutureFeatures c_future; /* module's __future__ */ + PyCompilerFlags c_flags; int c_optimize; /* optimization level */ int c_interactive; /* true if in interactive mode */ @@ -364,6 +423,9 @@ struct compiler { PyArena *c_arena; /* pointer to memory allocation arena */ }; +#define INSTR_SEQUENCE(C) (&((C)->u->u_instr_sequence)) + + typedef struct { // A list of strings corresponding to name captures. It is used to track: // - Repeated name assignments in the same pattern. @@ -380,7 +442,7 @@ typedef struct { // fail_pop[2]: POP_TOP // fail_pop[1]: POP_TOP // fail_pop[0]: NOP - basicblock **fail_pop; + jump_target_label *fail_pop; // The current length of fail_pop. Py_ssize_t fail_pop_size; // The number of items on top of the stack that need to *stay* on top of the @@ -389,17 +451,12 @@ typedef struct { Py_ssize_t on_top; } pattern_context; -static int compiler_enter_scope(struct compiler *, identifier, int, void *, int); +static int codegen_addop_i(instr_sequence *seq, int opcode, Py_ssize_t oparg, location loc); + static void compiler_free(struct compiler *); -static basicblock *compiler_new_block(struct compiler *); -static int compiler_next_instr(basicblock *); -static int compiler_addop(struct compiler *, int); -static int compiler_addop_i(struct compiler *, int, Py_ssize_t); -static int compiler_addop_j(struct compiler *, int, basicblock *); -static int compiler_addop_j_noline(struct compiler *, int, basicblock *); -static int compiler_error(struct compiler *, const char *, ...); -static int compiler_warn(struct compiler *, const char *, ...); -static int compiler_nameop(struct compiler *, identifier, expr_context_ty); +static int compiler_error(struct compiler *, location loc, const char *, ...); +static int compiler_warn(struct compiler *, location loc, const char *, ...); +static int compiler_nameop(struct compiler *, location, identifier, expr_context_ty); static PyCodeObject *compiler_mod(struct compiler *, mod_ty); static int compiler_visit_stmt(struct compiler *, stmt_ty); @@ -410,178 +467,122 @@ static int compiler_annassign(struct compiler *, stmt_ty); static int compiler_subscript(struct compiler *, expr_ty); static int compiler_slice(struct compiler *, expr_ty); -static int are_all_items_const(asdl_expr_seq *, Py_ssize_t, Py_ssize_t); +static bool are_all_items_const(asdl_expr_seq *, Py_ssize_t, Py_ssize_t); static int compiler_with(struct compiler *, stmt_ty, int); static int compiler_async_with(struct compiler *, stmt_ty, int); static int compiler_async_for(struct compiler *, stmt_ty); -static int validate_keywords(struct compiler *c, asdl_keyword_seq *keywords); static int compiler_call_simple_kw_helper(struct compiler *c, + location loc, asdl_keyword_seq *keywords, Py_ssize_t nkwelts); -static int compiler_call_helper(struct compiler *c, int n, - asdl_expr_seq *args, +static int compiler_call_helper(struct compiler *c, location loc, + int n, asdl_expr_seq *args, asdl_keyword_seq *keywords); static int compiler_try_except(struct compiler *, stmt_ty); static int compiler_try_star_except(struct compiler *, stmt_ty); static int compiler_set_qualname(struct compiler *); static int compiler_sync_comprehension_generator( - struct compiler *c, + struct compiler *c, location loc, asdl_comprehension_seq *generators, int gen_index, int depth, - expr_ty elt, expr_ty val, int type); + expr_ty elt, expr_ty val, int type, + int iter_on_stack); static int compiler_async_comprehension_generator( - struct compiler *c, + struct compiler *c, location loc, asdl_comprehension_seq *generators, int gen_index, int depth, - expr_ty elt, expr_ty val, int type); + expr_ty elt, expr_ty val, int type, + int iter_on_stack); static int compiler_pattern(struct compiler *, pattern_ty, pattern_context *); static int compiler_match(struct compiler *, stmt_ty); -static int compiler_pattern_subpattern(struct compiler *, pattern_ty, - pattern_context *); - -static void clean_basic_block(basicblock *bb); +static int compiler_pattern_subpattern(struct compiler *, + pattern_ty, pattern_context *); -static PyCodeObject *assemble(struct compiler *, int addNone); +static PyCodeObject *optimize_and_assemble(struct compiler *, int addNone); #define CAPSULE_NAME "compile.c compiler unit" -PyObject * -_Py_Mangle(PyObject *privateobj, PyObject *ident) -{ - /* Name mangling: __private becomes _classname__private. - This is independent from how the name is used. */ - PyObject *result; - size_t nlen, plen, ipriv; - Py_UCS4 maxchar; - if (privateobj == NULL || !PyUnicode_Check(privateobj) || - PyUnicode_READ_CHAR(ident, 0) != '_' || - PyUnicode_READ_CHAR(ident, 1) != '_') { - Py_INCREF(ident); - return ident; - } - nlen = PyUnicode_GET_LENGTH(ident); - plen = PyUnicode_GET_LENGTH(privateobj); - /* Don't mangle __id__ or names with dots. - - The only time a name with a dot can occur is when - we are compiling an import statement that has a - package name. - - TODO(jhylton): Decide whether we want to support - mangling of the module name, e.g. __M.X. - */ - if ((PyUnicode_READ_CHAR(ident, nlen-1) == '_' && - PyUnicode_READ_CHAR(ident, nlen-2) == '_') || - PyUnicode_FindChar(ident, '.', 0, nlen, 1) != -1) { - Py_INCREF(ident); - return ident; /* Don't mangle __whatever__ */ - } - /* Strip leading underscores from class name */ - ipriv = 0; - while (PyUnicode_READ_CHAR(privateobj, ipriv) == '_') - ipriv++; - if (ipriv == plen) { - Py_INCREF(ident); - return ident; /* Don't mangle if class is just underscores */ - } - plen -= ipriv; - - if (plen + nlen >= PY_SSIZE_T_MAX - 1) { - PyErr_SetString(PyExc_OverflowError, - "private identifier too large to be mangled"); - return NULL; - } - - maxchar = PyUnicode_MAX_CHAR_VALUE(ident); - if (PyUnicode_MAX_CHAR_VALUE(privateobj) > maxchar) - maxchar = PyUnicode_MAX_CHAR_VALUE(privateobj); - - result = PyUnicode_New(1 + nlen + plen, maxchar); - if (!result) - return 0; - /* ident = "_" + priv[ipriv:] + ident # i.e. 1+plen+nlen bytes */ - PyUnicode_WRITE(PyUnicode_KIND(result), PyUnicode_DATA(result), 0, '_'); - if (PyUnicode_CopyCharacters(result, 1, privateobj, ipriv, plen) < 0) { - Py_DECREF(result); - return NULL; - } - if (PyUnicode_CopyCharacters(result, plen+1, ident, 0, nlen) < 0) { - Py_DECREF(result); - return NULL; - } - assert(_PyUnicode_CheckConsistency(result, 1)); - return result; -} static int -compiler_init(struct compiler *c) +compiler_setup(struct compiler *c, mod_ty mod, PyObject *filename, + PyCompilerFlags *flags, int optimize, PyArena *arena) { - memset(c, 0, sizeof(struct compiler)); + PyCompilerFlags local_flags = _PyCompilerFlags_INIT; c->c_const_cache = PyDict_New(); if (!c->c_const_cache) { - return 0; + return ERROR; } c->c_stack = PyList_New(0); if (!c->c_stack) { - Py_CLEAR(c->c_const_cache); - return 0; + return ERROR; } - return 1; -} - -PyCodeObject * -_PyAST_Compile(mod_ty mod, PyObject *filename, PyCompilerFlags *flags, - int optimize, PyArena *arena) -{ - struct compiler c; - PyCodeObject *co = NULL; - PyCompilerFlags local_flags = _PyCompilerFlags_INIT; - int merged; - if (!compiler_init(&c)) - return NULL; - Py_INCREF(filename); - c.c_filename = filename; - c.c_arena = arena; - c.c_future = _PyFuture_FromAST(mod, filename); - if (c.c_future == NULL) - goto finally; + c->c_filename = Py_NewRef(filename); + c->c_arena = arena; + if (!_PyFuture_FromAST(mod, filename, &c->c_future)) { + return ERROR; + } if (!flags) { flags = &local_flags; } - merged = c.c_future->ff_features | flags->cf_flags; - c.c_future->ff_features = merged; + int merged = c->c_future.ff_features | flags->cf_flags; + c->c_future.ff_features = merged; flags->cf_flags = merged; - c.c_flags = flags; - c.c_optimize = (optimize == -1) ? _Py_GetConfig()->optimization_level : optimize; - c.c_nestlevel = 0; + c->c_flags = *flags; + c->c_optimize = (optimize == -1) ? _Py_GetConfig()->optimization_level : optimize; + c->c_nestlevel = 0; _PyASTOptimizeState state; - state.optimize = c.c_optimize; + state.optimize = c->c_optimize; state.ff_features = merged; if (!_PyAST_Optimize(mod, arena, &state)) { - goto finally; + return ERROR; } - - c.c_st = _PySymtable_Build(mod, filename, c.c_future); - if (c.c_st == NULL) { - if (!PyErr_Occurred()) + c->c_st = _PySymtable_Build(mod, filename, &c->c_future); + if (c->c_st == NULL) { + if (!PyErr_Occurred()) { PyErr_SetString(PyExc_SystemError, "no symtable"); - goto finally; + } + return ERROR; + } + return SUCCESS; +} + +static struct compiler* +new_compiler(mod_ty mod, PyObject *filename, PyCompilerFlags *pflags, + int optimize, PyArena *arena) +{ + struct compiler *c = PyMem_Calloc(1, sizeof(struct compiler)); + if (c == NULL) { + return NULL; + } + if (compiler_setup(c, mod, filename, pflags, optimize, arena) < 0) { + compiler_free(c); + return NULL; } + return c; +} - co = compiler_mod(&c, mod); +PyCodeObject * +_PyAST_Compile(mod_ty mod, PyObject *filename, PyCompilerFlags *pflags, + int optimize, PyArena *arena) +{ + assert(!PyErr_Occurred()); + struct compiler *c = new_compiler(mod, filename, pflags, optimize, arena); + if (c == NULL) { + return NULL; + } - finally: - compiler_free(&c); + PyCodeObject *co = compiler_mod(c, mod); + compiler_free(c); assert(co || PyErr_Occurred()); return co; } @@ -591,11 +592,10 @@ compiler_free(struct compiler *c) { if (c->c_st) _PySymtable_Free(c->c_st); - if (c->c_future) - PyObject_Free(c->c_future); Py_XDECREF(c->c_filename); - Py_DECREF(c->c_const_cache); - Py_DECREF(c->c_stack); + Py_XDECREF(c->c_const_cache); + Py_XDECREF(c->c_stack); + PyMem_Free(c); } static PyObject * @@ -687,46 +687,19 @@ dictbytype(PyObject *src, int scope_type, int flag, Py_ssize_t offset) return dest; } -static void -compiler_unit_check(struct compiler_unit *u) -{ - basicblock *block; - for (block = u->u_blocks; block != NULL; block = block->b_list) { - assert(!_PyMem_IsPtrFreed(block)); - if (block->b_instr != NULL) { - assert(block->b_ialloc > 0); - assert(block->b_iused >= 0); - assert(block->b_ialloc >= block->b_iused); - } - else { - assert (block->b_iused == 0); - assert (block->b_ialloc == 0); - } - } -} - static void compiler_unit_free(struct compiler_unit *u) { - basicblock *b, *next; - - compiler_unit_check(u); - b = u->u_blocks; - while (b != NULL) { - if (b->b_instr) - PyObject_Free((void *)b->b_instr); - next = b->b_list; - PyObject_Free((void *)b); - b = next; - } + instr_sequence_fini(&u->u_instr_sequence); Py_CLEAR(u->u_ste); - Py_CLEAR(u->u_name); - Py_CLEAR(u->u_qualname); - Py_CLEAR(u->u_consts); - Py_CLEAR(u->u_names); - Py_CLEAR(u->u_varnames); - Py_CLEAR(u->u_freevars); - Py_CLEAR(u->u_cellvars); + Py_CLEAR(u->u_metadata.u_name); + Py_CLEAR(u->u_metadata.u_qualname); + Py_CLEAR(u->u_metadata.u_consts); + Py_CLEAR(u->u_metadata.u_names); + Py_CLEAR(u->u_metadata.u_varnames); + Py_CLEAR(u->u_metadata.u_freevars); + Py_CLEAR(u->u_metadata.u_cellvars); + Py_CLEAR(u->u_metadata.u_fasthidden); Py_CLEAR(u->u_private); PyObject_Free(u); } @@ -749,14 +722,29 @@ compiler_set_qualname(struct compiler *c) capsule = PyList_GET_ITEM(c->c_stack, stack_size - 1); parent = (struct compiler_unit *)PyCapsule_GetPointer(capsule, CAPSULE_NAME); assert(parent); + if (parent->u_scope_type == COMPILER_SCOPE_TYPEPARAMS) { + /* The parent is a type parameter scope, so we need to + look at the grandparent. */ + if (stack_size == 2) { + // If we're immediately within the module, we can skip + // the rest and just set the qualname to be the same as name. + u->u_metadata.u_qualname = Py_NewRef(u->u_metadata.u_name); + return SUCCESS; + } + capsule = PyList_GET_ITEM(c->c_stack, stack_size - 2); + parent = (struct compiler_unit *)PyCapsule_GetPointer(capsule, CAPSULE_NAME); + assert(parent); + } if (u->u_scope_type == COMPILER_SCOPE_FUNCTION || u->u_scope_type == COMPILER_SCOPE_ASYNC_FUNCTION || u->u_scope_type == COMPILER_SCOPE_CLASS) { - assert(u->u_name); - mangled = _Py_Mangle(parent->u_private, u->u_name); - if (!mangled) - return 0; + assert(u->u_metadata.u_name); + mangled = _Py_Mangle(parent->u_private, u->u_metadata.u_name); + if (!mangled) { + return ERROR; + } + scope = _PyST_GetScope(parent->u_ste, mangled); Py_DECREF(mangled); assert(scope != GLOBAL_IMPLICIT); @@ -770,14 +758,14 @@ compiler_set_qualname(struct compiler *c) || parent->u_scope_type == COMPILER_SCOPE_LAMBDA) { _Py_DECLARE_STR(dot_locals, ".<locals>"); - base = PyUnicode_Concat(parent->u_qualname, + base = PyUnicode_Concat(parent->u_metadata.u_qualname, &_Py_STR(dot_locals)); - if (base == NULL) - return 0; + if (base == NULL) { + return ERROR; + } } else { - Py_INCREF(parent->u_qualname); - base = parent->u_qualname; + base = Py_NewRef(parent->u_metadata.u_qualname); } } } @@ -786,150 +774,21 @@ compiler_set_qualname(struct compiler *c) _Py_DECLARE_STR(dot, "."); name = PyUnicode_Concat(base, &_Py_STR(dot)); Py_DECREF(base); - if (name == NULL) - return 0; - PyUnicode_Append(&name, u->u_name); - if (name == NULL) - return 0; - } - else { - Py_INCREF(u->u_name); - name = u->u_name; - } - u->u_qualname = name; - - return 1; -} - - -/* Allocate a new block and return a pointer to it. - Returns NULL on error. -*/ - -static basicblock * -compiler_new_block(struct compiler *c) -{ - basicblock *b; - struct compiler_unit *u; - - u = c->u; - b = (basicblock *)PyObject_Calloc(1, sizeof(basicblock)); - if (b == NULL) { - PyErr_NoMemory(); - return NULL; - } - /* Extend the singly linked list of blocks with new block. */ - b->b_list = u->u_blocks; - u->u_blocks = b; - return b; -} - -static basicblock * -compiler_use_next_block(struct compiler *c, basicblock *block) -{ - assert(block != NULL); - c->u->u_curblock->b_next = block; - c->u->u_curblock = block; - c->u->u_need_new_implicit_block = 0; - return block; -} - -static basicblock * -compiler_copy_block(struct compiler *c, basicblock *block) -{ - /* Cannot copy a block if it has a fallthrough, since - * a block can only have one fallthrough predecessor. - */ - assert(block->b_nofallthrough); - basicblock *result = compiler_new_block(c); - if (result == NULL) { - return NULL; - } - for (int i = 0; i < block->b_iused; i++) { - int n = compiler_next_instr(result); - if (n < 0) { - return NULL; + if (name == NULL) { + return ERROR; } - result->b_instr[n] = block->b_instr[i]; - } - result->b_exit = block->b_exit; - result->b_nofallthrough = 1; - return result; -} - -/* Returns the offset of the next instruction in the current block's - b_instr array. Resizes the b_instr as necessary. - Returns -1 on failure. -*/ - -static int -compiler_next_instr(basicblock *b) -{ - assert(b != NULL); - if (b->b_instr == NULL) { - b->b_instr = (struct instr *)PyObject_Calloc( - DEFAULT_BLOCK_SIZE, sizeof(struct instr)); - if (b->b_instr == NULL) { - PyErr_NoMemory(); - return -1; + PyUnicode_Append(&name, u->u_metadata.u_name); + if (name == NULL) { + return ERROR; } - b->b_ialloc = DEFAULT_BLOCK_SIZE; } - else if (b->b_iused == b->b_ialloc) { - struct instr *tmp; - size_t oldsize, newsize; - oldsize = b->b_ialloc * sizeof(struct instr); - newsize = oldsize << 1; - - if (oldsize > (SIZE_MAX >> 1)) { - PyErr_NoMemory(); - return -1; - } - - if (newsize == 0) { - PyErr_NoMemory(); - return -1; - } - b->b_ialloc <<= 1; - tmp = (struct instr *)PyObject_Realloc( - (void *)b->b_instr, newsize); - if (tmp == NULL) { - PyErr_NoMemory(); - return -1; - } - b->b_instr = tmp; - memset((char *)b->b_instr + oldsize, 0, newsize - oldsize); + else { + name = Py_NewRef(u->u_metadata.u_name); } - return b->b_iused++; -} + u->u_metadata.u_qualname = name; -/* Set the line number and column offset for the following instructions. - - The line number is reset in the following cases: - - when entering a new scope - - on each statement - - on each expression and sub-expression - - before the "except" and "finally" clauses -*/ - -#define SET_LOC(c, x) \ - (c)->u->u_lineno = (x)->lineno; \ - (c)->u->u_col_offset = (x)->col_offset; \ - (c)->u->u_end_lineno = (x)->end_lineno; \ - (c)->u->u_end_col_offset = (x)->end_col_offset; - -// Artificial instructions -#define UNSET_LOC(c) \ - (c)->u->u_lineno = -1; \ - (c)->u->u_col_offset = -1; \ - (c)->u->u_end_lineno = -1; \ - (c)->u->u_end_col_offset = -1; - -#define COPY_INSTR_LOC(old, new) \ - (new).i_lineno = (old).i_lineno; \ - (new).i_col_offset = (old).i_col_offset; \ - (new).i_end_lineno = (old).i_end_lineno; \ - (new).i_end_col_offset = (old).i_end_col_offset; + return SUCCESS; +} /* Return the stack effect of opcode with argument oparg. @@ -943,139 +802,49 @@ compiler_next_instr(basicblock *b) static int stack_effect(int opcode, int oparg, int jump) { - switch (opcode) { - case NOP: - case EXTENDED_ARG: - case RESUME: - case CACHE: - return 0; - - /* Stack manipulation */ - case POP_TOP: - return -1; - case SWAP: - return 0; - - /* Unary operators */ - case UNARY_POSITIVE: - case UNARY_NEGATIVE: - case UNARY_NOT: - case UNARY_INVERT: - return 0; - - case SET_ADD: - case LIST_APPEND: - return -1; - case MAP_ADD: - return -2; - - case BINARY_SUBSCR: - return -1; - case STORE_SUBSCR: - return -3; - case DELETE_SUBSCR: - return -2; - - case GET_ITER: - return 0; - - case PRINT_EXPR: - return -1; - case LOAD_BUILD_CLASS: - return 1; + if (0 <= opcode && opcode <= MAX_REAL_OPCODE) { + if (_PyOpcode_Deopt[opcode] != opcode) { + // Specialized instructions are not supported. + return PY_INVALID_STACK_EFFECT; + } + int popped, pushed; + if (jump > 0) { + popped = _PyOpcode_num_popped(opcode, oparg, true); + pushed = _PyOpcode_num_pushed(opcode, oparg, true); + } + else { + popped = _PyOpcode_num_popped(opcode, oparg, false); + pushed = _PyOpcode_num_pushed(opcode, oparg, false); + } + if (popped < 0 || pushed < 0) { + return PY_INVALID_STACK_EFFECT; + } + if (jump >= 0) { + return pushed - popped; + } + if (jump < 0) { + // Compute max(pushed - popped, alt_pushed - alt_popped) + int alt_popped = _PyOpcode_num_popped(opcode, oparg, true); + int alt_pushed = _PyOpcode_num_pushed(opcode, oparg, true); + if (alt_popped < 0 || alt_pushed < 0) { + return PY_INVALID_STACK_EFFECT; + } + int diff = pushed - popped; + int alt_diff = alt_pushed - alt_popped; + if (alt_diff > diff) { + return alt_diff; + } + return diff; + } + } - case RETURN_VALUE: - return -1; - case IMPORT_STAR: - return -1; - case SETUP_ANNOTATIONS: - return 0; - case ASYNC_GEN_WRAP: - case YIELD_VALUE: - return 0; + // Pseudo ops + switch (opcode) { case POP_BLOCK: - return 0; - case POP_EXCEPT: - return -1; - - case STORE_NAME: - return -1; - case DELETE_NAME: - return 0; - case UNPACK_SEQUENCE: - return oparg-1; - case UNPACK_EX: - return (oparg&0xFF) + (oparg>>8); - case FOR_ITER: - /* -1 at end of iterator, 1 if continue iterating. */ - return jump > 0 ? -1 : 1; - case SEND: - return jump > 0 ? -1 : 0; - case STORE_ATTR: - return -2; - case DELETE_ATTR: - return -1; - case STORE_GLOBAL: - return -1; - case DELETE_GLOBAL: - return 0; - case LOAD_CONST: - return 1; - case LOAD_NAME: - return 1; - case BUILD_TUPLE: - case BUILD_LIST: - case BUILD_SET: - case BUILD_STRING: - return 1-oparg; - case BUILD_MAP: - return 1 - 2*oparg; - case BUILD_CONST_KEY_MAP: - return -oparg; - case LOAD_ATTR: - return 0; - case COMPARE_OP: - case IS_OP: - case CONTAINS_OP: - return -1; - case CHECK_EXC_MATCH: - return 0; - case CHECK_EG_MATCH: - return 0; - case IMPORT_NAME: - return -1; - case IMPORT_FROM: - return 1; - - /* Jumps */ - case JUMP_FORWARD: - case JUMP_BACKWARD: case JUMP: - case JUMP_BACKWARD_NO_INTERRUPT: case JUMP_NO_INTERRUPT: return 0; - case JUMP_IF_TRUE_OR_POP: - case JUMP_IF_FALSE_OR_POP: - return jump ? 0 : -1; - - case POP_JUMP_BACKWARD_IF_NONE: - case POP_JUMP_FORWARD_IF_NONE: - case POP_JUMP_IF_NONE: - case POP_JUMP_BACKWARD_IF_NOT_NONE: - case POP_JUMP_FORWARD_IF_NOT_NONE: - case POP_JUMP_IF_NOT_NONE: - case POP_JUMP_FORWARD_IF_FALSE: - case POP_JUMP_BACKWARD_IF_FALSE: - case POP_JUMP_IF_FALSE: - case POP_JUMP_FORWARD_IF_TRUE: - case POP_JUMP_BACKWARD_IF_TRUE: - case POP_JUMP_IF_TRUE: - return -1; - - case LOAD_GLOBAL: - return (oparg & 1) + 1; - /* Exception handling pseudo-instructions */ case SETUP_FINALLY: /* 0 in the normal flow. @@ -1092,107 +861,18 @@ stack_effect(int opcode, int oparg, int jump) * if an exception be raised. */ return jump ? 1 : 0; - case PREP_RERAISE_STAR: - return -1; - case RERAISE: - return -1; - case PUSH_EXC_INFO: - return 1; - - case WITH_EXCEPT_START: - return 1; - - case LOAD_FAST: - return 1; - case STORE_FAST: - return -1; - case DELETE_FAST: - return 0; - - case RETURN_GENERATOR: - return 0; - - case RAISE_VARARGS: - return -oparg; - - /* Functions and calls */ - case PRECALL: - return -oparg; - case KW_NAMES: - return 0; - case CALL: - return -1; - - case CALL_FUNCTION_EX: - return -2 - ((oparg & 0x01) != 0); - case MAKE_FUNCTION: - return 0 - ((oparg & 0x01) != 0) - ((oparg & 0x02) != 0) - - ((oparg & 0x04) != 0) - ((oparg & 0x08) != 0); - case BUILD_SLICE: - if (oparg == 3) - return -2; - else - return -1; - - /* Closures */ - case MAKE_CELL: - case COPY_FREE_VARS: - return 0; - case LOAD_CLOSURE: - return 1; - case LOAD_DEREF: - case LOAD_CLASSDEREF: - return 1; - case STORE_DEREF: + case STORE_FAST_MAYBE_NULL: return -1; - case DELETE_DEREF: - return 0; - - /* Iterators and generators */ - case GET_AWAITABLE: - return 0; - - case BEFORE_ASYNC_WITH: - case BEFORE_WITH: - return 1; - case GET_AITER: - return 0; - case GET_ANEXT: - return 1; - case GET_YIELD_FROM_ITER: - return 0; - case END_ASYNC_FOR: - return -2; - case FORMAT_VALUE: - /* If there's a fmt_spec on the stack, we go from 2->1, - else 1->1. */ - return (oparg & FVS_MASK) == FVS_HAVE_SPEC ? -1 : 0; case LOAD_METHOD: return 1; - case LOAD_ASSERTION_ERROR: - return 1; - case LIST_TO_TUPLE: - return 0; - case LIST_EXTEND: - case SET_UPDATE: - case DICT_MERGE: - case DICT_UPDATE: - return -1; - case MATCH_CLASS: - return -2; - case GET_LEN: - case MATCH_MAPPING: - case MATCH_SEQUENCE: - case MATCH_KEYS: - return 1; - case COPY: - case PUSH_NULL: - return 1; - case BINARY_OP: + case LOAD_SUPER_METHOD: + case LOAD_ZERO_SUPER_METHOD: + case LOAD_ZERO_SUPER_ATTR: return -1; default: return PY_INVALID_STACK_EFFECT; } + return PY_INVALID_STACK_EFFECT; /* not reachable */ } @@ -1208,89 +888,16 @@ PyCompile_OpcodeStackEffect(int opcode, int oparg) return stack_effect(opcode, oparg, -1); } -static int is_end_of_basic_block(struct instr *instr) -{ - int opcode = instr->i_opcode; - - return is_jump(instr) || - opcode == RETURN_VALUE || - opcode == RAISE_VARARGS || - opcode == RERAISE; -} - -static int -compiler_use_new_implicit_block_if_needed(struct compiler *c) -{ - if (c->u->u_need_new_implicit_block) { - basicblock *b = compiler_new_block(c); - if (b == NULL) { - return -1; - } - compiler_use_next_block(c, b); - } - return 0; -} - -static void -compiler_check_if_end_of_block(struct compiler *c, struct instr *instr) -{ - if (is_end_of_basic_block(instr)) { - c->u->u_need_new_implicit_block = 1; - } -} - -/* Add an opcode with no argument. - Returns 0 on failure, 1 on success. -*/ - static int -compiler_addop_line(struct compiler *c, int opcode, int line, - int end_line, int col_offset, int end_col_offset) +codegen_addop_noarg(instr_sequence *seq, int opcode, location loc) { - assert(IS_WITHIN_OPCODE_RANGE(opcode)); + assert(!HAS_ARG(opcode)); assert(!IS_ASSEMBLER_OPCODE(opcode)); - assert(!HAS_ARG(opcode) || IS_ARTIFICIAL(opcode)); - - if (compiler_use_new_implicit_block_if_needed(c) < 0) { - return -1; - } - - basicblock *b = c->u->u_curblock; - int off = compiler_next_instr(b); - if (off < 0) { - return 0; - } - struct instr *i = &b->b_instr[off]; - i->i_opcode = opcode; - i->i_oparg = 0; - if (opcode == RETURN_VALUE) { - b->b_return = 1; - } - i->i_lineno = line; - i->i_end_lineno = end_line; - i->i_col_offset = col_offset; - i->i_end_col_offset = end_col_offset; - - compiler_check_if_end_of_block(c, i); - return 1; -} - -static int -compiler_addop(struct compiler *c, int opcode) -{ - return compiler_addop_line(c, opcode, c->u->u_lineno, c->u->u_end_lineno, - c->u->u_col_offset, c->u->u_end_col_offset); -} - -static int -compiler_addop_noline(struct compiler *c, int opcode) -{ - return compiler_addop_line(c, opcode, -1, 0, 0, 0); + return instr_sequence_addop(seq, opcode, 0, loc); } - static Py_ssize_t -compiler_add_o(PyObject *dict, PyObject *o) +dict_add_o(PyObject *dict, PyObject *o) { PyObject *v; Py_ssize_t arg; @@ -1298,16 +905,16 @@ compiler_add_o(PyObject *dict, PyObject *o) v = PyDict_GetItemWithError(dict, o); if (!v) { if (PyErr_Occurred()) { - return -1; + return ERROR; } arg = PyDict_GET_SIZE(dict); v = PyLong_FromSsize_t(arg); if (!v) { - return -1; + return ERROR; } if (PyDict_SetItem(dict, o, v) < 0) { Py_DECREF(v); - return -1; + return ERROR; } Py_DECREF(v); } @@ -1318,13 +925,13 @@ compiler_add_o(PyObject *dict, PyObject *o) // Merge const *o* recursively and return constant key object. static PyObject* -merge_consts_recursive(struct compiler *c, PyObject *o) +merge_consts_recursive(PyObject *const_cache, PyObject *o) { + assert(PyDict_CheckExact(const_cache)); // None and Ellipsis are singleton, and key is the singleton. // No need to merge object and key. if (o == Py_None || o == Py_Ellipsis) { - Py_INCREF(o); - return o; + return Py_NewRef(o); } PyObject *key = _PyCode_ConstantKey(o); @@ -1333,22 +940,22 @@ merge_consts_recursive(struct compiler *c, PyObject *o) } // t is borrowed reference - PyObject *t = PyDict_SetDefault(c->c_const_cache, key, key); + PyObject *t = PyDict_SetDefault(const_cache, key, key); if (t != key) { - // o is registered in c_const_cache. Just use it. + // o is registered in const_cache. Just use it. Py_XINCREF(t); Py_DECREF(key); return t; } - // We registered o in c_const_cache. + // We registered o in const_cache. // When o is a tuple or frozenset, we want to merge its // items too. if (PyTuple_CheckExact(o)) { Py_ssize_t len = PyTuple_GET_SIZE(o); for (Py_ssize_t i = 0; i < len; i++) { PyObject *item = PyTuple_GET_ITEM(o, i); - PyObject *u = merge_consts_recursive(c, item); + PyObject *u = merge_consts_recursive(const_cache, item); if (u == NULL) { Py_DECREF(key); return NULL; @@ -1363,8 +970,7 @@ merge_consts_recursive(struct compiler *c, PyObject *o) v = u; } if (v != item) { - Py_INCREF(v); - PyTuple_SET_ITEM(o, i, v); + PyTuple_SET_ITEM(o, i, Py_NewRef(v)); Py_DECREF(item); } @@ -1391,7 +997,7 @@ merge_consts_recursive(struct compiler *c, PyObject *o) PyObject *item; Py_hash_t hash; while (_PySet_NextEntry(o, &pos, &item, &hash)) { - PyObject *k = merge_consts_recursive(c, item); + PyObject *k = merge_consts_recursive(const_cache, item); if (k == NULL) { Py_DECREF(tuple); Py_DECREF(key); @@ -1399,8 +1005,7 @@ merge_consts_recursive(struct compiler *c, PyObject *o) } PyObject *u; if (PyTuple_CheckExact(k)) { - u = PyTuple_GET_ITEM(k, 1); - Py_INCREF(u); + u = Py_NewRef(PyTuple_GET_ITEM(k, 1)); Py_DECREF(k); } else { @@ -1427,61 +1032,85 @@ merge_consts_recursive(struct compiler *c, PyObject *o) } static Py_ssize_t -compiler_add_const(struct compiler *c, PyObject *o) +compiler_add_const(PyObject *const_cache, struct compiler_unit *u, PyObject *o) { - PyObject *key = merge_consts_recursive(c, o); + assert(PyDict_CheckExact(const_cache)); + PyObject *key = merge_consts_recursive(const_cache, o); if (key == NULL) { - return -1; + return ERROR; } - Py_ssize_t arg = compiler_add_o(c->u->u_consts, key); + Py_ssize_t arg = dict_add_o(u->u_metadata.u_consts, key); Py_DECREF(key); return arg; } static int -compiler_addop_load_const(struct compiler *c, PyObject *o) +compiler_addop_load_const(PyObject *const_cache, struct compiler_unit *u, location loc, PyObject *o) { - Py_ssize_t arg = compiler_add_const(c, o); - if (arg < 0) - return 0; - return compiler_addop_i(c, LOAD_CONST, arg); + Py_ssize_t arg = compiler_add_const(const_cache, u, o); + if (arg < 0) { + return ERROR; + } + return codegen_addop_i(&u->u_instr_sequence, LOAD_CONST, arg, loc); } static int -compiler_addop_o(struct compiler *c, int opcode, PyObject *dict, - PyObject *o) +compiler_addop_o(struct compiler_unit *u, location loc, + int opcode, PyObject *dict, PyObject *o) { - Py_ssize_t arg = compiler_add_o(dict, o); - if (arg < 0) - return 0; - return compiler_addop_i(c, opcode, arg); + Py_ssize_t arg = dict_add_o(dict, o); + if (arg < 0) { + return ERROR; + } + return codegen_addop_i(&u->u_instr_sequence, opcode, arg, loc); } static int -compiler_addop_name(struct compiler *c, int opcode, PyObject *dict, - PyObject *o) +compiler_addop_name(struct compiler_unit *u, location loc, + int opcode, PyObject *dict, PyObject *o) { - Py_ssize_t arg; - - PyObject *mangled = _Py_Mangle(c->u->u_private, o); - if (!mangled) - return 0; - arg = compiler_add_o(dict, mangled); + PyObject *mangled = _Py_Mangle(u->u_private, o); + if (!mangled) { + return ERROR; + } + Py_ssize_t arg = dict_add_o(dict, mangled); Py_DECREF(mangled); - if (arg < 0) - return 0; - return compiler_addop_i(c, opcode, arg); + if (arg < 0) { + return ERROR; + } + if (opcode == LOAD_ATTR) { + arg <<= 1; + } + if (opcode == LOAD_METHOD) { + opcode = LOAD_ATTR; + arg <<= 1; + arg |= 1; + } + if (opcode == LOAD_SUPER_ATTR) { + arg <<= 2; + arg |= 2; + } + if (opcode == LOAD_SUPER_METHOD) { + opcode = LOAD_SUPER_ATTR; + arg <<= 2; + arg |= 3; + } + if (opcode == LOAD_ZERO_SUPER_ATTR) { + opcode = LOAD_SUPER_ATTR; + arg <<= 2; + } + if (opcode == LOAD_ZERO_SUPER_METHOD) { + opcode = LOAD_SUPER_ATTR; + arg <<= 2; + arg |= 1; + } + return codegen_addop_i(&u->u_instr_sequence, opcode, arg, loc); } -/* Add an opcode with an integer argument. - Returns 0 on failure, 1 on success. -*/ - +/* Add an opcode with an integer argument */ static int -compiler_addop_i_line(struct compiler *c, int opcode, Py_ssize_t oparg, - int lineno, int end_lineno, - int col_offset, int end_col_offset) +codegen_addop_i(instr_sequence *seq, int opcode, Py_ssize_t oparg, location loc) { /* oparg value is unsigned, but a signed C int is usually used to store it in the C code (like Python/ceval.c). @@ -1491,206 +1120,101 @@ compiler_addop_i_line(struct compiler *c, int opcode, Py_ssize_t oparg, The argument of a concrete bytecode instruction is limited to 8-bit. EXTENDED_ARG is used for 16, 24, and 32-bit arguments. */ - assert(IS_WITHIN_OPCODE_RANGE(opcode)); + int oparg_ = Py_SAFE_DOWNCAST(oparg, Py_ssize_t, int); assert(!IS_ASSEMBLER_OPCODE(opcode)); - assert(HAS_ARG(opcode)); - assert(0 <= oparg && oparg <= 2147483647); - - if (compiler_use_new_implicit_block_if_needed(c) < 0) { - return -1; - } - - basicblock *b = c->u->u_curblock; - int off = compiler_next_instr(b); - if (off < 0) { - return 0; - } - struct instr *i = &b->b_instr[off]; - i->i_opcode = opcode; - i->i_oparg = Py_SAFE_DOWNCAST(oparg, Py_ssize_t, int); - i->i_lineno = lineno; - i->i_end_lineno = end_lineno; - i->i_col_offset = col_offset; - i->i_end_col_offset = end_col_offset; - - compiler_check_if_end_of_block(c, i); - return 1; -} - -static int -compiler_addop_i(struct compiler *c, int opcode, Py_ssize_t oparg) -{ - return compiler_addop_i_line(c, opcode, oparg, - c->u->u_lineno, c->u->u_end_lineno, - c->u->u_col_offset, c->u->u_end_col_offset); + return instr_sequence_addop(seq, opcode, oparg_, loc); } static int -compiler_addop_i_noline(struct compiler *c, int opcode, Py_ssize_t oparg) -{ - return compiler_addop_i_line(c, opcode, oparg, -1, 0, 0, 0); -} - -static int add_jump_to_block(struct compiler *c, int opcode, - int lineno, int end_lineno, - int col_offset, int end_col_offset, - basicblock *target) +codegen_addop_j(instr_sequence *seq, location loc, + int opcode, jump_target_label target) { - assert(IS_WITHIN_OPCODE_RANGE(opcode)); + assert(IS_LABEL(target)); + assert(IS_JUMP_OPCODE(opcode) || IS_BLOCK_PUSH_OPCODE(opcode)); assert(!IS_ASSEMBLER_OPCODE(opcode)); - assert(HAS_ARG(opcode) || IS_VIRTUAL_OPCODE(opcode)); - assert(target != NULL); - - if (compiler_use_new_implicit_block_if_needed(c) < 0) { - return -1; - } - - basicblock *b = c->u->u_curblock; - int off = compiler_next_instr(b); - struct instr *i = &b->b_instr[off]; - if (off < 0) { - return 0; - } - i->i_opcode = opcode; - i->i_target = target; - i->i_lineno = lineno; - i->i_end_lineno = end_lineno; - i->i_col_offset = col_offset; - i->i_end_col_offset = end_col_offset; - - compiler_check_if_end_of_block(c, i); - return 1; -} - -static int -compiler_addop_j(struct compiler *c, int opcode, basicblock *b) -{ - return add_jump_to_block(c, opcode, c->u->u_lineno, - c->u->u_end_lineno, c->u->u_col_offset, - c->u->u_end_col_offset, b); -} - -static int -compiler_addop_j_noline(struct compiler *c, int opcode, basicblock *b) -{ - return add_jump_to_block(c, opcode, -1, 0, 0, 0, b); + return instr_sequence_addop(seq, opcode, target.id, loc); } -#define ADDOP(C, OP) { \ - if (!compiler_addop((C), (OP))) \ - return 0; \ +#define RETURN_IF_ERROR_IN_SCOPE(C, CALL) { \ + if ((CALL) < 0) { \ + compiler_exit_scope((C)); \ + return ERROR; \ + } \ } -#define ADDOP_NOLINE(C, OP) { \ - if (!compiler_addop_noline((C), (OP))) \ - return 0; \ -} +#define ADDOP(C, LOC, OP) \ + RETURN_IF_ERROR(codegen_addop_noarg(INSTR_SEQUENCE(C), (OP), (LOC))) -#define ADDOP_IN_SCOPE(C, OP) { \ - if (!compiler_addop((C), (OP))) { \ - compiler_exit_scope(c); \ - return 0; \ - } \ -} +#define ADDOP_IN_SCOPE(C, LOC, OP) RETURN_IF_ERROR_IN_SCOPE((C), codegen_addop_noarg(INSTR_SEQUENCE(C), (OP), (LOC))) -#define ADDOP_LOAD_CONST(C, O) { \ - if (!compiler_addop_load_const((C), (O))) \ - return 0; \ -} +#define ADDOP_LOAD_CONST(C, LOC, O) \ + RETURN_IF_ERROR(compiler_addop_load_const((C)->c_const_cache, (C)->u, (LOC), (O))) /* Same as ADDOP_LOAD_CONST, but steals a reference. */ -#define ADDOP_LOAD_CONST_NEW(C, O) { \ +#define ADDOP_LOAD_CONST_NEW(C, LOC, O) { \ PyObject *__new_const = (O); \ if (__new_const == NULL) { \ - return 0; \ + return ERROR; \ } \ - if (!compiler_addop_load_const((C), __new_const)) { \ + if (compiler_addop_load_const((C)->c_const_cache, (C)->u, (LOC), __new_const) < 0) { \ Py_DECREF(__new_const); \ - return 0; \ + return ERROR; \ } \ Py_DECREF(__new_const); \ } -#define ADDOP_N(C, OP, O, TYPE) { \ +#define ADDOP_N(C, LOC, OP, O, TYPE) { \ assert(!HAS_CONST(OP)); /* use ADDOP_LOAD_CONST_NEW */ \ - if (!compiler_addop_o((C), (OP), (C)->u->u_ ## TYPE, (O))) { \ + if (compiler_addop_o((C)->u, (LOC), (OP), (C)->u->u_metadata.u_ ## TYPE, (O)) < 0) { \ Py_DECREF((O)); \ - return 0; \ + return ERROR; \ } \ Py_DECREF((O)); \ } -#define ADDOP_NAME(C, OP, O, TYPE) { \ - if (!compiler_addop_name((C), (OP), (C)->u->u_ ## TYPE, (O))) \ - return 0; \ -} +#define ADDOP_NAME(C, LOC, OP, O, TYPE) \ + RETURN_IF_ERROR(compiler_addop_name((C)->u, (LOC), (OP), (C)->u->u_metadata.u_ ## TYPE, (O))) -#define ADDOP_I(C, OP, O) { \ - if (!compiler_addop_i((C), (OP), (O))) \ - return 0; \ -} +#define ADDOP_I(C, LOC, OP, O) \ + RETURN_IF_ERROR(codegen_addop_i(INSTR_SEQUENCE(C), (OP), (O), (LOC))) -#define ADDOP_I_NOLINE(C, OP, O) { \ - if (!compiler_addop_i_noline((C), (OP), (O))) \ - return 0; \ -} +#define ADDOP_JUMP(C, LOC, OP, O) \ + RETURN_IF_ERROR(codegen_addop_j(INSTR_SEQUENCE(C), (LOC), (OP), (O))) -#define ADDOP_JUMP(C, OP, O) { \ - if (!compiler_addop_j((C), (OP), (O))) \ - return 0; \ -} +#define ADDOP_COMPARE(C, LOC, CMP) \ + RETURN_IF_ERROR(compiler_addcompare((C), (LOC), (cmpop_ty)(CMP))) -/* Add a jump with no line number. - * Used for artificial jumps that have no corresponding - * token in the source code. */ -#define ADDOP_JUMP_NOLINE(C, OP, O) { \ - if (!compiler_addop_j_noline((C), (OP), (O))) \ - return 0; \ -} +#define ADDOP_BINARY(C, LOC, BINOP) \ + RETURN_IF_ERROR(addop_binary((C), (LOC), (BINOP), false)) -#define ADDOP_COMPARE(C, CMP) { \ - if (!compiler_addcompare((C), (cmpop_ty)(CMP))) \ - return 0; \ -} +#define ADDOP_INPLACE(C, LOC, BINOP) \ + RETURN_IF_ERROR(addop_binary((C), (LOC), (BINOP), true)) + +#define ADD_YIELD_FROM(C, LOC, await) \ + RETURN_IF_ERROR(compiler_add_yield_from((C), (LOC), (await))) -#define ADDOP_BINARY(C, BINOP) \ - RETURN_IF_FALSE(addop_binary((C), (BINOP), false)) +#define POP_EXCEPT_AND_RERAISE(C, LOC) \ + RETURN_IF_ERROR(compiler_pop_except_and_reraise((C), (LOC))) -#define ADDOP_INPLACE(C, BINOP) \ - RETURN_IF_FALSE(addop_binary((C), (BINOP), true)) +#define ADDOP_YIELD(C, LOC) \ + RETURN_IF_ERROR(addop_yield((C), (LOC))) /* VISIT and VISIT_SEQ takes an ASDL type as their second argument. They use the ASDL name to synthesize the name of the C type and the visit function. */ -#define ADD_YIELD_FROM(C, await) \ - RETURN_IF_FALSE(compiler_add_yield_from((C), (await))) - -#define POP_EXCEPT_AND_RERAISE(C) \ - RETURN_IF_FALSE(compiler_pop_except_and_reraise((C))) - -#define ADDOP_YIELD(C) \ - RETURN_IF_FALSE(addop_yield(C)) - -#define VISIT(C, TYPE, V) {\ - if (!compiler_visit_ ## TYPE((C), (V))) \ - return 0; \ -} +#define VISIT(C, TYPE, V) \ + RETURN_IF_ERROR(compiler_visit_ ## TYPE((C), (V))); -#define VISIT_IN_SCOPE(C, TYPE, V) {\ - if (!compiler_visit_ ## TYPE((C), (V))) { \ - compiler_exit_scope(c); \ - return 0; \ - } \ -} +#define VISIT_IN_SCOPE(C, TYPE, V) \ + RETURN_IF_ERROR_IN_SCOPE((C), compiler_visit_ ## TYPE((C), (V))) #define VISIT_SEQ(C, TYPE, SEQ) { \ int _i; \ asdl_ ## TYPE ## _seq *seq = (SEQ); /* avoid variable capture */ \ for (_i = 0; _i < asdl_seq_LEN(seq); _i++) { \ TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, _i); \ - if (!compiler_visit_ ## TYPE((C), elt)) \ - return 0; \ + RETURN_IF_ERROR(compiler_visit_ ## TYPE((C), elt)); \ } \ } @@ -1699,84 +1223,94 @@ compiler_addop_j_noline(struct compiler *c, int opcode, basicblock *b) asdl_ ## TYPE ## _seq *seq = (SEQ); /* avoid variable capture */ \ for (_i = 0; _i < asdl_seq_LEN(seq); _i++) { \ TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, _i); \ - if (!compiler_visit_ ## TYPE((C), elt)) { \ - compiler_exit_scope(c); \ - return 0; \ + if (compiler_visit_ ## TYPE((C), elt) < 0) { \ + compiler_exit_scope(C); \ + return ERROR; \ } \ } \ } -#define RETURN_IF_FALSE(X) \ - if (!(X)) { \ - return 0; \ - } static int compiler_enter_scope(struct compiler *c, identifier name, int scope_type, void *key, int lineno) { + location loc = LOCATION(lineno, lineno, 0, 0); + struct compiler_unit *u; - basicblock *block; u = (struct compiler_unit *)PyObject_Calloc(1, sizeof( struct compiler_unit)); if (!u) { PyErr_NoMemory(); - return 0; + return ERROR; } u->u_scope_type = scope_type; - u->u_argcount = 0; - u->u_posonlyargcount = 0; - u->u_kwonlyargcount = 0; + u->u_metadata.u_argcount = 0; + u->u_metadata.u_posonlyargcount = 0; + u->u_metadata.u_kwonlyargcount = 0; u->u_ste = PySymtable_Lookup(c->c_st, key); if (!u->u_ste) { compiler_unit_free(u); - return 0; + return ERROR; } - Py_INCREF(name); - u->u_name = name; - u->u_varnames = list2dict(u->u_ste->ste_varnames); - u->u_cellvars = dictbytype(u->u_ste->ste_symbols, CELL, 0, 0); - if (!u->u_varnames || !u->u_cellvars) { + u->u_metadata.u_name = Py_NewRef(name); + u->u_metadata.u_varnames = list2dict(u->u_ste->ste_varnames); + if (!u->u_metadata.u_varnames) { compiler_unit_free(u); - return 0; + return ERROR; + } + u->u_metadata.u_cellvars = dictbytype(u->u_ste->ste_symbols, CELL, DEF_COMP_CELL, 0); + if (!u->u_metadata.u_cellvars) { + compiler_unit_free(u); + return ERROR; } if (u->u_ste->ste_needs_class_closure) { /* Cook up an implicit __class__ cell. */ - int res; + Py_ssize_t res; assert(u->u_scope_type == COMPILER_SCOPE_CLASS); - assert(PyDict_GET_SIZE(u->u_cellvars) == 0); - res = PyDict_SetItem(u->u_cellvars, &_Py_ID(__class__), - _PyLong_GetZero()); + res = dict_add_o(u->u_metadata.u_cellvars, &_Py_ID(__class__)); if (res < 0) { compiler_unit_free(u); - return 0; + return ERROR; + } + } + if (u->u_ste->ste_needs_classdict) { + /* Cook up an implicit __classdict__ cell. */ + Py_ssize_t res; + assert(u->u_scope_type == COMPILER_SCOPE_CLASS); + res = dict_add_o(u->u_metadata.u_cellvars, &_Py_ID(__classdict__)); + if (res < 0) { + compiler_unit_free(u); + return ERROR; } } - u->u_freevars = dictbytype(u->u_ste->ste_symbols, FREE, DEF_FREE_CLASS, - PyDict_GET_SIZE(u->u_cellvars)); - if (!u->u_freevars) { + u->u_metadata.u_freevars = dictbytype(u->u_ste->ste_symbols, FREE, DEF_FREE_CLASS, + PyDict_GET_SIZE(u->u_metadata.u_cellvars)); + if (!u->u_metadata.u_freevars) { compiler_unit_free(u); - return 0; + return ERROR; + } + + u->u_metadata.u_fasthidden = PyDict_New(); + if (!u->u_metadata.u_fasthidden) { + compiler_unit_free(u); + return ERROR; } - u->u_blocks = NULL; u->u_nfblocks = 0; - u->u_firstlineno = lineno; - u->u_lineno = lineno; - u->u_col_offset = 0; - u->u_end_lineno = lineno; - u->u_end_col_offset = 0; - u->u_consts = PyDict_New(); - if (!u->u_consts) { + u->u_in_inlined_comp = 0; + u->u_metadata.u_firstlineno = lineno; + u->u_metadata.u_consts = PyDict_New(); + if (!u->u_metadata.u_consts) { compiler_unit_free(u); - return 0; + return ERROR; } - u->u_names = PyDict_New(); - if (!u->u_names) { + u->u_metadata.u_names = PyDict_New(); + if (!u->u_metadata.u_names) { compiler_unit_free(u); - return 0; + return ERROR; } u->u_private = NULL; @@ -1787,42 +1321,34 @@ compiler_enter_scope(struct compiler *c, identifier name, if (!capsule || PyList_Append(c->c_stack, capsule) < 0) { Py_XDECREF(capsule); compiler_unit_free(u); - return 0; + return ERROR; } Py_DECREF(capsule); - u->u_private = c->u->u_private; - Py_XINCREF(u->u_private); + u->u_private = Py_XNewRef(c->u->u_private); } c->u = u; c->c_nestlevel++; - block = compiler_new_block(c); - if (block == NULL) - return 0; - c->u->u_curblock = block; - if (u->u_scope_type == COMPILER_SCOPE_MODULE) { - c->u->u_lineno = 0; + loc.lineno = 0; } else { - if (!compiler_set_qualname(c)) - return 0; + RETURN_IF_ERROR(compiler_set_qualname(c)); } - ADDOP_I(c, RESUME, 0); + ADDOP_I(c, loc, RESUME, 0); if (u->u_scope_type == COMPILER_SCOPE_MODULE) { - c->u->u_lineno = -1; + loc.lineno = -1; } - return 1; + return SUCCESS; } static void compiler_exit_scope(struct compiler *c) { // Don't call PySequence_DelItem() with an exception raised - PyObject *exc_type, *exc_val, *exc_tb; - PyErr_Fetch(&exc_type, &exc_val, &exc_tb); + PyObject *exc = PyErr_GetRaisedException(); c->c_nestlevel--; compiler_unit_free(c->u); @@ -1837,18 +1363,17 @@ compiler_exit_scope(struct compiler *c) _PyErr_WriteUnraisableMsg("on removing the last compiler " "stack item", NULL); } - compiler_unit_check(c->u); } else { c->u = NULL; } - PyErr_Restore(exc_type, exc_val, exc_tb); + PyErr_SetRaisedException(exc); } /* Search if variable annotations are present statically in a block. */ -static int +static bool find_ann(asdl_stmt_seq *stmts) { int i, j, res = 0; @@ -1858,7 +1383,7 @@ find_ann(asdl_stmt_seq *stmts) st = (stmt_ty)asdl_seq_GET(stmts, i); switch (st->kind) { case AnnAssign_kind: - return 1; + return true; case For_kind: res = find_ann(st->v.For.body) || find_ann(st->v.For.orelse); @@ -1886,7 +1411,7 @@ find_ann(asdl_stmt_seq *stmts) excepthandler_ty handler = (excepthandler_ty)asdl_seq_GET( st->v.Try.handlers, j); if (find_ann(handler->v.ExceptHandler.body)) { - return 1; + return true; } } res = find_ann(st->v.Try.body) || @@ -1898,15 +1423,25 @@ find_ann(asdl_stmt_seq *stmts) excepthandler_ty handler = (excepthandler_ty)asdl_seq_GET( st->v.TryStar.handlers, j); if (find_ann(handler->v.ExceptHandler.body)) { - return 1; + return true; } } res = find_ann(st->v.TryStar.body) || find_ann(st->v.TryStar.finalbody) || find_ann(st->v.TryStar.orelse); break; + case Match_kind: + for (j = 0; j < asdl_seq_LEN(st->v.Match.cases); j++) { + match_case_ty match_case = (match_case_ty)asdl_seq_GET( + st->v.Match.cases, j); + if (find_ann(match_case->body)) { + return true; + } + } + break; default: - res = 0; + res = false; + break; } if (res) { break; @@ -1920,63 +1455,69 @@ find_ann(asdl_stmt_seq *stmts) */ static int -compiler_push_fblock(struct compiler *c, enum fblocktype t, basicblock *b, - basicblock *exit, void *datum) +compiler_push_fblock(struct compiler *c, location loc, + enum fblocktype t, jump_target_label block_label, + jump_target_label exit, void *datum) { struct fblockinfo *f; if (c->u->u_nfblocks >= CO_MAXBLOCKS) { - return compiler_error(c, "too many statically nested blocks"); + return compiler_error(c, loc, "too many statically nested blocks"); } f = &c->u->u_fblock[c->u->u_nfblocks++]; f->fb_type = t; - f->fb_block = b; + f->fb_block = block_label; f->fb_exit = exit; f->fb_datum = datum; - return 1; + return SUCCESS; } static void -compiler_pop_fblock(struct compiler *c, enum fblocktype t, basicblock *b) +compiler_pop_fblock(struct compiler *c, enum fblocktype t, jump_target_label block_label) { struct compiler_unit *u = c->u; assert(u->u_nfblocks > 0); u->u_nfblocks--; assert(u->u_fblock[u->u_nfblocks].fb_type == t); - assert(u->u_fblock[u->u_nfblocks].fb_block == b); + assert(SAME_LABEL(u->u_fblock[u->u_nfblocks].fb_block, block_label)); } static int -compiler_call_exit_with_nones(struct compiler *c) { - ADDOP_LOAD_CONST(c, Py_None); - ADDOP_LOAD_CONST(c, Py_None); - ADDOP_LOAD_CONST(c, Py_None); - ADDOP_I(c, PRECALL, 2); - ADDOP_I(c, CALL, 2); - return 1; +compiler_call_exit_with_nones(struct compiler *c, location loc) +{ + ADDOP_LOAD_CONST(c, loc, Py_None); + ADDOP_LOAD_CONST(c, loc, Py_None); + ADDOP_LOAD_CONST(c, loc, Py_None); + ADDOP_I(c, loc, CALL, 2); + return SUCCESS; } static int -compiler_add_yield_from(struct compiler *c, int await) +compiler_add_yield_from(struct compiler *c, location loc, int await) { - basicblock *start, *resume, *exit; - start = compiler_new_block(c); - resume = compiler_new_block(c); - exit = compiler_new_block(c); - if (start == NULL || resume == NULL || exit == NULL) { - return 0; - } - compiler_use_next_block(c, start); - ADDOP_JUMP(c, SEND, exit); - compiler_use_next_block(c, resume); - ADDOP(c, YIELD_VALUE); - ADDOP_I(c, RESUME, await ? 3 : 2); - ADDOP_JUMP(c, JUMP_NO_INTERRUPT, start); - compiler_use_next_block(c, exit); - return 1; + NEW_JUMP_TARGET_LABEL(c, send); + NEW_JUMP_TARGET_LABEL(c, fail); + NEW_JUMP_TARGET_LABEL(c, exit); + + USE_LABEL(c, send); + ADDOP_JUMP(c, loc, SEND, exit); + // Set up a virtual try/except to handle when StopIteration is raised during + // a close or throw call. The only way YIELD_VALUE raises if they do! + ADDOP_JUMP(c, loc, SETUP_FINALLY, fail); + ADDOP_I(c, loc, YIELD_VALUE, 0); + ADDOP(c, NO_LOCATION, POP_BLOCK); + ADDOP_I(c, loc, RESUME, await ? 3 : 2); + ADDOP_JUMP(c, loc, JUMP_NO_INTERRUPT, send); + + USE_LABEL(c, fail); + ADDOP(c, loc, CLEANUP_THROW); + + USE_LABEL(c, exit); + ADDOP(c, loc, END_SEND); + return SUCCESS; } static int -compiler_pop_except_and_reraise(struct compiler *c) +compiler_pop_except_and_reraise(struct compiler *c, location loc) { /* Stack contents * [exc_info, lasti, exc] COPY 3 @@ -1985,10 +1526,10 @@ compiler_pop_except_and_reraise(struct compiler *c) * (exception_unwind clears the stack) */ - ADDOP_I(c, COPY, 3); - ADDOP(c, POP_EXCEPT); - ADDOP_I(c, RERAISE, 1); - return 1; + ADDOP_I(c, loc, COPY, 3); + ADDOP(c, loc, POP_EXCEPT); + ADDOP_I(c, loc, RERAISE, 1); + return SUCCESS; } /* Unwind a frame block. If preserve_tos is true, the TOS before @@ -1997,140 +1538,136 @@ compiler_pop_except_and_reraise(struct compiler *c) * be popped. */ static int -compiler_unwind_fblock(struct compiler *c, struct fblockinfo *info, - int preserve_tos) +compiler_unwind_fblock(struct compiler *c, location *ploc, + struct fblockinfo *info, int preserve_tos) { switch (info->fb_type) { case WHILE_LOOP: case EXCEPTION_HANDLER: case EXCEPTION_GROUP_HANDLER: case ASYNC_COMPREHENSION_GENERATOR: - return 1; + return SUCCESS; case FOR_LOOP: /* Pop the iterator */ if (preserve_tos) { - ADDOP_I(c, SWAP, 2); + ADDOP_I(c, *ploc, SWAP, 2); } - ADDOP(c, POP_TOP); - return 1; + ADDOP(c, *ploc, POP_TOP); + return SUCCESS; case TRY_EXCEPT: - ADDOP(c, POP_BLOCK); - return 1; + ADDOP(c, *ploc, POP_BLOCK); + return SUCCESS; case FINALLY_TRY: /* This POP_BLOCK gets the line number of the unwinding statement */ - ADDOP(c, POP_BLOCK); + ADDOP(c, *ploc, POP_BLOCK); if (preserve_tos) { - if (!compiler_push_fblock(c, POP_VALUE, NULL, NULL, NULL)) { - return 0; - } + RETURN_IF_ERROR( + compiler_push_fblock(c, *ploc, POP_VALUE, NO_LABEL, NO_LABEL, NULL)); } /* Emit the finally block */ VISIT_SEQ(c, stmt, info->fb_datum); if (preserve_tos) { - compiler_pop_fblock(c, POP_VALUE, NULL); + compiler_pop_fblock(c, POP_VALUE, NO_LABEL); } /* The finally block should appear to execute after the * statement causing the unwinding, so make the unwinding * instruction artificial */ - UNSET_LOC(c); - return 1; + *ploc = NO_LOCATION; + return SUCCESS; case FINALLY_END: if (preserve_tos) { - ADDOP_I(c, SWAP, 2); + ADDOP_I(c, *ploc, SWAP, 2); } - ADDOP(c, POP_TOP); /* exc_value */ + ADDOP(c, *ploc, POP_TOP); /* exc_value */ if (preserve_tos) { - ADDOP_I(c, SWAP, 2); + ADDOP_I(c, *ploc, SWAP, 2); } - ADDOP(c, POP_BLOCK); - ADDOP(c, POP_EXCEPT); - return 1; + ADDOP(c, *ploc, POP_BLOCK); + ADDOP(c, *ploc, POP_EXCEPT); + return SUCCESS; case WITH: case ASYNC_WITH: - SET_LOC(c, (stmt_ty)info->fb_datum); - ADDOP(c, POP_BLOCK); + *ploc = LOC((stmt_ty)info->fb_datum); + ADDOP(c, *ploc, POP_BLOCK); if (preserve_tos) { - ADDOP_I(c, SWAP, 2); - } - if(!compiler_call_exit_with_nones(c)) { - return 0; + ADDOP_I(c, *ploc, SWAP, 2); } + RETURN_IF_ERROR(compiler_call_exit_with_nones(c, *ploc)); if (info->fb_type == ASYNC_WITH) { - ADDOP_I(c, GET_AWAITABLE, 2); - ADDOP_LOAD_CONST(c, Py_None); - ADD_YIELD_FROM(c, 1); + ADDOP_I(c, *ploc, GET_AWAITABLE, 2); + ADDOP_LOAD_CONST(c, *ploc, Py_None); + ADD_YIELD_FROM(c, *ploc, 1); } - ADDOP(c, POP_TOP); + ADDOP(c, *ploc, POP_TOP); /* The exit block should appear to execute after the * statement causing the unwinding, so make the unwinding * instruction artificial */ - UNSET_LOC(c); - return 1; + *ploc = NO_LOCATION; + return SUCCESS; - case HANDLER_CLEANUP: + case HANDLER_CLEANUP: { if (info->fb_datum) { - ADDOP(c, POP_BLOCK); + ADDOP(c, *ploc, POP_BLOCK); } if (preserve_tos) { - ADDOP_I(c, SWAP, 2); + ADDOP_I(c, *ploc, SWAP, 2); } - ADDOP(c, POP_BLOCK); - ADDOP(c, POP_EXCEPT); + ADDOP(c, *ploc, POP_BLOCK); + ADDOP(c, *ploc, POP_EXCEPT); if (info->fb_datum) { - ADDOP_LOAD_CONST(c, Py_None); - compiler_nameop(c, info->fb_datum, Store); - compiler_nameop(c, info->fb_datum, Del); + ADDOP_LOAD_CONST(c, *ploc, Py_None); + RETURN_IF_ERROR(compiler_nameop(c, *ploc, info->fb_datum, Store)); + RETURN_IF_ERROR(compiler_nameop(c, *ploc, info->fb_datum, Del)); } - return 1; - - case POP_VALUE: + return SUCCESS; + } + case POP_VALUE: { if (preserve_tos) { - ADDOP_I(c, SWAP, 2); + ADDOP_I(c, *ploc, SWAP, 2); } - ADDOP(c, POP_TOP); - return 1; + ADDOP(c, *ploc, POP_TOP); + return SUCCESS; + } } Py_UNREACHABLE(); } /** Unwind block stack. If loop is not NULL, then stop when the first loop is encountered. */ static int -compiler_unwind_fblock_stack(struct compiler *c, int preserve_tos, struct fblockinfo **loop) { +compiler_unwind_fblock_stack(struct compiler *c, location *ploc, + int preserve_tos, struct fblockinfo **loop) +{ if (c->u->u_nfblocks == 0) { - return 1; + return SUCCESS; } struct fblockinfo *top = &c->u->u_fblock[c->u->u_nfblocks-1]; if (top->fb_type == EXCEPTION_GROUP_HANDLER) { return compiler_error( - c, "'break', 'continue' and 'return' cannot appear in an except* block"); + c, *ploc, "'break', 'continue' and 'return' cannot appear in an except* block"); } if (loop != NULL && (top->fb_type == WHILE_LOOP || top->fb_type == FOR_LOOP)) { *loop = top; - return 1; + return SUCCESS; } struct fblockinfo copy = *top; c->u->u_nfblocks--; - if (!compiler_unwind_fblock(c, ©, preserve_tos)) { - return 0; - } - if (!compiler_unwind_fblock_stack(c, preserve_tos, loop)) { - return 0; - } + RETURN_IF_ERROR(compiler_unwind_fblock(c, ploc, ©, preserve_tos)); + RETURN_IF_ERROR(compiler_unwind_fblock_stack(c, ploc, preserve_tos, loop)); c->u->u_fblock[c->u->u_nfblocks] = copy; c->u->u_nfblocks++; - return 1; + return SUCCESS; } /* Compile a sequence of statements, checking for a docstring and for annotations. */ static int -compiler_body(struct compiler *c, asdl_stmt_seq *stmts) +compiler_body(struct compiler *c, location loc, asdl_stmt_seq *stmts) { int i = 0; stmt_ty st; @@ -2139,17 +1676,18 @@ compiler_body(struct compiler *c, asdl_stmt_seq *stmts) /* Set current line number to the line number of first statement. This way line number for SETUP_ANNOTATIONS will always coincide with the line number of first "real" statement in module. - If body is empty, then lineno will be set later in assemble. */ + If body is empty, then lineno will be set later in optimize_and_assemble. */ if (c->u->u_scope_type == COMPILER_SCOPE_MODULE && asdl_seq_LEN(stmts)) { st = (stmt_ty)asdl_seq_GET(stmts, 0); - SET_LOC(c, st); + loc = LOC(st); } /* Every annotated class and module should have __annotations__. */ if (find_ann(stmts)) { - ADDOP(c, SETUP_ANNOTATIONS); + ADDOP(c, loc, SETUP_ANNOTATIONS); + } + if (!asdl_seq_LEN(stmts)) { + return SUCCESS; } - if (!asdl_seq_LEN(stmts)) - return 1; /* if not -OO mode, set docstring */ if (c->c_optimize < 2) { docstring = _PyAST_GetDocString(stmts); @@ -2158,52 +1696,58 @@ compiler_body(struct compiler *c, asdl_stmt_seq *stmts) st = (stmt_ty)asdl_seq_GET(stmts, 0); assert(st->kind == Expr_kind); VISIT(c, expr, st->v.Expr.value); - UNSET_LOC(c); - if (!compiler_nameop(c, &_Py_ID(__doc__), Store)) - return 0; + RETURN_IF_ERROR(compiler_nameop(c, NO_LOCATION, &_Py_ID(__doc__), Store)); } } - for (; i < asdl_seq_LEN(stmts); i++) + for (; i < asdl_seq_LEN(stmts); i++) { VISIT(c, stmt, (stmt_ty)asdl_seq_GET(stmts, i)); - return 1; + } + return SUCCESS; } -static PyCodeObject * -compiler_mod(struct compiler *c, mod_ty mod) +static int +compiler_codegen(struct compiler *c, mod_ty mod) { - PyCodeObject *co; - int addNone = 1; _Py_DECLARE_STR(anon_module, "<module>"); - if (!compiler_enter_scope(c, &_Py_STR(anon_module), COMPILER_SCOPE_MODULE, - mod, 1)) { - return NULL; - } - c->u->u_lineno = 1; + RETURN_IF_ERROR( + compiler_enter_scope(c, &_Py_STR(anon_module), COMPILER_SCOPE_MODULE, + mod, 1)); + + location loc = LOCATION(1, 1, 0, 0); switch (mod->kind) { case Module_kind: - if (!compiler_body(c, mod->v.Module.body)) { + if (compiler_body(c, loc, mod->v.Module.body) < 0) { compiler_exit_scope(c); - return 0; + return ERROR; } break; case Interactive_kind: if (find_ann(mod->v.Interactive.body)) { - ADDOP(c, SETUP_ANNOTATIONS); + ADDOP(c, loc, SETUP_ANNOTATIONS); } c->c_interactive = 1; VISIT_SEQ_IN_SCOPE(c, stmt, mod->v.Interactive.body); break; case Expression_kind: VISIT_IN_SCOPE(c, expr, mod->v.Expression.body); - addNone = 0; break; default: PyErr_Format(PyExc_SystemError, "module kind %d should not be possible", mod->kind); - return 0; + return ERROR; } - co = assemble(c, addNone); + return SUCCESS; +} + +static PyCodeObject * +compiler_mod(struct compiler *c, mod_ty mod) +{ + int addNone = mod->kind != Expression_kind; + if (compiler_codegen(c, mod) < 0) { + return NULL; + } + PyCodeObject *co = optimize_and_assemble(c, addNone); compiler_exit_scope(c); return co; } @@ -2218,8 +1762,10 @@ get_ref_type(struct compiler *c, PyObject *name) { int scope; if (c->u->u_scope_type == COMPILER_SCOPE_CLASS && - _PyUnicode_EqualToASCIIString(name, "__class__")) + (_PyUnicode_EqualToASCIIString(name, "__class__") || + _PyUnicode_EqualToASCIIString(name, "__classdict__"))) { return CELL; + } scope = _PyST_GetScope(c->u->u_ste, name); if (scope == 0) { PyErr_Format(PyExc_SystemError, @@ -2227,9 +1773,9 @@ get_ref_type(struct compiler *c, PyObject *name) "unknown scope in unit %S (%R); " "symbols: %R; locals: %R; globals: %R", name, - c->u->u_name, c->u->u_ste->ste_id, - c->u->u_ste->ste_symbols, c->u->u_varnames, c->u->u_names); - return -1; + c->u->u_metadata.u_name, c->u->u_ste->ste_id, + c->u->u_ste->ste_symbols, c->u->u_metadata.u_varnames, c->u->u_metadata.u_names); + return ERROR; } return scope; } @@ -2237,22 +1783,19 @@ get_ref_type(struct compiler *c, PyObject *name) static int compiler_lookup_arg(PyObject *dict, PyObject *name) { - PyObject *v; - v = PyDict_GetItemWithError(dict, name); - if (v == NULL) - return -1; + PyObject *v = PyDict_GetItemWithError(dict, name); + if (v == NULL) { + return ERROR; + } return PyLong_AS_LONG(v); } static int -compiler_make_closure(struct compiler *c, PyCodeObject *co, Py_ssize_t flags, - PyObject *qualname) +compiler_make_closure(struct compiler *c, location loc, + PyCodeObject *co, Py_ssize_t flags) { - if (qualname == NULL) - qualname = co->co_name; - if (co->co_nfreevars) { - int i = co->co_nlocals + co->co_nplaincellvars; + int i = PyCode_GetFirstFree(co); for (; i < co->co_nlocalsplus; ++i) { /* Bypass com_addop_varname because it will generate LOAD_DEREF but LOAD_CLOSURE is needed. @@ -2267,14 +1810,14 @@ compiler_make_closure(struct compiler *c, PyCodeObject *co, Py_ssize_t flags, */ int reftype = get_ref_type(c, name); if (reftype == -1) { - return 0; + return ERROR; } int arg; if (reftype == CELL) { - arg = compiler_lookup_arg(c->u->u_cellvars, name); + arg = compiler_lookup_arg(c->u->u_metadata.u_cellvars, name); } else { - arg = compiler_lookup_arg(c->u->u_freevars, name); + arg = compiler_lookup_arg(c->u->u_metadata.u_freevars, name); } if (arg == -1) { PyObject *freevars = _PyCode_GetFreevars(co); @@ -2286,65 +1829,56 @@ compiler_make_closure(struct compiler *c, PyCodeObject *co, Py_ssize_t flags, "freevars of code %S: %R", name, reftype, - c->u->u_name, + c->u->u_metadata.u_name, co->co_name, freevars); Py_DECREF(freevars); - return 0; + return ERROR; } - ADDOP_I(c, LOAD_CLOSURE, arg); + ADDOP_I(c, loc, LOAD_CLOSURE, arg); } flags |= 0x08; - ADDOP_I(c, BUILD_TUPLE, co->co_nfreevars); + ADDOP_I(c, loc, BUILD_TUPLE, co->co_nfreevars); } - ADDOP_LOAD_CONST(c, (PyObject*)co); - ADDOP_I(c, MAKE_FUNCTION, flags); - return 1; + ADDOP_LOAD_CONST(c, loc, (PyObject*)co); + ADDOP_I(c, loc, MAKE_FUNCTION, flags); + return SUCCESS; } static int compiler_decorators(struct compiler *c, asdl_expr_seq* decos) { - int i; - - if (!decos) - return 1; + if (!decos) { + return SUCCESS; + } - for (i = 0; i < asdl_seq_LEN(decos); i++) { + for (Py_ssize_t i = 0; i < asdl_seq_LEN(decos); i++) { VISIT(c, expr, (expr_ty)asdl_seq_GET(decos, i)); } - return 1; + return SUCCESS; } static int compiler_apply_decorators(struct compiler *c, asdl_expr_seq* decos) { - if (!decos) - return 1; + if (!decos) { + return SUCCESS; + } - int old_lineno = c->u->u_lineno; - int old_end_lineno = c->u->u_end_lineno; - int old_col_offset = c->u->u_col_offset; - int old_end_col_offset = c->u->u_end_col_offset; for (Py_ssize_t i = asdl_seq_LEN(decos) - 1; i > -1; i--) { - SET_LOC(c, (expr_ty)asdl_seq_GET(decos, i)); - ADDOP_I(c, PRECALL, 0); - ADDOP_I(c, CALL, 0); - } - c->u->u_lineno = old_lineno; - c->u->u_end_lineno = old_end_lineno; - c->u->u_col_offset = old_col_offset; - c->u->u_end_col_offset = old_end_col_offset; - return 1; + location loc = LOC((expr_ty)asdl_seq_GET(decos, i)); + ADDOP_I(c, loc, CALL, 0); + } + return SUCCESS; } static int -compiler_visit_kwonlydefaults(struct compiler *c, asdl_arg_seq *kwonlyargs, - asdl_expr_seq *kw_defaults) +compiler_visit_kwonlydefaults(struct compiler *c, location loc, + asdl_arg_seq *kwonlyargs, asdl_expr_seq *kw_defaults) { /* Push a dict of keyword-only default values. - Return 0 on error, -1 if no dict pushed, 1 if a dict is pushed. + Return -1 on error, 0 if no dict pushed, 1 if a dict is pushed. */ int i; PyObject *keys = NULL; @@ -2361,7 +1895,7 @@ compiler_visit_kwonlydefaults(struct compiler *c, asdl_arg_seq *kwonlyargs, keys = PyList_New(1); if (keys == NULL) { Py_DECREF(mangled); - return 0; + return ERROR; } PyList_SET_ITEM(keys, 0, mangled); } @@ -2372,7 +1906,7 @@ compiler_visit_kwonlydefaults(struct compiler *c, asdl_arg_seq *kwonlyargs, goto error; } } - if (!compiler_visit_expr(c, default_)) { + if (compiler_visit_expr(c, default_) < 0) { goto error; } } @@ -2381,43 +1915,43 @@ compiler_visit_kwonlydefaults(struct compiler *c, asdl_arg_seq *kwonlyargs, Py_ssize_t default_count = PyList_GET_SIZE(keys); PyObject *keys_tuple = PyList_AsTuple(keys); Py_DECREF(keys); - ADDOP_LOAD_CONST_NEW(c, keys_tuple); - ADDOP_I(c, BUILD_CONST_KEY_MAP, default_count); + ADDOP_LOAD_CONST_NEW(c, loc, keys_tuple); + ADDOP_I(c, loc, BUILD_CONST_KEY_MAP, default_count); assert(default_count > 0); return 1; } else { - return -1; + return 0; } error: Py_XDECREF(keys); - return 0; + return ERROR; } static int compiler_visit_annexpr(struct compiler *c, expr_ty annotation) { - ADDOP_LOAD_CONST_NEW(c, _PyAST_ExprAsUnicode(annotation)); - return 1; + location loc = LOC(annotation); + ADDOP_LOAD_CONST_NEW(c, loc, _PyAST_ExprAsUnicode(annotation)); + return SUCCESS; } static int compiler_visit_argannotation(struct compiler *c, identifier id, - expr_ty annotation, Py_ssize_t *annotations_len) + expr_ty annotation, Py_ssize_t *annotations_len, location loc) { if (!annotation) { - return 1; + return SUCCESS; } - PyObject *mangled = _Py_Mangle(c->u->u_private, id); if (!mangled) { - return 0; + return ERROR; } - ADDOP_LOAD_CONST(c, mangled); + ADDOP_LOAD_CONST(c, loc, mangled); Py_DECREF(mangled); - if (c->c_future->ff_features & CO_FUTURE_ANNOTATIONS) { + if (c->c_future.ff_features & CO_FUTURE_ANNOTATIONS) { VISIT(c, annexpr, annotation); } else { @@ -2427,125 +1961,131 @@ compiler_visit_argannotation(struct compiler *c, identifier id, // (Note that in theory we could end up here even for an argument // other than *args, but in practice the grammar doesn't allow it.) VISIT(c, expr, annotation->v.Starred.value); - ADDOP_I(c, UNPACK_SEQUENCE, (Py_ssize_t) 1); + ADDOP_I(c, loc, UNPACK_SEQUENCE, (Py_ssize_t) 1); } else { VISIT(c, expr, annotation); } } *annotations_len += 2; - return 1; + return SUCCESS; } static int compiler_visit_argannotations(struct compiler *c, asdl_arg_seq* args, - Py_ssize_t *annotations_len) + Py_ssize_t *annotations_len, location loc) { int i; for (i = 0; i < asdl_seq_LEN(args); i++) { arg_ty arg = (arg_ty)asdl_seq_GET(args, i); - if (!compiler_visit_argannotation( + RETURN_IF_ERROR( + compiler_visit_argannotation( c, arg->arg, arg->annotation, - annotations_len)) - return 0; + annotations_len, + loc)); } - return 1; + return SUCCESS; } static int -compiler_visit_annotations(struct compiler *c, arguments_ty args, - expr_ty returns) +compiler_visit_annotations(struct compiler *c, location loc, + arguments_ty args, expr_ty returns) { /* Push arg annotation names and values. The expressions are evaluated out-of-order wrt the source code. - Return 0 on error, -1 if no annotations pushed, 1 if a annotations is pushed. + Return -1 on error, 0 if no annotations pushed, 1 if a annotations is pushed. */ Py_ssize_t annotations_len = 0; - if (!compiler_visit_argannotations(c, args->args, &annotations_len)) - return 0; - if (!compiler_visit_argannotations(c, args->posonlyargs, &annotations_len)) - return 0; - if (args->vararg && args->vararg->annotation && - !compiler_visit_argannotation(c, args->vararg->arg, - args->vararg->annotation, &annotations_len)) - return 0; - if (!compiler_visit_argannotations(c, args->kwonlyargs, &annotations_len)) - return 0; - if (args->kwarg && args->kwarg->annotation && - !compiler_visit_argannotation(c, args->kwarg->arg, - args->kwarg->annotation, &annotations_len)) - return 0; + RETURN_IF_ERROR( + compiler_visit_argannotations(c, args->args, &annotations_len, loc)); - if (!compiler_visit_argannotation(c, &_Py_ID(return), returns, - &annotations_len)) { - return 0; + RETURN_IF_ERROR( + compiler_visit_argannotations(c, args->posonlyargs, &annotations_len, loc)); + + if (args->vararg && args->vararg->annotation) { + RETURN_IF_ERROR( + compiler_visit_argannotation(c, args->vararg->arg, + args->vararg->annotation, &annotations_len, loc)); + } + + RETURN_IF_ERROR( + compiler_visit_argannotations(c, args->kwonlyargs, &annotations_len, loc)); + + if (args->kwarg && args->kwarg->annotation) { + RETURN_IF_ERROR( + compiler_visit_argannotation(c, args->kwarg->arg, + args->kwarg->annotation, &annotations_len, loc)); } + RETURN_IF_ERROR( + compiler_visit_argannotation(c, &_Py_ID(return), returns, &annotations_len, loc)); + if (annotations_len) { - ADDOP_I(c, BUILD_TUPLE, annotations_len); + ADDOP_I(c, loc, BUILD_TUPLE, annotations_len); return 1; } - return -1; + return 0; } static int -compiler_visit_defaults(struct compiler *c, arguments_ty args) +compiler_visit_defaults(struct compiler *c, arguments_ty args, + location loc) { VISIT_SEQ(c, expr, args->defaults); - ADDOP_I(c, BUILD_TUPLE, asdl_seq_LEN(args->defaults)); - return 1; + ADDOP_I(c, loc, BUILD_TUPLE, asdl_seq_LEN(args->defaults)); + return SUCCESS; } static Py_ssize_t -compiler_default_arguments(struct compiler *c, arguments_ty args) +compiler_default_arguments(struct compiler *c, location loc, + arguments_ty args) { Py_ssize_t funcflags = 0; if (args->defaults && asdl_seq_LEN(args->defaults) > 0) { - if (!compiler_visit_defaults(c, args)) - return -1; + RETURN_IF_ERROR(compiler_visit_defaults(c, args, loc)); funcflags |= 0x01; } if (args->kwonlyargs) { - int res = compiler_visit_kwonlydefaults(c, args->kwonlyargs, + int res = compiler_visit_kwonlydefaults(c, loc, + args->kwonlyargs, args->kw_defaults); - if (res == 0) { - return -1; - } - else if (res > 0) { + RETURN_IF_ERROR(res); + if (res > 0) { funcflags |= 0x02; } } return funcflags; } -static int -forbidden_name(struct compiler *c, identifier name, expr_context_ty ctx) +static bool +forbidden_name(struct compiler *c, location loc, identifier name, + expr_context_ty ctx) { - if (ctx == Store && _PyUnicode_EqualToASCIIString(name, "__debug__")) { - compiler_error(c, "cannot assign to __debug__"); - return 1; + compiler_error(c, loc, "cannot assign to __debug__"); + return true; } if (ctx == Del && _PyUnicode_EqualToASCIIString(name, "__debug__")) { - compiler_error(c, "cannot delete __debug__"); - return 1; + compiler_error(c, loc, "cannot delete __debug__"); + return true; } - return 0; + return false; } static int compiler_check_debug_one_arg(struct compiler *c, arg_ty arg) { if (arg != NULL) { - if (forbidden_name(c, arg->arg, Store)) - return 0; + if (forbidden_name(c, LOC(arg), arg->arg, Store)) { + return ERROR; + } } - return 1; + return SUCCESS; } static int @@ -2553,50 +2093,119 @@ compiler_check_debug_args_seq(struct compiler *c, asdl_arg_seq *args) { if (args != NULL) { for (Py_ssize_t i = 0, n = asdl_seq_LEN(args); i < n; i++) { - if (!compiler_check_debug_one_arg(c, asdl_seq_GET(args, i))) - return 0; + RETURN_IF_ERROR( + compiler_check_debug_one_arg(c, asdl_seq_GET(args, i))); } } - return 1; + return SUCCESS; } static int compiler_check_debug_args(struct compiler *c, arguments_ty args) { - if (!compiler_check_debug_args_seq(c, args->posonlyargs)) - return 0; - if (!compiler_check_debug_args_seq(c, args->args)) - return 0; - if (!compiler_check_debug_one_arg(c, args->vararg)) - return 0; - if (!compiler_check_debug_args_seq(c, args->kwonlyargs)) - return 0; - if (!compiler_check_debug_one_arg(c, args->kwarg)) - return 0; - return 1; + RETURN_IF_ERROR(compiler_check_debug_args_seq(c, args->posonlyargs)); + RETURN_IF_ERROR(compiler_check_debug_args_seq(c, args->args)); + RETURN_IF_ERROR(compiler_check_debug_one_arg(c, args->vararg)); + RETURN_IF_ERROR(compiler_check_debug_args_seq(c, args->kwonlyargs)); + RETURN_IF_ERROR(compiler_check_debug_one_arg(c, args->kwarg)); + return SUCCESS; } static int -compiler_function(struct compiler *c, stmt_ty s, int is_async) +wrap_in_stopiteration_handler(struct compiler *c) { - PyCodeObject *co; - PyObject *qualname, *docstring = NULL; + NEW_JUMP_TARGET_LABEL(c, handler); + + /* Insert SETUP_CLEANUP at start */ + RETURN_IF_ERROR( + instr_sequence_insert_instruction( + INSTR_SEQUENCE(c), 0, + SETUP_CLEANUP, handler.id, NO_LOCATION)); + + ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None); + ADDOP(c, NO_LOCATION, RETURN_VALUE); + USE_LABEL(c, handler); + ADDOP_I(c, NO_LOCATION, CALL_INTRINSIC_1, INTRINSIC_STOPITERATION_ERROR); + ADDOP_I(c, NO_LOCATION, RERAISE, 1); + return SUCCESS; +} + +static int +compiler_type_params(struct compiler *c, asdl_type_param_seq *type_params) +{ + if (!type_params) { + return SUCCESS; + } + Py_ssize_t n = asdl_seq_LEN(type_params); + + for (Py_ssize_t i = 0; i < n; i++) { + type_param_ty typeparam = asdl_seq_GET(type_params, i); + location loc = LOC(typeparam); + switch(typeparam->kind) { + case TypeVar_kind: + ADDOP_LOAD_CONST(c, loc, typeparam->v.TypeVar.name); + if (typeparam->v.TypeVar.bound) { + expr_ty bound = typeparam->v.TypeVar.bound; + if (compiler_enter_scope(c, typeparam->v.TypeVar.name, COMPILER_SCOPE_TYPEPARAMS, + (void *)typeparam, bound->lineno) == -1) { + return ERROR; + } + VISIT_IN_SCOPE(c, expr, bound); + ADDOP_IN_SCOPE(c, loc, RETURN_VALUE); + PyCodeObject *co = optimize_and_assemble(c, 1); + compiler_exit_scope(c); + if (co == NULL) { + return ERROR; + } + if (compiler_make_closure(c, loc, co, 0) < 0) { + Py_DECREF(co); + return ERROR; + } + Py_DECREF(co); + + int intrinsic = bound->kind == Tuple_kind + ? INTRINSIC_TYPEVAR_WITH_CONSTRAINTS + : INTRINSIC_TYPEVAR_WITH_BOUND; + ADDOP_I(c, loc, CALL_INTRINSIC_2, intrinsic); + } + else { + ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_TYPEVAR); + } + ADDOP_I(c, loc, COPY, 1); + RETURN_IF_ERROR(compiler_nameop(c, loc, typeparam->v.TypeVar.name, Store)); + break; + case TypeVarTuple_kind: + ADDOP_LOAD_CONST(c, loc, typeparam->v.TypeVarTuple.name); + ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_TYPEVARTUPLE); + ADDOP_I(c, loc, COPY, 1); + RETURN_IF_ERROR(compiler_nameop(c, loc, typeparam->v.TypeVarTuple.name, Store)); + break; + case ParamSpec_kind: + ADDOP_LOAD_CONST(c, loc, typeparam->v.ParamSpec.name); + ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_PARAMSPEC); + ADDOP_I(c, loc, COPY, 1); + RETURN_IF_ERROR(compiler_nameop(c, loc, typeparam->v.ParamSpec.name, Store)); + break; + } + } + ADDOP_I(c, LOC(asdl_seq_GET(type_params, 0)), BUILD_TUPLE, n); + return SUCCESS; +} + +static int +compiler_function_body(struct compiler *c, stmt_ty s, int is_async, Py_ssize_t funcflags, + int firstlineno) +{ + PyObject *docstring = NULL; arguments_ty args; - expr_ty returns; identifier name; - asdl_expr_seq* decos; asdl_stmt_seq *body; - Py_ssize_t i, funcflags; - int annotations; int scope_type; - int firstlineno; if (is_async) { assert(s->kind == AsyncFunctionDef_kind); args = s->v.AsyncFunctionDef.args; - returns = s->v.AsyncFunctionDef.returns; - decos = s->v.AsyncFunctionDef.decorator_list; name = s->v.AsyncFunctionDef.name; body = s->v.AsyncFunctionDef.body; @@ -2605,95 +2214,191 @@ compiler_function(struct compiler *c, stmt_ty s, int is_async) assert(s->kind == FunctionDef_kind); args = s->v.FunctionDef.args; - returns = s->v.FunctionDef.returns; - decos = s->v.FunctionDef.decorator_list; name = s->v.FunctionDef.name; body = s->v.FunctionDef.body; scope_type = COMPILER_SCOPE_FUNCTION; } - if (!compiler_check_debug_args(c, args)) - return 0; - - if (!compiler_decorators(c, decos)) - return 0; - - firstlineno = s->lineno; - if (asdl_seq_LEN(decos)) { - firstlineno = ((expr_ty)asdl_seq_GET(decos, 0))->lineno; - } - - funcflags = compiler_default_arguments(c, args); - if (funcflags == -1) { - return 0; - } - - annotations = compiler_visit_annotations(c, args, returns); - if (annotations == 0) { - return 0; - } - else if (annotations > 0) { - funcflags |= 0x04; - } - - if (!compiler_enter_scope(c, name, scope_type, (void *)s, firstlineno)) { - return 0; - } + RETURN_IF_ERROR( + compiler_enter_scope(c, name, scope_type, (void *)s, firstlineno)); /* if not -OO mode, add docstring */ if (c->c_optimize < 2) { docstring = _PyAST_GetDocString(body); } - if (compiler_add_const(c, docstring ? docstring : Py_None) < 0) { + if (compiler_add_const(c->c_const_cache, c->u, docstring ? docstring : Py_None) < 0) { compiler_exit_scope(c); - return 0; + return ERROR; } - c->u->u_argcount = asdl_seq_LEN(args->args); - c->u->u_posonlyargcount = asdl_seq_LEN(args->posonlyargs); - c->u->u_kwonlyargcount = asdl_seq_LEN(args->kwonlyargs); - for (i = docstring ? 1 : 0; i < asdl_seq_LEN(body); i++) { + c->u->u_metadata.u_argcount = asdl_seq_LEN(args->args); + c->u->u_metadata.u_posonlyargcount = asdl_seq_LEN(args->posonlyargs); + c->u->u_metadata.u_kwonlyargcount = asdl_seq_LEN(args->kwonlyargs); + for (Py_ssize_t i = docstring ? 1 : 0; i < asdl_seq_LEN(body); i++) { VISIT_IN_SCOPE(c, stmt, (stmt_ty)asdl_seq_GET(body, i)); } - co = assemble(c, 1); - qualname = c->u->u_qualname; - Py_INCREF(qualname); + if (c->u->u_ste->ste_coroutine || c->u->u_ste->ste_generator) { + if (wrap_in_stopiteration_handler(c) < 0) { + compiler_exit_scope(c); + return ERROR; + } + } + PyCodeObject *co = optimize_and_assemble(c, 1); compiler_exit_scope(c); if (co == NULL) { - Py_XDECREF(qualname); Py_XDECREF(co); - return 0; + return ERROR; } - - if (!compiler_make_closure(c, co, funcflags, qualname)) { - Py_DECREF(qualname); + location loc = LOC(s); + if (compiler_make_closure(c, loc, co, funcflags) < 0) { Py_DECREF(co); - return 0; + return ERROR; } - Py_DECREF(qualname); Py_DECREF(co); - - if (!compiler_apply_decorators(c, decos)) - return 0; - return compiler_nameop(c, name, Store); + return SUCCESS; } static int -compiler_class(struct compiler *c, stmt_ty s) +compiler_function(struct compiler *c, stmt_ty s, int is_async) { - PyCodeObject *co; - int i, firstlineno; - asdl_expr_seq *decos = s->v.ClassDef.decorator_list; + arguments_ty args; + expr_ty returns; + identifier name; + asdl_expr_seq *decos; + asdl_type_param_seq *type_params; + Py_ssize_t funcflags; + int annotations; + int firstlineno; - if (!compiler_decorators(c, decos)) - return 0; + if (is_async) { + assert(s->kind == AsyncFunctionDef_kind); + + args = s->v.AsyncFunctionDef.args; + returns = s->v.AsyncFunctionDef.returns; + decos = s->v.AsyncFunctionDef.decorator_list; + name = s->v.AsyncFunctionDef.name; + type_params = s->v.AsyncFunctionDef.type_params; + } else { + assert(s->kind == FunctionDef_kind); + + args = s->v.FunctionDef.args; + returns = s->v.FunctionDef.returns; + decos = s->v.FunctionDef.decorator_list; + name = s->v.FunctionDef.name; + type_params = s->v.FunctionDef.type_params; + } + + RETURN_IF_ERROR(compiler_check_debug_args(c, args)); + RETURN_IF_ERROR(compiler_decorators(c, decos)); firstlineno = s->lineno; if (asdl_seq_LEN(decos)) { firstlineno = ((expr_ty)asdl_seq_GET(decos, 0))->lineno; } + location loc = LOC(s); + + int is_generic = asdl_seq_LEN(type_params) > 0; + + if (is_generic) { + // Used by the CALL to the type parameters function. + ADDOP(c, loc, PUSH_NULL); + } + + funcflags = compiler_default_arguments(c, loc, args); + if (funcflags == -1) { + return ERROR; + } + + int num_typeparam_args = 0; + + if (is_generic) { + if (funcflags & 0x01) { + num_typeparam_args += 1; + } + if (funcflags & 0x02) { + num_typeparam_args += 1; + } + if (num_typeparam_args == 2) { + ADDOP_I(c, loc, SWAP, 2); + } + PyObject *type_params_name = PyUnicode_FromFormat("<generic parameters of %U>", name); + if (!type_params_name) { + return ERROR; + } + if (compiler_enter_scope(c, type_params_name, COMPILER_SCOPE_TYPEPARAMS, + (void *)type_params, firstlineno) == -1) { + Py_DECREF(type_params_name); + return ERROR; + } + Py_DECREF(type_params_name); + RETURN_IF_ERROR_IN_SCOPE(c, compiler_type_params(c, type_params)); + if ((funcflags & 0x01) || (funcflags & 0x02)) { + RETURN_IF_ERROR_IN_SCOPE(c, codegen_addop_i(INSTR_SEQUENCE(c), LOAD_FAST, 0, loc)); + } + if ((funcflags & 0x01) && (funcflags & 0x02)) { + RETURN_IF_ERROR_IN_SCOPE(c, codegen_addop_i(INSTR_SEQUENCE(c), LOAD_FAST, 1, loc)); + } + } + + annotations = compiler_visit_annotations(c, loc, args, returns); + if (annotations < 0) { + if (is_generic) { + compiler_exit_scope(c); + } + return ERROR; + } + if (annotations > 0) { + funcflags |= 0x04; + } + + if (compiler_function_body(c, s, is_async, funcflags, firstlineno) < 0) { + if (is_generic) { + compiler_exit_scope(c); + } + return ERROR; + } + + if (is_generic) { + RETURN_IF_ERROR_IN_SCOPE(c, codegen_addop_i( + INSTR_SEQUENCE(c), SWAP, 2, loc)); + RETURN_IF_ERROR_IN_SCOPE(c, codegen_addop_i( + INSTR_SEQUENCE(c), CALL_INTRINSIC_2, INTRINSIC_SET_FUNCTION_TYPE_PARAMS, loc)); + + c->u->u_metadata.u_argcount = num_typeparam_args; + PyCodeObject *co = optimize_and_assemble(c, 0); + compiler_exit_scope(c); + if (co == NULL) { + return ERROR; + } + if (compiler_make_closure(c, loc, co, 0) < 0) { + Py_DECREF(co); + return ERROR; + } + Py_DECREF(co); + if (num_typeparam_args > 0) { + ADDOP_I(c, loc, SWAP, num_typeparam_args + 1); + } + ADDOP_I(c, loc, CALL, num_typeparam_args); + } + + RETURN_IF_ERROR(compiler_apply_decorators(c, decos)); + return compiler_nameop(c, loc, name, Store); +} + +static int +compiler_set_type_params_in_class(struct compiler *c, location loc) +{ + _Py_DECLARE_STR(type_params, ".type_params"); + RETURN_IF_ERROR(compiler_nameop(c, loc, &_Py_STR(type_params), Load)); + RETURN_IF_ERROR(compiler_nameop(c, loc, &_Py_ID(__type_params__), Store)); + return 1; +} + +static int +compiler_class_body(struct compiler *c, stmt_ty s, int firstlineno) +{ /* ultimately generate code for: <name> = __build_class__(<func>, <name>, *<bases>, **<keywords>) where: @@ -2706,103 +2411,307 @@ compiler_class(struct compiler *c, stmt_ty s) */ /* 1. compile the class body into a code object */ - if (!compiler_enter_scope(c, s->v.ClassDef.name, - COMPILER_SCOPE_CLASS, (void *)s, firstlineno)) { - return 0; + RETURN_IF_ERROR( + compiler_enter_scope(c, s->v.ClassDef.name, + COMPILER_SCOPE_CLASS, (void *)s, firstlineno)); + + location loc = LOCATION(firstlineno, firstlineno, 0, 0); + /* use the class name for name mangling */ + Py_XSETREF(c->u->u_private, Py_NewRef(s->v.ClassDef.name)); + /* load (global) __name__ ... */ + if (compiler_nameop(c, loc, &_Py_ID(__name__), Load) < 0) { + compiler_exit_scope(c); + return ERROR; } - /* this block represents what we do in the new scope */ - { - /* use the class name for name mangling */ - Py_INCREF(s->v.ClassDef.name); - Py_XSETREF(c->u->u_private, s->v.ClassDef.name); - /* load (global) __name__ ... */ - if (!compiler_nameop(c, &_Py_ID(__name__), Load)) { + /* ... and store it as __module__ */ + if (compiler_nameop(c, loc, &_Py_ID(__module__), Store) < 0) { + compiler_exit_scope(c); + return ERROR; + } + assert(c->u->u_metadata.u_qualname); + ADDOP_LOAD_CONST(c, loc, c->u->u_metadata.u_qualname); + if (compiler_nameop(c, loc, &_Py_ID(__qualname__), Store) < 0) { + compiler_exit_scope(c); + return ERROR; + } + asdl_type_param_seq *type_params = s->v.ClassDef.type_params; + if (asdl_seq_LEN(type_params) > 0) { + if (!compiler_set_type_params_in_class(c, loc)) { compiler_exit_scope(c); - return 0; + return ERROR; } - /* ... and store it as __module__ */ - if (!compiler_nameop(c, &_Py_ID(__module__), Store)) { + } + if (c->u->u_ste->ste_needs_classdict) { + ADDOP(c, loc, LOAD_LOCALS); + + // We can't use compiler_nameop here because we need to generate a + // STORE_DEREF in a class namespace, and compiler_nameop() won't do + // that by default. + PyObject *cellvars = c->u->u_metadata.u_cellvars; + if (compiler_addop_o(c->u, loc, STORE_DEREF, cellvars, + &_Py_ID(__classdict__)) < 0) { compiler_exit_scope(c); - return 0; + return ERROR; } - assert(c->u->u_qualname); - ADDOP_LOAD_CONST(c, c->u->u_qualname); - if (!compiler_nameop(c, &_Py_ID(__qualname__), Store)) { + } + /* compile the body proper */ + if (compiler_body(c, loc, s->v.ClassDef.body) < 0) { + compiler_exit_scope(c); + return ERROR; + } + /* The following code is artificial */ + /* Set __classdictcell__ if necessary */ + if (c->u->u_ste->ste_needs_classdict) { + /* Store __classdictcell__ into class namespace */ + int i = compiler_lookup_arg(c->u->u_metadata.u_cellvars, &_Py_ID(__classdict__)); + if (i < 0) { compiler_exit_scope(c); - return 0; + return ERROR; } - /* compile the body proper */ - if (!compiler_body(c, s->v.ClassDef.body)) { + ADDOP_I(c, NO_LOCATION, LOAD_CLOSURE, i); + if (compiler_nameop(c, NO_LOCATION, &_Py_ID(__classdictcell__), Store) < 0) { compiler_exit_scope(c); - return 0; + return ERROR; } - /* The following code is artificial */ - UNSET_LOC(c); - /* Return __classcell__ if it is referenced, otherwise return None */ - if (c->u->u_ste->ste_needs_class_closure) { - /* Store __classcell__ into class namespace & return it */ - i = compiler_lookup_arg(c->u->u_cellvars, &_Py_ID(__class__)); - if (i < 0) { - compiler_exit_scope(c); - return 0; - } - assert(i == 0); - - ADDOP_I(c, LOAD_CLOSURE, i); - ADDOP_I(c, COPY, 1); - if (!compiler_nameop(c, &_Py_ID(__classcell__), Store)) { - compiler_exit_scope(c); - return 0; - } + } + /* Return __classcell__ if it is referenced, otherwise return None */ + if (c->u->u_ste->ste_needs_class_closure) { + /* Store __classcell__ into class namespace & return it */ + int i = compiler_lookup_arg(c->u->u_metadata.u_cellvars, &_Py_ID(__class__)); + if (i < 0) { + compiler_exit_scope(c); + return ERROR; } - else { - /* No methods referenced __class__, so just return None */ - assert(PyDict_GET_SIZE(c->u->u_cellvars) == 0); - ADDOP_LOAD_CONST(c, Py_None); + ADDOP_I(c, NO_LOCATION, LOAD_CLOSURE, i); + ADDOP_I(c, NO_LOCATION, COPY, 1); + if (compiler_nameop(c, NO_LOCATION, &_Py_ID(__classcell__), Store) < 0) { + compiler_exit_scope(c); + return ERROR; } - ADDOP_IN_SCOPE(c, RETURN_VALUE); - /* create the code object */ - co = assemble(c, 1); } + else { + /* No methods referenced __class__, so just return None */ + ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None); + } + ADDOP_IN_SCOPE(c, NO_LOCATION, RETURN_VALUE); + /* create the code object */ + PyCodeObject *co = optimize_and_assemble(c, 1); + /* leave the new scope */ compiler_exit_scope(c); - if (co == NULL) - return 0; + if (co == NULL) { + return ERROR; + } /* 2. load the 'build_class' function */ - ADDOP(c, PUSH_NULL); - ADDOP(c, LOAD_BUILD_CLASS); + + // these instructions should be attributed to the class line, + // not a decorator line + loc = LOC(s); + ADDOP(c, loc, PUSH_NULL); + ADDOP(c, loc, LOAD_BUILD_CLASS); /* 3. load a function (or closure) made from the code object */ - if (!compiler_make_closure(c, co, 0, NULL)) { + if (compiler_make_closure(c, loc, co, 0) < 0) { Py_DECREF(co); - return 0; + return ERROR; } Py_DECREF(co); /* 4. load class name */ - ADDOP_LOAD_CONST(c, s->v.ClassDef.name); + ADDOP_LOAD_CONST(c, loc, s->v.ClassDef.name); - /* 5. generate the rest of the code for the call */ - if (!compiler_call_helper(c, 2, s->v.ClassDef.bases, s->v.ClassDef.keywords)) - return 0; - /* 6. apply decorators */ - if (!compiler_apply_decorators(c, decos)) - return 0; + return SUCCESS; +} + +static int +compiler_class(struct compiler *c, stmt_ty s) +{ + asdl_expr_seq *decos = s->v.ClassDef.decorator_list; + + RETURN_IF_ERROR(compiler_decorators(c, decos)); + + int firstlineno = s->lineno; + if (asdl_seq_LEN(decos)) { + firstlineno = ((expr_ty)asdl_seq_GET(decos, 0))->lineno; + } + location loc = LOC(s); + + asdl_type_param_seq *type_params = s->v.ClassDef.type_params; + int is_generic = asdl_seq_LEN(type_params) > 0; + if (is_generic) { + Py_XSETREF(c->u->u_private, Py_NewRef(s->v.ClassDef.name)); + ADDOP(c, loc, PUSH_NULL); + PyObject *type_params_name = PyUnicode_FromFormat("<generic parameters of %U>", + s->v.ClassDef.name); + if (!type_params_name) { + return ERROR; + } + if (compiler_enter_scope(c, type_params_name, COMPILER_SCOPE_TYPEPARAMS, + (void *)type_params, firstlineno) == -1) { + Py_DECREF(type_params_name); + return ERROR; + } + Py_DECREF(type_params_name); + RETURN_IF_ERROR_IN_SCOPE(c, compiler_type_params(c, type_params)); + _Py_DECLARE_STR(type_params, ".type_params"); + RETURN_IF_ERROR_IN_SCOPE(c, compiler_nameop(c, loc, &_Py_STR(type_params), Store)); + } + + if (compiler_class_body(c, s, firstlineno) < 0) { + if (is_generic) { + compiler_exit_scope(c); + } + return ERROR; + } + + /* generate the rest of the code for the call */ + + if (is_generic) { + _Py_DECLARE_STR(type_params, ".type_params"); + _Py_DECLARE_STR(generic_base, ".generic_base"); + RETURN_IF_ERROR_IN_SCOPE(c, compiler_nameop(c, loc, &_Py_STR(type_params), Load)); + RETURN_IF_ERROR_IN_SCOPE( + c, codegen_addop_i(INSTR_SEQUENCE(c), CALL_INTRINSIC_1, INTRINSIC_SUBSCRIPT_GENERIC, loc) + ) + RETURN_IF_ERROR_IN_SCOPE(c, compiler_nameop(c, loc, &_Py_STR(generic_base), Store)); + + Py_ssize_t original_len = asdl_seq_LEN(s->v.ClassDef.bases); + asdl_expr_seq *bases = _Py_asdl_expr_seq_new( + original_len + 1, c->c_arena); + if (bases == NULL) { + compiler_exit_scope(c); + return ERROR; + } + for (Py_ssize_t i = 0; i < original_len; i++) { + asdl_seq_SET(bases, i, asdl_seq_GET(s->v.ClassDef.bases, i)); + } + expr_ty name_node = _PyAST_Name( + &_Py_STR(generic_base), Load, + loc.lineno, loc.col_offset, loc.end_lineno, loc.end_col_offset, c->c_arena + ); + if (name_node == NULL) { + compiler_exit_scope(c); + return ERROR; + } + asdl_seq_SET(bases, original_len, name_node); + RETURN_IF_ERROR_IN_SCOPE(c, compiler_call_helper(c, loc, 2, + bases, + s->v.ClassDef.keywords)); + + PyCodeObject *co = optimize_and_assemble(c, 0); + compiler_exit_scope(c); + if (co == NULL) { + return ERROR; + } + if (compiler_make_closure(c, loc, co, 0) < 0) { + Py_DECREF(co); + return ERROR; + } + Py_DECREF(co); + ADDOP_I(c, loc, CALL, 0); + } else { + RETURN_IF_ERROR(compiler_call_helper(c, loc, 2, + s->v.ClassDef.bases, + s->v.ClassDef.keywords)); + } + + /* 6. apply decorators */ + RETURN_IF_ERROR(compiler_apply_decorators(c, decos)); /* 7. store into <name> */ - if (!compiler_nameop(c, s->v.ClassDef.name, Store)) - return 0; - return 1; + RETURN_IF_ERROR(compiler_nameop(c, loc, s->v.ClassDef.name, Store)); + return SUCCESS; +} + +static int +compiler_typealias_body(struct compiler *c, stmt_ty s) +{ + location loc = LOC(s); + PyObject *name = s->v.TypeAlias.name->v.Name.id; + RETURN_IF_ERROR( + compiler_enter_scope(c, name, COMPILER_SCOPE_FUNCTION, s, loc.lineno)); + /* Make None the first constant, so the evaluate function can't have a + docstring. */ + RETURN_IF_ERROR(compiler_add_const(c->c_const_cache, c->u, Py_None)); + VISIT_IN_SCOPE(c, expr, s->v.TypeAlias.value); + ADDOP_IN_SCOPE(c, loc, RETURN_VALUE); + PyCodeObject *co = optimize_and_assemble(c, 0); + compiler_exit_scope(c); + if (co == NULL) { + return ERROR; + } + if (compiler_make_closure(c, loc, co, 0) < 0) { + Py_DECREF(co); + return ERROR; + } + Py_DECREF(co); + ADDOP_I(c, loc, BUILD_TUPLE, 3); + ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_TYPEALIAS); + return SUCCESS; } -/* Return 0 if the expression is a constant value except named singletons. - Return 1 otherwise. */ static int +compiler_typealias(struct compiler *c, stmt_ty s) +{ + location loc = LOC(s); + asdl_type_param_seq *type_params = s->v.TypeAlias.type_params; + int is_generic = asdl_seq_LEN(type_params) > 0; + PyObject *name = s->v.TypeAlias.name->v.Name.id; + if (is_generic) { + ADDOP(c, loc, PUSH_NULL); + PyObject *type_params_name = PyUnicode_FromFormat("<generic parameters of %U>", + name); + if (!type_params_name) { + return ERROR; + } + if (compiler_enter_scope(c, type_params_name, COMPILER_SCOPE_TYPEPARAMS, + (void *)type_params, loc.lineno) == -1) { + Py_DECREF(type_params_name); + return ERROR; + } + Py_DECREF(type_params_name); + RETURN_IF_ERROR_IN_SCOPE( + c, compiler_addop_load_const(c->c_const_cache, c->u, loc, name) + ); + RETURN_IF_ERROR_IN_SCOPE(c, compiler_type_params(c, type_params)); + } + else { + ADDOP_LOAD_CONST(c, loc, name); + ADDOP_LOAD_CONST(c, loc, Py_None); + } + + if (compiler_typealias_body(c, s) < 0) { + if (is_generic) { + compiler_exit_scope(c); + } + return ERROR; + } + + if (is_generic) { + PyCodeObject *co = optimize_and_assemble(c, 0); + compiler_exit_scope(c); + if (co == NULL) { + return ERROR; + } + if (compiler_make_closure(c, loc, co, 0) < 0) { + Py_DECREF(co); + return ERROR; + } + Py_DECREF(co); + ADDOP_I(c, loc, CALL, 0); + } + RETURN_IF_ERROR(compiler_nameop(c, loc, name, Store)); + return SUCCESS; +} + +/* Return false if the expression is a constant value except named singletons. + Return true otherwise. */ +static bool check_is_arg(expr_ty e) { if (e->kind != Constant_kind) { - return 1; + return true; } PyObject *value = e->v.Constant.value; return (value == Py_None @@ -2811,33 +2720,50 @@ check_is_arg(expr_ty e) || value == Py_Ellipsis); } -/* Check operands of identity chacks ("is" and "is not"). +static PyTypeObject * infer_type(expr_ty e); + +/* Check operands of identity checks ("is" and "is not"). Emit a warning if any operand is a constant except named singletons. - Return 0 on error. */ static int check_compare(struct compiler *c, expr_ty e) { Py_ssize_t i, n; - int left = check_is_arg(e->v.Compare.left); + bool left = check_is_arg(e->v.Compare.left); + expr_ty left_expr = e->v.Compare.left; n = asdl_seq_LEN(e->v.Compare.ops); for (i = 0; i < n; i++) { cmpop_ty op = (cmpop_ty)asdl_seq_GET(e->v.Compare.ops, i); - int right = check_is_arg((expr_ty)asdl_seq_GET(e->v.Compare.comparators, i)); + expr_ty right_expr = (expr_ty)asdl_seq_GET(e->v.Compare.comparators, i); + bool right = check_is_arg(right_expr); if (op == Is || op == IsNot) { if (!right || !left) { const char *msg = (op == Is) - ? "\"is\" with a literal. Did you mean \"==\"?" - : "\"is not\" with a literal. Did you mean \"!=\"?"; - return compiler_warn(c, msg); + ? "\"is\" with '%.200s' literal. Did you mean \"==\"?" + : "\"is not\" with '%.200s' literal. Did you mean \"!=\"?"; + expr_ty literal = !left ? left_expr : right_expr; + return compiler_warn( + c, LOC(e), msg, infer_type(literal)->tp_name + ); } } left = right; + left_expr = right_expr; } - return 1; + return SUCCESS; } -static int compiler_addcompare(struct compiler *c, cmpop_ty op) +static const int compare_masks[] = { + [Py_LT] = COMPARISON_LESS_THAN, + [Py_LE] = COMPARISON_LESS_THAN | COMPARISON_EQUALS, + [Py_EQ] = COMPARISON_EQUALS, + [Py_NE] = COMPARISON_NOT_EQUALS, + [Py_GT] = COMPARISON_GREATER_THAN, + [Py_GE] = COMPARISON_GREATER_THAN | COMPARISON_EQUALS, +}; + +static int compiler_addcompare(struct compiler *c, location loc, + cmpop_ty op) { int cmp; switch (op) { @@ -2860,33 +2786,37 @@ static int compiler_addcompare(struct compiler *c, cmpop_ty op) cmp = Py_GE; break; case Is: - ADDOP_I(c, IS_OP, 0); - return 1; + ADDOP_I(c, loc, IS_OP, 0); + return SUCCESS; case IsNot: - ADDOP_I(c, IS_OP, 1); - return 1; + ADDOP_I(c, loc, IS_OP, 1); + return SUCCESS; case In: - ADDOP_I(c, CONTAINS_OP, 0); - return 1; + ADDOP_I(c, loc, CONTAINS_OP, 0); + return SUCCESS; case NotIn: - ADDOP_I(c, CONTAINS_OP, 1); - return 1; + ADDOP_I(c, loc, CONTAINS_OP, 1); + return SUCCESS; default: Py_UNREACHABLE(); } - ADDOP_I(c, COMPARE_OP, cmp); - return 1; + /* cmp goes in top bits of the oparg, while the low bits are used by quickened + * versions of this opcode to store the comparison mask. */ + ADDOP_I(c, loc, COMPARE_OP, (cmp << 4) | compare_masks[cmp]); + return SUCCESS; } static int -compiler_jump_if(struct compiler *c, expr_ty e, basicblock *next, int cond) +compiler_jump_if(struct compiler *c, location loc, + expr_ty e, jump_target_label next, int cond) { switch (e->kind) { case UnaryOp_kind: - if (e->v.UnaryOp.op == Not) - return compiler_jump_if(c, e->v.UnaryOp.operand, next, !cond); + if (e->v.UnaryOp.op == Not) { + return compiler_jump_if(c, loc, e->v.UnaryOp.operand, next, !cond); + } /* fallback to general implementation */ break; case BoolOp_kind: { @@ -2894,74 +2824,66 @@ compiler_jump_if(struct compiler *c, expr_ty e, basicblock *next, int cond) Py_ssize_t i, n = asdl_seq_LEN(s) - 1; assert(n >= 0); int cond2 = e->v.BoolOp.op == Or; - basicblock *next2 = next; + jump_target_label next2 = next; if (!cond2 != !cond) { - next2 = compiler_new_block(c); - if (next2 == NULL) - return 0; + NEW_JUMP_TARGET_LABEL(c, new_next2); + next2 = new_next2; } for (i = 0; i < n; ++i) { - if (!compiler_jump_if(c, (expr_ty)asdl_seq_GET(s, i), next2, cond2)) - return 0; + RETURN_IF_ERROR( + compiler_jump_if(c, loc, (expr_ty)asdl_seq_GET(s, i), next2, cond2)); } - if (!compiler_jump_if(c, (expr_ty)asdl_seq_GET(s, n), next, cond)) - return 0; - if (next2 != next) - compiler_use_next_block(c, next2); - return 1; + RETURN_IF_ERROR( + compiler_jump_if(c, loc, (expr_ty)asdl_seq_GET(s, n), next, cond)); + if (!SAME_LABEL(next2, next)) { + USE_LABEL(c, next2); + } + return SUCCESS; } case IfExp_kind: { - basicblock *end, *next2; - end = compiler_new_block(c); - if (end == NULL) - return 0; - next2 = compiler_new_block(c); - if (next2 == NULL) - return 0; - if (!compiler_jump_if(c, e->v.IfExp.test, next2, 0)) - return 0; - if (!compiler_jump_if(c, e->v.IfExp.body, next, cond)) - return 0; - ADDOP_JUMP_NOLINE(c, JUMP, end); - compiler_use_next_block(c, next2); - if (!compiler_jump_if(c, e->v.IfExp.orelse, next, cond)) - return 0; - compiler_use_next_block(c, end); - return 1; + NEW_JUMP_TARGET_LABEL(c, end); + NEW_JUMP_TARGET_LABEL(c, next2); + RETURN_IF_ERROR( + compiler_jump_if(c, loc, e->v.IfExp.test, next2, 0)); + RETURN_IF_ERROR( + compiler_jump_if(c, loc, e->v.IfExp.body, next, cond)); + ADDOP_JUMP(c, NO_LOCATION, JUMP, end); + + USE_LABEL(c, next2); + RETURN_IF_ERROR( + compiler_jump_if(c, loc, e->v.IfExp.orelse, next, cond)); + + USE_LABEL(c, end); + return SUCCESS; } case Compare_kind: { - SET_LOC(c, e); - Py_ssize_t i, n = asdl_seq_LEN(e->v.Compare.ops) - 1; + Py_ssize_t n = asdl_seq_LEN(e->v.Compare.ops) - 1; if (n > 0) { - if (!check_compare(c, e)) { - return 0; - } - basicblock *cleanup = compiler_new_block(c); - if (cleanup == NULL) - return 0; + RETURN_IF_ERROR(check_compare(c, e)); + NEW_JUMP_TARGET_LABEL(c, cleanup); VISIT(c, expr, e->v.Compare.left); - for (i = 0; i < n; i++) { + for (Py_ssize_t i = 0; i < n; i++) { VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Compare.comparators, i)); - ADDOP_I(c, SWAP, 2); - ADDOP_I(c, COPY, 2); - ADDOP_COMPARE(c, asdl_seq_GET(e->v.Compare.ops, i)); - ADDOP_JUMP(c, POP_JUMP_IF_FALSE, cleanup); + ADDOP_I(c, LOC(e), SWAP, 2); + ADDOP_I(c, LOC(e), COPY, 2); + ADDOP_COMPARE(c, LOC(e), asdl_seq_GET(e->v.Compare.ops, i)); + ADDOP_JUMP(c, LOC(e), POP_JUMP_IF_FALSE, cleanup); } VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Compare.comparators, n)); - ADDOP_COMPARE(c, asdl_seq_GET(e->v.Compare.ops, n)); - ADDOP_JUMP(c, cond ? POP_JUMP_IF_TRUE : POP_JUMP_IF_FALSE, next); - basicblock *end = compiler_new_block(c); - if (end == NULL) - return 0; - ADDOP_JUMP_NOLINE(c, JUMP, end); - compiler_use_next_block(c, cleanup); - ADDOP(c, POP_TOP); + ADDOP_COMPARE(c, LOC(e), asdl_seq_GET(e->v.Compare.ops, n)); + ADDOP_JUMP(c, LOC(e), cond ? POP_JUMP_IF_TRUE : POP_JUMP_IF_FALSE, next); + NEW_JUMP_TARGET_LABEL(c, end); + ADDOP_JUMP(c, NO_LOCATION, JUMP, end); + + USE_LABEL(c, cleanup); + ADDOP(c, LOC(e), POP_TOP); if (!cond) { - ADDOP_JUMP_NOLINE(c, JUMP, next); + ADDOP_JUMP(c, NO_LOCATION, JUMP, next); } - compiler_use_next_block(c, end); - return 1; + + USE_LABEL(c, end); + return SUCCESS; } /* fallback to general implementation */ break; @@ -2973,337 +2895,292 @@ compiler_jump_if(struct compiler *c, expr_ty e, basicblock *next, int cond) /* general implementation */ VISIT(c, expr, e); - ADDOP_JUMP(c, cond ? POP_JUMP_IF_TRUE : POP_JUMP_IF_FALSE, next); - return 1; + ADDOP_JUMP(c, LOC(e), cond ? POP_JUMP_IF_TRUE : POP_JUMP_IF_FALSE, next); + return SUCCESS; } static int compiler_ifexp(struct compiler *c, expr_ty e) { - basicblock *end, *next; - assert(e->kind == IfExp_kind); - end = compiler_new_block(c); - if (end == NULL) - return 0; - next = compiler_new_block(c); - if (next == NULL) - return 0; - if (!compiler_jump_if(c, e->v.IfExp.test, next, 0)) - return 0; + NEW_JUMP_TARGET_LABEL(c, end); + NEW_JUMP_TARGET_LABEL(c, next); + + RETURN_IF_ERROR( + compiler_jump_if(c, LOC(e), e->v.IfExp.test, next, 0)); + VISIT(c, expr, e->v.IfExp.body); - ADDOP_JUMP_NOLINE(c, JUMP, end); - compiler_use_next_block(c, next); + ADDOP_JUMP(c, NO_LOCATION, JUMP, end); + + USE_LABEL(c, next); VISIT(c, expr, e->v.IfExp.orelse); - compiler_use_next_block(c, end); - return 1; + + USE_LABEL(c, end); + return SUCCESS; } static int compiler_lambda(struct compiler *c, expr_ty e) { PyCodeObject *co; - PyObject *qualname; Py_ssize_t funcflags; arguments_ty args = e->v.Lambda.args; assert(e->kind == Lambda_kind); - if (!compiler_check_debug_args(c, args)) - return 0; + RETURN_IF_ERROR(compiler_check_debug_args(c, args)); - funcflags = compiler_default_arguments(c, args); + location loc = LOC(e); + funcflags = compiler_default_arguments(c, loc, args); if (funcflags == -1) { - return 0; + return ERROR; } _Py_DECLARE_STR(anon_lambda, "<lambda>"); - if (!compiler_enter_scope(c, &_Py_STR(anon_lambda), COMPILER_SCOPE_LAMBDA, - (void *)e, e->lineno)) { - return 0; - } + RETURN_IF_ERROR( + compiler_enter_scope(c, &_Py_STR(anon_lambda), COMPILER_SCOPE_LAMBDA, + (void *)e, e->lineno)); + /* Make None the first constant, so the lambda can't have a docstring. */ - if (compiler_add_const(c, Py_None) < 0) - return 0; + RETURN_IF_ERROR(compiler_add_const(c->c_const_cache, c->u, Py_None)); - c->u->u_argcount = asdl_seq_LEN(args->args); - c->u->u_posonlyargcount = asdl_seq_LEN(args->posonlyargs); - c->u->u_kwonlyargcount = asdl_seq_LEN(args->kwonlyargs); + c->u->u_metadata.u_argcount = asdl_seq_LEN(args->args); + c->u->u_metadata.u_posonlyargcount = asdl_seq_LEN(args->posonlyargs); + c->u->u_metadata.u_kwonlyargcount = asdl_seq_LEN(args->kwonlyargs); VISIT_IN_SCOPE(c, expr, e->v.Lambda.body); if (c->u->u_ste->ste_generator) { - co = assemble(c, 0); + co = optimize_and_assemble(c, 0); } else { - ADDOP_IN_SCOPE(c, RETURN_VALUE); - co = assemble(c, 1); + location loc = LOCATION(e->lineno, e->lineno, 0, 0); + ADDOP_IN_SCOPE(c, loc, RETURN_VALUE); + co = optimize_and_assemble(c, 1); } - qualname = c->u->u_qualname; - Py_INCREF(qualname); compiler_exit_scope(c); if (co == NULL) { - Py_DECREF(qualname); - return 0; + return ERROR; } - if (!compiler_make_closure(c, co, funcflags, qualname)) { - Py_DECREF(qualname); + if (compiler_make_closure(c, loc, co, funcflags) < 0) { Py_DECREF(co); - return 0; + return ERROR; } - Py_DECREF(qualname); Py_DECREF(co); - return 1; + return SUCCESS; } static int compiler_if(struct compiler *c, stmt_ty s) { - basicblock *end, *next; + jump_target_label next; assert(s->kind == If_kind); - end = compiler_new_block(c); - if (end == NULL) { - return 0; - } + NEW_JUMP_TARGET_LABEL(c, end); if (asdl_seq_LEN(s->v.If.orelse)) { - next = compiler_new_block(c); - if (next == NULL) { - return 0; - } + NEW_JUMP_TARGET_LABEL(c, orelse); + next = orelse; } else { next = end; } - if (!compiler_jump_if(c, s->v.If.test, next, 0)) { - return 0; - } + RETURN_IF_ERROR( + compiler_jump_if(c, LOC(s), s->v.If.test, next, 0)); + VISIT_SEQ(c, stmt, s->v.If.body); if (asdl_seq_LEN(s->v.If.orelse)) { - ADDOP_JUMP_NOLINE(c, JUMP, end); - compiler_use_next_block(c, next); + ADDOP_JUMP(c, NO_LOCATION, JUMP, end); + + USE_LABEL(c, next); VISIT_SEQ(c, stmt, s->v.If.orelse); } - compiler_use_next_block(c, end); - return 1; + + USE_LABEL(c, end); + return SUCCESS; } static int compiler_for(struct compiler *c, stmt_ty s) { - basicblock *start, *body, *cleanup, *end; + location loc = LOC(s); + NEW_JUMP_TARGET_LABEL(c, start); + NEW_JUMP_TARGET_LABEL(c, body); + NEW_JUMP_TARGET_LABEL(c, cleanup); + NEW_JUMP_TARGET_LABEL(c, end); + + RETURN_IF_ERROR(compiler_push_fblock(c, loc, FOR_LOOP, start, end, NULL)); - start = compiler_new_block(c); - body = compiler_new_block(c); - cleanup = compiler_new_block(c); - end = compiler_new_block(c); - if (start == NULL || body == NULL || end == NULL || cleanup == NULL) { - return 0; - } - if (!compiler_push_fblock(c, FOR_LOOP, start, end, NULL)) { - return 0; - } VISIT(c, expr, s->v.For.iter); - ADDOP(c, GET_ITER); - compiler_use_next_block(c, start); - ADDOP_JUMP(c, FOR_ITER, cleanup); - compiler_use_next_block(c, body); + ADDOP(c, loc, GET_ITER); + + USE_LABEL(c, start); + ADDOP_JUMP(c, loc, FOR_ITER, cleanup); + + USE_LABEL(c, body); VISIT(c, expr, s->v.For.target); VISIT_SEQ(c, stmt, s->v.For.body); /* Mark jump as artificial */ - UNSET_LOC(c); - ADDOP_JUMP(c, JUMP, start); - compiler_use_next_block(c, cleanup); + ADDOP_JUMP(c, NO_LOCATION, JUMP, start); + + USE_LABEL(c, cleanup); + ADDOP(c, NO_LOCATION, END_FOR); compiler_pop_fblock(c, FOR_LOOP, start); VISIT_SEQ(c, stmt, s->v.For.orelse); - compiler_use_next_block(c, end); - return 1; + + USE_LABEL(c, end); + return SUCCESS; } static int compiler_async_for(struct compiler *c, stmt_ty s) { - basicblock *start, *except, *end; + location loc = LOC(s); if (IS_TOP_LEVEL_AWAIT(c)){ c->u->u_ste->ste_coroutine = 1; } else if (c->u->u_scope_type != COMPILER_SCOPE_ASYNC_FUNCTION) { - return compiler_error(c, "'async for' outside async function"); + return compiler_error(c, loc, "'async for' outside async function"); } - start = compiler_new_block(c); - except = compiler_new_block(c); - end = compiler_new_block(c); + NEW_JUMP_TARGET_LABEL(c, start); + NEW_JUMP_TARGET_LABEL(c, except); + NEW_JUMP_TARGET_LABEL(c, end); - if (start == NULL || except == NULL || end == NULL) { - return 0; - } VISIT(c, expr, s->v.AsyncFor.iter); - ADDOP(c, GET_AITER); + ADDOP(c, loc, GET_AITER); + + USE_LABEL(c, start); + RETURN_IF_ERROR(compiler_push_fblock(c, loc, FOR_LOOP, start, end, NULL)); - compiler_use_next_block(c, start); - if (!compiler_push_fblock(c, FOR_LOOP, start, end, NULL)) { - return 0; - } /* SETUP_FINALLY to guard the __anext__ call */ - ADDOP_JUMP(c, SETUP_FINALLY, except); - ADDOP(c, GET_ANEXT); - ADDOP_LOAD_CONST(c, Py_None); - ADD_YIELD_FROM(c, 1); - ADDOP(c, POP_BLOCK); /* for SETUP_FINALLY */ + ADDOP_JUMP(c, loc, SETUP_FINALLY, except); + ADDOP(c, loc, GET_ANEXT); + ADDOP_LOAD_CONST(c, loc, Py_None); + ADD_YIELD_FROM(c, loc, 1); + ADDOP(c, loc, POP_BLOCK); /* for SETUP_FINALLY */ /* Success block for __anext__ */ VISIT(c, expr, s->v.AsyncFor.target); VISIT_SEQ(c, stmt, s->v.AsyncFor.body); /* Mark jump as artificial */ - UNSET_LOC(c); - ADDOP_JUMP(c, JUMP, start); + ADDOP_JUMP(c, NO_LOCATION, JUMP, start); compiler_pop_fblock(c, FOR_LOOP, start); /* Except block for __anext__ */ - compiler_use_next_block(c, except); + USE_LABEL(c, except); /* Use same line number as the iterator, * as the END_ASYNC_FOR succeeds the `for`, not the body. */ - SET_LOC(c, s->v.AsyncFor.iter); - ADDOP(c, END_ASYNC_FOR); + loc = LOC(s->v.AsyncFor.iter); + ADDOP(c, loc, END_ASYNC_FOR); /* `else` block */ VISIT_SEQ(c, stmt, s->v.For.orelse); - compiler_use_next_block(c, end); - - return 1; + USE_LABEL(c, end); + return SUCCESS; } static int compiler_while(struct compiler *c, stmt_ty s) { - basicblock *loop, *body, *end, *anchor = NULL; - loop = compiler_new_block(c); - body = compiler_new_block(c); - anchor = compiler_new_block(c); - end = compiler_new_block(c); - if (loop == NULL || body == NULL || anchor == NULL || end == NULL) { - return 0; - } - compiler_use_next_block(c, loop); - if (!compiler_push_fblock(c, WHILE_LOOP, loop, end, NULL)) { - return 0; - } - if (!compiler_jump_if(c, s->v.While.test, anchor, 0)) { - return 0; - } + NEW_JUMP_TARGET_LABEL(c, loop); + NEW_JUMP_TARGET_LABEL(c, body); + NEW_JUMP_TARGET_LABEL(c, end); + NEW_JUMP_TARGET_LABEL(c, anchor); + + USE_LABEL(c, loop); - compiler_use_next_block(c, body); + RETURN_IF_ERROR(compiler_push_fblock(c, LOC(s), WHILE_LOOP, loop, end, NULL)); + RETURN_IF_ERROR(compiler_jump_if(c, LOC(s), s->v.While.test, anchor, 0)); + + USE_LABEL(c, body); VISIT_SEQ(c, stmt, s->v.While.body); - SET_LOC(c, s); - if (!compiler_jump_if(c, s->v.While.test, body, 1)) { - return 0; - } + RETURN_IF_ERROR(compiler_jump_if(c, LOC(s), s->v.While.test, body, 1)); compiler_pop_fblock(c, WHILE_LOOP, loop); - compiler_use_next_block(c, anchor); + USE_LABEL(c, anchor); if (s->v.While.orelse) { VISIT_SEQ(c, stmt, s->v.While.orelse); } - compiler_use_next_block(c, end); - return 1; + USE_LABEL(c, end); + return SUCCESS; } static int compiler_return(struct compiler *c, stmt_ty s) { + location loc = LOC(s); int preserve_tos = ((s->v.Return.value != NULL) && (s->v.Return.value->kind != Constant_kind)); - if (c->u->u_ste->ste_type != FunctionBlock) - return compiler_error(c, "'return' outside function"); + if (!_PyST_IsFunctionLike(c->u->u_ste)) { + return compiler_error(c, loc, "'return' outside function"); + } if (s->v.Return.value != NULL && c->u->u_ste->ste_coroutine && c->u->u_ste->ste_generator) { - return compiler_error( - c, "'return' with value in async generator"); + return compiler_error(c, loc, "'return' with value in async generator"); } + if (preserve_tos) { VISIT(c, expr, s->v.Return.value); } else { /* Emit instruction with line number for return value */ if (s->v.Return.value != NULL) { - SET_LOC(c, s->v.Return.value); - ADDOP(c, NOP); + loc = LOC(s->v.Return.value); + ADDOP(c, loc, NOP); } } if (s->v.Return.value == NULL || s->v.Return.value->lineno != s->lineno) { - SET_LOC(c, s); - ADDOP(c, NOP); + loc = LOC(s); + ADDOP(c, loc, NOP); } - if (!compiler_unwind_fblock_stack(c, preserve_tos, NULL)) - return 0; + RETURN_IF_ERROR(compiler_unwind_fblock_stack(c, &loc, preserve_tos, NULL)); if (s->v.Return.value == NULL) { - ADDOP_LOAD_CONST(c, Py_None); + ADDOP_LOAD_CONST(c, loc, Py_None); } else if (!preserve_tos) { - ADDOP_LOAD_CONST(c, s->v.Return.value->v.Constant.value); + ADDOP_LOAD_CONST(c, loc, s->v.Return.value->v.Constant.value); } - ADDOP(c, RETURN_VALUE); + ADDOP(c, loc, RETURN_VALUE); - return 1; + return SUCCESS; } static int -compiler_break(struct compiler *c) +compiler_break(struct compiler *c, location loc) { struct fblockinfo *loop = NULL; - int u_lineno = c->u->u_lineno; - int u_col_offset = c->u->u_col_offset; - int u_end_lineno = c->u->u_end_lineno; - int u_end_col_offset = c->u->u_end_col_offset; + location origin_loc = loc; /* Emit instruction with line number */ - ADDOP(c, NOP); - if (!compiler_unwind_fblock_stack(c, 0, &loop)) { - return 0; - } + ADDOP(c, loc, NOP); + RETURN_IF_ERROR(compiler_unwind_fblock_stack(c, &loc, 0, &loop)); if (loop == NULL) { - c->u->u_lineno = u_lineno; - c->u->u_col_offset = u_col_offset; - c->u->u_end_lineno = u_end_lineno; - c->u->u_end_col_offset = u_end_col_offset; - return compiler_error(c, "'break' outside loop"); - } - if (!compiler_unwind_fblock(c, loop, 0)) { - return 0; + return compiler_error(c, origin_loc, "'break' outside loop"); } - ADDOP_JUMP(c, JUMP, loop->fb_exit); - return 1; + RETURN_IF_ERROR(compiler_unwind_fblock(c, &loc, loop, 0)); + ADDOP_JUMP(c, loc, JUMP, loop->fb_exit); + return SUCCESS; } static int -compiler_continue(struct compiler *c) +compiler_continue(struct compiler *c, location loc) { struct fblockinfo *loop = NULL; - int u_lineno = c->u->u_lineno; - int u_col_offset = c->u->u_col_offset; - int u_end_lineno = c->u->u_end_lineno; - int u_end_col_offset = c->u->u_end_col_offset; + location origin_loc = loc; /* Emit instruction with line number */ - ADDOP(c, NOP); - if (!compiler_unwind_fblock_stack(c, 0, &loop)) { - return 0; - } + ADDOP(c, loc, NOP); + RETURN_IF_ERROR(compiler_unwind_fblock_stack(c, &loc, 0, &loop)); if (loop == NULL) { - c->u->u_lineno = u_lineno; - c->u->u_col_offset = u_col_offset; - c->u->u_end_lineno = u_end_lineno; - c->u->u_end_col_offset = u_end_col_offset; - return compiler_error(c, "'continue' not properly in loop"); + return compiler_error(c, origin_loc, "'continue' not properly in loop"); } - ADDOP_JUMP(c, JUMP, loop->fb_block); - return 1; + ADDOP_JUMP(c, loc, JUMP, loop->fb_block); + return SUCCESS; } @@ -3339,101 +3216,103 @@ compiler_continue(struct compiler *c) static int compiler_try_finally(struct compiler *c, stmt_ty s) { - basicblock *body, *end, *exit, *cleanup; + location loc = LOC(s); + + NEW_JUMP_TARGET_LABEL(c, body); + NEW_JUMP_TARGET_LABEL(c, end); + NEW_JUMP_TARGET_LABEL(c, exit); + NEW_JUMP_TARGET_LABEL(c, cleanup); - body = compiler_new_block(c); - end = compiler_new_block(c); - exit = compiler_new_block(c); - cleanup = compiler_new_block(c); - if (body == NULL || end == NULL || exit == NULL || cleanup == NULL) { - return 0; - } /* `try` block */ - ADDOP_JUMP(c, SETUP_FINALLY, end); - compiler_use_next_block(c, body); - if (!compiler_push_fblock(c, FINALLY_TRY, body, end, s->v.Try.finalbody)) - return 0; + ADDOP_JUMP(c, loc, SETUP_FINALLY, end); + + USE_LABEL(c, body); + RETURN_IF_ERROR( + compiler_push_fblock(c, loc, FINALLY_TRY, body, end, + s->v.Try.finalbody)); + if (s->v.Try.handlers && asdl_seq_LEN(s->v.Try.handlers)) { - if (!compiler_try_except(c, s)) - return 0; + RETURN_IF_ERROR(compiler_try_except(c, s)); } else { VISIT_SEQ(c, stmt, s->v.Try.body); } - ADDOP_NOLINE(c, POP_BLOCK); + ADDOP(c, NO_LOCATION, POP_BLOCK); compiler_pop_fblock(c, FINALLY_TRY, body); VISIT_SEQ(c, stmt, s->v.Try.finalbody); - ADDOP_JUMP_NOLINE(c, JUMP, exit); + + ADDOP_JUMP(c, NO_LOCATION, JUMP, exit); /* `finally` block */ - compiler_use_next_block(c, end); - UNSET_LOC(c); - ADDOP_JUMP(c, SETUP_CLEANUP, cleanup); - ADDOP(c, PUSH_EXC_INFO); - if (!compiler_push_fblock(c, FINALLY_END, end, NULL, NULL)) - return 0; + USE_LABEL(c, end); + + loc = NO_LOCATION; + ADDOP_JUMP(c, loc, SETUP_CLEANUP, cleanup); + ADDOP(c, loc, PUSH_EXC_INFO); + RETURN_IF_ERROR( + compiler_push_fblock(c, loc, FINALLY_END, end, NO_LABEL, NULL)); VISIT_SEQ(c, stmt, s->v.Try.finalbody); compiler_pop_fblock(c, FINALLY_END, end); - ADDOP_I(c, RERAISE, 0); - compiler_use_next_block(c, cleanup); - POP_EXCEPT_AND_RERAISE(c); - compiler_use_next_block(c, exit); - return 1; + + loc = NO_LOCATION; + ADDOP_I(c, loc, RERAISE, 0); + + USE_LABEL(c, cleanup); + POP_EXCEPT_AND_RERAISE(c, loc); + + USE_LABEL(c, exit); + return SUCCESS; } static int compiler_try_star_finally(struct compiler *c, stmt_ty s) { - basicblock *body = compiler_new_block(c); - if (body == NULL) { - return 0; - } - basicblock *end = compiler_new_block(c); - if (!end) { - return 0; - } - basicblock *exit = compiler_new_block(c); - if (!exit) { - return 0; - } - basicblock *cleanup = compiler_new_block(c); - if (!cleanup) { - return 0; - } + location loc = LOC(s); + + NEW_JUMP_TARGET_LABEL(c, body); + NEW_JUMP_TARGET_LABEL(c, end); + NEW_JUMP_TARGET_LABEL(c, exit); + NEW_JUMP_TARGET_LABEL(c, cleanup); /* `try` block */ - ADDOP_JUMP(c, SETUP_FINALLY, end); - compiler_use_next_block(c, body); - if (!compiler_push_fblock(c, FINALLY_TRY, body, end, s->v.TryStar.finalbody)) { - return 0; - } + ADDOP_JUMP(c, loc, SETUP_FINALLY, end); + + USE_LABEL(c, body); + RETURN_IF_ERROR( + compiler_push_fblock(c, loc, FINALLY_TRY, body, end, + s->v.TryStar.finalbody)); + if (s->v.TryStar.handlers && asdl_seq_LEN(s->v.TryStar.handlers)) { - if (!compiler_try_star_except(c, s)) { - return 0; - } + RETURN_IF_ERROR(compiler_try_star_except(c, s)); } else { VISIT_SEQ(c, stmt, s->v.TryStar.body); } - ADDOP_NOLINE(c, POP_BLOCK); + ADDOP(c, NO_LOCATION, POP_BLOCK); compiler_pop_fblock(c, FINALLY_TRY, body); VISIT_SEQ(c, stmt, s->v.TryStar.finalbody); - ADDOP_JUMP_NOLINE(c, JUMP, exit); + + ADDOP_JUMP(c, NO_LOCATION, JUMP, exit); + /* `finally` block */ - compiler_use_next_block(c, end); + USE_LABEL(c, end); + + loc = NO_LOCATION; + ADDOP_JUMP(c, loc, SETUP_CLEANUP, cleanup); + ADDOP(c, loc, PUSH_EXC_INFO); + RETURN_IF_ERROR( + compiler_push_fblock(c, loc, FINALLY_END, end, NO_LABEL, NULL)); - UNSET_LOC(c); - ADDOP_JUMP(c, SETUP_CLEANUP, cleanup); - ADDOP(c, PUSH_EXC_INFO); - if (!compiler_push_fblock(c, FINALLY_END, end, NULL, NULL)) { - return 0; - } VISIT_SEQ(c, stmt, s->v.TryStar.finalbody); + compiler_pop_fblock(c, FINALLY_END, end); - ADDOP_I(c, RERAISE, 0); - compiler_use_next_block(c, cleanup); - POP_EXCEPT_AND_RERAISE(c); - compiler_use_next_block(c, exit); - return 1; + loc = NO_LOCATION; + ADDOP_I(c, loc, RERAISE, 0); + + USE_LABEL(c, cleanup); + POP_EXCEPT_AND_RERAISE(c, loc); + + USE_LABEL(c, exit); + return SUCCESS; } @@ -3468,60 +3347,57 @@ compiler_try_star_finally(struct compiler *c, stmt_ty s) static int compiler_try_except(struct compiler *c, stmt_ty s) { - basicblock *body, *except, *end, *cleanup; + location loc = LOC(s); Py_ssize_t i, n; - body = compiler_new_block(c); - except = compiler_new_block(c); - end = compiler_new_block(c); - cleanup = compiler_new_block(c); - if (body == NULL || except == NULL || end == NULL || cleanup == NULL) - return 0; - ADDOP_JUMP(c, SETUP_FINALLY, except); - compiler_use_next_block(c, body); - if (!compiler_push_fblock(c, TRY_EXCEPT, body, NULL, NULL)) - return 0; + NEW_JUMP_TARGET_LABEL(c, body); + NEW_JUMP_TARGET_LABEL(c, except); + NEW_JUMP_TARGET_LABEL(c, end); + NEW_JUMP_TARGET_LABEL(c, cleanup); + + ADDOP_JUMP(c, loc, SETUP_FINALLY, except); + + USE_LABEL(c, body); + RETURN_IF_ERROR( + compiler_push_fblock(c, loc, TRY_EXCEPT, body, NO_LABEL, NULL)); VISIT_SEQ(c, stmt, s->v.Try.body); compiler_pop_fblock(c, TRY_EXCEPT, body); - ADDOP_NOLINE(c, POP_BLOCK); + ADDOP(c, NO_LOCATION, POP_BLOCK); if (s->v.Try.orelse && asdl_seq_LEN(s->v.Try.orelse)) { VISIT_SEQ(c, stmt, s->v.Try.orelse); } - ADDOP_JUMP_NOLINE(c, JUMP, end); + ADDOP_JUMP(c, NO_LOCATION, JUMP, end); n = asdl_seq_LEN(s->v.Try.handlers); - compiler_use_next_block(c, except); - UNSET_LOC(c); - ADDOP_JUMP(c, SETUP_CLEANUP, cleanup); - ADDOP(c, PUSH_EXC_INFO); + USE_LABEL(c, except); + + ADDOP_JUMP(c, NO_LOCATION, SETUP_CLEANUP, cleanup); + ADDOP(c, NO_LOCATION, PUSH_EXC_INFO); + /* Runtime will push a block here, so we need to account for that */ - if (!compiler_push_fblock(c, EXCEPTION_HANDLER, NULL, NULL, NULL)) - return 0; + RETURN_IF_ERROR( + compiler_push_fblock(c, loc, EXCEPTION_HANDLER, NO_LABEL, NO_LABEL, NULL)); + for (i = 0; i < n; i++) { excepthandler_ty handler = (excepthandler_ty)asdl_seq_GET( s->v.Try.handlers, i); - SET_LOC(c, handler); + location loc = LOC(handler); if (!handler->v.ExceptHandler.type && i < n-1) { - return compiler_error(c, "default 'except:' must be last"); + return compiler_error(c, loc, "default 'except:' must be last"); } - except = compiler_new_block(c); - if (except == NULL) - return 0; + NEW_JUMP_TARGET_LABEL(c, next_except); + except = next_except; if (handler->v.ExceptHandler.type) { VISIT(c, expr, handler->v.ExceptHandler.type); - ADDOP(c, CHECK_EXC_MATCH); - ADDOP_JUMP(c, POP_JUMP_IF_FALSE, except); + ADDOP(c, loc, CHECK_EXC_MATCH); + ADDOP_JUMP(c, loc, POP_JUMP_IF_FALSE, except); } if (handler->v.ExceptHandler.name) { - basicblock *cleanup_end, *cleanup_body; - - cleanup_end = compiler_new_block(c); - cleanup_body = compiler_new_block(c); - if (cleanup_end == NULL || cleanup_body == NULL) { - return 0; - } + NEW_JUMP_TARGET_LABEL(c, cleanup_end); + NEW_JUMP_TARGET_LABEL(c, cleanup_body); - compiler_nameop(c, handler->v.ExceptHandler.name, Store); + RETURN_IF_ERROR( + compiler_nameop(c, loc, handler->v.ExceptHandler.name, Store)); /* try: @@ -3535,64 +3411,67 @@ compiler_try_except(struct compiler *c, stmt_ty s) */ /* second try: */ - ADDOP_JUMP(c, SETUP_CLEANUP, cleanup_end); - compiler_use_next_block(c, cleanup_body); - if (!compiler_push_fblock(c, HANDLER_CLEANUP, cleanup_body, NULL, handler->v.ExceptHandler.name)) - return 0; + ADDOP_JUMP(c, loc, SETUP_CLEANUP, cleanup_end); + + USE_LABEL(c, cleanup_body); + RETURN_IF_ERROR( + compiler_push_fblock(c, loc, HANDLER_CLEANUP, cleanup_body, + NO_LABEL, handler->v.ExceptHandler.name)); /* second # body */ VISIT_SEQ(c, stmt, handler->v.ExceptHandler.body); compiler_pop_fblock(c, HANDLER_CLEANUP, cleanup_body); /* name = None; del name; # Mark as artificial */ - UNSET_LOC(c); - ADDOP(c, POP_BLOCK); - ADDOP(c, POP_BLOCK); - ADDOP(c, POP_EXCEPT); - ADDOP_LOAD_CONST(c, Py_None); - compiler_nameop(c, handler->v.ExceptHandler.name, Store); - compiler_nameop(c, handler->v.ExceptHandler.name, Del); - ADDOP_JUMP(c, JUMP, end); + ADDOP(c, NO_LOCATION, POP_BLOCK); + ADDOP(c, NO_LOCATION, POP_BLOCK); + ADDOP(c, NO_LOCATION, POP_EXCEPT); + ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None); + RETURN_IF_ERROR( + compiler_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Store)); + RETURN_IF_ERROR( + compiler_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Del)); + ADDOP_JUMP(c, NO_LOCATION, JUMP, end); /* except: */ - compiler_use_next_block(c, cleanup_end); + USE_LABEL(c, cleanup_end); - /* name = None; del name; # Mark as artificial */ - UNSET_LOC(c); - - ADDOP_LOAD_CONST(c, Py_None); - compiler_nameop(c, handler->v.ExceptHandler.name, Store); - compiler_nameop(c, handler->v.ExceptHandler.name, Del); + /* name = None; del name; # artificial */ + ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None); + RETURN_IF_ERROR( + compiler_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Store)); + RETURN_IF_ERROR( + compiler_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Del)); - ADDOP_I(c, RERAISE, 1); + ADDOP_I(c, NO_LOCATION, RERAISE, 1); } else { - basicblock *cleanup_body; + NEW_JUMP_TARGET_LABEL(c, cleanup_body); - cleanup_body = compiler_new_block(c); - if (!cleanup_body) - return 0; + ADDOP(c, loc, POP_TOP); /* exc_value */ + + USE_LABEL(c, cleanup_body); + RETURN_IF_ERROR( + compiler_push_fblock(c, loc, HANDLER_CLEANUP, cleanup_body, + NO_LABEL, NULL)); - ADDOP(c, POP_TOP); /* exc_value */ - compiler_use_next_block(c, cleanup_body); - if (!compiler_push_fblock(c, HANDLER_CLEANUP, cleanup_body, NULL, NULL)) - return 0; VISIT_SEQ(c, stmt, handler->v.ExceptHandler.body); compiler_pop_fblock(c, HANDLER_CLEANUP, cleanup_body); - UNSET_LOC(c); - ADDOP(c, POP_BLOCK); - ADDOP(c, POP_EXCEPT); - ADDOP_JUMP(c, JUMP, end); - } - compiler_use_next_block(c, except); - } - /* Mark as artificial */ - UNSET_LOC(c); - compiler_pop_fblock(c, EXCEPTION_HANDLER, NULL); - ADDOP_I(c, RERAISE, 0); - compiler_use_next_block(c, cleanup); - POP_EXCEPT_AND_RERAISE(c); - compiler_use_next_block(c, end); - return 1; + ADDOP(c, NO_LOCATION, POP_BLOCK); + ADDOP(c, NO_LOCATION, POP_EXCEPT); + ADDOP_JUMP(c, NO_LOCATION, JUMP, end); + } + + USE_LABEL(c, except); + } + /* artificial */ + compiler_pop_fblock(c, EXCEPTION_HANDLER, NO_LABEL); + ADDOP_I(c, NO_LOCATION, RERAISE, 0); + + USE_LABEL(c, cleanup); + POP_EXCEPT_AND_RERAISE(c, NO_LOCATION); + + USE_LABEL(c, end); + return SUCCESS; } /* @@ -3607,18 +3486,15 @@ compiler_try_except(struct compiler *c, stmt_ty s) [] POP_BLOCK [] JUMP L0 - [exc] L1: COPY 1 ) save copy of the original exception - [orig, exc] BUILD_LIST ) list for raised/reraised excs ("result") - [orig, exc, res] SWAP 2 + [exc] L1: BUILD_LIST ) list for raised/reraised excs ("result") + [orig, res] COPY 2 ) make a copy of the original EG [orig, res, exc] <evaluate E1> [orig, res, exc, E1] CHECK_EG_MATCH - [orig, red, rest/exc, match?] COPY 1 - [orig, red, rest/exc, match?, match?] POP_JUMP_IF_NOT_NONE H1 - [orig, red, exc, None] POP_TOP - [orig, red, exc] JUMP L2 + [orig, res, rest/exc, match?] COPY 1 + [orig, res, rest/exc, match?, match?] POP_JUMP_IF_NONE C1 - [orig, res, rest, match] H1: <assign to V1> (or POP if no V1) + [orig, res, rest, match] <assign to V1> (or POP if no V1) [orig, res, rest] SETUP_FINALLY R1 [orig, res, rest] <code for S1> @@ -3626,13 +3502,19 @@ compiler_try_except(struct compiler *c, stmt_ty s) [orig, res, rest, i, v] R1: LIST_APPEND 3 ) exc raised in except* body - add to res [orig, res, rest, i] POP + [orig, res, rest] JUMP LE2 + + [orig, res, rest] L2: NOP ) for lineno + [orig, res, rest] JUMP LE2 - [orig, res, rest] L2: <evaluate E2> + [orig, res, rest/exc, None] C1: POP + + [orig, res, rest] LE2: <evaluate E2> .............................etc....................... [orig, res, rest] Ln+1: LIST_APPEND 1 ) add unhandled exc to res (could be None) - [orig, res] PREP_RERAISE_STAR + [orig, res] CALL_INTRINSIC_2 PREP_RERAISE_STAR [exc] COPY 1 [exc, exc] POP_JUMP_IF_NOT_NONE RER [exc] POP_TOP @@ -3647,105 +3529,73 @@ compiler_try_except(struct compiler *c, stmt_ty s) static int compiler_try_star_except(struct compiler *c, stmt_ty s) { - basicblock *body = compiler_new_block(c); - if (body == NULL) { - return 0; - } - basicblock *except = compiler_new_block(c); - if (except == NULL) { - return 0; - } - basicblock *orelse = compiler_new_block(c); - if (orelse == NULL) { - return 0; - } - basicblock *end = compiler_new_block(c); - if (end == NULL) { - return 0; - } - basicblock *cleanup = compiler_new_block(c); - if (cleanup == NULL) { - return 0; - } - basicblock *reraise_star = compiler_new_block(c); - if (reraise_star == NULL) { - return 0; - } + location loc = LOC(s); - ADDOP_JUMP(c, SETUP_FINALLY, except); - compiler_use_next_block(c, body); - if (!compiler_push_fblock(c, TRY_EXCEPT, body, NULL, NULL)) { - return 0; - } + NEW_JUMP_TARGET_LABEL(c, body); + NEW_JUMP_TARGET_LABEL(c, except); + NEW_JUMP_TARGET_LABEL(c, orelse); + NEW_JUMP_TARGET_LABEL(c, end); + NEW_JUMP_TARGET_LABEL(c, cleanup); + NEW_JUMP_TARGET_LABEL(c, reraise_star); + + ADDOP_JUMP(c, loc, SETUP_FINALLY, except); + + USE_LABEL(c, body); + RETURN_IF_ERROR( + compiler_push_fblock(c, loc, TRY_EXCEPT, body, NO_LABEL, NULL)); VISIT_SEQ(c, stmt, s->v.TryStar.body); compiler_pop_fblock(c, TRY_EXCEPT, body); - ADDOP_NOLINE(c, POP_BLOCK); - ADDOP_JUMP_NOLINE(c, JUMP, orelse); + ADDOP(c, NO_LOCATION, POP_BLOCK); + ADDOP_JUMP(c, NO_LOCATION, JUMP, orelse); Py_ssize_t n = asdl_seq_LEN(s->v.TryStar.handlers); - compiler_use_next_block(c, except); - UNSET_LOC(c); - ADDOP_JUMP(c, SETUP_CLEANUP, cleanup); - ADDOP(c, PUSH_EXC_INFO); + USE_LABEL(c, except); + + ADDOP_JUMP(c, NO_LOCATION, SETUP_CLEANUP, cleanup); + ADDOP(c, NO_LOCATION, PUSH_EXC_INFO); + /* Runtime will push a block here, so we need to account for that */ - if (!compiler_push_fblock(c, EXCEPTION_GROUP_HANDLER, - NULL, NULL, "except handler")) { - return 0; - } + RETURN_IF_ERROR( + compiler_push_fblock(c, loc, EXCEPTION_GROUP_HANDLER, + NO_LABEL, NO_LABEL, "except handler")); + for (Py_ssize_t i = 0; i < n; i++) { excepthandler_ty handler = (excepthandler_ty)asdl_seq_GET( s->v.TryStar.handlers, i); - SET_LOC(c, handler); - except = compiler_new_block(c); - if (except == NULL) { - return 0; - } - basicblock *handle_match = compiler_new_block(c); - if (handle_match == NULL) { - return 0; - } + location loc = LOC(handler); + NEW_JUMP_TARGET_LABEL(c, next_except); + except = next_except; + NEW_JUMP_TARGET_LABEL(c, except_with_error); + NEW_JUMP_TARGET_LABEL(c, no_match); if (i == 0) { - /* Push the original EG into the stack */ + /* create empty list for exceptions raised/reraise in the except* blocks */ /* - [exc] COPY 1 - [orig, exc] + [orig] BUILD_LIST */ - ADDOP_I(c, COPY, 1); - - /* create empty list for exceptions raised/reraise in the except* blocks */ + /* Create a copy of the original EG */ /* - [orig, exc] BUILD_LIST - [orig, exc, []] SWAP 2 + [orig, []] COPY 2 [orig, [], exc] */ - ADDOP_I(c, BUILD_LIST, 0); - ADDOP_I(c, SWAP, 2); + ADDOP_I(c, loc, BUILD_LIST, 0); + ADDOP_I(c, loc, COPY, 2); } if (handler->v.ExceptHandler.type) { VISIT(c, expr, handler->v.ExceptHandler.type); - ADDOP(c, CHECK_EG_MATCH); - ADDOP_I(c, COPY, 1); - ADDOP_JUMP(c, POP_JUMP_IF_NOT_NONE, handle_match); - ADDOP(c, POP_TOP); // match - ADDOP_JUMP(c, JUMP, except); + ADDOP(c, loc, CHECK_EG_MATCH); + ADDOP_I(c, loc, COPY, 1); + ADDOP_JUMP(c, loc, POP_JUMP_IF_NONE, no_match); } - compiler_use_next_block(c, handle_match); - - basicblock *cleanup_end = compiler_new_block(c); - if (cleanup_end == NULL) { - return 0; - } - basicblock *cleanup_body = compiler_new_block(c); - if (cleanup_body == NULL) { - return 0; - } + NEW_JUMP_TARGET_LABEL(c, cleanup_end); + NEW_JUMP_TARGET_LABEL(c, cleanup_body); if (handler->v.ExceptHandler.name) { - compiler_nameop(c, handler->v.ExceptHandler.name, Store); + RETURN_IF_ERROR( + compiler_nameop(c, loc, handler->v.ExceptHandler.name, Store)); } else { - ADDOP(c, POP_TOP); // match + ADDOP(c, loc, POP_TOP); // match } /* @@ -3759,78 +3609,88 @@ compiler_try_star_except(struct compiler *c, stmt_ty s) del name */ /* second try: */ - ADDOP_JUMP(c, SETUP_CLEANUP, cleanup_end); - compiler_use_next_block(c, cleanup_body); - if (!compiler_push_fblock(c, HANDLER_CLEANUP, cleanup_body, NULL, handler->v.ExceptHandler.name)) - return 0; + ADDOP_JUMP(c, loc, SETUP_CLEANUP, cleanup_end); + + USE_LABEL(c, cleanup_body); + RETURN_IF_ERROR( + compiler_push_fblock(c, loc, HANDLER_CLEANUP, cleanup_body, + NO_LABEL, handler->v.ExceptHandler.name)); /* second # body */ VISIT_SEQ(c, stmt, handler->v.ExceptHandler.body); compiler_pop_fblock(c, HANDLER_CLEANUP, cleanup_body); - /* name = None; del name; # Mark as artificial */ - UNSET_LOC(c); - ADDOP(c, POP_BLOCK); + /* name = None; del name; # artificial */ + ADDOP(c, NO_LOCATION, POP_BLOCK); if (handler->v.ExceptHandler.name) { - ADDOP_LOAD_CONST(c, Py_None); - compiler_nameop(c, handler->v.ExceptHandler.name, Store); - compiler_nameop(c, handler->v.ExceptHandler.name, Del); + ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None); + RETURN_IF_ERROR( + compiler_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Store)); + RETURN_IF_ERROR( + compiler_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Del)); } - ADDOP_JUMP(c, JUMP, except); + ADDOP_JUMP(c, NO_LOCATION, JUMP, except); /* except: */ - compiler_use_next_block(c, cleanup_end); - - /* name = None; del name; # Mark as artificial */ - UNSET_LOC(c); + USE_LABEL(c, cleanup_end); + /* name = None; del name; # artificial */ if (handler->v.ExceptHandler.name) { - ADDOP_LOAD_CONST(c, Py_None); - compiler_nameop(c, handler->v.ExceptHandler.name, Store); - compiler_nameop(c, handler->v.ExceptHandler.name, Del); + ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None); + RETURN_IF_ERROR( + compiler_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Store)); + RETURN_IF_ERROR( + compiler_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Del)); } /* add exception raised to the res list */ - ADDOP_I(c, LIST_APPEND, 3); // exc - ADDOP(c, POP_TOP); // lasti + ADDOP_I(c, NO_LOCATION, LIST_APPEND, 3); // exc + ADDOP(c, NO_LOCATION, POP_TOP); // lasti + ADDOP_JUMP(c, NO_LOCATION, JUMP, except_with_error); + + USE_LABEL(c, except); + ADDOP(c, NO_LOCATION, NOP); // to hold a propagated location info + ADDOP_JUMP(c, NO_LOCATION, JUMP, except_with_error); - ADDOP_JUMP(c, JUMP, except); - compiler_use_next_block(c, except); + USE_LABEL(c, no_match); + ADDOP(c, loc, POP_TOP); // match (None) + + USE_LABEL(c, except_with_error); if (i == n - 1) { /* Add exc to the list (if not None it's the unhandled part of the EG) */ - ADDOP_I(c, LIST_APPEND, 1); - ADDOP_JUMP(c, JUMP, reraise_star); + ADDOP_I(c, NO_LOCATION, LIST_APPEND, 1); + ADDOP_JUMP(c, NO_LOCATION, JUMP, reraise_star); } } - /* Mark as artificial */ - UNSET_LOC(c); - compiler_pop_fblock(c, EXCEPTION_GROUP_HANDLER, NULL); - basicblock *reraise = compiler_new_block(c); - if (!reraise) { - return 0; - } + /* artificial */ + compiler_pop_fblock(c, EXCEPTION_GROUP_HANDLER, NO_LABEL); + NEW_JUMP_TARGET_LABEL(c, reraise); - compiler_use_next_block(c, reraise_star); - ADDOP(c, PREP_RERAISE_STAR); - ADDOP_I(c, COPY, 1); - ADDOP_JUMP(c, POP_JUMP_IF_NOT_NONE, reraise); + USE_LABEL(c, reraise_star); + ADDOP_I(c, NO_LOCATION, CALL_INTRINSIC_2, INTRINSIC_PREP_RERAISE_STAR); + ADDOP_I(c, NO_LOCATION, COPY, 1); + ADDOP_JUMP(c, NO_LOCATION, POP_JUMP_IF_NOT_NONE, reraise); /* Nothing to reraise */ - ADDOP(c, POP_TOP); - ADDOP(c, POP_BLOCK); - ADDOP(c, POP_EXCEPT); - ADDOP_JUMP(c, JUMP, end); - compiler_use_next_block(c, reraise); - ADDOP(c, POP_BLOCK); - ADDOP_I(c, SWAP, 2); - ADDOP(c, POP_EXCEPT); - ADDOP_I(c, RERAISE, 0); - compiler_use_next_block(c, cleanup); - POP_EXCEPT_AND_RERAISE(c); - compiler_use_next_block(c, orelse); + ADDOP(c, NO_LOCATION, POP_TOP); + ADDOP(c, NO_LOCATION, POP_BLOCK); + ADDOP(c, NO_LOCATION, POP_EXCEPT); + ADDOP_JUMP(c, NO_LOCATION, JUMP, end); + + USE_LABEL(c, reraise); + ADDOP(c, NO_LOCATION, POP_BLOCK); + ADDOP_I(c, NO_LOCATION, SWAP, 2); + ADDOP(c, NO_LOCATION, POP_EXCEPT); + ADDOP_I(c, NO_LOCATION, RERAISE, 0); + + USE_LABEL(c, cleanup); + POP_EXCEPT_AND_RERAISE(c, NO_LOCATION); + + USE_LABEL(c, orelse); VISIT_SEQ(c, stmt, s->v.TryStar.orelse); - compiler_use_next_block(c, end); - return 1; + + USE_LABEL(c, end); + return SUCCESS; } static int @@ -3853,7 +3713,8 @@ compiler_try_star(struct compiler *c, stmt_ty s) } static int -compiler_import_as(struct compiler *c, identifier name, identifier asname) +compiler_import_as(struct compiler *c, location loc, + identifier name, identifier asname) { /* The IMPORT_NAME opcode was already generated. This function merely needs to bind the result to a name. @@ -3863,38 +3724,40 @@ compiler_import_as(struct compiler *c, identifier name, identifier asname) */ Py_ssize_t len = PyUnicode_GET_LENGTH(name); Py_ssize_t dot = PyUnicode_FindChar(name, '.', 0, len, 1); - if (dot == -2) - return 0; + if (dot == -2) { + return ERROR; + } if (dot != -1) { /* Consume the base module name to get the first attribute */ while (1) { Py_ssize_t pos = dot + 1; PyObject *attr; dot = PyUnicode_FindChar(name, '.', pos, len, 1); - if (dot == -2) - return 0; + if (dot == -2) { + return ERROR; + } attr = PyUnicode_Substring(name, pos, (dot != -1) ? dot : len); - if (!attr) - return 0; - ADDOP_N(c, IMPORT_FROM, attr, names); + if (!attr) { + return ERROR; + } + ADDOP_N(c, loc, IMPORT_FROM, attr, names); if (dot == -1) { break; } - ADDOP_I(c, SWAP, 2); - ADDOP(c, POP_TOP); + ADDOP_I(c, loc, SWAP, 2); + ADDOP(c, loc, POP_TOP); } - if (!compiler_nameop(c, asname, Store)) { - return 0; - } - ADDOP(c, POP_TOP); - return 1; + RETURN_IF_ERROR(compiler_nameop(c, loc, asname, Store)); + ADDOP(c, loc, POP_TOP); + return SUCCESS; } - return compiler_nameop(c, asname, Store); + return compiler_nameop(c, loc, asname, Store); } static int compiler_import(struct compiler *c, stmt_ty s) { + location loc = LOC(s); /* The Import node stores a module name like a.b.c as a single string. This is convenient for all cases except import a.b.c as d @@ -3909,14 +3772,13 @@ compiler_import(struct compiler *c, stmt_ty s) alias_ty alias = (alias_ty)asdl_seq_GET(s->v.Import.names, i); int r; - ADDOP_LOAD_CONST(c, zero); - ADDOP_LOAD_CONST(c, Py_None); - ADDOP_NAME(c, IMPORT_NAME, alias->name, names); + ADDOP_LOAD_CONST(c, loc, zero); + ADDOP_LOAD_CONST(c, loc, Py_None); + ADDOP_NAME(c, loc, IMPORT_NAME, alias->name, names); if (alias->asname) { - r = compiler_import_as(c, alias->name, alias->asname); - if (!r) - return r; + r = compiler_import_as(c, loc, alias->name, alias->asname); + RETURN_IF_ERROR(r); } else { identifier tmp = alias->name; @@ -3924,83 +3786,82 @@ compiler_import(struct compiler *c, stmt_ty s) alias->name, '.', 0, PyUnicode_GET_LENGTH(alias->name), 1); if (dot != -1) { tmp = PyUnicode_Substring(alias->name, 0, dot); - if (tmp == NULL) - return 0; + if (tmp == NULL) { + return ERROR; + } } - r = compiler_nameop(c, tmp, Store); + r = compiler_nameop(c, loc, tmp, Store); if (dot != -1) { Py_DECREF(tmp); } - if (!r) - return r; + RETURN_IF_ERROR(r); } } - return 1; + return SUCCESS; } static int compiler_from_import(struct compiler *c, stmt_ty s) { - Py_ssize_t i, n = asdl_seq_LEN(s->v.ImportFrom.names); - PyObject *names; + Py_ssize_t n = asdl_seq_LEN(s->v.ImportFrom.names); - ADDOP_LOAD_CONST_NEW(c, PyLong_FromLong(s->v.ImportFrom.level)); + ADDOP_LOAD_CONST_NEW(c, LOC(s), PyLong_FromLong(s->v.ImportFrom.level)); - names = PyTuple_New(n); - if (!names) - return 0; + PyObject *names = PyTuple_New(n); + if (!names) { + return ERROR; + } /* build up the names */ - for (i = 0; i < n; i++) { + for (Py_ssize_t i = 0; i < n; i++) { alias_ty alias = (alias_ty)asdl_seq_GET(s->v.ImportFrom.names, i); - Py_INCREF(alias->name); - PyTuple_SET_ITEM(names, i, alias->name); + PyTuple_SET_ITEM(names, i, Py_NewRef(alias->name)); } - if (s->lineno > c->c_future->ff_lineno && s->v.ImportFrom.module && - _PyUnicode_EqualToASCIIString(s->v.ImportFrom.module, "__future__")) { + if (location_is_after(LOC(s), c->c_future.ff_location) && + s->v.ImportFrom.module && + _PyUnicode_EqualToASCIIString(s->v.ImportFrom.module, "__future__")) + { Py_DECREF(names); - return compiler_error(c, "from __future__ imports must occur " + return compiler_error(c, LOC(s), "from __future__ imports must occur " "at the beginning of the file"); } - ADDOP_LOAD_CONST_NEW(c, names); + ADDOP_LOAD_CONST_NEW(c, LOC(s), names); if (s->v.ImportFrom.module) { - ADDOP_NAME(c, IMPORT_NAME, s->v.ImportFrom.module, names); + ADDOP_NAME(c, LOC(s), IMPORT_NAME, s->v.ImportFrom.module, names); } else { _Py_DECLARE_STR(empty, ""); - ADDOP_NAME(c, IMPORT_NAME, &_Py_STR(empty), names); + ADDOP_NAME(c, LOC(s), IMPORT_NAME, &_Py_STR(empty), names); } - for (i = 0; i < n; i++) { + for (Py_ssize_t i = 0; i < n; i++) { alias_ty alias = (alias_ty)asdl_seq_GET(s->v.ImportFrom.names, i); identifier store_name; if (i == 0 && PyUnicode_READ_CHAR(alias->name, 0) == '*') { assert(n == 1); - ADDOP(c, IMPORT_STAR); - return 1; + ADDOP_I(c, LOC(s), CALL_INTRINSIC_1, INTRINSIC_IMPORT_STAR); + ADDOP(c, NO_LOCATION, POP_TOP); + return SUCCESS; } - ADDOP_NAME(c, IMPORT_FROM, alias->name, names); + ADDOP_NAME(c, LOC(s), IMPORT_FROM, alias->name, names); store_name = alias->name; - if (alias->asname) + if (alias->asname) { store_name = alias->asname; - - if (!compiler_nameop(c, store_name, Store)) { - return 0; } + + RETURN_IF_ERROR(compiler_nameop(c, LOC(s), store_name, Store)); } /* remove imported module */ - ADDOP(c, POP_TOP); - return 1; + ADDOP(c, LOC(s), POP_TOP); + return SUCCESS; } static int compiler_assert(struct compiler *c, stmt_ty s) { - basicblock *end; - /* Always emit a warning if the test is a non-zero length tuple */ if ((s->v.Assert.test->kind == Tuple_kind && asdl_seq_LEN(s->v.Assert.test->v.Tuple.elts) > 0) || @@ -4008,81 +3869,76 @@ compiler_assert(struct compiler *c, stmt_ty s) PyTuple_Check(s->v.Assert.test->v.Constant.value) && PyTuple_Size(s->v.Assert.test->v.Constant.value) > 0)) { - if (!compiler_warn(c, "assertion is always true, " - "perhaps remove parentheses?")) - { - return 0; - } + RETURN_IF_ERROR( + compiler_warn(c, LOC(s), "assertion is always true, " + "perhaps remove parentheses?")); } - if (c->c_optimize) - return 1; - end = compiler_new_block(c); - if (end == NULL) - return 0; - if (!compiler_jump_if(c, s->v.Assert.test, end, 1)) - return 0; - ADDOP(c, LOAD_ASSERTION_ERROR); + if (c->c_optimize) { + return SUCCESS; + } + NEW_JUMP_TARGET_LABEL(c, end); + RETURN_IF_ERROR(compiler_jump_if(c, LOC(s), s->v.Assert.test, end, 1)); + ADDOP(c, LOC(s), LOAD_ASSERTION_ERROR); if (s->v.Assert.msg) { VISIT(c, expr, s->v.Assert.msg); - ADDOP_I(c, PRECALL, 0); - ADDOP_I(c, CALL, 0); + ADDOP_I(c, LOC(s), CALL, 0); } - ADDOP_I(c, RAISE_VARARGS, 1); - compiler_use_next_block(c, end); - return 1; + ADDOP_I(c, LOC(s), RAISE_VARARGS, 1); + + USE_LABEL(c, end); + return SUCCESS; } static int -compiler_visit_stmt_expr(struct compiler *c, expr_ty value) +compiler_stmt_expr(struct compiler *c, location loc, expr_ty value) { if (c->c_interactive && c->c_nestlevel <= 1) { VISIT(c, expr, value); - ADDOP(c, PRINT_EXPR); - return 1; + ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_PRINT); + ADDOP(c, NO_LOCATION, POP_TOP); + return SUCCESS; } if (value->kind == Constant_kind) { /* ignore constant statement */ - ADDOP(c, NOP); - return 1; + ADDOP(c, loc, NOP); + return SUCCESS; } VISIT(c, expr, value); - /* Mark POP_TOP as artificial */ - UNSET_LOC(c); - ADDOP(c, POP_TOP); - return 1; + ADDOP(c, NO_LOCATION, POP_TOP); /* artificial */ + return SUCCESS; } static int compiler_visit_stmt(struct compiler *c, stmt_ty s) { - Py_ssize_t i, n; - - /* Always assign a lineno to the next instruction for a stmt. */ - SET_LOC(c, s); switch (s->kind) { case FunctionDef_kind: return compiler_function(c, s, 0); case ClassDef_kind: return compiler_class(c, s); + case TypeAlias_kind: + return compiler_typealias(c, s); case Return_kind: return compiler_return(c, s); case Delete_kind: VISIT_SEQ(c, expr, s->v.Delete.targets) break; case Assign_kind: - n = asdl_seq_LEN(s->v.Assign.targets); + { + Py_ssize_t n = asdl_seq_LEN(s->v.Assign.targets); VISIT(c, expr, s->v.Assign.value); - for (i = 0; i < n; i++) { + for (Py_ssize_t i = 0; i < n; i++) { if (i < n - 1) { - ADDOP_I(c, COPY, 1); + ADDOP_I(c, LOC(s), COPY, 1); } VISIT(c, expr, (expr_ty)asdl_seq_GET(s->v.Assign.targets, i)); } break; + } case AugAssign_kind: return compiler_augassign(c, s); case AnnAssign_kind: @@ -4096,7 +3952,8 @@ compiler_visit_stmt(struct compiler *c, stmt_ty s) case Match_kind: return compiler_match(c, s); case Raise_kind: - n = 0; + { + Py_ssize_t n = 0; if (s->v.Raise.exc) { VISIT(c, expr, s->v.Raise.exc); n++; @@ -4105,8 +3962,9 @@ compiler_visit_stmt(struct compiler *c, stmt_ty s) n++; } } - ADDOP_I(c, RAISE_VARARGS, (int)n); + ADDOP_I(c, LOC(s), RAISE_VARARGS, (int)n); break; + } case Try_kind: return compiler_try(c, s); case TryStar_kind: @@ -4121,14 +3979,22 @@ compiler_visit_stmt(struct compiler *c, stmt_ty s) case Nonlocal_kind: break; case Expr_kind: - return compiler_visit_stmt_expr(c, s->v.Expr.value); + { + return compiler_stmt_expr(c, LOC(s), s->v.Expr.value); + } case Pass_kind: - ADDOP(c, NOP); + { + ADDOP(c, LOC(s), NOP); break; + } case Break_kind: - return compiler_break(c); + { + return compiler_break(c, LOC(s)); + } case Continue_kind: - return compiler_continue(c); + { + return compiler_continue(c, LOC(s)); + } case With_kind: return compiler_with(c, s, 0); case AsyncFunctionDef_kind: @@ -4139,7 +4005,7 @@ compiler_visit_stmt(struct compiler *c, stmt_ty s) return compiler_async_for(c, s); } - return 1; + return SUCCESS; } static int @@ -4150,8 +4016,6 @@ unaryop(unaryop_ty op) return UNARY_INVERT; case Not: return UNARY_NOT; - case UAdd: - return UNARY_POSITIVE; case USub: return UNARY_NEGATIVE; default: @@ -4162,7 +4026,8 @@ unaryop(unaryop_ty op) } static int -addop_binary(struct compiler *c, operator_ty binop, bool inplace) +addop_binary(struct compiler *c, location loc, operator_ty binop, + bool inplace) { int oparg; switch (binop) { @@ -4208,62 +4073,66 @@ addop_binary(struct compiler *c, operator_ty binop, bool inplace) default: PyErr_Format(PyExc_SystemError, "%s op %d should not be possible", inplace ? "inplace" : "binary", binop); - return 0; + return ERROR; } - ADDOP_I(c, BINARY_OP, oparg); - return 1; + ADDOP_I(c, loc, BINARY_OP, oparg); + return SUCCESS; } static int -addop_yield(struct compiler *c) { +addop_yield(struct compiler *c, location loc) { if (c->u->u_ste->ste_generator && c->u->u_ste->ste_coroutine) { - ADDOP(c, ASYNC_GEN_WRAP); + ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_ASYNC_GEN_WRAP); } - ADDOP(c, YIELD_VALUE); - ADDOP_I(c, RESUME, 1); - return 1; + ADDOP_I(c, loc, YIELD_VALUE, 0); + ADDOP_I(c, loc, RESUME, 1); + return SUCCESS; } static int -compiler_nameop(struct compiler *c, identifier name, expr_context_ty ctx) +compiler_nameop(struct compiler *c, location loc, + identifier name, expr_context_ty ctx) { int op, scope; Py_ssize_t arg; enum { OP_FAST, OP_GLOBAL, OP_DEREF, OP_NAME } optype; - PyObject *dict = c->u->u_names; + PyObject *dict = c->u->u_metadata.u_names; PyObject *mangled; assert(!_PyUnicode_EqualToASCIIString(name, "None") && !_PyUnicode_EqualToASCIIString(name, "True") && !_PyUnicode_EqualToASCIIString(name, "False")); - if (forbidden_name(c, name, ctx)) - return 0; + if (forbidden_name(c, loc, name, ctx)) { + return ERROR; + } mangled = _Py_Mangle(c->u->u_private, name); - if (!mangled) - return 0; + if (!mangled) { + return ERROR; + } op = 0; optype = OP_NAME; scope = _PyST_GetScope(c->u->u_ste, mangled); switch (scope) { case FREE: - dict = c->u->u_freevars; + dict = c->u->u_metadata.u_freevars; optype = OP_DEREF; break; case CELL: - dict = c->u->u_cellvars; + dict = c->u->u_metadata.u_cellvars; optype = OP_DEREF; break; case LOCAL: - if (c->u->u_ste->ste_type == FunctionBlock) + if (_PyST_IsFunctionLike(c->u->u_ste) || + (PyDict_GetItem(c->u->u_metadata.u_fasthidden, mangled) == Py_True)) optype = OP_FAST; break; case GLOBAL_IMPLICIT: - if (c->u->u_ste->ste_type == FunctionBlock) + if (_PyST_IsFunctionLike(c->u->u_ste)) optype = OP_GLOBAL; break; case GLOBAL_EXPLICIT: @@ -4281,7 +4150,24 @@ compiler_nameop(struct compiler *c, identifier name, expr_context_ty ctx) case OP_DEREF: switch (ctx) { case Load: - op = (c->u->u_ste->ste_type == ClassBlock) ? LOAD_CLASSDEREF : LOAD_DEREF; + if (c->u->u_ste->ste_type == ClassBlock && !c->u->u_in_inlined_comp) { + op = LOAD_FROM_DICT_OR_DEREF; + // First load the locals + if (codegen_addop_noarg(INSTR_SEQUENCE(c), LOAD_LOCALS, loc) < 0) { + return ERROR; + } + } + else if (c->u->u_ste->ste_can_see_class_scope) { + op = LOAD_FROM_DICT_OR_DEREF; + // First load the classdict + if (compiler_addop_o(c->u, loc, LOAD_DEREF, + c->u->u_metadata.u_freevars, &_Py_ID(__classdict__)) < 0) { + return ERROR; + } + } + else { + op = LOAD_DEREF; + } break; case Store: op = STORE_DEREF; break; case Del: op = DELETE_DEREF; break; @@ -4293,18 +4179,34 @@ compiler_nameop(struct compiler *c, identifier name, expr_context_ty ctx) case Store: op = STORE_FAST; break; case Del: op = DELETE_FAST; break; } - ADDOP_N(c, op, mangled, varnames); - return 1; + ADDOP_N(c, loc, op, mangled, varnames); + return SUCCESS; case OP_GLOBAL: switch (ctx) { - case Load: op = LOAD_GLOBAL; break; + case Load: + if (c->u->u_ste->ste_can_see_class_scope && scope == GLOBAL_IMPLICIT) { + op = LOAD_FROM_DICT_OR_GLOBALS; + // First load the classdict + if (compiler_addop_o(c->u, loc, LOAD_DEREF, + c->u->u_metadata.u_freevars, &_Py_ID(__classdict__)) < 0) { + return ERROR; + } + } else { + op = LOAD_GLOBAL; + } + break; case Store: op = STORE_GLOBAL; break; case Del: op = DELETE_GLOBAL; break; } break; case OP_NAME: switch (ctx) { - case Load: op = LOAD_NAME; break; + case Load: + op = (c->u->u_ste->ste_type == ClassBlock + && c->u->u_in_inlined_comp) + ? LOAD_GLOBAL + : LOAD_NAME; + break; case Store: op = STORE_NAME; break; case Del: op = DELETE_NAME; break; } @@ -4312,83 +4214,79 @@ compiler_nameop(struct compiler *c, identifier name, expr_context_ty ctx) } assert(op); - arg = compiler_add_o(dict, mangled); + arg = dict_add_o(dict, mangled); Py_DECREF(mangled); if (arg < 0) { - return 0; + return ERROR; } if (op == LOAD_GLOBAL) { arg <<= 1; } - return compiler_addop_i(c, op, arg); + return codegen_addop_i(INSTR_SEQUENCE(c), op, arg, loc); } static int compiler_boolop(struct compiler *c, expr_ty e) { - basicblock *end; int jumpi; Py_ssize_t i, n; asdl_expr_seq *s; + location loc = LOC(e); assert(e->kind == BoolOp_kind); if (e->v.BoolOp.op == And) - jumpi = JUMP_IF_FALSE_OR_POP; + jumpi = POP_JUMP_IF_FALSE; else - jumpi = JUMP_IF_TRUE_OR_POP; - end = compiler_new_block(c); - if (end == NULL) - return 0; + jumpi = POP_JUMP_IF_TRUE; + NEW_JUMP_TARGET_LABEL(c, end); s = e->v.BoolOp.values; n = asdl_seq_LEN(s) - 1; assert(n >= 0); for (i = 0; i < n; ++i) { VISIT(c, expr, (expr_ty)asdl_seq_GET(s, i)); - ADDOP_JUMP(c, jumpi, end); - basicblock *next = compiler_new_block(c); - if (next == NULL) { - return 0; - } - compiler_use_next_block(c, next); + ADDOP_I(c, loc, COPY, 1); + ADDOP_JUMP(c, loc, jumpi, end); + ADDOP(c, loc, POP_TOP); } VISIT(c, expr, (expr_ty)asdl_seq_GET(s, n)); - compiler_use_next_block(c, end); - return 1; + + USE_LABEL(c, end); + return SUCCESS; } static int -starunpack_helper(struct compiler *c, asdl_expr_seq *elts, int pushed, +starunpack_helper(struct compiler *c, location loc, + asdl_expr_seq *elts, int pushed, int build, int add, int extend, int tuple) { Py_ssize_t n = asdl_seq_LEN(elts); if (n > 2 && are_all_items_const(elts, 0, n)) { PyObject *folded = PyTuple_New(n); if (folded == NULL) { - return 0; + return ERROR; } PyObject *val; for (Py_ssize_t i = 0; i < n; i++) { val = ((expr_ty)asdl_seq_GET(elts, i))->v.Constant.value; - Py_INCREF(val); - PyTuple_SET_ITEM(folded, i, val); + PyTuple_SET_ITEM(folded, i, Py_NewRef(val)); } if (tuple && !pushed) { - ADDOP_LOAD_CONST_NEW(c, folded); + ADDOP_LOAD_CONST_NEW(c, loc, folded); } else { if (add == SET_ADD) { Py_SETREF(folded, PyFrozenSet_New(folded)); if (folded == NULL) { - return 0; + return ERROR; } } - ADDOP_I(c, build, pushed); - ADDOP_LOAD_CONST_NEW(c, folded); - ADDOP_I(c, extend, 1); + ADDOP_I(c, loc, build, pushed); + ADDOP_LOAD_CONST_NEW(c, loc, folded); + ADDOP_I(c, loc, extend, 1); if (tuple) { - ADDOP(c, LIST_TO_TUPLE); + ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_LIST_TO_TUPLE); } } - return 1; + return SUCCESS; } int big = n+pushed > STACK_USE_GUIDELINE; @@ -4397,6 +4295,7 @@ starunpack_helper(struct compiler *c, asdl_expr_seq *elts, int pushed, expr_ty elt = asdl_seq_GET(elts, i); if (elt->kind == Starred_kind) { seen_star = 1; + break; } } if (!seen_star && !big) { @@ -4405,43 +4304,43 @@ starunpack_helper(struct compiler *c, asdl_expr_seq *elts, int pushed, VISIT(c, expr, elt); } if (tuple) { - ADDOP_I(c, BUILD_TUPLE, n+pushed); + ADDOP_I(c, loc, BUILD_TUPLE, n+pushed); } else { - ADDOP_I(c, build, n+pushed); + ADDOP_I(c, loc, build, n+pushed); } - return 1; + return SUCCESS; } int sequence_built = 0; if (big) { - ADDOP_I(c, build, pushed); + ADDOP_I(c, loc, build, pushed); sequence_built = 1; } for (Py_ssize_t i = 0; i < n; i++) { expr_ty elt = asdl_seq_GET(elts, i); if (elt->kind == Starred_kind) { if (sequence_built == 0) { - ADDOP_I(c, build, i+pushed); + ADDOP_I(c, loc, build, i+pushed); sequence_built = 1; } VISIT(c, expr, elt->v.Starred.value); - ADDOP_I(c, extend, 1); + ADDOP_I(c, loc, extend, 1); } else { VISIT(c, expr, elt); if (sequence_built) { - ADDOP_I(c, add, 1); + ADDOP_I(c, loc, add, 1); } } } assert(sequence_built); if (tuple) { - ADDOP(c, LIST_TO_TUPLE); + ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_LIST_TO_TUPLE); } - return 1; + return SUCCESS; } static int -unpack_helper(struct compiler *c, asdl_expr_seq *elts) +unpack_helper(struct compiler *c, location loc, asdl_expr_seq *elts) { Py_ssize_t n = asdl_seq_LEN(elts); int seen_star = 0; @@ -4449,85 +4348,91 @@ unpack_helper(struct compiler *c, asdl_expr_seq *elts) expr_ty elt = asdl_seq_GET(elts, i); if (elt->kind == Starred_kind && !seen_star) { if ((i >= (1 << 8)) || - (n-i-1 >= (INT_MAX >> 8))) - return compiler_error(c, + (n-i-1 >= (INT_MAX >> 8))) { + return compiler_error(c, loc, "too many expressions in " "star-unpacking assignment"); - ADDOP_I(c, UNPACK_EX, (i + ((n-i-1) << 8))); + } + ADDOP_I(c, loc, UNPACK_EX, (i + ((n-i-1) << 8))); seen_star = 1; } else if (elt->kind == Starred_kind) { - return compiler_error(c, + return compiler_error(c, loc, "multiple starred expressions in assignment"); } } if (!seen_star) { - ADDOP_I(c, UNPACK_SEQUENCE, n); + ADDOP_I(c, loc, UNPACK_SEQUENCE, n); } - return 1; + return SUCCESS; } static int -assignment_helper(struct compiler *c, asdl_expr_seq *elts) +assignment_helper(struct compiler *c, location loc, asdl_expr_seq *elts) { Py_ssize_t n = asdl_seq_LEN(elts); - RETURN_IF_FALSE(unpack_helper(c, elts)); + RETURN_IF_ERROR(unpack_helper(c, loc, elts)); for (Py_ssize_t i = 0; i < n; i++) { expr_ty elt = asdl_seq_GET(elts, i); VISIT(c, expr, elt->kind != Starred_kind ? elt : elt->v.Starred.value); } - return 1; + return SUCCESS; } static int compiler_list(struct compiler *c, expr_ty e) { + location loc = LOC(e); asdl_expr_seq *elts = e->v.List.elts; if (e->v.List.ctx == Store) { - return assignment_helper(c, elts); + return assignment_helper(c, loc, elts); } else if (e->v.List.ctx == Load) { - return starunpack_helper(c, elts, 0, BUILD_LIST, - LIST_APPEND, LIST_EXTEND, 0); + return starunpack_helper(c, loc, elts, 0, + BUILD_LIST, LIST_APPEND, LIST_EXTEND, 0); } - else + else { VISIT_SEQ(c, expr, elts); - return 1; + } + return SUCCESS; } static int compiler_tuple(struct compiler *c, expr_ty e) { + location loc = LOC(e); asdl_expr_seq *elts = e->v.Tuple.elts; if (e->v.Tuple.ctx == Store) { - return assignment_helper(c, elts); + return assignment_helper(c, loc, elts); } else if (e->v.Tuple.ctx == Load) { - return starunpack_helper(c, elts, 0, BUILD_LIST, - LIST_APPEND, LIST_EXTEND, 1); + return starunpack_helper(c, loc, elts, 0, + BUILD_LIST, LIST_APPEND, LIST_EXTEND, 1); } - else + else { VISIT_SEQ(c, expr, elts); - return 1; + } + return SUCCESS; } static int compiler_set(struct compiler *c, expr_ty e) { - return starunpack_helper(c, e->v.Set.elts, 0, BUILD_SET, - SET_ADD, SET_UPDATE, 0); + location loc = LOC(e); + return starunpack_helper(c, loc, e->v.Set.elts, 0, + BUILD_SET, SET_ADD, SET_UPDATE, 0); } -static int +static bool are_all_items_const(asdl_expr_seq *seq, Py_ssize_t begin, Py_ssize_t end) { - Py_ssize_t i; - for (i = begin; i < end; i++) { + for (Py_ssize_t i = begin; i < end; i++) { expr_ty key = (expr_ty)asdl_seq_GET(seq, i); - if (key == NULL || key->kind != Constant_kind) - return 0; + if (key == NULL || key->kind != Constant_kind) { + return false; + } } - return 1; + return true; } static int @@ -4536,42 +4441,43 @@ compiler_subdict(struct compiler *c, expr_ty e, Py_ssize_t begin, Py_ssize_t end Py_ssize_t i, n = end - begin; PyObject *keys, *key; int big = n*2 > STACK_USE_GUIDELINE; + location loc = LOC(e); if (n > 1 && !big && are_all_items_const(e->v.Dict.keys, begin, end)) { for (i = begin; i < end; i++) { VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Dict.values, i)); } keys = PyTuple_New(n); if (keys == NULL) { - return 0; + return SUCCESS; } for (i = begin; i < end; i++) { key = ((expr_ty)asdl_seq_GET(e->v.Dict.keys, i))->v.Constant.value; - Py_INCREF(key); - PyTuple_SET_ITEM(keys, i - begin, key); + PyTuple_SET_ITEM(keys, i - begin, Py_NewRef(key)); } - ADDOP_LOAD_CONST_NEW(c, keys); - ADDOP_I(c, BUILD_CONST_KEY_MAP, n); - return 1; + ADDOP_LOAD_CONST_NEW(c, loc, keys); + ADDOP_I(c, loc, BUILD_CONST_KEY_MAP, n); + return SUCCESS; } if (big) { - ADDOP_I(c, BUILD_MAP, 0); + ADDOP_I(c, loc, BUILD_MAP, 0); } for (i = begin; i < end; i++) { VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Dict.keys, i)); VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Dict.values, i)); if (big) { - ADDOP_I(c, MAP_ADD, 1); + ADDOP_I(c, loc, MAP_ADD, 1); } } if (!big) { - ADDOP_I(c, BUILD_MAP, n); + ADDOP_I(c, loc, BUILD_MAP, n); } - return 1; + return SUCCESS; } static int compiler_dict(struct compiler *c, expr_ty e) { + location loc = LOC(e); Py_ssize_t i, n, elements; int have_dict; int is_unpacking = 0; @@ -4582,29 +4488,25 @@ compiler_dict(struct compiler *c, expr_ty e) is_unpacking = (expr_ty)asdl_seq_GET(e->v.Dict.keys, i) == NULL; if (is_unpacking) { if (elements) { - if (!compiler_subdict(c, e, i - elements, i)) { - return 0; - } + RETURN_IF_ERROR(compiler_subdict(c, e, i - elements, i)); if (have_dict) { - ADDOP_I(c, DICT_UPDATE, 1); + ADDOP_I(c, loc, DICT_UPDATE, 1); } have_dict = 1; elements = 0; } if (have_dict == 0) { - ADDOP_I(c, BUILD_MAP, 0); + ADDOP_I(c, loc, BUILD_MAP, 0); have_dict = 1; } VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Dict.values, i)); - ADDOP_I(c, DICT_UPDATE, 1); + ADDOP_I(c, loc, DICT_UPDATE, 1); } else { if (elements*2 > STACK_USE_GUIDELINE) { - if (!compiler_subdict(c, e, i - elements, i + 1)) { - return 0; - } + RETURN_IF_ERROR(compiler_subdict(c, e, i - elements, i + 1)); if (have_dict) { - ADDOP_I(c, DICT_UPDATE, 1); + ADDOP_I(c, loc, DICT_UPDATE, 1); } have_dict = 1; elements = 0; @@ -4615,59 +4517,56 @@ compiler_dict(struct compiler *c, expr_ty e) } } if (elements) { - if (!compiler_subdict(c, e, n - elements, n)) { - return 0; - } + RETURN_IF_ERROR(compiler_subdict(c, e, n - elements, n)); if (have_dict) { - ADDOP_I(c, DICT_UPDATE, 1); + ADDOP_I(c, loc, DICT_UPDATE, 1); } have_dict = 1; } if (!have_dict) { - ADDOP_I(c, BUILD_MAP, 0); + ADDOP_I(c, loc, BUILD_MAP, 0); } - return 1; + return SUCCESS; } static int compiler_compare(struct compiler *c, expr_ty e) { + location loc = LOC(e); Py_ssize_t i, n; - if (!check_compare(c, e)) { - return 0; - } + RETURN_IF_ERROR(check_compare(c, e)); VISIT(c, expr, e->v.Compare.left); assert(asdl_seq_LEN(e->v.Compare.ops) > 0); n = asdl_seq_LEN(e->v.Compare.ops) - 1; if (n == 0) { VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Compare.comparators, 0)); - ADDOP_COMPARE(c, asdl_seq_GET(e->v.Compare.ops, 0)); + ADDOP_COMPARE(c, loc, asdl_seq_GET(e->v.Compare.ops, 0)); } else { - basicblock *cleanup = compiler_new_block(c); - if (cleanup == NULL) - return 0; + NEW_JUMP_TARGET_LABEL(c, cleanup); for (i = 0; i < n; i++) { VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Compare.comparators, i)); - ADDOP_I(c, SWAP, 2); - ADDOP_I(c, COPY, 2); - ADDOP_COMPARE(c, asdl_seq_GET(e->v.Compare.ops, i)); - ADDOP_JUMP(c, JUMP_IF_FALSE_OR_POP, cleanup); + ADDOP_I(c, loc, SWAP, 2); + ADDOP_I(c, loc, COPY, 2); + ADDOP_COMPARE(c, loc, asdl_seq_GET(e->v.Compare.ops, i)); + ADDOP_I(c, loc, COPY, 1); + ADDOP_JUMP(c, loc, POP_JUMP_IF_FALSE, cleanup); + ADDOP(c, loc, POP_TOP); } VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Compare.comparators, n)); - ADDOP_COMPARE(c, asdl_seq_GET(e->v.Compare.ops, n)); - basicblock *end = compiler_new_block(c); - if (end == NULL) - return 0; - ADDOP_JUMP_NOLINE(c, JUMP, end); - compiler_use_next_block(c, cleanup); - ADDOP_I(c, SWAP, 2); - ADDOP(c, POP_TOP); - compiler_use_next_block(c, end); + ADDOP_COMPARE(c, loc, asdl_seq_GET(e->v.Compare.ops, n)); + NEW_JUMP_TARGET_LABEL(c, end); + ADDOP_JUMP(c, NO_LOCATION, JUMP, end); + + USE_LABEL(c, cleanup); + ADDOP_I(c, loc, SWAP, 2); + ADDOP(c, loc, POP_TOP); + + USE_LABEL(c, end); } - return 1; + return SUCCESS; } static PyTypeObject * @@ -4713,12 +4612,14 @@ check_caller(struct compiler *c, expr_ty e) case SetComp_kind: case GeneratorExp_kind: case JoinedStr_kind: - case FormattedValue_kind: - return compiler_warn(c, "'%.200s' object is not callable; " - "perhaps you missed a comma?", - infer_type(e)->tp_name); + case FormattedValue_kind: { + location loc = LOC(e); + return compiler_warn(c, loc, "'%.200s' object is not callable; " + "perhaps you missed a comma?", + infer_type(e)->tp_name); + } default: - return 1; + return SUCCESS; } } @@ -4734,18 +4635,20 @@ check_subscripter(struct compiler *c, expr_ty e) PyLong_Check(v) || PyFloat_Check(v) || PyComplex_Check(v) || PyAnySet_Check(v))) { - return 1; + return SUCCESS; } /* fall through */ case Set_kind: case SetComp_kind: case GeneratorExp_kind: - case Lambda_kind: - return compiler_warn(c, "'%.200s' object is not subscriptable; " - "perhaps you missed a comma?", - infer_type(e)->tp_name); + case Lambda_kind: { + location loc = LOC(e); + return compiler_warn(c, loc, "'%.200s' object is not subscriptable; " + "perhaps you missed a comma?", + infer_type(e)->tp_name); + } default: - return 1; + return SUCCESS; } } @@ -4758,28 +4661,30 @@ check_index(struct compiler *c, expr_ty e, expr_ty s) if (index_type == NULL || PyType_FastSubclass(index_type, Py_TPFLAGS_LONG_SUBCLASS) || index_type == &PySlice_Type) { - return 1; + return SUCCESS; } switch (e->kind) { case Constant_kind: v = e->v.Constant.value; if (!(PyUnicode_Check(v) || PyBytes_Check(v) || PyTuple_Check(v))) { - return 1; + return SUCCESS; } /* fall through */ case Tuple_kind: case List_kind: case ListComp_kind: case JoinedStr_kind: - case FormattedValue_kind: - return compiler_warn(c, "%.200s indices must be integers or slices, " - "not %.200s; " - "perhaps you missed a comma?", - infer_type(e)->tp_name, - index_type->tp_name); + case FormattedValue_kind: { + location loc = LOC(e); + return compiler_warn(c, loc, "%.200s indices must be integers " + "or slices, not %.200s; " + "perhaps you missed a comma?", + infer_type(e)->tp_name, + index_type->tp_name); + } default: - return 1; + return SUCCESS; } } @@ -4800,34 +4705,118 @@ is_import_originated(struct compiler *c, expr_ty e) return flags & DEF_IMPORT; } +static int +can_optimize_super_call(struct compiler *c, expr_ty attr) +{ + expr_ty e = attr->v.Attribute.value; + if (e->kind != Call_kind || + e->v.Call.func->kind != Name_kind || + !_PyUnicode_EqualToASCIIString(e->v.Call.func->v.Name.id, "super") || + _PyUnicode_EqualToASCIIString(attr->v.Attribute.attr, "__class__") || + asdl_seq_LEN(e->v.Call.keywords) != 0) { + return 0; + } + Py_ssize_t num_args = asdl_seq_LEN(e->v.Call.args); + + PyObject *super_name = e->v.Call.func->v.Name.id; + // detect statically-visible shadowing of 'super' name + int scope = _PyST_GetScope(c->u->u_ste, super_name); + if (scope != GLOBAL_IMPLICIT) { + return 0; + } + scope = _PyST_GetScope(c->c_st->st_top, super_name); + if (scope != 0) { + return 0; + } + + if (num_args == 2) { + for (Py_ssize_t i = 0; i < num_args; i++) { + expr_ty elt = asdl_seq_GET(e->v.Call.args, i); + if (elt->kind == Starred_kind) { + return 0; + } + } + // exactly two non-starred args; we can just load + // the provided args + return 1; + } + + if (num_args != 0) { + return 0; + } + // we need the following for zero-arg super(): + + // enclosing function should have at least one argument + if (c->u->u_metadata.u_argcount == 0 && + c->u->u_metadata.u_posonlyargcount == 0) { + return 0; + } + // __class__ cell should be available + if (get_ref_type(c, &_Py_ID(__class__)) == FREE) { + return 1; + } + return 0; +} + +static int +load_args_for_super(struct compiler *c, expr_ty e) { + location loc = LOC(e); + + // load super() global + PyObject *super_name = e->v.Call.func->v.Name.id; + RETURN_IF_ERROR(compiler_nameop(c, LOC(e->v.Call.func), super_name, Load)); + + if (asdl_seq_LEN(e->v.Call.args) == 2) { + VISIT(c, expr, asdl_seq_GET(e->v.Call.args, 0)); + VISIT(c, expr, asdl_seq_GET(e->v.Call.args, 1)); + return SUCCESS; + } + + // load __class__ cell + PyObject *name = &_Py_ID(__class__); + assert(get_ref_type(c, name) == FREE); + RETURN_IF_ERROR(compiler_nameop(c, loc, name, Load)); + + // load self (first argument) + Py_ssize_t i = 0; + PyObject *key, *value; + if (!PyDict_Next(c->u->u_metadata.u_varnames, &i, &key, &value)) { + return ERROR; + } + RETURN_IF_ERROR(compiler_nameop(c, loc, key, Load)); + + return SUCCESS; +} + // If an attribute access spans multiple lines, update the current start // location to point to the attribute name. -static void -update_start_location_to_match_attr(struct compiler *c, expr_ty attr) +static location +update_start_location_to_match_attr(struct compiler *c, location loc, + expr_ty attr) { assert(attr->kind == Attribute_kind); - if (c->u->u_lineno != attr->end_lineno) { - c->u->u_lineno = attr->end_lineno; + if (loc.lineno != attr->end_lineno) { + loc.lineno = attr->end_lineno; int len = (int)PyUnicode_GET_LENGTH(attr->v.Attribute.attr); if (len <= attr->end_col_offset) { - c->u->u_col_offset = attr->end_col_offset - len; + loc.col_offset = attr->end_col_offset - len; } else { // GH-94694: Somebody's compiling weird ASTs. Just drop the columns: - c->u->u_col_offset = -1; - c->u->u_end_col_offset = -1; + loc.col_offset = -1; + loc.end_col_offset = -1; } // Make sure the end position still follows the start position, even for // weird ASTs: - c->u->u_end_lineno = Py_MAX(c->u->u_lineno, c->u->u_end_lineno); - if (c->u->u_lineno == c->u->u_end_lineno) { - c->u->u_end_col_offset = Py_MAX(c->u->u_col_offset, - c->u->u_end_col_offset); + loc.end_lineno = Py_MAX(loc.lineno, loc.end_lineno); + if (loc.lineno == loc.end_lineno) { + loc.end_col_offset = Py_MAX(loc.col_offset, loc.end_col_offset); } } + return loc; } -// Return 1 if the method call was optimized, -1 if not, and 0 on error. +// Return 1 if the method call was optimized, 0 if not, and -1 on error. static int maybe_optimize_method_call(struct compiler *c, expr_ty e) { @@ -4838,51 +4827,60 @@ maybe_optimize_method_call(struct compiler *c, expr_ty e) /* Check that the call node is an attribute access */ if (meth->kind != Attribute_kind || meth->v.Attribute.ctx != Load) { - return -1; + return 0; } /* Check that the base object is not something that is imported */ if (is_import_originated(c, meth->v.Attribute.value)) { - return -1; + return 0; } /* Check that there aren't too many arguments */ argsl = asdl_seq_LEN(args); kwdsl = asdl_seq_LEN(kwds); if (argsl + kwdsl + (kwdsl != 0) >= STACK_USE_GUIDELINE) { - return -1; + return 0; } /* Check that there are no *varargs types of arguments. */ for (i = 0; i < argsl; i++) { expr_ty elt = asdl_seq_GET(args, i); if (elt->kind == Starred_kind) { - return -1; + return 0; } } for (i = 0; i < kwdsl; i++) { keyword_ty kw = asdl_seq_GET(kwds, i); if (kw->arg == NULL) { - return -1; + return 0; } } + /* Alright, we can optimize the code. */ - VISIT(c, expr, meth->v.Attribute.value); - SET_LOC(c, meth); - update_start_location_to_match_attr(c, meth); - ADDOP_NAME(c, LOAD_METHOD, meth->v.Attribute.attr, names); + location loc = LOC(meth); + + if (can_optimize_super_call(c, meth)) { + RETURN_IF_ERROR(load_args_for_super(c, meth->v.Attribute.value)); + int opcode = asdl_seq_LEN(meth->v.Attribute.value->v.Call.args) ? + LOAD_SUPER_METHOD : LOAD_ZERO_SUPER_METHOD; + ADDOP_NAME(c, loc, opcode, meth->v.Attribute.attr, names); + loc = update_start_location_to_match_attr(c, loc, meth); + ADDOP(c, loc, NOP); + } else { + VISIT(c, expr, meth->v.Attribute.value); + loc = update_start_location_to_match_attr(c, loc, meth); + ADDOP_NAME(c, loc, LOAD_METHOD, meth->v.Attribute.attr, names); + } + VISIT_SEQ(c, expr, e->v.Call.args); if (kwdsl) { VISIT_SEQ(c, keyword, kwds); - if (!compiler_call_simple_kw_helper(c, kwds, kwdsl)) { - return 0; - }; + RETURN_IF_ERROR( + compiler_call_simple_kw_helper(c, loc, kwds, kwdsl)); } - SET_LOC(c, e); - update_start_location_to_match_attr(c, meth); - ADDOP_I(c, PRECALL, argsl + kwdsl); - ADDOP_I(c, CALL, argsl + kwdsl); + loc = update_start_location_to_match_attr(c, LOC(e), meth); + ADDOP_I(c, loc, CALL, argsl + kwdsl); return 1; } @@ -4895,39 +4893,38 @@ validate_keywords(struct compiler *c, asdl_keyword_seq *keywords) if (key->arg == NULL) { continue; } - if (forbidden_name(c, key->arg, Store)) { - return -1; + location loc = LOC(key); + if (forbidden_name(c, loc, key->arg, Store)) { + return ERROR; } for (Py_ssize_t j = i + 1; j < nkeywords; j++) { keyword_ty other = ((keyword_ty)asdl_seq_GET(keywords, j)); if (other->arg && !PyUnicode_Compare(key->arg, other->arg)) { - SET_LOC(c, other); - compiler_error(c, "keyword argument repeated: %U", key->arg); - return -1; + compiler_error(c, LOC(other), "keyword argument repeated: %U", key->arg); + return ERROR; } } } - return 0; + return SUCCESS; } static int compiler_call(struct compiler *c, expr_ty e) { - if (validate_keywords(c, e->v.Call.keywords) == -1) { - return 0; - } + RETURN_IF_ERROR(validate_keywords(c, e->v.Call.keywords)); int ret = maybe_optimize_method_call(c, e); - if (ret >= 0) { - return ret; + if (ret < 0) { + return ERROR; } - if (!check_caller(c, e->v.Call.func)) { - return 0; + if (ret == 1) { + return SUCCESS; } - SET_LOC(c, e->v.Call.func); - ADDOP(c, PUSH_NULL); - SET_LOC(c, e); + RETURN_IF_ERROR(check_caller(c, e->v.Call.func)); + location loc = LOC(e->v.Call.func); + ADDOP(c, loc, PUSH_NULL); VISIT(c, expr, e->v.Call.func); - return compiler_call_helper(c, 0, + loc = LOC(e); + return compiler_call_helper(c, loc, 0, e->v.Call.args, e->v.Call.keywords); } @@ -4935,27 +4932,26 @@ compiler_call(struct compiler *c, expr_ty e) static int compiler_joined_str(struct compiler *c, expr_ty e) { - + location loc = LOC(e); Py_ssize_t value_count = asdl_seq_LEN(e->v.JoinedStr.values); if (value_count > STACK_USE_GUIDELINE) { _Py_DECLARE_STR(empty, ""); - ADDOP_LOAD_CONST_NEW(c, Py_NewRef(&_Py_STR(empty))); - ADDOP_NAME(c, LOAD_METHOD, &_Py_ID(join), names); - ADDOP_I(c, BUILD_LIST, 0); + ADDOP_LOAD_CONST_NEW(c, loc, Py_NewRef(&_Py_STR(empty))); + ADDOP_NAME(c, loc, LOAD_METHOD, &_Py_ID(join), names); + ADDOP_I(c, loc, BUILD_LIST, 0); for (Py_ssize_t i = 0; i < asdl_seq_LEN(e->v.JoinedStr.values); i++) { VISIT(c, expr, asdl_seq_GET(e->v.JoinedStr.values, i)); - ADDOP_I(c, LIST_APPEND, 1); + ADDOP_I(c, loc, LIST_APPEND, 1); } - ADDOP_I(c, PRECALL, 1); - ADDOP_I(c, CALL, 1); + ADDOP_I(c, loc, CALL, 1); } else { VISIT_SEQ(c, expr, e->v.JoinedStr.values); if (asdl_seq_LEN(e->v.JoinedStr.values) != 1) { - ADDOP_I(c, BUILD_STRING, asdl_seq_LEN(e->v.JoinedStr.values)); + ADDOP_I(c, loc, BUILD_STRING, asdl_seq_LEN(e->v.JoinedStr.values)); } } - return 1; + return SUCCESS; } /* Used to implement f-strings. Format a single value. */ @@ -4990,7 +4986,7 @@ compiler_formatted_value(struct compiler *c, expr_ty e) default: PyErr_Format(PyExc_SystemError, "Unrecognized conversion character %d", conversion); - return 0; + return ERROR; } if (e->v.FormattedValue.format_spec) { /* Evaluate the format spec, and update our opcode arg. */ @@ -4999,13 +4995,16 @@ compiler_formatted_value(struct compiler *c, expr_ty e) } /* And push our opcode and oparg */ - ADDOP_I(c, FORMAT_VALUE, oparg); + location loc = LOC(e); + ADDOP_I(c, loc, FORMAT_VALUE, oparg); - return 1; + return SUCCESS; } static int -compiler_subkwargs(struct compiler *c, asdl_keyword_seq *keywords, Py_ssize_t begin, Py_ssize_t end) +compiler_subkwargs(struct compiler *c, location loc, + asdl_keyword_seq *keywords, + Py_ssize_t begin, Py_ssize_t end) { Py_ssize_t i, n = end - begin; keyword_ty kw; @@ -5019,75 +5018,69 @@ compiler_subkwargs(struct compiler *c, asdl_keyword_seq *keywords, Py_ssize_t be } keys = PyTuple_New(n); if (keys == NULL) { - return 0; + return ERROR; } for (i = begin; i < end; i++) { key = ((keyword_ty) asdl_seq_GET(keywords, i))->arg; - Py_INCREF(key); - PyTuple_SET_ITEM(keys, i - begin, key); + PyTuple_SET_ITEM(keys, i - begin, Py_NewRef(key)); } - ADDOP_LOAD_CONST_NEW(c, keys); - ADDOP_I(c, BUILD_CONST_KEY_MAP, n); - return 1; + ADDOP_LOAD_CONST_NEW(c, loc, keys); + ADDOP_I(c, loc, BUILD_CONST_KEY_MAP, n); + return SUCCESS; } if (big) { - ADDOP_I_NOLINE(c, BUILD_MAP, 0); + ADDOP_I(c, NO_LOCATION, BUILD_MAP, 0); } for (i = begin; i < end; i++) { kw = asdl_seq_GET(keywords, i); - ADDOP_LOAD_CONST(c, kw->arg); + ADDOP_LOAD_CONST(c, loc, kw->arg); VISIT(c, expr, kw->value); if (big) { - ADDOP_I_NOLINE(c, MAP_ADD, 1); + ADDOP_I(c, NO_LOCATION, MAP_ADD, 1); } } if (!big) { - ADDOP_I(c, BUILD_MAP, n); + ADDOP_I(c, loc, BUILD_MAP, n); } - return 1; + return SUCCESS; } /* Used by compiler_call_helper and maybe_optimize_method_call to emit * KW_NAMES before CALL. - * Returns 1 on success, 0 on error. */ static int -compiler_call_simple_kw_helper(struct compiler *c, - asdl_keyword_seq *keywords, - Py_ssize_t nkwelts) +compiler_call_simple_kw_helper(struct compiler *c, location loc, + asdl_keyword_seq *keywords, Py_ssize_t nkwelts) { PyObject *names; names = PyTuple_New(nkwelts); if (names == NULL) { - return 0; + return ERROR; } for (int i = 0; i < nkwelts; i++) { keyword_ty kw = asdl_seq_GET(keywords, i); - Py_INCREF(kw->arg); - PyTuple_SET_ITEM(names, i, kw->arg); + PyTuple_SET_ITEM(names, i, Py_NewRef(kw->arg)); } - Py_ssize_t arg = compiler_add_const(c, names); + Py_ssize_t arg = compiler_add_const(c->c_const_cache, c->u, names); if (arg < 0) { - return 0; + return ERROR; } Py_DECREF(names); - ADDOP_I(c, KW_NAMES, arg); - return 1; + ADDOP_I(c, loc, KW_NAMES, arg); + return SUCCESS; } /* shared code between compiler_call and compiler_class */ static int -compiler_call_helper(struct compiler *c, +compiler_call_helper(struct compiler *c, location loc, int n, /* Args already pushed */ asdl_expr_seq *args, asdl_keyword_seq *keywords) { Py_ssize_t i, nseen, nelts, nkwelts; - if (validate_keywords(c, keywords) == -1) { - return 0; - } + RETURN_IF_ERROR(validate_keywords(c, keywords)); nelts = asdl_seq_LEN(args); nkwelts = asdl_seq_LEN(keywords); @@ -5116,13 +5109,11 @@ compiler_call_helper(struct compiler *c, } if (nkwelts) { VISIT_SEQ(c, keyword, keywords); - if (!compiler_call_simple_kw_helper(c, keywords, nkwelts)) { - return 0; - }; + RETURN_IF_ERROR( + compiler_call_simple_kw_helper(c, loc, keywords, nkwelts)); } - ADDOP_I(c, PRECALL, n + nelts + nkwelts); - ADDOP_I(c, CALL, n + nelts + nkwelts); - return 1; + ADDOP_I(c, loc, CALL, n + nelts + nkwelts); + return SUCCESS; ex_call: @@ -5130,9 +5121,9 @@ ex_call: if (n ==0 && nelts == 1 && ((expr_ty)asdl_seq_GET(args, 0))->kind == Starred_kind) { VISIT(c, expr, ((expr_ty)asdl_seq_GET(args, 0))->v.Starred.value); } - else if (starunpack_helper(c, args, n, BUILD_LIST, - LIST_APPEND, LIST_EXTEND, 1) == 0) { - return 0; + else { + RETURN_IF_ERROR(starunpack_helper(c, loc, args, n, BUILD_LIST, + LIST_APPEND, LIST_EXTEND, 1)); } /* Then keyword arguments */ if (nkwelts) { @@ -5145,21 +5136,19 @@ ex_call: if (kw->arg == NULL) { /* A keyword argument unpacking. */ if (nseen) { - if (!compiler_subkwargs(c, keywords, i - nseen, i)) { - return 0; - } + RETURN_IF_ERROR(compiler_subkwargs(c, loc, keywords, i - nseen, i)); if (have_dict) { - ADDOP_I(c, DICT_MERGE, 1); + ADDOP_I(c, loc, DICT_MERGE, 1); } have_dict = 1; nseen = 0; } if (!have_dict) { - ADDOP_I(c, BUILD_MAP, 0); + ADDOP_I(c, loc, BUILD_MAP, 0); have_dict = 1; } VISIT(c, expr, kw->value); - ADDOP_I(c, DICT_MERGE, 1); + ADDOP_I(c, loc, DICT_MERGE, 1); } else { nseen++; @@ -5167,18 +5156,16 @@ ex_call: } if (nseen) { /* Pack up any trailing keyword arguments. */ - if (!compiler_subkwargs(c, keywords, nkwelts - nseen, nkwelts)) { - return 0; - } + RETURN_IF_ERROR(compiler_subkwargs(c, loc, keywords, nkwelts - nseen, nkwelts)); if (have_dict) { - ADDOP_I(c, DICT_MERGE, 1); + ADDOP_I(c, loc, DICT_MERGE, 1); } have_dict = 1; } assert(have_dict); } - ADDOP_I(c, CALL_FUNCTION_EX, nkwelts > 0); - return 1; + ADDOP_I(c, loc, CALL_FUNCTION_EX, nkwelts > 0); + return SUCCESS; } @@ -5197,98 +5184,99 @@ ex_call: static int -compiler_comprehension_generator(struct compiler *c, +compiler_comprehension_generator(struct compiler *c, location loc, asdl_comprehension_seq *generators, int gen_index, int depth, - expr_ty elt, expr_ty val, int type) + expr_ty elt, expr_ty val, int type, + int iter_on_stack) { comprehension_ty gen; gen = (comprehension_ty)asdl_seq_GET(generators, gen_index); if (gen->is_async) { return compiler_async_comprehension_generator( - c, generators, gen_index, depth, elt, val, type); + c, loc, generators, gen_index, depth, elt, val, type, + iter_on_stack); } else { return compiler_sync_comprehension_generator( - c, generators, gen_index, depth, elt, val, type); + c, loc, generators, gen_index, depth, elt, val, type, + iter_on_stack); } } static int -compiler_sync_comprehension_generator(struct compiler *c, - asdl_comprehension_seq *generators, int gen_index, - int depth, - expr_ty elt, expr_ty val, int type) +compiler_sync_comprehension_generator(struct compiler *c, location loc, + asdl_comprehension_seq *generators, + int gen_index, int depth, + expr_ty elt, expr_ty val, int type, + int iter_on_stack) { /* generate code for the iterator, then each of the ifs, and then write to the element */ - comprehension_ty gen; - basicblock *start, *anchor, *if_cleanup; - Py_ssize_t i, n; - - start = compiler_new_block(c); - if_cleanup = compiler_new_block(c); - anchor = compiler_new_block(c); + NEW_JUMP_TARGET_LABEL(c, start); + NEW_JUMP_TARGET_LABEL(c, if_cleanup); + NEW_JUMP_TARGET_LABEL(c, anchor); - if (start == NULL || if_cleanup == NULL || anchor == NULL) { - return 0; - } - - gen = (comprehension_ty)asdl_seq_GET(generators, gen_index); + comprehension_ty gen = (comprehension_ty)asdl_seq_GET(generators, + gen_index); - if (gen_index == 0) { - /* Receive outermost iter as an implicit argument */ - c->u->u_argcount = 1; - ADDOP_I(c, LOAD_FAST, 0); - } - else { - /* Sub-iter - calculate on the fly */ - /* Fast path for the temporary variable assignment idiom: - for y in [f(x)] - */ - asdl_expr_seq *elts; - switch (gen->iter->kind) { - case List_kind: - elts = gen->iter->v.List.elts; - break; - case Tuple_kind: - elts = gen->iter->v.Tuple.elts; - break; - default: - elts = NULL; - } - if (asdl_seq_LEN(elts) == 1) { - expr_ty elt = asdl_seq_GET(elts, 0); - if (elt->kind != Starred_kind) { - VISIT(c, expr, elt); - start = NULL; - } + if (!iter_on_stack) { + if (gen_index == 0) { + /* Receive outermost iter as an implicit argument */ + c->u->u_metadata.u_argcount = 1; + ADDOP_I(c, loc, LOAD_FAST, 0); } - if (start) { - VISIT(c, expr, gen->iter); - ADDOP(c, GET_ITER); + else { + /* Sub-iter - calculate on the fly */ + /* Fast path for the temporary variable assignment idiom: + for y in [f(x)] + */ + asdl_expr_seq *elts; + switch (gen->iter->kind) { + case List_kind: + elts = gen->iter->v.List.elts; + break; + case Tuple_kind: + elts = gen->iter->v.Tuple.elts; + break; + default: + elts = NULL; + } + if (asdl_seq_LEN(elts) == 1) { + expr_ty elt = asdl_seq_GET(elts, 0); + if (elt->kind != Starred_kind) { + VISIT(c, expr, elt); + start = NO_LABEL; + } + } + if (IS_LABEL(start)) { + VISIT(c, expr, gen->iter); + ADDOP(c, loc, GET_ITER); + } } } - if (start) { + if (IS_LABEL(start)) { depth++; - compiler_use_next_block(c, start); - ADDOP_JUMP(c, FOR_ITER, anchor); + USE_LABEL(c, start); + ADDOP_JUMP(c, loc, FOR_ITER, anchor); } VISIT(c, expr, gen->target); /* XXX this needs to be cleaned up...a lot! */ - n = asdl_seq_LEN(gen->ifs); - for (i = 0; i < n; i++) { + Py_ssize_t n = asdl_seq_LEN(gen->ifs); + for (Py_ssize_t i = 0; i < n; i++) { expr_ty e = (expr_ty)asdl_seq_GET(gen->ifs, i); - if (!compiler_jump_if(c, e, if_cleanup, 0)) - return 0; + RETURN_IF_ERROR(compiler_jump_if(c, loc, e, if_cleanup, 0)); } - if (++gen_index < asdl_seq_LEN(generators)) - if (!compiler_comprehension_generator(c, - generators, gen_index, depth, - elt, val, type)) - return 0; + if (++gen_index < asdl_seq_LEN(generators)) { + RETURN_IF_ERROR( + compiler_comprehension_generator(c, loc, + generators, gen_index, depth, + elt, val, type, 0)); + } + + location elt_loc = LOC(elt); /* only append after the last for generator */ if (gen_index >= asdl_seq_LEN(generators)) { @@ -5296,134 +5284,360 @@ compiler_sync_comprehension_generator(struct compiler *c, switch (type) { case COMP_GENEXP: VISIT(c, expr, elt); - ADDOP_YIELD(c); - ADDOP(c, POP_TOP); + ADDOP_YIELD(c, elt_loc); + ADDOP(c, elt_loc, POP_TOP); break; case COMP_LISTCOMP: VISIT(c, expr, elt); - ADDOP_I(c, LIST_APPEND, depth + 1); + ADDOP_I(c, elt_loc, LIST_APPEND, depth + 1); break; case COMP_SETCOMP: VISIT(c, expr, elt); - ADDOP_I(c, SET_ADD, depth + 1); + ADDOP_I(c, elt_loc, SET_ADD, depth + 1); break; case COMP_DICTCOMP: /* With '{k: v}', k is evaluated before v, so we do the same. */ VISIT(c, expr, elt); VISIT(c, expr, val); - ADDOP_I(c, MAP_ADD, depth + 1); + elt_loc = LOCATION(elt->lineno, + val->end_lineno, + elt->col_offset, + val->end_col_offset); + ADDOP_I(c, elt_loc, MAP_ADD, depth + 1); break; default: - return 0; + return ERROR; } } - compiler_use_next_block(c, if_cleanup); - if (start) { - ADDOP_JUMP(c, JUMP, start); - compiler_use_next_block(c, anchor); + + USE_LABEL(c, if_cleanup); + if (IS_LABEL(start)) { + ADDOP_JUMP(c, elt_loc, JUMP, start); + + USE_LABEL(c, anchor); + ADDOP(c, NO_LOCATION, END_FOR); } - return 1; + return SUCCESS; } static int -compiler_async_comprehension_generator(struct compiler *c, - asdl_comprehension_seq *generators, int gen_index, - int depth, - expr_ty elt, expr_ty val, int type) +compiler_async_comprehension_generator(struct compiler *c, location loc, + asdl_comprehension_seq *generators, + int gen_index, int depth, + expr_ty elt, expr_ty val, int type, + int iter_on_stack) { - comprehension_ty gen; - basicblock *start, *if_cleanup, *except; - Py_ssize_t i, n; - start = compiler_new_block(c); - except = compiler_new_block(c); - if_cleanup = compiler_new_block(c); + NEW_JUMP_TARGET_LABEL(c, start); + NEW_JUMP_TARGET_LABEL(c, except); + NEW_JUMP_TARGET_LABEL(c, if_cleanup); - if (start == NULL || if_cleanup == NULL || except == NULL) { - return 0; - } - - gen = (comprehension_ty)asdl_seq_GET(generators, gen_index); + comprehension_ty gen = (comprehension_ty)asdl_seq_GET(generators, + gen_index); - if (gen_index == 0) { - /* Receive outermost iter as an implicit argument */ - c->u->u_argcount = 1; - ADDOP_I(c, LOAD_FAST, 0); - } - else { - /* Sub-iter - calculate on the fly */ - VISIT(c, expr, gen->iter); - ADDOP(c, GET_AITER); + if (!iter_on_stack) { + if (gen_index == 0) { + /* Receive outermost iter as an implicit argument */ + c->u->u_metadata.u_argcount = 1; + ADDOP_I(c, loc, LOAD_FAST, 0); + } + else { + /* Sub-iter - calculate on the fly */ + VISIT(c, expr, gen->iter); + ADDOP(c, loc, GET_AITER); + } } - compiler_use_next_block(c, start); + USE_LABEL(c, start); /* Runtime will push a block here, so we need to account for that */ - if (!compiler_push_fblock(c, ASYNC_COMPREHENSION_GENERATOR, start, - NULL, NULL)) { - return 0; - } - - ADDOP_JUMP(c, SETUP_FINALLY, except); - ADDOP(c, GET_ANEXT); - ADDOP_LOAD_CONST(c, Py_None); - ADD_YIELD_FROM(c, 1); - ADDOP(c, POP_BLOCK); + RETURN_IF_ERROR( + compiler_push_fblock(c, loc, ASYNC_COMPREHENSION_GENERATOR, + start, NO_LABEL, NULL)); + + ADDOP_JUMP(c, loc, SETUP_FINALLY, except); + ADDOP(c, loc, GET_ANEXT); + ADDOP_LOAD_CONST(c, loc, Py_None); + ADD_YIELD_FROM(c, loc, 1); + ADDOP(c, loc, POP_BLOCK); VISIT(c, expr, gen->target); - n = asdl_seq_LEN(gen->ifs); - for (i = 0; i < n; i++) { + Py_ssize_t n = asdl_seq_LEN(gen->ifs); + for (Py_ssize_t i = 0; i < n; i++) { expr_ty e = (expr_ty)asdl_seq_GET(gen->ifs, i); - if (!compiler_jump_if(c, e, if_cleanup, 0)) - return 0; + RETURN_IF_ERROR(compiler_jump_if(c, loc, e, if_cleanup, 0)); } depth++; - if (++gen_index < asdl_seq_LEN(generators)) - if (!compiler_comprehension_generator(c, - generators, gen_index, depth, - elt, val, type)) - return 0; + if (++gen_index < asdl_seq_LEN(generators)) { + RETURN_IF_ERROR( + compiler_comprehension_generator(c, loc, + generators, gen_index, depth, + elt, val, type, 0)); + } + location elt_loc = LOC(elt); /* only append after the last for generator */ if (gen_index >= asdl_seq_LEN(generators)) { /* comprehension specific code */ switch (type) { case COMP_GENEXP: VISIT(c, expr, elt); - ADDOP_YIELD(c); - ADDOP(c, POP_TOP); + ADDOP_YIELD(c, elt_loc); + ADDOP(c, elt_loc, POP_TOP); break; case COMP_LISTCOMP: VISIT(c, expr, elt); - ADDOP_I(c, LIST_APPEND, depth + 1); + ADDOP_I(c, elt_loc, LIST_APPEND, depth + 1); break; case COMP_SETCOMP: VISIT(c, expr, elt); - ADDOP_I(c, SET_ADD, depth + 1); + ADDOP_I(c, elt_loc, SET_ADD, depth + 1); break; case COMP_DICTCOMP: /* With '{k: v}', k is evaluated before v, so we do the same. */ VISIT(c, expr, elt); VISIT(c, expr, val); - ADDOP_I(c, MAP_ADD, depth + 1); + elt_loc = LOCATION(elt->lineno, + val->end_lineno, + elt->col_offset, + val->end_col_offset); + ADDOP_I(c, elt_loc, MAP_ADD, depth + 1); break; default: - return 0; + return ERROR; } } - compiler_use_next_block(c, if_cleanup); - ADDOP_JUMP(c, JUMP, start); + + USE_LABEL(c, if_cleanup); + ADDOP_JUMP(c, elt_loc, JUMP, start); compiler_pop_fblock(c, ASYNC_COMPREHENSION_GENERATOR, start); - compiler_use_next_block(c, except); - //UNSET_LOC(c); + USE_LABEL(c, except); - ADDOP(c, END_ASYNC_FOR); + ADDOP(c, loc, END_ASYNC_FOR); - return 1; + return SUCCESS; +} + +typedef struct { + PyObject *pushed_locals; + PyObject *temp_symbols; + PyObject *fast_hidden; + jump_target_label cleanup; + jump_target_label end; +} inlined_comprehension_state; + +static int +push_inlined_comprehension_state(struct compiler *c, location loc, + PySTEntryObject *entry, + inlined_comprehension_state *state) +{ + int in_class_block = (c->u->u_ste->ste_type == ClassBlock) && !c->u->u_in_inlined_comp; + c->u->u_in_inlined_comp++; + // iterate over names bound in the comprehension and ensure we isolate + // them from the outer scope as needed + PyObject *k, *v; + Py_ssize_t pos = 0; + while (PyDict_Next(entry->ste_symbols, &pos, &k, &v)) { + assert(PyLong_Check(v)); + long symbol = PyLong_AS_LONG(v); + // only values bound in the comprehension (DEF_LOCAL) need to be handled + // at all; DEF_LOCAL | DEF_NONLOCAL can occur in the case of an + // assignment expression to a nonlocal in the comprehension, these don't + // need handling here since they shouldn't be isolated + if ((symbol & DEF_LOCAL && !(symbol & DEF_NONLOCAL)) || in_class_block) { + if (!_PyST_IsFunctionLike(c->u->u_ste)) { + // non-function scope: override this name to use fast locals + PyObject *orig = PyDict_GetItem(c->u->u_metadata.u_fasthidden, k); + if (orig != Py_True) { + if (PyDict_SetItem(c->u->u_metadata.u_fasthidden, k, Py_True) < 0) { + return ERROR; + } + if (state->fast_hidden == NULL) { + state->fast_hidden = PySet_New(NULL); + if (state->fast_hidden == NULL) { + return ERROR; + } + } + if (PySet_Add(state->fast_hidden, k) < 0) { + return ERROR; + } + } + } + long scope = (symbol >> SCOPE_OFFSET) & SCOPE_MASK; + PyObject *outv = PyDict_GetItemWithError(c->u->u_ste->ste_symbols, k); + if (outv == NULL) { + outv = _PyLong_GetZero(); + } + assert(PyLong_Check(outv)); + long outsc = (PyLong_AS_LONG(outv) >> SCOPE_OFFSET) & SCOPE_MASK; + if (scope != outsc && !(scope == CELL && outsc == FREE)) { + // If a name has different scope inside than outside the + // comprehension, we need to temporarily handle it with the + // right scope while compiling the comprehension. (If it's free + // in outer scope and cell in inner scope, we can't treat it as + // both cell and free in the same function, but treating it as + // free throughout is fine; it's *_DEREF either way.) + + if (state->temp_symbols == NULL) { + state->temp_symbols = PyDict_New(); + if (state->temp_symbols == NULL) { + return ERROR; + } + } + // update the symbol to the in-comprehension version and save + // the outer version; we'll restore it after running the + // comprehension + Py_INCREF(outv); + if (PyDict_SetItem(c->u->u_ste->ste_symbols, k, v) < 0) { + Py_DECREF(outv); + return ERROR; + } + if (PyDict_SetItem(state->temp_symbols, k, outv) < 0) { + Py_DECREF(outv); + return ERROR; + } + Py_DECREF(outv); + } + // local names bound in comprehension must be isolated from + // outer scope; push existing value (which may be NULL if + // not defined) on stack + if (state->pushed_locals == NULL) { + state->pushed_locals = PyList_New(0); + if (state->pushed_locals == NULL) { + return ERROR; + } + } + // in the case of a cell, this will actually push the cell + // itself to the stack, then we'll create a new one for the + // comprehension and restore the original one after + ADDOP_NAME(c, loc, LOAD_FAST_AND_CLEAR, k, varnames); + if (scope == CELL) { + if (outsc == FREE) { + ADDOP_NAME(c, loc, MAKE_CELL, k, freevars); + } else { + ADDOP_NAME(c, loc, MAKE_CELL, k, cellvars); + } + } + if (PyList_Append(state->pushed_locals, k) < 0) { + return ERROR; + } + } + } + if (state->pushed_locals) { + // Outermost iterable expression was already evaluated and is on the + // stack, we need to swap it back to TOS. This also rotates the order of + // `pushed_locals` on the stack, but this will be reversed when we swap + // out the comprehension result in pop_inlined_comprehension_state + ADDOP_I(c, loc, SWAP, PyList_GET_SIZE(state->pushed_locals) + 1); + + // Add our own cleanup handler to restore comprehension locals in case + // of exception, so they have the correct values inside an exception + // handler or finally block. + NEW_JUMP_TARGET_LABEL(c, cleanup); + state->cleanup = cleanup; + NEW_JUMP_TARGET_LABEL(c, end); + state->end = end; + + // no need to push an fblock for this "virtual" try/finally; there can't + // be return/continue/break inside a comprehension + ADDOP_JUMP(c, loc, SETUP_FINALLY, cleanup); + } + + return SUCCESS; +} + +static int +restore_inlined_comprehension_locals(struct compiler *c, location loc, + inlined_comprehension_state state) +{ + PyObject *k; + // pop names we pushed to stack earlier + Py_ssize_t npops = PyList_GET_SIZE(state.pushed_locals); + // Preserve the comprehension result (or exception) as TOS. This + // reverses the SWAP we did in push_inlined_comprehension_state to get + // the outermost iterable to TOS, so we can still just iterate + // pushed_locals in simple reverse order + ADDOP_I(c, loc, SWAP, npops + 1); + for (Py_ssize_t i = npops - 1; i >= 0; --i) { + k = PyList_GetItem(state.pushed_locals, i); + if (k == NULL) { + return ERROR; + } + ADDOP_NAME(c, loc, STORE_FAST_MAYBE_NULL, k, varnames); + } + return SUCCESS; +} + +static int +pop_inlined_comprehension_state(struct compiler *c, location loc, + inlined_comprehension_state state) +{ + c->u->u_in_inlined_comp--; + PyObject *k, *v; + Py_ssize_t pos = 0; + if (state.temp_symbols) { + while (PyDict_Next(state.temp_symbols, &pos, &k, &v)) { + if (PyDict_SetItem(c->u->u_ste->ste_symbols, k, v)) { + return ERROR; + } + } + Py_CLEAR(state.temp_symbols); + } + if (state.pushed_locals) { + ADDOP(c, NO_LOCATION, POP_BLOCK); + ADDOP_JUMP(c, NO_LOCATION, JUMP, state.end); + + // cleanup from an exception inside the comprehension + USE_LABEL(c, state.cleanup); + // discard incomplete comprehension result (beneath exc on stack) + ADDOP_I(c, NO_LOCATION, SWAP, 2); + ADDOP(c, NO_LOCATION, POP_TOP); + if (restore_inlined_comprehension_locals(c, loc, state) < 0) { + return ERROR; + } + ADDOP_I(c, NO_LOCATION, RERAISE, 0); + + USE_LABEL(c, state.end); + if (restore_inlined_comprehension_locals(c, loc, state) < 0) { + return ERROR; + } + Py_CLEAR(state.pushed_locals); + } + if (state.fast_hidden) { + while (PySet_Size(state.fast_hidden) > 0) { + PyObject *k = PySet_Pop(state.fast_hidden); + if (k == NULL) { + return ERROR; + } + // we set to False instead of clearing, so we can track which names + // were temporarily fast-locals and should use CO_FAST_HIDDEN + if (PyDict_SetItem(c->u->u_metadata.u_fasthidden, k, Py_False)) { + Py_DECREF(k); + return ERROR; + } + Py_DECREF(k); + } + Py_CLEAR(state.fast_hidden); + } + return SUCCESS; +} + +static inline int +compiler_comprehension_iter(struct compiler *c, location loc, + comprehension_ty comp) +{ + VISIT(c, expr, comp->iter); + if (comp->is_async) { + ADDOP(c, loc, GET_AITER); + } + else { + ADDOP(c, loc, GET_ITER); + } + return SUCCESS; } static int @@ -5432,29 +5646,44 @@ compiler_comprehension(struct compiler *c, expr_ty e, int type, expr_ty val) { PyCodeObject *co = NULL; + inlined_comprehension_state inline_state = {NULL, NULL, NULL, NO_LABEL, NO_LABEL}; comprehension_ty outermost; - PyObject *qualname = NULL; int scope_type = c->u->u_scope_type; - int is_async_generator = 0; int is_top_level_await = IS_TOP_LEVEL_AWAIT(c); - - outermost = (comprehension_ty) asdl_seq_GET(generators, 0); - if (!compiler_enter_scope(c, name, COMPILER_SCOPE_COMPREHENSION, - (void *)e, e->lineno)) - { + PySTEntryObject *entry = PySymtable_Lookup(c->c_st, (void *)e); + if (entry == NULL) { goto error; } - SET_LOC(c, e); + int is_inlined = entry->ste_comp_inlined; + int is_async_generator = entry->ste_coroutine; + + location loc = LOC(e); - is_async_generator = c->u->u_ste->ste_coroutine; + outermost = (comprehension_ty) asdl_seq_GET(generators, 0); + if (is_inlined) { + if (compiler_comprehension_iter(c, loc, outermost)) { + goto error; + } + if (push_inlined_comprehension_state(c, loc, entry, &inline_state)) { + goto error; + } + } + else { + if (compiler_enter_scope(c, name, COMPILER_SCOPE_COMPREHENSION, + (void *)e, e->lineno) < 0) + { + goto error; + } + } + Py_CLEAR(entry); if (is_async_generator && type != COMP_GENEXP && scope_type != COMPILER_SCOPE_ASYNC_FUNCTION && scope_type != COMPILER_SCOPE_COMPREHENSION && !is_top_level_await) { - compiler_error(c, "asynchronous comprehension outside of " - "an asynchronous function"); + compiler_error(c, loc, "asynchronous comprehension outside of " + "an asynchronous function"); goto error_in_scope; } @@ -5476,57 +5705,72 @@ compiler_comprehension(struct compiler *c, expr_ty e, int type, goto error_in_scope; } - ADDOP_I(c, op, 0); + ADDOP_I(c, loc, op, 0); + if (is_inlined) { + ADDOP_I(c, loc, SWAP, 2); + } } - if (!compiler_comprehension_generator(c, generators, 0, 0, elt, - val, type)) + if (compiler_comprehension_generator(c, loc, generators, 0, 0, + elt, val, type, is_inlined) < 0) { goto error_in_scope; + } + + if (is_inlined) { + if (pop_inlined_comprehension_state(c, loc, inline_state)) { + goto error; + } + return SUCCESS; + } if (type != COMP_GENEXP) { - ADDOP(c, RETURN_VALUE); + ADDOP(c, LOC(e), RETURN_VALUE); + } + if (type == COMP_GENEXP) { + if (wrap_in_stopiteration_handler(c) < 0) { + goto error_in_scope; + } } - co = assemble(c, 1); - qualname = c->u->u_qualname; - Py_INCREF(qualname); + co = optimize_and_assemble(c, 1); compiler_exit_scope(c); if (is_top_level_await && is_async_generator){ c->u->u_ste->ste_coroutine = 1; } - if (co == NULL) + if (co == NULL) { goto error; + } - if (!compiler_make_closure(c, co, 0, qualname)) { + loc = LOC(e); + if (compiler_make_closure(c, loc, co, 0) < 0) { goto error; } - Py_DECREF(qualname); - Py_DECREF(co); - - VISIT(c, expr, outermost->iter); + Py_CLEAR(co); - if (outermost->is_async) { - ADDOP(c, GET_AITER); - } else { - ADDOP(c, GET_ITER); + if (compiler_comprehension_iter(c, loc, outermost)) { + goto error; } - ADDOP_I(c, PRECALL, 0); - ADDOP_I(c, CALL, 0); + ADDOP_I(c, loc, CALL, 0); if (is_async_generator && type != COMP_GENEXP) { - ADDOP_I(c, GET_AWAITABLE, 0); - ADDOP_LOAD_CONST(c, Py_None); - ADD_YIELD_FROM(c, 1); + ADDOP_I(c, loc, GET_AWAITABLE, 0); + ADDOP_LOAD_CONST(c, loc, Py_None); + ADD_YIELD_FROM(c, loc, 1); } - return 1; + return SUCCESS; error_in_scope: - compiler_exit_scope(c); + if (!is_inlined) { + compiler_exit_scope(c); + } error: - Py_XDECREF(qualname); Py_XDECREF(co); - return 0; + Py_XDECREF(entry); + Py_XDECREF(inline_state.pushed_locals); + Py_XDECREF(inline_state.temp_symbols); + Py_XDECREF(inline_state.fast_hidden); + return ERROR; } static int @@ -5575,28 +5819,30 @@ static int compiler_visit_keyword(struct compiler *c, keyword_ty k) { VISIT(c, expr, k->value); - return 1; + return SUCCESS; } static int -compiler_with_except_finish(struct compiler *c, basicblock * cleanup) { - UNSET_LOC(c); - basicblock *exit; - exit = compiler_new_block(c); - if (exit == NULL) - return 0; - ADDOP_JUMP(c, POP_JUMP_IF_TRUE, exit); - ADDOP_I(c, RERAISE, 2); - compiler_use_next_block(c, cleanup); - POP_EXCEPT_AND_RERAISE(c); - compiler_use_next_block(c, exit); - ADDOP(c, POP_TOP); /* exc_value */ - ADDOP(c, POP_BLOCK); - ADDOP(c, POP_EXCEPT); - ADDOP(c, POP_TOP); - ADDOP(c, POP_TOP); - return 1; +compiler_with_except_finish(struct compiler *c, jump_target_label cleanup) { + NEW_JUMP_TARGET_LABEL(c, suppress); + ADDOP_JUMP(c, NO_LOCATION, POP_JUMP_IF_TRUE, suppress); + ADDOP_I(c, NO_LOCATION, RERAISE, 2); + + USE_LABEL(c, suppress); + ADDOP(c, NO_LOCATION, POP_TOP); /* exc_value */ + ADDOP(c, NO_LOCATION, POP_BLOCK); + ADDOP(c, NO_LOCATION, POP_EXCEPT); + ADDOP(c, NO_LOCATION, POP_TOP); + ADDOP(c, NO_LOCATION, POP_TOP); + NEW_JUMP_TARGET_LABEL(c, exit); + ADDOP_JUMP(c, NO_LOCATION, JUMP, exit); + + USE_LABEL(c, cleanup); + POP_EXCEPT_AND_RERAISE(c, NO_LOCATION); + + USE_LABEL(c, exit); + return SUCCESS; } /* @@ -5626,85 +5872,82 @@ compiler_with_except_finish(struct compiler *c, basicblock * cleanup) { static int compiler_async_with(struct compiler *c, stmt_ty s, int pos) { - basicblock *block, *final, *exit, *cleanup; + location loc = LOC(s); withitem_ty item = asdl_seq_GET(s->v.AsyncWith.items, pos); assert(s->kind == AsyncWith_kind); if (IS_TOP_LEVEL_AWAIT(c)){ c->u->u_ste->ste_coroutine = 1; } else if (c->u->u_scope_type != COMPILER_SCOPE_ASYNC_FUNCTION){ - return compiler_error(c, "'async with' outside async function"); + return compiler_error(c, loc, "'async with' outside async function"); } - block = compiler_new_block(c); - final = compiler_new_block(c); - exit = compiler_new_block(c); - cleanup = compiler_new_block(c); - if (!block || !final || !exit || !cleanup) - return 0; + NEW_JUMP_TARGET_LABEL(c, block); + NEW_JUMP_TARGET_LABEL(c, final); + NEW_JUMP_TARGET_LABEL(c, exit); + NEW_JUMP_TARGET_LABEL(c, cleanup); /* Evaluate EXPR */ VISIT(c, expr, item->context_expr); - ADDOP(c, BEFORE_ASYNC_WITH); - ADDOP_I(c, GET_AWAITABLE, 1); - ADDOP_LOAD_CONST(c, Py_None); - ADD_YIELD_FROM(c, 1); + ADDOP(c, loc, BEFORE_ASYNC_WITH); + ADDOP_I(c, loc, GET_AWAITABLE, 1); + ADDOP_LOAD_CONST(c, loc, Py_None); + ADD_YIELD_FROM(c, loc, 1); - ADDOP_JUMP(c, SETUP_WITH, final); + ADDOP_JUMP(c, loc, SETUP_WITH, final); /* SETUP_WITH pushes a finally block. */ - compiler_use_next_block(c, block); - if (!compiler_push_fblock(c, ASYNC_WITH, block, final, s)) { - return 0; - } + USE_LABEL(c, block); + RETURN_IF_ERROR(compiler_push_fblock(c, loc, ASYNC_WITH, block, final, s)); if (item->optional_vars) { VISIT(c, expr, item->optional_vars); } else { - /* Discard result from context.__aenter__() */ - ADDOP(c, POP_TOP); + /* Discard result from context.__aenter__() */ + ADDOP(c, loc, POP_TOP); } pos++; - if (pos == asdl_seq_LEN(s->v.AsyncWith.items)) + if (pos == asdl_seq_LEN(s->v.AsyncWith.items)) { /* BLOCK code */ VISIT_SEQ(c, stmt, s->v.AsyncWith.body) - else if (!compiler_async_with(c, s, pos)) - return 0; + } + else { + RETURN_IF_ERROR(compiler_async_with(c, s, pos)); + } compiler_pop_fblock(c, ASYNC_WITH, block); - ADDOP(c, POP_BLOCK); + + ADDOP(c, loc, POP_BLOCK); /* End of body; start the cleanup */ /* For successful outcome: * call __exit__(None, None, None) */ - SET_LOC(c, s); - if(!compiler_call_exit_with_nones(c)) - return 0; - ADDOP_I(c, GET_AWAITABLE, 2); - ADDOP_LOAD_CONST(c, Py_None); - ADD_YIELD_FROM(c, 1); + RETURN_IF_ERROR(compiler_call_exit_with_nones(c, loc)); + ADDOP_I(c, loc, GET_AWAITABLE, 2); + ADDOP_LOAD_CONST(c, loc, Py_None); + ADD_YIELD_FROM(c, loc, 1); - ADDOP(c, POP_TOP); + ADDOP(c, loc, POP_TOP); - ADDOP_JUMP(c, JUMP, exit); + ADDOP_JUMP(c, loc, JUMP, exit); /* For exceptional outcome: */ - compiler_use_next_block(c, final); + USE_LABEL(c, final); - ADDOP_JUMP(c, SETUP_CLEANUP, cleanup); - ADDOP(c, PUSH_EXC_INFO); - ADDOP(c, WITH_EXCEPT_START); - ADDOP_I(c, GET_AWAITABLE, 2); - ADDOP_LOAD_CONST(c, Py_None); - ADD_YIELD_FROM(c, 1); - compiler_with_except_finish(c, cleanup); + ADDOP_JUMP(c, loc, SETUP_CLEANUP, cleanup); + ADDOP(c, loc, PUSH_EXC_INFO); + ADDOP(c, loc, WITH_EXCEPT_START); + ADDOP_I(c, loc, GET_AWAITABLE, 2); + ADDOP_LOAD_CONST(c, loc, Py_None); + ADD_YIELD_FROM(c, loc, 1); + RETURN_IF_ERROR(compiler_with_except_finish(c, cleanup)); - compiler_use_next_block(c, exit); - return 1; + USE_LABEL(c, exit); + return SUCCESS; } @@ -5732,49 +5975,44 @@ compiler_async_with(struct compiler *c, stmt_ty s, int pos) static int compiler_with(struct compiler *c, stmt_ty s, int pos) { - basicblock *block, *final, *exit, *cleanup; withitem_ty item = asdl_seq_GET(s->v.With.items, pos); assert(s->kind == With_kind); - block = compiler_new_block(c); - final = compiler_new_block(c); - exit = compiler_new_block(c); - cleanup = compiler_new_block(c); - if (!block || !final || !exit || !cleanup) - return 0; + NEW_JUMP_TARGET_LABEL(c, block); + NEW_JUMP_TARGET_LABEL(c, final); + NEW_JUMP_TARGET_LABEL(c, exit); + NEW_JUMP_TARGET_LABEL(c, cleanup); /* Evaluate EXPR */ VISIT(c, expr, item->context_expr); /* Will push bound __exit__ */ - ADDOP(c, BEFORE_WITH); - ADDOP_JUMP(c, SETUP_WITH, final); + location loc = LOC(s); + ADDOP(c, loc, BEFORE_WITH); + ADDOP_JUMP(c, loc, SETUP_WITH, final); /* SETUP_WITH pushes a finally block. */ - compiler_use_next_block(c, block); - if (!compiler_push_fblock(c, WITH, block, final, s)) { - return 0; - } + USE_LABEL(c, block); + RETURN_IF_ERROR(compiler_push_fblock(c, loc, WITH, block, final, s)); if (item->optional_vars) { VISIT(c, expr, item->optional_vars); } else { /* Discard result from context.__enter__() */ - ADDOP(c, POP_TOP); + ADDOP(c, loc, POP_TOP); } pos++; - if (pos == asdl_seq_LEN(s->v.With.items)) + if (pos == asdl_seq_LEN(s->v.With.items)) { /* BLOCK code */ VISIT_SEQ(c, stmt, s->v.With.body) - else if (!compiler_with(c, s, pos)) - return 0; - + } + else { + RETURN_IF_ERROR(compiler_with(c, s, pos)); + } - /* Mark all following code as artificial */ - UNSET_LOC(c); - ADDOP(c, POP_BLOCK); + ADDOP(c, NO_LOCATION, POP_BLOCK); compiler_pop_fblock(c, WITH, block); /* End of body; start the cleanup. */ @@ -5782,31 +6020,31 @@ compiler_with(struct compiler *c, stmt_ty s, int pos) /* For successful outcome: * call __exit__(None, None, None) */ - SET_LOC(c, s); - if (!compiler_call_exit_with_nones(c)) - return 0; - ADDOP(c, POP_TOP); - ADDOP_JUMP(c, JUMP, exit); + loc = LOC(s); + RETURN_IF_ERROR(compiler_call_exit_with_nones(c, loc)); + ADDOP(c, loc, POP_TOP); + ADDOP_JUMP(c, loc, JUMP, exit); /* For exceptional outcome: */ - compiler_use_next_block(c, final); + USE_LABEL(c, final); - ADDOP_JUMP(c, SETUP_CLEANUP, cleanup); - ADDOP(c, PUSH_EXC_INFO); - ADDOP(c, WITH_EXCEPT_START); - compiler_with_except_finish(c, cleanup); + ADDOP_JUMP(c, loc, SETUP_CLEANUP, cleanup); + ADDOP(c, loc, PUSH_EXC_INFO); + ADDOP(c, loc, WITH_EXCEPT_START); + RETURN_IF_ERROR(compiler_with_except_finish(c, cleanup)); - compiler_use_next_block(c, exit); - return 1; + USE_LABEL(c, exit); + return SUCCESS; } static int compiler_visit_expr1(struct compiler *c, expr_ty e) { + location loc = LOC(e); switch (e->kind) { case NamedExpr_kind: VISIT(c, expr, e->v.NamedExpr.value); - ADDOP_I(c, COPY, 1); + ADDOP_I(c, loc, COPY, 1); VISIT(c, expr, e->v.NamedExpr.target); break; case BoolOp_kind: @@ -5814,11 +6052,16 @@ compiler_visit_expr1(struct compiler *c, expr_ty e) case BinOp_kind: VISIT(c, expr, e->v.BinOp.left); VISIT(c, expr, e->v.BinOp.right); - ADDOP_BINARY(c, e->v.BinOp.op); + ADDOP_BINARY(c, loc, e->v.BinOp.op); break; case UnaryOp_kind: VISIT(c, expr, e->v.UnaryOp.operand); - ADDOP(c, unaryop(e->v.UnaryOp.op)); + if (e->v.UnaryOp.op == UAdd) { + ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_UNARY_POSITIVE); + } + else { + ADDOP(c, loc, unaryop(e->v.UnaryOp.op)); + } break; case Lambda_kind: return compiler_lambda(c, e); @@ -5837,51 +6080,52 @@ compiler_visit_expr1(struct compiler *c, expr_ty e) case DictComp_kind: return compiler_dictcomp(c, e); case Yield_kind: - if (c->u->u_ste->ste_type != FunctionBlock) - return compiler_error(c, "'yield' outside function"); + if (!_PyST_IsFunctionLike(c->u->u_ste)) { + return compiler_error(c, loc, "'yield' outside function"); + } if (e->v.Yield.value) { VISIT(c, expr, e->v.Yield.value); } else { - ADDOP_LOAD_CONST(c, Py_None); + ADDOP_LOAD_CONST(c, loc, Py_None); } - ADDOP_YIELD(c); + ADDOP_YIELD(c, loc); break; case YieldFrom_kind: - if (c->u->u_ste->ste_type != FunctionBlock) - return compiler_error(c, "'yield' outside function"); - - if (c->u->u_scope_type == COMPILER_SCOPE_ASYNC_FUNCTION) - return compiler_error(c, "'yield from' inside async function"); - + if (!_PyST_IsFunctionLike(c->u->u_ste)) { + return compiler_error(c, loc, "'yield' outside function"); + } + if (c->u->u_scope_type == COMPILER_SCOPE_ASYNC_FUNCTION) { + return compiler_error(c, loc, "'yield from' inside async function"); + } VISIT(c, expr, e->v.YieldFrom.value); - ADDOP(c, GET_YIELD_FROM_ITER); - ADDOP_LOAD_CONST(c, Py_None); - ADD_YIELD_FROM(c, 0); + ADDOP(c, loc, GET_YIELD_FROM_ITER); + ADDOP_LOAD_CONST(c, loc, Py_None); + ADD_YIELD_FROM(c, loc, 0); break; case Await_kind: if (!IS_TOP_LEVEL_AWAIT(c)){ - if (c->u->u_ste->ste_type != FunctionBlock){ - return compiler_error(c, "'await' outside function"); + if (!_PyST_IsFunctionLike(c->u->u_ste)) { + return compiler_error(c, loc, "'await' outside function"); } if (c->u->u_scope_type != COMPILER_SCOPE_ASYNC_FUNCTION && - c->u->u_scope_type != COMPILER_SCOPE_COMPREHENSION){ - return compiler_error(c, "'await' outside async function"); + c->u->u_scope_type != COMPILER_SCOPE_COMPREHENSION) { + return compiler_error(c, loc, "'await' outside async function"); } } VISIT(c, expr, e->v.Await.value); - ADDOP_I(c, GET_AWAITABLE, 0); - ADDOP_LOAD_CONST(c, Py_None); - ADD_YIELD_FROM(c, 1); + ADDOP_I(c, loc, GET_AWAITABLE, 0); + ADDOP_LOAD_CONST(c, loc, Py_None); + ADD_YIELD_FROM(c, loc, 1); break; case Compare_kind: return compiler_compare(c, e); case Call_kind: return compiler_call(c, e); case Constant_kind: - ADDOP_LOAD_CONST(c, e->v.Constant.value); + ADDOP_LOAD_CONST(c, loc, e->v.Constant.value); break; case JoinedStr_kind: return compiler_joined_str(c, e); @@ -5889,22 +6133,30 @@ compiler_visit_expr1(struct compiler *c, expr_ty e) return compiler_formatted_value(c, e); /* The following exprs can be assignment targets. */ case Attribute_kind: + if (e->v.Attribute.ctx == Load && can_optimize_super_call(c, e)) { + RETURN_IF_ERROR(load_args_for_super(c, e->v.Attribute.value)); + int opcode = asdl_seq_LEN(e->v.Attribute.value->v.Call.args) ? + LOAD_SUPER_ATTR : LOAD_ZERO_SUPER_ATTR; + ADDOP_NAME(c, loc, opcode, e->v.Attribute.attr, names); + loc = update_start_location_to_match_attr(c, loc, e); + ADDOP(c, loc, NOP); + return SUCCESS; + } VISIT(c, expr, e->v.Attribute.value); - update_start_location_to_match_attr(c, e); + loc = LOC(e); + loc = update_start_location_to_match_attr(c, loc, e); switch (e->v.Attribute.ctx) { case Load: - { - ADDOP_NAME(c, LOAD_ATTR, e->v.Attribute.attr, names); + ADDOP_NAME(c, loc, LOAD_ATTR, e->v.Attribute.attr, names); break; - } case Store: - if (forbidden_name(c, e->v.Attribute.attr, e->v.Attribute.ctx)) { - return 0; + if (forbidden_name(c, loc, e->v.Attribute.attr, e->v.Attribute.ctx)) { + return ERROR; } - ADDOP_NAME(c, STORE_ATTR, e->v.Attribute.attr, names); + ADDOP_NAME(c, loc, STORE_ATTR, e->v.Attribute.attr, names); break; case Del: - ADDOP_NAME(c, DELETE_ATTR, e->v.Attribute.attr, names); + ADDOP_NAME(c, loc, DELETE_ATTR, e->v.Attribute.attr, names); break; } break; @@ -5915,114 +6167,126 @@ compiler_visit_expr1(struct compiler *c, expr_ty e) case Store: /* In all legitimate cases, the Starred node was already replaced * by compiler_list/compiler_tuple. XXX: is that okay? */ - return compiler_error(c, + return compiler_error(c, loc, "starred assignment target must be in a list or tuple"); default: - return compiler_error(c, + return compiler_error(c, loc, "can't use starred expression here"); } break; case Slice_kind: - return compiler_slice(c, e); + { + int n = compiler_slice(c, e); + RETURN_IF_ERROR(n); + ADDOP_I(c, loc, BUILD_SLICE, n); + break; + } case Name_kind: - return compiler_nameop(c, e->v.Name.id, e->v.Name.ctx); + return compiler_nameop(c, loc, e->v.Name.id, e->v.Name.ctx); /* child nodes of List and Tuple will have expr_context set */ case List_kind: return compiler_list(c, e); case Tuple_kind: return compiler_tuple(c, e); } - return 1; + return SUCCESS; } static int compiler_visit_expr(struct compiler *c, expr_ty e) { - int old_lineno = c->u->u_lineno; - int old_end_lineno = c->u->u_end_lineno; - int old_col_offset = c->u->u_col_offset; - int old_end_col_offset = c->u->u_end_col_offset; - SET_LOC(c, e); int res = compiler_visit_expr1(c, e); - c->u->u_lineno = old_lineno; - c->u->u_end_lineno = old_end_lineno; - c->u->u_col_offset = old_col_offset; - c->u->u_end_col_offset = old_end_col_offset; return res; } +static bool +is_two_element_slice(expr_ty s) +{ + return s->kind == Slice_kind && + s->v.Slice.step == NULL; +} + static int compiler_augassign(struct compiler *c, stmt_ty s) { assert(s->kind == AugAssign_kind); expr_ty e = s->v.AugAssign.target; - int old_lineno = c->u->u_lineno; - int old_end_lineno = c->u->u_end_lineno; - int old_col_offset = c->u->u_col_offset; - int old_end_col_offset = c->u->u_end_col_offset; - SET_LOC(c, e); + location loc = LOC(e); switch (e->kind) { case Attribute_kind: VISIT(c, expr, e->v.Attribute.value); - ADDOP_I(c, COPY, 1); - update_start_location_to_match_attr(c, e); - ADDOP_NAME(c, LOAD_ATTR, e->v.Attribute.attr, names); + ADDOP_I(c, loc, COPY, 1); + loc = update_start_location_to_match_attr(c, loc, e); + ADDOP_NAME(c, loc, LOAD_ATTR, e->v.Attribute.attr, names); break; case Subscript_kind: VISIT(c, expr, e->v.Subscript.value); - VISIT(c, expr, e->v.Subscript.slice); - ADDOP_I(c, COPY, 2); - ADDOP_I(c, COPY, 2); - ADDOP(c, BINARY_SUBSCR); + if (is_two_element_slice(e->v.Subscript.slice)) { + RETURN_IF_ERROR(compiler_slice(c, e->v.Subscript.slice)); + ADDOP_I(c, loc, COPY, 3); + ADDOP_I(c, loc, COPY, 3); + ADDOP_I(c, loc, COPY, 3); + ADDOP(c, loc, BINARY_SLICE); + } + else { + VISIT(c, expr, e->v.Subscript.slice); + ADDOP_I(c, loc, COPY, 2); + ADDOP_I(c, loc, COPY, 2); + ADDOP(c, loc, BINARY_SUBSCR); + } break; case Name_kind: - if (!compiler_nameop(c, e->v.Name.id, Load)) - return 0; + RETURN_IF_ERROR(compiler_nameop(c, loc, e->v.Name.id, Load)); break; default: PyErr_Format(PyExc_SystemError, "invalid node type (%d) for augmented assignment", e->kind); - return 0; + return ERROR; } - c->u->u_lineno = old_lineno; - c->u->u_end_lineno = old_end_lineno; - c->u->u_col_offset = old_col_offset; - c->u->u_end_col_offset = old_end_col_offset; + loc = LOC(s); VISIT(c, expr, s->v.AugAssign.value); - ADDOP_INPLACE(c, s->v.AugAssign.op); + ADDOP_INPLACE(c, loc, s->v.AugAssign.op); - SET_LOC(c, e); + loc = LOC(e); switch (e->kind) { case Attribute_kind: - update_start_location_to_match_attr(c, e); - ADDOP_I(c, SWAP, 2); - ADDOP_NAME(c, STORE_ATTR, e->v.Attribute.attr, names); + loc = update_start_location_to_match_attr(c, loc, e); + ADDOP_I(c, loc, SWAP, 2); + ADDOP_NAME(c, loc, STORE_ATTR, e->v.Attribute.attr, names); break; case Subscript_kind: - ADDOP_I(c, SWAP, 3); - ADDOP_I(c, SWAP, 2); - ADDOP(c, STORE_SUBSCR); + if (is_two_element_slice(e->v.Subscript.slice)) { + ADDOP_I(c, loc, SWAP, 4); + ADDOP_I(c, loc, SWAP, 3); + ADDOP_I(c, loc, SWAP, 2); + ADDOP(c, loc, STORE_SLICE); + } + else { + ADDOP_I(c, loc, SWAP, 3); + ADDOP_I(c, loc, SWAP, 2); + ADDOP(c, loc, STORE_SUBSCR); + } break; case Name_kind: - return compiler_nameop(c, e->v.Name.id, Store); + return compiler_nameop(c, loc, e->v.Name.id, Store); default: Py_UNREACHABLE(); } - return 1; + return SUCCESS; } static int check_ann_expr(struct compiler *c, expr_ty e) { VISIT(c, expr, e); - ADDOP(c, POP_TOP); - return 1; + ADDOP(c, LOC(e), POP_TOP); + return SUCCESS; } static int @@ -6030,8 +6294,8 @@ check_annotation(struct compiler *c, stmt_ty s) { /* Annotations of complex targets does not produce anything under annotations future */ - if (c->c_future->ff_features & CO_FUTURE_ANNOTATIONS) { - return 1; + if (c->c_future.ff_features & CO_FUTURE_ANNOTATIONS) { + return SUCCESS; } /* Annotations are only evaluated in a module or class. */ @@ -6039,7 +6303,7 @@ check_annotation(struct compiler *c, stmt_ty s) c->u->u_scope_type == COMPILER_SCOPE_CLASS) { return check_ann_expr(c, s->v.AnnAssign.annotation); } - return 1; + return SUCCESS; } static int @@ -6048,26 +6312,24 @@ check_ann_subscr(struct compiler *c, expr_ty e) /* We check that everything in a subscript is defined at runtime. */ switch (e->kind) { case Slice_kind: - if (e->v.Slice.lower && !check_ann_expr(c, e->v.Slice.lower)) { - return 0; + if (e->v.Slice.lower && check_ann_expr(c, e->v.Slice.lower) < 0) { + return ERROR; } - if (e->v.Slice.upper && !check_ann_expr(c, e->v.Slice.upper)) { - return 0; + if (e->v.Slice.upper && check_ann_expr(c, e->v.Slice.upper) < 0) { + return ERROR; } - if (e->v.Slice.step && !check_ann_expr(c, e->v.Slice.step)) { - return 0; + if (e->v.Slice.step && check_ann_expr(c, e->v.Slice.step) < 0) { + return ERROR; } - return 1; + return SUCCESS; case Tuple_kind: { /* extended slice */ asdl_expr_seq *elts = e->v.Tuple.elts; Py_ssize_t i, n = asdl_seq_LEN(elts); for (i = 0; i < n; i++) { - if (!check_ann_subscr(c, asdl_seq_GET(elts, i))) { - return 0; - } + RETURN_IF_ERROR(check_ann_subscr(c, asdl_seq_GET(elts, i))); } - return 1; + return SUCCESS; } default: return check_ann_expr(c, e); @@ -6077,6 +6339,7 @@ check_ann_subscr(struct compiler *c, expr_ty e) static int compiler_annassign(struct compiler *c, stmt_ty s) { + location loc = LOC(s); expr_ty targ = s->v.AnnAssign.target; PyObject* mangled; @@ -6089,50 +6352,52 @@ compiler_annassign(struct compiler *c, stmt_ty s) } switch (targ->kind) { case Name_kind: - if (forbidden_name(c, targ->v.Name.id, Store)) - return 0; + if (forbidden_name(c, loc, targ->v.Name.id, Store)) { + return ERROR; + } /* If we have a simple name in a module or class, store annotation. */ if (s->v.AnnAssign.simple && (c->u->u_scope_type == COMPILER_SCOPE_MODULE || c->u->u_scope_type == COMPILER_SCOPE_CLASS)) { - if (c->c_future->ff_features & CO_FUTURE_ANNOTATIONS) { + if (c->c_future.ff_features & CO_FUTURE_ANNOTATIONS) { VISIT(c, annexpr, s->v.AnnAssign.annotation) } else { VISIT(c, expr, s->v.AnnAssign.annotation); } - ADDOP_NAME(c, LOAD_NAME, &_Py_ID(__annotations__), names); + ADDOP_NAME(c, loc, LOAD_NAME, &_Py_ID(__annotations__), names); mangled = _Py_Mangle(c->u->u_private, targ->v.Name.id); - ADDOP_LOAD_CONST_NEW(c, mangled); - ADDOP(c, STORE_SUBSCR); + ADDOP_LOAD_CONST_NEW(c, loc, mangled); + ADDOP(c, loc, STORE_SUBSCR); } break; case Attribute_kind: - if (forbidden_name(c, targ->v.Attribute.attr, Store)) - return 0; + if (forbidden_name(c, loc, targ->v.Attribute.attr, Store)) { + return ERROR; + } if (!s->v.AnnAssign.value && - !check_ann_expr(c, targ->v.Attribute.value)) { - return 0; + check_ann_expr(c, targ->v.Attribute.value) < 0) { + return ERROR; } break; case Subscript_kind: if (!s->v.AnnAssign.value && - (!check_ann_expr(c, targ->v.Subscript.value) || - !check_ann_subscr(c, targ->v.Subscript.slice))) { - return 0; + (check_ann_expr(c, targ->v.Subscript.value) < 0 || + check_ann_subscr(c, targ->v.Subscript.slice) < 0)) { + return ERROR; } break; default: PyErr_Format(PyExc_SystemError, "invalid node type (%d) for annotated assignment", targ->kind); - return 0; + return ERROR; } /* Annotation is evaluated last. */ - if (!s->v.AnnAssign.simple && !check_annotation(c, s)) { - return 0; + if (!s->v.AnnAssign.simple && check_annotation(c, s) < 0) { + return ERROR; } - return 1; + return SUCCESS; } /* Raises a SyntaxError and returns 0. @@ -6140,36 +6405,32 @@ compiler_annassign(struct compiler *c, stmt_ty s) */ static int -compiler_error(struct compiler *c, const char *format, ...) +compiler_error(struct compiler *c, location loc, + const char *format, ...) { va_list vargs; -#ifdef HAVE_STDARG_PROTOTYPES va_start(vargs, format); -#else - va_start(vargs); -#endif PyObject *msg = PyUnicode_FromFormatV(format, vargs); va_end(vargs); if (msg == NULL) { - return 0; + return ERROR; } - PyObject *loc = PyErr_ProgramTextObject(c->c_filename, c->u->u_lineno); - if (loc == NULL) { - Py_INCREF(Py_None); - loc = Py_None; + PyObject *loc_obj = PyErr_ProgramTextObject(c->c_filename, loc.lineno); + if (loc_obj == NULL) { + loc_obj = Py_NewRef(Py_None); } PyObject *args = Py_BuildValue("O(OiiOii)", msg, c->c_filename, - c->u->u_lineno, c->u->u_col_offset + 1, loc, - c->u->u_end_lineno, c->u->u_end_col_offset + 1); + loc.lineno, loc.col_offset + 1, loc_obj, + loc.end_lineno, loc.end_col_offset + 1); Py_DECREF(msg); if (args == NULL) { goto exit; } PyErr_SetObject(PyExc_SyntaxError, args); exit: - Py_DECREF(loc); + Py_DECREF(loc_obj); Py_XDECREF(args); - return 0; + return ERROR; } /* Emits a SyntaxWarning and returns 1 on success. @@ -6177,63 +6438,71 @@ compiler_error(struct compiler *c, const char *format, ...) and returns 0. */ static int -compiler_warn(struct compiler *c, const char *format, ...) +compiler_warn(struct compiler *c, location loc, + const char *format, ...) { va_list vargs; -#ifdef HAVE_STDARG_PROTOTYPES va_start(vargs, format); -#else - va_start(vargs); -#endif PyObject *msg = PyUnicode_FromFormatV(format, vargs); va_end(vargs); if (msg == NULL) { - return 0; + return ERROR; } if (PyErr_WarnExplicitObject(PyExc_SyntaxWarning, msg, c->c_filename, - c->u->u_lineno, NULL, NULL) < 0) + loc.lineno, NULL, NULL) < 0) { if (PyErr_ExceptionMatches(PyExc_SyntaxWarning)) { /* Replace the SyntaxWarning exception with a SyntaxError to get a more accurate error report */ PyErr_Clear(); assert(PyUnicode_AsUTF8(msg) != NULL); - compiler_error(c, PyUnicode_AsUTF8(msg)); + compiler_error(c, loc, PyUnicode_AsUTF8(msg)); } Py_DECREF(msg); - return 0; + return ERROR; } Py_DECREF(msg); - return 1; + return SUCCESS; } static int compiler_subscript(struct compiler *c, expr_ty e) { + location loc = LOC(e); expr_context_ty ctx = e->v.Subscript.ctx; int op = 0; if (ctx == Load) { - if (!check_subscripter(c, e->v.Subscript.value)) { - return 0; + RETURN_IF_ERROR(check_subscripter(c, e->v.Subscript.value)); + RETURN_IF_ERROR(check_index(c, e->v.Subscript.value, e->v.Subscript.slice)); + } + + VISIT(c, expr, e->v.Subscript.value); + if (is_two_element_slice(e->v.Subscript.slice) && ctx != Del) { + RETURN_IF_ERROR(compiler_slice(c, e->v.Subscript.slice)); + if (ctx == Load) { + ADDOP(c, loc, BINARY_SLICE); } - if (!check_index(c, e->v.Subscript.value, e->v.Subscript.slice)) { - return 0; + else { + assert(ctx == Store); + ADDOP(c, loc, STORE_SLICE); } } - - switch (ctx) { - case Load: op = BINARY_SUBSCR; break; - case Store: op = STORE_SUBSCR; break; - case Del: op = DELETE_SUBSCR; break; + else { + VISIT(c, expr, e->v.Subscript.slice); + switch (ctx) { + case Load: op = BINARY_SUBSCR; break; + case Store: op = STORE_SUBSCR; break; + case Del: op = DELETE_SUBSCR; break; + } + assert(op); + ADDOP(c, loc, op); } - assert(op); - VISIT(c, expr, e->v.Subscript.value); - VISIT(c, expr, e->v.Subscript.slice); - ADDOP(c, op); - return 1; + return SUCCESS; } +/* Returns the number of the values emitted, + * thus are needed to build the slice, or -1 if there is an error. */ static int compiler_slice(struct compiler *c, expr_ty s) { @@ -6245,22 +6514,21 @@ compiler_slice(struct compiler *c, expr_ty s) VISIT(c, expr, s->v.Slice.lower); } else { - ADDOP_LOAD_CONST(c, Py_None); + ADDOP_LOAD_CONST(c, LOC(s), Py_None); } if (s->v.Slice.upper) { VISIT(c, expr, s->v.Slice.upper); } else { - ADDOP_LOAD_CONST(c, Py_None); + ADDOP_LOAD_CONST(c, LOC(s), Py_None); } if (s->v.Slice.step) { n++; VISIT(c, expr, s->v.Slice.step); } - ADDOP_I(c, BUILD_SLICE, n); - return 1; + return n; } @@ -6292,101 +6560,104 @@ ensure_fail_pop(struct compiler *c, pattern_context *pc, Py_ssize_t n) { Py_ssize_t size = n + 1; if (size <= pc->fail_pop_size) { - return 1; + return SUCCESS; } - Py_ssize_t needed = sizeof(basicblock*) * size; - basicblock **resized = PyObject_Realloc(pc->fail_pop, needed); + Py_ssize_t needed = sizeof(jump_target_label) * size; + jump_target_label *resized = PyObject_Realloc(pc->fail_pop, needed); if (resized == NULL) { PyErr_NoMemory(); - return 0; + return ERROR; } pc->fail_pop = resized; while (pc->fail_pop_size < size) { - basicblock *new_block; - RETURN_IF_FALSE(new_block = compiler_new_block(c)); + NEW_JUMP_TARGET_LABEL(c, new_block); pc->fail_pop[pc->fail_pop_size++] = new_block; } - return 1; + return SUCCESS; } // Use op to jump to the correct fail_pop block. static int -jump_to_fail_pop(struct compiler *c, pattern_context *pc, int op) +jump_to_fail_pop(struct compiler *c, location loc, + pattern_context *pc, int op) { // Pop any items on the top of the stack, plus any objects we were going to // capture on success: Py_ssize_t pops = pc->on_top + PyList_GET_SIZE(pc->stores); - RETURN_IF_FALSE(ensure_fail_pop(c, pc, pops)); - ADDOP_JUMP(c, op, pc->fail_pop[pops]); - return 1; + RETURN_IF_ERROR(ensure_fail_pop(c, pc, pops)); + ADDOP_JUMP(c, loc, op, pc->fail_pop[pops]); + return SUCCESS; } // Build all of the fail_pop blocks and reset fail_pop. static int -emit_and_reset_fail_pop(struct compiler *c, pattern_context *pc) +emit_and_reset_fail_pop(struct compiler *c, location loc, + pattern_context *pc) { if (!pc->fail_pop_size) { assert(pc->fail_pop == NULL); - return 1; + return SUCCESS; } while (--pc->fail_pop_size) { - compiler_use_next_block(c, pc->fail_pop[pc->fail_pop_size]); - if (!compiler_addop(c, POP_TOP)) { + USE_LABEL(c, pc->fail_pop[pc->fail_pop_size]); + if (codegen_addop_noarg(INSTR_SEQUENCE(c), POP_TOP, loc) < 0) { pc->fail_pop_size = 0; PyObject_Free(pc->fail_pop); pc->fail_pop = NULL; - return 0; + return ERROR; } } - compiler_use_next_block(c, pc->fail_pop[0]); + USE_LABEL(c, pc->fail_pop[0]); PyObject_Free(pc->fail_pop); pc->fail_pop = NULL; - return 1; + return SUCCESS; } static int -compiler_error_duplicate_store(struct compiler *c, identifier n) +compiler_error_duplicate_store(struct compiler *c, location loc, identifier n) { - return compiler_error(c, "multiple assignments to name %R in pattern", n); + return compiler_error(c, loc, + "multiple assignments to name %R in pattern", n); } // Duplicate the effect of 3.10's ROT_* instructions using SWAPs. static int -pattern_helper_rotate(struct compiler *c, Py_ssize_t count) +pattern_helper_rotate(struct compiler *c, location loc, Py_ssize_t count) { while (1 < count) { - ADDOP_I(c, SWAP, count--); + ADDOP_I(c, loc, SWAP, count--); } - return 1; + return SUCCESS; } static int -pattern_helper_store_name(struct compiler *c, identifier n, pattern_context *pc) +pattern_helper_store_name(struct compiler *c, location loc, + identifier n, pattern_context *pc) { if (n == NULL) { - ADDOP(c, POP_TOP); - return 1; + ADDOP(c, loc, POP_TOP); + return SUCCESS; } - if (forbidden_name(c, n, Store)) { - return 0; + if (forbidden_name(c, loc, n, Store)) { + return ERROR; } // Can't assign to the same name twice: int duplicate = PySequence_Contains(pc->stores, n); - if (duplicate < 0) { - return 0; - } + RETURN_IF_ERROR(duplicate); if (duplicate) { - return compiler_error_duplicate_store(c, n); + return compiler_error_duplicate_store(c, loc, n); } // Rotate this object underneath any items we need to preserve: Py_ssize_t rotations = pc->on_top + PyList_GET_SIZE(pc->stores) + 1; - RETURN_IF_FALSE(pattern_helper_rotate(c, rotations)); - return !PyList_Append(pc->stores, n); + RETURN_IF_ERROR(pattern_helper_rotate(c, loc, rotations)); + RETURN_IF_ERROR(PyList_Append(pc->stores, n)); + return SUCCESS; } static int -pattern_unpack_helper(struct compiler *c, asdl_pattern_seq *elts) +pattern_unpack_helper(struct compiler *c, location loc, + asdl_pattern_seq *elts) { Py_ssize_t n = asdl_seq_LEN(elts); int seen_star = 0; @@ -6394,29 +6665,31 @@ pattern_unpack_helper(struct compiler *c, asdl_pattern_seq *elts) pattern_ty elt = asdl_seq_GET(elts, i); if (elt->kind == MatchStar_kind && !seen_star) { if ((i >= (1 << 8)) || - (n-i-1 >= (INT_MAX >> 8))) - return compiler_error(c, + (n-i-1 >= (INT_MAX >> 8))) { + return compiler_error(c, loc, "too many expressions in " "star-unpacking sequence pattern"); - ADDOP_I(c, UNPACK_EX, (i + ((n-i-1) << 8))); + } + ADDOP_I(c, loc, UNPACK_EX, (i + ((n-i-1) << 8))); seen_star = 1; } else if (elt->kind == MatchStar_kind) { - return compiler_error(c, + return compiler_error(c, loc, "multiple starred expressions in sequence pattern"); } } if (!seen_star) { - ADDOP_I(c, UNPACK_SEQUENCE, n); + ADDOP_I(c, loc, UNPACK_SEQUENCE, n); } - return 1; + return SUCCESS; } static int -pattern_helper_sequence_unpack(struct compiler *c, asdl_pattern_seq *patterns, - Py_ssize_t star, pattern_context *pc) +pattern_helper_sequence_unpack(struct compiler *c, location loc, + asdl_pattern_seq *patterns, Py_ssize_t star, + pattern_context *pc) { - RETURN_IF_FALSE(pattern_unpack_helper(c, patterns)); + RETURN_IF_ERROR(pattern_unpack_helper(c, loc, patterns)); Py_ssize_t size = asdl_seq_LEN(patterns); // We've now got a bunch of new subjects on the stack. They need to remain // there after each subpattern match: @@ -6425,17 +6698,18 @@ pattern_helper_sequence_unpack(struct compiler *c, asdl_pattern_seq *patterns, // One less item to keep track of each time we loop through: pc->on_top--; pattern_ty pattern = asdl_seq_GET(patterns, i); - RETURN_IF_FALSE(compiler_pattern_subpattern(c, pattern, pc)); + RETURN_IF_ERROR(compiler_pattern_subpattern(c, pattern, pc)); } - return 1; + return SUCCESS; } // Like pattern_helper_sequence_unpack, but uses BINARY_SUBSCR instead of // UNPACK_SEQUENCE / UNPACK_EX. This is more efficient for patterns with a // starred wildcard like [first, *_] / [first, *_, last] / [*_, last] / etc. static int -pattern_helper_sequence_subscr(struct compiler *c, asdl_pattern_seq *patterns, - Py_ssize_t star, pattern_context *pc) +pattern_helper_sequence_subscr(struct compiler *c, location loc, + asdl_pattern_seq *patterns, Py_ssize_t star, + pattern_context *pc) { // We need to keep the subject around for extracting elements: pc->on_top++; @@ -6449,35 +6723,36 @@ pattern_helper_sequence_subscr(struct compiler *c, asdl_pattern_seq *patterns, assert(WILDCARD_STAR_CHECK(pattern)); continue; } - ADDOP_I(c, COPY, 1); + ADDOP_I(c, loc, COPY, 1); if (i < star) { - ADDOP_LOAD_CONST_NEW(c, PyLong_FromSsize_t(i)); + ADDOP_LOAD_CONST_NEW(c, loc, PyLong_FromSsize_t(i)); } else { // The subject may not support negative indexing! Compute a // nonnegative index: - ADDOP(c, GET_LEN); - ADDOP_LOAD_CONST_NEW(c, PyLong_FromSsize_t(size - i)); - ADDOP_BINARY(c, Sub); + ADDOP(c, loc, GET_LEN); + ADDOP_LOAD_CONST_NEW(c, loc, PyLong_FromSsize_t(size - i)); + ADDOP_BINARY(c, loc, Sub); } - ADDOP(c, BINARY_SUBSCR); - RETURN_IF_FALSE(compiler_pattern_subpattern(c, pattern, pc)); + ADDOP(c, loc, BINARY_SUBSCR); + RETURN_IF_ERROR(compiler_pattern_subpattern(c, pattern, pc)); } // Pop the subject, we're done with it: pc->on_top--; - ADDOP(c, POP_TOP); - return 1; + ADDOP(c, loc, POP_TOP); + return SUCCESS; } // Like compiler_pattern, but turn off checks for irrefutability. static int -compiler_pattern_subpattern(struct compiler *c, pattern_ty p, pattern_context *pc) +compiler_pattern_subpattern(struct compiler *c, + pattern_ty p, pattern_context *pc) { int allow_irrefutable = pc->allow_irrefutable; pc->allow_irrefutable = 1; - RETURN_IF_FALSE(compiler_pattern(c, p, pc)); + RETURN_IF_ERROR(compiler_pattern(c, p, pc)); pc->allow_irrefutable = allow_irrefutable; - return 1; + return SUCCESS; } static int @@ -6489,29 +6764,30 @@ compiler_pattern_as(struct compiler *c, pattern_ty p, pattern_context *pc) if (!pc->allow_irrefutable) { if (p->v.MatchAs.name) { const char *e = "name capture %R makes remaining patterns unreachable"; - return compiler_error(c, e, p->v.MatchAs.name); + return compiler_error(c, LOC(p), e, p->v.MatchAs.name); } const char *e = "wildcard makes remaining patterns unreachable"; - return compiler_error(c, e); + return compiler_error(c, LOC(p), e); } - return pattern_helper_store_name(c, p->v.MatchAs.name, pc); + return pattern_helper_store_name(c, LOC(p), p->v.MatchAs.name, pc); } // Need to make a copy for (possibly) storing later: pc->on_top++; - ADDOP_I(c, COPY, 1); - RETURN_IF_FALSE(compiler_pattern(c, p->v.MatchAs.pattern, pc)); + ADDOP_I(c, LOC(p), COPY, 1); + RETURN_IF_ERROR(compiler_pattern(c, p->v.MatchAs.pattern, pc)); // Success! Store it: pc->on_top--; - RETURN_IF_FALSE(pattern_helper_store_name(c, p->v.MatchAs.name, pc)); - return 1; + RETURN_IF_ERROR(pattern_helper_store_name(c, LOC(p), p->v.MatchAs.name, pc)); + return SUCCESS; } static int compiler_pattern_star(struct compiler *c, pattern_ty p, pattern_context *pc) { assert(p->kind == MatchStar_kind); - RETURN_IF_FALSE(pattern_helper_store_name(c, p->v.MatchStar.name, pc)); - return 1; + RETURN_IF_ERROR( + pattern_helper_store_name(c, LOC(p), p->v.MatchStar.name, pc)); + return SUCCESS; } static int @@ -6522,20 +6798,20 @@ validate_kwd_attrs(struct compiler *c, asdl_identifier_seq *attrs, asdl_pattern_ Py_ssize_t nattrs = asdl_seq_LEN(attrs); for (Py_ssize_t i = 0; i < nattrs; i++) { identifier attr = ((identifier)asdl_seq_GET(attrs, i)); - SET_LOC(c, ((pattern_ty) asdl_seq_GET(patterns, i))); - if (forbidden_name(c, attr, Store)) { - return -1; + location loc = LOC((pattern_ty) asdl_seq_GET(patterns, i)); + if (forbidden_name(c, loc, attr, Store)) { + return ERROR; } for (Py_ssize_t j = i + 1; j < nattrs; j++) { identifier other = ((identifier)asdl_seq_GET(attrs, j)); if (!PyUnicode_Compare(attr, other)) { - SET_LOC(c, ((pattern_ty) asdl_seq_GET(patterns, j))); - compiler_error(c, "attribute name repeated in class pattern: %U", attr); - return -1; + location loc = LOC((pattern_ty) asdl_seq_GET(patterns, j)); + compiler_error(c, loc, "attribute name repeated in class pattern: %U", attr); + return ERROR; } } } - return 0; + return SUCCESS; } static int @@ -6552,34 +6828,34 @@ compiler_pattern_class(struct compiler *c, pattern_ty p, pattern_context *pc) // AST validator shouldn't let this happen, but if it does, // just fail, don't crash out of the interpreter const char * e = "kwd_attrs (%d) / kwd_patterns (%d) length mismatch in class pattern"; - return compiler_error(c, e, nattrs, nkwd_patterns); + return compiler_error(c, LOC(p), e, nattrs, nkwd_patterns); } if (INT_MAX < nargs || INT_MAX < nargs + nattrs - 1) { const char *e = "too many sub-patterns in class pattern %R"; - return compiler_error(c, e, p->v.MatchClass.cls); + return compiler_error(c, LOC(p), e, p->v.MatchClass.cls); } if (nattrs) { - RETURN_IF_FALSE(!validate_kwd_attrs(c, kwd_attrs, kwd_patterns)); - SET_LOC(c, p); + RETURN_IF_ERROR(validate_kwd_attrs(c, kwd_attrs, kwd_patterns)); } VISIT(c, expr, p->v.MatchClass.cls); - PyObject *attr_names; - RETURN_IF_FALSE(attr_names = PyTuple_New(nattrs)); + PyObject *attr_names = PyTuple_New(nattrs); + if (attr_names == NULL) { + return ERROR; + } Py_ssize_t i; for (i = 0; i < nattrs; i++) { PyObject *name = asdl_seq_GET(kwd_attrs, i); - Py_INCREF(name); - PyTuple_SET_ITEM(attr_names, i, name); - } - ADDOP_LOAD_CONST_NEW(c, attr_names); - ADDOP_I(c, MATCH_CLASS, nargs); - ADDOP_I(c, COPY, 1); - ADDOP_LOAD_CONST(c, Py_None); - ADDOP_I(c, IS_OP, 1); + PyTuple_SET_ITEM(attr_names, i, Py_NewRef(name)); + } + ADDOP_LOAD_CONST_NEW(c, LOC(p), attr_names); + ADDOP_I(c, LOC(p), MATCH_CLASS, nargs); + ADDOP_I(c, LOC(p), COPY, 1); + ADDOP_LOAD_CONST(c, LOC(p), Py_None); + ADDOP_I(c, LOC(p), IS_OP, 1); // TOS is now a tuple of (nargs + nattrs) attributes (or None): pc->on_top++; - RETURN_IF_FALSE(jump_to_fail_pop(c, pc, POP_JUMP_IF_FALSE)); - ADDOP_I(c, UNPACK_SEQUENCE, nargs + nattrs); + RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE)); + ADDOP_I(c, LOC(p), UNPACK_SEQUENCE, nargs + nattrs); pc->on_top += nargs + nattrs - 1; for (i = 0; i < nargs + nattrs; i++) { pc->on_top--; @@ -6593,17 +6869,18 @@ compiler_pattern_class(struct compiler *c, pattern_ty p, pattern_context *pc) pattern = asdl_seq_GET(kwd_patterns, i - nargs); } if (WILDCARD_CHECK(pattern)) { - ADDOP(c, POP_TOP); + ADDOP(c, LOC(p), POP_TOP); continue; } - RETURN_IF_FALSE(compiler_pattern_subpattern(c, pattern, pc)); + RETURN_IF_ERROR(compiler_pattern_subpattern(c, pattern, pc)); } // Success! Pop the tuple of attributes: - return 1; + return SUCCESS; } static int -compiler_pattern_mapping(struct compiler *c, pattern_ty p, pattern_context *pc) +compiler_pattern_mapping(struct compiler *c, pattern_ty p, + pattern_context *pc) { assert(p->kind == MatchMapping_kind); asdl_expr_seq *keys = p->v.MatchMapping.keys; @@ -6614,29 +6891,29 @@ compiler_pattern_mapping(struct compiler *c, pattern_ty p, pattern_context *pc) // AST validator shouldn't let this happen, but if it does, // just fail, don't crash out of the interpreter const char * e = "keys (%d) / patterns (%d) length mismatch in mapping pattern"; - return compiler_error(c, e, size, npatterns); + return compiler_error(c, LOC(p), e, size, npatterns); } // We have a double-star target if "rest" is set PyObject *star_target = p->v.MatchMapping.rest; // We need to keep the subject on top during the mapping and length checks: pc->on_top++; - ADDOP(c, MATCH_MAPPING); - RETURN_IF_FALSE(jump_to_fail_pop(c, pc, POP_JUMP_IF_FALSE)); + ADDOP(c, LOC(p), MATCH_MAPPING); + RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE)); if (!size && !star_target) { // If the pattern is just "{}", we're done! Pop the subject: pc->on_top--; - ADDOP(c, POP_TOP); - return 1; + ADDOP(c, LOC(p), POP_TOP); + return SUCCESS; } if (size) { // If the pattern has any keys in it, perform a length check: - ADDOP(c, GET_LEN); - ADDOP_LOAD_CONST_NEW(c, PyLong_FromSsize_t(size)); - ADDOP_COMPARE(c, GtE); - RETURN_IF_FALSE(jump_to_fail_pop(c, pc, POP_JUMP_IF_FALSE)); + ADDOP(c, LOC(p), GET_LEN); + ADDOP_LOAD_CONST_NEW(c, LOC(p), PyLong_FromSsize_t(size)); + ADDOP_COMPARE(c, LOC(p), GtE); + RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE)); } if (INT_MAX < size - 1) { - return compiler_error(c, "too many sub-patterns in mapping pattern"); + return compiler_error(c, LOC(p), "too many sub-patterns in mapping pattern"); } // Collect all of the keys into a tuple for MATCH_KEYS and // **rest. They can either be dotted names or literals: @@ -6645,7 +6922,7 @@ compiler_pattern_mapping(struct compiler *c, pattern_ty p, pattern_context *pc) // SyntaxError in the case of duplicates. PyObject *seen = PySet_New(NULL); if (seen == NULL) { - return 0; + return ERROR; } // NOTE: goto error on failure in the loop below to avoid leaking `seen` @@ -6654,8 +6931,8 @@ compiler_pattern_mapping(struct compiler *c, pattern_ty p, pattern_context *pc) if (key == NULL) { const char *e = "can't use NULL keys in MatchMapping " "(set 'rest' parameter instead)"; - SET_LOC(c, ((pattern_ty) asdl_seq_GET(patterns, i))); - compiler_error(c, e); + location loc = LOC((pattern_ty) asdl_seq_GET(patterns, i)); + compiler_error(c, loc, e); goto error; } @@ -6666,7 +6943,7 @@ compiler_pattern_mapping(struct compiler *c, pattern_ty p, pattern_context *pc) } if (in_seen) { const char *e = "mapping pattern checks duplicate key (%R)"; - compiler_error(c, e, key->v.Constant.value); + compiler_error(c, LOC(p), e, key->v.Constant.value); goto error; } if (PySet_Add(seen, key->v.Constant.value)) { @@ -6676,10 +6953,10 @@ compiler_pattern_mapping(struct compiler *c, pattern_ty p, pattern_context *pc) else if (key->kind != Attribute_kind) { const char *e = "mapping pattern keys may only match literals and attribute lookups"; - compiler_error(c, e); + compiler_error(c, LOC(p), e); goto error; } - if (!compiler_visit_expr(c, key)) { + if (compiler_visit_expr(c, key) < 0) { goto error; } } @@ -6687,22 +6964,22 @@ compiler_pattern_mapping(struct compiler *c, pattern_ty p, pattern_context *pc) // all keys have been checked; there are no duplicates Py_DECREF(seen); - ADDOP_I(c, BUILD_TUPLE, size); - ADDOP(c, MATCH_KEYS); + ADDOP_I(c, LOC(p), BUILD_TUPLE, size); + ADDOP(c, LOC(p), MATCH_KEYS); // There's now a tuple of keys and a tuple of values on top of the subject: pc->on_top += 2; - ADDOP_I(c, COPY, 1); - ADDOP_LOAD_CONST(c, Py_None); - ADDOP_I(c, IS_OP, 1); - RETURN_IF_FALSE(jump_to_fail_pop(c, pc, POP_JUMP_IF_FALSE)); + ADDOP_I(c, LOC(p), COPY, 1); + ADDOP_LOAD_CONST(c, LOC(p), Py_None); + ADDOP_I(c, LOC(p), IS_OP, 1); + RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE)); // So far so good. Use that tuple of values on the stack to match // sub-patterns against: - ADDOP_I(c, UNPACK_SEQUENCE, size); + ADDOP_I(c, LOC(p), UNPACK_SEQUENCE, size); pc->on_top += size - 1; for (Py_ssize_t i = 0; i < size; i++) { pc->on_top--; pattern_ty pattern = asdl_seq_GET(patterns, i); - RETURN_IF_FALSE(compiler_pattern_subpattern(c, pattern, pc)); + RETURN_IF_ERROR(compiler_pattern_subpattern(c, pattern, pc)); } // If we get this far, it's a match! Whatever happens next should consume // the tuple of keys and the subject: @@ -6714,34 +6991,33 @@ compiler_pattern_mapping(struct compiler *c, pattern_ty p, pattern_context *pc) // rest = dict(TOS1) // for key in TOS: // del rest[key] - ADDOP_I(c, BUILD_MAP, 0); // [subject, keys, empty] - ADDOP_I(c, SWAP, 3); // [empty, keys, subject] - ADDOP_I(c, DICT_UPDATE, 2); // [copy, keys] - ADDOP_I(c, UNPACK_SEQUENCE, size); // [copy, keys...] + ADDOP_I(c, LOC(p), BUILD_MAP, 0); // [subject, keys, empty] + ADDOP_I(c, LOC(p), SWAP, 3); // [empty, keys, subject] + ADDOP_I(c, LOC(p), DICT_UPDATE, 2); // [copy, keys] + ADDOP_I(c, LOC(p), UNPACK_SEQUENCE, size); // [copy, keys...] while (size) { - ADDOP_I(c, COPY, 1 + size--); // [copy, keys..., copy] - ADDOP_I(c, SWAP, 2); // [copy, keys..., copy, key] - ADDOP(c, DELETE_SUBSCR); // [copy, keys...] + ADDOP_I(c, LOC(p), COPY, 1 + size--); // [copy, keys..., copy] + ADDOP_I(c, LOC(p), SWAP, 2); // [copy, keys..., copy, key] + ADDOP(c, LOC(p), DELETE_SUBSCR); // [copy, keys...] } - RETURN_IF_FALSE(pattern_helper_store_name(c, star_target, pc)); + RETURN_IF_ERROR(pattern_helper_store_name(c, LOC(p), star_target, pc)); } else { - ADDOP(c, POP_TOP); // Tuple of keys. - ADDOP(c, POP_TOP); // Subject. + ADDOP(c, LOC(p), POP_TOP); // Tuple of keys. + ADDOP(c, LOC(p), POP_TOP); // Subject. } - return 1; + return SUCCESS; error: Py_DECREF(seen); - return 0; + return ERROR; } static int compiler_pattern_or(struct compiler *c, pattern_ty p, pattern_context *pc) { assert(p->kind == MatchOr_kind); - basicblock *end; - RETURN_IF_FALSE(end = compiler_new_block(c)); + NEW_JUMP_TARGET_LABEL(c, end); Py_ssize_t size = asdl_seq_LEN(p->v.MatchOr.patterns); assert(size > 1); // We're going to be messing with pc. Keep the original info handy: @@ -6754,7 +7030,6 @@ compiler_pattern_or(struct compiler *c, pattern_ty p, pattern_context *pc) // NOTE: We can't use returning macros anymore! goto error on error. for (Py_ssize_t i = 0; i < size; i++) { pattern_ty alt = asdl_seq_GET(p->v.MatchOr.patterns, i); - SET_LOC(c, alt); PyObject *pc_stores = PyList_New(0); if (pc_stores == NULL) { goto error; @@ -6765,7 +7040,8 @@ compiler_pattern_or(struct compiler *c, pattern_ty p, pattern_context *pc) pc->fail_pop = NULL; pc->fail_pop_size = 0; pc->on_top = 0; - if (!compiler_addop_i(c, COPY, 1) || !compiler_pattern(c, alt, pc)) { + if (codegen_addop_i(INSTR_SEQUENCE(c), COPY, 1, LOC(alt)) < 0 || + compiler_pattern(c, alt, pc) < 0) { goto error; } // Success! @@ -6775,8 +7051,7 @@ compiler_pattern_or(struct compiler *c, pattern_ty p, pattern_context *pc) // for the others (they can't bind a different set of names, and // might need to be reordered): assert(control == NULL); - control = pc->stores; - Py_INCREF(control); + control = Py_NewRef(pc->stores); } else if (nstores != PyList_GET_SIZE(control)) { goto diff; @@ -6820,7 +7095,7 @@ compiler_pattern_or(struct compiler *c, pattern_ty p, pattern_context *pc) // Do the same thing to the stack, using several // rotations: while (rotations--) { - if (!pattern_helper_rotate(c, icontrol + 1)){ + if (pattern_helper_rotate(c, LOC(alt), icontrol + 1) < 0) { goto error; } } @@ -6828,8 +7103,8 @@ compiler_pattern_or(struct compiler *c, pattern_ty p, pattern_context *pc) } } assert(control); - if (!compiler_addop_j(c, JUMP, end) || - !emit_and_reset_fail_pop(c, pc)) + if (codegen_addop_j(INSTR_SEQUENCE(c), LOC(alt), JUMP, end) < 0 || + emit_and_reset_fail_pop(c, LOC(alt), pc) < 0) { goto error; } @@ -6840,10 +7115,12 @@ compiler_pattern_or(struct compiler *c, pattern_ty p, pattern_context *pc) // Need to NULL this for the PyObject_Free call in the error block. old_pc.fail_pop = NULL; // No match. Pop the remaining copy of the subject and fail: - if (!compiler_addop(c, POP_TOP) || !jump_to_fail_pop(c, pc, JUMP)) { + if (codegen_addop_noarg(INSTR_SEQUENCE(c), POP_TOP, LOC(p)) < 0 || + jump_to_fail_pop(c, LOC(p), pc, JUMP) < 0) { goto error; } - compiler_use_next_block(c, end); + + USE_LABEL(c, end); Py_ssize_t nstores = PyList_GET_SIZE(control); // There's a bunch of stuff on the stack between where the new stores // are and where they need to be: @@ -6854,7 +7131,7 @@ compiler_pattern_or(struct compiler *c, pattern_ty p, pattern_context *pc) Py_ssize_t nrots = nstores + 1 + pc->on_top + PyList_GET_SIZE(pc->stores); for (Py_ssize_t i = 0; i < nstores; i++) { // Rotate this capture to its proper place on the stack: - if (!pattern_helper_rotate(c, nrots)) { + if (pattern_helper_rotate(c, LOC(p), nrots) < 0) { goto error; } // Update the list of previous stores with this new name, checking for @@ -6865,7 +7142,7 @@ compiler_pattern_or(struct compiler *c, pattern_ty p, pattern_context *pc) goto error; } if (dupe) { - compiler_error_duplicate_store(c, name); + compiler_error_duplicate_store(c, LOC(p), name); goto error; } if (PyList_Append(pc->stores, name)) { @@ -6876,20 +7153,21 @@ compiler_pattern_or(struct compiler *c, pattern_ty p, pattern_context *pc) Py_DECREF(control); // NOTE: Returning macros are safe again. // Pop the copy of the subject: - ADDOP(c, POP_TOP); - return 1; + ADDOP(c, LOC(p), POP_TOP); + return SUCCESS; diff: - compiler_error(c, "alternative patterns bind different names"); + compiler_error(c, LOC(p), "alternative patterns bind different names"); error: PyObject_Free(old_pc.fail_pop); Py_DECREF(old_pc.stores); Py_XDECREF(control); - return 0; + return ERROR; } static int -compiler_pattern_sequence(struct compiler *c, pattern_ty p, pattern_context *pc) +compiler_pattern_sequence(struct compiler *c, pattern_ty p, + pattern_context *pc) { assert(p->kind == MatchSequence_kind); asdl_pattern_seq *patterns = p->v.MatchSequence.patterns; @@ -6903,7 +7181,7 @@ compiler_pattern_sequence(struct compiler *c, pattern_ty p, pattern_context *pc) if (pattern->kind == MatchStar_kind) { if (star >= 0) { const char *e = "multiple starred names in sequence pattern"; - return compiler_error(c, e); + return compiler_error(c, LOC(p), e); } star_wildcard = WILDCARD_STAR_CHECK(pattern); only_wildcard &= star_wildcard; @@ -6914,35 +7192,35 @@ compiler_pattern_sequence(struct compiler *c, pattern_ty p, pattern_context *pc) } // We need to keep the subject on top during the sequence and length checks: pc->on_top++; - ADDOP(c, MATCH_SEQUENCE); - RETURN_IF_FALSE(jump_to_fail_pop(c, pc, POP_JUMP_IF_FALSE)); + ADDOP(c, LOC(p), MATCH_SEQUENCE); + RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE)); if (star < 0) { // No star: len(subject) == size - ADDOP(c, GET_LEN); - ADDOP_LOAD_CONST_NEW(c, PyLong_FromSsize_t(size)); - ADDOP_COMPARE(c, Eq); - RETURN_IF_FALSE(jump_to_fail_pop(c, pc, POP_JUMP_IF_FALSE)); + ADDOP(c, LOC(p), GET_LEN); + ADDOP_LOAD_CONST_NEW(c, LOC(p), PyLong_FromSsize_t(size)); + ADDOP_COMPARE(c, LOC(p), Eq); + RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE)); } else if (size > 1) { // Star: len(subject) >= size - 1 - ADDOP(c, GET_LEN); - ADDOP_LOAD_CONST_NEW(c, PyLong_FromSsize_t(size - 1)); - ADDOP_COMPARE(c, GtE); - RETURN_IF_FALSE(jump_to_fail_pop(c, pc, POP_JUMP_IF_FALSE)); + ADDOP(c, LOC(p), GET_LEN); + ADDOP_LOAD_CONST_NEW(c, LOC(p), PyLong_FromSsize_t(size - 1)); + ADDOP_COMPARE(c, LOC(p), GtE); + RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE)); } // Whatever comes next should consume the subject: pc->on_top--; if (only_wildcard) { // Patterns like: [] / [_] / [_, _] / [*_] / [_, *_] / [_, _, *_] / etc. - ADDOP(c, POP_TOP); + ADDOP(c, LOC(p), POP_TOP); } else if (star_wildcard) { - RETURN_IF_FALSE(pattern_helper_sequence_subscr(c, patterns, star, pc)); + RETURN_IF_ERROR(pattern_helper_sequence_subscr(c, LOC(p), patterns, star, pc)); } else { - RETURN_IF_FALSE(pattern_helper_sequence_unpack(c, patterns, star, pc)); + RETURN_IF_ERROR(pattern_helper_sequence_unpack(c, LOC(p), patterns, star, pc)); } - return 1; + return SUCCESS; } static int @@ -6952,28 +7230,27 @@ compiler_pattern_value(struct compiler *c, pattern_ty p, pattern_context *pc) expr_ty value = p->v.MatchValue.value; if (!MATCH_VALUE_EXPR(value)) { const char *e = "patterns may only match literals and attribute lookups"; - return compiler_error(c, e); + return compiler_error(c, LOC(p), e); } VISIT(c, expr, value); - ADDOP_COMPARE(c, Eq); - RETURN_IF_FALSE(jump_to_fail_pop(c, pc, POP_JUMP_IF_FALSE)); - return 1; + ADDOP_COMPARE(c, LOC(p), Eq); + RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE)); + return SUCCESS; } static int compiler_pattern_singleton(struct compiler *c, pattern_ty p, pattern_context *pc) { assert(p->kind == MatchSingleton_kind); - ADDOP_LOAD_CONST(c, p->v.MatchSingleton.value); - ADDOP_COMPARE(c, Is); - RETURN_IF_FALSE(jump_to_fail_pop(c, pc, POP_JUMP_IF_FALSE)); - return 1; + ADDOP_LOAD_CONST(c, LOC(p), p->v.MatchSingleton.value); + ADDOP_COMPARE(c, LOC(p), Is); + RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE)); + return SUCCESS; } static int compiler_pattern(struct compiler *c, pattern_ty p, pattern_context *pc) { - SET_LOC(c, p); switch (p->kind) { case MatchValue_kind: return compiler_pattern_value(c, p, pc); @@ -6995,85 +7272,84 @@ compiler_pattern(struct compiler *c, pattern_ty p, pattern_context *pc) // AST validator shouldn't let this happen, but if it does, // just fail, don't crash out of the interpreter const char *e = "invalid match pattern node in AST (kind=%d)"; - return compiler_error(c, e, p->kind); + return compiler_error(c, LOC(p), e, p->kind); } static int compiler_match_inner(struct compiler *c, stmt_ty s, pattern_context *pc) { VISIT(c, expr, s->v.Match.subject); - basicblock *end; - RETURN_IF_FALSE(end = compiler_new_block(c)); + NEW_JUMP_TARGET_LABEL(c, end); Py_ssize_t cases = asdl_seq_LEN(s->v.Match.cases); assert(cases > 0); match_case_ty m = asdl_seq_GET(s->v.Match.cases, cases - 1); int has_default = WILDCARD_CHECK(m->pattern) && 1 < cases; for (Py_ssize_t i = 0; i < cases - has_default; i++) { m = asdl_seq_GET(s->v.Match.cases, i); - SET_LOC(c, m->pattern); // Only copy the subject if we're *not* on the last case: if (i != cases - has_default - 1) { - ADDOP_I(c, COPY, 1); + ADDOP_I(c, LOC(m->pattern), COPY, 1); + } + pc->stores = PyList_New(0); + if (pc->stores == NULL) { + return ERROR; } - RETURN_IF_FALSE(pc->stores = PyList_New(0)); // Irrefutable cases must be either guarded, last, or both: pc->allow_irrefutable = m->guard != NULL || i == cases - 1; pc->fail_pop = NULL; pc->fail_pop_size = 0; pc->on_top = 0; // NOTE: Can't use returning macros here (they'll leak pc->stores)! - if (!compiler_pattern(c, m->pattern, pc)) { + if (compiler_pattern(c, m->pattern, pc) < 0) { Py_DECREF(pc->stores); - return 0; + return ERROR; } assert(!pc->on_top); // It's a match! Store all of the captured names (they're on the stack). Py_ssize_t nstores = PyList_GET_SIZE(pc->stores); for (Py_ssize_t n = 0; n < nstores; n++) { PyObject *name = PyList_GET_ITEM(pc->stores, n); - if (!compiler_nameop(c, name, Store)) { + if (compiler_nameop(c, LOC(m->pattern), name, Store) < 0) { Py_DECREF(pc->stores); - return 0; + return ERROR; } } Py_DECREF(pc->stores); // NOTE: Returning macros are safe again. if (m->guard) { - RETURN_IF_FALSE(ensure_fail_pop(c, pc, 0)); - RETURN_IF_FALSE(compiler_jump_if(c, m->guard, pc->fail_pop[0], 0)); + RETURN_IF_ERROR(ensure_fail_pop(c, pc, 0)); + RETURN_IF_ERROR(compiler_jump_if(c, LOC(m->pattern), m->guard, pc->fail_pop[0], 0)); } // Success! Pop the subject off, we're done with it: if (i != cases - has_default - 1) { - ADDOP(c, POP_TOP); + ADDOP(c, LOC(m->pattern), POP_TOP); } VISIT_SEQ(c, stmt, m->body); - ADDOP_JUMP(c, JUMP, end); + ADDOP_JUMP(c, NO_LOCATION, JUMP, end); // If the pattern fails to match, we want the line number of the // cleanup to be associated with the failed pattern, not the last line // of the body - SET_LOC(c, m->pattern); - RETURN_IF_FALSE(emit_and_reset_fail_pop(c, pc)); + RETURN_IF_ERROR(emit_and_reset_fail_pop(c, LOC(m->pattern), pc)); } if (has_default) { // A trailing "case _" is common, and lets us save a bit of redundant // pushing and popping in the loop above: m = asdl_seq_GET(s->v.Match.cases, cases - 1); - SET_LOC(c, m->pattern); if (cases == 1) { // No matches. Done with the subject: - ADDOP(c, POP_TOP); + ADDOP(c, LOC(m->pattern), POP_TOP); } else { // Show line coverage for default case (it doesn't create bytecode) - ADDOP(c, NOP); + ADDOP(c, LOC(m->pattern), NOP); } if (m->guard) { - RETURN_IF_FALSE(compiler_jump_if(c, m->guard, end, 0)); + RETURN_IF_ERROR(compiler_jump_if(c, LOC(m->pattern), m->guard, end, 0)); } VISIT_SEQ(c, stmt, m->body); } - compiler_use_next_block(c, end); - return 1; + USE_LABEL(c, end); + return SUCCESS; } static int @@ -7089,2323 +7365,780 @@ compiler_match(struct compiler *c, stmt_ty s) #undef WILDCARD_CHECK #undef WILDCARD_STAR_CHECK -/* End of the compiler section, beginning of the assembler section */ - -/* do depth-first search of basic block graph, starting with block. - post records the block indices in post-order. - - XXX must handle implicit jumps from one block to next -*/ - - -struct assembler { - PyObject *a_bytecode; /* bytes containing bytecode */ - PyObject *a_except_table; /* bytes containing exception table */ - basicblock *a_entry; - int a_offset; /* offset into bytecode */ - int a_nblocks; /* number of reachable blocks */ - int a_except_table_off; /* offset into exception table */ - int a_prevlineno; /* lineno of last emitted line in line table */ - int a_prev_end_lineno; /* end_lineno of last emitted line in line table */ - int a_lineno; /* lineno of last emitted instruction */ - int a_end_lineno; /* end_lineno of last emitted instruction */ - int a_lineno_start; /* bytecode start offset of current lineno */ - int a_end_lineno_start; /* bytecode start offset of current end_lineno */ - /* Location Info */ - PyObject* a_linetable; /* bytes containing location info */ - int a_location_off; /* offset of last written location info frame */ -}; - -Py_LOCAL_INLINE(void) -stackdepth_push(basicblock ***sp, basicblock *b, int depth) -{ - assert(b->b_startdepth < 0 || b->b_startdepth == depth); - if (b->b_startdepth < depth && b->b_startdepth < 100) { - assert(b->b_startdepth < 0); - b->b_startdepth = depth; - *(*sp)++ = b; - } -} - -/* Find the flow path that needs the largest stack. We assume that - * cycles in the flow graph have no net effect on the stack depth. - */ -static int -stackdepth(struct compiler *c) +static PyObject * +consts_dict_keys_inorder(PyObject *dict) { - basicblock *b, *entryblock = NULL; - basicblock **stack, **sp; - int nblocks = 0, maxdepth = 0; - for (b = c->u->u_blocks; b != NULL; b = b->b_list) { - b->b_startdepth = INT_MIN; - entryblock = b; - nblocks++; - } - assert(entryblock!= NULL); - stack = (basicblock **)PyObject_Malloc(sizeof(basicblock *) * nblocks); - if (!stack) { - PyErr_NoMemory(); - return -1; - } + PyObject *consts, *k, *v; + Py_ssize_t i, pos = 0, size = PyDict_GET_SIZE(dict); - sp = stack; - if (c->u->u_ste->ste_generator || c->u->u_ste->ste_coroutine) { - stackdepth_push(&sp, entryblock, 1); - } else { - stackdepth_push(&sp, entryblock, 0); - } - while (sp != stack) { - b = *--sp; - int depth = b->b_startdepth; - assert(depth >= 0); - basicblock *next = b->b_next; - for (int i = 0; i < b->b_iused; i++) { - struct instr *instr = &b->b_instr[i]; - int effect = stack_effect(instr->i_opcode, instr->i_oparg, 0); - if (effect == PY_INVALID_STACK_EFFECT) { - PyErr_Format(PyExc_SystemError, - "compiler stack_effect(opcode=%d, arg=%i) failed", - instr->i_opcode, instr->i_oparg); - return -1; - } - int new_depth = depth + effect; - if (new_depth > maxdepth) { - maxdepth = new_depth; - } - assert(depth >= 0); /* invalid code or bug in stackdepth() */ - if (is_jump(instr) || is_block_push(instr)) { - effect = stack_effect(instr->i_opcode, instr->i_oparg, 1); - assert(effect != PY_INVALID_STACK_EFFECT); - int target_depth = depth + effect; - if (target_depth > maxdepth) { - maxdepth = target_depth; - } - assert(target_depth >= 0); /* invalid code or bug in stackdepth() */ - stackdepth_push(&sp, instr->i_target, target_depth); - } - depth = new_depth; - assert(!IS_ASSEMBLER_OPCODE(instr->i_opcode)); - if (instr->i_opcode == JUMP_NO_INTERRUPT || - instr->i_opcode == JUMP || - instr->i_opcode == RETURN_VALUE || - instr->i_opcode == RAISE_VARARGS || - instr->i_opcode == RERAISE) - { - /* remaining code is dead */ - next = NULL; - break; - } - } - if (next != NULL) { - assert(b->b_nofallthrough == 0); - stackdepth_push(&sp, next, depth); + consts = PyList_New(size); /* PyCode_Optimize() requires a list */ + if (consts == NULL) + return NULL; + while (PyDict_Next(dict, &pos, &k, &v)) { + i = PyLong_AS_LONG(v); + /* The keys of the dictionary can be tuples wrapping a constant. + * (see dict_add_o and _PyCode_ConstantKey). In that case + * the object we want is always second. */ + if (PyTuple_CheckExact(k)) { + k = PyTuple_GET_ITEM(k, 1); } + assert(i < size); + assert(i >= 0); + PyList_SET_ITEM(consts, i, Py_NewRef(k)); } - PyObject_Free(stack); - return maxdepth; + return consts; } static int -assemble_init(struct assembler *a, int nblocks, int firstlineno) +compute_code_flags(struct compiler *c) { - memset(a, 0, sizeof(struct assembler)); - a->a_prevlineno = a->a_lineno = firstlineno; - a->a_prev_end_lineno = a->a_end_lineno = firstlineno; - a->a_linetable = NULL; - a->a_location_off = 0; - a->a_except_table = NULL; - a->a_bytecode = PyBytes_FromStringAndSize(NULL, DEFAULT_CODE_SIZE); - if (a->a_bytecode == NULL) { - goto error; - } - a->a_linetable = PyBytes_FromStringAndSize(NULL, DEFAULT_CNOTAB_SIZE); - if (a->a_linetable == NULL) { - goto error; - } - a->a_except_table = PyBytes_FromStringAndSize(NULL, DEFAULT_LNOTAB_SIZE); - if (a->a_except_table == NULL) { - goto error; + PySTEntryObject *ste = c->u->u_ste; + int flags = 0; + if (_PyST_IsFunctionLike(c->u->u_ste)) { + flags |= CO_NEWLOCALS | CO_OPTIMIZED; + if (ste->ste_nested) + flags |= CO_NESTED; + if (ste->ste_generator && !ste->ste_coroutine) + flags |= CO_GENERATOR; + if (!ste->ste_generator && ste->ste_coroutine) + flags |= CO_COROUTINE; + if (ste->ste_generator && ste->ste_coroutine) + flags |= CO_ASYNC_GENERATOR; + if (ste->ste_varargs) + flags |= CO_VARARGS; + if (ste->ste_varkeywords) + flags |= CO_VARKEYWORDS; } - if ((size_t)nblocks > SIZE_MAX / sizeof(basicblock *)) { - PyErr_NoMemory(); - goto error; + + /* (Only) inherit compilerflags in PyCF_MASK */ + flags |= (c->c_flags.cf_flags & PyCF_MASK); + + if ((IS_TOP_LEVEL_AWAIT(c)) && + ste->ste_coroutine && + !ste->ste_generator) { + flags |= CO_COROUTINE; } - return 1; -error: - Py_XDECREF(a->a_bytecode); - Py_XDECREF(a->a_linetable); - Py_XDECREF(a->a_except_table); - return 0; -} -static void -assemble_free(struct assembler *a) -{ - Py_XDECREF(a->a_bytecode); - Py_XDECREF(a->a_linetable); - Py_XDECREF(a->a_except_table); + return flags; } -static int -blocksize(basicblock *b) +// Merge *obj* with constant cache. +// Unlike merge_consts_recursive(), this function doesn't work recursively. +int +_PyCompile_ConstCacheMergeOne(PyObject *const_cache, PyObject **obj) { - int i; - int size = 0; + assert(PyDict_CheckExact(const_cache)); + PyObject *key = _PyCode_ConstantKey(*obj); + if (key == NULL) { + return ERROR; + } - for (i = 0; i < b->b_iused; i++) { - size += instr_size(&b->b_instr[i]); + // t is borrowed reference + PyObject *t = PyDict_SetDefault(const_cache, key, key); + Py_DECREF(key); + if (t == NULL) { + return ERROR; + } + if (t == key) { // obj is new constant. + return SUCCESS; } - return size; -} -static basicblock * -push_except_block(ExceptStack *stack, struct instr *setup) { - assert(is_block_push(setup)); - int opcode = setup->i_opcode; - basicblock * target = setup->i_target; - if (opcode == SETUP_WITH || opcode == SETUP_CLEANUP) { - target->b_preserve_lasti = 1; + if (PyTuple_CheckExact(t)) { + // t is still borrowed reference + t = PyTuple_GET_ITEM(t, 1); } - stack->handlers[++stack->depth] = target; - return target; -} -static basicblock * -pop_except_block(ExceptStack *stack) { - assert(stack->depth > 0); - return stack->handlers[--stack->depth]; + Py_SETREF(*obj, Py_NewRef(t)); + return SUCCESS; } -static basicblock * -except_stack_top(ExceptStack *stack) { - return stack->handlers[stack->depth]; -} -static ExceptStack * -make_except_stack(void) { - ExceptStack *new = PyMem_Malloc(sizeof(ExceptStack)); - if (new == NULL) { +static int * +build_cellfixedoffsets(_PyCompile_CodeUnitMetadata *umd) +{ + int nlocals = (int)PyDict_GET_SIZE(umd->u_varnames); + int ncellvars = (int)PyDict_GET_SIZE(umd->u_cellvars); + int nfreevars = (int)PyDict_GET_SIZE(umd->u_freevars); + + int noffsets = ncellvars + nfreevars; + int *fixed = PyMem_New(int, noffsets); + if (fixed == NULL) { PyErr_NoMemory(); return NULL; } - new->depth = 0; - new->handlers[0] = NULL; - return new; -} + for (int i = 0; i < noffsets; i++) { + fixed[i] = nlocals + i; + } -static ExceptStack * -copy_except_stack(ExceptStack *stack) { - ExceptStack *copy = PyMem_Malloc(sizeof(ExceptStack)); - if (copy == NULL) { - PyErr_NoMemory(); - return NULL; + PyObject *varname, *cellindex; + Py_ssize_t pos = 0; + while (PyDict_Next(umd->u_cellvars, &pos, &varname, &cellindex)) { + PyObject *varindex = PyDict_GetItem(umd->u_varnames, varname); + if (varindex != NULL) { + assert(PyLong_AS_LONG(cellindex) < INT_MAX); + assert(PyLong_AS_LONG(varindex) < INT_MAX); + int oldindex = (int)PyLong_AS_LONG(cellindex); + int argoffset = (int)PyLong_AS_LONG(varindex); + fixed[oldindex] = argoffset; + } } - memcpy(copy, stack, sizeof(ExceptStack)); - return copy; + + return fixed; } static int -label_exception_targets(basicblock *entry) { - int nblocks = 0; - for (basicblock *b = entry; b != NULL; b = b->b_next) { - b->b_visited = 0; - nblocks++; - } - basicblock **todo_stack = PyMem_Malloc(sizeof(basicblock *)*nblocks); - if (todo_stack == NULL) { - PyErr_NoMemory(); - return -1; +insert_prefix_instructions(_PyCompile_CodeUnitMetadata *umd, basicblock *entryblock, + int *fixed, int nfreevars, int code_flags) +{ + assert(umd->u_firstlineno > 0); + + /* Add the generator prefix instructions. */ + if (code_flags & (CO_GENERATOR | CO_COROUTINE | CO_ASYNC_GENERATOR)) { + cfg_instr make_gen = { + .i_opcode = RETURN_GENERATOR, + .i_oparg = 0, + .i_loc = LOCATION(umd->u_firstlineno, umd->u_firstlineno, -1, -1), + .i_target = NULL, + }; + RETURN_IF_ERROR(_PyBasicblock_InsertInstruction(entryblock, 0, &make_gen)); + cfg_instr pop_top = { + .i_opcode = POP_TOP, + .i_oparg = 0, + .i_loc = NO_LOCATION, + .i_target = NULL, + }; + RETURN_IF_ERROR(_PyBasicblock_InsertInstruction(entryblock, 1, &pop_top)); } - ExceptStack *except_stack = make_except_stack(); - if (except_stack == NULL) { - PyMem_Free(todo_stack); - PyErr_NoMemory(); - return -1; - } - except_stack->depth = 0; - todo_stack[0] = entry; - entry->b_visited = 1; - entry->b_exceptstack = except_stack; - basicblock **todo = &todo_stack[1]; - basicblock *handler = NULL; - while (todo > todo_stack) { - todo--; - basicblock *b = todo[0]; - assert(b->b_visited == 1); - except_stack = b->b_exceptstack; - assert(except_stack != NULL); - b->b_exceptstack = NULL; - handler = except_stack_top(except_stack); - for (int i = 0; i < b->b_iused; i++) { - struct instr *instr = &b->b_instr[i]; - if (is_block_push(instr)) { - if (!instr->i_target->b_visited) { - ExceptStack *copy = copy_except_stack(except_stack); - if (copy == NULL) { - goto error; - } - instr->i_target->b_exceptstack = copy; - todo[0] = instr->i_target; - instr->i_target->b_visited = 1; - todo++; - } - handler = push_except_block(except_stack, instr); - } - else if (instr->i_opcode == POP_BLOCK) { - handler = pop_except_block(except_stack); - } - else if (is_jump(instr)) { - instr->i_except = handler; - assert(i == b->b_iused -1); - if (!instr->i_target->b_visited) { - if (b->b_nofallthrough == 0) { - ExceptStack *copy = copy_except_stack(except_stack); - if (copy == NULL) { - goto error; - } - instr->i_target->b_exceptstack = copy; - } - else { - instr->i_target->b_exceptstack = except_stack; - except_stack = NULL; - } - todo[0] = instr->i_target; - instr->i_target->b_visited = 1; - todo++; - } - } - else { - instr->i_except = handler; - } + + /* Set up cells for any variable that escapes, to be put in a closure. */ + const int ncellvars = (int)PyDict_GET_SIZE(umd->u_cellvars); + if (ncellvars) { + // umd->u_cellvars has the cells out of order so we sort them + // before adding the MAKE_CELL instructions. Note that we + // adjust for arg cells, which come first. + const int nvars = ncellvars + (int)PyDict_GET_SIZE(umd->u_varnames); + int *sorted = PyMem_RawCalloc(nvars, sizeof(int)); + if (sorted == NULL) { + PyErr_NoMemory(); + return ERROR; } - if (b->b_nofallthrough == 0 && !b->b_next->b_visited) { - assert(except_stack != NULL); - b->b_next->b_exceptstack = except_stack; - todo[0] = b->b_next; - b->b_next->b_visited = 1; - todo++; + for (int i = 0; i < ncellvars; i++) { + sorted[fixed[i]] = i + 1; } - else if (except_stack != NULL) { - PyMem_Free(except_stack); + for (int i = 0, ncellsused = 0; ncellsused < ncellvars; i++) { + int oldindex = sorted[i] - 1; + if (oldindex == -1) { + continue; + } + cfg_instr make_cell = { + .i_opcode = MAKE_CELL, + // This will get fixed in offset_derefs(). + .i_oparg = oldindex, + .i_loc = NO_LOCATION, + .i_target = NULL, + }; + if (_PyBasicblock_InsertInstruction(entryblock, ncellsused, &make_cell) < 0) { + PyMem_RawFree(sorted); + return ERROR; + } + ncellsused += 1; } + PyMem_RawFree(sorted); } -#ifdef Py_DEBUG - for (basicblock *b = entry; b != NULL; b = b->b_next) { - assert(b->b_exceptstack == NULL); + + if (nfreevars) { + cfg_instr copy_frees = { + .i_opcode = COPY_FREE_VARS, + .i_oparg = nfreevars, + .i_loc = NO_LOCATION, + .i_target = NULL, + }; + RETURN_IF_ERROR(_PyBasicblock_InsertInstruction(entryblock, 0, ©_frees)); } -#endif - PyMem_Free(todo_stack); - return 0; -error: - PyMem_Free(todo_stack); - PyMem_Free(except_stack); - return -1; + + return SUCCESS; } +static int +fix_cell_offsets(_PyCompile_CodeUnitMetadata *umd, basicblock *entryblock, int *fixedmap) +{ + int nlocals = (int)PyDict_GET_SIZE(umd->u_varnames); + int ncellvars = (int)PyDict_GET_SIZE(umd->u_cellvars); + int nfreevars = (int)PyDict_GET_SIZE(umd->u_freevars); + int noffsets = ncellvars + nfreevars; -static void -convert_exception_handlers_to_nops(basicblock *entry) { - for (basicblock *b = entry; b != NULL; b = b->b_next) { + // First deal with duplicates (arg cells). + int numdropped = 0; + for (int i = 0; i < noffsets ; i++) { + if (fixedmap[i] == i + nlocals) { + fixedmap[i] -= numdropped; + } + else { + // It was a duplicate (cell/arg). + numdropped += 1; + } + } + + // Then update offsets, either relative to locals or by cell2arg. + for (basicblock *b = entryblock; b != NULL; b = b->b_next) { for (int i = 0; i < b->b_iused; i++) { - struct instr *instr = &b->b_instr[i]; - if (is_block_push(instr) || instr->i_opcode == POP_BLOCK) { - instr->i_opcode = NOP; + cfg_instr *inst = &b->b_instr[i]; + // This is called before extended args are generated. + assert(inst->i_opcode != EXTENDED_ARG); + int oldoffset = inst->i_oparg; + switch(inst->i_opcode) { + case MAKE_CELL: + case LOAD_CLOSURE: + case LOAD_DEREF: + case STORE_DEREF: + case DELETE_DEREF: + case LOAD_FROM_DICT_OR_DEREF: + assert(oldoffset >= 0); + assert(oldoffset < noffsets); + assert(fixedmap[oldoffset] >= 0); + inst->i_oparg = fixedmap[oldoffset]; } } } -} -static inline void -write_except_byte(struct assembler *a, int byte) { - unsigned char *p = (unsigned char *) PyBytes_AS_STRING(a->a_except_table); - p[a->a_except_table_off++] = byte; + return numdropped; } -#define CONTINUATION_BIT 64 -static void -assemble_emit_exception_table_item(struct assembler *a, int value, int msb) +static int +prepare_localsplus(_PyCompile_CodeUnitMetadata *umd, cfg_builder *g, int code_flags) { - assert ((msb | 128) == 128); - assert(value >= 0 && value < (1 << 30)); - if (value >= 1 << 24) { - write_except_byte(a, (value >> 24) | CONTINUATION_BIT | msb); - msb = 0; - } - if (value >= 1 << 18) { - write_except_byte(a, ((value >> 18)&0x3f) | CONTINUATION_BIT | msb); - msb = 0; - } - if (value >= 1 << 12) { - write_except_byte(a, ((value >> 12)&0x3f) | CONTINUATION_BIT | msb); - msb = 0; - } - if (value >= 1 << 6) { - write_except_byte(a, ((value >> 6)&0x3f) | CONTINUATION_BIT | msb); - msb = 0; + assert(PyDict_GET_SIZE(umd->u_varnames) < INT_MAX); + assert(PyDict_GET_SIZE(umd->u_cellvars) < INT_MAX); + assert(PyDict_GET_SIZE(umd->u_freevars) < INT_MAX); + int nlocals = (int)PyDict_GET_SIZE(umd->u_varnames); + int ncellvars = (int)PyDict_GET_SIZE(umd->u_cellvars); + int nfreevars = (int)PyDict_GET_SIZE(umd->u_freevars); + assert(INT_MAX - nlocals - ncellvars > 0); + assert(INT_MAX - nlocals - ncellvars - nfreevars > 0); + int nlocalsplus = nlocals + ncellvars + nfreevars; + int* cellfixedoffsets = build_cellfixedoffsets(umd); + if (cellfixedoffsets == NULL) { + return ERROR; } - write_except_byte(a, (value&0x3f) | msb); -} -/* See Objects/exception_handling_notes.txt for details of layout */ -#define MAX_SIZE_OF_ENTRY 20 -static int -assemble_emit_exception_table_entry(struct assembler *a, int start, int end, basicblock *handler) -{ - Py_ssize_t len = PyBytes_GET_SIZE(a->a_except_table); - if (a->a_except_table_off + MAX_SIZE_OF_ENTRY >= len) { - if (_PyBytes_Resize(&a->a_except_table, len * 2) < 0) - return 0; + // This must be called before fix_cell_offsets(). + if (insert_prefix_instructions(umd, g->g_entryblock, cellfixedoffsets, nfreevars, code_flags)) { + PyMem_Free(cellfixedoffsets); + return ERROR; } - int size = end-start; - assert(end > start); - int target = handler->b_offset; - int depth = handler->b_startdepth - 1; - if (handler->b_preserve_lasti) { - depth -= 1; - } - assert(depth >= 0); - int depth_lasti = (depth<<1) | handler->b_preserve_lasti; - assemble_emit_exception_table_item(a, start, (1<<7)); - assemble_emit_exception_table_item(a, size, 0); - assemble_emit_exception_table_item(a, target, 0); - assemble_emit_exception_table_item(a, depth_lasti, 0); - return 1; + + int numdropped = fix_cell_offsets(umd, g->g_entryblock, cellfixedoffsets); + PyMem_Free(cellfixedoffsets); // At this point we're done with it. + cellfixedoffsets = NULL; + if (numdropped < 0) { + return ERROR; + } + + nlocalsplus -= numdropped; + return nlocalsplus; } static int -assemble_exception_table(struct assembler *a) +add_return_at_end(struct compiler *c, int addNone) { - basicblock *b; - int ioffset = 0; - basicblock *handler = NULL; - int start = -1; - for (b = a->a_entry; b != NULL; b = b->b_next) { - ioffset = b->b_offset; - for (int i = 0; i < b->b_iused; i++) { - struct instr *instr = &b->b_instr[i]; - if (instr->i_except != handler) { - if (handler != NULL) { - RETURN_IF_FALSE(assemble_emit_exception_table_entry(a, start, ioffset, handler)); - } - start = ioffset; - handler = instr->i_except; - } - ioffset += instr_size(instr); - } - } - if (handler != NULL) { - RETURN_IF_FALSE(assemble_emit_exception_table_entry(a, start, ioffset, handler)); + /* Make sure every instruction stream that falls off the end returns None. + * This also ensures that no jump target offsets are out of bounds. + */ + if (addNone) { + ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None); } - return 1; + ADDOP(c, NO_LOCATION, RETURN_VALUE); + return SUCCESS; } -/* Code location emitting code. See locations.md for a description of the format. */ +static int cfg_to_instr_sequence(cfg_builder *g, instr_sequence *seq); -#define MSB 0x80 - -static void -write_location_byte(struct assembler* a, int val) +static PyCodeObject * +optimize_and_assemble_code_unit(struct compiler_unit *u, PyObject *const_cache, + int code_flags, PyObject *filename) { - PyBytes_AS_STRING(a->a_linetable)[a->a_location_off] = val&255; - a->a_location_off++; -} + instr_sequence optimized_instrs; + memset(&optimized_instrs, 0, sizeof(instr_sequence)); + PyCodeObject *co = NULL; + PyObject *consts = consts_dict_keys_inorder(u->u_metadata.u_consts); + if (consts == NULL) { + goto error; + } + cfg_builder g; + if (instr_sequence_to_cfg(&u->u_instr_sequence, &g) < 0) { + goto error; + } + int nparams = (int)PyList_GET_SIZE(u->u_ste->ste_varnames); + int nlocals = (int)PyDict_GET_SIZE(u->u_metadata.u_varnames); + assert(u->u_metadata.u_firstlineno); + if (_PyCfg_OptimizeCodeUnit(&g, consts, const_cache, code_flags, nlocals, + nparams, u->u_metadata.u_firstlineno) < 0) { + goto error; + } -static uint8_t * -location_pointer(struct assembler* a) -{ - return (uint8_t *)PyBytes_AS_STRING(a->a_linetable) + - a->a_location_off; -} + /** Assembly **/ + int nlocalsplus = prepare_localsplus(&u->u_metadata, &g, code_flags); + if (nlocalsplus < 0) { + goto error; + } -static void -write_location_first_byte(struct assembler* a, int code, int length) -{ - a->a_location_off += write_location_entry_start( - location_pointer(a), code, length); -} + int maxdepth = _PyCfg_Stackdepth(g.g_entryblock, code_flags); + if (maxdepth < 0) { + goto error; + } -static void -write_location_varint(struct assembler* a, unsigned int val) -{ - uint8_t *ptr = location_pointer(a); - a->a_location_off += write_varint(ptr, val); -} + _PyCfg_ConvertPseudoOps(g.g_entryblock); + /* Order of basic blocks must have been determined by now */ -static void -write_location_signed_varint(struct assembler* a, int val) -{ - uint8_t *ptr = location_pointer(a); - a->a_location_off += write_signed_varint(ptr, val); -} + if (_PyCfg_ResolveJumps(&g) < 0) { + goto error; + } -static void -write_location_info_short_form(struct assembler* a, int length, int column, int end_column) -{ - assert(length > 0 && length <= 8); - int column_low_bits = column & 7; - int column_group = column >> 3; - assert(column < 80); - assert(end_column >= column); - assert(end_column - column < 16); - write_location_first_byte(a, PY_CODE_LOCATION_INFO_SHORT0 + column_group, length); - write_location_byte(a, (column_low_bits << 4) | (end_column - column)); -} + /* Can't modify the bytecode after computing jump offsets. */ -static void -write_location_info_oneline_form(struct assembler* a, int length, int line_delta, int column, int end_column) -{ - assert(length > 0 && length <= 8); - assert(line_delta >= 0 && line_delta < 3); - assert(column < 128); - assert(end_column < 128); - write_location_first_byte(a, PY_CODE_LOCATION_INFO_ONE_LINE0 + line_delta, length); - write_location_byte(a, column); - write_location_byte(a, end_column); -} + if (cfg_to_instr_sequence(&g, &optimized_instrs) < 0) { + goto error; + } -static void -write_location_info_long_form(struct assembler* a, struct instr* i, int length) -{ - assert(length > 0 && length <= 8); - write_location_first_byte(a, PY_CODE_LOCATION_INFO_LONG, length); - write_location_signed_varint(a, i->i_lineno - a->a_lineno); - assert(i->i_end_lineno >= i->i_lineno); - write_location_varint(a, i->i_end_lineno - i->i_lineno); - write_location_varint(a, i->i_col_offset+1); - write_location_varint(a, i->i_end_col_offset+1); + co = _PyAssemble_MakeCodeObject(&u->u_metadata, const_cache, consts, + maxdepth, &optimized_instrs, nlocalsplus, + code_flags, filename); + +error: + Py_XDECREF(consts); + instr_sequence_fini(&optimized_instrs); + _PyCfgBuilder_Fini(&g); + return co; } -static void -write_location_info_none(struct assembler* a, int length) +static PyCodeObject * +optimize_and_assemble(struct compiler *c, int addNone) { - write_location_first_byte(a, PY_CODE_LOCATION_INFO_NONE, length); + struct compiler_unit *u = c->u; + PyObject *const_cache = c->c_const_cache; + PyObject *filename = c->c_filename; + + int code_flags = compute_code_flags(c); + if (code_flags < 0) { + return NULL; + } + + if (add_return_at_end(c, addNone) < 0) { + return NULL; + } + + return optimize_and_assemble_code_unit(u, const_cache, code_flags, filename); } -static void -write_location_info_no_column(struct assembler* a, int length, int line_delta) +static int +cfg_to_instr_sequence(cfg_builder *g, instr_sequence *seq) { - write_location_first_byte(a, PY_CODE_LOCATION_INFO_NO_COLUMNS, length); - write_location_signed_varint(a, line_delta); + int lbl = 0; + for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) { + b->b_label = (jump_target_label){lbl}; + lbl += b->b_iused; + } + for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) { + RETURN_IF_ERROR(instr_sequence_use_label(seq, b->b_label.id)); + for (int i = 0; i < b->b_iused; i++) { + cfg_instr *instr = &b->b_instr[i]; + RETURN_IF_ERROR( + instr_sequence_addop(seq, instr->i_opcode, instr->i_oparg, instr->i_loc)); + + _PyCompile_ExceptHandlerInfo *hi = &seq->s_instrs[seq->s_used-1].i_except_handler_info; + if (instr->i_except != NULL) { + hi->h_offset = instr->i_except->b_offset; + hi->h_startdepth = instr->i_except->b_startdepth; + hi->h_preserve_lasti = instr->i_except->b_preserve_lasti; + } + else { + hi->h_offset = -1; + } + } + } + return SUCCESS; } -#define THEORETICAL_MAX_ENTRY_SIZE 25 /* 1 + 6 + 6 + 6 + 6 */ + +/* Access to compiler optimizations for unit tests. + * + * _PyCompile_CodeGen takes and AST, applies code-gen and + * returns the unoptimized CFG as an instruction list. + * + * _PyCompile_OptimizeCfg takes an instruction list, constructs + * a CFG, optimizes it and converts back to an instruction list. + * + * An instruction list is a PyList where each item is either + * a tuple describing a single instruction: + * (opcode, oparg, lineno, end_lineno, col, end_col), or + * a jump target label marking the beginning of a basic block. + */ static int -write_location_info_entry(struct assembler* a, struct instr* i, int isize) +instructions_to_instr_sequence(PyObject *instructions, instr_sequence *seq) { - Py_ssize_t len = PyBytes_GET_SIZE(a->a_linetable); - if (a->a_location_off + THEORETICAL_MAX_ENTRY_SIZE >= len) { - assert(len > THEORETICAL_MAX_ENTRY_SIZE); - if (_PyBytes_Resize(&a->a_linetable, len*2) < 0) { - return 0; - } - } - if (i->i_lineno < 0) { - write_location_info_none(a, isize); - return 1; + assert(PyList_Check(instructions)); + + Py_ssize_t num_insts = PyList_GET_SIZE(instructions); + bool *is_target = PyMem_Calloc(num_insts, sizeof(bool)); + if (is_target == NULL) { + return ERROR; } - int line_delta = i->i_lineno - a->a_lineno; - int column = i->i_col_offset; - int end_column = i->i_end_col_offset; - assert(column >= -1); - assert(end_column >= -1); - if (column < 0 || end_column < 0) { - if (i->i_end_lineno == i->i_lineno || i->i_end_lineno == -1) { - write_location_info_no_column(a, isize, line_delta); - a->a_lineno = i->i_lineno; - return 1; + for (Py_ssize_t i = 0; i < num_insts; i++) { + PyObject *item = PyList_GET_ITEM(instructions, i); + if (!PyTuple_Check(item) || PyTuple_GET_SIZE(item) != 6) { + PyErr_SetString(PyExc_ValueError, "expected a 6-tuple"); + goto error; } - } - else if (i->i_end_lineno == i->i_lineno) { - if (line_delta == 0 && column < 80 && end_column - column < 16 && end_column >= column) { - write_location_info_short_form(a, isize, column, end_column); - return 1; + int opcode = PyLong_AsLong(PyTuple_GET_ITEM(item, 0)); + if (PyErr_Occurred()) { + goto error; } - if (line_delta >= 0 && line_delta < 3 && column < 128 && end_column < 128) { - write_location_info_oneline_form(a, isize, line_delta, column, end_column); - a->a_lineno = i->i_lineno; - return 1; + if (HAS_TARGET(opcode)) { + int oparg = PyLong_AsLong(PyTuple_GET_ITEM(item, 1)); + if (PyErr_Occurred()) { + goto error; + } + if (oparg < 0 || oparg >= num_insts) { + PyErr_SetString(PyExc_ValueError, "label out of range"); + goto error; + } + is_target[oparg] = true; } } - write_location_info_long_form(a, i, isize); - a->a_lineno = i->i_lineno; - return 1; -} -static int -assemble_emit_location(struct assembler* a, struct instr* i) -{ - int isize = instr_size(i); - while (isize > 8) { - if (!write_location_info_entry(a, i, 8)) { - return 0; + for (int i = 0; i < num_insts; i++) { + if (is_target[i]) { + if (instr_sequence_use_label(seq, i) < 0) { + goto error; + } + } + PyObject *item = PyList_GET_ITEM(instructions, i); + if (!PyTuple_Check(item) || PyTuple_GET_SIZE(item) != 6) { + PyErr_SetString(PyExc_ValueError, "expected a 6-tuple"); + goto error; + } + int opcode = PyLong_AsLong(PyTuple_GET_ITEM(item, 0)); + if (PyErr_Occurred()) { + goto error; + } + int oparg; + if (HAS_ARG(opcode)) { + oparg = PyLong_AsLong(PyTuple_GET_ITEM(item, 1)); + if (PyErr_Occurred()) { + goto error; + } + } + else { + oparg = 0; + } + location loc; + loc.lineno = PyLong_AsLong(PyTuple_GET_ITEM(item, 2)); + if (PyErr_Occurred()) { + goto error; + } + loc.end_lineno = PyLong_AsLong(PyTuple_GET_ITEM(item, 3)); + if (PyErr_Occurred()) { + goto error; + } + loc.col_offset = PyLong_AsLong(PyTuple_GET_ITEM(item, 4)); + if (PyErr_Occurred()) { + goto error; + } + loc.end_col_offset = PyLong_AsLong(PyTuple_GET_ITEM(item, 5)); + if (PyErr_Occurred()) { + goto error; + } + if (instr_sequence_addop(seq, opcode, oparg, loc) < 0) { + goto error; } - isize -= 8; } - return write_location_info_entry(a, i, isize); + PyMem_Free(is_target); + return SUCCESS; +error: + PyMem_Free(is_target); + return ERROR; } -/* assemble_emit() - Extend the bytecode with a new instruction. - Update lnotab if necessary. -*/ - static int -assemble_emit(struct assembler *a, struct instr *i) +instructions_to_cfg(PyObject *instructions, cfg_builder *g) { - Py_ssize_t len = PyBytes_GET_SIZE(a->a_bytecode); - _Py_CODEUNIT *code; + instr_sequence seq; + memset(&seq, 0, sizeof(instr_sequence)); - int size = instr_size(i); - if (a->a_offset + size >= len / (int)sizeof(_Py_CODEUNIT)) { - if (len > PY_SSIZE_T_MAX / 2) - return 0; - if (_PyBytes_Resize(&a->a_bytecode, len * 2) < 0) - return 0; + if (instructions_to_instr_sequence(instructions, &seq) < 0) { + goto error; } - code = (_Py_CODEUNIT *)PyBytes_AS_STRING(a->a_bytecode) + a->a_offset; - a->a_offset += size; - write_instr(code, i, size); - return 1; + if (instr_sequence_to_cfg(&seq, g) < 0) { + goto error; + } + instr_sequence_fini(&seq); + return SUCCESS; +error: + instr_sequence_fini(&seq); + return ERROR; } -static void -normalize_jumps(struct assembler *a) +static PyObject * +instr_sequence_to_instructions(instr_sequence *seq) { - for (basicblock *b = a->a_entry; b != NULL; b = b->b_next) { - b->b_visited = 0; + PyObject *instructions = PyList_New(0); + if (instructions == NULL) { + return NULL; } - for (basicblock *b = a->a_entry; b != NULL; b = b->b_next) { - b->b_visited = 1; - if (b->b_iused == 0) { - continue; + for (int i = 0; i < seq->s_used; i++) { + instruction *instr = &seq->s_instrs[i]; + location loc = instr->i_loc; + int arg = HAS_TARGET(instr->i_opcode) ? + seq->s_labelmap[instr->i_oparg] : instr->i_oparg; + + PyObject *inst_tuple = Py_BuildValue( + "(iiiiii)", instr->i_opcode, arg, + loc.lineno, loc.end_lineno, + loc.col_offset, loc.end_col_offset); + if (inst_tuple == NULL) { + goto error; } - struct instr *last = &b->b_instr[b->b_iused-1]; - assert(!IS_ASSEMBLER_OPCODE(last->i_opcode)); - if (is_jump(last)) { - bool is_forward = last->i_target->b_visited == 0; - switch(last->i_opcode) { - case JUMP: - last->i_opcode = is_forward ? JUMP_FORWARD : JUMP_BACKWARD; - break; - case JUMP_NO_INTERRUPT: - last->i_opcode = is_forward ? - JUMP_FORWARD : JUMP_BACKWARD_NO_INTERRUPT; - break; - case POP_JUMP_IF_NOT_NONE: - last->i_opcode = is_forward ? - POP_JUMP_FORWARD_IF_NOT_NONE : POP_JUMP_BACKWARD_IF_NOT_NONE; - break; - case POP_JUMP_IF_NONE: - last->i_opcode = is_forward ? - POP_JUMP_FORWARD_IF_NONE : POP_JUMP_BACKWARD_IF_NONE; - break; - case POP_JUMP_IF_FALSE: - last->i_opcode = is_forward ? - POP_JUMP_FORWARD_IF_FALSE : POP_JUMP_BACKWARD_IF_FALSE; - break; - case POP_JUMP_IF_TRUE: - last->i_opcode = is_forward ? - POP_JUMP_FORWARD_IF_TRUE : POP_JUMP_BACKWARD_IF_TRUE; - break; - case JUMP_IF_TRUE_OR_POP: - case JUMP_IF_FALSE_OR_POP: - if (!is_forward) { - /* As far as we can tell, the compiler never emits - * these jumps with a backwards target. If/when this - * exception is raised, we have found a use case for - * a backwards version of this jump (or to replace - * it with the sequence (COPY 1, POP_JUMP_IF_T/F, POP) - */ - PyErr_Format(PyExc_SystemError, - "unexpected %s jumping backwards", - last->i_opcode == JUMP_IF_TRUE_OR_POP ? - "JUMP_IF_TRUE_OR_POP" : "JUMP_IF_FALSE_OR_POP"); - } - break; - } + + int res = PyList_Append(instructions, inst_tuple); + Py_DECREF(inst_tuple); + if (res != 0) { + goto error; } } + return instructions; +error: + Py_XDECREF(instructions); + return NULL; } -static void -assemble_jump_offsets(struct assembler *a, struct compiler *c) +static PyObject * +cfg_to_instructions(cfg_builder *g) { - basicblock *b; - int bsize, totsize, extended_arg_recompile; - int i; + PyObject *instructions = PyList_New(0); + if (instructions == NULL) { + return NULL; + } + int lbl = 0; + for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) { + b->b_label = (jump_target_label){lbl}; + lbl += b->b_iused; + } + for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) { + for (int i = 0; i < b->b_iused; i++) { + cfg_instr *instr = &b->b_instr[i]; + location loc = instr->i_loc; + int arg = HAS_TARGET(instr->i_opcode) ? + instr->i_target->b_label.id : instr->i_oparg; + + PyObject *inst_tuple = Py_BuildValue( + "(iiiiii)", instr->i_opcode, arg, + loc.lineno, loc.end_lineno, + loc.col_offset, loc.end_col_offset); + if (inst_tuple == NULL) { + goto error; + } - /* Compute the size of each block and fixup jump args. - Replace block pointer with position in bytecode. */ - do { - totsize = 0; - for (basicblock *b = a->a_entry; b != NULL; b = b->b_next) { - bsize = blocksize(b); - b->b_offset = totsize; - totsize += bsize; - } - extended_arg_recompile = 0; - for (b = c->u->u_blocks; b != NULL; b = b->b_list) { - bsize = b->b_offset; - for (i = 0; i < b->b_iused; i++) { - struct instr *instr = &b->b_instr[i]; - int isize = instr_size(instr); - /* Relative jumps are computed relative to - the instruction pointer after fetching - the jump instruction. - */ - bsize += isize; - if (is_jump(instr)) { - instr->i_oparg = instr->i_target->b_offset; - if (is_relative_jump(instr)) { - if (instr->i_oparg < bsize) { - assert(IS_BACKWARDS_JUMP_OPCODE(instr->i_opcode)); - instr->i_oparg = bsize - instr->i_oparg; - } - else { - assert(!IS_BACKWARDS_JUMP_OPCODE(instr->i_opcode)); - instr->i_oparg -= bsize; - } - } - else { - assert(!IS_BACKWARDS_JUMP_OPCODE(instr->i_opcode)); - } - if (instr_size(instr) != isize) { - extended_arg_recompile = 1; - } - } + if (PyList_Append(instructions, inst_tuple) != 0) { + Py_DECREF(inst_tuple); + goto error; } + Py_DECREF(inst_tuple); } + } - /* XXX: This is an awful hack that could hurt performance, but - on the bright side it should work until we come up - with a better solution. - - The issue is that in the first loop blocksize() is called - which calls instr_size() which requires i_oparg be set - appropriately. There is a bootstrap problem because - i_oparg is calculated in the second loop above. - - So we loop until we stop seeing new EXTENDED_ARGs. - The only EXTENDED_ARGs that could be popping up are - ones in jump instructions. So this should converge - fairly quickly. - */ - } while (extended_arg_recompile); + return instructions; +error: + Py_DECREF(instructions); + return NULL; } -static PyObject * -dict_keys_inorder(PyObject *dict, Py_ssize_t offset) +PyObject * +_PyCompile_CodeGen(PyObject *ast, PyObject *filename, PyCompilerFlags *pflags, + int optimize, int compile_mode) { - PyObject *tuple, *k, *v; - Py_ssize_t i, pos = 0, size = PyDict_GET_SIZE(dict); + PyObject *res = NULL; + PyObject *metadata = NULL; - tuple = PyTuple_New(size); - if (tuple == NULL) + if (!PyAST_Check(ast)) { + PyErr_SetString(PyExc_TypeError, "expected an AST"); return NULL; - while (PyDict_Next(dict, &pos, &k, &v)) { - i = PyLong_AS_LONG(v); - Py_INCREF(k); - assert((i - offset) < size); - assert((i - offset) >= 0); - PyTuple_SET_ITEM(tuple, i - offset, k); } - return tuple; -} - -static PyObject * -consts_dict_keys_inorder(PyObject *dict) -{ - PyObject *consts, *k, *v; - Py_ssize_t i, pos = 0, size = PyDict_GET_SIZE(dict); - consts = PyList_New(size); /* PyCode_Optimize() requires a list */ - if (consts == NULL) + PyArena *arena = _PyArena_New(); + if (arena == NULL) { return NULL; - while (PyDict_Next(dict, &pos, &k, &v)) { - i = PyLong_AS_LONG(v); - /* The keys of the dictionary can be tuples wrapping a constant. - * (see compiler_add_o and _PyCode_ConstantKey). In that case - * the object we want is always second. */ - if (PyTuple_CheckExact(k)) { - k = PyTuple_GET_ITEM(k, 1); - } - Py_INCREF(k); - assert(i < size); - assert(i >= 0); - PyList_SET_ITEM(consts, i, k); } - return consts; -} -static int -compute_code_flags(struct compiler *c) -{ - PySTEntryObject *ste = c->u->u_ste; - int flags = 0; - if (ste->ste_type == FunctionBlock) { - flags |= CO_NEWLOCALS | CO_OPTIMIZED; - if (ste->ste_nested) - flags |= CO_NESTED; - if (ste->ste_generator && !ste->ste_coroutine) - flags |= CO_GENERATOR; - if (!ste->ste_generator && ste->ste_coroutine) - flags |= CO_COROUTINE; - if (ste->ste_generator && ste->ste_coroutine) - flags |= CO_ASYNC_GENERATOR; - if (ste->ste_varargs) - flags |= CO_VARARGS; - if (ste->ste_varkeywords) - flags |= CO_VARKEYWORDS; + mod_ty mod = PyAST_obj2mod(ast, arena, compile_mode); + if (mod == NULL || !_PyAST_Validate(mod)) { + _PyArena_Free(arena); + return NULL; } - /* (Only) inherit compilerflags in PyCF_MASK */ - flags |= (c->c_flags->cf_flags & PyCF_MASK); - - if ((IS_TOP_LEVEL_AWAIT(c)) && - ste->ste_coroutine && - !ste->ste_generator) { - flags |= CO_COROUTINE; + struct compiler *c = new_compiler(mod, filename, pflags, optimize, arena); + if (c == NULL) { + _PyArena_Free(arena); + return NULL; } - return flags; -} - -// Merge *obj* with constant cache. -// Unlike merge_consts_recursive(), this function doesn't work recursively. -static int -merge_const_one(struct compiler *c, PyObject **obj) -{ - PyObject *key = _PyCode_ConstantKey(*obj); - if (key == NULL) { - return 0; + if (compiler_codegen(c, mod) < 0) { + goto finally; } - // t is borrowed reference - PyObject *t = PyDict_SetDefault(c->c_const_cache, key, key); - Py_DECREF(key); - if (t == NULL) { - return 0; + _PyCompile_CodeUnitMetadata *umd = &c->u->u_metadata; + metadata = PyDict_New(); + if (metadata == NULL) { + goto finally; } - if (t == key) { // obj is new constant. - return 1; +#define SET_MATADATA_ITEM(key, value) \ + if (value != NULL) { \ + if (PyDict_SetItemString(metadata, key, value) < 0) goto finally; \ + } + + SET_MATADATA_ITEM("name", umd->u_name); + SET_MATADATA_ITEM("qualname", umd->u_qualname); + SET_MATADATA_ITEM("consts", umd->u_consts); + SET_MATADATA_ITEM("names", umd->u_names); + SET_MATADATA_ITEM("varnames", umd->u_varnames); + SET_MATADATA_ITEM("cellvars", umd->u_cellvars); + SET_MATADATA_ITEM("freevars", umd->u_freevars); +#undef SET_MATADATA_ITEM + +#define SET_MATADATA_INT(key, value) do { \ + PyObject *v = PyLong_FromLong((long)value); \ + if (v == NULL) goto finally; \ + int res = PyDict_SetItemString(metadata, key, v); \ + Py_XDECREF(v); \ + if (res < 0) goto finally; \ + } while (0); + + SET_MATADATA_INT("argcount", umd->u_argcount); + SET_MATADATA_INT("posonlyargcount", umd->u_posonlyargcount); + SET_MATADATA_INT("kwonlyargcount", umd->u_kwonlyargcount); +#undef SET_MATADATA_INT + + int addNone = mod->kind != Expression_kind; + if (add_return_at_end(c, addNone) < 0) { + goto finally; } - if (PyTuple_CheckExact(t)) { - // t is still borrowed reference - t = PyTuple_GET_ITEM(t, 1); + PyObject *insts = instr_sequence_to_instructions(INSTR_SEQUENCE(c)); + if (insts == NULL) { + goto finally; } + res = PyTuple_Pack(2, insts, metadata); + Py_DECREF(insts); - Py_INCREF(t); - Py_DECREF(*obj); - *obj = t; - return 1; +finally: + Py_XDECREF(metadata); + compiler_exit_scope(c); + compiler_free(c); + _PyArena_Free(arena); + return res; } -// This is in codeobject.c. -extern void _Py_set_localsplus_info(int, PyObject *, unsigned char, - PyObject *, PyObject *); - -static void -compute_localsplus_info(struct compiler *c, int nlocalsplus, - PyObject *names, PyObject *kinds) +PyObject * +_PyCompile_OptimizeCfg(PyObject *instructions, PyObject *consts, int nlocals) { - PyObject *k, *v; - Py_ssize_t pos = 0; - while (PyDict_Next(c->u->u_varnames, &pos, &k, &v)) { - int offset = (int)PyLong_AS_LONG(v); - assert(offset >= 0); - assert(offset < nlocalsplus); - // For now we do not distinguish arg kinds. - _PyLocals_Kind kind = CO_FAST_LOCAL; - if (PyDict_GetItem(c->u->u_cellvars, k) != NULL) { - kind |= CO_FAST_CELL; - } - _Py_set_localsplus_info(offset, k, kind, names, kinds); + PyObject *res = NULL; + PyObject *const_cache = PyDict_New(); + if (const_cache == NULL) { + return NULL; } - int nlocals = (int)PyDict_GET_SIZE(c->u->u_varnames); - // This counter mirrors the fix done in fix_cell_offsets(). - int numdropped = 0; - pos = 0; - while (PyDict_Next(c->u->u_cellvars, &pos, &k, &v)) { - if (PyDict_GetItem(c->u->u_varnames, k) != NULL) { - // Skip cells that are already covered by locals. - numdropped += 1; - continue; - } - int offset = (int)PyLong_AS_LONG(v); - assert(offset >= 0); - offset += nlocals - numdropped; - assert(offset < nlocalsplus); - _Py_set_localsplus_info(offset, k, CO_FAST_CELL, names, kinds); + cfg_builder g; + if (instructions_to_cfg(instructions, &g) < 0) { + goto error; } - - pos = 0; - while (PyDict_Next(c->u->u_freevars, &pos, &k, &v)) { - int offset = (int)PyLong_AS_LONG(v); - assert(offset >= 0); - offset += nlocals - numdropped; - assert(offset < nlocalsplus); - _Py_set_localsplus_info(offset, k, CO_FAST_FREE, names, kinds); + int code_flags = 0, nparams = 0, firstlineno = 1; + if (_PyCfg_OptimizeCodeUnit(&g, consts, const_cache, code_flags, nlocals, + nparams, firstlineno) < 0) { + goto error; } + res = cfg_to_instructions(&g); +error: + Py_DECREF(const_cache); + _PyCfgBuilder_Fini(&g); + return res; } -static PyCodeObject * -makecode(struct compiler *c, struct assembler *a, PyObject *constslist, - int maxdepth, int nlocalsplus) +int _PyCfg_JumpLabelsToTargets(basicblock *entryblock); + +PyCodeObject * +_PyCompile_Assemble(_PyCompile_CodeUnitMetadata *umd, PyObject *filename, + PyObject *instructions) { PyCodeObject *co = NULL; - PyObject *names = NULL; - PyObject *consts = NULL; - PyObject *localsplusnames = NULL; - PyObject *localspluskinds = NULL; - - names = dict_keys_inorder(c->u->u_names, 0); - if (!names) { - goto error; - } - if (!merge_const_one(c, &names)) { - goto error; - } - - int flags = compute_code_flags(c); - if (flags < 0) { - goto error; - } + instr_sequence optimized_instrs; + memset(&optimized_instrs, 0, sizeof(instr_sequence)); - consts = PyList_AsTuple(constslist); /* PyCode_New requires a tuple */ - if (consts == NULL) { - goto error; - } - if (!merge_const_one(c, &consts)) { - goto error; + PyObject *const_cache = PyDict_New(); + if (const_cache == NULL) { + return NULL; } - assert(c->u->u_posonlyargcount < INT_MAX); - assert(c->u->u_argcount < INT_MAX); - assert(c->u->u_kwonlyargcount < INT_MAX); - int posonlyargcount = (int)c->u->u_posonlyargcount; - int posorkwargcount = (int)c->u->u_argcount; - assert(INT_MAX - posonlyargcount - posorkwargcount > 0); - int kwonlyargcount = (int)c->u->u_kwonlyargcount; - - localsplusnames = PyTuple_New(nlocalsplus); - if (localsplusnames == NULL) { + cfg_builder g; + if (instructions_to_cfg(instructions, &g) < 0) { goto error; } - localspluskinds = PyBytes_FromStringAndSize(NULL, nlocalsplus); - if (localspluskinds == NULL) { - goto error; - } - compute_localsplus_info(c, nlocalsplus, localsplusnames, localspluskinds); - - struct _PyCodeConstructor con = { - .filename = c->c_filename, - .name = c->u->u_name, - .qualname = c->u->u_qualname ? c->u->u_qualname : c->u->u_name, - .flags = flags, - - .code = a->a_bytecode, - .firstlineno = c->u->u_firstlineno, - .linetable = a->a_linetable, - .consts = consts, - .names = names, - - .localsplusnames = localsplusnames, - .localspluskinds = localspluskinds, - - .argcount = posonlyargcount + posorkwargcount, - .posonlyargcount = posonlyargcount, - .kwonlyargcount = kwonlyargcount, - - .stacksize = maxdepth, - - .exceptiontable = a->a_except_table, - }; - - if (_PyCode_Validate(&con) < 0) { + if (_PyCfg_JumpLabelsToTargets(g.g_entryblock) < 0) { goto error; } - if (!merge_const_one(c, &localsplusnames)) { + int code_flags = 0; + int nlocalsplus = prepare_localsplus(umd, &g, code_flags); + if (nlocalsplus < 0) { goto error; } - con.localsplusnames = localsplusnames; - co = _PyCode_New(&con); - if (co == NULL) { + int maxdepth = _PyCfg_Stackdepth(g.g_entryblock, code_flags); + if (maxdepth < 0) { goto error; } - error: - Py_XDECREF(names); - Py_XDECREF(consts); - Py_XDECREF(localsplusnames); - Py_XDECREF(localspluskinds); - return co; -} - - -/* For debugging purposes only */ -#if 0 -static void -dump_instr(struct instr *i) -{ - const char *jrel = (is_relative_jump(i)) ? "jrel " : ""; - const char *jabs = (is_jump(i) && !is_relative_jump(i))? "jabs " : ""; - - char arg[128]; - - *arg = '\0'; - if (HAS_ARG(i->i_opcode)) { - sprintf(arg, "arg: %d ", i->i_oparg); - } - fprintf(stderr, "line: %d, opcode: %d %s%s%s\n", - i->i_lineno, i->i_opcode, arg, jabs, jrel); -} - -static void -dump_basicblock(const basicblock *b) -{ - const char *b_return = b->b_return ? "return " : ""; - fprintf(stderr, "used: %d, depth: %d, offset: %d %s\n", - b->b_iused, b->b_startdepth, b->b_offset, b_return); - if (b->b_instr) { - int i; - for (i = 0; i < b->b_iused; i++) { - fprintf(stderr, " [%02d] ", i); - dump_instr(b->b_instr + i); - } - } -} -#endif - - -static int -normalize_basic_block(basicblock *bb); - -static int -optimize_cfg(struct compiler *c, struct assembler *a, PyObject *consts); - -static int -trim_unused_consts(struct compiler *c, struct assembler *a, PyObject *consts); - -/* Duplicates exit BBs, so that line numbers can be propagated to them */ -static int -duplicate_exits_without_lineno(struct compiler *c); - -static int -extend_block(basicblock *bb); - -static int * -build_cellfixedoffsets(struct compiler *c) -{ - int nlocals = (int)PyDict_GET_SIZE(c->u->u_varnames); - int ncellvars = (int)PyDict_GET_SIZE(c->u->u_cellvars); - int nfreevars = (int)PyDict_GET_SIZE(c->u->u_freevars); - - int noffsets = ncellvars + nfreevars; - int *fixed = PyMem_New(int, noffsets); - if (fixed == NULL) { - PyErr_NoMemory(); - return NULL; - } - for (int i = 0; i < noffsets; i++) { - fixed[i] = nlocals + i; - } - - PyObject *varname, *cellindex; - Py_ssize_t pos = 0; - while (PyDict_Next(c->u->u_cellvars, &pos, &varname, &cellindex)) { - PyObject *varindex = PyDict_GetItem(c->u->u_varnames, varname); - if (varindex != NULL) { - assert(PyLong_AS_LONG(cellindex) < INT_MAX); - assert(PyLong_AS_LONG(varindex) < INT_MAX); - int oldindex = (int)PyLong_AS_LONG(cellindex); - int argoffset = (int)PyLong_AS_LONG(varindex); - fixed[oldindex] = argoffset; - } - } - - return fixed; -} - -static inline int -insert_instruction(basicblock *block, int pos, struct instr *instr) { - if (compiler_next_instr(block) < 0) { - return -1; - } - for (int i = block->b_iused-1; i > pos; i--) { - block->b_instr[i] = block->b_instr[i-1]; - } - block->b_instr[pos] = *instr; - return 0; -} - -static int -insert_prefix_instructions(struct compiler *c, basicblock *entryblock, - int *fixed, int nfreevars) -{ - - int flags = compute_code_flags(c); - if (flags < 0) { - return -1; - } - assert(c->u->u_firstlineno > 0); - - /* Add the generator prefix instructions. */ - if (flags & (CO_GENERATOR | CO_COROUTINE | CO_ASYNC_GENERATOR)) { - struct instr make_gen = { - .i_opcode = RETURN_GENERATOR, - .i_oparg = 0, - .i_lineno = c->u->u_firstlineno, - .i_col_offset = -1, - .i_end_lineno = c->u->u_firstlineno, - .i_end_col_offset = -1, - .i_target = NULL, - }; - if (insert_instruction(entryblock, 0, &make_gen) < 0) { - return -1; - } - struct instr pop_top = { - .i_opcode = POP_TOP, - .i_oparg = 0, - .i_lineno = -1, - .i_col_offset = -1, - .i_end_lineno = -1, - .i_end_col_offset = -1, - .i_target = NULL, - }; - if (insert_instruction(entryblock, 1, &pop_top) < 0) { - return -1; - } - } - - /* Set up cells for any variable that escapes, to be put in a closure. */ - const int ncellvars = (int)PyDict_GET_SIZE(c->u->u_cellvars); - if (ncellvars) { - // c->u->u_cellvars has the cells out of order so we sort them - // before adding the MAKE_CELL instructions. Note that we - // adjust for arg cells, which come first. - const int nvars = ncellvars + (int)PyDict_GET_SIZE(c->u->u_varnames); - int *sorted = PyMem_RawCalloc(nvars, sizeof(int)); - if (sorted == NULL) { - PyErr_NoMemory(); - return -1; - } - for (int i = 0; i < ncellvars; i++) { - sorted[fixed[i]] = i + 1; - } - for (int i = 0, ncellsused = 0; ncellsused < ncellvars; i++) { - int oldindex = sorted[i] - 1; - if (oldindex == -1) { - continue; - } - struct instr make_cell = { - .i_opcode = MAKE_CELL, - // This will get fixed in offset_derefs(). - .i_oparg = oldindex, - .i_lineno = -1, - .i_col_offset = -1, - .i_end_lineno = -1, - .i_end_col_offset = -1, - .i_target = NULL, - }; - if (insert_instruction(entryblock, ncellsused, &make_cell) < 0) { - return -1; - } - ncellsused += 1; - } - PyMem_RawFree(sorted); - } - - if (nfreevars) { - struct instr copy_frees = { - .i_opcode = COPY_FREE_VARS, - .i_oparg = nfreevars, - .i_lineno = -1, - .i_col_offset = -1, - .i_end_lineno = -1, - .i_end_col_offset = -1, - .i_target = NULL, - }; - if (insert_instruction(entryblock, 0, ©_frees) < 0) { - return -1; - } - - } - - return 0; -} - -/* Make sure that all returns have a line number, even if early passes - * have failed to propagate a correct line number. - * The resulting line number may not be correct according to PEP 626, - * but should be "good enough", and no worse than in older versions. */ -static void -guarantee_lineno_for_exits(struct assembler *a, int firstlineno) { - int lineno = firstlineno; - assert(lineno > 0); - for (basicblock *b = a->a_entry; b != NULL; b = b->b_next) { - if (b->b_iused == 0) { - continue; - } - struct instr *last = &b->b_instr[b->b_iused-1]; - if (last->i_lineno < 0) { - if (last->i_opcode == RETURN_VALUE) { - for (int i = 0; i < b->b_iused; i++) { - assert(b->b_instr[i].i_lineno < 0); - - b->b_instr[i].i_lineno = lineno; - } - } - } - else { - lineno = last->i_lineno; - } - } -} - -static int -fix_cell_offsets(struct compiler *c, basicblock *entryblock, int *fixedmap) -{ - int nlocals = (int)PyDict_GET_SIZE(c->u->u_varnames); - int ncellvars = (int)PyDict_GET_SIZE(c->u->u_cellvars); - int nfreevars = (int)PyDict_GET_SIZE(c->u->u_freevars); - int noffsets = ncellvars + nfreevars; - - // First deal with duplicates (arg cells). - int numdropped = 0; - for (int i = 0; i < noffsets ; i++) { - if (fixedmap[i] == i + nlocals) { - fixedmap[i] -= numdropped; - } - else { - // It was a duplicate (cell/arg). - numdropped += 1; - } - } - - // Then update offsets, either relative to locals or by cell2arg. - for (basicblock *b = entryblock; b != NULL; b = b->b_next) { - for (int i = 0; i < b->b_iused; i++) { - struct instr *inst = &b->b_instr[i]; - // This is called before extended args are generated. - assert(inst->i_opcode != EXTENDED_ARG); - assert(inst->i_opcode != EXTENDED_ARG_QUICK); - int oldoffset = inst->i_oparg; - switch(inst->i_opcode) { - case MAKE_CELL: - case LOAD_CLOSURE: - case LOAD_DEREF: - case STORE_DEREF: - case DELETE_DEREF: - case LOAD_CLASSDEREF: - assert(oldoffset >= 0); - assert(oldoffset < noffsets); - assert(fixedmap[oldoffset] >= 0); - inst->i_oparg = fixedmap[oldoffset]; - } - } - } - - return numdropped; -} - -static void -propagate_line_numbers(struct assembler *a); - -static PyCodeObject * -assemble(struct compiler *c, int addNone) -{ - basicblock *b, *entryblock; - struct assembler a; - int j, nblocks; - PyCodeObject *co = NULL; - PyObject *consts = NULL; - memset(&a, 0, sizeof(struct assembler)); - - /* Make sure every block that falls off the end returns None. */ - if (!c->u->u_curblock->b_return) { - UNSET_LOC(c); - if (addNone) - ADDOP_LOAD_CONST(c, Py_None); - ADDOP(c, RETURN_VALUE); - } - - for (basicblock *b = c->u->u_blocks; b != NULL; b = b->b_list) { - if (normalize_basic_block(b)) { - return NULL; - } - } - - for (basicblock *b = c->u->u_blocks; b != NULL; b = b->b_list) { - if (extend_block(b)) { - return NULL; - } - } - - nblocks = 0; - entryblock = NULL; - for (b = c->u->u_blocks; b != NULL; b = b->b_list) { - nblocks++; - entryblock = b; - } - assert(entryblock != NULL); - - assert(PyDict_GET_SIZE(c->u->u_varnames) < INT_MAX); - assert(PyDict_GET_SIZE(c->u->u_cellvars) < INT_MAX); - assert(PyDict_GET_SIZE(c->u->u_freevars) < INT_MAX); - int nlocals = (int)PyDict_GET_SIZE(c->u->u_varnames); - int ncellvars = (int)PyDict_GET_SIZE(c->u->u_cellvars); - int nfreevars = (int)PyDict_GET_SIZE(c->u->u_freevars); - assert(INT_MAX - nlocals - ncellvars > 0); - assert(INT_MAX - nlocals - ncellvars - nfreevars > 0); - int nlocalsplus = nlocals + ncellvars + nfreevars; - int *cellfixedoffsets = build_cellfixedoffsets(c); - if (cellfixedoffsets == NULL) { - goto error; - } + _PyCfg_ConvertPseudoOps(g.g_entryblock); - /* Set firstlineno if it wasn't explicitly set. */ - if (!c->u->u_firstlineno) { - if (entryblock->b_instr && entryblock->b_instr->i_lineno) { - c->u->u_firstlineno = entryblock->b_instr->i_lineno; - } - else { - c->u->u_firstlineno = 1; - } - } + /* Order of basic blocks must have been determined by now */ - // This must be called before fix_cell_offsets(). - if (insert_prefix_instructions(c, entryblock, cellfixedoffsets, nfreevars)) { + if (_PyCfg_ResolveJumps(&g) < 0) { goto error; } - if (!assemble_init(&a, nblocks, c->u->u_firstlineno)) - goto error; - a.a_entry = entryblock; - a.a_nblocks = nblocks; + /* Can't modify the bytecode after computing jump offsets. */ - int numdropped = fix_cell_offsets(c, entryblock, cellfixedoffsets); - PyMem_Free(cellfixedoffsets); // At this point we're done with it. - cellfixedoffsets = NULL; - if (numdropped < 0) { + if (cfg_to_instr_sequence(&g, &optimized_instrs) < 0) { goto error; } - nlocalsplus -= numdropped; - consts = consts_dict_keys_inorder(c->u->u_consts); + PyObject *consts = consts_dict_keys_inorder(umd->u_consts); if (consts == NULL) { goto error; } + co = _PyAssemble_MakeCodeObject(umd, const_cache, + consts, maxdepth, &optimized_instrs, + nlocalsplus, code_flags, filename); + Py_DECREF(consts); - if (optimize_cfg(c, &a, consts)) { - goto error; - } - if (duplicate_exits_without_lineno(c)) { - return NULL; - } - if (trim_unused_consts(c, &a, consts)) { - goto error; - } - propagate_line_numbers(&a); - guarantee_lineno_for_exits(&a, c->u->u_firstlineno); - int maxdepth = stackdepth(c); - if (maxdepth < 0) { - goto error; - } - /* TO DO -- For 3.12, make sure that `maxdepth <= MAX_ALLOWED_STACK_USE` */ - - if (label_exception_targets(entryblock)) { - goto error; - } - convert_exception_handlers_to_nops(entryblock); - for (basicblock *b = a.a_entry; b != NULL; b = b->b_next) { - clean_basic_block(b); - } - - /* Order of basic blocks must have been determined by now */ - normalize_jumps(&a); - - /* Can't modify the bytecode after computing jump offsets. */ - assemble_jump_offsets(&a, c); - - /* Emit code. */ - for(b = entryblock; b != NULL; b = b->b_next) { - for (j = 0; j < b->b_iused; j++) - if (!assemble_emit(&a, &b->b_instr[j])) - goto error; - } - - /* Emit location info */ - a.a_lineno = c->u->u_firstlineno; - for(b = entryblock; b != NULL; b = b->b_next) { - for (j = 0; j < b->b_iused; j++) - if (!assemble_emit_location(&a, &b->b_instr[j])) - goto error; - } - - if (!assemble_exception_table(&a)) { - goto error; - } - if (_PyBytes_Resize(&a.a_except_table, a.a_except_table_off) < 0) { - goto error; - } - if (!merge_const_one(c, &a.a_except_table)) { - goto error; - } - - if (_PyBytes_Resize(&a.a_linetable, a.a_location_off) < 0) { - goto error; - } - if (!merge_const_one(c, &a.a_linetable)) { - goto error; - } - - if (_PyBytes_Resize(&a.a_bytecode, a.a_offset * sizeof(_Py_CODEUNIT)) < 0) { - goto error; - } - if (!merge_const_one(c, &a.a_bytecode)) { - goto error; - } - - co = makecode(c, &a, consts, maxdepth, nlocalsplus); - error: - Py_XDECREF(consts); - assemble_free(&a); - if (cellfixedoffsets != NULL) { - PyMem_Free(cellfixedoffsets); - } - return co; -} - -static PyObject* -get_const_value(int opcode, int oparg, PyObject *co_consts) -{ - PyObject *constant = NULL; - assert(HAS_CONST(opcode)); - if (opcode == LOAD_CONST) { - constant = PyList_GET_ITEM(co_consts, oparg); - } - - if (constant == NULL) { - PyErr_SetString(PyExc_SystemError, - "Internal error: failed to get value of a constant"); - return NULL; - } - Py_INCREF(constant); - return constant; -} - -/* Replace LOAD_CONST c1, LOAD_CONST c2 ... LOAD_CONST cn, BUILD_TUPLE n - with LOAD_CONST (c1, c2, ... cn). - The consts table must still be in list form so that the - new constant (c1, c2, ... cn) can be appended. - Called with codestr pointing to the first LOAD_CONST. -*/ -static int -fold_tuple_on_constants(struct compiler *c, - struct instr *inst, - int n, PyObject *consts) -{ - /* Pre-conditions */ - assert(PyList_CheckExact(consts)); - assert(inst[n].i_opcode == BUILD_TUPLE); - assert(inst[n].i_oparg == n); - - for (int i = 0; i < n; i++) { - if (!HAS_CONST(inst[i].i_opcode)) { - return 0; - } - } - - /* Buildup new tuple of constants */ - PyObject *newconst = PyTuple_New(n); - if (newconst == NULL) { - return -1; - } - for (int i = 0; i < n; i++) { - int op = inst[i].i_opcode; - int arg = inst[i].i_oparg; - PyObject *constant = get_const_value(op, arg, consts); - if (constant == NULL) { - return -1; - } - PyTuple_SET_ITEM(newconst, i, constant); - } - if (merge_const_one(c, &newconst) == 0) { - Py_DECREF(newconst); - return -1; - } - - Py_ssize_t index; - for (index = 0; index < PyList_GET_SIZE(consts); index++) { - if (PyList_GET_ITEM(consts, index) == newconst) { - break; - } - } - if (index == PyList_GET_SIZE(consts)) { - if ((size_t)index >= (size_t)INT_MAX - 1) { - Py_DECREF(newconst); - PyErr_SetString(PyExc_OverflowError, "too many constants"); - return -1; - } - if (PyList_Append(consts, newconst)) { - Py_DECREF(newconst); - return -1; - } - } - Py_DECREF(newconst); - for (int i = 0; i < n; i++) { - inst[i].i_opcode = NOP; - } - inst[n].i_opcode = LOAD_CONST; - inst[n].i_oparg = (int)index; - return 0; -} - -#define VISITED (-1) - -// Replace an arbitrary run of SWAPs and NOPs with an optimal one that has the -// same effect. -static int -swaptimize(basicblock *block, int *ix) -{ - // NOTE: "./python -m test test_patma" serves as a good, quick stress test - // for this function. Make sure to blow away cached *.pyc files first! - assert(*ix < block->b_iused); - struct instr *instructions = &block->b_instr[*ix]; - // Find the length of the current sequence of SWAPs and NOPs, and record the - // maximum depth of the stack manipulations: - assert(instructions[0].i_opcode == SWAP); - int depth = instructions[0].i_oparg; - int len = 0; - int more = false; - int limit = block->b_iused - *ix; - while (++len < limit) { - int opcode = instructions[len].i_opcode; - if (opcode == SWAP) { - depth = Py_MAX(depth, instructions[len].i_oparg); - more = true; - } - else if (opcode != NOP) { - break; - } - } - // It's already optimal if there's only one SWAP: - if (!more) { - return 0; - } - // Create an array with elements {0, 1, 2, ..., depth - 1}: - int *stack = PyMem_Malloc(depth * sizeof(int)); - if (stack == NULL) { - PyErr_NoMemory(); - return -1; - } - for (int i = 0; i < depth; i++) { - stack[i] = i; - } - // Simulate the combined effect of these instructions by "running" them on - // our "stack": - for (int i = 0; i < len; i++) { - if (instructions[i].i_opcode == SWAP) { - int oparg = instructions[i].i_oparg; - int top = stack[0]; - // SWAPs are 1-indexed: - stack[0] = stack[oparg - 1]; - stack[oparg - 1] = top; - } - } - // Now we can begin! Our approach here is based on a solution to a closely - // related problem (https://cs.stackexchange.com/a/13938). It's easiest to - // think of this algorithm as determining the steps needed to efficiently - // "un-shuffle" our stack. By performing the moves in *reverse* order, - // though, we can efficiently *shuffle* it! For this reason, we will be - // replacing instructions starting from the *end* of the run. Since the - // solution is optimal, we don't need to worry about running out of space: - int current = len - 1; - for (int i = 0; i < depth; i++) { - // Skip items that have already been visited, or just happen to be in - // the correct location: - if (stack[i] == VISITED || stack[i] == i) { - continue; - } - // Okay, we've found an item that hasn't been visited. It forms a cycle - // with other items; traversing the cycle and swapping each item with - // the next will put them all in the correct place. The weird - // loop-and-a-half is necessary to insert 0 into every cycle, since we - // can only swap from that position: - int j = i; - while (true) { - // Skip the actual swap if our item is zero, since swapping the top - // item with itself is pointless: - if (j) { - assert(0 <= current); - // SWAPs are 1-indexed: - instructions[current].i_opcode = SWAP; - instructions[current--].i_oparg = j + 1; - } - if (stack[j] == VISITED) { - // Completed the cycle: - assert(j == i); - break; - } - int next_j = stack[j]; - stack[j] = VISITED; - j = next_j; - } - } - // NOP out any unused instructions: - while (0 <= current) { - instructions[current--].i_opcode = NOP; - } - PyMem_Free(stack); - *ix += len - 1; - return 0; -} - -// This list is pretty small, since it's only okay to reorder opcodes that: -// - can't affect control flow (like jumping or raising exceptions) -// - can't invoke arbitrary code (besides finalizers) -// - only touch the TOS (and pop it when finished) -#define SWAPPABLE(opcode) \ - ((opcode) == STORE_FAST || (opcode) == POP_TOP) - -static int -next_swappable_instruction(basicblock *block, int i, int lineno) -{ - while (++i < block->b_iused) { - struct instr *instruction = &block->b_instr[i]; - if (0 <= lineno && instruction->i_lineno != lineno) { - // Optimizing across this instruction could cause user-visible - // changes in the names bound between line tracing events! - return -1; - } - if (instruction->i_opcode == NOP) { - continue; - } - if (SWAPPABLE(instruction->i_opcode)) { - return i; - } - return -1; - } - return -1; -} - -// Attempt to apply SWAPs statically by swapping *instructions* rather than -// stack items. For example, we can replace SWAP(2), POP_TOP, STORE_FAST(42) -// with the more efficient NOP, STORE_FAST(42), POP_TOP. -static void -apply_static_swaps(basicblock *block, int i) -{ - // SWAPs are to our left, and potential swaperands are to our right: - for (; 0 <= i; i--) { - assert(i < block->b_iused); - struct instr *swap = &block->b_instr[i]; - if (swap->i_opcode != SWAP) { - if (swap->i_opcode == NOP || SWAPPABLE(swap->i_opcode)) { - // Nope, but we know how to handle these. Keep looking: - continue; - } - // We can't reason about what this instruction does. Bail: - return; - } - int j = next_swappable_instruction(block, i, -1); - if (j < 0) { - return; - } - int k = j; - int lineno = block->b_instr[j].i_lineno; - for (int count = swap->i_oparg - 1; 0 < count; count--) { - k = next_swappable_instruction(block, k, lineno); - if (k < 0) { - return; - } - } - // Success! - swap->i_opcode = NOP; - struct instr temp = block->b_instr[j]; - block->b_instr[j] = block->b_instr[k]; - block->b_instr[k] = temp; - } -} - -// Attempt to eliminate jumps to jumps by updating inst to jump to -// target->i_target using the provided opcode. Return whether or not the -// optimization was successful. -static bool -jump_thread(struct instr *inst, struct instr *target, int opcode) -{ - assert(!IS_VIRTUAL_OPCODE(opcode) || IS_VIRTUAL_JUMP_OPCODE(opcode)); - assert(is_jump(inst)); - assert(is_jump(target)); - // bpo-45773: If inst->i_target == target->i_target, then nothing actually - // changes (and we fall into an infinite loop): - if (inst->i_lineno == target->i_lineno && - inst->i_target != target->i_target) - { - inst->i_target = target->i_target; - inst->i_opcode = opcode; - return true; - } - return false; -} - -/* Maximum size of basic block that should be copied in optimizer */ -#define MAX_COPY_SIZE 4 - -/* Optimization */ -static int -optimize_basic_block(struct compiler *c, basicblock *bb, PyObject *consts) -{ - assert(PyList_CheckExact(consts)); - struct instr nop; - nop.i_opcode = NOP; - struct instr *target; - for (int i = 0; i < bb->b_iused; i++) { - struct instr *inst = &bb->b_instr[i]; - int oparg = inst->i_oparg; - int nextop = i+1 < bb->b_iused ? bb->b_instr[i+1].i_opcode : 0; - if (is_jump(inst) || is_block_push(inst)) { - /* Skip over empty basic blocks. */ - while (inst->i_target->b_iused == 0) { - inst->i_target = inst->i_target->b_next; - } - target = &inst->i_target->b_instr[0]; - assert(!IS_ASSEMBLER_OPCODE(target->i_opcode)); - } - else { - target = &nop; - } - assert(!IS_ASSEMBLER_OPCODE(inst->i_opcode)); - switch (inst->i_opcode) { - /* Remove LOAD_CONST const; conditional jump */ - case LOAD_CONST: - { - PyObject* cnt; - int is_true; - int jump_if_true; - switch(nextop) { - case POP_JUMP_IF_FALSE: - case POP_JUMP_IF_TRUE: - cnt = get_const_value(inst->i_opcode, oparg, consts); - if (cnt == NULL) { - goto error; - } - is_true = PyObject_IsTrue(cnt); - Py_DECREF(cnt); - if (is_true == -1) { - goto error; - } - inst->i_opcode = NOP; - jump_if_true = nextop == POP_JUMP_IF_TRUE; - if (is_true == jump_if_true) { - bb->b_instr[i+1].i_opcode = JUMP; - bb->b_nofallthrough = 1; - } - else { - bb->b_instr[i+1].i_opcode = NOP; - } - break; - case JUMP_IF_FALSE_OR_POP: - case JUMP_IF_TRUE_OR_POP: - cnt = get_const_value(inst->i_opcode, oparg, consts); - if (cnt == NULL) { - goto error; - } - is_true = PyObject_IsTrue(cnt); - Py_DECREF(cnt); - if (is_true == -1) { - goto error; - } - jump_if_true = nextop == JUMP_IF_TRUE_OR_POP; - if (is_true == jump_if_true) { - bb->b_instr[i+1].i_opcode = JUMP; - bb->b_nofallthrough = 1; - } - else { - inst->i_opcode = NOP; - bb->b_instr[i+1].i_opcode = NOP; - } - break; - case IS_OP: - cnt = get_const_value(inst->i_opcode, oparg, consts); - if (cnt == NULL) { - goto error; - } - int jump_op = i+2 < bb->b_iused ? bb->b_instr[i+2].i_opcode : 0; - if (Py_IsNone(cnt) && (jump_op == POP_JUMP_IF_FALSE || jump_op == POP_JUMP_IF_TRUE)) { - unsigned char nextarg = bb->b_instr[i+1].i_oparg; - inst->i_opcode = NOP; - bb->b_instr[i+1].i_opcode = NOP; - bb->b_instr[i+2].i_opcode = nextarg ^ (jump_op == POP_JUMP_IF_FALSE) ? - POP_JUMP_IF_NOT_NONE : POP_JUMP_IF_NONE; - } - Py_DECREF(cnt); - break; - } - break; - } - - /* Try to fold tuples of constants. - Skip over BUILD_TUPLE(1) UNPACK_SEQUENCE(1). - Replace BUILD_TUPLE(2) UNPACK_SEQUENCE(2) with SWAP(2). - Replace BUILD_TUPLE(3) UNPACK_SEQUENCE(3) with SWAP(3). */ - case BUILD_TUPLE: - if (nextop == UNPACK_SEQUENCE && oparg == bb->b_instr[i+1].i_oparg) { - switch(oparg) { - case 1: - inst->i_opcode = NOP; - bb->b_instr[i+1].i_opcode = NOP; - continue; - case 2: - case 3: - inst->i_opcode = NOP; - bb->b_instr[i+1].i_opcode = SWAP; - continue; - } - } - if (i >= oparg) { - if (fold_tuple_on_constants(c, inst-oparg, oparg, consts)) { - goto error; - } - } - break; - - /* Simplify conditional jump to conditional jump where the - result of the first test implies the success of a similar - test or the failure of the opposite test. - Arises in code like: - "a and b or c" - "(a and b) and c" - "(a or b) or c" - "(a or b) and c" - x:JUMP_IF_FALSE_OR_POP y y:JUMP_IF_FALSE_OR_POP z - --> x:JUMP_IF_FALSE_OR_POP z - x:JUMP_IF_FALSE_OR_POP y y:JUMP_IF_TRUE_OR_POP z - --> x:POP_JUMP_IF_FALSE y+1 - where y+1 is the instruction following the second test. - */ - case JUMP_IF_FALSE_OR_POP: - switch (target->i_opcode) { - case POP_JUMP_IF_FALSE: - i -= jump_thread(inst, target, POP_JUMP_IF_FALSE); - break; - case JUMP: - case JUMP_IF_FALSE_OR_POP: - i -= jump_thread(inst, target, JUMP_IF_FALSE_OR_POP); - break; - case JUMP_IF_TRUE_OR_POP: - case POP_JUMP_IF_TRUE: - if (inst->i_lineno == target->i_lineno) { - // We don't need to bother checking for loops here, - // since a block's b_next cannot point to itself: - assert(inst->i_target != inst->i_target->b_next); - inst->i_opcode = POP_JUMP_IF_FALSE; - inst->i_target = inst->i_target->b_next; - --i; - } - break; - } - break; - case JUMP_IF_TRUE_OR_POP: - switch (target->i_opcode) { - case POP_JUMP_IF_TRUE: - i -= jump_thread(inst, target, POP_JUMP_IF_TRUE); - break; - case JUMP: - case JUMP_IF_TRUE_OR_POP: - i -= jump_thread(inst, target, JUMP_IF_TRUE_OR_POP); - break; - case JUMP_IF_FALSE_OR_POP: - case POP_JUMP_IF_FALSE: - if (inst->i_lineno == target->i_lineno) { - // We don't need to bother checking for loops here, - // since a block's b_next cannot point to itself: - assert(inst->i_target != inst->i_target->b_next); - inst->i_opcode = POP_JUMP_IF_TRUE; - inst->i_target = inst->i_target->b_next; - --i; - } - break; - } - break; - case POP_JUMP_IF_NOT_NONE: - case POP_JUMP_IF_NONE: - switch (target->i_opcode) { - case JUMP: - i -= jump_thread(inst, target, inst->i_opcode); - } - break; - case POP_JUMP_IF_FALSE: - switch (target->i_opcode) { - case JUMP: - i -= jump_thread(inst, target, POP_JUMP_IF_FALSE); - } - break; - case POP_JUMP_IF_TRUE: - switch (target->i_opcode) { - case JUMP: - i -= jump_thread(inst, target, POP_JUMP_IF_TRUE); - } - break; - case JUMP: - switch (target->i_opcode) { - case JUMP: - i -= jump_thread(inst, target, JUMP); - } - break; - case FOR_ITER: - if (target->i_opcode == JUMP) { - /* This will not work now because the jump (at target) could - * be forward or backward and FOR_ITER only jumps forward. We - * can re-enable this if ever we implement a backward version - * of FOR_ITER. - */ - /* - i -= jump_thread(inst, target, FOR_ITER); - */ - } - break; - case SWAP: - if (oparg == 1) { - inst->i_opcode = NOP; - break; - } - if (swaptimize(bb, &i)) { - goto error; - } - apply_static_swaps(bb, i); - break; - case KW_NAMES: - break; - case PUSH_NULL: - if (nextop == LOAD_GLOBAL && (inst[1].i_opcode & 1) == 0) { - inst->i_opcode = NOP; - inst->i_oparg = 0; - inst[1].i_oparg |= 1; - } - break; - default: - /* All HAS_CONST opcodes should be handled with LOAD_CONST */ - assert (!HAS_CONST(inst->i_opcode)); - } - } - return 0; error: - return -1; -} - -static bool -basicblock_has_lineno(const basicblock *bb) { - for (int i = 0; i < bb->b_iused; i++) { - if (bb->b_instr[i].i_lineno > 0) { - return true; - } - } - return false; -} - -/* If this block ends with an unconditional jump to an exit block, - * then remove the jump and extend this block with the target. - */ -static int -extend_block(basicblock *bb) { - if (bb->b_iused == 0) { - return 0; - } - struct instr *last = &bb->b_instr[bb->b_iused-1]; - if (last->i_opcode != JUMP && - last->i_opcode != JUMP_FORWARD && - last->i_opcode != JUMP_BACKWARD) { - return 0; - } - if (last->i_target->b_exit && last->i_target->b_iused <= MAX_COPY_SIZE) { - basicblock *to_copy = last->i_target; - if (basicblock_has_lineno(to_copy)) { - /* copy only blocks without line number (like implicit 'return None's) */ - return 0; - } - last->i_opcode = NOP; - for (int i = 0; i < to_copy->b_iused; i++) { - int index = compiler_next_instr(bb); - if (index < 0) { - return -1; - } - bb->b_instr[index] = to_copy->b_instr[i]; - } - bb->b_exit = 1; - } - return 0; -} - -static void -clean_basic_block(basicblock *bb) { - /* Remove NOPs when legal to do so. */ - int dest = 0; - int prev_lineno = -1; - for (int src = 0; src < bb->b_iused; src++) { - int lineno = bb->b_instr[src].i_lineno; - if (bb->b_instr[src].i_opcode == NOP) { - /* Eliminate no-op if it doesn't have a line number */ - if (lineno < 0) { - continue; - } - /* or, if the previous instruction had the same line number. */ - if (prev_lineno == lineno) { - continue; - } - /* or, if the next instruction has same line number or no line number */ - if (src < bb->b_iused - 1) { - int next_lineno = bb->b_instr[src+1].i_lineno; - if (next_lineno == lineno) { - continue; - } - if (next_lineno < 0) { - COPY_INSTR_LOC(bb->b_instr[src], bb->b_instr[src+1]); - continue; - } - } - else { - basicblock* next = bb->b_next; - while (next && next->b_iused == 0) { - next = next->b_next; - } - /* or if last instruction in BB and next BB has same line number */ - if (next) { - if (lineno == next->b_instr[0].i_lineno) { - continue; - } - } - } - - } - if (dest != src) { - bb->b_instr[dest] = bb->b_instr[src]; - } - dest++; - prev_lineno = lineno; - } - assert(dest <= bb->b_iused); - bb->b_iused = dest; -} - -static int -normalize_basic_block(basicblock *bb) { - /* Mark blocks as exit and/or nofallthrough. - Raise SystemError if CFG is malformed. */ - for (int i = 0; i < bb->b_iused; i++) { - assert(!IS_ASSEMBLER_OPCODE(bb->b_instr[i].i_opcode)); - switch(bb->b_instr[i].i_opcode) { - case RETURN_VALUE: - case RAISE_VARARGS: - case RERAISE: - bb->b_exit = 1; - bb->b_nofallthrough = 1; - break; - case JUMP: - case JUMP_NO_INTERRUPT: - bb->b_nofallthrough = 1; - /* fall through */ - case POP_JUMP_IF_NOT_NONE: - case POP_JUMP_IF_NONE: - case POP_JUMP_IF_FALSE: - case POP_JUMP_IF_TRUE: - case JUMP_IF_FALSE_OR_POP: - case JUMP_IF_TRUE_OR_POP: - case FOR_ITER: - if (i != bb->b_iused-1) { - PyErr_SetString(PyExc_SystemError, "malformed control flow graph."); - return -1; - } - /* Skip over empty basic blocks. */ - while (bb->b_instr[i].i_target->b_iused == 0) { - bb->b_instr[i].i_target = bb->b_instr[i].i_target->b_next; - } - - } - } - return 0; -} - -static int -mark_reachable(struct assembler *a) { - basicblock **stack, **sp; - sp = stack = (basicblock **)PyObject_Malloc(sizeof(basicblock *) * a->a_nblocks); - if (stack == NULL) { - return -1; - } - a->a_entry->b_predecessors = 1; - *sp++ = a->a_entry; - while (sp > stack) { - basicblock *b = *(--sp); - if (b->b_next && !b->b_nofallthrough) { - if (b->b_next->b_predecessors == 0) { - *sp++ = b->b_next; - } - b->b_next->b_predecessors++; - } - for (int i = 0; i < b->b_iused; i++) { - basicblock *target; - struct instr *instr = &b->b_instr[i]; - if (is_jump(instr) || is_block_push(instr)) { - target = instr->i_target; - if (target->b_predecessors == 0) { - *sp++ = target; - } - target->b_predecessors++; - } - } - } - PyObject_Free(stack); - return 0; -} - -static void -eliminate_empty_basic_blocks(basicblock *entry) { - /* Eliminate empty blocks */ - for (basicblock *b = entry; b != NULL; b = b->b_next) { - basicblock *next = b->b_next; - if (next) { - while (next->b_iused == 0 && next->b_next) { - next = next->b_next; - } - b->b_next = next; - } - } - for (basicblock *b = entry; b != NULL; b = b->b_next) { - if (b->b_iused == 0) { - continue; - } - if (is_jump(&b->b_instr[b->b_iused-1])) { - basicblock *target = b->b_instr[b->b_iused-1].i_target; - while (target->b_iused == 0) { - target = target->b_next; - } - b->b_instr[b->b_iused-1].i_target = target; - } - } -} - - -/* If an instruction has no line number, but it's predecessor in the BB does, - * then copy the line number. If a successor block has no line number, and only - * one predecessor, then inherit the line number. - * This ensures that all exit blocks (with one predecessor) receive a line number. - * Also reduces the size of the line number table, - * but has no impact on the generated line number events. - */ -static void -propagate_line_numbers(struct assembler *a) { - for (basicblock *b = a->a_entry; b != NULL; b = b->b_next) { - if (b->b_iused == 0) { - continue; - } - - // Not a real instruction, only to store positions - // from previous instructions and propagate them. - struct instr prev_instr = { - .i_lineno = -1, - .i_col_offset = -1, - .i_end_lineno = -1, - .i_end_col_offset = -1, - }; - for (int i = 0; i < b->b_iused; i++) { - if (b->b_instr[i].i_lineno < 0) { - COPY_INSTR_LOC(prev_instr, b->b_instr[i]); - } - else { - COPY_INSTR_LOC(b->b_instr[i], prev_instr); - } - } - if (!b->b_nofallthrough && b->b_next->b_predecessors == 1) { - assert(b->b_next->b_iused); - if (b->b_next->b_instr[0].i_lineno < 0) { - COPY_INSTR_LOC(prev_instr, b->b_next->b_instr[0]); - } - } - if (is_jump(&b->b_instr[b->b_iused-1])) { - basicblock *target = b->b_instr[b->b_iused-1].i_target; - if (target->b_predecessors == 1) { - if (target->b_instr[0].i_lineno < 0) { - COPY_INSTR_LOC(prev_instr, target->b_instr[0]); - } - } - } - } -} - -/* Perform optimizations on a control flow graph. - The consts object should still be in list form to allow new constants - to be appended. - - All transformations keep the code size the same or smaller. - For those that reduce size, the gaps are initially filled with - NOPs. Later those NOPs are removed. -*/ - -static int -optimize_cfg(struct compiler *c, struct assembler *a, PyObject *consts) -{ - for (basicblock *b = a->a_entry; b != NULL; b = b->b_next) { - if (optimize_basic_block(c, b, consts)) { - return -1; - } - clean_basic_block(b); - assert(b->b_predecessors == 0); - } - for (basicblock *b = c->u->u_blocks; b != NULL; b = b->b_list) { - if (extend_block(b)) { - return -1; - } - } - if (mark_reachable(a)) { - return -1; - } - /* Delete unreachable instructions */ - for (basicblock *b = a->a_entry; b != NULL; b = b->b_next) { - if (b->b_predecessors == 0) { - b->b_iused = 0; - b->b_nofallthrough = 0; - } - } - eliminate_empty_basic_blocks(a->a_entry); - for (basicblock *b = a->a_entry; b != NULL; b = b->b_next) { - clean_basic_block(b); - } - /* Delete jump instructions made redundant by previous step. If a non-empty - block ends with a jump instruction, check if the next non-empty block - reached through normal flow control is the target of that jump. If it - is, then the jump instruction is redundant and can be deleted. - */ - int maybe_empty_blocks = 0; - for (basicblock *b = a->a_entry; b != NULL; b = b->b_next) { - if (b->b_iused > 0) { - struct instr *b_last_instr = &b->b_instr[b->b_iused - 1]; - assert(!IS_ASSEMBLER_OPCODE(b_last_instr->i_opcode)); - if (b_last_instr->i_opcode == JUMP || - b_last_instr->i_opcode == JUMP_NO_INTERRUPT) { - if (b_last_instr->i_target == b->b_next) { - assert(b->b_next->b_iused); - b->b_nofallthrough = 0; - b_last_instr->i_opcode = NOP; - maybe_empty_blocks = 1; - } - } - } - } - if (maybe_empty_blocks) { - eliminate_empty_basic_blocks(a->a_entry); - } - return 0; -} - -// Remove trailing unused constants. -static int -trim_unused_consts(struct compiler *c, struct assembler *a, PyObject *consts) -{ - assert(PyList_CheckExact(consts)); - - // The first constant may be docstring; keep it always. - int max_const_index = 0; - for (basicblock *b = a->a_entry; b != NULL; b = b->b_next) { - for (int i = 0; i < b->b_iused; i++) { - if ((b->b_instr[i].i_opcode == LOAD_CONST || - b->b_instr[i].i_opcode == KW_NAMES) && - b->b_instr[i].i_oparg > max_const_index) { - max_const_index = b->b_instr[i].i_oparg; - } - } - } - if (max_const_index+1 < PyList_GET_SIZE(consts)) { - //fprintf(stderr, "removing trailing consts: max=%d, size=%d\n", - // max_const_index, (int)PyList_GET_SIZE(consts)); - if (PyList_SetSlice(consts, max_const_index+1, - PyList_GET_SIZE(consts), NULL) < 0) { - return 1; - } - } - return 0; -} - -static inline int -is_exit_without_lineno(basicblock *b) { - if (!b->b_exit) { - return 0; - } - for (int i = 0; i < b->b_iused; i++) { - if (b->b_instr[i].i_lineno >= 0) { - return 0; - } - } - return 1; -} - -/* PEP 626 mandates that the f_lineno of a frame is correct - * after a frame terminates. It would be prohibitively expensive - * to continuously update the f_lineno field at runtime, - * so we make sure that all exiting instruction (raises and returns) - * have a valid line number, allowing us to compute f_lineno lazily. - * We can do this by duplicating the exit blocks without line number - * so that none have more than one predecessor. We can then safely - * copy the line number from the sole predecessor block. - */ -static int -duplicate_exits_without_lineno(struct compiler *c) -{ - /* Copy all exit blocks without line number that are targets of a jump. - */ - for (basicblock *b = c->u->u_blocks; b != NULL; b = b->b_list) { - if (b->b_iused > 0 && is_jump(&b->b_instr[b->b_iused-1])) { - basicblock *target = b->b_instr[b->b_iused-1].i_target; - if (is_exit_without_lineno(target) && target->b_predecessors > 1) { - basicblock *new_target = compiler_copy_block(c, target); - if (new_target == NULL) { - return -1; - } - COPY_INSTR_LOC(b->b_instr[b->b_iused-1], new_target->b_instr[0]); - b->b_instr[b->b_iused-1].i_target = new_target; - target->b_predecessors--; - new_target->b_predecessors = 1; - new_target->b_next = target->b_next; - target->b_next = new_target; - } - } - } - /* Eliminate empty blocks */ - for (basicblock *b = c->u->u_blocks; b != NULL; b = b->b_list) { - while (b->b_next && b->b_next->b_iused == 0) { - b->b_next = b->b_next->b_next; - } - } - /* Any remaining reachable exit blocks without line number can only be reached by - * fall through, and thus can only have a single predecessor */ - for (basicblock *b = c->u->u_blocks; b != NULL; b = b->b_list) { - if (!b->b_nofallthrough && b->b_next && b->b_iused > 0) { - if (is_exit_without_lineno(b->b_next)) { - assert(b->b_next->b_iused > 0); - COPY_INSTR_LOC(b->b_instr[b->b_iused-1], b->b_next->b_instr[0]); - } - } - } - return 0; + Py_DECREF(const_cache); + _PyCfgBuilder_Fini(&g); + instr_sequence_fini(&optimized_instrs); + return co; } /* Retained for API compatibility. - * Optimization is now done in optimize_cfg */ + * Optimization is now done in _PyCfg_OptimizeCodeUnit */ PyObject * PyCode_Optimize(PyObject *code, PyObject* Py_UNUSED(consts), PyObject *Py_UNUSED(names), PyObject *Py_UNUSED(lnotab_obj)) { - Py_INCREF(code); - return code; + return Py_NewRef(code); } diff --git a/Python/condvar.h b/Python/condvar.h index e5df7ff1..4ddc5311 100644 --- a/Python/condvar.h +++ b/Python/condvar.h @@ -68,9 +68,9 @@ void _PyThread_cond_after(long long us, struct timespec *abs); Py_LOCAL_INLINE(int) PyCOND_TIMEDWAIT(PyCOND_T *cond, PyMUTEX_T *mut, long long us) { - struct timespec abs; - _PyThread_cond_after(us, &abs); - int ret = pthread_cond_timedwait(cond, mut, &abs); + struct timespec abs_timeout; + _PyThread_cond_after(us, &abs_timeout); + int ret = pthread_cond_timedwait(cond, mut, &abs_timeout); if (ret == ETIMEDOUT) { return 1; } diff --git a/Python/context.c b/Python/context.c index ef9db6a9..1ffae987 100644 --- a/Python/context.c +++ b/Python/context.c @@ -124,8 +124,7 @@ _PyContext_Enter(PyThreadState *ts, PyObject *octx) ctx->ctx_prev = (PyContext *)ts->context; /* borrow */ ctx->ctx_entered = 1; - Py_INCREF(ctx); - ts->context = (PyObject *)ctx; + ts->context = Py_NewRef(ctx); ts->context_ver++; return 0; @@ -400,8 +399,7 @@ context_new_from_vars(PyHamtObject *vars) return NULL; } - Py_INCREF(vars); - ctx->ctx_vars = vars; + ctx->ctx_vars = (PyHamtObject*)Py_NewRef(vars); _PyObject_GC_TRACK(ctx); return ctx; @@ -546,8 +544,7 @@ context_tp_subscript(PyContext *self, PyObject *key) PyErr_SetObject(PyExc_KeyError, key); return NULL; } - Py_INCREF(val); - return val; + return Py_NewRef(val); } static int @@ -588,11 +585,9 @@ _contextvars_Context_get_impl(PyContext *self, PyObject *key, return NULL; } if (found == 0) { - Py_INCREF(default_value); - return default_value; + return Py_NewRef(default_value); } - Py_INCREF(val); - return val; + return Py_NewRef(val); } @@ -831,11 +826,9 @@ contextvar_new(PyObject *name, PyObject *def) return NULL; } - Py_INCREF(name); - var->var_name = name; + var->var_name = Py_NewRef(name); - Py_XINCREF(def); - var->var_default = def; + var->var_default = Py_XNewRef(def); var->var_cached = NULL; var->var_cached_tsid = 0; @@ -1176,8 +1169,7 @@ error: static PyObject * token_get_var(PyContextToken *self, void *Py_UNUSED(ignored)) { - Py_INCREF(self->tok_var); - return (PyObject *)self->tok_var; + return Py_NewRef(self->tok_var);; } static PyObject * @@ -1187,8 +1179,7 @@ token_get_old_value(PyContextToken *self, void *Py_UNUSED(ignored)) return get_token_missing(); } - Py_INCREF(self->tok_oldval); - return self->tok_oldval; + return Py_NewRef(self->tok_oldval); } static PyGetSetDef PyContextTokenType_getsetlist[] = { @@ -1228,14 +1219,11 @@ token_new(PyContext *ctx, PyContextVar *var, PyObject *val) return NULL; } - Py_INCREF(ctx); - tok->tok_ctx = ctx; + tok->tok_ctx = (PyContext*)Py_NewRef(ctx); - Py_INCREF(var); - tok->tok_var = var; + tok->tok_var = (PyContextVar*)Py_NewRef(var); - Py_XINCREF(val); - tok->tok_oldval = val; + tok->tok_oldval = Py_XNewRef(val); tok->tok_used = 0; @@ -1247,25 +1235,29 @@ token_new(PyContext *ctx, PyContextVar *var, PyObject *val) /////////////////////////// Token.MISSING -static PyObject *_token_missing; - - -typedef struct { - PyObject_HEAD -} PyContextTokenMissing; - - static PyObject * context_token_missing_tp_repr(PyObject *self) { return PyUnicode_FromString("<Token.MISSING>"); } +static void +context_token_missing_tp_dealloc(_PyContextTokenMissing *Py_UNUSED(self)) +{ +#ifdef Py_DEBUG + /* The singleton is statically allocated. */ + _Py_FatalRefcountError("deallocating the token missing singleton"); +#else + return; +#endif +} + PyTypeObject _PyContextTokenMissing_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "Token.MISSING", - sizeof(PyContextTokenMissing), + sizeof(_PyContextTokenMissing), + .tp_dealloc = (destructor)context_token_missing_tp_dealloc, .tp_getattro = PyObject_GenericGetAttr, .tp_flags = Py_TPFLAGS_DEFAULT, .tp_repr = context_token_missing_tp_repr, @@ -1275,19 +1267,7 @@ PyTypeObject _PyContextTokenMissing_Type = { static PyObject * get_token_missing(void) { - if (_token_missing != NULL) { - Py_INCREF(_token_missing); - return _token_missing; - } - - _token_missing = (PyObject *)PyObject_New( - PyContextTokenMissing, &_PyContextTokenMissing_Type); - if (_token_missing == NULL) { - return NULL; - } - - Py_INCREF(_token_missing); - return _token_missing; + return Py_NewRef(&_Py_SINGLETON(context_token_missing)); } @@ -1312,15 +1292,11 @@ _PyContext_ClearFreeList(PyInterpreterState *interp) void _PyContext_Fini(PyInterpreterState *interp) { - if (_Py_IsMainInterpreter(interp)) { - Py_CLEAR(_token_missing); - } _PyContext_ClearFreeList(interp); #if defined(Py_DEBUG) && PyContext_MAXFREELIST > 0 struct _Py_context_state *state = &interp->context; state->numfree = -1; #endif - _PyHamt_Fini(interp); } @@ -1333,7 +1309,7 @@ _PyContext_Init(PyInterpreterState *interp) PyObject *missing = get_token_missing(); if (PyDict_SetItemString( - PyContextToken_Type.tp_dict, "MISSING", missing)) + _PyType_GetDict(&PyContextToken_Type), "MISSING", missing)) { Py_DECREF(missing); return _PyStatus_ERR("can't init context types"); diff --git a/Python/deepfreeze/README.txt b/Python/deepfreeze/README.txt index da55d4e7..276ab511 100644 --- a/Python/deepfreeze/README.txt +++ b/Python/deepfreeze/README.txt @@ -3,4 +3,4 @@ modules. Python/frozen.c depends on these files. None of these files are committed into the repo. -See Tools/scripts/freeze_modules.py for more info. +See Tools/build/freeze_modules.py for more info. diff --git a/Python/dtoa.c b/Python/dtoa.c index 733e70bc..c5e343b8 100644 --- a/Python/dtoa.c +++ b/Python/dtoa.c @@ -119,6 +119,7 @@ #include "Python.h" #include "pycore_dtoa.h" // _PY_SHORT_FLOAT_REPR +#include "pycore_pystate.h" // _PyInterpreterState_GET() #include <stdlib.h> // exit() /* if _PY_SHORT_FLOAT_REPR == 0, then don't even try to compile @@ -156,7 +157,7 @@ #endif -typedef uint32_t ULong; +// ULong is defined in pycore_dtoa.h. typedef int32_t Long; typedef uint64_t ULLong; @@ -171,12 +172,6 @@ typedef uint64_t ULLong; #define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);} #endif -#ifndef PRIVATE_MEM -#define PRIVATE_MEM 2304 -#endif -#define PRIVATE_mem ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double)) -static double private_mem[PRIVATE_mem], *pmem_next = private_mem; - #ifdef __cplusplus extern "C" { #endif @@ -278,11 +273,6 @@ typedef union { double d; ULong L[2]; } U; #define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1)) #define Big1 0xffffffff -/* Standard NaN used by _Py_dg_stdnan. */ - -#define NAN_WORD0 0x7ff80000 -#define NAN_WORD1 0 - /* Bits of the representation of positive infinity. */ #define POSINF_WORD0 0x7ff00000 @@ -298,8 +288,6 @@ BCinfo { #define FFFFFFFF 0xffffffffUL -#define Kmax 7 - /* struct Bigint is used to represent arbitrary-precision integers. These integers are stored in sign-magnitude format, with the magnitude stored as an array of base 2**32 digits. Bigints are always normalized: if x is a @@ -322,13 +310,7 @@ BCinfo { significant (x[0]) to most significant (x[wds-1]). */ -struct -Bigint { - struct Bigint *next; - int k, maxwds, sign, wds; - ULong x[1]; -}; - +// struct Bigint is defined in pycore_dtoa.h. typedef struct Bigint Bigint; #ifndef Py_USING_MEMORY_DEBUGGER @@ -352,7 +334,9 @@ typedef struct Bigint Bigint; Bfree to PyMem_Free. Investigate whether this has any significant performance on impact. */ -static Bigint *freelist[Kmax+1]; +#define freelist interp->dtoa.freelist +#define private_mem interp->dtoa.preallocated +#define pmem_next interp->dtoa.preallocated_next /* Allocate space for a Bigint with up to 1<<k digits */ @@ -362,14 +346,17 @@ Balloc(int k) int x; Bigint *rv; unsigned int len; + PyInterpreterState *interp = _PyInterpreterState_GET(); - if (k <= Kmax && (rv = freelist[k])) + if (k <= Bigint_Kmax && (rv = freelist[k])) freelist[k] = rv->next; else { x = 1 << k; len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1) /sizeof(double); - if (k <= Kmax && pmem_next - private_mem + len <= (Py_ssize_t)PRIVATE_mem) { + if (k <= Bigint_Kmax && + pmem_next - private_mem + len <= (Py_ssize_t)Bigint_PREALLOC_SIZE + ) { rv = (Bigint*)pmem_next; pmem_next += len; } @@ -391,15 +378,20 @@ static void Bfree(Bigint *v) { if (v) { - if (v->k > Kmax) + if (v->k > Bigint_Kmax) FREE((void*)v); else { + PyInterpreterState *interp = _PyInterpreterState_GET(); v->next = freelist[v->k]; freelist[v->k] = v; } } } +#undef pmem_next +#undef private_mem +#undef freelist + #else /* Alternative versions of Balloc and Bfree that use PyMem_Malloc and @@ -678,10 +670,6 @@ mult(Bigint *a, Bigint *b) #ifndef Py_USING_MEMORY_DEBUGGER -/* p5s is a linked list of powers of 5 of the form 5**(2**i), i >= 2 */ - -static Bigint *p5s; - /* multiply the Bigint b by 5**k. Returns a pointer to the result, or NULL on failure; if the returned pointer is distinct from b then the original Bigint b will have been Bfree'd. Ignores the sign of b. */ @@ -701,7 +689,8 @@ pow5mult(Bigint *b, int k) if (!(k >>= 2)) return b; - p5 = p5s; + PyInterpreterState *interp = _PyInterpreterState_GET(); + p5 = interp->dtoa.p5s; if (!p5) { /* first time */ p5 = i2b(625); @@ -709,7 +698,7 @@ pow5mult(Bigint *b, int k) Bfree(b); return NULL; } - p5s = p5; + interp->dtoa.p5s = p5; p5->next = 0; } for(;;) { @@ -1405,35 +1394,6 @@ bigcomp(U *rv, const char *s0, BCinfo *bc) return 0; } -/* Return a 'standard' NaN value. - - There are exactly two quiet NaNs that don't arise by 'quieting' signaling - NaNs (see IEEE 754-2008, section 6.2.1). If sign == 0, return the one whose - sign bit is cleared. Otherwise, return the one whose sign bit is set. -*/ - -double -_Py_dg_stdnan(int sign) -{ - U rv; - word0(&rv) = NAN_WORD0; - word1(&rv) = NAN_WORD1; - if (sign) - word0(&rv) |= Sign_bit; - return dval(&rv); -} - -/* Return positive or negative infinity, according to the given sign (0 for - * positive infinity, 1 for negative infinity). */ - -double -_Py_dg_infinity(int sign) -{ - U rv; - word0(&rv) = POSINF_WORD0; - word1(&rv) = POSINF_WORD1; - return sign ? -dval(&rv) : dval(&rv); -} double _Py_dg_strtod(const char *s00, char **se) diff --git a/Python/dynload_shlib.c b/Python/dynload_shlib.c index 3c5fd83d..6761bba4 100644 --- a/Python/dynload_shlib.c +++ b/Python/dynload_shlib.c @@ -75,7 +75,7 @@ _PyImport_FindSharedFuncptr(const char *prefix, return NULL; } - dlopenflags = _PyInterpreterState_GET()->dlopenflags; + dlopenflags = _PyImport_GetDLOpenFlags(_PyInterpreterState_GET()); handle = dlopen(pathname, dlopenflags); diff --git a/Python/dynload_win.c b/Python/dynload_win.c index b43e9fc2..acab05e2 100644 --- a/Python/dynload_win.c +++ b/Python/dynload_win.c @@ -125,14 +125,15 @@ static char *GetPythonImport (HINSTANCE hModule) !strncmp(import_name,"python",6)) { char *pch; -#ifndef _DEBUG - /* In a release version, don't claim that python3.dll is - a Python DLL. */ + /* Don't claim that python3.dll is a Python DLL. */ +#ifdef _DEBUG + if (strcmp(import_name, "python3_d.dll") == 0) { +#else if (strcmp(import_name, "python3.dll") == 0) { +#endif import_data += 20; continue; } -#endif /* Ensure python prefix is followed only by numbers to the end of the basename */ @@ -162,6 +163,7 @@ static char *GetPythonImport (HINSTANCE hModule) return NULL; } +#ifdef Py_ENABLE_SHARED /* Load python3.dll before loading any extension module that might refer to it. That way, we can be sure that always the python3.dll corresponding to this python DLL is loaded, not a python3.dll that might be on the path @@ -215,6 +217,7 @@ _Py_CheckPython3(void) return hPython3 != NULL; #undef MAXPATHLEN } +#endif /* Py_ENABLE_SHARED */ dl_funcptr _PyImport_FindSharedFuncptrWindows(const char *prefix, const char *shortname, @@ -223,13 +226,11 @@ dl_funcptr _PyImport_FindSharedFuncptrWindows(const char *prefix, dl_funcptr p; char funcname[258], *import_python; +#ifdef Py_ENABLE_SHARED _Py_CheckPython3(); +#endif /* Py_ENABLE_SHARED */ -#if USE_UNICODE_WCHAR_CACHE - const wchar_t *wpathname = _PyUnicode_AsUnicode(pathname); -#else /* USE_UNICODE_WCHAR_CACHE */ wchar_t *wpathname = PyUnicode_AsWideCharString(pathname, NULL); -#endif /* USE_UNICODE_WCHAR_CACHE */ if (wpathname == NULL) return NULL; @@ -237,10 +238,12 @@ dl_funcptr _PyImport_FindSharedFuncptrWindows(const char *prefix, { HINSTANCE hDLL = NULL; +#ifdef MS_WINDOWS_DESKTOP unsigned int old_mode; /* Don't display a message box when Python can't load a DLL */ old_mode = SetErrorMode(SEM_FAILCRITICALERRORS); +#endif /* bpo-36085: We use LoadLibraryEx with restricted search paths to avoid DLL preloading attacks and enable use of the @@ -251,12 +254,12 @@ dl_funcptr _PyImport_FindSharedFuncptrWindows(const char *prefix, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR); Py_END_ALLOW_THREADS -#if !USE_UNICODE_WCHAR_CACHE PyMem_Free(wpathname); -#endif /* USE_UNICODE_WCHAR_CACHE */ +#ifdef MS_WINDOWS_DESKTOP /* restore old error mode settings */ SetErrorMode(old_mode); +#endif if (hDLL==NULL){ PyObject *message; diff --git a/Python/errors.c b/Python/errors.c index 3eb8a5ef..6c46d1f2 100644 --- a/Python/errors.c +++ b/Python/errors.c @@ -6,7 +6,7 @@ #include "pycore_initconfig.h" // _PyStatus_ERR() #include "pycore_pyerrors.h" // _PyErr_Format() #include "pycore_pystate.h" // _PyThreadState_GET() -#include "pycore_structseq.h" // _PyStructSequence_FiniType() +#include "pycore_structseq.h" // _PyStructSequence_FiniBuiltin() #include "pycore_sysmodule.h" // _PySys_Audit() #include "pycore_traceback.h" // _PyTraceBack_FromFrame() @@ -27,33 +27,84 @@ static PyObject * _PyErr_FormatV(PyThreadState *tstate, PyObject *exception, const char *format, va_list vargs); - void -_PyErr_Restore(PyThreadState *tstate, PyObject *type, PyObject *value, - PyObject *traceback) +_PyErr_SetRaisedException(PyThreadState *tstate, PyObject *exc) { - PyObject *oldtype, *oldvalue, *oldtraceback; + PyObject *old_exc = tstate->current_exception; + tstate->current_exception = exc; + Py_XDECREF(old_exc); +} - if (traceback != NULL && !PyTraceBack_Check(traceback)) { - /* XXX Should never happen -- fatal error instead? */ - /* Well, it could be None. */ - Py_DECREF(traceback); - traceback = NULL; +static PyObject* +_PyErr_CreateException(PyObject *exception_type, PyObject *value) +{ + PyObject *exc; + + if (value == NULL || value == Py_None) { + exc = _PyObject_CallNoArgs(exception_type); + } + else if (PyTuple_Check(value)) { + exc = PyObject_Call(exception_type, value, NULL); + } + else { + exc = PyObject_CallOneArg(exception_type, value); } - /* Save these in locals to safeguard against recursive - invocation through Py_XDECREF */ - oldtype = tstate->curexc_type; - oldvalue = tstate->curexc_value; - oldtraceback = tstate->curexc_traceback; + if (exc != NULL && !PyExceptionInstance_Check(exc)) { + PyErr_Format(PyExc_TypeError, + "calling %R should have returned an instance of " + "BaseException, not %s", + exception_type, Py_TYPE(exc)->tp_name); + Py_CLEAR(exc); + } - tstate->curexc_type = type; - tstate->curexc_value = value; - tstate->curexc_traceback = traceback; + return exc; +} - Py_XDECREF(oldtype); - Py_XDECREF(oldvalue); - Py_XDECREF(oldtraceback); +void +_PyErr_Restore(PyThreadState *tstate, PyObject *type, PyObject *value, + PyObject *traceback) +{ + if (type == NULL) { + assert(value == NULL); + assert(traceback == NULL); + _PyErr_SetRaisedException(tstate, NULL); + return; + } + assert(PyExceptionClass_Check(type)); + if (value != NULL && type == (PyObject *)Py_TYPE(value)) { + /* Already normalized */ + assert(((PyBaseExceptionObject *)value)->traceback != Py_None); + } + else { + PyObject *exc = _PyErr_CreateException(type, value); + Py_XDECREF(value); + if (exc == NULL) { + Py_DECREF(type); + Py_XDECREF(traceback); + return; + } + value = exc; + } + assert(PyExceptionInstance_Check(value)); + if (traceback != NULL && !PyTraceBack_Check(traceback)) { + if (traceback == Py_None) { + Py_DECREF(Py_None); + traceback = NULL; + } + else { + PyErr_SetString(PyExc_TypeError, "traceback must be a Traceback or None"); + Py_XDECREF(value); + Py_DECREF(type); + Py_XDECREF(traceback); + return; + } + } + PyObject *old_traceback = ((PyBaseExceptionObject *)value)->traceback; + ((PyBaseExceptionObject *)value)->traceback = traceback; + Py_XDECREF(old_traceback); + _PyErr_SetRaisedException(tstate, value); + Py_DECREF(type); } void @@ -63,6 +114,12 @@ PyErr_Restore(PyObject *type, PyObject *value, PyObject *traceback) _PyErr_Restore(tstate, type, value, traceback); } +void +PyErr_SetRaisedException(PyObject *exc) +{ + PyThreadState *tstate = _PyThreadState_GET(); + _PyErr_SetRaisedException(tstate, exc); +} _PyErr_StackItem * _PyErr_GetTopmostException(PyThreadState *tstate) @@ -78,30 +135,26 @@ _PyErr_GetTopmostException(PyThreadState *tstate) return exc_info; } -static PyObject* -_PyErr_CreateException(PyObject *exception_type, PyObject *value) +static PyObject * +get_normalization_failure_note(PyThreadState *tstate, PyObject *exception, PyObject *value) { - PyObject *exc; - - if (value == NULL || value == Py_None) { - exc = _PyObject_CallNoArgs(exception_type); + PyObject *args = PyObject_Repr(value); + if (args == NULL) { + _PyErr_Clear(tstate); + args = PyUnicode_FromFormat("<unknown>"); } - else if (PyTuple_Check(value)) { - exc = PyObject_Call(exception_type, value, NULL); + PyObject *note; + const char *tpname = ((PyTypeObject*)exception)->tp_name; + if (args == NULL) { + _PyErr_Clear(tstate); + note = PyUnicode_FromFormat("Normalization failed: type=%s", tpname); } else { - exc = PyObject_CallOneArg(exception_type, value); - } - - if (exc != NULL && !PyExceptionInstance_Check(exc)) { - PyErr_Format(PyExc_TypeError, - "calling %R should have returned an instance of " - "BaseException, not %s", - exception_type, Py_TYPE(exc)->tp_name); - Py_CLEAR(exc); + note = PyUnicode_FromFormat("Normalization failed: type=%s args=%S", + tpname, args); + Py_DECREF(args); } - - return exc; + return note; } void @@ -118,30 +171,44 @@ _PyErr_SetObject(PyThreadState *tstate, PyObject *exception, PyObject *value) exception); return; } - + /* Normalize the exception */ + int is_subclass = 0; + if (value != NULL && PyExceptionInstance_Check(value)) { + is_subclass = PyObject_IsSubclass((PyObject *)Py_TYPE(value), exception); + if (is_subclass < 0) { + return; + } + } Py_XINCREF(value); - exc_value = _PyErr_GetTopmostException(tstate)->exc_value; - if (exc_value != NULL && exc_value != Py_None) { - /* Implicit exception chaining */ - Py_INCREF(exc_value); - if (value == NULL || !PyExceptionInstance_Check(value)) { - /* We must normalize the value right now */ - PyObject *fixed_value; + if (!is_subclass) { + /* We must normalize the value right now */ - /* Issue #23571: functions must not be called with an - exception set */ - _PyErr_Clear(tstate); + /* Issue #23571: functions must not be called with an + exception set */ + _PyErr_Clear(tstate); + + PyObject *fixed_value = _PyErr_CreateException(exception, value); + if (fixed_value == NULL) { + PyObject *exc = _PyErr_GetRaisedException(tstate); + assert(PyExceptionInstance_Check(exc)); - fixed_value = _PyErr_CreateException(exception, value); + PyObject *note = get_normalization_failure_note(tstate, exception, value); Py_XDECREF(value); - if (fixed_value == NULL) { - Py_DECREF(exc_value); - return; + if (note != NULL) { + /* ignore errors in _PyException_AddNote - they will be overwritten below */ + _PyException_AddNote(exc, note); + Py_DECREF(note); } - - value = fixed_value; + _PyErr_SetRaisedException(tstate, exc); + return; } + Py_XSETREF(value, fixed_value); + } + exc_value = _PyErr_GetTopmostException(tstate)->exc_value; + if (exc_value != NULL && exc_value != Py_None) { + /* Implicit exception chaining */ + Py_INCREF(exc_value); /* Avoid creating new reference cycles through the context chain, while taking care not to hang on pre-existing ones. @@ -176,10 +243,10 @@ _PyErr_SetObject(PyThreadState *tstate, PyObject *exception, PyObject *value) Py_DECREF(exc_value); } } - if (value != NULL && PyExceptionInstance_Check(value)) + assert(value != NULL); + if (PyExceptionInstance_Check(value)) tb = PyException_GetTraceback(value); - Py_XINCREF(exception); - _PyErr_Restore(tstate, exception, value, tb); + _PyErr_Restore(tstate, Py_NewRef(Py_TYPE(value)), value, tb); } void @@ -225,8 +292,10 @@ _PyErr_SetString(PyThreadState *tstate, PyObject *exception, const char *string) { PyObject *value = PyUnicode_FromString(string); - _PyErr_SetObject(tstate, exception, value); - Py_XDECREF(value); + if (value != NULL) { + _PyErr_SetObject(tstate, exception, value); + Py_DECREF(value); + } } void @@ -326,8 +395,7 @@ _PyErr_NormalizeException(PyThreadState *tstate, PyObject **exc, set to NULL. */ if (!value) { - value = Py_None; - Py_INCREF(value); + value = Py_NewRef(Py_None); } /* Normalize the exception so that if the type is a class, the @@ -355,16 +423,13 @@ _PyErr_NormalizeException(PyThreadState *tstate, PyObject **exc, if (fixed_value == NULL) { goto error; } - Py_DECREF(value); - value = fixed_value; + Py_SETREF(value, fixed_value); } /* If the class of the instance doesn't exactly match the class of the type, believe the instance. */ else if (inclass != type) { - Py_INCREF(inclass); - Py_DECREF(type); - type = inclass; + Py_SETREF(type, Py_NewRef(inclass)); } } *exc = type; @@ -420,17 +485,34 @@ PyErr_NormalizeException(PyObject **exc, PyObject **val, PyObject **tb) } +PyObject * +_PyErr_GetRaisedException(PyThreadState *tstate) { + PyObject *exc = tstate->current_exception; + tstate->current_exception = NULL; + return exc; +} + +PyObject * +PyErr_GetRaisedException(void) +{ + PyThreadState *tstate = _PyThreadState_GET(); + return _PyErr_GetRaisedException(tstate); +} + void _PyErr_Fetch(PyThreadState *tstate, PyObject **p_type, PyObject **p_value, PyObject **p_traceback) { - *p_type = tstate->curexc_type; - *p_value = tstate->curexc_value; - *p_traceback = tstate->curexc_traceback; - - tstate->curexc_type = NULL; - tstate->curexc_value = NULL; - tstate->curexc_traceback = NULL; + PyObject *exc = _PyErr_GetRaisedException(tstate); + *p_value = exc; + if (exc == NULL) { + *p_type = NULL; + *p_traceback = NULL; + } + else { + *p_type = Py_NewRef(Py_TYPE(exc)); + *p_traceback = Py_XNewRef(((PyBaseExceptionObject *)exc)->traceback); + } } @@ -490,13 +572,9 @@ _PyErr_GetExcInfo(PyThreadState *tstate, { _PyErr_StackItem *exc_info = _PyErr_GetTopmostException(tstate); - *p_type = get_exc_type(exc_info->exc_value); - *p_value = exc_info->exc_value; - *p_traceback = get_exc_traceback(exc_info->exc_value); - - Py_XINCREF(*p_type); - Py_XINCREF(*p_value); - Py_XINCREF(*p_traceback); + *p_type = Py_XNewRef(get_exc_type(exc_info->exc_value)); + *p_value = Py_XNewRef(exc_info->exc_value); + *p_traceback = Py_XNewRef(get_exc_traceback(exc_info->exc_value)); } PyObject* @@ -590,23 +668,43 @@ _PyErr_ChainExceptions(PyObject *typ, PyObject *val, PyObject *tb) } if (_PyErr_Occurred(tstate)) { - PyObject *typ2, *val2, *tb2; - _PyErr_Fetch(tstate, &typ2, &val2, &tb2); _PyErr_NormalizeException(tstate, &typ, &val, &tb); if (tb != NULL) { PyException_SetTraceback(val, tb); Py_DECREF(tb); } Py_DECREF(typ); - _PyErr_NormalizeException(tstate, &typ2, &val2, &tb2); - PyException_SetContext(val2, val); - _PyErr_Restore(tstate, typ2, val2, tb2); + PyObject *exc2 = _PyErr_GetRaisedException(tstate); + PyException_SetContext(exc2, val); + _PyErr_SetRaisedException(tstate, exc2); } else { _PyErr_Restore(tstate, typ, val, tb); } } +/* Like PyErr_SetRaisedException(), but if an exception is already set, + set the context associated with it. + + The caller is responsible for ensuring that this call won't create + any cycles in the exception context chain. */ +void +_PyErr_ChainExceptions1(PyObject *exc) +{ + if (exc == NULL) { + return; + } + PyThreadState *tstate = _PyThreadState_GET(); + if (_PyErr_Occurred(tstate)) { + PyObject *exc2 = _PyErr_GetRaisedException(tstate); + PyException_SetContext(exc2, exc); + _PyErr_SetRaisedException(tstate, exc2); + } + else { + _PyErr_SetRaisedException(tstate, exc); + } +} + /* Set the currently set exception's context to the given exception. If the provided exc_info is NULL, then the current Python thread state's @@ -659,27 +757,15 @@ static PyObject * _PyErr_FormatVFromCause(PyThreadState *tstate, PyObject *exception, const char *format, va_list vargs) { - PyObject *exc, *val, *val2, *tb; - assert(_PyErr_Occurred(tstate)); - _PyErr_Fetch(tstate, &exc, &val, &tb); - _PyErr_NormalizeException(tstate, &exc, &val, &tb); - if (tb != NULL) { - PyException_SetTraceback(val, tb); - Py_DECREF(tb); - } - Py_DECREF(exc); + PyObject *exc = _PyErr_GetRaisedException(tstate); assert(!_PyErr_Occurred(tstate)); - _PyErr_FormatV(tstate, exception, format, vargs); - - _PyErr_Fetch(tstate, &exc, &val2, &tb); - _PyErr_NormalizeException(tstate, &exc, &val2, &tb); - Py_INCREF(val); - PyException_SetCause(val2, val); - PyException_SetContext(val2, val); - _PyErr_Restore(tstate, exc, val2, tb); - + PyObject *exc2 = _PyErr_GetRaisedException(tstate); + PyException_SetCause(exc2, Py_NewRef(exc)); + PyException_SetContext(exc2, Py_NewRef(exc)); + Py_DECREF(exc); + _PyErr_SetRaisedException(tstate, exc2); return NULL; } @@ -688,11 +774,7 @@ _PyErr_FormatFromCauseTstate(PyThreadState *tstate, PyObject *exception, const char *format, ...) { va_list vargs; -#ifdef HAVE_STDARG_PROTOTYPES va_start(vargs, format); -#else - va_start(vargs); -#endif _PyErr_FormatVFromCause(tstate, exception, format, vargs); va_end(vargs); return NULL; @@ -703,11 +785,7 @@ _PyErr_FormatFromCause(PyObject *exception, const char *format, ...) { PyThreadState *tstate = _PyThreadState_GET(); va_list vargs; -#ifdef HAVE_STDARG_PROTOTYPES va_start(vargs, format); -#else - va_start(vargs); -#endif _PyErr_FormatVFromCause(tstate, exception, format, vargs); va_end(vargs); return NULL; @@ -724,19 +802,6 @@ PyErr_BadArgument(void) return 0; } -PyObject * -_PyErr_NoMemory(PyThreadState *tstate) -{ - if (Py_IS_TYPE(PyExc_MemoryError, NULL)) { - /* PyErr_NoMemory() has been called before PyExc_MemoryError has been - initialized by _PyExc_Init() */ - Py_FatalError("Out of memory and PyExc_MemoryError is not " - "initialized yet"); - } - _PyErr_SetNone(tstate, PyExc_MemoryError); - return NULL; -} - PyObject * PyErr_NoMemory(void) { @@ -852,7 +917,15 @@ PyErr_SetFromErrnoWithFilenameObjects(PyObject *exc, PyObject *filenameObject, P PyObject * PyErr_SetFromErrnoWithFilename(PyObject *exc, const char *filename) { - PyObject *name = filename ? PyUnicode_DecodeFSDefault(filename) : NULL; + PyObject *name = NULL; + if (filename) { + int i = errno; + name = PyUnicode_DecodeFSDefault(filename); + if (name == NULL) { + return NULL; + } + errno = i; + } PyObject *result = PyErr_SetFromErrnoWithFilenameObjects(exc, name, NULL); Py_XDECREF(name); return result; @@ -949,7 +1022,16 @@ PyObject *PyErr_SetExcFromWindowsErrWithFilename( int ierr, const char *filename) { - PyObject *name = filename ? PyUnicode_DecodeFSDefault(filename) : NULL; + PyObject *name = NULL; + if (filename) { + if ((DWORD)ierr == 0) { + ierr = (int)GetLastError(); + } + name = PyUnicode_DecodeFSDefault(filename); + if (name == NULL) { + return NULL; + } + } PyObject *ret = PyErr_SetExcFromWindowsErrWithFilenameObjects(exc, ierr, name, @@ -973,7 +1055,16 @@ PyObject *PyErr_SetFromWindowsErrWithFilename( int ierr, const char *filename) { - PyObject *name = filename ? PyUnicode_DecodeFSDefault(filename) : NULL; + PyObject *name = NULL; + if (filename) { + if ((DWORD)ierr == 0) { + ierr = (int)GetLastError(); + } + name = PyUnicode_DecodeFSDefault(filename); + if (name == NULL) { + return NULL; + } + } PyObject *result = PyErr_SetExcFromWindowsErrWithFilenameObjects( PyExc_OSError, ierr, name, NULL); @@ -983,9 +1074,10 @@ PyObject *PyErr_SetFromWindowsErrWithFilename( #endif /* MS_WINDOWS */ -PyObject * -PyErr_SetImportErrorSubclass(PyObject *exception, PyObject *msg, - PyObject *name, PyObject *path) +static PyObject * +_PyErr_SetImportErrorSubclassWithNameFrom( + PyObject *exception, PyObject *msg, + PyObject *name, PyObject *path, PyObject* from_name) { PyThreadState *tstate = _PyThreadState_GET(); int issubclass; @@ -1013,6 +1105,10 @@ PyErr_SetImportErrorSubclass(PyObject *exception, PyObject *msg, if (path == NULL) { path = Py_None; } + if (from_name == NULL) { + from_name = Py_None; + } + kwargs = PyDict_New(); if (kwargs == NULL) { @@ -1024,6 +1120,9 @@ PyErr_SetImportErrorSubclass(PyObject *exception, PyObject *msg, if (PyDict_SetItemString(kwargs, "path", path) < 0) { goto done; } + if (PyDict_SetItemString(kwargs, "name_from", from_name) < 0) { + goto done; + } error = PyObject_VectorcallDict(exception, &msg, 1, kwargs); if (error != NULL) { @@ -1036,6 +1135,20 @@ done: return NULL; } + +PyObject * +PyErr_SetImportErrorSubclass(PyObject *exception, PyObject *msg, + PyObject *name, PyObject *path) +{ + return _PyErr_SetImportErrorSubclassWithNameFrom(exception, msg, name, path, NULL); +} + +PyObject * +_PyErr_SetImportErrorWithNameFrom(PyObject *msg, PyObject *name, PyObject *path, PyObject* from_name) +{ + return _PyErr_SetImportErrorSubclassWithNameFrom(PyExc_ImportError, msg, name, path, from_name); +} + PyObject * PyErr_SetImportError(PyObject *msg, PyObject *name, PyObject *path) { @@ -1076,9 +1189,10 @@ _PyErr_FormatV(PyThreadState *tstate, PyObject *exception, _PyErr_Clear(tstate); string = PyUnicode_FromFormatV(format, vargs); - - _PyErr_SetObject(tstate, exception, string); - Py_XDECREF(string); + if (string != NULL) { + _PyErr_SetObject(tstate, exception, string); + Py_DECREF(string); + } return NULL; } @@ -1096,11 +1210,7 @@ _PyErr_Format(PyThreadState *tstate, PyObject *exception, const char *format, ...) { va_list vargs; -#ifdef HAVE_STDARG_PROTOTYPES va_start(vargs, format); -#else - va_start(vargs); -#endif _PyErr_FormatV(tstate, exception, format, vargs); va_end(vargs); return NULL; @@ -1112,17 +1222,40 @@ PyErr_Format(PyObject *exception, const char *format, ...) { PyThreadState *tstate = _PyThreadState_GET(); va_list vargs; -#ifdef HAVE_STDARG_PROTOTYPES va_start(vargs, format); -#else - va_start(vargs); -#endif _PyErr_FormatV(tstate, exception, format, vargs); va_end(vargs); return NULL; } +/* Adds a note to the current exception (if any) */ +void +_PyErr_FormatNote(const char *format, ...) +{ + PyObject *exc = PyErr_GetRaisedException(); + if (exc == NULL) { + return; + } + va_list vargs; + va_start(vargs, format); + PyObject *note = PyUnicode_FromFormatV(format, vargs); + va_end(vargs); + if (note == NULL) { + goto error; + } + int res = _PyException_AddNote(exc, note); + Py_DECREF(note); + if (res < 0) { + goto error; + } + PyErr_SetRaisedException(exc); + return; +error: + _PyErr_ChainExceptions1(exc); +} + + PyObject * PyErr_NewException(const char *name, PyObject *base, PyObject *dict) { @@ -1160,9 +1293,7 @@ PyErr_NewException(const char *name, PyObject *base, PyObject *dict) goto failure; } if (PyTuple_Check(base)) { - bases = base; - /* INCREF as we create a new ref in the else branch */ - Py_INCREF(bases); + bases = Py_NewRef(base); } else { bases = PyTuple_Pack(1, base); if (bases == NULL) @@ -1240,15 +1371,10 @@ static PyStructSequence_Desc UnraisableHookArgs_desc = { PyStatus _PyErr_InitTypes(PyInterpreterState *interp) { - if (!_Py_IsMainInterpreter(interp)) { - return _PyStatus_OK(); - } - - if (UnraisableHookArgsType.tp_name == NULL) { - if (PyStructSequence_InitType2(&UnraisableHookArgsType, - &UnraisableHookArgs_desc) < 0) { - return _PyStatus_ERR("failed to initialize UnraisableHookArgs type"); - } + if (_PyStructSequence_InitBuiltin(interp, &UnraisableHookArgsType, + &UnraisableHookArgs_desc) < 0) + { + return _PyStatus_ERR("failed to initialize UnraisableHookArgs type"); } return _PyStatus_OK(); } @@ -1257,11 +1383,7 @@ _PyErr_InitTypes(PyInterpreterState *interp) void _PyErr_FiniTypes(PyInterpreterState *interp) { - if (!_Py_IsMainInterpreter(interp)) { - return; - } - - _PyStructSequence_FiniType(&UnraisableHookArgsType); + _PyStructSequence_FiniBuiltin(interp, &UnraisableHookArgsType); } @@ -1281,8 +1403,7 @@ make_unraisable_hook_args(PyThreadState *tstate, PyObject *exc_type, if (exc_type == NULL) { \ exc_type = Py_None; \ } \ - Py_INCREF(exc_type); \ - PyStructSequence_SET_ITEM(args, pos++, exc_type); \ + PyStructSequence_SET_ITEM(args, pos++, Py_NewRef(exc_type)); \ } while (0) @@ -1610,19 +1731,18 @@ static void PyErr_SyntaxLocationObjectEx(PyObject *filename, int lineno, int col_offset, int end_lineno, int end_col_offset) { - PyObject *exc, *v, *tb, *tmp; PyThreadState *tstate = _PyThreadState_GET(); /* add attributes for the line number and filename for the error */ - _PyErr_Fetch(tstate, &exc, &v, &tb); - _PyErr_NormalizeException(tstate, &exc, &v, &tb); + PyObject *exc = _PyErr_GetRaisedException(tstate); /* XXX check that it is, indeed, a syntax error. It might not * be, though. */ - tmp = PyLong_FromLong(lineno); - if (tmp == NULL) + PyObject *tmp = PyLong_FromLong(lineno); + if (tmp == NULL) { _PyErr_Clear(tstate); + } else { - if (PyObject_SetAttr(v, &_Py_ID(lineno), tmp)) { + if (PyObject_SetAttr(exc, &_Py_ID(lineno), tmp)) { _PyErr_Clear(tstate); } Py_DECREF(tmp); @@ -1634,7 +1754,7 @@ PyErr_SyntaxLocationObjectEx(PyObject *filename, int lineno, int col_offset, _PyErr_Clear(tstate); } } - if (PyObject_SetAttr(v, &_Py_ID(offset), tmp ? tmp : Py_None)) { + if (PyObject_SetAttr(exc, &_Py_ID(offset), tmp ? tmp : Py_None)) { _PyErr_Clear(tstate); } Py_XDECREF(tmp); @@ -1646,7 +1766,7 @@ PyErr_SyntaxLocationObjectEx(PyObject *filename, int lineno, int col_offset, _PyErr_Clear(tstate); } } - if (PyObject_SetAttr(v, &_Py_ID(end_lineno), tmp ? tmp : Py_None)) { + if (PyObject_SetAttr(exc, &_Py_ID(end_lineno), tmp ? tmp : Py_None)) { _PyErr_Clear(tstate); } Py_XDECREF(tmp); @@ -1658,20 +1778,20 @@ PyErr_SyntaxLocationObjectEx(PyObject *filename, int lineno, int col_offset, _PyErr_Clear(tstate); } } - if (PyObject_SetAttr(v, &_Py_ID(end_offset), tmp ? tmp : Py_None)) { + if (PyObject_SetAttr(exc, &_Py_ID(end_offset), tmp ? tmp : Py_None)) { _PyErr_Clear(tstate); } Py_XDECREF(tmp); tmp = NULL; if (filename != NULL) { - if (PyObject_SetAttr(v, &_Py_ID(filename), filename)) { + if (PyObject_SetAttr(exc, &_Py_ID(filename), filename)) { _PyErr_Clear(tstate); } tmp = PyErr_ProgramTextObject(filename, lineno); if (tmp) { - if (PyObject_SetAttr(v, &_Py_ID(text), tmp)) { + if (PyObject_SetAttr(exc, &_Py_ID(text), tmp)) { _PyErr_Clear(tstate); } Py_DECREF(tmp); @@ -1680,17 +1800,17 @@ PyErr_SyntaxLocationObjectEx(PyObject *filename, int lineno, int col_offset, _PyErr_Clear(tstate); } } - if (exc != PyExc_SyntaxError) { - if (_PyObject_LookupAttr(v, &_Py_ID(msg), &tmp) < 0) { + if ((PyObject *)Py_TYPE(exc) != PyExc_SyntaxError) { + if (_PyObject_LookupAttr(exc, &_Py_ID(msg), &tmp) < 0) { _PyErr_Clear(tstate); } else if (tmp) { Py_DECREF(tmp); } else { - tmp = PyObject_Str(v); + tmp = PyObject_Str(exc); if (tmp) { - if (PyObject_SetAttr(v, &_Py_ID(msg), tmp)) { + if (PyObject_SetAttr(exc, &_Py_ID(msg), tmp)) { _PyErr_Clear(tstate); } Py_DECREF(tmp); @@ -1700,19 +1820,19 @@ PyErr_SyntaxLocationObjectEx(PyObject *filename, int lineno, int col_offset, } } - if (_PyObject_LookupAttr(v, &_Py_ID(print_file_and_line), &tmp) < 0) { + if (_PyObject_LookupAttr(exc, &_Py_ID(print_file_and_line), &tmp) < 0) { _PyErr_Clear(tstate); } else if (tmp) { Py_DECREF(tmp); } else { - if (PyObject_SetAttr(v, &_Py_ID(print_file_and_line), Py_None)) { + if (PyObject_SetAttr(exc, &_Py_ID(print_file_and_line), Py_None)) { _PyErr_Clear(tstate); } } } - _PyErr_Restore(tstate, exc, v, tb); + _PyErr_SetRaisedException(tstate, exc); } void diff --git a/Python/fileutils.c b/Python/fileutils.c index 27924261..610e729f 100644 --- a/Python/fileutils.c +++ b/Python/fileutils.c @@ -8,7 +8,13 @@ #ifdef MS_WINDOWS # include <malloc.h> # include <windows.h> -# include <pathcch.h> // PathCchCombineEx +# include <winioctl.h> // FILE_DEVICE_* constants +# include "pycore_fileutils_windows.h" // FILE_STAT_BASIC_INFORMATION +# if defined(MS_WINDOWS_GAMES) && !defined(MS_WINDOWS_DESKTOP) +# define PATHCCH_ALLOW_LONG_PATHS 0x01 +# else +# include <pathcch.h> // PathCchCombineEx +# endif extern int winerror_to_errno(int); #endif @@ -77,7 +83,8 @@ _Py_device_encoding(int fd) if (!valid) Py_RETURN_NONE; -#if defined(MS_WINDOWS) +#ifdef MS_WINDOWS +#ifdef HAVE_WINDOWS_CONSOLE_IO UINT cp; if (fd == 0) cp = GetConsoleCP(); @@ -92,6 +99,9 @@ _Py_device_encoding(int fd) } return PyUnicode_FromFormat("cp%u", (unsigned int)cp); +#else + Py_RETURN_NONE; +#endif /* HAVE_WINDOWS_CONSOLE_IO */ #else if (_PyRuntime.preconfig.utf8_mode) { _Py_DECLARE_STR(utf_8, "utf-8"); @@ -191,7 +201,7 @@ extern int _Py_normalize_encoding(const char *, char *, size_t); Py_DecodeLocale() uses mbstowcs() -1: unknown, need to call check_force_ascii() to get the value */ -static int force_ascii = -1; +#define force_ascii (_PyRuntime.fileutils.force_ascii) static int check_force_ascii(void) @@ -603,9 +613,9 @@ _Py_DecodeLocaleEx(const char* arg, wchar_t **wstr, size_t *wlen, return _Py_DecodeUTF8Ex(arg, strlen(arg), wstr, wlen, reason, errors); #else - int use_utf8 = (Py_UTF8Mode == 1); + int use_utf8 = (_PyRuntime.preconfig.utf8_mode >= 1); #ifdef MS_WINDOWS - use_utf8 |= !Py_LegacyWindowsFSEncodingFlag; + use_utf8 |= (_PyRuntime.preconfig.legacy_windows_fs_encoding == 0); #endif if (use_utf8) { return _Py_DecodeUTF8Ex(arg, strlen(arg), wstr, wlen, reason, @@ -795,9 +805,9 @@ encode_locale_ex(const wchar_t *text, char **str, size_t *error_pos, return _Py_EncodeUTF8Ex(text, str, error_pos, reason, raw_malloc, errors); #else - int use_utf8 = (Py_UTF8Mode == 1); + int use_utf8 = (_PyRuntime.preconfig.utf8_mode >= 1); #ifdef MS_WINDOWS - use_utf8 |= !Py_LegacyWindowsFSEncodingFlag; + use_utf8 |= (_PyRuntime.preconfig.legacy_windows_fs_encoding == 0); #endif if (use_utf8) { return _Py_EncodeUTF8Ex(text, str, error_pos, reason, @@ -1048,6 +1058,13 @@ FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, time_t *time_out, int* nsec_out) *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, time_t); } +static void +LARGE_INTEGER_to_time_t_nsec(LARGE_INTEGER *in_ptr, time_t *time_out, int* nsec_out) +{ + *nsec_out = (int)(in_ptr->QuadPart % 10000000) * 100; /* FILETIME is in units of 100 nsec. */ + *time_out = Py_SAFE_DOWNCAST((in_ptr->QuadPart / 10000000) - secs_between_epochs, __int64, time_t); +} + void _Py_time_t_to_FILE_TIME(time_t time_in, int nsec_in, FILETIME *out_ptr) { @@ -1077,33 +1094,127 @@ attributes_to_mode(DWORD attr) return m; } + +typedef union { + FILE_ID_128 id; + struct { + uint64_t st_ino; + uint64_t st_ino_high; + }; +} id_128_to_ino; + + void _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *info, ULONG reparse_tag, + FILE_BASIC_INFO *basic_info, FILE_ID_INFO *id_info, struct _Py_stat_struct *result) { memset(result, 0, sizeof(*result)); result->st_mode = attributes_to_mode(info->dwFileAttributes); result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow; - result->st_dev = info->dwVolumeSerialNumber; - result->st_rdev = result->st_dev; - FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec); - FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec); - FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec); + result->st_dev = id_info ? id_info->VolumeSerialNumber : info->dwVolumeSerialNumber; + result->st_rdev = 0; + /* st_ctime is deprecated, but we preserve the legacy value in our caller, not here */ + if (basic_info) { + LARGE_INTEGER_to_time_t_nsec(&basic_info->CreationTime, &result->st_birthtime, &result->st_birthtime_nsec); + LARGE_INTEGER_to_time_t_nsec(&basic_info->ChangeTime, &result->st_ctime, &result->st_ctime_nsec); + LARGE_INTEGER_to_time_t_nsec(&basic_info->LastWriteTime, &result->st_mtime, &result->st_mtime_nsec); + LARGE_INTEGER_to_time_t_nsec(&basic_info->LastAccessTime, &result->st_atime, &result->st_atime_nsec); + } else { + FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_birthtime, &result->st_birthtime_nsec); + FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec); + FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec); + } result->st_nlink = info->nNumberOfLinks; - result->st_ino = (((uint64_t)info->nFileIndexHigh) << 32) + info->nFileIndexLow; + + if (id_info) { + id_128_to_ino file_id; + file_id.id = id_info->FileId; + result->st_ino = file_id.st_ino; + result->st_ino_high = file_id.st_ino_high; + } + if (!result->st_ino && !result->st_ino_high) { + /* should only occur for DirEntry_from_find_data, in which case the + index is likely to be zero anyway. */ + result->st_ino = (((uint64_t)info->nFileIndexHigh) << 32) + info->nFileIndexLow; + } + /* bpo-37834: Only actual symlinks set the S_IFLNK flag. But lstat() will open other name surrogate reparse points without traversing them. To detect/handle these, check st_file_attributes and st_reparse_tag. */ result->st_reparse_tag = reparse_tag; if (info->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT && reparse_tag == IO_REPARSE_TAG_SYMLINK) { - /* first clear the S_IFMT bits */ - result->st_mode ^= (result->st_mode & S_IFMT); - /* now set the bits that make this a symlink */ - result->st_mode |= S_IFLNK; + /* set the bits that make this a symlink */ + result->st_mode = (result->st_mode & ~S_IFMT) | S_IFLNK; } result->st_file_attributes = info->dwFileAttributes; } + +void +_Py_stat_basic_info_to_stat(FILE_STAT_BASIC_INFORMATION *info, + struct _Py_stat_struct *result) +{ + memset(result, 0, sizeof(*result)); + result->st_mode = attributes_to_mode(info->FileAttributes); + result->st_size = info->EndOfFile.QuadPart; + LARGE_INTEGER_to_time_t_nsec(&info->CreationTime, &result->st_birthtime, &result->st_birthtime_nsec); + LARGE_INTEGER_to_time_t_nsec(&info->ChangeTime, &result->st_ctime, &result->st_ctime_nsec); + LARGE_INTEGER_to_time_t_nsec(&info->LastWriteTime, &result->st_mtime, &result->st_mtime_nsec); + LARGE_INTEGER_to_time_t_nsec(&info->LastAccessTime, &result->st_atime, &result->st_atime_nsec); + result->st_nlink = info->NumberOfLinks; + result->st_dev = info->VolumeSerialNumber.QuadPart; + /* File systems with less than 128-bits zero pad into this field */ + id_128_to_ino file_id; + file_id.id = info->FileId128; + result->st_ino = file_id.st_ino; + result->st_ino_high = file_id.st_ino_high; + /* bpo-37834: Only actual symlinks set the S_IFLNK flag. But lstat() will + open other name surrogate reparse points without traversing them. To + detect/handle these, check st_file_attributes and st_reparse_tag. */ + result->st_reparse_tag = info->ReparseTag; + if (info->FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT && + info->ReparseTag == IO_REPARSE_TAG_SYMLINK) { + /* set the bits that make this a symlink */ + result->st_mode = (result->st_mode & ~S_IFMT) | S_IFLNK; + } + result->st_file_attributes = info->FileAttributes; + switch (info->DeviceType) { + case FILE_DEVICE_DISK: + case FILE_DEVICE_VIRTUAL_DISK: + case FILE_DEVICE_DFS: + case FILE_DEVICE_CD_ROM: + case FILE_DEVICE_CONTROLLER: + case FILE_DEVICE_DATALINK: + break; + case FILE_DEVICE_DISK_FILE_SYSTEM: + case FILE_DEVICE_CD_ROM_FILE_SYSTEM: + case FILE_DEVICE_NETWORK_FILE_SYSTEM: + result->st_mode = (result->st_mode & ~S_IFMT) | 0x6000; /* _S_IFBLK */ + break; + case FILE_DEVICE_CONSOLE: + case FILE_DEVICE_NULL: + case FILE_DEVICE_KEYBOARD: + case FILE_DEVICE_MODEM: + case FILE_DEVICE_MOUSE: + case FILE_DEVICE_PARALLEL_PORT: + case FILE_DEVICE_PRINTER: + case FILE_DEVICE_SCREEN: + case FILE_DEVICE_SERIAL_PORT: + case FILE_DEVICE_SOUND: + result->st_mode = (result->st_mode & ~S_IFMT) | _S_IFCHR; + break; + case FILE_DEVICE_NAMED_PIPE: + result->st_mode = (result->st_mode & ~S_IFMT) | _S_IFIFO; + break; + default: + if (info->FileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + result->st_mode = (result->st_mode & ~S_IFMT) | _S_IFDIR; + } + break; + } +} + #endif /* Return information about a file. @@ -1123,6 +1234,8 @@ _Py_fstat_noraise(int fd, struct _Py_stat_struct *status) { #ifdef MS_WINDOWS BY_HANDLE_FILE_INFORMATION info; + FILE_BASIC_INFO basicInfo; + FILE_ID_INFO idInfo; HANDLE h; int type; @@ -1154,16 +1267,16 @@ _Py_fstat_noraise(int fd, struct _Py_stat_struct *status) return 0; } - if (!GetFileInformationByHandle(h, &info)) { + if (!GetFileInformationByHandle(h, &info) || + !GetFileInformationByHandleEx(h, FileBasicInfo, &basicInfo, sizeof(basicInfo)) || + !GetFileInformationByHandleEx(h, FileIdInfo, &idInfo, sizeof(idInfo))) { /* The Win32 error is already set, but we also set errno for callers who expect it */ errno = winerror_to_errno(GetLastError()); return -1; } - _Py_attribute_data_to_stat(&info, 0, status); - /* specific to fstat() */ - status->st_ino = (((uint64_t)info.nFileIndexHigh) << 32) + info.nFileIndexLow; + _Py_attribute_data_to_stat(&info, 0, &basicInfo, &idInfo, status); return 0; #else return fstat(fd, status); @@ -1244,18 +1357,12 @@ _Py_stat(PyObject *path, struct stat *statbuf) #ifdef MS_WINDOWS int err; -#if USE_UNICODE_WCHAR_CACHE - const wchar_t *wpath = _PyUnicode_AsUnicode(path); -#else /* USE_UNICODE_WCHAR_CACHE */ wchar_t *wpath = PyUnicode_AsWideCharString(path, NULL); -#endif /* USE_UNICODE_WCHAR_CACHE */ if (wpath == NULL) return -2; err = _Py_wstat(wpath, statbuf); -#if !USE_UNICODE_WCHAR_CACHE PyMem_Free(wpath); -#endif /* USE_UNICODE_WCHAR_CACHE */ return err; #else int ret; @@ -1278,6 +1385,13 @@ _Py_stat(PyObject *path, struct stat *statbuf) #endif } +#ifdef MS_WINDOWS +// For some Windows API partitions, SetHandleInformation() is declared +// but none of the handle flags are defined. +#ifndef HANDLE_FLAG_INHERIT +#define HANDLE_FLAG_INHERIT 0x00000001 +#endif +#endif /* This function MUST be kept async-signal-safe on POSIX when raise=0. */ static int @@ -1370,17 +1484,11 @@ set_inheritable(int fd, int inheritable, int raise, int *atomic_flag_works) else flags = 0; - /* This check can be removed once support for Windows 7 ends. */ -#define CONSOLE_PSEUDOHANDLE(handle) (((ULONG_PTR)(handle) & 0x3) == 0x3 && \ - GetFileType(handle) == FILE_TYPE_CHAR) - - if (!CONSOLE_PSEUDOHANDLE(handle) && - !SetHandleInformation(handle, HANDLE_FLAG_INHERIT, flags)) { + if (!SetHandleInformation(handle, HANDLE_FLAG_INHERIT, flags)) { if (raise) PyErr_SetFromWindowsErr(0); return -1; } -#undef CONSOLE_PSEUDOHANDLE return 0; #else @@ -1663,11 +1771,8 @@ _Py_fopen_obj(PyObject *path, const char *mode) Py_TYPE(path)); return NULL; } -#if USE_UNICODE_WCHAR_CACHE - const wchar_t *wpath = _PyUnicode_AsUnicode(path); -#else /* USE_UNICODE_WCHAR_CACHE */ + wchar_t *wpath = PyUnicode_AsWideCharString(path, NULL); -#endif /* USE_UNICODE_WCHAR_CACHE */ if (wpath == NULL) return NULL; @@ -1675,9 +1780,7 @@ _Py_fopen_obj(PyObject *path, const char *mode) wmode, Py_ARRAY_LENGTH(wmode)); if (usize == 0) { PyErr_SetFromWindowsErr(0); -#if !USE_UNICODE_WCHAR_CACHE PyMem_Free(wpath); -#endif /* USE_UNICODE_WCHAR_CACHE */ return NULL; } @@ -1687,9 +1790,8 @@ _Py_fopen_obj(PyObject *path, const char *mode) Py_END_ALLOW_THREADS } while (f == NULL && errno == EINTR && !(async_err = PyErr_CheckSignals())); -#if !USE_UNICODE_WCHAR_CACHE + int saved_errno = errno; PyMem_Free(wpath); -#endif /* USE_UNICODE_WCHAR_CACHE */ #else PyObject *bytes; const char *path_bytes; @@ -1711,13 +1813,14 @@ _Py_fopen_obj(PyObject *path, const char *mode) Py_END_ALLOW_THREADS } while (f == NULL && errno == EINTR && !(async_err = PyErr_CheckSignals())); - + int saved_errno = errno; Py_DECREF(bytes); #endif if (async_err) return NULL; if (f == NULL) { + errno = saved_errno; PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path); return NULL; } @@ -1765,7 +1868,15 @@ _Py_read(int fd, void *buf, size_t count) Py_BEGIN_ALLOW_THREADS errno = 0; #ifdef MS_WINDOWS + _doserrno = 0; n = read(fd, buf, (int)count); + // read() on a non-blocking empty pipe fails with EINVAL, which is + // mapped from the Windows error code ERROR_NO_DATA. + if (n < 0 && errno == EINVAL) { + if (_doserrno == ERROR_NO_DATA) { + errno = EAGAIN; + } + } #else n = read(fd, buf, count); #endif @@ -1819,6 +1930,7 @@ _Py_write_impl(int fd, const void *buf, size_t count, int gil_held) } } } + #endif if (count > _PY_WRITE_MAX) { count = _PY_WRITE_MAX; @@ -1829,7 +1941,18 @@ _Py_write_impl(int fd, const void *buf, size_t count, int gil_held) Py_BEGIN_ALLOW_THREADS errno = 0; #ifdef MS_WINDOWS - n = write(fd, buf, (int)count); + // write() on a non-blocking pipe fails with ENOSPC on Windows if + // the pipe lacks available space for the entire buffer. + int c = (int)count; + do { + _doserrno = 0; + n = write(fd, buf, c); + if (n >= 0 || errno != ENOSPC || _doserrno != 0) { + break; + } + errno = EAGAIN; + c /= 2; + } while (c > 0); #else n = write(fd, buf, count); #endif @@ -1844,7 +1967,18 @@ _Py_write_impl(int fd, const void *buf, size_t count, int gil_held) do { errno = 0; #ifdef MS_WINDOWS - n = write(fd, buf, (int)count); + // write() on a non-blocking pipe fails with ENOSPC on Windows if + // the pipe lacks available space for the entire buffer. + int c = (int)count; + do { + _doserrno = 0; + n = write(fd, buf, c); + if (n >= 0 || errno != ENOSPC || _doserrno != 0) { + break; + } + errno = EAGAIN; + c /= 2; + } while (c > 0); #else n = write(fd, buf, count); #endif @@ -2086,6 +2220,72 @@ _Py_abspath(const wchar_t *path, wchar_t **abspath_p) #endif } +// The Windows Games API family implements the PathCch* APIs in the Xbox OS, +// but does not expose them yet. Load them dynamically until +// 1) they are officially exposed +// 2) we stop supporting older versions of the GDK which do not expose them +#if defined(MS_WINDOWS_GAMES) && !defined(MS_WINDOWS_DESKTOP) +HRESULT +PathCchSkipRoot(const wchar_t *path, const wchar_t **rootEnd) +{ + static int initialized = 0; + typedef HRESULT(__stdcall *PPathCchSkipRoot) (PCWSTR pszPath, + PCWSTR *ppszRootEnd); + static PPathCchSkipRoot _PathCchSkipRoot; + + if (initialized == 0) { + HMODULE pathapi = LoadLibraryExW(L"api-ms-win-core-path-l1-1-0.dll", NULL, + LOAD_LIBRARY_SEARCH_SYSTEM32); + if (pathapi) { + _PathCchSkipRoot = (PPathCchSkipRoot)GetProcAddress( + pathapi, "PathCchSkipRoot"); + } + else { + _PathCchSkipRoot = NULL; + } + initialized = 1; + } + + if (!_PathCchSkipRoot) { + return E_NOINTERFACE; + } + + return _PathCchSkipRoot(path, rootEnd); +} + +static HRESULT +PathCchCombineEx(wchar_t *buffer, size_t bufsize, const wchar_t *dirname, + const wchar_t *relfile, unsigned long flags) +{ + static int initialized = 0; + typedef HRESULT(__stdcall *PPathCchCombineEx) (PWSTR pszPathOut, + size_t cchPathOut, + PCWSTR pszPathIn, + PCWSTR pszMore, + unsigned long dwFlags); + static PPathCchCombineEx _PathCchCombineEx; + + if (initialized == 0) { + HMODULE pathapi = LoadLibraryExW(L"api-ms-win-core-path-l1-1-0.dll", NULL, + LOAD_LIBRARY_SEARCH_SYSTEM32); + if (pathapi) { + _PathCchCombineEx = (PPathCchCombineEx)GetProcAddress( + pathapi, "PathCchCombineEx"); + } + else { + _PathCchCombineEx = NULL; + } + initialized = 1; + } + + if (!_PathCchCombineEx) { + return E_NOINTERFACE; + } + + return _PathCchCombineEx(buffer, bufsize, dirname, relfile, flags); +} + +#endif /* defined(MS_WINDOWS_GAMES) && !defined(MS_WINDOWS_DESKTOP) */ // The caller must ensure "buffer" is big enough. static int @@ -2142,7 +2342,10 @@ _Py_join_relfile(const wchar_t *dirname, const wchar_t *relfile) } assert(wcslen(dirname) < MAXPATHLEN); assert(wcslen(relfile) < MAXPATHLEN - wcslen(dirname)); - join_relfile(filename, bufsize, dirname, relfile); + if (join_relfile(filename, bufsize, dirname, relfile) < 0) { + PyMem_RawFree(filename); + return NULL; + } return filename; } @@ -2176,11 +2379,14 @@ _Py_find_basename(const wchar_t *filename) path, which will be within the original buffer. Guaranteed to not make the path longer, and will not fail. 'size' is the length of the path, if known. If -1, the first null character will be assumed - to be the end of the path. */ + to be the end of the path. 'normsize' will be set to contain the + length of the resulting normalized path. */ wchar_t * -_Py_normpath(wchar_t *path, Py_ssize_t size) +_Py_normpath_and_size(wchar_t *path, Py_ssize_t size, Py_ssize_t *normsize) { - if (!path[0] || size == 0) { + assert(path != NULL); + if ((size < 0 && !path[0]) || size == 0) { + *normsize = 0; return path; } wchar_t *pEnd = size >= 0 ? &path[size] : NULL; @@ -2229,11 +2435,7 @@ _Py_normpath(wchar_t *path, Py_ssize_t size) *p2++ = lastC = *p1; } } - if (sepCount) { - minP2 = p2; // Invalid path - } else { - minP2 = p2 - 1; // Absolute path has SEP at minP2 - } + minP2 = p2 - 1; } #else // Skip past two leading SEPs @@ -2293,13 +2495,28 @@ _Py_normpath(wchar_t *path, Py_ssize_t size) while (--p2 != minP2 && *p2 == SEP) { *p2 = L'\0'; } + } else { + --p2; } + *normsize = p2 - path + 1; #undef SEP_OR_END #undef IS_SEP #undef IS_END return path; } +/* In-place path normalisation. Returns the start of the normalized + path, which will be within the original buffer. Guaranteed to not + make the path longer, and will not fail. 'size' is the length of + the path, if known. If -1, the first null character will be assumed + to be the end of the path. */ +wchar_t * +_Py_normpath(wchar_t *path, Py_ssize_t size) +{ + Py_ssize_t norm_length; + return _Py_normpath_and_size(path, size, &norm_length); +} + /* Get the current directory. buflen is the buffer size in wide characters including the null character. Decode the path from the locale encoding. @@ -2465,6 +2682,64 @@ error: return -1; } #else /* MS_WINDOWS */ +int +_Py_get_blocking(int fd) +{ + HANDLE handle; + DWORD mode; + BOOL success; + + handle = _Py_get_osfhandle(fd); + if (handle == INVALID_HANDLE_VALUE) { + return -1; + } + + Py_BEGIN_ALLOW_THREADS + success = GetNamedPipeHandleStateW(handle, &mode, + NULL, NULL, NULL, NULL, 0); + Py_END_ALLOW_THREADS + + if (!success) { + PyErr_SetFromWindowsErr(0); + return -1; + } + + return !(mode & PIPE_NOWAIT); +} + +int +_Py_set_blocking(int fd, int blocking) +{ + HANDLE handle; + DWORD mode; + BOOL success; + + handle = _Py_get_osfhandle(fd); + if (handle == INVALID_HANDLE_VALUE) { + return -1; + } + + Py_BEGIN_ALLOW_THREADS + success = GetNamedPipeHandleStateW(handle, &mode, + NULL, NULL, NULL, NULL, 0); + if (success) { + if (blocking) { + mode &= ~PIPE_NOWAIT; + } + else { + mode |= PIPE_NOWAIT; + } + success = SetNamedPipeHandleState(handle, &mode, NULL, NULL); + } + Py_END_ALLOW_THREADS + + if (!success) { + PyErr_SetFromWindowsErr(0); + return -1; + } + return 0; +} + void* _Py_get_osfhandle_noraise(int fd) { diff --git a/Python/flowgraph.c b/Python/flowgraph.c new file mode 100644 index 00000000..f860631a --- /dev/null +++ b/Python/flowgraph.c @@ -0,0 +1,2218 @@ + +#include <stdbool.h> + +#include "Python.h" +#include "pycore_flowgraph.h" +#include "pycore_compile.h" +#include "pycore_pymem.h" // _PyMem_IsPtrFreed() + +#include "pycore_opcode_utils.h" +#define NEED_OPCODE_METADATA +#include "opcode_metadata.h" // _PyOpcode_opcode_metadata, _PyOpcode_num_popped/pushed +#undef NEED_OPCODE_METADATA + + +#undef SUCCESS +#undef ERROR +#define SUCCESS 0 +#define ERROR -1 + +#define RETURN_IF_ERROR(X) \ + if ((X) == -1) { \ + return ERROR; \ + } + +#define DEFAULT_BLOCK_SIZE 16 + +typedef _PyCompilerSrcLocation location; +typedef _PyCfgJumpTargetLabel jump_target_label; +typedef _PyCfgBasicblock basicblock; +typedef _PyCfgBuilder cfg_builder; +typedef _PyCfgInstruction cfg_instr; + +static const jump_target_label NO_LABEL = {-1}; + +#define SAME_LABEL(L1, L2) ((L1).id == (L2).id) +#define IS_LABEL(L) (!SAME_LABEL((L), (NO_LABEL))) + + +static inline int +is_block_push(cfg_instr *i) +{ + return IS_BLOCK_PUSH_OPCODE(i->i_opcode); +} + +static inline int +is_jump(cfg_instr *i) +{ + return IS_JUMP_OPCODE(i->i_opcode); +} + +/* One arg*/ +#define INSTR_SET_OP1(I, OP, ARG) \ + do { \ + assert(HAS_ARG(OP)); \ + _PyCfgInstruction *_instr__ptr_ = (I); \ + _instr__ptr_->i_opcode = (OP); \ + _instr__ptr_->i_oparg = (ARG); \ + } while (0); + +/* No args*/ +#define INSTR_SET_OP0(I, OP) \ + do { \ + assert(!HAS_ARG(OP)); \ + _PyCfgInstruction *_instr__ptr_ = (I); \ + _instr__ptr_->i_opcode = (OP); \ + _instr__ptr_->i_oparg = 0; \ + } while (0); + +/***** Blocks *****/ + +/* Returns the offset of the next instruction in the current block's + b_instr array. Resizes the b_instr as necessary. + Returns -1 on failure. +*/ +static int +basicblock_next_instr(basicblock *b) +{ + assert(b != NULL); + RETURN_IF_ERROR( + _PyCompile_EnsureArrayLargeEnough( + b->b_iused + 1, + (void**)&b->b_instr, + &b->b_ialloc, + DEFAULT_BLOCK_SIZE, + sizeof(cfg_instr))); + return b->b_iused++; +} + +/* Allocate a new block and return a pointer to it. + Returns NULL on error. +*/ + +static basicblock * +cfg_builder_new_block(cfg_builder *g) +{ + basicblock *b = (basicblock *)PyObject_Calloc(1, sizeof(basicblock)); + if (b == NULL) { + PyErr_NoMemory(); + return NULL; + } + /* Extend the singly linked list of blocks with new block. */ + b->b_list = g->g_block_list; + g->g_block_list = b; + b->b_label = NO_LABEL; + return b; +} + +static int +basicblock_addop(basicblock *b, int opcode, int oparg, location loc) +{ + assert(IS_WITHIN_OPCODE_RANGE(opcode)); + assert(!IS_ASSEMBLER_OPCODE(opcode)); + assert(HAS_ARG(opcode) || HAS_TARGET(opcode) || oparg == 0); + assert(0 <= oparg && oparg < (1 << 30)); + + int off = basicblock_next_instr(b); + if (off < 0) { + return ERROR; + } + cfg_instr *i = &b->b_instr[off]; + i->i_opcode = opcode; + i->i_oparg = oparg; + i->i_target = NULL; + i->i_loc = loc; + + return SUCCESS; +} + +static inline int +basicblock_append_instructions(basicblock *target, basicblock *source) +{ + for (int i = 0; i < source->b_iused; i++) { + int n = basicblock_next_instr(target); + if (n < 0) { + return ERROR; + } + target->b_instr[n] = source->b_instr[i]; + } + return SUCCESS; +} + +static basicblock * +copy_basicblock(cfg_builder *g, basicblock *block) +{ + /* Cannot copy a block if it has a fallthrough, since + * a block can only have one fallthrough predecessor. + */ + assert(BB_NO_FALLTHROUGH(block)); + basicblock *result = cfg_builder_new_block(g); + if (result == NULL) { + return NULL; + } + if (basicblock_append_instructions(result, block) < 0) { + return NULL; + } + return result; +} + +int +_PyBasicblock_InsertInstruction(basicblock *block, int pos, cfg_instr *instr) { + RETURN_IF_ERROR(basicblock_next_instr(block)); + for (int i = block->b_iused - 1; i > pos; i--) { + block->b_instr[i] = block->b_instr[i-1]; + } + block->b_instr[pos] = *instr; + return SUCCESS; +} + +static int +instr_size(cfg_instr *instruction) +{ + return _PyCompile_InstrSize(instruction->i_opcode, instruction->i_oparg); +} + +static int +blocksize(basicblock *b) +{ + int size = 0; + for (int i = 0; i < b->b_iused; i++) { + size += instr_size(&b->b_instr[i]); + } + return size; +} + +/* For debugging purposes only */ +#if 0 +static void +dump_instr(cfg_instr *i) +{ + const char *jump = is_jump(i) ? "jump " : ""; + + char arg[128]; + + *arg = '\0'; + if (HAS_ARG(i->i_opcode)) { + sprintf(arg, "arg: %d ", i->i_oparg); + } + if (HAS_TARGET(i->i_opcode)) { + sprintf(arg, "target: %p [%d] ", i->i_target, i->i_oparg); + } + fprintf(stderr, "line: %d, opcode: %d %s%s\n", + i->i_loc.lineno, i->i_opcode, arg, jump); +} + +static inline int +basicblock_returns(const basicblock *b) { + cfg_instr *last = _PyCfg_BasicblockLastInstr(b); + return last && (last->i_opcode == RETURN_VALUE || last->i_opcode == RETURN_CONST); +} + +static void +dump_basicblock(const basicblock *b) +{ + const char *b_return = basicblock_returns(b) ? "return " : ""; + fprintf(stderr, "%d: [EH=%d CLD=%d WRM=%d NO_FT=%d %p] used: %d, depth: %d, offset: %d %s\n", + b->b_label.id, b->b_except_handler, b->b_cold, b->b_warm, BB_NO_FALLTHROUGH(b), b, b->b_iused, + b->b_startdepth, b->b_offset, b_return); + if (b->b_instr) { + int i; + for (i = 0; i < b->b_iused; i++) { + fprintf(stderr, " [%02d] ", i); + dump_instr(b->b_instr + i); + } + } +} + +void +_PyCfgBuilder_DumpGraph(const basicblock *entryblock) +{ + for (const basicblock *b = entryblock; b != NULL; b = b->b_next) { + dump_basicblock(b); + } +} + +#endif + + +/***** CFG construction and modification *****/ + +static basicblock * +cfg_builder_use_next_block(cfg_builder *g, basicblock *block) +{ + assert(block != NULL); + g->g_curblock->b_next = block; + g->g_curblock = block; + return block; +} + +cfg_instr * +_PyCfg_BasicblockLastInstr(const basicblock *b) { + assert(b->b_iused >= 0); + if (b->b_iused > 0) { + assert(b->b_instr != NULL); + return &b->b_instr[b->b_iused - 1]; + } + return NULL; +} + +static inline int +basicblock_exits_scope(const basicblock *b) { + cfg_instr *last = _PyCfg_BasicblockLastInstr(b); + return last && IS_SCOPE_EXIT_OPCODE(last->i_opcode); +} + +static bool +cfg_builder_current_block_is_terminated(cfg_builder *g) +{ + cfg_instr *last = _PyCfg_BasicblockLastInstr(g->g_curblock); + if (last && IS_TERMINATOR_OPCODE(last->i_opcode)) { + return true; + } + if (IS_LABEL(g->g_current_label)) { + if (last || IS_LABEL(g->g_curblock->b_label)) { + return true; + } + else { + /* current block is empty, label it */ + g->g_curblock->b_label = g->g_current_label; + g->g_current_label = NO_LABEL; + } + } + return false; +} + +static int +cfg_builder_maybe_start_new_block(cfg_builder *g) +{ + if (cfg_builder_current_block_is_terminated(g)) { + basicblock *b = cfg_builder_new_block(g); + if (b == NULL) { + return ERROR; + } + b->b_label = g->g_current_label; + g->g_current_label = NO_LABEL; + cfg_builder_use_next_block(g, b); + } + return SUCCESS; +} + +#ifndef NDEBUG +static bool +cfg_builder_check(cfg_builder *g) +{ + assert(g->g_entryblock->b_iused > 0); + for (basicblock *block = g->g_block_list; block != NULL; block = block->b_list) { + assert(!_PyMem_IsPtrFreed(block)); + if (block->b_instr != NULL) { + assert(block->b_ialloc > 0); + assert(block->b_iused >= 0); + assert(block->b_ialloc >= block->b_iused); + } + else { + assert (block->b_iused == 0); + assert (block->b_ialloc == 0); + } + } + return true; +} +#endif + +int +_PyCfgBuilder_Init(cfg_builder *g) +{ + g->g_block_list = NULL; + basicblock *block = cfg_builder_new_block(g); + if (block == NULL) { + return ERROR; + } + g->g_curblock = g->g_entryblock = block; + g->g_current_label = NO_LABEL; + return SUCCESS; +} + +void +_PyCfgBuilder_Fini(cfg_builder* g) +{ + assert(cfg_builder_check(g)); + basicblock *b = g->g_block_list; + while (b != NULL) { + if (b->b_instr) { + PyObject_Free((void *)b->b_instr); + } + basicblock *next = b->b_list; + PyObject_Free((void *)b); + b = next; + } +} + +int +_PyCfgBuilder_UseLabel(cfg_builder *g, jump_target_label lbl) +{ + g->g_current_label = lbl; + return cfg_builder_maybe_start_new_block(g); +} + +int +_PyCfgBuilder_Addop(cfg_builder *g, int opcode, int oparg, location loc) +{ + RETURN_IF_ERROR(cfg_builder_maybe_start_new_block(g)); + return basicblock_addop(g->g_curblock, opcode, oparg, loc); +} + + +/***** debugging helpers *****/ + +#ifndef NDEBUG +static int remove_redundant_nops(basicblock *bb); + +/* +static bool +no_redundant_nops(cfg_builder *g) { + for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) { + if (remove_redundant_nops(b) != 0) { + return false; + } + } + return true; +} +*/ + +static bool +no_empty_basic_blocks(cfg_builder *g) { + for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) { + if (b->b_iused == 0) { + return false; + } + } + return true; +} + +static bool +no_redundant_jumps(cfg_builder *g) { + for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) { + cfg_instr *last = _PyCfg_BasicblockLastInstr(b); + if (last != NULL) { + if (IS_UNCONDITIONAL_JUMP_OPCODE(last->i_opcode)) { + assert(last->i_target != b->b_next); + if (last->i_target == b->b_next) { + return false; + } + } + } + } + return true; +} + +#endif + +/***** CFG preprocessing (jump targets and exceptions) *****/ + +static int +normalize_jumps_in_block(cfg_builder *g, basicblock *b) { + cfg_instr *last = _PyCfg_BasicblockLastInstr(b); + if (last == NULL || !is_jump(last)) { + return SUCCESS; + } + assert(!IS_ASSEMBLER_OPCODE(last->i_opcode)); + bool is_forward = last->i_target->b_visited == 0; + switch(last->i_opcode) { + case JUMP: + last->i_opcode = is_forward ? JUMP_FORWARD : JUMP_BACKWARD; + return SUCCESS; + case JUMP_NO_INTERRUPT: + last->i_opcode = is_forward ? + JUMP_FORWARD : JUMP_BACKWARD_NO_INTERRUPT; + return SUCCESS; + } + int reversed_opcode = 0; + switch(last->i_opcode) { + case POP_JUMP_IF_NOT_NONE: + reversed_opcode = POP_JUMP_IF_NONE; + break; + case POP_JUMP_IF_NONE: + reversed_opcode = POP_JUMP_IF_NOT_NONE; + break; + case POP_JUMP_IF_FALSE: + reversed_opcode = POP_JUMP_IF_TRUE; + break; + case POP_JUMP_IF_TRUE: + reversed_opcode = POP_JUMP_IF_FALSE; + break; + } + if (is_forward) { + return SUCCESS; + } + /* transform 'conditional jump T' to + * 'reversed_jump b_next' followed by 'jump_backwards T' + */ + + basicblock *target = last->i_target; + basicblock *backwards_jump = cfg_builder_new_block(g); + if (backwards_jump == NULL) { + return ERROR; + } + basicblock_addop(backwards_jump, JUMP, target->b_label.id, last->i_loc); + backwards_jump->b_instr[0].i_target = target; + last->i_opcode = reversed_opcode; + last->i_target = b->b_next; + + backwards_jump->b_cold = b->b_cold; + backwards_jump->b_next = b->b_next; + b->b_next = backwards_jump; + return SUCCESS; +} + + +static int +normalize_jumps(_PyCfgBuilder *g) +{ + basicblock *entryblock = g->g_entryblock; + for (basicblock *b = entryblock; b != NULL; b = b->b_next) { + b->b_visited = 0; + } + for (basicblock *b = entryblock; b != NULL; b = b->b_next) { + b->b_visited = 1; + RETURN_IF_ERROR(normalize_jumps_in_block(g, b)); + } + return SUCCESS; +} + +static void +resolve_jump_offsets(basicblock *entryblock) +{ + int bsize, totsize, extended_arg_recompile; + + /* Compute the size of each block and fixup jump args. + Replace block pointer with position in bytecode. */ + do { + totsize = 0; + for (basicblock *b = entryblock; b != NULL; b = b->b_next) { + bsize = blocksize(b); + b->b_offset = totsize; + totsize += bsize; + } + extended_arg_recompile = 0; + for (basicblock *b = entryblock; b != NULL; b = b->b_next) { + bsize = b->b_offset; + for (int i = 0; i < b->b_iused; i++) { + cfg_instr *instr = &b->b_instr[i]; + int isize = instr_size(instr); + /* jump offsets are computed relative to + * the instruction pointer after fetching + * the jump instruction. + */ + bsize += isize; + if (is_jump(instr)) { + instr->i_oparg = instr->i_target->b_offset; + if (instr->i_oparg < bsize) { + assert(IS_BACKWARDS_JUMP_OPCODE(instr->i_opcode)); + instr->i_oparg = bsize - instr->i_oparg; + } + else { + assert(!IS_BACKWARDS_JUMP_OPCODE(instr->i_opcode)); + instr->i_oparg -= bsize; + } + if (instr_size(instr) != isize) { + extended_arg_recompile = 1; + } + } + } + } + + /* XXX: This is an awful hack that could hurt performance, but + on the bright side it should work until we come up + with a better solution. + + The issue is that in the first loop blocksize() is called + which calls instr_size() which requires i_oparg be set + appropriately. There is a bootstrap problem because + i_oparg is calculated in the second loop above. + + So we loop until we stop seeing new EXTENDED_ARGs. + The only EXTENDED_ARGs that could be popping up are + ones in jump instructions. So this should converge + fairly quickly. + */ + } while (extended_arg_recompile); +} + +int +_PyCfg_ResolveJumps(_PyCfgBuilder *g) +{ + RETURN_IF_ERROR(normalize_jumps(g)); + assert(no_redundant_jumps(g)); + resolve_jump_offsets(g->g_entryblock); + return SUCCESS; +} + +static int +check_cfg(cfg_builder *g) { + for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) { + /* Raise SystemError if jump or exit is not last instruction in the block. */ + for (int i = 0; i < b->b_iused; i++) { + int opcode = b->b_instr[i].i_opcode; + assert(!IS_ASSEMBLER_OPCODE(opcode)); + if (IS_TERMINATOR_OPCODE(opcode)) { + if (i != b->b_iused - 1) { + PyErr_SetString(PyExc_SystemError, "malformed control flow graph."); + return ERROR; + } + } + } + } + return SUCCESS; +} + +static int +get_max_label(basicblock *entryblock) +{ + int lbl = -1; + for (basicblock *b = entryblock; b != NULL; b = b->b_next) { + if (b->b_label.id > lbl) { + lbl = b->b_label.id; + } + } + return lbl; +} + +/* Calculate the actual jump target from the target_label */ +static int +translate_jump_labels_to_targets(basicblock *entryblock) +{ + int max_label = get_max_label(entryblock); + size_t mapsize = sizeof(basicblock *) * (max_label + 1); + basicblock **label2block = (basicblock **)PyMem_Malloc(mapsize); + if (!label2block) { + PyErr_NoMemory(); + return ERROR; + } + memset(label2block, 0, mapsize); + for (basicblock *b = entryblock; b != NULL; b = b->b_next) { + if (b->b_label.id >= 0) { + label2block[b->b_label.id] = b; + } + } + for (basicblock *b = entryblock; b != NULL; b = b->b_next) { + for (int i = 0; i < b->b_iused; i++) { + cfg_instr *instr = &b->b_instr[i]; + assert(instr->i_target == NULL); + if (HAS_TARGET(instr->i_opcode)) { + int lbl = instr->i_oparg; + assert(lbl >= 0 && lbl <= max_label); + instr->i_target = label2block[lbl]; + assert(instr->i_target != NULL); + assert(instr->i_target->b_label.id == lbl); + } + } + } + PyMem_Free(label2block); + return SUCCESS; +} + +int +_PyCfg_JumpLabelsToTargets(basicblock *entryblock) +{ + return translate_jump_labels_to_targets(entryblock); +} + +static int +mark_except_handlers(basicblock *entryblock) { +#ifndef NDEBUG + for (basicblock *b = entryblock; b != NULL; b = b->b_next) { + assert(!b->b_except_handler); + } +#endif + for (basicblock *b = entryblock; b != NULL; b = b->b_next) { + for (int i=0; i < b->b_iused; i++) { + cfg_instr *instr = &b->b_instr[i]; + if (is_block_push(instr)) { + instr->i_target->b_except_handler = 1; + } + } + } + return SUCCESS; +} + + +typedef _PyCfgExceptStack ExceptStack; + +static basicblock * +push_except_block(ExceptStack *stack, cfg_instr *setup) { + assert(is_block_push(setup)); + int opcode = setup->i_opcode; + basicblock * target = setup->i_target; + if (opcode == SETUP_WITH || opcode == SETUP_CLEANUP) { + target->b_preserve_lasti = 1; + } + stack->handlers[++stack->depth] = target; + return target; +} + +static basicblock * +pop_except_block(ExceptStack *stack) { + assert(stack->depth > 0); + return stack->handlers[--stack->depth]; +} + +static basicblock * +except_stack_top(ExceptStack *stack) { + return stack->handlers[stack->depth]; +} + +static ExceptStack * +make_except_stack(void) { + ExceptStack *new = PyMem_Malloc(sizeof(ExceptStack)); + if (new == NULL) { + PyErr_NoMemory(); + return NULL; + } + new->depth = 0; + new->handlers[0] = NULL; + return new; +} + +static ExceptStack * +copy_except_stack(ExceptStack *stack) { + ExceptStack *copy = PyMem_Malloc(sizeof(ExceptStack)); + if (copy == NULL) { + PyErr_NoMemory(); + return NULL; + } + memcpy(copy, stack, sizeof(ExceptStack)); + return copy; +} + +static basicblock** +make_cfg_traversal_stack(basicblock *entryblock) { + int nblocks = 0; + for (basicblock *b = entryblock; b != NULL; b = b->b_next) { + b->b_visited = 0; + nblocks++; + } + basicblock **stack = (basicblock **)PyMem_Malloc(sizeof(basicblock *) * nblocks); + if (!stack) { + PyErr_NoMemory(); + } + return stack; +} + +Py_LOCAL_INLINE(void) +stackdepth_push(basicblock ***sp, basicblock *b, int depth) +{ + assert(b->b_startdepth < 0 || b->b_startdepth == depth); + if (b->b_startdepth < depth && b->b_startdepth < 100) { + assert(b->b_startdepth < 0); + b->b_startdepth = depth; + *(*sp)++ = b; + } +} + +/* Find the flow path that needs the largest stack. We assume that + * cycles in the flow graph have no net effect on the stack depth. + */ +int +_PyCfg_Stackdepth(basicblock *entryblock, int code_flags) +{ + for (basicblock *b = entryblock; b != NULL; b = b->b_next) { + b->b_startdepth = INT_MIN; + } + basicblock **stack = make_cfg_traversal_stack(entryblock); + if (!stack) { + return ERROR; + } + + int maxdepth = 0; + basicblock **sp = stack; + if (code_flags & (CO_GENERATOR | CO_COROUTINE | CO_ASYNC_GENERATOR)) { + stackdepth_push(&sp, entryblock, 1); + } else { + stackdepth_push(&sp, entryblock, 0); + } + + while (sp != stack) { + basicblock *b = *--sp; + int depth = b->b_startdepth; + assert(depth >= 0); + basicblock *next = b->b_next; + for (int i = 0; i < b->b_iused; i++) { + cfg_instr *instr = &b->b_instr[i]; + int effect = PyCompile_OpcodeStackEffectWithJump(instr->i_opcode, instr->i_oparg, 0); + if (effect == PY_INVALID_STACK_EFFECT) { + PyErr_Format(PyExc_SystemError, + "compiler PyCompile_OpcodeStackEffectWithJump(opcode=%d, arg=%i) failed", + instr->i_opcode, instr->i_oparg); + return ERROR; + } + int new_depth = depth + effect; + assert(new_depth >= 0); /* invalid code or bug in stackdepth() */ + if (new_depth > maxdepth) { + maxdepth = new_depth; + } + if (HAS_TARGET(instr->i_opcode)) { + effect = PyCompile_OpcodeStackEffectWithJump(instr->i_opcode, instr->i_oparg, 1); + assert(effect != PY_INVALID_STACK_EFFECT); + int target_depth = depth + effect; + assert(target_depth >= 0); /* invalid code or bug in stackdepth() */ + if (target_depth > maxdepth) { + maxdepth = target_depth; + } + stackdepth_push(&sp, instr->i_target, target_depth); + } + depth = new_depth; + assert(!IS_ASSEMBLER_OPCODE(instr->i_opcode)); + if (IS_UNCONDITIONAL_JUMP_OPCODE(instr->i_opcode) || + IS_SCOPE_EXIT_OPCODE(instr->i_opcode)) + { + /* remaining code is dead */ + next = NULL; + break; + } + } + if (next != NULL) { + assert(BB_HAS_FALLTHROUGH(b)); + stackdepth_push(&sp, next, depth); + } + } + PyMem_Free(stack); + return maxdepth; +} + +static int +label_exception_targets(basicblock *entryblock) { + basicblock **todo_stack = make_cfg_traversal_stack(entryblock); + if (todo_stack == NULL) { + return ERROR; + } + ExceptStack *except_stack = make_except_stack(); + if (except_stack == NULL) { + PyMem_Free(todo_stack); + PyErr_NoMemory(); + return ERROR; + } + except_stack->depth = 0; + todo_stack[0] = entryblock; + entryblock->b_visited = 1; + entryblock->b_exceptstack = except_stack; + basicblock **todo = &todo_stack[1]; + basicblock *handler = NULL; + while (todo > todo_stack) { + todo--; + basicblock *b = todo[0]; + assert(b->b_visited == 1); + except_stack = b->b_exceptstack; + assert(except_stack != NULL); + b->b_exceptstack = NULL; + handler = except_stack_top(except_stack); + for (int i = 0; i < b->b_iused; i++) { + cfg_instr *instr = &b->b_instr[i]; + if (is_block_push(instr)) { + if (!instr->i_target->b_visited) { + ExceptStack *copy = copy_except_stack(except_stack); + if (copy == NULL) { + goto error; + } + instr->i_target->b_exceptstack = copy; + todo[0] = instr->i_target; + instr->i_target->b_visited = 1; + todo++; + } + handler = push_except_block(except_stack, instr); + } + else if (instr->i_opcode == POP_BLOCK) { + handler = pop_except_block(except_stack); + } + else if (is_jump(instr)) { + instr->i_except = handler; + assert(i == b->b_iused -1); + if (!instr->i_target->b_visited) { + if (BB_HAS_FALLTHROUGH(b)) { + ExceptStack *copy = copy_except_stack(except_stack); + if (copy == NULL) { + goto error; + } + instr->i_target->b_exceptstack = copy; + } + else { + instr->i_target->b_exceptstack = except_stack; + except_stack = NULL; + } + todo[0] = instr->i_target; + instr->i_target->b_visited = 1; + todo++; + } + } + else { + if (instr->i_opcode == YIELD_VALUE) { + instr->i_oparg = except_stack->depth; + } + instr->i_except = handler; + } + } + if (BB_HAS_FALLTHROUGH(b) && !b->b_next->b_visited) { + assert(except_stack != NULL); + b->b_next->b_exceptstack = except_stack; + todo[0] = b->b_next; + b->b_next->b_visited = 1; + todo++; + } + else if (except_stack != NULL) { + PyMem_Free(except_stack); + } + } +#ifdef Py_DEBUG + for (basicblock *b = entryblock; b != NULL; b = b->b_next) { + assert(b->b_exceptstack == NULL); + } +#endif + PyMem_Free(todo_stack); + return SUCCESS; +error: + PyMem_Free(todo_stack); + PyMem_Free(except_stack); + return ERROR; +} + +/***** CFG optimizations *****/ + +static int +mark_reachable(basicblock *entryblock) { + basicblock **stack = make_cfg_traversal_stack(entryblock); + if (stack == NULL) { + return ERROR; + } + basicblock **sp = stack; + entryblock->b_predecessors = 1; + *sp++ = entryblock; + while (sp > stack) { + basicblock *b = *(--sp); + b->b_visited = 1; + if (b->b_next && BB_HAS_FALLTHROUGH(b)) { + if (!b->b_next->b_visited) { + assert(b->b_next->b_predecessors == 0); + *sp++ = b->b_next; + } + b->b_next->b_predecessors++; + } + for (int i = 0; i < b->b_iused; i++) { + basicblock *target; + cfg_instr *instr = &b->b_instr[i]; + if (is_jump(instr) || is_block_push(instr)) { + target = instr->i_target; + if (!target->b_visited) { + assert(target->b_predecessors == 0 || target == b->b_next); + *sp++ = target; + } + target->b_predecessors++; + } + } + } + PyMem_Free(stack); + return SUCCESS; +} + +static void +eliminate_empty_basic_blocks(cfg_builder *g) { + /* Eliminate empty blocks */ + for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) { + basicblock *next = b->b_next; + while (next && next->b_iused == 0) { + next = next->b_next; + } + b->b_next = next; + } + while(g->g_entryblock && g->g_entryblock->b_iused == 0) { + g->g_entryblock = g->g_entryblock->b_next; + } + int next_lbl = get_max_label(g->g_entryblock) + 1; + for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) { + assert(b->b_iused > 0); + for (int i = 0; i < b->b_iused; i++) { + cfg_instr *instr = &b->b_instr[i]; + if (HAS_TARGET(instr->i_opcode)) { + basicblock *target = instr->i_target; + while (target->b_iused == 0) { + target = target->b_next; + } + if (instr->i_target != target) { + if (!IS_LABEL(target->b_label)) { + target->b_label.id = next_lbl++; + } + instr->i_target = target; + instr->i_oparg = target->b_label.id; + } + assert(instr->i_target && instr->i_target->b_iused > 0); + } + } + } +} + +static int +remove_redundant_nops(basicblock *bb) { + /* Remove NOPs when legal to do so. */ + int dest = 0; + int prev_lineno = -1; + for (int src = 0; src < bb->b_iused; src++) { + int lineno = bb->b_instr[src].i_loc.lineno; + if (bb->b_instr[src].i_opcode == NOP) { + /* Eliminate no-op if it doesn't have a line number */ + if (lineno < 0) { + continue; + } + /* or, if the previous instruction had the same line number. */ + if (prev_lineno == lineno) { + continue; + } + /* or, if the next instruction has same line number or no line number */ + if (src < bb->b_iused - 1) { + int next_lineno = bb->b_instr[src+1].i_loc.lineno; + if (next_lineno == lineno) { + continue; + } + if (next_lineno < 0) { + bb->b_instr[src+1].i_loc = bb->b_instr[src].i_loc; + continue; + } + } + else { + basicblock* next = bb->b_next; + while (next && next->b_iused == 0) { + next = next->b_next; + } + /* or if last instruction in BB and next BB has same line number */ + if (next) { + if (lineno == next->b_instr[0].i_loc.lineno) { + continue; + } + } + } + + } + if (dest != src) { + bb->b_instr[dest] = bb->b_instr[src]; + } + dest++; + prev_lineno = lineno; + } + assert(dest <= bb->b_iused); + int num_removed = bb->b_iused - dest; + bb->b_iused = dest; + return num_removed; +} + +static int +remove_redundant_nops_and_pairs(basicblock *entryblock) +{ + bool done = false; + + while (! done) { + done = true; + cfg_instr *prev_instr = NULL; + cfg_instr *instr = NULL; + for (basicblock *b = entryblock; b != NULL; b = b->b_next) { + remove_redundant_nops(b); + if (IS_LABEL(b->b_label)) { + /* this block is a jump target, forget instr */ + instr = NULL; + } + for (int i = 0; i < b->b_iused; i++) { + prev_instr = instr; + instr = &b->b_instr[i]; + int prev_opcode = prev_instr ? prev_instr->i_opcode : 0; + int prev_oparg = prev_instr ? prev_instr->i_oparg : 0; + int opcode = instr->i_opcode; + bool is_redundant_pair = false; + if (opcode == POP_TOP) { + if (prev_opcode == LOAD_CONST) { + is_redundant_pair = true; + } + else if (prev_opcode == COPY && prev_oparg == 1) { + is_redundant_pair = true; + } + } + if (is_redundant_pair) { + INSTR_SET_OP0(prev_instr, NOP); + INSTR_SET_OP0(instr, NOP); + done = false; + } + } + if ((instr && is_jump(instr)) || !BB_HAS_FALLTHROUGH(b)) { + instr = NULL; + } + } + } + return SUCCESS; +} + +static int +remove_redundant_jumps(cfg_builder *g) { + /* If a non-empty block ends with a jump instruction, check if the next + * non-empty block reached through normal flow control is the target + * of that jump. If it is, then the jump instruction is redundant and + * can be deleted. + */ + assert(no_empty_basic_blocks(g)); + for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) { + cfg_instr *last = _PyCfg_BasicblockLastInstr(b); + assert(last != NULL); + assert(!IS_ASSEMBLER_OPCODE(last->i_opcode)); + if (IS_UNCONDITIONAL_JUMP_OPCODE(last->i_opcode)) { + if (last->i_target == NULL) { + PyErr_SetString(PyExc_SystemError, "jump with NULL target"); + return ERROR; + } + if (last->i_target == b->b_next) { + assert(b->b_next->b_iused); + INSTR_SET_OP0(last, NOP); + } + } + } + return SUCCESS; +} + +/* Maximum size of basic block that should be copied in optimizer */ +#define MAX_COPY_SIZE 4 + +/* If this block ends with an unconditional jump to a small exit block, then + * remove the jump and extend this block with the target. + * Returns 1 if extended, 0 if no change, and -1 on error. + */ +static int +inline_small_exit_blocks(basicblock *bb) { + cfg_instr *last = _PyCfg_BasicblockLastInstr(bb); + if (last == NULL) { + return 0; + } + if (!IS_UNCONDITIONAL_JUMP_OPCODE(last->i_opcode)) { + return 0; + } + basicblock *target = last->i_target; + if (basicblock_exits_scope(target) && target->b_iused <= MAX_COPY_SIZE) { + INSTR_SET_OP0(last, NOP); + RETURN_IF_ERROR(basicblock_append_instructions(bb, target)); + return 1; + } + return 0; +} + +// Attempt to eliminate jumps to jumps by updating inst to jump to +// target->i_target using the provided opcode. Return whether or not the +// optimization was successful. +static bool +jump_thread(cfg_instr *inst, cfg_instr *target, int opcode) +{ + assert(is_jump(inst)); + assert(is_jump(target)); + // bpo-45773: If inst->i_target == target->i_target, then nothing actually + // changes (and we fall into an infinite loop): + if ((inst->i_loc.lineno == target->i_loc.lineno || target->i_loc.lineno == -1) && + inst->i_target != target->i_target) + { + inst->i_target = target->i_target; + inst->i_opcode = opcode; + return true; + } + return false; +} + +static PyObject* +get_const_value(int opcode, int oparg, PyObject *co_consts) +{ + PyObject *constant = NULL; + assert(HAS_CONST(opcode)); + if (opcode == LOAD_CONST) { + constant = PyList_GET_ITEM(co_consts, oparg); + } + + if (constant == NULL) { + PyErr_SetString(PyExc_SystemError, + "Internal error: failed to get value of a constant"); + return NULL; + } + return Py_NewRef(constant); +} + +/* Replace LOAD_CONST c1, LOAD_CONST c2 ... LOAD_CONST cn, BUILD_TUPLE n + with LOAD_CONST (c1, c2, ... cn). + The consts table must still be in list form so that the + new constant (c1, c2, ... cn) can be appended. + Called with codestr pointing to the first LOAD_CONST. +*/ +static int +fold_tuple_on_constants(PyObject *const_cache, + cfg_instr *inst, + int n, PyObject *consts) +{ + /* Pre-conditions */ + assert(PyDict_CheckExact(const_cache)); + assert(PyList_CheckExact(consts)); + assert(inst[n].i_opcode == BUILD_TUPLE); + assert(inst[n].i_oparg == n); + + for (int i = 0; i < n; i++) { + if (!HAS_CONST(inst[i].i_opcode)) { + return SUCCESS; + } + } + + /* Buildup new tuple of constants */ + PyObject *newconst = PyTuple_New(n); + if (newconst == NULL) { + return ERROR; + } + for (int i = 0; i < n; i++) { + int op = inst[i].i_opcode; + int arg = inst[i].i_oparg; + PyObject *constant = get_const_value(op, arg, consts); + if (constant == NULL) { + return ERROR; + } + PyTuple_SET_ITEM(newconst, i, constant); + } + if (_PyCompile_ConstCacheMergeOne(const_cache, &newconst) < 0) { + Py_DECREF(newconst); + return ERROR; + } + + Py_ssize_t index; + for (index = 0; index < PyList_GET_SIZE(consts); index++) { + if (PyList_GET_ITEM(consts, index) == newconst) { + break; + } + } + if (index == PyList_GET_SIZE(consts)) { + if ((size_t)index >= (size_t)INT_MAX - 1) { + Py_DECREF(newconst); + PyErr_SetString(PyExc_OverflowError, "too many constants"); + return ERROR; + } + if (PyList_Append(consts, newconst)) { + Py_DECREF(newconst); + return ERROR; + } + } + Py_DECREF(newconst); + for (int i = 0; i < n; i++) { + INSTR_SET_OP0(&inst[i], NOP); + } + INSTR_SET_OP1(&inst[n], LOAD_CONST, (int)index); + return SUCCESS; +} + +#define VISITED (-1) + +// Replace an arbitrary run of SWAPs and NOPs with an optimal one that has the +// same effect. +static int +swaptimize(basicblock *block, int *ix) +{ + // NOTE: "./python -m test test_patma" serves as a good, quick stress test + // for this function. Make sure to blow away cached *.pyc files first! + assert(*ix < block->b_iused); + cfg_instr *instructions = &block->b_instr[*ix]; + // Find the length of the current sequence of SWAPs and NOPs, and record the + // maximum depth of the stack manipulations: + assert(instructions[0].i_opcode == SWAP); + int depth = instructions[0].i_oparg; + int len = 0; + int more = false; + int limit = block->b_iused - *ix; + while (++len < limit) { + int opcode = instructions[len].i_opcode; + if (opcode == SWAP) { + depth = Py_MAX(depth, instructions[len].i_oparg); + more = true; + } + else if (opcode != NOP) { + break; + } + } + // It's already optimal if there's only one SWAP: + if (!more) { + return SUCCESS; + } + // Create an array with elements {0, 1, 2, ..., depth - 1}: + int *stack = PyMem_Malloc(depth * sizeof(int)); + if (stack == NULL) { + PyErr_NoMemory(); + return ERROR; + } + for (int i = 0; i < depth; i++) { + stack[i] = i; + } + // Simulate the combined effect of these instructions by "running" them on + // our "stack": + for (int i = 0; i < len; i++) { + if (instructions[i].i_opcode == SWAP) { + int oparg = instructions[i].i_oparg; + int top = stack[0]; + // SWAPs are 1-indexed: + stack[0] = stack[oparg - 1]; + stack[oparg - 1] = top; + } + } + // Now we can begin! Our approach here is based on a solution to a closely + // related problem (https://cs.stackexchange.com/a/13938). It's easiest to + // think of this algorithm as determining the steps needed to efficiently + // "un-shuffle" our stack. By performing the moves in *reverse* order, + // though, we can efficiently *shuffle* it! For this reason, we will be + // replacing instructions starting from the *end* of the run. Since the + // solution is optimal, we don't need to worry about running out of space: + int current = len - 1; + for (int i = 0; i < depth; i++) { + // Skip items that have already been visited, or just happen to be in + // the correct location: + if (stack[i] == VISITED || stack[i] == i) { + continue; + } + // Okay, we've found an item that hasn't been visited. It forms a cycle + // with other items; traversing the cycle and swapping each item with + // the next will put them all in the correct place. The weird + // loop-and-a-half is necessary to insert 0 into every cycle, since we + // can only swap from that position: + int j = i; + while (true) { + // Skip the actual swap if our item is zero, since swapping the top + // item with itself is pointless: + if (j) { + assert(0 <= current); + // SWAPs are 1-indexed: + instructions[current].i_opcode = SWAP; + instructions[current--].i_oparg = j + 1; + } + if (stack[j] == VISITED) { + // Completed the cycle: + assert(j == i); + break; + } + int next_j = stack[j]; + stack[j] = VISITED; + j = next_j; + } + } + // NOP out any unused instructions: + while (0 <= current) { + INSTR_SET_OP0(&instructions[current--], NOP); + } + PyMem_Free(stack); + *ix += len - 1; + return SUCCESS; +} + + +// This list is pretty small, since it's only okay to reorder opcodes that: +// - can't affect control flow (like jumping or raising exceptions) +// - can't invoke arbitrary code (besides finalizers) +// - only touch the TOS (and pop it when finished) +#define SWAPPABLE(opcode) \ + ((opcode) == STORE_FAST || \ + (opcode) == STORE_FAST_MAYBE_NULL || \ + (opcode) == POP_TOP) + +#define STORES_TO(instr) \ + (((instr).i_opcode == STORE_FAST || \ + (instr).i_opcode == STORE_FAST_MAYBE_NULL) \ + ? (instr).i_oparg : -1) + +static int +next_swappable_instruction(basicblock *block, int i, int lineno) +{ + while (++i < block->b_iused) { + cfg_instr *instruction = &block->b_instr[i]; + if (0 <= lineno && instruction->i_loc.lineno != lineno) { + // Optimizing across this instruction could cause user-visible + // changes in the names bound between line tracing events! + return -1; + } + if (instruction->i_opcode == NOP) { + continue; + } + if (SWAPPABLE(instruction->i_opcode)) { + return i; + } + return -1; + } + return -1; +} + +// Attempt to apply SWAPs statically by swapping *instructions* rather than +// stack items. For example, we can replace SWAP(2), POP_TOP, STORE_FAST(42) +// with the more efficient NOP, STORE_FAST(42), POP_TOP. +static void +apply_static_swaps(basicblock *block, int i) +{ + // SWAPs are to our left, and potential swaperands are to our right: + for (; 0 <= i; i--) { + assert(i < block->b_iused); + cfg_instr *swap = &block->b_instr[i]; + if (swap->i_opcode != SWAP) { + if (swap->i_opcode == NOP || SWAPPABLE(swap->i_opcode)) { + // Nope, but we know how to handle these. Keep looking: + continue; + } + // We can't reason about what this instruction does. Bail: + return; + } + int j = next_swappable_instruction(block, i, -1); + if (j < 0) { + return; + } + int k = j; + int lineno = block->b_instr[j].i_loc.lineno; + for (int count = swap->i_oparg - 1; 0 < count; count--) { + k = next_swappable_instruction(block, k, lineno); + if (k < 0) { + return; + } + } + // The reordering is not safe if the two instructions to be swapped + // store to the same location, or if any intervening instruction stores + // to the same location as either of them. + int store_j = STORES_TO(block->b_instr[j]); + int store_k = STORES_TO(block->b_instr[k]); + if (store_j >= 0 || store_k >= 0) { + if (store_j == store_k) { + return; + } + for (int idx = j + 1; idx < k; idx++) { + int store_idx = STORES_TO(block->b_instr[idx]); + if (store_idx >= 0 && (store_idx == store_j || store_idx == store_k)) { + return; + } + } + } + + // Success! + INSTR_SET_OP0(swap, NOP); + cfg_instr temp = block->b_instr[j]; + block->b_instr[j] = block->b_instr[k]; + block->b_instr[k] = temp; + } +} + +static int +optimize_basic_block(PyObject *const_cache, basicblock *bb, PyObject *consts) +{ + assert(PyDict_CheckExact(const_cache)); + assert(PyList_CheckExact(consts)); + cfg_instr nop; + INSTR_SET_OP0(&nop, NOP); + cfg_instr *target = &nop; + int opcode = 0; + int oparg = 0; + int nextop = 0; + for (int i = 0; i < bb->b_iused; i++) { + cfg_instr *inst = &bb->b_instr[i]; + bool is_copy_of_load_const = (opcode == LOAD_CONST && + inst->i_opcode == COPY && + inst->i_oparg == 1); + if (! is_copy_of_load_const) { + opcode = inst->i_opcode; + oparg = inst->i_oparg; + if (HAS_TARGET(opcode)) { + assert(inst->i_target->b_iused > 0); + target = &inst->i_target->b_instr[0]; + assert(!IS_ASSEMBLER_OPCODE(target->i_opcode)); + } + else { + target = &nop; + } + } + nextop = i+1 < bb->b_iused ? bb->b_instr[i+1].i_opcode : 0; + assert(!IS_ASSEMBLER_OPCODE(opcode)); + switch (opcode) { + /* Remove LOAD_CONST const; conditional jump */ + case LOAD_CONST: + { + PyObject* cnt; + int is_true; + int jump_if_true; + switch(nextop) { + case POP_JUMP_IF_FALSE: + case POP_JUMP_IF_TRUE: + cnt = get_const_value(opcode, oparg, consts); + if (cnt == NULL) { + goto error; + } + is_true = PyObject_IsTrue(cnt); + Py_DECREF(cnt); + if (is_true == -1) { + goto error; + } + INSTR_SET_OP0(inst, NOP); + jump_if_true = nextop == POP_JUMP_IF_TRUE; + if (is_true == jump_if_true) { + bb->b_instr[i+1].i_opcode = JUMP; + } + else { + INSTR_SET_OP0(&bb->b_instr[i + 1], NOP); + } + break; + case IS_OP: + cnt = get_const_value(opcode, oparg, consts); + if (cnt == NULL) { + goto error; + } + int jump_op = i+2 < bb->b_iused ? bb->b_instr[i+2].i_opcode : 0; + if (Py_IsNone(cnt) && (jump_op == POP_JUMP_IF_FALSE || jump_op == POP_JUMP_IF_TRUE)) { + unsigned char nextarg = bb->b_instr[i+1].i_oparg; + INSTR_SET_OP0(inst, NOP); + INSTR_SET_OP0(&bb->b_instr[i + 1], NOP); + bb->b_instr[i+2].i_opcode = nextarg ^ (jump_op == POP_JUMP_IF_FALSE) ? + POP_JUMP_IF_NOT_NONE : POP_JUMP_IF_NONE; + } + Py_DECREF(cnt); + break; + case RETURN_VALUE: + INSTR_SET_OP0(inst, NOP); + INSTR_SET_OP1(&bb->b_instr[++i], RETURN_CONST, oparg); + break; + } + break; + } + /* Try to fold tuples of constants. + Skip over BUILD_TUPLE(1) UNPACK_SEQUENCE(1). + Replace BUILD_TUPLE(2) UNPACK_SEQUENCE(2) with SWAP(2). + Replace BUILD_TUPLE(3) UNPACK_SEQUENCE(3) with SWAP(3). */ + case BUILD_TUPLE: + if (nextop == UNPACK_SEQUENCE && oparg == bb->b_instr[i+1].i_oparg) { + switch(oparg) { + case 1: + INSTR_SET_OP0(inst, NOP); + INSTR_SET_OP0(&bb->b_instr[i + 1], NOP); + continue; + case 2: + case 3: + INSTR_SET_OP0(inst, NOP); + bb->b_instr[i+1].i_opcode = SWAP; + continue; + } + } + if (i >= oparg) { + if (fold_tuple_on_constants(const_cache, inst-oparg, oparg, consts)) { + goto error; + } + } + break; + case POP_JUMP_IF_NOT_NONE: + case POP_JUMP_IF_NONE: + switch (target->i_opcode) { + case JUMP: + i -= jump_thread(inst, target, inst->i_opcode); + } + break; + case POP_JUMP_IF_FALSE: + switch (target->i_opcode) { + case JUMP: + i -= jump_thread(inst, target, POP_JUMP_IF_FALSE); + } + break; + case POP_JUMP_IF_TRUE: + switch (target->i_opcode) { + case JUMP: + i -= jump_thread(inst, target, POP_JUMP_IF_TRUE); + } + break; + case JUMP: + switch (target->i_opcode) { + case JUMP: + i -= jump_thread(inst, target, JUMP); + } + break; + case FOR_ITER: + if (target->i_opcode == JUMP) { + /* This will not work now because the jump (at target) could + * be forward or backward and FOR_ITER only jumps forward. We + * can re-enable this if ever we implement a backward version + * of FOR_ITER. + */ + /* + i -= jump_thread(inst, target, FOR_ITER); + */ + } + break; + case SWAP: + if (oparg == 1) { + INSTR_SET_OP0(inst, NOP); + break; + } + if (swaptimize(bb, &i) < 0) { + goto error; + } + apply_static_swaps(bb, i); + break; + case KW_NAMES: + break; + case PUSH_NULL: + if (nextop == LOAD_GLOBAL && (inst[1].i_opcode & 1) == 0) { + INSTR_SET_OP0(inst, NOP); + inst[1].i_oparg |= 1; + } + break; + default: + /* All HAS_CONST opcodes should be handled with LOAD_CONST */ + assert (!HAS_CONST(inst->i_opcode)); + } + } + return SUCCESS; +error: + return ERROR; +} + + +/* Perform optimizations on a control flow graph. + The consts object should still be in list form to allow new constants + to be appended. + + Code trasnformations that reduce code size initially fill the gaps with + NOPs. Later those NOPs are removed. +*/ +static int +optimize_cfg(cfg_builder *g, PyObject *consts, PyObject *const_cache) +{ + assert(PyDict_CheckExact(const_cache)); + RETURN_IF_ERROR(check_cfg(g)); + eliminate_empty_basic_blocks(g); + for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) { + RETURN_IF_ERROR(inline_small_exit_blocks(b)); + } + assert(no_empty_basic_blocks(g)); + for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) { + RETURN_IF_ERROR(optimize_basic_block(const_cache, b, consts)); + assert(b->b_predecessors == 0); + } + RETURN_IF_ERROR(remove_redundant_nops_and_pairs(g->g_entryblock)); + for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) { + RETURN_IF_ERROR(inline_small_exit_blocks(b)); + } + RETURN_IF_ERROR(mark_reachable(g->g_entryblock)); + + /* Delete unreachable instructions */ + for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) { + if (b->b_predecessors == 0) { + b->b_iused = 0; + } + } + for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) { + remove_redundant_nops(b); + } + eliminate_empty_basic_blocks(g); + /* This assertion fails in an edge case (See gh-109889). + * Remove it for the release (it's just one more NOP in the + * bytecode for unlikely code). + */ + // assert(no_redundant_nops(g)); + RETURN_IF_ERROR(remove_redundant_jumps(g)); + return SUCCESS; +} + +// helper functions for add_checks_for_loads_of_unknown_variables +static inline void +maybe_push(basicblock *b, uint64_t unsafe_mask, basicblock ***sp) +{ + // Push b if the unsafe mask is giving us any new information. + // To avoid overflowing the stack, only allow each block once. + // Use b->b_visited=1 to mean that b is currently on the stack. + uint64_t both = b->b_unsafe_locals_mask | unsafe_mask; + if (b->b_unsafe_locals_mask != both) { + b->b_unsafe_locals_mask = both; + // More work left to do. + if (!b->b_visited) { + // not on the stack, so push it. + *(*sp)++ = b; + b->b_visited = 1; + } + } +} + +static void +scan_block_for_locals(basicblock *b, basicblock ***sp) +{ + // bit i is set if local i is potentially uninitialized + uint64_t unsafe_mask = b->b_unsafe_locals_mask; + for (int i = 0; i < b->b_iused; i++) { + cfg_instr *instr = &b->b_instr[i]; + assert(instr->i_opcode != EXTENDED_ARG); + assert(!IS_SUPERINSTRUCTION_OPCODE(instr->i_opcode)); + if (instr->i_except != NULL) { + maybe_push(instr->i_except, unsafe_mask, sp); + } + if (instr->i_oparg >= 64) { + continue; + } + assert(instr->i_oparg >= 0); + uint64_t bit = (uint64_t)1 << instr->i_oparg; + switch (instr->i_opcode) { + case DELETE_FAST: + case LOAD_FAST_AND_CLEAR: + case STORE_FAST_MAYBE_NULL: + unsafe_mask |= bit; + break; + case STORE_FAST: + unsafe_mask &= ~bit; + break; + case LOAD_FAST_CHECK: + // If this doesn't raise, then the local is defined. + unsafe_mask &= ~bit; + break; + case LOAD_FAST: + if (unsafe_mask & bit) { + instr->i_opcode = LOAD_FAST_CHECK; + } + unsafe_mask &= ~bit; + break; + } + } + if (b->b_next && BB_HAS_FALLTHROUGH(b)) { + maybe_push(b->b_next, unsafe_mask, sp); + } + cfg_instr *last = _PyCfg_BasicblockLastInstr(b); + if (last && is_jump(last)) { + assert(last->i_target != NULL); + maybe_push(last->i_target, unsafe_mask, sp); + } +} + +static int +fast_scan_many_locals(basicblock *entryblock, int nlocals) +{ + assert(nlocals > 64); + Py_ssize_t *states = PyMem_Calloc(nlocals - 64, sizeof(Py_ssize_t)); + if (states == NULL) { + PyErr_NoMemory(); + return ERROR; + } + Py_ssize_t blocknum = 0; + // state[i - 64] == blocknum if local i is guaranteed to + // be initialized, i.e., if it has had a previous LOAD_FAST or + // STORE_FAST within that basicblock (not followed by + // DELETE_FAST/LOAD_FAST_AND_CLEAR/STORE_FAST_MAYBE_NULL). + for (basicblock *b = entryblock; b != NULL; b = b->b_next) { + blocknum++; + for (int i = 0; i < b->b_iused; i++) { + cfg_instr *instr = &b->b_instr[i]; + assert(instr->i_opcode != EXTENDED_ARG); + assert(!IS_SUPERINSTRUCTION_OPCODE(instr->i_opcode)); + int arg = instr->i_oparg; + if (arg < 64) { + continue; + } + assert(arg >= 0); + switch (instr->i_opcode) { + case DELETE_FAST: + case LOAD_FAST_AND_CLEAR: + case STORE_FAST_MAYBE_NULL: + states[arg - 64] = blocknum - 1; + break; + case STORE_FAST: + states[arg - 64] = blocknum; + break; + case LOAD_FAST: + if (states[arg - 64] != blocknum) { + instr->i_opcode = LOAD_FAST_CHECK; + } + states[arg - 64] = blocknum; + break; + Py_UNREACHABLE(); + } + } + } + PyMem_Free(states); + return SUCCESS; +} + +static int +remove_unused_consts(basicblock *entryblock, PyObject *consts) +{ + assert(PyList_CheckExact(consts)); + Py_ssize_t nconsts = PyList_GET_SIZE(consts); + if (nconsts == 0) { + return SUCCESS; /* nothing to do */ + } + + Py_ssize_t *index_map = NULL; + Py_ssize_t *reverse_index_map = NULL; + int err = ERROR; + + index_map = PyMem_Malloc(nconsts * sizeof(Py_ssize_t)); + if (index_map == NULL) { + goto end; + } + for (Py_ssize_t i = 1; i < nconsts; i++) { + index_map[i] = -1; + } + // The first constant may be docstring; keep it always. + index_map[0] = 0; + + /* mark used consts */ + for (basicblock *b = entryblock; b != NULL; b = b->b_next) { + for (int i = 0; i < b->b_iused; i++) { + if (HAS_CONST(b->b_instr[i].i_opcode)) { + int index = b->b_instr[i].i_oparg; + index_map[index] = index; + } + } + } + /* now index_map[i] == i if consts[i] is used, -1 otherwise */ + /* condense consts */ + Py_ssize_t n_used_consts = 0; + for (int i = 0; i < nconsts; i++) { + if (index_map[i] != -1) { + assert(index_map[i] == i); + index_map[n_used_consts++] = index_map[i]; + } + } + if (n_used_consts == nconsts) { + /* nothing to do */ + err = SUCCESS; + goto end; + } + + /* move all used consts to the beginning of the consts list */ + assert(n_used_consts < nconsts); + for (Py_ssize_t i = 0; i < n_used_consts; i++) { + Py_ssize_t old_index = index_map[i]; + assert(i <= old_index && old_index < nconsts); + if (i != old_index) { + PyObject *value = PyList_GET_ITEM(consts, index_map[i]); + assert(value != NULL); + PyList_SetItem(consts, i, Py_NewRef(value)); + } + } + + /* truncate the consts list at its new size */ + if (PyList_SetSlice(consts, n_used_consts, nconsts, NULL) < 0) { + goto end; + } + /* adjust const indices in the bytecode */ + reverse_index_map = PyMem_Malloc(nconsts * sizeof(Py_ssize_t)); + if (reverse_index_map == NULL) { + goto end; + } + for (Py_ssize_t i = 0; i < nconsts; i++) { + reverse_index_map[i] = -1; + } + for (Py_ssize_t i = 0; i < n_used_consts; i++) { + assert(index_map[i] != -1); + assert(reverse_index_map[index_map[i]] == -1); + reverse_index_map[index_map[i]] = i; + } + + for (basicblock *b = entryblock; b != NULL; b = b->b_next) { + for (int i = 0; i < b->b_iused; i++) { + if (HAS_CONST(b->b_instr[i].i_opcode)) { + int index = b->b_instr[i].i_oparg; + assert(reverse_index_map[index] >= 0); + assert(reverse_index_map[index] < n_used_consts); + b->b_instr[i].i_oparg = (int)reverse_index_map[index]; + } + } + } + + err = SUCCESS; +end: + PyMem_Free(index_map); + PyMem_Free(reverse_index_map); + return err; +} + + + +static int +add_checks_for_loads_of_uninitialized_variables(basicblock *entryblock, + int nlocals, + int nparams) +{ + if (nlocals == 0) { + return SUCCESS; + } + if (nlocals > 64) { + // To avoid O(nlocals**2) compilation, locals beyond the first + // 64 are only analyzed one basicblock at a time: initialization + // info is not passed between basicblocks. + if (fast_scan_many_locals(entryblock, nlocals) < 0) { + return ERROR; + } + nlocals = 64; + } + basicblock **stack = make_cfg_traversal_stack(entryblock); + if (stack == NULL) { + return ERROR; + } + basicblock **sp = stack; + + // First origin of being uninitialized: + // The non-parameter locals in the entry block. + uint64_t start_mask = 0; + for (int i = nparams; i < nlocals; i++) { + start_mask |= (uint64_t)1 << i; + } + maybe_push(entryblock, start_mask, &sp); + + // Second origin of being uninitialized: + // There could be DELETE_FAST somewhere, so + // be sure to scan each basicblock at least once. + for (basicblock *b = entryblock; b != NULL; b = b->b_next) { + scan_block_for_locals(b, &sp); + } + // Now propagate the uncertainty from the origins we found: Use + // LOAD_FAST_CHECK for any LOAD_FAST where the local could be undefined. + while (sp > stack) { + basicblock *b = *--sp; + // mark as no longer on stack + b->b_visited = 0; + scan_block_for_locals(b, &sp); + } + PyMem_Free(stack); + return SUCCESS; +} + + +static int +mark_warm(basicblock *entryblock) { + basicblock **stack = make_cfg_traversal_stack(entryblock); + if (stack == NULL) { + return ERROR; + } + basicblock **sp = stack; + + *sp++ = entryblock; + entryblock->b_visited = 1; + while (sp > stack) { + basicblock *b = *(--sp); + assert(!b->b_except_handler); + b->b_warm = 1; + basicblock *next = b->b_next; + if (next && BB_HAS_FALLTHROUGH(b) && !next->b_visited) { + *sp++ = next; + next->b_visited = 1; + } + for (int i=0; i < b->b_iused; i++) { + cfg_instr *instr = &b->b_instr[i]; + if (is_jump(instr) && !instr->i_target->b_visited) { + *sp++ = instr->i_target; + instr->i_target->b_visited = 1; + } + } + } + PyMem_Free(stack); + return SUCCESS; +} + +static int +mark_cold(basicblock *entryblock) { + for (basicblock *b = entryblock; b != NULL; b = b->b_next) { + assert(!b->b_cold && !b->b_warm); + } + if (mark_warm(entryblock) < 0) { + return ERROR; + } + + basicblock **stack = make_cfg_traversal_stack(entryblock); + if (stack == NULL) { + return ERROR; + } + + basicblock **sp = stack; + for (basicblock *b = entryblock; b != NULL; b = b->b_next) { + if (b->b_except_handler) { + assert(!b->b_warm); + *sp++ = b; + b->b_visited = 1; + } + } + + while (sp > stack) { + basicblock *b = *(--sp); + b->b_cold = 1; + basicblock *next = b->b_next; + if (next && BB_HAS_FALLTHROUGH(b)) { + if (!next->b_warm && !next->b_visited) { + *sp++ = next; + next->b_visited = 1; + } + } + for (int i = 0; i < b->b_iused; i++) { + cfg_instr *instr = &b->b_instr[i]; + if (is_jump(instr)) { + assert(i == b->b_iused - 1); + basicblock *target = b->b_instr[i].i_target; + if (!target->b_warm && !target->b_visited) { + *sp++ = target; + target->b_visited = 1; + } + } + } + } + PyMem_Free(stack); + return SUCCESS; +} + + +static int +push_cold_blocks_to_end(cfg_builder *g, int code_flags) { + basicblock *entryblock = g->g_entryblock; + if (entryblock->b_next == NULL) { + /* single basicblock, no need to reorder */ + return SUCCESS; + } + RETURN_IF_ERROR(mark_cold(entryblock)); + + int next_lbl = get_max_label(g->g_entryblock) + 1; + + /* If we have a cold block with fallthrough to a warm block, add */ + /* an explicit jump instead of fallthrough */ + for (basicblock *b = entryblock; b != NULL; b = b->b_next) { + if (b->b_cold && BB_HAS_FALLTHROUGH(b) && b->b_next && b->b_next->b_warm) { + basicblock *explicit_jump = cfg_builder_new_block(g); + if (explicit_jump == NULL) { + return ERROR; + } + if (!IS_LABEL(b->b_next->b_label)) { + b->b_next->b_label.id = next_lbl++; + } + basicblock_addop(explicit_jump, JUMP, b->b_next->b_label.id, NO_LOCATION); + explicit_jump->b_cold = 1; + explicit_jump->b_next = b->b_next; + b->b_next = explicit_jump; + + /* set target */ + cfg_instr *last = _PyCfg_BasicblockLastInstr(explicit_jump); + last->i_target = explicit_jump->b_next; + } + } + + assert(!entryblock->b_cold); /* First block can't be cold */ + basicblock *cold_blocks = NULL; + basicblock *cold_blocks_tail = NULL; + + basicblock *b = entryblock; + while(b->b_next) { + assert(!b->b_cold); + while (b->b_next && !b->b_next->b_cold) { + b = b->b_next; + } + if (b->b_next == NULL) { + /* no more cold blocks */ + break; + } + + /* b->b_next is the beginning of a cold streak */ + assert(!b->b_cold && b->b_next->b_cold); + + basicblock *b_end = b->b_next; + while (b_end->b_next && b_end->b_next->b_cold) { + b_end = b_end->b_next; + } + + /* b_end is the end of the cold streak */ + assert(b_end && b_end->b_cold); + assert(b_end->b_next == NULL || !b_end->b_next->b_cold); + + if (cold_blocks == NULL) { + cold_blocks = b->b_next; + } + else { + cold_blocks_tail->b_next = b->b_next; + } + cold_blocks_tail = b_end; + b->b_next = b_end->b_next; + b_end->b_next = NULL; + } + assert(b != NULL && b->b_next == NULL); + b->b_next = cold_blocks; + + if (cold_blocks != NULL) { + RETURN_IF_ERROR(remove_redundant_jumps(g)); + } + return SUCCESS; +} + +void +_PyCfg_ConvertPseudoOps(basicblock *entryblock) +{ + for (basicblock *b = entryblock; b != NULL; b = b->b_next) { + for (int i = 0; i < b->b_iused; i++) { + cfg_instr *instr = &b->b_instr[i]; + if (is_block_push(instr) || instr->i_opcode == POP_BLOCK) { + INSTR_SET_OP0(instr, NOP); + } + else if (instr->i_opcode == STORE_FAST_MAYBE_NULL) { + instr->i_opcode = STORE_FAST; + } + } + } + for (basicblock *b = entryblock; b != NULL; b = b->b_next) { + remove_redundant_nops(b); + } +} + +static inline bool +is_exit_without_lineno(basicblock *b) { + if (!basicblock_exits_scope(b)) { + return false; + } + for (int i = 0; i < b->b_iused; i++) { + if (b->b_instr[i].i_loc.lineno >= 0) { + return false; + } + } + return true; +} + + +/* PEP 626 mandates that the f_lineno of a frame is correct + * after a frame terminates. It would be prohibitively expensive + * to continuously update the f_lineno field at runtime, + * so we make sure that all exiting instruction (raises and returns) + * have a valid line number, allowing us to compute f_lineno lazily. + * We can do this by duplicating the exit blocks without line number + * so that none have more than one predecessor. We can then safely + * copy the line number from the sole predecessor block. + */ +static int +duplicate_exits_without_lineno(cfg_builder *g) +{ + assert(no_empty_basic_blocks(g)); + + int next_lbl = get_max_label(g->g_entryblock) + 1; + + /* Copy all exit blocks without line number that are targets of a jump. + */ + basicblock *entryblock = g->g_entryblock; + for (basicblock *b = entryblock; b != NULL; b = b->b_next) { + cfg_instr *last = _PyCfg_BasicblockLastInstr(b); + assert(last != NULL); + if (is_jump(last)) { + basicblock *target = last->i_target; + if (is_exit_without_lineno(target) && target->b_predecessors > 1) { + basicblock *new_target = copy_basicblock(g, target); + if (new_target == NULL) { + return ERROR; + } + new_target->b_instr[0].i_loc = last->i_loc; + last->i_target = new_target; + target->b_predecessors--; + new_target->b_predecessors = 1; + new_target->b_next = target->b_next; + new_target->b_label.id = next_lbl++; + target->b_next = new_target; + } + } + } + + /* Any remaining reachable exit blocks without line number can only be reached by + * fall through, and thus can only have a single predecessor */ + for (basicblock *b = entryblock; b != NULL; b = b->b_next) { + if (BB_HAS_FALLTHROUGH(b) && b->b_next && b->b_iused > 0) { + if (is_exit_without_lineno(b->b_next)) { + cfg_instr *last = _PyCfg_BasicblockLastInstr(b); + assert(last != NULL); + b->b_next->b_instr[0].i_loc = last->i_loc; + } + } + } + return SUCCESS; +} + + +/* If an instruction has no line number, but it's predecessor in the BB does, + * then copy the line number. If a successor block has no line number, and only + * one predecessor, then inherit the line number. + * This ensures that all exit blocks (with one predecessor) receive a line number. + * Also reduces the size of the line number table, + * but has no impact on the generated line number events. + */ +static void +propagate_line_numbers(basicblock *entryblock) { + for (basicblock *b = entryblock; b != NULL; b = b->b_next) { + cfg_instr *last = _PyCfg_BasicblockLastInstr(b); + if (last == NULL) { + continue; + } + + location prev_location = NO_LOCATION; + for (int i = 0; i < b->b_iused; i++) { + if (b->b_instr[i].i_loc.lineno < 0) { + b->b_instr[i].i_loc = prev_location; + } + else { + prev_location = b->b_instr[i].i_loc; + } + } + if (BB_HAS_FALLTHROUGH(b) && b->b_next->b_predecessors == 1) { + assert(b->b_next->b_iused); + if (b->b_next->b_instr[0].i_loc.lineno < 0) { + b->b_next->b_instr[0].i_loc = prev_location; + } + } + if (is_jump(last)) { + basicblock *target = last->i_target; + if (target->b_predecessors == 1) { + if (target->b_instr[0].i_loc.lineno < 0) { + target->b_instr[0].i_loc = prev_location; + } + } + } + } +} + +/* Make sure that all returns have a line number, even if early passes + * have failed to propagate a correct line number. + * The resulting line number may not be correct according to PEP 626, + * but should be "good enough", and no worse than in older versions. */ +static void +guarantee_lineno_for_exits(basicblock *entryblock, int firstlineno) { + int lineno = firstlineno; + assert(lineno > 0); + for (basicblock *b = entryblock; b != NULL; b = b->b_next) { + cfg_instr *last = _PyCfg_BasicblockLastInstr(b); + if (last == NULL) { + continue; + } + if (last->i_loc.lineno < 0) { + if (last->i_opcode == RETURN_VALUE) { + for (int i = 0; i < b->b_iused; i++) { + assert(b->b_instr[i].i_loc.lineno < 0); + + b->b_instr[i].i_loc.lineno = lineno; + } + } + } + else { + lineno = last->i_loc.lineno; + } + } +} + +static int +resolve_line_numbers(cfg_builder *g, int firstlineno) +{ + RETURN_IF_ERROR(duplicate_exits_without_lineno(g)); + propagate_line_numbers(g->g_entryblock); + guarantee_lineno_for_exits(g->g_entryblock, firstlineno); + return SUCCESS; +} + +int +_PyCfg_OptimizeCodeUnit(cfg_builder *g, PyObject *consts, PyObject *const_cache, + int code_flags, int nlocals, int nparams, int firstlineno) +{ + assert(cfg_builder_check(g)); + /** Preprocessing **/ + /* Map labels to targets and mark exception handlers */ + RETURN_IF_ERROR(translate_jump_labels_to_targets(g->g_entryblock)); + RETURN_IF_ERROR(mark_except_handlers(g->g_entryblock)); + RETURN_IF_ERROR(label_exception_targets(g->g_entryblock)); + + /** Optimization **/ + RETURN_IF_ERROR(optimize_cfg(g, consts, const_cache)); + RETURN_IF_ERROR(remove_unused_consts(g->g_entryblock, consts)); + RETURN_IF_ERROR( + add_checks_for_loads_of_uninitialized_variables( + g->g_entryblock, nlocals, nparams)); + + RETURN_IF_ERROR(push_cold_blocks_to_end(g, code_flags)); + RETURN_IF_ERROR(resolve_line_numbers(g, firstlineno)); + return SUCCESS; +} diff --git a/Python/formatter_unicode.c b/Python/formatter_unicode.c index 04d37c0b..38e5f69b 100644 --- a/Python/formatter_unicode.c +++ b/Python/formatter_unicode.c @@ -608,7 +608,7 @@ fill_number(_PyUnicodeWriter *writer, const NumberFieldWidths *spec, { /* Used to keep track of digits, decimal, and remainder. */ Py_ssize_t d_pos = d_start; - const unsigned int kind = writer->kind; + const int kind = writer->kind; const void *data = writer->data; Py_ssize_t r; @@ -1215,7 +1215,7 @@ format_complex_internal(PyObject *value, int flags = 0; int result = -1; Py_UCS4 maxchar = 127; - enum PyUnicode_Kind rkind; + int rkind; void *rdata; Py_UCS4 re_sign_char = '\0'; Py_UCS4 im_sign_char = '\0'; diff --git a/Python/frame.c b/Python/frame.c index 3ea3a2ce..b84fd9b6 100644 --- a/Python/frame.c +++ b/Python/frame.c @@ -1,4 +1,6 @@ +#define _PY_INTERPRETER + #include "Python.h" #include "frameobject.h" #include "pycore_code.h" // stats @@ -11,7 +13,7 @@ _PyFrame_Traverse(_PyInterpreterFrame *frame, visitproc visit, void *arg) { Py_VISIT(frame->frame_obj); Py_VISIT(frame->f_locals); - Py_VISIT(frame->f_func); + Py_VISIT(frame->f_funcobj); Py_VISIT(frame->f_code); /* locals */ PyObject **locals = _PyFrame_GetLocalsArray(frame); @@ -27,17 +29,14 @@ PyFrameObject * _PyFrame_MakeAndSetFrameObject(_PyInterpreterFrame *frame) { assert(frame->frame_obj == NULL); - PyObject *error_type, *error_value, *error_traceback; - PyErr_Fetch(&error_type, &error_value, &error_traceback); + PyObject *exc = PyErr_GetRaisedException(); PyFrameObject *f = _PyFrame_New_NoTrack(frame->f_code); if (f == NULL) { - Py_XDECREF(error_type); - Py_XDECREF(error_value); - Py_XDECREF(error_traceback); + Py_XDECREF(exc); return NULL; } - PyErr_Restore(error_type, error_value, error_traceback); + PyErr_SetRaisedException(exc); if (frame->frame_obj) { // GH-97002: How did we get into this horrible situation? Most likely, // allocating f triggered a GC collection, which ran some code that @@ -78,9 +77,11 @@ _PyFrame_Copy(_PyInterpreterFrame *src, _PyInterpreterFrame *dest) static void take_ownership(PyFrameObject *f, _PyInterpreterFrame *frame) { + assert(frame->owner != FRAME_OWNED_BY_CSTACK); assert(frame->owner != FRAME_OWNED_BY_FRAME_OBJECT); assert(frame->owner != FRAME_CLEARED); Py_ssize_t size = ((char*)&frame->localsplus[frame->stacktop]) - (char *)frame; + Py_INCREF(frame->f_code); memcpy((_PyInterpreterFrame *)f->_f_frame_data, frame, size); frame = (_PyInterpreterFrame *)f->_f_frame_data; f->f_frame = frame; @@ -93,11 +94,10 @@ take_ownership(PyFrameObject *f, _PyInterpreterFrame *frame) } assert(!_PyFrame_IsIncomplete(frame)); assert(f->f_back == NULL); - _PyInterpreterFrame *prev = frame->previous; - while (prev && _PyFrame_IsIncomplete(prev)) { - prev = prev->previous; - } + _PyInterpreterFrame *prev = _PyFrame_GetFirstComplete(frame->previous); + frame->previous = NULL; if (prev) { + assert(prev->owner != FRAME_OWNED_BY_CSTACK); /* Link PyFrameObjects.f_back and remove link through _PyInterpreterFrame.previous */ PyFrameObject *back = _PyFrame_GetFrameObject(prev); if (back == NULL) { @@ -109,7 +109,6 @@ take_ownership(PyFrameObject *f, _PyInterpreterFrame *frame) else { f->f_back = (PyFrameObject *)Py_NewRef(back); } - frame->previous = NULL; } if (!_PyObject_GC_IS_TRACKED((PyObject *)f)) { _PyObject_GC_TRACK((PyObject *)f); @@ -117,7 +116,7 @@ take_ownership(PyFrameObject *f, _PyInterpreterFrame *frame) } void -_PyFrame_Clear(_PyInterpreterFrame *frame) +_PyFrame_ClearExceptCode(_PyInterpreterFrame *frame) { /* It is the responsibility of the owning generator/coroutine * to have cleared the enclosing generator, if any. */ @@ -142,28 +141,27 @@ _PyFrame_Clear(_PyInterpreterFrame *frame) } Py_XDECREF(frame->frame_obj); Py_XDECREF(frame->f_locals); - Py_DECREF(frame->f_func); - Py_DECREF(frame->f_code); + Py_DECREF(frame->f_funcobj); } -/* Consumes reference to func */ -_PyInterpreterFrame * -_PyFrame_Push(PyThreadState *tstate, PyFunctionObject *func) +/* Unstable API functions */ + +PyObject * +PyUnstable_InterpreterFrame_GetCode(struct _PyInterpreterFrame *frame) { - PyCodeObject *code = (PyCodeObject *)func->func_code; - size_t size = code->co_nlocalsplus + code->co_stacksize + FRAME_SPECIALS_SIZE; - CALL_STAT_INC(frames_pushed); - _PyInterpreterFrame *new_frame = _PyThreadState_BumpFramePointer(tstate, size); - if (new_frame == NULL) { - Py_DECREF(func); - return NULL; - } - _PyFrame_InitializeSpecials(new_frame, func, NULL, code->co_nlocalsplus); - return new_frame; + PyObject *code = (PyObject *)frame->f_code; + Py_INCREF(code); + return code; +} + +int +PyUnstable_InterpreterFrame_GetLasti(struct _PyInterpreterFrame *frame) +{ + return _PyInterpreterFrame_LASTI(frame) * sizeof(_Py_CODEUNIT); } int -_PyInterpreterFrame_GetLine(_PyInterpreterFrame *frame) +PyUnstable_InterpreterFrame_GetLine(_PyInterpreterFrame *frame) { int addr = _PyInterpreterFrame_LASTI(frame) * sizeof(_Py_CODEUNIT); return PyCode_Addr2Line(frame->f_code, addr); diff --git a/Python/frozen.c b/Python/frozen.c index 8a2a7243..6b977710 100644 --- a/Python/frozen.c +++ b/Python/frozen.c @@ -8,7 +8,7 @@ * These files must be regenerated any time the corresponding .pyc * file would change (including with changes to the compiler, bytecode * format, marshal format). This can be done with "make regen-frozen". - * That make target just runs Tools/scripts/freeze_modules.py. + * That make target just runs Tools/build/freeze_modules.py. * * The freeze_modules.py script also determines which modules get * frozen. Update the list at the top of the script to add, remove, @@ -41,6 +41,29 @@ #include <stdbool.h> /* Includes for frozen modules: */ +#include "frozen_modules/importlib._bootstrap.h" +#include "frozen_modules/importlib._bootstrap_external.h" +#include "frozen_modules/zipimport.h" +#include "frozen_modules/abc.h" +#include "frozen_modules/codecs.h" +#include "frozen_modules/io.h" +#include "frozen_modules/_collections_abc.h" +#include "frozen_modules/_sitebuiltins.h" +#include "frozen_modules/genericpath.h" +#include "frozen_modules/ntpath.h" +#include "frozen_modules/posixpath.h" +#include "frozen_modules/os.h" +#include "frozen_modules/site.h" +#include "frozen_modules/stat.h" +#include "frozen_modules/importlib.util.h" +#include "frozen_modules/importlib.machinery.h" +#include "frozen_modules/runpy.h" +#include "frozen_modules/__hello__.h" +#include "frozen_modules/__phello__.h" +#include "frozen_modules/__phello__.ham.h" +#include "frozen_modules/__phello__.ham.eggs.h" +#include "frozen_modules/__phello__.spam.h" +#include "frozen_modules/frozen_only.h" /* End includes */ #define GET_CODE(name) _Py_get_##name##_toplevel @@ -78,46 +101,46 @@ extern PyObject *_Py_get_frozen_only_toplevel(void); /* End extern declarations */ static const struct _frozen bootstrap_modules[] = { - {"_frozen_importlib", NULL, 0, false, GET_CODE(importlib__bootstrap)}, - {"_frozen_importlib_external", NULL, 0, false, GET_CODE(importlib__bootstrap_external)}, - {"zipimport", NULL, 0, false, GET_CODE(zipimport)}, + {"_frozen_importlib", _Py_M__importlib__bootstrap, (int)sizeof(_Py_M__importlib__bootstrap), false, GET_CODE(importlib__bootstrap)}, + {"_frozen_importlib_external", _Py_M__importlib__bootstrap_external, (int)sizeof(_Py_M__importlib__bootstrap_external), false, GET_CODE(importlib__bootstrap_external)}, + {"zipimport", _Py_M__zipimport, (int)sizeof(_Py_M__zipimport), false, GET_CODE(zipimport)}, {0, 0, 0} /* bootstrap sentinel */ }; static const struct _frozen stdlib_modules[] = { /* stdlib - startup, without site (python -S) */ - {"abc", NULL, 0, false, GET_CODE(abc)}, - {"codecs", NULL, 0, false, GET_CODE(codecs)}, - {"io", NULL, 0, false, GET_CODE(io)}, + {"abc", _Py_M__abc, (int)sizeof(_Py_M__abc), false, GET_CODE(abc)}, + {"codecs", _Py_M__codecs, (int)sizeof(_Py_M__codecs), false, GET_CODE(codecs)}, + {"io", _Py_M__io, (int)sizeof(_Py_M__io), false, GET_CODE(io)}, /* stdlib - startup, with site */ - {"_collections_abc", NULL, 0, false, GET_CODE(_collections_abc)}, - {"_sitebuiltins", NULL, 0, false, GET_CODE(_sitebuiltins)}, - {"genericpath", NULL, 0, false, GET_CODE(genericpath)}, - {"ntpath", NULL, 0, false, GET_CODE(ntpath)}, - {"posixpath", NULL, 0, false, GET_CODE(posixpath)}, - {"os.path", NULL, 0, false, GET_CODE(posixpath)}, - {"os", NULL, 0, false, GET_CODE(os)}, - {"site", NULL, 0, false, GET_CODE(site)}, - {"stat", NULL, 0, false, GET_CODE(stat)}, + {"_collections_abc", _Py_M___collections_abc, (int)sizeof(_Py_M___collections_abc), false, GET_CODE(_collections_abc)}, + {"_sitebuiltins", _Py_M___sitebuiltins, (int)sizeof(_Py_M___sitebuiltins), false, GET_CODE(_sitebuiltins)}, + {"genericpath", _Py_M__genericpath, (int)sizeof(_Py_M__genericpath), false, GET_CODE(genericpath)}, + {"ntpath", _Py_M__ntpath, (int)sizeof(_Py_M__ntpath), false, GET_CODE(ntpath)}, + {"posixpath", _Py_M__posixpath, (int)sizeof(_Py_M__posixpath), false, GET_CODE(posixpath)}, + {"os.path", _Py_M__posixpath, (int)sizeof(_Py_M__posixpath), false, GET_CODE(posixpath)}, + {"os", _Py_M__os, (int)sizeof(_Py_M__os), false, GET_CODE(os)}, + {"site", _Py_M__site, (int)sizeof(_Py_M__site), false, GET_CODE(site)}, + {"stat", _Py_M__stat, (int)sizeof(_Py_M__stat), false, GET_CODE(stat)}, /* runpy - run module with -m */ - {"importlib.util", NULL, 0, false, GET_CODE(importlib_util)}, - {"importlib.machinery", NULL, 0, false, GET_CODE(importlib_machinery)}, - {"runpy", NULL, 0, false, GET_CODE(runpy)}, + {"importlib.util", _Py_M__importlib_util, (int)sizeof(_Py_M__importlib_util), false, GET_CODE(importlib_util)}, + {"importlib.machinery", _Py_M__importlib_machinery, (int)sizeof(_Py_M__importlib_machinery), false, GET_CODE(importlib_machinery)}, + {"runpy", _Py_M__runpy, (int)sizeof(_Py_M__runpy), false, GET_CODE(runpy)}, {0, 0, 0} /* stdlib sentinel */ }; static const struct _frozen test_modules[] = { - {"__hello__", NULL, 0, false, GET_CODE(__hello__)}, - {"__hello_alias__", NULL, 0, false, GET_CODE(__hello__)}, - {"__phello_alias__", NULL, 0, true, GET_CODE(__hello__)}, - {"__phello_alias__.spam", NULL, 0, false, GET_CODE(__hello__)}, - {"__phello__", NULL, 0, true, GET_CODE(__phello__)}, - {"__phello__.__init__", NULL, 0, false, GET_CODE(__phello__)}, - {"__phello__.ham", NULL, 0, true, GET_CODE(__phello___ham)}, - {"__phello__.ham.__init__", NULL, 0, false, GET_CODE(__phello___ham)}, - {"__phello__.ham.eggs", NULL, 0, false, GET_CODE(__phello___ham_eggs)}, - {"__phello__.spam", NULL, 0, false, GET_CODE(__phello___spam)}, - {"__hello_only__", NULL, 0, false, GET_CODE(frozen_only)}, + {"__hello__", _Py_M____hello__, (int)sizeof(_Py_M____hello__), false, GET_CODE(__hello__)}, + {"__hello_alias__", _Py_M____hello__, (int)sizeof(_Py_M____hello__), false, GET_CODE(__hello__)}, + {"__phello_alias__", _Py_M____hello__, (int)sizeof(_Py_M____hello__), true, GET_CODE(__hello__)}, + {"__phello_alias__.spam", _Py_M____hello__, (int)sizeof(_Py_M____hello__), false, GET_CODE(__hello__)}, + {"__phello__", _Py_M____phello__, (int)sizeof(_Py_M____phello__), true, GET_CODE(__phello__)}, + {"__phello__.__init__", _Py_M____phello__, (int)sizeof(_Py_M____phello__), false, GET_CODE(__phello__)}, + {"__phello__.ham", _Py_M____phello___ham, (int)sizeof(_Py_M____phello___ham), true, GET_CODE(__phello___ham)}, + {"__phello__.ham.__init__", _Py_M____phello___ham, (int)sizeof(_Py_M____phello___ham), false, GET_CODE(__phello___ham)}, + {"__phello__.ham.eggs", _Py_M____phello___ham_eggs, (int)sizeof(_Py_M____phello___ham_eggs), false, GET_CODE(__phello___ham_eggs)}, + {"__phello__.spam", _Py_M____phello___spam, (int)sizeof(_Py_M____phello___spam), false, GET_CODE(__phello___spam)}, + {"__hello_only__", _Py_M__frozen_only, (int)sizeof(_Py_M__frozen_only), false, GET_CODE(frozen_only)}, {0, 0, 0} /* test sentinel */ }; const struct _frozen *_PyImport_FrozenBootstrap = bootstrap_modules; diff --git a/Python/frozen_modules/README.txt b/Python/frozen_modules/README.txt index 444167cc..795bb0ef 100644 --- a/Python/frozen_modules/README.txt +++ b/Python/frozen_modules/README.txt @@ -4,4 +4,4 @@ modules. Python/frozen.c depends on these files. Note that, other than the required frozen modules, none of these files are committed into the repo. -See Tools/scripts/freeze_modules.py for more info. +See Tools/build/freeze_modules.py for more info. diff --git a/Python/frozenmain.c b/Python/frozenmain.c index 8743e082..f8be165f 100644 --- a/Python/frozenmain.c +++ b/Python/frozenmain.c @@ -53,7 +53,7 @@ Py_FrozenMain(int argc, char **argv) PyWinFreeze_ExeInit(); #endif - if (Py_VerboseFlag) { + if (_Py_GetConfig()->verbose) { fprintf(stderr, "Python %s\n%s\n", Py_GetVersion(), Py_GetCopyright()); } diff --git a/Python/future.c b/Python/future.c index d465608c..d56f7330 100644 --- a/Python/future.c +++ b/Python/future.c @@ -2,8 +2,6 @@ #include "pycore_ast.h" // _PyAST_GetDocString() #define UNDEFINED_FUTURE_FEATURE "future feature %.100s is not defined" -#define ERR_LATE_FUTURE \ -"from __future__ imports must occur at the beginning of the file" static int future_check_features(PyFutureFeatures *ff, stmt_ty s, PyObject *filename) @@ -56,81 +54,56 @@ future_check_features(PyFutureFeatures *ff, stmt_ty s, PyObject *filename) static int future_parse(PyFutureFeatures *ff, mod_ty mod, PyObject *filename) { - int i, done = 0, prev_line = 0; - - if (!(mod->kind == Module_kind || mod->kind == Interactive_kind)) + if (!(mod->kind == Module_kind || mod->kind == Interactive_kind)) { return 1; + } - if (asdl_seq_LEN(mod->v.Module.body) == 0) + Py_ssize_t n = asdl_seq_LEN(mod->v.Module.body); + if (n == 0) { return 1; + } - /* A subsequent pass will detect future imports that don't - appear at the beginning of the file. There's one case, - however, that is easier to handle here: A series of imports - joined by semi-colons, where the first import is a future - statement but some subsequent import has the future form - but is preceded by a regular import. - */ - - i = 0; - if (_PyAST_GetDocString(mod->v.Module.body) != NULL) + Py_ssize_t i = 0; + if (_PyAST_GetDocString(mod->v.Module.body) != NULL) { i++; + } - for (; i < asdl_seq_LEN(mod->v.Module.body); i++) { + for (; i < n; i++) { stmt_ty s = (stmt_ty)asdl_seq_GET(mod->v.Module.body, i); - if (done && s->lineno > prev_line) - return 1; - prev_line = s->lineno; - - /* The tests below will return from this function unless it is - still possible to find a future statement. The only things - that can precede a future statement are another future - statement and a doc string. - */ + /* The only things that can precede a future statement + * are another future statement and a doc string. + */ if (s->kind == ImportFrom_kind) { identifier modname = s->v.ImportFrom.module; if (modname && _PyUnicode_EqualToASCIIString(modname, "__future__")) { - if (done) { - PyErr_SetString(PyExc_SyntaxError, - ERR_LATE_FUTURE); - PyErr_SyntaxLocationObject(filename, s->lineno, s->col_offset); + if (!future_check_features(ff, s, filename)) { return 0; } - if (!future_check_features(ff, s, filename)) - return 0; - ff->ff_lineno = s->lineno; + ff->ff_location = SRC_LOCATION_FROM_AST(s); } else { - done = 1; + return 1; } } else { - done = 1; + return 1; } } return 1; } -PyFutureFeatures * -_PyFuture_FromAST(mod_ty mod, PyObject *filename) +int +_PyFuture_FromAST(mod_ty mod, PyObject *filename, PyFutureFeatures *ff) { - PyFutureFeatures *ff; - - ff = (PyFutureFeatures *)PyObject_Malloc(sizeof(PyFutureFeatures)); - if (ff == NULL) { - PyErr_NoMemory(); - return NULL; - } ff->ff_features = 0; - ff->ff_lineno = -1; + ff->ff_location = (_PyCompilerSrcLocation){-1, -1, -1, -1}; if (!future_parse(ff, mod, filename)) { - PyObject_Free(ff); - return NULL; + return 0; } - return ff; + return 1; } diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h new file mode 100644 index 00000000..e4cff7bd --- /dev/null +++ b/Python/generated_cases.c.h @@ -0,0 +1,4805 @@ +// This file is generated by Tools/cases_generator/generate_cases.py +// from: +// Python/bytecodes.c +// Do not edit! + + TARGET(NOP) { + DISPATCH(); + } + + TARGET(RESUME) { + #line 137 "Python/bytecodes.c" + assert(tstate->cframe == &cframe); + assert(frame == cframe.current_frame); + /* Possibly combine this with eval breaker */ + if (frame->f_code->_co_instrumentation_version != tstate->interp->monitoring_version) { + int err = _Py_Instrument(frame->f_code, tstate->interp); + if (err) goto error; + next_instr--; + } + else if (_Py_atomic_load_relaxed_int32(&tstate->interp->ceval.eval_breaker) && oparg < 2) { + goto handle_eval_breaker; + } + #line 24 "Python/generated_cases.c.h" + DISPATCH(); + } + + TARGET(INSTRUMENTED_RESUME) { + #line 151 "Python/bytecodes.c" + /* Possible performance enhancement: + * We need to check the eval breaker anyway, can we + * combine the instrument verison check and the eval breaker test? + */ + if (frame->f_code->_co_instrumentation_version != tstate->interp->monitoring_version) { + if (_Py_Instrument(frame->f_code, tstate->interp)) { + goto error; + } + next_instr--; + } + else { + _PyFrame_SetStackPointer(frame, stack_pointer); + int err = _Py_call_instrumentation( + tstate, oparg > 0, frame, next_instr-1); + stack_pointer = _PyFrame_GetStackPointer(frame); + if (err) goto error; + if (frame->prev_instr != next_instr-1) { + /* Instrumentation has jumped */ + next_instr = frame->prev_instr; + DISPATCH(); + } + if (_Py_atomic_load_relaxed_int32(&tstate->interp->ceval.eval_breaker) && oparg < 2) { + goto handle_eval_breaker; + } + } + #line 55 "Python/generated_cases.c.h" + DISPATCH(); + } + + TARGET(LOAD_CLOSURE) { + PyObject *value; + #line 179 "Python/bytecodes.c" + /* We keep LOAD_CLOSURE so that the bytecode stays more readable. */ + value = GETLOCAL(oparg); + if (value == NULL) goto unbound_local_error; + Py_INCREF(value); + #line 66 "Python/generated_cases.c.h" + STACK_GROW(1); + stack_pointer[-1] = value; + DISPATCH(); + } + + TARGET(LOAD_FAST_CHECK) { + PyObject *value; + #line 186 "Python/bytecodes.c" + value = GETLOCAL(oparg); + if (value == NULL) goto unbound_local_error; + Py_INCREF(value); + #line 78 "Python/generated_cases.c.h" + STACK_GROW(1); + stack_pointer[-1] = value; + DISPATCH(); + } + + TARGET(LOAD_FAST) { + PyObject *value; + #line 192 "Python/bytecodes.c" + value = GETLOCAL(oparg); + assert(value != NULL); + Py_INCREF(value); + #line 90 "Python/generated_cases.c.h" + STACK_GROW(1); + stack_pointer[-1] = value; + DISPATCH(); + } + + TARGET(LOAD_FAST_AND_CLEAR) { + PyObject *value; + #line 198 "Python/bytecodes.c" + value = GETLOCAL(oparg); + // do not use SETLOCAL here, it decrefs the old value + GETLOCAL(oparg) = NULL; + #line 102 "Python/generated_cases.c.h" + STACK_GROW(1); + stack_pointer[-1] = value; + DISPATCH(); + } + + TARGET(LOAD_CONST) { + PREDICTED(LOAD_CONST); + PyObject *value; + #line 204 "Python/bytecodes.c" + value = GETITEM(frame->f_code->co_consts, oparg); + Py_INCREF(value); + #line 114 "Python/generated_cases.c.h" + STACK_GROW(1); + stack_pointer[-1] = value; + DISPATCH(); + } + + TARGET(STORE_FAST) { + PyObject *value = stack_pointer[-1]; + #line 209 "Python/bytecodes.c" + SETLOCAL(oparg, value); + #line 124 "Python/generated_cases.c.h" + STACK_SHRINK(1); + DISPATCH(); + } + + TARGET(LOAD_FAST__LOAD_FAST) { + PyObject *_tmp_1; + PyObject *_tmp_2; + { + PyObject *value; + #line 192 "Python/bytecodes.c" + value = GETLOCAL(oparg); + assert(value != NULL); + Py_INCREF(value); + #line 138 "Python/generated_cases.c.h" + _tmp_2 = value; + } + oparg = (next_instr++)->op.arg; + { + PyObject *value; + #line 192 "Python/bytecodes.c" + value = GETLOCAL(oparg); + assert(value != NULL); + Py_INCREF(value); + #line 148 "Python/generated_cases.c.h" + _tmp_1 = value; + } + STACK_GROW(2); + stack_pointer[-1] = _tmp_1; + stack_pointer[-2] = _tmp_2; + DISPATCH(); + } + + TARGET(LOAD_FAST__LOAD_CONST) { + PyObject *_tmp_1; + PyObject *_tmp_2; + { + PyObject *value; + #line 192 "Python/bytecodes.c" + value = GETLOCAL(oparg); + assert(value != NULL); + Py_INCREF(value); + #line 166 "Python/generated_cases.c.h" + _tmp_2 = value; + } + oparg = (next_instr++)->op.arg; + { + PyObject *value; + #line 204 "Python/bytecodes.c" + value = GETITEM(frame->f_code->co_consts, oparg); + Py_INCREF(value); + #line 175 "Python/generated_cases.c.h" + _tmp_1 = value; + } + STACK_GROW(2); + stack_pointer[-1] = _tmp_1; + stack_pointer[-2] = _tmp_2; + DISPATCH(); + } + + TARGET(STORE_FAST__LOAD_FAST) { + PyObject *_tmp_1 = stack_pointer[-1]; + { + PyObject *value = _tmp_1; + #line 209 "Python/bytecodes.c" + SETLOCAL(oparg, value); + #line 190 "Python/generated_cases.c.h" + } + oparg = (next_instr++)->op.arg; + { + PyObject *value; + #line 192 "Python/bytecodes.c" + value = GETLOCAL(oparg); + assert(value != NULL); + Py_INCREF(value); + #line 199 "Python/generated_cases.c.h" + _tmp_1 = value; + } + stack_pointer[-1] = _tmp_1; + DISPATCH(); + } + + TARGET(STORE_FAST__STORE_FAST) { + PyObject *_tmp_1 = stack_pointer[-1]; + PyObject *_tmp_2 = stack_pointer[-2]; + { + PyObject *value = _tmp_1; + #line 209 "Python/bytecodes.c" + SETLOCAL(oparg, value); + #line 213 "Python/generated_cases.c.h" + } + oparg = (next_instr++)->op.arg; + { + PyObject *value = _tmp_2; + #line 209 "Python/bytecodes.c" + SETLOCAL(oparg, value); + #line 220 "Python/generated_cases.c.h" + } + STACK_SHRINK(2); + DISPATCH(); + } + + TARGET(LOAD_CONST__LOAD_FAST) { + PyObject *_tmp_1; + PyObject *_tmp_2; + { + PyObject *value; + #line 204 "Python/bytecodes.c" + value = GETITEM(frame->f_code->co_consts, oparg); + Py_INCREF(value); + #line 234 "Python/generated_cases.c.h" + _tmp_2 = value; + } + oparg = (next_instr++)->op.arg; + { + PyObject *value; + #line 192 "Python/bytecodes.c" + value = GETLOCAL(oparg); + assert(value != NULL); + Py_INCREF(value); + #line 244 "Python/generated_cases.c.h" + _tmp_1 = value; + } + STACK_GROW(2); + stack_pointer[-1] = _tmp_1; + stack_pointer[-2] = _tmp_2; + DISPATCH(); + } + + TARGET(POP_TOP) { + PyObject *value = stack_pointer[-1]; + #line 219 "Python/bytecodes.c" + #line 256 "Python/generated_cases.c.h" + Py_DECREF(value); + STACK_SHRINK(1); + DISPATCH(); + } + + TARGET(PUSH_NULL) { + PyObject *res; + #line 223 "Python/bytecodes.c" + res = NULL; + #line 266 "Python/generated_cases.c.h" + STACK_GROW(1); + stack_pointer[-1] = res; + DISPATCH(); + } + + TARGET(END_FOR) { + PyObject *_tmp_1 = stack_pointer[-1]; + PyObject *_tmp_2 = stack_pointer[-2]; + { + PyObject *value = _tmp_1; + #line 219 "Python/bytecodes.c" + #line 278 "Python/generated_cases.c.h" + Py_DECREF(value); + } + { + PyObject *value = _tmp_2; + #line 219 "Python/bytecodes.c" + #line 284 "Python/generated_cases.c.h" + Py_DECREF(value); + } + STACK_SHRINK(2); + DISPATCH(); + } + + TARGET(INSTRUMENTED_END_FOR) { + PyObject *value = stack_pointer[-1]; + PyObject *receiver = stack_pointer[-2]; + #line 229 "Python/bytecodes.c" + /* Need to create a fake StopIteration error here, + * to conform to PEP 380 */ + if (PyGen_Check(receiver)) { + PyErr_SetObject(PyExc_StopIteration, value); + if (monitor_stop_iteration(tstate, frame, next_instr-1)) { + goto error; + } + PyErr_SetRaisedException(NULL); + } + #line 304 "Python/generated_cases.c.h" + Py_DECREF(receiver); + Py_DECREF(value); + STACK_SHRINK(2); + DISPATCH(); + } + + TARGET(END_SEND) { + PyObject *value = stack_pointer[-1]; + PyObject *receiver = stack_pointer[-2]; + #line 242 "Python/bytecodes.c" + Py_DECREF(receiver); + #line 316 "Python/generated_cases.c.h" + STACK_SHRINK(1); + stack_pointer[-1] = value; + DISPATCH(); + } + + TARGET(INSTRUMENTED_END_SEND) { + PyObject *value = stack_pointer[-1]; + PyObject *receiver = stack_pointer[-2]; + #line 246 "Python/bytecodes.c" + if (PyGen_Check(receiver) || PyCoro_CheckExact(receiver)) { + PyErr_SetObject(PyExc_StopIteration, value); + if (monitor_stop_iteration(tstate, frame, next_instr-1)) { + goto error; + } + PyErr_SetRaisedException(NULL); + } + Py_DECREF(receiver); + #line 334 "Python/generated_cases.c.h" + STACK_SHRINK(1); + stack_pointer[-1] = value; + DISPATCH(); + } + + TARGET(UNARY_NEGATIVE) { + PyObject *value = stack_pointer[-1]; + PyObject *res; + #line 257 "Python/bytecodes.c" + res = PyNumber_Negative(value); + #line 345 "Python/generated_cases.c.h" + Py_DECREF(value); + #line 259 "Python/bytecodes.c" + if (res == NULL) goto pop_1_error; + #line 349 "Python/generated_cases.c.h" + stack_pointer[-1] = res; + DISPATCH(); + } + + TARGET(UNARY_NOT) { + PyObject *value = stack_pointer[-1]; + PyObject *res; + #line 263 "Python/bytecodes.c" + int err = PyObject_IsTrue(value); + #line 359 "Python/generated_cases.c.h" + Py_DECREF(value); + #line 265 "Python/bytecodes.c" + if (err < 0) goto pop_1_error; + if (err == 0) { + res = Py_True; + } + else { + res = Py_False; + } + #line 369 "Python/generated_cases.c.h" + stack_pointer[-1] = res; + DISPATCH(); + } + + TARGET(UNARY_INVERT) { + PyObject *value = stack_pointer[-1]; + PyObject *res; + #line 275 "Python/bytecodes.c" + res = PyNumber_Invert(value); + #line 379 "Python/generated_cases.c.h" + Py_DECREF(value); + #line 277 "Python/bytecodes.c" + if (res == NULL) goto pop_1_error; + #line 383 "Python/generated_cases.c.h" + stack_pointer[-1] = res; + DISPATCH(); + } + + TARGET(BINARY_OP_MULTIPLY_INT) { + PyObject *right = stack_pointer[-1]; + PyObject *left = stack_pointer[-2]; + PyObject *prod; + #line 294 "Python/bytecodes.c" + DEOPT_IF(!PyLong_CheckExact(left), BINARY_OP); + DEOPT_IF(!PyLong_CheckExact(right), BINARY_OP); + STAT_INC(BINARY_OP, hit); + prod = _PyLong_Multiply((PyLongObject *)left, (PyLongObject *)right); + _Py_DECREF_SPECIALIZED(right, (destructor)PyObject_Free); + _Py_DECREF_SPECIALIZED(left, (destructor)PyObject_Free); + if (prod == NULL) goto pop_2_error; + #line 400 "Python/generated_cases.c.h" + STACK_SHRINK(1); + stack_pointer[-1] = prod; + next_instr += 1; + DISPATCH(); + } + + TARGET(BINARY_OP_MULTIPLY_FLOAT) { + PyObject *right = stack_pointer[-1]; + PyObject *left = stack_pointer[-2]; + PyObject *prod; + #line 304 "Python/bytecodes.c" + DEOPT_IF(!PyFloat_CheckExact(left), BINARY_OP); + DEOPT_IF(!PyFloat_CheckExact(right), BINARY_OP); + STAT_INC(BINARY_OP, hit); + double dprod = ((PyFloatObject *)left)->ob_fval * + ((PyFloatObject *)right)->ob_fval; + DECREF_INPUTS_AND_REUSE_FLOAT(left, right, dprod, prod); + #line 418 "Python/generated_cases.c.h" + STACK_SHRINK(1); + stack_pointer[-1] = prod; + next_instr += 1; + DISPATCH(); + } + + TARGET(BINARY_OP_SUBTRACT_INT) { + PyObject *right = stack_pointer[-1]; + PyObject *left = stack_pointer[-2]; + PyObject *sub; + #line 313 "Python/bytecodes.c" + DEOPT_IF(!PyLong_CheckExact(left), BINARY_OP); + DEOPT_IF(!PyLong_CheckExact(right), BINARY_OP); + STAT_INC(BINARY_OP, hit); + sub = _PyLong_Subtract((PyLongObject *)left, (PyLongObject *)right); + _Py_DECREF_SPECIALIZED(right, (destructor)PyObject_Free); + _Py_DECREF_SPECIALIZED(left, (destructor)PyObject_Free); + if (sub == NULL) goto pop_2_error; + #line 437 "Python/generated_cases.c.h" + STACK_SHRINK(1); + stack_pointer[-1] = sub; + next_instr += 1; + DISPATCH(); + } + + TARGET(BINARY_OP_SUBTRACT_FLOAT) { + PyObject *right = stack_pointer[-1]; + PyObject *left = stack_pointer[-2]; + PyObject *sub; + #line 323 "Python/bytecodes.c" + DEOPT_IF(!PyFloat_CheckExact(left), BINARY_OP); + DEOPT_IF(!PyFloat_CheckExact(right), BINARY_OP); + STAT_INC(BINARY_OP, hit); + double dsub = ((PyFloatObject *)left)->ob_fval - ((PyFloatObject *)right)->ob_fval; + DECREF_INPUTS_AND_REUSE_FLOAT(left, right, dsub, sub); + #line 454 "Python/generated_cases.c.h" + STACK_SHRINK(1); + stack_pointer[-1] = sub; + next_instr += 1; + DISPATCH(); + } + + TARGET(BINARY_OP_ADD_UNICODE) { + PyObject *right = stack_pointer[-1]; + PyObject *left = stack_pointer[-2]; + PyObject *res; + #line 331 "Python/bytecodes.c" + DEOPT_IF(!PyUnicode_CheckExact(left), BINARY_OP); + DEOPT_IF(Py_TYPE(right) != Py_TYPE(left), BINARY_OP); + STAT_INC(BINARY_OP, hit); + res = PyUnicode_Concat(left, right); + _Py_DECREF_SPECIALIZED(left, _PyUnicode_ExactDealloc); + _Py_DECREF_SPECIALIZED(right, _PyUnicode_ExactDealloc); + if (res == NULL) goto pop_2_error; + #line 473 "Python/generated_cases.c.h" + STACK_SHRINK(1); + stack_pointer[-1] = res; + next_instr += 1; + DISPATCH(); + } + + TARGET(BINARY_OP_INPLACE_ADD_UNICODE) { + PyObject *right = stack_pointer[-1]; + PyObject *left = stack_pointer[-2]; + #line 347 "Python/bytecodes.c" + DEOPT_IF(!PyUnicode_CheckExact(left), BINARY_OP); + DEOPT_IF(Py_TYPE(right) != Py_TYPE(left), BINARY_OP); + _Py_CODEUNIT true_next = next_instr[INLINE_CACHE_ENTRIES_BINARY_OP]; + assert(true_next.op.code == STORE_FAST || + true_next.op.code == STORE_FAST__LOAD_FAST); + PyObject **target_local = &GETLOCAL(true_next.op.arg); + DEOPT_IF(*target_local != left, BINARY_OP); + STAT_INC(BINARY_OP, hit); + /* Handle `left = left + right` or `left += right` for str. + * + * When possible, extend `left` in place rather than + * allocating a new PyUnicodeObject. This attempts to avoid + * quadratic behavior when one neglects to use str.join(). + * + * If `left` has only two references remaining (one from + * the stack, one in the locals), DECREFing `left` leaves + * only the locals reference, so PyUnicode_Append knows + * that the string is safe to mutate. + */ + assert(Py_REFCNT(left) >= 2); + _Py_DECREF_NO_DEALLOC(left); + PyUnicode_Append(target_local, right); + _Py_DECREF_SPECIALIZED(right, _PyUnicode_ExactDealloc); + if (*target_local == NULL) goto pop_2_error; + // The STORE_FAST is already done. + JUMPBY(INLINE_CACHE_ENTRIES_BINARY_OP + 1); + #line 510 "Python/generated_cases.c.h" + STACK_SHRINK(2); + DISPATCH(); + } + + TARGET(BINARY_OP_ADD_FLOAT) { + PyObject *right = stack_pointer[-1]; + PyObject *left = stack_pointer[-2]; + PyObject *sum; + #line 376 "Python/bytecodes.c" + DEOPT_IF(!PyFloat_CheckExact(left), BINARY_OP); + DEOPT_IF(Py_TYPE(right) != Py_TYPE(left), BINARY_OP); + STAT_INC(BINARY_OP, hit); + double dsum = ((PyFloatObject *)left)->ob_fval + + ((PyFloatObject *)right)->ob_fval; + DECREF_INPUTS_AND_REUSE_FLOAT(left, right, dsum, sum); + #line 526 "Python/generated_cases.c.h" + STACK_SHRINK(1); + stack_pointer[-1] = sum; + next_instr += 1; + DISPATCH(); + } + + TARGET(BINARY_OP_ADD_INT) { + PyObject *right = stack_pointer[-1]; + PyObject *left = stack_pointer[-2]; + PyObject *sum; + #line 385 "Python/bytecodes.c" + DEOPT_IF(!PyLong_CheckExact(left), BINARY_OP); + DEOPT_IF(Py_TYPE(right) != Py_TYPE(left), BINARY_OP); + STAT_INC(BINARY_OP, hit); + sum = _PyLong_Add((PyLongObject *)left, (PyLongObject *)right); + _Py_DECREF_SPECIALIZED(right, (destructor)PyObject_Free); + _Py_DECREF_SPECIALIZED(left, (destructor)PyObject_Free); + if (sum == NULL) goto pop_2_error; + #line 545 "Python/generated_cases.c.h" + STACK_SHRINK(1); + stack_pointer[-1] = sum; + next_instr += 1; + DISPATCH(); + } + + TARGET(BINARY_SUBSCR) { + PREDICTED(BINARY_SUBSCR); + static_assert(INLINE_CACHE_ENTRIES_BINARY_SUBSCR == 1, "incorrect cache size"); + PyObject *sub = stack_pointer[-1]; + PyObject *container = stack_pointer[-2]; + PyObject *res; + #line 403 "Python/bytecodes.c" + #if ENABLE_SPECIALIZATION + _PyBinarySubscrCache *cache = (_PyBinarySubscrCache *)next_instr; + if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { + next_instr--; + _Py_Specialize_BinarySubscr(container, sub, next_instr); + DISPATCH_SAME_OPARG(); + } + STAT_INC(BINARY_SUBSCR, deferred); + DECREMENT_ADAPTIVE_COUNTER(cache->counter); + #endif /* ENABLE_SPECIALIZATION */ + res = PyObject_GetItem(container, sub); + #line 570 "Python/generated_cases.c.h" + Py_DECREF(container); + Py_DECREF(sub); + #line 415 "Python/bytecodes.c" + if (res == NULL) goto pop_2_error; + #line 575 "Python/generated_cases.c.h" + STACK_SHRINK(1); + stack_pointer[-1] = res; + next_instr += 1; + DISPATCH(); + } + + TARGET(BINARY_SLICE) { + PyObject *stop = stack_pointer[-1]; + PyObject *start = stack_pointer[-2]; + PyObject *container = stack_pointer[-3]; + PyObject *res; + #line 419 "Python/bytecodes.c" + PyObject *slice = _PyBuildSlice_ConsumeRefs(start, stop); + // Can't use ERROR_IF() here, because we haven't + // DECREF'ed container yet, and we still own slice. + if (slice == NULL) { + res = NULL; + } + else { + res = PyObject_GetItem(container, slice); + Py_DECREF(slice); + } + Py_DECREF(container); + if (res == NULL) goto pop_3_error; + #line 600 "Python/generated_cases.c.h" + STACK_SHRINK(2); + stack_pointer[-1] = res; + DISPATCH(); + } + + TARGET(STORE_SLICE) { + PyObject *stop = stack_pointer[-1]; + PyObject *start = stack_pointer[-2]; + PyObject *container = stack_pointer[-3]; + PyObject *v = stack_pointer[-4]; + #line 434 "Python/bytecodes.c" + PyObject *slice = _PyBuildSlice_ConsumeRefs(start, stop); + int err; + if (slice == NULL) { + err = 1; + } + else { + err = PyObject_SetItem(container, slice, v); + Py_DECREF(slice); + } + Py_DECREF(v); + Py_DECREF(container); + if (err) goto pop_4_error; + #line 624 "Python/generated_cases.c.h" + STACK_SHRINK(4); + DISPATCH(); + } + + TARGET(BINARY_SUBSCR_LIST_INT) { + PyObject *sub = stack_pointer[-1]; + PyObject *list = stack_pointer[-2]; + PyObject *res; + #line 449 "Python/bytecodes.c" + DEOPT_IF(!PyLong_CheckExact(sub), BINARY_SUBSCR); + DEOPT_IF(!PyList_CheckExact(list), BINARY_SUBSCR); + + // Deopt unless 0 <= sub < PyList_Size(list) + DEOPT_IF(!_PyLong_IsNonNegativeCompact((PyLongObject *)sub), BINARY_SUBSCR); + Py_ssize_t index = ((PyLongObject*)sub)->long_value.ob_digit[0]; + DEOPT_IF(index >= PyList_GET_SIZE(list), BINARY_SUBSCR); + STAT_INC(BINARY_SUBSCR, hit); + res = PyList_GET_ITEM(list, index); + assert(res != NULL); + Py_INCREF(res); + _Py_DECREF_SPECIALIZED(sub, (destructor)PyObject_Free); + Py_DECREF(list); + #line 647 "Python/generated_cases.c.h" + STACK_SHRINK(1); + stack_pointer[-1] = res; + next_instr += 1; + DISPATCH(); + } + + TARGET(BINARY_SUBSCR_TUPLE_INT) { + PyObject *sub = stack_pointer[-1]; + PyObject *tuple = stack_pointer[-2]; + PyObject *res; + #line 465 "Python/bytecodes.c" + DEOPT_IF(!PyLong_CheckExact(sub), BINARY_SUBSCR); + DEOPT_IF(!PyTuple_CheckExact(tuple), BINARY_SUBSCR); + + // Deopt unless 0 <= sub < PyTuple_Size(list) + DEOPT_IF(!_PyLong_IsNonNegativeCompact((PyLongObject *)sub), BINARY_SUBSCR); + Py_ssize_t index = ((PyLongObject*)sub)->long_value.ob_digit[0]; + DEOPT_IF(index >= PyTuple_GET_SIZE(tuple), BINARY_SUBSCR); + STAT_INC(BINARY_SUBSCR, hit); + res = PyTuple_GET_ITEM(tuple, index); + assert(res != NULL); + Py_INCREF(res); + _Py_DECREF_SPECIALIZED(sub, (destructor)PyObject_Free); + Py_DECREF(tuple); + #line 672 "Python/generated_cases.c.h" + STACK_SHRINK(1); + stack_pointer[-1] = res; + next_instr += 1; + DISPATCH(); + } + + TARGET(BINARY_SUBSCR_DICT) { + PyObject *sub = stack_pointer[-1]; + PyObject *dict = stack_pointer[-2]; + PyObject *res; + #line 481 "Python/bytecodes.c" + DEOPT_IF(!PyDict_CheckExact(dict), BINARY_SUBSCR); + STAT_INC(BINARY_SUBSCR, hit); + res = PyDict_GetItemWithError(dict, sub); + if (res == NULL) { + if (!_PyErr_Occurred(tstate)) { + _PyErr_SetKeyError(sub); + } + #line 691 "Python/generated_cases.c.h" + Py_DECREF(dict); + Py_DECREF(sub); + #line 489 "Python/bytecodes.c" + if (true) goto pop_2_error; + } + Py_INCREF(res); // Do this before DECREF'ing dict, sub + #line 698 "Python/generated_cases.c.h" + Py_DECREF(dict); + Py_DECREF(sub); + STACK_SHRINK(1); + stack_pointer[-1] = res; + next_instr += 1; + DISPATCH(); + } + + TARGET(BINARY_SUBSCR_GETITEM) { + PyObject *sub = stack_pointer[-1]; + PyObject *container = stack_pointer[-2]; + #line 496 "Python/bytecodes.c" + DEOPT_IF(tstate->interp->eval_frame, BINARY_SUBSCR); + PyTypeObject *tp = Py_TYPE(container); + DEOPT_IF(!PyType_HasFeature(tp, Py_TPFLAGS_HEAPTYPE), BINARY_SUBSCR); + PyHeapTypeObject *ht = (PyHeapTypeObject *)tp; + PyObject *cached = ht->_spec_cache.getitem; + DEOPT_IF(cached == NULL, BINARY_SUBSCR); + assert(PyFunction_Check(cached)); + PyFunctionObject *getitem = (PyFunctionObject *)cached; + uint32_t cached_version = ht->_spec_cache.getitem_version; + DEOPT_IF(getitem->func_version != cached_version, BINARY_SUBSCR); + PyCodeObject *code = (PyCodeObject *)getitem->func_code; + assert(code->co_argcount == 2); + DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), BINARY_SUBSCR); + STAT_INC(BINARY_SUBSCR, hit); + Py_INCREF(getitem); + _PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, getitem, 2); + STACK_SHRINK(2); + new_frame->localsplus[0] = container; + new_frame->localsplus[1] = sub; + JUMPBY(INLINE_CACHE_ENTRIES_BINARY_SUBSCR); + frame->return_offset = 0; + DISPATCH_INLINED(new_frame); + #line 733 "Python/generated_cases.c.h" + } + + TARGET(LIST_APPEND) { + PyObject *v = stack_pointer[-1]; + PyObject *list = stack_pointer[-(2 + (oparg-1))]; + #line 521 "Python/bytecodes.c" + if (_PyList_AppendTakeRef((PyListObject *)list, v) < 0) goto pop_1_error; + #line 741 "Python/generated_cases.c.h" + STACK_SHRINK(1); + PREDICT(JUMP_BACKWARD); + DISPATCH(); + } + + TARGET(SET_ADD) { + PyObject *v = stack_pointer[-1]; + PyObject *set = stack_pointer[-(2 + (oparg-1))]; + #line 526 "Python/bytecodes.c" + int err = PySet_Add(set, v); + #line 752 "Python/generated_cases.c.h" + Py_DECREF(v); + #line 528 "Python/bytecodes.c" + if (err) goto pop_1_error; + #line 756 "Python/generated_cases.c.h" + STACK_SHRINK(1); + PREDICT(JUMP_BACKWARD); + DISPATCH(); + } + + TARGET(STORE_SUBSCR) { + PREDICTED(STORE_SUBSCR); + static_assert(INLINE_CACHE_ENTRIES_STORE_SUBSCR == 1, "incorrect cache size"); + PyObject *sub = stack_pointer[-1]; + PyObject *container = stack_pointer[-2]; + PyObject *v = stack_pointer[-3]; + uint16_t counter = read_u16(&next_instr[0].cache); + #line 539 "Python/bytecodes.c" + #if ENABLE_SPECIALIZATION + if (ADAPTIVE_COUNTER_IS_ZERO(counter)) { + next_instr--; + _Py_Specialize_StoreSubscr(container, sub, next_instr); + DISPATCH_SAME_OPARG(); + } + STAT_INC(STORE_SUBSCR, deferred); + _PyStoreSubscrCache *cache = (_PyStoreSubscrCache *)next_instr; + DECREMENT_ADAPTIVE_COUNTER(cache->counter); + #else + (void)counter; // Unused. + #endif /* ENABLE_SPECIALIZATION */ + /* container[sub] = v */ + int err = PyObject_SetItem(container, sub, v); + #line 784 "Python/generated_cases.c.h" + Py_DECREF(v); + Py_DECREF(container); + Py_DECREF(sub); + #line 554 "Python/bytecodes.c" + if (err) goto pop_3_error; + #line 790 "Python/generated_cases.c.h" + STACK_SHRINK(3); + next_instr += 1; + DISPATCH(); + } + + TARGET(STORE_SUBSCR_LIST_INT) { + PyObject *sub = stack_pointer[-1]; + PyObject *list = stack_pointer[-2]; + PyObject *value = stack_pointer[-3]; + #line 558 "Python/bytecodes.c" + DEOPT_IF(!PyLong_CheckExact(sub), STORE_SUBSCR); + DEOPT_IF(!PyList_CheckExact(list), STORE_SUBSCR); + + // Ensure nonnegative, zero-or-one-digit ints. + DEOPT_IF(!_PyLong_IsNonNegativeCompact((PyLongObject *)sub), STORE_SUBSCR); + Py_ssize_t index = ((PyLongObject*)sub)->long_value.ob_digit[0]; + // Ensure index < len(list) + DEOPT_IF(index >= PyList_GET_SIZE(list), STORE_SUBSCR); + STAT_INC(STORE_SUBSCR, hit); + + PyObject *old_value = PyList_GET_ITEM(list, index); + PyList_SET_ITEM(list, index, value); + assert(old_value != NULL); + Py_DECREF(old_value); + _Py_DECREF_SPECIALIZED(sub, (destructor)PyObject_Free); + Py_DECREF(list); + #line 817 "Python/generated_cases.c.h" + STACK_SHRINK(3); + next_instr += 1; + DISPATCH(); + } + + TARGET(STORE_SUBSCR_DICT) { + PyObject *sub = stack_pointer[-1]; + PyObject *dict = stack_pointer[-2]; + PyObject *value = stack_pointer[-3]; + #line 577 "Python/bytecodes.c" + DEOPT_IF(!PyDict_CheckExact(dict), STORE_SUBSCR); + STAT_INC(STORE_SUBSCR, hit); + int err = _PyDict_SetItem_Take2((PyDictObject *)dict, sub, value); + Py_DECREF(dict); + if (err) goto pop_3_error; + #line 833 "Python/generated_cases.c.h" + STACK_SHRINK(3); + next_instr += 1; + DISPATCH(); + } + + TARGET(DELETE_SUBSCR) { + PyObject *sub = stack_pointer[-1]; + PyObject *container = stack_pointer[-2]; + #line 585 "Python/bytecodes.c" + /* del container[sub] */ + int err = PyObject_DelItem(container, sub); + #line 845 "Python/generated_cases.c.h" + Py_DECREF(container); + Py_DECREF(sub); + #line 588 "Python/bytecodes.c" + if (err) goto pop_2_error; + #line 850 "Python/generated_cases.c.h" + STACK_SHRINK(2); + DISPATCH(); + } + + TARGET(CALL_INTRINSIC_1) { + PyObject *value = stack_pointer[-1]; + PyObject *res; + #line 592 "Python/bytecodes.c" + assert(oparg <= MAX_INTRINSIC_1); + res = _PyIntrinsics_UnaryFunctions[oparg](tstate, value); + #line 861 "Python/generated_cases.c.h" + Py_DECREF(value); + #line 595 "Python/bytecodes.c" + if (res == NULL) goto pop_1_error; + #line 865 "Python/generated_cases.c.h" + stack_pointer[-1] = res; + DISPATCH(); + } + + TARGET(CALL_INTRINSIC_2) { + PyObject *value1 = stack_pointer[-1]; + PyObject *value2 = stack_pointer[-2]; + PyObject *res; + #line 599 "Python/bytecodes.c" + assert(oparg <= MAX_INTRINSIC_2); + res = _PyIntrinsics_BinaryFunctions[oparg](tstate, value2, value1); + #line 877 "Python/generated_cases.c.h" + Py_DECREF(value2); + Py_DECREF(value1); + #line 602 "Python/bytecodes.c" + if (res == NULL) goto pop_2_error; + #line 882 "Python/generated_cases.c.h" + STACK_SHRINK(1); + stack_pointer[-1] = res; + DISPATCH(); + } + + TARGET(RAISE_VARARGS) { + PyObject **args = (stack_pointer - oparg); + #line 606 "Python/bytecodes.c" + PyObject *cause = NULL, *exc = NULL; + switch (oparg) { + case 2: + cause = args[1]; + /* fall through */ + case 1: + exc = args[0]; + /* fall through */ + case 0: + if (do_raise(tstate, exc, cause)) { + assert(oparg == 0); + monitor_reraise(tstate, frame, next_instr-1); + goto exception_unwind; + } + break; + default: + _PyErr_SetString(tstate, PyExc_SystemError, + "bad RAISE_VARARGS oparg"); + break; + } + if (true) { STACK_SHRINK(oparg); goto error; } + #line 912 "Python/generated_cases.c.h" + } + + TARGET(INTERPRETER_EXIT) { + PyObject *retval = stack_pointer[-1]; + #line 630 "Python/bytecodes.c" + assert(frame == &entry_frame); + assert(_PyFrame_IsIncomplete(frame)); + STACK_SHRINK(1); // Since we're not going to DISPATCH() + assert(EMPTY()); + /* Restore previous cframe and return. */ + tstate->cframe = cframe.previous; + assert(tstate->cframe->current_frame == frame->previous); + assert(!_PyErr_Occurred(tstate)); + tstate->c_recursion_remaining += PY_EVAL_C_STACK_UNITS; + return retval; + #line 928 "Python/generated_cases.c.h" + } + + TARGET(RETURN_VALUE) { + PyObject *retval = stack_pointer[-1]; + #line 643 "Python/bytecodes.c" + STACK_SHRINK(1); + assert(EMPTY()); + _PyFrame_SetStackPointer(frame, stack_pointer); + _Py_LeaveRecursiveCallPy(tstate); + assert(frame != &entry_frame); + // GH-99729: We need to unlink the frame *before* clearing it: + _PyInterpreterFrame *dying = frame; + frame = cframe.current_frame = dying->previous; + _PyEvalFrameClearAndPop(tstate, dying); + frame->prev_instr += frame->return_offset; + _PyFrame_StackPush(frame, retval); + goto resume_frame; + #line 946 "Python/generated_cases.c.h" + } + + TARGET(INSTRUMENTED_RETURN_VALUE) { + PyObject *retval = stack_pointer[-1]; + #line 658 "Python/bytecodes.c" + int err = _Py_call_instrumentation_arg( + tstate, PY_MONITORING_EVENT_PY_RETURN, + frame, next_instr-1, retval); + if (err) goto error; + STACK_SHRINK(1); + assert(EMPTY()); + _PyFrame_SetStackPointer(frame, stack_pointer); + _Py_LeaveRecursiveCallPy(tstate); + assert(frame != &entry_frame); + // GH-99729: We need to unlink the frame *before* clearing it: + _PyInterpreterFrame *dying = frame; + frame = cframe.current_frame = dying->previous; + _PyEvalFrameClearAndPop(tstate, dying); + frame->prev_instr += frame->return_offset; + _PyFrame_StackPush(frame, retval); + goto resume_frame; + #line 968 "Python/generated_cases.c.h" + } + + TARGET(RETURN_CONST) { + #line 677 "Python/bytecodes.c" + PyObject *retval = GETITEM(frame->f_code->co_consts, oparg); + Py_INCREF(retval); + assert(EMPTY()); + _PyFrame_SetStackPointer(frame, stack_pointer); + _Py_LeaveRecursiveCallPy(tstate); + assert(frame != &entry_frame); + // GH-99729: We need to unlink the frame *before* clearing it: + _PyInterpreterFrame *dying = frame; + frame = cframe.current_frame = dying->previous; + _PyEvalFrameClearAndPop(tstate, dying); + frame->prev_instr += frame->return_offset; + _PyFrame_StackPush(frame, retval); + goto resume_frame; + #line 986 "Python/generated_cases.c.h" + } + + TARGET(INSTRUMENTED_RETURN_CONST) { + #line 693 "Python/bytecodes.c" + PyObject *retval = GETITEM(frame->f_code->co_consts, oparg); + int err = _Py_call_instrumentation_arg( + tstate, PY_MONITORING_EVENT_PY_RETURN, + frame, next_instr-1, retval); + if (err) goto error; + Py_INCREF(retval); + assert(EMPTY()); + _PyFrame_SetStackPointer(frame, stack_pointer); + _Py_LeaveRecursiveCallPy(tstate); + assert(frame != &entry_frame); + // GH-99729: We need to unlink the frame *before* clearing it: + _PyInterpreterFrame *dying = frame; + frame = cframe.current_frame = dying->previous; + _PyEvalFrameClearAndPop(tstate, dying); + frame->prev_instr += frame->return_offset; + _PyFrame_StackPush(frame, retval); + goto resume_frame; + #line 1008 "Python/generated_cases.c.h" + } + + TARGET(GET_AITER) { + PyObject *obj = stack_pointer[-1]; + PyObject *iter; + #line 713 "Python/bytecodes.c" + unaryfunc getter = NULL; + PyTypeObject *type = Py_TYPE(obj); + + if (type->tp_as_async != NULL) { + getter = type->tp_as_async->am_aiter; + } + + if (getter == NULL) { + _PyErr_Format(tstate, PyExc_TypeError, + "'async for' requires an object with " + "__aiter__ method, got %.100s", + type->tp_name); + #line 1027 "Python/generated_cases.c.h" + Py_DECREF(obj); + #line 726 "Python/bytecodes.c" + if (true) goto pop_1_error; + } + + iter = (*getter)(obj); + #line 1034 "Python/generated_cases.c.h" + Py_DECREF(obj); + #line 731 "Python/bytecodes.c" + if (iter == NULL) goto pop_1_error; + + if (Py_TYPE(iter)->tp_as_async == NULL || + Py_TYPE(iter)->tp_as_async->am_anext == NULL) { + + _PyErr_Format(tstate, PyExc_TypeError, + "'async for' received an object from __aiter__ " + "that does not implement __anext__: %.100s", + Py_TYPE(iter)->tp_name); + Py_DECREF(iter); + if (true) goto pop_1_error; + } + #line 1049 "Python/generated_cases.c.h" + stack_pointer[-1] = iter; + DISPATCH(); + } + + TARGET(GET_ANEXT) { + PyObject *aiter = stack_pointer[-1]; + PyObject *awaitable; + #line 746 "Python/bytecodes.c" + unaryfunc getter = NULL; + PyObject *next_iter = NULL; + PyTypeObject *type = Py_TYPE(aiter); + + if (PyAsyncGen_CheckExact(aiter)) { + awaitable = type->tp_as_async->am_anext(aiter); + if (awaitable == NULL) { + goto error; + } + } else { + if (type->tp_as_async != NULL){ + getter = type->tp_as_async->am_anext; + } + + if (getter != NULL) { + next_iter = (*getter)(aiter); + if (next_iter == NULL) { + goto error; + } + } + else { + _PyErr_Format(tstate, PyExc_TypeError, + "'async for' requires an iterator with " + "__anext__ method, got %.100s", + type->tp_name); + goto error; + } + + awaitable = _PyCoro_GetAwaitableIter(next_iter); + if (awaitable == NULL) { + _PyErr_FormatFromCause( + PyExc_TypeError, + "'async for' received an invalid object " + "from __anext__: %.100s", + Py_TYPE(next_iter)->tp_name); + + Py_DECREF(next_iter); + goto error; + } else { + Py_DECREF(next_iter); + } + } + + #line 1101 "Python/generated_cases.c.h" + STACK_GROW(1); + stack_pointer[-1] = awaitable; + PREDICT(LOAD_CONST); + DISPATCH(); + } + + TARGET(GET_AWAITABLE) { + PREDICTED(GET_AWAITABLE); + PyObject *iterable = stack_pointer[-1]; + PyObject *iter; + #line 793 "Python/bytecodes.c" + iter = _PyCoro_GetAwaitableIter(iterable); + + if (iter == NULL) { + format_awaitable_error(tstate, Py_TYPE(iterable), oparg); + } + + #line 1119 "Python/generated_cases.c.h" + Py_DECREF(iterable); + #line 800 "Python/bytecodes.c" + + if (iter != NULL && PyCoro_CheckExact(iter)) { + PyObject *yf = _PyGen_yf((PyGenObject*)iter); + if (yf != NULL) { + /* `iter` is a coroutine object that is being + awaited, `yf` is a pointer to the current awaitable + being awaited on. */ + Py_DECREF(yf); + Py_CLEAR(iter); + _PyErr_SetString(tstate, PyExc_RuntimeError, + "coroutine is being awaited already"); + /* The code below jumps to `error` if `iter` is NULL. */ + } + } + + if (iter == NULL) goto pop_1_error; + + #line 1139 "Python/generated_cases.c.h" + stack_pointer[-1] = iter; + PREDICT(LOAD_CONST); + DISPATCH(); + } + + TARGET(SEND) { + PREDICTED(SEND); + static_assert(INLINE_CACHE_ENTRIES_SEND == 1, "incorrect cache size"); + PyObject *v = stack_pointer[-1]; + PyObject *receiver = stack_pointer[-2]; + PyObject *retval; + #line 826 "Python/bytecodes.c" + #if ENABLE_SPECIALIZATION + _PySendCache *cache = (_PySendCache *)next_instr; + if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { + next_instr--; + _Py_Specialize_Send(receiver, next_instr); + DISPATCH_SAME_OPARG(); + } + STAT_INC(SEND, deferred); + DECREMENT_ADAPTIVE_COUNTER(cache->counter); + #endif /* ENABLE_SPECIALIZATION */ + assert(frame != &entry_frame); + if ((tstate->interp->eval_frame == NULL) && + (Py_TYPE(receiver) == &PyGen_Type || Py_TYPE(receiver) == &PyCoro_Type) && + ((PyGenObject *)receiver)->gi_frame_state < FRAME_EXECUTING) + { + PyGenObject *gen = (PyGenObject *)receiver; + _PyInterpreterFrame *gen_frame = (_PyInterpreterFrame *)gen->gi_iframe; + frame->return_offset = oparg; + STACK_SHRINK(1); + _PyFrame_StackPush(gen_frame, v); + gen->gi_frame_state = FRAME_EXECUTING; + gen->gi_exc_state.previous_item = tstate->exc_info; + tstate->exc_info = &gen->gi_exc_state; + JUMPBY(INLINE_CACHE_ENTRIES_SEND); + DISPATCH_INLINED(gen_frame); + } + if (Py_IsNone(v) && PyIter_Check(receiver)) { + retval = Py_TYPE(receiver)->tp_iternext(receiver); + } + else { + retval = PyObject_CallMethodOneArg(receiver, &_Py_ID(send), v); + } + if (retval == NULL) { + if (_PyErr_ExceptionMatches(tstate, PyExc_StopIteration) + ) { + monitor_raise(tstate, frame, next_instr-1); + } + if (_PyGen_FetchStopIterationValue(&retval) == 0) { + assert(retval != NULL); + JUMPBY(oparg); + } + else { + goto error; + } + } + Py_DECREF(v); + #line 1198 "Python/generated_cases.c.h" + stack_pointer[-1] = retval; + next_instr += 1; + DISPATCH(); + } + + TARGET(SEND_GEN) { + PyObject *v = stack_pointer[-1]; + PyObject *receiver = stack_pointer[-2]; + #line 875 "Python/bytecodes.c" + DEOPT_IF(tstate->interp->eval_frame, SEND); + PyGenObject *gen = (PyGenObject *)receiver; + DEOPT_IF(Py_TYPE(gen) != &PyGen_Type && + Py_TYPE(gen) != &PyCoro_Type, SEND); + DEOPT_IF(gen->gi_frame_state >= FRAME_EXECUTING, SEND); + STAT_INC(SEND, hit); + _PyInterpreterFrame *gen_frame = (_PyInterpreterFrame *)gen->gi_iframe; + frame->return_offset = oparg; + STACK_SHRINK(1); + _PyFrame_StackPush(gen_frame, v); + gen->gi_frame_state = FRAME_EXECUTING; + gen->gi_exc_state.previous_item = tstate->exc_info; + tstate->exc_info = &gen->gi_exc_state; + JUMPBY(INLINE_CACHE_ENTRIES_SEND); + DISPATCH_INLINED(gen_frame); + #line 1223 "Python/generated_cases.c.h" + } + + TARGET(INSTRUMENTED_YIELD_VALUE) { + PyObject *retval = stack_pointer[-1]; + #line 893 "Python/bytecodes.c" + assert(frame != &entry_frame); + PyGenObject *gen = _PyFrame_GetGenerator(frame); + gen->gi_frame_state = FRAME_SUSPENDED; + _PyFrame_SetStackPointer(frame, stack_pointer - 1); + int err = _Py_call_instrumentation_arg( + tstate, PY_MONITORING_EVENT_PY_YIELD, + frame, next_instr-1, retval); + if (err) goto error; + tstate->exc_info = gen->gi_exc_state.previous_item; + gen->gi_exc_state.previous_item = NULL; + _Py_LeaveRecursiveCallPy(tstate); + _PyInterpreterFrame *gen_frame = frame; + frame = cframe.current_frame = frame->previous; + gen_frame->previous = NULL; + _PyFrame_StackPush(frame, retval); + goto resume_frame; + #line 1245 "Python/generated_cases.c.h" + } + + TARGET(YIELD_VALUE) { + PyObject *retval = stack_pointer[-1]; + #line 912 "Python/bytecodes.c" + // NOTE: It's important that YIELD_VALUE never raises an exception! + // The compiler treats any exception raised here as a failed close() + // or throw() call. + assert(frame != &entry_frame); + PyGenObject *gen = _PyFrame_GetGenerator(frame); + gen->gi_frame_state = FRAME_SUSPENDED; + _PyFrame_SetStackPointer(frame, stack_pointer - 1); + tstate->exc_info = gen->gi_exc_state.previous_item; + gen->gi_exc_state.previous_item = NULL; + _Py_LeaveRecursiveCallPy(tstate); + _PyInterpreterFrame *gen_frame = frame; + frame = cframe.current_frame = frame->previous; + gen_frame->previous = NULL; + _PyFrame_StackPush(frame, retval); + goto resume_frame; + #line 1266 "Python/generated_cases.c.h" + } + + TARGET(POP_EXCEPT) { + PyObject *exc_value = stack_pointer[-1]; + #line 930 "Python/bytecodes.c" + _PyErr_StackItem *exc_info = tstate->exc_info; + Py_XSETREF(exc_info->exc_value, exc_value); + #line 1274 "Python/generated_cases.c.h" + STACK_SHRINK(1); + DISPATCH(); + } + + TARGET(RERAISE) { + PyObject *exc = stack_pointer[-1]; + PyObject **values = (stack_pointer - (1 + oparg)); + #line 935 "Python/bytecodes.c" + assert(oparg >= 0 && oparg <= 2); + if (oparg) { + PyObject *lasti = values[0]; + if (PyLong_Check(lasti)) { + frame->prev_instr = _PyCode_CODE(frame->f_code) + PyLong_AsLong(lasti); + assert(!_PyErr_Occurred(tstate)); + } + else { + assert(PyLong_Check(lasti)); + _PyErr_SetString(tstate, PyExc_SystemError, "lasti is not an int"); + goto error; + } + } + assert(exc && PyExceptionInstance_Check(exc)); + Py_INCREF(exc); + _PyErr_SetRaisedException(tstate, exc); + monitor_reraise(tstate, frame, next_instr-1); + goto exception_unwind; + #line 1301 "Python/generated_cases.c.h" + } + + TARGET(END_ASYNC_FOR) { + PyObject *exc = stack_pointer[-1]; + PyObject *awaitable = stack_pointer[-2]; + #line 956 "Python/bytecodes.c" + assert(exc && PyExceptionInstance_Check(exc)); + if (PyErr_GivenExceptionMatches(exc, PyExc_StopAsyncIteration)) { + #line 1310 "Python/generated_cases.c.h" + Py_DECREF(awaitable); + Py_DECREF(exc); + #line 959 "Python/bytecodes.c" + } + else { + Py_INCREF(exc); + _PyErr_SetRaisedException(tstate, exc); + monitor_reraise(tstate, frame, next_instr-1); + goto exception_unwind; + } + #line 1321 "Python/generated_cases.c.h" + STACK_SHRINK(2); + DISPATCH(); + } + + TARGET(CLEANUP_THROW) { + PyObject *exc_value = stack_pointer[-1]; + PyObject *last_sent_val = stack_pointer[-2]; + PyObject *sub_iter = stack_pointer[-3]; + PyObject *none; + PyObject *value; + #line 969 "Python/bytecodes.c" + assert(throwflag); + assert(exc_value && PyExceptionInstance_Check(exc_value)); + if (PyErr_GivenExceptionMatches(exc_value, PyExc_StopIteration)) { + value = Py_NewRef(((PyStopIterationObject *)exc_value)->value); + #line 1337 "Python/generated_cases.c.h" + Py_DECREF(sub_iter); + Py_DECREF(last_sent_val); + Py_DECREF(exc_value); + #line 974 "Python/bytecodes.c" + none = Py_None; + } + else { + _PyErr_SetRaisedException(tstate, Py_NewRef(exc_value)); + monitor_reraise(tstate, frame, next_instr-1); + goto exception_unwind; + } + #line 1349 "Python/generated_cases.c.h" + STACK_SHRINK(1); + stack_pointer[-1] = value; + stack_pointer[-2] = none; + DISPATCH(); + } + + TARGET(LOAD_ASSERTION_ERROR) { + PyObject *value; + #line 984 "Python/bytecodes.c" + value = Py_NewRef(PyExc_AssertionError); + #line 1360 "Python/generated_cases.c.h" + STACK_GROW(1); + stack_pointer[-1] = value; + DISPATCH(); + } + + TARGET(LOAD_BUILD_CLASS) { + PyObject *bc; + #line 988 "Python/bytecodes.c" + if (PyDict_CheckExact(BUILTINS())) { + bc = _PyDict_GetItemWithError(BUILTINS(), + &_Py_ID(__build_class__)); + if (bc == NULL) { + if (!_PyErr_Occurred(tstate)) { + _PyErr_SetString(tstate, PyExc_NameError, + "__build_class__ not found"); + } + if (true) goto error; + } + Py_INCREF(bc); + } + else { + bc = PyObject_GetItem(BUILTINS(), &_Py_ID(__build_class__)); + if (bc == NULL) { + if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) + _PyErr_SetString(tstate, PyExc_NameError, + "__build_class__ not found"); + if (true) goto error; + } + } + #line 1390 "Python/generated_cases.c.h" + STACK_GROW(1); + stack_pointer[-1] = bc; + DISPATCH(); + } + + TARGET(STORE_NAME) { + PyObject *v = stack_pointer[-1]; + #line 1013 "Python/bytecodes.c" + PyObject *name = GETITEM(frame->f_code->co_names, oparg); + PyObject *ns = LOCALS(); + int err; + if (ns == NULL) { + _PyErr_Format(tstate, PyExc_SystemError, + "no locals found when storing %R", name); + #line 1405 "Python/generated_cases.c.h" + Py_DECREF(v); + #line 1020 "Python/bytecodes.c" + if (true) goto pop_1_error; + } + if (PyDict_CheckExact(ns)) + err = PyDict_SetItem(ns, name, v); + else + err = PyObject_SetItem(ns, name, v); + #line 1414 "Python/generated_cases.c.h" + Py_DECREF(v); + #line 1027 "Python/bytecodes.c" + if (err) goto pop_1_error; + #line 1418 "Python/generated_cases.c.h" + STACK_SHRINK(1); + DISPATCH(); + } + + TARGET(DELETE_NAME) { + #line 1031 "Python/bytecodes.c" + PyObject *name = GETITEM(frame->f_code->co_names, oparg); + PyObject *ns = LOCALS(); + int err; + if (ns == NULL) { + _PyErr_Format(tstate, PyExc_SystemError, + "no locals when deleting %R", name); + goto error; + } + err = PyObject_DelItem(ns, name); + // Can't use ERROR_IF here. + if (err != 0) { + format_exc_check_arg(tstate, PyExc_NameError, + NAME_ERROR_MSG, + name); + goto error; + } + #line 1441 "Python/generated_cases.c.h" + DISPATCH(); + } + + TARGET(UNPACK_SEQUENCE) { + PREDICTED(UNPACK_SEQUENCE); + static_assert(INLINE_CACHE_ENTRIES_UNPACK_SEQUENCE == 1, "incorrect cache size"); + PyObject *seq = stack_pointer[-1]; + #line 1057 "Python/bytecodes.c" + #if ENABLE_SPECIALIZATION + _PyUnpackSequenceCache *cache = (_PyUnpackSequenceCache *)next_instr; + if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { + next_instr--; + _Py_Specialize_UnpackSequence(seq, next_instr, oparg); + DISPATCH_SAME_OPARG(); + } + STAT_INC(UNPACK_SEQUENCE, deferred); + DECREMENT_ADAPTIVE_COUNTER(cache->counter); + #endif /* ENABLE_SPECIALIZATION */ + PyObject **top = stack_pointer + oparg - 1; + int res = unpack_iterable(tstate, seq, oparg, -1, top); + #line 1462 "Python/generated_cases.c.h" + Py_DECREF(seq); + #line 1070 "Python/bytecodes.c" + if (res == 0) goto pop_1_error; + #line 1466 "Python/generated_cases.c.h" + STACK_SHRINK(1); + STACK_GROW(oparg); + next_instr += 1; + DISPATCH(); + } + + TARGET(UNPACK_SEQUENCE_TWO_TUPLE) { + PyObject *seq = stack_pointer[-1]; + PyObject **values = stack_pointer - (1); + #line 1074 "Python/bytecodes.c" + DEOPT_IF(!PyTuple_CheckExact(seq), UNPACK_SEQUENCE); + DEOPT_IF(PyTuple_GET_SIZE(seq) != 2, UNPACK_SEQUENCE); + assert(oparg == 2); + STAT_INC(UNPACK_SEQUENCE, hit); + values[0] = Py_NewRef(PyTuple_GET_ITEM(seq, 1)); + values[1] = Py_NewRef(PyTuple_GET_ITEM(seq, 0)); + #line 1483 "Python/generated_cases.c.h" + Py_DECREF(seq); + STACK_SHRINK(1); + STACK_GROW(oparg); + next_instr += 1; + DISPATCH(); + } + + TARGET(UNPACK_SEQUENCE_TUPLE) { + PyObject *seq = stack_pointer[-1]; + PyObject **values = stack_pointer - (1); + #line 1084 "Python/bytecodes.c" + DEOPT_IF(!PyTuple_CheckExact(seq), UNPACK_SEQUENCE); + DEOPT_IF(PyTuple_GET_SIZE(seq) != oparg, UNPACK_SEQUENCE); + STAT_INC(UNPACK_SEQUENCE, hit); + PyObject **items = _PyTuple_ITEMS(seq); + for (int i = oparg; --i >= 0; ) { + *values++ = Py_NewRef(items[i]); + } + #line 1502 "Python/generated_cases.c.h" + Py_DECREF(seq); + STACK_SHRINK(1); + STACK_GROW(oparg); + next_instr += 1; + DISPATCH(); + } + + TARGET(UNPACK_SEQUENCE_LIST) { + PyObject *seq = stack_pointer[-1]; + PyObject **values = stack_pointer - (1); + #line 1095 "Python/bytecodes.c" + DEOPT_IF(!PyList_CheckExact(seq), UNPACK_SEQUENCE); + DEOPT_IF(PyList_GET_SIZE(seq) != oparg, UNPACK_SEQUENCE); + STAT_INC(UNPACK_SEQUENCE, hit); + PyObject **items = _PyList_ITEMS(seq); + for (int i = oparg; --i >= 0; ) { + *values++ = Py_NewRef(items[i]); + } + #line 1521 "Python/generated_cases.c.h" + Py_DECREF(seq); + STACK_SHRINK(1); + STACK_GROW(oparg); + next_instr += 1; + DISPATCH(); + } + + TARGET(UNPACK_EX) { + PyObject *seq = stack_pointer[-1]; + #line 1106 "Python/bytecodes.c" + int totalargs = 1 + (oparg & 0xFF) + (oparg >> 8); + PyObject **top = stack_pointer + totalargs - 1; + int res = unpack_iterable(tstate, seq, oparg & 0xFF, oparg >> 8, top); + #line 1535 "Python/generated_cases.c.h" + Py_DECREF(seq); + #line 1110 "Python/bytecodes.c" + if (res == 0) goto pop_1_error; + #line 1539 "Python/generated_cases.c.h" + STACK_GROW((oparg & 0xFF) + (oparg >> 8)); + DISPATCH(); + } + + TARGET(STORE_ATTR) { + PREDICTED(STORE_ATTR); + static_assert(INLINE_CACHE_ENTRIES_STORE_ATTR == 4, "incorrect cache size"); + PyObject *owner = stack_pointer[-1]; + PyObject *v = stack_pointer[-2]; + uint16_t counter = read_u16(&next_instr[0].cache); + #line 1121 "Python/bytecodes.c" + #if ENABLE_SPECIALIZATION + if (ADAPTIVE_COUNTER_IS_ZERO(counter)) { + PyObject *name = GETITEM(frame->f_code->co_names, oparg); + next_instr--; + _Py_Specialize_StoreAttr(owner, next_instr, name); + DISPATCH_SAME_OPARG(); + } + STAT_INC(STORE_ATTR, deferred); + _PyAttrCache *cache = (_PyAttrCache *)next_instr; + DECREMENT_ADAPTIVE_COUNTER(cache->counter); + #else + (void)counter; // Unused. + #endif /* ENABLE_SPECIALIZATION */ + PyObject *name = GETITEM(frame->f_code->co_names, oparg); + int err = PyObject_SetAttr(owner, name, v); + #line 1566 "Python/generated_cases.c.h" + Py_DECREF(v); + Py_DECREF(owner); + #line 1137 "Python/bytecodes.c" + if (err) goto pop_2_error; + #line 1571 "Python/generated_cases.c.h" + STACK_SHRINK(2); + next_instr += 4; + DISPATCH(); + } + + TARGET(DELETE_ATTR) { + PyObject *owner = stack_pointer[-1]; + #line 1141 "Python/bytecodes.c" + PyObject *name = GETITEM(frame->f_code->co_names, oparg); + int err = PyObject_SetAttr(owner, name, (PyObject *)NULL); + #line 1582 "Python/generated_cases.c.h" + Py_DECREF(owner); + #line 1144 "Python/bytecodes.c" + if (err) goto pop_1_error; + #line 1586 "Python/generated_cases.c.h" + STACK_SHRINK(1); + DISPATCH(); + } + + TARGET(STORE_GLOBAL) { + PyObject *v = stack_pointer[-1]; + #line 1148 "Python/bytecodes.c" + PyObject *name = GETITEM(frame->f_code->co_names, oparg); + int err = PyDict_SetItem(GLOBALS(), name, v); + #line 1596 "Python/generated_cases.c.h" + Py_DECREF(v); + #line 1151 "Python/bytecodes.c" + if (err) goto pop_1_error; + #line 1600 "Python/generated_cases.c.h" + STACK_SHRINK(1); + DISPATCH(); + } + + TARGET(DELETE_GLOBAL) { + #line 1155 "Python/bytecodes.c" + PyObject *name = GETITEM(frame->f_code->co_names, oparg); + int err; + err = PyDict_DelItem(GLOBALS(), name); + // Can't use ERROR_IF here. + if (err != 0) { + if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { + format_exc_check_arg(tstate, PyExc_NameError, + NAME_ERROR_MSG, name); + } + goto error; + } + #line 1618 "Python/generated_cases.c.h" + DISPATCH(); + } + + TARGET(LOAD_LOCALS) { + PyObject *locals; + #line 1169 "Python/bytecodes.c" + locals = LOCALS(); + if (locals == NULL) { + _PyErr_SetString(tstate, PyExc_SystemError, + "no locals found"); + if (true) goto error; + } + Py_INCREF(locals); + #line 1632 "Python/generated_cases.c.h" + STACK_GROW(1); + stack_pointer[-1] = locals; + DISPATCH(); + } + + TARGET(LOAD_FROM_DICT_OR_GLOBALS) { + PyObject *mod_or_class_dict = stack_pointer[-1]; + PyObject *v; + #line 1179 "Python/bytecodes.c" + PyObject *name = GETITEM(frame->f_code->co_names, oparg); + if (PyDict_CheckExact(mod_or_class_dict)) { + v = PyDict_GetItemWithError(mod_or_class_dict, name); + if (v != NULL) { + Py_INCREF(v); + } + else if (_PyErr_Occurred(tstate)) { + goto error; + } + } + else { + v = PyObject_GetItem(mod_or_class_dict, name); + if (v == NULL) { + if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { + goto error; + } + _PyErr_Clear(tstate); + } + } + if (v == NULL) { + v = PyDict_GetItemWithError(GLOBALS(), name); + if (v != NULL) { + Py_INCREF(v); + } + else if (_PyErr_Occurred(tstate)) { + goto error; + } + else { + if (PyDict_CheckExact(BUILTINS())) { + v = PyDict_GetItemWithError(BUILTINS(), name); + if (v == NULL) { + if (!_PyErr_Occurred(tstate)) { + format_exc_check_arg( + tstate, PyExc_NameError, + NAME_ERROR_MSG, name); + } + goto error; + } + Py_INCREF(v); + } + else { + v = PyObject_GetItem(BUILTINS(), name); + if (v == NULL) { + if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { + format_exc_check_arg( + tstate, PyExc_NameError, + NAME_ERROR_MSG, name); + } + goto error; + } + } + } + } + #line 1695 "Python/generated_cases.c.h" + Py_DECREF(mod_or_class_dict); + stack_pointer[-1] = v; + DISPATCH(); + } + + TARGET(LOAD_NAME) { + PyObject *v; + #line 1236 "Python/bytecodes.c" + PyObject *mod_or_class_dict = LOCALS(); + if (mod_or_class_dict == NULL) { + _PyErr_SetString(tstate, PyExc_SystemError, + "no locals found"); + if (true) goto error; + } + PyObject *name = GETITEM(frame->f_code->co_names, oparg); + if (PyDict_CheckExact(mod_or_class_dict)) { + v = PyDict_GetItemWithError(mod_or_class_dict, name); + if (v != NULL) { + Py_INCREF(v); + } + else if (_PyErr_Occurred(tstate)) { + goto error; + } + } + else { + v = PyObject_GetItem(mod_or_class_dict, name); + if (v == NULL) { + if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { + goto error; + } + _PyErr_Clear(tstate); + } + } + if (v == NULL) { + v = PyDict_GetItemWithError(GLOBALS(), name); + if (v != NULL) { + Py_INCREF(v); + } + else if (_PyErr_Occurred(tstate)) { + goto error; + } + else { + if (PyDict_CheckExact(BUILTINS())) { + v = PyDict_GetItemWithError(BUILTINS(), name); + if (v == NULL) { + if (!_PyErr_Occurred(tstate)) { + format_exc_check_arg( + tstate, PyExc_NameError, + NAME_ERROR_MSG, name); + } + goto error; + } + Py_INCREF(v); + } + else { + v = PyObject_GetItem(BUILTINS(), name); + if (v == NULL) { + if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { + format_exc_check_arg( + tstate, PyExc_NameError, + NAME_ERROR_MSG, name); + } + goto error; + } + } + } + } + #line 1763 "Python/generated_cases.c.h" + STACK_GROW(1); + stack_pointer[-1] = v; + DISPATCH(); + } + + TARGET(LOAD_GLOBAL) { + PREDICTED(LOAD_GLOBAL); + static_assert(INLINE_CACHE_ENTRIES_LOAD_GLOBAL == 4, "incorrect cache size"); + PyObject *null = NULL; + PyObject *v; + #line 1304 "Python/bytecodes.c" + #if ENABLE_SPECIALIZATION + _PyLoadGlobalCache *cache = (_PyLoadGlobalCache *)next_instr; + if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { + PyObject *name = GETITEM(frame->f_code->co_names, oparg>>1); + next_instr--; + _Py_Specialize_LoadGlobal(GLOBALS(), BUILTINS(), next_instr, name); + DISPATCH_SAME_OPARG(); + } + STAT_INC(LOAD_GLOBAL, deferred); + DECREMENT_ADAPTIVE_COUNTER(cache->counter); + #endif /* ENABLE_SPECIALIZATION */ + PyObject *name = GETITEM(frame->f_code->co_names, oparg>>1); + if (PyDict_CheckExact(GLOBALS()) + && PyDict_CheckExact(BUILTINS())) + { + v = _PyDict_LoadGlobal((PyDictObject *)GLOBALS(), + (PyDictObject *)BUILTINS(), + name); + if (v == NULL) { + if (!_PyErr_Occurred(tstate)) { + /* _PyDict_LoadGlobal() returns NULL without raising + * an exception if the key doesn't exist */ + format_exc_check_arg(tstate, PyExc_NameError, + NAME_ERROR_MSG, name); + } + if (true) goto error; + } + Py_INCREF(v); + } + else { + /* Slow-path if globals or builtins is not a dict */ + + /* namespace 1: globals */ + v = PyObject_GetItem(GLOBALS(), name); + if (v == NULL) { + if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) goto error; + _PyErr_Clear(tstate); + + /* namespace 2: builtins */ + v = PyObject_GetItem(BUILTINS(), name); + if (v == NULL) { + if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { + format_exc_check_arg( + tstate, PyExc_NameError, + NAME_ERROR_MSG, name); + } + if (true) goto error; + } + } + } + null = NULL; + #line 1826 "Python/generated_cases.c.h" + STACK_GROW(1); + STACK_GROW(((oparg & 1) ? 1 : 0)); + stack_pointer[-1] = v; + if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = null; } + next_instr += 4; + DISPATCH(); + } + + TARGET(LOAD_GLOBAL_MODULE) { + PyObject *null = NULL; + PyObject *res; + uint16_t index = read_u16(&next_instr[1].cache); + uint16_t version = read_u16(&next_instr[2].cache); + #line 1358 "Python/bytecodes.c" + DEOPT_IF(!PyDict_CheckExact(GLOBALS()), LOAD_GLOBAL); + PyDictObject *dict = (PyDictObject *)GLOBALS(); + DEOPT_IF(dict->ma_keys->dk_version != version, LOAD_GLOBAL); + assert(DK_IS_UNICODE(dict->ma_keys)); + PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(dict->ma_keys); + res = entries[index].me_value; + DEOPT_IF(res == NULL, LOAD_GLOBAL); + Py_INCREF(res); + STAT_INC(LOAD_GLOBAL, hit); + null = NULL; + #line 1851 "Python/generated_cases.c.h" + STACK_GROW(1); + STACK_GROW(((oparg & 1) ? 1 : 0)); + stack_pointer[-1] = res; + if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = null; } + next_instr += 4; + DISPATCH(); + } + + TARGET(LOAD_GLOBAL_BUILTIN) { + PyObject *null = NULL; + PyObject *res; + uint16_t index = read_u16(&next_instr[1].cache); + uint16_t mod_version = read_u16(&next_instr[2].cache); + uint16_t bltn_version = read_u16(&next_instr[3].cache); + #line 1371 "Python/bytecodes.c" + DEOPT_IF(!PyDict_CheckExact(GLOBALS()), LOAD_GLOBAL); + DEOPT_IF(!PyDict_CheckExact(BUILTINS()), LOAD_GLOBAL); + PyDictObject *mdict = (PyDictObject *)GLOBALS(); + PyDictObject *bdict = (PyDictObject *)BUILTINS(); + assert(opcode == LOAD_GLOBAL_BUILTIN); + DEOPT_IF(mdict->ma_keys->dk_version != mod_version, LOAD_GLOBAL); + DEOPT_IF(bdict->ma_keys->dk_version != bltn_version, LOAD_GLOBAL); + assert(DK_IS_UNICODE(bdict->ma_keys)); + PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(bdict->ma_keys); + res = entries[index].me_value; + DEOPT_IF(res == NULL, LOAD_GLOBAL); + Py_INCREF(res); + STAT_INC(LOAD_GLOBAL, hit); + null = NULL; + #line 1881 "Python/generated_cases.c.h" + STACK_GROW(1); + STACK_GROW(((oparg & 1) ? 1 : 0)); + stack_pointer[-1] = res; + if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = null; } + next_instr += 4; + DISPATCH(); + } + + TARGET(DELETE_FAST) { + #line 1388 "Python/bytecodes.c" + PyObject *v = GETLOCAL(oparg); + if (v == NULL) goto unbound_local_error; + SETLOCAL(oparg, NULL); + #line 1895 "Python/generated_cases.c.h" + DISPATCH(); + } + + TARGET(MAKE_CELL) { + #line 1394 "Python/bytecodes.c" + // "initial" is probably NULL but not if it's an arg (or set + // via PyFrame_LocalsToFast() before MAKE_CELL has run). + PyObject *initial = GETLOCAL(oparg); + PyObject *cell = PyCell_New(initial); + if (cell == NULL) { + goto resume_with_error; + } + SETLOCAL(oparg, cell); + #line 1909 "Python/generated_cases.c.h" + DISPATCH(); + } + + TARGET(DELETE_DEREF) { + #line 1405 "Python/bytecodes.c" + PyObject *cell = GETLOCAL(oparg); + PyObject *oldobj = PyCell_GET(cell); + // Can't use ERROR_IF here. + // Fortunately we don't need its superpower. + if (oldobj == NULL) { + format_exc_unbound(tstate, frame->f_code, oparg); + goto error; + } + PyCell_SET(cell, NULL); + Py_DECREF(oldobj); + #line 1925 "Python/generated_cases.c.h" + DISPATCH(); + } + + TARGET(LOAD_FROM_DICT_OR_DEREF) { + PyObject *class_dict = stack_pointer[-1]; + PyObject *value; + #line 1418 "Python/bytecodes.c" + PyObject *name; + assert(class_dict); + assert(oparg >= 0 && oparg < frame->f_code->co_nlocalsplus); + name = PyTuple_GET_ITEM(frame->f_code->co_localsplusnames, oparg); + if (PyDict_CheckExact(class_dict)) { + value = PyDict_GetItemWithError(class_dict, name); + if (value != NULL) { + Py_INCREF(value); + } + else if (_PyErr_Occurred(tstate)) { + Py_DECREF(class_dict); + goto error; + } + } + else { + value = PyObject_GetItem(class_dict, name); + if (value == NULL) { + if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { + Py_DECREF(class_dict); + goto error; + } + _PyErr_Clear(tstate); + } + } + Py_DECREF(class_dict); + if (!value) { + PyObject *cell = GETLOCAL(oparg); + value = PyCell_GET(cell); + if (value == NULL) { + format_exc_unbound(tstate, frame->f_code, oparg); + goto error; + } + Py_INCREF(value); + } + #line 1967 "Python/generated_cases.c.h" + stack_pointer[-1] = value; + DISPATCH(); + } + + TARGET(LOAD_DEREF) { + PyObject *value; + #line 1455 "Python/bytecodes.c" + PyObject *cell = GETLOCAL(oparg); + value = PyCell_GET(cell); + if (value == NULL) { + format_exc_unbound(tstate, frame->f_code, oparg); + if (true) goto error; + } + Py_INCREF(value); + #line 1982 "Python/generated_cases.c.h" + STACK_GROW(1); + stack_pointer[-1] = value; + DISPATCH(); + } + + TARGET(STORE_DEREF) { + PyObject *v = stack_pointer[-1]; + #line 1465 "Python/bytecodes.c" + PyObject *cell = GETLOCAL(oparg); + PyObject *oldobj = PyCell_GET(cell); + PyCell_SET(cell, v); + Py_XDECREF(oldobj); + #line 1995 "Python/generated_cases.c.h" + STACK_SHRINK(1); + DISPATCH(); + } + + TARGET(COPY_FREE_VARS) { + #line 1472 "Python/bytecodes.c" + /* Copy closure variables to free variables */ + PyCodeObject *co = frame->f_code; + assert(PyFunction_Check(frame->f_funcobj)); + PyObject *closure = ((PyFunctionObject *)frame->f_funcobj)->func_closure; + assert(oparg == co->co_nfreevars); + int offset = co->co_nlocalsplus - oparg; + for (int i = 0; i < oparg; ++i) { + PyObject *o = PyTuple_GET_ITEM(closure, i); + frame->localsplus[offset + i] = Py_NewRef(o); + } + #line 2012 "Python/generated_cases.c.h" + DISPATCH(); + } + + TARGET(BUILD_STRING) { + PyObject **pieces = (stack_pointer - oparg); + PyObject *str; + #line 1485 "Python/bytecodes.c" + str = _PyUnicode_JoinArray(&_Py_STR(empty), pieces, oparg); + #line 2021 "Python/generated_cases.c.h" + for (int _i = oparg; --_i >= 0;) { + Py_DECREF(pieces[_i]); + } + #line 1487 "Python/bytecodes.c" + if (str == NULL) { STACK_SHRINK(oparg); goto error; } + #line 2027 "Python/generated_cases.c.h" + STACK_SHRINK(oparg); + STACK_GROW(1); + stack_pointer[-1] = str; + DISPATCH(); + } + + TARGET(BUILD_TUPLE) { + PyObject **values = (stack_pointer - oparg); + PyObject *tup; + #line 1491 "Python/bytecodes.c" + tup = _PyTuple_FromArraySteal(values, oparg); + if (tup == NULL) { STACK_SHRINK(oparg); goto error; } + #line 2040 "Python/generated_cases.c.h" + STACK_SHRINK(oparg); + STACK_GROW(1); + stack_pointer[-1] = tup; + DISPATCH(); + } + + TARGET(BUILD_LIST) { + PyObject **values = (stack_pointer - oparg); + PyObject *list; + #line 1496 "Python/bytecodes.c" + list = _PyList_FromArraySteal(values, oparg); + if (list == NULL) { STACK_SHRINK(oparg); goto error; } + #line 2053 "Python/generated_cases.c.h" + STACK_SHRINK(oparg); + STACK_GROW(1); + stack_pointer[-1] = list; + DISPATCH(); + } + + TARGET(LIST_EXTEND) { + PyObject *iterable = stack_pointer[-1]; + PyObject *list = stack_pointer[-(2 + (oparg-1))]; + #line 1501 "Python/bytecodes.c" + PyObject *none_val = _PyList_Extend((PyListObject *)list, iterable); + if (none_val == NULL) { + if (_PyErr_ExceptionMatches(tstate, PyExc_TypeError) && + (Py_TYPE(iterable)->tp_iter == NULL && !PySequence_Check(iterable))) + { + _PyErr_Clear(tstate); + _PyErr_Format(tstate, PyExc_TypeError, + "Value after * must be an iterable, not %.200s", + Py_TYPE(iterable)->tp_name); + } + #line 2074 "Python/generated_cases.c.h" + Py_DECREF(iterable); + #line 1512 "Python/bytecodes.c" + if (true) goto pop_1_error; + } + assert(Py_IsNone(none_val)); + #line 2080 "Python/generated_cases.c.h" + Py_DECREF(iterable); + STACK_SHRINK(1); + DISPATCH(); + } + + TARGET(SET_UPDATE) { + PyObject *iterable = stack_pointer[-1]; + PyObject *set = stack_pointer[-(2 + (oparg-1))]; + #line 1519 "Python/bytecodes.c" + int err = _PySet_Update(set, iterable); + #line 2091 "Python/generated_cases.c.h" + Py_DECREF(iterable); + #line 1521 "Python/bytecodes.c" + if (err < 0) goto pop_1_error; + #line 2095 "Python/generated_cases.c.h" + STACK_SHRINK(1); + DISPATCH(); + } + + TARGET(BUILD_SET) { + PyObject **values = (stack_pointer - oparg); + PyObject *set; + #line 1525 "Python/bytecodes.c" + set = PySet_New(NULL); + if (set == NULL) + goto error; + int err = 0; + for (int i = 0; i < oparg; i++) { + PyObject *item = values[i]; + if (err == 0) + err = PySet_Add(set, item); + Py_DECREF(item); + } + if (err != 0) { + Py_DECREF(set); + if (true) { STACK_SHRINK(oparg); goto error; } + } + #line 2118 "Python/generated_cases.c.h" + STACK_SHRINK(oparg); + STACK_GROW(1); + stack_pointer[-1] = set; + DISPATCH(); + } + + TARGET(BUILD_MAP) { + PyObject **values = (stack_pointer - oparg*2); + PyObject *map; + #line 1542 "Python/bytecodes.c" + map = _PyDict_FromItems( + values, 2, + values+1, 2, + oparg); + if (map == NULL) + goto error; + + #line 2136 "Python/generated_cases.c.h" + for (int _i = oparg*2; --_i >= 0;) { + Py_DECREF(values[_i]); + } + #line 1550 "Python/bytecodes.c" + if (map == NULL) { STACK_SHRINK(oparg*2); goto error; } + #line 2142 "Python/generated_cases.c.h" + STACK_SHRINK(oparg*2); + STACK_GROW(1); + stack_pointer[-1] = map; + DISPATCH(); + } + + TARGET(SETUP_ANNOTATIONS) { + #line 1554 "Python/bytecodes.c" + int err; + PyObject *ann_dict; + if (LOCALS() == NULL) { + _PyErr_Format(tstate, PyExc_SystemError, + "no locals found when setting up annotations"); + if (true) goto error; + } + /* check if __annotations__ in locals()... */ + if (PyDict_CheckExact(LOCALS())) { + ann_dict = _PyDict_GetItemWithError(LOCALS(), + &_Py_ID(__annotations__)); + if (ann_dict == NULL) { + if (_PyErr_Occurred(tstate)) goto error; + /* ...if not, create a new one */ + ann_dict = PyDict_New(); + if (ann_dict == NULL) goto error; + err = PyDict_SetItem(LOCALS(), &_Py_ID(__annotations__), + ann_dict); + Py_DECREF(ann_dict); + if (err) goto error; + } + } + else { + /* do the same if locals() is not a dict */ + ann_dict = PyObject_GetItem(LOCALS(), &_Py_ID(__annotations__)); + if (ann_dict == NULL) { + if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) goto error; + _PyErr_Clear(tstate); + ann_dict = PyDict_New(); + if (ann_dict == NULL) goto error; + err = PyObject_SetItem(LOCALS(), &_Py_ID(__annotations__), + ann_dict); + Py_DECREF(ann_dict); + if (err) goto error; + } + else { + Py_DECREF(ann_dict); + } + } + #line 2190 "Python/generated_cases.c.h" + DISPATCH(); + } + + TARGET(BUILD_CONST_KEY_MAP) { + PyObject *keys = stack_pointer[-1]; + PyObject **values = (stack_pointer - (1 + oparg)); + PyObject *map; + #line 1596 "Python/bytecodes.c" + if (!PyTuple_CheckExact(keys) || + PyTuple_GET_SIZE(keys) != (Py_ssize_t)oparg) { + _PyErr_SetString(tstate, PyExc_SystemError, + "bad BUILD_CONST_KEY_MAP keys argument"); + goto error; // Pop the keys and values. + } + map = _PyDict_FromItems( + &PyTuple_GET_ITEM(keys, 0), 1, + values, 1, oparg); + #line 2208 "Python/generated_cases.c.h" + for (int _i = oparg; --_i >= 0;) { + Py_DECREF(values[_i]); + } + Py_DECREF(keys); + #line 1606 "Python/bytecodes.c" + if (map == NULL) { STACK_SHRINK(oparg); goto pop_1_error; } + #line 2215 "Python/generated_cases.c.h" + STACK_SHRINK(oparg); + stack_pointer[-1] = map; + DISPATCH(); + } + + TARGET(DICT_UPDATE) { + PyObject *update = stack_pointer[-1]; + #line 1610 "Python/bytecodes.c" + PyObject *dict = PEEK(oparg + 1); // update is still on the stack + if (PyDict_Update(dict, update) < 0) { + if (_PyErr_ExceptionMatches(tstate, PyExc_AttributeError)) { + _PyErr_Format(tstate, PyExc_TypeError, + "'%.200s' object is not a mapping", + Py_TYPE(update)->tp_name); + } + #line 2231 "Python/generated_cases.c.h" + Py_DECREF(update); + #line 1618 "Python/bytecodes.c" + if (true) goto pop_1_error; + } + #line 2236 "Python/generated_cases.c.h" + Py_DECREF(update); + STACK_SHRINK(1); + DISPATCH(); + } + + TARGET(DICT_MERGE) { + PyObject *update = stack_pointer[-1]; + #line 1624 "Python/bytecodes.c" + PyObject *dict = PEEK(oparg + 1); // update is still on the stack + + if (_PyDict_MergeEx(dict, update, 2) < 0) { + format_kwargs_error(tstate, PEEK(3 + oparg), update); + #line 2249 "Python/generated_cases.c.h" + Py_DECREF(update); + #line 1629 "Python/bytecodes.c" + if (true) goto pop_1_error; + } + #line 2254 "Python/generated_cases.c.h" + Py_DECREF(update); + STACK_SHRINK(1); + PREDICT(CALL_FUNCTION_EX); + DISPATCH(); + } + + TARGET(MAP_ADD) { + PyObject *value = stack_pointer[-1]; + PyObject *key = stack_pointer[-2]; + #line 1636 "Python/bytecodes.c" + PyObject *dict = PEEK(oparg + 2); // key, value are still on the stack + assert(PyDict_CheckExact(dict)); + /* dict[key] = value */ + // Do not DECREF INPUTS because the function steals the references + if (_PyDict_SetItem_Take2((PyDictObject *)dict, key, value) != 0) goto pop_2_error; + #line 2270 "Python/generated_cases.c.h" + STACK_SHRINK(2); + PREDICT(JUMP_BACKWARD); + DISPATCH(); + } + + TARGET(INSTRUMENTED_LOAD_SUPER_ATTR) { + #line 1645 "Python/bytecodes.c" + _PySuperAttrCache *cache = (_PySuperAttrCache *)next_instr; + // cancel out the decrement that will happen in LOAD_SUPER_ATTR; we + // don't want to specialize instrumented instructions + INCREMENT_ADAPTIVE_COUNTER(cache->counter); + GO_TO_INSTRUCTION(LOAD_SUPER_ATTR); + #line 2283 "Python/generated_cases.c.h" + } + + TARGET(LOAD_SUPER_ATTR) { + PREDICTED(LOAD_SUPER_ATTR); + static_assert(INLINE_CACHE_ENTRIES_LOAD_SUPER_ATTR == 1, "incorrect cache size"); + PyObject *self = stack_pointer[-1]; + PyObject *class = stack_pointer[-2]; + PyObject *global_super = stack_pointer[-3]; + PyObject *res2 = NULL; + PyObject *res; + #line 1659 "Python/bytecodes.c" + PyObject *name = GETITEM(frame->f_code->co_names, oparg >> 2); + int load_method = oparg & 1; + #if ENABLE_SPECIALIZATION + _PySuperAttrCache *cache = (_PySuperAttrCache *)next_instr; + if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { + next_instr--; + _Py_Specialize_LoadSuperAttr(global_super, class, next_instr, load_method); + DISPATCH_SAME_OPARG(); + } + STAT_INC(LOAD_SUPER_ATTR, deferred); + DECREMENT_ADAPTIVE_COUNTER(cache->counter); + #endif /* ENABLE_SPECIALIZATION */ + + if (opcode == INSTRUMENTED_LOAD_SUPER_ATTR) { + PyObject *arg = oparg & 2 ? class : &_PyInstrumentation_MISSING; + int err = _Py_call_instrumentation_2args( + tstate, PY_MONITORING_EVENT_CALL, + frame, next_instr-1, global_super, arg); + if (err) goto pop_3_error; + } + + // we make no attempt to optimize here; specializations should + // handle any case whose performance we care about + PyObject *stack[] = {class, self}; + PyObject *super = PyObject_Vectorcall(global_super, stack, oparg & 2, NULL); + if (opcode == INSTRUMENTED_LOAD_SUPER_ATTR) { + PyObject *arg = oparg & 2 ? class : &_PyInstrumentation_MISSING; + if (super == NULL) { + _Py_call_instrumentation_exc2( + tstate, PY_MONITORING_EVENT_C_RAISE, + frame, next_instr-1, global_super, arg); + } + else { + int err = _Py_call_instrumentation_2args( + tstate, PY_MONITORING_EVENT_C_RETURN, + frame, next_instr-1, global_super, arg); + if (err < 0) { + Py_CLEAR(super); + } + } + } + #line 2336 "Python/generated_cases.c.h" + Py_DECREF(global_super); + Py_DECREF(class); + Py_DECREF(self); + #line 1701 "Python/bytecodes.c" + if (super == NULL) goto pop_3_error; + res = PyObject_GetAttr(super, name); + Py_DECREF(super); + if (res == NULL) goto pop_3_error; + #line 2345 "Python/generated_cases.c.h" + STACK_SHRINK(2); + STACK_GROW(((oparg & 1) ? 1 : 0)); + stack_pointer[-1] = res; + if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = res2; } + next_instr += 1; + DISPATCH(); + } + + TARGET(LOAD_SUPER_ATTR_ATTR) { + PyObject *self = stack_pointer[-1]; + PyObject *class = stack_pointer[-2]; + PyObject *global_super = stack_pointer[-3]; + PyObject *res2 = NULL; + PyObject *res; + #line 1708 "Python/bytecodes.c" + assert(!(oparg & 1)); + DEOPT_IF(global_super != (PyObject *)&PySuper_Type, LOAD_SUPER_ATTR); + DEOPT_IF(!PyType_Check(class), LOAD_SUPER_ATTR); + STAT_INC(LOAD_SUPER_ATTR, hit); + PyObject *name = GETITEM(frame->f_code->co_names, oparg >> 2); + res = _PySuper_Lookup((PyTypeObject *)class, self, name, NULL); + #line 2367 "Python/generated_cases.c.h" + Py_DECREF(global_super); + Py_DECREF(class); + Py_DECREF(self); + #line 1715 "Python/bytecodes.c" + if (res == NULL) goto pop_3_error; + #line 2373 "Python/generated_cases.c.h" + STACK_SHRINK(2); + STACK_GROW(((oparg & 1) ? 1 : 0)); + stack_pointer[-1] = res; + if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = res2; } + next_instr += 1; + DISPATCH(); + } + + TARGET(LOAD_SUPER_ATTR_METHOD) { + PyObject *self = stack_pointer[-1]; + PyObject *class = stack_pointer[-2]; + PyObject *global_super = stack_pointer[-3]; + PyObject *res2; + PyObject *res; + #line 1719 "Python/bytecodes.c" + assert(oparg & 1); + DEOPT_IF(global_super != (PyObject *)&PySuper_Type, LOAD_SUPER_ATTR); + DEOPT_IF(!PyType_Check(class), LOAD_SUPER_ATTR); + STAT_INC(LOAD_SUPER_ATTR, hit); + PyObject *name = GETITEM(frame->f_code->co_names, oparg >> 2); + PyTypeObject *cls = (PyTypeObject *)class; + int method_found = 0; + res2 = _PySuper_Lookup(cls, self, name, + Py_TYPE(self)->tp_getattro == PyObject_GenericGetAttr ? &method_found : NULL); + Py_DECREF(global_super); + Py_DECREF(class); + if (res2 == NULL) { + Py_DECREF(self); + if (true) goto pop_3_error; + } + if (method_found) { + res = self; // transfer ownership + } else { + Py_DECREF(self); + res = res2; + res2 = NULL; + } + #line 2411 "Python/generated_cases.c.h" + STACK_SHRINK(1); + stack_pointer[-1] = res; + stack_pointer[-2] = res2; + next_instr += 1; + DISPATCH(); + } + + TARGET(LOAD_ATTR) { + PREDICTED(LOAD_ATTR); + static_assert(INLINE_CACHE_ENTRIES_LOAD_ATTR == 9, "incorrect cache size"); + PyObject *owner = stack_pointer[-1]; + PyObject *res2 = NULL; + PyObject *res; + #line 1758 "Python/bytecodes.c" + #if ENABLE_SPECIALIZATION + _PyAttrCache *cache = (_PyAttrCache *)next_instr; + if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { + PyObject *name = GETITEM(frame->f_code->co_names, oparg>>1); + next_instr--; + _Py_Specialize_LoadAttr(owner, next_instr, name); + DISPATCH_SAME_OPARG(); + } + STAT_INC(LOAD_ATTR, deferred); + DECREMENT_ADAPTIVE_COUNTER(cache->counter); + #endif /* ENABLE_SPECIALIZATION */ + PyObject *name = GETITEM(frame->f_code->co_names, oparg >> 1); + if (oparg & 1) { + /* Designed to work in tandem with CALL, pushes two values. */ + PyObject* meth = NULL; + if (_PyObject_GetMethod(owner, name, &meth)) { + /* We can bypass temporary bound method object. + meth is unbound method and obj is self. + + meth | self | arg1 | ... | argN + */ + assert(meth != NULL); // No errors on this branch + res2 = meth; + res = owner; // Transfer ownership + } + else { + /* meth is not an unbound method (but a regular attr, or + something was returned by a descriptor protocol). Set + the second element of the stack to NULL, to signal + CALL that it's not a method call. + + NULL | meth | arg1 | ... | argN + */ + #line 2459 "Python/generated_cases.c.h" + Py_DECREF(owner); + #line 1792 "Python/bytecodes.c" + if (meth == NULL) goto pop_1_error; + res2 = NULL; + res = meth; + } + } + else { + /* Classic, pushes one value. */ + res = PyObject_GetAttr(owner, name); + #line 2470 "Python/generated_cases.c.h" + Py_DECREF(owner); + #line 1801 "Python/bytecodes.c" + if (res == NULL) goto pop_1_error; + } + #line 2475 "Python/generated_cases.c.h" + STACK_GROW(((oparg & 1) ? 1 : 0)); + stack_pointer[-1] = res; + if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = res2; } + next_instr += 9; + DISPATCH(); + } + + TARGET(LOAD_ATTR_INSTANCE_VALUE) { + PyObject *owner = stack_pointer[-1]; + PyObject *res2 = NULL; + PyObject *res; + uint32_t type_version = read_u32(&next_instr[1].cache); + uint16_t index = read_u16(&next_instr[3].cache); + #line 1806 "Python/bytecodes.c" + PyTypeObject *tp = Py_TYPE(owner); + assert(type_version != 0); + DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR); + assert(tp->tp_dictoffset < 0); + assert(tp->tp_flags & Py_TPFLAGS_MANAGED_DICT); + PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); + DEOPT_IF(!_PyDictOrValues_IsValues(dorv), LOAD_ATTR); + res = _PyDictOrValues_GetValues(dorv)->values[index]; + DEOPT_IF(res == NULL, LOAD_ATTR); + STAT_INC(LOAD_ATTR, hit); + Py_INCREF(res); + res2 = NULL; + #line 2502 "Python/generated_cases.c.h" + Py_DECREF(owner); + STACK_GROW(((oparg & 1) ? 1 : 0)); + stack_pointer[-1] = res; + if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = res2; } + next_instr += 9; + DISPATCH(); + } + + TARGET(LOAD_ATTR_MODULE) { + PyObject *owner = stack_pointer[-1]; + PyObject *res2 = NULL; + PyObject *res; + uint32_t type_version = read_u32(&next_instr[1].cache); + uint16_t index = read_u16(&next_instr[3].cache); + #line 1822 "Python/bytecodes.c" + DEOPT_IF(!PyModule_CheckExact(owner), LOAD_ATTR); + PyDictObject *dict = (PyDictObject *)((PyModuleObject *)owner)->md_dict; + assert(dict != NULL); + DEOPT_IF(dict->ma_keys->dk_version != type_version, LOAD_ATTR); + assert(dict->ma_keys->dk_kind == DICT_KEYS_UNICODE); + assert(index < dict->ma_keys->dk_nentries); + PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(dict->ma_keys) + index; + res = ep->me_value; + DEOPT_IF(res == NULL, LOAD_ATTR); + STAT_INC(LOAD_ATTR, hit); + Py_INCREF(res); + res2 = NULL; + #line 2530 "Python/generated_cases.c.h" + Py_DECREF(owner); + STACK_GROW(((oparg & 1) ? 1 : 0)); + stack_pointer[-1] = res; + if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = res2; } + next_instr += 9; + DISPATCH(); + } + + TARGET(LOAD_ATTR_WITH_HINT) { + PyObject *owner = stack_pointer[-1]; + PyObject *res2 = NULL; + PyObject *res; + uint32_t type_version = read_u32(&next_instr[1].cache); + uint16_t index = read_u16(&next_instr[3].cache); + #line 1838 "Python/bytecodes.c" + PyTypeObject *tp = Py_TYPE(owner); + assert(type_version != 0); + DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR); + assert(tp->tp_flags & Py_TPFLAGS_MANAGED_DICT); + PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); + DEOPT_IF(_PyDictOrValues_IsValues(dorv), LOAD_ATTR); + PyDictObject *dict = (PyDictObject *)_PyDictOrValues_GetDict(dorv); + DEOPT_IF(dict == NULL, LOAD_ATTR); + assert(PyDict_CheckExact((PyObject *)dict)); + PyObject *name = GETITEM(frame->f_code->co_names, oparg>>1); + uint16_t hint = index; + DEOPT_IF(hint >= (size_t)dict->ma_keys->dk_nentries, LOAD_ATTR); + if (DK_IS_UNICODE(dict->ma_keys)) { + PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(dict->ma_keys) + hint; + DEOPT_IF(ep->me_key != name, LOAD_ATTR); + res = ep->me_value; + } + else { + PyDictKeyEntry *ep = DK_ENTRIES(dict->ma_keys) + hint; + DEOPT_IF(ep->me_key != name, LOAD_ATTR); + res = ep->me_value; + } + DEOPT_IF(res == NULL, LOAD_ATTR); + STAT_INC(LOAD_ATTR, hit); + Py_INCREF(res); + res2 = NULL; + #line 2572 "Python/generated_cases.c.h" + Py_DECREF(owner); + STACK_GROW(((oparg & 1) ? 1 : 0)); + stack_pointer[-1] = res; + if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = res2; } + next_instr += 9; + DISPATCH(); + } + + TARGET(LOAD_ATTR_SLOT) { + PyObject *owner = stack_pointer[-1]; + PyObject *res2 = NULL; + PyObject *res; + uint32_t type_version = read_u32(&next_instr[1].cache); + uint16_t index = read_u16(&next_instr[3].cache); + #line 1868 "Python/bytecodes.c" + PyTypeObject *tp = Py_TYPE(owner); + assert(type_version != 0); + DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR); + char *addr = (char *)owner + index; + res = *(PyObject **)addr; + DEOPT_IF(res == NULL, LOAD_ATTR); + STAT_INC(LOAD_ATTR, hit); + Py_INCREF(res); + res2 = NULL; + #line 2597 "Python/generated_cases.c.h" + Py_DECREF(owner); + STACK_GROW(((oparg & 1) ? 1 : 0)); + stack_pointer[-1] = res; + if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = res2; } + next_instr += 9; + DISPATCH(); + } + + TARGET(LOAD_ATTR_CLASS) { + PyObject *cls = stack_pointer[-1]; + PyObject *res2 = NULL; + PyObject *res; + uint32_t type_version = read_u32(&next_instr[1].cache); + PyObject *descr = read_obj(&next_instr[5].cache); + #line 1881 "Python/bytecodes.c" + + DEOPT_IF(!PyType_Check(cls), LOAD_ATTR); + DEOPT_IF(((PyTypeObject *)cls)->tp_version_tag != type_version, + LOAD_ATTR); + assert(type_version != 0); + + STAT_INC(LOAD_ATTR, hit); + res2 = NULL; + res = descr; + assert(res != NULL); + Py_INCREF(res); + #line 2624 "Python/generated_cases.c.h" + Py_DECREF(cls); + STACK_GROW(((oparg & 1) ? 1 : 0)); + stack_pointer[-1] = res; + if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = res2; } + next_instr += 9; + DISPATCH(); + } + + TARGET(LOAD_ATTR_PROPERTY) { + PyObject *owner = stack_pointer[-1]; + uint32_t type_version = read_u32(&next_instr[1].cache); + uint32_t func_version = read_u32(&next_instr[3].cache); + PyObject *fget = read_obj(&next_instr[5].cache); + #line 1896 "Python/bytecodes.c" + DEOPT_IF(tstate->interp->eval_frame, LOAD_ATTR); + + PyTypeObject *cls = Py_TYPE(owner); + DEOPT_IF(cls->tp_version_tag != type_version, LOAD_ATTR); + assert(type_version != 0); + assert(Py_IS_TYPE(fget, &PyFunction_Type)); + PyFunctionObject *f = (PyFunctionObject *)fget; + assert(func_version != 0); + DEOPT_IF(f->func_version != func_version, LOAD_ATTR); + PyCodeObject *code = (PyCodeObject *)f->func_code; + assert(code->co_argcount == 1); + DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), LOAD_ATTR); + STAT_INC(LOAD_ATTR, hit); + Py_INCREF(fget); + _PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, f, 1); + // Manipulate stack directly because we exit with DISPATCH_INLINED(). + SET_TOP(NULL); + int shrink_stack = !(oparg & 1); + STACK_SHRINK(shrink_stack); + new_frame->localsplus[0] = owner; + JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); + frame->return_offset = 0; + DISPATCH_INLINED(new_frame); + #line 2662 "Python/generated_cases.c.h" + } + + TARGET(LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN) { + PyObject *owner = stack_pointer[-1]; + uint32_t type_version = read_u32(&next_instr[1].cache); + uint32_t func_version = read_u32(&next_instr[3].cache); + PyObject *getattribute = read_obj(&next_instr[5].cache); + #line 1922 "Python/bytecodes.c" + DEOPT_IF(tstate->interp->eval_frame, LOAD_ATTR); + PyTypeObject *cls = Py_TYPE(owner); + DEOPT_IF(cls->tp_version_tag != type_version, LOAD_ATTR); + assert(type_version != 0); + assert(Py_IS_TYPE(getattribute, &PyFunction_Type)); + PyFunctionObject *f = (PyFunctionObject *)getattribute; + assert(func_version != 0); + DEOPT_IF(f->func_version != func_version, LOAD_ATTR); + PyCodeObject *code = (PyCodeObject *)f->func_code; + assert(code->co_argcount == 2); + DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), LOAD_ATTR); + STAT_INC(LOAD_ATTR, hit); + + PyObject *name = GETITEM(frame->f_code->co_names, oparg >> 1); + Py_INCREF(f); + _PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, f, 2); + // Manipulate stack directly because we exit with DISPATCH_INLINED(). + SET_TOP(NULL); + int shrink_stack = !(oparg & 1); + STACK_SHRINK(shrink_stack); + new_frame->localsplus[0] = owner; + new_frame->localsplus[1] = Py_NewRef(name); + JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); + frame->return_offset = 0; + DISPATCH_INLINED(new_frame); + #line 2696 "Python/generated_cases.c.h" + } + + TARGET(STORE_ATTR_INSTANCE_VALUE) { + PyObject *owner = stack_pointer[-1]; + PyObject *value = stack_pointer[-2]; + uint32_t type_version = read_u32(&next_instr[1].cache); + uint16_t index = read_u16(&next_instr[3].cache); + #line 1950 "Python/bytecodes.c" + PyTypeObject *tp = Py_TYPE(owner); + assert(type_version != 0); + DEOPT_IF(tp->tp_version_tag != type_version, STORE_ATTR); + assert(tp->tp_flags & Py_TPFLAGS_MANAGED_DICT); + PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); + DEOPT_IF(!_PyDictOrValues_IsValues(dorv), STORE_ATTR); + STAT_INC(STORE_ATTR, hit); + PyDictValues *values = _PyDictOrValues_GetValues(dorv); + PyObject *old_value = values->values[index]; + values->values[index] = value; + if (old_value == NULL) { + _PyDictValues_AddToInsertionOrder(values, index); + } + else { + Py_DECREF(old_value); + } + Py_DECREF(owner); + #line 2722 "Python/generated_cases.c.h" + STACK_SHRINK(2); + next_instr += 4; + DISPATCH(); + } + + TARGET(STORE_ATTR_WITH_HINT) { + PyObject *owner = stack_pointer[-1]; + PyObject *value = stack_pointer[-2]; + uint32_t type_version = read_u32(&next_instr[1].cache); + uint16_t hint = read_u16(&next_instr[3].cache); + #line 1970 "Python/bytecodes.c" + PyTypeObject *tp = Py_TYPE(owner); + assert(type_version != 0); + DEOPT_IF(tp->tp_version_tag != type_version, STORE_ATTR); + assert(tp->tp_flags & Py_TPFLAGS_MANAGED_DICT); + PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); + DEOPT_IF(_PyDictOrValues_IsValues(dorv), STORE_ATTR); + PyDictObject *dict = (PyDictObject *)_PyDictOrValues_GetDict(dorv); + DEOPT_IF(dict == NULL, STORE_ATTR); + assert(PyDict_CheckExact((PyObject *)dict)); + PyObject *name = GETITEM(frame->f_code->co_names, oparg); + DEOPT_IF(hint >= (size_t)dict->ma_keys->dk_nentries, STORE_ATTR); + PyObject *old_value; + uint64_t new_version; + if (DK_IS_UNICODE(dict->ma_keys)) { + PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(dict->ma_keys) + hint; + DEOPT_IF(ep->me_key != name, STORE_ATTR); + old_value = ep->me_value; + DEOPT_IF(old_value == NULL, STORE_ATTR); + new_version = _PyDict_NotifyEvent(tstate->interp, PyDict_EVENT_MODIFIED, dict, name, value); + ep->me_value = value; + } + else { + PyDictKeyEntry *ep = DK_ENTRIES(dict->ma_keys) + hint; + DEOPT_IF(ep->me_key != name, STORE_ATTR); + old_value = ep->me_value; + DEOPT_IF(old_value == NULL, STORE_ATTR); + new_version = _PyDict_NotifyEvent(tstate->interp, PyDict_EVENT_MODIFIED, dict, name, value); + ep->me_value = value; + } + Py_DECREF(old_value); + STAT_INC(STORE_ATTR, hit); + /* Ensure dict is GC tracked if it needs to be */ + if (!_PyObject_GC_IS_TRACKED(dict) && _PyObject_GC_MAY_BE_TRACKED(value)) { + _PyObject_GC_TRACK(dict); + } + /* PEP 509 */ + dict->ma_version_tag = new_version; + Py_DECREF(owner); + #line 2772 "Python/generated_cases.c.h" + STACK_SHRINK(2); + next_instr += 4; + DISPATCH(); + } + + TARGET(STORE_ATTR_SLOT) { + PyObject *owner = stack_pointer[-1]; + PyObject *value = stack_pointer[-2]; + uint32_t type_version = read_u32(&next_instr[1].cache); + uint16_t index = read_u16(&next_instr[3].cache); + #line 2011 "Python/bytecodes.c" + PyTypeObject *tp = Py_TYPE(owner); + assert(type_version != 0); + DEOPT_IF(tp->tp_version_tag != type_version, STORE_ATTR); + char *addr = (char *)owner + index; + STAT_INC(STORE_ATTR, hit); + PyObject *old_value = *(PyObject **)addr; + *(PyObject **)addr = value; + Py_XDECREF(old_value); + Py_DECREF(owner); + #line 2793 "Python/generated_cases.c.h" + STACK_SHRINK(2); + next_instr += 4; + DISPATCH(); + } + + TARGET(COMPARE_OP) { + PREDICTED(COMPARE_OP); + static_assert(INLINE_CACHE_ENTRIES_COMPARE_OP == 1, "incorrect cache size"); + PyObject *right = stack_pointer[-1]; + PyObject *left = stack_pointer[-2]; + PyObject *res; + #line 2030 "Python/bytecodes.c" + #if ENABLE_SPECIALIZATION + _PyCompareOpCache *cache = (_PyCompareOpCache *)next_instr; + if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { + next_instr--; + _Py_Specialize_CompareOp(left, right, next_instr, oparg); + DISPATCH_SAME_OPARG(); + } + STAT_INC(COMPARE_OP, deferred); + DECREMENT_ADAPTIVE_COUNTER(cache->counter); + #endif /* ENABLE_SPECIALIZATION */ + assert((oparg >> 4) <= Py_GE); + res = PyObject_RichCompare(left, right, oparg>>4); + #line 2818 "Python/generated_cases.c.h" + Py_DECREF(left); + Py_DECREF(right); + #line 2043 "Python/bytecodes.c" + if (res == NULL) goto pop_2_error; + #line 2823 "Python/generated_cases.c.h" + STACK_SHRINK(1); + stack_pointer[-1] = res; + next_instr += 1; + DISPATCH(); + } + + TARGET(COMPARE_OP_FLOAT) { + PyObject *right = stack_pointer[-1]; + PyObject *left = stack_pointer[-2]; + PyObject *res; + #line 2047 "Python/bytecodes.c" + DEOPT_IF(!PyFloat_CheckExact(left), COMPARE_OP); + DEOPT_IF(!PyFloat_CheckExact(right), COMPARE_OP); + STAT_INC(COMPARE_OP, hit); + double dleft = PyFloat_AS_DOUBLE(left); + double dright = PyFloat_AS_DOUBLE(right); + // 1 if NaN, 2 if <, 4 if >, 8 if ==; this matches low four bits of the oparg + int sign_ish = COMPARISON_BIT(dleft, dright); + _Py_DECREF_SPECIALIZED(left, _PyFloat_ExactDealloc); + _Py_DECREF_SPECIALIZED(right, _PyFloat_ExactDealloc); + res = (sign_ish & oparg) ? Py_True : Py_False; + #line 2845 "Python/generated_cases.c.h" + STACK_SHRINK(1); + stack_pointer[-1] = res; + next_instr += 1; + DISPATCH(); + } + + TARGET(COMPARE_OP_INT) { + PyObject *right = stack_pointer[-1]; + PyObject *left = stack_pointer[-2]; + PyObject *res; + #line 2061 "Python/bytecodes.c" + DEOPT_IF(!PyLong_CheckExact(left), COMPARE_OP); + DEOPT_IF(!PyLong_CheckExact(right), COMPARE_OP); + DEOPT_IF(!_PyLong_IsCompact((PyLongObject *)left), COMPARE_OP); + DEOPT_IF(!_PyLong_IsCompact((PyLongObject *)right), COMPARE_OP); + STAT_INC(COMPARE_OP, hit); + assert(_PyLong_DigitCount((PyLongObject *)left) <= 1 && + _PyLong_DigitCount((PyLongObject *)right) <= 1); + Py_ssize_t ileft = _PyLong_CompactValue((PyLongObject *)left); + Py_ssize_t iright = _PyLong_CompactValue((PyLongObject *)right); + // 2 if <, 4 if >, 8 if ==; this matches the low 4 bits of the oparg + int sign_ish = COMPARISON_BIT(ileft, iright); + _Py_DECREF_SPECIALIZED(left, (destructor)PyObject_Free); + _Py_DECREF_SPECIALIZED(right, (destructor)PyObject_Free); + res = (sign_ish & oparg) ? Py_True : Py_False; + #line 2871 "Python/generated_cases.c.h" + STACK_SHRINK(1); + stack_pointer[-1] = res; + next_instr += 1; + DISPATCH(); + } + + TARGET(COMPARE_OP_STR) { + PyObject *right = stack_pointer[-1]; + PyObject *left = stack_pointer[-2]; + PyObject *res; + #line 2079 "Python/bytecodes.c" + DEOPT_IF(!PyUnicode_CheckExact(left), COMPARE_OP); + DEOPT_IF(!PyUnicode_CheckExact(right), COMPARE_OP); + STAT_INC(COMPARE_OP, hit); + int eq = _PyUnicode_Equal(left, right); + assert((oparg >>4) == Py_EQ || (oparg >>4) == Py_NE); + _Py_DECREF_SPECIALIZED(left, _PyUnicode_ExactDealloc); + _Py_DECREF_SPECIALIZED(right, _PyUnicode_ExactDealloc); + assert(eq == 0 || eq == 1); + assert((oparg & 0xf) == COMPARISON_NOT_EQUALS || (oparg & 0xf) == COMPARISON_EQUALS); + assert(COMPARISON_NOT_EQUALS + 1 == COMPARISON_EQUALS); + res = ((COMPARISON_NOT_EQUALS + eq) & oparg) ? Py_True : Py_False; + #line 2894 "Python/generated_cases.c.h" + STACK_SHRINK(1); + stack_pointer[-1] = res; + next_instr += 1; + DISPATCH(); + } + + TARGET(IS_OP) { + PyObject *right = stack_pointer[-1]; + PyObject *left = stack_pointer[-2]; + PyObject *b; + #line 2093 "Python/bytecodes.c" + int res = Py_Is(left, right) ^ oparg; + #line 2907 "Python/generated_cases.c.h" + Py_DECREF(left); + Py_DECREF(right); + #line 2095 "Python/bytecodes.c" + b = res ? Py_True : Py_False; + #line 2912 "Python/generated_cases.c.h" + STACK_SHRINK(1); + stack_pointer[-1] = b; + DISPATCH(); + } + + TARGET(CONTAINS_OP) { + PyObject *right = stack_pointer[-1]; + PyObject *left = stack_pointer[-2]; + PyObject *b; + #line 2099 "Python/bytecodes.c" + int res = PySequence_Contains(right, left); + #line 2924 "Python/generated_cases.c.h" + Py_DECREF(left); + Py_DECREF(right); + #line 2101 "Python/bytecodes.c" + if (res < 0) goto pop_2_error; + b = (res ^ oparg) ? Py_True : Py_False; + #line 2930 "Python/generated_cases.c.h" + STACK_SHRINK(1); + stack_pointer[-1] = b; + DISPATCH(); + } + + TARGET(CHECK_EG_MATCH) { + PyObject *match_type = stack_pointer[-1]; + PyObject *exc_value = stack_pointer[-2]; + PyObject *rest; + PyObject *match; + #line 2106 "Python/bytecodes.c" + if (check_except_star_type_valid(tstate, match_type) < 0) { + #line 2943 "Python/generated_cases.c.h" + Py_DECREF(exc_value); + Py_DECREF(match_type); + #line 2108 "Python/bytecodes.c" + if (true) goto pop_2_error; + } + + match = NULL; + rest = NULL; + int res = exception_group_match(exc_value, match_type, + &match, &rest); + #line 2954 "Python/generated_cases.c.h" + Py_DECREF(exc_value); + Py_DECREF(match_type); + #line 2116 "Python/bytecodes.c" + if (res < 0) goto pop_2_error; + + assert((match == NULL) == (rest == NULL)); + if (match == NULL) goto pop_2_error; + + if (!Py_IsNone(match)) { + PyErr_SetHandledException(match); + } + #line 2966 "Python/generated_cases.c.h" + stack_pointer[-1] = match; + stack_pointer[-2] = rest; + DISPATCH(); + } + + TARGET(CHECK_EXC_MATCH) { + PyObject *right = stack_pointer[-1]; + PyObject *left = stack_pointer[-2]; + PyObject *b; + #line 2127 "Python/bytecodes.c" + assert(PyExceptionInstance_Check(left)); + if (check_except_type_valid(tstate, right) < 0) { + #line 2979 "Python/generated_cases.c.h" + Py_DECREF(right); + #line 2130 "Python/bytecodes.c" + if (true) goto pop_1_error; + } + + int res = PyErr_GivenExceptionMatches(left, right); + #line 2986 "Python/generated_cases.c.h" + Py_DECREF(right); + #line 2135 "Python/bytecodes.c" + b = res ? Py_True : Py_False; + #line 2990 "Python/generated_cases.c.h" + stack_pointer[-1] = b; + DISPATCH(); + } + + TARGET(IMPORT_NAME) { + PyObject *fromlist = stack_pointer[-1]; + PyObject *level = stack_pointer[-2]; + PyObject *res; + #line 2139 "Python/bytecodes.c" + PyObject *name = GETITEM(frame->f_code->co_names, oparg); + res = import_name(tstate, frame, name, fromlist, level); + #line 3002 "Python/generated_cases.c.h" + Py_DECREF(level); + Py_DECREF(fromlist); + #line 2142 "Python/bytecodes.c" + if (res == NULL) goto pop_2_error; + #line 3007 "Python/generated_cases.c.h" + STACK_SHRINK(1); + stack_pointer[-1] = res; + DISPATCH(); + } + + TARGET(IMPORT_FROM) { + PyObject *from = stack_pointer[-1]; + PyObject *res; + #line 2146 "Python/bytecodes.c" + PyObject *name = GETITEM(frame->f_code->co_names, oparg); + res = import_from(tstate, from, name); + if (res == NULL) goto error; + #line 3020 "Python/generated_cases.c.h" + STACK_GROW(1); + stack_pointer[-1] = res; + DISPATCH(); + } + + TARGET(JUMP_FORWARD) { + #line 2152 "Python/bytecodes.c" + JUMPBY(oparg); + #line 3029 "Python/generated_cases.c.h" + DISPATCH(); + } + + TARGET(JUMP_BACKWARD) { + PREDICTED(JUMP_BACKWARD); + #line 2156 "Python/bytecodes.c" + assert(oparg < INSTR_OFFSET()); + JUMPBY(-oparg); + #line 3038 "Python/generated_cases.c.h" + CHECK_EVAL_BREAKER(); + DISPATCH(); + } + + TARGET(POP_JUMP_IF_FALSE) { + PREDICTED(POP_JUMP_IF_FALSE); + PyObject *cond = stack_pointer[-1]; + #line 2162 "Python/bytecodes.c" + if (Py_IsFalse(cond)) { + JUMPBY(oparg); + } + else if (!Py_IsTrue(cond)) { + int err = PyObject_IsTrue(cond); + #line 3052 "Python/generated_cases.c.h" + Py_DECREF(cond); + #line 2168 "Python/bytecodes.c" + if (err == 0) { + JUMPBY(oparg); + } + else { + if (err < 0) goto pop_1_error; + } + } + #line 3062 "Python/generated_cases.c.h" + STACK_SHRINK(1); + DISPATCH(); + } + + TARGET(POP_JUMP_IF_TRUE) { + PyObject *cond = stack_pointer[-1]; + #line 2178 "Python/bytecodes.c" + if (Py_IsTrue(cond)) { + JUMPBY(oparg); + } + else if (!Py_IsFalse(cond)) { + int err = PyObject_IsTrue(cond); + #line 3075 "Python/generated_cases.c.h" + Py_DECREF(cond); + #line 2184 "Python/bytecodes.c" + if (err > 0) { + JUMPBY(oparg); + } + else { + if (err < 0) goto pop_1_error; + } + } + #line 3085 "Python/generated_cases.c.h" + STACK_SHRINK(1); + DISPATCH(); + } + + TARGET(POP_JUMP_IF_NOT_NONE) { + PyObject *value = stack_pointer[-1]; + #line 2194 "Python/bytecodes.c" + if (!Py_IsNone(value)) { + #line 3094 "Python/generated_cases.c.h" + Py_DECREF(value); + #line 2196 "Python/bytecodes.c" + JUMPBY(oparg); + } + #line 3099 "Python/generated_cases.c.h" + STACK_SHRINK(1); + DISPATCH(); + } + + TARGET(POP_JUMP_IF_NONE) { + PyObject *value = stack_pointer[-1]; + #line 2201 "Python/bytecodes.c" + if (Py_IsNone(value)) { + JUMPBY(oparg); + } + else { + #line 3111 "Python/generated_cases.c.h" + Py_DECREF(value); + #line 2206 "Python/bytecodes.c" + } + #line 3115 "Python/generated_cases.c.h" + STACK_SHRINK(1); + DISPATCH(); + } + + TARGET(JUMP_BACKWARD_NO_INTERRUPT) { + #line 2210 "Python/bytecodes.c" + /* This bytecode is used in the `yield from` or `await` loop. + * If there is an interrupt, we want it handled in the innermost + * generator or coroutine, so we deliberately do not check it here. + * (see bpo-30039). + */ + JUMPBY(-oparg); + #line 3128 "Python/generated_cases.c.h" + DISPATCH(); + } + + TARGET(GET_LEN) { + PyObject *obj = stack_pointer[-1]; + PyObject *len_o; + #line 2219 "Python/bytecodes.c" + // PUSH(len(TOS)) + Py_ssize_t len_i = PyObject_Length(obj); + if (len_i < 0) goto error; + len_o = PyLong_FromSsize_t(len_i); + if (len_o == NULL) goto error; + #line 3141 "Python/generated_cases.c.h" + STACK_GROW(1); + stack_pointer[-1] = len_o; + DISPATCH(); + } + + TARGET(MATCH_CLASS) { + PyObject *names = stack_pointer[-1]; + PyObject *type = stack_pointer[-2]; + PyObject *subject = stack_pointer[-3]; + PyObject *attrs; + #line 2227 "Python/bytecodes.c" + // Pop TOS and TOS1. Set TOS to a tuple of attributes on success, or + // None on failure. + assert(PyTuple_CheckExact(names)); + attrs = match_class(tstate, subject, type, oparg, names); + #line 3157 "Python/generated_cases.c.h" + Py_DECREF(subject); + Py_DECREF(type); + Py_DECREF(names); + #line 2232 "Python/bytecodes.c" + if (attrs) { + assert(PyTuple_CheckExact(attrs)); // Success! + } + else { + if (_PyErr_Occurred(tstate)) goto pop_3_error; + attrs = Py_None; // Failure! + } + #line 3169 "Python/generated_cases.c.h" + STACK_SHRINK(2); + stack_pointer[-1] = attrs; + DISPATCH(); + } + + TARGET(MATCH_MAPPING) { + PyObject *subject = stack_pointer[-1]; + PyObject *res; + #line 2242 "Python/bytecodes.c" + int match = Py_TYPE(subject)->tp_flags & Py_TPFLAGS_MAPPING; + res = match ? Py_True : Py_False; + #line 3181 "Python/generated_cases.c.h" + STACK_GROW(1); + stack_pointer[-1] = res; + PREDICT(POP_JUMP_IF_FALSE); + DISPATCH(); + } + + TARGET(MATCH_SEQUENCE) { + PyObject *subject = stack_pointer[-1]; + PyObject *res; + #line 2248 "Python/bytecodes.c" + int match = Py_TYPE(subject)->tp_flags & Py_TPFLAGS_SEQUENCE; + res = match ? Py_True : Py_False; + #line 3194 "Python/generated_cases.c.h" + STACK_GROW(1); + stack_pointer[-1] = res; + PREDICT(POP_JUMP_IF_FALSE); + DISPATCH(); + } + + TARGET(MATCH_KEYS) { + PyObject *keys = stack_pointer[-1]; + PyObject *subject = stack_pointer[-2]; + PyObject *values_or_none; + #line 2254 "Python/bytecodes.c" + // On successful match, PUSH(values). Otherwise, PUSH(None). + values_or_none = match_keys(tstate, subject, keys); + if (values_or_none == NULL) goto error; + #line 3209 "Python/generated_cases.c.h" + STACK_GROW(1); + stack_pointer[-1] = values_or_none; + DISPATCH(); + } + + TARGET(GET_ITER) { + PyObject *iterable = stack_pointer[-1]; + PyObject *iter; + #line 2260 "Python/bytecodes.c" + /* before: [obj]; after [getiter(obj)] */ + iter = PyObject_GetIter(iterable); + #line 3221 "Python/generated_cases.c.h" + Py_DECREF(iterable); + #line 2263 "Python/bytecodes.c" + if (iter == NULL) goto pop_1_error; + #line 3225 "Python/generated_cases.c.h" + stack_pointer[-1] = iter; + DISPATCH(); + } + + TARGET(GET_YIELD_FROM_ITER) { + PyObject *iterable = stack_pointer[-1]; + PyObject *iter; + #line 2267 "Python/bytecodes.c" + /* before: [obj]; after [getiter(obj)] */ + if (PyCoro_CheckExact(iterable)) { + /* `iterable` is a coroutine */ + if (!(frame->f_code->co_flags & (CO_COROUTINE | CO_ITERABLE_COROUTINE))) { + /* and it is used in a 'yield from' expression of a + regular generator. */ + _PyErr_SetString(tstate, PyExc_TypeError, + "cannot 'yield from' a coroutine object " + "in a non-coroutine generator"); + goto error; + } + iter = iterable; + } + else if (PyGen_CheckExact(iterable)) { + iter = iterable; + } + else { + /* `iterable` is not a generator. */ + iter = PyObject_GetIter(iterable); + if (iter == NULL) { + goto error; + } + #line 3256 "Python/generated_cases.c.h" + Py_DECREF(iterable); + #line 2290 "Python/bytecodes.c" + } + #line 3260 "Python/generated_cases.c.h" + stack_pointer[-1] = iter; + PREDICT(LOAD_CONST); + DISPATCH(); + } + + TARGET(FOR_ITER) { + PREDICTED(FOR_ITER); + static_assert(INLINE_CACHE_ENTRIES_FOR_ITER == 1, "incorrect cache size"); + PyObject *iter = stack_pointer[-1]; + PyObject *next; + #line 2309 "Python/bytecodes.c" + #if ENABLE_SPECIALIZATION + _PyForIterCache *cache = (_PyForIterCache *)next_instr; + if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { + next_instr--; + _Py_Specialize_ForIter(iter, next_instr, oparg); + DISPATCH_SAME_OPARG(); + } + STAT_INC(FOR_ITER, deferred); + DECREMENT_ADAPTIVE_COUNTER(cache->counter); + #endif /* ENABLE_SPECIALIZATION */ + /* before: [iter]; after: [iter, iter()] *or* [] (and jump over END_FOR.) */ + next = (*Py_TYPE(iter)->tp_iternext)(iter); + if (next == NULL) { + if (_PyErr_Occurred(tstate)) { + if (!_PyErr_ExceptionMatches(tstate, PyExc_StopIteration)) { + goto error; + } + monitor_raise(tstate, frame, next_instr-1); + _PyErr_Clear(tstate); + } + /* iterator ended normally */ + assert(next_instr[INLINE_CACHE_ENTRIES_FOR_ITER + oparg].op.code == END_FOR || + next_instr[INLINE_CACHE_ENTRIES_FOR_ITER + oparg].op.code == INSTRUMENTED_END_FOR); + Py_DECREF(iter); + STACK_SHRINK(1); + /* Jump forward oparg, then skip following END_FOR instruction */ + JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + oparg + 1); + DISPATCH(); + } + // Common case: no jump, leave it to the code generator + #line 3302 "Python/generated_cases.c.h" + STACK_GROW(1); + stack_pointer[-1] = next; + next_instr += 1; + DISPATCH(); + } + + TARGET(INSTRUMENTED_FOR_ITER) { + #line 2342 "Python/bytecodes.c" + _Py_CODEUNIT *here = next_instr-1; + _Py_CODEUNIT *target; + PyObject *iter = TOP(); + PyObject *next = (*Py_TYPE(iter)->tp_iternext)(iter); + if (next != NULL) { + PUSH(next); + target = next_instr + INLINE_CACHE_ENTRIES_FOR_ITER; + } + else { + if (_PyErr_Occurred(tstate)) { + if (!_PyErr_ExceptionMatches(tstate, PyExc_StopIteration)) { + goto error; + } + monitor_raise(tstate, frame, here); + _PyErr_Clear(tstate); + } + /* iterator ended normally */ + assert(next_instr[INLINE_CACHE_ENTRIES_FOR_ITER + oparg].op.code == END_FOR || + next_instr[INLINE_CACHE_ENTRIES_FOR_ITER + oparg].op.code == INSTRUMENTED_END_FOR); + STACK_SHRINK(1); + Py_DECREF(iter); + /* Skip END_FOR */ + target = next_instr + INLINE_CACHE_ENTRIES_FOR_ITER + oparg + 1; + } + INSTRUMENTED_JUMP(here, target, PY_MONITORING_EVENT_BRANCH); + #line 3336 "Python/generated_cases.c.h" + DISPATCH(); + } + + TARGET(FOR_ITER_LIST) { + PyObject *iter = stack_pointer[-1]; + PyObject *next; + #line 2370 "Python/bytecodes.c" + DEOPT_IF(Py_TYPE(iter) != &PyListIter_Type, FOR_ITER); + _PyListIterObject *it = (_PyListIterObject *)iter; + STAT_INC(FOR_ITER, hit); + PyListObject *seq = it->it_seq; + if (seq) { + if (it->it_index < PyList_GET_SIZE(seq)) { + next = Py_NewRef(PyList_GET_ITEM(seq, it->it_index++)); + goto end_for_iter_list; // End of this instruction + } + it->it_seq = NULL; + Py_DECREF(seq); + } + Py_DECREF(iter); + STACK_SHRINK(1); + /* Jump forward oparg, then skip following END_FOR instruction */ + JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + oparg + 1); + DISPATCH(); + end_for_iter_list: + // Common case: no jump, leave it to the code generator + #line 3363 "Python/generated_cases.c.h" + STACK_GROW(1); + stack_pointer[-1] = next; + next_instr += 1; + DISPATCH(); + } + + TARGET(FOR_ITER_TUPLE) { + PyObject *iter = stack_pointer[-1]; + PyObject *next; + #line 2392 "Python/bytecodes.c" + _PyTupleIterObject *it = (_PyTupleIterObject *)iter; + DEOPT_IF(Py_TYPE(it) != &PyTupleIter_Type, FOR_ITER); + STAT_INC(FOR_ITER, hit); + PyTupleObject *seq = it->it_seq; + if (seq) { + if (it->it_index < PyTuple_GET_SIZE(seq)) { + next = Py_NewRef(PyTuple_GET_ITEM(seq, it->it_index++)); + goto end_for_iter_tuple; // End of this instruction + } + it->it_seq = NULL; + Py_DECREF(seq); + } + Py_DECREF(iter); + STACK_SHRINK(1); + /* Jump forward oparg, then skip following END_FOR instruction */ + JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + oparg + 1); + DISPATCH(); + end_for_iter_tuple: + // Common case: no jump, leave it to the code generator + #line 3393 "Python/generated_cases.c.h" + STACK_GROW(1); + stack_pointer[-1] = next; + next_instr += 1; + DISPATCH(); + } + + TARGET(FOR_ITER_RANGE) { + PyObject *iter = stack_pointer[-1]; + PyObject *next; + #line 2414 "Python/bytecodes.c" + _PyRangeIterObject *r = (_PyRangeIterObject *)iter; + DEOPT_IF(Py_TYPE(r) != &PyRangeIter_Type, FOR_ITER); + STAT_INC(FOR_ITER, hit); + if (r->len <= 0) { + STACK_SHRINK(1); + Py_DECREF(r); + // Jump over END_FOR instruction. + JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER + oparg + 1); + DISPATCH(); + } + long value = r->start; + r->start = value + r->step; + r->len--; + next = PyLong_FromLong(value); + if (next == NULL) { + goto error; + } + #line 3421 "Python/generated_cases.c.h" + STACK_GROW(1); + stack_pointer[-1] = next; + next_instr += 1; + DISPATCH(); + } + + TARGET(FOR_ITER_GEN) { + PyObject *iter = stack_pointer[-1]; + #line 2434 "Python/bytecodes.c" + DEOPT_IF(tstate->interp->eval_frame, FOR_ITER); + PyGenObject *gen = (PyGenObject *)iter; + DEOPT_IF(Py_TYPE(gen) != &PyGen_Type, FOR_ITER); + DEOPT_IF(gen->gi_frame_state >= FRAME_EXECUTING, FOR_ITER); + STAT_INC(FOR_ITER, hit); + _PyInterpreterFrame *gen_frame = (_PyInterpreterFrame *)gen->gi_iframe; + frame->return_offset = oparg; + _PyFrame_StackPush(gen_frame, Py_None); + gen->gi_frame_state = FRAME_EXECUTING; + gen->gi_exc_state.previous_item = tstate->exc_info; + tstate->exc_info = &gen->gi_exc_state; + JUMPBY(INLINE_CACHE_ENTRIES_FOR_ITER); + assert(next_instr[oparg].op.code == END_FOR || + next_instr[oparg].op.code == INSTRUMENTED_END_FOR); + DISPATCH_INLINED(gen_frame); + #line 3446 "Python/generated_cases.c.h" + } + + TARGET(BEFORE_ASYNC_WITH) { + PyObject *mgr = stack_pointer[-1]; + PyObject *exit; + PyObject *res; + #line 2452 "Python/bytecodes.c" + PyObject *enter = _PyObject_LookupSpecial(mgr, &_Py_ID(__aenter__)); + if (enter == NULL) { + if (!_PyErr_Occurred(tstate)) { + _PyErr_Format(tstate, PyExc_TypeError, + "'%.200s' object does not support the " + "asynchronous context manager protocol", + Py_TYPE(mgr)->tp_name); + } + goto error; + } + exit = _PyObject_LookupSpecial(mgr, &_Py_ID(__aexit__)); + if (exit == NULL) { + if (!_PyErr_Occurred(tstate)) { + _PyErr_Format(tstate, PyExc_TypeError, + "'%.200s' object does not support the " + "asynchronous context manager protocol " + "(missed __aexit__ method)", + Py_TYPE(mgr)->tp_name); + } + Py_DECREF(enter); + goto error; + } + #line 3476 "Python/generated_cases.c.h" + Py_DECREF(mgr); + #line 2475 "Python/bytecodes.c" + res = _PyObject_CallNoArgs(enter); + Py_DECREF(enter); + if (res == NULL) { + Py_DECREF(exit); + if (true) goto pop_1_error; + } + #line 3485 "Python/generated_cases.c.h" + STACK_GROW(1); + stack_pointer[-1] = res; + stack_pointer[-2] = exit; + PREDICT(GET_AWAITABLE); + DISPATCH(); + } + + TARGET(BEFORE_WITH) { + PyObject *mgr = stack_pointer[-1]; + PyObject *exit; + PyObject *res; + #line 2485 "Python/bytecodes.c" + /* pop the context manager, push its __exit__ and the + * value returned from calling its __enter__ + */ + PyObject *enter = _PyObject_LookupSpecial(mgr, &_Py_ID(__enter__)); + if (enter == NULL) { + if (!_PyErr_Occurred(tstate)) { + _PyErr_Format(tstate, PyExc_TypeError, + "'%.200s' object does not support the " + "context manager protocol", + Py_TYPE(mgr)->tp_name); + } + goto error; + } + exit = _PyObject_LookupSpecial(mgr, &_Py_ID(__exit__)); + if (exit == NULL) { + if (!_PyErr_Occurred(tstate)) { + _PyErr_Format(tstate, PyExc_TypeError, + "'%.200s' object does not support the " + "context manager protocol " + "(missed __exit__ method)", + Py_TYPE(mgr)->tp_name); + } + Py_DECREF(enter); + goto error; + } + #line 3523 "Python/generated_cases.c.h" + Py_DECREF(mgr); + #line 2511 "Python/bytecodes.c" + res = _PyObject_CallNoArgs(enter); + Py_DECREF(enter); + if (res == NULL) { + Py_DECREF(exit); + if (true) goto pop_1_error; + } + #line 3532 "Python/generated_cases.c.h" + STACK_GROW(1); + stack_pointer[-1] = res; + stack_pointer[-2] = exit; + DISPATCH(); + } + + TARGET(WITH_EXCEPT_START) { + PyObject *val = stack_pointer[-1]; + PyObject *lasti = stack_pointer[-3]; + PyObject *exit_func = stack_pointer[-4]; + PyObject *res; + #line 2520 "Python/bytecodes.c" + /* At the top of the stack are 4 values: + - val: TOP = exc_info() + - unused: SECOND = previous exception + - lasti: THIRD = lasti of exception in exc_info() + - exit_func: FOURTH = the context.__exit__ bound method + We call FOURTH(type(TOP), TOP, GetTraceback(TOP)). + Then we push the __exit__ return value. + */ + PyObject *exc, *tb; + + assert(val && PyExceptionInstance_Check(val)); + exc = PyExceptionInstance_Class(val); + tb = PyException_GetTraceback(val); + if (tb == NULL) { + tb = Py_None; + } + else { + Py_DECREF(tb); + } + assert(PyLong_Check(lasti)); + (void)lasti; // Shut up compiler warning if asserts are off + PyObject *stack[4] = {NULL, exc, val, tb}; + res = PyObject_Vectorcall(exit_func, stack + 1, + 3 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); + if (res == NULL) goto error; + #line 3570 "Python/generated_cases.c.h" + STACK_GROW(1); + stack_pointer[-1] = res; + DISPATCH(); + } + + TARGET(PUSH_EXC_INFO) { + PyObject *new_exc = stack_pointer[-1]; + PyObject *prev_exc; + #line 2548 "Python/bytecodes.c" + _PyErr_StackItem *exc_info = tstate->exc_info; + if (exc_info->exc_value != NULL) { + prev_exc = exc_info->exc_value; + } + else { + prev_exc = Py_None; + } + assert(PyExceptionInstance_Check(new_exc)); + exc_info->exc_value = Py_NewRef(new_exc); + #line 3589 "Python/generated_cases.c.h" + STACK_GROW(1); + stack_pointer[-1] = new_exc; + stack_pointer[-2] = prev_exc; + DISPATCH(); + } + + TARGET(LOAD_ATTR_METHOD_WITH_VALUES) { + PyObject *self = stack_pointer[-1]; + PyObject *res2 = NULL; + PyObject *res; + uint32_t type_version = read_u32(&next_instr[1].cache); + uint32_t keys_version = read_u32(&next_instr[3].cache); + PyObject *descr = read_obj(&next_instr[5].cache); + #line 2560 "Python/bytecodes.c" + /* Cached method object */ + PyTypeObject *self_cls = Py_TYPE(self); + assert(type_version != 0); + DEOPT_IF(self_cls->tp_version_tag != type_version, LOAD_ATTR); + assert(self_cls->tp_flags & Py_TPFLAGS_MANAGED_DICT); + PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(self); + DEOPT_IF(!_PyDictOrValues_IsValues(dorv), LOAD_ATTR); + PyHeapTypeObject *self_heap_type = (PyHeapTypeObject *)self_cls; + DEOPT_IF(self_heap_type->ht_cached_keys->dk_version != + keys_version, LOAD_ATTR); + STAT_INC(LOAD_ATTR, hit); + assert(descr != NULL); + res2 = Py_NewRef(descr); + assert(_PyType_HasFeature(Py_TYPE(res2), Py_TPFLAGS_METHOD_DESCRIPTOR)); + res = self; + assert(oparg & 1); + #line 3620 "Python/generated_cases.c.h" + STACK_GROW(((oparg & 1) ? 1 : 0)); + stack_pointer[-1] = res; + if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = res2; } + next_instr += 9; + DISPATCH(); + } + + TARGET(LOAD_ATTR_METHOD_NO_DICT) { + PyObject *self = stack_pointer[-1]; + PyObject *res2 = NULL; + PyObject *res; + uint32_t type_version = read_u32(&next_instr[1].cache); + PyObject *descr = read_obj(&next_instr[5].cache); + #line 2579 "Python/bytecodes.c" + PyTypeObject *self_cls = Py_TYPE(self); + DEOPT_IF(self_cls->tp_version_tag != type_version, LOAD_ATTR); + assert(self_cls->tp_dictoffset == 0); + STAT_INC(LOAD_ATTR, hit); + assert(descr != NULL); + assert(_PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_METHOD_DESCRIPTOR)); + res2 = Py_NewRef(descr); + res = self; + assert(oparg & 1); + #line 3644 "Python/generated_cases.c.h" + STACK_GROW(((oparg & 1) ? 1 : 0)); + stack_pointer[-1] = res; + if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = res2; } + next_instr += 9; + DISPATCH(); + } + + TARGET(LOAD_ATTR_METHOD_LAZY_DICT) { + PyObject *self = stack_pointer[-1]; + PyObject *res2 = NULL; + PyObject *res; + uint32_t type_version = read_u32(&next_instr[1].cache); + PyObject *descr = read_obj(&next_instr[5].cache); + #line 2591 "Python/bytecodes.c" + PyTypeObject *self_cls = Py_TYPE(self); + DEOPT_IF(self_cls->tp_version_tag != type_version, LOAD_ATTR); + Py_ssize_t dictoffset = self_cls->tp_dictoffset; + assert(dictoffset > 0); + PyObject *dict = *(PyObject **)((char *)self + dictoffset); + /* This object has a __dict__, just not yet created */ + DEOPT_IF(dict != NULL, LOAD_ATTR); + STAT_INC(LOAD_ATTR, hit); + assert(descr != NULL); + assert(_PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_METHOD_DESCRIPTOR)); + res2 = Py_NewRef(descr); + res = self; + assert(oparg & 1); + #line 3672 "Python/generated_cases.c.h" + STACK_GROW(((oparg & 1) ? 1 : 0)); + stack_pointer[-1] = res; + if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = res2; } + next_instr += 9; + DISPATCH(); + } + + TARGET(KW_NAMES) { + #line 2607 "Python/bytecodes.c" + assert(kwnames == NULL); + assert(oparg < PyTuple_GET_SIZE(frame->f_code->co_consts)); + kwnames = GETITEM(frame->f_code->co_consts, oparg); + #line 3685 "Python/generated_cases.c.h" + DISPATCH(); + } + + TARGET(INSTRUMENTED_CALL) { + #line 2613 "Python/bytecodes.c" + int is_meth = PEEK(oparg+2) != NULL; + int total_args = oparg + is_meth; + PyObject *function = PEEK(total_args + 1); + PyObject *arg = total_args == 0 ? + &_PyInstrumentation_MISSING : PEEK(total_args); + int err = _Py_call_instrumentation_2args( + tstate, PY_MONITORING_EVENT_CALL, + frame, next_instr-1, function, arg); + if (err) goto error; + _PyCallCache *cache = (_PyCallCache *)next_instr; + INCREMENT_ADAPTIVE_COUNTER(cache->counter); + GO_TO_INSTRUCTION(CALL); + #line 3703 "Python/generated_cases.c.h" + } + + TARGET(CALL) { + PREDICTED(CALL); + static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size"); + PyObject **args = (stack_pointer - oparg); + PyObject *callable = stack_pointer[-(1 + oparg)]; + PyObject *method = stack_pointer[-(2 + oparg)]; + PyObject *res; + #line 2658 "Python/bytecodes.c" + int is_meth = method != NULL; + int total_args = oparg; + if (is_meth) { + callable = method; + args--; + total_args++; + } + #if ENABLE_SPECIALIZATION + _PyCallCache *cache = (_PyCallCache *)next_instr; + if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { + next_instr--; + _Py_Specialize_Call(callable, next_instr, total_args, kwnames); + DISPATCH_SAME_OPARG(); + } + STAT_INC(CALL, deferred); + DECREMENT_ADAPTIVE_COUNTER(cache->counter); + #endif /* ENABLE_SPECIALIZATION */ + if (!is_meth && Py_TYPE(callable) == &PyMethod_Type) { + is_meth = 1; // For consistenct; it's dead, though + args--; + total_args++; + PyObject *self = ((PyMethodObject *)callable)->im_self; + args[0] = Py_NewRef(self); + method = ((PyMethodObject *)callable)->im_func; + args[-1] = Py_NewRef(method); + Py_DECREF(callable); + callable = method; + } + int positional_args = total_args - KWNAMES_LEN(); + // Check if the call can be inlined or not + if (Py_TYPE(callable) == &PyFunction_Type && + tstate->interp->eval_frame == NULL && + ((PyFunctionObject *)callable)->vectorcall == _PyFunction_Vectorcall) + { + int code_flags = ((PyCodeObject*)PyFunction_GET_CODE(callable))->co_flags; + PyObject *locals = code_flags & CO_OPTIMIZED ? NULL : Py_NewRef(PyFunction_GET_GLOBALS(callable)); + _PyInterpreterFrame *new_frame = _PyEvalFramePushAndInit( + tstate, (PyFunctionObject *)callable, locals, + args, positional_args, kwnames + ); + kwnames = NULL; + // Manipulate stack directly since we leave using DISPATCH_INLINED(). + STACK_SHRINK(oparg + 2); + // The frame has stolen all the arguments from the stack, + // so there is no need to clean them up. + if (new_frame == NULL) { + goto error; + } + JUMPBY(INLINE_CACHE_ENTRIES_CALL); + frame->return_offset = 0; + DISPATCH_INLINED(new_frame); + } + /* Callable is not a normal Python function */ + res = PyObject_Vectorcall( + callable, args, + positional_args | PY_VECTORCALL_ARGUMENTS_OFFSET, + kwnames); + if (opcode == INSTRUMENTED_CALL) { + PyObject *arg = total_args == 0 ? + &_PyInstrumentation_MISSING : PEEK(total_args); + if (res == NULL) { + _Py_call_instrumentation_exc2( + tstate, PY_MONITORING_EVENT_C_RAISE, + frame, next_instr-1, callable, arg); + } + else { + int err = _Py_call_instrumentation_2args( + tstate, PY_MONITORING_EVENT_C_RETURN, + frame, next_instr-1, callable, arg); + if (err < 0) { + Py_CLEAR(res); + } + } + } + kwnames = NULL; + assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); + Py_DECREF(callable); + for (int i = 0; i < total_args; i++) { + Py_DECREF(args[i]); + } + if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } + #line 3795 "Python/generated_cases.c.h" + STACK_SHRINK(oparg); + STACK_SHRINK(1); + stack_pointer[-1] = res; + next_instr += 3; + CHECK_EVAL_BREAKER(); + DISPATCH(); + } + + TARGET(CALL_BOUND_METHOD_EXACT_ARGS) { + PyObject *callable = stack_pointer[-(1 + oparg)]; + PyObject *method = stack_pointer[-(2 + oparg)]; + #line 2746 "Python/bytecodes.c" + DEOPT_IF(method != NULL, CALL); + DEOPT_IF(Py_TYPE(callable) != &PyMethod_Type, CALL); + STAT_INC(CALL, hit); + PyObject *self = ((PyMethodObject *)callable)->im_self; + PEEK(oparg + 1) = Py_NewRef(self); // callable + PyObject *meth = ((PyMethodObject *)callable)->im_func; + PEEK(oparg + 2) = Py_NewRef(meth); // method + Py_DECREF(callable); + GO_TO_INSTRUCTION(CALL_PY_EXACT_ARGS); + #line 3817 "Python/generated_cases.c.h" + } + + TARGET(CALL_PY_EXACT_ARGS) { + PREDICTED(CALL_PY_EXACT_ARGS); + PyObject **args = (stack_pointer - oparg); + PyObject *callable = stack_pointer[-(1 + oparg)]; + PyObject *method = stack_pointer[-(2 + oparg)]; + uint32_t func_version = read_u32(&next_instr[1].cache); + #line 2758 "Python/bytecodes.c" + assert(kwnames == NULL); + DEOPT_IF(tstate->interp->eval_frame, CALL); + int is_meth = method != NULL; + int argcount = oparg; + if (is_meth) { + callable = method; + args--; + argcount++; + } + DEOPT_IF(!PyFunction_Check(callable), CALL); + PyFunctionObject *func = (PyFunctionObject *)callable; + DEOPT_IF(func->func_version != func_version, CALL); + PyCodeObject *code = (PyCodeObject *)func->func_code; + DEOPT_IF(code->co_argcount != argcount, CALL); + DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), CALL); + STAT_INC(CALL, hit); + _PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, func, argcount); + for (int i = 0; i < argcount; i++) { + new_frame->localsplus[i] = args[i]; + } + // Manipulate stack directly since we leave using DISPATCH_INLINED(). + STACK_SHRINK(oparg + 2); + JUMPBY(INLINE_CACHE_ENTRIES_CALL); + frame->return_offset = 0; + DISPATCH_INLINED(new_frame); + #line 3852 "Python/generated_cases.c.h" + } + + TARGET(CALL_PY_WITH_DEFAULTS) { + PyObject **args = (stack_pointer - oparg); + PyObject *callable = stack_pointer[-(1 + oparg)]; + PyObject *method = stack_pointer[-(2 + oparg)]; + uint32_t func_version = read_u32(&next_instr[1].cache); + #line 2786 "Python/bytecodes.c" + assert(kwnames == NULL); + DEOPT_IF(tstate->interp->eval_frame, CALL); + int is_meth = method != NULL; + int argcount = oparg; + if (is_meth) { + callable = method; + args--; + argcount++; + } + DEOPT_IF(!PyFunction_Check(callable), CALL); + PyFunctionObject *func = (PyFunctionObject *)callable; + DEOPT_IF(func->func_version != func_version, CALL); + PyCodeObject *code = (PyCodeObject *)func->func_code; + assert(func->func_defaults); + assert(PyTuple_CheckExact(func->func_defaults)); + int defcount = (int)PyTuple_GET_SIZE(func->func_defaults); + assert(defcount <= code->co_argcount); + int min_args = code->co_argcount - defcount; + DEOPT_IF(argcount > code->co_argcount, CALL); + DEOPT_IF(argcount < min_args, CALL); + DEOPT_IF(!_PyThreadState_HasStackSpace(tstate, code->co_framesize), CALL); + STAT_INC(CALL, hit); + _PyInterpreterFrame *new_frame = _PyFrame_PushUnchecked(tstate, func, code->co_argcount); + for (int i = 0; i < argcount; i++) { + new_frame->localsplus[i] = args[i]; + } + for (int i = argcount; i < code->co_argcount; i++) { + PyObject *def = PyTuple_GET_ITEM(func->func_defaults, i - min_args); + new_frame->localsplus[i] = Py_NewRef(def); + } + // Manipulate stack and cache directly since we leave using DISPATCH_INLINED(). + STACK_SHRINK(oparg + 2); + JUMPBY(INLINE_CACHE_ENTRIES_CALL); + frame->return_offset = 0; + DISPATCH_INLINED(new_frame); + #line 3896 "Python/generated_cases.c.h" + } + + TARGET(CALL_NO_KW_TYPE_1) { + PyObject **args = (stack_pointer - oparg); + PyObject *callable = stack_pointer[-(1 + oparg)]; + PyObject *null = stack_pointer[-(2 + oparg)]; + PyObject *res; + #line 2824 "Python/bytecodes.c" + assert(kwnames == NULL); + assert(oparg == 1); + DEOPT_IF(null != NULL, CALL); + PyObject *obj = args[0]; + DEOPT_IF(callable != (PyObject *)&PyType_Type, CALL); + STAT_INC(CALL, hit); + res = Py_NewRef(Py_TYPE(obj)); + Py_DECREF(obj); + Py_DECREF(&PyType_Type); // I.e., callable + #line 3914 "Python/generated_cases.c.h" + STACK_SHRINK(oparg); + STACK_SHRINK(1); + stack_pointer[-1] = res; + next_instr += 3; + DISPATCH(); + } + + TARGET(CALL_NO_KW_STR_1) { + PyObject **args = (stack_pointer - oparg); + PyObject *callable = stack_pointer[-(1 + oparg)]; + PyObject *null = stack_pointer[-(2 + oparg)]; + PyObject *res; + #line 2836 "Python/bytecodes.c" + assert(kwnames == NULL); + assert(oparg == 1); + DEOPT_IF(null != NULL, CALL); + DEOPT_IF(callable != (PyObject *)&PyUnicode_Type, CALL); + STAT_INC(CALL, hit); + PyObject *arg = args[0]; + res = PyObject_Str(arg); + Py_DECREF(arg); + Py_DECREF(&PyUnicode_Type); // I.e., callable + if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } + #line 3938 "Python/generated_cases.c.h" + STACK_SHRINK(oparg); + STACK_SHRINK(1); + stack_pointer[-1] = res; + next_instr += 3; + CHECK_EVAL_BREAKER(); + DISPATCH(); + } + + TARGET(CALL_NO_KW_TUPLE_1) { + PyObject **args = (stack_pointer - oparg); + PyObject *callable = stack_pointer[-(1 + oparg)]; + PyObject *null = stack_pointer[-(2 + oparg)]; + PyObject *res; + #line 2850 "Python/bytecodes.c" + assert(kwnames == NULL); + assert(oparg == 1); + DEOPT_IF(null != NULL, CALL); + DEOPT_IF(callable != (PyObject *)&PyTuple_Type, CALL); + STAT_INC(CALL, hit); + PyObject *arg = args[0]; + res = PySequence_Tuple(arg); + Py_DECREF(arg); + Py_DECREF(&PyTuple_Type); // I.e., tuple + if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } + #line 3963 "Python/generated_cases.c.h" + STACK_SHRINK(oparg); + STACK_SHRINK(1); + stack_pointer[-1] = res; + next_instr += 3; + CHECK_EVAL_BREAKER(); + DISPATCH(); + } + + TARGET(CALL_BUILTIN_CLASS) { + PyObject **args = (stack_pointer - oparg); + PyObject *callable = stack_pointer[-(1 + oparg)]; + PyObject *method = stack_pointer[-(2 + oparg)]; + PyObject *res; + #line 2864 "Python/bytecodes.c" + int is_meth = method != NULL; + int total_args = oparg; + if (is_meth) { + callable = method; + args--; + total_args++; + } + int kwnames_len = KWNAMES_LEN(); + DEOPT_IF(!PyType_Check(callable), CALL); + PyTypeObject *tp = (PyTypeObject *)callable; + DEOPT_IF(tp->tp_vectorcall == NULL, CALL); + STAT_INC(CALL, hit); + res = tp->tp_vectorcall((PyObject *)tp, args, + total_args - kwnames_len, kwnames); + kwnames = NULL; + /* Free the arguments. */ + for (int i = 0; i < total_args; i++) { + Py_DECREF(args[i]); + } + Py_DECREF(tp); + if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } + #line 3999 "Python/generated_cases.c.h" + STACK_SHRINK(oparg); + STACK_SHRINK(1); + stack_pointer[-1] = res; + next_instr += 3; + CHECK_EVAL_BREAKER(); + DISPATCH(); + } + + TARGET(CALL_NO_KW_BUILTIN_O) { + PyObject **args = (stack_pointer - oparg); + PyObject *callable = stack_pointer[-(1 + oparg)]; + PyObject *method = stack_pointer[-(2 + oparg)]; + PyObject *res; + #line 2889 "Python/bytecodes.c" + /* Builtin METH_O functions */ + assert(kwnames == NULL); + int is_meth = method != NULL; + int total_args = oparg; + if (is_meth) { + callable = method; + args--; + total_args++; + } + DEOPT_IF(total_args != 1, CALL); + DEOPT_IF(!PyCFunction_CheckExact(callable), CALL); + DEOPT_IF(PyCFunction_GET_FLAGS(callable) != METH_O, CALL); + STAT_INC(CALL, hit); + PyCFunction cfunc = PyCFunction_GET_FUNCTION(callable); + // This is slower but CPython promises to check all non-vectorcall + // function calls. + if (_Py_EnterRecursiveCallTstate(tstate, " while calling a Python object")) { + goto error; + } + PyObject *arg = args[0]; + res = _PyCFunction_TrampolineCall(cfunc, PyCFunction_GET_SELF(callable), arg); + _Py_LeaveRecursiveCallTstate(tstate); + assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); + + Py_DECREF(arg); + Py_DECREF(callable); + if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } + #line 4041 "Python/generated_cases.c.h" + STACK_SHRINK(oparg); + STACK_SHRINK(1); + stack_pointer[-1] = res; + next_instr += 3; + CHECK_EVAL_BREAKER(); + DISPATCH(); + } + + TARGET(CALL_NO_KW_BUILTIN_FAST) { + PyObject **args = (stack_pointer - oparg); + PyObject *callable = stack_pointer[-(1 + oparg)]; + PyObject *method = stack_pointer[-(2 + oparg)]; + PyObject *res; + #line 2920 "Python/bytecodes.c" + /* Builtin METH_FASTCALL functions, without keywords */ + assert(kwnames == NULL); + int is_meth = method != NULL; + int total_args = oparg; + if (is_meth) { + callable = method; + args--; + total_args++; + } + DEOPT_IF(!PyCFunction_CheckExact(callable), CALL); + DEOPT_IF(PyCFunction_GET_FLAGS(callable) != METH_FASTCALL, CALL); + STAT_INC(CALL, hit); + PyCFunction cfunc = PyCFunction_GET_FUNCTION(callable); + /* res = func(self, args, nargs) */ + res = ((_PyCFunctionFast)(void(*)(void))cfunc)( + PyCFunction_GET_SELF(callable), + args, + total_args); + assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); + + /* Free the arguments. */ + for (int i = 0; i < total_args; i++) { + Py_DECREF(args[i]); + } + Py_DECREF(callable); + if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } + /* Not deopting because this doesn't mean our optimization was + wrong. `res` can be NULL for valid reasons. Eg. getattr(x, + 'invalid'). In those cases an exception is set, so we must + handle it. + */ + #line 4087 "Python/generated_cases.c.h" + STACK_SHRINK(oparg); + STACK_SHRINK(1); + stack_pointer[-1] = res; + next_instr += 3; + CHECK_EVAL_BREAKER(); + DISPATCH(); + } + + TARGET(CALL_BUILTIN_FAST_WITH_KEYWORDS) { + PyObject **args = (stack_pointer - oparg); + PyObject *callable = stack_pointer[-(1 + oparg)]; + PyObject *method = stack_pointer[-(2 + oparg)]; + PyObject *res; + #line 2955 "Python/bytecodes.c" + /* Builtin METH_FASTCALL | METH_KEYWORDS functions */ + int is_meth = method != NULL; + int total_args = oparg; + if (is_meth) { + callable = method; + args--; + total_args++; + } + DEOPT_IF(!PyCFunction_CheckExact(callable), CALL); + DEOPT_IF(PyCFunction_GET_FLAGS(callable) != + (METH_FASTCALL | METH_KEYWORDS), CALL); + STAT_INC(CALL, hit); + /* res = func(self, args, nargs, kwnames) */ + _PyCFunctionFastWithKeywords cfunc = + (_PyCFunctionFastWithKeywords)(void(*)(void)) + PyCFunction_GET_FUNCTION(callable); + res = cfunc( + PyCFunction_GET_SELF(callable), + args, + total_args - KWNAMES_LEN(), + kwnames + ); + assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); + kwnames = NULL; + + /* Free the arguments. */ + for (int i = 0; i < total_args; i++) { + Py_DECREF(args[i]); + } + Py_DECREF(callable); + if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } + #line 4133 "Python/generated_cases.c.h" + STACK_SHRINK(oparg); + STACK_SHRINK(1); + stack_pointer[-1] = res; + next_instr += 3; + CHECK_EVAL_BREAKER(); + DISPATCH(); + } + + TARGET(CALL_NO_KW_LEN) { + PyObject **args = (stack_pointer - oparg); + PyObject *callable = stack_pointer[-(1 + oparg)]; + PyObject *method = stack_pointer[-(2 + oparg)]; + PyObject *res; + #line 2990 "Python/bytecodes.c" + assert(kwnames == NULL); + /* len(o) */ + int is_meth = method != NULL; + int total_args = oparg; + if (is_meth) { + callable = method; + args--; + total_args++; + } + DEOPT_IF(total_args != 1, CALL); + PyInterpreterState *interp = _PyInterpreterState_GET(); + DEOPT_IF(callable != interp->callable_cache.len, CALL); + STAT_INC(CALL, hit); + PyObject *arg = args[0]; + Py_ssize_t len_i = PyObject_Length(arg); + if (len_i < 0) { + goto error; + } + res = PyLong_FromSsize_t(len_i); + assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); + + Py_DECREF(callable); + Py_DECREF(arg); + if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } + #line 4172 "Python/generated_cases.c.h" + STACK_SHRINK(oparg); + STACK_SHRINK(1); + stack_pointer[-1] = res; + next_instr += 3; + DISPATCH(); + } + + TARGET(CALL_NO_KW_ISINSTANCE) { + PyObject **args = (stack_pointer - oparg); + PyObject *callable = stack_pointer[-(1 + oparg)]; + PyObject *method = stack_pointer[-(2 + oparg)]; + PyObject *res; + #line 3017 "Python/bytecodes.c" + assert(kwnames == NULL); + /* isinstance(o, o2) */ + int is_meth = method != NULL; + int total_args = oparg; + if (is_meth) { + callable = method; + args--; + total_args++; + } + DEOPT_IF(total_args != 2, CALL); + PyInterpreterState *interp = _PyInterpreterState_GET(); + DEOPT_IF(callable != interp->callable_cache.isinstance, CALL); + STAT_INC(CALL, hit); + PyObject *cls = args[1]; + PyObject *inst = args[0]; + int retval = PyObject_IsInstance(inst, cls); + if (retval < 0) { + goto error; + } + res = PyBool_FromLong(retval); + assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); + + Py_DECREF(inst); + Py_DECREF(cls); + Py_DECREF(callable); + if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } + #line 4212 "Python/generated_cases.c.h" + STACK_SHRINK(oparg); + STACK_SHRINK(1); + stack_pointer[-1] = res; + next_instr += 3; + DISPATCH(); + } + + TARGET(CALL_NO_KW_LIST_APPEND) { + PyObject **args = (stack_pointer - oparg); + PyObject *self = stack_pointer[-(1 + oparg)]; + PyObject *method = stack_pointer[-(2 + oparg)]; + #line 3047 "Python/bytecodes.c" + assert(kwnames == NULL); + assert(oparg == 1); + PyInterpreterState *interp = _PyInterpreterState_GET(); + DEOPT_IF(method != interp->callable_cache.list_append, CALL); + assert(self != NULL); + DEOPT_IF(!PyList_Check(self), CALL); + STAT_INC(CALL, hit); + if (_PyList_AppendTakeRef((PyListObject *)self, args[0]) < 0) { + goto pop_1_error; // Since arg is DECREF'ed already + } + Py_DECREF(self); + Py_DECREF(method); + STACK_SHRINK(3); + // CALL + POP_TOP + JUMPBY(INLINE_CACHE_ENTRIES_CALL + 1); + assert(next_instr[-1].op.code == POP_TOP); + DISPATCH(); + #line 4242 "Python/generated_cases.c.h" + } + + TARGET(CALL_NO_KW_METHOD_DESCRIPTOR_O) { + PyObject **args = (stack_pointer - oparg); + PyObject *method = stack_pointer[-(2 + oparg)]; + PyObject *res; + #line 3067 "Python/bytecodes.c" + assert(kwnames == NULL); + int is_meth = method != NULL; + int total_args = oparg; + if (is_meth) { + args--; + total_args++; + } + PyMethodDescrObject *callable = + (PyMethodDescrObject *)PEEK(total_args + 1); + DEOPT_IF(total_args != 2, CALL); + DEOPT_IF(!Py_IS_TYPE(callable, &PyMethodDescr_Type), CALL); + PyMethodDef *meth = callable->d_method; + DEOPT_IF(meth->ml_flags != METH_O, CALL); + PyObject *arg = args[1]; + PyObject *self = args[0]; + DEOPT_IF(!Py_IS_TYPE(self, callable->d_common.d_type), CALL); + STAT_INC(CALL, hit); + PyCFunction cfunc = meth->ml_meth; + // This is slower but CPython promises to check all non-vectorcall + // function calls. + if (_Py_EnterRecursiveCallTstate(tstate, " while calling a Python object")) { + goto error; + } + res = _PyCFunction_TrampolineCall(cfunc, self, arg); + _Py_LeaveRecursiveCallTstate(tstate); + assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); + Py_DECREF(self); + Py_DECREF(arg); + Py_DECREF(callable); + if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } + #line 4280 "Python/generated_cases.c.h" + STACK_SHRINK(oparg); + STACK_SHRINK(1); + stack_pointer[-1] = res; + next_instr += 3; + CHECK_EVAL_BREAKER(); + DISPATCH(); + } + + TARGET(CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS) { + PyObject **args = (stack_pointer - oparg); + PyObject *method = stack_pointer[-(2 + oparg)]; + PyObject *res; + #line 3101 "Python/bytecodes.c" + int is_meth = method != NULL; + int total_args = oparg; + if (is_meth) { + args--; + total_args++; + } + PyMethodDescrObject *callable = + (PyMethodDescrObject *)PEEK(total_args + 1); + DEOPT_IF(!Py_IS_TYPE(callable, &PyMethodDescr_Type), CALL); + PyMethodDef *meth = callable->d_method; + DEOPT_IF(meth->ml_flags != (METH_FASTCALL|METH_KEYWORDS), CALL); + PyTypeObject *d_type = callable->d_common.d_type; + PyObject *self = args[0]; + DEOPT_IF(!Py_IS_TYPE(self, d_type), CALL); + STAT_INC(CALL, hit); + int nargs = total_args - 1; + _PyCFunctionFastWithKeywords cfunc = + (_PyCFunctionFastWithKeywords)(void(*)(void))meth->ml_meth; + res = cfunc(self, args + 1, nargs - KWNAMES_LEN(), kwnames); + assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); + kwnames = NULL; + + /* Free the arguments. */ + for (int i = 0; i < total_args; i++) { + Py_DECREF(args[i]); + } + Py_DECREF(callable); + if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } + #line 4322 "Python/generated_cases.c.h" + STACK_SHRINK(oparg); + STACK_SHRINK(1); + stack_pointer[-1] = res; + next_instr += 3; + CHECK_EVAL_BREAKER(); + DISPATCH(); + } + + TARGET(CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS) { + PyObject **args = (stack_pointer - oparg); + PyObject *method = stack_pointer[-(2 + oparg)]; + PyObject *res; + #line 3133 "Python/bytecodes.c" + assert(kwnames == NULL); + assert(oparg == 0 || oparg == 1); + int is_meth = method != NULL; + int total_args = oparg; + if (is_meth) { + args--; + total_args++; + } + DEOPT_IF(total_args != 1, CALL); + PyMethodDescrObject *callable = (PyMethodDescrObject *)SECOND(); + DEOPT_IF(!Py_IS_TYPE(callable, &PyMethodDescr_Type), CALL); + PyMethodDef *meth = callable->d_method; + PyObject *self = args[0]; + DEOPT_IF(!Py_IS_TYPE(self, callable->d_common.d_type), CALL); + DEOPT_IF(meth->ml_flags != METH_NOARGS, CALL); + STAT_INC(CALL, hit); + PyCFunction cfunc = meth->ml_meth; + // This is slower but CPython promises to check all non-vectorcall + // function calls. + if (_Py_EnterRecursiveCallTstate(tstate, " while calling a Python object")) { + goto error; + } + res = _PyCFunction_TrampolineCall(cfunc, self, NULL); + _Py_LeaveRecursiveCallTstate(tstate); + assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); + Py_DECREF(self); + Py_DECREF(callable); + if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } + #line 4364 "Python/generated_cases.c.h" + STACK_SHRINK(oparg); + STACK_SHRINK(1); + stack_pointer[-1] = res; + next_instr += 3; + CHECK_EVAL_BREAKER(); + DISPATCH(); + } + + TARGET(CALL_NO_KW_METHOD_DESCRIPTOR_FAST) { + PyObject **args = (stack_pointer - oparg); + PyObject *method = stack_pointer[-(2 + oparg)]; + PyObject *res; + #line 3165 "Python/bytecodes.c" + assert(kwnames == NULL); + int is_meth = method != NULL; + int total_args = oparg; + if (is_meth) { + args--; + total_args++; + } + PyMethodDescrObject *callable = + (PyMethodDescrObject *)PEEK(total_args + 1); + /* Builtin METH_FASTCALL methods, without keywords */ + DEOPT_IF(!Py_IS_TYPE(callable, &PyMethodDescr_Type), CALL); + PyMethodDef *meth = callable->d_method; + DEOPT_IF(meth->ml_flags != METH_FASTCALL, CALL); + PyObject *self = args[0]; + DEOPT_IF(!Py_IS_TYPE(self, callable->d_common.d_type), CALL); + STAT_INC(CALL, hit); + _PyCFunctionFast cfunc = + (_PyCFunctionFast)(void(*)(void))meth->ml_meth; + int nargs = total_args - 1; + res = cfunc(self, args + 1, nargs); + assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL)); + /* Clear the stack of the arguments. */ + for (int i = 0; i < total_args; i++) { + Py_DECREF(args[i]); + } + Py_DECREF(callable); + if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } + #line 4405 "Python/generated_cases.c.h" + STACK_SHRINK(oparg); + STACK_SHRINK(1); + stack_pointer[-1] = res; + next_instr += 3; + CHECK_EVAL_BREAKER(); + DISPATCH(); + } + + TARGET(INSTRUMENTED_CALL_FUNCTION_EX) { + #line 3196 "Python/bytecodes.c" + GO_TO_INSTRUCTION(CALL_FUNCTION_EX); + #line 4417 "Python/generated_cases.c.h" + } + + TARGET(CALL_FUNCTION_EX) { + PREDICTED(CALL_FUNCTION_EX); + PyObject *kwargs = (oparg & 1) ? stack_pointer[-(((oparg & 1) ? 1 : 0))] : NULL; + PyObject *callargs = stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))]; + PyObject *func = stack_pointer[-(2 + ((oparg & 1) ? 1 : 0))]; + PyObject *result; + #line 3200 "Python/bytecodes.c" + // DICT_MERGE is called before this opcode if there are kwargs. + // It converts all dict subtypes in kwargs into regular dicts. + assert(kwargs == NULL || PyDict_CheckExact(kwargs)); + if (!PyTuple_CheckExact(callargs)) { + if (check_args_iterable(tstate, func, callargs) < 0) { + goto error; + } + PyObject *tuple = PySequence_Tuple(callargs); + if (tuple == NULL) { + goto error; + } + Py_SETREF(callargs, tuple); + } + assert(PyTuple_CheckExact(callargs)); + EVAL_CALL_STAT_INC_IF_FUNCTION(EVAL_CALL_FUNCTION_EX, func); + if (opcode == INSTRUMENTED_CALL_FUNCTION_EX && + !PyFunction_Check(func) && !PyMethod_Check(func) + ) { + PyObject *arg = PyTuple_GET_SIZE(callargs) > 0 ? + PyTuple_GET_ITEM(callargs, 0) : Py_None; + int err = _Py_call_instrumentation_2args( + tstate, PY_MONITORING_EVENT_CALL, + frame, next_instr-1, func, arg); + if (err) goto error; + result = PyObject_Call(func, callargs, kwargs); + if (result == NULL) { + _Py_call_instrumentation_exc2( + tstate, PY_MONITORING_EVENT_C_RAISE, + frame, next_instr-1, func, arg); + } + else { + int err = _Py_call_instrumentation_2args( + tstate, PY_MONITORING_EVENT_C_RETURN, + frame, next_instr-1, func, arg); + if (err < 0) { + Py_CLEAR(result); + } + } + } + else { + if (Py_TYPE(func) == &PyFunction_Type && + tstate->interp->eval_frame == NULL && + ((PyFunctionObject *)func)->vectorcall == _PyFunction_Vectorcall) { + assert(PyTuple_CheckExact(callargs)); + Py_ssize_t nargs = PyTuple_GET_SIZE(callargs); + int code_flags = ((PyCodeObject *)PyFunction_GET_CODE(func))->co_flags; + PyObject *locals = code_flags & CO_OPTIMIZED ? NULL : Py_NewRef(PyFunction_GET_GLOBALS(func)); + + _PyInterpreterFrame *new_frame = _PyEvalFramePushAndInit_Ex(tstate, + (PyFunctionObject *)func, locals, + nargs, callargs, kwargs); + // Need to manually shrink the stack since we exit with DISPATCH_INLINED. + STACK_SHRINK(oparg + 3); + if (new_frame == NULL) { + goto error; + } + frame->return_offset = 0; + DISPATCH_INLINED(new_frame); + } + result = PyObject_Call(func, callargs, kwargs); + } + #line 4488 "Python/generated_cases.c.h" + Py_DECREF(func); + Py_DECREF(callargs); + Py_XDECREF(kwargs); + #line 3262 "Python/bytecodes.c" + assert(PEEK(3 + (oparg & 1)) == NULL); + if (result == NULL) { STACK_SHRINK(((oparg & 1) ? 1 : 0)); goto pop_3_error; } + #line 4495 "Python/generated_cases.c.h" + STACK_SHRINK(((oparg & 1) ? 1 : 0)); + STACK_SHRINK(2); + stack_pointer[-1] = result; + CHECK_EVAL_BREAKER(); + DISPATCH(); + } + + TARGET(MAKE_FUNCTION) { + PyObject *codeobj = stack_pointer[-1]; + PyObject *closure = (oparg & 0x08) ? stack_pointer[-(1 + ((oparg & 0x08) ? 1 : 0))] : NULL; + PyObject *annotations = (oparg & 0x04) ? stack_pointer[-(1 + ((oparg & 0x08) ? 1 : 0) + ((oparg & 0x04) ? 1 : 0))] : NULL; + PyObject *kwdefaults = (oparg & 0x02) ? stack_pointer[-(1 + ((oparg & 0x08) ? 1 : 0) + ((oparg & 0x04) ? 1 : 0) + ((oparg & 0x02) ? 1 : 0))] : NULL; + PyObject *defaults = (oparg & 0x01) ? stack_pointer[-(1 + ((oparg & 0x08) ? 1 : 0) + ((oparg & 0x04) ? 1 : 0) + ((oparg & 0x02) ? 1 : 0) + ((oparg & 0x01) ? 1 : 0))] : NULL; + PyObject *func; + #line 3272 "Python/bytecodes.c" + + PyFunctionObject *func_obj = (PyFunctionObject *) + PyFunction_New(codeobj, GLOBALS()); + + Py_DECREF(codeobj); + if (func_obj == NULL) { + goto error; + } + + if (oparg & 0x08) { + assert(PyTuple_CheckExact(closure)); + func_obj->func_closure = closure; + } + if (oparg & 0x04) { + assert(PyTuple_CheckExact(annotations)); + func_obj->func_annotations = annotations; + } + if (oparg & 0x02) { + assert(PyDict_CheckExact(kwdefaults)); + func_obj->func_kwdefaults = kwdefaults; + } + if (oparg & 0x01) { + assert(PyTuple_CheckExact(defaults)); + func_obj->func_defaults = defaults; + } + + func_obj->func_version = ((PyCodeObject *)codeobj)->co_version; + func = (PyObject *)func_obj; + #line 4539 "Python/generated_cases.c.h" + STACK_SHRINK(((oparg & 0x01) ? 1 : 0) + ((oparg & 0x02) ? 1 : 0) + ((oparg & 0x04) ? 1 : 0) + ((oparg & 0x08) ? 1 : 0)); + stack_pointer[-1] = func; + DISPATCH(); + } + + TARGET(RETURN_GENERATOR) { + #line 3303 "Python/bytecodes.c" + assert(PyFunction_Check(frame->f_funcobj)); + PyFunctionObject *func = (PyFunctionObject *)frame->f_funcobj; + PyGenObject *gen = (PyGenObject *)_Py_MakeCoro(func); + if (gen == NULL) { + goto error; + } + assert(EMPTY()); + _PyFrame_SetStackPointer(frame, stack_pointer); + _PyInterpreterFrame *gen_frame = (_PyInterpreterFrame *)gen->gi_iframe; + _PyFrame_Copy(frame, gen_frame); + assert(frame->frame_obj == NULL); + gen->gi_frame_state = FRAME_CREATED; + gen_frame->owner = FRAME_OWNED_BY_GENERATOR; + _Py_LeaveRecursiveCallPy(tstate); + assert(frame != &entry_frame); + _PyInterpreterFrame *prev = frame->previous; + _PyThreadState_PopFrame(tstate, frame); + frame = cframe.current_frame = prev; + _PyFrame_StackPush(frame, (PyObject *)gen); + goto resume_frame; + #line 4567 "Python/generated_cases.c.h" + } + + TARGET(BUILD_SLICE) { + PyObject *step = (oparg == 3) ? stack_pointer[-(((oparg == 3) ? 1 : 0))] : NULL; + PyObject *stop = stack_pointer[-(1 + ((oparg == 3) ? 1 : 0))]; + PyObject *start = stack_pointer[-(2 + ((oparg == 3) ? 1 : 0))]; + PyObject *slice; + #line 3326 "Python/bytecodes.c" + slice = PySlice_New(start, stop, step); + #line 4577 "Python/generated_cases.c.h" + Py_DECREF(start); + Py_DECREF(stop); + Py_XDECREF(step); + #line 3328 "Python/bytecodes.c" + if (slice == NULL) { STACK_SHRINK(((oparg == 3) ? 1 : 0)); goto pop_2_error; } + #line 4583 "Python/generated_cases.c.h" + STACK_SHRINK(((oparg == 3) ? 1 : 0)); + STACK_SHRINK(1); + stack_pointer[-1] = slice; + DISPATCH(); + } + + TARGET(FORMAT_VALUE) { + PyObject *fmt_spec = ((oparg & FVS_MASK) == FVS_HAVE_SPEC) ? stack_pointer[-((((oparg & FVS_MASK) == FVS_HAVE_SPEC) ? 1 : 0))] : NULL; + PyObject *value = stack_pointer[-(1 + (((oparg & FVS_MASK) == FVS_HAVE_SPEC) ? 1 : 0))]; + PyObject *result; + #line 3332 "Python/bytecodes.c" + /* Handles f-string value formatting. */ + PyObject *(*conv_fn)(PyObject *); + int which_conversion = oparg & FVC_MASK; + + /* See if any conversion is specified. */ + switch (which_conversion) { + case FVC_NONE: conv_fn = NULL; break; + case FVC_STR: conv_fn = PyObject_Str; break; + case FVC_REPR: conv_fn = PyObject_Repr; break; + case FVC_ASCII: conv_fn = PyObject_ASCII; break; + default: + _PyErr_Format(tstate, PyExc_SystemError, + "unexpected conversion flag %d", + which_conversion); + goto error; + } + + /* If there's a conversion function, call it and replace + value with that result. Otherwise, just use value, + without conversion. */ + if (conv_fn != NULL) { + result = conv_fn(value); + Py_DECREF(value); + if (result == NULL) { + Py_XDECREF(fmt_spec); + if (true) { STACK_SHRINK((((oparg & FVS_MASK) == FVS_HAVE_SPEC) ? 1 : 0)); goto pop_1_error; } + } + value = result; + } + + result = PyObject_Format(value, fmt_spec); + Py_DECREF(value); + Py_XDECREF(fmt_spec); + if (result == NULL) { STACK_SHRINK((((oparg & FVS_MASK) == FVS_HAVE_SPEC) ? 1 : 0)); goto pop_1_error; } + #line 4629 "Python/generated_cases.c.h" + STACK_SHRINK((((oparg & FVS_MASK) == FVS_HAVE_SPEC) ? 1 : 0)); + stack_pointer[-1] = result; + DISPATCH(); + } + + TARGET(COPY) { + PyObject *bottom = stack_pointer[-(1 + (oparg-1))]; + PyObject *top; + #line 3369 "Python/bytecodes.c" + assert(oparg > 0); + top = Py_NewRef(bottom); + #line 4641 "Python/generated_cases.c.h" + STACK_GROW(1); + stack_pointer[-1] = top; + DISPATCH(); + } + + TARGET(BINARY_OP) { + PREDICTED(BINARY_OP); + static_assert(INLINE_CACHE_ENTRIES_BINARY_OP == 1, "incorrect cache size"); + PyObject *rhs = stack_pointer[-1]; + PyObject *lhs = stack_pointer[-2]; + PyObject *res; + #line 3374 "Python/bytecodes.c" + #if ENABLE_SPECIALIZATION + _PyBinaryOpCache *cache = (_PyBinaryOpCache *)next_instr; + if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { + next_instr--; + _Py_Specialize_BinaryOp(lhs, rhs, next_instr, oparg, &GETLOCAL(0)); + DISPATCH_SAME_OPARG(); + } + STAT_INC(BINARY_OP, deferred); + DECREMENT_ADAPTIVE_COUNTER(cache->counter); + #endif /* ENABLE_SPECIALIZATION */ + assert(0 <= oparg); + assert((unsigned)oparg < Py_ARRAY_LENGTH(binary_ops)); + assert(binary_ops[oparg]); + res = binary_ops[oparg](lhs, rhs); + #line 4668 "Python/generated_cases.c.h" + Py_DECREF(lhs); + Py_DECREF(rhs); + #line 3389 "Python/bytecodes.c" + if (res == NULL) goto pop_2_error; + #line 4673 "Python/generated_cases.c.h" + STACK_SHRINK(1); + stack_pointer[-1] = res; + next_instr += 1; + DISPATCH(); + } + + TARGET(SWAP) { + PyObject *top = stack_pointer[-1]; + PyObject *bottom = stack_pointer[-(2 + (oparg-2))]; + #line 3394 "Python/bytecodes.c" + assert(oparg >= 2); + #line 4685 "Python/generated_cases.c.h" + stack_pointer[-1] = bottom; + stack_pointer[-(2 + (oparg-2))] = top; + DISPATCH(); + } + + TARGET(INSTRUMENTED_INSTRUCTION) { + #line 3398 "Python/bytecodes.c" + int next_opcode = _Py_call_instrumentation_instruction( + tstate, frame, next_instr-1); + if (next_opcode < 0) goto error; + next_instr--; + if (_PyOpcode_Caches[next_opcode]) { + _PyBinaryOpCache *cache = (_PyBinaryOpCache *)(next_instr+1); + INCREMENT_ADAPTIVE_COUNTER(cache->counter); + } + assert(next_opcode > 0 && next_opcode < 256); + opcode = next_opcode; + DISPATCH_GOTO(); + #line 4704 "Python/generated_cases.c.h" + } + + TARGET(INSTRUMENTED_JUMP_FORWARD) { + #line 3412 "Python/bytecodes.c" + INSTRUMENTED_JUMP(next_instr-1, next_instr+oparg, PY_MONITORING_EVENT_JUMP); + #line 4710 "Python/generated_cases.c.h" + DISPATCH(); + } + + TARGET(INSTRUMENTED_JUMP_BACKWARD) { + #line 3416 "Python/bytecodes.c" + INSTRUMENTED_JUMP(next_instr-1, next_instr-oparg, PY_MONITORING_EVENT_JUMP); + #line 4717 "Python/generated_cases.c.h" + CHECK_EVAL_BREAKER(); + DISPATCH(); + } + + TARGET(INSTRUMENTED_POP_JUMP_IF_TRUE) { + #line 3421 "Python/bytecodes.c" + PyObject *cond = POP(); + int err = PyObject_IsTrue(cond); + Py_DECREF(cond); + if (err < 0) goto error; + _Py_CODEUNIT *here = next_instr-1; + assert(err == 0 || err == 1); + int offset = err*oparg; + INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH); + #line 4732 "Python/generated_cases.c.h" + DISPATCH(); + } + + TARGET(INSTRUMENTED_POP_JUMP_IF_FALSE) { + #line 3432 "Python/bytecodes.c" + PyObject *cond = POP(); + int err = PyObject_IsTrue(cond); + Py_DECREF(cond); + if (err < 0) goto error; + _Py_CODEUNIT *here = next_instr-1; + assert(err == 0 || err == 1); + int offset = (1-err)*oparg; + INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH); + #line 4746 "Python/generated_cases.c.h" + DISPATCH(); + } + + TARGET(INSTRUMENTED_POP_JUMP_IF_NONE) { + #line 3443 "Python/bytecodes.c" + PyObject *value = POP(); + _Py_CODEUNIT *here = next_instr-1; + int offset; + if (Py_IsNone(value)) { + offset = oparg; + } + else { + Py_DECREF(value); + offset = 0; + } + INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH); + #line 4763 "Python/generated_cases.c.h" + DISPATCH(); + } + + TARGET(INSTRUMENTED_POP_JUMP_IF_NOT_NONE) { + #line 3457 "Python/bytecodes.c" + PyObject *value = POP(); + _Py_CODEUNIT *here = next_instr-1; + int offset; + if (Py_IsNone(value)) { + offset = 0; + } + else { + Py_DECREF(value); + offset = oparg; + } + INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH); + #line 4780 "Python/generated_cases.c.h" + DISPATCH(); + } + + TARGET(EXTENDED_ARG) { + #line 3471 "Python/bytecodes.c" + assert(oparg); + opcode = next_instr->op.code; + oparg = oparg << 8 | next_instr->op.arg; + PRE_DISPATCH_GOTO(); + DISPATCH_GOTO(); + #line 4791 "Python/generated_cases.c.h" + } + + TARGET(CACHE) { + #line 3479 "Python/bytecodes.c" + assert(0 && "Executing a cache."); + Py_UNREACHABLE(); + #line 4798 "Python/generated_cases.c.h" + } + + TARGET(RESERVED) { + #line 3484 "Python/bytecodes.c" + assert(0 && "Executing RESERVED instruction."); + Py_UNREACHABLE(); + #line 4805 "Python/generated_cases.c.h" + } diff --git a/Python/getargs.c b/Python/getargs.c index 3105bd55..66dd9087 100644 --- a/Python/getargs.c +++ b/Python/getargs.c @@ -1012,58 +1012,6 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags, break; } - case 'u': /* raw unicode buffer (Py_UNICODE *) */ - case 'Z': /* raw unicode buffer or None */ - { - if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, - "getargs: The '%c' format is deprecated. Use 'U' instead.", c)) { - RETURN_ERR_OCCURRED; - } -_Py_COMP_DIAG_PUSH -_Py_COMP_DIAG_IGNORE_DEPR_DECLS - Py_UNICODE **p = va_arg(*p_va, Py_UNICODE **); - - if (*format == '#') { - /* "u#" or "Z#" */ - REQUIRE_PY_SSIZE_T_CLEAN; - Py_ssize_t *psize = va_arg(*p_va, Py_ssize_t*); - - if (c == 'Z' && arg == Py_None) { - *p = NULL; - *psize = 0; - } - else if (PyUnicode_Check(arg)) { - Py_ssize_t len; - *p = PyUnicode_AsUnicodeAndSize(arg, &len); - if (*p == NULL) - RETURN_ERR_OCCURRED; - *psize = len; - } - else - return converterr(c == 'Z' ? "str or None" : "str", - arg, msgbuf, bufsize); - format++; - } else { - /* "u" or "Z" */ - if (c == 'Z' && arg == Py_None) - *p = NULL; - else if (PyUnicode_Check(arg)) { - Py_ssize_t len; - *p = PyUnicode_AsUnicodeAndSize(arg, &len); - if (*p == NULL) - RETURN_ERR_OCCURRED; - if (wcslen(*p) != (size_t)len) { - PyErr_SetString(PyExc_ValueError, "embedded null character"); - RETURN_ERR_OCCURRED; - } - } else - return converterr(c == 'Z' ? "str or None" : "str", - arg, msgbuf, bufsize); - } - break; -_Py_COMP_DIAG_POP - } - case 'e': {/* encoded string */ char **buffer; const char *encoding; @@ -1098,8 +1046,7 @@ _Py_COMP_DIAG_POP /* Encode object */ if (!recode_strings && (PyBytes_Check(arg) || PyByteArray_Check(arg))) { - s = arg; - Py_INCREF(s); + s = Py_NewRef(arg); if (PyBytes_Check(arg)) { size = PyBytes_GET_SIZE(s); ptr = PyBytes_AS_STRING(s); @@ -1899,133 +1846,214 @@ vgetargskeywords(PyObject *args, PyObject *kwargs, const char *format, } -/* List of static parsers. */ -static struct _PyArg_Parser *static_arg_parsers = NULL; - static int -parser_init(struct _PyArg_Parser *parser) +scan_keywords(const char * const *keywords, int *ptotal, int *pposonly) { - const char * const *keywords; - const char *format, *msg; - int i, len, min, max, nkw; - PyObject *kwtuple; - - assert(parser->keywords != NULL); - if (parser->kwtuple != NULL) { - return 1; - } - - keywords = parser->keywords; /* scan keywords and count the number of positional-only parameters */ + int i; for (i = 0; keywords[i] && !*keywords[i]; i++) { } - parser->pos = i; + *pposonly = i; + /* scan keywords and get greatest possible nbr of args */ for (; keywords[i]; i++) { if (!*keywords[i]) { PyErr_SetString(PyExc_SystemError, "Empty keyword parameter name"); - return 0; + return -1; } } - len = i; + *ptotal = i; + return 0; +} - format = parser->format; - if (format) { - /* grab the function name or custom error msg first (mutually exclusive) */ - parser->fname = strchr(parser->format, ':'); - if (parser->fname) { - parser->fname++; - parser->custom_msg = NULL; +static int +parse_format(const char *format, int total, int npos, + const char **pfname, const char **pcustommsg, + int *pmin, int *pmax) +{ + /* grab the function name or custom error msg first (mutually exclusive) */ + const char *custommsg; + const char *fname = strchr(format, ':'); + if (fname) { + fname++; + custommsg = NULL; + } + else { + custommsg = strchr(format,';'); + if (custommsg) { + custommsg++; } - else { - parser->custom_msg = strchr(parser->format,';'); - if (parser->custom_msg) - parser->custom_msg++; - } - - min = max = INT_MAX; - for (i = 0; i < len; i++) { - if (*format == '|') { - if (min != INT_MAX) { - PyErr_SetString(PyExc_SystemError, - "Invalid format string (| specified twice)"); - return 0; - } - if (max != INT_MAX) { - PyErr_SetString(PyExc_SystemError, - "Invalid format string ($ before |)"); - return 0; - } - min = i; - format++; + } + + int min = INT_MAX; + int max = INT_MAX; + for (int i = 0; i < total; i++) { + if (*format == '|') { + if (min != INT_MAX) { + PyErr_SetString(PyExc_SystemError, + "Invalid format string (| specified twice)"); + return -1; } - if (*format == '$') { - if (max != INT_MAX) { - PyErr_SetString(PyExc_SystemError, - "Invalid format string ($ specified twice)"); - return 0; - } - if (i < parser->pos) { - PyErr_SetString(PyExc_SystemError, - "Empty parameter name after $"); - return 0; - } - max = i; - format++; + if (max != INT_MAX) { + PyErr_SetString(PyExc_SystemError, + "Invalid format string ($ before |)"); + return -1; } - if (IS_END_OF_FORMAT(*format)) { - PyErr_Format(PyExc_SystemError, - "More keyword list entries (%d) than " - "format specifiers (%d)", len, i); - return 0; + min = i; + format++; + } + if (*format == '$') { + if (max != INT_MAX) { + PyErr_SetString(PyExc_SystemError, + "Invalid format string ($ specified twice)"); + return -1; } - - msg = skipitem(&format, NULL, 0); - if (msg) { - PyErr_Format(PyExc_SystemError, "%s: '%s'", msg, - format); - return 0; + if (i < npos) { + PyErr_SetString(PyExc_SystemError, + "Empty parameter name after $"); + return -1; } + max = i; + format++; } - parser->min = Py_MIN(min, len); - parser->max = Py_MIN(max, len); - - if (!IS_END_OF_FORMAT(*format) && (*format != '|') && (*format != '$')) { + if (IS_END_OF_FORMAT(*format)) { PyErr_Format(PyExc_SystemError, - "more argument specifiers than keyword list entries " - "(remaining format:'%s')", format); - return 0; + "More keyword list entries (%d) than " + "format specifiers (%d)", total, i); + return -1; + } + + const char *msg = skipitem(&format, NULL, 0); + if (msg) { + PyErr_Format(PyExc_SystemError, "%s: '%s'", msg, + format); + return -1; } } + min = Py_MIN(min, total); + max = Py_MIN(max, total); - nkw = len - parser->pos; - kwtuple = PyTuple_New(nkw); + if (!IS_END_OF_FORMAT(*format) && (*format != '|') && (*format != '$')) { + PyErr_Format(PyExc_SystemError, + "more argument specifiers than keyword list entries " + "(remaining format:'%s')", format); + return -1; + } + + *pfname = fname; + *pcustommsg = custommsg; + *pmin = min; + *pmax = max; + return 0; +} + +static PyObject * +new_kwtuple(const char * const *keywords, int total, int pos) +{ + int nkw = total - pos; + PyObject *kwtuple = PyTuple_New(nkw); if (kwtuple == NULL) { - return 0; + return NULL; } - keywords = parser->keywords + parser->pos; - for (i = 0; i < nkw; i++) { + keywords += pos; + for (int i = 0; i < nkw; i++) { PyObject *str = PyUnicode_FromString(keywords[i]); if (str == NULL) { Py_DECREF(kwtuple); - return 0; + return NULL; } PyUnicode_InternInPlace(&str); PyTuple_SET_ITEM(kwtuple, i, str); } + return kwtuple; +} + +static int +_parser_init(struct _PyArg_Parser *parser) +{ + const char * const *keywords = parser->keywords; + assert(keywords != NULL); + assert(parser->pos == 0 && + (parser->format == NULL || parser->fname == NULL) && + parser->custom_msg == NULL && + parser->min == 0 && + parser->max == 0); + + int len, pos; + if (scan_keywords(keywords, &len, &pos) < 0) { + return 0; + } + + const char *fname, *custommsg = NULL; + int min = 0, max = 0; + if (parser->format) { + assert(parser->fname == NULL); + if (parse_format(parser->format, len, pos, + &fname, &custommsg, &min, &max) < 0) { + return 0; + } + } + else { + assert(parser->fname != NULL); + fname = parser->fname; + } + + int owned; + PyObject *kwtuple = parser->kwtuple; + if (kwtuple == NULL) { + kwtuple = new_kwtuple(keywords, len, pos); + if (kwtuple == NULL) { + return 0; + } + owned = 1; + } + else { + owned = 0; + } + + parser->pos = pos; + parser->fname = fname; + parser->custom_msg = custommsg; + parser->min = min; + parser->max = max; parser->kwtuple = kwtuple; + parser->initialized = owned ? 1 : -1; assert(parser->next == NULL); - parser->next = static_arg_parsers; - static_arg_parsers = parser; + parser->next = _PyRuntime.getargs.static_parsers; + _PyRuntime.getargs.static_parsers = parser; return 1; } +static int +parser_init(struct _PyArg_Parser *parser) +{ + // volatile as it can be modified by other threads + // and should not be optimized or reordered by compiler + if (*((volatile int *)&parser->initialized)) { + assert(parser->kwtuple != NULL); + return 1; + } + PyThread_acquire_lock(_PyRuntime.getargs.mutex, WAIT_LOCK); + // Check again if another thread initialized the parser + // while we were waiting for the lock. + if (*((volatile int *)&parser->initialized)) { + assert(parser->kwtuple != NULL); + PyThread_release_lock(_PyRuntime.getargs.mutex); + return 1; + } + int ret = _parser_init(parser); + PyThread_release_lock(_PyRuntime.getargs.mutex); + return ret; +} + static void parser_clear(struct _PyArg_Parser *parser) { - Py_CLEAR(parser->kwtuple); + if (parser->initialized == 1) { + Py_CLEAR(parser->kwtuple); + } } static PyObject* @@ -2152,6 +2180,7 @@ vgetargskeywordsfast_impl(PyObject *const *args, Py_ssize_t nargs, } format = parser->format; + assert(format != NULL || len == 0); /* convert tuple args and keyword args in same loop, using kwtuple to drive process */ for (i = 0; i < len; i++) { if (*format == '|') { @@ -2542,8 +2571,7 @@ _PyArg_UnpackKeywordsWithVararg(PyObject *const *args, Py_ssize_t nargs, /* copy tuple args */ for (i = 0; i < nargs; i++) { if (i >= vararg) { - Py_INCREF(args[i]); - PyTuple_SET_ITEM(buf[vararg], i - vararg, args[i]); + PyTuple_SET_ITEM(buf[vararg], i - vararg, Py_NewRef(args[i])); continue; } else { @@ -2675,8 +2703,6 @@ skipitem(const char **p_format, va_list *p_va, int flags) case 's': /* string */ case 'z': /* string or None */ case 'y': /* bytes */ - case 'u': /* unicode string */ - case 'Z': /* unicode string or None */ case 'w': /* buffer, read-write */ { if (p_va != NULL) { @@ -2834,11 +2860,7 @@ PyArg_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t m stack = _PyTuple_ITEMS(args); nargs = PyTuple_GET_SIZE(args); -#ifdef HAVE_STDARG_PROTOTYPES va_start(vargs, max); -#else - va_start(vargs); -#endif retval = unpack_stack(stack, nargs, name, min, max, vargs); va_end(vargs); return retval; @@ -2851,11 +2873,7 @@ _PyArg_UnpackStack(PyObject *const *args, Py_ssize_t nargs, const char *name, int retval; va_list vargs; -#ifdef HAVE_STDARG_PROTOTYPES va_start(vargs, max); -#else - va_start(vargs); -#endif retval = unpack_stack(args, nargs, name, min, max, vargs); va_end(vargs); return retval; @@ -2927,14 +2945,14 @@ _PyArg_NoKwnames(const char *funcname, PyObject *kwnames) void _PyArg_Fini(void) { - struct _PyArg_Parser *tmp, *s = static_arg_parsers; + struct _PyArg_Parser *tmp, *s = _PyRuntime.getargs.static_parsers; while (s) { tmp = s->next; s->next = NULL; parser_clear(s); s = tmp; } - static_arg_parsers = NULL; + _PyRuntime.getargs.static_parsers = NULL; } #ifdef __cplusplus diff --git a/Python/getversion.c b/Python/getversion.c index 46910451..5db836ab 100644 --- a/Python/getversion.c +++ b/Python/getversion.c @@ -5,12 +5,23 @@ #include "patchlevel.h" -const char * -Py_GetVersion(void) +static int initialized = 0; +static char version[250]; + +void _Py_InitVersion(void) { - static char version[250]; + if (initialized) { + return; + } + initialized = 1; PyOS_snprintf(version, sizeof(version), "%.80s (%.80s) %.80s", PY_VERSION, Py_GetBuildInfo(), Py_GetCompiler()); +} + +const char * +Py_GetVersion(void) +{ + _Py_InitVersion(); return version; } diff --git a/Python/hamt.c b/Python/hamt.c index 908c2531..8cb94641 100644 --- a/Python/hamt.c +++ b/Python/hamt.c @@ -319,13 +319,6 @@ typedef struct { } PyHamtNode_Array; -typedef struct { - PyObject_VAR_HEAD - uint32_t b_bitmap; - PyObject *b_array[1]; -} PyHamtNode_Bitmap; - - typedef struct { PyObject_VAR_HEAD int32_t c_hash; @@ -333,10 +326,6 @@ typedef struct { } PyHamtNode_Collision; -static PyHamtNode_Bitmap *_empty_bitmap_node; -static PyHamtObject *_empty_hamt; - - static PyHamtObject * hamt_alloc(void); @@ -496,11 +485,7 @@ _hamt_dump_format(_PyUnicodeWriter *writer, const char *format, ...) int ret; va_list vargs; -#ifdef HAVE_STDARG_PROTOTYPES va_start(vargs, format); -#else - va_start(vargs); -#endif msg = PyUnicode_FromFormatV(format, vargs); va_end(vargs); @@ -525,14 +510,16 @@ hamt_node_bitmap_new(Py_ssize_t size) PyHamtNode_Bitmap *node; Py_ssize_t i; + if (size == 0) { + /* Since bitmap nodes are immutable, we can cache the instance + for size=0 and reuse it whenever we need an empty bitmap node. + */ + return (PyHamtNode *)Py_NewRef(&_Py_SINGLETON(hamt_bitmap_node_empty)); + } + assert(size >= 0); assert(size % 2 == 0); - if (size == 0 && _empty_bitmap_node != NULL) { - Py_INCREF(_empty_bitmap_node); - return (PyHamtNode *)_empty_bitmap_node; - } - /* No freelist; allocate a new bitmap node */ node = PyObject_GC_NewVar( PyHamtNode_Bitmap, &_PyHamt_BitmapNode_Type, size); @@ -550,14 +537,6 @@ hamt_node_bitmap_new(Py_ssize_t size) _PyObject_GC_TRACK(node); - if (size == 0 && _empty_bitmap_node == NULL) { - /* Since bitmap nodes are immutable, we can cache the instance - for size=0 and reuse it whenever we need an empty bitmap node. - */ - _empty_bitmap_node = node; - Py_INCREF(_empty_bitmap_node); - } - return (PyHamtNode *)node; } @@ -581,8 +560,7 @@ hamt_node_bitmap_clone(PyHamtNode_Bitmap *node) } for (i = 0; i < Py_SIZE(node); i++) { - Py_XINCREF(node->b_array[i]); - clone->b_array[i] = node->b_array[i]; + clone->b_array[i] = Py_XNewRef(node->b_array[i]); } clone->b_bitmap = node->b_bitmap; @@ -607,14 +585,12 @@ hamt_node_bitmap_clone_without(PyHamtNode_Bitmap *o, uint32_t bit) uint32_t i; for (i = 0; i < key_idx; i++) { - Py_XINCREF(o->b_array[i]); - new->b_array[i] = o->b_array[i]; + new->b_array[i] = Py_XNewRef(o->b_array[i]); } assert(Py_SIZE(o) >= 0 && Py_SIZE(o) <= 32); for (i = val_idx + 1; i < (uint32_t)Py_SIZE(o); i++) { - Py_XINCREF(o->b_array[i]); - new->b_array[i - 2] = o->b_array[i]; + new->b_array[i - 2] = Py_XNewRef(o->b_array[i]); } new->b_bitmap = o->b_bitmap & ~bit; @@ -647,15 +623,11 @@ hamt_node_new_bitmap_or_collision(uint32_t shift, return NULL; } - Py_INCREF(key1); - n->c_array[0] = key1; - Py_INCREF(val1); - n->c_array[1] = val1; + n->c_array[0] = Py_NewRef(key1); + n->c_array[1] = Py_NewRef(val1); - Py_INCREF(key2); - n->c_array[2] = key2; - Py_INCREF(val2); - n->c_array[3] = val2; + n->c_array[2] = Py_NewRef(key2); + n->c_array[3] = Py_NewRef(val2); return (PyHamtNode *)n; } @@ -740,8 +712,7 @@ hamt_node_bitmap_assoc(PyHamtNode_Bitmap *self, if (val_or_node == (PyObject *)sub_node) { Py_DECREF(sub_node); - Py_INCREF(self); - return (PyHamtNode *)self; + return (PyHamtNode *)Py_NewRef(self); } PyHamtNode_Bitmap *ret = hamt_node_bitmap_clone(self); @@ -763,8 +734,7 @@ hamt_node_bitmap_assoc(PyHamtNode_Bitmap *self, if (comp_err == 1) { /* key == key_or_null */ if (val == val_or_node) { /* we already have the same key/val pair; return self. */ - Py_INCREF(self); - return (PyHamtNode *)self; + return (PyHamtNode *)Py_NewRef(self); } /* We're setting a new value for the key we had before. @@ -773,8 +743,7 @@ hamt_node_bitmap_assoc(PyHamtNode_Bitmap *self, if (ret == NULL) { return NULL; } - Py_INCREF(val); - Py_SETREF(ret->b_array[val_idx], val); + Py_SETREF(ret->b_array[val_idx], Py_NewRef(val)); return (PyHamtNode *)ret; } @@ -869,8 +838,7 @@ hamt_node_bitmap_assoc(PyHamtNode_Bitmap *self, if (self->b_array[j] == NULL) { new_node->a_array[i] = - (PyHamtNode *)self->b_array[j + 1]; - Py_INCREF(new_node->a_array[i]); + (PyHamtNode *)Py_NewRef(self->b_array[j + 1]); } else { int32_t rehash = hamt_hash(self->b_array[j]); @@ -927,22 +895,18 @@ hamt_node_bitmap_assoc(PyHamtNode_Bitmap *self, /* Copy all keys/values that will be before the new key/value we are adding. */ for (i = 0; i < key_idx; i++) { - Py_XINCREF(self->b_array[i]); - new_node->b_array[i] = self->b_array[i]; + new_node->b_array[i] = Py_XNewRef(self->b_array[i]); } /* Set the new key/value to the new Bitmap node. */ - Py_INCREF(key); - new_node->b_array[key_idx] = key; - Py_INCREF(val); - new_node->b_array[val_idx] = val; + new_node->b_array[key_idx] = Py_NewRef(key); + new_node->b_array[val_idx] = Py_NewRef(val); /* Copy all keys/values that will be after the new key/value we are adding. */ assert(Py_SIZE(self) >= 0 && Py_SIZE(self) <= 32); for (i = key_idx; i < (uint32_t)Py_SIZE(self); i++) { - Py_XINCREF(self->b_array[i]); - new_node->b_array[i + 2] = self->b_array[i]; + new_node->b_array[i + 2] = Py_XNewRef(self->b_array[i]); } new_node->b_bitmap = self->b_bitmap | bit; @@ -1023,10 +987,8 @@ hamt_node_bitmap_without(PyHamtNode_Bitmap *self, PyObject *key = sub_tree->b_array[0]; PyObject *val = sub_tree->b_array[1]; - Py_INCREF(key); - Py_XSETREF(clone->b_array[key_idx], key); - Py_INCREF(val); - Py_SETREF(clone->b_array[val_idx], val); + Py_XSETREF(clone->b_array[key_idx], Py_NewRef(key)); + Py_SETREF(clone->b_array[val_idx], Py_NewRef(val)); Py_DECREF(sub_tree); @@ -1164,6 +1126,16 @@ hamt_node_bitmap_dealloc(PyHamtNode_Bitmap *self) Py_ssize_t len = Py_SIZE(self); Py_ssize_t i; + if (Py_SIZE(self) == 0) { + /* The empty node is statically allocated. */ + assert(self == &_Py_SINGLETON(hamt_bitmap_node_empty)); +#ifdef Py_DEBUG + _Py_FatalRefcountError("deallocating the empty hamt node bitmap singleton"); +#else + return; +#endif + } + PyObject_GC_UnTrack(self); Py_TRASHCAN_BEGIN(self, hamt_node_bitmap_dealloc) @@ -1347,14 +1319,11 @@ hamt_node_collision_assoc(PyHamtNode_Collision *self, } for (i = 0; i < Py_SIZE(self); i++) { - Py_INCREF(self->c_array[i]); - new_node->c_array[i] = self->c_array[i]; + new_node->c_array[i] = Py_NewRef(self->c_array[i]); } - Py_INCREF(key); - new_node->c_array[i] = key; - Py_INCREF(val); - new_node->c_array[i + 1] = val; + new_node->c_array[i] = Py_NewRef(key); + new_node->c_array[i + 1] = Py_NewRef(val); *added_leaf = 1; return (PyHamtNode *)new_node; @@ -1368,8 +1337,7 @@ hamt_node_collision_assoc(PyHamtNode_Collision *self, if (self->c_array[val_idx] == val) { /* We're setting a key/value pair that's already set. */ - Py_INCREF(self); - return (PyHamtNode *)self; + return (PyHamtNode *)Py_NewRef(self); } /* We need to replace old value for the key @@ -1382,14 +1350,11 @@ hamt_node_collision_assoc(PyHamtNode_Collision *self, /* Copy all elements of the old node to the new one. */ for (i = 0; i < Py_SIZE(self); i++) { - Py_INCREF(self->c_array[i]); - new_node->c_array[i] = self->c_array[i]; + new_node->c_array[i] = Py_NewRef(self->c_array[i]); } /* Replace the old value with the new value for the our key. */ - Py_DECREF(new_node->c_array[val_idx]); - Py_INCREF(val); - new_node->c_array[val_idx] = val; + Py_SETREF(new_node->c_array[val_idx], Py_NewRef(val)); return (PyHamtNode *)new_node; @@ -1414,8 +1379,7 @@ hamt_node_collision_assoc(PyHamtNode_Collision *self, return NULL; } new_node->b_bitmap = hamt_bitpos(self->c_hash, shift); - Py_INCREF(self); - new_node->b_array[1] = (PyObject*) self; + new_node->b_array[1] = Py_NewRef(self); assoc_res = hamt_node_bitmap_assoc( new_node, shift, hash, key, val, added_leaf); @@ -1477,17 +1441,13 @@ hamt_node_collision_without(PyHamtNode_Collision *self, } if (key_idx == 0) { - Py_INCREF(self->c_array[2]); - node->b_array[0] = self->c_array[2]; - Py_INCREF(self->c_array[3]); - node->b_array[1] = self->c_array[3]; + node->b_array[0] = Py_NewRef(self->c_array[2]); + node->b_array[1] = Py_NewRef(self->c_array[3]); } else { assert(key_idx == 2); - Py_INCREF(self->c_array[0]); - node->b_array[0] = self->c_array[0]; - Py_INCREF(self->c_array[1]); - node->b_array[1] = self->c_array[1]; + node->b_array[0] = Py_NewRef(self->c_array[0]); + node->b_array[1] = Py_NewRef(self->c_array[1]); } node->b_bitmap = hamt_bitpos(hash, shift); @@ -1508,12 +1468,10 @@ hamt_node_collision_without(PyHamtNode_Collision *self, /* Copy all other keys from `self` to `new` */ Py_ssize_t i; for (i = 0; i < key_idx; i++) { - Py_INCREF(self->c_array[i]); - new->c_array[i] = self->c_array[i]; + new->c_array[i] = Py_NewRef(self->c_array[i]); } for (i = key_idx + 2; i < Py_SIZE(self); i++) { - Py_INCREF(self->c_array[i]); - new->c_array[i - 2] = self->c_array[i]; + new->c_array[i - 2] = Py_NewRef(self->c_array[i]); } *new_node = (PyHamtNode*)new; @@ -1665,8 +1623,7 @@ hamt_node_array_clone(PyHamtNode_Array *node) /* Copy all elements from the current Array node to the new one. */ for (i = 0; i < HAMT_ARRAY_NODE_SIZE; i++) { - Py_XINCREF(node->a_array[i]); - clone->a_array[i] = node->a_array[i]; + clone->a_array[i] = (PyHamtNode*)Py_XNewRef(node->a_array[i]); } VALIDATE_ARRAY_NODE(clone) @@ -1723,8 +1680,7 @@ hamt_node_array_assoc(PyHamtNode_Array *self, /* Copy all elements from the current Array node to the new one. */ for (i = 0; i < HAMT_ARRAY_NODE_SIZE; i++) { - Py_XINCREF(self->a_array[i]); - new_node->a_array[i] = self->a_array[i]; + new_node->a_array[i] = (PyHamtNode*)Py_XNewRef(self->a_array[i]); } assert(new_node->a_array[idx] == NULL); @@ -1872,15 +1828,12 @@ hamt_node_array_without(PyHamtNode_Array *self, PyObject *key = child->b_array[0]; PyObject *val = child->b_array[1]; - Py_INCREF(key); - new->b_array[new_i] = key; - Py_INCREF(val); - new->b_array[new_i + 1] = val; + new->b_array[new_i] = Py_NewRef(key); + new->b_array[new_i + 1] = Py_NewRef(val); } else { new->b_array[new_i] = NULL; - Py_INCREF(node); - new->b_array[new_i + 1] = (PyObject*)node; + new->b_array[new_i + 1] = Py_NewRef(node); } } else { @@ -1898,8 +1851,7 @@ hamt_node_array_without(PyHamtNode_Array *self, /* Just copy the node into our new Bitmap */ new->b_array[new_i] = NULL; - Py_INCREF(node); - new->b_array[new_i + 1] = (PyObject*)node; + new->b_array[new_i + 1] = Py_NewRef(node); } new_i += 2; @@ -2315,8 +2267,7 @@ _PyHamt_Assoc(PyHamtObject *o, PyObject *key, PyObject *val) if (new_root == o->h_root) { Py_DECREF(new_root); - Py_INCREF(o); - return o; + return (PyHamtObject*)Py_NewRef(o); } new_o = hamt_alloc(); @@ -2352,8 +2303,7 @@ _PyHamt_Without(PyHamtObject *o, PyObject *key) case W_EMPTY: return _PyHamt_New(); case W_NOT_FOUND: - Py_INCREF(o); - return o; + return (PyHamtObject*)Py_NewRef(o); case W_NEWNODE: { assert(new_root != NULL); @@ -2474,35 +2424,15 @@ hamt_alloc(void) return o; } +#define _empty_hamt \ + (&_Py_INTERP_SINGLETON(_PyInterpreterState_Get(), hamt_empty)) + PyHamtObject * _PyHamt_New(void) { - if (_empty_hamt != NULL) { - /* HAMT is an immutable object so we can easily cache an - empty instance. */ - Py_INCREF(_empty_hamt); - return _empty_hamt; - } - - PyHamtObject *o = hamt_alloc(); - if (o == NULL) { - return NULL; - } - - o->h_root = hamt_node_bitmap_new(0); - if (o->h_root == NULL) { - Py_DECREF(o); - return NULL; - } - - o->h_count = 0; - - if (_empty_hamt == NULL) { - Py_INCREF(o); - _empty_hamt = o; - } - - return o; + /* HAMT is an immutable object so we can easily cache an + empty instance. */ + return (PyHamtObject*)Py_NewRef(_empty_hamt); } #ifdef Py_DEBUG @@ -2595,8 +2525,7 @@ hamt_baseiter_new(PyTypeObject *type, binaryfunc yield, PyHamtObject *o) return NULL; } - Py_INCREF(o); - it->hi_obj = o; + it->hi_obj = (PyHamtObject*)Py_NewRef(o); it->hi_yield = yield; hamt_iterator_init(&it->hi_iter, o->h_root); @@ -2652,8 +2581,7 @@ PyTypeObject _PyHamtKeys_Type = { static PyObject * hamt_iter_yield_keys(PyObject *key, PyObject *val) { - Py_INCREF(key); - return key; + return Py_NewRef(key); } PyObject * @@ -2676,8 +2604,7 @@ PyTypeObject _PyHamtValues_Type = { static PyObject * hamt_iter_yield_values(PyObject *key, PyObject *val) { - Py_INCREF(val); - return val; + return Py_NewRef(val); } PyObject * @@ -2721,6 +2648,15 @@ hamt_tp_traverse(PyHamtObject *self, visitproc visit, void *arg) static void hamt_tp_dealloc(PyHamtObject *self) { + if (self == _empty_hamt) { + /* The empty one is statically allocated. */ +#ifdef Py_DEBUG + _Py_FatalRefcountError("deallocating the empty hamt singleton"); +#else + return; +#endif + } + PyObject_GC_UnTrack(self); if (self->h_weakreflist != NULL) { PyObject_ClearWeakRefs((PyObject*)self); @@ -2770,8 +2706,7 @@ hamt_tp_subscript(PyHamtObject *self, PyObject *key) case F_ERROR: return NULL; case F_FOUND: - Py_INCREF(val); - return val; + return Py_NewRef(val); case F_NOT_FOUND: PyErr_SetObject(PyExc_KeyError, key); return NULL; @@ -2821,14 +2756,12 @@ hamt_py_get(PyHamtObject *self, PyObject *args) case F_ERROR: return NULL; case F_FOUND: - Py_INCREF(val); - return val; + return Py_NewRef(val); case F_NOT_FOUND: if (def == NULL) { Py_RETURN_NONE; } - Py_INCREF(def); - return def; + return Py_NewRef(def); default: Py_UNREACHABLE(); } @@ -2959,11 +2892,3 @@ PyTypeObject _PyHamt_CollisionNode_Type = { .tp_free = PyObject_GC_Del, .tp_hash = PyObject_HashNotImplemented, }; - - -void -_PyHamt_Fini(PyInterpreterState *interp) -{ - Py_CLEAR(_empty_hamt); - Py_CLEAR(_empty_bitmap_node); -} diff --git a/Python/import.c b/Python/import.c index 07a8b900..3f3f2a2b 100644 --- a/Python/import.c +++ b/Python/import.c @@ -2,10 +2,12 @@ #include "Python.h" +#include "pycore_hashtable.h" // _Py_hashtable_new_full() #include "pycore_import.h" // _PyImport_BootstrapImp() #include "pycore_initconfig.h" // _PyStatus_OK() -#include "pycore_interp.h" // _PyInterpreterState_ClearModules() +#include "pycore_interp.h" // struct _import_runtime_state #include "pycore_namespace.h" // _PyNamespace_Type +#include "pycore_object.h" // _Py_SetImmortal() #include "pycore_pyerrors.h" // _PyErr_SetString() #include "pycore_pyhash.h" // _Py_KeyedHash() #include "pycore_pylifecycle.h" @@ -24,129 +26,121 @@ extern "C" { #endif -/* Forward references */ -static PyObject *import_add_module(PyThreadState *tstate, PyObject *name); -/* See _PyImport_FixupExtensionObject() below */ -static PyObject *extensions = NULL; +/*[clinic input] +module _imp +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=9c332475d8686284]*/ + +#include "clinic/import.c.h" + + +/*******************************/ +/* process-global import state */ +/*******************************/ /* This table is defined in config.c: */ extern struct _inittab _PyImport_Inittab[]; +// This is not used after Py_Initialize() is called. +// (See _PyRuntimeState.imports.inittab.) struct _inittab *PyImport_Inittab = _PyImport_Inittab; +// When we dynamically allocate a larger table for PyImport_ExtendInittab(), +// we track the pointer here so we can deallocate it during finalization. static struct _inittab *inittab_copy = NULL; -/*[clinic input] -module _imp -[clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=9c332475d8686284]*/ -#include "clinic/import.c.h" +/*******************************/ +/* runtime-global import state */ +/*******************************/ -/* Initialize things */ +#define INITTAB _PyRuntime.imports.inittab +#define LAST_MODULE_INDEX _PyRuntime.imports.last_module_index +#define EXTENSIONS _PyRuntime.imports.extensions -PyStatus -_PyImportZip_Init(PyThreadState *tstate) -{ - PyObject *path_hooks, *zipimport; - int err = 0; +#define PKGCONTEXT (_PyRuntime.imports.pkgcontext) - path_hooks = PySys_GetObject("path_hooks"); - if (path_hooks == NULL) { - _PyErr_SetString(tstate, PyExc_RuntimeError, - "unable to get sys.path_hooks"); - goto error; - } - int verbose = _PyInterpreterState_GetConfig(tstate->interp)->verbose; - if (verbose) { - PySys_WriteStderr("# installing zipimport hook\n"); - } +/*******************************/ +/* interpreter import state */ +/*******************************/ - zipimport = PyImport_ImportModule("zipimport"); - if (zipimport == NULL) { - _PyErr_Clear(tstate); /* No zip import module -- okay */ - if (verbose) { - PySys_WriteStderr("# can't import zipimport\n"); - } - } - else { - PyObject *zipimporter = PyObject_GetAttr(zipimport, &_Py_ID(zipimporter)); - Py_DECREF(zipimport); - if (zipimporter == NULL) { - _PyErr_Clear(tstate); /* No zipimporter object -- okay */ - if (verbose) { - PySys_WriteStderr("# can't import zipimport.zipimporter\n"); - } - } - else { - /* sys.path_hooks.insert(0, zipimporter) */ - err = PyList_Insert(path_hooks, 0, zipimporter); - Py_DECREF(zipimporter); - if (err < 0) { - goto error; - } - if (verbose) { - PySys_WriteStderr("# installed zipimport hook\n"); - } - } - } +#define MODULES(interp) \ + (interp)->imports.modules +#define MODULES_BY_INDEX(interp) \ + (interp)->imports.modules_by_index +#define IMPORTLIB(interp) \ + (interp)->imports.importlib +#define OVERRIDE_MULTI_INTERP_EXTENSIONS_CHECK(interp) \ + (interp)->imports.override_multi_interp_extensions_check +#define OVERRIDE_FROZEN_MODULES(interp) \ + (interp)->imports.override_frozen_modules +#ifdef HAVE_DLOPEN +# define DLOPENFLAGS(interp) \ + (interp)->imports.dlopenflags +#endif +#define IMPORT_FUNC(interp) \ + (interp)->imports.import_func - return _PyStatus_OK(); +#define IMPORT_LOCK(interp) \ + (interp)->imports.lock.mutex +#define IMPORT_LOCK_THREAD(interp) \ + (interp)->imports.lock.thread +#define IMPORT_LOCK_LEVEL(interp) \ + (interp)->imports.lock.level - error: - PyErr_Print(); - return _PyStatus_ERR("initializing zipimport failed"); -} +#define FIND_AND_LOAD(interp) \ + (interp)->imports.find_and_load + + +/*******************/ +/* the import lock */ +/*******************/ /* Locking primitives to prevent parallel imports of the same module in different threads to return with a partially loaded module. These calls are serialized by the global interpreter lock. */ -static PyThread_type_lock import_lock = NULL; -static unsigned long import_lock_thread = PYTHREAD_INVALID_THREAD_ID; -static int import_lock_level = 0; - void -_PyImport_AcquireLock(void) +_PyImport_AcquireLock(PyInterpreterState *interp) { unsigned long me = PyThread_get_thread_ident(); if (me == PYTHREAD_INVALID_THREAD_ID) return; /* Too bad */ - if (import_lock == NULL) { - import_lock = PyThread_allocate_lock(); - if (import_lock == NULL) + if (IMPORT_LOCK(interp) == NULL) { + IMPORT_LOCK(interp) = PyThread_allocate_lock(); + if (IMPORT_LOCK(interp) == NULL) return; /* Nothing much we can do. */ } - if (import_lock_thread == me) { - import_lock_level++; + if (IMPORT_LOCK_THREAD(interp) == me) { + IMPORT_LOCK_LEVEL(interp)++; return; } - if (import_lock_thread != PYTHREAD_INVALID_THREAD_ID || - !PyThread_acquire_lock(import_lock, 0)) + if (IMPORT_LOCK_THREAD(interp) != PYTHREAD_INVALID_THREAD_ID || + !PyThread_acquire_lock(IMPORT_LOCK(interp), 0)) { PyThreadState *tstate = PyEval_SaveThread(); - PyThread_acquire_lock(import_lock, WAIT_LOCK); + PyThread_acquire_lock(IMPORT_LOCK(interp), WAIT_LOCK); PyEval_RestoreThread(tstate); } - assert(import_lock_level == 0); - import_lock_thread = me; - import_lock_level = 1; + assert(IMPORT_LOCK_LEVEL(interp) == 0); + IMPORT_LOCK_THREAD(interp) = me; + IMPORT_LOCK_LEVEL(interp) = 1; } int -_PyImport_ReleaseLock(void) +_PyImport_ReleaseLock(PyInterpreterState *interp) { unsigned long me = PyThread_get_thread_ident(); - if (me == PYTHREAD_INVALID_THREAD_ID || import_lock == NULL) + if (me == PYTHREAD_INVALID_THREAD_ID || IMPORT_LOCK(interp) == NULL) return 0; /* Too bad */ - if (import_lock_thread != me) + if (IMPORT_LOCK_THREAD(interp) != me) return -1; - import_lock_level--; - assert(import_lock_level >= 0); - if (import_lock_level == 0) { - import_lock_thread = PYTHREAD_INVALID_THREAD_ID; - PyThread_release_lock(import_lock); + IMPORT_LOCK_LEVEL(interp)--; + assert(IMPORT_LOCK_LEVEL(interp) >= 0); + if (IMPORT_LOCK_LEVEL(interp) == 0) { + IMPORT_LOCK_THREAD(interp) = PYTHREAD_INVALID_THREAD_ID; + PyThread_release_lock(IMPORT_LOCK(interp)); } return 1; } @@ -157,131 +151,67 @@ _PyImport_ReleaseLock(void) We now acquire the import lock around fork() calls but on some platforms (Solaris 9 and earlier? see isue7242) that still left us with problems. */ PyStatus -_PyImport_ReInitLock(void) +_PyImport_ReInitLock(PyInterpreterState *interp) { - if (import_lock != NULL) { - if (_PyThread_at_fork_reinit(&import_lock) < 0) { + if (IMPORT_LOCK(interp) != NULL) { + if (_PyThread_at_fork_reinit(&IMPORT_LOCK(interp)) < 0) { return _PyStatus_ERR("failed to create a new lock"); } } - if (import_lock_level > 1) { + if (IMPORT_LOCK_LEVEL(interp) > 1) { /* Forked as a side effect of import */ unsigned long me = PyThread_get_thread_ident(); - PyThread_acquire_lock(import_lock, WAIT_LOCK); - import_lock_thread = me; - import_lock_level--; + PyThread_acquire_lock(IMPORT_LOCK(interp), WAIT_LOCK); + IMPORT_LOCK_THREAD(interp) = me; + IMPORT_LOCK_LEVEL(interp)--; } else { - import_lock_thread = PYTHREAD_INVALID_THREAD_ID; - import_lock_level = 0; + IMPORT_LOCK_THREAD(interp) = PYTHREAD_INVALID_THREAD_ID; + IMPORT_LOCK_LEVEL(interp) = 0; } return _PyStatus_OK(); } #endif -/*[clinic input] -_imp.lock_held - -Return True if the import lock is currently held, else False. - -On platforms without threads, return False. -[clinic start generated code]*/ - -static PyObject * -_imp_lock_held_impl(PyObject *module) -/*[clinic end generated code: output=8b89384b5e1963fc input=9b088f9b217d9bdf]*/ -{ - return PyBool_FromLong(import_lock_thread != PYTHREAD_INVALID_THREAD_ID); -} - -/*[clinic input] -_imp.acquire_lock - -Acquires the interpreter's import lock for the current thread. - -This lock should be used by import hooks to ensure thread-safety when importing -modules. On platforms without threads, this function does nothing. -[clinic start generated code]*/ - -static PyObject * -_imp_acquire_lock_impl(PyObject *module) -/*[clinic end generated code: output=1aff58cb0ee1b026 input=4a2d4381866d5fdc]*/ -{ - _PyImport_AcquireLock(); - Py_RETURN_NONE; -} - -/*[clinic input] -_imp.release_lock - -Release the interpreter's import lock. -On platforms without threads, this function does nothing. -[clinic start generated code]*/ +/***************/ +/* sys.modules */ +/***************/ -static PyObject * -_imp_release_lock_impl(PyObject *module) -/*[clinic end generated code: output=7faab6d0be178b0a input=934fb11516dd778b]*/ +PyObject * +_PyImport_InitModules(PyInterpreterState *interp) { - if (_PyImport_ReleaseLock() < 0) { - PyErr_SetString(PyExc_RuntimeError, - "not holding the import lock"); + assert(MODULES(interp) == NULL); + MODULES(interp) = PyDict_New(); + if (MODULES(interp) == NULL) { return NULL; } - Py_RETURN_NONE; + return MODULES(interp); } -void -_PyImport_Fini(void) +PyObject * +_PyImport_GetModules(PyInterpreterState *interp) { - Py_CLEAR(extensions); - if (import_lock != NULL) { - PyThread_free_lock(import_lock); - import_lock = NULL; - } + return MODULES(interp); } void -_PyImport_Fini2(void) +_PyImport_ClearModules(PyInterpreterState *interp) { - /* Use the same memory allocator than PyImport_ExtendInittab(). */ - PyMemAllocatorEx old_alloc; - _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - - // Reset PyImport_Inittab - PyImport_Inittab = _PyImport_Inittab; - - /* Free memory allocated by PyImport_ExtendInittab() */ - PyMem_RawFree(inittab_copy); - inittab_copy = NULL; - - PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); + Py_SETREF(MODULES(interp), NULL); } -/* Helper for sys */ - PyObject * PyImport_GetModuleDict(void) { PyInterpreterState *interp = _PyInterpreterState_GET(); - if (interp->modules == NULL) { + if (MODULES(interp) == NULL) { Py_FatalError("interpreter has no modules dictionary"); } - return interp->modules; -} - -/* In some corner cases it is important to be sure that the import - machinery has been initialized (or not cleaned up yet). For - example, see issue #4236 and PyModule_Create2(). */ - -int -_PyImport_IsInitialized(PyInterpreterState *interp) -{ - if (interp->modules == NULL) - return 0; - return 1; + return MODULES(interp); } +// This is only kept around for extensions that use _Py_IDENTIFIER. PyObject * _PyImport_GetModuleId(_Py_Identifier *nameid) { @@ -296,7 +226,7 @@ int _PyImport_SetModule(PyObject *name, PyObject *m) { PyInterpreterState *interp = _PyInterpreterState_GET(); - PyObject *modules = interp->modules; + PyObject *modules = MODULES(interp); return PyObject_SetItem(modules, name, m); } @@ -304,14 +234,14 @@ int _PyImport_SetModuleString(const char *name, PyObject *m) { PyInterpreterState *interp = _PyInterpreterState_GET(); - PyObject *modules = interp->modules; + PyObject *modules = MODULES(interp); return PyMapping_SetItemString(modules, name, m); } static PyObject * import_get_module(PyThreadState *tstate, PyObject *name) { - PyObject *modules = tstate->interp->modules; + PyObject *modules = MODULES(tstate->interp); if (modules == NULL) { _PyErr_SetString(tstate, PyExc_RuntimeError, "unable to get sys.modules"); @@ -334,7 +264,6 @@ import_get_module(PyThreadState *tstate, PyObject *name) return m; } - static int import_ensure_initialized(PyInterpreterState *interp, PyObject *mod, PyObject *name) { @@ -351,7 +280,7 @@ import_ensure_initialized(PyInterpreterState *interp, PyObject *mod, PyObject *n if (busy) { /* Wait until module is done importing. */ PyObject *value = _PyObject_CallMethodOneArg( - interp->importlib, &_Py_ID(_lock_unlock_module), name); + IMPORTLIB(interp), &_Py_ID(_lock_unlock_module), name); if (value == NULL) { return -1; } @@ -360,224 +289,52 @@ import_ensure_initialized(PyInterpreterState *interp, PyObject *mod, PyObject *n return 0; } +static void remove_importlib_frames(PyThreadState *tstate); -/* Helper for pythonrun.c -- return magic number and tag. */ - -long -PyImport_GetMagicNumber(void) -{ - long res; - PyInterpreterState *interp = _PyInterpreterState_GET(); - PyObject *external, *pyc_magic; - - external = PyObject_GetAttrString(interp->importlib, "_bootstrap_external"); - if (external == NULL) - return -1; - pyc_magic = PyObject_GetAttrString(external, "_RAW_MAGIC_NUMBER"); - Py_DECREF(external); - if (pyc_magic == NULL) - return -1; - res = PyLong_AsLong(pyc_magic); - Py_DECREF(pyc_magic); - return res; -} - - -extern const char * _PySys_ImplCacheTag; - -const char * -PyImport_GetMagicTag(void) -{ - return _PySys_ImplCacheTag; -} - - -/* Magic for extension modules (built-in as well as dynamically - loaded). To prevent initializing an extension module more than - once, we keep a static dictionary 'extensions' keyed by the tuple - (module name, module name) (for built-in modules) or by - (filename, module name) (for dynamically loaded modules), containing these - modules. A copy of the module's dictionary is stored by calling - _PyImport_FixupExtensionObject() immediately after the module initialization - function succeeds. A copy can be retrieved from there by calling - import_find_extension(). - - Modules which do support multiple initialization set their m_size - field to a non-negative number (indicating the size of the - module-specific state). They are still recorded in the extensions - dictionary, to avoid loading shared libraries twice. -*/ - -int -_PyImport_FixupExtensionObject(PyObject *mod, PyObject *name, - PyObject *filename, PyObject *modules) +PyObject * +PyImport_GetModule(PyObject *name) { - if (mod == NULL || !PyModule_Check(mod)) { - PyErr_BadInternalCall(); - return -1; - } - - struct PyModuleDef *def = PyModule_GetDef(mod); - if (!def) { - PyErr_BadInternalCall(); - return -1; - } - PyThreadState *tstate = _PyThreadState_GET(); - if (PyObject_SetItem(modules, name, mod) < 0) { - return -1; - } - if (_PyState_AddModule(tstate, mod, def) < 0) { - PyMapping_DelItem(modules, name); - return -1; - } - - // bpo-44050: Extensions and def->m_base.m_copy can be updated - // when the extension module doesn't support sub-interpreters. - if (_Py_IsMainInterpreter(tstate->interp) || def->m_size == -1) { - if (def->m_size == -1) { - if (def->m_base.m_copy) { - /* Somebody already imported the module, - likely under a different name. - XXX this should really not happen. */ - Py_CLEAR(def->m_base.m_copy); - } - PyObject *dict = PyModule_GetDict(mod); - if (dict == NULL) { - return -1; - } - def->m_base.m_copy = PyDict_Copy(dict); - if (def->m_base.m_copy == NULL) { - return -1; - } - } - - if (extensions == NULL) { - extensions = PyDict_New(); - if (extensions == NULL) { - return -1; - } - } + PyObject *mod; - PyObject *key = PyTuple_Pack(2, filename, name); - if (key == NULL) { - return -1; - } - int res = PyDict_SetItem(extensions, key, (PyObject *)def); - Py_DECREF(key); - if (res < 0) { - return -1; + mod = import_get_module(tstate, name); + if (mod != NULL && mod != Py_None) { + if (import_ensure_initialized(tstate->interp, mod, name) < 0) { + Py_DECREF(mod); + remove_importlib_frames(tstate); + return NULL; } } - - return 0; + return mod; } -int -_PyImport_FixupBuiltin(PyObject *mod, const char *name, PyObject *modules) -{ - int res; - PyObject *nameobj; - nameobj = PyUnicode_InternFromString(name); - if (nameobj == NULL) - return -1; - res = _PyImport_FixupExtensionObject(mod, nameobj, nameobj, modules); - Py_DECREF(nameobj); - return res; -} +/* Get the module object corresponding to a module name. + First check the modules dictionary if there's one there, + if not, create a new one and insert it in the modules dictionary. */ static PyObject * -import_find_extension(PyThreadState *tstate, PyObject *name, - PyObject *filename) +import_add_module(PyThreadState *tstate, PyObject *name) { - if (extensions == NULL) { + PyObject *modules = MODULES(tstate->interp); + if (modules == NULL) { + _PyErr_SetString(tstate, PyExc_RuntimeError, + "no import module dictionary"); return NULL; } - PyObject *key = PyTuple_Pack(2, filename, name); - if (key == NULL) { - return NULL; + PyObject *m; + if (PyDict_CheckExact(modules)) { + m = Py_XNewRef(PyDict_GetItemWithError(modules, name)); } - PyModuleDef* def = (PyModuleDef *)PyDict_GetItemWithError(extensions, key); - Py_DECREF(key); - if (def == NULL) { - return NULL; - } - - PyObject *mod, *mdict; - PyObject *modules = tstate->interp->modules; - - if (def->m_size == -1) { - /* Module does not support repeated initialization */ - if (def->m_base.m_copy == NULL) - return NULL; - mod = import_add_module(tstate, name); - if (mod == NULL) - return NULL; - mdict = PyModule_GetDict(mod); - if (mdict == NULL) { - Py_DECREF(mod); - return NULL; - } - if (PyDict_Update(mdict, def->m_base.m_copy)) { - Py_DECREF(mod); - return NULL; - } - } - else { - if (def->m_base.m_init == NULL) - return NULL; - mod = _PyImport_InitFunc_TrampolineCall(def->m_base.m_init); - if (mod == NULL) - return NULL; - if (PyObject_SetItem(modules, name, mod) == -1) { - Py_DECREF(mod); - return NULL; - } - } - if (_PyState_AddModule(tstate, mod, def) < 0) { - PyMapping_DelItem(modules, name); - Py_DECREF(mod); - return NULL; - } - - int verbose = _PyInterpreterState_GetConfig(tstate->interp)->verbose; - if (verbose) { - PySys_FormatStderr("import %U # previously loaded (%R)\n", - name, filename); - } - return mod; -} - - -/* Get the module object corresponding to a module name. - First check the modules dictionary if there's one there, - if not, create a new one and insert it in the modules dictionary. */ - -static PyObject * -import_add_module(PyThreadState *tstate, PyObject *name) -{ - PyObject *modules = tstate->interp->modules; - if (modules == NULL) { - _PyErr_SetString(tstate, PyExc_RuntimeError, - "no import module dictionary"); - return NULL; - } - - PyObject *m; - if (PyDict_CheckExact(modules)) { - m = PyDict_GetItemWithError(modules, name); - Py_XINCREF(m); - } - else { - m = PyObject_GetItem(modules, name); - // For backward-compatibility we copy the behavior - // of PyDict_GetItemWithError(). - if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { - _PyErr_Clear(tstate); - } - } - if (_PyErr_Occurred(tstate)) { + else { + m = PyObject_GetItem(modules, name); + // For backward-compatibility we copy the behavior + // of PyDict_GetItemWithError(). + if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { + _PyErr_Clear(tstate); + } + } + if (_PyErr_Occurred(tstate)) { return NULL; } if (m != NULL && PyModule_Check(m)) { @@ -634,10 +391,9 @@ PyImport_AddModule(const char *name) static void remove_module(PyThreadState *tstate, PyObject *name) { - PyObject *type, *value, *traceback; - _PyErr_Fetch(tstate, &type, &value, &traceback); + PyObject *exc = _PyErr_GetRaisedException(tstate); - PyObject *modules = tstate->interp->modules; + PyObject *modules = MODULES(tstate->interp); if (PyDict_CheckExact(modules)) { PyObject *mod = _PyDict_Pop(modules, name, Py_None); Py_XDECREF(mod); @@ -648,407 +404,1412 @@ remove_module(PyThreadState *tstate, PyObject *name) } } - _PyErr_ChainExceptions(type, value, traceback); + _PyErr_ChainExceptions1(exc); } -/* Execute a code object in a module and return the module object - * WITH INCREMENTED REFERENCE COUNT. If an error occurs, name is - * removed from sys.modules, to avoid leaving damaged module objects - * in sys.modules. The caller may wish to restore the original - * module object (if any) in this case; PyImport_ReloadModule is an - * example. - * - * Note that PyImport_ExecCodeModuleWithPathnames() is the preferred, richer - * interface. The other two exist primarily for backward compatibility. - */ -PyObject * -PyImport_ExecCodeModule(const char *name, PyObject *co) +/************************************/ +/* per-interpreter modules-by-index */ +/************************************/ + +Py_ssize_t +_PyImport_GetNextModuleIndex(void) { - return PyImport_ExecCodeModuleWithPathnames( - name, co, (char *)NULL, (char *)NULL); + PyThread_acquire_lock(EXTENSIONS.mutex, WAIT_LOCK); + LAST_MODULE_INDEX++; + Py_ssize_t index = LAST_MODULE_INDEX; + PyThread_release_lock(EXTENSIONS.mutex); + return index; } -PyObject * -PyImport_ExecCodeModuleEx(const char *name, PyObject *co, const char *pathname) +static const char * +_modules_by_index_check(PyInterpreterState *interp, Py_ssize_t index) { - return PyImport_ExecCodeModuleWithPathnames( - name, co, pathname, (char *)NULL); + if (index == 0) { + return "invalid module index"; + } + if (MODULES_BY_INDEX(interp) == NULL) { + return "Interpreters module-list not accessible."; + } + if (index > PyList_GET_SIZE(MODULES_BY_INDEX(interp))) { + return "Module index out of bounds."; + } + return NULL; } -PyObject * -PyImport_ExecCodeModuleWithPathnames(const char *name, PyObject *co, - const char *pathname, - const char *cpathname) +static PyObject * +_modules_by_index_get(PyInterpreterState *interp, PyModuleDef *def) { - PyObject *m = NULL; - PyObject *nameobj, *pathobj = NULL, *cpathobj = NULL, *external= NULL; - - nameobj = PyUnicode_FromString(name); - if (nameobj == NULL) + Py_ssize_t index = def->m_base.m_index; + if (_modules_by_index_check(interp, index) != NULL) { return NULL; - - if (cpathname != NULL) { - cpathobj = PyUnicode_DecodeFSDefault(cpathname); - if (cpathobj == NULL) - goto error; } - else - cpathobj = NULL; + PyObject *res = PyList_GET_ITEM(MODULES_BY_INDEX(interp), index); + return res==Py_None ? NULL : res; +} - if (pathname != NULL) { - pathobj = PyUnicode_DecodeFSDefault(pathname); - if (pathobj == NULL) - goto error; - } - else if (cpathobj != NULL) { - PyInterpreterState *interp = _PyInterpreterState_GET(); +static int +_modules_by_index_set(PyInterpreterState *interp, + PyModuleDef *def, PyObject *module) +{ + assert(def != NULL); + assert(def->m_slots == NULL); + assert(def->m_base.m_index > 0); - if (interp == NULL) { - Py_FatalError("no current interpreter"); + if (MODULES_BY_INDEX(interp) == NULL) { + MODULES_BY_INDEX(interp) = PyList_New(0); + if (MODULES_BY_INDEX(interp) == NULL) { + return -1; } + } - external= PyObject_GetAttrString(interp->importlib, - "_bootstrap_external"); - if (external != NULL) { - pathobj = _PyObject_CallMethodOneArg( - external, &_Py_ID(_get_sourcefile), cpathobj); - Py_DECREF(external); + Py_ssize_t index = def->m_base.m_index; + while (PyList_GET_SIZE(MODULES_BY_INDEX(interp)) <= index) { + if (PyList_Append(MODULES_BY_INDEX(interp), Py_None) < 0) { + return -1; } - if (pathobj == NULL) - PyErr_Clear(); } - else - pathobj = NULL; - m = PyImport_ExecCodeModuleObject(nameobj, co, pathobj, cpathobj); -error: - Py_DECREF(nameobj); - Py_XDECREF(pathobj); - Py_XDECREF(cpathobj); - return m; + return PyList_SetItem(MODULES_BY_INDEX(interp), index, Py_NewRef(module)); } -static PyObject * -module_dict_for_exec(PyThreadState *tstate, PyObject *name) +static int +_modules_by_index_clear_one(PyInterpreterState *interp, PyModuleDef *def) { - PyObject *m, *d; - - m = import_add_module(tstate, name); - if (m == NULL) - return NULL; - /* If the module is being reloaded, we get the old module back - and re-use its dict to exec the new code. */ - d = PyModule_GetDict(m); - int r = PyDict_Contains(d, &_Py_ID(__builtins__)); - if (r == 0) { - r = PyDict_SetItem(d, &_Py_ID(__builtins__), PyEval_GetBuiltins()); + Py_ssize_t index = def->m_base.m_index; + const char *err = _modules_by_index_check(interp, index); + if (err != NULL) { + Py_FatalError(err); + return -1; } - if (r < 0) { - remove_module(tstate, name); - Py_DECREF(m); + return PyList_SetItem(MODULES_BY_INDEX(interp), index, Py_NewRef(Py_None)); +} + + +PyObject* +PyState_FindModule(PyModuleDef* module) +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + if (module->m_slots) { return NULL; } + return _modules_by_index_get(interp, module); +} - Py_INCREF(d); - Py_DECREF(m); - return d; +/* _PyState_AddModule() has been completely removed from the C-API + (and was removed from the limited API in 3.6). However, we're + playing it safe and keeping it around for any stable ABI extensions + built against 3.2-3.5. */ +int +_PyState_AddModule(PyThreadState *tstate, PyObject* module, PyModuleDef* def) +{ + if (!def) { + assert(_PyErr_Occurred(tstate)); + return -1; + } + if (def->m_slots) { + _PyErr_SetString(tstate, + PyExc_SystemError, + "PyState_AddModule called on module with slots"); + return -1; + } + return _modules_by_index_set(tstate->interp, def, module); } -static PyObject * -exec_code_in_module(PyThreadState *tstate, PyObject *name, - PyObject *module_dict, PyObject *code_object) +int +PyState_AddModule(PyObject* module, PyModuleDef* def) { - PyObject *v, *m; + if (!def) { + Py_FatalError("module definition is NULL"); + return -1; + } - v = PyEval_EvalCode(code_object, module_dict, module_dict); - if (v == NULL) { - remove_module(tstate, name); - return NULL; + PyThreadState *tstate = _PyThreadState_GET(); + if (def->m_slots) { + _PyErr_SetString(tstate, + PyExc_SystemError, + "PyState_AddModule called on module with slots"); + return -1; } - Py_DECREF(v); - m = import_get_module(tstate, name); - if (m == NULL && !_PyErr_Occurred(tstate)) { - _PyErr_Format(tstate, PyExc_ImportError, - "Loaded module %R not found in sys.modules", - name); + PyInterpreterState *interp = tstate->interp; + Py_ssize_t index = def->m_base.m_index; + if (MODULES_BY_INDEX(interp) && + index < PyList_GET_SIZE(MODULES_BY_INDEX(interp)) && + module == PyList_GET_ITEM(MODULES_BY_INDEX(interp), index)) + { + _Py_FatalErrorFormat(__func__, "module %p already added", module); + return -1; } - return m; + return _modules_by_index_set(interp, def, module); } -PyObject* -PyImport_ExecCodeModuleObject(PyObject *name, PyObject *co, PyObject *pathname, - PyObject *cpathname) +int +PyState_RemoveModule(PyModuleDef* def) { PyThreadState *tstate = _PyThreadState_GET(); - PyObject *d, *external, *res; - - d = module_dict_for_exec(tstate, name); - if (d == NULL) { - return NULL; + if (def->m_slots) { + _PyErr_SetString(tstate, + PyExc_SystemError, + "PyState_RemoveModule called on module with slots"); + return -1; } + return _modules_by_index_clear_one(tstate->interp, def); +} - if (pathname == NULL) { - pathname = ((PyCodeObject *)co)->co_filename; - } - external = PyObject_GetAttrString(tstate->interp->importlib, - "_bootstrap_external"); - if (external == NULL) { - Py_DECREF(d); - return NULL; + +// Used by finalize_modules() +void +_PyImport_ClearModulesByIndex(PyInterpreterState *interp) +{ + if (!MODULES_BY_INDEX(interp)) { + return; } - res = PyObject_CallMethodObjArgs(external, &_Py_ID(_fix_up_module), - d, name, pathname, cpathname, NULL); - Py_DECREF(external); - if (res != NULL) { - Py_DECREF(res); - res = exec_code_in_module(tstate, name, d, co); + + Py_ssize_t i; + for (i = 0; i < PyList_GET_SIZE(MODULES_BY_INDEX(interp)); i++) { + PyObject *m = PyList_GET_ITEM(MODULES_BY_INDEX(interp), i); + if (PyModule_Check(m)) { + /* cleanup the saved copy of module dicts */ + PyModuleDef *md = PyModule_GetDef(m); + if (md) { + Py_CLEAR(md->m_base.m_copy); + } + } } - Py_DECREF(d); - return res; -} + /* Setting modules_by_index to NULL could be dangerous, so we + clear the list instead. */ + if (PyList_SetSlice(MODULES_BY_INDEX(interp), + 0, PyList_GET_SIZE(MODULES_BY_INDEX(interp)), + NULL)) { + PyErr_WriteUnraisable(MODULES_BY_INDEX(interp)); + } +} + + +/*********************/ +/* extension modules */ +/*********************/ + +/* + It may help to have a big picture view of what happens + when an extension is loaded. This includes when it is imported + for the first time. + + Here's a summary, using importlib._boostrap._load() as a starting point. + + 1. importlib._bootstrap._load() + 2. _load(): acquire import lock + 3. _load() -> importlib._bootstrap._load_unlocked() + 4. _load_unlocked() -> importlib._bootstrap.module_from_spec() + 5. module_from_spec() -> ExtensionFileLoader.create_module() + 6. create_module() -> _imp.create_dynamic() + (see below) + 7. module_from_spec() -> importlib._bootstrap._init_module_attrs() + 8. _load_unlocked(): sys.modules[name] = module + 9. _load_unlocked() -> ExtensionFileLoader.exec_module() + 10. exec_module() -> _imp.exec_dynamic() + (see below) + 11. _load(): release import lock + + + ...for single-phase init modules, where m_size == -1: + + (6). first time (not found in _PyRuntime.imports.extensions): + 1. _imp_create_dynamic_impl() -> import_find_extension() + 2. _imp_create_dynamic_impl() -> _PyImport_LoadDynamicModuleWithSpec() + 3. _PyImport_LoadDynamicModuleWithSpec(): load <module init func> + 4. _PyImport_LoadDynamicModuleWithSpec(): call <module init func> + 5. <module init func> -> PyModule_Create() -> PyModule_Create2() -> PyModule_CreateInitialized() + 6. PyModule_CreateInitialized() -> PyModule_New() + 7. PyModule_CreateInitialized(): allocate mod->md_state + 8. PyModule_CreateInitialized() -> PyModule_AddFunctions() + 9. PyModule_CreateInitialized() -> PyModule_SetDocString() + 10. PyModule_CreateInitialized(): set mod->md_def + 11. <module init func>: initialize the module + 12. _PyImport_LoadDynamicModuleWithSpec() -> _PyImport_CheckSubinterpIncompatibleExtensionAllowed() + 13. _PyImport_LoadDynamicModuleWithSpec(): set def->m_base.m_init + 14. _PyImport_LoadDynamicModuleWithSpec(): set __file__ + 15. _PyImport_LoadDynamicModuleWithSpec() -> _PyImport_FixupExtensionObject() + 16. _PyImport_FixupExtensionObject(): add it to interp->imports.modules_by_index + 17. _PyImport_FixupExtensionObject(): copy __dict__ into def->m_base.m_copy + 18. _PyImport_FixupExtensionObject(): add it to _PyRuntime.imports.extensions + + (6). subsequent times (found in _PyRuntime.imports.extensions): + 1. _imp_create_dynamic_impl() -> import_find_extension() + 2. import_find_extension() -> import_add_module() + 3. if name in sys.modules: use that module + 4. else: + 1. import_add_module() -> PyModule_NewObject() + 2. import_add_module(): set it on sys.modules + 5. import_find_extension(): copy the "m_copy" dict into __dict__ + 6. _imp_create_dynamic_impl() -> _PyImport_CheckSubinterpIncompatibleExtensionAllowed() + + (10). (every time): + 1. noop + + + ...for single-phase init modules, where m_size >= 0: + + (6). not main interpreter and never loaded there - every time (not found in _PyRuntime.imports.extensions): + 1-16. (same as for m_size == -1) + + (6). main interpreter - first time (not found in _PyRuntime.imports.extensions): + 1-16. (same as for m_size == -1) + 17. _PyImport_FixupExtensionObject(): add it to _PyRuntime.imports.extensions + + (6). previously loaded in main interpreter (found in _PyRuntime.imports.extensions): + 1. _imp_create_dynamic_impl() -> import_find_extension() + 2. import_find_extension(): call def->m_base.m_init + 3. import_find_extension(): add the module to sys.modules + + (10). every time: + 1. noop + + + ...for multi-phase init modules: + + (6). every time: + 1. _imp_create_dynamic_impl() -> import_find_extension() (not found) + 2. _imp_create_dynamic_impl() -> _PyImport_LoadDynamicModuleWithSpec() + 3. _PyImport_LoadDynamicModuleWithSpec(): load module init func + 4. _PyImport_LoadDynamicModuleWithSpec(): call module init func + 5. _PyImport_LoadDynamicModuleWithSpec() -> PyModule_FromDefAndSpec() + 6. PyModule_FromDefAndSpec(): gather/check moduledef slots + 7. if there's a Py_mod_create slot: + 1. PyModule_FromDefAndSpec(): call its function + 8. else: + 1. PyModule_FromDefAndSpec() -> PyModule_NewObject() + 9: PyModule_FromDefAndSpec(): set mod->md_def + 10. PyModule_FromDefAndSpec() -> _add_methods_to_object() + 11. PyModule_FromDefAndSpec() -> PyModule_SetDocString() + + (10). every time: + 1. _imp_exec_dynamic_impl() -> exec_builtin_or_dynamic() + 2. if mod->md_state == NULL (including if m_size == 0): + 1. exec_builtin_or_dynamic() -> PyModule_ExecDef() + 2. PyModule_ExecDef(): allocate mod->md_state + 3. if there's a Py_mod_exec slot: + 1. PyModule_ExecDef(): call its function + */ -static void -update_code_filenames(PyCodeObject *co, PyObject *oldname, PyObject *newname) -{ - PyObject *constants, *tmp; - Py_ssize_t i, n; - if (PyUnicode_Compare(co->co_filename, oldname)) - return; +/* Make sure name is fully qualified. - Py_INCREF(newname); - Py_XSETREF(co->co_filename, newname); + This is a bit of a hack: when the shared library is loaded, + the module name is "package.module", but the module calls + PyModule_Create*() with just "module" for the name. The shared + library loader squirrels away the true name of the module in + _PyRuntime.imports.pkgcontext, and PyModule_Create*() will + substitute this (if the name actually matches). +*/ - constants = co->co_consts; - n = PyTuple_GET_SIZE(constants); - for (i = 0; i < n; i++) { - tmp = PyTuple_GET_ITEM(constants, i); - if (PyCode_Check(tmp)) - update_code_filenames((PyCodeObject *)tmp, - oldname, newname); +#ifdef HAVE_THREAD_LOCAL +_Py_thread_local const char *pkgcontext = NULL; +# undef PKGCONTEXT +# define PKGCONTEXT pkgcontext +#endif + +const char * +_PyImport_ResolveNameWithPackageContext(const char *name) +{ +#ifndef HAVE_THREAD_LOCAL + PyThread_acquire_lock(EXTENSIONS.mutex, WAIT_LOCK); +#endif + if (PKGCONTEXT != NULL) { + const char *p = strrchr(PKGCONTEXT, '.'); + if (p != NULL && strcmp(name, p+1) == 0) { + name = PKGCONTEXT; + PKGCONTEXT = NULL; + } } +#ifndef HAVE_THREAD_LOCAL + PyThread_release_lock(EXTENSIONS.mutex); +#endif + return name; } -static void -update_compiled_module(PyCodeObject *co, PyObject *newname) +const char * +_PyImport_SwapPackageContext(const char *newcontext) { - PyObject *oldname; - - if (PyUnicode_Compare(co->co_filename, newname) == 0) - return; +#ifndef HAVE_THREAD_LOCAL + PyThread_acquire_lock(EXTENSIONS.mutex, WAIT_LOCK); +#endif + const char *oldcontext = PKGCONTEXT; + PKGCONTEXT = newcontext; +#ifndef HAVE_THREAD_LOCAL + PyThread_release_lock(EXTENSIONS.mutex); +#endif + return oldcontext; +} - oldname = co->co_filename; - Py_INCREF(oldname); - update_code_filenames(co, oldname, newname); - Py_DECREF(oldname); +#ifdef HAVE_DLOPEN +int +_PyImport_GetDLOpenFlags(PyInterpreterState *interp) +{ + return DLOPENFLAGS(interp); } -/*[clinic input] -_imp._fix_co_filename +void +_PyImport_SetDLOpenFlags(PyInterpreterState *interp, int new_val) +{ + DLOPENFLAGS(interp) = new_val; +} +#endif // HAVE_DLOPEN - code: object(type="PyCodeObject *", subclass_of="&PyCode_Type") - Code object to change. - path: unicode - File path to use. - / +/* Common implementation for _imp.exec_dynamic and _imp.exec_builtin */ +static int +exec_builtin_or_dynamic(PyObject *mod) { + PyModuleDef *def; + void *state; -Changes code.co_filename to specify the passed-in file path. -[clinic start generated code]*/ + if (!PyModule_Check(mod)) { + return 0; + } -static PyObject * -_imp__fix_co_filename_impl(PyObject *module, PyCodeObject *code, - PyObject *path) -/*[clinic end generated code: output=1d002f100235587d input=895ba50e78b82f05]*/ + def = PyModule_GetDef(mod); + if (def == NULL) { + return 0; + } -{ - update_compiled_module(code, path); + state = PyModule_GetState(mod); + if (state) { + /* Already initialized; skip reload */ + return 0; + } - Py_RETURN_NONE; + return PyModule_ExecDef(mod, def); } -/* Helper to test for built-in module */ +static int clear_singlephase_extension(PyInterpreterState *interp, + PyObject *name, PyObject *filename); -static int -is_builtin(PyObject *name) +// Currently, this is only used for testing. +// (See _testinternalcapi.clear_extension().) +int +_PyImport_ClearExtension(PyObject *name, PyObject *filename) { - int i; - for (i = 0; PyImport_Inittab[i].name != NULL; i++) { - if (_PyUnicode_EqualToASCIIString(name, PyImport_Inittab[i].name)) { - if (PyImport_Inittab[i].initfunc == NULL) - return -1; - else - return 1; - } + PyInterpreterState *interp = _PyInterpreterState_GET(); + + /* Clearing a module's C globals is up to the module. */ + if (clear_singlephase_extension(interp, name, filename) < 0) { + return -1; } + + // In the future we'll probably also make sure the extension's + // file handle (and DL handle) is closed (requires saving it). + return 0; } -/* Return a finder object for a sys.path/pkg.__path__ item 'p', - possibly by fetching it from the path_importer_cache dict. If it - wasn't yet cached, traverse path_hooks until a hook is found - that can handle the path item. Return None if no hook could; - this tells our caller that the path based finder could not find - a finder for this path item. Cache the result in - path_importer_cache. */ +/*******************/ -static PyObject * -get_path_importer(PyThreadState *tstate, PyObject *path_importer_cache, - PyObject *path_hooks, PyObject *p) -{ - PyObject *importer; - Py_ssize_t j, nhooks; +#if defined(__EMSCRIPTEN__) && defined(PY_CALL_TRAMPOLINE) +#include <emscripten.h> +EM_JS(PyObject*, _PyImport_InitFunc_TrampolineCall, (PyModInitFunction func), { + return wasmTable.get(func)(); +}); +#endif // __EMSCRIPTEN__ && PY_CALL_TRAMPOLINE - /* These conditions are the caller's responsibility: */ - assert(PyList_Check(path_hooks)); - assert(PyDict_Check(path_importer_cache)); - nhooks = PyList_Size(path_hooks); - if (nhooks < 0) - return NULL; /* Shouldn't happen */ +/*****************************/ +/* single-phase init modules */ +/*****************************/ + +/* +We support a number of kinds of single-phase init builtin/extension modules: + +* "basic" + * no module state (PyModuleDef.m_size == -1) + * does not support repeated init (we use PyModuleDef.m_base.m_copy) + * may have process-global state + * the module's def is cached in _PyRuntime.imports.extensions, + by (name, filename) +* "reinit" + * no module state (PyModuleDef.m_size == 0) + * supports repeated init (m_copy is never used) + * should not have any process-global state + * its def is never cached in _PyRuntime.imports.extensions + (except, currently, under the main interpreter, for some reason) +* "with state" (almost the same as reinit) + * has module state (PyModuleDef.m_size > 0) + * supports repeated init (m_copy is never used) + * should not have any process-global state + * its def is never cached in _PyRuntime.imports.extensions + (except, currently, under the main interpreter, for some reason) + +There are also variants within those classes: + +* two or more modules share a PyModuleDef + * a module's init func uses another module's PyModuleDef + * a module's init func calls another's module's init func + * a module's init "func" is actually a variable statically initialized + to another module's init func +* two or modules share "methods" + * a module's init func copies another module's PyModuleDef + (with a different name) +* (basic-only) two or modules share process-global state + +In the first case, where modules share a PyModuleDef, the following +notable weirdness happens: + +* the module's __name__ matches the def, not the requested name +* the last module (with the same def) to be imported for the first time wins + * returned by PyState_Find_Module() (via interp->modules_by_index) + * (non-basic-only) its init func is used when re-loading any of them + (via the def's m_init) + * (basic-only) the copy of its __dict__ is used when re-loading any of them + (via the def's m_copy) + +However, the following happens as expected: + +* a new module object (with its own __dict__) is created for each request +* the module's __spec__ has the requested name +* the loaded module is cached in sys.modules under the requested name +* the m_index field of the shared def is not changed, + so at least PyState_FindModule() will always look in the same place + +For "basic" modules there are other quirks: + +* (whether sharing a def or not) when loaded the first time, + m_copy is set before _init_module_attrs() is called + in importlib._bootstrap.module_from_spec(), + so when the module is re-loaded, the previous value + for __wpec__ (and others) is reset, possibly unexpectedly. + +Generally, when multiple interpreters are involved, some of the above +gets even messier. +*/ - importer = PyDict_GetItemWithError(path_importer_cache, p); - if (importer != NULL || _PyErr_Occurred(tstate)) { - Py_XINCREF(importer); - return importer; - } +static inline void +extensions_lock_acquire(void) +{ + PyThread_acquire_lock(_PyRuntime.imports.extensions.mutex, WAIT_LOCK); +} - /* set path_importer_cache[p] to None to avoid recursion */ - if (PyDict_SetItem(path_importer_cache, p, Py_None) != 0) - return NULL; +static inline void +extensions_lock_release(void) +{ + PyThread_release_lock(_PyRuntime.imports.extensions.mutex); +} - for (j = 0; j < nhooks; j++) { - PyObject *hook = PyList_GetItem(path_hooks, j); - if (hook == NULL) - return NULL; - importer = PyObject_CallOneArg(hook, p); - if (importer != NULL) - break; +/* Magic for extension modules (built-in as well as dynamically + loaded). To prevent initializing an extension module more than + once, we keep a static dictionary 'extensions' keyed by the tuple + (module name, module name) (for built-in modules) or by + (filename, module name) (for dynamically loaded modules), containing these + modules. A copy of the module's dictionary is stored by calling + _PyImport_FixupExtensionObject() immediately after the module initialization + function succeeds. A copy can be retrieved from there by calling + import_find_extension(). - if (!_PyErr_ExceptionMatches(tstate, PyExc_ImportError)) { - return NULL; - } - _PyErr_Clear(tstate); - } - if (importer == NULL) { - Py_RETURN_NONE; + Modules which do support multiple initialization set their m_size + field to a non-negative number (indicating the size of the + module-specific state). They are still recorded in the extensions + dictionary, to avoid loading shared libraries twice. +*/ + +static void * +hashtable_key_from_2_strings(PyObject *str1, PyObject *str2, const char sep) +{ + Py_ssize_t str1_len, str2_len; + const char *str1_data = PyUnicode_AsUTF8AndSize(str1, &str1_len); + const char *str2_data = PyUnicode_AsUTF8AndSize(str2, &str2_len); + if (str1_data == NULL || str2_data == NULL) { + return NULL; } - if (PyDict_SetItem(path_importer_cache, p, importer) < 0) { - Py_DECREF(importer); + /* Make sure sep and the NULL byte won't cause an overflow. */ + assert(SIZE_MAX - str1_len - str2_len > 2); + size_t size = str1_len + 1 + str2_len + 1; + + char *key = PyMem_RawMalloc(size); + if (key == NULL) { + PyErr_NoMemory(); return NULL; } - return importer; + + strncpy(key, str1_data, str1_len); + key[str1_len] = sep; + strncpy(key + str1_len + 1, str2_data, str2_len + 1); + assert(strlen(key) == size - 1); + return key; } -PyObject * -PyImport_GetImporter(PyObject *path) +static Py_uhash_t +hashtable_hash_str(const void *key) { - PyThreadState *tstate = _PyThreadState_GET(); - PyObject *path_importer_cache = PySys_GetObject("path_importer_cache"); - PyObject *path_hooks = PySys_GetObject("path_hooks"); - if (path_importer_cache == NULL || path_hooks == NULL) { - return NULL; - } - return get_path_importer(tstate, path_importer_cache, path_hooks, path); + return _Py_HashBytes(key, strlen((const char *)key)); } -#if defined(__EMSCRIPTEN__) && defined(PY_CALL_TRAMPOLINE) -#include <emscripten.h> -EM_JS(PyObject*, _PyImport_InitFunc_TrampolineCall, (PyModInitFunction func), { - return wasmTable.get(func)(); -}); -#endif // __EMSCRIPTEN__ && PY_CALL_TRAMPOLINE +static int +hashtable_compare_str(const void *key1, const void *key2) +{ + return strcmp((const char *)key1, (const char *)key2) == 0; +} -static PyObject* -create_builtin(PyThreadState *tstate, PyObject *name, PyObject *spec) +static void +hashtable_destroy_str(void *ptr) { - PyObject *mod = import_find_extension(tstate, name, name); - if (mod || _PyErr_Occurred(tstate)) { - return mod; - } + PyMem_RawFree(ptr); +} - PyObject *modules = tstate->interp->modules; - for (struct _inittab *p = PyImport_Inittab; p->name != NULL; p++) { - if (_PyUnicode_EqualToASCIIString(name, p->name)) { - if (p->initfunc == NULL) { - /* Cannot re-init internal module ("sys" or "builtins") */ - mod = PyImport_AddModuleObject(name); - return Py_XNewRef(mod); - } - mod = _PyImport_InitFunc_TrampolineCall(*p->initfunc); - if (mod == NULL) { - return NULL; - } +#define HTSEP ':' - if (PyObject_TypeCheck(mod, &PyModuleDef_Type)) { - return PyModule_FromDefAndSpec((PyModuleDef*)mod, spec); - } - else { - /* Remember pointer to module init function. */ - PyModuleDef *def = PyModule_GetDef(mod); - if (def == NULL) { - return NULL; - } +static PyModuleDef * +_extensions_cache_get(PyObject *filename, PyObject *name) +{ + PyModuleDef *def = NULL; + void *key = NULL; + extensions_lock_acquire(); - def->m_base.m_init = p->initfunc; - if (_PyImport_FixupExtensionObject(mod, name, name, - modules) < 0) { - return NULL; - } - return mod; - } - } + if (EXTENSIONS.hashtable == NULL) { + goto finally; } - // not found - Py_RETURN_NONE; + key = hashtable_key_from_2_strings(filename, name, HTSEP); + if (key == NULL) { + goto finally; + } + _Py_hashtable_entry_t *entry = _Py_hashtable_get_entry( + EXTENSIONS.hashtable, key); + if (entry == NULL) { + goto finally; + } + def = (PyModuleDef *)entry->value; + +finally: + extensions_lock_release(); + if (key != NULL) { + PyMem_RawFree(key); + } + return def; } +static int +_extensions_cache_set(PyObject *filename, PyObject *name, PyModuleDef *def) +{ + int res = -1; + extensions_lock_acquire(); + if (EXTENSIONS.hashtable == NULL) { + _Py_hashtable_allocator_t alloc = {PyMem_RawMalloc, PyMem_RawFree}; + EXTENSIONS.hashtable = _Py_hashtable_new_full( + hashtable_hash_str, + hashtable_compare_str, + hashtable_destroy_str, // key + /* There's no need to decref the def since it's immortal. */ + NULL, // value + &alloc + ); + if (EXTENSIONS.hashtable == NULL) { + PyErr_NoMemory(); + goto finally; + } + } -/*[clinic input] -_imp.create_builtin + void *key = hashtable_key_from_2_strings(filename, name, HTSEP); + if (key == NULL) { + goto finally; + } - spec: object - / + int already_set = 0; + _Py_hashtable_entry_t *entry = _Py_hashtable_get_entry( + EXTENSIONS.hashtable, key); + if (entry == NULL) { + if (_Py_hashtable_set(EXTENSIONS.hashtable, key, def) < 0) { + PyMem_RawFree(key); + PyErr_NoMemory(); + goto finally; + } + } + else { + if (entry->value == NULL) { + entry->value = def; + } + else { + /* We expect it to be static, so it must be the same pointer. */ + assert((PyModuleDef *)entry->value == def); + already_set = 1; + } + PyMem_RawFree(key); + } + if (!already_set) { + /* We assume that all module defs are statically allocated + and will never be freed. Otherwise, we would incref here. */ + _Py_SetImmortal(def); + } + res = 0; -Create an extension module. -[clinic start generated code]*/ +finally: + extensions_lock_release(); + return res; +} -static PyObject * -_imp_create_builtin(PyObject *module, PyObject *spec) -/*[clinic end generated code: output=ace7ff22271e6f39 input=37f966f890384e47]*/ +static void +_extensions_cache_delete(PyObject *filename, PyObject *name) { - PyThreadState *tstate = _PyThreadState_GET(); + void *key = NULL; + extensions_lock_acquire(); - PyObject *name = PyObject_GetAttrString(spec, "name"); - if (name == NULL) { - return NULL; + if (EXTENSIONS.hashtable == NULL) { + /* It was never added. */ + goto finally; } - PyObject *mod = create_builtin(tstate, name, spec); - Py_DECREF(name); - return mod; + key = hashtable_key_from_2_strings(filename, name, HTSEP); + if (key == NULL) { + goto finally; + } + + _Py_hashtable_entry_t *entry = _Py_hashtable_get_entry( + EXTENSIONS.hashtable, key); + if (entry == NULL) { + /* It was never added. */ + goto finally; + } + if (entry->value == NULL) { + /* It was already removed. */ + goto finally; + } + /* If we hadn't made the stored defs immortal, we would decref here. + However, this decref would be problematic if the module def were + dynamically allocated, it were the last ref, and this function + were called with an interpreter other than the def's owner. */ + assert(_Py_IsImmortal(entry->value)); + entry->value = NULL; + +finally: + extensions_lock_release(); + if (key != NULL) { + PyMem_RawFree(key); + } } +static void +_extensions_cache_clear_all(void) +{ + /* The runtime (i.e. main interpreter) must be finalizing, + so we don't need to worry about the lock. */ + _Py_hashtable_destroy(EXTENSIONS.hashtable); + EXTENSIONS.hashtable = NULL; +} + +#undef HTSEP + -/* Return true if the name is an alias. In that case, "alias" is set - to the original module name. If it is an alias but the original - module isn't known then "alias" is set to NULL while true is returned. */ static bool -resolve_module_alias(const char *name, const struct _module_alias *aliases, - const char **alias) +check_multi_interp_extensions(PyInterpreterState *interp) { - const struct _module_alias *entry; - for (entry = aliases; ; entry++) { - if (entry->name == NULL) { - /* It isn't an alias. */ + int override = OVERRIDE_MULTI_INTERP_EXTENSIONS_CHECK(interp); + if (override < 0) { + return false; + } + else if (override > 0) { + return true; + } + else if (_PyInterpreterState_HasFeature( + interp, Py_RTFLAGS_MULTI_INTERP_EXTENSIONS)) { + return true; + } + return false; +} + +int +_PyImport_CheckSubinterpIncompatibleExtensionAllowed(const char *name) +{ + PyInterpreterState *interp = _PyInterpreterState_Get(); + if (check_multi_interp_extensions(interp)) { + assert(!_Py_IsMainInterpreter(interp)); + PyErr_Format(PyExc_ImportError, + "module %s does not support loading in subinterpreters", + name); + return -1; + } + return 0; +} + +static PyObject * +get_core_module_dict(PyInterpreterState *interp, + PyObject *name, PyObject *filename) +{ + /* Only builtin modules are core. */ + if (filename == name) { + assert(!PyErr_Occurred()); + if (PyUnicode_CompareWithASCIIString(name, "sys") == 0) { + return interp->sysdict_copy; + } + assert(!PyErr_Occurred()); + if (PyUnicode_CompareWithASCIIString(name, "builtins") == 0) { + return interp->builtins_copy; + } + assert(!PyErr_Occurred()); + } + return NULL; +} + +static inline int +is_core_module(PyInterpreterState *interp, PyObject *name, PyObject *filename) +{ + /* This might be called before the core dict copies are in place, + so we can't rely on get_core_module_dict() here. */ + if (filename == name) { + if (PyUnicode_CompareWithASCIIString(name, "sys") == 0) { + return 1; + } + if (PyUnicode_CompareWithASCIIString(name, "builtins") == 0) { + return 1; + } + } + return 0; +} + +static int +fix_up_extension(PyObject *mod, PyObject *name, PyObject *filename) +{ + if (mod == NULL || !PyModule_Check(mod)) { + PyErr_BadInternalCall(); + return -1; + } + + struct PyModuleDef *def = PyModule_GetDef(mod); + if (!def) { + PyErr_BadInternalCall(); + return -1; + } + + PyThreadState *tstate = _PyThreadState_GET(); + if (_modules_by_index_set(tstate->interp, def, mod) < 0) { + return -1; + } + + // bpo-44050: Extensions and def->m_base.m_copy can be updated + // when the extension module doesn't support sub-interpreters. + if (def->m_size == -1) { + if (!is_core_module(tstate->interp, name, filename)) { + assert(PyUnicode_CompareWithASCIIString(name, "sys") != 0); + assert(PyUnicode_CompareWithASCIIString(name, "builtins") != 0); + if (def->m_base.m_copy) { + /* Somebody already imported the module, + likely under a different name. + XXX this should really not happen. */ + Py_CLEAR(def->m_base.m_copy); + } + PyObject *dict = PyModule_GetDict(mod); + if (dict == NULL) { + return -1; + } + def->m_base.m_copy = PyDict_Copy(dict); + if (def->m_base.m_copy == NULL) { + return -1; + } + } + } + + // XXX Why special-case the main interpreter? + if (_Py_IsMainInterpreter(tstate->interp) || def->m_size == -1) { + if (_extensions_cache_set(filename, name, def) < 0) { + return -1; + } + } + + return 0; +} + +int +_PyImport_FixupExtensionObject(PyObject *mod, PyObject *name, + PyObject *filename, PyObject *modules) +{ + if (PyObject_SetItem(modules, name, mod) < 0) { + return -1; + } + if (fix_up_extension(mod, name, filename) < 0) { + PyMapping_DelItem(modules, name); + return -1; + } + return 0; +} + + +static PyObject * +import_find_extension(PyThreadState *tstate, PyObject *name, + PyObject *filename) +{ + /* Only single-phase init modules will be in the cache. */ + PyModuleDef *def = _extensions_cache_get(filename, name); + if (def == NULL) { + return NULL; + } + + /* It may have been successfully imported previously + in an interpreter that allows legacy modules + but is not allowed in the current interpreter. */ + const char *name_buf = PyUnicode_AsUTF8(name); + assert(name_buf != NULL); + if (_PyImport_CheckSubinterpIncompatibleExtensionAllowed(name_buf) < 0) { + return NULL; + } + + PyObject *mod, *mdict; + PyObject *modules = MODULES(tstate->interp); + + if (def->m_size == -1) { + PyObject *m_copy = def->m_base.m_copy; + /* Module does not support repeated initialization */ + if (m_copy == NULL) { + /* It might be a core module (e.g. sys & builtins), + for which we don't set m_copy. */ + m_copy = get_core_module_dict(tstate->interp, name, filename); + if (m_copy == NULL) { + return NULL; + } + } + mod = import_add_module(tstate, name); + if (mod == NULL) { + return NULL; + } + mdict = PyModule_GetDict(mod); + if (mdict == NULL) { + Py_DECREF(mod); + return NULL; + } + if (PyDict_Update(mdict, m_copy)) { + Py_DECREF(mod); + return NULL; + } + } + else { + if (def->m_base.m_init == NULL) + return NULL; + mod = _PyImport_InitFunc_TrampolineCall(def->m_base.m_init); + if (mod == NULL) + return NULL; + if (PyObject_SetItem(modules, name, mod) == -1) { + Py_DECREF(mod); + return NULL; + } + } + if (_modules_by_index_set(tstate->interp, def, mod) < 0) { + PyMapping_DelItem(modules, name); + Py_DECREF(mod); + return NULL; + } + + int verbose = _PyInterpreterState_GetConfig(tstate->interp)->verbose; + if (verbose) { + PySys_FormatStderr("import %U # previously loaded (%R)\n", + name, filename); + } + return mod; +} + +static int +clear_singlephase_extension(PyInterpreterState *interp, + PyObject *name, PyObject *filename) +{ + PyModuleDef *def = _extensions_cache_get(filename, name); + if (def == NULL) { + if (PyErr_Occurred()) { + return -1; + } + return 0; + } + + /* Clear data set when the module was initially loaded. */ + def->m_base.m_init = NULL; + Py_CLEAR(def->m_base.m_copy); + // We leave m_index alone since there's no reason to reset it. + + /* Clear the PyState_*Module() cache entry. */ + if (_modules_by_index_check(interp, def->m_base.m_index) == NULL) { + if (_modules_by_index_clear_one(interp, def) < 0) { + return -1; + } + } + + /* Clear the cached module def. */ + _extensions_cache_delete(filename, name); + + return 0; +} + + +/*******************/ +/* builtin modules */ +/*******************/ + +int +_PyImport_FixupBuiltin(PyObject *mod, const char *name, PyObject *modules) +{ + int res = -1; + PyObject *nameobj; + nameobj = PyUnicode_InternFromString(name); + if (nameobj == NULL) { + return -1; + } + if (PyObject_SetItem(modules, nameobj, mod) < 0) { + goto finally; + } + if (fix_up_extension(mod, nameobj, nameobj) < 0) { + PyMapping_DelItem(modules, nameobj); + goto finally; + } + res = 0; + +finally: + Py_DECREF(nameobj); + return res; +} + +/* Helper to test for built-in module */ + +static int +is_builtin(PyObject *name) +{ + int i; + struct _inittab *inittab = INITTAB; + for (i = 0; inittab[i].name != NULL; i++) { + if (_PyUnicode_EqualToASCIIString(name, inittab[i].name)) { + if (inittab[i].initfunc == NULL) + return -1; + else + return 1; + } + } + return 0; +} + +static PyObject* +create_builtin(PyThreadState *tstate, PyObject *name, PyObject *spec) +{ + PyObject *mod = import_find_extension(tstate, name, name); + if (mod || _PyErr_Occurred(tstate)) { + return mod; + } + + PyObject *modules = MODULES(tstate->interp); + for (struct _inittab *p = INITTAB; p->name != NULL; p++) { + if (_PyUnicode_EqualToASCIIString(name, p->name)) { + if (p->initfunc == NULL) { + /* Cannot re-init internal module ("sys" or "builtins") */ + mod = PyImport_AddModuleObject(name); + return Py_XNewRef(mod); + } + mod = _PyImport_InitFunc_TrampolineCall(*p->initfunc); + if (mod == NULL) { + return NULL; + } + + if (PyObject_TypeCheck(mod, &PyModuleDef_Type)) { + return PyModule_FromDefAndSpec((PyModuleDef*)mod, spec); + } + else { + /* Remember pointer to module init function. */ + PyModuleDef *def = PyModule_GetDef(mod); + if (def == NULL) { + return NULL; + } + + def->m_base.m_init = p->initfunc; + if (_PyImport_FixupExtensionObject(mod, name, name, + modules) < 0) { + return NULL; + } + return mod; + } + } + } + + // not found + Py_RETURN_NONE; +} + + +/*****************************/ +/* the builtin modules table */ +/*****************************/ + +/* API for embedding applications that want to add their own entries + to the table of built-in modules. This should normally be called + *before* Py_Initialize(). When the table resize fails, -1 is + returned and the existing table is unchanged. + + After a similar function by Just van Rossum. */ + +int +PyImport_ExtendInittab(struct _inittab *newtab) +{ + struct _inittab *p; + size_t i, n; + int res = 0; + + if (INITTAB != NULL) { + Py_FatalError("PyImport_ExtendInittab() may not be called after Py_Initialize()"); + } + + /* Count the number of entries in both tables */ + for (n = 0; newtab[n].name != NULL; n++) + ; + if (n == 0) + return 0; /* Nothing to do */ + for (i = 0; PyImport_Inittab[i].name != NULL; i++) + ; + + /* Force default raw memory allocator to get a known allocator to be able + to release the memory in _PyImport_Fini2() */ + PyMemAllocatorEx old_alloc; + _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); + + /* Allocate new memory for the combined table */ + p = NULL; + if (i + n <= SIZE_MAX / sizeof(struct _inittab) - 1) { + size_t size = sizeof(struct _inittab) * (i + n + 1); + p = PyMem_RawRealloc(inittab_copy, size); + } + if (p == NULL) { + res = -1; + goto done; + } + + /* Copy the tables into the new memory at the first call + to PyImport_ExtendInittab(). */ + if (inittab_copy != PyImport_Inittab) { + memcpy(p, PyImport_Inittab, (i+1) * sizeof(struct _inittab)); + } + memcpy(p + i, newtab, (n + 1) * sizeof(struct _inittab)); + PyImport_Inittab = inittab_copy = p; + +done: + PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); + return res; +} + +/* Shorthand to add a single entry given a name and a function */ + +int +PyImport_AppendInittab(const char *name, PyObject* (*initfunc)(void)) +{ + struct _inittab newtab[2]; + + if (INITTAB != NULL) { + Py_FatalError("PyImport_AppendInittab() may not be called after Py_Initialize()"); + } + + memset(newtab, '\0', sizeof newtab); + + newtab[0].name = name; + newtab[0].initfunc = initfunc; + + return PyImport_ExtendInittab(newtab); +} + + +/* the internal table */ + +static int +init_builtin_modules_table(void) +{ + size_t size; + for (size = 0; PyImport_Inittab[size].name != NULL; size++) + ; + size++; + + /* Make the copy. */ + struct _inittab *copied = PyMem_RawMalloc(size * sizeof(struct _inittab)); + if (copied == NULL) { + return -1; + } + memcpy(copied, PyImport_Inittab, size * sizeof(struct _inittab)); + INITTAB = copied; + return 0; +} + +static void +fini_builtin_modules_table(void) +{ + struct _inittab *inittab = INITTAB; + INITTAB = NULL; + PyMem_RawFree(inittab); +} + +PyObject * +_PyImport_GetBuiltinModuleNames(void) +{ + PyObject *list = PyList_New(0); + if (list == NULL) { + return NULL; + } + struct _inittab *inittab = INITTAB; + for (Py_ssize_t i = 0; inittab[i].name != NULL; i++) { + PyObject *name = PyUnicode_FromString(inittab[i].name); + if (name == NULL) { + Py_DECREF(list); + return NULL; + } + if (PyList_Append(list, name) < 0) { + Py_DECREF(name); + Py_DECREF(list); + return NULL; + } + Py_DECREF(name); + } + return list; +} + + +/********************/ +/* the magic number */ +/********************/ + +/* Helper for pythonrun.c -- return magic number and tag. */ + +long +PyImport_GetMagicNumber(void) +{ + long res; + PyInterpreterState *interp = _PyInterpreterState_GET(); + PyObject *external, *pyc_magic; + + external = PyObject_GetAttrString(IMPORTLIB(interp), "_bootstrap_external"); + if (external == NULL) + return -1; + pyc_magic = PyObject_GetAttrString(external, "_RAW_MAGIC_NUMBER"); + Py_DECREF(external); + if (pyc_magic == NULL) + return -1; + res = PyLong_AsLong(pyc_magic); + Py_DECREF(pyc_magic); + return res; +} + + +extern const char * _PySys_ImplCacheTag; + +const char * +PyImport_GetMagicTag(void) +{ + return _PySys_ImplCacheTag; +} + + +/*********************************/ +/* a Python module's code object */ +/*********************************/ + +/* Execute a code object in a module and return the module object + * WITH INCREMENTED REFERENCE COUNT. If an error occurs, name is + * removed from sys.modules, to avoid leaving damaged module objects + * in sys.modules. The caller may wish to restore the original + * module object (if any) in this case; PyImport_ReloadModule is an + * example. + * + * Note that PyImport_ExecCodeModuleWithPathnames() is the preferred, richer + * interface. The other two exist primarily for backward compatibility. + */ +PyObject * +PyImport_ExecCodeModule(const char *name, PyObject *co) +{ + return PyImport_ExecCodeModuleWithPathnames( + name, co, (char *)NULL, (char *)NULL); +} + +PyObject * +PyImport_ExecCodeModuleEx(const char *name, PyObject *co, const char *pathname) +{ + return PyImport_ExecCodeModuleWithPathnames( + name, co, pathname, (char *)NULL); +} + +PyObject * +PyImport_ExecCodeModuleWithPathnames(const char *name, PyObject *co, + const char *pathname, + const char *cpathname) +{ + PyObject *m = NULL; + PyObject *nameobj, *pathobj = NULL, *cpathobj = NULL, *external= NULL; + + nameobj = PyUnicode_FromString(name); + if (nameobj == NULL) + return NULL; + + if (cpathname != NULL) { + cpathobj = PyUnicode_DecodeFSDefault(cpathname); + if (cpathobj == NULL) + goto error; + } + else + cpathobj = NULL; + + if (pathname != NULL) { + pathobj = PyUnicode_DecodeFSDefault(pathname); + if (pathobj == NULL) + goto error; + } + else if (cpathobj != NULL) { + PyInterpreterState *interp = _PyInterpreterState_GET(); + + if (interp == NULL) { + Py_FatalError("no current interpreter"); + } + + external= PyObject_GetAttrString(IMPORTLIB(interp), + "_bootstrap_external"); + if (external != NULL) { + pathobj = _PyObject_CallMethodOneArg( + external, &_Py_ID(_get_sourcefile), cpathobj); + Py_DECREF(external); + } + if (pathobj == NULL) + PyErr_Clear(); + } + else + pathobj = NULL; + + m = PyImport_ExecCodeModuleObject(nameobj, co, pathobj, cpathobj); +error: + Py_DECREF(nameobj); + Py_XDECREF(pathobj); + Py_XDECREF(cpathobj); + return m; +} + +static PyObject * +module_dict_for_exec(PyThreadState *tstate, PyObject *name) +{ + PyObject *m, *d; + + m = import_add_module(tstate, name); + if (m == NULL) + return NULL; + /* If the module is being reloaded, we get the old module back + and re-use its dict to exec the new code. */ + d = PyModule_GetDict(m); + int r = PyDict_Contains(d, &_Py_ID(__builtins__)); + if (r == 0) { + r = PyDict_SetItem(d, &_Py_ID(__builtins__), PyEval_GetBuiltins()); + } + if (r < 0) { + remove_module(tstate, name); + Py_DECREF(m); + return NULL; + } + + Py_INCREF(d); + Py_DECREF(m); + return d; +} + +static PyObject * +exec_code_in_module(PyThreadState *tstate, PyObject *name, + PyObject *module_dict, PyObject *code_object) +{ + PyObject *v, *m; + + v = PyEval_EvalCode(code_object, module_dict, module_dict); + if (v == NULL) { + remove_module(tstate, name); + return NULL; + } + Py_DECREF(v); + + m = import_get_module(tstate, name); + if (m == NULL && !_PyErr_Occurred(tstate)) { + _PyErr_Format(tstate, PyExc_ImportError, + "Loaded module %R not found in sys.modules", + name); + } + + return m; +} + +PyObject* +PyImport_ExecCodeModuleObject(PyObject *name, PyObject *co, PyObject *pathname, + PyObject *cpathname) +{ + PyThreadState *tstate = _PyThreadState_GET(); + PyObject *d, *external, *res; + + d = module_dict_for_exec(tstate, name); + if (d == NULL) { + return NULL; + } + + if (pathname == NULL) { + pathname = ((PyCodeObject *)co)->co_filename; + } + external = PyObject_GetAttrString(IMPORTLIB(tstate->interp), + "_bootstrap_external"); + if (external == NULL) { + Py_DECREF(d); + return NULL; + } + res = PyObject_CallMethodObjArgs(external, &_Py_ID(_fix_up_module), + d, name, pathname, cpathname, NULL); + Py_DECREF(external); + if (res != NULL) { + Py_DECREF(res); + res = exec_code_in_module(tstate, name, d, co); + } + Py_DECREF(d); + return res; +} + + +static void +update_code_filenames(PyCodeObject *co, PyObject *oldname, PyObject *newname) +{ + PyObject *constants, *tmp; + Py_ssize_t i, n; + + if (PyUnicode_Compare(co->co_filename, oldname)) + return; + + Py_XSETREF(co->co_filename, Py_NewRef(newname)); + + constants = co->co_consts; + n = PyTuple_GET_SIZE(constants); + for (i = 0; i < n; i++) { + tmp = PyTuple_GET_ITEM(constants, i); + if (PyCode_Check(tmp)) + update_code_filenames((PyCodeObject *)tmp, + oldname, newname); + } +} + +static void +update_compiled_module(PyCodeObject *co, PyObject *newname) +{ + PyObject *oldname; + + if (PyUnicode_Compare(co->co_filename, newname) == 0) + return; + + oldname = co->co_filename; + Py_INCREF(oldname); + update_code_filenames(co, oldname, newname); + Py_DECREF(oldname); +} + + +/******************/ +/* frozen modules */ +/******************/ + +/* Return true if the name is an alias. In that case, "alias" is set + to the original module name. If it is an alias but the original + module isn't known then "alias" is set to NULL while true is returned. */ +static bool +resolve_module_alias(const char *name, const struct _module_alias *aliases, + const char **alias) +{ + const struct _module_alias *entry; + for (entry = aliases; ; entry++) { + if (entry->name == NULL) { + /* It isn't an alias. */ return false; } if (strcmp(name, entry->name) == 0) { @@ -1060,14 +1821,11 @@ resolve_module_alias(const char *name, const struct _module_alias *aliases, } } - -/* Frozen modules */ - static bool use_frozen(void) { PyInterpreterState *interp = _PyInterpreterState_GET(); - int override = interp->override_frozen_modules; + int override = OVERRIDE_FROZEN_MODULES(interp); if (override > 0) { return true; } @@ -1317,9 +2075,9 @@ find_frozen(PyObject *nameobj, struct frozen_info *info) } static PyObject * -unmarshal_frozen_code(struct frozen_info *info) +unmarshal_frozen_code(PyInterpreterState *interp, struct frozen_info *info) { - if (info->get_code) { + if (info->get_code && _Py_IsMainInterpreter(interp)) { PyObject *code = info->get_code(); assert(code != NULL); return code; @@ -1327,6 +2085,7 @@ unmarshal_frozen_code(struct frozen_info *info) PyObject *co = PyMarshal_ReadObjectFromString(info->data, info->size); if (co == NULL) { /* Does not contain executable code. */ + PyErr_Clear(); set_frozen_error(FROZEN_INVALID, info->nameobj); return NULL; } @@ -1366,7 +2125,7 @@ PyImport_ImportFrozenModuleObject(PyObject *name) set_frozen_error(status, name); return -1; } - co = unmarshal_frozen_code(&info); + co = unmarshal_frozen_code(tstate->interp, &info); if (co == NULL) { return -1; } @@ -1406,35 +2165,295 @@ PyImport_ImportFrozenModuleObject(PyObject *name) } } else { - Py_INCREF(Py_None); - origname = Py_None; + origname = Py_NewRef(Py_None); } err = PyDict_SetItemString(d, "__origname__", origname); Py_DECREF(origname); if (err != 0) { goto err_return; } - Py_DECREF(d); - Py_DECREF(co); - return 1; + Py_DECREF(d); + Py_DECREF(co); + return 1; + +err_return: + Py_XDECREF(d); + Py_DECREF(co); + return -1; +} + +int +PyImport_ImportFrozenModule(const char *name) +{ + PyObject *nameobj; + int ret; + nameobj = PyUnicode_InternFromString(name); + if (nameobj == NULL) + return -1; + ret = PyImport_ImportFrozenModuleObject(nameobj); + Py_DECREF(nameobj); + return ret; +} + + +/*************/ +/* importlib */ +/*************/ + +/* Import the _imp extension by calling manually _imp.create_builtin() and + _imp.exec_builtin() since importlib is not initialized yet. Initializing + importlib requires the _imp module: this function fix the bootstrap issue. + */ +static PyObject* +bootstrap_imp(PyThreadState *tstate) +{ + PyObject *name = PyUnicode_FromString("_imp"); + if (name == NULL) { + return NULL; + } + + // Mock a ModuleSpec object just good enough for PyModule_FromDefAndSpec(): + // an object with just a name attribute. + // + // _imp.__spec__ is overridden by importlib._bootstrap._instal() anyway. + PyObject *attrs = Py_BuildValue("{sO}", "name", name); + if (attrs == NULL) { + goto error; + } + PyObject *spec = _PyNamespace_New(attrs); + Py_DECREF(attrs); + if (spec == NULL) { + goto error; + } + + // Create the _imp module from its definition. + PyObject *mod = create_builtin(tstate, name, spec); + Py_CLEAR(name); + Py_DECREF(spec); + if (mod == NULL) { + goto error; + } + assert(mod != Py_None); // not found + + // Execute the _imp module: call imp_module_exec(). + if (exec_builtin_or_dynamic(mod) < 0) { + Py_DECREF(mod); + goto error; + } + return mod; + +error: + Py_XDECREF(name); + return NULL; +} + +/* Global initializations. Can be undone by Py_FinalizeEx(). Don't + call this twice without an intervening Py_FinalizeEx() call. When + initializations fail, a fatal error is issued and the function does + not return. On return, the first thread and interpreter state have + been created. + + Locking: you must hold the interpreter lock while calling this. + (If the lock has not yet been initialized, that's equivalent to + having the lock, but you cannot use multiple threads.) + +*/ +static int +init_importlib(PyThreadState *tstate, PyObject *sysmod) +{ + assert(!_PyErr_Occurred(tstate)); + + PyInterpreterState *interp = tstate->interp; + int verbose = _PyInterpreterState_GetConfig(interp)->verbose; + + // Import _importlib through its frozen version, _frozen_importlib. + if (verbose) { + PySys_FormatStderr("import _frozen_importlib # frozen\n"); + } + if (PyImport_ImportFrozenModule("_frozen_importlib") <= 0) { + return -1; + } + PyObject *importlib = PyImport_AddModule("_frozen_importlib"); // borrowed + if (importlib == NULL) { + return -1; + } + IMPORTLIB(interp) = Py_NewRef(importlib); + + // Import the _imp module + if (verbose) { + PySys_FormatStderr("import _imp # builtin\n"); + } + PyObject *imp_mod = bootstrap_imp(tstate); + if (imp_mod == NULL) { + return -1; + } + if (_PyImport_SetModuleString("_imp", imp_mod) < 0) { + Py_DECREF(imp_mod); + return -1; + } + + // Install importlib as the implementation of import + PyObject *value = PyObject_CallMethod(importlib, "_install", + "OO", sysmod, imp_mod); + Py_DECREF(imp_mod); + if (value == NULL) { + return -1; + } + Py_DECREF(value); + + assert(!_PyErr_Occurred(tstate)); + return 0; +} + + +static int +init_importlib_external(PyInterpreterState *interp) +{ + PyObject *value; + value = PyObject_CallMethod(IMPORTLIB(interp), + "_install_external_importers", ""); + if (value == NULL) { + return -1; + } + Py_DECREF(value); + return 0; +} + +PyObject * +_PyImport_GetImportlibLoader(PyInterpreterState *interp, + const char *loader_name) +{ + return PyObject_GetAttrString(IMPORTLIB(interp), loader_name); +} + +PyObject * +_PyImport_GetImportlibExternalLoader(PyInterpreterState *interp, + const char *loader_name) +{ + PyObject *bootstrap = PyObject_GetAttrString(IMPORTLIB(interp), + "_bootstrap_external"); + if (bootstrap == NULL) { + return NULL; + } + + PyObject *loader_type = PyObject_GetAttrString(bootstrap, loader_name); + Py_DECREF(bootstrap); + return loader_type; +} + +PyObject * +_PyImport_BlessMyLoader(PyInterpreterState *interp, PyObject *module_globals) +{ + PyObject *external = PyObject_GetAttrString(IMPORTLIB(interp), + "_bootstrap_external"); + if (external == NULL) { + return NULL; + } + + PyObject *loader = PyObject_CallMethod(external, "_bless_my_loader", + "O", module_globals, NULL); + Py_DECREF(external); + return loader; +} + +PyObject * +_PyImport_ImportlibModuleRepr(PyInterpreterState *interp, PyObject *m) +{ + return PyObject_CallMethod(IMPORTLIB(interp), "_module_repr", "O", m); +} + + +/*******************/ + +/* Return a finder object for a sys.path/pkg.__path__ item 'p', + possibly by fetching it from the path_importer_cache dict. If it + wasn't yet cached, traverse path_hooks until a hook is found + that can handle the path item. Return None if no hook could; + this tells our caller that the path based finder could not find + a finder for this path item. Cache the result in + path_importer_cache. */ + +static PyObject * +get_path_importer(PyThreadState *tstate, PyObject *path_importer_cache, + PyObject *path_hooks, PyObject *p) +{ + PyObject *importer; + Py_ssize_t j, nhooks; + + /* These conditions are the caller's responsibility: */ + assert(PyList_Check(path_hooks)); + assert(PyDict_Check(path_importer_cache)); + + nhooks = PyList_Size(path_hooks); + if (nhooks < 0) + return NULL; /* Shouldn't happen */ + + importer = PyDict_GetItemWithError(path_importer_cache, p); + if (importer != NULL || _PyErr_Occurred(tstate)) { + return Py_XNewRef(importer); + } + + /* set path_importer_cache[p] to None to avoid recursion */ + if (PyDict_SetItem(path_importer_cache, p, Py_None) != 0) + return NULL; + + for (j = 0; j < nhooks; j++) { + PyObject *hook = PyList_GetItem(path_hooks, j); + if (hook == NULL) + return NULL; + importer = PyObject_CallOneArg(hook, p); + if (importer != NULL) + break; + + if (!_PyErr_ExceptionMatches(tstate, PyExc_ImportError)) { + return NULL; + } + _PyErr_Clear(tstate); + } + if (importer == NULL) { + Py_RETURN_NONE; + } + if (PyDict_SetItem(path_importer_cache, p, importer) < 0) { + Py_DECREF(importer); + return NULL; + } + return importer; +} -err_return: - Py_XDECREF(d); - Py_DECREF(co); - return -1; +PyObject * +PyImport_GetImporter(PyObject *path) +{ + PyThreadState *tstate = _PyThreadState_GET(); + PyObject *path_importer_cache = PySys_GetObject("path_importer_cache"); + PyObject *path_hooks = PySys_GetObject("path_hooks"); + if (path_importer_cache == NULL || path_hooks == NULL) { + return NULL; + } + return get_path_importer(tstate, path_importer_cache, path_hooks, path); } + +/*********************/ +/* importing modules */ +/*********************/ + int -PyImport_ImportFrozenModule(const char *name) +_PyImport_InitDefaultImportFunc(PyInterpreterState *interp) { - PyObject *nameobj; - int ret; - nameobj = PyUnicode_InternFromString(name); - if (nameobj == NULL) + // Get the __import__ function + PyObject *import_func = _PyDict_GetItemStringWithError(interp->builtins, + "__import__"); + if (import_func == NULL) { return -1; - ret = PyImport_ImportFrozenModuleObject(nameobj); - Py_DECREF(nameobj); - return ret; + } + IMPORT_FUNC(interp) = Py_NewRef(import_func); + return 0; +} + +int +_PyImport_IsDefaultImportFunc(PyInterpreterState *interp, PyObject *func) +{ + return func == IMPORT_FUNC(interp); } @@ -1482,565 +2501,918 @@ remove_importlib_frames(PyThreadState *tstate) const char *remove_frames = "_call_with_frames_removed"; int always_trim = 0; int in_importlib = 0; - PyObject *exception, *value, *base_tb, *tb; PyObject **prev_link, **outer_link = NULL; + PyObject *base_tb = NULL; + + /* Synopsis: if it's an ImportError, we trim all importlib chunks + from the traceback. We always trim chunks + which end with a call to "_call_with_frames_removed". */ + + PyObject *exc = _PyErr_GetRaisedException(tstate); + if (exc == NULL || _PyInterpreterState_GetConfig(tstate->interp)->verbose) { + goto done; + } + + if (PyType_IsSubtype(Py_TYPE(exc), (PyTypeObject *) PyExc_ImportError)) { + always_trim = 1; + } + + assert(PyExceptionInstance_Check(exc)); + base_tb = PyException_GetTraceback(exc); + prev_link = &base_tb; + PyObject *tb = base_tb; + while (tb != NULL) { + assert(PyTraceBack_Check(tb)); + PyTracebackObject *traceback = (PyTracebackObject *)tb; + PyObject *next = (PyObject *) traceback->tb_next; + PyFrameObject *frame = traceback->tb_frame; + PyCodeObject *code = PyFrame_GetCode(frame); + int now_in_importlib; + + now_in_importlib = _PyUnicode_EqualToASCIIString(code->co_filename, importlib_filename) || + _PyUnicode_EqualToASCIIString(code->co_filename, external_filename); + if (now_in_importlib && !in_importlib) { + /* This is the link to this chunk of importlib tracebacks */ + outer_link = prev_link; + } + in_importlib = now_in_importlib; + + if (in_importlib && + (always_trim || + _PyUnicode_EqualToASCIIString(code->co_name, remove_frames))) { + Py_XSETREF(*outer_link, Py_XNewRef(next)); + prev_link = outer_link; + } + else { + prev_link = (PyObject **) &traceback->tb_next; + } + Py_DECREF(code); + tb = next; + } + if (base_tb == NULL) { + base_tb = Py_None; + Py_INCREF(Py_None); + } + PyException_SetTraceback(exc, base_tb); +done: + Py_XDECREF(base_tb); + _PyErr_SetRaisedException(tstate, exc); +} + + +static PyObject * +resolve_name(PyThreadState *tstate, PyObject *name, PyObject *globals, int level) +{ + PyObject *abs_name; + PyObject *package = NULL; + PyObject *spec; + Py_ssize_t last_dot; + PyObject *base; + int level_up; + + if (globals == NULL) { + _PyErr_SetString(tstate, PyExc_KeyError, "'__name__' not in globals"); + goto error; + } + if (!PyDict_Check(globals)) { + _PyErr_SetString(tstate, PyExc_TypeError, "globals must be a dict"); + goto error; + } + package = PyDict_GetItemWithError(globals, &_Py_ID(__package__)); + if (package == Py_None) { + package = NULL; + } + else if (package == NULL && _PyErr_Occurred(tstate)) { + goto error; + } + spec = PyDict_GetItemWithError(globals, &_Py_ID(__spec__)); + if (spec == NULL && _PyErr_Occurred(tstate)) { + goto error; + } + + if (package != NULL) { + Py_INCREF(package); + if (!PyUnicode_Check(package)) { + _PyErr_SetString(tstate, PyExc_TypeError, + "package must be a string"); + goto error; + } + else if (spec != NULL && spec != Py_None) { + int equal; + PyObject *parent = PyObject_GetAttr(spec, &_Py_ID(parent)); + if (parent == NULL) { + goto error; + } + + equal = PyObject_RichCompareBool(package, parent, Py_EQ); + Py_DECREF(parent); + if (equal < 0) { + goto error; + } + else if (equal == 0) { + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "__package__ != __spec__.parent", 1) < 0) { + goto error; + } + } + } + } + else if (spec != NULL && spec != Py_None) { + package = PyObject_GetAttr(spec, &_Py_ID(parent)); + if (package == NULL) { + goto error; + } + else if (!PyUnicode_Check(package)) { + _PyErr_SetString(tstate, PyExc_TypeError, + "__spec__.parent must be a string"); + goto error; + } + } + else { + if (PyErr_WarnEx(PyExc_ImportWarning, + "can't resolve package from __spec__ or __package__, " + "falling back on __name__ and __path__", 1) < 0) { + goto error; + } + + package = PyDict_GetItemWithError(globals, &_Py_ID(__name__)); + if (package == NULL) { + if (!_PyErr_Occurred(tstate)) { + _PyErr_SetString(tstate, PyExc_KeyError, + "'__name__' not in globals"); + } + goto error; + } + + Py_INCREF(package); + if (!PyUnicode_Check(package)) { + _PyErr_SetString(tstate, PyExc_TypeError, + "__name__ must be a string"); + goto error; + } + + int haspath = PyDict_Contains(globals, &_Py_ID(__path__)); + if (haspath < 0) { + goto error; + } + if (!haspath) { + Py_ssize_t dot; + + if (PyUnicode_READY(package) < 0) { + goto error; + } + + dot = PyUnicode_FindChar(package, '.', + 0, PyUnicode_GET_LENGTH(package), -1); + if (dot == -2) { + goto error; + } + else if (dot == -1) { + goto no_parent_error; + } + PyObject *substr = PyUnicode_Substring(package, 0, dot); + if (substr == NULL) { + goto error; + } + Py_SETREF(package, substr); + } + } + + last_dot = PyUnicode_GET_LENGTH(package); + if (last_dot == 0) { + goto no_parent_error; + } + + for (level_up = 1; level_up < level; level_up += 1) { + last_dot = PyUnicode_FindChar(package, '.', 0, last_dot, -1); + if (last_dot == -2) { + goto error; + } + else if (last_dot == -1) { + _PyErr_SetString(tstate, PyExc_ImportError, + "attempted relative import beyond top-level " + "package"); + goto error; + } + } + + base = PyUnicode_Substring(package, 0, last_dot); + Py_DECREF(package); + if (base == NULL || PyUnicode_GET_LENGTH(name) == 0) { + return base; + } + + abs_name = PyUnicode_FromFormat("%U.%U", base, name); + Py_DECREF(base); + return abs_name; + + no_parent_error: + _PyErr_SetString(tstate, PyExc_ImportError, + "attempted relative import " + "with no known parent package"); + + error: + Py_XDECREF(package); + return NULL; +} + +static PyObject * +import_find_and_load(PyThreadState *tstate, PyObject *abs_name) +{ + PyObject *mod = NULL; + PyInterpreterState *interp = tstate->interp; + int import_time = _PyInterpreterState_GetConfig(interp)->import_time; +#define import_level FIND_AND_LOAD(interp).import_level +#define accumulated FIND_AND_LOAD(interp).accumulated + + _PyTime_t t1 = 0, accumulated_copy = accumulated; + + PyObject *sys_path = PySys_GetObject("path"); + PyObject *sys_meta_path = PySys_GetObject("meta_path"); + PyObject *sys_path_hooks = PySys_GetObject("path_hooks"); + if (_PySys_Audit(tstate, "import", "OOOOO", + abs_name, Py_None, sys_path ? sys_path : Py_None, + sys_meta_path ? sys_meta_path : Py_None, + sys_path_hooks ? sys_path_hooks : Py_None) < 0) { + return NULL; + } - /* Synopsis: if it's an ImportError, we trim all importlib chunks - from the traceback. We always trim chunks - which end with a call to "_call_with_frames_removed". */ - _PyErr_Fetch(tstate, &exception, &value, &base_tb); - if (!exception || _PyInterpreterState_GetConfig(tstate->interp)->verbose) { - goto done; + /* XOptions is initialized after first some imports. + * So we can't have negative cache before completed initialization. + * Anyway, importlib._find_and_load is much slower than + * _PyDict_GetItemIdWithError(). + */ + if (import_time) { +#define header FIND_AND_LOAD(interp).header + if (header) { + fputs("import time: self [us] | cumulative | imported package\n", + stderr); + header = 0; + } +#undef header + + import_level++; + t1 = _PyTime_GetPerfCounter(); + accumulated = 0; } - if (PyType_IsSubtype((PyTypeObject *) exception, - (PyTypeObject *) PyExc_ImportError)) - always_trim = 1; + if (PyDTrace_IMPORT_FIND_LOAD_START_ENABLED()) + PyDTrace_IMPORT_FIND_LOAD_START(PyUnicode_AsUTF8(abs_name)); - prev_link = &base_tb; - tb = base_tb; - while (tb != NULL) { - PyTracebackObject *traceback = (PyTracebackObject *)tb; - PyObject *next = (PyObject *) traceback->tb_next; - PyFrameObject *frame = traceback->tb_frame; - PyCodeObject *code = PyFrame_GetCode(frame); - int now_in_importlib; + mod = PyObject_CallMethodObjArgs(IMPORTLIB(interp), &_Py_ID(_find_and_load), + abs_name, IMPORT_FUNC(interp), NULL); - assert(PyTraceBack_Check(tb)); - now_in_importlib = _PyUnicode_EqualToASCIIString(code->co_filename, importlib_filename) || - _PyUnicode_EqualToASCIIString(code->co_filename, external_filename); - if (now_in_importlib && !in_importlib) { - /* This is the link to this chunk of importlib tracebacks */ - outer_link = prev_link; - } - in_importlib = now_in_importlib; + if (PyDTrace_IMPORT_FIND_LOAD_DONE_ENABLED()) + PyDTrace_IMPORT_FIND_LOAD_DONE(PyUnicode_AsUTF8(abs_name), + mod != NULL); - if (in_importlib && - (always_trim || - _PyUnicode_EqualToASCIIString(code->co_name, remove_frames))) { - Py_XINCREF(next); - Py_XSETREF(*outer_link, next); - prev_link = outer_link; - } - else { - prev_link = (PyObject **) &traceback->tb_next; - } - Py_DECREF(code); - tb = next; + if (import_time) { + _PyTime_t cum = _PyTime_GetPerfCounter() - t1; + + import_level--; + fprintf(stderr, "import time: %9ld | %10ld | %*s%s\n", + (long)_PyTime_AsMicroseconds(cum - accumulated, _PyTime_ROUND_CEILING), + (long)_PyTime_AsMicroseconds(cum, _PyTime_ROUND_CEILING), + import_level*2, "", PyUnicode_AsUTF8(abs_name)); + + accumulated = accumulated_copy + cum; } -done: - _PyErr_Restore(tstate, exception, value, base_tb); -} + return mod; +#undef import_level +#undef accumulated +} -static PyObject * -resolve_name(PyThreadState *tstate, PyObject *name, PyObject *globals, int level) +PyObject * +PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals, + PyObject *locals, PyObject *fromlist, + int level) { - PyObject *abs_name; + PyThreadState *tstate = _PyThreadState_GET(); + PyObject *abs_name = NULL; + PyObject *final_mod = NULL; + PyObject *mod = NULL; PyObject *package = NULL; - PyObject *spec; - Py_ssize_t last_dot; - PyObject *base; - int level_up; + PyInterpreterState *interp = tstate->interp; + int has_from; - if (globals == NULL) { - _PyErr_SetString(tstate, PyExc_KeyError, "'__name__' not in globals"); + if (name == NULL) { + _PyErr_SetString(tstate, PyExc_ValueError, "Empty module name"); goto error; } - if (!PyDict_Check(globals)) { - _PyErr_SetString(tstate, PyExc_TypeError, "globals must be a dict"); + + /* The below code is importlib.__import__() & _gcd_import(), ported to C + for added performance. */ + + if (!PyUnicode_Check(name)) { + _PyErr_SetString(tstate, PyExc_TypeError, + "module name must be a string"); goto error; } - package = PyDict_GetItemWithError(globals, &_Py_ID(__package__)); - if (package == Py_None) { - package = NULL; + if (PyUnicode_READY(name) < 0) { + goto error; } - else if (package == NULL && _PyErr_Occurred(tstate)) { + if (level < 0) { + _PyErr_SetString(tstate, PyExc_ValueError, "level must be >= 0"); goto error; } - spec = PyDict_GetItemWithError(globals, &_Py_ID(__spec__)); - if (spec == NULL && _PyErr_Occurred(tstate)) { + + if (level > 0) { + abs_name = resolve_name(tstate, name, globals, level); + if (abs_name == NULL) + goto error; + } + else { /* level == 0 */ + if (PyUnicode_GET_LENGTH(name) == 0) { + _PyErr_SetString(tstate, PyExc_ValueError, "Empty module name"); + goto error; + } + abs_name = Py_NewRef(name); + } + + mod = import_get_module(tstate, abs_name); + if (mod == NULL && _PyErr_Occurred(tstate)) { goto error; } - if (package != NULL) { - Py_INCREF(package); - if (!PyUnicode_Check(package)) { - _PyErr_SetString(tstate, PyExc_TypeError, - "package must be a string"); + if (mod != NULL && mod != Py_None) { + if (import_ensure_initialized(tstate->interp, mod, abs_name) < 0) { goto error; } - else if (spec != NULL && spec != Py_None) { - int equal; - PyObject *parent = PyObject_GetAttr(spec, &_Py_ID(parent)); - if (parent == NULL) { + } + else { + Py_XDECREF(mod); + mod = import_find_and_load(tstate, abs_name); + if (mod == NULL) { + goto error; + } + } + + has_from = 0; + if (fromlist != NULL && fromlist != Py_None) { + has_from = PyObject_IsTrue(fromlist); + if (has_from < 0) + goto error; + } + if (!has_from) { + Py_ssize_t len = PyUnicode_GET_LENGTH(name); + if (level == 0 || len > 0) { + Py_ssize_t dot; + + dot = PyUnicode_FindChar(name, '.', 0, len, 1); + if (dot == -2) { goto error; } - equal = PyObject_RichCompareBool(package, parent, Py_EQ); - Py_DECREF(parent); - if (equal < 0) { + if (dot == -1) { + /* No dot in module name, simple exit */ + final_mod = Py_NewRef(mod); goto error; } - else if (equal == 0) { - if (PyErr_WarnEx(PyExc_ImportWarning, - "__package__ != __spec__.parent", 1) < 0) { + + if (level == 0) { + PyObject *front = PyUnicode_Substring(name, 0, dot); + if (front == NULL) { + goto error; + } + + final_mod = PyImport_ImportModuleLevelObject(front, NULL, NULL, NULL, 0); + Py_DECREF(front); + } + else { + Py_ssize_t cut_off = len - dot; + Py_ssize_t abs_name_len = PyUnicode_GET_LENGTH(abs_name); + PyObject *to_return = PyUnicode_Substring(abs_name, 0, + abs_name_len - cut_off); + if (to_return == NULL) { + goto error; + } + + final_mod = import_get_module(tstate, to_return); + Py_DECREF(to_return); + if (final_mod == NULL) { + if (!_PyErr_Occurred(tstate)) { + _PyErr_Format(tstate, PyExc_KeyError, + "%R not in sys.modules as expected", + to_return); + } goto error; } } } - } - else if (spec != NULL && spec != Py_None) { - package = PyObject_GetAttr(spec, &_Py_ID(parent)); - if (package == NULL) { - goto error; - } - else if (!PyUnicode_Check(package)) { - _PyErr_SetString(tstate, PyExc_TypeError, - "__spec__.parent must be a string"); - goto error; + else { + final_mod = Py_NewRef(mod); } } else { - if (PyErr_WarnEx(PyExc_ImportWarning, - "can't resolve package from __spec__ or __package__, " - "falling back on __name__ and __path__", 1) < 0) { + PyObject *path; + if (_PyObject_LookupAttr(mod, &_Py_ID(__path__), &path) < 0) { goto error; } - - package = PyDict_GetItemWithError(globals, &_Py_ID(__name__)); - if (package == NULL) { - if (!_PyErr_Occurred(tstate)) { - _PyErr_SetString(tstate, PyExc_KeyError, - "'__name__' not in globals"); - } - goto error; + if (path) { + Py_DECREF(path); + final_mod = PyObject_CallMethodObjArgs( + IMPORTLIB(interp), &_Py_ID(_handle_fromlist), + mod, fromlist, IMPORT_FUNC(interp), NULL); + } + else { + final_mod = Py_NewRef(mod); } + } - Py_INCREF(package); - if (!PyUnicode_Check(package)) { - _PyErr_SetString(tstate, PyExc_TypeError, - "__name__ must be a string"); - goto error; + error: + Py_XDECREF(abs_name); + Py_XDECREF(mod); + Py_XDECREF(package); + if (final_mod == NULL) { + remove_importlib_frames(tstate); + } + return final_mod; +} + +PyObject * +PyImport_ImportModuleLevel(const char *name, PyObject *globals, PyObject *locals, + PyObject *fromlist, int level) +{ + PyObject *nameobj, *mod; + nameobj = PyUnicode_FromString(name); + if (nameobj == NULL) + return NULL; + mod = PyImport_ImportModuleLevelObject(nameobj, globals, locals, + fromlist, level); + Py_DECREF(nameobj); + return mod; +} + + +/* Re-import a module of any kind and return its module object, WITH + INCREMENTED REFERENCE COUNT */ + +PyObject * +PyImport_ReloadModule(PyObject *m) +{ + PyObject *reloaded_module = NULL; + PyObject *importlib = PyImport_GetModule(&_Py_ID(importlib)); + if (importlib == NULL) { + if (PyErr_Occurred()) { + return NULL; } - int haspath = PyDict_Contains(globals, &_Py_ID(__path__)); - if (haspath < 0) { - goto error; + importlib = PyImport_ImportModule("importlib"); + if (importlib == NULL) { + return NULL; } - if (!haspath) { - Py_ssize_t dot; + } - if (PyUnicode_READY(package) < 0) { - goto error; - } + reloaded_module = PyObject_CallMethodOneArg(importlib, &_Py_ID(reload), m); + Py_DECREF(importlib); + return reloaded_module; +} - dot = PyUnicode_FindChar(package, '.', - 0, PyUnicode_GET_LENGTH(package), -1); - if (dot == -2) { - goto error; - } - else if (dot == -1) { - goto no_parent_error; - } - PyObject *substr = PyUnicode_Substring(package, 0, dot); - if (substr == NULL) { - goto error; - } - Py_SETREF(package, substr); - } - } - last_dot = PyUnicode_GET_LENGTH(package); - if (last_dot == 0) { - goto no_parent_error; +/* Higher-level import emulator which emulates the "import" statement + more accurately -- it invokes the __import__() function from the + builtins of the current globals. This means that the import is + done using whatever import hooks are installed in the current + environment. + A dummy list ["__doc__"] is passed as the 4th argument so that + e.g. PyImport_Import(PyUnicode_FromString("win32com.client.gencache")) + will return <module "gencache"> instead of <module "win32com">. */ + +PyObject * +PyImport_Import(PyObject *module_name) +{ + PyThreadState *tstate = _PyThreadState_GET(); + PyObject *globals = NULL; + PyObject *import = NULL; + PyObject *builtins = NULL; + PyObject *r = NULL; + + PyObject *from_list = PyList_New(0); + if (from_list == NULL) { + goto err; } - for (level_up = 1; level_up < level; level_up += 1) { - last_dot = PyUnicode_FindChar(package, '.', 0, last_dot, -1); - if (last_dot == -2) { - goto error; - } - else if (last_dot == -1) { - _PyErr_SetString(tstate, PyExc_ImportError, - "attempted relative import beyond top-level " - "package"); - goto error; + /* Get the builtins from current globals */ + globals = PyEval_GetGlobals(); + if (globals != NULL) { + Py_INCREF(globals); + builtins = PyObject_GetItem(globals, &_Py_ID(__builtins__)); + if (builtins == NULL) + goto err; + } + else { + /* No globals -- use standard builtins, and fake globals */ + builtins = PyImport_ImportModuleLevel("builtins", + NULL, NULL, NULL, 0); + if (builtins == NULL) { + goto err; } + globals = Py_BuildValue("{OO}", &_Py_ID(__builtins__), builtins); + if (globals == NULL) + goto err; } - base = PyUnicode_Substring(package, 0, last_dot); - Py_DECREF(package); - if (base == NULL || PyUnicode_GET_LENGTH(name) == 0) { - return base; + /* Get the __import__ function from the builtins */ + if (PyDict_Check(builtins)) { + import = PyObject_GetItem(builtins, &_Py_ID(__import__)); + if (import == NULL) { + _PyErr_SetObject(tstate, PyExc_KeyError, &_Py_ID(__import__)); + } } + else + import = PyObject_GetAttr(builtins, &_Py_ID(__import__)); + if (import == NULL) + goto err; - abs_name = PyUnicode_FromFormat("%U.%U", base, name); - Py_DECREF(base); - return abs_name; + /* Call the __import__ function with the proper argument list + Always use absolute import here. + Calling for side-effect of import. */ + r = PyObject_CallFunction(import, "OOOOi", module_name, globals, + globals, from_list, 0, NULL); + if (r == NULL) + goto err; + Py_DECREF(r); - no_parent_error: - _PyErr_SetString(tstate, PyExc_ImportError, - "attempted relative import " - "with no known parent package"); + r = import_get_module(tstate, module_name); + if (r == NULL && !_PyErr_Occurred(tstate)) { + _PyErr_SetObject(tstate, PyExc_KeyError, module_name); + } - error: - Py_XDECREF(package); - return NULL; + err: + Py_XDECREF(globals); + Py_XDECREF(builtins); + Py_XDECREF(import); + Py_XDECREF(from_list); + + return r; } -static PyObject * -import_find_and_load(PyThreadState *tstate, PyObject *abs_name) -{ - PyObject *mod = NULL; - PyInterpreterState *interp = tstate->interp; - int import_time = _PyInterpreterState_GetConfig(interp)->import_time; - static int import_level; - static _PyTime_t accumulated; - _PyTime_t t1 = 0, accumulated_copy = accumulated; +/*********************/ +/* runtime lifecycle */ +/*********************/ - PyObject *sys_path = PySys_GetObject("path"); - PyObject *sys_meta_path = PySys_GetObject("meta_path"); - PyObject *sys_path_hooks = PySys_GetObject("path_hooks"); - if (_PySys_Audit(tstate, "import", "OOOOO", - abs_name, Py_None, sys_path ? sys_path : Py_None, - sys_meta_path ? sys_meta_path : Py_None, - sys_path_hooks ? sys_path_hooks : Py_None) < 0) { - return NULL; +PyStatus +_PyImport_Init(void) +{ + if (INITTAB != NULL) { + return _PyStatus_ERR("global import state already initialized"); } + PyStatus status = _PyStatus_OK(); - /* XOptions is initialized after first some imports. - * So we can't have negative cache before completed initialization. - * Anyway, importlib._find_and_load is much slower than - * _PyDict_GetItemIdWithError(). - */ - if (import_time) { - static int header = 1; - if (header) { - fputs("import time: self [us] | cumulative | imported package\n", - stderr); - header = 0; - } + /* Force default raw memory allocator to get a known allocator to be able + to release the memory in _PyImport_Fini() */ + PyMemAllocatorEx old_alloc; + _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - import_level++; - t1 = _PyTime_GetPerfCounter(); - accumulated = 0; + if (init_builtin_modules_table() != 0) { + status = PyStatus_NoMemory(); + goto done; } - if (PyDTrace_IMPORT_FIND_LOAD_START_ENABLED()) - PyDTrace_IMPORT_FIND_LOAD_START(PyUnicode_AsUTF8(abs_name)); +done: + PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); + return status; +} - mod = PyObject_CallMethodObjArgs(interp->importlib, &_Py_ID(_find_and_load), - abs_name, interp->import_func, NULL); +void +_PyImport_Fini(void) +{ + /* Destroy the database used by _PyImport_{Fixup,Find}Extension */ + // XXX Should we actually leave them (mostly) intact, since we don't + // ever dlclose() the module files? + _extensions_cache_clear_all(); - if (PyDTrace_IMPORT_FIND_LOAD_DONE_ENABLED()) - PyDTrace_IMPORT_FIND_LOAD_DONE(PyUnicode_AsUTF8(abs_name), - mod != NULL); + /* Use the same memory allocator as _PyImport_Init(). */ + PyMemAllocatorEx old_alloc; + _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - if (import_time) { - _PyTime_t cum = _PyTime_GetPerfCounter() - t1; + /* Free memory allocated by _PyImport_Init() */ + fini_builtin_modules_table(); - import_level--; - fprintf(stderr, "import time: %9ld | %10ld | %*s%s\n", - (long)_PyTime_AsMicroseconds(cum - accumulated, _PyTime_ROUND_CEILING), - (long)_PyTime_AsMicroseconds(cum, _PyTime_ROUND_CEILING), - import_level*2, "", PyUnicode_AsUTF8(abs_name)); + PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); +} - accumulated = accumulated_copy + cum; - } +void +_PyImport_Fini2(void) +{ + /* Use the same memory allocator than PyImport_ExtendInittab(). */ + PyMemAllocatorEx old_alloc; + _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - return mod; + // Reset PyImport_Inittab + PyImport_Inittab = _PyImport_Inittab; + + /* Free memory allocated by PyImport_ExtendInittab() */ + PyMem_RawFree(inittab_copy); + inittab_copy = NULL; + + PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); } -PyObject * -PyImport_GetModule(PyObject *name) + +/*************************/ +/* interpreter lifecycle */ +/*************************/ + +PyStatus +_PyImport_InitCore(PyThreadState *tstate, PyObject *sysmod, int importlib) { - PyThreadState *tstate = _PyThreadState_GET(); - PyObject *mod; + // XXX Initialize here: interp->modules and interp->import_func. + // XXX Initialize here: sys.modules and sys.meta_path. - mod = import_get_module(tstate, name); - if (mod != NULL && mod != Py_None) { - if (import_ensure_initialized(tstate->interp, mod, name) < 0) { - Py_DECREF(mod); - remove_importlib_frames(tstate); - return NULL; + if (importlib) { + /* This call sets up builtin and frozen import support */ + if (init_importlib(tstate, sysmod) < 0) { + return _PyStatus_ERR("failed to initialize importlib"); } } - return mod; + + return _PyStatus_OK(); } -PyObject * -PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals, - PyObject *locals, PyObject *fromlist, - int level) -{ - PyThreadState *tstate = _PyThreadState_GET(); - PyObject *abs_name = NULL; - PyObject *final_mod = NULL; - PyObject *mod = NULL; - PyObject *package = NULL; - PyInterpreterState *interp = tstate->interp; - int has_from; +/* In some corner cases it is important to be sure that the import + machinery has been initialized (or not cleaned up yet). For + example, see issue #4236 and PyModule_Create2(). */ - if (name == NULL) { - _PyErr_SetString(tstate, PyExc_ValueError, "Empty module name"); - goto error; - } +int +_PyImport_IsInitialized(PyInterpreterState *interp) +{ + if (MODULES(interp) == NULL) + return 0; + return 1; +} - /* The below code is importlib.__import__() & _gcd_import(), ported to C - for added performance. */ +/* Clear the direct per-interpreter import state, if not cleared already. */ +void +_PyImport_ClearCore(PyInterpreterState *interp) +{ + /* interp->modules should have been cleaned up and cleared already + by _PyImport_FiniCore(). */ + Py_CLEAR(MODULES(interp)); + Py_CLEAR(MODULES_BY_INDEX(interp)); + Py_CLEAR(IMPORTLIB(interp)); + Py_CLEAR(IMPORT_FUNC(interp)); +} - if (!PyUnicode_Check(name)) { - _PyErr_SetString(tstate, PyExc_TypeError, - "module name must be a string"); - goto error; - } - if (PyUnicode_READY(name) < 0) { - goto error; +void +_PyImport_FiniCore(PyInterpreterState *interp) +{ + int verbose = _PyInterpreterState_GetConfig(interp)->verbose; + + if (_PySys_ClearAttrString(interp, "meta_path", verbose) < 0) { + PyErr_WriteUnraisable(NULL); } - if (level < 0) { - _PyErr_SetString(tstate, PyExc_ValueError, "level must be >= 0"); - goto error; + + // XXX Pull in most of finalize_modules() in pylifecycle.c. + + if (_PySys_ClearAttrString(interp, "modules", verbose) < 0) { + PyErr_WriteUnraisable(NULL); } - if (level > 0) { - abs_name = resolve_name(tstate, name, globals, level); - if (abs_name == NULL) - goto error; + if (IMPORT_LOCK(interp) != NULL) { + PyThread_free_lock(IMPORT_LOCK(interp)); + IMPORT_LOCK(interp) = NULL; } - else { /* level == 0 */ - if (PyUnicode_GET_LENGTH(name) == 0) { - _PyErr_SetString(tstate, PyExc_ValueError, "Empty module name"); - goto error; - } - abs_name = name; - Py_INCREF(abs_name); + + _PyImport_ClearCore(interp); +} + +// XXX Add something like _PyImport_Disable() for use early in interp fini? + + +/* "external" imports */ + +static int +init_zipimport(PyThreadState *tstate, int verbose) +{ + PyObject *path_hooks = PySys_GetObject("path_hooks"); + if (path_hooks == NULL) { + _PyErr_SetString(tstate, PyExc_RuntimeError, + "unable to get sys.path_hooks"); + return -1; } - mod = import_get_module(tstate, abs_name); - if (mod == NULL && _PyErr_Occurred(tstate)) { - goto error; + if (verbose) { + PySys_WriteStderr("# installing zipimport hook\n"); } - if (mod != NULL && mod != Py_None) { - if (import_ensure_initialized(tstate->interp, mod, abs_name) < 0) { - goto error; + PyObject *zipimporter = _PyImport_GetModuleAttrString("zipimport", "zipimporter"); + if (zipimporter == NULL) { + _PyErr_Clear(tstate); /* No zipimporter object -- okay */ + if (verbose) { + PySys_WriteStderr("# can't import zipimport.zipimporter\n"); } } else { - Py_XDECREF(mod); - mod = import_find_and_load(tstate, abs_name); - if (mod == NULL) { - goto error; + /* sys.path_hooks.insert(0, zipimporter) */ + int err = PyList_Insert(path_hooks, 0, zipimporter); + Py_DECREF(zipimporter); + if (err < 0) { + return -1; + } + if (verbose) { + PySys_WriteStderr("# installed zipimport hook\n"); } } - has_from = 0; - if (fromlist != NULL && fromlist != Py_None) { - has_from = PyObject_IsTrue(fromlist); - if (has_from < 0) - goto error; + return 0; +} + +PyStatus +_PyImport_InitExternal(PyThreadState *tstate) +{ + int verbose = _PyInterpreterState_GetConfig(tstate->interp)->verbose; + + // XXX Initialize here: sys.path_hooks and sys.path_importer_cache. + + if (init_importlib_external(tstate->interp) != 0) { + _PyErr_Print(tstate); + return _PyStatus_ERR("external importer setup failed"); } - if (!has_from) { - Py_ssize_t len = PyUnicode_GET_LENGTH(name); - if (level == 0 || len > 0) { - Py_ssize_t dot; - dot = PyUnicode_FindChar(name, '.', 0, len, 1); - if (dot == -2) { - goto error; - } + if (init_zipimport(tstate, verbose) != 0) { + PyErr_Print(); + return _PyStatus_ERR("initializing zipimport failed"); + } - if (dot == -1) { - /* No dot in module name, simple exit */ - final_mod = mod; - Py_INCREF(mod); - goto error; - } + return _PyStatus_OK(); +} - if (level == 0) { - PyObject *front = PyUnicode_Substring(name, 0, dot); - if (front == NULL) { - goto error; - } +void +_PyImport_FiniExternal(PyInterpreterState *interp) +{ + int verbose = _PyInterpreterState_GetConfig(interp)->verbose; - final_mod = PyImport_ImportModuleLevelObject(front, NULL, NULL, NULL, 0); - Py_DECREF(front); - } - else { - Py_ssize_t cut_off = len - dot; - Py_ssize_t abs_name_len = PyUnicode_GET_LENGTH(abs_name); - PyObject *to_return = PyUnicode_Substring(abs_name, 0, - abs_name_len - cut_off); - if (to_return == NULL) { - goto error; - } + // XXX Uninstall importlib metapath importers here? - final_mod = import_get_module(tstate, to_return); - Py_DECREF(to_return); - if (final_mod == NULL) { - if (!_PyErr_Occurred(tstate)) { - _PyErr_Format(tstate, PyExc_KeyError, - "%R not in sys.modules as expected", - to_return); - } - goto error; - } - } - } - else { - final_mod = mod; - Py_INCREF(mod); - } + if (_PySys_ClearAttrString(interp, "path_importer_cache", verbose) < 0) { + PyErr_WriteUnraisable(NULL); } - else { - PyObject *path; - if (_PyObject_LookupAttr(mod, &_Py_ID(__path__), &path) < 0) { - goto error; - } - if (path) { - Py_DECREF(path); - final_mod = PyObject_CallMethodObjArgs( - interp->importlib, &_Py_ID(_handle_fromlist), - mod, fromlist, interp->import_func, NULL); - } - else { - final_mod = mod; - Py_INCREF(mod); - } + if (_PySys_ClearAttrString(interp, "path_hooks", verbose) < 0) { + PyErr_WriteUnraisable(NULL); } +} - error: - Py_XDECREF(abs_name); - Py_XDECREF(mod); - Py_XDECREF(package); - if (final_mod == NULL) { - remove_importlib_frames(tstate); + +/******************/ +/* module helpers */ +/******************/ + +PyObject * +_PyImport_GetModuleAttr(PyObject *modname, PyObject *attrname) +{ + PyObject *mod = PyImport_Import(modname); + if (mod == NULL) { + return NULL; } - return final_mod; + PyObject *result = PyObject_GetAttr(mod, attrname); + Py_DECREF(mod); + return result; } PyObject * -PyImport_ImportModuleLevel(const char *name, PyObject *globals, PyObject *locals, - PyObject *fromlist, int level) +_PyImport_GetModuleAttrString(const char *modname, const char *attrname) { - PyObject *nameobj, *mod; - nameobj = PyUnicode_FromString(name); - if (nameobj == NULL) + PyObject *pmodname = PyUnicode_FromString(modname); + if (pmodname == NULL) { return NULL; - mod = PyImport_ImportModuleLevelObject(nameobj, globals, locals, - fromlist, level); - Py_DECREF(nameobj); - return mod; + } + PyObject *pattrname = PyUnicode_FromString(attrname); + if (pattrname == NULL) { + Py_DECREF(pmodname); + return NULL; + } + PyObject *result = _PyImport_GetModuleAttr(pmodname, pattrname); + Py_DECREF(pattrname); + Py_DECREF(pmodname); + return result; } -/* Re-import a module of any kind and return its module object, WITH - INCREMENTED REFERENCE COUNT */ +/**************/ +/* the module */ +/**************/ -PyObject * -PyImport_ReloadModule(PyObject *m) +/*[clinic input] +_imp.lock_held + +Return True if the import lock is currently held, else False. + +On platforms without threads, return False. +[clinic start generated code]*/ + +static PyObject * +_imp_lock_held_impl(PyObject *module) +/*[clinic end generated code: output=8b89384b5e1963fc input=9b088f9b217d9bdf]*/ { - PyObject *reloaded_module = NULL; - PyObject *importlib = PyImport_GetModule(&_Py_ID(importlib)); - if (importlib == NULL) { - if (PyErr_Occurred()) { - return NULL; - } + PyInterpreterState *interp = _PyInterpreterState_GET(); + return PyBool_FromLong( + IMPORT_LOCK_THREAD(interp) != PYTHREAD_INVALID_THREAD_ID); +} - importlib = PyImport_ImportModule("importlib"); - if (importlib == NULL) { - return NULL; - } - } +/*[clinic input] +_imp.acquire_lock - reloaded_module = PyObject_CallMethodOneArg(importlib, &_Py_ID(reload), m); - Py_DECREF(importlib); - return reloaded_module; +Acquires the interpreter's import lock for the current thread. + +This lock should be used by import hooks to ensure thread-safety when importing +modules. On platforms without threads, this function does nothing. +[clinic start generated code]*/ + +static PyObject * +_imp_acquire_lock_impl(PyObject *module) +/*[clinic end generated code: output=1aff58cb0ee1b026 input=4a2d4381866d5fdc]*/ +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + _PyImport_AcquireLock(interp); + Py_RETURN_NONE; } +/*[clinic input] +_imp.release_lock -/* Higher-level import emulator which emulates the "import" statement - more accurately -- it invokes the __import__() function from the - builtins of the current globals. This means that the import is - done using whatever import hooks are installed in the current - environment. - A dummy list ["__doc__"] is passed as the 4th argument so that - e.g. PyImport_Import(PyUnicode_FromString("win32com.client.gencache")) - will return <module "gencache"> instead of <module "win32com">. */ +Release the interpreter's import lock. -PyObject * -PyImport_Import(PyObject *module_name) +On platforms without threads, this function does nothing. +[clinic start generated code]*/ + +static PyObject * +_imp_release_lock_impl(PyObject *module) +/*[clinic end generated code: output=7faab6d0be178b0a input=934fb11516dd778b]*/ { - PyThreadState *tstate = _PyThreadState_GET(); - PyObject *globals = NULL; - PyObject *import = NULL; - PyObject *builtins = NULL; - PyObject *r = NULL; + PyInterpreterState *interp = _PyInterpreterState_GET(); + if (_PyImport_ReleaseLock(interp) < 0) { + PyErr_SetString(PyExc_RuntimeError, + "not holding the import lock"); + return NULL; + } + Py_RETURN_NONE; +} + + +/*[clinic input] +_imp._fix_co_filename + + code: object(type="PyCodeObject *", subclass_of="&PyCode_Type") + Code object to change. + + path: unicode + File path to use. + / + +Changes code.co_filename to specify the passed-in file path. +[clinic start generated code]*/ + +static PyObject * +_imp__fix_co_filename_impl(PyObject *module, PyCodeObject *code, + PyObject *path) +/*[clinic end generated code: output=1d002f100235587d input=895ba50e78b82f05]*/ + +{ + update_compiled_module(code, path); + + Py_RETURN_NONE; +} - PyObject *from_list = PyList_New(0); - if (from_list == NULL) { - goto err; - } - /* Get the builtins from current globals */ - globals = PyEval_GetGlobals(); - if (globals != NULL) { - Py_INCREF(globals); - builtins = PyObject_GetItem(globals, &_Py_ID(__builtins__)); - if (builtins == NULL) - goto err; - } - else { - /* No globals -- use standard builtins, and fake globals */ - builtins = PyImport_ImportModuleLevel("builtins", - NULL, NULL, NULL, 0); - if (builtins == NULL) { - goto err; - } - globals = Py_BuildValue("{OO}", &_Py_ID(__builtins__), builtins); - if (globals == NULL) - goto err; - } +/*[clinic input] +_imp.create_builtin - /* Get the __import__ function from the builtins */ - if (PyDict_Check(builtins)) { - import = PyObject_GetItem(builtins, &_Py_ID(__import__)); - if (import == NULL) { - _PyErr_SetObject(tstate, PyExc_KeyError, &_Py_ID(__import__)); - } - } - else - import = PyObject_GetAttr(builtins, &_Py_ID(__import__)); - if (import == NULL) - goto err; + spec: object + / - /* Call the __import__ function with the proper argument list - Always use absolute import here. - Calling for side-effect of import. */ - r = PyObject_CallFunction(import, "OOOOi", module_name, globals, - globals, from_list, 0, NULL); - if (r == NULL) - goto err; - Py_DECREF(r); +Create an extension module. +[clinic start generated code]*/ - r = import_get_module(tstate, module_name); - if (r == NULL && !_PyErr_Occurred(tstate)) { - _PyErr_SetObject(tstate, PyExc_KeyError, module_name); +static PyObject * +_imp_create_builtin(PyObject *module, PyObject *spec) +/*[clinic end generated code: output=ace7ff22271e6f39 input=37f966f890384e47]*/ +{ + PyThreadState *tstate = _PyThreadState_GET(); + + PyObject *name = PyObject_GetAttrString(spec, "name"); + if (name == NULL) { + return NULL; } - err: - Py_XDECREF(globals); - Py_XDECREF(builtins); - Py_XDECREF(import); - Py_XDECREF(from_list); + if (!PyUnicode_Check(name)) { + PyErr_Format(PyExc_TypeError, + "name must be string, not %.200s", + Py_TYPE(name)->tp_name); + Py_DECREF(name); + return NULL; + } - return r; + PyObject *mod = create_builtin(tstate, name, spec); + Py_DECREF(name); + return mod; } + /*[clinic input] _imp.extension_suffixes @@ -2209,7 +3581,8 @@ _imp_get_frozen_object_impl(PyObject *module, PyObject *name, return NULL; } - PyObject *codeobj = unmarshal_frozen_code(&info); + PyInterpreterState *interp = _PyInterpreterState_GET(); + PyObject *codeobj = unmarshal_frozen_code(interp, &info); if (dataobj != Py_None) { PyBuffer_Release(&buf); } @@ -2305,32 +3678,36 @@ _imp__override_frozen_modules_for_tests_impl(PyObject *module, int override) /*[clinic end generated code: output=36d5cb1594160811 input=8f1f95a3ef21aec3]*/ { PyInterpreterState *interp = _PyInterpreterState_GET(); - interp->override_frozen_modules = override; + OVERRIDE_FROZEN_MODULES(interp) = override; Py_RETURN_NONE; } -/* Common implementation for _imp.exec_dynamic and _imp.exec_builtin */ -static int -exec_builtin_or_dynamic(PyObject *mod) { - PyModuleDef *def; - void *state; +/*[clinic input] +_imp._override_multi_interp_extensions_check - if (!PyModule_Check(mod)) { - return 0; - } + override: int + / - def = PyModule_GetDef(mod); - if (def == NULL) { - return 0; - } +(internal-only) Override PyInterpreterConfig.check_multi_interp_extensions. - state = PyModule_GetState(mod); - if (state) { - /* Already initialized; skip reload */ - return 0; - } +(-1: "never", 1: "always", 0: no override) +[clinic start generated code]*/ - return PyModule_ExecDef(mod, def); +static PyObject * +_imp__override_multi_interp_extensions_check_impl(PyObject *module, + int override) +/*[clinic end generated code: output=3ff043af52bbf280 input=e086a2ea181f92ae]*/ +{ + PyInterpreterState *interp = _PyInterpreterState_GET(); + if (_Py_IsMainInterpreter(interp)) { + PyErr_SetString(PyExc_RuntimeError, + "_imp._override_multi_interp_extensions_check() " + "cannot be used in the main interpreter"); + return NULL; + } + int oldvalue = OVERRIDE_MULTI_INTERP_EXTENSIONS_CHECK(interp); + OVERRIDE_MULTI_INTERP_EXTENSIONS_CHECK(interp) = override; + return PyLong_FromLong(oldvalue); } #ifdef HAVE_DYNAMIC_LOADING @@ -2365,18 +3742,15 @@ _imp_create_dynamic_impl(PyObject *module, PyObject *spec, PyObject *file) PyThreadState *tstate = _PyThreadState_GET(); mod = import_find_extension(tstate, name, path); - if (mod != NULL || PyErr_Occurred()) { - Py_DECREF(name); - Py_DECREF(path); - return mod; + if (mod != NULL || _PyErr_Occurred(tstate)) { + assert(mod == NULL || !_PyErr_Occurred(tstate)); + goto finally; } if (file != NULL) { fp = _Py_fopen_obj(path, "r"); if (fp == NULL) { - Py_DECREF(name); - Py_DECREF(path); - return NULL; + goto finally; } } else @@ -2384,10 +3758,12 @@ _imp_create_dynamic_impl(PyObject *module, PyObject *spec, PyObject *file) mod = _PyImport_LoadDynamicModuleWithSpec(spec, fp); - Py_DECREF(name); - Py_DECREF(path); if (fp) fclose(fp); + +finally: + Py_DECREF(name); + Py_DECREF(path); return mod; } @@ -2456,7 +3832,7 @@ _imp_source_hash_impl(PyObject *module, long key, Py_buffer *source) PyDoc_STRVAR(doc_imp, -"(Extremely) low-level import machinery bits as used by importlib and imp."); +"(Extremely) low-level import machinery bits as used by importlib."); static PyMethodDef imp_methods[] = { _IMP_EXTENSION_SUFFIXES_METHODDEF @@ -2472,6 +3848,7 @@ static PyMethodDef imp_methods[] = { _IMP_IS_FROZEN_METHODDEF _IMP__FROZEN_MODULE_NAMES_METHODDEF _IMP__OVERRIDE_FROZEN_MODULES_FOR_TESTS_METHODDEF + _IMP__OVERRIDE_MULTI_INTERP_EXTENSIONS_CHECK_METHODDEF _IMP_CREATE_DYNAMIC_METHODDEF _IMP_EXEC_DYNAMIC_METHODDEF _IMP_EXEC_BUILTIN_METHODDEF @@ -2501,6 +3878,7 @@ imp_module_exec(PyObject *module) static PyModuleDef_Slot imp_slots[] = { {Py_mod_exec, imp_module_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; @@ -2520,150 +3898,6 @@ PyInit__imp(void) } -// Import the _imp extension by calling manually _imp.create_builtin() and -// _imp.exec_builtin() since importlib is not initialized yet. Initializing -// importlib requires the _imp module: this function fix the bootstrap issue. -PyObject* -_PyImport_BootstrapImp(PyThreadState *tstate) -{ - PyObject *name = PyUnicode_FromString("_imp"); - if (name == NULL) { - return NULL; - } - - // Mock a ModuleSpec object just good enough for PyModule_FromDefAndSpec(): - // an object with just a name attribute. - // - // _imp.__spec__ is overridden by importlib._bootstrap._instal() anyway. - PyObject *attrs = Py_BuildValue("{sO}", "name", name); - if (attrs == NULL) { - goto error; - } - PyObject *spec = _PyNamespace_New(attrs); - Py_DECREF(attrs); - if (spec == NULL) { - goto error; - } - - // Create the _imp module from its definition. - PyObject *mod = create_builtin(tstate, name, spec); - Py_CLEAR(name); - Py_DECREF(spec); - if (mod == NULL) { - goto error; - } - assert(mod != Py_None); // not found - - // Execute the _imp module: call imp_module_exec(). - if (exec_builtin_or_dynamic(mod) < 0) { - Py_DECREF(mod); - goto error; - } - return mod; - -error: - Py_XDECREF(name); - return NULL; -} - - -/* API for embedding applications that want to add their own entries - to the table of built-in modules. This should normally be called - *before* Py_Initialize(). When the table resize fails, -1 is - returned and the existing table is unchanged. - - After a similar function by Just van Rossum. */ - -int -PyImport_ExtendInittab(struct _inittab *newtab) -{ - struct _inittab *p; - size_t i, n; - int res = 0; - - /* Count the number of entries in both tables */ - for (n = 0; newtab[n].name != NULL; n++) - ; - if (n == 0) - return 0; /* Nothing to do */ - for (i = 0; PyImport_Inittab[i].name != NULL; i++) - ; - - /* Force default raw memory allocator to get a known allocator to be able - to release the memory in _PyImport_Fini2() */ - PyMemAllocatorEx old_alloc; - _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - - /* Allocate new memory for the combined table */ - p = NULL; - if (i + n <= SIZE_MAX / sizeof(struct _inittab) - 1) { - size_t size = sizeof(struct _inittab) * (i + n + 1); - p = PyMem_RawRealloc(inittab_copy, size); - } - if (p == NULL) { - res = -1; - goto done; - } - - /* Copy the tables into the new memory at the first call - to PyImport_ExtendInittab(). */ - if (inittab_copy != PyImport_Inittab) { - memcpy(p, PyImport_Inittab, (i+1) * sizeof(struct _inittab)); - } - memcpy(p + i, newtab, (n + 1) * sizeof(struct _inittab)); - PyImport_Inittab = inittab_copy = p; - -done: - PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - return res; -} - -/* Shorthand to add a single entry given a name and a function */ - -int -PyImport_AppendInittab(const char *name, PyObject* (*initfunc)(void)) -{ - struct _inittab newtab[2]; - - memset(newtab, '\0', sizeof newtab); - - newtab[0].name = name; - newtab[0].initfunc = initfunc; - - return PyImport_ExtendInittab(newtab); -} - - -PyObject * -_PyImport_GetModuleAttr(PyObject *modname, PyObject *attrname) -{ - PyObject *mod = PyImport_Import(modname); - if (mod == NULL) { - return NULL; - } - PyObject *result = PyObject_GetAttr(mod, attrname); - Py_DECREF(mod); - return result; -} - -PyObject * -_PyImport_GetModuleAttrString(const char *modname, const char *attrname) -{ - PyObject *pmodname = PyUnicode_FromString(modname); - if (pmodname == NULL) { - return NULL; - } - PyObject *pattrname = PyUnicode_FromString(attrname); - if (pattrname == NULL) { - Py_DECREF(pmodname); - return NULL; - } - PyObject *result = _PyImport_GetModuleAttr(pmodname, pattrname); - Py_DECREF(pattrname); - Py_DECREF(pmodname); - return result; -} - #ifdef __cplusplus } #endif diff --git a/Python/importdl.c b/Python/importdl.c index 870ae273..3a3a30dd 100644 --- a/Python/importdl.c +++ b/Python/importdl.c @@ -3,6 +3,7 @@ #include "Python.h" #include "pycore_call.h" +#include "pycore_import.h" #include "pycore_pystate.h" #include "pycore_runtime.h" @@ -99,7 +100,7 @@ _PyImport_LoadDynamicModuleWithSpec(PyObject *spec, FILE *fp) #endif PyObject *name_unicode = NULL, *name = NULL, *path = NULL, *m = NULL; const char *name_buf, *hook_prefix; - const char *oldcontext; + const char *oldcontext, *newcontext; dl_funcptr exportfunc; PyModuleDef *def; PyModInitFunction p0; @@ -113,6 +114,10 @@ _PyImport_LoadDynamicModuleWithSpec(PyObject *spec, FILE *fp) "spec.name must be a string"); goto error; } + newcontext = PyUnicode_AsUTF8(name_unicode); + if (newcontext == NULL) { + goto error; + } name = get_encoded_name(name_unicode, &hook_prefix); if (name == NULL) { @@ -160,14 +165,9 @@ _PyImport_LoadDynamicModuleWithSpec(PyObject *spec, FILE *fp) p0 = (PyModInitFunction)exportfunc; /* Package context is needed for single-phase init */ - oldcontext = _Py_PackageContext; - _Py_PackageContext = PyUnicode_AsUTF8(name_unicode); - if (_Py_PackageContext == NULL) { - _Py_PackageContext = oldcontext; - goto error; - } + oldcontext = _PyImport_SwapPackageContext(newcontext); m = _PyImport_InitFunc_TrampolineCall(p0); - _Py_PackageContext = oldcontext; + _PyImport_SwapPackageContext(oldcontext); if (m == NULL) { if (!PyErr_Occurred()) { @@ -178,8 +178,7 @@ _PyImport_LoadDynamicModuleWithSpec(PyObject *spec, FILE *fp) } goto error; } else if (PyErr_Occurred()) { - PyErr_Clear(); - PyErr_Format( + _PyErr_FormatFromCause( PyExc_SystemError, "initialization of %s raised unreported exception", name_buf); @@ -205,6 +204,10 @@ _PyImport_LoadDynamicModuleWithSpec(PyObject *spec, FILE *fp) /* Fall back to single-phase init mechanism */ + if (_PyImport_CheckSubinterpIncompatibleExtensionAllowed(name_buf) < 0) { + goto error; + } + if (hook_prefix == nonascii_prefix) { /* don't allow legacy init for non-ASCII module names */ PyErr_Format( diff --git a/Python/initconfig.c b/Python/initconfig.c index d81cbaff..4e5d4bb9 100644 --- a/Python/initconfig.c +++ b/Python/initconfig.c @@ -5,7 +5,7 @@ #include "pycore_interp.h" // _PyInterpreterState.runtime #include "pycore_long.h" // _PY_LONG_MAX_STR_DIGITS_THRESHOLD #include "pycore_pathconfig.h" // _Py_path_config -#include "pycore_pyerrors.h" // _PyErr_Fetch() +#include "pycore_pyerrors.h" // _PyErr_GetRaisedException() #include "pycore_pylifecycle.h" // _Py_PreInitializeFromConfig() #include "pycore_pymem.h" // _PyMem_SetDefaultAllocator() #include "pycore_pystate.h" // _PyThreadState_GET() @@ -49,7 +49,7 @@ Options (and corresponding environment variables):\n\ .pyc extension; also PYTHONOPTIMIZE=x\n\ -OO : do -O changes and also discard docstrings; add .opt-2 before\n\ .pyc extension\n\ --P : don't prepend a potentially unsafe path to sys.path\n\ +-P : don't prepend a potentially unsafe path to sys.path; also PYTHONSAFEPATH\n\ -q : don't print version and copyright messages on interactive startup\n\ -s : don't add user site directory to sys.path; also PYTHONNOUSERSITE\n\ -S : don't imply 'import site' on initialization\n\ @@ -119,12 +119,24 @@ The following implementation-specific options are available:\n\ files are desired as well as suppressing the extra visual location indicators \n\ when the interpreter displays tracebacks.\n\ \n\ +-X perf: activate support for the Linux \"perf\" profiler by activating the \"perf\"\n\ + trampoline. When this option is activated, the Linux \"perf\" profiler will be \n\ + able to report Python calls. This option is only available on some platforms and will \n\ + do nothing if is not supported on the current system. The default value is \"off\".\n\ +\n\ -X frozen_modules=[on|off]: whether or not frozen modules should be used.\n\ The default is \"on\" (or \"off\" if you are running a local build).\n\ \n\ -X int_max_str_digits=number: limit the size of int<->str conversions.\n\ This helps avoid denial of service attacks when parsing untrusted data.\n\ - The default is sys.int_info.default_max_str_digits. 0 disables."; + The default is sys.int_info.default_max_str_digits. 0 disables." + +#ifdef Py_STATS +"\n\ +\n\ +-X pystats: Enable pystats collection at startup." +#endif +; /* Envvars that don't have equivalent command-line options are listed first */ static const char usage_envvars[] = @@ -132,7 +144,6 @@ static const char usage_envvars[] = "PYTHONSTARTUP: file executed on interactive startup (no default)\n" "PYTHONPATH : '%lc'-separated list of directories prefixed to the\n" " default module search path. The result is sys.path.\n" -"PYTHONSAFEPATH: don't prepend a potentially unsafe path to sys.path.\n" "PYTHONHOME : alternate <prefix> directory (or <prefix>%lc<exec_prefix>).\n" " The default module search path uses %s.\n" "PYTHONPLATLIBDIR : override sys.platlibdir.\n" @@ -172,6 +183,7 @@ static const char usage_envvars[] = " (-X int_max_str_digits=number)\n" "PYTHONNOUSERSITE : disable user site directory (-s)\n" "PYTHONOPTIMIZE : enable level 1 optimizations (-O)\n" +"PYTHONSAFEPATH : don't prepend a potentially unsafe path to sys.path (-P)\n" "PYTHONUNBUFFERED : disable stdout/stderr buffering (-u)\n" "PYTHONVERBOSE : trace import statements (-v)\n" "PYTHONWARNINGS=arg : warning control (-W arg)\n"; @@ -191,7 +203,7 @@ int Py_UTF8Mode = 0; int Py_DebugFlag = 0; /* Needed by parser.c */ int Py_VerboseFlag = 0; /* Needed by import.c */ int Py_QuietFlag = 0; /* Needed by sysmodule.c */ -int Py_InteractiveFlag = 0; /* Needed by Py_FdIsInteractive() below */ +int Py_InteractiveFlag = 0; /* Previously, was used by Py_FdIsInteractive() */ int Py_InspectFlag = 0; /* Needed to determine whether to exit at SystemExit */ int Py_OptimizeFlag = 0; /* Needed by compile.c */ int Py_NoSiteFlag = 0; /* Suppress 'import site' */ @@ -212,6 +224,8 @@ int Py_LegacyWindowsStdioFlag = 0; /* Uses FileIO instead of WindowsConsoleIO */ static PyObject * _Py_GetGlobalVariablesAsDict(void) { +_Py_COMP_DIAG_PUSH +_Py_COMP_DIAG_IGNORE_DEPR_DECLS PyObject *dict, *obj; dict = PyDict_New(); @@ -236,7 +250,7 @@ _Py_GetGlobalVariablesAsDict(void) #define FROM_STRING(STR) \ ((STR != NULL) ? \ PyUnicode_FromString(STR) \ - : (Py_INCREF(Py_None), Py_None)) + : Py_NewRef(Py_None)) #define SET_ITEM_STR(VAR) \ SET_ITEM(#VAR, FROM_STRING(VAR)) @@ -278,15 +292,19 @@ fail: #undef SET_ITEM #undef SET_ITEM_INT #undef SET_ITEM_STR +_Py_COMP_DIAG_POP } char* Py_GETENV(const char *name) { +_Py_COMP_DIAG_PUSH +_Py_COMP_DIAG_IGNORE_DEPR_DECLS if (Py_IgnoreEnvironmentFlag) { return NULL; } return getenv(name); +_Py_COMP_DIAG_POP } /* --- PyStatus ----------------------------------------------- */ @@ -548,8 +566,11 @@ Py_SetStandardStreamEncoding(const char *encoding, const char *errors) } #ifdef MS_WINDOWS if (_Py_StandardStreamEncoding) { +_Py_COMP_DIAG_PUSH +_Py_COMP_DIAG_IGNORE_DEPR_DECLS /* Overriding the stream encoding implies legacy streams */ Py_LegacyWindowsStdioFlag = 1; +_Py_COMP_DIAG_POP } #endif @@ -583,17 +604,13 @@ _Py_ClearStandardStreamEncoding(void) /* --- Py_GetArgcArgv() ------------------------------------------- */ -/* For Py_GetArgcArgv(); set by _Py_SetArgcArgv() */ -static PyWideStringList orig_argv = {.length = 0, .items = NULL}; - - void _Py_ClearArgcArgv(void) { PyMemAllocatorEx old_alloc; _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - _PyWideStringList_Clear(&orig_argv); + _PyWideStringList_Clear(&_PyRuntime.orig_argv); PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); } @@ -608,7 +625,9 @@ _Py_SetArgcArgv(Py_ssize_t argc, wchar_t * const *argv) PyMemAllocatorEx old_alloc; _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - res = _PyWideStringList_Copy(&orig_argv, &argv_list); + // XXX _PyRuntime.orig_argv only gets cleared by Py_Main(), + // so it it currently leaks for embedders. + res = _PyWideStringList_Copy(&_PyRuntime.orig_argv, &argv_list); PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); return res; @@ -619,8 +638,8 @@ _Py_SetArgcArgv(Py_ssize_t argc, wchar_t * const *argv) void Py_GetArgcArgv(int *argc, wchar_t ***argv) { - *argc = (int)orig_argv.length; - *argv = orig_argv.items; + *argc = (int)_PyRuntime.orig_argv.length; + *argv = _PyRuntime.orig_argv.items; } @@ -683,6 +702,7 @@ config_check_consistency(const PyConfig *config) assert(config->pathconfig_warnings >= 0); assert(config->_is_python_build >= 0); assert(config->safe_path >= 0); + assert(config->int_max_str_digits >= 0); // config->use_frozen_modules is initialized later // by _PyConfig_InitImportConfig(). return 1; @@ -747,6 +767,7 @@ _PyConfig_InitCompatConfig(PyConfig *config) config->use_hash_seed = -1; config->faulthandler = -1; config->tracemalloc = -1; + config->perf_profiling = -1; config->module_search_paths_set = 0; config->parse_argv = 0; config->site_import = -1; @@ -766,7 +787,6 @@ _PyConfig_InitCompatConfig(PyConfig *config) config->check_hash_pycs_mode = NULL; config->pathconfig_warnings = -1; config->_init_main = 1; - config->_isolated_interpreter = 0; #ifdef MS_WINDOWS config->legacy_windows_stdio = -1; #endif @@ -776,14 +796,11 @@ _PyConfig_InitCompatConfig(PyConfig *config) config->use_frozen_modules = 1; #endif config->safe_path = 0; + config->int_max_str_digits = -1; config->_is_python_build = 0; config->code_debug_ranges = 1; } -/* Excluded from public struct PyConfig for backporting reasons. */ -/* default to unconfigured, _PyLong_InitTypes() does the rest */ -int _Py_global_config_int_max_str_digits = -1; - static void config_init_defaults(PyConfig *config) @@ -835,6 +852,8 @@ PyConfig_InitIsolatedConfig(PyConfig *config) config->use_hash_seed = 0; config->faulthandler = 0; config->tracemalloc = 0; + config->perf_profiling = 0; + config->int_max_str_digits = _PY_LONG_DEFAULT_MAX_STR_DIGITS; config->safe_path = 1; config->pathconfig_warnings = 0; #ifdef MS_WINDOWS @@ -946,6 +965,7 @@ _PyConfig_Copy(PyConfig *config, const PyConfig *config2) COPY_ATTR(_install_importlib); COPY_ATTR(faulthandler); COPY_ATTR(tracemalloc); + COPY_ATTR(perf_profiling); COPY_ATTR(import_time); COPY_ATTR(code_debug_ranges); COPY_ATTR(show_ref_count); @@ -1001,11 +1021,11 @@ _PyConfig_Copy(PyConfig *config, const PyConfig *config2) COPY_WSTR_ATTR(check_hash_pycs_mode); COPY_ATTR(pathconfig_warnings); COPY_ATTR(_init_main); - COPY_ATTR(_isolated_interpreter); COPY_ATTR(use_frozen_modules); COPY_ATTR(safe_path); COPY_WSTRLIST(orig_argv); COPY_ATTR(_is_python_build); + COPY_ATTR(int_max_str_digits); #undef COPY_ATTR #undef COPY_WSTR_ATTR @@ -1041,7 +1061,7 @@ _PyConfig_AsDict(const PyConfig *config) #define FROM_WSTRING(STR) \ ((STR != NULL) ? \ PyUnicode_FromWideChar(STR, -1) \ - : (Py_INCREF(Py_None), Py_None)) + : Py_NewRef(Py_None)) #define SET_ITEM_WSTR(ATTR) \ SET_ITEM(#ATTR, FROM_WSTRING(config->ATTR)) #define SET_ITEM_WSTRLIST(LIST) \ @@ -1056,6 +1076,7 @@ _PyConfig_AsDict(const PyConfig *config) SET_ITEM_UINT(hash_seed); SET_ITEM_INT(faulthandler); SET_ITEM_INT(tracemalloc); + SET_ITEM_INT(perf_profiling); SET_ITEM_INT(import_time); SET_ITEM_INT(code_debug_ranges); SET_ITEM_INT(show_ref_count); @@ -1107,11 +1128,11 @@ _PyConfig_AsDict(const PyConfig *config) SET_ITEM_WSTR(check_hash_pycs_mode); SET_ITEM_INT(pathconfig_warnings); SET_ITEM_INT(_init_main); - SET_ITEM_INT(_isolated_interpreter); SET_ITEM_WSTRLIST(orig_argv); SET_ITEM_INT(use_frozen_modules); SET_ITEM_INT(safe_path); SET_ITEM_INT(_is_python_build); + SET_ITEM_INT(int_max_str_digits); return dict; @@ -1301,6 +1322,12 @@ _PyConfig_FromDict(PyConfig *config, PyObject *dict) } \ CHECK_VALUE(#KEY, config->KEY >= 0); \ } while (0) +#define GET_INT(KEY) \ + do { \ + if (config_dict_get_int(dict, #KEY, &config->KEY) < 0) { \ + return -1; \ + } \ + } while (0) #define GET_WSTR(KEY) \ do { \ if (config_dict_get_wstr(dict, #KEY, config, &config->KEY) < 0) { \ @@ -1337,6 +1364,7 @@ _PyConfig_FromDict(PyConfig *config, PyObject *dict) CHECK_VALUE("hash_seed", config->hash_seed <= MAX_HASH_SEED); GET_UINT(faulthandler); GET_UINT(tracemalloc); + GET_UINT(perf_profiling); GET_UINT(import_time); GET_UINT(code_debug_ranges); GET_UINT(show_ref_count); @@ -1394,13 +1422,14 @@ _PyConfig_FromDict(PyConfig *config, PyObject *dict) GET_UINT(_install_importlib); GET_UINT(_init_main); - GET_UINT(_isolated_interpreter); GET_UINT(use_frozen_modules); GET_UINT(safe_path); GET_UINT(_is_python_build); + GET_INT(int_max_str_digits); #undef CHECK_VALUE #undef GET_UINT +#undef GET_INT #undef GET_WSTR #undef GET_WSTR_OPT return 0; @@ -1458,6 +1487,8 @@ config_get_env_dup(PyConfig *config, static void config_get_global_vars(PyConfig *config) { +_Py_COMP_DIAG_PUSH +_Py_COMP_DIAG_IGNORE_DEPR_DECLS if (config->_config_init != _PyConfig_INIT_COMPAT) { /* Python and Isolated configuration ignore global variables */ return; @@ -1493,6 +1524,7 @@ config_get_global_vars(PyConfig *config) #undef COPY_FLAG #undef COPY_NOT_FLAG +_Py_COMP_DIAG_POP } @@ -1500,6 +1532,8 @@ config_get_global_vars(PyConfig *config) static void config_set_global_vars(const PyConfig *config) { +_Py_COMP_DIAG_PUSH +_Py_COMP_DIAG_IGNORE_DEPR_DECLS #define COPY_FLAG(ATTR, VAR) \ if (config->ATTR != -1) { \ VAR = config->ATTR; \ @@ -1534,6 +1568,7 @@ config_set_global_vars(const PyConfig *config) #undef COPY_FLAG #undef COPY_NOT_FLAG +_Py_COMP_DIAG_POP } @@ -1687,6 +1722,26 @@ config_read_env_vars(PyConfig *config) return _PyStatus_OK(); } +static PyStatus +config_init_perf_profiling(PyConfig *config) +{ + int active = 0; + const char *env = config_get_env(config, "PYTHONPERFSUPPORT"); + if (env) { + if (_Py_str_to_int(env, &active) != 0) { + active = 0; + } + if (active) { + config->perf_profiling = 1; + } + } + const wchar_t *xoption = config_get_xoption(config, L"perf"); + if (xoption) { + config->perf_profiling = 1; + } + return _PyStatus_OK(); + +} static PyStatus config_init_tracemalloc(PyConfig *config) @@ -1739,7 +1794,7 @@ config_init_int_max_str_digits(PyConfig *config) const char *env = config_get_env(config, "PYTHONINTMAXSTRDIGITS"); if (env) { - int valid = 0; + bool valid = 0; if (!_Py_str_to_int(env, &maxdigits)) { valid = ((maxdigits == 0) || (maxdigits >= _PY_LONG_MAX_STR_DIGITS_THRESHOLD)); } @@ -1751,13 +1806,13 @@ config_init_int_max_str_digits(PyConfig *config) STRINGIFY(_PY_LONG_MAX_STR_DIGITS_THRESHOLD) " or 0 for unlimited."); } - _Py_global_config_int_max_str_digits = maxdigits; + config->int_max_str_digits = maxdigits; } const wchar_t *xoption = config_get_xoption(config, L"int_max_str_digits"); if (xoption) { const wchar_t *sep = wcschr(xoption, L'='); - int valid = 0; + bool valid = 0; if (sep) { if (!config_wstr_to_int(sep + 1, &maxdigits)) { valid = ((maxdigits == 0) || (maxdigits >= _PY_LONG_MAX_STR_DIGITS_THRESHOLD)); @@ -1771,7 +1826,10 @@ config_init_int_max_str_digits(PyConfig *config) #undef _STRINGIFY #undef STRINGIFY } - _Py_global_config_int_max_str_digits = maxdigits; + config->int_max_str_digits = maxdigits; + } + if (config->int_max_str_digits < 0) { + config->int_max_str_digits = _PY_LONG_DEFAULT_MAX_STR_DIGITS; } return _PyStatus_OK(); } @@ -1831,7 +1889,15 @@ config_read_complex_options(PyConfig *config) return status; } } - if (_Py_global_config_int_max_str_digits < 0) { + + if (config->perf_profiling < 0) { + status = config_init_perf_profiling(config); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + } + + if (config->int_max_str_digits < 0) { status = config_init_int_max_str_digits(config); if (_PyStatus_EXCEPTION(status)) { return status; @@ -2129,6 +2195,12 @@ config_read(PyConfig *config, int compute_path_config) config->show_ref_count = 1; } +#ifdef Py_STATS + if (config_get_xoption(config, L"pystats")) { + _py_stats = &_py_stats_struct; + } +#endif + status = config_read_complex_options(config); if (_PyStatus_EXCEPTION(status)) { return status; @@ -2153,6 +2225,9 @@ config_read(PyConfig *config, int compute_path_config) if (config->tracemalloc < 0) { config->tracemalloc = 0; } + if (config->perf_profiling < 0) { + config->perf_profiling = 0; + } if (config->use_hash_seed < 0) { config->use_hash_seed = 0; config->hash_seed = 0; @@ -2280,13 +2355,13 @@ config_usage(int error, const wchar_t* program) } static void -config_envvars_usage() +config_envvars_usage(void) { printf(usage_envvars, (wint_t)DELIM, (wint_t)DELIM, PYTHONHOMEHELP); } static void -config_xoptions_usage() +config_xoptions_usage(void) { puts(usage_xoptions); } @@ -3068,8 +3143,7 @@ init_dump_ascii_wstr(const wchar_t *str) void _Py_DumpPathConfig(PyThreadState *tstate) { - PyObject *exc_type, *exc_value, *exc_tb; - _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb); + PyObject *exc = _PyErr_GetRaisedException(tstate); PySys_WriteStderr("Python path configuration:\n"); @@ -3127,5 +3201,5 @@ _Py_DumpPathConfig(PyThreadState *tstate) PySys_WriteStderr(" ]\n"); } - _PyErr_Restore(tstate, exc_type, exc_value, exc_tb); + _PyErr_SetRaisedException(tstate, exc); } diff --git a/Python/instrumentation.c b/Python/instrumentation.c new file mode 100644 index 00000000..a6ff7a8a --- /dev/null +++ b/Python/instrumentation.c @@ -0,0 +1,2178 @@ + + + + +#include "Python.h" +#include "pycore_call.h" +#include "pycore_frame.h" +#include "pycore_interp.h" +#include "pycore_long.h" +#include "pycore_namespace.h" +#include "pycore_object.h" +#include "pycore_opcode.h" +#include "pycore_pyerrors.h" +#include "pycore_pystate.h" + +/* Uncomment this to dump debugging output when assertions fail */ +// #define INSTRUMENT_DEBUG 1 + +PyObject _PyInstrumentation_DISABLE = +{ + .ob_refcnt = _Py_IMMORTAL_REFCNT, + .ob_type = &PyBaseObject_Type +}; + +PyObject _PyInstrumentation_MISSING = +{ + .ob_refcnt = _Py_IMMORTAL_REFCNT, + .ob_type = &PyBaseObject_Type +}; + +static const int8_t EVENT_FOR_OPCODE[256] = { + [RETURN_CONST] = PY_MONITORING_EVENT_PY_RETURN, + [INSTRUMENTED_RETURN_CONST] = PY_MONITORING_EVENT_PY_RETURN, + [RETURN_VALUE] = PY_MONITORING_EVENT_PY_RETURN, + [INSTRUMENTED_RETURN_VALUE] = PY_MONITORING_EVENT_PY_RETURN, + [CALL] = PY_MONITORING_EVENT_CALL, + [INSTRUMENTED_CALL] = PY_MONITORING_EVENT_CALL, + [CALL_FUNCTION_EX] = PY_MONITORING_EVENT_CALL, + [INSTRUMENTED_CALL_FUNCTION_EX] = PY_MONITORING_EVENT_CALL, + [LOAD_SUPER_ATTR] = PY_MONITORING_EVENT_CALL, + [INSTRUMENTED_LOAD_SUPER_ATTR] = PY_MONITORING_EVENT_CALL, + [RESUME] = -1, + [YIELD_VALUE] = PY_MONITORING_EVENT_PY_YIELD, + [INSTRUMENTED_YIELD_VALUE] = PY_MONITORING_EVENT_PY_YIELD, + [JUMP_FORWARD] = PY_MONITORING_EVENT_JUMP, + [JUMP_BACKWARD] = PY_MONITORING_EVENT_JUMP, + [POP_JUMP_IF_FALSE] = PY_MONITORING_EVENT_BRANCH, + [POP_JUMP_IF_TRUE] = PY_MONITORING_EVENT_BRANCH, + [POP_JUMP_IF_NONE] = PY_MONITORING_EVENT_BRANCH, + [POP_JUMP_IF_NOT_NONE] = PY_MONITORING_EVENT_BRANCH, + [INSTRUMENTED_JUMP_FORWARD] = PY_MONITORING_EVENT_JUMP, + [INSTRUMENTED_JUMP_BACKWARD] = PY_MONITORING_EVENT_JUMP, + [INSTRUMENTED_POP_JUMP_IF_FALSE] = PY_MONITORING_EVENT_BRANCH, + [INSTRUMENTED_POP_JUMP_IF_TRUE] = PY_MONITORING_EVENT_BRANCH, + [INSTRUMENTED_POP_JUMP_IF_NONE] = PY_MONITORING_EVENT_BRANCH, + [INSTRUMENTED_POP_JUMP_IF_NOT_NONE] = PY_MONITORING_EVENT_BRANCH, + [FOR_ITER] = PY_MONITORING_EVENT_BRANCH, + [INSTRUMENTED_FOR_ITER] = PY_MONITORING_EVENT_BRANCH, + [END_FOR] = PY_MONITORING_EVENT_STOP_ITERATION, + [INSTRUMENTED_END_FOR] = PY_MONITORING_EVENT_STOP_ITERATION, + [END_SEND] = PY_MONITORING_EVENT_STOP_ITERATION, + [INSTRUMENTED_END_SEND] = PY_MONITORING_EVENT_STOP_ITERATION, +}; + +static const uint8_t DE_INSTRUMENT[256] = { + [INSTRUMENTED_RESUME] = RESUME, + [INSTRUMENTED_RETURN_VALUE] = RETURN_VALUE, + [INSTRUMENTED_RETURN_CONST] = RETURN_CONST, + [INSTRUMENTED_CALL] = CALL, + [INSTRUMENTED_CALL_FUNCTION_EX] = CALL_FUNCTION_EX, + [INSTRUMENTED_YIELD_VALUE] = YIELD_VALUE, + [INSTRUMENTED_JUMP_FORWARD] = JUMP_FORWARD, + [INSTRUMENTED_JUMP_BACKWARD] = JUMP_BACKWARD, + [INSTRUMENTED_POP_JUMP_IF_FALSE] = POP_JUMP_IF_FALSE, + [INSTRUMENTED_POP_JUMP_IF_TRUE] = POP_JUMP_IF_TRUE, + [INSTRUMENTED_POP_JUMP_IF_NONE] = POP_JUMP_IF_NONE, + [INSTRUMENTED_POP_JUMP_IF_NOT_NONE] = POP_JUMP_IF_NOT_NONE, + [INSTRUMENTED_FOR_ITER] = FOR_ITER, + [INSTRUMENTED_END_FOR] = END_FOR, + [INSTRUMENTED_END_SEND] = END_SEND, + [INSTRUMENTED_LOAD_SUPER_ATTR] = LOAD_SUPER_ATTR, +}; + +static const uint8_t INSTRUMENTED_OPCODES[256] = { + [RETURN_CONST] = INSTRUMENTED_RETURN_CONST, + [INSTRUMENTED_RETURN_CONST] = INSTRUMENTED_RETURN_CONST, + [RETURN_VALUE] = INSTRUMENTED_RETURN_VALUE, + [INSTRUMENTED_RETURN_VALUE] = INSTRUMENTED_RETURN_VALUE, + [CALL] = INSTRUMENTED_CALL, + [INSTRUMENTED_CALL] = INSTRUMENTED_CALL, + [CALL_FUNCTION_EX] = INSTRUMENTED_CALL_FUNCTION_EX, + [INSTRUMENTED_CALL_FUNCTION_EX] = INSTRUMENTED_CALL_FUNCTION_EX, + [YIELD_VALUE] = INSTRUMENTED_YIELD_VALUE, + [INSTRUMENTED_YIELD_VALUE] = INSTRUMENTED_YIELD_VALUE, + [RESUME] = INSTRUMENTED_RESUME, + [INSTRUMENTED_RESUME] = INSTRUMENTED_RESUME, + [JUMP_FORWARD] = INSTRUMENTED_JUMP_FORWARD, + [INSTRUMENTED_JUMP_FORWARD] = INSTRUMENTED_JUMP_FORWARD, + [JUMP_BACKWARD] = INSTRUMENTED_JUMP_BACKWARD, + [INSTRUMENTED_JUMP_BACKWARD] = INSTRUMENTED_JUMP_BACKWARD, + [POP_JUMP_IF_FALSE] = INSTRUMENTED_POP_JUMP_IF_FALSE, + [INSTRUMENTED_POP_JUMP_IF_FALSE] = INSTRUMENTED_POP_JUMP_IF_FALSE, + [POP_JUMP_IF_TRUE] = INSTRUMENTED_POP_JUMP_IF_TRUE, + [INSTRUMENTED_POP_JUMP_IF_TRUE] = INSTRUMENTED_POP_JUMP_IF_TRUE, + [POP_JUMP_IF_NONE] = INSTRUMENTED_POP_JUMP_IF_NONE, + [INSTRUMENTED_POP_JUMP_IF_NONE] = INSTRUMENTED_POP_JUMP_IF_NONE, + [POP_JUMP_IF_NOT_NONE] = INSTRUMENTED_POP_JUMP_IF_NOT_NONE, + [INSTRUMENTED_POP_JUMP_IF_NOT_NONE] = INSTRUMENTED_POP_JUMP_IF_NOT_NONE, + [END_FOR] = INSTRUMENTED_END_FOR, + [INSTRUMENTED_END_FOR] = INSTRUMENTED_END_FOR, + [END_SEND] = INSTRUMENTED_END_SEND, + [INSTRUMENTED_END_SEND] = INSTRUMENTED_END_SEND, + [FOR_ITER] = INSTRUMENTED_FOR_ITER, + [INSTRUMENTED_FOR_ITER] = INSTRUMENTED_FOR_ITER, + [LOAD_SUPER_ATTR] = INSTRUMENTED_LOAD_SUPER_ATTR, + [INSTRUMENTED_LOAD_SUPER_ATTR] = INSTRUMENTED_LOAD_SUPER_ATTR, + + [INSTRUMENTED_LINE] = INSTRUMENTED_LINE, + [INSTRUMENTED_INSTRUCTION] = INSTRUMENTED_INSTRUCTION, +}; + +static inline bool +opcode_has_event(int opcode) +{ + return ( + opcode < INSTRUMENTED_LINE && + INSTRUMENTED_OPCODES[opcode] > 0 + ); +} + +static inline bool +is_instrumented(int opcode) +{ + assert(opcode != 0); + assert(opcode != RESERVED); + return opcode >= MIN_INSTRUMENTED_OPCODE; +} + +#ifndef NDEBUG +static inline bool +monitors_equals(_Py_LocalMonitors a, _Py_LocalMonitors b) +{ + for (int i = 0; i < _PY_MONITORING_LOCAL_EVENTS; i++) { + if (a.tools[i] != b.tools[i]) { + return false; + } + } + return true; +} +#endif + +static inline _Py_LocalMonitors +monitors_sub(_Py_LocalMonitors a, _Py_LocalMonitors b) +{ + _Py_LocalMonitors res; + for (int i = 0; i < _PY_MONITORING_LOCAL_EVENTS; i++) { + res.tools[i] = a.tools[i] & ~b.tools[i]; + } + return res; +} + +#ifndef NDEBUG +static inline _Py_LocalMonitors +monitors_and(_Py_LocalMonitors a, _Py_LocalMonitors b) +{ + _Py_LocalMonitors res; + for (int i = 0; i < _PY_MONITORING_LOCAL_EVENTS; i++) { + res.tools[i] = a.tools[i] & b.tools[i]; + } + return res; +} +#endif + +/* The union of the *local* events in a and b. + * Global events like RAISE are ignored. + * Used for instrumentation, as only local + * events get instrumented. + */ +static inline _Py_LocalMonitors +local_union(_Py_GlobalMonitors a, _Py_LocalMonitors b) +{ + _Py_LocalMonitors res; + for (int i = 0; i < _PY_MONITORING_LOCAL_EVENTS; i++) { + res.tools[i] = a.tools[i] | b.tools[i]; + } + return res; +} + +static inline bool +monitors_are_empty(_Py_LocalMonitors m) +{ + for (int i = 0; i < _PY_MONITORING_LOCAL_EVENTS; i++) { + if (m.tools[i]) { + return false; + } + } + return true; +} + +static inline bool +multiple_tools(_Py_LocalMonitors *m) +{ + for (int i = 0; i < _PY_MONITORING_LOCAL_EVENTS; i++) { + if (_Py_popcount32(m->tools[i]) > 1) { + return true; + } + } + return false; +} + +static inline _PyMonitoringEventSet +get_local_events(_Py_LocalMonitors *m, int tool_id) +{ + _PyMonitoringEventSet result = 0; + for (int e = 0; e < _PY_MONITORING_LOCAL_EVENTS; e++) { + if ((m->tools[e] >> tool_id) & 1) { + result |= (1 << e); + } + } + return result; +} + +static inline _PyMonitoringEventSet +get_events(_Py_GlobalMonitors *m, int tool_id) +{ + _PyMonitoringEventSet result = 0; + for (int e = 0; e < _PY_MONITORING_UNGROUPED_EVENTS; e++) { + if ((m->tools[e] >> tool_id) & 1) { + result |= (1 << e); + } + } + return result; +} + +/* Line delta. + * 8 bit value. + * if line_delta == -128: + * line = None # represented as -1 + * elif line_delta == -127: + * line = PyCode_Addr2Line(code, offset * sizeof(_Py_CODEUNIT)); + * else: + * line = first_line + (offset >> OFFSET_SHIFT) + line_delta; + */ + +#define NO_LINE -128 +#define COMPUTED_LINE -127 + +#define OFFSET_SHIFT 4 + +static int8_t +compute_line_delta(PyCodeObject *code, int offset, int line) +{ + if (line < 0) { + return NO_LINE; + } + int delta = line - code->co_firstlineno - (offset >> OFFSET_SHIFT); + if (delta <= INT8_MAX && delta > COMPUTED_LINE) { + return delta; + } + return COMPUTED_LINE; +} + +static int +compute_line(PyCodeObject *code, int offset, int8_t line_delta) +{ + if (line_delta > COMPUTED_LINE) { + return code->co_firstlineno + (offset >> OFFSET_SHIFT) + line_delta; + } + if (line_delta == NO_LINE) { + + return -1; + } + assert(line_delta == COMPUTED_LINE); + /* Look it up */ + return PyCode_Addr2Line(code, offset * sizeof(_Py_CODEUNIT)); +} + +static int +instruction_length(PyCodeObject *code, int offset) +{ + int opcode = _PyCode_CODE(code)[offset].op.code; + assert(opcode != 0); + assert(opcode != RESERVED); + if (opcode == INSTRUMENTED_LINE) { + opcode = code->_co_monitoring->lines[offset].original_opcode; + } + if (opcode == INSTRUMENTED_INSTRUCTION) { + opcode = code->_co_monitoring->per_instruction_opcodes[offset]; + } + int deinstrumented = DE_INSTRUMENT[opcode]; + if (deinstrumented) { + opcode = deinstrumented; + } + else { + opcode = _PyOpcode_Deopt[opcode]; + } + assert(opcode != 0); + assert(!is_instrumented(opcode)); + assert(opcode == _PyOpcode_Deopt[opcode]); + return 1 + _PyOpcode_Caches[opcode]; +} + +#ifdef INSTRUMENT_DEBUG + +static void +dump_instrumentation_data_tools(PyCodeObject *code, uint8_t *tools, int i, FILE*out) +{ + if (tools == NULL) { + fprintf(out, "tools = NULL"); + } + else { + fprintf(out, "tools = %d", tools[i]); + } +} + +static void +dump_instrumentation_data_lines(PyCodeObject *code, _PyCoLineInstrumentationData *lines, int i, FILE*out) +{ + if (lines == NULL) { + fprintf(out, ", lines = NULL"); + } + else if (lines[i].original_opcode == 0) { + fprintf(out, ", lines = {original_opcode = No LINE (0), line_delta = %d)", lines[i].line_delta); + } + else { + fprintf(out, ", lines = {original_opcode = %s, line_delta = %d)", _PyOpcode_OpName[lines[i].original_opcode], lines[i].line_delta); + } +} + +static void +dump_instrumentation_data_line_tools(PyCodeObject *code, uint8_t *line_tools, int i, FILE*out) +{ + if (line_tools == NULL) { + fprintf(out, ", line_tools = NULL"); + } + else { + fprintf(out, ", line_tools = %d", line_tools[i]); + } +} + +static void +dump_instrumentation_data_per_instruction(PyCodeObject *code, _PyCoMonitoringData *data, int i, FILE*out) +{ + if (data->per_instruction_opcodes == NULL) { + fprintf(out, ", per-inst opcode = NULL"); + } + else { + fprintf(out, ", per-inst opcode = %s", _PyOpcode_OpName[data->per_instruction_opcodes[i]]); + } + if (data->per_instruction_tools == NULL) { + fprintf(out, ", per-inst tools = NULL"); + } + else { + fprintf(out, ", per-inst tools = %d", data->per_instruction_tools[i]); + } +} + +static void +dump_global_monitors(const char *prefix, _Py_GlobalMonitors monitors, FILE*out) +{ + fprintf(out, "%s monitors:\n", prefix); + for (int event = 0; event < _PY_MONITORING_UNGROUPED_EVENTS; event++) { + fprintf(out, " Event %d: Tools %x\n", event, monitors.tools[event]); + } +} + +static void +dump_local_monitors(const char *prefix, _Py_LocalMonitors monitors, FILE*out) +{ + fprintf(out, "%s monitors:\n", prefix); + for (int event = 0; event < _PY_MONITORING_LOCAL_EVENTS; event++) { + fprintf(out, " Event %d: Tools %x\n", event, monitors.tools[event]); + } +} + +/* No error checking -- Don't use this for anything but experimental debugging */ +static void +dump_instrumentation_data(PyCodeObject *code, int star, FILE*out) +{ + _PyCoMonitoringData *data = code->_co_monitoring; + fprintf(out, "\n"); + PyObject_Print(code->co_name, out, Py_PRINT_RAW); + fprintf(out, "\n"); + if (data == NULL) { + fprintf(out, "NULL\n"); + return; + } + dump_global_monitors("Global", _PyInterpreterState_GET()->monitors, out); + dump_local_monitors("Code", data->local_monitors, out); + dump_local_monitors("Active", data->active_monitors, out); + int code_len = (int)Py_SIZE(code); + bool starred = false; + for (int i = 0; i < code_len; i += instruction_length(code, i)) { + _Py_CODEUNIT *instr = &_PyCode_CODE(code)[i]; + int opcode = instr->op.code; + if (i == star) { + fprintf(out, "** "); + starred = true; + } + fprintf(out, "Offset: %d, line: %d %s: ", i, PyCode_Addr2Line(code, i*2), _PyOpcode_OpName[opcode]); + dump_instrumentation_data_tools(code, data->tools, i, out); + dump_instrumentation_data_lines(code, data->lines, i, out); + dump_instrumentation_data_line_tools(code, data->line_tools, i, out); + dump_instrumentation_data_per_instruction(code, data, i, out); + fprintf(out, "\n"); + ; + } + if (!starred && star >= 0) { + fprintf(out, "Error offset not at valid instruction offset: %d\n", star); + fprintf(out, " "); + dump_instrumentation_data_tools(code, data->tools, star, out); + dump_instrumentation_data_lines(code, data->lines, star, out); + dump_instrumentation_data_line_tools(code, data->line_tools, star, out); + dump_instrumentation_data_per_instruction(code, data, star, out); + fprintf(out, "\n"); + } +} + +#define CHECK(test) do { \ + if (!(test)) { \ + dump_instrumentation_data(code, i, stderr); \ + } \ + assert(test); \ +} while (0) + +static bool +valid_opcode(int opcode) +{ + if (opcode > 0 && + opcode != RESERVED && + opcode < 255 && + _PyOpcode_OpName[opcode] && + _PyOpcode_OpName[opcode][0] != '<') + { + return true; + } + return false; +} + +static void +sanity_check_instrumentation(PyCodeObject *code) +{ + _PyCoMonitoringData *data = code->_co_monitoring; + if (data == NULL) { + return; + } + _Py_GlobalMonitors global_monitors = _PyInterpreterState_GET()->monitors; + _Py_LocalMonitors active_monitors; + if (code->_co_monitoring) { + _Py_LocalMonitors local_monitors = code->_co_monitoring->local_monitors; + active_monitors = local_union(global_monitors, local_monitors); + } + else { + _Py_LocalMonitors empty = (_Py_LocalMonitors) { 0 }; + active_monitors = local_union(global_monitors, empty); + } + assert(monitors_equals( + code->_co_monitoring->active_monitors, + active_monitors)); + int code_len = (int)Py_SIZE(code); + for (int i = 0; i < code_len;) { + _Py_CODEUNIT *instr = &_PyCode_CODE(code)[i]; + int opcode = instr->op.code; + int base_opcode = _Py_GetBaseOpcode(code, i); + CHECK(valid_opcode(opcode)); + CHECK(valid_opcode(base_opcode)); + if (opcode == INSTRUMENTED_INSTRUCTION) { + opcode = data->per_instruction_opcodes[i]; + if (!is_instrumented(opcode)) { + CHECK(_PyOpcode_Deopt[opcode] == opcode); + } + if (data->per_instruction_tools) { + uint8_t tools = active_monitors.tools[PY_MONITORING_EVENT_INSTRUCTION]; + CHECK((tools & data->per_instruction_tools[i]) == data->per_instruction_tools[i]); + } + } + if (opcode == INSTRUMENTED_LINE) { + CHECK(data->lines); + CHECK(valid_opcode(data->lines[i].original_opcode)); + opcode = data->lines[i].original_opcode; + CHECK(opcode != END_FOR); + CHECK(opcode != RESUME); + CHECK(opcode != RESUME_CHECK); + CHECK(opcode != INSTRUMENTED_RESUME); + if (!is_instrumented(opcode)) { + CHECK(_PyOpcode_Deopt[opcode] == opcode); + } + CHECK(opcode != INSTRUMENTED_LINE); + } + else if (data->lines) { + /* If original_opcode is INSTRUMENTED_INSTRUCTION + * *and* we are executing a INSTRUMENTED_LINE instruction + * that has de-instrumented itself, then we will execute + * an invalid INSTRUMENTED_INSTRUCTION */ + CHECK(data->lines[i].original_opcode != INSTRUMENTED_INSTRUCTION); + } + if (opcode == INSTRUMENTED_INSTRUCTION) { + CHECK(data->per_instruction_opcodes[i] != 0); + opcode = data->per_instruction_opcodes[i]; + } + if (is_instrumented(opcode)) { + CHECK(DE_INSTRUMENT[opcode] == base_opcode); + int event = EVENT_FOR_OPCODE[DE_INSTRUMENT[opcode]]; + if (event < 0) { + /* RESUME fixup */ + event = instr->op.arg ? 1: 0; + } + CHECK(active_monitors.tools[event] != 0); + } + if (data->lines && base_opcode != END_FOR) { + int line1 = compute_line(code, i, data->lines[i].line_delta); + int line2 = PyCode_Addr2Line(code, i*sizeof(_Py_CODEUNIT)); + CHECK(line1 == line2); + } + CHECK(valid_opcode(opcode)); + if (data->tools) { + uint8_t local_tools = data->tools[i]; + if (opcode_has_event(base_opcode)) { + int event = EVENT_FOR_OPCODE[base_opcode]; + if (event == -1) { + /* RESUME fixup */ + event = _PyCode_CODE(code)[i].op.arg; + } + CHECK((active_monitors.tools[event] & local_tools) == local_tools); + } + else { + CHECK(local_tools == 0xff); + } + } + i += instruction_length(code, i); + assert(i <= code_len); + } +} +#else + +#define CHECK(test) assert(test) + +#endif + +/* Get the underlying opcode, stripping instrumentation */ +int _Py_GetBaseOpcode(PyCodeObject *code, int i) +{ + int opcode = _PyCode_CODE(code)[i].op.code; + if (opcode == INSTRUMENTED_LINE) { + opcode = code->_co_monitoring->lines[i].original_opcode; + } + if (opcode == INSTRUMENTED_INSTRUCTION) { + opcode = code->_co_monitoring->per_instruction_opcodes[i]; + } + CHECK(opcode != INSTRUMENTED_INSTRUCTION); + CHECK(opcode != INSTRUMENTED_LINE); + int deinstrumented = DE_INSTRUMENT[opcode]; + if (deinstrumented) { + return deinstrumented; + } + return _PyOpcode_Deopt[opcode]; +} + +static void +de_instrument(PyCodeObject *code, int i, int event) +{ + assert(event != PY_MONITORING_EVENT_INSTRUCTION); + assert(event != PY_MONITORING_EVENT_LINE); + + _Py_CODEUNIT *instr = &_PyCode_CODE(code)[i]; + uint8_t *opcode_ptr = &instr->op.code; + int opcode = *opcode_ptr; + if (opcode == INSTRUMENTED_LINE) { + opcode_ptr = &code->_co_monitoring->lines[i].original_opcode; + opcode = *opcode_ptr; + } + if (opcode == INSTRUMENTED_INSTRUCTION) { + opcode_ptr = &code->_co_monitoring->per_instruction_opcodes[i]; + opcode = *opcode_ptr; + } + int deinstrumented = DE_INSTRUMENT[opcode]; + if (deinstrumented == 0) { + return; + } + CHECK(_PyOpcode_Deopt[deinstrumented] == deinstrumented); + *opcode_ptr = deinstrumented; + if (_PyOpcode_Caches[deinstrumented]) { + instr[1].cache = adaptive_counter_warmup(); + } +} + +static void +de_instrument_line(PyCodeObject *code, int i) +{ + _Py_CODEUNIT *instr = &_PyCode_CODE(code)[i]; + int opcode = instr->op.code; + if (opcode != INSTRUMENTED_LINE) { + return; + } + _PyCoLineInstrumentationData *lines = &code->_co_monitoring->lines[i]; + int original_opcode = lines->original_opcode; + if (original_opcode == INSTRUMENTED_INSTRUCTION) { + lines->original_opcode = code->_co_monitoring->per_instruction_opcodes[i]; + } + CHECK(original_opcode != 0); + CHECK(original_opcode == _PyOpcode_Deopt[original_opcode]); + instr->op.code = original_opcode; + if (_PyOpcode_Caches[original_opcode]) { + instr[1].cache = adaptive_counter_warmup(); + } + assert(instr->op.code != INSTRUMENTED_LINE); +} + +static void +de_instrument_per_instruction(PyCodeObject *code, int i) +{ + _Py_CODEUNIT *instr = &_PyCode_CODE(code)[i]; + uint8_t *opcode_ptr = &instr->op.code; + int opcode = *opcode_ptr; + if (opcode == INSTRUMENTED_LINE) { + opcode_ptr = &code->_co_monitoring->lines[i].original_opcode; + opcode = *opcode_ptr; + } + if (opcode != INSTRUMENTED_INSTRUCTION) { + return; + } + int original_opcode = code->_co_monitoring->per_instruction_opcodes[i]; + CHECK(original_opcode != 0); + CHECK(original_opcode == _PyOpcode_Deopt[original_opcode]); + *opcode_ptr = original_opcode; + if (_PyOpcode_Caches[original_opcode]) { + instr[1].cache = adaptive_counter_warmup(); + } + assert(*opcode_ptr != INSTRUMENTED_INSTRUCTION); + assert(instr->op.code != INSTRUMENTED_INSTRUCTION); + /* Keep things clean for sanity check */ + code->_co_monitoring->per_instruction_opcodes[i] = 0; +} + + +static void +instrument(PyCodeObject *code, int i) +{ + _Py_CODEUNIT *instr = &_PyCode_CODE(code)[i]; + uint8_t *opcode_ptr = &instr->op.code; + int opcode =*opcode_ptr; + if (opcode == INSTRUMENTED_LINE) { + _PyCoLineInstrumentationData *lines = &code->_co_monitoring->lines[i]; + opcode_ptr = &lines->original_opcode; + opcode = *opcode_ptr; + } + if (opcode == INSTRUMENTED_INSTRUCTION) { + opcode_ptr = &code->_co_monitoring->per_instruction_opcodes[i]; + opcode = *opcode_ptr; + CHECK(opcode != INSTRUMENTED_INSTRUCTION && opcode != INSTRUMENTED_LINE); + CHECK(opcode == _PyOpcode_Deopt[opcode]); + } + CHECK(opcode != 0); + if (!is_instrumented(opcode)) { + int deopt = _PyOpcode_Deopt[opcode]; + int instrumented = INSTRUMENTED_OPCODES[deopt]; + assert(instrumented); + *opcode_ptr = instrumented; + if (_PyOpcode_Caches[deopt]) { + instr[1].cache = adaptive_counter_warmup(); + } + } +} + +static void +instrument_line(PyCodeObject *code, int i) +{ + uint8_t *opcode_ptr = &_PyCode_CODE(code)[i].op.code; + int opcode = *opcode_ptr; + if (opcode == INSTRUMENTED_LINE) { + return; + } + _PyCoLineInstrumentationData *lines = &code->_co_monitoring->lines[i]; + lines->original_opcode = _PyOpcode_Deopt[opcode]; + CHECK(lines->original_opcode > 0); + *opcode_ptr = INSTRUMENTED_LINE; +} + +static void +instrument_per_instruction(PyCodeObject *code, int i) +{ + _Py_CODEUNIT *instr = &_PyCode_CODE(code)[i]; + uint8_t *opcode_ptr = &instr->op.code; + int opcode = *opcode_ptr; + if (opcode == INSTRUMENTED_LINE) { + _PyCoLineInstrumentationData *lines = &code->_co_monitoring->lines[i]; + opcode_ptr = &lines->original_opcode; + opcode = *opcode_ptr; + } + if (opcode == INSTRUMENTED_INSTRUCTION) { + assert(code->_co_monitoring->per_instruction_opcodes[i] > 0); + return; + } + CHECK(opcode != 0); + if (is_instrumented(opcode)) { + code->_co_monitoring->per_instruction_opcodes[i] = opcode; + } + else { + assert(opcode != 0); + assert(_PyOpcode_Deopt[opcode] != 0); + assert(_PyOpcode_Deopt[opcode] != RESUME); + code->_co_monitoring->per_instruction_opcodes[i] = _PyOpcode_Deopt[opcode]; + } + assert(code->_co_monitoring->per_instruction_opcodes[i] > 0); + *opcode_ptr = INSTRUMENTED_INSTRUCTION; +} + +static void +remove_tools(PyCodeObject * code, int offset, int event, int tools) +{ + assert(event != PY_MONITORING_EVENT_LINE); + assert(event != PY_MONITORING_EVENT_INSTRUCTION); + assert(PY_MONITORING_IS_INSTRUMENTED_EVENT(event)); + assert(opcode_has_event(_Py_GetBaseOpcode(code, offset))); + _PyCoMonitoringData *monitoring = code->_co_monitoring; + if (monitoring && monitoring->tools) { + monitoring->tools[offset] &= ~tools; + if (monitoring->tools[offset] == 0) { + de_instrument(code, offset, event); + } + } + else { + /* Single tool */ + uint8_t single_tool = code->_co_monitoring->active_monitors.tools[event]; + assert(_Py_popcount32(single_tool) <= 1); + if (((single_tool & tools) == single_tool)) { + de_instrument(code, offset, event); + } + } +} + +#ifndef NDEBUG +static bool +tools_is_subset_for_event(PyCodeObject * code, int event, int tools) +{ + int global_tools = PyInterpreterState_Get()->monitors.tools[event]; + int local_tools = code->_co_monitoring->local_monitors.tools[event]; + return tools == ((global_tools | local_tools) & tools); +} +#endif + +static void +remove_line_tools(PyCodeObject * code, int offset, int tools) +{ + assert(code->_co_monitoring); + if (code->_co_monitoring->line_tools) + { + uint8_t *toolsptr = &code->_co_monitoring->line_tools[offset]; + *toolsptr &= ~tools; + if (*toolsptr == 0 ) { + de_instrument_line(code, offset); + } + } + else { + /* Single tool */ + uint8_t single_tool = code->_co_monitoring->active_monitors.tools[PY_MONITORING_EVENT_LINE]; + assert(_Py_popcount32(single_tool) <= 1); + if (((single_tool & tools) == single_tool)) { + de_instrument_line(code, offset); + } + } +} + +static void +add_tools(PyCodeObject * code, int offset, int event, int tools) +{ + assert(event != PY_MONITORING_EVENT_LINE); + assert(event != PY_MONITORING_EVENT_INSTRUCTION); + assert(PY_MONITORING_IS_INSTRUMENTED_EVENT(event)); + assert(code->_co_monitoring); + if (code->_co_monitoring && + code->_co_monitoring->tools + ) { + code->_co_monitoring->tools[offset] |= tools; + } + else { + /* Single tool */ + assert(_Py_popcount32(tools) == 1); + assert(tools_is_subset_for_event(code, event, tools)); + } + instrument(code, offset); +} + +static void +add_line_tools(PyCodeObject * code, int offset, int tools) +{ + assert(tools_is_subset_for_event(code, PY_MONITORING_EVENT_LINE, tools)); + assert(code->_co_monitoring); + if (code->_co_monitoring->line_tools) { + code->_co_monitoring->line_tools[offset] |= tools; + } + else { + /* Single tool */ + assert(_Py_popcount32(tools) == 1); + } + instrument_line(code, offset); +} + + +static void +add_per_instruction_tools(PyCodeObject * code, int offset, int tools) +{ + assert(tools_is_subset_for_event(code, PY_MONITORING_EVENT_INSTRUCTION, tools)); + assert(code->_co_monitoring); + if (code->_co_monitoring->per_instruction_tools) { + code->_co_monitoring->per_instruction_tools[offset] |= tools; + } + else { + /* Single tool */ + assert(_Py_popcount32(tools) == 1); + } + instrument_per_instruction(code, offset); +} + + +static void +remove_per_instruction_tools(PyCodeObject * code, int offset, int tools) +{ + assert(code->_co_monitoring); + if (code->_co_monitoring->per_instruction_tools) { + uint8_t *toolsptr = &code->_co_monitoring->per_instruction_tools[offset]; + *toolsptr &= ~tools; + if (*toolsptr == 0) { + de_instrument_per_instruction(code, offset); + } + } + else { + /* Single tool */ + uint8_t single_tool = code->_co_monitoring->active_monitors.tools[PY_MONITORING_EVENT_INSTRUCTION]; + assert(_Py_popcount32(single_tool) <= 1); + if (((single_tool & tools) == single_tool)) { + de_instrument_per_instruction(code, offset); + } + } +} + + +/* Return 1 if DISABLE returned, -1 if error, 0 otherwise */ +static int +call_one_instrument( + PyInterpreterState *interp, PyThreadState *tstate, PyObject **args, + Py_ssize_t nargsf, int8_t tool, int event) +{ + assert(0 <= tool && tool < 8); + assert(tstate->tracing == 0); + PyObject *instrument = interp->monitoring_callables[tool][event]; + if (instrument == NULL) { + return 0; + } + int old_what = tstate->what_event; + tstate->what_event = event; + tstate->tracing++; + PyObject *res = _PyObject_VectorcallTstate(tstate, instrument, args, nargsf, NULL); + tstate->tracing--; + tstate->what_event = old_what; + if (res == NULL) { + return -1; + } + Py_DECREF(res); + return (res == &_PyInstrumentation_DISABLE); +} + +static const int8_t MOST_SIGNIFICANT_BITS[16] = { + -1, 0, 1, 1, + 2, 2, 2, 2, + 3, 3, 3, 3, + 3, 3, 3, 3, +}; + +/* We could use _Py_bit_length here, but that is designed for larger (32/64) + * bit ints, and can perform relatively poorly on platforms without the + * necessary intrinsics. */ +static inline int most_significant_bit(uint8_t bits) { + assert(bits != 0); + if (bits > 15) { + return MOST_SIGNIFICANT_BITS[bits>>4]+4; + } + return MOST_SIGNIFICANT_BITS[bits]; +} + +static bool +is_version_up_to_date(PyCodeObject *code, PyInterpreterState *interp) +{ + return interp->monitoring_version == code->_co_instrumentation_version; +} + +#ifndef NDEBUG +static bool +instrumentation_cross_checks(PyInterpreterState *interp, PyCodeObject *code) +{ + _Py_LocalMonitors expected = local_union( + interp->monitors, + code->_co_monitoring->local_monitors); + return monitors_equals(code->_co_monitoring->active_monitors, expected); +} +#endif + +static inline uint8_t +get_tools_for_instruction(PyCodeObject *code, PyInterpreterState *interp, int i, int event) +{ + uint8_t tools; + assert(event != PY_MONITORING_EVENT_LINE); + assert(event != PY_MONITORING_EVENT_INSTRUCTION); + if (event >= _PY_MONITORING_UNGROUPED_EVENTS) { + assert(event == PY_MONITORING_EVENT_C_RAISE || + event == PY_MONITORING_EVENT_C_RETURN); + event = PY_MONITORING_EVENT_CALL; + } + if (PY_MONITORING_IS_INSTRUMENTED_EVENT(event)) { + CHECK(is_version_up_to_date(code, interp)); + CHECK(instrumentation_cross_checks(interp, code)); + if (code->_co_monitoring->tools) { + tools = code->_co_monitoring->tools[i]; + } + else { + tools = code->_co_monitoring->active_monitors.tools[event]; + } + } + else { + tools = interp->monitors.tools[event]; + } + return tools; +} + +static const char *const event_names [] = { + [PY_MONITORING_EVENT_PY_START] = "PY_START", + [PY_MONITORING_EVENT_PY_RESUME] = "PY_RESUME", + [PY_MONITORING_EVENT_PY_RETURN] = "PY_RETURN", + [PY_MONITORING_EVENT_PY_YIELD] = "PY_YIELD", + [PY_MONITORING_EVENT_CALL] = "CALL", + [PY_MONITORING_EVENT_LINE] = "LINE", + [PY_MONITORING_EVENT_INSTRUCTION] = "INSTRUCTION", + [PY_MONITORING_EVENT_JUMP] = "JUMP", + [PY_MONITORING_EVENT_BRANCH] = "BRANCH", + [PY_MONITORING_EVENT_C_RETURN] = "C_RETURN", + [PY_MONITORING_EVENT_PY_THROW] = "PY_THROW", + [PY_MONITORING_EVENT_RAISE] = "RAISE", + [PY_MONITORING_EVENT_RERAISE] = "RERAISE", + [PY_MONITORING_EVENT_EXCEPTION_HANDLED] = "EXCEPTION_HANDLED", + [PY_MONITORING_EVENT_C_RAISE] = "C_RAISE", + [PY_MONITORING_EVENT_PY_UNWIND] = "PY_UNWIND", + [PY_MONITORING_EVENT_STOP_ITERATION] = "STOP_ITERATION", +}; + +static int +call_instrumentation_vector( + PyThreadState *tstate, int event, + _PyInterpreterFrame *frame, _Py_CODEUNIT *instr, Py_ssize_t nargs, PyObject *args[]) +{ + if (tstate->tracing) { + return 0; + } + assert(!_PyErr_Occurred(tstate)); + assert(args[0] == NULL); + PyCodeObject *code = frame->f_code; + assert(code->_co_instrumentation_version == tstate->interp->monitoring_version); + assert(is_version_up_to_date(code, tstate->interp)); + assert(instrumentation_cross_checks(tstate->interp, code)); + assert(args[1] == NULL); + args[1] = (PyObject *)code; + int offset = (int)(instr - _PyCode_CODE(code)); + /* Offset visible to user should be the offset in bytes, as that is the + * convention for APIs involving code offsets. */ + int bytes_offset = offset * (int)sizeof(_Py_CODEUNIT); + PyObject *offset_obj = PyLong_FromSsize_t(bytes_offset); + if (offset_obj == NULL) { + return -1; + } + assert(args[2] == NULL); + args[2] = offset_obj; + PyInterpreterState *interp = tstate->interp; + uint8_t tools = get_tools_for_instruction(code, interp, offset, event); + Py_ssize_t nargsf = nargs | PY_VECTORCALL_ARGUMENTS_OFFSET; + PyObject **callargs = &args[1]; + int err = 0; + while (tools) { + int tool = most_significant_bit(tools); + assert(tool >= 0 && tool < 8); + assert(tools & (1 << tool)); + tools ^= (1 << tool); + int res = call_one_instrument(interp, tstate, callargs, nargsf, tool, event); + if (res == 0) { + /* Nothing to do */ + } + else if (res < 0) { + /* error */ + err = -1; + break; + } + else { + /* DISABLE */ + if (!PY_MONITORING_IS_INSTRUMENTED_EVENT(event)) { + PyErr_Format(PyExc_ValueError, + "Cannot disable %s events. Callback removed.", + event_names[event]); + /* Clear tool to prevent infinite loop */ + Py_CLEAR(interp->monitoring_callables[tool][event]); + err = -1; + break; + } + else { + remove_tools(code, offset, event, 1 << tool); + } + } + } + Py_DECREF(offset_obj); + return err; +} + +int +_Py_call_instrumentation( + PyThreadState *tstate, int event, + _PyInterpreterFrame *frame, _Py_CODEUNIT *instr) +{ + PyObject *args[3] = { NULL, NULL, NULL }; + return call_instrumentation_vector(tstate, event, frame, instr, 2, args); +} + +int +_Py_call_instrumentation_arg( + PyThreadState *tstate, int event, + _PyInterpreterFrame *frame, _Py_CODEUNIT *instr, PyObject *arg) +{ + PyObject *args[4] = { NULL, NULL, NULL, arg }; + return call_instrumentation_vector(tstate, event, frame, instr, 3, args); +} + +int +_Py_call_instrumentation_2args( + PyThreadState *tstate, int event, + _PyInterpreterFrame *frame, _Py_CODEUNIT *instr, PyObject *arg0, PyObject *arg1) +{ + PyObject *args[5] = { NULL, NULL, NULL, arg0, arg1 }; + return call_instrumentation_vector(tstate, event, frame, instr, 4, args); +} + +_Py_CODEUNIT * +_Py_call_instrumentation_jump( + PyThreadState *tstate, int event, + _PyInterpreterFrame *frame, _Py_CODEUNIT *instr, _Py_CODEUNIT *target) +{ + assert(event == PY_MONITORING_EVENT_JUMP || + event == PY_MONITORING_EVENT_BRANCH); + assert(frame->prev_instr == instr); + /* Event should occur after the jump */ + frame->prev_instr = target; + PyCodeObject *code = frame->f_code; + int to = (int)(target - _PyCode_CODE(code)); + PyObject *to_obj = PyLong_FromLong(to * (int)sizeof(_Py_CODEUNIT)); + if (to_obj == NULL) { + return NULL; + } + PyObject *args[4] = { NULL, NULL, NULL, to_obj }; + int err = call_instrumentation_vector(tstate, event, frame, instr, 3, args); + Py_DECREF(to_obj); + if (err) { + return NULL; + } + if (frame->prev_instr != target) { + /* The callback has caused a jump (by setting the line number) */ + return frame->prev_instr; + } + /* Reset prev_instr for INSTRUMENTED_LINE */ + frame->prev_instr = instr; + return target; +} + +static void +call_instrumentation_vector_protected( + PyThreadState *tstate, int event, + _PyInterpreterFrame *frame, _Py_CODEUNIT *instr, Py_ssize_t nargs, PyObject *args[]) +{ + assert(_PyErr_Occurred(tstate)); + PyObject *exc = _PyErr_GetRaisedException(tstate); + int err = call_instrumentation_vector(tstate, event, frame, instr, nargs, args); + if (err) { + Py_XDECREF(exc); + } + else { + _PyErr_SetRaisedException(tstate, exc); + } + assert(_PyErr_Occurred(tstate)); +} + +void +_Py_call_instrumentation_exc2( + PyThreadState *tstate, int event, + _PyInterpreterFrame *frame, _Py_CODEUNIT *instr, PyObject *arg0, PyObject *arg1) +{ + assert(_PyErr_Occurred(tstate)); + PyObject *args[5] = { NULL, NULL, NULL, arg0, arg1 }; + call_instrumentation_vector_protected(tstate, event, frame, instr, 4, args); +} + + +int +_Py_Instrumentation_GetLine(PyCodeObject *code, int index) +{ + _PyCoMonitoringData *monitoring = code->_co_monitoring; + assert(monitoring != NULL); + assert(monitoring->lines != NULL); + assert(index >= code->_co_firsttraceable); + assert(index < Py_SIZE(code)); + _PyCoLineInstrumentationData *line_data = &monitoring->lines[index]; + int8_t line_delta = line_data->line_delta; + int line = compute_line(code, index, line_delta); + return line; +} + +int +_Py_call_instrumentation_line(PyThreadState *tstate, _PyInterpreterFrame* frame, _Py_CODEUNIT *instr, _Py_CODEUNIT *prev) +{ + frame->prev_instr = instr; + PyCodeObject *code = frame->f_code; + assert(is_version_up_to_date(code, tstate->interp)); + assert(instrumentation_cross_checks(tstate->interp, code)); + int i = (int)(instr - _PyCode_CODE(code)); + + _PyCoMonitoringData *monitoring = code->_co_monitoring; + _PyCoLineInstrumentationData *line_data = &monitoring->lines[i]; + if (tstate->tracing) { + goto done; + } + PyInterpreterState *interp = tstate->interp; + int8_t line_delta = line_data->line_delta; + int line = compute_line(code, i, line_delta); + assert(line >= 0); + int prev_index = (int)(prev - _PyCode_CODE(code)); + int prev_line = _Py_Instrumentation_GetLine(code, prev_index); + if (prev_line == line) { + int prev_opcode = _PyCode_CODE(code)[prev_index].op.code; + /* RESUME and INSTRUMENTED_RESUME are needed for the operation of + * instrumentation, so must never be hidden by an INSTRUMENTED_LINE. + */ + if (prev_opcode != RESUME && prev_opcode != INSTRUMENTED_RESUME) { + goto done; + } + } + uint8_t tools = code->_co_monitoring->line_tools != NULL ? + code->_co_monitoring->line_tools[i] : + (interp->monitors.tools[PY_MONITORING_EVENT_LINE] | + code->_co_monitoring->local_monitors.tools[PY_MONITORING_EVENT_LINE] + ); + PyObject *line_obj = PyLong_FromSsize_t(line); + if (line_obj == NULL) { + return -1; + } + PyObject *args[3] = { NULL, (PyObject *)code, line_obj }; + while (tools) { + int tool = most_significant_bit(tools); + assert(tool >= 0 && tool < 8); + assert(tools & (1 << tool)); + tools &= ~(1 << tool); + int res = call_one_instrument(interp, tstate, &args[1], + 2 | PY_VECTORCALL_ARGUMENTS_OFFSET, + tool, PY_MONITORING_EVENT_LINE); + if (res == 0) { + /* Nothing to do */ + } + else if (res < 0) { + /* error */ + Py_DECREF(line_obj); + return -1; + } + else { + /* DISABLE */ + remove_line_tools(code, i, 1 << tool); + } + } + Py_DECREF(line_obj); + uint8_t original_opcode; +done: + original_opcode = line_data->original_opcode; + assert(original_opcode != 0); + assert(original_opcode < INSTRUMENTED_LINE); + assert(_PyOpcode_Deopt[original_opcode] == original_opcode); + return original_opcode; +} + +int +_Py_call_instrumentation_instruction(PyThreadState *tstate, _PyInterpreterFrame* frame, _Py_CODEUNIT *instr) +{ + PyCodeObject *code = frame->f_code; + assert(is_version_up_to_date(code, tstate->interp)); + assert(instrumentation_cross_checks(tstate->interp, code)); + int offset = (int)(instr - _PyCode_CODE(code)); + _PyCoMonitoringData *instrumentation_data = code->_co_monitoring; + assert(instrumentation_data->per_instruction_opcodes); + int next_opcode = instrumentation_data->per_instruction_opcodes[offset]; + if (tstate->tracing) { + return next_opcode; + } + PyInterpreterState *interp = tstate->interp; + uint8_t tools = instrumentation_data->per_instruction_tools != NULL ? + instrumentation_data->per_instruction_tools[offset] : + (interp->monitors.tools[PY_MONITORING_EVENT_INSTRUCTION] | + code->_co_monitoring->local_monitors.tools[PY_MONITORING_EVENT_INSTRUCTION] + ); + int bytes_offset = offset * (int)sizeof(_Py_CODEUNIT); + PyObject *offset_obj = PyLong_FromSsize_t(bytes_offset); + if (offset_obj == NULL) { + return -1; + } + PyObject *args[3] = { NULL, (PyObject *)code, offset_obj }; + while (tools) { + int tool = most_significant_bit(tools); + assert(tool >= 0 && tool < 8); + assert(tools & (1 << tool)); + tools &= ~(1 << tool); + int res = call_one_instrument(interp, tstate, &args[1], + 2 | PY_VECTORCALL_ARGUMENTS_OFFSET, + tool, PY_MONITORING_EVENT_INSTRUCTION); + if (res == 0) { + /* Nothing to do */ + } + else if (res < 0) { + /* error */ + Py_DECREF(offset_obj); + return -1; + } + else { + /* DISABLE */ + remove_per_instruction_tools(code, offset, 1 << tool); + } + } + Py_DECREF(offset_obj); + assert(next_opcode != 0); + return next_opcode; +} + + +PyObject * +_PyMonitoring_RegisterCallback(int tool_id, int event_id, PyObject *obj) +{ + PyInterpreterState *is = _PyInterpreterState_Get(); + assert(0 <= tool_id && tool_id < PY_MONITORING_TOOL_IDS); + assert(0 <= event_id && event_id < _PY_MONITORING_EVENTS); + PyObject *callback = is->monitoring_callables[tool_id][event_id]; + is->monitoring_callables[tool_id][event_id] = Py_XNewRef(obj); + return callback; +} + +static void +initialize_tools(PyCodeObject *code) +{ + uint8_t* tools = code->_co_monitoring->tools; + assert(tools != NULL); + int code_len = (int)Py_SIZE(code); + for (int i = 0; i < code_len; i++) { + _Py_CODEUNIT *instr = &_PyCode_CODE(code)[i]; + int opcode = instr->op.code; + if (opcode == INSTRUMENTED_LINE) { + opcode = code->_co_monitoring->lines[i].original_opcode; + } + if (opcode == INSTRUMENTED_INSTRUCTION) { + opcode = code->_co_monitoring->per_instruction_opcodes[i]; + } + bool instrumented = is_instrumented(opcode); + if (instrumented) { + opcode = DE_INSTRUMENT[opcode]; + assert(opcode != 0); + } + opcode = _PyOpcode_Deopt[opcode]; + if (opcode_has_event(opcode)) { + if (instrumented) { + int8_t event; + if (opcode == RESUME) { + event = instr->op.arg != 0; + } + else { + event = EVENT_FOR_OPCODE[opcode]; + assert(event > 0); + } + assert(event >= 0); + assert(PY_MONITORING_IS_INSTRUMENTED_EVENT(event)); + tools[i] = code->_co_monitoring->active_monitors.tools[event]; + CHECK(tools[i] != 0); + } + else { + tools[i] = 0; + } + } +#ifdef Py_DEBUG + /* Initialize tools for invalid locations to all ones to try to catch errors */ + else { + tools[i] = 0xff; + } + for (int j = 1; j <= _PyOpcode_Caches[opcode]; j++) { + tools[i+j] = 0xff; + } +#endif + i += _PyOpcode_Caches[opcode]; + } +} + +#define NO_LINE -128 + +static void +initialize_lines(PyCodeObject *code) +{ + _PyCoLineInstrumentationData *line_data = code->_co_monitoring->lines; + assert(line_data != NULL); + int code_len = (int)Py_SIZE(code); + PyCodeAddressRange range; + _PyCode_InitAddressRange(code, &range); + for (int i = 0; i < code->_co_firsttraceable && i < code_len; i++) { + line_data[i].original_opcode = 0; + line_data[i].line_delta = -127; + } + int current_line = -1; + for (int i = code->_co_firsttraceable; i < code_len; ) { + int opcode = _Py_GetBaseOpcode(code, i); + int line = _PyCode_CheckLineNumber(i*(int)sizeof(_Py_CODEUNIT), &range); + line_data[i].line_delta = compute_line_delta(code, i, line); + int length = instruction_length(code, i); + switch (opcode) { + case END_ASYNC_FOR: + case END_FOR: + case END_SEND: + case RESUME: + /* END_FOR cannot start a line, as it is skipped by FOR_ITER + * END_SEND cannot start a line, as it is skipped by SEND + * RESUME must not be instrumented with INSTRUMENT_LINE */ + line_data[i].original_opcode = 0; + break; + default: + /* Set original_opcode to the opcode iff the instruction + * starts a line, and thus should be instrumented. + * This saves having to perform this check every time the + * we turn instrumentation on or off, and serves as a sanity + * check when debugging. + */ + if (line != current_line && line >= 0) { + line_data[i].original_opcode = opcode; + } + else { + line_data[i].original_opcode = 0; + } + current_line = line; + } + for (int j = 1; j < length; j++) { + line_data[i+j].original_opcode = 0; + line_data[i+j].line_delta = NO_LINE; + } + i += length; + } + for (int i = code->_co_firsttraceable; i < code_len; ) { + int opcode = _Py_GetBaseOpcode(code, i); + int oparg = 0; + while (opcode == EXTENDED_ARG) { + oparg = (oparg << 8) | _PyCode_CODE(code)[i].op.arg; + i++; + opcode = _Py_GetBaseOpcode(code, i); + } + oparg = (oparg << 8) | _PyCode_CODE(code)[i].op.arg; + i += instruction_length(code, i); + int target = -1; + switch (opcode) { + case POP_JUMP_IF_FALSE: + case POP_JUMP_IF_TRUE: + case POP_JUMP_IF_NONE: + case POP_JUMP_IF_NOT_NONE: + case JUMP_FORWARD: + { + target = i + oparg; + break; + } + case FOR_ITER: + case SEND: + { + /* Skip over END_FOR/END_SEND */ + target = i + oparg + 1; + break; + } + case JUMP_BACKWARD: + case JUMP_BACKWARD_NO_INTERRUPT: + { + target = i - oparg; + break; + } + default: + continue; + } + assert(target >= 0); + if (line_data[target].line_delta != NO_LINE) { + line_data[target].original_opcode = _Py_GetBaseOpcode(code, target); + } + } + /* Scan exception table */ + unsigned char *start = (unsigned char *)PyBytes_AS_STRING(code->co_exceptiontable); + unsigned char *end = start + PyBytes_GET_SIZE(code->co_exceptiontable); + unsigned char *scan = start; + while (scan < end) { + int start_offset, size, handler; + scan = parse_varint(scan, &start_offset); + assert(start_offset >= 0 && start_offset < code_len); + scan = parse_varint(scan, &size); + assert(size >= 0 && start_offset+size <= code_len); + scan = parse_varint(scan, &handler); + assert(handler >= 0 && handler < code_len); + int depth_and_lasti; + scan = parse_varint(scan, &depth_and_lasti); + int original_opcode = _Py_GetBaseOpcode(code, handler); + /* Skip if not the start of a line. + * END_ASYNC_FOR is a bit special as it marks the end of + * an `async for` loop, which should not generate its own + * line event. */ + if (line_data[handler].line_delta != NO_LINE && + original_opcode != END_ASYNC_FOR) { + line_data[handler].original_opcode = original_opcode; + } + } +} + +static void +initialize_line_tools(PyCodeObject *code, _Py_LocalMonitors *all_events) +{ + uint8_t *line_tools = code->_co_monitoring->line_tools; + assert(line_tools != NULL); + int code_len = (int)Py_SIZE(code); + for (int i = 0; i < code_len; i++) { + line_tools[i] = all_events->tools[PY_MONITORING_EVENT_LINE]; + } +} + +static int +allocate_instrumentation_data(PyCodeObject *code) +{ + + if (code->_co_monitoring == NULL) { + code->_co_monitoring = PyMem_Malloc(sizeof(_PyCoMonitoringData)); + if (code->_co_monitoring == NULL) { + PyErr_NoMemory(); + return -1; + } + code->_co_monitoring->local_monitors = (_Py_LocalMonitors){ 0 }; + code->_co_monitoring->active_monitors = (_Py_LocalMonitors){ 0 }; + code->_co_monitoring->tools = NULL; + code->_co_monitoring->lines = NULL; + code->_co_monitoring->line_tools = NULL; + code->_co_monitoring->per_instruction_opcodes = NULL; + code->_co_monitoring->per_instruction_tools = NULL; + } + return 0; +} + +static int +update_instrumentation_data(PyCodeObject *code, PyInterpreterState *interp) +{ + int code_len = (int)Py_SIZE(code); + if (allocate_instrumentation_data(code)) { + return -1; + } + _Py_LocalMonitors all_events = local_union( + interp->monitors, + code->_co_monitoring->local_monitors); + bool multitools = multiple_tools(&all_events); + if (code->_co_monitoring->tools == NULL && multitools) { + code->_co_monitoring->tools = PyMem_Malloc(code_len); + if (code->_co_monitoring->tools == NULL) { + PyErr_NoMemory(); + return -1; + } + initialize_tools(code); + } + if (all_events.tools[PY_MONITORING_EVENT_LINE]) { + if (code->_co_monitoring->lines == NULL) { + code->_co_monitoring->lines = PyMem_Malloc(code_len * sizeof(_PyCoLineInstrumentationData)); + if (code->_co_monitoring->lines == NULL) { + PyErr_NoMemory(); + return -1; + } + initialize_lines(code); + } + if (multitools && code->_co_monitoring->line_tools == NULL) { + code->_co_monitoring->line_tools = PyMem_Malloc(code_len); + if (code->_co_monitoring->line_tools == NULL) { + PyErr_NoMemory(); + return -1; + } + initialize_line_tools(code, &all_events); + } + } + if (all_events.tools[PY_MONITORING_EVENT_INSTRUCTION]) { + if (code->_co_monitoring->per_instruction_opcodes == NULL) { + code->_co_monitoring->per_instruction_opcodes = PyMem_Malloc(code_len * sizeof(_PyCoLineInstrumentationData)); + if (code->_co_monitoring->per_instruction_opcodes == NULL) { + PyErr_NoMemory(); + return -1; + } + /* This may not be necessary, as we can initialize this memory lazily, but it helps catch errors. */ + for (int i = 0; i < code_len; i++) { + code->_co_monitoring->per_instruction_opcodes[i] = 0; + } + } + if (multitools && code->_co_monitoring->per_instruction_tools == NULL) { + code->_co_monitoring->per_instruction_tools = PyMem_Malloc(code_len); + if (code->_co_monitoring->per_instruction_tools == NULL) { + PyErr_NoMemory(); + return -1; + } + /* This may not be necessary, as we can initialize this memory lazily, but it helps catch errors. */ + for (int i = 0; i < code_len; i++) { + code->_co_monitoring->per_instruction_tools[i] = 0; + } + } + } + return 0; +} + +static const uint8_t super_instructions[256] = { + [LOAD_FAST__LOAD_FAST] = 1, + [LOAD_FAST__LOAD_CONST] = 1, + [STORE_FAST__LOAD_FAST] = 1, + [STORE_FAST__STORE_FAST] = 1, + [LOAD_CONST__LOAD_FAST] = 1, +}; + +/* Should use instruction metadata for this */ +static bool +is_super_instruction(uint8_t opcode) { + return super_instructions[opcode] != 0; +} + +int +_Py_Instrument(PyCodeObject *code, PyInterpreterState *interp) +{ + + if (is_version_up_to_date(code, interp)) { + assert( + interp->monitoring_version == 0 || + instrumentation_cross_checks(interp, code) + ); + return 0; + } + int code_len = (int)Py_SIZE(code); + /* code->_co_firsttraceable >= code_len indicates + * that no instrumentation can be inserted. + * Exit early to avoid creating instrumentation + * data for potential statically allocated code + * objects. + * See https://github.com/python/cpython/issues/108390 */ + if (code->_co_firsttraceable >= code_len) { + return 0; + } + if (update_instrumentation_data(code, interp)) { + return -1; + } + _Py_LocalMonitors active_events = local_union( + interp->monitors, + code->_co_monitoring->local_monitors); + _Py_LocalMonitors new_events; + _Py_LocalMonitors removed_events; + + bool restarted = interp->last_restart_version > code->_co_instrumentation_version; + if (restarted) { + removed_events = code->_co_monitoring->active_monitors; + new_events = active_events; + } + else { + removed_events = monitors_sub(code->_co_monitoring->active_monitors, active_events); + new_events = monitors_sub(active_events, code->_co_monitoring->active_monitors); + assert(monitors_are_empty(monitors_and(new_events, removed_events))); + } + code->_co_monitoring->active_monitors = active_events; + code->_co_instrumentation_version = interp->monitoring_version; + if (monitors_are_empty(new_events) && monitors_are_empty(removed_events)) { +#ifdef INSTRUMENT_DEBUG + sanity_check_instrumentation(code); +#endif + return 0; + } + /* Insert instrumentation */ + for (int i = 0; i < code_len; i+= instruction_length(code, i)) { + _Py_CODEUNIT *instr = &_PyCode_CODE(code)[i]; + if (is_super_instruction(instr->op.code)) { + instr->op.code = _PyOpcode_Deopt[instr->op.code]; + } + CHECK(instr->op.code != 0); + int base_opcode = _Py_GetBaseOpcode(code, i); + if (opcode_has_event(base_opcode)) { + int8_t event; + if (base_opcode == RESUME) { + event = instr->op.arg > 0; + } + else { + event = EVENT_FOR_OPCODE[base_opcode]; + assert(event > 0); + } + uint8_t removed_tools = removed_events.tools[event]; + if (removed_tools) { + remove_tools(code, i, event, removed_tools); + } + uint8_t new_tools = new_events.tools[event]; + if (new_tools) { + add_tools(code, i, event, new_tools); + } + } + } + + // GH-103845: We need to remove both the line and instruction instrumentation before + // adding new ones, otherwise we may remove the newly added instrumentation. + + uint8_t removed_line_tools = removed_events.tools[PY_MONITORING_EVENT_LINE]; + uint8_t removed_per_instruction_tools = removed_events.tools[PY_MONITORING_EVENT_INSTRUCTION]; + + if (removed_line_tools) { + _PyCoLineInstrumentationData *line_data = code->_co_monitoring->lines; + for (int i = code->_co_firsttraceable; i < code_len;) { + if (line_data[i].original_opcode) { + if (removed_line_tools) { + remove_line_tools(code, i, removed_line_tools); + } + } + i += instruction_length(code, i); + } + } + if (removed_per_instruction_tools) { + for (int i = code->_co_firsttraceable; i < code_len;) { + int opcode = _Py_GetBaseOpcode(code, i); + if (opcode == RESUME || opcode == END_FOR) { + i += instruction_length(code, i); + continue; + } + if (removed_per_instruction_tools) { + remove_per_instruction_tools(code, i, removed_per_instruction_tools); + } + i += instruction_length(code, i); + } + } +#ifdef INSTRUMENT_DEBUG + sanity_check_instrumentation(code); +#endif + uint8_t new_line_tools = new_events.tools[PY_MONITORING_EVENT_LINE]; + uint8_t new_per_instruction_tools = new_events.tools[PY_MONITORING_EVENT_INSTRUCTION]; + + if (new_line_tools) { + _PyCoLineInstrumentationData *line_data = code->_co_monitoring->lines; + for (int i = code->_co_firsttraceable; i < code_len;) { + if (line_data[i].original_opcode) { + if (new_line_tools) { + add_line_tools(code, i, new_line_tools); + } + } + i += instruction_length(code, i); + } + } + if (new_per_instruction_tools) { + for (int i = code->_co_firsttraceable; i < code_len;) { + int opcode = _Py_GetBaseOpcode(code, i); + if (opcode == RESUME || opcode == END_FOR) { + i += instruction_length(code, i); + continue; + } + if (new_per_instruction_tools) { + add_per_instruction_tools(code, i, new_per_instruction_tools); + } + i += instruction_length(code, i); + } + } +#ifdef INSTRUMENT_DEBUG + sanity_check_instrumentation(code); +#endif + return 0; +} + +#define C_RETURN_EVENTS \ + ((1 << PY_MONITORING_EVENT_C_RETURN) | \ + (1 << PY_MONITORING_EVENT_C_RAISE)) + +#define C_CALL_EVENTS \ + (C_RETURN_EVENTS | (1 << PY_MONITORING_EVENT_CALL)) + + +static int +instrument_all_executing_code_objects(PyInterpreterState *interp) { + _PyRuntimeState *runtime = &_PyRuntime; + HEAD_LOCK(runtime); + PyThreadState* ts = PyInterpreterState_ThreadHead(interp); + HEAD_UNLOCK(runtime); + while (ts) { + _PyInterpreterFrame *frame = ts->cframe->current_frame; + while (frame) { + if (frame->owner != FRAME_OWNED_BY_CSTACK) { + if (_Py_Instrument(frame->f_code, interp)) { + return -1; + } + } + frame = frame->previous; + } + HEAD_LOCK(runtime); + ts = PyThreadState_Next(ts); + HEAD_UNLOCK(runtime); + } + return 0; +} + +static void +set_events(_Py_GlobalMonitors *m, int tool_id, _PyMonitoringEventSet events) +{ + assert(0 <= tool_id && tool_id < PY_MONITORING_TOOL_IDS); + for (int e = 0; e < _PY_MONITORING_UNGROUPED_EVENTS; e++) { + uint8_t *tools = &m->tools[e]; + int active = (events >> e) & 1; + *tools &= ~(1 << tool_id); + *tools |= (active << tool_id); + } +} + +static void +set_local_events(_Py_LocalMonitors *m, int tool_id, _PyMonitoringEventSet events) +{ + assert(0 <= tool_id && tool_id < PY_MONITORING_TOOL_IDS); + for (int e = 0; e < _PY_MONITORING_LOCAL_EVENTS; e++) { + uint8_t *tools = &m->tools[e]; + int val = (events >> e) & 1; + *tools &= ~(1 << tool_id); + *tools |= (val << tool_id); + } +} + +static int +check_tool(PyInterpreterState *interp, int tool_id) +{ + if (tool_id < PY_MONITORING_SYS_PROFILE_ID && + interp->monitoring_tool_names[tool_id] == NULL) + { + PyErr_Format(PyExc_ValueError, "tool %d is not in use", tool_id); + return -1; + } + return 0; +} + +int +_PyMonitoring_SetEvents(int tool_id, _PyMonitoringEventSet events) +{ + assert(0 <= tool_id && tool_id < PY_MONITORING_TOOL_IDS); + PyInterpreterState *interp = _PyInterpreterState_Get(); + assert(events < (1 << _PY_MONITORING_UNGROUPED_EVENTS)); + if (check_tool(interp, tool_id)) { + return -1; + } + uint32_t existing_events = get_events(&interp->monitors, tool_id); + if (existing_events == events) { + return 0; + } + set_events(&interp->monitors, tool_id, events); + interp->monitoring_version++; + return instrument_all_executing_code_objects(interp); +} + +int +_PyMonitoring_SetLocalEvents(PyCodeObject *code, int tool_id, _PyMonitoringEventSet events) +{ + assert(0 <= tool_id && tool_id < PY_MONITORING_TOOL_IDS); + PyInterpreterState *interp = _PyInterpreterState_Get(); + assert(events < (1 << _PY_MONITORING_LOCAL_EVENTS)); + if (code->_co_firsttraceable >= Py_SIZE(code)) { + PyErr_Format(PyExc_SystemError, "cannot instrument shim code object '%U'", code->co_name); + return -1; + } + if (check_tool(interp, tool_id)) { + return -1; + } + if (allocate_instrumentation_data(code)) { + return -1; + } + _Py_LocalMonitors *local = &code->_co_monitoring->local_monitors; + uint32_t existing_events = get_local_events(local, tool_id); + if (existing_events == events) { + return 0; + } + set_local_events(local, tool_id, events); + if (is_version_up_to_date(code, interp)) { + /* Force instrumentation update */ + code->_co_instrumentation_version = UINT64_MAX; + } + if (_Py_Instrument(code, interp)) { + return -1; + } + return 0; +} + +/*[clinic input] +module monitoring +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=37257f5987a360cf]*/ +/*[clinic end generated code]*/ + +#include "clinic/instrumentation.c.h" + +static int +check_valid_tool(int tool_id) +{ + if (tool_id < 0 || tool_id >= PY_MONITORING_SYS_PROFILE_ID) { + PyErr_Format(PyExc_ValueError, "invalid tool %d (must be between 0 and 5)", tool_id); + return -1; + } + return 0; +} + +/*[clinic input] +monitoring.use_tool_id + + tool_id: int + name: object + / + +[clinic start generated code]*/ + +static PyObject * +monitoring_use_tool_id_impl(PyObject *module, int tool_id, PyObject *name) +/*[clinic end generated code: output=30d76dc92b7cd653 input=ebc453761c621be1]*/ +{ + if (check_valid_tool(tool_id)) { + return NULL; + } + if (!PyUnicode_Check(name)) { + PyErr_SetString(PyExc_ValueError, "tool name must be a str"); + return NULL; + } + PyInterpreterState *interp = _PyInterpreterState_Get(); + if (interp->monitoring_tool_names[tool_id] != NULL) { + PyErr_Format(PyExc_ValueError, "tool %d is already in use", tool_id); + return NULL; + } + interp->monitoring_tool_names[tool_id] = Py_NewRef(name); + Py_RETURN_NONE; +} + +/*[clinic input] +monitoring.free_tool_id + + tool_id: int + / + +[clinic start generated code]*/ + +static PyObject * +monitoring_free_tool_id_impl(PyObject *module, int tool_id) +/*[clinic end generated code: output=86c2d2a1219a8591 input=a23fb6be3a8618e9]*/ +{ + if (check_valid_tool(tool_id)) { + return NULL; + } + PyInterpreterState *interp = _PyInterpreterState_Get(); + Py_CLEAR(interp->monitoring_tool_names[tool_id]); + Py_RETURN_NONE; +} + +/*[clinic input] +monitoring.get_tool + + tool_id: int + / + +[clinic start generated code]*/ + +static PyObject * +monitoring_get_tool_impl(PyObject *module, int tool_id) +/*[clinic end generated code: output=1c05a98b404a9a16 input=eeee9bebd0bcae9d]*/ + +/*[clinic end generated code]*/ +{ + if (check_valid_tool(tool_id)) { + return NULL; + } + PyInterpreterState *interp = _PyInterpreterState_Get(); + PyObject *name = interp->monitoring_tool_names[tool_id]; + if (name == NULL) { + Py_RETURN_NONE; + } + return Py_NewRef(name); +} + +/*[clinic input] +monitoring.register_callback + + + tool_id: int + event: int + func: object + / + +[clinic start generated code]*/ + +static PyObject * +monitoring_register_callback_impl(PyObject *module, int tool_id, int event, + PyObject *func) +/*[clinic end generated code: output=e64daa363004030c input=df6d70ea4cf81007]*/ +{ + if (check_valid_tool(tool_id)) { + return NULL; + } + if (_Py_popcount32(event) != 1) { + PyErr_SetString(PyExc_ValueError, "The callback can only be set for one event at a time"); + return NULL; + } + int event_id = _Py_bit_length(event)-1; + if (event_id < 0 || event_id >= _PY_MONITORING_EVENTS) { + PyErr_Format(PyExc_ValueError, "invalid event %d", event); + return NULL; + } + if (PySys_Audit("sys.monitoring.register_callback", "O", func) < 0) { + return NULL; + } + if (func == Py_None) { + func = NULL; + } + func = _PyMonitoring_RegisterCallback(tool_id, event_id, func); + if (func == NULL) { + Py_RETURN_NONE; + } + return func; +} + +/*[clinic input] +monitoring.get_events -> int + + tool_id: int + / + +[clinic start generated code]*/ + +static int +monitoring_get_events_impl(PyObject *module, int tool_id) +/*[clinic end generated code: output=4450cc13f826c8c0 input=a64b238f76c4b2f7]*/ +{ + if (check_valid_tool(tool_id)) { + return -1; + } + _Py_GlobalMonitors *m = &_PyInterpreterState_GET()->monitors; + _PyMonitoringEventSet event_set = get_events(m, tool_id); + return event_set; +} + +/*[clinic input] +monitoring.set_events + + tool_id: int + event_set: int + / + +[clinic start generated code]*/ + +static PyObject * +monitoring_set_events_impl(PyObject *module, int tool_id, int event_set) +/*[clinic end generated code: output=1916c1e49cfb5bdb input=a77ba729a242142b]*/ +{ + if (check_valid_tool(tool_id)) { + return NULL; + } + if (event_set < 0 || event_set >= (1 << _PY_MONITORING_EVENTS)) { + PyErr_Format(PyExc_ValueError, "invalid event set 0x%x", event_set); + return NULL; + } + if ((event_set & C_RETURN_EVENTS) && (event_set & C_CALL_EVENTS) != C_CALL_EVENTS) { + PyErr_Format(PyExc_ValueError, "cannot set C_RETURN or C_RAISE events independently"); + return NULL; + } + event_set &= ~C_RETURN_EVENTS; + if (_PyMonitoring_SetEvents(tool_id, event_set)) { + return NULL; + } + Py_RETURN_NONE; +} + +/*[clinic input] +monitoring.get_local_events -> int + + tool_id: int + code: object + / + +[clinic start generated code]*/ + +static int +monitoring_get_local_events_impl(PyObject *module, int tool_id, + PyObject *code) +/*[clinic end generated code: output=d3e92c1c9c1de8f9 input=bb0f927530386a94]*/ +{ + if (!PyCode_Check(code)) { + PyErr_Format( + PyExc_TypeError, + "code must be a code object" + ); + return -1; + } + if (check_valid_tool(tool_id)) { + return -1; + } + _PyMonitoringEventSet event_set = 0; + _PyCoMonitoringData *data = ((PyCodeObject *)code)->_co_monitoring; + if (data != NULL) { + for (int e = 0; e < _PY_MONITORING_LOCAL_EVENTS; e++) { + if ((data->local_monitors.tools[e] >> tool_id) & 1) { + event_set |= (1 << e); + } + } + } + return event_set; +} + +/*[clinic input] +monitoring.set_local_events + + tool_id: int + code: object + event_set: int + / + +[clinic start generated code]*/ + +static PyObject * +monitoring_set_local_events_impl(PyObject *module, int tool_id, + PyObject *code, int event_set) +/*[clinic end generated code: output=68cc755a65dfea99 input=5655ecd78d937a29]*/ +{ + if (!PyCode_Check(code)) { + PyErr_Format( + PyExc_TypeError, + "code must be a code object" + ); + return NULL; + } + if (check_valid_tool(tool_id)) { + return NULL; + } + if ((event_set & C_RETURN_EVENTS) && (event_set & C_CALL_EVENTS) != C_CALL_EVENTS) { + PyErr_Format(PyExc_ValueError, "cannot set C_RETURN or C_RAISE events independently"); + return NULL; + } + event_set &= ~C_RETURN_EVENTS; + if (event_set < 0 || event_set >= (1 << _PY_MONITORING_LOCAL_EVENTS)) { + PyErr_Format(PyExc_ValueError, "invalid local event set 0x%x", event_set); + return NULL; + } + + if (_PyMonitoring_SetLocalEvents((PyCodeObject*)code, tool_id, event_set)) { + return NULL; + } + Py_RETURN_NONE; +} + +/*[clinic input] +monitoring.restart_events + +[clinic start generated code]*/ + +static PyObject * +monitoring_restart_events_impl(PyObject *module) +/*[clinic end generated code: output=e025dd5ba33314c4 input=add8a855063c8008]*/ +{ + /* We want to ensure that: + * last restart version > instrumented version for all code objects + * last restart version < current version + */ + PyInterpreterState *interp = _PyInterpreterState_Get(); + interp->last_restart_version = interp->monitoring_version + 1; + interp->monitoring_version = interp->last_restart_version + 1; + if (instrument_all_executing_code_objects(interp)) { + return NULL; + } + Py_RETURN_NONE; +} + +static int +add_power2_constant(PyObject *obj, const char *name, int i) +{ + PyObject *val = PyLong_FromLong(1<<i); + if (val == NULL) { + return -1; + } + int err = PyObject_SetAttrString(obj, name, val); + Py_DECREF(val); + return err; +} + +/*[clinic input] +monitoring._all_events +[clinic start generated code]*/ + +static PyObject * +monitoring__all_events_impl(PyObject *module) +/*[clinic end generated code: output=6b7581e2dbb690f6 input=62ee9672c17b7f0e]*/ +{ + PyInterpreterState *interp = _PyInterpreterState_Get(); + PyObject *res = PyDict_New(); + if (res == NULL) { + return NULL; + } + for (int e = 0; e < _PY_MONITORING_UNGROUPED_EVENTS; e++) { + uint8_t tools = interp->monitors.tools[e]; + if (tools == 0) { + continue; + } + PyObject *tools_obj = PyLong_FromLong(tools); + assert(tools_obj != NULL); + int err = PyDict_SetItemString(res, event_names[e], tools_obj); + Py_DECREF(tools_obj); + if (err < 0) { + Py_DECREF(res); + return NULL; + } + } + return res; +} + +static PyMethodDef methods[] = { + MONITORING_USE_TOOL_ID_METHODDEF + MONITORING_FREE_TOOL_ID_METHODDEF + MONITORING_GET_TOOL_METHODDEF + MONITORING_REGISTER_CALLBACK_METHODDEF + MONITORING_GET_EVENTS_METHODDEF + MONITORING_SET_EVENTS_METHODDEF + MONITORING_GET_LOCAL_EVENTS_METHODDEF + MONITORING_SET_LOCAL_EVENTS_METHODDEF + MONITORING_RESTART_EVENTS_METHODDEF + MONITORING__ALL_EVENTS_METHODDEF + {NULL, NULL} // sentinel +}; + +static struct PyModuleDef monitoring_module = { + PyModuleDef_HEAD_INIT, + .m_name = "sys.monitoring", + .m_size = -1, /* multiple "initialization" just copies the module dict. */ + .m_methods = methods, +}; + +PyObject *_Py_CreateMonitoringObject(void) +{ + PyObject *mod = _PyModule_CreateInitialized(&monitoring_module, PYTHON_API_VERSION); + if (mod == NULL) { + return NULL; + } + if (PyObject_SetAttrString(mod, "DISABLE", &_PyInstrumentation_DISABLE)) { + goto error; + } + if (PyObject_SetAttrString(mod, "MISSING", &_PyInstrumentation_MISSING)) { + goto error; + } + PyObject *events = _PyNamespace_New(NULL); + if (events == NULL) { + goto error; + } + int err = PyObject_SetAttrString(mod, "events", events); + Py_DECREF(events); + if (err) { + goto error; + } + for (int i = 0; i < _PY_MONITORING_EVENTS; i++) { + if (add_power2_constant(events, event_names[i], i)) { + goto error; + } + } + err = PyObject_SetAttrString(events, "NO_EVENTS", _PyLong_GetZero()); + if (err) goto error; + PyObject *val = PyLong_FromLong(PY_MONITORING_DEBUGGER_ID); + err = PyObject_SetAttrString(mod, "DEBUGGER_ID", val); + Py_DECREF(val); + if (err) goto error; + val = PyLong_FromLong(PY_MONITORING_COVERAGE_ID); + err = PyObject_SetAttrString(mod, "COVERAGE_ID", val); + Py_DECREF(val); + if (err) goto error; + val = PyLong_FromLong(PY_MONITORING_PROFILER_ID); + err = PyObject_SetAttrString(mod, "PROFILER_ID", val); + Py_DECREF(val); + if (err) goto error; + val = PyLong_FromLong(PY_MONITORING_OPTIMIZER_ID); + err = PyObject_SetAttrString(mod, "OPTIMIZER_ID", val); + Py_DECREF(val); + if (err) goto error; + return mod; +error: + Py_DECREF(mod); + return NULL; +} diff --git a/Python/intrinsics.c b/Python/intrinsics.c new file mode 100644 index 00000000..c6f5ac54 --- /dev/null +++ b/Python/intrinsics.c @@ -0,0 +1,260 @@ + +#define _PY_INTERPRETER + +#include "Python.h" +#include "pycore_frame.h" +#include "pycore_function.h" +#include "pycore_runtime.h" +#include "pycore_global_objects.h" +#include "pycore_intrinsics.h" +#include "pycore_pyerrors.h" +#include "pycore_typevarobject.h" + + +/******** Unary functions ********/ + +static PyObject * +no_intrinsic(PyThreadState* tstate, PyObject *unused) +{ + _PyErr_SetString(tstate, PyExc_SystemError, "invalid intrinsic function"); + return NULL; +} + +static PyObject * +print_expr(PyThreadState* tstate, PyObject *value) +{ + PyObject *hook = _PySys_GetAttr(tstate, &_Py_ID(displayhook)); + // Can't use ERROR_IF here. + if (hook == NULL) { + _PyErr_SetString(tstate, PyExc_RuntimeError, + "lost sys.displayhook"); + return NULL; + } + return PyObject_CallOneArg(hook, value); +} + +static int +import_all_from(PyThreadState *tstate, PyObject *locals, PyObject *v) +{ + PyObject *all, *dict, *name, *value; + int skip_leading_underscores = 0; + int pos, err; + + if (_PyObject_LookupAttr(v, &_Py_ID(__all__), &all) < 0) { + return -1; /* Unexpected error */ + } + if (all == NULL) { + if (_PyObject_LookupAttr(v, &_Py_ID(__dict__), &dict) < 0) { + return -1; + } + if (dict == NULL) { + _PyErr_SetString(tstate, PyExc_ImportError, + "from-import-* object has no __dict__ and no __all__"); + return -1; + } + all = PyMapping_Keys(dict); + Py_DECREF(dict); + if (all == NULL) + return -1; + skip_leading_underscores = 1; + } + + for (pos = 0, err = 0; ; pos++) { + name = PySequence_GetItem(all, pos); + if (name == NULL) { + if (!_PyErr_ExceptionMatches(tstate, PyExc_IndexError)) { + err = -1; + } + else { + _PyErr_Clear(tstate); + } + break; + } + if (!PyUnicode_Check(name)) { + PyObject *modname = PyObject_GetAttr(v, &_Py_ID(__name__)); + if (modname == NULL) { + Py_DECREF(name); + err = -1; + break; + } + if (!PyUnicode_Check(modname)) { + _PyErr_Format(tstate, PyExc_TypeError, + "module __name__ must be a string, not %.100s", + Py_TYPE(modname)->tp_name); + } + else { + _PyErr_Format(tstate, PyExc_TypeError, + "%s in %U.%s must be str, not %.100s", + skip_leading_underscores ? "Key" : "Item", + modname, + skip_leading_underscores ? "__dict__" : "__all__", + Py_TYPE(name)->tp_name); + } + Py_DECREF(modname); + Py_DECREF(name); + err = -1; + break; + } + if (skip_leading_underscores) { + if (PyUnicode_READY(name) == -1) { + Py_DECREF(name); + err = -1; + break; + } + if (PyUnicode_READ_CHAR(name, 0) == '_') { + Py_DECREF(name); + continue; + } + } + value = PyObject_GetAttr(v, name); + if (value == NULL) + err = -1; + else if (PyDict_CheckExact(locals)) + err = PyDict_SetItem(locals, name, value); + else + err = PyObject_SetItem(locals, name, value); + Py_DECREF(name); + Py_XDECREF(value); + if (err < 0) + break; + } + Py_DECREF(all); + return err; +} + +static PyObject * +import_star(PyThreadState* tstate, PyObject *from) +{ + _PyInterpreterFrame *frame = tstate->cframe->current_frame; + if (_PyFrame_FastToLocalsWithError(frame) < 0) { + return NULL; + } + + PyObject *locals = frame->f_locals; + if (locals == NULL) { + _PyErr_SetString(tstate, PyExc_SystemError, + "no locals found during 'import *'"); + return NULL; + } + int err = import_all_from(tstate, locals, from); + _PyFrame_LocalsToFast(frame, 0); + if (err < 0) { + return NULL; + } + Py_RETURN_NONE; +} + +static PyObject * +stopiteration_error(PyThreadState* tstate, PyObject *exc) +{ + _PyInterpreterFrame *frame = tstate->cframe->current_frame; + assert(frame->owner == FRAME_OWNED_BY_GENERATOR); + assert(PyExceptionInstance_Check(exc)); + const char *msg = NULL; + if (PyErr_GivenExceptionMatches(exc, PyExc_StopIteration)) { + msg = "generator raised StopIteration"; + if (frame->f_code->co_flags & CO_ASYNC_GENERATOR) { + msg = "async generator raised StopIteration"; + } + else if (frame->f_code->co_flags & CO_COROUTINE) { + msg = "coroutine raised StopIteration"; + } + } + else if ((frame->f_code->co_flags & CO_ASYNC_GENERATOR) && + PyErr_GivenExceptionMatches(exc, PyExc_StopAsyncIteration)) + { + /* code in `gen` raised a StopAsyncIteration error: + raise a RuntimeError. + */ + msg = "async generator raised StopAsyncIteration"; + } + if (msg != NULL) { + PyObject *message = _PyUnicode_FromASCII(msg, strlen(msg)); + if (message == NULL) { + return NULL; + } + PyObject *error = PyObject_CallOneArg(PyExc_RuntimeError, message); + if (error == NULL) { + Py_DECREF(message); + return NULL; + } + assert(PyExceptionInstance_Check(error)); + PyException_SetCause(error, Py_NewRef(exc)); + // Steal exc reference, rather than Py_NewRef+Py_DECREF + PyException_SetContext(error, Py_NewRef(exc)); + Py_DECREF(message); + return error; + } + return Py_NewRef(exc); +} + +static PyObject * +unary_pos(PyThreadState* unused, PyObject *value) +{ + return PyNumber_Positive(value); +} + +static PyObject * +list_to_tuple(PyThreadState* unused, PyObject *v) +{ + assert(PyList_Check(v)); + return _PyTuple_FromArray(((PyListObject *)v)->ob_item, Py_SIZE(v)); +} + +static PyObject * +make_typevar(PyThreadState* Py_UNUSED(ignored), PyObject *v) +{ + assert(PyUnicode_Check(v)); + return _Py_make_typevar(v, NULL, NULL); +} + +const instrinsic_func1 +_PyIntrinsics_UnaryFunctions[] = { + [0] = no_intrinsic, + [INTRINSIC_PRINT] = print_expr, + [INTRINSIC_IMPORT_STAR] = import_star, + [INTRINSIC_STOPITERATION_ERROR] = stopiteration_error, + [INTRINSIC_ASYNC_GEN_WRAP] = _PyAsyncGenValueWrapperNew, + [INTRINSIC_UNARY_POSITIVE] = unary_pos, + [INTRINSIC_LIST_TO_TUPLE] = list_to_tuple, + [INTRINSIC_TYPEVAR] = make_typevar, + [INTRINSIC_PARAMSPEC] = _Py_make_paramspec, + [INTRINSIC_TYPEVARTUPLE] = _Py_make_typevartuple, + [INTRINSIC_SUBSCRIPT_GENERIC] = _Py_subscript_generic, + [INTRINSIC_TYPEALIAS] = _Py_make_typealias, +}; + + +/******** Binary functions ********/ + + +static PyObject * +prep_reraise_star(PyThreadState* unused, PyObject *orig, PyObject *excs) +{ + assert(PyList_Check(excs)); + return _PyExc_PrepReraiseStar(orig, excs); +} + +static PyObject * +make_typevar_with_bound(PyThreadState* Py_UNUSED(ignored), PyObject *name, + PyObject *evaluate_bound) +{ + assert(PyUnicode_Check(name)); + return _Py_make_typevar(name, evaluate_bound, NULL); +} + +static PyObject * +make_typevar_with_constraints(PyThreadState* Py_UNUSED(ignored), PyObject *name, + PyObject *evaluate_constraints) +{ + assert(PyUnicode_Check(name)); + return _Py_make_typevar(name, NULL, evaluate_constraints); +} + +const instrinsic_func2 +_PyIntrinsics_BinaryFunctions[] = { + [INTRINSIC_PREP_RERAISE_STAR] = prep_reraise_star, + [INTRINSIC_TYPEVAR_WITH_BOUND] = make_typevar_with_bound, + [INTRINSIC_TYPEVAR_WITH_CONSTRAINTS] = make_typevar_with_constraints, + [INTRINSIC_SET_FUNCTION_TYPE_PARAMS] = _Py_set_function_type_params, +}; diff --git a/Python/legacy_tracing.c b/Python/legacy_tracing.c new file mode 100644 index 00000000..b0136d2e --- /dev/null +++ b/Python/legacy_tracing.c @@ -0,0 +1,513 @@ +/* Support for legacy tracing on top of PEP 669 instrumentation + * Provides callables to forward PEP 669 events to legacy events. + */ + +#include <stddef.h> +#include "Python.h" +#include "opcode.h" +#include "pycore_ceval.h" +#include "pycore_object.h" +#include "pycore_sysmodule.h" + +typedef struct _PyLegacyEventHandler { + PyObject_HEAD + vectorcallfunc vectorcall; + int event; +} _PyLegacyEventHandler; + +/* The Py_tracefunc function expects the following arguments: + * obj: the trace object (PyObject *) + * frame: the current frame (PyFrameObject *) + * kind: the kind of event, see PyTrace_XXX #defines (int) + * arg: The arg (a PyObject *) + */ + +static PyObject * +call_profile_func(_PyLegacyEventHandler *self, PyObject *arg) +{ + PyThreadState *tstate = _PyThreadState_GET(); + if (tstate->c_profilefunc == NULL) { + Py_RETURN_NONE; + } + PyFrameObject *frame = PyEval_GetFrame(); + if (frame == NULL) { + PyErr_SetString(PyExc_SystemError, + "Missing frame when calling profile function."); + return NULL; + } + Py_INCREF(frame); + int err = tstate->c_profilefunc(tstate->c_profileobj, frame, self->event, arg); + Py_DECREF(frame); + if (err) { + return NULL; + } + Py_RETURN_NONE; +} + +static PyObject * +sys_profile_func2( + _PyLegacyEventHandler *self, PyObject *const *args, + size_t nargsf, PyObject *kwnames +) { + assert(kwnames == NULL); + assert(PyVectorcall_NARGS(nargsf) == 2); + return call_profile_func(self, Py_None); +} + +static PyObject * +sys_profile_func3( + _PyLegacyEventHandler *self, PyObject *const *args, + size_t nargsf, PyObject *kwnames +) { + assert(kwnames == NULL); + assert(PyVectorcall_NARGS(nargsf) == 3); + return call_profile_func(self, args[2]); +} + +static PyObject * +sys_profile_unwind( + _PyLegacyEventHandler *self, PyObject *const *args, + size_t nargsf, PyObject *kwnames +) { + assert(kwnames == NULL); + assert(PyVectorcall_NARGS(nargsf) == 3); + return call_profile_func(self, Py_None); +} + +static PyObject * +sys_profile_call_or_return( + _PyLegacyEventHandler *self, PyObject *const *args, + size_t nargsf, PyObject *kwnames +) { + assert(kwnames == NULL); + assert(PyVectorcall_NARGS(nargsf) == 4); + PyObject *callable = args[2]; + if (PyCFunction_Check(callable)) { + return call_profile_func(self, callable); + } + if (Py_TYPE(callable) == &PyMethodDescr_Type) { + PyObject *self_arg = args[3]; + /* For backwards compatibility need to + * convert to builtin method */ + + /* If no arg, skip */ + if (self_arg == &_PyInstrumentation_MISSING) { + Py_RETURN_NONE; + } + PyObject *meth = Py_TYPE(callable)->tp_descr_get( + callable, self_arg, (PyObject*)Py_TYPE(self_arg)); + if (meth == NULL) { + return NULL; + } + PyObject *res = call_profile_func(self, meth); + Py_DECREF(meth); + return res; + } + Py_RETURN_NONE; +} + +static PyObject * +call_trace_func(_PyLegacyEventHandler *self, PyObject *arg) +{ + PyThreadState *tstate = _PyThreadState_GET(); + if (tstate->c_tracefunc == NULL) { + Py_RETURN_NONE; + } + PyFrameObject *frame = PyEval_GetFrame(); + if (frame == NULL) { + PyErr_SetString(PyExc_SystemError, + "Missing frame when calling trace function."); + return NULL; + } + Py_INCREF(frame); + int err = tstate->c_tracefunc(tstate->c_traceobj, frame, self->event, arg); + Py_DECREF(frame); + if (err) { + return NULL; + } + Py_RETURN_NONE; +} + +static PyObject * +sys_trace_exception_func( + _PyLegacyEventHandler *self, PyObject *const *args, + size_t nargsf, PyObject *kwnames +) { + assert(kwnames == NULL); + assert(PyVectorcall_NARGS(nargsf) == 3); + PyObject *exc = args[2]; + assert(PyExceptionInstance_Check(exc)); + PyObject *type = (PyObject *)Py_TYPE(exc); + PyObject *tb = PyException_GetTraceback(exc); + if (tb == NULL) { + tb = Py_NewRef(Py_None); + } + PyObject *tuple = PyTuple_Pack(3, type, exc, tb); + Py_DECREF(tb); + if (tuple == NULL) { + return NULL; + } + PyObject *res = call_trace_func(self, tuple); + Py_DECREF(tuple); + return res; +} + +static PyObject * +sys_trace_func2( + _PyLegacyEventHandler *self, PyObject *const *args, + size_t nargsf, PyObject *kwnames +) { + assert(kwnames == NULL); + assert(PyVectorcall_NARGS(nargsf) == 2); + return call_trace_func(self, Py_None); +} + +static PyObject * +sys_trace_func3( + _PyLegacyEventHandler *self, PyObject *const *args, + size_t nargsf, PyObject *kwnames +) { + assert(kwnames == NULL); + assert(PyVectorcall_NARGS(nargsf) == 3); + return call_trace_func(self, Py_None); +} + +static PyObject * +sys_trace_return( + _PyLegacyEventHandler *self, PyObject *const *args, + size_t nargsf, PyObject *kwnames +) { + assert(!PyErr_Occurred()); + assert(kwnames == NULL); + assert(PyVectorcall_NARGS(nargsf) == 3); + assert(PyCode_Check(args[0])); + PyObject *val = args[2]; + PyObject *res = call_trace_func(self, val); + return res; +} + +static PyObject * +sys_trace_yield( + _PyLegacyEventHandler *self, PyObject *const *args, + size_t nargsf, PyObject *kwnames +) { + assert(kwnames == NULL); + assert(PyVectorcall_NARGS(nargsf) == 3); + return call_trace_func(self, args[2]); +} + +static PyObject * +sys_trace_instruction_func( + _PyLegacyEventHandler *self, PyObject *const *args, + size_t nargsf, PyObject *kwnames +) { + assert(kwnames == NULL); + assert(PyVectorcall_NARGS(nargsf) == 2); + PyFrameObject *frame = PyEval_GetFrame(); + if (frame == NULL) { + PyErr_SetString(PyExc_SystemError, + "Missing frame when calling trace function."); + return NULL; + } + if (!frame->f_trace_opcodes) { + Py_RETURN_NONE; + } + Py_INCREF(frame); + PyThreadState *tstate = _PyThreadState_GET(); + int err = tstate->c_tracefunc(tstate->c_traceobj, frame, self->event, Py_None); + frame->f_lineno = 0; + Py_DECREF(frame); + if (err) { + return NULL; + } + Py_RETURN_NONE; +} + +static PyObject * +trace_line( + PyThreadState *tstate, _PyLegacyEventHandler *self, + PyFrameObject *frame, int line +) { + if (!frame->f_trace_lines) { + Py_RETURN_NONE; + } + if (line < 0) { + Py_RETURN_NONE; + } + Py_INCREF(frame); + frame->f_lineno = line; + int err = tstate->c_tracefunc(tstate->c_traceobj, frame, self->event, Py_None); + frame->f_lineno = 0; + Py_DECREF(frame); + if (err) { + return NULL; + } + Py_RETURN_NONE; +} + +static PyObject * +sys_trace_line_func( + _PyLegacyEventHandler *self, PyObject *const *args, + size_t nargsf, PyObject *kwnames +) { + assert(kwnames == NULL); + PyThreadState *tstate = _PyThreadState_GET(); + if (tstate->c_tracefunc == NULL) { + Py_RETURN_NONE; + } + assert(PyVectorcall_NARGS(nargsf) == 2); + int line = _PyLong_AsInt(args[1]); + assert(line >= 0); + PyFrameObject *frame = PyEval_GetFrame(); + if (frame == NULL) { + PyErr_SetString(PyExc_SystemError, + "Missing frame when calling trace function."); + return NULL; + } + assert(args[0] == (PyObject *)frame->f_frame->f_code); + return trace_line(tstate, self, frame, line); +} + +/* sys.settrace generates line events for all backward + * edges, even if on the same line. + * Handle that case here */ +static PyObject * +sys_trace_jump_func( + _PyLegacyEventHandler *self, PyObject *const *args, + size_t nargsf, PyObject *kwnames +) { + assert(kwnames == NULL); + PyThreadState *tstate = _PyThreadState_GET(); + if (tstate->c_tracefunc == NULL) { + Py_RETURN_NONE; + } + assert(PyVectorcall_NARGS(nargsf) == 3); + int from = _PyLong_AsInt(args[1])/sizeof(_Py_CODEUNIT); + assert(from >= 0); + int to = _PyLong_AsInt(args[2])/sizeof(_Py_CODEUNIT); + assert(to >= 0); + if (to > from) { + /* Forward jump */ + return &_PyInstrumentation_DISABLE; + } + PyCodeObject *code = (PyCodeObject *)args[0]; + assert(PyCode_Check(code)); + /* We can call _Py_Instrumentation_GetLine because we always set + * line events for tracing */ + int to_line = _Py_Instrumentation_GetLine(code, to); + int from_line = _Py_Instrumentation_GetLine(code, from); + if (to_line != from_line) { + /* Will be handled by target INSTRUMENTED_LINE */ + return &_PyInstrumentation_DISABLE; + } + PyFrameObject *frame = PyEval_GetFrame(); + if (frame == NULL) { + PyErr_SetString(PyExc_SystemError, + "Missing frame when calling trace function."); + return NULL; + } + assert(code == frame->f_frame->f_code); + if (!frame->f_trace_lines) { + Py_RETURN_NONE; + } + return trace_line(tstate, self, frame, to_line); +} + +PyTypeObject _PyLegacyEventHandler_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "sys.legacy_event_handler", + sizeof(_PyLegacyEventHandler), + .tp_dealloc = (destructor)PyObject_Free, + .tp_vectorcall_offset = offsetof(_PyLegacyEventHandler, vectorcall), + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_HAVE_VECTORCALL | Py_TPFLAGS_DISALLOW_INSTANTIATION, + .tp_call = PyVectorcall_Call, +}; + +static int +set_callbacks(int tool, vectorcallfunc vectorcall, int legacy_event, int event1, int event2) +{ + _PyLegacyEventHandler *callback = + PyObject_NEW(_PyLegacyEventHandler, &_PyLegacyEventHandler_Type); + if (callback == NULL) { + return -1; + } + callback->vectorcall = vectorcall; + callback->event = legacy_event; + Py_XDECREF(_PyMonitoring_RegisterCallback(tool, event1, (PyObject *)callback)); + if (event2 >= 0) { + Py_XDECREF(_PyMonitoring_RegisterCallback(tool, event2, (PyObject *)callback)); + } + Py_DECREF(callback); + return 0; +} + +#ifndef NDEBUG +/* Ensure that tstate is valid: sanity check for PyEval_AcquireThread() and + PyEval_RestoreThread(). Detect if tstate memory was freed. It can happen + when a thread continues to run after Python finalization, especially + daemon threads. */ +static int +is_tstate_valid(PyThreadState *tstate) +{ + assert(!_PyMem_IsPtrFreed(tstate)); + assert(!_PyMem_IsPtrFreed(tstate->interp)); + return 1; +} +#endif + +int +_PyEval_SetProfile(PyThreadState *tstate, Py_tracefunc func, PyObject *arg) +{ + assert(is_tstate_valid(tstate)); + /* The caller must hold the GIL */ + assert(PyGILState_Check()); + + /* Call _PySys_Audit() in the context of the current thread state, + even if tstate is not the current thread state. */ + PyThreadState *current_tstate = _PyThreadState_GET(); + if (_PySys_Audit(current_tstate, "sys.setprofile", NULL) < 0) { + return -1; + } + /* Setup PEP 669 monitoring callbacks and events. */ + if (!tstate->interp->sys_profile_initialized) { + tstate->interp->sys_profile_initialized = true; + if (set_callbacks(PY_MONITORING_SYS_PROFILE_ID, + (vectorcallfunc)sys_profile_func2, PyTrace_CALL, + PY_MONITORING_EVENT_PY_START, PY_MONITORING_EVENT_PY_RESUME)) { + return -1; + } + if (set_callbacks(PY_MONITORING_SYS_PROFILE_ID, + (vectorcallfunc)sys_profile_func3, PyTrace_RETURN, + PY_MONITORING_EVENT_PY_RETURN, PY_MONITORING_EVENT_PY_YIELD)) { + return -1; + } + if (set_callbacks(PY_MONITORING_SYS_PROFILE_ID, + (vectorcallfunc)sys_profile_unwind, PyTrace_RETURN, + PY_MONITORING_EVENT_PY_UNWIND, -1)) { + return -1; + } + if (set_callbacks(PY_MONITORING_SYS_PROFILE_ID, + (vectorcallfunc)sys_profile_call_or_return, PyTrace_C_CALL, + PY_MONITORING_EVENT_CALL, -1)) { + return -1; + } + if (set_callbacks(PY_MONITORING_SYS_PROFILE_ID, + (vectorcallfunc)sys_profile_call_or_return, PyTrace_C_RETURN, + PY_MONITORING_EVENT_C_RETURN, -1)) { + return -1; + } + if (set_callbacks(PY_MONITORING_SYS_PROFILE_ID, + (vectorcallfunc)sys_profile_call_or_return, PyTrace_C_EXCEPTION, + PY_MONITORING_EVENT_C_RAISE, -1)) { + return -1; + } + } + + int delta = (func != NULL) - (tstate->c_profilefunc != NULL); + tstate->c_profilefunc = func; + PyObject *old_profileobj = tstate->c_profileobj; + tstate->c_profileobj = Py_XNewRef(arg); + Py_XDECREF(old_profileobj); + tstate->interp->sys_profiling_threads += delta; + assert(tstate->interp->sys_profiling_threads >= 0); + + uint32_t events = 0; + if (tstate->interp->sys_profiling_threads) { + events = + (1 << PY_MONITORING_EVENT_PY_START) | (1 << PY_MONITORING_EVENT_PY_RESUME) | + (1 << PY_MONITORING_EVENT_PY_RETURN) | (1 << PY_MONITORING_EVENT_PY_YIELD) | + (1 << PY_MONITORING_EVENT_CALL) | (1 << PY_MONITORING_EVENT_PY_UNWIND); + } + return _PyMonitoring_SetEvents(PY_MONITORING_SYS_PROFILE_ID, events); +} + +int +_PyEval_SetTrace(PyThreadState *tstate, Py_tracefunc func, PyObject *arg) +{ + assert(is_tstate_valid(tstate)); + /* The caller must hold the GIL */ + assert(PyGILState_Check()); + + /* Call _PySys_Audit() in the context of the current thread state, + even if tstate is not the current thread state. */ + PyThreadState *current_tstate = _PyThreadState_GET(); + if (_PySys_Audit(current_tstate, "sys.settrace", NULL) < 0) { + return -1; + } + + assert(tstate->interp->sys_tracing_threads >= 0); + /* Setup PEP 669 monitoring callbacks and events. */ + if (!tstate->interp->sys_trace_initialized) { + tstate->interp->sys_trace_initialized = true; + if (set_callbacks(PY_MONITORING_SYS_TRACE_ID, + (vectorcallfunc)sys_trace_func2, PyTrace_CALL, + PY_MONITORING_EVENT_PY_START, PY_MONITORING_EVENT_PY_RESUME)) { + return -1; + } + if (set_callbacks(PY_MONITORING_SYS_TRACE_ID, + (vectorcallfunc)sys_trace_func3, PyTrace_CALL, + PY_MONITORING_EVENT_PY_THROW, -1)) { + return -1; + } + if (set_callbacks(PY_MONITORING_SYS_TRACE_ID, + (vectorcallfunc)sys_trace_return, PyTrace_RETURN, + PY_MONITORING_EVENT_PY_RETURN, -1)) { + return -1; + } + if (set_callbacks(PY_MONITORING_SYS_TRACE_ID, + (vectorcallfunc)sys_trace_yield, PyTrace_RETURN, + PY_MONITORING_EVENT_PY_YIELD, -1)) { + return -1; + } + if (set_callbacks(PY_MONITORING_SYS_TRACE_ID, + (vectorcallfunc)sys_trace_exception_func, PyTrace_EXCEPTION, + PY_MONITORING_EVENT_RAISE, PY_MONITORING_EVENT_STOP_ITERATION)) { + return -1; + } + if (set_callbacks(PY_MONITORING_SYS_TRACE_ID, + (vectorcallfunc)sys_trace_line_func, PyTrace_LINE, + PY_MONITORING_EVENT_LINE, -1)) { + return -1; + } + if (set_callbacks(PY_MONITORING_SYS_TRACE_ID, + (vectorcallfunc)sys_trace_func3, PyTrace_RETURN, + PY_MONITORING_EVENT_PY_UNWIND, -1)) { + return -1; + } + if (set_callbacks(PY_MONITORING_SYS_TRACE_ID, + (vectorcallfunc)sys_trace_jump_func, PyTrace_LINE, + PY_MONITORING_EVENT_JUMP, -1)) { + return -1; + } + if (set_callbacks(PY_MONITORING_SYS_TRACE_ID, + (vectorcallfunc)sys_trace_instruction_func, PyTrace_OPCODE, + PY_MONITORING_EVENT_INSTRUCTION, -1)) { + return -1; + } + } + + int delta = (func != NULL) - (tstate->c_tracefunc != NULL); + tstate->c_tracefunc = func; + PyObject *old_traceobj = tstate->c_traceobj; + tstate->c_traceobj = Py_XNewRef(arg); + Py_XDECREF(old_traceobj); + tstate->interp->sys_tracing_threads += delta; + assert(tstate->interp->sys_tracing_threads >= 0); + + uint32_t events = 0; + if (tstate->interp->sys_tracing_threads) { + events = + (1 << PY_MONITORING_EVENT_PY_START) | (1 << PY_MONITORING_EVENT_PY_RESUME) | + (1 << PY_MONITORING_EVENT_PY_RETURN) | (1 << PY_MONITORING_EVENT_PY_YIELD) | + (1 << PY_MONITORING_EVENT_RAISE) | (1 << PY_MONITORING_EVENT_LINE) | + (1 << PY_MONITORING_EVENT_JUMP) | (1 << PY_MONITORING_EVENT_BRANCH) | + (1 << PY_MONITORING_EVENT_PY_UNWIND) | (1 << PY_MONITORING_EVENT_PY_THROW) | + (1 << PY_MONITORING_EVENT_STOP_ITERATION) | + (1 << PY_MONITORING_EVENT_EXCEPTION_HANDLED); + if (tstate->interp->f_opcode_trace_set) { + events |= (1 << PY_MONITORING_EVENT_INSTRUCTION); + } + } + return _PyMonitoring_SetEvents(PY_MONITORING_SYS_TRACE_ID, events); +} diff --git a/Python/makeopcodetargets.py b/Python/makeopcodetargets.py index 3bf2e35c..2b402ae0 100755 --- a/Python/makeopcodetargets.py +++ b/Python/makeopcodetargets.py @@ -7,24 +7,18 @@ import os import sys -try: - from importlib.machinery import SourceFileLoader -except ImportError: - import imp - - def find_module(modname): - """Finds and returns a module in the local dist/checkout. - """ - modpath = os.path.join( - os.path.dirname(os.path.dirname(__file__)), "Lib") - return imp.load_module(modname, *imp.find_module(modname, [modpath])) -else: - def find_module(modname): - """Finds and returns a module in the local dist/checkout. - """ - modpath = os.path.join( - os.path.dirname(os.path.dirname(__file__)), "Lib", modname + ".py") - return SourceFileLoader(modname, modpath).load_module() +# 2023-04-27(warsaw): Pre-Python 3.12, this would catch ImportErrors and try to +# import imp, and then use imp.load_module(). The imp module was removed in +# Python 3.12 (and long deprecated before that), and it's unclear under what +# conditions this import will now fail, so the fallback was simply removed. +from importlib.machinery import SourceFileLoader + +def find_module(modname): + """Finds and returns a module in the local dist/checkout. + """ + modpath = os.path.join( + os.path.dirname(os.path.dirname(__file__)), "Lib", modname + ".py") + return SourceFileLoader(modname, modpath).load_module() def write_contents(f): @@ -32,9 +26,9 @@ def write_contents(f): """ opcode = find_module('opcode') targets = ['_unknown_opcode'] * 256 - targets[255] = "TARGET_DO_TRACING" for opname, op in opcode.opmap.items(): - targets[op] = "TARGET_%s" % opname + if not opcode.is_pseudo(op): + targets[op] = "TARGET_%s" % opname next_op = 1 for opname in opcode._specialized_instructions: while targets[next_op] != '_unknown_opcode': diff --git a/Python/marshal.c b/Python/marshal.c index 2690f557..90953cbb 100644 --- a/Python/marshal.c +++ b/Python/marshal.c @@ -11,6 +11,7 @@ #include "Python.h" #include "pycore_call.h" // _PyObject_CallNoArgs() #include "pycore_code.h" // _PyCode_New() +#include "pycore_long.h" // _PyLong_DigitCount #include "pycore_hashtable.h" // _Py_hashtable_t #include "marshal.h" // Py_MARSHAL_VERSION @@ -232,15 +233,15 @@ w_PyLong(const PyLongObject *ob, char flag, WFILE *p) digit d; W_TYPE(TYPE_LONG, p); - if (Py_SIZE(ob) == 0) { + if (_PyLong_IsZero(ob)) { w_long((long)0, p); return; } /* set l to number of base PyLong_MARSHAL_BASE digits */ - n = Py_ABS(Py_SIZE(ob)); + n = _PyLong_DigitCount(ob); l = (n-1) * PyLong_MARSHAL_RATIO; - d = ob->ob_digit[n-1]; + d = ob->long_value.ob_digit[n-1]; assert(d != 0); /* a PyLong is always normalized */ do { d >>= PyLong_MARSHAL_SHIFT; @@ -251,17 +252,17 @@ w_PyLong(const PyLongObject *ob, char flag, WFILE *p) p->error = WFERR_UNMARSHALLABLE; return; } - w_long((long)(Py_SIZE(ob) > 0 ? l : -l), p); + w_long((long)(_PyLong_IsNegative(ob) ? -l : l), p); for (i=0; i < n-1; i++) { - d = ob->ob_digit[i]; + d = ob->long_value.ob_digit[i]; for (j=0; j < PyLong_MARSHAL_RATIO; j++) { w_short(d & PyLong_MARSHAL_MASK, p); d >>= PyLong_MARSHAL_SHIFT; } assert (d == 0); } - d = ob->ob_digit[n-1]; + d = ob->long_value.ob_digit[n-1]; do { w_short(d & PyLong_MARSHAL_MASK, p); d >>= PyLong_MARSHAL_SHIFT; @@ -326,8 +327,8 @@ w_ref(PyObject *v, char *flag, WFILE *p) goto err; } w = (int)s; - Py_INCREF(v); - if (_Py_hashtable_set(p->hashtable, v, (void *)(uintptr_t)w) < 0) { + if (_Py_hashtable_set(p->hashtable, Py_NewRef(v), + (void *)(uintptr_t)w) < 0) { Py_DECREF(v); goto err; } @@ -624,6 +625,10 @@ w_clear_refs(WFILE *wf) } /* version currently has no effect for writing ints. */ +/* Note that while the documentation states that this function + * can error, currently it never does. Setting an exception in + * this function should be regarded as an API-breaking change. + */ void PyMarshal_WriteLongToFile(long x, FILE *fp, int version) { @@ -746,23 +751,28 @@ r_string(Py_ssize_t n, RFILE *p) static int r_byte(RFILE *p) { - int c = EOF; - if (p->ptr != NULL) { - if (p->ptr < p->end) - c = (unsigned char) *p->ptr++; - return c; + if (p->ptr < p->end) { + return (unsigned char) *p->ptr++; + } } - if (!p->readable) { + else if (!p->readable) { assert(p->fp); - c = getc(p->fp); + int c = getc(p->fp); + if (c != EOF) { + return c; + } } else { const char *ptr = r_string(1, p); - if (ptr != NULL) - c = *(const unsigned char *) ptr; + if (ptr != NULL) { + return *(const unsigned char *) ptr; + } + return EOF; } - return c; + PyErr_SetString(PyExc_EOFError, + "EOF read where not expected"); + return EOF; } static int @@ -823,10 +833,11 @@ r_PyLong(RFILE *p) digit d; n = r_long(p); - if (PyErr_Occurred()) - return NULL; if (n == 0) return (PyObject *)_PyLong_New(0); + if (n == -1 && PyErr_Occurred()) { + return NULL; + } if (n < -SIZE32_MAX || n > SIZE32_MAX) { PyErr_SetString(PyExc_ValueError, "bad marshal data (long size out of range)"); @@ -839,30 +850,22 @@ r_PyLong(RFILE *p) if (ob == NULL) return NULL; - Py_SET_SIZE(ob, n > 0 ? size : -size); + _PyLong_SetSignAndDigitCount(ob, n < 0 ? -1 : 1, size); for (i = 0; i < size-1; i++) { d = 0; for (j=0; j < PyLong_MARSHAL_RATIO; j++) { md = r_short(p); - if (PyErr_Occurred()) { - Py_DECREF(ob); - return NULL; - } if (md < 0 || md > PyLong_MARSHAL_BASE) goto bad_digit; d += (digit)md << j*PyLong_MARSHAL_SHIFT; } - ob->ob_digit[i] = d; + ob->long_value.ob_digit[i] = d; } d = 0; for (j=0; j < shorts_in_top_digit; j++) { md = r_short(p); - if (PyErr_Occurred()) { - Py_DECREF(ob); - return NULL; - } if (md < 0 || md > PyLong_MARSHAL_BASE) goto bad_digit; /* topmost marshal digit should be nonzero */ @@ -874,18 +877,17 @@ r_PyLong(RFILE *p) } d += (digit)md << j*PyLong_MARSHAL_SHIFT; } - if (PyErr_Occurred()) { - Py_DECREF(ob); - return NULL; - } + assert(!PyErr_Occurred()); /* top digit should be nonzero, else the resulting PyLong won't be normalized */ - ob->ob_digit[size-1] = d; + ob->long_value.ob_digit[size-1] = d; return (PyObject *)ob; bad_digit: Py_DECREF(ob); - PyErr_SetString(PyExc_ValueError, - "bad marshal data (digit out of range in long)"); + if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_ValueError, + "bad marshal data (digit out of range in long)"); + } return NULL; } @@ -908,8 +910,6 @@ r_float_str(RFILE *p) const char *ptr; n = r_byte(p); if (n == EOF) { - PyErr_SetString(PyExc_EOFError, - "EOF read where object expected"); return -1; } ptr = r_string(n, p); @@ -951,8 +951,7 @@ r_ref_insert(PyObject *o, Py_ssize_t idx, int flag, RFILE *p) { if (o != NULL && flag) { /* currently only FLAG_REF is defined */ PyObject *tmp = PyList_GET_ITEM(p->refs, idx); - Py_INCREF(o); - PyList_SET_ITEM(p->refs, idx, o); + PyList_SET_ITEM(p->refs, idx, Py_NewRef(o)); Py_DECREF(tmp); } return o; @@ -988,8 +987,10 @@ r_object(RFILE *p) PyObject *retval = NULL; if (code == EOF) { - PyErr_SetString(PyExc_EOFError, - "EOF read where object expected"); + if (PyErr_ExceptionMatches(PyExc_EOFError)) { + PyErr_SetString(PyExc_EOFError, + "EOF read where object expected"); + } return NULL; } @@ -1015,33 +1016,31 @@ r_object(RFILE *p) break; case TYPE_NONE: - Py_INCREF(Py_None); - retval = Py_None; + retval = Py_NewRef(Py_None); break; case TYPE_STOPITER: - Py_INCREF(PyExc_StopIteration); - retval = PyExc_StopIteration; + retval = Py_NewRef(PyExc_StopIteration); break; case TYPE_ELLIPSIS: - Py_INCREF(Py_Ellipsis); - retval = Py_Ellipsis; + retval = Py_NewRef(Py_Ellipsis); break; case TYPE_FALSE: - Py_INCREF(Py_False); - retval = Py_False; + retval = Py_NewRef(Py_False); break; case TYPE_TRUE: - Py_INCREF(Py_True); - retval = Py_True; + retval = Py_NewRef(Py_True); break; case TYPE_INT: n = r_long(p); - retval = PyErr_Occurred() ? NULL : PyLong_FromLong(n); + if (n == -1 && PyErr_Occurred()) { + break; + } + retval = PyLong_FromLong(n); R_REF(retval); break; @@ -1107,10 +1106,11 @@ r_object(RFILE *p) { const char *ptr; n = r_long(p); - if (PyErr_Occurred()) - break; if (n < 0 || n > SIZE32_MAX) { - PyErr_SetString(PyExc_ValueError, "bad marshal data (bytes object size out of range)"); + if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_ValueError, + "bad marshal data (bytes object size out of range)"); + } break; } v = PyBytes_FromStringAndSize((char *)NULL, n); @@ -1132,10 +1132,11 @@ r_object(RFILE *p) /* fall through */ case TYPE_ASCII: n = r_long(p); - if (PyErr_Occurred()) - break; if (n < 0 || n > SIZE32_MAX) { - PyErr_SetString(PyExc_ValueError, "bad marshal data (string size out of range)"); + if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_ValueError, + "bad marshal data (string size out of range)"); + } break; } goto _read_ascii; @@ -1146,8 +1147,6 @@ r_object(RFILE *p) case TYPE_SHORT_ASCII: n = r_byte(p); if (n == EOF) { - PyErr_SetString(PyExc_EOFError, - "EOF read where object expected"); break; } _read_ascii: @@ -1174,10 +1173,11 @@ r_object(RFILE *p) const char *buffer; n = r_long(p); - if (PyErr_Occurred()) - break; if (n < 0 || n > SIZE32_MAX) { - PyErr_SetString(PyExc_ValueError, "bad marshal data (string size out of range)"); + if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_ValueError, + "bad marshal data (string size out of range)"); + } break; } if (n != 0) { @@ -1199,16 +1199,18 @@ r_object(RFILE *p) } case TYPE_SMALL_TUPLE: - n = (unsigned char) r_byte(p); - if (PyErr_Occurred()) + n = r_byte(p); + if (n == EOF) { break; + } goto _read_tuple; case TYPE_TUPLE: n = r_long(p); - if (PyErr_Occurred()) - break; if (n < 0 || n > SIZE32_MAX) { - PyErr_SetString(PyExc_ValueError, "bad marshal data (tuple size out of range)"); + if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_ValueError, + "bad marshal data (tuple size out of range)"); + } break; } _read_tuple: @@ -1223,8 +1225,7 @@ r_object(RFILE *p) if (!PyErr_Occurred()) PyErr_SetString(PyExc_TypeError, "NULL object in marshal data for tuple"); - Py_DECREF(v); - v = NULL; + Py_SETREF(v, NULL); break; } PyTuple_SET_ITEM(v, i, v2); @@ -1234,10 +1235,11 @@ r_object(RFILE *p) case TYPE_LIST: n = r_long(p); - if (PyErr_Occurred()) - break; if (n < 0 || n > SIZE32_MAX) { - PyErr_SetString(PyExc_ValueError, "bad marshal data (list size out of range)"); + if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_ValueError, + "bad marshal data (list size out of range)"); + } break; } v = PyList_New(n); @@ -1250,8 +1252,7 @@ r_object(RFILE *p) if (!PyErr_Occurred()) PyErr_SetString(PyExc_TypeError, "NULL object in marshal data for list"); - Py_DECREF(v); - v = NULL; + Py_SETREF(v, NULL); break; } PyList_SET_ITEM(v, i, v2); @@ -1283,8 +1284,7 @@ r_object(RFILE *p) Py_DECREF(val); } if (PyErr_Occurred()) { - Py_DECREF(v); - v = NULL; + Py_SETREF(v, NULL); } retval = v; break; @@ -1292,10 +1292,11 @@ r_object(RFILE *p) case TYPE_SET: case TYPE_FROZENSET: n = r_long(p); - if (PyErr_Occurred()) - break; if (n < 0 || n > SIZE32_MAX) { - PyErr_SetString(PyExc_ValueError, "bad marshal data (set size out of range)"); + if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_ValueError, + "bad marshal data (set size out of range)"); + } break; } @@ -1328,8 +1329,7 @@ r_object(RFILE *p) if (!PyErr_Occurred()) PyErr_SetString(PyExc_TypeError, "NULL object in marshal data for set"); - Py_DECREF(v); - v = NULL; + Py_SETREF(v, NULL); break; } if (PySet_Add(v, v2) == -1) { @@ -1373,20 +1373,20 @@ r_object(RFILE *p) /* XXX ignore long->int overflows for now */ argcount = (int)r_long(p); - if (PyErr_Occurred()) + if (argcount == -1 && PyErr_Occurred()) goto code_error; posonlyargcount = (int)r_long(p); - if (PyErr_Occurred()) { + if (posonlyargcount == -1 && PyErr_Occurred()) { goto code_error; } kwonlyargcount = (int)r_long(p); - if (PyErr_Occurred()) + if (kwonlyargcount == -1 && PyErr_Occurred()) goto code_error; stacksize = (int)r_long(p); - if (PyErr_Occurred()) + if (stacksize == -1 && PyErr_Occurred()) goto code_error; flags = (int)r_long(p); - if (PyErr_Occurred()) + if (flags == -1 && PyErr_Occurred()) goto code_error; code = r_object(p); if (code == NULL) @@ -1459,6 +1459,10 @@ r_object(RFILE *p) v = r_ref_insert(v, idx, flag, p); code_error: + if (v == NULL && !PyErr_Occurred()) { + PyErr_SetString(PyExc_TypeError, + "NULL object in marshal data for code object"); + } Py_XDECREF(code); Py_XDECREF(consts); Py_XDECREF(names); @@ -1476,9 +1480,10 @@ r_object(RFILE *p) case TYPE_REF: n = r_long(p); if (n < 0 || n >= PyList_GET_SIZE(p->refs)) { - if (n == -1 && PyErr_Occurred()) - break; - PyErr_SetString(PyExc_ValueError, "bad marshal data (invalid reference)"); + if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_ValueError, + "bad marshal data (invalid reference)"); + } break; } v = PyList_GET_ITEM(p->refs, n); @@ -1486,8 +1491,7 @@ r_object(RFILE *p) PyErr_SetString(PyExc_ValueError, "bad marshal data (invalid reference)"); break; } - Py_INCREF(v); - retval = v; + retval = Py_NewRef(v); break; default: @@ -1880,6 +1884,7 @@ marshal_module_exec(PyObject *mod) static PyModuleDef_Slot marshalmodule_slots[] = { {Py_mod_exec, marshal_module_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, {0, NULL} }; diff --git a/Python/modsupport.c b/Python/modsupport.c index 8655daa1..df4ae35a 100644 --- a/Python/modsupport.c +++ b/Python/modsupport.c @@ -3,6 +3,7 @@ #include "Python.h" #include "pycore_abstract.h" // _PyIndex_Check() +#include "pycore_object.h" // _PyType_IsReady() #define FLAG_SIZE_T 1 typedef double va_double; @@ -10,9 +11,6 @@ typedef double va_double; static PyObject *va_build_value(const char *, va_list, int); static PyObject **va_build_stack(PyObject **small_stack, Py_ssize_t small_stack_len, const char *, va_list, int, Py_ssize_t*); -/* Package context -- the full module name for package imports */ -const char *_Py_PackageContext = NULL; - int _Py_convert_optional_to_ssize_t(PyObject *obj, void *result) @@ -96,16 +94,12 @@ static PyObject *do_mkvalue(const char**, va_list *, int); static void do_ignore(const char **p_format, va_list *p_va, char endchar, Py_ssize_t n, int flags) { - PyObject *v; - Py_ssize_t i; assert(PyErr_Occurred()); - v = PyTuple_New(n); - for (i = 0; i < n; i++) { - PyObject *exception, *value, *tb, *w; - - PyErr_Fetch(&exception, &value, &tb); - w = do_mkvalue(p_format, p_va, flags); - PyErr_Restore(exception, value, tb); + PyObject *v = PyTuple_New(n); + for (Py_ssize_t i = 0; i < n; i++) { + PyObject *exc = PyErr_GetRaisedException(); + PyObject *w = do_mkvalue(p_format, p_va, flags); + PyErr_SetRaisedException(exc); if (w != NULL) { if (v != NULL) { PyTuple_SET_ITEM(v, i, w); @@ -359,8 +353,7 @@ do_mkvalue(const char **p_format, va_list *p_va, int flags) else n = -1; if (u == NULL) { - v = Py_None; - Py_INCREF(v); + v = Py_NewRef(Py_None); } else { if (n < 0) @@ -410,8 +403,7 @@ do_mkvalue(const char **p_format, va_list *p_va, int flags) else n = -1; if (str == NULL) { - v = Py_None; - Py_INCREF(v); + v = Py_NewRef(Py_None); } else { if (n < 0) { @@ -446,8 +438,7 @@ do_mkvalue(const char **p_format, va_list *p_va, int flags) else n = -1; if (str == NULL) { - v = Py_None; - Py_INCREF(v); + v = Py_NewRef(Py_None); } else { if (n < 0) { @@ -658,13 +649,16 @@ PyModule_AddObjectRef(PyObject *mod, const char *name, PyObject *value) PyModule_GetName(mod)); return -1; } - - if (PyDict_SetItemString(dict, name, value)) { - return -1; - } - return 0; + return PyDict_SetItemString(dict, name, value); } +int +_PyModule_Add(PyObject *mod, const char *name, PyObject *value) +{ + int res = PyModule_AddObjectRef(mod, name, value); + Py_XDECREF(value); + return res; +} int PyModule_AddObject(PyObject *mod, const char *name, PyObject *value) @@ -679,31 +673,19 @@ PyModule_AddObject(PyObject *mod, const char *name, PyObject *value) int PyModule_AddIntConstant(PyObject *m, const char *name, long value) { - PyObject *obj = PyLong_FromLong(value); - if (!obj) { - return -1; - } - int res = PyModule_AddObjectRef(m, name, obj); - Py_DECREF(obj); - return res; + return _PyModule_Add(m, name, PyLong_FromLong(value)); } int PyModule_AddStringConstant(PyObject *m, const char *name, const char *value) { - PyObject *obj = PyUnicode_FromString(value); - if (!obj) { - return -1; - } - int res = PyModule_AddObjectRef(m, name, obj); - Py_DECREF(obj); - return res; + return _PyModule_Add(m, name, PyUnicode_FromString(value)); } int PyModule_AddType(PyObject *module, PyTypeObject *type) { - if (PyType_Ready(type) < 0) { + if (!_PyType_IsReady(type) && PyType_Ready(type) < 0) { return -1; } diff --git a/Python/opcode_metadata.h b/Python/opcode_metadata.h new file mode 100644 index 00000000..f9b1c928 --- /dev/null +++ b/Python/opcode_metadata.h @@ -0,0 +1,1001 @@ +// This file is generated by Tools/cases_generator/generate_cases.py +// from: +// Python/bytecodes.c +// Do not edit! + +#ifndef NEED_OPCODE_METADATA +extern int _PyOpcode_num_popped(int opcode, int oparg, bool jump); +#else +int +_PyOpcode_num_popped(int opcode, int oparg, bool jump) { + switch(opcode) { + case NOP: + return 0; + case RESUME: + return 0; + case INSTRUMENTED_RESUME: + return 0; + case LOAD_CLOSURE: + return 0; + case LOAD_FAST_CHECK: + return 0; + case LOAD_FAST: + return 0; + case LOAD_FAST_AND_CLEAR: + return 0; + case LOAD_CONST: + return 0; + case STORE_FAST: + return 1; + case LOAD_FAST__LOAD_FAST: + return 0+0; + case LOAD_FAST__LOAD_CONST: + return 0+0; + case STORE_FAST__LOAD_FAST: + return 1+0; + case STORE_FAST__STORE_FAST: + return 1+1; + case LOAD_CONST__LOAD_FAST: + return 0+0; + case POP_TOP: + return 1; + case PUSH_NULL: + return 0; + case END_FOR: + return 1+1; + case INSTRUMENTED_END_FOR: + return 2; + case END_SEND: + return 2; + case INSTRUMENTED_END_SEND: + return 2; + case UNARY_NEGATIVE: + return 1; + case UNARY_NOT: + return 1; + case UNARY_INVERT: + return 1; + case BINARY_OP_MULTIPLY_INT: + return 2; + case BINARY_OP_MULTIPLY_FLOAT: + return 2; + case BINARY_OP_SUBTRACT_INT: + return 2; + case BINARY_OP_SUBTRACT_FLOAT: + return 2; + case BINARY_OP_ADD_UNICODE: + return 2; + case BINARY_OP_INPLACE_ADD_UNICODE: + return 2; + case BINARY_OP_ADD_FLOAT: + return 2; + case BINARY_OP_ADD_INT: + return 2; + case BINARY_SUBSCR: + return 2; + case BINARY_SLICE: + return 3; + case STORE_SLICE: + return 4; + case BINARY_SUBSCR_LIST_INT: + return 2; + case BINARY_SUBSCR_TUPLE_INT: + return 2; + case BINARY_SUBSCR_DICT: + return 2; + case BINARY_SUBSCR_GETITEM: + return 2; + case LIST_APPEND: + return (oparg-1) + 2; + case SET_ADD: + return (oparg-1) + 2; + case STORE_SUBSCR: + return 3; + case STORE_SUBSCR_LIST_INT: + return 3; + case STORE_SUBSCR_DICT: + return 3; + case DELETE_SUBSCR: + return 2; + case CALL_INTRINSIC_1: + return 1; + case CALL_INTRINSIC_2: + return 2; + case RAISE_VARARGS: + return oparg; + case INTERPRETER_EXIT: + return 1; + case RETURN_VALUE: + return 1; + case INSTRUMENTED_RETURN_VALUE: + return 1; + case RETURN_CONST: + return 0; + case INSTRUMENTED_RETURN_CONST: + return 0; + case GET_AITER: + return 1; + case GET_ANEXT: + return 1; + case GET_AWAITABLE: + return 1; + case SEND: + return 2; + case SEND_GEN: + return 2; + case INSTRUMENTED_YIELD_VALUE: + return 1; + case YIELD_VALUE: + return 1; + case POP_EXCEPT: + return 1; + case RERAISE: + return oparg + 1; + case END_ASYNC_FOR: + return 2; + case CLEANUP_THROW: + return 3; + case LOAD_ASSERTION_ERROR: + return 0; + case LOAD_BUILD_CLASS: + return 0; + case STORE_NAME: + return 1; + case DELETE_NAME: + return 0; + case UNPACK_SEQUENCE: + return 1; + case UNPACK_SEQUENCE_TWO_TUPLE: + return 1; + case UNPACK_SEQUENCE_TUPLE: + return 1; + case UNPACK_SEQUENCE_LIST: + return 1; + case UNPACK_EX: + return 1; + case STORE_ATTR: + return 2; + case DELETE_ATTR: + return 1; + case STORE_GLOBAL: + return 1; + case DELETE_GLOBAL: + return 0; + case LOAD_LOCALS: + return 0; + case LOAD_FROM_DICT_OR_GLOBALS: + return 1; + case LOAD_NAME: + return 0; + case LOAD_GLOBAL: + return 0; + case LOAD_GLOBAL_MODULE: + return 0; + case LOAD_GLOBAL_BUILTIN: + return 0; + case DELETE_FAST: + return 0; + case MAKE_CELL: + return 0; + case DELETE_DEREF: + return 0; + case LOAD_FROM_DICT_OR_DEREF: + return 1; + case LOAD_DEREF: + return 0; + case STORE_DEREF: + return 1; + case COPY_FREE_VARS: + return 0; + case BUILD_STRING: + return oparg; + case BUILD_TUPLE: + return oparg; + case BUILD_LIST: + return oparg; + case LIST_EXTEND: + return (oparg-1) + 2; + case SET_UPDATE: + return (oparg-1) + 2; + case BUILD_SET: + return oparg; + case BUILD_MAP: + return oparg*2; + case SETUP_ANNOTATIONS: + return 0; + case BUILD_CONST_KEY_MAP: + return oparg + 1; + case DICT_UPDATE: + return 1; + case DICT_MERGE: + return 1; + case MAP_ADD: + return 2; + case INSTRUMENTED_LOAD_SUPER_ATTR: + return 3; + case LOAD_SUPER_ATTR: + return 3; + case LOAD_SUPER_ATTR_ATTR: + return 3; + case LOAD_SUPER_ATTR_METHOD: + return 3; + case LOAD_ATTR: + return 1; + case LOAD_ATTR_INSTANCE_VALUE: + return 1; + case LOAD_ATTR_MODULE: + return 1; + case LOAD_ATTR_WITH_HINT: + return 1; + case LOAD_ATTR_SLOT: + return 1; + case LOAD_ATTR_CLASS: + return 1; + case LOAD_ATTR_PROPERTY: + return 1; + case LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN: + return 1; + case STORE_ATTR_INSTANCE_VALUE: + return 2; + case STORE_ATTR_WITH_HINT: + return 2; + case STORE_ATTR_SLOT: + return 2; + case COMPARE_OP: + return 2; + case COMPARE_OP_FLOAT: + return 2; + case COMPARE_OP_INT: + return 2; + case COMPARE_OP_STR: + return 2; + case IS_OP: + return 2; + case CONTAINS_OP: + return 2; + case CHECK_EG_MATCH: + return 2; + case CHECK_EXC_MATCH: + return 2; + case IMPORT_NAME: + return 2; + case IMPORT_FROM: + return 1; + case JUMP_FORWARD: + return 0; + case JUMP_BACKWARD: + return 0; + case POP_JUMP_IF_FALSE: + return 1; + case POP_JUMP_IF_TRUE: + return 1; + case POP_JUMP_IF_NOT_NONE: + return 1; + case POP_JUMP_IF_NONE: + return 1; + case JUMP_BACKWARD_NO_INTERRUPT: + return 0; + case GET_LEN: + return 1; + case MATCH_CLASS: + return 3; + case MATCH_MAPPING: + return 1; + case MATCH_SEQUENCE: + return 1; + case MATCH_KEYS: + return 2; + case GET_ITER: + return 1; + case GET_YIELD_FROM_ITER: + return 1; + case FOR_ITER: + return 1; + case INSTRUMENTED_FOR_ITER: + return 0; + case FOR_ITER_LIST: + return 1; + case FOR_ITER_TUPLE: + return 1; + case FOR_ITER_RANGE: + return 1; + case FOR_ITER_GEN: + return 1; + case BEFORE_ASYNC_WITH: + return 1; + case BEFORE_WITH: + return 1; + case WITH_EXCEPT_START: + return 4; + case PUSH_EXC_INFO: + return 1; + case LOAD_ATTR_METHOD_WITH_VALUES: + return 1; + case LOAD_ATTR_METHOD_NO_DICT: + return 1; + case LOAD_ATTR_METHOD_LAZY_DICT: + return 1; + case KW_NAMES: + return 0; + case INSTRUMENTED_CALL: + return 0; + case CALL: + return oparg + 2; + case CALL_BOUND_METHOD_EXACT_ARGS: + return oparg + 2; + case CALL_PY_EXACT_ARGS: + return oparg + 2; + case CALL_PY_WITH_DEFAULTS: + return oparg + 2; + case CALL_NO_KW_TYPE_1: + return oparg + 2; + case CALL_NO_KW_STR_1: + return oparg + 2; + case CALL_NO_KW_TUPLE_1: + return oparg + 2; + case CALL_BUILTIN_CLASS: + return oparg + 2; + case CALL_NO_KW_BUILTIN_O: + return oparg + 2; + case CALL_NO_KW_BUILTIN_FAST: + return oparg + 2; + case CALL_BUILTIN_FAST_WITH_KEYWORDS: + return oparg + 2; + case CALL_NO_KW_LEN: + return oparg + 2; + case CALL_NO_KW_ISINSTANCE: + return oparg + 2; + case CALL_NO_KW_LIST_APPEND: + return oparg + 2; + case CALL_NO_KW_METHOD_DESCRIPTOR_O: + return oparg + 2; + case CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS: + return oparg + 2; + case CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS: + return oparg + 2; + case CALL_NO_KW_METHOD_DESCRIPTOR_FAST: + return oparg + 2; + case INSTRUMENTED_CALL_FUNCTION_EX: + return 0; + case CALL_FUNCTION_EX: + return ((oparg & 1) ? 1 : 0) + 3; + case MAKE_FUNCTION: + return ((oparg & 0x01) ? 1 : 0) + ((oparg & 0x02) ? 1 : 0) + ((oparg & 0x04) ? 1 : 0) + ((oparg & 0x08) ? 1 : 0) + 1; + case RETURN_GENERATOR: + return 0; + case BUILD_SLICE: + return ((oparg == 3) ? 1 : 0) + 2; + case FORMAT_VALUE: + return (((oparg & FVS_MASK) == FVS_HAVE_SPEC) ? 1 : 0) + 1; + case COPY: + return (oparg-1) + 1; + case BINARY_OP: + return 2; + case SWAP: + return (oparg-2) + 2; + case INSTRUMENTED_INSTRUCTION: + return 0; + case INSTRUMENTED_JUMP_FORWARD: + return 0; + case INSTRUMENTED_JUMP_BACKWARD: + return 0; + case INSTRUMENTED_POP_JUMP_IF_TRUE: + return 0; + case INSTRUMENTED_POP_JUMP_IF_FALSE: + return 0; + case INSTRUMENTED_POP_JUMP_IF_NONE: + return 0; + case INSTRUMENTED_POP_JUMP_IF_NOT_NONE: + return 0; + case EXTENDED_ARG: + return 0; + case CACHE: + return 0; + case RESERVED: + return 0; + default: + return -1; + } +} +#endif + +#ifndef NEED_OPCODE_METADATA +extern int _PyOpcode_num_pushed(int opcode, int oparg, bool jump); +#else +int +_PyOpcode_num_pushed(int opcode, int oparg, bool jump) { + switch(opcode) { + case NOP: + return 0; + case RESUME: + return 0; + case INSTRUMENTED_RESUME: + return 0; + case LOAD_CLOSURE: + return 1; + case LOAD_FAST_CHECK: + return 1; + case LOAD_FAST: + return 1; + case LOAD_FAST_AND_CLEAR: + return 1; + case LOAD_CONST: + return 1; + case STORE_FAST: + return 0; + case LOAD_FAST__LOAD_FAST: + return 1+1; + case LOAD_FAST__LOAD_CONST: + return 1+1; + case STORE_FAST__LOAD_FAST: + return 0+1; + case STORE_FAST__STORE_FAST: + return 0+0; + case LOAD_CONST__LOAD_FAST: + return 1+1; + case POP_TOP: + return 0; + case PUSH_NULL: + return 1; + case END_FOR: + return 0+0; + case INSTRUMENTED_END_FOR: + return 0; + case END_SEND: + return 1; + case INSTRUMENTED_END_SEND: + return 1; + case UNARY_NEGATIVE: + return 1; + case UNARY_NOT: + return 1; + case UNARY_INVERT: + return 1; + case BINARY_OP_MULTIPLY_INT: + return 1; + case BINARY_OP_MULTIPLY_FLOAT: + return 1; + case BINARY_OP_SUBTRACT_INT: + return 1; + case BINARY_OP_SUBTRACT_FLOAT: + return 1; + case BINARY_OP_ADD_UNICODE: + return 1; + case BINARY_OP_INPLACE_ADD_UNICODE: + return 0; + case BINARY_OP_ADD_FLOAT: + return 1; + case BINARY_OP_ADD_INT: + return 1; + case BINARY_SUBSCR: + return 1; + case BINARY_SLICE: + return 1; + case STORE_SLICE: + return 0; + case BINARY_SUBSCR_LIST_INT: + return 1; + case BINARY_SUBSCR_TUPLE_INT: + return 1; + case BINARY_SUBSCR_DICT: + return 1; + case BINARY_SUBSCR_GETITEM: + return 1; + case LIST_APPEND: + return (oparg-1) + 1; + case SET_ADD: + return (oparg-1) + 1; + case STORE_SUBSCR: + return 0; + case STORE_SUBSCR_LIST_INT: + return 0; + case STORE_SUBSCR_DICT: + return 0; + case DELETE_SUBSCR: + return 0; + case CALL_INTRINSIC_1: + return 1; + case CALL_INTRINSIC_2: + return 1; + case RAISE_VARARGS: + return 0; + case INTERPRETER_EXIT: + return 0; + case RETURN_VALUE: + return 0; + case INSTRUMENTED_RETURN_VALUE: + return 0; + case RETURN_CONST: + return 0; + case INSTRUMENTED_RETURN_CONST: + return 0; + case GET_AITER: + return 1; + case GET_ANEXT: + return 2; + case GET_AWAITABLE: + return 1; + case SEND: + return 2; + case SEND_GEN: + return 2; + case INSTRUMENTED_YIELD_VALUE: + return 1; + case YIELD_VALUE: + return 1; + case POP_EXCEPT: + return 0; + case RERAISE: + return oparg; + case END_ASYNC_FOR: + return 0; + case CLEANUP_THROW: + return 2; + case LOAD_ASSERTION_ERROR: + return 1; + case LOAD_BUILD_CLASS: + return 1; + case STORE_NAME: + return 0; + case DELETE_NAME: + return 0; + case UNPACK_SEQUENCE: + return oparg; + case UNPACK_SEQUENCE_TWO_TUPLE: + return oparg; + case UNPACK_SEQUENCE_TUPLE: + return oparg; + case UNPACK_SEQUENCE_LIST: + return oparg; + case UNPACK_EX: + return (oparg & 0xFF) + (oparg >> 8) + 1; + case STORE_ATTR: + return 0; + case DELETE_ATTR: + return 0; + case STORE_GLOBAL: + return 0; + case DELETE_GLOBAL: + return 0; + case LOAD_LOCALS: + return 1; + case LOAD_FROM_DICT_OR_GLOBALS: + return 1; + case LOAD_NAME: + return 1; + case LOAD_GLOBAL: + return ((oparg & 1) ? 1 : 0) + 1; + case LOAD_GLOBAL_MODULE: + return ((oparg & 1) ? 1 : 0) + 1; + case LOAD_GLOBAL_BUILTIN: + return ((oparg & 1) ? 1 : 0) + 1; + case DELETE_FAST: + return 0; + case MAKE_CELL: + return 0; + case DELETE_DEREF: + return 0; + case LOAD_FROM_DICT_OR_DEREF: + return 1; + case LOAD_DEREF: + return 1; + case STORE_DEREF: + return 0; + case COPY_FREE_VARS: + return 0; + case BUILD_STRING: + return 1; + case BUILD_TUPLE: + return 1; + case BUILD_LIST: + return 1; + case LIST_EXTEND: + return (oparg-1) + 1; + case SET_UPDATE: + return (oparg-1) + 1; + case BUILD_SET: + return 1; + case BUILD_MAP: + return 1; + case SETUP_ANNOTATIONS: + return 0; + case BUILD_CONST_KEY_MAP: + return 1; + case DICT_UPDATE: + return 0; + case DICT_MERGE: + return 0; + case MAP_ADD: + return 0; + case INSTRUMENTED_LOAD_SUPER_ATTR: + return ((oparg & 1) ? 1 : 0) + 1; + case LOAD_SUPER_ATTR: + return ((oparg & 1) ? 1 : 0) + 1; + case LOAD_SUPER_ATTR_ATTR: + return ((oparg & 1) ? 1 : 0) + 1; + case LOAD_SUPER_ATTR_METHOD: + return 2; + case LOAD_ATTR: + return ((oparg & 1) ? 1 : 0) + 1; + case LOAD_ATTR_INSTANCE_VALUE: + return ((oparg & 1) ? 1 : 0) + 1; + case LOAD_ATTR_MODULE: + return ((oparg & 1) ? 1 : 0) + 1; + case LOAD_ATTR_WITH_HINT: + return ((oparg & 1) ? 1 : 0) + 1; + case LOAD_ATTR_SLOT: + return ((oparg & 1) ? 1 : 0) + 1; + case LOAD_ATTR_CLASS: + return ((oparg & 1) ? 1 : 0) + 1; + case LOAD_ATTR_PROPERTY: + return ((oparg & 1) ? 1 : 0) + 1; + case LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN: + return ((oparg & 1) ? 1 : 0) + 1; + case STORE_ATTR_INSTANCE_VALUE: + return 0; + case STORE_ATTR_WITH_HINT: + return 0; + case STORE_ATTR_SLOT: + return 0; + case COMPARE_OP: + return 1; + case COMPARE_OP_FLOAT: + return 1; + case COMPARE_OP_INT: + return 1; + case COMPARE_OP_STR: + return 1; + case IS_OP: + return 1; + case CONTAINS_OP: + return 1; + case CHECK_EG_MATCH: + return 2; + case CHECK_EXC_MATCH: + return 2; + case IMPORT_NAME: + return 1; + case IMPORT_FROM: + return 2; + case JUMP_FORWARD: + return 0; + case JUMP_BACKWARD: + return 0; + case POP_JUMP_IF_FALSE: + return 0; + case POP_JUMP_IF_TRUE: + return 0; + case POP_JUMP_IF_NOT_NONE: + return 0; + case POP_JUMP_IF_NONE: + return 0; + case JUMP_BACKWARD_NO_INTERRUPT: + return 0; + case GET_LEN: + return 2; + case MATCH_CLASS: + return 1; + case MATCH_MAPPING: + return 2; + case MATCH_SEQUENCE: + return 2; + case MATCH_KEYS: + return 3; + case GET_ITER: + return 1; + case GET_YIELD_FROM_ITER: + return 1; + case FOR_ITER: + return 2; + case INSTRUMENTED_FOR_ITER: + return 0; + case FOR_ITER_LIST: + return 2; + case FOR_ITER_TUPLE: + return 2; + case FOR_ITER_RANGE: + return 2; + case FOR_ITER_GEN: + return 2; + case BEFORE_ASYNC_WITH: + return 2; + case BEFORE_WITH: + return 2; + case WITH_EXCEPT_START: + return 5; + case PUSH_EXC_INFO: + return 2; + case LOAD_ATTR_METHOD_WITH_VALUES: + return ((oparg & 1) ? 1 : 0) + 1; + case LOAD_ATTR_METHOD_NO_DICT: + return ((oparg & 1) ? 1 : 0) + 1; + case LOAD_ATTR_METHOD_LAZY_DICT: + return ((oparg & 1) ? 1 : 0) + 1; + case KW_NAMES: + return 0; + case INSTRUMENTED_CALL: + return 0; + case CALL: + return 1; + case CALL_BOUND_METHOD_EXACT_ARGS: + return 1; + case CALL_PY_EXACT_ARGS: + return 1; + case CALL_PY_WITH_DEFAULTS: + return 1; + case CALL_NO_KW_TYPE_1: + return 1; + case CALL_NO_KW_STR_1: + return 1; + case CALL_NO_KW_TUPLE_1: + return 1; + case CALL_BUILTIN_CLASS: + return 1; + case CALL_NO_KW_BUILTIN_O: + return 1; + case CALL_NO_KW_BUILTIN_FAST: + return 1; + case CALL_BUILTIN_FAST_WITH_KEYWORDS: + return 1; + case CALL_NO_KW_LEN: + return 1; + case CALL_NO_KW_ISINSTANCE: + return 1; + case CALL_NO_KW_LIST_APPEND: + return 1; + case CALL_NO_KW_METHOD_DESCRIPTOR_O: + return 1; + case CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS: + return 1; + case CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS: + return 1; + case CALL_NO_KW_METHOD_DESCRIPTOR_FAST: + return 1; + case INSTRUMENTED_CALL_FUNCTION_EX: + return 0; + case CALL_FUNCTION_EX: + return 1; + case MAKE_FUNCTION: + return 1; + case RETURN_GENERATOR: + return 0; + case BUILD_SLICE: + return 1; + case FORMAT_VALUE: + return 1; + case COPY: + return (oparg-1) + 2; + case BINARY_OP: + return 1; + case SWAP: + return (oparg-2) + 2; + case INSTRUMENTED_INSTRUCTION: + return 0; + case INSTRUMENTED_JUMP_FORWARD: + return 0; + case INSTRUMENTED_JUMP_BACKWARD: + return 0; + case INSTRUMENTED_POP_JUMP_IF_TRUE: + return 0; + case INSTRUMENTED_POP_JUMP_IF_FALSE: + return 0; + case INSTRUMENTED_POP_JUMP_IF_NONE: + return 0; + case INSTRUMENTED_POP_JUMP_IF_NOT_NONE: + return 0; + case EXTENDED_ARG: + return 0; + case CACHE: + return 0; + case RESERVED: + return 0; + default: + return -1; + } +} +#endif + +enum InstructionFormat { INSTR_FMT_IB, INSTR_FMT_IBC, INSTR_FMT_IBC00, INSTR_FMT_IBC000, INSTR_FMT_IBC00000000, INSTR_FMT_IBIB, INSTR_FMT_IX, INSTR_FMT_IXC, INSTR_FMT_IXC000 }; +struct opcode_metadata { + bool valid_entry; + enum InstructionFormat instr_format; +}; + +#ifndef NEED_OPCODE_METADATA +extern const struct opcode_metadata _PyOpcode_opcode_metadata[256]; +#else +const struct opcode_metadata _PyOpcode_opcode_metadata[256] = { + [NOP] = { true, INSTR_FMT_IX }, + [RESUME] = { true, INSTR_FMT_IB }, + [INSTRUMENTED_RESUME] = { true, INSTR_FMT_IB }, + [LOAD_CLOSURE] = { true, INSTR_FMT_IB }, + [LOAD_FAST_CHECK] = { true, INSTR_FMT_IB }, + [LOAD_FAST] = { true, INSTR_FMT_IB }, + [LOAD_FAST_AND_CLEAR] = { true, INSTR_FMT_IB }, + [LOAD_CONST] = { true, INSTR_FMT_IB }, + [STORE_FAST] = { true, INSTR_FMT_IB }, + [LOAD_FAST__LOAD_FAST] = { true, INSTR_FMT_IBIB }, + [LOAD_FAST__LOAD_CONST] = { true, INSTR_FMT_IBIB }, + [STORE_FAST__LOAD_FAST] = { true, INSTR_FMT_IBIB }, + [STORE_FAST__STORE_FAST] = { true, INSTR_FMT_IBIB }, + [LOAD_CONST__LOAD_FAST] = { true, INSTR_FMT_IBIB }, + [POP_TOP] = { true, INSTR_FMT_IX }, + [PUSH_NULL] = { true, INSTR_FMT_IX }, + [END_FOR] = { true, INSTR_FMT_IB }, + [INSTRUMENTED_END_FOR] = { true, INSTR_FMT_IX }, + [END_SEND] = { true, INSTR_FMT_IX }, + [INSTRUMENTED_END_SEND] = { true, INSTR_FMT_IX }, + [UNARY_NEGATIVE] = { true, INSTR_FMT_IX }, + [UNARY_NOT] = { true, INSTR_FMT_IX }, + [UNARY_INVERT] = { true, INSTR_FMT_IX }, + [BINARY_OP_MULTIPLY_INT] = { true, INSTR_FMT_IXC }, + [BINARY_OP_MULTIPLY_FLOAT] = { true, INSTR_FMT_IXC }, + [BINARY_OP_SUBTRACT_INT] = { true, INSTR_FMT_IXC }, + [BINARY_OP_SUBTRACT_FLOAT] = { true, INSTR_FMT_IXC }, + [BINARY_OP_ADD_UNICODE] = { true, INSTR_FMT_IXC }, + [BINARY_OP_INPLACE_ADD_UNICODE] = { true, INSTR_FMT_IX }, + [BINARY_OP_ADD_FLOAT] = { true, INSTR_FMT_IXC }, + [BINARY_OP_ADD_INT] = { true, INSTR_FMT_IXC }, + [BINARY_SUBSCR] = { true, INSTR_FMT_IXC }, + [BINARY_SLICE] = { true, INSTR_FMT_IX }, + [STORE_SLICE] = { true, INSTR_FMT_IX }, + [BINARY_SUBSCR_LIST_INT] = { true, INSTR_FMT_IXC }, + [BINARY_SUBSCR_TUPLE_INT] = { true, INSTR_FMT_IXC }, + [BINARY_SUBSCR_DICT] = { true, INSTR_FMT_IXC }, + [BINARY_SUBSCR_GETITEM] = { true, INSTR_FMT_IXC }, + [LIST_APPEND] = { true, INSTR_FMT_IB }, + [SET_ADD] = { true, INSTR_FMT_IB }, + [STORE_SUBSCR] = { true, INSTR_FMT_IXC }, + [STORE_SUBSCR_LIST_INT] = { true, INSTR_FMT_IXC }, + [STORE_SUBSCR_DICT] = { true, INSTR_FMT_IXC }, + [DELETE_SUBSCR] = { true, INSTR_FMT_IX }, + [CALL_INTRINSIC_1] = { true, INSTR_FMT_IB }, + [CALL_INTRINSIC_2] = { true, INSTR_FMT_IB }, + [RAISE_VARARGS] = { true, INSTR_FMT_IB }, + [INTERPRETER_EXIT] = { true, INSTR_FMT_IX }, + [RETURN_VALUE] = { true, INSTR_FMT_IX }, + [INSTRUMENTED_RETURN_VALUE] = { true, INSTR_FMT_IX }, + [RETURN_CONST] = { true, INSTR_FMT_IB }, + [INSTRUMENTED_RETURN_CONST] = { true, INSTR_FMT_IB }, + [GET_AITER] = { true, INSTR_FMT_IX }, + [GET_ANEXT] = { true, INSTR_FMT_IX }, + [GET_AWAITABLE] = { true, INSTR_FMT_IB }, + [SEND] = { true, INSTR_FMT_IBC }, + [SEND_GEN] = { true, INSTR_FMT_IBC }, + [INSTRUMENTED_YIELD_VALUE] = { true, INSTR_FMT_IX }, + [YIELD_VALUE] = { true, INSTR_FMT_IX }, + [POP_EXCEPT] = { true, INSTR_FMT_IX }, + [RERAISE] = { true, INSTR_FMT_IB }, + [END_ASYNC_FOR] = { true, INSTR_FMT_IX }, + [CLEANUP_THROW] = { true, INSTR_FMT_IX }, + [LOAD_ASSERTION_ERROR] = { true, INSTR_FMT_IX }, + [LOAD_BUILD_CLASS] = { true, INSTR_FMT_IX }, + [STORE_NAME] = { true, INSTR_FMT_IB }, + [DELETE_NAME] = { true, INSTR_FMT_IB }, + [UNPACK_SEQUENCE] = { true, INSTR_FMT_IBC }, + [UNPACK_SEQUENCE_TWO_TUPLE] = { true, INSTR_FMT_IBC }, + [UNPACK_SEQUENCE_TUPLE] = { true, INSTR_FMT_IBC }, + [UNPACK_SEQUENCE_LIST] = { true, INSTR_FMT_IBC }, + [UNPACK_EX] = { true, INSTR_FMT_IB }, + [STORE_ATTR] = { true, INSTR_FMT_IBC000 }, + [DELETE_ATTR] = { true, INSTR_FMT_IB }, + [STORE_GLOBAL] = { true, INSTR_FMT_IB }, + [DELETE_GLOBAL] = { true, INSTR_FMT_IB }, + [LOAD_LOCALS] = { true, INSTR_FMT_IX }, + [LOAD_FROM_DICT_OR_GLOBALS] = { true, INSTR_FMT_IB }, + [LOAD_NAME] = { true, INSTR_FMT_IB }, + [LOAD_GLOBAL] = { true, INSTR_FMT_IBC000 }, + [LOAD_GLOBAL_MODULE] = { true, INSTR_FMT_IBC000 }, + [LOAD_GLOBAL_BUILTIN] = { true, INSTR_FMT_IBC000 }, + [DELETE_FAST] = { true, INSTR_FMT_IB }, + [MAKE_CELL] = { true, INSTR_FMT_IB }, + [DELETE_DEREF] = { true, INSTR_FMT_IB }, + [LOAD_FROM_DICT_OR_DEREF] = { true, INSTR_FMT_IB }, + [LOAD_DEREF] = { true, INSTR_FMT_IB }, + [STORE_DEREF] = { true, INSTR_FMT_IB }, + [COPY_FREE_VARS] = { true, INSTR_FMT_IB }, + [BUILD_STRING] = { true, INSTR_FMT_IB }, + [BUILD_TUPLE] = { true, INSTR_FMT_IB }, + [BUILD_LIST] = { true, INSTR_FMT_IB }, + [LIST_EXTEND] = { true, INSTR_FMT_IB }, + [SET_UPDATE] = { true, INSTR_FMT_IB }, + [BUILD_SET] = { true, INSTR_FMT_IB }, + [BUILD_MAP] = { true, INSTR_FMT_IB }, + [SETUP_ANNOTATIONS] = { true, INSTR_FMT_IX }, + [BUILD_CONST_KEY_MAP] = { true, INSTR_FMT_IB }, + [DICT_UPDATE] = { true, INSTR_FMT_IB }, + [DICT_MERGE] = { true, INSTR_FMT_IB }, + [MAP_ADD] = { true, INSTR_FMT_IB }, + [INSTRUMENTED_LOAD_SUPER_ATTR] = { true, INSTR_FMT_IBC00000000 }, + [LOAD_SUPER_ATTR] = { true, INSTR_FMT_IBC }, + [LOAD_SUPER_ATTR_ATTR] = { true, INSTR_FMT_IBC }, + [LOAD_SUPER_ATTR_METHOD] = { true, INSTR_FMT_IBC }, + [LOAD_ATTR] = { true, INSTR_FMT_IBC00000000 }, + [LOAD_ATTR_INSTANCE_VALUE] = { true, INSTR_FMT_IBC00000000 }, + [LOAD_ATTR_MODULE] = { true, INSTR_FMT_IBC00000000 }, + [LOAD_ATTR_WITH_HINT] = { true, INSTR_FMT_IBC00000000 }, + [LOAD_ATTR_SLOT] = { true, INSTR_FMT_IBC00000000 }, + [LOAD_ATTR_CLASS] = { true, INSTR_FMT_IBC00000000 }, + [LOAD_ATTR_PROPERTY] = { true, INSTR_FMT_IBC00000000 }, + [LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN] = { true, INSTR_FMT_IBC00000000 }, + [STORE_ATTR_INSTANCE_VALUE] = { true, INSTR_FMT_IXC000 }, + [STORE_ATTR_WITH_HINT] = { true, INSTR_FMT_IBC000 }, + [STORE_ATTR_SLOT] = { true, INSTR_FMT_IXC000 }, + [COMPARE_OP] = { true, INSTR_FMT_IBC }, + [COMPARE_OP_FLOAT] = { true, INSTR_FMT_IBC }, + [COMPARE_OP_INT] = { true, INSTR_FMT_IBC }, + [COMPARE_OP_STR] = { true, INSTR_FMT_IBC }, + [IS_OP] = { true, INSTR_FMT_IB }, + [CONTAINS_OP] = { true, INSTR_FMT_IB }, + [CHECK_EG_MATCH] = { true, INSTR_FMT_IX }, + [CHECK_EXC_MATCH] = { true, INSTR_FMT_IX }, + [IMPORT_NAME] = { true, INSTR_FMT_IB }, + [IMPORT_FROM] = { true, INSTR_FMT_IB }, + [JUMP_FORWARD] = { true, INSTR_FMT_IB }, + [JUMP_BACKWARD] = { true, INSTR_FMT_IB }, + [POP_JUMP_IF_FALSE] = { true, INSTR_FMT_IB }, + [POP_JUMP_IF_TRUE] = { true, INSTR_FMT_IB }, + [POP_JUMP_IF_NOT_NONE] = { true, INSTR_FMT_IB }, + [POP_JUMP_IF_NONE] = { true, INSTR_FMT_IB }, + [JUMP_BACKWARD_NO_INTERRUPT] = { true, INSTR_FMT_IB }, + [GET_LEN] = { true, INSTR_FMT_IX }, + [MATCH_CLASS] = { true, INSTR_FMT_IB }, + [MATCH_MAPPING] = { true, INSTR_FMT_IX }, + [MATCH_SEQUENCE] = { true, INSTR_FMT_IX }, + [MATCH_KEYS] = { true, INSTR_FMT_IX }, + [GET_ITER] = { true, INSTR_FMT_IX }, + [GET_YIELD_FROM_ITER] = { true, INSTR_FMT_IX }, + [FOR_ITER] = { true, INSTR_FMT_IBC }, + [INSTRUMENTED_FOR_ITER] = { true, INSTR_FMT_IB }, + [FOR_ITER_LIST] = { true, INSTR_FMT_IBC }, + [FOR_ITER_TUPLE] = { true, INSTR_FMT_IBC }, + [FOR_ITER_RANGE] = { true, INSTR_FMT_IBC }, + [FOR_ITER_GEN] = { true, INSTR_FMT_IBC }, + [BEFORE_ASYNC_WITH] = { true, INSTR_FMT_IX }, + [BEFORE_WITH] = { true, INSTR_FMT_IX }, + [WITH_EXCEPT_START] = { true, INSTR_FMT_IX }, + [PUSH_EXC_INFO] = { true, INSTR_FMT_IX }, + [LOAD_ATTR_METHOD_WITH_VALUES] = { true, INSTR_FMT_IBC00000000 }, + [LOAD_ATTR_METHOD_NO_DICT] = { true, INSTR_FMT_IBC00000000 }, + [LOAD_ATTR_METHOD_LAZY_DICT] = { true, INSTR_FMT_IBC00000000 }, + [KW_NAMES] = { true, INSTR_FMT_IB }, + [INSTRUMENTED_CALL] = { true, INSTR_FMT_IB }, + [CALL] = { true, INSTR_FMT_IBC00 }, + [CALL_BOUND_METHOD_EXACT_ARGS] = { true, INSTR_FMT_IBC00 }, + [CALL_PY_EXACT_ARGS] = { true, INSTR_FMT_IBC00 }, + [CALL_PY_WITH_DEFAULTS] = { true, INSTR_FMT_IBC00 }, + [CALL_NO_KW_TYPE_1] = { true, INSTR_FMT_IBC00 }, + [CALL_NO_KW_STR_1] = { true, INSTR_FMT_IBC00 }, + [CALL_NO_KW_TUPLE_1] = { true, INSTR_FMT_IBC00 }, + [CALL_BUILTIN_CLASS] = { true, INSTR_FMT_IBC00 }, + [CALL_NO_KW_BUILTIN_O] = { true, INSTR_FMT_IBC00 }, + [CALL_NO_KW_BUILTIN_FAST] = { true, INSTR_FMT_IBC00 }, + [CALL_BUILTIN_FAST_WITH_KEYWORDS] = { true, INSTR_FMT_IBC00 }, + [CALL_NO_KW_LEN] = { true, INSTR_FMT_IBC00 }, + [CALL_NO_KW_ISINSTANCE] = { true, INSTR_FMT_IBC00 }, + [CALL_NO_KW_LIST_APPEND] = { true, INSTR_FMT_IBC00 }, + [CALL_NO_KW_METHOD_DESCRIPTOR_O] = { true, INSTR_FMT_IBC00 }, + [CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = { true, INSTR_FMT_IBC00 }, + [CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS] = { true, INSTR_FMT_IBC00 }, + [CALL_NO_KW_METHOD_DESCRIPTOR_FAST] = { true, INSTR_FMT_IBC00 }, + [INSTRUMENTED_CALL_FUNCTION_EX] = { true, INSTR_FMT_IX }, + [CALL_FUNCTION_EX] = { true, INSTR_FMT_IB }, + [MAKE_FUNCTION] = { true, INSTR_FMT_IB }, + [RETURN_GENERATOR] = { true, INSTR_FMT_IX }, + [BUILD_SLICE] = { true, INSTR_FMT_IB }, + [FORMAT_VALUE] = { true, INSTR_FMT_IB }, + [COPY] = { true, INSTR_FMT_IB }, + [BINARY_OP] = { true, INSTR_FMT_IBC }, + [SWAP] = { true, INSTR_FMT_IB }, + [INSTRUMENTED_INSTRUCTION] = { true, INSTR_FMT_IX }, + [INSTRUMENTED_JUMP_FORWARD] = { true, INSTR_FMT_IB }, + [INSTRUMENTED_JUMP_BACKWARD] = { true, INSTR_FMT_IB }, + [INSTRUMENTED_POP_JUMP_IF_TRUE] = { true, INSTR_FMT_IB }, + [INSTRUMENTED_POP_JUMP_IF_FALSE] = { true, INSTR_FMT_IB }, + [INSTRUMENTED_POP_JUMP_IF_NONE] = { true, INSTR_FMT_IB }, + [INSTRUMENTED_POP_JUMP_IF_NOT_NONE] = { true, INSTR_FMT_IB }, + [EXTENDED_ARG] = { true, INSTR_FMT_IB }, + [CACHE] = { true, INSTR_FMT_IX }, + [RESERVED] = { true, INSTR_FMT_IX }, +}; +#endif diff --git a/Python/opcode_targets.h b/Python/opcode_targets.h index d37c1326..3add0636 100644 --- a/Python/opcode_targets.h +++ b/Python/opcode_targets.h @@ -2,92 +2,92 @@ static void *opcode_targets[256] = { &&TARGET_CACHE, &&TARGET_POP_TOP, &&TARGET_PUSH_NULL, - &&TARGET_BINARY_OP_ADAPTIVE, + &&TARGET_INTERPRETER_EXIT, + &&TARGET_END_FOR, + &&TARGET_END_SEND, &&TARGET_BINARY_OP_ADD_FLOAT, &&TARGET_BINARY_OP_ADD_INT, &&TARGET_BINARY_OP_ADD_UNICODE, - &&TARGET_BINARY_OP_INPLACE_ADD_UNICODE, - &&TARGET_BINARY_OP_MULTIPLY_FLOAT, &&TARGET_NOP, - &&TARGET_UNARY_POSITIVE, + &&TARGET_BINARY_OP_INPLACE_ADD_UNICODE, &&TARGET_UNARY_NEGATIVE, &&TARGET_UNARY_NOT, + &&TARGET_BINARY_OP_MULTIPLY_FLOAT, &&TARGET_BINARY_OP_MULTIPLY_INT, - &&TARGET_BINARY_OP_SUBTRACT_FLOAT, &&TARGET_UNARY_INVERT, + &&TARGET_BINARY_OP_SUBTRACT_FLOAT, + &&TARGET_RESERVED, &&TARGET_BINARY_OP_SUBTRACT_INT, - &&TARGET_BINARY_SUBSCR_ADAPTIVE, &&TARGET_BINARY_SUBSCR_DICT, &&TARGET_BINARY_SUBSCR_GETITEM, &&TARGET_BINARY_SUBSCR_LIST_INT, &&TARGET_BINARY_SUBSCR_TUPLE_INT, - &&TARGET_CALL_ADAPTIVE, &&TARGET_CALL_PY_EXACT_ARGS, &&TARGET_CALL_PY_WITH_DEFAULTS, &&TARGET_BINARY_SUBSCR, - &&TARGET_COMPARE_OP_ADAPTIVE, - &&TARGET_COMPARE_OP_FLOAT_JUMP, - &&TARGET_COMPARE_OP_INT_JUMP, - &&TARGET_COMPARE_OP_STR_JUMP, + &&TARGET_BINARY_SLICE, + &&TARGET_STORE_SLICE, + &&TARGET_CALL_BOUND_METHOD_EXACT_ARGS, + &&TARGET_CALL_BUILTIN_CLASS, &&TARGET_GET_LEN, &&TARGET_MATCH_MAPPING, &&TARGET_MATCH_SEQUENCE, &&TARGET_MATCH_KEYS, - &&TARGET_EXTENDED_ARG_QUICK, + &&TARGET_CALL_BUILTIN_FAST_WITH_KEYWORDS, &&TARGET_PUSH_EXC_INFO, &&TARGET_CHECK_EXC_MATCH, &&TARGET_CHECK_EG_MATCH, - &&TARGET_JUMP_BACKWARD_QUICK, - &&TARGET_LOAD_ATTR_ADAPTIVE, - &&TARGET_LOAD_ATTR_INSTANCE_VALUE, - &&TARGET_LOAD_ATTR_MODULE, - &&TARGET_LOAD_ATTR_SLOT, - &&TARGET_LOAD_ATTR_WITH_HINT, - &&TARGET_LOAD_CONST__LOAD_FAST, - &&TARGET_LOAD_FAST__LOAD_CONST, - &&TARGET_LOAD_FAST__LOAD_FAST, - &&TARGET_LOAD_GLOBAL_ADAPTIVE, - &&TARGET_LOAD_GLOBAL_BUILTIN, + &&TARGET_CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS, + &&TARGET_CALL_NO_KW_BUILTIN_FAST, + &&TARGET_CALL_NO_KW_BUILTIN_O, + &&TARGET_CALL_NO_KW_ISINSTANCE, + &&TARGET_CALL_NO_KW_LEN, + &&TARGET_CALL_NO_KW_LIST_APPEND, + &&TARGET_CALL_NO_KW_METHOD_DESCRIPTOR_FAST, + &&TARGET_CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS, + &&TARGET_CALL_NO_KW_METHOD_DESCRIPTOR_O, + &&TARGET_CALL_NO_KW_STR_1, + &&TARGET_CALL_NO_KW_TUPLE_1, &&TARGET_WITH_EXCEPT_START, &&TARGET_GET_AITER, &&TARGET_GET_ANEXT, &&TARGET_BEFORE_ASYNC_WITH, &&TARGET_BEFORE_WITH, &&TARGET_END_ASYNC_FOR, - &&TARGET_LOAD_GLOBAL_MODULE, - &&TARGET_LOAD_METHOD_ADAPTIVE, - &&TARGET_LOAD_METHOD_CLASS, - &&TARGET_LOAD_METHOD_MODULE, - &&TARGET_LOAD_METHOD_NO_DICT, + &&TARGET_CLEANUP_THROW, + &&TARGET_CALL_NO_KW_TYPE_1, + &&TARGET_COMPARE_OP_FLOAT, + &&TARGET_COMPARE_OP_INT, + &&TARGET_COMPARE_OP_STR, &&TARGET_STORE_SUBSCR, &&TARGET_DELETE_SUBSCR, - &&TARGET_LOAD_METHOD_WITH_DICT, - &&TARGET_LOAD_METHOD_WITH_VALUES, - &&TARGET_PRECALL_ADAPTIVE, - &&TARGET_PRECALL_BOUND_METHOD, - &&TARGET_PRECALL_BUILTIN_CLASS, - &&TARGET_PRECALL_BUILTIN_FAST_WITH_KEYWORDS, + &&TARGET_FOR_ITER_LIST, + &&TARGET_FOR_ITER_TUPLE, + &&TARGET_FOR_ITER_RANGE, + &&TARGET_FOR_ITER_GEN, + &&TARGET_LOAD_SUPER_ATTR_ATTR, + &&TARGET_LOAD_SUPER_ATTR_METHOD, &&TARGET_GET_ITER, &&TARGET_GET_YIELD_FROM_ITER, - &&TARGET_PRINT_EXPR, + &&TARGET_LOAD_ATTR_CLASS, &&TARGET_LOAD_BUILD_CLASS, - &&TARGET_PRECALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS, - &&TARGET_PRECALL_NO_KW_BUILTIN_FAST, + &&TARGET_LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN, + &&TARGET_LOAD_ATTR_INSTANCE_VALUE, &&TARGET_LOAD_ASSERTION_ERROR, &&TARGET_RETURN_GENERATOR, - &&TARGET_PRECALL_NO_KW_BUILTIN_O, - &&TARGET_PRECALL_NO_KW_ISINSTANCE, - &&TARGET_PRECALL_NO_KW_LEN, - &&TARGET_PRECALL_NO_KW_LIST_APPEND, - &&TARGET_PRECALL_NO_KW_METHOD_DESCRIPTOR_FAST, - &&TARGET_PRECALL_NO_KW_METHOD_DESCRIPTOR_NOARGS, - &&TARGET_LIST_TO_TUPLE, + &&TARGET_LOAD_ATTR_MODULE, + &&TARGET_LOAD_ATTR_PROPERTY, + &&TARGET_LOAD_ATTR_SLOT, + &&TARGET_LOAD_ATTR_WITH_HINT, + &&TARGET_LOAD_ATTR_METHOD_LAZY_DICT, + &&TARGET_LOAD_ATTR_METHOD_NO_DICT, + &&TARGET_LOAD_ATTR_METHOD_WITH_VALUES, &&TARGET_RETURN_VALUE, - &&TARGET_IMPORT_STAR, + &&TARGET_LOAD_CONST__LOAD_FAST, &&TARGET_SETUP_ANNOTATIONS, - &&TARGET_YIELD_VALUE, - &&TARGET_ASYNC_GEN_WRAP, - &&TARGET_PREP_RERAISE_STAR, + &&TARGET_LOAD_FAST__LOAD_CONST, + &&TARGET_LOAD_LOCALS, + &&TARGET_LOAD_FAST__LOAD_FAST, &&TARGET_POP_EXCEPT, &&TARGET_STORE_NAME, &&TARGET_DELETE_NAME, @@ -110,25 +110,25 @@ static void *opcode_targets[256] = { &&TARGET_IMPORT_NAME, &&TARGET_IMPORT_FROM, &&TARGET_JUMP_FORWARD, - &&TARGET_JUMP_IF_FALSE_OR_POP, - &&TARGET_JUMP_IF_TRUE_OR_POP, - &&TARGET_PRECALL_NO_KW_METHOD_DESCRIPTOR_O, - &&TARGET_POP_JUMP_FORWARD_IF_FALSE, - &&TARGET_POP_JUMP_FORWARD_IF_TRUE, + &&TARGET_LOAD_GLOBAL_BUILTIN, + &&TARGET_LOAD_GLOBAL_MODULE, + &&TARGET_STORE_ATTR_INSTANCE_VALUE, + &&TARGET_POP_JUMP_IF_FALSE, + &&TARGET_POP_JUMP_IF_TRUE, &&TARGET_LOAD_GLOBAL, &&TARGET_IS_OP, &&TARGET_CONTAINS_OP, &&TARGET_RERAISE, &&TARGET_COPY, - &&TARGET_PRECALL_NO_KW_STR_1, + &&TARGET_RETURN_CONST, &&TARGET_BINARY_OP, &&TARGET_SEND, &&TARGET_LOAD_FAST, &&TARGET_STORE_FAST, &&TARGET_DELETE_FAST, - &&TARGET_PRECALL_NO_KW_TUPLE_1, - &&TARGET_POP_JUMP_FORWARD_IF_NOT_NONE, - &&TARGET_POP_JUMP_FORWARD_IF_NONE, + &&TARGET_LOAD_FAST_CHECK, + &&TARGET_POP_JUMP_IF_NOT_NONE, + &&TARGET_POP_JUMP_IF_NONE, &&TARGET_RAISE_VARARGS, &&TARGET_GET_AWAITABLE, &&TARGET_MAKE_FUNCTION, @@ -140,48 +140,42 @@ static void *opcode_targets[256] = { &&TARGET_STORE_DEREF, &&TARGET_DELETE_DEREF, &&TARGET_JUMP_BACKWARD, - &&TARGET_PRECALL_NO_KW_TYPE_1, + &&TARGET_LOAD_SUPER_ATTR, &&TARGET_CALL_FUNCTION_EX, - &&TARGET_PRECALL_PYFUNC, + &&TARGET_LOAD_FAST_AND_CLEAR, &&TARGET_EXTENDED_ARG, &&TARGET_LIST_APPEND, &&TARGET_SET_ADD, &&TARGET_MAP_ADD, - &&TARGET_LOAD_CLASSDEREF, + &&TARGET_STORE_ATTR_SLOT, &&TARGET_COPY_FREE_VARS, - &&TARGET_RESUME_QUICK, + &&TARGET_YIELD_VALUE, &&TARGET_RESUME, &&TARGET_MATCH_CLASS, - &&TARGET_STORE_ATTR_ADAPTIVE, - &&TARGET_STORE_ATTR_INSTANCE_VALUE, + &&TARGET_STORE_ATTR_WITH_HINT, + &&TARGET_STORE_FAST__LOAD_FAST, &&TARGET_FORMAT_VALUE, &&TARGET_BUILD_CONST_KEY_MAP, &&TARGET_BUILD_STRING, - &&TARGET_STORE_ATTR_SLOT, - &&TARGET_STORE_ATTR_WITH_HINT, - &&TARGET_LOAD_METHOD, - &&TARGET_STORE_FAST__LOAD_FAST, - &&TARGET_LIST_EXTEND, - &&TARGET_SET_UPDATE, - &&TARGET_DICT_MERGE, - &&TARGET_DICT_UPDATE, - &&TARGET_PRECALL, &&TARGET_STORE_FAST__STORE_FAST, - &&TARGET_STORE_SUBSCR_ADAPTIVE, &&TARGET_STORE_SUBSCR_DICT, &&TARGET_STORE_SUBSCR_LIST_INT, - &&TARGET_CALL, - &&TARGET_KW_NAMES, - &&TARGET_POP_JUMP_BACKWARD_IF_NOT_NONE, - &&TARGET_POP_JUMP_BACKWARD_IF_NONE, - &&TARGET_POP_JUMP_BACKWARD_IF_FALSE, - &&TARGET_POP_JUMP_BACKWARD_IF_TRUE, - &&TARGET_UNPACK_SEQUENCE_ADAPTIVE, &&TARGET_UNPACK_SEQUENCE_LIST, + &&TARGET_LIST_EXTEND, + &&TARGET_SET_UPDATE, + &&TARGET_DICT_MERGE, + &&TARGET_DICT_UPDATE, &&TARGET_UNPACK_SEQUENCE_TUPLE, &&TARGET_UNPACK_SEQUENCE_TWO_TUPLE, + &&TARGET_SEND_GEN, &&_unknown_opcode, &&_unknown_opcode, + &&TARGET_CALL, + &&TARGET_KW_NAMES, + &&TARGET_CALL_INTRINSIC_1, + &&TARGET_CALL_INTRINSIC_2, + &&TARGET_LOAD_FROM_DICT_OR_GLOBALS, + &&TARGET_LOAD_FROM_DICT_OR_DEREF, &&_unknown_opcode, &&_unknown_opcode, &&_unknown_opcode, @@ -242,17 +236,23 @@ static void *opcode_targets[256] = { &&_unknown_opcode, &&_unknown_opcode, &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&_unknown_opcode, - &&TARGET_DO_TRACING + &&TARGET_INSTRUMENTED_LOAD_SUPER_ATTR, + &&TARGET_INSTRUMENTED_POP_JUMP_IF_NONE, + &&TARGET_INSTRUMENTED_POP_JUMP_IF_NOT_NONE, + &&TARGET_INSTRUMENTED_RESUME, + &&TARGET_INSTRUMENTED_CALL, + &&TARGET_INSTRUMENTED_RETURN_VALUE, + &&TARGET_INSTRUMENTED_YIELD_VALUE, + &&TARGET_INSTRUMENTED_CALL_FUNCTION_EX, + &&TARGET_INSTRUMENTED_JUMP_FORWARD, + &&TARGET_INSTRUMENTED_JUMP_BACKWARD, + &&TARGET_INSTRUMENTED_RETURN_CONST, + &&TARGET_INSTRUMENTED_FOR_ITER, + &&TARGET_INSTRUMENTED_POP_JUMP_IF_FALSE, + &&TARGET_INSTRUMENTED_POP_JUMP_IF_TRUE, + &&TARGET_INSTRUMENTED_END_FOR, + &&TARGET_INSTRUMENTED_END_SEND, + &&TARGET_INSTRUMENTED_INSTRUCTION, + &&TARGET_INSTRUMENTED_LINE, + &&_unknown_opcode }; diff --git a/Python/perf_trampoline.c b/Python/perf_trampoline.c new file mode 100644 index 00000000..6a6f223d --- /dev/null +++ b/Python/perf_trampoline.c @@ -0,0 +1,463 @@ +/* + +Perf trampoline instrumentation +=============================== + +This file contains instrumentation to allow to associate +calls to the CPython eval loop back to the names of the Python +functions and filename being executed. + +Many native performance profilers like the Linux perf tools are +only available to 'see' the C stack when sampling from the profiled +process. This means that if we have the following python code: + + import time + def foo(n): + # Some CPU intensive code + + def bar(n): + foo(n) + + def baz(n): + bar(n) + + baz(10000000) + +A performance profiler that is only able to see native frames will +produce the following backtrace when sampling from foo(): + + _PyEval_EvalFrameDefault -----> Evaluation frame of foo() + _PyEval_Vector + _PyFunction_Vectorcall + PyObject_Vectorcall + call_function + + _PyEval_EvalFrameDefault ------> Evaluation frame of bar() + _PyEval_EvalFrame + _PyEval_Vector + _PyFunction_Vectorcall + PyObject_Vectorcall + call_function + + _PyEval_EvalFrameDefault -------> Evaluation frame of baz() + _PyEval_EvalFrame + _PyEval_Vector + _PyFunction_Vectorcall + PyObject_Vectorcall + call_function + + ... + + Py_RunMain + +Because the profiler is only able to see the native frames and the native +function that runs the evaluation loop is the same (_PyEval_EvalFrameDefault) +then the profiler and any reporter generated by it will not be able to +associate the names of the Python functions and the filenames associated with +those calls, rendering the results useless in the Python world. + +To fix this problem, we introduce the concept of a trampoline frame. A +trampoline frame is a piece of code that is unique per Python code object that +is executed before entering the CPython eval loop. This piece of code just +calls the original Python evaluation function (_PyEval_EvalFrameDefault) and +forwards all the arguments received. In this way, when a profiler samples +frames from the previous example it will see; + + _PyEval_EvalFrameDefault -----> Evaluation frame of foo() + [Jit compiled code 3] + _PyEval_Vector + _PyFunction_Vectorcall + PyObject_Vectorcall + call_function + + _PyEval_EvalFrameDefault ------> Evaluation frame of bar() + [Jit compiled code 2] + _PyEval_EvalFrame + _PyEval_Vector + _PyFunction_Vectorcall + PyObject_Vectorcall + call_function + + _PyEval_EvalFrameDefault -------> Evaluation frame of baz() + [Jit compiled code 1] + _PyEval_EvalFrame + _PyEval_Vector + _PyFunction_Vectorcall + PyObject_Vectorcall + call_function + + ... + + Py_RunMain + +When we generate every unique copy of the trampoline (what here we called "[Jit +compiled code N]") we write the relationship between the compiled code and the +Python function that is associated with it. Every profiler requires this +information in a different format. For example, the Linux "perf" profiler +requires a file in "/tmp/perf-PID.map" (name and location not configurable) +with the following format: + + <compiled code address> <compiled code size> <name of the compiled code> + +If this file is available when "perf" generates reports, it will automatically +associate every trampoline with the Python function that it is associated with +allowing it to generate reports that include Python information. These reports +then can also be filtered in a way that *only* Python information appears. + +Notice that for this to work, there must be a unique copied of the trampoline +per Python code object even if the code in the trampoline is the same. To +achieve this we have a assembly template in Objects/asm_trampiline.S that is +compiled into the Python executable/shared library. This template generates a +symbol that maps the start of the assembly code and another that marks the end +of the assembly code for the trampoline. Then, every time we need a unique +trampoline for a Python code object, we copy the assembly code into a mmaped +area that has executable permissions and we return the start of that area as +our trampoline function. + +Asking for a mmap-ed memory area for trampoline is very wasteful so we +allocate big arenas of memory in a single mmap call, we populate the entire +arena with copies of the trampoline (this allows us to now have to invalidate +the icache for the instructions in the page) and then we return the next +available chunk every time someone asks for a new trampoline. We keep a linked +list of arenas in case the current memory arena is exhausted and another one is +needed. + +For the best results, Python should be compiled with +CFLAGS="-fno-omit-frame-pointer -mno-omit-leaf-frame-pointer" as this allows +profilers to unwind using only the frame pointer and not on DWARF debug +information (note that as trampilines are dynamically generated there won't be +any DWARF information available for them). +*/ + +#include "Python.h" +#include "pycore_ceval.h" +#include "pycore_frame.h" +#include "pycore_interp.h" + + +#ifdef PY_HAVE_PERF_TRAMPOLINE + +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <sys/mman.h> +#include <sys/types.h> +#include <unistd.h> + +#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__) +#define PY_HAVE_INVALIDATE_ICACHE + +#if defined(__clang__) || defined(__GNUC__) +extern void __clear_cache(void *, void*); +#endif + +static void invalidate_icache(char* begin, char*end) { +#if defined(__clang__) || defined(__GNUC__) + return __clear_cache(begin, end); +#else + return; +#endif +} +#endif + +/* The function pointer is passed as last argument. The other three arguments + * are passed in the same order as the function requires. This results in + * shorter, more efficient ASM code for trampoline. + */ +typedef PyObject *(*py_evaluator)(PyThreadState *, _PyInterpreterFrame *, + int throwflag); +typedef PyObject *(*py_trampoline)(PyThreadState *, _PyInterpreterFrame *, int, + py_evaluator); + +extern void *_Py_trampoline_func_start; // Start of the template of the + // assembly trampoline +extern void * + _Py_trampoline_func_end; // End of the template of the assembly trampoline + +struct code_arena_st { + char *start_addr; // Start of the memory arena + char *current_addr; // Address of the current trampoline within the arena + size_t size; // Size of the memory arena + size_t size_left; // Remaining size of the memory arena + size_t code_size; // Size of the code of every trampoline in the arena + struct code_arena_st + *prev; // Pointer to the arena or NULL if this is the first arena. +}; + +typedef struct code_arena_st code_arena_t; +typedef struct trampoline_api_st trampoline_api_t; + +#define perf_status _PyRuntime.ceval.perf.status +#define extra_code_index _PyRuntime.ceval.perf.extra_code_index +#define perf_code_arena _PyRuntime.ceval.perf.code_arena +#define trampoline_api _PyRuntime.ceval.perf.trampoline_api +#define perf_map_file _PyRuntime.ceval.perf.map_file + + +static void +perf_map_write_entry(void *state, const void *code_addr, + unsigned int code_size, PyCodeObject *co) +{ + const char *entry = ""; + if (co->co_qualname != NULL) { + entry = PyUnicode_AsUTF8(co->co_qualname); + } + const char *filename = ""; + if (co->co_filename != NULL) { + filename = PyUnicode_AsUTF8(co->co_filename); + } + size_t perf_map_entry_size = snprintf(NULL, 0, "py::%s:%s", entry, filename) + 1; + char* perf_map_entry = (char*) PyMem_RawMalloc(perf_map_entry_size); + if (perf_map_entry == NULL) { + return; + } + snprintf(perf_map_entry, perf_map_entry_size, "py::%s:%s", entry, filename); + PyUnstable_WritePerfMapEntry(code_addr, code_size, perf_map_entry); + PyMem_RawFree(perf_map_entry); +} + +_PyPerf_Callbacks _Py_perfmap_callbacks = { + NULL, + &perf_map_write_entry, + NULL, +}; + +static int +new_code_arena(void) +{ + // non-trivial programs typically need 64 to 256 kiB. + size_t mem_size = 4096 * 16; + assert(mem_size % sysconf(_SC_PAGESIZE) == 0); + char *memory = + mmap(NULL, // address + mem_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, + -1, // fd (not used here) + 0); // offset (not used here) + if (!memory) { + PyErr_SetFromErrno(PyExc_OSError); + _PyErr_WriteUnraisableMsg( + "Failed to create new mmap for perf trampoline", NULL); + perf_status = PERF_STATUS_FAILED; + return -1; + } + void *start = &_Py_trampoline_func_start; + void *end = &_Py_trampoline_func_end; + size_t code_size = end - start; + // TODO: Check the effect of alignment of the code chunks. Initial investigation + // showed that this has no effect on performance in x86-64 or aarch64 and the current + // version has the advantage that the unwinder in GDB can unwind across JIT-ed code. + // + // We should check the values in the future and see if there is a + // measurable performance improvement by rounding trampolines up to 32-bit + // or 64-bit alignment. + + size_t n_copies = mem_size / code_size; + for (size_t i = 0; i < n_copies; i++) { + memcpy(memory + i * code_size, start, code_size * sizeof(char)); + } + // Some systems may prevent us from creating executable code on the fly. + int res = mprotect(memory, mem_size, PROT_READ | PROT_EXEC); + if (res == -1) { + PyErr_SetFromErrno(PyExc_OSError); + munmap(memory, mem_size); + _PyErr_WriteUnraisableMsg( + "Failed to set mmap for perf trampoline to PROT_READ | PROT_EXEC", + NULL); + return -1; + } + +#ifdef PY_HAVE_INVALIDATE_ICACHE + // Before the JIT can run a block of code that has been emitted it must invalidate + // the instruction cache on some platforms like arm and aarch64. + invalidate_icache(memory, memory + mem_size); +#endif + + code_arena_t *new_arena = PyMem_RawCalloc(1, sizeof(code_arena_t)); + if (new_arena == NULL) { + PyErr_NoMemory(); + munmap(memory, mem_size); + _PyErr_WriteUnraisableMsg("Failed to allocate new code arena struct", + NULL); + return -1; + } + + new_arena->start_addr = memory; + new_arena->current_addr = memory; + new_arena->size = mem_size; + new_arena->size_left = mem_size; + new_arena->code_size = code_size; + new_arena->prev = perf_code_arena; + perf_code_arena = new_arena; + return 0; +} + +static void +free_code_arenas(void) +{ + code_arena_t *cur = perf_code_arena; + code_arena_t *prev; + perf_code_arena = NULL; // invalid static pointer + while (cur) { + munmap(cur->start_addr, cur->size); + prev = cur->prev; + PyMem_RawFree(cur); + cur = prev; + } +} + +static inline py_trampoline +code_arena_new_code(code_arena_t *code_arena) +{ + py_trampoline trampoline = (py_trampoline)code_arena->current_addr; + code_arena->size_left -= code_arena->code_size; + code_arena->current_addr += code_arena->code_size; + return trampoline; +} + +static inline py_trampoline +compile_trampoline(void) +{ + if ((perf_code_arena == NULL) || + (perf_code_arena->size_left <= perf_code_arena->code_size)) { + if (new_code_arena() < 0) { + return NULL; + } + } + assert(perf_code_arena->size_left <= perf_code_arena->size); + return code_arena_new_code(perf_code_arena); +} + +static PyObject * +py_trampoline_evaluator(PyThreadState *ts, _PyInterpreterFrame *frame, + int throw) +{ + if (perf_status == PERF_STATUS_FAILED || + perf_status == PERF_STATUS_NO_INIT) { + goto default_eval; + } + PyCodeObject *co = frame->f_code; + py_trampoline f = NULL; + assert(extra_code_index != -1); + int ret = _PyCode_GetExtra((PyObject *)co, extra_code_index, (void **)&f); + if (ret != 0 || f == NULL) { + // This is the first time we see this code object so we need + // to compile a trampoline for it. + py_trampoline new_trampoline = compile_trampoline(); + if (new_trampoline == NULL) { + goto default_eval; + } + trampoline_api.write_state(trampoline_api.state, new_trampoline, + perf_code_arena->code_size, co); + _PyCode_SetExtra((PyObject *)co, extra_code_index, + (void *)new_trampoline); + f = new_trampoline; + } + assert(f != NULL); + return f(ts, frame, throw, _PyEval_EvalFrameDefault); +default_eval: + // Something failed, fall back to the default evaluator. + return _PyEval_EvalFrameDefault(ts, frame, throw); +} +#endif // PY_HAVE_PERF_TRAMPOLINE + +int +_PyIsPerfTrampolineActive(void) +{ +#ifdef PY_HAVE_PERF_TRAMPOLINE + PyThreadState *tstate = _PyThreadState_GET(); + return tstate->interp->eval_frame == py_trampoline_evaluator; +#endif + return 0; +} + +void +_PyPerfTrampoline_GetCallbacks(_PyPerf_Callbacks *callbacks) +{ + if (callbacks == NULL) { + return; + } +#ifdef PY_HAVE_PERF_TRAMPOLINE + callbacks->init_state = trampoline_api.init_state; + callbacks->write_state = trampoline_api.write_state; + callbacks->free_state = trampoline_api.free_state; +#endif + return; +} + +int +_PyPerfTrampoline_SetCallbacks(_PyPerf_Callbacks *callbacks) +{ + if (callbacks == NULL) { + return -1; + } +#ifdef PY_HAVE_PERF_TRAMPOLINE + if (trampoline_api.state) { + _PyPerfTrampoline_Fini(); + } + trampoline_api.init_state = callbacks->init_state; + trampoline_api.write_state = callbacks->write_state; + trampoline_api.free_state = callbacks->free_state; + trampoline_api.state = NULL; + perf_status = PERF_STATUS_OK; +#endif + return 0; +} + +int +_PyPerfTrampoline_Init(int activate) +{ +#ifdef PY_HAVE_PERF_TRAMPOLINE + PyThreadState *tstate = _PyThreadState_GET(); + if (tstate->interp->eval_frame && + tstate->interp->eval_frame != py_trampoline_evaluator) { + PyErr_SetString(PyExc_RuntimeError, + "Trampoline cannot be initialized as a custom eval " + "frame is already present"); + return -1; + } + if (!activate) { + tstate->interp->eval_frame = NULL; + } + else { + tstate->interp->eval_frame = py_trampoline_evaluator; + if (new_code_arena() < 0) { + return -1; + } + extra_code_index = _PyEval_RequestCodeExtraIndex(NULL); + if (extra_code_index == -1) { + return -1; + } + perf_status = PERF_STATUS_OK; + } +#endif + return 0; +} + +int +_PyPerfTrampoline_Fini(void) +{ +#ifdef PY_HAVE_PERF_TRAMPOLINE + PyThreadState *tstate = _PyThreadState_GET(); + if (tstate->interp->eval_frame == py_trampoline_evaluator) { + tstate->interp->eval_frame = NULL; + } + free_code_arenas(); + extra_code_index = -1; +#endif + return 0; +} + +PyStatus +_PyPerfTrampoline_AfterFork_Child(void) +{ +#ifdef PY_HAVE_PERF_TRAMPOLINE + // Restart trampoline in file in child. + int was_active = _PyIsPerfTrampolineActive(); + _PyPerfTrampoline_Fini(); + PyUnstable_PerfMapState_Fini(); + if (was_active) { + _PyPerfTrampoline_Init(1); + } +#endif + return PyStatus_Ok(); +} diff --git a/Python/preconfig.c b/Python/preconfig.c index 0deb07a8..77a86d65 100644 --- a/Python/preconfig.c +++ b/Python/preconfig.c @@ -24,6 +24,8 @@ int _Py_HasFileSystemDefaultEncodeErrors = 0; void _Py_ClearFileSystemEncoding(void) { +_Py_COMP_DIAG_PUSH +_Py_COMP_DIAG_IGNORE_DEPR_DECLS if (!Py_HasFileSystemDefaultEncoding && Py_FileSystemDefaultEncoding) { PyMem_RawFree((char*)Py_FileSystemDefaultEncoding); Py_FileSystemDefaultEncoding = NULL; @@ -32,6 +34,7 @@ _Py_ClearFileSystemEncoding(void) PyMem_RawFree((char*)Py_FileSystemDefaultEncodeErrors); Py_FileSystemDefaultEncodeErrors = NULL; } +_Py_COMP_DIAG_POP } @@ -56,11 +59,14 @@ _Py_SetFileSystemEncoding(const char *encoding, const char *errors) _Py_ClearFileSystemEncoding(); +_Py_COMP_DIAG_PUSH +_Py_COMP_DIAG_IGNORE_DEPR_DECLS Py_FileSystemDefaultEncoding = encoding2; Py_HasFileSystemDefaultEncoding = 0; Py_FileSystemDefaultEncodeErrors = errors2; _Py_HasFileSystemDefaultEncodeErrors = 0; +_Py_COMP_DIAG_POP return 0; } @@ -472,6 +478,8 @@ preconfig_get_global_vars(PyPreConfig *config) config->ATTR = !(VALUE); \ } +_Py_COMP_DIAG_PUSH +_Py_COMP_DIAG_IGNORE_DEPR_DECLS COPY_FLAG(isolated, Py_IsolatedFlag); COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag); if (Py_UTF8Mode > 0) { @@ -480,6 +488,7 @@ preconfig_get_global_vars(PyPreConfig *config) #ifdef MS_WINDOWS COPY_FLAG(legacy_windows_fs_encoding, Py_LegacyWindowsFSEncodingFlag); #endif +_Py_COMP_DIAG_POP #undef COPY_FLAG #undef COPY_NOT_FLAG @@ -498,12 +507,15 @@ preconfig_set_global_vars(const PyPreConfig *config) VAR = !config->ATTR; \ } +_Py_COMP_DIAG_PUSH +_Py_COMP_DIAG_IGNORE_DEPR_DECLS COPY_FLAG(isolated, Py_IsolatedFlag); COPY_NOT_FLAG(use_environment, Py_IgnoreEnvironmentFlag); #ifdef MS_WINDOWS COPY_FLAG(legacy_windows_fs_encoding, Py_LegacyWindowsFSEncodingFlag); #endif COPY_FLAG(utf8_mode, Py_UTF8Mode); +_Py_COMP_DIAG_POP #undef COPY_FLAG #undef COPY_NOT_FLAG @@ -816,12 +828,10 @@ _PyPreConfig_Read(PyPreConfig *config, const _PyArgv *args) _Py_SetLocaleFromEnv(LC_CTYPE); } - _PyPreCmdline cmdline = _PyPreCmdline_INIT; - int init_utf8_mode = Py_UTF8Mode; -#ifdef MS_WINDOWS - int init_legacy_encoding = Py_LegacyWindowsFSEncodingFlag; -#endif + PyPreConfig save_runtime_config; + preconfig_copy(&save_runtime_config, &_PyRuntime.preconfig); + _PyPreCmdline cmdline = _PyPreCmdline_INIT; int locale_coerced = 0; int loops = 0; @@ -837,11 +847,9 @@ _PyPreConfig_Read(PyPreConfig *config, const _PyArgv *args) } /* bpo-34207: Py_DecodeLocale() and Py_EncodeLocale() depend - on Py_UTF8Mode and Py_LegacyWindowsFSEncodingFlag. */ - Py_UTF8Mode = config->utf8_mode; -#ifdef MS_WINDOWS - Py_LegacyWindowsFSEncodingFlag = config->legacy_windows_fs_encoding; -#endif + on the utf8_mode and legacy_windows_fs_encoding members + of _PyRuntime.preconfig. */ + preconfig_copy(&_PyRuntime.preconfig, config); if (args) { // Set command line arguments at each iteration. If they are bytes @@ -904,14 +912,10 @@ _PyPreConfig_Read(PyPreConfig *config, const _PyArgv *args) status = _PyStatus_OK(); done: - if (init_ctype_locale != NULL) { - setlocale(LC_CTYPE, init_ctype_locale); - PyMem_RawFree(init_ctype_locale); - } - Py_UTF8Mode = init_utf8_mode ; -#ifdef MS_WINDOWS - Py_LegacyWindowsFSEncodingFlag = init_legacy_encoding; -#endif + // Revert side effects + setlocale(LC_CTYPE, init_ctype_locale); + PyMem_RawFree(init_ctype_locale); + preconfig_copy(&_PyRuntime.preconfig, &save_runtime_config); _PyPreCmdline_Clear(&cmdline); return status; } diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 4060c23a..29771e07 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -2,7 +2,6 @@ #include "Python.h" -#include "pycore_bytesobject.h" // _PyBytes_InitTypes() #include "pycore_ceval.h" // _PyEval_FiniGIL() #include "pycore_context.h" // _PyContext_Init() #include "pycore_exceptions.h" // _PyExc_InitTypes() @@ -10,6 +9,7 @@ #include "pycore_fileutils.h" // _Py_ResetForceASCII() #include "pycore_floatobject.h" // _PyFloat_InitTypes() #include "pycore_genobject.h" // _PyAsyncGen_Fini() +#include "pycore_global_objects_fini_generated.h" // "_PyStaticObjects_CheckRefcnt() #include "pycore_import.h" // _PyImport_BootstrapImp() #include "pycore_initconfig.h" // _PyStatus_OK() #include "pycore_list.h" // _PyList_Fini() @@ -25,11 +25,10 @@ #include "pycore_sliceobject.h" // _PySlice_Fini() #include "pycore_sysmodule.h" // _PySys_ClearAuditHooks() #include "pycore_traceback.h" // _Py_DumpTracebackThreads() -#include "pycore_tuple.h" // _PyTuple_InitTypes() #include "pycore_typeobject.h" // _PyTypes_InitTypes() +#include "pycore_typevarobject.h" // _Py_clear_generic_types() #include "pycore_unicodeobject.h" // _PyUnicode_InitTypes() - -extern void _PyIO_Fini(void); +#include "opcode.h" #include <locale.h> // setlocale() #include <stdlib.h> // getenv() @@ -52,11 +51,6 @@ extern void _PyIO_Fini(void); #ifdef MS_WINDOWS # undef BYTE -# include "windows.h" - - extern PyTypeObject PyWindowsConsoleIO_Type; -# define PyWindowsConsoleIO_Check(op) \ - (PyObject_TypeCheck((op), &PyWindowsConsoleIO_Type)) #endif #define PUTS(fd, str) _Py_write_noraise(fd, str, (int)strlen(str)) @@ -75,8 +69,6 @@ static PyStatus init_sys_streams(PyThreadState *tstate); static void wait_for_thread_shutdown(PyThreadState *tstate); static void call_ll_exitfuncs(_PyRuntimeState *runtime); -int _Py_UnhandledKeyboardInterrupt = 0; - /* The following places the `_PyRuntime` structure in a location that can be * found without any external information. This is meant to ease access to the * interpreter state for various runtime debugging tools, but is *not* an @@ -103,7 +95,7 @@ _PyRuntimeState _PyRuntime #if defined(__linux__) && (defined(__GNUC__) || defined(__clang__)) __attribute__ ((section (".PyRuntime"))) #endif -= _PyRuntimeState_INIT; += _PyRuntimeState_INIT(_PyRuntime); _Py_COMP_DIAG_POP static int runtime_initialized = 0; @@ -161,79 +153,6 @@ Py_IsInitialized(void) } -/* Global initializations. Can be undone by Py_FinalizeEx(). Don't - call this twice without an intervening Py_FinalizeEx() call. When - initializations fail, a fatal error is issued and the function does - not return. On return, the first thread and interpreter state have - been created. - - Locking: you must hold the interpreter lock while calling this. - (If the lock has not yet been initialized, that's equivalent to - having the lock, but you cannot use multiple threads.) - -*/ -static int -init_importlib(PyThreadState *tstate, PyObject *sysmod) -{ - assert(!_PyErr_Occurred(tstate)); - - PyInterpreterState *interp = tstate->interp; - int verbose = _PyInterpreterState_GetConfig(interp)->verbose; - - // Import _importlib through its frozen version, _frozen_importlib. - if (verbose) { - PySys_FormatStderr("import _frozen_importlib # frozen\n"); - } - if (PyImport_ImportFrozenModule("_frozen_importlib") <= 0) { - return -1; - } - PyObject *importlib = PyImport_AddModule("_frozen_importlib"); // borrowed - if (importlib == NULL) { - return -1; - } - interp->importlib = Py_NewRef(importlib); - - // Import the _imp module - if (verbose) { - PySys_FormatStderr("import _imp # builtin\n"); - } - PyObject *imp_mod = _PyImport_BootstrapImp(tstate); - if (imp_mod == NULL) { - return -1; - } - if (_PyImport_SetModuleString("_imp", imp_mod) < 0) { - Py_DECREF(imp_mod); - return -1; - } - - // Install importlib as the implementation of import - PyObject *value = PyObject_CallMethod(importlib, "_install", - "OO", sysmod, imp_mod); - Py_DECREF(imp_mod); - if (value == NULL) { - return -1; - } - Py_DECREF(value); - - assert(!_PyErr_Occurred(tstate)); - return 0; -} - - -static PyStatus -init_importlib_external(PyThreadState *tstate) -{ - PyObject *value; - value = PyObject_CallMethod(tstate->interp->importlib, - "_install_external_importers", ""); - if (value == NULL) { - _PyErr_Print(tstate); - return _PyStatus_ERR("external importer setup failed"); - } - Py_DECREF(value); - return _PyImportZip_Init(tstate); -} - /* Helper functions to better handle the legacy C locale * * The legacy C locale assumes ASCII as the default text encoding, which @@ -481,6 +400,8 @@ interpreter_update_config(PyThreadState *tstate, int only_update_path_config) } } + tstate->interp->long_state.max_str_digits = config->int_max_str_digits; + // Update the sys module for the new configuration if (_PySys_UpdateConfig(tstate) < 0) { return -1; @@ -597,11 +518,23 @@ pycore_init_runtime(_PyRuntimeState *runtime, */ _PyRuntimeState_SetFinalizing(runtime, NULL); + _Py_InitVersion(); + status = _Py_HashRandomization_Init(config); if (_PyStatus_EXCEPTION(status)) { return status; } + status = _PyTime_Init(); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + status = _PyImport_Init(); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + status = _PyInterpreterState_Enable(runtime); if (_PyStatus_EXCEPTION(status)) { return status; @@ -611,12 +544,54 @@ pycore_init_runtime(_PyRuntimeState *runtime, static PyStatus -init_interp_create_gil(PyThreadState *tstate) +init_interp_settings(PyInterpreterState *interp, + const PyInterpreterConfig *config) +{ + assert(interp->feature_flags == 0); + + if (config->use_main_obmalloc) { + interp->feature_flags |= Py_RTFLAGS_USE_MAIN_OBMALLOC; + } + else if (!config->check_multi_interp_extensions) { + /* The reason: PyModuleDef.m_base.m_copy leaks objects between + interpreters. */ + return _PyStatus_ERR("per-interpreter obmalloc does not support " + "single-phase init extension modules"); + } + + if (config->allow_fork) { + interp->feature_flags |= Py_RTFLAGS_FORK; + } + if (config->allow_exec) { + interp->feature_flags |= Py_RTFLAGS_EXEC; + } + // Note that fork+exec is always allowed. + + if (config->allow_threads) { + interp->feature_flags |= Py_RTFLAGS_THREADS; + } + if (config->allow_daemon_threads) { + interp->feature_flags |= Py_RTFLAGS_DAEMON_THREADS; + } + + if (config->check_multi_interp_extensions) { + interp->feature_flags |= Py_RTFLAGS_MULTI_INTERP_EXTENSIONS; + } + + /* We check "gil" in init_interp_create_gil(). */ + + return _PyStatus_OK(); +} + + +static PyStatus +init_interp_create_gil(PyThreadState *tstate, int gil) { PyStatus status; /* finalize_interp_delete() comment explains why _PyEval_FiniGIL() is only called here. */ + // XXX This is broken with a per-interpreter GIL. _PyEval_FiniGIL(tstate->interp); /* Auto-thread-state API */ @@ -625,8 +600,17 @@ init_interp_create_gil(PyThreadState *tstate) return status; } + int own_gil; + switch (gil) { + case PyInterpreterConfig_DEFAULT_GIL: own_gil = 0; break; + case PyInterpreterConfig_SHARED_GIL: own_gil = 0; break; + case PyInterpreterConfig_OWN_GIL: own_gil = 1; break; + default: + return _PyStatus_ERR("invalid interpreter config 'gil' value"); + } + /* Create the GIL and take it */ - status = _PyEval_InitGIL(tstate); + status = _PyEval_InitGIL(tstate, own_gil); if (_PyStatus_EXCEPTION(status)) { return status; } @@ -637,33 +621,44 @@ init_interp_create_gil(PyThreadState *tstate) static PyStatus pycore_create_interpreter(_PyRuntimeState *runtime, - const PyConfig *config, + const PyConfig *src_config, PyThreadState **tstate_p) { - /* Auto-thread-state API */ - PyStatus status = _PyGILState_Init(runtime); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - + PyStatus status; PyInterpreterState *interp = PyInterpreterState_New(); if (interp == NULL) { return _PyStatus_ERR("can't make main interpreter"); } assert(_Py_IsMainInterpreter(interp)); - status = _PyConfig_Copy(&interp->config, config); + status = _PyConfig_Copy(&interp->config, src_config); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + /* Auto-thread-state API */ + status = _PyGILState_Init(interp); + if (_PyStatus_EXCEPTION(status)) { + return status; + } + + PyInterpreterConfig config = _PyInterpreterConfig_LEGACY_INIT; + // The main interpreter always has its own GIL. + config.gil = PyInterpreterConfig_OWN_GIL; + status = init_interp_settings(interp, &config); if (_PyStatus_EXCEPTION(status)) { return status; } - PyThreadState *tstate = PyThreadState_New(interp); + PyThreadState *tstate = _PyThreadState_New(interp); if (tstate == NULL) { return _PyStatus_ERR("can't make first thread"); } - (void) PyThreadState_Swap(tstate); + _PyThreadState_Bind(tstate); + // XXX For now we do this before the GIL is created. + (void) _PyThreadState_SwapNoGIL(tstate); - status = init_interp_create_gil(tstate); + status = init_interp_create_gil(tstate, config.gil); if (_PyStatus_EXCEPTION(status)) { return status; } @@ -696,21 +691,11 @@ pycore_init_types(PyInterpreterState *interp) { PyStatus status; - status = _PyTypes_InitState(interp); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - status = _PyTypes_InitTypes(interp); if (_PyStatus_EXCEPTION(status)) { return status; } - status = _PyBytes_InitTypes(interp); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - status = _PyLong_InitTypes(interp); if (_PyStatus_EXCEPTION(status)) { return status; @@ -726,11 +711,6 @@ pycore_init_types(PyInterpreterState *interp) return status; } - status = _PyTuple_InitTypes(interp); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - if (_PyExc_InitTypes(interp) < 0) { return _PyStatus_ERR("failed to initialize an exception type"); } @@ -757,6 +737,21 @@ pycore_init_types(PyInterpreterState *interp) return _PyStatus_OK(); } +static const uint8_t INTERPRETER_TRAMPOLINE_INSTRUCTIONS[] = { + /* Put a NOP at the start, so that the IP points into + * the code, rather than before it */ + NOP, 0, + INTERPRETER_EXIT, 0, + /* RESUME at end makes sure that the frame appears incomplete */ + RESUME, 0 +}; + +static const _PyShimCodeDef INTERPRETER_TRAMPOLINE_CODEDEF = { + INTERPRETER_TRAMPOLINE_INSTRUCTIONS, + sizeof(INTERPRETER_TRAMPOLINE_INSTRUCTIONS), + 1, + "<interpreter trampoline>" +}; static PyStatus pycore_init_builtins(PyThreadState *tstate) @@ -768,7 +763,8 @@ pycore_init_builtins(PyThreadState *tstate) goto error; } - if (_PyImport_FixupBuiltin(bimod, "builtins", interp->modules) < 0) { + PyObject *modules = _PyImport_GetModules(interp); + if (_PyImport_FixupBuiltin(bimod, "builtins", modules) < 0) { goto error; } @@ -776,8 +772,7 @@ pycore_init_builtins(PyThreadState *tstate) if (builtins_dict == NULL) { goto error; } - Py_INCREF(builtins_dict); - interp->builtins = builtins_dict; + interp->builtins = Py_NewRef(builtins_dict); PyObject *isinstance = PyDict_GetItem(builtins_dict, &_Py_ID(isinstance)); assert(isinstance); @@ -788,7 +783,13 @@ pycore_init_builtins(PyThreadState *tstate) PyObject *list_append = _PyType_Lookup(&PyList_Type, &_Py_ID(append)); assert(list_append); interp->callable_cache.list_append = list_append; - + PyObject *object__getattribute__ = _PyType_Lookup(&PyBaseObject_Type, &_Py_ID(__getattribute__)); + assert(object__getattribute__); + interp->callable_cache.object__getattribute__ = object__getattribute__; + interp->interpreter_trampoline = _Py_MakeShimCode(&INTERPRETER_TRAMPOLINE_CODEDEF); + if (interp->interpreter_trampoline == NULL) { + return _PyStatus_ERR("failed to create interpreter trampoline."); + } if (_PyBuiltins_AddExceptions(bimod) < 0) { return _PyStatus_ERR("failed to add exceptions to builtins"); } @@ -799,13 +800,9 @@ pycore_init_builtins(PyThreadState *tstate) } Py_DECREF(bimod); - // Get the __import__ function - PyObject *import_func = _PyDict_GetItemStringWithError(interp->builtins, - "__import__"); - if (import_func == NULL) { + if (_PyImport_InitDefaultImportFunc(interp) < 0) { goto error; } - interp->import_func = Py_NewRef(import_func); assert(!_PyErr_Occurred(tstate)); return _PyStatus_OK(); @@ -867,11 +864,10 @@ pycore_interp_init(PyThreadState *tstate) } const PyConfig *config = _PyInterpreterState_GetConfig(interp); - if (config->_install_importlib) { - /* This call sets up builtin and frozen import support */ - if (init_importlib(tstate, sysmod) < 0) { - return _PyStatus_ERR("failed to initialize importlib"); - } + + status = _PyImport_InitCore(tstate, sysmod, config->_install_importlib); + if (_PyStatus_EXCEPTION(status)) { + goto done; } done: @@ -1092,8 +1088,6 @@ pyinit_main_reconfigure(PyThreadState *tstate) static PyStatus init_interp_main(PyThreadState *tstate) { - extern void _PyThread_debug_deprecation(void); - assert(!_PyErr_Occurred(tstate)); PyStatus status; @@ -1123,7 +1117,7 @@ init_interp_main(PyThreadState *tstate) return _PyStatus_ERR("failed to update the Python config"); } - status = init_importlib_external(tstate); + status = _PyImport_InitExternal(tstate); if (_PyStatus_EXCEPTION(status)) { return status; } @@ -1146,9 +1140,20 @@ init_interp_main(PyThreadState *tstate) return _PyStatus_ERR("can't initialize signals"); } - if (_PyTraceMalloc_Init(config->tracemalloc) < 0) { - return _PyStatus_ERR("can't initialize tracemalloc"); + if (config->tracemalloc) { + if (_PyTraceMalloc_Start(config->tracemalloc) < 0) { + return _PyStatus_ERR("can't start tracemalloc"); + } + } + +#ifdef PY_HAVE_PERF_TRAMPOLINE + if (config->perf_profiling) { + if (_PyPerfTrampoline_SetCallbacks(&_Py_perfmap_callbacks) < 0 || + _PyPerfTrampoline_Init(config->perf_profiling) < 0) { + return _PyStatus_ERR("can't initialize the perf trampoline"); + } } +#endif } status = init_sys_streams(tstate); @@ -1195,9 +1200,6 @@ init_interp_main(PyThreadState *tstate) #endif } - // Warn about PYTHONTHREADDEBUG deprecation - _PyThread_debug_deprecation(); - assert(!_PyErr_Occurred(tstate)); return _PyStatus_OK(); @@ -1310,8 +1312,7 @@ _Py_InitializeMain(void) if (_PyStatus_EXCEPTION(status)) { return status; } - _PyRuntimeState *runtime = &_PyRuntime; - PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); + PyThreadState *tstate = _PyThreadState_GET(); return pyinit_main(tstate); } @@ -1321,10 +1322,13 @@ finalize_modules_delete_special(PyThreadState *tstate, int verbose) { // List of names to clear in sys static const char * const sys_deletes[] = { - "path", "argv", "ps1", "ps2", + "path", "argv", "ps1", "ps2", "last_exc", "last_type", "last_value", "last_traceback", - "path_hooks", "path_importer_cache", "meta_path", "__interactivehook__", + // path_hooks and path_importer_cache are cleared + // by _PyImport_FiniExternal(). + // XXX Clear meta_path in _PyImport_FiniCore(). + "meta_path", NULL }; @@ -1345,10 +1349,7 @@ finalize_modules_delete_special(PyThreadState *tstate, int verbose) const char * const *p; for (p = sys_deletes; *p != NULL; p++) { - if (verbose) { - PySys_WriteStderr("# clear sys.%s\n", *p); - } - if (PyDict_SetItemString(interp->sysdict, *p, Py_None) < 0) { + if (_PySys_ClearAttrString(interp, *p, verbose) < 0) { PyErr_WriteUnraisable(NULL); } } @@ -1469,7 +1470,7 @@ finalize_restore_builtins(PyThreadState *tstate) } PyDict_Clear(interp->builtins); if (PyDict_Update(interp->builtins, interp->builtins_copy)) { - _PyErr_Clear(tstate); + PyErr_WriteUnraisable(NULL); } Py_XDECREF(dict); } @@ -1520,11 +1521,12 @@ finalize_clear_sys_builtins_dict(PyInterpreterState *interp, int verbose) /* Clear modules, as good as we can */ +// XXX Move most of this to import.c. static void finalize_modules(PyThreadState *tstate) { PyInterpreterState *interp = tstate->interp; - PyObject *modules = interp->modules; + PyObject *modules = _PyImport_GetModules(interp); if (modules == NULL) { // Already done return; @@ -1589,12 +1591,12 @@ finalize_modules(PyThreadState *tstate) // clear PyInterpreterState.modules_by_index and // clear PyModuleDef.m_base.m_copy (of extensions not using the multi-phase // initialization API) - _PyInterpreterState_ClearModules(interp); + _PyImport_ClearModulesByIndex(interp); // Clear and delete the modules directory. Actual modules will // still be there only if imported during the execution of some // destructor. - Py_SETREF(interp->modules, NULL); + _PyImport_ClearModules(interp); // Collect garbage once more _PyGC_CollectNoFail(tstate); @@ -1671,17 +1673,20 @@ static void finalize_interp_types(PyInterpreterState *interp) { _PyUnicode_FiniTypes(interp); - _PySys_Fini(interp); + _PySys_FiniTypes(interp); _PyExc_Fini(interp); _PyAsyncGen_Fini(interp); _PyContext_Fini(interp); _PyFloat_FiniType(interp); _PyLong_FiniTypes(interp); _PyThread_FiniType(interp); + // XXX fini collections module static types (_PyStaticType_Dealloc()) + // XXX fini IO module static types (_PyStaticType_Dealloc()) _PyErr_FiniTypes(interp); - _PyTypes_Fini(interp); _PyTypes_FiniTypes(interp); + _PyTypes_Fini(interp); + // Call _PyUnicode_ClearInterned() before _PyDict_Fini() since it uses // a dict internally. _PyUnicode_ClearInterned(interp); @@ -1694,6 +1699,9 @@ finalize_interp_types(PyInterpreterState *interp) _PyUnicode_Fini(interp); _PyFloat_Fini(interp); +#ifdef Py_DEBUG + _PyStaticObjects_CheckRefcnt(interp); +#endif } @@ -1703,14 +1711,11 @@ finalize_interp_clear(PyThreadState *tstate) int is_main_interp = _Py_IsMainInterpreter(tstate->interp); _PyExc_ClearExceptionGroupType(tstate->interp); + _Py_clear_generic_types(tstate->interp); /* Clear interpreter state and all thread states */ _PyInterpreterState_Clear(tstate); - if (is_main_interp) { - _PyIO_Fini(); - } - /* Clear all loghooks */ /* Both _PySys_Audit function and users still need PyObject, such as tuple. Call _PySys_ClearAuditHooks when PyObject available. */ @@ -1723,6 +1728,7 @@ finalize_interp_clear(PyThreadState *tstate) _PyArg_Fini(); _Py_ClearFileSystemEncoding(); _Py_Deepfreeze_Fini(); + _PyPerfTrampoline_Fini(); } finalize_interp_types(tstate->interp); @@ -1732,10 +1738,8 @@ finalize_interp_clear(PyThreadState *tstate) static void finalize_interp_delete(PyInterpreterState *interp) { - if (_Py_IsMainInterpreter(interp)) { - /* Cleanup auto-thread-state */ - _PyGILState_Fini(interp); - } + /* Cleanup auto-thread-state */ + _PyGILState_Fini(interp); /* We can't call _PyEval_FiniGIL() here because destroying the GIL lock can fail when it is being awaited by another running daemon thread (see @@ -1758,7 +1762,12 @@ Py_FinalizeEx(void) } /* Get current thread state and interpreter pointer */ - PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); + PyThreadState *tstate = _PyThreadState_GET(); + // XXX assert(_Py_IsMainInterpreter(tstate->interp)); + // XXX assert(_Py_IsMainThread()); + + // Block some operations. + tstate->interp->finalizing = 1; // Wrap up existing "threading"-module-created, non-daemon threads. wait_for_thread_shutdown(tstate); @@ -1777,6 +1786,7 @@ Py_FinalizeEx(void) */ _PyAtExit_Call(tstate->interp); + PyUnstable_PerfMapState_Fini(); /* Copy the core config, PyInterpreterState_Delete() free the core config memory */ @@ -1793,10 +1803,13 @@ Py_FinalizeEx(void) /* Remaining daemon threads will automatically exit when they attempt to take the GIL (ex: PyEval_RestoreThread()). */ + _PyInterpreterState_SetFinalizing(tstate->interp, tstate); _PyRuntimeState_SetFinalizing(runtime, tstate); runtime->initialized = 0; runtime->core_initialized = 0; + // XXX Call something like _PyImport_Disable() here? + /* Destroy the state of all threads of the interpreter, except of the current thread. In practice, only daemon threads should still be alive, except if wait_for_thread_shutdown() has been cancelled by CTRL+C. @@ -1805,7 +1818,23 @@ Py_FinalizeEx(void) _PyRuntimeState_SetFinalizing() has been called, no other Python thread can take the GIL at this point: if they try, they will exit immediately. */ - _PyThreadState_DeleteExcept(runtime, tstate); + _PyThreadState_DeleteExcept(tstate); + + /* At this point no Python code should be running at all. + The only thread state left should be the main thread of the main + interpreter (AKA tstate), in which this code is running right now. + There may be other OS threads running but none of them will have + thread states associated with them, nor will be able to create + new thread states. + + Thus tstate is the only possible thread state from here on out. + It may still be used during finalization to run Python code as + needed or provide runtime state (e.g. sys.modules) but that will + happen sparingly. Furthermore, the order of finalization aims + to not need a thread (or interpreter) state as soon as possible. + */ + // XXX Make sure we are preventing the creating of any new thread states + // (or interpreters). /* Flush sys.stdout and sys.stderr */ if (flush_std_files() < 0) { @@ -1830,6 +1859,7 @@ Py_FinalizeEx(void) PyGC_Collect(); /* Destroy all modules */ + _PyImport_FiniExternal(tstate->interp); finalize_modules(tstate); /* Print debug stats if any */ @@ -1863,7 +1893,9 @@ Py_FinalizeEx(void) so it is possible to use tracemalloc in objects destructor. */ _PyTraceMalloc_Fini(); - /* Destroy the database used by _PyImport_{Fixup,Find}Extension */ + /* Finalize any remaining import state */ + // XXX Move these up to where finalize_modules() is currently. + _PyImport_FiniCore(tstate->interp); _PyImport_Fini(); /* unload faulthandler module */ @@ -1888,14 +1920,28 @@ Py_FinalizeEx(void) } if (dump_refs) { - _Py_PrintReferences(stderr); + _Py_PrintReferences(tstate->interp, stderr); } if (dump_refs_fp != NULL) { - _Py_PrintReferences(dump_refs_fp); + _Py_PrintReferences(tstate->interp, dump_refs_fp); } #endif /* Py_TRACE_REFS */ + /* At this point there's almost no other Python code that will run, + nor interpreter state needed. The only possibility is the + finalizers of the objects stored on tstate (and tstate->interp), + which are triggered via finalize_interp_clear(). + + For now we operate as though none of those finalizers actually + need an operational thread state or interpreter. In reality, + those finalizers may rely on some part of tstate or + tstate->interp, and/or may raise exceptions + or otherwise fail. + */ + // XXX Do this sooner during finalization. + // XXX Ensure finalizer errors are handled properly. + finalize_interp_clear(tstate); finalize_interp_delete(tstate->interp); @@ -1903,7 +1949,9 @@ Py_FinalizeEx(void) if (show_ref_count) { _PyDebug_PrintTotalRefs(); } + _Py_FinalizeRefTotal(runtime); #endif + _Py_FinalizeAllocatedBlocks(runtime); #ifdef Py_TRACE_REFS /* Display addresses (& refcnts) of all objects still alive. @@ -1912,11 +1960,11 @@ Py_FinalizeEx(void) */ if (dump_refs) { - _Py_PrintReferenceAddresses(stderr); + _Py_PrintReferenceAddresses(tstate->interp, stderr); } if (dump_refs_fp != NULL) { - _Py_PrintReferenceAddresses(dump_refs_fp); + _Py_PrintReferenceAddresses(tstate->interp, dump_refs_fp); fclose(dump_refs_fp); } #endif /* Py_TRACE_REFS */ @@ -1953,7 +2001,7 @@ Py_Finalize(void) */ static PyStatus -new_interpreter(PyThreadState **tstate_p, int isolated_subinterpreter) +new_interpreter(PyThreadState **tstate_p, const PyInterpreterConfig *config) { PyStatus status; @@ -1977,38 +2025,56 @@ new_interpreter(PyThreadState **tstate_p, int isolated_subinterpreter) return _PyStatus_OK(); } - PyThreadState *tstate = PyThreadState_New(interp); + PyThreadState *tstate = _PyThreadState_New(interp); if (tstate == NULL) { PyInterpreterState_Delete(interp); *tstate_p = NULL; return _PyStatus_OK(); } + _PyThreadState_Bind(tstate); + + // XXX For now we do this before the GIL is created. + PyThreadState *save_tstate = _PyThreadState_SwapNoGIL(tstate); + int has_gil = 0; - PyThreadState *save_tstate = PyThreadState_Swap(tstate); + /* From this point until the init_interp_create_gil() call, + we must not do anything that requires that the GIL be held + (or otherwise exist). That applies whether or not the new + interpreter has its own GIL (e.g. the main interpreter). */ /* Copy the current interpreter config into the new interpreter */ - const PyConfig *config; + const PyConfig *src_config; if (save_tstate != NULL) { - config = _PyInterpreterState_GetConfig(save_tstate->interp); + // XXX Might new_interpreter() have been called without the GIL held? + _PyEval_ReleaseLock(save_tstate->interp, save_tstate); + src_config = _PyInterpreterState_GetConfig(save_tstate->interp); } else { /* No current thread state, copy from the main interpreter */ PyInterpreterState *main_interp = _PyInterpreterState_Main(); - config = _PyInterpreterState_GetConfig(main_interp); + src_config = _PyInterpreterState_GetConfig(main_interp); } + /* This does not require that the GIL be held. */ + status = _PyConfig_Copy(&interp->config, src_config); + if (_PyStatus_EXCEPTION(status)) { + goto error; + } - status = _PyConfig_Copy(&interp->config, config); + /* This does not require that the GIL be held. */ + status = init_interp_settings(interp, config); if (_PyStatus_EXCEPTION(status)) { goto error; } - interp->config._isolated_interpreter = isolated_subinterpreter; - status = init_interp_create_gil(tstate); + status = init_interp_create_gil(tstate, config->gil); if (_PyStatus_EXCEPTION(status)) { goto error; } + has_gil = 1; + + /* No objects have been created yet. */ status = pycore_interp_init(tstate); if (_PyStatus_EXCEPTION(status)) { @@ -2028,30 +2094,36 @@ error: /* Oops, it didn't work. Undo it all. */ PyErr_PrintEx(0); + if (has_gil) { + PyThreadState_Swap(save_tstate); + } + else { + _PyThreadState_SwapNoGIL(save_tstate); + } PyThreadState_Clear(tstate); PyThreadState_Delete(tstate); PyInterpreterState_Delete(interp); - PyThreadState_Swap(save_tstate); return status; } +PyStatus +Py_NewInterpreterFromConfig(PyThreadState **tstate_p, + const PyInterpreterConfig *config) +{ + return new_interpreter(tstate_p, config); +} + PyThreadState * -_Py_NewInterpreter(int isolated_subinterpreter) +Py_NewInterpreter(void) { PyThreadState *tstate = NULL; - PyStatus status = new_interpreter(&tstate, isolated_subinterpreter); + const PyInterpreterConfig config = _PyInterpreterConfig_LEGACY_INIT; + PyStatus status = new_interpreter(&tstate, &config); if (_PyStatus_EXCEPTION(status)) { Py_ExitStatusException(status); } return tstate; - -} - -PyThreadState * -Py_NewInterpreter(void) -{ - return _Py_NewInterpreter(0); } /* Delete an interpreter and its last thread. This requires that the @@ -2082,18 +2154,41 @@ Py_EndInterpreter(PyThreadState *tstate) // Wrap up existing "threading"-module-created, non-daemon threads. wait_for_thread_shutdown(tstate); + // Make any remaining pending calls. + _Py_FinishPendingCalls(tstate); + _PyAtExit_Call(tstate->interp); if (tstate != interp->threads.head || tstate->next != NULL) { Py_FatalError("not the last thread"); } + /* Remaining daemon threads will automatically exit + when they attempt to take the GIL (ex: PyEval_RestoreThread()). */ + _PyInterpreterState_SetFinalizing(interp, tstate); + + // XXX Call something like _PyImport_Disable() here? + + _PyImport_FiniExternal(tstate->interp); finalize_modules(tstate); + _PyImport_FiniCore(tstate->interp); finalize_interp_clear(tstate); finalize_interp_delete(tstate->interp); } +int +_Py_IsInterpreterFinalizing(PyInterpreterState *interp) +{ + /* We check the runtime first since, in a daemon thread, + interp might be dangling pointer. */ + PyThreadState *finalizing = _PyRuntimeState_GetFinalizing(&_PyRuntime); + if (finalizing == NULL) { + finalizing = _PyInterpreterState_GetFinalizing(interp); + } + return finalizing != NULL; +} + /* Add the __main__ module */ static PyStatus @@ -2126,10 +2221,9 @@ add_main_module(PyInterpreterState *interp) Py_DECREF(bimod); } - /* Main is a little special - imp.is_builtin("__main__") will return - * False, but BuiltinImporter is still the most appropriate initial - * setting for its __loader__ attribute. A more suitable value will - * be set if __main__ gets further initialized later in the startup + /* Main is a little special - BuiltinImporter is the most appropriate + * initial setting for its __loader__ attribute. A more suitable value + * will be set if __main__ gets further initialized later in the startup * process. */ loader = _PyDict_GetItemStringWithError(d, "__loader__"); @@ -2137,8 +2231,8 @@ add_main_module(PyInterpreterState *interp) if (PyErr_Occurred()) { return _PyStatus_ERR("Failed to test __main__.__loader__"); } - PyObject *loader = PyObject_GetAttrString(interp->importlib, - "BuiltinImporter"); + PyObject *loader = _PyImport_GetImportlibLoader(interp, + "BuiltinImporter"); if (loader == NULL) { return _PyStatus_ERR("Failed to retrieve BuiltinImporter"); } @@ -2254,14 +2348,21 @@ create_stdio(const PyConfig *config, PyObject* io, goto error; } else { - raw = buf; - Py_INCREF(raw); + raw = Py_NewRef(buf); } -#ifdef MS_WINDOWS +#ifdef HAVE_WINDOWS_CONSOLE_IO /* Windows console IO is always UTF-8 encoded */ - if (PyWindowsConsoleIO_Check(raw)) + PyTypeObject *winconsoleio_type = (PyTypeObject *)_PyImport_GetModuleAttr( + &_Py_ID(_io), &_Py_ID(_WindowsConsoleIO)); + if (winconsoleio_type == NULL) { + goto error; + } + int is_subclass = PyObject_TypeCheck(raw, winconsoleio_type); + Py_DECREF(winconsoleio_type); + if (is_subclass) { encoding = L"utf-8"; + } #endif text = PyUnicode_FromString(name); @@ -2349,19 +2450,15 @@ error: static PyStatus init_set_builtins_open(void) { - PyObject *iomod = NULL, *wrapper; + PyObject *wrapper; PyObject *bimod = NULL; PyStatus res = _PyStatus_OK(); - if (!(iomod = PyImport_ImportModule("io"))) { - goto error; - } - if (!(bimod = PyImport_ImportModule("builtins"))) { goto error; } - if (!(wrapper = PyObject_GetAttrString(iomod, "open"))) { + if (!(wrapper = _PyImport_GetModuleAttrString("io", "open"))) { goto error; } @@ -2378,7 +2475,6 @@ error: done: Py_XDECREF(bimod); - Py_XDECREF(iomod); return res; } @@ -2503,42 +2599,29 @@ _Py_FatalError_DumpTracebacks(int fd, PyInterpreterState *interp, static int _Py_FatalError_PrintExc(PyThreadState *tstate) { - PyObject *ferr, *res; - PyObject *exception, *v, *tb; - int has_tb; - - _PyErr_Fetch(tstate, &exception, &v, &tb); - if (exception == NULL) { + PyObject *exc = _PyErr_GetRaisedException(tstate); + if (exc == NULL) { /* No current exception */ return 0; } - ferr = _PySys_GetAttr(tstate, &_Py_ID(stderr)); + PyObject *ferr = _PySys_GetAttr(tstate, &_Py_ID(stderr)); if (ferr == NULL || ferr == Py_None) { /* sys.stderr is not set yet or set to None, no need to try to display the exception */ + Py_DECREF(exc); return 0; } - _PyErr_NormalizeException(tstate, &exception, &v, &tb); - if (tb == NULL) { - tb = Py_None; - Py_INCREF(tb); - } - PyException_SetTraceback(v, tb); - if (exception == NULL) { - /* PyErr_NormalizeException() failed */ - return 0; - } + PyErr_DisplayException(exc); - has_tb = (tb != Py_None); - PyErr_Display(exception, v, tb); - Py_XDECREF(exception); - Py_XDECREF(v); + PyObject *tb = PyException_GetTraceback(exc); + int has_tb = (tb != NULL) && (tb != Py_None); Py_XDECREF(tb); + Py_DECREF(exc); /* sys.stderr may be buffered: call sys.stderr.flush() */ - res = PyObject_CallMethodNoArgs(ferr, &_Py_ID(flush)); + PyObject *res = PyObject_CallMethodNoArgs(ferr, &_Py_ID(flush)); if (res == NULL) { _PyErr_Clear(tstate); } @@ -2643,7 +2726,7 @@ _Py_DumpExtensionModules(int fd, PyInterpreterState *interp) if (interp == NULL) { return; } - PyObject *modules = interp->modules; + PyObject *modules = _PyImport_GetModules(interp); if (modules == NULL || !PyDict_Check(modules)) { return; } @@ -2764,7 +2847,7 @@ fatal_error(int fd, int header, const char *prefix, const char *msg, tss_tstate != tstate if the current Python thread does not hold the GIL. */ - PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime); + PyThreadState *tstate = _PyThreadState_GET(); PyInterpreterState *interp = NULL; PyThreadState *tss_tstate = PyGILState_GetThisThreadState(); if (tstate != NULL) { @@ -2843,11 +2926,7 @@ _Py_FatalErrorFormat(const char *func, const char *format, ...) } va_list vargs; -#ifdef HAVE_STDARG_PROTOTYPES va_start(vargs, format); -#else - va_start(vargs); -#endif vfprintf(stream, format, vargs); va_end(vargs); @@ -2909,26 +2988,37 @@ wait_for_thread_shutdown(PyThreadState *tstate) Py_DECREF(threading); } -#define NEXITFUNCS 32 int Py_AtExit(void (*func)(void)) { - if (_PyRuntime.nexitfuncs >= NEXITFUNCS) + struct _atexit_runtime_state *state = &_PyRuntime.atexit; + PyThread_acquire_lock(state->mutex, WAIT_LOCK); + if (state->ncallbacks >= NEXITFUNCS) { + PyThread_release_lock(state->mutex); return -1; - _PyRuntime.exitfuncs[_PyRuntime.nexitfuncs++] = func; + } + state->callbacks[state->ncallbacks++] = func; + PyThread_release_lock(state->mutex); return 0; } static void call_ll_exitfuncs(_PyRuntimeState *runtime) { - while (runtime->nexitfuncs > 0) { + atexit_callbackfunc exitfunc; + struct _atexit_runtime_state *state = &runtime->atexit; + + PyThread_acquire_lock(state->mutex, WAIT_LOCK); + while (state->ncallbacks > 0) { /* pop last function from the list */ - runtime->nexitfuncs--; - void (*exitfunc)(void) = runtime->exitfuncs[runtime->nexitfuncs]; - runtime->exitfuncs[runtime->nexitfuncs] = NULL; + state->ncallbacks--; + exitfunc = state->callbacks[state->ncallbacks]; + state->callbacks[state->ncallbacks] = NULL; + PyThread_release_lock(state->mutex); exitfunc(); + PyThread_acquire_lock(state->mutex, WAIT_LOCK); } + PyThread_release_lock(state->mutex); fflush(stdout); fflush(stderr); @@ -2954,28 +3044,30 @@ Py_Exit(int sts) int Py_FdIsInteractive(FILE *fp, const char *filename) { - if (isatty((int)fileno(fp))) + if (isatty(fileno(fp))) { return 1; - if (!Py_InteractiveFlag) + } + if (!_Py_GetConfig()->interactive) { return 0; - return (filename == NULL) || - (strcmp(filename, "<stdin>") == 0) || - (strcmp(filename, "???") == 0); + } + return ((filename == NULL) + || (strcmp(filename, "<stdin>") == 0) + || (strcmp(filename, "???") == 0)); } int _Py_FdIsInteractive(FILE *fp, PyObject *filename) { - if (isatty((int)fileno(fp))) { + if (isatty(fileno(fp))) { return 1; } - if (!Py_InteractiveFlag) { + if (!_Py_GetConfig()->interactive) { return 0; } - return (filename == NULL) || - (PyUnicode_CompareWithASCIIString(filename, "<stdin>") == 0) || - (PyUnicode_CompareWithASCIIString(filename, "???") == 0); + return ((filename == NULL) + || (PyUnicode_CompareWithASCIIString(filename, "<stdin>") == 0) + || (PyUnicode_CompareWithASCIIString(filename, "???") == 0)); } diff --git a/Python/pystate.c b/Python/pystate.c index c0d161f8..2ee16e3d 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -3,14 +3,15 @@ #include "Python.h" #include "pycore_ceval.h" -#include "pycore_code.h" // stats +#include "pycore_code.h" // stats +#include "pycore_dtoa.h" // _dtoa_state_INIT() #include "pycore_frame.h" #include "pycore_initconfig.h" #include "pycore_object.h" // _PyType_InitCache() #include "pycore_pyerrors.h" #include "pycore_pylifecycle.h" #include "pycore_pymem.h" // _PyMem_SetDefaultAllocator() -#include "pycore_pystate.h" // _PyThreadState_GET() +#include "pycore_pystate.h" #include "pycore_runtime_init.h" // _PyRuntimeState_INIT #include "pycore_sysmodule.h" @@ -37,56 +38,383 @@ to avoid the expense of doing their own locking). extern "C" { #endif -#define _PyRuntimeGILState_GetThreadState(gilstate) \ - ((PyThreadState*)_Py_atomic_load_relaxed(&(gilstate)->tstate_current)) -#define _PyRuntimeGILState_SetThreadState(gilstate, value) \ - _Py_atomic_store_relaxed(&(gilstate)->tstate_current, \ - (uintptr_t)(value)) -/* Forward declarations */ -static PyThreadState *_PyGILState_GetThisThreadState(struct _gilstate_runtime_state *gilstate); -static void _PyThreadState_Delete(PyThreadState *tstate, int check_current); +/****************************************/ +/* helpers for the current thread state */ +/****************************************/ + +// API for the current thread state is further down. + +/* "current" means one of: + - bound to the current OS thread + - holds the GIL + */ + +//------------------------------------------------- +// a highly efficient lookup for the current thread +//------------------------------------------------- + +/* + The stored thread state is set by PyThreadState_Swap(). + + For each of these functions, the GIL must be held by the current thread. + */ + + +#ifdef HAVE_THREAD_LOCAL +_Py_thread_local PyThreadState *_Py_tss_tstate = NULL; +#endif + +static inline PyThreadState * +current_fast_get(_PyRuntimeState *Py_UNUSED(runtime)) +{ +#ifdef HAVE_THREAD_LOCAL + return _Py_tss_tstate; +#else + // XXX Fall back to the PyThread_tss_*() API. +# error "no supported thread-local variable storage classifier" +#endif +} + +static inline void +current_fast_set(_PyRuntimeState *Py_UNUSED(runtime), PyThreadState *tstate) +{ + assert(tstate != NULL); +#ifdef HAVE_THREAD_LOCAL + _Py_tss_tstate = tstate; +#else + // XXX Fall back to the PyThread_tss_*() API. +# error "no supported thread-local variable storage classifier" +#endif +} + +static inline void +current_fast_clear(_PyRuntimeState *Py_UNUSED(runtime)) +{ +#ifdef HAVE_THREAD_LOCAL + _Py_tss_tstate = NULL; +#else + // XXX Fall back to the PyThread_tss_*() API. +# error "no supported thread-local variable storage classifier" +#endif +} + +#define tstate_verify_not_active(tstate) \ + if (tstate == current_fast_get((tstate)->interp->runtime)) { \ + _Py_FatalErrorFormat(__func__, "tstate %p is still current", tstate); \ + } + +PyThreadState * +_PyThreadState_GetCurrent(void) +{ + return current_fast_get(&_PyRuntime); +} + + +//------------------------------------------------ +// the thread state bound to the current OS thread +//------------------------------------------------ + +static inline int +tstate_tss_initialized(Py_tss_t *key) +{ + return PyThread_tss_is_created(key); +} + +static inline int +tstate_tss_init(Py_tss_t *key) +{ + assert(!tstate_tss_initialized(key)); + return PyThread_tss_create(key); +} + +static inline void +tstate_tss_fini(Py_tss_t *key) +{ + assert(tstate_tss_initialized(key)); + PyThread_tss_delete(key); +} + +static inline PyThreadState * +tstate_tss_get(Py_tss_t *key) +{ + assert(tstate_tss_initialized(key)); + return (PyThreadState *)PyThread_tss_get(key); +} + +static inline int +tstate_tss_set(Py_tss_t *key, PyThreadState *tstate) +{ + assert(tstate != NULL); + assert(tstate_tss_initialized(key)); + return PyThread_tss_set(key, (void *)tstate); +} + +static inline int +tstate_tss_clear(Py_tss_t *key) +{ + assert(tstate_tss_initialized(key)); + return PyThread_tss_set(key, (void *)NULL); +} + +#ifdef HAVE_FORK +/* Reset the TSS key - called by PyOS_AfterFork_Child(). + * This should not be necessary, but some - buggy - pthread implementations + * don't reset TSS upon fork(), see issue #10517. + */ +static PyStatus +tstate_tss_reinit(Py_tss_t *key) +{ + if (!tstate_tss_initialized(key)) { + return _PyStatus_OK(); + } + PyThreadState *tstate = tstate_tss_get(key); + + tstate_tss_fini(key); + if (tstate_tss_init(key) != 0) { + return _PyStatus_NO_MEMORY(); + } + + /* If the thread had an associated auto thread state, reassociate it with + * the new key. */ + if (tstate && tstate_tss_set(key, tstate) != 0) { + return _PyStatus_ERR("failed to re-set autoTSSkey"); + } + return _PyStatus_OK(); +} +#endif + + +/* + The stored thread state is set by bind_tstate() (AKA PyThreadState_Bind(). + + The GIL does no need to be held for these. + */ + +#define gilstate_tss_initialized(runtime) \ + tstate_tss_initialized(&(runtime)->autoTSSkey) +#define gilstate_tss_init(runtime) \ + tstate_tss_init(&(runtime)->autoTSSkey) +#define gilstate_tss_fini(runtime) \ + tstate_tss_fini(&(runtime)->autoTSSkey) +#define gilstate_tss_get(runtime) \ + tstate_tss_get(&(runtime)->autoTSSkey) +#define _gilstate_tss_set(runtime, tstate) \ + tstate_tss_set(&(runtime)->autoTSSkey, tstate) +#define _gilstate_tss_clear(runtime) \ + tstate_tss_clear(&(runtime)->autoTSSkey) +#define gilstate_tss_reinit(runtime) \ + tstate_tss_reinit(&(runtime)->autoTSSkey) + +static inline void +gilstate_tss_set(_PyRuntimeState *runtime, PyThreadState *tstate) +{ + assert(tstate != NULL && tstate->interp->runtime == runtime); + if (_gilstate_tss_set(runtime, tstate) != 0) { + Py_FatalError("failed to set current tstate (TSS)"); + } +} + +static inline void +gilstate_tss_clear(_PyRuntimeState *runtime) +{ + if (_gilstate_tss_clear(runtime) != 0) { + Py_FatalError("failed to clear current tstate (TSS)"); + } +} + + +#ifndef NDEBUG +static inline int tstate_is_alive(PyThreadState *tstate); + +static inline int +tstate_is_bound(PyThreadState *tstate) +{ + return tstate->_status.bound && !tstate->_status.unbound; +} +#endif // !NDEBUG + +static void bind_gilstate_tstate(PyThreadState *); +static void unbind_gilstate_tstate(PyThreadState *); + +static void +bind_tstate(PyThreadState *tstate) +{ + assert(tstate != NULL); + assert(tstate_is_alive(tstate) && !tstate->_status.bound); + assert(!tstate->_status.unbound); // just in case + assert(!tstate->_status.bound_gilstate); + assert(tstate != gilstate_tss_get(tstate->interp->runtime)); + assert(!tstate->_status.active); + assert(tstate->thread_id == 0); + assert(tstate->native_thread_id == 0); + + // Currently we don't necessarily store the thread state + // in thread-local storage (e.g. per-interpreter). + + tstate->thread_id = PyThread_get_thread_ident(); +#ifdef PY_HAVE_THREAD_NATIVE_ID + tstate->native_thread_id = PyThread_get_thread_native_id(); +#endif + + tstate->_status.bound = 1; +} + +static void +unbind_tstate(PyThreadState *tstate) +{ + assert(tstate != NULL); + // XXX assert(tstate_is_alive(tstate)); + assert(tstate_is_bound(tstate)); + // XXX assert(!tstate->_status.active); + assert(tstate->thread_id > 0); +#ifdef PY_HAVE_THREAD_NATIVE_ID + assert(tstate->native_thread_id > 0); +#endif + + // We leave thread_id and native_thread_id alone + // since they can be useful for debugging. + // Check the `_status` field to know if these values + // are still valid. + + // We leave tstate->_status.bound set to 1 + // to indicate it was previously bound. + tstate->_status.unbound = 1; +} + + +/* Stick the thread state for this thread in thread specific storage. + + When a thread state is created for a thread by some mechanism + other than PyGILState_Ensure(), it's important that the GILState + machinery knows about it so it doesn't try to create another + thread state for the thread. + (This is a better fix for SF bug #1010677 than the first one attempted.) + + The only situation where you can legitimately have more than one + thread state for an OS level thread is when there are multiple + interpreters. + + Before 3.12, the PyGILState_*() APIs didn't work with multiple + interpreters (see bpo-10915 and bpo-15751), so this function used + to set TSS only once. Thus, the first thread state created for that + given OS level thread would "win", which seemed reasonable behaviour. +*/ + +static void +bind_gilstate_tstate(PyThreadState *tstate) +{ + assert(tstate != NULL); + assert(tstate_is_alive(tstate)); + assert(tstate_is_bound(tstate)); + // XXX assert(!tstate->_status.active); + assert(!tstate->_status.bound_gilstate); + + _PyRuntimeState *runtime = tstate->interp->runtime; + PyThreadState *tcur = gilstate_tss_get(runtime); + assert(tstate != tcur); + + if (tcur != NULL) { + tcur->_status.bound_gilstate = 0; + } + gilstate_tss_set(runtime, tstate); + tstate->_status.bound_gilstate = 1; +} + +static void +unbind_gilstate_tstate(PyThreadState *tstate) +{ + assert(tstate != NULL); + // XXX assert(tstate_is_alive(tstate)); + assert(tstate_is_bound(tstate)); + // XXX assert(!tstate->_status.active); + assert(tstate->_status.bound_gilstate); + assert(tstate == gilstate_tss_get(tstate->interp->runtime)); + + gilstate_tss_clear(tstate->interp->runtime); + tstate->_status.bound_gilstate = 0; +} + + +//---------------------------------------------- +// the thread state that currently holds the GIL +//---------------------------------------------- + +/* This is not exported, as it is not reliable! It can only + ever be compared to the state for the *current* thread. + * If not equal, then it doesn't matter that the actual + value may change immediately after comparison, as it can't + possibly change to the current thread's state. + * If equal, then the current thread holds the lock, so the value can't + change until we yield the lock. +*/ +static int +holds_gil(PyThreadState *tstate) +{ + // XXX Fall back to tstate->interp->runtime->ceval.gil.last_holder + // (and tstate->interp->runtime->ceval.gil.locked). + assert(tstate != NULL); + _PyRuntimeState *runtime = tstate->interp->runtime; + /* Must be the tstate for this thread */ + assert(tstate == gilstate_tss_get(runtime)); + return tstate == current_fast_get(runtime); +} + + +/****************************/ +/* the global runtime state */ +/****************************/ + +//---------- +// lifecycle +//---------- /* Suppress deprecation warning for PyBytesObject.ob_shash */ _Py_COMP_DIAG_PUSH _Py_COMP_DIAG_IGNORE_DEPR_DECLS /* We use "initial" if the runtime gets re-used - (e.g. Py_Finalize() followed by Py_Initialize(). */ -static const _PyRuntimeState initial = _PyRuntimeState_INIT; + (e.g. Py_Finalize() followed by Py_Initialize(). + Note that we initialize "initial" relative to _PyRuntime, + to ensure pre-initialized pointers point to the active + runtime state (and not "initial"). */ +static const _PyRuntimeState initial = _PyRuntimeState_INIT(_PyRuntime); _Py_COMP_DIAG_POP +#define NUMLOCKS 9 +#define LOCKS_INIT(runtime) \ + { \ + &(runtime)->interpreters.mutex, \ + &(runtime)->xidregistry.mutex, \ + &(runtime)->getargs.mutex, \ + &(runtime)->unicode_state.ids.lock, \ + &(runtime)->imports.extensions.mutex, \ + &(runtime)->ceval.pending_mainthread.lock, \ + &(runtime)->atexit.mutex, \ + &(runtime)->audit_hooks.mutex, \ + &(runtime)->allocators.mutex, \ + } + static int -alloc_for_runtime(PyThread_type_lock *plock1, PyThread_type_lock *plock2, - PyThread_type_lock *plock3) +alloc_for_runtime(PyThread_type_lock locks[NUMLOCKS]) { /* Force default allocator, since _PyRuntimeState_Fini() must use the same allocator than this function. */ PyMemAllocatorEx old_alloc; _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - PyThread_type_lock lock1 = PyThread_allocate_lock(); - if (lock1 == NULL) { - return -1; - } - - PyThread_type_lock lock2 = PyThread_allocate_lock(); - if (lock2 == NULL) { - PyThread_free_lock(lock1); - return -1; - } - - PyThread_type_lock lock3 = PyThread_allocate_lock(); - if (lock3 == NULL) { - PyThread_free_lock(lock1); - PyThread_free_lock(lock2); - return -1; + for (int i = 0; i < NUMLOCKS; i++) { + PyThread_type_lock lock = PyThread_allocate_lock(); + if (lock == NULL) { + for (int j = 0; j < i; j++) { + PyThread_free_lock(locks[j]); + locks[j] = NULL; + } + break; + } + locks[i] = lock; } PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - - *plock1 = lock1; - *plock2 = lock2; - *plock3 = lock3; return 0; } @@ -95,9 +423,7 @@ init_runtime(_PyRuntimeState *runtime, void *open_code_hook, void *open_code_userdata, _Py_AuditHookEntry *audit_hook_head, Py_ssize_t unicode_next_index, - PyThread_type_lock unicode_ids_mutex, - PyThread_type_lock interpreters_mutex, - PyThread_type_lock xidregistry_mutex) + PyThread_type_lock locks[NUMLOCKS]) { if (runtime->_initialized) { Py_FatalError("runtime already initialized"); @@ -109,21 +435,20 @@ init_runtime(_PyRuntimeState *runtime, runtime->open_code_hook = open_code_hook; runtime->open_code_userdata = open_code_userdata; - runtime->audit_hook_head = audit_hook_head; - - _PyEval_InitRuntimeState(&runtime->ceval); + runtime->audit_hooks.head = audit_hook_head; PyPreConfig_InitPythonConfig(&runtime->preconfig); - runtime->interpreters.mutex = interpreters_mutex; - - runtime->xidregistry.mutex = xidregistry_mutex; + PyThread_type_lock *lockptrs[NUMLOCKS] = LOCKS_INIT(runtime); + for (int i = 0; i < NUMLOCKS; i++) { + assert(locks[i] != NULL); + *lockptrs[i] = locks[i]; + } // Set it to the ID of the main thread of the main interpreter. runtime->main_thread = PyThread_get_thread_ident(); - runtime->unicode_ids.next_index = unicode_next_index; - runtime->unicode_ids.lock = unicode_ids_mutex; + runtime->unicode_state.ids.next_index = unicode_next_index; runtime->_initialized = 1; } @@ -136,13 +461,13 @@ _PyRuntimeState_Init(_PyRuntimeState *runtime) initialization and interpreter initialization. */ void *open_code_hook = runtime->open_code_hook; void *open_code_userdata = runtime->open_code_userdata; - _Py_AuditHookEntry *audit_hook_head = runtime->audit_hook_head; + _Py_AuditHookEntry *audit_hook_head = runtime->audit_hooks.head; // bpo-42882: Preserve next_index value if Py_Initialize()/Py_Finalize() // is called multiple times. - Py_ssize_t unicode_next_index = runtime->unicode_ids.next_index; + Py_ssize_t unicode_next_index = runtime->unicode_state.ids.next_index; - PyThread_type_lock lock1, lock2, lock3; - if (alloc_for_runtime(&lock1, &lock2, &lock3) != 0) { + PyThread_type_lock locks[NUMLOCKS]; + if (alloc_for_runtime(locks) != 0) { return _PyStatus_NO_MEMORY(); } @@ -151,8 +476,19 @@ _PyRuntimeState_Init(_PyRuntimeState *runtime) // Reset to _PyRuntimeState_INIT. memcpy(runtime, &initial, sizeof(*runtime)); } + + if (gilstate_tss_init(runtime) != 0) { + _PyRuntimeState_Fini(runtime); + return _PyStatus_NO_MEMORY(); + } + + if (PyThread_tss_create(&runtime->trashTSSkey) != 0) { + _PyRuntimeState_Fini(runtime); + return _PyStatus_NO_MEMORY(); + } + init_runtime(runtime, open_code_hook, open_code_userdata, audit_hook_head, - unicode_next_index, lock1, lock2, lock3); + unicode_next_index, locks); return _PyStatus_OK(); } @@ -160,6 +496,19 @@ _PyRuntimeState_Init(_PyRuntimeState *runtime) void _PyRuntimeState_Fini(_PyRuntimeState *runtime) { +#ifdef Py_REF_DEBUG + /* The count is cleared by _Py_FinalizeRefTotal(). */ + assert(runtime->object_state.interpreter_leaks == 0); +#endif + + if (gilstate_tss_initialized(runtime)) { + gilstate_tss_fini(runtime); + } + + if (PyThread_tss_is_created(&runtime->trashTSSkey)) { + PyThread_tss_delete(&runtime->trashTSSkey); + } + /* Force the allocator used by _PyRuntimeState_Init(). */ PyMemAllocatorEx old_alloc; _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); @@ -169,9 +518,10 @@ _PyRuntimeState_Fini(_PyRuntimeState *runtime) LOCK = NULL; \ } - FREE_LOCK(runtime->interpreters.mutex); - FREE_LOCK(runtime->xidregistry.mutex); - FREE_LOCK(runtime->unicode_ids.lock); + PyThread_type_lock *lockptrs[NUMLOCKS] = LOCKS_INIT(runtime); + for (int i = 0; i < NUMLOCKS; i++) { + FREE_LOCK(*lockptrs[i]); + } #undef FREE_LOCK PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); @@ -191,36 +541,48 @@ _PyRuntimeState_ReInitThreads(_PyRuntimeState *runtime) PyMemAllocatorEx old_alloc; _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc); - int reinit_interp = _PyThread_at_fork_reinit(&runtime->interpreters.mutex); - int reinit_xidregistry = _PyThread_at_fork_reinit(&runtime->xidregistry.mutex); - int reinit_unicode_ids = _PyThread_at_fork_reinit(&runtime->unicode_ids.lock); + PyThread_type_lock *lockptrs[NUMLOCKS] = LOCKS_INIT(runtime); + int reinit_err = 0; + for (int i = 0; i < NUMLOCKS; i++) { + reinit_err += _PyThread_at_fork_reinit(lockptrs[i]); + } PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); /* bpo-42540: id_mutex is freed by _PyInterpreterState_Delete, which does * not force the default allocator. */ - int reinit_main_id = _PyThread_at_fork_reinit(&runtime->interpreters.main->id_mutex); + reinit_err += _PyThread_at_fork_reinit(&runtime->interpreters.main->id_mutex); - if (reinit_interp < 0 - || reinit_main_id < 0 - || reinit_xidregistry < 0 - || reinit_unicode_ids < 0) - { + if (reinit_err < 0) { return _PyStatus_ERR("Failed to reinitialize runtime locks"); + } + PyStatus status = gilstate_tss_reinit(runtime); + if (_PyStatus_EXCEPTION(status)) { + return status; } + + if (PyThread_tss_is_created(&runtime->trashTSSkey)) { + PyThread_tss_delete(&runtime->trashTSSkey); + } + if (PyThread_tss_create(&runtime->trashTSSkey) != 0) { + return _PyStatus_NO_MEMORY(); + } + return _PyStatus_OK(); } #endif -#define HEAD_LOCK(runtime) \ - PyThread_acquire_lock((runtime)->interpreters.mutex, WAIT_LOCK) -#define HEAD_UNLOCK(runtime) \ - PyThread_release_lock((runtime)->interpreters.mutex) -/* Forward declaration */ -static void _PyGILState_NoteThreadState( - struct _gilstate_runtime_state *gilstate, PyThreadState* tstate); +/*************************************/ +/* the per-interpreter runtime state */ +/*************************************/ + +//---------- +// lifecycle +//---------- + +/* Calling this indicates that the runtime is ready to create interpreters. */ PyStatus _PyInterpreterState_Enable(_PyRuntimeState *runtime) @@ -248,6 +610,7 @@ _PyInterpreterState_Enable(_PyRuntimeState *runtime) return _PyStatus_OK(); } + static PyInterpreterState * alloc_interpreter(void) { @@ -257,7 +620,9 @@ alloc_interpreter(void) static void free_interpreter(PyInterpreterState *interp) { - if (!interp->_static) { + // The main interpreter is statically allocated so + // should not be freed. + if (interp != &_PyRuntime._main_interpreter) { PyMem_RawFree(interp); } } @@ -268,8 +633,19 @@ free_interpreter(PyInterpreterState *interp) e.g. by PyMem_RawCalloc() or memset(), or otherwise pre-initialized. The runtime state is not manipulated. Instead it is assumed that the interpreter is getting added to the runtime. - */ + Note that the main interpreter was statically initialized as part + of the runtime and most state is already set properly. That leaves + a small number of fields to initialize dynamically, as well as some + that are initialized lazily. + + For subinterpreters we memcpy() the main interpreter in + PyInterpreterState_New(), leaving it in the same mostly-initialized + state. The only difference is that the interpreter has some + self-referential state that is statically initializexd to the + main interpreter. We fix those fields here, in addition + to the other dynamically initialized fields. + */ static void init_interpreter(PyInterpreterState *interp, _PyRuntimeState *runtime, int64_t id, @@ -290,11 +666,35 @@ init_interpreter(PyInterpreterState *interp, assert(next != NULL || (interp == runtime->interpreters.main)); interp->next = next; - _PyEval_InitState(&interp->ceval, pending_lock); + /* Initialize obmalloc, but only for subinterpreters, + since the main interpreter is initialized statically. */ + if (interp != &runtime->_main_interpreter) { + poolp temp[OBMALLOC_USED_POOLS_SIZE] = \ + _obmalloc_pools_INIT(interp->obmalloc.pools); + memcpy(&interp->obmalloc.pools.used, temp, sizeof(temp)); + } + _PyObject_InitState(interp); + + _PyEval_InitState(interp, pending_lock); _PyGC_InitState(&interp->gc); PyConfig_InitPythonConfig(&interp->config); _PyType_InitCache(interp); + for (int i = 0; i < _PY_MONITORING_UNGROUPED_EVENTS; i++) { + interp->monitors.tools[i] = 0; + } + for (int t = 0; t < PY_MONITORING_TOOL_IDS; t++) { + for (int e = 0; e < _PY_MONITORING_EVENTS; e++) { + interp->monitoring_callables[t][e] = NULL; + } + } + interp->sys_profile_initialized = false; + interp->sys_trace_initialized = false; + if (interp != &runtime->_main_interpreter) { + /* Fix the self-referential, statically initialized fields. */ + interp->dtoa = (struct _dtoa_state)_dtoa_state_INIT(interp); + } + interp->f_opcode_trace_set = false; interp->_initialized = 1; } @@ -302,7 +702,8 @@ PyInterpreterState * PyInterpreterState_New(void) { PyInterpreterState *interp; - PyThreadState *tstate = _PyThreadState_GET(); + _PyRuntimeState *runtime = &_PyRuntime; + PyThreadState *tstate = current_fast_get(runtime); /* tstate is NULL when Py_InitializeFromConfig() calls PyInterpreterState_New() to create the main interpreter. */ @@ -319,7 +720,6 @@ PyInterpreterState_New(void) } /* Don't get runtime from tstate since tstate can be NULL. */ - _PyRuntimeState *runtime = &_PyRuntime; struct pyinterpreters *interpreters = &runtime->interpreters; /* We completely serialize creation of multiple interpreters, since @@ -341,7 +741,6 @@ PyInterpreterState_New(void) interp = &runtime->_main_interpreter; assert(interp->id == 0); assert(interp->next == NULL); - assert(interp->_static); interpreters->main = interp; } @@ -356,9 +755,6 @@ PyInterpreterState_New(void) // Set to _PyInterpreterState_INIT. memcpy(interp, &initial._main_interpreter, sizeof(*interp)); - // We need to adjust any fields that are different from the initial - // interpreter (as defined in _PyInterpreterState_INIT): - interp->_static = false; if (id < 0) { /* overflow or Py_Initialize() not called yet! */ @@ -390,29 +786,79 @@ error: static void interpreter_clear(PyInterpreterState *interp, PyThreadState *tstate) { + assert(interp != NULL); + assert(tstate != NULL); _PyRuntimeState *runtime = interp->runtime; + /* XXX Conditions we need to enforce: + + * the GIL must be held by the current thread + * tstate must be the "current" thread state (current_fast_get()) + * tstate->interp must be interp + * for the main interpreter, tstate must be the main thread + */ + // XXX Ideally, we would not rely on any thread state in this function + // (and we would drop the "tstate" argument). + if (_PySys_Audit(tstate, "cpython.PyInterpreterState_Clear", NULL) < 0) { _PyErr_Clear(tstate); } + // Clear the current/main thread state last. HEAD_LOCK(runtime); - for (PyThreadState *p = interp->threads.head; p != NULL; p = p->next) { + PyThreadState *p = interp->threads.head; + HEAD_UNLOCK(runtime); + while (p != NULL) { + // See https://github.com/python/cpython/issues/102126 + // Must be called without HEAD_LOCK held as it can deadlock + // if any finalizer tries to acquire that lock. PyThreadState_Clear(p); + HEAD_LOCK(runtime); + p = p->next; + HEAD_UNLOCK(runtime); + } + if (tstate->interp == interp) { + /* We fix tstate->_status below when we for sure aren't using it + (e.g. no longer need the GIL). */ + // XXX Eliminate the need to do this. + tstate->_status.cleared = 0; } - HEAD_UNLOCK(runtime); + + /* It is possible that any of the objects below have a finalizer + that runs Python code or otherwise relies on a thread state + or even the interpreter state. For now we trust that isn't + a problem. + */ + // XXX Make sure we properly deal with problematic finalizers. Py_CLEAR(interp->audit_hooks); + for (int i = 0; i < _PY_MONITORING_UNGROUPED_EVENTS; i++) { + interp->monitors.tools[i] = 0; + } + for (int t = 0; t < PY_MONITORING_TOOL_IDS; t++) { + for (int e = 0; e < _PY_MONITORING_EVENTS; e++) { + Py_CLEAR(interp->monitoring_callables[t][e]); + } + } + interp->sys_profile_initialized = false; + interp->sys_trace_initialized = false; + for (int t = 0; t < PY_MONITORING_TOOL_IDS; t++) { + Py_CLEAR(interp->monitoring_tool_names[t]); + } + PyConfig_Clear(&interp->config); Py_CLEAR(interp->codec_search_path); Py_CLEAR(interp->codec_search_cache); Py_CLEAR(interp->codec_error_registry); - Py_CLEAR(interp->modules); - Py_CLEAR(interp->modules_by_index); + + assert(interp->imports.modules == NULL); + assert(interp->imports.modules_by_index == NULL); + assert(interp->imports.importlib == NULL); + assert(interp->imports.import_func == NULL); + + Py_CLEAR(interp->sysdict_copy); Py_CLEAR(interp->builtins_copy); - Py_CLEAR(interp->importlib); - Py_CLEAR(interp->import_func); Py_CLEAR(interp->dict); #ifdef HAVE_FORK Py_CLEAR(interp->before_forkers); @@ -439,7 +885,32 @@ interpreter_clear(PyInterpreterState *interp, PyThreadState *tstate) PyDict_Clear(interp->builtins); Py_CLEAR(interp->sysdict); Py_CLEAR(interp->builtins); + Py_CLEAR(interp->interpreter_trampoline); + + if (tstate->interp == interp) { + /* We are now safe to fix tstate->_status.cleared. */ + // XXX Do this (much) earlier? + tstate->_status.cleared = 1; + } + + for (int i=0; i < DICT_MAX_WATCHERS; i++) { + interp->dict_state.watchers[i] = NULL; + } + + for (int i=0; i < TYPE_MAX_WATCHERS; i++) { + interp->type_watchers[i] = NULL; + } + + for (int i=0; i < FUNC_MAX_WATCHERS; i++) { + interp->func_watchers[i] = NULL; + } + interp->active_func_watchers = 0; + for (int i=0; i < CODE_MAX_WATCHERS; i++) { + interp->code_watchers[i] = NULL; + } + interp->active_code_watchers = 0; + interp->f_opcode_trace_set = false; // XXX Once we have one allocator per interpreter (i.e. // per-interpreter GC) we must ensure that all of the interpreter's // objects have been cleaned up at the point. @@ -452,8 +923,8 @@ PyInterpreterState_Clear(PyInterpreterState *interp) // Use the current Python thread state to call audit hooks and to collect // garbage. It can be different than the current Python thread state // of 'interp'. - PyThreadState *current_tstate = _PyThreadState_GET(); - + PyThreadState *current_tstate = current_fast_get(interp->runtime); + _PyImport_ClearCore(interp); interpreter_clear(interp, current_tstate); } @@ -461,33 +932,40 @@ PyInterpreterState_Clear(PyInterpreterState *interp) void _PyInterpreterState_Clear(PyThreadState *tstate) { + _PyImport_ClearCore(tstate->interp); interpreter_clear(tstate->interp, tstate); } -static void -zapthreads(PyInterpreterState *interp, int check_current) -{ - PyThreadState *tstate; - /* No need to lock the mutex here because this should only happen - when the threads are all really dead (XXX famous last words). */ - while ((tstate = interp->threads.head) != NULL) { - _PyThreadState_Delete(tstate, check_current); - } -} - +static inline void tstate_deactivate(PyThreadState *tstate); +static void zapthreads(PyInterpreterState *interp); void PyInterpreterState_Delete(PyInterpreterState *interp) { _PyRuntimeState *runtime = interp->runtime; struct pyinterpreters *interpreters = &runtime->interpreters; - zapthreads(interp, 0); + + // XXX Clearing the "current" thread state should happen before + // we start finalizing the interpreter (or the current thread state). + PyThreadState *tcur = current_fast_get(runtime); + if (tcur != NULL && interp == tcur->interp) { + /* Unset current thread. After this, many C API calls become crashy. */ + current_fast_clear(runtime); + tstate_deactivate(tcur); + _PyEval_ReleaseLock(interp, NULL); + } + + zapthreads(interp); _PyEval_FiniState(&interp->ceval); - /* Delete current thread. After this, many C API calls become crashy. */ - _PyThreadState_Swap(&runtime->gilstate, NULL); + // XXX These two calls should be done at the end of clear_interpreter(), + // but currently some objects get decref'ed after that. +#ifdef Py_REF_DEBUG + _PyInterpreterState_FinalizeRefTotal(interp); +#endif + _PyInterpreterState_FinalizeAllocatedBlocks(interp); HEAD_LOCK(runtime); PyInterpreterState **p; @@ -527,10 +1005,9 @@ PyInterpreterState_Delete(PyInterpreterState *interp) PyStatus _PyInterpreterState_DeleteExceptMain(_PyRuntimeState *runtime) { - struct _gilstate_runtime_state *gilstate = &runtime->gilstate; struct pyinterpreters *interpreters = &runtime->interpreters; - PyThreadState *tstate = _PyThreadState_Swap(gilstate, NULL); + PyThreadState *tstate = _PyThreadState_Swap(runtime, NULL); if (tstate != NULL && tstate->interp != interpreters->main) { return _PyStatus_ERR("not main interpreter"); } @@ -546,8 +1023,10 @@ _PyInterpreterState_DeleteExceptMain(_PyRuntimeState *runtime) continue; } + // XXX Won't this fail since PyInterpreterState_Clear() requires + // the "current" tstate to be set? PyInterpreterState_Clear(interp); // XXX must activate? - zapthreads(interp, 1); + zapthreads(interp); if (interp->id_mutex != NULL) { PyThread_free_lock(interp->id_mutex); } @@ -560,24 +1039,15 @@ _PyInterpreterState_DeleteExceptMain(_PyRuntimeState *runtime) if (interpreters->head == NULL) { return _PyStatus_ERR("missing main interpreter"); } - _PyThreadState_Swap(gilstate, tstate); + _PyThreadState_Swap(runtime, tstate); return _PyStatus_OK(); } #endif -PyInterpreterState * -PyInterpreterState_Get(void) -{ - PyThreadState *tstate = _PyThreadState_GET(); - _Py_EnsureTstateNotNULL(tstate); - PyInterpreterState *interp = tstate->interp; - if (interp == NULL) { - Py_FatalError("no current interpreter"); - } - return interp; -} - +//---------- +// accessors +//---------- int64_t PyInterpreterState_GetID(PyInterpreterState *interp) @@ -590,41 +1060,6 @@ PyInterpreterState_GetID(PyInterpreterState *interp) } -static PyInterpreterState * -interp_look_up_id(_PyRuntimeState *runtime, int64_t requested_id) -{ - PyInterpreterState *interp = runtime->interpreters.head; - while (interp != NULL) { - int64_t id = PyInterpreterState_GetID(interp); - if (id < 0) { - return NULL; - } - if (requested_id == id) { - return interp; - } - interp = PyInterpreterState_Next(interp); - } - return NULL; -} - -PyInterpreterState * -_PyInterpreterState_LookUpID(int64_t requested_id) -{ - PyInterpreterState *interp = NULL; - if (requested_id >= 0) { - _PyRuntimeState *runtime = &_PyRuntime; - HEAD_LOCK(runtime); - interp = interp_look_up_id(runtime, requested_id); - HEAD_UNLOCK(runtime); - } - if (interp == NULL && !PyErr_Occurred()) { - PyErr_Format(PyExc_RuntimeError, - "unrecognized interpreter ID %lld", requested_id); - } - return interp; -} - - int _PyInterpreterState_IDInitref(PyInterpreterState *interp) { @@ -660,8 +1095,8 @@ void _PyInterpreterState_IDDecref(PyInterpreterState *interp) { assert(interp->id_mutex != NULL); + _PyRuntimeState *runtime = interp->runtime; - struct _gilstate_runtime_state *gilstate = &_PyRuntime.gilstate; PyThread_acquire_lock(interp->id_mutex, WAIT_LOCK); assert(interp->id_refcount != 0); interp->id_refcount -= 1; @@ -672,9 +1107,9 @@ _PyInterpreterState_IDDecref(PyInterpreterState *interp) // XXX Using the "head" thread isn't strictly correct. PyThreadState *tstate = PyInterpreterState_ThreadHead(interp); // XXX Possible GILState issues? - PyThreadState *save_tstate = _PyThreadState_Swap(gilstate, tstate); + PyThreadState *save_tstate = _PyThreadState_Swap(runtime, tstate); Py_EndInterpreter(tstate); - _PyThreadState_Swap(gilstate, save_tstate); + _PyThreadState_Swap(runtime, save_tstate); } } @@ -693,11 +1128,12 @@ _PyInterpreterState_RequireIDRef(PyInterpreterState *interp, int required) PyObject * _PyInterpreterState_GetMainModule(PyInterpreterState *interp) { - if (interp->modules == NULL) { + PyObject *modules = _PyImport_GetModules(interp); + if (modules == NULL) { PyErr_SetString(PyExc_RuntimeError, "interpreter not initialized"); return NULL; } - return PyMapping_GetItemString(interp->modules, "__main__"); + return PyMapping_GetItemString(modules, "__main__"); } PyObject * @@ -713,6 +1149,88 @@ PyInterpreterState_GetDict(PyInterpreterState *interp) return interp->dict; } + +//----------------------------- +// look up an interpreter state +//----------------------------- + +/* Return the interpreter associated with the current OS thread. + + The GIL must be held. + */ + +PyInterpreterState * +PyInterpreterState_Get(void) +{ + PyThreadState *tstate = current_fast_get(&_PyRuntime); + _Py_EnsureTstateNotNULL(tstate); + PyInterpreterState *interp = tstate->interp; + if (interp == NULL) { + Py_FatalError("no current interpreter"); + } + return interp; +} + + +static PyInterpreterState * +interp_look_up_id(_PyRuntimeState *runtime, int64_t requested_id) +{ + PyInterpreterState *interp = runtime->interpreters.head; + while (interp != NULL) { + int64_t id = PyInterpreterState_GetID(interp); + if (id < 0) { + return NULL; + } + if (requested_id == id) { + return interp; + } + interp = PyInterpreterState_Next(interp); + } + return NULL; +} + +/* Return the interpreter state with the given ID. + + Fail with RuntimeError if the interpreter is not found. */ + +PyInterpreterState * +_PyInterpreterState_LookUpID(int64_t requested_id) +{ + PyInterpreterState *interp = NULL; + if (requested_id >= 0) { + _PyRuntimeState *runtime = &_PyRuntime; + HEAD_LOCK(runtime); + interp = interp_look_up_id(runtime, requested_id); + HEAD_UNLOCK(runtime); + } + if (interp == NULL && !PyErr_Occurred()) { + PyErr_Format(PyExc_RuntimeError, + "unrecognized interpreter ID %lld", requested_id); + } + return interp; +} + + +/********************************/ +/* the per-thread runtime state */ +/********************************/ + +#ifndef NDEBUG +static inline int +tstate_is_alive(PyThreadState *tstate) +{ + return (tstate->_status.initialized && + !tstate->_status.finalized && + !tstate->_status.cleared && + !tstate->_status.finalizing); +} +#endif + + +//---------- +// lifecycle +//---------- + /* Minimum size of data stack chunk */ #define DATA_STACK_CHUNK_SIZE (16*1024) @@ -739,7 +1257,9 @@ alloc_threadstate(void) static void free_threadstate(PyThreadState *tstate) { - if (!tstate->_static) { + // The initial thread state of the interpreter is allocated + // as part of the interpreter state so should not be freed. + if (tstate != &tstate->interp->_initial_thread) { PyMem_RawFree(tstate); } } @@ -754,44 +1274,57 @@ free_threadstate(PyThreadState *tstate) static void init_threadstate(PyThreadState *tstate, - PyInterpreterState *interp, uint64_t id, - PyThreadState *next) + PyInterpreterState *interp, uint64_t id) { - if (tstate->_initialized) { + if (tstate->_status.initialized) { Py_FatalError("thread state already initialized"); } assert(interp != NULL); tstate->interp = interp; + // next/prev are set in add_threadstate(). + assert(tstate->next == NULL); + assert(tstate->prev == NULL); + assert(id > 0); tstate->id = id; - assert(interp->threads.head == tstate); - assert((next != NULL && id != 1) || (next == NULL && id == 1)); - if (next != NULL) { - assert(next->prev == NULL || next->prev == tstate); - next->prev = tstate; - } - tstate->next = next; - assert(tstate->prev == NULL); - - tstate->thread_id = PyThread_get_thread_ident(); -#ifdef PY_HAVE_THREAD_NATIVE_ID - tstate->native_thread_id = PyThread_get_thread_native_id(); -#endif + // thread_id and native_thread_id are set in bind_tstate(). - tstate->recursion_limit = interp->ceval.recursion_limit, - tstate->recursion_remaining = interp->ceval.recursion_limit, + tstate->py_recursion_limit = interp->ceval.recursion_limit, + tstate->py_recursion_remaining = interp->ceval.recursion_limit, + tstate->c_recursion_remaining = C_RECURSION_LIMIT; tstate->exc_info = &tstate->exc_state; + // PyGILState_Release must not try to delete this thread state. + // This is cleared when PyGILState_Ensure() creates the thread state. + tstate->gilstate_counter = 1; + tstate->cframe = &tstate->root_cframe; tstate->datastack_chunk = NULL; tstate->datastack_top = NULL; tstate->datastack_limit = NULL; + tstate->what_event = -1; - tstate->_initialized = 1; + tstate->_status.initialized = 1; +} + +static void +add_threadstate(PyInterpreterState *interp, PyThreadState *tstate, + PyThreadState *next) +{ + assert(interp->threads.head != tstate); + assert((next != NULL && tstate->id != 1) || + (next == NULL && tstate->id == 1)); + if (next != NULL) { + assert(next->prev == NULL || next->prev == tstate); + next->prev = tstate; + } + tstate->next = next; + assert(tstate->prev == NULL); + interp->threads.head = tstate; } static PyThreadState * @@ -821,7 +1354,6 @@ new_threadstate(PyInterpreterState *interp) assert(id == 1); used_newtstate = 0; tstate = &interp->_initial_thread; - assert(tstate->_static); } else { // Every valid interpreter must have at least one thread. @@ -833,13 +1365,10 @@ new_threadstate(PyInterpreterState *interp) memcpy(tstate, &initial._main_interpreter._initial_thread, sizeof(*tstate)); - // We need to adjust any fields that are different from the initial - // thread (as defined in _PyThreadState_INIT): - tstate->_static = false; } - interp->threads.head = tstate; - init_threadstate(tstate, interp, id, old_head); + init_threadstate(tstate, interp, id); + add_threadstate(interp, tstate, old_head); HEAD_UNLOCK(runtime); if (!used_newtstate) { @@ -853,185 +1382,99 @@ PyThreadState * PyThreadState_New(PyInterpreterState *interp) { PyThreadState *tstate = new_threadstate(interp); - _PyThreadState_SetCurrent(tstate); + if (tstate) { + bind_tstate(tstate); + // This makes sure there's a gilstate tstate bound + // as soon as possible. + if (gilstate_tss_get(tstate->interp->runtime) == NULL) { + bind_gilstate_tstate(tstate); + } + } return tstate; } +// This must be followed by a call to _PyThreadState_Bind(); PyThreadState * -_PyThreadState_Prealloc(PyInterpreterState *interp) +_PyThreadState_New(PyInterpreterState *interp) { return new_threadstate(interp); } -// We keep this around for (accidental) stable ABI compatibility. -// Realisically, no extensions are using it. -void -_PyThreadState_Init(PyThreadState *tstate) +// We keep this for stable ABI compabibility. +PyThreadState * +_PyThreadState_Prealloc(PyInterpreterState *interp) { - Py_FatalError("_PyThreadState_Init() is for internal use only"); + return _PyThreadState_New(interp); } +// We keep this around for (accidental) stable ABI compatibility. +// Realistically, no extensions are using it. void -_PyThreadState_SetCurrent(PyThreadState *tstate) -{ - _PyGILState_NoteThreadState(&tstate->interp->runtime->gilstate, tstate); -} - -PyObject* -PyState_FindModule(PyModuleDef* module) -{ - Py_ssize_t index = module->m_base.m_index; - PyInterpreterState *state = _PyInterpreterState_GET(); - PyObject *res; - if (module->m_slots) { - return NULL; - } - if (index == 0) - return NULL; - if (state->modules_by_index == NULL) - return NULL; - if (index >= PyList_GET_SIZE(state->modules_by_index)) - return NULL; - res = PyList_GET_ITEM(state->modules_by_index, index); - return res==Py_None ? NULL : res; -} - -int -_PyState_AddModule(PyThreadState *tstate, PyObject* module, PyModuleDef* def) +_PyThreadState_Init(PyThreadState *tstate) { - if (!def) { - assert(_PyErr_Occurred(tstate)); - return -1; - } - if (def->m_slots) { - _PyErr_SetString(tstate, - PyExc_SystemError, - "PyState_AddModule called on module with slots"); - return -1; - } - - PyInterpreterState *interp = tstate->interp; - if (!interp->modules_by_index) { - interp->modules_by_index = PyList_New(0); - if (!interp->modules_by_index) { - return -1; - } - } - - while (PyList_GET_SIZE(interp->modules_by_index) <= def->m_base.m_index) { - if (PyList_Append(interp->modules_by_index, Py_None) < 0) { - return -1; - } - } - - Py_INCREF(module); - return PyList_SetItem(interp->modules_by_index, - def->m_base.m_index, module); + Py_FatalError("_PyThreadState_Init() is for internal use only"); } -int -PyState_AddModule(PyObject* module, PyModuleDef* def) -{ - if (!def) { - Py_FatalError("module definition is NULL"); - return -1; - } - PyThreadState *tstate = _PyThreadState_GET(); - PyInterpreterState *interp = tstate->interp; - Py_ssize_t index = def->m_base.m_index; - if (interp->modules_by_index && - index < PyList_GET_SIZE(interp->modules_by_index) && - module == PyList_GET_ITEM(interp->modules_by_index, index)) - { - _Py_FatalErrorFormat(__func__, "module %p already added", module); - return -1; - } - return _PyState_AddModule(tstate, module, def); -} - -int -PyState_RemoveModule(PyModuleDef* def) +static void +clear_datastack(PyThreadState *tstate) { - PyThreadState *tstate = _PyThreadState_GET(); - PyInterpreterState *interp = tstate->interp; - - if (def->m_slots) { - _PyErr_SetString(tstate, - PyExc_SystemError, - "PyState_RemoveModule called on module with slots"); - return -1; - } - - Py_ssize_t index = def->m_base.m_index; - if (index == 0) { - Py_FatalError("invalid module index"); - } - if (interp->modules_by_index == NULL) { - Py_FatalError("Interpreters module-list not accessible."); - } - if (index > PyList_GET_SIZE(interp->modules_by_index)) { - Py_FatalError("Module index out of bounds."); + _PyStackChunk *chunk = tstate->datastack_chunk; + tstate->datastack_chunk = NULL; + while (chunk != NULL) { + _PyStackChunk *prev = chunk->previous; + _PyObject_VirtualFree(chunk, chunk->size); + chunk = prev; } - - Py_INCREF(Py_None); - return PyList_SetItem(interp->modules_by_index, index, Py_None); } -// Used by finalize_modules() void -_PyInterpreterState_ClearModules(PyInterpreterState *interp) +PyThreadState_Clear(PyThreadState *tstate) { - if (!interp->modules_by_index) { - return; - } + assert(tstate->_status.initialized && !tstate->_status.cleared); + // XXX assert(!tstate->_status.bound || tstate->_status.unbound); + tstate->_status.finalizing = 1; // just in case - Py_ssize_t i; - for (i = 0; i < PyList_GET_SIZE(interp->modules_by_index); i++) { - PyObject *m = PyList_GET_ITEM(interp->modules_by_index, i); - if (PyModule_Check(m)) { - /* cleanup the saved copy of module dicts */ - PyModuleDef *md = PyModule_GetDef(m); - if (md) { - Py_CLEAR(md->m_base.m_copy); - } - } - } + /* XXX Conditions we need to enforce: - /* Setting modules_by_index to NULL could be dangerous, so we - clear the list instead. */ - if (PyList_SetSlice(interp->modules_by_index, - 0, PyList_GET_SIZE(interp->modules_by_index), - NULL)) { - PyErr_WriteUnraisable(interp->modules_by_index); - } -} + * the GIL must be held by the current thread + * current_fast_get()->interp must match tstate->interp + * for the main interpreter, current_fast_get() must be the main thread + */ -void -PyThreadState_Clear(PyThreadState *tstate) -{ int verbose = _PyInterpreterState_GetConfig(tstate->interp)->verbose; if (verbose && tstate->cframe->current_frame != NULL) { /* bpo-20526: After the main thread calls - _PyRuntimeState_SetFinalizing() in Py_FinalizeEx(), threads must - exit when trying to take the GIL. If a thread exit in the middle of - _PyEval_EvalFrameDefault(), tstate->frame is not reset to its - previous value. It is more likely with daemon threads, but it can - happen with regular threads if threading._shutdown() fails + _PyInterpreterState_SetFinalizing() in Py_FinalizeEx() + (or in Py_EndInterpreter() for subinterpreters), + threads must exit when trying to take the GIL. + If a thread exit in the middle of _PyEval_EvalFrameDefault(), + tstate->frame is not reset to its previous value. + It is more likely with daemon threads, but it can happen + with regular threads if threading._shutdown() fails (ex: interrupted by CTRL+C). */ fprintf(stderr, "PyThreadState_Clear: warning: thread still has a frame\n"); } + /* At this point tstate shouldn't be used any more, + neither to run Python code nor for other uses. + + This is tricky when current_fast_get() == tstate, in the same way + as noted in interpreter_clear() above. The below finalizers + can possibly run Python code or otherwise use the partially + cleared thread state. For now we trust that isn't a problem + in practice. + */ + // XXX Deal with the possibility of problematic finalizers. + /* Don't clear tstate->pyframe: it is a borrowed reference */ Py_CLEAR(tstate->dict); Py_CLEAR(tstate->async_exc); - Py_CLEAR(tstate->curexc_type); - Py_CLEAR(tstate->curexc_value); - Py_CLEAR(tstate->curexc_traceback); + Py_CLEAR(tstate->current_exception); Py_CLEAR(tstate->exc_state.exc_value); @@ -1041,8 +1484,14 @@ PyThreadState_Clear(PyThreadState *tstate) "PyThreadState_Clear: warning: thread still has a generator\n"); } - tstate->c_profilefunc = NULL; - tstate->c_tracefunc = NULL; + if (tstate->c_profilefunc != NULL) { + tstate->interp->sys_profiling_threads--; + tstate->c_profilefunc = NULL; + } + if (tstate->c_tracefunc != NULL) { + tstate->interp->sys_tracing_threads--; + tstate->c_tracefunc = NULL; + } Py_CLEAR(tstate->c_profileobj); Py_CLEAR(tstate->c_traceobj); @@ -1054,15 +1503,19 @@ PyThreadState_Clear(PyThreadState *tstate) if (tstate->on_delete != NULL) { tstate->on_delete(tstate->on_delete_data); } -} + tstate->_status.cleared = 1; + + // XXX Call _PyThreadStateSwap(runtime, NULL) here if "current". + // XXX Do it as early in the function as possible. +} /* Common code for PyThreadState_Delete() and PyThreadState_DeleteCurrent() */ static void -tstate_delete_common(PyThreadState *tstate, - struct _gilstate_runtime_state *gilstate) +tstate_delete_common(PyThreadState *tstate) { - _Py_EnsureTstateNotNULL(tstate); + assert(tstate->_status.cleared && !tstate->_status.finalized); + PyInterpreterState *interp = tstate->interp; if (interp == NULL) { Py_FatalError("NULL interpreter"); @@ -1081,38 +1534,40 @@ tstate_delete_common(PyThreadState *tstate, } HEAD_UNLOCK(runtime); - if (gilstate->autoInterpreterState && - PyThread_tss_get(&gilstate->autoTSSkey) == tstate) - { - PyThread_tss_set(&gilstate->autoTSSkey, NULL); - } - _PyStackChunk *chunk = tstate->datastack_chunk; - tstate->datastack_chunk = NULL; - while (chunk != NULL) { - _PyStackChunk *prev = chunk->previous; - _PyObject_VirtualFree(chunk, chunk->size); - chunk = prev; + // XXX Unbind in PyThreadState_Clear(), or earlier + // (and assert not-equal here)? + if (tstate->_status.bound_gilstate) { + unbind_gilstate_tstate(tstate); } + unbind_tstate(tstate); + + // XXX Move to PyThreadState_Clear()? + clear_datastack(tstate); + + tstate->_status.finalized = 1; } static void -_PyThreadState_Delete(PyThreadState *tstate, int check_current) +zapthreads(PyInterpreterState *interp) { - struct _gilstate_runtime_state *gilstate = &tstate->interp->runtime->gilstate; - if (check_current) { - if (tstate == _PyRuntimeGILState_GetThreadState(gilstate)) { - _Py_FatalErrorFormat(__func__, "tstate %p is still current", tstate); - } + PyThreadState *tstate; + /* No need to lock the mutex here because this should only happen + when the threads are all really dead (XXX famous last words). */ + while ((tstate = interp->threads.head) != NULL) { + tstate_verify_not_active(tstate); + tstate_delete_common(tstate); + free_threadstate(tstate); } - tstate_delete_common(tstate, gilstate); - free_threadstate(tstate); } void PyThreadState_Delete(PyThreadState *tstate) { - _PyThreadState_Delete(tstate, 1); + _Py_EnsureTstateNotNULL(tstate); + tstate_verify_not_active(tstate); + tstate_delete_common(tstate); + free_threadstate(tstate); } @@ -1120,18 +1575,16 @@ void _PyThreadState_DeleteCurrent(PyThreadState *tstate) { _Py_EnsureTstateNotNULL(tstate); - struct _gilstate_runtime_state *gilstate = &tstate->interp->runtime->gilstate; - tstate_delete_common(tstate, gilstate); - _PyRuntimeGILState_SetThreadState(gilstate, NULL); - _PyEval_ReleaseLock(tstate); + tstate_delete_common(tstate); + current_fast_clear(tstate->interp->runtime); + _PyEval_ReleaseLock(tstate->interp, NULL); free_threadstate(tstate); } void PyThreadState_DeleteCurrent(void) { - struct _gilstate_runtime_state *gilstate = &_PyRuntime.gilstate; - PyThreadState *tstate = _PyRuntimeGILState_GetThreadState(gilstate); + PyThreadState *tstate = current_fast_get(&_PyRuntime); _PyThreadState_DeleteCurrent(tstate); } @@ -1144,9 +1597,11 @@ PyThreadState_DeleteCurrent(void) * be kept in those other interpreters. */ void -_PyThreadState_DeleteExcept(_PyRuntimeState *runtime, PyThreadState *tstate) +_PyThreadState_DeleteExcept(PyThreadState *tstate) { + assert(tstate != NULL); PyInterpreterState *interp = tstate->interp; + _PyRuntimeState *runtime = interp->runtime; HEAD_LOCK(runtime); /* Remove all thread states, except tstate, from the linked list of @@ -1178,52 +1633,9 @@ _PyThreadState_DeleteExcept(_PyRuntimeState *runtime, PyThreadState *tstate) } -PyThreadState * -_PyThreadState_UncheckedGet(void) -{ - return _PyThreadState_GET(); -} - - -PyThreadState * -PyThreadState_Get(void) -{ - PyThreadState *tstate = _PyThreadState_GET(); - _Py_EnsureTstateNotNULL(tstate); - return tstate; -} - - -PyThreadState * -_PyThreadState_Swap(struct _gilstate_runtime_state *gilstate, PyThreadState *newts) -{ - PyThreadState *oldts = _PyRuntimeGILState_GetThreadState(gilstate); - - _PyRuntimeGILState_SetThreadState(gilstate, newts); - /* It should not be possible for more than one thread state - to be used for a thread. Check this the best we can in debug - builds. - */ -#if defined(Py_DEBUG) - if (newts) { - /* This can be called from PyEval_RestoreThread(). Similar - to it, we need to ensure errno doesn't change. - */ - int err = errno; - PyThreadState *check = _PyGILState_GetThisThreadState(gilstate); - if (check && check->interp == newts->interp && check != newts) - Py_FatalError("Invalid thread state for this thread"); - errno = err; - } -#endif - return oldts; -} - -PyThreadState * -PyThreadState_Swap(PyThreadState *newts) -{ - return _PyThreadState_Swap(&_PyRuntime.gilstate, newts); -} +//---------- +// accessors +//---------- /* An extension mechanism to store arbitrary additional per-thread state. PyThreadState_GetDict() returns a dictionary that can be used to hold such @@ -1248,7 +1660,7 @@ _PyThreadState_GetDict(PyThreadState *tstate) PyObject * PyThreadState_GetDict(void) { - PyThreadState *tstate = _PyThreadState_GET(); + PyThreadState *tstate = current_fast_get(&_PyRuntime); if (tstate == NULL) { return NULL; } @@ -1268,10 +1680,7 @@ PyFrameObject* PyThreadState_GetFrame(PyThreadState *tstate) { assert(tstate != NULL); - _PyInterpreterFrame *f = tstate->cframe->current_frame; - while (f && _PyFrame_IsIncomplete(f)) { - f = f->previous; - } + _PyInterpreterFrame *f = _PyThreadState_GetFrame(tstate); if (f == NULL) { return NULL; } @@ -1279,8 +1688,7 @@ PyThreadState_GetFrame(PyThreadState *tstate) if (frame == NULL) { PyErr_Clear(); } - Py_XINCREF(frame); - return frame; + return (PyFrameObject*)Py_XNewRef(frame); } @@ -1292,6 +1700,42 @@ PyThreadState_GetID(PyThreadState *tstate) } +static inline void +tstate_activate(PyThreadState *tstate) +{ + assert(tstate != NULL); + // XXX assert(tstate_is_alive(tstate)); + assert(tstate_is_bound(tstate)); + assert(!tstate->_status.active); + + assert(!tstate->_status.bound_gilstate || + tstate == gilstate_tss_get((tstate->interp->runtime))); + if (!tstate->_status.bound_gilstate) { + bind_gilstate_tstate(tstate); + } + + tstate->_status.active = 1; +} + +static inline void +tstate_deactivate(PyThreadState *tstate) +{ + assert(tstate != NULL); + // XXX assert(tstate_is_alive(tstate)); + assert(tstate_is_bound(tstate)); + assert(tstate->_status.active); + + tstate->_status.active = 0; + + // We do not unbind the gilstate tstate here. + // It will still be used in PyGILState_Ensure(). +} + + +//---------- +// other API +//---------- + /* Asynchronously raise an exception in a thread. Requested by Just van Rossum and Alex Martelli. To prevent naive misuse, you must write your own extension @@ -1300,11 +1744,13 @@ PyThreadState_GetID(PyThreadState *tstate) match any known thread id). Can be called with exc=NULL to clear an existing async exception. This raises no exceptions. */ +// XXX Move this to Python/ceval_gil.c? +// XXX Deprecate this. int PyThreadState_SetAsyncExc(unsigned long id, PyObject *exc) { _PyRuntimeState *runtime = &_PyRuntime; - PyInterpreterState *interp = _PyRuntimeState_GetThreadState(runtime)->interp; + PyInterpreterState *interp = _PyInterpreterState_GET(); /* Although the GIL is held, a few C API functions can be called * without the GIL held, and in particular some that create and @@ -1318,28 +1764,124 @@ PyThreadState_SetAsyncExc(unsigned long id, PyObject *exc) continue; } - /* Tricky: we need to decref the current value - * (if any) in tstate->async_exc, but that can in turn - * allow arbitrary Python code to run, including - * perhaps calls to this function. To prevent - * deadlock, we need to release head_mutex before - * the decref. - */ - PyObject *old_exc = tstate->async_exc; - Py_XINCREF(exc); - tstate->async_exc = exc; - HEAD_UNLOCK(runtime); + /* Tricky: we need to decref the current value + * (if any) in tstate->async_exc, but that can in turn + * allow arbitrary Python code to run, including + * perhaps calls to this function. To prevent + * deadlock, we need to release head_mutex before + * the decref. + */ + PyObject *old_exc = tstate->async_exc; + tstate->async_exc = Py_XNewRef(exc); + HEAD_UNLOCK(runtime); + + Py_XDECREF(old_exc); + _PyEval_SignalAsyncExc(tstate->interp); + return 1; + } + HEAD_UNLOCK(runtime); + return 0; +} + + +//--------------------------------- +// API for the current thread state +//--------------------------------- + +PyThreadState * +_PyThreadState_UncheckedGet(void) +{ + return current_fast_get(&_PyRuntime); +} + + +PyThreadState * +PyThreadState_Get(void) +{ + PyThreadState *tstate = current_fast_get(&_PyRuntime); + _Py_EnsureTstateNotNULL(tstate); + return tstate; +} + + +static void +_swap_thread_states(_PyRuntimeState *runtime, + PyThreadState *oldts, PyThreadState *newts) +{ + // XXX Do this only if oldts != NULL? + current_fast_clear(runtime); + + if (oldts != NULL) { + // XXX assert(tstate_is_alive(oldts) && tstate_is_bound(oldts)); + tstate_deactivate(oldts); + } + + if (newts != NULL) { + // XXX assert(tstate_is_alive(newts)); + assert(tstate_is_bound(newts)); + current_fast_set(runtime, newts); + tstate_activate(newts); + } +} + +PyThreadState * +_PyThreadState_SwapNoGIL(PyThreadState *newts) +{ +#if defined(Py_DEBUG) + /* This can be called from PyEval_RestoreThread(). Similar + to it, we need to ensure errno doesn't change. + */ + int err = errno; +#endif + + PyThreadState *oldts = current_fast_get(&_PyRuntime); + _swap_thread_states(&_PyRuntime, oldts, newts); + +#if defined(Py_DEBUG) + errno = err; +#endif + return oldts; +} + +PyThreadState * +_PyThreadState_Swap(_PyRuntimeState *runtime, PyThreadState *newts) +{ + PyThreadState *oldts = current_fast_get(runtime); + if (oldts != NULL) { + _PyEval_ReleaseLock(oldts->interp, oldts); + } + _swap_thread_states(runtime, oldts, newts); + if (newts != NULL) { + _PyEval_AcquireLock(newts); + } + return oldts; +} + +PyThreadState * +PyThreadState_Swap(PyThreadState *newts) +{ + return _PyThreadState_Swap(&_PyRuntime, newts); +} + - Py_XDECREF(old_exc); - _PyEval_SignalAsyncExc(tstate->interp); - return 1; +void +_PyThreadState_Bind(PyThreadState *tstate) +{ + bind_tstate(tstate); + // This makes sure there's a gilstate tstate bound + // as soon as possible. + if (gilstate_tss_get(tstate->interp->runtime) == NULL) { + bind_gilstate_tstate(tstate); } - HEAD_UNLOCK(runtime); - return 0; } -/* Routines for advanced debuggers, requested by David Beazley. - Don't use unless you know what you are doing! */ + +/***********************************/ +/* routines for advanced debuggers */ +/***********************************/ + +// (requested by David Beazley) +// Don't use unless you know what you are doing! PyInterpreterState * PyInterpreterState_Head(void) @@ -1368,6 +1910,11 @@ PyThreadState_Next(PyThreadState *tstate) { return tstate->next; } + +/********************************************/ +/* reporting execution state of all threads */ +/********************************************/ + /* The implementation of sys._current_frames(). This is intended to be called with the GIL held, as it will be when called via sys._current_frames(). It's possible it would work fine even without @@ -1376,7 +1923,8 @@ PyThreadState_Next(PyThreadState *tstate) { PyObject * _PyThread_CurrentFrames(void) { - PyThreadState *tstate = _PyThreadState_GET(); + _PyRuntimeState *runtime = &_PyRuntime; + PyThreadState *tstate = current_fast_get(runtime); if (_PySys_Audit(tstate, "sys._current_frames", NULL) < 0) { return NULL; } @@ -1392,16 +1940,13 @@ _PyThread_CurrentFrames(void) * Because these lists can mutate even when the GIL is held, we * need to grab head_mutex for the duration. */ - _PyRuntimeState *runtime = tstate->interp->runtime; HEAD_LOCK(runtime); PyInterpreterState *i; for (i = runtime->interpreters.head; i != NULL; i = i->next) { PyThreadState *t; for (t = i->threads.head; t != NULL; t = t->next) { _PyInterpreterFrame *frame = t->cframe->current_frame; - while (frame && _PyFrame_IsIncomplete(frame)) { - frame = frame->previous; - } + frame = _PyFrame_GetFirstComplete(frame); if (frame == NULL) { continue; } @@ -1431,10 +1976,16 @@ done: return result; } +/* The implementation of sys._current_exceptions(). This is intended to be + called with the GIL held, as it will be when called via + sys._current_exceptions(). It's possible it would work fine even without + the GIL held, but haven't thought enough about that. +*/ PyObject * _PyThread_CurrentExceptions(void) { - PyThreadState *tstate = _PyThreadState_GET(); + _PyRuntimeState *runtime = &_PyRuntime; + PyThreadState *tstate = current_fast_get(runtime); _Py_EnsureTstateNotNULL(tstate); @@ -1453,7 +2004,6 @@ _PyThread_CurrentExceptions(void) * Because these lists can mutate even when the GIL is held, we * need to grab head_mutex for the duration. */ - _PyRuntimeState *runtime = tstate->interp->runtime; HEAD_LOCK(runtime); PyInterpreterState *i; for (i = runtime->interpreters.head; i != NULL; i = i->next) { @@ -1467,14 +2017,13 @@ _PyThread_CurrentExceptions(void) if (id == NULL) { goto fail; } - PyObject *exc_info = _PyErr_StackItemToExcInfoTuple(err_info); - if (exc_info == NULL) { - Py_DECREF(id); - goto fail; - } - int stat = PyDict_SetItem(result, id, exc_info); + PyObject *exc = err_info->exc_value; + assert(exc == NULL || + exc == Py_None || + PyExceptionInstance_Check(exc)); + + int stat = PyDict_SetItem(result, id, exc == NULL ? Py_None : exc); Py_DECREF(id); - Py_DECREF(exc_info); if (stat < 0) { goto fail; } @@ -1490,62 +2039,63 @@ done: return result; } -/* Python "auto thread state" API. */ -/* Keep this as a static, as it is not reliable! It can only - ever be compared to the state for the *current* thread. - * If not equal, then it doesn't matter that the actual - value may change immediately after comparison, as it can't - possibly change to the current thread's state. - * If equal, then the current thread holds the lock, so the value can't - change until we yield the lock. -*/ -static int -PyThreadState_IsCurrent(PyThreadState *tstate) -{ - /* Must be the tstate for this thread */ - struct _gilstate_runtime_state *gilstate = &_PyRuntime.gilstate; - assert(_PyGILState_GetThisThreadState(gilstate) == tstate); - return tstate == _PyRuntimeGILState_GetThreadState(gilstate); -} +/***********************************/ +/* Python "auto thread state" API. */ +/***********************************/ /* Internal initialization/finalization functions called by Py_Initialize/Py_FinalizeEx */ PyStatus -_PyGILState_Init(_PyRuntimeState *runtime) +_PyGILState_Init(PyInterpreterState *interp) { - struct _gilstate_runtime_state *gilstate = &runtime->gilstate; - if (PyThread_tss_create(&gilstate->autoTSSkey) != 0) { - return _PyStatus_NO_MEMORY(); + if (!_Py_IsMainInterpreter(interp)) { + /* Currently, PyGILState is shared by all interpreters. The main + * interpreter is responsible to initialize it. */ + return _PyStatus_OK(); } - // PyThreadState_New() calls _PyGILState_NoteThreadState() which does - // nothing before autoInterpreterState is set. - assert(gilstate->autoInterpreterState == NULL); + _PyRuntimeState *runtime = interp->runtime; + assert(gilstate_tss_get(runtime) == NULL); + assert(runtime->gilstate.autoInterpreterState == NULL); + runtime->gilstate.autoInterpreterState = interp; return _PyStatus_OK(); } +void +_PyGILState_Fini(PyInterpreterState *interp) +{ + if (!_Py_IsMainInterpreter(interp)) { + /* Currently, PyGILState is shared by all interpreters. The main + * interpreter is responsible to initialize it. */ + return; + } + interp->runtime->gilstate.autoInterpreterState = NULL; +} + +// XXX Drop this. PyStatus _PyGILState_SetTstate(PyThreadState *tstate) { + /* must init with valid states */ + assert(tstate != NULL); + assert(tstate->interp != NULL); + if (!_Py_IsMainInterpreter(tstate->interp)) { /* Currently, PyGILState is shared by all interpreters. The main * interpreter is responsible to initialize it. */ return _PyStatus_OK(); } - /* must init with valid states */ - assert(tstate != NULL); - assert(tstate->interp != NULL); - - struct _gilstate_runtime_state *gilstate = &tstate->interp->runtime->gilstate; +#ifndef NDEBUG + _PyRuntimeState *runtime = tstate->interp->runtime; - gilstate->autoInterpreterState = tstate->interp; - assert(PyThread_tss_get(&gilstate->autoTSSkey) == NULL); - assert(tstate->gilstate_counter == 0); + assert(runtime->gilstate.autoInterpreterState == tstate->interp); + assert(gilstate_tss_get(runtime) == tstate); + assert(tstate->gilstate_counter == 1); +#endif - _PyGILState_NoteThreadState(gilstate, tstate); return _PyStatus_OK(); } @@ -1555,118 +2105,42 @@ _PyGILState_GetInterpreterStateUnsafe(void) return _PyRuntime.gilstate.autoInterpreterState; } -void -_PyGILState_Fini(PyInterpreterState *interp) -{ - struct _gilstate_runtime_state *gilstate = &interp->runtime->gilstate; - PyThread_tss_delete(&gilstate->autoTSSkey); - gilstate->autoInterpreterState = NULL; -} - -#ifdef HAVE_FORK -/* Reset the TSS key - called by PyOS_AfterFork_Child(). - * This should not be necessary, but some - buggy - pthread implementations - * don't reset TSS upon fork(), see issue #10517. - */ -PyStatus -_PyGILState_Reinit(_PyRuntimeState *runtime) -{ - struct _gilstate_runtime_state *gilstate = &runtime->gilstate; - PyThreadState *tstate = _PyGILState_GetThisThreadState(gilstate); - - PyThread_tss_delete(&gilstate->autoTSSkey); - if (PyThread_tss_create(&gilstate->autoTSSkey) != 0) { - return _PyStatus_NO_MEMORY(); - } - - /* If the thread had an associated auto thread state, reassociate it with - * the new key. */ - if (tstate && - PyThread_tss_set(&gilstate->autoTSSkey, (void *)tstate) != 0) - { - return _PyStatus_ERR("failed to set autoTSSkey"); - } - return _PyStatus_OK(); -} -#endif - -/* When a thread state is created for a thread by some mechanism other than - PyGILState_Ensure, it's important that the GILState machinery knows about - it so it doesn't try to create another thread state for the thread (this is - a better fix for SF bug #1010677 than the first one attempted). -*/ -static void -_PyGILState_NoteThreadState(struct _gilstate_runtime_state *gilstate, PyThreadState* tstate) -{ - /* If autoTSSkey isn't initialized, this must be the very first - threadstate created in Py_Initialize(). Don't do anything for now - (we'll be back here when _PyGILState_Init is called). */ - if (!gilstate->autoInterpreterState) { - return; - } - - /* Stick the thread state for this thread in thread specific storage. - - The only situation where you can legitimately have more than one - thread state for an OS level thread is when there are multiple - interpreters. - - You shouldn't really be using the PyGILState_ APIs anyway (see issues - #10915 and #15751). - - The first thread state created for that given OS level thread will - "win", which seems reasonable behaviour. - */ - if (PyThread_tss_get(&gilstate->autoTSSkey) == NULL) { - if ((PyThread_tss_set(&gilstate->autoTSSkey, (void *)tstate)) != 0) { - Py_FatalError("Couldn't create autoTSSkey mapping"); - } - } - - /* PyGILState_Release must not try to delete this thread state. */ - tstate->gilstate_counter = 1; -} - /* The public functions */ -static PyThreadState * -_PyGILState_GetThisThreadState(struct _gilstate_runtime_state *gilstate) -{ - if (gilstate->autoInterpreterState == NULL) - return NULL; - return (PyThreadState *)PyThread_tss_get(&gilstate->autoTSSkey); -} PyThreadState * PyGILState_GetThisThreadState(void) { - return _PyGILState_GetThisThreadState(&_PyRuntime.gilstate); + _PyRuntimeState *runtime = &_PyRuntime; + if (!gilstate_tss_initialized(runtime)) { + return NULL; + } + return gilstate_tss_get(runtime); } int PyGILState_Check(void) { - struct _gilstate_runtime_state *gilstate = &_PyRuntime.gilstate; - if (!gilstate->check_enabled) { + _PyRuntimeState *runtime = &_PyRuntime; + if (!runtime->gilstate.check_enabled) { return 1; } - if (!PyThread_tss_is_created(&gilstate->autoTSSkey)) { + if (!gilstate_tss_initialized(runtime)) { return 1; } - PyThreadState *tstate = _PyRuntimeGILState_GetThreadState(gilstate); + PyThreadState *tstate = current_fast_get(runtime); if (tstate == NULL) { return 0; } - return (tstate == _PyGILState_GetThisThreadState(gilstate)); + return (tstate == gilstate_tss_get(runtime)); } PyGILState_STATE PyGILState_Ensure(void) { _PyRuntimeState *runtime = &_PyRuntime; - struct _gilstate_runtime_state *gilstate = &runtime->gilstate; /* Note that we do not auto-init Python here - apart from potential races with 2 threads auto-initializing, pep-311 @@ -1675,28 +2149,32 @@ PyGILState_Ensure(void) /* Ensure that _PyEval_InitThreads() and _PyGILState_Init() have been called by Py_Initialize() */ - assert(_PyEval_ThreadsInitialized(runtime)); - assert(gilstate->autoInterpreterState); + assert(_PyEval_ThreadsInitialized()); + assert(gilstate_tss_initialized(runtime)); + assert(runtime->gilstate.autoInterpreterState != NULL); - PyThreadState *tcur = (PyThreadState *)PyThread_tss_get(&gilstate->autoTSSkey); - int current; + PyThreadState *tcur = gilstate_tss_get(runtime); + int has_gil; if (tcur == NULL) { /* Create a new Python thread state for this thread */ - tcur = PyThreadState_New(gilstate->autoInterpreterState); + tcur = new_threadstate(runtime->gilstate.autoInterpreterState); if (tcur == NULL) { Py_FatalError("Couldn't create thread-state for new thread"); } + bind_tstate(tcur); + bind_gilstate_tstate(tcur); /* This is our thread state! We'll need to delete it in the matching call to PyGILState_Release(). */ + assert(tcur->gilstate_counter == 1); tcur->gilstate_counter = 0; - current = 0; /* new thread state is never current */ + has_gil = 0; /* new thread state is never current */ } else { - current = PyThreadState_IsCurrent(tcur); + has_gil = holds_gil(tcur); } - if (current == 0) { + if (!has_gil) { PyEval_RestoreThread(tcur); } @@ -1707,14 +2185,14 @@ PyGILState_Ensure(void) */ ++tcur->gilstate_counter; - return current ? PyGILState_LOCKED : PyGILState_UNLOCKED; + return has_gil ? PyGILState_LOCKED : PyGILState_UNLOCKED; } void PyGILState_Release(PyGILState_STATE oldstate) { _PyRuntimeState *runtime = &_PyRuntime; - PyThreadState *tstate = PyThread_tss_get(&runtime->gilstate.autoTSSkey); + PyThreadState *tstate = gilstate_tss_get(runtime); if (tstate == NULL) { Py_FatalError("auto-releasing thread-state, " "but no thread-state for this thread"); @@ -1725,12 +2203,12 @@ PyGILState_Release(PyGILState_STATE oldstate) but while this is very new (April 2003), the extra check by release-only users can't hurt. */ - if (!PyThreadState_IsCurrent(tstate)) { + if (!holds_gil(tstate)) { _Py_FatalErrorFormat(__func__, "thread state %p must be current when releasing", tstate); } - assert(PyThreadState_IsCurrent(tstate)); + assert(holds_gil(tstate)); --tstate->gilstate_counter; assert(tstate->gilstate_counter >= 0); /* illegal counter value */ @@ -1740,18 +2218,20 @@ PyGILState_Release(PyGILState_STATE oldstate) if (tstate->gilstate_counter == 0) { /* can't have been locked when we created it */ assert(oldstate == PyGILState_UNLOCKED); + // XXX Unbind tstate here. PyThreadState_Clear(tstate); /* Delete the thread-state. Note this releases the GIL too! * It's vital that the GIL be held here, to avoid shutdown * races; see bugs 225673 and 1061968 (that nasty bug has a * habit of coming back). */ - assert(_PyRuntimeGILState_GetThreadState(&runtime->gilstate) == tstate); + assert(current_fast_get(runtime) == tstate); _PyThreadState_DeleteCurrent(tstate); } /* Release the lock if necessary */ - else if (oldstate == PyGILState_UNLOCKED) + else if (oldstate == PyGILState_UNLOCKED) { PyEval_SaveThread(); + } } @@ -1761,30 +2241,78 @@ PyGILState_Release(PyGILState_STATE oldstate) /* cross-interpreter data */ -crossinterpdatafunc _PyCrossInterpreterData_Lookup(PyObject *); +static inline void +_xidata_init(_PyCrossInterpreterData *data) +{ + // If the value is being reused + // then _xidata_clear() should have been called already. + assert(data->data == NULL); + assert(data->obj == NULL); + *data = (_PyCrossInterpreterData){0}; + data->interp = -1; +} -/* This is a separate func from _PyCrossInterpreterData_Lookup in order - to keep the registry code separate. */ -static crossinterpdatafunc -_lookup_getdata(PyObject *obj) +static inline void +_xidata_clear(_PyCrossInterpreterData *data) { - crossinterpdatafunc getdata = _PyCrossInterpreterData_Lookup(obj); - if (getdata == NULL && PyErr_Occurred() == 0) - PyErr_Format(PyExc_ValueError, - "%S does not support cross-interpreter data", obj); - return getdata; + if (data->free != NULL) { + data->free(data->data); + } + data->data = NULL; + Py_CLEAR(data->obj); +} + +void +_PyCrossInterpreterData_Init(_PyCrossInterpreterData *data, + PyInterpreterState *interp, + void *shared, PyObject *obj, + xid_newobjectfunc new_object) +{ + assert(data != NULL); + assert(new_object != NULL); + _xidata_init(data); + data->data = shared; + if (obj != NULL) { + assert(interp != NULL); + // released in _PyCrossInterpreterData_Clear() + data->obj = Py_NewRef(obj); + } + // Ideally every object would know its owning interpreter. + // Until then, we have to rely on the caller to identify it + // (but we don't need it in all cases). + data->interp = (interp != NULL) ? interp->id : -1; + data->new_object = new_object; } int -_PyObject_CheckCrossInterpreterData(PyObject *obj) -{ - crossinterpdatafunc getdata = _lookup_getdata(obj); - if (getdata == NULL) { +_PyCrossInterpreterData_InitWithSize(_PyCrossInterpreterData *data, + PyInterpreterState *interp, + const size_t size, PyObject *obj, + xid_newobjectfunc new_object) +{ + assert(size > 0); + // For now we always free the shared data in the same interpreter + // where it was allocated, so the interpreter is required. + assert(interp != NULL); + _PyCrossInterpreterData_Init(data, interp, NULL, obj, new_object); + data->data = PyMem_RawMalloc(size); + if (data->data == NULL) { return -1; } + data->free = PyMem_RawFree; return 0; } +void +_PyCrossInterpreterData_Clear(PyInterpreterState *interp, + _PyCrossInterpreterData *data) +{ + assert(data != NULL); + // This must be called in the owning interpreter. + assert(interp == NULL || data->interp == interp->id); + _xidata_clear(data); +} + static int _check_xidata(PyThreadState *tstate, _PyCrossInterpreterData *data) { @@ -1807,10 +2335,35 @@ _check_xidata(PyThreadState *tstate, _PyCrossInterpreterData *data) return 0; } +crossinterpdatafunc _PyCrossInterpreterData_Lookup(PyObject *); + +/* This is a separate func from _PyCrossInterpreterData_Lookup in order + to keep the registry code separate. */ +static crossinterpdatafunc +_lookup_getdata(PyObject *obj) +{ + crossinterpdatafunc getdata = _PyCrossInterpreterData_Lookup(obj); + if (getdata == NULL && PyErr_Occurred() == 0) + PyErr_Format(PyExc_ValueError, + "%S does not support cross-interpreter data", obj); + return getdata; +} + +int +_PyObject_CheckCrossInterpreterData(PyObject *obj) +{ + crossinterpdatafunc getdata = _lookup_getdata(obj); + if (getdata == NULL) { + return -1; + } + return 0; +} + int _PyObject_GetCrossInterpreterData(PyObject *obj, _PyCrossInterpreterData *data) { - PyThreadState *tstate = _PyThreadState_GET(); + _PyRuntimeState *runtime = &_PyRuntime; + PyThreadState *tstate = current_fast_get(runtime); #ifdef Py_DEBUG // The caller must hold the GIL _Py_EnsureTstateNotNULL(tstate); @@ -1819,7 +2372,7 @@ _PyObject_GetCrossInterpreterData(PyObject *obj, _PyCrossInterpreterData *data) // Reset data before re-populating. *data = (_PyCrossInterpreterData){0}; - data->free = PyMem_RawFree; // Set a default that may be overridden. + data->interp = -1; // Call the "getdata" func for the object. Py_INCREF(obj); @@ -1828,7 +2381,7 @@ _PyObject_GetCrossInterpreterData(PyObject *obj, _PyCrossInterpreterData *data) Py_DECREF(obj); return -1; } - int res = getdata(obj, data); + int res = getdata(tstate, obj, data); Py_DECREF(obj); if (res != 0) { return -1; @@ -1837,75 +2390,70 @@ _PyObject_GetCrossInterpreterData(PyObject *obj, _PyCrossInterpreterData *data) // Fill in the blanks and validate the result. data->interp = interp->id; if (_check_xidata(tstate, data) != 0) { - _PyCrossInterpreterData_Release(data); + (void)_PyCrossInterpreterData_Release(data); return -1; } return 0; } -static void -_release_xidata(void *arg) +PyObject * +_PyCrossInterpreterData_NewObject(_PyCrossInterpreterData *data) { - _PyCrossInterpreterData *data = (_PyCrossInterpreterData *)arg; - if (data->free != NULL) { - data->free(data->data); - } - Py_XDECREF(data->obj); + return data->new_object(data); } +typedef void (*releasefunc)(PyInterpreterState *, void *); + static void -_call_in_interpreter(struct _gilstate_runtime_state *gilstate, - PyInterpreterState *interp, - void (*func)(void *), void *arg) +_call_in_interpreter(PyInterpreterState *interp, releasefunc func, void *arg) { /* We would use Py_AddPendingCall() if it weren't specific to the * main interpreter (see bpo-33608). In the meantime we take a * naive approach. */ + _PyRuntimeState *runtime = interp->runtime; PyThreadState *save_tstate = NULL; - if (interp != _PyRuntimeGILState_GetThreadState(gilstate)->interp) { + if (interp != current_fast_get(runtime)->interp) { // XXX Using the "head" thread isn't strictly correct. PyThreadState *tstate = PyInterpreterState_ThreadHead(interp); // XXX Possible GILState issues? - save_tstate = _PyThreadState_Swap(gilstate, tstate); + save_tstate = _PyThreadState_Swap(runtime, tstate); } - func(arg); + // XXX Once the GIL is per-interpreter, this should be called with the + // calling interpreter's GIL released and the target interpreter's held. + func(interp, arg); // Switch back. if (save_tstate != NULL) { - _PyThreadState_Swap(gilstate, save_tstate); + _PyThreadState_Swap(runtime, save_tstate); } } -void +int _PyCrossInterpreterData_Release(_PyCrossInterpreterData *data) { - if (data->data == NULL && data->obj == NULL) { + if (data->free == NULL && data->obj == NULL) { // Nothing to release! - return; + data->data = NULL; + return 0; } // Switch to the original interpreter. PyInterpreterState *interp = _PyInterpreterState_LookUpID(data->interp); if (interp == NULL) { // The interpreter was already destroyed. - if (data->free != NULL) { - // XXX Someone leaked some memory... - } - return; + // This function shouldn't have been called. + // XXX Someone leaked some memory... + assert(PyErr_Occurred()); + return -1; } // "Release" the data and/or the object. - struct _gilstate_runtime_state *gilstate = &_PyRuntime.gilstate; - _call_in_interpreter(gilstate, interp, _release_xidata, data); -} - -PyObject * -_PyCrossInterpreterData_NewObject(_PyCrossInterpreterData *data) -{ - return data->new_object(data); + _call_in_interpreter(interp, + (releasefunc)_PyCrossInterpreterData_Clear, data); + return 0; } /* registry of {type -> crossinterpdatafunc} */ @@ -1915,21 +2463,73 @@ _PyCrossInterpreterData_NewObject(_PyCrossInterpreterData *data) crossinterpdatafunc. It would be simpler and more efficient. */ static int -_register_xidata(struct _xidregistry *xidregistry, PyTypeObject *cls, +_xidregistry_add_type(struct _xidregistry *xidregistry, PyTypeObject *cls, crossinterpdatafunc getdata) { // Note that we effectively replace already registered classes // rather than failing. struct _xidregitem *newhead = PyMem_RawMalloc(sizeof(struct _xidregitem)); - if (newhead == NULL) + if (newhead == NULL) { + return -1; + } + // XXX Assign a callback to clear the entry from the registry? + newhead->cls = PyWeakref_NewRef((PyObject *)cls, NULL); + if (newhead->cls == NULL) { + PyMem_RawFree(newhead); return -1; - newhead->cls = cls; + } newhead->getdata = getdata; + newhead->prev = NULL; newhead->next = xidregistry->head; + if (newhead->next != NULL) { + newhead->next->prev = newhead; + } xidregistry->head = newhead; return 0; } +static struct _xidregitem * +_xidregistry_remove_entry(struct _xidregistry *xidregistry, + struct _xidregitem *entry) +{ + struct _xidregitem *next = entry->next; + if (entry->prev != NULL) { + assert(entry->prev->next == entry); + entry->prev->next = next; + } + else { + assert(xidregistry->head == entry); + xidregistry->head = next; + } + if (next != NULL) { + next->prev = entry->prev; + } + Py_DECREF(entry->cls); + PyMem_RawFree(entry); + return next; +} + +static struct _xidregitem * +_xidregistry_find_type(struct _xidregistry *xidregistry, PyTypeObject *cls) +{ + struct _xidregitem *cur = xidregistry->head; + while (cur != NULL) { + PyObject *registered = PyWeakref_GetObject(cur->cls); + if (registered == Py_None) { + // The weakly ref'ed object was freed. + cur = _xidregistry_remove_entry(xidregistry, cur); + } + else { + assert(PyType_Check(registered)); + if (registered == (PyObject *)cls) { + return cur; + } + cur = cur->next; + } + } + return NULL; +} + static void _register_builtins_for_crossinterpreter_data(struct _xidregistry *xidregistry); int @@ -1945,19 +2545,32 @@ _PyCrossInterpreterData_RegisterClass(PyTypeObject *cls, return -1; } - // Make sure the class isn't ever deallocated. - Py_INCREF((PyObject *)cls); - struct _xidregistry *xidregistry = &_PyRuntime.xidregistry ; PyThread_acquire_lock(xidregistry->mutex, WAIT_LOCK); if (xidregistry->head == NULL) { _register_builtins_for_crossinterpreter_data(xidregistry); } - int res = _register_xidata(xidregistry, cls, getdata); + int res = _xidregistry_add_type(xidregistry, cls, getdata); + PyThread_release_lock(xidregistry->mutex); + return res; +} + +int +_PyCrossInterpreterData_UnregisterClass(PyTypeObject *cls) +{ + int res = 0; + struct _xidregistry *xidregistry = &_PyRuntime.xidregistry ; + PyThread_acquire_lock(xidregistry->mutex, WAIT_LOCK); + struct _xidregitem *matched = _xidregistry_find_type(xidregistry, cls); + if (matched != NULL) { + (void)_xidregistry_remove_entry(xidregistry, matched); + res = 1; + } PyThread_release_lock(xidregistry->mutex); return res; } + /* Cross-interpreter objects are looked up by exact match on the class. We can reassess this policy when we move from a global registry to a tp_* slot. */ @@ -1967,22 +2580,15 @@ _PyCrossInterpreterData_Lookup(PyObject *obj) { struct _xidregistry *xidregistry = &_PyRuntime.xidregistry ; PyObject *cls = PyObject_Type(obj); - crossinterpdatafunc getdata = NULL; PyThread_acquire_lock(xidregistry->mutex, WAIT_LOCK); - struct _xidregitem *cur = xidregistry->head; - if (cur == NULL) { + if (xidregistry->head == NULL) { _register_builtins_for_crossinterpreter_data(xidregistry); - cur = xidregistry->head; - } - for(; cur != NULL; cur = cur->next) { - if (cur->cls == (PyTypeObject *)cls) { - getdata = cur->getdata; - break; - } } + struct _xidregitem *matched = _xidregistry_find_type(xidregistry, + (PyTypeObject *)cls); Py_DECREF(cls); PyThread_release_lock(xidregistry->mutex); - return getdata; + return matched != NULL ? matched->getdata : NULL; } /* cross-interpreter data for builtin types */ @@ -2000,17 +2606,21 @@ _new_bytes_object(_PyCrossInterpreterData *data) } static int -_bytes_shared(PyObject *obj, _PyCrossInterpreterData *data) +_bytes_shared(PyThreadState *tstate, PyObject *obj, + _PyCrossInterpreterData *data) { - struct _shared_bytes_data *shared = PyMem_NEW(struct _shared_bytes_data, 1); + if (_PyCrossInterpreterData_InitWithSize( + data, tstate->interp, sizeof(struct _shared_bytes_data), obj, + _new_bytes_object + ) < 0) + { + return -1; + } + struct _shared_bytes_data *shared = (struct _shared_bytes_data *)data->data; if (PyBytes_AsStringAndSize(obj, &shared->bytes, &shared->len) < 0) { + _PyCrossInterpreterData_Clear(tstate->interp, data); return -1; } - data->data = (void *)shared; - Py_INCREF(obj); - data->obj = obj; // Will be "released" (decref'ed) when data released. - data->new_object = _new_bytes_object; - data->free = PyMem_Free; return 0; } @@ -2028,17 +2638,20 @@ _new_str_object(_PyCrossInterpreterData *data) } static int -_str_shared(PyObject *obj, _PyCrossInterpreterData *data) +_str_shared(PyThreadState *tstate, PyObject *obj, + _PyCrossInterpreterData *data) { - struct _shared_str_data *shared = PyMem_NEW(struct _shared_str_data, 1); + if (_PyCrossInterpreterData_InitWithSize( + data, tstate->interp, sizeof(struct _shared_str_data), obj, + _new_str_object + ) < 0) + { + return -1; + } + struct _shared_str_data *shared = (struct _shared_str_data *)data->data; shared->kind = PyUnicode_KIND(obj); shared->buffer = PyUnicode_DATA(obj); shared->len = PyUnicode_GET_LENGTH(obj); - data->data = (void *)shared; - Py_INCREF(obj); - data->obj = obj; // Will be "released" (decref'ed) when data released. - data->new_object = _new_str_object; - data->free = PyMem_Free; return 0; } @@ -2049,7 +2662,8 @@ _new_long_object(_PyCrossInterpreterData *data) } static int -_long_shared(PyObject *obj, _PyCrossInterpreterData *data) +_long_shared(PyThreadState *tstate, PyObject *obj, + _PyCrossInterpreterData *data) { /* Note that this means the size of shareable ints is bounded by * sys.maxsize. Hence on 32-bit architectures that is half the @@ -2062,10 +2676,9 @@ _long_shared(PyObject *obj, _PyCrossInterpreterData *data) } return -1; } - data->data = (void *)value; - data->obj = NULL; - data->new_object = _new_long_object; - data->free = NULL; + _PyCrossInterpreterData_Init(data, tstate->interp, (void *)value, NULL, + _new_long_object); + // data->obj and data->free remain NULL return 0; } @@ -2073,17 +2686,16 @@ static PyObject * _new_none_object(_PyCrossInterpreterData *data) { // XXX Singleton refcounts are problematic across interpreters... - Py_INCREF(Py_None); - return Py_None; + return Py_NewRef(Py_None); } static int -_none_shared(PyObject *obj, _PyCrossInterpreterData *data) +_none_shared(PyThreadState *tstate, PyObject *obj, + _PyCrossInterpreterData *data) { - data->data = NULL; - // data->obj remains NULL - data->new_object = _new_none_object; - data->free = NULL; // There is nothing to free. + _PyCrossInterpreterData_Init(data, tstate->interp, NULL, NULL, + _new_none_object); + // data->data, data->obj and data->free remain NULL return 0; } @@ -2091,22 +2703,22 @@ static void _register_builtins_for_crossinterpreter_data(struct _xidregistry *xidregistry) { // None - if (_register_xidata(xidregistry, (PyTypeObject *)PyObject_Type(Py_None), _none_shared) != 0) { + if (_xidregistry_add_type(xidregistry, (PyTypeObject *)PyObject_Type(Py_None), _none_shared) != 0) { Py_FatalError("could not register None for cross-interpreter sharing"); } // int - if (_register_xidata(xidregistry, &PyLong_Type, _long_shared) != 0) { + if (_xidregistry_add_type(xidregistry, &PyLong_Type, _long_shared) != 0) { Py_FatalError("could not register int for cross-interpreter sharing"); } // bytes - if (_register_xidata(xidregistry, &PyBytes_Type, _bytes_shared) != 0) { + if (_xidregistry_add_type(xidregistry, &PyBytes_Type, _bytes_shared) != 0) { Py_FatalError("could not register bytes for cross-interpreter sharing"); } // str - if (_register_xidata(xidregistry, &PyUnicode_Type, _str_shared) != 0) { + if (_xidregistry_add_type(xidregistry, &PyUnicode_Type, _str_shared) != 0) { Py_FatalError("could not register str for cross-interpreter sharing"); } } @@ -2159,11 +2771,21 @@ _PyInterpreterState_GetConfigCopy(PyConfig *config) const PyConfig* _Py_GetConfig(void) { + _PyRuntimeState *runtime = &_PyRuntime; assert(PyGILState_Check()); - PyThreadState *tstate = _PyThreadState_GET(); + PyThreadState *tstate = current_fast_get(runtime); + _Py_EnsureTstateNotNULL(tstate); return _PyInterpreterState_GetConfig(tstate->interp); } + +int +_PyInterpreterState_HasFeature(PyInterpreterState *interp, unsigned long feature) +{ + return ((interp->feature_flags & feature) != 0); +} + + #define MINIMUM_OVERHEAD 1000 static PyObject ** @@ -2192,17 +2814,14 @@ push_chunk(PyThreadState *tstate, int size) } _PyInterpreterFrame * -_PyThreadState_BumpFramePointerSlow(PyThreadState *tstate, size_t size) +_PyThreadState_PushFrame(PyThreadState *tstate, size_t size) { - if (_PyThreadState_HasStackSpace(tstate, size)) { + assert(size < INT_MAX/sizeof(PyObject *)); + if (_PyThreadState_HasStackSpace(tstate, (int)size)) { _PyInterpreterFrame *res = (_PyInterpreterFrame *)tstate->datastack_top; tstate->datastack_top += size; return res; } - if (size > INT_MAX/2) { - PyErr_NoMemory(); - return NULL; - } return (_PyInterpreterFrame *)push_chunk(tstate, (int)size); } diff --git a/Python/pystrtod.c b/Python/pystrtod.c index d77b846f..9bb060e3 100644 --- a/Python/pystrtod.c +++ b/Python/pystrtod.c @@ -23,44 +23,6 @@ case_insensitive_match(const char *s, const char *t) return the NaN or Infinity as a double and set *endptr to point just beyond the successfully parsed portion of the string. On failure, return -1.0 and set *endptr to point to the start of the string. */ - -#if _PY_SHORT_FLOAT_REPR == 1 - -double -_Py_parse_inf_or_nan(const char *p, char **endptr) -{ - double retval; - const char *s; - int negate = 0; - - s = p; - if (*s == '-') { - negate = 1; - s++; - } - else if (*s == '+') { - s++; - } - if (case_insensitive_match(s, "inf")) { - s += 3; - if (case_insensitive_match(s, "inity")) - s += 5; - retval = _Py_dg_infinity(negate); - } - else if (case_insensitive_match(s, "nan")) { - s += 3; - retval = _Py_dg_stdnan(negate); - } - else { - s = p; - retval = -1.0; - } - *endptr = (char *)s; - return retval; -} - -#else - double _Py_parse_inf_or_nan(const char *p, char **endptr) { @@ -84,7 +46,7 @@ _Py_parse_inf_or_nan(const char *p, char **endptr) } else if (case_insensitive_match(s, "nan")) { s += 3; - retval = negate ? -Py_NAN : Py_NAN; + retval = negate ? -fabs(Py_NAN) : fabs(Py_NAN); } else { s = p; @@ -94,7 +56,6 @@ _Py_parse_inf_or_nan(const char *p, char **endptr) return retval; } -#endif /** * _PyOS_ascii_strtod: diff --git a/Python/pythonrun.c b/Python/pythonrun.c index f12b9f6e..99e2eec4 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -18,13 +18,12 @@ #include "pycore_interp.h" // PyInterpreterState.importlib #include "pycore_object.h" // _PyDebug_PrintTotalRefs() #include "pycore_parser.h" // _PyParser_ASTFromString() -#include "pycore_pyerrors.h" // _PyErr_Fetch, _Py_Offer_Suggestions +#include "pycore_pyerrors.h" // _PyErr_GetRaisedException, _Py_Offer_Suggestions #include "pycore_pylifecycle.h" // _Py_UnhandledKeyboardInterrupt #include "pycore_pystate.h" // _PyInterpreterState_GET() #include "pycore_sysmodule.h" // _PySys_Audit() #include "pycore_traceback.h" // _PyTraceBack_Print_Indented() -#include "token.h" // INDENT #include "errcode.h" // E_EOF #include "marshal.h" // PyMarshal_ReadLongFromFile() @@ -351,14 +350,8 @@ static int set_main_loader(PyObject *d, PyObject *filename, const char *loader_name) { PyInterpreterState *interp = _PyInterpreterState_GET(); - PyObject *bootstrap = PyObject_GetAttrString(interp->importlib, - "_bootstrap_external"); - if (bootstrap == NULL) { - return -1; - } - - PyObject *loader_type = PyObject_GetAttrString(bootstrap, loader_name); - Py_DECREF(bootstrap); + PyObject *loader_type = _PyImport_GetImportlibExternalLoader(interp, + loader_name); if (loader_type == NULL) { return -1; } @@ -516,8 +509,7 @@ parse_syntax_error(PyObject *err, PyObject **message, PyObject **filename, if (v == Py_None) { Py_DECREF(v); _Py_DECLARE_STR(anon_string, "<string>"); - *filename = &_Py_STR(anon_string); - Py_INCREF(*filename); + *filename = Py_NewRef(&_Py_STR(anon_string)); } else { *filename = v; @@ -706,31 +698,30 @@ _Py_HandleSystemExit(int *exitcode_p) return 0; } - PyObject *exception, *value, *tb; - PyErr_Fetch(&exception, &value, &tb); - fflush(stdout); int exitcode = 0; - if (value == NULL || value == Py_None) { + + PyObject *exc = PyErr_GetRaisedException(); + if (exc == NULL) { goto done; } + assert(PyExceptionInstance_Check(exc)); - if (PyExceptionInstance_Check(value)) { - /* The error code should be in the `code' attribute. */ - PyObject *code = PyObject_GetAttr(value, &_Py_ID(code)); - if (code) { - Py_DECREF(value); - value = code; - if (value == Py_None) - goto done; + /* The error code should be in the `code' attribute. */ + PyObject *code = PyObject_GetAttr(exc, &_Py_ID(code)); + if (code) { + Py_SETREF(exc, code); + if (exc == Py_None) { + goto done; } - /* If we failed to dig out the 'code' attribute, - just let the else clause below print the error. */ } + /* If we failed to dig out the 'code' attribute, + * just let the else clause below print the error. + */ - if (PyLong_Check(value)) { - exitcode = (int)PyLong_AsLong(value); + if (PyLong_Check(exc)) { + exitcode = (int)PyLong_AsLong(exc); } else { PyThreadState *tstate = _PyThreadState_GET(); @@ -741,23 +732,17 @@ _Py_HandleSystemExit(int *exitcode_p) */ PyErr_Clear(); if (sys_stderr != NULL && sys_stderr != Py_None) { - PyFile_WriteObject(value, sys_stderr, Py_PRINT_RAW); + PyFile_WriteObject(exc, sys_stderr, Py_PRINT_RAW); } else { - PyObject_Print(value, stderr, Py_PRINT_RAW); + PyObject_Print(exc, stderr, Py_PRINT_RAW); fflush(stderr); } PySys_WriteStderr("\n"); exitcode = 1; } - done: - /* Restore and clear the exception info, in order to properly decref - * the exception, value, and traceback. If we just exit instead, - * these leak, which confuses PYTHONDUMPREFS output, and may prevent - * some finalizers from running. - */ - PyErr_Restore(exception, value, tb); - PyErr_Clear(); +done: + Py_CLEAR(exc); *exitcode_p = exitcode; return 1; } @@ -776,40 +761,38 @@ handle_system_exit(void) static void _PyErr_PrintEx(PyThreadState *tstate, int set_sys_last_vars) { - PyObject *exception, *v, *tb, *hook; - + PyObject *typ = NULL, *tb = NULL; handle_system_exit(); - _PyErr_Fetch(tstate, &exception, &v, &tb); - if (exception == NULL) { + PyObject *exc = _PyErr_GetRaisedException(tstate); + if (exc == NULL) { goto done; } - - _PyErr_NormalizeException(tstate, &exception, &v, &tb); + assert(PyExceptionInstance_Check(exc)); + typ = Py_NewRef(Py_TYPE(exc)); + tb = PyException_GetTraceback(exc); if (tb == NULL) { - tb = Py_None; - Py_INCREF(tb); - } - PyException_SetTraceback(v, tb); - if (exception == NULL) { - goto done; + tb = Py_NewRef(Py_None); } - /* Now we know v != NULL too */ if (set_sys_last_vars) { - if (_PySys_SetAttr(&_Py_ID(last_type), exception) < 0) { + if (_PySys_SetAttr(&_Py_ID(last_exc), exc) < 0) { + _PyErr_Clear(tstate); + } + /* Legacy version: */ + if (_PySys_SetAttr(&_Py_ID(last_type), typ) < 0) { _PyErr_Clear(tstate); } - if (_PySys_SetAttr(&_Py_ID(last_value), v) < 0) { + if (_PySys_SetAttr(&_Py_ID(last_value), exc) < 0) { _PyErr_Clear(tstate); } if (_PySys_SetAttr(&_Py_ID(last_traceback), tb) < 0) { _PyErr_Clear(tstate); } } - hook = _PySys_GetAttr(tstate, &_Py_ID(excepthook)); + PyObject *hook = _PySys_GetAttr(tstate, &_Py_ID(excepthook)); if (_PySys_Audit(tstate, "sys.excepthook", "OOOO", hook ? hook : Py_None, - exception, v, tb) < 0) { + typ, exc, tb) < 0) { if (PyErr_ExceptionMatches(PyExc_RuntimeError)) { PyErr_Clear(); goto done; @@ -818,48 +801,34 @@ _PyErr_PrintEx(PyThreadState *tstate, int set_sys_last_vars) } if (hook) { PyObject* stack[3]; - PyObject *result; - - stack[0] = exception; - stack[1] = v; + stack[0] = typ; + stack[1] = exc; stack[2] = tb; - result = _PyObject_FastCall(hook, stack, 3); + PyObject *result = _PyObject_FastCall(hook, stack, 3); if (result == NULL) { handle_system_exit(); - PyObject *exception2, *v2, *tb2; - _PyErr_Fetch(tstate, &exception2, &v2, &tb2); - _PyErr_NormalizeException(tstate, &exception2, &v2, &tb2); - /* It should not be possible for exception2 or v2 - to be NULL. However PyErr_Display() can't - tolerate NULLs, so just be safe. */ - if (exception2 == NULL) { - exception2 = Py_None; - Py_INCREF(exception2); - } - if (v2 == NULL) { - v2 = Py_None; - Py_INCREF(v2); - } + PyObject *exc2 = _PyErr_GetRaisedException(tstate); + assert(exc2 && PyExceptionInstance_Check(exc2)); fflush(stdout); PySys_WriteStderr("Error in sys.excepthook:\n"); - PyErr_Display(exception2, v2, tb2); + PyErr_DisplayException(exc2); PySys_WriteStderr("\nOriginal exception was:\n"); - PyErr_Display(exception, v, tb); - Py_DECREF(exception2); - Py_DECREF(v2); - Py_XDECREF(tb2); + PyErr_DisplayException(exc); + Py_DECREF(exc2); + } + else { + Py_DECREF(result); } - Py_XDECREF(result); } else { PySys_WriteStderr("sys.excepthook is missing\n"); - PyErr_Display(exception, v, tb); + PyErr_DisplayException(exc); } done: - Py_XDECREF(exception); - Py_XDECREF(v); + Py_XDECREF(typ); + Py_XDECREF(exc); Py_XDECREF(tb); } @@ -1108,16 +1077,9 @@ print_exception_suggestions(struct exception_print_context *ctx, PyObject *f = ctx->file; PyObject *suggestions = _Py_Offer_Suggestions(value); if (suggestions) { - // Add a trailer ". Did you mean: (...)?" - if (PyFile_WriteString(". Did you mean: '", f) < 0) { - goto error; - } if (PyFile_WriteObject(suggestions, f, Py_PRINT_RAW) < 0) { goto error; } - if (PyFile_WriteString("'?", f) < 0) { - goto error; - } Py_DECREF(suggestions); } else if (PyErr_Occurred()) { @@ -1138,15 +1100,13 @@ print_exception_notes(struct exception_print_context *ctx, PyObject *value) return 0; } - if (!PyObject_HasAttr(value, &_Py_ID(__notes__))) { - return 0; - } - PyObject *notes = PyObject_GetAttr(value, &_Py_ID(__notes__)); - if (notes == NULL) { - return -1; + PyObject *notes; + int res = _PyObject_LookupAttr(value, &_Py_ID(__notes__), ¬es); + if (res <= 0) { + return res; } - if (!PySequence_Check(notes)) { - int res = 0; + if (!PySequence_Check(notes) || PyUnicode_Check(notes) || PyBytes_Check(notes)) { + res = 0; if (write_indented_margin(ctx, f) < 0) { res = -1; } @@ -1160,6 +1120,9 @@ print_exception_notes(struct exception_print_context *ctx, PyObject *value) Py_DECREF(s); } Py_DECREF(notes); + if (PyFile_WriteString("\n", f) < 0) { + res = -1; + } return res; } Py_ssize_t num_notes = PySequence_Length(notes); @@ -1268,8 +1231,7 @@ print_chained(struct exception_print_context* ctx, PyObject *value, const char * message, const char *tag) { PyObject *f = ctx->file; - - if (_Py_EnterRecursiveCall(" in print_chained") < 0) { + if (_Py_EnterRecursiveCall(" in print_chained")) { return -1; } bool need_close = ctx->need_close; @@ -1396,7 +1358,9 @@ print_exception_group(struct exception_print_context *ctx, PyObject *value) if (ctx->exception_group_depth == 0) { ctx->exception_group_depth += 1; } - print_exception(ctx, value); + if (print_exception(ctx, value) < 0) { + return -1; + } PyObject *excs = ((PyBaseExceptionGroupObject *)value)->excs; assert(excs && PyTuple_Check(excs)); @@ -1446,7 +1410,7 @@ print_exception_group(struct exception_print_context *ctx, PyObject *value) PyObject *exc = PyTuple_GET_ITEM(excs, i); if (!truncated) { - if (_Py_EnterRecursiveCall(" in print_exception_group") != 0) { + if (_Py_EnterRecursiveCall(" in print_exception_group")) { return -1; } int res = print_exception_recursive(ctx, exc); @@ -1499,29 +1463,37 @@ print_exception_group(struct exception_print_context *ctx, PyObject *value) static int print_exception_recursive(struct exception_print_context *ctx, PyObject *value) { + if (_Py_EnterRecursiveCall(" in print_exception_recursive")) { + return -1; + } if (ctx->seen != NULL) { /* Exception chaining */ if (print_exception_cause_and_context(ctx, value) < 0) { - return -1; + goto error; } } if (!_PyBaseExceptionGroup_Check(value)) { if (print_exception(ctx, value) < 0) { - return -1; + goto error; } } else if (print_exception_group(ctx, value) < 0) { - return -1; + goto error; } assert(!PyErr_Occurred()); + + _Py_LeaveRecursiveCall(); return 0; +error: + _Py_LeaveRecursiveCall(); + return -1; } #define PyErr_MAX_GROUP_WIDTH 15 #define PyErr_MAX_GROUP_DEPTH 10 void -_PyErr_Display(PyObject *file, PyObject *exception, PyObject *value, PyObject *tb) +_PyErr_Display(PyObject *file, PyObject *unused, PyObject *value, PyObject *tb) { assert(file != NULL && file != Py_None); if (PyExceptionInstance_Check(value) @@ -1529,10 +1501,12 @@ _PyErr_Display(PyObject *file, PyObject *exception, PyObject *value, PyObject *t /* Put the traceback on the exception, otherwise it won't get displayed. See issue #18776. */ PyObject *cur_tb = PyException_GetTraceback(value); - if (cur_tb == NULL) + if (cur_tb == NULL) { PyException_SetTraceback(value, tb); - else + } + else { Py_DECREF(cur_tb); + } } struct exception_print_context ctx; @@ -1568,7 +1542,7 @@ _PyErr_Display(PyObject *file, PyObject *exception, PyObject *value, PyObject *t } void -PyErr_Display(PyObject *exception, PyObject *value, PyObject *tb) +PyErr_Display(PyObject *unused, PyObject *value, PyObject *tb) { PyThreadState *tstate = _PyThreadState_GET(); PyObject *file = _PySys_GetAttr(tstate, &_Py_ID(stderr)); @@ -1581,10 +1555,20 @@ PyErr_Display(PyObject *exception, PyObject *value, PyObject *tb) return; } Py_INCREF(file); - _PyErr_Display(file, exception, value, tb); + _PyErr_Display(file, NULL, value, tb); Py_DECREF(file); } +void _PyErr_DisplayException(PyObject *file, PyObject *exc) +{ + _PyErr_Display(file, NULL, exc, NULL); +} + +void PyErr_DisplayException(PyObject *exc) +{ + PyErr_Display(NULL, exc, NULL); +} + PyObject * PyRun_StringFlags(const char *str, int start, PyObject *globals, PyObject *locals, PyCompilerFlags *flags) @@ -1654,35 +1638,29 @@ PyRun_FileExFlags(FILE *fp, const char *filename, int start, PyObject *globals, } - static void -flush_io(void) +flush_io_stream(PyThreadState *tstate, PyObject *name) { - PyObject *f, *r; - PyObject *type, *value, *traceback; - - /* Save the current exception */ - PyErr_Fetch(&type, &value, &traceback); - - PyThreadState *tstate = _PyThreadState_GET(); - f = _PySys_GetAttr(tstate, &_Py_ID(stderr)); - if (f != NULL) { - r = _PyObject_CallMethodNoArgs(f, &_Py_ID(flush)); - if (r) - Py_DECREF(r); - else - PyErr_Clear(); - } - f = _PySys_GetAttr(tstate, &_Py_ID(stdout)); + PyObject *f = _PySys_GetAttr(tstate, name); if (f != NULL) { - r = _PyObject_CallMethodNoArgs(f, &_Py_ID(flush)); - if (r) + PyObject *r = _PyObject_CallMethodNoArgs(f, &_Py_ID(flush)); + if (r) { Py_DECREF(r); - else + } + else { PyErr_Clear(); + } } +} - PyErr_Restore(type, value, traceback); +static void +flush_io(void) +{ + PyThreadState *tstate = _PyThreadState_GET(); + PyObject *exc = _PyErr_GetRaisedException(tstate); + flush_io_stream(tstate, &_Py_ID(stderr)); + flush_io_stream(tstate, &_Py_ID(stdout)); + _PyErr_SetRaisedException(tstate, exc); } static PyObject * @@ -1699,7 +1677,8 @@ run_eval_code_obj(PyThreadState *tstate, PyCodeObject *co, PyObject *globals, Py * uncaught exception to trigger an unexplained signal exit from a future * Py_Main() based one. */ - _Py_UnhandledKeyboardInterrupt = 0; + // XXX Isn't this dealt with by the move to _PyRuntimeState? + _PyRuntime.signals.unhandled_keyboard_interrupt = 0; /* Set globals['__builtins__'] if it doesn't exist */ if (globals != NULL && _PyDict_GetItemStringWithError(globals, "__builtins__") == NULL) { @@ -1713,7 +1692,7 @@ run_eval_code_obj(PyThreadState *tstate, PyCodeObject *co, PyObject *globals, Py v = PyEval_EvalCode((PyObject*)co, globals, locals); if (!v && _PyErr_Occurred(tstate) == PyExc_KeyboardInterrupt) { - _Py_UnhandledKeyboardInterrupt = 1; + _PyRuntime.signals.unhandled_keyboard_interrupt = 1; } return v; } @@ -1859,7 +1838,7 @@ _Py_SourceAsString(PyObject *cmd, const char *funcname, const char *what, PyComp } if (strlen(str) != (size_t)size) { - PyErr_SetString(PyExc_ValueError, + PyErr_SetString(PyExc_SyntaxError, "source code string cannot contain null bytes"); Py_CLEAR(*cmd_copy); return NULL; diff --git a/Python/pytime.c b/Python/pytime.c index f49a25bf..acd18420 100644 --- a/Python/pytime.c +++ b/Python/pytime.c @@ -1,5 +1,4 @@ #include "Python.h" -#include "pycore_pymath.h" // _Py_InIntegralTypeRange() #ifdef MS_WINDOWS # include <winsock2.h> // struct timeval #endif @@ -41,6 +40,14 @@ # error "unsupported time_t size" #endif +#if PY_TIME_T_MAX + PY_TIME_T_MIN != -1 +# error "time_t is not a two's complement integer type" +#endif + +#if _PyTime_MIN + _PyTime_MAX != -1 +# error "_PyTime_t is not a two's complement integer type" +#endif + static void pytime_time_t_overflow(void) @@ -294,7 +301,21 @@ pytime_double_to_denominator(double d, time_t *sec, long *numerator, } assert(0.0 <= floatpart && floatpart < denominator); - if (!_Py_InIntegralTypeRange(time_t, intpart)) { + /* + Conversion of an out-of-range value to time_t gives undefined behaviour + (C99 §6.3.1.4p1), so we must guard against it. However, checking that + `intpart` is in range is delicate: the obvious expression `intpart <= + PY_TIME_T_MAX` will first convert the value `PY_TIME_T_MAX` to a double, + potentially changing its value and leading to us failing to catch some + UB-inducing values. The code below works correctly under the mild + assumption that time_t is a two's complement integer type with no trap + representation, and that `PY_TIME_T_MIN` is within the representable + range of a C double. + + Note: we want the `if` condition below to be true for NaNs; therefore, + resist any temptation to simplify by applying De Morgan's laws. + */ + if (!((double)PY_TIME_T_MIN <= intpart && intpart < -(double)PY_TIME_T_MIN)) { pytime_time_t_overflow(); return -1; } @@ -349,7 +370,8 @@ _PyTime_ObjectToTime_t(PyObject *obj, time_t *sec, _PyTime_round_t round) d = pytime_round(d, round); (void)modf(d, &intpart); - if (!_Py_InIntegralTypeRange(time_t, intpart)) { + /* See comments in pytime_double_to_denominator */ + if (!((double)PY_TIME_T_MIN <= intpart && intpart < -(double)PY_TIME_T_MIN)) { pytime_time_t_overflow(); return -1; } @@ -406,6 +428,14 @@ _PyTime_FromNanoseconds(_PyTime_t ns) } +_PyTime_t +_PyTime_FromMicrosecondsClamp(_PyTime_t us) +{ + _PyTime_t ns = _PyTime_Mul(us, US_TO_NS); + return pytime_from_nanoseconds(ns); +} + + int _PyTime_FromNanosecondsObject(_PyTime_t *tp, PyObject *obj) { @@ -507,8 +537,9 @@ pytime_from_double(_PyTime_t *tp, double value, _PyTime_round_t round, d *= (double)unit_to_ns; d = pytime_round(d, round); - if (!_Py_InIntegralTypeRange(_PyTime_t, d)) { - pytime_overflow(); + /* See comments in pytime_double_to_denominator */ + if (!((double)_PyTime_MIN <= d && d < -(double)_PyTime_MIN)) { + pytime_time_t_overflow(); return -1; } _PyTime_t ns = (_PyTime_t)d; @@ -902,7 +933,7 @@ py_get_system_clock(_PyTime_t *tp, _Py_clock_info_t *info, int raise_exc) info->monotonic = 0; info->adjustable = 1; if (clock_getres(CLOCK_REALTIME, &res) == 0) { - info->resolution = res.tv_sec + res.tv_nsec * 1e-9; + info->resolution = (double)res.tv_sec + (double)res.tv_nsec * 1e-9; } else { info->resolution = 1e-9; diff --git a/Python/specialize.c b/Python/specialize.c index 08ce2f5c..63b44461 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -8,6 +8,7 @@ #include "pycore_object.h" #include "pycore_opcode.h" // _PyOpcode_Caches #include "structmember.h" // struct PyMemberDef, T_OFFSET_EX +#include "pycore_descrobject.h" #include <stdlib.h> // rand() @@ -15,25 +16,9 @@ * ./adaptive.md */ -/* Map from opcode to adaptive opcode. - Values of zero are ignored. */ -uint8_t _PyOpcode_Adaptive[256] = { - [LOAD_ATTR] = LOAD_ATTR_ADAPTIVE, - [LOAD_GLOBAL] = LOAD_GLOBAL_ADAPTIVE, - [LOAD_METHOD] = LOAD_METHOD_ADAPTIVE, - [BINARY_SUBSCR] = BINARY_SUBSCR_ADAPTIVE, - [STORE_SUBSCR] = STORE_SUBSCR_ADAPTIVE, - [CALL] = CALL_ADAPTIVE, - [PRECALL] = PRECALL_ADAPTIVE, - [STORE_ATTR] = STORE_ATTR_ADAPTIVE, - [BINARY_OP] = BINARY_OP_ADAPTIVE, - [COMPARE_OP] = COMPARE_OP_ADAPTIVE, - [UNPACK_SEQUENCE] = UNPACK_SEQUENCE_ADAPTIVE, -}; - -Py_ssize_t _Py_QuickenedCount = 0; #ifdef Py_STATS -PyStats _py_stats = { 0 }; +PyStats _py_stats_struct = { 0 }; +PyStats *_py_stats = NULL; #define ADD_STAT_TO_DICT(res, field) \ do { \ @@ -93,7 +78,7 @@ add_stat_dict( int opcode, const char *name) { - SpecializationStats *stats = &_py_stats.opcode_stats[opcode].specialization; + SpecializationStats *stats = &_py_stats_struct.opcode_stats[opcode].specialization; PyObject *d = stats_to_dict(stats); if (d == NULL) { return -1; @@ -111,9 +96,9 @@ _Py_GetSpecializationStats(void) { return NULL; } int err = 0; + err += add_stat_dict(stats, LOAD_SUPER_ATTR, "load_super_attr"); err += add_stat_dict(stats, LOAD_ATTR, "load_attr"); err += add_stat_dict(stats, LOAD_GLOBAL, "load_global"); - err += add_stat_dict(stats, LOAD_METHOD, "load_method"); err += add_stat_dict(stats, BINARY_SUBSCR, "binary_subscr"); err += add_stat_dict(stats, STORE_SUBSCR, "store_subscr"); err += add_stat_dict(stats, STORE_ATTR, "store_attr"); @@ -121,7 +106,7 @@ _Py_GetSpecializationStats(void) { err += add_stat_dict(stats, BINARY_OP, "binary_op"); err += add_stat_dict(stats, COMPARE_OP, "compare_op"); err += add_stat_dict(stats, UNPACK_SEQUENCE, "unpack_sequence"); - err += add_stat_dict(stats, PRECALL, "precall"); + err += add_stat_dict(stats, FOR_ITER, "for_iter"); if (err < 0) { Py_DECREF(stats); return NULL; @@ -141,9 +126,12 @@ print_spec_stats(FILE *out, OpcodeStats *stats) { /* Mark some opcodes as specializable for stats, * even though we don't specialize them yet. */ - fprintf(out, "opcode[%d].specializable : 1\n", FOR_ITER); + fprintf(out, "opcode[%d].specializable : 1\n", BINARY_SLICE); + fprintf(out, "opcode[%d].specializable : 1\n", COMPARE_OP); + fprintf(out, "opcode[%d].specializable : 1\n", STORE_SLICE); + fprintf(out, "opcode[%d].specializable : 1\n", SEND); for (int i = 0; i < 256; i++) { - if (_PyOpcode_Adaptive[i]) { + if (_PyOpcode_Caches[i]) { fprintf(out, "opcode[%d].specializable : 1\n", i); } PRINT_STAT(i, specialization.success); @@ -160,7 +148,7 @@ print_spec_stats(FILE *out, OpcodeStats *stats) PRIu64 "\n", i, j, val); } } - for(int j = 0; j < 256; j++) { + for (int j = 0; j < 256; j++) { if (stats[i].pair_count[j]) { fprintf(out, "opcode[%d].pair_count[%d] : %" PRIu64 "\n", i, j, stats[i].pair_count[j]); @@ -178,6 +166,9 @@ print_call_stats(FILE *out, CallStats *stats) fprintf(out, "Calls to Python functions inlined: %" PRIu64 "\n", stats->inlined_py_calls); fprintf(out, "Frames pushed: %" PRIu64 "\n", stats->frames_pushed); fprintf(out, "Frame objects created: %" PRIu64 "\n", stats->frame_objects_created); + for (int i = 0; i < EVAL_CALL_KINDS; i++) { + fprintf(out, "Calls via PyEval_EvalFrame[%d] : %" PRIu64 "\n", i, stats->eval_calls[i]); + } } static void @@ -191,10 +182,19 @@ print_object_stats(FILE *out, ObjectStats *stats) fprintf(out, "Object allocations over 4 kbytes: %" PRIu64 "\n", stats->allocations_big); fprintf(out, "Object frees: %" PRIu64 "\n", stats->frees); fprintf(out, "Object new values: %" PRIu64 "\n", stats->new_values); + fprintf(out, "Object interpreter increfs: %" PRIu64 "\n", stats->interpreter_increfs); + fprintf(out, "Object interpreter decrefs: %" PRIu64 "\n", stats->interpreter_decrefs); + fprintf(out, "Object increfs: %" PRIu64 "\n", stats->increfs); + fprintf(out, "Object decrefs: %" PRIu64 "\n", stats->decrefs); fprintf(out, "Object materialize dict (on request): %" PRIu64 "\n", stats->dict_materialized_on_request); fprintf(out, "Object materialize dict (new key): %" PRIu64 "\n", stats->dict_materialized_new_key); fprintf(out, "Object materialize dict (too big): %" PRIu64 "\n", stats->dict_materialized_too_big); fprintf(out, "Object materialize dict (str subclass): %" PRIu64 "\n", stats->dict_materialized_str_subclass); + fprintf(out, "Object method cache hits: %" PRIu64 "\n", stats->type_cache_hits); + fprintf(out, "Object method cache misses: %" PRIu64 "\n", stats->type_cache_misses); + fprintf(out, "Object method cache collisions: %" PRIu64 "\n", stats->type_cache_collisions); + fprintf(out, "Object method cache dunder hits: %" PRIu64 "\n", stats->type_cache_dunder_hits); + fprintf(out, "Object method cache dunder misses: %" PRIu64 "\n", stats->type_cache_dunder_misses); } static void @@ -204,6 +204,12 @@ print_stats(FILE *out, PyStats *stats) { print_object_stats(out, &stats->object_stats); } +void +_Py_StatsClear(void) +{ + _py_stats_struct = (PyStats) { 0 }; +} + void _Py_PrintSpecializationStats(int to_file) { @@ -237,7 +243,7 @@ _Py_PrintSpecializationStats(int to_file) else { fprintf(out, "Specialization stats:\n"); } - print_stats(out, &_py_stats); + print_stats(out, &_py_stats_struct); if (out != stderr) { fclose(out); } @@ -245,8 +251,12 @@ _Py_PrintSpecializationStats(int to_file) #ifdef Py_STATS -#define SPECIALIZATION_FAIL(opcode, kind) _py_stats.opcode_stats[opcode].specialization.failure_kinds[kind]++ - +#define SPECIALIZATION_FAIL(opcode, kind) \ +do { \ + if (_py_stats) { \ + _py_stats->opcode_stats[opcode].specialization.failure_kinds[kind]++; \ + } \ +} while (0) #endif #endif @@ -255,81 +265,45 @@ _Py_PrintSpecializationStats(int to_file) #define SPECIALIZATION_FAIL(opcode, kind) ((void)0) #endif -// Insert adaptive instructions and superinstructions. This cannot fail. +// Initialize warmup counters and insert superinstructions. This cannot fail. void _PyCode_Quicken(PyCodeObject *code) { - _Py_QuickenedCount++; - int previous_opcode = -1; + #if ENABLE_SPECIALIZATION + int opcode = 0; _Py_CODEUNIT *instructions = _PyCode_CODE(code); for (int i = 0; i < Py_SIZE(code); i++) { - int opcode = _Py_OPCODE(instructions[i]); - uint8_t adaptive_opcode = _PyOpcode_Adaptive[opcode]; - if (adaptive_opcode) { - _Py_SET_OPCODE(instructions[i], adaptive_opcode); - // Make sure the adaptive counter is zero: - assert(instructions[i + 1] == 0); - previous_opcode = -1; - i += _PyOpcode_Caches[opcode]; - } - else { - assert(!_PyOpcode_Caches[opcode]); - switch (opcode) { - case EXTENDED_ARG: - _Py_SET_OPCODE(instructions[i], EXTENDED_ARG_QUICK); - break; - case JUMP_BACKWARD: - _Py_SET_OPCODE(instructions[i], JUMP_BACKWARD_QUICK); - break; - case RESUME: - _Py_SET_OPCODE(instructions[i], RESUME_QUICK); - break; - case LOAD_FAST: - switch(previous_opcode) { - case LOAD_FAST: - _Py_SET_OPCODE(instructions[i - 1], - LOAD_FAST__LOAD_FAST); - break; - case STORE_FAST: - _Py_SET_OPCODE(instructions[i - 1], - STORE_FAST__LOAD_FAST); - break; - case LOAD_CONST: - _Py_SET_OPCODE(instructions[i - 1], - LOAD_CONST__LOAD_FAST); - break; - } - break; - case STORE_FAST: - if (previous_opcode == STORE_FAST) { - _Py_SET_OPCODE(instructions[i - 1], - STORE_FAST__STORE_FAST); - } - break; - case LOAD_CONST: - if (previous_opcode == LOAD_FAST) { - _Py_SET_OPCODE(instructions[i - 1], - LOAD_FAST__LOAD_CONST); - } - break; - } - previous_opcode = opcode; + int previous_opcode = opcode; + opcode = _Py_GetBaseOpcode(code, i); + assert(opcode < MIN_INSTRUMENTED_OPCODE); + int caches = _PyOpcode_Caches[opcode]; + if (caches) { + instructions[i + 1].cache = adaptive_counter_warmup(); + i += caches; + continue; + } + switch (previous_opcode << 8 | opcode) { + case LOAD_CONST << 8 | LOAD_FAST: + instructions[i - 1].op.code = LOAD_CONST__LOAD_FAST; + break; + case LOAD_FAST << 8 | LOAD_CONST: + instructions[i - 1].op.code = LOAD_FAST__LOAD_CONST; + break; + case LOAD_FAST << 8 | LOAD_FAST: + instructions[i - 1].op.code = LOAD_FAST__LOAD_FAST; + break; + case STORE_FAST << 8 | LOAD_FAST: + instructions[i - 1].op.code = STORE_FAST__LOAD_FAST; + break; + case STORE_FAST << 8 | STORE_FAST: + instructions[i - 1].op.code = STORE_FAST__STORE_FAST; + break; } } + #endif /* ENABLE_SPECIALIZATION */ } -static inline int -miss_counter_start(void) { - /* Starting value for the counter. - * This value needs to be not too low, otherwise - * it would cause excessive de-optimization. - * Neither should it be too high, or that would delay - * de-optimization excessively when it is needed. - * A value around 50 seems to work, and we choose a - * prime number to avoid artifacts. - */ - return 53; -} +#define SIMPLE_FUNCTION 0 /* Common */ @@ -340,51 +314,55 @@ miss_counter_start(void) { #define SPEC_FAIL_OUT_OF_RANGE 4 #define SPEC_FAIL_EXPECTED_ERROR 5 #define SPEC_FAIL_WRONG_NUMBER_ARGUMENTS 6 +#define SPEC_FAIL_CODE_COMPLEX_PARAMETERS 7 +#define SPEC_FAIL_CODE_NOT_OPTIMIZED 8 + +#define SPEC_FAIL_LOAD_GLOBAL_NON_DICT 17 #define SPEC_FAIL_LOAD_GLOBAL_NON_STRING_OR_SPLIT 18 +/* Super */ + +#define SPEC_FAIL_SUPER_BAD_CLASS 9 +#define SPEC_FAIL_SUPER_SHADOWED 10 + /* Attributes */ -#define SPEC_FAIL_ATTR_OVERRIDING_DESCRIPTOR 8 -#define SPEC_FAIL_ATTR_NON_OVERRIDING_DESCRIPTOR 9 -#define SPEC_FAIL_ATTR_NOT_DESCRIPTOR 10 -#define SPEC_FAIL_ATTR_METHOD 11 -#define SPEC_FAIL_ATTR_MUTABLE_CLASS 12 -#define SPEC_FAIL_ATTR_PROPERTY 13 -#define SPEC_FAIL_ATTR_NON_OBJECT_SLOT 14 -#define SPEC_FAIL_ATTR_READ_ONLY 15 -#define SPEC_FAIL_ATTR_AUDITED_SLOT 16 -#define SPEC_FAIL_ATTR_NOT_MANAGED_DICT 17 -#define SPEC_FAIL_ATTR_NON_STRING_OR_SPLIT 18 -#define SPEC_FAIL_ATTR_MODULE_ATTR_NOT_FOUND 19 - -/* Methods */ - -#define SPEC_FAIL_LOAD_METHOD_OVERRIDING_DESCRIPTOR 8 -#define SPEC_FAIL_LOAD_METHOD_NON_OVERRIDING_DESCRIPTOR 9 -#define SPEC_FAIL_LOAD_METHOD_NOT_DESCRIPTOR 10 -#define SPEC_FAIL_LOAD_METHOD_METHOD 11 -#define SPEC_FAIL_LOAD_METHOD_MUTABLE_CLASS 12 -#define SPEC_FAIL_LOAD_METHOD_PROPERTY 13 -#define SPEC_FAIL_LOAD_METHOD_NON_OBJECT_SLOT 14 -#define SPEC_FAIL_LOAD_METHOD_IS_ATTR 15 -#define SPEC_FAIL_LOAD_METHOD_DICT_SUBCLASS 16 -#define SPEC_FAIL_LOAD_METHOD_BUILTIN_CLASS_METHOD 17 -#define SPEC_FAIL_LOAD_METHOD_CLASS_METHOD_OBJ 18 -#define SPEC_FAIL_LOAD_METHOD_OBJECT_SLOT 19 -#define SPEC_FAIL_LOAD_METHOD_HAS_DICT 20 -#define SPEC_FAIL_LOAD_METHOD_HAS_MANAGED_DICT 21 -#define SPEC_FAIL_LOAD_METHOD_INSTANCE_ATTRIBUTE 22 -#define SPEC_FAIL_LOAD_METHOD_METACLASS_ATTRIBUTE 23 +#define SPEC_FAIL_ATTR_OVERRIDING_DESCRIPTOR 9 +#define SPEC_FAIL_ATTR_NON_OVERRIDING_DESCRIPTOR 10 +#define SPEC_FAIL_ATTR_NOT_DESCRIPTOR 11 +#define SPEC_FAIL_ATTR_METHOD 12 +#define SPEC_FAIL_ATTR_MUTABLE_CLASS 13 +#define SPEC_FAIL_ATTR_PROPERTY 14 +#define SPEC_FAIL_ATTR_NON_OBJECT_SLOT 15 +#define SPEC_FAIL_ATTR_READ_ONLY 16 +#define SPEC_FAIL_ATTR_AUDITED_SLOT 17 +#define SPEC_FAIL_ATTR_NOT_MANAGED_DICT 18 +#define SPEC_FAIL_ATTR_NON_STRING_OR_SPLIT 19 +#define SPEC_FAIL_ATTR_MODULE_ATTR_NOT_FOUND 20 + +#define SPEC_FAIL_ATTR_SHADOWED 21 +#define SPEC_FAIL_ATTR_BUILTIN_CLASS_METHOD 22 +#define SPEC_FAIL_ATTR_CLASS_METHOD_OBJ 23 +#define SPEC_FAIL_ATTR_OBJECT_SLOT 24 +#define SPEC_FAIL_ATTR_HAS_MANAGED_DICT 25 +#define SPEC_FAIL_ATTR_INSTANCE_ATTRIBUTE 26 +#define SPEC_FAIL_ATTR_METACLASS_ATTRIBUTE 27 +#define SPEC_FAIL_ATTR_PROPERTY_NOT_PY_FUNCTION 28 +#define SPEC_FAIL_ATTR_NOT_IN_KEYS 29 +#define SPEC_FAIL_ATTR_NOT_IN_DICT 30 +#define SPEC_FAIL_ATTR_CLASS_ATTR_SIMPLE 31 +#define SPEC_FAIL_ATTR_CLASS_ATTR_DESCRIPTOR 32 +#define SPEC_FAIL_ATTR_BUILTIN_CLASS_METHOD_OBJ 33 /* Binary subscr and store subscr */ -#define SPEC_FAIL_SUBSCR_ARRAY_INT 8 -#define SPEC_FAIL_SUBSCR_ARRAY_SLICE 9 -#define SPEC_FAIL_SUBSCR_LIST_SLICE 10 -#define SPEC_FAIL_SUBSCR_TUPLE_SLICE 11 -#define SPEC_FAIL_SUBSCR_STRING_INT 12 -#define SPEC_FAIL_SUBSCR_STRING_SLICE 13 +#define SPEC_FAIL_SUBSCR_ARRAY_INT 9 +#define SPEC_FAIL_SUBSCR_ARRAY_SLICE 10 +#define SPEC_FAIL_SUBSCR_LIST_SLICE 11 +#define SPEC_FAIL_SUBSCR_TUPLE_SLICE 12 +#define SPEC_FAIL_SUBSCR_STRING_INT 13 +#define SPEC_FAIL_SUBSCR_STRING_SLICE 14 #define SPEC_FAIL_SUBSCR_BUFFER_INT 15 #define SPEC_FAIL_SUBSCR_BUFFER_SLICE 16 #define SPEC_FAIL_SUBSCR_SEQUENCE_INT 17 @@ -399,127 +377,134 @@ miss_counter_start(void) { /* Binary op */ -#define SPEC_FAIL_BINARY_OP_ADD_DIFFERENT_TYPES 8 -#define SPEC_FAIL_BINARY_OP_ADD_OTHER 9 -#define SPEC_FAIL_BINARY_OP_AND_DIFFERENT_TYPES 10 -#define SPEC_FAIL_BINARY_OP_AND_INT 11 -#define SPEC_FAIL_BINARY_OP_AND_OTHER 12 -#define SPEC_FAIL_BINARY_OP_FLOOR_DIVIDE 13 -#define SPEC_FAIL_BINARY_OP_LSHIFT 14 -#define SPEC_FAIL_BINARY_OP_MATRIX_MULTIPLY 15 -#define SPEC_FAIL_BINARY_OP_MULTIPLY_DIFFERENT_TYPES 16 -#define SPEC_FAIL_BINARY_OP_MULTIPLY_OTHER 17 -#define SPEC_FAIL_BINARY_OP_OR 18 -#define SPEC_FAIL_BINARY_OP_POWER 19 -#define SPEC_FAIL_BINARY_OP_REMAINDER 20 -#define SPEC_FAIL_BINARY_OP_RSHIFT 21 -#define SPEC_FAIL_BINARY_OP_SUBTRACT_DIFFERENT_TYPES 22 -#define SPEC_FAIL_BINARY_OP_SUBTRACT_OTHER 23 -#define SPEC_FAIL_BINARY_OP_TRUE_DIVIDE_DIFFERENT_TYPES 24 -#define SPEC_FAIL_BINARY_OP_TRUE_DIVIDE_FLOAT 25 -#define SPEC_FAIL_BINARY_OP_TRUE_DIVIDE_OTHER 26 -#define SPEC_FAIL_BINARY_OP_XOR 27 +#define SPEC_FAIL_BINARY_OP_ADD_DIFFERENT_TYPES 9 +#define SPEC_FAIL_BINARY_OP_ADD_OTHER 10 +#define SPEC_FAIL_BINARY_OP_AND_DIFFERENT_TYPES 11 +#define SPEC_FAIL_BINARY_OP_AND_INT 12 +#define SPEC_FAIL_BINARY_OP_AND_OTHER 13 +#define SPEC_FAIL_BINARY_OP_FLOOR_DIVIDE 14 +#define SPEC_FAIL_BINARY_OP_LSHIFT 15 +#define SPEC_FAIL_BINARY_OP_MATRIX_MULTIPLY 16 +#define SPEC_FAIL_BINARY_OP_MULTIPLY_DIFFERENT_TYPES 17 +#define SPEC_FAIL_BINARY_OP_MULTIPLY_OTHER 18 +#define SPEC_FAIL_BINARY_OP_OR 19 +#define SPEC_FAIL_BINARY_OP_POWER 20 +#define SPEC_FAIL_BINARY_OP_REMAINDER 21 +#define SPEC_FAIL_BINARY_OP_RSHIFT 22 +#define SPEC_FAIL_BINARY_OP_SUBTRACT_DIFFERENT_TYPES 23 +#define SPEC_FAIL_BINARY_OP_SUBTRACT_OTHER 24 +#define SPEC_FAIL_BINARY_OP_TRUE_DIVIDE_DIFFERENT_TYPES 25 +#define SPEC_FAIL_BINARY_OP_TRUE_DIVIDE_FLOAT 26 +#define SPEC_FAIL_BINARY_OP_TRUE_DIVIDE_OTHER 27 +#define SPEC_FAIL_BINARY_OP_XOR 28 /* Calls */ -#define SPEC_FAIL_CALL_COMPLEX_PARAMETERS 9 -#define SPEC_FAIL_CALL_CO_NOT_OPTIMIZED 10 -/* SPEC_FAIL_METHOD defined as 11 above */ #define SPEC_FAIL_CALL_INSTANCE_METHOD 11 #define SPEC_FAIL_CALL_CMETHOD 12 -#define SPEC_FAIL_CALL_PYCFUNCTION 13 -#define SPEC_FAIL_CALL_PYCFUNCTION_WITH_KEYWORDS 14 -#define SPEC_FAIL_CALL_PYCFUNCTION_FAST_WITH_KEYWORDS 15 -#define SPEC_FAIL_CALL_PYCFUNCTION_NOARGS 16 -#define SPEC_FAIL_CALL_BAD_CALL_FLAGS 17 -#define SPEC_FAIL_CALL_CLASS 18 -#define SPEC_FAIL_CALL_PYTHON_CLASS 19 -#define SPEC_FAIL_CALL_METHOD_DESCRIPTOR 20 -#define SPEC_FAIL_CALL_BOUND_METHOD 21 -#define SPEC_FAIL_CALL_STR 22 -#define SPEC_FAIL_CALL_CLASS_NO_VECTORCALL 23 -#define SPEC_FAIL_CALL_CLASS_MUTABLE 24 -#define SPEC_FAIL_CALL_KWNAMES 25 -#define SPEC_FAIL_CALL_METHOD_WRAPPER 26 -#define SPEC_FAIL_CALL_OPERATOR_WRAPPER 27 -#define SPEC_FAIL_CALL_PYFUNCTION 28 -#define SPEC_FAIL_CALL_PEP_523 29 +#define SPEC_FAIL_CALL_CFUNC_VARARGS 13 +#define SPEC_FAIL_CALL_CFUNC_VARARGS_KEYWORDS 14 +#define SPEC_FAIL_CALL_CFUNC_NOARGS 15 +#define SPEC_FAIL_CALL_CFUNC_METHOD_FASTCALL_KEYWORDS 16 +#define SPEC_FAIL_CALL_METH_DESCR_VARARGS 17 +#define SPEC_FAIL_CALL_METH_DESCR_VARARGS_KEYWORDS 18 +#define SPEC_FAIL_CALL_METH_DESCR_METHOD_FASTCALL_KEYWORDS 19 +#define SPEC_FAIL_CALL_BAD_CALL_FLAGS 20 +#define SPEC_FAIL_CALL_PYTHON_CLASS 21 +#define SPEC_FAIL_CALL_PEP_523 22 +#define SPEC_FAIL_CALL_BOUND_METHOD 23 +#define SPEC_FAIL_CALL_STR 24 +#define SPEC_FAIL_CALL_CLASS_NO_VECTORCALL 25 +#define SPEC_FAIL_CALL_CLASS_MUTABLE 26 +#define SPEC_FAIL_CALL_KWNAMES 27 +#define SPEC_FAIL_CALL_METHOD_WRAPPER 28 +#define SPEC_FAIL_CALL_OPERATOR_WRAPPER 29 /* COMPARE_OP */ #define SPEC_FAIL_COMPARE_OP_DIFFERENT_TYPES 12 #define SPEC_FAIL_COMPARE_OP_STRING 13 -#define SPEC_FAIL_COMPARE_OP_NOT_FOLLOWED_BY_COND_JUMP 14 -#define SPEC_FAIL_COMPARE_OP_BIG_INT 15 -#define SPEC_FAIL_COMPARE_OP_BYTES 16 -#define SPEC_FAIL_COMPARE_OP_TUPLE 17 -#define SPEC_FAIL_COMPARE_OP_LIST 18 -#define SPEC_FAIL_COMPARE_OP_SET 19 -#define SPEC_FAIL_COMPARE_OP_BOOL 20 -#define SPEC_FAIL_COMPARE_OP_BASEOBJECT 21 -#define SPEC_FAIL_COMPARE_OP_FLOAT_LONG 22 -#define SPEC_FAIL_COMPARE_OP_LONG_FLOAT 23 -#define SPEC_FAIL_COMPARE_OP_EXTENDED_ARG 24 - -/* FOR_ITER */ -#define SPEC_FAIL_FOR_ITER_GENERATOR 10 -#define SPEC_FAIL_FOR_ITER_COROUTINE 11 -#define SPEC_FAIL_FOR_ITER_ASYNC_GENERATOR 12 -#define SPEC_FAIL_FOR_ITER_LIST 13 -#define SPEC_FAIL_FOR_ITER_TUPLE 14 -#define SPEC_FAIL_FOR_ITER_SET 15 -#define SPEC_FAIL_FOR_ITER_STRING 16 -#define SPEC_FAIL_FOR_ITER_BYTES 17 -#define SPEC_FAIL_FOR_ITER_RANGE 18 -#define SPEC_FAIL_FOR_ITER_ITERTOOLS 19 -#define SPEC_FAIL_FOR_ITER_DICT_KEYS 20 -#define SPEC_FAIL_FOR_ITER_DICT_ITEMS 21 -#define SPEC_FAIL_FOR_ITER_DICT_VALUES 22 -#define SPEC_FAIL_FOR_ITER_ENUMERATE 23 +#define SPEC_FAIL_COMPARE_OP_BIG_INT 14 +#define SPEC_FAIL_COMPARE_OP_BYTES 15 +#define SPEC_FAIL_COMPARE_OP_TUPLE 16 +#define SPEC_FAIL_COMPARE_OP_LIST 17 +#define SPEC_FAIL_COMPARE_OP_SET 18 +#define SPEC_FAIL_COMPARE_OP_BOOL 19 +#define SPEC_FAIL_COMPARE_OP_BASEOBJECT 20 +#define SPEC_FAIL_COMPARE_OP_FLOAT_LONG 21 +#define SPEC_FAIL_COMPARE_OP_LONG_FLOAT 22 + +/* FOR_ITER and SEND */ +#define SPEC_FAIL_ITER_GENERATOR 10 +#define SPEC_FAIL_ITER_COROUTINE 11 +#define SPEC_FAIL_ITER_ASYNC_GENERATOR 12 +#define SPEC_FAIL_ITER_LIST 13 +#define SPEC_FAIL_ITER_TUPLE 14 +#define SPEC_FAIL_ITER_SET 15 +#define SPEC_FAIL_ITER_STRING 16 +#define SPEC_FAIL_ITER_BYTES 17 +#define SPEC_FAIL_ITER_RANGE 18 +#define SPEC_FAIL_ITER_ITERTOOLS 19 +#define SPEC_FAIL_ITER_DICT_KEYS 20 +#define SPEC_FAIL_ITER_DICT_ITEMS 21 +#define SPEC_FAIL_ITER_DICT_VALUES 22 +#define SPEC_FAIL_ITER_ENUMERATE 23 +#define SPEC_FAIL_ITER_MAP 24 +#define SPEC_FAIL_ITER_ZIP 25 +#define SPEC_FAIL_ITER_SEQ_ITER 26 +#define SPEC_FAIL_ITER_REVERSED_LIST 27 +#define SPEC_FAIL_ITER_CALLABLE 28 +#define SPEC_FAIL_ITER_ASCII_STRING 29 +#define SPEC_FAIL_ITER_ASYNC_GENERATOR_SEND 30 // UNPACK_SEQUENCE -#define SPEC_FAIL_UNPACK_SEQUENCE_ITERATOR 8 -#define SPEC_FAIL_UNPACK_SEQUENCE_SEQUENCE 9 +#define SPEC_FAIL_UNPACK_SEQUENCE_ITERATOR 9 +#define SPEC_FAIL_UNPACK_SEQUENCE_SEQUENCE 10 +static int function_kind(PyCodeObject *code); +static bool function_check_args(PyObject *o, int expected_argcount, int opcode); +static uint32_t function_get_version(PyObject *o, int opcode); static int -specialize_module_load_attr(PyObject *owner, _Py_CODEUNIT *instr, - PyObject *name, int opcode, int opcode_module) -{ +specialize_module_load_attr( + PyObject *owner, _Py_CODEUNIT *instr, PyObject *name +) { _PyAttrCache *cache = (_PyAttrCache *)(instr + 1); PyModuleObject *m = (PyModuleObject *)owner; - PyObject *value = NULL; assert((owner->ob_type->tp_flags & Py_TPFLAGS_MANAGED_DICT) == 0); PyDictObject *dict = (PyDictObject *)m->md_dict; if (dict == NULL) { - SPECIALIZATION_FAIL(opcode, SPEC_FAIL_NO_DICT); + SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_NO_DICT); return -1; } if (dict->ma_keys->dk_kind != DICT_KEYS_UNICODE) { - SPECIALIZATION_FAIL(opcode, SPEC_FAIL_ATTR_NON_STRING_OR_SPLIT); + SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_NON_STRING_OR_SPLIT); return -1; } - Py_ssize_t index = _PyDict_GetItemHint(dict, &_Py_ID(__getattr__), -1, - &value); + Py_ssize_t index = _PyDict_LookupIndex(dict, &_Py_ID(__getattr__)); assert(index != DKIX_ERROR); if (index != DKIX_EMPTY) { - SPECIALIZATION_FAIL(opcode, SPEC_FAIL_ATTR_MODULE_ATTR_NOT_FOUND); + SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_MODULE_ATTR_NOT_FOUND); return -1; } - index = _PyDict_GetItemHint(dict, name, -1, &value); + index = _PyDict_LookupIndex(dict, name); assert (index != DKIX_ERROR); if (index != (uint16_t)index) { - SPECIALIZATION_FAIL(opcode, SPEC_FAIL_OUT_OF_RANGE); + SPECIALIZATION_FAIL(LOAD_ATTR, + index == DKIX_EMPTY ? + SPEC_FAIL_ATTR_MODULE_ATTR_NOT_FOUND : + SPEC_FAIL_OUT_OF_RANGE); return -1; } - uint32_t keys_version = _PyDictKeys_GetVersionForCurrentState(dict->ma_keys); + uint32_t keys_version = _PyDictKeys_GetVersionForCurrentState( + _PyInterpreterState_GET(), dict->ma_keys); if (keys_version == 0) { - SPECIALIZATION_FAIL(opcode, SPEC_FAIL_OUT_OF_VERSIONS); + SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_OUT_OF_VERSIONS); return -1; } write_u32(cache->version, keys_version); cache->index = (uint16_t)index; - _Py_SET_OPCODE(*instr, opcode_module); + instr->op.code = LOAD_ATTR_MODULE; return 0; } @@ -527,6 +512,34 @@ specialize_module_load_attr(PyObject *owner, _Py_CODEUNIT *instr, /* Attribute specialization */ +void +_Py_Specialize_LoadSuperAttr(PyObject *global_super, PyObject *cls, _Py_CODEUNIT *instr, int load_method) { + assert(ENABLE_SPECIALIZATION); + assert(_PyOpcode_Caches[LOAD_SUPER_ATTR] == INLINE_CACHE_ENTRIES_LOAD_SUPER_ATTR); + _PySuperAttrCache *cache = (_PySuperAttrCache *)(instr + 1); + if (global_super != (PyObject *)&PySuper_Type) { + SPECIALIZATION_FAIL(LOAD_SUPER_ATTR, SPEC_FAIL_SUPER_SHADOWED); + goto fail; + } + if (!PyType_Check(cls)) { + SPECIALIZATION_FAIL(LOAD_SUPER_ATTR, SPEC_FAIL_SUPER_BAD_CLASS); + goto fail; + } + instr->op.code = load_method ? LOAD_SUPER_ATTR_METHOD : LOAD_SUPER_ATTR_ATTR; + goto success; + +fail: + STAT_INC(LOAD_SUPER_ATTR, failure); + assert(!PyErr_Occurred()); + instr->op.code = LOAD_SUPER_ATTR; + cache->counter = adaptive_counter_backoff(cache->counter); + return; +success: + STAT_INC(LOAD_SUPER_ATTR, success); + assert(!PyErr_Occurred()); + cache->counter = adaptive_counter_cooldown(); +} + typedef enum { OVERRIDING, /* Is an overriding descriptor, and will remain so. */ METHOD, /* Attribute has Py_TPFLAGS_METHOD_DESCRIPTOR set */ @@ -540,13 +553,15 @@ typedef enum { MUTABLE, /* Instance of a mutable class; might, or might not, be a descriptor */ ABSENT, /* Attribute is not present on the class */ DUNDER_CLASS, /* __class__ attribute */ - GETSET_OVERRIDDEN /* __getattribute__ or __setattr__ has been overridden */ + GETSET_OVERRIDDEN, /* __getattribute__ or __setattr__ has been overridden */ + GETATTRIBUTE_IS_PYTHON_FUNCTION /* Descriptor requires calling a Python __getattribute__ */ } DescriptorClassification; static DescriptorClassification analyze_descriptor(PyTypeObject *type, PyObject *name, PyObject **descr, int store) { + bool has_getattr = false; if (store) { if (type->tp_setattro != PyObject_GenericSetAttr) { *descr = NULL; @@ -554,7 +569,42 @@ analyze_descriptor(PyTypeObject *type, PyObject *name, PyObject **descr, int sto } } else { - if (type->tp_getattro != PyObject_GenericGetAttr) { + getattrofunc getattro_slot = type->tp_getattro; + if (getattro_slot == PyObject_GenericGetAttr) { + /* Normal attribute lookup; */ + has_getattr = false; + } + else if (getattro_slot == _Py_slot_tp_getattr_hook || + getattro_slot == _Py_slot_tp_getattro) { + /* One or both of __getattribute__ or __getattr__ may have been + overridden See typeobject.c for why these functions are special. */ + PyObject *getattribute = _PyType_Lookup(type, + &_Py_ID(__getattribute__)); + PyInterpreterState *interp = _PyInterpreterState_GET(); + bool has_custom_getattribute = getattribute != NULL && + getattribute != interp->callable_cache.object__getattribute__; + has_getattr = _PyType_Lookup(type, &_Py_ID(__getattr__)) != NULL; + if (has_custom_getattribute) { + if (getattro_slot == _Py_slot_tp_getattro && + !has_getattr && + Py_IS_TYPE(getattribute, &PyFunction_Type)) { + *descr = getattribute; + return GETATTRIBUTE_IS_PYTHON_FUNCTION; + } + /* Potentially both __getattr__ and __getattribute__ are set. + Too complicated */ + *descr = NULL; + return GETSET_OVERRIDDEN; + } + /* Potentially has __getattr__ but no custom __getattribute__. + Fall through to usual descriptor analysis. + Usual attribute lookup should only be allowed at runtime + if we can guarantee that there is no way an exception can be + raised. This means some specializations, e.g. specializing + for property() isn't safe. + */ + } + else { *descr = NULL; return GETSET_OVERRIDDEN; } @@ -578,14 +628,19 @@ analyze_descriptor(PyTypeObject *type, PyObject *name, PyObject **descr, int sto return OTHER_SLOT; } if (desc_cls == &PyProperty_Type) { - return PROPERTY; + /* We can't detect at runtime whether an attribute exists + with property. So that means we may have to call + __getattr__. */ + return has_getattr ? GETSET_OVERRIDDEN : PROPERTY; } if (PyUnicode_CompareWithASCIIString(name, "__class__") == 0) { if (descriptor == _PyType_Lookup(&PyBaseObject_Type, name)) { return DUNDER_CLASS; } } - return OVERRIDING; + if (store) { + return OVERRIDING; + } } if (desc_cls->tp_descr_get) { if (desc_cls->tp_flags & Py_TPFLAGS_METHOD_DESCRIPTOR) { @@ -616,73 +671,130 @@ specialize_dict_access( return 0; } _PyAttrCache *cache = (_PyAttrCache *)(instr + 1); - PyObject **dictptr = _PyObject_ManagedDictPointer(owner); - PyDictObject *dict = (PyDictObject *)*dictptr; - if (dict == NULL) { + PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); + if (_PyDictOrValues_IsValues(dorv)) { // Virtual dictionary PyDictKeysObject *keys = ((PyHeapTypeObject *)type)->ht_cached_keys; assert(PyUnicode_CheckExact(name)); Py_ssize_t index = _PyDictKeys_StringLookup(keys, name); assert (index != DKIX_ERROR); if (index != (uint16_t)index) { - SPECIALIZATION_FAIL(base_op, SPEC_FAIL_OUT_OF_RANGE); + SPECIALIZATION_FAIL(base_op, + index == DKIX_EMPTY ? + SPEC_FAIL_ATTR_NOT_IN_KEYS : + SPEC_FAIL_OUT_OF_RANGE); return 0; } write_u32(cache->version, type->tp_version_tag); cache->index = (uint16_t)index; - _Py_SET_OPCODE(*instr, values_op); + instr->op.code = values_op; } else { - if (!PyDict_CheckExact(dict)) { + PyDictObject *dict = (PyDictObject *)_PyDictOrValues_GetDict(dorv); + if (dict == NULL || !PyDict_CheckExact(dict)) { SPECIALIZATION_FAIL(base_op, SPEC_FAIL_NO_DICT); return 0; } // We found an instance with a __dict__. - PyObject *value = NULL; - Py_ssize_t hint = - _PyDict_GetItemHint(dict, name, -1, &value); - if (hint != (uint16_t)hint) { - SPECIALIZATION_FAIL(base_op, SPEC_FAIL_OUT_OF_RANGE); + Py_ssize_t index = + _PyDict_LookupIndex(dict, name); + if (index != (uint16_t)index) { + SPECIALIZATION_FAIL(base_op, + index == DKIX_EMPTY ? + SPEC_FAIL_ATTR_NOT_IN_DICT : + SPEC_FAIL_OUT_OF_RANGE); return 0; } - cache->index = (uint16_t)hint; + cache->index = (uint16_t)index; write_u32(cache->version, type->tp_version_tag); - _Py_SET_OPCODE(*instr, hint_op); + instr->op.code = hint_op; } return 1; } -int +static int specialize_attr_loadmethod(PyObject* owner, _Py_CODEUNIT* instr, PyObject* name, + PyObject* descr, DescriptorClassification kind); +static int specialize_class_load_attr(PyObject* owner, _Py_CODEUNIT* instr, PyObject* name); + +void _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) { + assert(ENABLE_SPECIALIZATION); assert(_PyOpcode_Caches[LOAD_ATTR] == INLINE_CACHE_ENTRIES_LOAD_ATTR); _PyAttrCache *cache = (_PyAttrCache *)(instr + 1); + PyTypeObject *type = Py_TYPE(owner); + if (!_PyType_IsReady(type)) { + // We *might* not really need this check, but we inherited it from + // PyObject_GenericGetAttr and friends... and this way we still do the + // right thing if someone forgets to call PyType_Ready(type): + SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_OTHER); + goto fail; + } if (PyModule_CheckExact(owner)) { - int err = specialize_module_load_attr(owner, instr, name, LOAD_ATTR, - LOAD_ATTR_MODULE); - if (err) { + if (specialize_module_load_attr(owner, instr, name)) + { goto fail; } goto success; } - PyTypeObject *type = Py_TYPE(owner); - if (type->tp_dict == NULL) { - if (PyType_Ready(type) < 0) { - return -1; + if (PyType_Check(owner)) { + if (specialize_class_load_attr(owner, instr, name)) { + goto fail; } + goto success; } - PyObject *descr; + PyObject *descr = NULL; DescriptorClassification kind = analyze_descriptor(type, name, &descr, 0); + assert(descr != NULL || kind == ABSENT || kind == GETSET_OVERRIDDEN); switch(kind) { case OVERRIDING: SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_OVERRIDING_DESCRIPTOR); goto fail; case METHOD: - SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_METHOD); + { + int oparg = instr->op.arg; + if (oparg & 1) { + if (specialize_attr_loadmethod(owner, instr, name, descr, kind)) { + goto success; + } + } + else { + SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_METHOD); + } goto fail; + } case PROPERTY: - SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_PROPERTY); - goto fail; + { + _PyLoadMethodCache *lm_cache = (_PyLoadMethodCache *)(instr + 1); + assert(Py_TYPE(descr) == &PyProperty_Type); + PyObject *fget = ((_PyPropertyObject *)descr)->prop_get; + if (fget == NULL) { + SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_EXPECTED_ERROR); + goto fail; + } + if (!Py_IS_TYPE(fget, &PyFunction_Type)) { + SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_PROPERTY_NOT_PY_FUNCTION); + goto fail; + } + if (!function_check_args(fget, 1, LOAD_ATTR)) { + goto fail; + } + uint32_t version = function_get_version(fget, LOAD_ATTR); + if (version == 0) { + goto fail; + } + if (_PyInterpreterState_GET()->eval_frame) { + SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_OTHER); + goto fail; + } + write_u32(lm_cache->keys_version, version); + assert(type->tp_version_tag != 0); + write_u32(lm_cache->type_version, type->tp_version_tag); + /* borrowed */ + write_obj(lm_cache->descr, fget); + instr->op.code = LOAD_ATTR_PROPERTY; + goto success; + } case OBJECT_SLOT: { PyMemberDescrObject *member = (PyMemberDescrObject *)descr; @@ -704,7 +816,7 @@ _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) assert(offset > 0); cache->index = (uint16_t)offset; write_u32(cache->version, type->tp_version_tag); - _Py_SET_OPCODE(*instr, LOAD_ATTR_SLOT); + instr->op.code = LOAD_ATTR_SLOT; goto success; } case DUNDER_CLASS: @@ -713,7 +825,7 @@ _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) assert(offset == (uint16_t)offset); cache->index = (uint16_t)offset; write_u32(cache->version, type->tp_version_tag); - _Py_SET_OPCODE(*instr, LOAD_ATTR_SLOT); + instr->op.code = LOAD_ATTR_SLOT; goto success; } case OTHER_SLOT: @@ -725,41 +837,80 @@ _Py_Specialize_LoadAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) case GETSET_OVERRIDDEN: SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_OVERRIDDEN); goto fail; + case GETATTRIBUTE_IS_PYTHON_FUNCTION: + { + assert(type->tp_getattro == _Py_slot_tp_getattro); + assert(Py_IS_TYPE(descr, &PyFunction_Type)); + _PyLoadMethodCache *lm_cache = (_PyLoadMethodCache *)(instr + 1); + if (!function_check_args(descr, 2, LOAD_ATTR)) { + goto fail; + } + uint32_t version = function_get_version(descr, LOAD_ATTR); + if (version == 0) { + goto fail; + } + if (_PyInterpreterState_GET()->eval_frame) { + SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_OTHER); + goto fail; + } + write_u32(lm_cache->keys_version, version); + /* borrowed */ + write_obj(lm_cache->descr, descr); + write_u32(lm_cache->type_version, type->tp_version_tag); + instr->op.code = LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN; + goto success; + } case BUILTIN_CLASSMETHOD: + SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_BUILTIN_CLASS_METHOD_OBJ); + goto fail; case PYTHON_CLASSMETHOD: + SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_CLASS_METHOD_OBJ); + goto fail; case NON_OVERRIDING: + SPECIALIZATION_FAIL(LOAD_ATTR, + (type->tp_flags & Py_TPFLAGS_MANAGED_DICT) ? + SPEC_FAIL_ATTR_CLASS_ATTR_DESCRIPTOR : + SPEC_FAIL_ATTR_NOT_MANAGED_DICT); + goto fail; case NON_DESCRIPTOR: + SPECIALIZATION_FAIL(LOAD_ATTR, + (type->tp_flags & Py_TPFLAGS_MANAGED_DICT) ? + SPEC_FAIL_ATTR_CLASS_ATTR_SIMPLE : + SPEC_FAIL_ATTR_NOT_MANAGED_DICT); + goto fail; case ABSENT: - break; - } - int err = specialize_dict_access( - owner, instr, type, kind, name, - LOAD_ATTR, LOAD_ATTR_INSTANCE_VALUE, LOAD_ATTR_WITH_HINT - ); - if (err < 0) { - return -1; - } - if (err) { - goto success; + if (specialize_dict_access(owner, instr, type, kind, name, LOAD_ATTR, + LOAD_ATTR_INSTANCE_VALUE, LOAD_ATTR_WITH_HINT)) + { + goto success; + } } fail: STAT_INC(LOAD_ATTR, failure); assert(!PyErr_Occurred()); + instr->op.code = LOAD_ATTR; cache->counter = adaptive_counter_backoff(cache->counter); - return 0; + return; success: STAT_INC(LOAD_ATTR, success); assert(!PyErr_Occurred()); - cache->counter = miss_counter_start(); - return 0; + cache->counter = adaptive_counter_cooldown(); } -int +void _Py_Specialize_StoreAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) { + assert(ENABLE_SPECIALIZATION); assert(_PyOpcode_Caches[STORE_ATTR] == INLINE_CACHE_ENTRIES_STORE_ATTR); _PyAttrCache *cache = (_PyAttrCache *)(instr + 1); PyTypeObject *type = Py_TYPE(owner); + if (!_PyType_IsReady(type)) { + // We *might* not really need this check, but we inherited it from + // PyObject_GenericSetAttr and friends... and this way we still do the + // right thing if someone forgets to call PyType_Ready(type): + SPECIALIZATION_FAIL(STORE_ATTR, SPEC_FAIL_OTHER); + goto fail; + } if (PyModule_CheckExact(owner)) { SPECIALIZATION_FAIL(STORE_ATTR, SPEC_FAIL_OVERRIDDEN); goto fail; @@ -797,7 +948,7 @@ _Py_Specialize_StoreAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) assert(offset > 0); cache->index = (uint16_t)offset; write_u32(cache->version, type->tp_version_tag); - _Py_SET_OPCODE(*instr, STORE_ATTR_SLOT); + instr->op.code = STORE_ATTR_SLOT; goto success; } case DUNDER_CLASS: @@ -807,83 +958,86 @@ _Py_Specialize_StoreAttr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) case MUTABLE: SPECIALIZATION_FAIL(STORE_ATTR, SPEC_FAIL_ATTR_MUTABLE_CLASS); goto fail; + case GETATTRIBUTE_IS_PYTHON_FUNCTION: case GETSET_OVERRIDDEN: SPECIALIZATION_FAIL(STORE_ATTR, SPEC_FAIL_OVERRIDDEN); goto fail; case BUILTIN_CLASSMETHOD: + SPECIALIZATION_FAIL(STORE_ATTR, SPEC_FAIL_ATTR_BUILTIN_CLASS_METHOD_OBJ); + goto fail; case PYTHON_CLASSMETHOD: + SPECIALIZATION_FAIL(STORE_ATTR, SPEC_FAIL_ATTR_CLASS_METHOD_OBJ); + goto fail; case NON_OVERRIDING: + SPECIALIZATION_FAIL(STORE_ATTR, SPEC_FAIL_ATTR_CLASS_ATTR_DESCRIPTOR); + goto fail; case NON_DESCRIPTOR: + SPECIALIZATION_FAIL(STORE_ATTR, SPEC_FAIL_ATTR_CLASS_ATTR_SIMPLE); + goto fail; case ABSENT: - break; - } - - int err = specialize_dict_access( - owner, instr, type, kind, name, - STORE_ATTR, STORE_ATTR_INSTANCE_VALUE, STORE_ATTR_WITH_HINT - ); - if (err < 0) { - return -1; - } - if (err) { - goto success; + if (specialize_dict_access(owner, instr, type, kind, name, STORE_ATTR, + STORE_ATTR_INSTANCE_VALUE, STORE_ATTR_WITH_HINT)) + { + goto success; + } } fail: STAT_INC(STORE_ATTR, failure); assert(!PyErr_Occurred()); + instr->op.code = STORE_ATTR; cache->counter = adaptive_counter_backoff(cache->counter); - return 0; + return; success: STAT_INC(STORE_ATTR, success); assert(!PyErr_Occurred()); - cache->counter = miss_counter_start(); - return 0; + cache->counter = adaptive_counter_cooldown(); } #ifdef Py_STATS static int -load_method_fail_kind(DescriptorClassification kind) +load_attr_fail_kind(DescriptorClassification kind) { switch (kind) { case OVERRIDING: - return SPEC_FAIL_LOAD_METHOD_OVERRIDING_DESCRIPTOR; + return SPEC_FAIL_ATTR_OVERRIDING_DESCRIPTOR; case METHOD: - return SPEC_FAIL_LOAD_METHOD_METHOD; + return SPEC_FAIL_ATTR_METHOD; case PROPERTY: - return SPEC_FAIL_LOAD_METHOD_PROPERTY; + return SPEC_FAIL_ATTR_PROPERTY; case OBJECT_SLOT: - return SPEC_FAIL_LOAD_METHOD_OBJECT_SLOT; + return SPEC_FAIL_ATTR_OBJECT_SLOT; case OTHER_SLOT: - return SPEC_FAIL_LOAD_METHOD_NON_OBJECT_SLOT; + return SPEC_FAIL_ATTR_NON_OBJECT_SLOT; case DUNDER_CLASS: return SPEC_FAIL_OTHER; case MUTABLE: - return SPEC_FAIL_LOAD_METHOD_MUTABLE_CLASS; + return SPEC_FAIL_ATTR_MUTABLE_CLASS; case GETSET_OVERRIDDEN: + case GETATTRIBUTE_IS_PYTHON_FUNCTION: return SPEC_FAIL_OVERRIDDEN; case BUILTIN_CLASSMETHOD: - return SPEC_FAIL_LOAD_METHOD_BUILTIN_CLASS_METHOD; + return SPEC_FAIL_ATTR_BUILTIN_CLASS_METHOD; case PYTHON_CLASSMETHOD: - return SPEC_FAIL_LOAD_METHOD_CLASS_METHOD_OBJ; + return SPEC_FAIL_ATTR_CLASS_METHOD_OBJ; case NON_OVERRIDING: - return SPEC_FAIL_LOAD_METHOD_NON_OVERRIDING_DESCRIPTOR; + return SPEC_FAIL_ATTR_NON_OVERRIDING_DESCRIPTOR; case NON_DESCRIPTOR: - return SPEC_FAIL_LOAD_METHOD_NOT_DESCRIPTOR; + return SPEC_FAIL_ATTR_NOT_DESCRIPTOR; case ABSENT: - return SPEC_FAIL_LOAD_METHOD_INSTANCE_ATTRIBUTE; + return SPEC_FAIL_ATTR_INSTANCE_ATTRIBUTE; } Py_UNREACHABLE(); } #endif static int -specialize_class_load_method(PyObject *owner, _Py_CODEUNIT *instr, +specialize_class_load_attr(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) { _PyLoadMethodCache *cache = (_PyLoadMethodCache *)(instr + 1); if (!PyType_CheckExact(owner) || _PyType_Lookup(Py_TYPE(owner), name)) { - SPECIALIZATION_FAIL(LOAD_METHOD, SPEC_FAIL_LOAD_METHOD_METACLASS_ATTRIBUTE); + SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_METACLASS_ATTRIBUTE); return -1; } PyObject *descr = NULL; @@ -894,128 +1048,70 @@ specialize_class_load_method(PyObject *owner, _Py_CODEUNIT *instr, case NON_DESCRIPTOR: write_u32(cache->type_version, ((PyTypeObject *)owner)->tp_version_tag); write_obj(cache->descr, descr); - _Py_SET_OPCODE(*instr, LOAD_METHOD_CLASS); + instr->op.code = LOAD_ATTR_CLASS; return 0; #ifdef Py_STATS case ABSENT: - SPECIALIZATION_FAIL(LOAD_METHOD, SPEC_FAIL_EXPECTED_ERROR); + SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_EXPECTED_ERROR); return -1; #endif default: - SPECIALIZATION_FAIL(LOAD_METHOD, load_method_fail_kind(kind)); + SPECIALIZATION_FAIL(LOAD_ATTR, load_attr_fail_kind(kind)); return -1; } } -typedef enum { - MANAGED_VALUES = 1, - MANAGED_DICT = 2, - OFFSET_DICT = 3, - NO_DICT = 4 -} ObjectDictKind; - // Please collect stats carefully before and after modifying. A subtle change // can cause a significant drop in cache hits. A possible test is // python.exe -m test_typing test_re test_dis test_zlib. -int -_Py_Specialize_LoadMethod(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) +static int +specialize_attr_loadmethod(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name, +PyObject *descr, DescriptorClassification kind) { - assert(_PyOpcode_Caches[LOAD_METHOD] == INLINE_CACHE_ENTRIES_LOAD_METHOD); _PyLoadMethodCache *cache = (_PyLoadMethodCache *)(instr + 1); PyTypeObject *owner_cls = Py_TYPE(owner); - if (PyModule_CheckExact(owner)) { - assert(INLINE_CACHE_ENTRIES_LOAD_ATTR <= - INLINE_CACHE_ENTRIES_LOAD_METHOD); - int err = specialize_module_load_attr(owner, instr, name, LOAD_METHOD, - LOAD_METHOD_MODULE); - if (err) { - goto fail; - } - goto success; - } - if (owner_cls->tp_dict == NULL) { - if (PyType_Ready(owner_cls) < 0) { - return -1; - } - } - if (PyType_Check(owner)) { - int err = specialize_class_load_method(owner, instr, name); - if (err) { - goto fail; - } - goto success; - } - - PyObject *descr = NULL; - DescriptorClassification kind = 0; - kind = analyze_descriptor(owner_cls, name, &descr, 0); - assert(descr != NULL || kind == ABSENT || kind == GETSET_OVERRIDDEN); - if (kind != METHOD) { - SPECIALIZATION_FAIL(LOAD_METHOD, load_method_fail_kind(kind)); - goto fail; - } - ObjectDictKind dictkind; - PyDictKeysObject *keys; + assert(kind == METHOD && descr != NULL); if (owner_cls->tp_flags & Py_TPFLAGS_MANAGED_DICT) { - PyObject *dict = *_PyObject_ManagedDictPointer(owner); - keys = ((PyHeapTypeObject *)owner_cls)->ht_cached_keys; - if (dict == NULL) { - dictkind = MANAGED_VALUES; + PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); + PyDictKeysObject *keys = ((PyHeapTypeObject *)owner_cls)->ht_cached_keys; + if (!_PyDictOrValues_IsValues(dorv)) { + SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_HAS_MANAGED_DICT); + return 0; } - else { - dictkind = MANAGED_DICT; + Py_ssize_t index = _PyDictKeys_StringLookup(keys, name); + if (index != DKIX_EMPTY) { + SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_SHADOWED); + return 0; + } + uint32_t keys_version = _PyDictKeys_GetVersionForCurrentState( + _PyInterpreterState_GET(), keys); + if (keys_version == 0) { + SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_OUT_OF_VERSIONS); + return 0; } + write_u32(cache->keys_version, keys_version); + instr->op.code = LOAD_ATTR_METHOD_WITH_VALUES; } else { Py_ssize_t dictoffset = owner_cls->tp_dictoffset; if (dictoffset < 0 || dictoffset > INT16_MAX) { - SPECIALIZATION_FAIL(LOAD_METHOD, SPEC_FAIL_OUT_OF_RANGE); - goto fail; + SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_OUT_OF_RANGE); + return 0; } if (dictoffset == 0) { - dictkind = NO_DICT; - keys = NULL; + instr->op.code = LOAD_ATTR_METHOD_NO_DICT; } else { PyObject *dict = *(PyObject **) ((char *)owner + dictoffset); - if (dict == NULL) { - SPECIALIZATION_FAIL(LOAD_METHOD, SPEC_FAIL_NO_DICT); - goto fail; + if (dict) { + SPECIALIZATION_FAIL(LOAD_ATTR, SPEC_FAIL_ATTR_NOT_MANAGED_DICT); + return 0; } - keys = ((PyDictObject *)dict)->ma_keys; - dictkind = OFFSET_DICT; - } - } - if (dictkind != NO_DICT) { - Py_ssize_t index = _PyDictKeys_StringLookup(keys, name); - if (index != DKIX_EMPTY) { - SPECIALIZATION_FAIL(LOAD_METHOD, SPEC_FAIL_LOAD_METHOD_IS_ATTR); - goto fail; - } - uint32_t keys_version = _PyDictKeys_GetVersionForCurrentState(keys); - if (keys_version == 0) { - SPECIALIZATION_FAIL(LOAD_METHOD, SPEC_FAIL_OUT_OF_VERSIONS); - goto fail; + assert(owner_cls->tp_dictoffset > 0); + assert(owner_cls->tp_dictoffset <= INT16_MAX); + instr->op.code = LOAD_ATTR_METHOD_LAZY_DICT; } - write_u32(cache->keys_version, keys_version); - } - switch(dictkind) { - case NO_DICT: - _Py_SET_OPCODE(*instr, LOAD_METHOD_NO_DICT); - break; - case MANAGED_VALUES: - _Py_SET_OPCODE(*instr, LOAD_METHOD_WITH_VALUES); - break; - case MANAGED_DICT: - *(int16_t *)&cache->dict_offset = (int16_t)MANAGED_DICT_OFFSET; - _Py_SET_OPCODE(*instr, LOAD_METHOD_WITH_DICT); - break; - case OFFSET_DICT: - assert(owner_cls->tp_dictoffset > 0 && owner_cls->tp_dictoffset <= INT16_MAX); - cache->dict_offset = (uint16_t)owner_cls->tp_dictoffset; - _Py_SET_OPCODE(*instr, LOAD_METHOD_WITH_DICT); - break; } /* `descr` is borrowed. This is safe for methods (even inherited ones from * super classes!) as long as tp_version_tag is validated for two main reasons: @@ -1033,29 +1129,21 @@ _Py_Specialize_LoadMethod(PyObject *owner, _Py_CODEUNIT *instr, PyObject *name) */ write_u32(cache->type_version, owner_cls->tp_version_tag); write_obj(cache->descr, descr); - // Fall through. -success: - STAT_INC(LOAD_METHOD, success); - assert(!PyErr_Occurred()); - cache->counter = miss_counter_start(); - return 0; -fail: - STAT_INC(LOAD_METHOD, failure); - assert(!PyErr_Occurred()); - cache->counter = adaptive_counter_backoff(cache->counter); - return 0; + return 1; } -int +void _Py_Specialize_LoadGlobal( PyObject *globals, PyObject *builtins, _Py_CODEUNIT *instr, PyObject *name) { + assert(ENABLE_SPECIALIZATION); assert(_PyOpcode_Caches[LOAD_GLOBAL] == INLINE_CACHE_ENTRIES_LOAD_GLOBAL); /* Use inline cache */ _PyLoadGlobalCache *cache = (_PyLoadGlobalCache *)(instr + 1); assert(PyUnicode_CheckExact(name)); if (!PyDict_CheckExact(globals)) { + SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_LOAD_GLOBAL_NON_DICT); goto fail; } PyDictKeysObject * globals_keys = ((PyDictObject *)globals)->ma_keys; @@ -1065,23 +1153,32 @@ _Py_Specialize_LoadGlobal( } Py_ssize_t index = _PyDictKeys_StringLookup(globals_keys, name); if (index == DKIX_ERROR) { - SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_LOAD_GLOBAL_NON_STRING_OR_SPLIT); + SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_EXPECTED_ERROR); goto fail; } + PyInterpreterState *interp = _PyInterpreterState_GET(); if (index != DKIX_EMPTY) { if (index != (uint16_t)index) { + SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_OUT_OF_RANGE); goto fail; } - uint32_t keys_version = _PyDictKeys_GetVersionForCurrentState(globals_keys); + uint32_t keys_version = _PyDictKeys_GetVersionForCurrentState( + interp, globals_keys); if (keys_version == 0) { + SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_OUT_OF_VERSIONS); + goto fail; + } + if (keys_version != (uint16_t)keys_version) { + SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_OUT_OF_RANGE); goto fail; } cache->index = (uint16_t)index; - write_u32(cache->module_keys_version, keys_version); - _Py_SET_OPCODE(*instr, LOAD_GLOBAL_MODULE); + cache->module_keys_version = (uint16_t)keys_version; + instr->op.code = LOAD_GLOBAL_MODULE; goto success; } if (!PyDict_CheckExact(builtins)) { + SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_LOAD_GLOBAL_NON_DICT); goto fail; } PyDictKeysObject * builtin_keys = ((PyDictObject *)builtins)->ma_keys; @@ -1091,18 +1188,25 @@ _Py_Specialize_LoadGlobal( } index = _PyDictKeys_StringLookup(builtin_keys, name); if (index == DKIX_ERROR) { - SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_LOAD_GLOBAL_NON_STRING_OR_SPLIT); + SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_EXPECTED_ERROR); goto fail; } if (index != (uint16_t)index) { + SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_OUT_OF_RANGE); goto fail; } - uint32_t globals_version = _PyDictKeys_GetVersionForCurrentState(globals_keys); + uint32_t globals_version = _PyDictKeys_GetVersionForCurrentState( + interp, globals_keys); if (globals_version == 0) { SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_OUT_OF_VERSIONS); goto fail; } - uint32_t builtins_version = _PyDictKeys_GetVersionForCurrentState(builtin_keys); + if (globals_version != (uint16_t)globals_version) { + SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_OUT_OF_RANGE); + goto fail; + } + uint32_t builtins_version = _PyDictKeys_GetVersionForCurrentState( + interp, builtin_keys); if (builtins_version == 0) { SPECIALIZATION_FAIL(LOAD_GLOBAL, SPEC_FAIL_OUT_OF_VERSIONS); goto fail; @@ -1112,20 +1216,20 @@ _Py_Specialize_LoadGlobal( goto fail; } cache->index = (uint16_t)index; - write_u32(cache->module_keys_version, globals_version); + cache->module_keys_version = (uint16_t)globals_version; cache->builtin_keys_version = (uint16_t)builtins_version; - _Py_SET_OPCODE(*instr, LOAD_GLOBAL_BUILTIN); + instr->op.code = LOAD_GLOBAL_BUILTIN; goto success; fail: STAT_INC(LOAD_GLOBAL, failure); assert(!PyErr_Occurred()); + instr->op.code = LOAD_GLOBAL; cache->counter = adaptive_counter_backoff(cache->counter); - return 0; + return; success: STAT_INC(LOAD_GLOBAL, success); assert(!PyErr_Occurred()); - cache->counter = miss_counter_start(); - return 0; + cache->counter = adaptive_counter_cooldown(); } #ifdef Py_STATS @@ -1168,33 +1272,68 @@ binary_subscr_fail_kind(PyTypeObject *container_type, PyObject *sub) } #endif - -#define SIMPLE_FUNCTION 0 - static int function_kind(PyCodeObject *code) { int flags = code->co_flags; if ((flags & (CO_VARKEYWORDS | CO_VARARGS)) || code->co_kwonlyargcount) { - return SPEC_FAIL_CALL_COMPLEX_PARAMETERS; + return SPEC_FAIL_CODE_COMPLEX_PARAMETERS; } if ((flags & CO_OPTIMIZED) == 0) { - return SPEC_FAIL_CALL_CO_NOT_OPTIMIZED; + return SPEC_FAIL_CODE_NOT_OPTIMIZED; } return SIMPLE_FUNCTION; } -int +/* Returning false indicates a failure. */ +static bool +function_check_args(PyObject *o, int expected_argcount, int opcode) +{ + assert(Py_IS_TYPE(o, &PyFunction_Type)); + PyFunctionObject *func = (PyFunctionObject *)o; + PyCodeObject *fcode = (PyCodeObject *)func->func_code; + int kind = function_kind(fcode); + if (kind != SIMPLE_FUNCTION) { + SPECIALIZATION_FAIL(opcode, kind); + return false; + } + if (fcode->co_argcount != expected_argcount) { + SPECIALIZATION_FAIL(opcode, SPEC_FAIL_WRONG_NUMBER_ARGUMENTS); + return false; + } + return true; +} + +/* Returning 0 indicates a failure. */ +static uint32_t +function_get_version(PyObject *o, int opcode) +{ + assert(Py_IS_TYPE(o, &PyFunction_Type)); + PyFunctionObject *func = (PyFunctionObject *)o; + uint32_t version = _PyFunction_GetVersionForCurrentState(func); + if (version == 0) { + SPECIALIZATION_FAIL(opcode, SPEC_FAIL_OUT_OF_VERSIONS); + return 0; + } + return version; +} + +void _Py_Specialize_BinarySubscr( PyObject *container, PyObject *sub, _Py_CODEUNIT *instr) { + assert(ENABLE_SPECIALIZATION); assert(_PyOpcode_Caches[BINARY_SUBSCR] == INLINE_CACHE_ENTRIES_BINARY_SUBSCR); _PyBinarySubscrCache *cache = (_PyBinarySubscrCache *)(instr + 1); PyTypeObject *container_type = Py_TYPE(container); if (container_type == &PyList_Type) { if (PyLong_CheckExact(sub)) { - _Py_SET_OPCODE(*instr, BINARY_SUBSCR_LIST_INT); - goto success; + if (_PyLong_IsNonNegativeCompact((PyLongObject *)sub)) { + instr->op.code = BINARY_SUBSCR_LIST_INT; + goto success; + } + SPECIALIZATION_FAIL(BINARY_SUBSCR, SPEC_FAIL_OUT_OF_RANGE); + goto fail; } SPECIALIZATION_FAIL(BINARY_SUBSCR, PySlice_Check(sub) ? SPEC_FAIL_SUBSCR_LIST_SLICE : SPEC_FAIL_OTHER); @@ -1202,15 +1341,19 @@ _Py_Specialize_BinarySubscr( } if (container_type == &PyTuple_Type) { if (PyLong_CheckExact(sub)) { - _Py_SET_OPCODE(*instr, BINARY_SUBSCR_TUPLE_INT); - goto success; + if (_PyLong_IsNonNegativeCompact((PyLongObject *)sub)) { + instr->op.code = BINARY_SUBSCR_TUPLE_INT; + goto success; + } + SPECIALIZATION_FAIL(BINARY_SUBSCR, SPEC_FAIL_OUT_OF_RANGE); + goto fail; } SPECIALIZATION_FAIL(BINARY_SUBSCR, PySlice_Check(sub) ? SPEC_FAIL_SUBSCR_TUPLE_SLICE : SPEC_FAIL_OTHER); goto fail; } if (container_type == &PyDict_Type) { - _Py_SET_OPCODE(*instr, BINARY_SUBSCR_DICT); + instr->op.code = BINARY_SUBSCR_DICT; goto success; } PyTypeObject *cls = Py_TYPE(container); @@ -1231,16 +1374,21 @@ _Py_Specialize_BinarySubscr( SPECIALIZATION_FAIL(BINARY_SUBSCR, SPEC_FAIL_WRONG_NUMBER_ARGUMENTS); goto fail; } - assert(cls->tp_version_tag != 0); - write_u32(cache->type_version, cls->tp_version_tag); - int version = _PyFunction_GetVersionForCurrentState(func); - if (version == 0 || version != (uint16_t)version) { + uint32_t version = _PyFunction_GetVersionForCurrentState(func); + if (version == 0) { SPECIALIZATION_FAIL(BINARY_SUBSCR, SPEC_FAIL_OUT_OF_VERSIONS); goto fail; } - cache->func_version = version; - ((PyHeapTypeObject *)container_type)->_spec_cache.getitem = descriptor; - _Py_SET_OPCODE(*instr, BINARY_SUBSCR_GETITEM); + if (_PyInterpreterState_GET()->eval_frame) { + SPECIALIZATION_FAIL(BINARY_SUBSCR, SPEC_FAIL_OTHER); + goto fail; + } + PyHeapTypeObject *ht = (PyHeapTypeObject *)container_type; + // This pointer is invalidated by PyType_Modified (see the comment on + // struct _specialization_cache): + ht->_spec_cache.getitem = descriptor; + ht->_spec_cache.getitem_version = version; + instr->op.code = BINARY_SUBSCR_GETITEM; goto success; } SPECIALIZATION_FAIL(BINARY_SUBSCR, @@ -1248,26 +1396,27 @@ _Py_Specialize_BinarySubscr( fail: STAT_INC(BINARY_SUBSCR, failure); assert(!PyErr_Occurred()); + instr->op.code = BINARY_SUBSCR; cache->counter = adaptive_counter_backoff(cache->counter); - return 0; + return; success: STAT_INC(BINARY_SUBSCR, success); assert(!PyErr_Occurred()); - cache->counter = miss_counter_start(); - return 0; + cache->counter = adaptive_counter_cooldown(); } -int +void _Py_Specialize_StoreSubscr(PyObject *container, PyObject *sub, _Py_CODEUNIT *instr) { + assert(ENABLE_SPECIALIZATION); _PyStoreSubscrCache *cache = (_PyStoreSubscrCache *)(instr + 1); PyTypeObject *container_type = Py_TYPE(container); if (container_type == &PyList_Type) { if (PyLong_CheckExact(sub)) { - if ((Py_SIZE(sub) == 0 || Py_SIZE(sub) == 1) - && ((PyLongObject *)sub)->ob_digit[0] < (size_t)PyList_GET_SIZE(container)) + if (_PyLong_IsNonNegativeCompact((PyLongObject *)sub) + && ((PyLongObject *)sub)->long_value.ob_digit[0] < (size_t)PyList_GET_SIZE(container)) { - _Py_SET_OPCODE(*instr, STORE_SUBSCR_LIST_INT); + instr->op.code = STORE_SUBSCR_LIST_INT; goto success; } else { @@ -1285,8 +1434,8 @@ _Py_Specialize_StoreSubscr(PyObject *container, PyObject *sub, _Py_CODEUNIT *ins } } if (container_type == &PyDict_Type) { - _Py_SET_OPCODE(*instr, STORE_SUBSCR_DICT); - goto success; + instr->op.code = STORE_SUBSCR_DICT; + goto success; } #ifdef Py_STATS PyMappingMethods *as_mapping = container_type->tp_as_mapping; @@ -1296,7 +1445,7 @@ _Py_Specialize_StoreSubscr(PyObject *container, PyObject *sub, _Py_CODEUNIT *ins goto fail; } if (PyObject_CheckBuffer(container)) { - if (PyLong_CheckExact(sub) && (((size_t)Py_SIZE(sub)) > 1)) { + if (PyLong_CheckExact(sub) && (!_PyLong_IsNonNegativeCompact((PyLongObject *)sub))) { SPECIALIZATION_FAIL(STORE_SUBSCR, SPEC_FAIL_OUT_OF_RANGE); } else if (strcmp(container_type->tp_name, "array.array") == 0) { @@ -1352,49 +1501,49 @@ _Py_Specialize_StoreSubscr(PyObject *container, PyObject *sub, _Py_CODEUNIT *ins fail: STAT_INC(STORE_SUBSCR, failure); assert(!PyErr_Occurred()); + instr->op.code = STORE_SUBSCR; cache->counter = adaptive_counter_backoff(cache->counter); - return 0; + return; success: STAT_INC(STORE_SUBSCR, success); assert(!PyErr_Occurred()); - cache->counter = miss_counter_start(); - return 0; + cache->counter = adaptive_counter_cooldown(); } static int specialize_class_call(PyObject *callable, _Py_CODEUNIT *instr, int nargs, - PyObject *kwnames, int oparg) + PyObject *kwnames) { - assert(_Py_OPCODE(*instr) == PRECALL_ADAPTIVE); PyTypeObject *tp = _PyType_CAST(callable); if (tp->tp_new == PyBaseObject_Type.tp_new) { - SPECIALIZATION_FAIL(PRECALL, SPEC_FAIL_CALL_PYTHON_CLASS); + SPECIALIZATION_FAIL(CALL, SPEC_FAIL_CALL_PYTHON_CLASS); return -1; } if (tp->tp_flags & Py_TPFLAGS_IMMUTABLETYPE) { + int oparg = instr->op.arg; if (nargs == 1 && kwnames == NULL && oparg == 1) { if (tp == &PyUnicode_Type) { - _Py_SET_OPCODE(*instr, PRECALL_NO_KW_STR_1); + instr->op.code = CALL_NO_KW_STR_1; return 0; } else if (tp == &PyType_Type) { - _Py_SET_OPCODE(*instr, PRECALL_NO_KW_TYPE_1); + instr->op.code = CALL_NO_KW_TYPE_1; return 0; } else if (tp == &PyTuple_Type) { - _Py_SET_OPCODE(*instr, PRECALL_NO_KW_TUPLE_1); + instr->op.code = CALL_NO_KW_TUPLE_1; return 0; } } if (tp->tp_vectorcall != NULL) { - _Py_SET_OPCODE(*instr, PRECALL_BUILTIN_CLASS); + instr->op.code = CALL_BUILTIN_CLASS; return 0; } - SPECIALIZATION_FAIL(PRECALL, tp == &PyUnicode_Type ? + SPECIALIZATION_FAIL(CALL, tp == &PyUnicode_Type ? SPEC_FAIL_CALL_STR : SPEC_FAIL_CALL_CLASS_NO_VECTORCALL); return -1; } - SPECIALIZATION_FAIL(PRECALL, SPEC_FAIL_CALL_CLASS_MUTABLE); + SPECIALIZATION_FAIL(CALL, SPEC_FAIL_CALL_CLASS_MUTABLE); return -1; } @@ -1405,17 +1554,40 @@ builtin_call_fail_kind(int ml_flags) switch (ml_flags & (METH_VARARGS | METH_FASTCALL | METH_NOARGS | METH_O | METH_KEYWORDS | METH_METHOD)) { case METH_VARARGS: - return SPEC_FAIL_CALL_PYCFUNCTION; + return SPEC_FAIL_CALL_CFUNC_VARARGS; case METH_VARARGS | METH_KEYWORDS: - return SPEC_FAIL_CALL_PYCFUNCTION_WITH_KEYWORDS; - case METH_FASTCALL | METH_KEYWORDS: - return SPEC_FAIL_CALL_PYCFUNCTION_FAST_WITH_KEYWORDS; + return SPEC_FAIL_CALL_CFUNC_VARARGS_KEYWORDS; case METH_NOARGS: - return SPEC_FAIL_CALL_PYCFUNCTION_NOARGS; - /* This case should never happen with PyCFunctionObject -- only - PyMethodObject. See zlib.compressobj()'s methods for an example. - */ + return SPEC_FAIL_CALL_CFUNC_NOARGS; case METH_METHOD | METH_FASTCALL | METH_KEYWORDS: + return SPEC_FAIL_CALL_CFUNC_METHOD_FASTCALL_KEYWORDS; + /* These cases should be optimized, but return "other" just in case */ + case METH_O: + case METH_FASTCALL: + case METH_FASTCALL | METH_KEYWORDS: + return SPEC_FAIL_OTHER; + default: + return SPEC_FAIL_CALL_BAD_CALL_FLAGS; + } +} + +static int +meth_descr_call_fail_kind(int ml_flags) +{ + switch (ml_flags & (METH_VARARGS | METH_FASTCALL | METH_NOARGS | METH_O | + METH_KEYWORDS | METH_METHOD)) { + case METH_VARARGS: + return SPEC_FAIL_CALL_METH_DESCR_VARARGS; + case METH_VARARGS | METH_KEYWORDS: + return SPEC_FAIL_CALL_METH_DESCR_VARARGS_KEYWORDS; + case METH_METHOD | METH_FASTCALL | METH_KEYWORDS: + return SPEC_FAIL_CALL_METH_DESCR_METHOD_FASTCALL_KEYWORDS; + /* These cases should be optimized, but return "other" just in case */ + case METH_NOARGS: + case METH_O: + case METH_FASTCALL: + case METH_FASTCALL | METH_KEYWORDS: + return SPEC_FAIL_OTHER; default: return SPEC_FAIL_CALL_BAD_CALL_FLAGS; } @@ -1424,11 +1596,10 @@ builtin_call_fail_kind(int ml_flags) static int specialize_method_descriptor(PyMethodDescrObject *descr, _Py_CODEUNIT *instr, - int nargs, PyObject *kwnames, int oparg) + int nargs, PyObject *kwnames) { - assert(_Py_OPCODE(*instr) == PRECALL_ADAPTIVE); if (kwnames) { - SPECIALIZATION_FAIL(PRECALL, SPEC_FAIL_CALL_KWNAMES); + SPECIALIZATION_FAIL(CALL, SPEC_FAIL_CALL_KWNAMES); return -1; } @@ -1437,48 +1608,47 @@ specialize_method_descriptor(PyMethodDescrObject *descr, _Py_CODEUNIT *instr, METH_KEYWORDS | METH_METHOD)) { case METH_NOARGS: { if (nargs != 1) { - SPECIALIZATION_FAIL(PRECALL, SPEC_FAIL_WRONG_NUMBER_ARGUMENTS); + SPECIALIZATION_FAIL(CALL, SPEC_FAIL_WRONG_NUMBER_ARGUMENTS); return -1; } - _Py_SET_OPCODE(*instr, PRECALL_NO_KW_METHOD_DESCRIPTOR_NOARGS); + instr->op.code = CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS; return 0; } case METH_O: { if (nargs != 2) { - SPECIALIZATION_FAIL(PRECALL, SPEC_FAIL_WRONG_NUMBER_ARGUMENTS); + SPECIALIZATION_FAIL(CALL, SPEC_FAIL_WRONG_NUMBER_ARGUMENTS); return -1; } PyInterpreterState *interp = _PyInterpreterState_GET(); PyObject *list_append = interp->callable_cache.list_append; - _Py_CODEUNIT next = instr[INLINE_CACHE_ENTRIES_PRECALL + 1 - + INLINE_CACHE_ENTRIES_CALL + 1]; - bool pop = (_Py_OPCODE(next) == POP_TOP); + _Py_CODEUNIT next = instr[INLINE_CACHE_ENTRIES_CALL + 1]; + bool pop = (next.op.code == POP_TOP); + int oparg = instr->op.arg; if ((PyObject *)descr == list_append && oparg == 1 && pop) { - _Py_SET_OPCODE(*instr, PRECALL_NO_KW_LIST_APPEND); + instr->op.code = CALL_NO_KW_LIST_APPEND; return 0; } - _Py_SET_OPCODE(*instr, PRECALL_NO_KW_METHOD_DESCRIPTOR_O); + instr->op.code = CALL_NO_KW_METHOD_DESCRIPTOR_O; return 0; } case METH_FASTCALL: { - _Py_SET_OPCODE(*instr, PRECALL_NO_KW_METHOD_DESCRIPTOR_FAST); + instr->op.code = CALL_NO_KW_METHOD_DESCRIPTOR_FAST; return 0; } - case METH_FASTCALL|METH_KEYWORDS: { - _Py_SET_OPCODE(*instr, PRECALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS); + case METH_FASTCALL | METH_KEYWORDS: { + instr->op.code = CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS; return 0; } } - SPECIALIZATION_FAIL(PRECALL, builtin_call_fail_kind(descr->d_method->ml_flags)); + SPECIALIZATION_FAIL(CALL, meth_descr_call_fail_kind(descr->d_method->ml_flags)); return -1; } static int specialize_py_call(PyFunctionObject *func, _Py_CODEUNIT *instr, int nargs, - PyObject *kwnames) + PyObject *kwnames, bool bound_method) { _PyCallCache *cache = (_PyCallCache *)(instr + 1); - assert(_Py_OPCODE(*instr) == CALL_ADAPTIVE); PyCodeObject *code = (PyCodeObject *)func->func_code; int kind = function_kind(code); /* Don't specialize if PEP 523 is active */ @@ -1496,31 +1666,30 @@ specialize_py_call(PyFunctionObject *func, _Py_CODEUNIT *instr, int nargs, } int argcount = code->co_argcount; int defcount = func->func_defaults == NULL ? 0 : (int)PyTuple_GET_SIZE(func->func_defaults); - assert(defcount <= argcount); int min_args = argcount-defcount; - if (nargs > argcount || nargs < min_args) { + // GH-105840: min_args is negative when somebody sets too many __defaults__! + if (min_args < 0 || nargs > argcount || nargs < min_args) { SPECIALIZATION_FAIL(CALL, SPEC_FAIL_WRONG_NUMBER_ARGUMENTS); return -1; } assert(nargs <= argcount && nargs >= min_args); assert(min_args >= 0 && defcount >= 0); assert(defcount == 0 || func->func_defaults != NULL); - if (min_args > 0xffff) { - SPECIALIZATION_FAIL(CALL, SPEC_FAIL_OUT_OF_RANGE); - return -1; - } int version = _PyFunction_GetVersionForCurrentState(func); if (version == 0) { SPECIALIZATION_FAIL(CALL, SPEC_FAIL_OUT_OF_VERSIONS); return -1; } write_u32(cache->func_version, version); - cache->min_args = min_args; if (argcount == nargs) { - _Py_SET_OPCODE(*instr, CALL_PY_EXACT_ARGS); + instr->op.code = bound_method ? CALL_BOUND_METHOD_EXACT_ARGS : CALL_PY_EXACT_ARGS; + } + else if (bound_method) { + SPECIALIZATION_FAIL(CALL, SPEC_FAIL_CALL_BOUND_METHOD); + return -1; } else { - _Py_SET_OPCODE(*instr, CALL_PY_WITH_DEFAULTS); + instr->op.code = CALL_PY_WITH_DEFAULTS; } return 0; } @@ -1529,7 +1698,6 @@ static int specialize_c_call(PyObject *callable, _Py_CODEUNIT *instr, int nargs, PyObject *kwnames) { - assert(_Py_OPCODE(*instr) == PRECALL_ADAPTIVE); if (PyCFunction_GET_FUNCTION(callable) == NULL) { return 1; } @@ -1538,44 +1706,44 @@ specialize_c_call(PyObject *callable, _Py_CODEUNIT *instr, int nargs, METH_KEYWORDS | METH_METHOD)) { case METH_O: { if (kwnames) { - SPECIALIZATION_FAIL(PRECALL, SPEC_FAIL_CALL_KWNAMES); + SPECIALIZATION_FAIL(CALL, SPEC_FAIL_CALL_KWNAMES); return -1; } if (nargs != 1) { - SPECIALIZATION_FAIL(PRECALL, SPEC_FAIL_WRONG_NUMBER_ARGUMENTS); + SPECIALIZATION_FAIL(CALL, SPEC_FAIL_WRONG_NUMBER_ARGUMENTS); return 1; } /* len(o) */ PyInterpreterState *interp = _PyInterpreterState_GET(); if (callable == interp->callable_cache.len) { - _Py_SET_OPCODE(*instr, PRECALL_NO_KW_LEN); + instr->op.code = CALL_NO_KW_LEN; return 0; } - _Py_SET_OPCODE(*instr, PRECALL_NO_KW_BUILTIN_O); + instr->op.code = CALL_NO_KW_BUILTIN_O; return 0; } case METH_FASTCALL: { if (kwnames) { - SPECIALIZATION_FAIL(PRECALL, SPEC_FAIL_CALL_KWNAMES); + SPECIALIZATION_FAIL(CALL, SPEC_FAIL_CALL_KWNAMES); return -1; } if (nargs == 2) { /* isinstance(o1, o2) */ PyInterpreterState *interp = _PyInterpreterState_GET(); if (callable == interp->callable_cache.isinstance) { - _Py_SET_OPCODE(*instr, PRECALL_NO_KW_ISINSTANCE); + instr->op.code = CALL_NO_KW_ISINSTANCE; return 0; } } - _Py_SET_OPCODE(*instr, PRECALL_NO_KW_BUILTIN_FAST); + instr->op.code = CALL_NO_KW_BUILTIN_FAST; return 0; } case METH_FASTCALL | METH_KEYWORDS: { - _Py_SET_OPCODE(*instr, PRECALL_BUILTIN_FAST_WITH_KEYWORDS); + instr->op.code = CALL_BUILTIN_FAST_WITH_KEYWORDS; return 0; } default: - SPECIALIZATION_FAIL(PRECALL, + SPECIALIZATION_FAIL(CALL, builtin_call_fail_kind(PyCFunction_GET_FLAGS(callable))); return 1; } @@ -1585,33 +1753,18 @@ specialize_c_call(PyObject *callable, _Py_CODEUNIT *instr, int nargs, static int call_fail_kind(PyObject *callable) { - if (PyCFunction_CheckExact(callable)) { - return SPEC_FAIL_CALL_PYCFUNCTION; - } - else if (PyFunction_Check(callable)) { - return SPEC_FAIL_CALL_PYFUNCTION; - } - else if (PyInstanceMethod_Check(callable)) { + assert(!PyCFunction_CheckExact(callable)); + assert(!PyFunction_Check(callable)); + assert(!PyType_Check(callable)); + assert(!Py_IS_TYPE(callable, &PyMethodDescr_Type)); + assert(!PyMethod_Check(callable)); + if (PyInstanceMethod_Check(callable)) { return SPEC_FAIL_CALL_INSTANCE_METHOD; } - else if (PyMethod_Check(callable)) { - return SPEC_FAIL_CALL_BOUND_METHOD; - } // builtin method else if (PyCMethod_Check(callable)) { return SPEC_FAIL_CALL_CMETHOD; } - else if (PyType_Check(callable)) { - if (((PyTypeObject *)callable)->tp_new == PyBaseObject_Type.tp_new) { - return SPEC_FAIL_CALL_PYTHON_CLASS; - } - else { - return SPEC_FAIL_CALL_CLASS; - } - } - else if (Py_IS_TYPE(callable, &PyMethodDescr_Type)) { - return SPEC_FAIL_CALL_METHOD_DESCRIPTOR; - } else if (Py_TYPE(callable) == &PyWrapperDescr_Type) { return SPEC_FAIL_CALL_OPERATOR_WRAPPER; } @@ -1623,62 +1776,41 @@ call_fail_kind(PyObject *callable) #endif -int -_Py_Specialize_Precall(PyObject *callable, _Py_CODEUNIT *instr, int nargs, - PyObject *kwnames, int oparg) +/* TODO: + - Specialize calling classes. +*/ +void +_Py_Specialize_Call(PyObject *callable, _Py_CODEUNIT *instr, int nargs, + PyObject *kwnames) { - assert(_PyOpcode_Caches[PRECALL] == INLINE_CACHE_ENTRIES_PRECALL); - _PyPrecallCache *cache = (_PyPrecallCache *)(instr + 1); + assert(ENABLE_SPECIALIZATION); + assert(_PyOpcode_Caches[CALL] == INLINE_CACHE_ENTRIES_CALL); + assert(_Py_OPCODE(*instr) != INSTRUMENTED_CALL); + _PyCallCache *cache = (_PyCallCache *)(instr + 1); int fail; if (PyCFunction_CheckExact(callable)) { fail = specialize_c_call(callable, instr, nargs, kwnames); } else if (PyFunction_Check(callable)) { - _Py_SET_OPCODE(*instr, PRECALL_PYFUNC); - fail = 0; + fail = specialize_py_call((PyFunctionObject *)callable, instr, nargs, + kwnames, false); } else if (PyType_Check(callable)) { - fail = specialize_class_call(callable, instr, nargs, kwnames, oparg); + fail = specialize_class_call(callable, instr, nargs, kwnames); } else if (Py_IS_TYPE(callable, &PyMethodDescr_Type)) { fail = specialize_method_descriptor((PyMethodDescrObject *)callable, - instr, nargs, kwnames, oparg); - } - else if (Py_TYPE(callable) == &PyMethod_Type) { - _Py_SET_OPCODE(*instr, PRECALL_BOUND_METHOD); - fail = 0; + instr, nargs, kwnames); } - else { - SPECIALIZATION_FAIL(PRECALL, call_fail_kind(callable)); - fail = -1; - } - if (fail) { - STAT_INC(PRECALL, failure); - assert(!PyErr_Occurred()); - cache->counter = adaptive_counter_backoff(cache->counter); - } - else { - STAT_INC(PRECALL, success); - assert(!PyErr_Occurred()); - cache->counter = miss_counter_start(); - } - return 0; -} - - -/* TODO: - - Specialize calling classes. -*/ -int -_Py_Specialize_Call(PyObject *callable, _Py_CODEUNIT *instr, int nargs, - PyObject *kwnames) -{ - assert(_PyOpcode_Caches[CALL] == INLINE_CACHE_ENTRIES_CALL); - _PyCallCache *cache = (_PyCallCache *)(instr + 1); - int fail; - if (PyFunction_Check(callable)) { - fail = specialize_py_call((PyFunctionObject *)callable, instr, nargs, - kwnames); + else if (PyMethod_Check(callable)) { + PyObject *func = ((PyMethodObject *)callable)->im_func; + if (PyFunction_Check(func)) { + fail = specialize_py_call((PyFunctionObject *)func, + instr, nargs+1, kwnames, true); + } else { + SPECIALIZATION_FAIL(CALL, SPEC_FAIL_CALL_BOUND_METHOD); + fail = -1; + } } else { SPECIALIZATION_FAIL(CALL, call_fail_kind(callable)); @@ -1687,14 +1819,14 @@ _Py_Specialize_Call(PyObject *callable, _Py_CODEUNIT *instr, int nargs, if (fail) { STAT_INC(CALL, failure); assert(!PyErr_Occurred()); + instr->op.code = CALL; cache->counter = adaptive_counter_backoff(cache->counter); } else { STAT_INC(CALL, success); assert(!PyErr_Occurred()); - cache->counter = miss_counter_start(); + cache->counter = adaptive_counter_cooldown(); } - return 0; } #ifdef Py_STATS @@ -1771,6 +1903,7 @@ void _Py_Specialize_BinaryOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr, int oparg, PyObject **locals) { + assert(ENABLE_SPECIALIZATION); assert(_PyOpcode_Caches[BINARY_OP] == INLINE_CACHE_ENTRIES_BINARY_OP); _PyBinaryOpCache *cache = (_PyBinaryOpCache *)(instr + 1); switch (oparg) { @@ -1781,21 +1914,21 @@ _Py_Specialize_BinaryOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr, } if (PyUnicode_CheckExact(lhs)) { _Py_CODEUNIT next = instr[INLINE_CACHE_ENTRIES_BINARY_OP + 1]; - bool to_store = (_Py_OPCODE(next) == STORE_FAST || - _Py_OPCODE(next) == STORE_FAST__LOAD_FAST); - if (to_store && locals[_Py_OPARG(next)] == lhs) { - _Py_SET_OPCODE(*instr, BINARY_OP_INPLACE_ADD_UNICODE); + bool to_store = (next.op.code == STORE_FAST || + next.op.code == STORE_FAST__LOAD_FAST); + if (to_store && locals[next.op.arg] == lhs) { + instr->op.code = BINARY_OP_INPLACE_ADD_UNICODE; goto success; } - _Py_SET_OPCODE(*instr, BINARY_OP_ADD_UNICODE); + instr->op.code = BINARY_OP_ADD_UNICODE; goto success; } if (PyLong_CheckExact(lhs)) { - _Py_SET_OPCODE(*instr, BINARY_OP_ADD_INT); + instr->op.code = BINARY_OP_ADD_INT; goto success; } if (PyFloat_CheckExact(lhs)) { - _Py_SET_OPCODE(*instr, BINARY_OP_ADD_FLOAT); + instr->op.code = BINARY_OP_ADD_FLOAT; goto success; } break; @@ -1805,11 +1938,11 @@ _Py_Specialize_BinaryOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr, break; } if (PyLong_CheckExact(lhs)) { - _Py_SET_OPCODE(*instr, BINARY_OP_MULTIPLY_INT); + instr->op.code = BINARY_OP_MULTIPLY_INT; goto success; } if (PyFloat_CheckExact(lhs)) { - _Py_SET_OPCODE(*instr, BINARY_OP_MULTIPLY_FLOAT); + instr->op.code = BINARY_OP_MULTIPLY_FLOAT; goto success; } break; @@ -1819,32 +1952,23 @@ _Py_Specialize_BinaryOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr, break; } if (PyLong_CheckExact(lhs)) { - _Py_SET_OPCODE(*instr, BINARY_OP_SUBTRACT_INT); + instr->op.code = BINARY_OP_SUBTRACT_INT; goto success; } if (PyFloat_CheckExact(lhs)) { - _Py_SET_OPCODE(*instr, BINARY_OP_SUBTRACT_FLOAT); + instr->op.code = BINARY_OP_SUBTRACT_FLOAT; goto success; } break; -#ifndef Py_STATS - default: - // These operators don't have any available specializations. Rather - // than repeatedly attempting to specialize them, just convert them - // back to BINARY_OP (unless we're collecting stats, where it's more - // important to get accurate hit counts for the unadaptive version - // and each of the different failure types): - _Py_SET_OPCODE(*instr, BINARY_OP); - return; -#endif } SPECIALIZATION_FAIL(BINARY_OP, binary_op_fail_kind(oparg, lhs, rhs)); STAT_INC(BINARY_OP, failure); + instr->op.code = BINARY_OP; cache->counter = adaptive_counter_backoff(cache->counter); return; success: STAT_INC(BINARY_OP, success); - cache->counter = miss_counter_start(); + cache->counter = adaptive_counter_cooldown(); } @@ -1883,69 +2007,24 @@ compare_op_fail_kind(PyObject *lhs, PyObject *rhs) } #endif - -static int compare_masks[] = { - // 1-bit: jump if less than - // 2-bit: jump if equal - // 4-bit: jump if greater - [Py_LT] = 1 | 0 | 0, - [Py_LE] = 1 | 2 | 0, - [Py_EQ] = 0 | 2 | 0, - [Py_NE] = 1 | 0 | 4, - [Py_GT] = 0 | 0 | 4, - [Py_GE] = 0 | 2 | 4, -}; - void _Py_Specialize_CompareOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr, int oparg) { + assert(ENABLE_SPECIALIZATION); assert(_PyOpcode_Caches[COMPARE_OP] == INLINE_CACHE_ENTRIES_COMPARE_OP); _PyCompareOpCache *cache = (_PyCompareOpCache *)(instr + 1); - int next_opcode = _Py_OPCODE(instr[INLINE_CACHE_ENTRIES_COMPARE_OP + 1]); - if (next_opcode != POP_JUMP_FORWARD_IF_FALSE && - next_opcode != POP_JUMP_BACKWARD_IF_FALSE && - next_opcode != POP_JUMP_FORWARD_IF_TRUE && - next_opcode != POP_JUMP_BACKWARD_IF_TRUE) { - // Can't ever combine, so don't don't bother being adaptive (unless - // we're collecting stats, where it's more important to get accurate hit - // counts for the unadaptive version and each of the different failure - // types): -#ifndef Py_STATS - _Py_SET_OPCODE(*instr, COMPARE_OP); - return; -#else - if (next_opcode == EXTENDED_ARG) { - SPECIALIZATION_FAIL(COMPARE_OP, SPEC_FAIL_COMPARE_OP_EXTENDED_ARG); - goto failure; - } - SPECIALIZATION_FAIL(COMPARE_OP, SPEC_FAIL_COMPARE_OP_NOT_FOLLOWED_BY_COND_JUMP); - goto failure; -#endif - } - assert(oparg <= Py_GE); - int when_to_jump_mask = compare_masks[oparg]; - if (next_opcode == POP_JUMP_FORWARD_IF_FALSE || - next_opcode == POP_JUMP_BACKWARD_IF_FALSE) { - when_to_jump_mask = (1 | 2 | 4) & ~when_to_jump_mask; - } - if (next_opcode == POP_JUMP_BACKWARD_IF_TRUE || - next_opcode == POP_JUMP_BACKWARD_IF_FALSE) { - when_to_jump_mask <<= 3; - } if (Py_TYPE(lhs) != Py_TYPE(rhs)) { SPECIALIZATION_FAIL(COMPARE_OP, compare_op_fail_kind(lhs, rhs)); goto failure; } if (PyFloat_CheckExact(lhs)) { - _Py_SET_OPCODE(*instr, COMPARE_OP_FLOAT_JUMP); - cache->mask = when_to_jump_mask; + instr->op.code = COMPARE_OP_FLOAT; goto success; } if (PyLong_CheckExact(lhs)) { - if (Py_ABS(Py_SIZE(lhs)) <= 1 && Py_ABS(Py_SIZE(rhs)) <= 1) { - _Py_SET_OPCODE(*instr, COMPARE_OP_INT_JUMP); - cache->mask = when_to_jump_mask; + if (_PyLong_IsCompact((PyLongObject *)lhs) && _PyLong_IsCompact((PyLongObject *)rhs)) { + instr->op.code = COMPARE_OP_INT; goto success; } else { @@ -1954,24 +2033,25 @@ _Py_Specialize_CompareOp(PyObject *lhs, PyObject *rhs, _Py_CODEUNIT *instr, } } if (PyUnicode_CheckExact(lhs)) { - if (oparg != Py_EQ && oparg != Py_NE) { + int cmp = oparg >> 4; + if (cmp != Py_EQ && cmp != Py_NE) { SPECIALIZATION_FAIL(COMPARE_OP, SPEC_FAIL_COMPARE_OP_STRING); goto failure; } else { - _Py_SET_OPCODE(*instr, COMPARE_OP_STR_JUMP); - cache->mask = when_to_jump_mask; + instr->op.code = COMPARE_OP_STR; goto success; } } SPECIALIZATION_FAIL(COMPARE_OP, compare_op_fail_kind(lhs, rhs)); failure: STAT_INC(COMPARE_OP, failure); + instr->op.code = COMPARE_OP; cache->counter = adaptive_counter_backoff(cache->counter); return; success: STAT_INC(COMPARE_OP, success); - cache->counter = miss_counter_start(); + cache->counter = adaptive_counter_cooldown(); } #ifdef Py_STATS @@ -1991,6 +2071,7 @@ unpack_sequence_fail_kind(PyObject *seq) void _Py_Specialize_UnpackSequence(PyObject *seq, _Py_CODEUNIT *instr, int oparg) { + assert(ENABLE_SPECIALIZATION); assert(_PyOpcode_Caches[UNPACK_SEQUENCE] == INLINE_CACHE_ENTRIES_UNPACK_SEQUENCE); _PyUnpackSequenceCache *cache = (_PyUnpackSequenceCache *)(instr + 1); @@ -2000,10 +2081,10 @@ _Py_Specialize_UnpackSequence(PyObject *seq, _Py_CODEUNIT *instr, int oparg) goto failure; } if (PyTuple_GET_SIZE(seq) == 2) { - _Py_SET_OPCODE(*instr, UNPACK_SEQUENCE_TWO_TUPLE); + instr->op.code = UNPACK_SEQUENCE_TWO_TUPLE; goto success; } - _Py_SET_OPCODE(*instr, UNPACK_SEQUENCE_TUPLE); + instr->op.code = UNPACK_SEQUENCE_TUPLE; goto success; } if (PyList_CheckExact(seq)) { @@ -2011,17 +2092,18 @@ _Py_Specialize_UnpackSequence(PyObject *seq, _Py_CODEUNIT *instr, int oparg) SPECIALIZATION_FAIL(UNPACK_SEQUENCE, SPEC_FAIL_EXPECTED_ERROR); goto failure; } - _Py_SET_OPCODE(*instr, UNPACK_SEQUENCE_LIST); + instr->op.code = UNPACK_SEQUENCE_LIST; goto success; } SPECIALIZATION_FAIL(UNPACK_SEQUENCE, unpack_sequence_fail_kind(seq)); failure: STAT_INC(UNPACK_SEQUENCE, failure); + instr->op.code = UNPACK_SEQUENCE; cache->counter = adaptive_counter_backoff(cache->counter); return; success: STAT_INC(UNPACK_SEQUENCE, success); - cache->counter = miss_counter_start(); + cache->counter = adaptive_counter_cooldown(); } #ifdef Py_STATS @@ -2030,50 +2112,140 @@ int _PySpecialization_ClassifyIterator(PyObject *iter) { if (PyGen_CheckExact(iter)) { - return SPEC_FAIL_FOR_ITER_GENERATOR; + return SPEC_FAIL_ITER_GENERATOR; } if (PyCoro_CheckExact(iter)) { - return SPEC_FAIL_FOR_ITER_COROUTINE; + return SPEC_FAIL_ITER_COROUTINE; } if (PyAsyncGen_CheckExact(iter)) { - return SPEC_FAIL_FOR_ITER_ASYNC_GENERATOR; + return SPEC_FAIL_ITER_ASYNC_GENERATOR; + } + if (PyAsyncGenASend_CheckExact(iter)) { + return SPEC_FAIL_ITER_ASYNC_GENERATOR_SEND; } PyTypeObject *t = Py_TYPE(iter); if (t == &PyListIter_Type) { - return SPEC_FAIL_FOR_ITER_LIST; + return SPEC_FAIL_ITER_LIST; } if (t == &PyTupleIter_Type) { - return SPEC_FAIL_FOR_ITER_TUPLE; + return SPEC_FAIL_ITER_TUPLE; } if (t == &PyDictIterKey_Type) { - return SPEC_FAIL_FOR_ITER_DICT_KEYS; + return SPEC_FAIL_ITER_DICT_KEYS; } if (t == &PyDictIterValue_Type) { - return SPEC_FAIL_FOR_ITER_DICT_VALUES; + return SPEC_FAIL_ITER_DICT_VALUES; } if (t == &PyDictIterItem_Type) { - return SPEC_FAIL_FOR_ITER_DICT_ITEMS; + return SPEC_FAIL_ITER_DICT_ITEMS; } if (t == &PySetIter_Type) { - return SPEC_FAIL_FOR_ITER_SET; + return SPEC_FAIL_ITER_SET; } if (t == &PyUnicodeIter_Type) { - return SPEC_FAIL_FOR_ITER_STRING; + return SPEC_FAIL_ITER_STRING; } if (t == &PyBytesIter_Type) { - return SPEC_FAIL_FOR_ITER_BYTES; + return SPEC_FAIL_ITER_BYTES; } if (t == &PyRangeIter_Type) { - return SPEC_FAIL_FOR_ITER_RANGE; + return SPEC_FAIL_ITER_RANGE; } if (t == &PyEnum_Type) { - return SPEC_FAIL_FOR_ITER_ENUMERATE; + return SPEC_FAIL_ITER_ENUMERATE; } - - if (strncmp(t->tp_name, "itertools", 8) == 0) { - return SPEC_FAIL_FOR_ITER_ITERTOOLS; + if (t == &PyMap_Type) { + return SPEC_FAIL_ITER_MAP; + } + if (t == &PyZip_Type) { + return SPEC_FAIL_ITER_ZIP; + } + if (t == &PySeqIter_Type) { + return SPEC_FAIL_ITER_SEQ_ITER; + } + if (t == &PyListRevIter_Type) { + return SPEC_FAIL_ITER_REVERSED_LIST; + } + if (t == &_PyUnicodeASCIIIter_Type) { + return SPEC_FAIL_ITER_ASCII_STRING; + } + const char *name = t->tp_name; + if (strncmp(name, "itertools", 9) == 0) { + return SPEC_FAIL_ITER_ITERTOOLS; + } + if (strncmp(name, "callable_iterator", 17) == 0) { + return SPEC_FAIL_ITER_CALLABLE; } return SPEC_FAIL_OTHER; } #endif + +void +_Py_Specialize_ForIter(PyObject *iter, _Py_CODEUNIT *instr, int oparg) +{ + assert(ENABLE_SPECIALIZATION); + assert(_PyOpcode_Caches[FOR_ITER] == INLINE_CACHE_ENTRIES_FOR_ITER); + _PyForIterCache *cache = (_PyForIterCache *)(instr + 1); + PyTypeObject *tp = Py_TYPE(iter); + if (tp == &PyListIter_Type) { + instr->op.code = FOR_ITER_LIST; + goto success; + } + else if (tp == &PyTupleIter_Type) { + instr->op.code = FOR_ITER_TUPLE; + goto success; + } + else if (tp == &PyRangeIter_Type) { + instr->op.code = FOR_ITER_RANGE; + goto success; + } + else if (tp == &PyGen_Type && oparg <= SHRT_MAX) { + assert(instr[oparg + INLINE_CACHE_ENTRIES_FOR_ITER + 1].op.code == END_FOR || + instr[oparg + INLINE_CACHE_ENTRIES_FOR_ITER + 1].op.code == INSTRUMENTED_END_FOR + ); + if (_PyInterpreterState_GET()->eval_frame) { + SPECIALIZATION_FAIL(FOR_ITER, SPEC_FAIL_OTHER); + goto failure; + } + instr->op.code = FOR_ITER_GEN; + goto success; + } + SPECIALIZATION_FAIL(FOR_ITER, + _PySpecialization_ClassifyIterator(iter)); +failure: + STAT_INC(FOR_ITER, failure); + instr->op.code = FOR_ITER; + cache->counter = adaptive_counter_backoff(cache->counter); + return; +success: + STAT_INC(FOR_ITER, success); + cache->counter = adaptive_counter_cooldown(); +} + +void +_Py_Specialize_Send(PyObject *receiver, _Py_CODEUNIT *instr) +{ + assert(ENABLE_SPECIALIZATION); + assert(_PyOpcode_Caches[SEND] == INLINE_CACHE_ENTRIES_SEND); + _PySendCache *cache = (_PySendCache *)(instr + 1); + PyTypeObject *tp = Py_TYPE(receiver); + if (tp == &PyGen_Type || tp == &PyCoro_Type) { + if (_PyInterpreterState_GET()->eval_frame) { + SPECIALIZATION_FAIL(SEND, SPEC_FAIL_OTHER); + goto failure; + } + instr->op.code = SEND_GEN; + goto success; + } + SPECIALIZATION_FAIL(SEND, + _PySpecialization_ClassifyIterator(receiver)); +failure: + STAT_INC(SEND, failure); + instr->op.code = SEND; + cache->counter = adaptive_counter_backoff(cache->counter); + return; +success: + STAT_INC(SEND, success); + cache->counter = adaptive_counter_cooldown(); +} diff --git a/Python/stdlib_module_names.h b/Python/stdlib_module_names.h index 553585a7..ed4a0ac2 100644 --- a/Python/stdlib_module_names.h +++ b/Python/stdlib_module_names.h @@ -1,4 +1,4 @@ -// Auto-generated by Tools/scripts/generate_stdlib_module_names.py. +// Auto-generated by Tools/build/generate_stdlib_module_names.py. // List used to create sys.stdlib_module_names. static const char* _Py_stdlib_module_names[] = { @@ -9,7 +9,6 @@ static const char* _Py_stdlib_module_names[] = { "_asyncio", "_bisect", "_blake2", -"_bootsubprocess", "_bz2", "_codecs", "_codecs_cn", @@ -57,15 +56,16 @@ static const char* _Py_stdlib_module_names[] = { "_posixshmem", "_posixsubprocess", "_py_abc", +"_pydatetime", "_pydecimal", "_pyio", +"_pylong", "_queue", "_random", "_scproxy", "_sha1", -"_sha256", +"_sha2", "_sha3", -"_sha512", "_signal", "_sitebuiltins", "_socket", @@ -96,9 +96,7 @@ static const char* _Py_stdlib_module_names[] = { "argparse", "array", "ast", -"asynchat", "asyncio", -"asyncore", "atexit", "audioop", "base64", @@ -136,7 +134,6 @@ static const char* _Py_stdlib_module_names[] = { "decimal", "difflib", "dis", -"distutils", "doctest", "email", "encodings", @@ -168,7 +165,6 @@ static const char* _Py_stdlib_module_names[] = { "idlelib", "imaplib", "imghdr", -"imp", "importlib", "inspect", "io", @@ -242,7 +238,6 @@ static const char* _Py_stdlib_module_names[] = { "shutil", "signal", "site", -"smtpd", "smtplib", "sndhdr", "socket", diff --git a/Python/structmember.c b/Python/structmember.c index c7e31881..19a75224 100644 --- a/Python/structmember.c +++ b/Python/structmember.c @@ -8,6 +8,12 @@ PyObject * PyMember_GetOne(const char *obj_addr, PyMemberDef *l) { PyObject *v; + if (l->flags & Py_RELATIVE_OFFSET) { + PyErr_SetString( + PyExc_SystemError, + "PyMember_GetOne used with Py_RELATIVE_OFFSET"); + return NULL; + } const char* addr = obj_addr + l->offset; switch (l->type) { @@ -49,8 +55,7 @@ PyMember_GetOne(const char *obj_addr, PyMemberDef *l) break; case T_STRING: if (*(char**)addr == NULL) { - Py_INCREF(Py_None); - v = Py_None; + v = Py_NewRef(Py_None); } else v = PyUnicode_FromString(*(char**)addr); @@ -75,7 +80,7 @@ PyMember_GetOne(const char *obj_addr, PyMemberDef *l) PyErr_Format(PyExc_AttributeError, "'%.200s' object has no attribute '%s'", tp->tp_name, l->name); - } + } Py_XINCREF(v); break; case T_LONGLONG: @@ -85,8 +90,7 @@ PyMember_GetOne(const char *obj_addr, PyMemberDef *l) v = PyLong_FromUnsignedLongLong(*(unsigned long long *)addr); break; case T_NONE: - v = Py_None; - Py_INCREF(v); + v = Py_NewRef(Py_None); break; default: PyErr_SetString(PyExc_SystemError, "bad memberdescr type"); @@ -105,6 +109,12 @@ int PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v) { PyObject *oldv; + if (l->flags & Py_RELATIVE_OFFSET) { + PyErr_SetString( + PyExc_SystemError, + "PyMember_SetOne used with Py_RELATIVE_OFFSET"); + return -1; + } addr += l->offset; @@ -247,9 +257,8 @@ PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v) break; case T_OBJECT: case T_OBJECT_EX: - Py_XINCREF(v); oldv = *(PyObject **)addr; - *(PyObject **)addr = v; + *(PyObject **)addr = Py_XNewRef(v); Py_XDECREF(oldv); break; case T_CHAR: { diff --git a/Python/suggestions.c b/Python/suggestions.c index c336ec8f..ad583934 100644 --- a/Python/suggestions.c +++ b/Python/suggestions.c @@ -1,8 +1,11 @@ #include "Python.h" #include "pycore_frame.h" +#include "pycore_runtime.h" // _PyRuntime +#include "pycore_global_objects.h" // _Py_ID() #include "pycore_pyerrors.h" #include "pycore_code.h" // _PyCode_GetVarnames() +#include "stdlib_module_names.h" // _Py_stdlib_module_names #define MAX_CANDIDATE_ITEMS 750 #define MAX_STRING_SIZE 40 @@ -38,10 +41,8 @@ substitution_cost(char a, char b) static Py_ssize_t levenshtein_distance(const char *a, size_t a_size, const char *b, size_t b_size, - size_t max_cost) + size_t max_cost, size_t *buffer) { - static size_t buffer[MAX_STRING_SIZE]; - // Both strings are the same (by identity) if (a == b) { return 0; @@ -144,24 +145,28 @@ calculate_suggestions(PyObject *dir, if (name_str == NULL) { return NULL; } - + size_t *buffer = PyMem_New(size_t, MAX_STRING_SIZE); + if (buffer == NULL) { + return PyErr_NoMemory(); + } for (int i = 0; i < dir_size; ++i) { PyObject *item = PyList_GET_ITEM(dir, i); + if (_PyUnicode_Equal(name, item)) { + continue; + } Py_ssize_t item_size; const char *item_str = PyUnicode_AsUTF8AndSize(item, &item_size); if (item_str == NULL) { + PyMem_Free(buffer); return NULL; } - if (PyUnicode_CompareWithASCIIString(name, item_str) == 0) { - continue; - } // No more than 1/3 of the involved characters should need changed. Py_ssize_t max_distance = (name_size + item_size + 3) * MOVE_COST / 6; // Don't take matches we've already beaten. max_distance = Py_MIN(max_distance, suggestion_distance - 1); Py_ssize_t current_distance = - levenshtein_distance(name_str, name_size, - item_str, item_size, max_distance); + levenshtein_distance(name_str, name_size, item_str, + item_size, max_distance, buffer); if (current_distance > max_distance) { continue; } @@ -170,12 +175,12 @@ calculate_suggestions(PyObject *dir, suggestion_distance = current_distance; } } - Py_XINCREF(suggestion); - return suggestion; + PyMem_Free(buffer); + return Py_XNewRef(suggestion); } static PyObject * -offer_suggestions_for_attribute_error(PyAttributeErrorObject *exc) +get_suggestions_for_attribute_error(PyAttributeErrorObject *exc) { PyObject *name = exc->name; // borrowed reference PyObject *obj = exc->obj; // borrowed reference @@ -195,6 +200,107 @@ offer_suggestions_for_attribute_error(PyAttributeErrorObject *exc) return suggestions; } +static PyObject * +offer_suggestions_for_attribute_error(PyAttributeErrorObject *exc) +{ + PyObject* suggestion = get_suggestions_for_attribute_error(exc); + if (suggestion == NULL) { + return NULL; + } + // Add a trailer ". Did you mean: (...)?" + PyObject* result = PyUnicode_FromFormat(". Did you mean: %R?", suggestion); + Py_DECREF(suggestion); + return result; +} + +static PyObject * +get_suggestions_for_name_error(PyObject* name, PyFrameObject* frame) +{ + PyCodeObject *code = PyFrame_GetCode(frame); + assert(code != NULL && code->co_localsplusnames != NULL); + + PyObject *varnames = _PyCode_GetVarnames(code); + Py_DECREF(code); + if (varnames == NULL) { + return NULL; + } + PyObject *dir = PySequence_List(varnames); + Py_DECREF(varnames); + if (dir == NULL) { + return NULL; + } + + // Are we inside a method and the instance has an attribute called 'name'? + int res = PySequence_Contains(dir, &_Py_ID(self)); + if (res < 0) { + goto error; + } + if (res > 0) { + PyObject* locals = PyFrame_GetLocals(frame); + if (!locals) { + goto error; + } + PyObject* self = PyDict_GetItemWithError(locals, &_Py_ID(self)); /* borrowed */ + if (!self) { + Py_DECREF(locals); + goto error; + } + + PyObject *value; + res = _PyObject_LookupAttr(self, name, &value); + Py_DECREF(locals); + if (res < 0) { + goto error; + } + if (value) { + Py_DECREF(value); + Py_DECREF(dir); + return PyUnicode_FromFormat("self.%U", name); + } + } + + PyObject *suggestions = calculate_suggestions(dir, name); + Py_DECREF(dir); + if (suggestions != NULL || PyErr_Occurred()) { + return suggestions; + } + + dir = PySequence_List(frame->f_frame->f_globals); + if (dir == NULL) { + return NULL; + } + suggestions = calculate_suggestions(dir, name); + Py_DECREF(dir); + if (suggestions != NULL || PyErr_Occurred()) { + return suggestions; + } + + dir = PySequence_List(frame->f_frame->f_builtins); + if (dir == NULL) { + return NULL; + } + suggestions = calculate_suggestions(dir, name); + Py_DECREF(dir); + + return suggestions; + +error: + Py_DECREF(dir); + return NULL; +} + +static bool +is_name_stdlib_module(PyObject* name) +{ + const char* the_name = PyUnicode_AsUTF8(name); + Py_ssize_t len = Py_ARRAY_LENGTH(_Py_stdlib_module_names); + for (Py_ssize_t i = 0; i < len; i++) { + if (strcmp(the_name, _Py_stdlib_module_names[i]) == 0) { + return 1; + } + } + return 0; +} static PyObject * offer_suggestions_for_name_error(PyNameErrorObject *exc) @@ -222,43 +328,58 @@ offer_suggestions_for_name_error(PyNameErrorObject *exc) PyFrameObject *frame = traceback->tb_frame; assert(frame != NULL); - PyCodeObject *code = PyFrame_GetCode(frame); - assert(code != NULL && code->co_localsplusnames != NULL); - PyObject *varnames = _PyCode_GetVarnames(code); - if (varnames == NULL) { - return NULL; - } - PyObject *dir = PySequence_List(varnames); - Py_DECREF(varnames); - Py_DECREF(code); - if (dir == NULL) { + + PyObject* suggestion = get_suggestions_for_name_error(name, frame); + if (suggestion == NULL && PyErr_Occurred()) { return NULL; } - PyObject *suggestions = calculate_suggestions(dir, name); - Py_DECREF(dir); - if (suggestions != NULL) { - return suggestions; + // Add a trailer ". Did you mean: (...)?" + PyObject* result = NULL; + if (!is_name_stdlib_module(name)) { + if (suggestion == NULL) { + return NULL; + } + result = PyUnicode_FromFormat(". Did you mean: %R?", suggestion); + } else if (suggestion == NULL) { + result = PyUnicode_FromFormat(". Did you forget to import %R?", name); + } else { + result = PyUnicode_FromFormat(". Did you mean: %R? Or did you forget to import %R?", suggestion, name); } + Py_XDECREF(suggestion); + return result; +} - dir = PySequence_List(frame->f_frame->f_globals); - if (dir == NULL) { +static PyObject * +offer_suggestions_for_import_error(PyImportErrorObject *exc) +{ + PyObject *mod_name = exc->name; // borrowed reference + PyObject *name = exc->name_from; // borrowed reference + if (name == NULL || mod_name == NULL || name == Py_None || + !PyUnicode_CheckExact(name) || !PyUnicode_CheckExact(mod_name)) { return NULL; } - suggestions = calculate_suggestions(dir, name); - Py_DECREF(dir); - if (suggestions != NULL) { - return suggestions; + + PyObject* mod = PyImport_GetModule(mod_name); + if (mod == NULL) { + return NULL; } - dir = PySequence_List(frame->f_frame->f_builtins); + PyObject *dir = PyObject_Dir(mod); + Py_DECREF(mod); if (dir == NULL) { return NULL; } - suggestions = calculate_suggestions(dir, name); + + PyObject *suggestion = calculate_suggestions(dir, name); Py_DECREF(dir); + if (!suggestion) { + return NULL; + } - return suggestions; + PyObject* result = PyUnicode_FromFormat(". Did you mean: %R?", suggestion); + Py_DECREF(suggestion); + return result; } // Offer suggestions for a given exception. Returns a python string object containing the @@ -273,6 +394,8 @@ _Py_Offer_Suggestions(PyObject *exception) result = offer_suggestions_for_attribute_error((PyAttributeErrorObject *) exception); } else if (Py_IS_TYPE(exception, (PyTypeObject*)PyExc_NameError)) { result = offer_suggestions_for_name_error((PyNameErrorObject *) exception); + } else if (Py_IS_TYPE(exception, (PyTypeObject*)PyExc_ImportError)) { + result = offer_suggestions_for_import_error((PyImportErrorObject *) exception); } return result; } @@ -293,6 +416,14 @@ _Py_UTF8_Edit_Cost(PyObject *a, PyObject *b, Py_ssize_t max_cost) if (max_cost == -1) { max_cost = MOVE_COST * Py_MAX(size_a, size_b); } - return levenshtein_distance(utf8_a, size_a, utf8_b, size_b, max_cost); + size_t *buffer = PyMem_New(size_t, MAX_STRING_SIZE); + if (buffer == NULL) { + PyErr_NoMemory(); + return -1; + } + Py_ssize_t res = levenshtein_distance(utf8_a, size_a, + utf8_b, size_b, max_cost, buffer); + PyMem_Free(buffer); + return res; } diff --git a/Python/symtable.c b/Python/symtable.c index 0b259b08..4989e03d 100644 --- a/Python/symtable.c +++ b/Python/symtable.c @@ -1,6 +1,5 @@ #include "Python.h" #include "pycore_ast.h" // identifier, stmt_ty -#include "pycore_compile.h" // _Py_Mangle(), _PyFuture_FromAST() #include "pycore_parser.h" // _PyParser_ASTFromString() #include "pycore_pystate.h" // _PyThreadState_GET() #include "pycore_symtable.h" // PySTEntryObject @@ -36,6 +35,15 @@ #define NAMED_EXPR_COMP_IN_CLASS \ "assignment expression within a comprehension cannot be used in a class body" +#define NAMED_EXPR_COMP_IN_TYPEVAR_BOUND \ +"assignment expression within a comprehension cannot be used in a TypeVar bound" + +#define NAMED_EXPR_COMP_IN_TYPEALIAS \ +"assignment expression within a comprehension cannot be used in a type alias" + +#define NAMED_EXPR_COMP_IN_TYPEPARAM \ +"assignment expression within a comprehension cannot be used within the definition of a generic" + #define NAMED_EXPR_COMP_CONFLICT \ "assignment expression cannot rebind comprehension iteration variable '%U'" @@ -46,7 +54,19 @@ "assignment expression cannot be used in a comprehension iterable expression" #define ANNOTATION_NOT_ALLOWED \ -"'%s' can not be used within an annotation" +"%s cannot be used within an annotation" + +#define TYPEVAR_BOUND_NOT_ALLOWED \ +"%s cannot be used within a TypeVar bound" + +#define TYPEALIAS_NOT_ALLOWED \ +"%s cannot be used within a type alias" + +#define TYPEPARAM_NOT_ALLOWED \ +"%s cannot be used within the definition of a generic" + +#define DUPLICATE_TYPE_PARAM \ +"duplicate type parameter '%U'" #define LOCATION(x) \ @@ -74,8 +94,7 @@ ste_new(struct symtable *st, identifier name, _Py_block_ty block, ste->ste_table = st; ste->ste_id = k; /* ste owns reference to k */ - Py_INCREF(name); - ste->ste_name = name; + ste->ste_name = Py_NewRef(name); ste->ste_symbols = NULL; ste->ste_varnames = NULL; @@ -97,7 +116,7 @@ ste_new(struct symtable *st, identifier name, _Py_block_ty block, if (st->st_cur != NULL && (st->st_cur->ste_nested || - st->st_cur->ste_type == FunctionBlock)) + _PyST_IsFunctionLike(st->st_cur))) ste->ste_nested = 1; ste->ste_child_free = 0; ste->ste_generator = 0; @@ -105,8 +124,11 @@ ste_new(struct symtable *st, identifier name, _Py_block_ty block, ste->ste_comprehension = NoComprehension; ste->ste_returns_value = 0; ste->ste_needs_class_closure = 0; + ste->ste_comp_inlined = 0; ste->ste_comp_iter_target = 0; + ste->ste_can_see_class_scope = 0; ste->ste_comp_iter_expr = 0; + ste->ste_needs_classdict = 0; ste->ste_symbols = PyDict_New(); ste->ste_varnames = PyList_New(0); @@ -209,6 +231,7 @@ static int symtable_enter_block(struct symtable *st, identifier name, static int symtable_exit_block(struct symtable *st); static int symtable_visit_stmt(struct symtable *st, stmt_ty s); static int symtable_visit_expr(struct symtable *st, expr_ty s); +static int symtable_visit_type_param(struct symtable *st, type_param_ty s); static int symtable_visit_genexp(struct symtable *st, expr_ty s); static int symtable_visit_listcomp(struct symtable *st, expr_ty s); static int symtable_visit_setcomp(struct symtable *st, expr_ty s); @@ -259,17 +282,10 @@ symtable_new(void) return NULL; } -/* When compiling the use of C stack is probably going to be a lot - lighter than when executing Python code but still can overflow - and causing a Python crash if not checked (e.g. eval("()"*300000)). - Using the current recursion limit for the compiler seems too - restrictive (it caused at least one test to fail) so a factor is - used to allow deeper recursion when compiling an expression. - - Using a scaling factor means this should automatically adjust when +/* Using a scaling factor means this should automatically adjust when the recursion limit is adjusted for small or large C stack allocations. */ -#define COMPILER_STACK_FRAME_SCALE 3 +#define COMPILER_STACK_FRAME_SCALE 2 struct symtable * _PySymtable_Build(mod_ty mod, PyObject *filename, PyFutureFeatures *future) @@ -278,7 +294,6 @@ _PySymtable_Build(mod_ty mod, PyObject *filename, PyFutureFeatures *future) asdl_stmt_seq *seq; int i; PyThreadState *tstate; - int recursion_limit = Py_GetRecursionLimit(); int starting_recursion_depth; if (st == NULL) @@ -287,8 +302,7 @@ _PySymtable_Build(mod_ty mod, PyObject *filename, PyFutureFeatures *future) _PySymtable_Free(st); return NULL; } - Py_INCREF(filename); - st->st_filename = filename; + st->st_filename = Py_NewRef(filename); st->st_future = future; /* Setup recursion depth check counters */ @@ -298,12 +312,10 @@ _PySymtable_Build(mod_ty mod, PyObject *filename, PyFutureFeatures *future) return NULL; } /* Be careful here to prevent overflow. */ - int recursion_depth = tstate->recursion_limit - tstate->recursion_remaining; - starting_recursion_depth = (recursion_depth < INT_MAX / COMPILER_STACK_FRAME_SCALE) ? - recursion_depth * COMPILER_STACK_FRAME_SCALE : recursion_depth; + int recursion_depth = C_RECURSION_LIMIT - tstate->c_recursion_remaining; + starting_recursion_depth = recursion_depth * COMPILER_STACK_FRAME_SCALE; st->recursion_depth = starting_recursion_depth; - st->recursion_limit = (recursion_limit < INT_MAX / COMPILER_STACK_FRAME_SCALE) ? - recursion_limit * COMPILER_STACK_FRAME_SCALE : recursion_limit; + st->recursion_limit = C_RECURSION_LIMIT * COMPILER_STACK_FRAME_SCALE; /* Make the initial symbol information gathering pass */ if (!symtable_enter_block(st, &_Py_ID(top), ModuleBlock, (void *)mod, 0, 0, 0, 0)) { @@ -378,17 +390,17 @@ PySymtable_Lookup(struct symtable *st, void *key) if (k == NULL) return NULL; v = PyDict_GetItemWithError(st->st_blocks, k); + Py_DECREF(k); + if (v) { assert(PySTEntry_Check(v)); - Py_INCREF(v); } else if (!PyErr_Occurred()) { PyErr_SetString(PyExc_KeyError, "unknown symbol table entry"); } - Py_DECREF(k); - return (PySTEntryObject *)v; + return (PySTEntryObject *)Py_XNewRef(v); } long @@ -408,6 +420,15 @@ _PyST_GetScope(PySTEntryObject *ste, PyObject *name) return (symbol >> SCOPE_OFFSET) & SCOPE_MASK; } +int +_PyST_IsFunctionLike(PySTEntryObject *ste) +{ + return ste->ste_type == FunctionBlock + || ste->ste_type == TypeVarBoundBlock + || ste->ste_type == TypeAliasBlock + || ste->ste_type == TypeParamBlock; +} + static int error_at_directive(PySTEntryObject *ste, PyObject *name) { @@ -500,7 +521,7 @@ error_at_directive(PySTEntryObject *ste, PyObject *name) static int analyze_name(PySTEntryObject *ste, PyObject *scopes, PyObject *name, long flags, PyObject *bound, PyObject *local, PyObject *free, - PyObject *global) + PyObject *global, PyObject *type_params, PySTEntryObject *class_entry) { if (flags & DEF_GLOBAL) { if (flags & DEF_NONLOCAL) { @@ -529,6 +550,12 @@ analyze_name(PySTEntryObject *ste, PyObject *scopes, PyObject *name, long flags, return error_at_directive(ste, name); } + if (PySet_Contains(type_params, name)) { + PyErr_Format(PyExc_SyntaxError, + "nonlocal binding not allowed for type parameter '%U'", + name); + return error_at_directive(ste, name); + } SET_SCOPE(scopes, name, FREE); ste->ste_free = 1; return PySet_Add(free, name) >= 0; @@ -539,8 +566,34 @@ analyze_name(PySTEntryObject *ste, PyObject *scopes, PyObject *name, long flags, return 0; if (PySet_Discard(global, name) < 0) return 0; + if (flags & DEF_TYPE_PARAM) { + if (PySet_Add(type_params, name) < 0) + return 0; + } + else { + if (PySet_Discard(type_params, name) < 0) + return 0; + } return 1; } + // If we were passed class_entry (i.e., we're in an ste_can_see_class_scope scope) + // and the bound name is in that set, then the name is potentially bound both by + // the immediately enclosing class namespace, and also by an outer function namespace. + // In that case, we want the runtime name resolution to look at only the class + // namespace and the globals (not the namespace providing the bound). + // Similarly, if the name is explicitly global in the class namespace (through the + // global statement), we want to also treat it as a global in this scope. + if (class_entry != NULL) { + long class_flags = _PyST_GetSymbol(class_entry, name); + if (class_flags & DEF_GLOBAL) { + SET_SCOPE(scopes, name, GLOBAL_EXPLICIT); + return 1; + } + else if (class_flags & DEF_BOUND && !(class_flags & DEF_NONLOCAL)) { + SET_SCOPE(scopes, name, GLOBAL_IMPLICIT); + return 1; + } + } /* If an enclosing block has a binding for this name, it is a free variable rather than a global variable. Note that having a non-NULL bound implies that the block @@ -564,6 +617,75 @@ analyze_name(PySTEntryObject *ste, PyObject *scopes, PyObject *name, long flags, return 1; } +static int +is_free_in_any_child(PySTEntryObject *entry, PyObject *key) +{ + for (Py_ssize_t i = 0; i < PyList_GET_SIZE(entry->ste_children); i++) { + PySTEntryObject *child_ste = (PySTEntryObject *)PyList_GET_ITEM( + entry->ste_children, i); + long scope = _PyST_GetScope(child_ste, key); + if (scope == FREE) { + return 1; + } + } + return 0; +} + +static int +inline_comprehension(PySTEntryObject *ste, PySTEntryObject *comp, + PyObject *scopes, PyObject *comp_free, + PyObject *inlined_cells) +{ + PyObject *k, *v; + Py_ssize_t pos = 0; + while (PyDict_Next(comp->ste_symbols, &pos, &k, &v)) { + // skip comprehension parameter + long comp_flags = PyLong_AS_LONG(v); + if (comp_flags & DEF_PARAM) { + assert(_PyUnicode_EqualToASCIIString(k, ".0")); + continue; + } + int scope = (comp_flags >> SCOPE_OFFSET) & SCOPE_MASK; + int only_flags = comp_flags & ((1 << SCOPE_OFFSET) - 1); + if (scope == CELL || only_flags & DEF_COMP_CELL) { + if (PySet_Add(inlined_cells, k) < 0) { + return 0; + } + } + PyObject *existing = PyDict_GetItemWithError(ste->ste_symbols, k); + if (existing == NULL && PyErr_Occurred()) { + return 0; + } + if (!existing) { + // name does not exist in scope, copy from comprehension + assert(scope != FREE || PySet_Contains(comp_free, k) == 1); + PyObject *v_flags = PyLong_FromLong(only_flags); + if (v_flags == NULL) { + return 0; + } + int ok = PyDict_SetItem(ste->ste_symbols, k, v_flags); + Py_DECREF(v_flags); + if (ok < 0) { + return 0; + } + SET_SCOPE(scopes, k, scope); + } + else { + if (PyLong_AsLong(existing) & DEF_BOUND) { + // free vars in comprehension that are locals in outer scope can + // now simply be locals, unless they are free in comp children, + // or if the outer scope is a class block + if (!is_free_in_any_child(comp, k) && ste->ste_type != ClassBlock) { + if (PySet_Discard(comp_free, k) < 0) { + return 0; + } + } + } + } + } + return 1; +} + #undef SET_SCOPE /* If a name is defined in free and also in locals, then this block @@ -575,7 +697,7 @@ analyze_name(PySTEntryObject *ste, PyObject *scopes, PyObject *name, long flags, */ static int -analyze_cells(PyObject *scopes, PyObject *free) +analyze_cells(PyObject *scopes, PyObject *free, PyObject *inlined_cells) { PyObject *name, *v, *v_cell; int success = 0; @@ -590,7 +712,7 @@ analyze_cells(PyObject *scopes, PyObject *free) scope = PyLong_AS_LONG(v); if (scope != LOCAL) continue; - if (!PySet_Contains(free, name)) + if (!PySet_Contains(free, name) && !PySet_Contains(inlined_cells, name)) continue; /* Replace LOCAL with CELL for this name, and remove from free. It is safe to replace the value of name @@ -616,6 +738,11 @@ drop_class_free(PySTEntryObject *ste, PyObject *free) return 0; if (res) ste->ste_needs_class_closure = 1; + res = PySet_Discard(free, &_Py_ID(__classdict__)); + if (res < 0) + return 0; + if (res) + ste->ste_needs_classdict = 1; return 1; } @@ -625,7 +752,8 @@ drop_class_free(PySTEntryObject *ste, PyObject *free) */ static int update_symbols(PyObject *symbols, PyObject *scopes, - PyObject *bound, PyObject *free, int classflag) + PyObject *bound, PyObject *free, + PyObject *inlined_cells, int classflag) { PyObject *name = NULL, *itr = NULL; PyObject *v = NULL, *v_scope = NULL, *v_new = NULL, *v_free = NULL; @@ -636,6 +764,9 @@ update_symbols(PyObject *symbols, PyObject *scopes, long scope, flags; assert(PyLong_Check(v)); flags = PyLong_AS_LONG(v); + if (PySet_Contains(inlined_cells, name)) { + flags |= DEF_COMP_CELL; + } v_scope = PyDict_GetItemWithError(scopes, name); assert(v_scope && PyLong_Check(v_scope)); scope = PyLong_AS_LONG(v_scope); @@ -670,8 +801,7 @@ update_symbols(PyObject *symbols, PyObject *scopes, the class that has the same name as a local or global in the class scope. */ - if (classflag && - PyLong_AS_LONG(v) & (DEF_BOUND | DEF_GLOBAL)) { + if (classflag) { long flags = PyLong_AS_LONG(v) | DEF_FREE_CLASS; v_new = PyLong_FromLong(flags); if (!v_new) { @@ -733,17 +863,19 @@ error: static int analyze_child_block(PySTEntryObject *entry, PyObject *bound, PyObject *free, - PyObject *global, PyObject* child_free); + PyObject *global, PyObject *type_params, + PySTEntryObject *class_entry, PyObject **child_free); static int analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free, - PyObject *global) + PyObject *global, PyObject *type_params, + PySTEntryObject *class_entry) { PyObject *name, *v, *local = NULL, *scopes = NULL, *newbound = NULL; - PyObject *newglobal = NULL, *newfree = NULL, *allfree = NULL; + PyObject *newglobal = NULL, *newfree = NULL, *inlined_cells = NULL; PyObject *temp; - int i, success = 0; - Py_ssize_t pos = 0; + int success = 0; + Py_ssize_t i, pos = 0; local = PySet_New(NULL); /* collect new names bound in block */ if (!local) @@ -752,8 +884,8 @@ analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free, if (!scopes) goto error; - /* Allocate new global and bound variable dictionaries. These - dictionaries hold the names visible in nested blocks. For + /* Allocate new global, bound and free variable sets. These + sets hold the names visible in nested blocks. For ClassBlocks, the bound and global names are initialized before analyzing names, because class bindings aren't visible in methods. For other blocks, they are initialized @@ -772,6 +904,9 @@ analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free, newbound = PySet_New(NULL); if (!newbound) goto error; + inlined_cells = PySet_New(NULL); + if (!inlined_cells) + goto error; /* Class namespace has no effect on names visible in nested functions, so populate the global and bound @@ -796,14 +931,14 @@ analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free, while (PyDict_Next(ste->ste_symbols, &pos, &name, &v)) { long flags = PyLong_AS_LONG(v); if (!analyze_name(ste, scopes, name, flags, - bound, local, free, global)) + bound, local, free, global, type_params, class_entry)) goto error; } /* Populate global and bound sets to be passed to children. */ if (ste->ste_type != ClassBlock) { /* Add function locals to bound set */ - if (ste->ste_type == FunctionBlock) { + if (_PyST_IsFunctionLike(ste)) { temp = PyNumber_InPlaceOr(newbound, local); if (!temp) goto error; @@ -823,46 +958,85 @@ analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free, Py_DECREF(temp); } else { - /* Special-case __class__ */ + /* Special-case __class__ and __classdict__ */ if (PySet_Add(newbound, &_Py_ID(__class__)) < 0) goto error; + if (PySet_Add(newbound, &_Py_ID(__classdict__)) < 0) + goto error; } /* Recursively call analyze_child_block() on each child block. newbound, newglobal now contain the names visible in nested blocks. The free variables in the children will - be collected in allfree. + be added to newfree. */ - allfree = PySet_New(NULL); - if (!allfree) - goto error; for (i = 0; i < PyList_GET_SIZE(ste->ste_children); ++i) { + PyObject *child_free = NULL; PyObject *c = PyList_GET_ITEM(ste->ste_children, i); PySTEntryObject* entry; assert(c && PySTEntry_Check(c)); entry = (PySTEntryObject*)c; + + PySTEntryObject *new_class_entry = NULL; + if (entry->ste_can_see_class_scope) { + if (ste->ste_type == ClassBlock) { + new_class_entry = ste; + } + else if (class_entry) { + new_class_entry = class_entry; + } + } + + // we inline all non-generator-expression comprehensions + int inline_comp = + entry->ste_comprehension && + !entry->ste_generator; + if (!analyze_child_block(entry, newbound, newfree, newglobal, - allfree)) + type_params, new_class_entry, &child_free)) + { goto error; + } + if (inline_comp) { + if (!inline_comprehension(ste, entry, scopes, child_free, inlined_cells)) { + Py_DECREF(child_free); + goto error; + } + entry->ste_comp_inlined = 1; + } + temp = PyNumber_InPlaceOr(newfree, child_free); + Py_DECREF(child_free); + if (!temp) + goto error; + Py_DECREF(temp); /* Check if any children have free variables */ if (entry->ste_free || entry->ste_child_free) ste->ste_child_free = 1; } - temp = PyNumber_InPlaceOr(newfree, allfree); - if (!temp) - goto error; - Py_DECREF(temp); + /* Splice children of inlined comprehensions into our children list */ + for (i = PyList_GET_SIZE(ste->ste_children) - 1; i >= 0; --i) { + PyObject* c = PyList_GET_ITEM(ste->ste_children, i); + PySTEntryObject* entry; + assert(c && PySTEntry_Check(c)); + entry = (PySTEntryObject*)c; + if (entry->ste_comp_inlined && + PyList_SetSlice(ste->ste_children, i, i + 1, + entry->ste_children) < 0) + { + goto error; + } + } /* Check if any local variables must be converted to cell variables */ - if (ste->ste_type == FunctionBlock && !analyze_cells(scopes, newfree)) + if (_PyST_IsFunctionLike(ste) && !analyze_cells(scopes, newfree, inlined_cells)) goto error; else if (ste->ste_type == ClassBlock && !drop_class_free(ste, newfree)) goto error; /* Records the results of the analysis in the symbol table entry */ - if (!update_symbols(ste->ste_symbols, scopes, bound, newfree, - ste->ste_type == ClassBlock)) + if (!update_symbols(ste->ste_symbols, scopes, bound, newfree, inlined_cells, + (ste->ste_type == ClassBlock) || ste->ste_can_see_class_scope)) goto error; temp = PyNumber_InPlaceOr(free, newfree); @@ -876,7 +1050,7 @@ analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free, Py_XDECREF(newbound); Py_XDECREF(newglobal); Py_XDECREF(newfree); - Py_XDECREF(allfree); + Py_XDECREF(inlined_cells); if (!success) assert(PyErr_Occurred()); return success; @@ -884,16 +1058,17 @@ analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free, static int analyze_child_block(PySTEntryObject *entry, PyObject *bound, PyObject *free, - PyObject *global, PyObject* child_free) + PyObject *global, PyObject *type_params, + PySTEntryObject *class_entry, PyObject** child_free) { PyObject *temp_bound = NULL, *temp_global = NULL, *temp_free = NULL; - PyObject *temp; + PyObject *temp_type_params = NULL; - /* Copy the bound and global dictionaries. + /* Copy the bound/global/free sets. - These dictionaries are used by all blocks enclosed by the + These sets are used by all blocks enclosed by the current block. The analyze_block() call modifies these - dictionaries. + sets. */ temp_bound = PySet_New(bound); @@ -905,28 +1080,30 @@ analyze_child_block(PySTEntryObject *entry, PyObject *bound, PyObject *free, temp_global = PySet_New(global); if (!temp_global) goto error; - - if (!analyze_block(entry, temp_bound, temp_free, temp_global)) + temp_type_params = PySet_New(type_params); + if (!temp_type_params) goto error; - temp = PyNumber_InPlaceOr(child_free, temp_free); - if (!temp) + + if (!analyze_block(entry, temp_bound, temp_free, temp_global, + temp_type_params, class_entry)) goto error; - Py_DECREF(temp); + *child_free = temp_free; Py_DECREF(temp_bound); - Py_DECREF(temp_free); Py_DECREF(temp_global); + Py_DECREF(temp_type_params); return 1; error: Py_XDECREF(temp_bound); Py_XDECREF(temp_free); Py_XDECREF(temp_global); + Py_XDECREF(temp_type_params); return 0; } static int symtable_analyze(struct symtable *st) { - PyObject *free, *global; + PyObject *free, *global, *type_params; int r; free = PySet_New(NULL); @@ -937,9 +1114,16 @@ symtable_analyze(struct symtable *st) Py_DECREF(free); return 0; } - r = analyze_block(st->st_top, NULL, free, global); + type_params = PySet_New(NULL); + if (!type_params) { + Py_DECREF(free); + Py_DECREF(global); + return 0; + } + r = analyze_block(st->st_top, NULL, free, global, type_params, NULL); Py_DECREF(free); Py_DECREF(global); + Py_DECREF(type_params); return r; } @@ -1042,6 +1226,13 @@ symtable_add_def_helper(struct symtable *st, PyObject *name, int flag, struct _s end_lineno, end_col_offset + 1); goto error; } + if ((flag & DEF_TYPE_PARAM) && (val & DEF_TYPE_PARAM)) { + PyErr_Format(PyExc_SyntaxError, DUPLICATE_TYPE_PARAM, name); + PyErr_RangedSyntaxLocationObject(st->st_filename, + lineno, col_offset + 1, + end_lineno, end_col_offset + 1); + goto error; + } val |= flag; } else if (PyErr_Occurred()) { @@ -1113,6 +1304,65 @@ symtable_add_def(struct symtable *st, PyObject *name, int flag, lineno, col_offset, end_lineno, end_col_offset); } +static int +symtable_enter_type_param_block(struct symtable *st, identifier name, + void *ast, int has_defaults, int has_kwdefaults, + enum _stmt_kind kind, + int lineno, int col_offset, + int end_lineno, int end_col_offset) +{ + _Py_block_ty current_type = st->st_cur->ste_type; + if(!symtable_enter_block(st, name, TypeParamBlock, ast, lineno, + col_offset, end_lineno, end_col_offset)) { + return 0; + } + if (current_type == ClassBlock) { + st->st_cur->ste_can_see_class_scope = 1; + if (!symtable_add_def(st, &_Py_ID(__classdict__), USE, lineno, col_offset, end_lineno, end_col_offset)) { + return 0; + } + } + if (kind == ClassDef_kind) { + _Py_DECLARE_STR(type_params, ".type_params"); + // It gets "set" when we create the type params tuple and + // "used" when we build up the bases. + if (!symtable_add_def(st, &_Py_STR(type_params), DEF_LOCAL, + lineno, col_offset, end_lineno, end_col_offset)) { + return 0; + } + if (!symtable_add_def(st, &_Py_STR(type_params), USE, + lineno, col_offset, end_lineno, end_col_offset)) { + return 0; + } + st->st_private = name; + // This is used for setting the generic base + _Py_DECLARE_STR(generic_base, ".generic_base"); + if (!symtable_add_def(st, &_Py_STR(generic_base), DEF_LOCAL, + lineno, col_offset, end_lineno, end_col_offset)) { + return 0; + } + if (!symtable_add_def(st, &_Py_STR(generic_base), USE, + lineno, col_offset, end_lineno, end_col_offset)) { + return 0; + } + } + if (has_defaults) { + _Py_DECLARE_STR(defaults, ".defaults"); + if (!symtable_add_def(st, &_Py_STR(defaults), DEF_PARAM, + lineno, col_offset, end_lineno, end_col_offset)) { + return 0; + } + } + if (has_kwdefaults) { + _Py_DECLARE_STR(kwdefaults, ".kwdefaults"); + if (!symtable_add_def(st, &_Py_STR(kwdefaults), DEF_PARAM, + lineno, col_offset, end_lineno, end_col_offset)) { + return 0; + } + } + return 1; +} + /* VISIT, VISIT_SEQ and VIST_SEQ_TAIL take an ASDL type as their second argument. They use the ASDL name to synthesize the name of the C type and the visit function. @@ -1184,6 +1434,17 @@ symtable_record_directive(struct symtable *st, identifier name, int lineno, return res == 0; } +static int +has_kwonlydefaults(asdl_arg_seq *kwonlyargs, asdl_expr_seq *kw_defaults) +{ + for (int i = 0; i < asdl_seq_LEN(kwonlyargs); i++) { + expr_ty default_ = asdl_seq_GET(kw_defaults, i); + if (default_) { + return 1; + } + } + return 0; +} static int symtable_visit_stmt(struct symtable *st, stmt_ty s) @@ -1201,11 +1462,24 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s) VISIT_SEQ(st, expr, s->v.FunctionDef.args->defaults); if (s->v.FunctionDef.args->kw_defaults) VISIT_SEQ_WITH_NULL(st, expr, s->v.FunctionDef.args->kw_defaults); + if (s->v.FunctionDef.decorator_list) + VISIT_SEQ(st, expr, s->v.FunctionDef.decorator_list); + if (asdl_seq_LEN(s->v.FunctionDef.type_params) > 0) { + if (!symtable_enter_type_param_block( + st, s->v.FunctionDef.name, + (void *)s->v.FunctionDef.type_params, + s->v.FunctionDef.args->defaults != NULL, + has_kwonlydefaults(s->v.FunctionDef.args->kwonlyargs, + s->v.FunctionDef.args->kw_defaults), + s->kind, + LOCATION(s))) { + VISIT_QUIT(st, 0); + } + VISIT_SEQ(st, type_param, s->v.FunctionDef.type_params); + } if (!symtable_visit_annotations(st, s, s->v.FunctionDef.args, s->v.FunctionDef.returns)) VISIT_QUIT(st, 0); - if (s->v.FunctionDef.decorator_list) - VISIT_SEQ(st, expr, s->v.FunctionDef.decorator_list); if (!symtable_enter_block(st, s->v.FunctionDef.name, FunctionBlock, (void *)s, LOCATION(s))) @@ -1214,25 +1488,85 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s) VISIT_SEQ(st, stmt, s->v.FunctionDef.body); if (!symtable_exit_block(st)) VISIT_QUIT(st, 0); + if (asdl_seq_LEN(s->v.FunctionDef.type_params) > 0) { + if (!symtable_exit_block(st)) + VISIT_QUIT(st, 0); + } break; case ClassDef_kind: { PyObject *tmp; if (!symtable_add_def(st, s->v.ClassDef.name, DEF_LOCAL, LOCATION(s))) VISIT_QUIT(st, 0); - VISIT_SEQ(st, expr, s->v.ClassDef.bases); - VISIT_SEQ(st, keyword, s->v.ClassDef.keywords); if (s->v.ClassDef.decorator_list) VISIT_SEQ(st, expr, s->v.ClassDef.decorator_list); + if (asdl_seq_LEN(s->v.ClassDef.type_params) > 0) { + if (!symtable_enter_type_param_block(st, s->v.ClassDef.name, + (void *)s->v.ClassDef.type_params, + false, false, s->kind, + LOCATION(s))) { + VISIT_QUIT(st, 0); + } + VISIT_SEQ(st, type_param, s->v.ClassDef.type_params); + } + VISIT_SEQ(st, expr, s->v.ClassDef.bases); + VISIT_SEQ(st, keyword, s->v.ClassDef.keywords); if (!symtable_enter_block(st, s->v.ClassDef.name, ClassBlock, (void *)s, s->lineno, s->col_offset, s->end_lineno, s->end_col_offset)) VISIT_QUIT(st, 0); tmp = st->st_private; st->st_private = s->v.ClassDef.name; + if (asdl_seq_LEN(s->v.ClassDef.type_params) > 0) { + if (!symtable_add_def(st, &_Py_ID(__type_params__), + DEF_LOCAL, LOCATION(s))) { + VISIT_QUIT(st, 0); + } + _Py_DECLARE_STR(type_params, ".type_params"); + if (!symtable_add_def(st, &_Py_STR(type_params), + USE, LOCATION(s))) { + VISIT_QUIT(st, 0); + } + } VISIT_SEQ(st, stmt, s->v.ClassDef.body); st->st_private = tmp; if (!symtable_exit_block(st)) VISIT_QUIT(st, 0); + if (asdl_seq_LEN(s->v.ClassDef.type_params) > 0) { + if (!symtable_exit_block(st)) + VISIT_QUIT(st, 0); + } + break; + } + case TypeAlias_kind: { + VISIT(st, expr, s->v.TypeAlias.name); + assert(s->v.TypeAlias.name->kind == Name_kind); + PyObject *name = s->v.TypeAlias.name->v.Name.id; + int is_in_class = st->st_cur->ste_type == ClassBlock; + int is_generic = asdl_seq_LEN(s->v.TypeAlias.type_params) > 0; + if (is_generic) { + if (!symtable_enter_type_param_block( + st, name, + (void *)s->v.TypeAlias.type_params, + false, false, s->kind, + LOCATION(s))) { + VISIT_QUIT(st, 0); + } + VISIT_SEQ(st, type_param, s->v.TypeAlias.type_params); + } + if (!symtable_enter_block(st, name, TypeAliasBlock, + (void *)s, LOCATION(s))) + VISIT_QUIT(st, 0); + st->st_cur->ste_can_see_class_scope = is_in_class; + if (is_in_class && !symtable_add_def(st, &_Py_ID(__classdict__), USE, LOCATION(s->v.TypeAlias.value))) { + VISIT_QUIT(st, 0); + } + VISIT(st, expr, s->v.TypeAlias.value); + if (!symtable_exit_block(st)) + VISIT_QUIT(st, 0); + if (is_generic) { + if (!symtable_exit_block(st)) + VISIT_QUIT(st, 0); + } break; } case Return_kind: @@ -1441,11 +1775,24 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s) if (s->v.AsyncFunctionDef.args->kw_defaults) VISIT_SEQ_WITH_NULL(st, expr, s->v.AsyncFunctionDef.args->kw_defaults); + if (s->v.AsyncFunctionDef.decorator_list) + VISIT_SEQ(st, expr, s->v.AsyncFunctionDef.decorator_list); + if (asdl_seq_LEN(s->v.AsyncFunctionDef.type_params) > 0) { + if (!symtable_enter_type_param_block( + st, s->v.AsyncFunctionDef.name, + (void *)s->v.AsyncFunctionDef.type_params, + s->v.AsyncFunctionDef.args->defaults != NULL, + has_kwonlydefaults(s->v.AsyncFunctionDef.args->kwonlyargs, + s->v.AsyncFunctionDef.args->kw_defaults), + s->kind, + LOCATION(s))) { + VISIT_QUIT(st, 0); + } + VISIT_SEQ(st, type_param, s->v.AsyncFunctionDef.type_params); + } if (!symtable_visit_annotations(st, s, s->v.AsyncFunctionDef.args, s->v.AsyncFunctionDef.returns)) VISIT_QUIT(st, 0); - if (s->v.AsyncFunctionDef.decorator_list) - VISIT_SEQ(st, expr, s->v.AsyncFunctionDef.decorator_list); if (!symtable_enter_block(st, s->v.AsyncFunctionDef.name, FunctionBlock, (void *)s, s->lineno, s->col_offset, @@ -1456,6 +1803,10 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s) VISIT_SEQ(st, stmt, s->v.AsyncFunctionDef.body); if (!symtable_exit_block(st)) VISIT_QUIT(st, 0); + if (asdl_seq_LEN(s->v.AsyncFunctionDef.type_params) > 0) { + if (!symtable_exit_block(st)) + VISIT_QUIT(st, 0); + } break; case AsyncWith_kind: VISIT_SEQ(st, withitem, s->v.AsyncWith.items); @@ -1493,7 +1844,8 @@ symtable_extend_namedexpr_scope(struct symtable *st, expr_ty e) */ if (ste->ste_comprehension) { long target_in_scope = _PyST_GetSymbol(ste, target_name); - if (target_in_scope & DEF_COMP_ITER) { + if ((target_in_scope & DEF_COMP_ITER) && + (target_in_scope & DEF_LOCAL)) { PyErr_Format(PyExc_SyntaxError, NAMED_EXPR_COMP_CONFLICT, target_name); PyErr_RangedSyntaxLocationObject(st->st_filename, e->lineno, @@ -1529,9 +1881,27 @@ symtable_extend_namedexpr_scope(struct symtable *st, expr_ty e) return symtable_add_def_helper(st, target_name, DEF_GLOBAL, ste, LOCATION(e)); } - /* Disallow usage in ClassBlock */ - if (ste->ste_type == ClassBlock) { - PyErr_Format(PyExc_SyntaxError, NAMED_EXPR_COMP_IN_CLASS); + /* Disallow usage in ClassBlock and type scopes */ + if (ste->ste_type == ClassBlock || + ste->ste_type == TypeParamBlock || + ste->ste_type == TypeAliasBlock || + ste->ste_type == TypeVarBoundBlock) { + switch (ste->ste_type) { + case ClassBlock: + PyErr_Format(PyExc_SyntaxError, NAMED_EXPR_COMP_IN_CLASS); + break; + case TypeParamBlock: + PyErr_Format(PyExc_SyntaxError, NAMED_EXPR_COMP_IN_TYPEPARAM); + break; + case TypeAliasBlock: + PyErr_Format(PyExc_SyntaxError, NAMED_EXPR_COMP_IN_TYPEALIAS); + break; + case TypeVarBoundBlock: + PyErr_Format(PyExc_SyntaxError, NAMED_EXPR_COMP_IN_TYPEVAR_BOUND); + break; + default: + Py_UNREACHABLE(); + } PyErr_RangedSyntaxLocationObject(st->st_filename, e->lineno, e->col_offset + 1, @@ -1541,10 +1911,10 @@ symtable_extend_namedexpr_scope(struct symtable *st, expr_ty e) } } - /* We should always find either a FunctionBlock, ModuleBlock or ClassBlock + /* We should always find either a function-like block, ModuleBlock or ClassBlock and should never fall to this case */ - assert(0); + Py_UNREACHABLE(); return 0; } @@ -1598,6 +1968,17 @@ symtable_visit_expr(struct symtable *st, expr_ty e) VISIT(st, expr, e->v.UnaryOp.operand); break; case Lambda_kind: { + if (st->st_cur->ste_can_see_class_scope) { + // gh-109118 + PyErr_Format(PyExc_SyntaxError, + "Cannot use lambda in annotation scope within class scope"); + PyErr_RangedSyntaxLocationObject(st->st_filename, + e->lineno, + e->col_offset + 1, + e->end_lineno, + e->end_col_offset + 1); + VISIT_QUIT(st, 0); + } if (e->v.Lambda.args->defaults) VISIT_SEQ(st, expr, e->v.Lambda.args->defaults); if (e->v.Lambda.args->kw_defaults) @@ -1714,7 +2095,7 @@ symtable_visit_expr(struct symtable *st, expr_ty e) VISIT_QUIT(st, 0); /* Special-case super: it counts as a use of __class__ */ if (e->v.Name.ctx == Load && - st->st_cur->ste_type == FunctionBlock && + _PyST_IsFunctionLike(st->st_cur) && _PyUnicode_EqualToASCIIString(e->v.Name.id, "super")) { if (!symtable_add_def(st, &_Py_ID(__class__), USE, LOCATION(e))) VISIT_QUIT(st, 0); @@ -1731,6 +2112,45 @@ symtable_visit_expr(struct symtable *st, expr_ty e) VISIT_QUIT(st, 1); } +static int +symtable_visit_type_param(struct symtable *st, type_param_ty tp) +{ + if (++st->recursion_depth > st->recursion_limit) { + PyErr_SetString(PyExc_RecursionError, + "maximum recursion depth exceeded during compilation"); + VISIT_QUIT(st, 0); + } + switch(tp->kind) { + case TypeVar_kind: + if (!symtable_add_def(st, tp->v.TypeVar.name, DEF_TYPE_PARAM | DEF_LOCAL, LOCATION(tp))) + VISIT_QUIT(st, 0); + if (tp->v.TypeVar.bound) { + int is_in_class = st->st_cur->ste_can_see_class_scope; + if (!symtable_enter_block(st, tp->v.TypeVar.name, + TypeVarBoundBlock, (void *)tp, + LOCATION(tp))) + VISIT_QUIT(st, 0); + st->st_cur->ste_can_see_class_scope = is_in_class; + if (is_in_class && !symtable_add_def(st, &_Py_ID(__classdict__), USE, LOCATION(tp->v.TypeVar.bound))) { + VISIT_QUIT(st, 0); + } + VISIT(st, expr, tp->v.TypeVar.bound); + if (!symtable_exit_block(st)) + VISIT_QUIT(st, 0); + } + break; + case TypeVarTuple_kind: + if (!symtable_add_def(st, tp->v.TypeVarTuple.name, DEF_TYPE_PARAM | DEF_LOCAL, LOCATION(tp))) + VISIT_QUIT(st, 0); + break; + case ParamSpec_kind: + if (!symtable_add_def(st, tp->v.ParamSpec.name, DEF_TYPE_PARAM | DEF_LOCAL, LOCATION(tp))) + VISIT_QUIT(st, 0); + break; + } + VISIT_QUIT(st, 1); +} + static int symtable_visit_pattern(struct symtable *st, pattern_ty p) { @@ -1952,8 +2372,7 @@ symtable_visit_alias(struct symtable *st, alias_ty a) return 0; } else { - store_name = name; - Py_INCREF(store_name); + store_name = Py_NewRef(name); } if (!_PyUnicode_EqualToASCIIString(name, "*")) { int r = symtable_add_def(st, store_name, DEF_IMPORT, LOCATION(a)); @@ -2009,6 +2428,18 @@ symtable_handle_comprehension(struct symtable *st, expr_ty e, identifier scope_name, asdl_comprehension_seq *generators, expr_ty elt, expr_ty value) { + if (st->st_cur->ste_can_see_class_scope) { + // gh-109118 + PyErr_Format(PyExc_SyntaxError, + "Cannot use comprehension in annotation scope within class scope"); + PyErr_RangedSyntaxLocationObject(st->st_filename, + e->lineno, + e->col_offset + 1, + e->end_lineno, + e->end_col_offset + 1); + VISIT_QUIT(st, 0); + } + int is_generator = (e->kind == GeneratorExp_kind); comprehension_ty outermost = ((comprehension_ty) asdl_seq_GET(generators, 0)); @@ -2103,11 +2534,18 @@ symtable_visit_dictcomp(struct symtable *st, expr_ty e) static int symtable_raise_if_annotation_block(struct symtable *st, const char *name, expr_ty e) { - if (st->st_cur->ste_type != AnnotationBlock) { + enum _block_type type = st->st_cur->ste_type; + if (type == AnnotationBlock) + PyErr_Format(PyExc_SyntaxError, ANNOTATION_NOT_ALLOWED, name); + else if (type == TypeVarBoundBlock) + PyErr_Format(PyExc_SyntaxError, TYPEVAR_BOUND_NOT_ALLOWED, name); + else if (type == TypeAliasBlock) + PyErr_Format(PyExc_SyntaxError, TYPEALIAS_NOT_ALLOWED, name); + else if (type == TypeParamBlock) + PyErr_Format(PyExc_SyntaxError, TYPEPARAM_NOT_ALLOWED, name); + else return 1; - } - PyErr_Format(PyExc_SyntaxError, ANNOTATION_NOT_ALLOWED, name); PyErr_RangedSyntaxLocationObject(st->st_filename, e->lineno, e->col_offset + 1, @@ -2147,14 +2585,78 @@ _Py_SymtableStringObjectFlags(const char *str, PyObject *filename, _PyArena_Free(arena); return NULL; } - PyFutureFeatures *future = _PyFuture_FromAST(mod, filename); - if (future == NULL) { + PyFutureFeatures future; + if (!_PyFuture_FromAST(mod, filename, &future)) { _PyArena_Free(arena); return NULL; } - future->ff_features |= flags->cf_flags; - st = _PySymtable_Build(mod, filename, future); - PyObject_Free((void *)future); + future.ff_features |= flags->cf_flags; + st = _PySymtable_Build(mod, filename, &future); _PyArena_Free(arena); return st; } + +PyObject * +_Py_Mangle(PyObject *privateobj, PyObject *ident) +{ + /* Name mangling: __private becomes _classname__private. + This is independent from how the name is used. */ + if (privateobj == NULL || !PyUnicode_Check(privateobj) || + PyUnicode_READ_CHAR(ident, 0) != '_' || + PyUnicode_READ_CHAR(ident, 1) != '_') { + return Py_NewRef(ident); + } + size_t nlen = PyUnicode_GET_LENGTH(ident); + size_t plen = PyUnicode_GET_LENGTH(privateobj); + /* Don't mangle __id__ or names with dots. + + The only time a name with a dot can occur is when + we are compiling an import statement that has a + package name. + + TODO(jhylton): Decide whether we want to support + mangling of the module name, e.g. __M.X. + */ + if ((PyUnicode_READ_CHAR(ident, nlen-1) == '_' && + PyUnicode_READ_CHAR(ident, nlen-2) == '_') || + PyUnicode_FindChar(ident, '.', 0, nlen, 1) != -1) { + return Py_NewRef(ident); /* Don't mangle __whatever__ */ + } + /* Strip leading underscores from class name */ + size_t ipriv = 0; + while (PyUnicode_READ_CHAR(privateobj, ipriv) == '_') { + ipriv++; + } + if (ipriv == plen) { + return Py_NewRef(ident); /* Don't mangle if class is just underscores */ + } + plen -= ipriv; + + if (plen + nlen >= PY_SSIZE_T_MAX - 1) { + PyErr_SetString(PyExc_OverflowError, + "private identifier too large to be mangled"); + return NULL; + } + + Py_UCS4 maxchar = PyUnicode_MAX_CHAR_VALUE(ident); + if (PyUnicode_MAX_CHAR_VALUE(privateobj) > maxchar) { + maxchar = PyUnicode_MAX_CHAR_VALUE(privateobj); + } + + PyObject *result = PyUnicode_New(1 + nlen + plen, maxchar); + if (!result) { + return NULL; + } + /* ident = "_" + priv[ipriv:] + ident # i.e. 1+plen+nlen bytes */ + PyUnicode_WRITE(PyUnicode_KIND(result), PyUnicode_DATA(result), 0, '_'); + if (PyUnicode_CopyCharacters(result, 1, privateobj, ipriv, plen) < 0) { + Py_DECREF(result); + return NULL; + } + if (PyUnicode_CopyCharacters(result, plen+1, ident, 0, nlen) < 0) { + Py_DECREF(result); + return NULL; + } + assert(_PyUnicode_CheckConsistency(result, 1)); + return result; +} diff --git a/Python/sysmodule.c b/Python/sysmodule.c index 68a835a3..4bd38b4b 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -17,19 +17,18 @@ Data members: #include "Python.h" #include "pycore_call.h" // _PyObject_CallNoArgs() #include "pycore_ceval.h" // _PyEval_SetAsyncGenFinalizer() -#include "pycore_code.h" // _Py_QuickenedCount #include "pycore_frame.h" // _PyInterpreterFrame #include "pycore_initconfig.h" // _PyStatus_EXCEPTION() #include "pycore_long.h" // _PY_LONG_MAX_STR_DIGITS_THRESHOLD #include "pycore_namespace.h" // _PyNamespace_New() #include "pycore_object.h" // _PyObject_IS_GC() #include "pycore_pathconfig.h" // _PyPathConfig_ComputeSysPath0() -#include "pycore_pyerrors.h" // _PyErr_Fetch() +#include "pycore_pyerrors.h" // _PyErr_GetRaisedException() #include "pycore_pylifecycle.h" // _PyErr_WriteUnraisableDefaultHook() #include "pycore_pymath.h" // _PY_SHORT_FLOAT_REPR #include "pycore_pymem.h" // _PyMem_SetDefaultAllocator() #include "pycore_pystate.h" // _PyThreadState_GET() -#include "pycore_structseq.h" // _PyStructSequence_InitType() +#include "pycore_structseq.h" // _PyStructSequence_InitBuiltinWithFlags() #include "pycore_tuple.h" // _PyTuple_FromArray() #include "frameobject.h" // PyFrame_FastToLocalsWithError() @@ -53,6 +52,10 @@ extern const char *PyWin_DLLVersionString; #include <emscripten.h> #endif +#ifdef HAVE_FCNTL_H +#include <fcntl.h> +#endif + /*[clinic input] module sys [clinic start generated code]*/ @@ -67,12 +70,11 @@ _PySys_GetAttr(PyThreadState *tstate, PyObject *name) if (sd == NULL) { return NULL; } - PyObject *exc_type, *exc_value, *exc_tb; - _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb); + PyObject *exc = _PyErr_GetRaisedException(tstate); /* XXX Suppress a new exception if it was raised and restore * the old one. */ PyObject *value = _PyDict_GetItemWithError(sd, name); - _PyErr_Restore(tstate, exc_type, exc_value, exc_tb); + _PyErr_SetRaisedException(tstate, exc); return value; } @@ -91,12 +93,11 @@ PySys_GetObject(const char *name) { PyThreadState *tstate = _PyThreadState_GET(); - PyObject *exc_type, *exc_value, *exc_tb; - _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb); + PyObject *exc = _PyErr_GetRaisedException(tstate); PyObject *value = _PySys_GetObject(tstate->interp, name); /* XXX Suppress a new exception if it was raised and restore * the old one. */ - _PyErr_Restore(tstate, exc_type, exc_value, exc_tb); + _PyErr_SetRaisedException(tstate, exc); return value; } @@ -144,6 +145,20 @@ PySys_SetObject(const char *name, PyObject *v) return sys_set_object_str(interp, name, v); } +int +_PySys_ClearAttrString(PyInterpreterState *interp, + const char *name, int verbose) +{ + if (verbose) { + PySys_WriteStderr("# clear sys.%s\n", name); + } + /* To play it safe, we set the attr to None instead of deleting it. */ + if (PyDict_SetItemString(interp->sysdict, name, Py_None) < 0) { + return -1; + } + return 0; +} + static int should_audit(PyInterpreterState *interp) @@ -153,7 +168,7 @@ should_audit(PyInterpreterState *interp) if (!interp) { return 0; } - return (interp->runtime->audit_hook_head + return (interp->runtime->audit_hooks.head || interp->audit_hooks || PyDTrace_AUDIT_ENABLED()); } @@ -191,16 +206,15 @@ sys_audit_tstate(PyThreadState *ts, const char *event, int dtrace = PyDTrace_AUDIT_ENABLED(); - PyObject *exc_type, *exc_value, *exc_tb; - _PyErr_Fetch(ts, &exc_type, &exc_value, &exc_tb); + + PyObject *exc = _PyErr_GetRaisedException(ts); /* Initialize event args now */ if (argFormat && argFormat[0]) { eventArgs = _Py_VaBuildValue_SizeT(argFormat, vargs); if (eventArgs && !PyTuple_Check(eventArgs)) { PyObject *argTuple = PyTuple_Pack(1, eventArgs); - Py_DECREF(eventArgs); - eventArgs = argTuple; + Py_SETREF(eventArgs, argTuple); } } else { @@ -210,8 +224,11 @@ sys_audit_tstate(PyThreadState *ts, const char *event, goto exit; } - /* Call global hooks */ - _Py_AuditHookEntry *e = is->runtime->audit_hook_head; + /* Call global hooks + * + * We don't worry about any races on hooks getting added, + * since that would not leave is in an inconsistent state. */ + _Py_AuditHookEntry *e = is->runtime->audit_hooks.head; for (; e; e = e->next) { if (e->hookCFunction(event, eventArgs, e->userData) < 0) { goto exit; @@ -276,13 +293,11 @@ exit: Py_XDECREF(eventArgs); if (!res) { - _PyErr_Restore(ts, exc_type, exc_value, exc_tb); + _PyErr_SetRaisedException(ts, exc); } else { assert(_PyErr_Occurred(ts)); - Py_XDECREF(exc_type); - Py_XDECREF(exc_value); - Py_XDECREF(exc_tb); + Py_XDECREF(exc); } return res; @@ -293,11 +308,7 @@ _PySys_Audit(PyThreadState *tstate, const char *event, const char *argFormat, ...) { va_list vargs; -#ifdef HAVE_STDARG_PROTOTYPES va_start(vargs, argFormat); -#else - va_start(vargs); -#endif int res = sys_audit_tstate(tstate, event, argFormat, vargs); va_end(vargs); return res; @@ -308,11 +319,7 @@ PySys_Audit(const char *event, const char *argFormat, ...) { PyThreadState *tstate = _PyThreadState_GET(); va_list vargs; -#ifdef HAVE_STDARG_PROTOTYPES va_start(vargs, argFormat); -#else - va_start(vargs); -#endif int res = sys_audit_tstate(tstate, event, argFormat, vargs); va_end(vargs); return res; @@ -332,6 +339,7 @@ _PySys_ClearAuditHooks(PyThreadState *ts) } _PyRuntimeState *runtime = ts->interp->runtime; + /* The hooks are global so we have to check for runtime finalization. */ PyThreadState *finalizing = _PyRuntimeState_GetFinalizing(runtime); assert(finalizing == ts); if (finalizing != ts) { @@ -348,8 +356,12 @@ _PySys_ClearAuditHooks(PyThreadState *ts) _PySys_Audit(ts, "cpython._PySys_ClearAuditHooks", NULL); _PyErr_Clear(ts); - _Py_AuditHookEntry *e = runtime->audit_hook_head, *n; - runtime->audit_hook_head = NULL; + /* We don't worry about the very unlikely race right here, + * since it's entirely benign. Nothing else removes entries + * from the list and adding an entry right now would not cause + * any trouble. */ + _Py_AuditHookEntry *e = runtime->audit_hooks.head, *n; + runtime->audit_hooks.head = NULL; while (e) { n = e->next; PyMem_RawFree(e); @@ -357,6 +369,22 @@ _PySys_ClearAuditHooks(PyThreadState *ts) } } +static void +add_audit_hook_entry_unlocked(_PyRuntimeState *runtime, + _Py_AuditHookEntry *entry) +{ + if (runtime->audit_hooks.head == NULL) { + runtime->audit_hooks.head = entry; + } + else { + _Py_AuditHookEntry *last = runtime->audit_hooks.head; + while (last->next) { + last = last->next; + } + last->next = entry; + } +} + int PySys_AddAuditHook(Py_AuditHookFunction hook, void *userData) { @@ -365,7 +393,7 @@ PySys_AddAuditHook(Py_AuditHookFunction hook, void *userData) _PyRuntimeState *runtime = &_PyRuntime; PyThreadState *tstate; if (runtime->initialized) { - tstate = _PyRuntimeState_GetThreadState(runtime); + tstate = _PyThreadState_GET(); } else { tstate = NULL; @@ -384,29 +412,28 @@ PySys_AddAuditHook(Py_AuditHookFunction hook, void *userData) } } - _Py_AuditHookEntry *e = runtime->audit_hook_head; - if (!e) { - e = (_Py_AuditHookEntry*)PyMem_RawMalloc(sizeof(_Py_AuditHookEntry)); - runtime->audit_hook_head = e; - } else { - while (e->next) { - e = e->next; - } - e = e->next = (_Py_AuditHookEntry*)PyMem_RawMalloc( + _Py_AuditHookEntry *e = (_Py_AuditHookEntry*)PyMem_RawMalloc( sizeof(_Py_AuditHookEntry)); - } - if (!e) { if (tstate != NULL) { _PyErr_NoMemory(tstate); } return -1; } - e->next = NULL; e->hookCFunction = (Py_AuditHookFunction)hook; e->userData = userData; + if (runtime->audit_hooks.mutex == NULL) { + /* The runtime must not be initailized yet. */ + add_audit_hook_entry_unlocked(runtime, e); + } + else { + PyThread_acquire_lock(runtime->audit_hooks.mutex, WAIT_LOCK); + add_audit_hook_entry_unlocked(runtime, e); + PyThread_release_lock(runtime->audit_hooks.mutex); + } + return 0; } @@ -742,7 +769,7 @@ sys_excepthook_impl(PyObject *module, PyObject *exctype, PyObject *value, PyObject *traceback) /*[clinic end generated code: output=18d99fdda21b6b5e input=ecf606fa826f19d9]*/ { - PyErr_Display(exctype, value, traceback); + PyErr_Display(NULL, value, traceback); Py_RETURN_NONE; } @@ -849,8 +876,7 @@ sys_getdefaultencoding_impl(PyObject *module) { _Py_DECLARE_STR(utf_8, "utf-8"); PyObject *ret = &_Py_STR(utf_8); - Py_INCREF(ret); - return ret; + return Py_NewRef(ret); } /*[clinic input] @@ -950,10 +976,6 @@ call_trampoline(PyThreadState *tstate, PyObject* callback, PyObject *result = _PyObject_FastCallTstate(tstate, callback, stack, 3); PyFrame_LocalsToFast(frame, 1); - if (result == NULL) { - PyTraceBack_Here(frame); - } - return result; } @@ -961,10 +983,6 @@ static int profile_trampoline(PyObject *self, PyFrameObject *frame, int what, PyObject *arg) { - if (arg == NULL) { - arg = Py_None; - } - PyThreadState *tstate = _PyThreadState_GET(); PyObject *result = call_trampoline(tstate, self, frame, what, arg); if (result == NULL) { @@ -1032,6 +1050,36 @@ Set the global debug tracing function. It will be called on each\n\ function call. See the debugger chapter in the library manual." ); +/*[clinic input] +sys._settraceallthreads + + arg: object + / + +Set the global debug tracing function in all running threads belonging to the current interpreter. + +It will be called on each function call. See the debugger chapter +in the library manual. +[clinic start generated code]*/ + +static PyObject * +sys__settraceallthreads(PyObject *module, PyObject *arg) +/*[clinic end generated code: output=161cca30207bf3ca input=5906aa1485a50289]*/ +{ + PyObject* argument = NULL; + Py_tracefunc func = NULL; + + if (arg != Py_None) { + func = trace_trampoline; + argument = arg; + } + + + PyEval_SetTraceAllThreads(func, argument); + + Py_RETURN_NONE; +} + /*[clinic input] sys.gettrace @@ -1049,8 +1097,7 @@ sys_gettrace_impl(PyObject *module) if (temp == NULL) temp = Py_None; - Py_INCREF(temp); - return temp; + return Py_NewRef(temp); } static PyObject * @@ -1077,6 +1124,35 @@ Set the profiling function. It will be called on each function call\n\ and return. See the profiler chapter in the library manual." ); +/*[clinic input] +sys._setprofileallthreads + + arg: object + / + +Set the profiling function in all running threads belonging to the current interpreter. + +It will be called on each function call and return. See the profiler chapter +in the library manual. +[clinic start generated code]*/ + +static PyObject * +sys__setprofileallthreads(PyObject *module, PyObject *arg) +/*[clinic end generated code: output=2d61319e27b309fe input=d1a356d3f4f9060a]*/ +{ + PyObject* argument = NULL; + Py_tracefunc func = NULL; + + if (arg != Py_None) { + func = profile_trampoline; + argument = arg; + } + + PyEval_SetProfileAllThreads(func, argument); + + Py_RETURN_NONE; +} + /*[clinic input] sys.getprofile @@ -1094,8 +1170,7 @@ sys_getprofile_impl(PyObject *module) if (temp == NULL) temp = Py_None; - Py_INCREF(temp); - return temp; + return Py_NewRef(temp); } @@ -1169,7 +1244,7 @@ sys_setrecursionlimit_impl(PyObject *module, int new_limit) /* Reject too low new limit if the current recursion depth is higher than the new low-water mark. */ - int depth = tstate->recursion_limit - tstate->recursion_remaining; + int depth = tstate->py_recursion_limit - tstate->py_recursion_remaining; if (depth >= new_limit) { _PyErr_Format(tstate, PyExc_RecursionError, "cannot set the recursion limit to %i at " @@ -1320,11 +1395,8 @@ sys_get_asyncgen_hooks_impl(PyObject *module) finalizer = Py_None; } - Py_INCREF(firstiter); - PyStructSequence_SET_ITEM(res, 0, firstiter); - - Py_INCREF(finalizer); - PyStructSequence_SET_ITEM(res, 1, finalizer); + PyStructSequence_SET_ITEM(res, 0, Py_NewRef(firstiter)); + PyStructSequence_SET_ITEM(res, 1, Py_NewRef(finalizer)); return res; } @@ -1438,6 +1510,48 @@ static PyStructSequence_Desc windows_version_desc = { via indexing, the rest are name only */ }; +static PyObject * +_sys_getwindowsversion_from_kernel32(void) +{ +#ifndef MS_WINDOWS_DESKTOP + return NULL; +#else + HANDLE hKernel32; + wchar_t kernel32_path[MAX_PATH]; + LPVOID verblock; + DWORD verblock_size; + VS_FIXEDFILEINFO *ffi; + UINT ffi_len; + DWORD realMajor, realMinor, realBuild; + + Py_BEGIN_ALLOW_THREADS + hKernel32 = GetModuleHandleW(L"kernel32.dll"); + Py_END_ALLOW_THREADS + if (!hKernel32 || !GetModuleFileNameW(hKernel32, kernel32_path, MAX_PATH)) { + PyErr_SetFromWindowsErr(0); + return NULL; + } + verblock_size = GetFileVersionInfoSizeW(kernel32_path, NULL); + if (!verblock_size) { + PyErr_SetFromWindowsErr(0); + return NULL; + } + verblock = PyMem_RawMalloc(verblock_size); + if (!verblock || + !GetFileVersionInfoW(kernel32_path, 0, verblock_size, verblock) || + !VerQueryValueW(verblock, L"", (LPVOID)&ffi, &ffi_len)) { + PyErr_SetFromWindowsErr(0); + return NULL; + } + + realMajor = HIWORD(ffi->dwProductVersionMS); + realMinor = LOWORD(ffi->dwProductVersionMS); + realBuild = HIWORD(ffi->dwProductVersionLS); + PyMem_RawFree(verblock); + return Py_BuildValue("(kkk)", realMajor, realMinor, realBuild); +#endif /* !MS_WINDOWS_DESKTOP */ +} + /* Disable deprecation warnings about GetVersionEx as the result is being passed straight through to the caller, who is responsible for using it correctly. */ @@ -1467,11 +1581,13 @@ sys_getwindowsversion_impl(PyObject *module) PyObject *version; int pos = 0; OSVERSIONINFOEXW ver; - DWORD realMajor, realMinor, realBuild; - HANDLE hKernel32; - wchar_t kernel32_path[MAX_PATH]; - LPVOID verblock; - DWORD verblock_size; + + version = PyObject_GetAttrString(module, "_cached_windows_version"); + if (version && PyObject_TypeCheck(version, &WindowsVersionType)) { + return version; + } + Py_XDECREF(version); + PyErr_Clear(); ver.dwOSVersionInfoSize = sizeof(ver); if (!GetVersionExW((OSVERSIONINFOW*) &ver)) @@ -1491,41 +1607,34 @@ sys_getwindowsversion_impl(PyObject *module) PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.wSuiteMask)); PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.wProductType)); - realMajor = ver.dwMajorVersion; - realMinor = ver.dwMinorVersion; - realBuild = ver.dwBuildNumber; - // GetVersion will lie if we are running in a compatibility mode. // We need to read the version info from a system file resource // to accurately identify the OS version. If we fail for any reason, // just return whatever GetVersion said. - Py_BEGIN_ALLOW_THREADS - hKernel32 = GetModuleHandleW(L"kernel32.dll"); - Py_END_ALLOW_THREADS - if (hKernel32 && GetModuleFileNameW(hKernel32, kernel32_path, MAX_PATH) && - (verblock_size = GetFileVersionInfoSizeW(kernel32_path, NULL)) && - (verblock = PyMem_RawMalloc(verblock_size))) { - VS_FIXEDFILEINFO *ffi; - UINT ffi_len; - - if (GetFileVersionInfoW(kernel32_path, 0, verblock_size, verblock) && - VerQueryValueW(verblock, L"", (LPVOID)&ffi, &ffi_len)) { - realMajor = HIWORD(ffi->dwProductVersionMS); - realMinor = LOWORD(ffi->dwProductVersionMS); - realBuild = HIWORD(ffi->dwProductVersionLS); - } - PyMem_RawFree(verblock); + PyObject *realVersion = _sys_getwindowsversion_from_kernel32(); + if (!realVersion) { + PyErr_Clear(); + realVersion = Py_BuildValue("(kkk)", + ver.dwMajorVersion, + ver.dwMinorVersion, + ver.dwBuildNumber + ); + } + + if (realVersion) { + PyStructSequence_SET_ITEM(version, pos++, realVersion); } - PyStructSequence_SET_ITEM(version, pos++, Py_BuildValue("(kkk)", - realMajor, - realMinor, - realBuild - )); if (PyErr_Occurred()) { Py_DECREF(version); return NULL; } + + if (PyObject_SetAttrString(module, "_cached_windows_version", version) < 0) { + Py_DECREF(version); + return NULL; + } + return version; } @@ -1579,7 +1688,7 @@ sys_setdlopenflags_impl(PyObject *module, int new_val) /*[clinic end generated code: output=ec918b7fe0a37281 input=4c838211e857a77f]*/ { PyInterpreterState *interp = _PyInterpreterState_GET(); - interp->dlopenflags = new_val; + _PyImport_SetDLOpenFlags(interp, new_val); Py_RETURN_NONE; } @@ -1597,7 +1706,8 @@ sys_getdlopenflags_impl(PyObject *module) /*[clinic end generated code: output=e92cd1bc5005da6e input=dc4ea0899c53b4b6]*/ { PyInterpreterState *interp = _PyInterpreterState_GET(); - return PyLong_FromLong(interp->dlopenflags); + return PyLong_FromLong( + _PyImport_GetDLOpenFlags(interp)); } #endif /* HAVE_DLOPEN */ @@ -1635,7 +1745,7 @@ sys_get_int_max_str_digits_impl(PyObject *module) /*[clinic end generated code: output=0042f5e8ae0e8631 input=61bf9f99bc8b112d]*/ { PyInterpreterState *interp = _PyInterpreterState_GET(); - return PyLong_FromSsize_t(interp->int_max_str_digits); + return PyLong_FromLong(interp->long_state.max_str_digits); } /*[clinic input] @@ -1652,7 +1762,7 @@ sys_set_int_max_str_digits_impl(PyObject *module, int maxdigits) { PyThreadState *tstate = _PyThreadState_GET(); if ((!maxdigits) || (maxdigits >= _PY_LONG_MAX_STR_DIGITS_THRESHOLD)) { - tstate->interp->int_max_str_digits = maxdigits; + tstate->interp->long_state.max_str_digits = maxdigits; Py_RETURN_NONE; } else { PyErr_Format( @@ -1724,8 +1834,7 @@ sys_getsizeof(PyObject *self, PyObject *args, PyObject *kwds) /* Has a default value been given */ if (dflt != NULL && _PyErr_ExceptionMatches(tstate, PyExc_TypeError)) { _PyErr_Clear(tstate); - Py_INCREF(dflt); - return dflt; + return Py_NewRef(dflt); } else return NULL; @@ -1768,36 +1877,41 @@ static Py_ssize_t sys_gettotalrefcount_impl(PyObject *module) /*[clinic end generated code: output=4103886cf17c25bc input=53b744faa5d2e4f6]*/ { - return _Py_GetRefTotal(); + /* It may make sense to return the total for the current interpreter + or have a second function that does so. */ + return _Py_GetGlobalRefTotal(); } #endif /* Py_REF_DEBUG */ /*[clinic input] -sys._getquickenedcount -> Py_ssize_t +sys.getallocatedblocks -> Py_ssize_t + +Return the number of memory blocks currently allocated. [clinic start generated code]*/ static Py_ssize_t -sys__getquickenedcount_impl(PyObject *module) -/*[clinic end generated code: output=1ab259e7f91248a2 input=249d448159eca912]*/ +sys_getallocatedblocks_impl(PyObject *module) +/*[clinic end generated code: output=f0c4e873f0b6dcf7 input=dab13ee346a0673e]*/ { - return _Py_QuickenedCount; + // It might make sense to return the count + // for just the current interpreter. + return _Py_GetGlobalAllocatedBlocks(); } /*[clinic input] -sys.getallocatedblocks -> Py_ssize_t +sys.getunicodeinternedsize -> Py_ssize_t -Return the number of memory blocks currently allocated. +Return the number of elements of the unicode interned dictionary [clinic start generated code]*/ static Py_ssize_t -sys_getallocatedblocks_impl(PyObject *module) -/*[clinic end generated code: output=f0c4e873f0b6dcf7 input=dab13ee346a0673e]*/ +sys_getunicodeinternedsize_impl(PyObject *module) +/*[clinic end generated code: output=ad0e4c9738ed4129 input=726298eaa063347a]*/ { - return _Py_GetAllocatedBlocks(); + return _PyUnicode_InternedSize(); } - /*[clinic input] sys._getframe @@ -1824,13 +1938,10 @@ sys__getframe_impl(PyObject *module, int depth) if (frame != NULL) { while (depth > 0) { - frame = frame->previous; + frame = _PyFrame_GetFirstComplete(frame->previous); if (frame == NULL) { break; } - if (_PyFrame_IsIncomplete(frame)) { - continue; - } --depth; } } @@ -1932,11 +2043,6 @@ sys__debugmallocstats_impl(PyObject *module) extern PyObject *_Py_GetObjects(PyObject *, PyObject *); #endif -#ifdef Py_STATS -/* Defined in ceval.c because it uses static globals in that file */ -extern PyObject *_Py_GetDXProfile(PyObject *, PyObject *); -#endif - #ifdef __cplusplus } #endif @@ -1956,6 +2062,9 @@ sys__clear_type_cache_impl(PyObject *module) Py_RETURN_NONE; } +/* Note that, for now, we do not have a per-interpreter equivalent + for sys.is_finalizing(). */ + /*[clinic input] sys.is_finalizing @@ -1969,6 +2078,66 @@ sys_is_finalizing_impl(PyObject *module) return PyBool_FromLong(_Py_IsFinalizing()); } +#ifdef Py_STATS +/*[clinic input] +sys._stats_on + +Turns on stats gathering (stats gathering is on by default). +[clinic start generated code]*/ + +static PyObject * +sys__stats_on_impl(PyObject *module) +/*[clinic end generated code: output=aca53eafcbb4d9fe input=8ddc6df94e484f3a]*/ +{ + _py_stats = &_py_stats_struct; + Py_RETURN_NONE; +} + +/*[clinic input] +sys._stats_off + +Turns off stats gathering (stats gathering is on by default). +[clinic start generated code]*/ + +static PyObject * +sys__stats_off_impl(PyObject *module) +/*[clinic end generated code: output=1534c1ee63812214 input=b3e50e71ecf29f66]*/ +{ + _py_stats = NULL; + Py_RETURN_NONE; +} + +/*[clinic input] +sys._stats_clear + +Clears the stats. +[clinic start generated code]*/ + +static PyObject * +sys__stats_clear_impl(PyObject *module) +/*[clinic end generated code: output=fb65a2525ee50604 input=3e03f2654f44da96]*/ +{ + _Py_StatsClear(); + Py_RETURN_NONE; +} + +/*[clinic input] +sys._stats_dump + +Dump stats to file, and clears the stats. +[clinic start generated code]*/ + +static PyObject * +sys__stats_dump_impl(PyObject *module) +/*[clinic end generated code: output=79f796fb2b4ddf05 input=92346f16d64f6f95]*/ +{ + _Py_PrintSpecializationStats(1); + _Py_StatsClear(); + Py_RETURN_NONE; +} + +#endif + #ifdef ANDROID_API_LEVEL /*[clinic input] sys.getandroidapilevel @@ -1984,6 +2153,196 @@ sys_getandroidapilevel_impl(PyObject *module) } #endif /* ANDROID_API_LEVEL */ +/*[clinic input] +sys.activate_stack_trampoline + + backend: str + / + +Activate stack profiler trampoline *backend*. +[clinic start generated code]*/ + +static PyObject * +sys_activate_stack_trampoline_impl(PyObject *module, const char *backend) +/*[clinic end generated code: output=5783cdeb51874b43 input=a12df928758a82b4]*/ +{ +#ifdef PY_HAVE_PERF_TRAMPOLINE + if (strcmp(backend, "perf") == 0) { + _PyPerf_Callbacks cur_cb; + _PyPerfTrampoline_GetCallbacks(&cur_cb); + if (cur_cb.write_state != _Py_perfmap_callbacks.write_state) { + if (_PyPerfTrampoline_SetCallbacks(&_Py_perfmap_callbacks) < 0 ) { + PyErr_SetString(PyExc_ValueError, "can't activate perf trampoline"); + return NULL; + } + } + } + else { + PyErr_Format(PyExc_ValueError, "invalid backend: %s", backend); + return NULL; + } + if (_PyPerfTrampoline_Init(1) < 0) { + return NULL; + } + Py_RETURN_NONE; +#else + PyErr_SetString(PyExc_ValueError, "perf trampoline not available"); + return NULL; +#endif +} + + +/*[clinic input] +sys.deactivate_stack_trampoline + +Deactivate the current stack profiler trampoline backend. + +If no stack profiler is activated, this function has no effect. +[clinic start generated code]*/ + +static PyObject * +sys_deactivate_stack_trampoline_impl(PyObject *module) +/*[clinic end generated code: output=b50da25465df0ef1 input=9f629a6be9fe7fc8]*/ +{ + if (_PyPerfTrampoline_Init(0) < 0) { + return NULL; + } + Py_RETURN_NONE; +} + +/*[clinic input] +sys.is_stack_trampoline_active + +Return *True* if a stack profiler trampoline is active. +[clinic start generated code]*/ + +static PyObject * +sys_is_stack_trampoline_active_impl(PyObject *module) +/*[clinic end generated code: output=ab2746de0ad9d293 input=29616b7bf6a0b703]*/ +{ +#ifdef PY_HAVE_PERF_TRAMPOLINE + if (_PyIsPerfTrampolineActive()) { + Py_RETURN_TRUE; + } +#endif + Py_RETURN_FALSE; +} + + +/*[clinic input] +sys._getframemodulename + + depth: int = 0 + +Return the name of the module for a calling frame. + +The default depth returns the module containing the call to this API. +A more typical use in a library will pass a depth of 1 to get the user's +module rather than the library module. + +If no frame, module, or name can be found, returns None. +[clinic start generated code]*/ + +static PyObject * +sys__getframemodulename_impl(PyObject *module, int depth) +/*[clinic end generated code: output=1d70ef691f09d2db input=d4f1a8ed43b8fb46]*/ +{ + if (PySys_Audit("sys._getframemodulename", "i", depth) < 0) { + return NULL; + } + _PyInterpreterFrame *f = _PyThreadState_GET()->cframe->current_frame; + while (f && (_PyFrame_IsIncomplete(f) || depth-- > 0)) { + f = f->previous; + } + if (f == NULL || f->f_funcobj == NULL) { + Py_RETURN_NONE; + } + PyObject *r = PyFunction_GetModule(f->f_funcobj); + if (!r) { + PyErr_Clear(); + r = Py_None; + } + return Py_NewRef(r); +} + + +#ifdef __cplusplus +extern "C" { +#endif + +static PerfMapState perf_map_state; + +PyAPI_FUNC(int) PyUnstable_PerfMapState_Init(void) { +#ifndef MS_WINDOWS + char filename[100]; + pid_t pid = getpid(); + // Use nofollow flag to prevent symlink attacks. + int flags = O_WRONLY | O_CREAT | O_APPEND | O_NOFOLLOW; +#ifdef O_CLOEXEC + flags |= O_CLOEXEC; +#endif + snprintf(filename, sizeof(filename) - 1, "/tmp/perf-%jd.map", + (intmax_t)pid); + int fd = open(filename, flags, 0600); + if (fd == -1) { + return -1; + } + else{ + perf_map_state.perf_map = fdopen(fd, "a"); + if (perf_map_state.perf_map == NULL) { + close(fd); + return -1; + } + } + perf_map_state.map_lock = PyThread_allocate_lock(); + if (perf_map_state.map_lock == NULL) { + fclose(perf_map_state.perf_map); + return -2; + } +#endif + return 0; +} + +PyAPI_FUNC(int) PyUnstable_WritePerfMapEntry( + const void *code_addr, + unsigned int code_size, + const char *entry_name +) { +#ifndef MS_WINDOWS + if (perf_map_state.perf_map == NULL) { + int ret = PyUnstable_PerfMapState_Init(); + if(ret != 0){ + return ret; + } + } + PyThread_acquire_lock(perf_map_state.map_lock, 1); + fprintf(perf_map_state.perf_map, "%" PRIxPTR " %x %s\n", (uintptr_t) code_addr, code_size, entry_name); + fflush(perf_map_state.perf_map); + PyThread_release_lock(perf_map_state.map_lock); +#endif + return 0; +} + +PyAPI_FUNC(void) PyUnstable_PerfMapState_Fini(void) { +#ifndef MS_WINDOWS + if (perf_map_state.perf_map != NULL) { + // close the file + PyThread_acquire_lock(perf_map_state.map_lock, 1); + fclose(perf_map_state.perf_map); + PyThread_release_lock(perf_map_state.map_lock); + + // clean up the lock and state + PyThread_free_lock(perf_map_state.map_lock); + perf_map_state.perf_map = NULL; + } +#endif +} + +#ifdef __cplusplus +} +#endif + + static PyMethodDef sys_methods[] = { /* Might as well keep this in alphabetic order */ SYS_ADDAUDITHOOK_METHODDEF @@ -2001,12 +2360,9 @@ static PyMethodDef sys_methods[] = { SYS_GETDEFAULTENCODING_METHODDEF SYS_GETDLOPENFLAGS_METHODDEF SYS_GETALLOCATEDBLOCKS_METHODDEF -#ifdef Py_STATS - {"getdxp", _Py_GetDXProfile, METH_VARARGS}, -#endif + SYS_GETUNICODEINTERNEDSIZE_METHODDEF SYS_GETFILESYSTEMENCODING_METHODDEF SYS_GETFILESYSTEMENCODEERRORS_METHODDEF - SYS__GETQUICKENEDCOUNT_METHODDEF #ifdef Py_TRACE_REFS {"getobjects", _Py_GetObjects, METH_VARARGS}, #endif @@ -2016,6 +2372,7 @@ static PyMethodDef sys_methods[] = { {"getsizeof", _PyCFunction_CAST(sys_getsizeof), METH_VARARGS | METH_KEYWORDS, getsizeof_doc}, SYS__GETFRAME_METHODDEF + SYS__GETFRAMEMODULENAME_METHODDEF SYS_GETWINDOWSVERSION_METHODDEF SYS__ENABLELEGACYWINDOWSFSENCODING_METHODDEF SYS_INTERN_METHODDEF @@ -2025,9 +2382,11 @@ static PyMethodDef sys_methods[] = { SYS_GETSWITCHINTERVAL_METHODDEF SYS_SETDLOPENFLAGS_METHODDEF {"setprofile", sys_setprofile, METH_O, setprofile_doc}, + SYS__SETPROFILEALLTHREADS_METHODDEF SYS_GETPROFILE_METHODDEF SYS_SETRECURSIONLIMIT_METHODDEF {"settrace", sys_settrace, METH_O, settrace_doc}, + SYS__SETTRACEALLTHREADS_METHODDEF SYS_GETTRACE_METHODDEF SYS_CALL_TRACING_METHODDEF SYS__DEBUGMALLOCSTATS_METHODDEF @@ -2037,9 +2396,18 @@ static PyMethodDef sys_methods[] = { METH_VARARGS | METH_KEYWORDS, set_asyncgen_hooks_doc}, SYS_GET_ASYNCGEN_HOOKS_METHODDEF SYS_GETANDROIDAPILEVEL_METHODDEF + SYS_ACTIVATE_STACK_TRAMPOLINE_METHODDEF + SYS_DEACTIVATE_STACK_TRAMPOLINE_METHODDEF + SYS_IS_STACK_TRAMPOLINE_ACTIVE_METHODDEF SYS_UNRAISABLEHOOK_METHODDEF SYS_GET_INT_MAX_STR_DIGITS_METHODDEF SYS_SET_INT_MAX_STR_DIGITS_METHODDEF +#ifdef Py_STATS + SYS__STATS_ON_METHODDEF + SYS__STATS_OFF_METHODDEF + SYS__STATS_CLEAR_METHODDEF + SYS__STATS_DUMP_METHODDEF +#endif {NULL, NULL} // sentinel }; @@ -2047,21 +2415,10 @@ static PyMethodDef sys_methods[] = { static PyObject * list_builtin_module_names(void) { - PyObject *list = PyList_New(0); + PyObject *list = _PyImport_GetBuiltinModuleNames(); if (list == NULL) { return NULL; } - for (Py_ssize_t i = 0; PyImport_Inittab[i].name != NULL; i++) { - PyObject *name = PyUnicode_FromString(PyImport_Inittab[i].name); - if (name == NULL) { - goto error; - } - if (PyList_Append(list, name) < 0) { - Py_DECREF(name); - goto error; - } - Py_DECREF(name); - } if (PyList_Sort(list) != 0) { goto error; } @@ -2364,15 +2721,20 @@ _PySys_AddXOptionWithError(const wchar_t *s) const wchar_t *name_end = wcschr(s, L'='); if (!name_end) { name = PyUnicode_FromWideChar(s, -1); - value = Py_True; - Py_INCREF(value); + if (name == NULL) { + goto error; + } + value = Py_NewRef(Py_True); } else { name = PyUnicode_FromWideChar(s, name_end - s); + if (name == NULL) { + goto error; + } value = PyUnicode_FromWideChar(name_end + 1, -1); - } - if (name == NULL || value == NULL) { - goto error; + if (value == NULL) { + goto error; + } } if (PyDict_SetItem(opts, name, value) < 0) { goto error; @@ -2434,11 +2796,13 @@ stderr -- standard error object; used for error messages\n\ By assigning other file objects (or objects that behave like files)\n\ to these, it is possible to redirect all of the interpreter's I/O.\n\ \n\ +last_exc - the last uncaught exception\n\ + Only available in an interactive session after a\n\ + traceback has been printed.\n\ last_type -- type of last uncaught exception\n\ last_value -- value of last uncaught exception\n\ last_traceback -- traceback of last uncaught exception\n\ - These three are only available in an interactive session after a\n\ - traceback has been printed.\n\ + These three are the (deprecated) legacy representation of last_exc.\n\ " ) /* concatenating string here */ @@ -2583,7 +2947,7 @@ set_flags_from_config(PyInterpreterState *interp, PyObject *flags) SetFlag(preconfig->utf8_mode); SetFlag(config->warn_default_encoding); SetFlagObj(PyBool_FromLong(config->safe_path)); - SetFlag(_Py_global_config_int_max_str_digits); + SetFlag(config->int_max_str_digits); #undef SetFlagObj #undef SetFlag return 0; @@ -2820,8 +3184,7 @@ make_emscripten_info(void) } PyStructSequence_SET_ITEM(emscripten_info, pos++, oua); } else { - Py_INCREF(Py_None); - PyStructSequence_SET_ITEM(emscripten_info, pos++, Py_None); + PyStructSequence_SET_ITEM(emscripten_info, pos++, Py_NewRef(Py_None)); } #define SetBoolItem(flag) \ @@ -2887,6 +3250,7 @@ _PySys_InitCore(PyThreadState *tstate, PyObject *sysdict) { PyObject *version_info; int res; + PyInterpreterState *interp = tstate->interp; /* stdin/stdout/stderr are set in pylifecycle.c */ @@ -2912,10 +3276,10 @@ _PySys_InitCore(PyThreadState *tstate, PyObject *sysdict) SET_SYS("float_info", PyFloat_GetInfo()); SET_SYS("int_info", PyLong_GetInfo()); /* initialize hash_info */ - if (Hash_InfoType.tp_name == NULL) { - if (PyStructSequence_InitType2(&Hash_InfoType, &hash_info_desc) < 0) { - goto type_init_failed; - } + if (_PyStructSequence_InitBuiltin(interp, &Hash_InfoType, + &hash_info_desc) < 0) + { + goto type_init_failed; } SET_SYS("hash_info", get_hash_info(tstate)); SET_SYS("maxunicode", PyLong_FromLong(0x10FFFF)); @@ -2935,14 +3299,16 @@ _PySys_InitCore(PyThreadState *tstate, PyObject *sysdict) SET_SYS_FROM_STRING("abiflags", ABIFLAGS); #endif +#define ENSURE_INFO_TYPE(TYPE, DESC) \ + do { \ + if (_PyStructSequence_InitBuiltinWithFlags( \ + interp, &TYPE, &DESC, Py_TPFLAGS_DISALLOW_INSTANTIATION) < 0) { \ + goto type_init_failed; \ + } \ + } while (0) + /* version_info */ - if (VersionInfoType.tp_name == NULL) { - if (_PyStructSequence_InitType(&VersionInfoType, - &version_info_desc, - Py_TPFLAGS_DISALLOW_INSTANTIATION) < 0) { - goto type_init_failed; - } - } + ENSURE_INFO_TYPE(VersionInfoType, version_info_desc); version_info = make_version_info(tstate); SET_SYS("version_info", version_info); @@ -2950,27 +3316,18 @@ _PySys_InitCore(PyThreadState *tstate, PyObject *sysdict) SET_SYS("implementation", make_impl_info(version_info)); // sys.flags: updated in-place later by _PySys_UpdateConfig() - if (FlagsType.tp_name == 0) { - if (_PyStructSequence_InitType(&FlagsType, &flags_desc, - Py_TPFLAGS_DISALLOW_INSTANTIATION) < 0) { - goto type_init_failed; - } - } + ENSURE_INFO_TYPE(FlagsType, flags_desc); SET_SYS("flags", make_flags(tstate->interp)); #if defined(MS_WINDOWS) /* getwindowsversion */ - if (WindowsVersionType.tp_name == 0) { - if (_PyStructSequence_InitType(&WindowsVersionType, - &windows_version_desc, - Py_TPFLAGS_DISALLOW_INSTANTIATION) < 0) { - goto type_init_failed; - } - } + ENSURE_INFO_TYPE(WindowsVersionType, windows_version_desc); SET_SYS_FROM_STRING("_vpath", VPATH); #endif +#undef ENSURE_INFO_TYPE + /* float repr style: 0.03 (short) vs 0.029999999999999999 (legacy) */ #if _PY_SHORT_FLOAT_REPR == 1 SET_SYS_FROM_STRING("float_repr_style", "short"); @@ -2981,11 +3338,10 @@ _PySys_InitCore(PyThreadState *tstate, PyObject *sysdict) SET_SYS("thread_info", PyThread_GetInfo()); /* initialize asyncgen_hooks */ - if (AsyncGenHooksType.tp_name == NULL) { - if (PyStructSequence_InitType2( - &AsyncGenHooksType, &asyncgen_hooks_desc) < 0) { - goto type_init_failed; - } + if (_PyStructSequence_InitBuiltin(interp, &AsyncGenHooksType, + &asyncgen_hooks_desc) < 0) + { + goto type_init_failed; } #ifdef __EMSCRIPTEN__ @@ -3018,20 +3374,25 @@ err_occurred: static int sys_add_xoption(PyObject *opts, const wchar_t *s) { - PyObject *name, *value; + PyObject *name, *value = NULL; const wchar_t *name_end = wcschr(s, L'='); if (!name_end) { name = PyUnicode_FromWideChar(s, -1); - value = Py_True; - Py_INCREF(value); + if (name == NULL) { + goto error; + } + value = Py_NewRef(Py_True); } else { name = PyUnicode_FromWideChar(s, name_end - s); + if (name == NULL) { + goto error; + } value = PyUnicode_FromWideChar(name_end + 1, -1); - } - if (name == NULL || value == NULL) { - goto error; + if (value == NULL) { + goto error; + } } if (PyDict_SetItem(opts, name, value) < 0) { goto error; @@ -3176,6 +3537,7 @@ error: return _PyStatus_ERR("can't set preliminary stderr"); } +PyObject *_Py_CreateMonitoringObject(void); /* Create sys module without all attributes. _PySys_UpdateConfig() should be called later to add remaining attributes. */ @@ -3186,11 +3548,10 @@ _PySys_Create(PyThreadState *tstate, PyObject **sysmod_p) PyInterpreterState *interp = tstate->interp; - PyObject *modules = PyDict_New(); + PyObject *modules = _PyImport_InitModules(interp); if (modules == NULL) { goto error; } - interp->modules = modules; PyObject *sysmod = _PyModule_CreateInitialized(&sysmodule, PYTHON_API_VERSION); if (sysmod == NULL) { @@ -3201,10 +3562,14 @@ _PySys_Create(PyThreadState *tstate, PyObject **sysmod_p) if (sysdict == NULL) { goto error; } - Py_INCREF(sysdict); - interp->sysdict = sysdict; + interp->sysdict = Py_NewRef(sysdict); + + interp->sysdict_copy = PyDict_Copy(sysdict); + if (interp->sysdict_copy == NULL) { + goto error; + } - if (PyDict_SetItemString(sysdict, "modules", interp->modules) < 0) { + if (PyDict_SetItemString(sysdict, "modules", modules) < 0) { goto error; } @@ -3218,7 +3583,17 @@ _PySys_Create(PyThreadState *tstate, PyObject **sysmod_p) return status; } - if (_PyImport_FixupBuiltin(sysmod, "sys", interp->modules) < 0) { + if (_PyImport_FixupBuiltin(sysmod, "sys", modules) < 0) { + goto error; + } + + PyObject *monitoring = _Py_CreateMonitoringObject(); + if (monitoring == NULL) { + goto error; + } + int err = PyDict_SetItemString(sysdict, "monitoring", monitoring); + Py_DECREF(monitoring); + if (err < 0) { goto error; } @@ -3233,20 +3608,20 @@ error: void -_PySys_Fini(PyInterpreterState *interp) +_PySys_FiniTypes(PyInterpreterState *interp) { - if (_Py_IsMainInterpreter(interp)) { - _PyStructSequence_FiniType(&VersionInfoType); - _PyStructSequence_FiniType(&FlagsType); + _PyStructSequence_FiniBuiltin(interp, &VersionInfoType); + _PyStructSequence_FiniBuiltin(interp, &FlagsType); #if defined(MS_WINDOWS) - _PyStructSequence_FiniType(&WindowsVersionType); + _PyStructSequence_FiniBuiltin(interp, &WindowsVersionType); #endif - _PyStructSequence_FiniType(&Hash_InfoType); - _PyStructSequence_FiniType(&AsyncGenHooksType); + _PyStructSequence_FiniBuiltin(interp, &Hash_InfoType); + _PyStructSequence_FiniBuiltin(interp, &AsyncGenHooksType); #ifdef __EMSCRIPTEN__ + if (_Py_IsMainInterpreter(interp)) { Py_CLEAR(EmscriptenInfoType); -#endif } +#endif } @@ -3435,12 +3810,11 @@ static void sys_write(PyObject *key, FILE *fp, const char *format, va_list va) { PyObject *file; - PyObject *error_type, *error_value, *error_traceback; char buffer[1001]; int written; PyThreadState *tstate = _PyThreadState_GET(); - _PyErr_Fetch(tstate, &error_type, &error_value, &error_traceback); + PyObject *exc = _PyErr_GetRaisedException(tstate); file = _PySys_GetAttr(tstate, key); written = PyOS_vsnprintf(buffer, sizeof(buffer), format, va); if (sys_pyfile_write(buffer, file) != 0) { @@ -3452,7 +3826,7 @@ sys_write(PyObject *key, FILE *fp, const char *format, va_list va) if (sys_pyfile_write(truncated, file) != 0) fputs(truncated, fp); } - _PyErr_Restore(tstate, error_type, error_value, error_traceback); + _PyErr_SetRaisedException(tstate, exc); } void @@ -3479,11 +3853,10 @@ static void sys_format(PyObject *key, FILE *fp, const char *format, va_list va) { PyObject *file, *message; - PyObject *error_type, *error_value, *error_traceback; const char *utf8; PyThreadState *tstate = _PyThreadState_GET(); - _PyErr_Fetch(tstate, &error_type, &error_value, &error_traceback); + PyObject *exc = _PyErr_GetRaisedException(tstate); file = _PySys_GetAttr(tstate, key); message = PyUnicode_FromFormatV(format, va); if (message != NULL) { @@ -3495,7 +3868,7 @@ sys_format(PyObject *key, FILE *fp, const char *format, va_list va) } Py_DECREF(message); } - _PyErr_Restore(tstate, error_type, error_value, error_traceback); + _PyErr_SetRaisedException(tstate, exc); } void diff --git a/Python/thread.c b/Python/thread.c index 940d8b80..7fc53f9b 100644 --- a/Python/thread.c +++ b/Python/thread.c @@ -7,16 +7,8 @@ #include "Python.h" #include "pycore_pystate.h" // _PyInterpreterState_GET() -#include "pycore_structseq.h" // _PyStructSequence_FiniType() - -#ifndef _POSIX_THREADS -/* This means pthreads are not implemented in libc headers, hence the macro - not present in unistd.h. But they still can be implemented as an external - library (e.g. gnu pth in pthread emulation) */ -# ifdef HAVE_PTHREAD_H -# include <pthread.h> /* _POSIX_THREADS */ -# endif -#endif +#include "pycore_structseq.h" // _PyStructSequence_FiniBuiltin() +#include "pycore_pythread.h" #ifndef DONT_HAVE_STDIO_H #include <stdio.h> @@ -24,79 +16,25 @@ #include <stdlib.h> -#ifndef _POSIX_THREADS - -/* Check if we're running on HP-UX and _SC_THREADS is defined. If so, then - enough of the Posix threads package is implemented to support python - threads. - - This is valid for HP-UX 11.23 running on an ia64 system. If needed, add - a check of __ia64 to verify that we're running on an ia64 system instead - of a pa-risc system. -*/ -#ifdef __hpux -#ifdef _SC_THREADS -#define _POSIX_THREADS -#endif -#endif - -#endif /* _POSIX_THREADS */ - - -#ifdef Py_DEBUG -static int thread_debug = 0; -# define dprintf(args) (void)((thread_debug & 1) && printf args) -#else -# define dprintf(args) -#endif - -static int initialized; static void PyThread__init_thread(void); /* Forward */ +#define initialized _PyRuntime.threads.initialized + void PyThread_init_thread(void) { -#ifdef Py_DEBUG - const char *p = Py_GETENV("PYTHONTHREADDEBUG"); - - if (p) { - if (*p) - thread_debug = atoi(p); - else - thread_debug = 1; - } -#endif /* Py_DEBUG */ - if (initialized) + if (initialized) { return; + } initialized = 1; - dprintf(("PyThread_init_thread called\n")); PyThread__init_thread(); } -void -_PyThread_debug_deprecation(void) -{ -#ifdef Py_DEBUG - if (thread_debug) { - // Flush previous dprintf() logs - fflush(stdout); - if (PyErr_WarnEx(PyExc_DeprecationWarning, - "The threading debug (PYTHONTHREADDEBUG environment " - "variable) is deprecated and will be removed " - "in Python 3.12", - 0)) - { - _PyErr_WriteUnraisableMsg("at Python startup", NULL); - } - } -#endif -} - #if defined(HAVE_PTHREAD_STUBS) # define PYTHREAD_NAME "pthread-stubs" # include "thread_pthread_stubs.h" -#elif defined(_POSIX_THREADS) +#elif defined(_USE_PTHREADS) /* AKA _PTHREADS */ # if defined(__EMSCRIPTEN__) && !defined(__EMSCRIPTEN_PTHREADS__) # define PYTHREAD_NAME "pthread-stubs" # else @@ -199,9 +137,9 @@ PyThread_GetInfo(void) int len; #endif - if (ThreadInfoType.tp_name == 0) { - if (PyStructSequence_InitType2(&ThreadInfoType, &threadinfo_desc) < 0) - return NULL; + PyInterpreterState *interp = _PyInterpreterState_GET(); + if (_PyStructSequence_InitBuiltin(interp, &ThreadInfoType, &threadinfo_desc) < 0) { + return NULL; } threadinfo = PyStructSequence_New(&ThreadInfoType); @@ -244,8 +182,7 @@ PyThread_GetInfo(void) if (value == NULL) #endif { - Py_INCREF(Py_None); - value = Py_None; + value = Py_NewRef(Py_None); } PyStructSequence_SET_ITEM(threadinfo, pos++, value); return threadinfo; @@ -255,9 +192,5 @@ PyThread_GetInfo(void) void _PyThread_FiniType(PyInterpreterState *interp) { - if (!_Py_IsMainInterpreter(interp)) { - return; - } - - _PyStructSequence_FiniType(&ThreadInfoType); + _PyStructSequence_FiniBuiltin(interp, &ThreadInfoType); } diff --git a/Python/thread_nt.h b/Python/thread_nt.h index 084bd587..26f441bd 100644 --- a/Python/thread_nt.h +++ b/Python/thread_nt.h @@ -152,11 +152,12 @@ unsigned long PyThread_get_thread_native_id(void); #endif /* - * Initialization of the C package, should not be needed. + * Initialization for the current runtime. */ static void PyThread__init_thread(void) { + // Initialization of the C package should not be needed. } /* @@ -188,8 +189,6 @@ PyThread_start_new_thread(void (*func)(void *), void *arg) unsigned threadID; callobj *obj; - dprintf(("%lu: PyThread_start_new_thread called\n", - PyThread_get_thread_ident())); if (!initialized) PyThread_init_thread(); @@ -209,14 +208,10 @@ PyThread_start_new_thread(void (*func)(void *), void *arg) * too many threads". */ int e = errno; - dprintf(("%lu: PyThread_start_new_thread failed, errno %d\n", - PyThread_get_thread_ident(), e)); threadID = (unsigned)-1; HeapFree(GetProcessHeap(), 0, obj); } else { - dprintf(("%lu: PyThread_start_new_thread succeeded: %p\n", - PyThread_get_thread_ident(), (void*)hThread)); CloseHandle(hThread); } return threadID; @@ -257,7 +252,6 @@ PyThread_get_thread_native_id(void) void _Py_NO_RETURN PyThread_exit_thread(void) { - dprintf(("%lu: PyThread_exit_thread called\n", PyThread_get_thread_ident())); if (!initialized) exit(0); _endthreadex(0); @@ -271,24 +265,22 @@ PyThread_exit_thread(void) PyThread_type_lock PyThread_allocate_lock(void) { - PNRMUTEX aLock; + PNRMUTEX mutex; - dprintf(("PyThread_allocate_lock called\n")); if (!initialized) PyThread_init_thread(); - aLock = AllocNonRecursiveMutex() ; + mutex = AllocNonRecursiveMutex() ; - dprintf(("%lu: PyThread_allocate_lock() -> %p\n", PyThread_get_thread_ident(), aLock)); + PyThread_type_lock aLock = (PyThread_type_lock) mutex; + assert(aLock); - return (PyThread_type_lock) aLock; + return aLock; } void PyThread_free_lock(PyThread_type_lock aLock) { - dprintf(("%lu: PyThread_free_lock(%p) called\n", PyThread_get_thread_ident(),aLock)); - FreeNonRecursiveMutex(aLock) ; } @@ -307,6 +299,8 @@ PyLockStatus PyThread_acquire_lock_timed(PyThread_type_lock aLock, PY_TIMEOUT_T microseconds, int intr_flag) { + assert(aLock); + /* Fow now, intr_flag does nothing on Windows, and lock acquires are * uninterruptible. */ PyLockStatus success; @@ -333,20 +327,14 @@ PyThread_acquire_lock_timed(PyThread_type_lock aLock, milliseconds = INFINITE; } - dprintf(("%lu: PyThread_acquire_lock_timed(%p, %lld) called\n", - PyThread_get_thread_ident(), aLock, microseconds)); - - if (aLock && EnterNonRecursiveMutex((PNRMUTEX)aLock, - (DWORD)milliseconds) == WAIT_OBJECT_0) { + if (EnterNonRecursiveMutex((PNRMUTEX)aLock, + (DWORD)milliseconds) == WAIT_OBJECT_0) { success = PY_LOCK_ACQUIRED; } else { success = PY_LOCK_FAILURE; } - dprintf(("%lu: PyThread_acquire_lock(%p, %lld) -> %d\n", - PyThread_get_thread_ident(), aLock, microseconds, success)); - return success; } int @@ -358,10 +346,8 @@ PyThread_acquire_lock(PyThread_type_lock aLock, int waitflag) void PyThread_release_lock(PyThread_type_lock aLock) { - dprintf(("%lu: PyThread_release_lock(%p) called\n", PyThread_get_thread_ident(),aLock)); - - if (!(aLock && LeaveNonRecursiveMutex((PNRMUTEX) aLock))) - dprintf(("%lu: Could not PyThread_release_lock(%p) error: %ld\n", PyThread_get_thread_ident(), aLock, GetLastError())); + assert(aLock); + (void)LeaveNonRecursiveMutex((PNRMUTEX) aLock); } /* minimum/maximum thread stack sizes supported */ diff --git a/Python/thread_pthread.h b/Python/thread_pthread.h index ddc28c48..f96c57da 100644 --- a/Python/thread_pthread.h +++ b/Python/thread_pthread.h @@ -25,6 +25,8 @@ # include <sys/thread.h> /* thread_self() */ #elif defined(__NetBSD__) # include <lwp.h> /* _lwp_self() */ +#elif defined(__DragonFly__) +# include <sys/lwp.h> /* lwp_gettid() */ #endif /* The POSIX spec requires that use of pthread_attr_setstacksize @@ -113,41 +115,25 @@ #endif -#define MICROSECONDS_TO_TIMESPEC(microseconds, ts) \ -do { \ - struct timeval tv; \ - gettimeofday(&tv, NULL); \ - tv.tv_usec += microseconds % 1000000; \ - tv.tv_sec += microseconds / 1000000; \ - tv.tv_sec += tv.tv_usec / 1000000; \ - tv.tv_usec %= 1000000; \ - ts.tv_sec = tv.tv_sec; \ - ts.tv_nsec = tv.tv_usec * 1000; \ -} while(0) - - /* * pthread_cond support */ -#if defined(HAVE_PTHREAD_CONDATTR_SETCLOCK) && defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC) -// monotonic is supported statically. It doesn't mean it works on runtime. -#define CONDATTR_MONOTONIC -#endif - -// NULL when pthread_condattr_setclock(CLOCK_MONOTONIC) is not supported. -static pthread_condattr_t *condattr_monotonic = NULL; +#define condattr_monotonic _PyRuntime.threads._condattr_monotonic.ptr static void init_condattr(void) { #ifdef CONDATTR_MONOTONIC - static pthread_condattr_t ca; +# define ca _PyRuntime.threads._condattr_monotonic.val + // XXX We need to check the return code? pthread_condattr_init(&ca); + // XXX We need to run pthread_condattr_destroy() during runtime fini. if (pthread_condattr_setclock(&ca, CLOCK_MONOTONIC) == 0) { condattr_monotonic = &ca; // Use monotonic clock } -#endif +# undef ca +#endif // CONDATTR_MONOTONIC } int @@ -156,23 +142,23 @@ _PyThread_cond_init(PyCOND_T *cond) return pthread_cond_init(cond, condattr_monotonic); } + void _PyThread_cond_after(long long us, struct timespec *abs) { + _PyTime_t timeout = _PyTime_FromMicrosecondsClamp(us); + _PyTime_t t; #ifdef CONDATTR_MONOTONIC if (condattr_monotonic) { - clock_gettime(CLOCK_MONOTONIC, abs); - abs->tv_sec += us / 1000000; - abs->tv_nsec += (us % 1000000) * 1000; - abs->tv_sec += abs->tv_nsec / 1000000000; - abs->tv_nsec %= 1000000000; - return; + t = _PyTime_GetMonotonicClock(); } + else #endif - - struct timespec ts; - MICROSECONDS_TO_TIMESPEC(us, ts); - *abs = ts; + { + t = _PyTime_GetSystemClock(); + } + t = _PyTime_Add(t, timeout); + _PyTime_AsTimespec_clamp(t, abs); } @@ -203,15 +189,21 @@ typedef struct { "%s: %s\n", name, strerror(status)); error = 1; } /* - * Initialization. + * Initialization for the current runtime. */ static void PyThread__init_thread(void) { + // The library is only initialized once in the process, + // regardless of how many times the Python runtime is initialized. + static int lib_initialized = 0; + if (!lib_initialized) { + lib_initialized = 1; #if defined(_AIX) && defined(__GNUC__) - extern void pthread_init(void); - pthread_init(); + extern void pthread_init(void); + pthread_init(); #endif + } init_condattr(); } @@ -254,7 +246,6 @@ PyThread_start_new_thread(void (*func)(void *), void *arg) size_t tss; #endif - dprintf(("PyThread_start_new_thread called\n")); if (!initialized) PyThread_init_thread(); @@ -352,6 +343,9 @@ PyThread_get_thread_native_id(void) #elif defined(__NetBSD__) lwpid_t native_id; native_id = _lwp_self(); +#elif defined(__DragonFly__) + lwpid_t native_id; + native_id = lwp_gettid(); #endif return (unsigned long) native_id; } @@ -360,10 +354,17 @@ PyThread_get_thread_native_id(void) void _Py_NO_RETURN PyThread_exit_thread(void) { - dprintf(("PyThread_exit_thread called\n")); if (!initialized) exit(0); +#if defined(__wasi__) + /* + * wasi-threads doesn't have pthread_exit right now + * cf. https://github.com/WebAssembly/wasi-threads/issues/7 + */ + abort(); +#else pthread_exit(0); +#endif } #ifdef USE_SEMAPHORES @@ -378,7 +379,6 @@ PyThread_allocate_lock(void) sem_t *lock; int status, error = 0; - dprintf(("PyThread_allocate_lock called\n")); if (!initialized) PyThread_init_thread(); @@ -394,7 +394,6 @@ PyThread_allocate_lock(void) } } - dprintf(("PyThread_allocate_lock() -> %p\n", (void *)lock)); return (PyThread_type_lock)lock; } @@ -405,7 +404,6 @@ PyThread_free_lock(PyThread_type_lock lock) int status, error = 0; (void) error; /* silence unused-but-set-variable warning */ - dprintf(("PyThread_free_lock(%p) called\n", lock)); if (!thelock) return; @@ -437,27 +435,18 @@ PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds, int status, error = 0; (void) error; /* silence unused-but-set-variable warning */ - dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) called\n", - lock, microseconds, intr_flag)); _PyTime_t timeout; // relative timeout if (microseconds >= 0) { - _PyTime_t ns; - if (microseconds <= _PyTime_MAX / 1000) { - ns = microseconds * 1000; - } - else { - // bpo-41710: PyThread_acquire_lock_timed() cannot report timeout - // overflow to the caller, so clamp the timeout to - // [_PyTime_MIN, _PyTime_MAX]. - // - // _PyTime_MAX nanoseconds is around 292.3 years. - // - // _thread.Lock.acquire() and _thread.RLock.acquire() raise an - // OverflowError if microseconds is greater than PY_TIMEOUT_MAX. - ns = _PyTime_MAX; - } - timeout = _PyTime_FromNanoseconds(ns); + // bpo-41710: PyThread_acquire_lock_timed() cannot report timeout + // overflow to the caller, so clamp the timeout to + // [_PyTime_MIN, _PyTime_MAX]. + // + // _PyTime_MAX nanoseconds is around 292.3 years. + // + // _thread.Lock.acquire() and _thread.RLock.acquire() raise an + // OverflowError if microseconds is greater than PY_TIMEOUT_MAX. + timeout = _PyTime_FromMicrosecondsClamp(microseconds); } else { timeout = _PyTime_FromNanoseconds(-1); @@ -546,8 +535,6 @@ PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds, success = PY_LOCK_FAILURE; } - dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) -> %d\n", - lock, microseconds, intr_flag, success)); return success; } @@ -558,7 +545,6 @@ PyThread_release_lock(PyThread_type_lock lock) int status, error = 0; (void) error; /* silence unused-but-set-variable warning */ - dprintf(("PyThread_release_lock(%p) called\n", lock)); status = sem_post(thelock); CHECK_STATUS("sem_post"); @@ -575,7 +561,6 @@ PyThread_allocate_lock(void) pthread_lock *lock; int status, error = 0; - dprintf(("PyThread_allocate_lock called\n")); if (!initialized) PyThread_init_thread(); @@ -601,7 +586,6 @@ PyThread_allocate_lock(void) } } - dprintf(("PyThread_allocate_lock() -> %p\n", (void *)lock)); return (PyThread_type_lock) lock; } @@ -612,7 +596,6 @@ PyThread_free_lock(PyThread_type_lock lock) int status, error = 0; (void) error; /* silence unused-but-set-variable warning */ - dprintf(("PyThread_free_lock(%p) called\n", lock)); /* some pthread-like implementations tie the mutex to the cond * and must have the cond destroyed first. @@ -634,70 +617,81 @@ PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds, pthread_lock *thelock = (pthread_lock *)lock; int status, error = 0; - dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) called\n", - lock, microseconds, intr_flag)); - if (microseconds == 0) { status = pthread_mutex_trylock( &thelock->mut ); - if (status != EBUSY) + if (status != EBUSY) { CHECK_STATUS_PTHREAD("pthread_mutex_trylock[1]"); + } } else { status = pthread_mutex_lock( &thelock->mut ); CHECK_STATUS_PTHREAD("pthread_mutex_lock[1]"); } - if (status == 0) { - if (thelock->locked == 0) { - success = PY_LOCK_ACQUIRED; - } - else if (microseconds != 0) { - struct timespec abs; - if (microseconds > 0) { - _PyThread_cond_after(microseconds, &abs); + if (status != 0) { + goto done; + } + + if (thelock->locked == 0) { + success = PY_LOCK_ACQUIRED; + goto unlock; + } + if (microseconds == 0) { + goto unlock; + } + + struct timespec abs_timeout; + if (microseconds > 0) { + _PyThread_cond_after(microseconds, &abs_timeout); + } + // Continue trying until we get the lock + + // mut must be locked by me -- part of the condition protocol + while (1) { + if (microseconds > 0) { + status = pthread_cond_timedwait(&thelock->lock_released, + &thelock->mut, &abs_timeout); + if (status == 1) { + break; } - /* continue trying until we get the lock */ - - /* mut must be locked by me -- part of the condition - * protocol */ - while (success == PY_LOCK_FAILURE) { - if (microseconds > 0) { - status = pthread_cond_timedwait( - &thelock->lock_released, - &thelock->mut, &abs); - if (status == 1) { - break; - } - if (status == ETIMEDOUT) - break; - CHECK_STATUS_PTHREAD("pthread_cond_timedwait"); - } - else { - status = pthread_cond_wait( - &thelock->lock_released, - &thelock->mut); - CHECK_STATUS_PTHREAD("pthread_cond_wait"); - } - - if (intr_flag && status == 0 && thelock->locked) { - /* We were woken up, but didn't get the lock. We probably received - * a signal. Return PY_LOCK_INTR to allow the caller to handle - * it and retry. */ - success = PY_LOCK_INTR; - break; - } - else if (status == 0 && !thelock->locked) { - success = PY_LOCK_ACQUIRED; - } + if (status == ETIMEDOUT) { + break; } + CHECK_STATUS_PTHREAD("pthread_cond_timedwait"); + } + else { + status = pthread_cond_wait( + &thelock->lock_released, + &thelock->mut); + CHECK_STATUS_PTHREAD("pthread_cond_wait"); } - if (success == PY_LOCK_ACQUIRED) thelock->locked = 1; - status = pthread_mutex_unlock( &thelock->mut ); - CHECK_STATUS_PTHREAD("pthread_mutex_unlock[1]"); + + if (intr_flag && status == 0 && thelock->locked) { + // We were woken up, but didn't get the lock. We probably received + // a signal. Return PY_LOCK_INTR to allow the caller to handle + // it and retry. + success = PY_LOCK_INTR; + break; + } + + if (status == 0 && !thelock->locked) { + success = PY_LOCK_ACQUIRED; + break; + } + + // Wait got interrupted by a signal: retry + } + +unlock: + if (success == PY_LOCK_ACQUIRED) { + thelock->locked = 1; } + status = pthread_mutex_unlock( &thelock->mut ); + CHECK_STATUS_PTHREAD("pthread_mutex_unlock[1]"); - if (error) success = PY_LOCK_FAILURE; - dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) -> %d\n", - lock, microseconds, intr_flag, success)); +done: + if (error) { + success = PY_LOCK_FAILURE; + } return success; } @@ -708,7 +702,6 @@ PyThread_release_lock(PyThread_type_lock lock) int status, error = 0; (void) error; /* silence unused-but-set-variable warning */ - dprintf(("PyThread_release_lock(%p) called\n", lock)); status = pthread_mutex_lock( &thelock->mut ); CHECK_STATUS_PTHREAD("pthread_mutex_lock[3]"); diff --git a/Python/thread_pthread_stubs.h b/Python/thread_pthread_stubs.h index 8b80c0f8..56e5b614 100644 --- a/Python/thread_pthread_stubs.h +++ b/Python/thread_pthread_stubs.h @@ -124,13 +124,10 @@ pthread_attr_destroy(pthread_attr_t *attr) return 0; } -// pthread_key -typedef struct { - bool in_use; - void *value; -} py_tls_entry; -static py_tls_entry py_tls_entries[PTHREAD_KEYS_MAX] = {0}; +typedef struct py_stub_tls_entry py_tls_entry; + +#define py_tls_entries (_PyRuntime.threads.stubs.tls_entries) int pthread_key_create(pthread_key_t *key, void (*destr_function)(void *)) diff --git a/Python/traceback.c b/Python/traceback.c index 7f47349a..dc258703 100644 --- a/Python/traceback.c +++ b/Python/traceback.c @@ -11,7 +11,7 @@ #include "pycore_interp.h" // PyInterpreterState.gc #include "pycore_parser.h" // _PyParser_ASTFromString #include "pycore_pyarena.h" // _PyArena_Free() -#include "pycore_pyerrors.h" // _PyErr_Fetch() +#include "pycore_pyerrors.h" // _PyErr_GetRaisedException() #include "pycore_pystate.h" // _PyThreadState_GET() #include "pycore_traceback.h" // EXCEPTION_TB_HEADER @@ -52,10 +52,8 @@ tb_create_raw(PyTracebackObject *next, PyFrameObject *frame, int lasti, } tb = PyObject_GC_New(PyTracebackObject, &PyTraceBack_Type); if (tb != NULL) { - Py_XINCREF(next); - tb->tb_next = next; - Py_XINCREF(frame); - tb->tb_frame = frame; + tb->tb_next = (PyTracebackObject*)Py_XNewRef(next); + tb->tb_frame = (PyFrameObject*)Py_XNewRef(frame); tb->tb_lasti = lasti; tb->tb_lineno = lineno; PyObject_GC_Track(tb); @@ -106,8 +104,7 @@ tb_next_get(PyTracebackObject *self, void *Py_UNUSED(_)) if (!ret) { ret = Py_None; } - Py_INCREF(ret); - return ret; + return Py_NewRef(ret); } static int @@ -139,10 +136,7 @@ tb_next_set(PyTracebackObject *self, PyObject *new_next, void *Py_UNUSED(_)) cursor = cursor->tb_next; } - PyObject *old_next = (PyObject*)self->tb_next; - Py_XINCREF(new_next); - self->tb_next = (PyTracebackObject *)new_next; - Py_XDECREF(old_next); + Py_XSETREF(self->tb_next, (PyTracebackObject *)Py_XNewRef(new_next)); return 0; } @@ -248,15 +242,18 @@ _PyTraceBack_FromFrame(PyObject *tb_next, PyFrameObject *frame) int PyTraceBack_Here(PyFrameObject *frame) { - PyObject *exc, *val, *tb, *newtb; - PyErr_Fetch(&exc, &val, &tb); - newtb = _PyTraceBack_FromFrame(tb, frame); + PyObject *exc = PyErr_GetRaisedException(); + assert(PyExceptionInstance_Check(exc)); + PyObject *tb = PyException_GetTraceback(exc); + PyObject *newtb = _PyTraceBack_FromFrame(tb, frame); + Py_XDECREF(tb); if (newtb == NULL) { - _PyErr_ChainExceptions(exc, val, tb); + _PyErr_ChainExceptions1(exc); return -1; } - PyErr_Restore(exc, val, newtb); - Py_XDECREF(tb); + PyException_SetTraceback(exc, newtb); + Py_XDECREF(newtb); + PyErr_SetRaisedException(exc); return 0; } @@ -266,13 +263,12 @@ void _PyTraceback_Add(const char *funcname, const char *filename, int lineno) PyObject *globals; PyCodeObject *code; PyFrameObject *frame; - PyObject *exc, *val, *tb; PyThreadState *tstate = _PyThreadState_GET(); /* Save and clear the current exception. Python functions must not be called with an exception set. Calling Python functions happens when the codec of the filesystem encoding is implemented in pure Python. */ - _PyErr_Fetch(tstate, &exc, &val, &tb); + PyObject *exc = _PyErr_GetRaisedException(tstate); globals = PyDict_New(); if (!globals) @@ -289,13 +285,13 @@ void _PyTraceback_Add(const char *funcname, const char *filename, int lineno) goto error; frame->f_lineno = lineno; - _PyErr_Restore(tstate, exc, val, tb); + _PyErr_SetRaisedException(tstate, exc); PyTraceBack_Here(frame); Py_DECREF(frame); return; error: - _PyErr_ChainExceptions(exc, val, tb); + _PyErr_ChainExceptions1(exc); } static PyObject * @@ -522,8 +518,7 @@ display_source_line_with_margin(PyObject *f, PyObject *filename, int lineno, int } if (line) { - Py_INCREF(lineobj); - *line = lineobj; + *line = Py_NewRef(lineobj); } /* remove the indentation of the line */ @@ -538,8 +533,7 @@ display_source_line_with_margin(PyObject *f, PyObject *filename, int lineno, int PyObject *truncated; truncated = PyUnicode_Substring(lineobj, i, PyUnicode_GET_LENGTH(lineobj)); if (truncated) { - Py_DECREF(lineobj); - lineobj = truncated; + Py_SETREF(lineobj, truncated); } else { PyErr_Clear(); } @@ -621,6 +615,11 @@ extract_anchors_from_expr(const char *segment_str, expr_ty expr, Py_ssize_t *lef ++*right_anchor; } + // Keep going if the current char is not ')' + if (i+1 < right->col_offset && (segment_str[i] == ')')) { + continue; + } + // Set the error characters *primary_error_char = "~"; *secondary_error_char = "^"; @@ -631,6 +630,18 @@ extract_anchors_from_expr(const char *segment_str, expr_ty expr, Py_ssize_t *lef case Subscript_kind: { *left_anchor = expr->v.Subscript.value->end_col_offset; *right_anchor = expr->v.Subscript.slice->end_col_offset + 1; + Py_ssize_t str_len = strlen(segment_str); + + // Move right_anchor and left_anchor forward to the first non-whitespace character that is not ']' and '[' + while (*left_anchor < str_len && (IS_WHITESPACE(segment_str[*left_anchor]) || segment_str[*left_anchor] != '[')) { + ++*left_anchor; + } + while (*right_anchor < str_len && (IS_WHITESPACE(segment_str[*right_anchor]) || segment_str[*right_anchor] != ']')) { + ++*right_anchor; + } + if (*right_anchor < str_len){ + *right_anchor += 1; + } // Set the error characters *primary_error_char = "~"; @@ -1093,7 +1104,6 @@ _Py_DumpASCII(int fd, PyObject *text) int truncated; int kind; void *data = NULL; - wchar_t *wstr = NULL; Py_UCS4 ch; if (!PyUnicode_Check(text)) @@ -1101,13 +1111,7 @@ _Py_DumpASCII(int fd, PyObject *text) size = ascii->length; kind = ascii->state.kind; - if (kind == PyUnicode_WCHAR_KIND) { - wstr = ascii->wstr; - if (wstr == NULL) - return; - size = _PyCompactUnicodeObject_CAST(text)->wstr_length; - } - else if (ascii->state.compact) { + if (ascii->state.compact) { if (ascii->state.ascii) data = ascii + 1; else @@ -1148,10 +1152,7 @@ _Py_DumpASCII(int fd, PyObject *text) } for (i=0; i < size; i++) { - if (kind != PyUnicode_WCHAR_KIND) - ch = PyUnicode_READ(kind, data, i); - else - ch = wstr[i]; + ch = PyUnicode_READ(kind, data, i); if (' ' <= ch && ch <= 126) { /* printable ASCII character */ char c = (char)ch; @@ -1196,7 +1197,7 @@ dump_frame(int fd, _PyInterpreterFrame *frame) PUTS(fd, "???"); } - int lineno = _PyInterpreterFrame_GetLine(frame); + int lineno = PyUnstable_InterpreterFrame_GetLine(frame); PUTS(fd, ", line "); if (lineno >= 0) { _Py_DumpDecimal(fd, (size_t)lineno); @@ -1244,6 +1245,15 @@ dump_traceback(int fd, PyThreadState *tstate, int write_header) if (frame == NULL) { break; } + if (frame->owner == FRAME_OWNED_BY_CSTACK) { + /* Trampoline frame */ + frame = frame->previous; + } + if (frame == NULL) { + break; + } + /* Can't have more than one shim frame in a row */ + assert(frame->owner != FRAME_OWNED_BY_CSTACK); depth++; } } diff --git a/Python/tracemalloc.c b/Python/tracemalloc.c new file mode 100644 index 00000000..bc765623 --- /dev/null +++ b/Python/tracemalloc.c @@ -0,0 +1,1560 @@ +#include "Python.h" +#include "pycore_fileutils.h" // _Py_write_noraise() +#include "pycore_gc.h" // PyGC_Head +#include "pycore_hashtable.h" // _Py_hashtable_t +#include "pycore_object.h" // _PyType_PreHeaderSize +#include "pycore_pymem.h" // _Py_tracemalloc_config +#include "pycore_runtime.h" // _Py_ID() +#include "pycore_traceback.h" +#include <pycore_frame.h> +#include "frameobject.h" // _PyInterpreterFrame_GetLine + +#include <stdlib.h> // malloc() + +#define tracemalloc_config _PyRuntime.tracemalloc.config + +_Py_DECLARE_STR(anon_unknown, "<unknown>"); + +/* Forward declaration */ +static void* raw_malloc(size_t size); +static void raw_free(void *ptr); + +#ifdef Py_DEBUG +# define TRACE_DEBUG +#endif + +#define TO_PTR(key) ((const void *)(uintptr_t)(key)) +#define FROM_PTR(key) ((uintptr_t)(key)) + +#define allocators _PyRuntime.tracemalloc.allocators + + +#if defined(TRACE_RAW_MALLOC) +/* This lock is needed because tracemalloc_free() is called without + the GIL held from PyMem_RawFree(). It cannot acquire the lock because it + would introduce a deadlock in _PyThreadState_DeleteCurrent(). */ +# define tables_lock _PyRuntime.tracemalloc.tables_lock +# define TABLES_LOCK() PyThread_acquire_lock(tables_lock, 1) +# define TABLES_UNLOCK() PyThread_release_lock(tables_lock) +#else + /* variables are protected by the GIL */ +# define TABLES_LOCK() +# define TABLES_UNLOCK() +#endif + + +#define DEFAULT_DOMAIN 0 + +typedef struct tracemalloc_frame frame_t; +typedef struct tracemalloc_traceback traceback_t; + +#define TRACEBACK_SIZE(NFRAME) \ + (sizeof(traceback_t) + sizeof(frame_t) * (NFRAME - 1)) + +/* The maximum number of frames is either: + - The maximum number of frames we can store in `traceback_t.nframe` + - The maximum memory size_t we can allocate */ +static const unsigned long MAX_NFRAME = Py_MIN(UINT16_MAX, ((SIZE_MAX - sizeof(traceback_t)) / sizeof(frame_t) + 1)); + + +#define tracemalloc_empty_traceback _PyRuntime.tracemalloc.empty_traceback + + +/* Trace of a memory block */ +typedef struct { + /* Size of the memory block in bytes */ + size_t size; + + /* Traceback where the memory block was allocated */ + traceback_t *traceback; +} trace_t; + + +#define tracemalloc_traced_memory _PyRuntime.tracemalloc.traced_memory +#define tracemalloc_peak_traced_memory _PyRuntime.tracemalloc.peak_traced_memory +#define tracemalloc_filenames _PyRuntime.tracemalloc.filenames +#define tracemalloc_traceback _PyRuntime.tracemalloc.traceback +#define tracemalloc_tracebacks _PyRuntime.tracemalloc.tracebacks +#define tracemalloc_traces _PyRuntime.tracemalloc.traces +#define tracemalloc_domains _PyRuntime.tracemalloc.domains + + +#ifdef TRACE_DEBUG +static void +tracemalloc_error(const char *format, ...) +{ + va_list ap; + fprintf(stderr, "tracemalloc: "); + va_start(ap, format); + vfprintf(stderr, format, ap); + va_end(ap); + fprintf(stderr, "\n"); + fflush(stderr); +} +#endif + + +#if defined(TRACE_RAW_MALLOC) +#define REENTRANT_THREADLOCAL + +#define tracemalloc_reentrant_key _PyRuntime.tracemalloc.reentrant_key + +/* Any non-NULL pointer can be used */ +#define REENTRANT Py_True + +static int +get_reentrant(void) +{ + void *ptr; + + assert(PyThread_tss_is_created(&tracemalloc_reentrant_key)); + ptr = PyThread_tss_get(&tracemalloc_reentrant_key); + if (ptr != NULL) { + assert(ptr == REENTRANT); + return 1; + } + else + return 0; +} + +static void +set_reentrant(int reentrant) +{ + assert(reentrant == 0 || reentrant == 1); + assert(PyThread_tss_is_created(&tracemalloc_reentrant_key)); + + if (reentrant) { + assert(!get_reentrant()); + PyThread_tss_set(&tracemalloc_reentrant_key, REENTRANT); + } + else { + assert(get_reentrant()); + PyThread_tss_set(&tracemalloc_reentrant_key, NULL); + } +} + +#else + +/* TRACE_RAW_MALLOC not defined: variable protected by the GIL */ +static int tracemalloc_reentrant = 0; + +static int +get_reentrant(void) +{ + return tracemalloc_reentrant; +} + +static void +set_reentrant(int reentrant) +{ + assert(reentrant != tracemalloc_reentrant); + tracemalloc_reentrant = reentrant; +} +#endif + + +static Py_uhash_t +hashtable_hash_pyobject(const void *key) +{ + PyObject *obj = (PyObject *)key; + return PyObject_Hash(obj); +} + + +static int +hashtable_compare_unicode(const void *key1, const void *key2) +{ + PyObject *obj1 = (PyObject *)key1; + PyObject *obj2 = (PyObject *)key2; + if (obj1 != NULL && obj2 != NULL) { + return (PyUnicode_Compare(obj1, obj2) == 0); + } + else { + return obj1 == obj2; + } +} + + +static Py_uhash_t +hashtable_hash_uint(const void *key_raw) +{ + unsigned int key = (unsigned int)FROM_PTR(key_raw); + return (Py_uhash_t)key; +} + + +static _Py_hashtable_t * +hashtable_new(_Py_hashtable_hash_func hash_func, + _Py_hashtable_compare_func compare_func, + _Py_hashtable_destroy_func key_destroy_func, + _Py_hashtable_destroy_func value_destroy_func) +{ + _Py_hashtable_allocator_t hashtable_alloc = {malloc, free}; + return _Py_hashtable_new_full(hash_func, compare_func, + key_destroy_func, value_destroy_func, + &hashtable_alloc); +} + + +static void* +raw_malloc(size_t size) +{ + return allocators.raw.malloc(allocators.raw.ctx, size); +} + +static void +raw_free(void *ptr) +{ + allocators.raw.free(allocators.raw.ctx, ptr); +} + + +static Py_uhash_t +hashtable_hash_traceback(const void *key) +{ + const traceback_t *traceback = (const traceback_t *)key; + return traceback->hash; +} + + +static int +hashtable_compare_traceback(const void *key1, const void *key2) +{ + const traceback_t *traceback1 = (const traceback_t *)key1; + const traceback_t *traceback2 = (const traceback_t *)key2; + + if (traceback1->nframe != traceback2->nframe) { + return 0; + } + if (traceback1->total_nframe != traceback2->total_nframe) { + return 0; + } + + for (int i=0; i < traceback1->nframe; i++) { + const frame_t *frame1 = &traceback1->frames[i]; + const frame_t *frame2 = &traceback2->frames[i]; + + if (frame1->lineno != frame2->lineno) { + return 0; + } + if (frame1->filename != frame2->filename) { + assert(PyUnicode_Compare(frame1->filename, frame2->filename) != 0); + return 0; + } + } + return 1; +} + + +static void +tracemalloc_get_frame(_PyInterpreterFrame *pyframe, frame_t *frame) +{ + frame->filename = &_Py_STR(anon_unknown); + int lineno = PyUnstable_InterpreterFrame_GetLine(pyframe); + if (lineno < 0) { + lineno = 0; + } + frame->lineno = (unsigned int)lineno; + + PyObject *filename = pyframe->f_code->co_filename; + + if (filename == NULL) { +#ifdef TRACE_DEBUG + tracemalloc_error("failed to get the filename of the code object"); +#endif + return; + } + + if (!PyUnicode_Check(filename)) { +#ifdef TRACE_DEBUG + tracemalloc_error("filename is not a unicode string"); +#endif + return; + } + if (!PyUnicode_IS_READY(filename)) { + /* Don't make a Unicode string ready to avoid reentrant calls + to tracemalloc_malloc() or tracemalloc_realloc() */ +#ifdef TRACE_DEBUG + tracemalloc_error("filename is not a ready unicode string"); +#endif + return; + } + + /* intern the filename */ + _Py_hashtable_entry_t *entry; + entry = _Py_hashtable_get_entry(tracemalloc_filenames, filename); + if (entry != NULL) { + filename = (PyObject *)entry->key; + } + else { + /* tracemalloc_filenames is responsible to keep a reference + to the filename */ + if (_Py_hashtable_set(tracemalloc_filenames, Py_NewRef(filename), + NULL) < 0) { + Py_DECREF(filename); +#ifdef TRACE_DEBUG + tracemalloc_error("failed to intern the filename"); +#endif + return; + } + } + + /* the tracemalloc_filenames table keeps a reference to the filename */ + frame->filename = filename; +} + + +static Py_uhash_t +traceback_hash(traceback_t *traceback) +{ + /* code based on tuplehash() of Objects/tupleobject.c */ + Py_uhash_t x, y; /* Unsigned for defined overflow behavior. */ + int len = traceback->nframe; + Py_uhash_t mult = _PyHASH_MULTIPLIER; + frame_t *frame; + + x = 0x345678UL; + frame = traceback->frames; + while (--len >= 0) { + y = (Py_uhash_t)PyObject_Hash(frame->filename); + y ^= (Py_uhash_t)frame->lineno; + frame++; + + x = (x ^ y) * mult; + /* the cast might truncate len; that doesn't change hash stability */ + mult += (Py_uhash_t)(82520UL + len + len); + } + x ^= traceback->total_nframe; + x += 97531UL; + return x; +} + + +static void +traceback_get_frames(traceback_t *traceback) +{ + PyThreadState *tstate = PyGILState_GetThisThreadState(); + if (tstate == NULL) { +#ifdef TRACE_DEBUG + tracemalloc_error("failed to get the current thread state"); +#endif + return; + } + + _PyInterpreterFrame *pyframe = _PyThreadState_GetFrame(tstate); + while (pyframe) { + if (traceback->nframe < tracemalloc_config.max_nframe) { + tracemalloc_get_frame(pyframe, &traceback->frames[traceback->nframe]); + assert(traceback->frames[traceback->nframe].filename != NULL); + traceback->nframe++; + } + if (traceback->total_nframe < UINT16_MAX) { + traceback->total_nframe++; + } + pyframe = _PyFrame_GetFirstComplete(pyframe->previous); + } +} + + +static traceback_t * +traceback_new(void) +{ + traceback_t *traceback; + _Py_hashtable_entry_t *entry; + + assert(PyGILState_Check()); + + /* get frames */ + traceback = tracemalloc_traceback; + traceback->nframe = 0; + traceback->total_nframe = 0; + traceback_get_frames(traceback); + if (traceback->nframe == 0) + return &tracemalloc_empty_traceback; + traceback->hash = traceback_hash(traceback); + + /* intern the traceback */ + entry = _Py_hashtable_get_entry(tracemalloc_tracebacks, traceback); + if (entry != NULL) { + traceback = (traceback_t *)entry->key; + } + else { + traceback_t *copy; + size_t traceback_size; + + traceback_size = TRACEBACK_SIZE(traceback->nframe); + + copy = raw_malloc(traceback_size); + if (copy == NULL) { +#ifdef TRACE_DEBUG + tracemalloc_error("failed to intern the traceback: malloc failed"); +#endif + return NULL; + } + memcpy(copy, traceback, traceback_size); + + if (_Py_hashtable_set(tracemalloc_tracebacks, copy, NULL) < 0) { + raw_free(copy); +#ifdef TRACE_DEBUG + tracemalloc_error("failed to intern the traceback: putdata failed"); +#endif + return NULL; + } + traceback = copy; + } + return traceback; +} + + +static _Py_hashtable_t* +tracemalloc_create_traces_table(void) +{ + return hashtable_new(_Py_hashtable_hash_ptr, + _Py_hashtable_compare_direct, + NULL, raw_free); +} + + +static _Py_hashtable_t* +tracemalloc_create_domains_table(void) +{ + return hashtable_new(hashtable_hash_uint, + _Py_hashtable_compare_direct, + NULL, + (_Py_hashtable_destroy_func)_Py_hashtable_destroy); +} + + +static _Py_hashtable_t* +tracemalloc_get_traces_table(unsigned int domain) +{ + if (domain == DEFAULT_DOMAIN) { + return tracemalloc_traces; + } + else { + return _Py_hashtable_get(tracemalloc_domains, TO_PTR(domain)); + } +} + + +static void +tracemalloc_remove_trace(unsigned int domain, uintptr_t ptr) +{ + assert(tracemalloc_config.tracing); + + _Py_hashtable_t *traces = tracemalloc_get_traces_table(domain); + if (!traces) { + return; + } + + trace_t *trace = _Py_hashtable_steal(traces, TO_PTR(ptr)); + if (!trace) { + return; + } + assert(tracemalloc_traced_memory >= trace->size); + tracemalloc_traced_memory -= trace->size; + raw_free(trace); +} + +#define REMOVE_TRACE(ptr) \ + tracemalloc_remove_trace(DEFAULT_DOMAIN, (uintptr_t)(ptr)) + + +static int +tracemalloc_add_trace(unsigned int domain, uintptr_t ptr, + size_t size) +{ + assert(tracemalloc_config.tracing); + + traceback_t *traceback = traceback_new(); + if (traceback == NULL) { + return -1; + } + + _Py_hashtable_t *traces = tracemalloc_get_traces_table(domain); + if (traces == NULL) { + traces = tracemalloc_create_traces_table(); + if (traces == NULL) { + return -1; + } + + if (_Py_hashtable_set(tracemalloc_domains, TO_PTR(domain), traces) < 0) { + _Py_hashtable_destroy(traces); + return -1; + } + } + + trace_t *trace = _Py_hashtable_get(traces, TO_PTR(ptr)); + if (trace != NULL) { + /* the memory block is already tracked */ + assert(tracemalloc_traced_memory >= trace->size); + tracemalloc_traced_memory -= trace->size; + + trace->size = size; + trace->traceback = traceback; + } + else { + trace = raw_malloc(sizeof(trace_t)); + if (trace == NULL) { + return -1; + } + trace->size = size; + trace->traceback = traceback; + + int res = _Py_hashtable_set(traces, TO_PTR(ptr), trace); + if (res != 0) { + raw_free(trace); + return res; + } + } + + assert(tracemalloc_traced_memory <= SIZE_MAX - size); + tracemalloc_traced_memory += size; + if (tracemalloc_traced_memory > tracemalloc_peak_traced_memory) { + tracemalloc_peak_traced_memory = tracemalloc_traced_memory; + } + return 0; +} + +#define ADD_TRACE(ptr, size) \ + tracemalloc_add_trace(DEFAULT_DOMAIN, (uintptr_t)(ptr), size) + + +static void* +tracemalloc_alloc(int use_calloc, void *ctx, size_t nelem, size_t elsize) +{ + PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx; + void *ptr; + + assert(elsize == 0 || nelem <= SIZE_MAX / elsize); + + if (use_calloc) + ptr = alloc->calloc(alloc->ctx, nelem, elsize); + else + ptr = alloc->malloc(alloc->ctx, nelem * elsize); + if (ptr == NULL) + return NULL; + + TABLES_LOCK(); + if (ADD_TRACE(ptr, nelem * elsize) < 0) { + /* Failed to allocate a trace for the new memory block */ + TABLES_UNLOCK(); + alloc->free(alloc->ctx, ptr); + return NULL; + } + TABLES_UNLOCK(); + return ptr; +} + + +static void* +tracemalloc_realloc(void *ctx, void *ptr, size_t new_size) +{ + PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx; + void *ptr2; + + ptr2 = alloc->realloc(alloc->ctx, ptr, new_size); + if (ptr2 == NULL) + return NULL; + + if (ptr != NULL) { + /* an existing memory block has been resized */ + + TABLES_LOCK(); + + /* tracemalloc_add_trace() updates the trace if there is already + a trace at address ptr2 */ + if (ptr2 != ptr) { + REMOVE_TRACE(ptr); + } + + if (ADD_TRACE(ptr2, new_size) < 0) { + /* Memory allocation failed. The error cannot be reported to + the caller, because realloc() may already have shrunk the + memory block and so removed bytes. + + This case is very unlikely: a hash entry has just been + released, so the hash table should have at least one free entry. + + The GIL and the table lock ensures that only one thread is + allocating memory. */ + Py_FatalError("tracemalloc_realloc() failed to allocate a trace"); + } + TABLES_UNLOCK(); + } + else { + /* new allocation */ + + TABLES_LOCK(); + if (ADD_TRACE(ptr2, new_size) < 0) { + /* Failed to allocate a trace for the new memory block */ + TABLES_UNLOCK(); + alloc->free(alloc->ctx, ptr2); + return NULL; + } + TABLES_UNLOCK(); + } + return ptr2; +} + + +static void +tracemalloc_free(void *ctx, void *ptr) +{ + PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx; + + if (ptr == NULL) + return; + + /* GIL cannot be locked in PyMem_RawFree() because it would introduce + a deadlock in _PyThreadState_DeleteCurrent(). */ + + alloc->free(alloc->ctx, ptr); + + TABLES_LOCK(); + REMOVE_TRACE(ptr); + TABLES_UNLOCK(); +} + + +static void* +tracemalloc_alloc_gil(int use_calloc, void *ctx, size_t nelem, size_t elsize) +{ + void *ptr; + + if (get_reentrant()) { + PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx; + if (use_calloc) + return alloc->calloc(alloc->ctx, nelem, elsize); + else + return alloc->malloc(alloc->ctx, nelem * elsize); + } + + /* Ignore reentrant call. PyObjet_Malloc() calls PyMem_Malloc() for + allocations larger than 512 bytes, don't trace the same memory + allocation twice. */ + set_reentrant(1); + + ptr = tracemalloc_alloc(use_calloc, ctx, nelem, elsize); + + set_reentrant(0); + return ptr; +} + + +static void* +tracemalloc_malloc_gil(void *ctx, size_t size) +{ + return tracemalloc_alloc_gil(0, ctx, 1, size); +} + + +static void* +tracemalloc_calloc_gil(void *ctx, size_t nelem, size_t elsize) +{ + return tracemalloc_alloc_gil(1, ctx, nelem, elsize); +} + + +static void* +tracemalloc_realloc_gil(void *ctx, void *ptr, size_t new_size) +{ + void *ptr2; + + if (get_reentrant()) { + /* Reentrant call to PyMem_Realloc() and PyMem_RawRealloc(). + Example: PyMem_RawRealloc() is called internally by pymalloc + (_PyObject_Malloc() and _PyObject_Realloc()) to allocate a new + arena (new_arena()). */ + PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx; + + ptr2 = alloc->realloc(alloc->ctx, ptr, new_size); + if (ptr2 != NULL && ptr != NULL) { + TABLES_LOCK(); + REMOVE_TRACE(ptr); + TABLES_UNLOCK(); + } + return ptr2; + } + + /* Ignore reentrant call. PyObjet_Realloc() calls PyMem_Realloc() for + allocations larger than 512 bytes. Don't trace the same memory + allocation twice. */ + set_reentrant(1); + + ptr2 = tracemalloc_realloc(ctx, ptr, new_size); + + set_reentrant(0); + return ptr2; +} + + +#ifdef TRACE_RAW_MALLOC +static void* +tracemalloc_raw_alloc(int use_calloc, void *ctx, size_t nelem, size_t elsize) +{ + PyGILState_STATE gil_state; + void *ptr; + + if (get_reentrant()) { + PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx; + if (use_calloc) + return alloc->calloc(alloc->ctx, nelem, elsize); + else + return alloc->malloc(alloc->ctx, nelem * elsize); + } + + /* Ignore reentrant call. PyGILState_Ensure() may call PyMem_RawMalloc() + indirectly which would call PyGILState_Ensure() if reentrant are not + disabled. */ + set_reentrant(1); + + gil_state = PyGILState_Ensure(); + ptr = tracemalloc_alloc(use_calloc, ctx, nelem, elsize); + PyGILState_Release(gil_state); + + set_reentrant(0); + return ptr; +} + + +static void* +tracemalloc_raw_malloc(void *ctx, size_t size) +{ + return tracemalloc_raw_alloc(0, ctx, 1, size); +} + + +static void* +tracemalloc_raw_calloc(void *ctx, size_t nelem, size_t elsize) +{ + return tracemalloc_raw_alloc(1, ctx, nelem, elsize); +} + + +static void* +tracemalloc_raw_realloc(void *ctx, void *ptr, size_t new_size) +{ + PyGILState_STATE gil_state; + void *ptr2; + + if (get_reentrant()) { + /* Reentrant call to PyMem_RawRealloc(). */ + PyMemAllocatorEx *alloc = (PyMemAllocatorEx *)ctx; + + ptr2 = alloc->realloc(alloc->ctx, ptr, new_size); + + if (ptr2 != NULL && ptr != NULL) { + TABLES_LOCK(); + REMOVE_TRACE(ptr); + TABLES_UNLOCK(); + } + return ptr2; + } + + /* Ignore reentrant call. PyGILState_Ensure() may call PyMem_RawMalloc() + indirectly which would call PyGILState_Ensure() if reentrant calls are + not disabled. */ + set_reentrant(1); + + gil_state = PyGILState_Ensure(); + ptr2 = tracemalloc_realloc(ctx, ptr, new_size); + PyGILState_Release(gil_state); + + set_reentrant(0); + return ptr2; +} +#endif /* TRACE_RAW_MALLOC */ + + +static void +tracemalloc_clear_filename(void *value) +{ + PyObject *filename = (PyObject *)value; + Py_DECREF(filename); +} + + +/* reentrant flag must be set to call this function and GIL must be held */ +static void +tracemalloc_clear_traces(void) +{ + /* The GIL protects variables against concurrent access */ + assert(PyGILState_Check()); + + TABLES_LOCK(); + _Py_hashtable_clear(tracemalloc_traces); + _Py_hashtable_clear(tracemalloc_domains); + tracemalloc_traced_memory = 0; + tracemalloc_peak_traced_memory = 0; + TABLES_UNLOCK(); + + _Py_hashtable_clear(tracemalloc_tracebacks); + + _Py_hashtable_clear(tracemalloc_filenames); +} + + +int +_PyTraceMalloc_Init(void) +{ + if (tracemalloc_config.initialized == TRACEMALLOC_FINALIZED) { + PyErr_SetString(PyExc_RuntimeError, + "the tracemalloc module has been unloaded"); + return -1; + } + + if (tracemalloc_config.initialized == TRACEMALLOC_INITIALIZED) + return 0; + + PyMem_GetAllocator(PYMEM_DOMAIN_RAW, &allocators.raw); + +#ifdef REENTRANT_THREADLOCAL + if (PyThread_tss_create(&tracemalloc_reentrant_key) != 0) { +#ifdef MS_WINDOWS + PyErr_SetFromWindowsErr(0); +#else + PyErr_SetFromErrno(PyExc_OSError); +#endif + return -1; + } +#endif + +#if defined(TRACE_RAW_MALLOC) + if (tables_lock == NULL) { + tables_lock = PyThread_allocate_lock(); + if (tables_lock == NULL) { + PyErr_SetString(PyExc_RuntimeError, "cannot allocate lock"); + return -1; + } + } +#endif + + tracemalloc_filenames = hashtable_new(hashtable_hash_pyobject, + hashtable_compare_unicode, + tracemalloc_clear_filename, NULL); + + tracemalloc_tracebacks = hashtable_new(hashtable_hash_traceback, + hashtable_compare_traceback, + NULL, raw_free); + + tracemalloc_traces = tracemalloc_create_traces_table(); + tracemalloc_domains = tracemalloc_create_domains_table(); + + if (tracemalloc_filenames == NULL || tracemalloc_tracebacks == NULL + || tracemalloc_traces == NULL || tracemalloc_domains == NULL) { + PyErr_NoMemory(); + return -1; + } + + tracemalloc_empty_traceback.nframe = 1; + tracemalloc_empty_traceback.total_nframe = 1; + /* borrowed reference */ + tracemalloc_empty_traceback.frames[0].filename = &_Py_STR(anon_unknown); + tracemalloc_empty_traceback.frames[0].lineno = 0; + tracemalloc_empty_traceback.hash = traceback_hash(&tracemalloc_empty_traceback); + + tracemalloc_config.initialized = TRACEMALLOC_INITIALIZED; + return 0; +} + + +static void +tracemalloc_deinit(void) +{ + if (tracemalloc_config.initialized != TRACEMALLOC_INITIALIZED) + return; + tracemalloc_config.initialized = TRACEMALLOC_FINALIZED; + + _PyTraceMalloc_Stop(); + + /* destroy hash tables */ + _Py_hashtable_destroy(tracemalloc_domains); + _Py_hashtable_destroy(tracemalloc_traces); + _Py_hashtable_destroy(tracemalloc_tracebacks); + _Py_hashtable_destroy(tracemalloc_filenames); + +#if defined(TRACE_RAW_MALLOC) + if (tables_lock != NULL) { + PyThread_free_lock(tables_lock); + tables_lock = NULL; + } +#endif + +#ifdef REENTRANT_THREADLOCAL + PyThread_tss_delete(&tracemalloc_reentrant_key); +#endif +} + + +int +_PyTraceMalloc_Start(int max_nframe) +{ + PyMemAllocatorEx alloc; + size_t size; + + if (max_nframe < 1 || (unsigned long) max_nframe > MAX_NFRAME) { + PyErr_Format(PyExc_ValueError, + "the number of frames must be in range [1; %lu]", + MAX_NFRAME); + return -1; + } + + if (_PyTraceMalloc_Init() < 0) { + return -1; + } + + if (tracemalloc_config.tracing) { + /* hook already installed: do nothing */ + return 0; + } + + tracemalloc_config.max_nframe = max_nframe; + + /* allocate a buffer to store a new traceback */ + size = TRACEBACK_SIZE(max_nframe); + assert(tracemalloc_traceback == NULL); + tracemalloc_traceback = raw_malloc(size); + if (tracemalloc_traceback == NULL) { + PyErr_NoMemory(); + return -1; + } + +#ifdef TRACE_RAW_MALLOC + alloc.malloc = tracemalloc_raw_malloc; + alloc.calloc = tracemalloc_raw_calloc; + alloc.realloc = tracemalloc_raw_realloc; + alloc.free = tracemalloc_free; + + alloc.ctx = &allocators.raw; + PyMem_GetAllocator(PYMEM_DOMAIN_RAW, &allocators.raw); + PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &alloc); +#endif + + alloc.malloc = tracemalloc_malloc_gil; + alloc.calloc = tracemalloc_calloc_gil; + alloc.realloc = tracemalloc_realloc_gil; + alloc.free = tracemalloc_free; + + alloc.ctx = &allocators.mem; + PyMem_GetAllocator(PYMEM_DOMAIN_MEM, &allocators.mem); + PyMem_SetAllocator(PYMEM_DOMAIN_MEM, &alloc); + + alloc.ctx = &allocators.obj; + PyMem_GetAllocator(PYMEM_DOMAIN_OBJ, &allocators.obj); + PyMem_SetAllocator(PYMEM_DOMAIN_OBJ, &alloc); + + /* everything is ready: start tracing Python memory allocations */ + tracemalloc_config.tracing = 1; + + return 0; +} + + +void +_PyTraceMalloc_Stop(void) +{ + if (!tracemalloc_config.tracing) + return; + + /* stop tracing Python memory allocations */ + tracemalloc_config.tracing = 0; + + /* unregister the hook on memory allocators */ +#ifdef TRACE_RAW_MALLOC + PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &allocators.raw); +#endif + PyMem_SetAllocator(PYMEM_DOMAIN_MEM, &allocators.mem); + PyMem_SetAllocator(PYMEM_DOMAIN_OBJ, &allocators.obj); + + tracemalloc_clear_traces(); + + /* release memory */ + raw_free(tracemalloc_traceback); + tracemalloc_traceback = NULL; +} + + + +static PyObject* +frame_to_pyobject(frame_t *frame) +{ + PyObject *frame_obj, *lineno_obj; + + frame_obj = PyTuple_New(2); + if (frame_obj == NULL) + return NULL; + + PyTuple_SET_ITEM(frame_obj, 0, Py_NewRef(frame->filename)); + + lineno_obj = PyLong_FromUnsignedLong(frame->lineno); + if (lineno_obj == NULL) { + Py_DECREF(frame_obj); + return NULL; + } + PyTuple_SET_ITEM(frame_obj, 1, lineno_obj); + + return frame_obj; +} + + +static PyObject* +traceback_to_pyobject(traceback_t *traceback, _Py_hashtable_t *intern_table) +{ + PyObject *frames; + + if (intern_table != NULL) { + frames = _Py_hashtable_get(intern_table, (const void *)traceback); + if (frames) { + return Py_NewRef(frames); + } + } + + frames = PyTuple_New(traceback->nframe); + if (frames == NULL) + return NULL; + + for (int i=0; i < traceback->nframe; i++) { + PyObject *frame = frame_to_pyobject(&traceback->frames[i]); + if (frame == NULL) { + Py_DECREF(frames); + return NULL; + } + PyTuple_SET_ITEM(frames, i, frame); + } + + if (intern_table != NULL) { + if (_Py_hashtable_set(intern_table, traceback, frames) < 0) { + Py_DECREF(frames); + PyErr_NoMemory(); + return NULL; + } + /* intern_table keeps a new reference to frames */ + Py_INCREF(frames); + } + return frames; +} + + +static PyObject* +trace_to_pyobject(unsigned int domain, const trace_t *trace, + _Py_hashtable_t *intern_tracebacks) +{ + PyObject *trace_obj = NULL; + PyObject *obj; + + trace_obj = PyTuple_New(4); + if (trace_obj == NULL) + return NULL; + + obj = PyLong_FromSize_t(domain); + if (obj == NULL) { + Py_DECREF(trace_obj); + return NULL; + } + PyTuple_SET_ITEM(trace_obj, 0, obj); + + obj = PyLong_FromSize_t(trace->size); + if (obj == NULL) { + Py_DECREF(trace_obj); + return NULL; + } + PyTuple_SET_ITEM(trace_obj, 1, obj); + + obj = traceback_to_pyobject(trace->traceback, intern_tracebacks); + if (obj == NULL) { + Py_DECREF(trace_obj); + return NULL; + } + PyTuple_SET_ITEM(trace_obj, 2, obj); + + obj = PyLong_FromUnsignedLong(trace->traceback->total_nframe); + if (obj == NULL) { + Py_DECREF(trace_obj); + return NULL; + } + PyTuple_SET_ITEM(trace_obj, 3, obj); + + return trace_obj; +} + + +typedef struct { + _Py_hashtable_t *traces; + _Py_hashtable_t *domains; + _Py_hashtable_t *tracebacks; + PyObject *list; + unsigned int domain; +} get_traces_t; + + +static int +tracemalloc_copy_trace(_Py_hashtable_t *traces, + const void *key, const void *value, + void *user_data) +{ + _Py_hashtable_t *traces2 = (_Py_hashtable_t *)user_data; + + trace_t *trace = (trace_t *)value; + + trace_t *trace2 = raw_malloc(sizeof(trace_t)); + if (trace2 == NULL) { + return -1; + } + *trace2 = *trace; + if (_Py_hashtable_set(traces2, key, trace2) < 0) { + raw_free(trace2); + return -1; + } + return 0; +} + + +static _Py_hashtable_t* +tracemalloc_copy_traces(_Py_hashtable_t *traces) +{ + _Py_hashtable_t *traces2 = tracemalloc_create_traces_table(); + if (traces2 == NULL) { + return NULL; + } + + int err = _Py_hashtable_foreach(traces, + tracemalloc_copy_trace, + traces2); + if (err) { + _Py_hashtable_destroy(traces2); + return NULL; + } + return traces2; +} + + +static int +tracemalloc_copy_domain(_Py_hashtable_t *domains, + const void *key, const void *value, + void *user_data) +{ + _Py_hashtable_t *domains2 = (_Py_hashtable_t *)user_data; + + unsigned int domain = (unsigned int)FROM_PTR(key); + _Py_hashtable_t *traces = (_Py_hashtable_t *)value; + + _Py_hashtable_t *traces2 = tracemalloc_copy_traces(traces); + if (traces2 == NULL) { + return -1; + } + if (_Py_hashtable_set(domains2, TO_PTR(domain), traces2) < 0) { + _Py_hashtable_destroy(traces2); + return -1; + } + return 0; +} + + +static _Py_hashtable_t* +tracemalloc_copy_domains(_Py_hashtable_t *domains) +{ + _Py_hashtable_t *domains2 = tracemalloc_create_domains_table(); + if (domains2 == NULL) { + return NULL; + } + + int err = _Py_hashtable_foreach(domains, + tracemalloc_copy_domain, + domains2); + if (err) { + _Py_hashtable_destroy(domains2); + return NULL; + } + return domains2; +} + + +static int +tracemalloc_get_traces_fill(_Py_hashtable_t *traces, + const void *key, const void *value, + void *user_data) +{ + get_traces_t *get_traces = user_data; + + const trace_t *trace = (const trace_t *)value; + + PyObject *tuple = trace_to_pyobject(get_traces->domain, trace, + get_traces->tracebacks); + if (tuple == NULL) { + return 1; + } + + int res = PyList_Append(get_traces->list, tuple); + Py_DECREF(tuple); + if (res < 0) { + return 1; + } + + return 0; +} + + +static int +tracemalloc_get_traces_domain(_Py_hashtable_t *domains, + const void *key, const void *value, + void *user_data) +{ + get_traces_t *get_traces = user_data; + + unsigned int domain = (unsigned int)FROM_PTR(key); + _Py_hashtable_t *traces = (_Py_hashtable_t *)value; + + get_traces->domain = domain; + return _Py_hashtable_foreach(traces, + tracemalloc_get_traces_fill, + get_traces); +} + + +static void +tracemalloc_pyobject_decref(void *value) +{ + PyObject *obj = (PyObject *)value; + Py_DECREF(obj); +} + + +static traceback_t* +tracemalloc_get_traceback(unsigned int domain, uintptr_t ptr) +{ + + if (!tracemalloc_config.tracing) + return NULL; + + trace_t *trace; + TABLES_LOCK(); + _Py_hashtable_t *traces = tracemalloc_get_traces_table(domain); + if (traces) { + trace = _Py_hashtable_get(traces, TO_PTR(ptr)); + } + else { + trace = NULL; + } + TABLES_UNLOCK(); + + if (!trace) { + return NULL; + } + + return trace->traceback; +} + + +#define PUTS(fd, str) _Py_write_noraise(fd, str, (int)strlen(str)) + +static void +_PyMem_DumpFrame(int fd, frame_t * frame) +{ + PUTS(fd, " File \""); + _Py_DumpASCII(fd, frame->filename); + PUTS(fd, "\", line "); + _Py_DumpDecimal(fd, frame->lineno); + PUTS(fd, "\n"); +} + +/* Dump the traceback where a memory block was allocated into file descriptor + fd. The function may block on TABLES_LOCK() but it is unlikely. */ +void +_PyMem_DumpTraceback(int fd, const void *ptr) +{ + traceback_t *traceback; + int i; + + if (!tracemalloc_config.tracing) { + PUTS(fd, "Enable tracemalloc to get the memory block " + "allocation traceback\n\n"); + return; + } + + traceback = tracemalloc_get_traceback(DEFAULT_DOMAIN, (uintptr_t)ptr); + if (traceback == NULL) + return; + + PUTS(fd, "Memory block allocated at (most recent call first):\n"); + for (i=0; i < traceback->nframe; i++) { + _PyMem_DumpFrame(fd, &traceback->frames[i]); + } + PUTS(fd, "\n"); +} + +#undef PUTS + + +static int +tracemalloc_get_tracemalloc_memory_cb(_Py_hashtable_t *domains, + const void *key, const void *value, + void *user_data) +{ + const _Py_hashtable_t *traces = value; + size_t *size = (size_t*)user_data; + *size += _Py_hashtable_size(traces); + return 0; +} + +int +PyTraceMalloc_Track(unsigned int domain, uintptr_t ptr, + size_t size) +{ + int res; + PyGILState_STATE gil_state; + + if (!tracemalloc_config.tracing) { + /* tracemalloc is not tracing: do nothing */ + return -2; + } + + gil_state = PyGILState_Ensure(); + + TABLES_LOCK(); + res = tracemalloc_add_trace(domain, ptr, size); + TABLES_UNLOCK(); + + PyGILState_Release(gil_state); + return res; +} + + +int +PyTraceMalloc_Untrack(unsigned int domain, uintptr_t ptr) +{ + if (!tracemalloc_config.tracing) { + /* tracemalloc is not tracing: do nothing */ + return -2; + } + + TABLES_LOCK(); + tracemalloc_remove_trace(domain, ptr); + TABLES_UNLOCK(); + + return 0; +} + + +void +_PyTraceMalloc_Fini(void) +{ + assert(PyGILState_Check()); + tracemalloc_deinit(); +} + + +/* If the object memory block is already traced, update its trace + with the current Python traceback. + + Do nothing if tracemalloc is not tracing memory allocations + or if the object memory block is not already traced. */ +int +_PyTraceMalloc_NewReference(PyObject *op) +{ + assert(PyGILState_Check()); + + if (!tracemalloc_config.tracing) { + /* tracemalloc is not tracing: do nothing */ + return -1; + } + + PyTypeObject *type = Py_TYPE(op); + const size_t presize = _PyType_PreHeaderSize(type); + uintptr_t ptr = (uintptr_t)((char *)op - presize); + + int res = -1; + + TABLES_LOCK(); + trace_t *trace = _Py_hashtable_get(tracemalloc_traces, TO_PTR(ptr)); + if (trace != NULL) { + /* update the traceback of the memory block */ + traceback_t *traceback = traceback_new(); + if (traceback != NULL) { + trace->traceback = traceback; + res = 0; + } + } + /* else: cannot track the object, its memory block size is unknown */ + TABLES_UNLOCK(); + + return res; +} + + +PyObject* +_PyTraceMalloc_GetTraceback(unsigned int domain, uintptr_t ptr) +{ + traceback_t *traceback; + + traceback = tracemalloc_get_traceback(domain, ptr); + if (traceback == NULL) + Py_RETURN_NONE; + + return traceback_to_pyobject(traceback, NULL); +} + +int +_PyTraceMalloc_IsTracing(void) +{ + return tracemalloc_config.tracing; +} + +void +_PyTraceMalloc_ClearTraces(void) +{ + + if (!tracemalloc_config.tracing) { + return; + } + set_reentrant(1); + tracemalloc_clear_traces(); + set_reentrant(0); +} + +PyObject * +_PyTraceMalloc_GetTraces(void) +{ + get_traces_t get_traces; + get_traces.domain = DEFAULT_DOMAIN; + get_traces.traces = NULL; + get_traces.domains = NULL; + get_traces.tracebacks = NULL; + get_traces.list = PyList_New(0); + if (get_traces.list == NULL) + goto error; + + if (!tracemalloc_config.tracing) + return get_traces.list; + + /* the traceback hash table is used temporarily to intern traceback tuple + of (filename, lineno) tuples */ + get_traces.tracebacks = hashtable_new(_Py_hashtable_hash_ptr, + _Py_hashtable_compare_direct, + NULL, tracemalloc_pyobject_decref); + if (get_traces.tracebacks == NULL) { + goto no_memory; + } + + // Copy all traces so tracemalloc_get_traces_fill() doesn't have to disable + // temporarily tracemalloc which would impact other threads and so would + // miss allocations while get_traces() is called. + TABLES_LOCK(); + get_traces.traces = tracemalloc_copy_traces(tracemalloc_traces); + TABLES_UNLOCK(); + + if (get_traces.traces == NULL) { + goto no_memory; + } + + TABLES_LOCK(); + get_traces.domains = tracemalloc_copy_domains(tracemalloc_domains); + TABLES_UNLOCK(); + + if (get_traces.domains == NULL) { + goto no_memory; + } + + // Convert traces to a list of tuples + set_reentrant(1); + int err = _Py_hashtable_foreach(get_traces.traces, + tracemalloc_get_traces_fill, + &get_traces); + if (!err) { + err = _Py_hashtable_foreach(get_traces.domains, + tracemalloc_get_traces_domain, + &get_traces); + } + set_reentrant(0); + if (err) { + goto error; + } + + goto finally; + +no_memory: + PyErr_NoMemory(); + +error: + Py_CLEAR(get_traces.list); + +finally: + if (get_traces.tracebacks != NULL) { + _Py_hashtable_destroy(get_traces.tracebacks); + } + if (get_traces.traces != NULL) { + _Py_hashtable_destroy(get_traces.traces); + } + if (get_traces.domains != NULL) { + _Py_hashtable_destroy(get_traces.domains); + } + + return get_traces.list; +} + +PyObject * +_PyTraceMalloc_GetObjectTraceback(PyObject *obj) +/*[clinic end generated code: output=41ee0553a658b0aa input=29495f1b21c53212]*/ +{ + PyTypeObject *type; + traceback_t *traceback; + + type = Py_TYPE(obj); + const size_t presize = _PyType_PreHeaderSize(type); + uintptr_t ptr = (uintptr_t)((char *)obj - presize); + + traceback = tracemalloc_get_traceback(DEFAULT_DOMAIN, ptr); + if (traceback == NULL) { + Py_RETURN_NONE; + } + + return traceback_to_pyobject(traceback, NULL); +} + +int _PyTraceMalloc_GetTracebackLimit(void) { + return tracemalloc_config.max_nframe; +} + +size_t +_PyTraceMalloc_GetMemory(void) { + + size_t size; + + size = _Py_hashtable_size(tracemalloc_tracebacks); + size += _Py_hashtable_size(tracemalloc_filenames); + + TABLES_LOCK(); + size += _Py_hashtable_size(tracemalloc_traces); + _Py_hashtable_foreach(tracemalloc_domains, + tracemalloc_get_tracemalloc_memory_cb, &size); + TABLES_UNLOCK(); + return size; +} + + +PyObject * +_PyTraceMalloc_GetTracedMemory(void) +{ + Py_ssize_t size, peak_size; + + if (!tracemalloc_config.tracing) + return Py_BuildValue("ii", 0, 0); + + TABLES_LOCK(); + size = tracemalloc_traced_memory; + peak_size = tracemalloc_peak_traced_memory; + TABLES_UNLOCK(); + + return Py_BuildValue("nn", size, peak_size); +} + +void +_PyTraceMalloc_ResetPeak(void) +{ + if (!tracemalloc_config.tracing) { + return; + } + TABLES_LOCK(); + tracemalloc_peak_traced_memory = tracemalloc_traced_memory; + TABLES_UNLOCK(); +} diff --git a/README.rst b/README.rst index 2cd94716..979ca018 100644 --- a/README.rst +++ b/README.rst @@ -1,4 +1,4 @@ -This is Python version 3.11.2 +This is Python version 3.12.0 ============================= .. image:: https://github.com/python/cpython/workflows/Tests/badge.svg @@ -133,7 +133,7 @@ What's New ---------- We have a comprehensive overview of the changes in the `What's New in Python -3.11 <https://docs.python.org/3.11/whatsnew/3.11.html>`_ document. For a more +3.12 <https://docs.python.org/3.12/whatsnew/3.12.html>`_ document. For a more detailed change log, read `Misc/NEWS <https://github.com/python/cpython/tree/main/Misc/NEWS.d>`_, but a full accounting of changes can only be gleaned from the `commit history @@ -146,7 +146,7 @@ entitled "Installing multiple versions". Documentation ------------- -`Documentation for Python 3.11 <https://docs.python.org/3.11/>`_ is online, +`Documentation for Python 3.12 <https://docs.python.org/3.12/>`_ is online, updated daily. It can also be downloaded in many formats for faster access. The documentation @@ -206,39 +206,15 @@ intend to install multiple versions using the same prefix you must decide which version (if any) is your "primary" version. Install that version using ``make install``. Install all other versions using ``make altinstall``. -For example, if you want to install Python 2.7, 3.6, and 3.11 with 3.11 being the -primary version, you would execute ``make install`` in your 3.11 build directory +For example, if you want to install Python 2.7, 3.6, and 3.12 with 3.12 being the +primary version, you would execute ``make install`` in your 3.12 build directory and ``make altinstall`` in the others. -Issue Tracker and Mailing List ------------------------------- - -Bug reports are welcome! You can use Github to `report bugs -<https://github.com/python/cpython/issues>`_, and/or `submit pull requests -<https://github.com/python/cpython/pulls>`_. - -You can also follow development discussion on the `python-dev mailing list -<https://mail.python.org/mailman/listinfo/python-dev/>`_. - - -Proposals for enhancement -------------------------- - -If you have a proposal to change Python, you may want to send an email to the -`comp.lang.python`_ or `python-ideas`_ mailing lists for initial feedback. A -Python Enhancement Proposal (PEP) may be submitted if your idea gains ground. -All current PEPs, as well as guidelines for submitting a new PEP, are listed at -`peps.python.org <https://peps.python.org/>`_. - -.. _python-ideas: https://mail.python.org/mailman/listinfo/python-ideas/ -.. _comp.lang.python: https://mail.python.org/mailman/listinfo/python-list - - Release Schedule ---------------- -See :pep:`664` for Python 3.11 release details. +See :pep:`693` for Python 3.12 release details. Copyright and License Information diff --git a/Tools/README b/Tools/README index f8bfbc04..e51624f4 100644 --- a/Tools/README +++ b/Tools/README @@ -1,11 +1,20 @@ This directory contains a number of Python programs that are useful while building or extending Python. +build Automatically generated directory by the build system + contain build artifacts and intermediate files. + buildbot Batchfiles for running on Windows buildbot workers. +c-analyzer Tools to check no new global variables have been added. + +cases_generator Tooling to generate interpreters. + ccbench A Python threads-based concurrency benchmark. (*) -demo Several Python programming demos. +clinic A preprocessor for CPython C files in order to automate + the boilerplate involved with writing argument parsing + code for "builtins". freeze Create a stand-alone executable from a Python program. @@ -17,11 +26,16 @@ i18n Tools for internationalization. pygettext.py and msgfmt.py generates a binary message catalog from a catalog in text format. +importbench A set of micro-benchmarks for various import scenarios. + iobench Benchmark for the new Python I/O system. (*) msi Support for packaging Python as an MSI package on Windows. -parser Un-parsing tool to generate code from an AST. +nuget Files for the NuGet package manager for .NET. + +patchcheck Tools for checking and applying patches to the Python source code + and verifying the integrity of patch files. peg_generator PEG-based parser generator (pegen) used for new parser. @@ -30,9 +44,14 @@ scripts A number of useful single-file programs, e.g. tabnanny.py tabs and spaces, and 2to3, which converts Python 2 code to Python 3 code. +ssl Scripts to generate ssl_data.h from OpenSSL sources, and run + tests against multiple installations of OpenSSL and LibreSSL. + stringbench A suite of micro-benchmarks for various operations on strings (both 8-bit and unicode). (*) +tz A script to dump timezone from /usr/share/zoneinfo. + unicode Tools for generating unicodedata and codecs from unicode.org and other mapping files (by Fredrik Lundh, Marc-Andre Lemburg and Martin von Loewis). @@ -40,6 +59,8 @@ unicode Tools for generating unicodedata and codecs from unicode.org unittestgui A Tkinter based GUI test runner for unittest, with test discovery. +wasm Config and helpers to facilitate cross compilation of CPython + to WebAssembly (WASM). (*) A generic benchmark suite is maintained separately at https://github.com/python/performance diff --git a/Tools/build/check_extension_modules.py b/Tools/build/check_extension_modules.py new file mode 100644 index 00000000..59239c62 --- /dev/null +++ b/Tools/build/check_extension_modules.py @@ -0,0 +1,484 @@ +"""Check extension modules + +The script checks shared and built-in extension modules. It verifies that the +modules have been built and that they can be imported successfully. Missing +modules and failed imports are reported to the user. Shared extension +files are renamed on failed import. + +Module information is parsed from several sources: + +- core modules hard-coded in Modules/config.c.in +- Windows-specific modules that are hard-coded in PC/config.c +- MODULE_{name}_STATE entries in Makefile (provided through sysconfig) +- Various makesetup files: + - $(srcdir)/Modules/Setup + - Modules/Setup.[local|bootstrap|stdlib] files, which are generated + from $(srcdir)/Modules/Setup.*.in files + +See --help for more information +""" +import argparse +import collections +import enum +import logging +import os +import pathlib +import re +import sys +import sysconfig +import warnings + +from importlib._bootstrap import _load as bootstrap_load +from importlib.machinery import BuiltinImporter, ExtensionFileLoader, ModuleSpec +from importlib.util import spec_from_file_location, spec_from_loader +from typing import Iterable + +SRC_DIR = pathlib.Path(__file__).parent.parent.parent + +# core modules, hard-coded in Modules/config.h.in +CORE_MODULES = { + "_ast", + "_imp", + "_string", + "_tokenize", + "_warnings", + "builtins", + "gc", + "marshal", + "sys", +} + +# Windows-only modules +WINDOWS_MODULES = { + "_msi", + "_overlapped", + "_testconsole", + "_winapi", + "msvcrt", + "nt", + "winreg", + "winsound", +} + + +logger = logging.getLogger(__name__) + +parser = argparse.ArgumentParser( + prog="check_extension_modules", + description=__doc__, + formatter_class=argparse.RawDescriptionHelpFormatter, +) + +parser.add_argument( + "--verbose", + action="store_true", + help="Verbose, report builtin, shared, and unavailable modules", +) + +parser.add_argument( + "--debug", + action="store_true", + help="Enable debug logging", +) + +parser.add_argument( + "--strict", + action=argparse.BooleanOptionalAction, + help=( + "Strict check, fail when a module is missing or fails to import" + "(default: no, unless env var PYTHONSTRICTEXTENSIONBUILD is set)" + ), + default=bool(os.environ.get("PYTHONSTRICTEXTENSIONBUILD")), +) + +parser.add_argument( + "--cross-compiling", + action=argparse.BooleanOptionalAction, + help=( + "Use cross-compiling checks " + "(default: no, unless env var _PYTHON_HOST_PLATFORM is set)." + ), + default="_PYTHON_HOST_PLATFORM" in os.environ, +) + +parser.add_argument( + "--list-module-names", + action="store_true", + help="Print a list of module names to stdout and exit", +) + + +class ModuleState(enum.Enum): + # Makefile state "yes" + BUILTIN = "builtin" + SHARED = "shared" + + DISABLED = "disabled" + MISSING = "missing" + NA = "n/a" + # disabled by Setup / makesetup rule + DISABLED_SETUP = "disabled_setup" + + def __bool__(self): + return self.value in {"builtin", "shared"} + + +ModuleInfo = collections.namedtuple("ModuleInfo", "name state") + + +class ModuleChecker: + pybuilddir_txt = "pybuilddir.txt" + + setup_files = ( + # see end of configure.ac + "Modules/Setup.local", + "Modules/Setup.stdlib", + "Modules/Setup.bootstrap", + SRC_DIR / "Modules/Setup", + ) + + def __init__(self, cross_compiling: bool = False, strict: bool = False): + self.cross_compiling = cross_compiling + self.strict_extensions_build = strict + self.ext_suffix = sysconfig.get_config_var("EXT_SUFFIX") + self.platform = sysconfig.get_platform() + self.builddir = self.get_builddir() + self.modules = self.get_modules() + + self.builtin_ok = [] + self.shared_ok = [] + self.failed_on_import = [] + self.missing = [] + self.disabled_configure = [] + self.disabled_setup = [] + self.notavailable = [] + + def check(self): + for modinfo in self.modules: + logger.debug("Checking '%s' (%s)", modinfo.name, self.get_location(modinfo)) + if modinfo.state == ModuleState.DISABLED: + self.disabled_configure.append(modinfo) + elif modinfo.state == ModuleState.DISABLED_SETUP: + self.disabled_setup.append(modinfo) + elif modinfo.state == ModuleState.MISSING: + self.missing.append(modinfo) + elif modinfo.state == ModuleState.NA: + self.notavailable.append(modinfo) + else: + try: + if self.cross_compiling: + self.check_module_cross(modinfo) + else: + self.check_module_import(modinfo) + except (ImportError, FileNotFoundError): + self.rename_module(modinfo) + self.failed_on_import.append(modinfo) + else: + if modinfo.state == ModuleState.BUILTIN: + self.builtin_ok.append(modinfo) + else: + assert modinfo.state == ModuleState.SHARED + self.shared_ok.append(modinfo) + + def summary(self, *, verbose: bool = False): + longest = max([len(e.name) for e in self.modules], default=0) + + def print_three_column(modinfos: list[ModuleInfo]): + names = [modinfo.name for modinfo in modinfos] + names.sort(key=str.lower) + # guarantee zip() doesn't drop anything + while len(names) % 3: + names.append("") + for l, m, r in zip(names[::3], names[1::3], names[2::3]): + print("%-*s %-*s %-*s" % (longest, l, longest, m, longest, r)) + + if verbose and self.builtin_ok: + print("The following *built-in* modules have been successfully built:") + print_three_column(self.builtin_ok) + print() + + if verbose and self.shared_ok: + print("The following *shared* modules have been successfully built:") + print_three_column(self.shared_ok) + print() + + if self.disabled_configure: + print("The following modules are *disabled* in configure script:") + print_three_column(self.disabled_configure) + print() + + if self.disabled_setup: + print("The following modules are *disabled* in Modules/Setup files:") + print_three_column(self.disabled_setup) + print() + + if verbose and self.notavailable: + print( + f"The following modules are not available on platform '{self.platform}':" + ) + print_three_column(self.notavailable) + print() + + if self.missing: + print("The necessary bits to build these optional modules were not found:") + print_three_column(self.missing) + print("To find the necessary bits, look in configure.ac and config.log.") + print() + + if self.failed_on_import: + print( + "Following modules built successfully " + "but were removed because they could not be imported:" + ) + print_three_column(self.failed_on_import) + print() + + if any( + modinfo.name == "_ssl" for modinfo in self.missing + self.failed_on_import + ): + print("Could not build the ssl module!") + print("Python requires a OpenSSL 1.1.1 or newer") + if sysconfig.get_config_var("OPENSSL_LDFLAGS"): + print("Custom linker flags may require --with-openssl-rpath=auto") + print() + + disabled = len(self.disabled_configure) + len(self.disabled_setup) + print( + f"Checked {len(self.modules)} modules (" + f"{len(self.builtin_ok)} built-in, " + f"{len(self.shared_ok)} shared, " + f"{len(self.notavailable)} n/a on {self.platform}, " + f"{disabled} disabled, " + f"{len(self.missing)} missing, " + f"{len(self.failed_on_import)} failed on import)" + ) + + def check_strict_build(self): + """Fail if modules are missing and it's a strict build""" + if self.strict_extensions_build and (self.failed_on_import or self.missing): + raise RuntimeError("Failed to build some stdlib modules") + + def list_module_names(self, *, all: bool = False) -> set: + names = {modinfo.name for modinfo in self.modules} + if all: + names.update(WINDOWS_MODULES) + return names + + def get_builddir(self) -> pathlib.Path: + try: + with open(self.pybuilddir_txt, encoding="utf-8") as f: + builddir = f.read() + except FileNotFoundError: + logger.error("%s must be run from the top build directory", __file__) + raise + builddir = pathlib.Path(builddir) + logger.debug("%s: %s", self.pybuilddir_txt, builddir) + return builddir + + def get_modules(self) -> list[ModuleInfo]: + """Get module info from sysconfig and Modules/Setup* files""" + seen = set() + modules = [] + # parsing order is important, first entry wins + for modinfo in self.get_core_modules(): + modules.append(modinfo) + seen.add(modinfo.name) + for setup_file in self.setup_files: + for modinfo in self.parse_setup_file(setup_file): + if modinfo.name not in seen: + modules.append(modinfo) + seen.add(modinfo.name) + for modinfo in self.get_sysconfig_modules(): + if modinfo.name not in seen: + modules.append(modinfo) + seen.add(modinfo.name) + logger.debug("Found %i modules in total", len(modules)) + modules.sort() + return modules + + def get_core_modules(self) -> Iterable[ModuleInfo]: + """Get hard-coded core modules""" + for name in CORE_MODULES: + modinfo = ModuleInfo(name, ModuleState.BUILTIN) + logger.debug("Found core module %s", modinfo) + yield modinfo + + def get_sysconfig_modules(self) -> Iterable[ModuleInfo]: + """Get modules defined in Makefile through sysconfig + + MODBUILT_NAMES: modules in *static* block + MODSHARED_NAMES: modules in *shared* block + MODDISABLED_NAMES: modules in *disabled* block + """ + moddisabled = set(sysconfig.get_config_var("MODDISABLED_NAMES").split()) + if self.cross_compiling: + modbuiltin = set(sysconfig.get_config_var("MODBUILT_NAMES").split()) + else: + modbuiltin = set(sys.builtin_module_names) + + for key, value in sysconfig.get_config_vars().items(): + if not key.startswith("MODULE_") or not key.endswith("_STATE"): + continue + if value not in {"yes", "disabled", "missing", "n/a"}: + raise ValueError(f"Unsupported value '{value}' for {key}") + + modname = key[7:-6].lower() + if modname in moddisabled: + # Setup "*disabled*" rule + state = ModuleState.DISABLED_SETUP + elif value in {"disabled", "missing", "n/a"}: + state = ModuleState(value) + elif modname in modbuiltin: + assert value == "yes" + state = ModuleState.BUILTIN + else: + assert value == "yes" + state = ModuleState.SHARED + + modinfo = ModuleInfo(modname, state) + logger.debug("Found %s in Makefile", modinfo) + yield modinfo + + def parse_setup_file(self, setup_file: pathlib.Path) -> Iterable[ModuleInfo]: + """Parse a Modules/Setup file""" + assign_var = re.compile(r"^\w+=") # EGG_SPAM=foo + # default to static module + state = ModuleState.BUILTIN + logger.debug("Parsing Setup file %s", setup_file) + with open(setup_file, encoding="utf-8") as f: + for line in f: + line = line.strip() + if not line or line.startswith("#") or assign_var.match(line): + continue + match line.split(): + case ["*shared*"]: + state = ModuleState.SHARED + case ["*static*"]: + state = ModuleState.BUILTIN + case ["*disabled*"]: + state = ModuleState.DISABLED + case ["*noconfig*"]: + state = None + case [*items]: + if state == ModuleState.DISABLED: + # *disabled* can disable multiple modules per line + for item in items: + modinfo = ModuleInfo(item, state) + logger.debug("Found %s in %s", modinfo, setup_file) + yield modinfo + elif state in {ModuleState.SHARED, ModuleState.BUILTIN}: + # *shared* and *static*, first item is the name of the module. + modinfo = ModuleInfo(items[0], state) + logger.debug("Found %s in %s", modinfo, setup_file) + yield modinfo + + def get_spec(self, modinfo: ModuleInfo) -> ModuleSpec: + """Get ModuleSpec for builtin or extension module""" + if modinfo.state == ModuleState.SHARED: + location = os.fspath(self.get_location(modinfo)) + loader = ExtensionFileLoader(modinfo.name, location) + return spec_from_file_location(modinfo.name, location, loader=loader) + elif modinfo.state == ModuleState.BUILTIN: + return spec_from_loader(modinfo.name, loader=BuiltinImporter) + else: + raise ValueError(modinfo) + + def get_location(self, modinfo: ModuleInfo) -> pathlib.Path: + """Get shared library location in build directory""" + if modinfo.state == ModuleState.SHARED: + return self.builddir / f"{modinfo.name}{self.ext_suffix}" + else: + return None + + def _check_file(self, modinfo: ModuleInfo, spec: ModuleSpec): + """Check that the module file is present and not empty""" + if spec.loader is BuiltinImporter: + return + try: + st = os.stat(spec.origin) + except FileNotFoundError: + logger.error("%s (%s) is missing", modinfo.name, spec.origin) + raise + if not st.st_size: + raise ImportError(f"{spec.origin} is an empty file") + + def check_module_import(self, modinfo: ModuleInfo): + """Attempt to import module and report errors""" + spec = self.get_spec(modinfo) + self._check_file(modinfo, spec) + try: + with warnings.catch_warnings(): + # ignore deprecation warning from deprecated modules + warnings.simplefilter("ignore", DeprecationWarning) + bootstrap_load(spec) + except ImportError as e: + logger.error("%s failed to import: %s", modinfo.name, e) + raise + except Exception as e: + logger.exception("Importing extension '%s' failed!", modinfo.name) + raise + + def check_module_cross(self, modinfo: ModuleInfo): + """Sanity check for cross compiling""" + spec = self.get_spec(modinfo) + self._check_file(modinfo, spec) + + def rename_module(self, modinfo: ModuleInfo) -> None: + """Rename module file""" + if modinfo.state == ModuleState.BUILTIN: + logger.error("Cannot mark builtin module '%s' as failed!", modinfo.name) + return + + failed_name = f"{modinfo.name}_failed{self.ext_suffix}" + builddir_path = self.get_location(modinfo) + if builddir_path.is_symlink(): + symlink = builddir_path + module_path = builddir_path.resolve().relative_to(os.getcwd()) + failed_path = module_path.parent / failed_name + else: + symlink = None + module_path = builddir_path + failed_path = self.builddir / failed_name + + # remove old failed file + failed_path.unlink(missing_ok=True) + # remove symlink + if symlink is not None: + symlink.unlink(missing_ok=True) + # rename shared extension file + try: + module_path.rename(failed_path) + except FileNotFoundError: + logger.debug("Shared extension file '%s' does not exist.", module_path) + else: + logger.debug("Rename '%s' -> '%s'", module_path, failed_path) + + +def main(): + args = parser.parse_args() + if args.debug: + args.verbose = True + logging.basicConfig( + level=logging.DEBUG if args.debug else logging.INFO, + format="[%(levelname)s] %(message)s", + ) + + checker = ModuleChecker( + cross_compiling=args.cross_compiling, + strict=args.strict, + ) + if args.list_module_names: + names = checker.list_module_names(all=True) + for name in sorted(names): + print(name) + else: + checker.check() + checker.summary(verbose=args.verbose) + try: + checker.check_strict_build() + except RuntimeError as e: + parser.exit(1, f"\nError: {e}\n") + + +if __name__ == "__main__": + main() diff --git a/Tools/scripts/deepfreeze.py b/Tools/build/deepfreeze.py similarity index 88% rename from Tools/scripts/deepfreeze.py rename to Tools/build/deepfreeze.py index c300c301..b084d3e4 100644 --- a/Tools/scripts/deepfreeze.py +++ b/Tools/build/deepfreeze.py @@ -44,6 +44,7 @@ CO_FAST_LOCAL = 0x20 CO_FAST_CELL = 0x40 CO_FAST_FREE = 0x80 +next_code_version = 1 def get_localsplus(code: types.CodeType): a = collections.defaultdict(int) @@ -60,7 +61,6 @@ def get_localsplus_counts(code: types.CodeType, names: Tuple[str, ...], kinds: bytes) -> Tuple[int, int, int, int]: nlocals = 0 - nplaincellvars = 0 ncellvars = 0 nfreevars = 0 assert len(names) == len(kinds) @@ -71,15 +71,13 @@ def get_localsplus_counts(code: types.CodeType, ncellvars += 1 elif kind & CO_FAST_CELL: ncellvars += 1 - nplaincellvars += 1 elif kind & CO_FAST_FREE: nfreevars += 1 assert nlocals == len(code.co_varnames) == code.co_nlocals, \ (nlocals, len(code.co_varnames), code.co_nlocals) assert ncellvars == len(code.co_cellvars) assert nfreevars == len(code.co_freevars) - assert len(names) == nlocals + nplaincellvars + nfreevars - return nlocals, nplaincellvars, ncellvars, nfreevars + return nlocals, ncellvars, nfreevars PyUnicode_1BYTE_KIND = 1 @@ -114,12 +112,12 @@ class Printer: self.file = file self.cache: Dict[tuple[type, object, str], str] = {} self.hits, self.misses = 0, 0 - self.patchups: list[str] = [] - self.deallocs: list[str] = [] - self.interns: list[str] = [] + self.finis: list[str] = [] + self.inits: list[str] = [] self.write('#include "Python.h"') self.write('#include "internal/pycore_gc.h"') self.write('#include "internal/pycore_code.h"') + self.write('#include "internal/pycore_frame.h"') self.write('#include "internal/pycore_long.h"') self.write("") @@ -144,7 +142,7 @@ class Printer: def object_head(self, typename: str) -> None: with self.block(".ob_base =", ","): - self.write(f".ob_refcnt = 999999999,") + self.write(f".ob_refcnt = _Py_IMMORTAL_REFCNT,") self.write(f".ob_type = &{typename},") def object_var_head(self, typename: str, size: int) -> None: @@ -177,6 +175,12 @@ class Printer: return f"&_Py_STR({strings[s]})" if s in identifiers: return f"&_Py_ID({s})" + if len(s) == 1: + c = ord(s) + if c < 128: + return f"(PyObject *)&_Py_SINGLETON(strings).ascii[{c}]" + elif c < 256: + return f"(PyObject *)&_Py_SINGLETON(strings).latin1[{c - 128}]" if re.match(r'\A[A-Za-z0-9_]+\Z', s): name = f"const_str_{s}" kind, ascii = analyze_character_width(s) @@ -194,7 +198,6 @@ class Printer: else: self.write("PyCompactUnicodeObject _compact;") self.write(f"{datatype} _data[{len(s)+1}];") - self.deallocs.append(f"_PyStaticUnicode_Dealloc((PyObject *)&{name});") with self.block(f"{name} =", ";"): if ascii: with self.block("._ascii =", ","): @@ -205,7 +208,6 @@ class Printer: self.write(".kind = 1,") self.write(".compact = 1,") self.write(".ascii = 1,") - self.write(".ready = 1,") self.write(f"._data = {make_string_literal(s.encode('ascii'))},") return f"& {name}._ascii.ob_base" else: @@ -218,25 +220,18 @@ class Printer: self.write(f".kind = {kind},") self.write(".compact = 1,") self.write(".ascii = 0,") - self.write(".ready = 1,") + utf8 = s.encode('utf-8') + self.write(f'.utf8 = {make_string_literal(utf8)},') + self.write(f'.utf8_length = {len(utf8)},') with self.block(f"._data =", ","): for i in range(0, len(s), 16): data = s[i:i+16] self.write(", ".join(map(str, map(ord, data))) + ",") - if kind == PyUnicode_2BYTE_KIND: - self.patchups.append("if (sizeof(wchar_t) == 2) {") - self.patchups.append(f" {name}._compact._base.wstr = (wchar_t *) {name}._data;") - self.patchups.append(f" {name}._compact.wstr_length = {len(s)};") - self.patchups.append("}") - if kind == PyUnicode_4BYTE_KIND: - self.patchups.append("if (sizeof(wchar_t) == 4) {") - self.patchups.append(f" {name}._compact._base.wstr = (wchar_t *) {name}._data;") - self.patchups.append(f" {name}._compact.wstr_length = {len(s)};") - self.patchups.append("}") return f"& {name}._compact._base.ob_base" def generate_code(self, name: str, code: types.CodeType) -> str: + global next_code_version # The ordering here matches PyCode_NewWithPosOnlyArgs() # (but see below). co_consts = self.generate(name + "_consts", code.co_consts) @@ -251,7 +246,7 @@ class Printer: co_localsplusnames = self.generate(name + "_localsplusnames", localsplusnames) co_localspluskinds = self.generate(name + "_localspluskinds", localspluskinds) # Derived values - nlocals, nplaincellvars, ncellvars, nfreevars = \ + nlocals, ncellvars, nfreevars = \ get_localsplus_counts(code, localsplusnames, localspluskinds) co_code_adaptive = make_string_literal(code.co_code) self.write("static") @@ -266,34 +261,34 @@ class Printer: self.write(f".co_names = {co_names},") self.write(f".co_exceptiontable = {co_exceptiontable},") self.field(code, "co_flags") - self.write(".co_warmup = QUICKENING_INITIAL_WARMUP_VALUE,") - self.write("._co_linearray_entry_size = 0,") self.field(code, "co_argcount") self.field(code, "co_posonlyargcount") self.field(code, "co_kwonlyargcount") + # The following should remain in sync with _PyFrame_NumSlotsForCodeObject + self.write(f".co_framesize = {code.co_stacksize + len(localsplusnames)} + FRAME_SPECIALS_SIZE,") self.field(code, "co_stacksize") self.field(code, "co_firstlineno") self.write(f".co_nlocalsplus = {len(localsplusnames)},") self.field(code, "co_nlocals") - self.write(f".co_nplaincellvars = {nplaincellvars},") self.write(f".co_ncellvars = {ncellvars},") self.write(f".co_nfreevars = {nfreevars},") + self.write(f".co_version = {next_code_version},") + next_code_version += 1 self.write(f".co_localsplusnames = {co_localsplusnames},") self.write(f".co_localspluskinds = {co_localspluskinds},") self.write(f".co_filename = {co_filename},") self.write(f".co_name = {co_name},") self.write(f".co_qualname = {co_qualname},") self.write(f".co_linetable = {co_linetable},") - self.write(f"._co_code = NULL,") - self.write("._co_linearray = NULL,") + self.write(f"._co_cached = NULL,") self.write(f".co_code_adaptive = {co_code_adaptive},") for i, op in enumerate(code.co_code[::2]): if op == RESUME: self.write(f"._co_firsttraceable = {i},") break name_as_code = f"(PyCodeObject *)&{name}" - self.deallocs.append(f"_PyStaticCode_Dealloc({name_as_code});") - self.interns.append(f"_PyStaticCode_InternStrings({name_as_code})") + self.finis.append(f"_PyStaticCode_Fini({name_as_code});") + self.inits.append(f"_PyStaticCode_Init({name_as_code})") return f"& {name}.ob_base.ob_base" def generate_tuple(self, name: str, t: Tuple[object, ...]) -> str: @@ -318,7 +313,7 @@ class Printer: return f"& {name}._object.ob_base.ob_base" def _generate_int_for_bits(self, name: str, i: int, digit: int) -> None: - sign = -1 if i < 0 else 0 if i == 0 else +1 + sign = (i > 0) - (i < 0) i = abs(i) digits: list[int] = [] while i: @@ -327,10 +322,12 @@ class Printer: self.write("static") with self.indent(): with self.block("struct"): - self.write("PyObject_VAR_HEAD") + self.write("PyObject ob_base;") + self.write("uintptr_t lv_tag;") self.write(f"digit ob_digit[{max(1, len(digits))}];") with self.block(f"{name} =", ";"): - self.object_var_head("PyLong_Type", sign*len(digits)) + self.object_head("PyLong_Type") + self.write(f".lv_tag = TAG_FROM_SIGN_AND_SIZE({sign}, {len(digits)}),") if digits: ds = ", ".join(map(str, digits)) self.write(f".ob_digit = {{ {ds} }},") @@ -354,7 +351,7 @@ class Printer: self.write('#error "PYLONG_BITS_IN_DIGIT should be 15 or 30"') self.write("#endif") # If neither clause applies, it won't compile - return f"& {name}.ob_base.ob_base" + return f"& {name}.ob_base" def generate_float(self, name: str, x: float) -> str: with self.block(f"static PyFloatObject {name} =", ";"): @@ -381,11 +378,7 @@ class Printer: def generate_file(self, module: str, code: object)-> None: module = module.replace(".", "_") self.generate(f"{module}_toplevel", code) - with self.block(f"static void {module}_do_patchups(void)"): - for p in self.patchups: - self.write(p) - self.patchups.clear() - self.write(EPILOGUE.replace("%%NAME%%", module)) + self.write(EPILOGUE.format(name=module)) def generate(self, name: str, obj: object) -> str: # Use repr() in the key to distinguish -0.0 from +0.0 @@ -429,11 +422,10 @@ class Printer: EPILOGUE = """ PyObject * -_Py_get_%%NAME%%_toplevel(void) -{ - %%NAME%%_do_patchups(); - return Py_NewRef((PyObject *) &%%NAME%%_toplevel); -} +_Py_get_{name}_toplevel(void) +{{ + return Py_NewRef((PyObject *) &{name}_toplevel); +}} """ FROZEN_COMMENT_C = "/* Auto-generated by Programs/_freeze_module.c */" @@ -469,13 +461,14 @@ def generate(args: list[str], output: TextIO) -> None: code = compile(fd.read(), f"<frozen {modname}>", "exec") printer.generate_file(modname, code) with printer.block(f"void\n_Py_Deepfreeze_Fini(void)"): - for p in printer.deallocs: + for p in printer.finis: printer.write(p) with printer.block(f"int\n_Py_Deepfreeze_Init(void)"): - for p in printer.interns: + for p in printer.inits: with printer.block(f"if ({p} < 0)"): printer.write("return -1;") printer.write("return 0;") + printer.write(f"\nuint32_t _Py_next_func_version = {next_code_version};\n") if verbose: print(f"Cache hits: {printer.hits}, misses: {printer.misses}") diff --git a/Tools/scripts/freeze_modules.py b/Tools/build/freeze_modules.py similarity index 98% rename from Tools/scripts/freeze_modules.py rename to Tools/build/freeze_modules.py index dd208c78..12200979 100644 --- a/Tools/scripts/freeze_modules.py +++ b/Tools/build/freeze_modules.py @@ -8,7 +8,6 @@ import hashlib import os import ntpath import posixpath -import sys import argparse from update_file import updating_file_with_tmpfile @@ -33,6 +32,9 @@ PCBUILD_PYTHONCORE = os.path.join(ROOT_DIR, 'PCbuild', 'pythoncore.vcxproj') OS_PATH = 'ntpath' if os.name == 'nt' else 'posixpath' # These are modules that get frozen. +# If you're debugging new bytecode instructions, +# you can delete all sections except 'import system'. +# This also speeds up building somewhat. TESTS_SECTION = 'Test module' FROZEN = [ # See parse_frozen_spec() for the format. @@ -46,6 +48,7 @@ FROZEN = [ # on a builtin zip file instead of a filesystem. 'zipimport', ]), + # (You can delete entries from here down to the end of the list.) ('stdlib - startup, without site (python -S)', [ 'abc', 'codecs', @@ -81,6 +84,7 @@ FROZEN = [ '<__phello__.**.*>', f'frozen_only : __hello_only__ = {FROZEN_ONLY}', ]), + # (End of stuff you could delete.) ] BOOTSTRAP = { 'importlib._bootstrap', @@ -521,7 +525,7 @@ def regen_frozen(modules, frozen_modules: bool): for lines in (bootstraplines, stdliblines, testlines): # TODO: Is this necessary any more? - if not lines[0]: + if lines and not lines[0]: del lines[0] for i, line in enumerate(lines): if line: @@ -581,8 +585,8 @@ def regen_makefile(modules): pyfiles = [] frozenfiles = [] rules = [''] - deepfreezerules = ["Python/deepfreeze/deepfreeze.c: $(DEEPFREEZE_DEPS)", - "\t$(PYTHON_FOR_FREEZE) $(srcdir)/Tools/scripts/deepfreeze.py \\"] + deepfreezerules = ["$(DEEPFREEZE_C): $(DEEPFREEZE_DEPS)", + "\t$(PYTHON_FOR_FREEZE) $(srcdir)/Tools/build/deepfreeze.py \\"] for src in _iter_sources(modules): frozen_header = relpath_for_posix_display(src.frozenfile, ROOT_DIR) frozenfiles.append(f'\t\t{frozen_header} \\') @@ -647,7 +651,7 @@ def regen_pcbuild(modules): projlines = [] filterlines = [] corelines = [] - deepfreezerules = ['\t<Exec Command=\'$(PythonForBuild) "$(PySourcePath)Tools\\scripts\\deepfreeze.py" ^'] + deepfreezerules = ['\t<Exec Command=\'$(PythonForBuild) "$(PySourcePath)Tools\\build\\deepfreeze.py" ^'] for src in _iter_sources(modules): pyfile = relpath_for_windows_display(src.pyfile, ROOT_DIR) header = relpath_for_windows_display(src.frozenfile, ROOT_DIR) diff --git a/Tools/scripts/generate_global_objects.py b/Tools/build/generate_global_objects.py similarity index 56% rename from Tools/scripts/generate_global_objects.py rename to Tools/build/generate_global_objects.py index 2180acd7..ded19ee4 100644 --- a/Tools/scripts/generate_global_objects.py +++ b/Tools/build/generate_global_objects.py @@ -3,6 +3,7 @@ import io import os.path import re +SCRIPT_NAME = 'Tools/build/generate_global_objects.py' __file__ = os.path.abspath(__file__) ROOT = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) INTERNAL = os.path.join(ROOT, 'Include', 'internal') @@ -14,6 +15,7 @@ IGNORED = { 'DUNDER', # Objects/typeobject.c 'RDUNDER', # Objects/typeobject.c 'SPECIAL', # Objects/weakrefobject.c + 'NAME', # Objects/typeobject.c } IDENTIFIERS = [ # from ADD() Python/_warnings.c @@ -42,11 +44,27 @@ IDENTIFIERS = [ # from SLOT* in Objects/typeobject.c '__abs__', '__add__', + '__aiter__', '__and__', - '__divmod__', + '__anext__', + '__await__', + '__bool__', + '__call__', + '__contains__', + '__del__', + '__delattr__', + '__delete__', + '__delitem__', + '__eq__', '__float__', '__floordiv__', + '__ge__', + '__get__', + '__getattr__', + '__getattribute__', '__getitem__', + '__gt__', + '__hash__', '__iadd__', '__iand__', '__ifloordiv__', @@ -54,24 +72,34 @@ IDENTIFIERS = [ '__imatmul__', '__imod__', '__imul__', + '__index__', + '__init__', '__int__', '__invert__', '__ior__', + '__ipow__', '__irshift__', '__isub__', + '__iter__', '__itruediv__', '__ixor__', + '__le__', + '__len__', '__lshift__', + '__lt__', '__matmul__', '__mod__', '__mul__', + '__ne__', '__neg__', + '__new__', + '__next__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', - '__rdivmod__', + '__repr__', '__rfloordiv__', '__rlshift__', '__rmatmul__', @@ -84,10 +112,26 @@ IDENTIFIERS = [ '__rsub__', '__rtruediv__', '__rxor__', + '__set__', + '__setattr__', + '__setitem__', '__str__', '__sub__', '__truediv__', '__xor__', + '__divmod__', + '__rdivmod__', + '__buffer__', + '__release_buffer__', +] + +NON_GENERATED_IMMORTAL_OBJECTS = [ + # The generated ones come from generate_runtime_init(). + '(PyObject *)&_Py_SINGLETON(bytes_empty)', + '(PyObject *)&_Py_SINGLETON(tuple_empty)', + '(PyObject *)&_Py_SINGLETON(hamt_bitmap_node_empty)', + '(PyObject *)&_Py_INTERP_SINGLETON(interp, hamt_empty)', + '(PyObject *)&_Py_SINGLETON(context_token_missing)', ] @@ -181,7 +225,7 @@ def open_for_changes(filename, orig): ####################################### # the global objects -START = '/* The following is auto-generated by Tools/scripts/generate_global_objects.py. */' +START = f'/* The following is auto-generated by {SCRIPT_NAME}. */' END = '/* End auto-generated code */' @@ -237,7 +281,97 @@ def generate_runtime_init(identifiers, strings): assert nsmallposints and nsmallnegints # Then target the runtime initializer. - filename = os.path.join(INTERNAL, 'pycore_runtime_init.h') + filename = os.path.join(INTERNAL, 'pycore_runtime_init_generated.h') + + # Read the non-generated part of the file. + with open(filename) as infile: + orig = infile.read() + lines = iter(orig.rstrip().splitlines()) + before = '\n'.join(iter_to_marker(lines, START)) + for _ in iter_to_marker(lines, END): + pass + after = '\n'.join(lines) + + # Generate the file. + with open_for_changes(filename, orig) as outfile: + immortal_objects = [] + printer = Printer(outfile) + printer.write(before) + printer.write(START) + with printer.block('#define _Py_small_ints_INIT', continuation=True): + for i in range(-nsmallnegints, nsmallposints): + printer.write(f'_PyLong_DIGIT_INIT({i}),') + immortal_objects.append(f'(PyObject *)&_Py_SINGLETON(small_ints)[_PY_NSMALLNEGINTS + {i}]') + printer.write('') + with printer.block('#define _Py_bytes_characters_INIT', continuation=True): + for i in range(256): + printer.write(f'_PyBytes_CHAR_INIT({i}),') + immortal_objects.append(f'(PyObject *)&_Py_SINGLETON(bytes_characters)[{i}]') + printer.write('') + with printer.block('#define _Py_str_literals_INIT', continuation=True): + for literal, name in sorted(strings.items(), key=lambda x: x[1]): + printer.write(f'INIT_STR({name}, "{literal}"),') + immortal_objects.append(f'(PyObject *)&_Py_STR({name})') + printer.write('') + with printer.block('#define _Py_str_identifiers_INIT', continuation=True): + for name in sorted(identifiers): + assert name.isidentifier(), name + printer.write(f'INIT_ID({name}),') + immortal_objects.append(f'(PyObject *)&_Py_ID({name})') + printer.write('') + with printer.block('#define _Py_str_ascii_INIT', continuation=True): + for i in range(128): + printer.write(f'_PyASCIIObject_INIT("\\x{i:02x}"),') + immortal_objects.append(f'(PyObject *)&_Py_SINGLETON(strings).ascii[{i}]') + printer.write('') + with printer.block('#define _Py_str_latin1_INIT', continuation=True): + for i in range(128, 256): + utf8 = ['"'] + for c in chr(i).encode('utf-8'): + utf8.append(f"\\x{c:02x}") + utf8.append('"') + printer.write(f'_PyUnicode_LATIN1_INIT("\\x{i:02x}", {"".join(utf8)}),') + immortal_objects.append(f'(PyObject *)&_Py_SINGLETON(strings).latin1[{i} - 128]') + printer.write(END) + printer.write(after) + return immortal_objects + + +def generate_static_strings_initializer(identifiers, strings): + # Target the runtime initializer. + filename = os.path.join(INTERNAL, 'pycore_unicodeobject_generated.h') + + # Read the non-generated part of the file. + with open(filename) as infile: + orig = infile.read() + lines = iter(orig.rstrip().splitlines()) + before = '\n'.join(iter_to_marker(lines, START)) + for _ in iter_to_marker(lines, END): + pass + after = '\n'.join(lines) + + # Generate the file. + with open_for_changes(filename, orig) as outfile: + printer = Printer(outfile) + printer.write(before) + printer.write(START) + printer.write("static inline void") + with printer.block("_PyUnicode_InitStaticStrings(PyInterpreterState *interp)"): + printer.write(f'PyObject *string;') + for i in sorted(identifiers): + # This use of _Py_ID() is ignored by iter_global_strings() + # since iter_files() ignores .h files. + printer.write(f'string = &_Py_ID({i});') + printer.write(f'assert(_PyUnicode_CheckConsistency(string, 1));') + printer.write(f'_PyUnicode_InternInPlace(interp, &string);') + # XXX What about "strings"? + printer.write(END) + printer.write(after) + + +def generate_global_object_finalizers(generated_immortal_objects): + # Target the runtime initializer. + filename = os.path.join(INTERNAL, 'pycore_global_objects_fini_generated.h') # Read the non-generated part of the file. with open(filename) as infile: @@ -253,37 +387,18 @@ def generate_runtime_init(identifiers, strings): printer = Printer(outfile) printer.write(before) printer.write(START) - with printer.block('#define _Py_global_objects_INIT', continuation=True): - with printer.block('.singletons =', ','): - # Global int objects. - with printer.block('.small_ints =', ','): - for i in range(-nsmallnegints, nsmallposints): - printer.write(f'_PyLong_DIGIT_INIT({i}),') - printer.write('') - # Global bytes objects. - printer.write('.bytes_empty = _PyBytes_SIMPLE_INIT(0, 0),') - with printer.block('.bytes_characters =', ','): - for i in range(256): - printer.write(f'_PyBytes_CHAR_INIT({i}),') - printer.write('') - # Global strings. - with printer.block('.strings =', ','): - with printer.block('.literals =', ','): - for literal, name in sorted(strings.items(), key=lambda x: x[1]): - printer.write(f'INIT_STR({name}, "{literal}"),') - with printer.block('.identifiers =', ','): - for name in sorted(identifiers): - assert name.isidentifier(), name - printer.write(f'INIT_ID({name}),') - with printer.block('.ascii =', ','): - for i in range(128): - printer.write(f'_PyASCIIObject_INIT("\\x{i:02x}"),') - with printer.block('.latin1 =', ','): - for i in range(128, 256): - printer.write(f'_PyUnicode_LATIN1_INIT("\\x{i:02x}"),') - printer.write('') - with printer.block('.tuple_empty =', ','): - printer.write('.ob_base = _PyVarObject_IMMORTAL_INIT(&PyTuple_Type, 0)') + printer.write('#ifdef Py_DEBUG') + printer.write("static inline void") + with printer.block( + "_PyStaticObjects_CheckRefcnt(PyInterpreterState *interp)"): + printer.write('/* generated runtime-global */') + printer.write('// (see pycore_runtime_init_generated.h)') + for ref in generated_immortal_objects: + printer.write(f'_PyStaticObject_CheckRefcnt({ref});') + printer.write('/* non-generated */') + for ref in NON_GENERATED_IMMORTAL_OBJECTS: + printer.write(f'_PyStaticObject_CheckRefcnt({ref});') + printer.write('#endif // Py_DEBUG') printer.write(END) printer.write(after) @@ -310,11 +425,10 @@ def main() -> None: identifiers, strings = get_identifiers_and_strings() generate_global_strings(identifiers, strings) - generate_runtime_init(identifiers, strings) + generated_immortal_objects = generate_runtime_init(identifiers, strings) + generate_static_strings_initializer(identifiers, strings) + generate_global_object_finalizers(generated_immortal_objects) if __name__ == '__main__': - import argparse - parser = argparse.ArgumentParser() - args = parser.parse_args() - main(**vars(args)) + main() diff --git a/Tools/build/generate_levenshtein_examples.py b/Tools/build/generate_levenshtein_examples.py new file mode 100644 index 00000000..778eb458 --- /dev/null +++ b/Tools/build/generate_levenshtein_examples.py @@ -0,0 +1,70 @@ +"""Generate 10,000 unique examples for the Levenshtein short-circuit tests.""" + +import argparse +from functools import lru_cache +import json +import os.path +from random import choices, randrange + + +# This should be in sync with Lib/traceback.py. It's not importing those values +# because this script is being executed by PYTHON_FOR_REGEN and not by the in-tree +# build of Python. +_MOVE_COST = 2 +_CASE_COST = 1 + + +def _substitution_cost(ch_a, ch_b): + if ch_a == ch_b: + return 0 + if ch_a.lower() == ch_b.lower(): + return _CASE_COST + return _MOVE_COST + + +@lru_cache(None) +def levenshtein(a, b): + if not a or not b: + return (len(a) + len(b)) * _MOVE_COST + option1 = levenshtein(a[:-1], b[:-1]) + _substitution_cost(a[-1], b[-1]) + option2 = levenshtein(a[:-1], b) + _MOVE_COST + option3 = levenshtein(a, b[:-1]) + _MOVE_COST + return min(option1, option2, option3) + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('output_path', metavar='FILE', type=str) + parser.add_argument('--overwrite', dest='overwrite', action='store_const', + const=True, default=False, + help='overwrite an existing test file') + + args = parser.parse_args() + output_path = os.path.realpath(args.output_path) + if not args.overwrite and os.path.isfile(output_path): + print(f"{output_path} already exists, skipping regeneration.") + print( + "To force, add --overwrite to the invocation of this tool or" + " delete the existing file." + ) + return + + examples = set() + # Create a lot of non-empty examples, which should end up with a Gauss-like + # distribution for even costs (moves) and odd costs (case substitutions). + while len(examples) < 9990: + a = ''.join(choices("abcABC", k=randrange(1, 10))) + b = ''.join(choices("abcABC", k=randrange(1, 10))) + expected = levenshtein(a, b) + examples.add((a, b, expected)) + # Create one empty case each for strings between 0 and 9 in length. + for i in range(10): + b = ''.join(choices("abcABC", k=i)) + expected = levenshtein("", b) + examples.add(("", b, expected)) + with open(output_path, "w") as f: + json.dump(sorted(examples), f, indent=2) + + +if __name__ == "__main__": + main() diff --git a/Tools/scripts/generate_opcode_h.py b/Tools/build/generate_opcode_h.py similarity index 54% rename from Tools/scripts/generate_opcode_h.py rename to Tools/build/generate_opcode_h.py index 5b225f27..5be98100 100644 --- a/Tools/scripts/generate_opcode_h.py +++ b/Tools/build/generate_opcode_h.py @@ -3,7 +3,7 @@ import sys import tokenize -SCRIPT_NAME = "Tools/scripts/generate_opcode_h.py" +SCRIPT_NAME = "Tools/build/generate_opcode_h.py" PYTHON_OPCODE = "Lib/opcode.py" header = f""" @@ -20,11 +20,8 @@ extern "C" {{ """.lstrip() footer = """ -#define HAS_ARG(op) ((op) >= HAVE_ARGUMENT) -/* Reserve some bytecodes for internal use in the compiler. - * The value of 240 is arbitrary. */ -#define IS_ARTIFICIAL(op) ((op) > 240) +#define IS_PSEUDO_OPCODE(op) (((op) >= MIN_PSEUDO_OPCODE) && ((op) <= MAX_PSEUDO_OPCODE)) #ifdef __cplusplus } @@ -55,6 +52,18 @@ internal_footer = """ #endif // !Py_INTERNAL_OPCODE_H """ +intrinsic_header = f""" +// Auto-generated by {SCRIPT_NAME} from {PYTHON_OPCODE} + +""".lstrip() + +intrinsic_footer = """ +typedef PyObject *(*instrinsic_func1)(PyThreadState* tstate, PyObject *value); +typedef PyObject *(*instrinsic_func2)(PyThreadState* tstate, PyObject *value1, PyObject *value2); +extern const instrinsic_func1 _PyIntrinsics_UnaryFunctions[]; +extern const instrinsic_func2 _PyIntrinsics_BinaryFunctions[]; +""" + DEFINE = "#define {:<38} {:>3}\n" UINT32_MASK = (1<<32)-1 @@ -63,14 +72,16 @@ def write_int_array_from_ops(name, ops, out): bits = 0 for op in ops: bits |= 1<<op - out.write(f"static const uint32_t {name}[8] = {{\n") - for i in range(8): + out.write(f"const uint32_t {name}[9] = {{\n") + for i in range(9): out.write(f" {bits & UINT32_MASK}U,\n") bits >>= 32 assert bits == 0 out.write(f"}};\n") -def main(opcode_py, outfile='Include/opcode.h', internaloutfile='Include/internal/pycore_opcode.h'): +def main(opcode_py, outfile='Include/opcode.h', + internaloutfile='Include/internal/pycore_opcode.h', + intrinsicoutfile='Include/internal/pycore_intrinsics.h'): opcode = {} if hasattr(tokenize, 'open'): fp = tokenize.open(opcode_py) # Python 3.2+ @@ -81,10 +92,21 @@ def main(opcode_py, outfile='Include/opcode.h', internaloutfile='Include/interna exec(code, opcode) opmap = opcode['opmap'] opname = opcode['opname'] + hasarg = opcode['hasarg'] hasconst = opcode['hasconst'] hasjrel = opcode['hasjrel'] hasjabs = opcode['hasjabs'] - used = [ False ] * 256 + is_pseudo = opcode['is_pseudo'] + _pseudo_ops = opcode['_pseudo_ops'] + + ENABLE_SPECIALIZATION = opcode["ENABLE_SPECIALIZATION"] + HAVE_ARGUMENT = opcode["HAVE_ARGUMENT"] + MIN_PSEUDO_OPCODE = opcode["MIN_PSEUDO_OPCODE"] + MAX_PSEUDO_OPCODE = opcode["MAX_PSEUDO_OPCODE"] + MIN_INSTRUMENTED_OPCODE = opcode["MIN_INSTRUMENTED_OPCODE"] + + NUM_OPCODES = len(opname) + used = [ False ] * len(opname) next_op = 1 for name, op in opmap.items(): @@ -98,27 +120,36 @@ def main(opcode_py, outfile='Include/opcode.h', internaloutfile='Include/interna specialized_opmap[name] = next_op opname_including_specialized[next_op] = name used[next_op] = True - specialized_opmap['DO_TRACING'] = 255 - opname_including_specialized[255] = 'DO_TRACING' - used[255] = True - with open(outfile, 'w') as fobj, open(internaloutfile, 'w') as iobj: + with open(outfile, 'w') as fobj, open(internaloutfile, 'w') as iobj, open( + intrinsicoutfile, "w") as nobj: fobj.write(header) iobj.write(internal_header) + nobj.write(intrinsic_header) for name in opname: if name in opmap: - fobj.write(DEFINE.format(name, opmap[name])) - if name == 'POP_EXCEPT': # Special entry for HAVE_ARGUMENT - fobj.write(DEFINE.format("HAVE_ARGUMENT", opcode["HAVE_ARGUMENT"])) + op = opmap[name] + if op == HAVE_ARGUMENT: + fobj.write(DEFINE.format("HAVE_ARGUMENT", HAVE_ARGUMENT)) + if op == MIN_PSEUDO_OPCODE: + fobj.write(DEFINE.format("MIN_PSEUDO_OPCODE", MIN_PSEUDO_OPCODE)) + if op == MIN_INSTRUMENTED_OPCODE: + fobj.write(DEFINE.format("MIN_INSTRUMENTED_OPCODE", MIN_INSTRUMENTED_OPCODE)) + + fobj.write(DEFINE.format(name, op)) + + if op == MAX_PSEUDO_OPCODE: + fobj.write(DEFINE.format("MAX_PSEUDO_OPCODE", MAX_PSEUDO_OPCODE)) + for name, op in specialized_opmap.items(): fobj.write(DEFINE.format(name, op)) + iobj.write("\nextern const uint32_t _PyOpcode_Jump[9];\n") iobj.write("\nextern const uint8_t _PyOpcode_Caches[256];\n") iobj.write("\nextern const uint8_t _PyOpcode_Deopt[256];\n") iobj.write("\n#ifdef NEED_OPCODE_TABLES\n") - write_int_array_from_ops("_PyOpcode_RelativeJump", opcode['hasjrel'], iobj) write_int_array_from_ops("_PyOpcode_Jump", opcode['hasjrel'] + opcode['hasjabs'], iobj) iobj.write("\nconst uint8_t _PyOpcode_Caches[256] = {\n") @@ -128,8 +159,9 @@ def main(opcode_py, outfile='Include/opcode.h', internaloutfile='Include/interna iobj.write("};\n") deoptcodes = {} - for basic in opmap: - deoptcodes[basic] = basic + for basic, op in opmap.items(): + if not is_pseudo(op): + deoptcodes[basic] = basic for basic, family in opcode["_specializations"].items(): for specialized in family: deoptcodes[specialized] = basic @@ -139,19 +171,46 @@ def main(opcode_py, outfile='Include/opcode.h', internaloutfile='Include/interna iobj.write("};\n") iobj.write("#endif // NEED_OPCODE_TABLES\n") + fobj.write("\n") + fobj.write("#define HAS_ARG(op) ((((op) >= HAVE_ARGUMENT) && (!IS_PSEUDO_OPCODE(op)))\\") + for op in _pseudo_ops: + if opmap[op] in hasarg: + fobj.write(f"\n || ((op) == {op}) \\") + fobj.write("\n )\n") + fobj.write("\n") fobj.write("#define HAS_CONST(op) (false\\") for op in hasconst: - fobj.write(f"\n || ((op) == {op}) \\") + fobj.write(f"\n || ((op) == {opname[op]}) \\") fobj.write("\n )\n") fobj.write("\n") for i, (op, _) in enumerate(opcode["_nb_ops"]): fobj.write(DEFINE.format(op, i)) + nobj.write("/* Unary Functions: */") + nobj.write("\n") + for i, op in enumerate(opcode["_intrinsic_1_descs"]): + nobj.write(DEFINE.format(op, i)) + nobj.write("\n") + nobj.write(DEFINE.format("MAX_INTRINSIC_1", i)) + + nobj.write("\n\n") + nobj.write("/* Binary Functions: */\n") + for i, op in enumerate(opcode["_intrinsic_2_descs"]): + nobj.write(DEFINE.format(op, i)) + nobj.write("\n") + nobj.write(DEFINE.format("MAX_INTRINSIC_2", i)) + + nobj.write(intrinsic_footer) + + fobj.write("\n") + fobj.write("/* Defined in Lib/opcode.py */\n") + fobj.write(f"#define ENABLE_SPECIALIZATION {int(ENABLE_SPECIALIZATION)}") + iobj.write("\n") iobj.write("#ifdef Py_DEBUG\n") - iobj.write("static const char *const _PyOpcode_OpName[256] = {\n") + iobj.write(f"static const char *const _PyOpcode_OpName[{NUM_OPCODES}] = {{\n") for op, name in enumerate(opname_including_specialized): if name[0] != "<": op = name @@ -174,4 +233,4 @@ def main(opcode_py, outfile='Include/opcode.h', internaloutfile='Include/interna if __name__ == '__main__': - main(sys.argv[1], sys.argv[2], sys.argv[3]) + main(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4]) diff --git a/Tools/scripts/generate_re_casefix.py b/Tools/build/generate_re_casefix.py similarity index 95% rename from Tools/scripts/generate_re_casefix.py rename to Tools/build/generate_re_casefix.py index 00b048b5..b57ac074 100755 --- a/Tools/scripts/generate_re_casefix.py +++ b/Tools/build/generate_re_casefix.py @@ -2,10 +2,11 @@ # This script generates Lib/re/_casefix.py. import collections -import re import sys import unicodedata +SCRIPT_NAME = 'Tools/build/generate_re_casefix.py' + def update_file(file, content): try: with open(file, 'r', encoding='utf-8') as fobj: @@ -17,8 +18,8 @@ def update_file(file, content): fobj.write(content) return True -re_casefix_template = """\ -# Auto-generated by Tools/scripts/generate_re_casefix.py. +re_casefix_template = f"""\ +# Auto-generated by {SCRIPT_NAME}. # Maps the code of lowercased character to codes of different lowercased # characters which have the same uppercase. diff --git a/Tools/scripts/generate_sre_constants.py b/Tools/build/generate_sre_constants.py similarity index 94% rename from Tools/scripts/generate_sre_constants.py rename to Tools/build/generate_sre_constants.py index 72715076..abea069c 100755 --- a/Tools/scripts/generate_sre_constants.py +++ b/Tools/build/generate_sre_constants.py @@ -1,6 +1,8 @@ #! /usr/bin/env python3 # This script generates Modules/_sre/sre_constants.h from Lib/re/_constants.py. +SCRIPT_NAME = 'Tools/build/generate_sre_constants.py' + def update_file(file, content): try: @@ -13,13 +15,13 @@ def update_file(file, content): fobj.write(content) return True -sre_constants_header = """\ +sre_constants_header = f"""\ /* * Secret Labs' Regular Expression Engine * * regular expression matching engine * - * Auto-generated by Tools/scripts/generate_sre_constants.py from + * Auto-generated by {SCRIPT_NAME} from * Lib/re/_constants.py. * * Copyright (c) 1997-2001 by Secret Labs AB. All rights reserved. diff --git a/Tools/scripts/generate_stdlib_module_names.py b/Tools/build/generate_stdlib_module_names.py similarity index 66% rename from Tools/scripts/generate_stdlib_module_names.py rename to Tools/build/generate_stdlib_module_names.py index 02d2710c..7e0e9602 100644 --- a/Tools/scripts/generate_stdlib_module_names.py +++ b/Tools/build/generate_stdlib_module_names.py @@ -1,5 +1,5 @@ # This script lists the names of standard library modules -# to update Python/stdlib_mod_names.h +# to update Python/stdlib_module_names.h import _imp import os.path import re @@ -7,11 +7,13 @@ import subprocess import sys import sysconfig +from check_extension_modules import ModuleChecker + + +SCRIPT_NAME = 'Tools/build/generate_stdlib_module_names.py' SRC_DIR = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) STDLIB_PATH = os.path.join(SRC_DIR, 'Lib') -MODULES_SETUP = os.path.join(SRC_DIR, 'Modules', 'Setup') -SETUP_PY = os.path.join(SRC_DIR, 'setup.py') IGNORE = { '__init__', @@ -32,34 +34,17 @@ IGNORE = { '_testimportmultiple', '_testinternalcapi', '_testmultiphase', + '_testsinglephase', '_xxsubinterpreters', + '_xxinterpchannels', '_xxtestfuzz', - 'distutils.tests', 'idlelib.idle_test', - 'lib2to3.tests', 'test', 'xxlimited', 'xxlimited_35', 'xxsubtype', } -# Windows extension modules -WINDOWS_MODULES = ( - '_msi', - '_overlapped', - '_testconsole', - '_winapi', - 'msvcrt', - 'nt', - 'winreg', - 'winsound' -) - -# macOS extension modules -MACOS_MODULES = ( - '_scproxy', -) - # Pure Python modules (Lib/*.py) def list_python_modules(names): for filename in os.listdir(STDLIB_PATH): @@ -82,37 +67,11 @@ def list_packages(names): names.add(name) -# Extension modules built by setup.py -def list_setup_extensions(names): - cmd = [sys.executable, SETUP_PY, "-q", "build", "--list-module-names"] - output = subprocess.check_output(cmd) - output = output.decode("utf8") - extensions = output.splitlines() - names |= set(extensions) - - -# Built-in and extension modules built by Modules/Setup +# Built-in and extension modules built by Modules/Setup* +# includes Windows and macOS extensions. def list_modules_setup_extensions(names): - assign_var = re.compile("^[A-Z]+=") - - with open(MODULES_SETUP, encoding="utf-8") as modules_fp: - for line in modules_fp: - # Strip comment - line = line.partition("#")[0] - line = line.rstrip() - if not line: - continue - if assign_var.match(line): - # Ignore "VAR=VALUE" - continue - if line in ("*disabled*", "*shared*"): - continue - parts = line.split() - if len(parts) < 2: - continue - # "errno errnomodule.c" => write "errno" - name = parts[0] - names.add(name) + checker = ModuleChecker() + names.update(checker.list_module_names(all=True)) # List frozen modules of the PyImport_FrozenModules list (Python/frozen.c). @@ -136,9 +95,8 @@ def list_frozen(names): def list_modules(): - names = set(sys.builtin_module_names) | set(WINDOWS_MODULES) | set(MACOS_MODULES) + names = set(sys.builtin_module_names) list_modules_setup_extensions(names) - list_setup_extensions(names) list_packages(names) list_python_modules(names) list_frozen(names) @@ -158,7 +116,7 @@ def list_modules(): def write_modules(fp, names): - print("// Auto-generated by Tools/scripts/generate_stdlib_module_names.py.", + print(f"// Auto-generated by {SCRIPT_NAME}.", file=fp) print("// List used to create sys.stdlib_module_names.", file=fp) print(file=fp) diff --git a/Tools/scripts/generate_token.py b/Tools/build/generate_token.py similarity index 85% rename from Tools/scripts/generate_token.py rename to Tools/build/generate_token.py index 77bb5bd5..3bd307c1 100755 --- a/Tools/scripts/generate_token.py +++ b/Tools/build/generate_token.py @@ -7,6 +7,8 @@ # Lib/token.py +SCRIPT_NAME = 'Tools/build/generate_token.py' +AUTO_GENERATED_BY_SCRIPT = f'Auto-generated by {SCRIPT_NAME}' NT_OFFSET = 256 def load_tokens(path): @@ -47,17 +49,22 @@ def update_file(file, content): return True -token_h_template = """\ -/* Auto-generated by Tools/scripts/generate_token.py */ +token_h_template = f"""\ +/* {AUTO_GENERATED_BY_SCRIPT} */ +""" +token_h_template += """\ /* Token types */ -#ifndef Py_LIMITED_API -#ifndef Py_TOKEN_H -#define Py_TOKEN_H +#ifndef Py_INTERNAL_TOKEN_H +#define Py_INTERNAL_TOKEN_H #ifdef __cplusplus extern "C" { #endif +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + #undef TILDE /* Prevent clash of our definition with system macro. Ex AIX, ioctl.h */ %s\ @@ -73,21 +80,23 @@ extern "C" { (x) == NEWLINE || \\ (x) == INDENT || \\ (x) == DEDENT) +#define ISSTRINGLIT(x) ((x) == STRING || \\ + (x) == FSTRING_MIDDLE) +// Symbols exported for test_peg_generator PyAPI_DATA(const char * const) _PyParser_TokenNames[]; /* Token names */ -PyAPI_FUNC(int) PyToken_OneChar(int); -PyAPI_FUNC(int) PyToken_TwoChars(int, int); -PyAPI_FUNC(int) PyToken_ThreeChars(int, int, int); +PyAPI_FUNC(int) _PyToken_OneChar(int); +PyAPI_FUNC(int) _PyToken_TwoChars(int, int); +PyAPI_FUNC(int) _PyToken_ThreeChars(int, int, int); #ifdef __cplusplus } #endif -#endif /* !Py_TOKEN_H */ -#endif /* Py_LIMITED_API */ +#endif // !Py_INTERNAL_TOKEN_H """ -def make_h(infile, outfile='Include/token.h'): +def make_h(infile, outfile='Include/internal/pycore_token.h'): tok_names, ERRORTOKEN, string_to_tok = load_tokens(infile) defines = [] @@ -102,11 +111,13 @@ def make_h(infile, outfile='Include/token.h'): print("%s regenerated from %s" % (outfile, infile)) -token_c_template = """\ -/* Auto-generated by Tools/scripts/generate_token.py */ +token_c_template = f"""\ +/* {AUTO_GENERATED_BY_SCRIPT} */ +""" +token_c_template += """\ #include "Python.h" -#include "token.h" +#include "pycore_token.h" /* Token names */ @@ -117,21 +128,21 @@ const char * const _PyParser_TokenNames[] = { /* Return the token corresponding to a single character */ int -PyToken_OneChar(int c1) +_PyToken_OneChar(int c1) { %s\ return OP; } int -PyToken_TwoChars(int c1, int c2) +_PyToken_TwoChars(int c1, int c2) { %s\ return OP; } int -PyToken_ThreeChars(int c1, int c2, int c3) +_PyToken_ThreeChars(int c1, int c2, int c3) { %s\ return OP; @@ -186,8 +197,8 @@ def make_c(infile, outfile='Parser/token.c'): print("%s regenerated from %s" % (outfile, infile)) -token_inc_template = """\ -.. Auto-generated by Tools/scripts/generate_token.py +token_inc_template = f"""\ +.. {AUTO_GENERATED_BY_SCRIPT} %s .. data:: N_TOKENS @@ -210,10 +221,11 @@ def make_rst(infile, outfile='Doc/library/token-list.inc'): print("%s regenerated from %s" % (outfile, infile)) -token_py_template = '''\ +token_py_template = f'''\ """Token constants.""" -# Auto-generated by Tools/scripts/generate_token.py - +# {AUTO_GENERATED_BY_SCRIPT} +''' +token_py_template += ''' __all__ = ['tok_name', 'ISTERMINAL', 'ISNONTERMINAL', 'ISEOF'] %s diff --git a/Tools/scripts/parse_html5_entities.py b/Tools/build/parse_html5_entities.py similarity index 79% rename from Tools/scripts/parse_html5_entities.py rename to Tools/build/parse_html5_entities.py index c011328b..d2bf2909 100755 --- a/Tools/scripts/parse_html5_entities.py +++ b/Tools/build/parse_html5_entities.py @@ -2,10 +2,14 @@ """ Utility for parsing HTML5 entity definitions available from: - http://dev.w3.org/html5/spec/entities.json + https://html.spec.whatwg.org/entities.json + https://html.spec.whatwg.org/multipage/named-characters.html -Written by Ezio Melotti and Iuliia Proskurnia. +The page now contains the following note: + + "This list is static and will not be expanded or changed in the future." +Written by Ezio Melotti and Iuliia Proskurnia. """ import os @@ -14,7 +18,10 @@ import json from urllib.request import urlopen from html.entities import html5 -entities_url = 'http://dev.w3.org/html5/spec/entities.json' +SCRIPT_NAME = 'Tools/build/parse_html5_entities.py' +PAGE_URL = 'https://html.spec.whatwg.org/multipage/named-characters.html' +ENTITIES_URL = 'https://html.spec.whatwg.org/entities.json' +HTML5_SECTION_START = '# HTML5 named character references' def get_json(url): """Download the json file from the url and returns a decoded object.""" @@ -62,9 +69,15 @@ def write_items(entities, file=sys.stdout): # be before their equivalent lowercase version. keys = sorted(entities.keys()) keys = sorted(keys, key=str.lower) + print(HTML5_SECTION_START, file=file) + print(f'# Generated by {SCRIPT_NAME}\n' + f'# from {ENTITIES_URL} and\n' + f'# {PAGE_URL}.\n' + f'# Map HTML5 named character references to the ' + f'equivalent Unicode character(s).', file=file) print('html5 = {', file=file) for name in keys: - print(' {!r}: {!a},'.format(name, entities[name]), file=file) + print(f' {name!r}: {entities[name]!a},', file=file) print('}', file=file) @@ -72,11 +85,8 @@ if __name__ == '__main__': # without args print a diff between html.entities.html5 and new_html5 # with --create print the new html5 dict # with --patch patch the Lib/html/entities.py file - new_html5 = create_dict(get_json(entities_url)) + new_html5 = create_dict(get_json(ENTITIES_URL)) if '--create' in sys.argv: - print('# map the HTML5 named character references to the ' - 'equivalent Unicode character(s)') - print('# Generated by {}. Do not edit manually.'.format(__file__)) write_items(new_html5) elif '--patch' in sys.argv: fname = 'Lib/html/entities.py' @@ -84,7 +94,7 @@ if __name__ == '__main__': with open(fname) as f1, open(temp_fname, 'w') as f2: skip = False for line in f1: - if line.startswith('html5 = {'): + if line.startswith(HTML5_SECTION_START): write_items(new_html5, file=f2) skip = True continue diff --git a/Tools/scripts/smelly.py b/Tools/build/smelly.py similarity index 100% rename from Tools/scripts/smelly.py rename to Tools/build/smelly.py diff --git a/Tools/scripts/stable_abi.py b/Tools/build/stable_abi.py old mode 100755 new mode 100644 similarity index 98% rename from Tools/scripts/stable_abi.py rename to Tools/build/stable_abi.py index f5a9f8d2..4cd1cd95 --- a/Tools/scripts/stable_abi.py +++ b/Tools/build/stable_abi.py @@ -16,7 +16,6 @@ import argparse import textwrap import tomllib import difflib -import shutil import pprint import sys import os @@ -25,6 +24,7 @@ import io import re import csv +SCRIPT_NAME = 'Tools/build/stable_abi.py' MISSING = object() EXCLUDED_HEADERS = { @@ -183,11 +183,12 @@ def generator(var_name, default_path): def gen_python3dll(manifest, args, outfile): """Generate/check the source for the Windows stable ABI library""" write = partial(print, file=outfile) - write(textwrap.dedent(r""" + content = f"""\ /* Re-export stable Python ABI */ - /* Generated by Tools/scripts/stable_abi.py */ - + /* Generated by {SCRIPT_NAME} */ + """ + content += r""" #ifdef _M_IX86 #define DECORATE "_" #else @@ -198,7 +199,8 @@ def gen_python3dll(manifest, args, outfile): __pragma(comment(linker, "/EXPORT:" DECORATE #name "=" PYTHON_DLL_NAME "." #name)) #define EXPORT_DATA(name) \ __pragma(comment(linker, "/EXPORT:" DECORATE #name "=" PYTHON_DLL_NAME "." #name ",DATA")) - """)) + """ + write(textwrap.dedent(content)) def sort_key(item): return item.name.lower() @@ -265,8 +267,8 @@ def gen_doc_annotations(manifest, args, outfile): def gen_ctypes_test(manifest, args, outfile): """Generate/check the ctypes-based test for exported symbols""" write = partial(print, file=outfile) - write(textwrap.dedent(''' - # Generated by Tools/scripts/stable_abi.py + write(textwrap.dedent(f'''\ + # Generated by {SCRIPT_NAME} """Test that all symbols of the Stable ABI are accessible using ctypes """ @@ -339,7 +341,7 @@ def gen_ctypes_test(manifest, args, outfile): def gen_testcapi_feature_macros(manifest, args, outfile): """Generate/check the stable ABI list for documentation annotations""" write = partial(print, file=outfile) - write('// Generated by Tools/scripts/stable_abi.py') + write(f'// Generated by {SCRIPT_NAME}') write() write('// Add an entry in dict `result` for each Stable ABI feature macro.') write() @@ -682,7 +684,8 @@ def main(): if args.all: run_all_generators = True - args.unixy_check = True + if UNIXY: + args.unixy_check = True try: file = args.file.open('rb') diff --git a/Tools/scripts/umarshal.py b/Tools/build/umarshal.py similarity index 98% rename from Tools/scripts/umarshal.py rename to Tools/build/umarshal.py index f61570cb..e05d93cf 100644 --- a/Tools/scripts/umarshal.py +++ b/Tools/build/umarshal.py @@ -125,10 +125,10 @@ class Reader: x |= buf[1] << 8 x |= buf[2] << 16 x |= buf[3] << 24 - x |= buf[1] << 32 - x |= buf[1] << 40 - x |= buf[1] << 48 - x |= buf[1] << 56 + x |= buf[4] << 32 + x |= buf[5] << 40 + x |= buf[6] << 48 + x |= buf[7] << 56 x |= -(x & (1<<63)) # Sign-extend return x diff --git a/Tools/scripts/update_file.py b/Tools/build/update_file.py similarity index 100% rename from Tools/scripts/update_file.py rename to Tools/build/update_file.py diff --git a/Tools/scripts/verify_ensurepip_wheels.py b/Tools/build/verify_ensurepip_wheels.py similarity index 87% rename from Tools/scripts/verify_ensurepip_wheels.py rename to Tools/build/verify_ensurepip_wheels.py index 044d1fd6..29897425 100755 --- a/Tools/scripts/verify_ensurepip_wheels.py +++ b/Tools/build/verify_ensurepip_wheels.py @@ -1,4 +1,4 @@ -#! /usr/bin/env python3 +#!/usr/bin/env python3 """ Compare checksums for wheels in :mod:`ensurepip` against the Cheeseshop. @@ -14,7 +14,7 @@ import re from pathlib import Path from urllib.request import urlopen -PACKAGE_NAMES = ("pip", "setuptools") +PACKAGE_NAMES = ("pip",) ENSURE_PIP_ROOT = Path(__file__).parent.parent.parent / "Lib/ensurepip" WHEEL_DIR = ENSURE_PIP_ROOT / "_bundled" ENSURE_PIP_INIT_PY_TEXT = (ENSURE_PIP_ROOT / "__init__.py").read_text(encoding="utf-8") @@ -35,11 +35,17 @@ def print_error(file_path: str, message: str) -> None: def verify_wheel(package_name: str) -> bool: # Find the package on disk - package_path = next(WHEEL_DIR.glob(f"{package_name}*.whl"), None) - if not package_path: - print_error("", f"Could not find a {package_name} wheel on disk.") + package_paths = list(WHEEL_DIR.glob(f"{package_name}*.whl")) + if len(package_paths) != 1: + if package_paths: + for p in package_paths: + print_error(p, f"Found more than one wheel for package {package_name}.") + else: + print_error("", f"Could not find a {package_name} wheel on disk.") return False + package_path = package_paths[0] + print(f"Verifying checksum for {package_path}.") # Find the version of the package used by ensurepip diff --git a/Tools/buildbot/build.bat b/Tools/buildbot/build.bat index 5e840cc7..9af511a8 100644 --- a/Tools/buildbot/build.bat +++ b/Tools/buildbot/build.bat @@ -1,17 +1,17 @@ -@rem Used by the buildbot "compile" step. - -@rem Clean up -call "%~dp0clean.bat" %* - -@rem If you need the buildbots to start fresh (such as when upgrading to -@rem a new version of an external library, especially Tcl/Tk): -@rem 1) uncomment the following line: - -@rem call "%~dp0..\..\PCbuild\get_externals.bat" --clean-only - -@rem 2) commit and push -@rem 3) wait for all Windows bots to start a build with that changeset -@rem 4) re-comment, commit and push again - -@rem Do the build -call "%~dp0..\..\PCbuild\build.bat" -e -d -k -v %* +@rem Used by the buildbot "compile" step. + +@rem Clean up +call "%~dp0clean.bat" %* + +@rem If you need the buildbots to start fresh (such as when upgrading to +@rem a new version of an external library, especially Tcl/Tk): +@rem 1) uncomment the following line: + +@rem call "%~dp0..\..\PCbuild\get_externals.bat" --clean-only + +@rem 2) commit and push +@rem 3) wait for all Windows bots to start a build with that changeset +@rem 4) re-comment, commit and push again + +@rem Do the build +call "%~dp0..\..\PCbuild\build.bat" -e -d -k -v %* diff --git a/Tools/buildbot/buildmsi.bat b/Tools/buildbot/buildmsi.bat index e3c2dbd7..6804d794 100644 --- a/Tools/buildbot/buildmsi.bat +++ b/Tools/buildbot/buildmsi.bat @@ -1,9 +1,9 @@ -@rem Used by the buildbot "buildmsi" step. -setlocal - -pushd - -@rem build both snapshot MSIs -call "%~dp0..\msi\build.bat" -x86 -x64 - +@rem Used by the buildbot "buildmsi" step. +setlocal + +pushd + +@rem build both snapshot MSIs +call "%~dp0..\msi\build.bat" -x86 -x64 + popd \ No newline at end of file diff --git a/Tools/buildbot/clean.bat b/Tools/buildbot/clean.bat index 13e66799..fe252a91 100644 --- a/Tools/buildbot/clean.bat +++ b/Tools/buildbot/clean.bat @@ -1,17 +1,17 @@ -@echo off -rem Used by the buildbot "clean" step. - -setlocal -set root=%~dp0..\.. -set pcbuild=%root%\PCbuild - -echo Deleting build -call "%pcbuild%\build.bat" -t Clean -k %* -call "%pcbuild%\build.bat" -t Clean -k -d %* - -echo Deleting .pyc/.pyo files ... -del /s "%root%\Lib\*.pyc" "%root%\Lib\*.pyo" - -echo Deleting test leftovers ... -rmdir /s /q "%root%\build" -del /s "%pcbuild%\python*.zip" +@echo off +rem Used by the buildbot "clean" step. + +setlocal +set root=%~dp0..\.. +set pcbuild=%root%\PCbuild + +echo Deleting build +call "%pcbuild%\build.bat" -t Clean -k %* +call "%pcbuild%\build.bat" -t Clean -k -d %* + +echo Deleting .pyc/.pyo files ... +del /s "%root%\Lib\*.pyc" "%root%\Lib\*.pyo" + +echo Deleting test leftovers ... +rmdir /s /q "%root%\build" +del /s "%pcbuild%\python*.zip" diff --git a/Tools/buildbot/remoteDeploy.bat b/Tools/buildbot/remoteDeploy.bat index 90354efe..31f15192 100644 --- a/Tools/buildbot/remoteDeploy.bat +++ b/Tools/buildbot/remoteDeploy.bat @@ -1,60 +1,60 @@ -@echo off -rem Used by the buildbot "remotedeploy" step. -setlocal - -set PATH=%PATH%;%SystemRoot%\SysNative\OpenSSH;%SystemRoot%\System32\OpenSSH -set here=%~dp0 -set arm32_ssh= - -:CheckOpts -if "%1"=="-arm32" (set arm32_ssh=true) & shift & goto CheckOpts -if NOT "%1"=="" (echo unrecognized option %1) & goto Arm32SshHelp - -if "%arm32_ssh%"=="true" goto :Arm32Ssh - -:Arm32Ssh -if "%SSH_SERVER%"=="" goto :Arm32SshHelp - -ssh %SSH_SERVER% echo Make sure we can find SSH and SSH_SERVER variable is valid -if %ERRORLEVEL% NEQ 0 (echo SSH does not work) & exit /b %ERRORLEVEL% - -if "%PYTHON_SOURCE%"=="" (set PYTHON_SOURCE=%here%..\..\) -if "%REMOTE_PYTHON_DIR%"=="" (set REMOTE_PYTHON_DIR=C:\python\) -if NOT "%REMOTE_PYTHON_DIR:~-1,1%"=="\" (set REMOTE_PYTHON_DIR=%REMOTE_PYTHON_DIR%\) -echo PYTHON_SOURCE = %PYTHON_SOURCE% -echo REMOTE_PYTHON_DIR = %REMOTE_PYTHON_DIR% - -REM stop Python processes and remove existing files if found -ssh %SSH_SERVER% "kill python.exe" -ssh %SSH_SERVER% "kill python_d.exe" -ssh %SSH_SERVER% "if EXIST %REMOTE_PYTHON_DIR% (rd %REMOTE_PYTHON_DIR% /s/q)" - -REM Create Python directories -ssh %SSH_SERVER% "md %REMOTE_PYTHON_DIR%PCBuild\arm32" -ssh %SSH_SERVER% "md %REMOTE_PYTHON_DIR%temp" -ssh %SSH_SERVER% "md %REMOTE_PYTHON_DIR%Modules" -ssh %SSH_SERVER% "md %REMOTE_PYTHON_DIR%PC" - -REM Copy Python files -for /f "USEBACKQ" %%i in (`dir PCbuild\*.bat /b`) do @scp PCBuild\%%i "%SSH_SERVER%:%REMOTE_PYTHON_DIR%PCBuild" -for /f "USEBACKQ" %%i in (`dir PCbuild\*.py /b`) do @scp PCBuild\%%i "%SSH_SERVER%:%REMOTE_PYTHON_DIR%PCBuild" -for /f "USEBACKQ" %%i in (`dir PCbuild\arm32\*.exe /b`) do @scp PCBuild\arm32\%%i "%SSH_SERVER%:%REMOTE_PYTHON_DIR%PCBuild\arm32" -for /f "USEBACKQ" %%i in (`dir PCbuild\arm32\*.pyd /b`) do @scp PCBuild\arm32\%%i "%SSH_SERVER%:%REMOTE_PYTHON_DIR%PCBuild\arm32" -for /f "USEBACKQ" %%i in (`dir PCbuild\arm32\*.dll /b`) do @scp PCBuild\arm32\%%i "%SSH_SERVER%:%REMOTE_PYTHON_DIR%PCBuild\arm32" -scp -r "%PYTHON_SOURCE%Include" "%SSH_SERVER%:%REMOTE_PYTHON_DIR%Include" -scp -r "%PYTHON_SOURCE%Lib" "%SSH_SERVER%:%REMOTE_PYTHON_DIR%Lib" -scp -r "%PYTHON_SOURCE%Parser" "%SSH_SERVER%:%REMOTE_PYTHON_DIR%Parser" -scp -r "%PYTHON_SOURCE%Tools" "%SSH_SERVER%:%REMOTE_PYTHON_DIR%Tools" -scp "%PYTHON_SOURCE%Modules\Setup" "%SSH_SERVER%:%REMOTE_PYTHON_DIR%Modules" -scp "%PYTHON_SOURCE%PC\pyconfig.h" "%SSH_SERVER%:%REMOTE_PYTHON_DIR%PC" - -exit /b %ERRORLEVEL% - -:Arm32SshHelp -echo SSH_SERVER environment variable must be set to administrator@[ip address] -echo where [ip address] is the address of a Windows IoT Core ARM32 device. -echo. -echo The test worker should have the SSH agent running. -echo Also a key must be created with ssh-keygen and added to both the buildbot worker machine -echo and the ARM32 worker device: see https://docs.microsoft.com/en-us/windows/iot-core/connect-your-device/ssh -exit /b 127 +@echo off +rem Used by the buildbot "remotedeploy" step. +setlocal + +set PATH=%PATH%;%SystemRoot%\SysNative\OpenSSH;%SystemRoot%\System32\OpenSSH +set here=%~dp0 +set arm32_ssh= + +:CheckOpts +if "%1"=="-arm32" (set arm32_ssh=true) & shift & goto CheckOpts +if NOT "%1"=="" (echo unrecognized option %1) & goto Arm32SshHelp + +if "%arm32_ssh%"=="true" goto :Arm32Ssh + +:Arm32Ssh +if "%SSH_SERVER%"=="" goto :Arm32SshHelp + +ssh %SSH_SERVER% echo Make sure we can find SSH and SSH_SERVER variable is valid +if %ERRORLEVEL% NEQ 0 (echo SSH does not work) & exit /b %ERRORLEVEL% + +if "%PYTHON_SOURCE%"=="" (set PYTHON_SOURCE=%here%..\..\) +if "%REMOTE_PYTHON_DIR%"=="" (set REMOTE_PYTHON_DIR=C:\python\) +if NOT "%REMOTE_PYTHON_DIR:~-1,1%"=="\" (set REMOTE_PYTHON_DIR=%REMOTE_PYTHON_DIR%\) +echo PYTHON_SOURCE = %PYTHON_SOURCE% +echo REMOTE_PYTHON_DIR = %REMOTE_PYTHON_DIR% + +REM stop Python processes and remove existing files if found +ssh %SSH_SERVER% "kill python.exe" +ssh %SSH_SERVER% "kill python_d.exe" +ssh %SSH_SERVER% "if EXIST %REMOTE_PYTHON_DIR% (rd %REMOTE_PYTHON_DIR% /s/q)" + +REM Create Python directories +ssh %SSH_SERVER% "md %REMOTE_PYTHON_DIR%PCBuild\arm32" +ssh %SSH_SERVER% "md %REMOTE_PYTHON_DIR%temp" +ssh %SSH_SERVER% "md %REMOTE_PYTHON_DIR%Modules" +ssh %SSH_SERVER% "md %REMOTE_PYTHON_DIR%PC" + +REM Copy Python files +for /f "USEBACKQ" %%i in (`dir PCbuild\*.bat /b`) do @scp PCBuild\%%i "%SSH_SERVER%:%REMOTE_PYTHON_DIR%PCBuild" +for /f "USEBACKQ" %%i in (`dir PCbuild\*.py /b`) do @scp PCBuild\%%i "%SSH_SERVER%:%REMOTE_PYTHON_DIR%PCBuild" +for /f "USEBACKQ" %%i in (`dir PCbuild\arm32\*.exe /b`) do @scp PCBuild\arm32\%%i "%SSH_SERVER%:%REMOTE_PYTHON_DIR%PCBuild\arm32" +for /f "USEBACKQ" %%i in (`dir PCbuild\arm32\*.pyd /b`) do @scp PCBuild\arm32\%%i "%SSH_SERVER%:%REMOTE_PYTHON_DIR%PCBuild\arm32" +for /f "USEBACKQ" %%i in (`dir PCbuild\arm32\*.dll /b`) do @scp PCBuild\arm32\%%i "%SSH_SERVER%:%REMOTE_PYTHON_DIR%PCBuild\arm32" +scp -r "%PYTHON_SOURCE%Include" "%SSH_SERVER%:%REMOTE_PYTHON_DIR%Include" +scp -r "%PYTHON_SOURCE%Lib" "%SSH_SERVER%:%REMOTE_PYTHON_DIR%Lib" +scp -r "%PYTHON_SOURCE%Parser" "%SSH_SERVER%:%REMOTE_PYTHON_DIR%Parser" +scp -r "%PYTHON_SOURCE%Tools" "%SSH_SERVER%:%REMOTE_PYTHON_DIR%Tools" +scp "%PYTHON_SOURCE%Modules\Setup" "%SSH_SERVER%:%REMOTE_PYTHON_DIR%Modules" +scp "%PYTHON_SOURCE%PC\pyconfig.h" "%SSH_SERVER%:%REMOTE_PYTHON_DIR%PC" + +exit /b %ERRORLEVEL% + +:Arm32SshHelp +echo SSH_SERVER environment variable must be set to administrator@[ip address] +echo where [ip address] is the address of a Windows IoT Core ARM32 device. +echo. +echo The test worker should have the SSH agent running. +echo Also a key must be created with ssh-keygen and added to both the buildbot worker machine +echo and the ARM32 worker device: see https://docs.microsoft.com/en-us/windows/iot-core/connect-your-device/ssh +exit /b 127 diff --git a/Tools/buildbot/remotePythonInfo.bat b/Tools/buildbot/remotePythonInfo.bat index 570e5e32..b17717cb 100644 --- a/Tools/buildbot/remotePythonInfo.bat +++ b/Tools/buildbot/remotePythonInfo.bat @@ -1,35 +1,35 @@ -@echo off -rem Used by the buildbot "remotedeploy" step. -setlocal - -set PATH=%PATH%;%SystemRoot%\SysNative\OpenSSH;%SystemRoot%\System32\OpenSSH -set here=%~dp0 -set arm32_ssh= -set suffix=_d -if "%REMOTE_PYTHON_DIR%"=="" (set REMOTE_PYTHON_DIR=C:\python\) -if NOT "%REMOTE_PYTHON_DIR:~-1,1%"=="\" (set REMOTE_PYTHON_DIR=%REMOTE_PYTHON_DIR%\) - -:CheckOpts -if "%1"=="-arm32" (set arm32_ssh=true) & (set prefix=%REMOTE_PYTHON_DIR%pcbuild\arm32) & shift & goto CheckOpts -if "%1"=="-d" (set suffix=_d) & shift & goto CheckOpts -if "%1"=="+d" (set suffix=) & shift & goto CheckOpts -if NOT "%1"=="" (echo unrecognized option %1) & goto Arm32SshHelp - -if "%arm32_ssh%"=="true" goto :Arm32Ssh - -:Arm32Ssh -if "%SSH_SERVER%"=="" goto :Arm32SshHelp - -set PYTHON_EXE=%prefix%\python%suffix%.exe -echo on -ssh %SSH_SERVER% %PYTHON_EXE% -m test.pythoninfo -exit /b %ERRORLEVEL% - -:Arm32SshHelp -echo SSH_SERVER environment variable must be set to administrator@[ip address] -echo where [ip address] is the address of a Windows IoT Core ARM32 device. -echo. -echo The test worker should have the SSH agent running. -echo Also a key must be created with ssh-keygen and added to both the buildbot worker machine -echo and the ARM32 worker device: see https://docs.microsoft.com/en-us/windows/iot-core/connect-your-device/ssh -exit /b 127 +@echo off +rem Used by the buildbot "remotedeploy" step. +setlocal + +set PATH=%PATH%;%SystemRoot%\SysNative\OpenSSH;%SystemRoot%\System32\OpenSSH +set here=%~dp0 +set arm32_ssh= +set suffix=_d +if "%REMOTE_PYTHON_DIR%"=="" (set REMOTE_PYTHON_DIR=C:\python\) +if NOT "%REMOTE_PYTHON_DIR:~-1,1%"=="\" (set REMOTE_PYTHON_DIR=%REMOTE_PYTHON_DIR%\) + +:CheckOpts +if "%1"=="-arm32" (set arm32_ssh=true) & (set prefix=%REMOTE_PYTHON_DIR%pcbuild\arm32) & shift & goto CheckOpts +if "%1"=="-d" (set suffix=_d) & shift & goto CheckOpts +if "%1"=="+d" (set suffix=) & shift & goto CheckOpts +if NOT "%1"=="" (echo unrecognized option %1) & goto Arm32SshHelp + +if "%arm32_ssh%"=="true" goto :Arm32Ssh + +:Arm32Ssh +if "%SSH_SERVER%"=="" goto :Arm32SshHelp + +set PYTHON_EXE=%prefix%\python%suffix%.exe +echo on +ssh %SSH_SERVER% %PYTHON_EXE% -m test.pythoninfo +exit /b %ERRORLEVEL% + +:Arm32SshHelp +echo SSH_SERVER environment variable must be set to administrator@[ip address] +echo where [ip address] is the address of a Windows IoT Core ARM32 device. +echo. +echo The test worker should have the SSH agent running. +echo Also a key must be created with ssh-keygen and added to both the buildbot worker machine +echo and the ARM32 worker device: see https://docs.microsoft.com/en-us/windows/iot-core/connect-your-device/ssh +exit /b 127 diff --git a/Tools/buildbot/test.bat b/Tools/buildbot/test.bat index af917713..25c796a6 100644 --- a/Tools/buildbot/test.bat +++ b/Tools/buildbot/test.bat @@ -1,51 +1,51 @@ -@echo off -rem Used by the buildbot "test" step. -setlocal - -set PATH=%PATH%;%SystemRoot%\SysNative\OpenSSH;%SystemRoot%\System32\OpenSSH -set here=%~dp0 -set rt_opts=-q -d -set regrtest_args=-j1 -set arm32_ssh= - -:CheckOpts -if "%1"=="-x64" (set rt_opts=%rt_opts% %1) & shift & goto CheckOpts -if "%1"=="-arm64" (set rt_opts=%rt_opts% %1) & shift & goto CheckOpts -if "%1"=="-arm32" (set rt_opts=%rt_opts% %1) & (set arm32_ssh=true) & shift & goto CheckOpts -if "%1"=="-d" (set rt_opts=%rt_opts% %1) & shift & goto CheckOpts -if "%1"=="-O" (set rt_opts=%rt_opts% %1) & shift & goto CheckOpts -if "%1"=="-q" (set rt_opts=%rt_opts% %1) & shift & goto CheckOpts -if "%1"=="+d" (set rt_opts=%rt_opts:-d=%) & shift & goto CheckOpts -if "%1"=="+q" (set rt_opts=%rt_opts:-q=%) & shift & goto CheckOpts -if NOT "%1"=="" (set regrtest_args=%regrtest_args% %1) & shift & goto CheckOpts - -if "%PROCESSOR_ARCHITECTURE%"=="ARM" if "%arm32_ssh%"=="true" goto NativeExecution -if "%arm32_ssh%"=="true" goto :Arm32Ssh - -:NativeExecution -call "%here%..\..\PCbuild\rt.bat" %rt_opts% -uall -rwW --slowest --timeout=1200 --fail-env-changed %regrtest_args% -exit /b %ERRORLEVEL% - -:Arm32Ssh -set dashU=-unetwork -udecimal -usubprocess -uurlfetch -utzdata -if "%SSH_SERVER%"=="" goto :Arm32SshHelp -if "%PYTHON_SOURCE%"=="" (set PYTHON_SOURCE=%here%..\..\) -if "%REMOTE_PYTHON_DIR%"=="" (set REMOTE_PYTHON_DIR=C:\python\) -if NOT "%REMOTE_PYTHON_DIR:~-1,1%"=="\" (set REMOTE_PYTHON_DIR=%REMOTE_PYTHON_DIR%\) - -set TEMP_ARGS=--temp %REMOTE_PYTHON_DIR%temp - -set rt_args=%rt_opts% %dashU% -rwW --slowest --timeout=1200 --fail-env-changed %regrtest_args% %TEMP_ARGS% -ssh %SSH_SERVER% "set TEMP=%REMOTE_PYTHON_DIR%temp& cd %REMOTE_PYTHON_DIR% & %REMOTE_PYTHON_DIR%PCbuild\rt.bat" %rt_args% -set ERR=%ERRORLEVEL% -scp %SSH_SERVER%:"%REMOTE_PYTHON_DIR%test-results.xml" "%PYTHON_SOURCE%\test-results.xml" -exit /b %ERR% - -:Arm32SshHelp -echo SSH_SERVER environment variable must be set to administrator@[ip address] -echo where [ip address] is the address of a Windows IoT Core ARM32 device. -echo. -echo The test worker should have the SSH agent running. -echo Also a key must be created with ssh-keygen and added to both the buildbot worker machine -echo and the ARM32 worker device: see https://docs.microsoft.com/en-us/windows/iot-core/connect-your-device/ssh -exit /b 127 +@echo off +rem Used by the buildbot "test" step. +setlocal + +set PATH=%PATH%;%SystemRoot%\SysNative\OpenSSH;%SystemRoot%\System32\OpenSSH +set here=%~dp0 +set rt_opts=-q -d +set regrtest_args=-j1 +set arm32_ssh= + +:CheckOpts +if "%1"=="-x64" (set rt_opts=%rt_opts% %1) & shift & goto CheckOpts +if "%1"=="-arm64" (set rt_opts=%rt_opts% %1) & shift & goto CheckOpts +if "%1"=="-arm32" (set rt_opts=%rt_opts% %1) & (set arm32_ssh=true) & shift & goto CheckOpts +if "%1"=="-d" (set rt_opts=%rt_opts% %1) & shift & goto CheckOpts +if "%1"=="-O" (set rt_opts=%rt_opts% %1) & shift & goto CheckOpts +if "%1"=="-q" (set rt_opts=%rt_opts% %1) & shift & goto CheckOpts +if "%1"=="+d" (set rt_opts=%rt_opts:-d=%) & shift & goto CheckOpts +if "%1"=="+q" (set rt_opts=%rt_opts:-q=%) & shift & goto CheckOpts +if NOT "%1"=="" (set regrtest_args=%regrtest_args% %1) & shift & goto CheckOpts + +if "%PROCESSOR_ARCHITECTURE%"=="ARM" if "%arm32_ssh%"=="true" goto NativeExecution +if "%arm32_ssh%"=="true" goto :Arm32Ssh + +:NativeExecution +call "%here%..\..\PCbuild\rt.bat" %rt_opts% -uall -rwW --slowest --timeout=1200 --fail-env-changed %regrtest_args% +exit /b %ERRORLEVEL% + +:Arm32Ssh +set dashU=-unetwork -udecimal -usubprocess -uurlfetch -utzdata +if "%SSH_SERVER%"=="" goto :Arm32SshHelp +if "%PYTHON_SOURCE%"=="" (set PYTHON_SOURCE=%here%..\..\) +if "%REMOTE_PYTHON_DIR%"=="" (set REMOTE_PYTHON_DIR=C:\python\) +if NOT "%REMOTE_PYTHON_DIR:~-1,1%"=="\" (set REMOTE_PYTHON_DIR=%REMOTE_PYTHON_DIR%\) + +set TEMP_ARGS=--temp %REMOTE_PYTHON_DIR%temp + +set rt_args=%rt_opts% %dashU% -rwW --slowest --timeout=1200 --fail-env-changed %regrtest_args% %TEMP_ARGS% +ssh %SSH_SERVER% "set TEMP=%REMOTE_PYTHON_DIR%temp& cd %REMOTE_PYTHON_DIR% & %REMOTE_PYTHON_DIR%PCbuild\rt.bat" %rt_args% +set ERR=%ERRORLEVEL% +scp %SSH_SERVER%:"%REMOTE_PYTHON_DIR%test-results.xml" "%PYTHON_SOURCE%\test-results.xml" +exit /b %ERR% + +:Arm32SshHelp +echo SSH_SERVER environment variable must be set to administrator@[ip address] +echo where [ip address] is the address of a Windows IoT Core ARM32 device. +echo. +echo The test worker should have the SSH agent running. +echo Also a key must be created with ssh-keygen and added to both the buildbot worker machine +echo and the ARM32 worker device: see https://docs.microsoft.com/en-us/windows/iot-core/connect-your-device/ssh +exit /b 127 diff --git a/Tools/c-analyzer/TODO b/Tools/c-analyzer/TODO index 43760369..27a53581 100644 --- a/Tools/c-analyzer/TODO +++ b/Tools/c-analyzer/TODO @@ -495,7 +495,6 @@ Python/import.c:PyImport_ImportModuleLevelObject():PyId___path__ _Py_IDENTIFIER( Python/import.c:PyImport_ImportModuleLevelObject():PyId___spec__ _Py_IDENTIFIER(__spec__) Python/import.c:PyImport_ImportModuleLevelObject():PyId__handle_fromlist _Py_IDENTIFIER(_handle_fromlist) Python/import.c:PyImport_ImportModuleLevelObject():PyId__lock_unlock_module _Py_IDENTIFIER(_lock_unlock_module) -Python/import.c:PyImport_ReloadModule():PyId_imp _Py_IDENTIFIER(imp) Python/import.c:PyImport_ReloadModule():PyId_reload _Py_IDENTIFIER(reload) Python/import.c:_PyImportZip_Init():PyId_zipimporter _Py_IDENTIFIER(zipimporter) Python/import.c:import_find_and_load():PyId__find_and_load _Py_IDENTIFIER(_find_and_load) diff --git a/Tools/c-analyzer/c_analyzer/__main__.py b/Tools/c-analyzer/c_analyzer/__main__.py index 5d89b29a..cde39bc4 100644 --- a/Tools/c-analyzer/c_analyzer/__main__.py +++ b/Tools/c-analyzer/c_analyzer/__main__.py @@ -18,10 +18,8 @@ from c_common.scriptutil import ( configure_logger, get_prog, filter_filenames, - iter_marks, ) from c_parser.info import KIND -from c_parser.match import is_type_decl from .match import filter_forward from . import ( analyze as _analyze, diff --git a/Tools/c-analyzer/c_analyzer/info.py b/Tools/c-analyzer/c_analyzer/info.py index 27c3a5a4..d231e07a 100644 --- a/Tools/c-analyzer/c_analyzer/info.py +++ b/Tools/c-analyzer/c_analyzer/info.py @@ -1,4 +1,3 @@ -from collections import namedtuple import os.path from c_common import fsutil @@ -13,9 +12,6 @@ from c_parser.info import ( from c_parser.match import ( is_type_decl, ) -from .match import ( - is_process_global, -) IGNORED = _misc.Labeled('IGNORED') diff --git a/Tools/c-analyzer/c_common/fsutil.py b/Tools/c-analyzer/c_common/fsutil.py index 120a1402..a8cf8d05 100644 --- a/Tools/c-analyzer/c_common/fsutil.py +++ b/Tools/c-analyzer/c_common/fsutil.py @@ -104,6 +104,25 @@ def format_filename(filename, relroot=USE_CWD, *, return filename +def match_path_tail(path1, path2): + """Return True if one path ends the other.""" + if path1 == path2: + return True + if os.path.isabs(path1): + if os.path.isabs(path2): + return False + return _match_tail(path1, path2) + elif os.path.isabs(path2): + return _match_tail(path2, path1) + else: + return _match_tail(path1, path2) or _match_tail(path2, path1) + + +def _match_tail(path, tail): + assert not os.path.isabs(tail), repr(tail) + return path.endswith(os.path.sep + tail) + + ################################## # find files diff --git a/Tools/c-analyzer/c_common/info.py b/Tools/c-analyzer/c_common/info.py deleted file mode 100644 index e69de29b..00000000 diff --git a/Tools/c-analyzer/c_common/iterutil.py b/Tools/c-analyzer/c_common/iterutil.py index 6ded1053..dda3dd57 100644 --- a/Tools/c-analyzer/c_common/iterutil.py +++ b/Tools/c-analyzer/c_common/iterutil.py @@ -1,7 +1,3 @@ - -_NOT_SET = object() - - def peek_and_iter(items): if not items: return None, None diff --git a/Tools/c-analyzer/c_common/show.py b/Tools/c-analyzer/c_common/show.py deleted file mode 100644 index e69de29b..00000000 diff --git a/Tools/c-analyzer/c_common/tables.py b/Tools/c-analyzer/c_common/tables.py index 130be6be..fe8e8cf4 100644 --- a/Tools/c-analyzer/c_common/tables.py +++ b/Tools/c-analyzer/c_common/tables.py @@ -1,3 +1,4 @@ +from collections import namedtuple import csv import re import textwrap @@ -225,7 +226,11 @@ WIDTH = 20 def resolve_columns(specs): if isinstance(specs, str): specs = specs.replace(',', ' ').strip().split() - return _resolve_colspecs(specs) + resolved = [] + for raw in specs: + column = ColumnSpec.from_raw(raw) + resolved.append(column) + return resolved def build_table(specs, *, sep=' ', defaultwidth=None): @@ -233,37 +238,145 @@ def build_table(specs, *, sep=' ', defaultwidth=None): return _build_table(columns, sep=sep, defaultwidth=defaultwidth) -_COLSPEC_RE = re.compile(textwrap.dedent(r''' - ^ - (?: - \[ - ( - (?: [^\s\]] [^\]]* )? - [^\s\]] - ) # <label> - ] - )? - ( \w+ ) # <field> - (?: +class ColumnSpec(namedtuple('ColumnSpec', 'field label fmt')): + + REGEX = re.compile(textwrap.dedent(r''' + ^ (?: - : - ( [<^>] ) # <align> - ( \d+ ) # <width1> - ) - | + \[ + ( + (?: [^\s\]] [^\]]* )? + [^\s\]] + ) # <label> + ] + )? + ( [-\w]+ ) # <field> (?: (?: : - ( \d+ ) # <width2> - )? + ( [<^>] ) # <align> + ( \d+ )? # <width1> + ) + | (?: - : - ( .*? ) # <fmt> - )? - ) - )? - $ -'''), re.VERBOSE) + (?: + : + ( \d+ ) # <width2> + )? + (?: + : + ( .*? ) # <fmt> + )? + ) + )? + $ + '''), re.VERBOSE) + + @classmethod + def from_raw(cls, raw): + if not raw: + raise ValueError('missing column spec') + elif isinstance(raw, cls): + return raw + + if isinstance(raw, str): + *values, _ = cls._parse(raw) + else: + *values, _ = cls._normalize(raw) + if values is None: + raise ValueError(f'unsupported column spec {raw!r}') + return cls(*values) + + @classmethod + def parse(cls, specstr): + parsed = cls._parse(specstr) + if not parsed: + return None + *values, _ = parsed + return cls(*values) + + @classmethod + def _parse(cls, specstr): + m = cls.REGEX.match(specstr) + if not m: + return None + (label, field, + align, width1, + width2, fmt, + ) = m.groups() + if not label: + label = field + if fmt: + assert not align and not width1, (specstr,) + _parsed = _parse_fmt(fmt) + if not _parsed: + raise NotImplementedError + elif width2: + width, _ = _parsed + if width != int(width2): + raise NotImplementedError(specstr) + elif width2: + fmt = width2 + width = int(width2) + else: + assert not fmt, (fmt, specstr) + if align: + width = int(width1) if width1 else len(label) + fmt = f'{align}{width}' + else: + width = None + return field, label, fmt, width + + @classmethod + def _normalize(cls, spec): + if len(spec) == 1: + raw, = spec + raise NotImplementedError + return _resolve_column(raw) + + if len(spec) == 4: + label, field, width, fmt = spec + if width: + if not fmt: + fmt = str(width) + elif _parse_fmt(fmt)[0] != width: + raise ValueError(f'width mismatch in {spec}') + elif len(raw) == 3: + label, field, fmt = spec + if not field: + label, field = None, label + elif not isinstance(field, str) or not field.isidentifier(): + # XXX This doesn't seem right... + fmt = f'{field}:{fmt}' if fmt else field + label, field = None, label + elif len(raw) == 2: + label = None + field, fmt = raw + if not field: + field, fmt = fmt, None + elif not field.isidentifier() or fmt.isidentifier(): + label, field = field, fmt + else: + raise NotImplementedError + + fmt = f':{fmt}' if fmt else '' + if label: + return cls._parse(f'[{label}]{field}{fmt}') + else: + return cls._parse(f'{field}{fmt}') + + @property + def width(self): + if not self.fmt: + return None + parsed = _parse_fmt(self.fmt) + if not parsed: + return None + width, _ = parsed + return width + + def resolve_width(self, default=None): + return _resolve_width(self.width, self.fmt, self.label, default) def _parse_fmt(fmt): @@ -272,100 +385,31 @@ def _parse_fmt(fmt): width = fmt[1:] if width.isdigit(): return int(width), align - return None, None + elif fmt.isdigit(): + return int(fmt), '<' + return None -def _parse_colspec(raw): - m = _COLSPEC_RE.match(raw) - if not m: - return None - label, field, align, width1, width2, fmt = m.groups() - if not label: - label = field - if width1: - width = None - fmt = f'{align}{width1}' - elif width2: - width = int(width2) - if fmt: - _width, _ = _parse_fmt(fmt) - if _width == width: - width = None - else: - width = None - return field, label, width, fmt - - -def _normalize_colspec(spec): - if len(spec) == 1: - raw, = spec - return _resolve_column(raw) - - if len(spec) == 4: - label, field, width, fmt = spec - if width: - fmt = f'{width}:{fmt}' if fmt else width - elif len(raw) == 3: - label, field, fmt = spec - if not field: - label, field = None, label - elif not isinstance(field, str) or not field.isidentifier(): - fmt = f'{field}:{fmt}' if fmt else field - label, field = None, label - elif len(raw) == 2: - label = None - field, fmt = raw - if not field: - field, fmt = fmt, None - elif not field.isidentifier() or fmt.isidentifier(): - label, field = field, fmt - else: - raise NotImplementedError - - fmt = f':{fmt}' if fmt else '' - if label: - return _parse_colspec(f'[{label}]{field}{fmt}') - else: - return _parse_colspec(f'{field}{fmt}') - - -def _resolve_colspec(raw): - if isinstance(raw, str): - spec = _parse_colspec(raw) - else: - spec = _normalize_colspec(raw) - if spec is None: - raise ValueError(f'unsupported column spec {raw!r}') - return spec - - -def _resolve_colspecs(columns): - parsed = [] - for raw in columns: - column = _resolve_colspec(raw) - parsed.append(column) - return parsed - - -def _resolve_width(spec, defaultwidth): - _, label, width, fmt = spec +def _resolve_width(width, fmt, label, default): if width: if not isinstance(width, int): raise NotImplementedError return width - elif width and fmt: - width, _ = _parse_fmt(fmt) - if width: - return width - - if not defaultwidth: + elif fmt: + parsed = _parse_fmt(fmt) + if parsed: + width, _ = parsed + if width: + return width + + if not default: return WIDTH - elif not hasattr(defaultwidth, 'get'): - return defaultwidth or WIDTH - - defaultwidths = defaultwidth - defaultwidth = defaultwidths.get(None) or WIDTH - return defaultwidths.get(label) or defaultwidth + elif hasattr(default, 'get'): + defaults = default + default = defaults.get(None) or WIDTH + return defaults.get(label) or default + else: + return default or WIDTH def _build_table(columns, *, sep=' ', defaultwidth=None): @@ -373,16 +417,13 @@ def _build_table(columns, *, sep=' ', defaultwidth=None): div = [] rowfmt = [] for spec in columns: - label, field, _, colfmt = spec - width = _resolve_width(spec, defaultwidth) - if colfmt: - colfmt = f':{colfmt}' - else: - colfmt = f':{width}' + width = spec.resolve_width(defaultwidth) + colfmt = spec.fmt + colfmt = f':{spec.fmt}' if spec.fmt else f':{width}' - header.append(f' {{:^{width}}} '.format(label)) + header.append(f' {{:^{width}}} '.format(spec.label)) div.append('-' * (width + 2)) - rowfmt.append(f' {{{field}{colfmt}}} ') + rowfmt.append(f' {{{spec.field}{colfmt}}} ') return ( sep.join(header), sep.join(div), diff --git a/Tools/c-analyzer/c_parser/__init__.py b/Tools/c-analyzer/c_parser/__init__.py index fc10aff9..c7316fcf 100644 --- a/Tools/c-analyzer/c_parser/__init__.py +++ b/Tools/c-analyzer/c_parser/__init__.py @@ -22,8 +22,12 @@ def parse_files(filenames, *, if get_file_preprocessor is None: get_file_preprocessor = _get_preprocessor() for filename in filenames: - yield from _parse_file( - filename, match_kind, get_file_preprocessor, file_maxsizes) + try: + yield from _parse_file( + filename, match_kind, get_file_preprocessor, file_maxsizes) + except Exception: + print(f'# requested file: <{filename}>') + raise # re-raise def _parse_file(filename, match_kind, get_file_preprocessor, maxsizes): diff --git a/Tools/c-analyzer/c_parser/__main__.py b/Tools/c-analyzer/c_parser/__main__.py index 78f47a18..2454fcba 100644 --- a/Tools/c-analyzer/c_parser/__main__.py +++ b/Tools/c-analyzer/c_parser/__main__.py @@ -1,10 +1,7 @@ import logging -import os.path import sys -from c_common import fsutil from c_common.scriptutil import ( - CLIArgSpec as Arg, add_verbosity_cli, add_traceback_cli, add_kind_filtering_cli, @@ -15,7 +12,6 @@ from c_common.scriptutil import ( get_prog, main_for_filenames, ) -from .preprocessor import get_preprocessor from .preprocessor.__main__ import ( add_common_cli as add_preprocessor_cli, ) diff --git a/Tools/c-analyzer/c_parser/_state_machine.py b/Tools/c-analyzer/c_parser/_state_machine.py deleted file mode 100644 index 53cbb13e..00000000 --- a/Tools/c-analyzer/c_parser/_state_machine.py +++ /dev/null @@ -1,244 +0,0 @@ - -f''' - struct {ANON_IDENTIFIER}; - struct {{ ... }} - struct {IDENTIFIER} {{ ... }} - - union {ANON_IDENTIFIER}; - union {{ ... }} - union {IDENTIFIER} {{ ... }} - - enum {ANON_IDENTIFIER}; - enum {{ ... }} - enum {IDENTIFIER} {{ ... }} - - typedef {VARTYPE} {IDENTIFIER}; - typedef {IDENTIFIER}; - typedef {IDENTIFIER}; - typedef {IDENTIFIER}; -''' - - -def parse(srclines): - if isinstance(srclines, str): # a filename - raise NotImplementedError - - - -# This only handles at most 10 nested levels. -#MATCHED_PARENS = textwrap.dedent(rf''' -# # matched parens -# (?: -# [(] # level 0 -# (?: -# [^()]* -# [(] # level 1 -# (?: -# [^()]* -# [(] # level 2 -# (?: -# [^()]* -# [(] # level 3 -# (?: -# [^()]* -# [(] # level 4 -# (?: -# [^()]* -# [(] # level 5 -# (?: -# [^()]* -# [(] # level 6 -# (?: -# [^()]* -# [(] # level 7 -# (?: -# [^()]* -# [(] # level 8 -# (?: -# [^()]* -# [(] # level 9 -# (?: -# [^()]* -# [(] # level 10 -# [^()]* -# [)] -# )* -# [^()]* -# [)] -# )* -# [^()]* -# [)] -# )* -# [^()]* -# [)] -# )* -# [^()]* -# [)] -# )* -# [^()]* -# [)] -# )* -# [^()]* -# [)] -# )* -# [^()]* -# [)] -# )* -# [^()]* -# [)] -# )* -# [^()]* -# [)] -# )* -# [^()]* -# [)] -# ) -# # end matched parens -# ''') - -''' - # for loop - (?: - \s* \b for - \s* [(] - ( - [^;]* ; - [^;]* ; - .*? - ) # <header> - [)] - \s* - (?: - (?: - ( - {_ind(SIMPLE_STMT, 6)} - ) # <stmt> - ; - ) - | - ( {{ ) # <open> - ) - ) - | - - - - ( - (?: - (?: - (?: - {_ind(SIMPLE_STMT, 6)} - )? - return \b \s* - {_ind(INITIALIZER, 5)} - ) - | - (?: - (?: - {IDENTIFIER} \s* - (?: . | -> ) \s* - )* - {IDENTIFIER} - \s* = \s* - {_ind(INITIALIZER, 5)} - ) - | - (?: - {_ind(SIMPLE_STMT, 5)} - ) - ) - | - # cast compound literal - (?: - (?: - [^'"{{}};]* - {_ind(STRING_LITERAL, 5)} - )* - [^'"{{}};]*? - [^'"{{}};=] - = - \s* [(] [^)]* [)] - \s* {{ [^;]* }} - ) - ) # <stmt> - - - - # compound statement - (?: - ( - (?: - - # "for" statements are handled separately above. - (?: (?: else \s+ )? if | switch | while ) \s* - {_ind(COMPOUND_HEAD, 5)} - ) - | - (?: else | do ) - # We do not worry about compound statements for labels, - # "case", or "default". - )? # <header> - \s* - ( {{ ) # <open> - ) - - - - ( - (?: - [^'"{{}};]* - {_ind(STRING_LITERAL, 5)} - )* - [^'"{{}};]* - # Presumably we will not see "== {{". - [^\s='"{{}};] - )? # <header> - - - - ( - \b - (?: - # We don't worry about labels with a compound statement. - (?: - switch \s* [(] [^{{]* [)] - ) - | - (?: - case \b \s* [^:]+ [:] - ) - | - (?: - default \s* [:] - ) - | - (?: - do - ) - | - (?: - while \s* [(] [^{{]* [)] - ) - | - #(?: - # for \s* [(] [^{{]* [)] - # ) - #| - (?: - if \s* [(] - (?: [^{{]* [^)] \s* {{ )* [^{{]* - [)] - ) - | - (?: - else - (?: - \s* - if \s* [(] - (?: [^{{]* [^)] \s* {{ )* [^{{]* - [)] - )? - ) - ) - )? # <header> -''' diff --git a/Tools/c-analyzer/c_parser/info.py b/Tools/c-analyzer/c_parser/info.py index a1d349dc..799f9237 100644 --- a/Tools/c-analyzer/c_parser/info.py +++ b/Tools/c-analyzer/c_parser/info.py @@ -1,6 +1,5 @@ from collections import namedtuple import enum -import os.path import re from c_common import fsutil @@ -8,7 +7,7 @@ from c_common.clsutil import classonly import c_common.misc as _misc import c_common.strutil as _strutil import c_common.tables as _tables -from .parser._regexes import SIMPLE_TYPE, _STORAGE +from .parser._regexes import _STORAGE FIXED_TYPE = _misc.Labeled('FIXED_TYPE') @@ -385,6 +384,9 @@ def get_parsed_vartype(decl): elif isinstance(decl, Variable): storage = decl.storage typequal, typespec, abstract = decl.vartype + elif isinstance(decl, Signature): + storage = None + typequal, typespec, abstract = decl.returntype elif isinstance(decl, Function): storage = decl.storage typequal, typespec, abstract = decl.signature.returntype @@ -789,6 +791,7 @@ class Declaration(HighlevelParsedItem): if kind is not cls.kind: raise TypeError(f'expected kind {cls.kind.value!r}, got {row!r}') fileinfo = FileInfo.from_raw(filename) + extra = None if isinstance(data, str): data, extra = cls._parse_data(data, fmt='row') if extra: @@ -1012,6 +1015,18 @@ class Signature(namedtuple('Signature', 'params returntype inline isforward')): def returns(self): return self.returntype + @property + def typequal(self): + return self.returntype.typequal + + @property + def typespec(self): + return self.returntype.typespec + + @property + def abstract(self): + return self.returntype.abstract + class Function(Declaration): kind = KIND.FUNCTION @@ -1106,9 +1121,16 @@ class TypeDef(TypeDeclaration): def _resolve_data(cls, data): if not data: raise NotImplementedError(data) - vartype = dict(data) - del vartype['storage'] - return VarType(**vartype), None + kwargs = dict(data) + del kwargs['storage'] + if 'returntype' in kwargs: + vartype = kwargs['returntype'] + del vartype['storage'] + kwargs['returntype'] = VarType(**vartype) + datacls = Signature + else: + datacls = VarType + return datacls(**kwargs), None @classmethod def _raw_data(self, data): diff --git a/Tools/c-analyzer/c_parser/parser/__init__.py b/Tools/c-analyzer/c_parser/parser/__init__.py index 4c121adb..4227e938 100644 --- a/Tools/c-analyzer/c_parser/parser/__init__.py +++ b/Tools/c-analyzer/c_parser/parser/__init__.py @@ -42,7 +42,7 @@ separators: + (stmt) case: between expression and stmt + (stmt) default: between "default" and stmt * "=" - + (decl) delaration: between decl and initializer + + (decl) declaration: between decl and initializer + (decl) enumerator: between identifier and "initializer" + (expr) assignment: between "var" and expr @@ -92,7 +92,7 @@ Here are the cases where we've taken shortcuts or made assumptions: * no "inline" type decls in function return types * no superfluous parentheses in declarators * var decls in for loops are always "simple" (e.g. no inline types) -* only inline struct/union/enum decls may be anonymouns (without a name) +* only inline struct/union/enum decls may be anonymous (without a name) * no function pointers in function pointer parameters * for loop "headers" do not have curly braces (e.g. compound init) * syntactically, variable decls do not overlap with stmts/exprs, except diff --git a/Tools/c-analyzer/c_parser/parser/_alt.py b/Tools/c-analyzer/c_parser/parser/_alt.py deleted file mode 100644 index 05a9101b..00000000 --- a/Tools/c-analyzer/c_parser/parser/_alt.py +++ /dev/null @@ -1,6 +0,0 @@ - -def _parse(srclines, anon_name): - text = ' '.join(l for _, l in srclines) - - from ._delim import parse - yield from parse(text, anon_name) diff --git a/Tools/c-analyzer/c_parser/parser/_common.py b/Tools/c-analyzer/c_parser/parser/_common.py index 40c36039..2eacace2 100644 --- a/Tools/c-analyzer/c_parser/parser/_common.py +++ b/Tools/c-analyzer/c_parser/parser/_common.py @@ -7,9 +7,25 @@ from ._regexes import ( ) -def log_match(group, m): +def log_match(group, m, depth_before=None, depth_after=None): from . import _logger - _logger.debug(f'matched <{group}> ({m.group(0)})') + + if m is not None: + text = m.group(0) + if text.startswith(('(', ')')) or text.endswith(('(', ')')): + _logger.debug(f'matched <{group}> ({text!r})') + else: + _logger.debug(f'matched <{group}> ({text})') + + elif depth_before is not None or depth_after is not None: + if depth_before is None: + depth_before = '???' + elif depth_after is None: + depth_after = '???' + _logger.log(1, f'depth: %s -> %s', depth_before, depth_after) + + else: + raise NotImplementedError('this should not have been hit') ############################# diff --git a/Tools/c-analyzer/c_parser/parser/_delim.py b/Tools/c-analyzer/c_parser/parser/_delim.py deleted file mode 100644 index 51433a62..00000000 --- a/Tools/c-analyzer/c_parser/parser/_delim.py +++ /dev/null @@ -1,54 +0,0 @@ -import re -import textwrap - -from ._regexes import _ind, STRING_LITERAL - - -def parse(text, anon_name): - context = None - data = None - for m in DELIMITER_RE.find_iter(text): - before, opened, closed = m.groups() - delim = opened or closed - - handle_segment = HANDLERS[context][delim] - result, context, data = handle_segment(before, delim, data) - if result: - yield result - - -DELIMITER = textwrap.dedent(rf''' - ( - (?: - [^'"()\[\]{};]* - {_ind(STRING_LITERAL, 3)} - }* - [^'"()\[\]{};]+ - )? # <before> - (?: - ( - [(\[{] - ) # <open> - | - ( - [)\]};] - ) # <close> - )? - ''') -DELIMITER_RE = re.compile(DELIMITER, re.VERBOSE) - -_HANDLERS = { - None: { # global - # opened - '{': ..., - '[': None, - '(': None, - # closed - '}': None, - ']': None, - ')': None, - ';': ..., - }, - '': { - }, -} diff --git a/Tools/c-analyzer/c_parser/parser/_func_body.py b/Tools/c-analyzer/c_parser/parser/_func_body.py index 42fd459e..25f2f580 100644 --- a/Tools/c-analyzer/c_parser/parser/_func_body.py +++ b/Tools/c-analyzer/c_parser/parser/_func_body.py @@ -65,11 +65,11 @@ def parse_function_body(name, text, resolve, source, anon_name, parent): ) = m.groups() if empty: - log_match('', m) + log_match('', m, depth) resolve(None, None, None, text) yield None, text elif inline_kind: - log_match('', m) + log_match('', m, depth) kind = inline_kind name = inline_name or anon_name('inline-') data = [] # members @@ -92,7 +92,7 @@ def parse_function_body(name, text, resolve, source, anon_name, parent): # XXX Should "parent" really be None for inline type decls? yield resolve(kind, data, name, text, None), text elif block_close: - log_match('', m) + log_match('', m, depth) depth -= 1 resolve(None, None, None, text) # XXX This isn't great. Calling resolve() should have @@ -101,13 +101,13 @@ def parse_function_body(name, text, resolve, source, anon_name, parent): # needs to be fixed. yield None, text elif compound_bare: - log_match('', m) + log_match('', m, depth) yield resolve('statement', compound_bare, None, text, parent), text elif compound_labeled: - log_match('', m) + log_match('', m, depth) yield resolve('statement', compound_labeled, None, text, parent), text elif compound_paren: - log_match('', m) + log_match('', m, depth) try: pos = match_paren(text) except ValueError: @@ -132,7 +132,7 @@ def parse_function_body(name, text, resolve, source, anon_name, parent): } yield resolve('statement', data, None, text, parent), text elif block_open: - log_match('', m) + log_match('', m, depth) depth += 1 if block_leading: # An inline block: the last evaluated expression is used @@ -144,10 +144,10 @@ def parse_function_body(name, text, resolve, source, anon_name, parent): resolve(None, None, None, text) yield None, text elif simple_ending: - log_match('', m) + log_match('', m, depth) yield resolve('statement', simple_stmt, None, text, parent), text elif var_ending: - log_match('', m) + log_match('', m, depth) kind = 'variable' _, name, vartype = parse_var_decl(decl) data = { @@ -220,7 +220,7 @@ def _parse_next_local_static(m, srcinfo, anon_name, func, depth): remainder = srcinfo.text[m.end():] if inline_kind: - log_match('func inline', m) + log_match('func inline', m, depth, depth) kind = inline_kind name = inline_name or anon_name('inline-') # Immediately emit a forward declaration. @@ -249,7 +249,7 @@ def _parse_next_local_static(m, srcinfo, anon_name, func, depth): yield parse_body, depth elif static_decl: - log_match('local variable', m) + log_match('local variable', m, depth, depth) _, name, data = parse_var_decl(static_decl) yield srcinfo.resolve('variable', data, name, parent=func), depth @@ -266,10 +266,13 @@ def _parse_next_local_static(m, srcinfo, anon_name, func, depth): else: log_match('func other', m) if block_open: + log_match('func other', None, depth, depth + 1) depth += 1 elif block_close: + log_match('func other', None, depth, depth - 1) depth -= 1 elif stmt_end: + log_match('func other', None, depth, depth) pass else: # This should be unreachable. diff --git a/Tools/c-analyzer/c_parser/parser/_global.py b/Tools/c-analyzer/c_parser/parser/_global.py index 35947c12..b1ac9f5d 100644 --- a/Tools/c-analyzer/c_parser/parser/_global.py +++ b/Tools/c-analyzer/c_parser/parser/_global.py @@ -9,7 +9,6 @@ from ._common import ( set_capture_groups, ) from ._compound_decl_body import DECL_BODY_PARSERS -#from ._func_body import parse_function_body from ._func_body import parse_function_statics as parse_function_body diff --git a/Tools/c-analyzer/c_parser/parser/_regexes.py b/Tools/c-analyzer/c_parser/parser/_regexes.py index b7f22b18..5695daff 100644 --- a/Tools/c-analyzer/c_parser/parser/_regexes.py +++ b/Tools/c-analyzer/c_parser/parser/_regexes.py @@ -58,6 +58,7 @@ _KEYWORD = textwrap.dedent(r''' extern | register | static | + _Thread_local | typedef | const | @@ -137,7 +138,7 @@ COMPOUND_TYPE_KIND = r'(?: \b (?: struct | union | enum ) \b )' ####################################### # variable declarations -_STORAGE = 'auto register static extern'.split() +_STORAGE = 'auto register static extern _Thread_local'.split() STORAGE_CLASS = rf'(?: \b (?: {" | ".join(_STORAGE)} ) \b )' TYPE_QUALIFIER = r'(?: \b (?: const | volatile ) \b )' PTR_QUALIFIER = rf'(?: [*] (?: \s* {TYPE_QUALIFIER} )? )' diff --git a/Tools/c-analyzer/c_parser/preprocessor/__init__.py b/Tools/c-analyzer/c_parser/preprocessor/__init__.py index e38176fe..cdc1a4e1 100644 --- a/Tools/c-analyzer/c_parser/preprocessor/__init__.py +++ b/Tools/c-analyzer/c_parser/preprocessor/__init__.py @@ -1,7 +1,9 @@ import contextlib -import distutils.ccompiler import logging +import os import os.path +import re +import sys from c_common.fsutil import match_glob as _match_glob from c_common.tables import parse_table as _parse_table @@ -33,9 +35,11 @@ logger = logging.getLogger(__name__) def preprocess(source, *, incldirs=None, + includes=None, macros=None, samefiles=None, filename=None, + cwd=None, tool=True, ): """... @@ -43,17 +47,27 @@ def preprocess(source, *, CWD should be the project root and "source" should be relative. """ if tool: - logger.debug(f'CWD: {os.getcwd()!r}') - logger.debug(f'incldirs: {incldirs!r}') - logger.debug(f'macros: {macros!r}') + if not cwd: + cwd = os.getcwd() + logger.debug(f'CWD: {cwd!r}') + logger.debug(f'incldirs: {incldirs!r}') + logger.debug(f'includes: {includes!r}') + logger.debug(f'macros: {macros!r}') logger.debug(f'samefiles: {samefiles!r}') _preprocess = _get_preprocessor(tool) with _good_file(source, filename) as source: - return _preprocess(source, incldirs, macros, samefiles) or () + return _preprocess( + source, + incldirs, + includes, + macros, + samefiles, + cwd, + ) or () else: source, filename = _resolve_source(source, filename) # We ignore "includes", "macros", etc. - return _pure.preprocess(source, filename) + return _pure.preprocess(source, filename, cwd) # if _run() returns just the lines: # text = _run(source) @@ -70,6 +84,7 @@ def preprocess(source, *, def get_preprocessor(*, file_macros=None, + file_includes=None, file_incldirs=None, file_same=None, ignore_exc=False, @@ -78,10 +93,12 @@ def get_preprocessor(*, _preprocess = preprocess if file_macros: file_macros = tuple(_parse_macros(file_macros)) + if file_includes: + file_includes = tuple(_parse_includes(file_includes)) if file_incldirs: file_incldirs = tuple(_parse_incldirs(file_incldirs)) if file_same: - file_same = tuple(file_same) + file_same = dict(file_same or ()) if not callable(ignore_exc): ignore_exc = (lambda exc, _ig=ignore_exc: _ig) @@ -89,16 +106,26 @@ def get_preprocessor(*, filename = filename.strip() if file_macros: macros = list(_resolve_file_values(filename, file_macros)) + if file_includes: + # There's a small chance we could need to filter out any + # includes that import "filename". It isn't clear that it's + # a problem any longer. If we do end up filtering then + # it may make sense to use c_common.fsutil.match_path_tail(). + includes = [i for i, in _resolve_file_values(filename, file_includes)] if file_incldirs: incldirs = [v for v, in _resolve_file_values(filename, file_incldirs)] + if file_same: + samefiles = _resolve_samefiles(filename, file_same) def preprocess(**kwargs): if file_macros and 'macros' not in kwargs: kwargs['macros'] = macros + if file_includes and 'includes' not in kwargs: + kwargs['includes'] = includes if file_incldirs and 'incldirs' not in kwargs: - kwargs['incldirs'] = [v for v, in _resolve_file_values(filename, file_incldirs)] - if file_same and 'file_same' not in kwargs: - kwargs['samefiles'] = file_same + kwargs['incldirs'] = incldirs + if file_same and 'samefiles' not in kwargs: + kwargs['samefiles'] = samefiles kwargs.setdefault('filename', filename) with handling_errors(ignore_exc, log_err=log_err): return _preprocess(filename, **kwargs) @@ -118,6 +145,11 @@ def _parse_macros(macros): yield row +def _parse_includes(includes): + for row, srcfile in _parse_table(includes, '\t', 'glob\tinclude', default=None): + yield row + + def _parse_incldirs(incldirs): for row, srcfile in _parse_table(incldirs, '\t', 'glob\tdirname', default=None): glob, dirname = row @@ -128,6 +160,43 @@ def _parse_incldirs(incldirs): yield row +def _resolve_samefiles(filename, file_same): + assert '*' not in filename, (filename,) + assert os.path.normpath(filename) == filename, (filename,) + _, suffix = os.path.splitext(filename) + samefiles = [] + for patterns, in _resolve_file_values(filename, file_same.items()): + for pattern in patterns: + same = _resolve_samefile(filename, pattern, suffix) + if not same: + continue + samefiles.append(same) + return samefiles + + +def _resolve_samefile(filename, pattern, suffix): + if pattern == filename: + return None + if pattern.endswith(os.path.sep): + pattern += f'*{suffix}' + assert os.path.normpath(pattern) == pattern, (pattern,) + if '*' in os.path.dirname(pattern): + raise NotImplementedError((filename, pattern)) + if '*' not in os.path.basename(pattern): + return pattern + + common = os.path.commonpath([filename, pattern]) + relpattern = pattern[len(common) + len(os.path.sep):] + relpatterndir = os.path.dirname(relpattern) + relfile = filename[len(common) + len(os.path.sep):] + if os.path.basename(pattern) == '*': + return os.path.join(common, relpatterndir, relfile) + elif os.path.basename(relpattern) == '*' + suffix: + return os.path.join(common, relpatterndir, relfile) + else: + raise NotImplementedError((filename, pattern)) + + @contextlib.contextmanager def handling_errors(ignore_exc=None, *, log_err=None): try: @@ -168,9 +237,17 @@ _COMPILERS = { } +def _get_default_compiler(): + if re.match('cygwin.*', sys.platform) is not None: + return 'unix' + if os.name == 'nt': + return 'msvc' + return 'unix' + + def _get_preprocessor(tool): if tool is True: - tool = distutils.ccompiler.get_default_compiler() + tool = _get_default_compiler() preprocess = _COMPILERS.get(tool) if preprocess is None: raise ValueError(f'unsupported tool {tool}') diff --git a/Tools/c-analyzer/c_parser/preprocessor/common.py b/Tools/c-analyzer/c_parser/preprocessor/common.py index 63681025..06f8f4da 100644 --- a/Tools/c-analyzer/c_parser/preprocessor/common.py +++ b/Tools/c-analyzer/c_parser/preprocessor/common.py @@ -1,6 +1,7 @@ import contextlib import distutils.ccompiler import logging +import os import shlex import subprocess import sys @@ -40,11 +41,16 @@ def run_cmd(argv, *, kw.pop('kwargs') kwargs.update(kw) - proc = subprocess.run(argv, **kwargs) + # Remove LANG environment variable: the C parser doesn't support GCC + # localized messages + env = dict(os.environ) + env.pop('LANG', None) + + proc = subprocess.run(argv, env=env, **kwargs) return proc.stdout -def preprocess(tool, filename, **kwargs): +def preprocess(tool, filename, cwd=None, **kwargs): argv = _build_argv(tool, filename, **kwargs) logger.debug(' '.join(shlex.quote(v) for v in argv)) @@ -59,19 +65,24 @@ def preprocess(tool, filename, **kwargs): # distutil compiler object's preprocess() method, since that # one writes to stdout/stderr and it's simpler to do it directly # through subprocess. - return run_cmd(argv) + return run_cmd(argv, cwd=cwd) def _build_argv( tool, filename, incldirs=None, + includes=None, macros=None, preargs=None, postargs=None, executable=None, compiler=None, ): + if includes: + includes = tuple(f'-include{i}' for i in includes) + postargs = (includes + postargs) if postargs else includes + compiler = distutils.ccompiler.new_compiler( compiler=compiler or tool, ) @@ -110,15 +121,15 @@ def converted_error(tool, argv, filename): def convert_error(tool, argv, filename, stderr, rc): error = (stderr.splitlines()[0], rc) if (_expected := is_os_mismatch(filename, stderr)): - logger.debug(stderr.strip()) + logger.info(stderr.strip()) raise OSMismatchError(filename, _expected, argv, error, tool) elif (_missing := is_missing_dep(stderr)): - logger.debug(stderr.strip()) + logger.info(stderr.strip()) raise MissingDependenciesError(filename, (_missing,), argv, error, tool) elif '#error' in stderr: # XXX Ignore incompatible files. error = (stderr.splitlines()[1], rc) - logger.debug(stderr.strip()) + logger.info(stderr.strip()) raise ErrorDirectiveError(filename, argv, error, tool) else: # Try one more time, with stderr written to the terminal. diff --git a/Tools/c-analyzer/c_parser/preprocessor/gcc.py b/Tools/c-analyzer/c_parser/preprocessor/gcc.py index bb404a48..14761570 100644 --- a/Tools/c-analyzer/c_parser/preprocessor/gcc.py +++ b/Tools/c-analyzer/c_parser/preprocessor/gcc.py @@ -6,8 +6,18 @@ from . import common as _common TOOL = 'gcc' +META_FILES = { + '<built-in>', + '<command-line>', +} + # https://gcc.gnu.org/onlinedocs/cpp/Preprocessor-Output.html -LINE_MARKER_RE = re.compile(r'^# (\d+) "([^"]+)"(?: [1234])*$') +# flags: +# 1 start of a new file +# 2 returning to a file (after including another) +# 3 following text comes from a system header file +# 4 following text treated wrapped in implicit extern "C" block +LINE_MARKER_RE = re.compile(r'^# (\d+) "([^"]+)"((?: [1234])*)$') PREPROC_DIRECTIVE_RE = re.compile(r'^\s*#\s*(\w+)\b.*') COMPILER_DIRECTIVE_RE = re.compile(r''' ^ @@ -24,7 +34,7 @@ COMPILER_DIRECTIVE_RE = re.compile(r''' [^()]* )* ) # <args> - ( [)] [)] )? # <closed> + ( [)] [)] ) # <closed> ''', re.VERBOSE) POST_ARGS = ( @@ -40,41 +50,130 @@ POST_ARGS = ( ) -def preprocess(filename, incldirs=None, macros=None, samefiles=None): +def preprocess(filename, + incldirs=None, + includes=None, + macros=None, + samefiles=None, + cwd=None, + ): + if not cwd or not os.path.isabs(cwd): + cwd = os.path.abspath(cwd or '.') + filename = _normpath(filename, cwd) text = _common.preprocess( TOOL, filename, incldirs=incldirs, + includes=includes, macros=macros, #preargs=PRE_ARGS, postargs=POST_ARGS, executable=['gcc'], compiler='unix', + cwd=cwd, ) - return _iter_lines(text, filename, samefiles) + return _iter_lines(text, filename, samefiles, cwd) -def _iter_lines(text, filename, samefiles, *, raw=False): +def _iter_lines(text, reqfile, samefiles, cwd, raw=False): lines = iter(text.splitlines()) - # Build the lines and filter out directives. + # The first line is special. + # The next two lines are consistent. + firstlines = [ + f'# 0 "{reqfile}"', + '# 0 "<built-in>"', + '# 0 "<command-line>"', + ] + if text.startswith('# 1 '): + # Some preprocessors emit a lineno of 1 for line-less entries. + firstlines = [l.replace('# 0 ', '# 1 ') for l in firstlines] + for expected in firstlines: + line = next(lines) + if line != expected: + raise NotImplementedError((line, expected)) + + # Do all the CLI-provided includes. + filter_reqfile = (lambda f: _filter_reqfile(f, reqfile, samefiles)) + make_info = (lambda lno: _common.FileInfo(reqfile, lno)) + last = None + for line in lines: + assert last != reqfile, (last,) + lno, included, flags = _parse_marker_line(line, reqfile) + if not included: + raise NotImplementedError((line,)) + if included == reqfile: + # This will be the last one. + assert not flags, (line, flags) + else: + assert 1 in flags, (line, flags) + yield from _iter_top_include_lines( + lines, + _normpath(included, cwd), + cwd, + filter_reqfile, + make_info, + raw, + ) + last = included + # The last one is always the requested file. + assert included == reqfile, (line,) + + +def _iter_top_include_lines(lines, topfile, cwd, + filter_reqfile, make_info, + raw): partial = 0 # depth - origfile = None + files = [topfile] + # We start at 1 in case there are source lines (including blank onces) + # before the first marker line. Also, we already verified in + # _parse_marker_line() that the preprocessor reported lno as 1. + lno = 1 for line in lines: - m = LINE_MARKER_RE.match(line) - if m: - lno, origfile = m.groups() - lno = int(lno) - elif _filter_orig_file(origfile, filename, samefiles): + if line == '# 0 "<command-line>" 2' or line == '# 1 "<command-line>" 2': + # We're done with this top-level include. + return + + _lno, included, flags = _parse_marker_line(line) + if included: + lno = _lno + included = _normpath(included, cwd) + # We hit a marker line. + if 1 in flags: + # We're entering a file. + # XXX Cycles are unexpected? + #assert included not in files, (line, files) + files.append(included) + elif 2 in flags: + # We're returning to a file. + assert files and included in files, (line, files) + assert included != files[-1], (line, files) + while files[-1] != included: + files.pop() + # XXX How can a file return to line 1? + #assert lno > 1, (line, lno) + else: + if included == files[-1]: + # It's the next line from the file. + assert lno > 1, (line, lno) + else: + # We ran into a user-added #LINE directive, + # which we promptly ignore. + pass + elif not files: + raise NotImplementedError((line,)) + elif filter_reqfile(files[-1]): + assert lno is not None, (line, files[-1]) if (m := PREPROC_DIRECTIVE_RE.match(line)): name, = m.groups() if name != 'pragma': raise Exception(line) else: + line = re.sub(r'__inline__', 'inline', line) if not raw: line, partial = _strip_directives(line, partial=partial) yield _common.SourceLine( - _common.FileInfo(filename, lno), + make_info(lno), 'source', line or '', None, @@ -82,6 +181,34 @@ def _iter_lines(text, filename, samefiles, *, raw=False): lno += 1 +def _parse_marker_line(line, reqfile=None): + m = LINE_MARKER_RE.match(line) + if not m: + return None, None, None + lno, origfile, flags = m.groups() + lno = int(lno) + assert origfile not in META_FILES, (line,) + assert lno > 0, (line, lno) + flags = set(int(f) for f in flags.split()) if flags else () + + if 1 in flags: + # We're entering a file. + assert lno == 1, (line, lno) + assert 2 not in flags, (line,) + elif 2 in flags: + # We're returning to a file. + #assert lno > 1, (line, lno) + pass + elif reqfile and origfile == reqfile: + # We're starting the requested file. + assert lno == 1, (line, lno) + assert not flags, (line, flags) + else: + # It's the next line from the file. + assert lno > 1, (line, lno) + return lno, origfile, flags + + def _strip_directives(line, partial=0): # We assume there are no string literals with parens in directive bodies. while partial > 0: @@ -92,6 +219,7 @@ def _strip_directives(line, partial=0): line = line[m.end():] line = re.sub(r'__extension__', '', line) + line = re.sub(r'__thread\b', '_Thread_local', line) while (m := COMPILER_DIRECTIVE_RE.match(line)): before, _, _, closed = m.groups() @@ -106,18 +234,16 @@ def _strip_directives(line, partial=0): return line, partial -def _filter_orig_file(origfile, current, samefiles): - if origfile == current: +def _filter_reqfile(current, reqfile, samefiles): + if current == reqfile: + return True + if current == '<stdin>': return True - if origfile == '<stdin>': + if current in samefiles: return True - if os.path.isabs(origfile): - return False + return False - for filename in samefiles or (): - if filename.endswith(os.path.sep): - filename += os.path.basename(current) - if origfile == filename: - return True - return False +def _normpath(filename, cwd): + assert cwd + return os.path.normpath(os.path.join(cwd, filename)) diff --git a/Tools/c-analyzer/c_parser/preprocessor/pure.py b/Tools/c-analyzer/c_parser/preprocessor/pure.py index e971389b..f94447ad 100644 --- a/Tools/c-analyzer/c_parser/preprocessor/pure.py +++ b/Tools/c-analyzer/c_parser/preprocessor/pure.py @@ -4,7 +4,7 @@ from ..source import ( from . import common as _common -def preprocess(lines, filename=None): +def preprocess(lines, filename=None, cwd=None): if isinstance(lines, str): with _open_source(lines, filename) as (lines, filename): yield from preprocess(lines, filename) diff --git a/Tools/c-analyzer/check-c-globals.py b/Tools/c-analyzer/check-c-globals.py index b1364a61..73742f70 100644 --- a/Tools/c-analyzer/check-c-globals.py +++ b/Tools/c-analyzer/check-c-globals.py @@ -1,7 +1,9 @@ +import sys + from cpython.__main__ import main, configure_logger -def parse_args(): +def parse_args(argv=sys.argv[1:]): import argparse from c_common.scriptutil import ( add_verbosity_cli, @@ -13,7 +15,8 @@ def parse_args(): processors = [ add_verbosity_cli(parser), add_traceback_cli(parser), - _cli_check(parser, checks='<globals>'), + #_cli_check(parser, checks='<globals>'), + _cli_check(parser), ] args = parser.parse_args() diff --git a/Tools/c-analyzer/cpython/__main__.py b/Tools/c-analyzer/cpython/__main__.py index be331d50..ec026c69 100644 --- a/Tools/c-analyzer/cpython/__main__.py +++ b/Tools/c-analyzer/cpython/__main__.py @@ -1,7 +1,7 @@ import logging import sys +import textwrap -from c_common.fsutil import expand_filenames, iter_files_by_suffix from c_common.scriptutil import ( VERBOSITY, add_verbosity_cli, @@ -10,7 +10,6 @@ from c_common.scriptutil import ( add_kind_filtering_cli, add_files_cli, add_progress_cli, - main_for_filenames, process_args_by_key, configure_logger, get_prog, @@ -20,12 +19,45 @@ import c_parser.__main__ as c_parser import c_analyzer.__main__ as c_analyzer import c_analyzer as _c_analyzer from c_analyzer.info import UNKNOWN -from . import _analyzer, _capi, _files, _parser, REPO_ROOT +from . import _analyzer, _builtin_types, _capi, _files, _parser, REPO_ROOT logger = logging.getLogger(__name__) +CHECK_EXPLANATION = textwrap.dedent(''' + ------------------------- + + Non-constant global variables are generally not supported + in the CPython repo. We use a tool to analyze the C code + and report if any unsupported globals are found. The tool + may be run manually with: + + ./python Tools/c-analyzer/check-c-globals.py --format summary [FILE] + + Occasionally the tool is unable to parse updated code. + If this happens then add the file to the "EXCLUDED" list + in Tools/c-analyzer/cpython/_parser.py and create a new + issue for fixing the tool (and CC ericsnowcurrently + on the issue). + + If the tool reports an unsupported global variable and + it is actually const (and thus supported) then first try + fixing the declaration appropriately in the code. If that + doesn't work then add the variable to the "should be const" + section of Tools/c-analyzer/cpython/ignored.tsv. + + If the tool otherwise reports an unsupported global variable + then first try to make it non-global, possibly adding to + PyInterpreterState (for core code) or module state (for + extension modules). In an emergency, you can add the + variable to Tools/c-analyzer/cpython/globals-to-fix.tsv + to get CI passing, but doing so should be avoided. If + this course it taken, be sure to create an issue for + eliminating the global (and CC ericsnowcurrently). +''') + + def _resolve_filenames(filenames): if filenames: resolved = (_files.resolve_filename(f) for f in filenames) @@ -123,14 +155,26 @@ def _cli_check(parser, **kwargs): def cmd_check(filenames=None, **kwargs): filenames = _resolve_filenames(filenames) kwargs['get_file_preprocessor'] = _parser.get_preprocessor(log_err=print) - c_analyzer.cmd_check( - filenames, - relroot=REPO_ROOT, - _analyze=_analyzer.analyze, - _CHECKS=CHECKS, - file_maxsizes=_parser.MAX_SIZES, - **kwargs - ) + try: + c_analyzer.cmd_check( + filenames, + relroot=REPO_ROOT, + _analyze=_analyzer.analyze, + _CHECKS=CHECKS, + file_maxsizes=_parser.MAX_SIZES, + **kwargs + ) + except SystemExit as exc: + num_failed = exc.args[0] if getattr(exc, 'args', None) else None + if isinstance(num_failed, int): + if num_failed > 0: + sys.stderr.flush() + print(CHECK_EXPLANATION, flush=True) + raise # re-raise + except Exception: + sys.stderr.flush() + print(CHECK_EXPLANATION, flush=True) + raise # re-raise def cmd_analyze(filenames=None, **kwargs): @@ -325,6 +369,47 @@ def cmd_capi(filenames=None, *, print(line) +def _cli_builtin_types(parser): + parser.add_argument('--format', dest='fmt', default='table') +# parser.add_argument('--summary', dest='format', +# action='store_const', const='summary') + def process_format(args, *, argv=None): + orig = args.fmt + args.fmt = _builtin_types.resolve_format(args.fmt) + if isinstance(args.fmt, str): + if args.fmt not in _builtin_types._FORMATS: + parser.error(f'unsupported format {orig!r}') + + parser.add_argument('--include-modules', dest='showmodules', + action='store_true') + def process_modules(args, *, argv=None): + pass + + return [ + process_format, + process_modules, + ] + + +def cmd_builtin_types(fmt, *, + showmodules=False, + verbosity=VERBOSITY, + ): + render = _builtin_types.get_renderer(fmt) + types = _builtin_types.iter_builtin_types() + match = _builtin_types.resolve_matcher(showmodules) + if match: + types = (t for t in types if match(t, log=lambda msg: logger.log(1, msg))) + + lines = render( + types, +# verbose=verbosity > VERBOSITY, + ) + print() + for line in lines: + print(line) + + # We do not define any other cmd_*() handlers here, # favoring those defined elsewhere. @@ -354,6 +439,11 @@ COMMANDS = { [_cli_capi], cmd_capi, ), + 'builtin-types': ( + 'show the builtin types', + [_cli_builtin_types], + cmd_builtin_types, + ), } diff --git a/Tools/c-analyzer/cpython/_analyzer.py b/Tools/c-analyzer/cpython/_analyzer.py index 741fbadd..68d6b31c 100644 --- a/Tools/c-analyzer/cpython/_analyzer.py +++ b/Tools/c-analyzer/cpython/_analyzer.py @@ -4,16 +4,12 @@ import re from c_common.clsutil import classonly from c_parser.info import ( KIND, - DeclID, Declaration, TypeDeclaration, - TypeDef, - Struct, Member, FIXED_TYPE, ) from c_parser.match import ( - is_type_decl, is_pots, is_funcptr, ) @@ -60,6 +56,46 @@ _IGNORED = { # {ID => reason} } +# XXX We should be handling these through known.tsv. +_OTHER_SUPPORTED_TYPES = { + # Holds tuple of strings, which we statically initialize: + '_PyArg_Parser', + # Uses of these should be const, but we don't worry about it. + 'PyModuleDef', + 'PyModuleDef_Slot[]', + 'PyType_Spec', + 'PyType_Slot[]', + 'PyMethodDef', + 'PyMethodDef[]', + 'PyMemberDef[]', + 'PyGetSetDef[]', + 'PyNumberMethods', + 'PySequenceMethods', + 'PyMappingMethods', + 'PyAsyncMethods', + 'PyBufferProcs', + 'PyStructSequence_Field[]', + 'PyStructSequence_Desc', +} + +# XXX We should normalize all cases to a single name, +# e.g. "kwlist" (currently the most common). +_KWLIST_VARIANTS = [ + ('*', 'kwlist'), + ('*', 'keywords'), + ('*', 'kwargs'), + ('Modules/_csv.c', 'dialect_kws'), + ('Modules/_datetimemodule.c', 'date_kws'), + ('Modules/_datetimemodule.c', 'datetime_kws'), + ('Modules/_datetimemodule.c', 'time_kws'), + ('Modules/_datetimemodule.c', 'timezone_kws'), + ('Modules/_lzmamodule.c', 'optnames'), + ('Modules/_lzmamodule.c', 'arg_names'), + ('Modules/cjkcodecs/multibytecodec.c', 'incnewkwarglist'), + ('Modules/cjkcodecs/multibytecodec.c', 'streamkwarglist'), + ('Modules/socketmodule.c', 'kwnames'), +] + KINDS = frozenset((*KIND.TYPES, KIND.VARIABLE)) @@ -202,6 +238,8 @@ def _check_typedep(decl, typedecl, types, knowntypes): # XXX Fail? return 'typespec (missing)' elif typedecl is _info.UNKNOWN: + if _has_other_supported_type(decl): + return None # XXX Is this right? return 'typespec (unknown)' elif not isinstance(typedecl, TypeDeclaration): @@ -216,12 +254,46 @@ def _check_typedep(decl, typedecl, types, knowntypes): elif decl.kind is KIND.VARIABLE: if not is_process_global(decl): return None + if _is_kwlist(decl): + return None + if _has_other_supported_type(decl): + return None checked = _check_vartype(decl, typedecl, types, knowntypes) return 'mutable' if checked is FIXED_TYPE else checked else: raise NotImplementedError(decl) +def _is_kwlist(decl): + # keywords for PyArg_ParseTupleAndKeywords() + # "static char *name[]" -> "static const char * const name[]" + # XXX These should be made const. + for relpath, name in _KWLIST_VARIANTS: + if decl.name == name: + if relpath == '*': + break + assert os.path.isabs(decl.file.filename) + relpath = os.path.normpath(relpath) + if decl.file.filename.endswith(os.path.sep + relpath): + break + else: + return False + vartype = ''.join(str(decl.vartype).split()) + return vartype == 'char*[]' + + +def _has_other_supported_type(decl): + if hasattr(decl, 'file') and decl.file.filename.endswith('.c.h'): + assert 'clinic' in decl.file.filename, (decl,) + if decl.name == '_kwtuple': + return True + vartype = str(decl.vartype).split() + if vartype[0] == 'struct': + vartype = vartype[1:] + vartype = ''.join(vartype) + return vartype in _OTHER_SUPPORTED_TYPES + + def _check_vartype(decl, typedecl, types, knowntypes): """Return failure reason.""" checked = _check_typespec(decl, typedecl, types, knowntypes) diff --git a/Tools/c-analyzer/cpython/_builtin_types.py b/Tools/c-analyzer/cpython/_builtin_types.py new file mode 100644 index 00000000..faa0b7a8 --- /dev/null +++ b/Tools/c-analyzer/cpython/_builtin_types.py @@ -0,0 +1,365 @@ +from collections import namedtuple +import os.path +import re +import textwrap + +from c_common import tables +from . import REPO_ROOT +from ._files import iter_header_files, iter_filenames + + +CAPI_PREFIX = os.path.join('Include', '') +INTERNAL_PREFIX = os.path.join('Include', 'internal', '') + +REGEX = re.compile(textwrap.dedent(rf''' + (?: + ^ + (?: + (?: + (?: + (?: + (?: + ( static ) # <static> + \s+ + | + ( extern ) # <extern> + \s+ + )? + PyTypeObject \s+ + ) + | + (?: + ( PyAPI_DATA ) # <capi> + \s* [(] \s* PyTypeObject \s* [)] \s* + ) + ) + (\w+) # <name> + \s* + (?: + (?: + ( = \s* {{ ) # <def> + $ + ) + | + ( ; ) # <decl> + ) + ) + | + (?: + # These are specific to Objects/exceptions.c: + (?: + SimpleExtendsException + | + MiddlingExtendsException + | + ComplexExtendsException + ) + \( \w+ \s* , \s* + ( \w+ ) # <excname> + \s* , + ) + ) + ) +'''), re.VERBOSE) + + +def _parse_line(line): + m = re.match(REGEX, line) + if not m: + return None + (static, extern, capi, + name, + def_, decl, + excname, + ) = m.groups() + if def_: + isdecl = False + if extern or capi: + raise NotImplementedError(line) + kind = 'static' if static else None + elif excname: + name = f'_PyExc_{excname}' + isdecl = False + kind = 'static' + else: + isdecl = True + if static: + kind = 'static' + elif extern: + kind = 'extern' + elif capi: + kind = 'capi' + else: + kind = None + return name, isdecl, kind + + +class BuiltinTypeDecl(namedtuple('BuiltinTypeDecl', 'file lno name kind')): + + KINDS = { + 'static', + 'extern', + 'capi', + 'forward', + } + + @classmethod + def from_line(cls, line, filename, lno): + # This is similar to ._capi.CAPIItem.from_line(). + parsed = _parse_line(line) + if not parsed: + return None + name, isdecl, kind = parsed + if not isdecl: + return None + return cls.from_parsed(name, kind, filename, lno) + + @classmethod + def from_parsed(cls, name, kind, filename, lno): + if not kind: + kind = 'forward' + return cls.from_values(filename, lno, name, kind) + + @classmethod + def from_values(cls, filename, lno, name, kind): + if kind not in cls.KINDS: + raise ValueError(f'unsupported kind {kind!r}') + self = cls(filename, lno, name, kind) + if self.kind not in ('extern', 'capi') and self.api: + raise NotImplementedError(self) + elif self.kind == 'capi' and not self.api: + raise NotImplementedError(self) + return self + + @property + def relfile(self): + return self.file[len(REPO_ROOT) + 1:] + + @property + def api(self): + return self.relfile.startswith(CAPI_PREFIX) + + @property + def internal(self): + return self.relfile.startswith(INTERNAL_PREFIX) + + @property + def private(self): + if not self.name.startswith('_'): + return False + return self.api and not self.internal + + @property + def public(self): + if self.kind != 'capi': + return False + return not self.internal and not self.private + + +class BuiltinTypeInfo(namedtuple('BuiltinTypeInfo', 'file lno name static decl')): + + @classmethod + def from_line(cls, line, filename, lno, *, decls=None): + parsed = _parse_line(line) + if not parsed: + return None + name, isdecl, kind = parsed + if isdecl: + return None + return cls.from_parsed(name, kind, filename, lno, decls=decls) + + @classmethod + def from_parsed(cls, name, kind, filename, lno, *, decls=None): + if not kind: + static = False + elif kind == 'static': + static = True + else: + raise NotImplementedError((filename, line, kind)) + decl = decls.get(name) if decls else None + return cls(filename, lno, name, static, decl) + + @property + def relfile(self): + return self.file[len(REPO_ROOT) + 1:] + + @property + def exported(self): + return not self.static + + @property + def api(self): + if not self.decl: + return False + return self.decl.api + + @property + def internal(self): + if not self.decl: + return False + return self.decl.internal + + @property + def private(self): + if not self.decl: + return False + return self.decl.private + + @property + def public(self): + if not self.decl: + return False + return self.decl.public + + @property + def inmodule(self): + return self.relfile.startswith('Modules' + os.path.sep) + + def render_rowvalues(self, kinds): + row = { + 'name': self.name, + **{k: '' for k in kinds}, + 'filename': f'{self.relfile}:{self.lno}', + } + if self.static: + kind = 'static' + else: + if self.internal: + kind = 'internal' + elif self.private: + kind = 'private' + elif self.public: + kind = 'public' + else: + kind = 'global' + row['kind'] = kind + row[kind] = kind + return row + + +def _ensure_decl(decl, decls): + prev = decls.get(decl.name) + if prev: + if decl.kind == 'forward': + return None + if prev.kind != 'forward': + if decl.kind == prev.kind and decl.file == prev.file: + assert decl.lno != prev.lno, (decl, prev) + return None + raise NotImplementedError(f'duplicate {decl} (was {prev}') + decls[decl.name] = decl + + +def iter_builtin_types(filenames=None): + decls = {} + seen = set() + for filename in iter_header_files(): + seen.add(filename) + with open(filename) as infile: + for lno, line in enumerate(infile, 1): + decl = BuiltinTypeDecl.from_line(line, filename, lno) + if not decl: + continue + _ensure_decl(decl, decls) + srcfiles = [] + for filename in iter_filenames(): + if filename.endswith('.c'): + srcfiles.append(filename) + continue + if filename in seen: + continue + with open(filename) as infile: + for lno, line in enumerate(infile, 1): + decl = BuiltinTypeDecl.from_line(line, filename, lno) + if not decl: + continue + _ensure_decl(decl, decls) + + for filename in srcfiles: + with open(filename) as infile: + localdecls = {} + for lno, line in enumerate(infile, 1): + parsed = _parse_line(line) + if not parsed: + continue + name, isdecl, kind = parsed + if isdecl: + decl = BuiltinTypeDecl.from_parsed(name, kind, filename, lno) + if not decl: + raise NotImplementedError((filename, line)) + _ensure_decl(decl, localdecls) + else: + builtin = BuiltinTypeInfo.from_parsed( + name, kind, filename, lno, + decls=decls if name in decls else localdecls) + if not builtin: + raise NotImplementedError((filename, line)) + yield builtin + + +def resolve_matcher(showmodules=False): + def match(info, *, log=None): + if not info.inmodule: + return True + if log is not None: + log(f'ignored {info.name!r}') + return False + return match + + +################################## +# CLI rendering + +def resolve_format(fmt): + if not fmt: + return 'table' + elif isinstance(fmt, str) and fmt in _FORMATS: + return fmt + else: + raise NotImplementedError(fmt) + + +def get_renderer(fmt): + fmt = resolve_format(fmt) + if isinstance(fmt, str): + try: + return _FORMATS[fmt] + except KeyError: + raise ValueError(f'unsupported format {fmt!r}') + else: + raise NotImplementedError(fmt) + + +def render_table(types): + types = sorted(types, key=(lambda t: t.name)) + colspecs = tables.resolve_columns( + 'name:<33 static:^ global:^ internal:^ private:^ public:^ filename:<30') + header, div, rowfmt = tables.build_table(colspecs) + leader = ' ' * sum(c.width+2 for c in colspecs[:3]) + ' ' + yield leader + f'{"API":^29}' + yield leader + '-' * 29 + yield header + yield div + kinds = [c[0] for c in colspecs[1:-1]] + counts = {k: 0 for k in kinds} + base = {k: '' for k in kinds} + for t in types: + row = t.render_rowvalues(kinds) + kind = row['kind'] + yield rowfmt.format(**row) + counts[kind] += 1 + yield '' + yield f'total: {sum(counts.values()):>3}' + for kind in kinds: + yield f' {kind:>10}: {counts[kind]:>3}' + + +def render_repr(types): + for t in types: + yield repr(t) + + +_FORMATS = { + 'table': render_table, + 'repr': render_repr, +} diff --git a/Tools/c-analyzer/cpython/_capi.py b/Tools/c-analyzer/cpython/_capi.py index df8159a8..4552f714 100644 --- a/Tools/c-analyzer/cpython/_capi.py +++ b/Tools/c-analyzer/cpython/_capi.py @@ -7,7 +7,7 @@ import textwrap from c_common.tables import build_table, resolve_columns from c_parser.parser._regexes import _ind -from ._files import iter_header_files, resolve_filename +from ._files import iter_header_files from . import REPO_ROOT @@ -610,8 +610,7 @@ def _render_item_full(item, groupby, verbose): yield item.name yield f' {"filename:":10} {item.relfile}' for extra in ('kind', 'level'): - #if groupby != extra: - yield f' {extra+":":10} {getattr(item, extra)}' + yield f' {extra+":":10} {getattr(item, extra)}' if verbose: print(' ---------------------------------------') for lno, line in enumerate(item.text, item.lno): @@ -636,7 +635,6 @@ def render_summary(items, *, subtotals = summary['totals']['subs'] bygroup = summary['totals']['bygroup'] - lastempty = False for outer, subtotal in subtotals.items(): if bygroup: subtotal = f'({subtotal})' @@ -646,10 +644,6 @@ def render_summary(items, *, if outer in bygroup: for inner, count in bygroup[outer].items(): yield f' {inner + ":":9} {count}' - lastempty = False - else: - lastempty = True - total = f'*{summary["totals"]["all"]}*' label = '*total*:' if bygroup: diff --git a/Tools/c-analyzer/cpython/_parser.py b/Tools/c-analyzer/cpython/_parser.py index eaad7278..1587a197 100644 --- a/Tools/c-analyzer/cpython/_parser.py +++ b/Tools/c-analyzer/cpython/_parser.py @@ -47,15 +47,11 @@ def clean_lines(text): ''' # XXX Handle these. +# Tab separated: EXCLUDED = clean_lines(''' # @begin=conf@ -# Rather than fixing for this one, we manually make sure it's okay. -Modules/_sha3/kcp/KeccakP-1600-opt64.c - # OSX -#Modules/_ctypes/darwin/*.c -#Modules/_ctypes/libffi_osx/*.c Modules/_scproxy.c # SystemConfiguration/SystemConfiguration.h # Windows @@ -69,12 +65,13 @@ Python/thread_nt.h Python/dynload_aix.c # sys/ldr.h Python/dynload_dl.c # dl.h Python/dynload_hpux.c # dl.h -Python/thread_pthread.h Python/emscripten_signal.c +Python/thread_pthread.h +Python/thread_pthread_stubs.h # only huge constants (safe but parsing is slow) -Modules/_blake2/impl/blake2-kat.h Modules/_ssl_data.h +Modules/_ssl_data_31.h Modules/_ssl_data_300.h Modules/_ssl_data_111.h Modules/cjkcodecs/mappings_*.h @@ -85,8 +82,10 @@ Objects/unicodetype_db.h # generated Python/deepfreeze/*.c Python/frozen_modules/*.h -Python/opcode_targets.h -Python/stdlib_module_names.h +Python/generated_cases.c.h + +# not actually source +Python/bytecodes.c # @end=conf@ ''') @@ -95,22 +94,10 @@ Python/stdlib_module_names.h EXCLUDED += clean_lines(''' # The tool should be able to parse these... -Modules/hashlib.h -Objects/stringlib/codecs.h -Objects/stringlib/count.h -Objects/stringlib/ctype.h -Objects/stringlib/fastsearch.h -Objects/stringlib/find.h -Objects/stringlib/find_max_char.h -Objects/stringlib/partition.h -Objects/stringlib/replace.h -Objects/stringlib/split.h - -Modules/_dbmmodule.c -Modules/cjkcodecs/_codecs_*.c -Modules/expat/xmlrole.c +# The problem with xmlparse.c is that something +# has gone wrong where # we handle "maybe inline actual" +# in Tools/c-analyzer/c_parser/parser/_global.py. Modules/expat/xmlparse.c -Python/initconfig.c ''') INCL_DIRS = clean_lines(''' @@ -121,9 +108,58 @@ glob dirname * ./Include * ./Include/internal +Modules/_decimal/**/*.c Modules/_decimal/libmpdec +Modules/_elementtree.c Modules/expat +Modules/_hacl/*.c Modules/_hacl/include +Modules/_hacl/*.h Modules/_hacl/include +Modules/md5module.c Modules/_hacl/include +Modules/sha1module.c Modules/_hacl/include +Modules/sha2module.c Modules/_hacl/include +Modules/sha3module.c Modules/_hacl/include +Objects/stringlib/*.h Objects + +# possible system-installed headers, just in case Modules/_tkinter.c /usr/include/tcl8.6 +Modules/_uuidmodule.c /usr/include/uuid +Modules/nismodule.c /usr/include/tirpc Modules/tkappinit.c /usr/include/tcl -Modules/_decimal/**/*.c Modules/_decimal/libmpdec + +# @end=tsv@ +''')[1:] + +INCLUDES = clean_lines(''' +# @begin=tsv@ + +glob include + +**/*.h Python.h +Include/**/*.h object.h + +# for Py_HAVE_CONDVAR +Include/internal/pycore_gil.h pycore_condvar.h +Python/thread_pthread.h pycore_condvar.h + +# other + +Objects/stringlib/join.h stringlib/stringdefs.h +Objects/stringlib/ctype.h stringlib/stringdefs.h +Objects/stringlib/transmogrify.h stringlib/stringdefs.h +#Objects/stringlib/fastsearch.h stringlib/stringdefs.h +#Objects/stringlib/count.h stringlib/stringdefs.h +#Objects/stringlib/find.h stringlib/stringdefs.h +#Objects/stringlib/partition.h stringlib/stringdefs.h +#Objects/stringlib/split.h stringlib/stringdefs.h +Objects/stringlib/fastsearch.h stringlib/ucs1lib.h +Objects/stringlib/count.h stringlib/ucs1lib.h +Objects/stringlib/find.h stringlib/ucs1lib.h +Objects/stringlib/partition.h stringlib/ucs1lib.h +Objects/stringlib/split.h stringlib/ucs1lib.h +Objects/stringlib/find_max_char.h Objects/stringlib/ucs1lib.h +Objects/stringlib/count.h Objects/stringlib/fastsearch.h +Objects/stringlib/find.h Objects/stringlib/fastsearch.h +Objects/stringlib/partition.h Objects/stringlib/fastsearch.h +Objects/stringlib/replace.h Objects/stringlib/fastsearch.h +Objects/stringlib/split.h Objects/stringlib/fastsearch.h # @end=tsv@ ''')[1:] @@ -135,10 +171,14 @@ glob name value Include/internal/*.h Py_BUILD_CORE 1 Python/**/*.c Py_BUILD_CORE 1 +Python/**/*.h Py_BUILD_CORE 1 Parser/**/*.c Py_BUILD_CORE 1 +Parser/**/*.h Py_BUILD_CORE 1 Objects/**/*.c Py_BUILD_CORE 1 +Objects/**/*.h Py_BUILD_CORE 1 Modules/_asynciomodule.c Py_BUILD_CORE 1 +Modules/_codecsmodule.c Py_BUILD_CORE 1 Modules/_collectionsmodule.c Py_BUILD_CORE 1 Modules/_ctypes/_ctypes.c Py_BUILD_CORE 1 Modules/_ctypes/cfield.c Py_BUILD_CORE 1 @@ -147,6 +187,7 @@ Modules/_datetimemodule.c Py_BUILD_CORE 1 Modules/_functoolsmodule.c Py_BUILD_CORE 1 Modules/_heapqmodule.c Py_BUILD_CORE 1 Modules/_io/*.c Py_BUILD_CORE 1 +Modules/_io/*.h Py_BUILD_CORE 1 Modules/_localemodule.c Py_BUILD_CORE 1 Modules/_operator.c Py_BUILD_CORE 1 Modules/_posixsubprocess.c Py_BUILD_CORE 1 @@ -171,12 +212,6 @@ Modules/signalmodule.c Py_BUILD_CORE 1 Modules/symtablemodule.c Py_BUILD_CORE 1 Modules/timemodule.c Py_BUILD_CORE 1 Modules/unicodedata.c Py_BUILD_CORE 1 -Objects/stringlib/codecs.h Py_BUILD_CORE 1 -Objects/stringlib/unicode_format.h Py_BUILD_CORE 1 -Parser/string_parser.h Py_BUILD_CORE 1 -Parser/pegen.h Py_BUILD_CORE 1 -Python/ceval_gil.h Py_BUILD_CORE 1 -Python/condvar.h Py_BUILD_CORE 1 Modules/_json.c Py_BUILD_CORE_BUILTIN 1 Modules/_pickle.c Py_BUILD_CORE_BUILTIN 1 @@ -192,6 +227,7 @@ Include/cpython/fileobject.h Py_CPYTHON_FILEOBJECT_H 1 Include/cpython/fileutils.h Py_CPYTHON_FILEUTILS_H 1 Include/cpython/frameobject.h Py_CPYTHON_FRAMEOBJECT_H 1 Include/cpython/import.h Py_CPYTHON_IMPORT_H 1 +Include/cpython/interpreteridobject.h Py_CPYTHON_INTERPRETERIDOBJECT_H 1 Include/cpython/listobject.h Py_CPYTHON_LISTOBJECT_H 1 Include/cpython/methodobject.h Py_CPYTHON_METHODOBJECT_H 1 Include/cpython/object.h Py_CPYTHON_OBJECT_H 1 @@ -204,44 +240,22 @@ Include/cpython/sysmodule.h Py_CPYTHON_SYSMODULE_H 1 Include/cpython/traceback.h Py_CPYTHON_TRACEBACK_H 1 Include/cpython/tupleobject.h Py_CPYTHON_TUPLEOBJECT_H 1 Include/cpython/unicodeobject.h Py_CPYTHON_UNICODEOBJECT_H 1 -Include/internal/pycore_code.h SIZEOF_VOID_P 8 - -# implied include of pyport.h -Include/**/*.h PyAPI_DATA(RTYPE) extern RTYPE -Include/**/*.h PyAPI_FUNC(RTYPE) RTYPE -Include/**/*.h Py_DEPRECATED(VER) /* */ -Include/**/*.h _Py_NO_RETURN /* */ -Include/**/*.h PYLONG_BITS_IN_DIGIT 30 -Modules/**/*.c PyMODINIT_FUNC PyObject* -Objects/unicodeobject.c PyMODINIT_FUNC PyObject* -Python/marshal.c PyMODINIT_FUNC PyObject* -Python/_warnings.c PyMODINIT_FUNC PyObject* -Python/Python-ast.c PyMODINIT_FUNC PyObject* -Python/import.c PyMODINIT_FUNC PyObject* -Modules/_testcapimodule.c PyAPI_FUNC(RTYPE) RTYPE -Python/getargs.c PyAPI_FUNC(RTYPE) RTYPE -Objects/stringlib/unicode_format.h Py_LOCAL_INLINE(type) static inline type -Include/pymath.h _Py__has_builtin(x) 0 - -# implied include of pymacro.h -*/clinic/*.c.h PyDoc_VAR(name) static const char name[] -*/clinic/*.c.h PyDoc_STR(str) str -*/clinic/*.c.h PyDoc_STRVAR(name,str) PyDoc_VAR(name) = PyDoc_STR(str) - -# implied include of exports.h -#Modules/_io/bytesio.c Py_EXPORTED_SYMBOL /* */ - -# implied include of object.h -Include/**/*.h PyObject_HEAD PyObject ob_base; -Include/**/*.h PyObject_VAR_HEAD PyVarObject ob_base; - -# implied include of pyconfig.h -Include/**/*.h SIZEOF_WCHAR_T 4 # implied include of <unistd.h> Include/**/*.h _POSIX_THREADS 1 Include/**/*.h HAVE_PTHREAD_H 1 +# from pyconfig.h +Include/cpython/pthread_stubs.h HAVE_PTHREAD_STUBS 1 +Python/thread_pthread_stubs.h HAVE_PTHREAD_STUBS 1 + +# from Objects/bytesobject.c +Objects/stringlib/partition.h STRINGLIB_GET_EMPTY() bytes_get_empty() +Objects/stringlib/join.h STRINGLIB_MUTABLE 0 +Objects/stringlib/partition.h STRINGLIB_MUTABLE 0 +Objects/stringlib/split.h STRINGLIB_MUTABLE 0 +Objects/stringlib/transmogrify.h STRINGLIB_MUTABLE 0 + # from Makefile Modules/getpath.c PYTHONPATH 1 Modules/getpath.c PREFIX ... @@ -249,13 +263,9 @@ Modules/getpath.c EXEC_PREFIX ... Modules/getpath.c VERSION ... Modules/getpath.c VPATH ... Modules/getpath.c PLATLIBDIR ... - -# from Modules/_sha3/sha3module.c -Modules/_sha3/kcp/KeccakP-1600-inplace32BI.c PLATFORM_BYTE_ORDER 4321 # force big-endian -Modules/_sha3/kcp/*.c KeccakOpt 64 -Modules/_sha3/kcp/*.c KeccakP200_excluded 1 -Modules/_sha3/kcp/*.c KeccakP400_excluded 1 -Modules/_sha3/kcp/*.c KeccakP800_excluded 1 +#Modules/_dbmmodule.c USE_GDBM_COMPAT 1 +Modules/_dbmmodule.c USE_NDBM 1 +#Modules/_dbmmodule.c USE_BERKDB 1 # See: setup.py Modules/_decimal/**/*.c CONFIG_64 1 @@ -268,7 +278,6 @@ Modules/_dbmmodule.c HAVE_GDBM_DASH_NDBM_H 1 Modules/_sre/sre_lib.h LOCAL(type) static inline type Modules/_sre/sre_lib.h SRE(F) sre_ucs2_##F Objects/stringlib/codecs.h STRINGLIB_IS_UNICODE 1 -Include/internal/pycore_bitutils.h _Py__has_builtin(B) 0 # @end=tsv@ ''')[1:] @@ -285,28 +294,54 @@ Include/internal/pycore_bitutils.h _Py__has_builtin(B) 0 # -Wno-missing-field-initializers # -Werror=implicit-function-declaration -SAME = [ - './Include/cpython/', -] +SAME = { + _abs('Include/*.h'): [_abs('Include/cpython/')], + _abs('Python/ceval.c'): ['Python/generated_cases.c.h'], +} MAX_SIZES = { - _abs('Include/**/*.h'): (5_000, 500), + # GLOB: (MAXTEXT, MAXLINES), + # default: (10_000, 200) + # First match wins. _abs('Modules/_ctypes/ctypes.h'): (5_000, 500), _abs('Modules/_datetimemodule.c'): (20_000, 300), + _abs('Modules/_hacl/*.c'): (200_000, 500), _abs('Modules/posixmodule.c'): (20_000, 500), _abs('Modules/termios.c'): (10_000, 800), _abs('Modules/_testcapimodule.c'): (20_000, 400), _abs('Modules/expat/expat.h'): (10_000, 400), _abs('Objects/stringlib/unicode_format.h'): (10_000, 400), - _abs('Objects/typeobject.c'): (20_000, 200), + _abs('Objects/typeobject.c'): (35_000, 200), _abs('Python/compile.c'): (20_000, 500), _abs('Python/pylifecycle.c'): (500_000, 5000), _abs('Python/pystate.c'): (500_000, 5000), + + # Generated files: + _abs('Include/internal/pycore_opcode.h'): (10_000, 1000), + _abs('Include/internal/pycore_global_strings.h'): (5_000, 1000), + _abs('Include/internal/pycore_runtime_init_generated.h'): (5_000, 1000), + _abs('Python/deepfreeze/*.c'): (20_000, 500), + _abs('Python/frozen_modules/*.h'): (20_000, 500), + _abs('Python/opcode_targets.h'): (10_000, 500), + _abs('Python/stdlib_module_names.h'): (5_000, 500), + + # These large files are currently ignored (see above). + _abs('Modules/_ssl_data.h'): (80_000, 10_000), + _abs('Modules/_ssl_data_300.h'): (80_000, 10_000), + _abs('Modules/_ssl_data_111.h'): (80_000, 10_000), + _abs('Modules/cjkcodecs/mappings_*.h'): (160_000, 2_000), + _abs('Modules/unicodedata_db.h'): (180_000, 3_000), + _abs('Modules/unicodename_db.h'): (1_200_000, 15_000), + _abs('Objects/unicodetype_db.h'): (240_000, 3_000), + + # Catch-alls: + _abs('Include/**/*.h'): (5_000, 500), } def get_preprocessor(*, file_macros=None, + file_includes=None, file_incldirs=None, file_same=None, **kwargs @@ -314,13 +349,20 @@ def get_preprocessor(*, macros = tuple(MACROS) if file_macros: macros += tuple(file_macros) + includes = tuple(INCLUDES) + if file_includes: + includes += tuple(file_includes) incldirs = tuple(INCL_DIRS) if file_incldirs: incldirs += tuple(file_incldirs) + samefiles = dict(SAME) + if file_same: + samefiles.update(file_same) return _get_preprocessor( file_macros=macros, + file_includes=includes, file_incldirs=incldirs, - file_same=file_same, + file_same=samefiles, **kwargs ) diff --git a/Tools/c-analyzer/cpython/globals-to-fix.tsv b/Tools/c-analyzer/cpython/globals-to-fix.tsv index 7e939277..622c98d1 100644 --- a/Tools/c-analyzer/cpython/globals-to-fix.tsv +++ b/Tools/c-analyzer/cpython/globals-to-fix.tsv @@ -4,10 +4,10 @@ filename funcname name reason # These are all variables that we will be making non-global. ################################## -# global objects to fix in core code +## global objects to fix in core code -#----------------------- -# static types +##----------------------- +## exported builtin types (C-API) Objects/boolobject.c - PyBool_Type - Objects/bytearrayobject.c - PyByteArrayIter_Type - @@ -18,8 +18,6 @@ Objects/capsule.c - PyCapsule_Type - Objects/cellobject.c - PyCell_Type - Objects/classobject.c - PyInstanceMethod_Type - Objects/classobject.c - PyMethod_Type - -Objects/codeobject.c - LineIterator - -Objects/codeobject.c - PositionsIterator - Objects/codeobject.c - PyCode_Type - Objects/complexobject.c - PyComplex_Type - Objects/descrobject.c - PyClassMethodDescr_Type - @@ -42,10 +40,7 @@ Objects/dictobject.c - PyDictValues_Type - Objects/dictobject.c - PyDict_Type - Objects/enumobject.c - PyEnum_Type - Objects/enumobject.c - PyReversed_Type - -Objects/exceptions.c - _PyExc_BaseExceptionGroup - -Objects/exceptions.c - _PyExc_EncodingWarning - Objects/fileobject.c - PyStdPrinter_Type - -Objects/floatobject.c - FloatInfoType - Objects/floatobject.c - PyFloat_Type - Objects/frameobject.c - PyFrame_Type - Objects/funcobject.c - PyClassMethod_Type - @@ -62,13 +57,10 @@ Objects/genobject.c - _PyCoroWrapper_Type - Objects/interpreteridobject.c - _PyInterpreterID_Type - Objects/iterobject.c - PyCallIter_Type - Objects/iterobject.c - PySeqIter_Type - -Objects/iterobject.c - _PyAnextAwaitable_Type - Objects/listobject.c - PyListIter_Type - Objects/listobject.c - PyListRevIter_Type - Objects/listobject.c - PyList_Type - -Objects/longobject.c - Int_InfoType - Objects/longobject.c - PyLong_Type - -Objects/memoryobject.c - PyMemoryIter_Type - Objects/memoryobject.c - PyMemoryView_Type - Objects/memoryobject.c - _PyManagedBuffer_Type - Objects/methodobject.c - PyCFunction_Type - @@ -90,19 +82,17 @@ Objects/rangeobject.c - PyRange_Type - Objects/setobject.c - PyFrozenSet_Type - Objects/setobject.c - PySetIter_Type - Objects/setobject.c - PySet_Type - -Objects/setobject.c - _PySetDummy_Type - Objects/sliceobject.c - PyEllipsis_Type - Objects/sliceobject.c - PySlice_Type - Objects/tupleobject.c - PyTupleIter_Type - Objects/tupleobject.c - PyTuple_Type - +Objects/typeobject.c - _PyBufferWrapper_Type - Objects/typeobject.c - PyBaseObject_Type - Objects/typeobject.c - PySuper_Type - Objects/typeobject.c - PyType_Type - -Objects/unicodeobject.c - EncodingMapType - +Objects/typevarobject.c - _PyTypeAlias_Type - Objects/unicodeobject.c - PyUnicodeIter_Type - Objects/unicodeobject.c - PyUnicode_Type - -Objects/unionobject.c - _PyUnion_Type - -Objects/unionobject.c - _Py_UnionType - Objects/weakrefobject.c - _PyWeakref_CallableProxyType - Objects/weakrefobject.c - _PyWeakref_ProxyType - Objects/weakrefobject.c - _PyWeakref_RefType - @@ -112,8 +102,23 @@ Python/bltinmodule.c - PyZip_Type - Python/context.c - PyContextToken_Type - Python/context.c - PyContextVar_Type - Python/context.c - PyContext_Type - +Python/traceback.c - PyTraceBack_Type - + +##----------------------- +## other exported builtin types + +# Not in a .h file: +Objects/codeobject.c - _PyLineIterator - +# Not in a .h file: +Objects/codeobject.c - _PyPositionsIterator - +Objects/genericaliasobject.c - _Py_GenericAliasIterType - +# Not in a .h file: +Objects/iterobject.c - _PyAnextAwaitable_Type - +# Not in a .h file: +Objects/memoryobject.c - _PyMemoryIter_Type - +Objects/unicodeobject.c - _PyUnicodeASCIIIter_Type - +Objects/unionobject.c - _PyUnion_Type - Python/context.c - _PyContextTokenMissing_Type - -Python/errors.c - UnraisableHookArgsType - Python/hamt.c - _PyHamtItems_Type - Python/hamt.c - _PyHamtKeys_Type - Python/hamt.c - _PyHamtValues_Type - @@ -122,17 +127,37 @@ Python/hamt.c - _PyHamt_BitmapNode_Type - Python/hamt.c - _PyHamt_CollisionNode_Type - Python/hamt.c - _PyHamt_Type - Python/symtable.c - PySTEntry_Type - + +##----------------------- +## private static builtin types + +Objects/setobject.c - _PySetDummy_Type - +Objects/stringlib/unicode_format.h - PyFormatterIter_Type - +Objects/stringlib/unicode_format.h - PyFieldNameIter_Type - +Objects/unicodeobject.c - EncodingMapType - +#Objects/unicodeobject.c - PyFieldNameIter_Type - +#Objects/unicodeobject.c - PyFormatterIter_Type - +Python/legacy_tracing.c - _PyLegacyEventHandler_Type - +Objects/object.c - _PyLegacyEventHandler_Type - + + +##----------------------- +## static builtin structseq + +Objects/floatobject.c - FloatInfoType - +Objects/longobject.c - Int_InfoType - +Python/errors.c - UnraisableHookArgsType - Python/sysmodule.c - AsyncGenHooksType - Python/sysmodule.c - FlagsType - Python/sysmodule.c - Hash_InfoType - Python/sysmodule.c - VersionInfoType - Python/thread.c - ThreadInfoType - -Python/traceback.c - PyTraceBack_Type - -#----------------------- -# builtin exception types +##----------------------- +## builtin exception types Objects/exceptions.c - _PyExc_BaseException - +Objects/exceptions.c - _PyExc_BaseExceptionGroup - Objects/exceptions.c - _PyExc_UnicodeEncodeError - Objects/exceptions.c - _PyExc_UnicodeDecodeError - Objects/exceptions.c - _PyExc_UnicodeTranslateError - @@ -196,9 +221,11 @@ Objects/exceptions.c - _PyExc_ImportWarning - Objects/exceptions.c - _PyExc_UnicodeWarning - Objects/exceptions.c - _PyExc_BytesWarning - Objects/exceptions.c - _PyExc_ResourceWarning - +Objects/exceptions.c - _PyExc_EncodingWarning - Objects/exceptions.c - PyExc_EnvironmentError - Objects/exceptions.c - PyExc_IOError - Objects/exceptions.c - PyExc_BaseException - +Objects/exceptions.c - PyExc_BaseExceptionGroup - Objects/exceptions.c - PyExc_Exception - Objects/exceptions.c - PyExc_TypeError - Objects/exceptions.c - PyExc_StopAsyncIteration - @@ -262,548 +289,53 @@ Objects/exceptions.c - PyExc_ImportWarning - Objects/exceptions.c - PyExc_UnicodeWarning - Objects/exceptions.c - PyExc_BytesWarning - Objects/exceptions.c - PyExc_ResourceWarning - +Objects/exceptions.c - PyExc_EncodingWarning - -#----------------------- -# singletons +##----------------------- +## singletons Objects/boolobject.c - _Py_FalseStruct - Objects/boolobject.c - _Py_TrueStruct - Objects/dictobject.c - empty_keys_struct - -Objects/dictobject.c - empty_values_struct - Objects/object.c - _Py_NoneStruct - Objects/object.c - _Py_NotImplementedStruct - Objects/setobject.c - _dummy_struct - Objects/setobject.c - _PySet_Dummy - Objects/sliceobject.c - _Py_EllipsisObject - - -#----------------------- -# cached - initialized once - -# manually cached PyUnicodeObject -# XXX This should have been found by the analyzer but wasn't: -Python/ast_unparse.c - _str_replace_inf - - -# _PyArg_Parser (holds tuple of strings) -Objects/clinic/bytearrayobject.c.h bytearray___init__ _parser - -Objects/clinic/bytearrayobject.c.h bytearray_decode _parser - -Objects/clinic/bytearrayobject.c.h bytearray_hex _parser - -Objects/clinic/bytearrayobject.c.h bytearray_rsplit _parser - -Objects/clinic/bytearrayobject.c.h bytearray_split _parser - -Objects/clinic/bytearrayobject.c.h bytearray_splitlines _parser - -Objects/clinic/bytearrayobject.c.h bytearray_translate _parser - -Objects/clinic/bytesobject.c.h bytes_decode _parser - -Objects/clinic/bytesobject.c.h bytes_hex _parser - -Objects/clinic/bytesobject.c.h bytes_new _parser - -Objects/clinic/bytesobject.c.h bytes_rsplit _parser - -Objects/clinic/bytesobject.c.h bytes_split _parser - -Objects/clinic/bytesobject.c.h bytes_splitlines _parser - -Objects/clinic/bytesobject.c.h bytes_translate _parser - -Objects/clinic/codeobject.c.h code__varname_from_oparg _parser - -Objects/clinic/codeobject.c.h code_replace _parser - -Objects/clinic/complexobject.c.h complex_new _parser - -Objects/clinic/descrobject.c.h mappingproxy_new _parser - -Objects/clinic/descrobject.c.h property_init _parser - -Objects/clinic/enumobject.c.h enum_new _parser - -Objects/clinic/funcobject.c.h func_new _parser - -Objects/clinic/listobject.c.h list_sort _parser - -Objects/clinic/longobject.c.h int_from_bytes _parser - -Objects/clinic/longobject.c.h int_to_bytes _parser - -Objects/clinic/longobject.c.h long_new _parser - -Objects/clinic/memoryobject.c.h memoryview _parser - -Objects/clinic/memoryobject.c.h memoryview_cast _parser - -Objects/clinic/memoryobject.c.h memoryview_hex _parser - -Objects/clinic/memoryobject.c.h memoryview_tobytes _parser - -Objects/clinic/moduleobject.c.h module___init__ _parser - -Objects/clinic/odictobject.c.h OrderedDict_fromkeys _parser - -Objects/clinic/odictobject.c.h OrderedDict_move_to_end _parser - -Objects/clinic/odictobject.c.h OrderedDict_pop _parser - -Objects/clinic/odictobject.c.h OrderedDict_popitem _parser - -Objects/clinic/odictobject.c.h OrderedDict_setdefault _parser - -Objects/clinic/structseq.c.h structseq_new _parser - -Objects/clinic/unicodeobject.c.h unicode_encode _parser - -Objects/clinic/unicodeobject.c.h unicode_expandtabs _parser - -Objects/clinic/unicodeobject.c.h unicode_new _parser - -Objects/clinic/unicodeobject.c.h unicode_rsplit _parser - -Objects/clinic/unicodeobject.c.h unicode_split _parser - -Objects/clinic/unicodeobject.c.h unicode_splitlines _parser - -Python/clinic/Python-tokenize.c.h tokenizeriter_new _parser - -Python/clinic/_warnings.c.h warnings_warn _parser - -Python/clinic/bltinmodule.c.h builtin_compile _parser - -Python/clinic/bltinmodule.c.h builtin_pow _parser - -Python/clinic/bltinmodule.c.h builtin_print _parser - -Python/clinic/bltinmodule.c.h builtin_round _parser - -Python/clinic/bltinmodule.c.h builtin_sum _parser - -Python/clinic/import.c.h _imp_find_frozen _parser - -Python/clinic/import.c.h _imp_source_hash _parser - -Python/clinic/sysmodule.c.h sys_addaudithook _parser - -Python/clinic/sysmodule.c.h sys_set_coroutine_origin_tracking_depth _parser - -Python/clinic/traceback.c.h tb_new _parser - - -# holds strings -Objects/typeobject.c - slotdefs - - -# other -Objects/typeobject.c - method_cache - -Objects/typeobject.c object___reduce_ex___impl objreduce - -Objects/unicodeobject.c - _string_module - -Objects/unicodeobject.c - interned - -Objects/unicodeobject.c - static_strings - - -#----------------------- -# other - -# initialized once -Objects/exceptions.c - PyExc_BaseExceptionGroup - -Objects/exceptions.c - PyExc_EncodingWarning - -# XXX This should have been found by the analyzer but wasn't: -Python/context.c - _token_missing - -# XXX This should have been found by the analyzer but wasn't: -Python/fileutils.c - _Py_open_cloexec_works - -# XXX This should have been found by the analyzer but wasn't: -Python/hamt.c - _empty_bitmap_node - -# XXX This should have been found by the analyzer but wasn't: -Python/hamt.c - _empty_hamt - -# XXX This should have been found by the analyzer but wasn't: -Python/import.c PyImport_Import silly_list - - -# state -Objects/typeobject.c resolve_slotdups pname - -# XXX This should have been found by the analyzer but wasn't: -Python/import.c - extensions - +Python/instrumentation.c - _PyInstrumentation_DISABLE - +Python/instrumentation.c - _PyInstrumentation_MISSING - ################################## -# global non-objects to fix in core code +## global non-objects to fix in core code -#----------------------- -# initialized/set once - -# pre-allocated buffer -Modules/getbuildinfo.c Py_GetBuildInfo buildinfo - - -# during init -Objects/typeobject.c - slotdefs_initialized - -Objects/unicodeobject.c - bloom_linebreak - -Parser/parser.c - Py_DebugFlag - -Python/bootstrap_hash.c - _Py_HashSecret_Initialized - -Python/bootstrap_hash.c py_getrandom getrandom_works - -Python/pyhash.c - _Py_HashSecret - -Python/pylifecycle.c - runtime_initialized - -Python/sysmodule.c - _PySys_ImplCacheTag - -Python/sysmodule.c - _PySys_ImplName - -Python/sysmodule.c - _preinit_warnoptions - -Python/sysmodule.c - _preinit_xoptions - -Python/thread.c - thread_debug - -Python/thread.c - initialized - - -# lazy -Objects/floatobject.c - double_format - -Objects/floatobject.c - float_format - -Objects/floatobject.c - detected_double_format - -Objects/floatobject.c - detected_float_format - -Objects/longobject.c PyLong_FromString log_base_BASE - -Objects/longobject.c PyLong_FromString convwidth_base - -Objects/longobject.c PyLong_FromString convmultmax_base - -Objects/unicodeobject.c - ucnhash_capi - -Parser/action_helpers.c _PyPegen_dummy_name cache - -Python/dtoa.c - p5s - -Python/fileutils.c - force_ascii - -Python/fileutils.c set_inheritable ioctl_works - -# XXX This should have been found by the analyzer but wasn't: -Python/import.c - import_lock - -# XXX This should have been found by the analyzer but wasn't: -Python/import.c import_find_and_load header - -Python/specialize.c - _list_append - - -#----------------------- -# unlikely to change after init (or main thread) - -# through C-API -Python/frozen.c - PyImport_FrozenModules - -Python/frozen.c - _PyImport_FrozenAliases - -Python/frozen.c - _PyImport_FrozenBootstrap - -Python/frozen.c - _PyImport_FrozenStdlib - -Python/frozen.c - _PyImport_FrozenTest - -Python/import.c - inittab_copy - -Python/import.c - PyImport_Inittab - -Python/preconfig.c - Py_FileSystemDefaultEncoding - -Python/preconfig.c - Py_HasFileSystemDefaultEncoding - -Python/preconfig.c - Py_FileSystemDefaultEncodeErrors - -Python/preconfig.c - _Py_HasFileSystemDefaultEncodeErrors - - -# REPL -Parser/myreadline.c - _PyOS_ReadlineLock - -Parser/myreadline.c - _PyOS_ReadlineTState - -Parser/myreadline.c - PyOS_InputHook - -Parser/myreadline.c - PyOS_ReadlineFunctionPointer - - -# handling C argv -Python/getopt.c - _PyOS_optarg - -Python/getopt.c - _PyOS_opterr - -Python/getopt.c - _PyOS_optind - -Python/getopt.c - opt_ptr - -Python/pathconfig.c - _Py_path_config - - -#----------------------- -# state - -# allocator -Objects/obmalloc.c - _PyObject_Arena - -Objects/obmalloc.c - _Py_tracemalloc_config - -Objects/obmalloc.c - arena_map_bot_count - -Objects/obmalloc.c - arena_map_mid_count - -Objects/obmalloc.c - arena_map_root - -Objects/obmalloc.c - arenas - -Objects/obmalloc.c - maxarenas - -Objects/obmalloc.c - narenas_currently_allocated - -Objects/obmalloc.c - narenas_highwater - -Objects/obmalloc.c - nfp2lasta - -Objects/obmalloc.c - ntimes_arena_allocated - -Objects/obmalloc.c - raw_allocated_blocks - -Objects/obmalloc.c - unused_arena_objects - -Objects/obmalloc.c - usable_arenas - -Objects/obmalloc.c new_arena debug_stats - - -# pre-allocated memory -Python/dtoa.c - freelist - -Python/dtoa.c - private_mem - - -# local buffer -Python/getversion.c Py_GetVersion version - -Python/suggestions.c levenshtein_distance buffer - - -# linked list -Python/dtoa.c - pmem_next - -Python/getargs.c - static_arg_parsers - - -# other -Objects/dictobject.c - _pydict_global_version - -Objects/dictobject.c - next_dict_keys_version - -Objects/dictobject.c - pydict_global_version - -Objects/funcobject.c - next_func_version - -Objects/moduleobject.c - max_module_number - -Objects/object.c - _Py_RefTotal - -Objects/typeobject.c - next_version_tag - -Objects/typeobject.c resolve_slotdups ptrs - -Parser/pegen.c - memo_statistics - -# XXX This should have been found by the analyzer but wasn't: -Python/bootstrap_hash.c - urandom_cache - -# XXX This should have been found by the analyzer but wasn't: -Python/ceval.c - lltrace - -# XXX This should have been found by the analyzer but wasn't: -Python/ceval.c make_pending_calls busy - -Python/dynload_shlib.c - handles - -Python/dynload_shlib.c - nhandles - -# XXX This should have been found by the analyzer but wasn't: -Python/import.c - import_lock_level - -# XXX This should have been found by the analyzer but wasn't: -Python/import.c - import_lock_thread - -# XXX This should have been found by the analyzer but wasn't: -Python/import.c import_find_and_load accumulated - -# XXX This should have been found by the analyzer but wasn't: -Python/import.c import_find_and_load import_level - -Python/modsupport.c - _Py_PackageContext - -Python/pyfpe.c - PyFPE_counter - -Python/pylifecycle.c _Py_FatalErrorFormat reentrant - -# XXX This should have been found by the analyzer but wasn't: -Python/pylifecycle.c - _Py_UnhandledKeyboardInterrupt - -# XXX This should have been found by the analyzer but wasn't: -Python/pylifecycle.c fatal_error reentrant - -Python/specialize.c - _Py_QuickenedCount - +# <none> ################################## -# global objects to fix in builtin modules - -#----------------------- -# modules - -Modules/_abc.c - _abcmodule - -Modules/_codecsmodule.c - codecsmodule - -Modules/_collectionsmodule.c - _collectionsmodule - -Modules/_functoolsmodule.c - _functools_module - -Modules/_io/_iomodule.c - _PyIO_Module - -Modules/_io/_iomodule.h - _PyIO_Module - -Modules/_localemodule.c - _localemodule - -Modules/_sre.c - sremodule - -Modules/_stat.c - statmodule - -Modules/_threadmodule.c - threadmodule - -Modules/_tracemalloc.c - module_def - -Modules/_weakref.c - weakrefmodule - -Modules/atexitmodule.c - atexitmodule - -Modules/errnomodule.c - errnomodule - -Modules/faulthandler.c - module_def - -Modules/gcmodule.c - gcmodule - -Modules/itertoolsmodule.c - itertoolsmodule - -Modules/posixmodule.c - posixmodule - -Modules/pwdmodule.c - pwdmodule - -Modules/signalmodule.c - signalmodule - -Modules/symtablemodule.c - symtablemodule - -Modules/timemodule.c - timemodule - - -#----------------------- -# static types - -Modules/_collectionsmodule.c - defdict_type - -Modules/_collectionsmodule.c - deque_type - -Modules/_collectionsmodule.c - dequeiter_type - -Modules/_collectionsmodule.c - dequereviter_type - -Modules/_collectionsmodule.c - tuplegetter_type - -Modules/_functoolsmodule.c - keyobject_type - -Modules/_functoolsmodule.c - lru_cache_type - -Modules/_functoolsmodule.c - lru_list_elem_type - -Modules/_functoolsmodule.c - partial_type - -Modules/_io/bufferedio.c - PyBufferedIOBase_Type - -Modules/_io/bufferedio.c - PyBufferedRWPair_Type - -Modules/_io/bufferedio.c - PyBufferedRandom_Type - -Modules/_io/bufferedio.c - PyBufferedReader_Type - -Modules/_io/bufferedio.c - PyBufferedWriter_Type - -Modules/_io/bytesio.c - PyBytesIO_Type - -Modules/_io/bytesio.c - _PyBytesIOBuffer_Type - -Modules/_io/fileio.c - PyFileIO_Type - -Modules/_io/iobase.c - PyIOBase_Type - -Modules/_io/iobase.c - PyRawIOBase_Type - -Modules/_io/stringio.c - PyStringIO_Type - -Modules/_io/textio.c - PyIncrementalNewlineDecoder_Type - -Modules/_io/textio.c - PyTextIOBase_Type - -Modules/_io/textio.c - PyTextIOWrapper_Type - -Modules/_io/winconsoleio.c - PyWindowsConsoleIO_Type - -Modules/_threadmodule.c - Locktype - -Modules/_threadmodule.c - RLocktype - -Modules/_threadmodule.c - localdummytype - -Modules/_threadmodule.c - localtype - -Modules/itertoolsmodule.c - _grouper_type - -Modules/itertoolsmodule.c - accumulate_type - -Modules/itertoolsmodule.c - chain_type - -Modules/itertoolsmodule.c - combinations_type - -Modules/itertoolsmodule.c - compress_type - -Modules/itertoolsmodule.c - count_type - -Modules/itertoolsmodule.c - cwr_type - -Modules/itertoolsmodule.c - cycle_type - -Modules/itertoolsmodule.c - dropwhile_type - -Modules/itertoolsmodule.c - filterfalse_type - -Modules/itertoolsmodule.c - groupby_type - -Modules/itertoolsmodule.c - islice_type - -Modules/itertoolsmodule.c - pairwise_type - -Modules/itertoolsmodule.c - permutations_type - -Modules/itertoolsmodule.c - product_type - -Modules/itertoolsmodule.c - repeat_type - -Modules/itertoolsmodule.c - starmap_type - -Modules/itertoolsmodule.c - takewhile_type - -Modules/itertoolsmodule.c - tee_type - -Modules/itertoolsmodule.c - teedataobject_type - -Modules/itertoolsmodule.c - ziplongest_type - - -#----------------------- -# non-static types - initialized once - -# structseq types -Modules/_threadmodule.c - ExceptHookArgsType - -Modules/signalmodule.c - SiginfoType - -Modules/timemodule.c - StructTimeType - +## global objects to fix in builtin modules -# exception types -Modules/_threadmodule.c - ThreadError - -Modules/signalmodule.c - ItimerError - +##----------------------- +## static types -#----------------------- -# cached - initialized once - -# _PyArg_Parser -Modules/clinic/_codecsmodule.c.h _codecs_decode _parser - -Modules/clinic/_codecsmodule.c.h _codecs_encode _parser - -Modules/clinic/_sre.c.h _sre_SRE_Match_expand _parser - -Modules/clinic/_sre.c.h _sre_SRE_Match_groupdict _parser - -Modules/clinic/_sre.c.h _sre_SRE_Match_groups _parser - -Modules/clinic/_sre.c.h _sre_SRE_Pattern_findall _parser - -Modules/clinic/_sre.c.h _sre_SRE_Pattern_finditer _parser - -Modules/clinic/_sre.c.h _sre_SRE_Pattern_fullmatch _parser - -Modules/clinic/_sre.c.h _sre_SRE_Pattern_match _parser - -Modules/clinic/_sre.c.h _sre_SRE_Pattern_scanner _parser - -Modules/clinic/_sre.c.h _sre_SRE_Pattern_search _parser - -Modules/clinic/_sre.c.h _sre_SRE_Pattern_split _parser - -Modules/clinic/_sre.c.h _sre_SRE_Pattern_sub _parser - -Modules/clinic/_sre.c.h _sre_SRE_Pattern_subn _parser - -Modules/clinic/_sre.c.h _sre_SRE_Scanner_match _parser - -Modules/clinic/_sre.c.h _sre_SRE_Scanner_search _parser - -Modules/clinic/_sre.c.h _sre_compile _parser - -Modules/clinic/gcmodule.c.h gc_collect _parser - -Modules/clinic/gcmodule.c.h gc_get_objects _parser - -Modules/clinic/itertoolsmodule.c.h itertools_accumulate _parser - -Modules/clinic/itertoolsmodule.c.h itertools_combinations _parser - -Modules/clinic/itertoolsmodule.c.h itertools_combinations_with_replacement _parser - -Modules/clinic/itertoolsmodule.c.h itertools_compress _parser - -Modules/clinic/itertoolsmodule.c.h itertools_count _parser - -Modules/clinic/itertoolsmodule.c.h itertools_groupby _parser - -Modules/clinic/itertoolsmodule.c.h itertools_permutations _parser - -Modules/clinic/posixmodule.c.h os_DirEntry_is_dir _parser - -Modules/clinic/posixmodule.c.h os_DirEntry_is_file _parser - -Modules/clinic/posixmodule.c.h os_DirEntry_is_symlink _parser - -Modules/clinic/posixmodule.c.h os_DirEntry_stat _parser - -Modules/clinic/posixmodule.c.h os__exit _parser - -Modules/clinic/posixmodule.c.h os__path_normpath _parser - -Modules/clinic/posixmodule.c.h os_access _parser - -Modules/clinic/posixmodule.c.h os_chdir _parser - -Modules/clinic/posixmodule.c.h os_chmod _parser - -Modules/clinic/posixmodule.c.h os_close _parser - -Modules/clinic/posixmodule.c.h os_device_encoding _parser - -Modules/clinic/posixmodule.c.h os_dup2 _parser - -Modules/clinic/posixmodule.c.h os_fspath _parser - -Modules/clinic/posixmodule.c.h os_fstat _parser - -Modules/clinic/posixmodule.c.h os_listdir _parser - -Modules/clinic/posixmodule.c.h os_lstat _parser - -Modules/clinic/posixmodule.c.h os_mkdir _parser - -Modules/clinic/posixmodule.c.h os_open _parser - -Modules/clinic/posixmodule.c.h os_remove _parser - -Modules/clinic/posixmodule.c.h os_rename _parser - -Modules/clinic/posixmodule.c.h os_replace _parser - -Modules/clinic/posixmodule.c.h os_rmdir _parser - -Modules/clinic/posixmodule.c.h os_scandir _parser - -Modules/clinic/posixmodule.c.h os_stat _parser - -Modules/clinic/posixmodule.c.h os_unlink _parser - -Modules/clinic/posixmodule.c.h os_utime _parser - - -#----------------------- -# other - -# initialized once -Modules/_functoolsmodule.c - kwd_mark - -Modules/_io/_iomodule.c - _PyIO_empty_bytes - -Modules/_tracemalloc.c - tracemalloc_empty_traceback - -Modules/signalmodule.c - DefaultHandler - -Modules/signalmodule.c - IgnoreHandler - -Modules/signalmodule.c - IntHandler - - -# state -Modules/faulthandler.c - fatal_error - -Modules/faulthandler.c - thread - -Modules/faulthandler.c - user_signals - -Modules/faulthandler.c - stack - -Modules/faulthandler.c - old_stack - -Modules/signalmodule.c - Handlers - +Modules/_testcapi/vectorcall.c - MethodDescriptorBase_Type - +Modules/_testcapi/vectorcall.c - MethodDescriptorDerived_Type - +Modules/_testcapi/vectorcall.c - MethodDescriptorNopGet_Type - +Modules/_testcapi/vectorcall.c - MethodDescriptor2_Type - ################################## -# global non-objects to fix in builtin modules - -#----------------------- -# initialized once +## global non-objects to fix in builtin modules -Modules/_io/bufferedio.c _PyIO_trap_eintr eintr_int - -#Modules/cjkcodecs/cjkcodecs.h - codec_list - -#Modules/cjkcodecs/cjkcodecs.h - mapping_list - -Modules/posixmodule.c os_dup2_impl dup3_works - -Modules/posixmodule.c - structseq_new - -Modules/posixmodule.c - ticks_per_second - -Modules/signalmodule.c - initialized - -Modules/timemodule.c - initialized - -Modules/timemodule.c _PyTime_GetClockWithInfo initialized - -Modules/timemodule.c _PyTime_GetProcessTimeWithInfo ticks_per_second - - -#----------------------- -# state - -Modules/_tracemalloc.c - allocators - -Modules/_tracemalloc.c - tables_lock - -Modules/_tracemalloc.c - tracemalloc_traced_memory - -Modules/_tracemalloc.c - tracemalloc_peak_traced_memory - -Modules/_tracemalloc.c - tracemalloc_filenames - -Modules/_tracemalloc.c - tracemalloc_traceback - -Modules/_tracemalloc.c - tracemalloc_tracebacks - -Modules/_tracemalloc.c - tracemalloc_traces - -Modules/_tracemalloc.c - tracemalloc_domains - -Modules/_tracemalloc.c - tracemalloc_reentrant_key - -Modules/faulthandler.c faulthandler_dump_traceback reentrant - -Modules/posixmodule.c - environ - -Modules/signalmodule.c - is_tripped - -Modules/signalmodule.c - signal_global_state - -Modules/signalmodule.c - wakeup - +# <none> ################################## -# global objects to fix in extension modules - -#----------------------- -# modules +## global objects to fix in extension modules -Modules/_asynciomodule.c - _asynciomodule - -Modules/_bisectmodule.c - _bisectmodule - -Modules/_blake2/blake2module.c - blake2_module - -Modules/_bz2module.c - _bz2module - -Modules/_contextvarsmodule.c - _contextvarsmodule - -Modules/_cryptmodule.c - cryptmodule - -Modules/_csv.c - _csvmodule - -Modules/_ctypes/_ctypes.c - _ctypesmodule - -Modules/_curses_panel.c - _curses_panelmodule - -Modules/_cursesmodule.c - _cursesmodule - -Modules/_datetimemodule.c - datetimemodule - -Modules/_decimal/_decimal.c - _decimal_module - -Modules/_elementtree.c - elementtreemodule - -Modules/_gdbmmodule.c - _gdbmmodule - -Modules/_hashopenssl.c - _hashlibmodule - -Modules/_heapqmodule.c - _heapqmodule - -Modules/_json.c - jsonmodule - -Modules/_lsprof.c - _lsprofmodule - -Modules/_lzmamodule.c - _lzmamodule - -Modules/_multiprocessing/multiprocessing.c - multiprocessing_module - -Modules/_multiprocessing/posixshmem.c - this_module - -Modules/_opcode.c - opcodemodule - -Modules/_operator.c - operatormodule - -Modules/_pickle.c - _picklemodule - -Modules/_posixsubprocess.c - _posixsubprocessmodule - -Modules/_queuemodule.c - queuemodule - -Modules/_randommodule.c - _randommodule - -Modules/_sha3/sha3module.c - _sha3module - -Modules/_sqlite/module.c - _sqlite3module - -Modules/_ssl.c - PySocketModule - -Modules/_ssl.c - _sslmodule - -Modules/_statisticsmodule.c - statisticsmodule - -Modules/_struct.c - _structmodule - -Modules/_tkinter.c - _tkintermodule - -Modules/_uuidmodule.c - uuidmodule - -Modules/_xxsubinterpretersmodule.c - interpretersmodule - -Modules/_zoneinfo.c - zoneinfomodule - -Modules/arraymodule.c - arraymodule - -Modules/audioop.c - audioopmodule - -Modules/binascii.c - binasciimodule - -Modules/cjkcodecs/multibytecodec.c - _multibytecodecmodule - -Modules/cmathmodule.c - cmathmodule - -Modules/fcntlmodule.c - fcntlmodule - -Modules/grpmodule.c - grpmodule - -Modules/mathmodule.c - mathmodule - -Modules/md5module.c - _md5module - -Modules/mmapmodule.c - mmapmodule - -Modules/nismodule.c - nismodule - -Modules/ossaudiodev.c - ossaudiodevmodule - -Modules/pyexpat.c - pyexpatmodule - -Modules/readline.c - readlinemodule - -Modules/resource.c - resourcemodule - -Modules/selectmodule.c - selectmodule - -Modules/sha1module.c - _sha1module - -Modules/sha256module.c - _sha256module - -Modules/sha512module.c - _sha512module - -Modules/socketmodule.c - socketmodule - -Modules/spwdmodule.c - spwdmodule - -Modules/syslogmodule.c - syslogmodule - -Modules/termios.c - termiosmodule - -Modules/unicodedata.c - unicodedata_module - -Modules/xxlimited.c - xxmodule - -Modules/xxmodule.c - xxmodule - -Modules/xxsubtype.c - xxsubtypemodule - -Modules/zlibmodule.c - zlibmodule - +##----------------------- +## static types -#----------------------- -# static types - -Modules/_asynciomodule.c - FutureIterType - -Modules/_asynciomodule.c - FutureType - -Modules/_asynciomodule.c - PyRunningLoopHolder_Type - -Modules/_asynciomodule.c - TaskStepMethWrapper_Type - -Modules/_asynciomodule.c - TaskType - -Modules/_csv.c - Dialect_Type - -Modules/_csv.c - Reader_Type - -Modules/_csv.c - Writer_Type - -Modules/_ctypes/_ctypes.c - DictRemover_Type - Modules/_ctypes/_ctypes.c - PyCArrayType_Type - Modules/_ctypes/_ctypes.c - PyCArray_Type - Modules/_ctypes/_ctypes.c - PyCData_Type - @@ -813,15 +345,27 @@ Modules/_ctypes/_ctypes.c - PyCPointerType_Type - Modules/_ctypes/_ctypes.c - PyCPointer_Type - Modules/_ctypes/_ctypes.c - PyCSimpleType_Type - Modules/_ctypes/_ctypes.c - PyCStructType_Type - -Modules/_ctypes/_ctypes.c - PyComError_Type - Modules/_ctypes/_ctypes.c - Simple_Type - -Modules/_ctypes/_ctypes.c - StructParam_Type - Modules/_ctypes/_ctypes.c - Struct_Type - Modules/_ctypes/_ctypes.c - UnionType_Type - Modules/_ctypes/_ctypes.c - Union_Type - -Modules/_ctypes/callbacks.c - PyCThunk_Type - Modules/_ctypes/callproc.c - PyCArg_Type - -Modules/_ctypes/cfield.c - PyCField_Type - +Modules/_ctypes/ctypes.h - PyCArg_Type - +Modules/_ctypes/ctypes.h - PyCArrayType_Type - +Modules/_ctypes/ctypes.h - PyCArray_Type - +Modules/_ctypes/ctypes.h - PyCData_Type - +Modules/_ctypes/ctypes.h - PyCFuncPtrType_Type - +Modules/_ctypes/ctypes.h - PyCFuncPtr_Type - +Modules/_ctypes/ctypes.h - PyCPointerType_Type - +Modules/_ctypes/ctypes.h - PyCPointer_Type - +Modules/_ctypes/ctypes.h - PyCSimpleType_Type - +Modules/_ctypes/ctypes.h - PyCStgDict_Type - +Modules/_ctypes/ctypes.h - PyCStructType_Type - +Modules/_ctypes/ctypes.h - PyExc_ArgError - +Modules/_ctypes/ctypes.h - _ctypes_conversion_encoding - +Modules/_ctypes/ctypes.h - _ctypes_conversion_errors - +Modules/_ctypes/ctypes.h - _ctypes_ptrtype_cache - +Modules/_ctypes/ctypes.h - basespec_string - Modules/_ctypes/stgdict.c - PyCStgDict_Type - Modules/_cursesmodule.c - PyCursesWindow_Type - Modules/_datetimemodule.c - PyDateTime_DateTimeType - @@ -835,424 +379,45 @@ Modules/_decimal/_decimal.c - PyDecContextManager_Type - Modules/_decimal/_decimal.c - PyDecContext_Type - Modules/_decimal/_decimal.c - PyDecSignalDictMixin_Type - Modules/_decimal/_decimal.c - PyDec_Type - -Modules/_elementtree.c - ElementIter_Type - -Modules/_elementtree.c - Element_Type - -Modules/_elementtree.c - TreeBuilder_Type - -Modules/_elementtree.c - XMLParser_Type - -Modules/_multiprocessing/semaphore.c - _PyMp_SemLockType - -Modules/_pickle.c - Pdata_Type - -Modules/_pickle.c - PicklerMemoProxyType - -Modules/_pickle.c - Pickler_Type - -Modules/_pickle.c - UnpicklerMemoProxyType - -Modules/_pickle.c - Unpickler_Type - -Modules/_queuemodule.c - PySimpleQueueType - -Modules/_sre.c - Match_Type - -Modules/_sre.c - Pattern_Type - -Modules/_sre.c - Scanner_Type - -Modules/_ssl.c - PySSLContext_Type - -Modules/_ssl.c - PySSLMemoryBIO_Type - -Modules/_ssl.c - PySSLSession_Type - -Modules/_ssl.c - PySSLSocket_Type - -Modules/_xxsubinterpretersmodule.c - ChannelIDtype - -Modules/_zoneinfo.c - PyZoneInfo_ZoneInfoType - -Modules/arraymodule.c - Arraytype - -Modules/arraymodule.c - PyArrayIter_Type - -Modules/cjkcodecs/multibytecodec.c - MultibyteCodec_Type - -Modules/cjkcodecs/multibytecodec.c - MultibyteIncrementalDecoder_Type - -Modules/cjkcodecs/multibytecodec.c - MultibyteIncrementalEncoder_Type - -Modules/cjkcodecs/multibytecodec.c - MultibyteStreamReader_Type - -Modules/cjkcodecs/multibytecodec.c - MultibyteStreamWriter_Type - -Modules/mmapmodule.c - mmap_object_type - Modules/ossaudiodev.c - OSSAudioType - Modules/ossaudiodev.c - OSSMixerType - -Modules/pyexpat.c - Xmlparsetype - -Modules/socketmodule.c - sock_type - -Modules/xxlimited_35.c - Xxo_Type - Modules/xxmodule.c - Null_Type - Modules/xxmodule.c - Str_Type - Modules/xxmodule.c - Xxo_Type - Modules/xxsubtype.c - spamdict_type - Modules/xxsubtype.c - spamlist_type - -#----------------------- -# non-static types - initialized once +##----------------------- +## non-static types - initialized once -# structseq types -Modules/_cursesmodule.c - NcursesVersionType - -Modules/resource.c - StructRUsageType - -Modules/spwdmodule.c - StructSpwdType - - -# heap types +## heap types Modules/_decimal/_decimal.c - DecimalTuple - Modules/_decimal/_decimal.c - PyDecSignalDict_Type - Modules/_tkinter.c - PyTclObject_Type - Modules/_tkinter.c - Tkapp_Type - Modules/_tkinter.c - Tktt_Type - -Modules/xxlimited.c - Xxo_Type - +Modules/xxlimited_35.c - Xxo_Type - -# exception types +## exception types Modules/_ctypes/_ctypes.c - PyExc_ArgError - Modules/_cursesmodule.c - PyCursesError - Modules/_decimal/_decimal.c - DecimalException - -Modules/_queuemodule.c - EmptyError - -Modules/_ssl.c - PySSLErrorObject - -Modules/_ssl.c - PySSLCertVerificationErrorObject - -Modules/_ssl.c - PySSLZeroReturnErrorObject - -Modules/_ssl.c - PySSLWantReadErrorObject - -Modules/_ssl.c - PySSLWantWriteErrorObject - -Modules/_ssl.c - PySSLSyscallErrorObject - -Modules/_ssl.c - PySSLEOFErrorObject - Modules/_tkinter.c - Tkinter_TclError - -Modules/_xxsubinterpretersmodule.c - ChannelError - -Modules/_xxsubinterpretersmodule.c - ChannelNotFoundError - -Modules/_xxsubinterpretersmodule.c - ChannelClosedError - -Modules/_xxsubinterpretersmodule.c - ChannelEmptyError - -Modules/_xxsubinterpretersmodule.c - ChannelNotEmptyError - -Modules/_xxsubinterpretersmodule.c - RunFailedError - Modules/ossaudiodev.c - OSSAudioError - -Modules/pyexpat.c - ErrorObject - -Modules/socketmodule.c - socket_herror - -Modules/socketmodule.c - socket_gaierror - -Modules/socketmodule.c - socket_timeout - -Modules/xxlimited.c - ErrorObject - +Modules/xxlimited_35.c - ErrorObject - Modules/xxmodule.c - ErrorObject - -#----------------------- -# cached - initialized once - -# _Py_IDENTIFIER (global) -Modules/_asynciomodule.c - PyId___asyncio_running_event_loop__ - -Modules/_asynciomodule.c - PyId__asyncio_future_blocking - -Modules/_asynciomodule.c - PyId_add_done_callback - -Modules/_asynciomodule.c - PyId_call_soon - -Modules/_asynciomodule.c - PyId_cancel - -Modules/_asynciomodule.c - PyId_get_event_loop - -Modules/_asynciomodule.c - PyId_throw - -Modules/_bisectmodule.c - PyId_insert - -Modules/_datetimemodule.c - PyId_as_integer_ratio - -Modules/_datetimemodule.c - PyId_fromutc - -Modules/_datetimemodule.c - PyId_isoformat - -Modules/_datetimemodule.c - PyId_strftime - -Modules/_sqlite/connection.c - PyId_cursor - -Modules/cjkcodecs/multibytecodec.c - PyId_write - -Modules/unicodedata.c - PyId_NFC - -Modules/unicodedata.c - PyId_NFD - -Modules/unicodedata.c - PyId_NFKC - -Modules/unicodedata.c - PyId_NFKD - - -# _Py_IDENTIFIER (local) -Modules/_json.c _encoded_const PyId_false - -Modules/_json.c _encoded_const PyId_null - -Modules/_json.c _encoded_const PyId_true - -Modules/_json.c encoder_listencode_dict PyId_close_dict - -Modules/_json.c encoder_listencode_dict PyId_empty_dict - -Modules/_json.c encoder_listencode_dict PyId_open_dict - -Modules/_json.c encoder_listencode_list PyId_close_array - -Modules/_json.c encoder_listencode_list PyId_empty_array - -Modules/_json.c encoder_listencode_list PyId_open_array - -Modules/_json.c raise_errmsg PyId_JSONDecodeError - -Modules/_json.c raise_errmsg PyId_decoder - -Modules/_sqlite/connection.c final_callback PyId_finalize - -Modules/_sqlite/connection.c pysqlite_connection_execute_impl PyId_execute - -Modules/_sqlite/connection.c pysqlite_connection_executemany_impl PyId_executemany - -Modules/_sqlite/connection.c pysqlite_connection_executescript PyId_executescript - -Modules/_sqlite/connection.c pysqlite_connection_iterdump_impl PyId__iterdump - -Modules/_sqlite/module.c pysqlite_register_converter_impl PyId_upper - -Modules/pyexpat.c pyexpat_xmlparser_ParseFile_impl PyId_read - -Modules/_asynciomodule.c FutureObj_finalize PyId_call_exception_handler - -Modules/_asynciomodule.c FutureObj_finalize PyId_exception - -Modules/_asynciomodule.c FutureObj_finalize PyId_future - -Modules/_asynciomodule.c FutureObj_finalize PyId_message - -Modules/_asynciomodule.c FutureObj_finalize PyId_source_traceback - -Modules/_asynciomodule.c FutureObj_get_state PyId_CANCELLED - -Modules/_asynciomodule.c FutureObj_get_state PyId_FINISHED - -Modules/_asynciomodule.c FutureObj_get_state PyId_PENDING - -Modules/_asynciomodule.c FutureObj_repr PyId__repr_info - -Modules/_asynciomodule.c TaskObj_finalize PyId_call_exception_handler - -Modules/_asynciomodule.c TaskObj_finalize PyId_message - -Modules/_asynciomodule.c TaskObj_finalize PyId_source_traceback - -Modules/_asynciomodule.c TaskObj_finalize PyId_task - -Modules/_asynciomodule.c future_init PyId_get_debug - -Modules/_asynciomodule.c get_future_loop PyId__loop - -Modules/_asynciomodule.c get_future_loop PyId_get_loop - -Modules/_asynciomodule.c register_task PyId_add - -Modules/_asynciomodule.c unregister_task PyId_discard - -Modules/_csv.c csv_writer PyId_write - -Modules/_ctypes/_ctypes.c CDataType_from_param PyId__as_parameter_ - -Modules/_ctypes/_ctypes.c PyCArrayType_new PyId__length_ - -Modules/_ctypes/_ctypes.c PyCArrayType_new PyId__type_ - -Modules/_ctypes/_ctypes.c PyCFuncPtr_set_restype PyId__check_retval_ - -Modules/_ctypes/_ctypes.c PyCPointerType_new PyId__type_ - -Modules/_ctypes/_ctypes.c PyCPointerType_set_type PyId__type_ - -Modules/_ctypes/_ctypes.c PyCSimpleType_from_param PyId__as_parameter_ - -Modules/_ctypes/_ctypes.c PyCSimpleType_new PyId__type_ - -Modules/_ctypes/_ctypes.c StructUnionType_new PyId__abstract_ - -Modules/_ctypes/_ctypes.c StructUnionType_new PyId__fields_ - -Modules/_ctypes/_ctypes.c _build_result PyId___ctypes_from_outparam__ - -Modules/_ctypes/_ctypes.c _init_pos_args PyId__fields_ - -Modules/_ctypes/_ctypes.c c_char_p_from_param PyId__as_parameter_ - -Modules/_ctypes/_ctypes.c c_void_p_from_param PyId__as_parameter_ - -Modules/_ctypes/_ctypes.c c_wchar_p_from_param PyId__as_parameter_ - -Modules/_ctypes/_ctypes.c converters_from_argtypes PyId_from_param - -Modules/_ctypes/_ctypes.c make_funcptrtype_dict PyId__argtypes_ - -Modules/_ctypes/_ctypes.c make_funcptrtype_dict PyId__check_retval_ - -Modules/_ctypes/_ctypes.c make_funcptrtype_dict PyId__flags_ - -Modules/_ctypes/_ctypes.c make_funcptrtype_dict PyId__restype_ - -Modules/_ctypes/callproc.c ConvParam PyId__as_parameter_ - -Modules/_ctypes/callproc.c unpickle PyId___new__ - -Modules/_ctypes/callproc.c unpickle PyId___setstate__ - -Modules/_ctypes/stgdict.c MakeAnonFields PyId__anonymous_ - -Modules/_ctypes/stgdict.c PyCStructUnionType_update_stgdict PyId__pack_ - -Modules/_ctypes/stgdict.c PyCStructUnionType_update_stgdict PyId__swappedbytes_ - -Modules/_ctypes/stgdict.c PyCStructUnionType_update_stgdict PyId__use_broken_old_ctypes_structure_semantics_ - -Modules/_cursesmodule.c _curses_getwin PyId_read - -Modules/_cursesmodule.c _curses_window_putwin PyId_write - -Modules/_cursesmodule.c update_lines_cols PyId_COLS - -Modules/_cursesmodule.c update_lines_cols PyId_LINES - -Modules/_datetimemodule.c build_struct_time PyId_struct_time - -Modules/_datetimemodule.c call_tzname PyId_tzname - -Modules/_datetimemodule.c date_strftime PyId_timetuple - -Modules/_datetimemodule.c date_today PyId_fromtimestamp - -Modules/_datetimemodule.c datetime_strptime PyId__strptime_datetime - -Modules/_datetimemodule.c make_Zreplacement PyId_replace - -Modules/_datetimemodule.c time_time PyId_time - -Modules/_datetimemodule.c tzinfo_reduce PyId___getinitargs__ - -Modules/_datetimemodule.c tzinfo_reduce PyId___getstate__ - -Modules/_elementtree.c _elementtree_Element_find_impl PyId_find - -Modules/_elementtree.c _elementtree_Element_findall_impl PyId_findall - -Modules/_elementtree.c _elementtree_Element_findtext_impl PyId_findtext - -Modules/_elementtree.c _elementtree_Element_iterfind_impl PyId_iterfind - -Modules/_elementtree.c expat_start_doctype_handler PyId_doctype - -Modules/_elementtree.c treebuilder_add_subelement PyId_append - -Modules/_elementtree.c treebuilder_flush_data PyId_tail - -Modules/_elementtree.c treebuilder_flush_data PyId_text - -Modules/_gdbmmodule.c gdbm__exit__ PyId_close - -Modules/_lzmamodule.c build_filter_spec PyId_dict_size - -Modules/_lzmamodule.c build_filter_spec PyId_dist - -Modules/_lzmamodule.c build_filter_spec PyId_id - -Modules/_lzmamodule.c build_filter_spec PyId_lc - -Modules/_lzmamodule.c build_filter_spec PyId_lp - -Modules/_lzmamodule.c build_filter_spec PyId_pb - -Modules/_lzmamodule.c build_filter_spec PyId_start_offset - -Modules/_operator.c methodcaller_reduce PyId_partial - -Modules/_pickle.c _Pickle_InitState PyId_getattr - -Modules/_pickle.c _Pickler_SetOutputStream PyId_write - -Modules/_pickle.c _Unpickler_SetInputStream PyId_peek - -Modules/_pickle.c _Unpickler_SetInputStream PyId_read - -Modules/_pickle.c _Unpickler_SetInputStream PyId_readinto - -Modules/_pickle.c _Unpickler_SetInputStream PyId_readline - -Modules/_pickle.c _pickle_Pickler___init___impl PyId_dispatch_table - -Modules/_pickle.c _pickle_Pickler___init___impl PyId_persistent_id - -Modules/_pickle.c _pickle_Unpickler___init___impl PyId_persistent_load - -Modules/_pickle.c do_append PyId_append - -Modules/_pickle.c do_append PyId_extend - -Modules/_pickle.c dump PyId_reducer_override - -Modules/_pickle.c find_class PyId_find_class - -Modules/_pickle.c get_class PyId___class__ - -Modules/_pickle.c instantiate PyId___getinitargs__ - -Modules/_pickle.c instantiate PyId___new__ - -Modules/_pickle.c load_additems PyId_add - -Modules/_pickle.c load_build PyId___dict__ - -Modules/_pickle.c load_build PyId___setstate__ - -Modules/_pickle.c save PyId___reduce__ - -Modules/_pickle.c save PyId___reduce_ex__ - -Modules/_pickle.c save_bytes PyId_latin1 - -Modules/_pickle.c save_dict PyId_items - -Modules/_pickle.c save_global PyId___name__ - -Modules/_pickle.c save_global PyId___qualname__ - -Modules/_pickle.c save_reduce PyId___name__ - -Modules/_pickle.c save_reduce PyId___new__ - -Modules/_pickle.c save_reduce PyId___newobj__ - -Modules/_pickle.c save_reduce PyId___newobj_ex__ - -Modules/_pickle.c whichmodule PyId___main__ - -Modules/_pickle.c whichmodule PyId___module__ - -Modules/_pickle.c whichmodule PyId_modules - -Modules/_sqlite/connection.c _pysqlite_final_callback PyId_finalize - -Modules/_sqlite/connection.c pysqlite_connection_create_collation PyId_upper - -Modules/_sqlite/connection.c pysqlite_connection_iterdump PyId__iterdump - -Modules/_sqlite/connection.c pysqlite_connection_set_isolation_level PyId_upper - -Modules/_sqlite/cursor.c _pysqlite_get_converter PyId_upper - -Modules/_sqlite/microprotocols.c pysqlite_microprotocols_adapt PyId___adapt__ - -Modules/_sqlite/microprotocols.c pysqlite_microprotocols_adapt PyId___conform__ - -Modules/_sqlite/module.c module_register_converter PyId_upper - -Modules/_ssl.c fill_and_set_sslerror PyId_library - -Modules/_ssl.c fill_and_set_sslerror PyId_reason - -Modules/_ssl.c fill_and_set_sslerror PyId_verify_code - -Modules/_ssl.c fill_and_set_sslerror PyId_verify_message - -Modules/arraymodule.c array_array___reduce_ex__ PyId___dict__ - -Modules/arraymodule.c array_array___reduce_ex__ PyId__array_reconstructor - -Modules/arraymodule.c array_array_fromfile_impl PyId_read - -Modules/arraymodule.c array_array_tofile PyId_write - -Modules/arraymodule.c array_arrayiterator___reduce___impl PyId_iter - -Modules/mathmodule.c math_ceil PyId___ceil__ - -Modules/mathmodule.c math_floor PyId___floor__ - -Modules/mathmodule.c math_trunc PyId___trunc__ - -Modules/mmapmodule.c mmap__exit__method PyId_close - -Modules/ossaudiodev.c oss_exit PyId_close - -Modules/pyexpat.c pyexpat_xmlparser_ParseFile PyId_read - +##----------------------- +## cached - initialized once -# _Py_static_string -Modules/_pickle.c get_dotted_path PyId_dot - - -# manually cached PyUnicodeOjbect -Modules/_asynciomodule.c - context_kwname - +## manually cached PyUnicodeOjbect Modules/_ctypes/callproc.c _ctypes_get_errobj error_object_name - Modules/_ctypes/_ctypes.c CreateSwappedType suffix - -Modules/_json.c _encoded_const s_null - -Modules/_json.c _encoded_const s_true - -Modules/_json.c _encoded_const s_false - -Modules/_json.c encoder_listencode_dict open_dict - -Modules/_json.c encoder_listencode_dict close_dict - -Modules/_json.c encoder_listencode_dict empty_dict - -Modules/_json.c encoder_listencode_list open_array - -Modules/_json.c encoder_listencode_list close_array - -Modules/_json.c encoder_listencode_list empty_array - - -# _PyArg_Parser -Modules/clinic/_asynciomodule.c.h _asyncio_Future___init__ _parser - -Modules/clinic/_asynciomodule.c.h _asyncio_Future_add_done_callback _parser - -Modules/clinic/_asynciomodule.c.h _asyncio_Future_cancel _parser - -Modules/clinic/_asynciomodule.c.h _asyncio_Task___init__ _parser - -Modules/clinic/_asynciomodule.c.h _asyncio_Task_cancel _parser - -Modules/clinic/_asynciomodule.c.h _asyncio_Task_get_stack _parser - -Modules/clinic/_asynciomodule.c.h _asyncio_Task_print_stack _parser - -Modules/clinic/_asynciomodule.c.h _asyncio__enter_task _parser - -Modules/clinic/_asynciomodule.c.h _asyncio__get_event_loop _parser - -Modules/clinic/_asynciomodule.c.h _asyncio__leave_task _parser - -Modules/clinic/_asynciomodule.c.h _asyncio__register_task _parser - -Modules/clinic/_asynciomodule.c.h _asyncio__unregister_task _parser - -Modules/clinic/_bisectmodule.c.h _bisect_bisect_left _parser - -Modules/clinic/_bisectmodule.c.h _bisect_bisect_right _parser - -Modules/clinic/_bisectmodule.c.h _bisect_insort_left _parser - -Modules/clinic/_bisectmodule.c.h _bisect_insort_right _parser - -Modules/clinic/_bz2module.c.h _bz2_BZ2Decompressor_decompress _parser - -Modules/clinic/_curses_panel.c.h _curses_panel_panel_bottom _parser - -Modules/clinic/_curses_panel.c.h _curses_panel_panel_hide _parser - -Modules/clinic/_curses_panel.c.h _curses_panel_panel_move _parser - -Modules/clinic/_curses_panel.c.h _curses_panel_panel_replace _parser - -Modules/clinic/_curses_panel.c.h _curses_panel_panel_set_userptr _parser - -Modules/clinic/_curses_panel.c.h _curses_panel_panel_show _parser - -Modules/clinic/_curses_panel.c.h _curses_panel_panel_top _parser - -Modules/clinic/_curses_panel.c.h _curses_panel_panel_userptr _parser - -Modules/clinic/_cursesmodule.c.h _curses_setupterm _parser - -Modules/clinic/_datetimemodule.c.h datetime_datetime_now _parser - -Modules/clinic/_datetimemodule.c.h iso_calendar_date_new _parser - -Modules/clinic/_dbmmodule.c.h _dbm_dbm_get _parser - -Modules/clinic/_dbmmodule.c.h _dbm_dbm_keys _parser - -Modules/clinic/_dbmmodule.c.h _dbm_dbm_setdefault _parser - -Modules/clinic/_elementtree.c.h _elementtree_Element_find _parser - -Modules/clinic/_elementtree.c.h _elementtree_Element_findall _parser - -Modules/clinic/_elementtree.c.h _elementtree_Element_findtext _parser - -Modules/clinic/_elementtree.c.h _elementtree_Element_get _parser - -Modules/clinic/_elementtree.c.h _elementtree_Element_iter _parser - -Modules/clinic/_elementtree.c.h _elementtree_Element_iterfind _parser - -Modules/clinic/_elementtree.c.h _elementtree_TreeBuilder___init__ _parser - -Modules/clinic/_elementtree.c.h _elementtree_XMLParser___init__ _parser - -Modules/clinic/_gdbmmodule.c.h _gdbm_gdbm_firstkey _parser - -Modules/clinic/_gdbmmodule.c.h _gdbm_gdbm_keys _parser - -Modules/clinic/_gdbmmodule.c.h _gdbm_gdbm_nextkey _parser - -Modules/clinic/_gdbmmodule.c.h _gdbm_gdbm_reorganize _parser - -Modules/clinic/_gdbmmodule.c.h _gdbm_gdbm_sync _parser - -Modules/clinic/_hashopenssl.c.h EVP_new _parser - -Modules/clinic/_hashopenssl.c.h _hashlib_HMAC_update _parser - -Modules/clinic/_hashopenssl.c.h _hashlib_hmac_new _parser - -Modules/clinic/_hashopenssl.c.h _hashlib_hmac_singleshot _parser - -Modules/clinic/_hashopenssl.c.h _hashlib_openssl_md5 _parser - -Modules/clinic/_hashopenssl.c.h _hashlib_openssl_sha1 _parser - -Modules/clinic/_hashopenssl.c.h _hashlib_openssl_sha224 _parser - -Modules/clinic/_hashopenssl.c.h _hashlib_openssl_sha256 _parser - -Modules/clinic/_hashopenssl.c.h _hashlib_openssl_sha384 _parser - -Modules/clinic/_hashopenssl.c.h _hashlib_openssl_sha512 _parser - -Modules/clinic/_hashopenssl.c.h pbkdf2_hmac _parser - -Modules/clinic/_lsprof.c.h _lsprof_Profiler_getstats _parser - -Modules/clinic/_lzmamodule.c.h _lzma_LZMADecompressor___init__ _parser - -Modules/clinic/_lzmamodule.c.h _lzma_LZMADecompressor_decompress _parser - -Modules/clinic/_opcode.c.h _opcode_stack_effect _parser - -Modules/clinic/_pickle.c.h _pickle_Pickler___init__ _parser - -Modules/clinic/_pickle.c.h _pickle_Unpickler___init__ _parser - -Modules/clinic/_pickle.c.h _pickle_dump _parser - -Modules/clinic/_pickle.c.h _pickle_dumps _parser - -Modules/clinic/_pickle.c.h _pickle_load _parser - -Modules/clinic/_pickle.c.h _pickle_loads _parser - -Modules/clinic/_queuemodule.c.h _queue_SimpleQueue_get _parser - -Modules/clinic/_queuemodule.c.h _queue_SimpleQueue_get_nowait _parser - -Modules/clinic/_queuemodule.c.h _queue_SimpleQueue_put _parser - -Modules/clinic/_queuemodule.c.h _queue_SimpleQueue_put_nowait _parser - -Modules/clinic/_ssl.c.h _ssl__SSLContext__wrap_bio _parser - -Modules/clinic/_ssl.c.h _ssl__SSLContext__wrap_socket _parser - -Modules/clinic/_ssl.c.h _ssl__SSLContext_get_ca_certs _parser - -Modules/clinic/_ssl.c.h _ssl__SSLContext_load_cert_chain _parser - -Modules/clinic/_ssl.c.h _ssl__SSLContext_load_verify_locations _parser - -Modules/clinic/_ssl.c.h _ssl__SSLSocket_get_channel_binding _parser - -Modules/clinic/_ssl.c.h _ssl_txt2obj _parser - -Modules/clinic/_struct.c.h Struct___init__ _parser - -Modules/clinic/_struct.c.h Struct_unpack_from _parser - -Modules/clinic/_struct.c.h unpack_from _parser - -Modules/clinic/_testmultiphase.c.h _testmultiphase_StateAccessType_get_count _parser - -Modules/clinic/_testmultiphase.c.h _testmultiphase_StateAccessType_get_defining_module _parser - -Modules/clinic/_testmultiphase.c.h _testmultiphase_StateAccessType_getmodulebydef_bad_def _parser - -Modules/clinic/_testmultiphase.c.h _testmultiphase_StateAccessType_increment_count_clinic _parser - -Modules/clinic/_winapi.c.h _winapi_ConnectNamedPipe _parser - -Modules/clinic/_winapi.c.h _winapi_GetFileType _parser - -Modules/clinic/_winapi.c.h _winapi_ReadFile _parser - -Modules/clinic/_winapi.c.h _winapi_WriteFile _parser - -Modules/clinic/_winapi.c.h _winapi__mimetypes_read_windows_registry _parser - -Modules/clinic/arraymodule.c.h array_array_extend _parser - -Modules/clinic/binascii.c.h binascii_a2b_base64 _parser - -Modules/clinic/binascii.c.h binascii_a2b_qp _parser - -Modules/clinic/binascii.c.h binascii_b2a_base64 _parser - -Modules/clinic/binascii.c.h binascii_b2a_hex _parser - -Modules/clinic/binascii.c.h binascii_b2a_qp _parser - -Modules/clinic/binascii.c.h binascii_b2a_uu _parser - -Modules/clinic/binascii.c.h binascii_hexlify _parser - -Modules/clinic/cmathmodule.c.h cmath_isclose _parser - -Modules/clinic/grpmodule.c.h grp_getgrgid _parser - -Modules/clinic/grpmodule.c.h grp_getgrnam _parser - -Modules/clinic/mathmodule.c.h math_isclose _parser - -Modules/clinic/mathmodule.c.h math_prod _parser - -Modules/clinic/md5module.c.h MD5Type_copy _parser - -Modules/clinic/md5module.c.h _md5_md5 _parser - -Modules/clinic/overlapped.c.h _overlapped_Overlapped _parser - -Modules/clinic/pyexpat.c.h pyexpat_ParserCreate _parser - -Modules/clinic/pyexpat.c.h pyexpat_xmlparser_ExternalEntityParserCreate _parser - -Modules/clinic/pyexpat.c.h pyexpat_xmlparser_Parse _parser - -Modules/clinic/pyexpat.c.h pyexpat_xmlparser_ParseFile _parser - -Modules/clinic/sha1module.c.h SHA1Type_copy _parser - -Modules/clinic/sha1module.c.h _sha1_sha1 _parser - -Modules/clinic/sha256module.c.h SHA256Type_copy _parser - -Modules/clinic/sha256module.c.h _sha256_sha224 _parser - -Modules/clinic/sha256module.c.h _sha256_sha256 _parser - -Modules/clinic/sha512module.c.h SHA512Type_copy _parser - -Modules/clinic/sha512module.c.h _sha512_sha384 _parser - -Modules/clinic/sha512module.c.h _sha512_sha512 _parser - -Modules/clinic/zlibmodule.c.h zlib_Compress_compress _parser - -Modules/clinic/zlibmodule.c.h zlib_Compress_flush _parser - -Modules/clinic/zlibmodule.c.h zlib_Decompress_decompress _parser - -Modules/clinic/zlibmodule.c.h zlib_Decompress_flush _parser - -Modules/clinic/zlibmodule.c.h zlib_compress _parser - -Modules/clinic/zlibmodule.c.h zlib_compressobj _parser - -Modules/clinic/zlibmodule.c.h zlib_decompress _parser - -Modules/clinic/zlibmodule.c.h zlib_decompressobj _parser - -# other - during module init -Modules/_asynciomodule.c - asyncio_mod - -Modules/_asynciomodule.c - traceback_extract_stack - -Modules/_asynciomodule.c - asyncio_get_event_loop_policy - -Modules/_asynciomodule.c - asyncio_future_repr_info_func - -Modules/_asynciomodule.c - asyncio_iscoroutine_func - -Modules/_asynciomodule.c - asyncio_task_get_stack_func - -Modules/_asynciomodule.c - asyncio_task_print_stack_func - -Modules/_asynciomodule.c - asyncio_task_repr_info_func - -Modules/_asynciomodule.c - asyncio_InvalidStateError - -Modules/_asynciomodule.c - asyncio_CancelledError - -Modules/_zoneinfo.c - io_open - -Modules/_zoneinfo.c - _tzpath_find_tzfile - -Modules/_zoneinfo.c - _common_mod - +##----------------------- +## other -#----------------------- -# other - -# initialized once +## initialized once Modules/_ctypes/_ctypes.c - _unpickle - Modules/_ctypes/_ctypes.c PyCArrayType_from_ctype cache - Modules/_cursesmodule.c - ModDict - @@ -1266,7 +431,6 @@ Modules/_datetimemodule.c - us_per_hour - Modules/_datetimemodule.c - us_per_day - Modules/_datetimemodule.c - us_per_week - Modules/_datetimemodule.c - seconds_per_day - -Modules/_decimal/_decimal.c PyInit__decimal capsule - Modules/_decimal/_decimal.c - basic_context_template - Modules/_decimal/_decimal.c - current_context_var - Modules/_decimal/_decimal.c - default_context_template - @@ -1274,87 +438,50 @@ Modules/_decimal/_decimal.c - extended_context_template - Modules/_decimal/_decimal.c - round_map - Modules/_decimal/_decimal.c - Rational - Modules/_decimal/_decimal.c - SignalTuple - -Modules/_json.c raise_errmsg JSONDecodeError - -Modules/_sqlite/microprotocols.c - psyco_adapters - -Modules/_sqlite/module.h - _pysqlite_converters - -Modules/_ssl.c - err_codes_to_names - -Modules/_ssl.c - err_names_to_codes - -Modules/_ssl.c - lib_codes_to_names - -# XXX This should have been found by the analyzer but wasn't: -Modules/_ssl.c - _ssl_locks - -Modules/_struct.c - cache - -Modules/arraymodule.c array_array___reduce_ex__ array_reconstructor - -Modules/cjkcodecs/cjkcodecs.h getmultibytecodec cofunc - -# state -Modules/_asynciomodule.c - cached_running_holder - +## state Modules/_asynciomodule.c - fi_freelist - Modules/_asynciomodule.c - fi_freelist_len - -Modules/_asynciomodule.c - all_tasks - -Modules/_asynciomodule.c - current_tasks - -Modules/_asynciomodule.c - iscoroutine_typecache - Modules/_ctypes/_ctypes.c - _ctypes_ptrtype_cache - +Modules/_ctypes/_ctypes.c - global_state - +Modules/_ctypes/ctypes.h - global_state - Modules/_tkinter.c - tcl_lock - Modules/_tkinter.c - excInCmd - Modules/_tkinter.c - valInCmd - Modules/_tkinter.c - trbInCmd - -Modules/_zoneinfo.c - TIMEDELTA_CACHE - -Modules/_zoneinfo.c - ZONEINFO_WEAK_CACHE - -Modules/syslogmodule.c - S_ident_o - -Modules/xxlimited_35.c - ErrorObject - ################################## -# global non-objects to fix in extension modules +## global non-objects to fix in extension modules -#----------------------- -# initialized once +##----------------------- +## initialized once -# pre-allocated buffer +## pre-allocated buffer Modules/nismodule.c nisproc_maplist_2 res - -Modules/pyexpat.c PyUnknownEncodingHandler template_buffer - -# other +## other Include/datetime.h - PyDateTimeAPI - -Modules/_asynciomodule.c - module_initialized - Modules/_ctypes/cfield.c _ctypes_get_fielddesc initialized - Modules/_ctypes/malloc_closure.c - _pagesize - Modules/_cursesmodule.c - initialised - Modules/_cursesmodule.c - initialised_setupterm - Modules/_cursesmodule.c - initialisedcolors - Modules/_cursesmodule.c - screen_encoding - -Modules/_cursesmodule.c PyInit__curses PyCurses_API - -Modules/_datetimemodule.c - CAPI - -Modules/_decimal/_decimal.c PyInit__decimal initialized - Modules/_decimal/_decimal.c - _py_long_multiply - Modules/_decimal/_decimal.c - _py_long_floor_divide - Modules/_decimal/_decimal.c - _py_long_power - Modules/_decimal/_decimal.c - _py_float_abs - Modules/_decimal/_decimal.c - _py_long_bit_length - Modules/_decimal/_decimal.c - _py_float_as_integer_ratio - -Modules/_decimal/_decimal.c - _decimal_api - Modules/_elementtree.c - expat_capi - -Modules/_sqlite/module.h - _pysqlite_enable_callback_tracebacks - -Modules/_sqlite/module.h - pysqlite_BaseTypeAdapted - -Modules/_ssl.c - _ssl_locks_count - -Modules/cjkcodecs/cjkcodecs.h - codec_list - -Modules/cjkcodecs/cjkcodecs.h - mapping_list - -Modules/getaddrinfo.c - gai_afdl - -Modules/pyexpat.c PyInit_pyexpat capi - Modules/readline.c - libedit_append_replace_history_offset - Modules/readline.c - using_libedit_emulation - Modules/readline.c - libedit_history_start - -Modules/resource.c - initialized - -Modules/socketmodule.c - accept4_works - -Modules/socketmodule.c - sock_cloexec_works - -Modules/socketmodule.c - PySocketModuleAPI - -Modules/spwdmodule.c - initialized - -#----------------------- -# state +##----------------------- +## state -Modules/_asynciomodule.c - cached_running_holder_tsid - -Modules/_asynciomodule.c - task_name_counter - Modules/_ctypes/cfield.c - formattable - Modules/_ctypes/malloc_closure.c - free_list - Modules/_curses_panel.c - lop - @@ -1368,10 +495,6 @@ Modules/_tkinter.c - command_mutex - Modules/_tkinter.c - HeadFHCD - Modules/_tkinter.c - stdin_ready - Modules/_tkinter.c - event_tstate - -Modules/_xxsubinterpretersmodule.c - _globals - -Modules/_zoneinfo.c - ZONEINFO_STRONG_CACHE - -Modules/_zoneinfo.c - ZONEINFO_STRONG_CACHE_MAX_SIZE - -Modules/_zoneinfo.c - NO_TTINFO - Modules/readline.c - completer_word_break_characters - Modules/readline.c - _history_length - Modules/readline.c - should_auto_add_history - @@ -1380,5 +503,3 @@ Modules/readline.c - sigwinch_ohandler - Modules/readline.c - completed_input_string - Modules/rotatingtree.c - random_stream - Modules/rotatingtree.c - random_value - -Modules/socketmodule.c - defaulttimeout - -Modules/syslogmodule.c - S_log_open - diff --git a/Tools/c-analyzer/cpython/ignored.tsv b/Tools/c-analyzer/cpython/ignored.tsv index 63d0695b..6a7c14eb 100644 --- a/Tools/c-analyzer/cpython/ignored.tsv +++ b/Tools/c-analyzer/cpython/ignored.tsv @@ -1,74 +1,375 @@ filename funcname name reason #??? - somevar ??? +# All globals here are technically mutable but known to be safe. + + ################################## -# ignored by design +## process-global values - set once -Python/pylifecycle.c - _PyRuntime - +# These will never re-initialize (but would be idempotent). +# These are effectively const. + +##----------------------- +## process-global resources + +## indicators for resource availability/capability +# (set during first init) +Python/bootstrap_hash.c py_getrandom getrandom_works - +Python/fileutils.c - _Py_open_cloexec_works - +Python/fileutils.c set_inheritable ioctl_works - +# (set lazily, *after* first init) +# XXX Is this thread-safe? +Modules/posixmodule.c os_dup2_impl dup3_works - + +## guards around resource init +Python/thread_pthread.h PyThread__init_thread lib_initialized - + +##----------------------- +## other values (not Python-specific) + +## cached computed data - set lazily (*after* first init) +# XXX Are these safe relative to write races? +Objects/longobject.c long_from_non_binary_base log_base_BASE - +Objects/longobject.c long_from_non_binary_base convwidth_base - +Objects/longobject.c long_from_non_binary_base convmultmax_base - +Objects/unicodeobject.c - bloom_linebreak - +# This is safe: +Objects/unicodeobject.c _init_global_state initialized - + +##----------------------- +## other values (Python-specific) + +## internal state - set before/during first init +Modules/getbuildinfo.c - buildinfo - +Modules/getbuildinfo.c - initialized - +Python/getversion.c - initialized - +Python/getversion.c - version - + +## public C-API - set during first init +Python/bootstrap_hash.c - _Py_HashSecret_Initialized - +Python/pyhash.c - _Py_HashSecret - ################################## -# forward/extern references -# XXX The analyzer should have ignored these. +## state tied to Py_Main() +# (only in main thread) -Include/py_curses.h - PyCurses_API - -Include/pydecimal.h - _decimal_api - -Modules/_blake2/blake2module.c - blake2b_type_spec - -Modules/_blake2/blake2module.c - blake2s_type_spec - -Modules/_io/fileio.c - _Py_open_cloexec_works - -Modules/_io/_iomodule.h - PyIOBase_Type - -Modules/_io/_iomodule.h - PyRawIOBase_Type - -Modules/_io/_iomodule.h - PyBufferedIOBase_Type - -Modules/_io/_iomodule.h - PyTextIOBase_Type - -Modules/_io/_iomodule.h - PyFileIO_Type - -Modules/_io/_iomodule.h - PyBytesIO_Type - -Modules/_io/_iomodule.h - PyStringIO_Type - -Modules/_io/_iomodule.h - PyBufferedReader_Type - -Modules/_io/_iomodule.h - PyBufferedWriter_Type - -Modules/_io/_iomodule.h - PyBufferedRWPair_Type - -Modules/_io/_iomodule.h - PyBufferedRandom_Type - -Modules/_io/_iomodule.h - PyTextIOWrapper_Type - -Modules/_io/_iomodule.h - PyIncrementalNewlineDecoder_Type - -Modules/_io/_iomodule.h - _PyBytesIOBuffer_Type - -Modules/_io/_iomodule.h - _PyIO_str_close - -Modules/_io/_iomodule.h - _PyIO_str_closed - -Modules/_io/_iomodule.h - _PyIO_str_decode - -Modules/_io/_iomodule.h - _PyIO_str_encode - -Modules/_io/_iomodule.h - _PyIO_str_fileno - -Modules/_io/_iomodule.h - _PyIO_str_flush - -Modules/_io/_iomodule.h - _PyIO_str_getstate - -Modules/_io/_iomodule.h - _PyIO_str_isatty - -Modules/_io/_iomodule.h - _PyIO_str_newlines - -Modules/_io/_iomodule.h - _PyIO_str_nl - -Modules/_io/_iomodule.h - _PyIO_str_peek - -Modules/_io/_iomodule.h - _PyIO_str_read - -Modules/_io/_iomodule.h - _PyIO_str_read1 - -Modules/_io/_iomodule.h - _PyIO_str_readable - -Modules/_io/_iomodule.h - _PyIO_str_readall - -Modules/_io/_iomodule.h - _PyIO_str_readinto - -Modules/_io/_iomodule.h - _PyIO_str_readline - -Modules/_io/_iomodule.h - _PyIO_str_reset - -Modules/_io/_iomodule.h - _PyIO_str_seek - -Modules/_io/_iomodule.h - _PyIO_str_seekable - -Modules/_io/_iomodule.h - _PyIO_str_setstate - -Modules/_io/_iomodule.h - _PyIO_str_tell - -Modules/_io/_iomodule.h - _PyIO_str_truncate - -Modules/_io/_iomodule.h - _PyIO_str_writable - -Modules/_io/_iomodule.h - _PyIO_str_write - -Modules/_io/_iomodule.h - _PyIO_empty_str - -Modules/_io/_iomodule.h - _PyIO_empty_bytes - -Modules/_multiprocessing/multiprocessing.h - _PyMp_SemLockType - -Modules/_sqlite/module.c - _pysqlite_converters - -Modules/_sqlite/module.c - _pysqlite_enable_callback_tracebacks - -Modules/_sqlite/module.c - pysqlite_BaseTypeAdapted - -Modules/_sqlite/module.h - pysqlite_global_state - -Modules/_testcapimodule.c - _PyBytesIOBuffer_Type - -Modules/posixmodule.c - _Py_open_cloexec_works - -Python/importdl.h - _PyImport_DynLoadFiletab - +##----------------------- +## handling C argv + +Python/getopt.c - _PyOS_optarg - +Python/getopt.c - _PyOS_opterr - +Python/getopt.c - _PyOS_optind - +Python/getopt.c - opt_ptr - +Python/pathconfig.c - _Py_path_config - + +##----------------------- +## REPL + +Parser/myreadline.c - _PyOS_ReadlineLock - +Parser/myreadline.c - _PyOS_ReadlineTState - +Parser/myreadline.c - PyOS_InputHook - +Parser/myreadline.c - PyOS_ReadlineFunctionPointer - + + +################################## +## runtime-global values - set once with each init + +# These are effectively const. + +##----------------------- +## set by embedders before init +# (whether directly or through a call) + +Python/initconfig.c - _Py_StandardStreamEncoding - +Python/initconfig.c - _Py_StandardStreamErrors - + +##----------------------- +## public C-API + +## deprecated +Python/preconfig.c - Py_FileSystemDefaultEncoding - +Python/preconfig.c - Py_HasFileSystemDefaultEncoding - +Python/preconfig.c - Py_FileSystemDefaultEncodeErrors - +Python/preconfig.c - _Py_HasFileSystemDefaultEncodeErrors - + +## legacy config flags +Python/initconfig.c - Py_UTF8Mode - +Python/initconfig.c - Py_DebugFlag - +Python/initconfig.c - Py_VerboseFlag - +Python/initconfig.c - Py_QuietFlag - +Python/initconfig.c - Py_InteractiveFlag - +Python/initconfig.c - Py_InspectFlag - +Python/initconfig.c - Py_OptimizeFlag - +Python/initconfig.c - Py_NoSiteFlag - +Python/initconfig.c - Py_BytesWarningFlag - +Python/initconfig.c - Py_FrozenFlag - +Python/initconfig.c - Py_IgnoreEnvironmentFlag - +Python/initconfig.c - Py_DontWriteBytecodeFlag - +Python/initconfig.c - Py_NoUserSiteDirectory - +Python/initconfig.c - Py_UnbufferedStdioFlag - +Python/initconfig.c - Py_HashRandomizationFlag - +Python/initconfig.c - Py_IsolatedFlag - +Python/initconfig.c - Py_LegacyWindowsFSEncodingFlag - +Python/initconfig.c - Py_LegacyWindowsStdioFlag - + +##----------------------- +## initialized statically, may be customized by embedders + +Python/frozen.c - PyImport_FrozenModules - +Python/import.c - inittab_copy - +Python/import.c - PyImport_Inittab - ################################## -# test code +## runtime-global state + +##----------------------- +## tied to each init/fini cycle + +## the consolidated runtime state +Python/pylifecycle.c - _PyRuntime - +Python/pylifecycle.c - runtime_initialized - + +# All cases of _PyArg_Parser are handled in c-analyzr/cpython/_analyzer.py. + +## main interp state in stdlib modules +Modules/syslogmodule.c - S_ident_o - +Modules/syslogmodule.c - S_log_open - + +##----------------------- +## kept for stable ABI compatibility + +Objects/object.c - _Py_RefTotal - + +##----------------------- +## one-off temporary state + +# used during runtime init +Python/sysmodule.c - _preinit_warnoptions - +Python/sysmodule.c - _preinit_xoptions - + +# thread-safety +# XXX need race protection? +Modules/faulthandler.c faulthandler_dump_traceback reentrant - +Python/pylifecycle.c _Py_FatalErrorFormat reentrant - +Python/pylifecycle.c fatal_error reentrant - + +# explicitly protected, internal-only +Modules/_xxinterpchannelsmodule.c - _globals - + + +################################## +## not significant + +##----------------------- +## not used (kept for compatibility) + +Python/pyfpe.c - PyFPE_counter - + +##----------------------- +## thread-local variables + +Python/import.c - pkgcontext - +Python/pystate.c - _Py_tss_tstate - + +##----------------------- +## should be const +# XXX Make them const. + +# These are all variables that we will be leaving global. + +# All module defs, type defs, etc. are handled in c-analyzr/cpython/_analyzer.py. +# All kwlist arrays are handled in c-analyzr/cpython/_analyzer.py. + +# other vars that are actually constant + +Include/internal/pycore_blocks_output_buffer.h - BUFFER_BLOCK_SIZE - +Modules/_csv.c - quote_styles - +Modules/_ctypes/cfield.c - ffi_type_double - +Modules/_ctypes/cfield.c - ffi_type_float - +Modules/_ctypes/cfield.c - ffi_type_longdouble - +Modules/_ctypes/cfield.c - ffi_type_pointer - +Modules/_ctypes/cfield.c - ffi_type_sint16 - +Modules/_ctypes/cfield.c - ffi_type_sint32 - +Modules/_ctypes/cfield.c - ffi_type_sint64 - +Modules/_ctypes/cfield.c - ffi_type_sint8 - +Modules/_ctypes/cfield.c - ffi_type_uint16 - +Modules/_ctypes/cfield.c - ffi_type_uint32 - +Modules/_ctypes/cfield.c - ffi_type_uint64 - +Modules/_ctypes/cfield.c - ffi_type_uint8 - +Modules/_ctypes/cfield.c - ffi_type_void - +Modules/_datetimemodule.c - epoch - +Modules/_datetimemodule.c - max_fold_seconds - +Modules/_datetimemodule.c datetime_isoformat specs - +Modules/_datetimemodule.c parse_hh_mm_ss_ff correction - +Modules/_datetimemodule.c time_isoformat specs - +Modules/_decimal/_decimal.c - cond_map - +Modules/_decimal/_decimal.c - dec_signal_string - +Modules/_decimal/_decimal.c - dflt_ctx - +Modules/_decimal/_decimal.c - int_constants - +Modules/_decimal/_decimal.c - invalid_rounding_err - +Modules/_decimal/_decimal.c - invalid_signals_err - +Modules/_decimal/_decimal.c - signal_map - +Modules/_decimal/_decimal.c - ssize_constants - +Modules/_decimal/_decimal.c - INVALID_SIGNALDICT_ERROR_MSG - +Modules/_elementtree.c - ExpatMemoryHandler - +Modules/_hashopenssl.c - py_hashes - +Modules/_hacl/Hacl_Hash_SHA1.c - _h0 - +Modules/_hacl/Hacl_Hash_MD5.c - _h0 - +Modules/_hacl/Hacl_Hash_MD5.c - _t - +Modules/_io/_iomodule.c - static_types - +Modules/_io/textio.c - encodefuncs - +Modules/_io/winconsoleio.c - _PyWindowsConsoleIO_Type - +Modules/_localemodule.c - langinfo_constants - +Modules/_lsprof.c - callback_table - +Modules/_pickle.c - READ_WHOLE_LINE - +Modules/_sqlite/module.c - error_codes - +Modules/_sre/sre.c pattern_repr flag_names - +# XXX I'm pretty sure this is actually constant: +Modules/_sre/sre_targets.h - sre_targets - +Modules/_sre.c pattern_repr flag_names - +Modules/_struct.c - bigendian_table - +Modules/_struct.c - lilendian_table - +Modules/_struct.c - native_table - +Modules/_tkinter.c - state_key - +Modules/_xxinterpchannelsmodule.c - _channelid_end_recv - +Modules/_xxinterpchannelsmodule.c - _channelid_end_send - +Modules/_zoneinfo.c - DAYS_BEFORE_MONTH - +Modules/_zoneinfo.c - DAYS_IN_MONTH - +Modules/_xxsubinterpretersmodule.c - no_exception - +Modules/arraymodule.c - descriptors - +Modules/arraymodule.c - emptybuf - +Modules/cjkcodecs/_codecs_cn.c - _mapping_list - +Modules/cjkcodecs/_codecs_cn.c - mapping_list - +Modules/cjkcodecs/_codecs_cn.c - _codec_list - +Modules/cjkcodecs/_codecs_cn.c - codec_list - +Modules/cjkcodecs/_codecs_hk.c - big5hkscs_pairenc_table - +Modules/cjkcodecs/_codecs_hk.c - _mapping_list - +Modules/cjkcodecs/_codecs_hk.c - mapping_list - +Modules/cjkcodecs/_codecs_hk.c - _codec_list - +Modules/cjkcodecs/_codecs_hk.c - codec_list - +Modules/cjkcodecs/_codecs_iso2022.c - iso2022_kr_config - +Modules/cjkcodecs/_codecs_iso2022.c - iso2022_jp_config - +Modules/cjkcodecs/_codecs_iso2022.c - iso2022_jp_1_config - +Modules/cjkcodecs/_codecs_iso2022.c - iso2022_jp_2_config - +Modules/cjkcodecs/_codecs_iso2022.c - iso2022_jp_2004_config - +Modules/cjkcodecs/_codecs_iso2022.c - iso2022_jp_3_config - +Modules/cjkcodecs/_codecs_iso2022.c - iso2022_jp_ext_config - +Modules/cjkcodecs/_codecs_iso2022.c - _mapping_list - +Modules/cjkcodecs/_codecs_iso2022.c - mapping_list - +Modules/cjkcodecs/_codecs_iso2022.c - _codec_list - +Modules/cjkcodecs/_codecs_iso2022.c - codec_list - +Modules/cjkcodecs/_codecs_jp.c - _mapping_list - +Modules/cjkcodecs/_codecs_jp.c - mapping_list - +Modules/cjkcodecs/_codecs_jp.c - _codec_list - +Modules/cjkcodecs/_codecs_jp.c - codec_list - +Modules/cjkcodecs/_codecs_kr.c - u2johabjamo - +Modules/cjkcodecs/_codecs_kr.c - _mapping_list - +Modules/cjkcodecs/_codecs_kr.c - mapping_list - +Modules/cjkcodecs/_codecs_kr.c - _codec_list - +Modules/cjkcodecs/_codecs_kr.c - codec_list - +Modules/cjkcodecs/_codecs_tw.c - _mapping_list - +Modules/cjkcodecs/_codecs_tw.c - mapping_list - +Modules/cjkcodecs/_codecs_tw.c - _codec_list - +Modules/cjkcodecs/_codecs_tw.c - codec_list - +Modules/cjkcodecs/cjkcodecs.h - __methods - +Modules/cmathmodule.c - acos_special_values - +Modules/cmathmodule.c - acosh_special_values - +Modules/cmathmodule.c - asinh_special_values - +Modules/cmathmodule.c - atanh_special_values - +Modules/cmathmodule.c - cosh_special_values - +Modules/cmathmodule.c - exp_special_values - +Modules/cmathmodule.c - log_special_values - +Modules/cmathmodule.c - rect_special_values - +Modules/cmathmodule.c - sinh_special_values - +Modules/cmathmodule.c - sqrt_special_values - +Modules/cmathmodule.c - tanh_special_values - +Modules/config.c - _PyImport_Inittab - +Modules/faulthandler.c - faulthandler_handlers - +Modules/getnameinfo.c - gni_afdl - +Modules/nismodule.c - TIMEOUT - +Modules/nismodule.c - aliases - +Modules/ossaudiodev.c - control_labels - +Modules/ossaudiodev.c - control_names - +Modules/posixmodule.c os_getxattr_impl buffer_sizes - +Modules/posixmodule.c os_listxattr_impl buffer_sizes - +Modules/posixmodule.c - posix_constants_confstr - +Modules/posixmodule.c - posix_constants_pathconf - +Modules/posixmodule.c - posix_constants_sysconf - +Modules/pyexpat.c - ExpatMemoryHandler - +Modules/pyexpat.c - error_info_of - +Modules/pyexpat.c - handler_info - +Modules/termios.c - termios_constants - +Modules/timemodule.c init_timezone YEAR - +Objects/bytearrayobject.c - _PyByteArray_empty_string - +Objects/complexobject.c - c_1 - +Objects/exceptions.c - static_exceptions - +Objects/genobject.c - ASYNC_GEN_IGNORED_EXIT_MSG - +Objects/genobject.c - NON_INIT_CORO_MSG - +Objects/longobject.c - _PyLong_DigitValue - +Objects/object.c - _Py_SwappedOp - +Objects/object.c - _Py_abstract_hack - +Objects/object.c - last_final_reftotal - +Objects/object.c - static_types - +Objects/obmalloc.c - _PyMem - +Objects/obmalloc.c - _PyMem_Debug - +Objects/obmalloc.c - _PyMem_Raw - +Objects/obmalloc.c - _PyObject - +Objects/obmalloc.c - last_final_leaks - +Objects/obmalloc.c - usedpools - +Objects/typeobject.c - name_op - +Objects/typeobject.c - slotdefs - +Objects/unicodeobject.c - stripfuncnames - +Objects/unicodeobject.c - utf7_category - +Objects/unicodeobject.c unicode_decode_call_errorhandler_wchar argparse - +Objects/unicodeobject.c unicode_decode_call_errorhandler_writer argparse - +Objects/unicodeobject.c unicode_encode_call_errorhandler argparse - +Objects/unicodeobject.c unicode_translate_call_errorhandler argparse - +Parser/parser.c - reserved_keywords - +Parser/parser.c - soft_keywords - +Parser/tokenizer.c - type_comment_prefix - +Python/ast_opt.c fold_unaryop ops - +Python/ceval.c - binary_ops - +Python/codecs.c - Py_hexdigits - +Python/codecs.c - ucnhash_capi - +Python/codecs.c _PyCodecRegistry_Init methods - +Python/compile.c - NO_LABEL - +Python/compile.c - NO_LOCATION - +Python/dynload_shlib.c - _PyImport_DynLoadFiletab - +Python/dynload_stub.c - _PyImport_DynLoadFiletab - +Python/frozen.c - aliases - +Python/frozen.c - bootstrap_modules - +Python/frozen.c - stdlib_modules - +Python/frozen.c - test_modules - +Python/frozen.c - _PyImport_FrozenAliases - +Python/frozen.c - _PyImport_FrozenBootstrap - +Python/frozen.c - _PyImport_FrozenStdlib - +Python/frozen.c - _PyImport_FrozenTest - +Python/getopt.c - longopts - +Python/import.c - _PyImport_Inittab - +Python/import.c - _PySys_ImplCacheTag - +Python/intrinsics.c - _PyIntrinsics_UnaryFunctions - +Python/intrinsics.c - _PyIntrinsics_BinaryFunctions - +Python/opcode_targets.h - opcode_targets - +Python/perf_trampoline.c - _Py_perfmap_callbacks - +Python/pyhash.c - PyHash_Func - +Python/pylifecycle.c - _C_LOCALE_WARNING - +Python/pylifecycle.c - _PyOS_mystrnicmp_hack - +Python/pylifecycle.c - _TARGET_LOCALES - +Python/pylifecycle.c - INTERPRETER_TRAMPOLINE_CODEDEF - +Python/pystate.c - initial - +Python/specialize.c - adaptive_opcodes - +Python/specialize.c - cache_requirements - +Python/stdlib_module_names.h - _Py_stdlib_module_names - +Python/sysmodule.c - perf_map_state - +Python/sysmodule.c - _PySys_ImplCacheTag - +Python/sysmodule.c - _PySys_ImplName - +Python/sysmodule.c - whatstrings - + +##----------------------- +## test code Modules/_ctypes/_ctypes_test.c - _ctypes_test_slots - Modules/_ctypes/_ctypes_test.c - _ctypes_testmodule - @@ -112,6 +413,27 @@ Modules/_testbuffer.c ndarray_memoryview_from_buffer strides - Modules/_testbuffer.c ndarray_memoryview_from_buffer suboffsets - Modules/_testbuffer.c ndarray_push kwlist - Modules/_testbuffer.c staticarray_init kwlist - +Modules/_testcapi/buffer.c - testBufType - +Modules/_testcapi/code.c get_code_extra_index key - +Modules/_testcapi/datetime.c - test_run_counter - +Modules/_testcapi/exceptions.c - PyRecursingInfinitelyError_Type - +Modules/_testcapi/heaptype.c - _testcapimodule - +Modules/_testcapi/mem.c - FmData - +Modules/_testcapi/mem.c - FmHook - +Modules/_testcapi/structmember.c - test_structmembersType_OldAPI - +Modules/_testcapi/unicode.c - _testcapimodule - +Modules/_testcapi/watchers.c - g_dict_watch_events - +Modules/_testcapi/watchers.c - g_dict_watchers_installed - +Modules/_testcapi/watchers.c - g_type_modified_events - +Modules/_testcapi/watchers.c - g_type_watchers_installed - +Modules/_testcapi/watchers.c - code_watcher_ids - +Modules/_testcapi/watchers.c - num_code_object_created_events - +Modules/_testcapi/watchers.c - num_code_object_destroyed_events - +Modules/_testcapi/watchers.c - pyfunc_watchers - +Modules/_testcapi/watchers.c - func_watcher_ids - +Modules/_testcapi/watchers.c - func_watcher_callbacks - +Modules/_testcapimodule.c - BasicStaticTypes - +Modules/_testcapimodule.c - num_basic_static_types_used - Modules/_testcapimodule.c - ContainerNoGC_members - Modules/_testcapimodule.c - ContainerNoGC_type - Modules/_testcapimodule.c - FmData - @@ -178,14 +500,17 @@ Modules/_testcapimodule.c - meth_static_methods - Modules/_testcapimodule.c - ml - Modules/_testcapimodule.c - str1 - Modules/_testcapimodule.c - str2 - +Modules/_testcapimodule.c - test_c_thread - Modules/_testcapimodule.c - test_members - Modules/_testcapimodule.c - test_run_counter - Modules/_testcapimodule.c - test_structmembersType - Modules/_testcapimodule.c - thread_done - Modules/_testcapimodule.c - x - +Modules/_testcapimodule.c - wait_done - Modules/_testcapimodule.c getargs_keyword_only keywords - Modules/_testcapimodule.c getargs_keywords keywords - Modules/_testcapimodule.c getargs_positional_only_and_keywords keywords - +Modules/_testcapimodule.c getargs_s_hash_int2 keywords static char*[] Modules/_testcapimodule.c make_exception_with_doc kwlist - Modules/_testcapimodule.c raise_SIGINT_then_send_None PyId_send - Modules/_testcapimodule.c slot_tp_del PyId___tp_del__ - @@ -193,11 +518,14 @@ Modules/_testcapimodule.c test_capsule buffer - Modules/_testcapimodule.c test_empty_argparse kwlist - Modules/_testcapimodule.c test_structmembers_new keywords - Modules/_testcapimodule.c getargs_s_hash_int keywords - +Modules/_testcapimodule.c - g_dict_watch_events - +Modules/_testcapimodule.c - g_dict_watchers_installed - +Modules/_testcapimodule.c - g_type_modified_events - +Modules/_testcapimodule.c - g_type_watchers_installed - Modules/_testimportmultiple.c - _barmodule - Modules/_testimportmultiple.c - _foomodule - Modules/_testimportmultiple.c - _testimportmultiple - -Modules/_testinternalcapi.c - TestMethods - -Modules/_testinternalcapi.c - _testcapimodule - +Modules/_testinternalcapi.c - pending_identify_result - Modules/_testmultiphase.c - Example_Type_slots - Modules/_testmultiphase.c - Example_Type_spec - Modules/_testmultiphase.c - Example_methods - @@ -241,6 +569,7 @@ Modules/_testmultiphase.c - slots_exec_unreported_exception - Modules/_testmultiphase.c - slots_nonmodule_with_exec_slots - Modules/_testmultiphase.c - testexport_methods - Modules/_testmultiphase.c - uninitialized_def - +Modules/_testsinglephase.c - global_state - Modules/_xxtestfuzz/_xxtestfuzz.c - _fuzzmodule - Modules/_xxtestfuzz/_xxtestfuzz.c - module_methods - Modules/_xxtestfuzz/fuzzer.c - SRE_FLAG_DEBUG - @@ -261,1260 +590,125 @@ Modules/_xxtestfuzz/fuzzer.c LLVMFuzzerTestOneInput SRE_MATCH_INITIALIZED - Modules/_xxtestfuzz/fuzzer.c LLVMFuzzerTestOneInput STRUCT_UNPACK_INITIALIZED - Modules/_xxtestfuzz/fuzzer.c LLVMFuzzerTestOneInput AST_LITERAL_EVAL_INITIALIZED - +##----------------------- +## the analyzer should have ignored these +# XXX Fix the analyzer. -################################## -# should be const -# XXX Make them const. - -# These are all variables that we will be leaving global. - -#----------------------- -# keywords for PyArg_ParseTupleAndKeywords() -# "static char *name[]" -> "static const char * const name[]" - -Modules/cjkcodecs/multibytecodec.c - incnewkwarglist - -Modules/cjkcodecs/multibytecodec.c - streamkwarglist - -Modules/_csv.c - dialect_kws - -Modules/_datetimemodule.c date_fromisocalendar keywords - -Modules/_datetimemodule.c - date_kws - -Modules/_datetimemodule.c date_strftime keywords - -Modules/_datetimemodule.c datetime_astimezone keywords - -Modules/_datetimemodule.c datetime_combine keywords - -Modules/_datetimemodule.c datetime_fromtimestamp keywords - -Modules/_datetimemodule.c datetime_isoformat keywords - -Modules/_datetimemodule.c - datetime_kws - -Modules/_datetimemodule.c delta_new keywords - -Modules/_datetimemodule.c time_isoformat keywords - -Modules/_datetimemodule.c - time_kws - -Modules/_datetimemodule.c time_strftime keywords - -Modules/_datetimemodule.c - timezone_kws - -Modules/_decimal/_decimal.c context_init kwlist - -Modules/_decimal/_decimal.c ctxmanager_new kwlist - -Modules/_decimal/_decimal.c ctx_mpd_qpow kwlist - -Modules/_decimal/_decimal.c dec_mpd_class kwlist - -Modules/_decimal/_decimal.c dec_mpd_compare_total kwlist - -Modules/_decimal/_decimal.c dec_mpd_compare_total_mag kwlist - -Modules/_decimal/_decimal.c dec_mpd_isnormal kwlist - -Modules/_decimal/_decimal.c dec_mpd_issubnormal kwlist - -Modules/_decimal/_decimal.c dec_mpd_qand kwlist - -Modules/_decimal/_decimal.c dec_mpd_qcompare kwlist - -Modules/_decimal/_decimal.c dec_mpd_qcompare_signal kwlist - -Modules/_decimal/_decimal.c dec_mpd_qcopy_sign kwlist - -Modules/_decimal/_decimal.c dec_mpd_qexp kwlist - -Modules/_decimal/_decimal.c dec_mpd_qfma kwlist - -Modules/_decimal/_decimal.c dec_mpd_qinvert kwlist - -Modules/_decimal/_decimal.c dec_mpd_qln kwlist - -Modules/_decimal/_decimal.c dec_mpd_qlog10 kwlist - -Modules/_decimal/_decimal.c dec_mpd_qlogb kwlist - -Modules/_decimal/_decimal.c dec_mpd_qmax kwlist - -Modules/_decimal/_decimal.c dec_mpd_qmax_mag kwlist - -Modules/_decimal/_decimal.c dec_mpd_qmin kwlist - -Modules/_decimal/_decimal.c dec_mpd_qmin_mag kwlist - -Modules/_decimal/_decimal.c dec_mpd_qnext_minus kwlist - -Modules/_decimal/_decimal.c dec_mpd_qnext_plus kwlist - -Modules/_decimal/_decimal.c dec_mpd_qnext_toward kwlist - -Modules/_decimal/_decimal.c dec_mpd_qor kwlist - -Modules/_decimal/_decimal.c dec_mpd_qquantize kwlist - -Modules/_decimal/_decimal.c dec_mpd_qreduce kwlist - -Modules/_decimal/_decimal.c dec_mpd_qrem_near kwlist - -Modules/_decimal/_decimal.c dec_mpd_qrotate kwlist - -Modules/_decimal/_decimal.c dec_mpd_qscaleb kwlist - -Modules/_decimal/_decimal.c dec_mpd_qshift kwlist - -Modules/_decimal/_decimal.c dec_mpd_qsqrt kwlist - -Modules/_decimal/_decimal.c dec_mpd_qxor kwlist - -Modules/_decimal/_decimal.c dec_mpd_same_quantum kwlist - -Modules/_decimal/_decimal.c dec_mpd_to_eng kwlist - -Modules/_decimal/_decimal.c dec_new kwlist - -Modules/_decimal/_decimal.c PyDec_ToIntegralExact kwlist - -Modules/_decimal/_decimal.c PyDec_ToIntegralValue kwlist - -Modules/_elementtree.c element_setstate_from_Python kwlist - -Modules/faulthandler.c faulthandler_dump_traceback_later kwlist - -Modules/faulthandler.c faulthandler_dump_traceback_py kwlist - -Modules/faulthandler.c faulthandler_py_enable kwlist - -Modules/faulthandler.c faulthandler_register_py kwlist - -Modules/_functoolsmodule.c functools_cmp_to_key kwargs - -Modules/_functoolsmodule.c keyobject_call kwargs - -Modules/_functoolsmodule.c lru_cache_new keywords - -Modules/itertoolsmodule.c repeat_new kwargs - -Modules/_json.c encoder_call kwlist - -Modules/_json.c encoder_new kwlist - -Modules/_json.c scanner_call kwlist - -Modules/_json.c scanner_new kwlist - -Modules/_lsprof.c profiler_enable kwlist - -Modules/_lsprof.c profiler_init kwlist - -Modules/_lzmamodule.c Compressor_init arg_names - -Modules/_lzmamodule.c parse_filter_spec_bcj optnames - -Modules/_lzmamodule.c parse_filter_spec_delta optnames - -Modules/_lzmamodule.c parse_filter_spec_lzma optnames - -Modules/mmapmodule.c new_mmap_object keywords - -Modules/nismodule.c nis_cat kwlist - -Modules/nismodule.c nis_maps kwlist - -Modules/nismodule.c nis_match kwlist - -Modules/signalmodule.c signal_set_wakeup_fd kwlist - -Modules/socketmodule.c sock_initobj keywords - -Modules/socketmodule.c sock_recvfrom_into kwlist - -Modules/socketmodule.c sock_recv_into kwlist - -Modules/socketmodule.c sock_sendmsg_afalg keywords - -Modules/socketmodule.c socket_getaddrinfo kwnames - -Modules/_sqlite/connection.c pysqlite_connection_backup keywords - -Modules/_sqlite/connection.c pysqlite_connection_create_aggregate kwlist - -Modules/_sqlite/connection.c pysqlite_connection_create_function kwlist - -Modules/_sqlite/connection.c pysqlite_connection_cursor kwlist - -Modules/_sqlite/connection.c pysqlite_connection_init kwlist - -Modules/_sqlite/connection.c pysqlite_connection_set_authorizer kwlist - -Modules/_sqlite/connection.c pysqlite_connection_set_progress_handler kwlist - -Modules/_sqlite/connection.c pysqlite_connection_set_trace_callback kwlist - -Modules/_sqlite/cursor.c pysqlite_cursor_fetchmany kwlist - -Modules/_sqlite/module.c module_complete kwlist - -Modules/_sqlite/module.c module_connect kwlist - -Modules/_sqlite/module.c module_enable_shared_cache kwlist - -Modules/syslogmodule.c syslog_openlog keywords - -Modules/_xxsubinterpretersmodule.c channel_close kwlist - -Modules/_xxsubinterpretersmodule.c channel_destroy kwlist - -Modules/_xxsubinterpretersmodule.c channelid_new kwlist - -Modules/_xxsubinterpretersmodule.c channel_list_interpreters kwlist - -Modules/_xxsubinterpretersmodule.c channel_recv kwlist - -Modules/_xxsubinterpretersmodule.c channel_release kwlist - -Modules/_xxsubinterpretersmodule.c channel_send kwlist - -Modules/_xxsubinterpretersmodule.c interp_create kwlist - -Modules/_xxsubinterpretersmodule.c interp_destroy kwlist - -Modules/_xxsubinterpretersmodule.c interp_is_running kwlist - -Modules/_xxsubinterpretersmodule.c interp_run_string kwlist - -Modules/_xxsubinterpretersmodule.c object_is_shareable kwlist - -Modules/_zoneinfo.c zoneinfo_clear_cache kwlist - -Modules/_zoneinfo.c zoneinfo_from_file kwlist - -Modules/_zoneinfo.c zoneinfo_new kwlist - -Modules/_zoneinfo.c zoneinfo_no_cache kwlist - -Objects/exceptions.c ImportError_init kwlist - -Objects/interpreteridobject.c interpid_new kwlist - -Objects/weakrefobject.c weakref_call kwlist - -Objects/exceptions.c NameError_init kwlist - -Objects/exceptions.c AttributeError_init kwlist - -Python/_warnings.c warnings_warn_explicit kwd_list - -Python/bltinmodule.c builtin___import__ kwlist - -Python/bltinmodule.c min_max kwlist - -Python/bltinmodule.c zip_new kwlist - -Python/context.c contextvar_tp_new kwlist - -Python/sysmodule.c sys_getsizeof kwlist - -Python/sysmodule.c sys_set_asyncgen_hooks keywords - - -#----------------------- -# PyModuleDef - -Modules/_multiprocessing/posixshmem.c - _posixshmemmodule - -Modules/_sqlite/module.h - _sqlite3module - -Modules/_ssl.c - _sslmodule_def - -Modules/_ssl.h - _sslmodule_def - -Modules/_testmultiphase.c - def_module_state_shared - -Modules/_threadmodule.c - thread_module - -Modules/_typingmodule.c - typingmodule - -Modules/signalmodule.c - signal_module - -Modules/xxlimited_35.c - xxmodule - -Python/Python-ast.c - _astmodule - -Python/Python-tokenize.c - _tokenizemodule - -Python/_warnings.c - warnings_module - -Python/bltinmodule.c - builtinsmodule - -Python/import.c - imp_module - -Python/marshal.c - marshalmodule - -Python/sysmodule.c - sysmodule - - -#----------------------- -# PyModuleDef_Slot - -Modules/_abc.c - _abcmodule_slots - -Modules/_blake2/blake2module.c - _blake2_slots - -Modules/_bz2module.c - _bz2_slots - -Modules/_codecsmodule.c - _codecs_slots - -Modules/_collectionsmodule.c - collections_slots - -Modules/_contextvarsmodule.c - _contextvars_slots - -Modules/_cryptmodule.c - _crypt_slots - -Modules/_csv.c - csv_slots - -Modules/_curses_panel.c - _curses_slots - -Modules/_dbmmodule.c - _dbmmodule_slots - -Modules/_functoolsmodule.c - _functools_slots - -Modules/_gdbmmodule.c - _gdbm_module_slots - -Modules/_hashopenssl.c - hashlib_slots - -Modules/_heapqmodule.c - heapq_slots - -Modules/_json.c - _json_slots - -Modules/_localemodule.c - _locale_slots - -Modules/_lsprof.c - _lsprofslots - -Modules/_lzmamodule.c - lzma_slots - -Modules/_multiprocessing/multiprocessing.c - multiprocessing_slots - -Modules/_operator.c - operator_slots - -Modules/_posixsubprocess.c - _posixsubprocess_slots - -Modules/_queuemodule.c - queuemodule_slots - -Modules/_randommodule.c - _random_slots - -Modules/_scproxy.c - _scproxy_slots - -Modules/_sha3/sha3module.c - _sha3_slots - -Modules/_sqlite/module.c - module_slots - -Modules/_sre.c - sre_slots - -Modules/_ssl.c - sslmodule_slots - -Modules/_stat.c - stat_slots - -Modules/_statisticsmodule.c - _statisticsmodule_slots - -Modules/_struct.c - _structmodule_slots - -Modules/_threadmodule.c - thread_module_slots - -Modules/_typingmodule.c - _typingmodule_slots - -Modules/_uuidmodule.c - uuid_slots - -Modules/_weakref.c - weakref_slots - -Modules/_winapi.c - winapi_slots - -Modules/_zoneinfo.c - zoneinfomodule_slots - -Modules/arraymodule.c - arrayslots - -Modules/atexitmodule.c - atexit_slots - -Modules/audioop.c - audioop_slots - -Modules/binascii.c - binascii_slots - -Modules/cjkcodecs/cjkcodecs.h - _cjk_slots - -Modules/cjkcodecs/multibytecodec.c - _multibytecodec_slots - -Modules/cmathmodule.c - cmath_slots - -Modules/errnomodule.c - errno_slots - -Modules/faulthandler.c - faulthandler_slots - -Modules/fcntlmodule.c - fcntl_slots - -Modules/gcmodule.c - gcmodule_slots - -Modules/gcmodule.c - gcmodule_slots - -Modules/grpmodule.c - grpmodule_slots - -Modules/itertoolsmodule.c - itertoolsmodule_slots - -Modules/mathmodule.c - math_slots - -Modules/md5module.c - _md5_slots - -Modules/mmapmodule.c - mmap_slots - -Modules/nismodule.c - nis_slots - -Modules/overlapped.c - overlapped_slots - -Modules/posixmodule.c - posixmodile_slots - -Modules/pwdmodule.c - pwdmodule_slots - -Modules/pyexpat.c - pyexpat_slots - -Modules/resource.c - resource_slots - -Modules/selectmodule.c - _select_slots - -Modules/sha1module.c - _sha1_slots - -Modules/sha256module.c - _sha256_slots - -Modules/sha512module.c - _sha512_slots - -Modules/signalmodule.c - signal_slots - -Modules/spwdmodule.c - spwdmodule_slots - -Modules/symtablemodule.c - symtable_slots - -Modules/syslogmodule.c - syslog_slots - -Modules/termios.c - termios_slots - -Modules/timemodule.c - time_slots - -Modules/unicodedata.c - unicodedata_slots - -Modules/xxlimited.c - xx_slots - -Modules/xxlimited_35.c - xx_slots - -Modules/xxmodule.c - xx_slots - -Modules/xxsubtype.c - xxsubtype_slots - -Modules/zlibmodule.c - zlib_slots - -Python/Python-ast.c - astmodule_slots - -Python/Python-tokenize.c - tokenizemodule_slots - -Python/_warnings.c - warnings_slots - -Python/marshal.c - marshalmodule_slots - - -#----------------------- -# PyMethodDef and PyMethodDef[], for static types and modules - -Modules/_abc.c - _abcmodule_methods - -Modules/_abc.c - _destroy_def - -Modules/_asynciomodule.c - FutureIter_methods - -Modules/_asynciomodule.c - FutureType_methods - -Modules/_asynciomodule.c - TaskType_methods - -Modules/_asynciomodule.c - TaskWakeupDef - -Modules/_asynciomodule.c - asyncio_methods - -Modules/_bisectmodule.c - bisect_methods - -Modules/_blake2/blake2b_impl.c - py_blake2b_methods - -Modules/_blake2/blake2module.c - blake2mod_functions - -Modules/_blake2/blake2s_impl.c - py_blake2s_methods - -Modules/_bz2module.c - BZ2Compressor_methods - -Modules/_bz2module.c - BZ2Decompressor_methods - -Modules/_codecsmodule.c - _codecs_functions - -Modules/_collectionsmodule.c - collections_methods - -Modules/_collectionsmodule.c - defdict_methods - -Modules/_collectionsmodule.c - deque_methods - -Modules/_collectionsmodule.c - dequeiter_methods - -Modules/_collectionsmodule.c - tuplegetter_methods - -Modules/_contextvarsmodule.c - _contextvars_methods - -Modules/_cryptmodule.c - crypt_methods - -Modules/_csv.c - Reader_methods - -Modules/_csv.c - Writer_methods - -Modules/_csv.c - csv_methods - -Modules/_csv.c - dialect_methods - -Modules/_ctypes/_ctypes.c - Array_methods - -Modules/_ctypes/_ctypes.c - CDataType_methods - -Modules/_ctypes/_ctypes.c - PyCData_methods - -Modules/_ctypes/_ctypes.c - PyCPointerType_methods - -Modules/_ctypes/_ctypes.c - PyCSimpleType_methods - -Modules/_ctypes/_ctypes.c - Simple_methods - -Modules/_ctypes/_ctypes.c - c_char_p_method - -Modules/_ctypes/_ctypes.c - c_void_p_method - -Modules/_ctypes/_ctypes.c - c_wchar_p_method - -Modules/_ctypes/callproc.c - _ctypes_module_methods - -Modules/_ctypes/stgdict.c - PyCStgDict_methods - -Modules/_curses_panel.c - PyCursesPanel_Methods - -Modules/_curses_panel.c - PyCurses_methods - -Modules/_cursesmodule.c - PyCursesWindow_Methods - -Modules/_cursesmodule.c - PyCurses_methods - -Modules/_datetimemodule.c - date_methods - -Modules/_datetimemodule.c - datetime_methods - -Modules/_datetimemodule.c - delta_methods - -Modules/_datetimemodule.c - iso_calendar_date_methods - -Modules/_datetimemodule.c - module_methods - -Modules/_datetimemodule.c - time_methods - -Modules/_datetimemodule.c - timezone_methods - -Modules/_datetimemodule.c - tzinfo_methods - -Modules/_dbmmodule.c - dbm_methods - -Modules/_dbmmodule.c - dbmmodule_methods - -Modules/_decimal/_decimal.c - _decimal_methods - -Modules/_decimal/_decimal.c - context_methods - -Modules/_decimal/_decimal.c - ctxmanager_methods - -Modules/_decimal/_decimal.c - dec_methods - -Modules/_decimal/_decimal.c - signaldict_methods - -Modules/_elementtree.c - _functions - -Modules/_elementtree.c - element_methods - -Modules/_elementtree.c - treebuilder_methods - -Modules/_elementtree.c - xmlparser_methods - -Modules/_functoolsmodule.c - _functools_methods - -Modules/_functoolsmodule.c - lru_cache_methods - -Modules/_functoolsmodule.c - partial_methods - -Modules/_gdbmmodule.c - _gdbm_module_methods - -Modules/_gdbmmodule.c - gdbm_methods - -Modules/_hashopenssl.c - EVPXOF_methods - -Modules/_hashopenssl.c - EVP_functions - -Modules/_hashopenssl.c - EVP_methods - -Modules/_hashopenssl.c - HMAC_methods - -Modules/_heapqmodule.c - heapq_methods - -Modules/_io/_iomodule.c - module_methods - -Modules/_io/bufferedio.c - bufferediobase_methods - -Modules/_io/bufferedio.c - bufferedrandom_methods - -Modules/_io/bufferedio.c - bufferedreader_methods - -Modules/_io/bufferedio.c - bufferedrwpair_methods - -Modules/_io/bufferedio.c - bufferedwriter_methods - -Modules/_io/bytesio.c - bytesio_methods - -Modules/_io/fileio.c - fileio_methods - -Modules/_io/iobase.c - iobase_methods - -Modules/_io/iobase.c - rawiobase_methods - -Modules/_io/stringio.c - stringio_methods - -Modules/_io/textio.c - incrementalnewlinedecoder_methods - -Modules/_io/textio.c - textiobase_methods - -Modules/_io/textio.c - textiowrapper_methods - -Modules/_io/winconsoleio.c - winconsoleio_methods - -Modules/_json.c - speedups_methods - -Modules/_localemodule.c - PyLocale_Methods - -Modules/_lsprof.c - moduleMethods - -Modules/_lsprof.c - profiler_methods - -Modules/_lzmamodule.c - Compressor_methods - -Modules/_lzmamodule.c - Decompressor_methods - -Modules/_lzmamodule.c - lzma_methods - -Modules/_multiprocessing/multiprocessing.c - module_methods - -Modules/_multiprocessing/posixshmem.c - module_methods - -Modules/_multiprocessing/semaphore.c - semlock_methods - -Modules/_opcode.c - opcode_functions - -Modules/_operator.c - attrgetter_methods - -Modules/_operator.c - itemgetter_methods - -Modules/_operator.c - methodcaller_methods - -Modules/_operator.c - operator_methods - -Modules/_pickle.c - Pickler_methods - -Modules/_pickle.c - Unpickler_methods - -Modules/_pickle.c - pickle_methods - -Modules/_pickle.c - picklerproxy_methods - -Modules/_pickle.c - unpicklerproxy_methods - -Modules/_posixsubprocess.c - module_methods - -Modules/_queuemodule.c - simplequeue_methods - -Modules/_randommodule.c - random_methods - -Modules/_scproxy.c - mod_methods - -Modules/_sha3/sha3module.c - SHA3_methods - -Modules/_sha3/sha3module.c - SHAKE_methods - -Modules/_sqlite/connection.c - connection_methods - -Modules/_sqlite/cursor.c - cursor_methods - -Modules/_sqlite/module.c - module_methods - -Modules/_sqlite/row.c - row_methods - -Modules/_sre.c - _functions - -Modules/_sre.c - match_methods - -Modules/_sre.c - pattern_methods - -Modules/_sre.c - scanner_methods - -Modules/_ssl.c - PySSLMethods - -Modules/_ssl.c - PySSL_methods - -Modules/_ssl.c - context_methods - -Modules/_ssl.c - memory_bio_methods - -Modules/_ssl/cert.c - certificate_methods - -Modules/_stat.c - stat_methods - -Modules/_statisticsmodule.c - statistics_methods - -Modules/_struct.c - module_functions - -Modules/_struct.c - s_methods - -Modules/_struct.c - unpackiter_methods - -Modules/_threadmodule.c - lock_methods - -Modules/_threadmodule.c - rlock_methods - -Modules/_threadmodule.c - thread_methods - -Modules/_threadmodule.c local_new wr_callback_def - -Modules/_tkinter.c - Tkapp_methods - -Modules/_tkinter.c - Tktt_methods - -Modules/_tkinter.c - moduleMethods - -Modules/_tracemalloc.c - module_methods - -Modules/_typingmodule.c - typing_methods - -Modules/_uuidmodule.c - uuid_methods - -Modules/_weakref.c - weakref_functions - -Modules/_winapi.c - overlapped_methods - -Modules/_winapi.c - winapi_functions - -Modules/_xxsubinterpretersmodule.c - module_functions - -Modules/_zoneinfo.c - module_methods - -Modules/_zoneinfo.c - zoneinfo_methods - -Modules/arraymodule.c - a_methods - -Modules/arraymodule.c - array_methods - -Modules/arraymodule.c - arrayiter_methods - -Modules/atexitmodule.c - atexit_methods - -Modules/audioop.c - audioop_methods - -Modules/binascii.c - binascii_module_methods - -Modules/cjkcodecs/cjkcodecs.h - __methods - -Modules/cjkcodecs/cjkcodecs.h - _cjk_methods - -Modules/cjkcodecs/multibytecodec.c - __methods - -Modules/cjkcodecs/multibytecodec.c - _multibytecodec_methods - -Modules/cjkcodecs/multibytecodec.c - mbidecoder_methods - -Modules/cjkcodecs/multibytecodec.c - mbiencoder_methods - -Modules/cjkcodecs/multibytecodec.c - mbstreamreader_methods - -Modules/cjkcodecs/multibytecodec.c - mbstreamwriter_methods - -Modules/cjkcodecs/multibytecodec.c - multibytecodec_methods - -Modules/cmathmodule.c - cmath_methods - -Modules/errnomodule.c - errno_methods - -Modules/faulthandler.c - module_methods - -Modules/fcntlmodule.c - fcntl_methods - -Modules/gcmodule.c - GcMethods - -Modules/getpath.c - getpath_methods - -Modules/getpath.c - getpath_nowarn_method - -Modules/getpath.c - getpath_warn_method - -Modules/grpmodule.c - grp_methods - -Modules/itertoolsmodule.c - _grouper_methods - -Modules/itertoolsmodule.c - accumulate_methods - -Modules/itertoolsmodule.c - chain_methods - -Modules/itertoolsmodule.c - combinations_methods - -Modules/itertoolsmodule.c - compress_methods - -Modules/itertoolsmodule.c - count_methods - -Modules/itertoolsmodule.c - cwr_methods - -Modules/itertoolsmodule.c - cycle_methods - -Modules/itertoolsmodule.c - dropwhile_methods - -Modules/itertoolsmodule.c - filterfalse_methods - -Modules/itertoolsmodule.c - groupby_methods - -Modules/itertoolsmodule.c - islice_methods - -Modules/itertoolsmodule.c - module_methods - -Modules/itertoolsmodule.c - permuations_methods - -Modules/itertoolsmodule.c - product_methods - -Modules/itertoolsmodule.c - repeat_methods - -Modules/itertoolsmodule.c - starmap_methods - -Modules/itertoolsmodule.c - takewhile_reduce_methods - -Modules/itertoolsmodule.c - tee_methods - -Modules/itertoolsmodule.c - teedataobject_methods - -Modules/itertoolsmodule.c - zip_longest_methods - -Modules/mathmodule.c - math_methods - -Modules/md5module.c - MD5_functions - -Modules/md5module.c - MD5_methods - -Modules/mmapmodule.c - mmap_object_methods - -Modules/nismodule.c - nis_methods - -Modules/ossaudiodev.c - oss_methods - -Modules/ossaudiodev.c - oss_mixer_methods - -Modules/ossaudiodev.c - ossaudiodev_methods - -Modules/overlapped.c - Overlapped_methods - -Modules/overlapped.c - overlapped_functions - -Modules/posixmodule.c - DirEntry_methods - -Modules/posixmodule.c - ScandirIterator_methods - -Modules/posixmodule.c - posix_methods - -Modules/pwdmodule.c - pwd_methods - -Modules/pyexpat.c - pyexpat_methods - -Modules/pyexpat.c - xmlparse_methods - -Modules/readline.c - readline_methods - -Modules/resource.c - resource_methods - -Modules/selectmodule.c - devpoll_methods - -Modules/selectmodule.c - kqueue_queue_methods - -Modules/selectmodule.c - poll_methods - -Modules/selectmodule.c - pyepoll_methods - -Modules/selectmodule.c - select_methods - -Modules/sha1module.c - SHA1_functions - -Modules/sha1module.c - SHA1_methods - -Modules/sha256module.c - SHA_functions - -Modules/sha256module.c - SHA_methods - -Modules/sha512module.c - SHA_functions - -Modules/sha512module.c - SHA_methods - -Modules/signalmodule.c - signal_methods - -Modules/socketmodule.c - sock_methods - -Modules/socketmodule.c - socket_methods - -Modules/spwdmodule.c - spwd_methods - -Modules/symtablemodule.c - symtable_methods - -Modules/syslogmodule.c - syslog_methods - -Modules/termios.c - termios_methods - -Modules/timemodule.c - time_methods - -Modules/unicodedata.c - unicodedata_functions - -Modules/xxlimited.c - Xxo_methods - -Modules/xxlimited.c - xx_methods - -Modules/xxlimited_35.c - Xxo_methods - -Modules/xxlimited_35.c - xx_methods - -Modules/xxmodule.c - Xxo_methods - -Modules/xxmodule.c - xx_methods - -Modules/xxsubtype.c - spamdict_methods - -Modules/xxsubtype.c - spamlist_methods - -Modules/xxsubtype.c - xxsubtype_functions - -Modules/zlibmodule.c - Decomp_methods - -Modules/zlibmodule.c - comp_methods - -Modules/zlibmodule.c - zlib_methods - -Objects/bytearrayobject.c - bytearray_methods - -Objects/bytearrayobject.c - bytearrayiter_methods - -Objects/bytesobject.c - bytes_methods - -Objects/bytesobject.c - striter_methods - -Objects/classobject.c - method_methods - -Objects/codeobject.c - code_methods - -Objects/complexobject.c - complex_methods - -Objects/descrobject.c - descr_methods - -Objects/descrobject.c - mappingproxy_methods - -Objects/descrobject.c - property_methods - -Objects/descrobject.c - wrapper_methods - -Objects/dictobject.c - dictitems_methods - -Objects/dictobject.c - dictiter_methods - -Objects/dictobject.c - dictkeys_methods - -Objects/dictobject.c - dictvalues_methods - -Objects/dictobject.c - mapp_methods - -Objects/enumobject.c - enum_methods - -Objects/enumobject.c - reversediter_methods - -Objects/exceptions.c - AttributeError_methods - -Objects/exceptions.c - BaseExceptionGroup_methods - -Objects/exceptions.c - BaseException_methods - -Objects/exceptions.c - ImportError_methods - -Objects/exceptions.c - NameError_methods - -Objects/exceptions.c - OSError_methods - -Objects/fileobject.c - stdprinter_methods - -Objects/floatobject.c - float_methods - -Objects/frameobject.c - frame_methods - -Objects/genericaliasobject.c - ga_methods - -Objects/genobject.c - async_gen_asend_methods - -Objects/genobject.c - async_gen_athrow_methods - -Objects/genobject.c - async_gen_methods - -Objects/genobject.c - coro_methods - -Objects/genobject.c - coro_wrapper_methods - -Objects/genobject.c - gen_methods - -Objects/iterobject.c - anextawaitable_methods - -Objects/iterobject.c - calliter_methods - -Objects/iterobject.c - seqiter_methods - -Objects/listobject.c - list_methods - -Objects/listobject.c - listiter_methods - -Objects/listobject.c - listreviter_methods - -Objects/longobject.c - long_methods - -Objects/memoryobject.c - memory_methods - -Objects/methodobject.c - meth_methods - -Objects/moduleobject.c - module_methods - -Objects/namespaceobject.c - namespace_methods - -Objects/object.c - notimplemented_methods - -Objects/odictobject.c - odict_methods - -Objects/odictobject.c - odictitems_methods - -Objects/odictobject.c - odictiter_methods - -Objects/odictobject.c - odictkeys_methods - -Objects/odictobject.c - odictvalues_methods - -Objects/picklebufobject.c - picklebuf_methods - -Objects/rangeobject.c - longrangeiter_methods - -Objects/rangeobject.c - range_methods - -Objects/rangeobject.c - rangeiter_methods - -Objects/setobject.c - frozenset_methods - -Objects/setobject.c - set_methods - -Objects/setobject.c - setiter_methods - -Objects/sliceobject.c - ellipsis_methods - -Objects/sliceobject.c - slice_methods - -Objects/stringlib/unicode_format.h - fieldnameiter_methods - -Objects/stringlib/unicode_format.h - formatteriter_methods - -Objects/structseq.c - structseq_methods - -Objects/tupleobject.c - tuple_methods - -Objects/tupleobject.c - tupleiter_methods - -Objects/typeobject.c - object_methods - -Objects/typeobject.c - tp_new_methoddef - -Objects/typeobject.c - type_methods - -Objects/unicodeobject.c - _string_methods - -Objects/unicodeobject.c - encoding_map_methods - -Objects/unicodeobject.c - unicode_methods - -Objects/unicodeobject.c - unicodeiter_methods - -Objects/unionobject.c - union_methods - -Objects/weakrefobject.c - proxy_methods - -Objects/weakrefobject.c - weakref_methods - -Python/Python-ast.c - ast_type_methods - -Python/Python-tokenize.c - tokenize_methods - -Python/_warnings.c - warnings_functions - -Python/bltinmodule.c - builtin_methods - -Python/bltinmodule.c - filter_methods - -Python/bltinmodule.c - map_methods - -Python/bltinmodule.c - zip_methods - -Python/context.c - PyContextTokenType_methods - -Python/context.c - PyContextVar_methods - -Python/context.c - PyContext_methods - -Python/hamt.c - PyHamt_methods - -Python/import.c - imp_slots - -Python/import.c - imp_methods - -Python/marshal.c - marshal_methods - -Python/sysmodule.c - sys_methods - -Python/traceback.c - tb_methods - - -#----------------------- -# PyMemberDef[], for static types and strucseq - -Modules/_bz2module.c - BZ2Decompressor_members - -Modules/_collectionsmodule.c - defdict_members - -Modules/_collectionsmodule.c - tuplegetter_members - -Modules/_csv.c - Dialect_memberlist - -Modules/_csv.c - Reader_memberlist - -Modules/_csv.c - Writer_memberlist - -Modules/_ctypes/_ctypes.c - PyCData_members - -Modules/_ctypes/callproc.c - PyCArgType_members - -Modules/_datetimemodule.c - delta_members - -Modules/_elementtree.c - xmlparser_members - -Modules/_functoolsmodule.c - keyobject_members - -Modules/_functoolsmodule.c - lru_cache_memberlist - -Modules/_functoolsmodule.c - partial_memberlist - -Modules/_io/bufferedio.c - bufferedrandom_members - -Modules/_io/bufferedio.c - bufferedreader_members - -Modules/_io/bufferedio.c - bufferedwriter_members - -Modules/_io/fileio.c - fileio_members - -Modules/_io/textio.c - textiowrapper_members - -Modules/_io/winconsoleio.c - winconsoleio_members - -Modules/_json.c - encoder_members - -Modules/_json.c - scanner_members - -Modules/_lzmamodule.c - Decompressor_members - -Modules/_multiprocessing/semaphore.c - semlock_members - -Modules/_pickle.c - Pickler_members - -Modules/_queuemodule.c - simplequeue_members - -Modules/_sqlite/connection.c - connection_members - -Modules/_sqlite/cursor.c - cursor_members - -Modules/_sqlite/statement.c - stmt_members - -Modules/_sre.c - match_members - -Modules/_sre.c - pattern_members - -Modules/_sre.c - scanner_members - -Modules/_struct.c - s_members - -Modules/_threadmodule.c - local_dummy_type_members - -Modules/_threadmodule.c - local_type_members - -Modules/_threadmodule.c - lock_type_members - -Modules/_threadmodule.c - rlock_type_members - -Modules/_winapi.c - overlapped_members - -Modules/_zoneinfo.c - zoneinfo_members - -Modules/arraymodule.c - array_members - -Modules/cjkcodecs/multibytecodec.c - mbstreamreader_members - -Modules/cjkcodecs/multibytecodec.c - mbstreamwriter_members - -Modules/mmapmodule.c - mmap_object_members - -Modules/ossaudiodev.c - oss_members - -Modules/overlapped.c - Overlapped_members - -Modules/posixmodule.c - DirEntry_members - -Modules/pyexpat.c - xmlparse_members - -Modules/selectmodule.c - kqueue_event_members - -Modules/sha256module.c - SHA_members - -Modules/sha512module.c - SHA_members - -Modules/socketmodule.c - sock_memberlist - -Modules/unicodedata.c - DB_members - -Modules/xxsubtype.c - spamdict_members - -Modules/zlibmodule.c - Decomp_members - -Objects/classobject.c - instancemethod_memberlist - -Objects/classobject.c - method_memberlist - -Objects/codeobject.c - code_memberlist - -Objects/complexobject.c - complex_members - -Objects/descrobject.c - descr_members - -Objects/descrobject.c - property_members - -Objects/descrobject.c - wrapper_members - -Objects/exceptions.c - AttributeError_members - -Objects/exceptions.c - BaseExceptionGroup_members - -Objects/exceptions.c - BaseException_members - -Objects/exceptions.c - ImportError_members - -Objects/exceptions.c - NameError_members - -Objects/exceptions.c - OSError_members - -Objects/exceptions.c - StopIteration_members - -Objects/exceptions.c - SyntaxError_members - -Objects/exceptions.c - SystemExit_members - -Objects/exceptions.c - UnicodeError_members - -Objects/frameobject.c - frame_memberlist - -Objects/funcobject.c - cm_memberlist - -Objects/funcobject.c - func_memberlist - -Objects/funcobject.c - sm_memberlist - -Objects/genericaliasobject.c - ga_members - -Objects/genobject.c - async_gen_memberlist - -Objects/genobject.c - coro_memberlist - -Objects/genobject.c - gen_memberlist - -Objects/methodobject.c - meth_members - -Objects/moduleobject.c - module_members - -Objects/namespaceobject.c - namespace_members - -Objects/rangeobject.c - range_members - -Objects/sliceobject.c - slice_members - -Objects/typeobject.c - super_members - -Objects/typeobject.c - type_members - -Objects/unionobject.c - union_members - -Objects/weakrefobject.c - weakref_members - -Python/Python-ast.c - ast_type_members - -Python/context.c - PyContextVar_members - -Python/symtable.c - ste_memberlist - -Python/traceback.c - tb_memberlist - - -#----------------------- -# for static types - -# PyNumberMethods -Modules/_collectionsmodule.c - deque_as_number - -Modules/_collectionsmodule.c - defdict_as_number - -Modules/_ctypes/_ctypes.c - PyCFuncPtr_as_number - -Modules/_ctypes/_ctypes.c - Simple_as_number - -Modules/_ctypes/_ctypes.c - Pointer_as_number - -Modules/_datetimemodule.c - delta_as_number - -Modules/_datetimemodule.c - date_as_number - -Modules/_datetimemodule.c - datetime_as_number - -Modules/_decimal/_decimal.c - dec_number_methods - -Modules/_xxsubinterpretersmodule.c - channelid_as_number - -Objects/boolobject.c - bool_as_number - -Objects/bytearrayobject.c - bytearray_as_number - -Objects/bytesobject.c - bytes_as_number - -Objects/complexobject.c - complex_as_number - -Objects/descrobject.c - mappingproxy_as_number - -Objects/dictobject.c - dict_as_number - -Objects/dictobject.c - dictviews_as_number - -Objects/floatobject.c - float_as_number - -Objects/genericaliasobject.c - ga_as_number - -Objects/interpreteridobject.c - interpid_as_number - -Objects/longobject.c - long_as_number - -Objects/object.c - none_as_number - -Objects/object.c - notimplemented_as_number - -Objects/odictobject.c - odict_as_number - -Objects/rangeobject.c - range_as_number - -Objects/setobject.c - set_as_number - -Objects/setobject.c - frozenset_as_number - -Objects/typeobject.c - type_as_number - -Objects/unicodeobject.c - unicode_as_number - -Objects/unionobject.c - union_as_number - -Objects/weakrefobject.c - proxy_as_number - - -# PySequenceMethods -Modules/arraymodule.c - array_as_sequence - -Modules/_collectionsmodule.c - deque_as_sequence - -Modules/_ctypes/_ctypes.c - CDataType_as_sequence - -Modules/_ctypes/_ctypes.c - Array_as_sequence - -Modules/_ctypes/_ctypes.c - Pointer_as_sequence - -Modules/_elementtree.c - element_as_sequence - -Modules/mmapmodule.c - mmap_as_sequence - -Objects/bytearrayobject.c - bytearray_as_sequence - -Objects/bytesobject.c - bytes_as_sequence - -Objects/descrobject.c - mappingproxy_as_sequence - -Objects/dictobject.c - dict_as_sequence - -Objects/dictobject.c - dictkeys_as_sequence - -Objects/dictobject.c - dictitems_as_sequence - -Objects/dictobject.c - dictvalues_as_sequence - -Objects/listobject.c - list_as_sequence - -Objects/memoryobject.c - memory_as_sequence - -Objects/rangeobject.c - range_as_sequence - -Objects/setobject.c - set_as_sequence - -Objects/tupleobject.c - tuple_as_sequence - -Objects/unicodeobject.c - unicode_as_sequence - -Objects/weakrefobject.c - proxy_as_sequence - -Python/context.c - PyContext_as_sequence - -Python/hamt.c - PyHamt_as_sequence - - -# PyMappingMethods -Modules/arraymodule.c - array_as_mapping - -Modules/_ctypes/_ctypes.c - Array_as_mapping - -Modules/_ctypes/_ctypes.c - Pointer_as_mapping - -Modules/_decimal/_decimal.c - signaldict_as_mapping - -Modules/_elementtree.c - element_as_mapping - -Modules/mmapmodule.c - mmap_as_mapping - -Modules/_sre.c - match_as_mapping - -Objects/bytearrayobject.c - bytearray_as_mapping - -Objects/bytesobject.c - bytes_as_mapping - -Objects/descrobject.c - mappingproxy_as_mapping - -Objects/dictobject.c - dict_as_mapping - -Objects/genericaliasobject.c - ga_as_mapping - -Objects/listobject.c - list_as_mapping - -Objects/memoryobject.c - memory_as_mapping - -Objects/odictobject.c - odict_as_mapping - -Objects/rangeobject.c - range_as_mapping - -Objects/tupleobject.c - tuple_as_mapping - -Objects/unicodeobject.c - unicode_as_mapping - -Objects/unionobject.c - union_as_mapping - -Objects/weakrefobject.c - proxy_as_mapping - -Python/context.c - PyContext_as_mapping - -Python/hamt.c - PyHamtIterator_as_mapping - -Python/hamt.c - PyHamt_as_mapping - - -# PyAsyncMethods -Modules/_asynciomodule.c - FutureIterType_as_async - -Modules/_asynciomodule.c - FutureType_as_async - -Objects/genobject.c - async_gen_as_async - -Objects/genobject.c - async_gen_asend_as_async - -Objects/genobject.c - async_gen_athrow_as_async - -Objects/genobject.c - coro_as_async - -Objects/genobject.c - gen_as_async - -Objects/iterobject.c - anextawaitable_as_async - - -# PyBufferProcs -Modules/arraymodule.c - array_as_buffer - -Modules/_ctypes/_ctypes.c - PyCData_as_buffer - -Modules/_io/bytesio.c - bytesiobuf_as_buffer - -Modules/mmapmodule.c - mmap_as_buffer - -Objects/bytearrayobject.c - bytearray_as_buffer - -Objects/bytesobject.c - bytes_as_buffer - -Objects/memoryobject.c - memory_as_buffer - -Objects/picklebufobject.c - picklebuf_as_buffer - - -# PyGetSetDef -Modules/_asynciomodule.c - FutureType_getsetlist - -Modules/_asynciomodule.c - TaskStepMethWrapper_getsetlist - -Modules/_asynciomodule.c - TaskType_getsetlist - -Modules/_blake2/blake2b_impl.c - py_blake2b_getsetters - -Modules/_blake2/blake2s_impl.c - py_blake2s_getsetters - -Modules/_collectionsmodule.c - deque_getset - -Modules/_csv.c - Dialect_getsetlist - -Modules/_ctypes/_ctypes.c - CharArray_getsets - -Modules/_ctypes/_ctypes.c - Pointer_getsets - -Modules/_ctypes/_ctypes.c - PyCFuncPtr_getsets - -Modules/_ctypes/_ctypes.c - Simple_getsets - -Modules/_ctypes/_ctypes.c - WCharArray_getsets - -Modules/_ctypes/cfield.c - PyCField_getset - -Modules/_cursesmodule.c - PyCursesWindow_getsets - -Modules/_datetimemodule.c - date_getset - -Modules/_datetimemodule.c - datetime_getset - -Modules/_datetimemodule.c - iso_calendar_date_getset - -Modules/_datetimemodule.c - time_getset - -Modules/_decimal/_decimal.c - context_getsets - -Modules/_decimal/_decimal.c - dec_getsets - -Modules/_elementtree.c - element_getsetlist - -Modules/_elementtree.c - xmlparser_getsetlist - -Modules/_functoolsmodule.c - lru_cache_getsetlist - -Modules/_functoolsmodule.c - partial_getsetlist - -Modules/_hashopenssl.c - EVPXOF_getseters - -Modules/_hashopenssl.c - EVP_getseters - -Modules/_hashopenssl.c - HMAC_getset - -Modules/_io/bufferedio.c - bufferedrandom_getset - -Modules/_io/bufferedio.c - bufferedreader_getset - -Modules/_io/bufferedio.c - bufferedrwpair_getset - -Modules/_io/bufferedio.c - bufferedwriter_getset - -Modules/_io/bytesio.c - bytesio_getsetlist - -Modules/_io/fileio.c - fileio_getsetlist - -Modules/_io/iobase.c - iobase_getset - -Modules/_io/stringio.c - stringio_getset - -Modules/_io/textio.c - incrementalnewlinedecoder_getset - -Modules/_io/textio.c - textiobase_getset - -Modules/_io/textio.c - textiowrapper_getset - -Modules/_io/winconsoleio.c - winconsoleio_getsetlist - -Modules/_pickle.c - Pickler_getsets - -Modules/_pickle.c - Unpickler_getsets - -Modules/_sha3/sha3module.c - SHA3_getseters - -Modules/_sqlite/connection.c - connection_getset - -Modules/_sre.c - match_getset - -Modules/_sre.c - pattern_getset - -Modules/_ssl.c - PySSLSession_getsetlist - -Modules/_ssl.c - context_getsetlist - -Modules/_ssl.c - memory_bio_getsetlist - -Modules/_ssl.c - ssl_getsetlist - -Modules/_struct.c - s_getsetlist - -Modules/_tkinter.c - PyTclObject_getsetlist - -Modules/_xxsubinterpretersmodule.c - channelid_getsets - -Modules/arraymodule.c - array_getsets - -Modules/cjkcodecs/multibytecodec.c - codecctx_getsets - -Modules/md5module.c - MD5_getseters - -Modules/mmapmodule.c - mmap_object_getset - -Modules/ossaudiodev.c - oss_getsetlist - -Modules/overlapped.c - Overlapped_getsets - -Modules/pyexpat.c - xmlparse_getsetlist - -Modules/selectmodule.c - devpoll_getsetlist - -Modules/selectmodule.c - kqueue_queue_getsetlist - -Modules/selectmodule.c - pyepoll_getsetlist - -Modules/sha1module.c - SHA1_getseters - -Modules/sha256module.c - SHA_getseters - -Modules/sha512module.c - SHA_getseters - -Modules/socketmodule.c - sock_getsetlist - -Modules/xxlimited.c - Xxo_getsetlist - -Modules/xxsubtype.c - spamlist_getsets - -Objects/cellobject.c - cell_getsetlist - -Objects/classobject.c - instancemethod_getset - -Objects/classobject.c - method_getset - -Objects/codeobject.c - code_getsetlist - -Objects/descrobject.c - getset_getset - -Objects/descrobject.c - member_getset - -Objects/descrobject.c - method_getset - -Objects/descrobject.c - property_getsetlist - -Objects/descrobject.c - wrapper_getsets - -Objects/descrobject.c - wrapperdescr_getset - -Objects/dictobject.c - dictview_getset - -Objects/exceptions.c - BaseException_getset - -Objects/exceptions.c - OSError_getset - -Objects/fileobject.c - stdprinter_getsetlist - -Objects/floatobject.c - float_getset - -Objects/frameobject.c - frame_getsetlist - -Objects/funcobject.c - cm_getsetlist - -Objects/funcobject.c - func_getsetlist - -Objects/funcobject.c - sm_getsetlist - -Objects/genericaliasobject.c - ga_properties - -Objects/genobject.c - async_gen_getsetlist - -Objects/genobject.c - coro_getsetlist - -Objects/genobject.c - gen_getsetlist - -Objects/longobject.c - long_getset - -Objects/memoryobject.c - memory_getsetlist - -Objects/methodobject.c - meth_getsets - -Objects/moduleobject.c - module_getsets - -Objects/odictobject.c - odict_getset - -Objects/typeobject.c - object_getsets - -Objects/typeobject.c - subtype_getsets_dict_only - -Objects/typeobject.c - subtype_getsets_full - -Objects/typeobject.c - subtype_getsets_weakref_only - -Objects/typeobject.c - type_getsets - -Objects/unionobject.c - union_properties - -Python/Python-ast.c - ast_type_getsets - -Python/context.c - PyContextTokenType_getsetlist - -Python/traceback.c - tb_getsetters - - -#----------------------- -# for heap types - -# PyType_Slot -Modules/_abc.c - _abc_data_type_spec_slots - -Modules/_blake2/blake2b_impl.c - blake2b_type_slots - -Modules/_blake2/blake2s_impl.c - blake2s_type_slots - -Modules/_bz2module.c - bz2_compressor_type_slots - -Modules/_bz2module.c - bz2_decompressor_type_slots - -Modules/_csv.c - Dialect_Type_slots - -Modules/_csv.c - Reader_Type_slots - -Modules/_csv.c - Writer_Type_slots - -Modules/_csv.c - error_slots - -Modules/_curses_panel.c - PyCursesPanel_Type_slots - -Modules/_dbmmodule.c - dbmtype_spec_slots - -Modules/_functoolsmodule.c - keyobject_type_slots - -Modules/_functoolsmodule.c - lru_cache_type_slots - -Modules/_functoolsmodule.c - lru_list_elem_type_slots - -Modules/_functoolsmodule.c - partial_type_slots - -Modules/_gdbmmodule.c - gdbmtype_spec_slots - -Modules/_hashopenssl.c - EVPXOFtype_slots - -Modules/_hashopenssl.c - EVPtype_slots - -Modules/_hashopenssl.c - HMACtype_slots - -Modules/_json.c - PyEncoderType_slots - -Modules/_json.c - PyScannerType_slots - -Modules/_lsprof.c - _lsprof_profiler_type_spec_slots - -Modules/_lzmamodule.c - lzma_compressor_type_slots - -Modules/_lzmamodule.c - lzma_decompressor_type_slots - -Modules/_operator.c - attrgetter_type_slots - -Modules/_operator.c - itemgetter_type_slots - -Modules/_operator.c - methodcaller_type_slots - -Modules/_queuemodule.c - simplequeue_slots - -Modules/_randommodule.c - Random_Type_slots - -Modules/_sha3/sha3module.c - SHAKE128slots - -Modules/_sha3/sha3module.c - SHAKE256slots - -Modules/_sha3/sha3module.c - sha3_224_slots - -Modules/_sha3/sha3module.c - sha3_256_slots - -Modules/_sha3/sha3module.c - sha3_384_slots - -Modules/_sha3/sha3module.c - sha3_512_slots - -Modules/_sha3/sha3module.c - type_slots_obj - -Modules/_sqlite/connection.c - connection_slots - -Modules/_sqlite/cursor.c - cursor_slots - -Modules/_sqlite/prepare_protocol.c - type_slots - -Modules/_sqlite/row.c - row_slots - -Modules/_sqlite/statement.c - stmt_slots - -Modules/_sre.c - match_slots - -Modules/_sre.c - pattern_slots - -Modules/_sre.c - scanner_slots - -Modules/_ssl.c - PySSLContext_slots - -Modules/_ssl.c - PySSLMemoryBIO_slots - -Modules/_ssl.c - PySSLSession_slots - -Modules/_ssl.c - PySSLSocket_slots - -Modules/_ssl.c - sslerror_type_slots - -Modules/_ssl/cert.c - PySSLCertificate_slots - -Modules/_struct.c - PyStructType_slots - -Modules/_struct.c - unpackiter_type_slots - -Modules/_testcapimodule.c - HeapTypeNameType_slots - -Modules/_testcapimodule.c - NullTpDocType_slots - -Modules/_threadmodule.c - local_dummy_type_slots - -Modules/_threadmodule.c - local_type_slots - -Modules/_threadmodule.c - lock_type_slots - -Modules/_threadmodule.c - rlock_type_slots - -Modules/_tkinter.c - PyTclObject_Type_slots - -Modules/_tkinter.c - Tkapp_Type_slots - -Modules/_tkinter.c - Tktt_Type_slots - -Modules/_winapi.c - winapi_overlapped_type_slots - -Modules/arraymodule.c - array_slots - -Modules/arraymodule.c - arrayiter_slots - -Modules/cjkcodecs/multibytecodec.c - decoder_slots - -Modules/cjkcodecs/multibytecodec.c - encoder_slots - -Modules/cjkcodecs/multibytecodec.c - multibytecodec_slots - -Modules/cjkcodecs/multibytecodec.c - reader_slots - -Modules/cjkcodecs/multibytecodec.c - writer_slots - -Modules/md5module.c - md5_type_slots - -Modules/mmapmodule.c - mmap_object_slots - -Modules/overlapped.c - overlapped_type_slots - -Modules/posixmodule.c - DirEntryType_slots - -Modules/posixmodule.c - ScandirIteratorType_slots - -Modules/pyexpat.c - _xml_parse_type_spec_slots - -Modules/selectmodule.c - devpoll_Type_slots - -Modules/selectmodule.c - kqueue_event_Type_slots - -Modules/selectmodule.c - kqueue_queue_Type_slots - -Modules/selectmodule.c - poll_Type_slots - -Modules/selectmodule.c - pyEpoll_Type_slots - -Modules/sha1module.c - sha1_type_slots - -Modules/sha256module.c - sha256_types_slots - -Modules/sha512module.c - sha512_sha384_type_slots - -Modules/sha512module.c - sha512_sha512_type_slots - -Modules/unicodedata.c - ucd_type_slots - -Modules/xxlimited.c - Null_Type_slots - -Modules/xxlimited.c - Str_Type_slots - -Modules/xxlimited.c - Xxo_Type_slots - -Modules/xxlimited_35.c - Null_Type_slots - -Modules/xxlimited_35.c - Str_Type_slots - -Modules/xxlimited_35.c - Xxo_Type_slots - -Modules/zlibmodule.c - Comptype_slots - -Modules/zlibmodule.c - Decomptype_slots - -Python/Python-ast.c - AST_type_slots - -Python/Python-tokenize.c - tokenizeriter_slots - - -# PyType_Spec -Modules/_abc.c - _abc_data_type_spec - -Modules/_blake2/blake2b_impl.c - blake2b_type_spec - -Modules/_blake2/blake2s_impl.c - blake2s_type_spec - -Modules/_bz2module.c - bz2_compressor_type_spec - -Modules/_bz2module.c - bz2_decompressor_type_spec - -Modules/_csv.c - Dialect_Type_spec - -Modules/_csv.c - Reader_Type_spec - -Modules/_csv.c - Writer_Type_spec - -Modules/_csv.c - error_spec - -Modules/_curses_panel.c - PyCursesPanel_Type_spec - -Modules/_dbmmodule.c - dbmtype_spec - -Modules/_functoolsmodule.c - keyobject_type_spec - -Modules/_functoolsmodule.c - lru_cache_type_spec - -Modules/_functoolsmodule.c - lru_list_elem_type_spec - -Modules/_functoolsmodule.c - partial_type_spec - -Modules/_gdbmmodule.c - gdbmtype_spec - -Modules/_hashopenssl.c - EVPXOFtype_spec - -Modules/_hashopenssl.c - EVPtype_spec - -Modules/_hashopenssl.c - HMACtype_spec - -Modules/_json.c - PyEncoderType_spec - -Modules/_json.c - PyScannerType_spec - -Modules/_lsprof.c - _lsprof_profiler_type_spec - -Modules/_lzmamodule.c - lzma_compressor_type_spec - -Modules/_lzmamodule.c - lzma_decompressor_type_spec - -Modules/_operator.c - attrgetter_type_spec - -Modules/_operator.c - itemgetter_type_spec - -Modules/_operator.c - methodcaller_type_spec - -Modules/_queuemodule.c - simplequeue_spec - -Modules/_randommodule.c - Random_Type_spec - -Modules/_sha3/sha3module.c - SHAKE128_spec - -Modules/_sha3/sha3module.c - SHAKE256_spec - -Modules/_sha3/sha3module.c - sha3_224_spec - -Modules/_sha3/sha3module.c - sha3_256_spec - -Modules/_sha3/sha3module.c - sha3_384_spec - -Modules/_sha3/sha3module.c - sha3_512_spec - -Modules/_sha3/sha3module.c - type_spec_obj - -Modules/_sqlite/connection.c - connection_spec - -Modules/_sqlite/cursor.c - cursor_spec - -Modules/_sqlite/prepare_protocol.c - type_spec - -Modules/_sqlite/row.c - row_spec - -Modules/_sqlite/statement.c - stmt_spec - -Modules/_sre.c - match_spec - -Modules/_sre.c - pattern_spec - -Modules/_sre.c - scanner_spec - -Modules/_ssl.c - PySSLContext_spec - -Modules/_ssl.c - PySSLMemoryBIO_spec - -Modules/_ssl.c - PySSLSession_spec - -Modules/_ssl.c - PySSLSocket_spec - -Modules/_ssl.c - sslerror_type_spec - -Modules/_ssl/cert.c - PySSLCertificate_spec - -Modules/_struct.c - PyStructType_spec - -Modules/_struct.c - unpackiter_type_spec - -Modules/_testcapimodule.c - HeapTypeNameType_Spec - -Modules/_testcapimodule.c - NullTpDocType_spec - -Modules/_threadmodule.c - local_dummy_type_spec - -Modules/_threadmodule.c - local_type_spec - -Modules/_threadmodule.c - lock_type_spec - -Modules/_threadmodule.c - rlock_type_spec - -Modules/_tkinter.c - PyTclObject_Type_spec - -Modules/_tkinter.c - Tkapp_Type_spec - -Modules/_tkinter.c - Tktt_Type_spec - -Modules/_winapi.c - winapi_overlapped_type_spec - -Modules/_zoneinfo.c - DAYS_BEFORE_MONTH - -Modules/_zoneinfo.c - DAYS_IN_MONTH - -Modules/arraymodule.c - array_spec - -Modules/arraymodule.c - arrayiter_spec - -Modules/cjkcodecs/multibytecodec.c - decoder_spec - -Modules/cjkcodecs/multibytecodec.c - encoder_spec - -Modules/cjkcodecs/multibytecodec.c - multibytecodec_spec - -Modules/cjkcodecs/multibytecodec.c - reader_spec - -Modules/cjkcodecs/multibytecodec.c - writer_spec - -Modules/md5module.c - md5_type_spec - -Modules/mmapmodule.c - mmap_object_spec - -Modules/overlapped.c - overlapped_type_spec - -Modules/posixmodule.c - DirEntryType_spec - -Modules/posixmodule.c - ScandirIteratorType_spec - -Modules/pyexpat.c - _xml_parse_type_spec - -Modules/selectmodule.c - devpoll_Type_spec - -Modules/selectmodule.c - kqueue_event_Type_spec - -Modules/selectmodule.c - kqueue_queue_Type_spec - -Modules/selectmodule.c - poll_Type_spec - -Modules/selectmodule.c - pyEpoll_Type_spec - -Modules/sha1module.c - sha1_type_spec - -Modules/sha256module.c - sha224_type_spec - -Modules/sha256module.c - sha256_type_spec - -Modules/sha512module.c - sha512_sha384_type_spec - -Modules/sha512module.c - sha512_sha512_type_spec - -Modules/unicodedata.c - ucd_type_spec - -Modules/xxlimited.c - Null_Type_spec - -Modules/xxlimited.c - Str_Type_spec - -Modules/xxlimited.c - Xxo_Type_spec - -Modules/xxlimited_35.c - Null_Type_spec - -Modules/xxlimited_35.c - Str_Type_spec - -Modules/xxlimited_35.c - Xxo_Type_spec - -Modules/zlibmodule.c - Comptype_spec - -Modules/zlibmodule.c - Decomptype_spec - -Python/Python-ast.c - AST_type_spec - -Python/Python-tokenize.c - tokenizeriter_spec - - -#----------------------- -# for structseq - -# PyStructSequence_Field[] -Modules/_cursesmodule.c - ncurses_version_fields - -Modules/grpmodule.c - struct_group_type_fields - -Modules/_lsprof.c - profiler_entry_fields - -Modules/_lsprof.c - profiler_subentry_fields - -Modules/posixmodule.c - stat_result_fields - -Modules/posixmodule.c - statvfs_result_fields - -Modules/posixmodule.c - waitid_result_fields - -Modules/posixmodule.c - uname_result_fields - -Modules/posixmodule.c - sched_param_fields - -Modules/posixmodule.c - times_result_fields - -Modules/posixmodule.c - TerminalSize_fields - -Modules/pwdmodule.c - struct_pwd_type_fields - -Modules/resource.c - struct_rusage_fields - -Modules/signalmodule.c - struct_siginfo_fields - -Modules/spwdmodule.c - struct_spwd_type_fields - -Modules/_threadmodule.c - ExceptHookArgs_fields - -Modules/timemodule.c - struct_time_type_fields - -Objects/floatobject.c - floatinfo_fields - -Objects/longobject.c - int_info_fields - -Python/errors.c - UnraisableHookArgs_fields - -Python/sysmodule.c - asyncgen_hooks_fields - -Python/sysmodule.c - hash_info_fields - -Python/sysmodule.c - windows_version_fields - -Python/sysmodule.c - flags_fields - -Python/sysmodule.c - version_info_fields - -Python/thread.c - threadinfo_fields - - -# PyStructSequence_Desc -Modules/_cursesmodule.c - ncurses_version_desc - -Modules/grpmodule.c - struct_group_type_desc - -Modules/_lsprof.c - profiler_entry_desc - -Modules/_lsprof.c - profiler_subentry_desc - -Modules/posixmodule.c - stat_result_desc - -Modules/posixmodule.c - statvfs_result_desc - -Modules/posixmodule.c - waitid_result_desc - -Modules/posixmodule.c - uname_result_desc - -Modules/posixmodule.c - sched_param_desc - -Modules/posixmodule.c - times_result_desc - -Modules/posixmodule.c - TerminalSize_desc - -Modules/pwdmodule.c - struct_pwd_type_desc - -Modules/resource.c - struct_rusage_desc - -Modules/signalmodule.c - struct_siginfo_desc - -Modules/spwdmodule.c - struct_spwd_type_desc - -Modules/_threadmodule.c - ExceptHookArgs_desc - -Modules/timemodule.c - struct_time_type_desc - -Objects/floatobject.c - floatinfo_desc - -Objects/longobject.c - int_info_desc - -Python/errors.c - UnraisableHookArgs_desc - -Python/sysmodule.c - asyncgen_hooks_desc - -Python/sysmodule.c - hash_info_desc - -Python/sysmodule.c - windows_version_desc - -Python/sysmodule.c - flags_desc - -Python/sysmodule.c - version_info_desc - -Python/thread.c - threadinfo_desc - - -#----------------------- -# other vars that are actually constant - -Modules/_csv.c - quote_styles - -Modules/_ctypes/cfield.c - ffi_type_double - -Modules/_ctypes/cfield.c - ffi_type_float - -Modules/_ctypes/cfield.c - ffi_type_longdouble - -Modules/_ctypes/cfield.c - ffi_type_pointer - -Modules/_ctypes/cfield.c - ffi_type_sint16 - -Modules/_ctypes/cfield.c - ffi_type_sint32 - -Modules/_ctypes/cfield.c - ffi_type_sint64 - -Modules/_ctypes/cfield.c - ffi_type_sint8 - -Modules/_ctypes/cfield.c - ffi_type_uint16 - -Modules/_ctypes/cfield.c - ffi_type_uint32 - -Modules/_ctypes/cfield.c - ffi_type_uint64 - -Modules/_ctypes/cfield.c - ffi_type_uint8 - -Modules/_ctypes/cfield.c - ffi_type_void - -Modules/_datetimemodule.c - epoch - -Modules/_datetimemodule.c - max_fold_seconds - -Modules/_datetimemodule.c datetime_isoformat specs - -Modules/_datetimemodule.c time_isoformat specs - -Modules/_decimal/_decimal.c - cond_map - -Modules/_decimal/_decimal.c - dec_signal_string - -Modules/_decimal/_decimal.c - dflt_ctx - -Modules/_decimal/_decimal.c - int_constants - -Modules/_decimal/_decimal.c - invalid_rounding_err - -Modules/_decimal/_decimal.c - invalid_signals_err - -Modules/_decimal/_decimal.c - signal_map - -Modules/_decimal/_decimal.c - ssize_constants - -Modules/_elementtree.c - ExpatMemoryHandler - -Modules/_io/_iomodule.c - static_types - -Modules/_io/textio.c - encodefuncs - -Modules/_localemodule.c - langinfo_constants - -Modules/_sqlite/module.c - error_codes - -Modules/_sre.c pattern_repr flag_names - -Modules/_struct.c - bigendian_table - -Modules/_struct.c - lilendian_table - -Modules/_tkinter.c - state_key - -Modules/_xxsubinterpretersmodule.c - _channelid_end_recv - -Modules/_xxsubinterpretersmodule.c - _channelid_end_send - -Modules/arraymodule.c - descriptors - -Modules/arraymodule.c - emptybuf - -Modules/cjkcodecs/cjkcodecs.h - __methods - -Modules/cmathmodule.c - acos_special_values - -Modules/cmathmodule.c - acosh_special_values - -Modules/cmathmodule.c - asinh_special_values - -Modules/cmathmodule.c - atanh_special_values - -Modules/cmathmodule.c - cosh_special_values - -Modules/cmathmodule.c - exp_special_values - -Modules/cmathmodule.c - log_special_values - -Modules/cmathmodule.c - rect_special_values - -Modules/cmathmodule.c - sinh_special_values - -Modules/cmathmodule.c - sqrt_special_values - -Modules/cmathmodule.c - tanh_special_values - -Modules/config.c - _PyImport_Inittab - -Modules/faulthandler.c - faulthandler_handlers - -Modules/getnameinfo.c - gni_afdl - -Modules/nismodule.c - TIMEOUT - -Modules/nismodule.c - aliases - -Modules/ossaudiodev.c - control_labels - -Modules/ossaudiodev.c - control_names - -Modules/posixmodule.c - posix_constants_confstr - -Modules/posixmodule.c - posix_constants_pathconf - -Modules/posixmodule.c - posix_constants_sysconf - -Modules/pyexpat.c - ExpatMemoryHandler - -Modules/pyexpat.c - error_info_of - -Modules/pyexpat.c - handler_info - -Modules/termios.c - termios_constants - -Modules/timemodule.c init_timezone YEAR - -Objects/bytearrayobject.c - _PyByteArray_empty_string - -Objects/complexobject.c - c_1 - -Objects/exceptions.c - static_exceptions - -Objects/genobject.c - ASYNC_GEN_IGNORED_EXIT_MSG - -Objects/genobject.c - NON_INIT_CORO_MSG - -Objects/longobject.c - _PyLong_DigitValue - -Objects/object.c - _Py_SwappedOp - -Objects/object.c - _Py_abstract_hack - -Objects/object.c - static_types - -Objects/obmalloc.c - _PyMem - -Objects/obmalloc.c - _PyMem_Debug - -Objects/obmalloc.c - _PyMem_Raw - -Objects/obmalloc.c - _PyObject - -Objects/obmalloc.c - usedpools - -Objects/typeobject.c - name_op - -Objects/unicodeobject.c - stripfuncnames - -Objects/unicodeobject.c - utf7_category - -Objects/unicodeobject.c unicode_decode_call_errorhandler_wchar argparse - -Objects/unicodeobject.c unicode_decode_call_errorhandler_writer argparse - -Objects/unicodeobject.c unicode_encode_call_errorhandler argparse - -Objects/unicodeobject.c unicode_translate_call_errorhandler argparse - -Parser/parser.c - reserved_keywords - -Parser/parser.c - soft_keywords - -Parser/tokenizer.c - type_comment_prefix - -Python/ast_opt.c fold_unaryop ops - -Python/codecs.c - Py_hexdigits - -Python/codecs.c - ucnhash_capi - -Python/codecs.c _PyCodecRegistry_Init methods - -Python/dynload_shlib.c - _PyImport_DynLoadFiletab - -Python/dynload_stub.c - _PyImport_DynLoadFiletab - -Python/frozen.c - aliases - -Python/frozen.c - bootstrap_modules - -Python/frozen.c - stdlib_modules - -Python/frozen.c - test_modules - -Python/getopt.c - longopts - -Python/import.c - _PyImport_Inittab - -Python/import.c - _PySys_ImplCacheTag - -Python/opcode_targets.h - opcode_targets - -Python/pyhash.c - PyHash_Func - -Python/pylifecycle.c - _C_LOCALE_WARNING - -Python/pylifecycle.c - _PyOS_mystrnicmp_hack - -Python/pylifecycle.c - _TARGET_LOCALES - -Python/specialize.c - adaptive_opcodes - -Python/specialize.c - cache_requirements - -Python/specialize.c - compare_masks - -Python/sysmodule.c - whatstrings - +## forward/extern references +Include/py_curses.h - PyCurses_API - +Include/pydecimal.h - _decimal_api - +Modules/_blake2/blake2module.c - blake2b_type_spec - +Modules/_blake2/blake2module.c - blake2s_type_spec - +Modules/_io/fileio.c - _Py_open_cloexec_works - +Modules/_io/_iomodule.h - PyIOBase_Type - +Modules/_io/_iomodule.h - PyRawIOBase_Type - +Modules/_io/_iomodule.h - PyBufferedIOBase_Type - +Modules/_io/_iomodule.h - PyTextIOBase_Type - +Modules/_io/_iomodule.h - PyFileIO_Type - +Modules/_io/_iomodule.h - PyBytesIO_Type - +Modules/_io/_iomodule.h - PyStringIO_Type - +Modules/_io/_iomodule.h - PyBufferedReader_Type - +Modules/_io/_iomodule.h - PyBufferedWriter_Type - +Modules/_io/_iomodule.h - PyBufferedRWPair_Type - +Modules/_io/_iomodule.h - PyBufferedRandom_Type - +Modules/_io/_iomodule.h - PyTextIOWrapper_Type - +Modules/_io/_iomodule.h - PyIncrementalNewlineDecoder_Type - +Modules/_io/_iomodule.h - _PyBytesIOBuffer_Type - +Modules/_io/_iomodule.h - _PyIO_Module - +Modules/_io/_iomodule.h - _PyIO_str_close - +Modules/_io/_iomodule.h - _PyIO_str_closed - +Modules/_io/_iomodule.h - _PyIO_str_decode - +Modules/_io/_iomodule.h - _PyIO_str_encode - +Modules/_io/_iomodule.h - _PyIO_str_fileno - +Modules/_io/_iomodule.h - _PyIO_str_flush - +Modules/_io/_iomodule.h - _PyIO_str_getstate - +Modules/_io/_iomodule.h - _PyIO_str_isatty - +Modules/_io/_iomodule.h - _PyIO_str_newlines - +Modules/_io/_iomodule.h - _PyIO_str_nl - +Modules/_io/_iomodule.h - _PyIO_str_peek - +Modules/_io/_iomodule.h - _PyIO_str_read - +Modules/_io/_iomodule.h - _PyIO_str_read1 - +Modules/_io/_iomodule.h - _PyIO_str_readable - +Modules/_io/_iomodule.h - _PyIO_str_readall - +Modules/_io/_iomodule.h - _PyIO_str_readinto - +Modules/_io/_iomodule.h - _PyIO_str_readline - +Modules/_io/_iomodule.h - _PyIO_str_reset - +Modules/_io/_iomodule.h - _PyIO_str_seek - +Modules/_io/_iomodule.h - _PyIO_str_seekable - +Modules/_io/_iomodule.h - _PyIO_str_setstate - +Modules/_io/_iomodule.h - _PyIO_str_tell - +Modules/_io/_iomodule.h - _PyIO_str_truncate - +Modules/_io/_iomodule.h - _PyIO_str_writable - +Modules/_io/_iomodule.h - _PyIO_str_write - +Modules/_io/_iomodule.h - _PyIO_empty_str - +Modules/_io/_iomodule.h - _PyIO_empty_bytes - +Modules/_multiprocessing/multiprocessing.h - _PyMp_SemLockType - +Modules/_sqlite/module.c - _pysqlite_converters - +Modules/_sqlite/module.c - _pysqlite_enable_callback_tracebacks - +Modules/_sqlite/module.c - pysqlite_BaseTypeAdapted - +Modules/_sqlite/module.h - pysqlite_global_state - +Modules/_testcapimodule.c - _PyBytesIOBuffer_Type - +Modules/posixmodule.c - _Py_open_cloexec_works - +Modules/posixmodule.c - environ - +Objects/object.c - _Py_GenericAliasIterType - +Objects/object.c - _PyMemoryIter_Type - +Objects/object.c - _PyLineIterator - +Objects/object.c - _PyPositionsIterator - +Python/perf_trampoline.c - _Py_trampoline_func_start - +Python/perf_trampoline.c - _Py_trampoline_func_end - +Python/importdl.h - _PyImport_DynLoadFiletab - +Modules/expat/xmlrole.c - prolog0 - +Modules/expat/xmlrole.c - prolog1 - +Modules/expat/xmlrole.c - prolog2 - +Modules/expat/xmlrole.c - doctype0 - +Modules/expat/xmlrole.c - doctype1 - +Modules/expat/xmlrole.c - doctype2 - +Modules/expat/xmlrole.c - doctype3 - +Modules/expat/xmlrole.c - doctype4 - +Modules/expat/xmlrole.c - doctype5 - +Modules/expat/xmlrole.c - internalSubset - +Modules/expat/xmlrole.c - entity0 - +Modules/expat/xmlrole.c - entity1 - +Modules/expat/xmlrole.c - entity2 - +Modules/expat/xmlrole.c - entity3 - +Modules/expat/xmlrole.c - entity4 - +Modules/expat/xmlrole.c - entity5 - +Modules/expat/xmlrole.c - entity6 - +Modules/expat/xmlrole.c - entity7 - +Modules/expat/xmlrole.c - entity8 - +Modules/expat/xmlrole.c - entity9 - +Modules/expat/xmlrole.c - entity10 - +Modules/expat/xmlrole.c - notation0 - +Modules/expat/xmlrole.c - notation1 - +Modules/expat/xmlrole.c - notation2 - +Modules/expat/xmlrole.c - notation3 - +Modules/expat/xmlrole.c - notation4 - +Modules/expat/xmlrole.c - attlist0 - +Modules/expat/xmlrole.c - attlist1 - +Modules/expat/xmlrole.c - attlist2 - +Modules/expat/xmlrole.c - attlist3 - +Modules/expat/xmlrole.c - attlist4 - +Modules/expat/xmlrole.c - attlist5 - +Modules/expat/xmlrole.c - attlist6 - +Modules/expat/xmlrole.c - attlist7 - +Modules/expat/xmlrole.c - attlist8 - +Modules/expat/xmlrole.c - attlist9 - +Modules/expat/xmlrole.c - element0 - +Modules/expat/xmlrole.c - element1 - +Modules/expat/xmlrole.c - element2 - +Modules/expat/xmlrole.c - element3 - +Modules/expat/xmlrole.c - element4 - +Modules/expat/xmlrole.c - element5 - +Modules/expat/xmlrole.c - element6 - +Modules/expat/xmlrole.c - element7 - +Modules/expat/xmlrole.c - externalSubset0 - +Modules/expat/xmlrole.c - externalSubset1 - +Modules/expat/xmlrole.c - condSect0 - +Modules/expat/xmlrole.c - condSect1 - +Modules/expat/xmlrole.c - condSect2 - +Modules/expat/xmlrole.c - declClose - +Modules/expat/xmlrole.c - error - + +## other +Modules/_io/_iomodule.c - _PyIO_Module - +Modules/_sqlite/module.c - _sqlite3module - diff --git a/Tools/c-analyzer/distutils/README b/Tools/c-analyzer/distutils/README new file mode 100644 index 00000000..b260b8e0 --- /dev/null +++ b/Tools/c-analyzer/distutils/README @@ -0,0 +1,2 @@ +This is a partial copy of distutils as it was removed in 0faa0ba240e. +It only includes the parts needed by the C parser. diff --git a/Lib/tkinter/test/test_tkinter/__init__.py b/Tools/c-analyzer/distutils/__init__.py similarity index 100% rename from Lib/tkinter/test/test_tkinter/__init__.py rename to Tools/c-analyzer/distutils/__init__.py diff --git a/Tools/c-analyzer/distutils/_msvccompiler.py b/Tools/c-analyzer/distutils/_msvccompiler.py new file mode 100644 index 00000000..1e67870d --- /dev/null +++ b/Tools/c-analyzer/distutils/_msvccompiler.py @@ -0,0 +1,203 @@ +"""distutils._msvccompiler + +Contains MSVCCompiler, an implementation of the abstract CCompiler class +for Microsoft Visual Studio 2015. + +The module is compatible with VS 2015 and later. You can find legacy support +for older versions in distutils.msvc9compiler and distutils.msvccompiler. +""" + +# Written by Perry Stoll +# hacked by Robin Becker and Thomas Heller to do a better job of +# finding DevStudio (through the registry) +# ported to VS 2005 and VS 2008 by Christian Heimes +# ported to VS 2015 by Steve Dower + +import os +import subprocess +import winreg + +from distutils.errors import DistutilsPlatformError +from distutils.ccompiler import CCompiler +from distutils import log + +from itertools import count + +def _find_vc2015(): + try: + key = winreg.OpenKeyEx( + winreg.HKEY_LOCAL_MACHINE, + r"Software\Microsoft\VisualStudio\SxS\VC7", + access=winreg.KEY_READ | winreg.KEY_WOW64_32KEY + ) + except OSError: + log.debug("Visual C++ is not registered") + return None, None + + best_version = 0 + best_dir = None + with key: + for i in count(): + try: + v, vc_dir, vt = winreg.EnumValue(key, i) + except OSError: + break + if v and vt == winreg.REG_SZ and os.path.isdir(vc_dir): + try: + version = int(float(v)) + except (ValueError, TypeError): + continue + if version >= 14 and version > best_version: + best_version, best_dir = version, vc_dir + return best_version, best_dir + +def _find_vc2017(): + """Returns "15, path" based on the result of invoking vswhere.exe + If no install is found, returns "None, None" + + The version is returned to avoid unnecessarily changing the function + result. It may be ignored when the path is not None. + + If vswhere.exe is not available, by definition, VS 2017 is not + installed. + """ + root = os.environ.get("ProgramFiles(x86)") or os.environ.get("ProgramFiles") + if not root: + return None, None + + try: + path = subprocess.check_output([ + os.path.join(root, "Microsoft Visual Studio", "Installer", "vswhere.exe"), + "-latest", + "-prerelease", + "-requires", "Microsoft.VisualStudio.Component.VC.Tools.x86.x64", + "-property", "installationPath", + "-products", "*", + ], encoding="mbcs", errors="strict").strip() + except (subprocess.CalledProcessError, OSError, UnicodeDecodeError): + return None, None + + path = os.path.join(path, "VC", "Auxiliary", "Build") + if os.path.isdir(path): + return 15, path + + return None, None + +PLAT_SPEC_TO_RUNTIME = { + 'x86' : 'x86', + 'x86_amd64' : 'x64', + 'x86_arm' : 'arm', + 'x86_arm64' : 'arm64' +} + +def _find_vcvarsall(plat_spec): + # bpo-38597: Removed vcruntime return value + _, best_dir = _find_vc2017() + + if not best_dir: + best_version, best_dir = _find_vc2015() + + if not best_dir: + log.debug("No suitable Visual C++ version found") + return None, None + + vcvarsall = os.path.join(best_dir, "vcvarsall.bat") + if not os.path.isfile(vcvarsall): + log.debug("%s cannot be found", vcvarsall) + return None, None + + return vcvarsall, None + +def _get_vc_env(plat_spec): + if os.getenv("DISTUTILS_USE_SDK"): + return { + key.lower(): value + for key, value in os.environ.items() + } + + vcvarsall, _ = _find_vcvarsall(plat_spec) + if not vcvarsall: + raise DistutilsPlatformError("Unable to find vcvarsall.bat") + + try: + out = subprocess.check_output( + 'cmd /u /c "{}" {} && set'.format(vcvarsall, plat_spec), + stderr=subprocess.STDOUT, + ).decode('utf-16le', errors='replace') + except subprocess.CalledProcessError as exc: + log.error(exc.output) + raise DistutilsPlatformError("Error executing {}" + .format(exc.cmd)) + + env = { + key.lower(): value + for key, _, value in + (line.partition('=') for line in out.splitlines()) + if key and value + } + + return env + +def _find_exe(exe, paths=None): + """Return path to an MSVC executable program. + + Tries to find the program in several places: first, one of the + MSVC program search paths from the registry; next, the directories + in the PATH environment variable. If any of those work, return an + absolute path that is known to exist. If none of them work, just + return the original program name, 'exe'. + """ + if not paths: + paths = os.getenv('path').split(os.pathsep) + for p in paths: + fn = os.path.join(os.path.abspath(p), exe) + if os.path.isfile(fn): + return fn + return exe + +# A map keyed by get_platform() return values to values accepted by +# 'vcvarsall.bat'. Always cross-compile from x86 to work with the +# lighter-weight MSVC installs that do not include native 64-bit tools. +PLAT_TO_VCVARS = { + 'win32' : 'x86', + 'win-amd64' : 'x86_amd64', + 'win-arm32' : 'x86_arm', + 'win-arm64' : 'x86_arm64' +} + +class MSVCCompiler(CCompiler) : + """Concrete class that implements an interface to Microsoft Visual C++, + as defined by the CCompiler abstract class.""" + + compiler_type = 'msvc' + + # Just set this so CCompiler's constructor doesn't barf. We currently + # don't use the 'set_executables()' bureaucracy provided by CCompiler, + # as it really isn't necessary for this sort of single-compiler class. + # Would be nice to have a consistent interface with UnixCCompiler, + # though, so it's worth thinking about. + executables = {} + + # Private class data (need to distinguish C from C++ source for compiler) + _c_extensions = ['.c'] + _cpp_extensions = ['.cc', '.cpp', '.cxx'] + _rc_extensions = ['.rc'] + _mc_extensions = ['.mc'] + + # Needed for the filename generation methods provided by the + # base class, CCompiler. + src_extensions = (_c_extensions + _cpp_extensions + + _rc_extensions + _mc_extensions) + res_extension = '.res' + obj_extension = '.obj' + static_lib_extension = '.lib' + shared_lib_extension = '.dll' + static_lib_format = shared_lib_format = '%s%s' + exe_extension = '.exe' + + + def __init__(self, verbose=0, dry_run=0, force=0): + CCompiler.__init__ (self, verbose, dry_run, force) + # target platform (.plat_name is consistent with 'bdist') + self.plat_name = None + self.initialized = False diff --git a/Tools/c-analyzer/distutils/bcppcompiler.py b/Tools/c-analyzer/distutils/bcppcompiler.py new file mode 100644 index 00000000..4575b665 --- /dev/null +++ b/Tools/c-analyzer/distutils/bcppcompiler.py @@ -0,0 +1,109 @@ +"""distutils.bcppcompiler + +Contains BorlandCCompiler, an implementation of the abstract CCompiler class +for the Borland C++ compiler. +""" + +# This implementation by Lyle Johnson, based on the original msvccompiler.py +# module and using the directions originally published by Gordon Williams. + +# XXX looks like there's a LOT of overlap between these two classes: +# someone should sit down and factor out the common code as +# WindowsCCompiler! --GPW + + +import os +from distutils.errors import DistutilsExecError, CompileError +from distutils.ccompiler import \ + CCompiler, gen_preprocess_options +from distutils.dep_util import newer + +class BCPPCompiler(CCompiler) : + """Concrete class that implements an interface to the Borland C/C++ + compiler, as defined by the CCompiler abstract class. + """ + + compiler_type = 'bcpp' + + # Just set this so CCompiler's constructor doesn't barf. We currently + # don't use the 'set_executables()' bureaucracy provided by CCompiler, + # as it really isn't necessary for this sort of single-compiler class. + # Would be nice to have a consistent interface with UnixCCompiler, + # though, so it's worth thinking about. + executables = {} + + # Private class data (need to distinguish C from C++ source for compiler) + _c_extensions = ['.c'] + _cpp_extensions = ['.cc', '.cpp', '.cxx'] + + # Needed for the filename generation methods provided by the + # base class, CCompiler. + src_extensions = _c_extensions + _cpp_extensions + obj_extension = '.obj' + static_lib_extension = '.lib' + shared_lib_extension = '.dll' + static_lib_format = shared_lib_format = '%s%s' + exe_extension = '.exe' + + + def __init__ (self, + verbose=0, + dry_run=0, + force=0): + + CCompiler.__init__ (self, verbose, dry_run, force) + + # These executables are assumed to all be in the path. + # Borland doesn't seem to use any special registry settings to + # indicate their installation locations. + + self.cc = "bcc32.exe" + self.linker = "ilink32.exe" + self.lib = "tlib.exe" + + self.preprocess_options = None + self.compile_options = ['/tWM', '/O2', '/q', '/g0'] + self.compile_options_debug = ['/tWM', '/Od', '/q', '/g0'] + + self.ldflags_shared = ['/Tpd', '/Gn', '/q', '/x'] + self.ldflags_shared_debug = ['/Tpd', '/Gn', '/q', '/x'] + self.ldflags_static = [] + self.ldflags_exe = ['/Gn', '/q', '/x'] + self.ldflags_exe_debug = ['/Gn', '/q', '/x','/r'] + + + # -- Worker methods ------------------------------------------------ + + def preprocess (self, + source, + output_file=None, + macros=None, + include_dirs=None, + extra_preargs=None, + extra_postargs=None): + + (_, macros, include_dirs) = \ + self._fix_compile_args(None, macros, include_dirs) + pp_opts = gen_preprocess_options(macros, include_dirs) + pp_args = ['cpp32.exe'] + pp_opts + if output_file is not None: + pp_args.append('-o' + output_file) + if extra_preargs: + pp_args[:0] = extra_preargs + if extra_postargs: + pp_args.extend(extra_postargs) + pp_args.append(source) + + # We need to preprocess: either we're being forced to, or the + # source file is newer than the target (or the target doesn't + # exist). + if self.force or output_file is None or newer(source, output_file): + if output_file: + self.mkpath(os.path.dirname(output_file)) + try: + self.spawn(pp_args) + except DistutilsExecError as msg: + print(msg) + raise CompileError(msg) + + # preprocess() diff --git a/Tools/c-analyzer/distutils/ccompiler.py b/Tools/c-analyzer/distutils/ccompiler.py new file mode 100644 index 00000000..13e43103 --- /dev/null +++ b/Tools/c-analyzer/distutils/ccompiler.py @@ -0,0 +1,470 @@ +"""distutils.ccompiler + +Contains CCompiler, an abstract base class that defines the interface +for the Distutils compiler abstraction model.""" + +import sys, os, re +from distutils.errors import ( + DistutilsModuleError, DistutilsPlatformError, +) +from distutils.util import split_quoted + +class CCompiler: + """Abstract base class to define the interface that must be implemented + by real compiler classes. Also has some utility methods used by + several compiler classes. + + The basic idea behind a compiler abstraction class is that each + instance can be used for all the compile/link steps in building a + single project. Thus, attributes common to all of those compile and + link steps -- include directories, macros to define, libraries to link + against, etc. -- are attributes of the compiler instance. To allow for + variability in how individual files are treated, most of those + attributes may be varied on a per-compilation or per-link basis. + """ + + # 'compiler_type' is a class attribute that identifies this class. It + # keeps code that wants to know what kind of compiler it's dealing with + # from having to import all possible compiler classes just to do an + # 'isinstance'. In concrete CCompiler subclasses, 'compiler_type' + # should really, really be one of the keys of the 'compiler_class' + # dictionary (see below -- used by the 'new_compiler()' factory + # function) -- authors of new compiler interface classes are + # responsible for updating 'compiler_class'! + compiler_type = None + + # XXX things not handled by this compiler abstraction model: + # * client can't provide additional options for a compiler, + # e.g. warning, optimization, debugging flags. Perhaps this + # should be the domain of concrete compiler abstraction classes + # (UnixCCompiler, MSVCCompiler, etc.) -- or perhaps the base + # class should have methods for the common ones. + # * can't completely override the include or library searchg + # path, ie. no "cc -I -Idir1 -Idir2" or "cc -L -Ldir1 -Ldir2". + # I'm not sure how widely supported this is even by Unix + # compilers, much less on other platforms. And I'm even less + # sure how useful it is; maybe for cross-compiling, but + # support for that is a ways off. (And anyways, cross + # compilers probably have a dedicated binary with the + # right paths compiled in. I hope.) + # * can't do really freaky things with the library list/library + # dirs, e.g. "-Ldir1 -lfoo -Ldir2 -lfoo" to link against + # different versions of libfoo.a in different locations. I + # think this is useless without the ability to null out the + # library search path anyways. + + + # Subclasses that rely on the standard filename generation methods + # implemented below should override these; see the comment near + # those methods ('object_filenames()' et. al.) for details: + src_extensions = None # list of strings + obj_extension = None # string + static_lib_extension = None + shared_lib_extension = None # string + static_lib_format = None # format string + shared_lib_format = None # prob. same as static_lib_format + exe_extension = None # string + + # Default language settings. language_map is used to detect a source + # file or Extension target language, checking source filenames. + # language_order is used to detect the language precedence, when deciding + # what language to use when mixing source types. For example, if some + # extension has two files with ".c" extension, and one with ".cpp", it + # is still linked as c++. + language_map = {".c" : "c", + ".cc" : "c++", + ".cpp" : "c++", + ".cxx" : "c++", + ".m" : "objc", + } + language_order = ["c++", "objc", "c"] + + def __init__(self, verbose=0, dry_run=0, force=0): + self.dry_run = dry_run + self.force = force + self.verbose = verbose + + # 'output_dir': a common output directory for object, library, + # shared object, and shared library files + self.output_dir = None + + # 'macros': a list of macro definitions (or undefinitions). A + # macro definition is a 2-tuple (name, value), where the value is + # either a string or None (no explicit value). A macro + # undefinition is a 1-tuple (name,). + self.macros = [] + + # 'include_dirs': a list of directories to search for include files + self.include_dirs = [] + + # 'libraries': a list of libraries to include in any link + # (library names, not filenames: eg. "foo" not "libfoo.a") + self.libraries = [] + + # 'library_dirs': a list of directories to search for libraries + self.library_dirs = [] + + # 'runtime_library_dirs': a list of directories to search for + # shared libraries/objects at runtime + self.runtime_library_dirs = [] + + # 'objects': a list of object files (or similar, such as explicitly + # named library files) to include on any link + self.objects = [] + + for key in self.executables.keys(): + self.set_executable(key, self.executables[key]) + + def set_executables(self, **kwargs): + """Define the executables (and options for them) that will be run + to perform the various stages of compilation. The exact set of + executables that may be specified here depends on the compiler + class (via the 'executables' class attribute), but most will have: + compiler the C/C++ compiler + linker_so linker used to create shared objects and libraries + linker_exe linker used to create binary executables + archiver static library creator + + On platforms with a command-line (Unix, DOS/Windows), each of these + is a string that will be split into executable name and (optional) + list of arguments. (Splitting the string is done similarly to how + Unix shells operate: words are delimited by spaces, but quotes and + backslashes can override this. See + 'distutils.util.split_quoted()'.) + """ + + # Note that some CCompiler implementation classes will define class + # attributes 'cpp', 'cc', etc. with hard-coded executable names; + # this is appropriate when a compiler class is for exactly one + # compiler/OS combination (eg. MSVCCompiler). Other compiler + # classes (UnixCCompiler, in particular) are driven by information + # discovered at run-time, since there are many different ways to do + # basically the same things with Unix C compilers. + + for key in kwargs: + if key not in self.executables: + raise ValueError("unknown executable '%s' for class %s" % + (key, self.__class__.__name__)) + self.set_executable(key, kwargs[key]) + + def set_executable(self, key, value): + if isinstance(value, str): + setattr(self, key, split_quoted(value)) + else: + setattr(self, key, value) + + def _find_macro(self, name): + i = 0 + for defn in self.macros: + if defn[0] == name: + return i + i += 1 + return None + + def _check_macro_definitions(self, definitions): + """Ensures that every element of 'definitions' is a valid macro + definition, ie. either (name,value) 2-tuple or a (name,) tuple. Do + nothing if all definitions are OK, raise TypeError otherwise. + """ + for defn in definitions: + if not (isinstance(defn, tuple) and + (len(defn) in (1, 2) and + (isinstance (defn[1], str) or defn[1] is None)) and + isinstance (defn[0], str)): + raise TypeError(("invalid macro definition '%s': " % defn) + \ + "must be tuple (string,), (string, string), or " + \ + "(string, None)") + + + # -- Bookkeeping methods ------------------------------------------- + + def define_macro(self, name, value=None): + """Define a preprocessor macro for all compilations driven by this + compiler object. The optional parameter 'value' should be a + string; if it is not supplied, then the macro will be defined + without an explicit value and the exact outcome depends on the + compiler used (XXX true? does ANSI say anything about this?) + """ + # Delete from the list of macro definitions/undefinitions if + # already there (so that this one will take precedence). + i = self._find_macro (name) + if i is not None: + del self.macros[i] + + self.macros.append((name, value)) + + def undefine_macro(self, name): + """Undefine a preprocessor macro for all compilations driven by + this compiler object. If the same macro is defined by + 'define_macro()' and undefined by 'undefine_macro()' the last call + takes precedence (including multiple redefinitions or + undefinitions). If the macro is redefined/undefined on a + per-compilation basis (ie. in the call to 'compile()'), then that + takes precedence. + """ + # Delete from the list of macro definitions/undefinitions if + # already there (so that this one will take precedence). + i = self._find_macro (name) + if i is not None: + del self.macros[i] + + undefn = (name,) + self.macros.append(undefn) + + def add_include_dir(self, dir): + """Add 'dir' to the list of directories that will be searched for + header files. The compiler is instructed to search directories in + the order in which they are supplied by successive calls to + 'add_include_dir()'. + """ + self.include_dirs.append(dir) + + def set_include_dirs(self, dirs): + """Set the list of directories that will be searched to 'dirs' (a + list of strings). Overrides any preceding calls to + 'add_include_dir()'; subsequence calls to 'add_include_dir()' add + to the list passed to 'set_include_dirs()'. This does not affect + any list of standard include directories that the compiler may + search by default. + """ + self.include_dirs = dirs[:] + + + # -- Private utility methods -------------------------------------- + # (here for the convenience of subclasses) + + # Helper method to prep compiler in subclass compile() methods + + def _fix_compile_args(self, output_dir, macros, include_dirs): + """Typecheck and fix-up some of the arguments to the 'compile()' + method, and return fixed-up values. Specifically: if 'output_dir' + is None, replaces it with 'self.output_dir'; ensures that 'macros' + is a list, and augments it with 'self.macros'; ensures that + 'include_dirs' is a list, and augments it with 'self.include_dirs'. + Guarantees that the returned values are of the correct type, + i.e. for 'output_dir' either string or None, and for 'macros' and + 'include_dirs' either list or None. + """ + if output_dir is None: + output_dir = self.output_dir + elif not isinstance(output_dir, str): + raise TypeError("'output_dir' must be a string or None") + + if macros is None: + macros = self.macros + elif isinstance(macros, list): + macros = macros + (self.macros or []) + else: + raise TypeError("'macros' (if supplied) must be a list of tuples") + + if include_dirs is None: + include_dirs = self.include_dirs + elif isinstance(include_dirs, (list, tuple)): + include_dirs = list(include_dirs) + (self.include_dirs or []) + else: + raise TypeError( + "'include_dirs' (if supplied) must be a list of strings") + + return output_dir, macros, include_dirs + + + # -- Worker methods ------------------------------------------------ + # (must be implemented by subclasses) + + def preprocess(self, source, output_file=None, macros=None, + include_dirs=None, extra_preargs=None, extra_postargs=None): + """Preprocess a single C/C++ source file, named in 'source'. + Output will be written to file named 'output_file', or stdout if + 'output_file' not supplied. 'macros' is a list of macro + definitions as for 'compile()', which will augment the macros set + with 'define_macro()' and 'undefine_macro()'. 'include_dirs' is a + list of directory names that will be added to the default list. + + Raises PreprocessError on failure. + """ + pass + + + # -- Miscellaneous methods ----------------------------------------- + # These are all used by the 'gen_lib_options() function; there is + # no appropriate default implementation so subclasses should + # implement all of these. + +# def library_dir_option(self, dir): +# """Return the compiler option to add 'dir' to the list of +# directories searched for libraries. +# """ +# raise NotImplementedError +# +# def runtime_library_dir_option(self, dir): +# """Return the compiler option to add 'dir' to the list of +# directories searched for runtime libraries. +# """ +# raise NotImplementedError +# +# def library_option(self, lib): +# """Return the compiler option to add 'lib' to the list of libraries +# linked into the shared library or executable. +# """ +# raise NotImplementedError +# +# def find_library_file (self, dirs, lib, debug=0): +# """Search the specified list of directories for a static or shared +# library file 'lib' and return the full path to that file. If +# 'debug' true, look for a debugging version (if that makes sense on +# the current platform). Return None if 'lib' wasn't found in any of +# the specified directories. +# """ +# raise NotImplementedError + + + # -- Utility methods ----------------------------------------------- + + def spawn(self, cmd): + raise NotImplementedError + + +# Map a sys.platform/os.name ('posix', 'nt') to the default compiler +# type for that platform. Keys are interpreted as re match +# patterns. Order is important; platform mappings are preferred over +# OS names. +_default_compilers = ( + + # Platform string mappings + + # on a cygwin built python we can use gcc like an ordinary UNIXish + # compiler + ('cygwin.*', 'unix'), + + # OS name mappings + ('posix', 'unix'), + ('nt', 'msvc'), + + ) + +def get_default_compiler(osname=None, platform=None): + """Determine the default compiler to use for the given platform. + + osname should be one of the standard Python OS names (i.e. the + ones returned by os.name) and platform the common value + returned by sys.platform for the platform in question. + + The default values are os.name and sys.platform in case the + parameters are not given. + """ + if osname is None: + osname = os.name + if platform is None: + platform = sys.platform + for pattern, compiler in _default_compilers: + if re.match(pattern, platform) is not None or \ + re.match(pattern, osname) is not None: + return compiler + # Default to Unix compiler + return 'unix' + +# Map compiler types to (module_name, class_name) pairs -- ie. where to +# find the code that implements an interface to this compiler. (The module +# is assumed to be in the 'distutils' package.) +compiler_class = { 'unix': ('unixccompiler', 'UnixCCompiler', + "standard UNIX-style compiler"), + 'msvc': ('_msvccompiler', 'MSVCCompiler', + "Microsoft Visual C++"), + 'cygwin': ('cygwinccompiler', 'CygwinCCompiler', + "Cygwin port of GNU C Compiler for Win32"), + 'mingw32': ('cygwinccompiler', 'Mingw32CCompiler', + "Mingw32 port of GNU C Compiler for Win32"), + 'bcpp': ('bcppcompiler', 'BCPPCompiler', + "Borland C++ Compiler"), + } + + +def new_compiler(plat=None, compiler=None, verbose=0, dry_run=0, force=0): + """Generate an instance of some CCompiler subclass for the supplied + platform/compiler combination. 'plat' defaults to 'os.name' + (eg. 'posix', 'nt'), and 'compiler' defaults to the default compiler + for that platform. Currently only 'posix' and 'nt' are supported, and + the default compilers are "traditional Unix interface" (UnixCCompiler + class) and Visual C++ (MSVCCompiler class). Note that it's perfectly + possible to ask for a Unix compiler object under Windows, and a + Microsoft compiler object under Unix -- if you supply a value for + 'compiler', 'plat' is ignored. + """ + if plat is None: + plat = os.name + + try: + if compiler is None: + compiler = get_default_compiler(plat) + + (module_name, class_name, long_description) = compiler_class[compiler] + except KeyError: + msg = "don't know how to compile C/C++ code on platform '%s'" % plat + if compiler is not None: + msg = msg + " with '%s' compiler" % compiler + raise DistutilsPlatformError(msg) + + try: + module_name = "distutils." + module_name + __import__ (module_name) + module = sys.modules[module_name] + klass = vars(module)[class_name] + except ImportError: + raise + raise DistutilsModuleError( + "can't compile C/C++ code: unable to load module '%s'" % \ + module_name) + except KeyError: + raise DistutilsModuleError( + "can't compile C/C++ code: unable to find class '%s' " + "in module '%s'" % (class_name, module_name)) + + # XXX The None is necessary to preserve backwards compatibility + # with classes that expect verbose to be the first positional + # argument. + return klass(None, dry_run, force) + + +def gen_preprocess_options(macros, include_dirs): + """Generate C pre-processor options (-D, -U, -I) as used by at least + two types of compilers: the typical Unix compiler and Visual C++. + 'macros' is the usual thing, a list of 1- or 2-tuples, where (name,) + means undefine (-U) macro 'name', and (name,value) means define (-D) + macro 'name' to 'value'. 'include_dirs' is just a list of directory + names to be added to the header file search path (-I). Returns a list + of command-line options suitable for either Unix compilers or Visual + C++. + """ + # XXX it would be nice (mainly aesthetic, and so we don't generate + # stupid-looking command lines) to go over 'macros' and eliminate + # redundant definitions/undefinitions (ie. ensure that only the + # latest mention of a particular macro winds up on the command + # line). I don't think it's essential, though, since most (all?) + # Unix C compilers only pay attention to the latest -D or -U + # mention of a macro on their command line. Similar situation for + # 'include_dirs'. I'm punting on both for now. Anyways, weeding out + # redundancies like this should probably be the province of + # CCompiler, since the data structures used are inherited from it + # and therefore common to all CCompiler classes. + pp_opts = [] + for macro in macros: + if not (isinstance(macro, tuple) and 1 <= len(macro) <= 2): + raise TypeError( + "bad macro definition '%s': " + "each element of 'macros' list must be a 1- or 2-tuple" + % macro) + + if len(macro) == 1: # undefine this macro + pp_opts.append("-U%s" % macro[0]) + elif len(macro) == 2: + if macro[1] is None: # define with no explicit value + pp_opts.append("-D%s" % macro[0]) + else: + # XXX *don't* need to be clever about quoting the + # macro value here, because we're going to avoid the + # shell at all costs when we spawn the command! + pp_opts.append("-D%s=%s" % macro) + + for dir in include_dirs: + pp_opts.append("-I%s" % dir) + return pp_opts diff --git a/Lib/distutils/cygwinccompiler.py b/Tools/c-analyzer/distutils/cygwinccompiler.py similarity index 65% rename from Lib/distutils/cygwinccompiler.py rename to Tools/c-analyzer/distutils/cygwinccompiler.py index 66c12dd3..a3505f31 100644 --- a/Lib/distutils/cygwinccompiler.py +++ b/Tools/c-analyzer/distutils/cygwinccompiler.py @@ -47,14 +47,11 @@ cygwin in no-cygwin mode). import os import sys -import copy from subprocess import Popen, PIPE, check_output import re from distutils.unixccompiler import UnixCCompiler -from distutils.file_util import write_file -from distutils.errors import (DistutilsExecError, CCompilerError, - CompileError, UnknownFileError) +from distutils.errors import CCompilerError from distutils.version import LooseVersion from distutils.spawn import find_executable @@ -154,120 +151,6 @@ class CygwinCCompiler(UnixCCompiler): # with MSVC 7.0 or later. self.dll_libraries = get_msvcr() - def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts): - """Compiles the source by spawning GCC and windres if needed.""" - if ext == '.rc' or ext == '.res': - # gcc needs '.res' and '.rc' compiled to object files !!! - try: - self.spawn(["windres", "-i", src, "-o", obj]) - except DistutilsExecError as msg: - raise CompileError(msg) - else: # for other files use the C-compiler - try: - self.spawn(self.compiler_so + cc_args + [src, '-o', obj] + - extra_postargs) - except DistutilsExecError as msg: - raise CompileError(msg) - - def link(self, target_desc, objects, output_filename, output_dir=None, - libraries=None, library_dirs=None, runtime_library_dirs=None, - export_symbols=None, debug=0, extra_preargs=None, - extra_postargs=None, build_temp=None, target_lang=None): - """Link the objects.""" - # use separate copies, so we can modify the lists - extra_preargs = copy.copy(extra_preargs or []) - libraries = copy.copy(libraries or []) - objects = copy.copy(objects or []) - - # Additional libraries - libraries.extend(self.dll_libraries) - - # handle export symbols by creating a def-file - # with executables this only works with gcc/ld as linker - if ((export_symbols is not None) and - (target_desc != self.EXECUTABLE or self.linker_dll == "gcc")): - # (The linker doesn't do anything if output is up-to-date. - # So it would probably better to check if we really need this, - # but for this we had to insert some unchanged parts of - # UnixCCompiler, and this is not what we want.) - - # we want to put some files in the same directory as the - # object files are, build_temp doesn't help much - # where are the object files - temp_dir = os.path.dirname(objects[0]) - # name of dll to give the helper files the same base name - (dll_name, dll_extension) = os.path.splitext( - os.path.basename(output_filename)) - - # generate the filenames for these files - def_file = os.path.join(temp_dir, dll_name + ".def") - lib_file = os.path.join(temp_dir, 'lib' + dll_name + ".a") - - # Generate .def file - contents = [ - "LIBRARY %s" % os.path.basename(output_filename), - "EXPORTS"] - for sym in export_symbols: - contents.append(sym) - self.execute(write_file, (def_file, contents), - "writing %s" % def_file) - - # next add options for def-file and to creating import libraries - - # dllwrap uses different options than gcc/ld - if self.linker_dll == "dllwrap": - extra_preargs.extend(["--output-lib", lib_file]) - # for dllwrap we have to use a special option - extra_preargs.extend(["--def", def_file]) - # we use gcc/ld here and can be sure ld is >= 2.9.10 - else: - # doesn't work: bfd_close build\...\libfoo.a: Invalid operation - #extra_preargs.extend(["-Wl,--out-implib,%s" % lib_file]) - # for gcc/ld the def-file is specified as any object files - objects.append(def_file) - - #end: if ((export_symbols is not None) and - # (target_desc != self.EXECUTABLE or self.linker_dll == "gcc")): - - # who wants symbols and a many times larger output file - # should explicitly switch the debug mode on - # otherwise we let dllwrap/ld strip the output file - # (On my machine: 10KiB < stripped_file < ??100KiB - # unstripped_file = stripped_file + XXX KiB - # ( XXX=254 for a typical python extension)) - if not debug: - extra_preargs.append("-s") - - UnixCCompiler.link(self, target_desc, objects, output_filename, - output_dir, libraries, library_dirs, - runtime_library_dirs, - None, # export_symbols, we do this in our def-file - debug, extra_preargs, extra_postargs, build_temp, - target_lang) - - # -- Miscellaneous methods ----------------------------------------- - - def object_filenames(self, source_filenames, strip_dir=0, output_dir=''): - """Adds supports for rc and res files.""" - if output_dir is None: - output_dir = '' - obj_names = [] - for src_name in source_filenames: - # use normcase to make sure '.rc' is really '.rc' and not '.RC' - base, ext = os.path.splitext(os.path.normcase(src_name)) - if ext not in (self.src_extensions + ['.rc','.res']): - raise UnknownFileError("unknown file type '%s' (from '%s')" % \ - (ext, src_name)) - if strip_dir: - base = os.path.basename (base) - if ext in ('.res', '.rc'): - # these need to be compiled to object files - obj_names.append (os.path.join(output_dir, - base + ext + self.obj_extension)) - else: - obj_names.append (os.path.join(output_dir, - base + self.obj_extension)) - return obj_names # the same as cygwin plus some additional parameters class Mingw32CCompiler(CygwinCCompiler): @@ -344,7 +227,7 @@ def check_config_h(): # XXX since this function also checks sys.version, it's not strictly a # "pyconfig.h" check -- should probably be renamed... - from distutils import sysconfig + import sysconfig # if sys.version contains GCC then python was compiled with GCC, and the # pyconfig.h file should be OK diff --git a/Lib/distutils/debug.py b/Tools/c-analyzer/distutils/debug.py similarity index 100% rename from Lib/distutils/debug.py rename to Tools/c-analyzer/distutils/debug.py diff --git a/Tools/c-analyzer/distutils/dep_util.py b/Tools/c-analyzer/distutils/dep_util.py new file mode 100644 index 00000000..318c830f --- /dev/null +++ b/Tools/c-analyzer/distutils/dep_util.py @@ -0,0 +1,29 @@ +"""distutils.dep_util + +Utility functions for simple, timestamp-based dependency of files +and groups of files; also, function based entirely on such +timestamp dependency analysis.""" + +import os +from distutils.errors import DistutilsFileError + + +def newer (source, target): + """Return true if 'source' exists and is more recently modified than + 'target', or if 'source' exists and 'target' doesn't. Return false if + both exist and 'target' is the same age or younger than 'source'. + Raise DistutilsFileError if 'source' does not exist. + """ + if not os.path.exists(source): + raise DistutilsFileError("file '%s' does not exist" % + os.path.abspath(source)) + if not os.path.exists(target): + return 1 + + from stat import ST_MTIME + mtime1 = os.stat(source)[ST_MTIME] + mtime2 = os.stat(target)[ST_MTIME] + + return mtime1 > mtime2 + +# newer () diff --git a/Tools/c-analyzer/distutils/errors.py b/Tools/c-analyzer/distutils/errors.py new file mode 100644 index 00000000..10f8e316 --- /dev/null +++ b/Tools/c-analyzer/distutils/errors.py @@ -0,0 +1,48 @@ +"""distutils.errors + +Provides exceptions used by the Distutils modules. Note that Distutils +modules may raise standard exceptions; in particular, SystemExit is +usually raised for errors that are obviously the end-user's fault +(eg. bad command-line arguments). + +This module is safe to use in "from ... import *" mode; it only exports +symbols whose names start with "Distutils" and end with "Error".""" + +class DistutilsError (Exception): + """The root of all Distutils evil.""" + pass + +class DistutilsModuleError (DistutilsError): + """Unable to load an expected module, or to find an expected class + within some module (in particular, command modules and classes).""" + pass + +class DistutilsFileError (DistutilsError): + """Any problems in the filesystem: expected file not found, etc. + Typically this is for problems that we detect before OSError + could be raised.""" + pass + +class DistutilsPlatformError (DistutilsError): + """We don't know how to do something on the current platform (but + we do know how to do it on some platform) -- eg. trying to compile + C files on a platform not supported by a CCompiler subclass.""" + pass + +class DistutilsExecError (DistutilsError): + """Any problems executing an external program (such as the C + compiler, when compiling C files).""" + pass + +# Exception classes used by the CCompiler implementation classes +class CCompilerError (Exception): + """Some compile/link operation failed.""" + +class PreprocessError (CCompilerError): + """Failure to preprocess one or more C/C++ files.""" + +class CompileError (CCompilerError): + """Failure to compile one or more C/C++ source files.""" + +class UnknownFileError (CCompilerError): + """Attempt to process an unknown file type.""" diff --git a/Lib/distutils/log.py b/Tools/c-analyzer/distutils/log.py similarity index 84% rename from Lib/distutils/log.py rename to Tools/c-analyzer/distutils/log.py index 8ef6b28e..26ecf22a 100644 --- a/Lib/distutils/log.py +++ b/Tools/c-analyzer/distutils/log.py @@ -61,17 +61,3 @@ info = _global_log.info warn = _global_log.warn error = _global_log.error fatal = _global_log.fatal - -def set_threshold(level): - # return the old threshold for use from tests - old = _global_log.threshold - _global_log.threshold = level - return old - -def set_verbosity(v): - if v <= 0: - set_threshold(WARN) - elif v == 1: - set_threshold(INFO) - elif v >= 2: - set_threshold(DEBUG) diff --git a/Lib/distutils/msvc9compiler.py b/Tools/c-analyzer/distutils/msvc9compiler.py similarity index 51% rename from Lib/distutils/msvc9compiler.py rename to Tools/c-analyzer/distutils/msvc9compiler.py index a7976fbe..38fff9b2 100644 --- a/Lib/distutils/msvc9compiler.py +++ b/Tools/c-analyzer/distutils/msvc9compiler.py @@ -17,11 +17,9 @@ import subprocess import sys import re -from distutils.errors import DistutilsExecError, DistutilsPlatformError, \ - CompileError, LibError, LinkError -from distutils.ccompiler import CCompiler, gen_lib_options +from distutils.errors import DistutilsPlatformError +from distutils.ccompiler import CCompiler from distutils import log -from distutils.util import get_platform import winreg @@ -336,327 +334,8 @@ class MSVCCompiler(CCompiler) : self.__arch = None # deprecated name self.initialized = False - def initialize(self, plat_name=None): - # multi-init means we would need to check platform same each time... - assert not self.initialized, "don't init multiple times" - if plat_name is None: - plat_name = get_platform() - # sanity check for platforms to prevent obscure errors later. - ok_plats = 'win32', 'win-amd64' - if plat_name not in ok_plats: - raise DistutilsPlatformError("--plat-name must be one of %s" % - (ok_plats,)) - - if "DISTUTILS_USE_SDK" in os.environ and "MSSdk" in os.environ and self.find_exe("cl.exe"): - # Assume that the SDK set up everything alright; don't try to be - # smarter - self.cc = "cl.exe" - self.linker = "link.exe" - self.lib = "lib.exe" - self.rc = "rc.exe" - self.mc = "mc.exe" - else: - # On x86, 'vcvars32.bat amd64' creates an env that doesn't work; - # to cross compile, you use 'x86_amd64'. - # On AMD64, 'vcvars32.bat amd64' is a native build env; to cross - # compile use 'x86' (ie, it runs the x86 compiler directly) - if plat_name == get_platform() or plat_name == 'win32': - # native build or cross-compile to win32 - plat_spec = PLAT_TO_VCVARS[plat_name] - else: - # cross compile from win32 -> some 64bit - plat_spec = PLAT_TO_VCVARS[get_platform()] + '_' + \ - PLAT_TO_VCVARS[plat_name] - - vc_env = query_vcvarsall(VERSION, plat_spec) - - self.__paths = vc_env['path'].split(os.pathsep) - os.environ['lib'] = vc_env['lib'] - os.environ['include'] = vc_env['include'] - - if len(self.__paths) == 0: - raise DistutilsPlatformError("Python was built with %s, " - "and extensions need to be built with the same " - "version of the compiler, but it isn't installed." - % self.__product) - - self.cc = self.find_exe("cl.exe") - self.linker = self.find_exe("link.exe") - self.lib = self.find_exe("lib.exe") - self.rc = self.find_exe("rc.exe") # resource compiler - self.mc = self.find_exe("mc.exe") # message compiler - #self.set_path_env_var('lib') - #self.set_path_env_var('include') - - # extend the MSVC path with the current path - try: - for p in os.environ['path'].split(';'): - self.__paths.append(p) - except KeyError: - pass - self.__paths = normalize_and_reduce_paths(self.__paths) - os.environ['path'] = ";".join(self.__paths) - - self.preprocess_options = None - if self.__arch == "x86": - self.compile_options = [ '/nologo', '/Ox', '/MD', '/W3', - '/DNDEBUG'] - self.compile_options_debug = ['/nologo', '/Od', '/MDd', '/W3', - '/Z7', '/D_DEBUG'] - else: - # Win64 - self.compile_options = [ '/nologo', '/Ox', '/MD', '/W3', '/GS-' , - '/DNDEBUG'] - self.compile_options_debug = ['/nologo', '/Od', '/MDd', '/W3', '/GS-', - '/Z7', '/D_DEBUG'] - - self.ldflags_shared = ['/DLL', '/nologo', '/INCREMENTAL:NO'] - if self.__version >= 7: - self.ldflags_shared_debug = [ - '/DLL', '/nologo', '/INCREMENTAL:no', '/DEBUG' - ] - self.ldflags_static = [ '/nologo'] - - self.initialized = True - # -- Worker methods ------------------------------------------------ - def object_filenames(self, - source_filenames, - strip_dir=0, - output_dir=''): - # Copied from ccompiler.py, extended to return .res as 'object'-file - # for .rc input file - if output_dir is None: output_dir = '' - obj_names = [] - for src_name in source_filenames: - (base, ext) = os.path.splitext (src_name) - base = os.path.splitdrive(base)[1] # Chop off the drive - base = base[os.path.isabs(base):] # If abs, chop off leading / - if ext not in self.src_extensions: - # Better to raise an exception instead of silently continuing - # and later complain about sources and targets having - # different lengths - raise CompileError ("Don't know how to compile %s" % src_name) - if strip_dir: - base = os.path.basename (base) - if ext in self._rc_extensions: - obj_names.append (os.path.join (output_dir, - base + self.res_extension)) - elif ext in self._mc_extensions: - obj_names.append (os.path.join (output_dir, - base + self.res_extension)) - else: - obj_names.append (os.path.join (output_dir, - base + self.obj_extension)) - return obj_names - - - def compile(self, sources, - output_dir=None, macros=None, include_dirs=None, debug=0, - extra_preargs=None, extra_postargs=None, depends=None): - - if not self.initialized: - self.initialize() - compile_info = self._setup_compile(output_dir, macros, include_dirs, - sources, depends, extra_postargs) - macros, objects, extra_postargs, pp_opts, build = compile_info - - compile_opts = extra_preargs or [] - compile_opts.append ('/c') - if debug: - compile_opts.extend(self.compile_options_debug) - else: - compile_opts.extend(self.compile_options) - - for obj in objects: - try: - src, ext = build[obj] - except KeyError: - continue - if debug: - # pass the full pathname to MSVC in debug mode, - # this allows the debugger to find the source file - # without asking the user to browse for it - src = os.path.abspath(src) - - if ext in self._c_extensions: - input_opt = "/Tc" + src - elif ext in self._cpp_extensions: - input_opt = "/Tp" + src - elif ext in self._rc_extensions: - # compile .RC to .RES file - input_opt = src - output_opt = "/fo" + obj - try: - self.spawn([self.rc] + pp_opts + - [output_opt] + [input_opt]) - except DistutilsExecError as msg: - raise CompileError(msg) - continue - elif ext in self._mc_extensions: - # Compile .MC to .RC file to .RES file. - # * '-h dir' specifies the directory for the - # generated include file - # * '-r dir' specifies the target directory of the - # generated RC file and the binary message resource - # it includes - # - # For now (since there are no options to change this), - # we use the source-directory for the include file and - # the build directory for the RC file and message - # resources. This works at least for win32all. - h_dir = os.path.dirname(src) - rc_dir = os.path.dirname(obj) - try: - # first compile .MC to .RC and .H file - self.spawn([self.mc] + - ['-h', h_dir, '-r', rc_dir] + [src]) - base, _ = os.path.splitext (os.path.basename (src)) - rc_file = os.path.join (rc_dir, base + '.rc') - # then compile .RC to .RES file - self.spawn([self.rc] + - ["/fo" + obj] + [rc_file]) - - except DistutilsExecError as msg: - raise CompileError(msg) - continue - else: - # how to handle this file? - raise CompileError("Don't know how to compile %s to %s" - % (src, obj)) - - output_opt = "/Fo" + obj - try: - self.spawn([self.cc] + compile_opts + pp_opts + - [input_opt, output_opt] + - extra_postargs) - except DistutilsExecError as msg: - raise CompileError(msg) - - return objects - - - def create_static_lib(self, - objects, - output_libname, - output_dir=None, - debug=0, - target_lang=None): - - if not self.initialized: - self.initialize() - (objects, output_dir) = self._fix_object_args(objects, output_dir) - output_filename = self.library_filename(output_libname, - output_dir=output_dir) - - if self._need_link(objects, output_filename): - lib_args = objects + ['/OUT:' + output_filename] - if debug: - pass # XXX what goes here? - try: - self.spawn([self.lib] + lib_args) - except DistutilsExecError as msg: - raise LibError(msg) - else: - log.debug("skipping %s (up-to-date)", output_filename) - - - def link(self, - target_desc, - objects, - output_filename, - output_dir=None, - libraries=None, - library_dirs=None, - runtime_library_dirs=None, - export_symbols=None, - debug=0, - extra_preargs=None, - extra_postargs=None, - build_temp=None, - target_lang=None): - - if not self.initialized: - self.initialize() - (objects, output_dir) = self._fix_object_args(objects, output_dir) - fixed_args = self._fix_lib_args(libraries, library_dirs, - runtime_library_dirs) - (libraries, library_dirs, runtime_library_dirs) = fixed_args - - if runtime_library_dirs: - self.warn ("I don't know what to do with 'runtime_library_dirs': " - + str (runtime_library_dirs)) - - lib_opts = gen_lib_options(self, - library_dirs, runtime_library_dirs, - libraries) - if output_dir is not None: - output_filename = os.path.join(output_dir, output_filename) - - if self._need_link(objects, output_filename): - if target_desc == CCompiler.EXECUTABLE: - if debug: - ldflags = self.ldflags_shared_debug[1:] - else: - ldflags = self.ldflags_shared[1:] - else: - if debug: - ldflags = self.ldflags_shared_debug - else: - ldflags = self.ldflags_shared - - export_opts = [] - for sym in (export_symbols or []): - export_opts.append("/EXPORT:" + sym) - - ld_args = (ldflags + lib_opts + export_opts + - objects + ['/OUT:' + output_filename]) - - # The MSVC linker generates .lib and .exp files, which cannot be - # suppressed by any linker switches. The .lib files may even be - # needed! Make sure they are generated in the temporary build - # directory. Since they have different names for debug and release - # builds, they can go into the same directory. - build_temp = os.path.dirname(objects[0]) - if export_symbols is not None: - (dll_name, dll_ext) = os.path.splitext( - os.path.basename(output_filename)) - implib_file = os.path.join( - build_temp, - self.library_filename(dll_name)) - ld_args.append ('/IMPLIB:' + implib_file) - - self.manifest_setup_ldargs(output_filename, build_temp, ld_args) - - if extra_preargs: - ld_args[:0] = extra_preargs - if extra_postargs: - ld_args.extend(extra_postargs) - - self.mkpath(os.path.dirname(output_filename)) - try: - self.spawn([self.linker] + ld_args) - except DistutilsExecError as msg: - raise LinkError(msg) - - # embed the manifest - # XXX - this is somewhat fragile - if mt.exe fails, distutils - # will still consider the DLL up-to-date, but it will not have a - # manifest. Maybe we should link to a temp file? OTOH, that - # implies a build environment error that shouldn't go undetected. - mfinfo = self.manifest_get_embed_info(target_desc, ld_args) - if mfinfo is not None: - mffilename, mfid = mfinfo - out_arg = '-outputresource:%s;%s' % (output_filename, mfid) - try: - self.spawn(['mt.exe', '-nologo', '-manifest', - mffilename, out_arg]) - except DistutilsExecError as msg: - raise LinkError(msg) - else: - log.debug("skipping %s (up-to-date)", output_filename) - def manifest_setup_ldargs(self, output_filename, build_temp, ld_args): # If we need a manifest at all, an embedded manifest is recommended. # See MSDN article titled @@ -733,35 +412,6 @@ class MSVCCompiler(CCompiler) : pass # -- Miscellaneous methods ----------------------------------------- - # These are all used by the 'gen_lib_options() function, in - # ccompiler.py. - - def library_dir_option(self, dir): - return "/LIBPATH:" + dir - - def runtime_library_dir_option(self, dir): - raise DistutilsPlatformError( - "don't know how to set runtime library search path for MSVC++") - - def library_option(self, lib): - return self.library_filename(lib) - - - def find_library_file(self, dirs, lib, debug=0): - # Prefer a debugging library if found (and requested), but deal - # with it if we don't have one. - if debug: - try_names = [lib + "_d", lib] - else: - try_names = [lib] - for dir in dirs: - for name in try_names: - libfile = os.path.join(dir, self.library_filename (name)) - if os.path.exists(libfile): - return libfile - else: - # Oops, didn't find it in *any* of 'dirs' - return None # Helper methods for using the MSVC registry settings diff --git a/Tools/c-analyzer/distutils/msvccompiler.py b/Tools/c-analyzer/distutils/msvccompiler.py new file mode 100644 index 00000000..c0864b1f --- /dev/null +++ b/Tools/c-analyzer/distutils/msvccompiler.py @@ -0,0 +1,327 @@ +"""distutils.msvccompiler + +Contains MSVCCompiler, an implementation of the abstract CCompiler class +for the Microsoft Visual Studio. +""" + +# Written by Perry Stoll +# hacked by Robin Becker and Thomas Heller to do a better job of +# finding DevStudio (through the registry) + +import sys, os +from distutils.errors import DistutilsPlatformError +from distutils.ccompiler import CCompiler +from distutils import log + +_can_read_reg = False +try: + import winreg + + _can_read_reg = True + hkey_mod = winreg + + RegOpenKeyEx = winreg.OpenKeyEx + RegEnumKey = winreg.EnumKey + RegEnumValue = winreg.EnumValue + RegError = winreg.error + +except ImportError: + try: + import win32api + import win32con + _can_read_reg = True + hkey_mod = win32con + + RegOpenKeyEx = win32api.RegOpenKeyEx + RegEnumKey = win32api.RegEnumKey + RegEnumValue = win32api.RegEnumValue + RegError = win32api.error + except ImportError: + log.info("Warning: Can't read registry to find the " + "necessary compiler setting\n" + "Make sure that Python modules winreg, " + "win32api or win32con are installed.") + +if _can_read_reg: + HKEYS = (hkey_mod.HKEY_USERS, + hkey_mod.HKEY_CURRENT_USER, + hkey_mod.HKEY_LOCAL_MACHINE, + hkey_mod.HKEY_CLASSES_ROOT) + +def read_keys(base, key): + """Return list of registry keys.""" + try: + handle = RegOpenKeyEx(base, key) + except RegError: + return None + L = [] + i = 0 + while True: + try: + k = RegEnumKey(handle, i) + except RegError: + break + L.append(k) + i += 1 + return L + +def read_values(base, key): + """Return dict of registry keys and values. + + All names are converted to lowercase. + """ + try: + handle = RegOpenKeyEx(base, key) + except RegError: + return None + d = {} + i = 0 + while True: + try: + name, value, type = RegEnumValue(handle, i) + except RegError: + break + name = name.lower() + d[convert_mbcs(name)] = convert_mbcs(value) + i += 1 + return d + +def convert_mbcs(s): + dec = getattr(s, "decode", None) + if dec is not None: + try: + s = dec("mbcs") + except UnicodeError: + pass + return s + +class MacroExpander: + def __init__(self, version): + self.macros = {} + self.load_macros(version) + + def set_macro(self, macro, path, key): + for base in HKEYS: + d = read_values(base, path) + if d: + self.macros["$(%s)" % macro] = d[key] + break + + def load_macros(self, version): + vsbase = r"Software\Microsoft\VisualStudio\%0.1f" % version + self.set_macro("VCInstallDir", vsbase + r"\Setup\VC", "productdir") + self.set_macro("VSInstallDir", vsbase + r"\Setup\VS", "productdir") + net = r"Software\Microsoft\.NETFramework" + self.set_macro("FrameworkDir", net, "installroot") + try: + if version > 7.0: + self.set_macro("FrameworkSDKDir", net, "sdkinstallrootv1.1") + else: + self.set_macro("FrameworkSDKDir", net, "sdkinstallroot") + except KeyError as exc: # + raise DistutilsPlatformError( + """Python was built with Visual Studio 2003; +extensions must be built with a compiler than can generate compatible binaries. +Visual Studio 2003 was not found on this system. If you have Cygwin installed, +you can try compiling with MingW32, by passing "-c mingw32" to setup.py.""") + + p = r"Software\Microsoft\NET Framework Setup\Product" + for base in HKEYS: + try: + h = RegOpenKeyEx(base, p) + except RegError: + continue + key = RegEnumKey(h, 0) + d = read_values(base, r"%s\%s" % (p, key)) + self.macros["$(FrameworkVersion)"] = d["version"] + + def sub(self, s): + for k, v in self.macros.items(): + s = s.replace(k, v) + return s + +def get_build_version(): + """Return the version of MSVC that was used to build Python. + + For Python 2.3 and up, the version number is included in + sys.version. For earlier versions, assume the compiler is MSVC 6. + """ + prefix = "MSC v." + i = sys.version.find(prefix) + if i == -1: + return 6 + i = i + len(prefix) + s, rest = sys.version[i:].split(" ", 1) + majorVersion = int(s[:-2]) - 6 + if majorVersion >= 13: + # v13 was skipped and should be v14 + majorVersion += 1 + minorVersion = int(s[2:3]) / 10.0 + # I don't think paths are affected by minor version in version 6 + if majorVersion == 6: + minorVersion = 0 + if majorVersion >= 6: + return majorVersion + minorVersion + # else we don't know what version of the compiler this is + return None + +def get_build_architecture(): + """Return the processor architecture. + + Possible results are "Intel" or "AMD64". + """ + + prefix = " bit (" + i = sys.version.find(prefix) + if i == -1: + return "Intel" + j = sys.version.find(")", i) + return sys.version[i+len(prefix):j] + +def normalize_and_reduce_paths(paths): + """Return a list of normalized paths with duplicates removed. + + The current order of paths is maintained. + """ + # Paths are normalized so things like: /a and /a/ aren't both preserved. + reduced_paths = [] + for p in paths: + np = os.path.normpath(p) + # XXX(nnorwitz): O(n**2), if reduced_paths gets long perhaps use a set. + if np not in reduced_paths: + reduced_paths.append(np) + return reduced_paths + + +class MSVCCompiler(CCompiler) : + """Concrete class that implements an interface to Microsoft Visual C++, + as defined by the CCompiler abstract class.""" + + compiler_type = 'msvc' + + # Just set this so CCompiler's constructor doesn't barf. We currently + # don't use the 'set_executables()' bureaucracy provided by CCompiler, + # as it really isn't necessary for this sort of single-compiler class. + # Would be nice to have a consistent interface with UnixCCompiler, + # though, so it's worth thinking about. + executables = {} + + # Private class data (need to distinguish C from C++ source for compiler) + _c_extensions = ['.c'] + _cpp_extensions = ['.cc', '.cpp', '.cxx'] + _rc_extensions = ['.rc'] + _mc_extensions = ['.mc'] + + # Needed for the filename generation methods provided by the + # base class, CCompiler. + src_extensions = (_c_extensions + _cpp_extensions + + _rc_extensions + _mc_extensions) + res_extension = '.res' + obj_extension = '.obj' + static_lib_extension = '.lib' + shared_lib_extension = '.dll' + static_lib_format = shared_lib_format = '%s%s' + exe_extension = '.exe' + + def __init__(self, verbose=0, dry_run=0, force=0): + CCompiler.__init__ (self, verbose, dry_run, force) + self.__version = get_build_version() + self.__arch = get_build_architecture() + if self.__arch == "Intel": + # x86 + if self.__version >= 7: + self.__root = r"Software\Microsoft\VisualStudio" + self.__macros = MacroExpander(self.__version) + else: + self.__root = r"Software\Microsoft\Devstudio" + self.__product = "Visual Studio version %s" % self.__version + else: + # Win64. Assume this was built with the platform SDK + self.__product = "Microsoft SDK compiler %s" % (self.__version + 6) + + self.initialized = False + + + # -- Miscellaneous methods ----------------------------------------- + + # Helper methods for using the MSVC registry settings + + def find_exe(self, exe): + """Return path to an MSVC executable program. + + Tries to find the program in several places: first, one of the + MSVC program search paths from the registry; next, the directories + in the PATH environment variable. If any of those work, return an + absolute path that is known to exist. If none of them work, just + return the original program name, 'exe'. + """ + for p in self.__paths: + fn = os.path.join(os.path.abspath(p), exe) + if os.path.isfile(fn): + return fn + + # didn't find it; try existing path + for p in os.environ['Path'].split(';'): + fn = os.path.join(os.path.abspath(p),exe) + if os.path.isfile(fn): + return fn + + return exe + + def get_msvc_paths(self, path, platform='x86'): + """Get a list of devstudio directories (include, lib or path). + + Return a list of strings. The list will be empty if unable to + access the registry or appropriate registry keys not found. + """ + if not _can_read_reg: + return [] + + path = path + " dirs" + if self.__version >= 7: + key = (r"%s\%0.1f\VC\VC_OBJECTS_PLATFORM_INFO\Win32\Directories" + % (self.__root, self.__version)) + else: + key = (r"%s\6.0\Build System\Components\Platforms" + r"\Win32 (%s)\Directories" % (self.__root, platform)) + + for base in HKEYS: + d = read_values(base, key) + if d: + if self.__version >= 7: + return self.__macros.sub(d[path]).split(";") + else: + return d[path].split(";") + # MSVC 6 seems to create the registry entries we need only when + # the GUI is run. + if self.__version == 6: + for base in HKEYS: + if read_values(base, r"%s\6.0" % self.__root) is not None: + self.warn("It seems you have Visual Studio 6 installed, " + "but the expected registry settings are not present.\n" + "You must at least run the Visual Studio GUI once " + "so that these entries are created.") + break + return [] + + def set_path_env_var(self, name): + """Set environment variable 'name' to an MSVC path type value. + + This is equivalent to a SET command prior to execution of spawned + commands. + """ + + if name == "lib": + p = self.get_msvc_paths("library") + else: + p = self.get_msvc_paths(name) + if p: + os.environ[name] = ';'.join(p) + + +if get_build_version() >= 8.0: + log.debug("Importing new compiler from distutils.msvc9compiler") + OldMSVCCompiler = MSVCCompiler + from distutils.msvc9compiler import MSVCCompiler + # get_build_architecture not really relevant now we support cross-compile + from distutils.msvc9compiler import MacroExpander diff --git a/Tools/c-analyzer/distutils/spawn.py b/Tools/c-analyzer/distutils/spawn.py new file mode 100644 index 00000000..eb979496 --- /dev/null +++ b/Tools/c-analyzer/distutils/spawn.py @@ -0,0 +1,48 @@ +"""distutils.spawn + +Provides the 'spawn()' function, a front-end to various platform- +specific functions for launching another program in a sub-process. +Also provides the 'find_executable()' to search the path for a given +executable name. +""" + +import sys +import os +import os.path + + +def find_executable(executable, path=None): + """Tries to find 'executable' in the directories listed in 'path'. + + A string listing directories separated by 'os.pathsep'; defaults to + os.environ['PATH']. Returns the complete filename or None if not found. + """ + _, ext = os.path.splitext(executable) + if (sys.platform == 'win32') and (ext != '.exe'): + executable = executable + '.exe' + + if os.path.isfile(executable): + return executable + + if path is None: + path = os.environ.get('PATH', None) + if path is None: + try: + path = os.confstr("CS_PATH") + except (AttributeError, ValueError): + # os.confstr() or CS_PATH is not available + path = os.defpath + # bpo-35755: Don't use os.defpath if the PATH environment variable is + # set to an empty string + + # PATH='' doesn't match, whereas PATH=':' looks in the current directory + if not path: + return None + + paths = path.split(os.pathsep) + for p in paths: + f = os.path.join(p, executable) + if os.path.isfile(f): + # the file exists, we have a shot at spawn working + return f + return None diff --git a/Tools/c-analyzer/distutils/unixccompiler.py b/Tools/c-analyzer/distutils/unixccompiler.py new file mode 100644 index 00000000..1a3a8e52 --- /dev/null +++ b/Tools/c-analyzer/distutils/unixccompiler.py @@ -0,0 +1,102 @@ +"""distutils.unixccompiler + +Contains the UnixCCompiler class, a subclass of CCompiler that handles +the "typical" Unix-style command-line C compiler: + * macros defined with -Dname[=value] + * macros undefined with -Uname + * include search directories specified with -Idir + * libraries specified with -lllib + * library search directories specified with -Ldir + * compile handled by 'cc' (or similar) executable with -c option: + compiles .c to .o + * link static library handled by 'ar' command (possibly with 'ranlib') + * link shared library handled by 'cc -shared' +""" + +import os, sys, re + +from distutils.dep_util import newer +from distutils.ccompiler import CCompiler, gen_preprocess_options +from distutils.errors import DistutilsExecError, CompileError + +# XXX Things not currently handled: +# * optimization/debug/warning flags; we just use whatever's in Python's +# Makefile and live with it. Is this adequate? If not, we might +# have to have a bunch of subclasses GNUCCompiler, SGICCompiler, +# SunCCompiler, and I suspect down that road lies madness. +# * even if we don't know a warning flag from an optimization flag, +# we need some way for outsiders to feed preprocessor/compiler/linker +# flags in to us -- eg. a sysadmin might want to mandate certain flags +# via a site config file, or a user might want to set something for +# compiling this module distribution only via the setup.py command +# line, whatever. As long as these options come from something on the +# current system, they can be as system-dependent as they like, and we +# should just happily stuff them into the preprocessor/compiler/linker +# options and carry on. + + +class UnixCCompiler(CCompiler): + + compiler_type = 'unix' + + # These are used by CCompiler in two places: the constructor sets + # instance attributes 'preprocessor', 'compiler', etc. from them, and + # 'set_executable()' allows any of these to be set. The defaults here + # are pretty generic; they will probably have to be set by an outsider + # (eg. using information discovered by the sysconfig about building + # Python extensions). + executables = {'preprocessor' : None, + 'compiler' : ["cc"], + 'compiler_so' : ["cc"], + 'compiler_cxx' : ["cc"], + 'linker_so' : ["cc", "-shared"], + 'linker_exe' : ["cc"], + 'archiver' : ["ar", "-cr"], + 'ranlib' : None, + } + + if sys.platform[:6] == "darwin": + executables['ranlib'] = ["ranlib"] + + # Needed for the filename generation methods provided by the base + # class, CCompiler. NB. whoever instantiates/uses a particular + # UnixCCompiler instance should set 'shared_lib_ext' -- we set a + # reasonable common default here, but it's not necessarily used on all + # Unices! + + src_extensions = [".c",".C",".cc",".cxx",".cpp",".m"] + obj_extension = ".o" + static_lib_extension = ".a" + shared_lib_extension = ".so" + dylib_lib_extension = ".dylib" + xcode_stub_lib_extension = ".tbd" + static_lib_format = shared_lib_format = dylib_lib_format = "lib%s%s" + xcode_stub_lib_format = dylib_lib_format + if sys.platform == "cygwin": + exe_extension = ".exe" + + def preprocess(self, source, output_file=None, macros=None, + include_dirs=None, extra_preargs=None, extra_postargs=None): + fixed_args = self._fix_compile_args(None, macros, include_dirs) + ignore, macros, include_dirs = fixed_args + pp_opts = gen_preprocess_options(macros, include_dirs) + pp_args = self.preprocessor + pp_opts + if output_file: + pp_args.extend(['-o', output_file]) + if extra_preargs: + pp_args[:0] = extra_preargs + if extra_postargs: + pp_args.extend(extra_postargs) + pp_args.append(source) + + # We need to preprocess: either we're being forced to, or we're + # generating output to stdout, or there's a target output file and + # the source file is newer than the target (or the target doesn't + # exist). + if self.force or output_file is None or newer(source, output_file): + if output_file: + self.mkpath(os.path.dirname(output_file)) + try: + self.spawn(pp_args) + except DistutilsExecError as msg: + raise CompileError(msg) diff --git a/Tools/c-analyzer/distutils/util.py b/Tools/c-analyzer/distutils/util.py new file mode 100644 index 00000000..89ca0943 --- /dev/null +++ b/Tools/c-analyzer/distutils/util.py @@ -0,0 +1,171 @@ +"""distutils.util + +Miscellaneous utility functions -- anything that doesn't fit into +one of the other *util.py modules. +""" + +import os +import re +import string +import sys +from distutils.errors import DistutilsPlatformError + +def get_host_platform(): + """Return a string that identifies the current platform. This is used mainly to + distinguish platform-specific build directories and platform-specific built + distributions. Typically includes the OS name and version and the + architecture (as supplied by 'os.uname()'), although the exact information + included depends on the OS; eg. on Linux, the kernel version isn't + particularly important. + + Examples of returned values: + linux-i586 + linux-alpha (?) + solaris-2.6-sun4u + + Windows will return one of: + win-amd64 (64bit Windows on AMD64 (aka x86_64, Intel64, EM64T, etc) + win32 (all others - specifically, sys.platform is returned) + + For other non-POSIX platforms, currently just returns 'sys.platform'. + + """ + if os.name == 'nt': + if 'amd64' in sys.version.lower(): + return 'win-amd64' + if '(arm)' in sys.version.lower(): + return 'win-arm32' + if '(arm64)' in sys.version.lower(): + return 'win-arm64' + return sys.platform + + # Set for cross builds explicitly + if "_PYTHON_HOST_PLATFORM" in os.environ: + return os.environ["_PYTHON_HOST_PLATFORM"] + + if os.name != "posix" or not hasattr(os, 'uname'): + # XXX what about the architecture? NT is Intel or Alpha, + # Mac OS is M68k or PPC, etc. + return sys.platform + + # Try to distinguish various flavours of Unix + + (osname, host, release, version, machine) = os.uname() + + # Convert the OS name to lowercase, remove '/' characters, and translate + # spaces (for "Power Macintosh") + osname = osname.lower().replace('/', '') + machine = machine.replace(' ', '_') + machine = machine.replace('/', '-') + + if osname[:5] == "linux": + # At least on Linux/Intel, 'machine' is the processor -- + # i386, etc. + # XXX what about Alpha, SPARC, etc? + return "%s-%s" % (osname, machine) + elif osname[:5] == "sunos": + if release[0] >= "5": # SunOS 5 == Solaris 2 + osname = "solaris" + release = "%d.%s" % (int(release[0]) - 3, release[2:]) + # We can't use "platform.architecture()[0]" because a + # bootstrap problem. We use a dict to get an error + # if some suspicious happens. + bitness = {2147483647:"32bit", 9223372036854775807:"64bit"} + machine += ".%s" % bitness[sys.maxsize] + # fall through to standard osname-release-machine representation + elif osname[:3] == "aix": + from _aix_support import aix_platform + return aix_platform() + elif osname[:6] == "cygwin": + osname = "cygwin" + rel_re = re.compile (r'[\d.]+', re.ASCII) + m = rel_re.match(release) + if m: + release = m.group() + elif osname[:6] == "darwin": + import _osx_support, sysconfig + osname, release, machine = _osx_support.get_platform_osx( + sysconfig.get_config_vars(), + osname, release, machine) + + return "%s-%s-%s" % (osname, release, machine) + +def get_platform(): + if os.name == 'nt': + TARGET_TO_PLAT = { + 'x86' : 'win32', + 'x64' : 'win-amd64', + 'arm' : 'win-arm32', + } + return TARGET_TO_PLAT.get(os.environ.get('VSCMD_ARG_TGT_ARCH')) or get_host_platform() + else: + return get_host_platform() + + +# Needed by 'split_quoted()' +_wordchars_re = _squote_re = _dquote_re = None +def _init_regex(): + global _wordchars_re, _squote_re, _dquote_re + _wordchars_re = re.compile(r'[^\\\'\"%s ]*' % string.whitespace) + _squote_re = re.compile(r"'(?:[^'\\]|\\.)*'") + _dquote_re = re.compile(r'"(?:[^"\\]|\\.)*"') + +def split_quoted (s): + """Split a string up according to Unix shell-like rules for quotes and + backslashes. In short: words are delimited by spaces, as long as those + spaces are not escaped by a backslash, or inside a quoted string. + Single and double quotes are equivalent, and the quote characters can + be backslash-escaped. The backslash is stripped from any two-character + escape sequence, leaving only the escaped character. The quote + characters are stripped from any quoted string. Returns a list of + words. + """ + + # This is a nice algorithm for splitting up a single string, since it + # doesn't require character-by-character examination. It was a little + # bit of a brain-bender to get it working right, though... + if _wordchars_re is None: _init_regex() + + s = s.strip() + words = [] + pos = 0 + + while s: + m = _wordchars_re.match(s, pos) + end = m.end() + if end == len(s): + words.append(s[:end]) + break + + if s[end] in string.whitespace: # unescaped, unquoted whitespace: now + words.append(s[:end]) # we definitely have a word delimiter + s = s[end:].lstrip() + pos = 0 + + elif s[end] == '\\': # preserve whatever is being escaped; + # will become part of the current word + s = s[:end] + s[end+1:] + pos = end+1 + + else: + if s[end] == "'": # slurp singly-quoted string + m = _squote_re.match(s, end) + elif s[end] == '"': # slurp doubly-quoted string + m = _dquote_re.match(s, end) + else: + raise RuntimeError("this can't happen (bad char '%c')" % s[end]) + + if m is None: + raise ValueError("bad string (mismatched %s quotes?)" % s[end]) + + (beg, end) = m.span() + s = s[:beg] + s[beg+1:end-1] + s[end:] + pos = m.end() - 2 + + if pos >= len(s): + words.append(s) + break + + return words + +# split_quoted () diff --git a/Tools/c-analyzer/table-file.py b/Tools/c-analyzer/table-file.py index 3cc05cc9..d36f8144 100644 --- a/Tools/c-analyzer/table-file.py +++ b/Tools/c-analyzer/table-file.py @@ -1,43 +1,59 @@ +KINDS = [ + 'section-major', + 'section-minor', + 'section-group', + 'row', +] + + def iter_clean_lines(lines): lines = iter(lines) - for line in lines: - line = line.strip() - if line.startswith('# XXX'): + for rawline in lines: + line = rawline.strip() + if line.startswith('#') and not rawline.startswith('##'): continue - yield line + yield line, rawline def parse_table_lines(lines): lines = iter_clean_lines(lines) - for line in lines: - if line.startswith(('####', '#----')): - kind = 0 if line[1] == '#' else 1 - try: - line = next(lines).strip() - except StopIteration: - line = '' - if not line.startswith('# '): - raise NotImplementedError(line) - yield kind, line[2:].lstrip() - continue - - maybe = None - while line.startswith('#'): - if line != '#' and line[1] == ' ': - maybe = line[2:].lstrip() - try: - line = next(lines).strip() - except StopIteration: - return - if not line: - break - else: - if line: - if maybe: - yield 2, maybe - yield 'row', line + group = None + prev = '' + for line, rawline in lines: + if line.startswith('## '): + assert not rawline.startswith(' '), (line, rawline) + if group: + assert prev, (line, rawline) + kind, after, _ = group + assert kind and kind != 'section-group', (group, line, rawline) + assert after is not None, (group, line, rawline) + else: + assert not prev, (prev, line, rawline) + kind, after = group = ('section-group', None) + title = line[3:].lstrip() + assert title, (line, rawline) + if after is not None: + try: + line, rawline = next(lines) + except StopIteration: + line = None + if line != after: + raise NotImplementedError((group, line, rawline)) + yield kind, title + group = None + elif group: + raise NotImplementedError((group, line, rawline)) + elif line.startswith('##---'): + assert line.rstrip('-') == '##', (line, rawline) + group = ('section-minor', '', line) + elif line.startswith('#####'): + assert not line.strip('#'), (line, rawline) + group = ('section-major', '', line) + elif line: + yield 'row', line + prev = line def iter_sections(lines): @@ -49,12 +65,13 @@ def iter_sections(lines): if header is None: header = value continue - raise NotImplementedError(value) + raise NotImplementedError(repr(value)) yield tuple(section), value else: if header is None: header = False - section[kind:] = [value] + start = KINDS.index(kind) + section[start:] = [value] def collect_sections(lines): diff --git a/Tools/cases_generator/README.md b/Tools/cases_generator/README.md new file mode 100644 index 00000000..c595a932 --- /dev/null +++ b/Tools/cases_generator/README.md @@ -0,0 +1,36 @@ +# Tooling to generate interpreters + +Documentation for the instruction definitions in `Python/bytecodes.c` +("the DSL") is [here](interpreter_definition.md). + +What's currently here: + +- `lexer.py`: lexer for C, originally written by Mark Shannon +- `plexer.py`: OO interface on top of lexer.py; main class: `PLexer` +- `parser.py`: Parser for instruction definition DSL; main class `Parser` +- `generate_cases.py`: driver script to read `Python/bytecodes.c` and + write `Python/generated_cases.c.h` +- `test_generator.py`: tests, require manual running using `pytest` + +Note that there is some dummy C code at the top and bottom of +`Python/bytecodes.c` +to fool text editors like VS Code into believing this is valid C code. + +## A bit about the parser + +The parser class uses a pretty standard recursive descent scheme, +but with unlimited backtracking. +The `PLexer` class tokenizes the entire input before parsing starts. +We do not run the C preprocessor. +Each parsing method returns either an AST node (a `Node` instance) +or `None`, or raises `SyntaxError` (showing the error in the C source). + +Most parsing methods are decorated with `@contextual`, which automatically +resets the tokenizer input position when `None` is returned. +Parsing methods may also raise `SyntaxError`, which is irrecoverable. +When a parsing method returns `None`, it is possible that after backtracking +a different parsing method returns a valid AST. + +Neither the lexer nor the parsers are complete or fully correct. +Most known issues are tersely indicated by `# TODO:` comments. +We plan to fix issues as they become relevant. diff --git a/Tools/cases_generator/generate_cases.py b/Tools/cases_generator/generate_cases.py new file mode 100644 index 00000000..62ddeac0 --- /dev/null +++ b/Tools/cases_generator/generate_cases.py @@ -0,0 +1,1259 @@ +"""Generate the main interpreter switch. + +Reads the instruction definitions from bytecodes.c. +Writes the cases to generated_cases.c.h, which is #included in ceval.c. +""" + +import argparse +import contextlib +import dataclasses +import os +import posixpath +import re +import sys +import typing + +import lexer as lx +import parser +from parser import StackEffect + +HERE = os.path.dirname(__file__) +ROOT = os.path.join(HERE, "../..") +THIS = os.path.relpath(__file__, ROOT).replace(os.path.sep, posixpath.sep) + +DEFAULT_INPUT = os.path.relpath(os.path.join(ROOT, "Python/bytecodes.c")) +DEFAULT_OUTPUT = os.path.relpath(os.path.join(ROOT, "Python/generated_cases.c.h")) +DEFAULT_METADATA_OUTPUT = os.path.relpath( + os.path.join(ROOT, "Python/opcode_metadata.h") +) +BEGIN_MARKER = "// BEGIN BYTECODES //" +END_MARKER = "// END BYTECODES //" +RE_PREDICTED = ( + r"^\s*(?:PREDICT\(|GO_TO_INSTRUCTION\(|DEOPT_IF\(.*?,\s*)(\w+)\);\s*(?://.*)?$" +) +UNUSED = "unused" +BITS_PER_CODE_UNIT = 16 + +arg_parser = argparse.ArgumentParser( + description="Generate the code for the interpreter switch.", + formatter_class=argparse.ArgumentDefaultsHelpFormatter, +) +arg_parser.add_argument( + "-o", "--output", type=str, help="Generated code", default=DEFAULT_OUTPUT +) +arg_parser.add_argument( + "-m", "--metadata", type=str, help="Generated metadata", default=DEFAULT_METADATA_OUTPUT +) +arg_parser.add_argument( + "-l", "--emit-line-directives", help="Emit #line directives", action="store_true" +) +arg_parser.add_argument( + "input", nargs=argparse.REMAINDER, help="Instruction definition file(s)" +) + + +def effect_size(effect: StackEffect) -> tuple[int, str]: + """Return the 'size' impact of a stack effect. + + Returns a tuple (numeric, symbolic) where: + + - numeric is an int giving the statically analyzable size of the effect + - symbolic is a string representing a variable effect (e.g. 'oparg*2') + + At most one of these will be non-zero / non-empty. + """ + if effect.size: + assert not effect.cond, "Array effects cannot have a condition" + return 0, effect.size + elif effect.cond: + return 0, f"{maybe_parenthesize(effect.cond)} ? 1 : 0" + else: + return 1, "" + + +def maybe_parenthesize(sym: str) -> str: + """Add parentheses around a string if it contains an operator. + + An exception is made for '*' which is common and harmless + in the context where the symbolic size is used. + """ + if re.match(r"^[\s\w*]+$", sym): + return sym + else: + return f"({sym})" + + +def list_effect_size(effects: list[StackEffect]) -> tuple[int, str]: + numeric = 0 + symbolic: list[str] = [] + for effect in effects: + diff, sym = effect_size(effect) + numeric += diff + if sym: + symbolic.append(maybe_parenthesize(sym)) + return numeric, " + ".join(symbolic) + + +def string_effect_size(arg: tuple[int, str]) -> str: + numeric, symbolic = arg + if numeric and symbolic: + return f"{numeric} + {symbolic}" + elif symbolic: + return symbolic + else: + return str(numeric) + + +class Formatter: + """Wraps an output stream with the ability to indent etc.""" + + stream: typing.TextIO + prefix: str + emit_line_directives: bool = False + lineno: int # Next line number, 1-based + filename: str # Slightly improved stream.filename + nominal_lineno: int + nominal_filename: str + + def __init__( + self, stream: typing.TextIO, indent: int, emit_line_directives: bool = False + ) -> None: + self.stream = stream + self.prefix = " " * indent + self.emit_line_directives = emit_line_directives + self.lineno = 1 + filename = os.path.relpath(self.stream.name, ROOT) + # Make filename more user-friendly and less platform-specific + filename = filename.replace("\\", "/") + if filename.startswith("./"): + filename = filename[2:] + if filename.endswith(".new"): + filename = filename[:-4] + self.filename = filename + self.nominal_lineno = 1 + self.nominal_filename = filename + + def write_raw(self, s: str) -> None: + self.stream.write(s) + newlines = s.count("\n") + self.lineno += newlines + self.nominal_lineno += newlines + + def emit(self, arg: str) -> None: + if arg: + self.write_raw(f"{self.prefix}{arg}\n") + else: + self.write_raw("\n") + + def set_lineno(self, lineno: int, filename: str) -> None: + if self.emit_line_directives: + if lineno != self.nominal_lineno or filename != self.nominal_filename: + self.emit(f'#line {lineno} "{filename}"') + self.nominal_lineno = lineno + self.nominal_filename = filename + + def reset_lineno(self) -> None: + if self.lineno != self.nominal_lineno or self.filename != self.nominal_filename: + self.set_lineno(self.lineno + 1, self.filename) + + @contextlib.contextmanager + def indent(self): + self.prefix += " " + yield + self.prefix = self.prefix[:-4] + + @contextlib.contextmanager + def block(self, head: str): + if head: + self.emit(head + " {") + else: + self.emit("{") + with self.indent(): + yield + self.emit("}") + + def stack_adjust( + self, + diff: int, + input_effects: list[StackEffect], + output_effects: list[StackEffect], + ): + # TODO: Get rid of 'diff' parameter + shrink, isym = list_effect_size(input_effects) + grow, osym = list_effect_size(output_effects) + diff += grow - shrink + if isym and isym != osym: + self.emit(f"STACK_SHRINK({isym});") + if diff < 0: + self.emit(f"STACK_SHRINK({-diff});") + if diff > 0: + self.emit(f"STACK_GROW({diff});") + if osym and osym != isym: + self.emit(f"STACK_GROW({osym});") + + def declare(self, dst: StackEffect, src: StackEffect | None): + if dst.name == UNUSED: + return + typ = f"{dst.type}" if dst.type else "PyObject *" + if src: + cast = self.cast(dst, src) + init = f" = {cast}{src.name}" + elif dst.cond: + init = " = NULL" + else: + init = "" + sepa = "" if typ.endswith("*") else " " + self.emit(f"{typ}{sepa}{dst.name}{init};") + + def assign(self, dst: StackEffect, src: StackEffect): + if src.name == UNUSED: + return + if src.size: + # Don't write sized arrays -- it's up to the user code. + return + cast = self.cast(dst, src) + if re.match(r"^REG\(oparg(\d+)\)$", dst.name): + self.emit(f"Py_XSETREF({dst.name}, {cast}{src.name});") + else: + stmt = f"{dst.name} = {cast}{src.name};" + if src.cond: + stmt = f"if ({src.cond}) {{ {stmt} }}" + self.emit(stmt) + + def cast(self, dst: StackEffect, src: StackEffect) -> str: + return f"({dst.type or 'PyObject *'})" if src.type != dst.type else "" + + +@dataclasses.dataclass +class Instruction: + """An instruction with additional data and code.""" + + # Parts of the underlying instruction definition + inst: parser.InstDef + kind: typing.Literal["inst", "op", "legacy"] # Legacy means no (input -- output) + name: str + block: parser.Block + block_text: list[str] # Block.text, less curlies, less PREDICT() calls + predictions: list[str] # Prediction targets (instruction names) + block_line: int # First line of block in original code + + # Computed by constructor + always_exits: bool + cache_offset: int + cache_effects: list[parser.CacheEffect] + input_effects: list[StackEffect] + output_effects: list[StackEffect] + unmoved_names: frozenset[str] + instr_fmt: str + + # Set later + family: parser.Family | None = None + predicted: bool = False + + def __init__(self, inst: parser.InstDef): + self.inst = inst + self.kind = inst.kind + self.name = inst.name + self.block = inst.block + self.block_text, self.check_eval_breaker, self.predictions, self.block_line = \ + extract_block_text(self.block) + self.always_exits = always_exits(self.block_text) + self.cache_effects = [ + effect for effect in inst.inputs if isinstance(effect, parser.CacheEffect) + ] + self.cache_offset = sum(c.size for c in self.cache_effects) + self.input_effects = [ + effect for effect in inst.inputs if isinstance(effect, StackEffect) + ] + self.output_effects = inst.outputs # For consistency/completeness + unmoved_names: set[str] = set() + for ieffect, oeffect in zip(self.input_effects, self.output_effects): + if ieffect.name == oeffect.name: + unmoved_names.add(ieffect.name) + else: + break + self.unmoved_names = frozenset(unmoved_names) + if variable_used(inst, "oparg"): + fmt = "IB" + else: + fmt = "IX" + cache = "C" + for ce in self.cache_effects: + for _ in range(ce.size): + fmt += cache + cache = "0" + self.instr_fmt = fmt + + def write(self, out: Formatter) -> None: + """Write one instruction, sans prologue and epilogue.""" + # Write a static assertion that a family's cache size is correct + if family := self.family: + if self.name == family.members[0]: + if cache_size := family.size: + out.emit( + f"static_assert({cache_size} == " + f'{self.cache_offset}, "incorrect cache size");' + ) + + # Write input stack effect variable declarations and initializations + ieffects = list(reversed(self.input_effects)) + for i, ieffect in enumerate(ieffects): + isize = string_effect_size( + list_effect_size([ieff for ieff in ieffects[: i + 1]]) + ) + if ieffect.size: + src = StackEffect(f"(stack_pointer - {maybe_parenthesize(isize)})", "PyObject **") + elif ieffect.cond: + src = StackEffect(f"({ieffect.cond}) ? stack_pointer[-{maybe_parenthesize(isize)}] : NULL", "") + else: + src = StackEffect(f"stack_pointer[-{maybe_parenthesize(isize)}]", "") + out.declare(ieffect, src) + + # Write output stack effect variable declarations + isize = string_effect_size(list_effect_size(self.input_effects)) + input_names = {ieffect.name for ieffect in self.input_effects} + for i, oeffect in enumerate(self.output_effects): + if oeffect.name not in input_names: + if oeffect.size: + osize = string_effect_size( + list_effect_size([oeff for oeff in self.output_effects[:i]]) + ) + offset = "stack_pointer" + if isize != osize: + if isize != "0": + offset += f" - ({isize})" + if osize != "0": + offset += f" + {osize}" + src = StackEffect(offset, "PyObject **") + out.declare(oeffect, src) + else: + out.declare(oeffect, None) + + # out.emit(f"next_instr += OPSIZE({self.inst.name}) - 1;") + + self.write_body(out, 0) + + # Skip the rest if the block always exits + if self.always_exits: + return + + # Write net stack growth/shrinkage + out.stack_adjust( + 0, + [ieff for ieff in self.input_effects], + [oeff for oeff in self.output_effects], + ) + + # Write output stack effect assignments + oeffects = list(reversed(self.output_effects)) + for i, oeffect in enumerate(oeffects): + if oeffect.name in self.unmoved_names: + continue + osize = string_effect_size( + list_effect_size([oeff for oeff in oeffects[: i + 1]]) + ) + if oeffect.size: + dst = StackEffect(f"stack_pointer - {maybe_parenthesize(osize)}", "PyObject **") + else: + dst = StackEffect(f"stack_pointer[-{maybe_parenthesize(osize)}]", "") + out.assign(dst, oeffect) + + # Write cache effect + if self.cache_offset: + out.emit(f"next_instr += {self.cache_offset};") + + def write_body(self, out: Formatter, dedent: int, cache_adjust: int = 0) -> None: + """Write the instruction body.""" + # Write cache effect variable declarations and initializations + cache_offset = cache_adjust + for ceffect in self.cache_effects: + if ceffect.name != UNUSED: + bits = ceffect.size * BITS_PER_CODE_UNIT + if bits == 64: + # NOTE: We assume that 64-bit data in the cache + # is always an object pointer. + # If this becomes false, we need a way to specify + # syntactically what type the cache data is. + typ = "PyObject *" + func = "read_obj" + else: + typ = f"uint{bits}_t " + func = f"read_u{bits}" + out.emit( + f"{typ}{ceffect.name} = {func}(&next_instr[{cache_offset}].cache);" + ) + cache_offset += ceffect.size + assert cache_offset == self.cache_offset + cache_adjust + + # Write the body, substituting a goto for ERROR_IF() and other stuff + assert dedent <= 0 + extra = " " * -dedent + names_to_skip = self.unmoved_names | frozenset({UNUSED, "null"}) + offset = 0 + context = self.block.context + assert context != None + filename = context.owner.filename + for line in self.block_text: + out.set_lineno(self.block_line + offset, filename) + offset += 1 + if m := re.match(r"(\s*)ERROR_IF\((.+), (\w+)\);\s*(?://.*)?$", line): + space, cond, label = m.groups() + space = extra + space + # ERROR_IF() must pop the inputs from the stack. + # The code block is responsible for DECREF()ing them. + # NOTE: If the label doesn't exist, just add it to ceval.c. + + # Don't pop common input/output effects at the bottom! + # These aren't DECREF'ed so they can stay. + ieffs = list(self.input_effects) + oeffs = list(self.output_effects) + while ieffs and oeffs and ieffs[0] == oeffs[0]: + ieffs.pop(0) + oeffs.pop(0) + ninputs, symbolic = list_effect_size(ieffs) + if ninputs: + label = f"pop_{ninputs}_{label}" + if symbolic: + out.write_raw( + f"{space}if ({cond}) {{ STACK_SHRINK({symbolic}); goto {label}; }}\n" + ) + else: + out.write_raw(f"{space}if ({cond}) goto {label};\n") + elif m := re.match(r"(\s*)DECREF_INPUTS\(\);\s*(?://.*)?$", line): + out.reset_lineno() + space = extra + m.group(1) + for ieff in self.input_effects: + if ieff.name in names_to_skip: + continue + if ieff.size: + out.write_raw( + f"{space}for (int _i = {ieff.size}; --_i >= 0;) {{\n" + ) + out.write_raw(f"{space} Py_DECREF({ieff.name}[_i]);\n") + out.write_raw(f"{space}}}\n") + else: + decref = "XDECREF" if ieff.cond else "DECREF" + out.write_raw(f"{space}Py_{decref}({ieff.name});\n") + else: + out.write_raw(extra + line) + out.reset_lineno() + + +InstructionOrCacheEffect = Instruction | parser.CacheEffect +StackEffectMapping = list[tuple[StackEffect, StackEffect]] + + +@dataclasses.dataclass +class Component: + instr: Instruction + input_mapping: StackEffectMapping + output_mapping: StackEffectMapping + + def write_body(self, out: Formatter, cache_adjust: int) -> None: + with out.block(""): + input_names = {ieffect.name for _, ieffect in self.input_mapping} + for var, ieffect in self.input_mapping: + out.declare(ieffect, var) + for _, oeffect in self.output_mapping: + if oeffect.name not in input_names: + out.declare(oeffect, None) + + self.instr.write_body(out, dedent=-4, cache_adjust=cache_adjust) + + for var, oeffect in self.output_mapping: + out.assign(var, oeffect) + + +@dataclasses.dataclass +class SuperOrMacroInstruction: + """Common fields for super- and macro instructions.""" + + name: str + stack: list[StackEffect] + initial_sp: int + final_sp: int + instr_fmt: str + + +@dataclasses.dataclass +class SuperInstruction(SuperOrMacroInstruction): + """A super-instruction.""" + + super: parser.Super + parts: list[Component] + + +@dataclasses.dataclass +class MacroInstruction(SuperOrMacroInstruction): + """A macro instruction.""" + + macro: parser.Macro + parts: list[Component | parser.CacheEffect] + + +@dataclasses.dataclass +class OverriddenInstructionPlaceHolder: + name: str + + +AnyInstruction = Instruction | SuperInstruction | MacroInstruction +INSTR_FMT_PREFIX = "INSTR_FMT_" + + +class Analyzer: + """Parse input, analyze it, and write to output.""" + + input_filenames: list[str] + output_filename: str + metadata_filename: str + errors: int = 0 + emit_line_directives: bool = False + + def __init__(self, input_filenames: list[str], output_filename: str, metadata_filename: str): + """Read the input file.""" + self.input_filenames = input_filenames + self.output_filename = output_filename + self.metadata_filename = metadata_filename + + def error(self, msg: str, node: parser.Node) -> None: + lineno = 0 + filename = "<unknown file>" + if context := node.context: + filename = context.owner.filename + # Use line number of first non-comment in the node + for token in context.owner.tokens[context.begin : context.end]: + lineno = token.line + if token.kind != "COMMENT": + break + print(f"{filename}:{lineno}: {msg}", file=sys.stderr) + self.errors += 1 + + everything: list[ + parser.InstDef | parser.Super | parser.Macro | OverriddenInstructionPlaceHolder + ] + instrs: dict[str, Instruction] # Includes ops + supers: dict[str, parser.Super] + super_instrs: dict[str, SuperInstruction] + macros: dict[str, parser.Macro] + macro_instrs: dict[str, MacroInstruction] + families: dict[str, parser.Family] + + def parse(self) -> None: + """Parse the source text. + + We only want the parser to see the stuff between the + begin and end markers. + """ + + self.everything = [] + self.instrs = {} + self.supers = {} + self.macros = {} + self.families = {} + + instrs_idx: dict[str, int] = dict() + + for filename in self.input_filenames: + self.parse_file(filename, instrs_idx) + + files = " + ".join(self.input_filenames) + print( + f"Read {len(self.instrs)} instructions/ops, " + f"{len(self.supers)} supers, {len(self.macros)} macros, " + f"and {len(self.families)} families from {files}", + file=sys.stderr, + ) + + def parse_file(self, filename: str, instrs_idx: dict[str, int]) -> None: + with open(filename) as file: + src = file.read() + + filename = os.path.relpath(filename, ROOT) + # Make filename more user-friendly and less platform-specific + filename = filename.replace("\\", "/") + if filename.startswith("./"): + filename = filename[2:] + psr = parser.Parser(src, filename=filename) + + # Skip until begin marker + while tkn := psr.next(raw=True): + if tkn.text == BEGIN_MARKER: + break + else: + raise psr.make_syntax_error( + f"Couldn't find {BEGIN_MARKER!r} in {psr.filename}" + ) + start = psr.getpos() + + # Find end marker, then delete everything after it + while tkn := psr.next(raw=True): + if tkn.text == END_MARKER: + break + del psr.tokens[psr.getpos() - 1 :] + + # Parse from start + psr.setpos(start) + thing: parser.InstDef | parser.Super | parser.Macro | parser.Family | None + thing_first_token = psr.peek() + while thing := psr.definition(): + match thing: + case parser.InstDef(name=name): + if name in self.instrs: + if not thing.override: + raise psr.make_syntax_error( + f"Duplicate definition of '{name}' @ {thing.context} " + f"previous definition @ {self.instrs[name].inst.context}", + thing_first_token, + ) + self.everything[instrs_idx[name]] = OverriddenInstructionPlaceHolder(name=name) + if name not in self.instrs and thing.override: + raise psr.make_syntax_error( + f"Definition of '{name}' @ {thing.context} is supposed to be " + "an override but no previous definition exists.", + thing_first_token, + ) + self.instrs[name] = Instruction(thing) + instrs_idx[name] = len(self.everything) + self.everything.append(thing) + case parser.Super(name): + self.supers[name] = thing + self.everything.append(thing) + case parser.Macro(name): + self.macros[name] = thing + self.everything.append(thing) + case parser.Family(name): + self.families[name] = thing + case _: + typing.assert_never(thing) + if not psr.eof(): + raise psr.make_syntax_error(f"Extra stuff at the end of {filename}") + + def analyze(self) -> None: + """Analyze the inputs. + + Raises SystemExit if there is an error. + """ + self.find_predictions() + self.analyze_supers_and_macros() + self.map_families() + self.check_families() + + def find_predictions(self) -> None: + """Find the instructions that need PREDICTED() labels.""" + for instr in self.instrs.values(): + targets = set(instr.predictions) + for line in instr.block_text: + if m := re.match(RE_PREDICTED, line): + targets.add(m.group(1)) + for target in targets: + if target_instr := self.instrs.get(target): + target_instr.predicted = True + else: + self.error( + f"Unknown instruction {target!r} predicted in {instr.name!r}", + instr.inst, # TODO: Use better location + ) + + def map_families(self) -> None: + """Link instruction names back to their family, if they have one.""" + for family in self.families.values(): + for member in family.members: + if member_instr := self.instrs.get(member): + if member_instr.family not in (family, None): + self.error( + f"Instruction {member} is a member of multiple families " + f"({member_instr.family.name}, {family.name}).", + family, + ) + else: + member_instr.family = family + elif member_macro := self.macro_instrs.get(member): + for part in member_macro.parts: + if isinstance(part, Component): + if part.instr.family not in (family, None): + self.error( + f"Component {part.instr.name} of macro {member} " + f"is a member of multiple families " + f"({part.instr.family.name}, {family.name}).", + family, + ) + else: + part.instr.family = family + else: + self.error( + f"Unknown instruction {member!r} referenced in family {family.name!r}", + family, + ) + + def check_families(self) -> None: + """Check each family: + + - Must have at least 2 members + - All members must be known instructions + - All members must have the same cache, input and output effects + """ + for family in self.families.values(): + if len(family.members) < 2: + self.error(f"Family {family.name!r} has insufficient members", family) + members = [ + member + for member in family.members + if member in self.instrs or member in self.macro_instrs + ] + if members != family.members: + unknown = set(family.members) - set(members) + self.error( + f"Family {family.name!r} has unknown members: {unknown}", family + ) + if len(members) < 2: + continue + expected_effects = self.effect_counts(members[0]) + for member in members[1:]: + member_effects = self.effect_counts(member) + if member_effects != expected_effects: + self.error( + f"Family {family.name!r} has inconsistent " + f"(cache, input, output) effects:\n" + f" {family.members[0]} = {expected_effects}; " + f"{member} = {member_effects}", + family, + ) + + def effect_counts(self, name: str) -> tuple[int, int, int]: + if instr := self.instrs.get(name): + cache = instr.cache_offset + input = len(instr.input_effects) + output = len(instr.output_effects) + elif macro := self.macro_instrs.get(name): + cache, input, output = 0, 0, 0 + for part in macro.parts: + if isinstance(part, Component): + cache += part.instr.cache_offset + # A component may pop what the previous component pushed, + # so we offset the input/output counts by that. + delta_i = len(part.instr.input_effects) + delta_o = len(part.instr.output_effects) + offset = min(delta_i, output) + input += delta_i - offset + output += delta_o - offset + else: + assert isinstance(part, parser.CacheEffect), part + cache += part.size + else: + assert False, f"Unknown instruction {name!r}" + return cache, input, output + + def analyze_supers_and_macros(self) -> None: + """Analyze each super- and macro instruction.""" + self.super_instrs = {} + self.macro_instrs = {} + for name, super in self.supers.items(): + self.super_instrs[name] = self.analyze_super(super) + for name, macro in self.macros.items(): + self.macro_instrs[name] = self.analyze_macro(macro) + + def analyze_super(self, super: parser.Super) -> SuperInstruction: + components = self.check_super_components(super) + stack, initial_sp = self.stack_analysis(components) + sp = initial_sp + parts: list[Component] = [] + format = "" + for instr in components: + part, sp = self.analyze_instruction(instr, stack, sp) + parts.append(part) + format += instr.instr_fmt + final_sp = sp + return SuperInstruction( + super.name, stack, initial_sp, final_sp, format, super, parts + ) + + def analyze_macro(self, macro: parser.Macro) -> MacroInstruction: + components = self.check_macro_components(macro) + stack, initial_sp = self.stack_analysis(components) + sp = initial_sp + parts: list[Component | parser.CacheEffect] = [] + format = "IB" + cache = "C" + for component in components: + match component: + case parser.CacheEffect() as ceffect: + parts.append(ceffect) + for _ in range(ceffect.size): + format += cache + cache = "0" + case Instruction() as instr: + part, sp = self.analyze_instruction(instr, stack, sp) + parts.append(part) + for ce in instr.cache_effects: + for _ in range(ce.size): + format += cache + cache = "0" + case _: + typing.assert_never(component) + final_sp = sp + return MacroInstruction( + macro.name, stack, initial_sp, final_sp, format, macro, parts + ) + + def analyze_instruction( + self, instr: Instruction, stack: list[StackEffect], sp: int + ) -> tuple[Component, int]: + input_mapping: StackEffectMapping = [] + for ieffect in reversed(instr.input_effects): + sp -= 1 + input_mapping.append((stack[sp], ieffect)) + output_mapping: StackEffectMapping = [] + for oeffect in instr.output_effects: + output_mapping.append((stack[sp], oeffect)) + sp += 1 + return Component(instr, input_mapping, output_mapping), sp + + def check_super_components(self, super: parser.Super) -> list[Instruction]: + components: list[Instruction] = [] + for op in super.ops: + if op.name not in self.instrs: + self.error(f"Unknown instruction {op.name!r}", super) + else: + components.append(self.instrs[op.name]) + return components + + def check_macro_components( + self, macro: parser.Macro + ) -> list[InstructionOrCacheEffect]: + components: list[InstructionOrCacheEffect] = [] + for uop in macro.uops: + match uop: + case parser.OpName(name): + if name not in self.instrs: + self.error(f"Unknown instruction {name!r}", macro) + components.append(self.instrs[name]) + case parser.CacheEffect(): + components.append(uop) + case _: + typing.assert_never(uop) + return components + + def stack_analysis( + self, components: typing.Iterable[InstructionOrCacheEffect] + ) -> tuple[list[StackEffect], int]: + """Analyze a super-instruction or macro. + + Ignore cache effects. + + Return the list of variable names and the initial stack pointer. + """ + lowest = current = highest = 0 + for thing in components: + match thing: + case Instruction() as instr: + if any( + eff.size for eff in instr.input_effects + instr.output_effects + ): + # TODO: Eventually this will be needed, at least for macros. + self.error( + f"Instruction {instr.name!r} has variable-sized stack effect, " + "which are not supported in super- or macro instructions", + instr.inst, # TODO: Pass name+location of super/macro + ) + current -= len(instr.input_effects) + lowest = min(lowest, current) + current += len(instr.output_effects) + highest = max(highest, current) + case parser.CacheEffect(): + pass + case _: + typing.assert_never(thing) + # At this point, 'current' is the net stack effect, + # and 'lowest' and 'highest' are the extremes. + # Note that 'lowest' may be negative. + # TODO: Reverse the numbering. + stack = [ + StackEffect(f"_tmp_{i+1}", "") for i in reversed(range(highest - lowest)) + ] + return stack, -lowest + + def get_stack_effect_info( + self, thing: parser.InstDef | parser.Super | parser.Macro + ) -> tuple[AnyInstruction | None, str, str]: + def effect_str(effects: list[StackEffect]) -> str: + if getattr(thing, "kind", None) == "legacy": + return str(-1) + n_effect, sym_effect = list_effect_size(effects) + if sym_effect: + return f"{sym_effect} + {n_effect}" if n_effect else sym_effect + return str(n_effect) + + instr: AnyInstruction | None + match thing: + case parser.InstDef(): + if thing.kind != "op": + instr = self.instrs[thing.name] + popped = effect_str(instr.input_effects) + pushed = effect_str(instr.output_effects) + else: + instr = None + popped = "" + pushed = "" + case parser.Super(): + instr = self.super_instrs[thing.name] + popped = "+".join( + effect_str(comp.instr.input_effects) for comp in instr.parts + ) + pushed = "+".join( + effect_str(comp.instr.output_effects) for comp in instr.parts + ) + case parser.Macro(): + instr = self.macro_instrs[thing.name] + parts = [comp for comp in instr.parts if isinstance(comp, Component)] + popped = "+".join( + effect_str(comp.instr.input_effects) for comp in parts + ) + pushed = "+".join( + effect_str(comp.instr.output_effects) for comp in parts + ) + case _: + typing.assert_never(thing) + return instr, popped, pushed + + def write_stack_effect_functions(self) -> None: + popped_data: list[tuple[AnyInstruction, str]] = [] + pushed_data: list[tuple[AnyInstruction, str]] = [] + for thing in self.everything: + if isinstance(thing, OverriddenInstructionPlaceHolder): + continue + instr, popped, pushed = self.get_stack_effect_info(thing) + if instr is not None: + popped_data.append((instr, popped)) + pushed_data.append((instr, pushed)) + + def write_function( + direction: str, data: list[tuple[AnyInstruction, str]] + ) -> None: + self.out.emit("") + self.out.emit("#ifndef NEED_OPCODE_METADATA") + self.out.emit(f"extern int _PyOpcode_num_{direction}(int opcode, int oparg, bool jump);") + self.out.emit("#else") + self.out.emit("int") + self.out.emit(f"_PyOpcode_num_{direction}(int opcode, int oparg, bool jump) {{") + self.out.emit(" switch(opcode) {") + for instr, effect in data: + self.out.emit(f" case {instr.name}:") + self.out.emit(f" return {effect};") + self.out.emit(" default:") + self.out.emit(" return -1;") + self.out.emit(" }") + self.out.emit("}") + self.out.emit("#endif") + + write_function("popped", popped_data) + write_function("pushed", pushed_data) + self.out.emit("") + + def from_source_files(self) -> str: + paths = "\n// ".join( + os.path.relpath(filename, ROOT).replace(os.path.sep, posixpath.sep) + for filename in self.input_filenames + ) + return f"// from:\n// {paths}\n" + + def write_metadata(self) -> None: + """Write instruction metadata to output file.""" + + # Compute the set of all instruction formats. + all_formats: set[str] = set() + for thing in self.everything: + match thing: + case OverriddenInstructionPlaceHolder(): + continue + case parser.InstDef(): + format = self.instrs[thing.name].instr_fmt + case parser.Super(): + format = self.super_instrs[thing.name].instr_fmt + case parser.Macro(): + format = self.macro_instrs[thing.name].instr_fmt + case _: + typing.assert_never(thing) + all_formats.add(format) + # Turn it into a list of enum definitions. + format_enums = [INSTR_FMT_PREFIX + format for format in sorted(all_formats)] + + with open(self.metadata_filename, "w") as f: + # Create formatter + self.out = Formatter(f, 0) + + # Write provenance header + self.out.write_raw(f"// This file is generated by {THIS}\n") + self.out.write_raw(self.from_source_files()) + self.out.write_raw(f"// Do not edit!\n") + + + self.write_stack_effect_functions() + + # Write type definitions + self.out.emit(f"enum InstructionFormat {{ {', '.join(format_enums)} }};") + self.out.emit("struct opcode_metadata {") + with self.out.indent(): + self.out.emit("bool valid_entry;") + self.out.emit("enum InstructionFormat instr_format;") + self.out.emit("};") + self.out.emit("") + + # Write metadata array declaration + self.out.emit("#ifndef NEED_OPCODE_METADATA") + self.out.emit("extern const struct opcode_metadata _PyOpcode_opcode_metadata[256];") + self.out.emit("#else") + self.out.emit("const struct opcode_metadata _PyOpcode_opcode_metadata[256] = {") + + # Write metadata for each instruction + for thing in self.everything: + match thing: + case OverriddenInstructionPlaceHolder(): + continue + case parser.InstDef(): + if thing.kind != "op": + self.write_metadata_for_inst(self.instrs[thing.name]) + case parser.Super(): + self.write_metadata_for_super(self.super_instrs[thing.name]) + case parser.Macro(): + self.write_metadata_for_macro(self.macro_instrs[thing.name]) + case _: + typing.assert_never(thing) + + # Write end of array + self.out.emit("};") + self.out.emit("#endif") + + def write_metadata_for_inst(self, instr: Instruction) -> None: + """Write metadata for a single instruction.""" + self.out.emit( + f" [{instr.name}] = {{ true, {INSTR_FMT_PREFIX}{instr.instr_fmt} }}," + ) + + def write_metadata_for_super(self, sup: SuperInstruction) -> None: + """Write metadata for a super-instruction.""" + self.out.emit( + f" [{sup.name}] = {{ true, {INSTR_FMT_PREFIX}{sup.instr_fmt} }}," + ) + + def write_metadata_for_macro(self, mac: MacroInstruction) -> None: + """Write metadata for a macro-instruction.""" + self.out.emit( + f" [{mac.name}] = {{ true, {INSTR_FMT_PREFIX}{mac.instr_fmt} }}," + ) + + def write_instructions(self) -> None: + """Write instructions to output file.""" + with open(self.output_filename, "w") as f: + # Create formatter + self.out = Formatter(f, 8, self.emit_line_directives) + + # Write provenance header + self.out.write_raw(f"// This file is generated by {THIS}\n") + self.out.write_raw(self.from_source_files()) + self.out.write_raw(f"// Do not edit!\n") + + # Write and count instructions of all kinds + n_instrs = 0 + n_supers = 0 + n_macros = 0 + for thing in self.everything: + match thing: + case OverriddenInstructionPlaceHolder(): + self.write_overridden_instr_place_holder(thing) + case parser.InstDef(): + if thing.kind != "op": + n_instrs += 1 + self.write_instr(self.instrs[thing.name]) + case parser.Super(): + n_supers += 1 + self.write_super(self.super_instrs[thing.name]) + case parser.Macro(): + n_macros += 1 + self.write_macro(self.macro_instrs[thing.name]) + case _: + typing.assert_never(thing) + + print( + f"Wrote {n_instrs} instructions, {n_supers} supers, " + f"and {n_macros} macros to {self.output_filename}", + file=sys.stderr, + ) + + def write_overridden_instr_place_holder(self, + place_holder: OverriddenInstructionPlaceHolder) -> None: + self.out.emit("") + self.out.emit( + f"// TARGET({place_holder.name}) overridden by later definition") + + def write_instr(self, instr: Instruction) -> None: + name = instr.name + self.out.emit("") + if instr.inst.override: + self.out.emit("// Override") + with self.out.block(f"TARGET({name})"): + if instr.predicted: + self.out.emit(f"PREDICTED({name});") + instr.write(self.out) + if not instr.always_exits: + for prediction in instr.predictions: + self.out.emit(f"PREDICT({prediction});") + if instr.check_eval_breaker: + self.out.emit("CHECK_EVAL_BREAKER();") + self.out.emit(f"DISPATCH();") + + def write_super(self, sup: SuperInstruction) -> None: + """Write code for a super-instruction.""" + with self.wrap_super_or_macro(sup): + first = True + for comp in sup.parts: + if not first: + self.out.emit("oparg = (next_instr++)->op.arg;") + # self.out.emit("next_instr += OPSIZE(opcode) - 1;") + first = False + comp.write_body(self.out, 0) + if comp.instr.cache_offset: + self.out.emit(f"next_instr += {comp.instr.cache_offset};") + + def write_macro(self, mac: MacroInstruction) -> None: + """Write code for a macro instruction.""" + last_instr: Instruction | None = None + with self.wrap_super_or_macro(mac): + cache_adjust = 0 + for part in mac.parts: + match part: + case parser.CacheEffect(size=size): + cache_adjust += size + case Component() as comp: + last_instr = comp.instr + comp.write_body(self.out, cache_adjust) + cache_adjust += comp.instr.cache_offset + + if cache_adjust: + self.out.emit(f"next_instr += {cache_adjust};") + + if ( + last_instr + and (family := last_instr.family) + and mac.name == family.members[0] + and (cache_size := family.size) + ): + self.out.emit( + f"static_assert({cache_size} == " + f'{cache_adjust}, "incorrect cache size");' + ) + + @contextlib.contextmanager + def wrap_super_or_macro(self, up: SuperOrMacroInstruction): + """Shared boilerplate for super- and macro instructions.""" + # TODO: Somewhere (where?) make it so that if one instruction + # has an output that is input to another, and the variable names + # and types match and don't conflict with other instructions, + # that variable is declared with the right name and type in the + # outer block, rather than trusting the compiler to optimize it. + self.out.emit("") + with self.out.block(f"TARGET({up.name})"): + for i, var in reversed(list(enumerate(up.stack))): + src = None + if i < up.initial_sp: + src = StackEffect(f"stack_pointer[-{up.initial_sp - i}]", "") + self.out.declare(var, src) + + yield + + # TODO: Use slices of up.stack instead of numeric values + self.out.stack_adjust(up.final_sp - up.initial_sp, [], []) + + for i, var in enumerate(reversed(up.stack[: up.final_sp]), 1): + dst = StackEffect(f"stack_pointer[-{i}]", "") + self.out.assign(dst, var) + + self.out.emit(f"DISPATCH();") + + +def extract_block_text(block: parser.Block) -> tuple[list[str], bool, list[str], int]: + # Get lines of text with proper dedent + blocklines = block.text.splitlines(True) + first_token: lx.Token = block.tokens[0] # IndexError means the context is broken + block_line = first_token.begin[0] + + # Remove blank lines from both ends + while blocklines and not blocklines[0].strip(): + blocklines.pop(0) + block_line += 1 + while blocklines and not blocklines[-1].strip(): + blocklines.pop() + + # Remove leading and trailing braces + assert blocklines and blocklines[0].strip() == "{" + assert blocklines and blocklines[-1].strip() == "}" + blocklines.pop() + blocklines.pop(0) + block_line += 1 + + # Remove trailing blank lines + while blocklines and not blocklines[-1].strip(): + blocklines.pop() + + # Separate CHECK_EVAL_BREAKER() macro from end + check_eval_breaker = \ + blocklines != [] and blocklines[-1].strip() == "CHECK_EVAL_BREAKER();" + if check_eval_breaker: + del blocklines[-1] + + # Separate PREDICT(...) macros from end + predictions: list[str] = [] + while blocklines and ( + m := re.match(r"^\s*PREDICT\((\w+)\);\s*(?://.*)?$", blocklines[-1]) + ): + predictions.insert(0, m.group(1)) + blocklines.pop() + + return blocklines, check_eval_breaker, predictions, block_line + + +def always_exits(lines: list[str]) -> bool: + """Determine whether a block always ends in a return/goto/etc.""" + if not lines: + return False + line = lines[-1].rstrip() + # Indent must match exactly (TODO: Do something better) + if line[:12] != " " * 12: + return False + line = line[12:] + return line.startswith( + ( + "goto ", + "return ", + "DISPATCH", + "GO_TO_", + "Py_UNREACHABLE()", + "ERROR_IF(true, ", + ) + ) + + +def variable_used(node: parser.Node, name: str) -> bool: + """Determine whether a variable with a given name is used in a node.""" + return any( + token.kind == "IDENTIFIER" and token.text == name for token in node.tokens + ) + + +def main(): + """Parse command line, parse input, analyze, write output.""" + args = arg_parser.parse_args() # Prints message and sys.exit(2) on error + if len(args.input) == 0: + args.input.append(DEFAULT_INPUT) + a = Analyzer(args.input, args.output, args.metadata) # Raises OSError if input unreadable + if args.emit_line_directives: + a.emit_line_directives = True + a.parse() # Raises SyntaxError on failure + a.analyze() # Prints messages and sets a.errors on failure + if a.errors: + sys.exit(f"Found {a.errors} errors") + a.write_instructions() # Raises OSError if output can't be written + a.write_metadata() + + +if __name__ == "__main__": + main() diff --git a/Tools/cases_generator/interpreter_definition.md b/Tools/cases_generator/interpreter_definition.md new file mode 100644 index 00000000..6f902f60 --- /dev/null +++ b/Tools/cases_generator/interpreter_definition.md @@ -0,0 +1,409 @@ +# A higher level definition of the bytecode interpreter + +## Abstract + +The CPython interpreter is defined in C, meaning that the semantics of the +bytecode instructions, the dispatching mechanism, error handling, and +tracing and instrumentation are all intermixed. + +This document proposes defining a custom C-like DSL for defining the +instruction semantics and tools for generating the code deriving from +the instruction definitions. + +These tools would be used to: +* Generate the main interpreter (done) +* Generate the tier 2 interpreter +* Generate documentation for instructions +* Generate metadata about instructions, such as stack use (done). + +Having a single definition file ensures that there is a single source +of truth for bytecode semantics. + +Other tools that operate on bytecodes, like `frame.setlineno` +and the `dis` module, will be derived from the common semantic +definition, reducing errors. + +## Motivation + +The bytecode interpreter of CPython has traditionally been defined as standard +C code, but with a lot of macros. +The presence of these macros and the nature of bytecode interpreters means +that the interpreter is effectively defined in a domain specific language (DSL). + +Rather than using an ad-hoc DSL embedded in the C code for the interpreter, +a custom DSL should be defined and the semantics of the bytecode instructions, +and the instructions defined in that DSL. + +Generating the interpreter decouples low-level details of dispatching +and error handling from the semantics of the instructions, resulting +in more maintainable code and a potentially faster interpreter. + +It also provides the ability to create and check optimizers and optimization +passes from the semantic definition, reducing errors. + +## Rationale + +As we improve the performance of CPython, we need to optimize larger regions +of code, use more complex optimizations and, ultimately, translate to machine +code. + +All of these steps introduce the possibility of more bugs, and require more code +to be written. One way to mitigate this is through the use of code generators. +Code generators decouple the debugging of the code (the generator) from checking +the correctness (the DSL input). + +For example, we are likely to want a new interpreter for the tier 2 optimizer +to be added in 3.12. That interpreter will have a different API, a different +set of instructions and potentially different dispatching mechanism. +But the instructions it will interpret will be built from the same building +blocks as the instructions for the tier 1 (PEP 659) interpreter. + +Rewriting all the instructions is tedious and error-prone, and changing the +instructions is a maintenance headache as both versions need to be kept in sync. + +By using a code generator and using a common source for the instructions, or +parts of instructions, we can reduce the potential for errors considerably. + + +## Specification + +This specification is at an early stage and is likely to change considerably. + +Syntax +------ + +Each op definition has a kind, a name, a stack and instruction stream effect, +and a piece of C code describing its semantics:: + +``` + file: + (definition | family)+ + + definition: + "inst" "(" NAME ["," stack_effect] ")" "{" C-code "}" + | + "op" "(" NAME "," stack_effect ")" "{" C-code "}" + | + "macro" "(" NAME ")" "=" uop ("+" uop)* ";" + | + "super" "(" NAME ")" "=" NAME ("+" NAME)* ";" + + stack_effect: + "(" [inputs] "--" [outputs] ")" + + inputs: + input ("," input)* + + outputs: + output ("," output)* + + input: + object | stream | array + + output: + object | array + + uop: + NAME | stream + + object: + NAME [":" type] [ "if" "(" C-expression ")" ] + + type: + NAME + + stream: + NAME "/" size + + size: + INTEGER + + array: + object "[" C-expression "]" + + family: + "family" "(" NAME ")" = "{" NAME ("," NAME)+ "}" ";" +``` + +The following definitions may occur: + +* `inst`: A normal instruction, as previously defined by `TARGET(NAME)` in `ceval.c`. +* `op`: A part instruction from which macros can be constructed. +* `macro`: A bytecode instruction constructed from ops and cache effects. +* `super`: A super-instruction, such as `LOAD_FAST__LOAD_FAST`, constructed from + normal or macro instructions. + +`NAME` can be any ASCII identifier that is a C identifier and not a C or Python keyword. +`foo_1` is legal. `$` is not legal, nor is `struct` or `class`. + +The optional `type` in an `object` is the C type. It defaults to `PyObject *`. +The objects before the "--" are the objects on top of the stack at the start of +the instruction. Those after the "--" are the objects on top of the stack at the +end of the instruction. + +An `inst` without `stack_effect` is a transitional form to allow the original C code +definitions to be copied. It lacks information to generate anything other than the +interpreter, but is useful for initial porting of code. + +Stack effect names may be `unused`, indicating the space is to be reserved +but no use of it will be made in the instruction definition. +This is useful to ensure that all instructions in a family have the same +stack effect. + +The number in a `stream` define how many codeunits are consumed from the +instruction stream. It returns a 16, 32 or 64 bit value. +If the name is `unused` the size can be any value and that many codeunits +will be skipped in the instruction stream. + +By convention cache effects (`stream`) must precede the input effects. + +The name `oparg` is pre-defined as a 32 bit value fetched from the instruction stream. + +The C code may include special functions that are understood by the tools as +part of the DSL. + +Those functions include: + +* `DEOPT_IF(cond, instruction)`. Deoptimize if `cond` is met. +* `ERROR_IF(cond, label)`. Jump to error handler if `cond` is true. +* `DECREF_INPUTS()`. Generate `Py_DECREF()` calls for the input stack effects. + +Variables can either be defined in the input, output, or in the C code. +Variables defined in the input may not be assigned in the C code. +If an `ERROR_IF` occurs, all values will be removed from the stack; +they must already be `DECREF`'ed by the code block. +If a `DEOPT_IF` occurs, no values will be removed from the stack or +the instruction stream; no values must have been `DECREF`'ed or created. + +These requirements result in the following constraints on the use of +`DEOPT_IF` and `ERROR_IF` in any instruction's code block: + +1. Until the last `DEOPT_IF`, no objects may be allocated, `INCREF`ed, + or `DECREF`ed. +2. Before the first `ERROR_IF`, all input values must be `DECREF`ed, + and no objects may be allocated or `INCREF`ed, with the exception + of attempting to create an object and checking for success using + `ERROR_IF(result == NULL, label)`. (TODO: Unclear what to do with + intermediate results.) +3. No `DEOPT_IF` may follow an `ERROR_IF` in the same block. + +Semantics +--------- + +The underlying execution model is a stack machine. +Operations pop values from the stack, and push values to the stack. +They also can look at, and consume, values from the instruction stream. + +All members of a family must have the same stack and instruction stream effect. + +Examples +-------- + +(Another source of examples can be found in the [tests](test_generator.py).) + +Some examples: + +### Output stack effect +```C + inst ( LOAD_FAST, (-- value) ) { + value = frame->f_localsplus[oparg]; + Py_INCREF(value); + } +``` +This would generate: +```C + TARGET(LOAD_FAST) { + PyObject *value; + value = frame->f_localsplus[oparg]; + Py_INCREF(value); + PUSH(value); + DISPATCH(); + } +``` + +### Input stack effect +```C + inst ( STORE_FAST, (value --) ) { + SETLOCAL(oparg, value); + } +``` +This would generate: +```C + TARGET(STORE_FAST) { + PyObject *value = PEEK(1); + SETLOCAL(oparg, value); + STACK_SHRINK(1); + DISPATCH(); + } +``` + +### Super-instruction definition + +```C + super ( LOAD_FAST__LOAD_FAST ) = LOAD_FAST + LOAD_FAST ; +``` +This might get translated into the following: +```C + TARGET(LOAD_FAST__LOAD_FAST) { + PyObject *value; + value = frame->f_localsplus[oparg]; + Py_INCREF(value); + PUSH(value); + NEXTOPARG(); + next_instr++; + value = frame->f_localsplus[oparg]; + Py_INCREF(value); + PUSH(value); + DISPATCH(); + } +``` + +### Input stack effect and cache effect +```C + op ( CHECK_OBJECT_TYPE, (owner, type_version/2 -- owner) ) { + PyTypeObject *tp = Py_TYPE(owner); + assert(type_version != 0); + DEOPT_IF(tp->tp_version_tag != type_version); + } +``` +This might become (if it was an instruction): +```C + TARGET(CHECK_OBJECT_TYPE) { + PyObject *owner = PEEK(1); + uint32 type_version = read32(next_instr); + PyTypeObject *tp = Py_TYPE(owner); + assert(type_version != 0); + DEOPT_IF(tp->tp_version_tag != type_version); + next_instr += 2; + DISPATCH(); + } +``` + +### More examples + +For explanations see "Generating the interpreter" below.) +```C + op ( CHECK_HAS_INSTANCE_VALUES, (owner -- owner) ) { + PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); + DEOPT_IF(!_PyDictOrValues_IsValues(dorv)); + } +``` +```C + op ( LOAD_INSTANCE_VALUE, (owner, index/1 -- null if (oparg & 1), res) ) { + res = _PyDictOrValues_GetValues(dorv)->values[index]; + DEOPT_IF(res == NULL); + Py_INCREF(res); + null = NULL; + Py_DECREF(owner); + } +``` +```C + macro ( LOAD_ATTR_INSTANCE_VALUE ) = + counter/1 + CHECK_OBJECT_TYPE + CHECK_HAS_INSTANCE_VALUES + + LOAD_INSTANCE_VALUE + unused/4 ; +``` +```C + op ( LOAD_SLOT, (owner, index/1 -- null if (oparg & 1), res) ) { + char *addr = (char *)owner + index; + res = *(PyObject **)addr; + DEOPT_IF(res == NULL); + Py_INCREF(res); + null = NULL; + Py_DECREF(owner); + } +``` +```C + macro ( LOAD_ATTR_SLOT ) = counter/1 + CHECK_OBJECT_TYPE + LOAD_SLOT + unused/4; +``` +```C + inst ( BUILD_TUPLE, (items[oparg] -- tuple) ) { + tuple = _PyTuple_FromArraySteal(items, oparg); + ERROR_IF(tuple == NULL, error); + } +``` +```C + inst ( PRINT_EXPR ) { + PyObject *value = POP(); + PyObject *hook = _PySys_GetAttr(tstate, &_Py_ID(displayhook)); + PyObject *res; + if (hook == NULL) { + _PyErr_SetString(tstate, PyExc_RuntimeError, + "lost sys.displayhook"); + Py_DECREF(value); + goto error; + } + res = PyObject_CallOneArg(hook, value); + Py_DECREF(value); + ERROR_IF(res == NULL); + Py_DECREF(res); + } +``` + +### Define an instruction family +These opcodes all share the same instruction format): +```C + family(load_attr) = { LOAD_ATTR, LOAD_ATTR_INSTANCE_VALUE, LOAD_SLOT } ; +``` + +Generating the interpreter +========================== + +The generated C code for a single instruction includes a preamble and dispatch at the end +which can be easily inserted. What is more complex is ensuring the correct stack effects +and not generating excess pops and pushes. + +For example, in `CHECK_HAS_INSTANCE_VALUES`, `owner` occurs in the input, so it cannot be +redefined. Thus it doesn't need to written and can be read without adjusting the stack pointer. +The C code generated for `CHECK_HAS_INSTANCE_VALUES` would look something like: + +```C + { + PyObject *owner = stack_pointer[-1]; + PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner); + DEOPT_IF(!_PyDictOrValues_IsValues(dorv)); + } +``` + +When combining ops together to form instructions, temporary values should be used, +rather than popping and pushing, such that `LOAD_ATTR_SLOT` would look something like: + +```C + case LOAD_ATTR_SLOT: { + PyObject *s1 = stack_pointer[-1]; + /* CHECK_OBJECT_TYPE */ + { + PyObject *owner = s1; + uint32_t type_version = read32(next_instr + 1); + PyTypeObject *tp = Py_TYPE(owner); + assert(type_version != 0); + if (tp->tp_version_tag != type_version) goto deopt; + } + /* LOAD_SLOT */ + { + PyObject *owner = s1; + uint16_t index = *(next_instr + 1 + 2); + char *addr = (char *)owner + index; + PyObject *null; + PyObject *res = *(PyObject **)addr; + if (res == NULL) goto deopt; + Py_INCREF(res); + null = NULL; + Py_DECREF(owner); + if (oparg & 1) { + stack_pointer[0] = null; + stack_pointer += 1; + } + s1 = res; + } + next_instr += (1 + 1 + 2 + 1 + 4); + stack_pointer[-1] = s1; + DISPATCH(); + } +``` + +Other tools +=========== + +From the instruction definitions we can generate the stack marking code used in `frame.set_lineno()`, +and the tables for use by disassemblers. + diff --git a/Tools/cases_generator/lexer.py b/Tools/cases_generator/lexer.py new file mode 100644 index 00000000..1c70d1c4 --- /dev/null +++ b/Tools/cases_generator/lexer.py @@ -0,0 +1,262 @@ +# Parser for C code +# Originally by Mark Shannon (mark@hotpy.org) +# https://gist.github.com/markshannon/db7ab649440b5af765451bb77c7dba34 + +import re +import sys +import collections +from dataclasses import dataclass + +def choice(*opts): + return "|".join("(%s)" % opt for opt in opts) + +# Regexes + +# Longer operators must go before shorter ones. + +PLUSPLUS = r'\+\+' +MINUSMINUS = r'--' + +# -> +ARROW = r'->' +ELLIPSIS = r'\.\.\.' + +# Assignment operators +TIMESEQUAL = r'\*=' +DIVEQUAL = r'/=' +MODEQUAL = r'%=' +PLUSEQUAL = r'\+=' +MINUSEQUAL = r'-=' +LSHIFTEQUAL = r'<<=' +RSHIFTEQUAL = r'>>=' +ANDEQUAL = r'&=' +OREQUAL = r'\|=' +XOREQUAL = r'\^=' + +# Operators +PLUS = r'\+' +MINUS = r'-' +TIMES = r'\*' +DIVIDE = r'/' +MOD = r'%' +NOT = r'~' +XOR = r'\^' +LOR = r'\|\|' +LAND = r'&&' +LSHIFT = r'<<' +RSHIFT = r'>>' +LE = r'<=' +GE = r'>=' +EQ = r'==' +NE = r'!=' +LT = r'<' +GT = r'>' +LNOT = r'!' +OR = r'\|' +AND = r'&' +EQUALS = r'=' + +# ? +CONDOP = r'\?' + +# Delimiters +LPAREN = r'\(' +RPAREN = r'\)' +LBRACKET = r'\[' +RBRACKET = r'\]' +LBRACE = r'\{' +RBRACE = r'\}' +COMMA = r',' +PERIOD = r'\.' +SEMI = r';' +COLON = r':' +BACKSLASH = r'\\' + +operators = { op: pattern for op, pattern in globals().items() if op == op.upper() } +for op in operators: + globals()[op] = op +opmap = { pattern.replace("\\", "") or '\\' : op for op, pattern in operators.items() } + +# Macros +macro = r'# *(ifdef|ifndef|undef|define|error|endif|if|else|include|#)' +MACRO = 'MACRO' + +id_re = r'[a-zA-Z_][0-9a-zA-Z_]*' +IDENTIFIER = 'IDENTIFIER' + +suffix = r'([uU]?[lL]?[lL]?)' +octal = r'0[0-7]+' + suffix +hex = r'0[xX][0-9a-fA-F]+' +decimal_digits = r'(0|[1-9][0-9]*)' +decimal = decimal_digits + suffix + + +exponent = r"""([eE][-+]?[0-9]+)""" +fraction = r"""([0-9]*\.[0-9]+)|([0-9]+\.)""" +float = '(((('+fraction+')'+exponent+'?)|([0-9]+'+exponent+'))[FfLl]?)' + +number_re = choice(octal, hex, float, decimal) +NUMBER = 'NUMBER' + +simple_escape = r"""([a-zA-Z._~!=&\^\-\\?'"])""" +decimal_escape = r"""(\d+)""" +hex_escape = r"""(x[0-9a-fA-F]+)""" +escape_sequence = r"""(\\("""+simple_escape+'|'+decimal_escape+'|'+hex_escape+'))' +string_char = r"""([^"\\\n]|"""+escape_sequence+')' +str_re = '"'+string_char+'*"' +STRING = 'STRING' +char = r'\'.\'' # TODO: escape sequence +CHARACTER = 'CHARACTER' + +comment_re = r'//.*|/\*([^*]|\*[^/])*\*/' +COMMENT = 'COMMENT' + +newline = r"\n" +invalid = r"\S" # A single non-space character that's not caught by any of the other patterns +matcher = re.compile(choice(id_re, number_re, str_re, char, newline, macro, comment_re, *operators.values(), invalid)) +letter = re.compile(r'[a-zA-Z_]') + +kwds = ( + 'AUTO', 'BREAK', 'CASE', 'CHAR', 'CONST', + 'CONTINUE', 'DEFAULT', 'DO', 'DOUBLE', 'ELSE', 'ENUM', 'EXTERN', + 'FLOAT', 'FOR', 'GOTO', 'IF', 'INLINE', 'INT', 'LONG', 'OVERRIDE', + 'REGISTER', 'OFFSETOF', + 'RESTRICT', 'RETURN', 'SHORT', 'SIGNED', 'SIZEOF', 'STATIC', 'STRUCT', + 'SWITCH', 'TYPEDEF', 'UNION', 'UNSIGNED', 'VOID', + 'VOLATILE', 'WHILE' +) +for name in kwds: + globals()[name] = name +keywords = { name.lower() : name for name in kwds } + + +def make_syntax_error( + message: str, filename: str, line: int, column: int, line_text: str, +) -> SyntaxError: + return SyntaxError(message, (filename, line, column, line_text)) + + +@dataclass(slots=True) +class Token: + kind: str + text: str + begin: tuple[int, int] + end: tuple[int, int] + + @property + def line(self): + return self.begin[0] + + @property + def column(self): + return self.begin[1] + + @property + def end_line(self): + return self.end[0] + + @property + def end_column(self): + return self.end[1] + + @property + def width(self): + return self.end[1] - self.begin[1] + + def replaceText(self, txt): + assert isinstance(txt, str) + return Token(self.kind, txt, self.begin, self.end) + + def __repr__(self): + b0, b1 = self.begin + e0, e1 = self.end + if b0 == e0: + return f"{self.kind}({self.text!r}, {b0}:{b1}:{e1})" + else: + return f"{self.kind}({self.text!r}, {b0}:{b1}, {e0}:{e1})" + + +def tokenize(src, line=1, filename=None): + linestart = -1 + for m in matcher.finditer(src): + start, end = m.span() + text = m.group(0) + if text in keywords: + kind = keywords[text] + elif letter.match(text): + kind = IDENTIFIER + elif text == '...': + kind = ELLIPSIS + elif text == '.': + kind = PERIOD + elif text[0] in '0123456789.': + kind = NUMBER + elif text[0] == '"': + kind = STRING + elif text in opmap: + kind = opmap[text] + elif text == '\n': + linestart = start + line += 1 + kind = '\n' + elif text[0] == "'": + kind = CHARACTER + elif text[0] == '#': + kind = MACRO + elif text[0] == '/' and text[1] in '/*': + kind = COMMENT + else: + lineend = src.find("\n", start) + if lineend == -1: + lineend = len(src) + raise make_syntax_error(f"Bad token: {text}", + filename, line, start-linestart+1, src[linestart:lineend]) + if kind == COMMENT: + begin = line, start-linestart + newlines = text.count('\n') + if newlines: + linestart = start + text.rfind('\n') + line += newlines + else: + begin = line, start-linestart + if kind != "\n": + yield Token(kind, text, begin, (line, start-linestart+len(text))) + + +__all__ = [] +__all__.extend([kind for kind in globals() if kind.upper() == kind]) + + +def to_text(tkns: list[Token], dedent: int = 0) -> str: + res: list[str] = [] + line, col = -1, 1+dedent + for tkn in tkns: + if line == -1: + line, _ = tkn.begin + l, c = tkn.begin + #assert(l >= line), (line, txt, start, end) + while l > line: + line += 1 + res.append('\n') + col = 1+dedent + res.append(' '*(c-col)) + text = tkn.text + if dedent != 0 and tkn.kind == 'COMMENT' and '\n' in text: + if dedent < 0: + text = text.replace('\n', '\n' + ' '*-dedent) + # TODO: dedent > 0 + res.append(text) + line, col = tkn.end + return ''.join(res) + + +if __name__ == "__main__": + import sys + filename = sys.argv[1] + if filename == "-c": + src = sys.argv[2] + else: + src = open(filename).read() + # print(to_text(tokenize(src))) + for tkn in tokenize(src, filename=filename): + print(tkn) diff --git a/Tools/cases_generator/parser.py b/Tools/cases_generator/parser.py new file mode 100644 index 00000000..7bf45a35 --- /dev/null +++ b/Tools/cases_generator/parser.py @@ -0,0 +1,422 @@ +"""Parser for bytecodes.inst.""" + +from dataclasses import dataclass, field +from typing import NamedTuple, Callable, TypeVar, Literal + +import lexer as lx +from plexer import PLexer + + +P = TypeVar("P", bound="Parser") +N = TypeVar("N", bound="Node") + + +def contextual(func: Callable[[P], N | None]) -> Callable[[P], N | None]: + # Decorator to wrap grammar methods. + # Resets position if `func` returns None. + def contextual_wrapper(self: P) -> N | None: + begin = self.getpos() + res = func(self) + if res is None: + self.setpos(begin) + return + end = self.getpos() + res.context = Context(begin, end, self) + return res + + return contextual_wrapper + + +class Context(NamedTuple): + begin: int + end: int + owner: PLexer + + def __repr__(self): + return f"<{self.owner.filename}: {self.begin}-{self.end}>" + + +@dataclass +class Node: + context: Context | None = field(init=False, compare=False, default=None) + + @property + def text(self) -> str: + return self.to_text() + + def to_text(self, dedent: int = 0) -> str: + context = self.context + if not context: + return "" + return lx.to_text(self.tokens, dedent) + + @property + def tokens(self) -> list[lx.Token]: + context = self.context + if not context: + return [] + tokens = context.owner.tokens + begin = context.begin + end = context.end + return tokens[begin:end] + + +@dataclass +class Block(Node): + # This just holds a context which has the list of tokens. + pass + + +@dataclass +class StackEffect(Node): + name: str + type: str = "" # Optional `:type` + cond: str = "" # Optional `if (cond)` + size: str = "" # Optional `[size]` + # Note: size cannot be combined with type or cond + + +@dataclass +class Expression(Node): + size: str + + +@dataclass +class CacheEffect(Node): + name: str + size: int + + +@dataclass +class OpName(Node): + name: str + + +InputEffect = StackEffect | CacheEffect +OutputEffect = StackEffect +UOp = OpName | CacheEffect + + +@dataclass +class InstHeader(Node): + override: bool + register: bool + kind: Literal["inst", "op", "legacy"] # Legacy means no (inputs -- outputs) + name: str + inputs: list[InputEffect] + outputs: list[OutputEffect] + + +@dataclass +class InstDef(Node): + override: bool + register: bool + kind: Literal["inst", "op", "legacy"] + name: str + inputs: list[InputEffect] + outputs: list[OutputEffect] + block: Block + + +@dataclass +class Super(Node): + name: str + ops: list[OpName] + + +@dataclass +class Macro(Node): + name: str + uops: list[UOp] + + +@dataclass +class Family(Node): + name: str + size: str # Variable giving the cache size in code units + members: list[str] + + +class Parser(PLexer): + @contextual + def definition(self) -> InstDef | Super | Macro | Family | None: + if inst := self.inst_def(): + return inst + if super := self.super_def(): + return super + if macro := self.macro_def(): + return macro + if family := self.family_def(): + return family + + @contextual + def inst_def(self) -> InstDef | None: + if hdr := self.inst_header(): + if block := self.block(): + return InstDef( + hdr.override, hdr.register, hdr.kind, hdr.name, hdr.inputs, hdr.outputs, block + ) + raise self.make_syntax_error("Expected block") + return None + + @contextual + def inst_header(self) -> InstHeader | None: + # [override] inst(NAME) + # | [override] [register] inst(NAME, (inputs -- outputs)) + # | [override] [register] op(NAME, (inputs -- outputs)) + # TODO: Make INST a keyword in the lexer. + override = bool(self.expect(lx.OVERRIDE)) + register = bool(self.expect(lx.REGISTER)) + if (tkn := self.expect(lx.IDENTIFIER)) and (kind := tkn.text) in ("inst", "op"): + if self.expect(lx.LPAREN) and (tkn := self.expect(lx.IDENTIFIER)): + name = tkn.text + if self.expect(lx.COMMA): + inp, outp = self.io_effect() + if self.expect(lx.RPAREN): + if (tkn := self.peek()) and tkn.kind == lx.LBRACE: + return InstHeader(override, register, kind, name, inp, outp) + elif self.expect(lx.RPAREN) and kind == "inst": + # No legacy stack effect if kind is "op". + return InstHeader(override, register, "legacy", name, [], []) + return None + + def io_effect(self) -> tuple[list[InputEffect], list[OutputEffect]]: + # '(' [inputs] '--' [outputs] ')' + if self.expect(lx.LPAREN): + inputs = self.inputs() or [] + if self.expect(lx.MINUSMINUS): + outputs = self.outputs() or [] + if self.expect(lx.RPAREN): + return inputs, outputs + raise self.make_syntax_error("Expected stack effect") + + def inputs(self) -> list[InputEffect] | None: + # input (',' input)* + here = self.getpos() + if inp := self.input(): + near = self.getpos() + if self.expect(lx.COMMA): + if rest := self.inputs(): + return [inp] + rest + self.setpos(near) + return [inp] + self.setpos(here) + return None + + @contextual + def input(self) -> InputEffect | None: + return self.cache_effect() or self.stack_effect() + + def outputs(self) -> list[OutputEffect] | None: + # output (, output)* + here = self.getpos() + if outp := self.output(): + near = self.getpos() + if self.expect(lx.COMMA): + if rest := self.outputs(): + return [outp] + rest + self.setpos(near) + return [outp] + self.setpos(here) + return None + + @contextual + def output(self) -> OutputEffect | None: + return self.stack_effect() + + @contextual + def cache_effect(self) -> CacheEffect | None: + # IDENTIFIER '/' NUMBER + if tkn := self.expect(lx.IDENTIFIER): + if self.expect(lx.DIVIDE): + num = self.require(lx.NUMBER).text + try: + size = int(num) + except ValueError: + raise self.make_syntax_error(f"Expected integer, got {num!r}") + else: + return CacheEffect(tkn.text, size) + + @contextual + def stack_effect(self) -> StackEffect | None: + # IDENTIFIER [':' IDENTIFIER] ['if' '(' expression ')'] + # | IDENTIFIER '[' expression ']' + if tkn := self.expect(lx.IDENTIFIER): + type_text = "" + if self.expect(lx.COLON): + type_text = self.require(lx.IDENTIFIER).text.strip() + cond_text = "" + if self.expect(lx.IF): + self.require(lx.LPAREN) + if not (cond := self.expression()): + raise self.make_syntax_error("Expected condition") + self.require(lx.RPAREN) + cond_text = cond.text.strip() + size_text = "" + if self.expect(lx.LBRACKET): + if type_text or cond_text: + raise self.make_syntax_error("Unexpected [") + if not (size := self.expression()): + raise self.make_syntax_error("Expected expression") + self.require(lx.RBRACKET) + type_text = "PyObject **" + size_text = size.text.strip() + return StackEffect(tkn.text, type_text, cond_text, size_text) + + @contextual + def expression(self) -> Expression | None: + tokens: list[lx.Token] = [] + level = 1 + while tkn := self.peek(): + if tkn.kind in (lx.LBRACKET, lx.LPAREN): + level += 1 + elif tkn.kind in (lx.RBRACKET, lx.RPAREN): + level -= 1 + if level == 0: + break + tokens.append(tkn) + self.next() + if not tokens: + return None + return Expression(lx.to_text(tokens).strip()) + + @contextual + def super_def(self) -> Super | None: + if (tkn := self.expect(lx.IDENTIFIER)) and tkn.text == "super": + if self.expect(lx.LPAREN): + if tkn := self.expect(lx.IDENTIFIER): + if self.expect(lx.RPAREN): + if self.expect(lx.EQUALS): + if ops := self.ops(): + self.require(lx.SEMI) + res = Super(tkn.text, ops) + return res + + def ops(self) -> list[OpName] | None: + if op := self.op(): + ops = [op] + while self.expect(lx.PLUS): + if op := self.op(): + ops.append(op) + return ops + + @contextual + def op(self) -> OpName | None: + if tkn := self.expect(lx.IDENTIFIER): + return OpName(tkn.text) + + @contextual + def macro_def(self) -> Macro | None: + if (tkn := self.expect(lx.IDENTIFIER)) and tkn.text == "macro": + if self.expect(lx.LPAREN): + if tkn := self.expect(lx.IDENTIFIER): + if self.expect(lx.RPAREN): + if self.expect(lx.EQUALS): + if uops := self.uops(): + self.require(lx.SEMI) + res = Macro(tkn.text, uops) + return res + + def uops(self) -> list[UOp] | None: + if uop := self.uop(): + uops = [uop] + while self.expect(lx.PLUS): + if uop := self.uop(): + uops.append(uop) + else: + raise self.make_syntax_error("Expected op name or cache effect") + return uops + + @contextual + def uop(self) -> UOp | None: + if tkn := self.expect(lx.IDENTIFIER): + if self.expect(lx.DIVIDE): + if num := self.expect(lx.NUMBER): + try: + size = int(num.text) + except ValueError: + raise self.make_syntax_error( + f"Expected integer, got {num.text!r}" + ) + else: + return CacheEffect(tkn.text, size) + raise self.make_syntax_error("Expected integer") + else: + return OpName(tkn.text) + + @contextual + def family_def(self) -> Family | None: + if (tkn := self.expect(lx.IDENTIFIER)) and tkn.text == "family": + size = None + if self.expect(lx.LPAREN): + if tkn := self.expect(lx.IDENTIFIER): + if self.expect(lx.COMMA): + if not (size := self.expect(lx.IDENTIFIER)): + raise self.make_syntax_error("Expected identifier") + if self.expect(lx.RPAREN): + if self.expect(lx.EQUALS): + if not self.expect(lx.LBRACE): + raise self.make_syntax_error("Expected {") + if members := self.members(): + if self.expect(lx.RBRACE) and self.expect(lx.SEMI): + return Family( + tkn.text, size.text if size else "", members + ) + return None + + def members(self) -> list[str] | None: + here = self.getpos() + if tkn := self.expect(lx.IDENTIFIER): + members = [tkn.text] + while self.expect(lx.COMMA): + if tkn := self.expect(lx.IDENTIFIER): + members.append(tkn.text) + else: + break + peek = self.peek() + if not peek or peek.kind != lx.RBRACE: + raise self.make_syntax_error("Expected comma or right paren") + return members + self.setpos(here) + return None + + @contextual + def block(self) -> Block | None: + if self.c_blob(): + return Block() + + def c_blob(self) -> list[lx.Token]: + tokens: list[lx.Token] = [] + level = 0 + while tkn := self.next(raw=True): + tokens.append(tkn) + if tkn.kind in (lx.LBRACE, lx.LPAREN, lx.LBRACKET): + level += 1 + elif tkn.kind in (lx.RBRACE, lx.RPAREN, lx.RBRACKET): + level -= 1 + if level <= 0: + break + return tokens + + +if __name__ == "__main__": + import sys + + if sys.argv[1:]: + filename = sys.argv[1] + if filename == "-c" and sys.argv[2:]: + src = sys.argv[2] + filename = "<string>" + else: + with open(filename) as f: + src = f.read() + srclines = src.splitlines() + begin = srclines.index("// BEGIN BYTECODES //") + end = srclines.index("// END BYTECODES //") + src = "\n".join(srclines[begin + 1 : end]) + else: + filename = "<default>" + src = "if (x) { x.foo; // comment\n}" + parser = Parser(src, filename) + x = parser.definition() + print(x) diff --git a/Tools/cases_generator/plexer.py b/Tools/cases_generator/plexer.py new file mode 100644 index 00000000..a73254ed --- /dev/null +++ b/Tools/cases_generator/plexer.py @@ -0,0 +1,105 @@ +import lexer as lx +Token = lx.Token + + +class PLexer: + def __init__(self, src: str, filename: str): + self.src = src + self.filename = filename + self.tokens = list(lx.tokenize(self.src, filename=filename)) + self.pos = 0 + + def getpos(self) -> int: + # Current position + return self.pos + + def eof(self) -> bool: + # Are we at EOF? + return self.pos >= len(self.tokens) + + def setpos(self, pos: int) -> None: + # Reset position + assert 0 <= pos <= len(self.tokens), (pos, len(self.tokens)) + self.pos = pos + + def backup(self) -> None: + # Back up position by 1 + assert self.pos > 0 + self.pos -= 1 + + def next(self, raw: bool = False) -> Token | None: + # Return next token and advance position; None if at EOF + # TODO: Return synthetic EOF token instead of None? + while self.pos < len(self.tokens): + tok = self.tokens[self.pos] + self.pos += 1 + if raw or tok.kind != "COMMENT": + return tok + return None + + def peek(self, raw: bool = False) -> Token | None: + # Return next token without advancing position + tok = self.next(raw=raw) + self.backup() + return tok + + def maybe(self, kind: str, raw: bool = False) -> Token | None: + # Return next token without advancing position if kind matches + tok = self.peek(raw=raw) + if tok and tok.kind == kind: + return tok + return None + + def expect(self, kind: str) -> Token | None: + # Return next token and advance position if kind matches + tkn = self.next() + if tkn is not None: + if tkn.kind == kind: + return tkn + self.backup() + return None + + def require(self, kind: str) -> Token: + # Return next token and advance position, requiring kind to match + tkn = self.next() + if tkn is not None and tkn.kind == kind: + return tkn + raise self.make_syntax_error(f"Expected {kind!r} but got {tkn and tkn.text!r}", tkn) + + def extract_line(self, lineno: int) -> str: + # Return source line `lineno` (1-based) + lines = self.src.splitlines() + if lineno > len(lines): + return "" + return lines[lineno - 1] + + def make_syntax_error(self, message: str, tkn: Token|None = None) -> SyntaxError: + # Construct a SyntaxError instance from message and token + if tkn is None: + tkn = self.peek() + if tkn is None: + tkn = self.tokens[-1] + return lx.make_syntax_error(message, + self.filename, tkn.line, tkn.column, self.extract_line(tkn.line)) + + +if __name__ == "__main__": + import sys + if sys.argv[1:]: + filename = sys.argv[1] + if filename == "-c" and sys.argv[2:]: + src = sys.argv[2] + filename = "<string>" + else: + with open(filename) as f: + src = f.read() + else: + filename = "<default>" + src = "if (x) { x.foo; // comment\n}" + p = PLexer(src, filename) + while not p.eof(): + tok = p.next(raw=True) + assert tok + left = repr(tok) + right = lx.to_text([tok]).rstrip() + print(f"{left:40.40} {right}") diff --git a/Tools/cases_generator/test_generator.py b/Tools/cases_generator/test_generator.py new file mode 100644 index 00000000..036094ac --- /dev/null +++ b/Tools/cases_generator/test_generator.py @@ -0,0 +1,529 @@ +# Sorry for using pytest, these tests are mostly just for me. +# Use pytest -vv for best results. + +import tempfile + +import generate_cases +from parser import StackEffect + + +def test_effect_sizes(): + input_effects = [ + x := StackEffect("x", "", "", ""), + y := StackEffect("y", "", "", "oparg"), + z := StackEffect("z", "", "", "oparg*2"), + ] + output_effects = [ + StackEffect("a", "", "", ""), + StackEffect("b", "", "", "oparg*4"), + StackEffect("c", "", "", ""), + ] + other_effects = [ + StackEffect("p", "", "", "oparg<<1"), + StackEffect("q", "", "", ""), + StackEffect("r", "", "", ""), + ] + assert generate_cases.effect_size(x) == (1, "") + assert generate_cases.effect_size(y) == (0, "oparg") + assert generate_cases.effect_size(z) == (0, "oparg*2") + + assert generate_cases.list_effect_size(input_effects) == (1, "oparg + oparg*2") + assert generate_cases.list_effect_size(output_effects) == (2, "oparg*4") + assert generate_cases.list_effect_size(other_effects) == (2, "(oparg<<1)") + + assert generate_cases.string_effect_size(generate_cases.list_effect_size(input_effects)) == "1 + oparg + oparg*2" + assert generate_cases.string_effect_size(generate_cases.list_effect_size(output_effects)) == "2 + oparg*4" + assert generate_cases.string_effect_size(generate_cases.list_effect_size(other_effects)) == "2 + (oparg<<1)" + + +def run_cases_test(input: str, expected: str): + temp_input = tempfile.NamedTemporaryFile("w+") + temp_input.write(generate_cases.BEGIN_MARKER) + temp_input.write(input) + temp_input.write(generate_cases.END_MARKER) + temp_input.flush() + temp_output = tempfile.NamedTemporaryFile("w+") + a = generate_cases.Analyzer(temp_input.name, temp_output.name) + a.parse() + a.analyze() + if a.errors: + raise RuntimeError(f"Found {a.errors} errors") + a.write_instructions() + temp_output.seek(0) + lines = temp_output.readlines() + while lines and lines[0].startswith("// "): + lines.pop(0) + actual = "".join(lines) + # if actual.rstrip() != expected.rstrip(): + # print("Actual:") + # print(actual) + # print("Expected:") + # print(expected) + # print("End") + assert actual.rstrip() == expected.rstrip() + +def test_legacy(): + input = """ + inst(OP) { + spam(); + } + """ + output = """ + TARGET(OP) { + spam(); + DISPATCH(); + } + """ + run_cases_test(input, output) + +def test_inst_no_args(): + input = """ + inst(OP, (--)) { + spam(); + } + """ + output = """ + TARGET(OP) { + spam(); + DISPATCH(); + } + """ + run_cases_test(input, output) + +def test_inst_one_pop(): + input = """ + inst(OP, (value --)) { + spam(); + } + """ + output = """ + TARGET(OP) { + PyObject *value = PEEK(1); + spam(); + STACK_SHRINK(1); + DISPATCH(); + } + """ + run_cases_test(input, output) + +def test_inst_one_push(): + input = """ + inst(OP, (-- res)) { + spam(); + } + """ + output = """ + TARGET(OP) { + PyObject *res; + spam(); + STACK_GROW(1); + POKE(1, res); + DISPATCH(); + } + """ + run_cases_test(input, output) + +def test_inst_one_push_one_pop(): + input = """ + inst(OP, (value -- res)) { + spam(); + } + """ + output = """ + TARGET(OP) { + PyObject *value = PEEK(1); + PyObject *res; + spam(); + POKE(1, res); + DISPATCH(); + } + """ + run_cases_test(input, output) + +def test_binary_op(): + input = """ + inst(OP, (left, right -- res)) { + spam(); + } + """ + output = """ + TARGET(OP) { + PyObject *right = PEEK(1); + PyObject *left = PEEK(2); + PyObject *res; + spam(); + STACK_SHRINK(1); + POKE(1, res); + DISPATCH(); + } + """ + run_cases_test(input, output) + +def test_overlap(): + input = """ + inst(OP, (left, right -- left, result)) { + spam(); + } + """ + output = """ + TARGET(OP) { + PyObject *right = PEEK(1); + PyObject *left = PEEK(2); + PyObject *result; + spam(); + POKE(1, result); + DISPATCH(); + } + """ + run_cases_test(input, output) + +def test_predictions_and_eval_breaker(): + input = """ + inst(OP1, (--)) { + } + inst(OP2, (--)) { + } + inst(OP3, (arg -- res)) { + DEOPT_IF(xxx, OP1); + PREDICT(OP2); + CHECK_EVAL_BREAKER(); + } + """ + output = """ + TARGET(OP1) { + PREDICTED(OP1); + DISPATCH(); + } + + TARGET(OP2) { + PREDICTED(OP2); + DISPATCH(); + } + + TARGET(OP3) { + PyObject *arg = PEEK(1); + PyObject *res; + DEOPT_IF(xxx, OP1); + POKE(1, res); + PREDICT(OP2); + CHECK_EVAL_BREAKER(); + DISPATCH(); + } + """ + run_cases_test(input, output) + +def test_error_if_plain(): + input = """ + inst(OP, (--)) { + ERROR_IF(cond, label); + } + """ + output = """ + TARGET(OP) { + if (cond) goto label; + DISPATCH(); + } + """ + run_cases_test(input, output) + +def test_error_if_plain_with_comment(): + input = """ + inst(OP, (--)) { + ERROR_IF(cond, label); // Comment is ok + } + """ + output = """ + TARGET(OP) { + if (cond) goto label; + DISPATCH(); + } + """ + run_cases_test(input, output) + +def test_error_if_pop(): + input = """ + inst(OP, (left, right -- res)) { + ERROR_IF(cond, label); + } + """ + output = """ + TARGET(OP) { + PyObject *right = PEEK(1); + PyObject *left = PEEK(2); + PyObject *res; + if (cond) goto pop_2_label; + STACK_SHRINK(1); + POKE(1, res); + DISPATCH(); + } + """ + run_cases_test(input, output) + +def test_cache_effect(): + input = """ + inst(OP, (counter/1, extra/2, value --)) { + } + """ + output = """ + TARGET(OP) { + PyObject *value = PEEK(1); + uint16_t counter = read_u16(&next_instr[0].cache); + uint32_t extra = read_u32(&next_instr[1].cache); + STACK_SHRINK(1); + JUMPBY(3); + DISPATCH(); + } + """ + run_cases_test(input, output) + +def test_suppress_dispatch(): + input = """ + inst(OP, (--)) { + goto somewhere; + } + """ + output = """ + TARGET(OP) { + goto somewhere; + } + """ + run_cases_test(input, output) + +def test_super_instruction(): + # TODO: Test cache effect + input = """ + inst(OP1, (counter/1, arg --)) { + op1(); + } + inst(OP2, (extra/2, arg --)) { + op2(); + } + super(OP) = OP1 + OP2; + """ + output = """ + TARGET(OP1) { + PyObject *arg = PEEK(1); + uint16_t counter = read_u16(&next_instr[0].cache); + op1(); + STACK_SHRINK(1); + JUMPBY(1); + DISPATCH(); + } + + TARGET(OP2) { + PyObject *arg = PEEK(1); + uint32_t extra = read_u32(&next_instr[0].cache); + op2(); + STACK_SHRINK(1); + JUMPBY(2); + DISPATCH(); + } + + TARGET(OP) { + PyObject *_tmp_1 = PEEK(1); + PyObject *_tmp_2 = PEEK(2); + { + PyObject *arg = _tmp_1; + uint16_t counter = read_u16(&next_instr[0].cache); + op1(); + } + JUMPBY(1); + NEXTOPARG(); + JUMPBY(1); + { + PyObject *arg = _tmp_2; + uint32_t extra = read_u32(&next_instr[0].cache); + op2(); + } + JUMPBY(2); + STACK_SHRINK(2); + DISPATCH(); + } + """ + run_cases_test(input, output) + +def test_macro_instruction(): + input = """ + inst(OP1, (counter/1, left, right -- left, right)) { + op1(left, right); + } + op(OP2, (extra/2, arg2, left, right -- res)) { + res = op2(arg2, left, right); + } + macro(OP) = OP1 + cache/2 + OP2; + inst(OP3, (unused/5, arg2, left, right -- res)) { + res = op3(arg2, left, right); + } + family(op, INLINE_CACHE_ENTRIES_OP) = { OP, OP3 }; + """ + output = """ + TARGET(OP1) { + PyObject *right = PEEK(1); + PyObject *left = PEEK(2); + uint16_t counter = read_u16(&next_instr[0].cache); + op1(left, right); + JUMPBY(1); + DISPATCH(); + } + + TARGET(OP) { + PyObject *_tmp_1 = PEEK(1); + PyObject *_tmp_2 = PEEK(2); + PyObject *_tmp_3 = PEEK(3); + { + PyObject *right = _tmp_1; + PyObject *left = _tmp_2; + uint16_t counter = read_u16(&next_instr[0].cache); + op1(left, right); + _tmp_2 = left; + _tmp_1 = right; + } + { + PyObject *right = _tmp_1; + PyObject *left = _tmp_2; + PyObject *arg2 = _tmp_3; + PyObject *res; + uint32_t extra = read_u32(&next_instr[3].cache); + res = op2(arg2, left, right); + _tmp_3 = res; + } + JUMPBY(5); + static_assert(INLINE_CACHE_ENTRIES_OP == 5, "incorrect cache size"); + STACK_SHRINK(2); + POKE(1, _tmp_3); + DISPATCH(); + } + + TARGET(OP3) { + PyObject *right = PEEK(1); + PyObject *left = PEEK(2); + PyObject *arg2 = PEEK(3); + PyObject *res; + res = op3(arg2, left, right); + STACK_SHRINK(2); + POKE(1, res); + JUMPBY(5); + DISPATCH(); + } + """ + run_cases_test(input, output) + +def test_array_input(): + input = """ + inst(OP, (below, values[oparg*2], above --)) { + spam(); + } + """ + output = """ + TARGET(OP) { + PyObject *above = PEEK(1); + PyObject **values = &PEEK(1 + oparg*2); + PyObject *below = PEEK(2 + oparg*2); + spam(); + STACK_SHRINK(oparg*2); + STACK_SHRINK(2); + DISPATCH(); + } + """ + run_cases_test(input, output) + +def test_array_output(): + input = """ + inst(OP, (unused, unused -- below, values[oparg*3], above)) { + spam(values, oparg); + } + """ + output = """ + TARGET(OP) { + PyObject *below; + PyObject **values = stack_pointer - (2) + 1; + PyObject *above; + spam(values, oparg); + STACK_GROW(oparg*3); + POKE(1, above); + POKE(2 + oparg*3, below); + DISPATCH(); + } + """ + run_cases_test(input, output) + +def test_array_input_output(): + input = """ + inst(OP, (values[oparg] -- values[oparg], above)) { + spam(values, oparg); + } + """ + output = """ + TARGET(OP) { + PyObject **values = &PEEK(oparg); + PyObject *above; + spam(values, oparg); + STACK_GROW(1); + POKE(1, above); + DISPATCH(); + } + """ + run_cases_test(input, output) + +def test_array_error_if(): + input = """ + inst(OP, (extra, values[oparg] --)) { + ERROR_IF(oparg == 0, somewhere); + } + """ + output = """ + TARGET(OP) { + PyObject **values = &PEEK(oparg); + PyObject *extra = PEEK(1 + oparg); + if (oparg == 0) { STACK_SHRINK(oparg); goto pop_1_somewhere; } + STACK_SHRINK(oparg); + STACK_SHRINK(1); + DISPATCH(); + } + """ + run_cases_test(input, output) + +def test_register(): + input = """ + register inst(OP, (counter/1, left, right -- result)) { + result = op(left, right); + } + """ + output = """ + TARGET(OP) { + PyObject *left = REG(oparg1); + PyObject *right = REG(oparg2); + PyObject *result; + uint16_t counter = read_u16(&next_instr[0].cache); + result = op(left, right); + Py_XSETREF(REG(oparg3), result); + JUMPBY(1); + DISPATCH(); + } + """ + run_cases_test(input, output) + +def test_cond_effect(): + input = """ + inst(OP, (aa, input if ((oparg & 1) == 1), cc -- xx, output if (oparg & 2), zz)) { + output = spam(oparg, input); + } + """ + output = """ + TARGET(OP) { + PyObject *cc = PEEK(1); + PyObject *input = ((oparg & 1) == 1) ? PEEK(1 + (((oparg & 1) == 1) ? 1 : 0)) : NULL; + PyObject *aa = PEEK(2 + (((oparg & 1) == 1) ? 1 : 0)); + PyObject *xx; + PyObject *output = NULL; + PyObject *zz; + output = spam(oparg, input); + STACK_SHRINK((((oparg & 1) == 1) ? 1 : 0)); + STACK_GROW(((oparg & 2) ? 1 : 0)); + POKE(1, zz); + if (oparg & 2) { POKE(1 + ((oparg & 2) ? 1 : 0), output); } + POKE(2 + ((oparg & 2) ? 1 : 0), xx); + DISPATCH(); + } + """ + run_cases_test(input, output) diff --git a/Tools/clinic/clinic.py b/Tools/clinic/clinic.py index 82e49192..fd394c92 100755 --- a/Tools/clinic/clinic.py +++ b/Tools/clinic/clinic.py @@ -7,10 +7,12 @@ import abc import ast +import builtins as bltns import collections import contextlib import copy import cpp +import enum import functools import hashlib import inspect @@ -22,13 +24,12 @@ import re import shlex import string import sys -import tempfile import textwrap import traceback -import types -from types import * -NoneType = type(None) +from collections.abc import Callable +from types import FunctionType, NoneType +from typing import Any, Final, NamedTuple, NoReturn, Literal, overload # TODO: # @@ -43,48 +44,67 @@ NoneType = type(None) version = '1' -NoneType = type(None) NO_VARARG = "PY_SSIZE_T_MAX" CLINIC_PREFIX = "__clinic_" -CLINIC_PREFIXED_ARGS = {"args"} +CLINIC_PREFIXED_ARGS = { + "_keywords", + "_parser", + "args", + "argsbuf", + "fastargs", + "kwargs", + "kwnames", + "nargs", + "noptargs", + "return_value", +} -class Unspecified: - def __repr__(self): - return '<Unspecified>' -unspecified = Unspecified() +class Sentinels(enum.Enum): + unspecified = "unspecified" + unknown = "unknown" + def __repr__(self) -> str: + return f"<{self.value.capitalize()}>" -class Null: - def __repr__(self): - return '<Null>' -NULL = Null() +unspecified: Final = Sentinels.unspecified +unknown: Final = Sentinels.unknown -class Unknown: - def __repr__(self): - return '<Unknown>' +# This one needs to be a distinct class, unlike the other two +class Null: + def __repr__(self) -> str: + return '<Null>' + -unknown = Unknown() +NULL = Null() sig_end_marker = '--' +Appender = Callable[[str], None] +Outputter = Callable[[], str] +TemplateDict = dict[str, str] -_text_accumulator_nt = collections.namedtuple("_text_accumulator", "text append output") +class _TextAccumulator(NamedTuple): + text: list[str] + append: Appender + output: Outputter -def _text_accumulator(): - text = [] +def _text_accumulator() -> _TextAccumulator: + text: list[str] = [] def output(): s = ''.join(text) text.clear() return s - return _text_accumulator_nt(text, text.append, output) + return _TextAccumulator(text, text.append, output) -text_accumulator_nt = collections.namedtuple("text_accumulator", "text append") +class TextAccumulator(NamedTuple): + append: Appender + output: Outputter -def text_accumulator(): +def text_accumulator() -> TextAccumulator: """ Creates a simple text accumulator / joiner. @@ -96,10 +116,30 @@ def text_accumulator(): empties the accumulator. """ text, append, output = _text_accumulator() - return text_accumulator_nt(append, output) - - -def warn_or_fail(fail=False, *args, filename=None, line_number=None): + return TextAccumulator(append, output) + +@overload +def warn_or_fail( + *args: object, + fail: Literal[True], + filename: str | None = None, + line_number: int | None = None, +) -> NoReturn: ... + +@overload +def warn_or_fail( + *args: object, + fail: Literal[False] = False, + filename: str | None = None, + line_number: int | None = None, +) -> None: ... + +def warn_or_fail( + *args: object, + fail: bool = False, + filename: str | None = None, + line_number: int | None = None, +) -> None: joined = " ".join([str(a) for a in args]) add, output = text_accumulator() if fail: @@ -122,14 +162,22 @@ def warn_or_fail(fail=False, *args, filename=None, line_number=None): sys.exit(-1) -def warn(*args, filename=None, line_number=None): - return warn_or_fail(False, *args, filename=filename, line_number=line_number) +def warn( + *args: object, + filename: str | None = None, + line_number: int | None = None, +) -> None: + return warn_or_fail(*args, filename=filename, line_number=line_number, fail=False) -def fail(*args, filename=None, line_number=None): - return warn_or_fail(True, *args, filename=filename, line_number=line_number) +def fail( + *args: object, + filename: str | None = None, + line_number: int | None = None, +) -> NoReturn: + warn_or_fail(*args, filename=filename, line_number=line_number, fail=True) -def quoted_for_c_string(s): +def quoted_for_c_string(s: str) -> str: for old, new in ( ('\\', '\\\\'), # must be first! ('"', '\\"'), @@ -138,13 +186,13 @@ def quoted_for_c_string(s): s = s.replace(old, new) return s -def c_repr(s): +def c_repr(s: str) -> str: return '"' + s + '"' is_legal_c_identifier = re.compile('^[A-Za-z_][A-Za-z0-9_]*$').match -def is_legal_py_identifier(s): +def is_legal_py_identifier(s: str) -> bool: return all(is_legal_c_identifier(field) for field in s.split('.')) # identifiers that are okay in Python but aren't a good idea in C. @@ -157,16 +205,16 @@ register return short signed sizeof static struct switch typedef typeof union unsigned void volatile while """.strip().split()) -def ensure_legal_c_identifier(s): +def ensure_legal_c_identifier(s: str) -> str: # for now, just complain if what we're given isn't legal if not is_legal_c_identifier(s): - fail("Illegal C identifier: {}".format(s)) + fail("Illegal C identifier:", s) # but if we picked a C keyword, pick something else if s in c_keywords: return s + "_value" return s -def rstrip_lines(s): +def rstrip_lines(s: str) -> str: text, add, output = _text_accumulator() for line in s.split('\n'): add(line.rstrip()) @@ -174,14 +222,14 @@ def rstrip_lines(s): text.pop() return output() -def format_escape(s): +def format_escape(s: str) -> str: # double up curly-braces, this string will be used # as part of a format_map() template later s = s.replace('{', '{{') s = s.replace('}', '}}') return s -def linear_format(s, **kwargs): +def linear_format(s: str, **kwargs: str) -> str: """ Perform str.format-like substitution, except: * The strings substituted must be on lines by @@ -225,7 +273,7 @@ def linear_format(s, **kwargs): return output()[:-1] -def indent_all_lines(s, prefix): +def indent_all_lines(s: str, prefix: str) -> str: """ Returns 's', with 'prefix' prepended to all lines. @@ -246,7 +294,7 @@ def indent_all_lines(s, prefix): final.append(last) return ''.join(final) -def suffix_all_lines(s, suffix): +def suffix_all_lines(s: str, suffix: str) -> str: """ Returns 's', with 'suffix' appended to all lines. @@ -266,7 +314,7 @@ def suffix_all_lines(s, suffix): return ''.join(final) -def version_splitter(s): +def version_splitter(s: str) -> tuple[int, ...]: """Splits a version string into a tuple of integers. The following ASCII characters are allowed, and employ @@ -276,9 +324,9 @@ def version_splitter(s): c -> -1 (This permits Python-style version strings such as "1.4b3".) """ - version = [] - accumulator = [] - def flush(): + version: list[int] = [] + accumulator: list[str] = [] + def flush() -> None: if not accumulator: raise ValueError('Unsupported version string: ' + repr(s)) version.append(int(''.join(accumulator))) @@ -297,7 +345,7 @@ def version_splitter(s): flush() return tuple(version) -def version_comparitor(version1, version2): +def version_comparitor(version1: str, version2: str) -> Literal[-1, 0, 1]: iterator = itertools.zip_longest(version_splitter(version1), version_splitter(version2), fillvalue=0) for i, (a, b) in enumerate(iterator): if a < b: @@ -348,6 +396,7 @@ class CRenderData: # you should check the _return_value for errors, and # "goto exit" if there are any. self.return_conversion = [] + self.converter_retval = "_return_value" # The C statements required to do some operations # after the end of parsing but before cleaning up. @@ -460,7 +509,7 @@ class PythonLanguage(Language): def permute_left_option_groups(l): """ - Given [1, 2, 3], should yield: + Given [(1,), (2,), (3,)], should yield: () (3,) (2, 3) @@ -475,7 +524,7 @@ def permute_left_option_groups(l): def permute_right_option_groups(l): """ - Given [1, 2, 3], should yield: + Given [(1,), (2,), (3,)], should yield: () (1,) (1, 2) @@ -499,10 +548,9 @@ def permute_optional_groups(left, required, right): If required is empty, left must also be empty. """ required = tuple(required) - result = [] - if not required: - assert not left + if left: + raise ValueError("required is empty but left is not") accumulator = [] counts = set() @@ -542,6 +590,65 @@ def normalize_snippet(s, *, indent=0): return s +def declare_parser(f, *, hasformat=False): + """ + Generates the code template for a static local PyArg_Parser variable, + with an initializer. For core code (incl. builtin modules) the + kwtuple field is also statically initialized. Otherwise + it is initialized at runtime. + """ + if hasformat: + fname = '' + format_ = '.format = "{format_units}:{name}",' + else: + fname = '.fname = "{name}",' + format_ = '' + + num_keywords = len([ + p for p in f.parameters.values() + if not p.is_positional_only() and not p.is_vararg() + ]) + if num_keywords == 0: + declarations = """ + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty) + #else + # define KWTUPLE NULL + #endif + """ + else: + declarations = """ + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS %d + static struct {{ + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + PyObject *ob_item[NUM_KEYWORDS]; + }} _kwtuple = {{ + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_item = {{ {keywords_py} }}, + }}; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + """ % num_keywords + + declarations += """ + static const char * const _keywords[] = {{{keywords_c} NULL}}; + static _PyArg_Parser _parser = {{ + .keywords = _keywords, + %s + .kwtuple = KWTUPLE, + }}; + #undef KWTUPLE + """ % (format_ or fname) + return normalize_snippet(declarations) + + def wrap_declarations(text, length=78): """ A simple-minded text wrapper for C function declarations. @@ -746,13 +853,11 @@ class CLanguage(Language): # parser_body_fields remembers the fields passed in to the # previous call to parser_body. this is used for an awful hack. parser_body_fields = () - parser_body_declarations = '' def parser_body(prototype, *fields, declarations=''): - nonlocal parser_body_fields, parser_body_declarations + nonlocal parser_body_fields add, output = text_accumulator() add(prototype) parser_body_fields = fields - parser_body_declarations = declarations fields = list(fields) fields.insert(0, normalize_snippet(""" @@ -886,7 +991,7 @@ class CLanguage(Language): argname_fmt = 'PyTuple_GET_ITEM(args, %d)' - left_args = "{} - {}".format(nargs, max_pos) + left_args = f"{nargs} - {max_pos}" max_args = NO_VARARG if (vararg != NO_VARARG) else max_pos parser_code = [normalize_snippet(""" if (!_PyArg_CheckPositional("{name}", %s, %d, %s)) {{ @@ -981,11 +1086,8 @@ class CLanguage(Language): flags = "METH_FASTCALL|METH_KEYWORDS" parser_prototype = parser_prototype_fastcall_keywords argname_fmt = 'args[%d]' - declarations = normalize_snippet(""" - static const char * const _keywords[] = {{{keywords} NULL}}; - static _PyArg_Parser _parser = {{NULL, _keywords, "{name}", 0}}; - PyObject *argsbuf[%s]; - """ % len(converters)) + declarations = declare_parser(f) + declarations += "\nPyObject *argsbuf[%s];" % len(converters) if has_optional_kw: declarations += "\nPy_ssize_t noptargs = %s + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - %d;" % (nargs, min_pos + min_kw_only) parser_code = [normalize_snippet(""" @@ -999,13 +1101,10 @@ class CLanguage(Language): flags = "METH_VARARGS|METH_KEYWORDS" parser_prototype = parser_prototype_keyword argname_fmt = 'fastargs[%d]' - declarations = normalize_snippet(""" - static const char * const _keywords[] = {{{keywords} NULL}}; - static _PyArg_Parser _parser = {{NULL, _keywords, "{name}", 0}}; - PyObject *argsbuf[%s]; - PyObject * const *fastargs; - Py_ssize_t nargs = PyTuple_GET_SIZE(args); - """ % len(converters)) + declarations = declare_parser(f) + declarations += "\nPyObject *argsbuf[%s];" % len(converters) + declarations += "\nPyObject * const *fastargs;" + declarations += "\nPy_ssize_t nargs = PyTuple_GET_SIZE(args);" if has_optional_kw: declarations += "\nPy_ssize_t noptargs = %s + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - %d;" % (nargs, min_pos + min_kw_only) parser_code = [normalize_snippet(""" @@ -1082,9 +1181,7 @@ class CLanguage(Language): if add_label: parser_code.append("%s:" % add_label) else: - declarations = ( - 'static const char * const _keywords[] = {{{keywords} NULL}};\n' - 'static _PyArg_Parser _parser = {{"{format_units}:{name}", _keywords, 0}};') + declarations = declare_parser(f, hasformat=True) if not new_or_init: parser_code = [normalize_snippet(""" if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser{parse_arguments_comma} @@ -1125,6 +1222,7 @@ class CLanguage(Language): raise ValueError("Slot methods cannot access their defining class.") if not parses_keywords: + declarations = '{base_type_ptr}' fields.insert(0, normalize_snippet(""" if ({self_type_check}!_PyArg_NoKeywords("{name}", kwargs)) {{ goto exit; @@ -1138,7 +1236,7 @@ class CLanguage(Language): """, indent=4)) parser_definition = parser_body(parser_prototype, *fields, - declarations=parser_body_declarations) + declarations=declarations) if flags in ('METH_NOARGS', 'METH_O', 'METH_VARARGS'): @@ -1238,7 +1336,6 @@ class CLanguage(Language): if isinstance(parameters[0].converter, self_converter): del parameters[0] - groups = [] group = None left = [] right = [] @@ -1328,8 +1425,6 @@ class CLanguage(Language): first_optional = len(selfless) positional = selfless and selfless[-1].is_positional_only() new_or_init = f.kind in (METHOD_NEW, METHOD_INIT) - default_return_converter = (not f.return_converter or - f.return_converter.type == 'PyObject *') has_option_groups = False # offset i by -1 because first_optional needs to ignore self @@ -1340,7 +1435,7 @@ class CLanguage(Language): first_optional = min(first_optional, i) if p.is_vararg(): - data.cleanup.append("Py_XDECREF({});".format(c.parser_name)) + data.cleanup.append(f"Py_XDECREF({c.parser_name});") # insert group variable group = p.group @@ -1392,8 +1487,7 @@ class CLanguage(Language): template_dict['c_basename'] = c_basename - methoddef_name = "{}_METHODDEF".format(c_basename.upper()) - template_dict['methoddef_name'] = methoddef_name + template_dict['methoddef_name'] = c_basename.upper() + "_METHODDEF" template_dict['docstring'] = self.docstring_for_c_string(f) @@ -1407,7 +1501,11 @@ class CLanguage(Language): template_dict['declarations'] = format_escape("\n".join(data.declarations)) template_dict['initializers'] = "\n\n".join(data.initializers) template_dict['modifications'] = '\n\n'.join(data.modifications) - template_dict['keywords'] = ' '.join('"' + k + '",' for k in data.keywords) + template_dict['keywords_c'] = ' '.join('"' + k + '",' + for k in data.keywords) + keywords = [k for k in data.keywords if k] + template_dict['keywords_py'] = ' '.join('&_Py_ID(' + k + '),' + for k in keywords) template_dict['format_units'] = ''.join(data.format_units) template_dict['parse_arguments'] = ', '.join(data.parse_arguments) if data.parse_arguments: @@ -1422,7 +1520,6 @@ class CLanguage(Language): template_dict['return_value'] = data.return_value # used by unpack tuple code generator - ignore_self = -1 if isinstance(converters[0], self_converter) else 0 unpack_min = first_optional unpack_max = len(selfless) template_dict['unpack_min'] = str(unpack_min) @@ -1643,7 +1740,7 @@ class BlockParser: # make sure to recognize stop line even if it # doesn't end with EOL (it could be the very end of the file) if line.startswith(stop_line): - remainder = line[len(stop_line):] + remainder = line.removeprefix(stop_line) if remainder and not remainder.isspace(): fail(f"Garbage after stop line: {remainder!r}") return True @@ -1661,7 +1758,7 @@ class BlockParser: if body_prefix: line = line.lstrip() assert line.startswith(body_prefix) - line = line[len(body_prefix):] + line = line.removeprefix(body_prefix) input_add(line) # consume output and checksum line, if present. @@ -1693,16 +1790,14 @@ class BlockParser: for field in shlex.split(arguments): name, equals, value = field.partition('=') if not equals: - fail("Mangled Argument Clinic marker line: {!r}".format(line)) + fail("Mangled Argument Clinic marker line:", repr(line)) d[name.strip()] = value.strip() if self.verify: if 'input' in d: checksum = d['output'] - input_checksum = d['input'] else: checksum = d['checksum'] - input_checksum = None computed = compute_checksum(output, len(checksum)) if checksum != computed: @@ -1727,7 +1822,7 @@ class BlockPrinter: self.language = language self.f = f or io.StringIO() - def print_block(self, block): + def print_block(self, block, *, core_includes=False): input = block.input output = block.output dsl_name = block.dsl_name @@ -1754,14 +1849,27 @@ class BlockPrinter: write(self.language.stop_line.format(dsl_name=dsl_name)) write("\n") + output = '' + if core_includes: + output += textwrap.dedent(""" + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + # include "pycore_gc.h" // PyGC_Head + # include "pycore_runtime.h" // _Py_ID() + #endif + + """) + input = ''.join(block.input) - output = ''.join(block.output) + output += ''.join(block.output) if output: if not output.endswith('\n'): output += '\n' write(output) - arguments="output={} input={}".format(compute_checksum(output, 16), compute_checksum(input, 16)) + arguments = "output={output} input={input}".format( + output=compute_checksum(output, 16), + input=compute_checksum(input, 16) + ) write(self.language.checksum_line.format(dsl_name=dsl_name, arguments=arguments)) write("\n") @@ -1798,7 +1906,7 @@ class BufferSeries: def clear(self): for ta in self._array: - ta._text.clear() + ta.text.clear() def dump(self): texts = [ta.output() for ta in self._array] @@ -1851,35 +1959,14 @@ class Destination: # maps strings to Language objects. # "languages" maps the name of the language ("C", "Python"). # "extensions" maps the file extension ("c", "py"). +LangDict = dict[str, Callable[[str], Language]] + languages = { 'C': CLanguage, 'Python': PythonLanguage } -extensions = { name: CLanguage for name in "c cc cpp cxx h hh hpp hxx".split() } +extensions: LangDict = { name: CLanguage for name in "c cc cpp cxx h hh hpp hxx".split() } extensions['py'] = PythonLanguage -# maps strings to callables. -# these callables must be of the form: -# def foo(name, default, *, ...) -# The callable may have any number of keyword-only parameters. -# The callable must return a CConverter object. -# The callable should not call builtins.print. -converters = {} - -# maps strings to callables. -# these callables follow the same rules as those for "converters" above. -# note however that they will never be called with keyword-only parameters. -legacy_converters = {} - - -# maps strings to callables. -# these callables must be of the form: -# def foo(*, ...) -# The callable may have any number of keyword-only parameters. -# The callable must return a CConverter object. -# The callable should not call builtins.print. -return_converters = {} - - -def write_file(filename, new_contents): +def write_file(filename: str, new_contents: str) -> None: try: with open(filename, 'r', encoding="utf-8") as fp: old_contents = fp.read() @@ -1889,12 +1976,10 @@ def write_file(filename, new_contents): return except FileNotFoundError: pass - # Atomic write using a temporary file and os.replace() filename_new = f"{filename}.new" with open(filename_new, "w", encoding="utf-8") as fp: fp.write(new_contents) - try: os.replace(filename_new, filename) except: @@ -1902,6 +1987,11 @@ def write_file(filename, new_contents): raise +ClassDict = dict[str, "Class"] +DestinationDict = dict[str, Destination] +ModuleDict = dict[str, "Module"] +ParserDict = dict[str, "DSLParser"] + clinic = None class Clinic: @@ -1948,23 +2038,30 @@ impl_definition block """ - def __init__(self, language, printer=None, *, verify=True, filename=None): + def __init__( + self, + language: CLanguage, + printer: BlockPrinter | None = None, + *, + verify: bool = True, + filename: str | None = None + ) -> None: # maps strings to Parser objects. # (instantiated from the "parsers" global.) - self.parsers = {} - self.language = language + self.parsers: ParserDict = {} + self.language: CLanguage = language if printer: fail("Custom printers are broken right now") self.printer = printer or BlockPrinter(language) self.verify = verify self.filename = filename - self.modules = collections.OrderedDict() - self.classes = collections.OrderedDict() - self.functions = [] + self.modules: ModuleDict = {} + self.classes: ClassDict = {} + self.functions: list[Function] = [] self.line_prefix = self.line_suffix = '' - self.destinations = {} + self.destinations: DestinationDict = {} self.add_destination("block", "buffer") self.add_destination("suppress", "suppress") self.add_destination("buffer", "buffer") @@ -1972,23 +2069,26 @@ impl_definition block self.add_destination("file", "file", "{dirname}/clinic/{basename}.h") d = self.get_destination_buffer - self.destination_buffers = collections.OrderedDict(( - ('cpp_if', d('file')), - ('docstring_prototype', d('suppress')), - ('docstring_definition', d('file')), - ('methoddef_define', d('file')), - ('impl_prototype', d('file')), - ('parser_prototype', d('suppress')), - ('parser_definition', d('file')), - ('cpp_endif', d('file')), - ('methoddef_ifndef', d('file', 1)), - ('impl_definition', d('block')), - )) - - self.destination_buffers_stack = [] - self.ifndef_symbols = set() - - self.presets = {} + self.destination_buffers = { + 'cpp_if': d('file'), + 'docstring_prototype': d('suppress'), + 'docstring_definition': d('file'), + 'methoddef_define': d('file'), + 'impl_prototype': d('file'), + 'parser_prototype': d('suppress'), + 'parser_definition': d('file'), + 'cpp_endif': d('file'), + 'methoddef_ifndef': d('file', 1), + 'impl_definition': d('block'), + } + + DestBufferType = dict[str, Callable[..., Any]] + DestBufferList = list[DestBufferType] + + self.destination_buffers_stack: DestBufferList = [] + self.ifndef_symbols: set[str] = set() + + self.presets: dict[str, dict[Any, Any]] = {} preset = None for line in self.presets_text.strip().split('\n'): line = line.strip() @@ -1996,7 +2096,7 @@ impl_definition block continue name, value, *options = line.split() if name == 'preset': - self.presets[value] = preset = collections.OrderedDict() + self.presets[value] = preset = {} continue if len(options): @@ -2016,18 +2116,27 @@ impl_definition block global clinic clinic = self - def add_destination(self, name, type, *args): + def add_destination( + self, + name: str, + type: str, + *args + ) -> None: if name in self.destinations: fail("Destination already exists: " + repr(name)) self.destinations[name] = Destination(name, type, self, *args) - def get_destination(self, name): + def get_destination(self, name: str) -> Destination: d = self.destinations.get(name) if not d: fail("Destination does not exist: " + repr(name)) return d - def get_destination_buffer(self, name, item=0): + def get_destination_buffer( + self, + name: str, + item: int = 0 + ): d = self.get_destination(name) return d.buffers[item] @@ -2038,7 +2147,7 @@ impl_definition block dsl_name = block.dsl_name if dsl_name: if dsl_name not in self.parsers: - assert dsl_name in parsers, "No parser to handle {!r} block.".format(dsl_name) + assert dsl_name in parsers, f"No parser to handle {dsl_name!r} block." self.parsers[dsl_name] = parsers[dsl_name](self) parser = self.parsers[dsl_name] try: @@ -2048,8 +2157,6 @@ impl_definition block traceback.format_exc().rstrip()) printer.print_block(block) - second_pass_replacements = {} - # these are destinations not buffers for name, destination in self.destinations.items(): if destination.type == 'suppress': @@ -2057,7 +2164,6 @@ impl_definition block output = destination.dump() if output: - block = Block("", dsl_name="clinic", output=output) if destination.type == 'buffer': @@ -2078,7 +2184,7 @@ impl_definition block "can't make directory {}!".format( destination.filename, dirname)) if self.verify: - with open(destination.filename, "rt") as f: + with open(destination.filename) as f: parser_2 = BlockParser(f.read(), language=self.language) blocks = list(parser_2) if (len(blocks) != 1) or (blocks[0].input != 'preserve\n'): @@ -2088,26 +2194,11 @@ impl_definition block block.input = 'preserve\n' printer_2 = BlockPrinter(self.language) - printer_2.print_block(block) + printer_2.print_block(block, core_includes=True) write_file(destination.filename, printer_2.f.getvalue()) continue - text = printer.f.getvalue() - - if second_pass_replacements: - printer_2 = BlockPrinter(self.language) - parser_2 = BlockParser(text, self.language) - changed = False - for block in parser_2: - if block.dsl_name: - for id, replacement in second_pass_replacements.items(): - if id in block.output: - changed = True - block.output = block.output.replace(id, replacement) - printer_2.print_block(block) - if changed: - text = printer_2.f.getvalue() - return text + return printer.f.getvalue() def _module_and_class(self, fields): @@ -2141,7 +2232,12 @@ impl_definition block return module, cls -def parse_file(filename, *, verify=True, output=None): +def parse_file( + filename: str, + *, + verify: bool = True, + output: str | None = None +) -> None: if not output: output = filename @@ -2154,7 +2250,7 @@ def parse_file(filename, *, verify=True, output=None): except KeyError: fail("Can't identify file type for file " + repr(filename)) - with open(filename, 'r', encoding="utf-8") as f: + with open(filename, encoding="utf-8") as f: raw = f.read() # exit quickly if there are no clinic markers in the file @@ -2162,13 +2258,17 @@ def parse_file(filename, *, verify=True, output=None): if not find_start_re.search(raw): return + assert isinstance(language, CLanguage) clinic = Clinic(language, verify=verify, filename=filename) cooked = clinic.parse(raw) write_file(output, cooked) -def compute_checksum(input, length=None): +def compute_checksum( + input: str | None, + length: int | None = None +) -> str: input = input or '' s = hashlib.sha1(input.encode('utf-8')).hexdigest() if length: @@ -2179,10 +2279,10 @@ def compute_checksum(input, length=None): class PythonParser: - def __init__(self, clinic): + def __init__(self, clinic: Clinic) -> None: pass - def parse(self, block): + def parse(self, block: Block) -> None: s = io.StringIO() with OverrideStdioWith(s): exec(block.input) @@ -2190,19 +2290,31 @@ class PythonParser: class Module: - def __init__(self, name, module=None): + def __init__( + self, + name: str, + module = None + ) -> None: self.name = name self.module = self.parent = module - self.modules = collections.OrderedDict() - self.classes = collections.OrderedDict() - self.functions = [] + self.modules: ModuleDict = {} + self.classes: ClassDict = {} + self.functions: list[Function] = [] - def __repr__(self): + def __repr__(self) -> str: return "<clinic.Module " + repr(self.name) + " at " + str(id(self)) + ">" + class Class: - def __init__(self, name, module=None, cls=None, typedef=None, type_object=None): + def __init__( + self, + name: str, + module: Module | None = None, + cls = None, + typedef: str | None = None, + type_object: str | None = None + ) -> None: self.name = name self.module = module self.cls = cls @@ -2210,13 +2322,14 @@ class Class: self.type_object = type_object self.parent = cls or module - self.classes = collections.OrderedDict() - self.functions = [] + self.classes: ClassDict = {} + self.functions: list[Function] = [] - def __repr__(self): + def __repr__(self) -> str: return "<clinic.Class " + repr(self.name) + " at " + str(id(self)) + ">" -unsupported_special_methods = set(""" + +unsupported_special_methods: set[str] = set(""" __abs__ __add__ @@ -2292,6 +2405,9 @@ INVALID, CALLABLE, STATIC_METHOD, CLASS_METHOD, METHOD_INIT, METHOD_NEW = """ INVALID, CALLABLE, STATIC_METHOD, CLASS_METHOD, METHOD_INIT, METHOD_NEW """.replace(",", "").strip().split() +ParamDict = dict[str, "Parameter"] +ReturnConverterType = Callable[..., "CReturnConverter"] + class Function: """ Mutable duck type for inspect.Function. @@ -2304,13 +2420,23 @@ class Function: (not docstring) or ((not docstring[0].isspace()) and (docstring.rstrip() == docstring)) """ - def __init__(self, parameters=None, *, name, - module, cls=None, c_basename=None, - full_name=None, - return_converter, return_annotation=inspect.Signature.empty, - docstring=None, kind=CALLABLE, coexist=False, - docstring_only=False): - self.parameters = parameters or collections.OrderedDict() + def __init__( + self, + parameters: ParamDict | None = None, + *, + name: str, + module: Module, + cls: Class | None = None, + c_basename: str | None = None, + full_name: str | None = None, + return_converter: ReturnConverterType, + return_annotation = inspect.Signature.empty, + docstring: str | None = None, + kind: str = CALLABLE, + coexist: bool = False, + docstring_only: bool = False + ) -> None: + self.parameters = parameters or {} self.return_annotation = return_annotation self.name = name self.full_name = full_name @@ -2343,7 +2469,7 @@ class Function: return self.__render_parameters__ @property - def methoddef_flags(self): + def methoddef_flags(self) -> str | None: if self.kind in (METHOD_INIT, METHOD_NEW): return None flags = [] @@ -2357,10 +2483,10 @@ class Function: flags.append('METH_COEXIST') return '|'.join(flags) - def __repr__(self): + def __repr__(self) -> str: return '<clinic.Function ' + self.name + '>' - def copy(self, **overrides): + def copy(self, **overrides) -> "Function": kwargs = { 'name': self.name, 'module': self.module, 'parameters': self.parameters, 'cls': self.cls, 'c_basename': self.c_basename, @@ -2371,12 +2497,10 @@ class Function: } kwargs.update(overrides) f = Function(**kwargs) - - parameters = collections.OrderedDict() - for name, value in f.parameters.items(): - value = value.copy(function=f) - parameters[name] = value - f.parameters = parameters + f.parameters = { + name: value.copy(function=f) + for name, value in f.parameters.items() + } return f @@ -2385,9 +2509,18 @@ class Parameter: Mutable duck type of inspect.Parameter. """ - def __init__(self, name, kind, *, default=inspect.Parameter.empty, - function, converter, annotation=inspect.Parameter.empty, - docstring=None, group=0): + def __init__( + self, + name: str, + kind: str, + *, + default = inspect.Parameter.empty, + function: Function, + converter: "CConverter", + annotation = inspect.Parameter.empty, + docstring: str | None = None, + group: int = 0 + ) -> None: self.name = name self.kind = kind self.default = default @@ -2397,22 +2530,22 @@ class Parameter: self.docstring = docstring or '' self.group = group - def __repr__(self): + def __repr__(self) -> str: return '<clinic.Parameter ' + self.name + '>' - def is_keyword_only(self): + def is_keyword_only(self) -> bool: return self.kind == inspect.Parameter.KEYWORD_ONLY - def is_positional_only(self): + def is_positional_only(self) -> bool: return self.kind == inspect.Parameter.POSITIONAL_ONLY - def is_vararg(self): + def is_vararg(self) -> bool: return self.kind == inspect.Parameter.VAR_POSITIONAL - def is_optional(self): + def is_optional(self) -> bool: return not self.is_vararg() and (self.default is not unspecified) - def copy(self, **overrides): + def copy(self, **overrides) -> "Parameter": kwargs = { 'name': self.name, 'kind': self.kind, 'default':self.default, 'function': self.function, 'converter': self.converter, 'annotation': self.annotation, @@ -2425,24 +2558,24 @@ class Parameter: kwargs['converter'] = converter return Parameter(**kwargs) - def get_displayname(self, i): + def get_displayname(self, i: int) -> str: if i == 0: return '"argument"' if not self.is_positional_only(): - return '''"argument '{}'"'''.format(self.name) + return f'"argument {self.name!r}"' else: - return '"argument {}"'.format(i) + return f'"argument {i}"' class LandMine: # try to access any - def __init__(self, message): + def __init__(self, message: str) -> None: self.__message__ = message - def __repr__(self): + def __repr__(self) -> str: return '<LandMine ' + repr(self.__message__) + ">" - def __getattribute__(self, name): + def __getattribute__(self, name: str): if name in ('__repr__', '__message__'): return super().__getattribute__(name) # raise RuntimeError(repr(name)) @@ -2454,7 +2587,7 @@ def add_c_converter(f, name=None): name = f.__name__ if not name.endswith('_converter'): return f - name = name[:-len('_converter')] + name = name.removesuffix('_converter') converters[name] = f return f @@ -2494,34 +2627,34 @@ class CConverter(metaclass=CConverterAutoRegister): """ # The C name to use for this variable. - name = None + name: str | None = None # The Python name to use for this variable. - py_name = None + py_name: str | None = None # The C type to use for this variable. # 'type' should be a Python string specifying the type, e.g. "int". # If this is a pointer type, the type string should end with ' *'. - type = None + type: str | None = None # The Python default value for this parameter, as a Python value. # Or the magic value "unspecified" if there is no default. # Or the magic value "unknown" if this value is a cannot be evaluated # at Argument-Clinic-preprocessing time (but is presumed to be valid # at runtime). - default = unspecified + default: object = unspecified # If not None, default must be isinstance() of this type. # (You can also specify a tuple of types.) - default_type = None + default_type: bltns.type[Any] | tuple[bltns.type[Any], ...] | None = None # "default" converted into a C value, as a string. # Or None if there is no default. - c_default = None + c_default: str | None = None # "default" converted into a Python value, as a string. # Or None if there is no default. - py_default = None + py_default: str | None = None # The default value used to initialize the C variable when # there is no default, but not specifying a default may @@ -2533,11 +2666,14 @@ class CConverter(metaclass=CConverterAutoRegister): # # This value is specified as a string. # Every non-abstract subclass should supply a valid value. - c_ignored_default = 'NULL' + c_ignored_default: str = 'NULL' + + # If true, wrap with Py_UNUSED. + unused = False # The C converter *function* to be used, if any. # (If this is not None, format_unit must be 'O&'.) - converter = None + converter: str | None = None # Should Argument Clinic add a '&' before the name of # the variable when passing it into the _impl function? @@ -2561,7 +2697,7 @@ class CConverter(metaclass=CConverterAutoRegister): # What encoding do we want for this variable? Only used # by format units starting with 'e'. - encoding = None + encoding: str | None = None # Should this object be required to be a subclass of a specific type? # If not None, should be a string representing a pointer to a @@ -2587,16 +2723,33 @@ class CConverter(metaclass=CConverterAutoRegister): signature_name = None # keep in sync with self_converter.__init__! - def __init__(self, name, py_name, function, default=unspecified, *, c_default=None, py_default=None, annotation=unspecified, **kwargs): + def __init__(self, + # Positional args: + name: str, + py_name: str, + function, + default: object = unspecified, + *, # Keyword only args: + c_default: str | None = None, + py_default: str | None = None, + annotation: str | Literal[Sentinels.unspecified] = unspecified, + unused: bool = False, + **kwargs + ): self.name = ensure_legal_c_identifier(name) self.py_name = py_name + self.unused = unused if default is not unspecified: - if self.default_type and not isinstance(default, (self.default_type, Unknown)): + if (self.default_type + and default is not unknown + and not isinstance(default, self.default_type) + ): if isinstance(self.default_type, type): types_str = self.default_type.__name__ else: - types_str = ', '.join((cls.__name__ for cls in self.default_type)) + names = [cls.__name__ for cls in self.default_type] + types_str = ', '.join(names) fail("{}: default value {!r} for field {} is not of type {}".format( self.__class__.__name__, default, name, types_str)) self.default = default @@ -2606,7 +2759,7 @@ class CConverter(metaclass=CConverterAutoRegister): if py_default: self.py_default = py_default - if annotation != unspecified: + if annotation is not unspecified: fail("The 'annotation' parameter is not currently permitted.") # this is deliberate, to prevent you from caching information @@ -2620,10 +2773,10 @@ class CConverter(metaclass=CConverterAutoRegister): def converter_init(self): pass - def is_optional(self): + def is_optional(self) -> bool: return (self.default is not unspecified) - def _render_self(self, parameter, data): + def _render_self(self, parameter: str, data: CRenderData) -> None: self.parameter = parameter name = self.parser_name @@ -2683,7 +2836,7 @@ class CConverter(metaclass=CConverterAutoRegister): if cleanup: data.cleanup.append('/* Cleanup for ' + name + ' */\n' + cleanup.rstrip() + "\n") - def render(self, parameter, data): + def render(self, parameter: str, data: CRenderData) -> None: """ parameter is a clinic.Parameter instance. data is a CRenderData instance. @@ -2736,6 +2889,8 @@ class CConverter(metaclass=CConverterAutoRegister): name = self.parser_name else: name = self.name + if self.unused: + name = f"Py_UNUSED({name})" prototype.append(name) return "".join(prototype) @@ -2757,7 +2912,7 @@ class CConverter(metaclass=CConverterAutoRegister): declaration.append(';') return "".join(declaration) - def initialize(self): + def initialize(self) -> str: """ The C statements required to set up this variable before parsing. Returns a string containing this code indented at column 0. @@ -2765,15 +2920,15 @@ class CConverter(metaclass=CConverterAutoRegister): """ return "" - def modify(self): + def modify(self) -> str: """ The C statements required to modify this variable after parsing. Returns a string containing this code indented at column 0. - If no initialization is necessary, returns an empty string. + If no modification is necessary, returns an empty string. """ return "" - def post_parsing(self): + def post_parsing(self) -> str: """ The C statements required to do some operations after the end of parsing but before cleaning up. Return a string containing this code indented at column 0. @@ -2781,7 +2936,7 @@ class CConverter(metaclass=CConverterAutoRegister): """ return "" - def cleanup(self): + def cleanup(self) -> str: """ The C statements required to clean up after this variable. Returns a string containing this code indented at column 0. @@ -2834,7 +2989,7 @@ class CConverter(metaclass=CConverterAutoRegister): """.format(argname=argname, paramname=self.parser_name, cast=cast) return None - def set_template_dict(self, template_dict): + def set_template_dict(self, template_dict: TemplateDict) -> None: pass @property @@ -2857,13 +3012,41 @@ type_checks = { } +ConverterType = Callable[..., CConverter] +ConverterDict = dict[str, ConverterType] + +# maps strings to callables. +# these callables must be of the form: +# def foo(name, default, *, ...) +# The callable may have any number of keyword-only parameters. +# The callable must return a CConverter object. +# The callable should not call builtins.print. +converters: ConverterDict = {} + +# maps strings to callables. +# these callables follow the same rules as those for "converters" above. +# note however that they will never be called with keyword-only parameters. +legacy_converters: ConverterDict = {} + +# maps strings to callables. +# these callables must be of the form: +# def foo(*, ...) +# The callable may have any number of keyword-only parameters. +# The callable must return a CReturnConverter object. +# The callable should not call builtins.print. +ReturnConverterDict = dict[str, ReturnConverterType] +return_converters: ReturnConverterDict = {} + +TypeSet = set[bltns.type[Any]] + + class bool_converter(CConverter): type = 'int' default_type = bool format_unit = 'p' c_ignored_default = '0' - def converter_init(self, *, accept={object}): + def converter_init(self, *, accept: TypeSet = {object}) -> None: if accept == {int}: self.format_unit = 'i' elif accept != {object}: @@ -2872,7 +3055,7 @@ class bool_converter(CConverter): self.default = bool(self.default) self.c_default = str(int(self.default)) - def parse_arg(self, argname, displayname): + def parse_arg(self, argname: str, displayname: str) -> str: if self.format_unit == 'i': return """ {paramname} = _PyLong_AsInt({argname}); @@ -2898,10 +3081,10 @@ class defining_class_converter(CConverter): format_unit = '' show_in_signature = False - def converter_init(self, *, type=None): + def converter_init(self, *, type=None) -> None: self.specified_type = type - def render(self, parameter, data): + def render(self, parameter, data) -> None: self._render_self(parameter, data) def set_template_dict(self, template_dict): @@ -2914,7 +3097,7 @@ class char_converter(CConverter): format_unit = 'c' c_ignored_default = "'\0'" - def converter_init(self): + def converter_init(self) -> None: if isinstance(self.default, self.default_type): if len(self.default) != 1: fail("char_converter: illegal default value " + repr(self.default)) @@ -2923,7 +3106,7 @@ class char_converter(CConverter): if self.c_default == '"\'"': self.c_default = r"'\''" - def parse_arg(self, argname, displayname): + def parse_arg(self, argname: str, displayname: str) -> str: if self.format_unit == 'c': return """ if (PyBytes_Check({argname}) && PyBytes_GET_SIZE({argname}) == 1) {{{{ @@ -2948,11 +3131,11 @@ class unsigned_char_converter(CConverter): format_unit = 'b' c_ignored_default = "'\0'" - def converter_init(self, *, bitwise=False): + def converter_init(self, *, bitwise: bool = False) -> None: if bitwise: self.format_unit = 'B' - def parse_arg(self, argname, displayname): + def parse_arg(self, argname: str, displayname: str) -> str: if self.format_unit == 'b': return """ {{{{ @@ -2997,7 +3180,7 @@ class short_converter(CConverter): format_unit = 'h' c_ignored_default = "0" - def parse_arg(self, argname, displayname): + def parse_arg(self, argname: str, displayname: str) -> str: if self.format_unit == 'h': return """ {{{{ @@ -3027,13 +3210,13 @@ class unsigned_short_converter(CConverter): default_type = int c_ignored_default = "0" - def converter_init(self, *, bitwise=False): + def converter_init(self, *, bitwise: bool = False) -> None: if bitwise: self.format_unit = 'H' else: self.converter = '_PyLong_UnsignedShort_Converter' - def parse_arg(self, argname, displayname): + def parse_arg(self, argname: str, displayname: str) -> str: if self.format_unit == 'H': return """ {paramname} = (unsigned short)PyLong_AsUnsignedLongMask({argname}); @@ -3050,7 +3233,7 @@ class int_converter(CConverter): format_unit = 'i' c_ignored_default = "0" - def converter_init(self, *, accept={int}, type=None): + def converter_init(self, *, accept: TypeSet = {int}, type=None) -> None: if accept == {str}: self.format_unit = 'C' elif accept != {int}: @@ -3058,7 +3241,7 @@ class int_converter(CConverter): if type is not None: self.type = type - def parse_arg(self, argname, displayname): + def parse_arg(self, argname: str, displayname: str) -> str: if self.format_unit == 'i': return """ {paramname} = _PyLong_AsInt({argname}); @@ -3089,13 +3272,13 @@ class unsigned_int_converter(CConverter): default_type = int c_ignored_default = "0" - def converter_init(self, *, bitwise=False): + def converter_init(self, *, bitwise: bool = False) -> None: if bitwise: self.format_unit = 'I' else: self.converter = '_PyLong_UnsignedInt_Converter' - def parse_arg(self, argname, displayname): + def parse_arg(self, argname: str, displayname: str) -> str: if self.format_unit == 'I': return """ {paramname} = (unsigned int)PyLong_AsUnsignedLongMask({argname}); @@ -3111,7 +3294,7 @@ class long_converter(CConverter): format_unit = 'l' c_ignored_default = "0" - def parse_arg(self, argname, displayname): + def parse_arg(self, argname: str, displayname: str) -> str: if self.format_unit == 'l': return """ {paramname} = PyLong_AsLong({argname}); @@ -3126,13 +3309,13 @@ class unsigned_long_converter(CConverter): default_type = int c_ignored_default = "0" - def converter_init(self, *, bitwise=False): + def converter_init(self, *, bitwise: bool = False) -> None: if bitwise: self.format_unit = 'k' else: self.converter = '_PyLong_UnsignedLong_Converter' - def parse_arg(self, argname, displayname): + def parse_arg(self, argname: str, displayname: str) -> str: if self.format_unit == 'k': return """ if (!PyLong_Check({argname})) {{{{ @@ -3150,7 +3333,7 @@ class long_long_converter(CConverter): format_unit = 'L' c_ignored_default = "0" - def parse_arg(self, argname, displayname): + def parse_arg(self, argname: str, displayname: str) -> str: if self.format_unit == 'L': return """ {paramname} = PyLong_AsLongLong({argname}); @@ -3165,13 +3348,13 @@ class unsigned_long_long_converter(CConverter): default_type = int c_ignored_default = "0" - def converter_init(self, *, bitwise=False): + def converter_init(self, *, bitwise: bool = False) -> None: if bitwise: self.format_unit = 'K' else: self.converter = '_PyLong_UnsignedLongLong_Converter' - def parse_arg(self, argname, displayname): + def parse_arg(self, argname: str, displayname: str) -> str: if self.format_unit == 'K': return """ if (!PyLong_Check({argname})) {{{{ @@ -3187,7 +3370,7 @@ class Py_ssize_t_converter(CConverter): type = 'Py_ssize_t' c_ignored_default = "0" - def converter_init(self, *, accept={int}): + def converter_init(self, *, accept: TypeSet = {int}) -> None: if accept == {int}: self.format_unit = 'n' self.default_type = int @@ -3196,7 +3379,7 @@ class Py_ssize_t_converter(CConverter): else: fail("Py_ssize_t_converter: illegal 'accept' argument " + repr(accept)) - def parse_arg(self, argname, displayname): + def parse_arg(self, argname: str, displayname: str) -> str: if self.format_unit == 'n': return """ {{{{ @@ -3218,7 +3401,7 @@ class Py_ssize_t_converter(CConverter): class slice_index_converter(CConverter): type = 'Py_ssize_t' - def converter_init(self, *, accept={int, NoneType}): + def converter_init(self, *, accept: TypeSet = {int, NoneType}) -> None: if accept == {int}: self.converter = '_PyEval_SliceIndexNotNone' elif accept == {int, NoneType}: @@ -3231,7 +3414,7 @@ class size_t_converter(CConverter): converter = '_PyLong_Size_t_Converter' c_ignored_default = "0" - def parse_arg(self, argname, displayname): + def parse_arg(self, argname: str, displayname: str) -> str: if self.format_unit == 'n': return """ {paramname} = PyNumber_AsSsize_t({argname}, PyExc_OverflowError); @@ -3246,7 +3429,7 @@ class fildes_converter(CConverter): type = 'int' converter = '_PyLong_FileDescriptor_Converter' - def _parse_arg(self, argname, displayname): + def _parse_arg(self, argname: str, displayname: str) -> str: return """ {paramname} = PyObject_AsFileDescriptor({argname}); if ({paramname} == -1) {{{{ @@ -3261,7 +3444,7 @@ class float_converter(CConverter): format_unit = 'f' c_ignored_default = "0.0" - def parse_arg(self, argname, displayname): + def parse_arg(self, argname: str, displayname: str) -> str: if self.format_unit == 'f': return """ if (PyFloat_CheckExact({argname})) {{{{ @@ -3283,7 +3466,7 @@ class double_converter(CConverter): format_unit = 'd' c_ignored_default = "0.0" - def parse_arg(self, argname, displayname): + def parse_arg(self, argname: str, displayname: str) -> str: if self.format_unit == 'd': return """ if (PyFloat_CheckExact({argname})) {{{{ @@ -3306,7 +3489,7 @@ class Py_complex_converter(CConverter): format_unit = 'D' c_ignored_default = "{0.0, 0.0}" - def parse_arg(self, argname, displayname): + def parse_arg(self, argname: str, displayname: str) -> str: if self.format_unit == 'D': return """ {paramname} = PyComplex_AsCComplex({argname}); @@ -3321,7 +3504,12 @@ class object_converter(CConverter): type = 'PyObject *' format_unit = 'O' - def converter_init(self, *, converter=None, type=None, subclass_of=None): + def converter_init( + self, *, + converter=None, + type=None, + subclass_of=None + ) -> None: if converter: if subclass_of: fail("object: Cannot pass in both 'converter' and 'subclass_of'") @@ -3350,14 +3538,20 @@ class robuffer: pass def str_converter_key(types, encoding, zeroes): return (frozenset(types), bool(encoding), bool(zeroes)) -str_converter_argument_map = {} +str_converter_argument_map: dict[str, str] = {} class str_converter(CConverter): type = 'const char *' default_type = (str, Null, NoneType) format_unit = 's' - def converter_init(self, *, accept={str}, encoding=None, zeroes=False): + def converter_init( + self, + *, + accept: TypeSet = {str}, + encoding: str | None = None, + zeroes: bool = False + ) -> None: key = str_converter_key(accept, encoding, zeroes) format_unit = str_converter_argument_map.get(key) @@ -3382,7 +3576,7 @@ class str_converter(CConverter): name = self.name return f"PyMem_FREE({name});\n" - def parse_arg(self, argname, displayname): + def parse_arg(self, argname: str, displayname: str) -> str: if self.format_unit == 's': return """ if (!PyUnicode_Check({argname})) {{{{ @@ -3435,7 +3629,14 @@ class str_converter(CConverter): # mapping from arguments to format unit *and* registers the # legacy C converter for that format unit. # -def r(format_unit, *, accept, encoding=False, zeroes=False): +ConverterKeywordDict = dict[str, TypeSet | bool] + +def r(format_unit: str, + *, + accept: TypeSet, + encoding: bool = False, + zeroes: bool = False +) -> None: if not encoding and format_unit != 's': # add the legacy c converters here too. # @@ -3445,7 +3646,7 @@ def r(format_unit, *, accept, encoding=False, zeroes=False): # # also don't add the converter for 's' because # the metaclass for CConverter adds it for us. - kwargs = {} + kwargs: ConverterKeywordDict = {} if accept != {str}: kwargs['accept'] = accept if zeroes: @@ -3477,7 +3678,7 @@ class PyBytesObject_converter(CConverter): format_unit = 'S' # accept = {bytes} - def parse_arg(self, argname, displayname): + def parse_arg(self, argname: str, displayname: str) -> str: if self.format_unit == 'S': return """ if (!PyBytes_Check({argname})) {{{{ @@ -3494,7 +3695,7 @@ class PyByteArrayObject_converter(CConverter): format_unit = 'Y' # accept = {bytearray} - def parse_arg(self, argname, displayname): + def parse_arg(self, argname: str, displayname: str) -> str: if self.format_unit == 'Y': return """ if (!PyByteArray_Check({argname})) {{{{ @@ -3511,7 +3712,7 @@ class unicode_converter(CConverter): default_type = (str, Null, NoneType) format_unit = 'U' - def parse_arg(self, argname, displayname): + def parse_arg(self, argname: str, displayname: str) -> str: if self.format_unit == 'U': return """ if (!PyUnicode_Check({argname})) {{{{ @@ -3534,7 +3735,11 @@ class Py_UNICODE_converter(CConverter): type = 'const Py_UNICODE *' default_type = (str, Null, NoneType) - def converter_init(self, *, accept={str}, zeroes=False): + def converter_init( + self, *, + accept: TypeSet = {str}, + zeroes: bool = False + ) -> None: format_unit = 'Z' if accept=={str, NoneType} else 'u' if zeroes: format_unit += '#' @@ -3553,12 +3758,10 @@ class Py_UNICODE_converter(CConverter): def cleanup(self): if not self.length: return """\ -#if !USE_UNICODE_WCHAR_CACHE PyMem_Free((void *){name}); -#endif /* USE_UNICODE_WCHAR_CACHE */ """.format(name=self.name) - def parse_arg(self, argname, argnum): + def parse_arg(self, argname: str, argnum: str) -> str: if not self.length: if self.accept == {str}: return """ @@ -3566,11 +3769,7 @@ PyMem_Free((void *){name}); _PyArg_BadArgument("{{name}}", {argnum}, "str", {argname}); goto exit; }}}} - #if USE_UNICODE_WCHAR_CACHE - {paramname} = _PyUnicode_AsUnicode({argname}); - #else /* USE_UNICODE_WCHAR_CACHE */ {paramname} = PyUnicode_AsWideCharString({argname}, NULL); - #endif /* USE_UNICODE_WCHAR_CACHE */ if ({paramname} == NULL) {{{{ goto exit; }}}} @@ -3581,11 +3780,7 @@ PyMem_Free((void *){name}); {paramname} = NULL; }}}} else if (PyUnicode_Check({argname})) {{{{ - #if USE_UNICODE_WCHAR_CACHE - {paramname} = _PyUnicode_AsUnicode({argname}); - #else /* USE_UNICODE_WCHAR_CACHE */ {paramname} = PyUnicode_AsWideCharString({argname}, NULL); - #endif /* USE_UNICODE_WCHAR_CACHE */ if ({paramname} == NULL) {{{{ goto exit; }}}} @@ -3606,7 +3801,7 @@ class Py_buffer_converter(CConverter): impl_by_reference = True c_ignored_default = "{NULL, NULL}" - def converter_init(self, *, accept={buffer}): + def converter_init(self, *, accept: TypeSet = {buffer}) -> None: if self.default not in (unspecified, None): fail("The only legal default value for Py_buffer is None.") @@ -3629,7 +3824,7 @@ class Py_buffer_converter(CConverter): name = self.name return "".join(["if (", name, ".obj) {\n PyBuffer_Release(&", name, ");\n}\n"]) - def parse_arg(self, argname, displayname): + def parse_arg(self, argname: str, displayname: str) -> str: if self.format_unit == 'y*': return """ if (PyObject_GetBuffer({argname}, &{paramname}, PyBUF_SIMPLE) != 0) {{{{ @@ -3678,7 +3873,7 @@ class Py_buffer_converter(CConverter): return super().parse_arg(argname, displayname) -def correct_name_for_self(f): +def correct_name_for_self(f) -> tuple[str, str]: if f.kind in (CALLABLE, METHOD_INIT): if f.cls: return "PyObject *", "self" @@ -3704,7 +3899,7 @@ class self_converter(CConverter): type = None format_unit = '' - def converter_init(self, *, type=None): + def converter_init(self, *, type=None) -> None: self.specified_type = type def pre_render(self): @@ -3786,37 +3981,46 @@ class self_converter(CConverter): cls = self.function.cls if ((kind in (METHOD_NEW, METHOD_INIT)) and cls and cls.typedef): - type_object = self.function.cls.type_object - prefix = (type_object[1:] + '.' if type_object[0] == '&' else - type_object + '->') if kind == METHOD_NEW: - type_check = ('({0} == {1} ||\n ' - ' {0}->tp_init == {2}tp_init)' - ).format(self.name, type_object, prefix) + type_check = ( + '({0} == base_tp || {0}->tp_init == base_tp->tp_init)' + ).format(self.name) else: - type_check = ('(Py_IS_TYPE({0}, {1}) ||\n ' - ' Py_TYPE({0})->tp_new == {2}tp_new)' - ).format(self.name, type_object, prefix) + type_check = ('(Py_IS_TYPE({0}, base_tp) ||\n ' + ' Py_TYPE({0})->tp_new == base_tp->tp_new)' + ).format(self.name) - line = '{} &&\n '.format(type_check) + line = f'{type_check} &&\n ' template_dict['self_type_check'] = line + type_object = self.function.cls.type_object + type_ptr = f'PyTypeObject *base_tp = {type_object};' + template_dict['base_type_ptr'] = type_ptr -def add_c_return_converter(f, name=None): +def add_c_return_converter( + f: ReturnConverterType, + name: str | None = None +) -> ReturnConverterType: if not name: name = f.__name__ if not name.endswith('_return_converter'): return f - name = name[:-len('_return_converter')] + name = name.removesuffix('_return_converter') return_converters[name] = f return f class CReturnConverterAutoRegister(type): - def __init__(cls, name, bases, classdict): + def __init__( + cls: ReturnConverterType, + name: str, + bases: tuple[type, ...], + classdict: dict[str, Any] + ) -> None: add_c_return_converter(cls) + class CReturnConverter(metaclass=CReturnConverterAutoRegister): # The C type to use for this variable. @@ -3826,9 +4030,14 @@ class CReturnConverter(metaclass=CReturnConverterAutoRegister): # The Python default value for this parameter, as a Python value. # Or the magic value "unspecified" if there is no default. - default = None - - def __init__(self, *, py_default=None, **kwargs): + default: object = None + + def __init__( + self, + *, + py_default: str | None = None, + **kwargs + ) -> None: self.py_default = py_default try: self.return_converter_init(**kwargs) @@ -3836,52 +4045,58 @@ class CReturnConverter(metaclass=CReturnConverterAutoRegister): s = ', '.join(name + '=' + repr(value) for name, value in kwargs.items()) sys.exit(self.__class__.__name__ + '(' + s + ')\n' + str(e)) - def return_converter_init(self): - pass + def return_converter_init(self) -> None: ... - def declare(self, data, name="_return_value"): - line = [] + def declare(self, data: CRenderData) -> None: + line: list[str] = [] add = line.append add(self.type) if not self.type.endswith('*'): add(' ') - add(name + ';') + add(data.converter_retval + ';') data.declarations.append(''.join(line)) - data.return_value = name - - def err_occurred_if(self, expr, data): - data.return_conversion.append('if (({}) && PyErr_Occurred()) {{\n goto exit;\n}}\n'.format(expr)) + data.return_value = data.converter_retval + + def err_occurred_if( + self, + expr: str, + data: CRenderData + ) -> None: + line = f'if (({expr}) && PyErr_Occurred()) {{\n goto exit;\n}}\n' + data.return_conversion.append(line) + + def err_occurred_if_null_pointer( + self, + variable: str, + data: CRenderData + ) -> None: + line = f'if ({variable} == NULL) {{\n goto exit;\n}}\n' + data.return_conversion.append(line) + + def render( + self, + function: Function, + data: CRenderData + ) -> None: ... - def err_occurred_if_null_pointer(self, variable, data): - data.return_conversion.append('if ({} == NULL) {{\n goto exit;\n}}\n'.format(variable)) - - def render(self, function, data): - """ - function is a clinic.Function instance. - data is a CRenderData instance. - """ - pass add_c_return_converter(CReturnConverter, 'object') -class NoneType_return_converter(CReturnConverter): - def render(self, function, data): - self.declare(data) - data.return_conversion.append(''' -if (_return_value != Py_None) { - goto exit; -} -return_value = Py_None; -Py_INCREF(Py_None); -'''.strip()) class bool_return_converter(CReturnConverter): type = 'int' - def render(self, function, data): + def render( + self, + function: Function, + data: CRenderData + ) -> None: self.declare(data) - self.err_occurred_if("_return_value == -1", data) - data.return_conversion.append('return_value = PyBool_FromLong((long)_return_value);\n') + self.err_occurred_if(f"{data.converter_retval} == -1", data) + data.return_conversion.append( + f'return_value = PyBool_FromLong((long){data.converter_retval});\n' + ) + class long_return_converter(CReturnConverter): type = 'long' @@ -3889,16 +4104,23 @@ class long_return_converter(CReturnConverter): cast = '' unsigned_cast = '' - def render(self, function, data): + def render( + self, + function: Function, + data: CRenderData + ) -> None: self.declare(data) - self.err_occurred_if("_return_value == {}-1".format(self.unsigned_cast), data) + self.err_occurred_if(f"{data.converter_retval} == {self.unsigned_cast}-1", data) data.return_conversion.append( - ''.join(('return_value = ', self.conversion_fn, '(', self.cast, '_return_value);\n'))) + f'return_value = {self.conversion_fn}({self.cast}{data.converter_retval});\n' + ) + class int_return_converter(long_return_converter): type = 'int' cast = '(long)' + class init_return_converter(long_return_converter): """ Special return converter for __init__ functions. @@ -3906,23 +4128,30 @@ class init_return_converter(long_return_converter): type = 'int' cast = '(long)' - def render(self, function, data): - pass + def render( + self, + function: Function, + data: CRenderData + ) -> None: ... + class unsigned_long_return_converter(long_return_converter): type = 'unsigned long' conversion_fn = 'PyLong_FromUnsignedLong' unsigned_cast = '(unsigned long)' + class unsigned_int_return_converter(unsigned_long_return_converter): type = 'unsigned int' cast = '(unsigned long)' unsigned_cast = '(unsigned int)' + class Py_ssize_t_return_converter(long_return_converter): type = 'Py_ssize_t' conversion_fn = 'PyLong_FromSsize_t' + class size_t_return_converter(long_return_converter): type = 'size_t' conversion_fn = 'PyLong_FromSize_t' @@ -3933,11 +4162,17 @@ class double_return_converter(CReturnConverter): type = 'double' cast = '' - def render(self, function, data): + def render( + self, + function: Function, + data: CRenderData + ) -> None: self.declare(data) - self.err_occurred_if("_return_value == -1.0", data) + self.err_occurred_if(f"{data.converter_retval} == -1.0", data) data.return_conversion.append( - 'return_value = PyFloat_FromDouble(' + self.cast + '_return_value);\n') + f'return_value = PyFloat_FromDouble({self.cast}{data.converter_retval});\n' + ) + class float_return_converter(double_return_converter): type = 'float' @@ -3958,7 +4193,7 @@ def eval_ast_expr(node, globals, *, filename='-'): node = ast.Expression(node) co = compile(node, filename, 'eval') - fn = types.FunctionType(co, globals) + fn = FunctionType(co, globals) return fn() @@ -4042,8 +4277,11 @@ class IndentStack: return line[indent:] +StateKeeper = Callable[[str | None], None] +ConverterArgs = dict[str, Any] + class DSLParser: - def __init__(self, clinic): + def __init__(self, clinic: Clinic) -> None: self.clinic = clinic self.directives = {} @@ -4060,9 +4298,9 @@ class DSLParser: self.reset() - def reset(self): + def reset(self) -> None: self.function = None - self.state = self.state_dsl_start + self.state: StateKeeper = self.state_dsl_start self.parameter_indent = None self.keyword_only = False self.positional_only = False @@ -4072,17 +4310,17 @@ class DSLParser: self.indent = IndentStack() self.kind = CALLABLE self.coexist = False + self.forced_text_signature: str | None = None self.parameter_continuation = '' self.preserve_output = False - def directive_version(self, required): + def directive_version(self, required: str) -> None: global version if version_comparitor(version, required) < 0: fail("Insufficient Clinic version!\n Version: " + version + "\n Required: " + required) - def directive_module(self, name): - fields = name.split('.') - new = fields.pop() + def directive_module(self, name: str) -> None: + fields = name.split('.')[:-1] module, cls = self.clinic._module_and_class(fields) if cls: fail("Can't nest a module inside a class!") @@ -4094,12 +4332,14 @@ class DSLParser: module.modules[name] = m self.block.signatures.append(m) - def directive_class(self, name, typedef, type_object): + def directive_class( + self, + name: str, + typedef: str, + type_object: str + ) -> None: fields = name.split('.') - in_classes = False - parent = self name = fields.pop() - so_far = [] module, cls = self.clinic._module_and_class(fields) parent = cls or module @@ -4110,7 +4350,7 @@ class DSLParser: parent.classes[name] = c self.block.signatures.append(c) - def directive_set(self, name, value): + def directive_set(self, name: str, value: str) -> None: if name not in ("line_prefix", "line_suffix"): fail("unknown variable", repr(name)) @@ -4121,17 +4361,26 @@ class DSLParser: self.clinic.__dict__[name] = value - def directive_destination(self, name, command, *args): - if command == 'new': - self.clinic.add_destination(name, *args) - return - - if command == 'clear': - self.clinic.get_destination(name).clear() - fail("unknown destination command", repr(command)) - - - def directive_output(self, command_or_name, destination=''): + def directive_destination( + self, + name: str, + command: str, + *args + ) -> None: + match command: + case "new": + self.clinic.add_destination(name, *args) + case "clear": + self.clinic.get_destination(name).clear() + case _: + fail("unknown destination command", repr(command)) + + + def directive_output( + self, + command_or_name: str, + destination: str = '' + ) -> None: fd = self.clinic.destination_buffers if command_or_name == "preset": @@ -4169,34 +4418,39 @@ class DSLParser: fail("Invalid command / destination name " + repr(command_or_name) + ", must be one of:\n preset push pop print everything " + " ".join(fd)) fd[command_or_name] = d - def directive_dump(self, name): + def directive_dump(self, name: str) -> None: self.block.output.append(self.clinic.get_destination(name).dump()) - def directive_printout(self, *args): + def directive_printout(self, *args: str) -> None: self.block.output.append(' '.join(args)) self.block.output.append('\n') - def directive_preserve(self): + def directive_preserve(self) -> None: if self.preserve_output: fail("Can't have preserve twice in one block!") self.preserve_output = True - def at_classmethod(self): + def at_classmethod(self) -> None: if self.kind is not CALLABLE: fail("Can't set @classmethod, function is not a normal callable") self.kind = CLASS_METHOD - def at_staticmethod(self): + def at_staticmethod(self) -> None: if self.kind is not CALLABLE: fail("Can't set @staticmethod, function is not a normal callable") self.kind = STATIC_METHOD - def at_coexist(self): + def at_coexist(self) -> None: if self.coexist: fail("Called @coexist twice!") self.coexist = True - def parse(self, block): + def at_text_signature(self, text_signature: str) -> None: + if self.forced_text_signature: + fail("Called @text_signature twice!") + self.forced_text_signature = text_signature + + def parse(self, block: Block) -> None: self.reset() self.block = block self.saved_output = self.block.output @@ -4232,10 +4486,14 @@ class DSLParser: return False @staticmethod - def calculate_indent(line): + def calculate_indent(line: str) -> int: return len(line) - len(line.strip()) - def next(self, state, line=None): + def next( + self, + state: StateKeeper, + line: str | None = None + ) -> None: # real_print(self.state.__name__, "->", state.__name__, ", line=", line) self.state = state if line is not None: @@ -4326,13 +4584,13 @@ class DSLParser: c_basename = c_basename.strip() or None if not is_legal_py_identifier(full_name): - fail("Illegal function name: {}".format(full_name)) + fail("Illegal function name:", full_name) if c_basename and not is_legal_c_identifier(c_basename): - fail("Illegal C basename: {}".format(c_basename)) + fail("Illegal C basename:", c_basename) return_converter = None if returns: - ast_input = "def x() -> {}: pass".format(returns) + ast_input = f"def x() -> {returns}: pass" module = None try: module = ast.parse(ast_input) @@ -4545,7 +4803,7 @@ class DSLParser: module = None try: - ast_input = "def x({}): pass".format(base) + ast_input = f"def x({base}): pass" module = ast.parse(ast_input) except SyntaxError: try: @@ -4553,7 +4811,7 @@ class DSLParser: # c: int(accept={str}) # so assume there was no actual default value. default = None - ast_input = "def x({}): pass".format(line) + ast_input = f"def x({line}): pass" module = ast.parse(ast_input) except SyntaxError: pass @@ -4597,8 +4855,7 @@ class DSLParser: self.parameter_state = self.ps_optional default = default.strip() bad = False - ast_input = "x = {}".format(default) - bad = False + ast_input = f"x = {default}" try: module = ast.parse(ast_input) @@ -4635,7 +4892,7 @@ class DSLParser: # but at least make an attempt at ensuring it's a valid expression. try: value = eval(default) - if value == unspecified: + if value is unspecified: fail("'unspecified' is not a legal default value!") except NameError: pass # probably a named constant @@ -4653,10 +4910,8 @@ class DSLParser: c_default = "NULL" elif (isinstance(expr, ast.BinOp) or (isinstance(expr, ast.UnaryOp) and - not (isinstance(expr.operand, ast.Num) or - (hasattr(ast, 'Constant') and - isinstance(expr.operand, ast.Constant) and - type(expr.operand.value) in (int, float, complex))) + not (isinstance(expr.operand, ast.Constant) and + type(expr.operand.value) in {int, float, complex}) )): c_default = kwargs.get("c_default") if not (isinstance(c_default, str) and c_default): @@ -4707,7 +4962,7 @@ class DSLParser: dict = legacy_converters if legacy else converters legacy_str = "legacy " if legacy else "" if name not in dict: - fail('{} is not a valid {}converter'.format(name, legacy_str)) + fail(f'{name} is not a valid {legacy_str}converter') # if you use a c_name for the parameter, we just give that name to the converter # but the parameter object gets the python name converter = dict[name](c_name or parameter_name, parameter_name, self.function, value, **kwargs) @@ -4757,26 +5012,27 @@ class DSLParser: key = f"{parameter_name}_as_{c_name}" if c_name else parameter_name self.function.parameters[key] = p - def parse_converter(self, annotation): - if (hasattr(ast, 'Constant') and - isinstance(annotation, ast.Constant) and - type(annotation.value) is str): - return annotation.value, True, {} - - if isinstance(annotation, ast.Str): - return annotation.s, True, {} - - if isinstance(annotation, ast.Name): - return annotation.id, False, {} - - if not isinstance(annotation, ast.Call): - fail("Annotations must be either a name, a function call, or a string.") - - name = annotation.func.id - symbols = globals() - - kwargs = {node.arg: eval_ast_expr(node.value, symbols) for node in annotation.keywords} - return name, False, kwargs + @staticmethod + def parse_converter( + annotation: ast.expr | None + ) -> tuple[str, bool, ConverterArgs]: + match annotation: + case ast.Constant(value=str() as value): + return value, True, {} + case ast.Name(name): + return name, False, {} + case ast.Call(func=ast.Name(name)): + symbols = globals() + kwargs: ConverterArgs = {} + for node in annotation.keywords: + if not isinstance(node.arg, str): + fail("Cannot use a kwarg splat in a function-call annotation") + kwargs[node.arg] = eval_ast_expr(node.value, symbols) + return name, False, kwargs + case _: + fail( + "Annotations must be either a name, a function call, or a string." + ) def parse_special_symbol(self, symbol): if symbol == '*': @@ -4898,142 +5154,145 @@ class DSLParser: add(f.cls.name) else: add(f.name) - add('(') + if self.forced_text_signature: + add(self.forced_text_signature) + else: + add('(') + + # populate "right_bracket_count" field for every parameter + assert parameters, "We should always have a self parameter. " + repr(f) + assert isinstance(parameters[0].converter, self_converter) + # self is always positional-only. + assert parameters[0].is_positional_only() + parameters[0].right_bracket_count = 0 + positional_only = True + for p in parameters[1:]: + if not p.is_positional_only(): + positional_only = False + else: + assert positional_only + if positional_only: + p.right_bracket_count = abs(p.group) + else: + # don't put any right brackets around non-positional-only parameters, ever. + p.right_bracket_count = 0 + + right_bracket_count = 0 + + def fix_right_bracket_count(desired): + nonlocal right_bracket_count + s = '' + while right_bracket_count < desired: + s += '[' + right_bracket_count += 1 + while right_bracket_count > desired: + s += ']' + right_bracket_count -= 1 + return s + + need_slash = False + added_slash = False + need_a_trailing_slash = False + + # we only need a trailing slash: + # * if this is not a "docstring_only" signature + # * and if the last *shown* parameter is + # positional only + if not f.docstring_only: + for p in reversed(parameters): + if not p.converter.show_in_signature: + continue + if p.is_positional_only(): + need_a_trailing_slash = True + break - # populate "right_bracket_count" field for every parameter - assert parameters, "We should always have a self parameter. " + repr(f) - assert isinstance(parameters[0].converter, self_converter) - # self is always positional-only. - assert parameters[0].is_positional_only() - parameters[0].right_bracket_count = 0 - positional_only = True - for p in parameters[1:]: - if not p.is_positional_only(): - positional_only = False - else: - assert positional_only - if positional_only: - p.right_bracket_count = abs(p.group) - else: - # don't put any right brackets around non-positional-only parameters, ever. - p.right_bracket_count = 0 - - right_bracket_count = 0 - - def fix_right_bracket_count(desired): - nonlocal right_bracket_count - s = '' - while right_bracket_count < desired: - s += '[' - right_bracket_count += 1 - while right_bracket_count > desired: - s += ']' - right_bracket_count -= 1 - return s - need_slash = False - added_slash = False - need_a_trailing_slash = False + added_star = False - # we only need a trailing slash: - # * if this is not a "docstring_only" signature - # * and if the last *shown* parameter is - # positional only - if not f.docstring_only: - for p in reversed(parameters): + first_parameter = True + last_p = parameters[-1] + line_length = len(''.join(text)) + indent = " " * line_length + def add_parameter(text): + nonlocal line_length + nonlocal first_parameter + if first_parameter: + s = text + first_parameter = False + else: + s = ' ' + text + if line_length + len(s) >= 72: + add('\n') + add(indent) + line_length = len(indent) + s = text + line_length += len(s) + add(s) + + for p in parameters: if not p.converter.show_in_signature: continue - if p.is_positional_only(): - need_a_trailing_slash = True - break - - - added_star = False - - first_parameter = True - last_p = parameters[-1] - line_length = len(''.join(text)) - indent = " " * line_length - def add_parameter(text): - nonlocal line_length - nonlocal first_parameter - if first_parameter: - s = text - first_parameter = False - else: - s = ' ' + text - if line_length + len(s) >= 72: - add('\n') - add(indent) - line_length = len(indent) - s = text - line_length += len(s) - add(s) - - for p in parameters: - if not p.converter.show_in_signature: - continue - assert p.name + assert p.name - is_self = isinstance(p.converter, self_converter) - if is_self and f.docstring_only: - # this isn't a real machine-parsable signature, - # so let's not print the "self" parameter - continue + is_self = isinstance(p.converter, self_converter) + if is_self and f.docstring_only: + # this isn't a real machine-parsable signature, + # so let's not print the "self" parameter + continue - if p.is_positional_only(): - need_slash = not f.docstring_only - elif need_slash and not (added_slash or p.is_positional_only()): - added_slash = True - add_parameter('/,') - - if p.is_keyword_only() and not added_star: - added_star = True - add_parameter('*,') - - p_add, p_output = text_accumulator() - p_add(fix_right_bracket_count(p.right_bracket_count)) - - if isinstance(p.converter, self_converter): - # annotate first parameter as being a "self". - # - # if inspect.Signature gets this function, - # and it's already bound, the self parameter - # will be stripped off. - # - # if it's not bound, it should be marked - # as positional-only. - # - # note: we don't print "self" for __init__, - # because this isn't actually the signature - # for __init__. (it can't be, __init__ doesn't - # have a docstring.) if this is an __init__ - # (or __new__), then this signature is for - # calling the class to construct a new instance. - p_add('$') + if p.is_positional_only(): + need_slash = not f.docstring_only + elif need_slash and not (added_slash or p.is_positional_only()): + added_slash = True + add_parameter('/,') + + if p.is_keyword_only() and not added_star: + added_star = True + add_parameter('*,') + + p_add, p_output = text_accumulator() + p_add(fix_right_bracket_count(p.right_bracket_count)) + + if isinstance(p.converter, self_converter): + # annotate first parameter as being a "self". + # + # if inspect.Signature gets this function, + # and it's already bound, the self parameter + # will be stripped off. + # + # if it's not bound, it should be marked + # as positional-only. + # + # note: we don't print "self" for __init__, + # because this isn't actually the signature + # for __init__. (it can't be, __init__ doesn't + # have a docstring.) if this is an __init__ + # (or __new__), then this signature is for + # calling the class to construct a new instance. + p_add('$') - if p.is_vararg(): - p_add("*") + if p.is_vararg(): + p_add("*") - name = p.converter.signature_name or p.name - p_add(name) + name = p.converter.signature_name or p.name + p_add(name) - if not p.is_vararg() and p.converter.is_optional(): - p_add('=') - value = p.converter.py_default - if not value: - value = repr(p.converter.default) - p_add(value) + if not p.is_vararg() and p.converter.is_optional(): + p_add('=') + value = p.converter.py_default + if not value: + value = repr(p.converter.default) + p_add(value) - if (p != last_p) or need_a_trailing_slash: - p_add(',') + if (p != last_p) or need_a_trailing_slash: + p_add(',') - add_parameter(p_output()) + add_parameter(p_output()) - add(fix_right_bracket_count(0)) - if need_a_trailing_slash: - add_parameter('/') - add(')') + add(fix_right_bracket_count(0)) + if need_a_trailing_slash: + add_parameter('/') + add(')') # PEP 8 says: # @@ -5172,10 +5431,6 @@ clinic = None def main(argv): import sys - - if sys.version_info.major < 3 or sys.version_info.minor < 3: - sys.exit("Error: clinic.py requires Python 3.3 or greater.") - import argparse cmdline = argparse.ArgumentParser( description="""Preprocessor for CPython C files. @@ -5185,15 +5440,21 @@ with writing argument parsing code for builtins and providing introspection signatures ("docstrings") for CPython builtins. For more information see https://docs.python.org/3/howto/clinic.html""") - cmdline.add_argument("-f", "--force", action='store_true') - cmdline.add_argument("-o", "--output", type=str) - cmdline.add_argument("-v", "--verbose", action='store_true') - cmdline.add_argument("--converters", action='store_true') + cmdline.add_argument("-f", "--force", action='store_true', + help="force output regeneration") + cmdline.add_argument("-o", "--output", type=str, + help="redirect file output to OUTPUT") + cmdline.add_argument("-v", "--verbose", action='store_true', + help="enable verbose mode") + cmdline.add_argument("--converters", action='store_true', + help=("print a list of all supported converters " + "and return converters")) cmdline.add_argument("--make", action='store_true', - help="Walk --srcdir to run over all relevant files.") + help="walk --srcdir to run over all relevant files") cmdline.add_argument("--srcdir", type=str, default=os.curdir, - help="The directory tree to walk in --make mode.") - cmdline.add_argument("filename", type=str, nargs="*") + help="the directory tree to walk in --make mode") + cmdline.add_argument("filename", metavar="FILE", type=str, nargs="*", + help="the list of files to process") ns = cmdline.parse_args(argv) if ns.converters: @@ -5219,7 +5480,7 @@ For more information see https://docs.python.org/3/howto/clinic.html""") if name in ignored: continue if name.endswith(suffix): - ids.append((name, name[:-len(suffix)])) + ids.append((name, name.removesuffix(suffix))) break print() @@ -5247,7 +5508,7 @@ For more information see https://docs.python.org/3/howto/clinic.html""") for parameter_name, parameter in signature.parameters.items(): if parameter.kind == inspect.Parameter.KEYWORD_ONLY: if parameter.default != inspect.Parameter.empty: - s = '{}={!r}'.format(parameter_name, parameter.default) + s = f'{parameter_name}={parameter.default!r}' else: s = parameter_name parameters.append(s) diff --git a/Tools/clinic/cpp.py b/Tools/clinic/cpp.py index 77f5f969..c1a2eeef 100644 --- a/Tools/clinic/cpp.py +++ b/Tools/clinic/cpp.py @@ -1,7 +1,13 @@ import re import sys +from collections.abc import Callable +from typing import NoReturn -def negate(condition): + +TokenAndCondition = tuple[str, str] +TokenStack = list[TokenAndCondition] + +def negate(condition: str) -> str: """ Returns a CPP conditional that is the opposite of the conditional passed in. """ @@ -22,17 +28,18 @@ class Monitor: Anyway this implementation seems to work well enough for the CPython sources. """ + is_a_simple_defined: Callable[[str], re.Match[str] | None] is_a_simple_defined = re.compile(r'^defined\s*\(\s*[A-Za-z0-9_]+\s*\)$').match - def __init__(self, filename=None, *, verbose=False): - self.stack = [] + def __init__(self, filename: str | None = None, *, verbose: bool = False) -> None: + self.stack: TokenStack = [] self.in_comment = False - self.continuation = None + self.continuation: str | None = None self.line_number = 0 self.filename = filename self.verbose = verbose - def __repr__(self): + def __repr__(self) -> str: return ''.join(( '<Monitor ', str(id(self)), @@ -40,16 +47,16 @@ class Monitor: " condition=", repr(self.condition()), ">")) - def status(self): + def status(self) -> str: return str(self.line_number).rjust(4) + ": " + self.condition() - def condition(self): + def condition(self) -> str: """ Returns the current preprocessor state, as a single #if condition. """ return " && ".join(condition for token, condition in self.stack) - def fail(self, *a): + def fail(self, *a: object) -> NoReturn: if self.filename: filename = " " + self.filename else: @@ -58,19 +65,19 @@ class Monitor: print(" ", ' '.join(str(x) for x in a)) sys.exit(-1) - def close(self): + def close(self) -> None: if self.stack: self.fail("Ended file while still in a preprocessor conditional block!") - def write(self, s): + def write(self, s: str) -> None: for line in s.split("\n"): self.writeline(line) - def writeline(self, line): + def writeline(self, line: str) -> None: self.line_number += 1 line = line.strip() - def pop_stack(): + def pop_stack() -> TokenAndCondition: if not self.stack: self.fail("#" + token + " without matching #if / #ifdef / #ifndef!") return self.stack.pop() @@ -178,7 +185,7 @@ class Monitor: if __name__ == '__main__': for filename in sys.argv[1:]: - with open(filename, "rt") as f: + with open(filename) as f: cpp = Monitor(filename, verbose=True) print() print(filename) diff --git a/Tools/clinic/mypy.ini b/Tools/clinic/mypy.ini new file mode 100644 index 00000000..672911dc --- /dev/null +++ b/Tools/clinic/mypy.ini @@ -0,0 +1,12 @@ +[mypy] +# make sure clinic can still be run on Python 3.10 +python_version = 3.10 +pretty = True +enable_error_code = ignore-without-code +disallow_any_generics = True +strict_concatenate = True +warn_redundant_casts = True +warn_unused_ignores = True +warn_unused_configs = True +warn_unreachable = True +files = Tools/clinic/ diff --git a/Tools/clinic/requirements-dev.txt b/Tools/clinic/requirements-dev.txt new file mode 100644 index 00000000..15493400 --- /dev/null +++ b/Tools/clinic/requirements-dev.txt @@ -0,0 +1,2 @@ +# Requirements file for external linters and checks we run on Tools/clinic/ in CI +mypy==1.3.0 diff --git a/Tools/demo/README b/Tools/demo/README deleted file mode 100644 index 9fccb97d..00000000 --- a/Tools/demo/README +++ /dev/null @@ -1,16 +0,0 @@ -This directory contains a collection of demonstration scripts for -various aspects of Python programming. - -beer.py Well-known programming example: Bottles of beer. -eiffel.py Python advanced magic: A metaclass for Eiffel post/preconditions. -hanoi.py Well-known programming example: Towers of Hanoi. -life.py Curses programming: Simple game-of-life. -markov.py Algorithms: Markov chain simulation. -mcast.py Network programming: Send and receive UDP multicast packets. -queens.py Well-known programming example: N-Queens problem. -redemo.py Regular Expressions: GUI script to test regexes. -rpython.py Network programming: Small client for remote code execution. -rpythond.py Network programming: Small server for remote code execution. -sortvisu.py GUI programming: Visualization of different sort algorithms. -spreadsheet.py GUI/Application programming: A simple spreadsheet application. -vector.py Python basics: A vector class demonstrating special methods. diff --git a/Tools/demo/beer.py b/Tools/demo/beer.py deleted file mode 100755 index af58380e..00000000 --- a/Tools/demo/beer.py +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/env python3 - -""" -A Python version of the classic "bottles of beer on the wall" programming -example. - -By Guido van Rossum, demystified after a version by Fredrik Lundh. -""" - -import sys - -n = 100 -if sys.argv[1:]: - n = int(sys.argv[1]) - -def bottle(n): - if n == 0: return "no more bottles of beer" - if n == 1: return "one bottle of beer" - return str(n) + " bottles of beer" - -for i in range(n, 0, -1): - print(bottle(i), "on the wall,") - print(bottle(i) + ".") - print("Take one down, pass it around,") - print(bottle(i-1), "on the wall.") diff --git a/Tools/demo/eiffel.py b/Tools/demo/eiffel.py deleted file mode 100755 index a76c2324..00000000 --- a/Tools/demo/eiffel.py +++ /dev/null @@ -1,146 +0,0 @@ -#!/usr/bin/env python3 - -""" -Support Eiffel-style preconditions and postconditions for functions. - -An example for Python metaclasses. -""" - -import unittest -from types import FunctionType as function - -class EiffelBaseMetaClass(type): - - def __new__(meta, name, bases, dict): - meta.convert_methods(dict) - return super(EiffelBaseMetaClass, meta).__new__( - meta, name, bases, dict) - - @classmethod - def convert_methods(cls, dict): - """Replace functions in dict with EiffelMethod wrappers. - - The dict is modified in place. - - If a method ends in _pre or _post, it is removed from the dict - regardless of whether there is a corresponding method. - """ - # find methods with pre or post conditions - methods = [] - for k, v in dict.items(): - if k.endswith('_pre') or k.endswith('_post'): - assert isinstance(v, function) - elif isinstance(v, function): - methods.append(k) - for m in methods: - pre = dict.get("%s_pre" % m) - post = dict.get("%s_post" % m) - if pre or post: - dict[m] = cls.make_eiffel_method(dict[m], pre, post) - - -class EiffelMetaClass1(EiffelBaseMetaClass): - # an implementation of the "eiffel" meta class that uses nested functions - - @staticmethod - def make_eiffel_method(func, pre, post): - def method(self, *args, **kwargs): - if pre: - pre(self, *args, **kwargs) - rv = func(self, *args, **kwargs) - if post: - post(self, rv, *args, **kwargs) - return rv - - if func.__doc__: - method.__doc__ = func.__doc__ - - return method - - -class EiffelMethodWrapper: - - def __init__(self, inst, descr): - self._inst = inst - self._descr = descr - - def __call__(self, *args, **kwargs): - return self._descr.callmethod(self._inst, args, kwargs) - - -class EiffelDescriptor: - - def __init__(self, func, pre, post): - self._func = func - self._pre = pre - self._post = post - - self.__name__ = func.__name__ - self.__doc__ = func.__doc__ - - def __get__(self, obj, cls=None): - return EiffelMethodWrapper(obj, self) - - def callmethod(self, inst, args, kwargs): - if self._pre: - self._pre(inst, *args, **kwargs) - x = self._func(inst, *args, **kwargs) - if self._post: - self._post(inst, x, *args, **kwargs) - return x - - -class EiffelMetaClass2(EiffelBaseMetaClass): - # an implementation of the "eiffel" meta class that uses descriptors - - make_eiffel_method = EiffelDescriptor - - -class Tests(unittest.TestCase): - - def testEiffelMetaClass1(self): - self._test(EiffelMetaClass1) - - def testEiffelMetaClass2(self): - self._test(EiffelMetaClass2) - - def _test(self, metaclass): - class Eiffel(metaclass=metaclass): - pass - - class Test(Eiffel): - def m(self, arg): - """Make it a little larger""" - return arg + 1 - - def m2(self, arg): - """Make it a little larger""" - return arg + 1 - - def m2_pre(self, arg): - assert arg > 0 - - def m2_post(self, result, arg): - assert result > arg - - class Sub(Test): - def m2(self, arg): - return arg**2 - - def m2_post(self, Result, arg): - super(Sub, self).m2_post(Result, arg) - assert Result < 100 - - t = Test() - self.assertEqual(t.m(1), 2) - self.assertEqual(t.m2(1), 2) - self.assertRaises(AssertionError, t.m2, 0) - - s = Sub() - self.assertRaises(AssertionError, s.m2, 1) - self.assertRaises(AssertionError, s.m2, 10) - self.assertEqual(s.m2(5), 25) - - -if __name__ == "__main__": - unittest.main() diff --git a/Tools/demo/hanoi.py b/Tools/demo/hanoi.py deleted file mode 100755 index 8db895c2..00000000 --- a/Tools/demo/hanoi.py +++ /dev/null @@ -1,154 +0,0 @@ -#!/usr/bin/env python3 - -""" -Animated Towers of Hanoi using Tk with optional bitmap file in background. - -Usage: hanoi.py [n [bitmapfile]] - -n is the number of pieces to animate; default is 4, maximum 15. - -The bitmap file can be any X11 bitmap file (look in /usr/include/X11/bitmaps for -samples); it is displayed as the background of the animation. Default is no -bitmap. -""" - -from tkinter import Tk, Canvas - -# Basic Towers-of-Hanoi algorithm: move n pieces from a to b, using c -# as temporary. For each move, call report() -def hanoi(n, a, b, c, report): - if n <= 0: return - hanoi(n-1, a, c, b, report) - report(n, a, b) - hanoi(n-1, c, b, a, report) - - -# The graphical interface -class Tkhanoi: - - # Create our objects - def __init__(self, n, bitmap=None): - self.n = n - self.tk = tk = Tk() - self.canvas = c = Canvas(tk) - c.pack() - width, height = tk.getint(c['width']), tk.getint(c['height']) - - # Add background bitmap - if bitmap: - self.bitmap = c.create_bitmap(width//2, height//2, - bitmap=bitmap, - foreground='blue') - - # Generate pegs - pegwidth = 10 - pegheight = height//2 - pegdist = width//3 - x1, y1 = (pegdist-pegwidth)//2, height*1//3 - x2, y2 = x1+pegwidth, y1+pegheight - self.pegs = [] - p = c.create_rectangle(x1, y1, x2, y2, fill='black') - self.pegs.append(p) - x1, x2 = x1+pegdist, x2+pegdist - p = c.create_rectangle(x1, y1, x2, y2, fill='black') - self.pegs.append(p) - x1, x2 = x1+pegdist, x2+pegdist - p = c.create_rectangle(x1, y1, x2, y2, fill='black') - self.pegs.append(p) - self.tk.update() - - # Generate pieces - pieceheight = pegheight//16 - maxpiecewidth = pegdist*2//3 - minpiecewidth = 2*pegwidth - self.pegstate = [[], [], []] - self.pieces = {} - x1, y1 = (pegdist-maxpiecewidth)//2, y2-pieceheight-2 - x2, y2 = x1+maxpiecewidth, y1+pieceheight - dx = (maxpiecewidth-minpiecewidth) // (2*max(1, n-1)) - for i in range(n, 0, -1): - p = c.create_rectangle(x1, y1, x2, y2, fill='red') - self.pieces[i] = p - self.pegstate[0].append(i) - x1, x2 = x1 + dx, x2-dx - y1, y2 = y1 - pieceheight-2, y2-pieceheight-2 - self.tk.update() - self.tk.after(25) - - # Run -- never returns - def run(self): - while True: - hanoi(self.n, 0, 1, 2, self.report) - hanoi(self.n, 1, 2, 0, self.report) - hanoi(self.n, 2, 0, 1, self.report) - hanoi(self.n, 0, 2, 1, self.report) - hanoi(self.n, 2, 1, 0, self.report) - hanoi(self.n, 1, 0, 2, self.report) - - # Reporting callback for the actual hanoi function - def report(self, i, a, b): - if self.pegstate[a][-1] != i: raise RuntimeError # Assertion - del self.pegstate[a][-1] - p = self.pieces[i] - c = self.canvas - - # Lift the piece above peg a - ax1, ay1, ax2, ay2 = c.bbox(self.pegs[a]) - while True: - x1, y1, x2, y2 = c.bbox(p) - if y2 < ay1: break - c.move(p, 0, -1) - self.tk.update() - - # Move it towards peg b - bx1, by1, bx2, by2 = c.bbox(self.pegs[b]) - newcenter = (bx1+bx2)//2 - while True: - x1, y1, x2, y2 = c.bbox(p) - center = (x1+x2)//2 - if center == newcenter: break - if center > newcenter: c.move(p, -1, 0) - else: c.move(p, 1, 0) - self.tk.update() - - # Move it down on top of the previous piece - pieceheight = y2-y1 - newbottom = by2 - pieceheight*len(self.pegstate[b]) - 2 - while True: - x1, y1, x2, y2 = c.bbox(p) - if y2 >= newbottom: break - c.move(p, 0, 1) - self.tk.update() - - # Update peg state - self.pegstate[b].append(i) - - -def main(): - import sys - - # First argument is number of pegs, default 4 - if sys.argv[1:]: - n = int(sys.argv[1]) - else: - n = 4 - - # Second argument is bitmap file, default none - if sys.argv[2:]: - bitmap = sys.argv[2] - # Reverse meaning of leading '@' compared to Tk - if bitmap[0] == '@': bitmap = bitmap[1:] - else: bitmap = '@' + bitmap - else: - bitmap = None - - # Create the graphical objects... - h = Tkhanoi(n, bitmap) - - # ...and run! - h.run() - - -# Call main when run as script -if __name__ == '__main__': - main() diff --git a/Tools/demo/life.py b/Tools/demo/life.py deleted file mode 100755 index fc4cb495..00000000 --- a/Tools/demo/life.py +++ /dev/null @@ -1,262 +0,0 @@ -#!/usr/bin/env python3 - -""" -A curses-based version of Conway's Game of Life. - -An empty board will be displayed, and the following commands are available: - E : Erase the board - R : Fill the board randomly - S : Step for a single generation - C : Update continuously until a key is struck - Q : Quit - Cursor keys : Move the cursor around the board - Space or Enter : Toggle the contents of the cursor's position - -Contributed by Andrew Kuchling, Mouse support and color by Dafydd Crosby. -""" - -import curses -import random - - -class LifeBoard: - """Encapsulates a Life board - - Attributes: - X,Y : horizontal and vertical size of the board - state : dictionary mapping (x,y) to 0 or 1 - - Methods: - display(update_board) -- If update_board is true, compute the - next generation. Then display the state - of the board and refresh the screen. - erase() -- clear the entire board - make_random() -- fill the board randomly - set(y,x) -- set the given cell to Live; doesn't refresh the screen - toggle(y,x) -- change the given cell from live to dead, or vice - versa, and refresh the screen display - - """ - def __init__(self, scr, char=ord('*')): - """Create a new LifeBoard instance. - - scr -- curses screen object to use for display - char -- character used to render live cells (default: '*') - """ - self.state = {} - self.scr = scr - Y, X = self.scr.getmaxyx() - self.X, self.Y = X - 2, Y - 2 - 1 - self.char = char - self.scr.clear() - - # Draw a border around the board - border_line = '+' + (self.X * '-') + '+' - self.scr.addstr(0, 0, border_line) - self.scr.addstr(self.Y + 1, 0, border_line) - for y in range(0, self.Y): - self.scr.addstr(1 + y, 0, '|') - self.scr.addstr(1 + y, self.X + 1, '|') - self.scr.refresh() - - def set(self, y, x): - """Set a cell to the live state""" - if x < 0 or self.X <= x or y < 0 or self.Y <= y: - raise ValueError("Coordinates out of range %i,%i" % (y, x)) - self.state[x, y] = 1 - - def toggle(self, y, x): - """Toggle a cell's state between live and dead""" - if x < 0 or self.X <= x or y < 0 or self.Y <= y: - raise ValueError("Coordinates out of range %i,%i" % (y, x)) - if (x, y) in self.state: - del self.state[x, y] - self.scr.addch(y + 1, x + 1, ' ') - else: - self.state[x, y] = 1 - if curses.has_colors(): - # Let's pick a random color! - self.scr.attrset(curses.color_pair(random.randrange(1, 7))) - self.scr.addch(y + 1, x + 1, self.char) - self.scr.attrset(0) - self.scr.refresh() - - def erase(self): - """Clear the entire board and update the board display""" - self.state = {} - self.display(update_board=False) - - def display(self, update_board=True): - """Display the whole board, optionally computing one generation""" - M, N = self.X, self.Y - if not update_board: - for i in range(0, M): - for j in range(0, N): - if (i, j) in self.state: - self.scr.addch(j + 1, i + 1, self.char) - else: - self.scr.addch(j + 1, i + 1, ' ') - self.scr.refresh() - return - - d = {} - self.boring = 1 - for i in range(0, M): - L = range(max(0, i - 1), min(M, i + 2)) - for j in range(0, N): - s = 0 - live = (i, j) in self.state - for k in range(max(0, j - 1), min(N, j + 2)): - for l in L: - if (l, k) in self.state: - s += 1 - s -= live - if s == 3: - # Birth - d[i, j] = 1 - if curses.has_colors(): - # Let's pick a random color! - self.scr.attrset(curses.color_pair( - random.randrange(1, 7))) - self.scr.addch(j + 1, i + 1, self.char) - self.scr.attrset(0) - if not live: - self.boring = 0 - elif s == 2 and live: - # Survival - d[i, j] = 1 - elif live: - # Death - self.scr.addch(j + 1, i + 1, ' ') - self.boring = 0 - self.state = d - self.scr.refresh() - - def make_random(self): - "Fill the board with a random pattern" - self.state = {} - for i in range(0, self.X): - for j in range(0, self.Y): - if random.random() > 0.5: - self.set(j, i) - - -def erase_menu(stdscr, menu_y): - "Clear the space where the menu resides" - stdscr.move(menu_y, 0) - stdscr.clrtoeol() - stdscr.move(menu_y + 1, 0) - stdscr.clrtoeol() - - -def display_menu(stdscr, menu_y): - "Display the menu of possible keystroke commands" - erase_menu(stdscr, menu_y) - - # If color, then light the menu up :-) - if curses.has_colors(): - stdscr.attrset(curses.color_pair(1)) - stdscr.addstr(menu_y, 4, - 'Use the cursor keys to move, and space or Enter to toggle a cell.') - stdscr.addstr(menu_y + 1, 4, - 'E)rase the board, R)andom fill, S)tep once or C)ontinuously, Q)uit') - stdscr.attrset(0) - - -def keyloop(stdscr): - # Clear the screen and display the menu of keys - stdscr.clear() - stdscr_y, stdscr_x = stdscr.getmaxyx() - menu_y = (stdscr_y - 3) - 1 - display_menu(stdscr, menu_y) - - # If color, then initialize the color pairs - if curses.has_colors(): - curses.init_pair(1, curses.COLOR_BLUE, 0) - curses.init_pair(2, curses.COLOR_CYAN, 0) - curses.init_pair(3, curses.COLOR_GREEN, 0) - curses.init_pair(4, curses.COLOR_MAGENTA, 0) - curses.init_pair(5, curses.COLOR_RED, 0) - curses.init_pair(6, curses.COLOR_YELLOW, 0) - curses.init_pair(7, curses.COLOR_WHITE, 0) - - # Set up the mask to listen for mouse events - curses.mousemask(curses.BUTTON1_CLICKED) - - # Allocate a subwindow for the Life board and create the board object - subwin = stdscr.subwin(stdscr_y - 3, stdscr_x, 0, 0) - board = LifeBoard(subwin, char=ord('*')) - board.display(update_board=False) - - # xpos, ypos are the cursor's position - xpos, ypos = board.X // 2, board.Y // 2 - - # Main loop: - while True: - stdscr.move(1 + ypos, 1 + xpos) # Move the cursor - c = stdscr.getch() # Get a keystroke - if 0 < c < 256: - c = chr(c) - if c in ' \n': - board.toggle(ypos, xpos) - elif c in 'Cc': - erase_menu(stdscr, menu_y) - stdscr.addstr(menu_y, 6, ' Hit any key to stop continuously ' - 'updating the screen.') - stdscr.refresh() - # Activate nodelay mode; getch() will return -1 - # if no keystroke is available, instead of waiting. - stdscr.nodelay(1) - while True: - c = stdscr.getch() - if c != -1: - break - stdscr.addstr(0, 0, '/') - stdscr.refresh() - board.display() - stdscr.addstr(0, 0, '+') - stdscr.refresh() - - stdscr.nodelay(0) # Disable nodelay mode - display_menu(stdscr, menu_y) - - elif c in 'Ee': - board.erase() - elif c in 'Qq': - break - elif c in 'Rr': - board.make_random() - board.display(update_board=False) - elif c in 'Ss': - board.display() - else: - # Ignore incorrect keys - pass - elif c == curses.KEY_UP and ypos > 0: - ypos -= 1 - elif c == curses.KEY_DOWN and ypos + 1 < board.Y: - ypos += 1 - elif c == curses.KEY_LEFT and xpos > 0: - xpos -= 1 - elif c == curses.KEY_RIGHT and xpos + 1 < board.X: - xpos += 1 - elif c == curses.KEY_MOUSE: - mouse_id, mouse_x, mouse_y, mouse_z, button_state = curses.getmouse() - if (mouse_x > 0 and mouse_x < board.X + 1 and - mouse_y > 0 and mouse_y < board.Y + 1): - xpos = mouse_x - 1 - ypos = mouse_y - 1 - board.toggle(ypos, xpos) - else: - # They've clicked outside the board - curses.flash() - else: - # Ignore incorrect keys - pass - - -def main(stdscr): - keyloop(stdscr) # Enter the main loop - -if __name__ == '__main__': - curses.wrapper(main) diff --git a/Tools/demo/markov.py b/Tools/demo/markov.py deleted file mode 100755 index 9729f382..00000000 --- a/Tools/demo/markov.py +++ /dev/null @@ -1,125 +0,0 @@ -#!/usr/bin/env python3 - -""" -Markov chain simulation of words or characters. -""" - -class Markov: - def __init__(self, histsize, choice): - self.histsize = histsize - self.choice = choice - self.trans = {} - - def add(self, state, next): - self.trans.setdefault(state, []).append(next) - - def put(self, seq): - n = self.histsize - add = self.add - add(None, seq[:0]) - for i in range(len(seq)): - add(seq[max(0, i-n):i], seq[i:i+1]) - add(seq[len(seq)-n:], None) - - def get(self): - choice = self.choice - trans = self.trans - n = self.histsize - seq = choice(trans[None]) - while True: - subseq = seq[max(0, len(seq)-n):] - options = trans[subseq] - next = choice(options) - if not next: - break - seq += next - return seq - - -def test(): - import sys, random, getopt - args = sys.argv[1:] - try: - opts, args = getopt.getopt(args, '0123456789cdwq') - except getopt.error: - print('Usage: %s [-#] [-cddqw] [file] ...' % sys.argv[0]) - print('Options:') - print('-#: 1-digit history size (default 2)') - print('-c: characters (default)') - print('-w: words') - print('-d: more debugging output') - print('-q: no debugging output') - print('Input files (default stdin) are split in paragraphs') - print('separated blank lines and each paragraph is split') - print('in words by whitespace, then reconcatenated with') - print('exactly one space separating words.') - print('Output consists of paragraphs separated by blank') - print('lines, where lines are no longer than 72 characters.') - sys.exit(2) - histsize = 2 - do_words = False - debug = 1 - for o, a in opts: - if '-0' <= o <= '-9': histsize = int(o[1:]) - if o == '-c': do_words = False - if o == '-d': debug += 1 - if o == '-q': debug = 0 - if o == '-w': do_words = True - if not args: - args = ['-'] - - m = Markov(histsize, random.choice) - try: - for filename in args: - if filename == '-': - f = sys.stdin - if f.isatty(): - print('Sorry, need stdin from file') - continue - else: - f = open(filename, 'r') - with f: - if debug: print('processing', filename, '...') - text = f.read() - paralist = text.split('\n\n') - for para in paralist: - if debug > 1: print('feeding ...') - words = para.split() - if words: - if do_words: - data = tuple(words) - else: - data = ' '.join(words) - m.put(data) - except KeyboardInterrupt: - print('Interrupted -- continue with data read so far') - if not m.trans: - print('No valid input files') - return - if debug: print('done.') - - if debug > 1: - for key in m.trans.keys(): - if key is None or len(key) < histsize: - print(repr(key), m.trans[key]) - if histsize == 0: print(repr(''), m.trans['']) - print() - while True: - data = m.get() - if do_words: - words = data - else: - words = data.split() - n = 0 - limit = 72 - for w in words: - if n + len(w) > limit: - print() - n = 0 - print(w, end=' ') - n += len(w) + 1 - print() - print() - -if __name__ == "__main__": - test() diff --git a/Tools/demo/mcast.py b/Tools/demo/mcast.py deleted file mode 100755 index 924c7c3e..00000000 --- a/Tools/demo/mcast.py +++ /dev/null @@ -1,82 +0,0 @@ -#!/usr/bin/env python3 - -""" -Send/receive UDP multicast packets. -Requires that your OS kernel supports IP multicast. - -Usage: - mcast -s (sender, IPv4) - mcast -s -6 (sender, IPv6) - mcast (receivers, IPv4) - mcast -6 (receivers, IPv6) -""" - -MYPORT = 8123 -MYGROUP_4 = '225.0.0.250' -MYGROUP_6 = 'ff15:7079:7468:6f6e:6465:6d6f:6d63:6173' -MYTTL = 1 # Increase to reach other networks - -import time -import struct -import socket -import sys - -def main(): - group = MYGROUP_6 if "-6" in sys.argv[1:] else MYGROUP_4 - - if "-s" in sys.argv[1:]: - sender(group) - else: - receiver(group) - - -def sender(group): - addrinfo = socket.getaddrinfo(group, None)[0] - - s = socket.socket(addrinfo[0], socket.SOCK_DGRAM) - - # Set Time-to-live (optional) - ttl_bin = struct.pack('@i', MYTTL) - if addrinfo[0] == socket.AF_INET: # IPv4 - s.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, ttl_bin) - else: - s.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_HOPS, ttl_bin) - - while True: - data = repr(time.time()).encode('utf-8') + b'\0' - s.sendto(data, (addrinfo[4][0], MYPORT)) - time.sleep(1) - - -def receiver(group): - # Look up multicast group address in name server and find out IP version - addrinfo = socket.getaddrinfo(group, None)[0] - - # Create a socket - s = socket.socket(addrinfo[0], socket.SOCK_DGRAM) - - # Allow multiple copies of this program on one machine - # (not strictly needed) - s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - - # Bind it to the port - s.bind(('', MYPORT)) - - group_bin = socket.inet_pton(addrinfo[0], addrinfo[4][0]) - # Join group - if addrinfo[0] == socket.AF_INET: # IPv4 - mreq = group_bin + struct.pack('=I', socket.INADDR_ANY) - s.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq) - else: - mreq = group_bin + struct.pack('@I', 0) - s.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_JOIN_GROUP, mreq) - - # Loop, printing any data we receive - while True: - data, sender = s.recvfrom(1500) - while data[-1:] == '\0': data = data[:-1] # Strip trailing \0's - print(str(sender) + ' ' + repr(data)) - - -if __name__ == '__main__': - main() diff --git a/Tools/demo/queens.py b/Tools/demo/queens.py deleted file mode 100755 index dcc1bae1..00000000 --- a/Tools/demo/queens.py +++ /dev/null @@ -1,85 +0,0 @@ -#!/usr/bin/env python3 - -""" -N queens problem. - -The (well-known) problem is due to Niklaus Wirth. - -This solution is inspired by Dijkstra (Structured Programming). It is -a classic recursive backtracking approach. -""" - -N = 8 # Default; command line overrides - -class Queens: - - def __init__(self, n=N): - self.n = n - self.reset() - - def reset(self): - n = self.n - self.y = [None] * n # Where is the queen in column x - self.row = [0] * n # Is row[y] safe? - self.up = [0] * (2*n-1) # Is upward diagonal[x-y] safe? - self.down = [0] * (2*n-1) # Is downward diagonal[x+y] safe? - self.nfound = 0 # Instrumentation - - def solve(self, x=0): # Recursive solver - for y in range(self.n): - if self.safe(x, y): - self.place(x, y) - if x+1 == self.n: - self.display() - else: - self.solve(x+1) - self.remove(x, y) - - def safe(self, x, y): - return not self.row[y] and not self.up[x-y] and not self.down[x+y] - - def place(self, x, y): - self.y[x] = y - self.row[y] = 1 - self.up[x-y] = 1 - self.down[x+y] = 1 - - def remove(self, x, y): - self.y[x] = None - self.row[y] = 0 - self.up[x-y] = 0 - self.down[x+y] = 0 - - silent = 0 # If true, count solutions only - - def display(self): - self.nfound = self.nfound + 1 - if self.silent: - return - print('+-' + '--'*self.n + '+') - for y in range(self.n-1, -1, -1): - print('|', end=' ') - for x in range(self.n): - if self.y[x] == y: - print("Q", end=' ') - else: - print(".", end=' ') - print('|') - print('+-' + '--'*self.n + '+') - -def main(): - import sys - silent = 0 - n = N - if sys.argv[1:2] == ['-n']: - silent = 1 - del sys.argv[1] - if sys.argv[1:]: - n = int(sys.argv[1]) - q = Queens(n) - q.silent = silent - q.solve() - print("Found", q.nfound, "solutions.") - -if __name__ == "__main__": - main() diff --git a/Tools/demo/redemo.py b/Tools/demo/redemo.py deleted file mode 100755 index f801dfce..00000000 --- a/Tools/demo/redemo.py +++ /dev/null @@ -1,171 +0,0 @@ -#!/usr/bin/env python3 - -"""Basic regular expression demonstration facility (Perl style syntax).""" - -from tkinter import * -import re - -class ReDemo: - - def __init__(self, master): - self.master = master - - self.promptdisplay = Label(self.master, anchor=W, - text="Enter a Perl-style regular expression:") - self.promptdisplay.pack(side=TOP, fill=X) - - self.regexdisplay = Entry(self.master) - self.regexdisplay.pack(fill=X) - self.regexdisplay.focus_set() - - self.addoptions() - - self.statusdisplay = Label(self.master, text="", anchor=W) - self.statusdisplay.pack(side=TOP, fill=X) - - self.labeldisplay = Label(self.master, anchor=W, - text="Enter a string to search:") - self.labeldisplay.pack(fill=X) - self.labeldisplay.pack(fill=X) - - self.showframe = Frame(master) - self.showframe.pack(fill=X, anchor=W) - - self.showvar = StringVar(master) - self.showvar.set("first") - - self.showfirstradio = Radiobutton(self.showframe, - text="Highlight first match", - variable=self.showvar, - value="first", - command=self.recompile) - self.showfirstradio.pack(side=LEFT) - - self.showallradio = Radiobutton(self.showframe, - text="Highlight all matches", - variable=self.showvar, - value="all", - command=self.recompile) - self.showallradio.pack(side=LEFT) - - self.stringdisplay = Text(self.master, width=60, height=4) - self.stringdisplay.pack(fill=BOTH, expand=1) - self.stringdisplay.tag_configure("hit", background="yellow") - - self.grouplabel = Label(self.master, text="Groups:", anchor=W) - self.grouplabel.pack(fill=X) - - self.grouplist = Listbox(self.master) - self.grouplist.pack(expand=1, fill=BOTH) - - self.regexdisplay.bind('<Key>', self.recompile) - self.stringdisplay.bind('<Key>', self.reevaluate) - - self.compiled = None - self.recompile() - - btags = self.regexdisplay.bindtags() - self.regexdisplay.bindtags(btags[1:] + btags[:1]) - - btags = self.stringdisplay.bindtags() - self.stringdisplay.bindtags(btags[1:] + btags[:1]) - - def addoptions(self): - self.frames = [] - self.boxes = [] - self.vars = [] - for name in ('IGNORECASE', - 'MULTILINE', - 'DOTALL', - 'VERBOSE'): - if len(self.boxes) % 3 == 0: - frame = Frame(self.master) - frame.pack(fill=X) - self.frames.append(frame) - val = getattr(re, name).value - var = IntVar() - box = Checkbutton(frame, - variable=var, text=name, - offvalue=0, onvalue=val, - command=self.recompile) - box.pack(side=LEFT) - self.boxes.append(box) - self.vars.append(var) - - def getflags(self): - flags = 0 - for var in self.vars: - flags = flags | var.get() - return flags - - def recompile(self, event=None): - try: - self.compiled = re.compile(self.regexdisplay.get(), - self.getflags()) - bg = self.promptdisplay['background'] - self.statusdisplay.config(text="", background=bg) - except re.error as msg: - self.compiled = None - self.statusdisplay.config( - text="re.error: %s" % str(msg), - background="red") - self.reevaluate() - - def reevaluate(self, event=None): - try: - self.stringdisplay.tag_remove("hit", "1.0", END) - except TclError: - pass - try: - self.stringdisplay.tag_remove("hit0", "1.0", END) - except TclError: - pass - self.grouplist.delete(0, END) - if not self.compiled: - return - self.stringdisplay.tag_configure("hit", background="yellow") - self.stringdisplay.tag_configure("hit0", background="orange") - text = self.stringdisplay.get("1.0", END) - last = 0 - nmatches = 0 - while last <= len(text): - m = self.compiled.search(text, last) - if m is None: - break - first, last = m.span() - if last == first: - last = first+1 - tag = "hit0" - else: - tag = "hit" - pfirst = "1.0 + %d chars" % first - plast = "1.0 + %d chars" % last - self.stringdisplay.tag_add(tag, pfirst, plast) - if nmatches == 0: - self.stringdisplay.yview_pickplace(pfirst) - groups = list(m.groups()) - groups.insert(0, m.group()) - for i in range(len(groups)): - g = "%2d: %r" % (i, groups[i]) - self.grouplist.insert(END, g) - nmatches = nmatches + 1 - if self.showvar.get() == "first": - break - - if nmatches == 0: - self.statusdisplay.config(text="(no match)", - background="yellow") - else: - self.statusdisplay.config(text="") - - -# Main function, run when invoked as a stand-alone Python program. - -def main(): - root = Tk() - demo = ReDemo(root) - root.protocol('WM_DELETE_WINDOW', root.quit) - root.mainloop() - -if __name__ == '__main__': - main() diff --git a/Tools/demo/rpython.py b/Tools/demo/rpython.py deleted file mode 100755 index 11f72cb3..00000000 --- a/Tools/demo/rpython.py +++ /dev/null @@ -1,37 +0,0 @@ -#!/usr/bin/env python3 - -""" -Remote python client. -Execute Python commands remotely and send output back. -""" - -import sys -from socket import socket, AF_INET, SOCK_STREAM, SHUT_WR - -PORT = 4127 -BUFSIZE = 1024 - -def main(): - if len(sys.argv) < 3: - print("usage: rpython host command") - sys.exit(2) - host = sys.argv[1] - port = PORT - i = host.find(':') - if i >= 0: - port = int(host[i+1:]) - host = host[:i] - command = ' '.join(sys.argv[2:]) - with socket(AF_INET, SOCK_STREAM) as s: - s.connect((host, port)) - s.send(command.encode()) - s.shutdown(SHUT_WR) - reply = b'' - while True: - data = s.recv(BUFSIZE) - if not data: - break - reply += data - print(reply.decode(), end=' ') - -main() diff --git a/Tools/demo/rpythond.py b/Tools/demo/rpythond.py deleted file mode 100755 index 4e47fb9e..00000000 --- a/Tools/demo/rpythond.py +++ /dev/null @@ -1,58 +0,0 @@ -#!/usr/bin/env python3 - -""" -Remote python server. -Execute Python commands remotely and send output back. - -WARNING: This version has a gaping security hole -- it accepts requests -from any host on the internet! -""" - -import sys -from socket import socket, AF_INET, SOCK_STREAM -import io -import traceback - -PORT = 4127 -BUFSIZE = 1024 - -def main(): - if len(sys.argv) > 1: - port = int(sys.argv[1]) - else: - port = PORT - s = socket(AF_INET, SOCK_STREAM) - s.bind(('', port)) - s.listen(1) - while True: - conn, (remotehost, remoteport) = s.accept() - with conn: - print('connection from', remotehost, remoteport) - request = b'' - while True: - data = conn.recv(BUFSIZE) - if not data: - break - request += data - reply = execute(request.decode()) - conn.send(reply.encode()) - -def execute(request): - stdout = sys.stdout - stderr = sys.stderr - sys.stdout = sys.stderr = fakefile = io.StringIO() - try: - try: - exec(request, {}, {}) - except: - print() - traceback.print_exc(100) - finally: - sys.stderr = stderr - sys.stdout = stdout - return fakefile.getvalue() - -try: - main() -except KeyboardInterrupt: - pass diff --git a/Tools/demo/sortvisu.py b/Tools/demo/sortvisu.py deleted file mode 100755 index 056a0e05..00000000 --- a/Tools/demo/sortvisu.py +++ /dev/null @@ -1,635 +0,0 @@ -#!/usr/bin/env python3 - -""" -Sorting algorithms visualizer using Tkinter. - -This module is comprised of three ``components'': - -- an array visualizer with methods that implement basic sorting -operations (compare, swap) as well as methods for ``annotating'' the -sorting algorithm (e.g. to show the pivot element); - -- a number of sorting algorithms (currently quicksort, insertion sort, -selection sort and bubble sort, as well as a randomization function), -all using the array visualizer for its basic operations and with calls -to its annotation methods; - -- and a ``driver'' class which can be used as a Grail applet or as a -stand-alone application. -""" - -from tkinter import * -import random - -XGRID = 10 -YGRID = 10 -WIDTH = 6 - - -class Array: - - class Cancelled(BaseException): - pass - - def __init__(self, master, data=None): - self.master = master - self.frame = Frame(self.master) - self.frame.pack(fill=X) - self.label = Label(self.frame) - self.label.pack() - self.canvas = Canvas(self.frame) - self.canvas.pack() - self.report = Label(self.frame) - self.report.pack() - self.left = self.canvas.create_line(0, 0, 0, 0) - self.right = self.canvas.create_line(0, 0, 0, 0) - self.pivot = self.canvas.create_line(0, 0, 0, 0) - self.items = [] - self.size = self.maxvalue = 0 - if data: - self.setdata(data) - - def setdata(self, data): - olditems = self.items - self.items = [] - for item in olditems: - item.delete() - self.size = len(data) - self.maxvalue = max(data) - self.canvas.config(width=(self.size+1)*XGRID, - height=(self.maxvalue+1)*YGRID) - for i in range(self.size): - self.items.append(ArrayItem(self, i, data[i])) - self.reset("Sort demo, size %d" % self.size) - - speed = "normal" - - def setspeed(self, speed): - self.speed = speed - - def destroy(self): - self.frame.destroy() - - in_mainloop = 0 - stop_mainloop = 0 - - def cancel(self): - self.stop_mainloop = 1 - if self.in_mainloop: - self.master.quit() - - def step(self): - if self.in_mainloop: - self.master.quit() - - def wait(self, msecs): - if self.speed == "fastest": - msecs = 0 - elif self.speed == "fast": - msecs = msecs//10 - elif self.speed == "single-step": - msecs = 1000000000 - if not self.stop_mainloop: - self.master.update() - id = self.master.after(msecs, self.master.quit) - self.in_mainloop = 1 - self.master.mainloop() - self.master.after_cancel(id) - self.in_mainloop = 0 - if self.stop_mainloop: - self.stop_mainloop = 0 - self.message("Cancelled") - raise Array.Cancelled - - def getsize(self): - return self.size - - def show_partition(self, first, last): - for i in range(self.size): - item = self.items[i] - if first <= i < last: - self.canvas.itemconfig(item, fill='red') - else: - self.canvas.itemconfig(item, fill='orange') - self.hide_left_right_pivot() - - def hide_partition(self): - for i in range(self.size): - item = self.items[i] - self.canvas.itemconfig(item, fill='red') - self.hide_left_right_pivot() - - def show_left(self, left): - if not 0 <= left < self.size: - self.hide_left() - return - x1, y1, x2, y2 = self.items[left].position() -## top, bot = HIRO - self.canvas.coords(self.left, (x1 - 2, 0, x1 - 2, 9999)) - self.master.update() - - def show_right(self, right): - if not 0 <= right < self.size: - self.hide_right() - return - x1, y1, x2, y2 = self.items[right].position() - self.canvas.coords(self.right, (x2 + 2, 0, x2 + 2, 9999)) - self.master.update() - - def hide_left_right_pivot(self): - self.hide_left() - self.hide_right() - self.hide_pivot() - - def hide_left(self): - self.canvas.coords(self.left, (0, 0, 0, 0)) - - def hide_right(self): - self.canvas.coords(self.right, (0, 0, 0, 0)) - - def show_pivot(self, pivot): - x1, y1, x2, y2 = self.items[pivot].position() - self.canvas.coords(self.pivot, (0, y1 - 2, 9999, y1 - 2)) - - def hide_pivot(self): - self.canvas.coords(self.pivot, (0, 0, 0, 0)) - - def swap(self, i, j): - if i == j: return - self.countswap() - item = self.items[i] - other = self.items[j] - self.items[i], self.items[j] = other, item - item.swapwith(other) - - def compare(self, i, j): - self.countcompare() - item = self.items[i] - other = self.items[j] - return item.compareto(other) - - def reset(self, msg): - self.ncompares = 0 - self.nswaps = 0 - self.message(msg) - self.updatereport() - self.hide_partition() - - def message(self, msg): - self.label.config(text=msg) - - def countswap(self): - self.nswaps = self.nswaps + 1 - self.updatereport() - - def countcompare(self): - self.ncompares = self.ncompares + 1 - self.updatereport() - - def updatereport(self): - text = "%d cmps, %d swaps" % (self.ncompares, self.nswaps) - self.report.config(text=text) - - -class ArrayItem: - - def __init__(self, array, index, value): - self.array = array - self.index = index - self.value = value - self.canvas = array.canvas - x1, y1, x2, y2 = self.position() - self.item_id = array.canvas.create_rectangle(x1, y1, x2, y2, - fill='red', outline='black', width=1) - self.canvas.tag_bind(self.item_id, '<Button-1>', self.mouse_down) - self.canvas.tag_bind(self.item_id, '<Button1-Motion>', self.mouse_move) - self.canvas.tag_bind(self.item_id, '<ButtonRelease-1>', self.mouse_up) - - def delete(self): - item_id = self.item_id - self.array = None - self.item_id = None - self.canvas.delete(item_id) - - def mouse_down(self, event): - self.lastx = event.x - self.lasty = event.y - self.origx = event.x - self.origy = event.y - self.canvas.tag_raise(self.item_id) - - def mouse_move(self, event): - self.canvas.move(self.item_id, - event.x - self.lastx, event.y - self.lasty) - self.lastx = event.x - self.lasty = event.y - - def mouse_up(self, event): - i = self.nearestindex(event.x) - if i >= self.array.getsize(): - i = self.array.getsize() - 1 - if i < 0: - i = 0 - other = self.array.items[i] - here = self.index - self.array.items[here], self.array.items[i] = other, self - self.index = i - x1, y1, x2, y2 = self.position() - self.canvas.coords(self.item_id, (x1, y1, x2, y2)) - other.setindex(here) - - def setindex(self, index): - nsteps = steps(self.index, index) - if not nsteps: return - if self.array.speed == "fastest": - nsteps = 0 - oldpts = self.position() - self.index = index - newpts = self.position() - trajectory = interpolate(oldpts, newpts, nsteps) - self.canvas.tag_raise(self.item_id) - for pts in trajectory: - self.canvas.coords(self.item_id, pts) - self.array.wait(50) - - def swapwith(self, other): - nsteps = steps(self.index, other.index) - if not nsteps: return - if self.array.speed == "fastest": - nsteps = 0 - myoldpts = self.position() - otheroldpts = other.position() - self.index, other.index = other.index, self.index - mynewpts = self.position() - othernewpts = other.position() - myfill = self.canvas.itemcget(self.item_id, 'fill') - otherfill = self.canvas.itemcget(other.item_id, 'fill') - self.canvas.itemconfig(self.item_id, fill='green') - self.canvas.itemconfig(other.item_id, fill='yellow') - self.array.master.update() - if self.array.speed == "single-step": - self.canvas.coords(self.item_id, mynewpts) - self.canvas.coords(other.item_id, othernewpts) - self.array.master.update() - self.canvas.itemconfig(self.item_id, fill=myfill) - self.canvas.itemconfig(other.item_id, fill=otherfill) - self.array.wait(0) - return - mytrajectory = interpolate(myoldpts, mynewpts, nsteps) - othertrajectory = interpolate(otheroldpts, othernewpts, nsteps) - if self.value > other.value: - self.canvas.tag_raise(self.item_id) - self.canvas.tag_raise(other.item_id) - else: - self.canvas.tag_raise(other.item_id) - self.canvas.tag_raise(self.item_id) - try: - for i in range(len(mytrajectory)): - mypts = mytrajectory[i] - otherpts = othertrajectory[i] - self.canvas.coords(self.item_id, mypts) - self.canvas.coords(other.item_id, otherpts) - self.array.wait(50) - finally: - mypts = mytrajectory[-1] - otherpts = othertrajectory[-1] - self.canvas.coords(self.item_id, mypts) - self.canvas.coords(other.item_id, otherpts) - self.canvas.itemconfig(self.item_id, fill=myfill) - self.canvas.itemconfig(other.item_id, fill=otherfill) - - def compareto(self, other): - myfill = self.canvas.itemcget(self.item_id, 'fill') - otherfill = self.canvas.itemcget(other.item_id, 'fill') - if self.value < other.value: - myflash = 'white' - otherflash = 'black' - outcome = -1 - elif self.value > other.value: - myflash = 'black' - otherflash = 'white' - outcome = 1 - else: - myflash = otherflash = 'grey' - outcome = 0 - try: - self.canvas.itemconfig(self.item_id, fill=myflash) - self.canvas.itemconfig(other.item_id, fill=otherflash) - self.array.wait(500) - finally: - self.canvas.itemconfig(self.item_id, fill=myfill) - self.canvas.itemconfig(other.item_id, fill=otherfill) - return outcome - - def position(self): - x1 = (self.index+1)*XGRID - WIDTH//2 - x2 = x1+WIDTH - y2 = (self.array.maxvalue+1)*YGRID - y1 = y2 - (self.value)*YGRID - return x1, y1, x2, y2 - - def nearestindex(self, x): - return int(round(float(x)/XGRID)) - 1 - - -# Subroutines that don't need an object - -def steps(here, there): - nsteps = abs(here - there) - if nsteps <= 3: - nsteps = nsteps * 3 - elif nsteps <= 5: - nsteps = nsteps * 2 - elif nsteps > 10: - nsteps = 10 - return nsteps - -def interpolate(oldpts, newpts, n): - if len(oldpts) != len(newpts): - raise ValueError("can't interpolate arrays of different length") - pts = [0]*len(oldpts) - res = [tuple(oldpts)] - for i in range(1, n): - for k in range(len(pts)): - pts[k] = oldpts[k] + (newpts[k] - oldpts[k])*i//n - res.append(tuple(pts)) - res.append(tuple(newpts)) - return res - - -# Various (un)sorting algorithms - -def uniform(array): - size = array.getsize() - array.setdata([(size+1)//2] * size) - array.reset("Uniform data, size %d" % size) - -def distinct(array): - size = array.getsize() - array.setdata(range(1, size+1)) - array.reset("Distinct data, size %d" % size) - -def randomize(array): - array.reset("Randomizing") - n = array.getsize() - for i in range(n): - j = random.randint(0, n-1) - array.swap(i, j) - array.message("Randomized") - -def insertionsort(array): - size = array.getsize() - array.reset("Insertion sort") - for i in range(1, size): - j = i-1 - while j >= 0: - if array.compare(j, j+1) <= 0: - break - array.swap(j, j+1) - j = j-1 - array.message("Sorted") - -def selectionsort(array): - size = array.getsize() - array.reset("Selection sort") - try: - for i in range(size): - array.show_partition(i, size) - for j in range(i+1, size): - if array.compare(i, j) > 0: - array.swap(i, j) - array.message("Sorted") - finally: - array.hide_partition() - -def bubblesort(array): - size = array.getsize() - array.reset("Bubble sort") - for i in range(size): - for j in range(1, size): - if array.compare(j-1, j) > 0: - array.swap(j-1, j) - array.message("Sorted") - -def quicksort(array): - size = array.getsize() - array.reset("Quicksort") - try: - stack = [(0, size)] - while stack: - first, last = stack[-1] - del stack[-1] - array.show_partition(first, last) - if last-first < 5: - array.message("Insertion sort") - for i in range(first+1, last): - j = i-1 - while j >= first: - if array.compare(j, j+1) <= 0: - break - array.swap(j, j+1) - j = j-1 - continue - array.message("Choosing pivot") - j, i, k = first, (first+last) // 2, last-1 - if array.compare(k, i) < 0: - array.swap(k, i) - if array.compare(k, j) < 0: - array.swap(k, j) - if array.compare(j, i) < 0: - array.swap(j, i) - pivot = j - array.show_pivot(pivot) - array.message("Pivot at left of partition") - array.wait(1000) - left = first - right = last - while True: - array.message("Sweep right pointer") - right = right-1 - array.show_right(right) - while right > first and array.compare(right, pivot) >= 0: - right = right-1 - array.show_right(right) - array.message("Sweep left pointer") - left = left+1 - array.show_left(left) - while left < last and array.compare(left, pivot) <= 0: - left = left+1 - array.show_left(left) - if left > right: - array.message("End of partition") - break - array.message("Swap items") - array.swap(left, right) - array.message("Swap pivot back") - array.swap(pivot, right) - n1 = right-first - n2 = last-left - if n1 > 1: stack.append((first, right)) - if n2 > 1: stack.append((left, last)) - array.message("Sorted") - finally: - array.hide_partition() - -def demosort(array): - while True: - for alg in [quicksort, insertionsort, selectionsort, bubblesort]: - randomize(array) - alg(array) - - -# Sort demo class -- usable as a Grail applet - -class SortDemo: - - def __init__(self, master, size=15): - self.master = master - self.size = size - self.busy = 0 - self.array = Array(self.master) - - self.botframe = Frame(master) - self.botframe.pack(side=BOTTOM) - self.botleftframe = Frame(self.botframe) - self.botleftframe.pack(side=LEFT, fill=Y) - self.botrightframe = Frame(self.botframe) - self.botrightframe.pack(side=RIGHT, fill=Y) - - self.b_qsort = Button(self.botleftframe, - text="Quicksort", command=self.c_qsort) - self.b_qsort.pack(fill=X) - self.b_isort = Button(self.botleftframe, - text="Insertion sort", command=self.c_isort) - self.b_isort.pack(fill=X) - self.b_ssort = Button(self.botleftframe, - text="Selection sort", command=self.c_ssort) - self.b_ssort.pack(fill=X) - self.b_bsort = Button(self.botleftframe, - text="Bubble sort", command=self.c_bsort) - self.b_bsort.pack(fill=X) - - # Terrible hack to overcome limitation of OptionMenu... - class MyIntVar(IntVar): - def __init__(self, master, demo): - self.demo = demo - IntVar.__init__(self, master) - def set(self, value): - IntVar.set(self, value) - if str(value) != '0': - self.demo.resize(value) - - self.v_size = MyIntVar(self.master, self) - self.v_size.set(size) - sizes = [1, 2, 3, 4] + list(range(5, 55, 5)) - if self.size not in sizes: - sizes.append(self.size) - sizes.sort() - self.m_size = OptionMenu(self.botleftframe, self.v_size, *sizes) - self.m_size.pack(fill=X) - - self.v_speed = StringVar(self.master) - self.v_speed.set("normal") - self.m_speed = OptionMenu(self.botleftframe, self.v_speed, - "single-step", "normal", "fast", "fastest") - self.m_speed.pack(fill=X) - - self.b_step = Button(self.botleftframe, - text="Step", command=self.c_step) - self.b_step.pack(fill=X) - - self.b_randomize = Button(self.botrightframe, - text="Randomize", command=self.c_randomize) - self.b_randomize.pack(fill=X) - self.b_uniform = Button(self.botrightframe, - text="Uniform", command=self.c_uniform) - self.b_uniform.pack(fill=X) - self.b_distinct = Button(self.botrightframe, - text="Distinct", command=self.c_distinct) - self.b_distinct.pack(fill=X) - self.b_demo = Button(self.botrightframe, - text="Demo", command=self.c_demo) - self.b_demo.pack(fill=X) - self.b_cancel = Button(self.botrightframe, - text="Cancel", command=self.c_cancel) - self.b_cancel.pack(fill=X) - self.b_cancel.config(state=DISABLED) - self.b_quit = Button(self.botrightframe, - text="Quit", command=self.c_quit) - self.b_quit.pack(fill=X) - - def resize(self, newsize): - if self.busy: - self.master.bell() - return - self.size = newsize - self.array.setdata(range(1, self.size+1)) - - def c_qsort(self): - self.run(quicksort) - - def c_isort(self): - self.run(insertionsort) - - def c_ssort(self): - self.run(selectionsort) - - def c_bsort(self): - self.run(bubblesort) - - def c_demo(self): - self.run(demosort) - - def c_randomize(self): - self.run(randomize) - - def c_uniform(self): - self.run(uniform) - - def c_distinct(self): - self.run(distinct) - - def run(self, func): - if self.busy: - self.master.bell() - return - self.busy = 1 - self.array.setspeed(self.v_speed.get()) - self.b_cancel.config(state=NORMAL) - try: - func(self.array) - except Array.Cancelled: - pass - self.b_cancel.config(state=DISABLED) - self.busy = 0 - - def c_cancel(self): - if not self.busy: - self.master.bell() - return - self.array.cancel() - - def c_step(self): - if not self.busy: - self.master.bell() - return - self.v_speed.set("single-step") - self.array.setspeed("single-step") - self.array.step() - - def c_quit(self): - if self.busy: - self.array.cancel() - self.master.after_idle(self.master.quit) - - -# Main program -- for stand-alone operation outside Grail - -def main(): - root = Tk() - demo = SortDemo(root) - root.protocol('WM_DELETE_WINDOW', demo.c_quit) - root.mainloop() - -if __name__ == '__main__': - main() diff --git a/Tools/demo/spreadsheet.py b/Tools/demo/spreadsheet.py deleted file mode 100755 index bf88820d..00000000 --- a/Tools/demo/spreadsheet.py +++ /dev/null @@ -1,829 +0,0 @@ -#!/usr/bin/env python3 - -""" -SS1 -- a spreadsheet-like application. -""" - -import os -import re -import sys -from xml.parsers import expat -from xml.sax.saxutils import escape - -LEFT, CENTER, RIGHT = "LEFT", "CENTER", "RIGHT" - -def ljust(x, n): - return x.ljust(n) -def center(x, n): - return x.center(n) -def rjust(x, n): - return x.rjust(n) -align2action = {LEFT: ljust, CENTER: center, RIGHT: rjust} - -align2xml = {LEFT: "left", CENTER: "center", RIGHT: "right"} -xml2align = {"left": LEFT, "center": CENTER, "right": RIGHT} - -align2anchor = {LEFT: "w", CENTER: "center", RIGHT: "e"} - -def sum(seq): - total = 0 - for x in seq: - if x is not None: - total += x - return total - -class Sheet: - - def __init__(self): - self.cells = {} # {(x, y): cell, ...} - self.ns = dict( - cell = self.cellvalue, - cells = self.multicellvalue, - sum = sum, - ) - - def cellvalue(self, x, y): - cell = self.getcell(x, y) - if hasattr(cell, 'recalc'): - return cell.recalc(self.ns) - else: - return cell - - def multicellvalue(self, x1, y1, x2, y2): - if x1 > x2: - x1, x2 = x2, x1 - if y1 > y2: - y1, y2 = y2, y1 - seq = [] - for y in range(y1, y2+1): - for x in range(x1, x2+1): - seq.append(self.cellvalue(x, y)) - return seq - - def getcell(self, x, y): - return self.cells.get((x, y)) - - def setcell(self, x, y, cell): - assert x > 0 and y > 0 - assert isinstance(cell, BaseCell) - self.cells[x, y] = cell - - def clearcell(self, x, y): - try: - del self.cells[x, y] - except KeyError: - pass - - def clearcells(self, x1, y1, x2, y2): - for xy in self.selectcells(x1, y1, x2, y2): - del self.cells[xy] - - def clearrows(self, y1, y2): - self.clearcells(0, y1, sys.maxsize, y2) - - def clearcolumns(self, x1, x2): - self.clearcells(x1, 0, x2, sys.maxsize) - - def selectcells(self, x1, y1, x2, y2): - if x1 > x2: - x1, x2 = x2, x1 - if y1 > y2: - y1, y2 = y2, y1 - return [(x, y) for x, y in self.cells - if x1 <= x <= x2 and y1 <= y <= y2] - - def movecells(self, x1, y1, x2, y2, dx, dy): - if dx == 0 and dy == 0: - return - if x1 > x2: - x1, x2 = x2, x1 - if y1 > y2: - y1, y2 = y2, y1 - assert x1+dx > 0 and y1+dy > 0 - new = {} - for x, y in self.cells: - cell = self.cells[x, y] - if hasattr(cell, 'renumber'): - cell = cell.renumber(x1, y1, x2, y2, dx, dy) - if x1 <= x <= x2 and y1 <= y <= y2: - x += dx - y += dy - new[x, y] = cell - self.cells = new - - def insertrows(self, y, n): - assert n > 0 - self.movecells(0, y, sys.maxsize, sys.maxsize, 0, n) - - def deleterows(self, y1, y2): - if y1 > y2: - y1, y2 = y2, y1 - self.clearrows(y1, y2) - self.movecells(0, y2+1, sys.maxsize, sys.maxsize, 0, y1-y2-1) - - def insertcolumns(self, x, n): - assert n > 0 - self.movecells(x, 0, sys.maxsize, sys.maxsize, n, 0) - - def deletecolumns(self, x1, x2): - if x1 > x2: - x1, x2 = x2, x1 - self.clearcells(x1, x2) - self.movecells(x2+1, 0, sys.maxsize, sys.maxsize, x1-x2-1, 0) - - def getsize(self): - maxx = maxy = 0 - for x, y in self.cells: - maxx = max(maxx, x) - maxy = max(maxy, y) - return maxx, maxy - - def reset(self): - for cell in self.cells.values(): - if hasattr(cell, 'reset'): - cell.reset() - - def recalc(self): - self.reset() - for cell in self.cells.values(): - if hasattr(cell, 'recalc'): - cell.recalc(self.ns) - - def display(self): - maxx, maxy = self.getsize() - width, height = maxx+1, maxy+1 - colwidth = [1] * width - full = {} - # Add column heading labels in row 0 - for x in range(1, width): - full[x, 0] = text, alignment = colnum2name(x), RIGHT - colwidth[x] = max(colwidth[x], len(text)) - # Add row labels in column 0 - for y in range(1, height): - full[0, y] = text, alignment = str(y), RIGHT - colwidth[0] = max(colwidth[0], len(text)) - # Add sheet cells in columns with x>0 and y>0 - for (x, y), cell in self.cells.items(): - if x <= 0 or y <= 0: - continue - if hasattr(cell, 'recalc'): - cell.recalc(self.ns) - if hasattr(cell, 'format'): - text, alignment = cell.format() - assert isinstance(text, str) - assert alignment in (LEFT, CENTER, RIGHT) - else: - text = str(cell) - if isinstance(cell, str): - alignment = LEFT - else: - alignment = RIGHT - full[x, y] = (text, alignment) - colwidth[x] = max(colwidth[x], len(text)) - # Calculate the horizontal separator line (dashes and dots) - sep = "" - for x in range(width): - if sep: - sep += "+" - sep += "-"*colwidth[x] - # Now print The full grid - for y in range(height): - line = "" - for x in range(width): - text, alignment = full.get((x, y)) or ("", LEFT) - text = align2action[alignment](text, colwidth[x]) - if line: - line += '|' - line += text - print(line) - if y == 0: - print(sep) - - def xml(self): - out = ['<spreadsheet>'] - for (x, y), cell in self.cells.items(): - if hasattr(cell, 'xml'): - cellxml = cell.xml() - else: - cellxml = '<value>%s</value>' % escape(cell) - out.append('<cell row="%s" col="%s">\n %s\n</cell>' % - (y, x, cellxml)) - out.append('</spreadsheet>') - return '\n'.join(out) - - def save(self, filename): - text = self.xml() - with open(filename, "w", encoding='utf-8') as f: - f.write(text) - if text and not text.endswith('\n'): - f.write('\n') - - def load(self, filename): - with open(filename, 'rb') as f: - SheetParser(self).parsefile(f) - -class SheetParser: - - def __init__(self, sheet): - self.sheet = sheet - - def parsefile(self, f): - parser = expat.ParserCreate() - parser.StartElementHandler = self.startelement - parser.EndElementHandler = self.endelement - parser.CharacterDataHandler = self.data - parser.ParseFile(f) - - def startelement(self, tag, attrs): - method = getattr(self, 'start_'+tag, None) - if method: - method(attrs) - self.texts = [] - - def data(self, text): - self.texts.append(text) - - def endelement(self, tag): - method = getattr(self, 'end_'+tag, None) - if method: - method("".join(self.texts)) - - def start_cell(self, attrs): - self.y = int(attrs.get("row")) - self.x = int(attrs.get("col")) - - def start_value(self, attrs): - self.fmt = attrs.get('format') - self.alignment = xml2align.get(attrs.get('align')) - - start_formula = start_value - - def end_int(self, text): - try: - self.value = int(text) - except (TypeError, ValueError): - self.value = None - - end_long = end_int - - def end_double(self, text): - try: - self.value = float(text) - except (TypeError, ValueError): - self.value = None - - def end_complex(self, text): - try: - self.value = complex(text) - except (TypeError, ValueError): - self.value = None - - def end_string(self, text): - self.value = text - - def end_value(self, text): - if isinstance(self.value, BaseCell): - self.cell = self.value - elif isinstance(self.value, str): - self.cell = StringCell(self.value, - self.fmt or "%s", - self.alignment or LEFT) - else: - self.cell = NumericCell(self.value, - self.fmt or "%s", - self.alignment or RIGHT) - - def end_formula(self, text): - self.cell = FormulaCell(text, - self.fmt or "%s", - self.alignment or RIGHT) - - def end_cell(self, text): - self.sheet.setcell(self.x, self.y, self.cell) - -class BaseCell: - __init__ = None # Must provide - """Abstract base class for sheet cells. - - Subclasses may but needn't provide the following APIs: - - cell.reset() -- prepare for recalculation - cell.recalc(ns) -> value -- recalculate formula - cell.format() -> (value, alignment) -- return formatted value - cell.xml() -> string -- return XML - """ - -class NumericCell(BaseCell): - - def __init__(self, value, fmt="%s", alignment=RIGHT): - assert isinstance(value, (int, float, complex)) - assert alignment in (LEFT, CENTER, RIGHT) - self.value = value - self.fmt = fmt - self.alignment = alignment - - def recalc(self, ns): - return self.value - - def format(self): - try: - text = self.fmt % self.value - except: - text = str(self.value) - return text, self.alignment - - def xml(self): - method = getattr(self, '_xml_' + type(self.value).__name__) - return '<value align="%s" format="%s">%s</value>' % ( - align2xml[self.alignment], - self.fmt, - method()) - - def _xml_int(self): - if -2**31 <= self.value < 2**31: - return '<int>%s</int>' % self.value - else: - return '<long>%s</long>' % self.value - - def _xml_float(self): - return '<double>%r</double>' % self.value - - def _xml_complex(self): - return '<complex>%r</complex>' % self.value - -class StringCell(BaseCell): - - def __init__(self, text, fmt="%s", alignment=LEFT): - assert isinstance(text, str) - assert alignment in (LEFT, CENTER, RIGHT) - self.text = text - self.fmt = fmt - self.alignment = alignment - - def recalc(self, ns): - return self.text - - def format(self): - return self.text, self.alignment - - def xml(self): - s = '<value align="%s" format="%s"><string>%s</string></value>' - return s % ( - align2xml[self.alignment], - self.fmt, - escape(self.text)) - -class FormulaCell(BaseCell): - - def __init__(self, formula, fmt="%s", alignment=RIGHT): - assert alignment in (LEFT, CENTER, RIGHT) - self.formula = formula - self.translated = translate(self.formula) - self.fmt = fmt - self.alignment = alignment - self.reset() - - def reset(self): - self.value = None - - def recalc(self, ns): - if self.value is None: - try: - self.value = eval(self.translated, ns) - except: - exc = sys.exc_info()[0] - if hasattr(exc, "__name__"): - self.value = exc.__name__ - else: - self.value = str(exc) - return self.value - - def format(self): - try: - text = self.fmt % self.value - except: - text = str(self.value) - return text, self.alignment - - def xml(self): - return '<formula align="%s" format="%s">%s</formula>' % ( - align2xml[self.alignment], - self.fmt, - escape(self.formula)) - - def renumber(self, x1, y1, x2, y2, dx, dy): - out = [] - for part in re.split(r'(\w+)', self.formula): - m = re.match('^([A-Z]+)([1-9][0-9]*)$', part) - if m is not None: - sx, sy = m.groups() - x = colname2num(sx) - y = int(sy) - if x1 <= x <= x2 and y1 <= y <= y2: - part = cellname(x+dx, y+dy) - out.append(part) - return FormulaCell("".join(out), self.fmt, self.alignment) - -def translate(formula): - """Translate a formula containing fancy cell names to valid Python code. - - Examples: - B4 -> cell(2, 4) - B4:Z100 -> cells(2, 4, 26, 100) - """ - out = [] - for part in re.split(r"(\w+(?::\w+)?)", formula): - m = re.match(r"^([A-Z]+)([1-9][0-9]*)(?::([A-Z]+)([1-9][0-9]*))?$", part) - if m is None: - out.append(part) - else: - x1, y1, x2, y2 = m.groups() - x1 = colname2num(x1) - if x2 is None: - s = "cell(%s, %s)" % (x1, y1) - else: - x2 = colname2num(x2) - s = "cells(%s, %s, %s, %s)" % (x1, y1, x2, y2) - out.append(s) - return "".join(out) - -def cellname(x, y): - "Translate a cell coordinate to a fancy cell name (e.g. (1, 1)->'A1')." - assert x > 0 # Column 0 has an empty name, so can't use that - return colnum2name(x) + str(y) - -def colname2num(s): - "Translate a column name to number (e.g. 'A'->1, 'Z'->26, 'AA'->27)." - s = s.upper() - n = 0 - for c in s: - assert 'A' <= c <= 'Z' - n = n*26 + ord(c) - ord('A') + 1 - return n - -def colnum2name(n): - "Translate a column number to name (e.g. 1->'A', etc.)." - assert n > 0 - s = "" - while n: - n, m = divmod(n-1, 26) - s = chr(m+ord('A')) + s - return s - -import tkinter as Tk - -class SheetGUI: - - """Beginnings of a GUI for a spreadsheet. - - TO DO: - - clear multiple cells - - Insert, clear, remove rows or columns - - Show new contents while typing - - Scroll bars - - Grow grid when window is grown - - Proper menus - - Undo, redo - - Cut, copy and paste - - Formatting and alignment - """ - - def __init__(self, filename="sheet1.xml", rows=10, columns=5): - """Constructor. - - Load the sheet from the filename argument. - Set up the Tk widget tree. - """ - # Create and load the sheet - self.filename = filename - self.sheet = Sheet() - if os.path.isfile(filename): - self.sheet.load(filename) - # Calculate the needed grid size - maxx, maxy = self.sheet.getsize() - rows = max(rows, maxy) - columns = max(columns, maxx) - # Create the widgets - self.root = Tk.Tk() - self.root.wm_title("Spreadsheet: %s" % self.filename) - self.beacon = Tk.Label(self.root, text="A1", - font=('helvetica', 16, 'bold')) - self.entry = Tk.Entry(self.root) - self.savebutton = Tk.Button(self.root, text="Save", - command=self.save) - self.cellgrid = Tk.Frame(self.root) - # Configure the widget lay-out - self.cellgrid.pack(side="bottom", expand=1, fill="both") - self.beacon.pack(side="left") - self.savebutton.pack(side="right") - self.entry.pack(side="left", expand=1, fill="x") - # Bind some events - self.entry.bind("<Return>", self.return_event) - self.entry.bind("<Shift-Return>", self.shift_return_event) - self.entry.bind("<Tab>", self.tab_event) - self.entry.bind("<Shift-Tab>", self.shift_tab_event) - self.entry.bind("<Delete>", self.delete_event) - self.entry.bind("<Escape>", self.escape_event) - # Now create the cell grid - self.makegrid(rows, columns) - # Select the top-left cell - self.currentxy = None - self.cornerxy = None - self.setcurrent(1, 1) - # Copy the sheet cells to the GUI cells - self.sync() - - def delete_event(self, event): - if self.cornerxy != self.currentxy and self.cornerxy is not None: - self.sheet.clearcells(*(self.currentxy + self.cornerxy)) - else: - self.sheet.clearcell(*self.currentxy) - self.sync() - self.entry.delete(0, 'end') - return "break" - - def escape_event(self, event): - x, y = self.currentxy - self.load_entry(x, y) - - def load_entry(self, x, y): - cell = self.sheet.getcell(x, y) - if cell is None: - text = "" - elif isinstance(cell, FormulaCell): - text = '=' + cell.formula - else: - text, alignment = cell.format() - self.entry.delete(0, 'end') - self.entry.insert(0, text) - self.entry.selection_range(0, 'end') - - def makegrid(self, rows, columns): - """Helper to create the grid of GUI cells. - - The edge (x==0 or y==0) is filled with labels; the rest is real cells. - """ - self.rows = rows - self.columns = columns - self.gridcells = {} - # Create the top left corner cell (which selects all) - cell = Tk.Label(self.cellgrid, relief='raised') - cell.grid_configure(column=0, row=0, sticky='NSWE') - cell.bind("<ButtonPress-1>", self.selectall) - # Create the top row of labels, and configure the grid columns - for x in range(1, columns+1): - self.cellgrid.grid_columnconfigure(x, minsize=64) - cell = Tk.Label(self.cellgrid, text=colnum2name(x), relief='raised') - cell.grid_configure(column=x, row=0, sticky='WE') - self.gridcells[x, 0] = cell - cell.__x = x - cell.__y = 0 - cell.bind("<ButtonPress-1>", self.selectcolumn) - cell.bind("<B1-Motion>", self.extendcolumn) - cell.bind("<ButtonRelease-1>", self.extendcolumn) - cell.bind("<Shift-Button-1>", self.extendcolumn) - # Create the leftmost column of labels - for y in range(1, rows+1): - cell = Tk.Label(self.cellgrid, text=str(y), relief='raised') - cell.grid_configure(column=0, row=y, sticky='WE') - self.gridcells[0, y] = cell - cell.__x = 0 - cell.__y = y - cell.bind("<ButtonPress-1>", self.selectrow) - cell.bind("<B1-Motion>", self.extendrow) - cell.bind("<ButtonRelease-1>", self.extendrow) - cell.bind("<Shift-Button-1>", self.extendrow) - # Create the real cells - for x in range(1, columns+1): - for y in range(1, rows+1): - cell = Tk.Label(self.cellgrid, relief='sunken', - bg='white', fg='black') - cell.grid_configure(column=x, row=y, sticky='NSWE') - self.gridcells[x, y] = cell - cell.__x = x - cell.__y = y - # Bind mouse events - cell.bind("<ButtonPress-1>", self.press) - cell.bind("<B1-Motion>", self.motion) - cell.bind("<ButtonRelease-1>", self.release) - cell.bind("<Shift-Button-1>", self.release) - - def selectall(self, event): - self.setcurrent(1, 1) - self.setcorner(sys.maxsize, sys.maxsize) - - def selectcolumn(self, event): - x, y = self.whichxy(event) - self.setcurrent(x, 1) - self.setcorner(x, sys.maxsize) - - def extendcolumn(self, event): - x, y = self.whichxy(event) - if x > 0: - self.setcurrent(self.currentxy[0], 1) - self.setcorner(x, sys.maxsize) - - def selectrow(self, event): - x, y = self.whichxy(event) - self.setcurrent(1, y) - self.setcorner(sys.maxsize, y) - - def extendrow(self, event): - x, y = self.whichxy(event) - if y > 0: - self.setcurrent(1, self.currentxy[1]) - self.setcorner(sys.maxsize, y) - - def press(self, event): - x, y = self.whichxy(event) - if x > 0 and y > 0: - self.setcurrent(x, y) - - def motion(self, event): - x, y = self.whichxy(event) - if x > 0 and y > 0: - self.setcorner(x, y) - - release = motion - - def whichxy(self, event): - w = self.cellgrid.winfo_containing(event.x_root, event.y_root) - if w is not None and isinstance(w, Tk.Label): - try: - return w.__x, w.__y - except AttributeError: - pass - return 0, 0 - - def save(self): - self.sheet.save(self.filename) - - def setcurrent(self, x, y): - "Make (x, y) the current cell." - if self.currentxy is not None: - self.change_cell() - self.clearfocus() - self.beacon['text'] = cellname(x, y) - self.load_entry(x, y) - self.entry.focus_set() - self.currentxy = x, y - self.cornerxy = None - gridcell = self.gridcells.get(self.currentxy) - if gridcell is not None: - gridcell['bg'] = 'yellow' - - def setcorner(self, x, y): - if self.currentxy is None or self.currentxy == (x, y): - self.setcurrent(x, y) - return - self.clearfocus() - self.cornerxy = x, y - x1, y1 = self.currentxy - x2, y2 = self.cornerxy or self.currentxy - if x1 > x2: - x1, x2 = x2, x1 - if y1 > y2: - y1, y2 = y2, y1 - for (x, y), cell in self.gridcells.items(): - if x1 <= x <= x2 and y1 <= y <= y2: - cell['bg'] = 'lightBlue' - gridcell = self.gridcells.get(self.currentxy) - if gridcell is not None: - gridcell['bg'] = 'yellow' - self.setbeacon(x1, y1, x2, y2) - - def setbeacon(self, x1, y1, x2, y2): - if x1 == y1 == 1 and x2 == y2 == sys.maxsize: - name = ":" - elif (x1, x2) == (1, sys.maxsize): - if y1 == y2: - name = "%d" % y1 - else: - name = "%d:%d" % (y1, y2) - elif (y1, y2) == (1, sys.maxsize): - if x1 == x2: - name = "%s" % colnum2name(x1) - else: - name = "%s:%s" % (colnum2name(x1), colnum2name(x2)) - else: - name1 = cellname(*self.currentxy) - name2 = cellname(*self.cornerxy) - name = "%s:%s" % (name1, name2) - self.beacon['text'] = name - - - def clearfocus(self): - if self.currentxy is not None: - x1, y1 = self.currentxy - x2, y2 = self.cornerxy or self.currentxy - if x1 > x2: - x1, x2 = x2, x1 - if y1 > y2: - y1, y2 = y2, y1 - for (x, y), cell in self.gridcells.items(): - if x1 <= x <= x2 and y1 <= y <= y2: - cell['bg'] = 'white' - - def return_event(self, event): - "Callback for the Return key." - self.change_cell() - x, y = self.currentxy - self.setcurrent(x, y+1) - return "break" - - def shift_return_event(self, event): - "Callback for the Return key with Shift modifier." - self.change_cell() - x, y = self.currentxy - self.setcurrent(x, max(1, y-1)) - return "break" - - def tab_event(self, event): - "Callback for the Tab key." - self.change_cell() - x, y = self.currentxy - self.setcurrent(x+1, y) - return "break" - - def shift_tab_event(self, event): - "Callback for the Tab key with Shift modifier." - self.change_cell() - x, y = self.currentxy - self.setcurrent(max(1, x-1), y) - return "break" - - def change_cell(self): - "Set the current cell from the entry widget." - x, y = self.currentxy - text = self.entry.get() - cell = None - if text.startswith('='): - cell = FormulaCell(text[1:]) - else: - for cls in int, float, complex: - try: - value = cls(text) - except (TypeError, ValueError): - continue - else: - cell = NumericCell(value) - break - if cell is None and text: - cell = StringCell(text) - if cell is None: - self.sheet.clearcell(x, y) - else: - self.sheet.setcell(x, y, cell) - self.sync() - - def sync(self): - "Fill the GUI cells from the sheet cells." - self.sheet.recalc() - for (x, y), gridcell in self.gridcells.items(): - if x == 0 or y == 0: - continue - cell = self.sheet.getcell(x, y) - if cell is None: - gridcell['text'] = "" - else: - if hasattr(cell, 'format'): - text, alignment = cell.format() - else: - text, alignment = str(cell), LEFT - gridcell['text'] = text - gridcell['anchor'] = align2anchor[alignment] - - -def test_basic(): - "Basic non-gui self-test." - a = Sheet() - for x in range(1, 11): - for y in range(1, 11): - if x == 1: - cell = NumericCell(y) - elif y == 1: - cell = NumericCell(x) - else: - c1 = cellname(x, 1) - c2 = cellname(1, y) - formula = "%s*%s" % (c1, c2) - cell = FormulaCell(formula) - a.setcell(x, y, cell) -## if os.path.isfile("sheet1.xml"): -## print "Loading from sheet1.xml" -## a.load("sheet1.xml") - a.display() - a.save("sheet1.xml") - -def test_gui(): - "GUI test." - if sys.argv[1:]: - filename = sys.argv[1] - else: - filename = "sheet1.xml" - g = SheetGUI(filename) - g.root.mainloop() - -if __name__ == '__main__': - #test_basic() - test_gui() diff --git a/Tools/demo/vector.py b/Tools/demo/vector.py deleted file mode 100755 index 6df1f50a..00000000 --- a/Tools/demo/vector.py +++ /dev/null @@ -1,94 +0,0 @@ -#!/usr/bin/env python3 - -""" -A demonstration of classes and their special methods in Python. -""" - -class Vec: - """A simple vector class. - - Instances of the Vec class can be constructed from numbers - - >>> a = Vec(1, 2, 3) - >>> b = Vec(3, 2, 1) - - added - >>> a + b - Vec(4, 4, 4) - - subtracted - >>> a - b - Vec(-2, 0, 2) - - and multiplied by a scalar on the left - >>> 3.0 * a - Vec(3.0, 6.0, 9.0) - - or on the right - >>> a * 3.0 - Vec(3.0, 6.0, 9.0) - - and dot product - >>> a.dot(b) - 10 - - and printed in vector notation - >>> print(a) - <1 2 3> - - """ - - def __init__(self, *v): - self.v = list(v) - - @classmethod - def fromlist(cls, v): - if not isinstance(v, list): - raise TypeError - inst = cls() - inst.v = v - return inst - - def __repr__(self): - args = ', '.join([repr(x) for x in self.v]) - return f'{type(self).__name__}({args})' - - def __str__(self): - components = ' '.join([str(x) for x in self.v]) - return f'<{components}>' - - def __len__(self): - return len(self.v) - - def __getitem__(self, i): - return self.v[i] - - def __add__(self, other): - "Element-wise addition" - v = [x + y for x, y in zip(self.v, other.v)] - return Vec.fromlist(v) - - def __sub__(self, other): - "Element-wise subtraction" - v = [x - y for x, y in zip(self.v, other.v)] - return Vec.fromlist(v) - - def __mul__(self, scalar): - "Multiply by scalar" - v = [x * scalar for x in self.v] - return Vec.fromlist(v) - - __rmul__ = __mul__ - - def dot(self, other): - "Vector dot product" - if not isinstance(other, Vec): - raise TypeError - return sum(x_i * y_i for (x_i, y_i) in zip(self, other)) - - -def test(): - import doctest - doctest.testmod() - -test() diff --git a/Tools/freeze/test/freeze.py b/Tools/freeze/test/freeze.py index ddbfd7fc..92e97cb2 100644 --- a/Tools/freeze/test/freeze.py +++ b/Tools/freeze/test/freeze.py @@ -80,7 +80,19 @@ def copy_source_tree(newroot, oldroot): if newroot == SRCDIR: raise Exception('this probably isn\'t what you wanted') shutil.rmtree(newroot) - shutil.copytree(oldroot, newroot) + + def ignore_non_src(src, names): + """Turns what could be a 1000M copy into a 100M copy.""" + # Don't copy the ~600M+ of needless git repo metadata. + # source only, ignore cached .pyc files. + subdirs_to_skip = {'.git', '__pycache__'} + if os.path.basename(src) == 'Doc': + # Another potential ~250M+ of non test related data. + subdirs_to_skip.add('build') + subdirs_to_skip.add('venv') + return subdirs_to_skip + + shutil.copytree(oldroot, newroot, ignore=ignore_non_src) if os.path.exists(os.path.join(newroot, 'Makefile')): _run_quiet([MAKE, 'clean'], newroot) @@ -141,7 +153,7 @@ def prepare(script=None, outdir=None): print(f'configuring python in {builddir}...') cmd = [ os.path.join(srcdir, 'configure'), - *shlex.split(get_config_var(builddir, 'CONFIG_ARGS') or ''), + *shlex.split(get_config_var(SRCDIR, 'CONFIG_ARGS') or ''), ] ensure_opt(cmd, 'cache-file', os.path.join(outdir, 'python-config.cache')) prefix = os.path.join(outdir, 'python-installation') @@ -151,16 +163,25 @@ def prepare(script=None, outdir=None): if not MAKE: raise UnsupportedError('make') + cores = os.cpu_count() + if cores and cores >= 3: + # this test is most often run as part of the whole suite with a lot + # of other tests running in parallel, from 1-2 vCPU systems up to + # people's NNN core beasts. Don't attempt to use it all. + parallel = f'-j{cores*2//3}' + else: + parallel = '-j2' + # Build python. - print(f'building python in {builddir}...') + print(f'building python {parallel=} in {builddir}...') if os.path.exists(os.path.join(srcdir, 'Makefile')): # Out-of-tree builds require a clean srcdir. _run_quiet([MAKE, '-C', srcdir, 'clean']) - _run_quiet([MAKE, '-C', builddir, '-j8']) + _run_quiet([MAKE, '-C', builddir, parallel]) # Install the build. print(f'installing python into {prefix}...') - _run_quiet([MAKE, '-C', builddir, '-j8', 'install']) + _run_quiet([MAKE, '-C', builddir, 'install']) python = os.path.join(prefix, 'bin', 'python3') return outdir, scriptfile, python diff --git a/Tools/gdb/libpython.py b/Tools/gdb/libpython.py index a99ce945..e38bd59e 100755 --- a/Tools/gdb/libpython.py +++ b/Tools/gdb/libpython.py @@ -82,6 +82,8 @@ Py_TPFLAGS_DICT_SUBCLASS = (1 << 29) Py_TPFLAGS_BASE_EXC_SUBCLASS = (1 << 30) Py_TPFLAGS_TYPE_SUBCLASS = (1 << 31) +#From pycore_frame.h +FRAME_OWNED_BY_CSTACK = 3 MAX_OUTPUT_LEN=1024 @@ -478,17 +480,23 @@ class HeapTypeObjectPtr(PyObjectPtr): dictoffset = int_from_int(typeobj.field('tp_dictoffset')) if dictoffset != 0: if dictoffset < 0: - type_PyVarObject_ptr = gdb.lookup_type('PyVarObject').pointer() - tsize = int_from_int(self._gdbval.cast(type_PyVarObject_ptr)['ob_size']) - if tsize < 0: - tsize = -tsize - size = _PyObject_VAR_SIZE(typeobj, tsize) - dictoffset += size - assert dictoffset % _sizeof_void_p() == 0 + if int_from_int(typeobj.field('tp_flags')) & Py_TPFLAGS_MANAGED_DICT: + assert dictoffset == -1 + dictoffset = -3 * _sizeof_void_p() + else: + type_PyVarObject_ptr = gdb.lookup_type('PyVarObject').pointer() + tsize = int_from_int(self._gdbval.cast(type_PyVarObject_ptr)['ob_size']) + if tsize < 0: + tsize = -tsize + size = _PyObject_VAR_SIZE(typeobj, tsize) + dictoffset += size + assert dictoffset % _sizeof_void_p() == 0 dictptr = self._gdbval.cast(_type_char_ptr()) + dictoffset PyObjectPtrPtr = PyObjectPtr.get_gdb_type().pointer() dictptr = dictptr.cast(PyObjectPtrPtr) + if int(dictptr.dereference()) & 1: + return None return PyObjectPtr.from_pyobject_ptr(dictptr.dereference()) except RuntimeError: # Corrupt data somewhere; fail safe @@ -502,12 +510,14 @@ class HeapTypeObjectPtr(PyObjectPtr): has_values = int_from_int(typeobj.field('tp_flags')) & Py_TPFLAGS_MANAGED_DICT if not has_values: return None - PyDictValuesPtrPtr = gdb.lookup_type("PyDictValues").pointer().pointer() - valuesptr = self._gdbval.cast(PyDictValuesPtrPtr) - 4 - values = valuesptr.dereference() - if int(values) == 0: + charptrptr_t = _type_char_ptr().pointer() + ptr = self._gdbval.cast(charptrptr_t) - 3 + char_ptr = ptr.dereference() + if (int(char_ptr) & 1) == 0: return None - values = values['values'] + char_ptr += 1 + values_ptr = char_ptr.cast(gdb.lookup_type("PyDictValues").pointer()) + values = values_ptr['values'] return PyKeysValuesPair(self.get_cached_keys(), values) def get_cached_keys(self): @@ -527,14 +537,15 @@ class HeapTypeObjectPtr(PyObjectPtr): return ProxyAlreadyVisited('<...>') visited.add(self.as_address()) - pyop_attr_dict = self.get_attr_dict() keys_values = self.get_keys_values() if keys_values: attr_dict = keys_values.proxyval(visited) - elif pyop_attr_dict: - attr_dict = pyop_attr_dict.proxyval(visited) else: - attr_dict = {} + pyop_attr_dict = self.get_attr_dict() + if pyop_attr_dict: + attr_dict = pyop_attr_dict.proxyval(visited) + else: + attr_dict = {} tp_name = self.safe_tp_name() # Class: @@ -871,10 +882,16 @@ class PyLongObjectPtr(PyObjectPtr): def proxyval(self, visited): ''' Python's Include/longobjrep.h has this declaration: - struct _longobject { - PyObject_VAR_HEAD - digit ob_digit[1]; - }; + + typedef struct _PyLongValue { + uintptr_t lv_tag; /* Number of digits, sign and flags */ + digit ob_digit[1]; + } _PyLongValue; + + struct _longobject { + PyObject_HEAD + _PyLongValue long_value; + }; with this description: The absolute value of a number is equal to @@ -886,11 +903,13 @@ class PyLongObjectPtr(PyObjectPtr): #define PyLong_SHIFT 30 #define PyLong_SHIFT 15 ''' - ob_size = int(self.field('ob_size')) - if ob_size == 0: + long_value = self.field('long_value') + lv_tag = int(long_value['lv_tag']) + size = lv_tag >> 3 + if size == 0: return 0 - ob_digit = self.field('ob_digit') + ob_digit = long_value['ob_digit'] if gdb.lookup_type('digit').sizeof == 2: SHIFT = 15 @@ -898,9 +917,9 @@ class PyLongObjectPtr(PyObjectPtr): SHIFT = 30 digits = [int(ob_digit[i]) * 2**(SHIFT*i) - for i in safe_range(abs(ob_size))] + for i in safe_range(size)] result = sum(digits) - if ob_size < 0: + if (lv_tag & 3) == 2: result = -result return result @@ -1068,8 +1087,8 @@ class PyFramePtr: first_instr = self._f_code().field("co_code_adaptive").cast(codeunit_p) return int(prev_instr - first_instr) - def is_entry(self): - return self._f_special("is_entry", bool) + def is_shim(self): + return self._f_special("owner", int) == FRAME_OWNED_BY_CSTACK def previous(self): return self._f_special("previous", PyFramePtr) @@ -1376,57 +1395,28 @@ class PyUnicodeObjectPtr(PyObjectPtr): return _type_Py_UNICODE.sizeof def proxyval(self, visited): - may_have_surrogates = False compact = self.field('_base') ascii = compact['_base'] state = ascii['state'] is_compact_ascii = (int(state['ascii']) and int(state['compact'])) - if not int(state['ready']): - # string is not ready - field_length = int(compact['wstr_length']) - may_have_surrogates = True - field_str = ascii['wstr'] + field_length = int(ascii['length']) + if is_compact_ascii: + field_str = ascii.address + 1 + elif int(state['compact']): + field_str = compact.address + 1 else: - field_length = int(ascii['length']) - if is_compact_ascii: - field_str = ascii.address + 1 - elif int(state['compact']): - field_str = compact.address + 1 - else: - field_str = self.field('data')['any'] - repr_kind = int(state['kind']) - if repr_kind == 1: - field_str = field_str.cast(_type_unsigned_char_ptr()) - elif repr_kind == 2: - field_str = field_str.cast(_type_unsigned_short_ptr()) - elif repr_kind == 4: - field_str = field_str.cast(_type_unsigned_int_ptr()) + field_str = self.field('data')['any'] + repr_kind = int(state['kind']) + if repr_kind == 1: + field_str = field_str.cast(_type_unsigned_char_ptr()) + elif repr_kind == 2: + field_str = field_str.cast(_type_unsigned_short_ptr()) + elif repr_kind == 4: + field_str = field_str.cast(_type_unsigned_int_ptr()) # Gather a list of ints from the Py_UNICODE array; these are either # UCS-1, UCS-2 or UCS-4 code points: - if not may_have_surrogates: - Py_UNICODEs = [int(field_str[i]) for i in safe_range(field_length)] - else: - # A more elaborate routine if sizeof(Py_UNICODE) is 2 in the - # inferior process: we must join surrogate pairs. - Py_UNICODEs = [] - i = 0 - limit = safety_limit(field_length) - while i < limit: - ucs = int(field_str[i]) - i += 1 - if ucs < 0xD800 or ucs >= 0xDC00 or i == field_length: - Py_UNICODEs.append(ucs) - continue - # This could be a surrogate pair. - ucs2 = int(field_str[i]) - if ucs2 < 0xDC00 or ucs2 > 0xDFFF: - continue - code = (ucs & 0x03FF) << 10 - code |= ucs2 & 0x03FF - code += 0x00010000 - Py_UNICODEs.append(code) - i += 1 + Py_UNICODEs = [int(field_str[i]) for i in safe_range(field_length)] # Convert the int code points to unicode characters, and generate a # local unicode instance. @@ -1772,7 +1762,7 @@ class Frame(object): def is_waiting_for_gil(self): '''Is this frame waiting on the GIL?''' - # This assumes the _POSIX_THREADS version of Python/ceval_gil.h: + # This assumes the _POSIX_THREADS version of Python/ceval_gil.c: name = self._gdbframe.name() if name: return (name == 'take_gil') @@ -1841,14 +1831,14 @@ class Frame(object): interp_frame = self.get_pyop() while True: if interp_frame: + if interp_frame.is_shim(): + break line = interp_frame.get_truncated_repr(MAX_OUTPUT_LEN) sys.stdout.write('#%i %s\n' % (self.get_index(), line)) if not interp_frame.is_optimized_out(): line = interp_frame.current_line() if line is not None: sys.stdout.write(' %s\n' % line.strip()) - if interp_frame.is_entry(): - break else: sys.stdout.write('#%i (unable to read python frame information)\n' % self.get_index()) break @@ -1865,13 +1855,13 @@ class Frame(object): interp_frame = self.get_pyop() while True: if interp_frame: + if interp_frame.is_shim(): + break interp_frame.print_traceback() if not interp_frame.is_optimized_out(): line = interp_frame.current_line() if line is not None: sys.stdout.write(' %s\n' % line.strip()) - if interp_frame.is_entry(): - break else: sys.stdout.write(' (unable to read python frame information)\n') break @@ -2127,6 +2117,8 @@ class PyLocals(gdb.Command): if not pyop_frame: print(UNABLE_READ_INFO_PYTHON_FRAME) break + if pyop_frame.is_shim(): + break sys.stdout.write('Locals for %s\n' % (pyop_frame.co_name.proxyval(set()))) @@ -2135,8 +2127,6 @@ class PyLocals(gdb.Command): % (pyop_name.proxyval(set()), pyop_value.get_truncated_repr(MAX_OUTPUT_LEN))) - if pyop_frame.is_entry(): - break pyop_frame = pyop_frame.previous() diff --git a/Tools/i18n/pygettext.py b/Tools/i18n/pygettext.py index 7ada7910..3a0b27ba 100755 --- a/Tools/i18n/pygettext.py +++ b/Tools/i18n/pygettext.py @@ -174,7 +174,6 @@ DEFAULTKEYWORDS = ', '.join(default_keywords) EMPTYSTRING = '' - # The normal pot-file header. msgmerge and Emacs's po-mode work better if it's # there. pot_header = _('''\ @@ -196,7 +195,7 @@ msgstr "" ''') - + def usage(code, msg=''): print(__doc__ % globals(), file=sys.stderr) if msg: @@ -204,7 +203,6 @@ def usage(code, msg=''): sys.exit(code) - def make_escapes(pass_nonascii): global escapes, escape if pass_nonascii: @@ -258,7 +256,7 @@ def normalize(s, encoding): s = '""\n"' + lineterm.join(lines) + '"' return s - + def containsAny(str, set): """Check whether 'str' contains ANY of the chars in 'set'""" return 1 in [c in str for c in set] @@ -307,7 +305,7 @@ def getFilesForName(name): return [] - + class TokenEater: def __init__(self, options): self.__options = options @@ -515,7 +513,6 @@ class TokenEater: print('msgstr ""\n', file=fp) - def main(): global default_keywords try: @@ -675,7 +672,7 @@ def main(): if closep: fp.close() - + if __name__ == '__main__': main() # some more test strings diff --git a/Tools/importbench/importbench.py b/Tools/importbench/importbench.py index 6c4a537a..0c4b3bc7 100644 --- a/Tools/importbench/importbench.py +++ b/Tools/importbench/importbench.py @@ -6,7 +6,7 @@ thus has no external changes made to import-related attributes in sys. """ from test.test_importlib import util import decimal -import imp +from importlib.util import cache_from_source import importlib import importlib.machinery import json @@ -15,6 +15,7 @@ import py_compile import sys import tabnanny import timeit +import types def bench(name, cleanup=lambda: None, *, seconds=1, repeat=3): @@ -40,7 +41,7 @@ def bench(name, cleanup=lambda: None, *, seconds=1, repeat=3): def from_cache(seconds, repeat): """sys.modules""" name = '<benchmark import>' - module = imp.new_module(name) + module = types.ModuleType(name) module.__file__ = '<test>' module.__package__ = '' with util.uncache(name): @@ -65,7 +66,7 @@ def source_wo_bytecode(seconds, repeat): name = '__importlib_test_benchmark__' # Clears out sys.modules and puts an entry at the front of sys.path. with util.create_modules(name) as mapping: - assert not os.path.exists(imp.cache_from_source(mapping[name])) + assert not os.path.exists(cache_from_source(mapping[name])) sys.meta_path.append(importlib.machinery.PathFinder) loader = (importlib.machinery.SourceFileLoader, importlib.machinery.SOURCE_SUFFIXES) @@ -80,7 +81,7 @@ def _wo_bytecode(module): name = module.__name__ def benchmark_wo_bytecode(seconds, repeat): """Source w/o bytecode: {}""" - bytecode_path = imp.cache_from_source(module.__file__) + bytecode_path = cache_from_source(module.__file__) if os.path.exists(bytecode_path): os.unlink(bytecode_path) sys.dont_write_bytecode = True @@ -108,9 +109,9 @@ def source_writing_bytecode(seconds, repeat): sys.path_hooks.append(importlib.machinery.FileFinder.path_hook(loader)) def cleanup(): sys.modules.pop(name) - os.unlink(imp.cache_from_source(mapping[name])) + os.unlink(cache_from_source(mapping[name])) for result in bench(name, cleanup, repeat=repeat, seconds=seconds): - assert not os.path.exists(imp.cache_from_source(mapping[name])) + assert not os.path.exists(cache_from_source(mapping[name])) yield result @@ -121,7 +122,7 @@ def _writing_bytecode(module): assert not sys.dont_write_bytecode def cleanup(): sys.modules.pop(name) - os.unlink(imp.cache_from_source(module.__file__)) + os.unlink(cache_from_source(module.__file__)) yield from bench(name, cleanup, repeat=repeat, seconds=seconds) writing_bytecode_benchmark.__doc__ = ( @@ -141,7 +142,7 @@ def source_using_bytecode(seconds, repeat): importlib.machinery.SOURCE_SUFFIXES) sys.path_hooks.append(importlib.machinery.FileFinder.path_hook(loader)) py_compile.compile(mapping[name]) - assert os.path.exists(imp.cache_from_source(mapping[name])) + assert os.path.exists(cache_from_source(mapping[name])) yield from bench(name, lambda: sys.modules.pop(name), repeat=repeat, seconds=seconds) diff --git a/Tools/iobench/iobench.py b/Tools/iobench/iobench.py index b0a7feb9..4017149e 100644 --- a/Tools/iobench/iobench.py +++ b/Tools/iobench/iobench.py @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -# This file should be kept compatible with both Python 2.6 and Python >= 3.0. - import itertools import os import platform @@ -14,39 +11,37 @@ out = sys.stdout TEXT_ENCODING = 'utf8' NEWLINES = 'lf' -# Compatibility -try: - xrange -except NameError: - xrange = range def text_open(fn, mode, encoding=None): try: return open(fn, mode, encoding=encoding or TEXT_ENCODING) except TypeError: - if 'r' in mode: - mode += 'U' # 'U' mode is needed only in Python 2.x return open(fn, mode) + def get_file_sizes(): for s in ['20 KiB', '400 KiB', '10 MiB']: size, unit = s.split() size = int(size) * {'KiB': 1024, 'MiB': 1024 ** 2}[unit] yield s.replace(' ', ''), size + def get_binary_files(): return ((name + ".bin", size) for name, size in get_file_sizes()) + def get_text_files(): - return (("%s-%s-%s.txt" % (name, TEXT_ENCODING, NEWLINES), size) + return ((f"{name}-{TEXT_ENCODING}-{NEWLINES}.txt", size) for name, size in get_file_sizes()) + def with_open_mode(mode): def decorate(f): f.file_open_mode = mode return f return decorate + def with_sizes(*sizes): def decorate(f): f.file_sizes = sizes @@ -64,6 +59,7 @@ def read_bytewise(f): while f.read(1): pass + @with_open_mode("r") @with_sizes("medium") def read_small_chunks(f): @@ -72,6 +68,7 @@ def read_small_chunks(f): while f.read(20): pass + @with_open_mode("r") @with_sizes("medium") def read_big_chunks(f): @@ -80,6 +77,7 @@ def read_big_chunks(f): while f.read(4096): pass + @with_open_mode("r") @with_sizes("small", "medium", "large") def read_whole_file(f): @@ -88,6 +86,7 @@ def read_whole_file(f): while f.read(): pass + @with_open_mode("rt") @with_sizes("medium") def read_lines(f): @@ -96,6 +95,7 @@ def read_lines(f): for line in f: pass + @with_open_mode("r") @with_sizes("medium") def seek_forward_bytewise(f): @@ -103,9 +103,10 @@ def seek_forward_bytewise(f): f.seek(0, 2) size = f.tell() f.seek(0, 0) - for i in xrange(0, size - 1): + for i in range(0, size - 1): f.seek(i, 0) + @with_open_mode("r") @with_sizes("medium") def seek_forward_blockwise(f): @@ -113,9 +114,10 @@ def seek_forward_blockwise(f): f.seek(0, 2) size = f.tell() f.seek(0, 0) - for i in xrange(0, size - 1, 1000): + for i in range(0, size - 1, 1000): f.seek(i, 0) + @with_open_mode("rb") @with_sizes("medium") def read_seek_bytewise(f): @@ -124,6 +126,7 @@ def read_seek_bytewise(f): while f.read(1): f.seek(1, 1) + @with_open_mode("rb") @with_sizes("medium") def read_seek_blockwise(f): @@ -137,28 +140,31 @@ def read_seek_blockwise(f): @with_sizes("small") def write_bytewise(f, source): """ write one unit at a time """ - for i in xrange(0, len(source)): + for i in range(0, len(source)): f.write(source[i:i+1]) + @with_open_mode("w") @with_sizes("medium") def write_small_chunks(f, source): """ write 20 units at a time """ - for i in xrange(0, len(source), 20): + for i in range(0, len(source), 20): f.write(source[i:i+20]) + @with_open_mode("w") @with_sizes("medium") def write_medium_chunks(f, source): """ write 4096 units at a time """ - for i in xrange(0, len(source), 4096): + for i in range(0, len(source), 4096): f.write(source[i:i+4096]) + @with_open_mode("w") @with_sizes("large") def write_large_chunks(f, source): """ write 1e6 units at a time """ - for i in xrange(0, len(source), 1000000): + for i in range(0, len(source), 1000000): f.write(source[i:i+1000000]) @@ -167,59 +173,65 @@ def write_large_chunks(f, source): def modify_bytewise(f, source): """ modify one unit at a time """ f.seek(0) - for i in xrange(0, len(source)): + for i in range(0, len(source)): f.write(source[i:i+1]) + @with_open_mode("w+") @with_sizes("medium") def modify_small_chunks(f, source): """ modify 20 units at a time """ f.seek(0) - for i in xrange(0, len(source), 20): + for i in range(0, len(source), 20): f.write(source[i:i+20]) + @with_open_mode("w+") @with_sizes("medium") def modify_medium_chunks(f, source): """ modify 4096 units at a time """ f.seek(0) - for i in xrange(0, len(source), 4096): + for i in range(0, len(source), 4096): f.write(source[i:i+4096]) + @with_open_mode("wb+") @with_sizes("medium") def modify_seek_forward_bytewise(f, source): """ alternate write & seek one unit """ f.seek(0) - for i in xrange(0, len(source), 2): + for i in range(0, len(source), 2): f.write(source[i:i+1]) f.seek(i+2) + @with_open_mode("wb+") @with_sizes("medium") def modify_seek_forward_blockwise(f, source): """ alternate write & seek 1000 units """ f.seek(0) - for i in xrange(0, len(source), 2000): + for i in range(0, len(source), 2000): f.write(source[i:i+1000]) f.seek(i+2000) + # XXX the 2 following tests don't work with py3k's text IO @with_open_mode("wb+") @with_sizes("medium") def read_modify_bytewise(f, source): """ alternate read & write one unit """ f.seek(0) - for i in xrange(0, len(source), 2): + for i in range(0, len(source), 2): f.read(1) f.write(source[i+1:i+2]) + @with_open_mode("wb+") @with_sizes("medium") def read_modify_blockwise(f, source): """ alternate read & write 1000 units """ f.seek(0) - for i in xrange(0, len(source), 2000): + for i in range(0, len(source), 2000): f.read(1000) f.write(source[i+1000:i+2000]) @@ -242,6 +254,7 @@ modify_tests = [ read_modify_bytewise, read_modify_blockwise, ] + def run_during(duration, func): _t = time.time n = 0 @@ -257,6 +270,7 @@ def run_during(duration, func): real = (end[4] if start[4] else time.time()) - real_start return n, real, sum(end[0:2]) - sum(start[0:2]) + def warm_cache(filename): with open(filename, "rb") as f: f.read() @@ -266,9 +280,7 @@ def run_all_tests(options): def print_label(filename, func): name = re.split(r'[-.]', filename)[0] out.write( - ("[%s] %s... " - % (name.center(7), func.__doc__.strip()) - ).ljust(52)) + f"[{name.center(7)}] {func.__doc__.strip()}... ".ljust(52)) out.flush() def print_results(size, n, real, cpu): @@ -276,8 +288,9 @@ def run_all_tests(options): bw = ("%4d MiB/s" if bw > 100 else "%.3g MiB/s") % bw out.write(bw.rjust(12) + "\n") if cpu < 0.90 * real: - out.write(" warning: test above used only %d%% CPU, " - "result may be flawed!\n" % (100.0 * cpu / real)) + out.write(" warning: test above used only " + f"{cpu / real:%} CPU, " + "result may be flawed!\n") def run_one_test(name, size, open_func, test_func, *args): mode = test_func.file_open_mode @@ -308,22 +321,15 @@ def run_all_tests(options): "large": 2, } - print("Python %s" % sys.version) - if sys.version_info < (3, 3): - if sys.maxunicode > 0xffff: - text = "UCS-4 (wide build)" - else: - text = "UTF-16 (narrow build)" - else: - text = "PEP 393" - print("Unicode: %s" % text) + print(f"Python {sys.version}") + print("Unicode: PEP 393") print(platform.platform()) binary_files = list(get_binary_files()) text_files = list(get_text_files()) if "b" in options: print("Binary unit = one byte") if "t" in options: - print("Text unit = one character (%s-decoded)" % TEXT_ENCODING) + print(f"Text unit = one character ({TEXT_ENCODING}-decoded)") # Binary reads if "b" in options and "r" in options: @@ -338,6 +344,7 @@ def run_all_tests(options): # Binary writes if "b" in options and "w" in options: print("\n** Binary append **\n") + def make_test_source(name, size): with open(name, "rb") as f: return f.read() @@ -347,6 +354,7 @@ def run_all_tests(options): # Text writes if "t" in options and "w" in options: print("\n** Text append **\n") + def make_test_source(name, size): with text_open(name, "r") as f: return f.read() @@ -356,6 +364,7 @@ def run_all_tests(options): # Binary overwrites if "b" in options and "w" in options: print("\n** Binary overwrite **\n") + def make_test_source(name, size): with open(name, "rb") as f: return f.read() @@ -365,6 +374,7 @@ def run_all_tests(options): # Text overwrites if "t" in options and "w" in options: print("\n** Text overwrite **\n") + def make_test_source(name, size): with text_open(name, "r") as f: return f.read() @@ -388,7 +398,7 @@ def prepare_files(): break else: raise RuntimeError( - "Couldn't find chunk marker in %s !" % __file__) + f"Couldn't find chunk marker in {__file__} !") if NEWLINES == "all": it = itertools.cycle(["\n", "\r", "\r\n"]) else: @@ -414,6 +424,7 @@ def prepare_files(): f.write(head) f.write(tail) + def main(): global TEXT_ENCODING, NEWLINES @@ -433,7 +444,7 @@ def main(): help="run write & modify tests") parser.add_option("-E", "--encoding", action="store", dest="encoding", default=None, - help="encoding for text tests (default: %s)" % TEXT_ENCODING) + help=f"encoding for text tests (default: {TEXT_ENCODING})") parser.add_option("-N", "--newlines", action="store", dest="newlines", default='lf', help="line endings for text tests " @@ -446,7 +457,7 @@ def main(): parser.error("unexpected arguments") NEWLINES = options.newlines.lower() if NEWLINES not in ('lf', 'cr', 'crlf', 'all'): - parser.error("invalid 'newlines' option: %r" % NEWLINES) + parser.error(f"invalid 'newlines' option: {NEWLINES!r}") test_options = "" if options.read: @@ -471,6 +482,7 @@ def main(): prepare_files() run_all_tests(test_options) + if __name__ == "__main__": main() diff --git a/Tools/msi/build.bat b/Tools/msi/build.bat index 34918d2f..b9aab887 100644 --- a/Tools/msi/build.bat +++ b/Tools/msi/build.bat @@ -1,96 +1,86 @@ -@echo off -setlocal -set D=%~dp0 -set PCBUILD=%D%..\..\PCbuild\ - -set BUILDX86= -set BUILDX64= -set BUILDARM64= -set BUILDDOC= -set BUILDTEST= -set BUILDPACK= -set REBUILD= - -:CheckOpts -if "%~1" EQU "-h" goto Help -if /I "%~1" EQU "-x86" (set BUILDX86=1) && shift && goto CheckOpts -if /I "%~1" EQU "-Win32" (set BUILDX86=1) && shift && goto CheckOpts -if /I "%~1" EQU "-x64" (set BUILDX64=1) && shift && goto CheckOpts -if /I "%~1" EQU "-arm64" (set BUILDARM64=1) && shift && goto CheckOpts -if "%~1" EQU "--doc" (set BUILDDOC=1) && shift && goto CheckOpts -if "%~1" EQU "--no-test-marker" (set BUILDTEST=) && shift && goto CheckOpts -if "%~1" EQU "--test-marker" (set BUILDTEST=--test-marker) && shift && goto CheckOpts -if "%~1" EQU "--pack" (set BUILDPACK=1) && shift && goto CheckOpts -if "%~1" EQU "-r" (set REBUILD=-r) && shift && goto CheckOpts - -if not defined BUILDX86 if not defined BUILDX64 if not defined BUILDARM64 (set BUILDX86=1) && (set BUILDX64=1) - -call "%D%get_externals.bat" -call "%PCBUILD%find_msbuild.bat" %MSBUILD% -if ERRORLEVEL 1 (echo Cannot locate MSBuild.exe on PATH or as MSBUILD variable & exit /b 2) - -if defined BUILDX86 ( - call "%PCBUILD%build.bat" -p Win32 -d -e %REBUILD% %BUILDTEST% - if errorlevel 1 exit /B %ERRORLEVEL% - call "%PCBUILD%build.bat" -p Win32 -e %REBUILD% %BUILDTEST% - if errorlevel 1 exit /B %ERRORLEVEL% -) -if defined BUILDX64 ( - call "%PCBUILD%build.bat" -p x64 -d -e %REBUILD% %BUILDTEST% - if errorlevel 1 exit /B %ERRORLEVEL% - call "%PCBUILD%build.bat" -p x64 -e %REBUILD% %BUILDTEST% - if errorlevel 1 exit /B %ERRORLEVEL% -) -if defined BUILDARM64 ( - call "%PCBUILD%build.bat" -p ARM64 -d -e %REBUILD% %BUILDTEST% - if errorlevel 1 exit /B %ERRORLEVEL% - call "%PCBUILD%build.bat" -p ARM64 -e %REBUILD% %BUILDTEST% - if errorlevel 1 exit /B %ERRORLEVEL% -) - -if defined BUILDDOC ( - call "%PCBUILD%..\Doc\make.bat" html - if errorlevel 1 exit /B %ERRORLEVEL% -) - -rem Build the launcher MSI separately -%MSBUILD% "%D%launcher\launcher.wixproj" /p:Platform=x86 -if errorlevel 1 exit /B %ERRORLEVEL% - -set BUILD_CMD="%D%bundle\snapshot.wixproj" -if defined BUILDTEST ( - set BUILD_CMD=%BUILD_CMD% /p:UseTestMarker=true -) -if defined BUILDPACK ( - set BUILD_CMD=%BUILD_CMD% /p:Pack=true -) -if defined REBUILD ( - set BUILD_CMD=%BUILD_CMD% /t:Rebuild -) - -if defined BUILDX86 ( - %MSBUILD% /p:Platform=x86 %BUILD_CMD% - if errorlevel 1 exit /B %ERRORLEVEL% -) -if defined BUILDX64 ( - %MSBUILD% /p:Platform=x64 %BUILD_CMD% - if errorlevel 1 exit /B %ERRORLEVEL% -) -if defined BUILDARM64 ( - %MSBUILD% /p:Platform=ARM64 %BUILD_CMD% - if errorlevel 1 exit /B %ERRORLEVEL% -) - -exit /B 0 - -:Help -echo build.bat [-x86] [-x64] [-arm64] [--doc] [-h] [--test-marker] [--pack] [-r] -echo. -echo -x86 Build x86 installers -echo -x64 Build x64 installers -echo -ARM64 Build ARM64 installers -echo --doc Build documentation -echo --test-marker Build with test markers -echo --no-test-marker Build without test markers (default) -echo --pack Embed core MSIs into installer -echo -r Rebuild rather than incremental build +@echo off +setlocal +set D=%~dp0 +set PCBUILD=%D%..\..\PCbuild\ + +set BUILDX86= +set BUILDX64= +set BUILDARM64= +set BUILDDOC= +set BUILDTEST= +set BUILDPACK= +set REBUILD= + +:CheckOpts +if "%~1" EQU "-h" goto Help +if /I "%~1" EQU "-x86" (set BUILDX86=1) && shift && goto CheckOpts +if /I "%~1" EQU "-Win32" (set BUILDX86=1) && shift && goto CheckOpts +if /I "%~1" EQU "-x64" (set BUILDX64=1) && shift && goto CheckOpts +if /I "%~1" EQU "-arm64" (set BUILDARM64=1) && shift && goto CheckOpts +if "%~1" EQU "--doc" (set BUILDDOC=1) && shift && goto CheckOpts +if "%~1" EQU "--no-test-marker" (set BUILDTEST=) && shift && goto CheckOpts +if "%~1" EQU "--test-marker" (set BUILDTEST=--test-marker) && shift && goto CheckOpts +if "%~1" EQU "--pack" (set BUILDPACK=1) && shift && goto CheckOpts +if "%~1" EQU "-r" (set REBUILD=-r) && shift && goto CheckOpts + +if not defined BUILDX86 if not defined BUILDX64 if not defined BUILDARM64 (set BUILDX86=1) && (set BUILDX64=1) + +call "%D%get_externals.bat" +call "%PCBUILD%find_msbuild.bat" %MSBUILD% +if ERRORLEVEL 1 (echo Cannot locate MSBuild.exe on PATH or as MSBUILD variable & exit /b 2) + +if defined BUILDX86 call "%PCBUILD%build.bat" -p Win32 -d -e %REBUILD% %BUILDTEST% +if errorlevel 1 exit /B %ERRORLEVEL% +if defined BUILDX86 call "%PCBUILD%build.bat" -p Win32 -e %REBUILD% %BUILDTEST% +if errorlevel 1 exit /B %ERRORLEVEL% + +if defined BUILDX64 call "%PCBUILD%build.bat" -p x64 -d -e %REBUILD% %BUILDTEST% +if errorlevel 1 exit /B %ERRORLEVEL% +if defined BUILDX64 call "%PCBUILD%build.bat" -p x64 -e %REBUILD% %BUILDTEST% +if errorlevel 1 exit /B %ERRORLEVEL% + +if defined BUILDARM64 call "%PCBUILD%build.bat" -p ARM64 -d -e %REBUILD% %BUILDTEST% +if errorlevel 1 exit /B %ERRORLEVEL% +if defined BUILDARM64 call "%PCBUILD%build.bat" -p ARM64 -e %REBUILD% %BUILDTEST% +if errorlevel 1 exit /B %ERRORLEVEL% + +if defined BUILDDOC call "%PCBUILD%..\Doc\make.bat" html +if errorlevel 1 exit /B %ERRORLEVEL% + +rem Build the launcher MSI separately +%MSBUILD% "%D%launcher\launcher.wixproj" /p:Platform=x86 +if errorlevel 1 exit /B %ERRORLEVEL% + +set BUILD_CMD="%D%bundle\snapshot.wixproj" +if defined BUILDTEST ( + set BUILD_CMD=%BUILD_CMD% /p:UseTestMarker=true +) +if defined BUILDPACK ( + set BUILD_CMD=%BUILD_CMD% /p:Pack=true +) +if defined REBUILD ( + set BUILD_CMD=%BUILD_CMD% /t:Rebuild +) + +if defined BUILDX86 %MSBUILD% /p:Platform=x86 %BUILD_CMD% +if errorlevel 1 exit /B %ERRORLEVEL% + +if defined BUILDX64 %MSBUILD% /p:Platform=x64 %BUILD_CMD% +if errorlevel 1 exit /B %ERRORLEVEL% + +if defined BUILDARM64 %MSBUILD% /p:Platform=ARM64 %BUILD_CMD% +if errorlevel 1 exit /B %ERRORLEVEL% + +exit /B 0 + +:Help +echo build.bat [-x86] [-x64] [-arm64] [--doc] [-h] [--test-marker] [--pack] [-r] +echo. +echo -x86 Build x86 installers +echo -x64 Build x64 installers +echo -ARM64 Build ARM64 installers +echo --doc Build documentation +echo --test-marker Build with test markers +echo --no-test-marker Build without test markers (default) +echo --pack Embed core MSIs into installer +echo -r Rebuild rather than incremental build diff --git a/Tools/msi/buildrelease.bat b/Tools/msi/buildrelease.bat index b140839f..839f6204 100644 --- a/Tools/msi/buildrelease.bat +++ b/Tools/msi/buildrelease.bat @@ -1,261 +1,261 @@ -@setlocal -@echo off - -rem This script is intended for building official releases of Python. -rem To use it to build alternative releases, you should clone this file -rem and modify the following three URIs. - -rem These two will ensure that your release can be installed -rem alongside an official Python release, by modifying the GUIDs used -rem for all components. -rem -rem The following substitutions will be applied to the release URI: -rem Variable Description Example -rem {arch} architecture amd64, win32 -rem Do not change the scheme to https. Otherwise, releases built with this -rem script will not be upgradable to/from official releases of Python. -set RELEASE_URI=http://www.python.org/{arch} - -rem This is the URL that will be used to download installation files. -rem The files available from the default URL *will* conflict with your -rem installer. Trust me, you don't want them, even if it seems like a -rem good idea. -rem -rem The following substitutions will be applied to the download URL: -rem Variable Description Example -rem {version} version number 3.5.0 -rem {arch} architecture amd64, win32 -rem {releasename} release name a1, b2, rc3 (or blank for final) -rem {msi} MSI filename core.msi -set DOWNLOAD_URL=https://www.python.org/ftp/python/{version}/{arch}{releasename}/{msi} - -set D=%~dp0 -set PCBUILD=%D%..\..\PCbuild\ -if NOT DEFINED Py_OutDir set Py_OutDir=%PCBUILD% -set EXTERNALS=%D%..\..\externals\windows-installer\ - -set BUILDX86= -set BUILDX64= -set BUILDARM64= -set TARGET=Rebuild -set TESTTARGETDIR= -set PGO=-m test -q --pgo -set BUILDMSI=1 -set BUILDNUGET=1 -set BUILDZIP=1 - - -:CheckOpts -if "%1" EQU "-h" goto Help -if "%1" EQU "-c" (set CERTNAME=%~2) && shift && shift && goto CheckOpts -if "%1" EQU "--certificate" (set CERTNAME=%~2) && shift && shift && goto CheckOpts -if "%1" EQU "-o" (set OUTDIR=%~2) && shift && shift && goto CheckOpts -if "%1" EQU "--out" (set OUTDIR=%~2) && shift && shift && goto CheckOpts -if "%1" EQU "-D" (set SKIPDOC=1) && shift && goto CheckOpts -if "%1" EQU "--skip-doc" (set SKIPDOC=1) && shift && goto CheckOpts -if "%1" EQU "-B" (set SKIPBUILD=1) && shift && goto CheckOpts -if "%1" EQU "--skip-build" (set SKIPBUILD=1) && shift && goto CheckOpts -if "%1" EQU "--download" (set DOWNLOAD_URL=%~2) && shift && shift && goto CheckOpts -if "%1" EQU "--test" (set TESTTARGETDIR=%~2) && shift && shift && goto CheckOpts -if "%1" EQU "-b" (set TARGET=Build) && shift && goto CheckOpts -if "%1" EQU "--build" (set TARGET=Build) && shift && goto CheckOpts -if /I "%1" EQU "-x86" (set BUILDX86=1) && shift && goto CheckOpts -if /I "%1" EQU "-Win32" (set BUILDX86=1) && shift && goto CheckOpts -if /I "%1" EQU "-x64" (set BUILDX64=1) && shift && goto CheckOpts -if /I "%1" EQU "-arm64" (set BUILDARM64=1) && shift && goto CheckOpts -if "%1" EQU "--pgo" (set PGO=%~2) && shift && shift && goto CheckOpts -if "%1" EQU "--skip-pgo" (set PGO=) && shift && goto CheckOpts -if "%1" EQU "--skip-nuget" (set BUILDNUGET=) && shift && goto CheckOpts -if "%1" EQU "--skip-zip" (set BUILDZIP=) && shift && goto CheckOpts -if "%1" EQU "--skip-msi" (set BUILDMSI=) && shift && goto CheckOpts - -if "%1" NEQ "" echo Invalid option: "%1" && exit /B 1 - -if not defined BUILDX86 if not defined BUILDX64 if not defined BUILDARM64 (set BUILDX86=1) && (set BUILDX64=1) - -if not exist "%GIT%" where git > "%TEMP%\git.loc" 2> nul && set /P GIT= < "%TEMP%\git.loc" & del "%TEMP%\git.loc" -if not exist "%GIT%" echo Cannot find Git on PATH && exit /B 1 - -call "%D%get_externals.bat" -call "%PCBUILD%find_msbuild.bat" %MSBUILD% -if ERRORLEVEL 1 (echo Cannot locate MSBuild.exe on PATH or as MSBUILD variable & exit /b 2) - -:builddoc -if "%SKIPBUILD%" EQU "1" goto skipdoc -if "%SKIPDOC%" EQU "1" goto skipdoc - -call "%D%..\..\doc\make.bat" html -if errorlevel 1 exit /B %ERRORLEVEL% -:skipdoc - -if defined BUILDX86 ( - call :build x86 - if errorlevel 1 exit /B %ERRORLEVEL% -) - -if defined BUILDX64 ( - call :build x64 "%PGO%" - if errorlevel 1 exit /B %ERRORLEVEL% -) - -if defined BUILDARM64 ( - call :build ARM64 - if errorlevel 1 exit /B %ERRORLEVEL% -) - -if defined TESTTARGETDIR ( - call "%D%testrelease.bat" -t "%TESTTARGETDIR%" - if errorlevel 1 exit /B %ERRORLEVEL% -) - -exit /B 0 - -:build -@setlocal -@echo off - -if "%1" EQU "x86" ( - set PGO= - set BUILD=%Py_OutDir%win32\ - set BUILD_PLAT=Win32 - set OUTDIR_PLAT=win32 - set OBJDIR_PLAT=x86 -) else if "%1" EQU "x64" ( - set BUILD=%Py_OutDir%amd64\ - set PGO=%~2 - set BUILD_PLAT=x64 - set OUTDIR_PLAT=amd64 - set OBJDIR_PLAT=x64 -) else if "%1" EQU "ARM64" ( - set BUILD=%Py_OutDir%amd64\ - set PGO=%~2 - set BUILD_PLAT=ARM64 - set OUTDIR_PLAT=arm64 - set OBJDIR_PLAT=arm64 -) else ( - echo Unknown platform %1 - exit /B 1 -) - -if exist "%BUILD%en-us" ( - echo Deleting %BUILD%en-us - rmdir /q/s "%BUILD%en-us" - if errorlevel 1 exit /B %ERRORLEVEL% -) - -if exist "%D%obj\Debug_%OBJDIR_PLAT%" ( - echo Deleting "%D%obj\Debug_%OBJDIR_PLAT%" - rmdir /q/s "%D%obj\Debug_%OBJDIR_PLAT%" - if errorlevel 1 exit /B %ERRORLEVEL% -) - -if exist "%D%obj\Release_%OBJDIR_PLAT%" ( - echo Deleting "%D%obj\Release_%OBJDIR_PLAT%" - rmdir /q/s "%D%obj\Release_%OBJDIR_PLAT%" - if errorlevel 1 exit /B %ERRORLEVEL% -) - -if not "%CERTNAME%" EQU "" ( - set CERTOPTS="/p:SigningCertificate=%CERTNAME%" -) else ( - set CERTOPTS= -) -if not "%PGO%" EQU "" ( - set PGOOPTS=--pgo-job "%PGO%" -) else ( - set PGOOPTS= -) -if not "%SKIPBUILD%" EQU "1" ( - @echo call "%PCBUILD%build.bat" -e -p %BUILD_PLAT% -t %TARGET% %PGOOPTS% %CERTOPTS% - @call "%PCBUILD%build.bat" -e -p %BUILD_PLAT% -t %TARGET% %PGOOPTS% %CERTOPTS% - @if errorlevel 1 exit /B %ERRORLEVEL% - @rem build.bat turns echo back on, so we disable it again - @echo off - - @echo call "%PCBUILD%build.bat" -d -e -p %BUILD_PLAT% -t %TARGET% - @call "%PCBUILD%build.bat" -d -e -p %BUILD_PLAT% -t %TARGET% - @if errorlevel 1 exit /B %ERRORLEVEL% - @rem build.bat turns echo back on, so we disable it again - @echo off -) - -if "%OUTDIR_PLAT%" EQU "win32" ( - %MSBUILD% "%D%launcher\launcher.wixproj" /p:Platform=x86 %CERTOPTS% /p:ReleaseUri=%RELEASE_URI% - if errorlevel 1 exit /B %ERRORLEVEL% -) else if not exist "%Py_OutDir%win32\en-us\launcher.msi" ( - %MSBUILD% "%D%launcher\launcher.wixproj" /p:Platform=x86 %CERTOPTS% /p:ReleaseUri=%RELEASE_URI% - if errorlevel 1 exit /B %ERRORLEVEL% -) - -set BUILDOPTS=/p:Platform=%1 /p:BuildForRelease=true /p:DownloadUrl=%DOWNLOAD_URL% /p:DownloadUrlBase=%DOWNLOAD_URL_BASE% /p:ReleaseUri=%RELEASE_URI% -if defined BUILDMSI ( - %MSBUILD% "%D%bundle\releaselocal.wixproj" /t:Rebuild %BUILDOPTS% %CERTOPTS% /p:RebuildAll=true - if errorlevel 1 exit /B %ERRORLEVEL% -) - -if defined BUILDZIP ( - if "%BUILD_PLAT%" EQU "ARM64" ( - echo Skipping embeddable ZIP generation for ARM64 platform - ) else ( - %MSBUILD% "%D%make_zip.proj" /t:Build %BUILDOPTS% %CERTOPTS% /p:OutputPath="%BUILD%en-us" - if errorlevel 1 exit /B %ERRORLEVEL% - ) -) - -if defined BUILDNUGET ( - if "%BUILD_PLAT%" EQU "ARM64" ( - echo Skipping Nuget package generation for ARM64 platform - ) else ( - %MSBUILD% "%D%..\nuget\make_pkg.proj" /t:Build /p:Configuration=Release /p:Platform=%1 /p:OutputPath="%BUILD%en-us" - if errorlevel 1 exit /B %ERRORLEVEL% - ) -) - -if not "%OUTDIR%" EQU "" ( - mkdir "%OUTDIR%\%OUTDIR_PLAT%" - mkdir "%OUTDIR%\%OUTDIR_PLAT%\binaries" - mkdir "%OUTDIR%\%OUTDIR_PLAT%\symbols" - robocopy "%BUILD%en-us" "%OUTDIR%\%OUTDIR_PLAT%" /XF "*.wixpdb" - robocopy "%BUILD%\" "%OUTDIR%\%OUTDIR_PLAT%\binaries" *.exe *.dll *.pyd /XF "_test*" /XF "*_d.*" /XF "_freeze*" /XF "tcl*" /XF "tk*" /XF "*_test.*" - robocopy "%BUILD%\" "%OUTDIR%\%OUTDIR_PLAT%\symbols" *.pdb /XF "_test*" /XF "*_d.*" /XF "_freeze*" /XF "tcl*" /XF "tk*" /XF "*_test.*" -) - -exit /B 0 - -:Help -echo buildrelease.bat [--out DIR] [-x86] [-x64] [-arm64] [--certificate CERTNAME] [--build] [--pgo COMMAND] -echo [--skip-build] [--skip-doc] [--skip-nuget] [--skip-zip] [--skip-pgo] -echo [--download DOWNLOAD URL] [--test TARGETDIR] -echo [-h] -echo. -echo --out (-o) Specify an additional output directory for installers -echo -x86 Build x86 installers -echo -x64 Build x64 installers -echo -arm64 Build ARM64 installers -echo --build (-b) Incrementally build Python rather than rebuilding -echo --skip-build (-B) Do not build Python (just do the installers) -echo --skip-doc (-D) Do not build documentation -echo --pgo Specify PGO command for x64 installers -echo --skip-pgo Build x64 installers without using PGO -echo --skip-msi Do not build executable/MSI packages -echo --skip-nuget Do not build Nuget packages -echo --skip-zip Do not build embeddable package -echo --download Specify the full download URL for MSIs -echo --test Specify the test directory to run the installer tests -echo -h Display this help information -echo. -echo If no architecture is specified, all architectures will be built. -echo If --test is not specified, the installer tests are not run. -echo. -echo For the --pgo option, any Python command line can be used, or 'default' to -echo use the default task (-m test --pgo). -echo. -echo x86 and ARM64 builds will never use PGO. ARM64 builds will never generate -echo embeddable or Nuget packages. -echo. -echo The following substitutions will be applied to the download URL: -echo Variable Description Example -echo {version} version number 3.5.0 -echo {arch} architecture amd64, win32 -echo {releasename} release name a1, b2, rc3 (or blank for final) -echo {msi} MSI filename core.msi +@setlocal +@echo off + +rem This script is intended for building official releases of Python. +rem To use it to build alternative releases, you should clone this file +rem and modify the following three URIs. + +rem These two will ensure that your release can be installed +rem alongside an official Python release, by modifying the GUIDs used +rem for all components. +rem +rem The following substitutions will be applied to the release URI: +rem Variable Description Example +rem {arch} architecture amd64, win32 +rem Do not change the scheme to https. Otherwise, releases built with this +rem script will not be upgradable to/from official releases of Python. +set RELEASE_URI=http://www.python.org/{arch} + +rem This is the URL that will be used to download installation files. +rem The files available from the default URL *will* conflict with your +rem installer. Trust me, you don't want them, even if it seems like a +rem good idea. +rem +rem The following substitutions will be applied to the download URL: +rem Variable Description Example +rem {version} version number 3.5.0 +rem {arch} architecture amd64, win32 +rem {releasename} release name a1, b2, rc3 (or blank for final) +rem {msi} MSI filename core.msi +set DOWNLOAD_URL=https://www.python.org/ftp/python/{version}/{arch}{releasename}/{msi} + +set D=%~dp0 +set PCBUILD=%D%..\..\PCbuild\ +if NOT DEFINED Py_OutDir set Py_OutDir=%PCBUILD% +set EXTERNALS=%D%..\..\externals\windows-installer\ + +set BUILDX86= +set BUILDX64= +set BUILDARM64= +set TARGET=Rebuild +set TESTTARGETDIR= +set PGO=-m test -q --pgo +set BUILDMSI=1 +set BUILDNUGET=1 +set BUILDZIP=1 + + +:CheckOpts +if "%1" EQU "-h" goto Help +if "%1" EQU "-c" (set CERTNAME=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "--certificate" (set CERTNAME=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "-o" (set OUTDIR=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "--out" (set OUTDIR=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "-D" (set SKIPDOC=1) && shift && goto CheckOpts +if "%1" EQU "--skip-doc" (set SKIPDOC=1) && shift && goto CheckOpts +if "%1" EQU "-B" (set SKIPBUILD=1) && shift && goto CheckOpts +if "%1" EQU "--skip-build" (set SKIPBUILD=1) && shift && goto CheckOpts +if "%1" EQU "--download" (set DOWNLOAD_URL=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "--test" (set TESTTARGETDIR=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "-b" (set TARGET=Build) && shift && goto CheckOpts +if "%1" EQU "--build" (set TARGET=Build) && shift && goto CheckOpts +if /I "%1" EQU "-x86" (set BUILDX86=1) && shift && goto CheckOpts +if /I "%1" EQU "-Win32" (set BUILDX86=1) && shift && goto CheckOpts +if /I "%1" EQU "-x64" (set BUILDX64=1) && shift && goto CheckOpts +if /I "%1" EQU "-arm64" (set BUILDARM64=1) && shift && goto CheckOpts +if "%1" EQU "--pgo" (set PGO=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "--skip-pgo" (set PGO=) && shift && goto CheckOpts +if "%1" EQU "--skip-nuget" (set BUILDNUGET=) && shift && goto CheckOpts +if "%1" EQU "--skip-zip" (set BUILDZIP=) && shift && goto CheckOpts +if "%1" EQU "--skip-msi" (set BUILDMSI=) && shift && goto CheckOpts + +if "%1" NEQ "" echo Invalid option: "%1" && exit /B 1 + +if not defined BUILDX86 if not defined BUILDX64 if not defined BUILDARM64 (set BUILDX86=1) && (set BUILDX64=1) + +if not exist "%GIT%" where git > "%TEMP%\git.loc" 2> nul && set /P GIT= < "%TEMP%\git.loc" & del "%TEMP%\git.loc" +if not exist "%GIT%" echo Cannot find Git on PATH && exit /B 1 + +call "%D%get_externals.bat" +call "%PCBUILD%find_msbuild.bat" %MSBUILD% +if ERRORLEVEL 1 (echo Cannot locate MSBuild.exe on PATH or as MSBUILD variable & exit /b 2) + +:builddoc +if "%SKIPBUILD%" EQU "1" goto skipdoc +if "%SKIPDOC%" EQU "1" goto skipdoc + +call "%D%..\..\doc\make.bat" html +if errorlevel 1 exit /B %ERRORLEVEL% +:skipdoc + +if defined BUILDX86 ( + call :build x86 + if errorlevel 1 exit /B %ERRORLEVEL% +) + +if defined BUILDX64 ( + call :build x64 "%PGO%" + if errorlevel 1 exit /B %ERRORLEVEL% +) + +if defined BUILDARM64 ( + call :build ARM64 + if errorlevel 1 exit /B %ERRORLEVEL% +) + +if defined TESTTARGETDIR ( + call "%D%testrelease.bat" -t "%TESTTARGETDIR%" + if errorlevel 1 exit /B %ERRORLEVEL% +) + +exit /B 0 + +:build +@setlocal +@echo off + +if "%1" EQU "x86" ( + set PGO= + set BUILD=%Py_OutDir%win32\ + set BUILD_PLAT=Win32 + set OUTDIR_PLAT=win32 + set OBJDIR_PLAT=x86 +) else if "%1" EQU "x64" ( + set BUILD=%Py_OutDir%amd64\ + set PGO=%~2 + set BUILD_PLAT=x64 + set OUTDIR_PLAT=amd64 + set OBJDIR_PLAT=x64 +) else if "%1" EQU "ARM64" ( + set BUILD=%Py_OutDir%amd64\ + set PGO=%~2 + set BUILD_PLAT=ARM64 + set OUTDIR_PLAT=arm64 + set OBJDIR_PLAT=arm64 +) else ( + echo Unknown platform %1 + exit /B 1 +) + +if exist "%BUILD%en-us" ( + echo Deleting %BUILD%en-us + rmdir /q/s "%BUILD%en-us" + if errorlevel 1 exit /B %ERRORLEVEL% +) + +if exist "%D%obj\Debug_%OBJDIR_PLAT%" ( + echo Deleting "%D%obj\Debug_%OBJDIR_PLAT%" + rmdir /q/s "%D%obj\Debug_%OBJDIR_PLAT%" + if errorlevel 1 exit /B %ERRORLEVEL% +) + +if exist "%D%obj\Release_%OBJDIR_PLAT%" ( + echo Deleting "%D%obj\Release_%OBJDIR_PLAT%" + rmdir /q/s "%D%obj\Release_%OBJDIR_PLAT%" + if errorlevel 1 exit /B %ERRORLEVEL% +) + +if not "%CERTNAME%" EQU "" ( + set CERTOPTS="/p:SigningCertificate=%CERTNAME%" +) else ( + set CERTOPTS= +) +if not "%PGO%" EQU "" ( + set PGOOPTS=--pgo-job "%PGO%" +) else ( + set PGOOPTS= +) +if not "%SKIPBUILD%" EQU "1" ( + @echo call "%PCBUILD%build.bat" -e -p %BUILD_PLAT% -t %TARGET% %PGOOPTS% %CERTOPTS% + @call "%PCBUILD%build.bat" -e -p %BUILD_PLAT% -t %TARGET% %PGOOPTS% %CERTOPTS% + @if errorlevel 1 exit /B %ERRORLEVEL% + @rem build.bat turns echo back on, so we disable it again + @echo off + + @echo call "%PCBUILD%build.bat" -d -e -p %BUILD_PLAT% -t %TARGET% + @call "%PCBUILD%build.bat" -d -e -p %BUILD_PLAT% -t %TARGET% + @if errorlevel 1 exit /B %ERRORLEVEL% + @rem build.bat turns echo back on, so we disable it again + @echo off +) + +if "%OUTDIR_PLAT%" EQU "win32" ( + %MSBUILD% "%D%launcher\launcher.wixproj" /p:Platform=x86 %CERTOPTS% /p:ReleaseUri=%RELEASE_URI% + if errorlevel 1 exit /B %ERRORLEVEL% +) else if not exist "%Py_OutDir%win32\en-us\launcher.msi" ( + %MSBUILD% "%D%launcher\launcher.wixproj" /p:Platform=x86 %CERTOPTS% /p:ReleaseUri=%RELEASE_URI% + if errorlevel 1 exit /B %ERRORLEVEL% +) + +set BUILDOPTS=/p:Platform=%1 /p:BuildForRelease=true /p:DownloadUrl=%DOWNLOAD_URL% /p:DownloadUrlBase=%DOWNLOAD_URL_BASE% /p:ReleaseUri=%RELEASE_URI% +if defined BUILDMSI ( + %MSBUILD% "%D%bundle\releaselocal.wixproj" /t:Rebuild %BUILDOPTS% %CERTOPTS% /p:RebuildAll=true + if errorlevel 1 exit /B %ERRORLEVEL% +) + +if defined BUILDZIP ( + if "%BUILD_PLAT%" EQU "ARM64" ( + echo Skipping embeddable ZIP generation for ARM64 platform + ) else ( + %MSBUILD% "%D%make_zip.proj" /t:Build %BUILDOPTS% %CERTOPTS% /p:OutputPath="%BUILD%en-us" + if errorlevel 1 exit /B %ERRORLEVEL% + ) +) + +if defined BUILDNUGET ( + if "%BUILD_PLAT%" EQU "ARM64" ( + echo Skipping Nuget package generation for ARM64 platform + ) else ( + %MSBUILD% "%D%..\nuget\make_pkg.proj" /t:Build /p:Configuration=Release /p:Platform=%1 /p:OutputPath="%BUILD%en-us" + if errorlevel 1 exit /B %ERRORLEVEL% + ) +) + +if not "%OUTDIR%" EQU "" ( + mkdir "%OUTDIR%\%OUTDIR_PLAT%" + mkdir "%OUTDIR%\%OUTDIR_PLAT%\binaries" + mkdir "%OUTDIR%\%OUTDIR_PLAT%\symbols" + robocopy "%BUILD%en-us" "%OUTDIR%\%OUTDIR_PLAT%" /XF "*.wixpdb" + robocopy "%BUILD%\" "%OUTDIR%\%OUTDIR_PLAT%\binaries" *.exe *.dll *.pyd /XF "_test*" /XF "*_d.*" /XF "_freeze*" /XF "tcl*" /XF "tk*" /XF "*_test.*" + robocopy "%BUILD%\" "%OUTDIR%\%OUTDIR_PLAT%\symbols" *.pdb /XF "_test*" /XF "*_d.*" /XF "_freeze*" /XF "tcl*" /XF "tk*" /XF "*_test.*" +) + +exit /B 0 + +:Help +echo buildrelease.bat [--out DIR] [-x86] [-x64] [-arm64] [--certificate CERTNAME] [--build] [--pgo COMMAND] +echo [--skip-build] [--skip-doc] [--skip-nuget] [--skip-zip] [--skip-pgo] +echo [--download DOWNLOAD URL] [--test TARGETDIR] +echo [-h] +echo. +echo --out (-o) Specify an additional output directory for installers +echo -x86 Build x86 installers +echo -x64 Build x64 installers +echo -arm64 Build ARM64 installers +echo --build (-b) Incrementally build Python rather than rebuilding +echo --skip-build (-B) Do not build Python (just do the installers) +echo --skip-doc (-D) Do not build documentation +echo --pgo Specify PGO command for x64 installers +echo --skip-pgo Build x64 installers without using PGO +echo --skip-msi Do not build executable/MSI packages +echo --skip-nuget Do not build Nuget packages +echo --skip-zip Do not build embeddable package +echo --download Specify the full download URL for MSIs +echo --test Specify the test directory to run the installer tests +echo -h Display this help information +echo. +echo If no architecture is specified, all architectures will be built. +echo If --test is not specified, the installer tests are not run. +echo. +echo For the --pgo option, any Python command line can be used, or 'default' to +echo use the default task (-m test --pgo). +echo. +echo x86 and ARM64 builds will never use PGO. ARM64 builds will never generate +echo embeddable or Nuget packages. +echo. +echo The following substitutions will be applied to the download URL: +echo Variable Description Example +echo {version} version number 3.5.0 +echo {arch} architecture amd64, win32 +echo {releasename} release name a1, b2, rc3 (or blank for final) +echo {msi} MSI filename core.msi diff --git a/Tools/msi/bundle/Default.wxl b/Tools/msi/bundle/Default.wxl index d65dd836..6f8befba 100644 --- a/Tools/msi/bundle/Default.wxl +++ b/Tools/msi/bundle/Default.wxl @@ -112,19 +112,18 @@ See <a href="https://docs.python.org/[ShortVersion]/whatsnew/[ShortVersion].h <String Id="SuccessModifyMessage">Thank you for using [WixBundleName].</String> <String Id="SuccessRepairMessage">Thank you for using [WixBundleName]. -Feel free to email <a href="mailto:python-list@python.org">python-list@python.org</a> if you continue to encounter issues.</String> +Feel free to post at <a href="https://discuss.python.org/c/users/7">discuss.python.org</a> if you continue to encounter issues.</String> <String Id="SuccessRemoveMessage">Thank you for using [WixBundleName]. -Feel free to email <a href="mailto:python-list@python.org">python-list@python.org</a> if you encountered problems.</String> +Feel free to post at <a href="https://discuss.python.org/c/users/7">discuss.python.org</a> if you encountered problems.</String> <String Id="FailureHeader">Setup failed</String> <String Id="FailureHyperlinkLogText">One or more issues caused the setup to fail. Please fix the issues and then retry setup. For more information see the <a href="#">log file</a>.</String> <String Id="FailureRestartText">You must restart your computer to complete the rollback of the software.</String> <String Id="FailureRestartButton">&Restart</String> <String Id="FailureExistingInstall">Unable to install [WixBundleName] due to an existing install. Use Programs and Features to modify, repair or remove [WixBundleName].</String> - <String Id="FailureOldOS">At least Windows 8.1 or Windows Server 2012 are required to install [WixBundleName] -Visit <a href="https://www.python.org/">python.org</a> to download an earlier version of Python.</String> +Visit <a href="https://www.python.org/downloads/">python.org</a> to download an earlier version of Python.</String> <String Id="SuccessMaxPathButton">Disable path length limit</String> <String Id="SuccessMaxPathButtonNote">Changes your machine configuration to allow programs, including Python, to bypass the 260 character "MAX_PATH" limitation.</String> </WixLocalization> diff --git a/Tools/msi/bundle/bootstrap/pch.h b/Tools/msi/bundle/bootstrap/pch.h index b0aa5111..6d0974b3 100644 --- a/Tools/msi/bundle/bootstrap/pch.h +++ b/Tools/msi/bundle/bootstrap/pch.h @@ -5,7 +5,7 @@ // The license and further copyright text can be found in the file // LICENSE.TXT at the root directory of the distribution. // </copyright> -// +// // <summary> // Precompiled header for standard bootstrapper application. // </summary> diff --git a/Tools/msi/bundle/bootstrap/pythonba.sln b/Tools/msi/bundle/bootstrap/pythonba.sln index 48571804..bf43fed9 100644 --- a/Tools/msi/bundle/bootstrap/pythonba.sln +++ b/Tools/msi/bundle/bootstrap/pythonba.sln @@ -1,22 +1,22 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2013 -VisualStudioVersion = 12.0.30501.0 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pythonba", "pythonba.vcxproj", "{7A09B132-B3EE-499B-A700-A4B2157FEA3D}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Release|Win32 = Release|Win32 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {7A09B132-B3EE-499B-A700-A4B2157FEA3D}.Debug|Win32.ActiveCfg = Debug|Win32 - {7A09B132-B3EE-499B-A700-A4B2157FEA3D}.Debug|Win32.Build.0 = Debug|Win32 - {7A09B132-B3EE-499B-A700-A4B2157FEA3D}.Release|Win32.ActiveCfg = Release|Win32 - {7A09B132-B3EE-499B-A700-A4B2157FEA3D}.Release|Win32.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.30501.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pythonba", "pythonba.vcxproj", "{7A09B132-B3EE-499B-A700-A4B2157FEA3D}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {7A09B132-B3EE-499B-A700-A4B2157FEA3D}.Debug|Win32.ActiveCfg = Debug|Win32 + {7A09B132-B3EE-499B-A700-A4B2157FEA3D}.Debug|Win32.Build.0 = Debug|Win32 + {7A09B132-B3EE-499B-A700-A4B2157FEA3D}.Release|Win32.ActiveCfg = Release|Win32 + {7A09B132-B3EE-499B-A700-A4B2157FEA3D}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Tools/msi/bundle/bootstrap/pythonba.vcxproj b/Tools/msi/bundle/bootstrap/pythonba.vcxproj index db053ba0..bb383bfc 100644 --- a/Tools/msi/bundle/bootstrap/pythonba.vcxproj +++ b/Tools/msi/bundle/bootstrap/pythonba.vcxproj @@ -1,75 +1,75 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - <copyright file="wixstdba.vcxproj" company="Outercurve Foundation"> - Copyright (c) 2004, Outercurve Foundation. - This software is released under Microsoft Reciprocal License (MS-RL). - The license and further copyright text can be found in the file - LICENSE.TXT at the root directory of the distribution. - </copyright> ---> -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <Configuration Condition="'$(Configuration)' == ''">Release</Configuration> - <Platform Condition="'$(Platform)' == ''">Win32</Platform> - <PlatformToolset Condition="'$(PlatformToolset)' == '' and '$(VisualStudioVersion)' == '17.0'">v143</PlatformToolset> - <PlatformToolset Condition="'$(PlatformToolset)' == '' and '$(VisualStudioVersion)' == '16.0'">v142</PlatformToolset> - <PlatformToolset Condition="'$(PlatformToolset)' == '' and ('$(MSBuildToolsVersion)' == '15.0' or '$(VisualStudioVersion)' == '15.0')">v141</PlatformToolset> - <PlatformToolset Condition="'$(PlatformToolset)' == ''">v140</PlatformToolset> - <ProjectGuid>{7A09B132-B3EE-499B-A700-A4B2157FEA3D}</ProjectGuid> - <TargetName>PythonBA</TargetName> - </PropertyGroup> - <Import Project="..\..\wix.props" /> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <CharacterSet>Unicode</CharacterSet> - <Py_IntDir Condition="'$(Py_IntDir)' == ''">$(PySourcePath)PCbuild\obj\</Py_IntDir> - <IntDir>$(Py_IntDir)\$(MajorVersionNumber)$(MinorVersionNumber)$(ArchName)_$(Configuration)\msi_$(ProjectName)\</IntDir> - <IntDir>$(IntDir.Replace(`\\`, `\`))</IntDir> - <OutDir>$(IntDir)</OutDir> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ItemDefinitionGroup> - <ClCompile> - <PreprocessorDefinitions Condition="$(BuildForPlatform) == 'ARM64'">ARM64=1;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <PreprocessorDefinitions>_CRT_STDIO_LEGACY_WIDE_SPECIFIERS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories>$(WixInstallPath)sdk\inc</AdditionalIncludeDirectories> - <PrecompiledHeader>Use</PrecompiledHeader> - <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile> - <RuntimeLibrary>MultiThreaded</RuntimeLibrary> - </ClCompile> - <Link> - <AdditionalDependencies>comctl32.lib;gdiplus.lib;msimg32.lib;shlwapi.lib;wininet.lib;dutil.lib;balutil.lib;version.lib;uxtheme.lib;%(AdditionalDependencies)</AdditionalDependencies> - <AdditionalLibraryDirectories Condition="$(PlatformToolset.StartsWith(`v14`))">$(WixInstallPath)sdk\vs2017\lib\x86</AdditionalLibraryDirectories> - <AdditionalLibraryDirectories Condition="'$(PlatformToolset)' == 'v140'">$(WixInstallPath)sdk\vs2015\lib\x86</AdditionalLibraryDirectories> - <AdditionalLibraryDirectories Condition="'$(PlatformToolset)' == 'v120'">$(WixInstallPath)sdk\vs2013\lib\x86</AdditionalLibraryDirectories> - <ModuleDefinitionFile>pythonba.def</ModuleDefinitionFile> - <GenerateDebugInformation Condition="'$(Configuration)'=='Debug'">true</GenerateDebugInformation> - </Link> - </ItemDefinitionGroup> - <ItemGroup> - <ClCompile Include="PythonBootstrapperApplication.cpp" /> - <ClCompile Include="pythonba.cpp" /> - <ClCompile Include="pch.cpp"> - <PrecompiledHeader>Create</PrecompiledHeader> - </ClCompile> - </ItemGroup> - <ItemGroup> - <ClInclude Include="pch.h" /> - <ClInclude Include="resource.h" /> - </ItemGroup> - <ItemGroup> - <None Include="pythonba.def" /> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> -</Project> +<?xml version="1.0" encoding="utf-8"?> +<!-- + <copyright file="wixstdba.vcxproj" company="Outercurve Foundation"> + Copyright (c) 2004, Outercurve Foundation. + This software is released under Microsoft Reciprocal License (MS-RL). + The license and further copyright text can be found in the file + LICENSE.TXT at the root directory of the distribution. + </copyright> +--> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <Configuration Condition="'$(Configuration)' == ''">Release</Configuration> + <Platform Condition="'$(Platform)' == ''">Win32</Platform> + <PlatformToolset Condition="'$(PlatformToolset)' == '' and '$(VisualStudioVersion)' == '17.0'">v143</PlatformToolset> + <PlatformToolset Condition="'$(PlatformToolset)' == '' and '$(VisualStudioVersion)' == '16.0'">v142</PlatformToolset> + <PlatformToolset Condition="'$(PlatformToolset)' == '' and ('$(MSBuildToolsVersion)' == '15.0' or '$(VisualStudioVersion)' == '15.0')">v141</PlatformToolset> + <PlatformToolset Condition="'$(PlatformToolset)' == ''">v140</PlatformToolset> + <ProjectGuid>{7A09B132-B3EE-499B-A700-A4B2157FEA3D}</ProjectGuid> + <TargetName>PythonBA</TargetName> + </PropertyGroup> + <Import Project="..\..\wix.props" /> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <CharacterSet>Unicode</CharacterSet> + <Py_IntDir Condition="'$(Py_IntDir)' == ''">$(PySourcePath)PCbuild\obj\</Py_IntDir> + <IntDir>$(Py_IntDir)\$(MajorVersionNumber)$(MinorVersionNumber)$(ArchName)_$(Configuration)\msi_$(ProjectName)\</IntDir> + <IntDir>$(IntDir.Replace(`\\`, `\`))</IntDir> + <OutDir>$(IntDir)</OutDir> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ItemDefinitionGroup> + <ClCompile> + <PreprocessorDefinitions Condition="$(BuildForPlatform) == 'ARM64'">ARM64=1;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>_CRT_STDIO_LEGACY_WIDE_SPECIFIERS=1;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(WixInstallPath)sdk\inc</AdditionalIncludeDirectories> + <PrecompiledHeader>Use</PrecompiledHeader> + <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <AdditionalDependencies>comctl32.lib;gdiplus.lib;msimg32.lib;shlwapi.lib;wininet.lib;dutil.lib;balutil.lib;version.lib;uxtheme.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories Condition="$(PlatformToolset.StartsWith(`v14`))">$(WixInstallPath)sdk\vs2017\lib\x86</AdditionalLibraryDirectories> + <AdditionalLibraryDirectories Condition="'$(PlatformToolset)' == 'v140'">$(WixInstallPath)sdk\vs2015\lib\x86</AdditionalLibraryDirectories> + <AdditionalLibraryDirectories Condition="'$(PlatformToolset)' == 'v120'">$(WixInstallPath)sdk\vs2013\lib\x86</AdditionalLibraryDirectories> + <ModuleDefinitionFile>pythonba.def</ModuleDefinitionFile> + <GenerateDebugInformation Condition="'$(Configuration)'=='Debug'">true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="PythonBootstrapperApplication.cpp" /> + <ClCompile Include="pythonba.cpp" /> + <ClCompile Include="pch.cpp"> + <PrecompiledHeader>Create</PrecompiledHeader> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="pch.h" /> + <ClInclude Include="resource.h" /> + </ItemGroup> + <ItemGroup> + <None Include="pythonba.def" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> +</Project> diff --git a/Tools/msi/bundle/bootstrap/resource.h b/Tools/msi/bundle/bootstrap/resource.h index 53c03c31..d951e651 100644 --- a/Tools/msi/bundle/bootstrap/resource.h +++ b/Tools/msi/bundle/bootstrap/resource.h @@ -14,7 +14,7 @@ // Next default values for new objects -// +// #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 102 diff --git a/Tools/msi/bundle/bundle.targets b/Tools/msi/bundle/bundle.targets index 89a5960a..9c7410fe 100644 --- a/Tools/msi/bundle/bundle.targets +++ b/Tools/msi/bundle/bundle.targets @@ -71,7 +71,6 @@ <Package Include="..\pip\pip*.wixproj" /> <Package Include="..\tcltk\tcltk*.wixproj" /> <Package Include="..\test\test*.wixproj" /> - <Package Include="..\tools\tools*.wixproj" /> <Package Include="..\ucrt\ucrt*.wixproj" Condition="$(Platform) != 'ARM64'" /> </ItemGroup> diff --git a/Tools/msi/bundle/bundle.wxs b/Tools/msi/bundle/bundle.wxs index 19e67faf..8b12baae 100644 --- a/Tools/msi/bundle/bundle.wxs +++ b/Tools/msi/bundle/bundle.wxs @@ -28,7 +28,7 @@ <Variable Name="InstallAllUsers" Value="0" bal:Overridable="yes" /> <?if "$(var.PyTestExt)"="" ?> - <Variable Name="InstallLauncherAllUsers" Value="1" bal:Overridable="yes" /> + <Variable Name="InstallLauncherAllUsers" Value="0" bal:Overridable="yes" /> <?else ?> <Variable Name="InstallLauncherAllUsers" Value="0" /> <?endif ?> @@ -71,7 +71,7 @@ <Variable Name="Include_lib" Value="1" bal:Overridable="yes" /> <Variable Name="Include_test" Value="1" bal:Overridable="yes" /> <Variable Name="Include_doc" Value="1" bal:Overridable="yes" /> - <Variable Name="Include_tools" Value="1" bal:Overridable="yes" /> + <Variable Name="Include_tools" Value="0" bal:Overridable="yes" /> <Variable Name="Include_tcltk" Value="1" bal:Overridable="yes" /> <Variable Name="Include_pip" Value="1" bal:Overridable="yes" /> <Variable Name="Include_launcher" Value="-1" bal:Overridable="yes" /> @@ -106,7 +106,6 @@ <PackageGroupRef Id="lib" /> <PackageGroupRef Id="test" /> <PackageGroupRef Id="doc" /> - <PackageGroupRef Id="tools" /> <PackageGroupRef Id="tcltk" /> <PackageGroupRef Id="launcher" /> <PackageGroupRef Id="pip" /> diff --git a/Tools/msi/bundle/packagegroups/tools.wxs b/Tools/msi/bundle/packagegroups/tools.wxs deleted file mode 100644 index 1d9ab19f..00000000 --- a/Tools/msi/bundle/packagegroups/tools.wxs +++ /dev/null @@ -1,26 +0,0 @@ -<?xml version="1.0"?> -<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"> - <Fragment> - <PackageGroup Id="tools"> - <MsiPackage Id="tools_AllUsers" - SourceFile="tools.msi" - Compressed="$(var.CompressMSI)" - DownloadUrl="$(var.DownloadUrl)" - ForcePerMachine="yes" - InstallCondition="InstallAllUsers and Include_tools and not LauncherOnly"> - <MsiProperty Name="TARGETDIR" Value="[TargetDir]" /> - <MsiProperty Name="OPTIONALFEATURESREGISTRYKEY" Value="[OptionalFeaturesRegistryKey]" /> - </MsiPackage> - - <MsiPackage Id="tools_JustForMe" - SourceFile="tools.msi" - Compressed="$(var.CompressMSI)" - DownloadUrl="$(var.DownloadUrl)" - ForcePerMachine="no" - InstallCondition="not InstallAllUsers and Include_tools and not LauncherOnly"> - <MsiProperty Name="TARGETDIR" Value="[TargetDir]" /> - <MsiProperty Name="OPTIONALFEATURESREGISTRYKEY" Value="[OptionalFeaturesRegistryKey]" /> - </MsiPackage> - </PackageGroup> - </Fragment> -</Wix> \ No newline at end of file diff --git a/Tools/msi/common.wxs b/Tools/msi/common.wxs index b819d320..54fa749a 100644 --- a/Tools/msi/common.wxs +++ b/Tools/msi/common.wxs @@ -25,7 +25,6 @@ <UpgradeVersion Property="DOWNGRADE" Minimum="$(var.Version)" IncludeMinimum="no" OnlyDetect="yes" /> <UpgradeVersion Property="UPGRADE" Minimum="$(var.UpgradeMinimumVersion)" IncludeMinimum="yes" Maximum="$(var.Version)" IncludeMaximum="no" /> </Upgrade> - <?endif ?> <?ifdef CoreUpgradeCode ?> <?if $(var.UpgradeCode)!=$(var.CoreUpgradeCode) ?> @@ -42,6 +41,7 @@ <InstallExecuteSequence> <RemoveExistingProducts After="InstallInitialize" Overridable="yes">UPGRADE</RemoveExistingProducts> </InstallExecuteSequence> + <?endif ?> </Fragment> <Fragment> @@ -121,12 +121,6 @@ </DirectoryRef> </Fragment> - <Fragment> - <DirectoryRef Id="InstallDirectory"> - <Directory Id="Tools" Name="Tools" /> - </DirectoryRef> - </Fragment> - <!-- Start Menu folder --> <Fragment> <DirectoryRef Id="TARGETDIR"> diff --git a/Tools/msi/get_externals.bat b/Tools/msi/get_externals.bat index bf139b65..f6602ce9 100644 --- a/Tools/msi/get_externals.bat +++ b/Tools/msi/get_externals.bat @@ -1,91 +1,91 @@ -@echo off -setlocal -rem Simple script to fetch source for external libraries - -set HERE=%~dp0 -if "%PCBUILD%"=="" (set PCBUILD=%HERE%..\..\PCbuild\) -if "%EXTERNALS_DIR%"=="" (set EXTERNALS_DIR=%HERE%..\..\externals\windows-installer) -if "%NUGET%"=="" (set NUGET=%EXTERNALS_DIR%\..\nuget.exe) -if "%NUGET_URL%"=="" (set NUGET_URL=https://aka.ms/nugetclidl) - -set DO_FETCH=true -set DO_CLEAN=false - -:CheckOpts -if "%~1"=="--python" (set PYTHON=%2) & shift & shift & goto CheckOpts -if "%~1"=="--organization" (set ORG=%2) & shift & shift & goto CheckOpts -if "%~1"=="-c" (set DO_CLEAN=true) & shift & goto CheckOpts -if "%~1"=="--clean" (set DO_CLEAN=true) & shift & goto CheckOpts -if "%~1"=="--clean-only" (set DO_FETCH=false) & goto clean -if "x%~1" NEQ "x" goto usage - -if "%DO_CLEAN%"=="false" goto fetch -:clean -echo.Cleaning up external libraries. -if exist "%EXTERNALS_DIR%" ( - rem Sometimes this fails the first time; try it twice - rmdir /s /q "%EXTERNALS_DIR%" || rmdir /s /q "%EXTERNALS_DIR%" -) - -if "%DO_FETCH%"=="false" goto end -:fetch - -if "%ORG%"=="" (set ORG=python) - -call "%PCBUILD%\find_python.bat" "%PYTHON%" - -echo.Fetching external libraries... - -set libraries= - -for %%e in (%libraries%) do ( - if exist "%EXTERNALS_DIR%\%%e" ( - echo.%%e already exists, skipping. - ) else ( - echo.Fetching %%e... - %PYTHON% "%PCBUILD%get_external.py" -e "%EXTERNALS_DIR%" -O %ORG% %%e - ) -) - -echo.Fetching external tools... - -set binaries= -rem We always use whatever's latest in the repo for these -set binaries=%binaries% binutils -set binaries=%binaries% gpg -set binaries=%binaries% htmlhelp -set binaries=%binaries% nuget -set binaries=%binaries% redist-1 -set binaries=%binaries% wix-314 - -for %%b in (%binaries%) do ( - if exist "%EXTERNALS_DIR%\%%b" ( - echo.%%b already exists, skipping. - ) else ( - echo.Fetching %%b... - %PYTHON% "%PCBUILD%get_external.py" -e "%EXTERNALS_DIR%" -b -O %ORG% %%b - ) -) - -echo Finished. -goto end - -:usage -echo.Valid options: -c, --clean, --clean-only, --organization, --python, -echo.--no-tkinter, --no-openssl -echo. -echo.Pull all sources and binaries necessary for compiling optional extension -echo.modules that rely on external libraries. -echo. -echo.The --organization option determines which github organization to download -echo.from, the --python option determines which Python 3.6+ interpreter to use -echo.with PCbuild\get_external.py. -echo. -echo.Use the -c or --clean option to remove the entire externals directory. -echo. -echo.Use the --clean-only option to do the same cleaning, without pulling in -echo.anything new. -echo. -exit /b -1 - -:end +@echo off +setlocal +rem Simple script to fetch source for external libraries + +set HERE=%~dp0 +if "%PCBUILD%"=="" (set PCBUILD=%HERE%..\..\PCbuild\) +if "%EXTERNALS_DIR%"=="" (set EXTERNALS_DIR=%HERE%..\..\externals\windows-installer) +if "%NUGET%"=="" (set NUGET=%EXTERNALS_DIR%\..\nuget.exe) +if "%NUGET_URL%"=="" (set NUGET_URL=https://aka.ms/nugetclidl) + +set DO_FETCH=true +set DO_CLEAN=false + +:CheckOpts +if "%~1"=="--python" (set PYTHON=%2) & shift & shift & goto CheckOpts +if "%~1"=="--organization" (set ORG=%2) & shift & shift & goto CheckOpts +if "%~1"=="-c" (set DO_CLEAN=true) & shift & goto CheckOpts +if "%~1"=="--clean" (set DO_CLEAN=true) & shift & goto CheckOpts +if "%~1"=="--clean-only" (set DO_FETCH=false) & goto clean +if "x%~1" NEQ "x" goto usage + +if "%DO_CLEAN%"=="false" goto fetch +:clean +echo.Cleaning up external libraries. +if exist "%EXTERNALS_DIR%" ( + rem Sometimes this fails the first time; try it twice + rmdir /s /q "%EXTERNALS_DIR%" || rmdir /s /q "%EXTERNALS_DIR%" +) + +if "%DO_FETCH%"=="false" goto end +:fetch + +if "%ORG%"=="" (set ORG=python) + +call "%PCBUILD%\find_python.bat" "%PYTHON%" + +echo.Fetching external libraries... + +set libraries= + +for %%e in (%libraries%) do ( + if exist "%EXTERNALS_DIR%\%%e" ( + echo.%%e already exists, skipping. + ) else ( + echo.Fetching %%e... + %PYTHON% "%PCBUILD%get_external.py" -e "%EXTERNALS_DIR%" -O %ORG% %%e + ) +) + +echo.Fetching external tools... + +set binaries= +rem We always use whatever's latest in the repo for these +set binaries=%binaries% binutils +set binaries=%binaries% gpg +set binaries=%binaries% htmlhelp +set binaries=%binaries% nuget +set binaries=%binaries% redist-1 +set binaries=%binaries% wix-314 + +for %%b in (%binaries%) do ( + if exist "%EXTERNALS_DIR%\%%b" ( + echo.%%b already exists, skipping. + ) else ( + echo.Fetching %%b... + %PYTHON% "%PCBUILD%get_external.py" -e "%EXTERNALS_DIR%" -b -O %ORG% %%b + ) +) + +echo Finished. +goto end + +:usage +echo.Valid options: -c, --clean, --clean-only, --organization, --python, +echo.--no-tkinter, --no-openssl +echo. +echo.Pull all sources and binaries necessary for compiling optional extension +echo.modules that rely on external libraries. +echo. +echo.The --organization option determines which github organization to download +echo.from, the --python option determines which Python 3.6+ interpreter to use +echo.with PCbuild\get_external.py. +echo. +echo.Use the -c or --clean option to remove the entire externals directory. +echo. +echo.Use the --clean-only option to do the same cleaning, without pulling in +echo.anything new. +echo. +exit /b -1 + +:end diff --git a/Tools/msi/launcher/launcher.wxs b/Tools/msi/launcher/launcher.wxs index b83058c6..49f1f7b8 100644 --- a/Tools/msi/launcher/launcher.wxs +++ b/Tools/msi/launcher/launcher.wxs @@ -34,13 +34,34 @@ <Custom Before="SetLauncherInstallDirectoryLM" Action="SetLauncherInstallDirectoryCU">NOT Installed AND NOT ALLUSERS=1</Custom> <Custom Before="CostFinalize" Action="SetLauncherInstallDirectoryLM">NOT Installed AND ALLUSERS=1</Custom> + <?if $(var.UpgradeMinimumVersion)="3.11.0.0" ?> + <RemoveExistingProducts After="InstallValidate">UPGRADE or REMOVE_350_LAUNCHER or REMOVE_360A1_LAUNCHER or UPGRADE_3_11_0 or UPGRADE_3_11_1</RemoveExistingProducts> + <?else ?> <RemoveExistingProducts After="InstallValidate">UPGRADE or REMOVE_350_LAUNCHER or REMOVE_360A1_LAUNCHER</RemoveExistingProducts> + <?endif ?> </InstallExecuteSequence> + <?if $(var.UpgradeMinimumVersion)="3.11.0.0" ?> + <Condition Message="!(loc.NoDowngrade)">Installed OR NOT DOWNGRADE OR UPGRADE_3_11_0 OR UPGRADE_3_11_1</Condition> + <?else ?> + <Condition Message="!(loc.NoDowngrade)">Installed OR NOT DOWNGRADE</Condition> + <?endif ?> + <!-- Upgrade all versions of the launcher --> <Upgrade Id="$(var.UpgradeCode)"> <UpgradeVersion Property="DOWNGRADE" Minimum="$(var.Version)" IncludeMinimum="no" OnlyDetect="yes" /> <UpgradeVersion Property="UPGRADE" Minimum="0.0.0.0" IncludeMinimum="yes" Maximum="$(var.Version)" IncludeMaximum="no" /> + <!-- + Prior to 3.11.2150, version numbers incorrectly used date-based + revision numbers in the third field. Because these are higher than + the real version, it prevents upgrades. + Releases of 3.10 have a similar issue, however, no significant + changes have shipped in the launcher, so we don't worry about it. + --> + <?if $(var.UpgradeMinimumVersion)="3.11.0.0" ?> + <UpgradeVersion Property="UPGRADE_3_11_0" Minimum="3.11.7966.0" IncludeMinimum="yes" Maximum="3.11.7966.0" IncludeMaximum="yes" /> + <UpgradeVersion Property="UPGRADE_3_11_1" Minimum="3.11.8009.0" IncludeMinimum="yes" Maximum="3.11.8009.0" IncludeMaximum="yes" /> + <?endif ?> </Upgrade> <!-- Python 3.5.0 shipped with a different UpgradeCode --> <Upgrade Id="A71530B9-E89D-53DB-9C2D-C6D7551876D8"> diff --git a/Tools/msi/lib/lib_files.wxs b/Tools/msi/lib/lib_files.wxs index 64c046e6..73c02313 100644 --- a/Tools/msi/lib/lib_files.wxs +++ b/Tools/msi/lib/lib_files.wxs @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"> - <?define exts=pyexpat;select;unicodedata;winsound;_bz2;_elementtree;_socket;_ssl;_msi;_ctypes;_hashlib;_multiprocessing;_lzma;_decimal;_overlapped;_sqlite3;_asyncio;_queue;_uuid;_zoneinfo ?> + <?define exts=pyexpat;select;unicodedata;winsound;_bz2;_elementtree;_socket;_ssl;_msi;_ctypes;_hashlib;_multiprocessing;_lzma;_decimal;_overlapped;_sqlite3;_asyncio;_queue;_uuid;_wmi;_zoneinfo ?> <Fragment> <DirectoryRef Id="Lib_venv_scripts_nt" /> diff --git a/Tools/msi/make_appx.ps1 b/Tools/msi/make_appx.ps1 index 9ca2b350..e32bd76a 100644 --- a/Tools/msi/make_appx.ps1 +++ b/Tools/msi/make_appx.ps1 @@ -1,71 +1,71 @@ -<# -.Synopsis - Compiles and signs an APPX package -.Description - Given the file listing, ensures all the contents are signed - and builds and signs the final package. -.Parameter mapfile - The location on disk of the text mapping file. -.Parameter msix - The path and name to store the APPX/MSIX. -.Parameter sign - When set, signs the APPX/MSIX. Packages to be published to - the store should not be signed. -.Parameter description - Description to embed in the signature (optional). -.Parameter certname - The name of the certificate to sign with (optional). -.Parameter certsha1 - The SHA1 hash of the certificate to sign with (optional). -#> -param( - [Parameter(Mandatory=$true)][string]$layout, - [Parameter(Mandatory=$true)][string]$msix, - [switch]$sign, - [string]$description, - [string]$certname, - [string]$certsha1, - [string]$certfile -) - -$tools = $script:MyInvocation.MyCommand.Path | Split-Path -parent; -Import-Module $tools\sdktools.psm1 -WarningAction SilentlyContinue -Force - -Set-Alias makeappx (Find-Tool "makeappx.exe") -Scope Script -Set-Alias makepri (Find-Tool "makepri.exe") -Scope Script - -$msixdir = Split-Path $msix -Parent -if ($msixdir) { - $msixdir = (mkdir -Force $msixdir).FullName -} else { - $msixdir = Get-Location -} -$msix = Join-Path $msixdir (Split-Path $msix -Leaf) - -pushd $layout -try { - if (Test-Path resources.pri) { - del resources.pri - } - $name = ([xml](gc AppxManifest.xml)).Package.Identity.Name - makepri new /pr . /mn AppxManifest.xml /in $name /cf _resources.xml /of _resources.pri /mf appx /o - if (-not $? -or -not (Test-Path _resources.map.txt)) { - throw "makepri step failed" - } - $lines = gc _resources.map.txt - $lines | ?{ -not ($_ -match '"_resources[\w\.]+?"') } | Out-File _resources.map.txt -Encoding utf8 - makeappx pack /f _resources.map.txt /m AppxManifest.xml /o /p $msix - if (-not $?) { - throw "makeappx step failed" - } -} finally { - popd -} - -if ($sign) { - Sign-File -certname $certname -certsha1 $certsha1 -certfile $certfile -description $description -files $msix - - if (-not $?) { - throw "Package signing failed" - } -} +<# +.Synopsis + Compiles and signs an APPX package +.Description + Given the file listing, ensures all the contents are signed + and builds and signs the final package. +.Parameter mapfile + The location on disk of the text mapping file. +.Parameter msix + The path and name to store the APPX/MSIX. +.Parameter sign + When set, signs the APPX/MSIX. Packages to be published to + the store should not be signed. +.Parameter description + Description to embed in the signature (optional). +.Parameter certname + The name of the certificate to sign with (optional). +.Parameter certsha1 + The SHA1 hash of the certificate to sign with (optional). +#> +param( + [Parameter(Mandatory=$true)][string]$layout, + [Parameter(Mandatory=$true)][string]$msix, + [switch]$sign, + [string]$description, + [string]$certname, + [string]$certsha1, + [string]$certfile +) + +$tools = $script:MyInvocation.MyCommand.Path | Split-Path -parent; +Import-Module $tools\sdktools.psm1 -WarningAction SilentlyContinue -Force + +Set-Alias makeappx (Find-Tool "makeappx.exe") -Scope Script +Set-Alias makepri (Find-Tool "makepri.exe") -Scope Script + +$msixdir = Split-Path $msix -Parent +if ($msixdir) { + $msixdir = (mkdir -Force $msixdir).FullName +} else { + $msixdir = Get-Location +} +$msix = Join-Path $msixdir (Split-Path $msix -Leaf) + +pushd $layout +try { + if (Test-Path resources.pri) { + del resources.pri + } + $name = ([xml](gc AppxManifest.xml)).Package.Identity.Name + makepri new /pr . /mn AppxManifest.xml /in $name /cf _resources.xml /of _resources.pri /mf appx /o + if (-not $? -or -not (Test-Path _resources.map.txt)) { + throw "makepri step failed" + } + $lines = gc _resources.map.txt + $lines | ?{ -not ($_ -match '"_resources[\w\.]+?"') } | Out-File _resources.map.txt -Encoding utf8 + makeappx pack /f _resources.map.txt /m AppxManifest.xml /o /p $msix + if (-not $?) { + throw "makeappx step failed" + } +} finally { + popd +} + +if ($sign) { + Sign-File -certname $certname -certsha1 $certsha1 -certfile $certfile -description $description -files $msix + + if (-not $?) { + throw "Package signing failed" + } +} diff --git a/Tools/msi/make_cat.ps1 b/Tools/msi/make_cat.ps1 index 374bc7cf..9ea3ddd4 100644 --- a/Tools/msi/make_cat.ps1 +++ b/Tools/msi/make_cat.ps1 @@ -1,45 +1,45 @@ -<# -.Synopsis - Compiles and signs a catalog file. -.Description - Given the CDF definition file, builds and signs a catalog. -.Parameter catalog - The path to the catalog definition file to compile and - sign. It is assumed that the .cat file will be the same - name with a new extension. -.Parameter outfile - The path to move the built .cat file to (optional). -.Parameter description - The description to add to the signature (optional). -.Parameter certname - The name of the certificate to sign with (optional). -.Parameter certsha1 - The SHA1 hash of the certificate to sign with (optional). -#> -param( - [Parameter(Mandatory=$true)][string]$catalog, - [string]$outfile, - [switch]$sign, - [string]$description, - [string]$certname, - [string]$certsha1, - [string]$certfile -) - -$tools = $script:MyInvocation.MyCommand.Path | Split-Path -parent; -Import-Module $tools\sdktools.psm1 -WarningAction SilentlyContinue -Force - -Set-Alias MakeCat (Find-Tool "makecat.exe") -Scope Script - -MakeCat $catalog -if (-not $?) { - throw "Catalog compilation failed" -} -if ($sign) { - Sign-File -certname $certname -certsha1 $certsha1 -certfile $certfile -description $description -files @($catalog -replace 'cdf$', 'cat') -} - -if ($outfile) { - Split-Path -Parent $outfile | ?{ $_ } | %{ mkdir -Force $_; } - Move-Item ($catalog -replace 'cdf$', 'cat') $outfile -} +<# +.Synopsis + Compiles and signs a catalog file. +.Description + Given the CDF definition file, builds and signs a catalog. +.Parameter catalog + The path to the catalog definition file to compile and + sign. It is assumed that the .cat file will be the same + name with a new extension. +.Parameter outfile + The path to move the built .cat file to (optional). +.Parameter description + The description to add to the signature (optional). +.Parameter certname + The name of the certificate to sign with (optional). +.Parameter certsha1 + The SHA1 hash of the certificate to sign with (optional). +#> +param( + [Parameter(Mandatory=$true)][string]$catalog, + [string]$outfile, + [switch]$sign, + [string]$description, + [string]$certname, + [string]$certsha1, + [string]$certfile +) + +$tools = $script:MyInvocation.MyCommand.Path | Split-Path -parent; +Import-Module $tools\sdktools.psm1 -WarningAction SilentlyContinue -Force + +Set-Alias MakeCat (Find-Tool "makecat.exe") -Scope Script + +MakeCat $catalog +if (-not $?) { + throw "Catalog compilation failed" +} +if ($sign) { + Sign-File -certname $certname -certsha1 $certsha1 -certfile $certfile -description $description -files @($catalog -replace 'cdf$', 'cat') +} + +if ($outfile) { + Split-Path -Parent $outfile | ?{ $_ } | %{ mkdir -Force $_; } + Move-Item ($catalog -replace 'cdf$', 'cat') $outfile +} diff --git a/Tools/msi/make_zip.proj b/Tools/msi/make_zip.proj index bc2f81fb..125a434e 100644 --- a/Tools/msi/make_zip.proj +++ b/Tools/msi/make_zip.proj @@ -1,40 +1,40 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <PropertyGroup> - <ProjectGuid>{10487945-15D1-4092-A214-338395C4116B}</ProjectGuid> - <OutputName>python</OutputName> - <OutputSuffix></OutputSuffix> - <SupportSigning>false</SupportSigning> - </PropertyGroup> - - <Import Project="msi.props" /> - - <PropertyGroup> - <SignOutput>false</SignOutput> - <TargetName>python-$(PythonVersion)-embed-$(ArchName)</TargetName> - <TargetExt>.zip</TargetExt> - <TargetPath>$(OutputPath)\$(TargetName)$(TargetExt)</TargetPath> - <CleanCommand>rmdir /q/s "$(IntermediateOutputPath)\zip_$(ArchName)"</CleanCommand> - <Arguments>"$(PythonExe)" "$(PySourcePath)PC\layout"</Arguments> - <Arguments>$(Arguments) -b "$(BuildPath.TrimEnd(`\`))" -s "$(PySourcePath.TrimEnd(`\`))"</Arguments> - <Arguments>$(Arguments) -t "$(IntermediateOutputPath)\zip_$(ArchName)"</Arguments> - <Arguments>$(Arguments) --zip "$(TargetPath)"</Arguments> - <Arguments>$(Arguments) --precompile --zip-lib --include-underpth --include-stable --flat-dlls</Arguments> - <Environment>$(Environment)%0D%0Aset PYTHONPATH=$(PySourcePath)Lib</Environment> - </PropertyGroup> - - <Target Name="_Build"> - <Exec Command="setlocal%0D%0A$(Environment)%0D%0A$(CleanCommand)%0D%0A$(Arguments)" /> - </Target> - - <Target Name="AfterBuild" /> - <Target Name="Build" DependsOnTargets="_Build;AfterBuild" /> - - <Target Name="ShowHashes"> - <ItemGroup> - <UserFiles Include="@(File)" Condition="'%(File.CopyTo)' == '$(EXETarget)'" /> - </ItemGroup> - - <Exec Command=""$(PythonExe)" generate_md5.py @(UserFiles->'"%(FullPath)"',' ')" /> - </Target> -</Project> +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup> + <ProjectGuid>{10487945-15D1-4092-A214-338395C4116B}</ProjectGuid> + <OutputName>python</OutputName> + <OutputSuffix></OutputSuffix> + <SupportSigning>false</SupportSigning> + </PropertyGroup> + + <Import Project="msi.props" /> + + <PropertyGroup> + <SignOutput>false</SignOutput> + <TargetName>python-$(PythonVersion)-embed-$(ArchName)</TargetName> + <TargetExt>.zip</TargetExt> + <TargetPath>$(OutputPath)\$(TargetName)$(TargetExt)</TargetPath> + <CleanCommand>rmdir /q/s "$(IntermediateOutputPath)\zip_$(ArchName)"</CleanCommand> + <Arguments>"$(PythonExe)" "$(PySourcePath)PC\layout"</Arguments> + <Arguments>$(Arguments) -b "$(BuildPath.TrimEnd(`\`))" -s "$(PySourcePath.TrimEnd(`\`))"</Arguments> + <Arguments>$(Arguments) -t "$(IntermediateOutputPath)\zip_$(ArchName)"</Arguments> + <Arguments>$(Arguments) --zip "$(TargetPath)"</Arguments> + <Arguments>$(Arguments) --precompile --zip-lib --include-underpth --include-stable --flat-dlls</Arguments> + <Environment>$(Environment)%0D%0Aset PYTHONPATH=$(PySourcePath)Lib</Environment> + </PropertyGroup> + + <Target Name="_Build"> + <Exec Command="setlocal%0D%0A$(Environment)%0D%0A$(CleanCommand)%0D%0A$(Arguments)" /> + </Target> + + <Target Name="AfterBuild" /> + <Target Name="Build" DependsOnTargets="_Build;AfterBuild" /> + + <Target Name="ShowHashes"> + <ItemGroup> + <UserFiles Include="@(File)" Condition="'%(File.CopyTo)' == '$(EXETarget)'" /> + </ItemGroup> + + <Exec Command=""$(PythonExe)" generate_md5.py @(UserFiles->'"%(FullPath)"',' ')" /> + </Target> +</Project> diff --git a/Tools/msi/msi.props b/Tools/msi/msi.props index 0669d2d7..06aa0b8b 100644 --- a/Tools/msi/msi.props +++ b/Tools/msi/msi.props @@ -1,190 +1,190 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" TreatAsLocalProperty="ReleaseUri"> - <PropertyGroup> - <TargetName>$(OutputName)</TargetName> - <DefineSolutionProperties>false</DefineSolutionProperties> - <TreatWarningsAsErrors>false</TreatWarningsAsErrors> - <SuppressIces>$(SuppressIces);ICE03;ICE57;ICE61</SuppressIces> - <CompilerSuppressSpecificWarnings>1026</CompilerSuppressSpecificWarnings> - <BuildForRelease Condition="'$(BuildForRelease)' == ''">false</BuildForRelease> - <SignOutput Condition="'$(SigningCertificate)' != ''">true</SignOutput> - <Configuration Condition="'$(Configuration)' == ''">Release</Configuration> - <Platform Condition="'$(Platform)' == ''">x86</Platform> - <InstallScope Condition="'$(InstallScope)' != 'perMachine'">perUser</InstallScope> - <_MakeCatCommand Condition="'$(_MakeCatCommand)' == ''">makecat</_MakeCatCommand> - <SkipCopySSLDLL>true</SkipCopySSLDLL> - </PropertyGroup> - - <Import Project="wix.props" /> - <Import Project="..\..\PCbuild\openssl.props" /> - <Import Project="..\..\PCbuild\tcltk.props" /> - - <PropertyGroup> - <!-- - This URI is used to generate the various GUIDs used by the installer. - Installers built with the same URI will upgrade each other or block - when attempting to downgrade. - - By default, this is the local computer name, which will produce - installers that do not interfere with other installers. Products - that intend to bundle Python should rebuild these modules with their - own URI to avoid conflicting with the official releases. - - The official releases use "https://www.python.org/$(ArchName)" - - This is not the same as the DownloadUrl property used in the bundle - projects. - --> - <ReleaseUri Condition="'$(ReleaseUri)' == ''">$(ComputerName)/$(ArchName)/</ReleaseUri> - <ReleaseUri Condition="!$(ReleaseUri.EndsWith(`/`))">$(ReleaseUri)/</ReleaseUri> - </PropertyGroup> - - - <ItemGroup> - <Compile Include="$(MSBuildThisFileDirectory)common.wxs" /> - <WxlTemplate Include="$(MSBuildThisFileDirectory)\*.wxl_template" Condition="$(IgnoreCommonWxlTemplates) != 'true'" /> - <WixExtension Include="WixUtilExtension"> - <HintPath>WixUtilExtension</HintPath> - <Name>WixUtilExtension</Name> - </WixExtension> - </ItemGroup> - - <PropertyGroup> - <IntermediateOutputPath>$(Py_IntDir)\$(MajorVersionNumber)$(MinorVersionNumber)$(ArchName)_$(Configuration)\msi_$(OutputName)</IntermediateOutputPath> - <IntermediateOutputPath Condition="'$(OutputSuffix)' != ''">$(IntermediateOutputPath)_$(OutputSuffix)</IntermediateOutputPath> - <OutputPath Condition="'$(OutputPath)' == ''">$(BuildPath)</OutputPath> - <OutputPath Condition="!HasTrailingSlash($(OutputPath))">$(OutputPath)\</OutputPath> - <OutDir>$(OutputPath)</OutDir> - <ReuseCabinetCache>true</ReuseCabinetCache> - <CRTRedist Condition="'$(CRTRedist)' == ''">$(ExternalsDir)\windows-installer\redist-1\$(Platform)</CRTRedist> - <CRTRedist>$([System.IO.Path]::GetFullPath($(CRTRedist)))</CRTRedist> - <TclTkLibraryDir Condition="$(TclTkLibraryDir) == ''">$(tcltkDir)lib</TclTkLibraryDir> - <DocFilename>python$(MajorVersionNumber)$(MinorVersionNumber)$(MicroVersionNumber)$(ReleaseLevelName).chm</DocFilename> - - <InstallerVersion>$(MajorVersionNumber).$(MinorVersionNumber).$(Field3Value).0</InstallerVersion> - </PropertyGroup> - - <PropertyGroup Condition="!$(BuildForRelease)"> - <RevisionNumber Condition="'$(RevisionNumber)' == ''">$([System.Math]::Floor($([System.DateTime]::Now.Subtract($([System.DateTime]::new(2001, 1, 1))).TotalDays)))</RevisionNumber> - <PythonVersion>$(MajorVersionNumber).$(MinorVersionNumber).$(MicroVersionNumber)dev$(RevisionNumber)</PythonVersion> - <InstallerVersion>$(MajorVersionNumber).$(MinorVersionNumber).$(RevisionNumber).0</InstallerVersion> - </PropertyGroup> - - <PropertyGroup> - <Bitness>32-bit</Bitness> - <Bitness Condition="$(Platform) == 'x64'">64-bit</Bitness> - <Bitness Condition="$(Platform) == 'ARM64'">ARM64</Bitness> - <PlatformArchitecture>32bit</PlatformArchitecture> - <PlatformArchitecture Condition="$(Platform) == 'x64'">64bit</PlatformArchitecture> - <PlatformArchitecture Condition="$(Platform) == 'ARM64'">ARM64</PlatformArchitecture> - <DefineConstants> - $(DefineConstants); - Version=$(InstallerVersion); - ShortVersion=$(MajorVersionNumber).$(MinorVersionNumber); - LongVersion=$(PythonVersion); - MajorVersionNumber=$(MajorVersionNumber); - MinorVersionNumber=$(MinorVersionNumber); - UpgradeMinimumVersion=$(MajorVersionNumber).$(MinorVersionNumber).0.0; - NextMajorVersionNumber=$(MajorVersionNumber).$([msbuild]::Add($(MinorVersionNumber), 1)).0.0; - Bitness=$(Bitness); - PlatformArchitecture=$(PlatformArchitecture); - PyDebugExt=$(PyDebugExt); - PyArchExt=$(PyArchExt); - PyTestExt=$(PyTestExt); - OptionalFeatureName=$(OutputName); - ssltag=$(OpenSSLDLLSuffix); - Suffix32=$(PyArchExt); - </DefineConstants> - <DefineConstants Condition="'$(CRTRedist)' != ''"> - $(DefineConstants);CRTRedist=$(CRTRedist); - </DefineConstants> - </PropertyGroup> - - <ItemDefinitionGroup> - <InstallFiles> - <Group>generated_filelist</Group> - <Condition></Condition> - <DiskId></DiskId> - <IncludeInCat>false</IncludeInCat> - </InstallFiles> - <LinkerBindInputPaths> - <Visible>false</Visible> - </LinkerBindInputPaths> - </ItemDefinitionGroup> - <ItemGroup> - <LinkerBindInputPaths Include="$(PGOBuildPath);$(BuildPath)"> - <BindName></BindName> - </LinkerBindInputPaths> - <LinkerBindInputPaths Include="$(PySourcePath)"> - <BindName>src</BindName> - </LinkerBindInputPaths> - <LinkerBindInputPaths Include="$(TclTkLibraryDir)"> - <BindName>tcltk</BindName> - </LinkerBindInputPaths> - <LinkerBindInputPaths Include="$(CRTRedist)"> - <BindName>redist</BindName> - </LinkerBindInputPaths> - <LinkerBindInputPaths Include="$(BuildPath32)"> - <BindName>build32</BindName> - </LinkerBindInputPaths> - <LinkerBindInputPaths Include="$(BuildPath64)"> - <BindName>build64</BindName> - </LinkerBindInputPaths> - <LinkerBindInputPaths Include="$(BuildPathARM64)"> - <BindName>buildarm64</BindName> - </LinkerBindInputPaths> - </ItemGroup> - - <Target Name="_ValidateMsiProps" BeforeTargets="PrepareForBuild"> - <Error Text="Platform '$(Platform)' is not supported. Use 'x86', 'x64' or 'ARM64'." - Condition="$(Platform) != 'x86' and $(Platform) != 'x64' and $(Platform) != 'ARM64'" /> - </Target> - - <ItemGroup> - <_Uuid Include="CoreUpgradeCode"> - <Uri>upgradecode</Uri> - </_Uuid> - <_Uuid Include="UpgradeCode"> - <Uri>upgradecode/$(OutputName)</Uri> - </_Uuid> - <_Uuid Include="InstallDirectoryGuidSeed"> - <Uri>installdirectoryseed</Uri> - </_Uuid> - <_Uuid Include="PythonExeComponentGuid"> - <Uri>python.exe</Uri> - </_Uuid> - <_Uuid Include="PythonwExeComponentGuid"> - <Uri>pythonw.exe</Uri> - </_Uuid> - <_Uuid Include="RemoveLib2to3PickleComponentGuid"> - <Uri>lib2to3/pickles</Uri> - </_Uuid> - <_Uuid Include="CommonPythonRegComponentGuid"> - <Uri>registry</Uri> - </_Uuid> - <_Uuid Include="PythonRegComponentGuid"> - <Uri>registry/$(OutputName)</Uri> - </_Uuid> - </ItemGroup> - <Target Name="_GenerateGuids" - AfterTargets="PrepareForBuild" - DependsOnTargets="FindPythonForBuild" - Condition="$(TargetName) != 'launcher'"> - <PropertyGroup> - <_Uuids>@(_Uuid->'("%(Identity)", "$(MajorVersionNumber).$(MinorVersionNumber)/%(Uri)")',',')</_Uuids> - <_GenerateCommand>import uuid; print('\n'.join('{}={}'.format(i, uuid.uuid5(uuid.UUID('c8d9733e-a70c-43ff-ab0c-e26456f11083'), '$(ReleaseUri.Replace(`{arch}`, `$(ArchName)`))' + j)) for i,j in [$(_Uuids.Replace(`"`,`'`))]))</_GenerateCommand> - </PropertyGroup> - - <Exec Command='$(PythonForBuild) -c "$(_GenerateCommand)" > "$(IntermediateOutputPath)$(OutputName)guids.txt"' - WorkingDirectory="$(MSBuildThisFileDirectory)" - IgnoreExitCode="false" /> - - <ReadLinesFromFile File="$(IntermediateOutputPath)$(OutputName)guids.txt"> - <Output TaskParameter="Lines" ItemName="_UuidValue" /> - </ReadLinesFromFile> - - <PropertyGroup> - <DefineConstants>$(DefineConstants);@(_UuidValue,';');</DefineConstants> - </PropertyGroup> - </Target> +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" TreatAsLocalProperty="ReleaseUri"> + <PropertyGroup> + <TargetName>$(OutputName)</TargetName> + <DefineSolutionProperties>false</DefineSolutionProperties> + <TreatWarningsAsErrors>false</TreatWarningsAsErrors> + <SuppressIces>$(SuppressIces);ICE03;ICE57;ICE61</SuppressIces> + <CompilerSuppressSpecificWarnings>1026</CompilerSuppressSpecificWarnings> + <BuildForRelease Condition="'$(BuildForRelease)' == ''">false</BuildForRelease> + <SignOutput Condition="'$(SigningCertificate)' != ''">true</SignOutput> + <Configuration Condition="'$(Configuration)' == ''">Release</Configuration> + <Platform Condition="'$(Platform)' == ''">x86</Platform> + <InstallScope Condition="'$(InstallScope)' != 'perMachine'">perUser</InstallScope> + <_MakeCatCommand Condition="'$(_MakeCatCommand)' == ''">makecat</_MakeCatCommand> + <SkipCopySSLDLL>true</SkipCopySSLDLL> + </PropertyGroup> + + <Import Project="wix.props" /> + <Import Project="..\..\PCbuild\openssl.props" /> + <Import Project="..\..\PCbuild\tcltk.props" /> + + <PropertyGroup> + <!-- + This URI is used to generate the various GUIDs used by the installer. + Installers built with the same URI will upgrade each other or block + when attempting to downgrade. + + By default, this is the local computer name, which will produce + installers that do not interfere with other installers. Products + that intend to bundle Python should rebuild these modules with their + own URI to avoid conflicting with the official releases. + + The official releases use "https://www.python.org/$(ArchName)" + + This is not the same as the DownloadUrl property used in the bundle + projects. + --> + <ReleaseUri Condition="'$(ReleaseUri)' == ''">$(ComputerName)/$(ArchName)/</ReleaseUri> + <ReleaseUri Condition="!$(ReleaseUri.EndsWith(`/`))">$(ReleaseUri)/</ReleaseUri> + </PropertyGroup> + + + <ItemGroup> + <Compile Include="$(MSBuildThisFileDirectory)common.wxs" /> + <WxlTemplate Include="$(MSBuildThisFileDirectory)\*.wxl_template" Condition="$(IgnoreCommonWxlTemplates) != 'true'" /> + <WixExtension Include="WixUtilExtension"> + <HintPath>WixUtilExtension</HintPath> + <Name>WixUtilExtension</Name> + </WixExtension> + </ItemGroup> + + <PropertyGroup> + <IntermediateOutputPath>$(Py_IntDir)\$(MajorVersionNumber)$(MinorVersionNumber)$(ArchName)_$(Configuration)\msi_$(OutputName)</IntermediateOutputPath> + <IntermediateOutputPath Condition="'$(OutputSuffix)' != ''">$(IntermediateOutputPath)_$(OutputSuffix)</IntermediateOutputPath> + <OutputPath Condition="'$(OutputPath)' == ''">$(BuildPath)</OutputPath> + <OutputPath Condition="!HasTrailingSlash($(OutputPath))">$(OutputPath)\</OutputPath> + <OutDir>$(OutputPath)</OutDir> + <ReuseCabinetCache>true</ReuseCabinetCache> + <CRTRedist Condition="'$(CRTRedist)' == ''">$(ExternalsDir)\windows-installer\redist-1\$(Platform)</CRTRedist> + <CRTRedist>$([System.IO.Path]::GetFullPath($(CRTRedist)))</CRTRedist> + <TclTkLibraryDir Condition="$(TclTkLibraryDir) == ''">$(tcltkDir)lib</TclTkLibraryDir> + <DocFilename>python$(MajorVersionNumber)$(MinorVersionNumber)$(MicroVersionNumber)$(ReleaseLevelName).chm</DocFilename> + + <InstallerVersion>$(MajorVersionNumber).$(MinorVersionNumber).$(Field3Value).0</InstallerVersion> + </PropertyGroup> + + <PropertyGroup Condition="!$(BuildForRelease)"> + <RevisionNumber Condition="'$(RevisionNumber)' == ''">$([System.Math]::Floor($([System.DateTime]::Now.Subtract($([System.DateTime]::new(2001, 1, 1))).TotalDays)))</RevisionNumber> + <PythonVersion>$(MajorVersionNumber).$(MinorVersionNumber).$(MicroVersionNumber)dev$(RevisionNumber)</PythonVersion> + <InstallerVersion>$(MajorVersionNumber).$(MinorVersionNumber).$(RevisionNumber).0</InstallerVersion> + </PropertyGroup> + + <PropertyGroup> + <Bitness>32-bit</Bitness> + <Bitness Condition="$(Platform) == 'x64'">64-bit</Bitness> + <Bitness Condition="$(Platform) == 'ARM64'">ARM64</Bitness> + <PlatformArchitecture>32bit</PlatformArchitecture> + <PlatformArchitecture Condition="$(Platform) == 'x64'">64bit</PlatformArchitecture> + <PlatformArchitecture Condition="$(Platform) == 'ARM64'">ARM64</PlatformArchitecture> + <DefineConstants> + $(DefineConstants); + Version=$(InstallerVersion); + ShortVersion=$(MajorVersionNumber).$(MinorVersionNumber); + LongVersion=$(PythonVersion); + MajorVersionNumber=$(MajorVersionNumber); + MinorVersionNumber=$(MinorVersionNumber); + UpgradeMinimumVersion=$(MajorVersionNumber).$(MinorVersionNumber).0.0; + NextMajorVersionNumber=$(MajorVersionNumber).$([msbuild]::Add($(MinorVersionNumber), 1)).0.0; + Bitness=$(Bitness); + PlatformArchitecture=$(PlatformArchitecture); + PyDebugExt=$(PyDebugExt); + PyArchExt=$(PyArchExt); + PyTestExt=$(PyTestExt); + OptionalFeatureName=$(OutputName); + ssltag=$(OpenSSLDLLSuffix); + Suffix32=$(PyArchExt); + </DefineConstants> + <DefineConstants Condition="'$(CRTRedist)' != ''"> + $(DefineConstants);CRTRedist=$(CRTRedist); + </DefineConstants> + </PropertyGroup> + + <ItemDefinitionGroup> + <InstallFiles> + <Group>generated_filelist</Group> + <Condition></Condition> + <DiskId></DiskId> + <IncludeInCat>false</IncludeInCat> + </InstallFiles> + <LinkerBindInputPaths> + <Visible>false</Visible> + </LinkerBindInputPaths> + </ItemDefinitionGroup> + <ItemGroup> + <LinkerBindInputPaths Include="$(PGOBuildPath);$(BuildPath)"> + <BindName></BindName> + </LinkerBindInputPaths> + <LinkerBindInputPaths Include="$(PySourcePath)"> + <BindName>src</BindName> + </LinkerBindInputPaths> + <LinkerBindInputPaths Include="$(TclTkLibraryDir)"> + <BindName>tcltk</BindName> + </LinkerBindInputPaths> + <LinkerBindInputPaths Include="$(CRTRedist)"> + <BindName>redist</BindName> + </LinkerBindInputPaths> + <LinkerBindInputPaths Include="$(BuildPath32)"> + <BindName>build32</BindName> + </LinkerBindInputPaths> + <LinkerBindInputPaths Include="$(BuildPath64)"> + <BindName>build64</BindName> + </LinkerBindInputPaths> + <LinkerBindInputPaths Include="$(BuildPathARM64)"> + <BindName>buildarm64</BindName> + </LinkerBindInputPaths> + </ItemGroup> + + <Target Name="_ValidateMsiProps" BeforeTargets="PrepareForBuild"> + <Error Text="Platform '$(Platform)' is not supported. Use 'x86', 'x64' or 'ARM64'." + Condition="$(Platform) != 'x86' and $(Platform) != 'x64' and $(Platform) != 'ARM64'" /> + </Target> + + <ItemGroup> + <_Uuid Include="CoreUpgradeCode"> + <Uri>upgradecode</Uri> + </_Uuid> + <_Uuid Include="UpgradeCode"> + <Uri>upgradecode/$(OutputName)</Uri> + </_Uuid> + <_Uuid Include="InstallDirectoryGuidSeed"> + <Uri>installdirectoryseed</Uri> + </_Uuid> + <_Uuid Include="PythonExeComponentGuid"> + <Uri>python.exe</Uri> + </_Uuid> + <_Uuid Include="PythonwExeComponentGuid"> + <Uri>pythonw.exe</Uri> + </_Uuid> + <_Uuid Include="RemoveLib2to3PickleComponentGuid"> + <Uri>lib2to3/pickles</Uri> + </_Uuid> + <_Uuid Include="CommonPythonRegComponentGuid"> + <Uri>registry</Uri> + </_Uuid> + <_Uuid Include="PythonRegComponentGuid"> + <Uri>registry/$(OutputName)</Uri> + </_Uuid> + </ItemGroup> + <Target Name="_GenerateGuids" + AfterTargets="PrepareForBuild" + DependsOnTargets="FindPythonForBuild" + Condition="$(TargetName) != 'launcher'"> + <PropertyGroup> + <_Uuids>@(_Uuid->'("%(Identity)", "$(MajorVersionNumber).$(MinorVersionNumber)/%(Uri)")',',')</_Uuids> + <_GenerateCommand>import uuid; print('\n'.join('{}={}'.format(i, uuid.uuid5(uuid.UUID('c8d9733e-a70c-43ff-ab0c-e26456f11083'), '$(ReleaseUri.Replace(`{arch}`, `$(ArchName)`))' + j)) for i,j in [$(_Uuids.Replace(`"`,`'`))]))</_GenerateCommand> + </PropertyGroup> + + <Exec Command='$(PythonForBuild) -c "$(_GenerateCommand)" > "$(IntermediateOutputPath)$(OutputName)guids.txt"' + WorkingDirectory="$(MSBuildThisFileDirectory)" + IgnoreExitCode="false" /> + + <ReadLinesFromFile File="$(IntermediateOutputPath)$(OutputName)guids.txt"> + <Output TaskParameter="Lines" ItemName="_UuidValue" /> + </ReadLinesFromFile> + + <PropertyGroup> + <DefineConstants>$(DefineConstants);@(_UuidValue,';');</DefineConstants> + </PropertyGroup> + </Target> </Project> \ No newline at end of file diff --git a/Tools/msi/sign_build.ps1 b/Tools/msi/sign_build.ps1 index 42007b70..d3f75045 100644 --- a/Tools/msi/sign_build.ps1 +++ b/Tools/msi/sign_build.ps1 @@ -1,34 +1,34 @@ -<# -.Synopsis - Recursively signs the contents of a directory. -.Description - Given the file patterns, code signs the contents. -.Parameter root - The root directory to sign. -.Parameter patterns - The file patterns to sign -.Parameter description - The description to add to the signature (optional). -.Parameter certname - The name of the certificate to sign with (optional). -.Parameter certsha1 - The SHA1 hash of the certificate to sign with (optional). -#> -param( - [Parameter(Mandatory=$true)][string]$root, - [string[]]$patterns=@("*.exe", "*.dll", "*.pyd", "*.cat"), - [string]$description, - [string]$certname, - [string]$certsha1, - [string]$certfile -) - -$tools = $script:MyInvocation.MyCommand.Path | Split-Path -parent; -Import-Module $tools\sdktools.psm1 -WarningAction SilentlyContinue -Force - -pushd $root -try { - Sign-File -certname $certname -certsha1 $certsha1 -certfile $certfile -description $description -files (gci -r $patterns) -} finally { - popd +<# +.Synopsis + Recursively signs the contents of a directory. +.Description + Given the file patterns, code signs the contents. +.Parameter root + The root directory to sign. +.Parameter patterns + The file patterns to sign +.Parameter description + The description to add to the signature (optional). +.Parameter certname + The name of the certificate to sign with (optional). +.Parameter certsha1 + The SHA1 hash of the certificate to sign with (optional). +#> +param( + [Parameter(Mandatory=$true)][string]$root, + [string[]]$patterns=@("*.exe", "*.dll", "*.pyd", "*.cat"), + [string]$description, + [string]$certname, + [string]$certsha1, + [string]$certfile +) + +$tools = $script:MyInvocation.MyCommand.Path | Split-Path -parent; +Import-Module $tools\sdktools.psm1 -WarningAction SilentlyContinue -Force + +pushd $root +try { + Sign-File -certname $certname -certsha1 $certsha1 -certfile $certfile -description $description -files (gci -r $patterns) +} finally { + popd } \ No newline at end of file diff --git a/Tools/msi/tcltk/tcltk_files.wxs b/Tools/msi/tcltk/tcltk_files.wxs index 11945107..5dad7c98 100644 --- a/Tools/msi/tcltk/tcltk_files.wxs +++ b/Tools/msi/tcltk/tcltk_files.wxs @@ -16,6 +16,9 @@ <Component Id="tk86t.dll" Directory="DLLs" Guid="*"> <File Name="tk86t.dll" KeyPath="yes" /> </Component> + <Component Id="zlib1.dll" Directory="DLLs" Guid="*"> + <File Name="zlib1.dll" KeyPath="yes" /> + </Component> </ComponentGroup> </Fragment> diff --git a/Tools/msi/test/test_files.wxs b/Tools/msi/test/test_files.wxs index 9127ce89..87e164cb 100644 --- a/Tools/msi/test/test_files.wxs +++ b/Tools/msi/test/test_files.wxs @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"> - <?define exts=_testcapi;_ctypes_test;_testbuffer;_testimportmultiple;_testmultiphase;_testconsole;_testinternalcapi ?> + <?define exts=_testcapi;_ctypes_test;_testbuffer;_testimportmultiple;_testmultiphase;_testsinglephase;_testconsole;_testinternalcapi;_testclinic ?> <Fragment> <ComponentGroup Id="test_extensions"> <?foreach ext in $(var.exts)?> diff --git a/Tools/msi/testrelease.bat b/Tools/msi/testrelease.bat index d14dc209..02bcca94 100644 --- a/Tools/msi/testrelease.bat +++ b/Tools/msi/testrelease.bat @@ -1,117 +1,117 @@ -@setlocal enableextensions -@echo off - -set D=%~dp0 -set PCBUILD=%D%..\..\PCbuild\ - -set TARGETDIR=%TEMP% -set TESTX86= -set TESTX64= -set TESTALLUSER= -set TESTPERUSER= - -:CheckOpts -if "%1" EQU "-h" goto Help -if "%1" EQU "-x86" (set TESTX86=1) && shift && goto CheckOpts -if "%1" EQU "-x64" (set TESTX64=1) && shift && goto CheckOpts -if "%1" EQU "-t" (set TARGETDIR=%~2) && shift && shift && goto CheckOpts -if "%1" EQU "--target" (set TARGETDIR=%~2) && shift && shift && goto CheckOpts -if "%1" EQU "-a" (set TESTALLUSER=1) && shift && goto CheckOpts -if "%1" EQU "--alluser" (set TESTALLUSER=1) && shift && goto CheckOpts -if "%1" EQU "-p" (set TESTPERUSER=1) && shift && goto CheckOpts -if "%1" EQU "--peruser" (set TESTPERUSER=1) && shift && goto CheckOpts - -if not defined TESTX86 if not defined TESTX64 (set TESTX86=1) && (set TESTX64=1) -if not defined TESTALLUSER if not defined TESTPERUSER (set TESTALLUSER=1) && (set TESTPERUSER=1) - - -if defined TESTX86 ( - for %%f in ("%PCBUILD%win32\en-us\*.exe") do ( - if defined TESTALLUSER call :test "%%~ff" "%TARGETDIR%\%%~nf-alluser" "InstallAllUsers=1 CompileAll=1" - if errorlevel 1 exit /B - if defined TESTPERUSER call :test "%%~ff" "%TARGETDIR%\%%~nf-peruser" "InstallAllUsers=0 CompileAll=0" - if errorlevel 1 exit /B - ) -) - -if defined TESTX64 ( - for %%f in ("%PCBUILD%amd64\en-us\*.exe") do ( - if defined TESTALLUSER call :test "%%~ff" "%TARGETDIR%\%%~nf-alluser" "InstallAllUsers=1 CompileAll=1" - if errorlevel 1 exit /B - if defined TESTPERUSER call :test "%%~ff" "%TARGETDIR%\%%~nf-peruser" "InstallAllUsers=0 CompileAll=0" - if errorlevel 1 exit /B - ) -) - -exit /B 0 - -:test -@setlocal -@echo on - -@if not exist "%~1" exit /B 1 - -@set EXE=%~1 -@if not "%EXE:embed=%"=="%EXE%" exit /B 0 - -@set EXITCODE=0 -@echo Installing %1 into %2 -"%~1" /passive /log "%~2\install\log.txt" TargetDir="%~2\Python" Include_debug=1 Include_symbols=1 %~3 - -@if not errorlevel 1 ( - @echo Printing version - "%~2\Python\python.exe" -c "import sys; print(sys.version)" > "%~2\version.txt" 2>&1 -) - -@if not errorlevel 1 ( - @echo Capturing Start Menu - @dir /s/b "%PROGRAMDATA%\Microsoft\Windows\Start Menu\Programs" | findstr /ic:"python" > "%~2\startmenu.txt" 2>&1 - @dir /s/b "%APPDATA%\Microsoft\Windows\Start Menu\Programs" | findstr /ic:"python" >> "%~2\startmenu.txt" 2>&1 - - @echo Capturing registry - @for /F "usebackq" %%f in (`reg query HKCR /s /f python /k`) do @( - echo %%f >> "%~2\hkcr.txt" - reg query "%%f" /s >> "%~2\hkcr.txt" 2>&1 - ) - @reg query HKCU\Software\Python /s > "%~2\hkcu.txt" 2>&1 - @reg query HKLM\Software\Python /reg:32 /s > "%~2\hklm.txt" 2>&1 - @reg query HKLM\Software\Python /reg:64 /s >> "%~2\hklm.txt" 2>&1 - cmd /k exit 0 -) - -@if not errorlevel 1 ( - @echo Installing package - "%~2\Python\python.exe" -m pip install "azure<0.10" > "%~2\pip.txt" 2>&1 - @if not errorlevel 1 ( - "%~2\Python\python.exe" -m pip uninstall -y azure python-dateutil six >> "%~2\pip.txt" 2>&1 - ) -) -@if not errorlevel 1 ( - @echo Testing Tcl/tk - @set TCL_LIBRARY=%~2\Python\tcl\tcl8.6 - "%~2\Python\python.exe" -m test -uall -v test_ttk_guionly test_tk test_idle > "%~2\tcltk.txt" 2>&1 - @set TCL_LIBRARY= -) - -@set EXITCODE=%ERRORLEVEL% - -@echo Result was %EXITCODE% -@echo Removing %1 -"%~1" /passive /uninstall /log "%~2\uninstall\log.txt" - -@echo off -exit /B %EXITCODE% - -:Help -echo testrelease.bat [--target TARGET] [-x86] [-x64] [--alluser] [--peruser] [-h] -echo. -echo --target (-t) Specify the target directory for installs and logs -echo -x86 Run tests for x86 installers -echo -x64 Run tests for x64 installers -echo --alluser (-a) Run tests for all-user installs (requires Administrator) -echo --peruser (-p) Run tests for per-user installs -echo -h Display this help information -echo. -echo If no test architecture is specified, all architectures will be tested. -echo If no install type is selected, all install types will be tested. -echo. +@setlocal enableextensions +@echo off + +set D=%~dp0 +set PCBUILD=%D%..\..\PCbuild\ + +set TARGETDIR=%TEMP% +set TESTX86= +set TESTX64= +set TESTALLUSER= +set TESTPERUSER= + +:CheckOpts +if "%1" EQU "-h" goto Help +if "%1" EQU "-x86" (set TESTX86=1) && shift && goto CheckOpts +if "%1" EQU "-x64" (set TESTX64=1) && shift && goto CheckOpts +if "%1" EQU "-t" (set TARGETDIR=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "--target" (set TARGETDIR=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "-a" (set TESTALLUSER=1) && shift && goto CheckOpts +if "%1" EQU "--alluser" (set TESTALLUSER=1) && shift && goto CheckOpts +if "%1" EQU "-p" (set TESTPERUSER=1) && shift && goto CheckOpts +if "%1" EQU "--peruser" (set TESTPERUSER=1) && shift && goto CheckOpts + +if not defined TESTX86 if not defined TESTX64 (set TESTX86=1) && (set TESTX64=1) +if not defined TESTALLUSER if not defined TESTPERUSER (set TESTALLUSER=1) && (set TESTPERUSER=1) + + +if defined TESTX86 ( + for %%f in ("%PCBUILD%win32\en-us\*.exe") do ( + if defined TESTALLUSER call :test "%%~ff" "%TARGETDIR%\%%~nf-alluser" "InstallAllUsers=1 CompileAll=1" + if errorlevel 1 exit /B + if defined TESTPERUSER call :test "%%~ff" "%TARGETDIR%\%%~nf-peruser" "InstallAllUsers=0 CompileAll=0" + if errorlevel 1 exit /B + ) +) + +if defined TESTX64 ( + for %%f in ("%PCBUILD%amd64\en-us\*.exe") do ( + if defined TESTALLUSER call :test "%%~ff" "%TARGETDIR%\%%~nf-alluser" "InstallAllUsers=1 CompileAll=1" + if errorlevel 1 exit /B + if defined TESTPERUSER call :test "%%~ff" "%TARGETDIR%\%%~nf-peruser" "InstallAllUsers=0 CompileAll=0" + if errorlevel 1 exit /B + ) +) + +exit /B 0 + +:test +@setlocal +@echo on + +@if not exist "%~1" exit /B 1 + +@set EXE=%~1 +@if not "%EXE:embed=%"=="%EXE%" exit /B 0 + +@set EXITCODE=0 +@echo Installing %1 into %2 +"%~1" /passive /log "%~2\install\log.txt" TargetDir="%~2\Python" Include_debug=1 Include_symbols=1 %~3 + +@if not errorlevel 1 ( + @echo Printing version + "%~2\Python\python.exe" -c "import sys; print(sys.version)" > "%~2\version.txt" 2>&1 +) + +@if not errorlevel 1 ( + @echo Capturing Start Menu + @dir /s/b "%PROGRAMDATA%\Microsoft\Windows\Start Menu\Programs" | findstr /ic:"python" > "%~2\startmenu.txt" 2>&1 + @dir /s/b "%APPDATA%\Microsoft\Windows\Start Menu\Programs" | findstr /ic:"python" >> "%~2\startmenu.txt" 2>&1 + + @echo Capturing registry + @for /F "usebackq" %%f in (`reg query HKCR /s /f python /k`) do @( + echo %%f >> "%~2\hkcr.txt" + reg query "%%f" /s >> "%~2\hkcr.txt" 2>&1 + ) + @reg query HKCU\Software\Python /s > "%~2\hkcu.txt" 2>&1 + @reg query HKLM\Software\Python /reg:32 /s > "%~2\hklm.txt" 2>&1 + @reg query HKLM\Software\Python /reg:64 /s >> "%~2\hklm.txt" 2>&1 + cmd /k exit 0 +) + +@if not errorlevel 1 ( + @echo Installing package + "%~2\Python\python.exe" -m pip install "azure<0.10" > "%~2\pip.txt" 2>&1 + @if not errorlevel 1 ( + "%~2\Python\python.exe" -m pip uninstall -y azure python-dateutil six >> "%~2\pip.txt" 2>&1 + ) +) +@if not errorlevel 1 ( + @echo Testing Tcl/tk + @set TCL_LIBRARY=%~2\Python\tcl\tcl8.6 + "%~2\Python\python.exe" -m test -uall -v test_ttk_guionly test_tk test_idle > "%~2\tcltk.txt" 2>&1 + @set TCL_LIBRARY= +) + +@set EXITCODE=%ERRORLEVEL% + +@echo Result was %EXITCODE% +@echo Removing %1 +"%~1" /passive /uninstall /log "%~2\uninstall\log.txt" + +@echo off +exit /B %EXITCODE% + +:Help +echo testrelease.bat [--target TARGET] [-x86] [-x64] [--alluser] [--peruser] [-h] +echo. +echo --target (-t) Specify the target directory for installs and logs +echo -x86 Run tests for x86 installers +echo -x64 Run tests for x64 installers +echo --alluser (-a) Run tests for all-user installs (requires Administrator) +echo --peruser (-p) Run tests for per-user installs +echo -h Display this help information +echo. +echo If no test architecture is specified, all architectures will be tested. +echo If no install type is selected, all install types will be tested. +echo. diff --git a/Tools/msi/tools/tools.wixproj b/Tools/msi/tools/tools.wixproj deleted file mode 100644 index 2963048d..00000000 --- a/Tools/msi/tools/tools.wixproj +++ /dev/null @@ -1,38 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <PropertyGroup> - <ProjectGuid>{24CBEB95-BC1E-4EA9-AEA9-33834BCCD0EC}</ProjectGuid> - <SchemaVersion>2.0</SchemaVersion> - <OutputName>tools</OutputName> - <OutputType>Package</OutputType> - </PropertyGroup> - <Import Project="..\msi.props" /> - <ItemGroup> - <Compile Include="tools.wxs" /> - <Compile Include="tools_files.wxs" /> - </ItemGroup> - <ItemGroup> - <EmbeddedResource Include="*.wxl" /> - </ItemGroup> - <ItemGroup> - <InstallFiles Include="$(PySourcePath)Tools\scripts\**\*.py; - $(PySourcePath)Tools\scripts\**\*.pyw; - $(PySourcePath)Tools\scripts\**\*.txt; - $(PySourcePath)Tools\i18n\**\*.py; - $(PySourcePath)Tools\i18n\**\*.pyw; - $(PySourcePath)Tools\i18n\**\*.txt; - $(PySourcePath)Tools\demo\**\*.py; - $(PySourcePath)Tools\demo\**\*.pyw; - $(PySourcePath)Tools\demo\**\*.txt; - $(PySourcePath)Tools\parser\**\*.py"> - <SourceBase>$(PySourcePath)</SourceBase> - <Source>!(bindpath.src)</Source> - <TargetBase>$(PySourcePath)</TargetBase> - <Target_></Target_> - <Group>tools_py</Group> - <IncludeInCat>true</IncludeInCat> - </InstallFiles> - </ItemGroup> - - <Import Project="..\msi.targets" /> -</Project> diff --git a/Tools/msi/tools/tools.wxs b/Tools/msi/tools/tools.wxs deleted file mode 100644 index c06b3c27..00000000 --- a/Tools/msi/tools/tools.wxs +++ /dev/null @@ -1,17 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"> - <Product Id="*" Language="!(loc.LCID)" Name="!(loc.Title)" Version="$(var.Version)" Manufacturer="!(loc.Manufacturer)" UpgradeCode="$(var.UpgradeCode)"> - <Package InstallerVersion="500" Compressed="yes" InstallScope="perUser" /> - <MediaTemplate EmbedCab="yes" CompressionLevel="high" /> - - <PropertyRef Id="DetectTargetDir" /> - <PropertyRef Id="UpgradeTable" /> - - <Feature Id="DefaultFeature" AllowAdvertise="no" Title="!(loc.Title)" Description="!(loc.Description)"> - <ComponentGroupRef Id="tools_py" /> - <ComponentGroupRef Id="tools_scripts" /> - <ComponentGroupRef Id="tools_cat" /> - <ComponentRef Id="OptionalFeature" /> - </Feature> - </Product> -</Wix> diff --git a/Tools/msi/tools/tools_en-US.wxl b/Tools/msi/tools/tools_en-US.wxl deleted file mode 100644 index a1384177..00000000 --- a/Tools/msi/tools/tools_en-US.wxl +++ /dev/null @@ -1,5 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<WixLocalization Culture="en-us" xmlns="http://schemas.microsoft.com/wix/2006/localization"> - <String Id="Descriptor">Utility Scripts</String> - <String Id="ShortDescriptor">tools</String> -</WixLocalization> diff --git a/Tools/msi/tools/tools_files.wxs b/Tools/msi/tools/tools_files.wxs deleted file mode 100644 index 3de6c929..00000000 --- a/Tools/msi/tools/tools_files.wxs +++ /dev/null @@ -1,20 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"> - <Fragment> - <ComponentGroup Id="tools_scripts"> - <Component Id="Tools_scripts_2to3.py" Directory="Tools_scripts" Guid="*"> - <File Id="Tools_scripts_2to3.py" Name="2to3.py" Source="!(bindpath.src)Tools\scripts\2to3" /> - </Component> - <Component Id="Tools_scripts_pydoc3.py" Directory="Tools_scripts" Guid="*"> - <File Id="Tools_scripts_pydoc3.py" Name="pydoc3.py" Source="!(bindpath.src)Tools\scripts\pydoc3" /> - </Component> - </ComponentGroup> - </Fragment> - <Fragment> - <ComponentGroup Id="tools_cat"> - <Component Id="tools_cat" Directory="Catalogs" Guid="*"> - <File Name="python_tools.cat" KeyPath="yes" /> - </Component> - </ComponentGroup> - </Fragment> -</Wix> diff --git a/Tools/msi/uploadrelease.bat b/Tools/msi/uploadrelease.bat index 0f161b49..f262489c 100644 --- a/Tools/msi/uploadrelease.bat +++ b/Tools/msi/uploadrelease.bat @@ -1,109 +1,109 @@ -@setlocal -@echo off - -set D=%~dp0 -set PCBUILD=%D%..\..\PCbuild\ - -set HOST= -set USER= -set TARGET= -set DRYRUN=false -set NOUPLOAD= -set NOGPG= -set NOPURGE= -set NOTEST= - -:CheckOpts -if "%1" EQU "-h" goto Help -if "%1" EQU "-o" (set HOST=%~2) && shift && shift && goto CheckOpts -if "%1" EQU "--host" (set HOST=%~2) && shift && shift && goto CheckOpts -if "%1" EQU "-u" (set USER=%~2) && shift && shift && goto CheckOpts -if "%1" EQU "--user" (set USER=%~2) && shift && shift && goto CheckOpts -if "%1" EQU "-t" (set TARGET=%~2) && shift && shift && goto CheckOpts -if "%1" EQU "--target" (set TARGET=%~2) && shift && shift && goto CheckOpts -if "%1" EQU "--dry-run" (set DRYRUN=true) && shift && goto CheckOpts -if "%1" EQU "--skip-upload" (set NOUPLOAD=true) && shift && goto CheckOpts -if "%1" EQU "--skip-gpg" (set NOGPG=true) && shift && goto CheckOpts -if "%1" EQU "--skip-purge" (set NOPURGE=true) && shift && goto CheckOpts -if "%1" EQU "--skip-test" (set NOTEST=true) && shift && goto CheckOpts -if "%1" EQU "-T" (set NOTEST=true) && shift && goto CheckOpts -if "%1" NEQ "" echo Unexpected argument "%1" & exit /B 1 - -if not defined PLINK where plink > "%TEMP%\plink.loc" 2> nul && set /P PLINK= < "%TEMP%\plink.loc" & del "%TEMP%\plink.loc" -if not defined PLINK where /R "%ProgramFiles(x86)%\PuTTY" plink > "%TEMP%\plink.loc" 2> nul && set /P PLINK= < "%TEMP%\plink.loc" & del "%TEMP%\plink.loc" -if not defined PLINK where /R "%ProgramFiles%\PuTTY" plink > "%TEMP%\plink.loc" 2> nul && set /P PLINK= < "%TEMP%\plink.loc" & del "%TEMP%\plink.loc" -if not defined PLINK where /R "%ProgramFiles(x86)%" plink > "%TEMP%\plink.loc" 2> nul && set /P PLINK= < "%TEMP%\plink.loc" & del "%TEMP%\plink.loc" -if not defined PLINK where /R "%ProgramFiles%" plink > "%TEMP%\plink.loc" 2> nul && set /P PLINK= < "%TEMP%\plink.loc" & del "%TEMP%\plink.loc" -if not defined PLINK echo Cannot locate plink.exe & exit /B 1 -echo Found plink.exe at %PLINK% - -if not defined PSCP where pscp > "%TEMP%\pscp.loc" 2> nul && set /P pscp= < "%TEMP%\pscp.loc" & del "%TEMP%\pscp.loc" -if not defined PSCP where /R "%ProgramFiles(x86)%\PuTTY" pscp > "%TEMP%\pscp.loc" 2> nul && set /P pscp= < "%TEMP%\pscp.loc" & del "%TEMP%\pscp.loc" -if not defined PSCP where /R "%ProgramFiles%\PuTTY" pscp > "%TEMP%\pscp.loc" 2> nul && set /P pscp= < "%TEMP%\pscp.loc" & del "%TEMP%\pscp.loc" -if not defined PSCP where /R "%ProgramFiles(x86)%" pscp > "%TEMP%\pscp.loc" 2> nul && set /P pscp= < "%TEMP%\pscp.loc" & del "%TEMP%\pscp.loc" -if not defined PSCP where /R "%ProgramFiles%" pscp > "%TEMP%\pscp.loc" 2> nul && set /P pscp= < "%TEMP%\pscp.loc" & del "%TEMP%\pscp.loc" -if not defined PSCP echo Cannot locate pscp.exe & exit /B 1 -echo Found pscp.exe at %PSCP% - -if defined NOGPG ( - set GPG= - echo Skipping GPG signature generation because of --skip-gpg -) else ( - if not defined GPG where gpg2 > "%TEMP%\gpg.loc" 2> nul && set /P GPG= < "%TEMP%\gpg.loc" & del "%TEMP%\gpg.loc" - if not defined GPG where /R "%PCBUILD%..\externals\windows-installer" gpg2 > "%TEMP%\gpg.loc" 2> nul && set /P GPG= < "%TEMP%\gpg.loc" & del "%TEMP%\gpg.loc" - if not defined GPG echo Cannot locate gpg2.exe. Signatures will not be uploaded & pause - echo Found gpg2.exe at %GPG% -) - -call "%PCBUILD%find_msbuild.bat" %MSBUILD% -if ERRORLEVEL 1 (echo Cannot locate MSBuild.exe on PATH or as MSBUILD variable & exit /b 2) -pushd "%D%" -if not defined NOUPLOAD ( - %MSBUILD% /v:m /nologo uploadrelease.proj /t:Upload /p:Platform=x86 - if errorlevel 1 goto :failed - %MSBUILD% /v:m /nologo uploadrelease.proj /t:Upload /p:Platform=x64 /p:IncludeDoc=false - if errorlevel 1 goto :failed -) -if not defined NOPURGE ( - %MSBUILD% /v:m /nologo uploadrelease.proj /t:Purge -) -if not defined NOTEST ( - call :test x86 - if errorlevel 1 goto :failed - call :test x64 - if errorlevel 1 goto :failed -) -%MSBUILD% /v:m /nologo uploadrelease.proj /t:ShowHashes /p:Platform=x86 -if errorlevel 1 goto :failed -%MSBUILD% /v:m /nologo uploadrelease.proj /t:ShowHashes /p:Platform=x64 /p:IncludeDoc=false -if errorlevel 1 goto :failed - -popd -exit /B 0 - -:test -%MSBUILD% /v:m /nologo uploadrelease.proj /t:Test /p:Platform=%1 -if errorlevel 1 ( - echo Test failed - purging and retrying - %MSBUILD% /v:m /nologo uploadrelease.proj /t:Purge - if errorlevel 1 exit /B - %MSBUILD% /v:m /nologo uploadrelease.proj /t:Test /p:Platform=%1 -) -exit /B - -:failed -popd -exit /B - -:Help -echo uploadrelease.bat --host HOST --user USERNAME [--target TARGET] [--dry-run] [-h] -echo. -echo --host (-o) Specify the upload host (required) -echo --user (-u) Specify the user on the host (required) -echo --target (-t) Specify the target directory on the host -echo --dry-run Display commands and filenames without executing them -echo --skip-gpg Does not generate GPG signatures before uploading -echo --skip-purge Does not perform CDN purge after uploading -echo --skip-test (-T) Does not perform post-upload tests -echo -h Display this help information -echo. +@setlocal +@echo off + +set D=%~dp0 +set PCBUILD=%D%..\..\PCbuild\ + +set HOST= +set USER= +set TARGET= +set DRYRUN=false +set NOUPLOAD= +set NOGPG= +set NOPURGE= +set NOTEST= + +:CheckOpts +if "%1" EQU "-h" goto Help +if "%1" EQU "-o" (set HOST=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "--host" (set HOST=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "-u" (set USER=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "--user" (set USER=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "-t" (set TARGET=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "--target" (set TARGET=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "--dry-run" (set DRYRUN=true) && shift && goto CheckOpts +if "%1" EQU "--skip-upload" (set NOUPLOAD=true) && shift && goto CheckOpts +if "%1" EQU "--skip-gpg" (set NOGPG=true) && shift && goto CheckOpts +if "%1" EQU "--skip-purge" (set NOPURGE=true) && shift && goto CheckOpts +if "%1" EQU "--skip-test" (set NOTEST=true) && shift && goto CheckOpts +if "%1" EQU "-T" (set NOTEST=true) && shift && goto CheckOpts +if "%1" NEQ "" echo Unexpected argument "%1" & exit /B 1 + +if not defined PLINK where plink > "%TEMP%\plink.loc" 2> nul && set /P PLINK= < "%TEMP%\plink.loc" & del "%TEMP%\plink.loc" +if not defined PLINK where /R "%ProgramFiles(x86)%\PuTTY" plink > "%TEMP%\plink.loc" 2> nul && set /P PLINK= < "%TEMP%\plink.loc" & del "%TEMP%\plink.loc" +if not defined PLINK where /R "%ProgramFiles%\PuTTY" plink > "%TEMP%\plink.loc" 2> nul && set /P PLINK= < "%TEMP%\plink.loc" & del "%TEMP%\plink.loc" +if not defined PLINK where /R "%ProgramFiles(x86)%" plink > "%TEMP%\plink.loc" 2> nul && set /P PLINK= < "%TEMP%\plink.loc" & del "%TEMP%\plink.loc" +if not defined PLINK where /R "%ProgramFiles%" plink > "%TEMP%\plink.loc" 2> nul && set /P PLINK= < "%TEMP%\plink.loc" & del "%TEMP%\plink.loc" +if not defined PLINK echo Cannot locate plink.exe & exit /B 1 +echo Found plink.exe at %PLINK% + +if not defined PSCP where pscp > "%TEMP%\pscp.loc" 2> nul && set /P pscp= < "%TEMP%\pscp.loc" & del "%TEMP%\pscp.loc" +if not defined PSCP where /R "%ProgramFiles(x86)%\PuTTY" pscp > "%TEMP%\pscp.loc" 2> nul && set /P pscp= < "%TEMP%\pscp.loc" & del "%TEMP%\pscp.loc" +if not defined PSCP where /R "%ProgramFiles%\PuTTY" pscp > "%TEMP%\pscp.loc" 2> nul && set /P pscp= < "%TEMP%\pscp.loc" & del "%TEMP%\pscp.loc" +if not defined PSCP where /R "%ProgramFiles(x86)%" pscp > "%TEMP%\pscp.loc" 2> nul && set /P pscp= < "%TEMP%\pscp.loc" & del "%TEMP%\pscp.loc" +if not defined PSCP where /R "%ProgramFiles%" pscp > "%TEMP%\pscp.loc" 2> nul && set /P pscp= < "%TEMP%\pscp.loc" & del "%TEMP%\pscp.loc" +if not defined PSCP echo Cannot locate pscp.exe & exit /B 1 +echo Found pscp.exe at %PSCP% + +if defined NOGPG ( + set GPG= + echo Skipping GPG signature generation because of --skip-gpg +) else ( + if not defined GPG where gpg2 > "%TEMP%\gpg.loc" 2> nul && set /P GPG= < "%TEMP%\gpg.loc" & del "%TEMP%\gpg.loc" + if not defined GPG where /R "%PCBUILD%..\externals\windows-installer" gpg2 > "%TEMP%\gpg.loc" 2> nul && set /P GPG= < "%TEMP%\gpg.loc" & del "%TEMP%\gpg.loc" + if not defined GPG echo Cannot locate gpg2.exe. Signatures will not be uploaded & pause + echo Found gpg2.exe at %GPG% +) + +call "%PCBUILD%find_msbuild.bat" %MSBUILD% +if ERRORLEVEL 1 (echo Cannot locate MSBuild.exe on PATH or as MSBUILD variable & exit /b 2) +pushd "%D%" +if not defined NOUPLOAD ( + %MSBUILD% /v:m /nologo uploadrelease.proj /t:Upload /p:Platform=x86 + if errorlevel 1 goto :failed + %MSBUILD% /v:m /nologo uploadrelease.proj /t:Upload /p:Platform=x64 /p:IncludeDoc=false + if errorlevel 1 goto :failed +) +if not defined NOPURGE ( + %MSBUILD% /v:m /nologo uploadrelease.proj /t:Purge +) +if not defined NOTEST ( + call :test x86 + if errorlevel 1 goto :failed + call :test x64 + if errorlevel 1 goto :failed +) +%MSBUILD% /v:m /nologo uploadrelease.proj /t:ShowHashes /p:Platform=x86 +if errorlevel 1 goto :failed +%MSBUILD% /v:m /nologo uploadrelease.proj /t:ShowHashes /p:Platform=x64 /p:IncludeDoc=false +if errorlevel 1 goto :failed + +popd +exit /B 0 + +:test +%MSBUILD% /v:m /nologo uploadrelease.proj /t:Test /p:Platform=%1 +if errorlevel 1 ( + echo Test failed - purging and retrying + %MSBUILD% /v:m /nologo uploadrelease.proj /t:Purge + if errorlevel 1 exit /B + %MSBUILD% /v:m /nologo uploadrelease.proj /t:Test /p:Platform=%1 +) +exit /B + +:failed +popd +exit /B + +:Help +echo uploadrelease.bat --host HOST --user USERNAME [--target TARGET] [--dry-run] [-h] +echo. +echo --host (-o) Specify the upload host (required) +echo --user (-u) Specify the user on the host (required) +echo --target (-t) Specify the target directory on the host +echo --dry-run Display commands and filenames without executing them +echo --skip-gpg Does not generate GPG signatures before uploading +echo --skip-purge Does not perform CDN purge after uploading +echo --skip-test (-T) Does not perform post-upload tests +echo -h Display this help information +echo. diff --git a/Tools/msi/uploadrelease.proj b/Tools/msi/uploadrelease.proj index df0e1f9b..e70ae1de 100644 --- a/Tools/msi/uploadrelease.proj +++ b/Tools/msi/uploadrelease.proj @@ -1,113 +1,113 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <PropertyGroup> - <ProjectGuid>{2D69F2AB-D5D0-4344-84B5-EF6DB34A9BC9}</ProjectGuid> - <OutputName>python</OutputName> - <OutputSuffix></OutputSuffix> - - <DownloadUrlBase Condition="'$(DownloadUrlBase)' == ''">$(TARGET)</DownloadUrlBase> - <DownloadUrlBase Condition="'$(DownloadUrlBase)' == ''">/srv/www.python.org/ftp/python</DownloadUrlBase> - <IncludeDoc Condition="'$(IncludeDoc)' == ''">true</IncludeDoc> - <BuildForRelease Condition="'$(BuildForRelease)' == ''">true</BuildForRelease> - <DryRun Condition="'$(DryRun)' == ''">false</DryRun> - </PropertyGroup> - - <Import Project="msi.props" /> - <Import Project="bundle\bundle.targets" /> - - <PropertyGroup> - <EXETarget>$(DownloadUrlBase.TrimEnd(`/`))/$(MajorVersionNumber).$(MinorVersionNumber).$(MicroVersionNumber)</EXETarget> - <MSITarget>$(DownloadUrl.Replace(`{version}`, `$(MajorVersionNumber).$(MinorVersionNumber).$(MicroVersionNumber)`).Replace(`{arch}`, `$(ArchName)`).Replace(`{releasename}`, `$(ReleaseLevelName)`).Replace(`{msi}`, ``).TrimEnd(`/`))</MSITarget> - </PropertyGroup> - - <ItemGroup> - <File Include="$(OutputPath)\*.msi"> - <CopyTo>$(MSITarget)</CopyTo> - </File> - <File Include="$(OutputPath)\*.exe;$(OutputPath)\*.zip"> - <CopyTo>$(EXETarget)</CopyTo> - </File> - <File Include="$(PySourcePath)Doc\build\htmlhelp\python$(MajorVersionNumber)$(MinorVersionNumber)$(MicroVersionNumber)$(ReleaseLevelName).chm" Condition="$(IncludeDoc)"> - <CopyTo>$(EXETarget)</CopyTo> - </File> - </ItemGroup> - - <Target Name="_ValidateProperties"> - <Error Text="No value for Host provided" Condition="'$(Host)' == ''" /> - <Error Text="No value for User provided" Condition="'$(User)' == ''" /> - <Error Text="No path for PSCP provided" Condition="'$(PSCP)' == ''" /> - <Error Text="No path for PLINK provided" Condition="'$(PLINK)' == ''" /> - </Target> - - <Target Name="_RunGpg" Condition="'$(GPG)' != ''" Inputs="@(File)" Outputs="$(IntermediateOutputPath)\gpg\%(FileName)%(Extension).asc"> - <MakeDir Directories="$(IntermediateOutputPath)gpg" /> - <Delete Files="$(IntermediateOutputPath)\gpg\%(File.FileName)%(File.Extension).asc" Condition="Exists('$(IntermediateOutputPath)\gpg\%(File.FileName)%(File.Extension).asc')" /> - <Exec Command=""$(GPG)" -ba -o "$(IntermediateOutputPath)\gpg\%(File.FileName)%(File.Extension).asc" "%(File.FullPath)"" - IgnoreExitCode="false" /> - <ItemGroup> - <File Include="$(IntermediateOutputPath)\gpg\%(File.FileName)%(File.Extension).asc"> - <CopyTo>%(File.CopyTo)</CopyTo> - </File> - </ItemGroup> - </Target> - - <Target Name="_Upload" Condition="!$(DryRun)"> - <Exec Command=""$(PLINK)" $(User)@$(Host) mkdir %(File.CopyTo) ^&^& chgrp downloads %(File.CopyTo) ^&^& chmod g-w,o+rx %(File.CopyTo)" ContinueOnError="true" /> - <Exec Command=""$(PSCP)" @(File,' ') $(User)@$(Host):%(File.CopyTo)" /> - <Exec Command=""$(PLINK)" $(User)@$(Host) chgrp downloads %(File.CopyTo)/*; chmod g-w,o+r %(File.CopyTo)/*" ContinueOnError="true" /> - </Target> - - <Target Name="_PrintNames" Condition="$(DryRun)"> - <Exec Command="echo "$(PLINK)" $(User)@$(Host) mkdir %(File.CopyTo) ^&^& chgrp downloads %(File.CopyTo) ^&^& chmod g-w,o+rx %(File.CopyTo)" /> - <Exec Command="echo "$(PSCP)" @(File,' ') $(User)@$(Host):%(File.CopyTo)" /> - <Exec Command="echo "$(PLINK)" $(User)@$(Host) chgrp downloads %(File.CopyTo)/*; chmod g-w,o+r %(File.CopyTo)/*" /> - </Target> - - <Target Name="_TestLayout"> - <ItemGroup> - <WebInstaller Include="$(OutputPath)\*-webinstall.exe" /> - <WebInstaller> - <SourceDir>$(TEMP)\%(Filename)_source</SourceDir> - <SourceExe>$(TEMP)\%(Filename)_source\%(Filename)%(Extension)</SourceExe> - <LayoutDir>$(TEMP)\%(Filename)_layout</LayoutDir> - <LogDir>$(OutputPath)\%(Filename)_layoutlog</LogDir> - <LogFile>$(OutputPath)\%(Filename)_layoutlog\%(Filename).log</LogFile> - </WebInstaller> - </ItemGroup> - <Error Text="Could not find installer" Condition="@(WebInstaller) == ''" /> - <RemoveDir Directories="%(WebInstaller.SourceDir)" Condition="Exists('%(WebInstaller.SourceDir)')" /> - <RemoveDir Directories="%(WebInstaller.LayoutDir)" Condition="Exists('%(WebInstaller.LayoutDir)')" /> - <RemoveDir Directories="%(WebInstaller.LogDir)" Condition="Exists('%(WebInstaller.LogDir)')" /> - <MakeDir Directories="%(WebInstaller.SourceDir)" /> - <Copy SourceFiles="@(WebInstaller)" DestinationFiles="%(WebInstaller.SourceExe)" /> - <Exec Command="start "Install test" /wait "%(WebInstaller.SourceExe)" /layout "%(WebInstaller.LayoutDir)" /passive /log "%(WebInstaller.LogFile)"" - IgnoreExitCode="false" /> - <RemoveDir Directories="%(WebInstaller.LayoutDir)" /> - <RemoveDir Directories="%(WebInstaller.SourceDir)" /> - <RemoveDir Directories="%(WebInstaller.LogDir)" /> - <Message Text="Successfully downloaded %(WebInstaller.Filename)%(WebInstaller.Extension) layout" Importance="high" /> - </Target> - - <Target Name="Upload" DependsOnTargets="_ValidateProperties;_RunGpg;_PrintNames;_Upload" /> - <Target Name="Test" DependsOnTargets="_TestLayout" /> - - <Target Name="Purge"> - <Error Condition="!Exists('$(PythonExe)')" Text="No Python executable available at $(PythonExe)" /> - <Exec Command="echo "$(PythonExe)" purge.py $(PythonVersion)" Condition="$(DryRun)" /> - <Exec Command=""$(PythonExe)" purge.py $(PythonVersion)" Condition="!$(DryRun)" /> - <Message Text="Purged uploaded files" Importance="high" /> - </Target> - - <Target Name="ShowHashes"> - <ItemGroup> - <UserFiles Include="@(File)" Condition="'%(File.CopyTo)' == '$(EXETarget)'" /> - </ItemGroup> - - <Error Text="No files generated" Condition="@(UserFiles) == ''" /> - <Exec Command=""$(PythonExe)" generate_md5.py @(UserFiles->'"%(FullPath)"',' ')" /> - </Target> - - <Target Name="Build"> - <Error Text="This script should be invoked using uploadrelease.bat." /> - </Target> -</Project> +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup> + <ProjectGuid>{2D69F2AB-D5D0-4344-84B5-EF6DB34A9BC9}</ProjectGuid> + <OutputName>python</OutputName> + <OutputSuffix></OutputSuffix> + + <DownloadUrlBase Condition="'$(DownloadUrlBase)' == ''">$(TARGET)</DownloadUrlBase> + <DownloadUrlBase Condition="'$(DownloadUrlBase)' == ''">/srv/www.python.org/ftp/python</DownloadUrlBase> + <IncludeDoc Condition="'$(IncludeDoc)' == ''">true</IncludeDoc> + <BuildForRelease Condition="'$(BuildForRelease)' == ''">true</BuildForRelease> + <DryRun Condition="'$(DryRun)' == ''">false</DryRun> + </PropertyGroup> + + <Import Project="msi.props" /> + <Import Project="bundle\bundle.targets" /> + + <PropertyGroup> + <EXETarget>$(DownloadUrlBase.TrimEnd(`/`))/$(MajorVersionNumber).$(MinorVersionNumber).$(MicroVersionNumber)</EXETarget> + <MSITarget>$(DownloadUrl.Replace(`{version}`, `$(MajorVersionNumber).$(MinorVersionNumber).$(MicroVersionNumber)`).Replace(`{arch}`, `$(ArchName)`).Replace(`{releasename}`, `$(ReleaseLevelName)`).Replace(`{msi}`, ``).TrimEnd(`/`))</MSITarget> + </PropertyGroup> + + <ItemGroup> + <File Include="$(OutputPath)\*.msi"> + <CopyTo>$(MSITarget)</CopyTo> + </File> + <File Include="$(OutputPath)\*.exe;$(OutputPath)\*.zip"> + <CopyTo>$(EXETarget)</CopyTo> + </File> + <File Include="$(PySourcePath)Doc\build\htmlhelp\python$(MajorVersionNumber)$(MinorVersionNumber)$(MicroVersionNumber)$(ReleaseLevelName).chm" Condition="$(IncludeDoc)"> + <CopyTo>$(EXETarget)</CopyTo> + </File> + </ItemGroup> + + <Target Name="_ValidateProperties"> + <Error Text="No value for Host provided" Condition="'$(Host)' == ''" /> + <Error Text="No value for User provided" Condition="'$(User)' == ''" /> + <Error Text="No path for PSCP provided" Condition="'$(PSCP)' == ''" /> + <Error Text="No path for PLINK provided" Condition="'$(PLINK)' == ''" /> + </Target> + + <Target Name="_RunGpg" Condition="'$(GPG)' != ''" Inputs="@(File)" Outputs="$(IntermediateOutputPath)\gpg\%(FileName)%(Extension).asc"> + <MakeDir Directories="$(IntermediateOutputPath)gpg" /> + <Delete Files="$(IntermediateOutputPath)\gpg\%(File.FileName)%(File.Extension).asc" Condition="Exists('$(IntermediateOutputPath)\gpg\%(File.FileName)%(File.Extension).asc')" /> + <Exec Command=""$(GPG)" -ba -o "$(IntermediateOutputPath)\gpg\%(File.FileName)%(File.Extension).asc" "%(File.FullPath)"" + IgnoreExitCode="false" /> + <ItemGroup> + <File Include="$(IntermediateOutputPath)\gpg\%(File.FileName)%(File.Extension).asc"> + <CopyTo>%(File.CopyTo)</CopyTo> + </File> + </ItemGroup> + </Target> + + <Target Name="_Upload" Condition="!$(DryRun)"> + <Exec Command=""$(PLINK)" $(User)@$(Host) mkdir %(File.CopyTo) ^&^& chgrp downloads %(File.CopyTo) ^&^& chmod g-w,o+rx %(File.CopyTo)" ContinueOnError="true" /> + <Exec Command=""$(PSCP)" @(File,' ') $(User)@$(Host):%(File.CopyTo)" /> + <Exec Command=""$(PLINK)" $(User)@$(Host) chgrp downloads %(File.CopyTo)/*; chmod g-w,o+r %(File.CopyTo)/*" ContinueOnError="true" /> + </Target> + + <Target Name="_PrintNames" Condition="$(DryRun)"> + <Exec Command="echo "$(PLINK)" $(User)@$(Host) mkdir %(File.CopyTo) ^&^& chgrp downloads %(File.CopyTo) ^&^& chmod g-w,o+rx %(File.CopyTo)" /> + <Exec Command="echo "$(PSCP)" @(File,' ') $(User)@$(Host):%(File.CopyTo)" /> + <Exec Command="echo "$(PLINK)" $(User)@$(Host) chgrp downloads %(File.CopyTo)/*; chmod g-w,o+r %(File.CopyTo)/*" /> + </Target> + + <Target Name="_TestLayout"> + <ItemGroup> + <WebInstaller Include="$(OutputPath)\*-webinstall.exe" /> + <WebInstaller> + <SourceDir>$(TEMP)\%(Filename)_source</SourceDir> + <SourceExe>$(TEMP)\%(Filename)_source\%(Filename)%(Extension)</SourceExe> + <LayoutDir>$(TEMP)\%(Filename)_layout</LayoutDir> + <LogDir>$(OutputPath)\%(Filename)_layoutlog</LogDir> + <LogFile>$(OutputPath)\%(Filename)_layoutlog\%(Filename).log</LogFile> + </WebInstaller> + </ItemGroup> + <Error Text="Could not find installer" Condition="@(WebInstaller) == ''" /> + <RemoveDir Directories="%(WebInstaller.SourceDir)" Condition="Exists('%(WebInstaller.SourceDir)')" /> + <RemoveDir Directories="%(WebInstaller.LayoutDir)" Condition="Exists('%(WebInstaller.LayoutDir)')" /> + <RemoveDir Directories="%(WebInstaller.LogDir)" Condition="Exists('%(WebInstaller.LogDir)')" /> + <MakeDir Directories="%(WebInstaller.SourceDir)" /> + <Copy SourceFiles="@(WebInstaller)" DestinationFiles="%(WebInstaller.SourceExe)" /> + <Exec Command="start "Install test" /wait "%(WebInstaller.SourceExe)" /layout "%(WebInstaller.LayoutDir)" /passive /log "%(WebInstaller.LogFile)"" + IgnoreExitCode="false" /> + <RemoveDir Directories="%(WebInstaller.LayoutDir)" /> + <RemoveDir Directories="%(WebInstaller.SourceDir)" /> + <RemoveDir Directories="%(WebInstaller.LogDir)" /> + <Message Text="Successfully downloaded %(WebInstaller.Filename)%(WebInstaller.Extension) layout" Importance="high" /> + </Target> + + <Target Name="Upload" DependsOnTargets="_ValidateProperties;_RunGpg;_PrintNames;_Upload" /> + <Target Name="Test" DependsOnTargets="_TestLayout" /> + + <Target Name="Purge"> + <Error Condition="!Exists('$(PythonExe)')" Text="No Python executable available at $(PythonExe)" /> + <Exec Command="echo "$(PythonExe)" purge.py $(PythonVersion)" Condition="$(DryRun)" /> + <Exec Command=""$(PythonExe)" purge.py $(PythonVersion)" Condition="!$(DryRun)" /> + <Message Text="Purged uploaded files" Importance="high" /> + </Target> + + <Target Name="ShowHashes"> + <ItemGroup> + <UserFiles Include="@(File)" Condition="'%(File.CopyTo)' == '$(EXETarget)'" /> + </ItemGroup> + + <Error Text="No files generated" Condition="@(UserFiles) == ''" /> + <Exec Command=""$(PythonExe)" generate_md5.py @(UserFiles->'"%(FullPath)"',' ')" /> + </Target> + + <Target Name="Build"> + <Error Text="This script should be invoked using uploadrelease.bat." /> + </Target> +</Project> diff --git a/Tools/msi/uploadrelease.ps1 b/Tools/msi/uploadrelease.ps1 index 227ec255..a8669e5d 100644 --- a/Tools/msi/uploadrelease.ps1 +++ b/Tools/msi/uploadrelease.ps1 @@ -1,171 +1,171 @@ -<# -.Synopsis - Uploads from a VSTS release build layout to python.org -.Description - Given the downloaded/extracted build artifact from a release - build run on python.visualstudio.com, this script uploads - the files to the correct locations. -.Parameter build - The location on disk of the extracted build artifact. -.Parameter user - The username to use when logging into the host. -.Parameter server - The host or PuTTY session name. -.Parameter target - The subdirectory on the host to copy files to. -.Parameter tests - The path to run download tests in. -.Parameter doc_htmlhelp - Optional path besides -build to locate CHM files. -.Parameter embed - Optional path besides -build to locate ZIP files. -.Parameter skipupload - Skip uploading -.Parameter skippurge - Skip purging the CDN -.Parameter skiptest - Skip the download tests -.Parameter skiphash - Skip displaying hashes -#> -param( - [Parameter(Mandatory=$true)][string]$build, - [Parameter(Mandatory=$true)][string]$user, - [string]$server="python-downloads", - [string]$target="/srv/www.python.org/ftp/python", - [string]$tests=${env:TEMP}, - [string]$doc_htmlhelp=$null, - [string]$embed=$null, - [switch]$skipupload, - [switch]$skippurge, - [switch]$skiptest, - [switch]$skiphash -) - -if (-not $build) { throw "-build option is required" } -if (-not $user) { throw "-user option is required" } - -$tools = $script:MyInvocation.MyCommand.Path | Split-Path -parent; - -if (-not ((Test-Path "$build\win32\python-*.exe") -or (Test-Path "$build\amd64\python-*.exe"))) { - throw "-build argument does not look like a 'build' directory" -} - -function find-putty-tool { - param ([string]$n) - $t = gcm $n -EA 0 - if (-not $t) { $t = gcm ".\$n" -EA 0 } - if (-not $t) { $t = gcm "${env:ProgramFiles}\PuTTY\$n" -EA 0 } - if (-not $t) { $t = gcm "${env:ProgramFiles(x86)}\PuTTY\$n" -EA 0 } - if (-not $t) { throw "Unable to locate $n.exe. Please put it on $PATH" } - return gi $t.Path -} - -$p = gci -r "$build\python-*.exe" | ` - ?{ $_.Name -match '^python-(\d+\.\d+\.\d+)((a|b|rc)\d+)?-.+' } | ` - select -first 1 | ` - %{ $Matches[1], $Matches[2] } - -"Uploading version $($p[0]) $($p[1])" -" from: $build" -" to: $($server):$target/$($p[0])" -"" - -if (-not $skipupload) { - # Upload files to the server - $pscp = find-putty-tool "pscp" - $plink = find-putty-tool "plink" - - "Upload using $pscp and $plink" - "" - - if ($doc_htmlhelp) { - $chm = gci -EA 0 $doc_htmlhelp\python*.chm, $doc_htmlhelp\python*.chm.asc - } else { - $chm = gci -EA 0 $build\python*.chm, $build\python*.chm.asc - } - - $d = "$target/$($p[0])/" - & $plink -batch $user@$server mkdir $d - & $plink -batch $user@$server chgrp downloads $d - & $plink -batch $user@$server chmod o+rx $d - if ($chm) { - & $pscp -batch $chm.FullName "$user@${server}:$d" - if (-not $?) { throw "Failed to upload $chm" } - } - - $dirs = gci "$build" -Directory - if ($embed) { - $dirs = ($dirs, (gi $embed)) | %{ $_ } - } - - foreach ($a in $dirs) { - "Uploading files from $($a.FullName)" - pushd "$($a.FullName)" - $exe = gci *.exe, *.exe.asc, *.zip, *.zip.asc - $msi = gci *.msi, *.msi.asc, *.msu, *.msu.asc - popd - - if ($exe) { - & $pscp -batch $exe.FullName "$user@${server}:$d" - if (-not $?) { throw "Failed to upload $exe" } - } - - if ($msi) { - $sd = "$d$($a.Name)$($p[1])/" - & $plink -batch $user@$server mkdir $sd - & $plink -batch $user@$server chgrp downloads $sd - & $plink -batch $user@$server chmod o+rx $sd - & $pscp -batch $msi.FullName "$user@${server}:$sd" - if (-not $?) { throw "Failed to upload $msi" } - & $plink -batch $user@$server chgrp downloads $sd* - & $plink -batch $user@$server chmod g-x,o+r $sd* - } - } - - & $plink -batch $user@$server chgrp downloads $d* - & $plink -batch $user@$server chmod g-x,o+r $d* - & $pscp -ls "$user@${server}:$d" -} - -if (-not $skippurge) { - # Run a CDN purge - py $tools\purge.py "$($p[0])$($p[1])" -} - -if (-not $skiptest) { - # Use each web installer to produce a layout. This will download - # each referenced file and validate their signatures/hashes. - gci "$build\*-webinstall.exe" -r -File | %{ - $d = mkdir "$tests\$($_.BaseName)" -Force - gci $d -r -File | del - $ic = copy $_ $d -PassThru - "Checking layout for $($ic.Name)" - Start-Process -wait $ic "/passive", "/layout", "$d\layout", "/log", "$d\log\install.log" - if (-not $?) { - Write-Error "Failed to validate layout of $($inst.Name)" - } - } -} - -if (-not $skiphash) { - # Display MD5 hash and size of each downloadable file - pushd $build - $files = gci python*.chm, *\*.exe, *\*.zip - if ($doc_htmlhelp) { - cd $doc_htmlhelp - $files = ($files, (gci python*.chm)) | %{ $_ } - } - if ($embed) { - cd $embed - $files = ($files, (gci *.zip)) | %{ $_ } - } - popd - - $hashes = $files | ` - Sort-Object Name | ` - Format-Table Name, @{Label="MD5"; Expression={(Get-FileHash $_ -Algorithm MD5).Hash}}, Length -AutoSize | ` - Out-String -Width 4096 - $hashes | clip - $hashes -} +<# +.Synopsis + Uploads from a VSTS release build layout to python.org +.Description + Given the downloaded/extracted build artifact from a release + build run on python.visualstudio.com, this script uploads + the files to the correct locations. +.Parameter build + The location on disk of the extracted build artifact. +.Parameter user + The username to use when logging into the host. +.Parameter server + The host or PuTTY session name. +.Parameter target + The subdirectory on the host to copy files to. +.Parameter tests + The path to run download tests in. +.Parameter doc_htmlhelp + Optional path besides -build to locate CHM files. +.Parameter embed + Optional path besides -build to locate ZIP files. +.Parameter skipupload + Skip uploading +.Parameter skippurge + Skip purging the CDN +.Parameter skiptest + Skip the download tests +.Parameter skiphash + Skip displaying hashes +#> +param( + [Parameter(Mandatory=$true)][string]$build, + [Parameter(Mandatory=$true)][string]$user, + [string]$server="python-downloads", + [string]$target="/srv/www.python.org/ftp/python", + [string]$tests=${env:TEMP}, + [string]$doc_htmlhelp=$null, + [string]$embed=$null, + [switch]$skipupload, + [switch]$skippurge, + [switch]$skiptest, + [switch]$skiphash +) + +if (-not $build) { throw "-build option is required" } +if (-not $user) { throw "-user option is required" } + +$tools = $script:MyInvocation.MyCommand.Path | Split-Path -parent; + +if (-not ((Test-Path "$build\win32\python-*.exe") -or (Test-Path "$build\amd64\python-*.exe"))) { + throw "-build argument does not look like a 'build' directory" +} + +function find-putty-tool { + param ([string]$n) + $t = gcm $n -EA 0 + if (-not $t) { $t = gcm ".\$n" -EA 0 } + if (-not $t) { $t = gcm "${env:ProgramFiles}\PuTTY\$n" -EA 0 } + if (-not $t) { $t = gcm "${env:ProgramFiles(x86)}\PuTTY\$n" -EA 0 } + if (-not $t) { throw "Unable to locate $n.exe. Please put it on $PATH" } + return gi $t.Path +} + +$p = gci -r "$build\python-*.exe" | ` + ?{ $_.Name -match '^python-(\d+\.\d+\.\d+)((a|b|rc)\d+)?-.+' } | ` + select -first 1 | ` + %{ $Matches[1], $Matches[2] } + +"Uploading version $($p[0]) $($p[1])" +" from: $build" +" to: $($server):$target/$($p[0])" +"" + +if (-not $skipupload) { + # Upload files to the server + $pscp = find-putty-tool "pscp" + $plink = find-putty-tool "plink" + + "Upload using $pscp and $plink" + "" + + if ($doc_htmlhelp) { + $chm = gci -EA 0 $doc_htmlhelp\python*.chm, $doc_htmlhelp\python*.chm.asc + } else { + $chm = gci -EA 0 $build\python*.chm, $build\python*.chm.asc + } + + $d = "$target/$($p[0])/" + & $plink -batch $user@$server mkdir $d + & $plink -batch $user@$server chgrp downloads $d + & $plink -batch $user@$server chmod o+rx $d + if ($chm) { + & $pscp -batch $chm.FullName "$user@${server}:$d" + if (-not $?) { throw "Failed to upload $chm" } + } + + $dirs = gci "$build" -Directory + if ($embed) { + $dirs = ($dirs, (gi $embed)) | %{ $_ } + } + + foreach ($a in $dirs) { + "Uploading files from $($a.FullName)" + pushd "$($a.FullName)" + $exe = gci *.exe, *.exe.asc, *.zip, *.zip.asc + $msi = gci *.msi, *.msi.asc, *.msu, *.msu.asc + popd + + if ($exe) { + & $pscp -batch $exe.FullName "$user@${server}:$d" + if (-not $?) { throw "Failed to upload $exe" } + } + + if ($msi) { + $sd = "$d$($a.Name)$($p[1])/" + & $plink -batch $user@$server mkdir $sd + & $plink -batch $user@$server chgrp downloads $sd + & $plink -batch $user@$server chmod o+rx $sd + & $pscp -batch $msi.FullName "$user@${server}:$sd" + if (-not $?) { throw "Failed to upload $msi" } + & $plink -batch $user@$server chgrp downloads $sd* + & $plink -batch $user@$server chmod g-x,o+r $sd* + } + } + + & $plink -batch $user@$server chgrp downloads $d* + & $plink -batch $user@$server chmod g-x,o+r $d* + & $pscp -ls "$user@${server}:$d" +} + +if (-not $skippurge) { + # Run a CDN purge + py $tools\purge.py "$($p[0])$($p[1])" +} + +if (-not $skiptest) { + # Use each web installer to produce a layout. This will download + # each referenced file and validate their signatures/hashes. + gci "$build\*-webinstall.exe" -r -File | %{ + $d = mkdir "$tests\$($_.BaseName)" -Force + gci $d -r -File | del + $ic = copy $_ $d -PassThru + "Checking layout for $($ic.Name)" + Start-Process -wait $ic "/passive", "/layout", "$d\layout", "/log", "$d\log\install.log" + if (-not $?) { + Write-Error "Failed to validate layout of $($inst.Name)" + } + } +} + +if (-not $skiphash) { + # Display MD5 hash and size of each downloadable file + pushd $build + $files = gci python*.chm, *\*.exe, *\*.zip + if ($doc_htmlhelp) { + cd $doc_htmlhelp + $files = ($files, (gci python*.chm)) | %{ $_ } + } + if ($embed) { + cd $embed + $files = ($files, (gci *.zip)) | %{ $_ } + } + popd + + $hashes = $files | ` + Sort-Object Name | ` + Format-Table Name, @{Label="MD5"; Expression={(Get-FileHash $_ -Algorithm MD5).Hash}}, Length -AutoSize | ` + Out-String -Width 4096 + $hashes | clip + $hashes +} diff --git a/Tools/msi/wix.props b/Tools/msi/wix.props index 732f561e..d8ced317 100644 --- a/Tools/msi/wix.props +++ b/Tools/msi/wix.props @@ -1,12 +1,12 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <Import Project="..\..\PCbuild\python.props" /> - - <PropertyGroup> - <WixInstallPath Condition="'$(WixInstallPath)' == '' and Exists('$(MSBuildThisFileDirectory)\Wix')">$(MSBuildThisFileDirectory)\Wix\</WixInstallPath> - <WixInstallPath Condition="'$(WixInstallPath)' == '' and Exists('$(ExternalsDir)\windows-installer\wix-314')">$(ExternalsDir)\windows-installer\wix-314\</WixInstallPath> - <WixInstallPath Condition="'$(WixInstallPath)' == ''">$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Installer XML\3.10@InstallRoot)</WixInstallPath> - <WixInstallPath Condition="'$(WixInstallPath)' == ''">$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows Installer XML\3.10@InstallRoot)</WixInstallPath> - <WixTargetsPath>$(WixInstallPath)\Wix.targets</WixTargetsPath> - </PropertyGroup> +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="..\..\PCbuild\python.props" /> + + <PropertyGroup> + <WixInstallPath Condition="'$(WixInstallPath)' == '' and Exists('$(MSBuildThisFileDirectory)\Wix')">$(MSBuildThisFileDirectory)\Wix\</WixInstallPath> + <WixInstallPath Condition="'$(WixInstallPath)' == '' and Exists('$(ExternalsDir)\windows-installer\wix-314')">$(ExternalsDir)\windows-installer\wix-314\</WixInstallPath> + <WixInstallPath Condition="'$(WixInstallPath)' == ''">$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Installer XML\3.10@InstallRoot)</WixInstallPath> + <WixInstallPath Condition="'$(WixInstallPath)' == ''">$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows Installer XML\3.10@InstallRoot)</WixInstallPath> + <WixTargetsPath>$(WixInstallPath)\Wix.targets</WixTargetsPath> + </PropertyGroup> </Project> \ No newline at end of file diff --git a/Tools/nuget/build.bat b/Tools/nuget/build.bat index 1527a540..b532bd74 100644 --- a/Tools/nuget/build.bat +++ b/Tools/nuget/build.bat @@ -1,70 +1,70 @@ -@echo off -setlocal -set D=%~dp0 -set PCBUILD=%D%..\..\PCbuild\ -if "%Py_OutDir%"=="" set Py_OutDir=%PCBUILD% - -set BUILDX86= -set BUILDX64= -set BUILDARM32= -set REBUILD= -set OUTPUT= -set PACKAGES= -set PYTHON_EXE= - -:CheckOpts -if "%~1" EQU "-h" goto Help -if "%~1" EQU "-x86" (set BUILDX86=1) && shift && goto CheckOpts -if "%~1" EQU "-x64" (set BUILDX64=1) && shift && goto CheckOpts -if "%~1" EQU "-arm32" (set BUILDARM32=1) && shift && goto CheckOpts -if "%~1" EQU "-r" (set REBUILD=-r) && shift && goto CheckOpts -if "%~1" EQU "-o" (set OUTPUT="/p:OutputPath=%~2") && shift && shift && goto CheckOpts -if "%~1" EQU "--out" (set OUTPUT="/p:OutputPath=%~2") && shift && shift && goto CheckOpts -if "%~1" EQU "-p" (set PACKAGES=%PACKAGES% %~2) && shift && shift && goto CheckOpts -if "%~1" EQU "--python-exe" (set PYTHON_EXE="/p:PythonExe=%~2") && shift && shift && goto CheckOpts - -if not defined BUILDX86 if not defined BUILDX64 if not defined BUILDARM32 (set BUILDX86=1) && (set BUILDX64=1) && (set BUILDARM32=1) - -call "%D%..\msi\get_externals.bat" -call "%PCBUILD%find_msbuild.bat" %MSBUILD% -if ERRORLEVEL 1 (echo Cannot locate MSBuild.exe on PATH or as MSBUILD variable & exit /b 2) - -if defined PACKAGES set PACKAGES="/p:Packages=%PACKAGES%" - -if defined BUILDX86 ( - if defined REBUILD ( call "%PCBUILD%build.bat" -e -r - ) else if not exist "%Py_OutDir%win32\python.exe" call "%PCBUILD%build.bat" -e - if errorlevel 1 goto :eof - - %MSBUILD% "%D%make_pkg.proj" /p:Configuration=Release /p:Platform=x86 %OUTPUT% %PACKAGES% %PYTHON_EXE% - if errorlevel 1 goto :eof -) - -if defined BUILDX64 ( - if defined REBUILD ( call "%PCBUILD%build.bat" -p x64 -e -r - ) else if not exist "%Py_OutDir%amd64\python.exe" call "%PCBUILD%build.bat" -p x64 -e - if errorlevel 1 goto :eof - - %MSBUILD% "%D%make_pkg.proj" /p:Configuration=Release /p:Platform=x64 %OUTPUT% %PACKAGES% %PYTHON_EXE% - if errorlevel 1 goto :eof -) - -if defined BUILDARM32 ( - if defined REBUILD ( call "%PCBUILD%build.bat" -p ARM -e -r --no-tkinter - ) else if not exist "%Py_OutDir%arm32\python.exe" call "%PCBUILD%build.bat" -p ARM -e --no-tkinter - if errorlevel 1 goto :eof - - %MSBUILD% "%D%make_pkg.proj" /p:Configuration=Release /p:Platform=ARM %OUTPUT% %PACKAGES% %PYTHON_EXE% - if errorlevel 1 goto :eof -) - -exit /B 0 - -:Help -echo build.bat [-x86] [-x64] [--out DIR] [-r] [-h] -echo. -echo -x86 Build x86 installers -echo -x64 Build x64 installers -echo -r Rebuild rather than incremental build -echo --out [DIR] Override output directory -echo -h Show usage +@echo off +setlocal +set D=%~dp0 +set PCBUILD=%D%..\..\PCbuild\ +if "%Py_OutDir%"=="" set Py_OutDir=%PCBUILD% + +set BUILDX86= +set BUILDX64= +set BUILDARM32= +set REBUILD= +set OUTPUT= +set PACKAGES= +set PYTHON_EXE= + +:CheckOpts +if "%~1" EQU "-h" goto Help +if "%~1" EQU "-x86" (set BUILDX86=1) && shift && goto CheckOpts +if "%~1" EQU "-x64" (set BUILDX64=1) && shift && goto CheckOpts +if "%~1" EQU "-arm32" (set BUILDARM32=1) && shift && goto CheckOpts +if "%~1" EQU "-r" (set REBUILD=-r) && shift && goto CheckOpts +if "%~1" EQU "-o" (set OUTPUT="/p:OutputPath=%~2") && shift && shift && goto CheckOpts +if "%~1" EQU "--out" (set OUTPUT="/p:OutputPath=%~2") && shift && shift && goto CheckOpts +if "%~1" EQU "-p" (set PACKAGES=%PACKAGES% %~2) && shift && shift && goto CheckOpts +if "%~1" EQU "--python-exe" (set PYTHON_EXE="/p:PythonExe=%~2") && shift && shift && goto CheckOpts + +if not defined BUILDX86 if not defined BUILDX64 if not defined BUILDARM32 (set BUILDX86=1) && (set BUILDX64=1) && (set BUILDARM32=1) + +call "%D%..\msi\get_externals.bat" +call "%PCBUILD%find_msbuild.bat" %MSBUILD% +if ERRORLEVEL 1 (echo Cannot locate MSBuild.exe on PATH or as MSBUILD variable & exit /b 2) + +if defined PACKAGES set PACKAGES="/p:Packages=%PACKAGES%" + +if defined BUILDX86 ( + if defined REBUILD ( call "%PCBUILD%build.bat" -e -r + ) else if not exist "%Py_OutDir%win32\python.exe" call "%PCBUILD%build.bat" -e + if errorlevel 1 goto :eof + + %MSBUILD% "%D%make_pkg.proj" /p:Configuration=Release /p:Platform=x86 %OUTPUT% %PACKAGES% %PYTHON_EXE% + if errorlevel 1 goto :eof +) + +if defined BUILDX64 ( + if defined REBUILD ( call "%PCBUILD%build.bat" -p x64 -e -r + ) else if not exist "%Py_OutDir%amd64\python.exe" call "%PCBUILD%build.bat" -p x64 -e + if errorlevel 1 goto :eof + + %MSBUILD% "%D%make_pkg.proj" /p:Configuration=Release /p:Platform=x64 %OUTPUT% %PACKAGES% %PYTHON_EXE% + if errorlevel 1 goto :eof +) + +if defined BUILDARM32 ( + if defined REBUILD ( call "%PCBUILD%build.bat" -p ARM -e -r --no-tkinter + ) else if not exist "%Py_OutDir%arm32\python.exe" call "%PCBUILD%build.bat" -p ARM -e --no-tkinter + if errorlevel 1 goto :eof + + %MSBUILD% "%D%make_pkg.proj" /p:Configuration=Release /p:Platform=ARM %OUTPUT% %PACKAGES% %PYTHON_EXE% + if errorlevel 1 goto :eof +) + +exit /B 0 + +:Help +echo build.bat [-x86] [-x64] [--out DIR] [-r] [-h] +echo. +echo -x86 Build x86 installers +echo -x64 Build x64 installers +echo -r Rebuild rather than incremental build +echo --out [DIR] Override output directory +echo -h Show usage diff --git a/Tools/nuget/make_pkg.proj b/Tools/nuget/make_pkg.proj index 0fd0d304..710ef3dc 100644 --- a/Tools/nuget/make_pkg.proj +++ b/Tools/nuget/make_pkg.proj @@ -1,63 +1,63 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <PropertyGroup> - <ProjectGuid>{10487945-15D1-4092-A214-338395C4116B}</ProjectGuid> - <OutputName>python</OutputName> - <OutputName Condition="$(Platform) == 'x86'">$(OutputName)x86</OutputName> - <OutputName Condition="$(Platform) == 'ARM'">$(OutputName)arm32</OutputName> - <OutputName Condition="$(BuildForDaily) == 'true'">$(OutputName)daily</OutputName> - <OutputSuffix></OutputSuffix> - <SupportSigning>false</SupportSigning> - <BuildForRelease Condition="$(BuildForRelease) == ''">true</BuildForRelease> - </PropertyGroup> - - <Import Project="..\msi\msi.props" /> - - <PropertyGroup> - <Nuget Condition="$(Nuget) == ''">$(ExternalsDir)\windows-installer\nuget\nuget.exe</Nuget> - <NuspecVersion>$(MajorVersionNumber).$(MinorVersionNumber).$(MicroVersionNumber)</NuspecVersion> - <NuspecVersion Condition="$(ReleaseLevelName) != ''">$(NuspecVersion)-$(ReleaseLevelName)</NuspecVersion> - <NuspecVersion Condition="$(BuildForDaily) == 'true'">$(MajorVersionNumber).$(MinorVersionNumber).$(DailyBuildVersion)</NuspecVersion> - <SignOutput>false</SignOutput> - <TargetName>$(OutputName).$(NuspecVersion)</TargetName> - <TargetExt>.nupkg</TargetExt> - <IntermediateOutputPath>$(IntermediateOutputPath)\nuget_$(ArchName)\</IntermediateOutputPath> - - <CleanCommand>rmdir /q/s "$(IntermediateOutputPath.TrimEnd(`\`))"</CleanCommand> - - <PythonArguments>"$(PythonExe)" "$(PySourcePath)PC\layout"</PythonArguments> - <PythonArguments>$(PythonArguments) -b "$(BuildPath.TrimEnd(`\`))" -s "$(PySourcePath.TrimEnd(`\`))"</PythonArguments> - <PythonArguments>$(PythonArguments) -t "$(IntermediateOutputPath)obj"</PythonArguments> - <PythonArguments>$(PythonArguments) --copy "$(IntermediateOutputPath)pkg"</PythonArguments> - <PythonArguments>$(PythonArguments) --preset-nuget</PythonArguments> - - <PackageArguments Condition="$(Packages) != ''">"$(IntermediateOutputPath)pkg\pip.exe" -B -m pip install -U $(Packages)</PackageArguments> - - <NugetPackCommand>"$(Nuget)" pack "$(IntermediateOutputPath)pkg\python.nuspec" -BasePath "$(IntermediateOutputPath)pkg"</NugetPackCommand> - <NugetPackSymbolsCommand Condition="Exists('$(MSBuildThisFileDirectory)\$(OutputName).symbols.nuspec')">"$(Nuget)" pack "$(MSBuildThisFileDirectory)\$(OutputName).symbols.nuspec" -BasePath "$(BuildPath.TrimEnd(`\`))"</NugetPackSymbolsCommand> - <NugetArguments>$(NugetArguments) -OutputDirectory "$(OutputPath.Trim(`\`))"</NugetArguments> - <NugetArguments>$(NugetArguments) -Version "$(NuspecVersion)"</NugetArguments> - <NugetArguments>$(NugetArguments) -NoPackageAnalysis -NonInteractive</NugetArguments> - - <Environment>$(Environment)%0D%0Aset PYTHONPATH=$(PySourcePath)Lib</Environment> - <Environment>$(Environment)%0D%0Aset PYTHON_NUSPEC_VERSION=$(NuspecVersion)</Environment> - <Environment Condition="$(Platform) != 'x86'">$(Environment)%0D%0Aset PYTHON_PROPS_PLATFORM=$(Platform)</Environment> - <Environment Condition="$(Platform) == 'x86'">$(Environment)%0D%0Aset PYTHON_PROPS_PLATFORM=Win32</Environment> - <Environment>$(Environment)%0D%0Amkdir "$(OutputPath.Trim(`\`))" >nul 2>nul</Environment> - </PropertyGroup> - - <Target Name="_NugetMissing" BeforeTargets="_Build" Condition="!Exists($(Nuget))"> - <Error Text="$(Nuget) could not be found. Either avoid specifying the property or update your externals/windows-installer files." /> - </Target> - - <Target Name="_Build"> - <Exec Command="$(CleanCommand)" /> - <Exec Command="setlocal%0D%0A$(Environment)%0D%0A$(PythonArguments)%0D%0A$(PackageArguments)" /> - - <Exec Command="$(NugetPackCommand) $(NugetArguments)" /> - <Exec Command="$(NugetPackSymbolsCommand) $(NugetArguments)" Condition="$(NugetPackSymbolsCommand) != ''" /> - </Target> - - <Target Name="AfterBuild" /> - <Target Name="Build" DependsOnTargets="_Build;AfterBuild" /> -</Project> +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup> + <ProjectGuid>{10487945-15D1-4092-A214-338395C4116B}</ProjectGuid> + <OutputName>python</OutputName> + <OutputName Condition="$(Platform) == 'x86'">$(OutputName)x86</OutputName> + <OutputName Condition="$(Platform) == 'ARM'">$(OutputName)arm32</OutputName> + <OutputName Condition="$(BuildForDaily) == 'true'">$(OutputName)daily</OutputName> + <OutputSuffix></OutputSuffix> + <SupportSigning>false</SupportSigning> + <BuildForRelease Condition="$(BuildForRelease) == ''">true</BuildForRelease> + </PropertyGroup> + + <Import Project="..\msi\msi.props" /> + + <PropertyGroup> + <Nuget Condition="$(Nuget) == ''">$(ExternalsDir)\windows-installer\nuget\nuget.exe</Nuget> + <NuspecVersion>$(MajorVersionNumber).$(MinorVersionNumber).$(MicroVersionNumber)</NuspecVersion> + <NuspecVersion Condition="$(ReleaseLevelName) != ''">$(NuspecVersion)-$(ReleaseLevelName)</NuspecVersion> + <NuspecVersion Condition="$(BuildForDaily) == 'true'">$(MajorVersionNumber).$(MinorVersionNumber).$(DailyBuildVersion)</NuspecVersion> + <SignOutput>false</SignOutput> + <TargetName>$(OutputName).$(NuspecVersion)</TargetName> + <TargetExt>.nupkg</TargetExt> + <IntermediateOutputPath>$(IntermediateOutputPath)\nuget_$(ArchName)\</IntermediateOutputPath> + + <CleanCommand>rmdir /q/s "$(IntermediateOutputPath.TrimEnd(`\`))"</CleanCommand> + + <PythonArguments>"$(PythonExe)" "$(PySourcePath)PC\layout"</PythonArguments> + <PythonArguments>$(PythonArguments) -b "$(BuildPath.TrimEnd(`\`))" -s "$(PySourcePath.TrimEnd(`\`))"</PythonArguments> + <PythonArguments>$(PythonArguments) -t "$(IntermediateOutputPath)obj"</PythonArguments> + <PythonArguments>$(PythonArguments) --copy "$(IntermediateOutputPath)pkg"</PythonArguments> + <PythonArguments>$(PythonArguments) --preset-nuget</PythonArguments> + + <PackageArguments Condition="$(Packages) != ''">"$(IntermediateOutputPath)pkg\pip.exe" -B -m pip install -U $(Packages)</PackageArguments> + + <NugetPackCommand>"$(Nuget)" pack "$(IntermediateOutputPath)pkg\python.nuspec" -BasePath "$(IntermediateOutputPath)pkg"</NugetPackCommand> + <NugetPackSymbolsCommand Condition="Exists('$(MSBuildThisFileDirectory)\$(OutputName).symbols.nuspec')">"$(Nuget)" pack "$(MSBuildThisFileDirectory)\$(OutputName).symbols.nuspec" -BasePath "$(BuildPath.TrimEnd(`\`))"</NugetPackSymbolsCommand> + <NugetArguments>$(NugetArguments) -OutputDirectory "$(OutputPath.Trim(`\`))"</NugetArguments> + <NugetArguments>$(NugetArguments) -Version "$(NuspecVersion)"</NugetArguments> + <NugetArguments>$(NugetArguments) -NoPackageAnalysis -NonInteractive</NugetArguments> + + <Environment>$(Environment)%0D%0Aset PYTHONPATH=$(PySourcePath)Lib</Environment> + <Environment>$(Environment)%0D%0Aset PYTHON_NUSPEC_VERSION=$(NuspecVersion)</Environment> + <Environment Condition="$(Platform) != 'x86'">$(Environment)%0D%0Aset PYTHON_PROPS_PLATFORM=$(Platform)</Environment> + <Environment Condition="$(Platform) == 'x86'">$(Environment)%0D%0Aset PYTHON_PROPS_PLATFORM=Win32</Environment> + <Environment>$(Environment)%0D%0Amkdir "$(OutputPath.Trim(`\`))" >nul 2>nul</Environment> + </PropertyGroup> + + <Target Name="_NugetMissing" BeforeTargets="_Build" Condition="!Exists($(Nuget))"> + <Error Text="$(Nuget) could not be found. Either avoid specifying the property or update your externals/windows-installer files." /> + </Target> + + <Target Name="_Build"> + <Exec Command="$(CleanCommand)" /> + <Exec Command="setlocal%0D%0A$(Environment)%0D%0A$(PythonArguments)%0D%0A$(PackageArguments)" /> + + <Exec Command="$(NugetPackCommand) $(NugetArguments)" /> + <Exec Command="$(NugetPackSymbolsCommand) $(NugetArguments)" Condition="$(NugetPackSymbolsCommand) != ''" /> + </Target> + + <Target Name="AfterBuild" /> + <Target Name="Build" DependsOnTargets="_Build;AfterBuild" /> +</Project> diff --git a/Tools/scripts/patchcheck.py b/Tools/patchcheck/patchcheck.py similarity index 94% rename from Tools/scripts/patchcheck.py rename to Tools/patchcheck/patchcheck.py index a324eafc..fa3a43af 100755 --- a/Tools/scripts/patchcheck.py +++ b/Tools/patchcheck/patchcheck.py @@ -13,11 +13,11 @@ import untabify # Excluded directories which are copies of external libraries: # don't check their coding style -EXCLUDE_DIRS = [os.path.join('Modules', '_ctypes', 'libffi_osx'), - os.path.join('Modules', '_ctypes', 'libffi_msvc'), - os.path.join('Modules', '_decimal', 'libmpdec'), - os.path.join('Modules', 'expat'), - os.path.join('Modules', 'zlib')] +EXCLUDE_DIRS = [ + os.path.join('Modules', '_decimal', 'libmpdec'), + os.path.join('Modules', 'expat'), + os.path.join('Modules', 'zlib'), + ] SRCDIR = sysconfig.get_config_var('srcdir') @@ -130,9 +130,10 @@ def changed_files(base_branch=None): with subprocess.Popen(cmd.split(), stdout=subprocess.PIPE, cwd=SRCDIR) as st: - if st.wait() != 0: + git_file_status, _ = st.communicate() + if st.returncode != 0: sys.exit(f'error running {cmd}') - for line in st.stdout: + for line in git_file_status.splitlines(): line = line.decode().rstrip() status_text, filename = line.split(maxsplit=1) status = set(status_text) @@ -169,12 +170,24 @@ def report_modified_files(file_paths): return "\n".join(lines) +#: Python files that have tabs by design: +_PYTHON_FILES_WITH_TABS = frozenset({ + 'Tools/c-analyzer/cpython/_parser.py', +}) + + @status("Fixing Python file whitespace", info=report_modified_files) def normalize_whitespace(file_paths): """Make sure that the whitespace for .py files have been normalized.""" reindent.makebackup = False # No need to create backups. - fixed = [path for path in file_paths if path.endswith('.py') and - reindent.check(os.path.join(SRCDIR, path))] + fixed = [ + path for path in file_paths + if ( + path.endswith('.py') + and path not in _PYTHON_FILES_WITH_TABS + and reindent.check(os.path.join(SRCDIR, path)) + ) + ] return fixed diff --git a/Tools/scripts/reindent.py b/Tools/patchcheck/reindent.py similarity index 100% rename from Tools/scripts/reindent.py rename to Tools/patchcheck/reindent.py diff --git a/Tools/scripts/untabify.py b/Tools/patchcheck/untabify.py similarity index 100% rename from Tools/scripts/untabify.py rename to Tools/patchcheck/untabify.py diff --git a/Tools/peg_generator/Makefile b/Tools/peg_generator/Makefile index d010f19d..084da154 100644 --- a/Tools/peg_generator/Makefile +++ b/Tools/peg_generator/Makefile @@ -88,7 +88,7 @@ time_stdlib: $(CPYTHON) venv -d $(CPYTHON) \ $(TESTFLAGS) \ --exclude "*/bad*" \ - --exclude "*/lib2to3/tests/data/*" + --exclude "*/test/test_lib2to3/data/*" mypy: regen-metaparser $(MYPY) # For list of files, see mypy.ini diff --git a/Tools/peg_generator/peg_extension/peg_extension.c b/Tools/peg_generator/peg_extension/peg_extension.c index 3ebb7bdd..7df134b5 100644 --- a/Tools/peg_generator/peg_extension/peg_extension.c +++ b/Tools/peg_generator/peg_extension/peg_extension.c @@ -12,8 +12,7 @@ _build_return_object(mod_ty module, int mode, PyObject *filename_ob, PyArena *ar } else if (mode == 1) { result = PyAST_mod2obj(module); } else { - result = Py_None; - Py_INCREF(result); + result = Py_NewRef(Py_None); } return result; diff --git a/Tools/peg_generator/pegen/build.py b/Tools/peg_generator/pegen/build.py index 5805ff63..aace6840 100644 --- a/Tools/peg_generator/pegen/build.py +++ b/Tools/peg_generator/pegen/build.py @@ -1,4 +1,5 @@ import itertools +import os import pathlib import sys import sysconfig @@ -27,6 +28,46 @@ def get_extra_flags(compiler_flags: str, compiler_py_flags_nodist: str) -> List[ return f"{flags} {py_flags_nodist}".split() +def fixup_build_ext(cmd): + """Function needed to make build_ext tests pass. + + When Python was built with --enable-shared on Unix, -L. is not enough to + find libpython<blah>.so, because regrtest runs in a tempdir, not in the + source directory where the .so lives. + + When Python was built with in debug mode on Windows, build_ext commands + need their debug attribute set, and it is not done automatically for + some reason. + + This function handles both of these things. Example use: + + cmd = build_ext(dist) + support.fixup_build_ext(cmd) + cmd.ensure_finalized() + + Unlike most other Unix platforms, Mac OS X embeds absolute paths + to shared libraries into executables, so the fixup is not needed there. + + Taken from distutils (was part of the CPython stdlib until Python 3.11) + """ + if os.name == 'nt': + cmd.debug = sys.executable.endswith('_d.exe') + elif sysconfig.get_config_var('Py_ENABLE_SHARED'): + # To further add to the shared builds fun on Unix, we can't just add + # library_dirs to the Extension() instance because that doesn't get + # plumbed through to the final compiler command. + runshared = sysconfig.get_config_var('RUNSHARED') + if runshared is None: + cmd.library_dirs = ['.'] + else: + if sys.platform == 'darwin': + cmd.library_dirs = [] + else: + name, equals, value = runshared.partition('=') + cmd.library_dirs = [d for d in value.split(os.pathsep) if d] + + + def compile_c_extension( generated_source_path: str, build_dir: Optional[str] = None, @@ -49,16 +90,15 @@ def compile_c_extension( static library of the common parser sources (this is useful in case you are creating multiple extensions). """ - import distutils.log - from distutils.core import Distribution, Extension - from distutils.tests.support import fixup_build_ext # type: ignore + import setuptools.logging - from distutils.ccompiler import new_compiler - from distutils.dep_util import newer_group - from distutils.sysconfig import customize_compiler + from setuptools import Extension, Distribution + from setuptools._distutils.dep_util import newer_group + from setuptools._distutils.ccompiler import new_compiler + from setuptools._distutils.sysconfig import customize_compiler if verbose: - distutils.log.set_threshold(distutils.log.DEBUG) + setuptools.logging.set_threshold(setuptools.logging.logging.DEBUG) source_file_path = pathlib.Path(generated_source_path) extension_name = source_file_path.stem diff --git a/Tools/peg_generator/pegen/c_generator.py b/Tools/peg_generator/pegen/c_generator.py index 295bc1f8..301949bd 100644 --- a/Tools/peg_generator/pegen/c_generator.py +++ b/Tools/peg_generator/pegen/c_generator.py @@ -32,7 +32,7 @@ EXTENSION_PREFIX = """\ #include "pegen.h" #if defined(Py_DEBUG) && defined(Py_BUILD_CORE) -# define D(x) if (Py_DebugFlag) x; +# define D(x) if (p->debug) { x; } #else # define D(x) #endif @@ -68,6 +68,7 @@ class NodeTypes(Enum): KEYWORD = 4 SOFT_KEYWORD = 5 CUT_OPERATOR = 6 + F_STRING_CHUNK = 7 BASE_NODETYPES = { @@ -374,8 +375,7 @@ class CParserGenerator(ParserGenerator, GrammarVisitor): def add_level(self) -> None: self.print("if (p->level++ == MAXSTACK) {") with self.indent(): - self.print("p->error_indicator = 1;") - self.print("PyErr_NoMemory();") + self.print("_Pypegen_stack_overflow(p);") self.print("}") def remove_level(self) -> None: @@ -619,7 +619,8 @@ class CParserGenerator(ParserGenerator, GrammarVisitor): self.add_return("_res") self.print("}") self.print("int _mark = p->mark;") - self.print("int _start_mark = p->mark;") + if memoize: + self.print("int _start_mark = p->mark;") self.print("void **_children = PyMem_Malloc(sizeof(void *));") self.out_of_memory_return(f"!_children") self.print("Py_ssize_t _children_capacity = 1;") @@ -642,7 +643,7 @@ class CParserGenerator(ParserGenerator, GrammarVisitor): self.out_of_memory_return(f"!_seq", cleanup_code="PyMem_Free(_children);") self.print("for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]);") self.print("PyMem_Free(_children);") - if node.name: + if memoize and node.name: self.print(f"_PyPegen_insert_memo(p, _start_mark, {node.name}_type, _seq);") self.add_return("_seq") diff --git a/Tools/peg_generator/pegen/grammar.py b/Tools/peg_generator/pegen/grammar.py index fa47b982..03d60d01 100644 --- a/Tools/peg_generator/pegen/grammar.py +++ b/Tools/peg_generator/pegen/grammar.py @@ -1,23 +1,16 @@ from __future__ import annotations -from abc import abstractmethod from typing import ( - TYPE_CHECKING, AbstractSet, Any, - Dict, Iterable, Iterator, List, Optional, - Set, Tuple, Union, ) -if TYPE_CHECKING: - from pegen.parser_generator import ParserGenerator - class GrammarError(Exception): pass diff --git a/Tools/peg_generator/scripts/benchmark.py b/Tools/peg_generator/scripts/benchmark.py index 4a063bf1..053f8ef0 100644 --- a/Tools/peg_generator/scripts/benchmark.py +++ b/Tools/peg_generator/scripts/benchmark.py @@ -78,7 +78,7 @@ def run_benchmark_stdlib(subcommand): verbose=False, excluded_files=[ "*/bad*", - "*/lib2to3/tests/data/*", + "*/test/test_lib2to3/data/*", ], short=True, mode=modes[subcommand], diff --git a/Tools/peg_generator/scripts/grammar_grapher.py b/Tools/peg_generator/scripts/grammar_grapher.py index 4a41dfaa..e5271a0e 100755 --- a/Tools/peg_generator/scripts/grammar_grapher.py +++ b/Tools/peg_generator/scripts/grammar_grapher.py @@ -30,7 +30,6 @@ from pegen.grammar import ( Alt, Cut, Forced, - Grammar, Group, Leaf, Lookahead, diff --git a/Tools/peg_generator/scripts/test_parse_directory.py b/Tools/peg_generator/scripts/test_parse_directory.py index a5e26f0a..f5cf198b 100755 --- a/Tools/peg_generator/scripts/test_parse_directory.py +++ b/Tools/peg_generator/scripts/test_parse_directory.py @@ -5,7 +5,6 @@ import ast import os import sys import time -import traceback import tokenize from glob import glob, escape from pathlib import PurePath @@ -13,7 +12,6 @@ from pathlib import PurePath from typing import List, Optional, Any, Tuple sys.path.insert(0, os.getcwd()) -from pegen.ast_dump import ast_dump from pegen.testutil import print_memstats SUCCESS = "\033[92m" diff --git a/Tools/peg_generator/scripts/test_pypi_packages.py b/Tools/peg_generator/scripts/test_pypi_packages.py index e2eaef9d..01ccc3d2 100755 --- a/Tools/peg_generator/scripts/test_pypi_packages.py +++ b/Tools/peg_generator/scripts/test_pypi_packages.py @@ -9,11 +9,10 @@ import shutil import pathlib import sys -from typing import Generator, Any +from typing import Generator sys.path.insert(0, ".") -from pegen import build from scripts import test_parse_directory HERE = pathlib.Path(__file__).resolve().parent diff --git a/Tools/requirements-hypothesis.txt b/Tools/requirements-hypothesis.txt new file mode 100644 index 00000000..9db2b74c --- /dev/null +++ b/Tools/requirements-hypothesis.txt @@ -0,0 +1,4 @@ +# Requirements file for hypothesis that +# we use to run our property-based tests in CI. + +hypothesis==6.84.0 diff --git a/Tools/scripts/2to3 b/Tools/scripts/2to3 index fbd4aa6b..f27d18ec 100755 --- a/Tools/scripts/2to3 +++ b/Tools/scripts/2to3 @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 import sys from lib2to3.main import main diff --git a/Tools/scripts/README b/Tools/scripts/README index c1d66731..9dbb89a8 100644 --- a/Tools/scripts/README +++ b/Tools/scripts/README @@ -1,65 +1,16 @@ This directory contains a collection of executable Python scripts that are -useful while building, extending or managing Python. Some (e.g., dutree or lll) -are also generally useful UNIX tools. +useful while building, extending or managing Python. 2to3 Main script for running the 2to3 conversion tool -abitype.py Converts a C file to use the PEP 384 type definition API -analyze_dxp.py Analyzes the result of sys.getdxp() -byext.py Print lines/words/chars stats of files by extension -byteyears.py Print product of a file's size and age -cleanfuture.py Fix redundant Python __future__ statements +checkpip.py Checks the version of the projects bundled in ensurepip + are the latest available combinerefs.py A helper for analyzing PYTHONDUMPREFS output -copytime.py Copy one file's atime and mtime to another -crlf.py Change CRLF line endings to LF (Windows to Unix) -db2pickle.py Dump a database file to a pickle -diff.py Print file diffs in context, unified, or ndiff formats -dutree.py Format du(1) output as a tree sorted by size -eptags.py Create Emacs TAGS file for Python modules -finddiv.py A grep-like tool that looks for division operators -findlinksto.py Recursively find symbolic links to a given path prefix -findnocoding.py Find source files which need an encoding declaration -find_recursionlimit.py Find the maximum recursion limit on this machine -find-uname.py Look for the given arguments in the sets of all Unicode names -fixcid.py Massive identifier substitution on C source files -fixdiv.py Tool to fix division operators. -fixheader.py Add some cpp magic to a C include file -fixnotice.py Fix the copyright notice in source files -fixps.py Fix Python scripts' first line (if #!) -ftpmirror.py FTP mirror script -get-remote-certificate.py Fetch the certificate that the server(s) are providing in PEM form -google.py Open a webbrowser with Google -gprof2html.py Transform gprof(1) output into useful HTML -highlight.py Python syntax highlighting with HTML output +divmod_threshold.py Determine threshold for switching from longobject.c + divmod to _pylong.int_divmod() idle3 Main program to start IDLE -ifdef.py Remove #if(n)def groups from C sources -import_diagnostics.py Miscellaneous diagnostics for the import system -lfcr.py Change LF line endings to CRLF (Unix to Windows) -linktree.py Make a copy of a tree with links to original files -lll.py Find and list symbolic links in current directory -mailerdaemon.py Parse error messages from mailer daemons (Sjoerd&Jack) -make_ctype.py Generate ctype.h replacement in stringobject.c -md5sum.py Print MD5 checksums of argument files -mkreal.py Turn a symbolic link into a real file or directory -ndiff.py Intelligent diff between text files (Tim Peters) -nm2def.py Create a template for PC/python_nt.def (Marc Lemburg) -objgraph.py Print object graph from nm output on a library -parseentities.py Utility for parsing HTML entity definitions -parse_html5_entities.py Utility for parsing HTML5 entity definitions -patchcheck.py Perform common checks and cleanup before committing -pathfix.py Change #!/usr/local/bin/python into something else -pdeps.py Print dependencies between Python modules -pickle2db.py Load a pickle generated by db2pickle.py to a database -pindent.py Indent Python code, giving block-closing comments -ptags.py Create vi tags file for Python modules pydoc3 Python documentation browser -pysource.py Find Python source files -reindent.py Change .py files to use 4-space indents -reindent-rst.py Fix-up reStructuredText file whitespace -rgrep.py Reverse grep through a file (useful for big logfiles) run_tests.py Run the test suite with more sensible default options -stable_abi.py Stable ABI checks and file generators. -suff.py Sort a list of files by suffix -texi2html.py Convert GNU texinfo files into HTML -untabify.py Replace tabs with spaces in argument files -which.py Find a program in $PATH -win_add2path.py Add Python to the search path on Windows +summarize_stats.py Summarize specialization stats for all files in the + default stats folders +var_access_benchmark.py Show relative speeds of local, nonlocal, global, + and built-in access diff --git a/Tools/scripts/abitype.py b/Tools/scripts/abitype.py deleted file mode 100755 index d6a74a1f..00000000 --- a/Tools/scripts/abitype.py +++ /dev/null @@ -1,202 +0,0 @@ -#!/usr/bin/env python3 -# This script converts a C file to use the PEP 384 type definition API -# Usage: abitype.py < old_code > new_code -import re, sys - -###### Replacement of PyTypeObject static instances ############## - -# classify each token, giving it a one-letter code: -# S: static -# T: PyTypeObject -# I: ident -# W: whitespace -# =, {, }, ; : themselves -def classify(): - res = [] - for t,v in tokens: - if t == 'other' and v in "={};": - res.append(v) - elif t == 'ident': - if v == 'PyTypeObject': - res.append('T') - elif v == 'static': - res.append('S') - else: - res.append('I') - elif t == 'ws': - res.append('W') - else: - res.append('.') - return ''.join(res) - -# Obtain a list of fields of a PyTypeObject, in declaration order, -# skipping ob_base -# All comments are dropped from the variable (which are typically -# just the slot names, anyway), and information is discarded whether -# the original type was static. -def get_fields(start, real_end): - pos = start - # static? - if tokens[pos][1] == 'static': - pos += 2 - # PyTypeObject - pos += 2 - # name - name = tokens[pos][1] - pos += 1 - while tokens[pos][1] != '{': - pos += 1 - pos += 1 - # PyVarObject_HEAD_INIT - while tokens[pos][0] in ('ws', 'comment'): - pos += 1 - if tokens[pos][1] != 'PyVarObject_HEAD_INIT': - raise Exception('%s has no PyVarObject_HEAD_INIT' % name) - while tokens[pos][1] != ')': - pos += 1 - pos += 1 - # field definitions: various tokens, comma-separated - fields = [] - while True: - while tokens[pos][0] in ('ws', 'comment'): - pos += 1 - end = pos - while tokens[end][1] not in ',}': - if tokens[end][1] == '(': - nesting = 1 - while nesting: - end += 1 - if tokens[end][1] == '(': nesting+=1 - if tokens[end][1] == ')': nesting-=1 - end += 1 - assert end < real_end - # join field, excluding separator and trailing ws - end1 = end-1 - while tokens[end1][0] in ('ws', 'comment'): - end1 -= 1 - fields.append(''.join(t[1] for t in tokens[pos:end1+1])) - if tokens[end][1] == '}': - break - pos = end+1 - return name, fields - -# List of type slots as of Python 3.2, omitting ob_base -typeslots = [ - 'tp_name', - 'tp_basicsize', - 'tp_itemsize', - 'tp_dealloc', - 'tp_print', - 'tp_getattr', - 'tp_setattr', - 'tp_reserved', - 'tp_repr', - 'tp_as_number', - 'tp_as_sequence', - 'tp_as_mapping', - 'tp_hash', - 'tp_call', - 'tp_str', - 'tp_getattro', - 'tp_setattro', - 'tp_as_buffer', - 'tp_flags', - 'tp_doc', - 'tp_traverse', - 'tp_clear', - 'tp_richcompare', - 'tp_weaklistoffset', - 'tp_iter', - 'iternextfunc', - 'tp_methods', - 'tp_members', - 'tp_getset', - 'tp_base', - 'tp_dict', - 'tp_descr_get', - 'tp_descr_set', - 'tp_dictoffset', - 'tp_init', - 'tp_alloc', - 'tp_new', - 'tp_free', - 'tp_is_gc', - 'tp_bases', - 'tp_mro', - 'tp_cache', - 'tp_subclasses', - 'tp_weaklist', - 'tp_del', - 'tp_version_tag', -] - -# Generate a PyType_Spec definition -def make_slots(name, fields): - res = [] - res.append('static PyType_Slot %s_slots[] = {' % name) - # defaults for spec - spec = { 'tp_itemsize':'0' } - for i, val in enumerate(fields): - if val.endswith('0'): - continue - if typeslots[i] in ('tp_name', 'tp_doc', 'tp_basicsize', - 'tp_itemsize', 'tp_flags'): - spec[typeslots[i]] = val - continue - res.append(' {Py_%s, %s},' % (typeslots[i], val)) - res.append('};') - res.append('static PyType_Spec %s_spec = {' % name) - res.append(' %s,' % spec['tp_name']) - res.append(' %s,' % spec['tp_basicsize']) - res.append(' %s,' % spec['tp_itemsize']) - res.append(' %s,' % spec['tp_flags']) - res.append(' %s_slots,' % name) - res.append('};\n') - return '\n'.join(res) - - -if __name__ == '__main__': - - ############ Simplistic C scanner ################################## - tokenizer = re.compile( - r"(?P<preproc>#.*\n)" - r"|(?P<comment>/\*.*?\*/)" - r"|(?P<ident>[a-zA-Z_][a-zA-Z0-9_]*)" - r"|(?P<ws>[ \t\n]+)" - r"|(?P<other>.)", - re.MULTILINE) - - tokens = [] - source = sys.stdin.read() - pos = 0 - while pos != len(source): - m = tokenizer.match(source, pos) - tokens.append([m.lastgroup, m.group()]) - pos += len(tokens[-1][1]) - if tokens[-1][0] == 'preproc': - # continuation lines are considered - # only in preprocess statements - while tokens[-1][1].endswith('\\\n'): - nl = source.find('\n', pos) - if nl == -1: - line = source[pos:] - else: - line = source[pos:nl+1] - tokens[-1][1] += line - pos += len(line) - - # Main loop: replace all static PyTypeObjects until - # there are none left. - while 1: - c = classify() - m = re.search('(SW)?TWIW?=W?{.*?};', c) - if not m: - break - start = m.start() - end = m.end() - name, fields = get_fields(start, end) - tokens[start:end] = [('',make_slots(name, fields))] - - # Output result to stdout - for t, v in tokens: - sys.stdout.write(v) diff --git a/Tools/scripts/analyze_dxp.py b/Tools/scripts/analyze_dxp.py deleted file mode 100644 index bde931e7..00000000 --- a/Tools/scripts/analyze_dxp.py +++ /dev/null @@ -1,129 +0,0 @@ -""" -Some helper functions to analyze the output of sys.getdxp() (which is -only available if Python was built with -DDYNAMIC_EXECUTION_PROFILE). -These will tell you which opcodes have been executed most frequently -in the current process, and, if Python was also built with -DDXPAIRS, -will tell you which instruction _pairs_ were executed most frequently, -which may help in choosing new instructions. - -If Python was built without -DDYNAMIC_EXECUTION_PROFILE, importing -this module will raise a RuntimeError. - -If you're running a script you want to profile, a simple way to get -the common pairs is: - -$ PYTHONPATH=$PYTHONPATH:<python_srcdir>/Tools/scripts \ -./python -i -O the_script.py --args -... -> from analyze_dxp import * -> s = render_common_pairs() -> open('/tmp/some_file', 'w').write(s) -""" - -import copy -import opcode -import operator -import sys -import threading - -if not hasattr(sys, "getdxp"): - raise RuntimeError("Can't import analyze_dxp: Python built without" - " -DDYNAMIC_EXECUTION_PROFILE.") - - -_profile_lock = threading.RLock() -_cumulative_profile = sys.getdxp() - -# If Python was built with -DDXPAIRS, sys.getdxp() returns a list of -# lists of ints. Otherwise it returns just a list of ints. -def has_pairs(profile): - """Returns True if the Python that produced the argument profile - was built with -DDXPAIRS.""" - - return len(profile) > 0 and isinstance(profile[0], list) - - -def reset_profile(): - """Forgets any execution profile that has been gathered so far.""" - with _profile_lock: - sys.getdxp() # Resets the internal profile - global _cumulative_profile - _cumulative_profile = sys.getdxp() # 0s out our copy. - - -def merge_profile(): - """Reads sys.getdxp() and merges it into this module's cached copy. - - We need this because sys.getdxp() 0s itself every time it's called.""" - - with _profile_lock: - new_profile = sys.getdxp() - if has_pairs(new_profile): - for first_inst in range(len(_cumulative_profile)): - for second_inst in range(len(_cumulative_profile[first_inst])): - _cumulative_profile[first_inst][second_inst] += ( - new_profile[first_inst][second_inst]) - else: - for inst in range(len(_cumulative_profile)): - _cumulative_profile[inst] += new_profile[inst] - - -def snapshot_profile(): - """Returns the cumulative execution profile until this call.""" - with _profile_lock: - merge_profile() - return copy.deepcopy(_cumulative_profile) - - -def common_instructions(profile): - """Returns the most common opcodes in order of descending frequency. - - The result is a list of tuples of the form - (opcode, opname, # of occurrences) - - """ - if has_pairs(profile) and profile: - inst_list = profile[-1] - else: - inst_list = profile - result = [(op, opcode.opname[op], count) - for op, count in enumerate(inst_list) - if count > 0] - result.sort(key=operator.itemgetter(2), reverse=True) - return result - - -def common_pairs(profile): - """Returns the most common opcode pairs in order of descending frequency. - - The result is a list of tuples of the form - ((1st opcode, 2nd opcode), - (1st opname, 2nd opname), - # of occurrences of the pair) - - """ - if not has_pairs(profile): - return [] - result = [((op1, op2), (opcode.opname[op1], opcode.opname[op2]), count) - # Drop the row of single-op profiles with [:-1] - for op1, op1profile in enumerate(profile[:-1]) - for op2, count in enumerate(op1profile) - if count > 0] - result.sort(key=operator.itemgetter(2), reverse=True) - return result - - -def render_common_pairs(profile=None): - """Renders the most common opcode pairs to a string in order of - descending frequency. - - The result is a series of lines of the form: - # of occurrences: ('1st opname', '2nd opname') - - """ - if profile is None: - profile = snapshot_profile() - def seq(): - for _, ops, count in common_pairs(profile): - yield "%s: %s\n" % (count, ops) - return ''.join(seq()) diff --git a/Tools/scripts/byext.py b/Tools/scripts/byext.py deleted file mode 100755 index a4b2f7ff..00000000 --- a/Tools/scripts/byext.py +++ /dev/null @@ -1,132 +0,0 @@ -#! /usr/bin/env python3 - -"""Show file statistics by extension.""" - -import os -import sys - - -class Stats: - - def __init__(self): - self.stats = {} - - def statargs(self, args): - for arg in args: - if os.path.isdir(arg): - self.statdir(arg) - elif os.path.isfile(arg): - self.statfile(arg) - else: - sys.stderr.write("Can't find %s\n" % arg) - self.addstats("<???>", "unknown", 1) - - def statdir(self, dir): - self.addstats("<dir>", "dirs", 1) - try: - names = os.listdir(dir) - except OSError as err: - sys.stderr.write("Can't list %s: %s\n" % (dir, err)) - self.addstats("<dir>", "unlistable", 1) - return - for name in sorted(names): - if name.startswith(".#"): - continue # Skip CVS temp files - if name.endswith("~"): - continue # Skip Emacs backup files - full = os.path.join(dir, name) - if os.path.islink(full): - self.addstats("<lnk>", "links", 1) - elif os.path.isdir(full): - self.statdir(full) - else: - self.statfile(full) - - def statfile(self, filename): - head, ext = os.path.splitext(filename) - head, base = os.path.split(filename) - if ext == base: - ext = "" # E.g. .cvsignore is deemed not to have an extension - ext = os.path.normcase(ext) - if not ext: - ext = "<none>" - self.addstats(ext, "files", 1) - try: - with open(filename, "rb") as f: - data = f.read() - except IOError as err: - sys.stderr.write("Can't open %s: %s\n" % (filename, err)) - self.addstats(ext, "unopenable", 1) - return - self.addstats(ext, "bytes", len(data)) - if b'\0' in data: - self.addstats(ext, "binary", 1) - return - if not data: - self.addstats(ext, "empty", 1) - # self.addstats(ext, "chars", len(data)) - lines = str(data, "latin-1").splitlines() - self.addstats(ext, "lines", len(lines)) - del lines - words = data.split() - self.addstats(ext, "words", len(words)) - - def addstats(self, ext, key, n): - d = self.stats.setdefault(ext, {}) - d[key] = d.get(key, 0) + n - - def report(self): - exts = sorted(self.stats) - # Get the column keys - columns = {} - for ext in exts: - columns.update(self.stats[ext]) - cols = sorted(columns) - colwidth = {} - colwidth["ext"] = max(map(len, exts)) - minwidth = 6 - self.stats["TOTAL"] = {} - for col in cols: - total = 0 - cw = max(minwidth, len(col)) - for ext in exts: - value = self.stats[ext].get(col) - if value is None: - w = 0 - else: - w = len("%d" % value) - total += value - cw = max(cw, w) - cw = max(cw, len(str(total))) - colwidth[col] = cw - self.stats["TOTAL"][col] = total - exts.append("TOTAL") - for ext in exts: - self.stats[ext]["ext"] = ext - cols.insert(0, "ext") - - def printheader(): - for col in cols: - print("%*s" % (colwidth[col], col), end=' ') - print() - - printheader() - for ext in exts: - for col in cols: - value = self.stats[ext].get(col, "") - print("%*s" % (colwidth[col], value), end=' ') - print() - printheader() # Another header at the bottom - - -def main(): - args = sys.argv[1:] - if not args: - args = [os.curdir] - s = Stats() - s.statargs(args) - s.report() - - -if __name__ == "__main__": - main() diff --git a/Tools/scripts/byteyears.py b/Tools/scripts/byteyears.py deleted file mode 100755 index f58c3460..00000000 --- a/Tools/scripts/byteyears.py +++ /dev/null @@ -1,61 +0,0 @@ -#! /usr/bin/env python3 - -# Print the product of age and size of each file, in suitable units. -# -# Usage: byteyears [ -a | -m | -c ] file ... -# -# Options -[amc] select atime, mtime (default) or ctime as age. - -import sys, os, time -from stat import * - -def main(): - - # Use lstat() to stat files if it exists, else stat() - try: - statfunc = os.lstat - except AttributeError: - statfunc = os.stat - - # Parse options - if sys.argv[1] == '-m': - itime = ST_MTIME - del sys.argv[1] - elif sys.argv[1] == '-c': - itime = ST_CTIME - del sys.argv[1] - elif sys.argv[1] == '-a': - itime = ST_CTIME - del sys.argv[1] - else: - itime = ST_MTIME - - secs_per_year = 365.0 * 24.0 * 3600.0 # Scale factor - now = time.time() # Current time, for age computations - status = 0 # Exit status, set to 1 on errors - - # Compute max file name length - maxlen = 1 - for filename in sys.argv[1:]: - maxlen = max(maxlen, len(filename)) - - # Process each argument in turn - for filename in sys.argv[1:]: - try: - st = statfunc(filename) - except OSError as msg: - sys.stderr.write("can't stat %r: %r\n" % (filename, msg)) - status = 1 - st = () - if st: - anytime = st[itime] - size = st[ST_SIZE] - age = now - anytime - byteyears = float(size) * float(age) / secs_per_year - print(filename.ljust(maxlen), end=' ') - print(repr(int(byteyears)).rjust(8)) - - sys.exit(status) - -if __name__ == '__main__': - main() diff --git a/Tools/scripts/cleanfuture.py b/Tools/scripts/cleanfuture.py deleted file mode 100755 index 94f69126..00000000 --- a/Tools/scripts/cleanfuture.py +++ /dev/null @@ -1,275 +0,0 @@ -#! /usr/bin/env python3 - -"""cleanfuture [-d][-r][-v] path ... - --d Dry run. Analyze, but don't make any changes to, files. --r Recurse. Search for all .py files in subdirectories too. --v Verbose. Print informative msgs. - -Search Python (.py) files for future statements, and remove the features -from such statements that are already mandatory in the version of Python -you're using. - -Pass one or more file and/or directory paths. When a directory path, all -.py files within the directory will be examined, and, if the -r option is -given, likewise recursively for subdirectories. - -Overwrites files in place, renaming the originals with a .bak extension. If -cleanfuture finds nothing to change, the file is left alone. If cleanfuture -does change a file, the changed file is a fixed-point (i.e., running -cleanfuture on the resulting .py file won't change it again, at least not -until you try it again with a later Python release). - -Limitations: You can do these things, but this tool won't help you then: - -+ A future statement cannot be mixed with any other statement on the same - physical line (separated by semicolon). - -+ A future statement cannot contain an "as" clause. - -Example: Assuming you're using Python 2.2, if a file containing - -from __future__ import nested_scopes, generators - -is analyzed by cleanfuture, the line is rewritten to - -from __future__ import generators - -because nested_scopes is no longer optional in 2.2 but generators is. -""" - -import __future__ -import tokenize -import os -import sys - -dryrun = 0 -recurse = 0 -verbose = 0 - -def errprint(*args): - strings = map(str, args) - msg = ' '.join(strings) - if msg[-1:] != '\n': - msg += '\n' - sys.stderr.write(msg) - -def main(): - import getopt - global verbose, recurse, dryrun - try: - opts, args = getopt.getopt(sys.argv[1:], "drv") - except getopt.error as msg: - errprint(msg) - return - for o, a in opts: - if o == '-d': - dryrun += 1 - elif o == '-r': - recurse += 1 - elif o == '-v': - verbose += 1 - if not args: - errprint("Usage:", __doc__) - return - for arg in args: - check(arg) - -def check(file): - if os.path.isdir(file) and not os.path.islink(file): - if verbose: - print("listing directory", file) - names = os.listdir(file) - for name in names: - fullname = os.path.join(file, name) - if ((recurse and os.path.isdir(fullname) and - not os.path.islink(fullname)) - or name.lower().endswith(".py")): - check(fullname) - return - - if verbose: - print("checking", file, "...", end=' ') - try: - f = open(file) - except IOError as msg: - errprint("%r: I/O Error: %s" % (file, str(msg))) - return - - with f: - ff = FutureFinder(f, file) - changed = ff.run() - if changed: - ff.gettherest() - if changed: - if verbose: - print("changed.") - if dryrun: - print("But this is a dry run, so leaving it alone.") - for s, e, line in changed: - print("%r lines %d-%d" % (file, s+1, e+1)) - for i in range(s, e+1): - print(ff.lines[i], end=' ') - if line is None: - print("-- deleted") - else: - print("-- change to:") - print(line, end=' ') - if not dryrun: - bak = file + ".bak" - if os.path.exists(bak): - os.remove(bak) - os.rename(file, bak) - if verbose: - print("renamed", file, "to", bak) - with open(file, "w") as g: - ff.write(g) - if verbose: - print("wrote new", file) - else: - if verbose: - print("unchanged.") - -class FutureFinder: - - def __init__(self, f, fname): - self.f = f - self.fname = fname - self.ateof = 0 - self.lines = [] # raw file lines - - # List of (start_index, end_index, new_line) triples. - self.changed = [] - - # Line-getter for tokenize. - def getline(self): - if self.ateof: - return "" - line = self.f.readline() - if line == "": - self.ateof = 1 - else: - self.lines.append(line) - return line - - def run(self): - STRING = tokenize.STRING - NL = tokenize.NL - NEWLINE = tokenize.NEWLINE - COMMENT = tokenize.COMMENT - NAME = tokenize.NAME - OP = tokenize.OP - - changed = self.changed - get = tokenize.generate_tokens(self.getline).__next__ - type, token, (srow, scol), (erow, ecol), line = get() - - # Chew up initial comments and blank lines (if any). - while type in (COMMENT, NL, NEWLINE): - type, token, (srow, scol), (erow, ecol), line = get() - - # Chew up docstring (if any -- and it may be implicitly catenated!). - while type is STRING: - type, token, (srow, scol), (erow, ecol), line = get() - - # Analyze the future stmts. - while 1: - # Chew up comments and blank lines (if any). - while type in (COMMENT, NL, NEWLINE): - type, token, (srow, scol), (erow, ecol), line = get() - - if not (type is NAME and token == "from"): - break - startline = srow - 1 # tokenize is one-based - type, token, (srow, scol), (erow, ecol), line = get() - - if not (type is NAME and token == "__future__"): - break - type, token, (srow, scol), (erow, ecol), line = get() - - if not (type is NAME and token == "import"): - break - type, token, (srow, scol), (erow, ecol), line = get() - - # Get the list of features. - features = [] - while type is NAME: - features.append(token) - type, token, (srow, scol), (erow, ecol), line = get() - - if not (type is OP and token == ','): - break - type, token, (srow, scol), (erow, ecol), line = get() - - # A trailing comment? - comment = None - if type is COMMENT: - comment = token - type, token, (srow, scol), (erow, ecol), line = get() - - if type is not NEWLINE: - errprint("Skipping file %r; can't parse line %d:\n%s" % - (self.fname, srow, line)) - return [] - - endline = srow - 1 - - # Check for obsolete features. - okfeatures = [] - for f in features: - object = getattr(__future__, f, None) - if object is None: - # A feature we don't know about yet -- leave it in. - # They'll get a compile-time error when they compile - # this program, but that's not our job to sort out. - okfeatures.append(f) - else: - released = object.getMandatoryRelease() - if released is None or released <= sys.version_info: - # Withdrawn or obsolete. - pass - else: - okfeatures.append(f) - - # Rewrite the line if at least one future-feature is obsolete. - if len(okfeatures) < len(features): - if len(okfeatures) == 0: - line = None - else: - line = "from __future__ import " - line += ', '.join(okfeatures) - if comment is not None: - line += ' ' + comment - line += '\n' - changed.append((startline, endline, line)) - - # Loop back for more future statements. - - return changed - - def gettherest(self): - if self.ateof: - self.therest = '' - else: - self.therest = self.f.read() - - def write(self, f): - changed = self.changed - assert changed - # Prevent calling this again. - self.changed = [] - # Apply changes in reverse order. - changed.reverse() - for s, e, line in changed: - if line is None: - # pure deletion - del self.lines[s:e+1] - else: - self.lines[s:e+1] = [line] - f.writelines(self.lines) - # Copy over the remainder of the file. - if self.therest: - f.write(self.therest) - -if __name__ == '__main__': - main() diff --git a/Tools/scripts/copytime.py b/Tools/scripts/copytime.py deleted file mode 100755 index 715683f1..00000000 --- a/Tools/scripts/copytime.py +++ /dev/null @@ -1,26 +0,0 @@ -#! /usr/bin/env python3 - -# Copy one file's atime and mtime to another - -import sys -import os -from stat import ST_ATIME, ST_MTIME # Really constants 7 and 8 - -def main(): - if len(sys.argv) != 3: - sys.stderr.write('usage: copytime source destination\n') - sys.exit(2) - file1, file2 = sys.argv[1], sys.argv[2] - try: - stat1 = os.stat(file1) - except OSError: - sys.stderr.write(file1 + ': cannot stat\n') - sys.exit(1) - try: - os.utime(file2, (stat1[ST_ATIME], stat1[ST_MTIME])) - except OSError: - sys.stderr.write(file2 + ': cannot change time\n') - sys.exit(2) - -if __name__ == '__main__': - main() diff --git a/Tools/scripts/crlf.py b/Tools/scripts/crlf.py deleted file mode 100755 index f231d292..00000000 --- a/Tools/scripts/crlf.py +++ /dev/null @@ -1,23 +0,0 @@ -#! /usr/bin/env python3 -"Replace CRLF with LF in argument files. Print names of changed files." - -import sys, os - -def main(): - for filename in sys.argv[1:]: - if os.path.isdir(filename): - print(filename, "Directory!") - continue - with open(filename, "rb") as f: - data = f.read() - if b'\0' in data: - print(filename, "Binary!") - continue - newdata = data.replace(b"\r\n", b"\n") - if newdata != data: - print(filename) - with open(filename, "wb") as f: - f.write(newdata) - -if __name__ == '__main__': - main() diff --git a/Tools/scripts/db2pickle.py b/Tools/scripts/db2pickle.py deleted file mode 100755 index a5532a8f..00000000 --- a/Tools/scripts/db2pickle.py +++ /dev/null @@ -1,135 +0,0 @@ -#!/usr/bin/env python3 - -""" -Synopsis: %(prog)s [-h|-g|-b|-r|-a] dbfile [ picklefile ] - -Convert the database file given on the command line to a pickle -representation. The optional flags indicate the type of the database: - - -a - open using dbm (any supported format) - -b - open as bsddb btree file - -d - open as dbm file - -g - open as gdbm file - -h - open as bsddb hash file - -r - open as bsddb recno file - -The default is hash. If a pickle file is named it is opened for write -access (deleting any existing data). If no pickle file is named, the pickle -output is written to standard output. - -""" - -import getopt -try: - import bsddb -except ImportError: - bsddb = None -try: - import dbm.ndbm as dbm -except ImportError: - dbm = None -try: - import dbm.gnu as gdbm -except ImportError: - gdbm = None -try: - import dbm.ndbm as anydbm -except ImportError: - anydbm = None -import sys -try: - import pickle as pickle -except ImportError: - import pickle - -prog = sys.argv[0] - -def usage(): - sys.stderr.write(__doc__ % globals()) - -def main(args): - try: - opts, args = getopt.getopt(args, "hbrdag", - ["hash", "btree", "recno", "dbm", - "gdbm", "anydbm"]) - except getopt.error: - usage() - return 1 - - if len(args) == 0 or len(args) > 2: - usage() - return 1 - elif len(args) == 1: - dbfile = args[0] - pfile = sys.stdout - else: - dbfile = args[0] - try: - pfile = open(args[1], 'wb') - except IOError: - sys.stderr.write("Unable to open %s\n" % args[1]) - return 1 - - dbopen = None - for opt, arg in opts: - if opt in ("-h", "--hash"): - try: - dbopen = bsddb.hashopen - except AttributeError: - sys.stderr.write("bsddb module unavailable.\n") - return 1 - elif opt in ("-b", "--btree"): - try: - dbopen = bsddb.btopen - except AttributeError: - sys.stderr.write("bsddb module unavailable.\n") - return 1 - elif opt in ("-r", "--recno"): - try: - dbopen = bsddb.rnopen - except AttributeError: - sys.stderr.write("bsddb module unavailable.\n") - return 1 - elif opt in ("-a", "--anydbm"): - try: - dbopen = anydbm.open - except AttributeError: - sys.stderr.write("dbm module unavailable.\n") - return 1 - elif opt in ("-g", "--gdbm"): - try: - dbopen = gdbm.open - except AttributeError: - sys.stderr.write("dbm.gnu module unavailable.\n") - return 1 - elif opt in ("-d", "--dbm"): - try: - dbopen = dbm.open - except AttributeError: - sys.stderr.write("dbm.ndbm module unavailable.\n") - return 1 - if dbopen is None: - if bsddb is None: - sys.stderr.write("bsddb module unavailable - ") - sys.stderr.write("must specify dbtype.\n") - return 1 - else: - dbopen = bsddb.hashopen - - try: - db = dbopen(dbfile, 'r') - except bsddb.error: - sys.stderr.write("Unable to open %s. " % dbfile) - sys.stderr.write("Check for format or version mismatch.\n") - return 1 - - for k in db.keys(): - pickle.dump((k, db[k]), pfile, 1==1) - - db.close() - pfile.close() - - return 0 - -if __name__ == "__main__": - sys.exit(main(sys.argv[1:])) diff --git a/Tools/scripts/divmod_threshold.py b/Tools/scripts/divmod_threshold.py new file mode 100644 index 00000000..69819fe3 --- /dev/null +++ b/Tools/scripts/divmod_threshold.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python3 +# +# Determine threshold for switching from longobject.c divmod to +# _pylong.int_divmod(). + +from random import randrange +from time import perf_counter as now +from _pylong import int_divmod as divmod_fast + +BITS_PER_DIGIT = 30 + + +def rand_digits(n): + top = 1 << (n * BITS_PER_DIGIT) + return randrange(top >> 1, top) + + +def probe_den(nd): + den = rand_digits(nd) + count = 0 + for nn in range(nd, nd + 3000): + num = rand_digits(nn) + t0 = now() + e1, e2 = divmod(num, den) + t1 = now() + f1, f2 = divmod_fast(num, den) + t2 = now() + s1 = t1 - t0 + s2 = t2 - t1 + assert e1 == f1 + assert e2 == f2 + if s2 < s1: + count += 1 + if count >= 3: + print( + "for", + nd, + "denom digits,", + nn - nd, + "extra num digits is enough", + ) + break + else: + count = 0 + else: + print("for", nd, "denom digits, no num seems big enough") + + +def main(): + for nd in range(30): + nd = (nd + 1) * 100 + probe_den(nd) + + +if __name__ == '__main__': + main() diff --git a/Tools/scripts/dutree.doc b/Tools/scripts/dutree.doc deleted file mode 100644 index 490126b0..00000000 --- a/Tools/scripts/dutree.doc +++ /dev/null @@ -1,54 +0,0 @@ -Path: cwi.nl!sun4nl!mcsun!uunet!cs.utexas.edu!convex!usenet -From: tchrist@convex.COM (Tom Christiansen) -Newsgroups: comp.lang.perl -Subject: Re: The problems of Perl (Re: Question (silly?)) -Message-ID: <1992Jan17.053115.4220@convex.com> -Date: 17 Jan 92 05:31:15 GMT -References: <17458@ector.cs.purdue.edu> <1992Jan16.165347.25583@cherokee.uswest.com> <=#Hues+4@cs.psu.edu> -Sender: usenet@convex.com (news access account) -Reply-To: tchrist@convex.COM (Tom Christiansen) -Organization: CONVEX Realtime Development, Colorado Springs, CO -Lines: 83 -Nntp-Posting-Host: pixel.convex.com - -From the keyboard of flee@cs.psu.edu (Felix Lee): -:And Perl is definitely awkward with data types. I haven't yet found a -:pleasant way of shoving non-trivial data types into Perl's grammar. - -Yes, it's pretty awful at that, alright. Sometimes I write perl programs -that need them, and sometimes it just takes a little creativity. But -sometimes it's not worth it. I actually wrote a C program the other day -(gasp) because I didn't want to deal with a game matrix with six links per node. - -:Here's a very simple problem that's tricky to express in Perl: process -:the output of "du" to produce output that's indented to reflect the -:tree structure, and with each subtree sorted by size. Something like: -: 434 /etc -: | 344 . -: | 50 install -: | 35 uucp -: | 3 nserve -: | | 2 . -: | | 1 auth.info -: | 1 sm -: | 1 sm.bak - -At first I thought I could just keep one local list around -at once, but this seems inherently recursive. Which means -I need an real recursive data structure. Maybe you could -do it with one of the %assoc arrays Larry uses in the begat -programs, but I broke down and got dirty. I think the hardest -part was matching Felix's desired output exactly. It's not -blazingly fast: I should probably inline the &childof routine, -but it *was* faster to write than I could have written the -equivalent C program. - - ---tom - --- -"GUIs normally make it simple to accomplish simple actions and impossible -to accomplish complex actions." --Doug Gwyn (22/Jun/91 in comp.unix.wizards) - - Tom Christiansen tchrist@convex.com convex!tchrist - diff --git a/Tools/scripts/dutree.py b/Tools/scripts/dutree.py deleted file mode 100755 index d25cf72b..00000000 --- a/Tools/scripts/dutree.py +++ /dev/null @@ -1,60 +0,0 @@ -#! /usr/bin/env python3 -# Format du output in a tree shape - -import os, sys, errno - -def main(): - total, d = None, {} - with os.popen('du ' + ' '.join(sys.argv[1:])) as p: - for line in p: - i = 0 - while line[i] in '0123456789': i = i+1 - size = eval(line[:i]) - while line[i] in ' \t': i = i+1 - filename = line[i:-1] - comps = filename.split('/') - if comps[0] == '': comps[0] = '/' - if comps[len(comps)-1] == '': del comps[len(comps)-1] - total, d = store(size, comps, total, d) - try: - display(total, d) - except IOError as e: - if e.errno != errno.EPIPE: - raise - -def store(size, comps, total, d): - if comps == []: - return size, d - if comps[0] not in d: - d[comps[0]] = None, {} - t1, d1 = d[comps[0]] - d[comps[0]] = store(size, comps[1:], t1, d1) - return total, d - -def display(total, d): - show(total, d, '') - -def show(total, d, prefix): - if not d: return - list = [] - sum = 0 - for key in d.keys(): - tsub, dsub = d[key] - list.append((tsub, key)) - if tsub is not None: sum = sum + tsub -## if sum < total: -## list.append((total - sum, os.curdir)) - list.sort() - list.reverse() - width = len(repr(list[0][0])) - for tsub, key in list: - if tsub is None: - psub = prefix - else: - print(prefix + repr(tsub).rjust(width) + ' ' + key) - psub = prefix + ' '*(width-1) + '|' + ' '*(len(key)+1) - if key in d: - show(tsub, d[key][1], psub) - -if __name__ == '__main__': - main() diff --git a/Tools/scripts/eptags.py b/Tools/scripts/eptags.py deleted file mode 100755 index 7f8059ba..00000000 --- a/Tools/scripts/eptags.py +++ /dev/null @@ -1,57 +0,0 @@ -#! /usr/bin/env python3 -"""Create a TAGS file for Python programs, usable with GNU Emacs. - -usage: eptags pyfiles... - -The output TAGS file is usable with Emacs version 18, 19, 20. -Tagged are: - - functions (even inside other defs or classes) - - classes - -eptags warns about files it cannot open. -eptags will not give warnings about duplicate tags. - -BUGS: - Because of tag duplication (methods with the same name in different - classes), TAGS files are not very useful for most object-oriented - python projects. -""" -import sys,re - -expr = r'^[ \t]*(def|class)[ \t]+([a-zA-Z_][a-zA-Z0-9_]*)[ \t]*[:\(]' -matcher = re.compile(expr) - -def treat_file(filename, outfp): - """Append tags found in file named 'filename' to the open file 'outfp'""" - try: - fp = open(filename, 'r') - except OSError: - sys.stderr.write('Cannot open %s\n'%filename) - return - with fp: - charno = 0 - lineno = 0 - tags = [] - size = 0 - while 1: - line = fp.readline() - if not line: - break - lineno = lineno + 1 - m = matcher.search(line) - if m: - tag = m.group(0) + '\177%d,%d\n' % (lineno, charno) - tags.append(tag) - size = size + len(tag) - charno = charno + len(line) - outfp.write('\f\n%s,%d\n' % (filename,size)) - for tag in tags: - outfp.write(tag) - -def main(): - with open('TAGS', 'w') as outfp: - for filename in sys.argv[1:]: - treat_file(filename, outfp) - -if __name__=="__main__": - main() diff --git a/Tools/scripts/find-uname.py b/Tools/scripts/find-uname.py deleted file mode 100755 index b6ec1b6d..00000000 --- a/Tools/scripts/find-uname.py +++ /dev/null @@ -1,40 +0,0 @@ -#!/usr/bin/env python3 - -""" -For each argument on the command line, look for it in the set of all Unicode -names. Arguments are treated as case-insensitive regular expressions, e.g.: - - % find-uname 'small letter a$' 'horizontal line' - *** small letter a$ matches *** - LATIN SMALL LETTER A (97) - COMBINING LATIN SMALL LETTER A (867) - CYRILLIC SMALL LETTER A (1072) - PARENTHESIZED LATIN SMALL LETTER A (9372) - CIRCLED LATIN SMALL LETTER A (9424) - FULLWIDTH LATIN SMALL LETTER A (65345) - *** horizontal line matches *** - HORIZONTAL LINE EXTENSION (9135) -""" - -import unicodedata -import sys -import re - -def main(args): - unicode_names = [] - for ix in range(sys.maxunicode+1): - try: - unicode_names.append((ix, unicodedata.name(chr(ix)))) - except ValueError: # no name for the character - pass - for arg in args: - pat = re.compile(arg, re.I) - matches = [(y,x) for (x,y) in unicode_names - if pat.search(y) is not None] - if matches: - print("***", arg, "matches", "***") - for match in matches: - print("%s (%d)" % match) - -if __name__ == "__main__": - main(sys.argv[1:]) diff --git a/Tools/scripts/find_recursionlimit.py b/Tools/scripts/find_recursionlimit.py deleted file mode 100755 index b2842a62..00000000 --- a/Tools/scripts/find_recursionlimit.py +++ /dev/null @@ -1,128 +0,0 @@ -#! /usr/bin/env python3 -"""Find the maximum recursion limit that prevents interpreter termination. - -This script finds the maximum safe recursion limit on a particular -platform. If you need to change the recursion limit on your system, -this script will tell you a safe upper bound. To use the new limit, -call sys.setrecursionlimit(). - -This module implements several ways to create infinite recursion in -Python. Different implementations end up pushing different numbers of -C stack frames, depending on how many calls through Python's abstract -C API occur. - -After each round of tests, it prints a message: -"Limit of NNNN is fine". - -The highest printed value of "NNNN" is therefore the highest potentially -safe limit for your system (which depends on the OS, architecture, but also -the compilation flags). Please note that it is practically impossible to -test all possible recursion paths in the interpreter, so the results of -this test should not be trusted blindly -- although they give a good hint -of which values are reasonable. - -NOTE: When the C stack space allocated by your system is exceeded due -to excessive recursion, exact behaviour depends on the platform, although -the interpreter will always fail in a likely brutal way: either a -segmentation fault, a MemoryError, or just a silent abort. - -NB: A program that does not use __methods__ can set a higher limit. -""" - -import sys -import itertools - -class RecursiveBlowup1: - def __init__(self): - self.__init__() - -def test_init(): - return RecursiveBlowup1() - -class RecursiveBlowup2: - def __repr__(self): - return repr(self) - -def test_repr(): - return repr(RecursiveBlowup2()) - -class RecursiveBlowup4: - def __add__(self, x): - return x + self - -def test_add(): - return RecursiveBlowup4() + RecursiveBlowup4() - -class RecursiveBlowup5: - def __getattr__(self, attr): - return getattr(self, attr) - -def test_getattr(): - return RecursiveBlowup5().attr - -class RecursiveBlowup6: - def __getitem__(self, item): - return self[item - 2] + self[item - 1] - -def test_getitem(): - return RecursiveBlowup6()[5] - -def test_recurse(): - return test_recurse() - -def test_cpickle(_cache={}): - import io - try: - import _pickle - except ImportError: - print("cannot import _pickle, skipped!") - return - k, l = None, None - for n in itertools.count(): - try: - l = _cache[n] - continue # Already tried and it works, let's save some time - except KeyError: - for i in range(100): - l = [k, l] - k = {i: l} - _pickle.Pickler(io.BytesIO(), protocol=-1).dump(l) - _cache[n] = l - -def test_compiler_recursion(): - # The compiler uses a scaling factor to support additional levels - # of recursion. This is a sanity check of that scaling to ensure - # it still raises RecursionError even at higher recursion limits - compile("()" * (10 * sys.getrecursionlimit()), "<single>", "single") - -def check_limit(n, test_func_name): - sys.setrecursionlimit(n) - if test_func_name.startswith("test_"): - print(test_func_name[5:]) - else: - print(test_func_name) - test_func = globals()[test_func_name] - try: - test_func() - # AttributeError can be raised because of the way e.g. PyDict_GetItem() - # silences all exceptions and returns NULL, which is usually interpreted - # as "missing attribute". - except (RecursionError, AttributeError): - pass - else: - print("Yikes!") - -if __name__ == '__main__': - - limit = 1000 - while 1: - check_limit(limit, "test_recurse") - check_limit(limit, "test_add") - check_limit(limit, "test_repr") - check_limit(limit, "test_init") - check_limit(limit, "test_getattr") - check_limit(limit, "test_getitem") - check_limit(limit, "test_cpickle") - check_limit(limit, "test_compiler_recursion") - print("Limit of %d is fine" % limit) - limit = limit + 100 diff --git a/Tools/scripts/finddiv.py b/Tools/scripts/finddiv.py deleted file mode 100755 index d21253cf..00000000 --- a/Tools/scripts/finddiv.py +++ /dev/null @@ -1,89 +0,0 @@ -#! /usr/bin/env python3 - -"""finddiv - a grep-like tool that looks for division operators. - -Usage: finddiv [-l] file_or_directory ... - -For directory arguments, all files in the directory whose name ends in -.py are processed, and subdirectories are processed recursively. - -This actually tokenizes the files to avoid false hits in comments or -strings literals. - -By default, this prints all lines containing a / or /= operator, in -grep -n style. With the -l option specified, it prints the filename -of files that contain at least one / or /= operator. -""" - -import os -import sys -import getopt -import tokenize - -def main(): - try: - opts, args = getopt.getopt(sys.argv[1:], "lh") - except getopt.error as msg: - usage(msg) - return 2 - if not args: - usage("at least one file argument is required") - return 2 - listnames = 0 - for o, a in opts: - if o == "-h": - print(__doc__) - return - if o == "-l": - listnames = 1 - exit = None - for filename in args: - x = process(filename, listnames) - exit = exit or x - return exit - -def usage(msg): - sys.stderr.write("%s: %s\n" % (sys.argv[0], msg)) - sys.stderr.write("Usage: %s [-l] file ...\n" % sys.argv[0]) - sys.stderr.write("Try `%s -h' for more information.\n" % sys.argv[0]) - -def process(filename, listnames): - if os.path.isdir(filename): - return processdir(filename, listnames) - try: - fp = open(filename) - except IOError as msg: - sys.stderr.write("Can't open: %s\n" % msg) - return 1 - with fp: - g = tokenize.generate_tokens(fp.readline) - lastrow = None - for type, token, (row, col), end, line in g: - if token in ("/", "/="): - if listnames: - print(filename) - break - if row != lastrow: - lastrow = row - print("%s:%d:%s" % (filename, row, line), end=' ') - -def processdir(dir, listnames): - try: - names = os.listdir(dir) - except OSError as msg: - sys.stderr.write("Can't list directory: %s\n" % dir) - return 1 - files = [] - for name in names: - fn = os.path.join(dir, name) - if os.path.normcase(fn).endswith(".py") or os.path.isdir(fn): - files.append(fn) - files.sort(key=os.path.normcase) - exit = None - for fn in files: - x = process(fn, listnames) - exit = exit or x - return exit - -if __name__ == "__main__": - sys.exit(main()) diff --git a/Tools/scripts/findlinksto.py b/Tools/scripts/findlinksto.py deleted file mode 100755 index b924f27b..00000000 --- a/Tools/scripts/findlinksto.py +++ /dev/null @@ -1,43 +0,0 @@ -#! /usr/bin/env python3 - -# findlinksto -# -# find symbolic links to a path matching a regular expression - -import os -import sys -import re -import getopt - -def main(): - try: - opts, args = getopt.getopt(sys.argv[1:], '') - if len(args) < 2: - raise getopt.GetoptError('not enough arguments', None) - except getopt.GetoptError as msg: - sys.stdout = sys.stderr - print(msg) - print('usage: findlinksto pattern directory ...') - sys.exit(2) - pat, dirs = args[0], args[1:] - prog = re.compile(pat) - for dirname in dirs: - os.walk(dirname, visit, prog) - -def visit(prog, dirname, names): - if os.path.islink(dirname): - names[:] = [] - return - if os.path.ismount(dirname): - print('descend into', dirname) - for name in names: - name = os.path.join(dirname, name) - try: - linkto = os.readlink(name) - if prog.search(linkto) is not None: - print(name, '->', linkto) - except OSError: - pass - -if __name__ == '__main__': - main() diff --git a/Tools/scripts/findnocoding.py b/Tools/scripts/findnocoding.py deleted file mode 100755 index 6c16b1ce..00000000 --- a/Tools/scripts/findnocoding.py +++ /dev/null @@ -1,107 +0,0 @@ -#!/usr/bin/env python3 - -"""List all those Python files that require a coding directive - -Usage: findnocoding.py dir1 [dir2...] -""" - -__author__ = "Oleg Broytmann, Georg Brandl" - -import sys, os, re, getopt - -# our pysource module finds Python source files -try: - import pysource -except ImportError: - # emulate the module with a simple os.walk - class pysource: - has_python_ext = looks_like_python = can_be_compiled = None - def walk_python_files(self, paths, *args, **kwargs): - for path in paths: - if os.path.isfile(path): - yield path.endswith(".py") - elif os.path.isdir(path): - for root, dirs, files in os.walk(path): - for filename in files: - if filename.endswith(".py"): - yield os.path.join(root, filename) - pysource = pysource() - - - print("The pysource module is not available; " - "no sophisticated Python source file search will be done.", file=sys.stderr) - - -decl_re = re.compile(rb'^[ \t\f]*#.*?coding[:=][ \t]*([-\w.]+)') -blank_re = re.compile(rb'^[ \t\f]*(?:[#\r\n]|$)') - -def get_declaration(line): - match = decl_re.match(line) - if match: - return match.group(1) - return b'' - -def has_correct_encoding(text, codec): - try: - str(text, codec) - except UnicodeDecodeError: - return False - else: - return True - -def needs_declaration(fullpath): - try: - infile = open(fullpath, 'rb') - except IOError: # Oops, the file was removed - ignore it - return None - - with infile: - line1 = infile.readline() - line2 = infile.readline() - - if (get_declaration(line1) or - blank_re.match(line1) and get_declaration(line2)): - # the file does have an encoding declaration, so trust it - return False - - # check the whole file for non utf-8 characters - rest = infile.read() - - if has_correct_encoding(line1+line2+rest, "utf-8"): - return False - - return True - - -usage = """Usage: %s [-cd] paths... - -c: recognize Python source files trying to compile them - -d: debug output""" % sys.argv[0] - -if __name__ == '__main__': - - try: - opts, args = getopt.getopt(sys.argv[1:], 'cd') - except getopt.error as msg: - print(msg, file=sys.stderr) - print(usage, file=sys.stderr) - sys.exit(1) - - is_python = pysource.looks_like_python - debug = False - - for o, a in opts: - if o == '-c': - is_python = pysource.can_be_compiled - elif o == '-d': - debug = True - - if not args: - print(usage, file=sys.stderr) - sys.exit(1) - - for fullpath in pysource.walk_python_files(args, is_python): - if debug: - print("Testing for coding: %s" % fullpath) - result = needs_declaration(fullpath) - if result: - print(fullpath) diff --git a/Tools/scripts/fixcid.py b/Tools/scripts/fixcid.py deleted file mode 100755 index 8f35eaee..00000000 --- a/Tools/scripts/fixcid.py +++ /dev/null @@ -1,316 +0,0 @@ -#! /usr/bin/env python3 - -# Perform massive identifier substitution on C source files. -# This actually tokenizes the files (to some extent) so it can -# avoid making substitutions inside strings or comments. -# Inside strings, substitutions are never made; inside comments, -# it is a user option (off by default). -# -# The substitutions are read from one or more files whose lines, -# when not empty, after stripping comments starting with #, -# must contain exactly two words separated by whitespace: the -# old identifier and its replacement. -# -# The option -r reverses the sense of the substitutions (this may be -# useful to undo a particular substitution). -# -# If the old identifier is prefixed with a '*' (with no intervening -# whitespace), then it will not be substituted inside comments. -# -# Command line arguments are files or directories to be processed. -# Directories are searched recursively for files whose name looks -# like a C file (ends in .h or .c). The special filename '-' means -# operate in filter mode: read stdin, write stdout. -# -# Symbolic links are always ignored (except as explicit directory -# arguments). -# -# The original files are kept as back-up with a "~" suffix. -# -# Changes made are reported to stdout in a diff-like format. -# -# NB: by changing only the function fixline() you can turn this -# into a program for different changes to C source files; by -# changing the function wanted() you can make a different selection of -# files. - -import sys -import re -import os -from stat import * -import getopt - -err = sys.stderr.write -dbg = err -rep = sys.stdout.write - -def usage(): - progname = sys.argv[0] - err('Usage: ' + progname + - ' [-c] [-r] [-s file] ... file-or-directory ...\n') - err('\n') - err('-c : substitute inside comments\n') - err('-r : reverse direction for following -s options\n') - err('-s substfile : add a file of substitutions\n') - err('\n') - err('Each non-empty non-comment line in a substitution file must\n') - err('contain exactly two words: an identifier and its replacement.\n') - err('Comments start with a # character and end at end of line.\n') - err('If an identifier is preceded with a *, it is not substituted\n') - err('inside a comment even when -c is specified.\n') - -def main(): - try: - opts, args = getopt.getopt(sys.argv[1:], 'crs:') - except getopt.error as msg: - err('Options error: ' + str(msg) + '\n') - usage() - sys.exit(2) - bad = 0 - if not args: # No arguments - usage() - sys.exit(2) - for opt, arg in opts: - if opt == '-c': - setdocomments() - if opt == '-r': - setreverse() - if opt == '-s': - addsubst(arg) - for arg in args: - if os.path.isdir(arg): - if recursedown(arg): bad = 1 - elif os.path.islink(arg): - err(arg + ': will not process symbolic links\n') - bad = 1 - else: - if fix(arg): bad = 1 - sys.exit(bad) - -# Change this regular expression to select a different set of files -Wanted = r'^[a-zA-Z0-9_]+\.[ch]$' -def wanted(name): - return re.match(Wanted, name) - -def recursedown(dirname): - dbg('recursedown(%r)\n' % (dirname,)) - bad = 0 - try: - names = os.listdir(dirname) - except OSError as msg: - err(dirname + ': cannot list directory: ' + str(msg) + '\n') - return 1 - names.sort() - subdirs = [] - for name in names: - if name in (os.curdir, os.pardir): continue - fullname = os.path.join(dirname, name) - if os.path.islink(fullname): pass - elif os.path.isdir(fullname): - subdirs.append(fullname) - elif wanted(name): - if fix(fullname): bad = 1 - for fullname in subdirs: - if recursedown(fullname): bad = 1 - return bad - -def fix(filename): -## dbg('fix(%r)\n' % (filename,)) - if filename == '-': - # Filter mode - f = sys.stdin - g = sys.stdout - else: - # File replacement mode - try: - f = open(filename, 'r') - except IOError as msg: - err(filename + ': cannot open: ' + str(msg) + '\n') - return 1 - head, tail = os.path.split(filename) - tempname = os.path.join(head, '@' + tail) - g = None - # If we find a match, we rewind the file and start over but - # now copy everything to a temp file. - lineno = 0 - initfixline() - while 1: - line = f.readline() - if not line: break - lineno = lineno + 1 - while line[-2:] == '\\\n': - nextline = f.readline() - if not nextline: break - line = line + nextline - lineno = lineno + 1 - newline = fixline(line) - if newline != line: - if g is None: - try: - g = open(tempname, 'w') - except IOError as msg: - f.close() - err(tempname+': cannot create: '+ - str(msg)+'\n') - return 1 - f.seek(0) - lineno = 0 - initfixline() - rep(filename + ':\n') - continue # restart from the beginning - rep(repr(lineno) + '\n') - rep('< ' + line) - rep('> ' + newline) - if g is not None: - g.write(newline) - - # End of file - if filename == '-': return 0 # Done in filter mode - f.close() - if not g: return 0 # No changes - g.close() - - # Finishing touch -- move files - - # First copy the file's mode to the temp file - try: - statbuf = os.stat(filename) - os.chmod(tempname, statbuf[ST_MODE] & 0o7777) - except OSError as msg: - err(tempname + ': warning: chmod failed (' + str(msg) + ')\n') - # Then make a backup of the original file as filename~ - try: - os.rename(filename, filename + '~') - except OSError as msg: - err(filename + ': warning: backup failed (' + str(msg) + ')\n') - # Now move the temp file to the original file - try: - os.rename(tempname, filename) - except OSError as msg: - err(filename + ': rename failed (' + str(msg) + ')\n') - return 1 - # Return success - return 0 - -# Tokenizing ANSI C (partly) - -Identifier = '(struct )?[a-zA-Z_][a-zA-Z0-9_]+' -String = r'"([^\n\\"]|\\.)*"' -Char = r"'([^\n\\']|\\.)*'" -CommentStart = r'/\*' -CommentEnd = r'\*/' - -Hexnumber = '0[xX][0-9a-fA-F]*[uUlL]*' -Octnumber = '0[0-7]*[uUlL]*' -Decnumber = '[1-9][0-9]*[uUlL]*' -Intnumber = Hexnumber + '|' + Octnumber + '|' + Decnumber -Exponent = '[eE][-+]?[0-9]+' -Pointfloat = r'([0-9]+\.[0-9]*|\.[0-9]+)(' + Exponent + r')?' -Expfloat = '[0-9]+' + Exponent -Floatnumber = Pointfloat + '|' + Expfloat -Number = Floatnumber + '|' + Intnumber - -# Anything else is an operator -- don't list this explicitly because of '/*' - -OutsideComment = (Identifier, Number, String, Char, CommentStart) -OutsideCommentPattern = '(' + '|'.join(OutsideComment) + ')' -OutsideCommentProgram = re.compile(OutsideCommentPattern) - -InsideComment = (Identifier, Number, CommentEnd) -InsideCommentPattern = '(' + '|'.join(InsideComment) + ')' -InsideCommentProgram = re.compile(InsideCommentPattern) - -def initfixline(): - global Program - Program = OutsideCommentProgram - -def fixline(line): - global Program -## print('-->', repr(line)) - i = 0 - while i < len(line): - match = Program.search(line, i) - if match is None: break - i = match.start() - found = match.group(0) -## if Program is InsideCommentProgram: print(end='... ') -## else: print(end=' ') -## print(found) - if len(found) == 2: - if found == '/*': - Program = InsideCommentProgram - elif found == '*/': - Program = OutsideCommentProgram - n = len(found) - if found in Dict: - subst = Dict[found] - if Program is InsideCommentProgram: - if not Docomments: - print('Found in comment:', found) - i = i + n - continue - if found in NotInComment: -## print(end='Ignored in comment: ') -## print(found, '-->', subst) -## print('Line:', line, end='') - subst = found -## else: -## print(end='Substituting in comment: ') -## print(found, '-->', subst) -## print('Line:', line, end='') - line = line[:i] + subst + line[i+n:] - n = len(subst) - i = i + n - return line - -Docomments = 0 -def setdocomments(): - global Docomments - Docomments = 1 - -Reverse = 0 -def setreverse(): - global Reverse - Reverse = (not Reverse) - -Dict = {} -NotInComment = {} -def addsubst(substfile): - try: - fp = open(substfile, 'r') - except IOError as msg: - err(substfile + ': cannot read substfile: ' + str(msg) + '\n') - sys.exit(1) - with fp: - lineno = 0 - while 1: - line = fp.readline() - if not line: break - lineno = lineno + 1 - try: - i = line.index('#') - except ValueError: - i = -1 # Happens to delete trailing \n - words = line[:i].split() - if not words: continue - if len(words) == 3 and words[0] == 'struct': - words[:2] = [words[0] + ' ' + words[1]] - elif len(words) != 2: - err(substfile + '%s:%r: warning: bad line: %r' % (substfile, lineno, line)) - continue - if Reverse: - [value, key] = words - else: - [key, value] = words - if value[0] == '*': - value = value[1:] - if key[0] == '*': - key = key[1:] - NotInComment[key] = value - if key in Dict: - err('%s:%r: warning: overriding: %r %r\n' % (substfile, lineno, key, value)) - err('%s:%r: warning: previous: %r\n' % (substfile, lineno, Dict[key])) - Dict[key] = value - -if __name__ == '__main__': - main() diff --git a/Tools/scripts/fixdiv.py b/Tools/scripts/fixdiv.py deleted file mode 100755 index df7c481a..00000000 --- a/Tools/scripts/fixdiv.py +++ /dev/null @@ -1,378 +0,0 @@ -#! /usr/bin/env python3 - -"""fixdiv - tool to fix division operators. - -To use this tool, first run `python -Qwarnall yourscript.py 2>warnings'. -This runs the script `yourscript.py' while writing warning messages -about all uses of the classic division operator to the file -`warnings'. The warnings look like this: - - <file>:<line>: DeprecationWarning: classic <type> division - -The warnings are written to stderr, so you must use `2>' for the I/O -redirect. I know of no way to redirect stderr on Windows in a DOS -box, so you will have to modify the script to set sys.stderr to some -kind of log file if you want to do this on Windows. - -The warnings are not limited to the script; modules imported by the -script may also trigger warnings. In fact a useful technique is to -write a test script specifically intended to exercise all code in a -particular module or set of modules. - -Then run `python fixdiv.py warnings'. This first reads the warnings, -looking for classic division warnings, and sorts them by file name and -line number. Then, for each file that received at least one warning, -it parses the file and tries to match the warnings up to the division -operators found in the source code. If it is successful, it writes -its findings to stdout, preceded by a line of dashes and a line of the -form: - - Index: <file> - -If the only findings found are suggestions to change a / operator into -a // operator, the output is acceptable input for the Unix 'patch' -program. - -Here are the possible messages on stdout (N stands for a line number): - -- A plain-diff-style change ('NcN', a line marked by '<', a line - containing '---', and a line marked by '>'): - - A / operator was found that should be changed to //. This is the - recommendation when only int and/or long arguments were seen. - -- 'True division / operator at line N' and a line marked by '=': - - A / operator was found that can remain unchanged. This is the - recommendation when only float and/or complex arguments were seen. - -- 'Ambiguous / operator (..., ...) at line N', line marked by '?': - - A / operator was found for which int or long as well as float or - complex arguments were seen. This is highly unlikely; if it occurs, - you may have to restructure the code to keep the classic semantics, - or maybe you don't care about the classic semantics. - -- 'No conclusive evidence on line N', line marked by '*': - - A / operator was found for which no warnings were seen. This could - be code that was never executed, or code that was only executed - with user-defined objects as arguments. You will have to - investigate further. Note that // can be overloaded separately from - /, using __floordiv__. True division can also be separately - overloaded, using __truediv__. Classic division should be the same - as either of those. (XXX should I add a warning for division on - user-defined objects, to disambiguate this case from code that was - never executed?) - -- 'Phantom ... warnings for line N', line marked by '*': - - A warning was seen for a line not containing a / operator. The most - likely cause is a warning about code executed by 'exec' or eval() - (see note below), or an indirect invocation of the / operator, for - example via the div() function in the operator module. It could - also be caused by a change to the file between the time the test - script was run to collect warnings and the time fixdiv was run. - -- 'More than one / operator in line N'; or - 'More than one / operator per statement in lines N-N': - - The scanner found more than one / operator on a single line, or in a - statement split across multiple lines. Because the warnings - framework doesn't (and can't) show the offset within the line, and - the code generator doesn't always give the correct line number for - operations in a multi-line statement, we can't be sure whether all - operators in the statement were executed. To be on the safe side, - by default a warning is issued about this case. In practice, these - cases are usually safe, and the -m option suppresses these warning. - -- 'Can't find the / operator in line N', line marked by '*': - - This really shouldn't happen. It means that the tokenize module - reported a '/' operator but the line it returns didn't contain a '/' - character at the indicated position. - -- 'Bad warning for line N: XYZ', line marked by '*': - - This really shouldn't happen. It means that a 'classic XYZ - division' warning was read with XYZ being something other than - 'int', 'long', 'float', or 'complex'. - -Notes: - -- The augmented assignment operator /= is handled the same way as the - / operator. - -- This tool never looks at the // operator; no warnings are ever - generated for use of this operator. - -- This tool never looks at the / operator when a future division - statement is in effect; no warnings are generated in this case, and - because the tool only looks at files for which at least one classic - division warning was seen, it will never look at files containing a - future division statement. - -- Warnings may be issued for code not read from a file, but executed - using the exec() or eval() functions. These may have - <string> in the filename position, in which case the fixdiv script - will attempt and fail to open a file named '<string>' and issue a - warning about this failure; or these may be reported as 'Phantom' - warnings (see above). You're on your own to deal with these. You - could make all recommended changes and add a future division - statement to all affected files, and then re-run the test script; it - should not issue any warnings. If there are any, and you have a - hard time tracking down where they are generated, you can use the - -Werror option to force an error instead of a first warning, - generating a traceback. - -- The tool should be run from the same directory as that from which - the original script was run, otherwise it won't be able to open - files given by relative pathnames. -""" - -import sys -import getopt -import re -import tokenize - -multi_ok = 0 - -def main(): - try: - opts, args = getopt.getopt(sys.argv[1:], "hm") - except getopt.error as msg: - usage(msg) - return 2 - for o, a in opts: - if o == "-h": - print(__doc__) - return - if o == "-m": - global multi_ok - multi_ok = 1 - if not args: - usage("at least one file argument is required") - return 2 - if args[1:]: - sys.stderr.write("%s: extra file arguments ignored\n", sys.argv[0]) - warnings = readwarnings(args[0]) - if warnings is None: - return 1 - files = list(warnings.keys()) - if not files: - print("No classic division warnings read from", args[0]) - return - files.sort() - exit = None - for filename in files: - x = process(filename, warnings[filename]) - exit = exit or x - return exit - -def usage(msg): - sys.stderr.write("%s: %s\n" % (sys.argv[0], msg)) - sys.stderr.write("Usage: %s [-m] warnings\n" % sys.argv[0]) - sys.stderr.write("Try `%s -h' for more information.\n" % sys.argv[0]) - -PATTERN = (r"^(.+?):(\d+): DeprecationWarning: " - r"classic (int|long|float|complex) division$") - -def readwarnings(warningsfile): - prog = re.compile(PATTERN) - warnings = {} - try: - f = open(warningsfile) - except IOError as msg: - sys.stderr.write("can't open: %s\n" % msg) - return - with f: - while 1: - line = f.readline() - if not line: - break - m = prog.match(line) - if not m: - if line.find("division") >= 0: - sys.stderr.write("Warning: ignored input " + line) - continue - filename, lineno, what = m.groups() - list = warnings.get(filename) - if list is None: - warnings[filename] = list = [] - list.append((int(lineno), sys.intern(what))) - return warnings - -def process(filename, list): - print("-"*70) - assert list # if this fails, readwarnings() is broken - try: - fp = open(filename) - except IOError as msg: - sys.stderr.write("can't open: %s\n" % msg) - return 1 - with fp: - print("Index:", filename) - f = FileContext(fp) - list.sort() - index = 0 # list[:index] has been processed, list[index:] is still to do - g = tokenize.generate_tokens(f.readline) - while 1: - startlineno, endlineno, slashes = lineinfo = scanline(g) - if startlineno is None: - break - assert startlineno <= endlineno is not None - orphans = [] - while index < len(list) and list[index][0] < startlineno: - orphans.append(list[index]) - index += 1 - if orphans: - reportphantomwarnings(orphans, f) - warnings = [] - while index < len(list) and list[index][0] <= endlineno: - warnings.append(list[index]) - index += 1 - if not slashes and not warnings: - pass - elif slashes and not warnings: - report(slashes, "No conclusive evidence") - elif warnings and not slashes: - reportphantomwarnings(warnings, f) - else: - if len(slashes) > 1: - if not multi_ok: - rows = [] - lastrow = None - for (row, col), line in slashes: - if row == lastrow: - continue - rows.append(row) - lastrow = row - assert rows - if len(rows) == 1: - print("*** More than one / operator in line", rows[0]) - else: - print("*** More than one / operator per statement", end=' ') - print("in lines %d-%d" % (rows[0], rows[-1])) - intlong = [] - floatcomplex = [] - bad = [] - for lineno, what in warnings: - if what in ("int", "long"): - intlong.append(what) - elif what in ("float", "complex"): - floatcomplex.append(what) - else: - bad.append(what) - lastrow = None - for (row, col), line in slashes: - if row == lastrow: - continue - lastrow = row - line = chop(line) - if line[col:col+1] != "/": - print("*** Can't find the / operator in line %d:" % row) - print("*", line) - continue - if bad: - print("*** Bad warning for line %d:" % row, bad) - print("*", line) - elif intlong and not floatcomplex: - print("%dc%d" % (row, row)) - print("<", line) - print("---") - print(">", line[:col] + "/" + line[col:]) - elif floatcomplex and not intlong: - print("True division / operator at line %d:" % row) - print("=", line) - elif intlong and floatcomplex: - print("*** Ambiguous / operator (%s, %s) at line %d:" % - ("|".join(intlong), "|".join(floatcomplex), row)) - print("?", line) - -def reportphantomwarnings(warnings, f): - blocks = [] - lastrow = None - lastblock = None - for row, what in warnings: - if row != lastrow: - lastblock = [row] - blocks.append(lastblock) - lastblock.append(what) - for block in blocks: - row = block[0] - whats = "/".join(block[1:]) - print("*** Phantom %s warnings for line %d:" % (whats, row)) - f.report(row, mark="*") - -def report(slashes, message): - lastrow = None - for (row, col), line in slashes: - if row != lastrow: - print("*** %s on line %d:" % (message, row)) - print("*", chop(line)) - lastrow = row - -class FileContext: - def __init__(self, fp, window=5, lineno=1): - self.fp = fp - self.window = 5 - self.lineno = 1 - self.eoflookahead = 0 - self.lookahead = [] - self.buffer = [] - def fill(self): - while len(self.lookahead) < self.window and not self.eoflookahead: - line = self.fp.readline() - if not line: - self.eoflookahead = 1 - break - self.lookahead.append(line) - def readline(self): - self.fill() - if not self.lookahead: - return "" - line = self.lookahead.pop(0) - self.buffer.append(line) - self.lineno += 1 - return line - def __getitem__(self, index): - self.fill() - bufstart = self.lineno - len(self.buffer) - lookend = self.lineno + len(self.lookahead) - if bufstart <= index < self.lineno: - return self.buffer[index - bufstart] - if self.lineno <= index < lookend: - return self.lookahead[index - self.lineno] - raise KeyError - def report(self, first, last=None, mark="*"): - if last is None: - last = first - for i in range(first, last+1): - try: - line = self[first] - except KeyError: - line = "<missing line>" - print(mark, chop(line)) - -def scanline(g): - slashes = [] - startlineno = None - endlineno = None - for type, token, start, end, line in g: - endlineno = end[0] - if startlineno is None: - startlineno = endlineno - if token in ("/", "/="): - slashes.append((start, line)) - if type == tokenize.NEWLINE: - break - return startlineno, endlineno, slashes - -def chop(line): - if line.endswith("\n"): - return line[:-1] - else: - return line - -if __name__ == "__main__": - sys.exit(main()) diff --git a/Tools/scripts/fixheader.py b/Tools/scripts/fixheader.py deleted file mode 100755 index c834eec1..00000000 --- a/Tools/scripts/fixheader.py +++ /dev/null @@ -1,49 +0,0 @@ -#! /usr/bin/env python3 - -# Add some standard cpp magic to a header file - -import sys - -def main(): - args = sys.argv[1:] - for filename in args: - process(filename) - -def process(filename): - try: - f = open(filename, 'r') - except IOError as msg: - sys.stderr.write('%s: can\'t open: %s\n' % (filename, str(msg))) - return - with f: - data = f.read() - if data[:2] != '/*': - sys.stderr.write('%s does not begin with C comment\n' % filename) - return - try: - f = open(filename, 'w') - except IOError as msg: - sys.stderr.write('%s: can\'t write: %s\n' % (filename, str(msg))) - return - with f: - sys.stderr.write('Processing %s ...\n' % filename) - magic = 'Py_' - for c in filename: - if ord(c)<=0x80 and c.isalnum(): - magic = magic + c.upper() - else: magic = magic + '_' - print('#ifndef', magic, file=f) - print('#define', magic, file=f) - print('#ifdef __cplusplus', file=f) - print('extern "C" {', file=f) - print('#endif', file=f) - print(file=f) - f.write(data) - print(file=f) - print('#ifdef __cplusplus', file=f) - print('}', file=f) - print('#endif', file=f) - print('#endif /*', '!'+magic, '*/', file=f) - -if __name__ == '__main__': - main() diff --git a/Tools/scripts/fixnotice.py b/Tools/scripts/fixnotice.py deleted file mode 100755 index 317051dd..00000000 --- a/Tools/scripts/fixnotice.py +++ /dev/null @@ -1,109 +0,0 @@ -#! /usr/bin/env python3 - -"""(Ostensibly) fix copyright notices in files. - -Actually, this script will simply replace a block of text in a file from one -string to another. It will only do this once though, i.e. not globally -throughout the file. It writes a backup file and then does an os.rename() -dance for atomicity. - -Usage: fixnotices.py [options] [filenames] -Options: - -h / --help - Print this message and exit - - --oldnotice=file - Use the notice in the file as the old (to be replaced) string, instead - of the hard coded value in the script. - - --newnotice=file - Use the notice in the file as the new (replacement) string, instead of - the hard coded value in the script. - - --dry-run - Don't actually make the changes, but print out the list of files that - would change. When used with -v, a status will be printed for every - file. - - -v / --verbose - Print a message for every file looked at, indicating whether the file - is changed or not. -""" - -OLD_NOTICE = """/*********************************************************** -Copyright (c) 2000, BeOpen.com. -Copyright (c) 1995-2000, Corporation for National Research Initiatives. -Copyright (c) 1990-1995, Stichting Mathematisch Centrum. -All rights reserved. - -See the file "Misc/COPYRIGHT" for information on usage and -redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES. -******************************************************************/ -""" -import os -import sys -import getopt - -NEW_NOTICE = "" -DRYRUN = 0 -VERBOSE = 0 - - -def usage(code, msg=''): - print(__doc__ % globals()) - if msg: - print(msg) - sys.exit(code) - - -def main(): - global DRYRUN, OLD_NOTICE, NEW_NOTICE, VERBOSE - try: - opts, args = getopt.getopt(sys.argv[1:], 'hv', - ['help', 'oldnotice=', 'newnotice=', - 'dry-run', 'verbose']) - except getopt.error as msg: - usage(1, msg) - - for opt, arg in opts: - if opt in ('-h', '--help'): - usage(0) - elif opt in ('-v', '--verbose'): - VERBOSE = 1 - elif opt == '--dry-run': - DRYRUN = 1 - elif opt == '--oldnotice': - with open(arg) as fp: - OLD_NOTICE = fp.read() - elif opt == '--newnotice': - with open(arg) as fp: - NEW_NOTICE = fp.read() - - for arg in args: - process(arg) - - -def process(file): - with open(file) as f: - data = f.read() - i = data.find(OLD_NOTICE) - if i < 0: - if VERBOSE: - print('no change:', file) - return - elif DRYRUN or VERBOSE: - print(' change:', file) - if DRYRUN: - # Don't actually change the file - return - data = data[:i] + NEW_NOTICE + data[i+len(OLD_NOTICE):] - new = file + ".new" - backup = file + ".bak" - with open(new, "w") as f: - f.write(data) - os.rename(file, backup) - os.rename(new, file) - - -if __name__ == '__main__': - main() diff --git a/Tools/scripts/fixps.py b/Tools/scripts/fixps.py deleted file mode 100755 index 725300e5..00000000 --- a/Tools/scripts/fixps.py +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/env python3 - -# Fix Python script(s) to reference the interpreter via /usr/bin/env python. -# Warning: this overwrites the file without making a backup. - -import sys -import re - - -def main(): - for filename in sys.argv[1:]: - try: - f = open(filename, 'r') - except IOError as msg: - print(filename, ': can\'t open :', msg) - continue - with f: - line = f.readline() - if not re.match('^#! */usr/local/bin/python', line): - print(filename, ': not a /usr/local/bin/python script') - continue - rest = f.read() - line = re.sub('/usr/local/bin/python', - '/usr/bin/env python', line) - print(filename, ':', repr(line)) - with open(filename, "w") as f: - f.write(line) - f.write(rest) - -if __name__ == '__main__': - main() diff --git a/Tools/scripts/get-remote-certificate.py b/Tools/scripts/get-remote-certificate.py deleted file mode 100755 index 68272fca..00000000 --- a/Tools/scripts/get-remote-certificate.py +++ /dev/null @@ -1,70 +0,0 @@ -#!/usr/bin/env python3 -# -# fetch the certificate that the server(s) are providing in PEM form -# -# args are HOST:PORT [, HOST:PORT...] -# -# By Bill Janssen. - -import re -import os -import sys -import tempfile - - -def fetch_server_certificate (host, port): - - def subproc(cmd): - from subprocess import Popen, PIPE, STDOUT, DEVNULL - proc = Popen(cmd, stdout=PIPE, stderr=STDOUT, stdin=DEVNULL) - status = proc.wait() - output = proc.stdout.read() - return status, output - - def strip_to_x509_cert(certfile_contents, outfile=None): - m = re.search(br"^([-]+BEGIN CERTIFICATE[-]+[\r]*\n" - br".*[\r]*^[-]+END CERTIFICATE[-]+)$", - certfile_contents, re.MULTILINE | re.DOTALL) - if not m: - return None - else: - tn = tempfile.mktemp() - with open(tn, "wb") as fp: - fp.write(m.group(1) + b"\n") - try: - tn2 = (outfile or tempfile.mktemp()) - cmd = ['openssl', 'x509', '-in', tn, '-out', tn2] - status, output = subproc(cmd) - if status != 0: - raise RuntimeError('OpenSSL x509 failed with status %s and ' - 'output: %r' % (status, output)) - with open(tn2, 'rb') as fp: - data = fp.read() - os.unlink(tn2) - return data - finally: - os.unlink(tn) - - cmd = ['openssl', 's_client', '-connect', '%s:%s' % (host, port), '-showcerts'] - status, output = subproc(cmd) - - if status != 0: - raise RuntimeError('OpenSSL connect failed with status %s and ' - 'output: %r' % (status, output)) - certtext = strip_to_x509_cert(output) - if not certtext: - raise ValueError("Invalid response received from server at %s:%s" % - (host, port)) - return certtext - - -if __name__ == "__main__": - if len(sys.argv) < 2: - sys.stderr.write( - "Usage: %s HOSTNAME:PORTNUMBER [, HOSTNAME:PORTNUMBER...]\n" % - sys.argv[0]) - sys.exit(1) - for arg in sys.argv[1:]: - host, port = arg.split(":") - sys.stdout.buffer.write(fetch_server_certificate(host, int(port))) - sys.exit(0) diff --git a/Tools/scripts/google.py b/Tools/scripts/google.py deleted file mode 100755 index 82fb2871..00000000 --- a/Tools/scripts/google.py +++ /dev/null @@ -1,25 +0,0 @@ -#! /usr/bin/env python3 - -"""Script to search with Google - -Usage: - python3 google.py [search terms] -""" - -import sys -import urllib.parse -import webbrowser - - -def main(args): - def quote(arg): - if ' ' in arg: - arg = '"%s"' % arg - return urllib.parse.quote_plus(arg) - - qstring = '+'.join(quote(arg) for arg in args) - url = urllib.parse.urljoin('https://www.google.com/search', '?q=' + qstring) - webbrowser.open(url) - -if __name__ == '__main__': - main(sys.argv[1:]) diff --git a/Tools/scripts/gprof2html.py b/Tools/scripts/gprof2html.py deleted file mode 100755 index bf0530ef..00000000 --- a/Tools/scripts/gprof2html.py +++ /dev/null @@ -1,87 +0,0 @@ -#! /usr/bin/env python3 - -"""Transform gprof(1) output into useful HTML.""" - -import html -import os -import re -import sys -import webbrowser - -header = """\ -<html> -<head> - <title>gprof output (%s) - - -
-"""
-
-trailer = """\
-
- - -""" - -def add_escapes(filename): - with open(filename, encoding="utf-8") as fp: - for line in fp: - yield html.escape(line) - -def gprof2html(input, output, filename): - output.write(header % filename) - for line in input: - output.write(line) - if line.startswith(" time"): - break - labels = {} - for line in input: - m = re.match(r"(.* )(\w+)\n", line) - if not m: - output.write(line) - break - stuff, fname = m.group(1, 2) - labels[fname] = fname - output.write('%s%s\n' % - (stuff, fname, fname, fname)) - for line in input: - output.write(line) - if line.startswith("index % time"): - break - for line in input: - m = re.match(r"(.* )(\w+)(( <cycle.*>)? \[\d+\])\n", line) - if not m: - output.write(line) - if line.startswith("Index by function name"): - break - continue - prefix, fname, suffix = m.group(1, 2, 3) - if fname not in labels: - output.write(line) - continue - if line.startswith("["): - output.write('%s%s%s\n' % - (prefix, fname, fname, fname, suffix)) - else: - output.write('%s%s%s\n' % - (prefix, fname, fname, suffix)) - for line in input: - for part in re.findall(r"(\w+(?:\.c)?|\W+)", line): - if part in labels: - part = '%s' % (part, part) - output.write(part) - output.write(trailer) - - -def main(): - filename = "gprof.out" - if sys.argv[1:]: - filename = sys.argv[1] - outputfilename = filename + ".html" - input = add_escapes(filename) - with open(outputfilename, "w", encoding="utf-8") as output: - gprof2html(input, output, filename) - webbrowser.open("file:" + os.path.abspath(outputfilename)) - -if __name__ == '__main__': - main() diff --git a/Tools/scripts/highlight.py b/Tools/scripts/highlight.py deleted file mode 100755 index 9272fee4..00000000 --- a/Tools/scripts/highlight.py +++ /dev/null @@ -1,265 +0,0 @@ -#!/usr/bin/env python3 -'''Add syntax highlighting to Python source code''' - -__author__ = 'Raymond Hettinger' - -import builtins -import functools -import html as html_module -import keyword -import re -import tokenize - -#### Analyze Python Source ################################# - -def is_builtin(s): - 'Return True if s is the name of a builtin' - return hasattr(builtins, s) - -def combine_range(lines, start, end): - 'Join content from a range of lines between start and end' - (srow, scol), (erow, ecol) = start, end - if srow == erow: - return lines[srow-1][scol:ecol], end - rows = [lines[srow-1][scol:]] + lines[srow: erow-1] + [lines[erow-1][:ecol]] - return ''.join(rows), end - -def analyze_python(source): - '''Generate and classify chunks of Python for syntax highlighting. - Yields tuples in the form: (category, categorized_text). - ''' - lines = source.splitlines(True) - lines.append('') - readline = functools.partial(next, iter(lines), '') - kind = tok_str = '' - tok_type = tokenize.COMMENT - written = (1, 0) - for tok in tokenize.generate_tokens(readline): - prev_tok_type, prev_tok_str = tok_type, tok_str - tok_type, tok_str, (srow, scol), (erow, ecol), logical_lineno = tok - kind = '' - if tok_type == tokenize.COMMENT: - kind = 'comment' - elif tok_type == tokenize.OP and tok_str[:1] not in '{}[](),.:;@': - kind = 'operator' - elif tok_type == tokenize.STRING: - kind = 'string' - if prev_tok_type == tokenize.INDENT or scol==0: - kind = 'docstring' - elif tok_type == tokenize.NAME: - if tok_str in ('def', 'class', 'import', 'from'): - kind = 'definition' - elif prev_tok_str in ('def', 'class'): - kind = 'defname' - elif keyword.iskeyword(tok_str): - kind = 'keyword' - elif is_builtin(tok_str) and prev_tok_str != '.': - kind = 'builtin' - if kind: - text, written = combine_range(lines, written, (srow, scol)) - yield '', text - text, written = tok_str, (erow, ecol) - yield kind, text - line_upto_token, written = combine_range(lines, written, (erow, ecol)) - yield '', line_upto_token - -#### Raw Output ########################################### - -def raw_highlight(classified_text): - 'Straight text display of text classifications' - result = [] - for kind, text in classified_text: - result.append('%15s: %r\n' % (kind or 'plain', text)) - return ''.join(result) - -#### ANSI Output ########################################### - -default_ansi = { - 'comment': ('\033[0;31m', '\033[0m'), - 'string': ('\033[0;32m', '\033[0m'), - 'docstring': ('\033[0;32m', '\033[0m'), - 'keyword': ('\033[0;33m', '\033[0m'), - 'builtin': ('\033[0;35m', '\033[0m'), - 'definition': ('\033[0;33m', '\033[0m'), - 'defname': ('\033[0;34m', '\033[0m'), - 'operator': ('\033[0;33m', '\033[0m'), -} - -def ansi_highlight(classified_text, colors=default_ansi): - 'Add syntax highlighting to source code using ANSI escape sequences' - # http://en.wikipedia.org/wiki/ANSI_escape_code - result = [] - for kind, text in classified_text: - opener, closer = colors.get(kind, ('', '')) - result += [opener, text, closer] - return ''.join(result) - -#### HTML Output ########################################### - -def html_highlight(classified_text,opener='
\n', closer='
\n'): - 'Convert classified text to an HTML fragment' - result = [opener] - for kind, text in classified_text: - if kind: - result.append('' % kind) - result.append(html_module.escape(text)) - if kind: - result.append('') - result.append(closer) - return ''.join(result) - -default_css = { - '.comment': '{color: crimson;}', - '.string': '{color: forestgreen;}', - '.docstring': '{color: forestgreen; font-style:italic;}', - '.keyword': '{color: darkorange;}', - '.builtin': '{color: purple;}', - '.definition': '{color: darkorange; font-weight:bold;}', - '.defname': '{color: blue;}', - '.operator': '{color: brown;}', -} - -default_html = '''\ - - - - - {title} - - - -{body} - - -''' - -def build_html_page(classified_text, title='python', - css=default_css, html=default_html): - 'Create a complete HTML page with colorized source code' - css_str = '\n'.join(['%s %s' % item for item in css.items()]) - result = html_highlight(classified_text) - title = html_module.escape(title) - return html.format(title=title, css=css_str, body=result) - -#### LaTeX Output ########################################## - -default_latex_commands = { - 'comment': r'{\color{red}#1}', - 'string': r'{\color{ForestGreen}#1}', - 'docstring': r'{\emph{\color{ForestGreen}#1}}', - 'keyword': r'{\color{orange}#1}', - 'builtin': r'{\color{purple}#1}', - 'definition': r'{\color{orange}#1}', - 'defname': r'{\color{blue}#1}', - 'operator': r'{\color{brown}#1}', -} - -default_latex_document = r''' -\documentclass{article} -\usepackage{alltt} -\usepackage{upquote} -\usepackage{color} -\usepackage[usenames,dvipsnames]{xcolor} -\usepackage[cm]{fullpage} -%(macros)s -\begin{document} -\center{\LARGE{%(title)s}} -\begin{alltt} -%(body)s -\end{alltt} -\end{document} -''' - -def alltt_escape(s): - 'Replace backslash and braces with their escaped equivalents' - xlat = {'{': r'\{', '}': r'\}', '\\': r'\textbackslash{}'} - return re.sub(r'[\\{}]', lambda mo: xlat[mo.group()], s) - -def latex_highlight(classified_text, title = 'python', - commands = default_latex_commands, - document = default_latex_document): - 'Create a complete LaTeX document with colorized source code' - macros = '\n'.join(r'\newcommand{\py%s}[1]{%s}' % c for c in commands.items()) - result = [] - for kind, text in classified_text: - if kind: - result.append(r'\py%s{' % kind) - result.append(alltt_escape(text)) - if kind: - result.append('}') - return default_latex_document % dict(title=title, macros=macros, body=''.join(result)) - - -if __name__ == '__main__': - import argparse - import os.path - import sys - import textwrap - import webbrowser - - parser = argparse.ArgumentParser( - description = 'Add syntax highlighting to Python source code', - formatter_class=argparse.RawDescriptionHelpFormatter, - epilog = textwrap.dedent(''' - examples: - - # Show syntax highlighted code in the terminal window - $ ./highlight.py myfile.py - - # Colorize myfile.py and display in a browser - $ ./highlight.py -b myfile.py - - # Create an HTML section to embed in an existing webpage - ./highlight.py -s myfile.py - - # Create a complete HTML file - $ ./highlight.py -c myfile.py > myfile.html - - # Create a PDF using LaTeX - $ ./highlight.py -l myfile.py | pdflatex - - ''')) - parser.add_argument('sourcefile', metavar = 'SOURCEFILE', - help = 'file containing Python sourcecode') - parser.add_argument('-b', '--browser', action = 'store_true', - help = 'launch a browser to show results') - parser.add_argument('-c', '--complete', action = 'store_true', - help = 'build a complete html webpage') - parser.add_argument('-l', '--latex', action = 'store_true', - help = 'build a LaTeX document') - parser.add_argument('-r', '--raw', action = 'store_true', - help = 'raw parse of categorized text') - parser.add_argument('-s', '--section', action = 'store_true', - help = 'show an HTML section rather than a complete webpage') - args = parser.parse_args() - - if args.section and (args.browser or args.complete): - parser.error('The -s/--section option is incompatible with ' - 'the -b/--browser or -c/--complete options') - - sourcefile = args.sourcefile - with open(sourcefile) as f: - source = f.read() - classified_text = analyze_python(source) - - if args.raw: - encoded = raw_highlight(classified_text) - elif args.complete or args.browser: - encoded = build_html_page(classified_text, title=sourcefile) - elif args.section: - encoded = html_highlight(classified_text) - elif args.latex: - encoded = latex_highlight(classified_text, title=sourcefile) - else: - encoded = ansi_highlight(classified_text) - - if args.browser: - htmlfile = os.path.splitext(os.path.basename(sourcefile))[0] + '.html' - with open(htmlfile, 'w') as f: - f.write(encoded) - webbrowser.open('file://' + os.path.abspath(htmlfile)) - else: - sys.stdout.write(encoded) diff --git a/Tools/scripts/idle3 b/Tools/scripts/idle3 index d7332bca..2b4f1b5c 100755 --- a/Tools/scripts/idle3 +++ b/Tools/scripts/idle3 @@ -1,4 +1,4 @@ -#! /usr/bin/env python3 +#!/usr/bin/env python3 from idlelib.pyshell import main if __name__ == '__main__': diff --git a/Tools/scripts/ifdef.py b/Tools/scripts/ifdef.py deleted file mode 100755 index 22249b2d..00000000 --- a/Tools/scripts/ifdef.py +++ /dev/null @@ -1,111 +0,0 @@ -#! /usr/bin/env python3 - -# Selectively preprocess #ifdef / #ifndef statements. -# Usage: -# ifdef [-Dname] ... [-Uname] ... [file] ... -# -# This scans the file(s), looking for #ifdef and #ifndef preprocessor -# commands that test for one of the names mentioned in the -D and -U -# options. On standard output it writes a copy of the input file(s) -# minus those code sections that are suppressed by the selected -# combination of defined/undefined symbols. The #if(n)def/#else/#else -# lines themselves (if the #if(n)def tests for one of the mentioned -# names) are removed as well. - -# Features: Arbitrary nesting of recognized and unrecognized -# preprocessor statements works correctly. Unrecognized #if* commands -# are left in place, so it will never remove too much, only too -# little. It does accept whitespace around the '#' character. - -# Restrictions: There should be no comments or other symbols on the -# #if(n)def lines. The effect of #define/#undef commands in the input -# file or in included files is not taken into account. Tests using -# #if and the defined() pseudo function are not recognized. The #elif -# command is not recognized. Improperly nesting is not detected. -# Lines that look like preprocessor commands but which are actually -# part of comments or string literals will be mistaken for -# preprocessor commands. - -import sys -import getopt - -defs = [] -undefs = [] - -def main(): - opts, args = getopt.getopt(sys.argv[1:], 'D:U:') - for o, a in opts: - if o == '-D': - defs.append(a) - if o == '-U': - undefs.append(a) - if not args: - args = ['-'] - for filename in args: - if filename == '-': - process(sys.stdin, sys.stdout) - else: - with open(filename) as f: - process(f, sys.stdout) - -def process(fpi, fpo): - keywords = ('if', 'ifdef', 'ifndef', 'else', 'endif') - ok = 1 - stack = [] - while 1: - line = fpi.readline() - if not line: break - while line[-2:] == '\\\n': - nextline = fpi.readline() - if not nextline: break - line = line + nextline - tmp = line.strip() - if tmp[:1] != '#': - if ok: fpo.write(line) - continue - tmp = tmp[1:].strip() - words = tmp.split() - keyword = words[0] - if keyword not in keywords: - if ok: fpo.write(line) - continue - if keyword in ('ifdef', 'ifndef') and len(words) == 2: - if keyword == 'ifdef': - ko = 1 - else: - ko = 0 - word = words[1] - if word in defs: - stack.append((ok, ko, word)) - if not ko: ok = 0 - elif word in undefs: - stack.append((ok, not ko, word)) - if ko: ok = 0 - else: - stack.append((ok, -1, word)) - if ok: fpo.write(line) - elif keyword == 'if': - stack.append((ok, -1, '')) - if ok: fpo.write(line) - elif keyword == 'else' and stack: - s_ok, s_ko, s_word = stack[-1] - if s_ko < 0: - if ok: fpo.write(line) - else: - s_ko = not s_ko - ok = s_ok - if not s_ko: ok = 0 - stack[-1] = s_ok, s_ko, s_word - elif keyword == 'endif' and stack: - s_ok, s_ko, s_word = stack[-1] - if s_ko < 0: - if ok: fpo.write(line) - del stack[-1] - ok = s_ok - else: - sys.stderr.write('Unknown keyword %s\n' % keyword) - if stack: - sys.stderr.write('stack: %s\n' % stack) - -if __name__ == '__main__': - main() diff --git a/Tools/scripts/import_diagnostics.py b/Tools/scripts/import_diagnostics.py deleted file mode 100755 index c907221d..00000000 --- a/Tools/scripts/import_diagnostics.py +++ /dev/null @@ -1,37 +0,0 @@ -#!/usr/bin/env python3 -"""Miscellaneous diagnostics for the import system""" - -import sys -import argparse -from pprint import pprint - -def _dump_state(args): - print(sys.version) - for name in args.attributes: - print("sys.{}:".format(name)) - pprint(getattr(sys, name)) - -def _add_dump_args(cmd): - cmd.add_argument("attributes", metavar="ATTR", nargs="+", - help="sys module attribute to display") - -COMMANDS = ( - ("dump", "Dump import state", _dump_state, _add_dump_args), -) - -def _make_parser(): - parser = argparse.ArgumentParser() - sub = parser.add_subparsers(title="Commands") - for name, description, implementation, add_args in COMMANDS: - cmd = sub.add_parser(name, help=description) - cmd.set_defaults(command=implementation) - add_args(cmd) - return parser - -def main(args): - parser = _make_parser() - args = parser.parse_args(args) - return args.command(args) - -if __name__ == "__main__": - sys.exit(main(sys.argv[1:])) diff --git a/Tools/scripts/lfcr.py b/Tools/scripts/lfcr.py deleted file mode 100755 index bf8fe1c2..00000000 --- a/Tools/scripts/lfcr.py +++ /dev/null @@ -1,24 +0,0 @@ -#! /usr/bin/env python3 - -"Replace LF with CRLF in argument files. Print names of changed files." - -import sys, re, os - -def main(): - for filename in sys.argv[1:]: - if os.path.isdir(filename): - print(filename, "Directory!") - continue - with open(filename, "rb") as f: - data = f.read() - if b'\0' in data: - print(filename, "Binary!") - continue - newdata = re.sub(b"\r?\n", b"\r\n", data) - if newdata != data: - print(filename) - with open(filename, "wb") as f: - f.write(newdata) - -if __name__ == '__main__': - main() diff --git a/Tools/scripts/linktree.py b/Tools/scripts/linktree.py deleted file mode 100755 index e83f1985..00000000 --- a/Tools/scripts/linktree.py +++ /dev/null @@ -1,80 +0,0 @@ -#! /usr/bin/env python3 - -# linktree -# -# Make a copy of a directory tree with symbolic links to all files in the -# original tree. -# All symbolic links go to a special symbolic link at the top, so you -# can easily fix things if the original source tree moves. -# See also "mkreal". -# -# usage: mklinks oldtree newtree - -import sys, os - -LINK = '.LINK' # Name of special symlink at the top. - -debug = 0 - -def main(): - if not 3 <= len(sys.argv) <= 4: - print('usage:', sys.argv[0], 'oldtree newtree [linkto]') - return 2 - oldtree, newtree = sys.argv[1], sys.argv[2] - if len(sys.argv) > 3: - link = sys.argv[3] - link_may_fail = 1 - else: - link = LINK - link_may_fail = 0 - if not os.path.isdir(oldtree): - print(oldtree + ': not a directory') - return 1 - try: - os.mkdir(newtree, 0o777) - except OSError as msg: - print(newtree + ': cannot mkdir:', msg) - return 1 - linkname = os.path.join(newtree, link) - try: - os.symlink(os.path.join(os.pardir, oldtree), linkname) - except OSError as msg: - if not link_may_fail: - print(linkname + ': cannot symlink:', msg) - return 1 - else: - print(linkname + ': warning: cannot symlink:', msg) - linknames(oldtree, newtree, link) - return 0 - -def linknames(old, new, link): - if debug: print('linknames', (old, new, link)) - try: - names = os.listdir(old) - except OSError as msg: - print(old + ': warning: cannot listdir:', msg) - return - for name in names: - if name not in (os.curdir, os.pardir): - oldname = os.path.join(old, name) - linkname = os.path.join(link, name) - newname = os.path.join(new, name) - if debug > 1: print(oldname, newname, linkname) - if os.path.isdir(oldname) and \ - not os.path.islink(oldname): - try: - os.mkdir(newname, 0o777) - ok = 1 - except: - print(newname + \ - ': warning: cannot mkdir:', msg) - ok = 0 - if ok: - linkname = os.path.join(os.pardir, - linkname) - linknames(oldname, newname, linkname) - else: - os.symlink(linkname, newname) - -if __name__ == '__main__': - sys.exit(main()) diff --git a/Tools/scripts/lll.py b/Tools/scripts/lll.py deleted file mode 100755 index 1b48eac8..00000000 --- a/Tools/scripts/lll.py +++ /dev/null @@ -1,27 +0,0 @@ -#! /usr/bin/env python3 - -# Find symbolic links and show where they point to. -# Arguments are directories to search; default is current directory. -# No recursion. -# (This is a totally different program from "findsymlinks.py"!) - -import sys, os - -def lll(dirname): - for name in os.listdir(dirname): - if name not in (os.curdir, os.pardir): - full = os.path.join(dirname, name) - if os.path.islink(full): - print(name, '->', os.readlink(full)) -def main(args): - if not args: args = [os.curdir] - first = 1 - for arg in args: - if len(args) > 1: - if not first: print() - first = 0 - print(arg + ':') - lll(arg) - -if __name__ == '__main__': - main(sys.argv[1:]) diff --git a/Tools/scripts/mailerdaemon.py b/Tools/scripts/mailerdaemon.py deleted file mode 100755 index 635e5482..00000000 --- a/Tools/scripts/mailerdaemon.py +++ /dev/null @@ -1,246 +0,0 @@ -#!/usr/bin/env python3 -"""Classes to parse mailer-daemon messages.""" - -import calendar -import email.message -import re -import os -import sys - - -class Unparseable(Exception): - pass - - -class ErrorMessage(email.message.Message): - def __init__(self): - email.message.Message.__init__(self) - self.sub = '' - - def is_warning(self): - sub = self.get('Subject') - if not sub: - return 0 - sub = sub.lower() - if sub.startswith('waiting mail'): - return 1 - if 'warning' in sub: - return 1 - self.sub = sub - return 0 - - def get_errors(self): - for p in EMPARSERS: - self.rewindbody() - try: - return p(self.fp, self.sub) - except Unparseable: - pass - raise Unparseable - -# List of re's or tuples of re's. -# If a re, it should contain at least a group (?P...) which -# should refer to the email address. The re can also contain a group -# (?P...) which should refer to the reason (error message). -# If no reason is present, the emparse_list_reason list is used to -# find a reason. -# If a tuple, the tuple should contain 2 re's. The first re finds a -# location, the second re is repeated one or more times to find -# multiple email addresses. The second re is matched (not searched) -# where the previous match ended. -# The re's are compiled using the re module. -emparse_list_list = [ - 'error: (?Punresolvable): (?P.+)', - ('----- The following addresses had permanent fatal errors -----\n', - '(?P[^ \n].*)\n( .*\n)?'), - 'remote execution.*\n.*rmail (?P.+)', - ('The following recipients did not receive your message:\n\n', - ' +(?P.*)\n(The following recipients did not receive your message:\n\n)?'), - '------- Failure Reasons --------\n\n(?P.*)\n(?P.*)', - '^<(?P.*)>:\n(?P.*)', - '^(?PUser mailbox exceeds allowed size): (?P.+)', - '^5\\d{2} <(?P[^\n>]+)>\\.\\.\\. (?P.+)', - '^Original-Recipient: rfc822;(?P.*)', - '^did not reach the following recipient\\(s\\):\n\n(?P.*) on .*\n +(?P.*)', - '^ <(?P[^\n>]+)> \\.\\.\\. (?P.*)', - '^Report on your message to: (?P.*)\nReason: (?P.*)', - '^Your message was not delivered to +(?P.*)\n +for the following reason:\n +(?P.*)', - '^ was not +(?P[^ \n].*?) *\n.*\n.*\n.*\n because:.*\n +(?P[^ \n].*?) *\n', - ] -# compile the re's in the list and store them in-place. -for i in range(len(emparse_list_list)): - x = emparse_list_list[i] - if type(x) is type(''): - x = re.compile(x, re.MULTILINE) - else: - xl = [] - for x in x: - xl.append(re.compile(x, re.MULTILINE)) - x = tuple(xl) - del xl - emparse_list_list[i] = x - del x -del i - -# list of re's used to find reasons (error messages). -# if a string, "<>" is replaced by a copy of the email address. -# The expressions are searched for in order. After the first match, -# no more expressions are searched for. So, order is important. -emparse_list_reason = [ - r'^5\d{2} <>\.\.\. (?P.*)', - r'<>\.\.\. (?P.*)', - re.compile(r'^<<< 5\d{2} (?P.*)', re.MULTILINE), - re.compile('===== stderr was =====\nrmail: (?P.*)'), - re.compile('^Diagnostic-Code: (?P.*)', re.MULTILINE), - ] -emparse_list_from = re.compile('^From:', re.IGNORECASE|re.MULTILINE) -def emparse_list(fp, sub): - data = fp.read() - res = emparse_list_from.search(data) - if res is None: - from_index = len(data) - else: - from_index = res.start(0) - errors = [] - emails = [] - reason = None - for regexp in emparse_list_list: - if type(regexp) is type(()): - res = regexp[0].search(data, 0, from_index) - if res is not None: - try: - reason = res.group('reason') - except IndexError: - pass - while 1: - res = regexp[1].match(data, res.end(0), from_index) - if res is None: - break - emails.append(res.group('email')) - break - else: - res = regexp.search(data, 0, from_index) - if res is not None: - emails.append(res.group('email')) - try: - reason = res.group('reason') - except IndexError: - pass - break - if not emails: - raise Unparseable - if not reason: - reason = sub - if reason[:15] == 'returned mail: ': - reason = reason[15:] - for regexp in emparse_list_reason: - if type(regexp) is type(''): - for i in range(len(emails)-1,-1,-1): - email = emails[i] - exp = re.compile(re.escape(email).join(regexp.split('<>')), re.MULTILINE) - res = exp.search(data) - if res is not None: - errors.append(' '.join((email.strip()+': '+res.group('reason')).split())) - del emails[i] - continue - res = regexp.search(data) - if res is not None: - reason = res.group('reason') - break - for email in emails: - errors.append(' '.join((email.strip()+': '+reason).split())) - return errors - -EMPARSERS = [emparse_list] - -def sort_numeric(a, b): - a = int(a) - b = int(b) - if a < b: - return -1 - elif a > b: - return 1 - else: - return 0 - -def parsedir(dir, modify): - os.chdir(dir) - pat = re.compile('^[0-9]*$') - errordict = {} - errorfirst = {} - errorlast = {} - nok = nwarn = nbad = 0 - - # find all numeric file names and sort them - files = list(filter(lambda fn, pat=pat: pat.match(fn) is not None, os.listdir('.'))) - files.sort(sort_numeric) - - for fn in files: - # Lets try to parse the file. - fp = open(fn) - m = email.message_from_file(fp, _class=ErrorMessage) - sender = m.getaddr('From') - print('%s\t%-40s\t'%(fn, sender[1]), end=' ') - - if m.is_warning(): - fp.close() - print('warning only') - nwarn = nwarn + 1 - if modify: - os.rename(fn, ','+fn) -## os.unlink(fn) - continue - - try: - errors = m.get_errors() - except Unparseable: - print('** Not parseable') - nbad = nbad + 1 - fp.close() - continue - print(len(errors), 'errors') - - # Remember them - for e in errors: - try: - mm, dd = m.getdate('date')[1:1+2] - date = '%s %02d' % (calendar.month_abbr[mm], dd) - except: - date = '??????' - if e not in errordict: - errordict[e] = 1 - errorfirst[e] = '%s (%s)' % (fn, date) - else: - errordict[e] = errordict[e] + 1 - errorlast[e] = '%s (%s)' % (fn, date) - - fp.close() - nok = nok + 1 - if modify: - os.rename(fn, ','+fn) -## os.unlink(fn) - - print('--------------') - print(nok, 'files parsed,',nwarn,'files warning-only,', end=' ') - print(nbad,'files unparseable') - print('--------------') - list = [] - for e in errordict.keys(): - list.append((errordict[e], errorfirst[e], errorlast[e], e)) - list.sort() - for num, first, last, e in list: - print('%d %s - %s\t%s' % (num, first, last, e)) - -def main(): - modify = 0 - if len(sys.argv) > 1 and sys.argv[1] == '-d': - modify = 1 - del sys.argv[1] - if len(sys.argv) > 1: - for folder in sys.argv[1:]: - parsedir(folder, modify) - else: - parsedir('/ufs/jack/Mail/errorsinbox', modify) - -if __name__ == '__main__' or sys.argv[0] == __name__: - main() diff --git a/Tools/scripts/make_ctype.py b/Tools/scripts/make_ctype.py deleted file mode 100755 index afee1c58..00000000 --- a/Tools/scripts/make_ctype.py +++ /dev/null @@ -1,94 +0,0 @@ -#!/usr/bin/env python3 -"""Script that generates the ctype.h-replacement in stringobject.c.""" - -NAMES = ("LOWER", "UPPER", "ALPHA", "DIGIT", "XDIGIT", "ALNUM", "SPACE") - -print(""" -#define FLAG_LOWER 0x01 -#define FLAG_UPPER 0x02 -#define FLAG_ALPHA (FLAG_LOWER|FLAG_UPPER) -#define FLAG_DIGIT 0x04 -#define FLAG_ALNUM (FLAG_ALPHA|FLAG_DIGIT) -#define FLAG_SPACE 0x08 -#define FLAG_XDIGIT 0x10 - -static unsigned int ctype_table[256] = {""") - -for i in range(128): - c = chr(i) - flags = [] - for name in NAMES: - if name in ("ALPHA", "ALNUM"): - continue - if name == "XDIGIT": - method = lambda: c.isdigit() or c.upper() in "ABCDEF" - else: - method = getattr(c, "is" + name.lower()) - if method(): - flags.append("FLAG_" + name) - rc = repr(c) - if c == '\v': - rc = "'\\v'" - elif c == '\f': - rc = "'\\f'" - if not flags: - print(" 0, /* 0x%x %s */" % (i, rc)) - else: - print(" %s, /* 0x%x %s */" % ("|".join(flags), i, rc)) - -for i in range(128, 256, 16): - print(" %s," % ", ".join(16*["0"])) - -print("};") -print("") - -for name in NAMES: - print("#define IS%s(c) (ctype_table[Py_CHARMASK(c)] & FLAG_%s)" % - (name, name)) - -print("") - -for name in NAMES: - name = "is" + name.lower() - print("#undef %s" % name) - print("#define %s(c) undefined_%s(c)" % (name, name)) - -print(""" -static unsigned char ctype_tolower[256] = {""") - -for i in range(0, 256, 8): - values = [] - for i in range(i, i+8): - if i < 128: - c = chr(i) - if c.isupper(): - i = ord(c.lower()) - values.append("0x%02x" % i) - print(" %s," % ", ".join(values)) - -print("};") - -print(""" -static unsigned char ctype_toupper[256] = {""") - -for i in range(0, 256, 8): - values = [] - for i in range(i, i+8): - if i < 128: - c = chr(i) - if c.islower(): - i = ord(c.upper()) - values.append("0x%02x" % i) - print(" %s," % ", ".join(values)) - -print("};") - -print(""" -#define TOLOWER(c) (ctype_tolower[Py_CHARMASK(c)]) -#define TOUPPER(c) (ctype_toupper[Py_CHARMASK(c)]) - -#undef tolower -#define tolower(c) undefined_tolower(c) -#undef toupper -#define toupper(c) undefined_toupper(c) -""") diff --git a/Tools/scripts/md5sum.py b/Tools/scripts/md5sum.py deleted file mode 100755 index f9105763..00000000 --- a/Tools/scripts/md5sum.py +++ /dev/null @@ -1,93 +0,0 @@ -#! /usr/bin/env python3 - -"""Python utility to print MD5 checksums of argument files. -""" - - -bufsize = 8096 -fnfilter = None -rmode = 'rb' - -usage = """ -usage: md5sum.py [-b] [-t] [-l] [-s bufsize] [file ...] --b : read files in binary mode (default) --t : read files in text mode (you almost certainly don't want this!) --l : print last pathname component only --s bufsize: read buffer size (default %d) -file ... : files to sum; '-' or no files means stdin -""" % bufsize - -import io -import sys -import os -import getopt -from hashlib import md5 - -def sum(*files): - sts = 0 - if files and isinstance(files[-1], io.IOBase): - out, files = files[-1], files[:-1] - else: - out = sys.stdout - if len(files) == 1 and not isinstance(files[0], str): - files = files[0] - for f in files: - if isinstance(f, str): - if f == '-': - sts = printsumfp(sys.stdin, '', out) or sts - else: - sts = printsum(f, out) or sts - else: - sts = sum(f, out) or sts - return sts - -def printsum(filename, out=sys.stdout): - try: - fp = open(filename, rmode) - except IOError as msg: - sys.stderr.write('%s: Can\'t open: %s\n' % (filename, msg)) - return 1 - with fp: - if fnfilter: - filename = fnfilter(filename) - sts = printsumfp(fp, filename, out) - return sts - -def printsumfp(fp, filename, out=sys.stdout): - m = md5() - try: - while 1: - data = fp.read(bufsize) - if not data: - break - if isinstance(data, str): - data = data.encode(fp.encoding) - m.update(data) - except IOError as msg: - sys.stderr.write('%s: I/O error: %s\n' % (filename, msg)) - return 1 - out.write('%s %s\n' % (m.hexdigest(), filename)) - return 0 - -def main(args = sys.argv[1:], out=sys.stdout): - global fnfilter, rmode, bufsize - try: - opts, args = getopt.getopt(args, 'blts:') - except getopt.error as msg: - sys.stderr.write('%s: %s\n%s' % (sys.argv[0], msg, usage)) - return 2 - for o, a in opts: - if o == '-l': - fnfilter = os.path.basename - elif o == '-b': - rmode = 'rb' - elif o == '-t': - rmode = 'r' - elif o == '-s': - bufsize = int(a) - if not args: - args = ['-'] - return sum(args, out) - -if __name__ == '__main__' or __name__ == sys.argv[0]: - sys.exit(main(sys.argv[1:], sys.stdout)) diff --git a/Tools/scripts/mkreal.py b/Tools/scripts/mkreal.py deleted file mode 100755 index f169da43..00000000 --- a/Tools/scripts/mkreal.py +++ /dev/null @@ -1,65 +0,0 @@ -#! /usr/bin/env python3 - -# mkreal -# -# turn a symlink to a directory into a real directory - -import sys -import os -from stat import * - -join = os.path.join - -error = 'mkreal error' - -BUFSIZE = 32*1024 - -def mkrealfile(name): - st = os.stat(name) # Get the mode - mode = S_IMODE(st[ST_MODE]) - linkto = os.readlink(name) # Make sure again it's a symlink - with open(name, 'rb') as f_in: # This ensures it's a file - os.unlink(name) - with open(name, 'wb') as f_out: - while 1: - buf = f_in.read(BUFSIZE) - if not buf: break - f_out.write(buf) - os.chmod(name, mode) - -def mkrealdir(name): - st = os.stat(name) # Get the mode - mode = S_IMODE(st[ST_MODE]) - linkto = os.readlink(name) - files = os.listdir(name) - os.unlink(name) - os.mkdir(name, mode) - os.chmod(name, mode) - linkto = join(os.pardir, linkto) - # - for filename in files: - if filename not in (os.curdir, os.pardir): - os.symlink(join(linkto, filename), join(name, filename)) - -def main(): - sys.stdout = sys.stderr - progname = os.path.basename(sys.argv[0]) - if progname == '-c': progname = 'mkreal' - args = sys.argv[1:] - if not args: - print('usage:', progname, 'path ...') - sys.exit(2) - status = 0 - for name in args: - if not os.path.islink(name): - print(progname+':', name+':', 'not a symlink') - status = 1 - else: - if os.path.isdir(name): - mkrealdir(name) - else: - mkrealfile(name) - sys.exit(status) - -if __name__ == '__main__': - main() diff --git a/Tools/scripts/nm2def.py b/Tools/scripts/nm2def.py deleted file mode 100755 index a885ebd6..00000000 --- a/Tools/scripts/nm2def.py +++ /dev/null @@ -1,104 +0,0 @@ -#! /usr/bin/env python3 -"""nm2def.py - -Helpers to extract symbols from Unix libs and auto-generate -Windows definition files from them. Depends on nm(1). Tested -on Linux and Solaris only (-p option to nm is for Solaris only). - -By Marc-Andre Lemburg, Aug 1998. - -Additional notes: the output of nm is supposed to look like this: - -acceler.o: -000001fd T PyGrammar_AddAccelerators - U PyGrammar_FindDFA -00000237 T PyGrammar_RemoveAccelerators - U _IO_stderr_ - U exit - U fprintf - U free - U malloc - U printf - -grammar1.o: -00000000 T PyGrammar_FindDFA -00000034 T PyGrammar_LabelRepr - U _PyParser_TokenNames - U abort - U printf - U sprintf - -... - -Even if this isn't the default output of your nm, there is generally an -option to produce this format (since it is the original v7 Unix format). - -""" -import os, sys - -PYTHONLIB = 'libpython%d.%d.a' % sys.version_info[:2] -PC_PYTHONLIB = 'Python%d%d.dll' % sys.version_info[:2] -NM = 'nm -p -g %s' # For Linux, use "nm -g %s" - -def symbols(lib=PYTHONLIB,types=('T','C','D')): - - with os.popen(NM % lib) as pipe: - lines = pipe.readlines() - lines = [s.strip() for s in lines] - symbols = {} - for line in lines: - if len(line) == 0 or ':' in line: - continue - items = line.split() - if len(items) != 3: - continue - address, type, name = items - if type not in types: - continue - symbols[name] = address,type - return symbols - -def export_list(symbols): - - data = [] - code = [] - for name,(addr,type) in symbols.items(): - if type in ('C','D'): - data.append('\t'+name) - else: - code.append('\t'+name) - data.sort() - data.append('') - code.sort() - return ' DATA\n'.join(data)+'\n'+'\n'.join(code) - -# Definition file template -DEF_TEMPLATE = """\ -EXPORTS -%s -""" - -# Special symbols that have to be included even though they don't -# pass the filter -SPECIALS = ( - ) - -def filter_Python(symbols,specials=SPECIALS): - - for name in list(symbols.keys()): - if name[:2] == 'Py' or name[:3] == '_Py': - pass - elif name not in specials: - del symbols[name] - -def main(): - - s = symbols(PYTHONLIB) - filter_Python(s) - exports = export_list(s) - f = sys.stdout # open('PC/python_nt.def','w') - f.write(DEF_TEMPLATE % (exports)) - # f.close() - -if __name__ == '__main__': - main() diff --git a/Tools/scripts/objgraph.py b/Tools/scripts/objgraph.py deleted file mode 100755 index add41e69..00000000 --- a/Tools/scripts/objgraph.py +++ /dev/null @@ -1,211 +0,0 @@ -#! /usr/bin/env python3 - -# objgraph -# -# Read "nm -o" input of a set of libraries or modules and print various -# interesting listings, such as: -# -# - which names are used but not defined in the set (and used where), -# - which names are defined in the set (and where), -# - which modules use which other modules, -# - which modules are used by which other modules. -# -# Usage: objgraph [-cdu] [file] ... -# -c: print callers per objectfile -# -d: print callees per objectfile -# -u: print usage of undefined symbols -# If none of -cdu is specified, all are assumed. -# Use "nm -o" to generate the input -# e.g.: nm -o /lib/libc.a | objgraph - - -import sys -import os -import getopt -import re - -# Types of symbols. -# -definitions = 'TRGDSBAEC' -externals = 'UV' -ignore = 'Nntrgdsbavuc' - -# Regular expression to parse "nm -o" output. -# -matcher = re.compile('(.*):\t?........ (.) (.*)$') - -# Store "item" in "dict" under "key". -# The dictionary maps keys to lists of items. -# If there is no list for the key yet, it is created. -# -def store(dict, key, item): - if key in dict: - dict[key].append(item) - else: - dict[key] = [item] - -# Return a flattened version of a list of strings: the concatenation -# of its elements with intervening spaces. -# -def flat(list): - s = '' - for item in list: - s = s + ' ' + item - return s[1:] - -# Global variables mapping defined/undefined names to files and back. -# -file2undef = {} -def2file = {} -file2def = {} -undef2file = {} - -# Read one input file and merge the data into the tables. -# Argument is an open file. -# -def readinput(fp): - while 1: - s = fp.readline() - if not s: - break - # If you get any output from this line, - # it is probably caused by an unexpected input line: - if matcher.search(s) < 0: s; continue # Shouldn't happen - (ra, rb), (r1a, r1b), (r2a, r2b), (r3a, r3b) = matcher.regs[:4] - fn, name, type = s[r1a:r1b], s[r3a:r3b], s[r2a:r2b] - if type in definitions: - store(def2file, name, fn) - store(file2def, fn, name) - elif type in externals: - store(file2undef, fn, name) - store(undef2file, name, fn) - elif not type in ignore: - print(fn + ':' + name + ': unknown type ' + type) - -# Print all names that were undefined in some module and where they are -# defined. -# -def printcallee(): - flist = sorted(file2undef.keys()) - for filename in flist: - print(filename + ':') - elist = file2undef[filename] - elist.sort() - for ext in elist: - if len(ext) >= 8: - tabs = '\t' - else: - tabs = '\t\t' - if ext not in def2file: - print('\t' + ext + tabs + ' *undefined') - else: - print('\t' + ext + tabs + flat(def2file[ext])) - -# Print for each module the names of the other modules that use it. -# -def printcaller(): - files = sorted(file2def.keys()) - for filename in files: - callers = [] - for label in file2def[filename]: - if label in undef2file: - callers = callers + undef2file[label] - if callers: - callers.sort() - print(filename + ':') - lastfn = '' - for fn in callers: - if fn != lastfn: - print('\t' + fn) - lastfn = fn - else: - print(filename + ': unused') - -# Print undefined names and where they are used. -# -def printundef(): - undefs = {} - for filename in list(file2undef.keys()): - for ext in file2undef[filename]: - if ext not in def2file: - store(undefs, ext, filename) - elist = sorted(undefs.keys()) - for ext in elist: - print(ext + ':') - flist = sorted(undefs[ext]) - for filename in flist: - print('\t' + filename) - -# Print warning messages about names defined in more than one file. -# -def warndups(): - savestdout = sys.stdout - sys.stdout = sys.stderr - names = sorted(def2file.keys()) - for name in names: - if len(def2file[name]) > 1: - print('warning:', name, 'multiply defined:', end=' ') - print(flat(def2file[name])) - sys.stdout = savestdout - -# Main program -# -def main(): - try: - optlist, args = getopt.getopt(sys.argv[1:], 'cdu') - except getopt.error: - sys.stdout = sys.stderr - print('Usage:', os.path.basename(sys.argv[0]), end=' ') - print('[-cdu] [file] ...') - print('-c: print callers per objectfile') - print('-d: print callees per objectfile') - print('-u: print usage of undefined symbols') - print('If none of -cdu is specified, all are assumed.') - print('Use "nm -o" to generate the input') - print('e.g.: nm -o /lib/libc.a | objgraph') - return 1 - optu = optc = optd = 0 - for opt, void in optlist: - if opt == '-u': - optu = 1 - elif opt == '-c': - optc = 1 - elif opt == '-d': - optd = 1 - if optu == optc == optd == 0: - optu = optc = optd = 1 - if not args: - args = ['-'] - for filename in args: - if filename == '-': - readinput(sys.stdin) - else: - with open(filename) as f: - readinput(f) - # - warndups() - # - more = (optu + optc + optd > 1) - if optd: - if more: - print('---------------All callees------------------') - printcallee() - if optu: - if more: - print('---------------Undefined callees------------') - printundef() - if optc: - if more: - print('---------------All Callers------------------') - printcaller() - return 0 - -# Call the main program. -# Use its return value as exit status. -# Catch interrupts to avoid stack trace. -# -if __name__ == '__main__': - try: - sys.exit(main()) - except KeyboardInterrupt: - sys.exit(1) diff --git a/Tools/scripts/parseentities.py b/Tools/scripts/parseentities.py deleted file mode 100755 index 0229d3af..00000000 --- a/Tools/scripts/parseentities.py +++ /dev/null @@ -1,64 +0,0 @@ -#!/usr/bin/env python3 -""" Utility for parsing HTML entity definitions available from: - - http://www.w3.org/ as e.g. - http://www.w3.org/TR/REC-html40/HTMLlat1.ent - - Input is read from stdin, output is written to stdout in form of a - Python snippet defining a dictionary "entitydefs" mapping literal - entity name to character or numeric entity. - - Marc-Andre Lemburg, mal@lemburg.com, 1999. - Use as you like. NO WARRANTIES. - -""" -import re,sys - -entityRE = re.compile(r'') - -def parse(text,pos=0,endpos=None): - - pos = 0 - if endpos is None: - endpos = len(text) - d = {} - while 1: - m = entityRE.search(text,pos,endpos) - if not m: - break - name,charcode,comment = m.groups() - d[name] = charcode,comment - pos = m.end() - return d - -def writefile(f,defs): - - f.write("entitydefs = {\n") - items = sorted(defs.items()) - for name, (charcode,comment) in items: - if charcode[:2] == '&#': - code = int(charcode[2:-1]) - if code < 256: - charcode = r"'\%o'" % code - else: - charcode = repr(charcode) - else: - charcode = repr(charcode) - comment = ' '.join(comment.split()) - f.write(" '%s':\t%s, \t# %s\n" % (name,charcode,comment)) - f.write('\n}\n') - -if __name__ == '__main__': - if len(sys.argv) > 1: - with open(sys.argv[1]) as infile: - text = infile.read() - else: - text = sys.stdin.read() - - defs = parse(text) - - if len(sys.argv) > 2: - with open(sys.argv[2],'w') as outfile: - writefile(outfile, defs) - else: - writefile(sys.stdout, defs) diff --git a/Tools/scripts/pathfix.py b/Tools/scripts/pathfix.py deleted file mode 100755 index d252321a..00000000 --- a/Tools/scripts/pathfix.py +++ /dev/null @@ -1,226 +0,0 @@ -#!/usr/bin/env python3 - -# Change the #! line (shebang) occurring in Python scripts. The new interpreter -# pathname must be given with a -i option. -# -# Command line arguments are files or directories to be processed. -# Directories are searched recursively for files whose name looks -# like a python module. -# Symbolic links are always ignored (except as explicit directory -# arguments). -# The original file is kept as a back-up (with a "~" attached to its name), -# -n flag can be used to disable this. - -# Sometimes you may find shebangs with flags such as `#! /usr/bin/env python -si`. -# Normally, pathfix overwrites the entire line, including the flags. -# To change interpreter and keep flags from the original shebang line, use -k. -# If you want to keep flags and add to them one single literal flag, use option -a. - - -# Undoubtedly you can do this using find and sed or perl, but this is -# a nice example of Python code that recurses down a directory tree -# and uses regular expressions. Also note several subtleties like -# preserving the file's mode and avoiding to even write a temp file -# when no changes are needed for a file. -# -# NB: by changing only the function fixfile() you can turn this -# into a program for a different change to Python programs... - -import sys -import re -import os -from stat import * -import getopt - -err = sys.stderr.write -dbg = err -rep = sys.stdout.write - -new_interpreter = None -preserve_timestamps = False -create_backup = True -keep_flags = False -add_flags = b'' - - -def main(): - global new_interpreter - global preserve_timestamps - global create_backup - global keep_flags - global add_flags - - usage = ('usage: %s -i /interpreter -p -n -k -a file-or-directory ...\n' % - sys.argv[0]) - try: - opts, args = getopt.getopt(sys.argv[1:], 'i:a:kpn') - except getopt.error as msg: - err(str(msg) + '\n') - err(usage) - sys.exit(2) - for o, a in opts: - if o == '-i': - new_interpreter = a.encode() - if o == '-p': - preserve_timestamps = True - if o == '-n': - create_backup = False - if o == '-k': - keep_flags = True - if o == '-a': - add_flags = a.encode() - if b' ' in add_flags: - err("-a option doesn't support whitespaces") - sys.exit(2) - if not new_interpreter or not new_interpreter.startswith(b'/') or \ - not args: - err('-i option or file-or-directory missing\n') - err(usage) - sys.exit(2) - bad = 0 - for arg in args: - if os.path.isdir(arg): - if recursedown(arg): bad = 1 - elif os.path.islink(arg): - err(arg + ': will not process symbolic links\n') - bad = 1 - else: - if fix(arg): bad = 1 - sys.exit(bad) - - -def ispython(name): - return name.endswith('.py') - - -def recursedown(dirname): - dbg('recursedown(%r)\n' % (dirname,)) - bad = 0 - try: - names = os.listdir(dirname) - except OSError as msg: - err('%s: cannot list directory: %r\n' % (dirname, msg)) - return 1 - names.sort() - subdirs = [] - for name in names: - if name in (os.curdir, os.pardir): continue - fullname = os.path.join(dirname, name) - if os.path.islink(fullname): pass - elif os.path.isdir(fullname): - subdirs.append(fullname) - elif ispython(name): - if fix(fullname): bad = 1 - for fullname in subdirs: - if recursedown(fullname): bad = 1 - return bad - - -def fix(filename): -## dbg('fix(%r)\n' % (filename,)) - try: - f = open(filename, 'rb') - except IOError as msg: - err('%s: cannot open: %r\n' % (filename, msg)) - return 1 - with f: - line = f.readline() - fixed = fixline(line) - if line == fixed: - rep(filename+': no change\n') - return - head, tail = os.path.split(filename) - tempname = os.path.join(head, '@' + tail) - try: - g = open(tempname, 'wb') - except IOError as msg: - err('%s: cannot create: %r\n' % (tempname, msg)) - return 1 - with g: - rep(filename + ': updating\n') - g.write(fixed) - BUFSIZE = 8*1024 - while 1: - buf = f.read(BUFSIZE) - if not buf: break - g.write(buf) - - # Finishing touch -- move files - - mtime = None - atime = None - # First copy the file's mode to the temp file - try: - statbuf = os.stat(filename) - mtime = statbuf.st_mtime - atime = statbuf.st_atime - os.chmod(tempname, statbuf[ST_MODE] & 0o7777) - except OSError as msg: - err('%s: warning: chmod failed (%r)\n' % (tempname, msg)) - # Then make a backup of the original file as filename~ - if create_backup: - try: - os.rename(filename, filename + '~') - except OSError as msg: - err('%s: warning: backup failed (%r)\n' % (filename, msg)) - else: - try: - os.remove(filename) - except OSError as msg: - err('%s: warning: removing failed (%r)\n' % (filename, msg)) - # Now move the temp file to the original file - try: - os.rename(tempname, filename) - except OSError as msg: - err('%s: rename failed (%r)\n' % (filename, msg)) - return 1 - if preserve_timestamps: - if atime and mtime: - try: - os.utime(filename, (atime, mtime)) - except OSError as msg: - err('%s: reset of timestamp failed (%r)\n' % (filename, msg)) - return 1 - # Return success - return 0 - - -def parse_shebang(shebangline): - shebangline = shebangline.rstrip(b'\n') - start = shebangline.find(b' -') - if start == -1: - return b'' - return shebangline[start:] - - -def populate_flags(shebangline): - old_flags = b'' - if keep_flags: - old_flags = parse_shebang(shebangline) - if old_flags: - old_flags = old_flags[2:] - if not (old_flags or add_flags): - return b'' - # On Linux, the entire string following the interpreter name - # is passed as a single argument to the interpreter. - # e.g. "#! /usr/bin/python3 -W Error -s" runs "/usr/bin/python3 "-W Error -s" - # so shebang should have single '-' where flags are given and - # flag might need argument for that reasons adding new flags is - # between '-' and original flags - # e.g. #! /usr/bin/python3 -sW Error - return b' -' + add_flags + old_flags - - -def fixline(line): - if not line.startswith(b'#!'): - return line - - if b"python" not in line: - return line - - flags = populate_flags(line) - return b'#! ' + new_interpreter + flags + b'\n' - - -if __name__ == '__main__': - main() diff --git a/Tools/scripts/pdeps.py b/Tools/scripts/pdeps.py deleted file mode 100755 index ab0040f4..00000000 --- a/Tools/scripts/pdeps.py +++ /dev/null @@ -1,164 +0,0 @@ -#! /usr/bin/env python3 - -# pdeps -# -# Find dependencies between a bunch of Python modules. -# -# Usage: -# pdeps file1.py file2.py ... -# -# Output: -# Four tables separated by lines like '--- Closure ---': -# 1) Direct dependencies, listing which module imports which other modules -# 2) The inverse of (1) -# 3) Indirect dependencies, or the closure of the above -# 4) The inverse of (3) -# -# To do: -# - command line options to select output type -# - option to automatically scan the Python library for referenced modules -# - option to limit output to particular modules - - -import sys -import re -import os - - -# Main program -# -def main(): - args = sys.argv[1:] - if not args: - print('usage: pdeps file.py file.py ...') - return 2 - # - table = {} - for arg in args: - process(arg, table) - # - print('--- Uses ---') - printresults(table) - # - print('--- Used By ---') - inv = inverse(table) - printresults(inv) - # - print('--- Closure of Uses ---') - reach = closure(table) - printresults(reach) - # - print('--- Closure of Used By ---') - invreach = inverse(reach) - printresults(invreach) - # - return 0 - - -# Compiled regular expressions to search for import statements -# -m_import = re.compile('^[ \t]*from[ \t]+([^ \t]+)[ \t]+') -m_from = re.compile('^[ \t]*import[ \t]+([^#]+)') - - -# Collect data from one file -# -def process(filename, table): - with open(filename, encoding='utf-8') as fp: - mod = os.path.basename(filename) - if mod[-3:] == '.py': - mod = mod[:-3] - table[mod] = list = [] - while 1: - line = fp.readline() - if not line: break - while line[-1:] == '\\': - nextline = fp.readline() - if not nextline: break - line = line[:-1] + nextline - m_found = m_import.match(line) or m_from.match(line) - if m_found: - (a, b), (a1, b1) = m_found.regs[:2] - else: continue - words = line[a1:b1].split(',') - # print '#', line, words - for word in words: - word = word.strip() - if word not in list: - list.append(word) - - -# Compute closure (this is in fact totally general) -# -def closure(table): - modules = list(table.keys()) - # - # Initialize reach with a copy of table - # - reach = {} - for mod in modules: - reach[mod] = table[mod][:] - # - # Iterate until no more change - # - change = 1 - while change: - change = 0 - for mod in modules: - for mo in reach[mod]: - if mo in modules: - for m in reach[mo]: - if m not in reach[mod]: - reach[mod].append(m) - change = 1 - # - return reach - - -# Invert a table (this is again totally general). -# All keys of the original table are made keys of the inverse, -# so there may be empty lists in the inverse. -# -def inverse(table): - inv = {} - for key in table.keys(): - if key not in inv: - inv[key] = [] - for item in table[key]: - store(inv, item, key) - return inv - - -# Store "item" in "dict" under "key". -# The dictionary maps keys to lists of items. -# If there is no list for the key yet, it is created. -# -def store(dict, key, item): - if key in dict: - dict[key].append(item) - else: - dict[key] = [item] - - -# Tabulate results neatly -# -def printresults(table): - modules = sorted(table.keys()) - maxlen = 0 - for mod in modules: maxlen = max(maxlen, len(mod)) - for mod in modules: - list = sorted(table[mod]) - print(mod.ljust(maxlen), ':', end=' ') - if mod in list: - print('(*)', end=' ') - for ref in list: - print(ref, end=' ') - print() - - -# Call main and honor exit status -if __name__ == '__main__': - try: - sys.exit(main()) - except KeyboardInterrupt: - sys.exit(1) diff --git a/Tools/scripts/pep384_macrocheck.py b/Tools/scripts/pep384_macrocheck.py deleted file mode 100644 index ab9dd7c9..00000000 --- a/Tools/scripts/pep384_macrocheck.py +++ /dev/null @@ -1,148 +0,0 @@ -""" -pep384_macrocheck.py - -This program tries to locate errors in the relevant Python header -files where macros access type fields when they are reachable from -the limited API. - -The idea is to search macros with the string "->tp_" in it. -When the macro name does not begin with an underscore, -then we have found a dormant error. - -Christian Tismer -2018-06-02 -""" - -import sys -import os -import re - - -DEBUG = False - -def dprint(*args, **kw): - if DEBUG: - print(*args, **kw) - -def parse_headerfiles(startpath): - """ - Scan all header files which are reachable fronm Python.h - """ - search = "Python.h" - name = os.path.join(startpath, search) - if not os.path.exists(name): - raise ValueError("file {} was not found in {}\n" - "Please give the path to Python's include directory." - .format(search, startpath)) - errors = 0 - with open(name) as python_h: - while True: - line = python_h.readline() - if not line: - break - found = re.match(r'^\s*#\s*include\s*"(\w+\.h)"', line) - if not found: - continue - include = found.group(1) - dprint("Scanning", include) - name = os.path.join(startpath, include) - if not os.path.exists(name): - name = os.path.join(startpath, "../PC", include) - errors += parse_file(name) - return errors - -def ifdef_level_gen(): - """ - Scan lines for #ifdef and track the level. - """ - level = 0 - ifdef_pattern = r"^\s*#\s*if" # covers ifdef and ifndef as well - endif_pattern = r"^\s*#\s*endif" - while True: - line = yield level - if re.match(ifdef_pattern, line): - level += 1 - elif re.match(endif_pattern, line): - level -= 1 - -def limited_gen(): - """ - Scan lines for Py_LIMITED_API yes(1) no(-1) or nothing (0) - """ - limited = [0] # nothing - unlimited_pattern = r"^\s*#\s*ifndef\s+Py_LIMITED_API" - limited_pattern = "|".join([ - r"^\s*#\s*ifdef\s+Py_LIMITED_API", - r"^\s*#\s*(el)?if\s+!\s*defined\s*\(\s*Py_LIMITED_API\s*\)\s*\|\|", - r"^\s*#\s*(el)?if\s+defined\s*\(\s*Py_LIMITED_API" - ]) - else_pattern = r"^\s*#\s*else" - ifdef_level = ifdef_level_gen() - status = next(ifdef_level) - wait_for = -1 - while True: - line = yield limited[-1] - new_status = ifdef_level.send(line) - dir = new_status - status - status = new_status - if dir == 1: - if re.match(unlimited_pattern, line): - limited.append(-1) - wait_for = status - 1 - elif re.match(limited_pattern, line): - limited.append(1) - wait_for = status - 1 - elif dir == -1: - # this must have been an endif - if status == wait_for: - limited.pop() - wait_for = -1 - else: - # it could be that we have an elif - if re.match(limited_pattern, line): - limited.append(1) - wait_for = status - 1 - elif re.match(else_pattern, line): - limited.append(-limited.pop()) # negate top - -def parse_file(fname): - errors = 0 - with open(fname) as f: - lines = f.readlines() - type_pattern = r"^.*?->\s*tp_" - define_pattern = r"^\s*#\s*define\s+(\w+)" - limited = limited_gen() - status = next(limited) - for nr, line in enumerate(lines): - status = limited.send(line) - line = line.rstrip() - dprint(fname, nr, status, line) - if status != -1: - if re.match(define_pattern, line): - name = re.match(define_pattern, line).group(1) - if not name.startswith("_"): - # found a candidate, check it! - macro = line + "\n" - idx = nr - while line.endswith("\\"): - idx += 1 - line = lines[idx].rstrip() - macro += line + "\n" - if re.match(type_pattern, macro, re.DOTALL): - # this type field can reach the limited API - report(fname, nr + 1, macro) - errors += 1 - return errors - -def report(fname, nr, macro): - f = sys.stderr - print(fname + ":" + str(nr), file=f) - print(macro, file=f) - -if __name__ == "__main__": - p = sys.argv[1] if sys.argv[1:] else "../../Include" - errors = parse_headerfiles(p) - if errors: - # somehow it makes sense to raise a TypeError :-) - raise TypeError("These {} locations contradict the limited API." - .format(errors)) diff --git a/Tools/scripts/pickle2db.py b/Tools/scripts/pickle2db.py deleted file mode 100755 index b5b65718..00000000 --- a/Tools/scripts/pickle2db.py +++ /dev/null @@ -1,147 +0,0 @@ -#!/usr/bin/env python3 - -""" -Synopsis: %(prog)s [-h|-b|-g|-r|-a|-d] [ picklefile ] dbfile - -Read the given picklefile as a series of key/value pairs and write to a new -database. If the database already exists, any contents are deleted. The -optional flags indicate the type of the output database: - - -a - open using dbm (open any supported format) - -b - open as bsddb btree file - -d - open as dbm.ndbm file - -g - open as dbm.gnu file - -h - open as bsddb hash file - -r - open as bsddb recno file - -The default is hash. If a pickle file is named it is opened for read -access. If no pickle file is named, the pickle input is read from standard -input. - -Note that recno databases can only contain integer keys, so you can't dump a -hash or btree database using db2pickle.py and reconstitute it to a recno -database with %(prog)s unless your keys are integers. - -""" - -import getopt -try: - import bsddb -except ImportError: - bsddb = None -try: - import dbm.ndbm as dbm -except ImportError: - dbm = None -try: - import dbm.gnu as gdbm -except ImportError: - gdbm = None -try: - import dbm.ndbm as anydbm -except ImportError: - anydbm = None -import sys -try: - import pickle as pickle -except ImportError: - import pickle - -prog = sys.argv[0] - -def usage(): - sys.stderr.write(__doc__ % globals()) - -def main(args): - try: - opts, args = getopt.getopt(args, "hbrdag", - ["hash", "btree", "recno", "dbm", "anydbm", - "gdbm"]) - except getopt.error: - usage() - return 1 - - if len(args) == 0 or len(args) > 2: - usage() - return 1 - elif len(args) == 1: - pfile = sys.stdin - dbfile = args[0] - else: - try: - pfile = open(args[0], 'rb') - except IOError: - sys.stderr.write("Unable to open %s\n" % args[0]) - return 1 - dbfile = args[1] - - dbopen = None - for opt, arg in opts: - if opt in ("-h", "--hash"): - try: - dbopen = bsddb.hashopen - except AttributeError: - sys.stderr.write("bsddb module unavailable.\n") - return 1 - elif opt in ("-b", "--btree"): - try: - dbopen = bsddb.btopen - except AttributeError: - sys.stderr.write("bsddb module unavailable.\n") - return 1 - elif opt in ("-r", "--recno"): - try: - dbopen = bsddb.rnopen - except AttributeError: - sys.stderr.write("bsddb module unavailable.\n") - return 1 - elif opt in ("-a", "--anydbm"): - try: - dbopen = anydbm.open - except AttributeError: - sys.stderr.write("dbm module unavailable.\n") - return 1 - elif opt in ("-g", "--gdbm"): - try: - dbopen = gdbm.open - except AttributeError: - sys.stderr.write("dbm.gnu module unavailable.\n") - return 1 - elif opt in ("-d", "--dbm"): - try: - dbopen = dbm.open - except AttributeError: - sys.stderr.write("dbm.ndbm module unavailable.\n") - return 1 - if dbopen is None: - if bsddb is None: - sys.stderr.write("bsddb module unavailable - ") - sys.stderr.write("must specify dbtype.\n") - return 1 - else: - dbopen = bsddb.hashopen - - try: - db = dbopen(dbfile, 'c') - except bsddb.error: - sys.stderr.write("Unable to open %s. " % dbfile) - sys.stderr.write("Check for format or version mismatch.\n") - return 1 - else: - for k in list(db.keys()): - del db[k] - - while 1: - try: - (key, val) = pickle.load(pfile) - except EOFError: - break - db[key] = val - - db.close() - pfile.close() - - return 0 - -if __name__ == "__main__": - sys.exit(main(sys.argv[1:])) diff --git a/Tools/scripts/pindent.py b/Tools/scripts/pindent.py deleted file mode 100755 index 33334204..00000000 --- a/Tools/scripts/pindent.py +++ /dev/null @@ -1,506 +0,0 @@ -#! /usr/bin/env python3 - -# This file contains a class and a main program that perform three -# related (though complimentary) formatting operations on Python -# programs. When called as "pindent -c", it takes a valid Python -# program as input and outputs a version augmented with block-closing -# comments. When called as "pindent -d", it assumes its input is a -# Python program with block-closing comments and outputs a commentless -# version. When called as "pindent -r" it assumes its input is a -# Python program with block-closing comments but with its indentation -# messed up, and outputs a properly indented version. - -# A "block-closing comment" is a comment of the form '# end ' -# where is the keyword that opened the block. If the -# opening keyword is 'def' or 'class', the function or class name may -# be repeated in the block-closing comment as well. Here is an -# example of a program fully augmented with block-closing comments: - -# def foobar(a, b): -# if a == b: -# a = a+1 -# elif a < b: -# b = b-1 -# if b > a: a = a-1 -# # end if -# else: -# print 'oops!' -# # end if -# # end def foobar - -# Note that only the last part of an if...elif...else... block needs a -# block-closing comment; the same is true for other compound -# statements (e.g. try...except). Also note that "short-form" blocks -# like the second 'if' in the example must be closed as well; -# otherwise the 'else' in the example would be ambiguous (remember -# that indentation is not significant when interpreting block-closing -# comments). - -# The operations are idempotent (i.e. applied to their own output -# they yield an identical result). Running first "pindent -c" and -# then "pindent -r" on a valid Python program produces a program that -# is semantically identical to the input (though its indentation may -# be different). Running "pindent -e" on that output produces a -# program that only differs from the original in indentation. - -# Other options: -# -s stepsize: set the indentation step size (default 8) -# -t tabsize : set the number of spaces a tab character is worth (default 8) -# -e : expand TABs into spaces -# file ... : input file(s) (default standard input) -# The results always go to standard output - -# Caveats: -# - comments ending in a backslash will be mistaken for continued lines -# - continuations using backslash are always left unchanged -# - continuations inside parentheses are not extra indented by -r -# but must be indented for -c to work correctly (this breaks -# idempotency!) -# - continued lines inside triple-quoted strings are totally garbled - -# Secret feature: -# - On input, a block may also be closed with an "end statement" -- -# this is a block-closing comment without the '#' sign. - -# Possible improvements: -# - check syntax based on transitions in 'next' table -# - better error reporting -# - better error recovery -# - check identifier after class/def - -# The following wishes need a more complete tokenization of the source: -# - Don't get fooled by comments ending in backslash -# - reindent continuation lines indicated by backslash -# - handle continuation lines inside parentheses/braces/brackets -# - handle triple quoted strings spanning lines -# - realign comments -# - optionally do much more thorough reformatting, a la C indent - -# Defaults -STEPSIZE = 8 -TABSIZE = 8 -EXPANDTABS = False - -import io -import re -import sys - -next = {} -next['if'] = next['elif'] = 'elif', 'else', 'end' -next['while'] = next['for'] = 'else', 'end' -next['try'] = 'except', 'finally' -next['except'] = 'except', 'else', 'finally', 'end' -next['else'] = next['finally'] = next['with'] = \ - next['def'] = next['class'] = 'end' -next['end'] = () -start = 'if', 'while', 'for', 'try', 'with', 'def', 'class' - -class PythonIndenter: - - def __init__(self, fpi = sys.stdin, fpo = sys.stdout, - indentsize = STEPSIZE, tabsize = TABSIZE, expandtabs = EXPANDTABS): - self.fpi = fpi - self.fpo = fpo - self.indentsize = indentsize - self.tabsize = tabsize - self.lineno = 0 - self.expandtabs = expandtabs - self._write = fpo.write - self.kwprog = re.compile( - r'^(?:\s|\\\n)*(?P[a-z]+)' - r'((?:\s|\\\n)+(?P[a-zA-Z_]\w*))?' - r'[^\w]') - self.endprog = re.compile( - r'^(?:\s|\\\n)*#?\s*end\s+(?P[a-z]+)' - r'(\s+(?P[a-zA-Z_]\w*))?' - r'[^\w]') - self.wsprog = re.compile(r'^[ \t]*') - # end def __init__ - - def write(self, line): - if self.expandtabs: - self._write(line.expandtabs(self.tabsize)) - else: - self._write(line) - # end if - # end def write - - def readline(self): - line = self.fpi.readline() - if line: self.lineno += 1 - # end if - return line - # end def readline - - def error(self, fmt, *args): - if args: fmt = fmt % args - # end if - sys.stderr.write('Error at line %d: %s\n' % (self.lineno, fmt)) - self.write('### %s ###\n' % fmt) - # end def error - - def getline(self): - line = self.readline() - while line[-2:] == '\\\n': - line2 = self.readline() - if not line2: break - # end if - line += line2 - # end while - return line - # end def getline - - def putline(self, line, indent): - tabs, spaces = divmod(indent*self.indentsize, self.tabsize) - i = self.wsprog.match(line).end() - line = line[i:] - if line[:1] not in ('\n', '\r', ''): - line = '\t'*tabs + ' '*spaces + line - # end if - self.write(line) - # end def putline - - def reformat(self): - stack = [] - while True: - line = self.getline() - if not line: break # EOF - # end if - m = self.endprog.match(line) - if m: - kw = 'end' - kw2 = m.group('kw') - if not stack: - self.error('unexpected end') - elif stack.pop()[0] != kw2: - self.error('unmatched end') - # end if - self.putline(line, len(stack)) - continue - # end if - m = self.kwprog.match(line) - if m: - kw = m.group('kw') - if kw in start: - self.putline(line, len(stack)) - stack.append((kw, kw)) - continue - # end if - if kw in next and stack: - self.putline(line, len(stack)-1) - kwa, kwb = stack[-1] - stack[-1] = kwa, kw - continue - # end if - # end if - self.putline(line, len(stack)) - # end while - if stack: - self.error('unterminated keywords') - for kwa, kwb in stack: - self.write('\t%s\n' % kwa) - # end for - # end if - # end def reformat - - def delete(self): - begin_counter = 0 - end_counter = 0 - while True: - line = self.getline() - if not line: break # EOF - # end if - m = self.endprog.match(line) - if m: - end_counter += 1 - continue - # end if - m = self.kwprog.match(line) - if m: - kw = m.group('kw') - if kw in start: - begin_counter += 1 - # end if - # end if - self.write(line) - # end while - if begin_counter - end_counter < 0: - sys.stderr.write('Warning: input contained more end tags than expected\n') - elif begin_counter - end_counter > 0: - sys.stderr.write('Warning: input contained less end tags than expected\n') - # end if - # end def delete - - def complete(self): - stack = [] - todo = [] - currentws = thisid = firstkw = lastkw = topid = '' - while True: - line = self.getline() - i = self.wsprog.match(line).end() - m = self.endprog.match(line) - if m: - thiskw = 'end' - endkw = m.group('kw') - thisid = m.group('id') - else: - m = self.kwprog.match(line) - if m: - thiskw = m.group('kw') - if thiskw not in next: - thiskw = '' - # end if - if thiskw in ('def', 'class'): - thisid = m.group('id') - else: - thisid = '' - # end if - elif line[i:i+1] in ('\n', '#'): - todo.append(line) - continue - else: - thiskw = '' - # end if - # end if - indentws = line[:i] - indent = len(indentws.expandtabs(self.tabsize)) - current = len(currentws.expandtabs(self.tabsize)) - while indent < current: - if firstkw: - if topid: - s = '# end %s %s\n' % ( - firstkw, topid) - else: - s = '# end %s\n' % firstkw - # end if - self.write(currentws + s) - firstkw = lastkw = '' - # end if - currentws, firstkw, lastkw, topid = stack.pop() - current = len(currentws.expandtabs(self.tabsize)) - # end while - if indent == current and firstkw: - if thiskw == 'end': - if endkw != firstkw: - self.error('mismatched end') - # end if - firstkw = lastkw = '' - elif not thiskw or thiskw in start: - if topid: - s = '# end %s %s\n' % ( - firstkw, topid) - else: - s = '# end %s\n' % firstkw - # end if - self.write(currentws + s) - firstkw = lastkw = topid = '' - # end if - # end if - if indent > current: - stack.append((currentws, firstkw, lastkw, topid)) - if thiskw and thiskw not in start: - # error - thiskw = '' - # end if - currentws, firstkw, lastkw, topid = \ - indentws, thiskw, thiskw, thisid - # end if - if thiskw: - if thiskw in start: - firstkw = lastkw = thiskw - topid = thisid - else: - lastkw = thiskw - # end if - # end if - for l in todo: self.write(l) - # end for - todo = [] - if not line: break - # end if - self.write(line) - # end while - # end def complete -# end class PythonIndenter - -# Simplified user interface -# - xxx_filter(input, output): read and write file objects -# - xxx_string(s): take and return string object -# - xxx_file(filename): process file in place, return true iff changed - -def complete_filter(input = sys.stdin, output = sys.stdout, - stepsize = STEPSIZE, tabsize = TABSIZE, expandtabs = EXPANDTABS): - pi = PythonIndenter(input, output, stepsize, tabsize, expandtabs) - pi.complete() -# end def complete_filter - -def delete_filter(input= sys.stdin, output = sys.stdout, - stepsize = STEPSIZE, tabsize = TABSIZE, expandtabs = EXPANDTABS): - pi = PythonIndenter(input, output, stepsize, tabsize, expandtabs) - pi.delete() -# end def delete_filter - -def reformat_filter(input = sys.stdin, output = sys.stdout, - stepsize = STEPSIZE, tabsize = TABSIZE, expandtabs = EXPANDTABS): - pi = PythonIndenter(input, output, stepsize, tabsize, expandtabs) - pi.reformat() -# end def reformat_filter - -def complete_string(source, stepsize = STEPSIZE, tabsize = TABSIZE, expandtabs = EXPANDTABS): - input = io.StringIO(source) - output = io.StringIO() - pi = PythonIndenter(input, output, stepsize, tabsize, expandtabs) - pi.complete() - return output.getvalue() -# end def complete_string - -def delete_string(source, stepsize = STEPSIZE, tabsize = TABSIZE, expandtabs = EXPANDTABS): - input = io.StringIO(source) - output = io.StringIO() - pi = PythonIndenter(input, output, stepsize, tabsize, expandtabs) - pi.delete() - return output.getvalue() -# end def delete_string - -def reformat_string(source, stepsize = STEPSIZE, tabsize = TABSIZE, expandtabs = EXPANDTABS): - input = io.StringIO(source) - output = io.StringIO() - pi = PythonIndenter(input, output, stepsize, tabsize, expandtabs) - pi.reformat() - return output.getvalue() -# end def reformat_string - -def make_backup(filename): - import os, os.path - backup = filename + '~' - if os.path.lexists(backup): - try: - os.remove(backup) - except OSError: - print("Can't remove backup %r" % (backup,), file=sys.stderr) - # end try - # end if - try: - os.rename(filename, backup) - except OSError: - print("Can't rename %r to %r" % (filename, backup), file=sys.stderr) - # end try -# end def make_backup - -def complete_file(filename, stepsize = STEPSIZE, tabsize = TABSIZE, expandtabs = EXPANDTABS): - with open(filename, 'r') as f: - source = f.read() - # end with - result = complete_string(source, stepsize, tabsize, expandtabs) - if source == result: return 0 - # end if - make_backup(filename) - with open(filename, 'w') as f: - f.write(result) - # end with - return 1 -# end def complete_file - -def delete_file(filename, stepsize = STEPSIZE, tabsize = TABSIZE, expandtabs = EXPANDTABS): - with open(filename, 'r') as f: - source = f.read() - # end with - result = delete_string(source, stepsize, tabsize, expandtabs) - if source == result: return 0 - # end if - make_backup(filename) - with open(filename, 'w') as f: - f.write(result) - # end with - return 1 -# end def delete_file - -def reformat_file(filename, stepsize = STEPSIZE, tabsize = TABSIZE, expandtabs = EXPANDTABS): - with open(filename, 'r') as f: - source = f.read() - # end with - result = reformat_string(source, stepsize, tabsize, expandtabs) - if source == result: return 0 - # end if - make_backup(filename) - with open(filename, 'w') as f: - f.write(result) - # end with - return 1 -# end def reformat_file - -# Test program when called as a script - -usage = """ -usage: pindent (-c|-d|-r) [-s stepsize] [-t tabsize] [-e] [file] ... --c : complete a correctly indented program (add #end directives) --d : delete #end directives --r : reformat a completed program (use #end directives) --s stepsize: indentation step (default %(STEPSIZE)d) --t tabsize : the worth in spaces of a tab (default %(TABSIZE)d) --e : expand TABs into spaces (default OFF) -[file] ... : files are changed in place, with backups in file~ -If no files are specified or a single - is given, -the program acts as a filter (reads stdin, writes stdout). -""" % vars() - -def error_both(op1, op2): - sys.stderr.write('Error: You can not specify both '+op1+' and -'+op2[0]+' at the same time\n') - sys.stderr.write(usage) - sys.exit(2) -# end def error_both - -def test(): - import getopt - try: - opts, args = getopt.getopt(sys.argv[1:], 'cdrs:t:e') - except getopt.error as msg: - sys.stderr.write('Error: %s\n' % msg) - sys.stderr.write(usage) - sys.exit(2) - # end try - action = None - stepsize = STEPSIZE - tabsize = TABSIZE - expandtabs = EXPANDTABS - for o, a in opts: - if o == '-c': - if action: error_both(o, action) - # end if - action = 'complete' - elif o == '-d': - if action: error_both(o, action) - # end if - action = 'delete' - elif o == '-r': - if action: error_both(o, action) - # end if - action = 'reformat' - elif o == '-s': - stepsize = int(a) - elif o == '-t': - tabsize = int(a) - elif o == '-e': - expandtabs = True - # end if - # end for - if not action: - sys.stderr.write( - 'You must specify -c(omplete), -d(elete) or -r(eformat)\n') - sys.stderr.write(usage) - sys.exit(2) - # end if - if not args or args == ['-']: - action = eval(action + '_filter') - action(sys.stdin, sys.stdout, stepsize, tabsize, expandtabs) - else: - action = eval(action + '_file') - for filename in args: - action(filename, stepsize, tabsize, expandtabs) - # end for - # end if -# end def test - -if __name__ == '__main__': - test() -# end if diff --git a/Tools/scripts/ptags.py b/Tools/scripts/ptags.py deleted file mode 100755 index eedd4117..00000000 --- a/Tools/scripts/ptags.py +++ /dev/null @@ -1,54 +0,0 @@ -#! /usr/bin/env python3 - -# ptags -# -# Create a tags file for Python programs, usable with vi. -# Tagged are: -# - functions (even inside other defs or classes) -# - classes -# - filenames -# Warns about files it cannot open. -# No warnings about duplicate tags. - -import sys, re, os - -tags = [] # Modified global variable! - -def main(): - args = sys.argv[1:] - for filename in args: - treat_file(filename) - if tags: - with open('tags', 'w') as fp: - tags.sort() - for s in tags: fp.write(s) - - -expr = r'^[ \t]*(def|class)[ \t]+([a-zA-Z0-9_]+)[ \t]*[:\(]' -matcher = re.compile(expr) - -def treat_file(filename): - try: - fp = open(filename, 'r') - except: - sys.stderr.write('Cannot open %s\n' % filename) - return - with fp: - base = os.path.basename(filename) - if base[-3:] == '.py': - base = base[:-3] - s = base + '\t' + filename + '\t' + '1\n' - tags.append(s) - while 1: - line = fp.readline() - if not line: - break - m = matcher.match(line) - if m: - content = m.group(0) - name = m.group(2) - s = name + '\t' + filename + '\t/^' + content + '/\n' - tags.append(s) - -if __name__ == '__main__': - main() diff --git a/Tools/scripts/pysource.py b/Tools/scripts/pysource.py deleted file mode 100755 index 69e8e0df..00000000 --- a/Tools/scripts/pysource.py +++ /dev/null @@ -1,130 +0,0 @@ -#!/usr/bin/env python3 - -"""\ -List python source files. - -There are three functions to check whether a file is a Python source, listed -here with increasing complexity: - -- has_python_ext() checks whether a file name ends in '.py[w]'. -- look_like_python() checks whether the file is not binary and either has - the '.py[w]' extension or the first line contains the word 'python'. -- can_be_compiled() checks whether the file can be compiled by compile(). - -The file also must be of appropriate size - not bigger than a megabyte. - -walk_python_files() recursively lists all Python files under the given directories. -""" -__author__ = "Oleg Broytmann, Georg Brandl" - -__all__ = ["has_python_ext", "looks_like_python", "can_be_compiled", "walk_python_files"] - - -import os, re - -binary_re = re.compile(br'[\x00-\x08\x0E-\x1F\x7F]') - -debug = False - -def print_debug(msg): - if debug: print(msg) - - -def _open(fullpath): - try: - size = os.stat(fullpath).st_size - except OSError as err: # Permission denied - ignore the file - print_debug("%s: permission denied: %s" % (fullpath, err)) - return None - - if size > 1024*1024: # too big - print_debug("%s: the file is too big: %d bytes" % (fullpath, size)) - return None - - try: - return open(fullpath, "rb") - except IOError as err: # Access denied, or a special file - ignore it - print_debug("%s: access denied: %s" % (fullpath, err)) - return None - -def has_python_ext(fullpath): - return fullpath.endswith(".py") or fullpath.endswith(".pyw") - -def looks_like_python(fullpath): - infile = _open(fullpath) - if infile is None: - return False - - with infile: - line = infile.readline() - - if binary_re.search(line): - # file appears to be binary - print_debug("%s: appears to be binary" % fullpath) - return False - - if fullpath.endswith(".py") or fullpath.endswith(".pyw"): - return True - elif b"python" in line: - # disguised Python script (e.g. CGI) - return True - - return False - -def can_be_compiled(fullpath): - infile = _open(fullpath) - if infile is None: - return False - - with infile: - code = infile.read() - - try: - compile(code, fullpath, "exec") - except Exception as err: - print_debug("%s: cannot compile: %s" % (fullpath, err)) - return False - - return True - - -def walk_python_files(paths, is_python=looks_like_python, exclude_dirs=None): - """\ - Recursively yield all Python source files below the given paths. - - paths: a list of files and/or directories to be checked. - is_python: a function that takes a file name and checks whether it is a - Python source file - exclude_dirs: a list of directory base names that should be excluded in - the search - """ - if exclude_dirs is None: - exclude_dirs=[] - - for path in paths: - print_debug("testing: %s" % path) - if os.path.isfile(path): - if is_python(path): - yield path - elif os.path.isdir(path): - print_debug(" it is a directory") - for dirpath, dirnames, filenames in os.walk(path): - for exclude in exclude_dirs: - if exclude in dirnames: - dirnames.remove(exclude) - for filename in filenames: - fullpath = os.path.join(dirpath, filename) - print_debug("testing: %s" % fullpath) - if is_python(fullpath): - yield fullpath - else: - print_debug(" unknown type") - - -if __name__ == "__main__": - # Two simple examples/tests - for fullpath in walk_python_files(['.']): - print(fullpath) - print("----------") - for fullpath in walk_python_files(['.'], is_python=can_be_compiled): - print(fullpath) diff --git a/Tools/scripts/reindent-rst.py b/Tools/scripts/reindent-rst.py deleted file mode 100755 index 25608af6..00000000 --- a/Tools/scripts/reindent-rst.py +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env python3 - -# Make a reST file compliant to our pre-commit hook. -# Currently just remove trailing whitespace. - -import sys - -import patchcheck - -def main(argv=sys.argv): - patchcheck.normalize_docs_whitespace(argv[1:]) - -if __name__ == '__main__': - sys.exit(main()) diff --git a/Tools/scripts/rgrep.py b/Tools/scripts/rgrep.py deleted file mode 100755 index c39bf93a..00000000 --- a/Tools/scripts/rgrep.py +++ /dev/null @@ -1,67 +0,0 @@ -#! /usr/bin/env python3 - -"""Reverse grep. - -Usage: rgrep [-i] pattern file -""" - -import sys -import re -import getopt - - -def main(): - bufsize = 64 * 1024 - reflags = 0 - opts, args = getopt.getopt(sys.argv[1:], "i") - for o, a in opts: - if o == '-i': - reflags = reflags | re.IGNORECASE - if len(args) < 2: - usage("not enough arguments") - if len(args) > 2: - usage("exactly one file argument required") - pattern, filename = args - try: - prog = re.compile(pattern, reflags) - except re.error as msg: - usage("error in regular expression: %s" % msg) - try: - f = open(filename) - except IOError as msg: - usage("can't open %r: %s" % (filename, msg), 1) - with f: - f.seek(0, 2) - pos = f.tell() - leftover = None - while pos > 0: - size = min(pos, bufsize) - pos = pos - size - f.seek(pos) - buffer = f.read(size) - lines = buffer.split("\n") - del buffer - if leftover is None: - if not lines[-1]: - del lines[-1] - else: - lines[-1] = lines[-1] + leftover - if pos > 0: - leftover = lines[0] - del lines[0] - else: - leftover = None - for line in reversed(lines): - if prog.search(line): - print(line) - - -def usage(msg, code=2): - sys.stdout = sys.stderr - print(msg) - print(__doc__) - sys.exit(code) - - -if __name__ == '__main__': - main() diff --git a/Tools/scripts/startuptime.py b/Tools/scripts/startuptime.py deleted file mode 100644 index 1bb5b208..00000000 --- a/Tools/scripts/startuptime.py +++ /dev/null @@ -1,22 +0,0 @@ -# Quick script to time startup for various binaries - -import subprocess -import sys -import time - -NREPS = 100 - - -def main(): - binaries = sys.argv[1:] - for bin in binaries: - t0 = time.time() - for _ in range(NREPS): - result = subprocess.run([bin, "-c", "pass"]) - result.check_returncode() - t1 = time.time() - print(f"{(t1-t0)/NREPS:6.3f} {bin}") - - -if __name__ == "__main__": - main() diff --git a/Tools/scripts/suff.py b/Tools/scripts/suff.py deleted file mode 100755 index 0eea0d75..00000000 --- a/Tools/scripts/suff.py +++ /dev/null @@ -1,26 +0,0 @@ -#! /usr/bin/env python3 - -# suff -# -# show different suffixes amongst arguments - -import sys - - -def main(): - files = sys.argv[1:] - suffixes = {} - for filename in files: - suff = getsuffix(filename) - suffixes.setdefault(suff, []).append(filename) - for suff, filenames in sorted(suffixes.items()): - print(repr(suff), len(filenames)) - - -def getsuffix(filename): - name, sep, suff = filename.rpartition('.') - return sep + suff if sep else '' - - -if __name__ == '__main__': - main() diff --git a/Tools/scripts/summarize_stats.py b/Tools/scripts/summarize_stats.py index bc528ca3..9c881897 100644 --- a/Tools/scripts/summarize_stats.py +++ b/Tools/scripts/summarize_stats.py @@ -2,12 +2,14 @@ default stats folders. """ +import argparse import collections +import json import os.path import opcode from datetime import date import itertools -import argparse +import sys if os.name == "nt": DEFAULT_DIR = "c:\\temp\\py_stats\\" @@ -30,7 +32,104 @@ for name in opcode.opname[1:]: opmap = {name: i for i, name in enumerate(opname)} opmap = dict(sorted(opmap.items())) -TOTAL = "specialization.deferred", "specialization.hit", "specialization.miss", "execution_count" +TOTAL = "specialization.hit", "specialization.miss", "execution_count" + +def format_ratio(num, den): + """ + Format a ratio as a percentage. When the denominator is 0, returns the empty + string. + """ + if den == 0: + return "" + else: + return f"{num/den:.01%}" + +def join_rows(a_rows, b_rows): + """ + Joins two tables together, side-by-side, where the first column in each is a + common key. + """ + if len(a_rows) == 0 and len(b_rows) == 0: + return [] + + if len(a_rows): + a_ncols = list(set(len(x) for x in a_rows)) + if len(a_ncols) != 1: + raise ValueError("Table a is ragged") + + if len(b_rows): + b_ncols = list(set(len(x) for x in b_rows)) + if len(b_ncols) != 1: + raise ValueError("Table b is ragged") + + if len(a_rows) and len(b_rows) and a_ncols[0] != b_ncols[0]: + raise ValueError("Tables have different widths") + + if len(a_rows): + ncols = a_ncols[0] + else: + ncols = b_ncols[0] + + default = [""] * (ncols - 1) + a_data = {x[0]: x[1:] for x in a_rows} + b_data = {x[0]: x[1:] for x in b_rows} + + if len(a_data) != len(a_rows) or len(b_data) != len(b_rows): + raise ValueError("Duplicate keys") + + # To preserve ordering, use A's keys as is and then add any in B that aren't + # in A + keys = list(a_data.keys()) + [k for k in b_data.keys() if k not in a_data] + return [(k, *a_data.get(k, default), *b_data.get(k, default)) for k in keys] + +def calculate_specialization_stats(family_stats, total): + rows = [] + for key in sorted(family_stats): + if key.startswith("specialization.failure_kinds"): + continue + if key in ("specialization.hit", "specialization.miss"): + label = key[len("specialization."):] + elif key == "execution_count": + continue + elif key in ("specialization.success", "specialization.failure", "specializable"): + continue + elif key.startswith("pair"): + continue + else: + label = key + rows.append((f"{label:>12}", f"{family_stats[key]:>12}", format_ratio(family_stats[key], total))) + return rows + +def calculate_specialization_success_failure(family_stats): + total_attempts = 0 + for key in ("specialization.success", "specialization.failure"): + total_attempts += family_stats.get(key, 0) + rows = [] + if total_attempts: + for key in ("specialization.success", "specialization.failure"): + label = key[len("specialization."):] + label = label[0].upper() + label[1:] + val = family_stats.get(key, 0) + rows.append((label, val, format_ratio(val, total_attempts))) + return rows + +def calculate_specialization_failure_kinds(name, family_stats, defines): + total_failures = family_stats.get("specialization.failure", 0) + failure_kinds = [ 0 ] * 40 + for key in family_stats: + if not key.startswith("specialization.failure_kind"): + continue + _, index = key[:-1].split("[") + index = int(index) + failure_kinds[index] = family_stats[key] + failures = [(value, index) for (index, value) in enumerate(failure_kinds)] + failures.sort(reverse=True) + rows = [] + for value, index in failures: + if not value: + continue + rows.append((kind_to_text(index, defines, name), value, format_ratio(value, total_failures))) + return rows def print_specialization_stats(name, family_stats, defines): if "specializable" not in family_stats: @@ -39,60 +138,66 @@ def print_specialization_stats(name, family_stats, defines): if total == 0: return with Section(name, 3, f"specialization stats for {name} family"): - rows = [] - for key in sorted(family_stats): - if key.startswith("specialization.failure_kinds"): - continue - if key in ("specialization.hit", "specialization.miss"): - label = key[len("specialization."):] - elif key == "execution_count": - label = "unquickened" - elif key in ("specialization.success", "specialization.failure", "specializable"): - continue - elif key.startswith("pair"): - continue - else: - label = key - rows.append((f"{label:>12}", f"{family_stats[key]:>12}", f"{100*family_stats[key]/total:0.1f}%")) + rows = calculate_specialization_stats(family_stats, total) emit_table(("Kind", "Count", "Ratio"), rows) - print_title("Specialization attempts", 4) - total_attempts = 0 - for key in ("specialization.success", "specialization.failure"): - total_attempts += family_stats.get(key, 0) - rows = [] - for key in ("specialization.success", "specialization.failure"): - label = key[len("specialization."):] - label = label[0].upper() + label[1:] - val = family_stats.get(key, 0) - rows.append((label, val, f"{100*val/total_attempts:0.1f}%")) - emit_table(("", "Count:", "Ratio:"), rows) - total_failures = family_stats.get("specialization.failure", 0) - failure_kinds = [ 0 ] * 30 - for key in family_stats: - if not key.startswith("specialization.failure_kind"): - continue - _, index = key[:-1].split("[") - index = int(index) - failure_kinds[index] = family_stats[key] - failures = [(value, index) for (index, value) in enumerate(failure_kinds)] - failures.sort(reverse=True) - rows = [] - for value, index in failures: - if not value: - continue - rows.append((kind_to_text(index, defines, name), value, f"{100*value/total_failures:0.1f}%")) - emit_table(("Failure kind", "Count:", "Ratio:"), rows) - -def gather_stats(): - stats = collections.Counter() - for filename in os.listdir(DEFAULT_DIR): - with open(os.path.join(DEFAULT_DIR, filename)) as fd: - for line in fd: - key, value = line.split(":") - key = key.strip() - value = int(value) - stats[key] += value - return stats + rows = calculate_specialization_success_failure(family_stats) + if rows: + print_title("Specialization attempts", 4) + emit_table(("", "Count:", "Ratio:"), rows) + rows = calculate_specialization_failure_kinds(name, family_stats, defines) + emit_table(("Failure kind", "Count:", "Ratio:"), rows) + +def print_comparative_specialization_stats(name, base_family_stats, head_family_stats, defines): + if "specializable" not in base_family_stats: + return + + base_total = sum(base_family_stats.get(kind, 0) for kind in TOTAL) + head_total = sum(head_family_stats.get(kind, 0) for kind in TOTAL) + if base_total + head_total == 0: + return + with Section(name, 3, f"specialization stats for {name} family"): + base_rows = calculate_specialization_stats(base_family_stats, base_total) + head_rows = calculate_specialization_stats(head_family_stats, head_total) + emit_table( + ("Kind", "Base Count", "Base Ratio", "Head Count", "Head Ratio"), + join_rows(base_rows, head_rows) + ) + base_rows = calculate_specialization_success_failure(base_family_stats) + head_rows = calculate_specialization_success_failure(head_family_stats) + rows = join_rows(base_rows, head_rows) + if rows: + print_title("Specialization attempts", 4) + emit_table(("", "Base Count:", "Base Ratio:", "Head Count:", "Head Ratio:"), rows) + base_rows = calculate_specialization_failure_kinds(name, base_family_stats, defines) + head_rows = calculate_specialization_failure_kinds(name, head_family_stats, defines) + emit_table( + ("Failure kind", "Base Count:", "Base Ratio:", "Head Count:", "Head Ratio:"), + join_rows(base_rows, head_rows) + ) + +def gather_stats(input): + # Note the output of this function must be JSON-serializable + + if os.path.isfile(input): + with open(input, "r") as fd: + return json.load(fd) + elif os.path.isdir(input): + stats = collections.Counter() + for filename in os.listdir(input): + with open(os.path.join(input, filename)) as fd: + for line in fd: + try: + key, value = line.split(":") + except ValueError: + print(f"Unparsable line: '{line.strip()}' in {filename}", file=sys.stderr) + continue + key = key.strip() + value = int(value) + stats[key] += value + stats['__nfiles__'] += 1 + return stats + else: + raise ValueError(f"{input:r} is not a file or directory path") def extract_opcode_stats(stats): opcode_stats = [ {} for _ in range(256) ] @@ -103,13 +208,14 @@ def extract_opcode_stats(stats): opcode_stats[int(n)][rest.strip(".")] = value return opcode_stats -def parse_kinds(spec_src): +def parse_kinds(spec_src, prefix="SPEC_FAIL"): defines = collections.defaultdict(list) + start = "#define " + prefix + "_" for line in spec_src: line = line.strip() - if not line.startswith("#define SPEC_FAIL_"): + if not line.startswith(start): continue - line = line[len("#define SPEC_FAIL_"):] + line = line[len(start):] name, val = line.split() defines[int(val.strip())].append(name.strip()) return defines @@ -118,14 +224,16 @@ def pretty(defname): return defname.replace("_", " ").lower() def kind_to_text(kind, defines, opname): - if kind < 7: + if kind <= 8: return pretty(defines[kind][0]) - if opname.endswith("ATTR"): + if opname == "LOAD_SUPER_ATTR": + opname = "SUPER" + elif opname.endswith("ATTR"): opname = "ATTR" - if opname.endswith("SUBSCR"): + elif opname in ("FOR_ITER", "SEND"): + opname = "ITER" + elif opname.endswith("SUBSCR"): opname = "SUBSCR" - if opname.startswith("PRECALL"): - opname = "CALL" for name in defines[kind]: if name.startswith(opname): return pretty(name[len(opname)+1:]) @@ -137,10 +245,7 @@ def categorized_counts(opcode_stats): not_specialized = 0 specialized_instructions = { op for op in opcode._specialized_instructions - if "__" not in op and "ADAPTIVE" not in op} - adaptive_instructions = { - op for op in opcode._specialized_instructions - if "ADAPTIVE" in op} + if "__" not in op} for i, opcode_stat in enumerate(opcode_stats): if "execution_count" not in opcode_stat: continue @@ -148,8 +253,6 @@ def categorized_counts(opcode_stats): name = opname[i] if "specializable" in opcode_stat: not_specialized += count - elif name in adaptive_instructions: - not_specialized += count elif name in specialized_instructions: miss = opcode_stat.get("specialization.miss", 0) not_specialized += miss @@ -184,6 +287,12 @@ class Section: print("") print() +def to_str(x): + if isinstance(x, int): + return format(x, ",d") + else: + return str(x) + def emit_table(header, rows): width = len(header) header_line = "|" @@ -199,85 +308,203 @@ def emit_table(header, rows): print(under_line) for row in rows: if width is not None and len(row) != width: - raise ValueError("Wrong number of elements in row '" + str(rows) + "'") - print("|", " | ".join(str(i) for i in row), "|") + raise ValueError("Wrong number of elements in row '" + str(row) + "'") + print("|", " | ".join(to_str(i) for i in row), "|") print() +def calculate_execution_counts(opcode_stats, total): + counts = [] + for i, opcode_stat in enumerate(opcode_stats): + if "execution_count" in opcode_stat: + count = opcode_stat['execution_count'] + miss = 0 + if "specializable" not in opcode_stat: + miss = opcode_stat.get("specialization.miss") + counts.append((count, opname[i], miss)) + counts.sort(reverse=True) + cumulative = 0 + rows = [] + for (count, name, miss) in counts: + cumulative += count + if miss: + miss = format_ratio(miss, count) + else: + miss = "" + rows.append((name, count, format_ratio(count, total), + format_ratio(cumulative, total), miss)) + return rows + def emit_execution_counts(opcode_stats, total): with Section("Execution counts", summary="execution counts for all instructions"): - counts = [] - for i, opcode_stat in enumerate(opcode_stats): - if "execution_count" in opcode_stat: - count = opcode_stat['execution_count'] - miss = 0 - if "specializable" not in opcode_stat: - miss = opcode_stat.get("specialization.miss") - counts.append((count, opname[i], miss)) - counts.sort(reverse=True) - cumulative = 0 - rows = [] - for (count, name, miss) in counts: - cumulative += count - if miss: - miss = f"{100*miss/count:0.1f}%" - else: - miss = "" - rows.append((name, count, f"{100*count/total:0.1f}%", - f"{100*cumulative/total:0.1f}%", miss)) + rows = calculate_execution_counts(opcode_stats, total) emit_table( ("Name", "Count:", "Self:", "Cumulative:", "Miss ratio:"), rows ) +def emit_comparative_execution_counts( + base_opcode_stats, base_total, head_opcode_stats, head_total +): + with Section("Execution counts", summary="execution counts for all instructions"): + base_rows = calculate_execution_counts(base_opcode_stats, base_total) + head_rows = calculate_execution_counts(head_opcode_stats, head_total) + base_data = dict((x[0], x[1:]) for x in base_rows) + head_data = dict((x[0], x[1:]) for x in head_rows) + opcodes = set(base_data.keys()) | set(head_data.keys()) -def emit_specialization_stats(opcode_stats): + rows = [] + default = [0, "0.0%", "0.0%", 0] + for opcode in opcodes: + base_entry = base_data.get(opcode, default) + head_entry = head_data.get(opcode, default) + if base_entry[0] == 0: + change = 1 + else: + change = (head_entry[0] - base_entry[0]) / base_entry[0] + rows.append( + (opcode, base_entry[0], head_entry[0], + f"{100*change:0.1f}%")) + + rows.sort(key=lambda x: -abs(float(x[-1][:-1]))) + + emit_table( + ("Name", "Base Count:", "Head Count:", "Change:"), + rows + ) + +def get_defines(): spec_path = os.path.join(os.path.dirname(__file__), "../../Python/specialize.c") with open(spec_path) as spec_src: defines = parse_kinds(spec_src) + return defines + +def emit_specialization_stats(opcode_stats): + defines = get_defines() with Section("Specialization stats", summary="specialization stats by family"): for i, opcode_stat in enumerate(opcode_stats): name = opname[i] print_specialization_stats(name, opcode_stat, defines) -def emit_specialization_overview(opcode_stats, total): +def emit_comparative_specialization_stats(base_opcode_stats, head_opcode_stats): + defines = get_defines() + with Section("Specialization stats", summary="specialization stats by family"): + for i, (base_opcode_stat, head_opcode_stat) in enumerate(zip(base_opcode_stats, head_opcode_stats)): + name = opname[i] + print_comparative_specialization_stats(name, base_opcode_stat, head_opcode_stat, defines) + +def calculate_specialization_effectiveness(opcode_stats, total): basic, not_specialized, specialized = categorized_counts(opcode_stats) + return [ + ("Basic", basic, format_ratio(basic, total)), + ("Not specialized", not_specialized, format_ratio(not_specialized, total)), + ("Specialized", specialized, format_ratio(specialized, total)), + ] + +def emit_specialization_overview(opcode_stats, total): with Section("Specialization effectiveness"): - emit_table(("Instructions", "Count:", "Ratio:"), ( - ("Basic", basic, f"{basic*100/total:0.1f}%"), - ("Not specialized", not_specialized, f"{not_specialized*100/total:0.1f}%"), - ("Specialized", specialized, f"{specialized*100/total:0.1f}%"), - )) + rows = calculate_specialization_effectiveness(opcode_stats, total) + emit_table(("Instructions", "Count:", "Ratio:"), rows) + for title, field in (("Deferred", "specialization.deferred"), ("Misses", "specialization.miss")): + total = 0 + counts = [] + for i, opcode_stat in enumerate(opcode_stats): + # Avoid double counting misses + if title == "Misses" and "specializable" in opcode_stat: + continue + value = opcode_stat.get(field, 0) + counts.append((value, opname[i])) + total += value + counts.sort(reverse=True) + if total: + with Section(f"{title} by instruction", 3): + rows = [ (name, count, format_ratio(count, total)) for (count, name) in counts[:10] ] + emit_table(("Name", "Count:", "Ratio:"), rows) + +def emit_comparative_specialization_overview(base_opcode_stats, base_total, head_opcode_stats, head_total): + with Section("Specialization effectiveness"): + base_rows = calculate_specialization_effectiveness(base_opcode_stats, base_total) + head_rows = calculate_specialization_effectiveness(head_opcode_stats, head_total) + emit_table( + ("Instructions", "Base Count:", "Base Ratio:", "Head Count:", "Head Ratio:"), + join_rows(base_rows, head_rows) + ) + +def get_stats_defines(): + stats_path = os.path.join(os.path.dirname(__file__), "../../Include/pystats.h") + with open(stats_path) as stats_src: + defines = parse_kinds(stats_src, prefix="EVAL_CALL") + return defines + +def calculate_call_stats(stats): + defines = get_stats_defines() + total = 0 + for key, value in stats.items(): + if "Calls to" in key: + total += value + rows = [] + for key, value in stats.items(): + if "Calls to" in key: + rows.append((key, value, format_ratio(value, total))) + elif key.startswith("Calls "): + name, index = key[:-1].split("[") + index = int(index) + label = name + " (" + pretty(defines[index][0]) + ")" + rows.append((label, value, format_ratio(value, total))) + for key, value in stats.items(): + if key.startswith("Frame"): + rows.append((key, value, format_ratio(value, total))) + return rows def emit_call_stats(stats): with Section("Call stats", summary="Inlined calls and frame stats"): - total = 0 - for key, value in stats.items(): - if "Calls to" in key: - total += value - rows = [] - for key, value in stats.items(): - if "Calls to" in key: - rows.append((key, value, f"{100*value/total:0.1f}%")) - for key, value in stats.items(): - if key.startswith("Frame"): - rows.append((key, value, f"{100*value/total:0.1f}%")) + rows = calculate_call_stats(stats) emit_table(("", "Count:", "Ratio:"), rows) +def emit_comparative_call_stats(base_stats, head_stats): + with Section("Call stats", summary="Inlined calls and frame stats"): + base_rows = calculate_call_stats(base_stats) + head_rows = calculate_call_stats(head_stats) + rows = join_rows(base_rows, head_rows) + rows.sort(key=lambda x: -float(x[-1][:-1])) + emit_table( + ("", "Base Count:", "Base Ratio:", "Head Count:", "Head Ratio:"), + rows + ) + +def calculate_object_stats(stats): + total_materializations = stats.get("Object new values") + total_allocations = stats.get("Object allocations") + stats.get("Object allocations from freelist") + total_increfs = stats.get("Object interpreter increfs") + stats.get("Object increfs") + total_decrefs = stats.get("Object interpreter decrefs") + stats.get("Object decrefs") + rows = [] + for key, value in stats.items(): + if key.startswith("Object"): + if "materialize" in key: + ratio = format_ratio(value, total_materializations) + elif "allocations" in key: + ratio = format_ratio(value, total_allocations) + elif "increfs" in key: + ratio = format_ratio(value, total_increfs) + elif "decrefs" in key: + ratio = format_ratio(value, total_decrefs) + else: + ratio = "" + label = key[6:].strip() + label = label[0].upper() + label[1:] + rows.append((label, value, ratio)) + return rows + def emit_object_stats(stats): with Section("Object stats", summary="allocations, frees and dict materializatons"): - total = stats.get("Object new values") - rows = [] - for key, value in stats.items(): - if key.startswith("Object"): - if "materialize" in key: - materialize = f"{100*value/total:0.1f}%" - else: - materialize = "" - label = key[6:].strip() - label = label[0].upper() + label[1:] - rows.append((label, value, materialize)) + rows = calculate_object_stats(stats) emit_table(("", "Count:", "Ratio:"), rows) +def emit_comparative_object_stats(base_stats, head_stats): + with Section("Object stats", summary="allocations, frees and dict materializatons"): + base_rows = calculate_object_stats(base_stats) + head_rows = calculate_object_stats(head_stats) + emit_table(("", "Base Count:", "Base Ratio:", "Head Count:", "Head Ratio:"), join_rows(base_rows, head_rows)) + def get_total(opcode_stats): total = 0 for opcode_stat in opcode_stats: @@ -302,12 +529,12 @@ def emit_pair_counts(opcode_stats, total): for (count, pair) in itertools.islice(pair_counts, 100): i, j = pair cumulative += count - rows.append((opname[i] + " " + opname[j], count, f"{100*count/total:0.1f}%", - f"{100*cumulative/total:0.1f}%")) + rows.append((opname[i] + " " + opname[j], count, format_ratio(count, total), + format_ratio(cumulative, total))) emit_table(("Pair", "Count:", "Self:", "Cumulative:"), rows ) - with Section("Predecessor/Successor Pairs", summary="Top 3 predecessors and successors of each opcode"): + with Section("Predecessor/Successor Pairs", summary="Top 5 predecessors and successors of each opcode"): predecessors = collections.defaultdict(collections.Counter) successors = collections.defaultdict(collections.Counter) total_predecessors = collections.Counter() @@ -326,10 +553,10 @@ def emit_pair_counts(opcode_stats, total): pred_rows = succ_rows = () if total1: pred_rows = [(opname[pred], count, f"{count/total1:.1%}") - for (pred, count) in predecessors[i].most_common(3)] + for (pred, count) in predecessors[i].most_common(5)] if total2: succ_rows = [(opname[succ], count, f"{count/total2:.1%}") - for (succ, count) in successors[i].most_common(3)] + for (succ, count) in successors[i].most_common(5)] with Section(name, 3, f"Successors and predecessors for {name}"): emit_table(("Predecessors", "Count:", "Percentage:"), pred_rows @@ -338,8 +565,7 @@ def emit_pair_counts(opcode_stats, total): succ_rows ) -def main(): - stats = gather_stats() +def output_single_stats(stats): opcode_stats = extract_opcode_stats(stats) total = get_total(opcode_stats) emit_execution_counts(opcode_stats, total) @@ -348,8 +574,79 @@ def main(): emit_specialization_overview(opcode_stats, total) emit_call_stats(stats) emit_object_stats(stats) + with Section("Meta stats", summary="Meta statistics"): + emit_table(("", "Count:"), [('Number of data files', stats['__nfiles__'])]) + + +def output_comparative_stats(base_stats, head_stats): + base_opcode_stats = extract_opcode_stats(base_stats) + base_total = get_total(base_opcode_stats) + + head_opcode_stats = extract_opcode_stats(head_stats) + head_total = get_total(head_opcode_stats) + + emit_comparative_execution_counts( + base_opcode_stats, base_total, head_opcode_stats, head_total + ) + emit_comparative_specialization_stats( + base_opcode_stats, head_opcode_stats + ) + emit_comparative_specialization_overview( + base_opcode_stats, base_total, head_opcode_stats, head_total + ) + emit_comparative_call_stats(base_stats, head_stats) + emit_comparative_object_stats(base_stats, head_stats) + +def output_stats(inputs, json_output=None): + if len(inputs) == 1: + stats = gather_stats(inputs[0]) + if json_output is not None: + json.dump(stats, json_output) + output_single_stats(stats) + elif len(inputs) == 2: + if json_output is not None: + raise ValueError( + "Can not output to JSON when there are multiple inputs" + ) + + base_stats = gather_stats(inputs[0]) + head_stats = gather_stats(inputs[1]) + output_comparative_stats(base_stats, head_stats) + print("---") print("Stats gathered on:", date.today()) +def main(): + parser = argparse.ArgumentParser(description="Summarize pystats results") + + parser.add_argument( + "inputs", + nargs="*", + type=str, + default=[DEFAULT_DIR], + help=f""" + Input source(s). + For each entry, if a .json file, the output provided by --json-output from a previous run; + if a directory, a directory containing raw pystats .txt files. + If one source is provided, its stats are printed. + If two sources are provided, comparative stats are printed. + Default is {DEFAULT_DIR}. + """ + ) + + parser.add_argument( + "--json-output", + nargs="?", + type=argparse.FileType("w"), + help="Output complete raw results to the given JSON file." + ) + + args = parser.parse_args() + + if len(args.inputs) > 2: + raise ValueError("0-2 arguments may be provided.") + + output_stats(args.inputs, json_output=args.json_output) + if __name__ == "__main__": main() diff --git a/Tools/scripts/texi2html.py b/Tools/scripts/texi2html.py deleted file mode 100755 index c06d812a..00000000 --- a/Tools/scripts/texi2html.py +++ /dev/null @@ -1,2071 +0,0 @@ -#! /usr/bin/env python3 - -# Convert GNU texinfo files into HTML, one file per node. -# Based on Texinfo 2.14. -# Usage: texi2html [-d] [-d] [-c] inputfile outputdirectory -# The input file must be a complete texinfo file, e.g. emacs.texi. -# This creates many files (one per info node) in the output directory, -# overwriting existing files of the same name. All files created have -# ".html" as their extension. - - -# XXX To do: -# - handle @comment*** correctly -# - handle @xref {some words} correctly -# - handle @ftable correctly (items aren't indexed?) -# - handle @itemx properly -# - handle @exdent properly -# - add links directly to the proper line from indices -# - check against the definitive list of @-cmds; we still miss (among others): -# - @defindex (hard) -# - @c(omment) in the middle of a line (rarely used) -# - @this* (not really needed, only used in headers anyway) -# - @today{} (ever used outside title page?) - -# More consistent handling of chapters/sections/etc. -# Lots of documentation -# Many more options: -# -top designate top node -# -links customize which types of links are included -# -split split at chapters or sections instead of nodes -# -name Allow different types of filename handling. Non unix systems -# will have problems with long node names -# ... -# Support the most recent texinfo version and take a good look at HTML 3.0 -# More debugging output (customizable) and more flexible error handling -# How about icons ? - -# rpyron 2002-05-07 -# Robert Pyron -# 1. BUGFIX: In function makefile(), strip blanks from the nodename. -# This is necessary to match the behavior of parser.makeref() and -# parser.do_node(). -# 2. BUGFIX fixed KeyError in end_ifset (well, I may have just made -# it go away, rather than fix it) -# 3. BUGFIX allow @menu and menu items inside @ifset or @ifclear -# 4. Support added for: -# @uref URL reference -# @image image file reference (see note below) -# @multitable output an HTML table -# @vtable -# 5. Partial support for accents, to match MAKEINFO output -# 6. I added a new command-line option, '-H basename', to specify -# HTML Help output. This will cause three files to be created -# in the current directory: -# `basename`.hhp HTML Help Workshop project file -# `basename`.hhc Contents file for the project -# `basename`.hhk Index file for the project -# When fed into HTML Help Workshop, the resulting file will be -# named `basename`.chm. -# 7. A new class, HTMLHelp, to accomplish item 6. -# 8. Various calls to HTMLHelp functions. -# A NOTE ON IMAGES: Just as 'outputdirectory' must exist before -# running this program, all referenced images must already exist -# in outputdirectory. - -import os -import sys -import string -import re - -MAGIC = '\\input texinfo' - -cmprog = re.compile('^@([a-z]+)([ \t]|$)') # Command (line-oriented) -blprog = re.compile('^[ \t]*$') # Blank line -kwprog = re.compile('@[a-z]+') # Keyword (embedded, usually - # with {} args) -spprog = re.compile('[\n@{}&<>]') # Special characters in - # running text - # - # menu item (Yuck!) -miprog = re.compile(r'^\* ([^:]*):(:|[ \t]*([^\t,\n.]+)([^ \t\n]*))[ \t\n]*') -# 0 1 1 2 3 34 42 0 -# ----- ---------- --------- -# -|----------------------------- -# ----------------------------------------------------- - - - - -class HTMLNode: - """Some of the parser's functionality is separated into this class. - - A Node accumulates its contents, takes care of links to other Nodes - and saves itself when it is finished and all links are resolved. - """ - - DOCTYPE = '' - - type = 0 - cont = '' - epilogue = '\n' - - def __init__(self, dir, name, topname, title, next, prev, up): - self.dirname = dir - self.name = name - if topname: - self.topname = topname - else: - self.topname = name - self.title = title - self.next = next - self.prev = prev - self.up = up - self.lines = [] - - def write(self, *lines): - for line in lines: - self.lines.append(line) - - def flush(self): - with open(self.dirname + '/' + makefile(self.name), 'w') as fp: - fp.write(self.prologue) - fp.write(self.text) - fp.write(self.epilogue) - - def link(self, label, nodename, rel=None, rev=None): - if nodename: - if nodename.lower() == '(dir)': - addr = '../dir.html' - title = '' - else: - addr = makefile(nodename) - title = ' TITLE="%s"' % nodename - self.write(label, ': ', nodename, ' \n') - - def finalize(self): - length = len(self.lines) - self.text = ''.join(self.lines) - self.lines = [] - self.open_links() - self.output_links() - self.close_links() - links = ''.join(self.lines) - self.lines = [] - self.prologue = ( - self.DOCTYPE + - '\n\n' - ' \n' - ' ' + self.title + '\n' - ' \n' - ' \n' - ' \n' - '\n' + - links) - if length > 20: - self.epilogue = '

\n%s\n' % links - - def open_links(self): - self.write('


\n') - - def close_links(self): - self.write('
\n') - - def output_links(self): - if self.cont != self.next: - self.link(' Cont', self.cont) - self.link(' Next', self.next, rel='Next') - self.link(' Prev', self.prev, rel='Previous') - self.link(' Up', self.up, rel='Up') - if self.name != self.topname: - self.link(' Top', self.topname) - - -class HTML3Node(HTMLNode): - - DOCTYPE = '' - - def open_links(self): - self.write('\n') - - -class TexinfoParser: - - COPYRIGHT_SYMBOL = "©" - FN_ID_PATTERN = "(%(id)s)" - FN_SOURCE_PATTERN = '' \ - + FN_ID_PATTERN + '' - FN_TARGET_PATTERN = '' \ - + FN_ID_PATTERN + '\n%(text)s

\n' - FN_HEADER = '\n

\n


\n' \ - 'Footnotes\n

' - - - Node = HTMLNode - - # Initialize an instance - def __init__(self): - self.unknown = {} # statistics about unknown @-commands - self.filenames = {} # Check for identical filenames - self.debugging = 0 # larger values produce more output - self.print_headers = 0 # always print headers? - self.nodefp = None # open file we're writing to - self.nodelineno = 0 # Linenumber relative to node - self.links = None # Links from current node - self.savetext = None # If not None, save text head instead - self.savestack = [] # If not None, save text head instead - self.htmlhelp = None # html help data - self.dirname = 'tmp' # directory where files are created - self.includedir = '.' # directory to search @include files - self.nodename = '' # name of current node - self.topname = '' # name of top node (first node seen) - self.title = '' # title of this whole Texinfo tree - self.resetindex() # Reset all indices - self.contents = [] # Reset table of contents - self.numbering = [] # Reset section numbering counters - self.nofill = 0 # Normal operation: fill paragraphs - self.values={'html': 1} # Names that should be parsed in ifset - self.stackinfo={} # Keep track of state in the stack - # XXX The following should be reset per node?! - self.footnotes = [] # Reset list of footnotes - self.itemarg = None # Reset command used by @item - self.itemnumber = None # Reset number for @item in @enumerate - self.itemindex = None # Reset item index name - self.node = None - self.nodestack = [] - self.cont = 0 - self.includedepth = 0 - - # Set htmlhelp helper class - def sethtmlhelp(self, htmlhelp): - self.htmlhelp = htmlhelp - - # Set (output) directory name - def setdirname(self, dirname): - self.dirname = dirname - - # Set include directory name - def setincludedir(self, includedir): - self.includedir = includedir - - # Parse the contents of an entire file - def parse(self, fp): - line = fp.readline() - lineno = 1 - while line and (line[0] == '%' or blprog.match(line)): - line = fp.readline() - lineno = lineno + 1 - if line[:len(MAGIC)] != MAGIC: - raise SyntaxError('file does not begin with %r' % (MAGIC,)) - self.parserest(fp, lineno) - - # Parse the contents of a file, not expecting a MAGIC header - def parserest(self, fp, initial_lineno): - lineno = initial_lineno - self.done = 0 - self.skip = 0 - self.stack = [] - accu = [] - while not self.done: - line = fp.readline() - self.nodelineno = self.nodelineno + 1 - if not line: - if accu: - if not self.skip: self.process(accu) - accu = [] - if initial_lineno > 0: - print('*** EOF before @bye') - break - lineno = lineno + 1 - mo = cmprog.match(line) - if mo: - a, b = mo.span(1) - cmd = line[a:b] - if cmd in ('noindent', 'refill'): - accu.append(line) - else: - if accu: - if not self.skip: - self.process(accu) - accu = [] - self.command(line, mo) - elif blprog.match(line) and \ - 'format' not in self.stack and \ - 'example' not in self.stack: - if accu: - if not self.skip: - self.process(accu) - if self.nofill: - self.write('\n') - else: - self.write('

\n') - accu = [] - else: - # Append the line including trailing \n! - accu.append(line) - # - if self.skip: - print('*** Still skipping at the end') - if self.stack: - print('*** Stack not empty at the end') - print('***', self.stack) - if self.includedepth == 0: - while self.nodestack: - self.nodestack[-1].finalize() - self.nodestack[-1].flush() - del self.nodestack[-1] - - # Start saving text in a buffer instead of writing it to a file - def startsaving(self): - if self.savetext is not None: - self.savestack.append(self.savetext) - # print '*** Recursively saving text, expect trouble' - self.savetext = '' - - # Return the text saved so far and start writing to file again - def collectsavings(self): - savetext = self.savetext - if len(self.savestack) > 0: - self.savetext = self.savestack[-1] - del self.savestack[-1] - else: - self.savetext = None - return savetext or '' - - # Write text to file, or save it in a buffer, or ignore it - def write(self, *args): - try: - text = ''.join(args) - except: - print(args) - raise TypeError - if self.savetext is not None: - self.savetext = self.savetext + text - elif self.nodefp: - self.nodefp.write(text) - elif self.node: - self.node.write(text) - - # Complete the current node -- write footnotes and close file - def endnode(self): - if self.savetext is not None: - print('*** Still saving text at end of node') - dummy = self.collectsavings() - if self.footnotes: - self.writefootnotes() - if self.nodefp: - if self.nodelineno > 20: - self.write('


\n') - [name, next, prev, up] = self.nodelinks[:4] - self.link('Next', next) - self.link('Prev', prev) - self.link('Up', up) - if self.nodename != self.topname: - self.link('Top', self.topname) - self.write('
\n') - self.write('\n') - self.nodefp.close() - self.nodefp = None - elif self.node: - if not self.cont and \ - (not self.node.type or \ - (self.node.next and self.node.prev and self.node.up)): - self.node.finalize() - self.node.flush() - else: - self.nodestack.append(self.node) - self.node = None - self.nodename = '' - - # Process a list of lines, expanding embedded @-commands - # This mostly distinguishes between menus and normal text - def process(self, accu): - if self.debugging > 1: - print('!'*self.debugging, 'process:', self.skip, self.stack, end=' ') - if accu: print(accu[0][:30], end=' ') - if accu[0][30:] or accu[1:]: print('...', end=' ') - print() - if self.inmenu(): - # XXX should be done differently - for line in accu: - mo = miprog.match(line) - if not mo: - line = line.strip() + '\n' - self.expand(line) - continue - bgn, end = mo.span(0) - a, b = mo.span(1) - c, d = mo.span(2) - e, f = mo.span(3) - g, h = mo.span(4) - label = line[a:b] - nodename = line[c:d] - if nodename[0] == ':': nodename = label - else: nodename = line[e:f] - punct = line[g:h] - self.write('
  • ', nodename, - '', punct, '\n') - self.htmlhelp.menuitem(nodename) - self.expand(line[end:]) - else: - text = ''.join(accu) - self.expand(text) - - # find 'menu' (we might be inside 'ifset' or 'ifclear') - def inmenu(self): - #if 'menu' in self.stack: - # print 'inmenu :', self.skip, self.stack, self.stackinfo - stack = self.stack - while stack and stack[-1] in ('ifset','ifclear'): - try: - if self.stackinfo[len(stack)]: - return 0 - except KeyError: - pass - stack = stack[:-1] - return (stack and stack[-1] == 'menu') - - # Write a string, expanding embedded @-commands - def expand(self, text): - stack = [] - i = 0 - n = len(text) - while i < n: - start = i - mo = spprog.search(text, i) - if mo: - i = mo.start() - else: - self.write(text[start:]) - break - self.write(text[start:i]) - c = text[i] - i = i+1 - if c == '\n': - self.write('\n') - continue - if c == '<': - self.write('<') - continue - if c == '>': - self.write('>') - continue - if c == '&': - self.write('&') - continue - if c == '{': - stack.append('') - continue - if c == '}': - if not stack: - print('*** Unmatched }') - self.write('}') - continue - cmd = stack[-1] - del stack[-1] - try: - method = getattr(self, 'close_' + cmd) - except AttributeError: - self.unknown_close(cmd) - continue - method() - continue - if c != '@': - # Cannot happen unless spprog is changed - raise RuntimeError('unexpected funny %r' % c) - start = i - while i < n and text[i] in string.ascii_letters: i = i+1 - if i == start: - # @ plus non-letter: literal next character - i = i+1 - c = text[start:i] - if c == ':': - # `@:' means no extra space after - # preceding `.', `?', `!' or `:' - pass - else: - # `@.' means a sentence-ending period; - # `@@', `@{', `@}' quote `@', `{', `}' - self.write(c) - continue - cmd = text[start:i] - if i < n and text[i] == '{': - i = i+1 - stack.append(cmd) - try: - method = getattr(self, 'open_' + cmd) - except AttributeError: - self.unknown_open(cmd) - continue - method() - continue - try: - method = getattr(self, 'handle_' + cmd) - except AttributeError: - self.unknown_handle(cmd) - continue - method() - if stack: - print('*** Stack not empty at para:', stack) - - # --- Handle unknown embedded @-commands --- - - def unknown_open(self, cmd): - print('*** No open func for @' + cmd + '{...}') - cmd = cmd + '{' - self.write('@', cmd) - if cmd not in self.unknown: - self.unknown[cmd] = 1 - else: - self.unknown[cmd] = self.unknown[cmd] + 1 - - def unknown_close(self, cmd): - print('*** No close func for @' + cmd + '{...}') - cmd = '}' + cmd - self.write('}') - if cmd not in self.unknown: - self.unknown[cmd] = 1 - else: - self.unknown[cmd] = self.unknown[cmd] + 1 - - def unknown_handle(self, cmd): - print('*** No handler for @' + cmd) - self.write('@', cmd) - if cmd not in self.unknown: - self.unknown[cmd] = 1 - else: - self.unknown[cmd] = self.unknown[cmd] + 1 - - # XXX The following sections should be ordered as the texinfo docs - - # --- Embedded @-commands without {} argument list -- - - def handle_noindent(self): pass - - def handle_refill(self): pass - - # --- Include file handling --- - - def do_include(self, args): - file = args - file = os.path.join(self.includedir, file) - try: - fp = open(file, 'r') - except IOError as msg: - print('*** Can\'t open include file', repr(file)) - return - with fp: - print('!'*self.debugging, '--> file', repr(file)) - save_done = self.done - save_skip = self.skip - save_stack = self.stack - self.includedepth = self.includedepth + 1 - self.parserest(fp, 0) - self.includedepth = self.includedepth - 1 - self.done = save_done - self.skip = save_skip - self.stack = save_stack - print('!'*self.debugging, '<-- file', repr(file)) - - # --- Special Insertions --- - - def open_dmn(self): pass - def close_dmn(self): pass - - def open_dots(self): self.write('...') - def close_dots(self): pass - - def open_bullet(self): pass - def close_bullet(self): pass - - def open_TeX(self): self.write('TeX') - def close_TeX(self): pass - - def handle_copyright(self): self.write(self.COPYRIGHT_SYMBOL) - def open_copyright(self): self.write(self.COPYRIGHT_SYMBOL) - def close_copyright(self): pass - - def open_minus(self): self.write('-') - def close_minus(self): pass - - # --- Accents --- - - # rpyron 2002-05-07 - # I would like to do at least as well as makeinfo when - # it is producing HTML output: - # - # input output - # @"o @"o umlaut accent - # @'o 'o acute accent - # @,{c} @,{c} cedilla accent - # @=o @=o macron/overbar accent - # @^o @^o circumflex accent - # @`o `o grave accent - # @~o @~o tilde accent - # @dotaccent{o} @dotaccent{o} overdot accent - # @H{o} @H{o} long Hungarian umlaut - # @ringaccent{o} @ringaccent{o} ring accent - # @tieaccent{oo} @tieaccent{oo} tie-after accent - # @u{o} @u{o} breve accent - # @ubaraccent{o} @ubaraccent{o} underbar accent - # @udotaccent{o} @udotaccent{o} underdot accent - # @v{o} @v{o} hacek or check accent - # @exclamdown{} ¡ upside-down ! - # @questiondown{} ¿ upside-down ? - # @aa{},@AA{} å,Å a,A with circle - # @ae{},@AE{} æ,Æ ae,AE ligatures - # @dotless{i} @dotless{i} dotless i - # @dotless{j} @dotless{j} dotless j - # @l{},@L{} l/,L/ suppressed-L,l - # @o{},@O{} ø,Ø O,o with slash - # @oe{},@OE{} oe,OE oe,OE ligatures - # @ss{} ß es-zet or sharp S - # - # The following character codes and approximations have been - # copied from makeinfo's HTML output. - - def open_exclamdown(self): self.write('¡') # upside-down ! - def close_exclamdown(self): pass - def open_questiondown(self): self.write('¿') # upside-down ? - def close_questiondown(self): pass - def open_aa(self): self.write('å') # a with circle - def close_aa(self): pass - def open_AA(self): self.write('Å') # A with circle - def close_AA(self): pass - def open_ae(self): self.write('æ') # ae ligatures - def close_ae(self): pass - def open_AE(self): self.write('Æ') # AE ligatures - def close_AE(self): pass - def open_o(self): self.write('ø') # o with slash - def close_o(self): pass - def open_O(self): self.write('Ø') # O with slash - def close_O(self): pass - def open_ss(self): self.write('ß') # es-zet or sharp S - def close_ss(self): pass - def open_oe(self): self.write('oe') # oe ligatures - def close_oe(self): pass - def open_OE(self): self.write('OE') # OE ligatures - def close_OE(self): pass - def open_l(self): self.write('l/') # suppressed-l - def close_l(self): pass - def open_L(self): self.write('L/') # suppressed-L - def close_L(self): pass - - # --- Special Glyphs for Examples --- - - def open_result(self): self.write('=>') - def close_result(self): pass - - def open_expansion(self): self.write('==>') - def close_expansion(self): pass - - def open_print(self): self.write('-|') - def close_print(self): pass - - def open_error(self): self.write('error-->') - def close_error(self): pass - - def open_equiv(self): self.write('==') - def close_equiv(self): pass - - def open_point(self): self.write('-!-') - def close_point(self): pass - - # --- Cross References --- - - def open_pxref(self): - self.write('see ') - self.startsaving() - def close_pxref(self): - self.makeref() - - def open_xref(self): - self.write('See ') - self.startsaving() - def close_xref(self): - self.makeref() - - def open_ref(self): - self.startsaving() - def close_ref(self): - self.makeref() - - def open_inforef(self): - self.write('See info file ') - self.startsaving() - def close_inforef(self): - text = self.collectsavings() - args = [s.strip() for s in text.split(',')] - while len(args) < 3: args.append('') - node = args[0] - file = args[2] - self.write('`', file, '\', node `', node, '\'') - - def makeref(self): - text = self.collectsavings() - args = [s.strip() for s in text.split(',')] - while len(args) < 5: args.append('') - nodename = label = args[0] - if args[2]: label = args[2] - file = args[3] - title = args[4] - href = makefile(nodename) - if file: - href = '../' + file + '/' + href - self.write('', label, '') - - # rpyron 2002-05-07 uref support - def open_uref(self): - self.startsaving() - def close_uref(self): - text = self.collectsavings() - args = [s.strip() for s in text.split(',')] - while len(args) < 2: args.append('') - href = args[0] - label = args[1] - if not label: label = href - self.write('', label, '') - - # rpyron 2002-05-07 image support - # GNU makeinfo producing HTML output tries `filename.png'; if - # that does not exist, it tries `filename.jpg'. If that does - # not exist either, it complains. GNU makeinfo does not handle - # GIF files; however, I include GIF support here because - # MySQL documentation uses GIF files. - - def open_image(self): - self.startsaving() - def close_image(self): - self.makeimage() - def makeimage(self): - text = self.collectsavings() - args = [s.strip() for s in text.split(',')] - while len(args) < 5: args.append('') - filename = args[0] - width = args[1] - height = args[2] - alt = args[3] - ext = args[4] - - # The HTML output will have a reference to the image - # that is relative to the HTML output directory, - # which is what 'filename' gives us. However, we need - # to find it relative to our own current directory, - # so we construct 'imagename'. - imagelocation = self.dirname + '/' + filename - - if os.path.exists(imagelocation+'.png'): - filename += '.png' - elif os.path.exists(imagelocation+'.jpg'): - filename += '.jpg' - elif os.path.exists(imagelocation+'.gif'): # MySQL uses GIF files - filename += '.gif' - else: - print("*** Cannot find image " + imagelocation) - #TODO: what is 'ext'? - self.write('' ) - self.htmlhelp.addimage(imagelocation) - - - # --- Marking Words and Phrases --- - - # --- Other @xxx{...} commands --- - - def open_(self): pass # Used by {text enclosed in braces} - def close_(self): pass - - open_asis = open_ - close_asis = close_ - - def open_cite(self): self.write('') - def close_cite(self): self.write('') - - def open_code(self): self.write('') - def close_code(self): self.write('') - - def open_t(self): self.write('') - def close_t(self): self.write('') - - def open_dfn(self): self.write('') - def close_dfn(self): self.write('') - - def open_emph(self): self.write('') - def close_emph(self): self.write('') - - def open_i(self): self.write('') - def close_i(self): self.write('') - - def open_footnote(self): - # if self.savetext is not None: - # print '*** Recursive footnote -- expect weirdness' - id = len(self.footnotes) + 1 - self.write(self.FN_SOURCE_PATTERN % {'id': repr(id)}) - self.startsaving() - - def close_footnote(self): - id = len(self.footnotes) + 1 - self.footnotes.append((id, self.collectsavings())) - - def writefootnotes(self): - self.write(self.FN_HEADER) - for id, text in self.footnotes: - self.write(self.FN_TARGET_PATTERN - % {'id': repr(id), 'text': text}) - self.footnotes = [] - - def open_file(self): self.write('') - def close_file(self): self.write('') - - def open_kbd(self): self.write('') - def close_kbd(self): self.write('') - - def open_key(self): self.write('') - def close_key(self): self.write('') - - def open_r(self): self.write('') - def close_r(self): self.write('') - - def open_samp(self): self.write('`') - def close_samp(self): self.write('\'') - - def open_sc(self): self.write('') - def close_sc(self): self.write('') - - def open_strong(self): self.write('') - def close_strong(self): self.write('') - - def open_b(self): self.write('') - def close_b(self): self.write('') - - def open_var(self): self.write('') - def close_var(self): self.write('') - - def open_w(self): self.write('') - def close_w(self): self.write('') - - def open_url(self): self.startsaving() - def close_url(self): - text = self.collectsavings() - self.write('', text, '') - - def open_email(self): self.startsaving() - def close_email(self): - text = self.collectsavings() - self.write('', text, '') - - open_titlefont = open_ - close_titlefont = close_ - - def open_small(self): pass - def close_small(self): pass - - def command(self, line, mo): - a, b = mo.span(1) - cmd = line[a:b] - args = line[b:].strip() - if self.debugging > 1: - print('!'*self.debugging, 'command:', self.skip, self.stack, \ - '@' + cmd, args) - try: - func = getattr(self, 'do_' + cmd) - except AttributeError: - try: - func = getattr(self, 'bgn_' + cmd) - except AttributeError: - # don't complain if we are skipping anyway - if not self.skip: - self.unknown_cmd(cmd, args) - return - self.stack.append(cmd) - func(args) - return - if not self.skip or cmd == 'end': - func(args) - - def unknown_cmd(self, cmd, args): - print('*** unknown', '@' + cmd, args) - if cmd not in self.unknown: - self.unknown[cmd] = 1 - else: - self.unknown[cmd] = self.unknown[cmd] + 1 - - def do_end(self, args): - words = args.split() - if not words: - print('*** @end w/o args') - else: - cmd = words[0] - if not self.stack or self.stack[-1] != cmd: - print('*** @end', cmd, 'unexpected') - else: - del self.stack[-1] - try: - func = getattr(self, 'end_' + cmd) - except AttributeError: - self.unknown_end(cmd) - return - func() - - def unknown_end(self, cmd): - cmd = 'end ' + cmd - print('*** unknown', '@' + cmd) - if cmd not in self.unknown: - self.unknown[cmd] = 1 - else: - self.unknown[cmd] = self.unknown[cmd] + 1 - - # --- Comments --- - - def do_comment(self, args): pass - do_c = do_comment - - # --- Conditional processing --- - - def bgn_ifinfo(self, args): pass - def end_ifinfo(self): pass - - def bgn_iftex(self, args): self.skip = self.skip + 1 - def end_iftex(self): self.skip = self.skip - 1 - - def bgn_ignore(self, args): self.skip = self.skip + 1 - def end_ignore(self): self.skip = self.skip - 1 - - def bgn_tex(self, args): self.skip = self.skip + 1 - def end_tex(self): self.skip = self.skip - 1 - - def do_set(self, args): - fields = args.split(' ') - key = fields[0] - if len(fields) == 1: - value = 1 - else: - value = ' '.join(fields[1:]) - self.values[key] = value - - def do_clear(self, args): - self.values[args] = None - - def bgn_ifset(self, args): - if args not in self.values or self.values[args] is None: - self.skip = self.skip + 1 - self.stackinfo[len(self.stack)] = 1 - else: - self.stackinfo[len(self.stack)] = 0 - def end_ifset(self): - try: - if self.stackinfo[len(self.stack) + 1]: - self.skip = self.skip - 1 - del self.stackinfo[len(self.stack) + 1] - except KeyError: - print('*** end_ifset: KeyError :', len(self.stack) + 1) - - def bgn_ifclear(self, args): - if args in self.values and self.values[args] is not None: - self.skip = self.skip + 1 - self.stackinfo[len(self.stack)] = 1 - else: - self.stackinfo[len(self.stack)] = 0 - def end_ifclear(self): - try: - if self.stackinfo[len(self.stack) + 1]: - self.skip = self.skip - 1 - del self.stackinfo[len(self.stack) + 1] - except KeyError: - print('*** end_ifclear: KeyError :', len(self.stack) + 1) - - def open_value(self): - self.startsaving() - - def close_value(self): - key = self.collectsavings() - if key in self.values: - self.write(self.values[key]) - else: - print('*** Undefined value: ', key) - - # --- Beginning a file --- - - do_finalout = do_comment - do_setchapternewpage = do_comment - do_setfilename = do_comment - - def do_settitle(self, args): - self.startsaving() - self.expand(args) - self.title = self.collectsavings() - def do_parskip(self, args): pass - - # --- Ending a file --- - - def do_bye(self, args): - self.endnode() - self.done = 1 - - # --- Title page --- - - def bgn_titlepage(self, args): self.skip = self.skip + 1 - def end_titlepage(self): self.skip = self.skip - 1 - def do_shorttitlepage(self, args): pass - - def do_center(self, args): - # Actually not used outside title page... - self.write('

    ') - self.expand(args) - self.write('

    \n') - do_title = do_center - do_subtitle = do_center - do_author = do_center - - do_vskip = do_comment - do_vfill = do_comment - do_smallbook = do_comment - - do_paragraphindent = do_comment - do_setchapternewpage = do_comment - do_headings = do_comment - do_footnotestyle = do_comment - - do_evenheading = do_comment - do_evenfooting = do_comment - do_oddheading = do_comment - do_oddfooting = do_comment - do_everyheading = do_comment - do_everyfooting = do_comment - - # --- Nodes --- - - def do_node(self, args): - self.endnode() - self.nodelineno = 0 - parts = [s.strip() for s in args.split(',')] - while len(parts) < 4: parts.append('') - self.nodelinks = parts - [name, next, prev, up] = parts[:4] - file = self.dirname + '/' + makefile(name) - if file in self.filenames: - print('*** Filename already in use: ', file) - else: - if self.debugging: print('!'*self.debugging, '--- writing', file) - self.filenames[file] = 1 - # self.nodefp = open(file, 'w') - self.nodename = name - if self.cont and self.nodestack: - self.nodestack[-1].cont = self.nodename - if not self.topname: self.topname = name - title = name - if self.title: title = title + ' -- ' + self.title - self.node = self.Node(self.dirname, self.nodename, self.topname, - title, next, prev, up) - self.htmlhelp.addnode(self.nodename,next,prev,up,file) - - def link(self, label, nodename): - if nodename: - if nodename.lower() == '(dir)': - addr = '../dir.html' - else: - addr = makefile(nodename) - self.write(label, ': ', nodename, ' \n') - - # --- Sectioning commands --- - - def popstack(self, type): - if (self.node): - self.node.type = type - while self.nodestack: - if self.nodestack[-1].type > type: - self.nodestack[-1].finalize() - self.nodestack[-1].flush() - del self.nodestack[-1] - elif self.nodestack[-1].type == type: - if not self.nodestack[-1].next: - self.nodestack[-1].next = self.node.name - if not self.node.prev: - self.node.prev = self.nodestack[-1].name - self.nodestack[-1].finalize() - self.nodestack[-1].flush() - del self.nodestack[-1] - else: - if type > 1 and not self.node.up: - self.node.up = self.nodestack[-1].name - break - - def do_chapter(self, args): - self.heading('H1', args, 0) - self.popstack(1) - - def do_unnumbered(self, args): - self.heading('H1', args, -1) - self.popstack(1) - def do_appendix(self, args): - self.heading('H1', args, -1) - self.popstack(1) - def do_top(self, args): - self.heading('H1', args, -1) - def do_chapheading(self, args): - self.heading('H1', args, -1) - def do_majorheading(self, args): - self.heading('H1', args, -1) - - def do_section(self, args): - self.heading('H1', args, 1) - self.popstack(2) - - def do_unnumberedsec(self, args): - self.heading('H1', args, -1) - self.popstack(2) - def do_appendixsec(self, args): - self.heading('H1', args, -1) - self.popstack(2) - do_appendixsection = do_appendixsec - def do_heading(self, args): - self.heading('H1', args, -1) - - def do_subsection(self, args): - self.heading('H2', args, 2) - self.popstack(3) - def do_unnumberedsubsec(self, args): - self.heading('H2', args, -1) - self.popstack(3) - def do_appendixsubsec(self, args): - self.heading('H2', args, -1) - self.popstack(3) - def do_subheading(self, args): - self.heading('H2', args, -1) - - def do_subsubsection(self, args): - self.heading('H3', args, 3) - self.popstack(4) - def do_unnumberedsubsubsec(self, args): - self.heading('H3', args, -1) - self.popstack(4) - def do_appendixsubsubsec(self, args): - self.heading('H3', args, -1) - self.popstack(4) - def do_subsubheading(self, args): - self.heading('H3', args, -1) - - def heading(self, type, args, level): - if level >= 0: - while len(self.numbering) <= level: - self.numbering.append(0) - del self.numbering[level+1:] - self.numbering[level] = self.numbering[level] + 1 - x = '' - for i in self.numbering: - x = x + repr(i) + '.' - args = x + ' ' + args - self.contents.append((level, args, self.nodename)) - self.write('<', type, '>') - self.expand(args) - self.write('\n') - if self.debugging or self.print_headers: - print('---', args) - - def do_contents(self, args): - # pass - self.listcontents('Table of Contents', 999) - - def do_shortcontents(self, args): - pass - # self.listcontents('Short Contents', 0) - do_summarycontents = do_shortcontents - - def listcontents(self, title, maxlevel): - self.write('

    ', title, '

    \n
      \n') - prevlevels = [0] - for level, title, node in self.contents: - if level > maxlevel: - continue - if level > prevlevels[-1]: - # can only advance one level at a time - self.write(' '*prevlevels[-1], '
        \n') - prevlevels.append(level) - elif level < prevlevels[-1]: - # might drop back multiple levels - while level < prevlevels[-1]: - del prevlevels[-1] - self.write(' '*prevlevels[-1], - '
      \n') - self.write(' '*level, '
    • ') - self.expand(title) - self.write('\n') - self.write('
    \n' * len(prevlevels)) - - # --- Page lay-out --- - - # These commands are only meaningful in printed text - - def do_page(self, args): pass - - def do_need(self, args): pass - - def bgn_group(self, args): pass - def end_group(self): pass - - # --- Line lay-out --- - - def do_sp(self, args): - if self.nofill: - self.write('\n') - else: - self.write('

    \n') - - def do_hline(self, args): - self.write('


    ') - - # --- Function and variable definitions --- - - def bgn_deffn(self, args): - self.write('
    ') - self.do_deffnx(args) - - def end_deffn(self): - self.write('
    \n') - - def do_deffnx(self, args): - self.write('
    ') - words = splitwords(args, 2) - [category, name], rest = words[:2], words[2:] - self.expand('@b{%s}' % name) - for word in rest: self.expand(' ' + makevar(word)) - #self.expand(' -- ' + category) - self.write('\n
    ') - self.index('fn', name) - - def bgn_defun(self, args): self.bgn_deffn('Function ' + args) - end_defun = end_deffn - def do_defunx(self, args): self.do_deffnx('Function ' + args) - - def bgn_defmac(self, args): self.bgn_deffn('Macro ' + args) - end_defmac = end_deffn - def do_defmacx(self, args): self.do_deffnx('Macro ' + args) - - def bgn_defspec(self, args): self.bgn_deffn('{Special Form} ' + args) - end_defspec = end_deffn - def do_defspecx(self, args): self.do_deffnx('{Special Form} ' + args) - - def bgn_defvr(self, args): - self.write('
    ') - self.do_defvrx(args) - - end_defvr = end_deffn - - def do_defvrx(self, args): - self.write('
    ') - words = splitwords(args, 2) - [category, name], rest = words[:2], words[2:] - self.expand('@code{%s}' % name) - # If there are too many arguments, show them - for word in rest: self.expand(' ' + word) - #self.expand(' -- ' + category) - self.write('\n
    ') - self.index('vr', name) - - def bgn_defvar(self, args): self.bgn_defvr('Variable ' + args) - end_defvar = end_defvr - def do_defvarx(self, args): self.do_defvrx('Variable ' + args) - - def bgn_defopt(self, args): self.bgn_defvr('{User Option} ' + args) - end_defopt = end_defvr - def do_defoptx(self, args): self.do_defvrx('{User Option} ' + args) - - # --- Ditto for typed languages --- - - def bgn_deftypefn(self, args): - self.write('
    ') - self.do_deftypefnx(args) - - end_deftypefn = end_deffn - - def do_deftypefnx(self, args): - self.write('
    ') - words = splitwords(args, 3) - [category, datatype, name], rest = words[:3], words[3:] - self.expand('@code{%s} @b{%s}' % (datatype, name)) - for word in rest: self.expand(' ' + makevar(word)) - #self.expand(' -- ' + category) - self.write('\n
    ') - self.index('fn', name) - - - def bgn_deftypefun(self, args): self.bgn_deftypefn('Function ' + args) - end_deftypefun = end_deftypefn - def do_deftypefunx(self, args): self.do_deftypefnx('Function ' + args) - - def bgn_deftypevr(self, args): - self.write('
    ') - self.do_deftypevrx(args) - - end_deftypevr = end_deftypefn - - def do_deftypevrx(self, args): - self.write('
    ') - words = splitwords(args, 3) - [category, datatype, name], rest = words[:3], words[3:] - self.expand('@code{%s} @b{%s}' % (datatype, name)) - # If there are too many arguments, show them - for word in rest: self.expand(' ' + word) - #self.expand(' -- ' + category) - self.write('\n
    ') - self.index('fn', name) - - def bgn_deftypevar(self, args): - self.bgn_deftypevr('Variable ' + args) - end_deftypevar = end_deftypevr - def do_deftypevarx(self, args): - self.do_deftypevrx('Variable ' + args) - - # --- Ditto for object-oriented languages --- - - def bgn_defcv(self, args): - self.write('
    ') - self.do_defcvx(args) - - end_defcv = end_deftypevr - - def do_defcvx(self, args): - self.write('
    ') - words = splitwords(args, 3) - [category, classname, name], rest = words[:3], words[3:] - self.expand('@b{%s}' % name) - # If there are too many arguments, show them - for word in rest: self.expand(' ' + word) - #self.expand(' -- %s of @code{%s}' % (category, classname)) - self.write('\n
    ') - self.index('vr', '%s @r{on %s}' % (name, classname)) - - def bgn_defivar(self, args): - self.bgn_defcv('{Instance Variable} ' + args) - end_defivar = end_defcv - def do_defivarx(self, args): - self.do_defcvx('{Instance Variable} ' + args) - - def bgn_defop(self, args): - self.write('
    ') - self.do_defopx(args) - - end_defop = end_defcv - - def do_defopx(self, args): - self.write('
    ') - words = splitwords(args, 3) - [category, classname, name], rest = words[:3], words[3:] - self.expand('@b{%s}' % name) - for word in rest: self.expand(' ' + makevar(word)) - #self.expand(' -- %s of @code{%s}' % (category, classname)) - self.write('\n
    ') - self.index('fn', '%s @r{on %s}' % (name, classname)) - - def bgn_defmethod(self, args): - self.bgn_defop('Method ' + args) - end_defmethod = end_defop - def do_defmethodx(self, args): - self.do_defopx('Method ' + args) - - # --- Ditto for data types --- - - def bgn_deftp(self, args): - self.write('
    ') - self.do_deftpx(args) - - end_deftp = end_defcv - - def do_deftpx(self, args): - self.write('
    ') - words = splitwords(args, 2) - [category, name], rest = words[:2], words[2:] - self.expand('@b{%s}' % name) - for word in rest: self.expand(' ' + word) - #self.expand(' -- ' + category) - self.write('\n
    ') - self.index('tp', name) - - # --- Making Lists and Tables - - def bgn_enumerate(self, args): - if not args: - self.write('
      \n') - self.stackinfo[len(self.stack)] = '
    \n' - else: - self.itemnumber = args - self.write('
      \n') - self.stackinfo[len(self.stack)] = '
    \n' - def end_enumerate(self): - self.itemnumber = None - self.write(self.stackinfo[len(self.stack) + 1]) - del self.stackinfo[len(self.stack) + 1] - - def bgn_itemize(self, args): - self.itemarg = args - self.write('
      \n') - def end_itemize(self): - self.itemarg = None - self.write('
    \n') - - def bgn_table(self, args): - self.itemarg = args - self.write('
    \n') - def end_table(self): - self.itemarg = None - self.write('
    \n') - - def bgn_ftable(self, args): - self.itemindex = 'fn' - self.bgn_table(args) - def end_ftable(self): - self.itemindex = None - self.end_table() - - def bgn_vtable(self, args): - self.itemindex = 'vr' - self.bgn_table(args) - def end_vtable(self): - self.itemindex = None - self.end_table() - - def do_item(self, args): - if self.itemindex: self.index(self.itemindex, args) - if self.itemarg: - if self.itemarg[0] == '@' and self.itemarg[1] and \ - self.itemarg[1] in string.ascii_letters: - args = self.itemarg + '{' + args + '}' - else: - # some other character, e.g. '-' - args = self.itemarg + ' ' + args - if self.itemnumber is not None: - args = self.itemnumber + '. ' + args - self.itemnumber = increment(self.itemnumber) - if self.stack and self.stack[-1] == 'table': - self.write('
    ') - self.expand(args) - self.write('\n
    ') - elif self.stack and self.stack[-1] == 'multitable': - self.write('') - self.expand(args) - self.write('\n\n') - else: - self.write('
  • ') - self.expand(args) - self.write(' ') - do_itemx = do_item # XXX Should suppress leading blank line - - # rpyron 2002-05-07 multitable support - def bgn_multitable(self, args): - self.itemarg = None # should be handled by columnfractions - self.write('\n') - def end_multitable(self): - self.itemarg = None - self.write('
    \n
    \n') - def handle_columnfractions(self): - # It would be better to handle this, but for now it's in the way... - self.itemarg = None - def handle_tab(self): - self.write('\n ') - - # --- Enumerations, displays, quotations --- - # XXX Most of these should increase the indentation somehow - - def bgn_quotation(self, args): self.write('
    ') - def end_quotation(self): self.write('
    \n') - - def bgn_example(self, args): - self.nofill = self.nofill + 1 - self.write('
    ')
    -    def end_example(self):
    -        self.write('
    \n') - self.nofill = self.nofill - 1 - - bgn_lisp = bgn_example # Synonym when contents are executable lisp code - end_lisp = end_example - - bgn_smallexample = bgn_example # XXX Should use smaller font - end_smallexample = end_example - - bgn_smalllisp = bgn_lisp # Ditto - end_smalllisp = end_lisp - - bgn_display = bgn_example - end_display = end_example - - bgn_format = bgn_display - end_format = end_display - - def do_exdent(self, args): self.expand(args + '\n') - # XXX Should really mess with indentation - - def bgn_flushleft(self, args): - self.nofill = self.nofill + 1 - self.write('
    \n')
    -    def end_flushleft(self):
    -        self.write('
    \n') - self.nofill = self.nofill - 1 - - def bgn_flushright(self, args): - self.nofill = self.nofill + 1 - self.write('
    \n') - def end_flushright(self): - self.write('
    \n') - self.nofill = self.nofill - 1 - - def bgn_menu(self, args): - self.write('\n') - self.write(' Menu

    \n') - self.htmlhelp.beginmenu() - def end_menu(self): - self.write('

    \n') - self.htmlhelp.endmenu() - - def bgn_cartouche(self, args): pass - def end_cartouche(self): pass - - # --- Indices --- - - def resetindex(self): - self.noncodeindices = ['cp'] - self.indextitle = {} - self.indextitle['cp'] = 'Concept' - self.indextitle['fn'] = 'Function' - self.indextitle['ky'] = 'Keyword' - self.indextitle['pg'] = 'Program' - self.indextitle['tp'] = 'Type' - self.indextitle['vr'] = 'Variable' - # - self.whichindex = {} - for name in self.indextitle: - self.whichindex[name] = [] - - def user_index(self, name, args): - if name in self.whichindex: - self.index(name, args) - else: - print('*** No index named', repr(name)) - - def do_cindex(self, args): self.index('cp', args) - def do_findex(self, args): self.index('fn', args) - def do_kindex(self, args): self.index('ky', args) - def do_pindex(self, args): self.index('pg', args) - def do_tindex(self, args): self.index('tp', args) - def do_vindex(self, args): self.index('vr', args) - - def index(self, name, args): - self.whichindex[name].append((args, self.nodename)) - self.htmlhelp.index(args, self.nodename) - - def do_synindex(self, args): - words = args.split() - if len(words) != 2: - print('*** bad @synindex', args) - return - [old, new] = words - if old not in self.whichindex or \ - new not in self.whichindex: - print('*** bad key(s) in @synindex', args) - return - if old != new and \ - self.whichindex[old] is not self.whichindex[new]: - inew = self.whichindex[new] - inew[len(inew):] = self.whichindex[old] - self.whichindex[old] = inew - do_syncodeindex = do_synindex # XXX Should use code font - - def do_printindex(self, args): - words = args.split() - for name in words: - if name in self.whichindex: - self.prindex(name) - else: - print('*** No index named', repr(name)) - - def prindex(self, name): - iscodeindex = (name not in self.noncodeindices) - index = self.whichindex[name] - if not index: return - if self.debugging: - print('!'*self.debugging, '--- Generating', \ - self.indextitle[name], 'index') - # The node already provides a title - index1 = [] - junkprog = re.compile('^(@[a-z]+)?{') - for key, node in index: - sortkey = key.lower() - # Remove leading `@cmd{' from sort key - # -- don't bother about the matching `}' - oldsortkey = sortkey - while 1: - mo = junkprog.match(sortkey) - if not mo: - break - i = mo.end() - sortkey = sortkey[i:] - index1.append((sortkey, key, node)) - del index[:] - index1.sort() - self.write('
    \n') - prevkey = prevnode = None - for sortkey, key, node in index1: - if (key, node) == (prevkey, prevnode): - continue - if self.debugging > 1: print('!'*self.debugging, key, ':', node) - self.write('
    ') - if iscodeindex: key = '@code{' + key + '}' - if key != prevkey: - self.expand(key) - self.write('\n
    %s\n' % (makefile(node), node)) - prevkey, prevnode = key, node - self.write('
    \n') - - # --- Final error reports --- - - def report(self): - if self.unknown: - print('--- Unrecognized commands ---') - cmds = sorted(self.unknown.keys()) - for cmd in cmds: - print(cmd.ljust(20), self.unknown[cmd]) - - -class TexinfoParserHTML3(TexinfoParser): - - COPYRIGHT_SYMBOL = "©" - FN_ID_PATTERN = "[%(id)s]" - FN_SOURCE_PATTERN = '' + FN_ID_PATTERN + '' - FN_TARGET_PATTERN = '\n' \ - '

    ' + FN_ID_PATTERN \ - + '\n%(text)s

    \n' - FN_HEADER = '
    \n
    \n' \ - ' Footnotes\n

    \n' - - Node = HTML3Node - - def bgn_quotation(self, args): self.write('') - def end_quotation(self): self.write('\n') - - def bgn_example(self, args): - # this use of would not be legal in HTML 2.0, - # but is in more recent DTDs. - self.nofill = self.nofill + 1 - self.write('

    ')
    -    def end_example(self):
    -        self.write("
    \n") - self.nofill = self.nofill - 1 - - def bgn_flushleft(self, args): - self.nofill = self.nofill + 1 - self.write('
    \n')
    -
    -    def bgn_flushright(self, args):
    -        self.nofill = self.nofill + 1
    -        self.write('
    \n') - def end_flushright(self): - self.write('
    \n') - self.nofill = self.nofill - 1 - - def bgn_menu(self, args): - self.write('\n') - - -# rpyron 2002-05-07 -class HTMLHelp: - """ - This class encapsulates support for HTML Help. Node names, - file names, menu items, index items, and image file names are - accumulated until a call to finalize(). At that time, three - output files are created in the current directory: - - `helpbase`.hhp is a HTML Help Workshop project file. - It contains various information, some of - which I do not understand; I just copied - the default project info from a fresh - installation. - `helpbase`.hhc is the Contents file for the project. - `helpbase`.hhk is the Index file for the project. - - When these files are used as input to HTML Help Workshop, - the resulting file will be named: - - `helpbase`.chm - - If none of the defaults in `helpbase`.hhp are changed, - the .CHM file will have Contents, Index, Search, and - Favorites tabs. - """ - - codeprog = re.compile('@code{(.*?)}') - - def __init__(self,helpbase,dirname): - self.helpbase = helpbase - self.dirname = dirname - self.projectfile = None - self.contentfile = None - self.indexfile = None - self.nodelist = [] - self.nodenames = {} # nodename : index - self.nodeindex = {} - self.filenames = {} # filename : filename - self.indexlist = [] # (args,nodename) == (key,location) - self.current = '' - self.menudict = {} - self.dumped = {} - - - def addnode(self,name,next,prev,up,filename): - node = (name,next,prev,up,filename) - # add this file to dict - # retrieve list with self.filenames.values() - self.filenames[filename] = filename - # add this node to nodelist - self.nodeindex[name] = len(self.nodelist) - self.nodelist.append(node) - # set 'current' for menu items - self.current = name - self.menudict[self.current] = [] - - def menuitem(self,nodename): - menu = self.menudict[self.current] - menu.append(nodename) - - - def addimage(self,imagename): - self.filenames[imagename] = imagename - - def index(self, args, nodename): - self.indexlist.append((args,nodename)) - - def beginmenu(self): - pass - - def endmenu(self): - pass - - def finalize(self): - if not self.helpbase: - return - - # generate interesting filenames - resultfile = self.helpbase + '.chm' - projectfile = self.helpbase + '.hhp' - contentfile = self.helpbase + '.hhc' - indexfile = self.helpbase + '.hhk' - - # generate a reasonable title - title = self.helpbase - - # get the default topic file - (topname,topnext,topprev,topup,topfile) = self.nodelist[0] - defaulttopic = topfile - - # PROJECT FILE - try: - with open(projectfile, 'w') as fp: - print('[OPTIONS]', file=fp) - print('Auto Index=Yes', file=fp) - print('Binary TOC=No', file=fp) - print('Binary Index=Yes', file=fp) - print('Compatibility=1.1', file=fp) - print('Compiled file=' + resultfile + '', file=fp) - print('Contents file=' + contentfile + '', file=fp) - print('Default topic=' + defaulttopic + '', file=fp) - print('Error log file=ErrorLog.log', file=fp) - print('Index file=' + indexfile + '', file=fp) - print('Title=' + title + '', file=fp) - print('Display compile progress=Yes', file=fp) - print('Full-text search=Yes', file=fp) - print('Default window=main', file=fp) - print('', file=fp) - print('[WINDOWS]', file=fp) - print('main=,"' + contentfile + '","' + indexfile - + '","","",,,,,0x23520,222,0x1046,[10,10,780,560],' - '0xB0000,,,,,,0', file=fp) - print('', file=fp) - print('[FILES]', file=fp) - print('', file=fp) - self.dumpfiles(fp) - except IOError as msg: - print(projectfile, ':', msg) - sys.exit(1) - - # CONTENT FILE - try: - with open(contentfile, 'w') as fp: - print('', file=fp) - print('', file=fp) - print('', file=fp) - print('', file=fp) - print('', file=fp) - print('', file=fp) - print('', file=fp) - print('', file=fp) - print(' ', file=fp) - print(' ', file=fp) - print(' ', file=fp) - print(' ', file=fp) - print(' ', file=fp) - self.dumpnodes(fp) - print('', file=fp) - print('', file=fp) - except IOError as msg: - print(contentfile, ':', msg) - sys.exit(1) - - # INDEX FILE - try: - with open(indexfile, 'w') as fp: - print('', file=fp) - print('', file=fp) - print('', file=fp) - print('', file=fp) - print('', file=fp) - print('', file=fp) - print('', file=fp) - print('', file=fp) - print('', file=fp) - print('', file=fp) - self.dumpindex(fp) - print('', file=fp) - print('', file=fp) - except IOError as msg: - print(indexfile , ':', msg) - sys.exit(1) - - def dumpfiles(self, outfile=sys.stdout): - filelist = sorted(self.filenames.values()) - for filename in filelist: - print(filename, file=outfile) - - def dumpnodes(self, outfile=sys.stdout): - self.dumped = {} - if self.nodelist: - nodename, dummy, dummy, dummy, dummy = self.nodelist[0] - self.topnode = nodename - - print('
      ', file=outfile) - for node in self.nodelist: - self.dumpnode(node,0,outfile) - print('
    ', file=outfile) - - def dumpnode(self, node, indent=0, outfile=sys.stdout): - if node: - # Retrieve info for this node - (nodename,next,prev,up,filename) = node - self.current = nodename - - # Have we been dumped already? - if nodename in self.dumped: - return - self.dumped[nodename] = 1 - - # Print info for this node - print(' '*indent, end=' ', file=outfile) - print('
  • ', end=' ', file=outfile) - print('', end=' ', file=outfile) - print('', end=' ', file=outfile) - print('', file=outfile) - - # Does this node have menu items? - try: - menu = self.menudict[nodename] - self.dumpmenu(menu,indent+2,outfile) - except KeyError: - pass - - def dumpmenu(self, menu, indent=0, outfile=sys.stdout): - if menu: - currentnode = self.current - if currentnode != self.topnode: # XXX this is a hack - print(' '*indent + '
      ', file=outfile) - indent += 2 - for item in menu: - menunode = self.getnode(item) - self.dumpnode(menunode,indent,outfile) - if currentnode != self.topnode: # XXX this is a hack - print(' '*indent + '
    ', file=outfile) - indent -= 2 - - def getnode(self, nodename): - try: - index = self.nodeindex[nodename] - return self.nodelist[index] - except KeyError: - return None - except IndexError: - return None - - # (args,nodename) == (key,location) - def dumpindex(self, outfile=sys.stdout): - print('
      ', file=outfile) - for (key,location) in self.indexlist: - key = self.codeexpand(key) - location = makefile(location) - location = self.dirname + '/' + location - print('
    • ', end=' ', file=outfile) - print('', end=' ', file=outfile) - print('', end=' ', file=outfile) - print('', file=outfile) - print('
    ', file=outfile) - - def codeexpand(self, line): - co = self.codeprog.match(line) - if not co: - return line - bgn, end = co.span(0) - a, b = co.span(1) - line = line[:bgn] + line[a:b] + line[end:] - return line - - -# Put @var{} around alphabetic substrings -def makevar(str): - return '@var{'+str+'}' - - -# Split a string in "words" according to findwordend -def splitwords(str, minlength): - words = [] - i = 0 - n = len(str) - while i < n: - while i < n and str[i] in ' \t\n': i = i+1 - if i >= n: break - start = i - i = findwordend(str, i, n) - words.append(str[start:i]) - while len(words) < minlength: words.append('') - return words - - -# Find the end of a "word", matching braces and interpreting @@ @{ @} -fwprog = re.compile('[@{} ]') -def findwordend(str, i, n): - level = 0 - while i < n: - mo = fwprog.search(str, i) - if not mo: - break - i = mo.start() - c = str[i]; i = i+1 - if c == '@': i = i+1 # Next character is not special - elif c == '{': level = level+1 - elif c == '}': level = level-1 - elif c == ' ' and level <= 0: return i-1 - return n - - -# Convert a node name into a file name -def makefile(nodename): - nodename = nodename.strip() - return fixfunnychars(nodename) + '.html' - - -# Characters that are perfectly safe in filenames and hyperlinks -goodchars = string.ascii_letters + string.digits + '!@-=+.' - -# Replace characters that aren't perfectly safe by dashes -# Underscores are bad since Cern HTTPD treats them as delimiters for -# encoding times, so you get mismatches if you compress your files: -# a.html.gz will map to a_b.html.gz -def fixfunnychars(addr): - i = 0 - while i < len(addr): - c = addr[i] - if c not in goodchars: - c = '-' - addr = addr[:i] + c + addr[i+1:] - i = i + len(c) - return addr - - -# Increment a string used as an enumeration -def increment(s): - if not s: - return '1' - for sequence in string.digits, string.ascii_lowercase, string.ascii_uppercase: - lastc = s[-1] - if lastc in sequence: - i = sequence.index(lastc) + 1 - if i >= len(sequence): - if len(s) == 1: - s = sequence[0]*2 - if s == '00': - s = '10' - else: - s = increment(s[:-1]) + sequence[0] - else: - s = s[:-1] + sequence[i] - return s - return s # Don't increment - - -def test(): - import sys - debugging = 0 - print_headers = 0 - cont = 0 - html3 = 0 - htmlhelp = '' - - while sys.argv[1] == ['-d']: - debugging = debugging + 1 - del sys.argv[1] - if sys.argv[1] == '-p': - print_headers = 1 - del sys.argv[1] - if sys.argv[1] == '-c': - cont = 1 - del sys.argv[1] - if sys.argv[1] == '-3': - html3 = 1 - del sys.argv[1] - if sys.argv[1] == '-H': - helpbase = sys.argv[2] - del sys.argv[1:3] - if len(sys.argv) != 3: - print('usage: texi2hh [-d [-d]] [-p] [-c] [-3] [-H htmlhelp]', \ - 'inputfile outputdirectory') - sys.exit(2) - - if html3: - parser = TexinfoParserHTML3() - else: - parser = TexinfoParser() - parser.cont = cont - parser.debugging = debugging - parser.print_headers = print_headers - - file = sys.argv[1] - dirname = sys.argv[2] - parser.setdirname(dirname) - parser.setincludedir(os.path.dirname(file)) - - htmlhelp = HTMLHelp(helpbase, dirname) - parser.sethtmlhelp(htmlhelp) - - try: - fp = open(file, 'r') - except IOError as msg: - print(file, ':', msg) - sys.exit(1) - - with fp: - parser.parse(fp) - parser.report() - - htmlhelp.finalize() - - -if __name__ == "__main__": - test() diff --git a/Tools/scripts/which.py b/Tools/scripts/which.py deleted file mode 100755 index b42e07c7..00000000 --- a/Tools/scripts/which.py +++ /dev/null @@ -1,61 +0,0 @@ -#! /usr/bin/env python3 - -# Variant of "which". -# On stderr, near and total misses are reported. -# '-l' argument adds ls -l of each file found. - -import sys -if sys.path[0] in (".", ""): del sys.path[0] - -import sys, os -from stat import * - -def msg(str): - sys.stderr.write(str + '\n') - -def main(): - pathlist = os.environ['PATH'].split(os.pathsep) - - sts = 0 - longlist = '' - - if sys.argv[1:] and sys.argv[1][:2] == '-l': - longlist = sys.argv[1] - del sys.argv[1] - - for prog in sys.argv[1:]: - ident = () - for dir in pathlist: - filename = os.path.join(dir, prog) - try: - st = os.stat(filename) - except OSError: - continue - if not S_ISREG(st[ST_MODE]): - msg(filename + ': not a disk file') - else: - mode = S_IMODE(st[ST_MODE]) - if mode & 0o111: - if not ident: - print(filename) - ident = st[:3] - else: - if st[:3] == ident: - s = 'same as: ' - else: - s = 'also: ' - msg(s + filename) - else: - msg(filename + ': not executable') - if longlist: - sts = os.system('ls ' + longlist + ' ' + filename) - sts = os.waitstatus_to_exitcode(sts) - if sts: msg('"ls -l" exit status: ' + repr(sts)) - if not ident: - msg(prog + ': not found') - sts = 1 - - sys.exit(sts) - -if __name__ == '__main__': - main() diff --git a/Tools/scripts/win_add2path.py b/Tools/scripts/win_add2path.py deleted file mode 100644 index 1c9aedc5..00000000 --- a/Tools/scripts/win_add2path.py +++ /dev/null @@ -1,58 +0,0 @@ -"""Add Python to the search path on Windows - -This is a simple script to add Python to the Windows search path. It -modifies the current user (HKCU) tree of the registry. - -Copyright (c) 2008 by Christian Heimes -Licensed to PSF under a Contributor Agreement. -""" - -import sys -import site -import os -import winreg - -HKCU = winreg.HKEY_CURRENT_USER -ENV = "Environment" -PATH = "PATH" -DEFAULT = "%PATH%" - -def modify(): - pythonpath = os.path.dirname(os.path.normpath(sys.executable)) - scripts = os.path.join(pythonpath, "Scripts") - appdata = os.environ["APPDATA"] - if hasattr(site, "USER_SITE"): - usersite = site.USER_SITE.replace(appdata, "%APPDATA%") - userpath = os.path.dirname(usersite) - userscripts = os.path.join(userpath, "Scripts") - else: - userscripts = None - - with winreg.CreateKey(HKCU, ENV) as key: - try: - envpath = winreg.QueryValueEx(key, PATH)[0] - except OSError: - envpath = DEFAULT - - paths = [envpath] - for path in (pythonpath, scripts, userscripts): - if path and path not in envpath and os.path.isdir(path): - paths.append(path) - - envpath = os.pathsep.join(paths) - winreg.SetValueEx(key, PATH, 0, winreg.REG_EXPAND_SZ, envpath) - return paths, envpath - -def main(): - paths, envpath = modify() - if len(paths) > 1: - print("Path(s) added:") - print('\n'.join(paths[1:])) - else: - print("No path was added") - print("\nPATH is now:\n%s\n" % envpath) - print("Expanded:") - print(winreg.ExpandEnvironmentStrings(envpath)) - -if __name__ == '__main__': - main() diff --git a/Tools/ssl/multissltests.py b/Tools/ssl/multissltests.py index b1aacfa5..f066fb52 100755 --- a/Tools/ssl/multissltests.py +++ b/Tools/ssl/multissltests.py @@ -35,7 +35,6 @@ except ImportError: from urllib2 import urlopen, HTTPError import re import shutil -import string import subprocess import sys import tarfile @@ -47,8 +46,9 @@ OPENSSL_OLD_VERSIONS = [ ] OPENSSL_RECENT_VERSIONS = [ - "1.1.1q", - "3.0.5" + "1.1.1w", + "3.0.11", + "3.1.3", ] LIBRESSL_OLD_VERSIONS = [ @@ -359,7 +359,7 @@ class AbstractBuilder(object): env["LD_RUN_PATH"] = self.lib_dir log.info("Rebuilding Python modules") - cmd = [sys.executable, os.path.join(PYTHONROOT, "setup.py"), "build"] + cmd = ["make", "sharedmods", "checksharedmods"] self._subprocess_call(cmd, env=env) self.check_imports() @@ -473,7 +473,7 @@ def main(): start = datetime.now() if args.steps in {'modules', 'tests'}: - for name in ['setup.py', 'Modules/_ssl.c']: + for name in ['Makefile.pre.in', 'Modules/_ssl.c']: if not os.path.isfile(os.path.join(PYTHONROOT, name)): parser.error( "Must be executed from CPython build dir" diff --git a/Tools/unicode/genmap_tchinese.py b/Tools/unicode/genmap_tchinese.py new file mode 100644 index 00000000..a416cf3d --- /dev/null +++ b/Tools/unicode/genmap_tchinese.py @@ -0,0 +1,239 @@ +# +# genmap_tchinese.py: Traditional Chinese Codecs Map Generator +# +# Original Author: Hye-Shik Chang +# +import os + +from genmap_support import * + + +# ranges for (lead byte, follower byte) +BIG5_C1 = (0xa1, 0xfe) +BIG5_C2 = (0x40, 0xfe) +BIG5HKSCS_C1 = (0x87, 0xfe) +BIG5HKSCS_C2 = (0x40, 0xfe) + +MAPPINGS_BIG5 = 'https://unicode.org/Public/MAPPINGS/OBSOLETE/EASTASIA/OTHER/BIG5.TXT' +MAPPINGS_CP950 = 'https://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP950.TXT' + +HKSCS_VERSION = '2004' +# The files for HKSCS mappings are available under a restrictive license. +# Users of the script need to download the files from the HKSARG CCLI website: +MAPPINGS_HKSCS = f'https://www.ccli.gov.hk/en/archive/terms_hkscs-{HKSCS_VERSION}-big5-iso.html' + + +def bh2s(code): + return ((code >> 8) - 0x87) * (0xfe - 0x40 + 1) + ((code & 0xff) - 0x40) + + +def split_bytes(code): + """Split 0xABCD into 0xAB, 0xCD""" + return code >> 8, code & 0xff + + +def parse_hkscs_map(fo): + fo.seek(0, 0) + table = [] + for line in fo: + line = line.split('#', 1)[0].strip() + # We expect 4 columns in supported HKSCS files: + # [1999]: unsupported + # [2001]: unsupported + # [2004]: Big-5; iso10646-1:1993; iso10646-1:2000; iso10646:2003+amd1 + # [2008]: Big-5; iso10646-1:1993; iso10646-1:2000; iso10646:2003+amd6 + # [2016]: not supported here--uses a json file instead + # + # In both supported cases, we only need the first and last column: + # * Big-5 is a hex string (always 4 digits) + # * iso10646:2003 is either a hex string (4 or 5 digits) or a sequence + # of hex strings like: `` + try: + hkscs_col, _, _, uni_col = line.split() + hkscs = int(hkscs_col, 16) + seq = tuple(int(cp, 16) for cp in uni_col.strip('<>').split(',')) + except ValueError: + continue + table.append((hkscs, seq)) + return table + + +def make_hkscs_map(table): + decode_map = {} + encode_map_bmp, encode_map_notbmp = {}, {} + is_bmp_map = {} + sequences = [] + beginnings = {} + single_cp_table = [] + # Determine multi-codepoint sequences, and sequence beginnings that encode + # multiple multibyte (i.e. Big-5) codes. + for mbcode, cp_seq in table: + cp, *_ = cp_seq + if len(cp_seq) == 1: + single_cp_table.append((mbcode, cp)) + else: + sequences.append((mbcode, cp_seq)) + beginnings.setdefault(cp, []).append(mbcode) + # Decode table only cares about single code points (no sequences) currently + for mbcode, cp in single_cp_table: + b1, b2 = split_bytes(mbcode) + decode_map.setdefault(b1, {}) + decode_map[b1][b2] = cp & 0xffff + # Encode table needs to mark code points beginning a sequence as tuples. + for cp, mbcodes in beginnings.items(): + plane = cp >> 16 + if plane == 0: + encode_map = encode_map_bmp + elif plane == 2: + encode_map = encode_map_notbmp + is_bmp_map[bh2s(mbcodes[0])] = 1 + else: + assert False, 'only plane 0 (BMP) and plane 2 (SIP) allowed' + if len(mbcodes) == 1: + encode_value = mbcodes[0] + else: + encode_value = tuple(mbcodes) + uni_b1, uni_b2 = split_bytes(cp & 0xffff) + encode_map.setdefault(uni_b1, {}) + encode_map[uni_b1][uni_b2] = encode_value + + return decode_map, encode_map_bmp, encode_map_notbmp, is_bmp_map + + +def load_big5_map(): + mapfile = open_mapping_file('python-mappings/BIG5.txt', MAPPINGS_BIG5) + with mapfile: + big5decmap = loadmap(mapfile) + # big5 mapping fix: use the cp950 mapping for these characters as the file + # provided by unicode.org doesn't define a mapping. See notes in BIG5.txt. + # Since U+5341, U+5345, U+FF0F, U+FF3C already have a big5 mapping, no + # roundtrip compatibility is guaranteed for those. + for m in """\ + 0xA15A 0x2574 + 0xA1C3 0xFFE3 + 0xA1C5 0x02CD + 0xA1FE 0xFF0F + 0xA240 0xFF3C + 0xA2CC 0x5341 + 0xA2CE 0x5345""".splitlines(): + bcode, ucode = list(map(eval, m.split())) + big5decmap[bcode >> 8][bcode & 0xff] = ucode + # encoding map + big5encmap = {} + for c1, m in list(big5decmap.items()): + for c2, code in list(m.items()): + big5encmap.setdefault(code >> 8, {}) + if code & 0xff not in big5encmap[code >> 8]: + big5encmap[code >> 8][code & 0xff] = c1 << 8 | c2 + # fix unicode->big5 priority for the above-mentioned duplicate characters + big5encmap[0xFF][0x0F] = 0xA241 + big5encmap[0xFF][0x3C] = 0xA242 + big5encmap[0x53][0x41] = 0xA451 + big5encmap[0x53][0x45] = 0xA4CA + + return big5decmap, big5encmap + + +def load_cp950_map(): + mapfile = open_mapping_file('python-mappings/CP950.TXT', MAPPINGS_CP950) + with mapfile: + cp950decmap = loadmap(mapfile) + cp950encmap = {} + for c1, m in list(cp950decmap.items()): + for c2, code in list(m.items()): + cp950encmap.setdefault(code >> 8, {}) + if code & 0xff not in cp950encmap[code >> 8]: + cp950encmap[code >> 8][code & 0xff] = c1 << 8 | c2 + # fix unicode->big5 duplicated mapping priority + cp950encmap[0x53][0x41] = 0xA451 + cp950encmap[0x53][0x45] = 0xA4CA + return cp950decmap, cp950encmap + + +def main_tw(): + big5decmap, big5encmap = load_big5_map() + cp950decmap, cp950encmap = load_cp950_map() + + # CP950 extends Big5, and the codec can use the Big5 lookup tables + # for most entries. So the CP950 tables should only include entries + # that are not in Big5: + for c1, m in list(cp950encmap.items()): + for c2, code in list(m.items()): + if (c1 in big5encmap and c2 in big5encmap[c1] + and big5encmap[c1][c2] == code): + del cp950encmap[c1][c2] + for c1, m in list(cp950decmap.items()): + for c2, code in list(m.items()): + if (c1 in big5decmap and c2 in big5decmap[c1] + and big5decmap[c1][c2] == code): + del cp950decmap[c1][c2] + + with open('mappings_tw.h', 'w') as fp: + print_autogen(fp, os.path.basename(__file__)) + write_big5_maps(fp, 'BIG5', 'big5', big5decmap, big5encmap) + write_big5_maps(fp, 'CP950', 'cp950ext', cp950decmap, cp950encmap) + + +def write_big5_maps(fp, display_name, table_name, decode_map, encode_map): + print(f'Generating {display_name} decode map...') + writer = DecodeMapWriter(fp, table_name, decode_map) + writer.update_decode_map(BIG5_C1, BIG5_C2) + writer.generate() + print(f'Generating {display_name} encode map...') + writer = EncodeMapWriter(fp, table_name, encode_map) + writer.generate() + + +class HintsWriter: + filler_class = BufferedFiller + + def __init__(self, fp, prefix, isbmpmap): + self.fp = fp + self.prefix = prefix + self.isbmpmap = isbmpmap + self.filler = self.filler_class() + + def fillhints(self, hintfrom, hintto): + name = f'{self.prefix}_phint_{hintfrom}' + self.fp.write(f'static const unsigned char {name}[] = {{\n') + for msbcode in range(hintfrom, hintto+1, 8): + v = 0 + for c in range(msbcode, msbcode+8): + v |= self.isbmpmap.get(c, 0) << (c - msbcode) + self.filler.write('%d,' % v) + self.filler.printout(self.fp) + self.fp.write('};\n\n') + + +def main_hkscs(): + filename = f'python-mappings/hkscs-{HKSCS_VERSION}-big5-iso.txt' + with open_mapping_file(filename, MAPPINGS_HKSCS) as f: + table = parse_hkscs_map(f) + hkscsdecmap, hkscsencmap_bmp, hkscsencmap_nonbmp, isbmpmap = ( + make_hkscs_map(table) + ) + with open('mappings_hk.h', 'w') as fp: + print('Generating BIG5HKSCS decode map...') + print_autogen(fp, os.path.basename(__file__)) + writer = DecodeMapWriter(fp, 'big5hkscs', hkscsdecmap) + writer.update_decode_map(BIG5HKSCS_C1, BIG5HKSCS_C2) + writer.generate() + + print('Generating BIG5HKSCS decode map Unicode plane hints...') + writer = HintsWriter(fp, 'big5hkscs', isbmpmap) + writer.fillhints(bh2s(0x8740), bh2s(0xa0fe)) + writer.fillhints(bh2s(0xc6a1), bh2s(0xc8fe)) + writer.fillhints(bh2s(0xf9d6), bh2s(0xfefe)) + + print('Generating BIG5HKSCS encode map (BMP)...') + writer = EncodeMapWriter(fp, 'big5hkscs_bmp', hkscsencmap_bmp) + writer.generate() + + print('Generating BIG5HKSCS encode map (non-BMP)...') + writer = EncodeMapWriter(fp, 'big5hkscs_nonbmp', hkscsencmap_nonbmp) + writer.generate() + + +if __name__ == '__main__': + main_tw() + main_hkscs() diff --git a/Tools/unicode/genwincodecs.bat b/Tools/unicode/genwincodecs.bat index ad45c6c4..43cab0d6 100644 --- a/Tools/unicode/genwincodecs.bat +++ b/Tools/unicode/genwincodecs.bat @@ -1,7 +1,7 @@ -@rem Recreate some python charmap codecs from the Windows function -@rem MultiByteToWideChar. - -@cd /d %~dp0 -@mkdir build -@rem Arabic DOS code page -c:\python30\python genwincodec.py 720 > build/cp720.py +@rem Recreate some python charmap codecs from the Windows function +@rem MultiByteToWideChar. + +@cd /d %~dp0 +@mkdir build +@rem Arabic DOS code page +c:\python30\python genwincodec.py 720 > build/cp720.py diff --git a/Tools/unicode/makeunicodedata.py b/Tools/unicode/makeunicodedata.py index 48948444..034642db 100644 --- a/Tools/unicode/makeunicodedata.py +++ b/Tools/unicode/makeunicodedata.py @@ -44,7 +44,7 @@ VERSION = "3.3" # * Doc/library/stdtypes.rst, and # * Doc/library/unicodedata.rst # * Doc/reference/lexical_analysis.rst (two occurrences) -UNIDATA_VERSION = "14.0.0" +UNIDATA_VERSION = "15.0.0" UNICODE_DATA = "UnicodeData%s.txt" COMPOSITION_EXCLUSIONS = "CompositionExclusions%s.txt" EASTASIAN_WIDTH = "EastAsianWidth%s.txt" @@ -77,7 +77,8 @@ BIDIRECTIONAL_NAMES = [ "", "L", "LRE", "LRO", "R", "AL", "RLE", "RLO", "PDF", "EN", "ES", "ET", "AN", "CS", "NSM", "BN", "B", "S", "WS", "ON", "LRI", "RLI", "FSI", "PDI" ] -EASTASIANWIDTH_NAMES = [ "F", "H", "W", "Na", "A", "N" ] +# "N" needs to be the first entry, see the comment in makeunicodedata +EASTASIANWIDTH_NAMES = [ "N", "H", "W", "Na", "A", "F" ] MANDATORY_LINE_BREAKS = [ "BK", "CR", "LF", "NL" ] @@ -103,11 +104,12 @@ cjk_ranges = [ ('3400', '4DBF'), ('4E00', '9FFF'), ('20000', '2A6DF'), - ('2A700', '2B738'), + ('2A700', '2B739'), ('2B740', '2B81D'), ('2B820', '2CEA1'), ('2CEB0', '2EBE0'), ('30000', '3134A'), + ('31350', '323AF'), ] @@ -135,6 +137,14 @@ def maketables(trace=0): def makeunicodedata(unicode, trace): + # the default value of east_asian_width is "N", for unassigned code points + # not mentioned in EastAsianWidth.txt + # in addition there are some reserved but unassigned code points in CJK + # ranges that are classified as "W". code points in private use areas + # have a width of "A". both of these have entries in + # EastAsianWidth.txt + # see https://unicode.org/reports/tr11/#Unassigned + assert EASTASIANWIDTH_NAMES[0] == "N" dummy = (0, 0, 0, 0, 0, 0) table = [dummy] cache = {0: dummy} @@ -160,15 +170,24 @@ def makeunicodedata(unicode, trace): category, combining, bidirectional, mirrored, eastasianwidth, normalizationquickcheck ) - # add entry to index and item tables - i = cache.get(item) - if i is None: - cache[item] = i = len(table) - table.append(item) - index[char] = i + elif unicode.widths[char] is not None: + # an unassigned but reserved character, with a known + # east_asian_width + eastasianwidth = EASTASIANWIDTH_NAMES.index(unicode.widths[char]) + item = (0, 0, 0, 0, eastasianwidth, 0) + else: + continue + + # add entry to index and item tables + i = cache.get(item) + if i is None: + cache[item] = i = len(table) + table.append(item) + index[char] = i # 2) decomposition data + decomp_data_cache = {} decomp_data = [0] decomp_prefix = [""] decomp_index = [0] * len(unicode.chars) @@ -207,12 +226,15 @@ def makeunicodedata(unicode, trace): comp_first[l] = 1 comp_last[r] = 1 comp_pairs.append((l,r,char)) - try: - i = decomp_data.index(decomp) - except ValueError: + key = tuple(decomp) + i = decomp_data_cache.get(key, -1) + if i == -1: i = len(decomp_data) decomp_data.extend(decomp) decomp_size = decomp_size + len(decomp) * 2 + decomp_data_cache[key] = i + else: + assert decomp_data[i:i+len(decomp)] == decomp else: i = 0 decomp_index[char] = i @@ -395,7 +417,7 @@ def makeunicodetype(unicode, trace): # extract unicode types dummy = (0, 0, 0, 0, 0, 0) table = [dummy] - cache = {0: dummy} + cache = {dummy: 0} index = [0] * len(unicode.chars) numeric = {} spaces = [] @@ -1081,6 +1103,7 @@ class UnicodeData: for i in range(0, 0x110000): if table[i] is not None: table[i].east_asian_width = widths[i] + self.widths = widths for char, (p,) in UcdFile(DERIVED_CORE_PROPERTIES, version).expanded(): if table[char]: diff --git a/Tools/wasm/.editorconfig b/Tools/wasm/.editorconfig index da1aa6ac..4de5fe59 100644 --- a/Tools/wasm/.editorconfig +++ b/Tools/wasm/.editorconfig @@ -1,4 +1,5 @@ -root = false # This extends the root .editorconfig +# This extends the root .editorconfig +root = false [*.{html,js}] trim_trailing_whitespace = true diff --git a/Tools/wasm/README.md b/Tools/wasm/README.md index fe9a1dc9..8874f9b7 100644 --- a/Tools/wasm/README.md +++ b/Tools/wasm/README.md @@ -157,7 +157,7 @@ functions. - Threading is disabled by default. The ``configure`` option ``--enable-wasm-pthreads`` adds compiler flag ``-pthread`` and - linker flags ``-sUSE_PTHREADS -sPROXY_TO_PTHREAD``. + linker flags ``-sUSE_PTHREADS -sPROXY_TO_PTHREAD``. - pthread support requires WASM threads and SharedArrayBuffer (bulk memory). The Node.JS runtime keeps a pool of web workers around. Each web worker uses several file descriptors (eventfd, epoll, pipe). @@ -168,7 +168,7 @@ functions. - Most user, group, and permission related function and modules are not supported or don't work as expected, e.g.``pwd`` module, ``grp`` module, - ``os.setgroups``, ``os.chown``, and so on. ``lchown`` and `lchmod`` are + ``os.setgroups``, ``os.chown``, and so on. ``lchown`` and ``lchmod`` are not available. - ``umask`` is a no-op. - hard links (``os.link``) are not supported. @@ -192,7 +192,7 @@ functions. supports. It's currently known to crash in combination with threading. - glibc extensions for date and time formatting are not available. - ``locales`` module is affected by musl libc issues, - [bpo-46390](https://bugs.python.org/issue46390). + [gh-90548](https://github.com/python/cpython/issues/90548). - Python's object allocator ``obmalloc`` is disabled by default. - ``ensurepip`` is not available. - Some ``ctypes`` features like ``c_longlong`` and ``c_longdouble`` may need @@ -203,7 +203,7 @@ functions. - The interactive shell does not handle copy 'n paste and unicode support well. - The bundled stdlib is limited. Network-related modules, - distutils, multiprocessing, dbm, tests and similar modules + multiprocessing, dbm, tests and similar modules are not shipped. All other modules are bundled as pre-compiled ``pyc`` files. - In-memory file system (MEMFS) is not persistent and limited. @@ -283,7 +283,7 @@ popd ## WASI limitations and issues (WASI SDK 15.0) -A lot of Emscripten limitations also apply to WASI. Noticable restrictions +A lot of Emscripten limitations also apply to WASI. Noticeable restrictions are: - Call stack size is limited. Default recursion limit and parser stack size diff --git a/Tools/wasm/Setup.local.example b/Tools/wasm/Setup.local.example index ad58c31a..cfb9f7fc 100644 --- a/Tools/wasm/Setup.local.example +++ b/Tools/wasm/Setup.local.example @@ -5,6 +5,7 @@ audioop _bz2 _crypt _decimal +nis _pickle pyexpat _elementtree _sha3 _blake2 diff --git a/Tools/wasm/config.site-wasm32-emscripten b/Tools/wasm/config.site-wasm32-emscripten index b695a7bf..1471546a 100644 --- a/Tools/wasm/config.site-wasm32-emscripten +++ b/Tools/wasm/config.site-wasm32-emscripten @@ -14,9 +14,6 @@ ac_cv_buggy_getaddrinfo=no ac_cv_file__dev_ptmx=no ac_cv_file__dev_ptc=no -# dummy readelf, Emscripten build does not need readelf. -ac_cv_prog_ac_ct_READELF=true - # new undefined symbols / unsupported features ac_cv_func_posix_spawn=no ac_cv_func_posix_spawnp=no diff --git a/Tools/wasm/config.site-wasm32-wasi b/Tools/wasm/config.site-wasm32-wasi index 893a0d13..5e987754 100644 --- a/Tools/wasm/config.site-wasm32-wasi +++ b/Tools/wasm/config.site-wasm32-wasi @@ -9,9 +9,6 @@ ac_cv_buggy_getaddrinfo=no ac_cv_file__dev_ptmx=no ac_cv_file__dev_ptc=no -# dummy readelf, WASI build does not need readelf. -ac_cv_prog_ac_ct_READELF=true - # get/setrlimit are not supported ac_cv_header_sys_resource_h=no @@ -40,3 +37,6 @@ ac_cv_header_netpacket_packet_h=no # disable accept for WASM runtimes without sock_accept #ac_cv_func_accept=no #ac_cv_func_accept4=no + +# Disable int-conversion for wask-sdk as it triggers an error from version 17. +ac_cv_disable_int_conversion=yes diff --git a/Tools/wasm/wasm_assets.py b/Tools/wasm/wasm_assets.py index 6557e3f3..1fc97fd5 100755 --- a/Tools/wasm/wasm_assets.py +++ b/Tools/wasm/wasm_assets.py @@ -6,7 +6,8 @@ contains: - a stripped down, pyc-only stdlib zip file, e.g. {PREFIX}/lib/python311.zip - os.py as marker module {PREFIX}/lib/python3.11/os.py -- empty lib-dynload directory, to make sure it is copied into the bundle {PREFIX}/lib/python3.11/lib-dynload/.empty +- empty lib-dynload directory, to make sure it is copied into the bundle: + {PREFIX}/lib/python3.11/lib-dynload/.empty """ import argparse @@ -41,16 +42,12 @@ OMIT_FILES = ( "ensurepip/", "venv/", # build system - "distutils/", "lib2to3/", # deprecated - "asyncore.py", - "asynchat.py", "uu.py", "xdrlib.py", # other platforms "_aix_support.py", - "_bootsubprocess.py", "_osx_support.py", # webbrowser "antigravity.py", @@ -79,7 +76,6 @@ OMIT_NETWORKING_FILES = ( "mailcap.py", "nntplib.py", "poplib.py", - "smtpd.py", "smtplib.py", "socketserver.py", "telnetlib.py", @@ -110,13 +106,6 @@ OMIT_MODULE_FILES = { "_zoneinfo": ["zoneinfo/"], } -# regression test sub directories -OMIT_SUBDIRS = ( - "ctypes/test/", - "tkinter/test/", - "unittest/test/", -) - SYSCONFIG_NAMES = ( "_sysconfigdata__emscripten_wasm32-emscripten", "_sysconfigdata__emscripten_wasm32-emscripten", diff --git a/Tools/wasm/wasm_build.py b/Tools/wasm/wasm_build.py index 63812c6f..c9947057 100755 --- a/Tools/wasm/wasm_build.py +++ b/Tools/wasm/wasm_build.py @@ -73,7 +73,7 @@ Builds require a clean source directory. Please use a clean checkout or run "make clean -C '{SRCDIR}'". """ -INSTALL_NATIVE = f""" +INSTALL_NATIVE = """ Builds require a C compiler (gcc, clang), make, pkg-config, and development headers for dependencies like zlib. @@ -137,7 +137,7 @@ def read_python_version(configure: pathlib.Path = CONFIGURE) -> str: configure and configure.ac are the canonical source for major and minor version number. """ - version_re = re.compile("^PACKAGE_VERSION='(\d\.\d+)'") + version_re = re.compile(r"^PACKAGE_VERSION='(\d\.\d+)'") with configure.open(encoding="utf-8") as f: for line in f: mo = version_re.match(line) @@ -480,7 +480,6 @@ class BuildProfile: cmd.append(f"--{opt}-wasm-dynamic-linking") if self.pthreads is not None: - assert self.host.is_emscripten opt = "enable" if self.pthreads else "disable" cmd.append(f"--{opt}-wasm-pthreads") @@ -598,7 +597,7 @@ class BuildProfile: end = time.monotonic() + 3.0 while time.monotonic() < end and srv.returncode is None: try: - with socket.create_connection((bind, port), timeout=0.1) as s: + with socket.create_connection((bind, port), timeout=0.1) as _: pass except OSError: time.sleep(0.01) @@ -745,6 +744,13 @@ _profiles = [ support_level=SupportLevel.supported, host=Host.wasm32_wasi, ), + # wasm32-wasi-threads + BuildProfile( + "wasi-threads", + support_level=SupportLevel.experimental, + host=Host.wasm32_wasi, + pthreads=True, + ), # no SDK available yet # BuildProfile( # "wasm64-wasi", diff --git a/aclocal.m4 b/aclocal.m4 index 6a33c0cc..da8ee95b 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -1,6 +1,6 @@ -# generated automatically by aclocal 1.16.3 -*- Autoconf -*- +# generated automatically by aclocal 1.16.4 -*- Autoconf -*- -# Copyright (C) 1996-2020 Free Software Foundation, Inc. +# Copyright (C) 1996-2021 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -184,7 +184,7 @@ AS_VAR_POPDEF([CACHEVAR])dnl # and this notice are preserved. This file is offered as-is, without any # warranty. -#serial 10 +#serial 11 AU_ALIAS([CHECK_SSL], [AX_CHECK_OPENSSL]) AC_DEFUN([AX_CHECK_OPENSSL], [ @@ -227,7 +227,7 @@ AC_DEFUN([AX_CHECK_OPENSSL], [ if ! $found; then OPENSSL_INCLUDES= for ssldir in $ssldirs; do - AC_MSG_CHECKING([for openssl/ssl.h in $ssldir]) + AC_MSG_CHECKING([for include/openssl/ssl.h in $ssldir]) if test -f "$ssldir/include/openssl/ssl.h"; then OPENSSL_INCLUDES="-I$ssldir/include" OPENSSL_LDFLAGS="-L$ssldir/lib" @@ -621,7 +621,7 @@ AS_IF([test "$AS_TR_SH([with_]m4_tolower([$1]))" = "yes"], # AM_CONDITIONAL -*- Autoconf -*- -# Copyright (C) 1997-2020 Free Software Foundation, Inc. +# Copyright (C) 1997-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -652,7 +652,7 @@ AC_CONFIG_COMMANDS_PRE( Usually this means the macro was only invoked conditionally.]]) fi])]) -# Copyright (C) 2006-2020 Free Software Foundation, Inc. +# Copyright (C) 2006-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff --git a/configure b/configure index 9e762877..b6f90bcd 100755 --- a/configure +++ b/configure @@ -1,11 +1,12 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for python 3.11. +# Generated by GNU Autoconf 2.71 for python 3.12. # # Report bugs to . # # -# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. +# Copyright (C) 1992-1996, 1998-2017, 2020-2021 Free Software Foundation, +# Inc. # # # This configure script is free software; the Free Software Foundation @@ -16,14 +17,16 @@ # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : +as_nop=: +if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 +then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST -else +else $as_nop case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( @@ -33,46 +36,46 @@ esac fi + +# Reset variables that may have inherited troublesome values from +# the environment. + +# IFS needs to be set, to space, tab, and newline, in precisely that order. +# (If _AS_PATH_WALK were called with IFS unset, it would have the +# side effect of setting IFS to empty, thus disabling word splitting.) +# Quoting is to prevent editors from complaining about space-tab. as_nl=' ' export as_nl -# Printing a long string crashes Solaris 7 /usr/bin/printf. -as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo -# Prefer a ksh shell builtin over an external printf program on Solaris, -# but without wasting forks for bash or zsh. -if test -z "$BASH_VERSION$ZSH_VERSION" \ - && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='print -r --' - as_echo_n='print -rn --' -elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='printf %s\n' - as_echo_n='printf %s' -else - if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then - as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' - as_echo_n='/usr/ucb/echo -n' - else - as_echo_body='eval expr "X$1" : "X\\(.*\\)"' - as_echo_n_body='eval - arg=$1; - case $arg in #( - *"$as_nl"*) - expr "X$arg" : "X\\(.*\\)$as_nl"; - arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; - esac; - expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" - ' - export as_echo_n_body - as_echo_n='sh -c $as_echo_n_body as_echo' - fi - export as_echo_body - as_echo='sh -c $as_echo_body as_echo' -fi +IFS=" "" $as_nl" + +PS1='$ ' +PS2='> ' +PS4='+ ' + +# Ensure predictable behavior from utilities with locale-dependent output. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# We cannot yet rely on "unset" to work, but we need these variables +# to be unset--not just set to an empty or harmless value--now, to +# avoid bugs in old shells (e.g. pre-3.0 UWIN ksh). This construct +# also avoids known problems related to "unset" and subshell syntax +# in other old shells (e.g. bash 2.01 and pdksh 5.2.14). +for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH +do eval test \${$as_var+y} \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done + +# Ensure that fds 0, 1, and 2 are open. +if (exec 3>&0) 2>/dev/null; then :; else exec 0&1) 2>/dev/null; then :; else exec 1>/dev/null; fi +if (exec 3>&2) ; then :; else exec 2>/dev/null; fi # The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then +if ${PATH_SEPARATOR+false} :; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || @@ -81,13 +84,6 @@ if test "${PATH_SEPARATOR+set}" != set; then fi -# IFS -# We need space, tab and new line, in precisely that order. Quoting is -# there to prevent editors from complaining about space-tab. -# (If _AS_PATH_WALK were called with IFS unset, it would disable word -# splitting by setting IFS to empty value.) -IFS=" "" $as_nl" - # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( @@ -96,8 +92,12 @@ case $0 in #(( for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + test -r "$as_dir$0" && as_myself=$as_dir$0 && break done IFS=$as_save_IFS @@ -109,30 +109,10 @@ if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then - $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi -# Unset variables that we do not need and which cause bugs (e.g. in -# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" -# suppresses any "Segmentation fault" message there. '((' could -# trigger a bug in pdksh 5.2.14. -for as_var in BASH_ENV ENV MAIL MAILPATH -do eval test x\${$as_var+set} = xset \ - && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : -done -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -LC_ALL=C -export LC_ALL -LANGUAGE=C -export LANGUAGE - -# CDPATH. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH # Use a proper internal environment variable to ensure we don't fall # into an infinite loop, continuously re-executing ourselves. @@ -154,20 +134,22 @@ esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. -$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 -as_fn_exit 255 +printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2 +exit 255 fi # We don't want this to propagate to other subprocesses. { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then - as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + as_bourne_compatible="as_nop=: +if test \${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 +then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST -else +else \$as_nop case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( @@ -187,42 +169,53 @@ as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } -if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : +if ( set x; as_fn_ret_success y && test x = \"\$1\" ) +then : -else +else \$as_nop exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1 +blah=\$(echo \$(echo blah)) +test x\"\$blah\" = xblah || exit 1 test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test \$(( 1 + 1 )) = 2 || exit 1" - if (eval "$as_required") 2>/dev/null; then : + if (eval "$as_required") 2>/dev/null +then : as_have_required=yes -else +else $as_nop as_have_required=no fi - if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null +then : -else +else $as_nop as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. - as_shell=$as_dir/$as_base + as_shell=$as_dir$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && - { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + as_run=a "$as_shell" -c "$as_bourne_compatible""$as_required" 2>/dev/null +then : CONFIG_SHELL=$as_shell as_have_required=yes - if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + if as_run=a "$as_shell" -c "$as_bourne_compatible""$as_suggested" 2>/dev/null +then : break 2 fi fi @@ -230,14 +223,21 @@ fi esac as_found=false done -$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && - { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : - CONFIG_SHELL=$SHELL as_have_required=yes -fi; } IFS=$as_save_IFS +if $as_found +then : + +else $as_nop + if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + as_run=a "$SHELL" -c "$as_bourne_compatible""$as_required" 2>/dev/null +then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi +fi - if test "x$CONFIG_SHELL" != x; then : + if test "x$CONFIG_SHELL" != x +then : export CONFIG_SHELL # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also @@ -255,18 +255,19 @@ esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. -$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi - if test x$as_have_required = xno; then : - $as_echo "$0: This script requires a shell more modern than all" - $as_echo "$0: the shells that I found on your system." - if test x${ZSH_VERSION+set} = xset ; then - $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" - $as_echo "$0: be upgraded to zsh 4.3.4 or later." + if test x$as_have_required = xno +then : + printf "%s\n" "$0: This script requires a shell more modern than all" + printf "%s\n" "$0: the shells that I found on your system." + if test ${ZSH_VERSION+y} ; then + printf "%s\n" "$0: In particular, zsh $ZSH_VERSION has bugs and should" + printf "%s\n" "$0: be upgraded to zsh 4.3.4 or later." else - $as_echo "$0: Please tell bug-autoconf@gnu.org and + printf "%s\n" "$0: Please tell bug-autoconf@gnu.org and $0: https://github.com/python/cpython/issues/ about your $0: system, including any error possibly output before this $0: message. Then install a modern shell, or manually run @@ -294,6 +295,7 @@ as_fn_unset () } as_unset=as_fn_unset + # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. @@ -311,6 +313,14 @@ as_fn_exit () as_fn_set_status $1 exit $1 } # as_fn_exit +# as_fn_nop +# --------- +# Do nothing but, unlike ":", preserve the value of $?. +as_fn_nop () +{ + return $? +} +as_nop=as_fn_nop # as_fn_mkdir_p # ------------- @@ -325,7 +335,7 @@ as_fn_mkdir_p () as_dirs= while :; do case $as_dir in #( - *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" @@ -334,7 +344,7 @@ $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_dir" | +printf "%s\n" X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q @@ -373,12 +383,13 @@ as_fn_executable_p () # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. -if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null +then : eval 'as_fn_append () { eval $1+=\$2 }' -else +else $as_nop as_fn_append () { eval $1=\$$1\$2 @@ -390,18 +401,27 @@ fi # as_fn_append # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. -if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null +then : eval 'as_fn_arith () { as_val=$(( $* )) }' -else +else $as_nop as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith +# as_fn_nop +# --------- +# Do nothing but, unlike ":", preserve the value of $?. +as_fn_nop () +{ + return $? +} +as_nop=as_fn_nop # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- @@ -413,9 +433,9 @@ as_fn_error () as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi - $as_echo "$as_me: error: $2" >&2 + printf "%s\n" "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error @@ -442,7 +462,7 @@ as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$0" | +printf "%s\n" X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q @@ -486,7 +506,7 @@ as_cr_alnum=$as_cr_Letters$as_cr_digits s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || - { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + { printf "%s\n" "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # If we had to re-execute with $CONFIG_SHELL, we're ensured to have # already done that, so ensure we don't try to do so again and fall @@ -500,6 +520,10 @@ as_cr_alnum=$as_cr_Letters$as_cr_digits exit } + +# Determine whether it's possible to make 'echo' print without a newline. +# These variables are no longer used directly by Autoconf, but are AC_SUBSTed +# for compatibility with existing Makefiles. ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) @@ -513,6 +537,13 @@ case `echo -n x` in #((((( ECHO_N='-n';; esac +# For backward compatibility with old third-party macros, we provide +# the shell variables $as_echo and $as_echo_n. New code should use +# AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively. +as_echo='printf %s\n' +as_echo_n='printf %s' + + rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file @@ -580,48 +611,44 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='python' PACKAGE_TARNAME='python' -PACKAGE_VERSION='3.11' -PACKAGE_STRING='python 3.11' +PACKAGE_VERSION='3.12' +PACKAGE_STRING='python 3.12' PACKAGE_BUGREPORT='https://github.com/python/cpython/issues/' PACKAGE_URL='' ac_unique_file="Include/object.h" # Factoring default headers for most tests. ac_includes_default="\ -#include -#ifdef HAVE_SYS_TYPES_H -# include -#endif -#ifdef HAVE_SYS_STAT_H -# include +#include +#ifdef HAVE_STDIO_H +# include #endif -#ifdef STDC_HEADERS +#ifdef HAVE_STDLIB_H # include -# include -#else -# ifdef HAVE_STDLIB_H -# include -# endif #endif #ifdef HAVE_STRING_H -# if !defined STDC_HEADERS && defined HAVE_MEMORY_H -# include -# endif # include #endif -#ifdef HAVE_STRINGS_H -# include -#endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif #ifdef HAVE_UNISTD_H # include #endif" +ac_header_c_list= ac_subst_vars='LTLIBOBJS MODULE_BLOCK MODULE_XXLIMITED_35_FALSE @@ -632,6 +659,8 @@ MODULE__CTYPES_TEST_FALSE MODULE__CTYPES_TEST_TRUE MODULE__XXTESTFUZZ_FALSE MODULE__XXTESTFUZZ_TRUE +MODULE_XXSUBTYPE_FALSE +MODULE_XXSUBTYPE_TRUE MODULE__TESTMULTIPHASE_FALSE MODULE__TESTMULTIPHASE_TRUE MODULE__TESTIMPORTMULTIPLE_FALSE @@ -662,22 +691,30 @@ MODULE__TKINTER_FALSE MODULE__TKINTER_TRUE MODULE__SQLITE3_FALSE MODULE__SQLITE3_TRUE +MODULE_READLINE_FALSE +MODULE_READLINE_TRUE MODULE_NIS_FALSE MODULE_NIS_TRUE MODULE__GDBM_FALSE MODULE__GDBM_TRUE +MODULE__DBM_FALSE +MODULE__DBM_TRUE MODULE__DECIMAL_FALSE MODULE__DECIMAL_TRUE +MODULE__CURSES_PANEL_FALSE +MODULE__CURSES_PANEL_TRUE +MODULE__CURSES_FALSE +MODULE__CURSES_TRUE +MODULE__CTYPES_FALSE +MODULE__CTYPES_TRUE MODULE__CRYPT_FALSE MODULE__CRYPT_TRUE MODULE__BLAKE2_FALSE MODULE__BLAKE2_TRUE MODULE__SHA3_FALSE MODULE__SHA3_TRUE -MODULE__SHA512_FALSE -MODULE__SHA512_TRUE -MODULE__SHA256_FALSE -MODULE__SHA256_TRUE +MODULE__SHA2_FALSE +MODULE__SHA2_TRUE MODULE__SHA1_FALSE MODULE__SHA1_TRUE MODULE__MD5_FALSE @@ -740,6 +777,8 @@ MODULE__MULTIPROCESSING_FALSE MODULE__MULTIPROCESSING_TRUE MODULE__ZONEINFO_FALSE MODULE__ZONEINFO_TRUE +MODULE__XXINTERPCHANNELS_FALSE +MODULE__XXINTERPCHANNELS_TRUE MODULE__XXSUBINTERPRETERS_FALSE MODULE__XXSUBINTERPRETERS_TRUE MODULE__TYPING_FALSE @@ -778,18 +817,24 @@ MODULE_TIME_FALSE MODULE_TIME_TRUE MODULE__IO_FALSE MODULE__IO_TRUE -MODULES_SETUP_STDLIB MODULE_BUILDTYPE TEST_MODULES LIBB2_LIBS LIBB2_CFLAGS -OPENSSL_RPATH OPENSSL_LDFLAGS OPENSSL_LIBS OPENSSL_INCLUDES ENSUREPIP SRCDIRS THREADHEADERS +PANEL_LIBS +PANEL_CFLAGS +CURSES_LIBS +CURSES_CFLAGS +LIBEDIT_LIBS +LIBEDIT_CFLAGS +LIBREADLINE_LIBS +LIBREADLINE_CFLAGS WHEEL_PKG_DIR LIBPL PY_ENABLE_SHARED @@ -836,15 +881,16 @@ LIBSQLITE3_CFLAGS LIBNSL_LIBS LIBNSL_CFLAGS LIBMPDEC_INTERNAL -LIBMPDEC_LDFLAGS LIBMPDEC_CFLAGS -LIBFFI_INCLUDEDIR +MODULE__CTYPES_MALLOC_CLOSURE +LIBFFI_LIBS +LIBFFI_CFLAGS LIBEXPAT_INTERNAL -LIBEXPAT_LDFLAGS LIBEXPAT_CFLAGS TZPATH LIBUUID_LIBS LIBUUID_CFLAGS +PERF_TRAMPOLINE_OBJ SHLIBS CFLAGSFORSHARED LINKFORSHARED @@ -853,8 +899,8 @@ BLDSHARED LDCXXSHARED LDSHARED SHLIB_SUFFIX -LIBTOOL_CRUFT -OTHER_LIBTOOL_OPT +DSYMUTIL_PATH +DSYMUTIL UNIVERSAL_ARCH_FLAGS WASM_STDLIB WASM_ASSETS_DIR @@ -864,6 +910,12 @@ CFLAGS_NODIST BASECFLAGS CFLAGS_ALIASING OPT +BOLT_APPLY_FLAGS +BOLT_INSTRUMENT_FLAGS +BOLT_BINARIES +MERGE_FDATA +LLVM_BOLT +PREBOLT_RULE LLVM_PROF_FOUND LLVM_PROFDATA LLVM_PROF_ERR @@ -882,8 +934,6 @@ MKDIR_P INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM -ac_ct_READELF -READELF ARFLAGS ac_ct_AR AR @@ -912,7 +962,6 @@ MULTIARCH_CPPFLAGS PLATFORM_TRIPLET MULTIARCH ac_ct_CXX -MAINCC CXX EGREP SED @@ -925,6 +974,7 @@ CPPFLAGS LDFLAGS CFLAGS CC +HAS_XCRUN EXPORT_MACOSX_DEPLOYMENT_TARGET CONFIGURE_MACOSX_DEPLOYMENT_TARGET _PYTHON_HOST_PLATFORM @@ -1020,7 +1070,6 @@ enable_universalsdk with_universal_archs with_framework_name enable_framework -with_cxx_main with_emscripten_target enable_wasm_dynamic_linking enable_wasm_pthreads @@ -1034,6 +1083,9 @@ enable_pystats with_assertions enable_optimizations with_lto +enable_bolt +with_strict_overflow +with_dsymutil with_address_sanitizer with_memory_sanitizer with_undefined_behavior_sanitizer @@ -1041,7 +1093,6 @@ with_hash_algorithm with_tzpath with_libs with_system_expat -with_system_ffi with_system_libmpdec with_decimal_contextvar enable_loadable_sqlite_extensions @@ -1082,8 +1133,12 @@ CPPFLAGS CPP HOSTRUNNER PROFILE_TASK +BOLT_INSTRUMENT_FLAGS +BOLT_APPLY_FLAGS LIBUUID_CFLAGS LIBUUID_LIBS +LIBFFI_CFLAGS +LIBFFI_LIBS LIBNSL_CFLAGS LIBNSL_LIBS LIBSQLITE3_CFLAGS @@ -1102,6 +1157,14 @@ LIBLZMA_CFLAGS LIBLZMA_LIBS LIBCRYPT_CFLAGS LIBCRYPT_LIBS +LIBREADLINE_CFLAGS +LIBREADLINE_LIBS +LIBEDIT_CFLAGS +LIBEDIT_LIBS +CURSES_CFLAGS +CURSES_LIBS +PANEL_CFLAGS +PANEL_LIBS LIBB2_CFLAGS LIBB2_LIBS' @@ -1172,8 +1235,6 @@ do *) ac_optarg=yes ;; esac - # Accept the important Cygnus configure options, so we can diagnose typos. - case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; @@ -1214,9 +1275,9 @@ do ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid feature name: $ac_useropt" + as_fn_error $? "invalid feature name: \`$ac_useropt'" ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" @@ -1240,9 +1301,9 @@ do ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid feature name: $ac_useropt" + as_fn_error $? "invalid feature name: \`$ac_useropt'" ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" @@ -1453,9 +1514,9 @@ do ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid package name: $ac_useropt" + as_fn_error $? "invalid package name: \`$ac_useropt'" ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" @@ -1469,9 +1530,9 @@ do ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid package name: $ac_useropt" + as_fn_error $? "invalid package name: \`$ac_useropt'" ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" @@ -1515,9 +1576,9 @@ Try \`$0 --help' for more information" *) # FIXME: should be removed in autoconf 3.0. - $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + printf "%s\n" "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && - $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + printf "%s\n" "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; @@ -1533,7 +1594,7 @@ if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; - *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + *) printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi @@ -1597,7 +1658,7 @@ $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_myself" | +printf "%s\n" X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q @@ -1654,7 +1715,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures python 3.11 to adapt to many kinds of systems. +\`configure' configures python 3.12 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1720,7 +1781,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of python 3.11:";; + short | recursive ) echo "Configuration of python 3.12:";; esac cat <<\_ACEOF @@ -1749,6 +1810,8 @@ Optional Features: --enable-pystats enable internal statistics gathering (default is no) --enable-optimizations enable expensive, stable optimizations (PGO, etc.) (default is no) + --enable-bolt enable usage of the llvm-bolt post-link optimizer + (default is no) --enable-loadable-sqlite-extensions support loadable extensions in the sqlite3 module, see Doc/library/sqlite3.rst (default is no) @@ -1762,9 +1825,9 @@ Optional Features: Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) - --with-build-python=python3.11 + --with-build-python=python3.12 path to build python binary for cross compiling - (default: _bootstrap_python or python3.11) + (default: _bootstrap_python or python3.12) --with-pkg-config=[yes|no|check] use pkg-config to detect build options (default is check) @@ -1779,9 +1842,6 @@ Optional Packages: specify the name for the python framework on macOS only valid when --enable-framework is set. see Mac/README.rst (default is 'Python') - --with-cxx-main[=COMPILER] - compile main() and link Python executable with C++ - compiler specified in COMPILER (default is $CXX) --with-emscripten-target=[browser|node] Emscripten platform --with-suffix=SUFFIX set executable suffix to SUFFIX (default is empty, @@ -1796,6 +1856,10 @@ Optional Packages: --with-lto=[full|thin|no|yes] enable Link-Time-Optimization in any build (default is no) + --with-strict-overflow if 'yes', add -fstrict-overflow to CFLAGS, else add + -fno-strict-overflow (default is no) + --with-dsymutil link debug information into final executable with + dsymutil in macOS (default is no) --with-address-sanitizer enable AddressSanitizer memory error detector, 'asan' (default is no) @@ -1808,14 +1872,11 @@ Optional Packages: select hash algorithm for use in Python/pyhash.c (default is SipHash13) --with-tzpath= - Select the default time zone search path for zoneinfo.TZPATH - + Select the default time zone search path for + zoneinfo.TZPATH --with-libs='lib1 ...' link against additional libs (default is no) --with-system-expat build pyexpat module using an installed expat library, see Doc/library/pyexpat.rst (default is no) - --with-system-ffi build _ctypes module using an installed ffi library, - see Doc/library/ctypes.rst (default is - system-dependent) --with-system-libmpdec build _decimal module using an installed libmpdec library, see Doc/library/decimal.rst (default is no) --with-decimal-contextvar @@ -1842,8 +1903,8 @@ Optional Packages: --with-wheel-pkg-dir=PATH Directory of wheel packages used by ensurepip (default: none) - --with(out)-readline[=editline] - use Editline for backend or disable readline module + --with(out)-readline[=editline|readline|no] + use libedit for backend or disable readline module --with-computed-gotos enable computed gotos in evaluation loop (enabled by default on supported compilers) --with-ensurepip[=install|upgrade|no] @@ -1861,9 +1922,9 @@ Optional Packages: leave OpenSSL's defaults untouched, STRING: use a custom string, python and STRING also set TLS 1.2 as minimum TLS version - --with-builtin-hashlib-hashes=md5,sha1,sha256,sha512,sha3,blake2 - builtin hash modules, md5, sha1, sha256, sha512, - sha3 (with shake), blake2 + --with-builtin-hashlib-hashes=md5,sha1,sha2,sha3,blake2 + builtin hash modules, md5, sha1, sha2, sha3 (with + shake), blake2 Some influential environment variables: PKG_CONFIG path to pkg-config utility @@ -1883,10 +1944,17 @@ Some influential environment variables: HOSTRUNNER Program to run CPython for the host platform PROFILE_TASK Python args for PGO generation task + BOLT_INSTRUMENT_FLAGS + Arguments to llvm-bolt when instrumenting binaries + BOLT_APPLY_FLAGS + Arguments to llvm-bolt when creating a BOLT optimized binary LIBUUID_CFLAGS C compiler flags for LIBUUID, overriding pkg-config LIBUUID_LIBS linker flags for LIBUUID, overriding pkg-config + LIBFFI_CFLAGS + C compiler flags for LIBFFI, overriding pkg-config + LIBFFI_LIBS linker flags for LIBFFI, overriding pkg-config LIBNSL_CFLAGS C compiler flags for LIBNSL, overriding pkg-config LIBNSL_LIBS linker flags for LIBNSL, overriding pkg-config @@ -1914,6 +1982,20 @@ Some influential environment variables: C compiler flags for LIBCRYPT, overriding pkg-config LIBCRYPT_LIBS linker flags for LIBCRYPT, overriding pkg-config + LIBREADLINE_CFLAGS + C compiler flags for LIBREADLINE, overriding pkg-config + LIBREADLINE_LIBS + linker flags for LIBREADLINE, overriding pkg-config + LIBEDIT_CFLAGS + C compiler flags for LIBEDIT, overriding pkg-config + LIBEDIT_LIBS + linker flags for LIBEDIT, overriding pkg-config + CURSES_CFLAGS + C compiler flags for CURSES, overriding pkg-config + CURSES_LIBS linker flags for CURSES, overriding pkg-config + PANEL_CFLAGS + C compiler flags for PANEL, overriding pkg-config + PANEL_LIBS linker flags for PANEL, overriding pkg-config LIBB2_CFLAGS C compiler flags for LIBB2, overriding pkg-config LIBB2_LIBS linker flags for LIBB2, overriding pkg-config @@ -1937,9 +2019,9 @@ if test "$ac_init_help" = "recursive"; then case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) - ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. - ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; @@ -1967,7 +2049,8 @@ esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } - # Check for guested configure. + # Check for configure.gnu first; this name is used for a wrapper for + # Metaconfig's "Configure" on case-insensitive file systems. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive @@ -1975,7 +2058,7 @@ ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix echo && $SHELL "$ac_srcdir/configure" --help=recursive else - $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + printf "%s\n" "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done @@ -1984,10 +2067,10 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -python configure 3.11 -generated by GNU Autoconf 2.69 +python configure 3.12 +generated by GNU Autoconf 2.71 -Copyright (C) 2012 Free Software Foundation, Inc. +Copyright (C) 2021 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF @@ -2004,14 +2087,14 @@ fi ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -f conftest.$ac_objext + rm -f conftest.$ac_objext conftest.beam if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 +printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then @@ -2019,14 +2102,15 @@ $as_echo "$ac_try_echo"; } >&5 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err - } && test -s conftest.$ac_objext; then : + } && test -s conftest.$ac_objext +then : ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 +else $as_nop + printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 @@ -2048,7 +2132,7 @@ case "(($ac_try" in *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 +printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then @@ -2056,14 +2140,15 @@ $as_echo "$ac_try_echo"; } >&5 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err - }; then : + } +then : ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 +else $as_nop + printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 @@ -2073,139 +2158,6 @@ fi } # ac_fn_c_try_cpp -# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES -# ------------------------------------------------------- -# Tests whether HEADER exists, giving a warning if it cannot be compiled using -# the include files in INCLUDES and setting the cache variable VAR -# accordingly. -ac_fn_c_check_header_mongrel () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if eval \${$3+:} false; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -else - # Is the header compilable? -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 -$as_echo_n "checking $2 usability... " >&6; } -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -#include <$2> -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_header_compiler=yes -else - ac_header_compiler=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 -$as_echo "$ac_header_compiler" >&6; } - -# Is the header present? -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 -$as_echo_n "checking $2 presence... " >&6; } -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <$2> -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - ac_header_preproc=yes -else - ac_header_preproc=no -fi -rm -f conftest.err conftest.i conftest.$ac_ext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 -$as_echo "$ac_header_preproc" >&6; } - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( - yes:no: ) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 -$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 -$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} - ;; - no:yes:* ) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 -$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 -$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 -$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 -$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 -$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} -( $as_echo "## -------------------------------------------------------- ## -## Report this to https://github.com/python/cpython/issues/ ## -## -------------------------------------------------------- ##" - ) | sed "s/^/$as_me: WARNING: /" >&2 - ;; -esac - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else - eval "$3=\$ac_header_compiler" -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_check_header_mongrel - -# ac_fn_c_try_run LINENO -# ---------------------- -# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes -# that executables *can* be run. -ac_fn_c_try_run () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' - { { case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; }; then : - ac_retval=0 -else - $as_echo "$as_me: program exited with status $ac_status" >&5 - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=$ac_status -fi - rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_run - # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in @@ -2213,26 +2165,28 @@ fi ac_fn_c_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +printf %s "checking for $2... " >&6; } +if eval test \${$3+y} +then : + printf %s "(cached) " >&6 +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : eval "$3=yes" -else +else $as_nop eval "$3=no" fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_compile @@ -2243,14 +2197,14 @@ $as_echo "$ac_res" >&6; } ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -f conftest.$ac_objext conftest$ac_exeext + rm -f conftest.$ac_objext conftest.beam conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 +printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then @@ -2258,17 +2212,18 @@ $as_echo "$ac_try_echo"; } >&5 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext - }; then : + } +then : ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 +else $as_nop + printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 @@ -2283,6 +2238,49 @@ fi } # ac_fn_c_try_link +# ac_fn_c_try_run LINENO +# ---------------------- +# Try to run conftest.$ac_ext, and return whether this succeeded. Assumes that +# executables *can* be run. +ac_fn_c_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; } +then : + ac_retval=0 +else $as_nop + printf "%s\n" "$as_me: program exited with status $ac_status" >&5 + printf "%s\n" "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_run + # ac_fn_c_check_type LINENO TYPE VAR INCLUDES # ------------------------------------------- # Tests whether TYPE exists after having included INCLUDES, setting cache @@ -2290,17 +2288,18 @@ fi ac_fn_c_check_type () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +printf %s "checking for $2... " >&6; } +if eval test \${$3+y} +then : + printf %s "(cached) " >&6 +else $as_nop eval "$3=no" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int -main () +main (void) { if (sizeof ($2)) return 0; @@ -2308,12 +2307,13 @@ if (sizeof ($2)) return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int -main () +main (void) { if (sizeof (($2))) return 0; @@ -2321,18 +2321,19 @@ if (sizeof (($2))) return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : -else +else $as_nop eval "$3=yes" fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_type @@ -2351,7 +2352,7 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int -main () +main (void) { static int test_array [1 - 2 * !(($2) >= 0)]; test_array [0] = 0; @@ -2361,14 +2362,15 @@ return test_array [0]; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : ac_lo=0 ac_mid=0 while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int -main () +main (void) { static int test_array [1 - 2 * !(($2) <= $ac_mid)]; test_array [0] = 0; @@ -2378,9 +2380,10 @@ return test_array [0]; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : ac_hi=$ac_mid; break -else +else $as_nop as_fn_arith $ac_mid + 1 && ac_lo=$as_val if test $ac_lo -le $ac_mid; then ac_lo= ac_hi= @@ -2388,14 +2391,14 @@ else fi as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext done -else +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int -main () +main (void) { static int test_array [1 - 2 * !(($2) < 0)]; test_array [0] = 0; @@ -2405,14 +2408,15 @@ return test_array [0]; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : ac_hi=-1 ac_mid=-1 while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int -main () +main (void) { static int test_array [1 - 2 * !(($2) >= $ac_mid)]; test_array [0] = 0; @@ -2422,9 +2426,10 @@ return test_array [0]; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : ac_lo=$ac_mid; break -else +else $as_nop as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val if test $ac_mid -le $ac_hi; then ac_lo= ac_hi= @@ -2432,14 +2437,14 @@ else fi as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext done -else +else $as_nop ac_lo= ac_hi= fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext # Binary search between lo and hi bounds. while test "x$ac_lo" != "x$ac_hi"; do as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val @@ -2447,7 +2452,7 @@ while test "x$ac_lo" != "x$ac_hi"; do /* end confdefs.h. */ $4 int -main () +main (void) { static int test_array [1 - 2 * !(($2) <= $ac_mid)]; test_array [0] = 0; @@ -2457,12 +2462,13 @@ return test_array [0]; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : ac_hi=$ac_mid -else +else $as_nop as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext done case $ac_lo in #(( ?*) eval "$3=\$ac_lo"; ac_retval=0 ;; @@ -2472,12 +2478,12 @@ esac cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 -static long int longval () { return $2; } -static unsigned long int ulongval () { return $2; } +static long int longval (void) { return $2; } +static unsigned long int ulongval (void) { return $2; } #include #include int -main () +main (void) { FILE *f = fopen ("conftest.val", "w"); @@ -2505,9 +2511,10 @@ main () return 0; } _ACEOF -if ac_fn_c_try_run "$LINENO"; then : +if ac_fn_c_try_run "$LINENO" +then : echo >>conftest.val; read $3 &5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +printf %s "checking for $2... " >&6; } +if eval test \${$3+y} +then : + printf %s "(cached) " >&6 +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. @@ -2538,16 +2546,9 @@ else #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $2 (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif + which can conflict with char $2 (); below. */ +#include #undef $2 /* Override any GCC internal prototype to avoid an error. @@ -2565,47 +2566,51 @@ choke me #endif int -main () +main (void) { return $2 (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : eval "$3=yes" -else +else $as_nop eval "$3=no" fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_func -# ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES -# --------------------------------------------- +# ac_fn_check_decl LINENO SYMBOL VAR INCLUDES EXTRA-OPTIONS FLAG-VAR +# ------------------------------------------------------------------ # Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR -# accordingly. -ac_fn_c_check_decl () +# accordingly. Pass EXTRA-OPTIONS to the compiler, using FLAG-VAR. +ac_fn_check_decl () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack as_decl_name=`echo $2|sed 's/ *(.*//'` + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5 +printf %s "checking whether $as_decl_name is declared... " >&6; } +if eval test \${$3+y} +then : + printf %s "(cached) " >&6 +else $as_nop as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'` - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5 -$as_echo_n "checking whether $as_decl_name is declared... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else + eval ac_save_FLAGS=\$$6 + as_fn_append $6 " $5" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int -main () +main (void) { #ifndef $as_decl_name #ifdef __cplusplus @@ -2619,19 +2624,22 @@ main () return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : eval "$3=yes" -else +else $as_nop eval "$3=no" fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + eval $6=\$ac_save_FLAGS + fi eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno -} # ac_fn_c_check_decl +} # ac_fn_check_decl # ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES # ---------------------------------------------------- @@ -2640,16 +2648,17 @@ $as_echo "$ac_res" >&6; } ac_fn_c_check_member () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5 -$as_echo_n "checking for $2.$3... " >&6; } -if eval \${$4+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5 +printf %s "checking for $2.$3... " >&6; } +if eval test \${$4+y} +then : + printf %s "(cached) " >&6 +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $5 int -main () +main (void) { static $2 ac_aggr; if (ac_aggr.$3) @@ -2658,14 +2667,15 @@ return 0; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : eval "$4=yes" -else +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $5 int -main () +main (void) { static $2 ac_aggr; if (sizeof ac_aggr.$3) @@ -2674,29 +2684,50 @@ return 0; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : eval "$4=yes" -else +else $as_nop eval "$4=no" fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi eval ac_res=\$$4 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_member +ac_configure_args_raw= +for ac_arg +do + case $ac_arg in + *\'*) + ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append ac_configure_args_raw " '$ac_arg'" +done + +case $ac_configure_args_raw in + *$as_nl*) + ac_safe_unquote= ;; + *) + ac_unsafe_z='|&;<>()$`\\"*?[ '' ' # This string ends in space, tab. + ac_unsafe_a="$ac_unsafe_z#~" + ac_safe_unquote="s/ '\\([^$ac_unsafe_a][^$ac_unsafe_z]*\\)'/ \\1/g" + ac_configure_args_raw=` printf "%s\n" "$ac_configure_args_raw" | sed "$ac_safe_unquote"`;; +esac + cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by python $as_me 3.11, which was -generated by GNU Autoconf 2.69. Invocation command line was +It was created by python $as_me 3.12, which was +generated by GNU Autoconf 2.71. Invocation command line was - $ $0 $@ + $ $0$ac_configure_args_raw _ACEOF exec 5>>config.log @@ -2729,8 +2760,12 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - $as_echo "PATH: $as_dir" + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + printf "%s\n" "PATH: $as_dir" done IFS=$as_save_IFS @@ -2765,7 +2800,7 @@ do | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) - ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; @@ -2800,11 +2835,13 @@ done # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? + # Sanitize IFS. + IFS=" "" $as_nl" # Save into config.log some information that might help in debugging. { echo - $as_echo "## ---------------- ## + printf "%s\n" "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo @@ -2815,8 +2852,8 @@ trap 'exit_status=$? case $ac_val in #( *${as_nl}*) case $ac_var in #( - *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 -$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( @@ -2840,7 +2877,7 @@ $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; ) echo - $as_echo "## ----------------- ## + printf "%s\n" "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo @@ -2848,14 +2885,14 @@ $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; do eval ac_val=\$$ac_var case $ac_val in - *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac - $as_echo "$ac_var='\''$ac_val'\''" + printf "%s\n" "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then - $as_echo "## ------------------- ## + printf "%s\n" "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo @@ -2863,15 +2900,15 @@ $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; do eval ac_val=\$$ac_var case $ac_val in - *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac - $as_echo "$ac_var='\''$ac_val'\''" + printf "%s\n" "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then - $as_echo "## ----------- ## + printf "%s\n" "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo @@ -2879,8 +2916,8 @@ $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; echo fi test "$ac_signal" != 0 && - $as_echo "$as_me: caught signal $ac_signal" - $as_echo "$as_me: exit $exit_status" + printf "%s\n" "$as_me: caught signal $ac_signal" + printf "%s\n" "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && @@ -2894,63 +2931,48 @@ ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h -$as_echo "/* confdefs.h */" > confdefs.h +printf "%s\n" "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. -cat >>confdefs.h <<_ACEOF -#define PACKAGE_NAME "$PACKAGE_NAME" -_ACEOF +printf "%s\n" "#define PACKAGE_NAME \"$PACKAGE_NAME\"" >>confdefs.h -cat >>confdefs.h <<_ACEOF -#define PACKAGE_TARNAME "$PACKAGE_TARNAME" -_ACEOF +printf "%s\n" "#define PACKAGE_TARNAME \"$PACKAGE_TARNAME\"" >>confdefs.h -cat >>confdefs.h <<_ACEOF -#define PACKAGE_VERSION "$PACKAGE_VERSION" -_ACEOF +printf "%s\n" "#define PACKAGE_VERSION \"$PACKAGE_VERSION\"" >>confdefs.h -cat >>confdefs.h <<_ACEOF -#define PACKAGE_STRING "$PACKAGE_STRING" -_ACEOF +printf "%s\n" "#define PACKAGE_STRING \"$PACKAGE_STRING\"" >>confdefs.h -cat >>confdefs.h <<_ACEOF -#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" -_ACEOF +printf "%s\n" "#define PACKAGE_BUGREPORT \"$PACKAGE_BUGREPORT\"" >>confdefs.h -cat >>confdefs.h <<_ACEOF -#define PACKAGE_URL "$PACKAGE_URL" -_ACEOF +printf "%s\n" "#define PACKAGE_URL \"$PACKAGE_URL\"" >>confdefs.h # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. -ac_site_file1=NONE -ac_site_file2=NONE if test -n "$CONFIG_SITE"; then - # We do not want a PATH search for config.site. - case $CONFIG_SITE in #(( - -*) ac_site_file1=./$CONFIG_SITE;; - */*) ac_site_file1=$CONFIG_SITE;; - *) ac_site_file1=./$CONFIG_SITE;; - esac + ac_site_files="$CONFIG_SITE" elif test "x$prefix" != xNONE; then - ac_site_file1=$prefix/share/config.site - ac_site_file2=$prefix/etc/config.site + ac_site_files="$prefix/share/config.site $prefix/etc/config.site" else - ac_site_file1=$ac_default_prefix/share/config.site - ac_site_file2=$ac_default_prefix/etc/config.site + ac_site_files="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" fi -for ac_site_file in "$ac_site_file1" "$ac_site_file2" + +for ac_site_file in $ac_site_files do - test "x$ac_site_file" = xNONE && continue - if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 -$as_echo "$as_me: loading site script $ac_site_file" >&6;} + case $ac_site_file in #( + */*) : + ;; #( + *) : + ac_site_file=./$ac_site_file ;; +esac + if test -f "$ac_site_file" && test -r "$ac_site_file"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +printf "%s\n" "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ - || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + || { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi @@ -2960,75 +2982,493 @@ if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 -$as_echo "$as_me: loading cache $cache_file" >&6;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +printf "%s\n" "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else - { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 -$as_echo "$as_me: creating cache $cache_file" >&6;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +printf "%s\n" "$as_me: creating cache $cache_file" >&6;} >$cache_file fi -# Check that the precious variables saved in the cache have kept the same -# value. -ac_cache_corrupted=false -for ac_var in $ac_precious_vars; do - eval ac_old_set=\$ac_cv_env_${ac_var}_set - eval ac_new_set=\$ac_env_${ac_var}_set - eval ac_old_val=\$ac_cv_env_${ac_var}_value - eval ac_new_val=\$ac_env_${ac_var}_value - case $ac_old_set,$ac_new_set in - set,) - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 -$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} - ac_cache_corrupted=: ;; - ,set) - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 -$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} - ac_cache_corrupted=: ;; - ,);; - *) - if test "x$ac_old_val" != "x$ac_new_val"; then - # differences in whitespace do not lead to failure. - ac_old_val_w=`echo x $ac_old_val` - ac_new_val_w=`echo x $ac_new_val` - if test "$ac_old_val_w" != "$ac_new_val_w"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 -$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} - ac_cache_corrupted=: - else - { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 -$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} - eval $ac_var=\$ac_old_val - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 -$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 -$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} - fi;; - esac - # Pass precious variables to config.status. - if test "$ac_new_set" = set; then - case $ac_new_val in - *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; - *) ac_arg=$ac_var=$ac_new_val ;; - esac - case " $ac_configure_args " in - *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. - *) as_fn_append ac_configure_args " '$ac_arg'" ;; +# Test code for whether the C compiler supports C89 (global declarations) +ac_c_conftest_c89_globals=' +/* Does the compiler advertise C89 conformance? + Do not test the value of __STDC__, because some compilers set it to 0 + while being otherwise adequately conformant. */ +#if !defined __STDC__ +# error "Compiler does not advertise C89 conformance" +#endif + +#include +#include +struct stat; +/* Most of the following tests are stolen from RCS 5.7 src/conf.sh. */ +struct buf { int x; }; +struct buf * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not \xHH hex character constants. + These do not provoke an error unfortunately, instead are silently treated + as an "x". The following induces an error, until -std is added to get + proper ANSI mode. Curiously \x00 != x always comes out true, for an + array size at least. It is necessary to write \x00 == 0 to get something + that is true only with -std. */ +int osf4_cc_array ['\''\x00'\'' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) '\''x'\'' +int xlc6_cc_array[FOO(a) == '\''x'\'' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, int *(*)(struct buf *, struct stat *, int), + int, int);' + +# Test code for whether the C compiler supports C89 (body of main). +ac_c_conftest_c89_main=' +ok |= (argc == 0 || f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]); +' + +# Test code for whether the C compiler supports C99 (global declarations) +ac_c_conftest_c99_globals=' +// Does the compiler advertise C99 conformance? +#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L +# error "Compiler does not advertise C99 conformance" +#endif + +#include +extern int puts (const char *); +extern int printf (const char *, ...); +extern int dprintf (int, const char *, ...); +extern void *malloc (size_t); + +// Check varargs macros. These examples are taken from C99 6.10.3.5. +// dprintf is used instead of fprintf to avoid needing to declare +// FILE and stderr. +#define debug(...) dprintf (2, __VA_ARGS__) +#define showlist(...) puts (#__VA_ARGS__) +#define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__)) +static void +test_varargs_macros (void) +{ + int x = 1234; + int y = 5678; + debug ("Flag"); + debug ("X = %d\n", x); + showlist (The first, second, and third items.); + report (x>y, "x is %d but y is %d", x, y); +} + +// Check long long types. +#define BIG64 18446744073709551615ull +#define BIG32 4294967295ul +#define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0) +#if !BIG_OK + #error "your preprocessor is broken" +#endif +#if BIG_OK +#else + #error "your preprocessor is broken" +#endif +static long long int bignum = -9223372036854775807LL; +static unsigned long long int ubignum = BIG64; + +struct incomplete_array +{ + int datasize; + double data[]; +}; + +struct named_init { + int number; + const wchar_t *name; + double average; +}; + +typedef const char *ccp; + +static inline int +test_restrict (ccp restrict text) +{ + // See if C++-style comments work. + // Iterate through items via the restricted pointer. + // Also check for declarations in for loops. + for (unsigned int i = 0; *(text+i) != '\''\0'\''; ++i) + continue; + return 0; +} + +// Check varargs and va_copy. +static bool +test_varargs (const char *format, ...) +{ + va_list args; + va_start (args, format); + va_list args_copy; + va_copy (args_copy, args); + + const char *str = ""; + int number = 0; + float fnumber = 0; + + while (*format) + { + switch (*format++) + { + case '\''s'\'': // string + str = va_arg (args_copy, const char *); + break; + case '\''d'\'': // int + number = va_arg (args_copy, int); + break; + case '\''f'\'': // float + fnumber = va_arg (args_copy, double); + break; + default: + break; + } + } + va_end (args_copy); + va_end (args); + + return *str && number && fnumber; +} +' + +# Test code for whether the C compiler supports C99 (body of main). +ac_c_conftest_c99_main=' + // Check bool. + _Bool success = false; + success |= (argc != 0); + + // Check restrict. + if (test_restrict ("String literal") == 0) + success = true; + char *restrict newvar = "Another string"; + + // Check varargs. + success &= test_varargs ("s, d'\'' f .", "string", 65, 34.234); + test_varargs_macros (); + + // Check flexible array members. + struct incomplete_array *ia = + malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10)); + ia->datasize = 10; + for (int i = 0; i < ia->datasize; ++i) + ia->data[i] = i * 1.234; + + // Check named initializers. + struct named_init ni = { + .number = 34, + .name = L"Test wide string", + .average = 543.34343, + }; + + ni.number = 58; + + int dynamic_array[ni.number]; + dynamic_array[0] = argv[0][0]; + dynamic_array[ni.number - 1] = 543; + + // work around unused variable warnings + ok |= (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == '\''x'\'' + || dynamic_array[ni.number - 1] != 543); +' + +# Test code for whether the C compiler supports C11 (global declarations) +ac_c_conftest_c11_globals=' +// Does the compiler advertise C11 conformance? +#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112L +# error "Compiler does not advertise C11 conformance" +#endif + +// Check _Alignas. +char _Alignas (double) aligned_as_double; +char _Alignas (0) no_special_alignment; +extern char aligned_as_int; +char _Alignas (0) _Alignas (int) aligned_as_int; + +// Check _Alignof. +enum +{ + int_alignment = _Alignof (int), + int_array_alignment = _Alignof (int[100]), + char_alignment = _Alignof (char) +}; +_Static_assert (0 < -_Alignof (int), "_Alignof is signed"); + +// Check _Noreturn. +int _Noreturn does_not_return (void) { for (;;) continue; } + +// Check _Static_assert. +struct test_static_assert +{ + int x; + _Static_assert (sizeof (int) <= sizeof (long int), + "_Static_assert does not work in struct"); + long int y; +}; + +// Check UTF-8 literals. +#define u8 syntax error! +char const utf8_literal[] = u8"happens to be ASCII" "another string"; + +// Check duplicate typedefs. +typedef long *long_ptr; +typedef long int *long_ptr; +typedef long_ptr long_ptr; + +// Anonymous structures and unions -- taken from C11 6.7.2.1 Example 1. +struct anonymous +{ + union { + struct { int i; int j; }; + struct { int k; long int l; } w; + }; + int m; +} v1; +' + +# Test code for whether the C compiler supports C11 (body of main). +ac_c_conftest_c11_main=' + _Static_assert ((offsetof (struct anonymous, i) + == offsetof (struct anonymous, w.k)), + "Anonymous union alignment botch"); + v1.i = 2; + v1.w.k = 5; + ok |= v1.i != 5; +' + +# Test code for whether the C compiler supports C11 (complete). +ac_c_conftest_c11_program="${ac_c_conftest_c89_globals} +${ac_c_conftest_c99_globals} +${ac_c_conftest_c11_globals} + +int +main (int argc, char **argv) +{ + int ok = 0; + ${ac_c_conftest_c89_main} + ${ac_c_conftest_c99_main} + ${ac_c_conftest_c11_main} + return ok; +} +" + +# Test code for whether the C compiler supports C99 (complete). +ac_c_conftest_c99_program="${ac_c_conftest_c89_globals} +${ac_c_conftest_c99_globals} + +int +main (int argc, char **argv) +{ + int ok = 0; + ${ac_c_conftest_c89_main} + ${ac_c_conftest_c99_main} + return ok; +} +" + +# Test code for whether the C compiler supports C89 (complete). +ac_c_conftest_c89_program="${ac_c_conftest_c89_globals} + +int +main (int argc, char **argv) +{ + int ok = 0; + ${ac_c_conftest_c89_main} + return ok; +} +" + +as_fn_append ac_header_c_list " stdio.h stdio_h HAVE_STDIO_H" +as_fn_append ac_header_c_list " stdlib.h stdlib_h HAVE_STDLIB_H" +as_fn_append ac_header_c_list " string.h string_h HAVE_STRING_H" +as_fn_append ac_header_c_list " inttypes.h inttypes_h HAVE_INTTYPES_H" +as_fn_append ac_header_c_list " stdint.h stdint_h HAVE_STDINT_H" +as_fn_append ac_header_c_list " strings.h strings_h HAVE_STRINGS_H" +as_fn_append ac_header_c_list " sys/stat.h sys_stat_h HAVE_SYS_STAT_H" +as_fn_append ac_header_c_list " sys/types.h sys_types_h HAVE_SYS_TYPES_H" +as_fn_append ac_header_c_list " unistd.h unistd_h HAVE_UNISTD_H" +as_fn_append ac_header_c_list " wchar.h wchar_h HAVE_WCHAR_H" +as_fn_append ac_header_c_list " minix/config.h minix_config_h HAVE_MINIX_CONFIG_H" + +# Auxiliary files required by this configure script. +ac_aux_files="install-sh config.guess config.sub" + +# Locations in which to look for auxiliary files. +ac_aux_dir_candidates="${srcdir}${PATH_SEPARATOR}${srcdir}/..${PATH_SEPARATOR}${srcdir}/../.." + +# Search for a directory containing all of the required auxiliary files, +# $ac_aux_files, from the $PATH-style list $ac_aux_dir_candidates. +# If we don't find one directory that contains all the files we need, +# we report the set of missing files from the *first* directory in +# $ac_aux_dir_candidates and give up. +ac_missing_aux_files="" +ac_first_candidate=: +printf "%s\n" "$as_me:${as_lineno-$LINENO}: looking for aux files: $ac_aux_files" >&5 +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in $ac_aux_dir_candidates +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + as_found=: + + printf "%s\n" "$as_me:${as_lineno-$LINENO}: trying $as_dir" >&5 + ac_aux_dir_found=yes + ac_install_sh= + for ac_aux in $ac_aux_files + do + # As a special case, if "install-sh" is required, that requirement + # can be satisfied by any of "install-sh", "install.sh", or "shtool", + # and $ac_install_sh is set appropriately for whichever one is found. + if test x"$ac_aux" = x"install-sh" + then + if test -f "${as_dir}install-sh"; then + printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}install-sh found" >&5 + ac_install_sh="${as_dir}install-sh -c" + elif test -f "${as_dir}install.sh"; then + printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}install.sh found" >&5 + ac_install_sh="${as_dir}install.sh -c" + elif test -f "${as_dir}shtool"; then + printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}shtool found" >&5 + ac_install_sh="${as_dir}shtool install -c" + else + ac_aux_dir_found=no + if $ac_first_candidate; then + ac_missing_aux_files="${ac_missing_aux_files} install-sh" + else + break + fi + fi + else + if test -f "${as_dir}${ac_aux}"; then + printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}${ac_aux} found" >&5 + else + ac_aux_dir_found=no + if $ac_first_candidate; then + ac_missing_aux_files="${ac_missing_aux_files} ${ac_aux}" + else + break + fi + fi + fi + done + if test "$ac_aux_dir_found" = yes; then + ac_aux_dir="$as_dir" + break + fi + ac_first_candidate=false + + as_found=false +done +IFS=$as_save_IFS +if $as_found +then : + +else $as_nop + as_fn_error $? "cannot find required auxiliary files:$ac_missing_aux_files" "$LINENO" 5 +fi + + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +if test -f "${ac_aux_dir}config.guess"; then + ac_config_guess="$SHELL ${ac_aux_dir}config.guess" +fi +if test -f "${ac_aux_dir}config.sub"; then + ac_config_sub="$SHELL ${ac_aux_dir}config.sub" +fi +if test -f "$ac_aux_dir/configure"; then + ac_configure="$SHELL ${ac_aux_dir}configure" +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +printf "%s\n" "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +printf "%s\n" "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +printf "%s\n" "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +printf "%s\n" "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +printf "%s\n" "$as_me: former value: \`$ac_old_val'" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +printf "%s\n" "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`printf "%s\n" "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then - { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 -$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} - as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +printf "%s\n" "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run \`${MAKE-make} distclean' and/or \`rm $cache_file' + and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## @@ -3056,7 +3496,6 @@ if test "$srcdir" != . -a "$srcdir" != "$(pwd)"; then # resources get picked up before their $srcdir counterparts. # Objects/ -> typeslots.inc # Include/ -> Python.h - # Python/ -> importlib.h # (A side effect of this is that these resources will automatically be # regenerated when building out-of-tree, regardless of whether or not # the $srcdir counterpart is up-to-date. This is an acceptable trade @@ -3074,11 +3513,12 @@ if test -e $srcdir/.git then # Extract the first word of "git", so it can be a program name with args. set dummy git; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_HAS_GIT+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_HAS_GIT+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$HAS_GIT"; then ac_cv_prog_HAS_GIT="$HAS_GIT" # Let the user override the test. else @@ -3086,11 +3526,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_HAS_GIT="found" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -3102,11 +3546,11 @@ fi fi HAS_GIT=$ac_cv_prog_HAS_GIT if test -n "$HAS_GIT"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAS_GIT" >&5 -$as_echo "$HAS_GIT" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $HAS_GIT" >&5 +printf "%s\n" "$HAS_GIT" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -3128,55 +3572,30 @@ fi ac_config_headers="$ac_config_headers pyconfig.h" -ac_aux_dir= -for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do - if test -f "$ac_dir/install-sh"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install-sh -c" - break - elif test -f "$ac_dir/install.sh"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install.sh -c" - break - elif test -f "$ac_dir/shtool"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/shtool install -c" - break - fi -done -if test -z "$ac_aux_dir"; then - as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 -fi -# These three variables are undocumented and unsupported, -# and are intended to be withdrawn in a future Autoconf release. -# They can cause serious problems if a builder's source tree is in a directory -# whose full name contains unusual characters. -ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. -ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. -ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. -# Make sure we can run config.sub. -$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || - as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 + # Make sure we can run config.sub. +$SHELL "${ac_aux_dir}config.sub" sun4 >/dev/null 2>&1 || + as_fn_error $? "cannot run $SHELL ${ac_aux_dir}config.sub" "$LINENO" 5 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 -$as_echo_n "checking build system type... " >&6; } -if ${ac_cv_build+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 +printf %s "checking build system type... " >&6; } +if test ${ac_cv_build+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_build_alias=$build_alias test "x$ac_build_alias" = x && - ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` + ac_build_alias=`$SHELL "${ac_aux_dir}config.guess"` test "x$ac_build_alias" = x && as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 -ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || - as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 +ac_cv_build=`$SHELL "${ac_aux_dir}config.sub" $ac_build_alias` || + as_fn_error $? "$SHELL ${ac_aux_dir}config.sub $ac_build_alias failed" "$LINENO" 5 fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 -$as_echo "$ac_cv_build" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 +printf "%s\n" "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; @@ -3195,21 +3614,22 @@ IFS=$ac_save_IFS case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 -$as_echo_n "checking host system type... " >&6; } -if ${ac_cv_host+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 +printf %s "checking host system type... " >&6; } +if test ${ac_cv_host+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test "x$host_alias" = x; then ac_cv_host=$ac_cv_build else - ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || - as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 + ac_cv_host=`$SHELL "${ac_aux_dir}config.sub" $host_alias` || + as_fn_error $? "$SHELL ${ac_aux_dir}config.sub $host_alias failed" "$LINENO" 5 fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 -$as_echo "$ac_cv_host" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 +printf "%s\n" "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; @@ -3231,7 +3651,8 @@ case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac -if test "x$cross_compiling" = xmaybe; then : +if test "x$cross_compiling" = xmaybe +then : as_fn_error $? "Cross compiling required --host=HOST-TUPLE and --build=ARCH" "$LINENO" 5 fi @@ -3241,15 +3662,18 @@ rm -f pybuilddir.txt # Check whether --with-build-python was given. -if test "${with_build_python+set}" = set; then : +if test ${with_build_python+y} +then : withval=$with_build_python; - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-build-python" >&5 -$as_echo_n "checking for --with-build-python... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-build-python" >&5 +printf %s "checking for --with-build-python... " >&6; } - if test "x$with_build_python" = xyes; then : + if test "x$with_build_python" = xyes +then : with_build_python=python$PACKAGE_VERSION fi - if test "x$with_build_python" = xno; then : + if test "x$with_build_python" = xno +then : as_fn_error $? "invalid --with-build-python option: expected path or \"yes\", not \"no\"" "$LINENO" 5 fi @@ -3263,12 +3687,13 @@ fi ac_cv_prog_PYTHON_FOR_REGEN=$with_build_python PYTHON_FOR_FREEZE="$with_build_python" PYTHON_FOR_BUILD='_PYTHON_PROJECT_BASE=$(abs_builddir) _PYTHON_HOST_PLATFORM=$(_PYTHON_HOST_PLATFORM) PYTHONPATH=$(shell test -f pybuilddir.txt && echo $(abs_builddir)/`cat pybuilddir.txt`:)$(srcdir)/Lib _PYTHON_SYSCONFIGDATA_NAME=_sysconfigdata_$(ABIFLAGS)_$(MACHDEP)_$(MULTIARCH) '$with_build_python - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_build_python" >&5 -$as_echo "$with_build_python" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_build_python" >&5 +printf "%s\n" "$with_build_python" >&6; } -else +else $as_nop - if test "x$cross_compiling" = xyes; then : + if test "x$cross_compiling" = xyes +then : as_fn_error $? "Cross compiling requires --with-build-python" "$LINENO" 5 fi @@ -3280,13 +3705,14 @@ fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Python interpreter freezing" >&5 -$as_echo_n "checking for Python interpreter freezing... " >&6; } -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON_FOR_FREEZE" >&5 -$as_echo "$PYTHON_FOR_FREEZE" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Python interpreter freezing" >&5 +printf %s "checking for Python interpreter freezing... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PYTHON_FOR_FREEZE" >&5 +printf "%s\n" "$PYTHON_FOR_FREEZE" >&6; } -if test "x$cross_compiling" = xyes; then : +if test "x$cross_compiling" = xyes +then : FREEZE_MODULE_BOOTSTRAP='$(PYTHON_FOR_FREEZE) $(srcdir)/Programs/_freeze_module.py' FREEZE_MODULE_BOOTSTRAP_DEPS='$(srcdir)/Programs/_freeze_module.py' @@ -3294,7 +3720,7 @@ if test "x$cross_compiling" = xyes; then : FREEZE_MODULE_DEPS='$(FREEZE_MODULE_BOOTSTRAP_DEPS)' PYTHON_FOR_BUILD_DEPS='' -else +else $as_nop FREEZE_MODULE_BOOTSTRAP='./Programs/_freeze_module' FREEZE_MODULE_BOOTSTRAP_DEPS="Programs/_freeze_module" @@ -3310,15 +3736,16 @@ fi -for ac_prog in python$PACKAGE_VERSION python3.10 python3.9 python3.8 python3.7 python3.6 python3 python +for ac_prog in python$PACKAGE_VERSION python3.12 python3.11 python3.10 python3 python do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_PYTHON_FOR_REGEN+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_PYTHON_FOR_REGEN+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$PYTHON_FOR_REGEN"; then ac_cv_prog_PYTHON_FOR_REGEN="$PYTHON_FOR_REGEN" # Let the user override the test. else @@ -3326,11 +3753,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_PYTHON_FOR_REGEN="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -3341,11 +3772,11 @@ fi fi PYTHON_FOR_REGEN=$ac_cv_prog_PYTHON_FOR_REGEN if test -n "$PYTHON_FOR_REGEN"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON_FOR_REGEN" >&5 -$as_echo "$PYTHON_FOR_REGEN" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PYTHON_FOR_REGEN" >&5 +printf "%s\n" "$PYTHON_FOR_REGEN" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -3355,14 +3786,14 @@ test -n "$PYTHON_FOR_REGEN" || PYTHON_FOR_REGEN="python3" -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking Python for regen version" >&5 -$as_echo_n "checking Python for regen version... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking Python for regen version" >&5 +printf %s "checking Python for regen version... " >&6; } if command -v "$PYTHON_FOR_REGEN" >/dev/null 2>&1; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $($PYTHON_FOR_REGEN -V 2>/dev/null)" >&5 -$as_echo "$($PYTHON_FOR_REGEN -V 2>/dev/null)" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $($PYTHON_FOR_REGEN -V 2>/dev/null)" >&5 +printf "%s\n" "$($PYTHON_FOR_REGEN -V 2>/dev/null)" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: missing" >&5 -$as_echo "missing" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: missing" >&5 +printf "%s\n" "missing" >&6; } fi @@ -3380,7 +3811,7 @@ rm confdefs.h mv confdefs.h.new confdefs.h -VERSION=3.11 +VERSION=3.12 # Version number of Python's own shared library file. @@ -3390,21 +3821,21 @@ SOVERSION=1.0 # certain features on NetBSD, so we need _NETBSD_SOURCE to re-enable # them. -$as_echo "#define _NETBSD_SOURCE 1" >>confdefs.h +printf "%s\n" "#define _NETBSD_SOURCE 1" >>confdefs.h # The later definition of _XOPEN_SOURCE and _POSIX_C_SOURCE disables # certain features on FreeBSD, so we need __BSD_VISIBLE to re-enable # them. -$as_echo "#define __BSD_VISIBLE 1" >>confdefs.h +printf "%s\n" "#define __BSD_VISIBLE 1" >>confdefs.h # The later definition of _XOPEN_SOURCE and _POSIX_C_SOURCE disables # certain features on Mac OS X, so we need _DARWIN_C_SOURCE to re-enable # them. -$as_echo "#define _DARWIN_C_SOURCE 1" >>confdefs.h +printf "%s\n" "#define _DARWIN_C_SOURCE 1" >>confdefs.h @@ -3416,9 +3847,10 @@ CONFIG_ARGS="$ac_configure_args" # Check whether --with-pkg-config was given. -if test "${with_pkg_config+set}" = set; then : +if test ${with_pkg_config+y} +then : withval=$with_pkg_config; -else +else $as_nop with_pkg_config=check fi @@ -3442,11 +3874,12 @@ if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_PKG_CONFIG+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_PKG_CONFIG+y} +then : + printf %s "(cached) " >&6 +else $as_nop case $PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. @@ -3456,11 +3889,15 @@ else for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_PKG_CONFIG="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -3472,11 +3909,11 @@ esac fi PKG_CONFIG=$ac_cv_path_PKG_CONFIG if test -n "$PKG_CONFIG"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 -$as_echo "$PKG_CONFIG" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 +printf "%s\n" "$PKG_CONFIG" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -3485,11 +3922,12 @@ if test -z "$ac_cv_path_PKG_CONFIG"; then ac_pt_PKG_CONFIG=$PKG_CONFIG # Extract the first word of "pkg-config", so it can be a program name with args. set dummy pkg-config; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_ac_pt_PKG_CONFIG+y} +then : + printf %s "(cached) " >&6 +else $as_nop case $ac_pt_PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. @@ -3499,11 +3937,15 @@ else for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_ac_pt_PKG_CONFIG="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -3515,11 +3957,11 @@ esac fi ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG if test -n "$ac_pt_PKG_CONFIG"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 -$as_echo "$ac_pt_PKG_CONFIG" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 +printf "%s\n" "$ac_pt_PKG_CONFIG" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi if test "x$ac_pt_PKG_CONFIG" = x; then @@ -3527,8 +3969,8 @@ fi else case $cross_compiling:$ac_tool_warned in yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac PKG_CONFIG=$ac_pt_PKG_CONFIG @@ -3540,14 +3982,14 @@ fi fi if test -n "$PKG_CONFIG"; then _pkg_min_version=0.9.0 - { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 -$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 +printf %s "checking pkg-config is at least version $_pkg_min_version... " >&6; } if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } PKG_CONFIG="" fi fi @@ -3566,10 +4008,11 @@ if test "$with_pkg_config" = yes -a -z "$PKG_CONFIG"; then as_fn_error $? "pkg-config is required" "$LINENO" 5] fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --enable-universalsdk" >&5 -$as_echo_n "checking for --enable-universalsdk... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --enable-universalsdk" >&5 +printf %s "checking for --enable-universalsdk... " >&6; } # Check whether --enable-universalsdk was given. -if test "${enable_universalsdk+set}" = set; then : +if test ${enable_universalsdk+y} +then : enableval=$enable_universalsdk; case $enableval in yes) @@ -3601,7 +4044,7 @@ if test "${enable_universalsdk+set}" = set; then : esac -else +else $as_nop UNIVERSALSDK= enable_universalsdk= @@ -3610,11 +4053,11 @@ fi if test -n "${UNIVERSALSDK}" then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${UNIVERSALSDK}" >&5 -$as_echo "${UNIVERSALSDK}" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ${UNIVERSALSDK}" >&5 +printf "%s\n" "${UNIVERSALSDK}" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -3637,11 +4080,12 @@ fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-universal-archs" >&5 -$as_echo_n "checking for --with-universal-archs... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-universal-archs" >&5 +printf %s "checking for --with-universal-archs... " >&6; } # Check whether --with-universal-archs was given. -if test "${with_universal_archs+set}" = set; then : +if test ${with_universal_archs+y} +then : withval=$with_universal_archs; UNIVERSAL_ARCHS="$withval" @@ -3649,22 +4093,23 @@ fi if test -n "${UNIVERSALSDK}" then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${UNIVERSAL_ARCHS}" >&5 -$as_echo "${UNIVERSAL_ARCHS}" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ${UNIVERSAL_ARCHS}" >&5 +printf "%s\n" "${UNIVERSAL_ARCHS}" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi # Check whether --with-framework-name was given. -if test "${with_framework_name+set}" = set; then : +if test ${with_framework_name+y} +then : withval=$with_framework_name; PYTHONFRAMEWORK=${withval} PYTHONFRAMEWORKDIR=${withval}.framework PYTHONFRAMEWORKIDENTIFIER=org.python.`echo $withval | tr 'A-Z' 'a-z'` -else +else $as_nop PYTHONFRAMEWORK=Python PYTHONFRAMEWORKDIR=Python.framework @@ -3673,7 +4118,8 @@ else fi # Check whether --enable-framework was given. -if test "${enable_framework+set}" = set; then : +if test ${enable_framework+y} +then : enableval=$enable_framework; case $enableval in yes) @@ -3762,7 +4208,7 @@ if test "${enable_framework+set}" = set; then : esac -else +else $as_nop PYTHONFRAMEWORK= PYTHONFRAMEWORKDIR=no-framework @@ -3797,15 +4243,13 @@ fi -cat >>confdefs.h <<_ACEOF -#define _PYTHONFRAMEWORK "${PYTHONFRAMEWORK}" -_ACEOF +printf "%s\n" "#define _PYTHONFRAMEWORK \"${PYTHONFRAMEWORK}\"" >>confdefs.h # Set name for machine-dependent library files -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking MACHDEP" >&5 -$as_echo_n "checking MACHDEP... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking MACHDEP" >&5 +printf %s "checking MACHDEP... " >&6; } if test -z "$MACHDEP" then # avoid using uname for cross builds @@ -3861,8 +4305,8 @@ then '') MACHDEP="unknown";; esac fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: \"$MACHDEP\"" >&5 -$as_echo "\"$MACHDEP\"" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: \"$MACHDEP\"" >&5 +printf "%s\n" "\"$MACHDEP\"" >&6; } if test "$cross_compiling" = yes; then @@ -3914,7 +4358,7 @@ case $ac_sys_system/$ac_sys_release in # also defined. This can be overridden by defining _BSD_SOURCE # As this has a different meaning on Linux, only define it on OpenBSD -$as_echo "#define _BSD_SOURCE 1" >>confdefs.h +printf "%s\n" "#define _BSD_SOURCE 1" >>confdefs.h ;; OpenBSD/*) @@ -3922,7 +4366,7 @@ $as_echo "#define _BSD_SOURCE 1" >>confdefs.h # also defined. This can be overridden by defining _BSD_SOURCE # As this has a different meaning on Linux, only define it on OpenBSD -$as_echo "#define _BSD_SOURCE 1" >>confdefs.h +printf "%s\n" "#define _BSD_SOURCE 1" >>confdefs.h ;; # Defining _XOPEN_SOURCE on NetBSD version prior to the introduction of @@ -3980,7 +4424,7 @@ if test $define_xopen_source = yes then # X/Open 7, incorporating POSIX.1-2008 -$as_echo "#define _XOPEN_SOURCE 700" >>confdefs.h +printf "%s\n" "#define _XOPEN_SOURCE 700" >>confdefs.h # On Tru64 Unix 4.0F, defining _XOPEN_SOURCE also requires @@ -3988,11 +4432,11 @@ $as_echo "#define _XOPEN_SOURCE 700" >>confdefs.h # several APIs are not declared. Since this is also needed in some # cases for HP-UX, we define it globally. -$as_echo "#define _XOPEN_SOURCE_EXTENDED 1" >>confdefs.h +printf "%s\n" "#define _XOPEN_SOURCE_EXTENDED 1" >>confdefs.h -$as_echo "#define _POSIX_C_SOURCE 200809L" >>confdefs.h +printf "%s\n" "#define _POSIX_C_SOURCE 200809L" >>confdefs.h fi @@ -4007,7 +4451,7 @@ esac if test $define_stdc_a1 = yes then -$as_echo "#define _INCLUDE__STDC_A1_SOURCE 1" >>confdefs.h +printf "%s\n" "#define _INCLUDE__STDC_A1_SOURCE 1" >>confdefs.h fi @@ -4053,6 +4497,61 @@ esac if test "$ac_sys_system" = "Darwin" then + # Extract the first word of "xcrun", so it can be a program name with args. +set dummy xcrun; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_HAS_XCRUN+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$HAS_XCRUN"; then + ac_cv_prog_HAS_XCRUN="$HAS_XCRUN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_HAS_XCRUN="yes" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_prog_HAS_XCRUN" && ac_cv_prog_HAS_XCRUN="missing" +fi +fi +HAS_XCRUN=$ac_cv_prog_HAS_XCRUN +if test -n "$HAS_XCRUN"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $HAS_XCRUN" >&5 +printf "%s\n" "$HAS_XCRUN" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking macOS SDKROOT" >&5 +printf %s "checking macOS SDKROOT... " >&6; } + if test -z "$SDKROOT"; then + if test "$HAS_XCRUN" = "yes"; then + SDKROOT=$(xcrun --show-sdk-path) + else + SDKROOT="/" + fi + fi + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $SDKROOT" >&5 +printf "%s\n" "$SDKROOT" >&6; } + # Compiler selection on MacOSX is more complicated than # AC_PROG_CC can handle, see Mac/README for more # information @@ -4081,8 +4580,8 @@ then then if test -n "`"$found_gcc" --version | grep llvm-gcc`" then - { $as_echo "$as_me:${as_lineno-$LINENO}: Detected llvm-gcc, falling back to clang" >&5 -$as_echo "$as_me: Detected llvm-gcc, falling back to clang" >&6;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Detected llvm-gcc, falling back to clang" >&5 +printf "%s\n" "$as_me: Detected llvm-gcc, falling back to clang" >&6;} CC="$found_clang" CXX="$found_clang++" fi @@ -4090,8 +4589,8 @@ $as_echo "$as_me: Detected llvm-gcc, falling back to clang" >&6;} elif test -z "$found_gcc" -a -n "$found_clang" then - { $as_echo "$as_me:${as_lineno-$LINENO}: No GCC found, use CLANG" >&5 -$as_echo "$as_me: No GCC found, use CLANG" >&6;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: No GCC found, use CLANG" >&5 +printf "%s\n" "$as_me: No GCC found, use CLANG" >&6;} CC="$found_clang" CXX="$found_clang++" @@ -4100,8 +4599,8 @@ $as_echo "$as_me: No GCC found, use CLANG" >&6;} found_clang=`/usr/bin/xcrun -find clang 2>/dev/null` if test -n "${found_clang}" then - { $as_echo "$as_me:${as_lineno-$LINENO}: Using clang from Xcode.app" >&5 -$as_echo "$as_me: Using clang from Xcode.app" >&6;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Using clang from Xcode.app" >&5 +printf "%s\n" "$as_me: Using clang from Xcode.app" >&6;} CC="${found_clang}" CXX="`/usr/bin/xcrun -find clang++`" @@ -4110,6 +4609,15 @@ $as_echo "$as_me: Using clang from Xcode.app" >&6;} fi fi fi + + + + + + + + + ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -4118,11 +4626,12 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_CC+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else @@ -4130,11 +4639,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -4145,11 +4658,11 @@ fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +printf "%s\n" "$CC" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -4158,11 +4671,12 @@ if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_CC+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else @@ -4170,11 +4684,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -4185,11 +4703,11 @@ fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 -$as_echo "$ac_ct_CC" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +printf "%s\n" "$ac_ct_CC" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi if test "x$ac_ct_CC" = x; then @@ -4197,8 +4715,8 @@ fi else case $cross_compiling:$ac_tool_warned in yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC @@ -4211,11 +4729,12 @@ if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_CC+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else @@ -4223,11 +4742,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -4238,11 +4761,11 @@ fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +printf "%s\n" "$CC" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -4251,11 +4774,12 @@ fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_CC+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else @@ -4264,15 +4788,19 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + if test "$as_dir$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -4288,18 +4816,18 @@ if test $ac_prog_rejected = yes; then # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift - ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + ac_cv_prog_CC="$as_dir$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +printf "%s\n" "$CC" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -4310,11 +4838,12 @@ if test -z "$CC"; then do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_CC+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else @@ -4322,11 +4851,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -4337,11 +4870,11 @@ fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +printf "%s\n" "$CC" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -4354,11 +4887,12 @@ if test -z "$CC"; then do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_CC+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else @@ -4366,11 +4900,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -4381,11 +4919,11 @@ fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 -$as_echo "$ac_ct_CC" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +printf "%s\n" "$ac_ct_CC" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -4397,8 +4935,8 @@ done else case $cross_compiling:$ac_tool_warned in yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC @@ -4406,25 +4944,129 @@ esac fi fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}clang", so it can be a program name with args. +set dummy ${ac_tool_prefix}clang; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_CC+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}clang" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +printf "%s\n" "$CC" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi -test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "clang", so it can be a program name with args. +set dummy clang; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_CC+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="clang" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +printf "%s\n" "$ac_ct_CC" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +fi + + +test -z "$CC" && { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. -$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 -for ac_option in --version -v -V -qversion; do +for ac_option in --version -v -V -qversion -version; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 +printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then @@ -4434,7 +5076,7 @@ $as_echo "$ac_try_echo"; } >&5 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done @@ -4442,7 +5084,7 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int -main () +main (void) { ; @@ -4454,9 +5096,9 @@ ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 -$as_echo_n "checking whether the C compiler works... " >&6; } -ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 +printf %s "checking whether the C compiler works... " >&6; } +ac_link_default=`printf "%s\n" "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" @@ -4477,11 +5119,12 @@ case "(($ac_try" in *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 +printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then : + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, @@ -4498,7 +5141,7 @@ do # certainly right. break;; *.* ) - if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + if test ${ac_cv_exeext+y} && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi @@ -4514,44 +5157,46 @@ do done test "$ac_cv_exeext" = no && ac_cv_exeext= -else +else $as_nop ac_file='' fi -if test -z "$ac_file"; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -$as_echo "$as_me: failed program was:" >&5 +if test -z "$ac_file" +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables See \`config.log' for more details" "$LINENO" 5; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 -$as_echo_n "checking for C compiler default output file name... " >&6; } -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 -$as_echo "$ac_file" >&6; } +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 +printf %s "checking for C compiler default output file name... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +printf "%s\n" "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 -$as_echo_n "checking for suffix of executables... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +printf %s "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 +printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then : + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with @@ -4565,15 +5210,15 @@ for ac_file in conftest.exe conftest conftest.*; do * ) break;; esac done -else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +else $as_nop + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 -$as_echo "$ac_cv_exeext" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +printf "%s\n" "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext @@ -4582,7 +5227,7 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int -main () +main (void) { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; @@ -4594,8 +5239,8 @@ _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 -$as_echo_n "checking whether we are cross compiling... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +printf %s "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in @@ -4603,10 +5248,10 @@ case "(($ac_try" in *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 +printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in @@ -4614,39 +5259,40 @@ $as_echo "$ac_try_echo"; } >&5 *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 +printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "cannot run C compiled programs. + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 -$as_echo "$cross_compiling" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +printf "%s\n" "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 -$as_echo_n "checking for suffix of object files... " >&6; } -if ${ac_cv_objext+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +printf %s "checking for suffix of object files... " >&6; } +if test ${ac_cv_objext+y} +then : + printf %s "(cached) " >&6 +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int -main () +main (void) { ; @@ -4660,11 +5306,12 @@ case "(($ac_try" in *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 +printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then : + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in @@ -4673,31 +5320,32 @@ $as_echo "$ac_try_echo"; } >&5 break;; esac done -else - $as_echo "$as_me: failed program was:" >&5 +else $as_nop + printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 -$as_echo "$ac_cv_objext" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +printf "%s\n" "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 -$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } -if ${ac_cv_c_compiler_gnu+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GNU C" >&5 +printf %s "checking whether the compiler supports GNU C... " >&6; } +if test ${ac_cv_c_compiler_gnu+y} +then : + printf %s "(cached) " >&6 +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int -main () +main (void) { #ifndef __GNUC__ choke me @@ -4707,29 +5355,33 @@ main () return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : ac_compiler_gnu=yes -else +else $as_nop ac_compiler_gnu=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 -$as_echo "$ac_cv_c_compiler_gnu" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +printf "%s\n" "$ac_cv_c_compiler_gnu" >&6; } +ac_compiler_gnu=$ac_cv_c_compiler_gnu + if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi -ac_test_CFLAGS=${CFLAGS+set} +ac_test_CFLAGS=${CFLAGS+y} ac_save_CFLAGS=$CFLAGS -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 -$as_echo_n "checking whether $CC accepts -g... " >&6; } -if ${ac_cv_prog_cc_g+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +printf %s "checking whether $CC accepts -g... " >&6; } +if test ${ac_cv_prog_cc_g+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no @@ -4738,57 +5390,60 @@ else /* end confdefs.h. */ int -main () +main (void) { ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : ac_cv_prog_cc_g=yes -else +else $as_nop CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int -main () +main (void) { ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : -else +else $as_nop ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int -main () +main (void) { ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : ac_cv_prog_cc_g=yes fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 -$as_echo "$ac_cv_prog_cc_g" >&6; } -if test "$ac_test_CFLAGS" = set; then +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +printf "%s\n" "$ac_cv_prog_cc_g" >&6; } +if test $ac_test_CFLAGS; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then @@ -4803,94 +5458,144 @@ else CFLAGS= fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 -$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } -if ${ac_cv_prog_cc_c89+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_cv_prog_cc_c89=no +ac_prog_cc_stdc=no +if test x$ac_prog_cc_stdc = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C11 features" >&5 +printf %s "checking for $CC option to enable C11 features... " >&6; } +if test ${ac_cv_prog_cc_c11+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_cv_prog_cc_c11=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include -#include -struct stat; -/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ -struct buf { int x; }; -FILE * (*rcsopen) (struct buf *, struct stat *, int); -static char *e (p, i) - char **p; - int i; -{ - return p[i]; -} -static char *f (char * (*g) (char **, int), char **p, ...) -{ - char *s; - va_list v; - va_start (v,p); - s = g (p, va_arg (v,int)); - va_end (v); - return s; -} - -/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has - function prototypes and stuff, but not '\xHH' hex character constants. - These don't provoke an error unfortunately, instead are silently treated - as 'x'. The following induces an error, until -std is added to get - proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an - array size at least. It's necessary to write '\x00'==0 to get something - that's true only with -std. */ -int osf4_cc_array ['\x00' == 0 ? 1 : -1]; +$ac_c_conftest_c11_program +_ACEOF +for ac_arg in '' -std=gnu11 +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_prog_cc_c11=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam + test "x$ac_cv_prog_cc_c11" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC +fi -/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters - inside strings and character constants. */ -#define FOO(x) 'x' -int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; +if test "x$ac_cv_prog_cc_c11" = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +printf "%s\n" "unsupported" >&6; } +else $as_nop + if test "x$ac_cv_prog_cc_c11" = x +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +printf "%s\n" "none needed" >&6; } +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c11" >&5 +printf "%s\n" "$ac_cv_prog_cc_c11" >&6; } + CC="$CC $ac_cv_prog_cc_c11" +fi + ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c11 + ac_prog_cc_stdc=c11 +fi +fi +if test x$ac_prog_cc_stdc = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C99 features" >&5 +printf %s "checking for $CC option to enable C99 features... " >&6; } +if test ${ac_cv_prog_cc_c99+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_cv_prog_cc_c99=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_c_conftest_c99_program +_ACEOF +for ac_arg in '' -std=gnu99 -std=c99 -c99 -qlanglvl=extc1x -qlanglvl=extc99 -AC99 -D_STDC_C99= +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_prog_cc_c99=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam + test "x$ac_cv_prog_cc_c99" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC +fi -int test (int i, double x); -struct s1 {int (*f) (int a);}; -struct s2 {int (*f) (double a);}; -int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); -int argc; -char **argv; -int -main () -{ -return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; - ; - return 0; -} +if test "x$ac_cv_prog_cc_c99" = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +printf "%s\n" "unsupported" >&6; } +else $as_nop + if test "x$ac_cv_prog_cc_c99" = x +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +printf "%s\n" "none needed" >&6; } +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5 +printf "%s\n" "$ac_cv_prog_cc_c99" >&6; } + CC="$CC $ac_cv_prog_cc_c99" +fi + ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99 + ac_prog_cc_stdc=c99 +fi +fi +if test x$ac_prog_cc_stdc = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C89 features" >&5 +printf %s "checking for $CC option to enable C89 features... " >&6; } +if test ${ac_cv_prog_cc_c89+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_c_conftest_c89_program _ACEOF -for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ - -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" - if ac_fn_c_try_compile "$LINENO"; then : + if ac_fn_c_try_compile "$LINENO" +then : ac_cv_prog_cc_c89=$ac_arg fi -rm -f core conftest.err conftest.$ac_objext +rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC - fi -# AC_CACHE_VAL -case "x$ac_cv_prog_cc_c89" in - x) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 -$as_echo "none needed" >&6; } ;; - xno) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 -$as_echo "unsupported" >&6; } ;; - *) - CC="$CC $ac_cv_prog_cc_c89" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 -$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; -esac -if test "x$ac_cv_prog_cc_c89" != xno; then : +if test "x$ac_cv_prog_cc_c89" = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +printf "%s\n" "unsupported" >&6; } +else $as_nop + if test "x$ac_cv_prog_cc_c89" = x +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +printf "%s\n" "none needed" >&6; } +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +printf "%s\n" "$ac_cv_prog_cc_c89" >&6; } + CC="$CC $ac_cv_prog_cc_c89" +fi + ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89 + ac_prog_cc_stdc=c89 +fi fi ac_ext=c @@ -4904,40 +5609,36 @@ ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 -$as_echo_n "checking how to run the C preprocessor... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +printf %s "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then - if ${ac_cv_prog_CPP+:} false; then : - $as_echo_n "(cached) " >&6 -else - # Double quotes because CPP needs to be expanded - for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + if test ${ac_cv_prog_CPP+y} +then : + printf %s "(cached) " >&6 +else $as_nop + # Double quotes because $CC needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" cpp /lib/cpp do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. - # Prefer to if __STDC__ is defined, since - # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#ifdef __STDC__ -# include -#else -# include -#endif +#include Syntax error _ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : +if ac_fn_c_try_cpp "$LINENO" +then : -else +else $as_nop # Broken: fails on valid input. continue fi @@ -4949,10 +5650,11 @@ rm -f conftest.err conftest.i conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : +if ac_fn_c_try_cpp "$LINENO" +then : # Broken: success on invalid input. continue -else +else $as_nop # Passes both tests. ac_preproc_ok=: break @@ -4962,7 +5664,8 @@ rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext -if $ac_preproc_ok; then : +if $ac_preproc_ok +then : break fi @@ -4974,29 +5677,24 @@ fi else ac_cv_prog_CPP=$CPP fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 -$as_echo "$CPP" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +printf "%s\n" "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. - # Prefer to if __STDC__ is defined, since - # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#ifdef __STDC__ -# include -#else -# include -#endif +#include Syntax error _ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : +if ac_fn_c_try_cpp "$LINENO" +then : -else +else $as_nop # Broken: fails on valid input. continue fi @@ -5008,10 +5706,11 @@ rm -f conftest.err conftest.i conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : +if ac_fn_c_try_cpp "$LINENO" +then : # Broken: success on invalid input. continue -else +else $as_nop # Passes both tests. ac_preproc_ok=: break @@ -5021,11 +5720,12 @@ rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext -if $ac_preproc_ok; then : +if $ac_preproc_ok +then : -else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +else $as_nop + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi @@ -5036,11 +5736,12 @@ ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 -$as_echo_n "checking for grep that handles long lines and -e... " >&6; } -if ${ac_cv_path_GREP+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +printf %s "checking for grep that handles long lines and -e... " >&6; } +if test ${ac_cv_path_GREP+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST @@ -5048,10 +5749,15 @@ else for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in grep ggrep; do + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_prog in grep ggrep + do for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + ac_path_GREP="$as_dir$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_GREP" || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP @@ -5060,13 +5766,13 @@ case `"$ac_path_GREP" --version 2>&1` in ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 - $as_echo_n 0123456789 >"conftest.in" + printf %s 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" - $as_echo 'GREP' >> "conftest.nl" + printf "%s\n" 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val @@ -5094,16 +5800,17 @@ else fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 -$as_echo "$ac_cv_path_GREP" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +printf "%s\n" "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 -$as_echo_n "checking for a sed that does not truncate output... " >&6; } -if ${ac_cv_path_SED+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 +printf %s "checking for a sed that does not truncate output... " >&6; } +if test ${ac_cv_path_SED+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ for ac_i in 1 2 3 4 5 6 7; do ac_script="$ac_script$as_nl$ac_script" @@ -5117,10 +5824,15 @@ else for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in sed gsed; do + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_prog in sed gsed + do for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" + ac_path_SED="$as_dir$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_SED" || continue # Check for GNU ac_path_SED and select it if it is found. # Check for GNU $ac_path_SED @@ -5129,13 +5841,13 @@ case `"$ac_path_SED" --version 2>&1` in ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; *) ac_count=0 - $as_echo_n 0123456789 >"conftest.in" + printf %s 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" - $as_echo '' >> "conftest.nl" + printf "%s\n" '' >> "conftest.nl" "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val @@ -5163,16 +5875,17 @@ else fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 -$as_echo "$ac_cv_path_SED" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 +printf "%s\n" "$ac_cv_path_SED" >&6; } SED="$ac_cv_path_SED" rm -f conftest.sed -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 -$as_echo_n "checking for egrep... " >&6; } -if ${ac_cv_path_EGREP+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +printf %s "checking for egrep... " >&6; } +if test ${ac_cv_path_EGREP+y} +then : + printf %s "(cached) " >&6 +else $as_nop if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else @@ -5183,10 +5896,15 @@ else for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in egrep; do + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_prog in egrep + do for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + ac_path_EGREP="$as_dir$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_EGREP" || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP @@ -5195,13 +5913,13 @@ case `"$ac_path_EGREP" --version 2>&1` in ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 - $as_echo_n 0123456789 >"conftest.in" + printf %s 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" - $as_echo 'EGREP' >> "conftest.nl" + printf "%s\n" 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val @@ -5230,17 +5948,18 @@ fi fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 -$as_echo "$ac_cv_path_EGREP" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +printf "%s\n" "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for CC compiler name" >&5 -$as_echo_n "checking for CC compiler name... " >&6; } -if ${ac_cv_cc_name+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for CC compiler name" >&5 +printf %s "checking for CC compiler name... " >&6; } +if test ${ac_cv_cc_name+y} +then : + printf %s "(cached) " >&6 +else $as_nop cat > conftest.c <&5 -$as_echo "$ac_cv_cc_name" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cc_name" >&5 +printf "%s\n" "$ac_cv_cc_name" >&6; } # checks for UNIX variants that set C preprocessor variables # may set _GNU_SOURCE, __EXTENSIONS__, _POSIX_PTHREAD_SEMANTICS, # _POSIX_SOURCE, _POSIX_1_SOURCE, and more +ac_header= ac_cache= +for ac_item in $ac_header_c_list +do + if test $ac_cache; then + ac_fn_c_check_header_compile "$LINENO" $ac_header ac_cv_header_$ac_cache "$ac_includes_default" + if eval test \"x\$ac_cv_header_$ac_cache\" = xyes; then + printf "%s\n" "#define $ac_item 1" >> confdefs.h + fi + ac_header= ac_cache= + elif test $ac_header; then + ac_cache=$ac_item + else + ac_header=$ac_item + fi +done -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 -$as_echo_n "checking for ANSI C header files... " >&6; } -if ${ac_cv_header_stdc+:} false; then : - $as_echo_n "(cached) " >&6 -else + + + + + + + +if test $ac_cv_header_stdlib_h = yes && test $ac_cv_header_string_h = yes +then : + +printf "%s\n" "#define STDC_HEADERS 1" >>confdefs.h + +fi + + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether it is safe to define __EXTENSIONS__" >&5 +printf %s "checking whether it is safe to define __EXTENSIONS__... " >&6; } +if test ${ac_cv_safe_to_define___extensions__+y} +then : + printf %s "(cached) " >&6 +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include -#include -#include -#include +# define __EXTENSIONS__ 1 + $ac_includes_default int -main () +main (void) { ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_header_stdc=yes -else - ac_cv_header_stdc=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - -if test $ac_cv_header_stdc = yes; then - # SunOS 4.x string.h does not declare mem*, contrary to ANSI. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "memchr" >/dev/null 2>&1; then : - -else - ac_cv_header_stdc=no +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_safe_to_define___extensions__=yes +else $as_nop + ac_cv_safe_to_define___extensions__=no fi -rm -f conftest* - +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_safe_to_define___extensions__" >&5 +printf "%s\n" "$ac_cv_safe_to_define___extensions__" >&6; } -if test $ac_cv_header_stdc = yes; then - # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether _XOPEN_SOURCE should be defined" >&5 +printf %s "checking whether _XOPEN_SOURCE should be defined... " >&6; } +if test ${ac_cv_should_define__xopen_source+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_cv_should_define__xopen_source=no + if test $ac_cv_header_wchar_h = yes +then : cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "free" >/dev/null 2>&1; then : -else - ac_cv_header_stdc=no -fi -rm -f conftest* + #include + mbstate_t x; +int +main (void) +{ -fi + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : -if test $ac_cv_header_stdc = yes; then - # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. - if test "$cross_compiling" = yes; then : - : -else +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include -#include -#if ((' ' & 0x0FF) == 0x020) -# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') -# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) -#else -# define ISLOWER(c) \ - (('a' <= (c) && (c) <= 'i') \ - || ('j' <= (c) && (c) <= 'r') \ - || ('s' <= (c) && (c) <= 'z')) -# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) -#endif -#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) + #define _XOPEN_SOURCE 500 + #include + mbstate_t x; int -main () +main (void) { - int i; - for (i = 0; i < 256; i++) - if (XOR (islower (i), ISLOWER (i)) - || toupper (i) != TOUPPER (i)) - return 2; + + ; return 0; } _ACEOF -if ac_fn_c_try_run "$LINENO"; then : - -else - ac_cv_header_stdc=no +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_should_define__xopen_source=yes fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi - +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 -$as_echo "$ac_cv_header_stdc" >&6; } -if test $ac_cv_header_stdc = yes; then - -$as_echo "#define STDC_HEADERS 1" >>confdefs.h +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_should_define__xopen_source" >&5 +printf "%s\n" "$ac_cv_should_define__xopen_source" >&6; } -fi + printf "%s\n" "#define _ALL_SOURCE 1" >>confdefs.h -# On IRIX 5.3, sys/types and inttypes.h are conflicting. -for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ - inttypes.h stdint.h unistd.h -do : - as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default -" -if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF + printf "%s\n" "#define _DARWIN_C_SOURCE 1" >>confdefs.h -fi + printf "%s\n" "#define _GNU_SOURCE 1" >>confdefs.h -done + printf "%s\n" "#define _HPUX_ALT_XOPEN_SOCKET_API 1" >>confdefs.h + printf "%s\n" "#define _NETBSD_SOURCE 1" >>confdefs.h + printf "%s\n" "#define _OPENBSD_SOURCE 1" >>confdefs.h - ac_fn_c_check_header_mongrel "$LINENO" "minix/config.h" "ac_cv_header_minix_config_h" "$ac_includes_default" -if test "x$ac_cv_header_minix_config_h" = xyes; then : - MINIX=yes -else - MINIX= -fi + printf "%s\n" "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h + printf "%s\n" "#define __STDC_WANT_IEC_60559_ATTRIBS_EXT__ 1" >>confdefs.h - if test "$MINIX" = yes; then + printf "%s\n" "#define __STDC_WANT_IEC_60559_BFP_EXT__ 1" >>confdefs.h -$as_echo "#define _POSIX_SOURCE 1" >>confdefs.h + printf "%s\n" "#define __STDC_WANT_IEC_60559_DFP_EXT__ 1" >>confdefs.h + printf "%s\n" "#define __STDC_WANT_IEC_60559_FUNCS_EXT__ 1" >>confdefs.h -$as_echo "#define _POSIX_1_SOURCE 2" >>confdefs.h + printf "%s\n" "#define __STDC_WANT_IEC_60559_TYPES_EXT__ 1" >>confdefs.h + printf "%s\n" "#define __STDC_WANT_LIB_EXT2__ 1" >>confdefs.h -$as_echo "#define _MINIX 1" >>confdefs.h + printf "%s\n" "#define __STDC_WANT_MATH_SPEC_FUNCS__ 1" >>confdefs.h - fi + printf "%s\n" "#define _TANDEM_SOURCE 1" >>confdefs.h + if test $ac_cv_header_minix_config_h = yes +then : + MINIX=yes + printf "%s\n" "#define _MINIX 1" >>confdefs.h - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether it is safe to define __EXTENSIONS__" >&5 -$as_echo_n "checking whether it is safe to define __EXTENSIONS__... " >&6; } -if ${ac_cv_safe_to_define___extensions__+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ + printf "%s\n" "#define _POSIX_SOURCE 1" >>confdefs.h -# define __EXTENSIONS__ 1 - $ac_includes_default -int -main () -{ + printf "%s\n" "#define _POSIX_1_SOURCE 2" >>confdefs.h - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_safe_to_define___extensions__=yes -else - ac_cv_safe_to_define___extensions__=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +else $as_nop + MINIX= fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_safe_to_define___extensions__" >&5 -$as_echo "$ac_cv_safe_to_define___extensions__" >&6; } - test $ac_cv_safe_to_define___extensions__ = yes && - $as_echo "#define __EXTENSIONS__ 1" >>confdefs.h - - $as_echo "#define _ALL_SOURCE 1" >>confdefs.h - - $as_echo "#define _GNU_SOURCE 1" >>confdefs.h - - $as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h - - $as_echo "#define _TANDEM_SOURCE 1" >>confdefs.h - + if test $ac_cv_safe_to_define___extensions__ = yes +then : + printf "%s\n" "#define __EXTENSIONS__ 1" >>confdefs.h +fi + if test $ac_cv_should_define__xopen_source = yes +then : + printf "%s\n" "#define _XOPEN_SOURCE 500" >>confdefs.h +fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-cxx-main=" >&5 -$as_echo_n "checking for --with-cxx-main=... " >&6; } - -# Check whether --with-cxx_main was given. -if test "${with_cxx_main+set}" = set; then : - withval=$with_cxx_main; - - case $withval in - no) with_cxx_main=no - MAINCC='$(CC)';; - yes) with_cxx_main=yes - MAINCC='$(CXX)';; - *) with_cxx_main=yes - MAINCC=$withval - if test -z "$CXX" - then - CXX=$withval - fi;; - esac -else - - with_cxx_main=no - MAINCC='$(CC)' - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_cxx_main" >&5 -$as_echo "$with_cxx_main" >&6; } preset_cxx="$CXX" if test -z "$CXX" @@ -5503,11 +6172,12 @@ then gcc) if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}g++", so it can be a program name with args. set dummy ${ac_tool_prefix}g++; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_CXX+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_CXX+y} +then : + printf %s "(cached) " >&6 +else $as_nop case $CXX in [\\/]* | ?:[\\/]*) ac_cv_path_CXX="$CXX" # Let the user override the test with a path. @@ -5517,11 +6187,15 @@ else for as_dir in notfound do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_CXX="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_CXX="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -5533,11 +6207,11 @@ esac fi CXX=$ac_cv_path_CXX if test -n "$CXX"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 -$as_echo "$CXX" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 +printf "%s\n" "$CXX" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -5546,11 +6220,12 @@ if test -z "$ac_cv_path_CXX"; then ac_pt_CXX=$CXX # Extract the first word of "g++", so it can be a program name with args. set dummy g++; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_ac_pt_CXX+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_ac_pt_CXX+y} +then : + printf %s "(cached) " >&6 +else $as_nop case $ac_pt_CXX in [\\/]* | ?:[\\/]*) ac_cv_path_ac_pt_CXX="$ac_pt_CXX" # Let the user override the test with a path. @@ -5560,11 +6235,15 @@ else for as_dir in notfound do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_ac_pt_CXX="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_ac_pt_CXX="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -5576,11 +6255,11 @@ esac fi ac_pt_CXX=$ac_cv_path_ac_pt_CXX if test -n "$ac_pt_CXX"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_CXX" >&5 -$as_echo "$ac_pt_CXX" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_pt_CXX" >&5 +printf "%s\n" "$ac_pt_CXX" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi if test "x$ac_pt_CXX" = x; then @@ -5588,8 +6267,8 @@ fi else case $cross_compiling:$ac_tool_warned in yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CXX=$ac_pt_CXX @@ -5601,11 +6280,12 @@ fi cc) if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}c++", so it can be a program name with args. set dummy ${ac_tool_prefix}c++; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_CXX+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_CXX+y} +then : + printf %s "(cached) " >&6 +else $as_nop case $CXX in [\\/]* | ?:[\\/]*) ac_cv_path_CXX="$CXX" # Let the user override the test with a path. @@ -5615,11 +6295,15 @@ else for as_dir in notfound do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_CXX="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_CXX="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -5631,11 +6315,11 @@ esac fi CXX=$ac_cv_path_CXX if test -n "$CXX"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 -$as_echo "$CXX" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 +printf "%s\n" "$CXX" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -5644,11 +6328,12 @@ if test -z "$ac_cv_path_CXX"; then ac_pt_CXX=$CXX # Extract the first word of "c++", so it can be a program name with args. set dummy c++; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_ac_pt_CXX+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_ac_pt_CXX+y} +then : + printf %s "(cached) " >&6 +else $as_nop case $ac_pt_CXX in [\\/]* | ?:[\\/]*) ac_cv_path_ac_pt_CXX="$ac_pt_CXX" # Let the user override the test with a path. @@ -5658,11 +6343,15 @@ else for as_dir in notfound do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_ac_pt_CXX="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_ac_pt_CXX="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -5674,11 +6363,11 @@ esac fi ac_pt_CXX=$ac_cv_path_ac_pt_CXX if test -n "$ac_pt_CXX"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_CXX" >&5 -$as_echo "$ac_pt_CXX" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_pt_CXX" >&5 +printf "%s\n" "$ac_pt_CXX" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi if test "x$ac_pt_CXX" = x; then @@ -5686,8 +6375,8 @@ fi else case $cross_compiling:$ac_tool_warned in yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CXX=$ac_pt_CXX @@ -5699,11 +6388,12 @@ fi clang|*/clang) if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}clang++", so it can be a program name with args. set dummy ${ac_tool_prefix}clang++; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_CXX+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_CXX+y} +then : + printf %s "(cached) " >&6 +else $as_nop case $CXX in [\\/]* | ?:[\\/]*) ac_cv_path_CXX="$CXX" # Let the user override the test with a path. @@ -5713,11 +6403,15 @@ else for as_dir in notfound do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_CXX="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_CXX="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -5729,11 +6423,11 @@ esac fi CXX=$ac_cv_path_CXX if test -n "$CXX"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 -$as_echo "$CXX" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 +printf "%s\n" "$CXX" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -5742,11 +6436,12 @@ if test -z "$ac_cv_path_CXX"; then ac_pt_CXX=$CXX # Extract the first word of "clang++", so it can be a program name with args. set dummy clang++; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_ac_pt_CXX+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_ac_pt_CXX+y} +then : + printf %s "(cached) " >&6 +else $as_nop case $ac_pt_CXX in [\\/]* | ?:[\\/]*) ac_cv_path_ac_pt_CXX="$ac_pt_CXX" # Let the user override the test with a path. @@ -5756,11 +6451,15 @@ else for as_dir in notfound do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_ac_pt_CXX="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_ac_pt_CXX="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -5772,11 +6471,11 @@ esac fi ac_pt_CXX=$ac_cv_path_ac_pt_CXX if test -n "$ac_pt_CXX"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_CXX" >&5 -$as_echo "$ac_pt_CXX" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_pt_CXX" >&5 +printf "%s\n" "$ac_pt_CXX" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi if test "x$ac_pt_CXX" = x; then @@ -5784,8 +6483,8 @@ fi else case $cross_compiling:$ac_tool_warned in yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CXX=$ac_pt_CXX @@ -5797,11 +6496,12 @@ fi icc|*/icc) if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}icpc", so it can be a program name with args. set dummy ${ac_tool_prefix}icpc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_CXX+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_CXX+y} +then : + printf %s "(cached) " >&6 +else $as_nop case $CXX in [\\/]* | ?:[\\/]*) ac_cv_path_CXX="$CXX" # Let the user override the test with a path. @@ -5811,11 +6511,15 @@ else for as_dir in notfound do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_CXX="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_CXX="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -5827,11 +6531,11 @@ esac fi CXX=$ac_cv_path_CXX if test -n "$CXX"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 -$as_echo "$CXX" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 +printf "%s\n" "$CXX" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -5840,11 +6544,12 @@ if test -z "$ac_cv_path_CXX"; then ac_pt_CXX=$CXX # Extract the first word of "icpc", so it can be a program name with args. set dummy icpc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_ac_pt_CXX+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_ac_pt_CXX+y} +then : + printf %s "(cached) " >&6 +else $as_nop case $ac_pt_CXX in [\\/]* | ?:[\\/]*) ac_cv_path_ac_pt_CXX="$ac_pt_CXX" # Let the user override the test with a path. @@ -5854,11 +6559,15 @@ else for as_dir in notfound do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_ac_pt_CXX="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_ac_pt_CXX="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -5870,11 +6579,11 @@ esac fi ac_pt_CXX=$ac_cv_path_ac_pt_CXX if test -n "$ac_pt_CXX"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_CXX" >&5 -$as_echo "$ac_pt_CXX" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_pt_CXX" >&5 +printf "%s\n" "$ac_pt_CXX" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi if test "x$ac_pt_CXX" = x; then @@ -5882,8 +6591,8 @@ fi else case $cross_compiling:$ac_tool_warned in yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CXX=$ac_pt_CXX @@ -5905,11 +6614,12 @@ then do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CXX+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_CXX+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$CXX"; then ac_cv_prog_CXX="$CXX" # Let the user override the test. else @@ -5917,11 +6627,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -5932,11 +6646,11 @@ fi fi CXX=$ac_cv_prog_CXX if test -n "$CXX"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 -$as_echo "$CXX" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 +printf "%s\n" "$CXX" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -5949,11 +6663,12 @@ if test -z "$CXX"; then do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_CXX+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_CXX+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$ac_ct_CXX"; then ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. else @@ -5961,11 +6676,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CXX="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -5976,11 +6695,11 @@ fi fi ac_ct_CXX=$ac_cv_prog_ac_ct_CXX if test -n "$ac_ct_CXX"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 -$as_echo "$ac_ct_CXX" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 +printf "%s\n" "$ac_ct_CXX" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -5992,8 +6711,8 @@ done else case $cross_compiling:$ac_tool_warned in yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CXX=$ac_ct_CXX @@ -6007,12 +6726,12 @@ fi fi if test "$preset_cxx" != "$CXX" then - { $as_echo "$as_me:${as_lineno-$LINENO}: + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: By default, distutils will build C++ extension modules with \"$CXX\". If this is not intended, then set CXX on the configure command line. " >&5 -$as_echo "$as_me: +printf "%s\n" "$as_me: By default, distutils will build C++ extension modules with \"$CXX\". If this is not intended, then set CXX on the configure command line. @@ -6020,8 +6739,8 @@ $as_echo "$as_me: fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for the platform triplet based on compiler characteristics" >&5 -$as_echo_n "checking for the platform triplet based on compiler characteristics... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for the platform triplet based on compiler characteristics" >&5 +printf %s "checking for the platform triplet based on compiler characteristics... " >&6; } cat > conftest.c < conftest.c <=6) && defined(_MIPSEL) @@ -6166,7 +6899,11 @@ cat > conftest.c <conftest.out 2>/dev/null; then PLATFORM_TRIPLET=`echo "$PLATFORM_TRIPLET" | sed 's/linux-gnu/linux-musl/'` ;; esac - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PLATFORM_TRIPLET" >&5 -$as_echo "$PLATFORM_TRIPLET" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PLATFORM_TRIPLET" >&5 +printf "%s\n" "$PLATFORM_TRIPLET" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 -$as_echo "none" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none" >&5 +printf "%s\n" "none" >&6; } fi rm -f conftest.c conftest.out -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for multiarch" >&5 -$as_echo_n "checking for multiarch... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for multiarch" >&5 +printf %s "checking for multiarch... " >&6; } case $ac_sys_system in #( Darwin*) : MULTIARCH="" ;; #( @@ -6211,8 +6948,8 @@ case $ac_sys_system in #( ;; esac -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MULTIARCH" >&5 -$as_echo "$MULTIARCH" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MULTIARCH" >&5 +printf "%s\n" "$MULTIARCH" >&6; } if test x$PLATFORM_TRIPLET != x && test x$MULTIARCH != x; then if test x$PLATFORM_TRIPLET != x$MULTIARCH; then @@ -6228,8 +6965,8 @@ if test x$MULTIARCH != x; then fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for PEP 11 support tier" >&5 -$as_echo_n "checking for PEP 11 support tier... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for PEP 11 support tier" >&5 +printf %s "checking for PEP 11 support tier... " >&6; } case $host/$ac_cv_cc_name in #( x86_64-*-linux-gnu/gcc) : PY_SUPPORT_TIER=1 ;; #( @@ -6272,63 +7009,63 @@ esac case $PY_SUPPORT_TIER in #( 1) : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $host/$ac_cv_cc_name has tier 1 (supported)" >&5 -$as_echo "$host/$ac_cv_cc_name has tier 1 (supported)" >&6; } ;; #( + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $host/$ac_cv_cc_name has tier 1 (supported)" >&5 +printf "%s\n" "$host/$ac_cv_cc_name has tier 1 (supported)" >&6; } ;; #( 2) : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $host/$ac_cv_cc_name has tier 2 (supported)" >&5 -$as_echo "$host/$ac_cv_cc_name has tier 2 (supported)" >&6; } ;; #( + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $host/$ac_cv_cc_name has tier 2 (supported)" >&5 +printf "%s\n" "$host/$ac_cv_cc_name has tier 2 (supported)" >&6; } ;; #( 3) : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $host/$ac_cv_cc_name has tier 3 (partially supported)" >&5 -$as_echo "$host/$ac_cv_cc_name has tier 3 (partially supported)" >&6; } ;; #( + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $host/$ac_cv_cc_name has tier 3 (partially supported)" >&5 +printf "%s\n" "$host/$ac_cv_cc_name has tier 3 (partially supported)" >&6; } ;; #( *) : - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $host/$ac_cv_cc_name is not supported" >&5 -$as_echo "$as_me: WARNING: $host/$ac_cv_cc_name is not supported" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $host/$ac_cv_cc_name is not supported" >&5 +printf "%s\n" "$as_me: WARNING: $host/$ac_cv_cc_name is not supported" >&2;} ;; esac -cat >>confdefs.h <<_ACEOF -#define PY_SUPPORT_TIER $PY_SUPPORT_TIER -_ACEOF +printf "%s\n" "#define PY_SUPPORT_TIER $PY_SUPPORT_TIER" >>confdefs.h -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for -Wl,--no-as-needed" >&5 -$as_echo_n "checking for -Wl,--no-as-needed... " >&6; } -if ${ac_cv_wl_no_as_needed+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -Wl,--no-as-needed" >&5 +printf %s "checking for -Wl,--no-as-needed... " >&6; } +if test ${ac_cv_wl_no_as_needed+y} +then : + printf %s "(cached) " >&6 +else $as_nop save_LDFLAGS="$LDFLAGS" - as_fn_append LDFLAGS -Wl,--no-as-needed + as_fn_append LDFLAGS " -Wl,--no-as-needed" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int -main () +main (void) { ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : NO_AS_NEEDED="-Wl,--no-as-needed" ac_cv_wl_no_as_needed=yes -else +else $as_nop NO_AS_NEEDED="" ac_cv_wl_no_as_needed=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LDFLAGS="$save_LDFLAGS" fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_wl_no_as_needed" >&5 -$as_echo "$ac_cv_wl_no_as_needed" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_wl_no_as_needed" >&5 +printf "%s\n" "$ac_cv_wl_no_as_needed" >&6; } -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for the Android API level" >&5 -$as_echo_n "checking for the Android API level... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for the Android API level" >&5 +printf %s "checking for the Android API level... " >&6; } cat > conftest.c <conftest.out 2>/dev/null; then ANDROID_API_LEVEL=`sed -n -e '/__ANDROID_API__/d' -e 's/^android_api = //p' conftest.out` _arm_arch=`sed -n -e '/__ARM_ARCH/d' -e 's/^arm_arch = //p' conftest.out` - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ANDROID_API_LEVEL" >&5 -$as_echo "$ANDROID_API_LEVEL" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ANDROID_API_LEVEL" >&5 +printf "%s\n" "$ANDROID_API_LEVEL" >&6; } if test -z "$ANDROID_API_LEVEL"; then as_fn_error $? "Fatal: you must define __ANDROID_API__" "$LINENO" 5 fi -cat >>confdefs.h <<_ACEOF -#define ANDROID_API_LEVEL $ANDROID_API_LEVEL -_ACEOF +printf "%s\n" "#define ANDROID_API_LEVEL $ANDROID_API_LEVEL" >>confdefs.h - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the Android arm ABI" >&5 -$as_echo_n "checking for the Android arm ABI... " >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_arm_arch" >&5 -$as_echo "$_arm_arch" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for the Android arm ABI" >&5 +printf %s "checking for the Android arm ABI... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $_arm_arch" >&5 +printf "%s\n" "$_arm_arch" >&6; } if test "$_arm_arch" = 7; then BASECFLAGS="${BASECFLAGS} -mfloat-abi=softfp -mfpu=vfpv3-d16" LDFLAGS="${LDFLAGS} -march=armv7-a -Wl,--fix-cortex-a8" fi else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: not Android" >&5 -$as_echo "not Android" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: not Android" >&5 +printf "%s\n" "not Android" >&6; } fi rm -f conftest.c conftest.out @@ -6377,13 +7112,15 @@ case $ac_sys_system/$ac_sys_release in #( ;; esac -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-emscripten-target" >&5 -$as_echo_n "checking for --with-emscripten-target... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-emscripten-target" >&5 +printf %s "checking for --with-emscripten-target... " >&6; } # Check whether --with-emscripten-target was given. -if test "${with_emscripten_target+set}" = set; then : +if test ${with_emscripten_target+y} +then : withval=$with_emscripten_target; - if test "x$ac_sys_system" = xEmscripten; then : + if test "x$ac_sys_system" = xEmscripten +then : case $with_emscripten_target in #( browser) : @@ -6399,27 +7136,29 @@ if test "${with_emscripten_target+set}" = set; then : ;; esac -else +else $as_nop as_fn_error $? "--with-emscripten-target only applies to Emscripten" "$LINENO" 5 fi -else +else $as_nop - if test "x$ac_sys_system" = xEmscripten; then : + if test "x$ac_sys_system" = xEmscripten +then : ac_sys_emscripten_target=browser fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_sys_emscripten_target" >&5 -$as_echo "$ac_sys_emscripten_target" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_sys_emscripten_target" >&5 +printf "%s\n" "$ac_sys_emscripten_target" >&6; } -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --enable-wasm-dynamic-linking" >&5 -$as_echo_n "checking for --enable-wasm-dynamic-linking... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --enable-wasm-dynamic-linking" >&5 +printf %s "checking for --enable-wasm-dynamic-linking... " >&6; } # Check whether --enable-wasm-dynamic-linking was given. -if test "${enable_wasm_dynamic_linking+set}" = set; then : +if test ${enable_wasm_dynamic_linking+y} +then : enableval=$enable_wasm_dynamic_linking; case $ac_sys_system in #( Emscripten) : @@ -6431,44 +7170,46 @@ if test "${enable_wasm_dynamic_linking+set}" = set; then : ;; esac -else +else $as_nop enable_wasm_dynamic_linking=missing fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_wasm_dynamic_linking" >&5 -$as_echo "$enable_wasm_dynamic_linking" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_wasm_dynamic_linking" >&5 +printf "%s\n" "$enable_wasm_dynamic_linking" >&6; } -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --enable-wasm-pthreads" >&5 -$as_echo_n "checking for --enable-wasm-pthreads... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --enable-wasm-pthreads" >&5 +printf %s "checking for --enable-wasm-pthreads... " >&6; } # Check whether --enable-wasm-pthreads was given. -if test "${enable_wasm_pthreads+set}" = set; then : +if test ${enable_wasm_pthreads+y} +then : enableval=$enable_wasm_pthreads; case $ac_sys_system in #( Emscripten) : ;; #( WASI) : - as_fn_error $? "WASI threading is not implemented yet." "$LINENO" 5 ;; #( + ;; #( *) : as_fn_error $? "--enable-wasm-pthreads only applies to Emscripten and WASI" "$LINENO" 5 ;; esac -else +else $as_nop enable_wasm_pthreads=missing fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_wasm_pthreads" >&5 -$as_echo "$enable_wasm_pthreads" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_wasm_pthreads" >&5 +printf "%s\n" "$enable_wasm_pthreads" >&6; } -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-suffix" >&5 -$as_echo_n "checking for --with-suffix... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-suffix" >&5 +printf %s "checking for --with-suffix... " >&6; } # Check whether --with-suffix was given. -if test "${with_suffix+set}" = set; then : +if test ${with_suffix+y} +then : withval=$with_suffix; case $with_suffix in #( no) : @@ -6480,7 +7221,7 @@ if test "${with_suffix+set}" = set; then : ;; esac -else +else $as_nop case $ac_sys_system/$ac_sys_emscripten_target in #( Emscripten/browser*) : @@ -6496,26 +7237,26 @@ esac fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $EXEEXT" >&5 -$as_echo "$EXEEXT" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $EXEEXT" >&5 +printf "%s\n" "$EXEEXT" >&6; } # Test whether we're running on a non-case-sensitive system, in which # case we give a warning if no ext is given -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for case-insensitive build directory" >&5 -$as_echo_n "checking for case-insensitive build directory... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for case-insensitive build directory" >&5 +printf %s "checking for case-insensitive build directory... " >&6; } if test ! -d CaseSensitiveTestDir; then mkdir CaseSensitiveTestDir fi if test -d casesensitivetestdir && test -z "$EXEEXT" then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } BUILDEXEEXT=.exe else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } BUILDEXEEXT=$EXEEXT fi rmdir CaseSensitiveTestDir @@ -6528,14 +7269,14 @@ hp*|HP*) esac -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking LIBRARY" >&5 -$as_echo_n "checking LIBRARY... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking LIBRARY" >&5 +printf %s "checking LIBRARY... " >&6; } if test -z "$LIBRARY" then LIBRARY='libpython$(VERSION)$(ABIFLAGS).a' fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBRARY" >&5 -$as_echo "$LIBRARY" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $LIBRARY" >&5 +printf "%s\n" "$LIBRARY" >&6; } # LDLIBRARY is the name of the library to link against (as opposed to the # name of the library into which to insert object files). BLDLIBRARY is also @@ -6574,11 +7315,11 @@ LDVERSION="$VERSION" # compiled with CXX, LINKCC is CXX instead. Always using CXX is undesirable: # python might then depend on the C++ runtime -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking LINKCC" >&5 -$as_echo_n "checking LINKCC... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking LINKCC" >&5 +printf %s "checking LINKCC... " >&6; } if test -z "$LINKCC" then - LINKCC='$(PURIFY) $(MAINCC)' + LINKCC='$(PURIFY) $(CC)' case $ac_sys_system in QNX*) # qcc must be used because the other compilers do not @@ -6586,8 +7327,8 @@ then LINKCC=qcc;; esac fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $LINKCC" >&5 -$as_echo "$LINKCC" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $LINKCC" >&5 +printf "%s\n" "$LINKCC" >&6; } # EXPORTSYMS holds the list of exported symbols for AIX. # EXPORTSFROM holds the module name exporting symbols on AIX. @@ -6595,16 +7336,16 @@ EXPORTSYMS= EXPORTSFROM= -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking EXPORTSYMS" >&5 -$as_echo_n "checking EXPORTSYMS... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking EXPORTSYMS" >&5 +printf %s "checking EXPORTSYMS... " >&6; } case $ac_sys_system in AIX*) EXPORTSYMS="Modules/python.exp" EXPORTSFROM=. # the main executable ;; esac -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $EXPORTSYMS" >&5 -$as_echo "$EXPORTSYMS" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $EXPORTSYMS" >&5 +printf "%s\n" "$EXPORTSYMS" >&6; } # GNULD is set to "yes" if the GNU linker is used. If this goes wrong # make sure we default having it set to "no": this is used by @@ -6612,8 +7353,8 @@ $as_echo "$EXPORTSYMS" >&6; } # to linker command lines, and failing to detect GNU ld simply results # in the same behaviour as before. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 -$as_echo_n "checking for GNU ld... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +printf %s "checking for GNU ld... " >&6; } ac_prog=ld if test "$GCC" = yes; then ac_prog=`$CC -print-prog-name=ld` @@ -6624,13 +7365,14 @@ case `"$ac_prog" -V 2>&1 < /dev/null` in *) GNULD=no;; esac -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $GNULD" >&5 -$as_echo "$GNULD" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $GNULD" >&5 +printf "%s\n" "$GNULD" >&6; } -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --enable-shared" >&5 -$as_echo_n "checking for --enable-shared... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --enable-shared" >&5 +printf %s "checking for --enable-shared... " >&6; } # Check whether --enable-shared was given. -if test "${enable_shared+set}" = set; then : +if test ${enable_shared+y} +then : enableval=$enable_shared; fi @@ -6644,37 +7386,39 @@ then enable_shared="no";; esac fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 -$as_echo "$enable_shared" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 +printf "%s\n" "$enable_shared" >&6; } # --with-static-libpython STATIC_LIBPYTHON=1 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-static-libpython" >&5 -$as_echo_n "checking for --with-static-libpython... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-static-libpython" >&5 +printf %s "checking for --with-static-libpython... " >&6; } # Check whether --with-static-libpython was given. -if test "${with_static_libpython+set}" = set; then : +if test ${with_static_libpython+y} +then : withval=$with_static_libpython; if test "$withval" = no then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; }; + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; }; STATIC_LIBPYTHON=0 else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; }; + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; }; fi -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --enable-profiling" >&5 -$as_echo_n "checking for --enable-profiling... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --enable-profiling" >&5 +printf %s "checking for --enable-profiling... " >&6; } # Check whether --enable-profiling was given. -if test "${enable_profiling+set}" = set; then : +if test ${enable_profiling+y} +then : enableval=$enable_profiling; fi @@ -6685,27 +7429,28 @@ if test "x$enable_profiling" = xyes; then /* end confdefs.h. */ int main(void) { return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : -else +else $as_nop enable_profiling=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext CC="$ac_save_cc" else enable_profiling=no fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_profiling" >&5 -$as_echo "$enable_profiling" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_profiling" >&5 +printf "%s\n" "$enable_profiling" >&6; } if test "x$enable_profiling" = xyes; then BASECFLAGS="-pg $BASECFLAGS" LDFLAGS="-pg $LDFLAGS" fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking LDLIBRARY" >&5 -$as_echo_n "checking LDLIBRARY... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking LDLIBRARY" >&5 +printf %s "checking LDLIBRARY... " >&6; } # MacOSX framework builds need more magic. LDLIBRARY is the dynamic # library that we build, but we do not want to link against it (we @@ -6726,7 +7471,7 @@ fi if test $enable_shared = "yes"; then PY_ENABLE_SHARED=1 -$as_echo "#define Py_ENABLE_SHARED 1" >>confdefs.h +printf "%s\n" "#define Py_ENABLE_SHARED 1" >>confdefs.h case $ac_sys_system in CYGWIN*) @@ -6799,11 +7544,12 @@ then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}node", so it can be a program name with args. set dummy ${ac_tool_prefix}node; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_NODE+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_NODE+y} +then : + printf %s "(cached) " >&6 +else $as_nop case $NODE in [\\/]* | ?:[\\/]*) ac_cv_path_NODE="$NODE" # Let the user override the test with a path. @@ -6813,11 +7559,15 @@ else for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_NODE="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_NODE="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -6829,11 +7579,11 @@ esac fi NODE=$ac_cv_path_NODE if test -n "$NODE"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NODE" >&5 -$as_echo "$NODE" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $NODE" >&5 +printf "%s\n" "$NODE" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -6842,11 +7592,12 @@ if test -z "$ac_cv_path_NODE"; then ac_pt_NODE=$NODE # Extract the first word of "node", so it can be a program name with args. set dummy node; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_ac_pt_NODE+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_ac_pt_NODE+y} +then : + printf %s "(cached) " >&6 +else $as_nop case $ac_pt_NODE in [\\/]* | ?:[\\/]*) ac_cv_path_ac_pt_NODE="$ac_pt_NODE" # Let the user override the test with a path. @@ -6856,11 +7607,15 @@ else for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_ac_pt_NODE="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_ac_pt_NODE="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -6872,11 +7627,11 @@ esac fi ac_pt_NODE=$ac_cv_path_ac_pt_NODE if test -n "$ac_pt_NODE"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_NODE" >&5 -$as_echo "$ac_pt_NODE" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_pt_NODE" >&5 +printf "%s\n" "$ac_pt_NODE" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi if test "x$ac_pt_NODE" = x; then @@ -6884,8 +7639,8 @@ fi else case $cross_compiling:$ac_tool_warned in yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac NODE=$ac_pt_NODE @@ -6897,11 +7652,12 @@ fi HOSTRUNNER="$NODE" # bigint for ctypes c_longlong, c_longdouble # no longer available in Node 16 - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for node --experimental-wasm-bigint" >&5 -$as_echo_n "checking for node --experimental-wasm-bigint... " >&6; } -if ${ac_cv_tool_node_wasm_bigint+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for node --experimental-wasm-bigint" >&5 +printf %s "checking for node --experimental-wasm-bigint... " >&6; } +if test ${ac_cv_tool_node_wasm_bigint+y} +then : + printf %s "(cached) " >&6 +else $as_nop if $NODE -v --experimental-wasm-bigint > /dev/null 2>&1; then ac_cv_tool_node_wasm_bigint=yes @@ -6910,23 +7666,26 @@ else fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_tool_node_wasm_bigint" >&5 -$as_echo "$ac_cv_tool_node_wasm_bigint" >&6; } - if test "x$ac_cv_tool_node_wasm_bigint" = xyes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_tool_node_wasm_bigint" >&5 +printf "%s\n" "$ac_cv_tool_node_wasm_bigint" >&6; } + if test "x$ac_cv_tool_node_wasm_bigint" = xyes +then : as_fn_append HOSTRUNNER " --experimental-wasm-bigint" fi - if test "x$enable_wasm_pthreads" = xyes; then : + if test "x$enable_wasm_pthreads" = xyes +then : as_fn_append HOSTRUNNER " --experimental-wasm-threads" # no longer available in Node 16 - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for node --experimental-wasm-bulk-memory" >&5 -$as_echo_n "checking for node --experimental-wasm-bulk-memory... " >&6; } -if ${ac_cv_tool_node_wasm_bulk_memory+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for node --experimental-wasm-bulk-memory" >&5 +printf %s "checking for node --experimental-wasm-bulk-memory... " >&6; } +if test ${ac_cv_tool_node_wasm_bulk_memory+y} +then : + printf %s "(cached) " >&6 +else $as_nop if $NODE -v --experimental-wasm-bulk-memory > /dev/null 2>&1; then ac_cv_tool_node_wasm_bulk_memory=yes @@ -6935,9 +7694,10 @@ else fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_tool_node_wasm_bulk_memory" >&5 -$as_echo "$ac_cv_tool_node_wasm_bulk_memory" >&6; } - if test "x$ac_cv_tool_node_wasm_bulk_memory" = xyes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_tool_node_wasm_bulk_memory" >&5 +printf "%s\n" "$ac_cv_tool_node_wasm_bulk_memory" >&6; } + if test "x$ac_cv_tool_node_wasm_bulk_memory" = xyes +then : as_fn_append HOSTRUNNER " --experimental-wasm-bulk-memory" @@ -6945,29 +7705,30 @@ fi fi - if test "x$host_cpu" = xwasm64; then : + if test "x$host_cpu" = xwasm64 +then : as_fn_append HOSTRUNNER " --experimental-wasm-memory64" fi ;; #( WASI/*) : - HOSTRUNNER='wasmtime run --env PYTHONPATH=/$(shell realpath --relative-to $(abs_srcdir) $(abs_builddir))/$(shell cat pybuilddir.txt) --mapdir /::$(srcdir) --' ;; #( + HOSTRUNNER='wasmtime run --env PYTHONPATH=/$(shell realpath --relative-to $(abs_srcdir) $(abs_builddir))/$(shell cat pybuilddir.txt):/Lib --mapdir /::$(srcdir) --' ;; #( *) : HOSTRUNNER='' ;; esac fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking HOSTRUNNER" >&5 -$as_echo_n "checking HOSTRUNNER... " >&6; } -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $HOSTRUNNER" >&5 -$as_echo "$HOSTRUNNER" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking HOSTRUNNER" >&5 +printf %s "checking HOSTRUNNER... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $HOSTRUNNER" >&5 +printf "%s\n" "$HOSTRUNNER" >&6; } if test -n "$HOSTRUNNER"; then PYTHON_FOR_BUILD="_PYTHON_HOSTRUNNER='$HOSTRUNNER' $PYTHON_FOR_BUILD" fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $LDLIBRARY" >&5 -$as_echo "$LDLIBRARY" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $LDLIBRARY" >&5 +printf "%s\n" "$LDLIBRARY" >&6; } # LIBRARY_DEPS, LINK_PYTHON_OBJS and LINK_PYTHON_DEPS variable case $ac_sys_system/$ac_sys_emscripten_target in #( @@ -7006,11 +7767,12 @@ if test -n "$ac_tool_prefix"; then do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_AR+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_AR+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$AR"; then ac_cv_prog_AR="$AR" # Let the user override the test. else @@ -7018,11 +7780,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_AR="$ac_tool_prefix$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -7033,11 +7799,11 @@ fi fi AR=$ac_cv_prog_AR if test -n "$AR"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 -$as_echo "$AR" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +printf "%s\n" "$AR" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -7050,11 +7816,12 @@ if test -z "$AR"; then do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_AR+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_AR+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$ac_ct_AR"; then ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. else @@ -7062,11 +7829,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_AR="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -7077,11 +7848,11 @@ fi fi ac_ct_AR=$ac_cv_prog_ac_ct_AR if test -n "$ac_ct_AR"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 -$as_echo "$ac_ct_AR" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 +printf "%s\n" "$ac_ct_AR" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -7093,8 +7864,8 @@ done else case $cross_compiling:$ac_tool_warned in yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac AR=$ac_ct_AR @@ -7109,116 +7880,6 @@ then ARFLAGS="rcs" fi -if test -n "$ac_tool_prefix"; then - for ac_prog in readelf - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_READELF+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$READELF"; then - ac_cv_prog_READELF="$READELF" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_READELF="$ac_tool_prefix$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -READELF=$ac_cv_prog_READELF -if test -n "$READELF"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $READELF" >&5 -$as_echo "$READELF" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$READELF" && break - done -fi -if test -z "$READELF"; then - ac_ct_READELF=$READELF - for ac_prog in readelf -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_READELF+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_READELF"; then - ac_cv_prog_ac_ct_READELF="$ac_ct_READELF" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_READELF="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_READELF=$ac_cv_prog_ac_ct_READELF -if test -n "$ac_ct_READELF"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_READELF" >&5 -$as_echo "$ac_ct_READELF" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$ac_ct_READELF" && break -done - - if test "x$ac_ct_READELF" = x; then - READELF=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - READELF=$ac_ct_READELF - fi -fi - -if test "$cross_compiling" = yes; then - case "$READELF" in - readelf|:) - as_fn_error $? "readelf for the host is required for cross builds" "$LINENO" 5 - ;; - esac -fi - - - case $MACHDEP in hp*|HP*) # install -d does not work on HP-UX @@ -7227,7 +7888,8 @@ hp*|HP*) INSTALL="${srcdir}/install-sh -c" fi esac -# Find a good install program. We prefer a C program (faster), + + # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install @@ -7241,20 +7903,25 @@ esac # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. # Reject install programs that cannot install multiple files. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 -$as_echo_n "checking for a BSD-compatible install... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +printf %s "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then -if ${ac_cv_path_install+:} false; then : - $as_echo_n "(cached) " >&6 -else +if test ${ac_cv_path_install+y} +then : + printf %s "(cached) " >&6 +else $as_nop as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - # Account for people who put trailing slashes in PATH elements. -case $as_dir/ in #(( - ./ | .// | /[cC]/* | \ + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + # Account for fact that we put trailing slashes in our PATH walk. +case $as_dir in #(( + ./ | /[cC]/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ /usr/ucb/* ) ;; @@ -7264,13 +7931,13 @@ case $as_dir/ in #(( # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_prog$ac_exec_ext"; then if test $ac_prog = install && - grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + grep dspmsg "$as_dir$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && - grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + grep pwplus "$as_dir$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else @@ -7278,12 +7945,12 @@ case $as_dir/ in #(( echo one > conftest.one echo two > conftest.two mkdir conftest.dir - if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && + if "$as_dir$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir/" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then - ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + ac_cv_path_install="$as_dir$ac_prog$ac_exec_ext -c" break 3 fi fi @@ -7299,7 +7966,7 @@ IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir fi - if test "${ac_cv_path_install+set}" = set; then + if test ${ac_cv_path_install+y}; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a @@ -7309,8 +7976,8 @@ fi INSTALL=$ac_install_sh fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 -$as_echo "$INSTALL" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +printf "%s\n" "$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. @@ -7320,25 +7987,31 @@ test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 -$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a race-free mkdir -p" >&5 +printf %s "checking for a race-free mkdir -p... " >&6; } if test -z "$MKDIR_P"; then - if ${ac_cv_path_mkdir+:} false; then : - $as_echo_n "(cached) " >&6 -else + if test ${ac_cv_path_mkdir+y} +then : + printf %s "(cached) " >&6 +else $as_nop as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_prog in mkdir gmkdir; do for ac_exec_ext in '' $ac_executable_extensions; do - as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue - case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( - 'mkdir (GNU coreutils) '* | \ - 'mkdir (coreutils) '* | \ + as_fn_executable_p "$as_dir$ac_prog$ac_exec_ext" || continue + case `"$as_dir$ac_prog$ac_exec_ext" --version 2>&1` in #( + 'mkdir ('*'coreutils) '* | \ + 'BusyBox '* | \ 'mkdir (fileutils) '4.1*) - ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext + ac_cv_path_mkdir=$as_dir$ac_prog$ac_exec_ext break 3;; esac done @@ -7349,7 +8022,7 @@ IFS=$as_save_IFS fi test -d ./--version && rmdir ./--version - if test "${ac_cv_path_mkdir+set}" = set; then + if test ${ac_cv_path_mkdir+y}; then MKDIR_P="$ac_cv_path_mkdir -p" else # As a last resort, use the slow shell script. Don't cache a @@ -7359,8 +8032,8 @@ fi MKDIR_P="$ac_install_sh -d" fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 -$as_echo "$MKDIR_P" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 +printf "%s\n" "$MKDIR_P" >&6; } # Not every filesystem supports hard links @@ -7377,71 +8050,76 @@ fi ABIFLAGS="" # Check for --with-pydebug -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-pydebug" >&5 -$as_echo_n "checking for --with-pydebug... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-pydebug" >&5 +printf %s "checking for --with-pydebug... " >&6; } # Check whether --with-pydebug was given. -if test "${with_pydebug+set}" = set; then : +if test ${with_pydebug+y} +then : withval=$with_pydebug; if test "$withval" != no then -$as_echo "#define Py_DEBUG 1" >>confdefs.h +printf "%s\n" "#define Py_DEBUG 1" >>confdefs.h - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; }; + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; }; Py_DEBUG='true' ABIFLAGS="${ABIFLAGS}d" -else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; }; Py_DEBUG='false' +else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; }; Py_DEBUG='false' fi -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi # Check for --with-trace-refs # --with-trace-refs -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-trace-refs" >&5 -$as_echo_n "checking for --with-trace-refs... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-trace-refs" >&5 +printf %s "checking for --with-trace-refs... " >&6; } # Check whether --with-trace-refs was given. -if test "${with_trace_refs+set}" = set; then : +if test ${with_trace_refs+y} +then : withval=$with_trace_refs; -else +else $as_nop with_trace_refs=no + fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_trace_refs" >&5 -$as_echo "$with_trace_refs" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_trace_refs" >&5 +printf "%s\n" "$with_trace_refs" >&6; } if test "$with_trace_refs" = "yes" then -$as_echo "#define Py_TRACE_REFS 1" >>confdefs.h +printf "%s\n" "#define Py_TRACE_REFS 1" >>confdefs.h fi # Check for --enable-pystats -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --enable-pystats" >&5 -$as_echo_n "checking for --enable-pystats... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --enable-pystats" >&5 +printf %s "checking for --enable-pystats... " >&6; } # Check whether --enable-pystats was given. -if test "${enable_pystats+set}" = set; then : +if test ${enable_pystats+y} +then : enableval=$enable_pystats; -else +else $as_nop enable_pystats=no fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_pystats" >&5 -$as_echo "$enable_pystats" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_pystats" >&5 +printf "%s\n" "$enable_pystats" >&6; } -if test "x$enable_pystats" = xyes; then : +if test "x$enable_pystats" = xyes +then : -$as_echo "#define Py_STATS 1" >>confdefs.h +printf "%s\n" "#define Py_STATS 1" >>confdefs.h fi @@ -7449,11 +8127,12 @@ fi # Check for --with-assertions. # This allows enabling assertions without Py_DEBUG. assertions='false' -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-assertions" >&5 -$as_echo_n "checking for --with-assertions... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-assertions" >&5 +printf %s "checking for --with-assertions... " >&6; } # Check whether --with-assertions was given. -if test "${with_assertions+set}" = set; then : +if test ${with_assertions+y} +then : withval=$with_assertions; if test "$withval" != no then @@ -7462,39 +8141,40 @@ fi fi if test "$assertions" = 'true'; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } elif test "$Py_DEBUG" = 'true'; then assertions='true' - { $as_echo "$as_me:${as_lineno-$LINENO}: result: implied by --with-pydebug" >&5 -$as_echo "implied by --with-pydebug" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: implied by --with-pydebug" >&5 +printf "%s\n" "implied by --with-pydebug" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi # Enable optimization flags Py_OPT='false' -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --enable-optimizations" >&5 -$as_echo_n "checking for --enable-optimizations... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --enable-optimizations" >&5 +printf %s "checking for --enable-optimizations... " >&6; } # Check whether --enable-optimizations was given. -if test "${enable_optimizations+set}" = set; then : +if test ${enable_optimizations+y} +then : enableval=$enable_optimizations; if test "$enableval" != no then Py_OPT='true' - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; }; + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; }; else Py_OPT='false' - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; }; + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; }; fi -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -7508,11 +8188,12 @@ if test "$Py_OPT" = 'true' ; then DEF_MAKE_RULE="build_all" case $CC in *gcc*) - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -fno-semantic-interposition" >&5 -$as_echo_n "checking whether C compiler accepts -fno-semantic-interposition... " >&6; } -if ${ax_cv_check_cflags___fno_semantic_interposition+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -fno-semantic-interposition" >&5 +printf %s "checking whether C compiler accepts -fno-semantic-interposition... " >&6; } +if test ${ax_cv_check_cflags___fno_semantic_interposition+y} +then : + printf %s "(cached) " >&6 +else $as_nop ax_check_save_flags=$CFLAGS CFLAGS="$CFLAGS -fno-semantic-interposition" @@ -7520,29 +8201,31 @@ else /* end confdefs.h. */ int -main () +main (void) { ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : ax_cv_check_cflags___fno_semantic_interposition=yes -else +else $as_nop ax_cv_check_cflags___fno_semantic_interposition=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext CFLAGS=$ax_check_save_flags fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___fno_semantic_interposition" >&5 -$as_echo "$ax_cv_check_cflags___fno_semantic_interposition" >&6; } -if test "x$ax_cv_check_cflags___fno_semantic_interposition" = xyes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___fno_semantic_interposition" >&5 +printf "%s\n" "$ax_cv_check_cflags___fno_semantic_interposition" >&6; } +if test "x$ax_cv_check_cflags___fno_semantic_interposition" = xyes +then : CFLAGS_NODIST="$CFLAGS_NODIST -fno-semantic-interposition" LDFLAGS_NODIST="$LDFLAGS_NODIST -fno-semantic-interposition" -else +else $as_nop : fi @@ -7559,14 +8242,14 @@ else fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking PROFILE_TASK" >&5 -$as_echo_n "checking PROFILE_TASK... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking PROFILE_TASK" >&5 +printf %s "checking PROFILE_TASK... " >&6; } if test -z "$PROFILE_TASK" then PROFILE_TASK='-m test --pgo --timeout=$(TESTTIMEOUT)' fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $PROFILE_TASK" >&5 -$as_echo "$PROFILE_TASK" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PROFILE_TASK" >&5 +printf "%s\n" "$PROFILE_TASK" >&6; } # Make llvm-related checks work on systems where llvm tools are not installed with their # normal names in the default $PATH (ie: Ubuntu). They exist under the @@ -7589,35 +8272,36 @@ then fi # Enable LTO flags -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-lto" >&5 -$as_echo_n "checking for --with-lto... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-lto" >&5 +printf %s "checking for --with-lto... " >&6; } # Check whether --with-lto was given. -if test "${with_lto+set}" = set; then : +if test ${with_lto+y} +then : withval=$with_lto; case "$withval" in full) Py_LTO='true' Py_LTO_POLICY='full' - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } ;; thin) Py_LTO='true' Py_LTO_POLICY='thin' - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } ;; yes) Py_LTO='true' Py_LTO_POLICY='default' - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } ;; no) Py_LTO='false' - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } ;; *) Py_LTO='false' @@ -7625,20 +8309,21 @@ $as_echo "no" >&6; } ;; esac -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi if test "$Py_LTO" = 'true' ; then case $CC in *clang*) LDFLAGS_NOLTO="-fno-lto" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -flto=thin" >&5 -$as_echo_n "checking whether C compiler accepts -flto=thin... " >&6; } -if ${ax_cv_check_cflags___flto_thin+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -flto=thin" >&5 +printf %s "checking whether C compiler accepts -flto=thin... " >&6; } +if test ${ax_cv_check_cflags___flto_thin+y} +then : + printf %s "(cached) " >&6 +else $as_nop ax_check_save_flags=$CFLAGS CFLAGS="$CFLAGS -flto=thin" @@ -7646,26 +8331,28 @@ else /* end confdefs.h. */ int -main () +main (void) { ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : ax_cv_check_cflags___flto_thin=yes -else +else $as_nop ax_cv_check_cflags___flto_thin=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext CFLAGS=$ax_check_save_flags fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___flto_thin" >&5 -$as_echo "$ax_cv_check_cflags___flto_thin" >&6; } -if test "x$ax_cv_check_cflags___flto_thin" = xyes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___flto_thin" >&5 +printf "%s\n" "$ax_cv_check_cflags___flto_thin" >&6; } +if test "x$ax_cv_check_cflags___flto_thin" = xyes +then : LDFLAGS_NOLTO="-flto=thin" -else +else $as_nop LDFLAGS_NOLTO="-flto" fi @@ -7673,11 +8360,12 @@ fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}llvm-ar", so it can be a program name with args. set dummy ${ac_tool_prefix}llvm-ar; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_LLVM_AR+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_LLVM_AR+y} +then : + printf %s "(cached) " >&6 +else $as_nop case $LLVM_AR in [\\/]* | ?:[\\/]*) ac_cv_path_LLVM_AR="$LLVM_AR" # Let the user override the test with a path. @@ -7687,11 +8375,15 @@ else for as_dir in ${llvm_path} do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_LLVM_AR="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_LLVM_AR="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -7703,11 +8395,11 @@ esac fi LLVM_AR=$ac_cv_path_LLVM_AR if test -n "$LLVM_AR"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LLVM_AR" >&5 -$as_echo "$LLVM_AR" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $LLVM_AR" >&5 +printf "%s\n" "$LLVM_AR" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -7716,11 +8408,12 @@ if test -z "$ac_cv_path_LLVM_AR"; then ac_pt_LLVM_AR=$LLVM_AR # Extract the first word of "llvm-ar", so it can be a program name with args. set dummy llvm-ar; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_ac_pt_LLVM_AR+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_ac_pt_LLVM_AR+y} +then : + printf %s "(cached) " >&6 +else $as_nop case $ac_pt_LLVM_AR in [\\/]* | ?:[\\/]*) ac_cv_path_ac_pt_LLVM_AR="$ac_pt_LLVM_AR" # Let the user override the test with a path. @@ -7730,11 +8423,15 @@ else for as_dir in ${llvm_path} do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_ac_pt_LLVM_AR="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_ac_pt_LLVM_AR="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -7746,11 +8443,11 @@ esac fi ac_pt_LLVM_AR=$ac_cv_path_ac_pt_LLVM_AR if test -n "$ac_pt_LLVM_AR"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_LLVM_AR" >&5 -$as_echo "$ac_pt_LLVM_AR" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_pt_LLVM_AR" >&5 +printf "%s\n" "$ac_pt_LLVM_AR" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi if test "x$ac_pt_LLVM_AR" = x; then @@ -7758,8 +8455,8 @@ fi else case $cross_compiling:$ac_tool_warned in yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac LLVM_AR=$ac_pt_LLVM_AR @@ -7783,8 +8480,8 @@ fi then LLVM_AR='/usr/bin/xcrun ar' LLVM_AR_FOUND=found - { $as_echo "$as_me:${as_lineno-$LINENO}: llvm-ar found via xcrun: ${LLVM_AR}" >&5 -$as_echo "$as_me: llvm-ar found via xcrun: ${LLVM_AR}" >&6;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: llvm-ar found via xcrun: ${LLVM_AR}" >&5 +printf "%s\n" "$as_me: llvm-ar found via xcrun: ${LLVM_AR}" >&6;} fi fi if test $LLVM_AR_FOUND = not-found @@ -7800,17 +8497,99 @@ $as_echo "$as_me: llvm-ar found via xcrun: ${LLVM_AR}" >&6;} # Any changes made here should be reflected in the GCC+Darwin case below if test $Py_LTO_POLICY = default then - LTOFLAGS="-flto -Wl,-export_dynamic" - LTOCFLAGS="-flto" + # Check that ThinLTO is accepted. + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -flto=thin" >&5 +printf %s "checking whether C compiler accepts -flto=thin... " >&6; } +if test ${ax_cv_check_cflags___flto_thin+y} +then : + printf %s "(cached) " >&6 +else $as_nop + + ax_check_save_flags=$CFLAGS + CFLAGS="$CFLAGS -flto=thin" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ax_cv_check_cflags___flto_thin=yes +else $as_nop + ax_cv_check_cflags___flto_thin=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + CFLAGS=$ax_check_save_flags +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___flto_thin" >&5 +printf "%s\n" "$ax_cv_check_cflags___flto_thin" >&6; } +if test "x$ax_cv_check_cflags___flto_thin" = xyes +then : + + LTOFLAGS="-flto=thin -Wl,-export_dynamic -Wl,-object_path_lto,\"\$@\".lto" + LTOCFLAGS="-flto=thin" + +else $as_nop + + LTOFLAGS="-flto -Wl,-export_dynamic -Wl,-object_path_lto,\"\$@\".lto" + LTOCFLAGS="-flto" + + +fi + else - LTOFLAGS="-flto=${Py_LTO_POLICY} -Wl,-export_dynamic" + LTOFLAGS="-flto=${Py_LTO_POLICY} -Wl,-export_dynamic -Wl,-object_path_lto,\"\$@\".lto" LTOCFLAGS="-flto=${Py_LTO_POLICY}" fi ;; *) if test $Py_LTO_POLICY = default then - LTOFLAGS="-flto" + # Check that ThinLTO is accepted + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -flto=thin" >&5 +printf %s "checking whether C compiler accepts -flto=thin... " >&6; } +if test ${ax_cv_check_cflags___flto_thin+y} +then : + printf %s "(cached) " >&6 +else $as_nop + + ax_check_save_flags=$CFLAGS + CFLAGS="$CFLAGS -flto=thin" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ax_cv_check_cflags___flto_thin=yes +else $as_nop + ax_cv_check_cflags___flto_thin=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + CFLAGS=$ax_check_save_flags +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___flto_thin" >&5 +printf "%s\n" "$ax_cv_check_cflags___flto_thin" >&6; } +if test "x$ax_cv_check_cflags___flto_thin" = xyes +then : + LTOFLAGS="-flto=thin" +else $as_nop + LTOFLAGS="-flto" +fi + else LTOFLAGS="-flto=${Py_LTO_POLICY}" fi @@ -7832,7 +8611,7 @@ $as_echo "$as_me: llvm-ar found via xcrun: ${LLVM_AR}" >&6;} LDFLAGS_NOLTO="-fno-lto" case $ac_sys_system in Darwin*) - LTOFLAGS="-flto -Wl,-export_dynamic" + LTOFLAGS="-flto -Wl,-export_dynamic -Wl,-object_path_lto,\"\$@\".lto" LTOCFLAGS="-flto" ;; *) @@ -7863,11 +8642,12 @@ fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}llvm-profdata", so it can be a program name with args. set dummy ${ac_tool_prefix}llvm-profdata; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_LLVM_PROFDATA+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_LLVM_PROFDATA+y} +then : + printf %s "(cached) " >&6 +else $as_nop case $LLVM_PROFDATA in [\\/]* | ?:[\\/]*) ac_cv_path_LLVM_PROFDATA="$LLVM_PROFDATA" # Let the user override the test with a path. @@ -7877,11 +8657,15 @@ else for as_dir in ${llvm_path} do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_LLVM_PROFDATA="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_LLVM_PROFDATA="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -7893,11 +8677,11 @@ esac fi LLVM_PROFDATA=$ac_cv_path_LLVM_PROFDATA if test -n "$LLVM_PROFDATA"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LLVM_PROFDATA" >&5 -$as_echo "$LLVM_PROFDATA" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $LLVM_PROFDATA" >&5 +printf "%s\n" "$LLVM_PROFDATA" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -7906,11 +8690,12 @@ if test -z "$ac_cv_path_LLVM_PROFDATA"; then ac_pt_LLVM_PROFDATA=$LLVM_PROFDATA # Extract the first word of "llvm-profdata", so it can be a program name with args. set dummy llvm-profdata; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_ac_pt_LLVM_PROFDATA+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_ac_pt_LLVM_PROFDATA+y} +then : + printf %s "(cached) " >&6 +else $as_nop case $ac_pt_LLVM_PROFDATA in [\\/]* | ?:[\\/]*) ac_cv_path_ac_pt_LLVM_PROFDATA="$ac_pt_LLVM_PROFDATA" # Let the user override the test with a path. @@ -7920,11 +8705,15 @@ else for as_dir in ${llvm_path} do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_ac_pt_LLVM_PROFDATA="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_ac_pt_LLVM_PROFDATA="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -7936,11 +8725,11 @@ esac fi ac_pt_LLVM_PROFDATA=$ac_cv_path_ac_pt_LLVM_PROFDATA if test -n "$ac_pt_LLVM_PROFDATA"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_LLVM_PROFDATA" >&5 -$as_echo "$ac_pt_LLVM_PROFDATA" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_pt_LLVM_PROFDATA" >&5 +printf "%s\n" "$ac_pt_LLVM_PROFDATA" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi if test "x$ac_pt_LLVM_PROFDATA" = x; then @@ -7948,8 +8737,8 @@ fi else case $cross_compiling:$ac_tool_warned in yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac LLVM_PROFDATA=$ac_pt_LLVM_PROFDATA @@ -7974,8 +8763,8 @@ then # https://apple.stackexchange.com/questions/197053/ LLVM_PROFDATA='/usr/bin/xcrun llvm-profdata' LLVM_PROF_FOUND=found - { $as_echo "$as_me:${as_lineno-$LINENO}: llvm-profdata found via xcrun: ${LLVM_PROFDATA}" >&5 -$as_echo "$as_me: llvm-profdata found via xcrun: ${LLVM_PROFDATA}" >&6;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: llvm-profdata found via xcrun: ${LLVM_PROFDATA}" >&5 +printf "%s\n" "$as_me: llvm-profdata found via xcrun: ${LLVM_PROFDATA}" >&6;} fi fi LLVM_PROF_ERR=no @@ -8027,104 +8816,508 @@ case $CC in ;; esac -# XXX Shouldn't the code above that fiddles with BASECFLAGS and OPT be -# merged with this chunk of code? +# BOLT optimization. Always configured after PGO since it always runs after PGO. +Py_BOLT='false' +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --enable-bolt" >&5 +printf %s "checking for --enable-bolt... " >&6; } +# Check whether --enable-bolt was given. +if test ${enable_bolt+y} +then : + enableval=$enable_bolt; +if test "$enableval" != no +then + Py_BOLT='true' + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; }; +else + Py_BOLT='false' + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; }; +fi +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi -# Optimizer/debugger flags -# ------------------------ -# (The following bit of code is complicated enough - please keep things -# indented properly. Just pretend you're editing Python code. ;-) -# There are two parallel sets of case statements below, one that checks to -# see if OPT was set and one that does BASECFLAGS setting based upon -# compiler and platform. BASECFLAGS tweaks need to be made even if the -# user set OPT. -case $CC in - *clang*) - cc_is_clang=1 - ;; - *) - if $CC --version 2>&1 | grep -q clang - then - cc_is_clang=1 - else - cc_is_clang= - fi -esac +if test "$Py_BOLT" = 'true' ; then + PREBOLT_RULE="${DEF_MAKE_ALL_RULE}" + DEF_MAKE_ALL_RULE="bolt-opt" + DEF_MAKE_RULE="build_all" -# Check if CC supports -Og optimization level -save_CFLAGS=$CFLAGS -CFLAGS="-Og" -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports -Og optimization level" >&5 -$as_echo_n "checking if $CC supports -Og optimization level... " >&6; } -if ${ac_cv_cc_supports_og+:} false; then : - $as_echo_n "(cached) " >&6 -else + # -fno-reorder-blocks-and-partition is required for bolt to work. + # Possibly GCC only. + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -fno-reorder-blocks-and-partition" >&5 +printf %s "checking whether C compiler accepts -fno-reorder-blocks-and-partition... " >&6; } +if test ${ax_cv_check_cflags___fno_reorder_blocks_and_partition+y} +then : + printf %s "(cached) " >&6 +else $as_nop + + ax_check_save_flags=$CFLAGS + CFLAGS="$CFLAGS -fno-reorder-blocks-and-partition" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - int -main () +main (void) { ; return 0; } - _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - - ac_cv_cc_supports_og=yes - -else - - ac_cv_cc_supports_og=no - +if ac_fn_c_try_compile "$LINENO" +then : + ax_cv_check_cflags___fno_reorder_blocks_and_partition=yes +else $as_nop + ax_cv_check_cflags___fno_reorder_blocks_and_partition=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + CFLAGS=$ax_check_save_flags fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cc_supports_og" >&5 -$as_echo "$ac_cv_cc_supports_og" >&6; } -CFLAGS=$save_CFLAGS +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___fno_reorder_blocks_and_partition" >&5 +printf "%s\n" "$ax_cv_check_cflags___fno_reorder_blocks_and_partition" >&6; } +if test "x$ax_cv_check_cflags___fno_reorder_blocks_and_partition" = xyes +then : -# Optimization messes up debuggers, so turn it off for -# debug builds. -PYDEBUG_CFLAGS="-O0" -if test "x$ac_cv_cc_supports_og" = xyes; then : - PYDEBUG_CFLAGS="-Og" + CFLAGS_NODIST="$CFLAGS_NODIST -fno-reorder-blocks-and-partition" + +else $as_nop + : fi -# tweak OPT based on compiler and platform, only if the user didn't set -# it on the command line + # These flags are required for bolt to work: + LDFLAGS_NODIST="$LDFLAGS_NODIST -Wl,--emit-relocs" -if test "${OPT-unset}" = "unset" -then - case $GCC in - yes) - # For gcc 4.x we need to use -fwrapv so lets check if its supported - if "$CC" -v --help 2>/dev/null |grep -- -fwrapv > /dev/null; then - WRAP="-fwrapv" - fi + # These flags are required to get good performance from bolt: + CFLAGS_NODIST="$CFLAGS_NODIST -fno-pie" + # We want to add these no-pie flags to linking executables but not shared libraries: + LINKCC="$LINKCC -fno-pie -no-pie" - if test -n "${cc_is_clang}" - then - # Clang also needs -fwrapv - WRAP="-fwrapv" - # bpo-30104: disable strict aliasing to compile correctly dtoa.c, - # see Makefile.pre.in for more information - CFLAGS_ALIASING="-fno-strict-aliasing" - fi + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}llvm-bolt", so it can be a program name with args. +set dummy ${ac_tool_prefix}llvm-bolt; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_LLVM_BOLT+y} +then : + printf %s "(cached) " >&6 +else $as_nop + case $LLVM_BOLT in + [\\/]* | ?:[\\/]*) + ac_cv_path_LLVM_BOLT="$LLVM_BOLT" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in ${llvm_path} +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_LLVM_BOLT="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS - case $ac_cv_prog_cc_g in + ;; +esac +fi +LLVM_BOLT=$ac_cv_path_LLVM_BOLT +if test -n "$LLVM_BOLT"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $LLVM_BOLT" >&5 +printf "%s\n" "$LLVM_BOLT" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_path_LLVM_BOLT"; then + ac_pt_LLVM_BOLT=$LLVM_BOLT + # Extract the first word of "llvm-bolt", so it can be a program name with args. +set dummy llvm-bolt; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_ac_pt_LLVM_BOLT+y} +then : + printf %s "(cached) " >&6 +else $as_nop + case $ac_pt_LLVM_BOLT in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_pt_LLVM_BOLT="$ac_pt_LLVM_BOLT" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in ${llvm_path} +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_ac_pt_LLVM_BOLT="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +ac_pt_LLVM_BOLT=$ac_cv_path_ac_pt_LLVM_BOLT +if test -n "$ac_pt_LLVM_BOLT"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_pt_LLVM_BOLT" >&5 +printf "%s\n" "$ac_pt_LLVM_BOLT" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_pt_LLVM_BOLT" = x; then + LLVM_BOLT="''" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + LLVM_BOLT=$ac_pt_LLVM_BOLT + fi +else + LLVM_BOLT="$ac_cv_path_LLVM_BOLT" +fi + + if test -n "${LLVM_BOLT}" -a -x "${LLVM_BOLT}" + then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: \"Found llvm-bolt\"" >&5 +printf "%s\n" "\"Found llvm-bolt\"" >&6; } + else + as_fn_error $? "llvm-bolt is required for a --enable-bolt build but could not be found." "$LINENO" 5 + fi + + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}merge-fdata", so it can be a program name with args. +set dummy ${ac_tool_prefix}merge-fdata; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_MERGE_FDATA+y} +then : + printf %s "(cached) " >&6 +else $as_nop + case $MERGE_FDATA in + [\\/]* | ?:[\\/]*) + ac_cv_path_MERGE_FDATA="$MERGE_FDATA" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in ${llvm_path} +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_MERGE_FDATA="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +MERGE_FDATA=$ac_cv_path_MERGE_FDATA +if test -n "$MERGE_FDATA"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MERGE_FDATA" >&5 +printf "%s\n" "$MERGE_FDATA" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_path_MERGE_FDATA"; then + ac_pt_MERGE_FDATA=$MERGE_FDATA + # Extract the first word of "merge-fdata", so it can be a program name with args. +set dummy merge-fdata; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_ac_pt_MERGE_FDATA+y} +then : + printf %s "(cached) " >&6 +else $as_nop + case $ac_pt_MERGE_FDATA in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_pt_MERGE_FDATA="$ac_pt_MERGE_FDATA" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in ${llvm_path} +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_ac_pt_MERGE_FDATA="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +ac_pt_MERGE_FDATA=$ac_cv_path_ac_pt_MERGE_FDATA +if test -n "$ac_pt_MERGE_FDATA"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_pt_MERGE_FDATA" >&5 +printf "%s\n" "$ac_pt_MERGE_FDATA" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_pt_MERGE_FDATA" = x; then + MERGE_FDATA="''" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + MERGE_FDATA=$ac_pt_MERGE_FDATA + fi +else + MERGE_FDATA="$ac_cv_path_MERGE_FDATA" +fi + + if test -n "${MERGE_FDATA}" -a -x "${MERGE_FDATA}" + then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: \"Found merge-fdata\"" >&5 +printf "%s\n" "\"Found merge-fdata\"" >&6; } + else + as_fn_error $? "merge-fdata is required for a --enable-bolt build but could not be found." "$LINENO" 5 + fi +fi + + +BOLT_BINARIES='$(BUILDPYTHON)' +if test "x$enable_shared" = xyes +then : + + BOLT_BINARIES="${BOLT_BINARIES} \$(INSTSONAME)" + +fi + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking BOLT_INSTRUMENT_FLAGS" >&5 +printf %s "checking BOLT_INSTRUMENT_FLAGS... " >&6; } +if test -z "${BOLT_INSTRUMENT_FLAGS}" +then + BOLT_INSTRUMENT_FLAGS= +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $BOLT_INSTRUMENT_FLAGS" >&5 +printf "%s\n" "$BOLT_INSTRUMENT_FLAGS" >&6; } + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking BOLT_APPLY_FLAGS" >&5 +printf %s "checking BOLT_APPLY_FLAGS... " >&6; } +if test -z "${BOLT_APPLY_FLAGS}" +then + BOLT_APPLY_FLAGS=" -update-debug-sections -reorder-blocks=ext-tsp -reorder-functions=hfsort+ -split-functions -icf=1 -inline-all -split-eh -reorder-functions-use-hot-size -peepholes=none -jump-tables=aggressive -inline-ap -indirect-call-promotion=all -dyno-stats -use-gnu-stack -frame-opt=hot " + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $BOLT_APPLY_FLAGS" >&5 +printf "%s\n" "$BOLT_APPLY_FLAGS" >&6; } + +# XXX Shouldn't the code above that fiddles with BASECFLAGS and OPT be +# merged with this chunk of code? + +# Optimizer/debugger flags +# ------------------------ +# (The following bit of code is complicated enough - please keep things +# indented properly. Just pretend you're editing Python code. ;-) + +# There are two parallel sets of case statements below, one that checks to +# see if OPT was set and one that does BASECFLAGS setting based upon +# compiler and platform. BASECFLAGS tweaks need to be made even if the +# user set OPT. + +case $CC in + *clang*) + cc_is_clang=1 + ;; + *) + if $CC --version 2>&1 | grep -q clang + then + cc_is_clang=1 + else + cc_is_clang= + fi +esac + +save_CFLAGS=$CFLAGS +CFLAGS="-fstrict-overflow -fno-strict-overflow" +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports -fstrict-overflow and -fno-strict-overflow" >&5 +printf %s "checking if $CC supports -fstrict-overflow and -fno-strict-overflow... " >&6; } +if test ${ac_cv_cc_supports_fstrict_overflow+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_cc_supports_fstrict_overflow=yes +else $as_nop + ac_cv_cc_supports_fstrict_overflow=no + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cc_supports_fstrict_overflow" >&5 +printf "%s\n" "$ac_cv_cc_supports_fstrict_overflow" >&6; } +CFLAGS=$save_CFLAGS + +if test "x$ac_cv_cc_supports_fstrict_overflow" = xyes +then : + STRICT_OVERFLOW_CFLAGS="-fstrict-overflow" + NO_STRICT_OVERFLOW_CFLAGS="-fno-strict-overflow" +else $as_nop + STRICT_OVERFLOW_CFLAGS="" + NO_STRICT_OVERFLOW_CFLAGS="" +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-strict-overflow" >&5 +printf %s "checking for --with-strict-overflow... " >&6; } + +# Check whether --with-strict-overflow was given. +if test ${with_strict_overflow+y} +then : + withval=$with_strict_overflow; + if test "x$ac_cv_cc_supports_fstrict_overflow" = xno +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: --with-strict-overflow=yes requires a compiler that supports -fstrict-overflow" >&5 +printf "%s\n" "$as_me: WARNING: --with-strict-overflow=yes requires a compiler that supports -fstrict-overflow" >&2;} +fi + +else $as_nop + with_strict_overflow=no + +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_strict_overflow" >&5 +printf "%s\n" "$with_strict_overflow" >&6; } + +# Check if CC supports -Og optimization level +save_CFLAGS=$CFLAGS +CFLAGS="-Og" +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC supports -Og optimization level" >&5 +printf %s "checking if $CC supports -Og optimization level... " >&6; } +if test ${ac_cv_cc_supports_og+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main (void) +{ + + ; + return 0; +} + +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + + ac_cv_cc_supports_og=yes + +else $as_nop + + ac_cv_cc_supports_og=no + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cc_supports_og" >&5 +printf "%s\n" "$ac_cv_cc_supports_og" >&6; } +CFLAGS=$save_CFLAGS + +# Optimization messes up debuggers, so turn it off for +# debug builds. +PYDEBUG_CFLAGS="-O0" +if test "x$ac_cv_cc_supports_og" = xyes +then : + PYDEBUG_CFLAGS="-Og" +fi + +# tweak OPT based on compiler and platform, only if the user didn't set +# it on the command line + + +if test "${OPT-unset}" = "unset" +then + case $GCC in + yes) + if test -n "${cc_is_clang}" + then + # bpo-30104: disable strict aliasing to compile correctly dtoa.c, + # see Makefile.pre.in for more information + CFLAGS_ALIASING="-fno-strict-aliasing" + fi + + case $ac_cv_prog_cc_g in yes) if test "$Py_DEBUG" = 'true' ; then OPT="-g $PYDEBUG_CFLAGS -Wall" else - OPT="-g $WRAP -O3 -Wall" + OPT="-g -O3 -Wall" fi ;; *) @@ -8148,9 +9341,10 @@ fi case $ac_sys_system in #( Emscripten) : - if test "x$Py_DEBUG" = xyes; then : + if test "x$Py_DEBUG" = xyes +then : wasm_debug=yes -else +else $as_nop wasm_debug=no fi @@ -8160,13 +9354,15 @@ fi as_fn_append LDFLAGS_NODIST " -sFORCE_FILESYSTEM -lidbfs.js -lnodefs.js -lproxyfs.js -lworkerfs.js" - if test "x$enable_wasm_dynamic_linking" = xyes; then : + if test "x$enable_wasm_dynamic_linking" = xyes +then : as_fn_append LINKFORSHARED " -sMAIN_MODULE" fi - if test "x$enable_wasm_pthreads" = xyes; then : + if test "x$enable_wasm_pthreads" = xyes +then : as_fn_append CFLAGS_NODIST " -pthread" as_fn_append LDFLAGS_NODIST " -sUSE_PTHREADS" @@ -8177,7 +9373,8 @@ fi case $ac_sys_emscripten_target in #( browser*) : - if test "x$ac_sys_emscripten_target" = xbrowser-debug; then : + if test "x$ac_sys_emscripten_target" = xbrowser-debug +then : wasm_debug=yes fi as_fn_append LINKFORSHARED " --preload-file=\$(WASM_ASSETS_DIR)" @@ -8187,7 +9384,8 @@ fi ;; #( node*) : - if test "x$ac_sys_emscripten_target" = xnode-debug; then : + if test "x$ac_sys_emscripten_target" = xnode-debug +then : wasm_debug=yes fi as_fn_append LDFLAGS_NODIST " -sALLOW_MEMORY_GROWTH -sNODERAWFS" @@ -8199,12 +9397,13 @@ fi ;; esac - if test "x$wasm_debug" = xyes; then : + if test "x$wasm_debug" = xyes +then : as_fn_append LDFLAGS_NODIST " -sASSERTIONS" as_fn_append LINKFORSHARED " $WASM_LINKFORSHARED_DEBUG" -else +else $as_nop as_fn_append LINKFORSHARED " -O2 -g0" @@ -8213,17 +9412,32 @@ fi WASI) : -$as_echo "#define _WASI_EMULATED_SIGNAL 1" >>confdefs.h +printf "%s\n" "#define _WASI_EMULATED_SIGNAL 1" >>confdefs.h -$as_echo "#define _WASI_EMULATED_GETPID 1" >>confdefs.h +printf "%s\n" "#define _WASI_EMULATED_GETPID 1" >>confdefs.h -$as_echo "#define _WASI_EMULATED_PROCESS_CLOCKS 1" >>confdefs.h +printf "%s\n" "#define _WASI_EMULATED_PROCESS_CLOCKS 1" >>confdefs.h LIBS="$LIBS -lwasi-emulated-signal -lwasi-emulated-getpid -lwasi-emulated-process-clocks" echo "#define _WASI_EMULATED_SIGNAL 1" >> confdefs.h + if test "x$enable_wasm_pthreads" = xyes +then : + + # Note: update CFLAGS because ac_compile/ac_link needs this too. + # without this, configure fails to find pthread_create, sem_init, + # etc because they are only available in the sysroot for + # wasm32-wasi-threads. + as_fn_append CFLAGS " -target wasm32-wasi-threads -pthread" + as_fn_append CFLAGS_NODIST " -target wasm32-wasi-threads -pthread" + as_fn_append LDFLAGS_NODIST " -target wasm32-wasi-threads -pthread" + as_fn_append LDFLAGS_NODIST " -Wl,--import-memory" + as_fn_append LDFLAGS_NODIST " -Wl,--max-memory=10485760" + +fi + as_fn_append LDFLAGS_NODIST " -z stack-size=524288 -Wl,--stack-first -Wl,--initial-memory=10485760" ;; #( @@ -8257,17 +9471,25 @@ UNIVERSAL_ARCH_FLAGS= # tweak BASECFLAGS based on compiler and platform +if test "x$with_strict_overflow" = xyes +then : + BASECFLAGS="$BASECFLAGS $STRICT_OVERFLOW_CFLAGS" +else $as_nop + BASECFLAGS="$BASECFLAGS $NO_STRICT_OVERFLOW_CFLAGS" +fi + case $GCC in yes) CFLAGS_NODIST="$CFLAGS_NODIST -std=c11" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can add -Wextra" >&5 -$as_echo_n "checking if we can add -Wextra... " >&6; } -if ${ac_cv_enable_extra_warning+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if we can add -Wextra" >&5 +printf %s "checking if we can add -Wextra... " >&6; } +if test ${ac_cv_enable_extra_warning+y} +then : + printf %s "(cached) " >&6 +else $as_nop py_cflags=$CFLAGS as_fn_append CFLAGS "-Wextra -Werror" @@ -8275,27 +9497,29 @@ else /* end confdefs.h. */ int -main () +main (void) { ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : ac_cv_enable_extra_warning=yes -else +else $as_nop ac_cv_enable_extra_warning=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext CFLAGS=$py_cflags fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_enable_extra_warning" >&5 -$as_echo "$ac_cv_enable_extra_warning" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_enable_extra_warning" >&5 +printf "%s\n" "$ac_cv_enable_extra_warning" >&6; } - if test "x$ac_cv_enable_extra_warning" = xyes; then : + if test "x$ac_cv_enable_extra_warning" = xyes +then : CFLAGS_NODIST="$CFLAGS_NODIST -Wextra" fi @@ -8306,17 +9530,18 @@ fi ac_save_cc="$CC" CC="$CC -fno-strict-aliasing" save_CFLAGS="$CFLAGS" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts and needs -fno-strict-aliasing" >&5 -$as_echo_n "checking whether $CC accepts and needs -fno-strict-aliasing... " >&6; } -if ${ac_cv_no_strict_aliasing+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts and needs -fno-strict-aliasing" >&5 +printf %s "checking whether $CC accepts and needs -fno-strict-aliasing... " >&6; } +if test ${ac_cv_no_strict_aliasing+y} +then : + printf %s "(cached) " >&6 +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int -main () +main (void) { ; @@ -8324,7 +9549,8 @@ main () } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : CC="$ac_save_cc -fstrict-aliasing" CFLAGS="$CFLAGS -Werror -Wstrict-aliasing" @@ -8333,7 +9559,7 @@ if ac_fn_c_try_compile "$LINENO"; then : void f(int **x) {} int -main () +main (void) { double *x; f((int **) &x); ; @@ -8341,29 +9567,31 @@ double *x; f((int **) &x); } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : ac_cv_no_strict_aliasing=no -else +else $as_nop ac_cv_no_strict_aliasing=yes fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext -else +else $as_nop ac_cv_no_strict_aliasing=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_no_strict_aliasing" >&5 -$as_echo "$ac_cv_no_strict_aliasing" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_no_strict_aliasing" >&5 +printf "%s\n" "$ac_cv_no_strict_aliasing" >&6; } CFLAGS="$save_CFLAGS" CC="$ac_save_cc" - if test "x$ac_cv_no_strict_aliasing" = xyes; then : + if test "x$ac_cv_no_strict_aliasing" = xyes +then : BASECFLAGS="$BASECFLAGS -fno-strict-aliasing" fi @@ -8374,11 +9602,12 @@ fi ac_cv_disable_unused_result_warning=no - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can disable $CC unused-result warning" >&5 -$as_echo_n "checking if we can disable $CC unused-result warning... " >&6; } -if ${ac_cv_disable_unused_result_warning+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if we can disable $CC unused-result warning" >&5 +printf %s "checking if we can disable $CC unused-result warning... " >&6; } +if test ${ac_cv_disable_unused_result_warning+y} +then : + printf %s "(cached) " >&6 +else $as_nop py_cflags=$CFLAGS as_fn_append CFLAGS "-Wunused-result -Werror" @@ -8386,41 +9615,44 @@ else /* end confdefs.h. */ int -main () +main (void) { ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : ac_cv_disable_unused_result_warning=yes -else +else $as_nop ac_cv_disable_unused_result_warning=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext CFLAGS=$py_cflags fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_disable_unused_result_warning" >&5 -$as_echo "$ac_cv_disable_unused_result_warning" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_disable_unused_result_warning" >&5 +printf "%s\n" "$ac_cv_disable_unused_result_warning" >&6; } ;; #( *) : ;; esac - if test "x$ac_cv_disable_unused_result_warning" = xyes; then : + if test "x$ac_cv_disable_unused_result_warning" = xyes +then : BASECFLAGS="$BASECFLAGS -Wno-unused-result" CFLAGS_NODIST="$CFLAGS_NODIST -Wno-unused-result" fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can disable $CC unused-parameter warning" >&5 -$as_echo_n "checking if we can disable $CC unused-parameter warning... " >&6; } -if ${ac_cv_disable_unused_parameter_warning+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if we can disable $CC unused-parameter warning" >&5 +printf %s "checking if we can disable $CC unused-parameter warning... " >&6; } +if test ${ac_cv_disable_unused_parameter_warning+y} +then : + printf %s "(cached) " >&6 +else $as_nop py_cflags=$CFLAGS as_fn_append CFLAGS "-Wunused-parameter -Werror" @@ -8428,138 +9660,189 @@ else /* end confdefs.h. */ int -main () +main (void) { ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : ac_cv_disable_unused_parameter_warning=yes -else +else $as_nop ac_cv_disable_unused_parameter_warning=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext CFLAGS=$py_cflags fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_disable_unused_parameter_warning" >&5 -$as_echo "$ac_cv_disable_unused_parameter_warning" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_disable_unused_parameter_warning" >&5 +printf "%s\n" "$ac_cv_disable_unused_parameter_warning" >&6; } - if test "x$ac_cv_disable_unused_parameter_warning" = xyes; then : + if test "x$ac_cv_disable_unused_parameter_warning" = xyes +then : CFLAGS_NODIST="$CFLAGS_NODIST -Wno-unused-parameter" fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can disable $CC missing-field-initializers warning" >&5 -$as_echo_n "checking if we can disable $CC missing-field-initializers warning... " >&6; } -if ${ac_cv_disable_missing_field_initializers_warning+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if we can disable $CC int-conversion warning" >&5 +printf %s "checking if we can disable $CC int-conversion warning... " >&6; } +if test ${ac_cv_disable_int_conversion_warning+y} +then : + printf %s "(cached) " >&6 +else $as_nop py_cflags=$CFLAGS - as_fn_append CFLAGS "-Wmissing-field-initializers -Werror" + as_fn_append CFLAGS "-Wint-conversion -Werror" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int -main () +main (void) { ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_disable_missing_field_initializers_warning=yes -else - ac_cv_disable_missing_field_initializers_warning=no +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_disable_int_conversion_warning=yes +else $as_nop + ac_cv_disable_int_conversion_warning=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext CFLAGS=$py_cflags fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_disable_missing_field_initializers_warning" >&5 -$as_echo "$ac_cv_disable_missing_field_initializers_warning" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_disable_int_conversion_warning" >&5 +printf "%s\n" "$ac_cv_disable_int_conversion_warning" >&6; } - if test "x$ac_cv_disable_missing_field_initializers_warning" = xyes; then : - CFLAGS_NODIST="$CFLAGS_NODIST -Wno-missing-field-initializers" + if test "x$ac_cv_disable_int_conversion" = xyes +then : + CFLAGS_NODIST="$CFLAGS_NODIST -Wno-int-conversion" fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can enable $CC sign-compare warning" >&5 -$as_echo_n "checking if we can enable $CC sign-compare warning... " >&6; } -if ${ac_cv_enable_sign_compare_warning+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if we can disable $CC missing-field-initializers warning" >&5 +printf %s "checking if we can disable $CC missing-field-initializers warning... " >&6; } +if test ${ac_cv_disable_missing_field_initializers_warning+y} +then : + printf %s "(cached) " >&6 +else $as_nop py_cflags=$CFLAGS - as_fn_append CFLAGS "-Wsign-compare -Werror" + as_fn_append CFLAGS "-Wmissing-field-initializers -Werror" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int -main () +main (void) { ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_enable_sign_compare_warning=yes -else - ac_cv_enable_sign_compare_warning=no +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_disable_missing_field_initializers_warning=yes +else $as_nop + ac_cv_disable_missing_field_initializers_warning=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext CFLAGS=$py_cflags fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_enable_sign_compare_warning" >&5 -$as_echo "$ac_cv_enable_sign_compare_warning" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_disable_missing_field_initializers_warning" >&5 +printf "%s\n" "$ac_cv_disable_missing_field_initializers_warning" >&6; } - if test "x$ac_cv_enable_sign_compare_warning" = xyes; then : - BASECFLAGS="$BASECFLAGS -Wsign-compare" + if test "x$ac_cv_disable_missing_field_initializers_warning" = xyes +then : + CFLAGS_NODIST="$CFLAGS_NODIST -Wno-missing-field-initializers" fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can enable $CC unreachable-code warning" >&5 -$as_echo_n "checking if we can enable $CC unreachable-code warning... " >&6; } -if ${ac_cv_enable_unreachable_code_warning+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if we can enable $CC sign-compare warning" >&5 +printf %s "checking if we can enable $CC sign-compare warning... " >&6; } +if test ${ac_cv_enable_sign_compare_warning+y} +then : + printf %s "(cached) " >&6 +else $as_nop py_cflags=$CFLAGS - as_fn_append CFLAGS "-Wunreachable-code -Werror" + as_fn_append CFLAGS "-Wsign-compare -Werror" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int -main () +main (void) { ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_enable_unreachable_code_warning=yes -else - ac_cv_enable_unreachable_code_warning=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_enable_sign_compare_warning=yes +else $as_nop + ac_cv_enable_sign_compare_warning=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + CFLAGS=$py_cflags + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_enable_sign_compare_warning" >&5 +printf "%s\n" "$ac_cv_enable_sign_compare_warning" >&6; } + + + if test "x$ac_cv_enable_sign_compare_warning" = xyes +then : + BASECFLAGS="$BASECFLAGS -Wsign-compare" +fi + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if we can enable $CC unreachable-code warning" >&5 +printf %s "checking if we can enable $CC unreachable-code warning... " >&6; } +if test ${ac_cv_enable_unreachable_code_warning+y} +then : + printf %s "(cached) " >&6 +else $as_nop + + py_cflags=$CFLAGS + as_fn_append CFLAGS "-Wunreachable-code -Werror" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_enable_unreachable_code_warning=yes +else $as_nop + ac_cv_enable_unreachable_code_warning=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext CFLAGS=$py_cflags fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_enable_unreachable_code_warning" >&5 -$as_echo "$ac_cv_enable_unreachable_code_warning" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_enable_unreachable_code_warning" >&5 +printf "%s\n" "$ac_cv_enable_unreachable_code_warning" >&6; } # Don't enable unreachable code warning in debug mode, since it usually @@ -8580,11 +9863,12 @@ $as_echo "$ac_cv_enable_unreachable_code_warning" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can enable $CC strict-prototypes warning" >&5 -$as_echo_n "checking if we can enable $CC strict-prototypes warning... " >&6; } -if ${ac_cv_enable_strict_prototypes_warning+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if we can enable $CC strict-prototypes warning" >&5 +printf %s "checking if we can enable $CC strict-prototypes warning... " >&6; } +if test ${ac_cv_enable_strict_prototypes_warning+y} +then : + printf %s "(cached) " >&6 +else $as_nop py_cflags=$CFLAGS as_fn_append CFLAGS "-Wstrict-prototypes -Werror" @@ -8592,43 +9876,46 @@ else /* end confdefs.h. */ int -main () +main (void) { ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : ac_cv_enable_strict_prototypes_warning=yes -else +else $as_nop ac_cv_enable_strict_prototypes_warning=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext CFLAGS=$py_cflags fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_enable_strict_prototypes_warning" >&5 -$as_echo "$ac_cv_enable_strict_prototypes_warning" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_enable_strict_prototypes_warning" >&5 +printf "%s\n" "$ac_cv_enable_strict_prototypes_warning" >&6; } - if test "x$ac_cv_enable_strict_prototypes_warning" = xyes; then : + if test "x$ac_cv_enable_strict_prototypes_warning" = xyes +then : CFLAGS_NODIST="$CFLAGS_NODIST -Wstrict-prototypes" fi ac_save_cc="$CC" CC="$CC -Werror=implicit-function-declaration" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can make implicit function declaration an error in $CC" >&5 -$as_echo_n "checking if we can make implicit function declaration an error in $CC... " >&6; } -if ${ac_cv_enable_implicit_function_declaration_error+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if we can make implicit function declaration an error in $CC" >&5 +printf %s "checking if we can make implicit function declaration an error in $CC... " >&6; } +if test ${ac_cv_enable_implicit_function_declaration_error+y} +then : + printf %s "(cached) " >&6 +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int -main () +main (void) { ; @@ -8636,38 +9923,41 @@ main () } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : ac_cv_enable_implicit_function_declaration_error=yes -else +else $as_nop ac_cv_enable_implicit_function_declaration_error=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_enable_implicit_function_declaration_error" >&5 -$as_echo "$ac_cv_enable_implicit_function_declaration_error" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_enable_implicit_function_declaration_error" >&5 +printf "%s\n" "$ac_cv_enable_implicit_function_declaration_error" >&6; } CC="$ac_save_cc" - if test "x$ac_cv_enable_implicit_function_declaration_error" = xyes; then : + if test "x$ac_cv_enable_implicit_function_declaration_error" = xyes +then : CFLAGS_NODIST="$CFLAGS_NODIST -Werror=implicit-function-declaration" fi ac_save_cc="$CC" CC="$CC -fvisibility=hidden" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can use visibility in $CC" >&5 -$as_echo_n "checking if we can use visibility in $CC... " >&6; } -if ${ac_cv_enable_visibility+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if we can use visibility in $CC" >&5 +printf %s "checking if we can use visibility in $CC... " >&6; } +if test ${ac_cv_enable_visibility+y} +then : + printf %s "(cached) " >&6 +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int -main () +main (void) { ; @@ -8675,22 +9965,24 @@ main () } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : ac_cv_enable_visibility=yes -else +else $as_nop ac_cv_enable_visibility=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_enable_visibility" >&5 -$as_echo "$ac_cv_enable_visibility" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_enable_visibility" >&5 +printf "%s\n" "$ac_cv_enable_visibility" >&6; } CC="$ac_save_cc" - if test "x$ac_cv_enable_visibility" = xyes; then : + if test "x$ac_cv_enable_visibility" = xyes +then : CFLAGS_NODIST="$CFLAGS_NODIST -fvisibility=hidden" fi @@ -8713,8 +10005,8 @@ fi # used to be here, but non-Apple gcc doesn't accept them. if test "${CC}" = gcc then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking which compiler should be used" >&5 -$as_echo_n "checking which compiler should be used... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking which compiler should be used" >&5 +printf %s "checking which compiler should be used... " >&6; } case "${UNIVERSALSDK}" in */MacOSX10.4u.sdk) # Build using 10.4 SDK, force usage of gcc when the @@ -8724,8 +10016,8 @@ $as_echo_n "checking which compiler should be used... " >&6; } CPP=cpp-4.0 ;; esac - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +printf "%s\n" "$CC" >&6; } fi LIPO_INTEL64_FLAGS="" @@ -8802,8 +10094,8 @@ $as_echo "$CC" >&6; } # below to pick either 10.3, 10.4, or 10.5 as the target. # 4. If we are running on OS X 10.2 or earlier, good luck! - { $as_echo "$as_me:${as_lineno-$LINENO}: checking which MACOSX_DEPLOYMENT_TARGET to use" >&5 -$as_echo_n "checking which MACOSX_DEPLOYMENT_TARGET to use... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking which MACOSX_DEPLOYMENT_TARGET to use" >&5 +printf %s "checking which MACOSX_DEPLOYMENT_TARGET to use... " >&6; } cur_target_major=`sw_vers -productVersion | \ sed 's/\([0-9]*\)\.\([0-9]*\).*/\1/'` cur_target_minor=`sw_vers -productVersion | \ @@ -8840,32 +10132,33 @@ $as_echo_n "checking which MACOSX_DEPLOYMENT_TARGET to use... " >&6; } MACOSX_DEPLOYMENT_TARGET="$CONFIGURE_MACOSX_DEPLOYMENT_TARGET" export MACOSX_DEPLOYMENT_TARGET EXPORT_MACOSX_DEPLOYMENT_TARGET='' - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MACOSX_DEPLOYMENT_TARGET" >&5 -$as_echo "$MACOSX_DEPLOYMENT_TARGET" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MACOSX_DEPLOYMENT_TARGET" >&5 +printf "%s\n" "$MACOSX_DEPLOYMENT_TARGET" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if specified universal architectures work" >&5 -$as_echo_n "checking if specified universal architectures work... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if specified universal architectures work" >&5 +printf %s "checking if specified universal architectures work... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int -main () +main (void) { printf("%d", 42); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - { $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; } +if ac_fn_c_try_link "$LINENO" +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } as_fn_error $? "check config.log and use the '--with-universal-archs' option" "$LINENO" 5 fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext # end of Darwin* tests @@ -8886,6 +10179,9 @@ rm -f core conftest.err conftest.$ac_objext \ esac case "$CC" in +*mpicc*) + CFLAGS_NODIST="$CFLAGS_NODIST" + ;; *icc*) # ICC needs -fp-model strict or floats behave badly CFLAGS_NODIST="$CFLAGS_NODIST -fp-model strict" @@ -8911,14 +10207,16 @@ fi # complain if unaccepted options are passed (e.g. gcc on Mac OS X). # So we have to see first whether pthreads are available without # options before we can check whether -Kpthread improves anything. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads are available without options" >&5 -$as_echo_n "checking whether pthreads are available without options... " >&6; } -if ${ac_cv_pthread_is_default+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "$cross_compiling" = yes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether pthreads are available without options" >&5 +printf %s "checking whether pthreads are available without options... " >&6; } +if test ${ac_cv_pthread_is_default+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test "$cross_compiling" = yes +then : ac_cv_pthread_is_default=no -else +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -8936,13 +10234,14 @@ int main(void){ } _ACEOF -if ac_fn_c_try_run "$LINENO"; then : +if ac_fn_c_try_run "$LINENO" +then : ac_cv_pthread_is_default=yes ac_cv_kthread=no ac_cv_pthread=no -else +else $as_nop ac_cv_pthread_is_default=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -8951,8 +10250,8 @@ fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_pthread_is_default" >&5 -$as_echo "$ac_cv_pthread_is_default" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_pthread_is_default" >&5 +printf "%s\n" "$ac_cv_pthread_is_default" >&6; } if test $ac_cv_pthread_is_default = yes @@ -8964,16 +10263,18 @@ else # Some compilers won't report that they do not support -Kpthread, # so we need to run a program to see whether it really made the # function available. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -Kpthread" >&5 -$as_echo_n "checking whether $CC accepts -Kpthread... " >&6; } -if ${ac_cv_kpthread+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -Kpthread" >&5 +printf %s "checking whether $CC accepts -Kpthread... " >&6; } +if test ${ac_cv_kpthread+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_save_cc="$CC" CC="$CC -Kpthread" -if test "$cross_compiling" = yes; then : +if test "$cross_compiling" = yes +then : ac_cv_kpthread=no -else +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -8991,9 +10292,10 @@ int main(void){ } _ACEOF -if ac_fn_c_try_run "$LINENO"; then : +if ac_fn_c_try_run "$LINENO" +then : ac_cv_kpthread=yes -else +else $as_nop ac_cv_kpthread=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -9002,8 +10304,8 @@ fi CC="$ac_save_cc" fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_kpthread" >&5 -$as_echo "$ac_cv_kpthread" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_kpthread" >&5 +printf "%s\n" "$ac_cv_kpthread" >&6; } fi if test $ac_cv_kpthread = no -a $ac_cv_pthread_is_default = no @@ -9013,16 +10315,18 @@ then # Some compilers won't report that they do not support -Kthread, # so we need to run a program to see whether it really made the # function available. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -Kthread" >&5 -$as_echo_n "checking whether $CC accepts -Kthread... " >&6; } -if ${ac_cv_kthread+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -Kthread" >&5 +printf %s "checking whether $CC accepts -Kthread... " >&6; } +if test ${ac_cv_kthread+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_save_cc="$CC" CC="$CC -Kthread" -if test "$cross_compiling" = yes; then : +if test "$cross_compiling" = yes +then : ac_cv_kthread=no -else +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -9040,9 +10344,10 @@ int main(void){ } _ACEOF -if ac_fn_c_try_run "$LINENO"; then : +if ac_fn_c_try_run "$LINENO" +then : ac_cv_kthread=yes -else +else $as_nop ac_cv_kthread=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -9051,8 +10356,8 @@ fi CC="$ac_save_cc" fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_kthread" >&5 -$as_echo "$ac_cv_kthread" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_kthread" >&5 +printf "%s\n" "$ac_cv_kthread" >&6; } fi if test $ac_cv_kthread = no -a $ac_cv_pthread_is_default = no @@ -9062,16 +10367,18 @@ then # Some compilers won't report that they do not support -pthread, # so we need to run a program to see whether it really made the # function available. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -pthread" >&5 -$as_echo_n "checking whether $CC accepts -pthread... " >&6; } -if ${ac_cv_pthread+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -pthread" >&5 +printf %s "checking whether $CC accepts -pthread... " >&6; } +if test ${ac_cv_pthread+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_save_cc="$CC" CC="$CC -pthread" -if test "$cross_compiling" = yes; then : +if test "$cross_compiling" = yes +then : ac_cv_pthread=no -else +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -9089,9 +10396,10 @@ int main(void){ } _ACEOF -if ac_fn_c_try_run "$LINENO"; then : +if ac_fn_c_try_run "$LINENO" +then : ac_cv_pthread=yes -else +else $as_nop ac_cv_pthread=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -9100,18 +10408,21 @@ fi CC="$ac_save_cc" fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_pthread" >&5 -$as_echo "$ac_cv_pthread" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_pthread" >&5 +printf "%s\n" "$ac_cv_pthread" >&6; } fi # If we have set a CC compiler flag for thread support then # check if it works for CXX, too. -ac_cv_cxx_thread=no if test ! -z "$CXX" then -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX also accepts flags for thread support" >&5 -$as_echo_n "checking whether $CXX also accepts flags for thread support... " >&6; } -ac_save_cxx="$CXX" +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CXX also accepts flags for thread support" >&5 +printf %s "checking whether $CXX also accepts flags for thread support... " >&6; } +if test ${ac_cv_cxx_thread+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_save_cxx="$CXX" if test "$ac_cv_kpthread" = "yes" then @@ -9125,6 +10436,8 @@ elif test "$ac_cv_pthread" = "yes" then CXX="$CXX -pthread" ac_cv_cxx_thread=yes +else + ac_cv_cxx_thread=no fi if test $ac_cv_cxx_thread = yes @@ -9140,57 +10453,535 @@ then fi rm -fr conftest* fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_thread" >&5 -$as_echo "$ac_cv_cxx_thread" >&6; } -fi CXX="$ac_save_cxx" +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_thread" >&5 +printf "%s\n" "$ac_cv_cxx_thread" >&6; } +else + ac_cv_cxx_thread=no +fi -$as_echo "#define STDC_HEADERS 1" >>confdefs.h +printf "%s\n" "#define STDC_HEADERS 1" >>confdefs.h # checks for header files -for ac_header in \ - alloca.h asm/types.h bluetooth.h conio.h crypt.h direct.h dlfcn.h endian.h errno.h fcntl.h grp.h \ - ieeefp.h io.h langinfo.h libintl.h libutil.h linux/auxvec.h sys/auxv.h linux/memfd.h \ - linux/random.h linux/soundcard.h \ - linux/tipc.h linux/wait.h netdb.h netinet/in.h netpacket/packet.h poll.h process.h pthread.h pty.h \ - sched.h setjmp.h shadow.h signal.h spawn.h stropts.h sys/audioio.h sys/bsdtty.h sys/devpoll.h \ - sys/endian.h sys/epoll.h sys/event.h sys/eventfd.h sys/file.h sys/ioctl.h sys/kern_control.h \ - sys/loadavg.h sys/lock.h sys/memfd.h sys/mkdev.h sys/mman.h sys/modem.h sys/param.h sys/poll.h \ - sys/random.h sys/resource.h sys/select.h sys/sendfile.h sys/socket.h sys/soundcard.h sys/stat.h \ - sys/statvfs.h sys/sys_domain.h sys/syscall.h sys/sysmacros.h sys/termio.h sys/time.h sys/times.h \ - sys/types.h sys/uio.h sys/un.h sys/utsname.h sys/wait.h sys/xattr.h sysexits.h syslog.h \ - termios.h util.h utime.h utmp.h \ +ac_fn_c_check_header_compile "$LINENO" "alloca.h" "ac_cv_header_alloca_h" "$ac_includes_default" +if test "x$ac_cv_header_alloca_h" = xyes +then : + printf "%s\n" "#define HAVE_ALLOCA_H 1" >>confdefs.h -do : - as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" -if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF +fi +ac_fn_c_check_header_compile "$LINENO" "asm/types.h" "ac_cv_header_asm_types_h" "$ac_includes_default" +if test "x$ac_cv_header_asm_types_h" = xyes +then : + printf "%s\n" "#define HAVE_ASM_TYPES_H 1" >>confdefs.h fi +ac_fn_c_check_header_compile "$LINENO" "bluetooth.h" "ac_cv_header_bluetooth_h" "$ac_includes_default" +if test "x$ac_cv_header_bluetooth_h" = xyes +then : + printf "%s\n" "#define HAVE_BLUETOOTH_H 1" >>confdefs.h -done +fi +ac_fn_c_check_header_compile "$LINENO" "conio.h" "ac_cv_header_conio_h" "$ac_includes_default" +if test "x$ac_cv_header_conio_h" = xyes +then : + printf "%s\n" "#define HAVE_CONIO_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "crypt.h" "ac_cv_header_crypt_h" "$ac_includes_default" +if test "x$ac_cv_header_crypt_h" = xyes +then : + printf "%s\n" "#define HAVE_CRYPT_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "direct.h" "ac_cv_header_direct_h" "$ac_includes_default" +if test "x$ac_cv_header_direct_h" = xyes +then : + printf "%s\n" "#define HAVE_DIRECT_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default" +if test "x$ac_cv_header_dlfcn_h" = xyes +then : + printf "%s\n" "#define HAVE_DLFCN_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "endian.h" "ac_cv_header_endian_h" "$ac_includes_default" +if test "x$ac_cv_header_endian_h" = xyes +then : + printf "%s\n" "#define HAVE_ENDIAN_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "errno.h" "ac_cv_header_errno_h" "$ac_includes_default" +if test "x$ac_cv_header_errno_h" = xyes +then : + printf "%s\n" "#define HAVE_ERRNO_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "fcntl.h" "ac_cv_header_fcntl_h" "$ac_includes_default" +if test "x$ac_cv_header_fcntl_h" = xyes +then : + printf "%s\n" "#define HAVE_FCNTL_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "grp.h" "ac_cv_header_grp_h" "$ac_includes_default" +if test "x$ac_cv_header_grp_h" = xyes +then : + printf "%s\n" "#define HAVE_GRP_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "ieeefp.h" "ac_cv_header_ieeefp_h" "$ac_includes_default" +if test "x$ac_cv_header_ieeefp_h" = xyes +then : + printf "%s\n" "#define HAVE_IEEEFP_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "io.h" "ac_cv_header_io_h" "$ac_includes_default" +if test "x$ac_cv_header_io_h" = xyes +then : + printf "%s\n" "#define HAVE_IO_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "langinfo.h" "ac_cv_header_langinfo_h" "$ac_includes_default" +if test "x$ac_cv_header_langinfo_h" = xyes +then : + printf "%s\n" "#define HAVE_LANGINFO_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "libintl.h" "ac_cv_header_libintl_h" "$ac_includes_default" +if test "x$ac_cv_header_libintl_h" = xyes +then : + printf "%s\n" "#define HAVE_LIBINTL_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "libutil.h" "ac_cv_header_libutil_h" "$ac_includes_default" +if test "x$ac_cv_header_libutil_h" = xyes +then : + printf "%s\n" "#define HAVE_LIBUTIL_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "linux/auxvec.h" "ac_cv_header_linux_auxvec_h" "$ac_includes_default" +if test "x$ac_cv_header_linux_auxvec_h" = xyes +then : + printf "%s\n" "#define HAVE_LINUX_AUXVEC_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/auxv.h" "ac_cv_header_sys_auxv_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_auxv_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_AUXV_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "linux/fs.h" "ac_cv_header_linux_fs_h" "$ac_includes_default" +if test "x$ac_cv_header_linux_fs_h" = xyes +then : + printf "%s\n" "#define HAVE_LINUX_FS_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "linux/limits.h" "ac_cv_header_linux_limits_h" "$ac_includes_default" +if test "x$ac_cv_header_linux_limits_h" = xyes +then : + printf "%s\n" "#define HAVE_LINUX_LIMITS_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "linux/memfd.h" "ac_cv_header_linux_memfd_h" "$ac_includes_default" +if test "x$ac_cv_header_linux_memfd_h" = xyes +then : + printf "%s\n" "#define HAVE_LINUX_MEMFD_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "linux/random.h" "ac_cv_header_linux_random_h" "$ac_includes_default" +if test "x$ac_cv_header_linux_random_h" = xyes +then : + printf "%s\n" "#define HAVE_LINUX_RANDOM_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "linux/soundcard.h" "ac_cv_header_linux_soundcard_h" "$ac_includes_default" +if test "x$ac_cv_header_linux_soundcard_h" = xyes +then : + printf "%s\n" "#define HAVE_LINUX_SOUNDCARD_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "linux/tipc.h" "ac_cv_header_linux_tipc_h" "$ac_includes_default" +if test "x$ac_cv_header_linux_tipc_h" = xyes +then : + printf "%s\n" "#define HAVE_LINUX_TIPC_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "linux/wait.h" "ac_cv_header_linux_wait_h" "$ac_includes_default" +if test "x$ac_cv_header_linux_wait_h" = xyes +then : + printf "%s\n" "#define HAVE_LINUX_WAIT_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "netdb.h" "ac_cv_header_netdb_h" "$ac_includes_default" +if test "x$ac_cv_header_netdb_h" = xyes +then : + printf "%s\n" "#define HAVE_NETDB_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "net/ethernet.h" "ac_cv_header_net_ethernet_h" "$ac_includes_default" +if test "x$ac_cv_header_net_ethernet_h" = xyes +then : + printf "%s\n" "#define HAVE_NET_ETHERNET_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "netinet/in.h" "ac_cv_header_netinet_in_h" "$ac_includes_default" +if test "x$ac_cv_header_netinet_in_h" = xyes +then : + printf "%s\n" "#define HAVE_NETINET_IN_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "netpacket/packet.h" "ac_cv_header_netpacket_packet_h" "$ac_includes_default" +if test "x$ac_cv_header_netpacket_packet_h" = xyes +then : + printf "%s\n" "#define HAVE_NETPACKET_PACKET_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "poll.h" "ac_cv_header_poll_h" "$ac_includes_default" +if test "x$ac_cv_header_poll_h" = xyes +then : + printf "%s\n" "#define HAVE_POLL_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "process.h" "ac_cv_header_process_h" "$ac_includes_default" +if test "x$ac_cv_header_process_h" = xyes +then : + printf "%s\n" "#define HAVE_PROCESS_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "pthread.h" "ac_cv_header_pthread_h" "$ac_includes_default" +if test "x$ac_cv_header_pthread_h" = xyes +then : + printf "%s\n" "#define HAVE_PTHREAD_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "pty.h" "ac_cv_header_pty_h" "$ac_includes_default" +if test "x$ac_cv_header_pty_h" = xyes +then : + printf "%s\n" "#define HAVE_PTY_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sched.h" "ac_cv_header_sched_h" "$ac_includes_default" +if test "x$ac_cv_header_sched_h" = xyes +then : + printf "%s\n" "#define HAVE_SCHED_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "setjmp.h" "ac_cv_header_setjmp_h" "$ac_includes_default" +if test "x$ac_cv_header_setjmp_h" = xyes +then : + printf "%s\n" "#define HAVE_SETJMP_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "shadow.h" "ac_cv_header_shadow_h" "$ac_includes_default" +if test "x$ac_cv_header_shadow_h" = xyes +then : + printf "%s\n" "#define HAVE_SHADOW_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "signal.h" "ac_cv_header_signal_h" "$ac_includes_default" +if test "x$ac_cv_header_signal_h" = xyes +then : + printf "%s\n" "#define HAVE_SIGNAL_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "spawn.h" "ac_cv_header_spawn_h" "$ac_includes_default" +if test "x$ac_cv_header_spawn_h" = xyes +then : + printf "%s\n" "#define HAVE_SPAWN_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "stropts.h" "ac_cv_header_stropts_h" "$ac_includes_default" +if test "x$ac_cv_header_stropts_h" = xyes +then : + printf "%s\n" "#define HAVE_STROPTS_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/audioio.h" "ac_cv_header_sys_audioio_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_audioio_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_AUDIOIO_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/bsdtty.h" "ac_cv_header_sys_bsdtty_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_bsdtty_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_BSDTTY_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/devpoll.h" "ac_cv_header_sys_devpoll_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_devpoll_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_DEVPOLL_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/endian.h" "ac_cv_header_sys_endian_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_endian_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_ENDIAN_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/epoll.h" "ac_cv_header_sys_epoll_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_epoll_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_EPOLL_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/event.h" "ac_cv_header_sys_event_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_event_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_EVENT_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/eventfd.h" "ac_cv_header_sys_eventfd_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_eventfd_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_EVENTFD_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/file.h" "ac_cv_header_sys_file_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_file_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_FILE_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/ioctl.h" "ac_cv_header_sys_ioctl_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_ioctl_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_IOCTL_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/kern_control.h" "ac_cv_header_sys_kern_control_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_kern_control_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_KERN_CONTROL_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/loadavg.h" "ac_cv_header_sys_loadavg_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_loadavg_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_LOADAVG_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/lock.h" "ac_cv_header_sys_lock_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_lock_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_LOCK_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/memfd.h" "ac_cv_header_sys_memfd_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_memfd_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_MEMFD_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/mkdev.h" "ac_cv_header_sys_mkdev_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_mkdev_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_MKDEV_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/mman.h" "ac_cv_header_sys_mman_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_mman_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_MMAN_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/modem.h" "ac_cv_header_sys_modem_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_modem_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_MODEM_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/param.h" "ac_cv_header_sys_param_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_param_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_PARAM_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/poll.h" "ac_cv_header_sys_poll_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_poll_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_POLL_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/random.h" "ac_cv_header_sys_random_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_random_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_RANDOM_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/resource.h" "ac_cv_header_sys_resource_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_resource_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_RESOURCE_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/select.h" "ac_cv_header_sys_select_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_select_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_SELECT_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/sendfile.h" "ac_cv_header_sys_sendfile_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_sendfile_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_SENDFILE_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/socket.h" "ac_cv_header_sys_socket_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_socket_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_SOCKET_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/soundcard.h" "ac_cv_header_sys_soundcard_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_soundcard_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_SOUNDCARD_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/stat.h" "ac_cv_header_sys_stat_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_stat_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_STAT_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/statvfs.h" "ac_cv_header_sys_statvfs_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_statvfs_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_STATVFS_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/sys_domain.h" "ac_cv_header_sys_sys_domain_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_sys_domain_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_SYS_DOMAIN_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/syscall.h" "ac_cv_header_sys_syscall_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_syscall_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_SYSCALL_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/sysmacros.h" "ac_cv_header_sys_sysmacros_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_sysmacros_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_SYSMACROS_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/termio.h" "ac_cv_header_sys_termio_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_termio_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_TERMIO_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/time.h" "ac_cv_header_sys_time_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_time_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_TIME_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/times.h" "ac_cv_header_sys_times_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_times_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_TIMES_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/types.h" "ac_cv_header_sys_types_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_types_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_TYPES_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/uio.h" "ac_cv_header_sys_uio_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_uio_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_UIO_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/un.h" "ac_cv_header_sys_un_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_un_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_UN_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/utsname.h" "ac_cv_header_sys_utsname_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_utsname_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_UTSNAME_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/wait.h" "ac_cv_header_sys_wait_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_wait_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_WAIT_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sys/xattr.h" "ac_cv_header_sys_xattr_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_xattr_h" = xyes +then : + printf "%s\n" "#define HAVE_SYS_XATTR_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sysexits.h" "ac_cv_header_sysexits_h" "$ac_includes_default" +if test "x$ac_cv_header_sysexits_h" = xyes +then : + printf "%s\n" "#define HAVE_SYSEXITS_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "syslog.h" "ac_cv_header_syslog_h" "$ac_includes_default" +if test "x$ac_cv_header_syslog_h" = xyes +then : + printf "%s\n" "#define HAVE_SYSLOG_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "termios.h" "ac_cv_header_termios_h" "$ac_includes_default" +if test "x$ac_cv_header_termios_h" = xyes +then : + printf "%s\n" "#define HAVE_TERMIOS_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "util.h" "ac_cv_header_util_h" "$ac_includes_default" +if test "x$ac_cv_header_util_h" = xyes +then : + printf "%s\n" "#define HAVE_UTIL_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "utime.h" "ac_cv_header_utime_h" "$ac_includes_default" +if test "x$ac_cv_header_utime_h" = xyes +then : + printf "%s\n" "#define HAVE_UTIME_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "utmp.h" "ac_cv_header_utmp_h" "$ac_includes_default" +if test "x$ac_cv_header_utmp_h" = xyes +then : + printf "%s\n" "#define HAVE_UTMP_H 1" >>confdefs.h + +fi ac_header_dirent=no for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do - as_ac_Header=`$as_echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_hdr that defines DIR" >&5 -$as_echo_n "checking for $ac_hdr that defines DIR... " >&6; } -if eval \${$as_ac_Header+:} false; then : - $as_echo_n "(cached) " >&6 -else + as_ac_Header=`printf "%s\n" "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh` +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_hdr that defines DIR" >&5 +printf %s "checking for $ac_hdr that defines DIR... " >&6; } +if eval test \${$as_ac_Header+y} +then : + printf %s "(cached) " >&6 +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include <$ac_hdr> int -main () +main (void) { if ((DIR *) 0) return 0; @@ -9198,19 +10989,21 @@ return 0; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : eval "$as_ac_Header=yes" -else +else $as_nop eval "$as_ac_Header=no" fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi eval ac_res=\$$as_ac_Header - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +printf "%s\n" "$ac_res" >&6; } +if eval test \"x\$"$as_ac_Header"\" = x"yes" +then : cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_hdr" | $as_tr_cpp` 1 +#define `printf "%s\n" "HAVE_$ac_hdr" | $as_tr_cpp` 1 _ACEOF ac_header_dirent=$ac_hdr; break @@ -9219,11 +11012,12 @@ fi done # Two versions of opendir et al. are in -ldir and -lx on SCO Xenix. if test $ac_header_dirent = dirent.h; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5 -$as_echo_n "checking for library containing opendir... " >&6; } -if ${ac_cv_search_opendir+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5 +printf %s "checking for library containing opendir... " >&6; } +if test ${ac_cv_search_opendir+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -9231,56 +11025,59 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char opendir (); int -main () +main (void) { return opendir (); ; return 0; } _ACEOF -for ac_lib in '' dir; do +for ac_lib in '' dir +do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi - if ac_fn_c_try_link "$LINENO"; then : + if ac_fn_c_try_link "$LINENO" +then : ac_cv_search_opendir=$ac_res fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext - if ${ac_cv_search_opendir+:} false; then : + if test ${ac_cv_search_opendir+y} +then : break fi done -if ${ac_cv_search_opendir+:} false; then : +if test ${ac_cv_search_opendir+y} +then : -else +else $as_nop ac_cv_search_opendir=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5 -$as_echo "$ac_cv_search_opendir" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5 +printf "%s\n" "$ac_cv_search_opendir" >&6; } ac_res=$ac_cv_search_opendir -if test "$ac_res" != no; then : +if test "$ac_res" != no +then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5 -$as_echo_n "checking for library containing opendir... " >&6; } -if ${ac_cv_search_opendir+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5 +printf %s "checking for library containing opendir... " >&6; } +if test ${ac_cv_search_opendir+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -9288,100 +11085,72 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char opendir (); int -main () +main (void) { return opendir (); ; return 0; } _ACEOF -for ac_lib in '' x; do +for ac_lib in '' x +do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi - if ac_fn_c_try_link "$LINENO"; then : + if ac_fn_c_try_link "$LINENO" +then : ac_cv_search_opendir=$ac_res fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext - if ${ac_cv_search_opendir+:} false; then : + if test ${ac_cv_search_opendir+y} +then : break fi done -if ${ac_cv_search_opendir+:} false; then : +if test ${ac_cv_search_opendir+y} +then : -else +else $as_nop ac_cv_search_opendir=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5 -$as_echo "$ac_cv_search_opendir" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5 +printf "%s\n" "$ac_cv_search_opendir" >&6; } ac_res=$ac_cv_search_opendir -if test "$ac_res" != no; then : +if test "$ac_res" != no +then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether sys/types.h defines makedev" >&5 -$as_echo_n "checking whether sys/types.h defines makedev... " >&6; } -if ${ac_cv_header_sys_types_h_makedev+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -int -main () -{ -return makedev(0, 0); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_header_sys_types_h_makedev=yes -else - ac_cv_header_sys_types_h_makedev=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_sys_types_h_makedev" >&5 -$as_echo "$ac_cv_header_sys_types_h_makedev" >&6; } -if test $ac_cv_header_sys_types_h_makedev = no; then -ac_fn_c_check_header_mongrel "$LINENO" "sys/mkdev.h" "ac_cv_header_sys_mkdev_h" "$ac_includes_default" -if test "x$ac_cv_header_sys_mkdev_h" = xyes; then : +ac_fn_c_check_header_compile "$LINENO" "sys/mkdev.h" "ac_cv_header_sys_mkdev_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_mkdev_h" = xyes +then : -$as_echo "#define MAJOR_IN_MKDEV 1" >>confdefs.h +printf "%s\n" "#define MAJOR_IN_MKDEV 1" >>confdefs.h fi +if test $ac_cv_header_sys_mkdev_h = no; then + ac_fn_c_check_header_compile "$LINENO" "sys/sysmacros.h" "ac_cv_header_sys_sysmacros_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_sysmacros_h" = xyes +then : - - if test $ac_cv_header_sys_mkdev_h = no; then - ac_fn_c_check_header_mongrel "$LINENO" "sys/sysmacros.h" "ac_cv_header_sys_sysmacros_h" "$ac_includes_default" -if test "x$ac_cv_header_sys_sysmacros_h" = xyes; then : - -$as_echo "#define MAJOR_IN_SYSMACROS 1" >>confdefs.h +printf "%s\n" "#define MAJOR_IN_SYSMACROS 1" >>confdefs.h fi - - fi fi @@ -9389,24 +11158,17 @@ fi # http://permalink.gmane.org/gmane.linux.bluez.kernel/22294 SAVE_CFLAGS=$CFLAGS CFLAGS="-std=c99 $CFLAGS" -for ac_header in bluetooth/bluetooth.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "bluetooth/bluetooth.h" "ac_cv_header_bluetooth_bluetooth_h" "$ac_includes_default" -if test "x$ac_cv_header_bluetooth_bluetooth_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_BLUETOOTH_BLUETOOTH_H 1 -_ACEOF +ac_fn_c_check_header_compile "$LINENO" "bluetooth/bluetooth.h" "ac_cv_header_bluetooth_bluetooth_h" "$ac_includes_default" +if test "x$ac_cv_header_bluetooth_bluetooth_h" = xyes +then : + printf "%s\n" "#define HAVE_BLUETOOTH_BLUETOOTH_H 1" >>confdefs.h fi -done - CFLAGS=$SAVE_CFLAGS # On Darwin (OS X) net/if.h requires sys/socket.h to be imported first. -for ac_header in net/if.h -do : - ac_fn_c_check_header_compile "$LINENO" "net/if.h" "ac_cv_header_net_if_h" "#include +ac_fn_c_check_header_compile "$LINENO" "net/if.h" "ac_cv_header_net_if_h" "#include #include #include #ifdef HAVE_SYS_SOCKET_H @@ -9414,20 +11176,15 @@ do : #endif " -if test "x$ac_cv_header_net_if_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_NET_IF_H 1 -_ACEOF +if test "x$ac_cv_header_net_if_h" = xyes +then : + printf "%s\n" "#define HAVE_NET_IF_H 1" >>confdefs.h fi -done - # On Linux, netlink.h requires asm/types.h -for ac_header in linux/netlink.h -do : - ac_fn_c_check_header_compile "$LINENO" "linux/netlink.h" "ac_cv_header_linux_netlink_h" " +ac_fn_c_check_header_compile "$LINENO" "linux/netlink.h" "ac_cv_header_linux_netlink_h" " #ifdef HAVE_ASM_TYPES_H #include #endif @@ -9436,20 +11193,15 @@ do : #endif " -if test "x$ac_cv_header_linux_netlink_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LINUX_NETLINK_H 1 -_ACEOF +if test "x$ac_cv_header_linux_netlink_h" = xyes +then : + printf "%s\n" "#define HAVE_LINUX_NETLINK_H 1" >>confdefs.h fi -done - # On Linux, qrtr.h requires asm/types.h -for ac_header in linux/qrtr.h -do : - ac_fn_c_check_header_compile "$LINENO" "linux/qrtr.h" "ac_cv_header_linux_qrtr_h" " +ac_fn_c_check_header_compile "$LINENO" "linux/qrtr.h" "ac_cv_header_linux_qrtr_h" " #ifdef HAVE_ASM_TYPES_H #include #endif @@ -9458,61 +11210,93 @@ do : #endif " -if test "x$ac_cv_header_linux_qrtr_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LINUX_QRTR_H 1 -_ACEOF +if test "x$ac_cv_header_linux_qrtr_h" = xyes +then : + printf "%s\n" "#define HAVE_LINUX_QRTR_H 1" >>confdefs.h fi -done - -for ac_header in linux/vm_sockets.h -do : - ac_fn_c_check_header_compile "$LINENO" "linux/vm_sockets.h" "ac_cv_header_linux_vm_sockets_h" " +ac_fn_c_check_header_compile "$LINENO" "linux/vm_sockets.h" "ac_cv_header_linux_vm_sockets_h" " #ifdef HAVE_SYS_SOCKET_H #include #endif " -if test "x$ac_cv_header_linux_vm_sockets_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LINUX_VM_SOCKETS_H 1 -_ACEOF +if test "x$ac_cv_header_linux_vm_sockets_h" = xyes +then : + printf "%s\n" "#define HAVE_LINUX_VM_SOCKETS_H 1" >>confdefs.h fi -done - # On Linux, can.h, can/bcm.h, can/j1939.h, can/raw.h require sys/socket.h # On NetBSD, netcan/can.h requires sys/socket.h -for ac_header in linux/can.h linux/can/bcm.h linux/can/j1939.h linux/can/raw.h netcan/can.h -do : - as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" " +ac_fn_c_check_header_compile "$LINENO" "linux/can.h" "ac_cv_header_linux_can_h" " #ifdef HAVE_SYS_SOCKET_H #include #endif " -if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF +if test "x$ac_cv_header_linux_can_h" = xyes +then : + printf "%s\n" "#define HAVE_LINUX_CAN_H 1" >>confdefs.h fi +ac_fn_c_check_header_compile "$LINENO" "linux/can/bcm.h" "ac_cv_header_linux_can_bcm_h" " +#ifdef HAVE_SYS_SOCKET_H +#include +#endif -done +" +if test "x$ac_cv_header_linux_can_bcm_h" = xyes +then : + printf "%s\n" "#define HAVE_LINUX_CAN_BCM_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "linux/can/j1939.h" "ac_cv_header_linux_can_j1939_h" " +#ifdef HAVE_SYS_SOCKET_H +#include +#endif + +" +if test "x$ac_cv_header_linux_can_j1939_h" = xyes +then : + printf "%s\n" "#define HAVE_LINUX_CAN_J1939_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "linux/can/raw.h" "ac_cv_header_linux_can_raw_h" " +#ifdef HAVE_SYS_SOCKET_H +#include +#endif + +" +if test "x$ac_cv_header_linux_can_raw_h" = xyes +then : + printf "%s\n" "#define HAVE_LINUX_CAN_RAW_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "netcan/can.h" "ac_cv_header_netcan_can_h" " +#ifdef HAVE_SYS_SOCKET_H +#include +#endif + +" +if test "x$ac_cv_header_netcan_can_h" = xyes +then : + printf "%s\n" "#define HAVE_NETCAN_CAN_H 1" >>confdefs.h + +fi # checks for typedefs -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for clock_t in time.h" >&5 -$as_echo_n "checking for clock_t in time.h... " >&6; } -if ${ac_cv_clock_t_time_h+:} false; then : - $as_echo_n "(cached) " >&6 -else + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for clock_t in time.h" >&5 +printf %s "checking for clock_t in time.h... " >&6; } +if test ${ac_cv_clock_t_time_h+y} +then : + printf %s "(cached) " >&6 +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -9520,30 +11304,33 @@ else _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "clock_t" >/dev/null 2>&1; then : + $EGREP "clock_t" >/dev/null 2>&1 +then : ac_cv_clock_t_time_h=yes -else +else $as_nop ac_cv_clock_t_time_h=no fi -rm -f conftest* +rm -rf conftest* fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_clock_t_time_h" >&5 -$as_echo "$ac_cv_clock_t_time_h" >&6; } -if test "x$ac_cv_clock_t_time_h" = xno; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_clock_t_time_h" >&5 +printf "%s\n" "$ac_cv_clock_t_time_h" >&6; } +if test "x$ac_cv_clock_t_time_h" = xno +then : -$as_echo "#define clock_t long" >>confdefs.h +printf "%s\n" "#define clock_t long" >>confdefs.h fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for makedev" >&5 -$as_echo_n "checking for makedev... " >&6; } -if ${ac_cv_func_makedev+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for makedev" >&5 +printf %s "checking for makedev... " >&6; } +if test ${ac_cv_func_makedev+y} +then : + printf %s "(cached) " >&6 +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -9557,7 +11344,7 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext #endif int -main () +main (void) { makedev(0, 0) @@ -9566,32 +11353,35 @@ main () } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_func_makedev=yes -else +else $as_nop ac_cv_func_makedev=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_makedev" >&5 -$as_echo "$ac_cv_func_makedev" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_makedev" >&5 +printf "%s\n" "$ac_cv_func_makedev" >&6; } -if test "x$ac_cv_func_makedev" = xyes; then : +if test "x$ac_cv_func_makedev" = xyes +then : -$as_echo "#define HAVE_MAKEDEV 1" >>confdefs.h +printf "%s\n" "#define HAVE_MAKEDEV 1" >>confdefs.h fi # byte swapping -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for le64toh" >&5 -$as_echo_n "checking for le64toh... " >&6; } -if ${ac_cv_func_le64toh+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for le64toh" >&5 +printf %s "checking for le64toh... " >&6; } +if test ${ac_cv_func_le64toh+y} +then : + printf %s "(cached) " >&6 +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -9603,7 +11393,7 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext #endif int -main () +main (void) { le64toh(1) @@ -9612,22 +11402,24 @@ main () } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_func_le64toh=yes -else +else $as_nop ac_cv_func_le64toh=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_le64toh" >&5 -$as_echo "$ac_cv_func_le64toh" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_le64toh" >&5 +printf "%s\n" "$ac_cv_func_le64toh" >&6; } -if test "x$ac_cv_func_le64toh" = xyes; then : +if test "x$ac_cv_func_le64toh" = xyes +then : -$as_echo "#define HAVE_HTOLE64 1" >>confdefs.h +printf "%s\n" "#define HAVE_HTOLE64 1" >>confdefs.h fi @@ -9644,15 +11436,15 @@ if test "$use_lfs" = "yes"; then case $ac_sys_system/$ac_sys_release in AIX*) -$as_echo "#define _LARGE_FILES 1" >>confdefs.h +printf "%s\n" "#define _LARGE_FILES 1" >>confdefs.h ;; esac -$as_echo "#define _LARGEFILE_SOURCE 1" >>confdefs.h +printf "%s\n" "#define _LARGEFILE_SOURCE 1" >>confdefs.h -$as_echo "#define _FILE_OFFSET_BITS 64" >>confdefs.h +printf "%s\n" "#define _FILE_OFFSET_BITS 64" >>confdefs.h fi @@ -9665,96 +11457,121 @@ EOF # Type availability checks ac_fn_c_check_type "$LINENO" "mode_t" "ac_cv_type_mode_t" "$ac_includes_default" -if test "x$ac_cv_type_mode_t" = xyes; then : +if test "x$ac_cv_type_mode_t" = xyes +then : -else +else $as_nop -cat >>confdefs.h <<_ACEOF -#define mode_t int -_ACEOF +printf "%s\n" "#define mode_t int" >>confdefs.h fi ac_fn_c_check_type "$LINENO" "off_t" "ac_cv_type_off_t" "$ac_includes_default" -if test "x$ac_cv_type_off_t" = xyes; then : +if test "x$ac_cv_type_off_t" = xyes +then : -else +else $as_nop -cat >>confdefs.h <<_ACEOF -#define off_t long int -_ACEOF +printf "%s\n" "#define off_t long int" >>confdefs.h fi -ac_fn_c_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default" -if test "x$ac_cv_type_pid_t" = xyes; then : -else + ac_fn_c_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default +" +if test "x$ac_cv_type_pid_t" = xyes +then : + +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #if defined _WIN64 && !defined __CYGWIN__ + LLP64 + #endif + +int +main (void) +{ + + ; + return 0; +} -cat >>confdefs.h <<_ACEOF -#define pid_t int _ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_pid_type='int' +else $as_nop + ac_pid_type='__int64' +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +printf "%s\n" "#define pid_t $ac_pid_type" >>confdefs.h + fi -cat >>confdefs.h <<_ACEOF -#define RETSIGTYPE void -_ACEOF + +printf "%s\n" "#define RETSIGTYPE void" >>confdefs.h ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" -if test "x$ac_cv_type_size_t" = xyes; then : +if test "x$ac_cv_type_size_t" = xyes +then : -else +else $as_nop -cat >>confdefs.h <<_ACEOF -#define size_t unsigned int -_ACEOF +printf "%s\n" "#define size_t unsigned int" >>confdefs.h fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for uid_t in sys/types.h" >&5 -$as_echo_n "checking for uid_t in sys/types.h... " >&6; } -if ${ac_cv_type_uid_t+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for uid_t in sys/types.h" >&5 +printf %s "checking for uid_t in sys/types.h... " >&6; } +if test ${ac_cv_type_uid_t+y} +then : + printf %s "(cached) " >&6 +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "uid_t" >/dev/null 2>&1; then : + $EGREP "uid_t" >/dev/null 2>&1 +then : ac_cv_type_uid_t=yes -else +else $as_nop ac_cv_type_uid_t=no fi -rm -f conftest* +rm -rf conftest* fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_uid_t" >&5 -$as_echo "$ac_cv_type_uid_t" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_uid_t" >&5 +printf "%s\n" "$ac_cv_type_uid_t" >&6; } if test $ac_cv_type_uid_t = no; then -$as_echo "#define uid_t int" >>confdefs.h +printf "%s\n" "#define uid_t int" >>confdefs.h -$as_echo "#define gid_t int" >>confdefs.h +printf "%s\n" "#define gid_t int" >>confdefs.h fi ac_fn_c_check_type "$LINENO" "ssize_t" "ac_cv_type_ssize_t" "$ac_includes_default" -if test "x$ac_cv_type_ssize_t" = xyes; then : +if test "x$ac_cv_type_ssize_t" = xyes +then : -$as_echo "#define HAVE_SSIZE_T 1" >>confdefs.h +printf "%s\n" "#define HAVE_SSIZE_T 1" >>confdefs.h fi ac_fn_c_check_type "$LINENO" "__uint128_t" "ac_cv_type___uint128_t" "$ac_includes_default" -if test "x$ac_cv_type___uint128_t" = xyes; then : +if test "x$ac_cv_type___uint128_t" = xyes +then : -$as_echo "#define HAVE_GCC_UINT128_T 1" >>confdefs.h +printf "%s\n" "#define HAVE_GCC_UINT128_T 1" >>confdefs.h fi @@ -9765,17 +11582,19 @@ fi # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of int" >&5 -$as_echo_n "checking size of int... " >&6; } -if ${ac_cv_sizeof_int+:} false; then : - $as_echo_n "(cached) " >&6 -else - if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (int))" "ac_cv_sizeof_int" "$ac_includes_default"; then : - -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of int" >&5 +printf %s "checking size of int... " >&6; } +if test ${ac_cv_sizeof_int+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (int))" "ac_cv_sizeof_int" "$ac_includes_default" +then : + +else $as_nop if test "$ac_cv_type_int" = yes; then - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (int) See \`config.log' for more details" "$LINENO" 5; } else @@ -9784,31 +11603,31 @@ See \`config.log' for more details" "$LINENO" 5; } fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_int" >&5 -$as_echo "$ac_cv_sizeof_int" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_int" >&5 +printf "%s\n" "$ac_cv_sizeof_int" >&6; } -cat >>confdefs.h <<_ACEOF -#define SIZEOF_INT $ac_cv_sizeof_int -_ACEOF +printf "%s\n" "#define SIZEOF_INT $ac_cv_sizeof_int" >>confdefs.h # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long" >&5 -$as_echo_n "checking size of long... " >&6; } -if ${ac_cv_sizeof_long+:} false; then : - $as_echo_n "(cached) " >&6 -else - if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long))" "ac_cv_sizeof_long" "$ac_includes_default"; then : - -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of long" >&5 +printf %s "checking size of long... " >&6; } +if test ${ac_cv_sizeof_long+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long))" "ac_cv_sizeof_long" "$ac_includes_default" +then : + +else $as_nop if test "$ac_cv_type_long" = yes; then - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (long) See \`config.log' for more details" "$LINENO" 5; } else @@ -9817,33 +11636,30 @@ See \`config.log' for more details" "$LINENO" 5; } fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long" >&5 -$as_echo "$ac_cv_sizeof_long" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long" >&5 +printf "%s\n" "$ac_cv_sizeof_long" >&6; } -cat >>confdefs.h <<_ACEOF -#define SIZEOF_LONG $ac_cv_sizeof_long -_ACEOF +printf "%s\n" "#define SIZEOF_LONG $ac_cv_sizeof_long" >>confdefs.h # The cast to long int works around a bug in the HP C Compiler, # see AC_CHECK_SIZEOF for more information. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking alignment of long" >&5 -$as_echo_n "checking alignment of long... " >&6; } -if ${ac_cv_alignof_long+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking alignment of long" >&5 +printf %s "checking alignment of long... " >&6; } +if test ${ac_cv_alignof_long+y} +then : + printf %s "(cached) " >&6 +else $as_nop if ac_fn_c_compute_int "$LINENO" "(long int) offsetof (ac__type_alignof_, y)" "ac_cv_alignof_long" "$ac_includes_default -#ifndef offsetof -# define offsetof(type, member) ((char *) &((type *) 0)->member - (char *) 0) -#endif -typedef struct { char x; long y; } ac__type_alignof_;"; then : +typedef struct { char x; long y; } ac__type_alignof_;" +then : -else +else $as_nop if test "$ac_cv_type_long" = yes; then - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute alignment of long See \`config.log' for more details" "$LINENO" 5; } else @@ -9852,31 +11668,31 @@ See \`config.log' for more details" "$LINENO" 5; } fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_alignof_long" >&5 -$as_echo "$ac_cv_alignof_long" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_alignof_long" >&5 +printf "%s\n" "$ac_cv_alignof_long" >&6; } -cat >>confdefs.h <<_ACEOF -#define ALIGNOF_LONG $ac_cv_alignof_long -_ACEOF +printf "%s\n" "#define ALIGNOF_LONG $ac_cv_alignof_long" >>confdefs.h # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long long" >&5 -$as_echo_n "checking size of long long... " >&6; } -if ${ac_cv_sizeof_long_long+:} false; then : - $as_echo_n "(cached) " >&6 -else - if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long long))" "ac_cv_sizeof_long_long" "$ac_includes_default"; then : - -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of long long" >&5 +printf %s "checking size of long long... " >&6; } +if test ${ac_cv_sizeof_long_long+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long long))" "ac_cv_sizeof_long_long" "$ac_includes_default" +then : + +else $as_nop if test "$ac_cv_type_long_long" = yes; then - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (long long) See \`config.log' for more details" "$LINENO" 5; } else @@ -9885,31 +11701,31 @@ See \`config.log' for more details" "$LINENO" 5; } fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long_long" >&5 -$as_echo "$ac_cv_sizeof_long_long" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long_long" >&5 +printf "%s\n" "$ac_cv_sizeof_long_long" >&6; } -cat >>confdefs.h <<_ACEOF -#define SIZEOF_LONG_LONG $ac_cv_sizeof_long_long -_ACEOF +printf "%s\n" "#define SIZEOF_LONG_LONG $ac_cv_sizeof_long_long" >>confdefs.h # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of void *" >&5 -$as_echo_n "checking size of void *... " >&6; } -if ${ac_cv_sizeof_void_p+:} false; then : - $as_echo_n "(cached) " >&6 -else - if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (void *))" "ac_cv_sizeof_void_p" "$ac_includes_default"; then : - -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of void *" >&5 +printf %s "checking size of void *... " >&6; } +if test ${ac_cv_sizeof_void_p+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (void *))" "ac_cv_sizeof_void_p" "$ac_includes_default" +then : + +else $as_nop if test "$ac_cv_type_void_p" = yes; then - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (void *) See \`config.log' for more details" "$LINENO" 5; } else @@ -9918,31 +11734,31 @@ See \`config.log' for more details" "$LINENO" 5; } fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_void_p" >&5 -$as_echo "$ac_cv_sizeof_void_p" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_void_p" >&5 +printf "%s\n" "$ac_cv_sizeof_void_p" >&6; } -cat >>confdefs.h <<_ACEOF -#define SIZEOF_VOID_P $ac_cv_sizeof_void_p -_ACEOF +printf "%s\n" "#define SIZEOF_VOID_P $ac_cv_sizeof_void_p" >>confdefs.h # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of short" >&5 -$as_echo_n "checking size of short... " >&6; } -if ${ac_cv_sizeof_short+:} false; then : - $as_echo_n "(cached) " >&6 -else - if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (short))" "ac_cv_sizeof_short" "$ac_includes_default"; then : - -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of short" >&5 +printf %s "checking size of short... " >&6; } +if test ${ac_cv_sizeof_short+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (short))" "ac_cv_sizeof_short" "$ac_includes_default" +then : + +else $as_nop if test "$ac_cv_type_short" = yes; then - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (short) See \`config.log' for more details" "$LINENO" 5; } else @@ -9951,31 +11767,31 @@ See \`config.log' for more details" "$LINENO" 5; } fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_short" >&5 -$as_echo "$ac_cv_sizeof_short" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_short" >&5 +printf "%s\n" "$ac_cv_sizeof_short" >&6; } -cat >>confdefs.h <<_ACEOF -#define SIZEOF_SHORT $ac_cv_sizeof_short -_ACEOF +printf "%s\n" "#define SIZEOF_SHORT $ac_cv_sizeof_short" >>confdefs.h # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of float" >&5 -$as_echo_n "checking size of float... " >&6; } -if ${ac_cv_sizeof_float+:} false; then : - $as_echo_n "(cached) " >&6 -else - if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (float))" "ac_cv_sizeof_float" "$ac_includes_default"; then : - -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of float" >&5 +printf %s "checking size of float... " >&6; } +if test ${ac_cv_sizeof_float+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (float))" "ac_cv_sizeof_float" "$ac_includes_default" +then : + +else $as_nop if test "$ac_cv_type_float" = yes; then - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (float) See \`config.log' for more details" "$LINENO" 5; } else @@ -9984,31 +11800,31 @@ See \`config.log' for more details" "$LINENO" 5; } fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_float" >&5 -$as_echo "$ac_cv_sizeof_float" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_float" >&5 +printf "%s\n" "$ac_cv_sizeof_float" >&6; } -cat >>confdefs.h <<_ACEOF -#define SIZEOF_FLOAT $ac_cv_sizeof_float -_ACEOF +printf "%s\n" "#define SIZEOF_FLOAT $ac_cv_sizeof_float" >>confdefs.h # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of double" >&5 -$as_echo_n "checking size of double... " >&6; } -if ${ac_cv_sizeof_double+:} false; then : - $as_echo_n "(cached) " >&6 -else - if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (double))" "ac_cv_sizeof_double" "$ac_includes_default"; then : - -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of double" >&5 +printf %s "checking size of double... " >&6; } +if test ${ac_cv_sizeof_double+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (double))" "ac_cv_sizeof_double" "$ac_includes_default" +then : + +else $as_nop if test "$ac_cv_type_double" = yes; then - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (double) See \`config.log' for more details" "$LINENO" 5; } else @@ -10017,31 +11833,31 @@ See \`config.log' for more details" "$LINENO" 5; } fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_double" >&5 -$as_echo "$ac_cv_sizeof_double" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_double" >&5 +printf "%s\n" "$ac_cv_sizeof_double" >&6; } -cat >>confdefs.h <<_ACEOF -#define SIZEOF_DOUBLE $ac_cv_sizeof_double -_ACEOF +printf "%s\n" "#define SIZEOF_DOUBLE $ac_cv_sizeof_double" >>confdefs.h # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of fpos_t" >&5 -$as_echo_n "checking size of fpos_t... " >&6; } -if ${ac_cv_sizeof_fpos_t+:} false; then : - $as_echo_n "(cached) " >&6 -else - if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (fpos_t))" "ac_cv_sizeof_fpos_t" "$ac_includes_default"; then : - -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of fpos_t" >&5 +printf %s "checking size of fpos_t... " >&6; } +if test ${ac_cv_sizeof_fpos_t+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (fpos_t))" "ac_cv_sizeof_fpos_t" "$ac_includes_default" +then : + +else $as_nop if test "$ac_cv_type_fpos_t" = yes; then - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (fpos_t) See \`config.log' for more details" "$LINENO" 5; } else @@ -10050,31 +11866,31 @@ See \`config.log' for more details" "$LINENO" 5; } fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_fpos_t" >&5 -$as_echo "$ac_cv_sizeof_fpos_t" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_fpos_t" >&5 +printf "%s\n" "$ac_cv_sizeof_fpos_t" >&6; } -cat >>confdefs.h <<_ACEOF -#define SIZEOF_FPOS_T $ac_cv_sizeof_fpos_t -_ACEOF +printf "%s\n" "#define SIZEOF_FPOS_T $ac_cv_sizeof_fpos_t" >>confdefs.h # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of size_t" >&5 -$as_echo_n "checking size of size_t... " >&6; } -if ${ac_cv_sizeof_size_t+:} false; then : - $as_echo_n "(cached) " >&6 -else - if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (size_t))" "ac_cv_sizeof_size_t" "$ac_includes_default"; then : - -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of size_t" >&5 +printf %s "checking size of size_t... " >&6; } +if test ${ac_cv_sizeof_size_t+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (size_t))" "ac_cv_sizeof_size_t" "$ac_includes_default" +then : + +else $as_nop if test "$ac_cv_type_size_t" = yes; then - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (size_t) See \`config.log' for more details" "$LINENO" 5; } else @@ -10083,33 +11899,30 @@ See \`config.log' for more details" "$LINENO" 5; } fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_size_t" >&5 -$as_echo "$ac_cv_sizeof_size_t" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_size_t" >&5 +printf "%s\n" "$ac_cv_sizeof_size_t" >&6; } -cat >>confdefs.h <<_ACEOF -#define SIZEOF_SIZE_T $ac_cv_sizeof_size_t -_ACEOF +printf "%s\n" "#define SIZEOF_SIZE_T $ac_cv_sizeof_size_t" >>confdefs.h # The cast to long int works around a bug in the HP C Compiler, # see AC_CHECK_SIZEOF for more information. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking alignment of size_t" >&5 -$as_echo_n "checking alignment of size_t... " >&6; } -if ${ac_cv_alignof_size_t+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking alignment of size_t" >&5 +printf %s "checking alignment of size_t... " >&6; } +if test ${ac_cv_alignof_size_t+y} +then : + printf %s "(cached) " >&6 +else $as_nop if ac_fn_c_compute_int "$LINENO" "(long int) offsetof (ac__type_alignof_, y)" "ac_cv_alignof_size_t" "$ac_includes_default -#ifndef offsetof -# define offsetof(type, member) ((char *) &((type *) 0)->member - (char *) 0) -#endif -typedef struct { char x; size_t y; } ac__type_alignof_;"; then : +typedef struct { char x; size_t y; } ac__type_alignof_;" +then : -else +else $as_nop if test "$ac_cv_type_size_t" = yes; then - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute alignment of size_t See \`config.log' for more details" "$LINENO" 5; } else @@ -10118,31 +11931,31 @@ See \`config.log' for more details" "$LINENO" 5; } fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_alignof_size_t" >&5 -$as_echo "$ac_cv_alignof_size_t" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_alignof_size_t" >&5 +printf "%s\n" "$ac_cv_alignof_size_t" >&6; } -cat >>confdefs.h <<_ACEOF -#define ALIGNOF_SIZE_T $ac_cv_alignof_size_t -_ACEOF +printf "%s\n" "#define ALIGNOF_SIZE_T $ac_cv_alignof_size_t" >>confdefs.h # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of pid_t" >&5 -$as_echo_n "checking size of pid_t... " >&6; } -if ${ac_cv_sizeof_pid_t+:} false; then : - $as_echo_n "(cached) " >&6 -else - if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (pid_t))" "ac_cv_sizeof_pid_t" "$ac_includes_default"; then : - -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of pid_t" >&5 +printf %s "checking size of pid_t... " >&6; } +if test ${ac_cv_sizeof_pid_t+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (pid_t))" "ac_cv_sizeof_pid_t" "$ac_includes_default" +then : + +else $as_nop if test "$ac_cv_type_pid_t" = yes; then - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (pid_t) See \`config.log' for more details" "$LINENO" 5; } else @@ -10151,31 +11964,31 @@ See \`config.log' for more details" "$LINENO" 5; } fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_pid_t" >&5 -$as_echo "$ac_cv_sizeof_pid_t" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_pid_t" >&5 +printf "%s\n" "$ac_cv_sizeof_pid_t" >&6; } -cat >>confdefs.h <<_ACEOF -#define SIZEOF_PID_T $ac_cv_sizeof_pid_t -_ACEOF +printf "%s\n" "#define SIZEOF_PID_T $ac_cv_sizeof_pid_t" >>confdefs.h # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of uintptr_t" >&5 -$as_echo_n "checking size of uintptr_t... " >&6; } -if ${ac_cv_sizeof_uintptr_t+:} false; then : - $as_echo_n "(cached) " >&6 -else - if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (uintptr_t))" "ac_cv_sizeof_uintptr_t" "$ac_includes_default"; then : - -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of uintptr_t" >&5 +printf %s "checking size of uintptr_t... " >&6; } +if test ${ac_cv_sizeof_uintptr_t+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (uintptr_t))" "ac_cv_sizeof_uintptr_t" "$ac_includes_default" +then : + +else $as_nop if test "$ac_cv_type_uintptr_t" = yes; then - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (uintptr_t) See \`config.log' for more details" "$LINENO" 5; } else @@ -10184,23 +11997,54 @@ See \`config.log' for more details" "$LINENO" 5; } fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_uintptr_t" >&5 -$as_echo "$ac_cv_sizeof_uintptr_t" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_uintptr_t" >&5 +printf "%s\n" "$ac_cv_sizeof_uintptr_t" >&6; } -cat >>confdefs.h <<_ACEOF -#define SIZEOF_UINTPTR_T $ac_cv_sizeof_uintptr_t -_ACEOF +printf "%s\n" "#define SIZEOF_UINTPTR_T $ac_cv_sizeof_uintptr_t" >>confdefs.h + + +# The cast to long int works around a bug in the HP C Compiler, +# see AC_CHECK_SIZEOF for more information. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking alignment of max_align_t" >&5 +printf %s "checking alignment of max_align_t... " >&6; } +if test ${ac_cv_alignof_max_align_t+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if ac_fn_c_compute_int "$LINENO" "(long int) offsetof (ac__type_alignof_, y)" "ac_cv_alignof_max_align_t" "$ac_includes_default +typedef struct { char x; max_align_t y; } ac__type_alignof_;" +then : + +else $as_nop + if test "$ac_cv_type_max_align_t" = yes; then + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute alignment of max_align_t +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_alignof_max_align_t=0 + fi +fi + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_alignof_max_align_t" >&5 +printf "%s\n" "$ac_cv_alignof_max_align_t" >&6; } +printf "%s\n" "#define ALIGNOF_MAX_ALIGN_T $ac_cv_alignof_max_align_t" >>confdefs.h - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for long double" >&5 -$as_echo_n "checking for long double... " >&6; } -if ${ac_cv_type_long_double+:} false; then : - $as_echo_n "(cached) " >&6 -else + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for long double" >&5 +printf %s "checking for long double... " >&6; } +if test ${ac_cv_type_long_double+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test "$GCC" = yes; then ac_cv_type_long_double=yes else @@ -10210,7 +12054,7 @@ else not support it. */ long double foo = 0.0L; int -main () +main (void) { static int test_array [1 - 2 * !(/* On Ultrix 4.3 cc, long double is 4 and double is 8. */ sizeof (double) <= sizeof (long double))]; @@ -10221,19 +12065,20 @@ return test_array [0]; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : ac_cv_type_long_double=yes -else +else $as_nop ac_cv_type_long_double=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_long_double" >&5 -$as_echo "$ac_cv_type_long_double" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_long_double" >&5 +printf "%s\n" "$ac_cv_type_long_double" >&6; } if test $ac_cv_type_long_double = yes; then -$as_echo "#define HAVE_LONG_DOUBLE 1" >>confdefs.h +printf "%s\n" "#define HAVE_LONG_DOUBLE 1" >>confdefs.h fi @@ -10241,17 +12086,19 @@ $as_echo "#define HAVE_LONG_DOUBLE 1" >>confdefs.h # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long double" >&5 -$as_echo_n "checking size of long double... " >&6; } -if ${ac_cv_sizeof_long_double+:} false; then : - $as_echo_n "(cached) " >&6 -else - if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long double))" "ac_cv_sizeof_long_double" "$ac_includes_default"; then : - -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of long double" >&5 +printf %s "checking size of long double... " >&6; } +if test ${ac_cv_sizeof_long_double+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long double))" "ac_cv_sizeof_long_double" "$ac_includes_default" +then : + +else $as_nop if test "$ac_cv_type_long_double" = yes; then - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (long double) See \`config.log' for more details" "$LINENO" 5; } else @@ -10260,14 +12107,12 @@ See \`config.log' for more details" "$LINENO" 5; } fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long_double" >&5 -$as_echo "$ac_cv_sizeof_long_double" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long_double" >&5 +printf "%s\n" "$ac_cv_sizeof_long_double" >&6; } -cat >>confdefs.h <<_ACEOF -#define SIZEOF_LONG_DOUBLE $ac_cv_sizeof_long_double -_ACEOF +printf "%s\n" "#define SIZEOF_LONG_DOUBLE $ac_cv_sizeof_long_double" >>confdefs.h @@ -10275,17 +12120,19 @@ _ACEOF # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of _Bool" >&5 -$as_echo_n "checking size of _Bool... " >&6; } -if ${ac_cv_sizeof__Bool+:} false; then : - $as_echo_n "(cached) " >&6 -else - if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (_Bool))" "ac_cv_sizeof__Bool" "$ac_includes_default"; then : - -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of _Bool" >&5 +printf %s "checking size of _Bool... " >&6; } +if test ${ac_cv_sizeof__Bool+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (_Bool))" "ac_cv_sizeof__Bool" "$ac_includes_default" +then : + +else $as_nop if test "$ac_cv_type__Bool" = yes; then - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (_Bool) See \`config.log' for more details" "$LINENO" 5; } else @@ -10294,14 +12141,12 @@ See \`config.log' for more details" "$LINENO" 5; } fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof__Bool" >&5 -$as_echo "$ac_cv_sizeof__Bool" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof__Bool" >&5 +printf "%s\n" "$ac_cv_sizeof__Bool" >&6; } -cat >>confdefs.h <<_ACEOF -#define SIZEOF__BOOL $ac_cv_sizeof__Bool -_ACEOF +printf "%s\n" "#define SIZEOF__BOOL $ac_cv_sizeof__Bool" >>confdefs.h @@ -10309,22 +12154,24 @@ _ACEOF # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of off_t" >&5 -$as_echo_n "checking size of off_t... " >&6; } -if ${ac_cv_sizeof_off_t+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of off_t" >&5 +printf %s "checking size of off_t... " >&6; } +if test ${ac_cv_sizeof_off_t+y} +then : + printf %s "(cached) " >&6 +else $as_nop if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (off_t))" "ac_cv_sizeof_off_t" " #ifdef HAVE_SYS_TYPES_H #include #endif -"; then : +" +then : -else +else $as_nop if test "$ac_cv_type_off_t" = yes; then - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (off_t) See \`config.log' for more details" "$LINENO" 5; } else @@ -10333,19 +12180,17 @@ See \`config.log' for more details" "$LINENO" 5; } fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_off_t" >&5 -$as_echo "$ac_cv_sizeof_off_t" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_off_t" >&5 +printf "%s\n" "$ac_cv_sizeof_off_t" >&6; } -cat >>confdefs.h <<_ACEOF -#define SIZEOF_OFF_T $ac_cv_sizeof_off_t -_ACEOF +printf "%s\n" "#define SIZEOF_OFF_T $ac_cv_sizeof_off_t" >>confdefs.h -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable large file support" >&5 -$as_echo_n "checking whether to enable large file support... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable large file support" >&5 +printf %s "checking whether to enable large file support... " >&6; } if test "$ac_cv_sizeof_off_t" -gt "$ac_cv_sizeof_long" -a \ "$ac_cv_sizeof_long_long" -ge "$ac_cv_sizeof_off_t"; then have_largefile_support="yes" @@ -10359,18 +12204,19 @@ case $ac_sys_system in #( *) : ;; esac -if test "x$have_largefile_support" = xyes; then : +if test "x$have_largefile_support" = xyes +then : -$as_echo "#define HAVE_LARGEFILE_SUPPORT 1" >>confdefs.h +printf "%s\n" "#define HAVE_LARGEFILE_SUPPORT 1" >>confdefs.h - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } -else +else $as_nop - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -10378,11 +12224,12 @@ fi # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of time_t" >&5 -$as_echo_n "checking size of time_t... " >&6; } -if ${ac_cv_sizeof_time_t+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of time_t" >&5 +printf %s "checking size of time_t... " >&6; } +if test ${ac_cv_sizeof_time_t+y} +then : + printf %s "(cached) " >&6 +else $as_nop if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (time_t))" "ac_cv_sizeof_time_t" " #ifdef HAVE_SYS_TYPES_H #include @@ -10391,12 +12238,13 @@ else #include #endif -"; then : +" +then : -else +else $as_nop if test "$ac_cv_type_time_t" = yes; then - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (time_t) See \`config.log' for more details" "$LINENO" 5; } else @@ -10405,14 +12253,12 @@ See \`config.log' for more details" "$LINENO" 5; } fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_time_t" >&5 -$as_echo "$ac_cv_sizeof_time_t" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_time_t" >&5 +printf "%s\n" "$ac_cv_sizeof_time_t" >&6; } -cat >>confdefs.h <<_ACEOF -#define SIZEOF_TIME_T $ac_cv_sizeof_time_t -_ACEOF +printf "%s\n" "#define SIZEOF_TIME_T $ac_cv_sizeof_time_t" >>confdefs.h @@ -10426,18 +12272,19 @@ elif test "$ac_cv_pthread" = "yes" then CC="$CC -pthread" fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_t" >&5 -$as_echo_n "checking for pthread_t... " >&6; } -if ${ac_cv_have_pthread_t+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for pthread_t" >&5 +printf %s "checking for pthread_t... " >&6; } +if test ${ac_cv_have_pthread_t+y} +then : + printf %s "(cached) " >&6 +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int -main () +main (void) { pthread_t x; x = *(pthread_t*)0; ; @@ -10445,38 +12292,42 @@ pthread_t x; x = *(pthread_t*)0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : ac_cv_have_pthread_t=yes -else +else $as_nop ac_cv_have_pthread_t=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_pthread_t" >&5 -$as_echo "$ac_cv_have_pthread_t" >&6; } -if test "x$ac_cv_have_pthread_t" = xyes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_pthread_t" >&5 +printf "%s\n" "$ac_cv_have_pthread_t" >&6; } +if test "x$ac_cv_have_pthread_t" = xyes +then : # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of pthread_t" >&5 -$as_echo_n "checking size of pthread_t... " >&6; } -if ${ac_cv_sizeof_pthread_t+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of pthread_t" >&5 +printf %s "checking size of pthread_t... " >&6; } +if test ${ac_cv_sizeof_pthread_t+y} +then : + printf %s "(cached) " >&6 +else $as_nop if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (pthread_t))" "ac_cv_sizeof_pthread_t" " #ifdef HAVE_PTHREAD_H #include #endif -"; then : +" +then : -else +else $as_nop if test "$ac_cv_type_pthread_t" = yes; then - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (pthread_t) See \`config.log' for more details" "$LINENO" 5; } else @@ -10485,14 +12336,12 @@ See \`config.log' for more details" "$LINENO" 5; } fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_pthread_t" >&5 -$as_echo "$ac_cv_sizeof_pthread_t" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_pthread_t" >&5 +printf "%s\n" "$ac_cv_sizeof_pthread_t" >&6; } -cat >>confdefs.h <<_ACEOF -#define SIZEOF_PTHREAD_T $ac_cv_sizeof_pthread_t -_ACEOF +printf "%s\n" "#define SIZEOF_PTHREAD_T $ac_cv_sizeof_pthread_t" >>confdefs.h @@ -10504,18 +12353,20 @@ fi # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of pthread_key_t" >&5 -$as_echo_n "checking size of pthread_key_t... " >&6; } -if ${ac_cv_sizeof_pthread_key_t+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of pthread_key_t" >&5 +printf %s "checking size of pthread_key_t... " >&6; } +if test ${ac_cv_sizeof_pthread_key_t+y} +then : + printf %s "(cached) " >&6 +else $as_nop if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (pthread_key_t))" "ac_cv_sizeof_pthread_key_t" "#include -"; then : +" +then : -else +else $as_nop if test "$ac_cv_type_pthread_key_t" = yes; then - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (pthread_key_t) See \`config.log' for more details" "$LINENO" 5; } else @@ -10524,218 +12375,212 @@ See \`config.log' for more details" "$LINENO" 5; } fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_pthread_key_t" >&5 -$as_echo "$ac_cv_sizeof_pthread_key_t" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_pthread_key_t" >&5 +printf "%s\n" "$ac_cv_sizeof_pthread_key_t" >&6; } -cat >>confdefs.h <<_ACEOF -#define SIZEOF_PTHREAD_KEY_T $ac_cv_sizeof_pthread_key_t -_ACEOF +printf "%s\n" "#define SIZEOF_PTHREAD_KEY_T $ac_cv_sizeof_pthread_key_t" >>confdefs.h -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthread_key_t is compatible with int" >&5 -$as_echo_n "checking whether pthread_key_t is compatible with int... " >&6; } -if ${ac_cv_pthread_key_t_is_arithmetic_type+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether pthread_key_t is compatible with int" >&5 +printf %s "checking whether pthread_key_t is compatible with int... " >&6; } +if test ${ac_cv_pthread_key_t_is_arithmetic_type+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test "$ac_cv_sizeof_pthread_key_t" -eq "$ac_cv_sizeof_int" ; then cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int -main () +main (void) { pthread_key_t k; k * 1; ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : ac_cv_pthread_key_t_is_arithmetic_type=yes -else +else $as_nop ac_cv_pthread_key_t_is_arithmetic_type=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext else ac_cv_pthread_key_t_is_arithmetic_type=no fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_pthread_key_t_is_arithmetic_type" >&5 -$as_echo "$ac_cv_pthread_key_t_is_arithmetic_type" >&6; } -if test "x$ac_cv_pthread_key_t_is_arithmetic_type" = xyes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_pthread_key_t_is_arithmetic_type" >&5 +printf "%s\n" "$ac_cv_pthread_key_t_is_arithmetic_type" >&6; } +if test "x$ac_cv_pthread_key_t_is_arithmetic_type" = xyes +then : -$as_echo "#define PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT 1" >>confdefs.h +printf "%s\n" "#define PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT 1" >>confdefs.h fi CC="$ac_save_cc" - -case $ac_sys_system/$ac_sys_release in - Darwin/[01567]\..*) - OTHER_LIBTOOL_OPT="-prebind -seg1addr 0x10000000" - ;; - Darwin/*) - OTHER_LIBTOOL_OPT="" - ;; -esac - - - -case $ac_sys_system/$ac_sys_release in - Darwin/[01567]\..*) - LIBTOOL_CRUFT="-framework System -lcc_dynamic" - if test "${enable_universalsdk}"; then - : - else - LIBTOOL_CRUFT="${LIBTOOL_CRUFT} -arch_only `/usr/bin/arch`" - fi - LIBTOOL_CRUFT=$LIBTOOL_CRUFT' -install_name $(PYTHONFRAMEWORKINSTALLDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK)' - LIBTOOL_CRUFT=$LIBTOOL_CRUFT' -compatibility_version $(VERSION) -current_version $(VERSION)';; - Darwin/*) - gcc_version=`gcc -dumpversion` - if test ${gcc_version} '<' 4.0 - then - LIBTOOL_CRUFT="-lcc_dynamic" - else - LIBTOOL_CRUFT="" - fi - if test "$cross_compiling" = yes; then : - ac_osx_32bit=yes -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - #include - int main(int argc, char*argv[]) - { - if (sizeof(long) == 4) { - return 0; - } else { - return 1; - } - } - -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - ac_osx_32bit=yes -else - ac_osx_32bit=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - - - if test "${ac_osx_32bit}" = "yes"; then - case `/usr/bin/arch` in - i386) - MACOSX_DEFAULT_ARCH="i386" - ;; - ppc) - MACOSX_DEFAULT_ARCH="ppc" - ;; - *) - as_fn_error $? "Unexpected output of 'arch' on macOS" "$LINENO" 5 - ;; - esac - else - case `/usr/bin/arch` in - i386) - MACOSX_DEFAULT_ARCH="x86_64" - ;; - ppc) - MACOSX_DEFAULT_ARCH="ppc64" - ;; - arm64) - MACOSX_DEFAULT_ARCH="arm64" - ;; - *) - as_fn_error $? "Unexpected output of 'arch' on macOS" "$LINENO" 5 - ;; - esac - - fi - - LIBTOOL_CRUFT=$LIBTOOL_CRUFT" -lSystem -lSystemStubs -arch_only ${MACOSX_DEFAULT_ARCH}" - LIBTOOL_CRUFT=$LIBTOOL_CRUFT' -install_name $(PYTHONFRAMEWORKINSTALLDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK)' - LIBTOOL_CRUFT=$LIBTOOL_CRUFT' -compatibility_version $(VERSION) -current_version $(VERSION)';; -esac -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --enable-framework" >&5 -$as_echo_n "checking for --enable-framework... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --enable-framework" >&5 +printf %s "checking for --enable-framework... " >&6; } if test "$enable_framework" then BASECFLAGS="$BASECFLAGS -fno-common -dynamic" # -F. is needed to allow linking to the framework while # in the build location. -$as_echo "#define WITH_NEXT_FRAMEWORK 1" >>confdefs.h +printf "%s\n" "#define WITH_NEXT_FRAMEWORK 1" >>confdefs.h - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } if test $enable_shared = "yes" then as_fn_error $? "Specifying both --enable-shared and --enable-framework is not supported, use only --enable-framework instead" "$LINENO" 5 fi else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + +# Check for --with-dsymutil + + +DSYMUTIL= +DSYMUTIL_PATH= +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-dsymutil" >&5 +printf %s "checking for --with-dsymutil... " >&6; } + +# Check whether --with-dsymutil was given. +if test ${with_dsymutil+y} +then : + withval=$with_dsymutil; +if test "$withval" != no +then + if test "$MACHDEP" != "darwin"; then + as_fn_error $? "dsymutil debug linking is only available in macOS." "$LINENO" 5 + fi + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; }; + DSYMUTIL='true' +else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; }; DSYMUTIL= +fi +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +if test "$DSYMUTIL"; then + # Extract the first word of "dsymutil", so it can be a program name with args. +set dummy dsymutil; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_DSYMUTIL_PATH+y} +then : + printf %s "(cached) " >&6 +else $as_nop + case $DSYMUTIL_PATH in + [\\/]* | ?:[\\/]*) + ac_cv_path_DSYMUTIL_PATH="$DSYMUTIL_PATH" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_DSYMUTIL_PATH="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_path_DSYMUTIL_PATH" && ac_cv_path_DSYMUTIL_PATH="not found" + ;; +esac +fi +DSYMUTIL_PATH=$ac_cv_path_DSYMUTIL_PATH +if test -n "$DSYMUTIL_PATH"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL_PATH" >&5 +printf "%s\n" "$DSYMUTIL_PATH" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for dyld" >&5 -$as_echo_n "checking for dyld... " >&6; } + + if test "$DSYMUTIL_PATH" = "not found"; then + as_fn_error $? "dsymutil command not found on \$PATH" "$LINENO" 5 + fi +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dyld" >&5 +printf %s "checking for dyld... " >&6; } case $ac_sys_system/$ac_sys_release in Darwin/*) -$as_echo "#define WITH_DYLD 1" >>confdefs.h +printf "%s\n" "#define WITH_DYLD 1" >>confdefs.h - { $as_echo "$as_me:${as_lineno-$LINENO}: result: always on for Darwin" >&5 -$as_echo "always on for Darwin" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: always on for Darwin" >&5 +printf "%s\n" "always on for Darwin" >&6; } ;; *) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } ;; esac -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-address-sanitizer" >&5 -$as_echo_n "checking for --with-address-sanitizer... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-address-sanitizer" >&5 +printf %s "checking for --with-address-sanitizer... " >&6; } # Check whether --with-address_sanitizer was given. -if test "${with_address_sanitizer+set}" = set; then : +if test ${with_address_sanitizer+y} +then : withval=$with_address_sanitizer; -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $withval" >&5 -$as_echo "$withval" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $withval" >&5 +printf "%s\n" "$withval" >&6; } BASECFLAGS="-fsanitize=address -fno-omit-frame-pointer $BASECFLAGS" LDFLAGS="-fsanitize=address $LDFLAGS" # ASan works by controlling memory allocation, our own malloc interferes. with_pymalloc="no" -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-memory-sanitizer" >&5 -$as_echo_n "checking for --with-memory-sanitizer... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-memory-sanitizer" >&5 +printf %s "checking for --with-memory-sanitizer... " >&6; } # Check whether --with-memory_sanitizer was given. -if test "${with_memory_sanitizer+set}" = set; then : +if test ${with_memory_sanitizer+y} +then : withval=$with_memory_sanitizer; -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $withval" >&5 -$as_echo "$withval" >&6; } -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -fsanitize=memory" >&5 -$as_echo_n "checking whether C compiler accepts -fsanitize=memory... " >&6; } -if ${ax_cv_check_cflags___fsanitize_memory+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $withval" >&5 +printf "%s\n" "$withval" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -fsanitize=memory" >&5 +printf %s "checking whether C compiler accepts -fsanitize=memory... " >&6; } +if test ${ax_cv_check_cflags___fsanitize_memory+y} +then : + printf %s "(cached) " >&6 +else $as_nop ax_check_save_flags=$CFLAGS CFLAGS="$CFLAGS -fsanitize=memory" @@ -10743,57 +12588,60 @@ else /* end confdefs.h. */ int -main () +main (void) { ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : ax_cv_check_cflags___fsanitize_memory=yes -else +else $as_nop ax_cv_check_cflags___fsanitize_memory=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext CFLAGS=$ax_check_save_flags fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___fsanitize_memory" >&5 -$as_echo "$ax_cv_check_cflags___fsanitize_memory" >&6; } -if test "x$ax_cv_check_cflags___fsanitize_memory" = xyes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___fsanitize_memory" >&5 +printf "%s\n" "$ax_cv_check_cflags___fsanitize_memory" >&6; } +if test "x$ax_cv_check_cflags___fsanitize_memory" = xyes +then : BASECFLAGS="-fsanitize=memory -fsanitize-memory-track-origins=2 -fno-omit-frame-pointer $BASECFLAGS" LDFLAGS="-fsanitize=memory -fsanitize-memory-track-origins=2 $LDFLAGS" -else +else $as_nop as_fn_error $? "The selected compiler doesn't support memory sanitizer" "$LINENO" 5 fi # MSan works by controlling memory allocation, our own malloc interferes. with_pymalloc="no" -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-undefined-behavior-sanitizer" >&5 -$as_echo_n "checking for --with-undefined-behavior-sanitizer... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-undefined-behavior-sanitizer" >&5 +printf %s "checking for --with-undefined-behavior-sanitizer... " >&6; } # Check whether --with-undefined_behavior_sanitizer was given. -if test "${with_undefined_behavior_sanitizer+set}" = set; then : +if test ${with_undefined_behavior_sanitizer+y} +then : withval=$with_undefined_behavior_sanitizer; -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $withval" >&5 -$as_echo "$withval" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $withval" >&5 +printf "%s\n" "$withval" >&6; } BASECFLAGS="-fsanitize=undefined $BASECFLAGS" LDFLAGS="-fsanitize=undefined $LDFLAGS" with_ubsan="yes" -else +else $as_nop -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } with_ubsan="no" fi @@ -10809,8 +12657,8 @@ fi # SHLIB_SUFFIX is the extension of shared libraries `(including the dot!) # -- usually .so, .sl on HP-UX, .dll on Cygwin -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the extension of shared libraries" >&5 -$as_echo_n "checking the extension of shared libraries... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking the extension of shared libraries" >&5 +printf %s "checking the extension of shared libraries... " >&6; } if test -z "$SHLIB_SUFFIX"; then case $ac_sys_system in hp*|HP*) @@ -10823,15 +12671,15 @@ if test -z "$SHLIB_SUFFIX"; then *) SHLIB_SUFFIX=.so;; esac fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $SHLIB_SUFFIX" >&5 -$as_echo "$SHLIB_SUFFIX" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $SHLIB_SUFFIX" >&5 +printf "%s\n" "$SHLIB_SUFFIX" >&6; } # LDSHARED is the ld *command* used to create shared library # -- "cc -G" on SunOS 5.x. # (Shared libraries in this instance are shared modules to be loaded into # Python, as opposed to building Python itself as a shared library.) -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking LDSHARED" >&5 -$as_echo_n "checking LDSHARED... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking LDSHARED" >&5 +printf %s "checking LDSHARED... " >&6; } if test -z "$LDSHARED" then case $ac_sys_system/$ac_sys_release in @@ -10947,7 +12795,8 @@ then LDSHARED='$(CC) -Wl,-G,-Bexport' LDCXXSHARED='$(CXX) -Wl,-G,-Bexport';; WASI*) - if test "x$enable_wasm_dynamic_linking" = xyes; then : + if test "x$enable_wasm_dynamic_linking" = xyes +then : fi;; @@ -10962,20 +12811,20 @@ if test "$enable_wasm_dynamic_linking" = "yes" -a "$ac_sys_system" = "Emscripten BLDSHARED='$(CC) -shared -sSIDE_MODULE=1' fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $LDSHARED" >&5 -$as_echo "$LDSHARED" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $LDSHARED" >&5 +printf "%s\n" "$LDSHARED" >&6; } LDCXXSHARED=${LDCXXSHARED-$LDSHARED} -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking BLDSHARED flags" >&5 -$as_echo_n "checking BLDSHARED flags... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking BLDSHARED flags" >&5 +printf %s "checking BLDSHARED flags... " >&6; } BLDSHARED=${BLDSHARED-$LDSHARED} -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $BLDSHARED" >&5 -$as_echo "$BLDSHARED" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $BLDSHARED" >&5 +printf "%s\n" "$BLDSHARED" >&6; } # CCSHARED are the C *flags* used to create objects to go into a shared # library (module) -- this is only needed for a few systems -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking CCSHARED" >&5 -$as_echo_n "checking CCSHARED... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking CCSHARED" >&5 +printf %s "checking CCSHARED... " >&6; } if test -z "$CCSHARED" then case $ac_sys_system/$ac_sys_release in @@ -10992,7 +12841,8 @@ then Linux-android*) ;; Linux*|GNU*) CCSHARED="-fPIC";; Emscripten*|WASI*) - if test "x$enable_wasm_dynamic_linking" = xyes; then : + if test "x$enable_wasm_dynamic_linking" = xyes +then : CCSHARED="-fPIC" @@ -11013,12 +12863,12 @@ fi;; CCSHARED="-fpic -D__SO_PICABILINUX__ -ftls-model=global-dynamic" esac fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CCSHARED" >&5 -$as_echo "$CCSHARED" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CCSHARED" >&5 +printf "%s\n" "$CCSHARED" >&6; } # LINKFORSHARED are the flags passed to the $(CC) command that links # the python executable -- this is only needed for a few systems -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking LINKFORSHARED" >&5 -$as_echo_n "checking LINKFORSHARED... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking LINKFORSHARED" >&5 +printf %s "checking LINKFORSHARED... " >&6; } if test -z "$LINKFORSHARED" then case $ac_sys_system/$ac_sys_release in @@ -11045,9 +12895,7 @@ then LINKFORSHARED="-Wl,-stack_size,$stack_size $LINKFORSHARED" -cat >>confdefs.h <<_ACEOF -#define THREAD_STACK_SIZE 0x$stack_size -_ACEOF +printf "%s\n" "#define THREAD_STACK_SIZE 0x$stack_size" >>confdefs.h if test "$enable_framework" @@ -11086,13 +12934,13 @@ _ACEOF LINKFORSHARED='-Wl,-export-dynamic';; esac fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $LINKFORSHARED" >&5 -$as_echo "$LINKFORSHARED" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $LINKFORSHARED" >&5 +printf "%s\n" "$LINKFORSHARED" >&6; } -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking CFLAGSFORSHARED" >&5 -$as_echo_n "checking CFLAGSFORSHARED... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking CFLAGSFORSHARED" >&5 +printf %s "checking CFLAGSFORSHARED... " >&6; } if test ! "$LIBRARY" = "$LDLIBRARY" then case $ac_sys_system in @@ -11105,14 +12953,15 @@ then esac fi -if test "x$enable_wasm_dynamic_linking" = xyes; then : +if test "x$enable_wasm_dynamic_linking" = xyes +then : CFLAGSFORSHARED='$(CCSHARED)' fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CFLAGSFORSHARED" >&5 -$as_echo "$CFLAGSFORSHARED" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CFLAGSFORSHARED" >&5 +printf "%s\n" "$CFLAGSFORSHARED" >&6; } # SHLIBS are libraries (except -lc and -lm) to link to the python shared # library (with --enable-shared). @@ -11123,22 +12972,54 @@ $as_echo "$CFLAGSFORSHARED" >&6; } # don't need to link LIBS explicitly. The default should be only changed # on systems where this approach causes problems. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking SHLIBS" >&5 -$as_echo_n "checking SHLIBS... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking SHLIBS" >&5 +printf %s "checking SHLIBS... " >&6; } case "$ac_sys_system" in *) SHLIBS='$(LIBS)';; esac -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $SHLIBS" >&5 -$as_echo "$SHLIBS" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $SHLIBS" >&5 +printf "%s\n" "$SHLIBS" >&6; } + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking perf trampoline" >&5 +printf %s "checking perf trampoline... " >&6; } +case $PLATFORM_TRIPLET in #( + x86_64-linux-gnu) : + perf_trampoline=yes ;; #( + aarch64-linux-gnu) : + perf_trampoline=yes ;; #( + *) : + perf_trampoline=no + ;; +esac +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $perf_trampoline" >&5 +printf "%s\n" "$perf_trampoline" >&6; } + +if test "x$perf_trampoline" = xyes +then : + + +printf "%s\n" "#define PY_HAVE_PERF_TRAMPOLINE 1" >>confdefs.h + + PERF_TRAMPOLINE_OBJ=Python/asm_trampoline.o + + if test "x$Py_DEBUG" = xtrue +then : + + as_fn_append BASECFLAGS " -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer" + +fi + +fi # checks for libraries -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sendfile in -lsendfile" >&5 -$as_echo_n "checking for sendfile in -lsendfile... " >&6; } -if ${ac_cv_lib_sendfile_sendfile+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sendfile in -lsendfile" >&5 +printf %s "checking for sendfile in -lsendfile... " >&6; } +if test ${ac_cv_lib_sendfile_sendfile+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lsendfile $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -11147,43 +13028,41 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char sendfile (); int -main () +main (void) { return sendfile (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_lib_sendfile_sendfile=yes -else +else $as_nop ac_cv_lib_sendfile_sendfile=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sendfile_sendfile" >&5 -$as_echo "$ac_cv_lib_sendfile_sendfile" >&6; } -if test "x$ac_cv_lib_sendfile_sendfile" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBSENDFILE 1 -_ACEOF +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sendfile_sendfile" >&5 +printf "%s\n" "$ac_cv_lib_sendfile_sendfile" >&6; } +if test "x$ac_cv_lib_sendfile_sendfile" = xyes +then : + printf "%s\n" "#define HAVE_LIBSENDFILE 1" >>confdefs.h LIBS="-lsendfile $LIBS" fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 -$as_echo_n "checking for dlopen in -ldl... " >&6; } -if ${ac_cv_lib_dl_dlopen+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +printf %s "checking for dlopen in -ldl... " >&6; } +if test ${ac_cv_lib_dl_dlopen+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -11192,43 +13071,41 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char dlopen (); int -main () +main (void) { return dlopen (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_lib_dl_dlopen=yes -else +else $as_nop ac_cv_lib_dl_dlopen=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 -$as_echo "$ac_cv_lib_dl_dlopen" >&6; } -if test "x$ac_cv_lib_dl_dlopen" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBDL 1 -_ACEOF +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +printf "%s\n" "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes +then : + printf "%s\n" "#define HAVE_LIBDL 1" >>confdefs.h LIBS="-ldl $LIBS" fi - # Dynamic linking for SunOS/Solaris and SYSV -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 -$as_echo_n "checking for shl_load in -ldld... " >&6; } -if ${ac_cv_lib_dld_shl_load+:} false; then : - $as_echo_n "(cached) " >&6 -else + # Dynamic linking for SunOS/Solaris and SYSV +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 +printf %s "checking for shl_load in -ldld... " >&6; } +if test ${ac_cv_lib_dld_shl_load+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -11237,38 +13114,35 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char shl_load (); int -main () +main (void) { return shl_load (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_lib_dld_shl_load=yes -else +else $as_nop ac_cv_lib_dld_shl_load=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 -$as_echo "$ac_cv_lib_dld_shl_load" >&6; } -if test "x$ac_cv_lib_dld_shl_load" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBDLD 1 -_ACEOF +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 +printf "%s\n" "$ac_cv_lib_dld_shl_load" >&6; } +if test "x$ac_cv_lib_dld_shl_load" = xyes +then : + printf "%s\n" "#define HAVE_LIBDLD 1" >>confdefs.h LIBS="-ldld $LIBS" fi - # Dynamic linking for HP-UX + # Dynamic linking for HP-UX @@ -11276,51 +13150,50 @@ fi have_uuid=missing -for ac_header in uuid.h + for ac_header in uuid.h do : - ac_fn_c_check_header_mongrel "$LINENO" "uuid.h" "ac_cv_header_uuid_h" "$ac_includes_default" -if test "x$ac_cv_header_uuid_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_UUID_H 1 -_ACEOF + ac_fn_c_check_header_compile "$LINENO" "uuid.h" "ac_cv_header_uuid_h" "$ac_includes_default" +if test "x$ac_cv_header_uuid_h" = xyes +then : + printf "%s\n" "#define HAVE_UUID_H 1" >>confdefs.h for ac_func in uuid_create uuid_enc_be do : - as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` + as_ac_var=`printf "%s\n" "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -if eval test \"x\$"$as_ac_var"\" = x"yes"; then : +if eval test \"x\$"$as_ac_var"\" = x"yes" +then : cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +#define `printf "%s\n" "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF - - have_uuid=yes + have_uuid=yes LIBUUID_CFLAGS=${LIBUUID_CFLAGS-""} LIBUUID_LIBS=${LIBUUID_LIBS-""} fi -done +done fi done - -if test "x$have_uuid" = xmissing; then : +if test "x$have_uuid" = xmissing +then : pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBUUID" >&5 -$as_echo_n "checking for LIBUUID... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for LIBUUID" >&5 +printf %s "checking for LIBUUID... " >&6; } if test -n "$LIBUUID_CFLAGS"; then pkg_cv_LIBUUID_CFLAGS="$LIBUUID_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"uuid >= 2.20\""; } >&5 + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"uuid >= 2.20\""; } >&5 ($PKG_CONFIG --exists --print-errors "uuid >= 2.20") 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_LIBUUID_CFLAGS=`$PKG_CONFIG --cflags "uuid >= 2.20" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes @@ -11334,10 +13207,10 @@ if test -n "$LIBUUID_LIBS"; then pkg_cv_LIBUUID_LIBS="$LIBUUID_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"uuid >= 2.20\""; } >&5 + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"uuid >= 2.20\""; } >&5 ($PKG_CONFIG --exists --print-errors "uuid >= 2.20") 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_LIBUUID_LIBS=`$PKG_CONFIG --libs "uuid >= 2.20" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes @@ -11351,8 +13224,8 @@ fi if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes @@ -11376,20 +13249,20 @@ save_LIBS=$LIBS CPPFLAGS="$CPPFLAGS $LIBUUID_CFLAGS" LDFLAGS="$LDFLAGS $LIBUUID_LIBS" - for ac_header in uuid/uuid.h + for ac_header in uuid/uuid.h do : - ac_fn_c_check_header_mongrel "$LINENO" "uuid/uuid.h" "ac_cv_header_uuid_uuid_h" "$ac_includes_default" -if test "x$ac_cv_header_uuid_uuid_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_UUID_UUID_H 1 -_ACEOF + ac_fn_c_check_header_compile "$LINENO" "uuid/uuid.h" "ac_cv_header_uuid_uuid_h" "$ac_includes_default" +if test "x$ac_cv_header_uuid_uuid_h" = xyes +then : + printf "%s\n" "#define HAVE_UUID_UUID_H 1" >>confdefs.h py_check_lib_save_LIBS=$LIBS -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for uuid_generate_time in -luuid" >&5 -$as_echo_n "checking for uuid_generate_time in -luuid... " >&6; } -if ${ac_cv_lib_uuid_uuid_generate_time+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for uuid_generate_time in -luuid" >&5 +printf %s "checking for uuid_generate_time in -luuid... " >&6; } +if test ${ac_cv_lib_uuid_uuid_generate_time+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-luuid $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -11398,41 +13271,41 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char uuid_generate_time (); int -main () +main (void) { return uuid_generate_time (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_lib_uuid_uuid_generate_time=yes -else +else $as_nop ac_cv_lib_uuid_uuid_generate_time=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_uuid_uuid_generate_time" >&5 -$as_echo "$ac_cv_lib_uuid_uuid_generate_time" >&6; } -if test "x$ac_cv_lib_uuid_uuid_generate_time" = xyes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_uuid_uuid_generate_time" >&5 +printf "%s\n" "$ac_cv_lib_uuid_uuid_generate_time" >&6; } +if test "x$ac_cv_lib_uuid_uuid_generate_time" = xyes +then : have_uuid=yes fi LIBS=$py_check_lib_save_LIBS py_check_lib_save_LIBS=$LIBS -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for uuid_generate_time_safe in -luuid" >&5 -$as_echo_n "checking for uuid_generate_time_safe in -luuid... " >&6; } -if ${ac_cv_lib_uuid_uuid_generate_time_safe+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for uuid_generate_time_safe in -luuid" >&5 +printf %s "checking for uuid_generate_time_safe in -luuid... " >&6; } +if test ${ac_cv_lib_uuid_uuid_generate_time_safe+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-luuid $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -11441,44 +13314,41 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char uuid_generate_time_safe (); int -main () +main (void) { return uuid_generate_time_safe (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_lib_uuid_uuid_generate_time_safe=yes -else +else $as_nop ac_cv_lib_uuid_uuid_generate_time_safe=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_uuid_uuid_generate_time_safe" >&5 -$as_echo "$ac_cv_lib_uuid_uuid_generate_time_safe" >&6; } -if test "x$ac_cv_lib_uuid_uuid_generate_time_safe" = xyes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_uuid_uuid_generate_time_safe" >&5 +printf "%s\n" "$ac_cv_lib_uuid_uuid_generate_time_safe" >&6; } +if test "x$ac_cv_lib_uuid_uuid_generate_time_safe" = xyes +then : have_uuid=yes - $as_echo "#define HAVE_UUID_GENERATE_TIME_SAFE 1" >>confdefs.h - + printf "%s\n" "#define HAVE_UUID_GENERATE_TIME_SAFE 1" >>confdefs.h fi LIBS=$py_check_lib_save_LIBS - fi done - - if test "x$have_uuid" = xyes; then : + if test "x$have_uuid" = xyes +then : LIBUUID_CFLAGS=${LIBUUID_CFLAGS-""} LIBUUID_LIBS=${LIBUUID_LIBS-"-luuid"} @@ -11494,8 +13364,8 @@ LIBS=$save_LIBS elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } save_CFLAGS=$CFLAGS save_CPPFLAGS=$CPPFLAGS @@ -11505,20 +13375,20 @@ save_LIBS=$LIBS CPPFLAGS="$CPPFLAGS $LIBUUID_CFLAGS" LDFLAGS="$LDFLAGS $LIBUUID_LIBS" - for ac_header in uuid/uuid.h + for ac_header in uuid/uuid.h do : - ac_fn_c_check_header_mongrel "$LINENO" "uuid/uuid.h" "ac_cv_header_uuid_uuid_h" "$ac_includes_default" -if test "x$ac_cv_header_uuid_uuid_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_UUID_UUID_H 1 -_ACEOF + ac_fn_c_check_header_compile "$LINENO" "uuid/uuid.h" "ac_cv_header_uuid_uuid_h" "$ac_includes_default" +if test "x$ac_cv_header_uuid_uuid_h" = xyes +then : + printf "%s\n" "#define HAVE_UUID_UUID_H 1" >>confdefs.h py_check_lib_save_LIBS=$LIBS -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for uuid_generate_time in -luuid" >&5 -$as_echo_n "checking for uuid_generate_time in -luuid... " >&6; } -if ${ac_cv_lib_uuid_uuid_generate_time+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for uuid_generate_time in -luuid" >&5 +printf %s "checking for uuid_generate_time in -luuid... " >&6; } +if test ${ac_cv_lib_uuid_uuid_generate_time+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-luuid $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -11527,41 +13397,41 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char uuid_generate_time (); int -main () +main (void) { return uuid_generate_time (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_lib_uuid_uuid_generate_time=yes -else +else $as_nop ac_cv_lib_uuid_uuid_generate_time=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_uuid_uuid_generate_time" >&5 -$as_echo "$ac_cv_lib_uuid_uuid_generate_time" >&6; } -if test "x$ac_cv_lib_uuid_uuid_generate_time" = xyes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_uuid_uuid_generate_time" >&5 +printf "%s\n" "$ac_cv_lib_uuid_uuid_generate_time" >&6; } +if test "x$ac_cv_lib_uuid_uuid_generate_time" = xyes +then : have_uuid=yes fi LIBS=$py_check_lib_save_LIBS py_check_lib_save_LIBS=$LIBS -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for uuid_generate_time_safe in -luuid" >&5 -$as_echo_n "checking for uuid_generate_time_safe in -luuid... " >&6; } -if ${ac_cv_lib_uuid_uuid_generate_time_safe+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for uuid_generate_time_safe in -luuid" >&5 +printf %s "checking for uuid_generate_time_safe in -luuid... " >&6; } +if test ${ac_cv_lib_uuid_uuid_generate_time_safe+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-luuid $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -11570,44 +13440,41 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char uuid_generate_time_safe (); int -main () +main (void) { return uuid_generate_time_safe (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_lib_uuid_uuid_generate_time_safe=yes -else +else $as_nop ac_cv_lib_uuid_uuid_generate_time_safe=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_uuid_uuid_generate_time_safe" >&5 -$as_echo "$ac_cv_lib_uuid_uuid_generate_time_safe" >&6; } -if test "x$ac_cv_lib_uuid_uuid_generate_time_safe" = xyes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_uuid_uuid_generate_time_safe" >&5 +printf "%s\n" "$ac_cv_lib_uuid_uuid_generate_time_safe" >&6; } +if test "x$ac_cv_lib_uuid_uuid_generate_time_safe" = xyes +then : have_uuid=yes - $as_echo "#define HAVE_UUID_GENERATE_TIME_SAFE 1" >>confdefs.h - + printf "%s\n" "#define HAVE_UUID_GENERATE_TIME_SAFE 1" >>confdefs.h fi LIBS=$py_check_lib_save_LIBS - fi done - - if test "x$have_uuid" = xyes; then : + if test "x$have_uuid" = xyes +then : LIBUUID_CFLAGS=${LIBUUID_CFLAGS-""} LIBUUID_LIBS=${LIBUUID_LIBS-"-luuid"} @@ -11625,31 +13492,31 @@ LIBS=$save_LIBS else LIBUUID_CFLAGS=$pkg_cv_LIBUUID_CFLAGS LIBUUID_LIBS=$pkg_cv_LIBUUID_LIBS - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - - have_uuid=yes - $as_echo "#define HAVE_UUID_H 1" >>confdefs.h + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + have_uuid=yes + printf "%s\n" "#define HAVE_UUID_H 1" >>confdefs.h - $as_echo "#define HAVE_UUID_GENERATE_TIME_SAFE 1" >>confdefs.h + printf "%s\n" "#define HAVE_UUID_GENERATE_TIME_SAFE 1" >>confdefs.h fi fi -if test "x$have_uuid" = xmissing; then : +if test "x$have_uuid" = xmissing +then : - for ac_header in uuid/uuid.h + for ac_header in uuid/uuid.h do : - ac_fn_c_check_header_mongrel "$LINENO" "uuid/uuid.h" "ac_cv_header_uuid_uuid_h" "$ac_includes_default" -if test "x$ac_cv_header_uuid_uuid_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_UUID_UUID_H 1 -_ACEOF + ac_fn_c_check_header_compile "$LINENO" "uuid/uuid.h" "ac_cv_header_uuid_uuid_h" "$ac_includes_default" +if test "x$ac_cv_header_uuid_uuid_h" = xyes +then : + printf "%s\n" "#define HAVE_UUID_UUID_H 1" >>confdefs.h ac_fn_c_check_func "$LINENO" "uuid_generate_time" "ac_cv_func_uuid_generate_time" -if test "x$ac_cv_func_uuid_generate_time" = xyes; then : +if test "x$ac_cv_func_uuid_generate_time" = xyes +then : have_uuid=yes LIBUUID_CFLAGS=${LIBUUID_CFLAGS-""} @@ -11662,21 +13529,22 @@ fi done - fi -if test "x$have_uuid" = xmissing; then : +if test "x$have_uuid" = xmissing +then : have_uuid=no fi # 'Real Time' functions on Solaris # posix4 on Solaris 2.6 # pthread (first!) on Linux -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing sem_init" >&5 -$as_echo_n "checking for library containing sem_init... " >&6; } -if ${ac_cv_search_sem_init+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing sem_init" >&5 +printf %s "checking for library containing sem_init... " >&6; } +if test ${ac_cv_search_sem_init+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -11684,57 +13552,60 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char sem_init (); int -main () +main (void) { return sem_init (); ; return 0; } _ACEOF -for ac_lib in '' pthread rt posix4; do +for ac_lib in '' pthread rt posix4 +do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi - if ac_fn_c_try_link "$LINENO"; then : + if ac_fn_c_try_link "$LINENO" +then : ac_cv_search_sem_init=$ac_res fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext - if ${ac_cv_search_sem_init+:} false; then : + if test ${ac_cv_search_sem_init+y} +then : break fi done -if ${ac_cv_search_sem_init+:} false; then : +if test ${ac_cv_search_sem_init+y} +then : -else +else $as_nop ac_cv_search_sem_init=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_sem_init" >&5 -$as_echo "$ac_cv_search_sem_init" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_sem_init" >&5 +printf "%s\n" "$ac_cv_search_sem_init" >&6; } ac_res=$ac_cv_search_sem_init -if test "$ac_res" != no; then : +if test "$ac_res" != no +then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi # check if we need libintl for locale functions -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for textdomain in -lintl" >&5 -$as_echo_n "checking for textdomain in -lintl... " >&6; } -if ${ac_cv_lib_intl_textdomain+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for textdomain in -lintl" >&5 +printf %s "checking for textdomain in -lintl... " >&6; } +if test ${ac_cv_lib_intl_textdomain+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lintl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -11743,32 +13614,31 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char textdomain (); int -main () +main (void) { return textdomain (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_lib_intl_textdomain=yes -else +else $as_nop ac_cv_lib_intl_textdomain=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_intl_textdomain" >&5 -$as_echo "$ac_cv_lib_intl_textdomain" >&6; } -if test "x$ac_cv_lib_intl_textdomain" = xyes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_intl_textdomain" >&5 +printf "%s\n" "$ac_cv_lib_intl_textdomain" >&6; } +if test "x$ac_cv_lib_intl_textdomain" = xyes +then : -$as_echo "#define WITH_LIBINTL 1" >>confdefs.h +printf "%s\n" "#define WITH_LIBINTL 1" >>confdefs.h LIBS="-lintl $LIBS" fi @@ -11776,14 +13646,14 @@ fi # checks for system dependent C++ extensions support case "$ac_sys_system" in - AIX*) { $as_echo "$as_me:${as_lineno-$LINENO}: checking for genuine AIX C++ extensions support" >&5 -$as_echo_n "checking for genuine AIX C++ extensions support... " >&6; } + AIX*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for genuine AIX C++ extensions support" >&5 +printf %s "checking for genuine AIX C++ extensions support... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int -main () +main (void) { loadAndInit("", 0, "") ; @@ -11791,48 +13661,49 @@ loadAndInit("", 0, "") } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : -$as_echo "#define AIX_GENUINE_CPLUSPLUS 1" >>confdefs.h +printf "%s\n" "#define AIX_GENUINE_CPLUSPLUS 1" >>confdefs.h - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } -else +else $as_nop - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext # BUILD_GNU_TYPE + AIX_BUILDDATE are used to construct the platform_tag # of the AIX system used to build/package Python executable. This tag serves # as a baseline for bdist module packages - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the system builddate" >&5 -$as_echo_n "checking for the system builddate... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for the system builddate" >&5 +printf %s "checking for the system builddate... " >&6; } AIX_BUILDDATE=$(lslpp -Lcq bos.mp64 | awk -F: '{ print $NF }') -cat >>confdefs.h <<_ACEOF -#define AIX_BUILDDATE $AIX_BUILDDATE -_ACEOF +printf "%s\n" "#define AIX_BUILDDATE $AIX_BUILDDATE" >>confdefs.h - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AIX_BUILDDATE" >&5 -$as_echo "$AIX_BUILDDATE" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $AIX_BUILDDATE" >&5 +printf "%s\n" "$AIX_BUILDDATE" >&6; } ;; *) ;; esac # check for systems that require aligned memory access -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking aligned memory access is required" >&5 -$as_echo_n "checking aligned memory access is required... " >&6; } -if ${ac_cv_aligned_required+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "$cross_compiling" = yes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking aligned memory access is required" >&5 +printf %s "checking aligned memory access is required... " >&6; } +if test ${ac_cv_aligned_required+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test "$cross_compiling" = yes +then : ac_cv_aligned_required=yes -else +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -11849,9 +13720,10 @@ int main(void) return 0; } _ACEOF -if ac_fn_c_try_run "$LINENO"; then : +if ac_fn_c_try_run "$LINENO" +then : ac_cv_aligned_required=no -else +else $as_nop ac_cv_aligned_required=yes fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -11860,36 +13732,37 @@ fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_aligned_required" >&5 -$as_echo "$ac_cv_aligned_required" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_aligned_required" >&5 +printf "%s\n" "$ac_cv_aligned_required" >&6; } if test "$ac_cv_aligned_required" = yes ; then -$as_echo "#define HAVE_ALIGNED_REQUIRED 1" >>confdefs.h +printf "%s\n" "#define HAVE_ALIGNED_REQUIRED 1" >>confdefs.h fi # str, bytes and memoryview hash algorithm -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-hash-algorithm" >&5 -$as_echo_n "checking for --with-hash-algorithm... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-hash-algorithm" >&5 +printf %s "checking for --with-hash-algorithm... " >&6; } # Check whether --with-hash_algorithm was given. -if test "${with_hash_algorithm+set}" = set; then : +if test ${with_hash_algorithm+y} +then : withval=$with_hash_algorithm; -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $withval" >&5 -$as_echo "$withval" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $withval" >&5 +printf "%s\n" "$withval" >&6; } case "$withval" in siphash13) - $as_echo "#define Py_HASH_ALGORITHM 3" >>confdefs.h + printf "%s\n" "#define Py_HASH_ALGORITHM 3" >>confdefs.h ;; siphash24) - $as_echo "#define Py_HASH_ALGORITHM 1" >>confdefs.h + printf "%s\n" "#define Py_HASH_ALGORITHM 1" >>confdefs.h ;; fnv) - $as_echo "#define Py_HASH_ALGORITHM 2" >>confdefs.h + printf "%s\n" "#define Py_HASH_ALGORITHM 2" >>confdefs.h ;; *) @@ -11897,9 +13770,9 @@ case "$withval" in ;; esac -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: default" >&5 -$as_echo "default" >&6; } +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: default" >&5 +printf "%s\n" "default" >&6; } fi @@ -11918,11 +13791,12 @@ validate_tzpath() { } TZPATH="/usr/share/zoneinfo:/usr/lib/zoneinfo:/usr/share/lib/zoneinfo:/etc/zoneinfo" -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-tzpath" >&5 -$as_echo_n "checking for --with-tzpath... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-tzpath" >&5 +printf %s "checking for --with-tzpath... " >&6; } # Check whether --with-tzpath was given. -if test "${with_tzpath+set}" = set; then : +if test ${with_tzpath+y} +then : withval=$with_tzpath; case "$withval" in yes) @@ -11931,25 +13805,26 @@ case "$withval" in *) validate_tzpath "$withval" TZPATH="$withval" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: \"$withval\"" >&5 -$as_echo "\"$withval\"" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: \"$withval\"" >&5 +printf "%s\n" "\"$withval\"" >&6; } ;; esac -else +else $as_nop validate_tzpath "$TZPATH" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: \"$TZPATH\"" >&5 -$as_echo "\"$TZPATH\"" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: \"$TZPATH\"" >&5 +printf "%s\n" "\"$TZPATH\"" >&6; } fi # Most SVR4 platforms (e.g. Solaris) need -lsocket and -lnsl. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for t_open in -lnsl" >&5 -$as_echo_n "checking for t_open in -lnsl... " >&6; } -if ${ac_cv_lib_nsl_t_open+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for t_open in -lnsl" >&5 +printf %s "checking for t_open in -lnsl... " >&6; } +if test ${ac_cv_lib_nsl_t_open+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lnsl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -11958,38 +13833,38 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char t_open (); int -main () +main (void) { return t_open (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_lib_nsl_t_open=yes -else +else $as_nop ac_cv_lib_nsl_t_open=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_t_open" >&5 -$as_echo "$ac_cv_lib_nsl_t_open" >&6; } -if test "x$ac_cv_lib_nsl_t_open" = xyes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_t_open" >&5 +printf "%s\n" "$ac_cv_lib_nsl_t_open" >&6; } +if test "x$ac_cv_lib_nsl_t_open" = xyes +then : LIBS="-lnsl $LIBS" fi # SVR4 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for socket in -lsocket" >&5 -$as_echo_n "checking for socket in -lsocket... " >&6; } -if ${ac_cv_lib_socket_socket+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for socket in -lsocket" >&5 +printf %s "checking for socket in -lsocket... " >&6; } +if test ${ac_cv_lib_socket_socket+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lsocket $LIBS $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -11998,41 +13873,41 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char socket (); int -main () +main (void) { return socket (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_lib_socket_socket=yes -else +else $as_nop ac_cv_lib_socket_socket=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_socket" >&5 -$as_echo "$ac_cv_lib_socket_socket" >&6; } -if test "x$ac_cv_lib_socket_socket" = xyes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_socket" >&5 +printf "%s\n" "$ac_cv_lib_socket_socket" >&6; } +if test "x$ac_cv_lib_socket_socket" = xyes +then : LIBS="-lsocket $LIBS" fi # SVR4 sockets case $ac_sys_system/$ac_sys_release in Haiku*) - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for socket in -lnetwork" >&5 -$as_echo_n "checking for socket in -lnetwork... " >&6; } -if ${ac_cv_lib_network_socket+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for socket in -lnetwork" >&5 +printf %s "checking for socket in -lnetwork... " >&6; } +if test ${ac_cv_lib_network_socket+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lnetwork $LIBS $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -12041,74 +13916,76 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char socket (); int -main () +main (void) { return socket (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_lib_network_socket=yes -else +else $as_nop ac_cv_lib_network_socket=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_network_socket" >&5 -$as_echo "$ac_cv_lib_network_socket" >&6; } -if test "x$ac_cv_lib_network_socket" = xyes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_network_socket" >&5 +printf "%s\n" "$ac_cv_lib_network_socket" >&6; } +if test "x$ac_cv_lib_network_socket" = xyes +then : LIBS="-lnetwork $LIBS" fi ;; esac -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-libs" >&5 -$as_echo_n "checking for --with-libs... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-libs" >&5 +printf %s "checking for --with-libs... " >&6; } # Check whether --with-libs was given. -if test "${with_libs+set}" = set; then : +if test ${with_libs+y} +then : withval=$with_libs; -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $withval" >&5 -$as_echo "$withval" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $withval" >&5 +printf "%s\n" "$withval" >&6; } LIBS="$withval $LIBS" -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi # Check for use of the system expat library -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-system-expat" >&5 -$as_echo_n "checking for --with-system-expat... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-system-expat" >&5 +printf %s "checking for --with-system-expat... " >&6; } # Check whether --with-system_expat was given. -if test "${with_system_expat+set}" = set; then : +if test ${with_system_expat+y} +then : withval=$with_system_expat; -else +else $as_nop with_system_expat="no" fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_system_expat" >&5 -$as_echo "$with_system_expat" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_system_expat" >&5 +printf "%s\n" "$with_system_expat" >&6; } -if test "x$with_system_expat" = xyes; then : +if test "x$with_system_expat" = xyes +then : LIBEXPAT_CFLAGS=${LIBEXPAT_CFLAGS-""} LIBEXPAT_LDFLAGS=${LIBEXPAT_LDFLAGS-"-lexpat"} LIBEXPAT_INTERNAL= -else +else $as_nop LIBEXPAT_CFLAGS="-I\$(srcdir)/Modules/expat" LIBEXPAT_LDFLAGS="-lm \$(LIBEXPAT_A)" @@ -12119,114 +13996,525 @@ fi +have_libffi=missing +if test "x$ac_sys_system" = xDarwin +then : + + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + CFLAGS="-I${SDKROOT}/usr/include/ffi $CFLAGS" + ac_fn_c_check_header_compile "$LINENO" "ffi.h" "ac_cv_header_ffi_h" "$ac_includes_default" +if test "x$ac_cv_header_ffi_h" = xyes +then : + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ffi_call in -lffi" >&5 +printf %s "checking for ffi_call in -lffi... " >&6; } +if test ${ac_cv_lib_ffi_ffi_call+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_check_lib_save_LIBS=$LIBS +LIBS="-lffi $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char ffi_call (); +int +main (void) +{ +return ffi_call (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_ffi_ffi_call=yes +else $as_nop + ac_cv_lib_ffi_ffi_call=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ffi_ffi_call" >&5 +printf "%s\n" "$ac_cv_lib_ffi_ffi_call" >&6; } +if test "x$ac_cv_lib_ffi_ffi_call" = xyes +then : + + have_libffi=yes + LIBFFI_CFLAGS="-I${SDKROOT}/usr/include/ffi -DUSING_APPLE_OS_LIBFFI=1" + LIBFFI_LIBS="-lffi" + +fi + + +fi + + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + -# Check for use of the system libffi library -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-system-ffi" >&5 -$as_echo_n "checking for --with-system-ffi... " >&6; } -# Check whether --with-system_ffi was given. -if test "${with_system_ffi+set}" = set; then : - withval=$with_system_ffi; fi +if test "x$have_libffi" = xmissing +then : -if test "$ac_sys_system" = "Darwin" -then - case "$with_system_ffi" in - "") - with_system_ffi="no" - ;; - yes|no) - ;; - *) - as_fn_error $? "--with-system-ffi accepts no arguments" "$LINENO" 5 - ;; - esac - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_system_ffi" >&5 -$as_echo "$with_system_ffi" >&6; } +pkg_failed=no +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for LIBFFI" >&5 +printf %s "checking for LIBFFI... " >&6; } + +if test -n "$LIBFFI_CFLAGS"; then + pkg_cv_LIBFFI_CFLAGS="$LIBFFI_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libffi\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libffi") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBFFI_CFLAGS=`$PKG_CONFIG --cflags "libffi" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - if test "$with_system_ffi" != "" - then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: --with(out)-system-ffi is ignored on this platform" >&5 -$as_echo "$as_me: WARNING: --with(out)-system-ffi is ignored on this platform" >&2;} - fi - with_system_ffi="yes" + pkg_failed=yes fi - -if test "$with_system_ffi" = "yes" && test -n "$PKG_CONFIG"; then - LIBFFI_INCLUDEDIR="`"$PKG_CONFIG" libffi --cflags-only-I 2>/dev/null | sed -e 's/^-I//;s/ *$//'`" + else + pkg_failed=untried +fi +if test -n "$LIBFFI_LIBS"; then + pkg_cv_LIBFFI_LIBS="$LIBFFI_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libffi\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libffi") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBFFI_LIBS=`$PKG_CONFIG --libs "libffi" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes else - LIBFFI_INCLUDEDIR="" + pkg_failed=yes +fi + else + pkg_failed=untried fi -# Check for use of the system libmpdec library -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-system-libmpdec" >&5 -$as_echo_n "checking for --with-system-libmpdec... " >&6; } -# Check whether --with-system_libmpdec was given. -if test "${with_system_libmpdec+set}" = set; then : - withval=$with_system_libmpdec; +if test $pkg_failed = yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes else - with_system_libmpdec="no" + _pkg_short_errors_supported=no fi + if test $_pkg_short_errors_supported = yes; then + LIBFFI_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libffi" 2>&1` + else + LIBFFI_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libffi" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LIBFFI_PKG_ERRORS" >&5 -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_system_libmpdec" >&5 -$as_echo "$with_system_libmpdec" >&6; } -if test "x$with_system_libmpdec" = xyes; then : + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS - LIBMPDEC_CFLAGS=${LIBMPDEC_CFLAGS-""} - LIBMPDEC_LDFLAGS=${LIBMPDEC_LDFLAGS-"-lmpdec"} - LIBMPDEC_INTERNAL= -else + CPPFLAGS="$CPPFLAGS $LIBFFI_CFLAGS" + LDFLAGS="$LDFLAGS $LIBFFI_LIBS" + ac_fn_c_check_header_compile "$LINENO" "ffi.h" "ac_cv_header_ffi_h" "$ac_includes_default" +if test "x$ac_cv_header_ffi_h" = xyes +then : - LIBMPDEC_CFLAGS="-I\$(srcdir)/Modules/_decimal/libmpdec" - LIBMPDEC_LDFLAGS="-lm \$(LIBMPDEC_A)" - LIBMPDEC_INTERNAL="\$(LIBMPDEC_HEADERS) \$(LIBMPDEC_A)" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ffi_call in -lffi" >&5 +printf %s "checking for ffi_call in -lffi... " >&6; } +if test ${ac_cv_lib_ffi_ffi_call+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_check_lib_save_LIBS=$LIBS +LIBS="-lffi $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ - if test "x$with_pydebug" = xyes; then : +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char ffi_call (); +int +main (void) +{ +return ffi_call (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_ffi_ffi_call=yes +else $as_nop + ac_cv_lib_ffi_ffi_call=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ffi_ffi_call" >&5 +printf "%s\n" "$ac_cv_lib_ffi_ffi_call" >&6; } +if test "x$ac_cv_lib_ffi_ffi_call" = xyes +then : - as_fn_append LIBMPDEC_CFLAGS " -DTEST_COVERAGE" + have_libffi=yes + LIBFFI_CFLAGS=${LIBFFI_CFLAGS-""} + LIBFFI_LIBS=${LIBFFI_LIBS-"-lffi"} +else $as_nop + have_libffi=no fi + fi +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS -# Check whether _decimal should use a coroutine-local or thread-local context -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-decimal-contextvar" >&5 -$as_echo_n "checking for --with-decimal-contextvar... " >&6; } +elif test $pkg_failed = untried; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } -# Check whether --with-decimal_contextvar was given. -if test "${with_decimal_contextvar+set}" = set; then : - withval=$with_decimal_contextvar; -else - with_decimal_contextvar="yes" -fi + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS -if test "$with_decimal_contextvar" != "no" -then + CPPFLAGS="$CPPFLAGS $LIBFFI_CFLAGS" + LDFLAGS="$LDFLAGS $LIBFFI_LIBS" + ac_fn_c_check_header_compile "$LINENO" "ffi.h" "ac_cv_header_ffi_h" "$ac_includes_default" +if test "x$ac_cv_header_ffi_h" = xyes +then : -$as_echo "#define WITH_DECIMAL_CONTEXTVAR 1" >>confdefs.h + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ffi_call in -lffi" >&5 +printf %s "checking for ffi_call in -lffi... " >&6; } +if test ${ac_cv_lib_ffi_ffi_call+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_check_lib_save_LIBS=$LIBS +LIBS="-lffi $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char ffi_call (); +int +main (void) +{ +return ffi_call (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_ffi_ffi_call=yes +else $as_nop + ac_cv_lib_ffi_ffi_call=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ffi_ffi_call" >&5 +printf "%s\n" "$ac_cv_lib_ffi_ffi_call" >&6; } +if test "x$ac_cv_lib_ffi_ffi_call" = xyes +then : -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_decimal_contextvar" >&5 -$as_echo "$with_decimal_contextvar" >&6; } + have_libffi=yes + LIBFFI_CFLAGS=${LIBFFI_CFLAGS-""} + LIBFFI_LIBS=${LIBFFI_LIBS-"-lffi"} -# Check for libmpdec machine flavor -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for decimal libmpdec machine" >&5 -$as_echo_n "checking for decimal libmpdec machine... " >&6; } -case $ac_sys_system in #( - Darwin*) : +else $as_nop + have_libffi=no +fi + + +fi + + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + +else + LIBFFI_CFLAGS=$pkg_cv_LIBFFI_CFLAGS + LIBFFI_LIBS=$pkg_cv_LIBFFI_LIBS + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + have_libffi=yes +fi + +fi + +if test "x$have_libffi" = xyes +then : + + ctypes_malloc_closure=no + case $ac_sys_system in #( + Darwin) : + + ctypes_malloc_closure=yes + ;; #( + sunos5) : + as_fn_append LIBFFI_LIBS " -mimpure-text" + ;; #( + *) : + ;; +esac + if test "x$ctypes_malloc_closure" = xyes +then : + + MODULE__CTYPES_MALLOC_CLOSURE=_ctypes/malloc_closure.c + as_fn_append LIBFFI_CFLAGS " -DUSING_MALLOC_CLOSURE_DOT_C=1" + +fi + + + if test "x$ac_cv_lib_dl_dlopen" = xyes +then : + as_fn_append LIBFFI_LIBS " -ldl" +fi + + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + CFLAGS="$LIBFFI_CFLAGS $CFLAGS" + LDFLAGS="$LIBFFI_LIBS $LDFLAGS" + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ffi_prep_cif_var" >&5 +printf %s "checking for ffi_prep_cif_var... " >&6; } +if test ${ac_cv_func_ffi_prep_cif_var+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main (void) +{ +void *x=ffi_prep_cif_var + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_ffi_prep_cif_var=yes +else $as_nop + ac_cv_func_ffi_prep_cif_var=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_ffi_prep_cif_var" >&5 +printf "%s\n" "$ac_cv_func_ffi_prep_cif_var" >&6; } + if test "x$ac_cv_func_ffi_prep_cif_var" = xyes +then : + +printf "%s\n" "#define HAVE_FFI_PREP_CIF_VAR 1" >>confdefs.h + +fi + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ffi_prep_closure_loc" >&5 +printf %s "checking for ffi_prep_closure_loc... " >&6; } +if test ${ac_cv_func_ffi_prep_closure_loc+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main (void) +{ +void *x=ffi_prep_closure_loc + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_ffi_prep_closure_loc=yes +else $as_nop + ac_cv_func_ffi_prep_closure_loc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_ffi_prep_closure_loc" >&5 +printf "%s\n" "$ac_cv_func_ffi_prep_closure_loc" >&6; } + if test "x$ac_cv_func_ffi_prep_closure_loc" = xyes +then : + +printf "%s\n" "#define HAVE_FFI_PREP_CLOSURE_LOC 1" >>confdefs.h + +fi + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ffi_closure_alloc" >&5 +printf %s "checking for ffi_closure_alloc... " >&6; } +if test ${ac_cv_func_ffi_closure_alloc+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main (void) +{ +void *x=ffi_closure_alloc + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_ffi_closure_alloc=yes +else $as_nop + ac_cv_func_ffi_closure_alloc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_ffi_closure_alloc" >&5 +printf "%s\n" "$ac_cv_func_ffi_closure_alloc" >&6; } + if test "x$ac_cv_func_ffi_closure_alloc" = xyes +then : + +printf "%s\n" "#define HAVE_FFI_CLOSURE_ALLOC 1" >>confdefs.h + +fi + + + + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + +fi + +# Check for use of the system libmpdec library +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-system-libmpdec" >&5 +printf %s "checking for --with-system-libmpdec... " >&6; } + +# Check whether --with-system_libmpdec was given. +if test ${with_system_libmpdec+y} +then : + withval=$with_system_libmpdec; +else $as_nop + with_system_libmpdec="no" +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_system_libmpdec" >&5 +printf "%s\n" "$with_system_libmpdec" >&6; } + +if test "x$with_system_libmpdec" = xyes +then : + + LIBMPDEC_CFLAGS=${LIBMPDEC_CFLAGS-""} + LIBMPDEC_LDFLAGS=${LIBMPDEC_LDFLAGS-"-lmpdec"} + LIBMPDEC_INTERNAL= + +else $as_nop + + LIBMPDEC_CFLAGS="-I\$(srcdir)/Modules/_decimal/libmpdec" + LIBMPDEC_LDFLAGS="-lm \$(LIBMPDEC_A)" + LIBMPDEC_INTERNAL="\$(LIBMPDEC_HEADERS) \$(LIBMPDEC_A)" + + if test "x$with_pydebug" = xyes +then : + + as_fn_append LIBMPDEC_CFLAGS " -DTEST_COVERAGE" + +fi + +fi + + + + +# Check whether _decimal should use a coroutine-local or thread-local context +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-decimal-contextvar" >&5 +printf %s "checking for --with-decimal-contextvar... " >&6; } + +# Check whether --with-decimal_contextvar was given. +if test ${with_decimal_contextvar+y} +then : + withval=$with_decimal_contextvar; +else $as_nop + with_decimal_contextvar="yes" +fi + + +if test "$with_decimal_contextvar" != "no" +then + +printf "%s\n" "#define WITH_DECIMAL_CONTEXTVAR 1" >>confdefs.h + +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_decimal_contextvar" >&5 +printf "%s\n" "$with_decimal_contextvar" >&6; } + +# Check for libmpdec machine flavor +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for decimal libmpdec machine" >&5 +printf %s "checking for decimal libmpdec machine... " >&6; } +case $ac_sys_system in #( + Darwin*) : libmpdec_system=Darwin ;; #( SunOS*) : libmpdec_system=sunos ;; #( @@ -12263,8 +14551,8 @@ esac libmpdec_machine=ansi32 fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libmpdec_machine" >&5 -$as_echo "$libmpdec_machine" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $libmpdec_machine" >&5 +printf "%s\n" "$libmpdec_machine" >&6; } case $libmpdec_machine in #( x64) : @@ -12302,17 +14590,17 @@ fi pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBNSL" >&5 -$as_echo_n "checking for LIBNSL... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for LIBNSL" >&5 +printf %s "checking for LIBNSL... " >&6; } if test -n "$LIBNSL_CFLAGS"; then pkg_cv_LIBNSL_CFLAGS="$LIBNSL_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libnsl\""; } >&5 + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libnsl\""; } >&5 ($PKG_CONFIG --exists --print-errors "libnsl") 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_LIBNSL_CFLAGS=`$PKG_CONFIG --cflags "libnsl" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes @@ -12326,10 +14614,10 @@ if test -n "$LIBNSL_LIBS"; then pkg_cv_LIBNSL_LIBS="$LIBNSL_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libnsl\""; } >&5 + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libnsl\""; } >&5 ($PKG_CONFIG --exists --print-errors "libnsl") 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_LIBNSL_LIBS=`$PKG_CONFIG --libs "libnsl" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes @@ -12343,8 +14631,8 @@ fi if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes @@ -12367,11 +14655,12 @@ save_LDFLAGS=$LDFLAGS save_LIBS=$LIBS - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing yp_match" >&5 -$as_echo_n "checking for library containing yp_match... " >&6; } -if ${ac_cv_search_yp_match+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing yp_match" >&5 +printf %s "checking for library containing yp_match... " >&6; } +if test ${ac_cv_search_yp_match+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -12379,49 +14668,51 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char yp_match (); int -main () +main (void) { return yp_match (); ; return 0; } _ACEOF -for ac_lib in '' nsl; do +for ac_lib in '' nsl +do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi - if ac_fn_c_try_link "$LINENO"; then : + if ac_fn_c_try_link "$LINENO" +then : ac_cv_search_yp_match=$ac_res fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext - if ${ac_cv_search_yp_match+:} false; then : + if test ${ac_cv_search_yp_match+y} +then : break fi done -if ${ac_cv_search_yp_match+:} false; then : +if test ${ac_cv_search_yp_match+y} +then : -else +else $as_nop ac_cv_search_yp_match=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_yp_match" >&5 -$as_echo "$ac_cv_search_yp_match" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_yp_match" >&5 +printf "%s\n" "$ac_cv_search_yp_match" >&6; } ac_res=$ac_cv_search_yp_match -if test "$ac_res" != no; then : +if test "$ac_res" != no +then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" have_nis=yes -else +else $as_nop have_nis=no fi @@ -12444,8 +14735,8 @@ esac LIBNSL_LIBS=${LIBNSL_LIBS-$libnsl} elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } LIBNSL_CFLAGS=${LIBNSL_CFLAGS-""} save_CFLAGS=$CFLAGS @@ -12454,11 +14745,12 @@ save_LDFLAGS=$LDFLAGS save_LIBS=$LIBS - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing yp_match" >&5 -$as_echo_n "checking for library containing yp_match... " >&6; } -if ${ac_cv_search_yp_match+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing yp_match" >&5 +printf %s "checking for library containing yp_match... " >&6; } +if test ${ac_cv_search_yp_match+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -12466,49 +14758,51 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char yp_match (); int -main () +main (void) { return yp_match (); ; return 0; } _ACEOF -for ac_lib in '' nsl; do +for ac_lib in '' nsl +do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi - if ac_fn_c_try_link "$LINENO"; then : + if ac_fn_c_try_link "$LINENO" +then : ac_cv_search_yp_match=$ac_res fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext - if ${ac_cv_search_yp_match+:} false; then : + if test ${ac_cv_search_yp_match+y} +then : break fi done -if ${ac_cv_search_yp_match+:} false; then : +if test ${ac_cv_search_yp_match+y} +then : -else +else $as_nop ac_cv_search_yp_match=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_yp_match" >&5 -$as_echo "$ac_cv_search_yp_match" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_yp_match" >&5 +printf "%s\n" "$ac_cv_search_yp_match" >&6; } ac_res=$ac_cv_search_yp_match -if test "$ac_res" != no; then : +if test "$ac_res" != no +then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" have_nis=yes -else +else $as_nop have_nis=no fi @@ -12533,12 +14827,13 @@ esac else LIBNSL_CFLAGS=$pkg_cv_LIBNSL_CFLAGS LIBNSL_LIBS=$pkg_cv_LIBNSL_LIBS - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } have_nis=yes fi -if test "x$have_nis" = xyes; then : +if test "x$have_nis" = xyes +then : save_CFLAGS=$CFLAGS save_CPPFLAGS=$CPPFLAGS @@ -12547,18 +14842,13 @@ save_LIBS=$LIBS CPPFLAGS="$CPPFLAGS $LIBNSL_CFLAGS" - for ac_header in rpc/rpc.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "rpc/rpc.h" "ac_cv_header_rpc_rpc_h" "$ac_includes_default" -if test "x$ac_cv_header_rpc_rpc_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_RPC_RPC_H 1 -_ACEOF + ac_fn_c_check_header_compile "$LINENO" "rpc/rpc.h" "ac_cv_header_rpc_rpc_h" "$ac_includes_default" +if test "x$ac_cv_header_rpc_rpc_h" = xyes +then : + printf "%s\n" "#define HAVE_RPC_RPC_H 1" >>confdefs.h fi -done - CFLAGS=$save_CFLAGS CPPFLAGS=$save_CPPFLAGS @@ -12580,7 +14870,8 @@ esac - if test "$ac_sys_system" = "Emscripten" -a -z "$LIBSQLITE3_CFLAGS" -a -z "$LIBSQLITE3_LIBS"; then : + if test "$ac_sys_system" = "Emscripten" -a -z "$LIBSQLITE3_CFLAGS" -a -z "$LIBSQLITE3_LIBS" +then : LIBSQLITE3_CFLAGS="-sUSE_SQLITE3" LIBSQLITE3_LIBS="-sUSE_SQLITE3" @@ -12592,17 +14883,17 @@ fi pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBSQLITE3" >&5 -$as_echo_n "checking for LIBSQLITE3... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for LIBSQLITE3" >&5 +printf %s "checking for LIBSQLITE3... " >&6; } if test -n "$LIBSQLITE3_CFLAGS"; then pkg_cv_LIBSQLITE3_CFLAGS="$LIBSQLITE3_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"sqlite3 >= 3.7.15\""; } >&5 + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"sqlite3 >= 3.7.15\""; } >&5 ($PKG_CONFIG --exists --print-errors "sqlite3 >= 3.7.15") 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_LIBSQLITE3_CFLAGS=`$PKG_CONFIG --cflags "sqlite3 >= 3.7.15" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes @@ -12616,10 +14907,10 @@ if test -n "$LIBSQLITE3_LIBS"; then pkg_cv_LIBSQLITE3_LIBS="$LIBSQLITE3_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"sqlite3 >= 3.7.15\""; } >&5 + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"sqlite3 >= 3.7.15\""; } >&5 ($PKG_CONFIG --exists --print-errors "sqlite3 >= 3.7.15") 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_LIBSQLITE3_LIBS=`$PKG_CONFIG --libs "sqlite3 >= 3.7.15" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes @@ -12633,8 +14924,8 @@ fi if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes @@ -12655,8 +14946,8 @@ fi elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } LIBSQLITE3_CFLAGS=${LIBSQLITE3_CFLAGS-""} LIBSQLITE3_LIBS=${LIBSQLITE3_LIBS-"-lsqlite3"} @@ -12665,8 +14956,8 @@ $as_echo "no" >&6; } else LIBSQLITE3_CFLAGS=$pkg_cv_LIBSQLITE3_CFLAGS LIBSQLITE3_LIBS=$pkg_cv_LIBSQLITE3_LIBS - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } fi as_fn_append LIBSQLITE3_CFLAGS ' -I$(srcdir)/Modules/_sqlite' @@ -12682,8 +14973,9 @@ save_LIBS=$LIBS CPPFLAGS="$CPPFLAGS $LIBSQLITE3_CFLAGS" LDFLAGS="$LIBSQLITE3_LIBS $LDFLAGS" - ac_fn_c_check_header_mongrel "$LINENO" "sqlite3.h" "ac_cv_header_sqlite3_h" "$ac_includes_default" -if test "x$ac_cv_header_sqlite3_h" = xyes; then : + ac_fn_c_check_header_compile "$LINENO" "sqlite3.h" "ac_cv_header_sqlite3_h" "$ac_includes_default" +if test "x$ac_cv_header_sqlite3_h" = xyes +then : have_sqlite3=yes @@ -12697,7 +14989,7 @@ if test "x$ac_cv_header_sqlite3_h" = xyes; then : #endif int -main () +main (void) { ; @@ -12705,15 +14997,17 @@ main () } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : have_supported_sqlite3=yes - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sqlite3_bind_double in -lsqlite3" >&5 -$as_echo_n "checking for sqlite3_bind_double in -lsqlite3... " >&6; } -if ${ac_cv_lib_sqlite3_sqlite3_bind_double+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sqlite3_bind_double in -lsqlite3" >&5 +printf %s "checking for sqlite3_bind_double in -lsqlite3... " >&6; } +if test ${ac_cv_lib_sqlite3_sqlite3_bind_double+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lsqlite3 $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -12722,37 +15016,34 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char sqlite3_bind_double (); int -main () +main (void) { return sqlite3_bind_double (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_lib_sqlite3_sqlite3_bind_double=yes -else +else $as_nop ac_cv_lib_sqlite3_sqlite3_bind_double=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sqlite3_sqlite3_bind_double" >&5 -$as_echo "$ac_cv_lib_sqlite3_sqlite3_bind_double" >&6; } -if test "x$ac_cv_lib_sqlite3_sqlite3_bind_double" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBSQLITE3 1 -_ACEOF +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sqlite3_sqlite3_bind_double" >&5 +printf "%s\n" "$ac_cv_lib_sqlite3_sqlite3_bind_double" >&6; } +if test "x$ac_cv_lib_sqlite3_sqlite3_bind_double" = xyes +then : + printf "%s\n" "#define HAVE_LIBSQLITE3 1" >>confdefs.h LIBS="-lsqlite3 $LIBS" -else +else $as_nop have_supported_sqlite3=no @@ -12760,11 +15051,12 @@ fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sqlite3_column_decltype in -lsqlite3" >&5 -$as_echo_n "checking for sqlite3_column_decltype in -lsqlite3... " >&6; } -if ${ac_cv_lib_sqlite3_sqlite3_column_decltype+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sqlite3_column_decltype in -lsqlite3" >&5 +printf %s "checking for sqlite3_column_decltype in -lsqlite3... " >&6; } +if test ${ac_cv_lib_sqlite3_sqlite3_column_decltype+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lsqlite3 $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -12773,37 +15065,34 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char sqlite3_column_decltype (); int -main () +main (void) { return sqlite3_column_decltype (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_lib_sqlite3_sqlite3_column_decltype=yes -else +else $as_nop ac_cv_lib_sqlite3_sqlite3_column_decltype=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sqlite3_sqlite3_column_decltype" >&5 -$as_echo "$ac_cv_lib_sqlite3_sqlite3_column_decltype" >&6; } -if test "x$ac_cv_lib_sqlite3_sqlite3_column_decltype" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBSQLITE3 1 -_ACEOF +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sqlite3_sqlite3_column_decltype" >&5 +printf "%s\n" "$ac_cv_lib_sqlite3_sqlite3_column_decltype" >&6; } +if test "x$ac_cv_lib_sqlite3_sqlite3_column_decltype" = xyes +then : + printf "%s\n" "#define HAVE_LIBSQLITE3 1" >>confdefs.h LIBS="-lsqlite3 $LIBS" -else +else $as_nop have_supported_sqlite3=no @@ -12811,11 +15100,12 @@ fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sqlite3_column_double in -lsqlite3" >&5 -$as_echo_n "checking for sqlite3_column_double in -lsqlite3... " >&6; } -if ${ac_cv_lib_sqlite3_sqlite3_column_double+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sqlite3_column_double in -lsqlite3" >&5 +printf %s "checking for sqlite3_column_double in -lsqlite3... " >&6; } +if test ${ac_cv_lib_sqlite3_sqlite3_column_double+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lsqlite3 $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -12824,37 +15114,34 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char sqlite3_column_double (); int -main () +main (void) { return sqlite3_column_double (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_lib_sqlite3_sqlite3_column_double=yes -else +else $as_nop ac_cv_lib_sqlite3_sqlite3_column_double=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sqlite3_sqlite3_column_double" >&5 -$as_echo "$ac_cv_lib_sqlite3_sqlite3_column_double" >&6; } -if test "x$ac_cv_lib_sqlite3_sqlite3_column_double" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBSQLITE3 1 -_ACEOF +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sqlite3_sqlite3_column_double" >&5 +printf "%s\n" "$ac_cv_lib_sqlite3_sqlite3_column_double" >&6; } +if test "x$ac_cv_lib_sqlite3_sqlite3_column_double" = xyes +then : + printf "%s\n" "#define HAVE_LIBSQLITE3 1" >>confdefs.h LIBS="-lsqlite3 $LIBS" -else +else $as_nop have_supported_sqlite3=no @@ -12862,11 +15149,12 @@ fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sqlite3_complete in -lsqlite3" >&5 -$as_echo_n "checking for sqlite3_complete in -lsqlite3... " >&6; } -if ${ac_cv_lib_sqlite3_sqlite3_complete+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sqlite3_complete in -lsqlite3" >&5 +printf %s "checking for sqlite3_complete in -lsqlite3... " >&6; } +if test ${ac_cv_lib_sqlite3_sqlite3_complete+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lsqlite3 $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -12875,37 +15163,34 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char sqlite3_complete (); int -main () +main (void) { return sqlite3_complete (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_lib_sqlite3_sqlite3_complete=yes -else +else $as_nop ac_cv_lib_sqlite3_sqlite3_complete=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sqlite3_sqlite3_complete" >&5 -$as_echo "$ac_cv_lib_sqlite3_sqlite3_complete" >&6; } -if test "x$ac_cv_lib_sqlite3_sqlite3_complete" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBSQLITE3 1 -_ACEOF +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sqlite3_sqlite3_complete" >&5 +printf "%s\n" "$ac_cv_lib_sqlite3_sqlite3_complete" >&6; } +if test "x$ac_cv_lib_sqlite3_sqlite3_complete" = xyes +then : + printf "%s\n" "#define HAVE_LIBSQLITE3 1" >>confdefs.h LIBS="-lsqlite3 $LIBS" -else +else $as_nop have_supported_sqlite3=no @@ -12913,11 +15198,12 @@ fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sqlite3_enable_shared_cache in -lsqlite3" >&5 -$as_echo_n "checking for sqlite3_enable_shared_cache in -lsqlite3... " >&6; } -if ${ac_cv_lib_sqlite3_sqlite3_enable_shared_cache+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sqlite3_progress_handler in -lsqlite3" >&5 +printf %s "checking for sqlite3_progress_handler in -lsqlite3... " >&6; } +if test ${ac_cv_lib_sqlite3_sqlite3_progress_handler+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lsqlite3 $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -12926,37 +15212,34 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char sqlite3_enable_shared_cache (); +char sqlite3_progress_handler (); int -main () +main (void) { -return sqlite3_enable_shared_cache (); +return sqlite3_progress_handler (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_sqlite3_sqlite3_enable_shared_cache=yes -else - ac_cv_lib_sqlite3_sqlite3_enable_shared_cache=no +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_sqlite3_sqlite3_progress_handler=yes +else $as_nop + ac_cv_lib_sqlite3_sqlite3_progress_handler=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sqlite3_sqlite3_enable_shared_cache" >&5 -$as_echo "$ac_cv_lib_sqlite3_sqlite3_enable_shared_cache" >&6; } -if test "x$ac_cv_lib_sqlite3_sqlite3_enable_shared_cache" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBSQLITE3 1 -_ACEOF +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sqlite3_sqlite3_progress_handler" >&5 +printf "%s\n" "$ac_cv_lib_sqlite3_sqlite3_progress_handler" >&6; } +if test "x$ac_cv_lib_sqlite3_sqlite3_progress_handler" = xyes +then : + printf "%s\n" "#define HAVE_LIBSQLITE3 1" >>confdefs.h LIBS="-lsqlite3 $LIBS" -else +else $as_nop have_supported_sqlite3=no @@ -12964,11 +15247,12 @@ fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sqlite3_progress_handler in -lsqlite3" >&5 -$as_echo_n "checking for sqlite3_progress_handler in -lsqlite3... " >&6; } -if ${ac_cv_lib_sqlite3_sqlite3_progress_handler+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sqlite3_result_double in -lsqlite3" >&5 +printf %s "checking for sqlite3_result_double in -lsqlite3... " >&6; } +if test ${ac_cv_lib_sqlite3_sqlite3_result_double+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lsqlite3 $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -12977,37 +15261,34 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char sqlite3_progress_handler (); +char sqlite3_result_double (); int -main () +main (void) { -return sqlite3_progress_handler (); +return sqlite3_result_double (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_sqlite3_sqlite3_progress_handler=yes -else - ac_cv_lib_sqlite3_sqlite3_progress_handler=no +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_sqlite3_sqlite3_result_double=yes +else $as_nop + ac_cv_lib_sqlite3_sqlite3_result_double=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sqlite3_sqlite3_progress_handler" >&5 -$as_echo "$ac_cv_lib_sqlite3_sqlite3_progress_handler" >&6; } -if test "x$ac_cv_lib_sqlite3_sqlite3_progress_handler" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBSQLITE3 1 -_ACEOF +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sqlite3_sqlite3_result_double" >&5 +printf "%s\n" "$ac_cv_lib_sqlite3_sqlite3_result_double" >&6; } +if test "x$ac_cv_lib_sqlite3_sqlite3_result_double" = xyes +then : + printf "%s\n" "#define HAVE_LIBSQLITE3 1" >>confdefs.h LIBS="-lsqlite3 $LIBS" -else +else $as_nop have_supported_sqlite3=no @@ -13015,11 +15296,12 @@ fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sqlite3_result_double in -lsqlite3" >&5 -$as_echo_n "checking for sqlite3_result_double in -lsqlite3... " >&6; } -if ${ac_cv_lib_sqlite3_sqlite3_result_double+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sqlite3_set_authorizer in -lsqlite3" >&5 +printf %s "checking for sqlite3_set_authorizer in -lsqlite3... " >&6; } +if test ${ac_cv_lib_sqlite3_sqlite3_set_authorizer+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lsqlite3 $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -13028,37 +15310,34 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char sqlite3_result_double (); +char sqlite3_set_authorizer (); int -main () +main (void) { -return sqlite3_result_double (); +return sqlite3_set_authorizer (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_sqlite3_sqlite3_result_double=yes -else - ac_cv_lib_sqlite3_sqlite3_result_double=no +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_sqlite3_sqlite3_set_authorizer=yes +else $as_nop + ac_cv_lib_sqlite3_sqlite3_set_authorizer=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sqlite3_sqlite3_result_double" >&5 -$as_echo "$ac_cv_lib_sqlite3_sqlite3_result_double" >&6; } -if test "x$ac_cv_lib_sqlite3_sqlite3_result_double" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBSQLITE3 1 -_ACEOF +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sqlite3_sqlite3_set_authorizer" >&5 +printf "%s\n" "$ac_cv_lib_sqlite3_sqlite3_set_authorizer" >&6; } +if test "x$ac_cv_lib_sqlite3_sqlite3_set_authorizer" = xyes +then : + printf "%s\n" "#define HAVE_LIBSQLITE3 1" >>confdefs.h LIBS="-lsqlite3 $LIBS" -else +else $as_nop have_supported_sqlite3=no @@ -13066,11 +15345,12 @@ fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sqlite3_set_authorizer in -lsqlite3" >&5 -$as_echo_n "checking for sqlite3_set_authorizer in -lsqlite3... " >&6; } -if ${ac_cv_lib_sqlite3_sqlite3_set_authorizer+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sqlite3_trace_v2 in -lsqlite3" >&5 +printf %s "checking for sqlite3_trace_v2 in -lsqlite3... " >&6; } +if test ${ac_cv_lib_sqlite3_sqlite3_trace_v2+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lsqlite3 $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -13079,96 +15359,43 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char sqlite3_set_authorizer (); +char sqlite3_trace_v2 (); int -main () -{ -return sqlite3_set_authorizer (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_sqlite3_sqlite3_set_authorizer=yes -else - ac_cv_lib_sqlite3_sqlite3_set_authorizer=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sqlite3_sqlite3_set_authorizer" >&5 -$as_echo "$ac_cv_lib_sqlite3_sqlite3_set_authorizer" >&6; } -if test "x$ac_cv_lib_sqlite3_sqlite3_set_authorizer" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBSQLITE3 1 -_ACEOF - - LIBS="-lsqlite3 $LIBS" - -else - - have_supported_sqlite3=no - -fi - - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sqlite3_trace_v2 in -lsqlite3" >&5 -$as_echo_n "checking for sqlite3_trace_v2 in -lsqlite3... " >&6; } -if ${ac_cv_lib_sqlite3_sqlite3_trace_v2+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lsqlite3 $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char sqlite3_trace_v2 (); -int -main () +main (void) { return sqlite3_trace_v2 (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_lib_sqlite3_sqlite3_trace_v2=yes -else +else $as_nop ac_cv_lib_sqlite3_sqlite3_trace_v2=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sqlite3_sqlite3_trace_v2" >&5 -$as_echo "$ac_cv_lib_sqlite3_sqlite3_trace_v2" >&6; } -if test "x$ac_cv_lib_sqlite3_sqlite3_trace_v2" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBSQLITE3 1 -_ACEOF +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sqlite3_sqlite3_trace_v2" >&5 +printf "%s\n" "$ac_cv_lib_sqlite3_sqlite3_trace_v2" >&6; } +if test "x$ac_cv_lib_sqlite3_sqlite3_trace_v2" = xyes +then : + printf "%s\n" "#define HAVE_LIBSQLITE3 1" >>confdefs.h LIBS="-lsqlite3 $LIBS" -else +else $as_nop - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sqlite3_trace in -lsqlite3" >&5 -$as_echo_n "checking for sqlite3_trace in -lsqlite3... " >&6; } -if ${ac_cv_lib_sqlite3_sqlite3_trace+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sqlite3_trace in -lsqlite3" >&5 +printf %s "checking for sqlite3_trace in -lsqlite3... " >&6; } +if test ${ac_cv_lib_sqlite3_sqlite3_trace+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lsqlite3 $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -13177,37 +15404,34 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char sqlite3_trace (); int -main () +main (void) { return sqlite3_trace (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_lib_sqlite3_sqlite3_trace=yes -else +else $as_nop ac_cv_lib_sqlite3_sqlite3_trace=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sqlite3_sqlite3_trace" >&5 -$as_echo "$ac_cv_lib_sqlite3_sqlite3_trace" >&6; } -if test "x$ac_cv_lib_sqlite3_sqlite3_trace" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBSQLITE3 1 -_ACEOF +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sqlite3_sqlite3_trace" >&5 +printf "%s\n" "$ac_cv_lib_sqlite3_sqlite3_trace" >&6; } +if test "x$ac_cv_lib_sqlite3_sqlite3_trace" = xyes +then : + printf "%s\n" "#define HAVE_LIBSQLITE3 1" >>confdefs.h LIBS="-lsqlite3 $LIBS" -else +else $as_nop have_supported_sqlite3=no @@ -13220,11 +15444,12 @@ fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sqlite3_value_double in -lsqlite3" >&5 -$as_echo_n "checking for sqlite3_value_double in -lsqlite3... " >&6; } -if ${ac_cv_lib_sqlite3_sqlite3_value_double+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sqlite3_value_double in -lsqlite3" >&5 +printf %s "checking for sqlite3_value_double in -lsqlite3... " >&6; } +if test ${ac_cv_lib_sqlite3_sqlite3_value_double+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lsqlite3 $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -13233,48 +15458,46 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char sqlite3_value_double (); int -main () +main (void) { return sqlite3_value_double (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_lib_sqlite3_sqlite3_value_double=yes -else +else $as_nop ac_cv_lib_sqlite3_sqlite3_value_double=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sqlite3_sqlite3_value_double" >&5 -$as_echo "$ac_cv_lib_sqlite3_sqlite3_value_double" >&6; } -if test "x$ac_cv_lib_sqlite3_sqlite3_value_double" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBSQLITE3 1 -_ACEOF +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sqlite3_sqlite3_value_double" >&5 +printf "%s\n" "$ac_cv_lib_sqlite3_sqlite3_value_double" >&6; } +if test "x$ac_cv_lib_sqlite3_sqlite3_value_double" = xyes +then : + printf "%s\n" "#define HAVE_LIBSQLITE3 1" >>confdefs.h LIBS="-lsqlite3 $LIBS" -else +else $as_nop have_supported_sqlite3=no fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sqlite3_load_extension in -lsqlite3" >&5 -$as_echo_n "checking for sqlite3_load_extension in -lsqlite3... " >&6; } -if ${ac_cv_lib_sqlite3_sqlite3_load_extension+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sqlite3_load_extension in -lsqlite3" >&5 +printf %s "checking for sqlite3_load_extension in -lsqlite3... " >&6; } +if test ${ac_cv_lib_sqlite3_sqlite3_load_extension+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lsqlite3 $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -13283,41 +15506,41 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char sqlite3_load_extension (); int -main () +main (void) { return sqlite3_load_extension (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_lib_sqlite3_sqlite3_load_extension=yes -else +else $as_nop ac_cv_lib_sqlite3_sqlite3_load_extension=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sqlite3_sqlite3_load_extension" >&5 -$as_echo "$ac_cv_lib_sqlite3_sqlite3_load_extension" >&6; } -if test "x$ac_cv_lib_sqlite3_sqlite3_load_extension" = xyes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sqlite3_sqlite3_load_extension" >&5 +printf "%s\n" "$ac_cv_lib_sqlite3_sqlite3_load_extension" >&6; } +if test "x$ac_cv_lib_sqlite3_sqlite3_load_extension" = xyes +then : have_sqlite3_load_extension=yes -else +else $as_nop have_sqlite3_load_extension=no fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sqlite3_serialize in -lsqlite3" >&5 -$as_echo_n "checking for sqlite3_serialize in -lsqlite3... " >&6; } -if ${ac_cv_lib_sqlite3_sqlite3_serialize+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sqlite3_serialize in -lsqlite3" >&5 +printf %s "checking for sqlite3_serialize in -lsqlite3... " >&6; } +if test ${ac_cv_lib_sqlite3_sqlite3_serialize+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lsqlite3 $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -13326,49 +15549,47 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char sqlite3_serialize (); int -main () +main (void) { return sqlite3_serialize (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_lib_sqlite3_sqlite3_serialize=yes -else +else $as_nop ac_cv_lib_sqlite3_sqlite3_serialize=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sqlite3_sqlite3_serialize" >&5 -$as_echo "$ac_cv_lib_sqlite3_sqlite3_serialize" >&6; } -if test "x$ac_cv_lib_sqlite3_sqlite3_serialize" = xyes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sqlite3_sqlite3_serialize" >&5 +printf "%s\n" "$ac_cv_lib_sqlite3_sqlite3_serialize" >&6; } +if test "x$ac_cv_lib_sqlite3_sqlite3_serialize" = xyes +then : -$as_echo "#define PY_SQLITE_HAVE_SERIALIZE 1" >>confdefs.h +printf "%s\n" "#define PY_SQLITE_HAVE_SERIALIZE 1" >>confdefs.h fi -else +else $as_nop have_supported_sqlite3=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi - CFLAGS=$save_CFLAGS CPPFLAGS=$save_CPPFLAGS LDFLAGS=$save_LDFLAGS @@ -13376,32 +15597,34 @@ LIBS=$save_LIBS -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --enable-loadable-sqlite-extensions" >&5 -$as_echo_n "checking for --enable-loadable-sqlite-extensions... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --enable-loadable-sqlite-extensions" >&5 +printf %s "checking for --enable-loadable-sqlite-extensions... " >&6; } # Check whether --enable-loadable-sqlite-extensions was given. -if test "${enable_loadable_sqlite_extensions+set}" = set; then : +if test ${enable_loadable_sqlite_extensions+y} +then : enableval=$enable_loadable_sqlite_extensions; - if test "x$have_sqlite3_load_extension" = xno; then : + if test "x$have_sqlite3_load_extension" = xno +then : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: n/a" >&5 -$as_echo "n/a" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Your version of SQLite does not support loadable extensions" >&5 -$as_echo "$as_me: WARNING: Your version of SQLite does not support loadable extensions" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: n/a" >&5 +printf "%s\n" "n/a" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Your version of SQLite does not support loadable extensions" >&5 +printf "%s\n" "$as_me: WARNING: Your version of SQLite does not support loadable extensions" >&2;} -else +else $as_nop - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } -$as_echo "#define PY_SQLITE_ENABLE_LOAD_EXTENSION 1" >>confdefs.h +printf "%s\n" "#define PY_SQLITE_ENABLE_LOAD_EXTENSION 1" >>confdefs.h fi -else +else $as_nop - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -13416,25 +15639,25 @@ for _QUERY in \ "tcl85 >= 8.5.12 tk85 >= 8.5.12" \ ; do if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$_QUERY\""; } >&5 + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$_QUERY\""; } >&5 ($PKG_CONFIG --exists --print-errors "$_QUERY") 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for TCLTK" >&5 -$as_echo_n "checking for TCLTK... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for TCLTK" >&5 +printf %s "checking for TCLTK... " >&6; } if test -n "$TCLTK_CFLAGS"; then pkg_cv_TCLTK_CFLAGS="$TCLTK_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$_QUERY\""; } >&5 + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$_QUERY\""; } >&5 ($PKG_CONFIG --exists --print-errors "$_QUERY") 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_TCLTK_CFLAGS=`$PKG_CONFIG --cflags "$_QUERY" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes @@ -13448,10 +15671,10 @@ if test -n "$TCLTK_LIBS"; then pkg_cv_TCLTK_LIBS="$TCLTK_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$_QUERY\""; } >&5 + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$_QUERY\""; } >&5 ($PKG_CONFIG --exists --print-errors "$_QUERY") 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_TCLTK_LIBS=`$PKG_CONFIG --libs "$_QUERY" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes @@ -13465,8 +15688,8 @@ fi if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes @@ -13483,24 +15706,26 @@ fi found_tcltk=no elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } found_tcltk=no else TCLTK_CFLAGS=$pkg_cv_TCLTK_CFLAGS TCLTK_LIBS=$pkg_cv_TCLTK_LIBS - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } found_tcltk=yes fi fi - if test "x$found_tcltk" = xyes; then : + if test "x$found_tcltk" = xyes +then : break fi done -if test "x$found_tcltk" = xno; then : +if test "x$found_tcltk" = xno +then : TCLTK_CFLAGS=${TCLTK_CFLAGS-""} TCLTK_LIBS=${TCLTK_LIBS-""} @@ -13511,25 +15736,25 @@ case $ac_sys_system in #( FreeBSD*) : if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"x11\""; } >&5 + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"x11\""; } >&5 ($PKG_CONFIG --exists --print-errors "x11") 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for X11" >&5 -$as_echo_n "checking for X11... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for X11" >&5 +printf %s "checking for X11... " >&6; } if test -n "$X11_CFLAGS"; then pkg_cv_X11_CFLAGS="$X11_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"x11\""; } >&5 + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"x11\""; } >&5 ($PKG_CONFIG --exists --print-errors "x11") 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_X11_CFLAGS=`$PKG_CONFIG --cflags "x11" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes @@ -13543,10 +15768,10 @@ if test -n "$X11_LIBS"; then pkg_cv_X11_LIBS="$X11_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"x11\""; } >&5 + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"x11\""; } >&5 ($PKG_CONFIG --exists --print-errors "x11") 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_X11_LIBS=`$PKG_CONFIG --libs "x11" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes @@ -13560,8 +15785,8 @@ fi if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes @@ -13587,10 +15812,10 @@ Alternatively, you may set the environment variables X11_CFLAGS and X11_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details." "$LINENO" 5 elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. @@ -13604,8 +15829,8 @@ See \`config.log' for more details" "$LINENO" 5; } else X11_CFLAGS=$pkg_cv_X11_CFLAGS X11_LIBS=$pkg_cv_X11_LIBS - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } TCLTK_CFLAGS="$TCLTK_CFLAGS $X11_CFLAGS" TCLTK_LIBS="$TCLTK_LIBS $X11_LIBS" @@ -13651,7 +15876,7 @@ save_LIBS=$LIBS #endif int -main () +main (void) { void *x1 = Tcl_Init; @@ -13662,17 +15887,18 @@ main () } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : have_tcltk=yes as_fn_append TCLTK_CFLAGS " -Wno-strict-prototypes -DWITH_APPINIT=1" -else +else $as_nop have_tcltk=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext CFLAGS=$save_CFLAGS @@ -13692,19 +15918,19 @@ save_LIBS=$LIBS CPPFLAGS="$CPPFLAGS $GDBM_CFLAGS" LDFLAGS="$GDBM_LIBS $LDFLAGS" - for ac_header in gdbm.h + for ac_header in gdbm.h do : - ac_fn_c_check_header_mongrel "$LINENO" "gdbm.h" "ac_cv_header_gdbm_h" "$ac_includes_default" -if test "x$ac_cv_header_gdbm_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_GDBM_H 1 -_ACEOF - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gdbm_open in -lgdbm" >&5 -$as_echo_n "checking for gdbm_open in -lgdbm... " >&6; } -if ${ac_cv_lib_gdbm_gdbm_open+:} false; then : - $as_echo_n "(cached) " >&6 -else + ac_fn_c_check_header_compile "$LINENO" "gdbm.h" "ac_cv_header_gdbm_h" "$ac_includes_default" +if test "x$ac_cv_header_gdbm_h" = xyes +then : + printf "%s\n" "#define HAVE_GDBM_H 1" >>confdefs.h + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gdbm_open in -lgdbm" >&5 +printf %s "checking for gdbm_open in -lgdbm... " >&6; } +if test ${ac_cv_lib_gdbm_gdbm_open+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lgdbm $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -13713,46 +15939,44 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char gdbm_open (); int -main () +main (void) { return gdbm_open (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_lib_gdbm_gdbm_open=yes -else +else $as_nop ac_cv_lib_gdbm_gdbm_open=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gdbm_gdbm_open" >&5 -$as_echo "$ac_cv_lib_gdbm_gdbm_open" >&6; } -if test "x$ac_cv_lib_gdbm_gdbm_open" = xyes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gdbm_gdbm_open" >&5 +printf "%s\n" "$ac_cv_lib_gdbm_gdbm_open" >&6; } +if test "x$ac_cv_lib_gdbm_gdbm_open" = xyes +then : have_gdbm=yes GDBM_LIBS=${GDBM_LIBS-"-lgdbm"} -else +else $as_nop have_gdbm=no fi -else +else $as_nop have_gdbm=no fi done - CFLAGS=$save_CFLAGS CPPFLAGS=$save_CPPFLAGS LDFLAGS=$save_LDFLAGS @@ -13760,246 +15984,279 @@ LIBS=$save_LIBS -# check for _dbmmodule.c dependencies -for ac_header in ndbm.h + for ac_header in ndbm.h do : - ac_fn_c_check_header_mongrel "$LINENO" "ndbm.h" "ac_cv_header_ndbm_h" "$ac_includes_default" -if test "x$ac_cv_header_ndbm_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_NDBM_H 1 -_ACEOF + ac_fn_c_check_header_compile "$LINENO" "ndbm.h" "ac_cv_header_ndbm_h" "$ac_includes_default" +if test "x$ac_cv_header_ndbm_h" = xyes +then : + printf "%s\n" "#define HAVE_NDBM_H 1" >>confdefs.h - LIBS_SAVE="$LIBS" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dbm_open in -lndbm" >&5 -$as_echo_n "checking for dbm_open in -lndbm... " >&6; } -if ${ac_cv_lib_ndbm_dbm_open+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lndbm $LIBS" + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing dbm_open" >&5 +printf %s "checking for library containing dbm_open... " >&6; } +if test ${ac_cv_search_dbm_open+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char dbm_open (); int -main () +main (void) { return dbm_open (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_ndbm_dbm_open=yes -else - ac_cv_lib_ndbm_dbm_open=no +for ac_lib in '' ndbm gdbm_compat +do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO" +then : + ac_cv_search_dbm_open=$ac_res fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext + if test ${ac_cv_search_dbm_open+y} +then : + break fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ndbm_dbm_open" >&5 -$as_echo "$ac_cv_lib_ndbm_dbm_open" >&6; } -if test "x$ac_cv_lib_ndbm_dbm_open" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBNDBM 1 -_ACEOF - - LIBS="-lndbm $LIBS" +done +if test ${ac_cv_search_dbm_open+y} +then : +else $as_nop + ac_cv_search_dbm_open=no fi - - LIBS="$LIBS_SAVE" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dbm_open in -lgdbm_compat" >&5 -$as_echo_n "checking for dbm_open in -lgdbm_compat... " >&6; } -if ${ac_cv_lib_gdbm_compat_dbm_open+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lgdbm_compat $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char dbm_open (); -int -main () -{ -return dbm_open (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_gdbm_compat_dbm_open=yes -else - ac_cv_lib_gdbm_compat_dbm_open=no +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_dbm_open" >&5 +printf "%s\n" "$ac_cv_search_dbm_open" >&6; } +ac_res=$ac_cv_search_dbm_open +if test "$ac_res" != no +then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gdbm_compat_dbm_open" >&5 -$as_echo "$ac_cv_lib_gdbm_compat_dbm_open" >&6; } -if test "x$ac_cv_lib_gdbm_compat_dbm_open" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBGDBM_COMPAT 1 -_ACEOF - LIBS="-lgdbm_compat $LIBS" -fi +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + - LIBS="$LIBS_SAVE" fi done +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ndbm presence and linker args" >&5 +printf %s "checking for ndbm presence and linker args... " >&6; } +case $ac_cv_search_dbm_open in #( + *ndbm*|*gdbm_compat*) : -# "gdbm-ndbm.h" and "gdbm/ndbm.h" are both normalized to "gdbm_ndbm_h" -# unset ac_cv_header_gdbm_ndbm_h to prevent false positive cache hits. -{ ac_cv_header_gdbm_ndbm_h=; unset ac_cv_header_gdbm_ndbm_h;} -if ${ac_cv_header_gdbm_slash_ndbm_h+:} false; then : - $as_echo_n "(cached) " >&6 -else + dbm_ndbm="$ac_cv_search_dbm_open" + have_ndbm=yes + ;; #( + none*) : + + dbm_ndbm="" + have_ndbm=yes + ;; #( + no) : + have_ndbm=no + ;; #( + *) : + ;; +esac +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_ndbm ($dbm_ndbm)" >&5 +printf "%s\n" "$have_ndbm ($dbm_ndbm)" >&6; } - ac_fn_c_check_header_mongrel "$LINENO" "gdbm/ndbm.h" "ac_cv_header_gdbm_ndbm_h" "$ac_includes_default" -if test "x$ac_cv_header_gdbm_ndbm_h" = xyes; then : +{ ac_cv_header_gdbm_ndbm_h=; unset ac_cv_header_gdbm_ndbm_h;} +if test ${ac_cv_header_gdbm_slash_ndbm_h+y} +then : + printf %s "(cached) " >&6 +else $as_nop + + ac_fn_c_check_header_compile "$LINENO" "gdbm/ndbm.h" "ac_cv_header_gdbm_ndbm_h" "$ac_includes_default" +if test "x$ac_cv_header_gdbm_ndbm_h" = xyes +then : ac_cv_header_gdbm_slash_ndbm_h=yes -else +else $as_nop ac_cv_header_gdbm_slash_ndbm_h=no fi - fi -if test "x$ac_cv_header_gdbm_slash_ndbm_h" = xyes; then : +if test "x$ac_cv_header_gdbm_slash_ndbm_h" = xyes +then : -$as_echo "#define HAVE_GDBM_NDBM_H 1" >>confdefs.h +printf "%s\n" "#define HAVE_GDBM_NDBM_H 1" >>confdefs.h fi { ac_cv_header_gdbm_ndbm_h=; unset ac_cv_header_gdbm_ndbm_h;} -if ${ac_cv_header_gdbm_dash_ndbm_h+:} false; then : - $as_echo_n "(cached) " >&6 -else - - ac_fn_c_check_header_mongrel "$LINENO" "gdbm-ndbm.h" "ac_cv_header_gdbm_ndbm_h" "$ac_includes_default" -if test "x$ac_cv_header_gdbm_ndbm_h" = xyes; then : +if test ${ac_cv_header_gdbm_dash_ndbm_h+y} +then : + printf %s "(cached) " >&6 +else $as_nop + + ac_fn_c_check_header_compile "$LINENO" "gdbm-ndbm.h" "ac_cv_header_gdbm_ndbm_h" "$ac_includes_default" +if test "x$ac_cv_header_gdbm_ndbm_h" = xyes +then : ac_cv_header_gdbm_dash_ndbm_h=yes -else +else $as_nop ac_cv_header_gdbm_dash_ndbm_h=no fi - fi -if test "x$ac_cv_header_gdbm_dash_ndbm_h" = xyes; then : +if test "x$ac_cv_header_gdbm_dash_ndbm_h" = xyes +then : -$as_echo "#define HAVE_GDBM_DASH_NDBM_H 1" >>confdefs.h +printf "%s\n" "#define HAVE_GDBM_DASH_NDBM_H 1" >>confdefs.h fi { ac_cv_header_gdbm_ndbm_h=; unset ac_cv_header_gdbm_ndbm_h;} if test "$ac_cv_header_gdbm_slash_ndbm_h" = yes -o "$ac_cv_header_gdbm_dash_ndbm_h" = yes; then - LIBS_SAVE="$LIBS" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dbm_open in -lgdbm_compat" >&5 -$as_echo_n "checking for dbm_open in -lgdbm_compat... " >&6; } -if ${ac_cv_lib_gdbm_compat_dbm_open+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lgdbm_compat $LIBS" + { ac_cv_search_dbm_open=; unset ac_cv_search_dbm_open;} + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing dbm_open" >&5 +printf %s "checking for library containing dbm_open... " >&6; } +if test ${ac_cv_search_dbm_open+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char dbm_open (); int -main () +main (void) { return dbm_open (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_gdbm_compat_dbm_open=yes -else - ac_cv_lib_gdbm_compat_dbm_open=no +for ac_lib in '' gdbm_compat +do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO" +then : + ac_cv_search_dbm_open=$ac_res fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext + if test ${ac_cv_search_dbm_open+y} +then : + break fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gdbm_compat_dbm_open" >&5 -$as_echo "$ac_cv_lib_gdbm_compat_dbm_open" >&6; } -if test "x$ac_cv_lib_gdbm_compat_dbm_open" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBGDBM_COMPAT 1 -_ACEOF - - LIBS="-lgdbm_compat $LIBS" +done +if test ${ac_cv_search_dbm_open+y} +then : +else $as_nop + ac_cv_search_dbm_open=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_dbm_open" >&5 +printf "%s\n" "$ac_cv_search_dbm_open" >&6; } +ac_res=$ac_cv_search_dbm_open +if test "$ac_res" != no +then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + have_gdbm_compat=yes +else $as_nop + have_gdbm_compat=no fi - LIBS="$LIBS_SAVE" + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + fi # Check for libdb >= 5 with dbm_open() # db.h re-defines the name of the function -for ac_header in db.h + for ac_header in db.h do : - ac_fn_c_check_header_mongrel "$LINENO" "db.h" "ac_cv_header_db_h" "$ac_includes_default" -if test "x$ac_cv_header_db_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_DB_H 1 -_ACEOF + ac_fn_c_check_header_compile "$LINENO" "db.h" "ac_cv_header_db_h" "$ac_includes_default" +if test "x$ac_cv_header_db_h" = xyes +then : + printf "%s\n" "#define HAVE_DB_H 1" >>confdefs.h + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libdb" >&5 +printf %s "checking for libdb... " >&6; } +if test ${ac_cv_have_libdb+y} +then : + printf %s "(cached) " >&6 +else $as_nop + + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libdb" >&5 -$as_echo_n "checking for libdb... " >&6; } -if ${ac_cv_have_libdb+:} false; then : - $as_echo_n "(cached) " >&6 -else - LIBS_SAVE="$LIBS" - LIBS="$LIBS -ldb" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + LIBS="$LIBS -ldb" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - #define DB_DBM_HSEARCH 1 - #include - #if DB_VERSION_MAJOR < 5 - #error "dh.h: DB_VERSION_MAJOR < 5 is not supported." - #endif + #define DB_DBM_HSEARCH 1 + #include + #if DB_VERSION_MAJOR < 5 + #error "dh.h: DB_VERSION_MAJOR < 5 is not supported." + #endif int -main () +main (void) { DBM *dbm = dbm_open(NULL, 0, 0) ; @@ -14007,22 +16264,30 @@ DBM *dbm = dbm_open(NULL, 0, 0) } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_have_libdb=yes -else +else $as_nop ac_cv_have_libdb=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext - LIBS="$LIBS_SAVE" + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_libdb" >&5 -$as_echo "$ac_cv_have_libdb" >&6; } - if test "x$ac_cv_have_libdb" = xyes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_libdb" >&5 +printf "%s\n" "$ac_cv_have_libdb" >&6; } + if test "x$ac_cv_have_libdb" = xyes +then : -$as_echo "#define HAVE_LIBDB 1" >>confdefs.h +printf "%s\n" "#define HAVE_LIBDB 1" >>confdefs.h fi @@ -14031,15 +16296,15 @@ fi done - # Check for --with-dbmliborder -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-dbmliborder" >&5 -$as_echo_n "checking for --with-dbmliborder... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-dbmliborder" >&5 +printf %s "checking for --with-dbmliborder... " >&6; } # Check whether --with-dbmliborder was given. -if test "${with_dbmliborder+set}" = set; then : +if test ${with_dbmliborder+y} +then : withval=$with_dbmliborder; -else +else $as_nop with_dbmliborder=gdbm:ndbm:bdb fi @@ -14061,13 +16326,51 @@ for db in $with_dbmliborder; do esac done IFS=$as_save_IFS -if test "x$with_dbmliborder" = xerror; then : +if test "x$with_dbmliborder" = xerror +then : as_fn_error $? "proper usage is --with-dbmliborder=db1:db2:... (gdbm:ndbm:bdb)" "$LINENO" 5 fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_dbmliborder" >&5 -$as_echo "$with_dbmliborder" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_dbmliborder" >&5 +printf "%s\n" "$with_dbmliborder" >&6; } + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for _dbm module CFLAGS and LIBS" >&5 +printf %s "checking for _dbm module CFLAGS and LIBS... " >&6; } +have_dbm=no +as_save_IFS=$IFS +IFS=: +for db in $with_dbmliborder; do + case "$db" in + ndbm) + if test "$have_ndbm" = yes; then + DBM_CFLAGS="-DUSE_NDBM" + DBM_LIBS="$dbm_ndbm" + have_dbm=yes + break + fi + ;; + gdbm) + if test "$have_gdbm_compat" = yes; then + DBM_CFLAGS="-DUSE_GDBM_COMPAT" + DBM_LIBS="-lgdbm_compat" + have_dbm=yes + break + fi + ;; + bdb) + if test "$ac_cv_have_libdb" = yes; then + DBM_CFLAGS="-DUSE_BERKDB" + DBM_LIBS="-ldb" + have_dbm=yes + break + fi + ;; + esac +done +IFS=$as_save_IFS +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $DBM_CFLAGS $DBM_LIBS" >&5 +printf "%s\n" "$DBM_CFLAGS $DBM_LIBS" >&6; } # Templates for things AC_DEFINEd more than once. # For a single AC_DEFINE, no template is needed. @@ -14076,7 +16379,7 @@ $as_echo "$with_dbmliborder" >&6; } if test "$ac_cv_pthread_is_default" = yes then # Defining _REENTRANT on system with POSIX threads should not hurt. - $as_echo "#define _REENTRANT 1" >>confdefs.h + printf "%s\n" "#define _REENTRANT 1" >>confdefs.h posix_threads=yes if test "$ac_sys_system" = "SunOS"; then @@ -14111,8 +16414,8 @@ else # According to the POSIX spec, a pthreads implementation must # define _POSIX_THREADS in unistd.h. Some apparently don't # (e.g. gnu pth with pthread emulation) - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _POSIX_THREADS in unistd.h" >&5 -$as_echo_n "checking for _POSIX_THREADS in unistd.h... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for _POSIX_THREADS in unistd.h" >&5 +printf %s "checking for _POSIX_THREADS in unistd.h... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -14123,25 +16426,26 @@ yes _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "yes" >/dev/null 2>&1; then : + $EGREP "yes" >/dev/null 2>&1 +then : unistd_defines_pthreads=yes -else +else $as_nop unistd_defines_pthreads=no fi -rm -f conftest* +rm -rf conftest* - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $unistd_defines_pthreads" >&5 -$as_echo "$unistd_defines_pthreads" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $unistd_defines_pthreads" >&5 +printf "%s\n" "$unistd_defines_pthreads" >&6; } - $as_echo "#define _REENTRANT 1" >>confdefs.h + printf "%s\n" "#define _REENTRANT 1" >>confdefs.h # Just looking for pthread_create in libpthread is not enough: # on HP/UX, pthread.h renames pthread_create to a different symbol name. # So we really have to include pthread.h, and then link. _libs=$LIBS LIBS="$LIBS -lpthread" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_create in -lpthread" >&5 -$as_echo_n "checking for pthread_create in -lpthread... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for pthread_create in -lpthread" >&5 +printf %s "checking for pthread_create in -lpthread... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -14151,7 +16455,7 @@ $as_echo_n "checking for pthread_create in -lpthread... " >&6; } void * start_routine (void *arg) { exit (0); } int -main () +main (void) { pthread_create (NULL, NULL, start_routine, NULL) @@ -14159,27 +16463,30 @@ pthread_create (NULL, NULL, start_routine, NULL) return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } posix_threads=yes -else +else $as_nop LIBS=$_libs ac_fn_c_check_func "$LINENO" "pthread_detach" "ac_cv_func_pthread_detach" -if test "x$ac_cv_func_pthread_detach" = xyes; then : +if test "x$ac_cv_func_pthread_detach" = xyes +then : posix_threads=yes -else +else $as_nop - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_create in -lpthreads" >&5 -$as_echo_n "checking for pthread_create in -lpthreads... " >&6; } -if ${ac_cv_lib_pthreads_pthread_create+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for pthread_create in -lpthreads" >&5 +printf %s "checking for pthread_create in -lpthreads... " >&6; } +if test ${ac_cv_lib_pthreads_pthread_create+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lpthreads $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -14188,41 +16495,41 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char pthread_create (); int -main () +main (void) { return pthread_create (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_lib_pthreads_pthread_create=yes -else +else $as_nop ac_cv_lib_pthreads_pthread_create=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthreads_pthread_create" >&5 -$as_echo "$ac_cv_lib_pthreads_pthread_create" >&6; } -if test "x$ac_cv_lib_pthreads_pthread_create" = xyes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthreads_pthread_create" >&5 +printf "%s\n" "$ac_cv_lib_pthreads_pthread_create" >&6; } +if test "x$ac_cv_lib_pthreads_pthread_create" = xyes +then : posix_threads=yes LIBS="$LIBS -lpthreads" -else +else $as_nop - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_create in -lc_r" >&5 -$as_echo_n "checking for pthread_create in -lc_r... " >&6; } -if ${ac_cv_lib_c_r_pthread_create+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for pthread_create in -lc_r" >&5 +printf %s "checking for pthread_create in -lc_r... " >&6; } +if test ${ac_cv_lib_c_r_pthread_create+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lc_r $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -14231,41 +16538,41 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char pthread_create (); int -main () +main (void) { return pthread_create (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_lib_c_r_pthread_create=yes -else +else $as_nop ac_cv_lib_c_r_pthread_create=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_c_r_pthread_create" >&5 -$as_echo "$ac_cv_lib_c_r_pthread_create" >&6; } -if test "x$ac_cv_lib_c_r_pthread_create" = xyes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_c_r_pthread_create" >&5 +printf "%s\n" "$ac_cv_lib_c_r_pthread_create" >&6; } +if test "x$ac_cv_lib_c_r_pthread_create" = xyes +then : posix_threads=yes LIBS="$LIBS -lc_r" -else +else $as_nop - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __pthread_create_system in -lpthread" >&5 -$as_echo_n "checking for __pthread_create_system in -lpthread... " >&6; } -if ${ac_cv_lib_pthread___pthread_create_system+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for __pthread_create_system in -lpthread" >&5 +printf %s "checking for __pthread_create_system in -lpthread... " >&6; } +if test ${ac_cv_lib_pthread___pthread_create_system+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lpthread $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -14274,41 +16581,41 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char __pthread_create_system (); int -main () +main (void) { return __pthread_create_system (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_lib_pthread___pthread_create_system=yes -else +else $as_nop ac_cv_lib_pthread___pthread_create_system=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread___pthread_create_system" >&5 -$as_echo "$ac_cv_lib_pthread___pthread_create_system" >&6; } -if test "x$ac_cv_lib_pthread___pthread_create_system" = xyes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread___pthread_create_system" >&5 +printf "%s\n" "$ac_cv_lib_pthread___pthread_create_system" >&6; } +if test "x$ac_cv_lib_pthread___pthread_create_system" = xyes +then : posix_threads=yes LIBS="$LIBS -lpthread" -else +else $as_nop - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_create in -lcma" >&5 -$as_echo_n "checking for pthread_create in -lcma... " >&6; } -if ${ac_cv_lib_cma_pthread_create+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for pthread_create in -lcma" >&5 +printf %s "checking for pthread_create in -lcma... " >&6; } +if test ${ac_cv_lib_cma_pthread_create+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lcma $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -14317,35 +16624,34 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char pthread_create (); int -main () +main (void) { return pthread_create (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_lib_cma_pthread_create=yes -else +else $as_nop ac_cv_lib_cma_pthread_create=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_cma_pthread_create" >&5 -$as_echo "$ac_cv_lib_cma_pthread_create" >&6; } -if test "x$ac_cv_lib_cma_pthread_create" = xyes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_cma_pthread_create" >&5 +printf "%s\n" "$ac_cv_lib_cma_pthread_create" >&6; } +if test "x$ac_cv_lib_cma_pthread_create" = xyes +then : posix_threads=yes LIBS="$LIBS -lcma" -else +else $as_nop case $ac_sys_system in #( WASI) : @@ -14366,14 +16672,15 @@ fi fi fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for usconfig in -lmpc" >&5 -$as_echo_n "checking for usconfig in -lmpc... " >&6; } -if ${ac_cv_lib_mpc_usconfig+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for usconfig in -lmpc" >&5 +printf %s "checking for usconfig in -lmpc... " >&6; } +if test ${ac_cv_lib_mpc_usconfig+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lmpc $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -14382,30 +16689,29 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char usconfig (); int -main () +main (void) { return usconfig (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_lib_mpc_usconfig=yes -else +else $as_nop ac_cv_lib_mpc_usconfig=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_mpc_usconfig" >&5 -$as_echo "$ac_cv_lib_mpc_usconfig" >&6; } -if test "x$ac_cv_lib_mpc_usconfig" = xyes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_mpc_usconfig" >&5 +printf "%s\n" "$ac_cv_lib_mpc_usconfig" >&6; } +if test "x$ac_cv_lib_mpc_usconfig" = xyes +then : LIBS="$LIBS -lmpc" @@ -14417,38 +16723,40 @@ fi if test "$posix_threads" = "yes"; then if test "$unistd_defines_pthreads" = "no"; then -$as_echo "#define _POSIX_THREADS 1" >>confdefs.h +printf "%s\n" "#define _POSIX_THREADS 1" >>confdefs.h fi # Bug 662787: Using semaphores causes unexplicable hangs on Solaris 8. case $ac_sys_system/$ac_sys_release in SunOS/5.6) -$as_echo "#define HAVE_PTHREAD_DESTRUCTOR 1" >>confdefs.h +printf "%s\n" "#define HAVE_PTHREAD_DESTRUCTOR 1" >>confdefs.h ;; SunOS/5.8) -$as_echo "#define HAVE_BROKEN_POSIX_SEMAPHORES 1" >>confdefs.h +printf "%s\n" "#define HAVE_BROKEN_POSIX_SEMAPHORES 1" >>confdefs.h ;; AIX/*) -$as_echo "#define HAVE_BROKEN_POSIX_SEMAPHORES 1" >>confdefs.h +printf "%s\n" "#define HAVE_BROKEN_POSIX_SEMAPHORES 1" >>confdefs.h ;; NetBSD/*) -$as_echo "#define HAVE_BROKEN_POSIX_SEMAPHORES 1" >>confdefs.h +printf "%s\n" "#define HAVE_BROKEN_POSIX_SEMAPHORES 1" >>confdefs.h ;; esac - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if PTHREAD_SCOPE_SYSTEM is supported" >&5 -$as_echo_n "checking if PTHREAD_SCOPE_SYSTEM is supported... " >&6; } -if ${ac_cv_pthread_system_supported+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "$cross_compiling" = yes; then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if PTHREAD_SCOPE_SYSTEM is supported" >&5 +printf %s "checking if PTHREAD_SCOPE_SYSTEM is supported... " >&6; } +if test ${ac_cv_pthread_system_supported+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test "$cross_compiling" = yes +then : ac_cv_pthread_system_supported=no -else +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -14466,9 +16774,10 @@ else return (0); } _ACEOF -if ac_fn_c_try_run "$LINENO"; then : +if ac_fn_c_try_run "$LINENO" +then : ac_cv_pthread_system_supported=yes -else +else $as_nop ac_cv_pthread_system_supported=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -14477,71 +16786,69 @@ fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_pthread_system_supported" >&5 -$as_echo "$ac_cv_pthread_system_supported" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_pthread_system_supported" >&5 +printf "%s\n" "$ac_cv_pthread_system_supported" >&6; } if test "$ac_cv_pthread_system_supported" = "yes"; then -$as_echo "#define PTHREAD_SYSTEM_SCHED_SUPPORTED 1" >>confdefs.h +printf "%s\n" "#define PTHREAD_SYSTEM_SCHED_SUPPORTED 1" >>confdefs.h fi - for ac_func in pthread_sigmask + + for ac_func in pthread_sigmask do : ac_fn_c_check_func "$LINENO" "pthread_sigmask" "ac_cv_func_pthread_sigmask" -if test "x$ac_cv_func_pthread_sigmask" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_PTHREAD_SIGMASK 1 -_ACEOF +if test "x$ac_cv_func_pthread_sigmask" = xyes +then : + printf "%s\n" "#define HAVE_PTHREAD_SIGMASK 1" >>confdefs.h case $ac_sys_system in CYGWIN*) -$as_echo "#define HAVE_BROKEN_PTHREAD_SIGMASK 1" >>confdefs.h +printf "%s\n" "#define HAVE_BROKEN_PTHREAD_SIGMASK 1" >>confdefs.h ;; esac fi -done - for ac_func in pthread_getcpuclockid -do : - ac_fn_c_check_func "$LINENO" "pthread_getcpuclockid" "ac_cv_func_pthread_getcpuclockid" -if test "x$ac_cv_func_pthread_getcpuclockid" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_PTHREAD_GETCPUCLOCKID 1 -_ACEOF +done + ac_fn_c_check_func "$LINENO" "pthread_getcpuclockid" "ac_cv_func_pthread_getcpuclockid" +if test "x$ac_cv_func_pthread_getcpuclockid" = xyes +then : + printf "%s\n" "#define HAVE_PTHREAD_GETCPUCLOCKID 1" >>confdefs.h fi -done fi -if test "x$posix_threads" = xstub; then : +if test "x$posix_threads" = xstub +then : -$as_echo "#define HAVE_PTHREAD_STUBS 1" >>confdefs.h +printf "%s\n" "#define HAVE_PTHREAD_STUBS 1" >>confdefs.h fi # Check for enable-ipv6 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if --enable-ipv6 is specified" >&5 -$as_echo_n "checking if --enable-ipv6 is specified... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if --enable-ipv6 is specified" >&5 +printf %s "checking if --enable-ipv6 is specified... " >&6; } # Check whether --enable-ipv6 was given. -if test "${enable_ipv6+set}" = set; then : +if test ${enable_ipv6+y} +then : enableval=$enable_ipv6; case "$enableval" in no) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } ipv6=no ;; - *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - $as_echo "#define ENABLE_IPV6 1" >>confdefs.h + *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + printf "%s\n" "#define ENABLE_IPV6 1" >>confdefs.h ipv6=yes ;; esac -else +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -14549,23 +16856,24 @@ else #include #include int -main () +main (void) { int domain = AF_INET6; ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : ipv6=yes -else +else $as_nop ipv6=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext case $ac_sys_system in #( WASI) : @@ -14575,19 +16883,19 @@ case $ac_sys_system in #( ;; esac -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ipv6" >&5 -$as_echo "$ipv6" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ipv6" >&5 +printf "%s\n" "$ipv6" >&6; } if test "$ipv6" = "yes"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if RFC2553 API is available" >&5 -$as_echo_n "checking if RFC2553 API is available... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if RFC2553 API is available" >&5 +printf %s "checking if RFC2553 API is available... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int -main () +main (void) { struct sockaddr_in6 x; x.sin6_scope_id; @@ -14596,24 +16904,25 @@ struct sockaddr_in6 x; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } ipv6=yes -else +else $as_nop - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } ipv6=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi if test "$ipv6" = "yes"; then - $as_echo "#define ENABLE_IPV6 1" >>confdefs.h + printf "%s\n" "#define ENABLE_IPV6 1" >>confdefs.h fi @@ -14625,8 +16934,8 @@ ipv6lib=none ipv6trylibc=no if test "$ipv6" = "yes"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking ipv6 stack type" >&5 -$as_echo_n "checking ipv6 stack type... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking ipv6 stack type" >&5 +printf %s "checking ipv6 stack type... " >&6; } for i in inria kame linux-glibc linux-inet6 solaris toshiba v6d zeta; do case $i in @@ -14640,10 +16949,11 @@ yes #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "yes" >/dev/null 2>&1; then : + $EGREP "yes" >/dev/null 2>&1 +then : ipv6type=$i fi -rm -f conftest* +rm -rf conftest* ;; kame) @@ -14656,13 +16966,14 @@ yes #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "yes" >/dev/null 2>&1; then : + $EGREP "yes" >/dev/null 2>&1 +then : ipv6type=$i; ipv6lib=inet6 ipv6libdir=/usr/local/v6/lib ipv6trylibc=yes fi -rm -f conftest* +rm -rf conftest* ;; linux-glibc) @@ -14675,11 +16986,12 @@ yes #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "yes" >/dev/null 2>&1; then : + $EGREP "yes" >/dev/null 2>&1 +then : ipv6type=$i; ipv6trylibc=yes fi -rm -f conftest* +rm -rf conftest* ;; linux-inet6) @@ -14708,12 +17020,13 @@ yes #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "yes" >/dev/null 2>&1; then : + $EGREP "yes" >/dev/null 2>&1 +then : ipv6type=$i; ipv6lib=inet6; ipv6libdir=/usr/local/v6/lib fi -rm -f conftest* +rm -rf conftest* ;; v6d) @@ -14726,13 +17039,14 @@ yes #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "yes" >/dev/null 2>&1; then : + $EGREP "yes" >/dev/null 2>&1 +then : ipv6type=$i; ipv6lib=v6; ipv6libdir=/usr/local/v6/lib; BASECFLAGS="-I/usr/local/v6/include $BASECFLAGS" fi -rm -f conftest* +rm -rf conftest* ;; zeta) @@ -14745,12 +17059,13 @@ yes #endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "yes" >/dev/null 2>&1; then : + $EGREP "yes" >/dev/null 2>&1 +then : ipv6type=$i; ipv6lib=inet6; ipv6libdir=/usr/local/v6/lib fi -rm -f conftest* +rm -rf conftest* ;; esac @@ -14758,22 +17073,23 @@ rm -f conftest* break fi done - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ipv6type" >&5 -$as_echo "$ipv6type" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ipv6type" >&5 +printf "%s\n" "$ipv6type" >&6; } fi if test "$ipv6" = "yes" -a "$ipv6lib" != "none"; then if test -d $ipv6libdir -a -f $ipv6libdir/lib$ipv6lib.a; then LIBS="-L$ipv6libdir -l$ipv6lib $LIBS" - { $as_echo "$as_me:${as_lineno-$LINENO}: using lib$ipv6lib" >&5 -$as_echo "$as_me: using lib$ipv6lib" >&6;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: using lib$ipv6lib" >&5 +printf "%s\n" "$as_me: using lib$ipv6lib" >&6;} else - if test "x$ipv6trylibc" = xyes; then : + if test "x$ipv6trylibc" = xyes +then : - { $as_echo "$as_me:${as_lineno-$LINENO}: using libc" >&5 -$as_echo "$as_me: using libc" >&6;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: using libc" >&5 +printf "%s\n" "$as_me: using libc" >&6;} -else +else $as_nop as_fn_error $? "No $ipv6lib library found; cannot continue. You need to fetch lib$ipv6lib.a from appropriate ipv6 kit and compile beforehand." "$LINENO" 5 @@ -14782,84 +17098,91 @@ fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking CAN_RAW_FD_FRAMES" >&5 -$as_echo_n "checking CAN_RAW_FD_FRAMES... " >&6; } -if ${ac_cv_can_raw_fd_frames+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking CAN_RAW_FD_FRAMES" >&5 +printf %s "checking CAN_RAW_FD_FRAMES... " >&6; } +if test ${ac_cv_can_raw_fd_frames+y} +then : + printf %s "(cached) " >&6 +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* CAN_RAW_FD_FRAMES available check */ #include int -main () +main (void) { int can_raw_fd_frames = CAN_RAW_FD_FRAMES; ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : ac_cv_can_raw_fd_frames=yes -else +else $as_nop ac_cv_can_raw_fd_frames=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_can_raw_fd_frames" >&5 -$as_echo "$ac_cv_can_raw_fd_frames" >&6; } -if test "x$ac_cv_can_raw_fd_frames" = xyes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_can_raw_fd_frames" >&5 +printf "%s\n" "$ac_cv_can_raw_fd_frames" >&6; } +if test "x$ac_cv_can_raw_fd_frames" = xyes +then : -$as_echo "#define HAVE_LINUX_CAN_RAW_FD_FRAMES 1" >>confdefs.h +printf "%s\n" "#define HAVE_LINUX_CAN_RAW_FD_FRAMES 1" >>confdefs.h fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for CAN_RAW_JOIN_FILTERS" >&5 -$as_echo_n "checking for CAN_RAW_JOIN_FILTERS... " >&6; } -if ${ac_cv_can_raw_join_filters+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for CAN_RAW_JOIN_FILTERS" >&5 +printf %s "checking for CAN_RAW_JOIN_FILTERS... " >&6; } +if test ${ac_cv_can_raw_join_filters+y} +then : + printf %s "(cached) " >&6 +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int -main () +main (void) { int can_raw_join_filters = CAN_RAW_JOIN_FILTERS; ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : ac_cv_can_raw_join_filters=yes -else +else $as_nop ac_cv_can_raw_join_filters=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_can_raw_join_filters" >&5 -$as_echo "$ac_cv_can_raw_join_filters" >&6; } -if test "x$ac_cv_can_raw_join_filters" = xyes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_can_raw_join_filters" >&5 +printf "%s\n" "$ac_cv_can_raw_join_filters" >&6; } +if test "x$ac_cv_can_raw_join_filters" = xyes +then : -$as_echo "#define HAVE_LINUX_CAN_RAW_JOIN_FILTERS 1" >>confdefs.h +printf "%s\n" "#define HAVE_LINUX_CAN_RAW_JOIN_FILTERS 1" >>confdefs.h fi # Check for --with-doc-strings -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-doc-strings" >&5 -$as_echo_n "checking for --with-doc-strings... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-doc-strings" >&5 +printf %s "checking for --with-doc-strings... " >&6; } # Check whether --with-doc-strings was given. -if test "${with_doc_strings+set}" = set; then : +if test ${with_doc_strings+y} +then : withval=$with_doc_strings; fi @@ -14870,18 +17193,19 @@ fi if test "$with_doc_strings" != "no" then -$as_echo "#define WITH_DOC_STRINGS 1" >>confdefs.h +printf "%s\n" "#define WITH_DOC_STRINGS 1" >>confdefs.h fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_doc_strings" >&5 -$as_echo "$with_doc_strings" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_doc_strings" >&5 +printf "%s\n" "$with_doc_strings" >&6; } # Check for Python-specific malloc support -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-pymalloc" >&5 -$as_echo_n "checking for --with-pymalloc... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-pymalloc" >&5 +printf %s "checking for --with-pymalloc... " >&6; } # Check whether --with-pymalloc was given. -if test "${with_pymalloc+set}" = set; then : +if test ${with_pymalloc+y} +then : withval=$with_pymalloc; fi @@ -14901,19 +17225,20 @@ fi if test "$with_pymalloc" != "no" then -$as_echo "#define WITH_PYMALLOC 1" >>confdefs.h +printf "%s\n" "#define WITH_PYMALLOC 1" >>confdefs.h fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_pymalloc" >&5 -$as_echo "$with_pymalloc" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_pymalloc" >&5 +printf "%s\n" "$with_pymalloc" >&6; } # Check whether objects such as float, tuple and dict are using # freelists to optimization memory allocation. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-freelists" >&5 -$as_echo_n "checking for --with-freelists... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-freelists" >&5 +printf %s "checking for --with-freelists... " >&6; } # Check whether --with-freelists was given. -if test "${with_freelists+set}" = set; then : +if test ${with_freelists+y} +then : withval=$with_freelists; fi @@ -14925,18 +17250,19 @@ fi if test "$with_freelists" != "no" then -$as_echo "#define WITH_FREELISTS 1" >>confdefs.h +printf "%s\n" "#define WITH_FREELISTS 1" >>confdefs.h fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_freelists" >&5 -$as_echo "$with_freelists" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_freelists" >&5 +printf "%s\n" "$with_freelists" >&6; } # Check for --with-c-locale-coercion -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-c-locale-coercion" >&5 -$as_echo_n "checking for --with-c-locale-coercion... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-c-locale-coercion" >&5 +printf %s "checking for --with-c-locale-coercion... " >&6; } # Check whether --with-c-locale-coercion was given. -if test "${with_c_locale_coercion+set}" = set; then : +if test ${with_c_locale_coercion+y} +then : withval=$with_c_locale_coercion; fi @@ -14948,53 +17274,56 @@ fi if test "$with_c_locale_coercion" != "no" then -$as_echo "#define PY_COERCE_C_LOCALE 1" >>confdefs.h +printf "%s\n" "#define PY_COERCE_C_LOCALE 1" >>confdefs.h fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_c_locale_coercion" >&5 -$as_echo "$with_c_locale_coercion" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_c_locale_coercion" >&5 +printf "%s\n" "$with_c_locale_coercion" >&6; } # Check for Valgrind support -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-valgrind" >&5 -$as_echo_n "checking for --with-valgrind... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-valgrind" >&5 +printf %s "checking for --with-valgrind... " >&6; } # Check whether --with-valgrind was given. -if test "${with_valgrind+set}" = set; then : +if test ${with_valgrind+y} +then : withval=$with_valgrind; -else +else $as_nop with_valgrind=no + fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_valgrind" >&5 -$as_echo "$with_valgrind" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_valgrind" >&5 +printf "%s\n" "$with_valgrind" >&6; } if test "$with_valgrind" != no; then - ac_fn_c_check_header_mongrel "$LINENO" "valgrind/valgrind.h" "ac_cv_header_valgrind_valgrind_h" "$ac_includes_default" -if test "x$ac_cv_header_valgrind_valgrind_h" = xyes; then : + ac_fn_c_check_header_compile "$LINENO" "valgrind/valgrind.h" "ac_cv_header_valgrind_valgrind_h" "$ac_includes_default" +if test "x$ac_cv_header_valgrind_valgrind_h" = xyes +then : -$as_echo "#define WITH_VALGRIND 1" >>confdefs.h +printf "%s\n" "#define WITH_VALGRIND 1" >>confdefs.h -else +else $as_nop as_fn_error $? "Valgrind support requested but headers not available" "$LINENO" 5 fi - OPT="-DDYNAMIC_ANNOTATIONS_ENABLED=1 $OPT" fi # Check for DTrace support -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-dtrace" >&5 -$as_echo_n "checking for --with-dtrace... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-dtrace" >&5 +printf %s "checking for --with-dtrace... " >&6; } # Check whether --with-dtrace was given. -if test "${with_dtrace+set}" = set; then : +if test ${with_dtrace+y} +then : withval=$with_dtrace; -else +else $as_nop with_dtrace=no fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_dtrace" >&5 -$as_echo "$with_dtrace" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_dtrace" >&5 +printf "%s\n" "$with_dtrace" >&6; } @@ -15008,11 +17337,12 @@ if test "$with_dtrace" = "yes" then # Extract the first word of "dtrace", so it can be a program name with args. set dummy dtrace; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_DTRACE+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_path_DTRACE+y} +then : + printf %s "(cached) " >&6 +else $as_nop case $DTRACE in [\\/]* | ?:[\\/]*) ac_cv_path_DTRACE="$DTRACE" # Let the user override the test with a path. @@ -15022,11 +17352,15 @@ else for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_DTRACE="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_path_DTRACE="$as_dir$ac_word$ac_exec_ext" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -15039,11 +17373,11 @@ esac fi DTRACE=$ac_cv_path_DTRACE if test -n "$DTRACE"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DTRACE" >&5 -$as_echo "$DTRACE" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $DTRACE" >&5 +printf "%s\n" "$DTRACE" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -15051,7 +17385,7 @@ fi as_fn_error $? "dtrace command not found on \$PATH" "$LINENO" 5 fi -$as_echo "#define WITH_DTRACE 1" >>confdefs.h +printf "%s\n" "#define WITH_DTRACE 1" >>confdefs.h DTRACE_HEADERS="Include/pydtrace_probes.h" @@ -15059,19 +17393,20 @@ $as_echo "#define WITH_DTRACE 1" >>confdefs.h # linked into the binary. Correspondingly, dtrace(1) is missing the ELF # generation flag '-G'. We check for presence of this flag, rather than # hardcoding support by OS, in the interest of robustness. - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether DTrace probes require linking" >&5 -$as_echo_n "checking whether DTrace probes require linking... " >&6; } -if ${ac_cv_dtrace_link+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether DTrace probes require linking" >&5 +printf %s "checking whether DTrace probes require linking... " >&6; } +if test ${ac_cv_dtrace_link+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_cv_dtrace_link=no echo 'BEGIN{}' > conftest.d "$DTRACE" $DFLAGS -G -s conftest.d -o conftest.o > /dev/null 2>&1 && \ ac_cv_dtrace_link=yes fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_dtrace_link" >&5 -$as_echo "$ac_cv_dtrace_link" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_dtrace_link" >&5 +printf "%s\n" "$ac_cv_dtrace_link" >&6; } if test "$ac_cv_dtrace_link" = "yes"; then DTRACE_OBJS="Python/pydtrace.o" fi @@ -15098,23 +17433,19 @@ DLINCLDIR=. # the dlopen() function means we might want to use dynload_shlib.o. some # platforms have dlopen(), but don't want to use it. -for ac_func in dlopen -do : - ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" -if test "x$ac_cv_func_dlopen" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_DLOPEN 1 -_ACEOF +ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" +if test "x$ac_cv_func_dlopen" = xyes +then : + printf "%s\n" "#define HAVE_DLOPEN 1" >>confdefs.h fi -done # DYNLOADFILE specifies which dynload_*.o file we will use for dynamic # loading of modules. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking DYNLOADFILE" >&5 -$as_echo_n "checking DYNLOADFILE... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking DYNLOADFILE" >&5 +printf %s "checking DYNLOADFILE... " >&6; } if test -z "$DYNLOADFILE" then case $ac_sys_system/$ac_sys_release in @@ -15129,20 +17460,20 @@ then ;; esac fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $DYNLOADFILE" >&5 -$as_echo "$DYNLOADFILE" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $DYNLOADFILE" >&5 +printf "%s\n" "$DYNLOADFILE" >&6; } if test "$DYNLOADFILE" != "dynload_stub.o" then -$as_echo "#define HAVE_DYNAMIC_LOADING 1" >>confdefs.h +printf "%s\n" "#define HAVE_DYNAMIC_LOADING 1" >>confdefs.h fi # MACHDEP_OBJS can be set to platform-specific object files needed by Python -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking MACHDEP_OBJS" >&5 -$as_echo_n "checking MACHDEP_OBJS... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking MACHDEP_OBJS" >&5 +printf %s "checking MACHDEP_OBJS... " >&6; } if test -z "$MACHDEP_OBJS" then MACHDEP_OBJS=$extra_machdep_objs @@ -15150,999 +17481,1298 @@ else MACHDEP_OBJS="$MACHDEP_OBJS $extra_machdep_objs" fi if test -z "$MACHDEP_OBJS"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 -$as_echo "none" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none" >&5 +printf "%s\n" "none" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MACHDEP_OBJS" >&5 -$as_echo "$MACHDEP_OBJS" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MACHDEP_OBJS" >&5 +printf "%s\n" "$MACHDEP_OBJS" >&6; } fi # checks for library functions -for ac_func in \ - accept4 alarm bind_textdomain_codeset chmod chown clock close_range confstr \ - copy_file_range ctermid dup dup3 execv explicit_bzero explicit_memset \ - faccessat fchmod fchmodat fchown fchownat fdopendir fdwalk fexecve \ - fork fork1 fpathconf fstatat ftime ftruncate futimens futimes futimesat \ - gai_strerror getegid getentropy geteuid getgid getgrgid getgrgid_r \ - getgrnam_r getgrouplist getgroups gethostname getitimer getloadavg getlogin \ - getpeername getpgid getpid getppid getpriority _getpty \ - getpwent getpwnam_r getpwuid getpwuid_r getresgid getresuid getrusage getsid getspent \ - getspnam getuid getwd if_nameindex initgroups kill killpg lchown linkat \ - lockf lstat lutimes madvise mbrtowc memrchr mkdirat mkfifo mkfifoat \ - mknod mknodat mktime mmap mremap nice openat opendir pathconf pause pipe \ - pipe2 plock poll posix_fadvise posix_fallocate posix_spawn posix_spawnp \ - pread preadv preadv2 pthread_condattr_setclock pthread_init pthread_kill \ - pwrite pwritev pwritev2 readlink readlinkat readv realpath renameat \ - rtpSpawn sched_get_priority_max sched_rr_get_interval sched_setaffinity \ - sched_setparam sched_setscheduler sem_clockwait sem_getvalue sem_open \ - sem_timedwait sem_unlink sendfile setegid seteuid setgid sethostname \ - setitimer setlocale setpgid setpgrp setpriority setregid setresgid \ - setresuid setreuid setsid setuid setvbuf shutdown sigaction sigaltstack \ - sigfillset siginterrupt sigpending sigrelse sigtimedwait sigwait \ - sigwaitinfo snprintf splice strftime strlcpy strsignal symlinkat sync \ - sysconf system tcgetpgrp tcsetpgrp tempnam timegm times tmpfile \ - tmpnam tmpnam_r truncate ttyname umask uname unlinkat utimensat utimes vfork \ - wait wait3 wait4 waitid waitpid wcscoll wcsftime wcsxfrm wmemcmp writev \ +ac_fn_c_check_func "$LINENO" "accept4" "ac_cv_func_accept4" +if test "x$ac_cv_func_accept4" = xyes +then : + printf "%s\n" "#define HAVE_ACCEPT4 1" >>confdefs.h -do : - as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` -ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -if eval test \"x\$"$as_ac_var"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF +fi +ac_fn_c_check_func "$LINENO" "alarm" "ac_cv_func_alarm" +if test "x$ac_cv_func_alarm" = xyes +then : + printf "%s\n" "#define HAVE_ALARM 1" >>confdefs.h fi -done +ac_fn_c_check_func "$LINENO" "bind_textdomain_codeset" "ac_cv_func_bind_textdomain_codeset" +if test "x$ac_cv_func_bind_textdomain_codeset" = xyes +then : + printf "%s\n" "#define HAVE_BIND_TEXTDOMAIN_CODESET 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "chmod" "ac_cv_func_chmod" +if test "x$ac_cv_func_chmod" = xyes +then : + printf "%s\n" "#define HAVE_CHMOD 1" >>confdefs.h -# Force lchmod off for Linux. Linux disallows changing the mode of symbolic -# links. Some libc implementations have a stub lchmod implementation that always -# returns an error. -if test "$MACHDEP" != linux; then - for ac_func in lchmod -do : - ac_fn_c_check_func "$LINENO" "lchmod" "ac_cv_func_lchmod" -if test "x$ac_cv_func_lchmod" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LCHMOD 1 -_ACEOF +fi +ac_fn_c_check_func "$LINENO" "chown" "ac_cv_func_chown" +if test "x$ac_cv_func_chown" = xyes +then : + printf "%s\n" "#define HAVE_CHOWN 1" >>confdefs.h fi -done +ac_fn_c_check_func "$LINENO" "clock" "ac_cv_func_clock" +if test "x$ac_cv_func_clock" = xyes +then : + printf "%s\n" "#define HAVE_CLOCK 1" >>confdefs.h fi +ac_fn_c_check_func "$LINENO" "close_range" "ac_cv_func_close_range" +if test "x$ac_cv_func_close_range" = xyes +then : + printf "%s\n" "#define HAVE_CLOSE_RANGE 1" >>confdefs.h -ac_fn_c_check_decl "$LINENO" "dirfd" "ac_cv_have_decl_dirfd" "#include - #include -" -if test "x$ac_cv_have_decl_dirfd" = xyes; then : +fi +ac_fn_c_check_func "$LINENO" "confstr" "ac_cv_func_confstr" +if test "x$ac_cv_func_confstr" = xyes +then : + printf "%s\n" "#define HAVE_CONFSTR 1" >>confdefs.h -$as_echo "#define HAVE_DIRFD 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "copy_file_range" "ac_cv_func_copy_file_range" +if test "x$ac_cv_func_copy_file_range" = xyes +then : + printf "%s\n" "#define HAVE_COPY_FILE_RANGE 1" >>confdefs.h fi +ac_fn_c_check_func "$LINENO" "ctermid" "ac_cv_func_ctermid" +if test "x$ac_cv_func_ctermid" = xyes +then : + printf "%s\n" "#define HAVE_CTERMID 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "dup" "ac_cv_func_dup" +if test "x$ac_cv_func_dup" = xyes +then : + printf "%s\n" "#define HAVE_DUP 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "dup3" "ac_cv_func_dup3" +if test "x$ac_cv_func_dup3" = xyes +then : + printf "%s\n" "#define HAVE_DUP3 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "execv" "ac_cv_func_execv" +if test "x$ac_cv_func_execv" = xyes +then : + printf "%s\n" "#define HAVE_EXECV 1" >>confdefs.h -# For some functions, having a definition is not sufficient, since -# we want to take their address. +fi +ac_fn_c_check_func "$LINENO" "explicit_bzero" "ac_cv_func_explicit_bzero" +if test "x$ac_cv_func_explicit_bzero" = xyes +then : + printf "%s\n" "#define HAVE_EXPLICIT_BZERO 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "explicit_memset" "ac_cv_func_explicit_memset" +if test "x$ac_cv_func_explicit_memset" = xyes +then : + printf "%s\n" "#define HAVE_EXPLICIT_MEMSET 1" >>confdefs.h - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for chroot" >&5 -$as_echo_n "checking for chroot... " >&6; } -if ${ac_cv_func_chroot+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -int -main () -{ -void *x=chroot - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_func_chroot=yes -else - ac_cv_func_chroot=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_fn_c_check_func "$LINENO" "faccessat" "ac_cv_func_faccessat" +if test "x$ac_cv_func_faccessat" = xyes +then : + printf "%s\n" "#define HAVE_FACCESSAT 1" >>confdefs.h fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_chroot" >&5 -$as_echo "$ac_cv_func_chroot" >&6; } - if test "x$ac_cv_func_chroot" = xyes; then : +ac_fn_c_check_func "$LINENO" "fchmod" "ac_cv_func_fchmod" +if test "x$ac_cv_func_fchmod" = xyes +then : + printf "%s\n" "#define HAVE_FCHMOD 1" >>confdefs.h -$as_echo "#define HAVE_CHROOT 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "fchmodat" "ac_cv_func_fchmodat" +if test "x$ac_cv_func_fchmodat" = xyes +then : + printf "%s\n" "#define HAVE_FCHMODAT 1" >>confdefs.h fi +ac_fn_c_check_func "$LINENO" "fchown" "ac_cv_func_fchown" +if test "x$ac_cv_func_fchown" = xyes +then : + printf "%s\n" "#define HAVE_FCHOWN 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "fchownat" "ac_cv_func_fchownat" +if test "x$ac_cv_func_fchownat" = xyes +then : + printf "%s\n" "#define HAVE_FCHOWNAT 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "fdopendir" "ac_cv_func_fdopendir" +if test "x$ac_cv_func_fdopendir" = xyes +then : + printf "%s\n" "#define HAVE_FDOPENDIR 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "fdwalk" "ac_cv_func_fdwalk" +if test "x$ac_cv_func_fdwalk" = xyes +then : + printf "%s\n" "#define HAVE_FDWALK 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "fexecve" "ac_cv_func_fexecve" +if test "x$ac_cv_func_fexecve" = xyes +then : + printf "%s\n" "#define HAVE_FEXECVE 1" >>confdefs.h - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for link" >&5 -$as_echo_n "checking for link... " >&6; } -if ${ac_cv_func_link+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -int -main () -{ -void *x=link - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_func_link=yes -else - ac_cv_func_link=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_fn_c_check_func "$LINENO" "fork" "ac_cv_func_fork" +if test "x$ac_cv_func_fork" = xyes +then : + printf "%s\n" "#define HAVE_FORK 1" >>confdefs.h fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_link" >&5 -$as_echo "$ac_cv_func_link" >&6; } - if test "x$ac_cv_func_link" = xyes; then : +ac_fn_c_check_func "$LINENO" "fork1" "ac_cv_func_fork1" +if test "x$ac_cv_func_fork1" = xyes +then : + printf "%s\n" "#define HAVE_FORK1 1" >>confdefs.h -$as_echo "#define HAVE_LINK 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "fpathconf" "ac_cv_func_fpathconf" +if test "x$ac_cv_func_fpathconf" = xyes +then : + printf "%s\n" "#define HAVE_FPATHCONF 1" >>confdefs.h fi +ac_fn_c_check_func "$LINENO" "fstatat" "ac_cv_func_fstatat" +if test "x$ac_cv_func_fstatat" = xyes +then : + printf "%s\n" "#define HAVE_FSTATAT 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "ftime" "ac_cv_func_ftime" +if test "x$ac_cv_func_ftime" = xyes +then : + printf "%s\n" "#define HAVE_FTIME 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "ftruncate" "ac_cv_func_ftruncate" +if test "x$ac_cv_func_ftruncate" = xyes +then : + printf "%s\n" "#define HAVE_FTRUNCATE 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "futimens" "ac_cv_func_futimens" +if test "x$ac_cv_func_futimens" = xyes +then : + printf "%s\n" "#define HAVE_FUTIMENS 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "futimes" "ac_cv_func_futimes" +if test "x$ac_cv_func_futimes" = xyes +then : + printf "%s\n" "#define HAVE_FUTIMES 1" >>confdefs.h - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for symlink" >&5 -$as_echo_n "checking for symlink... " >&6; } -if ${ac_cv_func_symlink+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -int -main () -{ -void *x=symlink - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_func_symlink=yes -else - ac_cv_func_symlink=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_fn_c_check_func "$LINENO" "futimesat" "ac_cv_func_futimesat" +if test "x$ac_cv_func_futimesat" = xyes +then : + printf "%s\n" "#define HAVE_FUTIMESAT 1" >>confdefs.h fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_symlink" >&5 -$as_echo "$ac_cv_func_symlink" >&6; } - if test "x$ac_cv_func_symlink" = xyes; then : +ac_fn_c_check_func "$LINENO" "gai_strerror" "ac_cv_func_gai_strerror" +if test "x$ac_cv_func_gai_strerror" = xyes +then : + printf "%s\n" "#define HAVE_GAI_STRERROR 1" >>confdefs.h -$as_echo "#define HAVE_SYMLINK 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "getegid" "ac_cv_func_getegid" +if test "x$ac_cv_func_getegid" = xyes +then : + printf "%s\n" "#define HAVE_GETEGID 1" >>confdefs.h fi +ac_fn_c_check_func "$LINENO" "getentropy" "ac_cv_func_getentropy" +if test "x$ac_cv_func_getentropy" = xyes +then : + printf "%s\n" "#define HAVE_GETENTROPY 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "geteuid" "ac_cv_func_geteuid" +if test "x$ac_cv_func_geteuid" = xyes +then : + printf "%s\n" "#define HAVE_GETEUID 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "getgid" "ac_cv_func_getgid" +if test "x$ac_cv_func_getgid" = xyes +then : + printf "%s\n" "#define HAVE_GETGID 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "getgrgid" "ac_cv_func_getgrgid" +if test "x$ac_cv_func_getgrgid" = xyes +then : + printf "%s\n" "#define HAVE_GETGRGID 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "getgrgid_r" "ac_cv_func_getgrgid_r" +if test "x$ac_cv_func_getgrgid_r" = xyes +then : + printf "%s\n" "#define HAVE_GETGRGID_R 1" >>confdefs.h - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fchdir" >&5 -$as_echo_n "checking for fchdir... " >&6; } -if ${ac_cv_func_fchdir+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -int -main () -{ -void *x=fchdir - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_func_fchdir=yes -else - ac_cv_func_fchdir=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_fn_c_check_func "$LINENO" "getgrnam_r" "ac_cv_func_getgrnam_r" +if test "x$ac_cv_func_getgrnam_r" = xyes +then : + printf "%s\n" "#define HAVE_GETGRNAM_R 1" >>confdefs.h fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_fchdir" >&5 -$as_echo "$ac_cv_func_fchdir" >&6; } - if test "x$ac_cv_func_fchdir" = xyes; then : +ac_fn_c_check_func "$LINENO" "getgrouplist" "ac_cv_func_getgrouplist" +if test "x$ac_cv_func_getgrouplist" = xyes +then : + printf "%s\n" "#define HAVE_GETGROUPLIST 1" >>confdefs.h -$as_echo "#define HAVE_FCHDIR 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "getgroups" "ac_cv_func_getgroups" +if test "x$ac_cv_func_getgroups" = xyes +then : + printf "%s\n" "#define HAVE_GETGROUPS 1" >>confdefs.h fi +ac_fn_c_check_func "$LINENO" "gethostname" "ac_cv_func_gethostname" +if test "x$ac_cv_func_gethostname" = xyes +then : + printf "%s\n" "#define HAVE_GETHOSTNAME 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "getitimer" "ac_cv_func_getitimer" +if test "x$ac_cv_func_getitimer" = xyes +then : + printf "%s\n" "#define HAVE_GETITIMER 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "getloadavg" "ac_cv_func_getloadavg" +if test "x$ac_cv_func_getloadavg" = xyes +then : + printf "%s\n" "#define HAVE_GETLOADAVG 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "getlogin" "ac_cv_func_getlogin" +if test "x$ac_cv_func_getlogin" = xyes +then : + printf "%s\n" "#define HAVE_GETLOGIN 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "getpeername" "ac_cv_func_getpeername" +if test "x$ac_cv_func_getpeername" = xyes +then : + printf "%s\n" "#define HAVE_GETPEERNAME 1" >>confdefs.h - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fsync" >&5 -$as_echo_n "checking for fsync... " >&6; } -if ${ac_cv_func_fsync+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -int -main () -{ -void *x=fsync - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_func_fsync=yes -else - ac_cv_func_fsync=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_fn_c_check_func "$LINENO" "getpgid" "ac_cv_func_getpgid" +if test "x$ac_cv_func_getpgid" = xyes +then : + printf "%s\n" "#define HAVE_GETPGID 1" >>confdefs.h fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_fsync" >&5 -$as_echo "$ac_cv_func_fsync" >&6; } - if test "x$ac_cv_func_fsync" = xyes; then : +ac_fn_c_check_func "$LINENO" "getpid" "ac_cv_func_getpid" +if test "x$ac_cv_func_getpid" = xyes +then : + printf "%s\n" "#define HAVE_GETPID 1" >>confdefs.h -$as_echo "#define HAVE_FSYNC 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "getppid" "ac_cv_func_getppid" +if test "x$ac_cv_func_getppid" = xyes +then : + printf "%s\n" "#define HAVE_GETPPID 1" >>confdefs.h fi +ac_fn_c_check_func "$LINENO" "getpriority" "ac_cv_func_getpriority" +if test "x$ac_cv_func_getpriority" = xyes +then : + printf "%s\n" "#define HAVE_GETPRIORITY 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "_getpty" "ac_cv_func__getpty" +if test "x$ac_cv_func__getpty" = xyes +then : + printf "%s\n" "#define HAVE__GETPTY 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "getpwent" "ac_cv_func_getpwent" +if test "x$ac_cv_func_getpwent" = xyes +then : + printf "%s\n" "#define HAVE_GETPWENT 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "getpwnam_r" "ac_cv_func_getpwnam_r" +if test "x$ac_cv_func_getpwnam_r" = xyes +then : + printf "%s\n" "#define HAVE_GETPWNAM_R 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "getpwuid" "ac_cv_func_getpwuid" +if test "x$ac_cv_func_getpwuid" = xyes +then : + printf "%s\n" "#define HAVE_GETPWUID 1" >>confdefs.h - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fdatasync" >&5 -$as_echo_n "checking for fdatasync... " >&6; } -if ${ac_cv_func_fdatasync+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -int -main () -{ -void *x=fdatasync - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_func_fdatasync=yes -else - ac_cv_func_fdatasync=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_fn_c_check_func "$LINENO" "getpwuid_r" "ac_cv_func_getpwuid_r" +if test "x$ac_cv_func_getpwuid_r" = xyes +then : + printf "%s\n" "#define HAVE_GETPWUID_R 1" >>confdefs.h fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_fdatasync" >&5 -$as_echo "$ac_cv_func_fdatasync" >&6; } - if test "x$ac_cv_func_fdatasync" = xyes; then : +ac_fn_c_check_func "$LINENO" "getresgid" "ac_cv_func_getresgid" +if test "x$ac_cv_func_getresgid" = xyes +then : + printf "%s\n" "#define HAVE_GETRESGID 1" >>confdefs.h -$as_echo "#define HAVE_FDATASYNC 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "getresuid" "ac_cv_func_getresuid" +if test "x$ac_cv_func_getresuid" = xyes +then : + printf "%s\n" "#define HAVE_GETRESUID 1" >>confdefs.h fi +ac_fn_c_check_func "$LINENO" "getrusage" "ac_cv_func_getrusage" +if test "x$ac_cv_func_getrusage" = xyes +then : + printf "%s\n" "#define HAVE_GETRUSAGE 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "getsid" "ac_cv_func_getsid" +if test "x$ac_cv_func_getsid" = xyes +then : + printf "%s\n" "#define HAVE_GETSID 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "getspent" "ac_cv_func_getspent" +if test "x$ac_cv_func_getspent" = xyes +then : + printf "%s\n" "#define HAVE_GETSPENT 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "getspnam" "ac_cv_func_getspnam" +if test "x$ac_cv_func_getspnam" = xyes +then : + printf "%s\n" "#define HAVE_GETSPNAM 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "getuid" "ac_cv_func_getuid" +if test "x$ac_cv_func_getuid" = xyes +then : + printf "%s\n" "#define HAVE_GETUID 1" >>confdefs.h - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for epoll_create" >&5 -$as_echo_n "checking for epoll_create... " >&6; } -if ${ac_cv_func_epoll_create+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -int -main () -{ -void *x=epoll_create - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_func_epoll_create=yes -else - ac_cv_func_epoll_create=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_fn_c_check_func "$LINENO" "getwd" "ac_cv_func_getwd" +if test "x$ac_cv_func_getwd" = xyes +then : + printf "%s\n" "#define HAVE_GETWD 1" >>confdefs.h fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_epoll_create" >&5 -$as_echo "$ac_cv_func_epoll_create" >&6; } - if test "x$ac_cv_func_epoll_create" = xyes; then : +ac_fn_c_check_func "$LINENO" "if_nameindex" "ac_cv_func_if_nameindex" +if test "x$ac_cv_func_if_nameindex" = xyes +then : + printf "%s\n" "#define HAVE_IF_NAMEINDEX 1" >>confdefs.h -$as_echo "#define HAVE_EPOLL 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "initgroups" "ac_cv_func_initgroups" +if test "x$ac_cv_func_initgroups" = xyes +then : + printf "%s\n" "#define HAVE_INITGROUPS 1" >>confdefs.h fi +ac_fn_c_check_func "$LINENO" "kill" "ac_cv_func_kill" +if test "x$ac_cv_func_kill" = xyes +then : + printf "%s\n" "#define HAVE_KILL 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "killpg" "ac_cv_func_killpg" +if test "x$ac_cv_func_killpg" = xyes +then : + printf "%s\n" "#define HAVE_KILLPG 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "lchown" "ac_cv_func_lchown" +if test "x$ac_cv_func_lchown" = xyes +then : + printf "%s\n" "#define HAVE_LCHOWN 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "linkat" "ac_cv_func_linkat" +if test "x$ac_cv_func_linkat" = xyes +then : + printf "%s\n" "#define HAVE_LINKAT 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "lockf" "ac_cv_func_lockf" +if test "x$ac_cv_func_lockf" = xyes +then : + printf "%s\n" "#define HAVE_LOCKF 1" >>confdefs.h - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for epoll_create1" >&5 -$as_echo_n "checking for epoll_create1... " >&6; } -if ${ac_cv_func_epoll_create1+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -int -main () -{ -void *x=epoll_create1 - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_func_epoll_create1=yes -else - ac_cv_func_epoll_create1=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_fn_c_check_func "$LINENO" "lstat" "ac_cv_func_lstat" +if test "x$ac_cv_func_lstat" = xyes +then : + printf "%s\n" "#define HAVE_LSTAT 1" >>confdefs.h fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_epoll_create1" >&5 -$as_echo "$ac_cv_func_epoll_create1" >&6; } - if test "x$ac_cv_func_epoll_create1" = xyes; then : +ac_fn_c_check_func "$LINENO" "lutimes" "ac_cv_func_lutimes" +if test "x$ac_cv_func_lutimes" = xyes +then : + printf "%s\n" "#define HAVE_LUTIMES 1" >>confdefs.h -$as_echo "#define HAVE_EPOLL_CREATE1 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "madvise" "ac_cv_func_madvise" +if test "x$ac_cv_func_madvise" = xyes +then : + printf "%s\n" "#define HAVE_MADVISE 1" >>confdefs.h fi +ac_fn_c_check_func "$LINENO" "mbrtowc" "ac_cv_func_mbrtowc" +if test "x$ac_cv_func_mbrtowc" = xyes +then : + printf "%s\n" "#define HAVE_MBRTOWC 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "memrchr" "ac_cv_func_memrchr" +if test "x$ac_cv_func_memrchr" = xyes +then : + printf "%s\n" "#define HAVE_MEMRCHR 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "mkdirat" "ac_cv_func_mkdirat" +if test "x$ac_cv_func_mkdirat" = xyes +then : + printf "%s\n" "#define HAVE_MKDIRAT 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "mkfifo" "ac_cv_func_mkfifo" +if test "x$ac_cv_func_mkfifo" = xyes +then : + printf "%s\n" "#define HAVE_MKFIFO 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "mkfifoat" "ac_cv_func_mkfifoat" +if test "x$ac_cv_func_mkfifoat" = xyes +then : + printf "%s\n" "#define HAVE_MKFIFOAT 1" >>confdefs.h - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for kqueue" >&5 -$as_echo_n "checking for kqueue... " >&6; } -if ${ac_cv_func_kqueue+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ +fi +ac_fn_c_check_func "$LINENO" "mknod" "ac_cv_func_mknod" +if test "x$ac_cv_func_mknod" = xyes +then : + printf "%s\n" "#define HAVE_MKNOD 1" >>confdefs.h -#include -#include +fi +ac_fn_c_check_func "$LINENO" "mknodat" "ac_cv_func_mknodat" +if test "x$ac_cv_func_mknodat" = xyes +then : + printf "%s\n" "#define HAVE_MKNODAT 1" >>confdefs.h -int -main () -{ -void *x=kqueue - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_func_kqueue=yes -else - ac_cv_func_kqueue=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_fn_c_check_func "$LINENO" "mktime" "ac_cv_func_mktime" +if test "x$ac_cv_func_mktime" = xyes +then : + printf "%s\n" "#define HAVE_MKTIME 1" >>confdefs.h fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_kqueue" >&5 -$as_echo "$ac_cv_func_kqueue" >&6; } - if test "x$ac_cv_func_kqueue" = xyes; then : +ac_fn_c_check_func "$LINENO" "mmap" "ac_cv_func_mmap" +if test "x$ac_cv_func_mmap" = xyes +then : + printf "%s\n" "#define HAVE_MMAP 1" >>confdefs.h -$as_echo "#define HAVE_KQUEUE 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "mremap" "ac_cv_func_mremap" +if test "x$ac_cv_func_mremap" = xyes +then : + printf "%s\n" "#define HAVE_MREMAP 1" >>confdefs.h fi +ac_fn_c_check_func "$LINENO" "nice" "ac_cv_func_nice" +if test "x$ac_cv_func_nice" = xyes +then : + printf "%s\n" "#define HAVE_NICE 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "openat" "ac_cv_func_openat" +if test "x$ac_cv_func_openat" = xyes +then : + printf "%s\n" "#define HAVE_OPENAT 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "opendir" "ac_cv_func_opendir" +if test "x$ac_cv_func_opendir" = xyes +then : + printf "%s\n" "#define HAVE_OPENDIR 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "pathconf" "ac_cv_func_pathconf" +if test "x$ac_cv_func_pathconf" = xyes +then : + printf "%s\n" "#define HAVE_PATHCONF 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "pause" "ac_cv_func_pause" +if test "x$ac_cv_func_pause" = xyes +then : + printf "%s\n" "#define HAVE_PAUSE 1" >>confdefs.h - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for prlimit" >&5 -$as_echo_n "checking for prlimit... " >&6; } -if ${ac_cv_func_prlimit+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ +fi +ac_fn_c_check_func "$LINENO" "pipe" "ac_cv_func_pipe" +if test "x$ac_cv_func_pipe" = xyes +then : + printf "%s\n" "#define HAVE_PIPE 1" >>confdefs.h -#include -#include +fi +ac_fn_c_check_func "$LINENO" "pipe2" "ac_cv_func_pipe2" +if test "x$ac_cv_func_pipe2" = xyes +then : + printf "%s\n" "#define HAVE_PIPE2 1" >>confdefs.h -int -main () -{ -void *x=prlimit - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_func_prlimit=yes -else - ac_cv_func_prlimit=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_fn_c_check_func "$LINENO" "plock" "ac_cv_func_plock" +if test "x$ac_cv_func_plock" = xyes +then : + printf "%s\n" "#define HAVE_PLOCK 1" >>confdefs.h fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_prlimit" >&5 -$as_echo "$ac_cv_func_prlimit" >&6; } - if test "x$ac_cv_func_prlimit" = xyes; then : +ac_fn_c_check_func "$LINENO" "poll" "ac_cv_func_poll" +if test "x$ac_cv_func_poll" = xyes +then : + printf "%s\n" "#define HAVE_POLL 1" >>confdefs.h -$as_echo "#define HAVE_PRLIMIT 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "posix_fadvise" "ac_cv_func_posix_fadvise" +if test "x$ac_cv_func_posix_fadvise" = xyes +then : + printf "%s\n" "#define HAVE_POSIX_FADVISE 1" >>confdefs.h fi +ac_fn_c_check_func "$LINENO" "posix_fallocate" "ac_cv_func_posix_fallocate" +if test "x$ac_cv_func_posix_fallocate" = xyes +then : + printf "%s\n" "#define HAVE_POSIX_FALLOCATE 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "posix_spawn" "ac_cv_func_posix_spawn" +if test "x$ac_cv_func_posix_spawn" = xyes +then : + printf "%s\n" "#define HAVE_POSIX_SPAWN 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "posix_spawnp" "ac_cv_func_posix_spawnp" +if test "x$ac_cv_func_posix_spawnp" = xyes +then : + printf "%s\n" "#define HAVE_POSIX_SPAWNP 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "pread" "ac_cv_func_pread" +if test "x$ac_cv_func_pread" = xyes +then : + printf "%s\n" "#define HAVE_PREAD 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "preadv" "ac_cv_func_preadv" +if test "x$ac_cv_func_preadv" = xyes +then : + printf "%s\n" "#define HAVE_PREADV 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "preadv2" "ac_cv_func_preadv2" +if test "x$ac_cv_func_preadv2" = xyes +then : + printf "%s\n" "#define HAVE_PREADV2 1" >>confdefs.h - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _dyld_shared_cache_contains_path" >&5 -$as_echo_n "checking for _dyld_shared_cache_contains_path... " >&6; } -if ${ac_cv_func__dyld_shared_cache_contains_path+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -int -main () -{ -void *x=_dyld_shared_cache_contains_path - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_func__dyld_shared_cache_contains_path=yes -else - ac_cv_func__dyld_shared_cache_contains_path=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_fn_c_check_func "$LINENO" "pthread_condattr_setclock" "ac_cv_func_pthread_condattr_setclock" +if test "x$ac_cv_func_pthread_condattr_setclock" = xyes +then : + printf "%s\n" "#define HAVE_PTHREAD_CONDATTR_SETCLOCK 1" >>confdefs.h fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func__dyld_shared_cache_contains_path" >&5 -$as_echo "$ac_cv_func__dyld_shared_cache_contains_path" >&6; } - if test "x$ac_cv_func__dyld_shared_cache_contains_path" = xyes; then : +ac_fn_c_check_func "$LINENO" "pthread_init" "ac_cv_func_pthread_init" +if test "x$ac_cv_func_pthread_init" = xyes +then : + printf "%s\n" "#define HAVE_PTHREAD_INIT 1" >>confdefs.h -$as_echo "#define HAVE_DYLD_SHARED_CACHE_CONTAINS_PATH 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "pthread_kill" "ac_cv_func_pthread_kill" +if test "x$ac_cv_func_pthread_kill" = xyes +then : + printf "%s\n" "#define HAVE_PTHREAD_KILL 1" >>confdefs.h fi +ac_fn_c_check_func "$LINENO" "pwrite" "ac_cv_func_pwrite" +if test "x$ac_cv_func_pwrite" = xyes +then : + printf "%s\n" "#define HAVE_PWRITE 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "pwritev" "ac_cv_func_pwritev" +if test "x$ac_cv_func_pwritev" = xyes +then : + printf "%s\n" "#define HAVE_PWRITEV 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "pwritev2" "ac_cv_func_pwritev2" +if test "x$ac_cv_func_pwritev2" = xyes +then : + printf "%s\n" "#define HAVE_PWRITEV2 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "readlink" "ac_cv_func_readlink" +if test "x$ac_cv_func_readlink" = xyes +then : + printf "%s\n" "#define HAVE_READLINK 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "readlinkat" "ac_cv_func_readlinkat" +if test "x$ac_cv_func_readlinkat" = xyes +then : + printf "%s\n" "#define HAVE_READLINKAT 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "readv" "ac_cv_func_readv" +if test "x$ac_cv_func_readv" = xyes +then : + printf "%s\n" "#define HAVE_READV 1" >>confdefs.h - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for memfd_create" >&5 -$as_echo_n "checking for memfd_create... " >&6; } -if ${ac_cv_func_memfd_create+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ +fi +ac_fn_c_check_func "$LINENO" "realpath" "ac_cv_func_realpath" +if test "x$ac_cv_func_realpath" = xyes +then : + printf "%s\n" "#define HAVE_REALPATH 1" >>confdefs.h -#ifdef HAVE_SYS_MMAN_H -#include -#endif -#ifdef HAVE_SYS_MEMFD_H -#include -#endif +fi +ac_fn_c_check_func "$LINENO" "renameat" "ac_cv_func_renameat" +if test "x$ac_cv_func_renameat" = xyes +then : + printf "%s\n" "#define HAVE_RENAMEAT 1" >>confdefs.h -int -main () -{ -void *x=memfd_create - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_func_memfd_create=yes -else - ac_cv_func_memfd_create=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_fn_c_check_func "$LINENO" "rtpSpawn" "ac_cv_func_rtpSpawn" +if test "x$ac_cv_func_rtpSpawn" = xyes +then : + printf "%s\n" "#define HAVE_RTPSPAWN 1" >>confdefs.h fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_memfd_create" >&5 -$as_echo "$ac_cv_func_memfd_create" >&6; } - if test "x$ac_cv_func_memfd_create" = xyes; then : +ac_fn_c_check_func "$LINENO" "sched_get_priority_max" "ac_cv_func_sched_get_priority_max" +if test "x$ac_cv_func_sched_get_priority_max" = xyes +then : + printf "%s\n" "#define HAVE_SCHED_GET_PRIORITY_MAX 1" >>confdefs.h -$as_echo "#define HAVE_MEMFD_CREATE 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "sched_rr_get_interval" "ac_cv_func_sched_rr_get_interval" +if test "x$ac_cv_func_sched_rr_get_interval" = xyes +then : + printf "%s\n" "#define HAVE_SCHED_RR_GET_INTERVAL 1" >>confdefs.h fi +ac_fn_c_check_func "$LINENO" "sched_setaffinity" "ac_cv_func_sched_setaffinity" +if test "x$ac_cv_func_sched_setaffinity" = xyes +then : + printf "%s\n" "#define HAVE_SCHED_SETAFFINITY 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "sched_setparam" "ac_cv_func_sched_setparam" +if test "x$ac_cv_func_sched_setparam" = xyes +then : + printf "%s\n" "#define HAVE_SCHED_SETPARAM 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "sched_setscheduler" "ac_cv_func_sched_setscheduler" +if test "x$ac_cv_func_sched_setscheduler" = xyes +then : + printf "%s\n" "#define HAVE_SCHED_SETSCHEDULER 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "sem_clockwait" "ac_cv_func_sem_clockwait" +if test "x$ac_cv_func_sem_clockwait" = xyes +then : + printf "%s\n" "#define HAVE_SEM_CLOCKWAIT 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "sem_getvalue" "ac_cv_func_sem_getvalue" +if test "x$ac_cv_func_sem_getvalue" = xyes +then : + printf "%s\n" "#define HAVE_SEM_GETVALUE 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "sem_open" "ac_cv_func_sem_open" +if test "x$ac_cv_func_sem_open" = xyes +then : + printf "%s\n" "#define HAVE_SEM_OPEN 1" >>confdefs.h - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for eventfd" >&5 -$as_echo_n "checking for eventfd... " >&6; } -if ${ac_cv_func_eventfd+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ +fi +ac_fn_c_check_func "$LINENO" "sem_timedwait" "ac_cv_func_sem_timedwait" +if test "x$ac_cv_func_sem_timedwait" = xyes +then : + printf "%s\n" "#define HAVE_SEM_TIMEDWAIT 1" >>confdefs.h -#ifdef HAVE_SYS_EVENTFD_H -#include -#endif +fi +ac_fn_c_check_func "$LINENO" "sem_unlink" "ac_cv_func_sem_unlink" +if test "x$ac_cv_func_sem_unlink" = xyes +then : + printf "%s\n" "#define HAVE_SEM_UNLINK 1" >>confdefs.h -int -main () -{ -void *x=eventfd - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_func_eventfd=yes -else - ac_cv_func_eventfd=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_fn_c_check_func "$LINENO" "sendfile" "ac_cv_func_sendfile" +if test "x$ac_cv_func_sendfile" = xyes +then : + printf "%s\n" "#define HAVE_SENDFILE 1" >>confdefs.h fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_eventfd" >&5 -$as_echo "$ac_cv_func_eventfd" >&6; } - if test "x$ac_cv_func_eventfd" = xyes; then : +ac_fn_c_check_func "$LINENO" "setegid" "ac_cv_func_setegid" +if test "x$ac_cv_func_setegid" = xyes +then : + printf "%s\n" "#define HAVE_SETEGID 1" >>confdefs.h -$as_echo "#define HAVE_EVENTFD 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "seteuid" "ac_cv_func_seteuid" +if test "x$ac_cv_func_seteuid" = xyes +then : + printf "%s\n" "#define HAVE_SETEUID 1" >>confdefs.h fi +ac_fn_c_check_func "$LINENO" "setgid" "ac_cv_func_setgid" +if test "x$ac_cv_func_setgid" = xyes +then : + printf "%s\n" "#define HAVE_SETGID 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "sethostname" "ac_cv_func_sethostname" +if test "x$ac_cv_func_sethostname" = xyes +then : + printf "%s\n" "#define HAVE_SETHOSTNAME 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "setitimer" "ac_cv_func_setitimer" +if test "x$ac_cv_func_setitimer" = xyes +then : + printf "%s\n" "#define HAVE_SETITIMER 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "setlocale" "ac_cv_func_setlocale" +if test "x$ac_cv_func_setlocale" = xyes +then : + printf "%s\n" "#define HAVE_SETLOCALE 1" >>confdefs.h -# On some systems (eg. FreeBSD 5), we would find a definition of the -# functions ctermid_r, setgroups in the library, but no prototype -# (e.g. because we use _XOPEN_SOURCE). See whether we can take their -# address to avoid compiler warnings and potential miscompilations -# because of the missing prototypes. +fi +ac_fn_c_check_func "$LINENO" "setpgid" "ac_cv_func_setpgid" +if test "x$ac_cv_func_setpgid" = xyes +then : + printf "%s\n" "#define HAVE_SETPGID 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "setpgrp" "ac_cv_func_setpgrp" +if test "x$ac_cv_func_setpgrp" = xyes +then : + printf "%s\n" "#define HAVE_SETPGRP 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "setpriority" "ac_cv_func_setpriority" +if test "x$ac_cv_func_setpriority" = xyes +then : + printf "%s\n" "#define HAVE_SETPRIORITY 1" >>confdefs.h - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ctermid_r" >&5 -$as_echo_n "checking for ctermid_r... " >&6; } -if ${ac_cv_func_ctermid_r+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -int -main () -{ -void *x=ctermid_r - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_func_ctermid_r=yes -else - ac_cv_func_ctermid_r=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_fn_c_check_func "$LINENO" "setregid" "ac_cv_func_setregid" +if test "x$ac_cv_func_setregid" = xyes +then : + printf "%s\n" "#define HAVE_SETREGID 1" >>confdefs.h fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_ctermid_r" >&5 -$as_echo "$ac_cv_func_ctermid_r" >&6; } - if test "x$ac_cv_func_ctermid_r" = xyes; then : +ac_fn_c_check_func "$LINENO" "setresgid" "ac_cv_func_setresgid" +if test "x$ac_cv_func_setresgid" = xyes +then : + printf "%s\n" "#define HAVE_SETRESGID 1" >>confdefs.h -$as_echo "#define HAVE_CTERMID_R 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "setresuid" "ac_cv_func_setresuid" +if test "x$ac_cv_func_setresuid" = xyes +then : + printf "%s\n" "#define HAVE_SETRESUID 1" >>confdefs.h fi +ac_fn_c_check_func "$LINENO" "setreuid" "ac_cv_func_setreuid" +if test "x$ac_cv_func_setreuid" = xyes +then : + printf "%s\n" "#define HAVE_SETREUID 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "setsid" "ac_cv_func_setsid" +if test "x$ac_cv_func_setsid" = xyes +then : + printf "%s\n" "#define HAVE_SETSID 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "setuid" "ac_cv_func_setuid" +if test "x$ac_cv_func_setuid" = xyes +then : + printf "%s\n" "#define HAVE_SETUID 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "setvbuf" "ac_cv_func_setvbuf" +if test "x$ac_cv_func_setvbuf" = xyes +then : + printf "%s\n" "#define HAVE_SETVBUF 1" >>confdefs.h -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for flock declaration" >&5 -$as_echo_n "checking for flock declaration... " >&6; } -if ${ac_cv_flock_decl+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -int -main () -{ -void* p = flock +fi +ac_fn_c_check_func "$LINENO" "shutdown" "ac_cv_func_shutdown" +if test "x$ac_cv_func_shutdown" = xyes +then : + printf "%s\n" "#define HAVE_SHUTDOWN 1" >>confdefs.h - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_flock_decl=yes -else - ac_cv_flock_decl=no +fi +ac_fn_c_check_func "$LINENO" "sigaction" "ac_cv_func_sigaction" +if test "x$ac_cv_func_sigaction" = xyes +then : + printf "%s\n" "#define HAVE_SIGACTION 1" >>confdefs.h fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_fn_c_check_func "$LINENO" "sigaltstack" "ac_cv_func_sigaltstack" +if test "x$ac_cv_func_sigaltstack" = xyes +then : + printf "%s\n" "#define HAVE_SIGALTSTACK 1" >>confdefs.h fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_flock_decl" >&5 -$as_echo "$ac_cv_flock_decl" >&6; } -if test "x$ac_cv_flock_decl" = xyes; then : - for ac_func in flock -do : - ac_fn_c_check_func "$LINENO" "flock" "ac_cv_func_flock" -if test "x$ac_cv_func_flock" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_FLOCK 1 -_ACEOF +ac_fn_c_check_func "$LINENO" "sigfillset" "ac_cv_func_sigfillset" +if test "x$ac_cv_func_sigfillset" = xyes +then : + printf "%s\n" "#define HAVE_SIGFILLSET 1" >>confdefs.h fi -done +ac_fn_c_check_func "$LINENO" "siginterrupt" "ac_cv_func_siginterrupt" +if test "x$ac_cv_func_siginterrupt" = xyes +then : + printf "%s\n" "#define HAVE_SIGINTERRUPT 1" >>confdefs.h - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for flock in -lbsd" >&5 -$as_echo_n "checking for flock in -lbsd... " >&6; } -if ${ac_cv_lib_bsd_flock+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lbsd $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ +fi +ac_fn_c_check_func "$LINENO" "sigpending" "ac_cv_func_sigpending" +if test "x$ac_cv_func_sigpending" = xyes +then : + printf "%s\n" "#define HAVE_SIGPENDING 1" >>confdefs.h -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char flock (); -int -main () -{ -return flock (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_bsd_flock=yes -else - ac_cv_lib_bsd_flock=no fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS +ac_fn_c_check_func "$LINENO" "sigrelse" "ac_cv_func_sigrelse" +if test "x$ac_cv_func_sigrelse" = xyes +then : + printf "%s\n" "#define HAVE_SIGRELSE 1" >>confdefs.h + fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bsd_flock" >&5 -$as_echo "$ac_cv_lib_bsd_flock" >&6; } -if test "x$ac_cv_lib_bsd_flock" = xyes; then : - FCNTL_LIBS="-lbsd" +ac_fn_c_check_func "$LINENO" "sigtimedwait" "ac_cv_func_sigtimedwait" +if test "x$ac_cv_func_sigtimedwait" = xyes +then : + printf "%s\n" "#define HAVE_SIGTIMEDWAIT 1" >>confdefs.h + fi +ac_fn_c_check_func "$LINENO" "sigwait" "ac_cv_func_sigwait" +if test "x$ac_cv_func_sigwait" = xyes +then : + printf "%s\n" "#define HAVE_SIGWAIT 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "sigwaitinfo" "ac_cv_func_sigwaitinfo" +if test "x$ac_cv_func_sigwaitinfo" = xyes +then : + printf "%s\n" "#define HAVE_SIGWAITINFO 1" >>confdefs.h fi +ac_fn_c_check_func "$LINENO" "snprintf" "ac_cv_func_snprintf" +if test "x$ac_cv_func_snprintf" = xyes +then : + printf "%s\n" "#define HAVE_SNPRINTF 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "splice" "ac_cv_func_splice" +if test "x$ac_cv_func_splice" = xyes +then : + printf "%s\n" "#define HAVE_SPLICE 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "strftime" "ac_cv_func_strftime" +if test "x$ac_cv_func_strftime" = xyes +then : + printf "%s\n" "#define HAVE_STRFTIME 1" >>confdefs.h - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getpagesize" >&5 -$as_echo_n "checking for getpagesize... " >&6; } -if ${ac_cv_func_getpagesize+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -int -main () -{ -void *x=getpagesize - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_func_getpagesize=yes -else - ac_cv_func_getpagesize=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_fn_c_check_func "$LINENO" "strlcpy" "ac_cv_func_strlcpy" +if test "x$ac_cv_func_strlcpy" = xyes +then : + printf "%s\n" "#define HAVE_STRLCPY 1" >>confdefs.h fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_getpagesize" >&5 -$as_echo "$ac_cv_func_getpagesize" >&6; } - if test "x$ac_cv_func_getpagesize" = xyes; then : +ac_fn_c_check_func "$LINENO" "strsignal" "ac_cv_func_strsignal" +if test "x$ac_cv_func_strsignal" = xyes +then : + printf "%s\n" "#define HAVE_STRSIGNAL 1" >>confdefs.h -$as_echo "#define HAVE_GETPAGESIZE 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "symlinkat" "ac_cv_func_symlinkat" +if test "x$ac_cv_func_symlinkat" = xyes +then : + printf "%s\n" "#define HAVE_SYMLINKAT 1" >>confdefs.h fi +ac_fn_c_check_func "$LINENO" "sync" "ac_cv_func_sync" +if test "x$ac_cv_func_sync" = xyes +then : + printf "%s\n" "#define HAVE_SYNC 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "sysconf" "ac_cv_func_sysconf" +if test "x$ac_cv_func_sysconf" = xyes +then : + printf "%s\n" "#define HAVE_SYSCONF 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "system" "ac_cv_func_system" +if test "x$ac_cv_func_system" = xyes +then : + printf "%s\n" "#define HAVE_SYSTEM 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "tcgetpgrp" "ac_cv_func_tcgetpgrp" +if test "x$ac_cv_func_tcgetpgrp" = xyes +then : + printf "%s\n" "#define HAVE_TCGETPGRP 1" >>confdefs.h -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for broken unsetenv" >&5 -$as_echo_n "checking for broken unsetenv... " >&6; } -if ${ac_cv_broken_unsetenv+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -int -main () -{ -int res = unsetenv("DUMMY") - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_broken_unsetenv=no -else - ac_cv_broken_unsetenv=yes +fi +ac_fn_c_check_func "$LINENO" "tcsetpgrp" "ac_cv_func_tcsetpgrp" +if test "x$ac_cv_func_tcsetpgrp" = xyes +then : + printf "%s\n" "#define HAVE_TCSETPGRP 1" >>confdefs.h fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_fn_c_check_func "$LINENO" "tempnam" "ac_cv_func_tempnam" +if test "x$ac_cv_func_tempnam" = xyes +then : + printf "%s\n" "#define HAVE_TEMPNAM 1" >>confdefs.h fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_broken_unsetenv" >&5 -$as_echo "$ac_cv_broken_unsetenv" >&6; } -if test "x$ac_cv_broken_unsetenv" = xyes; then : +ac_fn_c_check_func "$LINENO" "timegm" "ac_cv_func_timegm" +if test "x$ac_cv_func_timegm" = xyes +then : + printf "%s\n" "#define HAVE_TIMEGM 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "times" "ac_cv_func_times" +if test "x$ac_cv_func_times" = xyes +then : + printf "%s\n" "#define HAVE_TIMES 1" >>confdefs.h -$as_echo "#define HAVE_BROKEN_UNSETENV 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "tmpfile" "ac_cv_func_tmpfile" +if test "x$ac_cv_func_tmpfile" = xyes +then : + printf "%s\n" "#define HAVE_TMPFILE 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "tmpnam" "ac_cv_func_tmpnam" +if test "x$ac_cv_func_tmpnam" = xyes +then : + printf "%s\n" "#define HAVE_TMPNAM 1" >>confdefs.h fi +ac_fn_c_check_func "$LINENO" "tmpnam_r" "ac_cv_func_tmpnam_r" +if test "x$ac_cv_func_tmpnam_r" = xyes +then : + printf "%s\n" "#define HAVE_TMPNAM_R 1" >>confdefs.h -for ac_prog in true -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_TRUE+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$TRUE"; then - ac_cv_prog_TRUE="$TRUE" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_TRUE="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS +fi +ac_fn_c_check_func "$LINENO" "truncate" "ac_cv_func_truncate" +if test "x$ac_cv_func_truncate" = xyes +then : + printf "%s\n" "#define HAVE_TRUNCATE 1" >>confdefs.h fi +ac_fn_c_check_func "$LINENO" "ttyname" "ac_cv_func_ttyname" +if test "x$ac_cv_func_ttyname" = xyes +then : + printf "%s\n" "#define HAVE_TTYNAME 1" >>confdefs.h + fi -TRUE=$ac_cv_prog_TRUE -if test -n "$TRUE"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $TRUE" >&5 -$as_echo "$TRUE" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } +ac_fn_c_check_func "$LINENO" "umask" "ac_cv_func_umask" +if test "x$ac_cv_func_umask" = xyes +then : + printf "%s\n" "#define HAVE_UMASK 1" >>confdefs.h + fi +ac_fn_c_check_func "$LINENO" "uname" "ac_cv_func_uname" +if test "x$ac_cv_func_uname" = xyes +then : + printf "%s\n" "#define HAVE_UNAME 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "unlinkat" "ac_cv_func_unlinkat" +if test "x$ac_cv_func_unlinkat" = xyes +then : + printf "%s\n" "#define HAVE_UNLINKAT 1" >>confdefs.h - test -n "$TRUE" && break -done -test -n "$TRUE" || TRUE="/bin/true" +fi +ac_fn_c_check_func "$LINENO" "utimensat" "ac_cv_func_utimensat" +if test "x$ac_cv_func_utimensat" = xyes +then : + printf "%s\n" "#define HAVE_UTIMENSAT 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "utimes" "ac_cv_func_utimes" +if test "x$ac_cv_func_utimes" = xyes +then : + printf "%s\n" "#define HAVE_UTIMES 1" >>confdefs.h -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_aton in -lc" >&5 -$as_echo_n "checking for inet_aton in -lc... " >&6; } -if ${ac_cv_lib_c_inet_aton+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lc $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ +fi +ac_fn_c_check_func "$LINENO" "vfork" "ac_cv_func_vfork" +if test "x$ac_cv_func_vfork" = xyes +then : + printf "%s\n" "#define HAVE_VFORK 1" >>confdefs.h -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char inet_aton (); -int -main () -{ -return inet_aton (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_c_inet_aton=yes -else - ac_cv_lib_c_inet_aton=no fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS +ac_fn_c_check_func "$LINENO" "wait" "ac_cv_func_wait" +if test "x$ac_cv_func_wait" = xyes +then : + printf "%s\n" "#define HAVE_WAIT 1" >>confdefs.h + fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_c_inet_aton" >&5 -$as_echo "$ac_cv_lib_c_inet_aton" >&6; } -if test "x$ac_cv_lib_c_inet_aton" = xyes; then : - $ac_cv_prog_TRUE -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_aton in -lresolv" >&5 -$as_echo_n "checking for inet_aton in -lresolv... " >&6; } -if ${ac_cv_lib_resolv_inet_aton+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lresolv $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ +ac_fn_c_check_func "$LINENO" "wait3" "ac_cv_func_wait3" +if test "x$ac_cv_func_wait3" = xyes +then : + printf "%s\n" "#define HAVE_WAIT3 1" >>confdefs.h -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char inet_aton (); -int -main () -{ -return inet_aton (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_resolv_inet_aton=yes -else - ac_cv_lib_resolv_inet_aton=no fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS +ac_fn_c_check_func "$LINENO" "wait4" "ac_cv_func_wait4" +if test "x$ac_cv_func_wait4" = xyes +then : + printf "%s\n" "#define HAVE_WAIT4 1" >>confdefs.h + fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_resolv_inet_aton" >&5 -$as_echo "$ac_cv_lib_resolv_inet_aton" >&6; } -if test "x$ac_cv_lib_resolv_inet_aton" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBRESOLV 1 -_ACEOF +ac_fn_c_check_func "$LINENO" "waitid" "ac_cv_func_waitid" +if test "x$ac_cv_func_waitid" = xyes +then : + printf "%s\n" "#define HAVE_WAITID 1" >>confdefs.h - LIBS="-lresolv $LIBS" +fi +ac_fn_c_check_func "$LINENO" "waitpid" "ac_cv_func_waitpid" +if test "x$ac_cv_func_waitpid" = xyes +then : + printf "%s\n" "#define HAVE_WAITPID 1" >>confdefs.h fi +ac_fn_c_check_func "$LINENO" "wcscoll" "ac_cv_func_wcscoll" +if test "x$ac_cv_func_wcscoll" = xyes +then : + printf "%s\n" "#define HAVE_WCSCOLL 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "wcsftime" "ac_cv_func_wcsftime" +if test "x$ac_cv_func_wcsftime" = xyes +then : + printf "%s\n" "#define HAVE_WCSFTIME 1" >>confdefs.h fi +ac_fn_c_check_func "$LINENO" "wcsxfrm" "ac_cv_func_wcsxfrm" +if test "x$ac_cv_func_wcsxfrm" = xyes +then : + printf "%s\n" "#define HAVE_WCSXFRM 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "wmemcmp" "ac_cv_func_wmemcmp" +if test "x$ac_cv_func_wmemcmp" = xyes +then : + printf "%s\n" "#define HAVE_WMEMCMP 1" >>confdefs.h -# On Tru64, chflags seems to be present, but calling it will -# exit Python -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for chflags" >&5 -$as_echo_n "checking for chflags... " >&6; } -if ${ac_cv_have_chflags+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "$cross_compiling" = yes; then : - ac_cv_have_chflags=cross -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext +fi +ac_fn_c_check_func "$LINENO" "writev" "ac_cv_func_writev" +if test "x$ac_cv_func_writev" = xyes +then : + printf "%s\n" "#define HAVE_WRITEV 1" >>confdefs.h + +fi + + +# Force lchmod off for Linux. Linux disallows changing the mode of symbolic +# links. Some libc implementations have a stub lchmod implementation that always +# returns an error. +if test "$MACHDEP" != linux; then + ac_fn_c_check_func "$LINENO" "lchmod" "ac_cv_func_lchmod" +if test "x$ac_cv_func_lchmod" = xyes +then : + printf "%s\n" "#define HAVE_LCHMOD 1" >>confdefs.h + +fi + +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC options needed to detect all undeclared functions" >&5 +printf %s "checking for $CC options needed to detect all undeclared functions... " >&6; } +if test ${ac_cv_c_undeclared_builtin_options+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_save_CFLAGS=$CFLAGS + ac_cv_c_undeclared_builtin_options='cannot detect' + for ac_arg in '' -fno-builtin; do + CFLAGS="$ac_save_CFLAGS $ac_arg" + # This test program should *not* compile successfully. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include -#include -int main(int argc, char *argv[]) +int +main (void) { - if(chflags(argv[0], 0) != 0) - return 1; +(void) strchr; + ; return 0; } +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : +else $as_nop + # This test program should compile successfully. + # No library function is consistently available on + # freestanding implementations, so test against a dummy + # declaration. Include always-available headers on the + # off chance that they somehow elicit warnings. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include +extern void ac_decl (int, char *); + +int +main (void) +{ +(void) ac_decl (0, (char *) 0); + (void) ac_decl; + + ; + return 0; +} _ACEOF -if ac_fn_c_try_run "$LINENO"; then : - ac_cv_have_chflags=yes -else - ac_cv_have_chflags=no +if ac_fn_c_try_compile "$LINENO" +then : + if test x"$ac_arg" = x +then : + ac_cv_c_undeclared_builtin_options='none needed' +else $as_nop + ac_cv_c_undeclared_builtin_options=$ac_arg fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext + break fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + done + CFLAGS=$ac_save_CFLAGS + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_undeclared_builtin_options" >&5 +printf "%s\n" "$ac_cv_c_undeclared_builtin_options" >&6; } + case $ac_cv_c_undeclared_builtin_options in #( + 'cannot detect') : + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot make $CC report undeclared builtins +See \`config.log' for more details" "$LINENO" 5; } ;; #( + 'none needed') : + ac_c_undeclared_builtin_options='' ;; #( + *) : + ac_c_undeclared_builtin_options=$ac_cv_c_undeclared_builtin_options ;; +esac +ac_fn_check_decl "$LINENO" "dirfd" "ac_cv_have_decl_dirfd" "#include + #include +" "$ac_c_undeclared_builtin_options" "CFLAGS" +if test "x$ac_cv_have_decl_dirfd" = xyes +then : -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_chflags" >&5 -$as_echo "$ac_cv_have_chflags" >&6; } -if test "$ac_cv_have_chflags" = cross ; then - ac_fn_c_check_func "$LINENO" "chflags" "ac_cv_func_chflags" -if test "x$ac_cv_func_chflags" = xyes; then : - ac_cv_have_chflags="yes" -else - ac_cv_have_chflags="no" -fi +printf "%s\n" "#define HAVE_DIRFD 1" >>confdefs.h fi -if test "$ac_cv_have_chflags" = yes ; then -$as_echo "#define HAVE_CHFLAGS 1" >>confdefs.h +# For some functions, having a definition is not sufficient, since +# we want to take their address. -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for lchflags" >&5 -$as_echo_n "checking for lchflags... " >&6; } -if ${ac_cv_have_lchflags+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "$cross_compiling" = yes; then : - ac_cv_have_lchflags=cross -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for chroot" >&5 +printf %s "checking for chroot... " >&6; } +if test ${ac_cv_func_chroot+y} +then : + printf %s "(cached) " >&6 +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - -#include #include -int main(int argc, char *argv[]) +int +main (void) { - if(lchflags(argv[0], 0) != 0) - return 1; +void *x=chroot + ; return 0; } - _ACEOF -if ac_fn_c_try_run "$LINENO"; then : - ac_cv_have_lchflags=yes -else - ac_cv_have_lchflags=no +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_chroot=yes +else $as_nop + ac_cv_func_chroot=no fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_chroot" >&5 +printf "%s\n" "$ac_cv_func_chroot" >&6; } + if test "x$ac_cv_func_chroot" = xyes +then : +printf "%s\n" "#define HAVE_CHROOT 1" >>confdefs.h fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_lchflags" >&5 -$as_echo "$ac_cv_have_lchflags" >&6; } -if test "$ac_cv_have_lchflags" = cross ; then - ac_fn_c_check_func "$LINENO" "lchflags" "ac_cv_func_lchflags" -if test "x$ac_cv_func_lchflags" = xyes; then : - ac_cv_have_lchflags="yes" -else - ac_cv_have_lchflags="no" + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for link" >&5 +printf %s "checking for link... " >&6; } +if test ${ac_cv_func_link+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main (void) +{ +void *x=link + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_link=yes +else $as_nop + ac_cv_func_link=no fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi -if test "$ac_cv_have_lchflags" = yes ; then +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_link" >&5 +printf "%s\n" "$ac_cv_func_link" >&6; } + if test "x$ac_cv_func_link" = xyes +then : -$as_echo "#define HAVE_LCHFLAGS 1" >>confdefs.h +printf "%s\n" "#define HAVE_LINK 1" >>confdefs.h fi @@ -16150,11 +18780,38 @@ fi + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for symlink" >&5 +printf %s "checking for symlink... " >&6; } +if test ${ac_cv_func_symlink+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main (void) +{ +void *x=symlink + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_symlink=yes +else $as_nop + ac_cv_func_symlink=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext - if test "$ac_sys_system" = "Emscripten" -a -z "$ZLIB_CFLAGS" -a -z "$ZLIB_LIBS"; then : +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_symlink" >&5 +printf "%s\n" "$ac_cv_func_symlink" >&6; } + if test "x$ac_cv_func_symlink" = xyes +then : - ZLIB_CFLAGS="-sUSE_ZLIB" - ZLIB_LIBS="-sUSE_ZLIB" +printf "%s\n" "#define HAVE_SYMLINK 1" >>confdefs.h fi @@ -16162,954 +18819,865 @@ fi -pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ZLIB" >&5 -$as_echo_n "checking for ZLIB... " >&6; } - -if test -n "$ZLIB_CFLAGS"; then - pkg_cv_ZLIB_CFLAGS="$ZLIB_CFLAGS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"zlib >= 1.2.0\""; } >&5 - ($PKG_CONFIG --exists --print-errors "zlib >= 1.2.0") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_ZLIB_CFLAGS=`$PKG_CONFIG --cflags "zlib >= 1.2.0" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi -if test -n "$ZLIB_LIBS"; then - pkg_cv_ZLIB_LIBS="$ZLIB_LIBS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"zlib >= 1.2.0\""; } >&5 - ($PKG_CONFIG --exists --print-errors "zlib >= 1.2.0") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_ZLIB_LIBS=`$PKG_CONFIG --libs "zlib >= 1.2.0" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for fchdir" >&5 +printf %s "checking for fchdir... " >&6; } +if test ${ac_cv_func_fchdir+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main (void) +{ +void *x=fchdir + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_fchdir=yes +else $as_nop + ac_cv_func_fchdir=no fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_fchdir" >&5 +printf "%s\n" "$ac_cv_func_fchdir" >&6; } + if test "x$ac_cv_func_fchdir" = xyes +then : +printf "%s\n" "#define HAVE_FCHDIR 1" >>confdefs.h -if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - -if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then - _pkg_short_errors_supported=yes -else - _pkg_short_errors_supported=no fi - if test $_pkg_short_errors_supported = yes; then - ZLIB_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "zlib >= 1.2.0" 2>&1` - else - ZLIB_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "zlib >= 1.2.0" 2>&1` - fi - # Put the nasty error message in config.log where it belongs - echo "$ZLIB_PKG_ERRORS" >&5 - save_CFLAGS=$CFLAGS -save_CPPFLAGS=$CPPFLAGS -save_LDFLAGS=$LDFLAGS -save_LIBS=$LIBS - CPPFLAGS="$CPPFLAGS $ZLIB_CFLAGS" - LDFLAGS="$LDFLAGS $ZLIB_LIBS" - for ac_header in zlib.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default" -if test "x$ac_cv_header_zlib_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_ZLIB_H 1 -_ACEOF - py_check_lib_save_LIBS=$LIBS -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for gzread in -lz" >&5 -$as_echo_n "checking for gzread in -lz... " >&6; } -if ${ac_cv_lib_z_gzread+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lz $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for fsync" >&5 +printf %s "checking for fsync... " >&6; } +if test ${ac_cv_func_fsync+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char gzread (); +#include int -main () +main (void) { -return gzread (); +void *x=fsync ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_z_gzread=yes -else - ac_cv_lib_z_gzread=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_gzread" >&5 -$as_echo "$ac_cv_lib_z_gzread" >&6; } -if test "x$ac_cv_lib_z_gzread" = xyes; then : - have_zlib=yes -else - have_zlib=no +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_fsync=yes +else $as_nop + ac_cv_func_fsync=no fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext -LIBS=$py_check_lib_save_LIBS +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_fsync" >&5 +printf "%s\n" "$ac_cv_func_fsync" >&6; } + if test "x$ac_cv_func_fsync" = xyes +then : +printf "%s\n" "#define HAVE_FSYNC 1" >>confdefs.h -else - have_zlib=no fi -done - if test "x$have_zlib" = xyes; then : - ZLIB_CFLAGS=${ZLIB_CFLAGS-""} - ZLIB_LIBS=${ZLIB_LIBS-"-lz"} - py_check_lib_save_LIBS=$LIBS -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inflateCopy in -lz" >&5 -$as_echo_n "checking for inflateCopy in -lz... " >&6; } -if ${ac_cv_lib_z_inflateCopy+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lz $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char inflateCopy (); + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for fdatasync" >&5 +printf %s "checking for fdatasync... " >&6; } +if test ${ac_cv_func_fdatasync+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include int -main () +main (void) { -return inflateCopy (); +void *x=fdatasync ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_z_inflateCopy=yes -else - ac_cv_lib_z_inflateCopy=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_fdatasync=yes +else $as_nop + ac_cv_func_fdatasync=no fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_inflateCopy" >&5 -$as_echo "$ac_cv_lib_z_inflateCopy" >&6; } -if test "x$ac_cv_lib_z_inflateCopy" = xyes; then : - $as_echo "#define HAVE_ZLIB_COPY 1" >>confdefs.h +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_fdatasync" >&5 +printf "%s\n" "$ac_cv_func_fdatasync" >&6; } + if test "x$ac_cv_func_fdatasync" = xyes +then : -LIBS=$py_check_lib_save_LIBS - +printf "%s\n" "#define HAVE_FDATASYNC 1" >>confdefs.h fi -CFLAGS=$save_CFLAGS -CPPFLAGS=$save_CPPFLAGS -LDFLAGS=$save_LDFLAGS -LIBS=$save_LIBS - -elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - - save_CFLAGS=$CFLAGS -save_CPPFLAGS=$CPPFLAGS -save_LDFLAGS=$LDFLAGS -save_LIBS=$LIBS - - CPPFLAGS="$CPPFLAGS $ZLIB_CFLAGS" - LDFLAGS="$LDFLAGS $ZLIB_LIBS" - for ac_header in zlib.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default" -if test "x$ac_cv_header_zlib_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_ZLIB_H 1 -_ACEOF - py_check_lib_save_LIBS=$LIBS -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for gzread in -lz" >&5 -$as_echo_n "checking for gzread in -lz... " >&6; } -if ${ac_cv_lib_z_gzread+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lz $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for epoll_create" >&5 +printf %s "checking for epoll_create... " >&6; } +if test ${ac_cv_func_epoll_create+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char gzread (); +#include int -main () +main (void) { -return gzread (); +void *x=epoll_create ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_z_gzread=yes -else - ac_cv_lib_z_gzread=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_gzread" >&5 -$as_echo "$ac_cv_lib_z_gzread" >&6; } -if test "x$ac_cv_lib_z_gzread" = xyes; then : - have_zlib=yes -else - have_zlib=no +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_epoll_create=yes +else $as_nop + ac_cv_func_epoll_create=no fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext -LIBS=$py_check_lib_save_LIBS +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_epoll_create" >&5 +printf "%s\n" "$ac_cv_func_epoll_create" >&6; } + if test "x$ac_cv_func_epoll_create" = xyes +then : +printf "%s\n" "#define HAVE_EPOLL 1" >>confdefs.h -else - have_zlib=no fi -done - if test "x$have_zlib" = xyes; then : - ZLIB_CFLAGS=${ZLIB_CFLAGS-""} - ZLIB_LIBS=${ZLIB_LIBS-"-lz"} - py_check_lib_save_LIBS=$LIBS -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inflateCopy in -lz" >&5 -$as_echo_n "checking for inflateCopy in -lz... " >&6; } -if ${ac_cv_lib_z_inflateCopy+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lz $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char inflateCopy (); + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for epoll_create1" >&5 +printf %s "checking for epoll_create1... " >&6; } +if test ${ac_cv_func_epoll_create1+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include int -main () +main (void) { -return inflateCopy (); +void *x=epoll_create1 ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_z_inflateCopy=yes -else - ac_cv_lib_z_inflateCopy=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_epoll_create1=yes +else $as_nop + ac_cv_func_epoll_create1=no fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_inflateCopy" >&5 -$as_echo "$ac_cv_lib_z_inflateCopy" >&6; } -if test "x$ac_cv_lib_z_inflateCopy" = xyes; then : - $as_echo "#define HAVE_ZLIB_COPY 1" >>confdefs.h +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_epoll_create1" >&5 +printf "%s\n" "$ac_cv_func_epoll_create1" >&6; } + if test "x$ac_cv_func_epoll_create1" = xyes +then : -LIBS=$py_check_lib_save_LIBS - +printf "%s\n" "#define HAVE_EPOLL_CREATE1 1" >>confdefs.h fi -CFLAGS=$save_CFLAGS -CPPFLAGS=$save_CPPFLAGS -LDFLAGS=$save_LDFLAGS -LIBS=$save_LIBS -else - ZLIB_CFLAGS=$pkg_cv_ZLIB_CFLAGS - ZLIB_LIBS=$pkg_cv_ZLIB_LIBS - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - have_zlib=yes - $as_echo "#define HAVE_ZLIB_COPY 1" >>confdefs.h + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for kqueue" >&5 +printf %s "checking for kqueue... " >&6; } +if test ${ac_cv_func_kqueue+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +int +main (void) +{ +void *x=kqueue + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_kqueue=yes +else $as_nop + ac_cv_func_kqueue=no fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext -if test "x$have_zlib" = xyes; then : +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_kqueue" >&5 +printf "%s\n" "$ac_cv_func_kqueue" >&6; } + if test "x$ac_cv_func_kqueue" = xyes +then : - BINASCII_CFLAGS="-DUSE_ZLIB_CRC32 $ZLIB_CFLAGS" - BINASCII_LIBS="$ZLIB_LIBS" +printf "%s\n" "#define HAVE_KQUEUE 1" >>confdefs.h fi - if test "$ac_sys_system" = "Emscripten" -a -z "$BZIP2_CFLAGS" -a -z "$BZIP2_LIBS"; then : - BZIP2_CFLAGS="-sUSE_BZIP2" - BZIP2_LIBS="-sUSE_BZIP2" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for prlimit" >&5 +printf %s "checking for prlimit... " >&6; } +if test ${ac_cv_func_prlimit+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +int +main (void) +{ +void *x=prlimit + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_prlimit=yes +else $as_nop + ac_cv_func_prlimit=no fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_prlimit" >&5 +printf "%s\n" "$ac_cv_func_prlimit" >&6; } + if test "x$ac_cv_func_prlimit" = xyes +then : +printf "%s\n" "#define HAVE_PRLIMIT 1" >>confdefs.h +fi -pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BZIP2" >&5 -$as_echo_n "checking for BZIP2... " >&6; } -if test -n "$BZIP2_CFLAGS"; then - pkg_cv_BZIP2_CFLAGS="$BZIP2_CFLAGS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"bzip2\""; } >&5 - ($PKG_CONFIG --exists --print-errors "bzip2") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_BZIP2_CFLAGS=`$PKG_CONFIG --cflags "bzip2" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi -if test -n "$BZIP2_LIBS"; then - pkg_cv_BZIP2_LIBS="$BZIP2_LIBS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"bzip2\""; } >&5 - ($PKG_CONFIG --exists --print-errors "bzip2") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_BZIP2_LIBS=`$PKG_CONFIG --libs "bzip2" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi -if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for _dyld_shared_cache_contains_path" >&5 +printf %s "checking for _dyld_shared_cache_contains_path... " >&6; } +if test ${ac_cv_func__dyld_shared_cache_contains_path+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main (void) +{ +void *x=_dyld_shared_cache_contains_path + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func__dyld_shared_cache_contains_path=yes +else $as_nop + ac_cv_func__dyld_shared_cache_contains_path=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext -if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then - _pkg_short_errors_supported=yes -else - _pkg_short_errors_supported=no fi - if test $_pkg_short_errors_supported = yes; then - BZIP2_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "bzip2" 2>&1` - else - BZIP2_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "bzip2" 2>&1` - fi - # Put the nasty error message in config.log where it belongs - echo "$BZIP2_PKG_ERRORS" >&5 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func__dyld_shared_cache_contains_path" >&5 +printf "%s\n" "$ac_cv_func__dyld_shared_cache_contains_path" >&6; } + if test "x$ac_cv_func__dyld_shared_cache_contains_path" = xyes +then : +printf "%s\n" "#define HAVE_DYLD_SHARED_CACHE_CONTAINS_PATH 1" >>confdefs.h - save_CFLAGS=$CFLAGS -save_CPPFLAGS=$CPPFLAGS -save_LDFLAGS=$LDFLAGS -save_LIBS=$LIBS +fi - CPPFLAGS="$CPPFLAGS $BZIP2_CFLAGS" - LDFLAGS="$LDFLAGS $BZIP2_LIBS" - for ac_header in bzlib.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "bzlib.h" "ac_cv_header_bzlib_h" "$ac_includes_default" -if test "x$ac_cv_header_bzlib_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_BZLIB_H 1 -_ACEOF - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for BZ2_bzCompress in -lbz2" >&5 -$as_echo_n "checking for BZ2_bzCompress in -lbz2... " >&6; } -if ${ac_cv_lib_bz2_BZ2_bzCompress+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lbz2 $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for memfd_create" >&5 +printf %s "checking for memfd_create... " >&6; } +if test ${ac_cv_func_memfd_create+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" +#ifdef HAVE_SYS_MMAN_H +#include #endif -char BZ2_bzCompress (); +#ifdef HAVE_SYS_MEMFD_H +#include +#endif + int -main () +main (void) { -return BZ2_bzCompress (); +void *x=memfd_create ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_bz2_BZ2_bzCompress=yes -else - ac_cv_lib_bz2_BZ2_bzCompress=no +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_memfd_create=yes +else $as_nop + ac_cv_func_memfd_create=no fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bz2_BZ2_bzCompress" >&5 -$as_echo "$ac_cv_lib_bz2_BZ2_bzCompress" >&6; } -if test "x$ac_cv_lib_bz2_BZ2_bzCompress" = xyes; then : - have_bzip2=yes -else - have_bzip2=no +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_memfd_create" >&5 +printf "%s\n" "$ac_cv_func_memfd_create" >&6; } + if test "x$ac_cv_func_memfd_create" = xyes +then : + +printf "%s\n" "#define HAVE_MEMFD_CREATE 1" >>confdefs.h + fi -else - have_bzip2=no -fi - -done - - if test "x$have_bzip2" = xyes; then : - - BZIP2_CFLAGS=${BZIP2_CFLAGS-""} - BZIP2_LIBS=${BZIP2_LIBS-"-lbz2"} - -fi - -CFLAGS=$save_CFLAGS -CPPFLAGS=$save_CPPFLAGS -LDFLAGS=$save_LDFLAGS -LIBS=$save_LIBS -elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - - save_CFLAGS=$CFLAGS -save_CPPFLAGS=$CPPFLAGS -save_LDFLAGS=$LDFLAGS -save_LIBS=$LIBS - - - CPPFLAGS="$CPPFLAGS $BZIP2_CFLAGS" - LDFLAGS="$LDFLAGS $BZIP2_LIBS" - for ac_header in bzlib.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "bzlib.h" "ac_cv_header_bzlib_h" "$ac_includes_default" -if test "x$ac_cv_header_bzlib_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_BZLIB_H 1 -_ACEOF - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for BZ2_bzCompress in -lbz2" >&5 -$as_echo_n "checking for BZ2_bzCompress in -lbz2... " >&6; } -if ${ac_cv_lib_bz2_BZ2_bzCompress+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lbz2 $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for eventfd" >&5 +printf %s "checking for eventfd... " >&6; } +if test ${ac_cv_func_eventfd+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" +#ifdef HAVE_SYS_EVENTFD_H +#include #endif -char BZ2_bzCompress (); + int -main () +main (void) { -return BZ2_bzCompress (); +void *x=eventfd ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_bz2_BZ2_bzCompress=yes -else - ac_cv_lib_bz2_BZ2_bzCompress=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_eventfd=yes +else $as_nop + ac_cv_func_eventfd=no fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bz2_BZ2_bzCompress" >&5 -$as_echo "$ac_cv_lib_bz2_BZ2_bzCompress" >&6; } -if test "x$ac_cv_lib_bz2_BZ2_bzCompress" = xyes; then : - have_bzip2=yes -else - have_bzip2=no +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_eventfd" >&5 +printf "%s\n" "$ac_cv_func_eventfd" >&6; } + if test "x$ac_cv_func_eventfd" = xyes +then : +printf "%s\n" "#define HAVE_EVENTFD 1" >>confdefs.h -else - have_bzip2=no fi -done - - if test "x$have_bzip2" = xyes; then : - BZIP2_CFLAGS=${BZIP2_CFLAGS-""} - BZIP2_LIBS=${BZIP2_LIBS-"-lbz2"} -fi -CFLAGS=$save_CFLAGS -CPPFLAGS=$save_CPPFLAGS -LDFLAGS=$save_LDFLAGS -LIBS=$save_LIBS +# On some systems (eg. FreeBSD 5), we would find a definition of the +# functions ctermid_r, setgroups in the library, but no prototype +# (e.g. because we use _XOPEN_SOURCE). See whether we can take their +# address to avoid compiler warnings and potential miscompilations +# because of the missing prototypes. -else - BZIP2_CFLAGS=$pkg_cv_BZIP2_CFLAGS - BZIP2_LIBS=$pkg_cv_BZIP2_LIBS - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - have_bzip2=yes + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ctermid_r" >&5 +printf %s "checking for ctermid_r... " >&6; } +if test ${ac_cv_func_ctermid_r+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main (void) +{ +void *x=ctermid_r + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_ctermid_r=yes +else $as_nop + ac_cv_func_ctermid_r=no fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_ctermid_r" >&5 +printf "%s\n" "$ac_cv_func_ctermid_r" >&6; } + if test "x$ac_cv_func_ctermid_r" = xyes +then : -pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBLZMA" >&5 -$as_echo_n "checking for LIBLZMA... " >&6; } +printf "%s\n" "#define HAVE_CTERMID_R 1" >>confdefs.h -if test -n "$LIBLZMA_CFLAGS"; then - pkg_cv_LIBLZMA_CFLAGS="$LIBLZMA_CFLAGS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblzma\""; } >&5 - ($PKG_CONFIG --exists --print-errors "liblzma") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_LIBLZMA_CFLAGS=`$PKG_CONFIG --cflags "liblzma" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi -if test -n "$LIBLZMA_LIBS"; then - pkg_cv_LIBLZMA_LIBS="$LIBLZMA_LIBS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblzma\""; } >&5 - ($PKG_CONFIG --exists --print-errors "liblzma") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_LIBLZMA_LIBS=`$PKG_CONFIG --libs "liblzma" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried fi -if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then - _pkg_short_errors_supported=yes -else - _pkg_short_errors_supported=no -fi - if test $_pkg_short_errors_supported = yes; then - LIBLZMA_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "liblzma" 2>&1` - else - LIBLZMA_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "liblzma" 2>&1` - fi - # Put the nasty error message in config.log where it belongs - echo "$LIBLZMA_PKG_ERRORS" >&5 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for flock declaration" >&5 +printf %s "checking for flock declaration... " >&6; } +if test ${ac_cv_flock_decl+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main (void) +{ +void* p = flock + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_flock_decl=yes +else $as_nop + ac_cv_flock_decl=no - save_CFLAGS=$CFLAGS -save_CPPFLAGS=$CPPFLAGS -save_LDFLAGS=$LDFLAGS -save_LIBS=$LIBS +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_flock_decl" >&5 +printf "%s\n" "$ac_cv_flock_decl" >&6; } +if test "x$ac_cv_flock_decl" = xyes +then : - CPPFLAGS="$CPPFLAGS $LIBLZMA_CFLAGS" - LDFLAGS="$LDFLAGS $LIBLZMA_LIBS" - for ac_header in lzma.h + for ac_func in flock do : - ac_fn_c_check_header_mongrel "$LINENO" "lzma.h" "ac_cv_header_lzma_h" "$ac_includes_default" -if test "x$ac_cv_header_lzma_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LZMA_H 1 -_ACEOF - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for lzma_easy_encoder in -llzma" >&5 -$as_echo_n "checking for lzma_easy_encoder in -llzma... " >&6; } -if ${ac_cv_lib_lzma_lzma_easy_encoder+:} false; then : - $as_echo_n "(cached) " >&6 -else + ac_fn_c_check_func "$LINENO" "flock" "ac_cv_func_flock" +if test "x$ac_cv_func_flock" = xyes +then : + printf "%s\n" "#define HAVE_FLOCK 1" >>confdefs.h + +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for flock in -lbsd" >&5 +printf %s "checking for flock in -lbsd... " >&6; } +if test ${ac_cv_lib_bsd_flock+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS -LIBS="-llzma $LIBS" +LIBS="-lbsd $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char lzma_easy_encoder (); +char flock (); int -main () +main (void) { -return lzma_easy_encoder (); +return flock (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_lzma_lzma_easy_encoder=yes -else - ac_cv_lib_lzma_lzma_easy_encoder=no +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_bsd_flock=yes +else $as_nop + ac_cv_lib_bsd_flock=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lzma_lzma_easy_encoder" >&5 -$as_echo "$ac_cv_lib_lzma_lzma_easy_encoder" >&6; } -if test "x$ac_cv_lib_lzma_lzma_easy_encoder" = xyes; then : - have_liblzma=yes -else - have_liblzma=no +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bsd_flock" >&5 +printf "%s\n" "$ac_cv_lib_bsd_flock" >&6; } +if test "x$ac_cv_lib_bsd_flock" = xyes +then : + FCNTL_LIBS="-lbsd" fi - -else - have_liblzma=no fi done +fi - if test "x$have_liblzma" = xyes; then : - LIBLZMA_CFLAGS=${LIBLZMA_CFLAGS-""} - LIBLZMA_LIBS=${LIBLZMA_LIBS-"-llzma"} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for getpagesize" >&5 +printf %s "checking for getpagesize... " >&6; } +if test ${ac_cv_func_getpagesize+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main (void) +{ +void *x=getpagesize + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_getpagesize=yes +else $as_nop + ac_cv_func_getpagesize=no fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext -CFLAGS=$save_CFLAGS -CPPFLAGS=$save_CPPFLAGS -LDFLAGS=$save_LDFLAGS -LIBS=$save_LIBS - +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_getpagesize" >&5 +printf "%s\n" "$ac_cv_func_getpagesize" >&6; } + if test "x$ac_cv_func_getpagesize" = xyes +then : +printf "%s\n" "#define HAVE_GETPAGESIZE 1" >>confdefs.h -elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } +fi - save_CFLAGS=$CFLAGS -save_CPPFLAGS=$CPPFLAGS -save_LDFLAGS=$LDFLAGS -save_LIBS=$LIBS - CPPFLAGS="$CPPFLAGS $LIBLZMA_CFLAGS" - LDFLAGS="$LDFLAGS $LIBLZMA_LIBS" - for ac_header in lzma.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "lzma.h" "ac_cv_header_lzma_h" "$ac_includes_default" -if test "x$ac_cv_header_lzma_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LZMA_H 1 -_ACEOF - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for lzma_easy_encoder in -llzma" >&5 -$as_echo_n "checking for lzma_easy_encoder in -llzma... " >&6; } -if ${ac_cv_lib_lzma_lzma_easy_encoder+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-llzma $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for broken unsetenv" >&5 +printf %s "checking for broken unsetenv... " >&6; } +if test ${ac_cv_broken_unsetenv+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char lzma_easy_encoder (); +#include int -main () +main (void) { -return lzma_easy_encoder (); +int res = unsetenv("DUMMY") ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_lzma_lzma_easy_encoder=yes -else - ac_cv_lib_lzma_lzma_easy_encoder=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lzma_lzma_easy_encoder" >&5 -$as_echo "$ac_cv_lib_lzma_lzma_easy_encoder" >&6; } -if test "x$ac_cv_lib_lzma_lzma_easy_encoder" = xyes; then : - have_liblzma=yes -else - have_liblzma=no -fi +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_broken_unsetenv=no +else $as_nop + ac_cv_broken_unsetenv=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext -else - have_liblzma=no fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_broken_unsetenv" >&5 +printf "%s\n" "$ac_cv_broken_unsetenv" >&6; } +if test "x$ac_cv_broken_unsetenv" = xyes +then : -done - if test "x$have_liblzma" = xyes; then : +printf "%s\n" "#define HAVE_BROKEN_UNSETENV 1" >>confdefs.h - LIBLZMA_CFLAGS=${LIBLZMA_CFLAGS-""} - LIBLZMA_LIBS=${LIBLZMA_LIBS-"-llzma"} fi -CFLAGS=$save_CFLAGS -CPPFLAGS=$save_CPPFLAGS -LDFLAGS=$save_LDFLAGS -LIBS=$save_LIBS - - - -else - LIBLZMA_CFLAGS=$pkg_cv_LIBLZMA_CFLAGS - LIBLZMA_LIBS=$pkg_cv_LIBLZMA_LIBS - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - have_liblzma=yes -fi +for ac_prog in true +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_TRUE+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$TRUE"; then + ac_cv_prog_TRUE="$TRUE" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_TRUE="$ac_prog" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS +fi +fi +TRUE=$ac_cv_prog_TRUE +if test -n "$TRUE"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $TRUE" >&5 +printf "%s\n" "$TRUE" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + test -n "$TRUE" && break +done +test -n "$TRUE" || TRUE="/bin/true" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for hstrerror" >&5 -$as_echo_n "checking for hstrerror... " >&6; } -if ${ac_cv_func_hstrerror+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for inet_aton in -lc" >&5 +printf %s "checking for inet_aton in -lc... " >&6; } +if test ${ac_cv_lib_c_inet_aton+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_check_lib_save_LIBS=$LIBS +LIBS="-lc $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char inet_aton (); int -main () +main (void) { -void *x=hstrerror +return inet_aton (); ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_func_hstrerror=yes -else - ac_cv_func_hstrerror=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_c_inet_aton=yes +else $as_nop + ac_cv_lib_c_inet_aton=no fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_hstrerror" >&5 -$as_echo "$ac_cv_func_hstrerror" >&6; } - if test "x$ac_cv_func_hstrerror" = xyes; then : - -$as_echo "#define HAVE_HSTRERROR 1" >>confdefs.h - +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS fi - - - - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getservbyname" >&5 -$as_echo_n "checking for getservbyname... " >&6; } -if ${ac_cv_func_getservbyname+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_c_inet_aton" >&5 +printf "%s\n" "$ac_cv_lib_c_inet_aton" >&6; } +if test "x$ac_cv_lib_c_inet_aton" = xyes +then : + $ac_cv_prog_TRUE +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for inet_aton in -lresolv" >&5 +printf %s "checking for inet_aton in -lresolv... " >&6; } +if test ${ac_cv_lib_resolv_inet_aton+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_check_lib_save_LIBS=$LIBS +LIBS="-lresolv $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char inet_aton (); int -main () +main (void) { -void *x=getservbyname +return inet_aton (); ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_func_getservbyname=yes -else - ac_cv_func_getservbyname=no +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_resolv_inet_aton=yes +else $as_nop + ac_cv_lib_resolv_inet_aton=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_getservbyname" >&5 -$as_echo "$ac_cv_func_getservbyname" >&6; } - if test "x$ac_cv_func_getservbyname" = xyes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_resolv_inet_aton" >&5 +printf "%s\n" "$ac_cv_lib_resolv_inet_aton" >&6; } +if test "x$ac_cv_lib_resolv_inet_aton" = xyes +then : + printf "%s\n" "#define HAVE_LIBRESOLV 1" >>confdefs.h -$as_echo "#define HAVE_GETSERVBYNAME 1" >>confdefs.h + LIBS="-lresolv $LIBS" fi +fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getservbyport" >&5 -$as_echo_n "checking for getservbyport... " >&6; } -if ${ac_cv_func_getservbyport+:} false; then : - $as_echo_n "(cached) " >&6 -else +# On Tru64, chflags seems to be present, but calling it will +# exit Python +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for chflags" >&5 +printf %s "checking for chflags... " >&6; } +if test ${ac_cv_have_chflags+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test "$cross_compiling" = yes +then : + ac_cv_have_chflags=cross +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include -int -main () + +#include +#include +int main(int argc, char *argv[]) { -void *x=getservbyport - ; + if(chflags(argv[0], 0) != 0) + return 1; return 0; } + _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_func_getservbyport=yes -else - ac_cv_func_getservbyport=no +if ac_fn_c_try_run "$LINENO" +then : + ac_cv_have_chflags=yes +else $as_nop + ac_cv_have_chflags=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_getservbyport" >&5 -$as_echo "$ac_cv_func_getservbyport" >&6; } - if test "x$ac_cv_func_getservbyport" = xyes; then : -$as_echo "#define HAVE_GETSERVBYPORT 1" >>confdefs.h +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_chflags" >&5 +printf "%s\n" "$ac_cv_have_chflags" >&6; } +if test "$ac_cv_have_chflags" = cross ; then + ac_fn_c_check_func "$LINENO" "chflags" "ac_cv_func_chflags" +if test "x$ac_cv_func_chflags" = xyes +then : + ac_cv_have_chflags="yes" +else $as_nop + ac_cv_have_chflags="no" fi +fi +if test "$ac_cv_have_chflags" = yes ; then +printf "%s\n" "#define HAVE_CHFLAGS 1" >>confdefs.h +fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname" >&5 -$as_echo_n "checking for gethostbyname... " >&6; } -if ${ac_cv_func_gethostbyname+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for lchflags" >&5 +printf %s "checking for lchflags... " >&6; } +if test ${ac_cv_have_lchflags+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test "$cross_compiling" = yes +then : + ac_cv_have_lchflags=cross +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include -int -main () + +#include +#include +int main(int argc, char *argv[]) { -void *x=gethostbyname - ; + if(lchflags(argv[0], 0) != 0) + return 1; return 0; } + _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_func_gethostbyname=yes -else - ac_cv_func_gethostbyname=no +if ac_fn_c_try_run "$LINENO" +then : + ac_cv_have_lchflags=yes +else $as_nop + ac_cv_have_lchflags=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_lchflags" >&5 +printf "%s\n" "$ac_cv_have_lchflags" >&6; } +if test "$ac_cv_have_lchflags" = cross ; then + ac_fn_c_check_func "$LINENO" "lchflags" "ac_cv_func_lchflags" +if test "x$ac_cv_func_lchflags" = xyes +then : + ac_cv_have_lchflags="yes" +else $as_nop + ac_cv_have_lchflags="no" fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_gethostbyname" >&5 -$as_echo "$ac_cv_func_gethostbyname" >&6; } - if test "x$ac_cv_func_gethostbyname" = xyes; then : +if test "$ac_cv_have_lchflags" = yes ; then -$as_echo "#define HAVE_GETHOSTBYNAME 1" >>confdefs.h +printf "%s\n" "#define HAVE_LCHFLAGS 1" >>confdefs.h fi @@ -17117,35 +19685,12 @@ fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyaddr" >&5 -$as_echo_n "checking for gethostbyaddr... " >&6; } -if ${ac_cv_func_gethostbyaddr+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -int -main () -{ -void *x=gethostbyaddr - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_func_gethostbyaddr=yes -else - ac_cv_func_gethostbyaddr=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_gethostbyaddr" >&5 -$as_echo "$ac_cv_func_gethostbyaddr" >&6; } - if test "x$ac_cv_func_gethostbyaddr" = xyes; then : + if test "$ac_sys_system" = "Emscripten" -a -z "$ZLIB_CFLAGS" -a -z "$ZLIB_LIBS" +then : -$as_echo "#define HAVE_GETHOSTBYADDR 1" >>confdefs.h + ZLIB_CFLAGS="-sUSE_ZLIB" + ZLIB_LIBS="-sUSE_ZLIB" fi @@ -17153,489 +19698,845 @@ fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getprotobyname" >&5 -$as_echo_n "checking for getprotobyname... " >&6; } -if ${ac_cv_func_getprotobyname+:} false; then : - $as_echo_n "(cached) " >&6 +pkg_failed=no +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ZLIB" >&5 +printf %s "checking for ZLIB... " >&6; } + +if test -n "$ZLIB_CFLAGS"; then + pkg_cv_ZLIB_CFLAGS="$ZLIB_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"zlib >= 1.2.0\""; } >&5 + ($PKG_CONFIG --exists --print-errors "zlib >= 1.2.0") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_ZLIB_CFLAGS=`$PKG_CONFIG --cflags "zlib >= 1.2.0" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -int -main () -{ -void *x=getprotobyname - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_func_getprotobyname=yes + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$ZLIB_LIBS"; then + pkg_cv_ZLIB_LIBS="$ZLIB_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"zlib >= 1.2.0\""; } >&5 + ($PKG_CONFIG --exists --print-errors "zlib >= 1.2.0") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_ZLIB_LIBS=`$PKG_CONFIG --libs "zlib >= 1.2.0" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes else - ac_cv_func_getprotobyname=no + pkg_failed=yes fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - + else + pkg_failed=untried fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_getprotobyname" >&5 -$as_echo "$ac_cv_func_getprotobyname" >&6; } - if test "x$ac_cv_func_getprotobyname" = xyes; then : -$as_echo "#define HAVE_GETPROTOBYNAME 1" >>confdefs.h - -fi +if test $pkg_failed = yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + ZLIB_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "zlib >= 1.2.0" 2>&1` + else + ZLIB_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "zlib >= 1.2.0" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$ZLIB_PKG_ERRORS" >&5 + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + CPPFLAGS="$CPPFLAGS $ZLIB_CFLAGS" + LDFLAGS="$LDFLAGS $ZLIB_LIBS" + for ac_header in zlib.h +do : + ac_fn_c_check_header_compile "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default" +if test "x$ac_cv_header_zlib_h" = xyes +then : + printf "%s\n" "#define HAVE_ZLIB_H 1" >>confdefs.h - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_aton" >&5 -$as_echo_n "checking for inet_aton... " >&6; } -if ${ac_cv_func_inet_aton+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + py_check_lib_save_LIBS=$LIBS +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gzread in -lz" >&5 +printf %s "checking for gzread in -lz... " >&6; } +if test ${ac_cv_lib_z_gzread+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_check_lib_save_LIBS=$LIBS +LIBS="-lz $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include -#include -#include -#include - +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char gzread (); int -main () +main (void) { -void *x=inet_aton +return gzread (); ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_func_inet_aton=yes -else - ac_cv_func_inet_aton=no +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_z_gzread=yes +else $as_nop + ac_cv_lib_z_gzread=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_inet_aton" >&5 -$as_echo "$ac_cv_func_inet_aton" >&6; } - if test "x$ac_cv_func_inet_aton" = xyes; then : - -$as_echo "#define HAVE_INET_ATON 1" >>confdefs.h - +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_gzread" >&5 +printf "%s\n" "$ac_cv_lib_z_gzread" >&6; } +if test "x$ac_cv_lib_z_gzread" = xyes +then : + have_zlib=yes +else $as_nop + have_zlib=no fi +LIBS=$py_check_lib_save_LIBS +else $as_nop + have_zlib=no +fi +done + if test "x$have_zlib" = xyes +then : - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_ntoa" >&5 -$as_echo_n "checking for inet_ntoa... " >&6; } -if ${ac_cv_func_inet_ntoa+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + ZLIB_CFLAGS=${ZLIB_CFLAGS-""} + ZLIB_LIBS=${ZLIB_LIBS-"-lz"} + py_check_lib_save_LIBS=$LIBS +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for inflateCopy in -lz" >&5 +printf %s "checking for inflateCopy in -lz... " >&6; } +if test ${ac_cv_lib_z_inflateCopy+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_check_lib_save_LIBS=$LIBS +LIBS="-lz $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include -#include -#include -#include - +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char inflateCopy (); int -main () +main (void) { -void *x=inet_ntoa +return inflateCopy (); ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_func_inet_ntoa=yes -else - ac_cv_func_inet_ntoa=no +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_z_inflateCopy=yes +else $as_nop + ac_cv_lib_z_inflateCopy=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_inflateCopy" >&5 +printf "%s\n" "$ac_cv_lib_z_inflateCopy" >&6; } +if test "x$ac_cv_lib_z_inflateCopy" = xyes +then : + printf "%s\n" "#define HAVE_ZLIB_COPY 1" >>confdefs.h fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_inet_ntoa" >&5 -$as_echo "$ac_cv_func_inet_ntoa" >&6; } - if test "x$ac_cv_func_inet_ntoa" = xyes; then : -$as_echo "#define HAVE_INET_NTOA 1" >>confdefs.h +LIBS=$py_check_lib_save_LIBS + fi +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS +elif test $pkg_failed = untried; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_pton" >&5 -$as_echo_n "checking for inet_pton... " >&6; } -if ${ac_cv_func_inet_pton+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS -#include -#include -#include -#include + CPPFLAGS="$CPPFLAGS $ZLIB_CFLAGS" + LDFLAGS="$LDFLAGS $ZLIB_LIBS" + for ac_header in zlib.h +do : + ac_fn_c_check_header_compile "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default" +if test "x$ac_cv_header_zlib_h" = xyes +then : + printf "%s\n" "#define HAVE_ZLIB_H 1" >>confdefs.h + + py_check_lib_save_LIBS=$LIBS +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gzread in -lz" >&5 +printf %s "checking for gzread in -lz... " >&6; } +if test ${ac_cv_lib_z_gzread+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_check_lib_save_LIBS=$LIBS +LIBS="-lz $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char gzread (); int -main () +main (void) { -void *x=inet_pton +return gzread (); ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_func_inet_pton=yes -else - ac_cv_func_inet_pton=no +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_z_gzread=yes +else $as_nop + ac_cv_lib_z_gzread=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_inet_pton" >&5 -$as_echo "$ac_cv_func_inet_pton" >&6; } - if test "x$ac_cv_func_inet_pton" = xyes; then : - -$as_echo "#define HAVE_INET_PTON 1" >>confdefs.h - +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_gzread" >&5 +printf "%s\n" "$ac_cv_lib_z_gzread" >&6; } +if test "x$ac_cv_lib_z_gzread" = xyes +then : + have_zlib=yes +else $as_nop + have_zlib=no fi +LIBS=$py_check_lib_save_LIBS +else $as_nop + have_zlib=no +fi +done + if test "x$have_zlib" = xyes +then : - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getpeername" >&5 -$as_echo_n "checking for getpeername... " >&6; } -if ${ac_cv_func_getpeername+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + ZLIB_CFLAGS=${ZLIB_CFLAGS-""} + ZLIB_LIBS=${ZLIB_LIBS-"-lz"} + py_check_lib_save_LIBS=$LIBS +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for inflateCopy in -lz" >&5 +printf %s "checking for inflateCopy in -lz... " >&6; } +if test ${ac_cv_lib_z_inflateCopy+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_check_lib_save_LIBS=$LIBS +LIBS="-lz $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include -#include -#include -#include - +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char inflateCopy (); int -main () +main (void) { -void *x=getpeername +return inflateCopy (); ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_func_getpeername=yes -else - ac_cv_func_getpeername=no +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_z_inflateCopy=yes +else $as_nop + ac_cv_lib_z_inflateCopy=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_inflateCopy" >&5 +printf "%s\n" "$ac_cv_lib_z_inflateCopy" >&6; } +if test "x$ac_cv_lib_z_inflateCopy" = xyes +then : + printf "%s\n" "#define HAVE_ZLIB_COPY 1" >>confdefs.h fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_getpeername" >&5 -$as_echo "$ac_cv_func_getpeername" >&6; } - if test "x$ac_cv_func_getpeername" = xyes; then : -$as_echo "#define HAVE_GETPEERNAME 1" >>confdefs.h +LIBS=$py_check_lib_save_LIBS + fi +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getsockname" >&5 -$as_echo_n "checking for getsockname... " >&6; } -if ${ac_cv_func_getsockname+:} false; then : - $as_echo_n "(cached) " >&6 else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ + ZLIB_CFLAGS=$pkg_cv_ZLIB_CFLAGS + ZLIB_LIBS=$pkg_cv_ZLIB_LIBS + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } -#include -#include -#include -#include + have_zlib=yes + printf "%s\n" "#define HAVE_ZLIB_COPY 1" >>confdefs.h -int -main () -{ -void *x=getsockname - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_func_getsockname=yes -else - ac_cv_func_getsockname=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_getsockname" >&5 -$as_echo "$ac_cv_func_getsockname" >&6; } - if test "x$ac_cv_func_getsockname" = xyes; then : -$as_echo "#define HAVE_GETSOCKNAME 1" >>confdefs.h +if test "x$have_zlib" = xyes +then : + + BINASCII_CFLAGS="-DUSE_ZLIB_CRC32 $ZLIB_CFLAGS" + BINASCII_LIBS="$ZLIB_LIBS" fi + if test "$ac_sys_system" = "Emscripten" -a -z "$BZIP2_CFLAGS" -a -z "$BZIP2_LIBS" +then : - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for accept" >&5 -$as_echo_n "checking for accept... " >&6; } -if ${ac_cv_func_accept+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ + BZIP2_CFLAGS="-sUSE_BZIP2" + BZIP2_LIBS="-sUSE_BZIP2" -#include -#include -#include -#include +fi -int -main () -{ -void *x=accept - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_func_accept=yes + + + + +pkg_failed=no +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for BZIP2" >&5 +printf %s "checking for BZIP2... " >&6; } + +if test -n "$BZIP2_CFLAGS"; then + pkg_cv_BZIP2_CFLAGS="$BZIP2_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"bzip2\""; } >&5 + ($PKG_CONFIG --exists --print-errors "bzip2") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_BZIP2_CFLAGS=`$PKG_CONFIG --cflags "bzip2" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes else - ac_cv_func_accept=no + pkg_failed=yes fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - + else + pkg_failed=untried +fi +if test -n "$BZIP2_LIBS"; then + pkg_cv_BZIP2_LIBS="$BZIP2_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"bzip2\""; } >&5 + ($PKG_CONFIG --exists --print-errors "bzip2") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_BZIP2_LIBS=`$PKG_CONFIG --libs "bzip2" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_accept" >&5 -$as_echo "$ac_cv_func_accept" >&6; } - if test "x$ac_cv_func_accept" = xyes; then : -$as_echo "#define HAVE_ACCEPT 1" >>confdefs.h -fi +if test $pkg_failed = yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + BZIP2_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "bzip2" 2>&1` + else + BZIP2_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "bzip2" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$BZIP2_PKG_ERRORS" >&5 + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for bind" >&5 -$as_echo_n "checking for bind... " >&6; } -if ${ac_cv_func_bind+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include -#include -#include + CPPFLAGS="$CPPFLAGS $BZIP2_CFLAGS" + LDFLAGS="$LDFLAGS $BZIP2_LIBS" + for ac_header in bzlib.h +do : + ac_fn_c_check_header_compile "$LINENO" "bzlib.h" "ac_cv_header_bzlib_h" "$ac_includes_default" +if test "x$ac_cv_header_bzlib_h" = xyes +then : + printf "%s\n" "#define HAVE_BZLIB_H 1" >>confdefs.h + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for BZ2_bzCompress in -lbz2" >&5 +printf %s "checking for BZ2_bzCompress in -lbz2... " >&6; } +if test ${ac_cv_lib_bz2_BZ2_bzCompress+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_check_lib_save_LIBS=$LIBS +LIBS="-lbz2 $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char BZ2_bzCompress (); int -main () +main (void) { -void *x=bind +return BZ2_bzCompress (); ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_func_bind=yes -else - ac_cv_func_bind=no +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_bz2_BZ2_bzCompress=yes +else $as_nop + ac_cv_lib_bz2_BZ2_bzCompress=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bz2_BZ2_bzCompress" >&5 +printf "%s\n" "$ac_cv_lib_bz2_BZ2_bzCompress" >&6; } +if test "x$ac_cv_lib_bz2_BZ2_bzCompress" = xyes +then : + have_bzip2=yes +else $as_nop + have_bzip2=no fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_bind" >&5 -$as_echo "$ac_cv_func_bind" >&6; } - if test "x$ac_cv_func_bind" = xyes; then : -$as_echo "#define HAVE_BIND 1" >>confdefs.h +else $as_nop + have_bzip2=no fi +done + if test "x$have_bzip2" = xyes +then : + BZIP2_CFLAGS=${BZIP2_CFLAGS-""} + BZIP2_LIBS=${BZIP2_LIBS-"-lbz2"} +fi +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for connect" >&5 -$as_echo_n "checking for connect... " >&6; } -if ${ac_cv_func_connect+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include -#include -#include +elif test $pkg_failed = untried; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + CPPFLAGS="$CPPFLAGS $BZIP2_CFLAGS" + LDFLAGS="$LDFLAGS $BZIP2_LIBS" + for ac_header in bzlib.h +do : + ac_fn_c_check_header_compile "$LINENO" "bzlib.h" "ac_cv_header_bzlib_h" "$ac_includes_default" +if test "x$ac_cv_header_bzlib_h" = xyes +then : + printf "%s\n" "#define HAVE_BZLIB_H 1" >>confdefs.h + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for BZ2_bzCompress in -lbz2" >&5 +printf %s "checking for BZ2_bzCompress in -lbz2... " >&6; } +if test ${ac_cv_lib_bz2_BZ2_bzCompress+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_check_lib_save_LIBS=$LIBS +LIBS="-lbz2 $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char BZ2_bzCompress (); int -main () +main (void) { -void *x=connect +return BZ2_bzCompress (); ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_func_connect=yes -else - ac_cv_func_connect=no +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_bz2_BZ2_bzCompress=yes +else $as_nop + ac_cv_lib_bz2_BZ2_bzCompress=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bz2_BZ2_bzCompress" >&5 +printf "%s\n" "$ac_cv_lib_bz2_BZ2_bzCompress" >&6; } +if test "x$ac_cv_lib_bz2_BZ2_bzCompress" = xyes +then : + have_bzip2=yes +else $as_nop + have_bzip2=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +else $as_nop + have_bzip2=no fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_connect" >&5 -$as_echo "$ac_cv_func_connect" >&6; } - if test "x$ac_cv_func_connect" = xyes; then : -$as_echo "#define HAVE_CONNECT 1" >>confdefs.h +done + if test "x$have_bzip2" = xyes +then : + + BZIP2_CFLAGS=${BZIP2_CFLAGS-""} + BZIP2_LIBS=${BZIP2_LIBS-"-lbz2"} fi +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + +else + BZIP2_CFLAGS=$pkg_cv_BZIP2_CFLAGS + BZIP2_LIBS=$pkg_cv_BZIP2_LIBS + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + have_bzip2=yes +fi +pkg_failed=no +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for LIBLZMA" >&5 +printf %s "checking for LIBLZMA... " >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for listen" >&5 -$as_echo_n "checking for listen... " >&6; } -if ${ac_cv_func_listen+:} false; then : - $as_echo_n "(cached) " >&6 +if test -n "$LIBLZMA_CFLAGS"; then + pkg_cv_LIBLZMA_CFLAGS="$LIBLZMA_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblzma\""; } >&5 + ($PKG_CONFIG --exists --print-errors "liblzma") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBLZMA_CFLAGS=`$PKG_CONFIG --cflags "liblzma" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$LIBLZMA_LIBS"; then + pkg_cv_LIBLZMA_LIBS="$LIBLZMA_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"liblzma\""; } >&5 + ($PKG_CONFIG --exists --print-errors "liblzma") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBLZMA_LIBS=`$PKG_CONFIG --libs "liblzma" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + LIBLZMA_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "liblzma" 2>&1` + else + LIBLZMA_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "liblzma" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LIBLZMA_PKG_ERRORS" >&5 + + + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS -#include -#include -#include -#include + CPPFLAGS="$CPPFLAGS $LIBLZMA_CFLAGS" + LDFLAGS="$LDFLAGS $LIBLZMA_LIBS" + for ac_header in lzma.h +do : + ac_fn_c_check_header_compile "$LINENO" "lzma.h" "ac_cv_header_lzma_h" "$ac_includes_default" +if test "x$ac_cv_header_lzma_h" = xyes +then : + printf "%s\n" "#define HAVE_LZMA_H 1" >>confdefs.h + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for lzma_easy_encoder in -llzma" >&5 +printf %s "checking for lzma_easy_encoder in -llzma... " >&6; } +if test ${ac_cv_lib_lzma_lzma_easy_encoder+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_check_lib_save_LIBS=$LIBS +LIBS="-llzma $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char lzma_easy_encoder (); int -main () +main (void) { -void *x=listen +return lzma_easy_encoder (); ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_func_listen=yes -else - ac_cv_func_listen=no +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_lzma_lzma_easy_encoder=yes +else $as_nop + ac_cv_lib_lzma_lzma_easy_encoder=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lzma_lzma_easy_encoder" >&5 +printf "%s\n" "$ac_cv_lib_lzma_lzma_easy_encoder" >&6; } +if test "x$ac_cv_lib_lzma_lzma_easy_encoder" = xyes +then : + have_liblzma=yes +else $as_nop + have_liblzma=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +else $as_nop + have_liblzma=no fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_listen" >&5 -$as_echo "$ac_cv_func_listen" >&6; } - if test "x$ac_cv_func_listen" = xyes; then : -$as_echo "#define HAVE_LISTEN 1" >>confdefs.h +done + if test "x$have_liblzma" = xyes +then : + + LIBLZMA_CFLAGS=${LIBLZMA_CFLAGS-""} + LIBLZMA_LIBS=${LIBLZMA_LIBS-"-llzma"} fi +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + +elif test $pkg_failed = untried; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for recvfrom" >&5 -$as_echo_n "checking for recvfrom... " >&6; } -if ${ac_cv_func_recvfrom+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include -#include -#include + CPPFLAGS="$CPPFLAGS $LIBLZMA_CFLAGS" + LDFLAGS="$LDFLAGS $LIBLZMA_LIBS" + for ac_header in lzma.h +do : + ac_fn_c_check_header_compile "$LINENO" "lzma.h" "ac_cv_header_lzma_h" "$ac_includes_default" +if test "x$ac_cv_header_lzma_h" = xyes +then : + printf "%s\n" "#define HAVE_LZMA_H 1" >>confdefs.h + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for lzma_easy_encoder in -llzma" >&5 +printf %s "checking for lzma_easy_encoder in -llzma... " >&6; } +if test ${ac_cv_lib_lzma_lzma_easy_encoder+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_check_lib_save_LIBS=$LIBS +LIBS="-llzma $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char lzma_easy_encoder (); int -main () +main (void) { -void *x=recvfrom +return lzma_easy_encoder (); ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_func_recvfrom=yes -else - ac_cv_func_recvfrom=no +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_lzma_lzma_easy_encoder=yes +else $as_nop + ac_cv_lib_lzma_lzma_easy_encoder=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lzma_lzma_easy_encoder" >&5 +printf "%s\n" "$ac_cv_lib_lzma_lzma_easy_encoder" >&6; } +if test "x$ac_cv_lib_lzma_lzma_easy_encoder" = xyes +then : + have_liblzma=yes +else $as_nop + have_liblzma=no fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_recvfrom" >&5 -$as_echo "$ac_cv_func_recvfrom" >&6; } - if test "x$ac_cv_func_recvfrom" = xyes; then : -$as_echo "#define HAVE_RECVFROM 1" >>confdefs.h +else $as_nop + have_liblzma=no fi +done + if test "x$have_liblzma" = xyes +then : + + LIBLZMA_CFLAGS=${LIBLZMA_CFLAGS-""} + LIBLZMA_LIBS=${LIBLZMA_LIBS-"-llzma"} + +fi +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sendto" >&5 -$as_echo_n "checking for sendto... " >&6; } -if ${ac_cv_func_sendto+:} false; then : - $as_echo_n "(cached) " >&6 else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ + LIBLZMA_CFLAGS=$pkg_cv_LIBLZMA_CFLAGS + LIBLZMA_LIBS=$pkg_cv_LIBLZMA_LIBS + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + have_liblzma=yes +fi + + + -#include -#include -#include -#include + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for hstrerror" >&5 +printf %s "checking for hstrerror... " >&6; } +if test ${ac_cv_func_hstrerror+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include int -main () +main (void) { -void *x=sendto +void *x=hstrerror ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_func_sendto=yes -else - ac_cv_func_sendto=no +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_hstrerror=yes +else $as_nop + ac_cv_func_hstrerror=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_sendto" >&5 -$as_echo "$ac_cv_func_sendto" >&6; } - if test "x$ac_cv_func_sendto" = xyes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_hstrerror" >&5 +printf "%s\n" "$ac_cv_func_hstrerror" >&6; } + if test "x$ac_cv_func_hstrerror" = xyes +then : -$as_echo "#define HAVE_SENDTO 1" >>confdefs.h +printf "%s\n" "#define HAVE_HSTRERROR 1" >>confdefs.h fi @@ -17643,40 +20544,38 @@ fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for setsockopt" >&5 -$as_echo_n "checking for setsockopt... " >&6; } -if ${ac_cv_func_setsockopt+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for getservbyname" >&5 +printf %s "checking for getservbyname... " >&6; } +if test ${ac_cv_func_getservbyname+y} +then : + printf %s "(cached) " >&6 +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - -#include -#include -#include -#include - +#include int -main () +main (void) { -void *x=setsockopt +void *x=getservbyname ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_func_setsockopt=yes -else - ac_cv_func_setsockopt=no +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_getservbyname=yes +else $as_nop + ac_cv_func_getservbyname=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_setsockopt" >&5 -$as_echo "$ac_cv_func_setsockopt" >&6; } - if test "x$ac_cv_func_setsockopt" = xyes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_getservbyname" >&5 +printf "%s\n" "$ac_cv_func_getservbyname" >&6; } + if test "x$ac_cv_func_getservbyname" = xyes +then : -$as_echo "#define HAVE_SETSOCKOPT 1" >>confdefs.h +printf "%s\n" "#define HAVE_GETSERVBYNAME 1" >>confdefs.h fi @@ -17684,2772 +20583,3489 @@ fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for socket" >&5 -$as_echo_n "checking for socket... " >&6; } -if ${ac_cv_func_socket+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for getservbyport" >&5 +printf %s "checking for getservbyport... " >&6; } +if test ${ac_cv_func_getservbyport+y} +then : + printf %s "(cached) " >&6 +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - -#include -#include -#include -#include - +#include int -main () +main (void) { -void *x=socket +void *x=getservbyport ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_func_socket=yes -else - ac_cv_func_socket=no +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_getservbyport=yes +else $as_nop + ac_cv_func_getservbyport=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_socket" >&5 -$as_echo "$ac_cv_func_socket" >&6; } - if test "x$ac_cv_func_socket" = xyes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_getservbyport" >&5 +printf "%s\n" "$ac_cv_func_getservbyport" >&6; } + if test "x$ac_cv_func_getservbyport" = xyes +then : -$as_echo "#define HAVE_SOCKET 1" >>confdefs.h +printf "%s\n" "#define HAVE_GETSERVBYPORT 1" >>confdefs.h fi -# On some systems, setgroups is in unistd.h, on others, in grp.h - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for setgroups" >&5 -$as_echo_n "checking for setgroups... " >&6; } -if ${ac_cv_func_setgroups+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gethostbyname" >&5 +printf %s "checking for gethostbyname... " >&6; } +if test ${ac_cv_func_gethostbyname+y} +then : + printf %s "(cached) " >&6 +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - -#include -#ifdef HAVE_GRP_H -#include -#endif - +#include int -main () +main (void) { -void *x=setgroups +void *x=gethostbyname ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_func_setgroups=yes -else - ac_cv_func_setgroups=no +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_gethostbyname=yes +else $as_nop + ac_cv_func_gethostbyname=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_setgroups" >&5 -$as_echo "$ac_cv_func_setgroups" >&6; } - if test "x$ac_cv_func_setgroups" = xyes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_gethostbyname" >&5 +printf "%s\n" "$ac_cv_func_gethostbyname" >&6; } + if test "x$ac_cv_func_gethostbyname" = xyes +then : -$as_echo "#define HAVE_SETGROUPS 1" >>confdefs.h +printf "%s\n" "#define HAVE_GETHOSTBYNAME 1" >>confdefs.h fi -# check for openpty, login_tty, and forkpty - -for ac_func in openpty -do : - ac_fn_c_check_func "$LINENO" "openpty" "ac_cv_func_openpty" -if test "x$ac_cv_func_openpty" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_OPENPTY 1 -_ACEOF -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for openpty in -lutil" >&5 -$as_echo_n "checking for openpty in -lutil... " >&6; } -if ${ac_cv_lib_util_openpty+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lutil $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gethostbyaddr" >&5 +printf %s "checking for gethostbyaddr... " >&6; } +if test ${ac_cv_func_gethostbyaddr+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char openpty (); +#include int -main () +main (void) { -return openpty (); +void *x=gethostbyaddr ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_util_openpty=yes -else - ac_cv_lib_util_openpty=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_gethostbyaddr=yes +else $as_nop + ac_cv_func_gethostbyaddr=no fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_util_openpty" >&5 -$as_echo "$ac_cv_lib_util_openpty" >&6; } -if test "x$ac_cv_lib_util_openpty" = xyes; then : - $as_echo "#define HAVE_OPENPTY 1" >>confdefs.h - LIBS="$LIBS -lutil" -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for openpty in -lbsd" >&5 -$as_echo_n "checking for openpty in -lbsd... " >&6; } -if ${ac_cv_lib_bsd_openpty+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lbsd $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char openpty (); -int -main () -{ -return openpty (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_bsd_openpty=yes -else - ac_cv_lib_bsd_openpty=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bsd_openpty" >&5 -$as_echo "$ac_cv_lib_bsd_openpty" >&6; } -if test "x$ac_cv_lib_bsd_openpty" = xyes; then : - $as_echo "#define HAVE_OPENPTY 1" >>confdefs.h - LIBS="$LIBS -lbsd" fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_gethostbyaddr" >&5 +printf "%s\n" "$ac_cv_func_gethostbyaddr" >&6; } + if test "x$ac_cv_func_gethostbyaddr" = xyes +then : +printf "%s\n" "#define HAVE_GETHOSTBYADDR 1" >>confdefs.h fi -fi -done -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing login_tty" >&5 -$as_echo_n "checking for library containing login_tty... " >&6; } -if ${ac_cv_search_login_tty+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_func_search_save_LIBS=$LIBS -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char login_tty (); + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for getprotobyname" >&5 +printf %s "checking for getprotobyname... " >&6; } +if test ${ac_cv_func_getprotobyname+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include int -main () +main (void) { -return login_tty (); +void *x=getprotobyname ; return 0; } _ACEOF -for ac_lib in '' util; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - if ac_fn_c_try_link "$LINENO"; then : - ac_cv_search_login_tty=$ac_res -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext - if ${ac_cv_search_login_tty+:} false; then : - break +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_getprotobyname=yes +else $as_nop + ac_cv_func_getprotobyname=no fi -done -if ${ac_cv_search_login_tty+:} false; then : +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext -else - ac_cv_search_login_tty=no fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_getprotobyname" >&5 +printf "%s\n" "$ac_cv_func_getprotobyname" >&6; } + if test "x$ac_cv_func_getprotobyname" = xyes +then : + +printf "%s\n" "#define HAVE_GETPROTOBYNAME 1" >>confdefs.h + fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_login_tty" >&5 -$as_echo "$ac_cv_search_login_tty" >&6; } -ac_res=$ac_cv_search_login_tty -if test "$ac_res" != no; then : - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" -$as_echo "#define HAVE_LOGIN_TTY 1" >>confdefs.h -fi -for ac_func in forkpty -do : - ac_fn_c_check_func "$LINENO" "forkpty" "ac_cv_func_forkpty" -if test "x$ac_cv_func_forkpty" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_FORKPTY 1 -_ACEOF -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for forkpty in -lutil" >&5 -$as_echo_n "checking for forkpty in -lutil... " >&6; } -if ${ac_cv_lib_util_forkpty+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lutil $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for inet_aton" >&5 +printf %s "checking for inet_aton... " >&6; } +if test ${ac_cv_func_inet_aton+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char forkpty (); +#include +#include +#include +#include + int -main () +main (void) { -return forkpty (); +void *x=inet_aton ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_util_forkpty=yes -else - ac_cv_lib_util_forkpty=no +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_inet_aton=yes +else $as_nop + ac_cv_func_inet_aton=no fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_util_forkpty" >&5 -$as_echo "$ac_cv_lib_util_forkpty" >&6; } -if test "x$ac_cv_lib_util_forkpty" = xyes; then : - $as_echo "#define HAVE_FORKPTY 1" >>confdefs.h - LIBS="$LIBS -lutil" -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for forkpty in -lbsd" >&5 -$as_echo_n "checking for forkpty in -lbsd... " >&6; } -if ${ac_cv_lib_bsd_forkpty+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lbsd $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_inet_aton" >&5 +printf "%s\n" "$ac_cv_func_inet_aton" >&6; } + if test "x$ac_cv_func_inet_aton" = xyes +then : + +printf "%s\n" "#define HAVE_INET_ATON 1" >>confdefs.h + +fi + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for inet_ntoa" >&5 +printf %s "checking for inet_ntoa... " >&6; } +if test ${ac_cv_func_inet_ntoa+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char forkpty (); +#include +#include +#include +#include + int -main () +main (void) { -return forkpty (); +void *x=inet_ntoa ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_bsd_forkpty=yes -else - ac_cv_lib_bsd_forkpty=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bsd_forkpty" >&5 -$as_echo "$ac_cv_lib_bsd_forkpty" >&6; } -if test "x$ac_cv_lib_bsd_forkpty" = xyes; then : - $as_echo "#define HAVE_FORKPTY 1" >>confdefs.h - LIBS="$LIBS -lbsd" +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_inet_ntoa=yes +else $as_nop + ac_cv_func_inet_ntoa=no fi - +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_inet_ntoa" >&5 +printf "%s\n" "$ac_cv_func_inet_ntoa" >&6; } + if test "x$ac_cv_func_inet_ntoa" = xyes +then : +printf "%s\n" "#define HAVE_INET_NTOA 1" >>confdefs.h fi -done - - -# check for long file support functions -for ac_func in fseek64 fseeko fstatvfs ftell64 ftello statvfs -do : - as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` -ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -if eval test \"x\$"$as_ac_var"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF -fi -done -ac_fn_c_check_func "$LINENO" "dup2" "ac_cv_func_dup2" -if test "x$ac_cv_func_dup2" = xyes; then : - $as_echo "#define HAVE_DUP2 1" >>confdefs.h -else - case " $LIBOBJS " in - *" dup2.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS dup2.$ac_objext" - ;; -esac -fi + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for inet_pton" >&5 +printf %s "checking for inet_pton... " >&6; } +if test ${ac_cv_func_inet_pton+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include -for ac_func in getpgrp -do : - ac_fn_c_check_func "$LINENO" "getpgrp" "ac_cv_func_getpgrp" -if test "x$ac_cv_func_getpgrp" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_GETPGRP 1 -_ACEOF - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include int -main () +main (void) { -getpgrp(0); +void *x=inet_pton ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - -$as_echo "#define GETPGRP_HAVE_ARG 1" >>confdefs.h +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_inet_pton=yes +else $as_nop + ac_cv_func_inet_pton=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_inet_pton" >&5 +printf "%s\n" "$ac_cv_func_inet_pton" >&6; } + if test "x$ac_cv_func_inet_pton" = xyes +then : + +printf "%s\n" "#define HAVE_INET_PTON 1" >>confdefs.h fi -done -for ac_func in setpgrp -do : - ac_fn_c_check_func "$LINENO" "setpgrp" "ac_cv_func_setpgrp" -if test "x$ac_cv_func_setpgrp" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_SETPGRP 1 -_ACEOF - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for getpeername" >&5 +printf %s "checking for getpeername... " >&6; } +if test ${ac_cv_func_getpeername+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include + +#include +#include +#include +#include + int -main () +main (void) { -setpgrp(0,0); +void *x=getpeername ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - -$as_echo "#define SETPGRP_HAVE_ARG 1" >>confdefs.h +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_getpeername=yes +else $as_nop + ac_cv_func_getpeername=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_getpeername" >&5 +printf "%s\n" "$ac_cv_func_getpeername" >&6; } + if test "x$ac_cv_func_getpeername" = xyes +then : + +printf "%s\n" "#define HAVE_GETPEERNAME 1" >>confdefs.h fi -done -pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBCRYPT" >&5 -$as_echo_n "checking for LIBCRYPT... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for getsockname" >&5 +printf %s "checking for getsockname... " >&6; } +if test ${ac_cv_func_getsockname+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ -if test -n "$LIBCRYPT_CFLAGS"; then - pkg_cv_LIBCRYPT_CFLAGS="$LIBCRYPT_CFLAGS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libxcrypt >= 3.1.1\""; } >&5 - ($PKG_CONFIG --exists --print-errors "libxcrypt >= 3.1.1") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_LIBCRYPT_CFLAGS=`$PKG_CONFIG --cflags "libxcrypt >= 3.1.1" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi -if test -n "$LIBCRYPT_LIBS"; then - pkg_cv_LIBCRYPT_LIBS="$LIBCRYPT_LIBS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libxcrypt >= 3.1.1\""; } >&5 - ($PKG_CONFIG --exists --print-errors "libxcrypt >= 3.1.1") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_LIBCRYPT_LIBS=`$PKG_CONFIG --libs "libxcrypt >= 3.1.1" 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi +#include +#include +#include +#include +int +main (void) +{ +void *x=getsockname + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_getsockname=yes +else $as_nop + ac_cv_func_getsockname=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_getsockname" >&5 +printf "%s\n" "$ac_cv_func_getsockname" >&6; } + if test "x$ac_cv_func_getsockname" = xyes +then : -if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } +printf "%s\n" "#define HAVE_GETSOCKNAME 1" >>confdefs.h -if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then - _pkg_short_errors_supported=yes -else - _pkg_short_errors_supported=no fi - if test $_pkg_short_errors_supported = yes; then - LIBCRYPT_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libxcrypt >= 3.1.1" 2>&1` - else - LIBCRYPT_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libxcrypt >= 3.1.1" 2>&1` - fi - # Put the nasty error message in config.log where it belongs - echo "$LIBCRYPT_PKG_ERRORS" >&5 - save_CFLAGS=$CFLAGS -save_CPPFLAGS=$CPPFLAGS -save_LDFLAGS=$LDFLAGS -save_LIBS=$LIBS - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing crypt_r" >&5 -$as_echo_n "checking for library containing crypt_r... " >&6; } -if ${ac_cv_search_crypt_r+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_func_search_save_LIBS=$LIBS -cat confdefs.h - <<_ACEOF >conftest.$ac_ext + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for accept" >&5 +printf %s "checking for accept... " >&6; } +if test ${ac_cv_func_accept+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char crypt_r (); +#include +#include +#include +#include + int -main () +main (void) { -return crypt_r (); +void *x=accept ; return 0; } _ACEOF -for ac_lib in '' crypt; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - if ac_fn_c_try_link "$LINENO"; then : - ac_cv_search_crypt_r=$ac_res -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext - if ${ac_cv_search_crypt_r+:} false; then : - break +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_accept=yes +else $as_nop + ac_cv_func_accept=no fi -done -if ${ac_cv_search_crypt_r+:} false; then : +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext -else - ac_cv_search_crypt_r=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_crypt_r" >&5 -$as_echo "$ac_cv_search_crypt_r" >&6; } -ac_res=$ac_cv_search_crypt_r -if test "$ac_res" != no; then : - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_accept" >&5 +printf "%s\n" "$ac_cv_func_accept" >&6; } + if test "x$ac_cv_func_accept" = xyes +then : - $as_echo "#define HAVE_CRYPT_R 1" >>confdefs.h - - if test "$ac_cv_search_crypt_r" = "none required"; then - libcrypt= - else - libcrypt="$ac_cv_search_crypt_r" - fi - LIBCRYPT_LIBS=${LIBCRYPT_LIBS-$libcrypt} +printf "%s\n" "#define HAVE_ACCEPT 1" >>confdefs.h fi -CFLAGS=$save_CFLAGS -CPPFLAGS=$save_CPPFLAGS -LDFLAGS=$save_LDFLAGS -LIBS=$save_LIBS - -elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - - save_CFLAGS=$CFLAGS -save_CPPFLAGS=$CPPFLAGS -save_LDFLAGS=$LDFLAGS -save_LIBS=$LIBS - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing crypt_r" >&5 -$as_echo_n "checking for library containing crypt_r... " >&6; } -if ${ac_cv_search_crypt_r+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_func_search_save_LIBS=$LIBS -cat confdefs.h - <<_ACEOF >conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for bind" >&5 +printf %s "checking for bind... " >&6; } +if test ${ac_cv_func_bind+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char crypt_r (); +#include +#include +#include +#include + int -main () +main (void) { -return crypt_r (); +void *x=bind ; return 0; } _ACEOF -for ac_lib in '' crypt; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - if ac_fn_c_try_link "$LINENO"; then : - ac_cv_search_crypt_r=$ac_res -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext - if ${ac_cv_search_crypt_r+:} false; then : - break +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_bind=yes +else $as_nop + ac_cv_func_bind=no fi -done -if ${ac_cv_search_crypt_r+:} false; then : +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext -else - ac_cv_search_crypt_r=no fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_crypt_r" >&5 -$as_echo "$ac_cv_search_crypt_r" >&6; } -ac_res=$ac_cv_search_crypt_r -if test "$ac_res" != no; then : - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - - $as_echo "#define HAVE_CRYPT_R 1" >>confdefs.h +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_bind" >&5 +printf "%s\n" "$ac_cv_func_bind" >&6; } + if test "x$ac_cv_func_bind" = xyes +then : - if test "$ac_cv_search_crypt_r" = "none required"; then - libcrypt= - else - libcrypt="$ac_cv_search_crypt_r" - fi - LIBCRYPT_LIBS=${LIBCRYPT_LIBS-$libcrypt} +printf "%s\n" "#define HAVE_BIND 1" >>confdefs.h fi -CFLAGS=$save_CFLAGS -CPPFLAGS=$save_CPPFLAGS -LDFLAGS=$save_LDFLAGS -LIBS=$save_LIBS - - - -else - LIBCRYPT_CFLAGS=$pkg_cv_LIBCRYPT_CFLAGS - LIBCRYPT_LIBS=$pkg_cv_LIBCRYPT_LIBS - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - - $as_echo "#define HAVE_CRYPT_R 1" >>confdefs.h - - -fi - -save_CFLAGS=$CFLAGS -save_CPPFLAGS=$CPPFLAGS -save_LDFLAGS=$LDFLAGS -save_LIBS=$LIBS - CPPFLAGS="$CPPFLAGS $LIBCRYPT_CFLAGS" - LIBS="$LIBCRYPT_LIBS $LIBS" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for crypt or crypt_r" >&5 -$as_echo_n "checking for crypt or crypt_r... " >&6; } -if ${ac_cv_crypt_crypt+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for connect" >&5 +printf %s "checking for connect... " >&6; } +if test ${ac_cv_func_connect+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - #ifdef HAVE_CRYPT_H - #include - #endif - #include +#include +#include +#include +#include int -main () +main (void) { - - #ifdef HAVE_CRYPT_R - void *x = crypt_r; - #else - void *x = crypt; - #endif - +void *x=connect ; return 0; } - _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_crypt_crypt=yes -else - ac_cv_crypt_crypt=no +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_connect=yes +else $as_nop + ac_cv_func_connect=no fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_crypt_crypt" >&5 -$as_echo "$ac_cv_crypt_crypt" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_connect" >&5 +printf "%s\n" "$ac_cv_func_connect" >&6; } + if test "x$ac_cv_func_connect" = xyes +then : -CFLAGS=$save_CFLAGS -CPPFLAGS=$save_CPPFLAGS -LDFLAGS=$save_LDFLAGS -LIBS=$save_LIBS +printf "%s\n" "#define HAVE_CONNECT 1" >>confdefs.h +fi -for ac_func in clock_gettime -do : - ac_fn_c_check_func "$LINENO" "clock_gettime" "ac_cv_func_clock_gettime" -if test "x$ac_cv_func_clock_gettime" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_CLOCK_GETTIME 1 -_ACEOF -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for clock_gettime in -lrt" >&5 -$as_echo_n "checking for clock_gettime in -lrt... " >&6; } -if ${ac_cv_lib_rt_clock_gettime+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lrt $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for listen" >&5 +printf %s "checking for listen... " >&6; } +if test ${ac_cv_func_listen+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char clock_gettime (); +#include +#include +#include +#include + int -main () +main (void) { -return clock_gettime (); +void *x=listen ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_rt_clock_gettime=yes -else - ac_cv_lib_rt_clock_gettime=no +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_listen=yes +else $as_nop + ac_cv_func_listen=no fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_rt_clock_gettime" >&5 -$as_echo "$ac_cv_lib_rt_clock_gettime" >&6; } -if test "x$ac_cv_lib_rt_clock_gettime" = xyes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_listen" >&5 +printf "%s\n" "$ac_cv_func_listen" >&6; } + if test "x$ac_cv_func_listen" = xyes +then : - LIBS="$LIBS -lrt" - $as_echo "#define HAVE_CLOCK_GETTIME 1" >>confdefs.h +printf "%s\n" "#define HAVE_LISTEN 1" >>confdefs.h +fi -$as_echo "#define TIMEMODULE_LIB rt" >>confdefs.h -fi -fi -done + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for recvfrom" >&5 +printf %s "checking for recvfrom... " >&6; } +if test ${ac_cv_func_recvfrom+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include -for ac_func in clock_getres -do : - ac_fn_c_check_func "$LINENO" "clock_getres" "ac_cv_func_clock_getres" -if test "x$ac_cv_func_clock_getres" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_CLOCK_GETRES 1 +int +main (void) +{ +void *x=recvfrom + ; + return 0; +} _ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_recvfrom=yes +else $as_nop + ac_cv_func_recvfrom=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext -else +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_recvfrom" >&5 +printf "%s\n" "$ac_cv_func_recvfrom" >&6; } + if test "x$ac_cv_func_recvfrom" = xyes +then : - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for clock_getres in -lrt" >&5 -$as_echo_n "checking for clock_getres in -lrt... " >&6; } -if ${ac_cv_lib_rt_clock_getres+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lrt $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext +printf "%s\n" "#define HAVE_RECVFROM 1" >>confdefs.h + +fi + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sendto" >&5 +printf %s "checking for sendto... " >&6; } +if test ${ac_cv_func_sendto+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char clock_getres (); +#include +#include +#include +#include + int -main () +main (void) { -return clock_getres (); +void *x=sendto ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_rt_clock_getres=yes -else - ac_cv_lib_rt_clock_getres=no +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_sendto=yes +else $as_nop + ac_cv_func_sendto=no fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_rt_clock_getres" >&5 -$as_echo "$ac_cv_lib_rt_clock_getres" >&6; } -if test "x$ac_cv_lib_rt_clock_getres" = xyes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_sendto" >&5 +printf "%s\n" "$ac_cv_func_sendto" >&6; } + if test "x$ac_cv_func_sendto" = xyes +then : - $as_echo "#define HAVE_CLOCK_GETRES 1" >>confdefs.h +printf "%s\n" "#define HAVE_SENDTO 1" >>confdefs.h +fi + + + + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for setsockopt" >&5 +printf %s "checking for setsockopt... " >&6; } +if test ${ac_cv_func_setsockopt+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +#include +#include + +int +main (void) +{ +void *x=setsockopt + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_setsockopt=yes +else $as_nop + ac_cv_func_setsockopt=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_setsockopt" >&5 +printf "%s\n" "$ac_cv_func_setsockopt" >&6; } + if test "x$ac_cv_func_setsockopt" = xyes +then : +printf "%s\n" "#define HAVE_SETSOCKOPT 1" >>confdefs.h fi -done -for ac_func in clock_settime -do : - ac_fn_c_check_func "$LINENO" "clock_settime" "ac_cv_func_clock_settime" -if test "x$ac_cv_func_clock_settime" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_CLOCK_SETTIME 1 -_ACEOF -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for clock_settime in -lrt" >&5 -$as_echo_n "checking for clock_settime in -lrt... " >&6; } -if ${ac_cv_lib_rt_clock_settime+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lrt $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for socket" >&5 +printf %s "checking for socket... " >&6; } +if test ${ac_cv_func_socket+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char clock_settime (); +#include +#include +#include +#include + int -main () +main (void) { -return clock_settime (); +void *x=socket ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_rt_clock_settime=yes -else - ac_cv_lib_rt_clock_settime=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_socket=yes +else $as_nop + ac_cv_func_socket=no fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_rt_clock_settime" >&5 -$as_echo "$ac_cv_lib_rt_clock_settime" >&6; } -if test "x$ac_cv_lib_rt_clock_settime" = xyes; then : +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext - $as_echo "#define HAVE_CLOCK_SETTIME 1" >>confdefs.h +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_socket" >&5 +printf "%s\n" "$ac_cv_func_socket" >&6; } + if test "x$ac_cv_func_socket" = xyes +then : +printf "%s\n" "#define HAVE_SOCKET 1" >>confdefs.h fi -fi -done -for ac_func in clock_nanosleep -do : - ac_fn_c_check_func "$LINENO" "clock_nanosleep" "ac_cv_func_clock_nanosleep" -if test "x$ac_cv_func_clock_nanosleep" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_CLOCK_NANOSLEEP 1 -_ACEOF +# On some systems, setgroups is in unistd.h, on others, in grp.h -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for clock_nanosleep in -lrt" >&5 -$as_echo_n "checking for clock_nanosleep in -lrt... " >&6; } -if ${ac_cv_lib_rt_clock_nanosleep+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lrt $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for setgroups" >&5 +printf %s "checking for setgroups... " >&6; } +if test ${ac_cv_func_setgroups+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" +#include +#ifdef HAVE_GRP_H +#include #endif -char clock_nanosleep (); + int -main () +main (void) { -return clock_nanosleep (); +void *x=setgroups ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_rt_clock_nanosleep=yes -else - ac_cv_lib_rt_clock_nanosleep=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_setgroups=yes +else $as_nop + ac_cv_func_setgroups=no fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_rt_clock_nanosleep" >&5 -$as_echo "$ac_cv_lib_rt_clock_nanosleep" >&6; } -if test "x$ac_cv_lib_rt_clock_nanosleep" = xyes; then : +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext - $as_echo "#define HAVE_CLOCK_NANOSLEEP 1" >>confdefs.h +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_setgroups" >&5 +printf "%s\n" "$ac_cv_func_setgroups" >&6; } + if test "x$ac_cv_func_setgroups" = xyes +then : +printf "%s\n" "#define HAVE_SETGROUPS 1" >>confdefs.h fi -fi -done -for ac_func in nanosleep -do : - ac_fn_c_check_func "$LINENO" "nanosleep" "ac_cv_func_nanosleep" -if test "x$ac_cv_func_nanosleep" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_NANOSLEEP 1 -_ACEOF +# check for openpty, login_tty, and forkpty -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for nanosleep in -lrt" >&5 -$as_echo_n "checking for nanosleep in -lrt... " >&6; } -if ${ac_cv_lib_rt_nanosleep+:} false; then : - $as_echo_n "(cached) " >&6 -else + for ac_func in openpty +do : + ac_fn_c_check_func "$LINENO" "openpty" "ac_cv_func_openpty" +if test "x$ac_cv_func_openpty" = xyes +then : + printf "%s\n" "#define HAVE_OPENPTY 1" >>confdefs.h + +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for openpty in -lutil" >&5 +printf %s "checking for openpty in -lutil... " >&6; } +if test ${ac_cv_lib_util_openpty+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS -LIBS="-lrt $LIBS" +LIBS="-lutil $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char nanosleep (); +char openpty (); int -main () +main (void) { -return nanosleep (); +return openpty (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_rt_nanosleep=yes -else - ac_cv_lib_rt_nanosleep=no +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_util_openpty=yes +else $as_nop + ac_cv_lib_util_openpty=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_rt_nanosleep" >&5 -$as_echo "$ac_cv_lib_rt_nanosleep" >&6; } -if test "x$ac_cv_lib_rt_nanosleep" = xyes; then : - - $as_echo "#define HAVE_NANOSLEEP 1" >>confdefs.h - - -fi - - -fi -done - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for major, minor, and makedev" >&5 -$as_echo_n "checking for major, minor, and makedev... " >&6; } -if ${ac_cv_device_macros+:} false; then : - $as_echo_n "(cached) " >&6 -else - +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_util_openpty" >&5 +printf "%s\n" "$ac_cv_lib_util_openpty" >&6; } +if test "x$ac_cv_lib_util_openpty" = xyes +then : + printf "%s\n" "#define HAVE_OPENPTY 1" >>confdefs.h + LIBS="$LIBS -lutil" +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for openpty in -lbsd" >&5 +printf %s "checking for openpty in -lbsd... " >&6; } +if test ${ac_cv_lib_bsd_openpty+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_check_lib_save_LIBS=$LIBS +LIBS="-lbsd $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#if defined(MAJOR_IN_MKDEV) -#include -#elif defined(MAJOR_IN_SYSMACROS) -#include -#else -#include -#endif - +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char openpty (); int -main () +main (void) { - - makedev(major(0),minor(0)); - +return openpty (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_device_macros=yes -else - ac_cv_device_macros=no +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_bsd_openpty=yes +else $as_nop + ac_cv_lib_bsd_openpty=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext - +LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_device_macros" >&5 -$as_echo "$ac_cv_device_macros" >&6; } -if test "x$ac_cv_device_macros" = xyes; then : - - -$as_echo "#define HAVE_DEVICE_MACROS 1" >>confdefs.h - - +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bsd_openpty" >&5 +printf "%s\n" "$ac_cv_lib_bsd_openpty" >&6; } +if test "x$ac_cv_lib_bsd_openpty" = xyes +then : + printf "%s\n" "#define HAVE_OPENPTY 1" >>confdefs.h + LIBS="$LIBS -lbsd" fi +fi -$as_echo "#define SYS_SELECT_WITH_SYS_TIME 1" >>confdefs.h - - -# On OSF/1 V5.1, getaddrinfo is available, but a define -# for [no]getaddrinfo in netdb.h. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for getaddrinfo" >&5 -$as_echo_n "checking for getaddrinfo... " >&6; } -if ${ac_cv_func_getaddrinfo+:} false; then : - $as_echo_n "(cached) " >&6 -else +fi +done +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing login_tty" >&5 +printf %s "checking for library containing login_tty... " >&6; } +if test ${ac_cv_search_login_tty+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include -#include -#include -#include - +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char login_tty (); int -main () +main (void) { -getaddrinfo(NULL, NULL, NULL, NULL); +return login_tty (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_func_getaddrinfo=yes -else - ac_cv_func_getaddrinfo=no +for ac_lib in '' util +do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO" +then : + ac_cv_search_login_tty=$ac_res fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext + if test ${ac_cv_search_login_tty+y} +then : + break +fi +done +if test ${ac_cv_search_login_tty+y} +then : +else $as_nop + ac_cv_search_login_tty=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_getaddrinfo" >&5 -$as_echo "$ac_cv_func_getaddrinfo" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_login_tty" >&5 +printf "%s\n" "$ac_cv_search_login_tty" >&6; } +ac_res=$ac_cv_search_login_tty +if test "$ac_res" != no +then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" -if test "x$ac_cv_func_getaddrinfo" = xyes; then : +printf "%s\n" "#define HAVE_LOGIN_TTY 1" >>confdefs.h - { $as_echo "$as_me:${as_lineno-$LINENO}: checking getaddrinfo bug" >&5 -$as_echo_n "checking getaddrinfo bug... " >&6; } -if ${ac_cv_buggy_getaddrinfo+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "$cross_compiling" = yes; then : -if test "${enable_ipv6+set}" = set; then - ac_cv_buggy_getaddrinfo="no -- configured with --(en|dis)able-ipv6" -else - ac_cv_buggy_getaddrinfo=yes fi -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#include -#include -#include -#include -#include -#include - -int main(void) -{ - int passive, gaierr, inet4 = 0, inet6 = 0; - struct addrinfo hints, *ai, *aitop; - char straddr[INET6_ADDRSTRLEN], strport[16]; - for (passive = 0; passive <= 1; passive++) { - memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_UNSPEC; - hints.ai_flags = passive ? AI_PASSIVE : 0; - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = IPPROTO_TCP; - if ((gaierr = getaddrinfo(NULL, "54321", &hints, &aitop)) != 0) { - (void)gai_strerror(gaierr); - goto bad; - } - for (ai = aitop; ai; ai = ai->ai_next) { - if (ai->ai_addr == NULL || - ai->ai_addrlen == 0 || - getnameinfo(ai->ai_addr, ai->ai_addrlen, - straddr, sizeof(straddr), strport, sizeof(strport), - NI_NUMERICHOST|NI_NUMERICSERV) != 0) { - goto bad; - } - switch (ai->ai_family) { - case AF_INET: - if (strcmp(strport, "54321") != 0) { - goto bad; - } - if (passive) { - if (strcmp(straddr, "0.0.0.0") != 0) { - goto bad; - } - } else { - if (strcmp(straddr, "127.0.0.1") != 0) { - goto bad; - } - } - inet4++; - break; - case AF_INET6: - if (strcmp(strport, "54321") != 0) { - goto bad; - } - if (passive) { - if (strcmp(straddr, "::") != 0) { - goto bad; - } - } else { - if (strcmp(straddr, "::1") != 0) { - goto bad; - } - } - inet6++; - break; - case AF_UNSPEC: - goto bad; - break; - default: - /* another family support? */ - break; - } - } - freeaddrinfo(aitop); - aitop = NULL; - } - if (!(inet4 == 0 || inet4 == 2)) - goto bad; - if (!(inet6 == 0 || inet6 == 2)) - goto bad; + for ac_func in forkpty +do : + ac_fn_c_check_func "$LINENO" "forkpty" "ac_cv_func_forkpty" +if test "x$ac_cv_func_forkpty" = xyes +then : + printf "%s\n" "#define HAVE_FORKPTY 1" >>confdefs.h + +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for forkpty in -lutil" >&5 +printf %s "checking for forkpty in -lutil... " >&6; } +if test ${ac_cv_lib_util_forkpty+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_check_lib_save_LIBS=$LIBS +LIBS="-lutil $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ - if (aitop) - freeaddrinfo(aitop); +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char forkpty (); +int +main (void) +{ +return forkpty (); + ; return 0; - - bad: - if (aitop) - freeaddrinfo(aitop); - return 1; } - _ACEOF -if ac_fn_c_try_run "$LINENO"; then : - ac_cv_buggy_getaddrinfo=no -else - ac_cv_buggy_getaddrinfo=yes +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_util_forkpty=yes +else $as_nop + ac_cv_lib_util_forkpty=no fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_util_forkpty" >&5 +printf "%s\n" "$ac_cv_lib_util_forkpty" >&6; } +if test "x$ac_cv_lib_util_forkpty" = xyes +then : + printf "%s\n" "#define HAVE_FORKPTY 1" >>confdefs.h + LIBS="$LIBS -lutil" +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for forkpty in -lbsd" >&5 +printf %s "checking for forkpty in -lbsd... " >&6; } +if test ${ac_cv_lib_bsd_forkpty+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_check_lib_save_LIBS=$LIBS +LIBS="-lbsd $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char forkpty (); +int +main (void) +{ +return forkpty (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_bsd_forkpty=yes +else $as_nop + ac_cv_lib_bsd_forkpty=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bsd_forkpty" >&5 +printf "%s\n" "$ac_cv_lib_bsd_forkpty" >&6; } +if test "x$ac_cv_lib_bsd_forkpty" = xyes +then : + printf "%s\n" "#define HAVE_FORKPTY 1" >>confdefs.h + LIBS="$LIBS -lbsd" fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_buggy_getaddrinfo" >&5 -$as_echo "$ac_cv_buggy_getaddrinfo" >&6; } +fi fi -if test "$ac_cv_func_getaddrinfo" = no -o "$ac_cv_buggy_getaddrinfo" = yes -then - if test "x$ipv6" = xyes; then : +done - as_fn_error $? "You must get working getaddrinfo() function or pass the \"--disable-ipv6\" option to configure." "$LINENO" 5 +# check for long file support functions +ac_fn_c_check_func "$LINENO" "fseek64" "ac_cv_func_fseek64" +if test "x$ac_cv_func_fseek64" = xyes +then : + printf "%s\n" "#define HAVE_FSEEK64 1" >>confdefs.h fi -else - -$as_echo "#define HAVE_GETADDRINFO 1" >>confdefs.h +ac_fn_c_check_func "$LINENO" "fseeko" "ac_cv_func_fseeko" +if test "x$ac_cv_func_fseeko" = xyes +then : + printf "%s\n" "#define HAVE_FSEEKO 1" >>confdefs.h fi +ac_fn_c_check_func "$LINENO" "fstatvfs" "ac_cv_func_fstatvfs" +if test "x$ac_cv_func_fstatvfs" = xyes +then : + printf "%s\n" "#define HAVE_FSTATVFS 1" >>confdefs.h -for ac_func in getnameinfo -do : - ac_fn_c_check_func "$LINENO" "getnameinfo" "ac_cv_func_getnameinfo" -if test "x$ac_cv_func_getnameinfo" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_GETNAMEINFO 1 -_ACEOF +fi +ac_fn_c_check_func "$LINENO" "ftell64" "ac_cv_func_ftell64" +if test "x$ac_cv_func_ftell64" = xyes +then : + printf "%s\n" "#define HAVE_FTELL64 1" >>confdefs.h fi -done +ac_fn_c_check_func "$LINENO" "ftello" "ac_cv_func_ftello" +if test "x$ac_cv_func_ftello" = xyes +then : + printf "%s\n" "#define HAVE_FTELLO 1" >>confdefs.h +fi +ac_fn_c_check_func "$LINENO" "statvfs" "ac_cv_func_statvfs" +if test "x$ac_cv_func_statvfs" = xyes +then : + printf "%s\n" "#define HAVE_STATVFS 1" >>confdefs.h -if test "x$ac_cv_header_sys_time_h" = xyes; then : +fi -$as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h +ac_fn_c_check_func "$LINENO" "dup2" "ac_cv_func_dup2" +if test "x$ac_cv_func_dup2" = xyes +then : + printf "%s\n" "#define HAVE_DUP2 1" >>confdefs.h +else $as_nop + case " $LIBOBJS " in + *" dup2.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS dup2.$ac_objext" + ;; +esac fi -# checks for structures -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether struct tm is in sys/time.h or time.h" >&5 -$as_echo_n "checking whether struct tm is in sys/time.h or time.h... " >&6; } -if ${ac_cv_struct_tm+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include + for ac_func in getpgrp +do : + ac_fn_c_check_func "$LINENO" "getpgrp" "ac_cv_func_getpgrp" +if test "x$ac_cv_func_getpgrp" = xyes +then : + printf "%s\n" "#define HAVE_GETPGRP 1" >>confdefs.h + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include int -main () +main (void) { -struct tm tm; - int *p = &tm.tm_sec; - return !p; +getpgrp(0); ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_struct_tm=time.h -else - ac_cv_struct_tm=sys/time.h -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_struct_tm" >&5 -$as_echo "$ac_cv_struct_tm" >&6; } -if test $ac_cv_struct_tm = sys/time.h; then - -$as_echo "#define TM_IN_SYS_TIME 1" >>confdefs.h - -fi - -ac_fn_c_check_member "$LINENO" "struct tm" "tm_zone" "ac_cv_member_struct_tm_tm_zone" "#include -#include <$ac_cv_struct_tm> - -" -if test "x$ac_cv_member_struct_tm_tm_zone" = xyes; then : - -cat >>confdefs.h <<_ACEOF -#define HAVE_STRUCT_TM_TM_ZONE 1 -_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : +printf "%s\n" "#define GETPGRP_HAVE_ARG 1" >>confdefs.h fi - -if test "$ac_cv_member_struct_tm_tm_zone" = yes; then - -$as_echo "#define HAVE_TM_ZONE 1" >>confdefs.h - -else - ac_fn_c_check_decl "$LINENO" "tzname" "ac_cv_have_decl_tzname" "#include -" -if test "x$ac_cv_have_decl_tzname" = xyes; then : - ac_have_decl=1 -else - ac_have_decl=0 +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi -cat >>confdefs.h <<_ACEOF -#define HAVE_DECL_TZNAME $ac_have_decl -_ACEOF +done - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tzname" >&5 -$as_echo_n "checking for tzname... " >&6; } -if ${ac_cv_var_tzname+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + for ac_func in setpgrp +do : + ac_fn_c_check_func "$LINENO" "setpgrp" "ac_cv_func_setpgrp" +if test "x$ac_cv_func_setpgrp" = xyes +then : + printf "%s\n" "#define HAVE_SETPGRP 1" >>confdefs.h + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include -#if !HAVE_DECL_TZNAME -extern char *tzname[]; -#endif - +#include int -main () +main (void) { -return tzname[0][0]; +setpgrp(0,0); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_var_tzname=yes -else - ac_cv_var_tzname=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_var_tzname" >&5 -$as_echo "$ac_cv_var_tzname" >&6; } - if test $ac_cv_var_tzname = yes; then +if ac_fn_c_try_compile "$LINENO" +then : -$as_echo "#define HAVE_TZNAME 1" >>confdefs.h +printf "%s\n" "#define SETPGRP_HAVE_ARG 1" >>confdefs.h - fi fi - -ac_fn_c_check_member "$LINENO" "struct stat" "st_rdev" "ac_cv_member_struct_stat_st_rdev" "$ac_includes_default" -if test "x$ac_cv_member_struct_stat_st_rdev" = xyes; then : - -cat >>confdefs.h <<_ACEOF -#define HAVE_STRUCT_STAT_ST_RDEV 1 -_ACEOF - - +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi -ac_fn_c_check_member "$LINENO" "struct stat" "st_blksize" "ac_cv_member_struct_stat_st_blksize" "$ac_includes_default" -if test "x$ac_cv_member_struct_stat_st_blksize" = xyes; then : - -cat >>confdefs.h <<_ACEOF -#define HAVE_STRUCT_STAT_ST_BLKSIZE 1 -_ACEOF +done +# check for namespace functions +ac_fn_c_check_func "$LINENO" "setns" "ac_cv_func_setns" +if test "x$ac_cv_func_setns" = xyes +then : + printf "%s\n" "#define HAVE_SETNS 1" >>confdefs.h fi - -ac_fn_c_check_member "$LINENO" "struct stat" "st_flags" "ac_cv_member_struct_stat_st_flags" "$ac_includes_default" -if test "x$ac_cv_member_struct_stat_st_flags" = xyes; then : - -cat >>confdefs.h <<_ACEOF -#define HAVE_STRUCT_STAT_ST_FLAGS 1 -_ACEOF - +ac_fn_c_check_func "$LINENO" "unshare" "ac_cv_func_unshare" +if test "x$ac_cv_func_unshare" = xyes +then : + printf "%s\n" "#define HAVE_UNSHARE 1" >>confdefs.h fi -ac_fn_c_check_member "$LINENO" "struct stat" "st_gen" "ac_cv_member_struct_stat_st_gen" "$ac_includes_default" -if test "x$ac_cv_member_struct_stat_st_gen" = xyes; then : - -cat >>confdefs.h <<_ACEOF -#define HAVE_STRUCT_STAT_ST_GEN 1 -_ACEOF - -fi -ac_fn_c_check_member "$LINENO" "struct stat" "st_birthtime" "ac_cv_member_struct_stat_st_birthtime" "$ac_includes_default" -if test "x$ac_cv_member_struct_stat_st_birthtime" = xyes; then : -cat >>confdefs.h <<_ACEOF -#define HAVE_STRUCT_STAT_ST_BIRTHTIME 1 -_ACEOF +pkg_failed=no +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for LIBCRYPT" >&5 +printf %s "checking for LIBCRYPT... " >&6; } +if test -n "$LIBCRYPT_CFLAGS"; then + pkg_cv_LIBCRYPT_CFLAGS="$LIBCRYPT_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libxcrypt >= 3.1.1\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libxcrypt >= 3.1.1") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBCRYPT_CFLAGS=`$PKG_CONFIG --cflags "libxcrypt >= 3.1.1" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes fi + else + pkg_failed=untried +fi +if test -n "$LIBCRYPT_LIBS"; then + pkg_cv_LIBCRYPT_LIBS="$LIBCRYPT_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libxcrypt >= 3.1.1\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libxcrypt >= 3.1.1") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBCRYPT_LIBS=`$PKG_CONFIG --libs "libxcrypt >= 3.1.1" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + -ac_fn_c_check_member "$LINENO" "struct stat" "st_blocks" "ac_cv_member_struct_stat_st_blocks" "$ac_includes_default" -if test "x$ac_cv_member_struct_stat_st_blocks" = xyes; then : - -cat >>confdefs.h <<_ACEOF -#define HAVE_STRUCT_STAT_ST_BLOCKS 1 -_ACEOF - +if test $pkg_failed = yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no fi + if test $_pkg_short_errors_supported = yes; then + LIBCRYPT_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libxcrypt >= 3.1.1" 2>&1` + else + LIBCRYPT_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libxcrypt >= 3.1.1" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LIBCRYPT_PKG_ERRORS" >&5 -ac_fn_c_check_member "$LINENO" "struct passwd" "pw_gecos" "ac_cv_member_struct_passwd_pw_gecos" " - #include - #include -" -if test "x$ac_cv_member_struct_passwd_pw_gecos" = xyes; then : + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS -cat >>confdefs.h <<_ACEOF -#define HAVE_STRUCT_PASSWD_PW_GECOS 1 -_ACEOF + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing crypt_r" >&5 +printf %s "checking for library containing crypt_r... " >&6; } +if test ${ac_cv_search_crypt_r+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char crypt_r (); +int +main (void) +{ +return crypt_r (); + ; + return 0; +} +_ACEOF +for ac_lib in '' crypt +do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO" +then : + ac_cv_search_crypt_r=$ac_res fi -ac_fn_c_check_member "$LINENO" "struct passwd" "pw_passwd" "ac_cv_member_struct_passwd_pw_passwd" " - #include - #include +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext + if test ${ac_cv_search_crypt_r+y} +then : + break +fi +done +if test ${ac_cv_search_crypt_r+y} +then : -" -if test "x$ac_cv_member_struct_passwd_pw_passwd" = xyes; then : +else $as_nop + ac_cv_search_crypt_r=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_crypt_r" >&5 +printf "%s\n" "$ac_cv_search_crypt_r" >&6; } +ac_res=$ac_cv_search_crypt_r +if test "$ac_res" != no +then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" -cat >>confdefs.h <<_ACEOF -#define HAVE_STRUCT_PASSWD_PW_PASSWD 1 -_ACEOF + printf "%s\n" "#define HAVE_CRYPT_R 1" >>confdefs.h + if test "$ac_cv_search_crypt_r" = "none required"; then + libcrypt= + else + libcrypt="$ac_cv_search_crypt_r" + fi + LIBCRYPT_LIBS=${LIBCRYPT_LIBS-$libcrypt} fi -# Issue #21085: In Cygwin, siginfo_t does not have si_band field. -ac_fn_c_check_member "$LINENO" "siginfo_t" "si_band" "ac_cv_member_siginfo_t_si_band" "#include -" -if test "x$ac_cv_member_siginfo_t_si_band" = xyes; then : -cat >>confdefs.h <<_ACEOF -#define HAVE_SIGINFO_T_SI_BAND 1 -_ACEOF +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS -fi +elif test $pkg_failed = untried; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for time.h that defines altzone" >&5 -$as_echo_n "checking for time.h that defines altzone... " >&6; } -if ${ac_cv_header_time_altzone+:} false; then : - $as_echo_n "(cached) " >&6 -else + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing crypt_r" >&5 +printf %s "checking for library containing crypt_r... " >&6; } +if test ${ac_cv_search_crypt_r+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char crypt_r (); int -main () +main (void) { -return altzone; +return crypt_r (); ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_header_time_altzone=yes -else - ac_cv_header_time_altzone=no +for ac_lib in '' crypt +do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO" +then : + ac_cv_search_crypt_r=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext + if test ${ac_cv_search_crypt_r+y} +then : + break fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +done +if test ${ac_cv_search_crypt_r+y} +then : +else $as_nop + ac_cv_search_crypt_r=no fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_time_altzone" >&5 -$as_echo "$ac_cv_header_time_altzone" >&6; } -if test $ac_cv_header_time_altzone = yes; then +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_crypt_r" >&5 +printf "%s\n" "$ac_cv_search_crypt_r" >&6; } +ac_res=$ac_cv_search_crypt_r +if test "$ac_res" != no +then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" -$as_echo "#define HAVE_ALTZONE 1" >>confdefs.h + printf "%s\n" "#define HAVE_CRYPT_R 1" >>confdefs.h + + if test "$ac_cv_search_crypt_r" = "none required"; then + libcrypt= + else + libcrypt="$ac_cv_search_crypt_r" + fi + LIBCRYPT_LIBS=${LIBCRYPT_LIBS-$libcrypt} fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for addrinfo" >&5 -$as_echo_n "checking for addrinfo... " >&6; } -if ${ac_cv_struct_addrinfo+:} false; then : - $as_echo_n "(cached) " >&6 + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + LIBCRYPT_CFLAGS=$pkg_cv_LIBCRYPT_CFLAGS + LIBCRYPT_LIBS=$pkg_cv_LIBCRYPT_LIBS + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + + printf "%s\n" "#define HAVE_CRYPT_R 1" >>confdefs.h + + +fi + +save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + CPPFLAGS="$CPPFLAGS $LIBCRYPT_CFLAGS" + LIBS="$LIBCRYPT_LIBS $LIBS" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for crypt or crypt_r" >&5 +printf %s "checking for crypt or crypt_r... " >&6; } +if test ${ac_cv_crypt_crypt+y} +then : + printf %s "(cached) " >&6 +else $as_nop + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include + + #ifdef HAVE_CRYPT_H + #include + #endif + #include + int -main () +main (void) { -struct addrinfo a + + #ifdef HAVE_CRYPT_R + void *x = crypt_r; + #else + void *x = crypt; + #endif + ; return 0; } + _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_struct_addrinfo=yes -else - ac_cv_struct_addrinfo=no +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_crypt_crypt=yes +else $as_nop + ac_cv_crypt_crypt=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_struct_addrinfo" >&5 -$as_echo "$ac_cv_struct_addrinfo" >&6; } -if test $ac_cv_struct_addrinfo = yes; then +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_crypt_crypt" >&5 +printf "%s\n" "$ac_cv_crypt_crypt" >&6; } + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS -$as_echo "#define HAVE_ADDRINFO 1" >>confdefs.h -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sockaddr_storage" >&5 -$as_echo_n "checking for sockaddr_storage... " >&6; } -if ${ac_cv_struct_sockaddr_storage+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + + for ac_func in clock_gettime +do : + ac_fn_c_check_func "$LINENO" "clock_gettime" "ac_cv_func_clock_gettime" +if test "x$ac_cv_func_clock_gettime" = xyes +then : + printf "%s\n" "#define HAVE_CLOCK_GETTIME 1" >>confdefs.h + +else $as_nop + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for clock_gettime in -lrt" >&5 +printf %s "checking for clock_gettime in -lrt... " >&6; } +if test ${ac_cv_lib_rt_clock_gettime+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_check_lib_save_LIBS=$LIBS +LIBS="-lrt $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -# include -# include +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char clock_gettime (); int -main () +main (void) { -struct sockaddr_storage s +return clock_gettime (); ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_struct_sockaddr_storage=yes -else - ac_cv_struct_sockaddr_storage=no +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_rt_clock_gettime=yes +else $as_nop + ac_cv_lib_rt_clock_gettime=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_struct_sockaddr_storage" >&5 -$as_echo "$ac_cv_struct_sockaddr_storage" >&6; } -if test $ac_cv_struct_sockaddr_storage = yes; then +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_rt_clock_gettime" >&5 +printf "%s\n" "$ac_cv_lib_rt_clock_gettime" >&6; } +if test "x$ac_cv_lib_rt_clock_gettime" = xyes +then : + + LIBS="$LIBS -lrt" + printf "%s\n" "#define HAVE_CLOCK_GETTIME 1" >>confdefs.h + + +printf "%s\n" "#define TIMEMODULE_LIB rt" >>confdefs.h -$as_echo "#define HAVE_SOCKADDR_STORAGE 1" >>confdefs.h fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sockaddr_alg" >&5 -$as_echo_n "checking for sockaddr_alg... " >&6; } -if ${ac_cv_struct_sockaddr_alg+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + +fi + +done + + + for ac_func in clock_getres +do : + ac_fn_c_check_func "$LINENO" "clock_getres" "ac_cv_func_clock_getres" +if test "x$ac_cv_func_clock_getres" = xyes +then : + printf "%s\n" "#define HAVE_CLOCK_GETRES 1" >>confdefs.h + +else $as_nop + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for clock_getres in -lrt" >&5 +printf %s "checking for clock_getres in -lrt... " >&6; } +if test ${ac_cv_lib_rt_clock_getres+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_check_lib_save_LIBS=$LIBS +LIBS="-lrt $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -# include -# include -# include +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char clock_getres (); int -main () +main (void) { -struct sockaddr_alg s +return clock_getres (); ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_struct_sockaddr_alg=yes -else - ac_cv_struct_sockaddr_alg=no +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_rt_clock_getres=yes +else $as_nop + ac_cv_lib_rt_clock_getres=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_struct_sockaddr_alg" >&5 -$as_echo "$ac_cv_struct_sockaddr_alg" >&6; } -if test $ac_cv_struct_sockaddr_alg = yes; then +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_rt_clock_getres" >&5 +printf "%s\n" "$ac_cv_lib_rt_clock_getres" >&6; } +if test "x$ac_cv_lib_rt_clock_getres" = xyes +then : + + printf "%s\n" "#define HAVE_CLOCK_GETRES 1" >>confdefs.h -$as_echo "#define HAVE_SOCKADDR_ALG 1" >>confdefs.h fi -# checks for compiler characteristics - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 -$as_echo_n "checking for an ANSI C-conforming const... " >&6; } -if ${ac_cv_c_const+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - -#ifndef __cplusplus - /* Ultrix mips cc rejects this sort of thing. */ - typedef int charset[2]; - const charset cs = { 0, 0 }; - /* SunOS 4.1.1 cc rejects this. */ - char const *const *pcpcc; - char **ppc; - /* NEC SVR4.0.2 mips cc rejects this. */ - struct point {int x, y;}; - static struct point const zero = {0,0}; - /* AIX XL C 1.02.0.0 rejects this. - It does not let you subtract one const X* pointer from another in - an arm of an if-expression whose if-part is not a constant - expression */ - const char *g = "string"; - pcpcc = &g + (g ? g-g : 0); - /* HPUX 7.0 cc rejects these. */ - ++pcpcc; - ppc = (char**) pcpcc; - pcpcc = (char const *const *) ppc; - { /* SCO 3.2v4 cc rejects this sort of thing. */ - char tx; - char *t = &tx; - char const *s = 0 ? (char *) 0 : (char const *) 0; - - *t++ = 0; - if (s) return 0; - } - { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ - int x[] = {25, 17}; - const int *foo = &x[0]; - ++foo; - } - { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ - typedef const int *iptr; - iptr p = 0; - ++p; - } - { /* AIX XL C 1.02.0.0 rejects this sort of thing, saying - "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ - struct s { int j; const int *ap[3]; } bx; - struct s *b = &bx; b->j = 5; - } - { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ - const int foo = 10; - if (!foo) return 0; - } - return !cs[0] && !zero.x; -#endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_c_const=yes -else - ac_cv_c_const=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 -$as_echo "$ac_cv_c_const" >&6; } -if test $ac_cv_c_const = no; then - -$as_echo "#define const /**/" >>confdefs.h fi +done -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working signed char" >&5 -$as_echo_n "checking for working signed char... " >&6; } -if ${ac_cv_working_signed_char_c+:} false; then : - $as_echo_n "(cached) " >&6 -else + for ac_func in clock_settime +do : + ac_fn_c_check_func "$LINENO" "clock_settime" "ac_cv_func_clock_settime" +if test "x$ac_cv_func_clock_settime" = xyes +then : + printf "%s\n" "#define HAVE_CLOCK_SETTIME 1" >>confdefs.h + +else $as_nop + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for clock_settime in -lrt" >&5 +printf %s "checking for clock_settime in -lrt... " >&6; } +if test ${ac_cv_lib_rt_clock_settime+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_check_lib_save_LIBS=$LIBS +LIBS="-lrt $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char clock_settime (); int -main () +main (void) { -signed char c; +return clock_settime (); ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_working_signed_char_c=yes -else - ac_cv_working_signed_char_c=no +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_rt_clock_settime=yes +else $as_nop + ac_cv_lib_rt_clock_settime=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_working_signed_char_c" >&5 -$as_echo "$ac_cv_working_signed_char_c" >&6; } -if test "x$ac_cv_working_signed_char_c" = xno; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_rt_clock_settime" >&5 +printf "%s\n" "$ac_cv_lib_rt_clock_settime" >&6; } +if test "x$ac_cv_lib_rt_clock_settime" = xyes +then : - -$as_echo "#define signed /**/" >>confdefs.h + printf "%s\n" "#define HAVE_CLOCK_SETTIME 1" >>confdefs.h fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for prototypes" >&5 -$as_echo_n "checking for prototypes... " >&6; } -if ${ac_cv_function_prototypes+:} false; then : - $as_echo_n "(cached) " >&6 -else - -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -int foo(int x) { return 0; } -int -main () -{ -return foo(10); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_function_prototypes=yes -else - ac_cv_function_prototypes=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_function_prototypes" >&5 -$as_echo "$ac_cv_function_prototypes" >&6; } -if test "x$ac_cv_function_prototypes" = xyes; then : - - -$as_echo "#define HAVE_PROTOTYPES 1" >>confdefs.h - -fi +done -works=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for variable length prototypes and stdarg.h" >&5 -$as_echo_n "checking for variable length prototypes and stdarg.h... " >&6; } -if ${ac_cv_stdarg_prototypes+:} false; then : - $as_echo_n "(cached) " >&6 -else + for ac_func in clock_nanosleep +do : + ac_fn_c_check_func "$LINENO" "clock_nanosleep" "ac_cv_func_clock_nanosleep" +if test "x$ac_cv_func_clock_nanosleep" = xyes +then : + printf "%s\n" "#define HAVE_CLOCK_NANOSLEEP 1" >>confdefs.h + +else $as_nop + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for clock_nanosleep in -lrt" >&5 +printf %s "checking for clock_nanosleep in -lrt... " >&6; } +if test ${ac_cv_lib_rt_clock_nanosleep+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_check_lib_save_LIBS=$LIBS +LIBS="-lrt $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include -int foo(int x, ...) { - va_list va; - va_start(va, x); - va_arg(va, int); - va_arg(va, char *); - va_arg(va, double); - return 0; -} - +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char clock_nanosleep (); int -main () +main (void) { -return foo(10, "", 3.14); +return clock_nanosleep (); ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_stdarg_prototypes=yes -else - ac_cv_stdarg_prototypes=no +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_rt_clock_nanosleep=yes +else $as_nop + ac_cv_lib_rt_clock_nanosleep=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_stdarg_prototypes" >&5 -$as_echo "$ac_cv_stdarg_prototypes" >&6; } -if test "x$ac_cv_stdarg_prototypes" = xyes; then : - +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_rt_clock_nanosleep" >&5 +printf "%s\n" "$ac_cv_lib_rt_clock_nanosleep" >&6; } +if test "x$ac_cv_lib_rt_clock_nanosleep" = xyes +then : -$as_echo "#define HAVE_STDARG_PROTOTYPES 1" >>confdefs.h + printf "%s\n" "#define HAVE_CLOCK_NANOSLEEP 1" >>confdefs.h fi -# check for socketpair +fi +done - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for socketpair" >&5 -$as_echo_n "checking for socketpair... " >&6; } -if ${ac_cv_func_socketpair+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include + for ac_func in nanosleep +do : + ac_fn_c_check_func "$LINENO" "nanosleep" "ac_cv_func_nanosleep" +if test "x$ac_cv_func_nanosleep" = xyes +then : + printf "%s\n" "#define HAVE_NANOSLEEP 1" >>confdefs.h + +else $as_nop + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for nanosleep in -lrt" >&5 +printf %s "checking for nanosleep in -lrt... " >&6; } +if test ${ac_cv_lib_rt_nanosleep+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_check_lib_save_LIBS=$LIBS +LIBS="-lrt $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char nanosleep (); int -main () +main (void) { -void *x=socketpair +return nanosleep (); ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_func_socketpair=yes -else - ac_cv_func_socketpair=no +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_rt_nanosleep=yes +else $as_nop + ac_cv_lib_rt_nanosleep=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_socketpair" >&5 -$as_echo "$ac_cv_func_socketpair" >&6; } - if test "x$ac_cv_func_socketpair" = xyes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_rt_nanosleep" >&5 +printf "%s\n" "$ac_cv_lib_rt_nanosleep" >&6; } +if test "x$ac_cv_lib_rt_nanosleep" = xyes +then : + + printf "%s\n" "#define HAVE_NANOSLEEP 1" >>confdefs.h -$as_echo "#define HAVE_SOCKETPAIR 1" >>confdefs.h fi +fi +done -# check if sockaddr has sa_len member -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if sockaddr has sa_len member" >&5 -$as_echo_n "checking if sockaddr has sa_len member... " >&6; } -if ${ac_cv_struct_sockaddr_sa_len+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for major, minor, and makedev" >&5 +printf %s "checking for major, minor, and makedev... " >&6; } +if test ${ac_cv_device_macros+y} +then : + printf %s "(cached) " >&6 +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ + +#if defined(MAJOR_IN_MKDEV) +#include +#elif defined(MAJOR_IN_SYSMACROS) +#include +#else #include -#include +#endif + int -main () +main (void) { -struct sockaddr x; -x.sa_len = 0; + + makedev(major(0),minor(0)); + ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_struct_sockaddr_sa_len=yes -else - ac_cv_struct_sockaddr_sa_len=no +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_device_macros=yes +else $as_nop + ac_cv_device_macros=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_struct_sockaddr_sa_len" >&5 -$as_echo "$ac_cv_struct_sockaddr_sa_len" >&6; } -if test "x$ac_cv_struct_sockaddr_sa_len" = xyes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_device_macros" >&5 +printf "%s\n" "$ac_cv_device_macros" >&6; } +if test "x$ac_cv_device_macros" = xyes +then : -$as_echo "#define HAVE_SOCKADDR_SA_LEN 1" >>confdefs.h +printf "%s\n" "#define HAVE_DEVICE_MACROS 1" >>confdefs.h fi -# sigh -- gethostbyname_r is a mess; it can have 3, 5 or 6 arguments :-( +printf "%s\n" "#define SYS_SELECT_WITH_SYS_TIME 1" >>confdefs.h -ac_fn_c_check_func "$LINENO" "gethostbyname_r" "ac_cv_func_gethostbyname_r" -if test "x$ac_cv_func_gethostbyname_r" = xyes; then : - $as_echo "#define HAVE_GETHOSTBYNAME_R 1" >>confdefs.h +# On OSF/1 V5.1, getaddrinfo is available, but a define +# for [no]getaddrinfo in netdb.h. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for getaddrinfo" >&5 +printf %s "checking for getaddrinfo... " >&6; } +if test ${ac_cv_func_getaddrinfo+y} +then : + printf %s "(cached) " >&6 +else $as_nop - { $as_echo "$as_me:${as_lineno-$LINENO}: checking gethostbyname_r with 6 args" >&5 -$as_echo_n "checking gethostbyname_r with 6 args... " >&6; } - OLD_CFLAGS=$CFLAGS - CFLAGS="$CFLAGS $MY_CPPFLAGS $MY_THREAD_CPPFLAGS $MY_CFLAGS" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext +cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -# include +#include +#include +#include +#include int -main () +main (void) { - - char *name; - struct hostent *he, *res; - char buffer[2048]; - int buflen = 2048; - int h_errnop; - - (void) gethostbyname_r(name, he, buffer, buflen, &res, &h_errnop) - +getaddrinfo(NULL, NULL, NULL, NULL); ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - - $as_echo "#define HAVE_GETHOSTBYNAME_R 1" >>confdefs.h +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_func_getaddrinfo=yes +else $as_nop + ac_cv_func_getaddrinfo=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_getaddrinfo" >&5 +printf "%s\n" "$ac_cv_func_getaddrinfo" >&6; } -$as_echo "#define HAVE_GETHOSTBYNAME_R_6_ARG 1" >>confdefs.h +if test "x$ac_cv_func_getaddrinfo" = xyes +then : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking getaddrinfo bug" >&5 +printf %s "checking getaddrinfo bug... " >&6; } +if test ${ac_cv_buggy_getaddrinfo+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test "$cross_compiling" = yes +then : +if test "${enable_ipv6+set}" = set; then + ac_cv_buggy_getaddrinfo="no -- configured with --(en|dis)able-ipv6" else - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking gethostbyname_r with 5 args" >&5 -$as_echo_n "checking gethostbyname_r with 5 args... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + ac_cv_buggy_getaddrinfo=yes +fi +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -# include +#include +#include +#include +#include +#include +#include -int -main () +int main(void) { + int passive, gaierr, inet4 = 0, inet6 = 0; + struct addrinfo hints, *ai, *aitop; + char straddr[INET6_ADDRSTRLEN], strport[16]; - char *name; - struct hostent *he; - char buffer[2048]; - int buflen = 2048; - int h_errnop; - - (void) gethostbyname_r(name, he, buffer, buflen, &h_errnop) - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - - $as_echo "#define HAVE_GETHOSTBYNAME_R 1" >>confdefs.h - - -$as_echo "#define HAVE_GETHOSTBYNAME_R_5_ARG 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; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking gethostbyname_r with 3 args" >&5 -$as_echo_n "checking gethostbyname_r with 3 args... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -# include - -int -main () -{ - - char *name; - struct hostent *he; - struct hostent_data data; + for (passive = 0; passive <= 1; passive++) { + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_flags = passive ? AI_PASSIVE : 0; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + if ((gaierr = getaddrinfo(NULL, "54321", &hints, &aitop)) != 0) { + (void)gai_strerror(gaierr); + goto bad; + } + for (ai = aitop; ai; ai = ai->ai_next) { + if (ai->ai_addr == NULL || + ai->ai_addrlen == 0 || + getnameinfo(ai->ai_addr, ai->ai_addrlen, + straddr, sizeof(straddr), strport, sizeof(strport), + NI_NUMERICHOST|NI_NUMERICSERV) != 0) { + goto bad; + } + switch (ai->ai_family) { + case AF_INET: + if (strcmp(strport, "54321") != 0) { + goto bad; + } + if (passive) { + if (strcmp(straddr, "0.0.0.0") != 0) { + goto bad; + } + } else { + if (strcmp(straddr, "127.0.0.1") != 0) { + goto bad; + } + } + inet4++; + break; + case AF_INET6: + if (strcmp(strport, "54321") != 0) { + goto bad; + } + if (passive) { + if (strcmp(straddr, "::") != 0) { + goto bad; + } + } else { + if (strcmp(straddr, "::1") != 0) { + goto bad; + } + } + inet6++; + break; + case AF_UNSPEC: + goto bad; + break; + default: + /* another family support? */ + break; + } + } + freeaddrinfo(aitop); + aitop = NULL; + } - (void) gethostbyname_r(name, he, &data); + if (!(inet4 == 0 || inet4 == 2)) + goto bad; + if (!(inet6 == 0 || inet6 == 2)) + goto bad; - ; + if (aitop) + freeaddrinfo(aitop); return 0; + + bad: + if (aitop) + freeaddrinfo(aitop); + return 1; } + _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_run "$LINENO" +then : + ac_cv_buggy_getaddrinfo=no +else $as_nop + ac_cv_buggy_getaddrinfo=yes +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_buggy_getaddrinfo" >&5 +printf "%s\n" "$ac_cv_buggy_getaddrinfo" >&6; } - $as_echo "#define HAVE_GETHOSTBYNAME_R 1" >>confdefs.h +fi -$as_echo "#define HAVE_GETHOSTBYNAME_R_3_ARG 1" >>confdefs.h +if test "$ac_cv_func_getaddrinfo" = no -o "$ac_cv_buggy_getaddrinfo" = yes +then + if test "x$ipv6" = xyes +then : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } + as_fn_error $? "You must get working getaddrinfo() function or pass the \"--disable-ipv6\" option to configure." "$LINENO" 5 +fi else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } +printf "%s\n" "#define HAVE_GETADDRINFO 1" >>confdefs.h fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_fn_c_check_func "$LINENO" "getnameinfo" "ac_cv_func_getnameinfo" +if test "x$ac_cv_func_getnameinfo" = xyes +then : + printf "%s\n" "#define HAVE_GETNAMEINFO 1" >>confdefs.h fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - CFLAGS=$OLD_CFLAGS -else - for ac_func in gethostbyname -do : - ac_fn_c_check_func "$LINENO" "gethostbyname" "ac_cv_func_gethostbyname" -if test "x$ac_cv_func_gethostbyname" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_GETHOSTBYNAME 1 -_ACEOF +# checks for structures +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether struct tm is in sys/time.h or time.h" >&5 +printf %s "checking whether struct tm is in sys/time.h or time.h... " >&6; } +if test ${ac_cv_struct_tm+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +int +main (void) +{ +struct tm tm; + int *p = &tm.tm_sec; + return !p; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_struct_tm=time.h +else $as_nop + ac_cv_struct_tm=sys/time.h fi -done +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_struct_tm" >&5 +printf "%s\n" "$ac_cv_struct_tm" >&6; } +if test $ac_cv_struct_tm = sys/time.h; then +printf "%s\n" "#define TM_IN_SYS_TIME 1" >>confdefs.h fi +ac_fn_c_check_member "$LINENO" "struct tm" "tm_zone" "ac_cv_member_struct_tm_tm_zone" "#include +#include <$ac_cv_struct_tm> +" +if test "x$ac_cv_member_struct_tm_tm_zone" = xyes +then : +printf "%s\n" "#define HAVE_STRUCT_TM_TM_ZONE 1" >>confdefs.h +fi +if test "$ac_cv_member_struct_tm_tm_zone" = yes; then -# checks for system services -# (none yet) - -# Linux requires this for correct f.p. operations -ac_fn_c_check_func "$LINENO" "__fpu_control" "ac_cv_func___fpu_control" -if test "x$ac_cv_func___fpu_control" = xyes; then : +printf "%s\n" "#define HAVE_TM_ZONE 1" >>confdefs.h else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __fpu_control in -lieee" >&5 -$as_echo_n "checking for __fpu_control in -lieee... " >&6; } -if ${ac_cv_lib_ieee___fpu_control+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lieee $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ + ac_fn_check_decl "$LINENO" "tzname" "ac_cv_have_decl_tzname" "#include +" "$ac_c_undeclared_builtin_options" "CFLAGS" +if test "x$ac_cv_have_decl_tzname" = xyes +then : + ac_have_decl=1 +else $as_nop + ac_have_decl=0 +fi +printf "%s\n" "#define HAVE_DECL_TZNAME $ac_have_decl" >>confdefs.h -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for tzname" >&5 +printf %s "checking for tzname... " >&6; } +if test ${ac_cv_var_tzname+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#if !HAVE_DECL_TZNAME +extern char *tzname[]; #endif -char __fpu_control (); + int -main () +main (void) { -return __fpu_control (); +return tzname[0][0]; ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_ieee___fpu_control=yes -else - ac_cv_lib_ieee___fpu_control=no +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_var_tzname=yes +else $as_nop + ac_cv_var_tzname=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ieee___fpu_control" >&5 -$as_echo "$ac_cv_lib_ieee___fpu_control" >&6; } -if test "x$ac_cv_lib_ieee___fpu_control" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBIEEE 1 -_ACEOF +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_var_tzname" >&5 +printf "%s\n" "$ac_cv_var_tzname" >&6; } + if test $ac_cv_var_tzname = yes; then - LIBS="-lieee $LIBS" +printf "%s\n" "#define HAVE_TZNAME 1" >>confdefs.h + fi fi +ac_fn_c_check_member "$LINENO" "struct stat" "st_rdev" "ac_cv_member_struct_stat_st_rdev" "$ac_includes_default" +if test "x$ac_cv_member_struct_stat_st_rdev" = xyes +then : + +printf "%s\n" "#define HAVE_STRUCT_STAT_ST_RDEV 1" >>confdefs.h + fi +ac_fn_c_check_member "$LINENO" "struct stat" "st_blksize" "ac_cv_member_struct_stat_st_blksize" "$ac_includes_default" +if test "x$ac_cv_member_struct_stat_st_blksize" = xyes +then : -# check for --with-libm=... +printf "%s\n" "#define HAVE_STRUCT_STAT_ST_BLKSIZE 1" >>confdefs.h -case $ac_sys_system in -Darwin) ;; -*) LIBM=-lm -esac -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-libm=STRING" >&5 -$as_echo_n "checking for --with-libm=STRING... " >&6; } -# Check whether --with-libm was given. -if test "${with_libm+set}" = set; then : - withval=$with_libm; -if test "$withval" = no -then LIBM= - { $as_echo "$as_me:${as_lineno-$LINENO}: result: force LIBM empty" >&5 -$as_echo "force LIBM empty" >&6; } -elif test "$withval" != yes -then LIBM=$withval - { $as_echo "$as_me:${as_lineno-$LINENO}: result: set LIBM=\"$withval\"" >&5 -$as_echo "set LIBM=\"$withval\"" >&6; } -else as_fn_error $? "proper usage is --with-libm=STRING" "$LINENO" 5 -fi -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: default LIBM=\"$LIBM\"" >&5 -$as_echo "default LIBM=\"$LIBM\"" >&6; } fi +ac_fn_c_check_member "$LINENO" "struct stat" "st_flags" "ac_cv_member_struct_stat_st_flags" "$ac_includes_default" +if test "x$ac_cv_member_struct_stat_st_flags" = xyes +then : -# check for --with-libc=... +printf "%s\n" "#define HAVE_STRUCT_STAT_ST_FLAGS 1" >>confdefs.h -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-libc=STRING" >&5 -$as_echo_n "checking for --with-libc=STRING... " >&6; } -# Check whether --with-libc was given. -if test "${with_libc+set}" = set; then : - withval=$with_libc; -if test "$withval" = no -then LIBC= - { $as_echo "$as_me:${as_lineno-$LINENO}: result: force LIBC empty" >&5 -$as_echo "force LIBC empty" >&6; } -elif test "$withval" != yes -then LIBC=$withval - { $as_echo "$as_me:${as_lineno-$LINENO}: result: set LIBC=\"$withval\"" >&5 -$as_echo "set LIBC=\"$withval\"" >&6; } -else as_fn_error $? "proper usage is --with-libc=STRING" "$LINENO" 5 -fi -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: default LIBC=\"$LIBC\"" >&5 -$as_echo "default LIBC=\"$LIBC\"" >&6; } fi +ac_fn_c_check_member "$LINENO" "struct stat" "st_gen" "ac_cv_member_struct_stat_st_gen" "$ac_includes_default" +if test "x$ac_cv_member_struct_stat_st_gen" = xyes +then : -# ************************************** -# * Check for gcc x64 inline assembler * -# ************************************** - +printf "%s\n" "#define HAVE_STRUCT_STAT_ST_GEN 1" >>confdefs.h -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for x64 gcc inline assembler" >&5 -$as_echo_n "checking for x64 gcc inline assembler... " >&6; } -if ${ac_cv_gcc_asm_for_x64+:} false; then : - $as_echo_n "(cached) " >&6 -else -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ +fi -int -main () -{ +ac_fn_c_check_member "$LINENO" "struct stat" "st_birthtime" "ac_cv_member_struct_stat_st_birthtime" "$ac_includes_default" +if test "x$ac_cv_member_struct_stat_st_birthtime" = xyes +then : - __asm__ __volatile__ ("movq %rcx, %rax"); +printf "%s\n" "#define HAVE_STRUCT_STAT_ST_BIRTHTIME 1" >>confdefs.h - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_gcc_asm_for_x64=yes -else - ac_cv_gcc_asm_for_x64=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_gcc_asm_for_x64" >&5 -$as_echo "$ac_cv_gcc_asm_for_x64" >&6; } - -if test "x$ac_cv_gcc_asm_for_x64" = xyes; then : +ac_fn_c_check_member "$LINENO" "struct stat" "st_blocks" "ac_cv_member_struct_stat_st_blocks" "$ac_includes_default" +if test "x$ac_cv_member_struct_stat_st_blocks" = xyes +then : -$as_echo "#define HAVE_GCC_ASM_FOR_X64 1" >>confdefs.h +printf "%s\n" "#define HAVE_STRUCT_STAT_ST_BLOCKS 1" >>confdefs.h fi -# ************************************************** -# * Check for various properties of floating point * -# ************************************************** - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether float word ordering is bigendian" >&5 -$as_echo_n "checking whether float word ordering is bigendian... " >&6; } -if ${ax_cv_c_float_words_bigendian+:} false; then : - $as_echo_n "(cached) " >&6 -else +ac_fn_c_check_member "$LINENO" "struct passwd" "pw_gecos" "ac_cv_member_struct_passwd_pw_gecos" " + #include + #include +" +if test "x$ac_cv_member_struct_passwd_pw_gecos" = xyes +then : -ax_cv_c_float_words_bigendian=unknown -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ +printf "%s\n" "#define HAVE_STRUCT_PASSWD_PW_GECOS 1" >>confdefs.h -double d = 90904234967036810337470478905505011476211692735615632014797120844053488865816695273723469097858056257517020191247487429516932130503560650002327564517570778480236724525140520121371739201496540132640109977779420565776568942592.0; +fi +ac_fn_c_check_member "$LINENO" "struct passwd" "pw_passwd" "ac_cv_member_struct_passwd_pw_passwd" " + #include + #include +" +if test "x$ac_cv_member_struct_passwd_pw_passwd" = xyes +then : -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +printf "%s\n" "#define HAVE_STRUCT_PASSWD_PW_PASSWD 1" >>confdefs.h -if grep noonsees conftest.$ac_objext >/dev/null ; then - ax_cv_c_float_words_bigendian=yes -fi -if grep seesnoon conftest.$ac_objext >/dev/null ; then - if test "$ax_cv_c_float_words_bigendian" = unknown; then - ax_cv_c_float_words_bigendian=no - else - ax_cv_c_float_words_bigendian=unknown - fi fi +# Issue #21085: In Cygwin, siginfo_t does not have si_band field. +ac_fn_c_check_member "$LINENO" "siginfo_t" "si_band" "ac_cv_member_siginfo_t_si_band" "#include +" +if test "x$ac_cv_member_siginfo_t_si_band" = xyes +then : + +printf "%s\n" "#define HAVE_SIGINFO_T_SI_BAND 1" >>confdefs.h + fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_c_float_words_bigendian" >&5 -$as_echo "$ax_cv_c_float_words_bigendian" >&6; } -case $ax_cv_c_float_words_bigendian in - yes) -$as_echo "#define FLOAT_WORDS_BIGENDIAN 1" >>confdefs.h - ;; - no) - ;; - *) - as_fn_error $? " +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for time.h that defines altzone" >&5 +printf %s "checking for time.h that defines altzone... " >&6; } +if test ${ac_cv_header_time_altzone+y} +then : + printf %s "(cached) " >&6 +else $as_nop -Unknown float word ordering. You need to manually preset -ax_cv_c_float_words_bigendian=no (or yes) according to your system. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main (void) +{ +return altzone; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_header_time_altzone=yes +else $as_nop + ac_cv_header_time_altzone=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext - " "$LINENO" 5 ;; -esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_time_altzone" >&5 +printf "%s\n" "$ac_cv_header_time_altzone" >&6; } +if test $ac_cv_header_time_altzone = yes; then +printf "%s\n" "#define HAVE_ALTZONE 1" >>confdefs.h -if test "$ax_cv_c_float_words_bigendian" = "yes" -then +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for addrinfo" >&5 +printf %s "checking for addrinfo... " >&6; } +if test ${ac_cv_struct_addrinfo+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main (void) +{ +struct addrinfo a + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_struct_addrinfo=yes +else $as_nop + ac_cv_struct_addrinfo=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_struct_addrinfo" >&5 +printf "%s\n" "$ac_cv_struct_addrinfo" >&6; } +if test $ac_cv_struct_addrinfo = yes; then -$as_echo "#define DOUBLE_IS_BIG_ENDIAN_IEEE754 1" >>confdefs.h +printf "%s\n" "#define HAVE_ADDRINFO 1" >>confdefs.h -elif test "$ax_cv_c_float_words_bigendian" = "no" -then +fi -$as_echo "#define DOUBLE_IS_LITTLE_ENDIAN_IEEE754 1" >>confdefs.h +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sockaddr_storage" >&5 +printf %s "checking for sockaddr_storage... " >&6; } +if test ${ac_cv_struct_sockaddr_storage+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ -else - # Some ARM platforms use a mixed-endian representation for doubles. - # While Python doesn't currently have full support for these platforms - # (see e.g., issue 1762561), we can at least make sure that float <-> string - # conversions work. - # FLOAT_WORDS_BIGENDIAN doesnt actually detect this case, but if it's not big - # or little, then it must be this? +# include +# include +int +main (void) +{ +struct sockaddr_storage s + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_struct_sockaddr_storage=yes +else $as_nop + ac_cv_struct_sockaddr_storage=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_struct_sockaddr_storage" >&5 +printf "%s\n" "$ac_cv_struct_sockaddr_storage" >&6; } +if test $ac_cv_struct_sockaddr_storage = yes; then -$as_echo "#define DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754 1" >>confdefs.h +printf "%s\n" "#define HAVE_SOCKADDR_STORAGE 1" >>confdefs.h fi -# The short float repr introduced in Python 3.1 requires the -# correctly-rounded string <-> double conversion functions from -# Python/dtoa.c, which in turn require that the FPU uses 53-bit -# rounding; this is a problem on x86, where the x87 FPU has a default -# rounding precision of 64 bits. For gcc/x86, we can fix this by -# using inline assembler to get and set the x87 FPU control word. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sockaddr_alg" >&5 +printf %s "checking for sockaddr_alg... " >&6; } +if test ${ac_cv_struct_sockaddr_alg+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ -# This inline assembler syntax may also work for suncc and icc, -# so we try it on all platforms. +# include +# include +# include +int +main (void) +{ +struct sockaddr_alg s + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_struct_sockaddr_alg=yes +else $as_nop + ac_cv_struct_sockaddr_alg=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_struct_sockaddr_alg" >&5 +printf "%s\n" "$ac_cv_struct_sockaddr_alg" >&6; } +if test $ac_cv_struct_sockaddr_alg = yes; then -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we can use gcc inline assembler to get and set x87 control word" >&5 -$as_echo_n "checking whether we can use gcc inline assembler to get and set x87 control word... " >&6; } -if ${ac_cv_gcc_asm_for_x87+:} false; then : - $as_echo_n "(cached) " >&6 -else +printf "%s\n" "#define HAVE_SOCKADDR_ALG 1" >>confdefs.h -cat confdefs.h - <<_ACEOF >conftest.$ac_ext +fi + +# checks for compiler characteristics + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 +printf %s "checking for an ANSI C-conforming const... " >&6; } +if test ${ac_cv_c_const+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int -main () +main (void) { - unsigned short cw; - __asm__ __volatile__ ("fnstcw %0" : "=m" (cw)); - __asm__ __volatile__ ("fldcw %0" : : "m" (cw)); +#ifndef __cplusplus + /* Ultrix mips cc rejects this sort of thing. */ + typedef int charset[2]; + const charset cs = { 0, 0 }; + /* SunOS 4.1.1 cc rejects this. */ + char const *const *pcpcc; + char **ppc; + /* NEC SVR4.0.2 mips cc rejects this. */ + struct point {int x, y;}; + static struct point const zero = {0,0}; + /* IBM XL C 1.02.0.0 rejects this. + It does not let you subtract one const X* pointer from another in + an arm of an if-expression whose if-part is not a constant + expression */ + const char *g = "string"; + pcpcc = &g + (g ? g-g : 0); + /* HPUX 7.0 cc rejects these. */ + ++pcpcc; + ppc = (char**) pcpcc; + pcpcc = (char const *const *) ppc; + { /* SCO 3.2v4 cc rejects this sort of thing. */ + char tx; + char *t = &tx; + char const *s = 0 ? (char *) 0 : (char const *) 0; + + *t++ = 0; + if (s) return 0; + } + { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ + int x[] = {25, 17}; + const int *foo = &x[0]; + ++foo; + } + { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ + typedef const int *iptr; + iptr p = 0; + ++p; + } + { /* IBM XL C 1.02.0.0 rejects this sort of thing, saying + "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ + struct s { int j; const int *ap[3]; } bx; + struct s *b = &bx; b->j = 5; + } + { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; + if (!foo) return 0; + } + return !cs[0] && !zero.x; +#endif ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_gcc_asm_for_x87=yes -else - ac_cv_gcc_asm_for_x87=no +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_c_const=yes +else $as_nop + ac_cv_c_const=no fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_gcc_asm_for_x87" >&5 -$as_echo "$ac_cv_gcc_asm_for_x87" >&6; } -if test "x$ac_cv_gcc_asm_for_x87" = xyes; then : - - -$as_echo "#define HAVE_GCC_ASM_FOR_X87 1" >>confdefs.h +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 +printf "%s\n" "$ac_cv_c_const" >&6; } +if test $ac_cv_c_const = no; then +printf "%s\n" "#define const /**/" >>confdefs.h fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we can use gcc inline assembler to get and set mc68881 fpcr" >&5 -$as_echo_n "checking whether we can use gcc inline assembler to get and set mc68881 fpcr... " >&6; } -if ${ac_cv_gcc_asm_for_mc68881+:} false; then : - $as_echo_n "(cached) " >&6 -else + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for working signed char" >&5 +printf %s "checking for working signed char... " >&6; } +if test ${ac_cv_working_signed_char_c+y} +then : + printf %s "(cached) " >&6 +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int -main () +main (void) { - - unsigned int fpcr; - __asm__ __volatile__ ("fmove.l %%fpcr,%0" : "=g" (fpcr)); - __asm__ __volatile__ ("fmove.l %0,%%fpcr" : : "g" (fpcr)); - +signed char c; ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_gcc_asm_for_mc68881=yes -else - ac_cv_gcc_asm_for_mc68881=no +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_working_signed_char_c=yes +else $as_nop + ac_cv_working_signed_char_c=no fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_gcc_asm_for_mc68881" >&5 -$as_echo "$ac_cv_gcc_asm_for_mc68881" >&6; } -if test "x$ac_cv_gcc_asm_for_mc68881" = xyes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_working_signed_char_c" >&5 +printf "%s\n" "$ac_cv_working_signed_char_c" >&6; } +if test "x$ac_cv_working_signed_char_c" = xno +then : -$as_echo "#define HAVE_GCC_ASM_FOR_MC68881 1" >>confdefs.h +printf "%s\n" "#define signed /**/" >>confdefs.h fi -# Detect whether system arithmetic is subject to x87-style double -# rounding issues. The result of this test has little meaning on non -# IEEE 754 platforms. On IEEE 754, test should return 1 if rounding -# mode is round-to-nearest and double rounding issues are present, and -# 0 otherwise. See https://github.com/python/cpython/issues/47186 for more info. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for x87-style double rounding" >&5 -$as_echo_n "checking for x87-style double rounding... " >&6; } -if ${ac_cv_x87_double_rounding+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for prototypes" >&5 +printf %s "checking for prototypes... " >&6; } +if test ${ac_cv_function_prototypes+y} +then : + printf %s "(cached) " >&6 +else $as_nop -# $BASECFLAGS may affect the result -ac_save_cc="$CC" -CC="$CC $BASECFLAGS" -if test "$cross_compiling" = yes; then : - ac_cv_x87_double_rounding=no -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext +cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - -#include -#include -int main(void) { - volatile double x, y, z; - /* 1./(1-2**-53) -> 1+2**-52 (correct), 1.0 (double rounding) */ - x = 0.99999999999999989; /* 1-2**-53 */ - y = 1./x; - if (y != 1.) - exit(0); - /* 1e16+2.99999 -> 1e16+2. (correct), 1e16+4. (double rounding) */ - x = 1e16; - y = 2.99999; - z = x + y; - if (z != 1e16+4.) - exit(0); - /* both tests show evidence of double rounding */ - exit(1); +int foo(int x) { return 0; } +int +main (void) +{ +return foo(10); + ; + return 0; } - _ACEOF -if ac_fn_c_try_run "$LINENO"; then : - ac_cv_x87_double_rounding=no -else - ac_cv_x87_double_rounding=yes +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_function_prototypes=yes +else $as_nop + ac_cv_function_prototypes=no fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_function_prototypes" >&5 +printf "%s\n" "$ac_cv_function_prototypes" >&6; } +if test "x$ac_cv_function_prototypes" = xyes +then : -CC="$ac_save_cc" -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_x87_double_rounding" >&5 -$as_echo "$ac_cv_x87_double_rounding" >&6; } +printf "%s\n" "#define HAVE_PROTOTYPES 1" >>confdefs.h -if test "x$ac_cv_x87_double_rounding" = xyes; then : +fi -$as_echo "#define X87_DOUBLE_ROUNDING 1" >>confdefs.h +# check for socketpair -fi -# ************************************ -# * Check for mathematical functions * -# ************************************ + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for socketpair" >&5 +printf %s "checking for socketpair... " >&6; } +if test ${ac_cv_func_socketpair+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ -LIBS_SAVE=$LIBS -LIBS="$LIBS $LIBM" +#include +#include -for ac_func in acosh asinh atanh erf erfc expm1 log1p log2 -do : - as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` -ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -if eval test \"x\$"$as_ac_var"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +int +main (void) +{ +void *x=socketpair + ; + return 0; +} _ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_func_socketpair=yes +else $as_nop + ac_cv_func_socketpair=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext -else - as_fn_error $? "Python requires C99 compatible libm" "$LINENO" 5 +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_socketpair" >&5 +printf "%s\n" "$ac_cv_func_socketpair" >&6; } + if test "x$ac_cv_func_socketpair" = xyes +then : + +printf "%s\n" "#define HAVE_SOCKETPAIR 1" >>confdefs.h fi -done -LIBS=$LIBS_SAVE -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether POSIX semaphores are enabled" >&5 -$as_echo_n "checking whether POSIX semaphores are enabled... " >&6; } -if ${ac_cv_posix_semaphores_enabled+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "$cross_compiling" = yes; then : - ac_cv_posix_semaphores_enabled=yes -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - #include - #include - #include - #include - #include - - int main(void) { - sem_t *a = sem_open("/autoconf", O_CREAT, S_IRUSR|S_IWUSR, 0); - if (a == SEM_FAILED) { - perror("sem_open"); - return 1; - } - sem_close(a); - sem_unlink("/autoconf"); - return 0; - } - +# check if sockaddr has sa_len member +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if sockaddr has sa_len member" >&5 +printf %s "checking if sockaddr has sa_len member... " >&6; } +if test ${ac_cv_struct_sockaddr_sa_len+y} +then : + printf %s "(cached) " >&6 +else $as_nop +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +int +main (void) +{ +struct sockaddr x; +x.sa_len = 0; + ; + return 0; +} _ACEOF -if ac_fn_c_try_run "$LINENO"; then : - ac_cv_posix_semaphores_enabled=yes -else - ac_cv_posix_semaphores_enabled=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_struct_sockaddr_sa_len=yes +else $as_nop + ac_cv_struct_sockaddr_sa_len=no fi - +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_posix_semaphores_enabled" >&5 -$as_echo "$ac_cv_posix_semaphores_enabled" >&6; } -if test "x$ac_cv_posix_semaphores_enabled" = xno; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_struct_sockaddr_sa_len" >&5 +printf "%s\n" "$ac_cv_struct_sockaddr_sa_len" >&6; } +if test "x$ac_cv_struct_sockaddr_sa_len" = xyes +then : -$as_echo "#define POSIX_SEMAPHORES_NOT_ENABLED 1" >>confdefs.h +printf "%s\n" "#define HAVE_SOCKADDR_SA_LEN 1" >>confdefs.h fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for broken sem_getvalue" >&5 -$as_echo_n "checking for broken sem_getvalue... " >&6; } -if ${ac_cv_broken_sem_getvalue+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "$cross_compiling" = yes; then : - ac_cv_broken_sem_getvalue=yes -else +# sigh -- gethostbyname_r is a mess; it can have 3, 5 or 6 arguments :-( + + +ac_fn_c_check_func "$LINENO" "gethostbyname_r" "ac_cv_func_gethostbyname_r" +if test "x$ac_cv_func_gethostbyname_r" = xyes +then : + printf "%s\n" "#define HAVE_GETHOSTBYNAME_R 1" >>confdefs.h + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking gethostbyname_r with 6 args" >&5 +printf %s "checking gethostbyname_r with 6 args... " >&6; } + OLD_CFLAGS=$CFLAGS + CFLAGS="$CFLAGS $MY_CPPFLAGS $MY_THREAD_CPPFLAGS $MY_CFLAGS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ +# include - #include - #include - #include - #include - #include - - int main(void){ - sem_t *a = sem_open("/autocftw", O_CREAT, S_IRUSR|S_IWUSR, 0); - int count; - int res; - if(a==SEM_FAILED){ - perror("sem_open"); - return 1; +int +main (void) +{ - } - res = sem_getvalue(a, &count); - sem_close(a); - sem_unlink("/autocftw"); - return res==-1 ? 1 : 0; - } + char *name; + struct hostent *he, *res; + char buffer[2048]; + int buflen = 2048; + int h_errnop; + (void) gethostbyname_r(name, he, buffer, buflen, &res, &h_errnop) + ; + return 0; +} _ACEOF -if ac_fn_c_try_run "$LINENO"; then : - ac_cv_broken_sem_getvalue=no -else - ac_cv_broken_sem_getvalue=yes -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi +if ac_fn_c_try_compile "$LINENO" +then : + printf "%s\n" "#define HAVE_GETHOSTBYNAME_R 1" >>confdefs.h -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_broken_sem_getvalue" >&5 -$as_echo "$ac_cv_broken_sem_getvalue" >&6; } -if test "x$ac_cv_broken_sem_getvalue" = xyes; then : +printf "%s\n" "#define HAVE_GETHOSTBYNAME_R_6_ARG 1" >>confdefs.h -$as_echo "#define HAVE_BROKEN_SEM_GETVALUE 1" >>confdefs.h + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +else $as_nop -fi + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking gethostbyname_r with 5 args" >&5 +printf %s "checking gethostbyname_r with 5 args... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ -ac_fn_c_check_decl "$LINENO" "RTLD_LAZY" "ac_cv_have_decl_RTLD_LAZY" "#include -" -if test "x$ac_cv_have_decl_RTLD_LAZY" = xyes; then : - ac_have_decl=1 -else - ac_have_decl=0 -fi +# include -cat >>confdefs.h <<_ACEOF -#define HAVE_DECL_RTLD_LAZY $ac_have_decl -_ACEOF -ac_fn_c_check_decl "$LINENO" "RTLD_NOW" "ac_cv_have_decl_RTLD_NOW" "#include -" -if test "x$ac_cv_have_decl_RTLD_NOW" = xyes; then : - ac_have_decl=1 -else - ac_have_decl=0 -fi +int +main (void) +{ -cat >>confdefs.h <<_ACEOF -#define HAVE_DECL_RTLD_NOW $ac_have_decl -_ACEOF -ac_fn_c_check_decl "$LINENO" "RTLD_GLOBAL" "ac_cv_have_decl_RTLD_GLOBAL" "#include -" -if test "x$ac_cv_have_decl_RTLD_GLOBAL" = xyes; then : - ac_have_decl=1 -else - ac_have_decl=0 -fi + char *name; + struct hostent *he; + char buffer[2048]; + int buflen = 2048; + int h_errnop; -cat >>confdefs.h <<_ACEOF -#define HAVE_DECL_RTLD_GLOBAL $ac_have_decl -_ACEOF -ac_fn_c_check_decl "$LINENO" "RTLD_LOCAL" "ac_cv_have_decl_RTLD_LOCAL" "#include -" -if test "x$ac_cv_have_decl_RTLD_LOCAL" = xyes; then : - ac_have_decl=1 -else - ac_have_decl=0 -fi + (void) gethostbyname_r(name, he, buffer, buflen, &h_errnop) -cat >>confdefs.h <<_ACEOF -#define HAVE_DECL_RTLD_LOCAL $ac_have_decl + ; + return 0; +} _ACEOF -ac_fn_c_check_decl "$LINENO" "RTLD_NODELETE" "ac_cv_have_decl_RTLD_NODELETE" "#include -" -if test "x$ac_cv_have_decl_RTLD_NODELETE" = xyes; then : - ac_have_decl=1 -else - ac_have_decl=0 -fi +if ac_fn_c_try_compile "$LINENO" +then : -cat >>confdefs.h <<_ACEOF -#define HAVE_DECL_RTLD_NODELETE $ac_have_decl -_ACEOF -ac_fn_c_check_decl "$LINENO" "RTLD_NOLOAD" "ac_cv_have_decl_RTLD_NOLOAD" "#include -" -if test "x$ac_cv_have_decl_RTLD_NOLOAD" = xyes; then : - ac_have_decl=1 -else - ac_have_decl=0 -fi + printf "%s\n" "#define HAVE_GETHOSTBYNAME_R 1" >>confdefs.h -cat >>confdefs.h <<_ACEOF -#define HAVE_DECL_RTLD_NOLOAD $ac_have_decl -_ACEOF -ac_fn_c_check_decl "$LINENO" "RTLD_DEEPBIND" "ac_cv_have_decl_RTLD_DEEPBIND" "#include -" -if test "x$ac_cv_have_decl_RTLD_DEEPBIND" = xyes; then : - ac_have_decl=1 -else - ac_have_decl=0 -fi -cat >>confdefs.h <<_ACEOF -#define HAVE_DECL_RTLD_DEEPBIND $ac_have_decl -_ACEOF -ac_fn_c_check_decl "$LINENO" "RTLD_MEMBER" "ac_cv_have_decl_RTLD_MEMBER" "#include -" -if test "x$ac_cv_have_decl_RTLD_MEMBER" = xyes; then : - ac_have_decl=1 -else - ac_have_decl=0 -fi +printf "%s\n" "#define HAVE_GETHOSTBYNAME_R_5_ARG 1" >>confdefs.h -cat >>confdefs.h <<_ACEOF -#define HAVE_DECL_RTLD_MEMBER $ac_have_decl -_ACEOF + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +else $as_nop -# determine what size digit to use for Python's longs -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking digit size for Python's longs" >&5 -$as_echo_n "checking digit size for Python's longs... " >&6; } -# Check whether --enable-big-digits was given. -if test "${enable_big_digits+set}" = set; then : - enableval=$enable_big_digits; case $enable_big_digits in -yes) - enable_big_digits=30 ;; -no) - enable_big_digits=15 ;; -15|30) - ;; -*) - as_fn_error $? "bad value $enable_big_digits for --enable-big-digits; value should be 15 or 30" "$LINENO" 5 ;; -esac -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_big_digits" >&5 -$as_echo "$enable_big_digits" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking gethostbyname_r with 3 args" >&5 +printf %s "checking gethostbyname_r with 3 args... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ -cat >>confdefs.h <<_ACEOF -#define PYLONG_BITS_IN_DIGIT $enable_big_digits -_ACEOF +# include +int +main (void) +{ -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no value specified" >&5 -$as_echo "no value specified" >&6; } -fi + char *name; + struct hostent *he; + struct hostent_data data; + (void) gethostbyname_r(name, he, &data); -# check for wchar.h -ac_fn_c_check_header_mongrel "$LINENO" "wchar.h" "ac_cv_header_wchar_h" "$ac_includes_default" -if test "x$ac_cv_header_wchar_h" = xyes; then : + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + printf "%s\n" "#define HAVE_GETHOSTBYNAME_R 1" >>confdefs.h -$as_echo "#define HAVE_WCHAR_H 1" >>confdefs.h - wchar_h="yes" +printf "%s\n" "#define HAVE_GETHOSTBYNAME_R_3_ARG 1" >>confdefs.h -else - wchar_h="no" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + +else $as_nop + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + CFLAGS=$OLD_CFLAGS -# determine wchar_t size -if test "$wchar_h" = yes -then - # The cast to long int works around a bug in the HP C Compiler -# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects -# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. -# This bug is HP SR number 8606223364. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of wchar_t" >&5 -$as_echo_n "checking size of wchar_t... " >&6; } -if ${ac_cv_sizeof_wchar_t+:} false; then : - $as_echo_n "(cached) " >&6 -else - if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (wchar_t))" "ac_cv_sizeof_wchar_t" "#include -"; then : +else $as_nop + + ac_fn_c_check_func "$LINENO" "gethostbyname" "ac_cv_func_gethostbyname" +if test "x$ac_cv_func_gethostbyname" = xyes +then : + printf "%s\n" "#define HAVE_GETHOSTBYNAME 1" >>confdefs.h -else - if test "$ac_cv_type_wchar_t" = yes; then - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "cannot compute sizeof (wchar_t) -See \`config.log' for more details" "$LINENO" 5; } - else - ac_cv_sizeof_wchar_t=0 - fi fi + fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_wchar_t" >&5 -$as_echo "$ac_cv_sizeof_wchar_t" >&6; } -cat >>confdefs.h <<_ACEOF -#define SIZEOF_WCHAR_T $ac_cv_sizeof_wchar_t -_ACEOF -fi -# check whether wchar_t is signed or not -if test "$wchar_h" = yes -then - # check whether wchar_t is signed or not - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether wchar_t is signed" >&5 -$as_echo_n "checking whether wchar_t is signed... " >&6; } -if ${ac_cv_wchar_t_signed+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "$cross_compiling" = yes; then : - ac_cv_wchar_t_signed=yes -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ +# checks for system services +# (none yet) - #include - int main() - { - /* Success: exit code 0 */ - return ((((wchar_t) -1) < ((wchar_t) 0)) ? 0 : 1); - } +# Linux requires this for correct f.p. operations +ac_fn_c_check_func "$LINENO" "__fpu_control" "ac_cv_func___fpu_control" +if test "x$ac_cv_func___fpu_control" = xyes +then : + +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for __fpu_control in -lieee" >&5 +printf %s "checking for __fpu_control in -lieee... " >&6; } +if test ${ac_cv_lib_ieee___fpu_control+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_check_lib_save_LIBS=$LIBS +LIBS="-lieee $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char __fpu_control (); +int +main (void) +{ +return __fpu_control (); + ; + return 0; +} _ACEOF -if ac_fn_c_try_run "$LINENO"; then : - ac_cv_wchar_t_signed=yes -else - ac_cv_wchar_t_signed=no +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_ieee___fpu_control=yes +else $as_nop + ac_cv_lib_ieee___fpu_control=no fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ieee___fpu_control" >&5 +printf "%s\n" "$ac_cv_lib_ieee___fpu_control" >&6; } +if test "x$ac_cv_lib_ieee___fpu_control" = xyes +then : + printf "%s\n" "#define HAVE_LIBIEEE 1" >>confdefs.h -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_wchar_t_signed" >&5 -$as_echo "$ac_cv_wchar_t_signed" >&6; } -fi + LIBS="-lieee $LIBS" -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether wchar_t is usable" >&5 -$as_echo_n "checking whether wchar_t is usable... " >&6; } -# wchar_t is only usable if it maps to an unsigned type -if test "$ac_cv_sizeof_wchar_t" -ge 2 \ - -a "$ac_cv_wchar_t_signed" = "no" -then +fi -$as_echo "#define HAVE_USABLE_WCHAR_T 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 -case $ac_sys_system/$ac_sys_release in -SunOS/*) + +# check for --with-libm=... + +case $ac_sys_system in +Darwin) ;; +*) LIBM=-lm +esac +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-libm=STRING" >&5 +printf %s "checking for --with-libm=STRING... " >&6; } + +# Check whether --with-libm was given. +if test ${with_libm+y} +then : + withval=$with_libm; +if test "$withval" = no +then LIBM= + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: force LIBM empty" >&5 +printf "%s\n" "force LIBM empty" >&6; } +elif test "$withval" != yes +then LIBM=$withval + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: set LIBM=\"$withval\"" >&5 +printf "%s\n" "set LIBM=\"$withval\"" >&6; } +else as_fn_error $? "proper usage is --with-libm=STRING" "$LINENO" 5 +fi +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: default LIBM=\"$LIBM\"" >&5 +printf "%s\n" "default LIBM=\"$LIBM\"" >&6; } +fi + + +# check for --with-libc=... + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-libc=STRING" >&5 +printf %s "checking for --with-libc=STRING... " >&6; } + +# Check whether --with-libc was given. +if test ${with_libc+y} +then : + withval=$with_libc; +if test "$withval" = no +then LIBC= + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: force LIBC empty" >&5 +printf "%s\n" "force LIBC empty" >&6; } +elif test "$withval" != yes +then LIBC=$withval + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: set LIBC=\"$withval\"" >&5 +printf "%s\n" "set LIBC=\"$withval\"" >&6; } +else as_fn_error $? "proper usage is --with-libc=STRING" "$LINENO" 5 +fi +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: default LIBC=\"$LIBC\"" >&5 +printf "%s\n" "default LIBC=\"$LIBC\"" >&6; } +fi + + +# ************************************** +# * Check for gcc x64 inline assembler * +# ************************************** + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for x64 gcc inline assembler" >&5 +printf %s "checking for x64 gcc inline assembler... " >&6; } +if test ${ac_cv_gcc_asm_for_x64+y} +then : + printf %s "(cached) " >&6 +else $as_nop + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + __asm__ __volatile__ ("movq %rcx, %rax"); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_gcc_asm_for_x64=yes +else $as_nop + ac_cv_gcc_asm_for_x64=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_gcc_asm_for_x64" >&5 +printf "%s\n" "$ac_cv_gcc_asm_for_x64" >&6; } + +if test "x$ac_cv_gcc_asm_for_x64" = xyes +then : + + +printf "%s\n" "#define HAVE_GCC_ASM_FOR_X64 1" >>confdefs.h + + +fi + +# ************************************************** +# * Check for various properties of floating point * +# ************************************************** + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether float word ordering is bigendian" >&5 +printf %s "checking whether float word ordering is bigendian... " >&6; } +if test ${ax_cv_c_float_words_bigendian+y} +then : + printf %s "(cached) " >&6 +else $as_nop + + +ax_cv_c_float_words_bigendian=unknown +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +double d = 90904234967036810337470478905505011476211692735615632014797120844053488865816695273723469097858056257517020191247487429516932130503560650002327564517570778480236724525140520121371739201496540132640109977779420565776568942592.0; + + +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + + +if grep noonsees conftest.$ac_objext >/dev/null ; then + ax_cv_c_float_words_bigendian=yes +fi +if grep seesnoon conftest.$ac_objext >/dev/null ; then + if test "$ax_cv_c_float_words_bigendian" = unknown; then + ax_cv_c_float_words_bigendian=no + else + ax_cv_c_float_words_bigendian=unknown + fi +fi + + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_c_float_words_bigendian" >&5 +printf "%s\n" "$ax_cv_c_float_words_bigendian" >&6; } + +case $ax_cv_c_float_words_bigendian in + yes) + +printf "%s\n" "#define FLOAT_WORDS_BIGENDIAN 1" >>confdefs.h + ;; + no) + ;; + *) + as_fn_error $? " + +Unknown float word ordering. You need to manually preset +ax_cv_c_float_words_bigendian=no (or yes) according to your system. + + " "$LINENO" 5 ;; +esac + + +if test "$ax_cv_c_float_words_bigendian" = "yes" +then + +printf "%s\n" "#define DOUBLE_IS_BIG_ENDIAN_IEEE754 1" >>confdefs.h + +elif test "$ax_cv_c_float_words_bigendian" = "no" +then + +printf "%s\n" "#define DOUBLE_IS_LITTLE_ENDIAN_IEEE754 1" >>confdefs.h + +else + # Some ARM platforms use a mixed-endian representation for doubles. + # While Python doesn't currently have full support for these platforms + # (see e.g., issue 1762561), we can at least make sure that float <-> string + # conversions work. + # FLOAT_WORDS_BIGENDIAN doesnt actually detect this case, but if it's not big + # or little, then it must be this? + +printf "%s\n" "#define DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754 1" >>confdefs.h + +fi + +# The short float repr introduced in Python 3.1 requires the +# correctly-rounded string <-> double conversion functions from +# Python/dtoa.c, which in turn require that the FPU uses 53-bit +# rounding; this is a problem on x86, where the x87 FPU has a default +# rounding precision of 64 bits. For gcc/x86, we can fix this by +# using inline assembler to get and set the x87 FPU control word. + +# This inline assembler syntax may also work for suncc and icc, +# so we try it on all platforms. + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether we can use gcc inline assembler to get and set x87 control word" >&5 +printf %s "checking whether we can use gcc inline assembler to get and set x87 control word... " >&6; } +if test ${ac_cv_gcc_asm_for_x87+y} +then : + printf %s "(cached) " >&6 +else $as_nop + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + unsigned short cw; + __asm__ __volatile__ ("fnstcw %0" : "=m" (cw)); + __asm__ __volatile__ ("fldcw %0" : : "m" (cw)); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_gcc_asm_for_x87=yes +else $as_nop + ac_cv_gcc_asm_for_x87=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_gcc_asm_for_x87" >&5 +printf "%s\n" "$ac_cv_gcc_asm_for_x87" >&6; } +if test "x$ac_cv_gcc_asm_for_x87" = xyes +then : + + +printf "%s\n" "#define HAVE_GCC_ASM_FOR_X87 1" >>confdefs.h + + +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether we can use gcc inline assembler to get and set mc68881 fpcr" >&5 +printf %s "checking whether we can use gcc inline assembler to get and set mc68881 fpcr... " >&6; } +if test ${ac_cv_gcc_asm_for_mc68881+y} +then : + printf %s "(cached) " >&6 +else $as_nop + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + unsigned int fpcr; + __asm__ __volatile__ ("fmove.l %%fpcr,%0" : "=g" (fpcr)); + __asm__ __volatile__ ("fmove.l %0,%%fpcr" : : "g" (fpcr)); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_gcc_asm_for_mc68881=yes +else $as_nop + ac_cv_gcc_asm_for_mc68881=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_gcc_asm_for_mc68881" >&5 +printf "%s\n" "$ac_cv_gcc_asm_for_mc68881" >&6; } +if test "x$ac_cv_gcc_asm_for_mc68881" = xyes +then : + + +printf "%s\n" "#define HAVE_GCC_ASM_FOR_MC68881 1" >>confdefs.h + + +fi + +# Detect whether system arithmetic is subject to x87-style double +# rounding issues. The result of this test has little meaning on non +# IEEE 754 platforms. On IEEE 754, test should return 1 if rounding +# mode is round-to-nearest and double rounding issues are present, and +# 0 otherwise. See https://github.com/python/cpython/issues/47186 for more info. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for x87-style double rounding" >&5 +printf %s "checking for x87-style double rounding... " >&6; } +if test ${ac_cv_x87_double_rounding+y} +then : + printf %s "(cached) " >&6 +else $as_nop + +# $BASECFLAGS may affect the result +ac_save_cc="$CC" +CC="$CC $BASECFLAGS" +if test "$cross_compiling" = yes +then : + ac_cv_x87_double_rounding=no +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +int main(void) { + volatile double x, y, z; + /* 1./(1-2**-53) -> 1+2**-52 (correct), 1.0 (double rounding) */ + x = 0.99999999999999989; /* 1-2**-53 */ + y = 1./x; + if (y != 1.) + exit(0); + /* 1e16+2.99999 -> 1e16+2. (correct), 1e16+4. (double rounding) */ + x = 1e16; + y = 2.99999; + z = x + y; + if (z != 1e16+4.) + exit(0); + /* both tests show evidence of double rounding */ + exit(1); +} + +_ACEOF +if ac_fn_c_try_run "$LINENO" +then : + ac_cv_x87_double_rounding=no +else $as_nop + ac_cv_x87_double_rounding=yes +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +CC="$ac_save_cc" + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_x87_double_rounding" >&5 +printf "%s\n" "$ac_cv_x87_double_rounding" >&6; } + +if test "x$ac_cv_x87_double_rounding" = xyes +then : + + +printf "%s\n" "#define X87_DOUBLE_ROUNDING 1" >>confdefs.h + + +fi + +# ************************************ +# * Check for mathematical functions * +# ************************************ + +LIBS_SAVE=$LIBS +LIBS="$LIBS $LIBM" + + + for ac_func in acosh asinh atanh erf erfc expm1 log1p log2 +do : + as_ac_var=`printf "%s\n" "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes" +then : + cat >>confdefs.h <<_ACEOF +#define `printf "%s\n" "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +else $as_nop + as_fn_error $? "Python requires C99 compatible libm" "$LINENO" 5 + +fi + +done +LIBS=$LIBS_SAVE + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether POSIX semaphores are enabled" >&5 +printf %s "checking whether POSIX semaphores are enabled... " >&6; } +if test ${ac_cv_posix_semaphores_enabled+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test "$cross_compiling" = yes +then : + ac_cv_posix_semaphores_enabled=yes +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + + #include + #include + #include + #include + #include + + int main(void) { + sem_t *a = sem_open("/autoconf", O_CREAT, S_IRUSR|S_IWUSR, 0); + if (a == SEM_FAILED) { + perror("sem_open"); + return 1; + } + sem_close(a); + sem_unlink("/autoconf"); + return 0; + } + + +_ACEOF +if ac_fn_c_try_run "$LINENO" +then : + ac_cv_posix_semaphores_enabled=yes +else $as_nop + ac_cv_posix_semaphores_enabled=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_posix_semaphores_enabled" >&5 +printf "%s\n" "$ac_cv_posix_semaphores_enabled" >&6; } +if test "x$ac_cv_posix_semaphores_enabled" = xno +then : + + +printf "%s\n" "#define POSIX_SEMAPHORES_NOT_ENABLED 1" >>confdefs.h + + +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for broken sem_getvalue" >&5 +printf %s "checking for broken sem_getvalue... " >&6; } +if test ${ac_cv_broken_sem_getvalue+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test "$cross_compiling" = yes +then : + ac_cv_broken_sem_getvalue=yes +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + + #include + #include + #include + #include + #include + + int main(void){ + sem_t *a = sem_open("/autocftw", O_CREAT, S_IRUSR|S_IWUSR, 0); + int count; + int res; + if(a==SEM_FAILED){ + perror("sem_open"); + return 1; + + } + res = sem_getvalue(a, &count); + sem_close(a); + sem_unlink("/autocftw"); + return res==-1 ? 1 : 0; + } + + +_ACEOF +if ac_fn_c_try_run "$LINENO" +then : + ac_cv_broken_sem_getvalue=no +else $as_nop + ac_cv_broken_sem_getvalue=yes +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_broken_sem_getvalue" >&5 +printf "%s\n" "$ac_cv_broken_sem_getvalue" >&6; } +if test "x$ac_cv_broken_sem_getvalue" = xyes +then : + + +printf "%s\n" "#define HAVE_BROKEN_SEM_GETVALUE 1" >>confdefs.h + + +fi + +ac_fn_check_decl "$LINENO" "RTLD_LAZY" "ac_cv_have_decl_RTLD_LAZY" "#include +" "$ac_c_undeclared_builtin_options" "CFLAGS" +if test "x$ac_cv_have_decl_RTLD_LAZY" = xyes +then : + ac_have_decl=1 +else $as_nop + ac_have_decl=0 +fi +printf "%s\n" "#define HAVE_DECL_RTLD_LAZY $ac_have_decl" >>confdefs.h +ac_fn_check_decl "$LINENO" "RTLD_NOW" "ac_cv_have_decl_RTLD_NOW" "#include +" "$ac_c_undeclared_builtin_options" "CFLAGS" +if test "x$ac_cv_have_decl_RTLD_NOW" = xyes +then : + ac_have_decl=1 +else $as_nop + ac_have_decl=0 +fi +printf "%s\n" "#define HAVE_DECL_RTLD_NOW $ac_have_decl" >>confdefs.h +ac_fn_check_decl "$LINENO" "RTLD_GLOBAL" "ac_cv_have_decl_RTLD_GLOBAL" "#include +" "$ac_c_undeclared_builtin_options" "CFLAGS" +if test "x$ac_cv_have_decl_RTLD_GLOBAL" = xyes +then : + ac_have_decl=1 +else $as_nop + ac_have_decl=0 +fi +printf "%s\n" "#define HAVE_DECL_RTLD_GLOBAL $ac_have_decl" >>confdefs.h +ac_fn_check_decl "$LINENO" "RTLD_LOCAL" "ac_cv_have_decl_RTLD_LOCAL" "#include +" "$ac_c_undeclared_builtin_options" "CFLAGS" +if test "x$ac_cv_have_decl_RTLD_LOCAL" = xyes +then : + ac_have_decl=1 +else $as_nop + ac_have_decl=0 +fi +printf "%s\n" "#define HAVE_DECL_RTLD_LOCAL $ac_have_decl" >>confdefs.h +ac_fn_check_decl "$LINENO" "RTLD_NODELETE" "ac_cv_have_decl_RTLD_NODELETE" "#include +" "$ac_c_undeclared_builtin_options" "CFLAGS" +if test "x$ac_cv_have_decl_RTLD_NODELETE" = xyes +then : + ac_have_decl=1 +else $as_nop + ac_have_decl=0 +fi +printf "%s\n" "#define HAVE_DECL_RTLD_NODELETE $ac_have_decl" >>confdefs.h +ac_fn_check_decl "$LINENO" "RTLD_NOLOAD" "ac_cv_have_decl_RTLD_NOLOAD" "#include +" "$ac_c_undeclared_builtin_options" "CFLAGS" +if test "x$ac_cv_have_decl_RTLD_NOLOAD" = xyes +then : + ac_have_decl=1 +else $as_nop + ac_have_decl=0 +fi +printf "%s\n" "#define HAVE_DECL_RTLD_NOLOAD $ac_have_decl" >>confdefs.h +ac_fn_check_decl "$LINENO" "RTLD_DEEPBIND" "ac_cv_have_decl_RTLD_DEEPBIND" "#include +" "$ac_c_undeclared_builtin_options" "CFLAGS" +if test "x$ac_cv_have_decl_RTLD_DEEPBIND" = xyes +then : + ac_have_decl=1 +else $as_nop + ac_have_decl=0 +fi +printf "%s\n" "#define HAVE_DECL_RTLD_DEEPBIND $ac_have_decl" >>confdefs.h +ac_fn_check_decl "$LINENO" "RTLD_MEMBER" "ac_cv_have_decl_RTLD_MEMBER" "#include +" "$ac_c_undeclared_builtin_options" "CFLAGS" +if test "x$ac_cv_have_decl_RTLD_MEMBER" = xyes +then : + ac_have_decl=1 +else $as_nop + ac_have_decl=0 +fi +printf "%s\n" "#define HAVE_DECL_RTLD_MEMBER $ac_have_decl" >>confdefs.h + + +# determine what size digit to use for Python's longs +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking digit size for Python's longs" >&5 +printf %s "checking digit size for Python's longs... " >&6; } +# Check whether --enable-big-digits was given. +if test ${enable_big_digits+y} +then : + enableval=$enable_big_digits; case $enable_big_digits in +yes) + enable_big_digits=30 ;; +no) + enable_big_digits=15 ;; +15|30) + ;; +*) + as_fn_error $? "bad value $enable_big_digits for --enable-big-digits; value should be 15 or 30" "$LINENO" 5 ;; +esac +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_big_digits" >&5 +printf "%s\n" "$enable_big_digits" >&6; } + +printf "%s\n" "#define PYLONG_BITS_IN_DIGIT $enable_big_digits" >>confdefs.h + + +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no value specified" >&5 +printf "%s\n" "no value specified" >&6; } +fi + + +# check for wchar.h +ac_fn_c_check_header_compile "$LINENO" "wchar.h" "ac_cv_header_wchar_h" "$ac_includes_default" +if test "x$ac_cv_header_wchar_h" = xyes +then : + + +printf "%s\n" "#define HAVE_WCHAR_H 1" >>confdefs.h + + wchar_h="yes" + +else $as_nop + wchar_h="no" + +fi + + +# determine wchar_t size +if test "$wchar_h" = yes +then + # The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of wchar_t" >&5 +printf %s "checking size of wchar_t... " >&6; } +if test ${ac_cv_sizeof_wchar_t+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (wchar_t))" "ac_cv_sizeof_wchar_t" "#include +" +then : + +else $as_nop + if test "$ac_cv_type_wchar_t" = yes; then + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (wchar_t) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_wchar_t=0 + fi +fi + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_wchar_t" >&5 +printf "%s\n" "$ac_cv_sizeof_wchar_t" >&6; } + + + +printf "%s\n" "#define SIZEOF_WCHAR_T $ac_cv_sizeof_wchar_t" >>confdefs.h + + +fi + +# check whether wchar_t is signed or not +if test "$wchar_h" = yes +then + # check whether wchar_t is signed or not + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether wchar_t is signed" >&5 +printf %s "checking whether wchar_t is signed... " >&6; } +if test ${ac_cv_wchar_t_signed+y} +then : + printf %s "(cached) " >&6 +else $as_nop + + if test "$cross_compiling" = yes +then : + ac_cv_wchar_t_signed=yes +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include + int main() + { + /* Success: exit code 0 */ + return ((((wchar_t) -1) < ((wchar_t) 0)) ? 0 : 1); + } + +_ACEOF +if ac_fn_c_try_run "$LINENO" +then : + ac_cv_wchar_t_signed=yes +else $as_nop + ac_cv_wchar_t_signed=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_wchar_t_signed" >&5 +printf "%s\n" "$ac_cv_wchar_t_signed" >&6; } +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether wchar_t is usable" >&5 +printf %s "checking whether wchar_t is usable... " >&6; } +# wchar_t is only usable if it maps to an unsigned type +if test "$ac_cv_sizeof_wchar_t" -ge 2 \ + -a "$ac_cv_wchar_t_signed" = "no" +then + +printf "%s\n" "#define HAVE_USABLE_WCHAR_T 1" >>confdefs.h + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + +case $ac_sys_system/$ac_sys_release in +SunOS/*) if test -f /etc/os-release; then OS_NAME=$(awk -F= '/^NAME=/ {print substr($2,2,length($2)-2)}' /etc/os-release) if test "x$OS_NAME" = "xOracle Solaris"; then @@ -20457,1117 +24073,2457 @@ SunOS/*) # non-Unicode locales is not Unicode and hence cannot be used directly. # https://docs.oracle.com/cd/E37838_01/html/E61053/gmwke.html -$as_echo "#define HAVE_NON_UNICODE_WCHAR_T_REPRESENTATION 1" >>confdefs.h +printf "%s\n" "#define HAVE_NON_UNICODE_WCHAR_T_REPRESENTATION 1" >>confdefs.h + + fi + fi + ;; +esac + +# check for endianness + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5 +printf %s "checking whether byte ordering is bigendian... " >&6; } +if test ${ac_cv_c_bigendian+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_cv_c_bigendian=unknown + # See if we're dealing with a universal compiler. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifndef __APPLE_CC__ + not a universal capable compiler + #endif + typedef int dummy; + +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + + # Check for potential -arch flags. It is not universal unless + # there are at least two -arch flags with different values. + ac_arch= + ac_prev= + for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do + if test -n "$ac_prev"; then + case $ac_word in + i?86 | x86_64 | ppc | ppc64) + if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then + ac_arch=$ac_word + else + ac_cv_c_bigendian=universal + break + fi + ;; + esac + ac_prev= + elif test "x$ac_word" = "x-arch"; then + ac_prev=arch + fi + done +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + if test $ac_cv_c_bigendian = unknown; then + # See if sys/param.h defines the BYTE_ORDER macro. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + #include + +int +main (void) +{ +#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \ + && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \ + && LITTLE_ENDIAN) + bogus endian macros + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + # It does; now see whether it defined to BIG_ENDIAN or not. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + #include + +int +main (void) +{ +#if BYTE_ORDER != BIG_ENDIAN + not big endian + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_c_bigendian=yes +else $as_nop + ac_cv_c_bigendian=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + fi + if test $ac_cv_c_bigendian = unknown; then + # See if defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris). + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +int +main (void) +{ +#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN) + bogus endian macros + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + # It does; now see whether it defined to _BIG_ENDIAN or not. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +int +main (void) +{ +#ifndef _BIG_ENDIAN + not big endian + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_c_bigendian=yes +else $as_nop + ac_cv_c_bigendian=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + fi + if test $ac_cv_c_bigendian = unknown; then + # Compile a test program. + if test "$cross_compiling" = yes +then : + # Try to guess by grepping values from an object file. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +unsigned short int ascii_mm[] = + { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; + unsigned short int ascii_ii[] = + { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; + int use_ascii (int i) { + return ascii_mm[i] + ascii_ii[i]; + } + unsigned short int ebcdic_ii[] = + { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; + unsigned short int ebcdic_mm[] = + { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; + int use_ebcdic (int i) { + return ebcdic_mm[i] + ebcdic_ii[i]; + } + extern int foo; + +int +main (void) +{ +return use_ascii (foo) == use_ebcdic (foo); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then + ac_cv_c_bigendian=yes + fi + if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then + if test "$ac_cv_c_bigendian" = unknown; then + ac_cv_c_bigendian=no + else + # finding both strings is unlikely to happen, but who knows? + ac_cv_c_bigendian=unknown + fi + fi +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main (void) +{ + + /* Are we little or big endian? From Harbison&Steele. */ + union + { + long int l; + char c[sizeof (long int)]; + } u; + u.l = 1; + return u.c[sizeof (long int) - 1] == 1; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO" +then : + ac_cv_c_bigendian=no +else $as_nop + ac_cv_c_bigendian=yes +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + fi +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5 +printf "%s\n" "$ac_cv_c_bigendian" >&6; } + case $ac_cv_c_bigendian in #( + yes) + printf "%s\n" "#define WORDS_BIGENDIAN 1" >>confdefs.h +;; #( + no) + ;; #( + universal) + +printf "%s\n" "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h + + ;; #( + *) + as_fn_error $? "unknown endianness + presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;; + esac + + +# ABI version string for Python extension modules. This appears between the +# periods in shared library file names, e.g. foo..so. It is calculated +# from the following attributes which affect the ABI of this Python build (in +# this order): +# +# * The Python implementation (always 'cpython-' for us) +# * The major and minor version numbers +# * --with-pydebug (adds a 'd') +# +# Thus for example, Python 3.2 built with wide unicode, pydebug, and pymalloc, +# would get a shared library ABI version tag of 'cpython-32dmu' and shared +# libraries would be named 'foo.cpython-32dmu.so'. +# +# In Python 3.2 and older, --with-wide-unicode added a 'u' flag. +# In Python 3.7 and older, --with-pymalloc added a 'm' flag. + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking ABIFLAGS" >&5 +printf %s "checking ABIFLAGS... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ABIFLAGS" >&5 +printf "%s\n" "$ABIFLAGS" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking SOABI" >&5 +printf %s "checking SOABI... " >&6; } +SOABI='cpython-'`echo $VERSION | tr -d .`${ABIFLAGS}${PLATFORM_TRIPLET:+-$PLATFORM_TRIPLET} +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $SOABI" >&5 +printf "%s\n" "$SOABI" >&6; } + +# Release and debug (Py_DEBUG) ABI are compatible, but not Py_TRACE_REFS ABI +if test "$Py_DEBUG" = 'true' -a "$with_trace_refs" != "yes"; then + # Similar to SOABI but remove "d" flag from ABIFLAGS + + ALT_SOABI='cpython-'`echo $VERSION | tr -d .``echo $ABIFLAGS | tr -d d`${PLATFORM_TRIPLET:+-$PLATFORM_TRIPLET} + +printf "%s\n" "#define ALT_SOABI \"${ALT_SOABI}\"" >>confdefs.h + +fi + + +EXT_SUFFIX=.${SOABI}${SHLIB_SUFFIX} + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking LDVERSION" >&5 +printf %s "checking LDVERSION... " >&6; } +LDVERSION='$(VERSION)$(ABIFLAGS)' +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $LDVERSION" >&5 +printf "%s\n" "$LDVERSION" >&6; } + +# On Android and Cygwin the shared libraries must be linked with libpython. + +if test "$PY_ENABLE_SHARED" = "1" && ( test -n "$ANDROID_API_LEVEL" || test "$MACHDEP" = "cygwin"); then + LIBPYTHON="-lpython${VERSION}${ABIFLAGS}" +else + LIBPYTHON='' +fi + + + +BINLIBDEST='$(LIBDIR)/python$(VERSION)' + + +# Check for --with-platlibdir +# /usr/$LIDIRNAME/python$VERSION + +PLATLIBDIR="lib" +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-platlibdir" >&5 +printf %s "checking for --with-platlibdir... " >&6; } + +# Check whether --with-platlibdir was given. +if test ${with_platlibdir+y} +then : + withval=$with_platlibdir; +# ignore 3 options: +# --with-platlibdir +# --with-platlibdir= +# --without-platlibdir +if test -n "$withval" -a "$withval" != yes -a "$withval" != no +then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + PLATLIBDIR="$withval" + BINLIBDEST='${exec_prefix}/${PLATLIBDIR}/python$(VERSION)' +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + + +if test x$PLATFORM_TRIPLET = x; then + LIBPL='$(prefix)'"/${PLATLIBDIR}/python${VERSION}/config-${LDVERSION}" +else + LIBPL='$(prefix)'"/${PLATLIBDIR}/python${VERSION}/config-${LDVERSION}-${PLATFORM_TRIPLET}" +fi + + +# Check for --with-wheel-pkg-dir=PATH + +WHEEL_PKG_DIR="" +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-wheel-pkg-dir" >&5 +printf %s "checking for --with-wheel-pkg-dir... " >&6; } + +# Check whether --with-wheel-pkg-dir was given. +if test ${with_wheel_pkg_dir+y} +then : + withval=$with_wheel_pkg_dir; +if test -n "$withval"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + WHEEL_PKG_DIR="$withval" +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +# Check whether right shifting a negative integer extends the sign bit +# or fills with zeros (like the Cray J90, according to Tim Peters). +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether right shift extends the sign bit" >&5 +printf %s "checking whether right shift extends the sign bit... " >&6; } +if test ${ac_cv_rshift_extends_sign+y} +then : + printf %s "(cached) " >&6 +else $as_nop + +if test "$cross_compiling" = yes +then : + ac_cv_rshift_extends_sign=yes +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int main(void) +{ + return (((-1)>>3 == -1) ? 0 : 1); +} + +_ACEOF +if ac_fn_c_try_run "$LINENO" +then : + ac_cv_rshift_extends_sign=yes +else $as_nop + ac_cv_rshift_extends_sign=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_rshift_extends_sign" >&5 +printf "%s\n" "$ac_cv_rshift_extends_sign" >&6; } +if test "$ac_cv_rshift_extends_sign" = no +then + +printf "%s\n" "#define SIGNED_RIGHT_SHIFT_ZERO_FILLS 1" >>confdefs.h + +fi + +# check for getc_unlocked and related locking functions +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for getc_unlocked() and friends" >&5 +printf %s "checking for getc_unlocked() and friends... " >&6; } +if test ${ac_cv_have_getc_unlocked+y} +then : + printf %s "(cached) " >&6 +else $as_nop + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main (void) +{ + + FILE *f = fopen("/dev/null", "r"); + flockfile(f); + getc_unlocked(f); + funlockfile(f); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_have_getc_unlocked=yes +else $as_nop + ac_cv_have_getc_unlocked=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_getc_unlocked" >&5 +printf "%s\n" "$ac_cv_have_getc_unlocked" >&6; } +if test "$ac_cv_have_getc_unlocked" = yes +then + +printf "%s\n" "#define HAVE_GETC_UNLOCKED 1" >>confdefs.h + +fi + + + + + +# Check whether --with-readline was given. +if test ${with_readline+y} +then : + withval=$with_readline; + case $with_readline in #( + editline|edit) : + with_readline=edit ;; #( + yes|readline) : + with_readline=readline ;; #( + no) : + ;; #( + *) : + as_fn_error $? "proper usage is --with(out)-readline[=editline|readline|no]" "$LINENO" 5 + ;; +esac + +else $as_nop + with_readline=readline + +fi + + +if test "x$with_readline" = xreadline +then : + + +pkg_failed=no +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for LIBREADLINE" >&5 +printf %s "checking for LIBREADLINE... " >&6; } + +if test -n "$LIBREADLINE_CFLAGS"; then + pkg_cv_LIBREADLINE_CFLAGS="$LIBREADLINE_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"readline\""; } >&5 + ($PKG_CONFIG --exists --print-errors "readline") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBREADLINE_CFLAGS=`$PKG_CONFIG --cflags "readline" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$LIBREADLINE_LIBS"; then + pkg_cv_LIBREADLINE_LIBS="$LIBREADLINE_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"readline\""; } >&5 + ($PKG_CONFIG --exists --print-errors "readline") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBREADLINE_LIBS=`$PKG_CONFIG --libs "readline" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + LIBREADLINE_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "readline" 2>&1` + else + LIBREADLINE_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "readline" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LIBREADLINE_PKG_ERRORS" >&5 + + + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + CPPFLAGS="$CPPFLAGS $LIBREADLINE_CFLAGS" + LDFLAGS="$LDFLAGS $LIBREADLINE_LIBS" + for ac_header in readline/readline.h +do : + ac_fn_c_check_header_compile "$LINENO" "readline/readline.h" "ac_cv_header_readline_readline_h" "$ac_includes_default" +if test "x$ac_cv_header_readline_readline_h" = xyes +then : + printf "%s\n" "#define HAVE_READLINE_READLINE_H 1" >>confdefs.h + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for readline in -lreadline" >&5 +printf %s "checking for readline in -lreadline... " >&6; } +if test ${ac_cv_lib_readline_readline+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_check_lib_save_LIBS=$LIBS +LIBS="-lreadline $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char readline (); +int +main (void) +{ +return readline (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_readline_readline=yes +else $as_nop + ac_cv_lib_readline_readline=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_readline_readline" >&5 +printf "%s\n" "$ac_cv_lib_readline_readline" >&6; } +if test "x$ac_cv_lib_readline_readline" = xyes +then : + + LIBREADLINE=readline + READLINE_CFLAGS=${LIBREADLINE_CFLAGS-""} + READLINE_LIBS=${LIBREADLINE_LIBS-"-lreadline"} + +else $as_nop + with_readline=no +fi + + +else $as_nop + with_readline=no +fi + +done + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + +elif test $pkg_failed = untried; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + CPPFLAGS="$CPPFLAGS $LIBREADLINE_CFLAGS" + LDFLAGS="$LDFLAGS $LIBREADLINE_LIBS" + for ac_header in readline/readline.h +do : + ac_fn_c_check_header_compile "$LINENO" "readline/readline.h" "ac_cv_header_readline_readline_h" "$ac_includes_default" +if test "x$ac_cv_header_readline_readline_h" = xyes +then : + printf "%s\n" "#define HAVE_READLINE_READLINE_H 1" >>confdefs.h + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for readline in -lreadline" >&5 +printf %s "checking for readline in -lreadline... " >&6; } +if test ${ac_cv_lib_readline_readline+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_check_lib_save_LIBS=$LIBS +LIBS="-lreadline $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char readline (); +int +main (void) +{ +return readline (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_readline_readline=yes +else $as_nop + ac_cv_lib_readline_readline=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_readline_readline" >&5 +printf "%s\n" "$ac_cv_lib_readline_readline" >&6; } +if test "x$ac_cv_lib_readline_readline" = xyes +then : + + LIBREADLINE=readline + READLINE_CFLAGS=${LIBREADLINE_CFLAGS-""} + READLINE_LIBS=${LIBREADLINE_LIBS-"-lreadline"} + +else $as_nop + with_readline=no +fi + + +else $as_nop + with_readline=no +fi + +done + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + +else + LIBREADLINE_CFLAGS=$pkg_cv_LIBREADLINE_CFLAGS + LIBREADLINE_LIBS=$pkg_cv_LIBREADLINE_LIBS + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + + LIBREADLINE=readline + READLINE_CFLAGS=$LIBREADLINE_CFLAGS + READLINE_LIBS=$LIBREADLINE_LIBS + +fi + +fi + +if test "x$with_readline" = xedit +then : + + +pkg_failed=no +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for LIBEDIT" >&5 +printf %s "checking for LIBEDIT... " >&6; } + +if test -n "$LIBEDIT_CFLAGS"; then + pkg_cv_LIBEDIT_CFLAGS="$LIBEDIT_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libedit\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libedit") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBEDIT_CFLAGS=`$PKG_CONFIG --cflags "libedit" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$LIBEDIT_LIBS"; then + pkg_cv_LIBEDIT_LIBS="$LIBEDIT_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libedit\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libedit") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBEDIT_LIBS=`$PKG_CONFIG --libs "libedit" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + - fi - fi - ;; -esac -# check for endianness - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5 -$as_echo_n "checking whether byte ordering is bigendian... " >&6; } -if ${ac_cv_c_bigendian+:} false; then : - $as_echo_n "(cached) " >&6 +if test $pkg_failed = yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes else - ac_cv_c_bigendian=unknown - # See if we're dealing with a universal compiler. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + LIBEDIT_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libedit" 2>&1` + else + LIBEDIT_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libedit" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LIBEDIT_PKG_ERRORS" >&5 + + + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + CPPFLAGS="$CPPFLAGS $LIBEDIT_CFLAGS" + LDFLAGS="$LDFLAGS $LIBEDIT_LIBS" + for ac_header in editline/readline.h +do : + ac_fn_c_check_header_compile "$LINENO" "editline/readline.h" "ac_cv_header_editline_readline_h" "$ac_includes_default" +if test "x$ac_cv_header_editline_readline_h" = xyes +then : + printf "%s\n" "#define HAVE_EDITLINE_READLINE_H 1" >>confdefs.h + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for readline in -ledit" >&5 +printf %s "checking for readline in -ledit... " >&6; } +if test ${ac_cv_lib_edit_readline+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_check_lib_save_LIBS=$LIBS +LIBS="-ledit $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#ifndef __APPLE_CC__ - not a universal capable compiler - #endif - typedef int dummy; +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char readline (); +int +main (void) +{ +return readline (); + ; + return 0; +} _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_edit_readline=yes +else $as_nop + ac_cv_lib_edit_readline=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_edit_readline" >&5 +printf "%s\n" "$ac_cv_lib_edit_readline" >&6; } +if test "x$ac_cv_lib_edit_readline" = xyes +then : - # Check for potential -arch flags. It is not universal unless - # there are at least two -arch flags with different values. - ac_arch= - ac_prev= - for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do - if test -n "$ac_prev"; then - case $ac_word in - i?86 | x86_64 | ppc | ppc64) - if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then - ac_arch=$ac_word - else - ac_cv_c_bigendian=universal - break - fi - ;; - esac - ac_prev= - elif test "x$ac_word" = "x-arch"; then - ac_prev=arch - fi - done + LIBREADLINE=edit + printf "%s\n" "#define WITH_EDITLINE 1" >>confdefs.h + + READLINE_CFLAGS=${LIBEDIT_CFLAGS-""} + READLINE_LIBS=${LIBEDIT_LIBS-"-ledit"} + +else $as_nop + with_readline=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - if test $ac_cv_c_bigendian = unknown; then - # See if sys/param.h defines the BYTE_ORDER macro. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + + +else $as_nop + with_readline=no +fi + +done + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + +elif test $pkg_failed = untried; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + CPPFLAGS="$CPPFLAGS $LIBEDIT_CFLAGS" + LDFLAGS="$LDFLAGS $LIBEDIT_LIBS" + for ac_header in editline/readline.h +do : + ac_fn_c_check_header_compile "$LINENO" "editline/readline.h" "ac_cv_header_editline_readline_h" "$ac_includes_default" +if test "x$ac_cv_header_editline_readline_h" = xyes +then : + printf "%s\n" "#define HAVE_EDITLINE_READLINE_H 1" >>confdefs.h + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for readline in -ledit" >&5 +printf %s "checking for readline in -ledit... " >&6; } +if test ${ac_cv_lib_edit_readline+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_check_lib_save_LIBS=$LIBS +LIBS="-ledit $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include - #include +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char readline (); int -main () +main (void) { -#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \ - && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \ - && LITTLE_ENDIAN) - bogus endian macros - #endif - +return readline (); ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - # It does; now see whether it defined to BIG_ENDIAN or not. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_edit_readline=yes +else $as_nop + ac_cv_lib_edit_readline=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_edit_readline" >&5 +printf "%s\n" "$ac_cv_lib_edit_readline" >&6; } +if test "x$ac_cv_lib_edit_readline" = xyes +then : + + LIBREADLINE=edit + printf "%s\n" "#define WITH_EDITLINE 1" >>confdefs.h + + READLINE_CFLAGS=${LIBEDIT_CFLAGS-""} + READLINE_LIBS=${LIBEDIT_LIBS-"-ledit"} + +else $as_nop + with_readline=no +fi + + +else $as_nop + with_readline=no +fi + +done + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + +else + LIBEDIT_CFLAGS=$pkg_cv_LIBEDIT_CFLAGS + LIBEDIT_LIBS=$pkg_cv_LIBEDIT_LIBS + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + + printf "%s\n" "#define WITH_EDITLINE 1" >>confdefs.h + + LIBREADLINE=edit + READLINE_CFLAGS=$LIBEDIT_CFLAGS + READLINE_LIBS=$LIBEDIT_LIBS + +fi + +fi + +READLINE_CFLAGS=$(echo $READLINE_CFLAGS | sed 's/-D_XOPEN_SOURCE=600//g') + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to link readline" >&5 +printf %s "checking how to link readline... " >&6; } +if test "x$with_readline" = xno +then : + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + +else $as_nop + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_readline (CFLAGS: $READLINE_CFLAGS, LIBS: $READLINE_LIBS)" >&5 +printf "%s\n" "$with_readline (CFLAGS: $READLINE_CFLAGS, LIBS: $READLINE_LIBS)" >&6; } + + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + CPPFLAGS="$CPPFLAGS $READLINE_CFLAGS" + LIBS="$READLINE_LIBS $LIBS" + LIBS_SAVE=$LIBS + + + + # check for readline 2.2 + ac_fn_check_decl "$LINENO" "rl_completion_append_character" "ac_cv_have_decl_rl_completion_append_character" " + #include /* Must be first for Gnu Readline */ + #ifdef WITH_EDITLINE + # include + #else + # include + # include + #endif + +" "$ac_c_undeclared_builtin_options" "CFLAGS" +if test "x$ac_cv_have_decl_rl_completion_append_character" = xyes +then : + + +printf "%s\n" "#define HAVE_RL_COMPLETION_APPEND_CHARACTER 1" >>confdefs.h + + +fi + + ac_fn_check_decl "$LINENO" "rl_completion_suppress_append" "ac_cv_have_decl_rl_completion_suppress_append" " + #include /* Must be first for Gnu Readline */ + #ifdef WITH_EDITLINE + # include + #else + # include + # include + #endif + +" "$ac_c_undeclared_builtin_options" "CFLAGS" +if test "x$ac_cv_have_decl_rl_completion_suppress_append" = xyes +then : + + +printf "%s\n" "#define HAVE_RL_COMPLETION_SUPPRESS_APPEND 1" >>confdefs.h + + +fi + + # check for readline 4.0 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for rl_pre_input_hook in -l$LIBREADLINE" >&5 +printf %s "checking for rl_pre_input_hook in -l$LIBREADLINE... " >&6; } +if test ${ac_cv_readline_rl_pre_input_hook+y} +then : + printf %s "(cached) " >&6 +else $as_nop + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include - #include + + #include /* Must be first for Gnu Readline */ + #ifdef WITH_EDITLINE + # include + #else + # include + # include + #endif int -main () +main (void) { -#if BYTE_ORDER != BIG_ENDIAN - not big endian - #endif +void *x = rl_pre_input_hook + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_readline_rl_pre_input_hook=yes +else $as_nop + ac_cv_readline_rl_pre_input_hook=no + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_readline_rl_pre_input_hook" >&5 +printf "%s\n" "$ac_cv_readline_rl_pre_input_hook" >&6; } + if test "x$ac_cv_readline_rl_pre_input_hook" = xyes +then : + +printf "%s\n" "#define HAVE_RL_PRE_INPUT_HOOK 1" >>confdefs.h + + +fi + + # also in 4.0 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for rl_completion_display_matches_hook in -l$LIBREADLINE" >&5 +printf %s "checking for rl_completion_display_matches_hook in -l$LIBREADLINE... " >&6; } +if test ${ac_cv_readline_rl_completion_display_matches_hook+y} +then : + printf %s "(cached) " >&6 +else $as_nop + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include /* Must be first for Gnu Readline */ + #ifdef WITH_EDITLINE + # include + #else + # include + # include + #endif + +int +main (void) +{ +void *x = rl_completion_display_matches_hook ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_c_bigendian=yes -else - ac_cv_c_bigendian=no +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_readline_rl_completion_display_matches_hook=yes +else $as_nop + ac_cv_readline_rl_completion_display_matches_hook=no + fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - fi - if test $ac_cv_c_bigendian = unknown; then - # See if defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris). +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_readline_rl_completion_display_matches_hook" >&5 +printf "%s\n" "$ac_cv_readline_rl_completion_display_matches_hook" >&6; } + if test "x$ac_cv_readline_rl_completion_display_matches_hook" = xyes +then : + + +printf "%s\n" "#define HAVE_RL_COMPLETION_DISPLAY_MATCHES_HOOK 1" >>confdefs.h + + +fi + + # also in 4.0, but not in editline + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for rl_resize_terminal in -l$LIBREADLINE" >&5 +printf %s "checking for rl_resize_terminal in -l$LIBREADLINE... " >&6; } +if test ${ac_cv_readline_rl_resize_terminal+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include + + #include /* Must be first for Gnu Readline */ + #ifdef WITH_EDITLINE + # include + #else + # include + # include + #endif int -main () +main (void) { -#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN) - bogus endian macros - #endif +void *x = rl_resize_terminal + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_readline_rl_resize_terminal=yes +else $as_nop + ac_cv_readline_rl_resize_terminal=no + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_readline_rl_resize_terminal" >&5 +printf "%s\n" "$ac_cv_readline_rl_resize_terminal" >&6; } + if test "x$ac_cv_readline_rl_resize_terminal" = xyes +then : + + +printf "%s\n" "#define HAVE_RL_RESIZE_TERMINAL 1" >>confdefs.h + + +fi - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - # It does; now see whether it defined to _BIG_ENDIAN or not. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + # check for readline 4.2 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for rl_completion_matches in -l$LIBREADLINE" >&5 +printf %s "checking for rl_completion_matches in -l$LIBREADLINE... " >&6; } +if test ${ac_cv_readline_rl_completion_matches+y} +then : + printf %s "(cached) " >&6 +else $as_nop + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include + + #include /* Must be first for Gnu Readline */ + #ifdef WITH_EDITLINE + # include + #else + # include + # include + #endif int -main () +main (void) { -#ifndef _BIG_ENDIAN - not big endian - #endif - +void *x = rl_completion_matches ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_c_bigendian=yes -else - ac_cv_c_bigendian=no +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_readline_rl_completion_matches=yes +else $as_nop + ac_cv_readline_rl_completion_matches=no + fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - fi - if test $ac_cv_c_bigendian = unknown; then - # Compile a test program. - if test "$cross_compiling" = yes; then : - # Try to guess by grepping values from an object file. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_readline_rl_completion_matches" >&5 +printf "%s\n" "$ac_cv_readline_rl_completion_matches" >&6; } + if test "x$ac_cv_readline_rl_completion_matches" = xyes +then : + + +printf "%s\n" "#define HAVE_RL_COMPLETION_MATCHES 1" >>confdefs.h + + +fi + + # also in readline 4.2 + ac_fn_check_decl "$LINENO" "rl_catch_signals" "ac_cv_have_decl_rl_catch_signals" " + #include /* Must be first for Gnu Readline */ + #ifdef WITH_EDITLINE + # include + #else + # include + # include + #endif + +" "$ac_c_undeclared_builtin_options" "CFLAGS" +if test "x$ac_cv_have_decl_rl_catch_signals" = xyes +then : + + +printf "%s\n" "#define HAVE_RL_CATCH_SIGNAL 1" >>confdefs.h + + +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for append_history in -l$LIBREADLINE" >&5 +printf %s "checking for append_history in -l$LIBREADLINE... " >&6; } +if test ${ac_cv_readline_append_history+y} +then : + printf %s "(cached) " >&6 +else $as_nop + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -short int ascii_mm[] = - { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; - short int ascii_ii[] = - { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; - int use_ascii (int i) { - return ascii_mm[i] + ascii_ii[i]; - } - short int ebcdic_ii[] = - { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; - short int ebcdic_mm[] = - { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; - int use_ebcdic (int i) { - return ebcdic_mm[i] + ebcdic_ii[i]; - } - extern int foo; + + #include /* Must be first for Gnu Readline */ + #ifdef WITH_EDITLINE + # include + #else + # include + # include + #endif int -main () +main (void) { -return use_ascii (foo) == use_ebcdic (foo); +void *x = append_history ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then - ac_cv_c_bigendian=yes - fi - if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then - if test "$ac_cv_c_bigendian" = unknown; then - ac_cv_c_bigendian=no - else - # finding both strings is unlikely to happen, but who knows? - ac_cv_c_bigendian=unknown - fi - fi +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_readline_append_history=yes +else $as_nop + ac_cv_readline_append_history=no + fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -else +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_readline_append_history" >&5 +printf "%s\n" "$ac_cv_readline_append_history" >&6; } + if test "x$ac_cv_readline_append_history" = xyes +then : + + +printf "%s\n" "#define HAVE_RL_APPEND_HISTORY 1" >>confdefs.h + + +fi + + + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + +fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for broken nice()" >&5 +printf %s "checking for broken nice()... " >&6; } +if test ${ac_cv_broken_nice+y} +then : + printf %s "(cached) " >&6 +else $as_nop + +if test "$cross_compiling" = yes +then : + ac_cv_broken_nice=no +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -$ac_includes_default -int -main () -{ - - /* Are we little or big endian? From Harbison&Steele. */ - union - { - long int l; - char c[sizeof (long int)]; - } u; - u.l = 1; - return u.c[sizeof (long int) - 1] == 1; - ; - return 0; +#include +#include +int main(void) +{ + int val1 = nice(1); + if (val1 != -1 && val1 == nice(2)) + exit(0); + exit(1); } + _ACEOF -if ac_fn_c_try_run "$LINENO"; then : - ac_cv_c_bigendian=no -else - ac_cv_c_bigendian=yes +if ac_fn_c_try_run "$LINENO" +then : + ac_cv_broken_nice=yes +else $as_nop + ac_cv_broken_nice=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi - fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5 -$as_echo "$ac_cv_c_bigendian" >&6; } - case $ac_cv_c_bigendian in #( - yes) - $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h -;; #( - no) - ;; #( - universal) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_broken_nice" >&5 +printf "%s\n" "$ac_cv_broken_nice" >&6; } +if test "$ac_cv_broken_nice" = yes +then -$as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h +printf "%s\n" "#define HAVE_BROKEN_NICE 1" >>confdefs.h - ;; #( - *) - as_fn_error $? "unknown endianness - presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;; - esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for broken poll()" >&5 +printf %s "checking for broken poll()... " >&6; } +if test ${ac_cv_broken_poll+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test "$cross_compiling" = yes +then : + ac_cv_broken_poll=no +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ -# ABI version string for Python extension modules. This appears between the -# periods in shared library file names, e.g. foo..so. It is calculated -# from the following attributes which affect the ABI of this Python build (in -# this order): -# -# * The Python implementation (always 'cpython-' for us) -# * The major and minor version numbers -# * --with-pydebug (adds a 'd') -# -# Thus for example, Python 3.2 built with wide unicode, pydebug, and pymalloc, -# would get a shared library ABI version tag of 'cpython-32dmu' and shared -# libraries would be named 'foo.cpython-32dmu.so'. -# -# In Python 3.2 and older, --with-wide-unicode added a 'u' flag. -# In Python 3.7 and older, --with-pymalloc added a 'm' flag. +#include +#include -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking ABIFLAGS" >&5 -$as_echo_n "checking ABIFLAGS... " >&6; } -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ABIFLAGS" >&5 -$as_echo "$ABIFLAGS" >&6; } -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking SOABI" >&5 -$as_echo_n "checking SOABI... " >&6; } -SOABI='cpython-'`echo $VERSION | tr -d .`${ABIFLAGS}${PLATFORM_TRIPLET:+-$PLATFORM_TRIPLET} -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $SOABI" >&5 -$as_echo "$SOABI" >&6; } +int main(void) +{ + struct pollfd poll_struct = { 42, POLLIN|POLLPRI|POLLOUT, 0 }; + int poll_test; -# Release and debug (Py_DEBUG) ABI are compatible, but not Py_TRACE_REFS ABI -if test "$Py_DEBUG" = 'true' -a "$with_trace_refs" != "yes"; then - # Similar to SOABI but remove "d" flag from ABIFLAGS + close (42); - ALT_SOABI='cpython-'`echo $VERSION | tr -d .``echo $ABIFLAGS | tr -d d`${PLATFORM_TRIPLET:+-$PLATFORM_TRIPLET} + poll_test = poll(&poll_struct, 1, 0); + if (poll_test < 0) + return 0; + else if (poll_test == 0 && poll_struct.revents != POLLNVAL) + return 0; + else + return 1; +} -cat >>confdefs.h <<_ACEOF -#define ALT_SOABI "${ALT_SOABI}" _ACEOF - +if ac_fn_c_try_run "$LINENO" +then : + ac_cv_broken_poll=yes +else $as_nop + ac_cv_broken_poll=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext fi +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_broken_poll" >&5 +printf "%s\n" "$ac_cv_broken_poll" >&6; } +if test "$ac_cv_broken_poll" = yes +then -EXT_SUFFIX=.${SOABI}${SHLIB_SUFFIX} - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking LDVERSION" >&5 -$as_echo_n "checking LDVERSION... " >&6; } -LDVERSION='$(VERSION)$(ABIFLAGS)' -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $LDVERSION" >&5 -$as_echo "$LDVERSION" >&6; } - -# On Android and Cygwin the shared libraries must be linked with libpython. +printf "%s\n" "#define HAVE_BROKEN_POLL 1" >>confdefs.h -if test -n "$ANDROID_API_LEVEL" -o "$MACHDEP" = "cygwin"; then - LIBPYTHON="-lpython${VERSION}${ABIFLAGS}" -else - LIBPYTHON='' fi +# check tzset(3) exists and works like we expect it to +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for working tzset()" >&5 +printf %s "checking for working tzset()... " >&6; } +if test ${ac_cv_working_tzset+y} +then : + printf %s "(cached) " >&6 +else $as_nop + +if test "$cross_compiling" = yes +then : + ac_cv_working_tzset=no +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +#include +#if HAVE_TZNAME +extern char *tzname[]; +#endif -BINLIBDEST='$(LIBDIR)/python$(VERSION)' +int main(void) +{ + /* Note that we need to ensure that not only does tzset(3) + do 'something' with localtime, but it works as documented + in the library reference and as expected by the test suite. + This includes making sure that tzname is set properly if + tm->tm_zone does not exist since it is the alternative way + of getting timezone info. + Red Hat 6.2 doesn't understand the southern hemisphere + after New Year's Day. + */ -# Check for --with-platlibdir -# /usr/$LIDIRNAME/python$VERSION + time_t groundhogday = 1044144000; /* GMT-based */ + time_t midyear = groundhogday + (365 * 24 * 3600 / 2); -PLATLIBDIR="lib" -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-platlibdir" >&5 -$as_echo_n "checking for --with-platlibdir... " >&6; } + putenv("TZ=UTC+0"); + tzset(); + if (localtime(&groundhogday)->tm_hour != 0) + exit(1); +#if HAVE_TZNAME + /* For UTC, tzname[1] is sometimes "", sometimes " " */ + if (strcmp(tzname[0], "UTC") || + (tzname[1][0] != 0 && tzname[1][0] != ' ')) + exit(1); +#endif -# Check whether --with-platlibdir was given. -if test "${with_platlibdir+set}" = set; then : - withval=$with_platlibdir; -# ignore 3 options: -# --with-platlibdir -# --with-platlibdir= -# --without-platlibdir -if test -n "$withval" -a "$withval" != yes -a "$withval" != no -then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - PLATLIBDIR="$withval" - BINLIBDEST='${exec_prefix}/${PLATLIBDIR}/python$(VERSION)' -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi + putenv("TZ=EST+5EDT,M4.1.0,M10.5.0"); + tzset(); + if (localtime(&groundhogday)->tm_hour != 19) + exit(1); +#if HAVE_TZNAME + if (strcmp(tzname[0], "EST") || strcmp(tzname[1], "EDT")) + exit(1); +#endif + putenv("TZ=AEST-10AEDT-11,M10.5.0,M3.5.0"); + tzset(); + if (localtime(&groundhogday)->tm_hour != 11) + exit(1); +#if HAVE_TZNAME + if (strcmp(tzname[0], "AEST") || strcmp(tzname[1], "AEDT")) + exit(1); +#endif +#if HAVE_STRUCT_TM_TM_ZONE + if (strcmp(localtime(&groundhogday)->tm_zone, "AEDT")) + exit(1); + if (strcmp(localtime(&midyear)->tm_zone, "AEST")) + exit(1); +#endif + exit(0); +} -if test x$PLATFORM_TRIPLET = x; then - LIBPL='$(prefix)'"/${PLATLIBDIR}/python${VERSION}/config-${LDVERSION}" -else - LIBPL='$(prefix)'"/${PLATLIBDIR}/python${VERSION}/config-${LDVERSION}-${PLATFORM_TRIPLET}" +_ACEOF +if ac_fn_c_try_run "$LINENO" +then : + ac_cv_working_tzset=yes +else $as_nop + ac_cv_working_tzset=no fi - - -# Check for --with-wheel-pkg-dir=PATH - -WHEEL_PKG_DIR="" -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-wheel-pkg-dir" >&5 -$as_echo_n "checking for --with-wheel-pkg-dir... " >&6; } - -# Check whether --with-wheel-pkg-dir was given. -if test "${with_wheel_pkg_dir+set}" = set; then : - withval=$with_wheel_pkg_dir; -if test -n "$withval"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - WHEEL_PKG_DIR="$withval" -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext fi -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_working_tzset" >&5 +printf "%s\n" "$ac_cv_working_tzset" >&6; } +if test "$ac_cv_working_tzset" = yes +then +printf "%s\n" "#define HAVE_WORKING_TZSET 1" >>confdefs.h -# Check whether right shifting a negative integer extends the sign bit -# or fills with zeros (like the Cray J90, according to Tim Peters). -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether right shift extends the sign bit" >&5 -$as_echo_n "checking whether right shift extends the sign bit... " >&6; } -if ${ac_cv_rshift_extends_sign+:} false; then : - $as_echo_n "(cached) " >&6 -else +fi -if test "$cross_compiling" = yes; then : - ac_cv_rshift_extends_sign=yes -else +# Look for subsecond timestamps in struct stat +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for tv_nsec in struct stat" >&5 +printf %s "checking for tv_nsec in struct stat... " >&6; } +if test ${ac_cv_stat_tv_nsec+y} +then : + printf %s "(cached) " >&6 +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - -int main(void) +#include +int +main (void) { - return (((-1)>>3 == -1) ? 0 : 1); -} +struct stat st; +st.st_mtim.tv_nsec = 1; + + ; + return 0; +} _ACEOF -if ac_fn_c_try_run "$LINENO"; then : - ac_cv_rshift_extends_sign=yes -else - ac_cv_rshift_extends_sign=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_stat_tv_nsec=yes +else $as_nop + ac_cv_stat_tv_nsec=no fi - +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_rshift_extends_sign" >&5 -$as_echo "$ac_cv_rshift_extends_sign" >&6; } -if test "$ac_cv_rshift_extends_sign" = no +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_stat_tv_nsec" >&5 +printf "%s\n" "$ac_cv_stat_tv_nsec" >&6; } +if test "$ac_cv_stat_tv_nsec" = yes then -$as_echo "#define SIGNED_RIGHT_SHIFT_ZERO_FILLS 1" >>confdefs.h +printf "%s\n" "#define HAVE_STAT_TV_NSEC 1" >>confdefs.h fi -# check for getc_unlocked and related locking functions -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for getc_unlocked() and friends" >&5 -$as_echo_n "checking for getc_unlocked() and friends... " >&6; } -if ${ac_cv_have_getc_unlocked+:} false; then : - $as_echo_n "(cached) " >&6 -else - -cat confdefs.h - <<_ACEOF >conftest.$ac_ext +# Look for BSD style subsecond timestamps in struct stat +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for tv_nsec2 in struct stat" >&5 +printf %s "checking for tv_nsec2 in struct stat... " >&6; } +if test ${ac_cv_stat_tv_nsec2+y} +then : + printf %s "(cached) " >&6 +else $as_nop + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include +#include int -main () +main (void) { - FILE *f = fopen("/dev/null", "r"); - flockfile(f); - getc_unlocked(f); - funlockfile(f); +struct stat st; +st.st_mtimespec.tv_nsec = 1; ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_have_getc_unlocked=yes -else - ac_cv_have_getc_unlocked=no +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_stat_tv_nsec2=yes +else $as_nop + ac_cv_stat_tv_nsec2=no fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_getc_unlocked" >&5 -$as_echo "$ac_cv_have_getc_unlocked" >&6; } -if test "$ac_cv_have_getc_unlocked" = yes +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_stat_tv_nsec2" >&5 +printf "%s\n" "$ac_cv_stat_tv_nsec2" >&6; } +if test "$ac_cv_stat_tv_nsec2" = yes then -$as_echo "#define HAVE_GETC_UNLOCKED 1" >>confdefs.h +printf "%s\n" "#define HAVE_STAT_TV_NSEC2 1" >>confdefs.h fi +have_curses=no +have_panel=no -# Check whether --with-readline was given. -if test "${with_readline+set}" = set; then : - withval=$with_readline; + +ac_fn_c_check_header_compile "$LINENO" "curses.h" "ac_cv_header_curses_h" "$ac_includes_default" +if test "x$ac_cv_header_curses_h" = xyes +then : + printf "%s\n" "#define HAVE_CURSES_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "ncurses.h" "ac_cv_header_ncurses_h" "$ac_includes_default" +if test "x$ac_cv_header_ncurses_h" = xyes +then : + printf "%s\n" "#define HAVE_NCURSES_H 1" >>confdefs.h + +fi + + +if test "x$ac_cv_header_ncurses_h" = xyes +then : + + if test "$ac_sys_system" != "Darwin"; then + +pkg_failed=no +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for CURSES" >&5 +printf %s "checking for CURSES... " >&6; } + +if test -n "$CURSES_CFLAGS"; then + pkg_cv_CURSES_CFLAGS="$CURSES_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"ncursesw\""; } >&5 + ($PKG_CONFIG --exists --print-errors "ncursesw") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_CURSES_CFLAGS=`$PKG_CONFIG --cflags "ncursesw" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$CURSES_LIBS"; then + pkg_cv_CURSES_LIBS="$CURSES_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"ncursesw\""; } >&5 + ($PKG_CONFIG --exists --print-errors "ncursesw") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_CURSES_LIBS=`$PKG_CONFIG --libs "ncursesw" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes else - with_readline=yes + pkg_failed=yes +fi + else + pkg_failed=untried fi -# check where readline lives -py_cv_lib_readline=no -# save the value of LIBS so we don't actually link Python with readline -LIBS_no_readline=$LIBS -if test "$with_readline" != no; then - case "$with_readline" in - editline|edit) - LIBREADLINE=edit +if test $pkg_failed = yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + CURSES_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "ncursesw" 2>&1` + else + CURSES_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "ncursesw" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$CURSES_PKG_ERRORS" >&5 -$as_echo "#define WITH_EDITLINE 1" >>confdefs.h - ;; - yes|readline) - LIBREADLINE=readline - ;; - *) - as_fn_error $? "proper usage is --with(out)-readline[=editline]" "$LINENO" 5 - ;; - esac + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS - # On some systems we need to link readline to a termcap compatible - # library. NOTE: Keep the precedence of listed libraries synchronised - # with setup.py. - { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to link readline libs" >&5 -$as_echo_n "checking how to link readline libs... " >&6; } - for py_libtermcap in "" tinfo ncursesw ncurses curses termcap; do - if test -z "$py_libtermcap"; then - READLINE_LIBS="-l$LIBREADLINE" - else - READLINE_LIBS="-l$LIBREADLINE -l$py_libtermcap" - fi - LIBS="$READLINE_LIBS $LIBS_no_readline" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for initscr in -lncursesw" >&5 +printf %s "checking for initscr in -lncursesw... " >&6; } +if test ${ac_cv_lib_ncursesw_initscr+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_check_lib_save_LIBS=$LIBS +LIBS="-lncursesw $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char readline (); +char initscr (); int -main () +main (void) { -return readline (); +return initscr (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - py_cv_lib_readline=yes +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_ncursesw_initscr=yes +else $as_nop + ac_cv_lib_ncursesw_initscr=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext - if test $py_cv_lib_readline = yes; then - break - fi - done +LIBS=$ac_check_lib_save_LIBS +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ncursesw_initscr" >&5 +printf "%s\n" "$ac_cv_lib_ncursesw_initscr" >&6; } +if test "x$ac_cv_lib_ncursesw_initscr" = xyes +then : - # Uncomment this line if you want to use READLINE_LIBS in Makefile or scripts - #AC_SUBST([READLINE_LIBS]) - if test $py_cv_lib_readline = no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 -$as_echo "none" >&6; } - else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $READLINE_LIBS" >&5 -$as_echo "$READLINE_LIBS" >&6; } + printf "%s\n" "#define HAVE_NCURSESW 1" >>confdefs.h -$as_echo "#define HAVE_LIBREADLINE 1" >>confdefs.h + have_curses=ncursesw + CURSES_CFLAGS=${CURSES_CFLAGS-""} + CURSES_LIBS=${CURSES_LIBS-"-lncursesw"} - fi fi -if test "$py_cv_lib_readline" = yes; then - # check for readline 2.2 - ac_fn_c_check_decl "$LINENO" "rl_completion_append_character" "ac_cv_have_decl_rl_completion_append_character" " -#include /* Must be first for Gnu Readline */ -#ifdef WITH_EDITLINE -# include -#else -# include -#endif - -" -if test "x$ac_cv_have_decl_rl_completion_append_character" = xyes; then : - -$as_echo "#define HAVE_RL_COMPLETION_APPEND_CHARACTER 1" >>confdefs.h -fi +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS - ac_fn_c_check_decl "$LINENO" "rl_completion_suppress_append" "ac_cv_have_decl_rl_completion_suppress_append" " -#include /* Must be first for Gnu Readline */ -#ifdef WITH_EDITLINE -# include -#else -# include -#endif -" -if test "x$ac_cv_have_decl_rl_completion_suppress_append" = xyes; then : -$as_echo "#define HAVE_RL_COMPLETION_SUPPRESS_APPEND 1" >>confdefs.h +elif test $pkg_failed = untried; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } -fi + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS - # check for readline 4.0 - as_ac_Lib=`$as_echo "ac_cv_lib_$LIBREADLINE''_rl_pre_input_hook" | $as_tr_sh` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for rl_pre_input_hook in -l$LIBREADLINE" >&5 -$as_echo_n "checking for rl_pre_input_hook in -l$LIBREADLINE... " >&6; } -if eval \${$as_ac_Lib+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for initscr in -lncursesw" >&5 +printf %s "checking for initscr in -lncursesw... " >&6; } +if test ${ac_cv_lib_ncursesw_initscr+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS -LIBS="-l$LIBREADLINE $READLINE_LIBS $LIBS" +LIBS="-lncursesw $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char rl_pre_input_hook (); +char initscr (); int -main () +main (void) { -return rl_pre_input_hook (); +return initscr (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - eval "$as_ac_Lib=yes" -else - eval "$as_ac_Lib=no" +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_ncursesw_initscr=yes +else $as_nop + ac_cv_lib_ncursesw_initscr=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -eval ac_res=\$$as_ac_Lib - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ncursesw_initscr" >&5 +printf "%s\n" "$ac_cv_lib_ncursesw_initscr" >&6; } +if test "x$ac_cv_lib_ncursesw_initscr" = xyes +then : + + printf "%s\n" "#define HAVE_NCURSESW 1" >>confdefs.h + + have_curses=ncursesw + CURSES_CFLAGS=${CURSES_CFLAGS-""} + CURSES_LIBS=${CURSES_LIBS-"-lncursesw"} + +fi + + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + +else + CURSES_CFLAGS=$pkg_cv_CURSES_CFLAGS + CURSES_LIBS=$pkg_cv_CURSES_LIBS + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + + printf "%s\n" "#define HAVE_NCURSESW 1" >>confdefs.h + + have_curses=ncursesw + +fi + fi + + if test "x$have_curses" = xno +then : -$as_echo "#define HAVE_RL_PRE_INPUT_HOOK 1" >>confdefs.h +pkg_failed=no +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for CURSES" >&5 +printf %s "checking for CURSES... " >&6; } + +if test -n "$CURSES_CFLAGS"; then + pkg_cv_CURSES_CFLAGS="$CURSES_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"ncurses\""; } >&5 + ($PKG_CONFIG --exists --print-errors "ncurses") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_CURSES_CFLAGS=`$PKG_CONFIG --cflags "ncurses" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$CURSES_LIBS"; then + pkg_cv_CURSES_LIBS="$CURSES_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"ncurses\""; } >&5 + ($PKG_CONFIG --exists --print-errors "ncurses") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_CURSES_LIBS=`$PKG_CONFIG --libs "ncurses" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes fi + else + pkg_failed=untried +fi + - # also in 4.0 - as_ac_Lib=`$as_echo "ac_cv_lib_$LIBREADLINE''_rl_completion_display_matches_hook" | $as_tr_sh` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for rl_completion_display_matches_hook in -l$LIBREADLINE" >&5 -$as_echo_n "checking for rl_completion_display_matches_hook in -l$LIBREADLINE... " >&6; } -if eval \${$as_ac_Lib+:} false; then : - $as_echo_n "(cached) " >&6 +if test $pkg_failed = yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + CURSES_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "ncurses" 2>&1` + else + CURSES_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "ncurses" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$CURSES_PKG_ERRORS" >&5 + + + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for initscr in -lncurses" >&5 +printf %s "checking for initscr in -lncurses... " >&6; } +if test ${ac_cv_lib_ncurses_initscr+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS -LIBS="-l$LIBREADLINE $READLINE_LIBS $LIBS" +LIBS="-lncurses $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char rl_completion_display_matches_hook (); +char initscr (); int -main () +main (void) { -return rl_completion_display_matches_hook (); +return initscr (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - eval "$as_ac_Lib=yes" -else - eval "$as_ac_Lib=no" +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_ncurses_initscr=yes +else $as_nop + ac_cv_lib_ncurses_initscr=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -eval ac_res=\$$as_ac_Lib - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ncurses_initscr" >&5 +printf "%s\n" "$ac_cv_lib_ncurses_initscr" >&6; } +if test "x$ac_cv_lib_ncurses_initscr" = xyes +then : + + have_curses=ncurses + CURSES_CFLAGS=${CURSES_CFLAGS-""} + CURSES_LIBS=${CURSES_LIBS-"-lncurses"} + +fi + + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + -$as_echo "#define HAVE_RL_COMPLETION_DISPLAY_MATCHES_HOOK 1" >>confdefs.h -fi +elif test $pkg_failed = untried; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS - # also in 4.0, but not in editline - as_ac_Lib=`$as_echo "ac_cv_lib_$LIBREADLINE''_rl_resize_terminal" | $as_tr_sh` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for rl_resize_terminal in -l$LIBREADLINE" >&5 -$as_echo_n "checking for rl_resize_terminal in -l$LIBREADLINE... " >&6; } -if eval \${$as_ac_Lib+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for initscr in -lncurses" >&5 +printf %s "checking for initscr in -lncurses... " >&6; } +if test ${ac_cv_lib_ncurses_initscr+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS -LIBS="-l$LIBREADLINE $READLINE_LIBS $LIBS" +LIBS="-lncurses $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char rl_resize_terminal (); +char initscr (); int -main () +main (void) { -return rl_resize_terminal (); +return initscr (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - eval "$as_ac_Lib=yes" -else - eval "$as_ac_Lib=no" +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_ncurses_initscr=yes +else $as_nop + ac_cv_lib_ncurses_initscr=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -eval ac_res=\$$as_ac_Lib - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ncurses_initscr" >&5 +printf "%s\n" "$ac_cv_lib_ncurses_initscr" >&6; } +if test "x$ac_cv_lib_ncurses_initscr" = xyes +then : + + have_curses=ncurses + CURSES_CFLAGS=${CURSES_CFLAGS-""} + CURSES_LIBS=${CURSES_LIBS-"-lncurses"} + +fi + + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + +else + CURSES_CFLAGS=$pkg_cv_CURSES_CFLAGS + CURSES_LIBS=$pkg_cv_CURSES_LIBS + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + + have_curses=ncurses + +fi + +fi + + +fi +CURSES_CFLAGS=$(echo $CURSES_CFLAGS | sed 's/-D_XOPEN_SOURCE=600//g') + +if test "$have_curses" = no -a "$ac_sys_system" = "Darwin"; then + + as_fn_append CURSES_CFLAGS " -D_XOPEN_SOURCE_EXTENDED=1" + printf "%s\n" "#define HAVE_NCURSESW 1" >>confdefs.h + +fi + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking curses module flags" >&5 +printf %s "checking curses module flags... " >&6; } +if test "x$have_curses" = xno +then : + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + +else $as_nop + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_curses (CFLAGS: $CURSES_CFLAGS, LIBS: $CURSES_LIBS)" >&5 +printf "%s\n" "$have_curses (CFLAGS: $CURSES_CFLAGS, LIBS: $CURSES_LIBS)" >&6; } + +fi + +ac_fn_c_check_header_compile "$LINENO" "panel.h" "ac_cv_header_panel_h" "$ac_includes_default" +if test "x$ac_cv_header_panel_h" = xyes +then : + printf "%s\n" "#define HAVE_PANEL_H 1" >>confdefs.h + +fi + -$as_echo "#define HAVE_RL_RESIZE_TERMINAL 1" >>confdefs.h +if test "x$ac_cv_header_panel_h" = xyes +then : + + if test "$ac_sys_system" != "Darwin"; then + if test "x$have_curses" = xncursesw +then : + + +pkg_failed=no +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for PANEL" >&5 +printf %s "checking for PANEL... " >&6; } + +if test -n "$PANEL_CFLAGS"; then + pkg_cv_PANEL_CFLAGS="$PANEL_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"panelw\""; } >&5 + ($PKG_CONFIG --exists --print-errors "panelw") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_PANEL_CFLAGS=`$PKG_CONFIG --cflags "panelw" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$PANEL_LIBS"; then + pkg_cv_PANEL_LIBS="$PANEL_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"panelw\""; } >&5 + ($PKG_CONFIG --exists --print-errors "panelw") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_PANEL_LIBS=`$PKG_CONFIG --libs "panelw" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried fi - # check for readline 4.2 - as_ac_Lib=`$as_echo "ac_cv_lib_$LIBREADLINE''_rl_completion_matches" | $as_tr_sh` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for rl_completion_matches in -l$LIBREADLINE" >&5 -$as_echo_n "checking for rl_completion_matches in -l$LIBREADLINE... " >&6; } -if eval \${$as_ac_Lib+:} false; then : - $as_echo_n "(cached) " >&6 + +if test $pkg_failed = yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + PANEL_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "panelw" 2>&1` + else + PANEL_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "panelw" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$PANEL_PKG_ERRORS" >&5 + + + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for update_panels in -lpanelw" >&5 +printf %s "checking for update_panels in -lpanelw... " >&6; } +if test ${ac_cv_lib_panelw_update_panels+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS -LIBS="-l$LIBREADLINE $READLINE_LIBS $LIBS" +LIBS="-lpanelw $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char rl_completion_matches (); +char update_panels (); int -main () +main (void) { -return rl_completion_matches (); +return update_panels (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - eval "$as_ac_Lib=yes" -else - eval "$as_ac_Lib=no" +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_panelw_update_panels=yes +else $as_nop + ac_cv_lib_panelw_update_panels=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -eval ac_res=\$$as_ac_Lib - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_panelw_update_panels" >&5 +printf "%s\n" "$ac_cv_lib_panelw_update_panels" >&6; } +if test "x$ac_cv_lib_panelw_update_panels" = xyes +then : -$as_echo "#define HAVE_RL_COMPLETION_MATCHES 1" >>confdefs.h + have_panel=panelw + PANEL_CFLAGS=${PANEL_CFLAGS-""} + PANEL_LIBS=${PANEL_LIBS-"-lpanelw"} fi - # also in readline 4.2 - ac_fn_c_check_decl "$LINENO" "rl_catch_signals" "ac_cv_have_decl_rl_catch_signals" " -#include /* Must be first for Gnu Readline */ -#ifdef WITH_EDITLINE -# include -#else -# include -#endif +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS -" -if test "x$ac_cv_have_decl_rl_catch_signals" = xyes; then : -$as_echo "#define HAVE_RL_CATCH_SIGNAL 1" >>confdefs.h -fi +elif test $pkg_failed = untried; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS - as_ac_Lib=`$as_echo "ac_cv_lib_$LIBREADLINE''_append_history" | $as_tr_sh` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for append_history in -l$LIBREADLINE" >&5 -$as_echo_n "checking for append_history in -l$LIBREADLINE... " >&6; } -if eval \${$as_ac_Lib+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for update_panels in -lpanelw" >&5 +printf %s "checking for update_panels in -lpanelw... " >&6; } +if test ${ac_cv_lib_panelw_update_panels+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_check_lib_save_LIBS=$LIBS -LIBS="-l$LIBREADLINE $READLINE_LIBS $LIBS" +LIBS="-lpanelw $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char append_history (); +char update_panels (); int -main () +main (void) { -return append_history (); +return update_panels (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - eval "$as_ac_Lib=yes" -else - eval "$as_ac_Lib=no" +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_panelw_update_panels=yes +else $as_nop + ac_cv_lib_panelw_update_panels=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -eval ac_res=\$$as_ac_Lib - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_panelw_update_panels" >&5 +printf "%s\n" "$ac_cv_lib_panelw_update_panels" >&6; } +if test "x$ac_cv_lib_panelw_update_panels" = xyes +then : -$as_echo "#define HAVE_RL_APPEND_HISTORY 1" >>confdefs.h - -fi + have_panel=panelw + PANEL_CFLAGS=${PANEL_CFLAGS-""} + PANEL_LIBS=${PANEL_LIBS-"-lpanelw"} fi -# End of readline checks: restore LIBS -LIBS=$LIBS_no_readline -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for broken nice()" >&5 -$as_echo_n "checking for broken nice()... " >&6; } -if ${ac_cv_broken_nice+:} false; then : - $as_echo_n "(cached) " >&6 -else +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS -if test "$cross_compiling" = yes; then : - ac_cv_broken_nice=no -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include -int main(void) -{ - int val1 = nice(1); - if (val1 != -1 && val1 == nice(2)) - exit(0); - exit(1); -} -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - ac_cv_broken_nice=yes else - ac_cv_broken_nice=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_broken_nice" >&5 -$as_echo "$ac_cv_broken_nice" >&6; } -if test "$ac_cv_broken_nice" = yes -then + PANEL_CFLAGS=$pkg_cv_PANEL_CFLAGS + PANEL_LIBS=$pkg_cv_PANEL_LIBS + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } -$as_echo "#define HAVE_BROKEN_NICE 1" >>confdefs.h + have_panel=panelw fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for broken poll()" >&5 -$as_echo_n "checking for broken poll()... " >&6; } -if ${ac_cv_broken_poll+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "$cross_compiling" = yes; then : - ac_cv_broken_poll=no -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#include -#include +fi + fi -int main(void) -{ - struct pollfd poll_struct = { 42, POLLIN|POLLPRI|POLLOUT, 0 }; - int poll_test; + if test "x$have_curses" = xncurses +then : - close (42); - poll_test = poll(&poll_struct, 1, 0); - if (poll_test < 0) - return 0; - else if (poll_test == 0 && poll_struct.revents != POLLNVAL) - return 0; - else - return 1; -} +pkg_failed=no +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for PANEL" >&5 +printf %s "checking for PANEL... " >&6; } -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - ac_cv_broken_poll=yes +if test -n "$PANEL_CFLAGS"; then + pkg_cv_PANEL_CFLAGS="$PANEL_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"panel\""; } >&5 + ($PKG_CONFIG --exists --print-errors "panel") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_PANEL_CFLAGS=`$PKG_CONFIG --cflags "panel" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes else - ac_cv_broken_poll=no + pkg_failed=yes fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext + else + pkg_failed=untried fi - +if test -n "$PANEL_LIBS"; then + pkg_cv_PANEL_LIBS="$PANEL_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"panel\""; } >&5 + ($PKG_CONFIG --exists --print-errors "panel") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_PANEL_LIBS=`$PKG_CONFIG --libs "panel" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_broken_poll" >&5 -$as_echo "$ac_cv_broken_poll" >&6; } -if test "$ac_cv_broken_poll" = yes -then - -$as_echo "#define HAVE_BROKEN_POLL 1" >>confdefs.h - + else + pkg_failed=untried fi -# check tzset(3) exists and works like we expect it to -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working tzset()" >&5 -$as_echo_n "checking for working tzset()... " >&6; } -if ${ac_cv_working_tzset+:} false; then : - $as_echo_n "(cached) " >&6 -else - -if test "$cross_compiling" = yes; then : - ac_cv_working_tzset=no -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#include -#include -#include - -#if HAVE_TZNAME -extern char *tzname[]; -#endif - -int main(void) -{ - /* Note that we need to ensure that not only does tzset(3) - do 'something' with localtime, but it works as documented - in the library reference and as expected by the test suite. - This includes making sure that tzname is set properly if - tm->tm_zone does not exist since it is the alternative way - of getting timezone info. - - Red Hat 6.2 doesn't understand the southern hemisphere - after New Year's Day. - */ - - time_t groundhogday = 1044144000; /* GMT-based */ - time_t midyear = groundhogday + (365 * 24 * 3600 / 2); - - putenv("TZ=UTC+0"); - tzset(); - if (localtime(&groundhogday)->tm_hour != 0) - exit(1); -#if HAVE_TZNAME - /* For UTC, tzname[1] is sometimes "", sometimes " " */ - if (strcmp(tzname[0], "UTC") || - (tzname[1][0] != 0 && tzname[1][0] != ' ')) - exit(1); -#endif - - putenv("TZ=EST+5EDT,M4.1.0,M10.5.0"); - tzset(); - if (localtime(&groundhogday)->tm_hour != 19) - exit(1); -#if HAVE_TZNAME - if (strcmp(tzname[0], "EST") || strcmp(tzname[1], "EDT")) - exit(1); -#endif - - putenv("TZ=AEST-10AEDT-11,M10.5.0,M3.5.0"); - tzset(); - if (localtime(&groundhogday)->tm_hour != 11) - exit(1); -#if HAVE_TZNAME - if (strcmp(tzname[0], "AEST") || strcmp(tzname[1], "AEDT")) - exit(1); -#endif -#if HAVE_STRUCT_TM_TM_ZONE - if (strcmp(localtime(&groundhogday)->tm_zone, "AEDT")) - exit(1); - if (strcmp(localtime(&midyear)->tm_zone, "AEST")) - exit(1); -#endif - exit(0); -} +if test $pkg_failed = yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - ac_cv_working_tzset=yes +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes else - ac_cv_working_tzset=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext + _pkg_short_errors_supported=no fi + if test $_pkg_short_errors_supported = yes; then + PANEL_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "panel" 2>&1` + else + PANEL_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "panel" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$PANEL_PKG_ERRORS" >&5 -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_working_tzset" >&5 -$as_echo "$ac_cv_working_tzset" >&6; } -if test "$ac_cv_working_tzset" = yes -then -$as_echo "#define HAVE_WORKING_TZSET 1" >>confdefs.h + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS -fi -# Look for subsecond timestamps in struct stat -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for tv_nsec in struct stat" >&5 -$as_echo_n "checking for tv_nsec in struct stat... " >&6; } -if ${ac_cv_stat_tv_nsec+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for update_panels in -lpanel" >&5 +printf %s "checking for update_panels in -lpanel... " >&6; } +if test ${ac_cv_lib_panel_update_panels+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_check_lib_save_LIBS=$LIBS +LIBS="-lpanel $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char update_panels (); int -main () +main (void) { - -struct stat st; -st.st_mtim.tv_nsec = 1; - +return update_panels (); ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_stat_tv_nsec=yes -else - ac_cv_stat_tv_nsec=no +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_panel_update_panels=yes +else $as_nop + ac_cv_lib_panel_update_panels=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_stat_tv_nsec" >&5 -$as_echo "$ac_cv_stat_tv_nsec" >&6; } -if test "$ac_cv_stat_tv_nsec" = yes -then +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_panel_update_panels" >&5 +printf "%s\n" "$ac_cv_lib_panel_update_panels" >&6; } +if test "x$ac_cv_lib_panel_update_panels" = xyes +then : -$as_echo "#define HAVE_STAT_TV_NSEC 1" >>confdefs.h + have_panel=panel + PANEL_CFLAGS=${PANEL_CFLAGS-""} + PANEL_LIBS=${PANEL_LIBS-"-lpanel"} fi -# Look for BSD style subsecond timestamps in struct stat -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for tv_nsec2 in struct stat" >&5 -$as_echo_n "checking for tv_nsec2 in struct stat... " >&6; } -if ${ac_cv_stat_tv_nsec2+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + +elif test $pkg_failed = untried; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + + save_CFLAGS=$CFLAGS +save_CPPFLAGS=$CPPFLAGS +save_LDFLAGS=$LDFLAGS +save_LIBS=$LIBS + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for update_panels in -lpanel" >&5 +printf %s "checking for update_panels in -lpanel... " >&6; } +if test ${ac_cv_lib_panel_update_panels+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_check_lib_save_LIBS=$LIBS +LIBS="-lpanel $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +char update_panels (); int -main () +main (void) { - -struct stat st; -st.st_mtimespec.tv_nsec = 1; - +return update_panels (); ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_stat_tv_nsec2=yes -else - ac_cv_stat_tv_nsec2=no +if ac_fn_c_try_link "$LINENO" +then : + ac_cv_lib_panel_update_panels=yes +else $as_nop + ac_cv_lib_panel_update_panels=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_stat_tv_nsec2" >&5 -$as_echo "$ac_cv_stat_tv_nsec2" >&6; } -if test "$ac_cv_stat_tv_nsec2" = yes -then +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_panel_update_panels" >&5 +printf "%s\n" "$ac_cv_lib_panel_update_panels" >&6; } +if test "x$ac_cv_lib_panel_update_panels" = xyes +then : -$as_echo "#define HAVE_STAT_TV_NSEC2 1" >>confdefs.h + have_panel=panel + PANEL_CFLAGS=${PANEL_CFLAGS-""} + PANEL_LIBS=${PANEL_LIBS-"-lpanel"} + +fi + + +CFLAGS=$save_CFLAGS +CPPFLAGS=$save_CPPFLAGS +LDFLAGS=$save_LDFLAGS +LIBS=$save_LIBS + + + +else + PANEL_CFLAGS=$pkg_cv_PANEL_CFLAGS + PANEL_LIBS=$pkg_cv_PANEL_LIBS + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + + have_panel=panel fi -# first curses header check -ac_save_cppflags="$CPPFLAGS" -if test "$cross_compiling" = no; then - CPPFLAGS="$CPPFLAGS -I/usr/include/ncursesw" fi -for ac_header in curses.h ncurses.h -do : - as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" -if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF fi +PANEL_CFLAGS=$(echo $PANEL_CFLAGS | sed 's/-D_XOPEN_SOURCE=600//g') -done +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking panel flags" >&5 +printf %s "checking panel flags... " >&6; } +if test "x$have_panel" = xno +then : + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + +else $as_nop + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_panel (CFLAGS: $PANEL_CFLAGS, LIBS: $PANEL_LIBS)" >&5 +printf "%s\n" "$have_panel (CFLAGS: $PANEL_CFLAGS, LIBS: $PANEL_LIBS)" >&6; } +fi + +# first curses header check +ac_save_cppflags="$CPPFLAGS" +if test "$cross_compiling" = no; then + CPPFLAGS="$CPPFLAGS -I/usr/include/ncursesw" +fi # On Solaris, term.h requires curses.h -for ac_header in term.h -do : - ac_fn_c_check_header_compile "$LINENO" "term.h" "ac_cv_header_term_h" " +ac_fn_c_check_header_compile "$LINENO" "term.h" "ac_cv_header_term_h" " #ifdef HAVE_CURSES_H #include #endif " -if test "x$ac_cv_header_term_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_TERM_H 1 -_ACEOF +if test "x$ac_cv_header_term_h" = xyes +then : + printf "%s\n" "#define HAVE_TERM_H 1" >>confdefs.h fi -done - # On HP/UX 11.0, mvwdelch is a block with a return statement -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether mvwdelch is an expression" >&5 -$as_echo_n "checking whether mvwdelch is an expression... " >&6; } -if ${ac_cv_mvwdelch_is_expression+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether mvwdelch is an expression" >&5 +printf %s "checking whether mvwdelch is an expression... " >&6; } +if test ${ac_cv_mvwdelch_is_expression+y} +then : + printf %s "(cached) " >&6 +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int -main () +main (void) { int rtn; @@ -21577,20 +26533,21 @@ main () return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : ac_cv_mvwdelch_is_expression=yes -else +else $as_nop ac_cv_mvwdelch_is_expression=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_mvwdelch_is_expression" >&5 -$as_echo "$ac_cv_mvwdelch_is_expression" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_mvwdelch_is_expression" >&5 +printf "%s\n" "$ac_cv_mvwdelch_is_expression" >&6; } if test "$ac_cv_mvwdelch_is_expression" = yes then -$as_echo "#define MVWDELCH_IS_EXPRESSION 1" >>confdefs.h +printf "%s\n" "#define MVWDELCH_IS_EXPRESSION 1" >>confdefs.h fi @@ -21598,11 +26555,12 @@ fi # 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 : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether WINDOW has _flags" >&5 +printf %s "checking whether WINDOW has _flags... " >&6; } +if test ${ac_cv_window_has_flags+y} +then : + printf %s "(cached) " >&6 +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -21610,7 +26568,7 @@ else #include int -main () +main (void) { WINDOW *w; @@ -21620,21 +26578,22 @@ main () return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : ac_cv_window_has_flags=yes -else +else $as_nop ac_cv_window_has_flags=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_window_has_flags" >&5 -$as_echo "$ac_cv_window_has_flags" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_window_has_flags" >&5 +printf "%s\n" "$ac_cv_window_has_flags" >&6; } if test "$ac_cv_window_has_flags" = yes then -$as_echo "#define WINDOW_HAS_FLAGS 1" >>confdefs.h +printf "%s\n" "#define WINDOW_HAS_FLAGS 1" >>confdefs.h fi @@ -21642,16 +26601,17 @@ fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for curses function is_pad" >&5 -$as_echo_n "checking for curses function is_pad... " >&6; } -if ${ac_cv_lib_curses_is_pad+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for curses function is_pad" >&5 +printf %s "checking for curses function is_pad... " >&6; } +if test ${ac_cv_lib_curses_is_pad+y} +then : + printf %s "(cached) " >&6 +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int -main () +main (void) { #ifndef is_pad @@ -21662,19 +26622,21 @@ main () return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : ac_cv_lib_curses_is_pad=yes -else +else $as_nop ac_cv_lib_curses_is_pad=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_is_pad" >&5 -$as_echo "$ac_cv_lib_curses_is_pad" >&6; } - if test "x$ac_cv_lib_curses_is_pad" = xyes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_is_pad" >&5 +printf "%s\n" "$ac_cv_lib_curses_is_pad" >&6; } + if test "x$ac_cv_lib_curses_is_pad" = xyes +then : -$as_echo "#define HAVE_CURSES_IS_PAD 1" >>confdefs.h +printf "%s\n" "#define HAVE_CURSES_IS_PAD 1" >>confdefs.h fi @@ -21682,16 +26644,17 @@ fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for curses function is_term_resized" >&5 -$as_echo_n "checking for curses function is_term_resized... " >&6; } -if ${ac_cv_lib_curses_is_term_resized+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for curses function is_term_resized" >&5 +printf %s "checking for curses function is_term_resized... " >&6; } +if test ${ac_cv_lib_curses_is_term_resized+y} +then : + printf %s "(cached) " >&6 +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int -main () +main (void) { #ifndef is_term_resized @@ -21702,19 +26665,21 @@ main () return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : ac_cv_lib_curses_is_term_resized=yes -else +else $as_nop ac_cv_lib_curses_is_term_resized=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_is_term_resized" >&5 -$as_echo "$ac_cv_lib_curses_is_term_resized" >&6; } - if test "x$ac_cv_lib_curses_is_term_resized" = xyes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_is_term_resized" >&5 +printf "%s\n" "$ac_cv_lib_curses_is_term_resized" >&6; } + if test "x$ac_cv_lib_curses_is_term_resized" = xyes +then : -$as_echo "#define HAVE_CURSES_IS_TERM_RESIZED 1" >>confdefs.h +printf "%s\n" "#define HAVE_CURSES_IS_TERM_RESIZED 1" >>confdefs.h fi @@ -21722,16 +26687,17 @@ fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for curses function resize_term" >&5 -$as_echo_n "checking for curses function resize_term... " >&6; } -if ${ac_cv_lib_curses_resize_term+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for curses function resize_term" >&5 +printf %s "checking for curses function resize_term... " >&6; } +if test ${ac_cv_lib_curses_resize_term+y} +then : + printf %s "(cached) " >&6 +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int -main () +main (void) { #ifndef resize_term @@ -21742,19 +26708,21 @@ main () return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : ac_cv_lib_curses_resize_term=yes -else +else $as_nop ac_cv_lib_curses_resize_term=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_resize_term" >&5 -$as_echo "$ac_cv_lib_curses_resize_term" >&6; } - if test "x$ac_cv_lib_curses_resize_term" = xyes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_resize_term" >&5 +printf "%s\n" "$ac_cv_lib_curses_resize_term" >&6; } + if test "x$ac_cv_lib_curses_resize_term" = xyes +then : -$as_echo "#define HAVE_CURSES_RESIZE_TERM 1" >>confdefs.h +printf "%s\n" "#define HAVE_CURSES_RESIZE_TERM 1" >>confdefs.h fi @@ -21762,16 +26730,17 @@ fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for curses function resizeterm" >&5 -$as_echo_n "checking for curses function resizeterm... " >&6; } -if ${ac_cv_lib_curses_resizeterm+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for curses function resizeterm" >&5 +printf %s "checking for curses function resizeterm... " >&6; } +if test ${ac_cv_lib_curses_resizeterm+y} +then : + printf %s "(cached) " >&6 +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int -main () +main (void) { #ifndef resizeterm @@ -21782,19 +26751,21 @@ main () return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : ac_cv_lib_curses_resizeterm=yes -else +else $as_nop ac_cv_lib_curses_resizeterm=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_resizeterm" >&5 -$as_echo "$ac_cv_lib_curses_resizeterm" >&6; } - if test "x$ac_cv_lib_curses_resizeterm" = xyes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_resizeterm" >&5 +printf "%s\n" "$ac_cv_lib_curses_resizeterm" >&6; } + if test "x$ac_cv_lib_curses_resizeterm" = xyes +then : -$as_echo "#define HAVE_CURSES_RESIZETERM 1" >>confdefs.h +printf "%s\n" "#define HAVE_CURSES_RESIZETERM 1" >>confdefs.h fi @@ -21802,16 +26773,17 @@ fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for curses function immedok" >&5 -$as_echo_n "checking for curses function immedok... " >&6; } -if ${ac_cv_lib_curses_immedok+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for curses function immedok" >&5 +printf %s "checking for curses function immedok... " >&6; } +if test ${ac_cv_lib_curses_immedok+y} +then : + printf %s "(cached) " >&6 +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int -main () +main (void) { #ifndef immedok @@ -21822,19 +26794,21 @@ main () return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : ac_cv_lib_curses_immedok=yes -else +else $as_nop ac_cv_lib_curses_immedok=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_immedok" >&5 -$as_echo "$ac_cv_lib_curses_immedok" >&6; } - if test "x$ac_cv_lib_curses_immedok" = xyes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_immedok" >&5 +printf "%s\n" "$ac_cv_lib_curses_immedok" >&6; } + if test "x$ac_cv_lib_curses_immedok" = xyes +then : -$as_echo "#define HAVE_CURSES_IMMEDOK 1" >>confdefs.h +printf "%s\n" "#define HAVE_CURSES_IMMEDOK 1" >>confdefs.h fi @@ -21842,16 +26816,17 @@ fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for curses function syncok" >&5 -$as_echo_n "checking for curses function syncok... " >&6; } -if ${ac_cv_lib_curses_syncok+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for curses function syncok" >&5 +printf %s "checking for curses function syncok... " >&6; } +if test ${ac_cv_lib_curses_syncok+y} +then : + printf %s "(cached) " >&6 +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int -main () +main (void) { #ifndef syncok @@ -21862,19 +26837,21 @@ main () return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : ac_cv_lib_curses_syncok=yes -else +else $as_nop ac_cv_lib_curses_syncok=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_syncok" >&5 -$as_echo "$ac_cv_lib_curses_syncok" >&6; } - if test "x$ac_cv_lib_curses_syncok" = xyes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_syncok" >&5 +printf "%s\n" "$ac_cv_lib_curses_syncok" >&6; } + if test "x$ac_cv_lib_curses_syncok" = xyes +then : -$as_echo "#define HAVE_CURSES_SYNCOK 1" >>confdefs.h +printf "%s\n" "#define HAVE_CURSES_SYNCOK 1" >>confdefs.h fi @@ -21882,16 +26859,17 @@ fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for curses function wchgat" >&5 -$as_echo_n "checking for curses function wchgat... " >&6; } -if ${ac_cv_lib_curses_wchgat+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for curses function wchgat" >&5 +printf %s "checking for curses function wchgat... " >&6; } +if test ${ac_cv_lib_curses_wchgat+y} +then : + printf %s "(cached) " >&6 +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int -main () +main (void) { #ifndef wchgat @@ -21902,19 +26880,21 @@ main () return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : ac_cv_lib_curses_wchgat=yes -else +else $as_nop ac_cv_lib_curses_wchgat=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_wchgat" >&5 -$as_echo "$ac_cv_lib_curses_wchgat" >&6; } - if test "x$ac_cv_lib_curses_wchgat" = xyes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_wchgat" >&5 +printf "%s\n" "$ac_cv_lib_curses_wchgat" >&6; } + if test "x$ac_cv_lib_curses_wchgat" = xyes +then : -$as_echo "#define HAVE_CURSES_WCHGAT 1" >>confdefs.h +printf "%s\n" "#define HAVE_CURSES_WCHGAT 1" >>confdefs.h fi @@ -21922,16 +26902,17 @@ fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for curses function filter" >&5 -$as_echo_n "checking for curses function filter... " >&6; } -if ${ac_cv_lib_curses_filter+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for curses function filter" >&5 +printf %s "checking for curses function filter... " >&6; } +if test ${ac_cv_lib_curses_filter+y} +then : + printf %s "(cached) " >&6 +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int -main () +main (void) { #ifndef filter @@ -21942,19 +26923,21 @@ main () return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : ac_cv_lib_curses_filter=yes -else +else $as_nop ac_cv_lib_curses_filter=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_filter" >&5 -$as_echo "$ac_cv_lib_curses_filter" >&6; } - if test "x$ac_cv_lib_curses_filter" = xyes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_filter" >&5 +printf "%s\n" "$ac_cv_lib_curses_filter" >&6; } + if test "x$ac_cv_lib_curses_filter" = xyes +then : -$as_echo "#define HAVE_CURSES_FILTER 1" >>confdefs.h +printf "%s\n" "#define HAVE_CURSES_FILTER 1" >>confdefs.h fi @@ -21962,16 +26945,17 @@ fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for curses function has_key" >&5 -$as_echo_n "checking for curses function has_key... " >&6; } -if ${ac_cv_lib_curses_has_key+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for curses function has_key" >&5 +printf %s "checking for curses function has_key... " >&6; } +if test ${ac_cv_lib_curses_has_key+y} +then : + printf %s "(cached) " >&6 +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int -main () +main (void) { #ifndef has_key @@ -21982,19 +26966,21 @@ main () return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : ac_cv_lib_curses_has_key=yes -else +else $as_nop ac_cv_lib_curses_has_key=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_has_key" >&5 -$as_echo "$ac_cv_lib_curses_has_key" >&6; } - if test "x$ac_cv_lib_curses_has_key" = xyes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_has_key" >&5 +printf "%s\n" "$ac_cv_lib_curses_has_key" >&6; } + if test "x$ac_cv_lib_curses_has_key" = xyes +then : -$as_echo "#define HAVE_CURSES_HAS_KEY 1" >>confdefs.h +printf "%s\n" "#define HAVE_CURSES_HAS_KEY 1" >>confdefs.h fi @@ -22002,16 +26988,17 @@ fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for curses function typeahead" >&5 -$as_echo_n "checking for curses function typeahead... " >&6; } -if ${ac_cv_lib_curses_typeahead+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for curses function typeahead" >&5 +printf %s "checking for curses function typeahead... " >&6; } +if test ${ac_cv_lib_curses_typeahead+y} +then : + printf %s "(cached) " >&6 +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int -main () +main (void) { #ifndef typeahead @@ -22022,19 +27009,21 @@ main () return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : ac_cv_lib_curses_typeahead=yes -else +else $as_nop ac_cv_lib_curses_typeahead=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_typeahead" >&5 -$as_echo "$ac_cv_lib_curses_typeahead" >&6; } - if test "x$ac_cv_lib_curses_typeahead" = xyes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_typeahead" >&5 +printf "%s\n" "$ac_cv_lib_curses_typeahead" >&6; } + if test "x$ac_cv_lib_curses_typeahead" = xyes +then : -$as_echo "#define HAVE_CURSES_TYPEAHEAD 1" >>confdefs.h +printf "%s\n" "#define HAVE_CURSES_TYPEAHEAD 1" >>confdefs.h fi @@ -22042,16 +27031,17 @@ fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for curses function use_env" >&5 -$as_echo_n "checking for curses function use_env... " >&6; } -if ${ac_cv_lib_curses_use_env+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for curses function use_env" >&5 +printf %s "checking for curses function use_env... " >&6; } +if test ${ac_cv_lib_curses_use_env+y} +then : + printf %s "(cached) " >&6 +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int -main () +main (void) { #ifndef use_env @@ -22062,19 +27052,21 @@ main () return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : ac_cv_lib_curses_use_env=yes -else +else $as_nop ac_cv_lib_curses_use_env=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_use_env" >&5 -$as_echo "$ac_cv_lib_curses_use_env" >&6; } - if test "x$ac_cv_lib_curses_use_env" = xyes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_curses_use_env" >&5 +printf "%s\n" "$ac_cv_lib_curses_use_env" >&6; } + if test "x$ac_cv_lib_curses_use_env" = xyes +then : -$as_echo "#define HAVE_CURSES_USE_ENV 1" >>confdefs.h +printf "%s\n" "#define HAVE_CURSES_USE_ENV 1" >>confdefs.h fi @@ -22082,31 +27074,32 @@ fi CPPFLAGS=$ac_save_cppflags -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for device files" >&5 -$as_echo "$as_me: checking for device files" >&6;} +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for device files" >&5 +printf "%s\n" "$as_me: checking for device files" >&6;} if test "x$cross_compiling" = xyes; then if test "${ac_cv_file__dev_ptmx+set}" != set; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for /dev/ptmx" >&5 -$as_echo_n "checking for /dev/ptmx... " >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: result: not set" >&5 -$as_echo "not set" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for /dev/ptmx" >&5 +printf %s "checking for /dev/ptmx... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: not set" >&5 +printf "%s\n" "not set" >&6; } as_fn_error $? "set ac_cv_file__dev_ptmx to yes/no in your CONFIG_SITE file when cross compiling" "$LINENO" 5 fi if test "${ac_cv_file__dev_ptc+set}" != set; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for /dev/ptc" >&5 -$as_echo_n "checking for /dev/ptc... " >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: result: not set" >&5 -$as_echo "not set" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for /dev/ptc" >&5 +printf %s "checking for /dev/ptc... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: not set" >&5 +printf "%s\n" "not set" >&6; } as_fn_error $? "set ac_cv_file__dev_ptc to yes/no in your CONFIG_SITE file when cross compiling" "$LINENO" 5 fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for /dev/ptmx" >&5 -$as_echo_n "checking for /dev/ptmx... " >&6; } -if ${ac_cv_file__dev_ptmx+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for /dev/ptmx" >&5 +printf %s "checking for /dev/ptmx... " >&6; } +if test ${ac_cv_file__dev_ptmx+y} +then : + printf %s "(cached) " >&6 +else $as_nop test "$cross_compiling" = yes && as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 if test -r "/dev/ptmx"; then @@ -22115,22 +27108,24 @@ else ac_cv_file__dev_ptmx=no fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_file__dev_ptmx" >&5 -$as_echo "$ac_cv_file__dev_ptmx" >&6; } -if test "x$ac_cv_file__dev_ptmx" = xyes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_file__dev_ptmx" >&5 +printf "%s\n" "$ac_cv_file__dev_ptmx" >&6; } +if test "x$ac_cv_file__dev_ptmx" = xyes +then : fi if test "x$ac_cv_file__dev_ptmx" = xyes; then -$as_echo "#define HAVE_DEV_PTMX 1" >>confdefs.h +printf "%s\n" "#define HAVE_DEV_PTMX 1" >>confdefs.h fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for /dev/ptc" >&5 -$as_echo_n "checking for /dev/ptc... " >&6; } -if ${ac_cv_file__dev_ptc+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for /dev/ptc" >&5 +printf %s "checking for /dev/ptc... " >&6; } +if test ${ac_cv_file__dev_ptc+y} +then : + printf %s "(cached) " >&6 +else $as_nop test "$cross_compiling" = yes && as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 if test -r "/dev/ptc"; then @@ -22139,15 +27134,16 @@ else ac_cv_file__dev_ptc=no fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_file__dev_ptc" >&5 -$as_echo "$ac_cv_file__dev_ptc" >&6; } -if test "x$ac_cv_file__dev_ptc" = xyes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_file__dev_ptc" >&5 +printf "%s\n" "$ac_cv_file__dev_ptc" >&6; } +if test "x$ac_cv_file__dev_ptc" = xyes +then : fi if test "x$ac_cv_file__dev_ptc" = xyes; then -$as_echo "#define HAVE_DEV_PTC 1" >>confdefs.h +printf "%s\n" "#define HAVE_DEV_PTC 1" >>confdefs.h fi @@ -22156,72 +27152,6 @@ then LIBS="$LIBS -framework CoreFoundation" fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for %zd printf() format support" >&5 -$as_echo_n "checking for %zd printf() format support... " >&6; } -if ${ac_cv_have_size_t_format+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "$cross_compiling" = yes; then : - ac_cv_have_size_t_format="cross -- assuming yes" - -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#include -#include -#include - -#ifdef HAVE_SYS_TYPES_H -#include -#endif - -#ifdef HAVE_SSIZE_T -typedef ssize_t Py_ssize_t; -#elif SIZEOF_VOID_P == SIZEOF_LONG -typedef long Py_ssize_t; -#else -typedef int Py_ssize_t; -#endif - -int main() -{ - char buffer[256]; - - if(sprintf(buffer, "%zd", (size_t)123) < 0) - return 1; - - if (strcmp(buffer, "123")) - return 1; - - if (sprintf(buffer, "%zd", (Py_ssize_t)-123) < 0) - return 1; - - if (strcmp(buffer, "-123")) - return 1; - - return 0; -} - -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - ac_cv_have_size_t_format=yes -else - ac_cv_have_size_t_format=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_size_t_format" >&5 -$as_echo "$ac_cv_have_size_t_format" >&6; } -if test "$ac_cv_have_size_t_format" != no ; then - -$as_echo "#define PY_FORMAT_SIZE_T \"z\"" >>confdefs.h - -fi - ac_fn_c_check_type "$LINENO" "socklen_t" "ac_cv_type_socklen_t" " #ifdef HAVE_SYS_TYPES_H #include @@ -22231,23 +27161,26 @@ ac_fn_c_check_type "$LINENO" "socklen_t" "ac_cv_type_socklen_t" " #endif " -if test "x$ac_cv_type_socklen_t" = xyes; then : +if test "x$ac_cv_type_socklen_t" = xyes +then : -else +else $as_nop -$as_echo "#define socklen_t int" >>confdefs.h +printf "%s\n" "#define socklen_t int" >>confdefs.h fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for broken mbstowcs" >&5 -$as_echo_n "checking for broken mbstowcs... " >&6; } -if ${ac_cv_broken_mbstowcs+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "$cross_compiling" = yes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for broken mbstowcs" >&5 +printf %s "checking for broken mbstowcs... " >&6; } +if test ${ac_cv_broken_mbstowcs+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test "$cross_compiling" = yes +then : ac_cv_broken_mbstowcs=no -else +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -22262,9 +27195,10 @@ int main(void) { } _ACEOF -if ac_fn_c_try_run "$LINENO"; then : +if ac_fn_c_try_run "$LINENO" +then : ac_cv_broken_mbstowcs=no -else +else $as_nop ac_cv_broken_mbstowcs=yes fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -22272,57 +27206,60 @@ rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_broken_mbstowcs" >&5 -$as_echo "$ac_cv_broken_mbstowcs" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_broken_mbstowcs" >&5 +printf "%s\n" "$ac_cv_broken_mbstowcs" >&6; } if test "$ac_cv_broken_mbstowcs" = yes then -$as_echo "#define HAVE_BROKEN_MBSTOWCS 1" >>confdefs.h +printf "%s\n" "#define HAVE_BROKEN_MBSTOWCS 1" >>confdefs.h fi # Check for --with-computed-gotos -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-computed-gotos" >&5 -$as_echo_n "checking for --with-computed-gotos... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-computed-gotos" >&5 +printf %s "checking for --with-computed-gotos... " >&6; } # Check whether --with-computed-gotos was given. -if test "${with_computed_gotos+set}" = set; then : +if test ${with_computed_gotos+y} +then : withval=$with_computed_gotos; if test "$withval" = yes then -$as_echo "#define USE_COMPUTED_GOTOS 1" >>confdefs.h +printf "%s\n" "#define USE_COMPUTED_GOTOS 1" >>confdefs.h - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } fi if test "$withval" = no then -$as_echo "#define USE_COMPUTED_GOTOS 0" >>confdefs.h +printf "%s\n" "#define USE_COMPUTED_GOTOS 0" >>confdefs.h - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no value specified" >&5 -$as_echo "no value specified" >&6; } +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no value specified" >&5 +printf "%s\n" "no value specified" >&6; } fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports computed gotos" >&5 -$as_echo_n "checking whether $CC supports computed gotos... " >&6; } -if ${ac_cv_computed_gotos+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "$cross_compiling" = yes; then : +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC supports computed gotos" >&5 +printf %s "checking whether $CC supports computed gotos... " >&6; } +if test ${ac_cv_computed_gotos+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test "$cross_compiling" = yes +then : if test "${with_computed_gotos+set}" = set; then ac_cv_computed_gotos="$with_computed_gotos -- configured --with(out)-computed-gotos" else ac_cv_computed_gotos=no fi -else +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -22338,9 +27275,10 @@ LABEL2: } _ACEOF -if ac_fn_c_try_run "$LINENO"; then : +if ac_fn_c_try_run "$LINENO" +then : ac_cv_computed_gotos=yes -else +else $as_nop ac_cv_computed_gotos=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -22348,18 +27286,18 @@ rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_computed_gotos" >&5 -$as_echo "$ac_cv_computed_gotos" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_computed_gotos" >&5 +printf "%s\n" "$ac_cv_computed_gotos" >&6; } case "$ac_cv_computed_gotos" in yes*) -$as_echo "#define HAVE_COMPUTED_GOTOS 1" >>confdefs.h +printf "%s\n" "#define HAVE_COMPUTED_GOTOS 1" >>confdefs.h esac case $ac_sys_system in AIX*) -$as_echo "#define HAVE_BROKEN_PIPE_BUF 1" >>confdefs.h +printf "%s\n" "#define HAVE_BROKEN_PIPE_BUF 1" >>confdefs.h ;; esac @@ -22378,11 +27316,12 @@ SRCDIRS="\ Modules/_ctypes \ Modules/_decimal \ Modules/_decimal/libmpdec \ + Modules/_hacl \ Modules/_io \ Modules/_multiprocessing \ - Modules/_sha3 \ Modules/_sqlite \ Modules/_sre \ + Modules/_testcapi \ Modules/_xxtestfuzz \ Modules/cjkcodecs \ Modules/expat \ @@ -22392,22 +27331,23 @@ SRCDIRS="\ Python \ Python/frozen_modules \ Python/deepfreeze" -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for build directories" >&5 -$as_echo_n "checking for build directories... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for build directories" >&5 +printf %s "checking for build directories... " >&6; } for dir in $SRCDIRS; do if test ! -d $dir; then mkdir $dir fi done -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 -$as_echo "done" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: done" >&5 +printf "%s\n" "done" >&6; } # Availability of -O2: -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for -O2" >&5 -$as_echo_n "checking for -O2... " >&6; } -if ${ac_cv_compile_o2+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -O2" >&5 +printf %s "checking for -O2... " >&6; } +if test ${ac_cv_compile_o2+y} +then : + printf %s "(cached) " >&6 +else $as_nop saved_cflags="$CFLAGS" CFLAGS="-O2" @@ -22415,37 +27355,39 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int -main () +main (void) { ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_compile "$LINENO" +then : ac_cv_compile_o2=yes -else +else $as_nop ac_cv_compile_o2=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext CFLAGS="$saved_cflags" fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_compile_o2" >&5 -$as_echo "$ac_cv_compile_o2" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_compile_o2" >&5 +printf "%s\n" "$ac_cv_compile_o2" >&6; } # _FORTIFY_SOURCE wrappers for memmove and bcopy are incorrect: # http://sourceware.org/ml/libc-alpha/2010-12/msg00009.html -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for glibc _FORTIFY_SOURCE/memmove bug" >&5 -$as_echo_n "checking for glibc _FORTIFY_SOURCE/memmove bug... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for glibc _FORTIFY_SOURCE/memmove bug" >&5 +printf %s "checking for glibc _FORTIFY_SOURCE/memmove bug... " >&6; } saved_cflags="$CFLAGS" CFLAGS="-O2 -D_FORTIFY_SOURCE=2" if test "$ac_cv_compile_o2" = no; then CFLAGS="" fi -if test "$cross_compiling" = yes; then : +if test "$cross_compiling" = yes +then : have_glibc_memmove_bug=undefined -else +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -22465,9 +27407,10 @@ int main(void) { } _ACEOF -if ac_fn_c_try_run "$LINENO"; then : +if ac_fn_c_try_run "$LINENO" +then : have_glibc_memmove_bug=no -else +else $as_nop have_glibc_memmove_bug=yes fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -22475,11 +27418,11 @@ rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ fi CFLAGS="$saved_cflags" -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_glibc_memmove_bug" >&5 -$as_echo "$have_glibc_memmove_bug" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_glibc_memmove_bug" >&5 +printf "%s\n" "$have_glibc_memmove_bug" >&6; } if test "$have_glibc_memmove_bug" = yes; then -$as_echo "#define HAVE_GLIBC_MEMMOVE_BUG 1" >>confdefs.h +printf "%s\n" "#define HAVE_GLIBC_MEMMOVE_BUG 1" >>confdefs.h fi @@ -22489,13 +27432,14 @@ if test "$ac_cv_gcc_asm_for_x87" = yes; then # http://gcc.gnu.org/ml/gcc/2010-11/msg00366.html case $CC in *gcc*) - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gcc ipa-pure-const bug" >&5 -$as_echo_n "checking for gcc ipa-pure-const bug... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gcc ipa-pure-const bug" >&5 +printf %s "checking for gcc ipa-pure-const bug... " >&6; } saved_cflags="$CFLAGS" CFLAGS="-O2" - if test "$cross_compiling" = yes; then : + if test "$cross_compiling" = yes +then : have_ipa_pure_const_bug=undefined -else +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -22516,9 +27460,10 @@ else } _ACEOF -if ac_fn_c_try_run "$LINENO"; then : +if ac_fn_c_try_run "$LINENO" +then : have_ipa_pure_const_bug=no -else +else $as_nop have_ipa_pure_const_bug=yes fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ @@ -22526,11 +27471,11 @@ rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ fi CFLAGS="$saved_cflags" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_ipa_pure_const_bug" >&5 -$as_echo "$have_ipa_pure_const_bug" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_ipa_pure_const_bug" >&5 +printf "%s\n" "$have_ipa_pure_const_bug" >&6; } if test "$have_ipa_pure_const_bug" = yes; then -$as_echo "#define HAVE_IPA_PURE_CONST_BUG 1" >>confdefs.h +printf "%s\n" "#define HAVE_IPA_PURE_CONST_BUG 1" >>confdefs.h fi ;; @@ -22538,11 +27483,12 @@ $as_echo "#define HAVE_IPA_PURE_CONST_BUG 1" >>confdefs.h fi # Check for stdatomic.h -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdatomic.h" >&5 -$as_echo_n "checking for stdatomic.h... " >&6; } -if ${ac_cv_header_stdatomic_h+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdatomic.h" >&5 +printf %s "checking for stdatomic.h... " >&6; } +if test ${ac_cv_header_stdatomic_h+y} +then : + printf %s "(cached) " >&6 +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -22560,32 +27506,35 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_header_stdatomic_h=yes -else +else $as_nop ac_cv_header_stdatomic_h=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdatomic_h" >&5 -$as_echo "$ac_cv_header_stdatomic_h" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdatomic_h" >&5 +printf "%s\n" "$ac_cv_header_stdatomic_h" >&6; } -if test "x$ac_cv_header_stdatomic_h" = xyes; then : +if test "x$ac_cv_header_stdatomic_h" = xyes +then : -$as_echo "#define HAVE_STD_ATOMIC 1" >>confdefs.h +printf "%s\n" "#define HAVE_STD_ATOMIC 1" >>confdefs.h fi # Check for GCC >= 4.7 and clang __atomic builtin functions -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for builtin __atomic_load_n and __atomic_store_n functions" >&5 -$as_echo_n "checking for builtin __atomic_load_n and __atomic_store_n functions... " >&6; } -if ${ac_cv_builtin_atomic+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for builtin __atomic_load_n and __atomic_store_n functions" >&5 +printf %s "checking for builtin __atomic_load_n and __atomic_store_n functions... " >&6; } +if test ${ac_cv_builtin_atomic+y} +then : + printf %s "(cached) " >&6 +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -22600,34 +27549,37 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_builtin_atomic=yes -else +else $as_nop ac_cv_builtin_atomic=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_builtin_atomic" >&5 -$as_echo "$ac_cv_builtin_atomic" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_builtin_atomic" >&5 +printf "%s\n" "$ac_cv_builtin_atomic" >&6; } -if test "x$ac_cv_builtin_atomic" = xyes; then : +if test "x$ac_cv_builtin_atomic" = xyes +then : -$as_echo "#define HAVE_BUILTIN_ATOMIC 1" >>confdefs.h +printf "%s\n" "#define HAVE_BUILTIN_ATOMIC 1" >>confdefs.h fi # ensurepip option -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ensurepip" >&5 -$as_echo_n "checking for ensurepip... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ensurepip" >&5 +printf %s "checking for ensurepip... " >&6; } # Check whether --with-ensurepip was given. -if test "${with_ensurepip+set}" = set; then : +if test ${with_ensurepip+y} +then : withval=$with_ensurepip; -else +else $as_nop case $ac_sys_system in #( Emscripten) : @@ -22651,16 +27603,17 @@ case $with_ensurepip in #( *) : as_fn_error $? "--with-ensurepip=upgrade|install|no" "$LINENO" 5 ;; esac -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ENSUREPIP" >&5 -$as_echo "$ENSUREPIP" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ENSUREPIP" >&5 +printf "%s\n" "$ENSUREPIP" >&6; } # check if the dirent structure of a d_type field and DT_UNKNOWN is defined -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the dirent structure of a d_type field" >&5 -$as_echo_n "checking if the dirent structure of a d_type field... " >&6; } -if ${ac_cv_dirent_d_type+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if the dirent structure of a d_type field" >&5 +printf %s "checking if the dirent structure of a d_type field... " >&6; } +if test ${ac_cv_dirent_d_type+y} +then : + printf %s "(cached) " >&6 +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -22675,32 +27628,35 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_dirent_d_type=yes -else +else $as_nop ac_cv_dirent_d_type=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_dirent_d_type" >&5 -$as_echo "$ac_cv_dirent_d_type" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_dirent_d_type" >&5 +printf "%s\n" "$ac_cv_dirent_d_type" >&6; } -if test "x$ac_cv_dirent_d_type" = xyes; then : +if test "x$ac_cv_dirent_d_type" = xyes +then : -$as_echo "#define HAVE_DIRENT_D_TYPE 1" >>confdefs.h +printf "%s\n" "#define HAVE_DIRENT_D_TYPE 1" >>confdefs.h fi # check if the Linux getrandom() syscall is available -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for the Linux getrandom() syscall" >&5 -$as_echo_n "checking for the Linux getrandom() syscall... " >&6; } -if ${ac_cv_getrandom_syscall+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for the Linux getrandom() syscall" >&5 +printf %s "checking for the Linux getrandom() syscall... " >&6; } +if test ${ac_cv_getrandom_syscall+y} +then : + printf %s "(cached) " >&6 +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -22722,33 +27678,36 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_getrandom_syscall=yes -else +else $as_nop ac_cv_getrandom_syscall=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_getrandom_syscall" >&5 -$as_echo "$ac_cv_getrandom_syscall" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_getrandom_syscall" >&5 +printf "%s\n" "$ac_cv_getrandom_syscall" >&6; } -if test "x$ac_cv_getrandom_syscall" = xyes; then : +if test "x$ac_cv_getrandom_syscall" = xyes +then : -$as_echo "#define HAVE_GETRANDOM_SYSCALL 1" >>confdefs.h +printf "%s\n" "#define HAVE_GETRANDOM_SYSCALL 1" >>confdefs.h fi # check if the getrandom() function is available # the test was written for the Solaris function of -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for the getrandom() function" >&5 -$as_echo_n "checking for the getrandom() function... " >&6; } -if ${ac_cv_func_getrandom+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for the getrandom() function" >&5 +printf %s "checking for the getrandom() function... " >&6; } +if test ${ac_cv_func_getrandom+y} +then : + printf %s "(cached) " >&6 +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -22768,22 +27727,24 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_func_getrandom=yes -else +else $as_nop ac_cv_func_getrandom=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_getrandom" >&5 -$as_echo "$ac_cv_func_getrandom" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_getrandom" >&5 +printf "%s\n" "$ac_cv_func_getrandom" >&6; } -if test "x$ac_cv_func_getrandom" = xyes; then : +if test "x$ac_cv_func_getrandom" = xyes +then : -$as_echo "#define HAVE_GETRANDOM 1" >>confdefs.h +printf "%s\n" "#define HAVE_GETRANDOM 1" >>confdefs.h fi @@ -22797,11 +27758,12 @@ save_LDFLAGS=$LDFLAGS save_LIBS=$LIBS - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing shm_open" >&5 -$as_echo_n "checking for library containing shm_open... " >&6; } -if ${ac_cv_search_shm_open+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing shm_open" >&5 +printf %s "checking for library containing shm_open... " >&6; } +if test ${ac_cv_search_shm_open+y} +then : + printf %s "(cached) " >&6 +else $as_nop ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -22809,51 +27771,54 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif char shm_open (); int -main () +main (void) { return shm_open (); ; return 0; } _ACEOF -for ac_lib in '' rt; do +for ac_lib in '' rt +do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi - if ac_fn_c_try_link "$LINENO"; then : + if ac_fn_c_try_link "$LINENO" +then : ac_cv_search_shm_open=$ac_res fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext - if ${ac_cv_search_shm_open+:} false; then : + if test ${ac_cv_search_shm_open+y} +then : break fi done -if ${ac_cv_search_shm_open+:} false; then : +if test ${ac_cv_search_shm_open+y} +then : -else +else $as_nop ac_cv_search_shm_open=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_shm_open" >&5 -$as_echo "$ac_cv_search_shm_open" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_shm_open" >&5 +printf "%s\n" "$ac_cv_search_shm_open" >&6; } ac_res=$ac_cv_search_shm_open -if test "$ac_res" != no; then : +if test "$ac_res" != no +then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi - if test "x$ac_cv_search_shm_open" = x-lrt; then : + if test "x$ac_cv_search_shm_open" = x-lrt +then : POSIXSHMEM_LIBS="-lrt" fi @@ -22866,20 +27831,22 @@ fi # endif #endif " + for ac_func in shm_open shm_unlink do : - as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` + as_ac_var=`printf "%s\n" "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -if eval test \"x\$"$as_ac_var"\" = x"yes"; then : +if eval test \"x\$"$as_ac_var"\" = x"yes" +then : cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +#define `printf "%s\n" "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF have_posix_shmem=yes -else +else $as_nop have_posix_shmem=no fi -done +done ac_includes_default=$save_ac_includes_default CFLAGS=$save_CFLAGS @@ -22894,7 +27861,8 @@ LIBS=$save_LIBS found=false # Check whether --with-openssl was given. -if test "${with_openssl+set}" = set; then : +if test ${with_openssl+y} +then : withval=$with_openssl; case "$withval" in "" | y | ye | yes | n | no) @@ -22904,18 +27872,19 @@ if test "${with_openssl+set}" = set; then : ;; esac -else +else $as_nop # if pkg-config is installed and openssl has installed a .pc file, # then use that information and don't search ssldirs if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_PKG_CONFIG+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_PKG_CONFIG+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$PKG_CONFIG"; then ac_cv_prog_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test. else @@ -22923,11 +27892,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_PKG_CONFIG="${ac_tool_prefix}pkg-config" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -22938,11 +27911,11 @@ fi fi PKG_CONFIG=$ac_cv_prog_PKG_CONFIG if test -n "$PKG_CONFIG"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 -$as_echo "$PKG_CONFIG" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 +printf "%s\n" "$PKG_CONFIG" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi @@ -22951,11 +27924,12 @@ if test -z "$ac_cv_prog_PKG_CONFIG"; then ac_ct_PKG_CONFIG=$PKG_CONFIG # Extract the first word of "pkg-config", so it can be a program name with args. set dummy pkg-config; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_PKG_CONFIG+:} false; then : - $as_echo_n "(cached) " >&6 -else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_PKG_CONFIG+y} +then : + printf %s "(cached) " >&6 +else $as_nop if test -n "$ac_ct_PKG_CONFIG"; then ac_cv_prog_ac_ct_PKG_CONFIG="$ac_ct_PKG_CONFIG" # Let the user override the test. else @@ -22963,11 +27937,15 @@ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_PKG_CONFIG="pkg-config" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -22978,11 +27956,11 @@ fi fi ac_ct_PKG_CONFIG=$ac_cv_prog_ac_ct_PKG_CONFIG if test -n "$ac_ct_PKG_CONFIG"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_PKG_CONFIG" >&5 -$as_echo "$ac_ct_PKG_CONFIG" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_PKG_CONFIG" >&5 +printf "%s\n" "$ac_ct_PKG_CONFIG" >&6; } else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi if test "x$ac_ct_PKG_CONFIG" = x; then @@ -22990,8 +27968,8 @@ fi else case $cross_compiling:$ac_tool_warned in yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac PKG_CONFIG=$ac_ct_PKG_CONFIG @@ -23025,19 +28003,19 @@ fi if ! $found; then OPENSSL_INCLUDES= for ssldir in $ssldirs; do - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for openssl/ssl.h in $ssldir" >&5 -$as_echo_n "checking for openssl/ssl.h in $ssldir... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for include/openssl/ssl.h in $ssldir" >&5 +printf %s "checking for include/openssl/ssl.h in $ssldir... " >&6; } if test -f "$ssldir/include/openssl/ssl.h"; then OPENSSL_INCLUDES="-I$ssldir/include" OPENSSL_LDFLAGS="-L$ssldir/lib" OPENSSL_LIBS="-lssl -lcrypto" found=true - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } break else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } fi done @@ -23048,8 +28026,8 @@ $as_echo "no" >&6; } # try the preprocessor and linker with our new flags, # being careful not to pollute the global LIBS, LDFLAGS, and CPPFLAGS - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether compiling and linking against OpenSSL works" >&5 -$as_echo_n "checking whether compiling and linking against OpenSSL works... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether compiling and linking against OpenSSL works" >&5 +printf %s "checking whether compiling and linking against OpenSSL works... " >&6; } echo "Trying link with OPENSSL_LDFLAGS=$OPENSSL_LDFLAGS;" \ "OPENSSL_LIBS=$OPENSSL_LIBS; OPENSSL_INCLUDES=$OPENSSL_INCLUDES" >&5 @@ -23063,27 +28041,28 @@ $as_echo_n "checking whether compiling and linking against OpenSSL works... " >& /* end confdefs.h. */ #include int -main () +main (void) { SSL_new(NULL) ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } have_openssl=yes -else +else $as_nop - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } have_openssl=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" @@ -23095,23 +28074,25 @@ rm -f core conftest.err conftest.$ac_objext \ # rpath to libssl and libcrypto -if test "x$GNULD" = xyes; then : +if test "x$GNULD" = xyes +then : rpath_arg="-Wl,--enable-new-dtags,-rpath=" -else +else $as_nop rpath_arg="-Wl,-rpath=" fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-openssl-rpath" >&5 -$as_echo_n "checking for --with-openssl-rpath... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-openssl-rpath" >&5 +printf %s "checking for --with-openssl-rpath... " >&6; } # Check whether --with-openssl-rpath was given. -if test "${with_openssl_rpath+set}" = set; then : +if test ${with_openssl_rpath+y} +then : withval=$with_openssl_rpath; -else +else $as_nop with_openssl_rpath=no fi @@ -23133,29 +28114,30 @@ esac no) : OPENSSL_RPATH= ;; #( *) : - if test -d "$with_openssl_rpath"; then : + if test -d "$with_openssl_rpath" +then : OPENSSL_RPATH="$with_openssl_rpath" OPENSSL_LDFLAGS_RPATH="${rpath_arg}$with_openssl_rpath" -else +else $as_nop as_fn_error $? "--with-openssl-rpath \"$with_openssl_rpath\" is not a directory" "$LINENO" 5 fi ;; esac -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $OPENSSL_RPATH" >&5 -$as_echo "$OPENSSL_RPATH" >&6; } - +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $OPENSSL_RPATH" >&5 +printf "%s\n" "$OPENSSL_RPATH" >&6; } # This static linking is NOT OFFICIALLY SUPPORTED and not advertised. # Requires static OpenSSL build with position-independent code. Some features # like DSO engines or external OSSL providers don't work. Only tested with GCC # and clang on X86_64. -if test "x$PY_UNSUPPORTED_OPENSSL_BUILD" = xstatic; then : +if test "x$PY_UNSUPPORTED_OPENSSL_BUILD" = xstatic +then : - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for unsupported static openssl build" >&5 -$as_echo_n "checking for unsupported static openssl build... " >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for unsupported static openssl build" >&5 +printf %s "checking for unsupported static openssl build... " >&6; } new_OPENSSL_LIBS= for arg in $OPENSSL_LIBS; do case $arg in #( @@ -23170,8 +28152,8 @@ $as_echo_n "checking for unsupported static openssl build... " >&6; } esac done OPENSSL_LIBS="$new_OPENSSL_LIBS $ZLIB_LIBS" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OPENSSL_LIBS" >&5 -$as_echo "$OPENSSL_LIBS" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $OPENSSL_LIBS" >&5 +printf "%s\n" "$OPENSSL_LIBS" >&6; } fi @@ -23197,11 +28179,12 @@ save_LIBS=$LIBS CFLAGS="$CFLAGS $OPENSSL_INCLUDES" LDFLAGS="$LDFLAGS $OPENSSL_LDFLAGS $OPENSSL_LDFLAGS_RPATH" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether OpenSSL provides required ssl module APIs" >&5 -$as_echo_n "checking whether OpenSSL provides required ssl module APIs... " >&6; } -if ${ac_cv_working_openssl_ssl+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether OpenSSL provides required ssl module APIs" >&5 +printf %s "checking whether OpenSSL provides required ssl module APIs... " >&6; } +if test ${ac_cv_working_openssl_ssl+y} +then : + printf %s "(cached) " >&6 +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -23214,7 +28197,7 @@ else static void keylog_cb(const SSL *ssl, const char *line) {} int -main () +main (void) { SSL_CTX *ctx = SSL_CTX_new(TLS_client_method()); @@ -23229,17 +28212,18 @@ main () return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_working_openssl_ssl=yes -else +else $as_nop ac_cv_working_openssl_ssl=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_working_openssl_ssl" >&5 -$as_echo "$ac_cv_working_openssl_ssl" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_working_openssl_ssl" >&5 +printf "%s\n" "$ac_cv_working_openssl_ssl" >&6; } CFLAGS=$save_CFLAGS CPPFLAGS=$save_CPPFLAGS @@ -23258,11 +28242,12 @@ save_LIBS=$LIBS CFLAGS="$CFLAGS $OPENSSL_INCLUDES" LDFLAGS="$LDFLAGS $OPENSSL_LDFLAGS $OPENSSL_LDFLAGS_RPATH" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether OpenSSL provides required hashlib module APIs" >&5 -$as_echo_n "checking whether OpenSSL provides required hashlib module APIs... " >&6; } -if ${ac_cv_working_openssl_hashlib+:} false; then : - $as_echo_n "(cached) " >&6 -else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether OpenSSL provides required hashlib module APIs" >&5 +printf %s "checking whether OpenSSL provides required hashlib module APIs... " >&6; } +if test ${ac_cv_working_openssl_hashlib+y} +then : + printf %s "(cached) " >&6 +else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -23274,7 +28259,7 @@ else #endif int -main () +main (void) { OBJ_nid2sn(NID_md5); @@ -23287,17 +28272,18 @@ main () return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +if ac_fn_c_try_link "$LINENO" +then : ac_cv_working_openssl_hashlib=yes -else +else $as_nop ac_cv_working_openssl_hashlib=no fi -rm -f core conftest.err conftest.$ac_objext \ +rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_working_openssl_hashlib" >&5 -$as_echo "$ac_cv_working_openssl_hashlib" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_working_openssl_hashlib" >&5 +printf "%s\n" "$ac_cv_working_openssl_hashlib" >&6; } CFLAGS=$save_CFLAGS CPPFLAGS=$save_CPPFLAGS @@ -23310,53 +28296,53 @@ LIBS=$save_LIBS -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-ssl-default-suites" >&5 -$as_echo_n "checking for --with-ssl-default-suites... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-ssl-default-suites" >&5 +printf %s "checking for --with-ssl-default-suites... " >&6; } # Check whether --with-ssl-default-suites was given. -if test "${with_ssl_default_suites+set}" = set; then : +if test ${with_ssl_default_suites+y} +then : withval=$with_ssl_default_suites; -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $withval" >&5 -$as_echo "$withval" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $withval" >&5 +printf "%s\n" "$withval" >&6; } case "$withval" in python) - $as_echo "#define PY_SSL_DEFAULT_CIPHERS 1" >>confdefs.h + printf "%s\n" "#define PY_SSL_DEFAULT_CIPHERS 1" >>confdefs.h ;; openssl) - $as_echo "#define PY_SSL_DEFAULT_CIPHERS 2" >>confdefs.h + printf "%s\n" "#define PY_SSL_DEFAULT_CIPHERS 2" >>confdefs.h ;; *) - $as_echo "#define PY_SSL_DEFAULT_CIPHERS 0" >>confdefs.h + printf "%s\n" "#define PY_SSL_DEFAULT_CIPHERS 0" >>confdefs.h - cat >>confdefs.h <<_ACEOF -#define PY_SSL_DEFAULT_CIPHER_STRING "$withval" -_ACEOF + printf "%s\n" "#define PY_SSL_DEFAULT_CIPHER_STRING \"$withval\"" >>confdefs.h ;; esac -else +else $as_nop -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: python" >&5 -$as_echo "python" >&6; } -$as_echo "#define PY_SSL_DEFAULT_CIPHERS 1" >>confdefs.h +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: python" >&5 +printf "%s\n" "python" >&6; } +printf "%s\n" "#define PY_SSL_DEFAULT_CIPHERS 1" >>confdefs.h fi # builtin hash modules -default_hashlib_hashes="md5,sha1,sha256,sha512,sha3,blake2" +default_hashlib_hashes="md5,sha1,sha2,sha3,blake2" -$as_echo "#define PY_BUILTIN_HASHLIB_HASHES /**/" >>confdefs.h +printf "%s\n" "#define PY_BUILTIN_HASHLIB_HASHES /**/" >>confdefs.h -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-builtin-hashlib-hashes" >&5 -$as_echo_n "checking for --with-builtin-hashlib-hashes... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --with-builtin-hashlib-hashes" >&5 +printf %s "checking for --with-builtin-hashlib-hashes... " >&6; } # Check whether --with-builtin-hashlib-hashes was given. -if test "${with_builtin_hashlib_hashes+set}" = set; then : +if test ${with_builtin_hashlib_hashes+y} +then : withval=$with_builtin_hashlib_hashes; case $with_builtin_hashlib_hashes in #( yes) : @@ -23368,16 +28354,14 @@ if test "${with_builtin_hashlib_hashes+set}" = set; then : ;; esac -else +else $as_nop with_builtin_hashlib_hashes=$default_hashlib_hashes fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_builtin_hashlib_hashes" >&5 -$as_echo "$with_builtin_hashlib_hashes" >&6; } -cat >>confdefs.h <<_ACEOF -#define PY_BUILTIN_HASHLIB_HASHES "$with_builtin_hashlib_hashes" -_ACEOF +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_builtin_hashlib_hashes" >&5 +printf "%s\n" "$with_builtin_hashlib_hashes" >&6; } +printf "%s\n" "#define PY_BUILTIN_HASHLIB_HASHES \"$with_builtin_hashlib_hashes\"" >>confdefs.h as_save_IFS=$IFS @@ -23388,10 +28372,8 @@ for builtin_hash in $with_builtin_hashlib_hashes; do with_builtin_md5=yes ;; #( sha1) : with_builtin_sha1=yes ;; #( - sha256) : - with_builtin_sha256=yes ;; #( - sha512) : - with_builtin_sha512=yes ;; #( + sha2) : + with_builtin_sha2=yes ;; #( sha3) : with_builtin_sha3=yes ;; #( blake2) : @@ -23403,21 +28385,22 @@ esac done IFS=$as_save_IFS -if test "x$with_builtin_blake2" = xyes; then : +if test "x$with_builtin_blake2" = xyes +then : pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBB2" >&5 -$as_echo_n "checking for LIBB2... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for LIBB2" >&5 +printf %s "checking for LIBB2... " >&6; } if test -n "$LIBB2_CFLAGS"; then pkg_cv_LIBB2_CFLAGS="$LIBB2_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libb2\""; } >&5 + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libb2\""; } >&5 ($PKG_CONFIG --exists --print-errors "libb2") 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_LIBB2_CFLAGS=`$PKG_CONFIG --cflags "libb2" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes @@ -23431,10 +28414,10 @@ if test -n "$LIBB2_LIBS"; then pkg_cv_LIBB2_LIBS="$LIBB2_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libb2\""; } >&5 + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libb2\""; } >&5 ($PKG_CONFIG --exists --print-errors "libb2") 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_LIBB2_LIBS=`$PKG_CONFIG --libs "libb2" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes @@ -23448,8 +28431,8 @@ fi if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes @@ -23466,18 +28449,18 @@ fi have_libb2=no elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } have_libb2=no else LIBB2_CFLAGS=$pkg_cv_LIBB2_CFLAGS LIBB2_LIBS=$pkg_cv_LIBB2_LIBS - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } have_libb2=yes -$as_echo "#define HAVE_LIBB2 1" >>confdefs.h +printf "%s\n" "#define HAVE_LIBB2 1" >>confdefs.h fi @@ -23486,18 +28469,20 @@ fi # Check whether to disable test modules. Once set, setup.py will not build # test extension modules and "make install" will not install test suites. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --disable-test-modules" >&5 -$as_echo_n "checking for --disable-test-modules... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for --disable-test-modules" >&5 +printf %s "checking for --disable-test-modules... " >&6; } # Check whether --enable-test-modules was given. -if test "${enable_test_modules+set}" = set; then : +if test ${enable_test_modules+y} +then : enableval=$enable_test_modules; - if test "x$enable_test_modules" = xyes; then : + if test "x$enable_test_modules" = xyes +then : TEST_MODULES=yes -else +else $as_nop TEST_MODULES=no fi -else +else $as_nop case $ac_sys_system/$ac_sys_emscripten_target in #( Emscripten/browser*) : @@ -23509,8 +28494,8 @@ esac fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $TEST_MODULES" >&5 -$as_echo "$TEST_MODULES" >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $TEST_MODULES" >&5 +printf "%s\n" "$TEST_MODULES" >&6; } @@ -23569,6 +28554,7 @@ case $ac_sys_system in #( py_cv_module__scproxy=n/a py_cv_module__tkinter=n/a py_cv_module__xxsubinterpreters=n/a + py_cv_module__xxinterpchannels=n/a py_cv_module_grp=n/a py_cv_module_nis=n/a py_cv_module_ossaudiodev=n/a @@ -23620,25 +28606,9 @@ case $host_cpu in #( wasm32|wasm64) : MODULE_BUILDTYPE=static ;; #( *) : - MODULE_BUILDTYPE=${MODULE_BUILDTYPE:-shared} - ;; -esac - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for additional Modules/Setup files" >&5 -$as_echo_n "checking for additional Modules/Setup files... " >&6; } -case $ac_sys_system in #( - Emscripten) : - MODULES_SETUP_STDLIB=Modules/Setup.stdlib ;; #( - WASI) : - MODULES_SETUP_STDLIB=Modules/Setup.stdlib ;; #( - *) : - MODULES_SETUP_STDLIB= + MODULE_BUILDTYPE=${MODULE_BUILDTYPE:-shared} ;; esac -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MODULES_SETUP_STDLIB" >&5 -$as_echo "$MODULES_SETUP_STDLIB" >&6; } - @@ -23649,7 +28619,8 @@ MODULE_BLOCK= - if test "$py_cv_module__io" != "n/a"; then : + if test "$py_cv_module__io" != "n/a" +then : py_cv_module__io=yes fi if test "$py_cv_module__io" = yes; then @@ -23661,7 +28632,8 @@ else fi as_fn_append MODULE_BLOCK "MODULE__IO_STATE=$py_cv_module__io$as_nl" - if test "x$py_cv_module__io" = xyes; then : + if test "x$py_cv_module__io" = xyes +then : as_fn_append MODULE_BLOCK "MODULE__IO_CFLAGS=-I\$(srcdir)/Modules/_io$as_nl" @@ -23669,7 +28641,8 @@ fi fi - if test "$py_cv_module_time" != "n/a"; then : + if test "$py_cv_module_time" != "n/a" +then : py_cv_module_time=yes fi if test "$py_cv_module_time" = yes; then @@ -23681,7 +28654,8 @@ else fi as_fn_append MODULE_BLOCK "MODULE_TIME_STATE=$py_cv_module_time$as_nl" - if test "x$py_cv_module_time" = xyes; then : + if test "x$py_cv_module_time" = xyes +then : as_fn_append MODULE_BLOCK "MODULE_TIME_LDFLAGS=$TIMEMODULE_LIB$as_nl" @@ -23690,7 +28664,8 @@ fi - if test "$py_cv_module_array" != "n/a"; then : + if test "$py_cv_module_array" != "n/a" +then : py_cv_module_array=yes fi if test "$py_cv_module_array" = yes; then @@ -23702,7 +28677,8 @@ else fi as_fn_append MODULE_BLOCK "MODULE_ARRAY_STATE=$py_cv_module_array$as_nl" - if test "x$py_cv_module_array" = xyes; then : + if test "x$py_cv_module_array" = xyes +then : @@ -23710,7 +28686,8 @@ fi fi - if test "$py_cv_module__asyncio" != "n/a"; then : + if test "$py_cv_module__asyncio" != "n/a" +then : py_cv_module__asyncio=yes fi if test "$py_cv_module__asyncio" = yes; then @@ -23722,7 +28699,8 @@ else fi as_fn_append MODULE_BLOCK "MODULE__ASYNCIO_STATE=$py_cv_module__asyncio$as_nl" - if test "x$py_cv_module__asyncio" = xyes; then : + if test "x$py_cv_module__asyncio" = xyes +then : @@ -23730,7 +28708,8 @@ fi fi - if test "$py_cv_module__bisect" != "n/a"; then : + if test "$py_cv_module__bisect" != "n/a" +then : py_cv_module__bisect=yes fi if test "$py_cv_module__bisect" = yes; then @@ -23742,7 +28721,8 @@ else fi as_fn_append MODULE_BLOCK "MODULE__BISECT_STATE=$py_cv_module__bisect$as_nl" - if test "x$py_cv_module__bisect" = xyes; then : + if test "x$py_cv_module__bisect" = xyes +then : @@ -23750,7 +28730,8 @@ fi fi - if test "$py_cv_module__contextvars" != "n/a"; then : + if test "$py_cv_module__contextvars" != "n/a" +then : py_cv_module__contextvars=yes fi if test "$py_cv_module__contextvars" = yes; then @@ -23762,7 +28743,8 @@ else fi as_fn_append MODULE_BLOCK "MODULE__CONTEXTVARS_STATE=$py_cv_module__contextvars$as_nl" - if test "x$py_cv_module__contextvars" = xyes; then : + if test "x$py_cv_module__contextvars" = xyes +then : @@ -23770,7 +28752,8 @@ fi fi - if test "$py_cv_module__csv" != "n/a"; then : + if test "$py_cv_module__csv" != "n/a" +then : py_cv_module__csv=yes fi if test "$py_cv_module__csv" = yes; then @@ -23782,7 +28765,8 @@ else fi as_fn_append MODULE_BLOCK "MODULE__CSV_STATE=$py_cv_module__csv$as_nl" - if test "x$py_cv_module__csv" = xyes; then : + if test "x$py_cv_module__csv" = xyes +then : @@ -23790,7 +28774,8 @@ fi fi - if test "$py_cv_module__heapq" != "n/a"; then : + if test "$py_cv_module__heapq" != "n/a" +then : py_cv_module__heapq=yes fi if test "$py_cv_module__heapq" = yes; then @@ -23802,7 +28787,8 @@ else fi as_fn_append MODULE_BLOCK "MODULE__HEAPQ_STATE=$py_cv_module__heapq$as_nl" - if test "x$py_cv_module__heapq" = xyes; then : + if test "x$py_cv_module__heapq" = xyes +then : @@ -23810,7 +28796,8 @@ fi fi - if test "$py_cv_module__json" != "n/a"; then : + if test "$py_cv_module__json" != "n/a" +then : py_cv_module__json=yes fi if test "$py_cv_module__json" = yes; then @@ -23822,7 +28809,8 @@ else fi as_fn_append MODULE_BLOCK "MODULE__JSON_STATE=$py_cv_module__json$as_nl" - if test "x$py_cv_module__json" = xyes; then : + if test "x$py_cv_module__json" = xyes +then : @@ -23830,7 +28818,8 @@ fi fi - if test "$py_cv_module__lsprof" != "n/a"; then : + if test "$py_cv_module__lsprof" != "n/a" +then : py_cv_module__lsprof=yes fi if test "$py_cv_module__lsprof" = yes; then @@ -23842,7 +28831,8 @@ else fi as_fn_append MODULE_BLOCK "MODULE__LSPROF_STATE=$py_cv_module__lsprof$as_nl" - if test "x$py_cv_module__lsprof" = xyes; then : + if test "x$py_cv_module__lsprof" = xyes +then : @@ -23850,7 +28840,8 @@ fi fi - if test "$py_cv_module__opcode" != "n/a"; then : + if test "$py_cv_module__opcode" != "n/a" +then : py_cv_module__opcode=yes fi if test "$py_cv_module__opcode" = yes; then @@ -23862,7 +28853,8 @@ else fi as_fn_append MODULE_BLOCK "MODULE__OPCODE_STATE=$py_cv_module__opcode$as_nl" - if test "x$py_cv_module__opcode" = xyes; then : + if test "x$py_cv_module__opcode" = xyes +then : @@ -23870,7 +28862,8 @@ fi fi - if test "$py_cv_module__pickle" != "n/a"; then : + if test "$py_cv_module__pickle" != "n/a" +then : py_cv_module__pickle=yes fi if test "$py_cv_module__pickle" = yes; then @@ -23882,7 +28875,8 @@ else fi as_fn_append MODULE_BLOCK "MODULE__PICKLE_STATE=$py_cv_module__pickle$as_nl" - if test "x$py_cv_module__pickle" = xyes; then : + if test "x$py_cv_module__pickle" = xyes +then : @@ -23890,7 +28884,8 @@ fi fi - if test "$py_cv_module__posixsubprocess" != "n/a"; then : + if test "$py_cv_module__posixsubprocess" != "n/a" +then : py_cv_module__posixsubprocess=yes fi if test "$py_cv_module__posixsubprocess" = yes; then @@ -23902,7 +28897,8 @@ else fi as_fn_append MODULE_BLOCK "MODULE__POSIXSUBPROCESS_STATE=$py_cv_module__posixsubprocess$as_nl" - if test "x$py_cv_module__posixsubprocess" = xyes; then : + if test "x$py_cv_module__posixsubprocess" = xyes +then : @@ -23910,7 +28906,8 @@ fi fi - if test "$py_cv_module__queue" != "n/a"; then : + if test "$py_cv_module__queue" != "n/a" +then : py_cv_module__queue=yes fi if test "$py_cv_module__queue" = yes; then @@ -23922,7 +28919,8 @@ else fi as_fn_append MODULE_BLOCK "MODULE__QUEUE_STATE=$py_cv_module__queue$as_nl" - if test "x$py_cv_module__queue" = xyes; then : + if test "x$py_cv_module__queue" = xyes +then : @@ -23930,7 +28928,8 @@ fi fi - if test "$py_cv_module__random" != "n/a"; then : + if test "$py_cv_module__random" != "n/a" +then : py_cv_module__random=yes fi if test "$py_cv_module__random" = yes; then @@ -23942,7 +28941,8 @@ else fi as_fn_append MODULE_BLOCK "MODULE__RANDOM_STATE=$py_cv_module__random$as_nl" - if test "x$py_cv_module__random" = xyes; then : + if test "x$py_cv_module__random" = xyes +then : @@ -23950,7 +28950,8 @@ fi fi - if test "$py_cv_module_select" != "n/a"; then : + if test "$py_cv_module_select" != "n/a" +then : py_cv_module_select=yes fi if test "$py_cv_module_select" = yes; then @@ -23962,7 +28963,8 @@ else fi as_fn_append MODULE_BLOCK "MODULE_SELECT_STATE=$py_cv_module_select$as_nl" - if test "x$py_cv_module_select" = xyes; then : + if test "x$py_cv_module_select" = xyes +then : @@ -23970,7 +28972,8 @@ fi fi - if test "$py_cv_module__struct" != "n/a"; then : + if test "$py_cv_module__struct" != "n/a" +then : py_cv_module__struct=yes fi if test "$py_cv_module__struct" = yes; then @@ -23982,7 +28985,8 @@ else fi as_fn_append MODULE_BLOCK "MODULE__STRUCT_STATE=$py_cv_module__struct$as_nl" - if test "x$py_cv_module__struct" = xyes; then : + if test "x$py_cv_module__struct" = xyes +then : @@ -23990,7 +28994,8 @@ fi fi - if test "$py_cv_module__typing" != "n/a"; then : + if test "$py_cv_module__typing" != "n/a" +then : py_cv_module__typing=yes fi if test "$py_cv_module__typing" = yes; then @@ -24002,7 +29007,8 @@ else fi as_fn_append MODULE_BLOCK "MODULE__TYPING_STATE=$py_cv_module__typing$as_nl" - if test "x$py_cv_module__typing" = xyes; then : + if test "x$py_cv_module__typing" = xyes +then : @@ -24010,7 +29016,8 @@ fi fi - if test "$py_cv_module__xxsubinterpreters" != "n/a"; then : + if test "$py_cv_module__xxsubinterpreters" != "n/a" +then : py_cv_module__xxsubinterpreters=yes fi if test "$py_cv_module__xxsubinterpreters" = yes; then @@ -24022,7 +29029,30 @@ else fi as_fn_append MODULE_BLOCK "MODULE__XXSUBINTERPRETERS_STATE=$py_cv_module__xxsubinterpreters$as_nl" - if test "x$py_cv_module__xxsubinterpreters" = xyes; then : + if test "x$py_cv_module__xxsubinterpreters" = xyes +then : + + + + +fi + + + if test "$py_cv_module__xxinterpchannels" != "n/a" +then : + py_cv_module__xxinterpchannels=yes +fi + if test "$py_cv_module__xxinterpchannels" = yes; then + MODULE__XXINTERPCHANNELS_TRUE= + MODULE__XXINTERPCHANNELS_FALSE='#' +else + MODULE__XXINTERPCHANNELS_TRUE='#' + MODULE__XXINTERPCHANNELS_FALSE= +fi + + as_fn_append MODULE_BLOCK "MODULE__XXINTERPCHANNELS_STATE=$py_cv_module__xxinterpchannels$as_nl" + if test "x$py_cv_module__xxinterpchannels" = xyes +then : @@ -24030,7 +29060,8 @@ fi fi - if test "$py_cv_module__zoneinfo" != "n/a"; then : + if test "$py_cv_module__zoneinfo" != "n/a" +then : py_cv_module__zoneinfo=yes fi if test "$py_cv_module__zoneinfo" = yes; then @@ -24042,7 +29073,8 @@ else fi as_fn_append MODULE_BLOCK "MODULE__ZONEINFO_STATE=$py_cv_module__zoneinfo$as_nl" - if test "x$py_cv_module__zoneinfo" = xyes; then : + if test "x$py_cv_module__zoneinfo" = xyes +then : @@ -24051,23 +29083,27 @@ fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _multiprocessing" >&5 -$as_echo_n "checking for stdlib extension module _multiprocessing... " >&6; } - if test "$py_cv_module__multiprocessing" != "n/a"; then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _multiprocessing" >&5 +printf %s "checking for stdlib extension module _multiprocessing... " >&6; } + if test "$py_cv_module__multiprocessing" != "n/a" +then : - if true; then : - if test "$ac_cv_func_sem_unlink" = "yes"; then : + if true +then : + if test "$ac_cv_func_sem_unlink" = "yes" +then : py_cv_module__multiprocessing=yes -else +else $as_nop py_cv_module__multiprocessing=missing fi -else +else $as_nop py_cv_module__multiprocessing=disabled fi fi as_fn_append MODULE_BLOCK "MODULE__MULTIPROCESSING_STATE=$py_cv_module__multiprocessing$as_nl" - if test "x$py_cv_module__multiprocessing" = xyes; then : + if test "x$py_cv_module__multiprocessing" = xyes +then : as_fn_append MODULE_BLOCK "MODULE__MULTIPROCESSING_CFLAGS=-I\$(srcdir)/Modules/_multiprocessing$as_nl" @@ -24081,27 +29117,31 @@ else MODULE__MULTIPROCESSING_FALSE= fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__multiprocessing" >&5 -$as_echo "$py_cv_module__multiprocessing" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__multiprocessing" >&5 +printf "%s\n" "$py_cv_module__multiprocessing" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _posixshmem" >&5 -$as_echo_n "checking for stdlib extension module _posixshmem... " >&6; } - if test "$py_cv_module__posixshmem" != "n/a"; then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _posixshmem" >&5 +printf %s "checking for stdlib extension module _posixshmem... " >&6; } + if test "$py_cv_module__posixshmem" != "n/a" +then : - if true; then : - if test "$have_posix_shmem" = "yes"; then : + if true +then : + if test "$have_posix_shmem" = "yes" +then : py_cv_module__posixshmem=yes -else +else $as_nop py_cv_module__posixshmem=missing fi -else +else $as_nop py_cv_module__posixshmem=disabled fi fi as_fn_append MODULE_BLOCK "MODULE__POSIXSHMEM_STATE=$py_cv_module__posixshmem$as_nl" - if test "x$py_cv_module__posixshmem" = xyes; then : + if test "x$py_cv_module__posixshmem" = xyes +then : as_fn_append MODULE_BLOCK "MODULE__POSIXSHMEM_CFLAGS=$POSIXSHMEM_CFLAGS$as_nl" as_fn_append MODULE_BLOCK "MODULE__POSIXSHMEM_LDFLAGS=$POSIXSHMEM_LIBS$as_nl" @@ -24115,12 +29155,13 @@ else MODULE__POSIXSHMEM_FALSE= fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__posixshmem" >&5 -$as_echo "$py_cv_module__posixshmem" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__posixshmem" >&5 +printf "%s\n" "$py_cv_module__posixshmem" >&6; } - if test "$py_cv_module_audioop" != "n/a"; then : + if test "$py_cv_module_audioop" != "n/a" +then : py_cv_module_audioop=yes fi if test "$py_cv_module_audioop" = yes; then @@ -24132,7 +29173,8 @@ else fi as_fn_append MODULE_BLOCK "MODULE_AUDIOOP_STATE=$py_cv_module_audioop$as_nl" - if test "x$py_cv_module_audioop" = xyes; then : + if test "x$py_cv_module_audioop" = xyes +then : as_fn_append MODULE_BLOCK "MODULE_AUDIOOP_LDFLAGS=$LIBM$as_nl" @@ -24140,7 +29182,8 @@ fi fi - if test "$py_cv_module__statistics" != "n/a"; then : + if test "$py_cv_module__statistics" != "n/a" +then : py_cv_module__statistics=yes fi if test "$py_cv_module__statistics" = yes; then @@ -24152,7 +29195,8 @@ else fi as_fn_append MODULE_BLOCK "MODULE__STATISTICS_STATE=$py_cv_module__statistics$as_nl" - if test "x$py_cv_module__statistics" = xyes; then : + if test "x$py_cv_module__statistics" = xyes +then : as_fn_append MODULE_BLOCK "MODULE__STATISTICS_LDFLAGS=$LIBM$as_nl" @@ -24160,7 +29204,8 @@ fi fi - if test "$py_cv_module_cmath" != "n/a"; then : + if test "$py_cv_module_cmath" != "n/a" +then : py_cv_module_cmath=yes fi if test "$py_cv_module_cmath" = yes; then @@ -24172,7 +29217,8 @@ else fi as_fn_append MODULE_BLOCK "MODULE_CMATH_STATE=$py_cv_module_cmath$as_nl" - if test "x$py_cv_module_cmath" = xyes; then : + if test "x$py_cv_module_cmath" = xyes +then : as_fn_append MODULE_BLOCK "MODULE_CMATH_LDFLAGS=$LIBM$as_nl" @@ -24180,7 +29226,8 @@ fi fi - if test "$py_cv_module_math" != "n/a"; then : + if test "$py_cv_module_math" != "n/a" +then : py_cv_module_math=yes fi if test "$py_cv_module_math" = yes; then @@ -24192,7 +29239,8 @@ else fi as_fn_append MODULE_BLOCK "MODULE_MATH_STATE=$py_cv_module_math$as_nl" - if test "x$py_cv_module_math" = xyes; then : + if test "x$py_cv_module_math" = xyes +then : as_fn_append MODULE_BLOCK "MODULE_MATH_LDFLAGS=$LIBM$as_nl" @@ -24201,7 +29249,8 @@ fi - if test "$py_cv_module__datetime" != "n/a"; then : + if test "$py_cv_module__datetime" != "n/a" +then : py_cv_module__datetime=yes fi if test "$py_cv_module__datetime" = yes; then @@ -24213,7 +29262,8 @@ else fi as_fn_append MODULE_BLOCK "MODULE__DATETIME_STATE=$py_cv_module__datetime$as_nl" - if test "x$py_cv_module__datetime" = xyes; then : + if test "x$py_cv_module__datetime" = xyes +then : as_fn_append MODULE_BLOCK "MODULE__DATETIME_LDFLAGS=$TIMEMODULE_LIB $LIBM$as_nl" @@ -24222,23 +29272,27 @@ fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module fcntl" >&5 -$as_echo_n "checking for stdlib extension module fcntl... " >&6; } - if test "$py_cv_module_fcntl" != "n/a"; then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module fcntl" >&5 +printf %s "checking for stdlib extension module fcntl... " >&6; } + if test "$py_cv_module_fcntl" != "n/a" +then : - if true; then : - if test "$ac_cv_header_sys_ioctl_h" = "yes" -a "$ac_cv_header_fcntl_h" = "yes"; then : + if true +then : + if test "$ac_cv_header_sys_ioctl_h" = "yes" -a "$ac_cv_header_fcntl_h" = "yes" +then : py_cv_module_fcntl=yes -else +else $as_nop py_cv_module_fcntl=missing fi -else +else $as_nop py_cv_module_fcntl=disabled fi fi as_fn_append MODULE_BLOCK "MODULE_FCNTL_STATE=$py_cv_module_fcntl$as_nl" - if test "x$py_cv_module_fcntl" = xyes; then : + if test "x$py_cv_module_fcntl" = xyes +then : as_fn_append MODULE_BLOCK "MODULE_FCNTL_LDFLAGS=$FCNTL_LIBS$as_nl" @@ -24252,27 +29306,31 @@ else MODULE_FCNTL_FALSE= fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module_fcntl" >&5 -$as_echo "$py_cv_module_fcntl" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module_fcntl" >&5 +printf "%s\n" "$py_cv_module_fcntl" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module mmap" >&5 -$as_echo_n "checking for stdlib extension module mmap... " >&6; } - if test "$py_cv_module_mmap" != "n/a"; then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module mmap" >&5 +printf %s "checking for stdlib extension module mmap... " >&6; } + if test "$py_cv_module_mmap" != "n/a" +then : - if true; then : - if test "$ac_cv_header_sys_mman_h" = "yes" -a "$ac_cv_header_sys_stat_h" = "yes"; then : + if true +then : + if test "$ac_cv_header_sys_mman_h" = "yes" -a "$ac_cv_header_sys_stat_h" = "yes" +then : py_cv_module_mmap=yes -else +else $as_nop py_cv_module_mmap=missing fi -else +else $as_nop py_cv_module_mmap=disabled fi fi as_fn_append MODULE_BLOCK "MODULE_MMAP_STATE=$py_cv_module_mmap$as_nl" - if test "x$py_cv_module_mmap" = xyes; then : + if test "x$py_cv_module_mmap" = xyes +then : @@ -24286,27 +29344,31 @@ else MODULE_MMAP_FALSE= fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module_mmap" >&5 -$as_echo "$py_cv_module_mmap" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module_mmap" >&5 +printf "%s\n" "$py_cv_module_mmap" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _socket" >&5 -$as_echo_n "checking for stdlib extension module _socket... " >&6; } - if test "$py_cv_module__socket" != "n/a"; then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _socket" >&5 +printf %s "checking for stdlib extension module _socket... " >&6; } + if test "$py_cv_module__socket" != "n/a" +then : - if true; then : - if test "$ac_cv_header_sys_socket_h" = "yes" -a "$ac_cv_header_sys_types_h" = "yes" -a "$ac_cv_header_netinet_in_h" = "yes"; then : + if true +then : + if test "$ac_cv_header_sys_socket_h" = "yes" -a "$ac_cv_header_sys_types_h" = "yes" -a "$ac_cv_header_netinet_in_h" = "yes" +then : py_cv_module__socket=yes -else +else $as_nop py_cv_module__socket=missing fi -else +else $as_nop py_cv_module__socket=disabled fi fi as_fn_append MODULE_BLOCK "MODULE__SOCKET_STATE=$py_cv_module__socket$as_nl" - if test "x$py_cv_module__socket" = xyes; then : + if test "x$py_cv_module__socket" = xyes +then : @@ -24320,28 +29382,32 @@ else MODULE__SOCKET_FALSE= fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__socket" >&5 -$as_echo "$py_cv_module__socket" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__socket" >&5 +printf "%s\n" "$py_cv_module__socket" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module grp" >&5 -$as_echo_n "checking for stdlib extension module grp... " >&6; } - if test "$py_cv_module_grp" != "n/a"; then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module grp" >&5 +printf %s "checking for stdlib extension module grp... " >&6; } + if test "$py_cv_module_grp" != "n/a" +then : - if true; then : - if test "$ac_cv_func_getgrgid" = yes -o "$ac_cv_func_getgrgid_r" = yes; then : + if true +then : + if test "$ac_cv_func_getgrgid" = yes -o "$ac_cv_func_getgrgid_r" = yes +then : py_cv_module_grp=yes -else +else $as_nop py_cv_module_grp=missing fi -else +else $as_nop py_cv_module_grp=disabled fi fi as_fn_append MODULE_BLOCK "MODULE_GRP_STATE=$py_cv_module_grp$as_nl" - if test "x$py_cv_module_grp" = xyes; then : + if test "x$py_cv_module_grp" = xyes +then : @@ -24355,27 +29421,31 @@ else MODULE_GRP_FALSE= fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module_grp" >&5 -$as_echo "$py_cv_module_grp" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module_grp" >&5 +printf "%s\n" "$py_cv_module_grp" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module ossaudiodev" >&5 -$as_echo_n "checking for stdlib extension module ossaudiodev... " >&6; } - if test "$py_cv_module_ossaudiodev" != "n/a"; then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module ossaudiodev" >&5 +printf %s "checking for stdlib extension module ossaudiodev... " >&6; } + if test "$py_cv_module_ossaudiodev" != "n/a" +then : - if true; then : - if test "$ac_cv_header_linux_soundcard_h" = yes -o "$ac_cv_header_sys_soundcard_h" = yes; then : + if true +then : + if test "$ac_cv_header_linux_soundcard_h" = yes -o "$ac_cv_header_sys_soundcard_h" = yes +then : py_cv_module_ossaudiodev=yes -else +else $as_nop py_cv_module_ossaudiodev=missing fi -else +else $as_nop py_cv_module_ossaudiodev=disabled fi fi as_fn_append MODULE_BLOCK "MODULE_OSSAUDIODEV_STATE=$py_cv_module_ossaudiodev$as_nl" - if test "x$py_cv_module_ossaudiodev" = xyes; then : + if test "x$py_cv_module_ossaudiodev" = xyes +then : as_fn_append MODULE_BLOCK "MODULE_OSSAUDIODEV_LDFLAGS=$OSSAUDIODEV_LIBS$as_nl" @@ -24389,27 +29459,31 @@ else MODULE_OSSAUDIODEV_FALSE= fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module_ossaudiodev" >&5 -$as_echo "$py_cv_module_ossaudiodev" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module_ossaudiodev" >&5 +printf "%s\n" "$py_cv_module_ossaudiodev" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module pwd" >&5 -$as_echo_n "checking for stdlib extension module pwd... " >&6; } - if test "$py_cv_module_pwd" != "n/a"; then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module pwd" >&5 +printf %s "checking for stdlib extension module pwd... " >&6; } + if test "$py_cv_module_pwd" != "n/a" +then : - if true; then : - if test "$ac_cv_func_getpwuid" = yes -o "$ac_cv_func_getpwuid_r" = yes; then : + if true +then : + if test "$ac_cv_func_getpwuid" = yes -o "$ac_cv_func_getpwuid_r" = yes +then : py_cv_module_pwd=yes -else +else $as_nop py_cv_module_pwd=missing fi -else +else $as_nop py_cv_module_pwd=disabled fi fi as_fn_append MODULE_BLOCK "MODULE_PWD_STATE=$py_cv_module_pwd$as_nl" - if test "x$py_cv_module_pwd" = xyes; then : + if test "x$py_cv_module_pwd" = xyes +then : @@ -24423,27 +29497,31 @@ else MODULE_PWD_FALSE= fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module_pwd" >&5 -$as_echo "$py_cv_module_pwd" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module_pwd" >&5 +printf "%s\n" "$py_cv_module_pwd" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module resource" >&5 -$as_echo_n "checking for stdlib extension module resource... " >&6; } - if test "$py_cv_module_resource" != "n/a"; then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module resource" >&5 +printf %s "checking for stdlib extension module resource... " >&6; } + if test "$py_cv_module_resource" != "n/a" +then : - if true; then : - if test "$ac_cv_header_sys_resource_h" = yes; then : + if true +then : + if test "$ac_cv_header_sys_resource_h" = yes +then : py_cv_module_resource=yes -else +else $as_nop py_cv_module_resource=missing fi -else +else $as_nop py_cv_module_resource=disabled fi fi as_fn_append MODULE_BLOCK "MODULE_RESOURCE_STATE=$py_cv_module_resource$as_nl" - if test "x$py_cv_module_resource" = xyes; then : + if test "x$py_cv_module_resource" = xyes +then : @@ -24457,27 +29535,31 @@ else MODULE_RESOURCE_FALSE= fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module_resource" >&5 -$as_echo "$py_cv_module_resource" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module_resource" >&5 +printf "%s\n" "$py_cv_module_resource" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _scproxy" >&5 -$as_echo_n "checking for stdlib extension module _scproxy... " >&6; } - if test "$py_cv_module__scproxy" != "n/a"; then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _scproxy" >&5 +printf %s "checking for stdlib extension module _scproxy... " >&6; } + if test "$py_cv_module__scproxy" != "n/a" +then : - if test "$ac_sys_system" = "Darwin"; then : - if true; then : + if test "$ac_sys_system" = "Darwin" +then : + if true +then : py_cv_module__scproxy=yes -else +else $as_nop py_cv_module__scproxy=missing fi -else +else $as_nop py_cv_module__scproxy=disabled fi fi as_fn_append MODULE_BLOCK "MODULE__SCPROXY_STATE=$py_cv_module__scproxy$as_nl" - if test "x$py_cv_module__scproxy" = xyes; then : + if test "x$py_cv_module__scproxy" = xyes +then : as_fn_append MODULE_BLOCK "MODULE__SCPROXY_LDFLAGS=-framework SystemConfiguration -framework CoreFoundation$as_nl" @@ -24491,27 +29573,31 @@ else MODULE__SCPROXY_FALSE= fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__scproxy" >&5 -$as_echo "$py_cv_module__scproxy" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__scproxy" >&5 +printf "%s\n" "$py_cv_module__scproxy" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module spwd" >&5 -$as_echo_n "checking for stdlib extension module spwd... " >&6; } - if test "$py_cv_module_spwd" != "n/a"; then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module spwd" >&5 +printf %s "checking for stdlib extension module spwd... " >&6; } + if test "$py_cv_module_spwd" != "n/a" +then : - if true; then : - if test "$ac_cv_func_getspent" = yes -o "$ac_cv_func_getspnam" = yes; then : + if true +then : + if test "$ac_cv_func_getspent" = yes -o "$ac_cv_func_getspnam" = yes +then : py_cv_module_spwd=yes -else +else $as_nop py_cv_module_spwd=missing fi -else +else $as_nop py_cv_module_spwd=disabled fi fi as_fn_append MODULE_BLOCK "MODULE_SPWD_STATE=$py_cv_module_spwd$as_nl" - if test "x$py_cv_module_spwd" = xyes; then : + if test "x$py_cv_module_spwd" = xyes +then : @@ -24525,27 +29611,31 @@ else MODULE_SPWD_FALSE= fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module_spwd" >&5 -$as_echo "$py_cv_module_spwd" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module_spwd" >&5 +printf "%s\n" "$py_cv_module_spwd" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module syslog" >&5 -$as_echo_n "checking for stdlib extension module syslog... " >&6; } - if test "$py_cv_module_syslog" != "n/a"; then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module syslog" >&5 +printf %s "checking for stdlib extension module syslog... " >&6; } + if test "$py_cv_module_syslog" != "n/a" +then : - if true; then : - if test "$ac_cv_header_syslog_h" = yes; then : + if true +then : + if test "$ac_cv_header_syslog_h" = yes +then : py_cv_module_syslog=yes -else +else $as_nop py_cv_module_syslog=missing fi -else +else $as_nop py_cv_module_syslog=disabled fi fi as_fn_append MODULE_BLOCK "MODULE_SYSLOG_STATE=$py_cv_module_syslog$as_nl" - if test "x$py_cv_module_syslog" = xyes; then : + if test "x$py_cv_module_syslog" = xyes +then : @@ -24559,27 +29649,31 @@ else MODULE_SYSLOG_FALSE= fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module_syslog" >&5 -$as_echo "$py_cv_module_syslog" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module_syslog" >&5 +printf "%s\n" "$py_cv_module_syslog" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module termios" >&5 -$as_echo_n "checking for stdlib extension module termios... " >&6; } - if test "$py_cv_module_termios" != "n/a"; then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module termios" >&5 +printf %s "checking for stdlib extension module termios... " >&6; } + if test "$py_cv_module_termios" != "n/a" +then : - if true; then : - if test "$ac_cv_header_termios_h" = yes; then : + if true +then : + if test "$ac_cv_header_termios_h" = yes +then : py_cv_module_termios=yes -else +else $as_nop py_cv_module_termios=missing fi -else +else $as_nop py_cv_module_termios=disabled fi fi as_fn_append MODULE_BLOCK "MODULE_TERMIOS_STATE=$py_cv_module_termios$as_nl" - if test "x$py_cv_module_termios" = xyes; then : + if test "x$py_cv_module_termios" = xyes +then : @@ -24593,28 +29687,32 @@ else MODULE_TERMIOS_FALSE= fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module_termios" >&5 -$as_echo "$py_cv_module_termios" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module_termios" >&5 +printf "%s\n" "$py_cv_module_termios" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module pyexpat" >&5 -$as_echo_n "checking for stdlib extension module pyexpat... " >&6; } - if test "$py_cv_module_pyexpat" != "n/a"; then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module pyexpat" >&5 +printf %s "checking for stdlib extension module pyexpat... " >&6; } + if test "$py_cv_module_pyexpat" != "n/a" +then : - if true; then : - if true; then : + if true +then : + if test "$ac_cv_header_sys_time_h" = "yes" +then : py_cv_module_pyexpat=yes -else +else $as_nop py_cv_module_pyexpat=missing fi -else +else $as_nop py_cv_module_pyexpat=disabled fi fi as_fn_append MODULE_BLOCK "MODULE_PYEXPAT_STATE=$py_cv_module_pyexpat$as_nl" - if test "x$py_cv_module_pyexpat" = xyes; then : + if test "x$py_cv_module_pyexpat" = xyes +then : as_fn_append MODULE_BLOCK "MODULE_PYEXPAT_CFLAGS=$LIBEXPAT_CFLAGS$as_nl" as_fn_append MODULE_BLOCK "MODULE_PYEXPAT_LDFLAGS=$LIBEXPAT_LDFLAGS$as_nl" @@ -24628,27 +29726,31 @@ else MODULE_PYEXPAT_FALSE= fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module_pyexpat" >&5 -$as_echo "$py_cv_module_pyexpat" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module_pyexpat" >&5 +printf "%s\n" "$py_cv_module_pyexpat" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _elementtree" >&5 -$as_echo_n "checking for stdlib extension module _elementtree... " >&6; } - if test "$py_cv_module__elementtree" != "n/a"; then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _elementtree" >&5 +printf %s "checking for stdlib extension module _elementtree... " >&6; } + if test "$py_cv_module__elementtree" != "n/a" +then : - if true; then : - if true; then : + if true +then : + if true +then : py_cv_module__elementtree=yes -else +else $as_nop py_cv_module__elementtree=missing fi -else +else $as_nop py_cv_module__elementtree=disabled fi fi as_fn_append MODULE_BLOCK "MODULE__ELEMENTTREE_STATE=$py_cv_module__elementtree$as_nl" - if test "x$py_cv_module__elementtree" = xyes; then : + if test "x$py_cv_module__elementtree" = xyes +then : as_fn_append MODULE_BLOCK "MODULE__ELEMENTTREE_CFLAGS=$LIBEXPAT_CFLAGS$as_nl" @@ -24662,11 +29764,12 @@ else MODULE__ELEMENTTREE_FALSE= fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__elementtree" >&5 -$as_echo "$py_cv_module__elementtree" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__elementtree" >&5 +printf "%s\n" "$py_cv_module__elementtree" >&6; } - if test "$py_cv_module__codecs_cn" != "n/a"; then : + if test "$py_cv_module__codecs_cn" != "n/a" +then : py_cv_module__codecs_cn=yes fi if test "$py_cv_module__codecs_cn" = yes; then @@ -24678,7 +29781,8 @@ else fi as_fn_append MODULE_BLOCK "MODULE__CODECS_CN_STATE=$py_cv_module__codecs_cn$as_nl" - if test "x$py_cv_module__codecs_cn" = xyes; then : + if test "x$py_cv_module__codecs_cn" = xyes +then : @@ -24686,7 +29790,8 @@ fi fi - if test "$py_cv_module__codecs_hk" != "n/a"; then : + if test "$py_cv_module__codecs_hk" != "n/a" +then : py_cv_module__codecs_hk=yes fi if test "$py_cv_module__codecs_hk" = yes; then @@ -24698,7 +29803,8 @@ else fi as_fn_append MODULE_BLOCK "MODULE__CODECS_HK_STATE=$py_cv_module__codecs_hk$as_nl" - if test "x$py_cv_module__codecs_hk" = xyes; then : + if test "x$py_cv_module__codecs_hk" = xyes +then : @@ -24706,7 +29812,8 @@ fi fi - if test "$py_cv_module__codecs_iso2022" != "n/a"; then : + if test "$py_cv_module__codecs_iso2022" != "n/a" +then : py_cv_module__codecs_iso2022=yes fi if test "$py_cv_module__codecs_iso2022" = yes; then @@ -24718,7 +29825,8 @@ else fi as_fn_append MODULE_BLOCK "MODULE__CODECS_ISO2022_STATE=$py_cv_module__codecs_iso2022$as_nl" - if test "x$py_cv_module__codecs_iso2022" = xyes; then : + if test "x$py_cv_module__codecs_iso2022" = xyes +then : @@ -24726,7 +29834,8 @@ fi fi - if test "$py_cv_module__codecs_jp" != "n/a"; then : + if test "$py_cv_module__codecs_jp" != "n/a" +then : py_cv_module__codecs_jp=yes fi if test "$py_cv_module__codecs_jp" = yes; then @@ -24738,7 +29847,8 @@ else fi as_fn_append MODULE_BLOCK "MODULE__CODECS_JP_STATE=$py_cv_module__codecs_jp$as_nl" - if test "x$py_cv_module__codecs_jp" = xyes; then : + if test "x$py_cv_module__codecs_jp" = xyes +then : @@ -24746,7 +29856,8 @@ fi fi - if test "$py_cv_module__codecs_kr" != "n/a"; then : + if test "$py_cv_module__codecs_kr" != "n/a" +then : py_cv_module__codecs_kr=yes fi if test "$py_cv_module__codecs_kr" = yes; then @@ -24758,7 +29869,8 @@ else fi as_fn_append MODULE_BLOCK "MODULE__CODECS_KR_STATE=$py_cv_module__codecs_kr$as_nl" - if test "x$py_cv_module__codecs_kr" = xyes; then : + if test "x$py_cv_module__codecs_kr" = xyes +then : @@ -24766,7 +29878,8 @@ fi fi - if test "$py_cv_module__codecs_tw" != "n/a"; then : + if test "$py_cv_module__codecs_tw" != "n/a" +then : py_cv_module__codecs_tw=yes fi if test "$py_cv_module__codecs_tw" = yes; then @@ -24778,7 +29891,8 @@ else fi as_fn_append MODULE_BLOCK "MODULE__CODECS_TW_STATE=$py_cv_module__codecs_tw$as_nl" - if test "x$py_cv_module__codecs_tw" = xyes; then : + if test "x$py_cv_module__codecs_tw" = xyes +then : @@ -24786,7 +29900,8 @@ fi fi - if test "$py_cv_module__multibytecodec" != "n/a"; then : + if test "$py_cv_module__multibytecodec" != "n/a" +then : py_cv_module__multibytecodec=yes fi if test "$py_cv_module__multibytecodec" = yes; then @@ -24798,7 +29913,8 @@ else fi as_fn_append MODULE_BLOCK "MODULE__MULTIBYTECODEC_STATE=$py_cv_module__multibytecodec$as_nl" - if test "x$py_cv_module__multibytecodec" = xyes; then : + if test "x$py_cv_module__multibytecodec" = xyes +then : @@ -24806,7 +29922,8 @@ fi fi - if test "$py_cv_module_unicodedata" != "n/a"; then : + if test "$py_cv_module_unicodedata" != "n/a" +then : py_cv_module_unicodedata=yes fi if test "$py_cv_module_unicodedata" = yes; then @@ -24818,7 +29935,8 @@ else fi as_fn_append MODULE_BLOCK "MODULE_UNICODEDATA_STATE=$py_cv_module_unicodedata$as_nl" - if test "x$py_cv_module_unicodedata" = xyes; then : + if test "x$py_cv_module_unicodedata" = xyes +then : @@ -24827,25 +29945,29 @@ fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _md5" >&5 -$as_echo_n "checking for stdlib extension module _md5... " >&6; } - if test "$py_cv_module__md5" != "n/a"; then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _md5" >&5 +printf %s "checking for stdlib extension module _md5... " >&6; } + if test "$py_cv_module__md5" != "n/a" +then : - if test "$with_builtin_md5" = yes; then : - if true; then : + if test "$with_builtin_md5" = yes +then : + if true +then : py_cv_module__md5=yes -else +else $as_nop py_cv_module__md5=missing fi -else +else $as_nop py_cv_module__md5=disabled fi fi as_fn_append MODULE_BLOCK "MODULE__MD5_STATE=$py_cv_module__md5$as_nl" - if test "x$py_cv_module__md5" = xyes; then : - + if test "x$py_cv_module__md5" = xyes +then : + as_fn_append MODULE_BLOCK "MODULE__MD5_CFLAGS=-I\$(srcdir)/Modules/_hacl/include -I\$(srcdir)/Modules/_hacl/internal -D_BSD_SOURCE -D_DEFAULT_SOURCE$as_nl" fi @@ -24857,29 +29979,33 @@ else MODULE__MD5_FALSE= fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__md5" >&5 -$as_echo "$py_cv_module__md5" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__md5" >&5 +printf "%s\n" "$py_cv_module__md5" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _sha1" >&5 -$as_echo_n "checking for stdlib extension module _sha1... " >&6; } - if test "$py_cv_module__sha1" != "n/a"; then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _sha1" >&5 +printf %s "checking for stdlib extension module _sha1... " >&6; } + if test "$py_cv_module__sha1" != "n/a" +then : - if test "$with_builtin_sha1" = yes; then : - if true; then : + if test "$with_builtin_sha1" = yes +then : + if true +then : py_cv_module__sha1=yes -else +else $as_nop py_cv_module__sha1=missing fi -else +else $as_nop py_cv_module__sha1=disabled fi fi as_fn_append MODULE_BLOCK "MODULE__SHA1_STATE=$py_cv_module__sha1$as_nl" - if test "x$py_cv_module__sha1" = xyes; then : - + if test "x$py_cv_module__sha1" = xyes +then : + as_fn_append MODULE_BLOCK "MODULE__SHA1_CFLAGS=-I\$(srcdir)/Modules/_hacl/include -I\$(srcdir)/Modules/_hacl/internal -D_BSD_SOURCE -D_DEFAULT_SOURCE$as_nl" fi @@ -24891,95 +30017,69 @@ else MODULE__SHA1_FALSE= fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__sha1" >&5 -$as_echo "$py_cv_module__sha1" >&6; } - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _sha256" >&5 -$as_echo_n "checking for stdlib extension module _sha256... " >&6; } - if test "$py_cv_module__sha256" != "n/a"; then : - - if test "$with_builtin_sha256" = yes; then : - if true; then : - py_cv_module__sha256=yes -else - py_cv_module__sha256=missing -fi -else - py_cv_module__sha256=disabled -fi - -fi - as_fn_append MODULE_BLOCK "MODULE__SHA256_STATE=$py_cv_module__sha256$as_nl" - if test "x$py_cv_module__sha256" = xyes; then : - - - - -fi - if test "$py_cv_module__sha256" = yes; then - MODULE__SHA256_TRUE= - MODULE__SHA256_FALSE='#' -else - MODULE__SHA256_TRUE='#' - MODULE__SHA256_FALSE= -fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__sha256" >&5 -$as_echo "$py_cv_module__sha256" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__sha1" >&5 +printf "%s\n" "$py_cv_module__sha1" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _sha512" >&5 -$as_echo_n "checking for stdlib extension module _sha512... " >&6; } - if test "$py_cv_module__sha512" != "n/a"; then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _sha2" >&5 +printf %s "checking for stdlib extension module _sha2... " >&6; } + if test "$py_cv_module__sha2" != "n/a" +then : - if test "$with_builtin_sha512" = yes; then : - if true; then : - py_cv_module__sha512=yes -else - py_cv_module__sha512=missing + if test "$with_builtin_sha2" = yes +then : + if true +then : + py_cv_module__sha2=yes +else $as_nop + py_cv_module__sha2=missing fi -else - py_cv_module__sha512=disabled +else $as_nop + py_cv_module__sha2=disabled fi fi - as_fn_append MODULE_BLOCK "MODULE__SHA512_STATE=$py_cv_module__sha512$as_nl" - if test "x$py_cv_module__sha512" = xyes; then : - + as_fn_append MODULE_BLOCK "MODULE__SHA2_STATE=$py_cv_module__sha2$as_nl" + if test "x$py_cv_module__sha2" = xyes +then : + as_fn_append MODULE_BLOCK "MODULE__SHA2_CFLAGS=-I\$(srcdir)/Modules/_hacl/include -I\$(srcdir)/Modules/_hacl/internal -D_BSD_SOURCE -D_DEFAULT_SOURCE$as_nl" fi - if test "$py_cv_module__sha512" = yes; then - MODULE__SHA512_TRUE= - MODULE__SHA512_FALSE='#' + if test "$py_cv_module__sha2" = yes; then + MODULE__SHA2_TRUE= + MODULE__SHA2_FALSE='#' else - MODULE__SHA512_TRUE='#' - MODULE__SHA512_FALSE= + MODULE__SHA2_TRUE='#' + MODULE__SHA2_FALSE= fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__sha512" >&5 -$as_echo "$py_cv_module__sha512" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__sha2" >&5 +printf "%s\n" "$py_cv_module__sha2" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _sha3" >&5 -$as_echo_n "checking for stdlib extension module _sha3... " >&6; } - if test "$py_cv_module__sha3" != "n/a"; then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _sha3" >&5 +printf %s "checking for stdlib extension module _sha3... " >&6; } + if test "$py_cv_module__sha3" != "n/a" +then : - if test "$with_builtin_sha3" = yes; then : - if true; then : + if test "$with_builtin_sha3" = yes +then : + if true +then : py_cv_module__sha3=yes -else +else $as_nop py_cv_module__sha3=missing fi -else +else $as_nop py_cv_module__sha3=disabled fi fi as_fn_append MODULE_BLOCK "MODULE__SHA3_STATE=$py_cv_module__sha3$as_nl" - if test "x$py_cv_module__sha3" = xyes; then : + if test "x$py_cv_module__sha3" = xyes +then : @@ -24993,27 +30093,31 @@ else MODULE__SHA3_FALSE= fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__sha3" >&5 -$as_echo "$py_cv_module__sha3" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__sha3" >&5 +printf "%s\n" "$py_cv_module__sha3" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _blake2" >&5 -$as_echo_n "checking for stdlib extension module _blake2... " >&6; } - if test "$py_cv_module__blake2" != "n/a"; then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _blake2" >&5 +printf %s "checking for stdlib extension module _blake2... " >&6; } + if test "$py_cv_module__blake2" != "n/a" +then : - if test "$with_builtin_blake2" = yes; then : - if true; then : + if test "$with_builtin_blake2" = yes +then : + if true +then : py_cv_module__blake2=yes -else +else $as_nop py_cv_module__blake2=missing fi -else +else $as_nop py_cv_module__blake2=disabled fi fi as_fn_append MODULE_BLOCK "MODULE__BLAKE2_STATE=$py_cv_module__blake2$as_nl" - if test "x$py_cv_module__blake2" = xyes; then : + if test "x$py_cv_module__blake2" = xyes +then : as_fn_append MODULE_BLOCK "MODULE__BLAKE2_CFLAGS=$LIBB2_CFLAGS$as_nl" as_fn_append MODULE_BLOCK "MODULE__BLAKE2_LDFLAGS=$LIBB2_LIBS$as_nl" @@ -25027,28 +30131,32 @@ else MODULE__BLAKE2_FALSE= fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__blake2" >&5 -$as_echo "$py_cv_module__blake2" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__blake2" >&5 +printf "%s\n" "$py_cv_module__blake2" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _crypt" >&5 -$as_echo_n "checking for stdlib extension module _crypt... " >&6; } - if test "$py_cv_module__crypt" != "n/a"; then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _crypt" >&5 +printf %s "checking for stdlib extension module _crypt... " >&6; } + if test "$py_cv_module__crypt" != "n/a" +then : - if true; then : - if test "$ac_cv_crypt_crypt" = yes; then : + if true +then : + if test "$ac_cv_crypt_crypt" = yes +then : py_cv_module__crypt=yes -else +else $as_nop py_cv_module__crypt=missing fi -else +else $as_nop py_cv_module__crypt=disabled fi fi as_fn_append MODULE_BLOCK "MODULE__CRYPT_STATE=$py_cv_module__crypt$as_nl" - if test "x$py_cv_module__crypt" = xyes; then : + if test "x$py_cv_module__crypt" = xyes +then : as_fn_append MODULE_BLOCK "MODULE__CRYPT_CFLAGS=$LIBCRYPT_CFLAGS$as_nl" as_fn_append MODULE_BLOCK "MODULE__CRYPT_LDFLAGS=$LIBCRYPT_LIBS$as_nl" @@ -25062,27 +30170,147 @@ else MODULE__CRYPT_FALSE= fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__crypt" >&5 -$as_echo "$py_cv_module__crypt" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__crypt" >&5 +printf "%s\n" "$py_cv_module__crypt" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _decimal" >&5 -$as_echo_n "checking for stdlib extension module _decimal... " >&6; } - if test "$py_cv_module__decimal" != "n/a"; then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _ctypes" >&5 +printf %s "checking for stdlib extension module _ctypes... " >&6; } + if test "$py_cv_module__ctypes" != "n/a" +then : - if true; then : - if true; then : - py_cv_module__decimal=yes + if true +then : + if test "$have_libffi" = yes +then : + py_cv_module__ctypes=yes +else $as_nop + py_cv_module__ctypes=missing +fi +else $as_nop + py_cv_module__ctypes=disabled +fi + +fi + as_fn_append MODULE_BLOCK "MODULE__CTYPES_STATE=$py_cv_module__ctypes$as_nl" + if test "x$py_cv_module__ctypes" = xyes +then : + + as_fn_append MODULE_BLOCK "MODULE__CTYPES_CFLAGS=$NO_STRICT_OVERFLOW_CFLAGS $LIBFFI_CFLAGS$as_nl" + as_fn_append MODULE_BLOCK "MODULE__CTYPES_LDFLAGS=$LIBFFI_LIBS$as_nl" + +fi + if test "$py_cv_module__ctypes" = yes; then + MODULE__CTYPES_TRUE= + MODULE__CTYPES_FALSE='#' else - py_cv_module__decimal=missing + MODULE__CTYPES_TRUE='#' + MODULE__CTYPES_FALSE= +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__ctypes" >&5 +printf "%s\n" "$py_cv_module__ctypes" >&6; } + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _curses" >&5 +printf %s "checking for stdlib extension module _curses... " >&6; } + if test "$py_cv_module__curses" != "n/a" +then : + + if true +then : + if test "$have_curses" != "no" +then : + py_cv_module__curses=yes +else $as_nop + py_cv_module__curses=missing +fi +else $as_nop + py_cv_module__curses=disabled +fi + +fi + as_fn_append MODULE_BLOCK "MODULE__CURSES_STATE=$py_cv_module__curses$as_nl" + if test "x$py_cv_module__curses" = xyes +then : + + as_fn_append MODULE_BLOCK "MODULE__CURSES_CFLAGS=$CURSES_CFLAGS$as_nl" + as_fn_append MODULE_BLOCK "MODULE__CURSES_LDFLAGS=$CURSES_LIBS +$as_nl" + +fi + if test "$py_cv_module__curses" = yes; then + MODULE__CURSES_TRUE= + MODULE__CURSES_FALSE='#' +else + MODULE__CURSES_TRUE='#' + MODULE__CURSES_FALSE= +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__curses" >&5 +printf "%s\n" "$py_cv_module__curses" >&6; } + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _curses_panel" >&5 +printf %s "checking for stdlib extension module _curses_panel... " >&6; } + if test "$py_cv_module__curses_panel" != "n/a" +then : + + if true +then : + if test "$have_panel" != "no" +then : + py_cv_module__curses_panel=yes +else $as_nop + py_cv_module__curses_panel=missing +fi +else $as_nop + py_cv_module__curses_panel=disabled +fi + +fi + as_fn_append MODULE_BLOCK "MODULE__CURSES_PANEL_STATE=$py_cv_module__curses_panel$as_nl" + if test "x$py_cv_module__curses_panel" = xyes +then : + + as_fn_append MODULE_BLOCK "MODULE__CURSES_PANEL_CFLAGS=$PANEL_CFLAGS $CURSES_CFLAGS$as_nl" + as_fn_append MODULE_BLOCK "MODULE__CURSES_PANEL_LDFLAGS=$PANEL_LIBS $CURSES_LIBS +$as_nl" + fi + if test "$py_cv_module__curses_panel" = yes; then + MODULE__CURSES_PANEL_TRUE= + MODULE__CURSES_PANEL_FALSE='#' else + MODULE__CURSES_PANEL_TRUE='#' + MODULE__CURSES_PANEL_FALSE= +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__curses_panel" >&5 +printf "%s\n" "$py_cv_module__curses_panel" >&6; } + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _decimal" >&5 +printf %s "checking for stdlib extension module _decimal... " >&6; } + if test "$py_cv_module__decimal" != "n/a" +then : + + if true +then : + if true +then : + py_cv_module__decimal=yes +else $as_nop + py_cv_module__decimal=missing +fi +else $as_nop py_cv_module__decimal=disabled fi fi as_fn_append MODULE_BLOCK "MODULE__DECIMAL_STATE=$py_cv_module__decimal$as_nl" - if test "x$py_cv_module__decimal" = xyes; then : + if test "x$py_cv_module__decimal" = xyes +then : as_fn_append MODULE_BLOCK "MODULE__DECIMAL_CFLAGS=$LIBMPDEC_CFLAGS$as_nl" as_fn_append MODULE_BLOCK "MODULE__DECIMAL_LDFLAGS=$LIBMPDEC_LDFLAGS$as_nl" @@ -25096,27 +30324,69 @@ else MODULE__DECIMAL_FALSE= fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__decimal" >&5 -$as_echo "$py_cv_module__decimal" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__decimal" >&5 +printf "%s\n" "$py_cv_module__decimal" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _gdbm" >&5 -$as_echo_n "checking for stdlib extension module _gdbm... " >&6; } - if test "$py_cv_module__gdbm" != "n/a"; then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _dbm" >&5 +printf %s "checking for stdlib extension module _dbm... " >&6; } + if test "$py_cv_module__dbm" != "n/a" +then : - if test "$have_gdbm_dbmliborder" = yes; then : - if test "$have_gdbm" = yes; then : - py_cv_module__gdbm=yes + if test -n "$with_dbmliborder" +then : + if test "$have_dbm" != "no" +then : + py_cv_module__dbm=yes +else $as_nop + py_cv_module__dbm=missing +fi +else $as_nop + py_cv_module__dbm=disabled +fi + +fi + as_fn_append MODULE_BLOCK "MODULE__DBM_STATE=$py_cv_module__dbm$as_nl" + if test "x$py_cv_module__dbm" = xyes +then : + + as_fn_append MODULE_BLOCK "MODULE__DBM_CFLAGS=$DBM_CFLAGS$as_nl" + as_fn_append MODULE_BLOCK "MODULE__DBM_LDFLAGS=$DBM_LIBS$as_nl" + +fi + if test "$py_cv_module__dbm" = yes; then + MODULE__DBM_TRUE= + MODULE__DBM_FALSE='#' else + MODULE__DBM_TRUE='#' + MODULE__DBM_FALSE= +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__dbm" >&5 +printf "%s\n" "$py_cv_module__dbm" >&6; } + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _gdbm" >&5 +printf %s "checking for stdlib extension module _gdbm... " >&6; } + if test "$py_cv_module__gdbm" != "n/a" +then : + + if test "$have_gdbm_dbmliborder" = yes +then : + if test "$have_gdbm" = yes +then : + py_cv_module__gdbm=yes +else $as_nop py_cv_module__gdbm=missing fi -else +else $as_nop py_cv_module__gdbm=disabled fi fi as_fn_append MODULE_BLOCK "MODULE__GDBM_STATE=$py_cv_module__gdbm$as_nl" - if test "x$py_cv_module__gdbm" = xyes; then : + if test "x$py_cv_module__gdbm" = xyes +then : as_fn_append MODULE_BLOCK "MODULE__GDBM_CFLAGS=$GDBM_CFLAGS$as_nl" as_fn_append MODULE_BLOCK "MODULE__GDBM_LDFLAGS=$GDBM_LIBS$as_nl" @@ -25130,27 +30400,31 @@ else MODULE__GDBM_FALSE= fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__gdbm" >&5 -$as_echo "$py_cv_module__gdbm" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__gdbm" >&5 +printf "%s\n" "$py_cv_module__gdbm" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module nis" >&5 -$as_echo_n "checking for stdlib extension module nis... " >&6; } - if test "$py_cv_module_nis" != "n/a"; then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module nis" >&5 +printf %s "checking for stdlib extension module nis... " >&6; } + if test "$py_cv_module_nis" != "n/a" +then : - if true; then : - if test "$have_nis" = yes -a "$ac_cv_header_rpc_rpc_h" = yes; then : + if true +then : + if test "$have_nis" = yes -a "$ac_cv_header_rpc_rpc_h" = yes +then : py_cv_module_nis=yes -else +else $as_nop py_cv_module_nis=missing fi -else +else $as_nop py_cv_module_nis=disabled fi fi as_fn_append MODULE_BLOCK "MODULE_NIS_STATE=$py_cv_module_nis$as_nl" - if test "x$py_cv_module_nis" = xyes; then : + if test "x$py_cv_module_nis" = xyes +then : as_fn_append MODULE_BLOCK "MODULE_NIS_CFLAGS=$LIBNSL_CFLAGS$as_nl" as_fn_append MODULE_BLOCK "MODULE_NIS_LDFLAGS=$LIBNSL_LIBS$as_nl" @@ -25164,27 +30438,69 @@ else MODULE_NIS_FALSE= fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module_nis" >&5 -$as_echo "$py_cv_module_nis" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module_nis" >&5 +printf "%s\n" "$py_cv_module_nis" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _sqlite3" >&5 -$as_echo_n "checking for stdlib extension module _sqlite3... " >&6; } - if test "$py_cv_module__sqlite3" != "n/a"; then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module readline" >&5 +printf %s "checking for stdlib extension module readline... " >&6; } + if test "$py_cv_module_readline" != "n/a" +then : - if test "$have_sqlite3" = "yes"; then : - if test "$have_supported_sqlite3" = "yes"; then : - py_cv_module__sqlite3=yes + if true +then : + if test "$with_readline" != "no" +then : + py_cv_module_readline=yes +else $as_nop + py_cv_module_readline=missing +fi +else $as_nop + py_cv_module_readline=disabled +fi + +fi + as_fn_append MODULE_BLOCK "MODULE_READLINE_STATE=$py_cv_module_readline$as_nl" + if test "x$py_cv_module_readline" = xyes +then : + + as_fn_append MODULE_BLOCK "MODULE_READLINE_CFLAGS=$READLINE_CFLAGS$as_nl" + as_fn_append MODULE_BLOCK "MODULE_READLINE_LDFLAGS=$READLINE_LIBS$as_nl" + +fi + if test "$py_cv_module_readline" = yes; then + MODULE_READLINE_TRUE= + MODULE_READLINE_FALSE='#' else + MODULE_READLINE_TRUE='#' + MODULE_READLINE_FALSE= +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module_readline" >&5 +printf "%s\n" "$py_cv_module_readline" >&6; } + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _sqlite3" >&5 +printf %s "checking for stdlib extension module _sqlite3... " >&6; } + if test "$py_cv_module__sqlite3" != "n/a" +then : + + if test "$have_sqlite3" = "yes" +then : + if test "$have_supported_sqlite3" = "yes" +then : + py_cv_module__sqlite3=yes +else $as_nop py_cv_module__sqlite3=missing fi -else +else $as_nop py_cv_module__sqlite3=disabled fi fi as_fn_append MODULE_BLOCK "MODULE__SQLITE3_STATE=$py_cv_module__sqlite3$as_nl" - if test "x$py_cv_module__sqlite3" = xyes; then : + if test "x$py_cv_module__sqlite3" = xyes +then : as_fn_append MODULE_BLOCK "MODULE__SQLITE3_CFLAGS=$LIBSQLITE3_CFLAGS$as_nl" as_fn_append MODULE_BLOCK "MODULE__SQLITE3_LDFLAGS=$LIBSQLITE3_LIBS$as_nl" @@ -25198,27 +30514,31 @@ else MODULE__SQLITE3_FALSE= fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__sqlite3" >&5 -$as_echo "$py_cv_module__sqlite3" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__sqlite3" >&5 +printf "%s\n" "$py_cv_module__sqlite3" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _tkinter" >&5 -$as_echo_n "checking for stdlib extension module _tkinter... " >&6; } - if test "$py_cv_module__tkinter" != "n/a"; then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _tkinter" >&5 +printf %s "checking for stdlib extension module _tkinter... " >&6; } + if test "$py_cv_module__tkinter" != "n/a" +then : - if true; then : - if test "$have_tcltk" = "yes"; then : + if true +then : + if test "$have_tcltk" = "yes" +then : py_cv_module__tkinter=yes -else +else $as_nop py_cv_module__tkinter=missing fi -else +else $as_nop py_cv_module__tkinter=disabled fi fi as_fn_append MODULE_BLOCK "MODULE__TKINTER_STATE=$py_cv_module__tkinter$as_nl" - if test "x$py_cv_module__tkinter" = xyes; then : + if test "x$py_cv_module__tkinter" = xyes +then : as_fn_append MODULE_BLOCK "MODULE__TKINTER_CFLAGS=$TCLTK_CFLAGS$as_nl" as_fn_append MODULE_BLOCK "MODULE__TKINTER_LDFLAGS=$TCLTK_LIBS$as_nl" @@ -25232,27 +30552,31 @@ else MODULE__TKINTER_FALSE= fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__tkinter" >&5 -$as_echo "$py_cv_module__tkinter" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__tkinter" >&5 +printf "%s\n" "$py_cv_module__tkinter" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _uuid" >&5 -$as_echo_n "checking for stdlib extension module _uuid... " >&6; } - if test "$py_cv_module__uuid" != "n/a"; then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _uuid" >&5 +printf %s "checking for stdlib extension module _uuid... " >&6; } + if test "$py_cv_module__uuid" != "n/a" +then : - if true; then : - if test "$have_uuid" = "yes"; then : + if true +then : + if test "$have_uuid" = "yes" +then : py_cv_module__uuid=yes -else +else $as_nop py_cv_module__uuid=missing fi -else +else $as_nop py_cv_module__uuid=disabled fi fi as_fn_append MODULE_BLOCK "MODULE__UUID_STATE=$py_cv_module__uuid$as_nl" - if test "x$py_cv_module__uuid" = xyes; then : + if test "x$py_cv_module__uuid" = xyes +then : as_fn_append MODULE_BLOCK "MODULE__UUID_CFLAGS=$LIBUUID_CFLAGS$as_nl" as_fn_append MODULE_BLOCK "MODULE__UUID_LDFLAGS=$LIBUUID_LIBS$as_nl" @@ -25266,28 +30590,32 @@ else MODULE__UUID_FALSE= fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__uuid" >&5 -$as_echo "$py_cv_module__uuid" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__uuid" >&5 +printf "%s\n" "$py_cv_module__uuid" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module zlib" >&5 -$as_echo_n "checking for stdlib extension module zlib... " >&6; } - if test "$py_cv_module_zlib" != "n/a"; then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module zlib" >&5 +printf %s "checking for stdlib extension module zlib... " >&6; } + if test "$py_cv_module_zlib" != "n/a" +then : - if true; then : - if test "$have_zlib" = yes; then : + if true +then : + if test "$have_zlib" = yes +then : py_cv_module_zlib=yes -else +else $as_nop py_cv_module_zlib=missing fi -else +else $as_nop py_cv_module_zlib=disabled fi fi as_fn_append MODULE_BLOCK "MODULE_ZLIB_STATE=$py_cv_module_zlib$as_nl" - if test "x$py_cv_module_zlib" = xyes; then : + if test "x$py_cv_module_zlib" = xyes +then : as_fn_append MODULE_BLOCK "MODULE_ZLIB_CFLAGS=$ZLIB_CFLAGS$as_nl" as_fn_append MODULE_BLOCK "MODULE_ZLIB_LDFLAGS=$ZLIB_LIBS$as_nl" @@ -25301,11 +30629,12 @@ else MODULE_ZLIB_FALSE= fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module_zlib" >&5 -$as_echo "$py_cv_module_zlib" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module_zlib" >&5 +printf "%s\n" "$py_cv_module_zlib" >&6; } - if test "$py_cv_module_binascii" != "n/a"; then : + if test "$py_cv_module_binascii" != "n/a" +then : py_cv_module_binascii=yes fi if test "$py_cv_module_binascii" = yes; then @@ -25317,7 +30646,8 @@ else fi as_fn_append MODULE_BLOCK "MODULE_BINASCII_STATE=$py_cv_module_binascii$as_nl" - if test "x$py_cv_module_binascii" = xyes; then : + if test "x$py_cv_module_binascii" = xyes +then : as_fn_append MODULE_BLOCK "MODULE_BINASCII_CFLAGS=$BINASCII_CFLAGS$as_nl" as_fn_append MODULE_BLOCK "MODULE_BINASCII_LDFLAGS=$BINASCII_LIBS$as_nl" @@ -25325,23 +30655,27 @@ fi fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _bz2" >&5 -$as_echo_n "checking for stdlib extension module _bz2... " >&6; } - if test "$py_cv_module__bz2" != "n/a"; then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _bz2" >&5 +printf %s "checking for stdlib extension module _bz2... " >&6; } + if test "$py_cv_module__bz2" != "n/a" +then : - if true; then : - if test "$have_bzip2" = yes; then : + if true +then : + if test "$have_bzip2" = yes +then : py_cv_module__bz2=yes -else +else $as_nop py_cv_module__bz2=missing fi -else +else $as_nop py_cv_module__bz2=disabled fi fi as_fn_append MODULE_BLOCK "MODULE__BZ2_STATE=$py_cv_module__bz2$as_nl" - if test "x$py_cv_module__bz2" = xyes; then : + if test "x$py_cv_module__bz2" = xyes +then : as_fn_append MODULE_BLOCK "MODULE__BZ2_CFLAGS=$BZIP2_CFLAGS$as_nl" as_fn_append MODULE_BLOCK "MODULE__BZ2_LDFLAGS=$BZIP2_LIBS$as_nl" @@ -25355,27 +30689,31 @@ else MODULE__BZ2_FALSE= fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__bz2" >&5 -$as_echo "$py_cv_module__bz2" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__bz2" >&5 +printf "%s\n" "$py_cv_module__bz2" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _lzma" >&5 -$as_echo_n "checking for stdlib extension module _lzma... " >&6; } - if test "$py_cv_module__lzma" != "n/a"; then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _lzma" >&5 +printf %s "checking for stdlib extension module _lzma... " >&6; } + if test "$py_cv_module__lzma" != "n/a" +then : - if true; then : - if test "$have_liblzma" = yes; then : + if true +then : + if test "$have_liblzma" = yes +then : py_cv_module__lzma=yes -else +else $as_nop py_cv_module__lzma=missing fi -else +else $as_nop py_cv_module__lzma=disabled fi fi as_fn_append MODULE_BLOCK "MODULE__LZMA_STATE=$py_cv_module__lzma$as_nl" - if test "x$py_cv_module__lzma" = xyes; then : + if test "x$py_cv_module__lzma" = xyes +then : as_fn_append MODULE_BLOCK "MODULE__LZMA_CFLAGS=$LIBLZMA_CFLAGS$as_nl" as_fn_append MODULE_BLOCK "MODULE__LZMA_LDFLAGS=$LIBLZMA_LIBS$as_nl" @@ -25389,28 +30727,32 @@ else MODULE__LZMA_FALSE= fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__lzma" >&5 -$as_echo "$py_cv_module__lzma" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__lzma" >&5 +printf "%s\n" "$py_cv_module__lzma" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _ssl" >&5 -$as_echo_n "checking for stdlib extension module _ssl... " >&6; } - if test "$py_cv_module__ssl" != "n/a"; then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _ssl" >&5 +printf %s "checking for stdlib extension module _ssl... " >&6; } + if test "$py_cv_module__ssl" != "n/a" +then : - if true; then : - if test "$ac_cv_working_openssl_ssl" = yes; then : + if true +then : + if test "$ac_cv_working_openssl_ssl" = yes +then : py_cv_module__ssl=yes -else +else $as_nop py_cv_module__ssl=missing fi -else +else $as_nop py_cv_module__ssl=disabled fi fi as_fn_append MODULE_BLOCK "MODULE__SSL_STATE=$py_cv_module__ssl$as_nl" - if test "x$py_cv_module__ssl" = xyes; then : + if test "x$py_cv_module__ssl" = xyes +then : as_fn_append MODULE_BLOCK "MODULE__SSL_CFLAGS=$OPENSSL_INCLUDES$as_nl" as_fn_append MODULE_BLOCK "MODULE__SSL_LDFLAGS=$OPENSSL_LDFLAGS $OPENSSL_LDFLAGS_RPATH $OPENSSL_LIBS$as_nl" @@ -25424,27 +30766,31 @@ else MODULE__SSL_FALSE= fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__ssl" >&5 -$as_echo "$py_cv_module__ssl" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__ssl" >&5 +printf "%s\n" "$py_cv_module__ssl" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _hashlib" >&5 -$as_echo_n "checking for stdlib extension module _hashlib... " >&6; } - if test "$py_cv_module__hashlib" != "n/a"; then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _hashlib" >&5 +printf %s "checking for stdlib extension module _hashlib... " >&6; } + if test "$py_cv_module__hashlib" != "n/a" +then : - if true; then : - if test "$ac_cv_working_openssl_hashlib" = yes; then : + if true +then : + if test "$ac_cv_working_openssl_hashlib" = yes +then : py_cv_module__hashlib=yes -else +else $as_nop py_cv_module__hashlib=missing fi -else +else $as_nop py_cv_module__hashlib=disabled fi fi as_fn_append MODULE_BLOCK "MODULE__HASHLIB_STATE=$py_cv_module__hashlib$as_nl" - if test "x$py_cv_module__hashlib" = xyes; then : + if test "x$py_cv_module__hashlib" = xyes +then : as_fn_append MODULE_BLOCK "MODULE__HASHLIB_CFLAGS=$OPENSSL_INCLUDES$as_nl" as_fn_append MODULE_BLOCK "MODULE__HASHLIB_LDFLAGS=$OPENSSL_LDFLAGS $OPENSSL_LDFLAGS_RPATH $LIBCRYPTO_LIBS$as_nl" @@ -25458,28 +30804,32 @@ else MODULE__HASHLIB_FALSE= fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__hashlib" >&5 -$as_echo "$py_cv_module__hashlib" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__hashlib" >&5 +printf "%s\n" "$py_cv_module__hashlib" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _testcapi" >&5 -$as_echo_n "checking for stdlib extension module _testcapi... " >&6; } - if test "$py_cv_module__testcapi" != "n/a"; then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _testcapi" >&5 +printf %s "checking for stdlib extension module _testcapi... " >&6; } + if test "$py_cv_module__testcapi" != "n/a" +then : - if test "$TEST_MODULES" = yes; then : - if true; then : + if test "$TEST_MODULES" = yes +then : + if true +then : py_cv_module__testcapi=yes -else +else $as_nop py_cv_module__testcapi=missing fi -else +else $as_nop py_cv_module__testcapi=disabled fi fi as_fn_append MODULE_BLOCK "MODULE__TESTCAPI_STATE=$py_cv_module__testcapi$as_nl" - if test "x$py_cv_module__testcapi" = xyes; then : + if test "x$py_cv_module__testcapi" = xyes +then : @@ -25493,27 +30843,31 @@ else MODULE__TESTCAPI_FALSE= fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__testcapi" >&5 -$as_echo "$py_cv_module__testcapi" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__testcapi" >&5 +printf "%s\n" "$py_cv_module__testcapi" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _testclinic" >&5 -$as_echo_n "checking for stdlib extension module _testclinic... " >&6; } - if test "$py_cv_module__testclinic" != "n/a"; then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _testclinic" >&5 +printf %s "checking for stdlib extension module _testclinic... " >&6; } + if test "$py_cv_module__testclinic" != "n/a" +then : - if test "$TEST_MODULES" = yes; then : - if true; then : + if test "$TEST_MODULES" = yes +then : + if true +then : py_cv_module__testclinic=yes -else +else $as_nop py_cv_module__testclinic=missing fi -else +else $as_nop py_cv_module__testclinic=disabled fi fi as_fn_append MODULE_BLOCK "MODULE__TESTCLINIC_STATE=$py_cv_module__testclinic$as_nl" - if test "x$py_cv_module__testclinic" = xyes; then : + if test "x$py_cv_module__testclinic" = xyes +then : @@ -25527,27 +30881,31 @@ else MODULE__TESTCLINIC_FALSE= fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__testclinic" >&5 -$as_echo "$py_cv_module__testclinic" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__testclinic" >&5 +printf "%s\n" "$py_cv_module__testclinic" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _testinternalcapi" >&5 -$as_echo_n "checking for stdlib extension module _testinternalcapi... " >&6; } - if test "$py_cv_module__testinternalcapi" != "n/a"; then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _testinternalcapi" >&5 +printf %s "checking for stdlib extension module _testinternalcapi... " >&6; } + if test "$py_cv_module__testinternalcapi" != "n/a" +then : - if test "$TEST_MODULES" = yes; then : - if true; then : + if test "$TEST_MODULES" = yes +then : + if true +then : py_cv_module__testinternalcapi=yes -else +else $as_nop py_cv_module__testinternalcapi=missing fi -else +else $as_nop py_cv_module__testinternalcapi=disabled fi fi as_fn_append MODULE_BLOCK "MODULE__TESTINTERNALCAPI_STATE=$py_cv_module__testinternalcapi$as_nl" - if test "x$py_cv_module__testinternalcapi" = xyes; then : + if test "x$py_cv_module__testinternalcapi" = xyes +then : @@ -25561,27 +30919,31 @@ else MODULE__TESTINTERNALCAPI_FALSE= fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__testinternalcapi" >&5 -$as_echo "$py_cv_module__testinternalcapi" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__testinternalcapi" >&5 +printf "%s\n" "$py_cv_module__testinternalcapi" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _testbuffer" >&5 -$as_echo_n "checking for stdlib extension module _testbuffer... " >&6; } - if test "$py_cv_module__testbuffer" != "n/a"; then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _testbuffer" >&5 +printf %s "checking for stdlib extension module _testbuffer... " >&6; } + if test "$py_cv_module__testbuffer" != "n/a" +then : - if test "$TEST_MODULES" = yes; then : - if true; then : + if test "$TEST_MODULES" = yes +then : + if true +then : py_cv_module__testbuffer=yes -else +else $as_nop py_cv_module__testbuffer=missing fi -else +else $as_nop py_cv_module__testbuffer=disabled fi fi as_fn_append MODULE_BLOCK "MODULE__TESTBUFFER_STATE=$py_cv_module__testbuffer$as_nl" - if test "x$py_cv_module__testbuffer" = xyes; then : + if test "x$py_cv_module__testbuffer" = xyes +then : @@ -25595,27 +30957,31 @@ else MODULE__TESTBUFFER_FALSE= fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__testbuffer" >&5 -$as_echo "$py_cv_module__testbuffer" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__testbuffer" >&5 +printf "%s\n" "$py_cv_module__testbuffer" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _testimportmultiple" >&5 -$as_echo_n "checking for stdlib extension module _testimportmultiple... " >&6; } - if test "$py_cv_module__testimportmultiple" != "n/a"; then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _testimportmultiple" >&5 +printf %s "checking for stdlib extension module _testimportmultiple... " >&6; } + if test "$py_cv_module__testimportmultiple" != "n/a" +then : - if test "$TEST_MODULES" = yes; then : - if test "$ac_cv_func_dlopen" = yes; then : + if test "$TEST_MODULES" = yes +then : + if test "$ac_cv_func_dlopen" = yes +then : py_cv_module__testimportmultiple=yes -else +else $as_nop py_cv_module__testimportmultiple=missing fi -else +else $as_nop py_cv_module__testimportmultiple=disabled fi fi as_fn_append MODULE_BLOCK "MODULE__TESTIMPORTMULTIPLE_STATE=$py_cv_module__testimportmultiple$as_nl" - if test "x$py_cv_module__testimportmultiple" = xyes; then : + if test "x$py_cv_module__testimportmultiple" = xyes +then : @@ -25629,27 +30995,31 @@ else MODULE__TESTIMPORTMULTIPLE_FALSE= fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__testimportmultiple" >&5 -$as_echo "$py_cv_module__testimportmultiple" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__testimportmultiple" >&5 +printf "%s\n" "$py_cv_module__testimportmultiple" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _testmultiphase" >&5 -$as_echo_n "checking for stdlib extension module _testmultiphase... " >&6; } - if test "$py_cv_module__testmultiphase" != "n/a"; then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _testmultiphase" >&5 +printf %s "checking for stdlib extension module _testmultiphase... " >&6; } + if test "$py_cv_module__testmultiphase" != "n/a" +then : - if test "$TEST_MODULES" = yes; then : - if test "$ac_cv_func_dlopen" = yes; then : + if test "$TEST_MODULES" = yes +then : + if test "$ac_cv_func_dlopen" = yes +then : py_cv_module__testmultiphase=yes -else +else $as_nop py_cv_module__testmultiphase=missing fi -else +else $as_nop py_cv_module__testmultiphase=disabled fi fi as_fn_append MODULE_BLOCK "MODULE__TESTMULTIPHASE_STATE=$py_cv_module__testmultiphase$as_nl" - if test "x$py_cv_module__testmultiphase" = xyes; then : + if test "x$py_cv_module__testmultiphase" = xyes +then : @@ -25663,27 +31033,69 @@ else MODULE__TESTMULTIPHASE_FALSE= fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__testmultiphase" >&5 -$as_echo "$py_cv_module__testmultiphase" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__testmultiphase" >&5 +printf "%s\n" "$py_cv_module__testmultiphase" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _xxtestfuzz" >&5 -$as_echo_n "checking for stdlib extension module _xxtestfuzz... " >&6; } - if test "$py_cv_module__xxtestfuzz" != "n/a"; then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module xxsubtype" >&5 +printf %s "checking for stdlib extension module xxsubtype... " >&6; } + if test "$py_cv_module_xxsubtype" != "n/a" +then : - if test "$TEST_MODULES" = yes; then : - if true; then : - py_cv_module__xxtestfuzz=yes + if test "$TEST_MODULES" = yes +then : + if true +then : + py_cv_module_xxsubtype=yes +else $as_nop + py_cv_module_xxsubtype=missing +fi +else $as_nop + py_cv_module_xxsubtype=disabled +fi + +fi + as_fn_append MODULE_BLOCK "MODULE_XXSUBTYPE_STATE=$py_cv_module_xxsubtype$as_nl" + if test "x$py_cv_module_xxsubtype" = xyes +then : + + + + +fi + if test "$py_cv_module_xxsubtype" = yes; then + MODULE_XXSUBTYPE_TRUE= + MODULE_XXSUBTYPE_FALSE='#' else + MODULE_XXSUBTYPE_TRUE='#' + MODULE_XXSUBTYPE_FALSE= +fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module_xxsubtype" >&5 +printf "%s\n" "$py_cv_module_xxsubtype" >&6; } + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _xxtestfuzz" >&5 +printf %s "checking for stdlib extension module _xxtestfuzz... " >&6; } + if test "$py_cv_module__xxtestfuzz" != "n/a" +then : + + if test "$TEST_MODULES" = yes +then : + if true +then : + py_cv_module__xxtestfuzz=yes +else $as_nop py_cv_module__xxtestfuzz=missing fi -else +else $as_nop py_cv_module__xxtestfuzz=disabled fi fi as_fn_append MODULE_BLOCK "MODULE__XXTESTFUZZ_STATE=$py_cv_module__xxtestfuzz$as_nl" - if test "x$py_cv_module__xxtestfuzz" = xyes; then : + if test "x$py_cv_module__xxtestfuzz" = xyes +then : @@ -25697,30 +31109,34 @@ else MODULE__XXTESTFUZZ_FALSE= fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__xxtestfuzz" >&5 -$as_echo "$py_cv_module__xxtestfuzz" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__xxtestfuzz" >&5 +printf "%s\n" "$py_cv_module__xxtestfuzz" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _ctypes_test" >&5 -$as_echo_n "checking for stdlib extension module _ctypes_test... " >&6; } - if test "$py_cv_module__ctypes_test" != "n/a"; then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module _ctypes_test" >&5 +printf %s "checking for stdlib extension module _ctypes_test... " >&6; } + if test "$py_cv_module__ctypes_test" != "n/a" +then : - if test "$TEST_MODULES" = yes; then : - if test "$ac_cv_func_dlopen" = yes; then : + if test "$TEST_MODULES" = yes +then : + if test "$have_libffi" = yes -a "$ac_cv_func_dlopen" = yes +then : py_cv_module__ctypes_test=yes -else +else $as_nop py_cv_module__ctypes_test=missing fi -else +else $as_nop py_cv_module__ctypes_test=disabled fi fi as_fn_append MODULE_BLOCK "MODULE__CTYPES_TEST_STATE=$py_cv_module__ctypes_test$as_nl" - if test "x$py_cv_module__ctypes_test" = xyes; then : + if test "x$py_cv_module__ctypes_test" = xyes +then : - as_fn_append MODULE_BLOCK "MODULE__CTYPES_TEST_LDFLAGS=-lm$as_nl" + as_fn_append MODULE_BLOCK "MODULE__CTYPES_TEST_LDFLAGS=$LIBM$as_nl" fi if test "$py_cv_module__ctypes_test" = yes; then @@ -25731,28 +31147,32 @@ else MODULE__CTYPES_TEST_FALSE= fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__ctypes_test" >&5 -$as_echo "$py_cv_module__ctypes_test" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module__ctypes_test" >&5 +printf "%s\n" "$py_cv_module__ctypes_test" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module xxlimited" >&5 -$as_echo_n "checking for stdlib extension module xxlimited... " >&6; } - if test "$py_cv_module_xxlimited" != "n/a"; then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module xxlimited" >&5 +printf %s "checking for stdlib extension module xxlimited... " >&6; } + if test "$py_cv_module_xxlimited" != "n/a" +then : - if test "$with_trace_refs" = "no"; then : - if test "$ac_cv_func_dlopen" = yes; then : + if test "$with_trace_refs" = "no" +then : + if test "$ac_cv_func_dlopen" = yes +then : py_cv_module_xxlimited=yes -else +else $as_nop py_cv_module_xxlimited=missing fi -else +else $as_nop py_cv_module_xxlimited=disabled fi fi as_fn_append MODULE_BLOCK "MODULE_XXLIMITED_STATE=$py_cv_module_xxlimited$as_nl" - if test "x$py_cv_module_xxlimited" = xyes; then : + if test "x$py_cv_module_xxlimited" = xyes +then : @@ -25766,27 +31186,31 @@ else MODULE_XXLIMITED_FALSE= fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module_xxlimited" >&5 -$as_echo "$py_cv_module_xxlimited" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module_xxlimited" >&5 +printf "%s\n" "$py_cv_module_xxlimited" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module xxlimited_35" >&5 -$as_echo_n "checking for stdlib extension module xxlimited_35... " >&6; } - if test "$py_cv_module_xxlimited_35" != "n/a"; then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for stdlib extension module xxlimited_35" >&5 +printf %s "checking for stdlib extension module xxlimited_35... " >&6; } + if test "$py_cv_module_xxlimited_35" != "n/a" +then : - if test "$with_trace_refs" = "no"; then : - if test "$ac_cv_func_dlopen" = yes; then : + if test "$with_trace_refs" = "no" +then : + if test "$ac_cv_func_dlopen" = yes +then : py_cv_module_xxlimited_35=yes -else +else $as_nop py_cv_module_xxlimited_35=missing fi -else +else $as_nop py_cv_module_xxlimited_35=disabled fi fi as_fn_append MODULE_BLOCK "MODULE_XXLIMITED_35_STATE=$py_cv_module_xxlimited_35$as_nl" - if test "x$py_cv_module_xxlimited_35" = xyes; then : + if test "x$py_cv_module_xxlimited_35" = xyes +then : @@ -25800,8 +31224,8 @@ else MODULE_XXLIMITED_35_FALSE= fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py_cv_module_xxlimited_35" >&5 -$as_echo "$py_cv_module_xxlimited_35" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $py_cv_module_xxlimited_35" >&5 +printf "%s\n" "$py_cv_module_xxlimited_35" >&6; } # substitute multiline block, must come after last PY_STDLIB_MOD() @@ -25841,8 +31265,8 @@ _ACEOF case $ac_val in #( *${as_nl}*) case $ac_var in #( - *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 -$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( @@ -25872,15 +31296,15 @@ $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; /^ac_cv_env_/b end t clear :clear - s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + s/^\([^=]*\)=\(.*[{}].*\)$/test ${\1+y} || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 -$as_echo "$as_me: updating cache $cache_file" >&6;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +printf "%s\n" "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else @@ -25894,8 +31318,8 @@ $as_echo "$as_me: updating cache $cache_file" >&6;} fi fi else - { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 -$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +printf "%s\n" "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache @@ -25912,7 +31336,7 @@ U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' - ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + ac_i=`printf "%s\n" "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" @@ -26000,6 +31424,10 @@ if test -z "${MODULE__XXSUBINTERPRETERS_TRUE}" && test -z "${MODULE__XXSUBINTERP as_fn_error $? "conditional \"MODULE__XXSUBINTERPRETERS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${MODULE__XXINTERPCHANNELS_TRUE}" && test -z "${MODULE__XXINTERPCHANNELS_FALSE}"; then + as_fn_error $? "conditional \"MODULE__XXINTERPCHANNELS\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${MODULE__ZONEINFO_TRUE}" && test -z "${MODULE__ZONEINFO_FALSE}"; then as_fn_error $? "conditional \"MODULE__ZONEINFO\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -26124,12 +31552,8 @@ if test -z "${MODULE__SHA1_TRUE}" && test -z "${MODULE__SHA1_FALSE}"; then as_fn_error $? "conditional \"MODULE__SHA1\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi -if test -z "${MODULE__SHA256_TRUE}" && test -z "${MODULE__SHA256_FALSE}"; then - as_fn_error $? "conditional \"MODULE__SHA256\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${MODULE__SHA512_TRUE}" && test -z "${MODULE__SHA512_FALSE}"; then - as_fn_error $? "conditional \"MODULE__SHA512\" was never defined. +if test -z "${MODULE__SHA2_TRUE}" && test -z "${MODULE__SHA2_FALSE}"; then + as_fn_error $? "conditional \"MODULE__SHA2\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${MODULE__SHA3_TRUE}" && test -z "${MODULE__SHA3_FALSE}"; then @@ -26144,10 +31568,26 @@ if test -z "${MODULE__CRYPT_TRUE}" && test -z "${MODULE__CRYPT_FALSE}"; then as_fn_error $? "conditional \"MODULE__CRYPT\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${MODULE__CTYPES_TRUE}" && test -z "${MODULE__CTYPES_FALSE}"; then + as_fn_error $? "conditional \"MODULE__CTYPES\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__CURSES_TRUE}" && test -z "${MODULE__CURSES_FALSE}"; then + as_fn_error $? "conditional \"MODULE__CURSES\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${MODULE__CURSES_PANEL_TRUE}" && test -z "${MODULE__CURSES_PANEL_FALSE}"; then + as_fn_error $? "conditional \"MODULE__CURSES_PANEL\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${MODULE__DECIMAL_TRUE}" && test -z "${MODULE__DECIMAL_FALSE}"; then as_fn_error $? "conditional \"MODULE__DECIMAL\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${MODULE__DBM_TRUE}" && test -z "${MODULE__DBM_FALSE}"; then + as_fn_error $? "conditional \"MODULE__DBM\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${MODULE__GDBM_TRUE}" && test -z "${MODULE__GDBM_FALSE}"; then as_fn_error $? "conditional \"MODULE__GDBM\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -26156,6 +31596,10 @@ if test -z "${MODULE_NIS_TRUE}" && test -z "${MODULE_NIS_FALSE}"; then as_fn_error $? "conditional \"MODULE_NIS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${MODULE_READLINE_TRUE}" && test -z "${MODULE_READLINE_FALSE}"; then + as_fn_error $? "conditional \"MODULE_READLINE\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${MODULE__SQLITE3_TRUE}" && test -z "${MODULE__SQLITE3_FALSE}"; then as_fn_error $? "conditional \"MODULE__SQLITE3\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -26216,6 +31660,10 @@ if test -z "${MODULE__TESTMULTIPHASE_TRUE}" && test -z "${MODULE__TESTMULTIPHASE as_fn_error $? "conditional \"MODULE__TESTMULTIPHASE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${MODULE_XXSUBTYPE_TRUE}" && test -z "${MODULE_XXSUBTYPE_FALSE}"; then + as_fn_error $? "conditional \"MODULE_XXSUBTYPE\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${MODULE__XXTESTFUZZ_TRUE}" && test -z "${MODULE__XXTESTFUZZ_FALSE}"; then as_fn_error $? "conditional \"MODULE__XXTESTFUZZ\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -26237,8 +31685,8 @@ fi ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" -{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 -$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +printf "%s\n" "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL @@ -26261,14 +31709,16 @@ cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : +as_nop=: +if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 +then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST -else +else $as_nop case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( @@ -26278,46 +31728,46 @@ esac fi + +# Reset variables that may have inherited troublesome values from +# the environment. + +# IFS needs to be set, to space, tab, and newline, in precisely that order. +# (If _AS_PATH_WALK were called with IFS unset, it would have the +# side effect of setting IFS to empty, thus disabling word splitting.) +# Quoting is to prevent editors from complaining about space-tab. as_nl=' ' export as_nl -# Printing a long string crashes Solaris 7 /usr/bin/printf. -as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo -# Prefer a ksh shell builtin over an external printf program on Solaris, -# but without wasting forks for bash or zsh. -if test -z "$BASH_VERSION$ZSH_VERSION" \ - && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='print -r --' - as_echo_n='print -rn --' -elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='printf %s\n' - as_echo_n='printf %s' -else - if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then - as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' - as_echo_n='/usr/ucb/echo -n' - else - as_echo_body='eval expr "X$1" : "X\\(.*\\)"' - as_echo_n_body='eval - arg=$1; - case $arg in #( - *"$as_nl"*) - expr "X$arg" : "X\\(.*\\)$as_nl"; - arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; - esac; - expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" - ' - export as_echo_n_body - as_echo_n='sh -c $as_echo_n_body as_echo' - fi - export as_echo_body - as_echo='sh -c $as_echo_body as_echo' -fi +IFS=" "" $as_nl" + +PS1='$ ' +PS2='> ' +PS4='+ ' + +# Ensure predictable behavior from utilities with locale-dependent output. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# We cannot yet rely on "unset" to work, but we need these variables +# to be unset--not just set to an empty or harmless value--now, to +# avoid bugs in old shells (e.g. pre-3.0 UWIN ksh). This construct +# also avoids known problems related to "unset" and subshell syntax +# in other old shells (e.g. bash 2.01 and pdksh 5.2.14). +for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH +do eval test \${$as_var+y} \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done + +# Ensure that fds 0, 1, and 2 are open. +if (exec 3>&0) 2>/dev/null; then :; else exec 0&1) 2>/dev/null; then :; else exec 1>/dev/null; fi +if (exec 3>&2) ; then :; else exec 2>/dev/null; fi # The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then +if ${PATH_SEPARATOR+false} :; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || @@ -26326,13 +31776,6 @@ if test "${PATH_SEPARATOR+set}" != set; then fi -# IFS -# We need space, tab and new line, in precisely that order. Quoting is -# there to prevent editors from complaining about space-tab. -# (If _AS_PATH_WALK were called with IFS unset, it would disable word -# splitting by setting IFS to empty value.) -IFS=" "" $as_nl" - # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( @@ -26341,8 +31784,12 @@ case $0 in #(( for as_dir in $PATH do IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + test -r "$as_dir$0" && as_myself=$as_dir$0 && break done IFS=$as_save_IFS @@ -26354,30 +31801,10 @@ if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then - $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi -# Unset variables that we do not need and which cause bugs (e.g. in -# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" -# suppresses any "Segmentation fault" message there. '((' could -# trigger a bug in pdksh 5.2.14. -for as_var in BASH_ENV ENV MAIL MAILPATH -do eval test x\${$as_var+set} = xset \ - && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : -done -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -LC_ALL=C -export LC_ALL -LANGUAGE=C -export LANGUAGE - -# CDPATH. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] @@ -26390,13 +31817,14 @@ as_fn_error () as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi - $as_echo "$as_me: error: $2" >&2 + printf "%s\n" "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error + # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. @@ -26423,18 +31851,20 @@ as_fn_unset () { eval $1=; unset $1;} } as_unset=as_fn_unset + # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. -if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null +then : eval 'as_fn_append () { eval $1+=\$2 }' -else +else $as_nop as_fn_append () { eval $1=\$$1\$2 @@ -26446,12 +31876,13 @@ fi # as_fn_append # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. -if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null +then : eval 'as_fn_arith () { as_val=$(( $* )) }' -else +else $as_nop as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` @@ -26482,7 +31913,7 @@ as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$0" | +printf "%s\n" X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q @@ -26504,6 +31935,10 @@ as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits + +# Determine whether it's possible to make 'echo' print without a newline. +# These variables are no longer used directly by Autoconf, but are AC_SUBSTed +# for compatibility with existing Makefiles. ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) @@ -26517,6 +31952,12 @@ case `echo -n x` in #((((( ECHO_N='-n';; esac +# For backward compatibility with old third-party macros, we provide +# the shell variables $as_echo and $as_echo_n. New code should use +# AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively. +as_echo='printf %s\n' +as_echo_n='printf %s' + rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file @@ -26558,7 +31999,7 @@ as_fn_mkdir_p () as_dirs= while :; do case $as_dir in #( - *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" @@ -26567,7 +32008,7 @@ $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_dir" | +printf "%s\n" X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q @@ -26629,8 +32070,8 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by python $as_me 3.11, which was -generated by GNU Autoconf 2.69. Invocation command line was +This file was extended by python $as_me 3.12, which was +generated by GNU Autoconf 2.71. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS @@ -26688,14 +32129,16 @@ $config_headers Report bugs to ." _ACEOF +ac_cs_config=`printf "%s\n" "$ac_configure_args" | sed "$ac_safe_unquote"` +ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\''/g"` cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" +ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ -python config.status 3.11 -configured by $0, generated by GNU Autoconf 2.69, +python config.status 3.12 +configured by $0, generated by GNU Autoconf 2.71, with options \\"\$ac_cs_config\\" -Copyright (C) 2012 Free Software Foundation, Inc. +Copyright (C) 2021 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." @@ -26734,15 +32177,15 @@ do -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) - $as_echo "$ac_cs_version"; exit ;; + printf "%s\n" "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) - $as_echo "$ac_cs_config"; exit ;; + printf "%s\n" "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in - *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + *\'*) ac_optarg=`printf "%s\n" "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" @@ -26750,7 +32193,7 @@ do --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in - *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + *\'*) ac_optarg=`printf "%s\n" "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; @@ -26759,7 +32202,7 @@ do as_fn_error $? "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) - $as_echo "$ac_cs_usage"; exit ;; + printf "%s\n" "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; @@ -26787,7 +32230,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift - \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + \printf "%s\n" "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" @@ -26801,7 +32244,7 @@ exec 5>>config.log sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX - $as_echo "$ac_log" + printf "%s\n" "$ac_log" } >&5 _ACEOF @@ -26837,8 +32280,8 @@ done # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then - test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files - test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test ${CONFIG_FILES+y} || CONFIG_FILES=$config_files + test ${CONFIG_HEADERS+y} || CONFIG_HEADERS=$config_headers fi # Have a temporary directory for convenience. Make it in the build tree @@ -27174,7 +32617,7 @@ do esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac - case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + case $ac_f in *\'*) ac_f=`printf "%s\n" "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done @@ -27182,17 +32625,17 @@ do # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` - $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + printf "%s\n" "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" - { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 -$as_echo "$as_me: creating $ac_file" >&6;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +printf "%s\n" "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) - ac_sed_conf_input=`$as_echo "$configure_input" | + ac_sed_conf_input=`printf "%s\n" "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac @@ -27209,7 +32652,7 @@ $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$ac_file" | +printf "%s\n" X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q @@ -27233,9 +32676,9 @@ $as_echo X"$ac_file" | case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) - ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. - ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; @@ -27297,8 +32740,8 @@ ac_sed_dataroot=' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 -$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +printf "%s\n" "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' @@ -27342,9 +32785,9 @@ test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 -$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +printf "%s\n" "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" @@ -27360,20 +32803,20 @@ which seems to be undefined. Please make sure it is defined" >&2;} # if test x"$ac_file" != x-; then { - $as_echo "/* $configure_input */" \ + printf "%s\n" "/* $configure_input */" >&1 \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" } >"$ac_tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then - { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 -$as_echo "$as_me: $ac_file is unchanged" >&6;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 +printf "%s\n" "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$ac_tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else - $as_echo "/* $configure_input */" \ + printf "%s\n" "/* $configure_input */" >&1 \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi @@ -27419,52 +32862,58 @@ if test "$no_create" != yes; then $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 -$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: creating Modules/Setup.local" >&5 -$as_echo "$as_me: creating Modules/Setup.local" >&6;} +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating Modules/Setup.local" >&5 +printf "%s\n" "$as_me: creating Modules/Setup.local" >&6;} if test ! -f Modules/Setup.local then echo "# Edit this file for local setup changes" >Modules/Setup.local fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: creating Makefile" >&5 -$as_echo "$as_me: creating Makefile" >&6;} +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating Makefile" >&5 +printf "%s\n" "$as_me: creating Makefile" >&6;} $SHELL $srcdir/Modules/makesetup -c $srcdir/Modules/config.c.in \ -s Modules \ - Modules/Setup.local $MODULES_SETUP_STDLIB Modules/Setup.bootstrap $srcdir/Modules/Setup + Modules/Setup.local Modules/Setup.stdlib Modules/Setup.bootstrap $srcdir/Modules/Setup +if test $? -ne 0; then + as_fn_error $? "makesetup failed" "$LINENO" 5 +fi + mv config.c Modules if test -z "$PKG_CONFIG"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: pkg-config is missing. Some dependencies may not be detected correctly." >&5 -$as_echo "$as_me: WARNING: pkg-config is missing. Some dependencies may not be detected correctly." >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: pkg-config is missing. Some dependencies may not be detected correctly." >&5 +printf "%s\n" "$as_me: WARNING: pkg-config is missing. Some dependencies may not be detected correctly." >&2;} fi if test "$Py_OPT" = 'false' -a "$Py_DEBUG" != 'true'; then - { $as_echo "$as_me:${as_lineno-$LINENO}: + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: If you want a release build with all stable optimizations active (PGO, etc), please run ./configure --enable-optimizations " >&5 -$as_echo "$as_me: +printf "%s\n" "$as_me: If you want a release build with all stable optimizations active (PGO, etc), please run ./configure --enable-optimizations " >&6;} fi -if test "x$PY_SUPPORT_TIER" = x0; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: +if test "x$PY_SUPPORT_TIER" = x0 +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Platform \"$host\" with compiler \"$ac_cv_cc_name\" is not supported by the CPython core team, see https://peps.python.org/pep-0011/ for more information. " >&5 -$as_echo "$as_me: WARNING: +printf "%s\n" "$as_me: WARNING: Platform \"$host\" with compiler \"$ac_cv_cc_name\" is not supported by the CPython core team, see https://peps.python.org/pep-0011/ for more information. " >&2;} fi + diff --git a/configure.ac b/configure.ac index c62a565e..ba768aea 100644 --- a/configure.ac +++ b/configure.ac @@ -2,13 +2,20 @@ dnl *************************************************** dnl * Please run autoreconf -if to test your changes! * dnl *************************************************** dnl -dnl Python's configure.ac file requires autoconf 2.69 and autoconf-archive. +dnl Python's configure script requires autoconf 2.71, autoconf-archive, +dnl pkgconf's m4 macros. +dnl +dnl It is recommended to use a cpython_autoconf container to regenerate the +dnl configure script: +dnl +dnl podman run --rm --pull=always -v $(pwd):/src:Z quay.io/tiran/cpython_autoconf:271 +dnl docker run --rm --pull=always -v $(pwd):/src quay.io/tiran/cpython_autoconf:271 dnl # Set VERSION so we only need to edit in one place (i.e., here) -m4_define(PYTHON_VERSION, 3.11) +m4_define([PYTHON_VERSION], [3.12]) -AC_PREREQ([2.69]) +AC_PREREQ([2.71]) AC_INIT([python],[PYTHON_VERSION],[https://github.com/python/cpython/issues/]) @@ -73,7 +80,7 @@ dnl PY_CHECK_LIB(LIBRARY, FUNCTION, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND], [O dnl Like AC_CHECK_LIB() but does not modify LIBS AC_DEFUN([PY_CHECK_LIB], [AS_VAR_COPY([py_check_lib_save_LIBS], [LIBS])] -[AC_CHECK_LIB($1, $2, $3, $4, $5)] +[AC_CHECK_LIB([$1], [$2], [$3], [$4], [$5])] [AS_VAR_COPY([LIBS], [py_check_lib_save_LIBS])] ) @@ -91,13 +98,12 @@ AC_DEFUN([PY_CHECK_EMSCRIPTEN_PORT], [ AS_VAR_POPDEF([py_libs]) ]) -AC_SUBST(BASECPPFLAGS) +AC_SUBST([BASECPPFLAGS]) if test "$srcdir" != . -a "$srcdir" != "$(pwd)"; then # If we're building out-of-tree, we need to make sure the following # resources get picked up before their $srcdir counterparts. # Objects/ -> typeslots.inc # Include/ -> Python.h - # Python/ -> importlib.h # (A side effect of this is that these resources will automatically be # regenerated when building out-of-tree, regardless of whether or not # the $srcdir counterpart is up-to-date. This is an acceptable trade @@ -107,13 +113,13 @@ else BASECPPFLAGS="" fi -AC_SUBST(GITVERSION) -AC_SUBST(GITTAG) -AC_SUBST(GITBRANCH) +AC_SUBST([GITVERSION]) +AC_SUBST([GITTAG]) +AC_SUBST([GITBRANCH]) if test -e $srcdir/.git then -AC_CHECK_PROG(HAS_GIT, git, found, not-found) +AC_CHECK_PROG([HAS_GIT], [git], [found], [not-found]) else HAS_GIT=no-repository fi @@ -132,8 +138,8 @@ AC_CONFIG_SRCDIR([Include/object.h]) AC_CONFIG_HEADERS([pyconfig.h]) AC_CANONICAL_HOST -AC_SUBST(build) -AC_SUBST(host) +AC_SUBST([build]) +AC_SUBST([host]) AS_VAR_IF([cross_compiling], [maybe], [AC_MSG_ERROR([Cross compiling required --host=HOST-TUPLE and --build=ARCH])] @@ -142,8 +148,7 @@ AS_VAR_IF([cross_compiling], [maybe], # pybuilddir.txt will be created by --generate-posix-vars in the Makefile rm -f pybuilddir.txt -AC_ARG_WITH( - [build-python], +AC_ARG_WITH([build-python], [AS_HELP_STRING([--with-build-python=python]PYTHON_VERSION, [path to build python binary for cross compiling (default: _bootstrap_python or python]PYTHON_VERSION[)])], [ @@ -203,9 +208,9 @@ AC_SUBST([FREEZE_MODULE_DEPS]) AC_SUBST([PYTHON_FOR_BUILD_DEPS]) AC_CHECK_PROGS([PYTHON_FOR_REGEN], - [python$PACKAGE_VERSION python3.10 python3.9 python3.8 python3.7 python3.6 python3 python], + [python$PACKAGE_VERSION python3.12 python3.11 python3.10 python3 python], [python3]) -AC_SUBST(PYTHON_FOR_REGEN) +AC_SUBST([PYTHON_FOR_REGEN]) AC_MSG_CHECKING([Python for regen version]) if command -v "$PYTHON_FOR_REGEN" >/dev/null 2>&1; then @@ -244,38 +249,40 @@ grep -v 'define PACKAGE_' confdefs.h.new rm confdefs.h mv confdefs.h.new confdefs.h -AC_SUBST(VERSION) +AC_SUBST([VERSION]) VERSION=PYTHON_VERSION # Version number of Python's own shared library file. -AC_SUBST(SOVERSION) +AC_SUBST([SOVERSION]) SOVERSION=1.0 # The later definition of _XOPEN_SOURCE and _POSIX_C_SOURCE disables # certain features on NetBSD, so we need _NETBSD_SOURCE to re-enable # them. -AC_DEFINE(_NETBSD_SOURCE, 1, [Define on NetBSD to activate all library features]) +AC_DEFINE([_NETBSD_SOURCE], [1], + [Define on NetBSD to activate all library features]) # The later definition of _XOPEN_SOURCE and _POSIX_C_SOURCE disables # certain features on FreeBSD, so we need __BSD_VISIBLE to re-enable # them. -AC_DEFINE(__BSD_VISIBLE, 1, [Define on FreeBSD to activate all library features]) +AC_DEFINE([__BSD_VISIBLE], [1], + [Define on FreeBSD to activate all library features]) # The later definition of _XOPEN_SOURCE and _POSIX_C_SOURCE disables # certain features on Mac OS X, so we need _DARWIN_C_SOURCE to re-enable # them. -AC_DEFINE(_DARWIN_C_SOURCE, 1, [Define on Darwin to activate all library features]) +AC_DEFINE([_DARWIN_C_SOURCE], [1], + [Define on Darwin to activate all library features]) define_xopen_source=yes # Arguments passed to configure. -AC_SUBST(CONFIG_ARGS) +AC_SUBST([CONFIG_ARGS]) CONFIG_ARGS="$ac_configure_args" dnl Allow users to disable pkg-config or require pkg-config -AC_ARG_WITH( - [pkg-config], +AC_ARG_WITH([pkg-config], [AS_HELP_STRING([[--with-pkg-config=[yes|no|check]]], [use pkg-config to detect build options (default is check)])], [], @@ -304,7 +311,7 @@ if test "$with_pkg_config" = yes -a -z "$PKG_CONFIG"; then fi AC_MSG_CHECKING([for --enable-universalsdk]) -AC_ARG_ENABLE(universalsdk, +AC_ARG_ENABLE([universalsdk], AS_HELP_STRING([--enable-universalsdk@<:@=SDKDIR@:>@], [create a universal binary build. SDKDIR specifies which macOS SDK should be used to perform the build, @@ -345,13 +352,13 @@ AC_ARG_ENABLE(universalsdk, ]) if test -n "${UNIVERSALSDK}" then - AC_MSG_RESULT(${UNIVERSALSDK}) + AC_MSG_RESULT([${UNIVERSALSDK}]) else - AC_MSG_RESULT(no) + AC_MSG_RESULT([no]) fi -AC_SUBST(UNIVERSALSDK) +AC_SUBST([UNIVERSALSDK]) -AC_SUBST(ARCH_RUN_32BIT) +AC_SUBST([ARCH_RUN_32BIT]) ARCH_RUN_32BIT="" # For backward compatibility reasons we prefer to select '32-bit' if available, @@ -368,10 +375,10 @@ then fi fi -AC_SUBST(LIPO_32BIT_FLAGS) -AC_SUBST(LIPO_INTEL64_FLAGS) -AC_MSG_CHECKING(for --with-universal-archs) -AC_ARG_WITH(universal-archs, +AC_SUBST([LIPO_32BIT_FLAGS]) +AC_SUBST([LIPO_INTEL64_FLAGS]) +AC_MSG_CHECKING([for --with-universal-archs]) +AC_ARG_WITH([universal-archs], AS_HELP_STRING([--with-universal-archs=ARCH], [specify the kind of macOS universal binary that should be created. This option is only valid when --enable-universalsdk is set; options are: @@ -384,12 +391,12 @@ AC_ARG_WITH(universal-archs, []) if test -n "${UNIVERSALSDK}" then - AC_MSG_RESULT(${UNIVERSAL_ARCHS}) + AC_MSG_RESULT([${UNIVERSAL_ARCHS}]) else - AC_MSG_RESULT(no) + AC_MSG_RESULT([no]) fi -AC_ARG_WITH(framework-name, +AC_ARG_WITH([framework-name], AS_HELP_STRING([--with-framework-name=FRAMEWORK], [specify the name for the python framework on macOS only valid when --enable-framework is set. see Mac/README.rst @@ -404,7 +411,7 @@ AC_ARG_WITH(framework-name, PYTHONFRAMEWORKIDENTIFIER=org.python.python ]) dnl quadrigraphs "@<:@" and "@:>@" produce "[" and "]" in the output -AC_ARG_ENABLE(framework, +AC_ARG_ENABLE([framework], AS_HELP_STRING([--enable-framework@<:@=INSTALLDIR@:>@], [create a Python.framework rather than a traditional Unix install. optional INSTALLDIR specifies the installation path. see Mac/README.rst @@ -487,10 +494,10 @@ AC_ARG_ENABLE(framework, # Add files for Mac specific code to the list of output # files: - AC_CONFIG_FILES(Mac/Makefile) - AC_CONFIG_FILES(Mac/PythonLauncher/Makefile) - AC_CONFIG_FILES(Mac/Resources/framework/Info.plist) - AC_CONFIG_FILES(Mac/Resources/app/Info.plist) + AC_CONFIG_FILES([Mac/Makefile]) + AC_CONFIG_FILES([Mac/PythonLauncher/Makefile]) + AC_CONFIG_FILES([Mac/Resources/framework/Info.plist]) + AC_CONFIG_FILES([Mac/Resources/app/Info.plist]) esac ],[ PYTHONFRAMEWORK= @@ -510,24 +517,25 @@ AC_ARG_ENABLE(framework, enable_framework= ]) -AC_SUBST(PYTHONFRAMEWORK) -AC_SUBST(PYTHONFRAMEWORKIDENTIFIER) -AC_SUBST(PYTHONFRAMEWORKDIR) -AC_SUBST(PYTHONFRAMEWORKPREFIX) -AC_SUBST(PYTHONFRAMEWORKINSTALLDIR) -AC_SUBST(FRAMEWORKINSTALLFIRST) -AC_SUBST(FRAMEWORKINSTALLLAST) -AC_SUBST(FRAMEWORKALTINSTALLFIRST) -AC_SUBST(FRAMEWORKALTINSTALLLAST) -AC_SUBST(FRAMEWORKPYTHONW) -AC_SUBST(FRAMEWORKUNIXTOOLSPREFIX) -AC_SUBST(FRAMEWORKINSTALLAPPSPREFIX) +AC_SUBST([PYTHONFRAMEWORK]) +AC_SUBST([PYTHONFRAMEWORKIDENTIFIER]) +AC_SUBST([PYTHONFRAMEWORKDIR]) +AC_SUBST([PYTHONFRAMEWORKPREFIX]) +AC_SUBST([PYTHONFRAMEWORKINSTALLDIR]) +AC_SUBST([FRAMEWORKINSTALLFIRST]) +AC_SUBST([FRAMEWORKINSTALLLAST]) +AC_SUBST([FRAMEWORKALTINSTALLFIRST]) +AC_SUBST([FRAMEWORKALTINSTALLLAST]) +AC_SUBST([FRAMEWORKPYTHONW]) +AC_SUBST([FRAMEWORKUNIXTOOLSPREFIX]) +AC_SUBST([FRAMEWORKINSTALLAPPSPREFIX]) -AC_DEFINE_UNQUOTED(_PYTHONFRAMEWORK, "${PYTHONFRAMEWORK}", [framework name]) +AC_DEFINE_UNQUOTED([_PYTHONFRAMEWORK], ["${PYTHONFRAMEWORK}"], + [framework name]) # Set name for machine-dependent library files AC_ARG_VAR([MACHDEP], [name for machine-dependent library files]) -AC_MSG_CHECKING(MACHDEP) +AC_MSG_CHECKING([MACHDEP]) if test -z "$MACHDEP" then # avoid using uname for cross builds @@ -583,9 +591,9 @@ then '') MACHDEP="unknown";; esac fi -AC_MSG_RESULT("$MACHDEP") +AC_MSG_RESULT(["$MACHDEP"]) -AC_SUBST(_PYTHON_HOST_PLATFORM) +AC_SUBST([_PYTHON_HOST_PLATFORM]) if test "$cross_compiling" = yes; then case "$host" in *-*-linux*) @@ -635,13 +643,15 @@ case $ac_sys_system/$ac_sys_release in # OpenBSD undoes our definition of __BSD_VISIBLE if _XOPEN_SOURCE is # also defined. This can be overridden by defining _BSD_SOURCE # As this has a different meaning on Linux, only define it on OpenBSD - AC_DEFINE(_BSD_SOURCE, 1, [Define on OpenBSD to activate all library features]) + AC_DEFINE([_BSD_SOURCE], [1], + [Define on OpenBSD to activate all library features]) ;; OpenBSD/*) # OpenBSD undoes our definition of __BSD_VISIBLE if _XOPEN_SOURCE is # also defined. This can be overridden by defining _BSD_SOURCE # As this has a different meaning on Linux, only define it on OpenBSD - AC_DEFINE(_BSD_SOURCE, 1, [Define on OpenBSD to activate all library features]) + AC_DEFINE([_BSD_SOURCE], [1], + [Define on OpenBSD to activate all library features]) ;; # Defining _XOPEN_SOURCE on NetBSD version prior to the introduction of # _NETBSD_SOURCE disables certain features (eg. setgroups). Reported by @@ -697,17 +707,18 @@ esac if test $define_xopen_source = yes then # X/Open 7, incorporating POSIX.1-2008 - AC_DEFINE(_XOPEN_SOURCE, 700, - Define to the level of X/Open that your system supports) + AC_DEFINE([_XOPEN_SOURCE], [700], + [Define to the level of X/Open that your system supports]) # On Tru64 Unix 4.0F, defining _XOPEN_SOURCE also requires # definition of _XOPEN_SOURCE_EXTENDED and _POSIX_C_SOURCE, or else # several APIs are not declared. Since this is also needed in some # cases for HP-UX, we define it globally. - AC_DEFINE(_XOPEN_SOURCE_EXTENDED, 1, - Define to activate Unix95-and-earlier features) + AC_DEFINE([_XOPEN_SOURCE_EXTENDED], [1], + [Define to activate Unix95-and-earlier features]) - AC_DEFINE(_POSIX_C_SOURCE, 200809L, Define to activate features from IEEE Stds 1003.1-2008) + AC_DEFINE([_POSIX_C_SOURCE], [200809L], + [Define to activate features from IEEE Stds 1003.1-2008]) fi # On HP-UX mbstate_t requires _INCLUDE__STDC_A1_SOURCE @@ -720,14 +731,15 @@ esac if test $define_stdc_a1 = yes then - AC_DEFINE(_INCLUDE__STDC_A1_SOURCE, 1, Define to include mbstate_t for mbrtowc) + AC_DEFINE([_INCLUDE__STDC_A1_SOURCE], [1], + [Define to include mbstate_t for mbrtowc]) fi # Record the configure-time value of MACOSX_DEPLOYMENT_TARGET, # it may influence the way we can build extensions, so distutils # needs to check it -AC_SUBST(CONFIGURE_MACOSX_DEPLOYMENT_TARGET) -AC_SUBST(EXPORT_MACOSX_DEPLOYMENT_TARGET) +AC_SUBST([CONFIGURE_MACOSX_DEPLOYMENT_TARGET]) +AC_SUBST([EXPORT_MACOSX_DEPLOYMENT_TARGET]) CONFIGURE_MACOSX_DEPLOYMENT_TARGET= EXPORT_MACOSX_DEPLOYMENT_TARGET='#' @@ -765,6 +777,21 @@ AS_CASE([$host], if test "$ac_sys_system" = "Darwin" then + dnl look for SDKROOT + AC_CHECK_PROG([HAS_XCRUN], [xcrun], [yes], [missing]) + AC_MSG_CHECKING([macOS SDKROOT]) + if test -z "$SDKROOT"; then + dnl SDKROOT not set + if test "$HAS_XCRUN" = "yes"; then + dnl detect with Xcode + SDKROOT=$(xcrun --show-sdk-path) + else + dnl default to root + SDKROOT="/" + fi + fi + AC_MSG_RESULT([$SDKROOT]) + # Compiler selection on MacOSX is more complicated than # AC_PROG_CC can handle, see Mac/README for more # information @@ -859,39 +886,16 @@ rm -f conftest.c conftest.out # _POSIX_SOURCE, _POSIX_1_SOURCE, and more AC_USE_SYSTEM_EXTENSIONS -AC_SUBST(CXX) -AC_SUBST(MAINCC) -AC_MSG_CHECKING(for --with-cxx-main=) -AC_ARG_WITH(cxx_main, - AS_HELP_STRING([--with-cxx-main@<:@=COMPILER@:>@], - [compile main() and link Python executable with C++ compiler specified in COMPILER (default is $CXX)]), -[ - - case $withval in - no) with_cxx_main=no - MAINCC='$(CC)';; - yes) with_cxx_main=yes - MAINCC='$(CXX)';; - *) with_cxx_main=yes - MAINCC=$withval - if test -z "$CXX" - then - CXX=$withval - fi;; - esac], [ - with_cxx_main=no - MAINCC='$(CC)' -]) -AC_MSG_RESULT($with_cxx_main) +AC_SUBST([CXX]) preset_cxx="$CXX" if test -z "$CXX" then case "$CC" in - gcc) AC_PATH_TOOL(CXX, [g++], [g++], [notfound]) ;; - cc) AC_PATH_TOOL(CXX, [c++], [c++], [notfound]) ;; - clang|*/clang) AC_PATH_TOOL(CXX, [clang++], [clang++], [notfound]) ;; - icc|*/icc) AC_PATH_TOOL(CXX, [icpc], [icpc], [notfound]) ;; + gcc) AC_PATH_TOOL([CXX], [g++], [g++], [notfound]) ;; + cc) AC_PATH_TOOL([CXX], [c++], [c++], [notfound]) ;; + clang|*/clang) AC_PATH_TOOL([CXX], [clang++], [clang++], [notfound]) ;; + icc|*/icc) AC_PATH_TOOL([CXX], [icpc], [icpc], [notfound]) ;; esac if test "$CXX" = "notfound" then @@ -900,7 +904,7 @@ then fi if test -z "$CXX" then - AC_CHECK_TOOLS(CXX, $CCC c++ g++ gcc CC cxx cc++ cl, notfound) + AC_CHECK_TOOLS([CXX], [$CCC c++ g++ gcc CC cxx cc++ cl], [notfound]) if test "$CXX" = "notfound" then CXX="" @@ -968,6 +972,20 @@ cat > conftest.c <=6) && defined(_MIPSEL) @@ -1061,7 +1079,11 @@ cat > conftest.c < conftest.c <conftest.out 2>/dev/null; then if test -z "$ANDROID_API_LEVEL"; then AC_MSG_ERROR([Fatal: you must define __ANDROID_API__]) fi - AC_DEFINE_UNQUOTED(ANDROID_API_LEVEL, $ANDROID_API_LEVEL, [The Android API level.]) + AC_DEFINE_UNQUOTED([ANDROID_API_LEVEL], [$ANDROID_API_LEVEL], + [The Android API level.]) AC_MSG_CHECKING([for the Android arm ABI]) AC_MSG_RESULT([$_arm_arch]) @@ -1253,7 +1276,7 @@ AC_ARG_ENABLE([wasm-pthreads], [ AS_CASE([$ac_sys_system], [Emscripten], [], - [WASI], [AC_MSG_ERROR([WASI threading is not implemented yet.])], + [WASI], [], [AC_MSG_ERROR([--enable-wasm-pthreads only applies to Emscripten and WASI])] ) ], [ @@ -1282,18 +1305,18 @@ AC_MSG_RESULT([$EXEEXT]) # Test whether we're running on a non-case-sensitive system, in which # case we give a warning if no ext is given -AC_SUBST(BUILDEXEEXT) -AC_MSG_CHECKING(for case-insensitive build directory) +AC_SUBST([BUILDEXEEXT]) +AC_MSG_CHECKING([for case-insensitive build directory]) if test ! -d CaseSensitiveTestDir; then mkdir CaseSensitiveTestDir fi if test -d casesensitivetestdir && test -z "$EXEEXT" then - AC_MSG_RESULT(yes) + AC_MSG_RESULT([yes]) BUILDEXEEXT=.exe else - AC_MSG_RESULT(no) + AC_MSG_RESULT([no]) BUILDEXEEXT=$EXEEXT fi rmdir CaseSensitiveTestDir @@ -1305,13 +1328,13 @@ hp*|HP*) esac;; esac -AC_SUBST(LIBRARY) -AC_MSG_CHECKING(LIBRARY) +AC_SUBST([LIBRARY]) +AC_MSG_CHECKING([LIBRARY]) if test -z "$LIBRARY" then LIBRARY='libpython$(VERSION)$(ABIFLAGS).a' fi -AC_MSG_RESULT($LIBRARY) +AC_MSG_RESULT([$LIBRARY]) # LDLIBRARY is the name of the library to link against (as opposed to the # name of the library into which to insert object files). BLDLIBRARY is also @@ -1329,14 +1352,14 @@ AC_MSG_RESULT($LIBRARY) # # LDVERSION is the shared library version number, normally the Python version # with the ABI build flags appended. -AC_SUBST(LDLIBRARY) -AC_SUBST(DLLLIBRARY) -AC_SUBST(BLDLIBRARY) -AC_SUBST(PY3LIBRARY) -AC_SUBST(LDLIBRARYDIR) -AC_SUBST(INSTSONAME) -AC_SUBST(RUNSHARED) -AC_SUBST(LDVERSION) +AC_SUBST([LDLIBRARY]) +AC_SUBST([DLLLIBRARY]) +AC_SUBST([BLDLIBRARY]) +AC_SUBST([PY3LIBRARY]) +AC_SUBST([LDLIBRARYDIR]) +AC_SUBST([INSTSONAME]) +AC_SUBST([RUNSHARED]) +AC_SUBST([LDVERSION]) LDLIBRARY="$LIBRARY" BLDLIBRARY='$(LDLIBRARY)' INSTSONAME='$(LDLIBRARY)' @@ -1349,11 +1372,11 @@ LDVERSION="$VERSION" # If CXX is set, and if it is needed to link a main function that was # compiled with CXX, LINKCC is CXX instead. Always using CXX is undesirable: # python might then depend on the C++ runtime -AC_SUBST(LINKCC) -AC_MSG_CHECKING(LINKCC) +AC_SUBST([LINKCC]) +AC_MSG_CHECKING([LINKCC]) if test -z "$LINKCC" then - LINKCC='$(PURIFY) $(MAINCC)' + LINKCC='$(PURIFY) $(CC)' case $ac_sys_system in QNX*) # qcc must be used because the other compilers do not @@ -1361,30 +1384,30 @@ then LINKCC=qcc;; esac fi -AC_MSG_RESULT($LINKCC) +AC_MSG_RESULT([$LINKCC]) # EXPORTSYMS holds the list of exported symbols for AIX. # EXPORTSFROM holds the module name exporting symbols on AIX. EXPORTSYMS= EXPORTSFROM= -AC_SUBST(EXPORTSYMS) -AC_SUBST(EXPORTSFROM) -AC_MSG_CHECKING(EXPORTSYMS) +AC_SUBST([EXPORTSYMS]) +AC_SUBST([EXPORTSFROM]) +AC_MSG_CHECKING([EXPORTSYMS]) case $ac_sys_system in AIX*) EXPORTSYMS="Modules/python.exp" EXPORTSFROM=. # the main executable ;; esac -AC_MSG_RESULT($EXPORTSYMS) +AC_MSG_RESULT([$EXPORTSYMS]) # GNULD is set to "yes" if the GNU linker is used. If this goes wrong # make sure we default having it set to "no": this is used by # distutils.unixccompiler to know if it should add --enable-new-dtags # to linker command lines, and failing to detect GNU ld simply results # in the same behaviour as before. -AC_SUBST(GNULD) -AC_MSG_CHECKING(for GNU ld) +AC_SUBST([GNULD]) +AC_MSG_CHECKING([for GNU ld]) ac_prog=ld if test "$GCC" = yes; then ac_prog=`$CC -print-prog-name=ld` @@ -1395,10 +1418,10 @@ case `"$ac_prog" -V 2>&1 < /dev/null` in *) GNULD=no;; esac -AC_MSG_RESULT($GNULD) +AC_MSG_RESULT([$GNULD]) -AC_MSG_CHECKING(for --enable-shared) -AC_ARG_ENABLE(shared, +AC_MSG_CHECKING([for --enable-shared]) +AC_ARG_ENABLE([shared], AS_HELP_STRING([--enable-shared], [enable building a shared Python library (default is no)])) if test -z "$enable_shared" @@ -1410,27 +1433,27 @@ then enable_shared="no";; esac fi -AC_MSG_RESULT($enable_shared) +AC_MSG_RESULT([$enable_shared]) # --with-static-libpython STATIC_LIBPYTHON=1 -AC_MSG_CHECKING(for --with-static-libpython) -AC_ARG_WITH(static-libpython, +AC_MSG_CHECKING([for --with-static-libpython]) +AC_ARG_WITH([static-libpython], AS_HELP_STRING([--without-static-libpython], [do not build libpythonMAJOR.MINOR.a and do not install python.o (default is yes)]), [ if test "$withval" = no then - AC_MSG_RESULT(no); + AC_MSG_RESULT([no]); STATIC_LIBPYTHON=0 else - AC_MSG_RESULT(yes); + AC_MSG_RESULT([yes]); fi], -[AC_MSG_RESULT(yes)]) -AC_SUBST(STATIC_LIBPYTHON) +[AC_MSG_RESULT([yes])]) +AC_SUBST([STATIC_LIBPYTHON]) -AC_MSG_CHECKING(for --enable-profiling) -AC_ARG_ENABLE(profiling, +AC_MSG_CHECKING([for --enable-profiling]) +AC_ARG_ENABLE([profiling], AS_HELP_STRING([--enable-profiling], [enable C-level code profiling with gprof (default is no)])) if test "x$enable_profiling" = xyes; then ac_save_cc="$CC" @@ -1442,14 +1465,14 @@ if test "x$enable_profiling" = xyes; then else enable_profiling=no fi -AC_MSG_RESULT($enable_profiling) +AC_MSG_RESULT([$enable_profiling]) if test "x$enable_profiling" = xyes; then BASECFLAGS="-pg $BASECFLAGS" LDFLAGS="-pg $LDFLAGS" fi -AC_MSG_CHECKING(LDLIBRARY) +AC_MSG_CHECKING([LDLIBRARY]) # MacOSX framework builds need more magic. LDLIBRARY is the dynamic # library that we build, but we do not want to link against it (we @@ -1469,7 +1492,8 @@ fi # Other platforms follow if test $enable_shared = "yes"; then PY_ENABLE_SHARED=1 - AC_DEFINE(Py_ENABLE_SHARED, 1, [Defined if Python is built as a shared library.]) + AC_DEFINE([Py_ENABLE_SHARED], [1], + [Defined if Python is built as a shared library.]) case $ac_sys_system in CYGWIN*) LDLIBRARY='libpython$(LDVERSION).dll.a' @@ -1572,7 +1596,7 @@ then dnl TODO: support other WASI runtimes dnl wasmtime starts the proces with "/" as CWD. For OOT builds add the dnl directory containing _sysconfigdata to PYTHONPATH. - [WASI/*], [HOSTRUNNER='wasmtime run --env PYTHONPATH=/$(shell realpath --relative-to $(abs_srcdir) $(abs_builddir))/$(shell cat pybuilddir.txt) --mapdir /::$(srcdir) --'], + [WASI/*], [HOSTRUNNER='wasmtime run --env PYTHONPATH=/$(shell realpath --relative-to $(abs_srcdir) $(abs_builddir))/$(shell cat pybuilddir.txt):/Lib --mapdir /::$(srcdir) --'], [HOSTRUNNER=''] ) fi @@ -1585,7 +1609,7 @@ if test -n "$HOSTRUNNER"; then PYTHON_FOR_BUILD="_PYTHON_HOSTRUNNER='$HOSTRUNNER' $PYTHON_FOR_BUILD" fi -AC_MSG_RESULT($LDLIBRARY) +AC_MSG_RESULT([$LDLIBRARY]) # LIBRARY_DEPS, LINK_PYTHON_OBJS and LINK_PYTHON_DEPS variable AS_CASE([$ac_sys_system/$ac_sys_emscripten_target], @@ -1610,32 +1634,21 @@ else # Link Python program to object files LINK_PYTHON_OBJS='$(LIBRARY_OBJS)' fi -AC_SUBST(LIBRARY_DEPS) -AC_SUBST(LINK_PYTHON_DEPS) -AC_SUBST(LINK_PYTHON_OBJS) +AC_SUBST([LIBRARY_DEPS]) +AC_SUBST([LINK_PYTHON_DEPS]) +AC_SUBST([LINK_PYTHON_OBJS]) # ar program -AC_SUBST(AR) -AC_CHECK_TOOLS(AR, ar aal, ar) +AC_SUBST([AR]) +AC_CHECK_TOOLS([AR], [ar aal], [ar]) # tweak ARFLAGS only if the user didn't set it on the command line -AC_SUBST(ARFLAGS) +AC_SUBST([ARFLAGS]) if test -z "$ARFLAGS" then ARFLAGS="rcs" fi -AC_CHECK_TOOLS([READELF], [readelf], [:]) -if test "$cross_compiling" = yes; then - case "$READELF" in - readelf|:) - AC_MSG_ERROR([readelf for the host is required for cross builds]) - ;; - esac -fi -AC_SUBST(READELF) - - case $MACHDEP in hp*|HP*) # install -d does not work on HP-UX @@ -1648,7 +1661,7 @@ AC_PROG_INSTALL AC_PROG_MKDIR_P # Not every filesystem supports hard links -AC_SUBST(LN) +AC_SUBST([LN]) if test -z "$LN" ; then case $ac_sys_system in CYGWIN*) LN="ln -s";; @@ -1657,38 +1670,38 @@ if test -z "$LN" ; then fi # For calculating the .so ABI tag. -AC_SUBST(ABIFLAGS) +AC_SUBST([ABIFLAGS]) ABIFLAGS="" # Check for --with-pydebug -AC_MSG_CHECKING(for --with-pydebug) -AC_ARG_WITH(pydebug, - AS_HELP_STRING([--with-pydebug], [build with Py_DEBUG defined (default is no)]), +AC_MSG_CHECKING([for --with-pydebug]) +AC_ARG_WITH([pydebug], + [AS_HELP_STRING([--with-pydebug], [build with Py_DEBUG defined (default is no)]) ], [ if test "$withval" != no then - AC_DEFINE(Py_DEBUG, 1, + AC_DEFINE([Py_DEBUG], [1], [Define if you want to build an interpreter with many run-time checks.]) - AC_MSG_RESULT(yes); + AC_MSG_RESULT([yes]); Py_DEBUG='true' ABIFLAGS="${ABIFLAGS}d" -else AC_MSG_RESULT(no); Py_DEBUG='false' +else AC_MSG_RESULT([no]); Py_DEBUG='false' fi], -[AC_MSG_RESULT(no)]) +[AC_MSG_RESULT([no])]) # Check for --with-trace-refs # --with-trace-refs -AC_MSG_CHECKING(for --with-trace-refs) -AC_ARG_WITH(trace-refs, - AS_HELP_STRING( - [--with-trace-refs], - [enable tracing references for debugging purpose (default is no)]),, - with_trace_refs=no) -AC_MSG_RESULT($with_trace_refs) +AC_MSG_CHECKING([for --with-trace-refs]) +AC_ARG_WITH([trace-refs], + [AS_HELP_STRING([--with-trace-refs], [enable tracing references for debugging purpose (default is no)])], + [], [with_trace_refs=no] +) +AC_MSG_RESULT([$with_trace_refs]) if test "$with_trace_refs" = "yes" then - AC_DEFINE(Py_TRACE_REFS, 1, [Define if you want to enable tracing references for debugging purpose]) + AC_DEFINE([Py_TRACE_REFS], [1], + [Define if you want to enable tracing references for debugging purpose]) fi @@ -1697,8 +1710,9 @@ AC_MSG_CHECKING([for --enable-pystats]) AC_ARG_ENABLE([pystats], [AS_HELP_STRING( [--enable-pystats], - [enable internal statistics gathering (default is no)])],, - [enable_pystats=no] + [enable internal statistics gathering (default is no)] + )], + [], [enable_pystats=no] ) AC_MSG_RESULT([$enable_pystats]) @@ -1709,8 +1723,8 @@ AS_VAR_IF([enable_pystats], [yes], [ # Check for --with-assertions. # This allows enabling assertions without Py_DEBUG. assertions='false' -AC_MSG_CHECKING(for --with-assertions) -AC_ARG_WITH(assertions, +AC_MSG_CHECKING([for --with-assertions]) +AC_ARG_WITH([assertions], AS_HELP_STRING([--with-assertions],[build with C assertions enabled (default is no)]), [ if test "$withval" != no @@ -1719,32 +1733,32 @@ then fi], []) if test "$assertions" = 'true'; then - AC_MSG_RESULT(yes) + AC_MSG_RESULT([yes]) elif test "$Py_DEBUG" = 'true'; then assertions='true' - AC_MSG_RESULT(implied by --with-pydebug) + AC_MSG_RESULT([implied by --with-pydebug]) else - AC_MSG_RESULT(no) + AC_MSG_RESULT([no]) fi # Enable optimization flags -AC_SUBST(DEF_MAKE_ALL_RULE) -AC_SUBST(DEF_MAKE_RULE) +AC_SUBST([DEF_MAKE_ALL_RULE]) +AC_SUBST([DEF_MAKE_RULE]) Py_OPT='false' -AC_MSG_CHECKING(for --enable-optimizations) -AC_ARG_ENABLE(optimizations, AS_HELP_STRING( +AC_MSG_CHECKING([for --enable-optimizations]) +AC_ARG_ENABLE([optimizations], AS_HELP_STRING( [--enable-optimizations], [enable expensive, stable optimizations (PGO, etc.) (default is no)]), [ if test "$enableval" != no then Py_OPT='true' - AC_MSG_RESULT(yes); + AC_MSG_RESULT([yes]); else Py_OPT='false' - AC_MSG_RESULT(no); + AC_MSG_RESULT([no]); fi], -[AC_MSG_RESULT(no)]) +[AC_MSG_RESULT([no])]) if test "$Py_OPT" = 'true' ; then # Intentionally not forcing Py_LTO='true' here. Too many toolchains do not @@ -1774,13 +1788,13 @@ else DEF_MAKE_RULE="all" fi -AC_ARG_VAR(PROFILE_TASK, Python args for PGO generation task) -AC_MSG_CHECKING(PROFILE_TASK) +AC_ARG_VAR([PROFILE_TASK], [Python args for PGO generation task]) +AC_MSG_CHECKING([PROFILE_TASK]) if test -z "$PROFILE_TASK" then PROFILE_TASK='-m test --pgo --timeout=$(TESTTIMEOUT)' fi -AC_MSG_RESULT($PROFILE_TASK) +AC_MSG_RESULT([$PROFILE_TASK]) # Make llvm-related checks work on systems where llvm tools are not installed with their # normal names in the default $PATH (ie: Ubuntu). They exist under the @@ -1803,28 +1817,29 @@ then fi # Enable LTO flags -AC_MSG_CHECKING(for --with-lto) -AC_ARG_WITH(lto, AS_HELP_STRING([--with-lto=@<:@full|thin|no|yes@:>@], [enable Link-Time-Optimization in any build (default is no)]), +AC_MSG_CHECKING([for --with-lto]) +AC_ARG_WITH([lto], + [AS_HELP_STRING([--with-lto=@<:@full|thin|no|yes@:>@], [enable Link-Time-Optimization in any build (default is no)])], [ case "$withval" in full) Py_LTO='true' Py_LTO_POLICY='full' - AC_MSG_RESULT(yes) + AC_MSG_RESULT([yes]) ;; thin) Py_LTO='true' Py_LTO_POLICY='thin' - AC_MSG_RESULT(yes) + AC_MSG_RESULT([yes]) ;; yes) Py_LTO='true' Py_LTO_POLICY='default' - AC_MSG_RESULT(yes) + AC_MSG_RESULT([yes]) ;; no) Py_LTO='false' - AC_MSG_RESULT(no) + AC_MSG_RESULT([no]) ;; *) Py_LTO='false' @@ -1832,7 +1847,7 @@ case "$withval" in ;; esac ], -[AC_MSG_RESULT(no)]) +[AC_MSG_RESULT([no])]) if test "$Py_LTO" = 'true' ; then case $CC in *clang*) @@ -1840,9 +1855,9 @@ if test "$Py_LTO" = 'true' ; then dnl Clang linker requires -flto in order to link objects with LTO information. dnl Thin LTO is faster and works for object files with full LTO information, too. AX_CHECK_COMPILE_FLAG([-flto=thin],[LDFLAGS_NOLTO="-flto=thin"],[LDFLAGS_NOLTO="-flto"]) - AC_SUBST(LLVM_AR) - AC_PATH_TOOL(LLVM_AR, llvm-ar, '', ${llvm_path}) - AC_SUBST(LLVM_AR_FOUND) + AC_SUBST([LLVM_AR]) + AC_PATH_TOOL([LLVM_AR], [llvm-ar], [''], [${llvm_path}]) + AC_SUBST([LLVM_AR_FOUND]) if test -n "${LLVM_AR}" -a -x "${LLVM_AR}" then LLVM_AR_FOUND="found" @@ -1873,17 +1888,25 @@ if test "$Py_LTO" = 'true' ; then # Any changes made here should be reflected in the GCC+Darwin case below if test $Py_LTO_POLICY = default then - LTOFLAGS="-flto -Wl,-export_dynamic" - LTOCFLAGS="-flto" + # Check that ThinLTO is accepted. + AX_CHECK_COMPILE_FLAG([-flto=thin],[ + LTOFLAGS="-flto=thin -Wl,-export_dynamic -Wl,-object_path_lto,\"\$@\".lto" + LTOCFLAGS="-flto=thin" + ],[ + LTOFLAGS="-flto -Wl,-export_dynamic -Wl,-object_path_lto,\"\$@\".lto" + LTOCFLAGS="-flto" + ] + ) else - LTOFLAGS="-flto=${Py_LTO_POLICY} -Wl,-export_dynamic" + LTOFLAGS="-flto=${Py_LTO_POLICY} -Wl,-export_dynamic -Wl,-object_path_lto,\"\$@\".lto" LTOCFLAGS="-flto=${Py_LTO_POLICY}" fi ;; *) if test $Py_LTO_POLICY = default then - LTOFLAGS="-flto" + # Check that ThinLTO is accepted + AX_CHECK_COMPILE_FLAG([-flto=thin],[LTOFLAGS="-flto=thin"],[LTOFLAGS="-flto"]) else LTOFLAGS="-flto=${Py_LTO_POLICY}" fi @@ -1906,7 +1929,7 @@ if test "$Py_LTO" = 'true' ; then LDFLAGS_NOLTO="-fno-lto" case $ac_sys_system in Darwin*) - LTOFLAGS="-flto -Wl,-export_dynamic" + LTOFLAGS="-flto -Wl,-export_dynamic -Wl,-object_path_lto,\"\$@\".lto" LTOCFLAGS="-flto" ;; *) @@ -1928,14 +1951,14 @@ if test "$Py_LTO" = 'true' ; then fi # Enable PGO flags. -AC_SUBST(PGO_PROF_GEN_FLAG) -AC_SUBST(PGO_PROF_USE_FLAG) -AC_SUBST(LLVM_PROF_MERGER) -AC_SUBST(LLVM_PROF_FILE) -AC_SUBST(LLVM_PROF_ERR) -AC_SUBST(LLVM_PROFDATA) -AC_PATH_TOOL(LLVM_PROFDATA, llvm-profdata, '', ${llvm_path}) -AC_SUBST(LLVM_PROF_FOUND) +AC_SUBST([PGO_PROF_GEN_FLAG]) +AC_SUBST([PGO_PROF_USE_FLAG]) +AC_SUBST([LLVM_PROF_MERGER]) +AC_SUBST([LLVM_PROF_FILE]) +AC_SUBST([LLVM_PROF_ERR]) +AC_SUBST([LLVM_PROFDATA]) +AC_PATH_TOOL([LLVM_PROFDATA], [llvm-profdata], [''], [${llvm_path}]) +AC_SUBST([LLVM_PROF_FOUND]) if test -n "${LLVM_PROFDATA}" -a -x "${LLVM_PROFDATA}" then LLVM_PROF_FOUND="found" @@ -2003,6 +2026,109 @@ case $CC in ;; esac +# BOLT optimization. Always configured after PGO since it always runs after PGO. +Py_BOLT='false' +AC_MSG_CHECKING([for --enable-bolt]) +AC_ARG_ENABLE([bolt], [AS_HELP_STRING( + [--enable-bolt], + [enable usage of the llvm-bolt post-link optimizer (default is no)])], +[ +if test "$enableval" != no +then + Py_BOLT='true' + AC_MSG_RESULT([yes]); +else + Py_BOLT='false' + AC_MSG_RESULT([no]); +fi], +[AC_MSG_RESULT([no])]) + +AC_SUBST([PREBOLT_RULE]) +if test "$Py_BOLT" = 'true' ; then + PREBOLT_RULE="${DEF_MAKE_ALL_RULE}" + DEF_MAKE_ALL_RULE="bolt-opt" + DEF_MAKE_RULE="build_all" + + # -fno-reorder-blocks-and-partition is required for bolt to work. + # Possibly GCC only. + AX_CHECK_COMPILE_FLAG([-fno-reorder-blocks-and-partition],[ + CFLAGS_NODIST="$CFLAGS_NODIST -fno-reorder-blocks-and-partition" + ]) + + # These flags are required for bolt to work: + LDFLAGS_NODIST="$LDFLAGS_NODIST -Wl,--emit-relocs" + + # These flags are required to get good performance from bolt: + CFLAGS_NODIST="$CFLAGS_NODIST -fno-pie" + # We want to add these no-pie flags to linking executables but not shared libraries: + LINKCC="$LINKCC -fno-pie -no-pie" + AC_SUBST([LLVM_BOLT]) + AC_PATH_TOOL([LLVM_BOLT], [llvm-bolt], [''], [${llvm_path}]) + if test -n "${LLVM_BOLT}" -a -x "${LLVM_BOLT}" + then + AC_MSG_RESULT(["Found llvm-bolt"]) + else + AC_MSG_ERROR([llvm-bolt is required for a --enable-bolt build but could not be found.]) + fi + + AC_SUBST([MERGE_FDATA]) + AC_PATH_TOOL([MERGE_FDATA], [merge-fdata], [''], [${llvm_path}]) + if test -n "${MERGE_FDATA}" -a -x "${MERGE_FDATA}" + then + AC_MSG_RESULT(["Found merge-fdata"]) + else + AC_MSG_ERROR([merge-fdata is required for a --enable-bolt build but could not be found.]) + fi +fi + +dnl Enable BOLT of libpython if built. +AC_SUBST([BOLT_BINARIES]) +BOLT_BINARIES='$(BUILDPYTHON)' +AS_VAR_IF([enable_shared], [yes], [ + BOLT_BINARIES="${BOLT_BINARIES} \$(INSTSONAME)" +]) + +AC_ARG_VAR( + [BOLT_INSTRUMENT_FLAGS], + [Arguments to llvm-bolt when instrumenting binaries] +) +AC_MSG_CHECKING([BOLT_INSTRUMENT_FLAGS]) +if test -z "${BOLT_INSTRUMENT_FLAGS}" +then + BOLT_INSTRUMENT_FLAGS= +fi +AC_MSG_RESULT([$BOLT_INSTRUMENT_FLAGS]) + +AC_ARG_VAR( + [BOLT_APPLY_FLAGS], + [Arguments to llvm-bolt when creating a BOLT optimized binary] +) +AC_MSG_CHECKING([BOLT_APPLY_FLAGS]) +if test -z "${BOLT_APPLY_FLAGS}" +then + AS_VAR_SET( + [BOLT_APPLY_FLAGS], + [m4_normalize(" + -update-debug-sections + -reorder-blocks=ext-tsp + -reorder-functions=hfsort+ + -split-functions + -icf=1 + -inline-all + -split-eh + -reorder-functions-use-hot-size + -peepholes=none + -jump-tables=aggressive + -inline-ap + -indirect-call-promotion=all + -dyno-stats + -use-gnu-stack + -frame-opt=hot + ")] + ) +fi +AC_MSG_RESULT([$BOLT_APPLY_FLAGS]) + # XXX Shouldn't the code above that fiddles with BASECFLAGS and OPT be # merged with this chunk of code? @@ -2029,6 +2155,45 @@ case $CC in fi esac +dnl Historically, some of our code assumed that signed integer overflow +dnl is defined behaviour via twos-complement. +dnl Set STRICT_OVERFLOW_CFLAGS and NO_STRICT_OVERFLOW_CFLAGS depending on compiler support. +dnl Pass the latter to modules that depend on such behaviour. +_SAVE_VAR([CFLAGS]) +CFLAGS="-fstrict-overflow -fno-strict-overflow" +AC_CACHE_CHECK([if $CC supports -fstrict-overflow and -fno-strict-overflow], + [ac_cv_cc_supports_fstrict_overflow], + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([[]], [[]])], + [ac_cv_cc_supports_fstrict_overflow=yes], + [ac_cv_cc_supports_fstrict_overflow=no] + ) +) +_RESTORE_VAR([CFLAGS]) + +AS_VAR_IF([ac_cv_cc_supports_fstrict_overflow], [yes], + [STRICT_OVERFLOW_CFLAGS="-fstrict-overflow" + NO_STRICT_OVERFLOW_CFLAGS="-fno-strict-overflow"], + [STRICT_OVERFLOW_CFLAGS="" + NO_STRICT_OVERFLOW_CFLAGS=""]) + +AC_MSG_CHECKING([for --with-strict-overflow]) +AC_ARG_WITH([strict-overflow], + AS_HELP_STRING( + [--with-strict-overflow], + [if 'yes', add -fstrict-overflow to CFLAGS, else add -fno-strict-overflow (default is no)] + ), + [ + AS_VAR_IF( + [ac_cv_cc_supports_fstrict_overflow], [no], + [AC_MSG_WARN([--with-strict-overflow=yes requires a compiler that supports -fstrict-overflow])], + [] + ) + ], + [with_strict_overflow=no] +) +AC_MSG_RESULT([$with_strict_overflow]) + # Check if CC supports -Og optimization level _SAVE_VAR([CFLAGS]) CFLAGS="-Og" @@ -2053,21 +2218,14 @@ AS_VAR_IF([ac_cv_cc_supports_og], [yes], # tweak OPT based on compiler and platform, only if the user didn't set # it on the command line -AC_SUBST(OPT) -AC_SUBST(CFLAGS_ALIASING) +AC_SUBST([OPT]) +AC_SUBST([CFLAGS_ALIASING]) if test "${OPT-unset}" = "unset" then case $GCC in yes) - # For gcc 4.x we need to use -fwrapv so lets check if its supported - if "$CC" -v --help 2>/dev/null |grep -- -fwrapv > /dev/null; then - WRAP="-fwrapv" - fi - if test -n "${cc_is_clang}" then - # Clang also needs -fwrapv - WRAP="-fwrapv" # bpo-30104: disable strict aliasing to compile correctly dtoa.c, # see Makefile.pre.in for more information CFLAGS_ALIASING="-fno-strict-aliasing" @@ -2078,7 +2236,7 @@ then if test "$Py_DEBUG" = 'true' ; then OPT="-g $PYDEBUG_CFLAGS -Wall" else - OPT="-g $WRAP -O3 -Wall" + OPT="-g -O3 -Wall" fi ;; *) @@ -2155,6 +2313,18 @@ AS_CASE([$ac_sys_system], LIBS="$LIBS -lwasi-emulated-signal -lwasi-emulated-getpid -lwasi-emulated-process-clocks" echo "#define _WASI_EMULATED_SIGNAL 1" >> confdefs.h + AS_VAR_IF([enable_wasm_pthreads], [yes], [ + # Note: update CFLAGS because ac_compile/ac_link needs this too. + # without this, configure fails to find pthread_create, sem_init, + # etc because they are only available in the sysroot for + # wasm32-wasi-threads. + AS_VAR_APPEND([CFLAGS], [" -target wasm32-wasi-threads -pthread"]) + AS_VAR_APPEND([CFLAGS_NODIST], [" -target wasm32-wasi-threads -pthread"]) + AS_VAR_APPEND([LDFLAGS_NODIST], [" -target wasm32-wasi-threads -pthread"]) + AS_VAR_APPEND([LDFLAGS_NODIST], [" -Wl,--import-memory"]) + AS_VAR_APPEND([LDFLAGS_NODIST], [" -Wl,--max-memory=10485760"]) + ]) + dnl increase initial memory and stack size, move stack first dnl https://github.com/WebAssembly/wasi-libc/issues/233 AS_VAR_APPEND([LDFLAGS_NODIST], [" -z stack-size=524288 -Wl,--stack-first -Wl,--initial-memory=10485760"]) @@ -2167,21 +2337,21 @@ AS_CASE([$enable_wasm_dynamic_linking], [missing], [] ) -AC_SUBST(BASECFLAGS) -AC_SUBST(CFLAGS_NODIST) -AC_SUBST(LDFLAGS_NODIST) -AC_SUBST(LDFLAGS_NOLTO) +AC_SUBST([BASECFLAGS]) +AC_SUBST([CFLAGS_NODIST]) +AC_SUBST([LDFLAGS_NODIST]) +AC_SUBST([LDFLAGS_NOLTO]) AC_SUBST([WASM_ASSETS_DIR]) AC_SUBST([WASM_STDLIB]) # The -arch flags for universal builds on macOS UNIVERSAL_ARCH_FLAGS= -AC_SUBST(UNIVERSAL_ARCH_FLAGS) +AC_SUBST([UNIVERSAL_ARCH_FLAGS]) dnl PY_CHECK_CC_WARNING(ENABLE, WARNING, [MSG]) AC_DEFUN([PY_CHECK_CC_WARNING], [ AS_VAR_PUSHDEF([py_var], [ac_cv_$1_]m4_normalize($2)[_warning]) - AC_CACHE_CHECK(m4_ifblank([$3], [if we can $1 $CC $2 warning], [$3]), [py_var], [ + AC_CACHE_CHECK([m4_ifblank([$3], [if we can $1 $CC $2 warning], [$3])], [py_var], [ AS_VAR_COPY([py_cflags], [CFLAGS]) AS_VAR_APPEND([CFLAGS], ["-W$2 -Werror"]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], @@ -2193,6 +2363,10 @@ AC_DEFUN([PY_CHECK_CC_WARNING], [ ]) # tweak BASECFLAGS based on compiler and platform +AS_VAR_IF([with_strict_overflow], [yes], + [BASECFLAGS="$BASECFLAGS $STRICT_OVERFLOW_CFLAGS"], + [BASECFLAGS="$BASECFLAGS $NO_STRICT_OVERFLOW_CFLAGS"]) + case $GCC in yes) CFLAGS_NODIST="$CFLAGS_NODIST -std=c11" @@ -2246,6 +2420,10 @@ yes) AS_VAR_IF([ac_cv_disable_unused_parameter_warning], [yes], [CFLAGS_NODIST="$CFLAGS_NODIST -Wno-unused-parameter"]) + PY_CHECK_CC_WARNING([disable], [int-conversion]) + AS_VAR_IF([ac_cv_disable_int_conversion], [yes], + [CFLAGS_NODIST="$CFLAGS_NODIST -Wno-int-conversion"]) + PY_CHECK_CC_WARNING([disable], [missing-field-initializers]) AS_VAR_IF([ac_cv_disable_missing_field_initializers_warning], [yes], [CFLAGS_NODIST="$CFLAGS_NODIST -Wno-missing-field-initializers"]) @@ -2327,7 +2505,7 @@ yes) # used to be here, but non-Apple gcc doesn't accept them. if test "${CC}" = gcc then - AC_MSG_CHECKING(which compiler should be used) + AC_MSG_CHECKING([which compiler should be used]) case "${UNIVERSALSDK}" in */MacOSX10.4u.sdk) # Build using 10.4 SDK, force usage of gcc when the @@ -2337,7 +2515,7 @@ yes) CPP=cpp-4.0 ;; esac - AC_MSG_RESULT($CC) + AC_MSG_RESULT([$CC]) fi LIPO_INTEL64_FLAGS="" @@ -2414,7 +2592,7 @@ yes) # below to pick either 10.3, 10.4, or 10.5 as the target. # 4. If we are running on OS X 10.2 or earlier, good luck! - AC_MSG_CHECKING(which MACOSX_DEPLOYMENT_TARGET to use) + AC_MSG_CHECKING([which MACOSX_DEPLOYMENT_TARGET to use]) cur_target_major=`sw_vers -productVersion | \ sed 's/\([[0-9]]*\)\.\([[0-9]]*\).*/\1/'` cur_target_minor=`sw_vers -productVersion | \ @@ -2451,13 +2629,13 @@ yes) MACOSX_DEPLOYMENT_TARGET="$CONFIGURE_MACOSX_DEPLOYMENT_TARGET" export MACOSX_DEPLOYMENT_TARGET EXPORT_MACOSX_DEPLOYMENT_TARGET='' - AC_MSG_RESULT($MACOSX_DEPLOYMENT_TARGET) + AC_MSG_RESULT([$MACOSX_DEPLOYMENT_TARGET]) - AC_MSG_CHECKING(if specified universal architectures work) - AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[printf("%d", 42);]])], - [AC_MSG_RESULT(yes)], - [AC_MSG_RESULT(no) - AC_MSG_ERROR(check config.log and use the '--with-universal-archs' option) + AC_MSG_CHECKING([if specified universal architectures work]) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[@%:@include ]], [[printf("%d", 42);]])], + [AC_MSG_RESULT([yes])], + [AC_MSG_RESULT([no]) + AC_MSG_ERROR([check config.log and use the '--with-universal-archs' option]) ]) # end of Darwin* tests @@ -2478,6 +2656,9 @@ yes) esac case "$CC" in +*mpicc*) + CFLAGS_NODIST="$CFLAGS_NODIST" + ;; *icc*) # ICC needs -fp-model strict or floats behave badly CFLAGS_NODIST="$CFLAGS_NODIST -fp-model strict" @@ -2611,11 +2792,10 @@ fi # If we have set a CC compiler flag for thread support then # check if it works for CXX, too. -ac_cv_cxx_thread=no if test ! -z "$CXX" then -AC_MSG_CHECKING(whether $CXX also accepts flags for thread support) -ac_save_cxx="$CXX" +AC_CACHE_CHECK([whether $CXX also accepts flags for thread support], [ac_cv_cxx_thread], +[ac_save_cxx="$CXX" if test "$ac_cv_kpthread" = "yes" then @@ -2629,6 +2809,8 @@ elif test "$ac_cv_pthread" = "yes" then CXX="$CXX -pthread" ac_cv_cxx_thread=yes +else + ac_cv_cxx_thread=no fi if test $ac_cv_cxx_thread = yes @@ -2644,9 +2826,10 @@ then fi rm -fr conftest* fi -AC_MSG_RESULT($ac_cv_cxx_thread) +CXX="$ac_save_cxx"]) +else + ac_cv_cxx_thread=no fi -CXX="$ac_save_cxx" dnl # check for ANSI or K&R ("traditional") preprocessor dnl AC_MSG_CHECKING(for C preprocessor type) @@ -2659,14 +2842,15 @@ dnl AC_MSG_RESULT($cpp_type) dnl autoconf 2.71 deprecates STDC_HEADERS, keep for backwards compatibility dnl assume C99 compilers provide ANSI C headers -AC_DEFINE(STDC_HEADERS, 1, [Define to 1 if you have the ANSI C header files.]) +AC_DEFINE([STDC_HEADERS], [1], + [Define to 1 if you have the ANSI C header files.]) # checks for header files AC_CHECK_HEADERS([ \ alloca.h asm/types.h bluetooth.h conio.h crypt.h direct.h dlfcn.h endian.h errno.h fcntl.h grp.h \ - ieeefp.h io.h langinfo.h libintl.h libutil.h linux/auxvec.h sys/auxv.h linux/memfd.h \ + ieeefp.h io.h langinfo.h libintl.h libutil.h linux/auxvec.h sys/auxv.h linux/fs.h linux/limits.h linux/memfd.h \ linux/random.h linux/soundcard.h \ - linux/tipc.h linux/wait.h netdb.h netinet/in.h netpacket/packet.h poll.h process.h pthread.h pty.h \ + linux/tipc.h linux/wait.h netdb.h net/ethernet.h netinet/in.h netpacket/packet.h poll.h process.h pthread.h pty.h \ sched.h setjmp.h shadow.h signal.h spawn.h stropts.h sys/audioio.h sys/bsdtty.h sys/devpoll.h \ sys/endian.h sys/epoll.h sys/event.h sys/eventfd.h sys/file.h sys/ioctl.h sys/kern_control.h \ sys/loadavg.h sys/lock.h sys/memfd.h sys/mkdev.h sys/mman.h sys/modem.h sys/param.h sys/poll.h \ @@ -2682,7 +2866,7 @@ AC_HEADER_MAJOR # http://permalink.gmane.org/gmane.linux.bluez.kernel/22294 SAVE_CFLAGS=$CFLAGS CFLAGS="-std=c99 $CFLAGS" -AC_CHECK_HEADERS(bluetooth/bluetooth.h) +AC_CHECK_HEADERS([bluetooth/bluetooth.h]) CFLAGS=$SAVE_CFLAGS # On Darwin (OS X) net/if.h requires sys/socket.h to be imported first. @@ -2696,7 +2880,7 @@ AC_CHECK_HEADERS([net/if.h], [], [], ]) # On Linux, netlink.h requires asm/types.h -AC_CHECK_HEADERS(linux/netlink.h,,,[ +AC_CHECK_HEADERS([linux/netlink.h], [], [], [ #ifdef HAVE_ASM_TYPES_H #include #endif @@ -2706,7 +2890,7 @@ AC_CHECK_HEADERS(linux/netlink.h,,,[ ]) # On Linux, qrtr.h requires asm/types.h -AC_CHECK_HEADERS(linux/qrtr.h,,,[ +AC_CHECK_HEADERS([linux/qrtr.h], [], [], [ #ifdef HAVE_ASM_TYPES_H #include #endif @@ -2715,7 +2899,7 @@ AC_CHECK_HEADERS(linux/qrtr.h,,,[ #endif ]) -AC_CHECK_HEADERS(linux/vm_sockets.h,,,[ +AC_CHECK_HEADERS([linux/vm_sockets.h], [], [], [ #ifdef HAVE_SYS_SOCKET_H #include #endif @@ -2723,7 +2907,9 @@ AC_CHECK_HEADERS(linux/vm_sockets.h,,,[ # On Linux, can.h, can/bcm.h, can/j1939.h, can/raw.h require sys/socket.h # On NetBSD, netcan/can.h requires sys/socket.h -AC_CHECK_HEADERS(linux/can.h linux/can/bcm.h linux/can/j1939.h linux/can/raw.h netcan/can.h,,,[ +AC_CHECK_HEADERS( +[linux/can.h linux/can/bcm.h linux/can/j1939.h linux/can/raw.h netcan/can.h], +[], [], [ #ifdef HAVE_SYS_SOCKET_H #include #endif @@ -2735,7 +2921,8 @@ AC_CACHE_CHECK([for clock_t in time.h], [ac_cv_clock_t_time_h], [ ]) dnl checks for "no" AS_VAR_IF([ac_cv_clock_t_time_h], [no], [ - AC_DEFINE(clock_t, long, [Define to 'long' if doesn't define.]) + AC_DEFINE([clock_t], [long], + [Define to 'long' if doesn't define.]) ]) AC_CACHE_CHECK([for makedev], [ac_cv_func_makedev], [ @@ -2753,7 +2940,8 @@ AC_LINK_IFELSE([AC_LANG_PROGRAM([[ ]) AS_VAR_IF([ac_cv_func_makedev], [yes], [ - AC_DEFINE(HAVE_MAKEDEV, 1, [Define this if you have the makedev macro.]) + AC_DEFINE([HAVE_MAKEDEV], [1], + [Define this if you have the makedev macro.]) ]) # byte swapping @@ -2770,7 +2958,8 @@ AC_LINK_IFELSE([AC_LANG_PROGRAM([[ ]) AS_VAR_IF([ac_cv_func_le64toh], [yes], [ - AC_DEFINE(HAVE_HTOLE64, 1, [Define this if you have le64toh()]) + AC_DEFINE([HAVE_HTOLE64], [1], + [Define this if you have le64toh()]) ]) use_lfs=yes @@ -2784,13 +2973,13 @@ if test "$use_lfs" = "yes"; then # These may affect some typedefs case $ac_sys_system/$ac_sys_release in AIX*) - AC_DEFINE(_LARGE_FILES, 1, + AC_DEFINE([_LARGE_FILES], [1], [This must be defined on AIX systems to enable large file support.]) ;; esac -AC_DEFINE(_LARGEFILE_SOURCE, 1, +AC_DEFINE([_LARGEFILE_SOURCE], [1], [This must be defined on some systems to enable large file support.]) -AC_DEFINE(_FILE_OFFSET_BITS, 64, +AC_DEFINE([_FILE_OFFSET_BITS], [64], [This must be set to 64 on some systems to enable large file support.]) fi @@ -2809,39 +2998,42 @@ AC_DEFINE_UNQUOTED([RETSIGTYPE],[void],[assume C89 semantics that RETSIGTYPE is AC_TYPE_SIZE_T AC_TYPE_UID_T -AC_CHECK_TYPE(ssize_t, - AC_DEFINE(HAVE_SSIZE_T, 1, [Define if your compiler provides ssize_t]),,) -AC_CHECK_TYPE(__uint128_t, - AC_DEFINE(HAVE_GCC_UINT128_T, 1, [Define if your compiler provides __uint128_t]),,) +AC_CHECK_TYPE([ssize_t], + AC_DEFINE([HAVE_SSIZE_T], [1], + [Define if your compiler provides ssize_t]), [], []) +AC_CHECK_TYPE([__uint128_t], + AC_DEFINE([HAVE_GCC_UINT128_T], [1], + [Define if your compiler provides __uint128_t]), [], []) # Sizes and alignments of various common basic types # ANSI C requires sizeof(char) == 1, so no need to check it -AC_CHECK_SIZEOF(int, 4) -AC_CHECK_SIZEOF(long, 4) -AC_CHECK_ALIGNOF(long) -AC_CHECK_SIZEOF(long long, 8) -AC_CHECK_SIZEOF(void *, 4) -AC_CHECK_SIZEOF(short, 2) -AC_CHECK_SIZEOF(float, 4) -AC_CHECK_SIZEOF(double, 8) -AC_CHECK_SIZEOF(fpos_t, 4) -AC_CHECK_SIZEOF(size_t, 4) -AC_CHECK_ALIGNOF(size_t) -AC_CHECK_SIZEOF(pid_t, 4) -AC_CHECK_SIZEOF(uintptr_t) +AC_CHECK_SIZEOF([int], [4]) +AC_CHECK_SIZEOF([long], [4]) +AC_CHECK_ALIGNOF([long]) +AC_CHECK_SIZEOF([long long], [8]) +AC_CHECK_SIZEOF([void *], [4]) +AC_CHECK_SIZEOF([short], [2]) +AC_CHECK_SIZEOF([float], [4]) +AC_CHECK_SIZEOF([double], [8]) +AC_CHECK_SIZEOF([fpos_t], [4]) +AC_CHECK_SIZEOF([size_t], [4]) +AC_CHECK_ALIGNOF([size_t]) +AC_CHECK_SIZEOF([pid_t], [4]) +AC_CHECK_SIZEOF([uintptr_t]) +AC_CHECK_ALIGNOF([max_align_t]) AC_TYPE_LONG_DOUBLE -AC_CHECK_SIZEOF(long double, 16) +AC_CHECK_SIZEOF([long double], [16]) -AC_CHECK_SIZEOF(_Bool, 1) +AC_CHECK_SIZEOF([_Bool], [1]) -AC_CHECK_SIZEOF(off_t, [], [ +AC_CHECK_SIZEOF([off_t], [], [ #ifdef HAVE_SYS_TYPES_H #include #endif ]) -AC_MSG_CHECKING(whether to enable large file support) +AC_MSG_CHECKING([whether to enable large file support]) if test "$ac_cv_sizeof_off_t" -gt "$ac_cv_sizeof_long" -a \ "$ac_cv_sizeof_long_long" -ge "$ac_cv_sizeof_off_t"; then have_largefile_support="yes" @@ -2853,17 +3045,17 @@ AS_CASE([$ac_sys_system], [Emscripten], [have_largefile_support="no"] ) AS_VAR_IF([have_largefile_support], [yes], [ - AC_DEFINE(HAVE_LARGEFILE_SUPPORT, 1, + AC_DEFINE([HAVE_LARGEFILE_SUPPORT], [1], [Defined to enable large file support when an off_t is bigger than a long and long long is at least as big as an off_t. You may need to add some flags for configuration and compilation to enable this mode. (For Solaris and Linux, the necessary defines are already defined.)]) - AC_MSG_RESULT(yes) + AC_MSG_RESULT([yes]) ], [ - AC_MSG_RESULT(no) + AC_MSG_RESULT([no]) ]) -AC_CHECK_SIZEOF(time_t, [], [ +AC_CHECK_SIZEOF([time_t], [], [ #ifdef HAVE_SYS_TYPES_H #include #endif @@ -2884,11 +3076,11 @@ fi AC_CACHE_CHECK([for pthread_t], [ac_cv_have_pthread_t], [ AC_COMPILE_IFELSE([ - AC_LANG_PROGRAM([[#include ]], [[pthread_t x; x = *(pthread_t*)0;]]) + AC_LANG_PROGRAM([[@%:@include ]], [[pthread_t x; x = *(pthread_t*)0;]]) ], [ac_cv_have_pthread_t=yes], [ac_cv_have_pthread_t=no]) ]) AS_VAR_IF([ac_cv_have_pthread_t], [yes], [ - AC_CHECK_SIZEOF(pthread_t, [], [ + AC_CHECK_SIZEOF([pthread_t], [], [ #ifdef HAVE_PTHREAD_H #include #endif @@ -2897,11 +3089,11 @@ AS_VAR_IF([ac_cv_have_pthread_t], [yes], [ # Issue #25658: POSIX hasn't defined that pthread_key_t is compatible with int. # This checking will be unnecessary after removing deprecated TLS API. -AC_CHECK_SIZEOF(pthread_key_t, [], [[#include ]]) +AC_CHECK_SIZEOF([pthread_key_t], [], [[@%:@include ]]) AC_CACHE_CHECK([whether pthread_key_t is compatible with int], [ac_cv_pthread_key_t_is_arithmetic_type], [ if test "$ac_cv_sizeof_pthread_key_t" -eq "$ac_cv_sizeof_int" ; then AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM([[#include ]], [[pthread_key_t k; k * 1;]])], + [AC_LANG_PROGRAM([[@%:@include ]], [[pthread_key_t k; k * 1;]])], [ac_cv_pthread_key_t_is_arithmetic_type=yes], [ac_cv_pthread_key_t_is_arithmetic_type=no] ) @@ -2910,139 +3102,97 @@ else fi ]) AS_VAR_IF([ac_cv_pthread_key_t_is_arithmetic_type], [yes], [ - AC_DEFINE(PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT, 1, + AC_DEFINE([PTHREAD_KEY_T_IS_COMPATIBLE_WITH_INT], [1], [Define if pthread_key_t is compatible with int.]) ]) CC="$ac_save_cc" -AC_SUBST(OTHER_LIBTOOL_OPT) -case $ac_sys_system/$ac_sys_release in - Darwin/@<:@01567@:>@\..*) - OTHER_LIBTOOL_OPT="-prebind -seg1addr 0x10000000" - ;; - Darwin/*) - OTHER_LIBTOOL_OPT="" - ;; -esac - - -AC_SUBST(LIBTOOL_CRUFT) -case $ac_sys_system/$ac_sys_release in - Darwin/@<:@01567@:>@\..*) - LIBTOOL_CRUFT="-framework System -lcc_dynamic" - if test "${enable_universalsdk}"; then - : - else - LIBTOOL_CRUFT="${LIBTOOL_CRUFT} -arch_only `/usr/bin/arch`" - fi - LIBTOOL_CRUFT=$LIBTOOL_CRUFT' -install_name $(PYTHONFRAMEWORKINSTALLDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK)' - LIBTOOL_CRUFT=$LIBTOOL_CRUFT' -compatibility_version $(VERSION) -current_version $(VERSION)';; - Darwin/*) - gcc_version=`gcc -dumpversion` - if test ${gcc_version} '<' 4.0 - then - LIBTOOL_CRUFT="-lcc_dynamic" - else - LIBTOOL_CRUFT="" - fi - AC_RUN_IFELSE([AC_LANG_SOURCE([[ - #include - int main(int argc, char*argv[]) - { - if (sizeof(long) == 4) { - return 0; - } else { - return 1; - } - } - ]])],[ac_osx_32bit=yes],[ac_osx_32bit=no],[ac_osx_32bit=yes]) - - if test "${ac_osx_32bit}" = "yes"; then - case `/usr/bin/arch` in - i386) - MACOSX_DEFAULT_ARCH="i386" - ;; - ppc) - MACOSX_DEFAULT_ARCH="ppc" - ;; - *) - AC_MSG_ERROR([Unexpected output of 'arch' on macOS]) - ;; - esac - else - case `/usr/bin/arch` in - i386) - MACOSX_DEFAULT_ARCH="x86_64" - ;; - ppc) - MACOSX_DEFAULT_ARCH="ppc64" - ;; - arm64) - MACOSX_DEFAULT_ARCH="arm64" - ;; - *) - AC_MSG_ERROR([Unexpected output of 'arch' on macOS]) - ;; - esac - - fi - - LIBTOOL_CRUFT=$LIBTOOL_CRUFT" -lSystem -lSystemStubs -arch_only ${MACOSX_DEFAULT_ARCH}" - LIBTOOL_CRUFT=$LIBTOOL_CRUFT' -install_name $(PYTHONFRAMEWORKINSTALLDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK)' - LIBTOOL_CRUFT=$LIBTOOL_CRUFT' -compatibility_version $(VERSION) -current_version $(VERSION)';; -esac -AC_MSG_CHECKING(for --enable-framework) +AC_MSG_CHECKING([for --enable-framework]) if test "$enable_framework" then BASECFLAGS="$BASECFLAGS -fno-common -dynamic" # -F. is needed to allow linking to the framework while # in the build location. - AC_DEFINE(WITH_NEXT_FRAMEWORK, 1, + AC_DEFINE([WITH_NEXT_FRAMEWORK], [1], [Define if you want to produce an OpenStep/Rhapsody framework (shared library plus accessory files).]) - AC_MSG_RESULT(yes) + AC_MSG_RESULT([yes]) if test $enable_shared = "yes" then AC_MSG_ERROR([Specifying both --enable-shared and --enable-framework is not supported, use only --enable-framework instead]) fi else - AC_MSG_RESULT(no) + AC_MSG_RESULT([no]) fi -AC_MSG_CHECKING(for dyld) +# Check for --with-dsymutil +AC_SUBST([DSYMUTIL]) +AC_SUBST([DSYMUTIL_PATH]) +DSYMUTIL= +DSYMUTIL_PATH= +AC_MSG_CHECKING([for --with-dsymutil]) +AC_ARG_WITH( + [dsymutil], + [AS_HELP_STRING( + [--with-dsymutil], + [link debug information into final executable with dsymutil in macOS (default is no)] + )], +[ +if test "$withval" != no +then + if test "$MACHDEP" != "darwin"; then + AC_MSG_ERROR([dsymutil debug linking is only available in macOS.]) + fi + AC_MSG_RESULT([yes]); + DSYMUTIL='true' +else AC_MSG_RESULT([no]); DSYMUTIL= +fi], +[AC_MSG_RESULT([no])]) + +if test "$DSYMUTIL"; then + AC_PATH_PROG([DSYMUTIL_PATH], [dsymutil], [not found]) + if test "$DSYMUTIL_PATH" = "not found"; then + AC_MSG_ERROR([dsymutil command not found on \$PATH]) + fi +fi + +AC_MSG_CHECKING([for dyld]) case $ac_sys_system/$ac_sys_release in Darwin/*) - AC_DEFINE(WITH_DYLD, 1, + AC_DEFINE([WITH_DYLD], [1], [Define if you want to use the new-style (Openstep, Rhapsody, MacOS) dynamic linker (dyld) instead of the old-style (NextStep) dynamic linker (rld). Dyld is necessary to support frameworks.]) - AC_MSG_RESULT(always on for Darwin) + AC_MSG_RESULT([always on for Darwin]) ;; *) - AC_MSG_RESULT(no) + AC_MSG_RESULT([no]) ;; esac -AC_MSG_CHECKING(for --with-address-sanitizer) -AC_ARG_WITH(address_sanitizer, +AC_MSG_CHECKING([for --with-address-sanitizer]) +AC_ARG_WITH([address_sanitizer], AS_HELP_STRING([--with-address-sanitizer], [enable AddressSanitizer memory error detector, 'asan' (default is no)]), [ -AC_MSG_RESULT($withval) +AC_MSG_RESULT([$withval]) BASECFLAGS="-fsanitize=address -fno-omit-frame-pointer $BASECFLAGS" LDFLAGS="-fsanitize=address $LDFLAGS" # ASan works by controlling memory allocation, our own malloc interferes. with_pymalloc="no" ], -[AC_MSG_RESULT(no)]) +[AC_MSG_RESULT([no])]) -AC_MSG_CHECKING(for --with-memory-sanitizer) -AC_ARG_WITH(memory_sanitizer, - AS_HELP_STRING([--with-memory-sanitizer], - [enable MemorySanitizer allocation error detector, 'msan' (default is no)]), +AC_MSG_CHECKING([for --with-memory-sanitizer]) +AC_ARG_WITH( + [memory_sanitizer], + [AS_HELP_STRING( + [--with-memory-sanitizer], + [enable MemorySanitizer allocation error detector, 'msan' (default is no)] + )], [ -AC_MSG_RESULT($withval) +AC_MSG_RESULT([$withval]) AX_CHECK_COMPILE_FLAG([-fsanitize=memory],[ BASECFLAGS="-fsanitize=memory -fsanitize-memory-track-origins=2 -fno-omit-frame-pointer $BASECFLAGS" LDFLAGS="-fsanitize=memory -fsanitize-memory-track-origins=2 $LDFLAGS" @@ -3050,34 +3200,37 @@ LDFLAGS="-fsanitize=memory -fsanitize-memory-track-origins=2 $LDFLAGS" # MSan works by controlling memory allocation, our own malloc interferes. with_pymalloc="no" ], -[AC_MSG_RESULT(no)]) +[AC_MSG_RESULT([no])]) -AC_MSG_CHECKING(for --with-undefined-behavior-sanitizer) -AC_ARG_WITH(undefined_behavior_sanitizer, - AS_HELP_STRING([--with-undefined-behavior-sanitizer], - [enable UndefinedBehaviorSanitizer undefined behaviour detector, 'ubsan' (default is no)]), +AC_MSG_CHECKING([for --with-undefined-behavior-sanitizer]) +AC_ARG_WITH( + [undefined_behavior_sanitizer], + [AS_HELP_STRING( + [--with-undefined-behavior-sanitizer], + [enable UndefinedBehaviorSanitizer undefined behaviour detector, 'ubsan' (default is no)] + )], [ -AC_MSG_RESULT($withval) +AC_MSG_RESULT([$withval]) BASECFLAGS="-fsanitize=undefined $BASECFLAGS" LDFLAGS="-fsanitize=undefined $LDFLAGS" with_ubsan="yes" ], [ -AC_MSG_RESULT(no) +AC_MSG_RESULT([no]) with_ubsan="no" ]) # Set info about shared libraries. -AC_SUBST(SHLIB_SUFFIX) -AC_SUBST(LDSHARED) -AC_SUBST(LDCXXSHARED) -AC_SUBST(BLDSHARED) -AC_SUBST(CCSHARED) -AC_SUBST(LINKFORSHARED) +AC_SUBST([SHLIB_SUFFIX]) +AC_SUBST([LDSHARED]) +AC_SUBST([LDCXXSHARED]) +AC_SUBST([BLDSHARED]) +AC_SUBST([CCSHARED]) +AC_SUBST([LINKFORSHARED]) # SHLIB_SUFFIX is the extension of shared libraries `(including the dot!) # -- usually .so, .sl on HP-UX, .dll on Cygwin -AC_MSG_CHECKING(the extension of shared libraries) +AC_MSG_CHECKING([the extension of shared libraries]) if test -z "$SHLIB_SUFFIX"; then case $ac_sys_system in hp*|HP*) @@ -3090,13 +3243,13 @@ if test -z "$SHLIB_SUFFIX"; then *) SHLIB_SUFFIX=.so;; esac fi -AC_MSG_RESULT($SHLIB_SUFFIX) +AC_MSG_RESULT([$SHLIB_SUFFIX]) # LDSHARED is the ld *command* used to create shared library # -- "cc -G" on SunOS 5.x. # (Shared libraries in this instance are shared modules to be loaded into # Python, as opposed to building Python itself as a shared library.) -AC_MSG_CHECKING(LDSHARED) +AC_MSG_CHECKING([LDSHARED]) if test -z "$LDSHARED" then case $ac_sys_system/$ac_sys_release in @@ -3228,7 +3381,7 @@ if test "$enable_wasm_dynamic_linking" = "yes" -a "$ac_sys_system" = "Emscripten BLDSHARED='$(CC) -shared -sSIDE_MODULE=1' fi -AC_MSG_RESULT($LDSHARED) +AC_MSG_RESULT([$LDSHARED]) LDCXXSHARED=${LDCXXSHARED-$LDSHARED} AC_MSG_CHECKING([BLDSHARED flags]) @@ -3237,7 +3390,7 @@ AC_MSG_RESULT([$BLDSHARED]) # CCSHARED are the C *flags* used to create objects to go into a shared # library (module) -- this is only needed for a few systems -AC_MSG_CHECKING(CCSHARED) +AC_MSG_CHECKING([CCSHARED]) if test -z "$CCSHARED" then case $ac_sys_system/$ac_sys_release in @@ -3273,10 +3426,10 @@ then CCSHARED="-fpic -D__SO_PICABILINUX__ -ftls-model=global-dynamic" esac fi -AC_MSG_RESULT($CCSHARED) +AC_MSG_RESULT([$CCSHARED]) # LINKFORSHARED are the flags passed to the $(CC) command that links # the python executable -- this is only needed for a few systems -AC_MSG_CHECKING(LINKFORSHARED) +AC_MSG_CHECKING([LINKFORSHARED]) if test -z "$LINKFORSHARED" then case $ac_sys_system/$ac_sys_release in @@ -3302,8 +3455,8 @@ then LINKFORSHARED="-Wl,-stack_size,$stack_size $LINKFORSHARED" - AC_DEFINE_UNQUOTED(THREAD_STACK_SIZE, - 0x$stack_size, + AC_DEFINE_UNQUOTED([THREAD_STACK_SIZE], + [0x$stack_size], [Custom thread stack size depending on chosen sanitizer runtimes.]) if test "$enable_framework" @@ -3342,11 +3495,11 @@ then LINKFORSHARED='-Wl,-export-dynamic';; esac fi -AC_MSG_RESULT($LINKFORSHARED) +AC_MSG_RESULT([$LINKFORSHARED]) -AC_SUBST(CFLAGSFORSHARED) -AC_MSG_CHECKING(CFLAGSFORSHARED) +AC_SUBST([CFLAGSFORSHARED]) +AC_MSG_CHECKING([CFLAGSFORSHARED]) if test ! "$LIBRARY" = "$LDLIBRARY" then case $ac_sys_system in @@ -3364,7 +3517,7 @@ AS_VAR_IF([enable_wasm_dynamic_linking], [yes], [ CFLAGSFORSHARED='$(CCSHARED)' ]) -AC_MSG_RESULT($CFLAGSFORSHARED) +AC_MSG_RESULT([$CFLAGSFORSHARED]) # SHLIBS are libraries (except -lc and -lm) to link to the python shared # library (with --enable-shared). @@ -3374,19 +3527,39 @@ AC_MSG_RESULT($CFLAGSFORSHARED) # to LIBS. This, in turn, means that applications linking the shared libpython # don't need to link LIBS explicitly. The default should be only changed # on systems where this approach causes problems. -AC_SUBST(SHLIBS) -AC_MSG_CHECKING(SHLIBS) +AC_SUBST([SHLIBS]) +AC_MSG_CHECKING([SHLIBS]) case "$ac_sys_system" in *) SHLIBS='$(LIBS)';; esac -AC_MSG_RESULT($SHLIBS) +AC_MSG_RESULT([$SHLIBS]) + +dnl perf trampoline is Linux specific and requires an arch-specific +dnl trampoline in asssembly. +AC_MSG_CHECKING([perf trampoline]) +AS_CASE([$PLATFORM_TRIPLET], + [x86_64-linux-gnu], [perf_trampoline=yes], + [aarch64-linux-gnu], [perf_trampoline=yes], + [perf_trampoline=no] +) +AC_MSG_RESULT([$perf_trampoline]) +AS_VAR_IF([perf_trampoline], [yes], [ + AC_DEFINE([PY_HAVE_PERF_TRAMPOLINE], [1], [Define to 1 if you have the perf trampoline.]) + PERF_TRAMPOLINE_OBJ=Python/asm_trampoline.o + + dnl perf needs frame pointers for unwinding, include compiler option in debug builds + AS_VAR_IF([Py_DEBUG], [true], [ + AS_VAR_APPEND([BASECFLAGS], [" -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer"]) + ]) +]) +AC_SUBST([PERF_TRAMPOLINE_OBJ]) # checks for libraries -AC_CHECK_LIB(sendfile, sendfile) -AC_CHECK_LIB(dl, dlopen) # Dynamic linking for SunOS/Solaris and SYSV -AC_CHECK_LIB(dld, shl_load) # Dynamic linking for HP-UX +AC_CHECK_LIB([sendfile], [sendfile]) +AC_CHECK_LIB([dl], [dlopen]) # Dynamic linking for SunOS/Solaris and SYSV +AC_CHECK_LIB([dld], [shl_load]) # Dynamic linking for HP-UX dnl check for uuid dependencies @@ -3399,9 +3572,9 @@ dnl AIX provides support for RFC4122 (uuid) in libc.a starting with AIX 6.1 dnl (anno 2007). FreeBSD and OpenBSD provides support in libc as well. dnl Little-endian FreeBSD, OpenBSD and NetBSD needs encoding into an octet dnl stream in big-endian byte-order -AC_CHECK_HEADERS([uuid.h], [ - AC_CHECK_FUNCS([uuid_create uuid_enc_be], [ - have_uuid=yes +AC_CHECK_HEADERS([uuid.h], + [AC_CHECK_FUNCS([uuid_create uuid_enc_be], + [have_uuid=yes LIBUUID_CFLAGS=${LIBUUID_CFLAGS-""} LIBUUID_LIBS=${LIBUUID_LIBS-""} ]) @@ -3409,8 +3582,8 @@ AC_CHECK_HEADERS([uuid.h], [ AS_VAR_IF([have_uuid], [missing], [ PKG_CHECK_MODULES( - [LIBUUID], [uuid >= 2.20], [ - dnl linux-util's libuuid has uuid_generate_time_safe() since v2.20 (2011) + [LIBUUID], [uuid >= 2.20], + [dnl linux-util's libuuid has uuid_generate_time_safe() since v2.20 (2011) dnl and provides . have_uuid=yes AC_DEFINE([HAVE_UUID_H], [1]) @@ -3421,11 +3594,9 @@ AS_VAR_IF([have_uuid], [missing], [ LDFLAGS="$LDFLAGS $LIBUUID_LIBS" AC_CHECK_HEADERS([uuid/uuid.h], [ PY_CHECK_LIB([uuid], [uuid_generate_time], [have_uuid=yes]) - PY_CHECK_LIB([uuid], [uuid_generate_time_safe], [ - have_uuid=yes - AC_DEFINE([HAVE_UUID_GENERATE_TIME_SAFE], [1]) - ]) - ]) + PY_CHECK_LIB([uuid], [uuid_generate_time_safe], + [have_uuid=yes + AC_DEFINE([HAVE_UUID_GENERATE_TIME_SAFE], [1]) ]) ]) AS_VAR_IF([have_uuid], [yes], [ LIBUUID_CFLAGS=${LIBUUID_CFLAGS-""} LIBUUID_LIBS=${LIBUUID_LIBS-"-luuid"} @@ -3451,37 +3622,37 @@ AS_VAR_IF([have_uuid], [missing], [have_uuid=no]) # 'Real Time' functions on Solaris # posix4 on Solaris 2.6 # pthread (first!) on Linux -AC_SEARCH_LIBS(sem_init, pthread rt posix4) +AC_SEARCH_LIBS([sem_init], [pthread rt posix4]) # check if we need libintl for locale functions -AC_CHECK_LIB(intl, textdomain, - [AC_DEFINE(WITH_LIBINTL, 1, +AC_CHECK_LIB([intl], [textdomain], + [AC_DEFINE([WITH_LIBINTL], [1], [Define to 1 if libintl is needed for locale functions.]) LIBS="-lintl $LIBS"]) # checks for system dependent C++ extensions support case "$ac_sys_system" in - AIX*) AC_MSG_CHECKING(for genuine AIX C++ extensions support) + AIX*) AC_MSG_CHECKING([for genuine AIX C++ extensions support]) AC_LINK_IFELSE([ - AC_LANG_PROGRAM([[#include ]], + AC_LANG_PROGRAM([[@%:@include ]], [[loadAndInit("", 0, "")]]) ],[ - AC_DEFINE(AIX_GENUINE_CPLUSPLUS, 1, + AC_DEFINE([AIX_GENUINE_CPLUSPLUS], [1], [Define for AIX if your compiler is a genuine IBM xlC/xlC_r and you want support for AIX C++ shared extension modules.]) - AC_MSG_RESULT(yes) + AC_MSG_RESULT([yes]) ],[ - AC_MSG_RESULT(no) + AC_MSG_RESULT([no]) ]) dnl The AIX_BUILDDATE is obtained from the kernel fileset - bos.mp64 # BUILD_GNU_TYPE + AIX_BUILDDATE are used to construct the platform_tag # of the AIX system used to build/package Python executable. This tag serves # as a baseline for bdist module packages - AC_MSG_CHECKING(for the system builddate) + AC_MSG_CHECKING([for the system builddate]) AIX_BUILDDATE=$(lslpp -Lcq bos.mp64 | awk -F: '{ print $NF }') AC_DEFINE_UNQUOTED([AIX_BUILDDATE], [$AIX_BUILDDATE], [BUILD_GNU_TYPE + AIX_BUILDDATE are used to construct the PEP425 tag of the build system.]) - AC_MSG_RESULT($AIX_BUILDDATE) + AC_MSG_RESULT([$AIX_BUILDDATE]) ;; *) ;; esac @@ -3511,33 +3682,36 @@ if test "$ac_cv_aligned_required" = yes ; then fi # str, bytes and memoryview hash algorithm -AH_TEMPLATE(Py_HASH_ALGORITHM, +AH_TEMPLATE([Py_HASH_ALGORITHM], [Define hash algorithm for str, bytes and memoryview. SipHash24: 1, FNV: 2, SipHash13: 3, externally defined: 0]) -AC_MSG_CHECKING(for --with-hash-algorithm) +AC_MSG_CHECKING([for --with-hash-algorithm]) dnl quadrigraphs "@<:@" and "@:>@" produce "[" and "]" in the output -AC_ARG_WITH(hash_algorithm, - AS_HELP_STRING([--with-hash-algorithm=@<:@fnv|siphash13|siphash24@:>@], - [select hash algorithm for use in Python/pyhash.c (default is SipHash13)]), +AC_ARG_WITH( + [hash_algorithm], + [AS_HELP_STRING( + [--with-hash-algorithm=@<:@fnv|siphash13|siphash24@:>@], + [select hash algorithm for use in Python/pyhash.c (default is SipHash13)] + )], [ -AC_MSG_RESULT($withval) +AC_MSG_RESULT([$withval]) case "$withval" in siphash13) - AC_DEFINE(Py_HASH_ALGORITHM, 3) + AC_DEFINE([Py_HASH_ALGORITHM], [3]) ;; siphash24) - AC_DEFINE(Py_HASH_ALGORITHM, 1) + AC_DEFINE([Py_HASH_ALGORITHM], [1]) ;; fnv) - AC_DEFINE(Py_HASH_ALGORITHM, 2) + AC_DEFINE([Py_HASH_ALGORITHM], [2]) ;; *) AC_MSG_ERROR([unknown hash algorithm '$withval']) ;; esac ], -[AC_MSG_RESULT(default)]) +[AC_MSG_RESULT([default])]) validate_tzpath() { # Checks that each element of the path is an absolute path @@ -3555,10 +3729,13 @@ validate_tzpath() { } TZPATH="/usr/share/zoneinfo:/usr/lib/zoneinfo:/usr/share/lib/zoneinfo:/etc/zoneinfo" -AC_MSG_CHECKING(for --with-tzpath) -AC_ARG_WITH(tzpath, - AS_HELP_STRING([--with-tzpath=] - [Select the default time zone search path for zoneinfo.TZPATH]), +AC_MSG_CHECKING([for --with-tzpath]) +AC_ARG_WITH( + [tzpath], + [AS_HELP_STRING( + [--with-tzpath=], + [Select the default time zone search path for zoneinfo.TZPATH] + )], [ case "$withval" in yes) @@ -3567,41 +3744,47 @@ case "$withval" in *) validate_tzpath "$withval" TZPATH="$withval" - AC_MSG_RESULT("$withval") + AC_MSG_RESULT(["$withval"]) ;; esac ], [validate_tzpath "$TZPATH" - AC_MSG_RESULT("$TZPATH")]) -AC_SUBST(TZPATH) + AC_MSG_RESULT(["$TZPATH"])]) +AC_SUBST([TZPATH]) # Most SVR4 platforms (e.g. Solaris) need -lsocket and -lnsl. -AC_CHECK_LIB(nsl, t_open, [LIBS="-lnsl $LIBS"]) # SVR4 -AC_CHECK_LIB(socket, socket, [LIBS="-lsocket $LIBS"], [], $LIBS) # SVR4 sockets +AC_CHECK_LIB([nsl], [t_open], [LIBS="-lnsl $LIBS"]) # SVR4 +AC_CHECK_LIB([socket], [socket], [LIBS="-lsocket $LIBS"], [], $LIBS) # SVR4 sockets case $ac_sys_system/$ac_sys_release in Haiku*) - AC_CHECK_LIB(network, socket, [LIBS="-lnetwork $LIBS"], [], $LIBS) + AC_CHECK_LIB([network], [socket], [LIBS="-lnetwork $LIBS"], [], [$LIBS]) ;; esac -AC_MSG_CHECKING(for --with-libs) -AC_ARG_WITH(libs, - AS_HELP_STRING([--with-libs='lib1 ...'], [link against additional libs (default is no)]), +AC_MSG_CHECKING([for --with-libs]) +AC_ARG_WITH( + [libs], + [AS_HELP_STRING( + [--with-libs='lib1 ...'], + [link against additional libs (default is no)] + )], [ -AC_MSG_RESULT($withval) +AC_MSG_RESULT([$withval]) LIBS="$withval $LIBS" ], -[AC_MSG_RESULT(no)]) +[AC_MSG_RESULT([no])]) # Check for use of the system expat library -AC_MSG_CHECKING(for --with-system-expat) -AC_ARG_WITH(system_expat, - AS_HELP_STRING([--with-system-expat], [build pyexpat module using an installed expat library, see Doc/library/pyexpat.rst (default is no)]), - [], - [with_system_expat="no"]) +AC_MSG_CHECKING([for --with-system-expat]) +AC_ARG_WITH( + [system_expat], + [AS_HELP_STRING( + [--with-system-expat], + [build pyexpat module using an installed expat library, see Doc/library/pyexpat.rst (default is no)] + )], [], [with_system_expat="no"]) -AC_MSG_RESULT($with_system_expat) +AC_MSG_RESULT([$with_system_expat]) AS_VAR_IF([with_system_expat], [yes], [ LIBEXPAT_CFLAGS=${LIBEXPAT_CFLAGS-""} @@ -3614,50 +3797,78 @@ AS_VAR_IF([with_system_expat], [yes], [ ]) AC_SUBST([LIBEXPAT_CFLAGS]) -AC_SUBST([LIBEXPAT_LDFLAGS]) AC_SUBST([LIBEXPAT_INTERNAL]) -# Check for use of the system libffi library -AC_MSG_CHECKING(for --with-system-ffi) -AC_ARG_WITH(system_ffi, - AS_HELP_STRING([--with-system-ffi], [build _ctypes module using an installed ffi library, see Doc/library/ctypes.rst (default is system-dependent)]),,,) +dnl detect libffi +have_libffi=missing +AS_VAR_IF([ac_sys_system], [Darwin], [ + WITH_SAVE_ENV([ + CFLAGS="-I${SDKROOT}/usr/include/ffi $CFLAGS" + AC_CHECK_HEADER([ffi.h], [ + AC_CHECK_LIB([ffi], [ffi_call], [ + dnl use ffi from SDK root + have_libffi=yes + LIBFFI_CFLAGS="-I${SDKROOT}/usr/include/ffi -DUSING_APPLE_OS_LIBFFI=1" + LIBFFI_LIBS="-lffi" + ]) + ]) + ]) +]) +AS_VAR_IF([have_libffi], [missing], [ + PKG_CHECK_MODULES([LIBFFI], [libffi], [have_libffi=yes], [ + WITH_SAVE_ENV([ + CPPFLAGS="$CPPFLAGS $LIBFFI_CFLAGS" + LDFLAGS="$LDFLAGS $LIBFFI_LIBS" + AC_CHECK_HEADER([ffi.h], [ + AC_CHECK_LIB([ffi], [ffi_call], [ + have_libffi=yes + LIBFFI_CFLAGS=${LIBFFI_CFLAGS-""} + LIBFFI_LIBS=${LIBFFI_LIBS-"-lffi"} + ], [have_libffi=no]) + ]) + ]) + ]) +]) -if test "$ac_sys_system" = "Darwin" -then - case "$with_system_ffi" in - "") - with_system_ffi="no" - ;; - yes|no) - ;; - *) - AC_MSG_ERROR([--with-system-ffi accepts no arguments]) - ;; - esac - AC_MSG_RESULT($with_system_ffi) -else - AC_MSG_RESULT(yes) - if test "$with_system_ffi" != "" - then - AC_MSG_WARN([--with(out)-system-ffi is ignored on this platform]) - fi - with_system_ffi="yes" -fi +AS_VAR_IF([have_libffi], [yes], [ + ctypes_malloc_closure=no + AS_CASE([$ac_sys_system], + [Darwin], [ + dnl when do we need USING_APPLE_OS_LIBFFI? + ctypes_malloc_closure=yes + ], + [sunos5], [AS_VAR_APPEND([LIBFFI_LIBS], [" -mimpure-text"])] + ) + AS_VAR_IF([ctypes_malloc_closure], [yes], [ + MODULE__CTYPES_MALLOC_CLOSURE=_ctypes/malloc_closure.c + AS_VAR_APPEND([LIBFFI_CFLAGS], [" -DUSING_MALLOC_CLOSURE_DOT_C=1"]) + ]) + AC_SUBST([MODULE__CTYPES_MALLOC_CLOSURE]) -if test "$with_system_ffi" = "yes" && test -n "$PKG_CONFIG"; then - LIBFFI_INCLUDEDIR="`"$PKG_CONFIG" libffi --cflags-only-I 2>/dev/null | sed -e 's/^-I//;s/ *$//'`" -else - LIBFFI_INCLUDEDIR="" -fi -AC_SUBST(LIBFFI_INCLUDEDIR) + dnl HAVE_LIBDL: for dlopen, see gh-76828 + AS_VAR_IF([ac_cv_lib_dl_dlopen], [yes], [AS_VAR_APPEND([LIBFFI_LIBS], [" -ldl"])]) + + WITH_SAVE_ENV([ + CFLAGS="$LIBFFI_CFLAGS $CFLAGS" + LDFLAGS="$LIBFFI_LIBS $LDFLAGS" + + PY_CHECK_FUNC([ffi_prep_cif_var], [@%:@include ]) + PY_CHECK_FUNC([ffi_prep_closure_loc], [@%:@include ]) + PY_CHECK_FUNC([ffi_closure_alloc], [@%:@include ]) + ]) +]) # Check for use of the system libmpdec library -AC_MSG_CHECKING(for --with-system-libmpdec) -AC_ARG_WITH(system_libmpdec, - AS_HELP_STRING([--with-system-libmpdec], [build _decimal module using an installed libmpdec library, see Doc/library/decimal.rst (default is no)]), - [], - [with_system_libmpdec="no"]) -AC_MSG_RESULT($with_system_libmpdec) +AC_MSG_CHECKING([for --with-system-libmpdec]) +AC_ARG_WITH( + [system_libmpdec], + [AS_HELP_STRING( + [--with-system-libmpdec], + [build _decimal module using an installed libmpdec library, see Doc/library/decimal.rst (default is no)] + )], + [], + [with_system_libmpdec="no"]) +AC_MSG_RESULT([$with_system_libmpdec]) AS_VAR_IF([with_system_libmpdec], [yes], [ LIBMPDEC_CFLAGS=${LIBMPDEC_CFLAGS-""} @@ -3675,26 +3886,29 @@ AS_VAR_IF([with_system_libmpdec], [yes], [ ]) AC_SUBST([LIBMPDEC_CFLAGS]) -AC_SUBST([LIBMPDEC_LDFLAGS]) AC_SUBST([LIBMPDEC_INTERNAL]) # Check whether _decimal should use a coroutine-local or thread-local context -AC_MSG_CHECKING(for --with-decimal-contextvar) -AC_ARG_WITH(decimal_contextvar, - AS_HELP_STRING([--with-decimal-contextvar], [build _decimal module using a coroutine-local rather than a thread-local context (default is yes)]), - [], - [with_decimal_contextvar="yes"]) +AC_MSG_CHECKING([for --with-decimal-contextvar]) +AC_ARG_WITH( + [decimal_contextvar], + [AS_HELP_STRING( + [--with-decimal-contextvar], + [build _decimal module using a coroutine-local rather than a thread-local context (default is yes)] + )], + [], + [with_decimal_contextvar="yes"]) if test "$with_decimal_contextvar" != "no" then - AC_DEFINE(WITH_DECIMAL_CONTEXTVAR, 1, + AC_DEFINE([WITH_DECIMAL_CONTEXTVAR], [1], [Define if you want build the _decimal module using a coroutine-local rather than a thread-local context]) fi -AC_MSG_RESULT($with_decimal_contextvar) +AC_MSG_RESULT([$with_decimal_contextvar]) # Check for libmpdec machine flavor -AC_MSG_CHECKING(for decimal libmpdec machine) +AC_MSG_CHECKING([for decimal libmpdec machine]) AS_CASE([$ac_sys_system], [Darwin*], [libmpdec_system=Darwin], [SunOS*], [libmpdec_system=sunos], @@ -3823,7 +4037,6 @@ dnl hence CPPFLAGS instead of CFLAGS. PY_CHECK_SQLITE_FUNC([sqlite3_column_decltype]) PY_CHECK_SQLITE_FUNC([sqlite3_column_double]) PY_CHECK_SQLITE_FUNC([sqlite3_complete]) - PY_CHECK_SQLITE_FUNC([sqlite3_enable_shared_cache]) PY_CHECK_SQLITE_FUNC([sqlite3_progress_handler]) PY_CHECK_SQLITE_FUNC([sqlite3_result_double]) PY_CHECK_SQLITE_FUNC([sqlite3_set_authorizer]) @@ -3958,17 +4171,30 @@ WITH_SAVE_ENV([ ], [have_gdbm=no]) ]) -# check for _dbmmodule.c dependencies +dnl check for _dbmmodule.c dependencies +dnl ndbm, gdbm_compat, libdb AC_CHECK_HEADERS([ndbm.h], [ - LIBS_SAVE="$LIBS" - AC_CHECK_LIB([ndbm], [dbm_open]) - LIBS="$LIBS_SAVE" - AC_CHECK_LIB([gdbm_compat], [dbm_open]) - LIBS="$LIBS_SAVE" + WITH_SAVE_ENV([ + AC_SEARCH_LIBS([dbm_open], [ndbm gdbm_compat]) + ]) ]) -# "gdbm-ndbm.h" and "gdbm/ndbm.h" are both normalized to "gdbm_ndbm_h" -# unset ac_cv_header_gdbm_ndbm_h to prevent false positive cache hits. +AC_MSG_CHECKING([for ndbm presence and linker args]) +AS_CASE([$ac_cv_search_dbm_open], + [*ndbm*|*gdbm_compat*], [ + dbm_ndbm="$ac_cv_search_dbm_open" + have_ndbm=yes + ], + [none*], [ + dbm_ndbm="" + have_ndbm=yes + ], + [no], [have_ndbm=no] +) +AC_MSG_RESULT([$have_ndbm ($dbm_ndbm)]) + +dnl "gdbm-ndbm.h" and "gdbm/ndbm.h" are both normalized to "gdbm_ndbm_h" +dnl unset ac_cv_header_gdbm_ndbm_h to prevent false positive cache hits. AS_UNSET([ac_cv_header_gdbm_ndbm_h]) AC_CACHE_VAL([ac_cv_header_gdbm_slash_ndbm_h], [ AC_CHECK_HEADER( @@ -3993,26 +4219,27 @@ AS_VAR_IF([ac_cv_header_gdbm_dash_ndbm_h], [yes], [ AS_UNSET([ac_cv_header_gdbm_ndbm_h]) if test "$ac_cv_header_gdbm_slash_ndbm_h" = yes -o "$ac_cv_header_gdbm_dash_ndbm_h" = yes; then - LIBS_SAVE="$LIBS" - AC_CHECK_LIB([gdbm_compat], [dbm_open]) - LIBS="$LIBS_SAVE" + AS_UNSET([ac_cv_search_dbm_open]) + WITH_SAVE_ENV([ + AC_SEARCH_LIBS([dbm_open], [gdbm_compat], [have_gdbm_compat=yes], [have_gdbm_compat=no]) + ]) fi # Check for libdb >= 5 with dbm_open() # db.h re-defines the name of the function AC_CHECK_HEADERS([db.h], [ AC_CACHE_CHECK([for libdb], [ac_cv_have_libdb], [ - LIBS_SAVE="$LIBS" - LIBS="$LIBS -ldb" - AC_LINK_IFELSE([AC_LANG_PROGRAM([ - #define DB_DBM_HSEARCH 1 - #include - #if DB_VERSION_MAJOR < 5 - #error "dh.h: DB_VERSION_MAJOR < 5 is not supported." - #endif - ], [DBM *dbm = dbm_open(NULL, 0, 0)]) - ], [ac_cv_have_libdb=yes], [ac_cv_have_libdb=no]) - LIBS="$LIBS_SAVE" + WITH_SAVE_ENV([ + LIBS="$LIBS -ldb" + AC_LINK_IFELSE([AC_LANG_PROGRAM([ + #define DB_DBM_HSEARCH 1 + #include + #if DB_VERSION_MAJOR < 5 + #error "dh.h: DB_VERSION_MAJOR < 5 is not supported." + #endif + ], [DBM *dbm = dbm_open(NULL, 0, 0)]) + ], [ac_cv_have_libdb=yes], [ac_cv_have_libdb=no]) + ]) ]) AS_VAR_IF([ac_cv_have_libdb], [yes], [ AC_DEFINE([HAVE_LIBDB], [1], [Define to 1 if you have the `db' library (-ldb).]) @@ -4020,10 +4247,14 @@ AC_CHECK_HEADERS([db.h], [ ]) # Check for --with-dbmliborder -AC_MSG_CHECKING(for --with-dbmliborder) -AC_ARG_WITH(dbmliborder, - AS_HELP_STRING([--with-dbmliborder=db1:db2:...], [override order to check db backends for dbm; a valid value is a colon separated string with the backend names `ndbm', `gdbm' and `bdb'.]), -[], [with_dbmliborder=gdbm:ndbm:bdb]) +AC_MSG_CHECKING([for --with-dbmliborder]) +AC_ARG_WITH( + [dbmliborder], + [AS_HELP_STRING( + [--with-dbmliborder=db1:db2:...], + [override order to check db backends for dbm; a valid value is a colon separated string with the backend names `ndbm', `gdbm' and `bdb'.] + )], + [], [with_dbmliborder=gdbm:ndbm:bdb]) have_gdbm_dbmliborder=no as_save_IFS=$IFS @@ -4040,17 +4271,52 @@ IFS=$as_save_IFS AS_VAR_IF([with_dbmliborder], [error], [ AC_MSG_ERROR([proper usage is --with-dbmliborder=db1:db2:... (gdbm:ndbm:bdb)]) ]) -AC_MSG_RESULT($with_dbmliborder) +AC_MSG_RESULT([$with_dbmliborder]) + +AC_MSG_CHECKING([for _dbm module CFLAGS and LIBS]) +have_dbm=no +as_save_IFS=$IFS +IFS=: +for db in $with_dbmliborder; do + case "$db" in + ndbm) + if test "$have_ndbm" = yes; then + DBM_CFLAGS="-DUSE_NDBM" + DBM_LIBS="$dbm_ndbm" + have_dbm=yes + break + fi + ;; + gdbm) + if test "$have_gdbm_compat" = yes; then + DBM_CFLAGS="-DUSE_GDBM_COMPAT" + DBM_LIBS="-lgdbm_compat" + have_dbm=yes + break + fi + ;; + bdb) + if test "$ac_cv_have_libdb" = yes; then + DBM_CFLAGS="-DUSE_BERKDB" + DBM_LIBS="-ldb" + have_dbm=yes + break + fi + ;; + esac +done +IFS=$as_save_IFS +AC_MSG_RESULT([$DBM_CFLAGS $DBM_LIBS]) # Templates for things AC_DEFINEd more than once. # For a single AC_DEFINE, no template is needed. -AH_TEMPLATE(_REENTRANT, +AH_TEMPLATE([_REENTRANT], [Define to force use of thread-safe errno, h_errno, and other functions]) if test "$ac_cv_pthread_is_default" = yes then # Defining _REENTRANT on system with POSIX threads should not hurt. - AC_DEFINE(_REENTRANT) + AC_DEFINE([_REENTRANT]) posix_threads=yes if test "$ac_sys_system" = "SunOS"; then CFLAGS="$CFLAGS -D_REENTRANT" @@ -4084,17 +4350,17 @@ else # According to the POSIX spec, a pthreads implementation must # define _POSIX_THREADS in unistd.h. Some apparently don't # (e.g. gnu pth with pthread emulation) - AC_MSG_CHECKING(for _POSIX_THREADS in unistd.h) - AC_EGREP_CPP(yes, + AC_MSG_CHECKING([for _POSIX_THREADS in unistd.h]) + AC_EGREP_CPP([yes], [ #include #ifdef _POSIX_THREADS yes #endif ], unistd_defines_pthreads=yes, unistd_defines_pthreads=no) - AC_MSG_RESULT($unistd_defines_pthreads) + AC_MSG_RESULT([$unistd_defines_pthreads]) - AC_DEFINE(_REENTRANT) + AC_DEFINE([_REENTRANT]) # Just looking for pthread_create in libpthread is not enough: # on HP/UX, pthread.h renames pthread_create to a different symbol name. # So we really have to include pthread.h, and then link. @@ -4108,26 +4374,26 @@ yes void * start_routine (void *arg) { exit (0); }]], [[ pthread_create (NULL, NULL, start_routine, NULL)]])],[ - AC_MSG_RESULT(yes) + AC_MSG_RESULT([yes]) posix_threads=yes ],[ LIBS=$_libs - AC_CHECK_FUNC(pthread_detach, [ + AC_CHECK_FUNC([pthread_detach], [ posix_threads=yes ],[ - AC_CHECK_LIB(pthreads, pthread_create, [ + AC_CHECK_LIB([pthreads], [pthread_create], [ posix_threads=yes LIBS="$LIBS -lpthreads" ], [ - AC_CHECK_LIB(c_r, pthread_create, [ + AC_CHECK_LIB([c_r], [pthread_create], [ posix_threads=yes LIBS="$LIBS -lc_r" ], [ - AC_CHECK_LIB(pthread, __pthread_create_system, [ + AC_CHECK_LIB([pthread], [__pthread_create_system], [ posix_threads=yes LIBS="$LIBS -lpthread" ], [ - AC_CHECK_LIB(cma, pthread_create, [ + AC_CHECK_LIB([cma], [pthread_create], [ posix_threads=yes LIBS="$LIBS -lcma" ],[ @@ -4137,7 +4403,7 @@ pthread_create (NULL, NULL, start_routine, NULL)]])],[ ) ])])])])])]) - AC_CHECK_LIB(mpc, usconfig, [ + AC_CHECK_LIB([mpc], [usconfig], [ LIBS="$LIBS -lmpc" ]) @@ -4145,23 +4411,23 @@ fi if test "$posix_threads" = "yes"; then if test "$unistd_defines_pthreads" = "no"; then - AC_DEFINE(_POSIX_THREADS, 1, + AC_DEFINE([_POSIX_THREADS], [1], [Define if you have POSIX threads, and your system does not define that.]) fi # Bug 662787: Using semaphores causes unexplicable hangs on Solaris 8. case $ac_sys_system/$ac_sys_release in - SunOS/5.6) AC_DEFINE(HAVE_PTHREAD_DESTRUCTOR, 1, + SunOS/5.6) AC_DEFINE([HAVE_PTHREAD_DESTRUCTOR], [1], [Defined for Solaris 2.6 bug in pthread header.]) ;; - SunOS/5.8) AC_DEFINE(HAVE_BROKEN_POSIX_SEMAPHORES, 1, + SunOS/5.8) AC_DEFINE([HAVE_BROKEN_POSIX_SEMAPHORES], [1], [Define if the Posix semaphores do not work on your system]) ;; - AIX/*) AC_DEFINE(HAVE_BROKEN_POSIX_SEMAPHORES, 1, + AIX/*) AC_DEFINE([HAVE_BROKEN_POSIX_SEMAPHORES], [1], [Define if the Posix semaphores do not work on your system]) ;; - NetBSD/*) AC_DEFINE(HAVE_BROKEN_POSIX_SEMAPHORES, 1, + NetBSD/*) AC_DEFINE([HAVE_BROKEN_POSIX_SEMAPHORES], [1], [Define if the Posix semaphores do not work on your system]) ;; esac @@ -4186,16 +4452,17 @@ if test "$posix_threads" = "yes"; then [ac_cv_pthread_system_supported=no]) ]) if test "$ac_cv_pthread_system_supported" = "yes"; then - AC_DEFINE(PTHREAD_SYSTEM_SCHED_SUPPORTED, 1, [Defined if PTHREAD_SCOPE_SYSTEM supported.]) + AC_DEFINE([PTHREAD_SYSTEM_SCHED_SUPPORTED], [1], + [Defined if PTHREAD_SCOPE_SYSTEM supported.]) fi - AC_CHECK_FUNCS(pthread_sigmask, + AC_CHECK_FUNCS([pthread_sigmask], [case $ac_sys_system in CYGWIN*) - AC_DEFINE(HAVE_BROKEN_PTHREAD_SIGMASK, 1, + AC_DEFINE([HAVE_BROKEN_PTHREAD_SIGMASK], [1], [Define if pthread_sigmask() does not work on your system.]) ;; esac]) - AC_CHECK_FUNCS(pthread_getcpuclockid) + AC_CHECK_FUNCS([pthread_getcpuclockid]) fi AS_VAR_IF([posix_threads], [stub], [ @@ -4203,18 +4470,20 @@ AS_VAR_IF([posix_threads], [stub], [ ]) # Check for enable-ipv6 -AH_TEMPLATE(ENABLE_IPV6, [Define if --enable-ipv6 is specified]) +AH_TEMPLATE([ENABLE_IPV6], [Define if --enable-ipv6 is specified]) AC_MSG_CHECKING([if --enable-ipv6 is specified]) -AC_ARG_ENABLE(ipv6, - AS_HELP_STRING([--enable-ipv6], - [enable ipv6 (with ipv4) support, see Doc/library/socket.rst (default is yes if supported)]), +AC_ARG_ENABLE([ipv6], + [AS_HELP_STRING( + [--enable-ipv6], + [enable ipv6 (with ipv4) support, see Doc/library/socket.rst (default is yes if supported)] + )], [ case "$enableval" in no) - AC_MSG_RESULT(no) + AC_MSG_RESULT([no]) ipv6=no ;; - *) AC_MSG_RESULT(yes) - AC_DEFINE(ENABLE_IPV6) + *) AC_MSG_RESULT([yes]) + AC_DEFINE([ENABLE_IPV6]) ipv6=yes ;; esac ], @@ -4223,7 +4492,7 @@ AC_ARG_ENABLE(ipv6, dnl the check does not work on cross compilation case... AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ /* AF_INET6 available check */ #include -#include ]], +@%:@include ]], [[int domain = AF_INET6;]])],[ ipv6=yes ],[ @@ -4237,23 +4506,23 @@ AS_CASE([$ac_sys_system], AC_MSG_RESULT([$ipv6]) if test "$ipv6" = "yes"; then - AC_MSG_CHECKING(if RFC2553 API is available) + AC_MSG_CHECKING([if RFC2553 API is available]) AC_COMPILE_IFELSE([ AC_LANG_PROGRAM([[#include -#include ]], +@%:@include ]], [[struct sockaddr_in6 x; x.sin6_scope_id;]]) ],[ - AC_MSG_RESULT(yes) + AC_MSG_RESULT([yes]) ipv6=yes ],[ - AC_MSG_RESULT(no, IPv6 disabled) + AC_MSG_RESULT([no], [IPv6 disabled]) ipv6=no ]) fi if test "$ipv6" = "yes"; then - AC_DEFINE(ENABLE_IPV6) + AC_DEFINE([ENABLE_IPV6]) fi ]) @@ -4268,20 +4537,20 @@ if test "$ipv6" = "yes"; then case $i in inria) dnl http://www.kame.net/ - AC_EGREP_CPP(yes, [ + AC_EGREP_CPP([yes], [ #include #ifdef IPV6_INRIA_VERSION yes -#endif], +@%:@endif], [ipv6type=$i]) ;; kame) dnl http://www.kame.net/ - AC_EGREP_CPP(yes, [ + AC_EGREP_CPP([yes], [ #include #ifdef __KAME__ yes -#endif], +@%:@endif], [ipv6type=$i; ipv6lib=inet6 ipv6libdir=/usr/local/v6/lib @@ -4289,11 +4558,11 @@ yes ;; linux-glibc) dnl http://www.v6.linux.or.jp/ - AC_EGREP_CPP(yes, [ + AC_EGREP_CPP([yes], [ #include #if defined(__GLIBC__) && ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1) || (__GLIBC__ > 2)) yes -#endif], +@%:@endif], [ipv6type=$i; ipv6trylibc=yes]) ;; @@ -4315,32 +4584,32 @@ yes fi ;; toshiba) - AC_EGREP_CPP(yes, [ + AC_EGREP_CPP([yes], [ #include #ifdef _TOSHIBA_INET6 yes -#endif], +@%:@endif], [ipv6type=$i; ipv6lib=inet6; ipv6libdir=/usr/local/v6/lib]) ;; v6d) - AC_EGREP_CPP(yes, [ + AC_EGREP_CPP([yes], [ #include #ifdef __V6D__ yes -#endif], +@%:@endif], [ipv6type=$i; ipv6lib=v6; ipv6libdir=/usr/local/v6/lib; BASECFLAGS="-I/usr/local/v6/include $BASECFLAGS"]) ;; zeta) - AC_EGREP_CPP(yes, [ + AC_EGREP_CPP([yes], [ #include #ifdef _ZETA_MINAMI_INET6 yes -#endif], +@%:@endif], [ipv6type=$i; ipv6lib=inet6; ipv6libdir=/usr/local/v6/lib]) @@ -4350,7 +4619,7 @@ yes break fi done - AC_MSG_RESULT($ipv6type) + AC_MSG_RESULT([$ipv6type]) fi if test "$ipv6" = "yes" -a "$ipv6lib" != "none"; then @@ -4373,45 +4642,49 @@ fi AC_CACHE_CHECK([CAN_RAW_FD_FRAMES], [ac_cv_can_raw_fd_frames], [ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ /* CAN_RAW_FD_FRAMES available check */ -#include ]], +@%:@include ]], [[int can_raw_fd_frames = CAN_RAW_FD_FRAMES;]])], [ac_cv_can_raw_fd_frames=yes], [ac_cv_can_raw_fd_frames=no]) ]) AS_VAR_IF([ac_cv_can_raw_fd_frames], [yes], [ - AC_DEFINE(HAVE_LINUX_CAN_RAW_FD_FRAMES, 1, [Define if compiling using Linux 3.6 or later.]) + AC_DEFINE([HAVE_LINUX_CAN_RAW_FD_FRAMES], [1], + [Define if compiling using Linux 3.6 or later.]) ]) AC_CACHE_CHECK([for CAN_RAW_JOIN_FILTERS], [ac_cv_can_raw_join_filters], [ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ -#include ]], +@%:@include ]], [[int can_raw_join_filters = CAN_RAW_JOIN_FILTERS;]])], [ac_cv_can_raw_join_filters=yes], [ac_cv_can_raw_join_filters=no]) ]) AS_VAR_IF([ac_cv_can_raw_join_filters], [yes], [ - AC_DEFINE(HAVE_LINUX_CAN_RAW_JOIN_FILTERS, 1, [Define if compiling using Linux 4.1 or later.]) + AC_DEFINE([HAVE_LINUX_CAN_RAW_JOIN_FILTERS], [1], + [Define if compiling using Linux 4.1 or later.]) ]) # Check for --with-doc-strings -AC_MSG_CHECKING(for --with-doc-strings) -AC_ARG_WITH(doc-strings, - AS_HELP_STRING([--with-doc-strings], [enable documentation strings (default is yes)])) +AC_MSG_CHECKING([for --with-doc-strings]) +AC_ARG_WITH( + [doc-strings], + [AS_HELP_STRING([--with-doc-strings], [enable documentation strings (default is yes)])]) if test -z "$with_doc_strings" then with_doc_strings="yes" fi if test "$with_doc_strings" != "no" then - AC_DEFINE(WITH_DOC_STRINGS, 1, + AC_DEFINE([WITH_DOC_STRINGS], [1], [Define if you want documentation strings in extension modules]) fi -AC_MSG_RESULT($with_doc_strings) +AC_MSG_RESULT([$with_doc_strings]) # Check for Python-specific malloc support -AC_MSG_CHECKING(for --with-pymalloc) -AC_ARG_WITH(pymalloc, - AS_HELP_STRING([--with-pymalloc], [enable specialized mallocs (default is yes)])) +AC_MSG_CHECKING([for --with-pymalloc]) +AC_ARG_WITH( + [pymalloc], + [AS_HELP_STRING([--with-pymalloc], [enable specialized mallocs (default is yes)])]) if test -z "$with_pymalloc" then @@ -4424,16 +4697,17 @@ then fi if test "$with_pymalloc" != "no" then - AC_DEFINE(WITH_PYMALLOC, 1, + AC_DEFINE([WITH_PYMALLOC], [1], [Define if you want to compile in Python-specific mallocs]) fi -AC_MSG_RESULT($with_pymalloc) +AC_MSG_RESULT([$with_pymalloc]) # Check whether objects such as float, tuple and dict are using # freelists to optimization memory allocation. -AC_MSG_CHECKING(for --with-freelists) -AC_ARG_WITH(freelists, - AS_HELP_STRING([--with-freelists], [enable object freelists (default is yes)])) +AC_MSG_CHECKING([for --with-freelists]) +AC_ARG_WITH( + [freelists], + [AS_HELP_STRING([--with-freelists], [enable object freelists (default is yes)])]) if test -z "$with_freelists" then @@ -4441,16 +4715,16 @@ then fi if test "$with_freelists" != "no" then - AC_DEFINE(WITH_FREELISTS, 1, + AC_DEFINE([WITH_FREELISTS], [1], [Define if you want to compile in object freelists optimization]) fi -AC_MSG_RESULT($with_freelists) +AC_MSG_RESULT([$with_freelists]) # Check for --with-c-locale-coercion -AC_MSG_CHECKING(for --with-c-locale-coercion) -AC_ARG_WITH(c-locale-coercion, - AS_HELP_STRING([--with-c-locale-coercion], - [enable C locale coercion to a UTF-8 based locale (default is yes)])) +AC_MSG_CHECKING([for --with-c-locale-coercion]) +AC_ARG_WITH( + [c-locale-coercion], + [AS_HELP_STRING([--with-c-locale-coercion], [enable C locale coercion to a UTF-8 based locale (default is yes)])]) if test -z "$with_c_locale_coercion" then @@ -4458,16 +4732,18 @@ then fi if test "$with_c_locale_coercion" != "no" then - AC_DEFINE(PY_COERCE_C_LOCALE, 1, + AC_DEFINE([PY_COERCE_C_LOCALE], [1], [Define if you want to coerce the C locale to a UTF-8 based locale]) fi -AC_MSG_RESULT($with_c_locale_coercion) +AC_MSG_RESULT([$with_c_locale_coercion]) # Check for Valgrind support AC_MSG_CHECKING([for --with-valgrind]) -AC_ARG_WITH([valgrind], - AS_HELP_STRING([--with-valgrind], [enable Valgrind support (default is no)]),, - with_valgrind=no) +AC_ARG_WITH( + [valgrind], + [AS_HELP_STRING([--with-valgrind], [enable Valgrind support (default is no)])], + [], [with_valgrind=no] +) AC_MSG_RESULT([$with_valgrind]) if test "$with_valgrind" != no; then AC_CHECK_HEADER([valgrind/valgrind.h], @@ -4478,27 +4754,29 @@ if test "$with_valgrind" != no; then fi # Check for DTrace support -AC_MSG_CHECKING(for --with-dtrace) -AC_ARG_WITH(dtrace, - AS_HELP_STRING([--with-dtrace],[enable DTrace support (default is no)]),, - with_dtrace=no) -AC_MSG_RESULT($with_dtrace) - -AC_SUBST(DTRACE) -AC_SUBST(DFLAGS) -AC_SUBST(DTRACE_HEADERS) -AC_SUBST(DTRACE_OBJS) +AC_MSG_CHECKING([for --with-dtrace]) +AC_ARG_WITH( + [dtrace], + [AS_HELP_STRING([--with-dtrace], [enable DTrace support (default is no)])], + [], [with_dtrace=no]) +AC_MSG_RESULT([$with_dtrace]) + +AC_SUBST([DTRACE]) +AC_SUBST([DFLAGS]) +AC_SUBST([DTRACE_HEADERS]) +AC_SUBST([DTRACE_OBJS]) DTRACE= DTRACE_HEADERS= DTRACE_OBJS= if test "$with_dtrace" = "yes" then - AC_PATH_PROG(DTRACE, [dtrace], [not found]) + AC_PATH_PROG([DTRACE], [dtrace], [not found]) if test "$DTRACE" = "not found"; then AC_MSG_ERROR([dtrace command not found on \$PATH]) fi - AC_DEFINE(WITH_DTRACE, 1, [Define if you want to compile in DTrace support]) + AC_DEFINE([WITH_DTRACE], [1], + [Define if you want to compile in DTrace support]) DTRACE_HEADERS="Include/pydtrace_probes.h" # On OS X, DTrace providers do not need to be explicitly compiled and @@ -4531,17 +4809,17 @@ AC_SUBST([PLATFORM_HEADERS]) AC_SUBST([PLATFORM_OBJS]) # -I${DLINCLDIR} is added to the compile rule for importdl.o -AC_SUBST(DLINCLDIR) +AC_SUBST([DLINCLDIR]) DLINCLDIR=. # the dlopen() function means we might want to use dynload_shlib.o. some # platforms have dlopen(), but don't want to use it. -AC_CHECK_FUNCS(dlopen) +AC_CHECK_FUNCS([dlopen]) # DYNLOADFILE specifies which dynload_*.o file we will use for dynamic # loading of modules. -AC_SUBST(DYNLOADFILE) -AC_MSG_CHECKING(DYNLOADFILE) +AC_SUBST([DYNLOADFILE]) +AC_MSG_CHECKING([DYNLOADFILE]) if test -z "$DYNLOADFILE" then case $ac_sys_system/$ac_sys_release in @@ -4556,17 +4834,17 @@ then ;; esac fi -AC_MSG_RESULT($DYNLOADFILE) +AC_MSG_RESULT([$DYNLOADFILE]) if test "$DYNLOADFILE" != "dynload_stub.o" then - AC_DEFINE(HAVE_DYNAMIC_LOADING, 1, + AC_DEFINE([HAVE_DYNAMIC_LOADING], [1], [Defined when any dynamic module loading is enabled.]) fi # MACHDEP_OBJS can be set to platform-specific object files needed by Python -AC_SUBST(MACHDEP_OBJS) -AC_MSG_CHECKING(MACHDEP_OBJS) +AC_SUBST([MACHDEP_OBJS]) +AC_MSG_CHECKING([MACHDEP_OBJS]) if test -z "$MACHDEP_OBJS" then MACHDEP_OBJS=$extra_machdep_objs @@ -4611,45 +4889,26 @@ AC_CHECK_FUNCS([ \ # links. Some libc implementations have a stub lchmod implementation that always # returns an error. if test "$MACHDEP" != linux; then - AC_CHECK_FUNCS(lchmod) + AC_CHECK_FUNCS([lchmod]) fi -AC_CHECK_DECL(dirfd, - AC_DEFINE(HAVE_DIRFD, 1, - Define if you have the 'dirfd' function or macro.), , - [#include - #include ]) - -dnl PY_CHECK_FUNC(FUNCTION, [INCLUDES], [AC_DEFINE-VAR]) -AC_DEFUN([PY_CHECK_FUNC], -[ AS_VAR_PUSHDEF([py_var], [ac_cv_func_$1]) - AS_VAR_PUSHDEF([py_define], m4_ifblank([$3], [[HAVE_]m4_toupper($1)], [$3])) - AC_CACHE_CHECK( - [for $1], - [py_var], - [AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM([$2], [void *x=$1])], - [AS_VAR_SET([py_var], [yes])], - [AS_VAR_SET([py_var], [no])])] - ) - AS_VAR_IF( - [py_var], - [yes], - [AC_DEFINE([py_define], [1], [Define if you have the '$1' function.])]) - AS_VAR_POPDEF([py_var]) - AS_VAR_POPDEF([py_define]) -]) +AC_CHECK_DECL([dirfd], + [AC_DEFINE([HAVE_DIRFD], [1], + [Define if you have the 'dirfd' function or macro.])], + [], + [@%:@include + @%:@include ]) # For some functions, having a definition is not sufficient, since # we want to take their address. -PY_CHECK_FUNC([chroot], [#include ]) -PY_CHECK_FUNC([link], [#include ]) -PY_CHECK_FUNC([symlink], [#include ]) -PY_CHECK_FUNC([fchdir], [#include ]) -PY_CHECK_FUNC([fsync], [#include ]) -PY_CHECK_FUNC([fdatasync], [#include ]) -PY_CHECK_FUNC([epoll_create], [#include ], [HAVE_EPOLL]) -PY_CHECK_FUNC([epoll_create1], [#include ]) +PY_CHECK_FUNC([chroot], [@%:@include ]) +PY_CHECK_FUNC([link], [@%:@include ]) +PY_CHECK_FUNC([symlink], [@%:@include ]) +PY_CHECK_FUNC([fchdir], [@%:@include ]) +PY_CHECK_FUNC([fsync], [@%:@include ]) +PY_CHECK_FUNC([fdatasync], [@%:@include ]) +PY_CHECK_FUNC([epoll_create], [@%:@include ], [HAVE_EPOLL]) +PY_CHECK_FUNC([epoll_create1], [@%:@include ]) PY_CHECK_FUNC([kqueue],[ #include #include @@ -4659,7 +4918,7 @@ PY_CHECK_FUNC([prlimit], [ #include ]) -PY_CHECK_FUNC([_dyld_shared_cache_contains_path], [#include ], [HAVE_DYLD_SHARED_CACHE_CONTAINS_PATH]) +PY_CHECK_FUNC([_dyld_shared_cache_contains_path], [@%:@include ], [HAVE_DYLD_SHARED_CACHE_CONTAINS_PATH]) PY_CHECK_FUNC([memfd_create], [ #ifdef HAVE_SYS_MMAN_H @@ -4682,12 +4941,12 @@ PY_CHECK_FUNC([eventfd], [ # address to avoid compiler warnings and potential miscompilations # because of the missing prototypes. -PY_CHECK_FUNC([ctermid_r], [#include ]) +PY_CHECK_FUNC([ctermid_r], [@%:@include ]) AC_CACHE_CHECK([for flock declaration], [ac_cv_flock_decl], [AC_COMPILE_IFELSE( [AC_LANG_PROGRAM( - [#include ], + [@%:@include ], [void* p = flock] )], [ac_cv_flock_decl=yes], @@ -4696,32 +4955,32 @@ AC_CACHE_CHECK([for flock declaration], [ac_cv_flock_decl], ]) dnl Linking with libbsd may be necessary on AIX for flock function. AS_VAR_IF([ac_cv_flock_decl], [yes], - AC_CHECK_FUNCS([flock]) - AC_CHECK_LIB([bsd], [flock], [FCNTL_LIBS="-lbsd"]) -) + [AC_CHECK_FUNCS([flock], [], + [AC_CHECK_LIB([bsd], [flock], [FCNTL_LIBS="-lbsd"])])]) -PY_CHECK_FUNC([getpagesize], [#include ]) +PY_CHECK_FUNC([getpagesize], [@%:@include ]) AC_CACHE_CHECK([for broken unsetenv], [ac_cv_broken_unsetenv], [AC_COMPILE_IFELSE( [AC_LANG_PROGRAM( - [#include ], + [@%:@include ], [int res = unsetenv("DUMMY")])], [ac_cv_broken_unsetenv=no], [ac_cv_broken_unsetenv=yes] ) ]) AS_VAR_IF([ac_cv_broken_unsetenv], [yes], [ - AC_DEFINE(HAVE_BROKEN_UNSETENV, 1, [Define if 'unsetenv' does not return an int.]) + AC_DEFINE([HAVE_BROKEN_UNSETENV], [1], + [Define if 'unsetenv' does not return an int.]) ]) dnl check for true -AC_CHECK_PROGS(TRUE, true, /bin/true) +AC_CHECK_PROGS([TRUE], [true], [/bin/true]) dnl On some systems (e.g. Solaris 9), hstrerror and inet_aton are in -lresolv dnl On others, they are in the C library, so we to take no action -AC_CHECK_LIB(c, inet_aton, [$ac_cv_prog_TRUE], - AC_CHECK_LIB(resolv, inet_aton) +AC_CHECK_LIB([c], [inet_aton], [$ac_cv_prog_TRUE], + AC_CHECK_LIB([resolv], [inet_aton]) ) # On Tru64, chflags seems to be present, but calling it will @@ -4745,7 +5004,8 @@ if test "$ac_cv_have_chflags" = cross ; then AC_CHECK_FUNC([chflags], [ac_cv_have_chflags="yes"], [ac_cv_have_chflags="no"]) fi if test "$ac_cv_have_chflags" = yes ; then - AC_DEFINE(HAVE_CHFLAGS, 1, [Define to 1 if you have the 'chflags' function.]) + AC_DEFINE([HAVE_CHFLAGS], [1], + [Define to 1 if you have the 'chflags' function.]) fi AC_CACHE_CHECK([for lchflags], [ac_cv_have_lchflags], [dnl @@ -4764,7 +5024,8 @@ if test "$ac_cv_have_lchflags" = cross ; then AC_CHECK_FUNC([lchflags], [ac_cv_have_lchflags="yes"], [ac_cv_have_lchflags="no"]) fi if test "$ac_cv_have_lchflags" = yes ; then - AC_DEFINE(HAVE_LCHFLAGS, 1, [Define to 1 if you have the 'lchflags' function.]) + AC_DEFINE([HAVE_LCHFLAGS], [1], + [Define to 1 if you have the 'lchflags' function.]) fi dnl Check for compression libraries @@ -4830,7 +5091,7 @@ PKG_CHECK_MODULES([LIBLZMA], [liblzma], [have_liblzma=yes], [ ]) dnl PY_CHECK_NETDB_FUNC(FUNCTION) -AC_DEFUN([PY_CHECK_NETDB_FUNC], [PY_CHECK_FUNC([$1], [#include ])]) +AC_DEFUN([PY_CHECK_NETDB_FUNC], [PY_CHECK_FUNC([$1], [@%:@include ])]) PY_CHECK_NETDB_FUNC([hstrerror]) dnl not available in WASI yet @@ -4873,36 +5134,41 @@ PY_CHECK_FUNC([setgroups], [ # check for openpty, login_tty, and forkpty -AC_CHECK_FUNCS(openpty,, - AC_CHECK_LIB(util,openpty, - [AC_DEFINE(HAVE_OPENPTY) LIBS="$LIBS -lutil"], - AC_CHECK_LIB(bsd,openpty, [AC_DEFINE(HAVE_OPENPTY) LIBS="$LIBS -lbsd"]) - ) -) +AC_CHECK_FUNCS([openpty], [], + [AC_CHECK_LIB([util], [openpty], + [AC_DEFINE([HAVE_OPENPTY]) LIBS="$LIBS -lutil"], + [AC_CHECK_LIB([bsd], [openpty], + [AC_DEFINE([HAVE_OPENPTY]) LIBS="$LIBS -lbsd"])])]) AC_SEARCH_LIBS([login_tty], [util], [AC_DEFINE([HAVE_LOGIN_TTY], [1], [Define to 1 if you have the `login_tty' function.])] ) -AC_CHECK_FUNCS(forkpty,, - AC_CHECK_LIB(util,forkpty, - [AC_DEFINE(HAVE_FORKPTY) LIBS="$LIBS -lutil"], - AC_CHECK_LIB(bsd,forkpty, [AC_DEFINE(HAVE_FORKPTY) LIBS="$LIBS -lbsd"]) - ) -) +AC_CHECK_FUNCS([forkpty], [], + [AC_CHECK_LIB([util], [forkpty], + [AC_DEFINE([HAVE_FORKPTY]) LIBS="$LIBS -lutil"], + [AC_CHECK_LIB([bsd], [forkpty], + [AC_DEFINE([HAVE_FORKPTY]) LIBS="$LIBS -lbsd"])])]) # check for long file support functions -AC_CHECK_FUNCS(fseek64 fseeko fstatvfs ftell64 ftello statvfs) +AC_CHECK_FUNCS([fseek64 fseeko fstatvfs ftell64 ftello statvfs]) -AC_REPLACE_FUNCS(dup2) -AC_CHECK_FUNCS(getpgrp, - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[getpgrp(0);]])], - [AC_DEFINE(GETPGRP_HAVE_ARG, 1, [Define if getpgrp() must be called as getpgrp(0).])], - []) -) -AC_CHECK_FUNCS(setpgrp, - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[setpgrp(0,0);]])], - [AC_DEFINE(SETPGRP_HAVE_ARG, 1, [Define if setpgrp() must be called as setpgrp(0, 0).])], - []) -) +AC_REPLACE_FUNCS([dup2]) +AC_CHECK_FUNCS([getpgrp], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([@%:@include ], + [getpgrp(0);])], + [AC_DEFINE([GETPGRP_HAVE_ARG], [1], + [Define if getpgrp() must be called as getpgrp(0).])], + [])]) +AC_CHECK_FUNCS([setpgrp], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([@%:@include ], + [setpgrp(0,0);])], + [AC_DEFINE([SETPGRP_HAVE_ARG], [1], + [Define if setpgrp() must be called as setpgrp(0, 0).])], + [])]) + +# check for namespace functions +AC_CHECK_FUNCS([setns unshare]) dnl We search for both crypt and crypt_r as one or the other may be defined dnl libxcrypt provides and libcrypt with crypt_r() since @@ -4946,36 +5212,36 @@ WITH_SAVE_ENV([ ]) ]) -AC_CHECK_FUNCS(clock_gettime, [], [ - AC_CHECK_LIB(rt, clock_gettime, [ +AC_CHECK_FUNCS([clock_gettime], [], [ + AC_CHECK_LIB([rt], [clock_gettime], [ LIBS="$LIBS -lrt" - AC_DEFINE(HAVE_CLOCK_GETTIME, 1) - AC_DEFINE(TIMEMODULE_LIB, [rt], + AC_DEFINE([HAVE_CLOCK_GETTIME], [1]) + AC_DEFINE([TIMEMODULE_LIB], [rt], [Library needed by timemodule.c: librt may be needed for clock_gettime()]) ]) ]) -AC_CHECK_FUNCS(clock_getres, [], [ - AC_CHECK_LIB(rt, clock_getres, [ - AC_DEFINE(HAVE_CLOCK_GETRES, 1) +AC_CHECK_FUNCS([clock_getres], [], [ + AC_CHECK_LIB([rt], [clock_getres], [ + AC_DEFINE([HAVE_CLOCK_GETRES], [1]) ]) ]) -AC_CHECK_FUNCS(clock_settime, [], [ - AC_CHECK_LIB(rt, clock_settime, [ - AC_DEFINE(HAVE_CLOCK_SETTIME, 1) +AC_CHECK_FUNCS([clock_settime], [], [ + AC_CHECK_LIB([rt], [clock_settime], [ + AC_DEFINE([HAVE_CLOCK_SETTIME], [1]) ]) ]) -AC_CHECK_FUNCS(clock_nanosleep, [], [ - AC_CHECK_LIB(rt, clock_nanosleep, [ - AC_DEFINE(HAVE_CLOCK_NANOSLEEP, 1) +AC_CHECK_FUNCS([clock_nanosleep], [], [ + AC_CHECK_LIB([rt], [clock_nanosleep], [ + AC_DEFINE([HAVE_CLOCK_NANOSLEEP], [1]) ]) ]) -AC_CHECK_FUNCS(nanosleep, [], [ - AC_CHECK_LIB(rt, nanosleep, [ - AC_DEFINE(HAVE_NANOSLEEP, 1) +AC_CHECK_FUNCS([nanosleep], [], [ + AC_CHECK_LIB([rt], [nanosleep], [ + AC_DEFINE([HAVE_NANOSLEEP], [1]) ]) ]) @@ -4993,12 +5259,12 @@ AC_LINK_IFELSE([AC_LANG_PROGRAM([[ ]])],[ac_cv_device_macros=yes], [ac_cv_device_macros=no]) ]) AS_VAR_IF([ac_cv_device_macros], [yes], [ - AC_DEFINE(HAVE_DEVICE_MACROS, 1, + AC_DEFINE([HAVE_DEVICE_MACROS], [1], [Define to 1 if you have the device macros.]) ]) dnl no longer used, now always defined for backwards compatibility -AC_DEFINE(SYS_SELECT_WITH_SYS_TIME, 1, +AC_DEFINE([SYS_SELECT_WITH_SYS_TIME], [1], [Define if you can safely include both and (which you can't on SCO ODT 3.0).]) @@ -5128,16 +5394,11 @@ then ])]) ]) else - AC_DEFINE(HAVE_GETADDRINFO, 1, [Define if you have the getaddrinfo function.]) + AC_DEFINE([HAVE_GETADDRINFO], [1], + [Define if you have the getaddrinfo function.]) fi -AC_CHECK_FUNCS(getnameinfo) - -dnl autoconf 2.71 deprecates AC_HEADER_TIME, keep for backwards compatibility -dnl TIME_WITH_SYS_TIME works on all supported systems that have sys/time.h -AS_VAR_IF([ac_cv_header_sys_time_h], [yes], [ - AC_DEFINE([TIME_WITH_SYS_TIME], 1, [Define to 1 if you can safely include both and .]) -]) +AC_CHECK_FUNCS([getnameinfo]) # checks for structures AC_STRUCT_TM @@ -5153,44 +5414,47 @@ AC_CHECK_MEMBERS([struct passwd.pw_gecos, struct passwd.pw_passwd], [], [], [[ #include ]]) # Issue #21085: In Cygwin, siginfo_t does not have si_band field. -AC_CHECK_MEMBERS([siginfo_t.si_band], [], [], [[#include ]]) +AC_CHECK_MEMBERS([siginfo_t.si_band], [], [], [[@%:@include ]]) AC_CACHE_CHECK([for time.h that defines altzone], [ac_cv_header_time_altzone], [ - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[return altzone;]])], + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include ]], [[return altzone;]])], [ac_cv_header_time_altzone=yes], [ac_cv_header_time_altzone=no]) ]) if test $ac_cv_header_time_altzone = yes; then - AC_DEFINE(HAVE_ALTZONE, 1, [Define this if your time.h defines altzone.]) + AC_DEFINE([HAVE_ALTZONE], [1], + [Define this if your time.h defines altzone.]) fi AC_CACHE_CHECK([for addrinfo], [ac_cv_struct_addrinfo], -AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[struct addrinfo a]])], +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include ]], [[struct addrinfo a]])], [ac_cv_struct_addrinfo=yes], [ac_cv_struct_addrinfo=no])) if test $ac_cv_struct_addrinfo = yes; then - AC_DEFINE(HAVE_ADDRINFO, 1, [struct addrinfo (netdb.h)]) + AC_DEFINE([HAVE_ADDRINFO], [1], [struct addrinfo (netdb.h)]) fi AC_CACHE_CHECK([for sockaddr_storage], [ac_cv_struct_sockaddr_storage], AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ # include -# include ]], [[struct sockaddr_storage s]])], +@%:@ include ]], [[struct sockaddr_storage s]])], [ac_cv_struct_sockaddr_storage=yes], [ac_cv_struct_sockaddr_storage=no])) if test $ac_cv_struct_sockaddr_storage = yes; then - AC_DEFINE(HAVE_SOCKADDR_STORAGE, 1, [struct sockaddr_storage (sys/socket.h)]) + AC_DEFINE([HAVE_SOCKADDR_STORAGE], [1], + [struct sockaddr_storage (sys/socket.h)]) fi AC_CACHE_CHECK([for sockaddr_alg], [ac_cv_struct_sockaddr_alg], AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ # include # include -# include ]], [[struct sockaddr_alg s]])], +@%:@ include ]], [[struct sockaddr_alg s]])], [ac_cv_struct_sockaddr_alg=yes], [ac_cv_struct_sockaddr_alg=no])) if test $ac_cv_struct_sockaddr_alg = yes; then - AC_DEFINE(HAVE_SOCKADDR_ALG, 1, [struct sockaddr_alg (linux/if_alg.h)]) + AC_DEFINE([HAVE_SOCKADDR_ALG], [1], + [struct sockaddr_alg (linux/if_alg.h)]) fi # checks for compiler characteristics @@ -5202,7 +5466,7 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[signed char c;]])], [ac_cv_working_signed_char_c=yes], [ac_cv_working_signed_char_c=no]) ]) AS_VAR_IF([ac_cv_working_signed_char_c], [no], [ - AC_DEFINE(signed, , [Define to empty if the keyword does not work.]) + AC_DEFINE([signed], [], [Define to empty if the keyword does not work.]) ]) AC_CACHE_CHECK([for prototypes], [ac_cv_function_prototypes], [ @@ -5210,31 +5474,10 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[int foo(int x) { return 0; }]], [[return fo [ac_cv_function_prototypes=yes], [ac_cv_function_prototypes=no]) ]) AS_VAR_IF([ac_cv_function_prototypes], [yes], [ - AC_DEFINE(HAVE_PROTOTYPES, 1, + AC_DEFINE([HAVE_PROTOTYPES], [1], [Define if your compiler supports function prototype]) ]) -works=no -AC_CACHE_CHECK([for variable length prototypes and stdarg.h], [ac_cv_stdarg_prototypes], [ -AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ -#include -int foo(int x, ...) { - va_list va; - va_start(va, x); - va_arg(va, int); - va_arg(va, char *); - va_arg(va, double); - return 0; -} -]], [[return foo(10, "", 3.14);]])], - [ac_cv_stdarg_prototypes=yes], [ac_cv_stdarg_prototypes=no]) -]) -AS_VAR_IF([ac_cv_stdarg_prototypes], [yes], [ - AC_DEFINE(HAVE_STDARG_PROTOTYPES, 1, - [Define if your compiler supports variable length function prototypes - (e.g. void fprintf(FILE *, char *, ...);) *and* ]) -]) - # check for socketpair PY_CHECK_FUNC([socketpair], [ @@ -5245,20 +5488,21 @@ PY_CHECK_FUNC([socketpair], [ # check if sockaddr has sa_len member AC_CACHE_CHECK([if sockaddr has sa_len member], [ac_cv_struct_sockaddr_sa_len], [ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include -#include ]], [[struct sockaddr x; +@%:@include ]], [[struct sockaddr x; x.sa_len = 0;]])], [ac_cv_struct_sockaddr_sa_len=yes], [ac_cv_struct_sockaddr_sa_len=no]) ]) AS_VAR_IF([ac_cv_struct_sockaddr_sa_len], [yes], [ - AC_DEFINE(HAVE_SOCKADDR_SA_LEN, 1, [Define if sockaddr has sa_len member]) + AC_DEFINE([HAVE_SOCKADDR_SA_LEN], [1], + [Define if sockaddr has sa_len member]) ]) # sigh -- gethostbyname_r is a mess; it can have 3, 5 or 6 arguments :-( -AH_TEMPLATE(HAVE_GETHOSTBYNAME_R, +AH_TEMPLATE([HAVE_GETHOSTBYNAME_R], [Define this if you have some version of gethostbyname_r()]) -AC_CHECK_FUNC(gethostbyname_r, [ - AC_DEFINE(HAVE_GETHOSTBYNAME_R) +AC_CHECK_FUNC([gethostbyname_r], + [AC_DEFINE([HAVE_GETHOSTBYNAME_R]) AC_MSG_CHECKING([gethostbyname_r with 6 args]) OLD_CFLAGS=$CFLAGS CFLAGS="$CFLAGS $MY_CPPFLAGS $MY_THREAD_CPPFLAGS $MY_CFLAGS" @@ -5273,12 +5517,12 @@ AC_CHECK_FUNC(gethostbyname_r, [ (void) gethostbyname_r(name, he, buffer, buflen, &res, &h_errnop) ]])],[ - AC_DEFINE(HAVE_GETHOSTBYNAME_R) - AC_DEFINE(HAVE_GETHOSTBYNAME_R_6_ARG, 1, + AC_DEFINE([HAVE_GETHOSTBYNAME_R]) + AC_DEFINE([HAVE_GETHOSTBYNAME_R_6_ARG], [1], [Define this if you have the 6-arg version of gethostbyname_r().]) - AC_MSG_RESULT(yes) + AC_MSG_RESULT([yes]) ],[ - AC_MSG_RESULT(no) + AC_MSG_RESULT([no]) AC_MSG_CHECKING([gethostbyname_r with 5 args]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ # include @@ -5292,12 +5536,12 @@ AC_CHECK_FUNC(gethostbyname_r, [ (void) gethostbyname_r(name, he, buffer, buflen, &h_errnop) ]])], [ - AC_DEFINE(HAVE_GETHOSTBYNAME_R) - AC_DEFINE(HAVE_GETHOSTBYNAME_R_5_ARG, 1, + AC_DEFINE([HAVE_GETHOSTBYNAME_R]) + AC_DEFINE([HAVE_GETHOSTBYNAME_R_5_ARG], [1], [Define this if you have the 5-arg version of gethostbyname_r().]) - AC_MSG_RESULT(yes) + AC_MSG_RESULT([yes]) ], [ - AC_MSG_RESULT(no) + AC_MSG_RESULT([no]) AC_MSG_CHECKING([gethostbyname_r with 3 args]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ # include @@ -5309,69 +5553,69 @@ AC_CHECK_FUNC(gethostbyname_r, [ (void) gethostbyname_r(name, he, &data); ]])], [ - AC_DEFINE(HAVE_GETHOSTBYNAME_R) - AC_DEFINE(HAVE_GETHOSTBYNAME_R_3_ARG, 1, + AC_DEFINE([HAVE_GETHOSTBYNAME_R]) + AC_DEFINE([HAVE_GETHOSTBYNAME_R_3_ARG], [1], [Define this if you have the 3-arg version of gethostbyname_r().]) - AC_MSG_RESULT(yes) + AC_MSG_RESULT([yes]) ], [ - AC_MSG_RESULT(no) + AC_MSG_RESULT([no]) ]) ]) ]) CFLAGS=$OLD_CFLAGS ], [ - AC_CHECK_FUNCS(gethostbyname) + AC_CHECK_FUNCS([gethostbyname]) ]) -AC_SUBST(HAVE_GETHOSTBYNAME_R_6_ARG) -AC_SUBST(HAVE_GETHOSTBYNAME_R_5_ARG) -AC_SUBST(HAVE_GETHOSTBYNAME_R_3_ARG) -AC_SUBST(HAVE_GETHOSTBYNAME_R) -AC_SUBST(HAVE_GETHOSTBYNAME) +AC_SUBST([HAVE_GETHOSTBYNAME_R_6_ARG]) +AC_SUBST([HAVE_GETHOSTBYNAME_R_5_ARG]) +AC_SUBST([HAVE_GETHOSTBYNAME_R_3_ARG]) +AC_SUBST([HAVE_GETHOSTBYNAME_R]) +AC_SUBST([HAVE_GETHOSTBYNAME]) # checks for system services # (none yet) # Linux requires this for correct f.p. operations -AC_CHECK_FUNC(__fpu_control, +AC_CHECK_FUNC([__fpu_control], [], - [AC_CHECK_LIB(ieee, __fpu_control) + [AC_CHECK_LIB([ieee], [__fpu_control]) ]) # check for --with-libm=... -AC_SUBST(LIBM) +AC_SUBST([LIBM]) case $ac_sys_system in Darwin) ;; *) LIBM=-lm esac -AC_MSG_CHECKING(for --with-libm=STRING) -AC_ARG_WITH(libm, - AS_HELP_STRING([--with-libm=STRING], [override libm math library to STRING (default is system-dependent)]), +AC_MSG_CHECKING([for --with-libm=STRING]) +AC_ARG_WITH([libm], + [AS_HELP_STRING([--with-libm=STRING], [override libm math library to STRING (default is system-dependent)])], [ if test "$withval" = no then LIBM= - AC_MSG_RESULT(force LIBM empty) + AC_MSG_RESULT([force LIBM empty]) elif test "$withval" != yes then LIBM=$withval - AC_MSG_RESULT(set LIBM="$withval") + AC_MSG_RESULT([set LIBM="$withval"]) else AC_MSG_ERROR([proper usage is --with-libm=STRING]) fi], -[AC_MSG_RESULT(default LIBM="$LIBM")]) +[AC_MSG_RESULT([default LIBM="$LIBM"])]) # check for --with-libc=... -AC_SUBST(LIBC) -AC_MSG_CHECKING(for --with-libc=STRING) -AC_ARG_WITH(libc, - AS_HELP_STRING([--with-libc=STRING], [override libc C library to STRING (default is system-dependent)]), +AC_SUBST([LIBC]) +AC_MSG_CHECKING([for --with-libc=STRING]) +AC_ARG_WITH([libc], + [AS_HELP_STRING([--with-libc=STRING], [override libc C library to STRING (default is system-dependent)])], [ if test "$withval" = no then LIBC= - AC_MSG_RESULT(force LIBC empty) + AC_MSG_RESULT([force LIBC empty]) elif test "$withval" != yes then LIBC=$withval - AC_MSG_RESULT(set LIBC="$withval") + AC_MSG_RESULT([set LIBC="$withval"]) else AC_MSG_ERROR([proper usage is --with-libc=STRING]) fi], -[AC_MSG_RESULT(default LIBC="$LIBC")]) +[AC_MSG_RESULT([default LIBC="$LIBC"])]) # ************************************** # * Check for gcc x64 inline assembler * @@ -5385,7 +5629,7 @@ AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[ ]) AS_VAR_IF([ac_cv_gcc_asm_for_x64], [yes], [ - AC_DEFINE(HAVE_GCC_ASM_FOR_X64, 1, + AC_DEFINE([HAVE_GCC_ASM_FOR_X64], [1], [Define if we can use x64 gcc inline assembler]) ]) @@ -5396,12 +5640,12 @@ AS_VAR_IF([ac_cv_gcc_asm_for_x64], [yes], [ AX_C_FLOAT_WORDS_BIGENDIAN if test "$ax_cv_c_float_words_bigendian" = "yes" then - AC_DEFINE(DOUBLE_IS_BIG_ENDIAN_IEEE754, 1, + AC_DEFINE([DOUBLE_IS_BIG_ENDIAN_IEEE754], [1], [Define if C doubles are 64-bit IEEE 754 binary format, stored with the most significant byte first]) elif test "$ax_cv_c_float_words_bigendian" = "no" then - AC_DEFINE(DOUBLE_IS_LITTLE_ENDIAN_IEEE754, 1, + AC_DEFINE([DOUBLE_IS_LITTLE_ENDIAN_IEEE754], [1], [Define if C doubles are 64-bit IEEE 754 binary format, stored with the least significant byte first]) else @@ -5411,7 +5655,7 @@ else # conversions work. # FLOAT_WORDS_BIGENDIAN doesnt actually detect this case, but if it's not big # or little, then it must be this? - AC_DEFINE(DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754, 1, + AC_DEFINE([DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754], [1], [Define if C doubles are 64-bit IEEE 754 binary format, stored in ARM mixed-endian order (byte order 45670123)]) fi @@ -5434,7 +5678,7 @@ AC_LINK_IFELSE( [AC_LANG_PROGRAM([[]], [[ ]])],[ac_cv_gcc_asm_for_x87=yes],[ac_cv_gcc_asm_for_x87=no]) ]) AS_VAR_IF([ac_cv_gcc_asm_for_x87], [yes], [ - AC_DEFINE(HAVE_GCC_ASM_FOR_X87, 1, + AC_DEFINE([HAVE_GCC_ASM_FOR_X87], [1], [Define if we can use gcc inline assembler to get and set x87 control word]) ]) @@ -5446,7 +5690,7 @@ AC_LINK_IFELSE( [AC_LANG_PROGRAM([[]], [[ ]])],[ac_cv_gcc_asm_for_mc68881=yes],[ac_cv_gcc_asm_for_mc68881=no]) ]) AS_VAR_IF([ac_cv_gcc_asm_for_mc68881], [yes], [ - AC_DEFINE(HAVE_GCC_ASM_FOR_MC68881, 1, + AC_DEFINE([HAVE_GCC_ASM_FOR_MC68881], [1], [Define if we can use gcc inline assembler to get and set mc68881 fpcr]) ]) @@ -5486,7 +5730,7 @@ CC="$ac_save_cc" ]) AS_VAR_IF([ac_cv_x87_double_rounding], [yes], [ - AC_DEFINE(X87_DOUBLE_ROUNDING, 1, + AC_DEFINE([X87_DOUBLE_ROUNDING], [1], [Define if arithmetic is subject to x87-style double rounding issue]) ]) @@ -5578,11 +5822,11 @@ AS_VAR_IF([ac_cv_broken_sem_getvalue], [yes], [ ) ]) -AC_CHECK_DECLS([RTLD_LAZY, RTLD_NOW, RTLD_GLOBAL, RTLD_LOCAL, RTLD_NODELETE, RTLD_NOLOAD, RTLD_DEEPBIND, RTLD_MEMBER], [], [], [[#include ]]) +AC_CHECK_DECLS([RTLD_LAZY, RTLD_NOW, RTLD_GLOBAL, RTLD_LOCAL, RTLD_NODELETE, RTLD_NOLOAD, RTLD_DEEPBIND, RTLD_MEMBER], [], [], [[@%:@include ]]) # determine what size digit to use for Python's longs AC_MSG_CHECKING([digit size for Python's longs]) -AC_ARG_ENABLE(big-digits, +AC_ARG_ENABLE([big-digits], AS_HELP_STRING([--enable-big-digits@<:@=15|30@:>@],[use big digits (30 or 15 bits) for Python longs (default is 30)]]), [case $enable_big_digits in yes) @@ -5594,14 +5838,15 @@ no) *) AC_MSG_ERROR([bad value $enable_big_digits for --enable-big-digits; value should be 15 or 30]) ;; esac -AC_MSG_RESULT($enable_big_digits) -AC_DEFINE_UNQUOTED(PYLONG_BITS_IN_DIGIT, $enable_big_digits, [Define as the preferred size in bits of long digits]) +AC_MSG_RESULT([$enable_big_digits]) +AC_DEFINE_UNQUOTED([PYLONG_BITS_IN_DIGIT], [$enable_big_digits], + [Define as the preferred size in bits of long digits]) ], -[AC_MSG_RESULT(no value specified)]) +[AC_MSG_RESULT([no value specified])]) # check for wchar.h -AC_CHECK_HEADER(wchar.h, [ - AC_DEFINE(HAVE_WCHAR_H, 1, +AC_CHECK_HEADER([wchar.h], [ + AC_DEFINE([HAVE_WCHAR_H], [1], [Define if the compiler provides a wchar.h header file.]) wchar_h="yes" ], @@ -5611,7 +5856,9 @@ wchar_h="no" # determine wchar_t size if test "$wchar_h" = yes then - AC_CHECK_SIZEOF(wchar_t, 4, [#include ]) + AC_CHECK_SIZEOF([wchar_t], [4], [m4_normalize([ + #include + ])]) fi # check whether wchar_t is signed or not @@ -5632,18 +5879,18 @@ then [ac_cv_wchar_t_signed=yes])]) fi -AC_MSG_CHECKING(whether wchar_t is usable) +AC_MSG_CHECKING([whether wchar_t is usable]) # wchar_t is only usable if it maps to an unsigned type if test "$ac_cv_sizeof_wchar_t" -ge 2 \ -a "$ac_cv_wchar_t_signed" = "no" then - AC_DEFINE(HAVE_USABLE_WCHAR_T, 1, + AC_DEFINE([HAVE_USABLE_WCHAR_T], [1], [Define if you have a useable wchar_t type defined in wchar.h; useable means wchar_t must be an unsigned type with at least 16 bits. (see Include/unicodeobject.h).]) - AC_MSG_RESULT(yes) + AC_MSG_RESULT([yes]) else - AC_MSG_RESULT(no) + AC_MSG_RESULT([no]) fi case $ac_sys_system/$ac_sys_release in @@ -5654,7 +5901,7 @@ SunOS/*) # bpo-43667: In Oracle Solaris, the internal form of wchar_t in # non-Unicode locales is not Unicode and hence cannot be used directly. # https://docs.oracle.com/cd/E37838_01/html/E61053/gmwke.html - AC_DEFINE(HAVE_NON_UNICODE_WCHAR_T_REPRESENTATION, 1, + AC_DEFINE([HAVE_NON_UNICODE_WCHAR_T_REPRESENTATION], [1], [Define if the internal form of wchar_t in non-Unicode locales is not Unicode.]) fi @@ -5680,50 +5927,53 @@ AC_C_BIGENDIAN # # In Python 3.2 and older, --with-wide-unicode added a 'u' flag. # In Python 3.7 and older, --with-pymalloc added a 'm' flag. -AC_SUBST(SOABI) -AC_MSG_CHECKING(ABIFLAGS) -AC_MSG_RESULT($ABIFLAGS) -AC_MSG_CHECKING(SOABI) +AC_SUBST([SOABI]) +AC_MSG_CHECKING([ABIFLAGS]) +AC_MSG_RESULT([$ABIFLAGS]) +AC_MSG_CHECKING([SOABI]) SOABI='cpython-'`echo $VERSION | tr -d .`${ABIFLAGS}${PLATFORM_TRIPLET:+-$PLATFORM_TRIPLET} -AC_MSG_RESULT($SOABI) +AC_MSG_RESULT([$SOABI]) # Release and debug (Py_DEBUG) ABI are compatible, but not Py_TRACE_REFS ABI if test "$Py_DEBUG" = 'true' -a "$with_trace_refs" != "yes"; then # Similar to SOABI but remove "d" flag from ABIFLAGS - AC_SUBST(ALT_SOABI) + AC_SUBST([ALT_SOABI]) ALT_SOABI='cpython-'`echo $VERSION | tr -d .``echo $ABIFLAGS | tr -d d`${PLATFORM_TRIPLET:+-$PLATFORM_TRIPLET} - AC_DEFINE_UNQUOTED(ALT_SOABI, "${ALT_SOABI}", + AC_DEFINE_UNQUOTED([ALT_SOABI], ["${ALT_SOABI}"], [Alternative SOABI used in debug build to load C extensions built in release mode]) fi -AC_SUBST(EXT_SUFFIX) +AC_SUBST([EXT_SUFFIX]) EXT_SUFFIX=.${SOABI}${SHLIB_SUFFIX} -AC_MSG_CHECKING(LDVERSION) +AC_MSG_CHECKING([LDVERSION]) LDVERSION='$(VERSION)$(ABIFLAGS)' -AC_MSG_RESULT($LDVERSION) +AC_MSG_RESULT([$LDVERSION]) # On Android and Cygwin the shared libraries must be linked with libpython. -AC_SUBST(LIBPYTHON) -if test -n "$ANDROID_API_LEVEL" -o "$MACHDEP" = "cygwin"; then +AC_SUBST([LIBPYTHON]) +if test "$PY_ENABLE_SHARED" = "1" && ( test -n "$ANDROID_API_LEVEL" || test "$MACHDEP" = "cygwin"); then LIBPYTHON="-lpython${VERSION}${ABIFLAGS}" else LIBPYTHON='' fi -AC_SUBST(BINLIBDEST) +AC_SUBST([BINLIBDEST]) BINLIBDEST='$(LIBDIR)/python$(VERSION)' # Check for --with-platlibdir # /usr/$LIDIRNAME/python$VERSION -AC_SUBST(PLATLIBDIR) +AC_SUBST([PLATLIBDIR]) PLATLIBDIR="lib" -AC_MSG_CHECKING(for --with-platlibdir) -AC_ARG_WITH(platlibdir, - AS_HELP_STRING([--with-platlibdir=DIRNAME], - [Python library directory name (default is "lib")]), +AC_MSG_CHECKING([for --with-platlibdir]) +AC_ARG_WITH( + [platlibdir], + [AS_HELP_STRING( + [--with-platlibdir=DIRNAME], + [Python library directory name (default is "lib")] + )], [ # ignore 3 options: # --with-platlibdir @@ -5731,39 +5981,42 @@ AC_ARG_WITH(platlibdir, # --without-platlibdir if test -n "$withval" -a "$withval" != yes -a "$withval" != no then - AC_MSG_RESULT(yes) + AC_MSG_RESULT([yes]) PLATLIBDIR="$withval" BINLIBDEST='${exec_prefix}/${PLATLIBDIR}/python$(VERSION)' else - AC_MSG_RESULT(no) + AC_MSG_RESULT([no]) fi], -[AC_MSG_RESULT(no)]) +[AC_MSG_RESULT([no])]) dnl define LIBPL after ABIFLAGS and LDVERSION is defined. -AC_SUBST(PY_ENABLE_SHARED) +AC_SUBST([PY_ENABLE_SHARED]) if test x$PLATFORM_TRIPLET = x; then LIBPL='$(prefix)'"/${PLATLIBDIR}/python${VERSION}/config-${LDVERSION}" else LIBPL='$(prefix)'"/${PLATLIBDIR}/python${VERSION}/config-${LDVERSION}-${PLATFORM_TRIPLET}" fi -AC_SUBST(LIBPL) +AC_SUBST([LIBPL]) # Check for --with-wheel-pkg-dir=PATH -AC_SUBST(WHEEL_PKG_DIR) +AC_SUBST([WHEEL_PKG_DIR]) WHEEL_PKG_DIR="" -AC_MSG_CHECKING(for --with-wheel-pkg-dir) -AC_ARG_WITH(wheel-pkg-dir, - AS_HELP_STRING([--with-wheel-pkg-dir=PATH], - [Directory of wheel packages used by ensurepip (default: none)]), +AC_MSG_CHECKING([for --with-wheel-pkg-dir]) +AC_ARG_WITH( + [wheel-pkg-dir], + [AS_HELP_STRING( + [--with-wheel-pkg-dir=PATH], + [Directory of wheel packages used by ensurepip (default: none)] + )], [ if test -n "$withval"; then - AC_MSG_RESULT(yes) + AC_MSG_RESULT([yes]) WHEEL_PKG_DIR="$withval" else - AC_MSG_RESULT(no) + AC_MSG_RESULT([no]) fi], -[AC_MSG_RESULT(no)]) +[AC_MSG_RESULT([no])]) # Check whether right shifting a negative integer extends the sign bit # or fills with zeros (like the Cray J90, according to Tim Peters). @@ -5779,14 +6032,14 @@ int main(void) [ac_cv_rshift_extends_sign=yes])]) if test "$ac_cv_rshift_extends_sign" = no then - AC_DEFINE(SIGNED_RIGHT_SHIFT_ZERO_FILLS, 1, + AC_DEFINE([SIGNED_RIGHT_SHIFT_ZERO_FILLS], [1], [Define if i>>j for signed int i does not extend the sign bit when i < 0]) fi # check for getc_unlocked and related locking functions AC_CACHE_CHECK([for getc_unlocked() and friends], [ac_cv_have_getc_unlocked], [ -AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[ +AC_LINK_IFELSE([AC_LANG_PROGRAM([[@%:@include ]], [[ FILE *f = fopen("/dev/null", "r"); flockfile(f); getc_unlocked(f); @@ -5794,131 +6047,175 @@ AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[ ]])],[ac_cv_have_getc_unlocked=yes],[ac_cv_have_getc_unlocked=no])]) if test "$ac_cv_have_getc_unlocked" = yes then - AC_DEFINE(HAVE_GETC_UNLOCKED, 1, + AC_DEFINE([HAVE_GETC_UNLOCKED], [1], [Define this if you have flockfile(), getc_unlocked(), and funlockfile()]) fi -AC_ARG_WITH([readline], - [AS_HELP_STRING([--with(out)-readline@<:@=editline@:>@], - [use Editline for backend or disable readline module])], - [], - [with_readline=yes]) +dnl Check for libreadline and libedit +dnl - libreadline provides "readline/readline.h" header and "libreadline" +dnl shared library. pkg-config file is readline.pc +dnl - libedit provides "editline/readline.h" header and "libedit" shared +dnl library. pkg-config file ins libedit.pc +dnl - editline is not supported ("readline.h" and "libeditline" shared library) +dnl +dnl NOTE: In the past we checked if readline needs an additional termcap +dnl library (tinfo ncursesw ncurses termcap). We now assume that libreadline +dnl or readline.pc provide correct linker information. -# check where readline lives -py_cv_lib_readline=no -# save the value of LIBS so we don't actually link Python with readline -LIBS_no_readline=$LIBS +AH_TEMPLATE([WITH_EDITLINE], [Define to build the readline module against libedit.]) -if test "$with_readline" != no; then - case "$with_readline" in - editline|edit) - LIBREADLINE=edit - AC_DEFINE(WITH_EDITLINE, 1, - [Define to build the readline module against Editline.]) - ;; - yes|readline) +AC_ARG_WITH( + [readline], + [AS_HELP_STRING([--with(out)-readline@<:@=editline|readline|no@:>@], + [use libedit for backend or disable readline module])], + [ + AS_CASE([$with_readline], + [editline|edit], [with_readline=edit], + [yes|readline], [with_readline=readline], + [no], [], + [AC_MSG_ERROR([proper usage is --with(out)-readline@<:@=editline|readline|no@:>@])] + ) + ], + [with_readline=readline] +) + +AS_VAR_IF([with_readline], [readline], [ + PKG_CHECK_MODULES([LIBREADLINE], [readline], [ LIBREADLINE=readline - ;; - *) - AC_MSG_ERROR([proper usage is --with(out)-readline@<:@=editline@:>@]) - ;; - esac + READLINE_CFLAGS=$LIBREADLINE_CFLAGS + READLINE_LIBS=$LIBREADLINE_LIBS + ], [ + WITH_SAVE_ENV([ + CPPFLAGS="$CPPFLAGS $LIBREADLINE_CFLAGS" + LDFLAGS="$LDFLAGS $LIBREADLINE_LIBS" + AC_CHECK_HEADERS([readline/readline.h], [ + AC_CHECK_LIB([readline], [readline], [ + LIBREADLINE=readline + READLINE_CFLAGS=${LIBREADLINE_CFLAGS-""} + READLINE_LIBS=${LIBREADLINE_LIBS-"-lreadline"} + ], [with_readline=no]) + ], [with_readline=no]) + ]) + ]) +]) - # On some systems we need to link readline to a termcap compatible - # library. NOTE: Keep the precedence of listed libraries synchronised - # with setup.py. - AC_MSG_CHECKING([how to link readline libs]) - for py_libtermcap in "" tinfo ncursesw ncurses curses termcap; do - if test -z "$py_libtermcap"; then - READLINE_LIBS="-l$LIBREADLINE" - else - READLINE_LIBS="-l$LIBREADLINE -l$py_libtermcap" - fi - LIBS="$READLINE_LIBS $LIBS_no_readline" - AC_LINK_IFELSE( - [AC_LANG_CALL([],[readline])], - [py_cv_lib_readline=yes]) - if test $py_cv_lib_readline = yes; then - break - fi - done +AS_VAR_IF([with_readline], [edit], [ + PKG_CHECK_MODULES([LIBEDIT], [libedit], [ + AC_DEFINE([WITH_EDITLINE], [1]) + LIBREADLINE=edit + READLINE_CFLAGS=$LIBEDIT_CFLAGS + READLINE_LIBS=$LIBEDIT_LIBS + ], [ + WITH_SAVE_ENV([ + CPPFLAGS="$CPPFLAGS $LIBEDIT_CFLAGS" + LDFLAGS="$LDFLAGS $LIBEDIT_LIBS" + AC_CHECK_HEADERS([editline/readline.h], [ + AC_CHECK_LIB([edit], [readline], [ + LIBREADLINE=edit + AC_DEFINE([WITH_EDITLINE], [1]) + READLINE_CFLAGS=${LIBEDIT_CFLAGS-""} + READLINE_LIBS=${LIBEDIT_LIBS-"-ledit"} + ], [with_readline=no]) + ], [with_readline=no]) + ]) + ]) +]) - # Uncomment this line if you want to use READLINE_LIBS in Makefile or scripts - #AC_SUBST([READLINE_LIBS]) - if test $py_cv_lib_readline = no; then - AC_MSG_RESULT([none]) - else - AC_MSG_RESULT([$READLINE_LIBS]) - AC_DEFINE(HAVE_LIBREADLINE, 1, - [Define to build the readline module.]) - fi -fi +dnl pyconfig.h defines _XOPEN_SOURCE=700 +READLINE_CFLAGS=$(echo $READLINE_CFLAGS | sed 's/-D_XOPEN_SOURCE=600//g') -if test "$py_cv_lib_readline" = yes; then - # check for readline 2.2 - AC_CHECK_DECL(rl_completion_append_character, - AC_DEFINE(HAVE_RL_COMPLETION_APPEND_CHARACTER, 1, - [Define if you have readline 2.2]),, - [ -#include /* Must be first for Gnu Readline */ -#ifdef WITH_EDITLINE -# include -#else -# include -#endif +AC_MSG_CHECKING([how to link readline]) +AS_VAR_IF([with_readline], [no], [ + AC_MSG_RESULT([no]) +], [ + AC_MSG_RESULT([$with_readline (CFLAGS: $READLINE_CFLAGS, LIBS: $READLINE_LIBS)]) + + WITH_SAVE_ENV([ + CPPFLAGS="$CPPFLAGS $READLINE_CFLAGS" + LIBS="$READLINE_LIBS $LIBS" + LIBS_SAVE=$LIBS + + m4_define([readline_includes], [ + #include /* Must be first for Gnu Readline */ + #ifdef WITH_EDITLINE + # include + #else + # include + # include + #endif ]) - AC_CHECK_DECL(rl_completion_suppress_append, - AC_DEFINE(HAVE_RL_COMPLETION_SUPPRESS_APPEND, 1, - [Define if you have rl_completion_suppress_append]),, - [ -#include /* Must be first for Gnu Readline */ -#ifdef WITH_EDITLINE -# include -#else -# include -#endif + + # check for readline 2.2 + AC_CHECK_DECL([rl_completion_append_character], [ + AC_DEFINE([HAVE_RL_COMPLETION_APPEND_CHARACTER], [1], [Define if you have readline 2.2]) + ], [], [readline_includes]) + + AC_CHECK_DECL([rl_completion_suppress_append], [ + AC_DEFINE([HAVE_RL_COMPLETION_SUPPRESS_APPEND], [1], [Define if you have rl_completion_suppress_append]) + ], [], [readline_includes]) + + # check for readline 4.0 + AC_CACHE_CHECK([for rl_pre_input_hook in -l$LIBREADLINE], [ac_cv_readline_rl_pre_input_hook], [ + AC_LINK_IFELSE( + [AC_LANG_PROGRAM([readline_includes], [void *x = rl_pre_input_hook])], + [ac_cv_readline_rl_pre_input_hook=yes], [ac_cv_readline_rl_pre_input_hook=no] + ) + ]) + AS_VAR_IF([ac_cv_readline_rl_pre_input_hook], [yes], [ + AC_DEFINE([HAVE_RL_PRE_INPUT_HOOK], [1], [Define if you have readline 4.0]) ]) - # check for readline 4.0 - AC_CHECK_LIB($LIBREADLINE, rl_pre_input_hook, - AC_DEFINE(HAVE_RL_PRE_INPUT_HOOK, 1, - [Define if you have readline 4.0]),,$READLINE_LIBS) - - # also in 4.0 - AC_CHECK_LIB($LIBREADLINE, rl_completion_display_matches_hook, - AC_DEFINE(HAVE_RL_COMPLETION_DISPLAY_MATCHES_HOOK, 1, - [Define if you have readline 4.0]),,$READLINE_LIBS) - - # also in 4.0, but not in editline - AC_CHECK_LIB($LIBREADLINE, rl_resize_terminal, - AC_DEFINE(HAVE_RL_RESIZE_TERMINAL, 1, - [Define if you have readline 4.0]),,$READLINE_LIBS) - - # check for readline 4.2 - AC_CHECK_LIB($LIBREADLINE, rl_completion_matches, - AC_DEFINE(HAVE_RL_COMPLETION_MATCHES, 1, - [Define if you have readline 4.2]),,$READLINE_LIBS) - - # also in readline 4.2 - AC_CHECK_DECL(rl_catch_signals, - AC_DEFINE(HAVE_RL_CATCH_SIGNAL, 1, - [Define if you can turn off readline's signal handling.]),, - [ -#include /* Must be first for Gnu Readline */ -#ifdef WITH_EDITLINE -# include -#else -# include -#endif + # also in 4.0 + AC_CACHE_CHECK([for rl_completion_display_matches_hook in -l$LIBREADLINE], [ac_cv_readline_rl_completion_display_matches_hook], [ + AC_LINK_IFELSE( + [AC_LANG_PROGRAM([readline_includes], [void *x = rl_completion_display_matches_hook])], + [ac_cv_readline_rl_completion_display_matches_hook=yes], [ac_cv_readline_rl_completion_display_matches_hook=no] + ) + ]) + AS_VAR_IF([ac_cv_readline_rl_completion_display_matches_hook], [yes], [ + AC_DEFINE([HAVE_RL_COMPLETION_DISPLAY_MATCHES_HOOK], [1], [Define if you have readline 4.0]) ]) - AC_CHECK_LIB($LIBREADLINE, append_history, - AC_DEFINE(HAVE_RL_APPEND_HISTORY, 1, - [Define if readline supports append_history]),,$READLINE_LIBS) -fi + # also in 4.0, but not in editline + AC_CACHE_CHECK([for rl_resize_terminal in -l$LIBREADLINE], [ac_cv_readline_rl_resize_terminal], [ + AC_LINK_IFELSE( + [AC_LANG_PROGRAM([readline_includes], [void *x = rl_resize_terminal])], + [ac_cv_readline_rl_resize_terminal=yes], [ac_cv_readline_rl_resize_terminal=no] + ) + ]) + AS_VAR_IF([ac_cv_readline_rl_resize_terminal], [yes], [ + AC_DEFINE([HAVE_RL_RESIZE_TERMINAL], [1], [Define if you have readline 4.0]) + ]) -# End of readline checks: restore LIBS -LIBS=$LIBS_no_readline + # check for readline 4.2 + AC_CACHE_CHECK([for rl_completion_matches in -l$LIBREADLINE], [ac_cv_readline_rl_completion_matches], [ + AC_LINK_IFELSE( + [AC_LANG_PROGRAM([readline_includes], [void *x = rl_completion_matches])], + [ac_cv_readline_rl_completion_matches=yes], [ac_cv_readline_rl_completion_matches=no] + ) + ]) + AS_VAR_IF([ac_cv_readline_rl_completion_matches], [yes], [ + AC_DEFINE([HAVE_RL_COMPLETION_MATCHES], [1], [Define if you have readline 4.2]) + ]) + + # also in readline 4.2 + AC_CHECK_DECL([rl_catch_signals], [ + AC_DEFINE([HAVE_RL_CATCH_SIGNAL], [1], [Define if you can turn off readline's signal handling.]) + ], [], [readline_includes]) + + AC_CACHE_CHECK([for append_history in -l$LIBREADLINE], [ac_cv_readline_append_history], [ + AC_LINK_IFELSE( + [AC_LANG_PROGRAM([readline_includes], [void *x = append_history])], + [ac_cv_readline_append_history=yes], [ac_cv_readline_append_history=no] + ) + ]) + AS_VAR_IF([ac_cv_readline_append_history], [yes], [ + AC_DEFINE([HAVE_RL_APPEND_HISTORY], [1], [Define if readline supports append_history]) + ]) + + m4_undefine([readline_includes]) + ])dnl WITH_SAVE_ENV() +]) AC_CACHE_CHECK([for broken nice()], [ac_cv_broken_nice], [ AC_RUN_IFELSE([AC_LANG_SOURCE([[ @@ -5937,7 +6234,7 @@ int main(void) [ac_cv_broken_nice=no])]) if test "$ac_cv_broken_nice" = yes then - AC_DEFINE(HAVE_BROKEN_NICE, 1, + AC_DEFINE([HAVE_BROKEN_NICE], [1], [Define if nice() returns success/failure instead of the new priority.]) fi @@ -5967,7 +6264,7 @@ int main(void) [ac_cv_broken_poll=no])) if test "$ac_cv_broken_poll" = yes then - AC_DEFINE(HAVE_BROKEN_POLL, 1, + AC_DEFINE([HAVE_BROKEN_POLL], [1], [Define if poll() sets errno on invalid file descriptors.]) fi @@ -6042,13 +6339,13 @@ int main(void) [ac_cv_working_tzset=no])]) if test "$ac_cv_working_tzset" = yes then - AC_DEFINE(HAVE_WORKING_TZSET, 1, + AC_DEFINE([HAVE_WORKING_TZSET], [1], [Define if tzset() actually switches the local timezone in a meaningful way.]) fi # Look for subsecond timestamps in struct stat AC_CACHE_CHECK([for tv_nsec in struct stat], [ac_cv_stat_tv_nsec], -AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[ +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include ]], [[ struct stat st; st.st_mtim.tv_nsec = 1; ]])], @@ -6056,13 +6353,13 @@ st.st_mtim.tv_nsec = 1; [ac_cv_stat_tv_nsec=no])) if test "$ac_cv_stat_tv_nsec" = yes then - AC_DEFINE(HAVE_STAT_TV_NSEC, 1, + AC_DEFINE([HAVE_STAT_TV_NSEC], [1], [Define if you have struct stat.st_mtim.tv_nsec]) fi # Look for BSD style subsecond timestamps in struct stat AC_CACHE_CHECK([for tv_nsec2 in struct stat], [ac_cv_stat_tv_nsec2], -AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[ +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include ]], [[ struct stat st; st.st_mtimespec.tv_nsec = 1; ]])], @@ -6070,20 +6367,134 @@ st.st_mtimespec.tv_nsec = 1; [ac_cv_stat_tv_nsec2=no])) if test "$ac_cv_stat_tv_nsec2" = yes then - AC_DEFINE(HAVE_STAT_TV_NSEC2, 1, + AC_DEFINE([HAVE_STAT_TV_NSEC2], [1], [Define if you have struct stat.st_mtimensec]) fi +dnl check for ncurses/ncursesw and panel/panelw +dnl NOTE: old curses is not detected. +dnl have_curses=[no, ncursesw, ncurses] +dnl have_panel=[no, panelw, panel] +have_curses=no +have_panel=no + +AH_TEMPLATE([HAVE_NCURSESW], [Define to 1 if you have the `ncursesw' library.]) +AC_CHECK_HEADERS([curses.h ncurses.h]) + +AS_VAR_IF([ac_cv_header_ncurses_h], [yes], [ + if test "$ac_sys_system" != "Darwin"; then + dnl On macOS, there is no separate /usr/lib/libncursesw nor libpanelw. + PKG_CHECK_MODULES([CURSES], [ncursesw], [ + AC_DEFINE([HAVE_NCURSESW], [1]) + have_curses=ncursesw + ], [ + WITH_SAVE_ENV([ + AC_CHECK_LIB([ncursesw], [initscr], [ + AC_DEFINE([HAVE_NCURSESW], [1]) + have_curses=ncursesw + CURSES_CFLAGS=${CURSES_CFLAGS-""} + CURSES_LIBS=${CURSES_LIBS-"-lncursesw"} + ]) + ]) + ]) + fi + + AS_VAR_IF([have_curses], [no], [ + PKG_CHECK_MODULES([CURSES], [ncurses], [ + have_curses=ncurses + ], [ + WITH_SAVE_ENV([ + AC_CHECK_LIB([ncurses], [initscr], [ + have_curses=ncurses + CURSES_CFLAGS=${CURSES_CFLAGS-""} + CURSES_LIBS=${CURSES_LIBS-"-lncurses"} + ]) + ]) + ]) + ]) + +])dnl ac_cv_header_ncurses_h = yes + +dnl remove _XOPEN_SOURCE macro from curses cflags. pyconfig.h sets +dnl the macro to 700. +CURSES_CFLAGS=$(echo $CURSES_CFLAGS | sed 's/-D_XOPEN_SOURCE=600//g') + +if test "$have_curses" = no -a "$ac_sys_system" = "Darwin"; then + dnl On macOS, there is no separate /usr/lib/libncursesw nor libpanelw. + dnl If we are here, we found a locally-supplied version of libncursesw. + dnl There should also be a libpanelw. + dnl _XOPEN_SOURCE defines are usually excluded for macOS, but we need + dnl _XOPEN_SOURCE_EXTENDED here for ncurses wide char support. + + AS_VAR_APPEND([CURSES_CFLAGS], [" -D_XOPEN_SOURCE_EXTENDED=1"]) + AC_DEFINE([HAVE_NCURSESW], [1]) +fi + +dnl TODO: detect "curses" and special cases tinfo, terminfo, or termcap + +AC_MSG_CHECKING([curses module flags]) +AS_VAR_IF([have_curses], [no], [ + AC_MSG_RESULT([no]) +], [ + AC_MSG_RESULT([$have_curses (CFLAGS: $CURSES_CFLAGS, LIBS: $CURSES_LIBS)]) +]) + +dnl check for ncurses' panel/panelw library +AC_CHECK_HEADERS([panel.h]) + +AS_VAR_IF([ac_cv_header_panel_h], [yes], [ + + if test "$ac_sys_system" != "Darwin"; then + dnl On macOS, there is no separate /usr/lib/libncursesw nor libpanelw. + AS_VAR_IF([have_curses], [ncursesw], [ + PKG_CHECK_MODULES([PANEL], [panelw], [ + have_panel=panelw + ], [ + WITH_SAVE_ENV([ + AC_CHECK_LIB([panelw], [update_panels], [ + have_panel=panelw + PANEL_CFLAGS=${PANEL_CFLAGS-""} + PANEL_LIBS=${PANEL_LIBS-"-lpanelw"} + ]) + ]) + ]) + ]) + fi + + AS_VAR_IF([have_curses], [ncurses], [ + PKG_CHECK_MODULES([PANEL], [panel], [ + have_panel=panel + ], [ + WITH_SAVE_ENV([ + AC_CHECK_LIB([panel], [update_panels], [ + have_panel=panel + PANEL_CFLAGS=${PANEL_CFLAGS-""} + PANEL_LIBS=${PANEL_LIBS-"-lpanel"} + ]) + ]) + ]) + ]) + +])dnl ac_cv_header_panel_h = yes + +dnl pyconfig.h defines _XOPEN_SOURCE=700 +PANEL_CFLAGS=$(echo $PANEL_CFLAGS | sed 's/-D_XOPEN_SOURCE=600//g') + +AC_MSG_CHECKING([panel flags]) +AS_VAR_IF([have_panel], [no], [ + AC_MSG_RESULT([no]) +], [ + AC_MSG_RESULT([$have_panel (CFLAGS: $PANEL_CFLAGS, LIBS: $PANEL_LIBS)]) +]) + # first curses header check ac_save_cppflags="$CPPFLAGS" if test "$cross_compiling" = no; then CPPFLAGS="$CPPFLAGS -I/usr/include/ncursesw" fi -AC_CHECK_HEADERS(curses.h ncurses.h) - # On Solaris, term.h requires curses.h -AC_CHECK_HEADERS(term.h,,,[ +AC_CHECK_HEADERS([term.h], [], [], [ #ifdef HAVE_CURSES_H #include #endif @@ -6091,7 +6502,7 @@ AC_CHECK_HEADERS(term.h,,,[ # On HP/UX 11.0, mvwdelch is a block with a return statement AC_CACHE_CHECK([whether mvwdelch is an expression], [ac_cv_mvwdelch_is_expression], -AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[ +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include ]], [[ int rtn; rtn = mvwdelch(0,0,0); ]])], @@ -6100,7 +6511,7 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[ if test "$ac_cv_mvwdelch_is_expression" = yes then - AC_DEFINE(MVWDELCH_IS_EXPRESSION, 1, + AC_DEFINE([MVWDELCH_IS_EXPRESSION], [1], [Define if mvwdelch in curses.h is an expression.]) fi @@ -6122,7 +6533,7 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ if test "$ac_cv_window_has_flags" = yes then - AC_DEFINE(WINDOW_HAS_FLAGS, 1, + AC_DEFINE([WINDOW_HAS_FLAGS], [1], [Define if WINDOW in curses.h offers a field _flags.]) fi @@ -6135,7 +6546,7 @@ AC_DEFUN([PY_CHECK_CURSES_FUNC], [py_var], [AC_COMPILE_IFELSE( [AC_LANG_PROGRAM( - [#include ], [ + [@%:@include ], [ #ifndef $1 void *x=$1 #endif @@ -6180,14 +6591,14 @@ if test "x$cross_compiling" = xyes; then fi fi -AC_CHECK_FILE(/dev/ptmx, [], []) +AC_CHECK_FILE([/dev/ptmx], [], []) if test "x$ac_cv_file__dev_ptmx" = xyes; then - AC_DEFINE(HAVE_DEV_PTMX, 1, + AC_DEFINE([HAVE_DEV_PTMX], [1], [Define to 1 if you have the /dev/ptmx device file.]) fi -AC_CHECK_FILE(/dev/ptc, [], []) +AC_CHECK_FILE([/dev/ptc], [], []) if test "x$ac_cv_file__dev_ptc" = xyes; then - AC_DEFINE(HAVE_DEV_PTC, 1, + AC_DEFINE([HAVE_DEV_PTC], [1], [Define to 1 if you have the /dev/ptc device file.]) fi @@ -6196,55 +6607,12 @@ then LIBS="$LIBS -framework CoreFoundation" fi -AC_CACHE_CHECK([for %zd printf() format support], ac_cv_have_size_t_format, [dnl -AC_RUN_IFELSE([AC_LANG_SOURCE([[ -#include -#include -#include - -#ifdef HAVE_SYS_TYPES_H -#include -#endif - -#ifdef HAVE_SSIZE_T -typedef ssize_t Py_ssize_t; -#elif SIZEOF_VOID_P == SIZEOF_LONG -typedef long Py_ssize_t; -#else -typedef int Py_ssize_t; -#endif - -int main() -{ - char buffer[256]; - - if(sprintf(buffer, "%zd", (size_t)123) < 0) - return 1; - - if (strcmp(buffer, "123")) - return 1; - - if (sprintf(buffer, "%zd", (Py_ssize_t)-123) < 0) - return 1; - - if (strcmp(buffer, "-123")) - return 1; - - return 0; -} -]])], - [ac_cv_have_size_t_format=yes], - [ac_cv_have_size_t_format=no], - [ac_cv_have_size_t_format="cross -- assuming yes" -])]) -if test "$ac_cv_have_size_t_format" != no ; then - AC_DEFINE(PY_FORMAT_SIZE_T, "z", - [Define to printf format modifier for Py_ssize_t]) -fi - -AC_CHECK_TYPE(socklen_t,, - AC_DEFINE(socklen_t,int, - [Define to `int' if does not define.]),[ +AC_CHECK_TYPE( + [socklen_t], [], + [AC_DEFINE( + [socklen_t], [int], + [Define to `int' if does not define.] + )], [ #ifdef HAVE_SYS_TYPES_H #include #endif @@ -6270,31 +6638,34 @@ int main(void) { [ac_cv_broken_mbstowcs=no])) if test "$ac_cv_broken_mbstowcs" = yes then - AC_DEFINE(HAVE_BROKEN_MBSTOWCS, 1, + AC_DEFINE([HAVE_BROKEN_MBSTOWCS], [1], [Define if mbstowcs(NULL, "text", 0) does not return the number of wide chars that would be converted.]) fi # Check for --with-computed-gotos -AC_MSG_CHECKING(for --with-computed-gotos) -AC_ARG_WITH(computed-gotos, - AS_HELP_STRING([--with-computed-gotos], - [enable computed gotos in evaluation loop (enabled by default on supported compilers)]), +AC_MSG_CHECKING([for --with-computed-gotos]) +AC_ARG_WITH( + [computed-gotos], + [AS_HELP_STRING( + [--with-computed-gotos], + [enable computed gotos in evaluation loop (enabled by default on supported compilers)] + )], [ if test "$withval" = yes then - AC_DEFINE(USE_COMPUTED_GOTOS, 1, + AC_DEFINE([USE_COMPUTED_GOTOS], [1], [Define if you want to use computed gotos in ceval.c.]) - AC_MSG_RESULT(yes) + AC_MSG_RESULT([yes]) fi if test "$withval" = no then - AC_DEFINE(USE_COMPUTED_GOTOS, 0, + AC_DEFINE([USE_COMPUTED_GOTOS], [0], [Define if you want to use computed gotos in ceval.c.]) - AC_MSG_RESULT(no) + AC_MSG_RESULT([no]) fi ], -[AC_MSG_RESULT(no value specified)]) +[AC_MSG_RESULT([no value specified])]) AC_CACHE_CHECK([whether $CC supports computed gotos], [ac_cv_computed_gotos], AC_RUN_IFELSE([AC_LANG_SOURCE([[[ @@ -6317,35 +6688,37 @@ LABEL2: ac_cv_computed_gotos=no fi])) case "$ac_cv_computed_gotos" in yes*) - AC_DEFINE(HAVE_COMPUTED_GOTOS, 1, + AC_DEFINE([HAVE_COMPUTED_GOTOS], [1], [Define if the C compiler supports computed gotos.]) esac case $ac_sys_system in AIX*) - AC_DEFINE(HAVE_BROKEN_PIPE_BUF, 1, [Define if the system reports an invalid PIPE_BUF value.]) ;; + AC_DEFINE([HAVE_BROKEN_PIPE_BUF], [1], + [Define if the system reports an invalid PIPE_BUF value.]) ;; esac -AC_SUBST(THREADHEADERS) +AC_SUBST([THREADHEADERS]) for h in `(cd $srcdir;echo Python/thread_*.h)` do THREADHEADERS="$THREADHEADERS \$(srcdir)/$h" done -AC_SUBST(SRCDIRS) +AC_SUBST([SRCDIRS]) SRCDIRS="\ Modules \ Modules/_blake2 \ Modules/_ctypes \ Modules/_decimal \ Modules/_decimal/libmpdec \ + Modules/_hacl \ Modules/_io \ Modules/_multiprocessing \ - Modules/_sha3 \ Modules/_sqlite \ Modules/_sre \ + Modules/_testcapi \ Modules/_xxtestfuzz \ Modules/cjkcodecs \ Modules/expat \ @@ -6355,13 +6728,13 @@ SRCDIRS="\ Python \ Python/frozen_modules \ Python/deepfreeze" -AC_MSG_CHECKING(for build directories) +AC_MSG_CHECKING([for build directories]) for dir in $SRCDIRS; do if test ! -d $dir; then mkdir $dir fi done -AC_MSG_RESULT(done) +AC_MSG_RESULT([done]) # Availability of -O2: AC_CACHE_CHECK([for -O2], [ac_cv_compile_o2], [ @@ -6373,7 +6746,7 @@ CFLAGS="$saved_cflags" # _FORTIFY_SOURCE wrappers for memmove and bcopy are incorrect: # http://sourceware.org/ml/libc-alpha/2010-12/msg00009.html -AC_MSG_CHECKING(for glibc _FORTIFY_SOURCE/memmove bug) +AC_MSG_CHECKING([for glibc _FORTIFY_SOURCE/memmove bug]) saved_cflags="$CFLAGS" CFLAGS="-O2 -D_FORTIFY_SOURCE=2" if test "$ac_cv_compile_o2" = no; then @@ -6399,9 +6772,9 @@ int main(void) { [have_glibc_memmove_bug=yes], [have_glibc_memmove_bug=undefined]) CFLAGS="$saved_cflags" -AC_MSG_RESULT($have_glibc_memmove_bug) +AC_MSG_RESULT([$have_glibc_memmove_bug]) if test "$have_glibc_memmove_bug" = yes; then - AC_DEFINE(HAVE_GLIBC_MEMMOVE_BUG, 1, + AC_DEFINE([HAVE_GLIBC_MEMMOVE_BUG], [1], [Define if glibc has incorrect _FORTIFY_SOURCE wrappers for memmove and bcopy.]) fi @@ -6412,7 +6785,7 @@ if test "$ac_cv_gcc_asm_for_x87" = yes; then # http://gcc.gnu.org/ml/gcc/2010-11/msg00366.html case $CC in *gcc*) - AC_MSG_CHECKING(for gcc ipa-pure-const bug) + AC_MSG_CHECKING([for gcc ipa-pure-const bug]) saved_cflags="$CFLAGS" CFLAGS="-O2" AC_RUN_IFELSE([AC_LANG_SOURCE([[ @@ -6436,9 +6809,9 @@ if test "$ac_cv_gcc_asm_for_x87" = yes; then [have_ipa_pure_const_bug=yes], [have_ipa_pure_const_bug=undefined]) CFLAGS="$saved_cflags" - AC_MSG_RESULT($have_ipa_pure_const_bug) + AC_MSG_RESULT([$have_ipa_pure_const_bug]) if test "$have_ipa_pure_const_bug" = yes; then - AC_DEFINE(HAVE_IPA_PURE_CONST_BUG, 1, + AC_DEFINE([HAVE_IPA_PURE_CONST_BUG], [1], [Define if gcc has the ipa-pure-const bug.]) fi ;; @@ -6464,7 +6837,7 @@ AC_LINK_IFELSE( ]) AS_VAR_IF([ac_cv_header_stdatomic_h], [yes], [ - AC_DEFINE(HAVE_STD_ATOMIC, 1, + AC_DEFINE([HAVE_STD_ATOMIC], [1], [Has stdatomic.h with atomic_int and atomic_uintptr_t]) ]) @@ -6484,12 +6857,13 @@ AC_LINK_IFELSE( ]) AS_VAR_IF([ac_cv_builtin_atomic], [yes], [ - AC_DEFINE(HAVE_BUILTIN_ATOMIC, 1, [Has builtin __atomic_load_n() and __atomic_store_n() functions]) + AC_DEFINE([HAVE_BUILTIN_ATOMIC], [1], + [Has builtin __atomic_load_n() and __atomic_store_n() functions]) ]) # ensurepip option -AC_MSG_CHECKING(for ensurepip) -AC_ARG_WITH(ensurepip, +AC_MSG_CHECKING([for ensurepip]) +AC_ARG_WITH([ensurepip], [AS_HELP_STRING([--with-ensurepip@<:@=install|upgrade|no@:>@], ["install" or "upgrade" using bundled pip (default is upgrade)])], [], @@ -6500,13 +6874,13 @@ AC_ARG_WITH(ensurepip, [with_ensurepip=upgrade] ) ]) -AS_CASE($with_ensurepip, +AS_CASE([$with_ensurepip], [yes|upgrade],[ENSUREPIP=upgrade], [install],[ENSUREPIP=install], [no],[ENSUREPIP=no], [AC_MSG_ERROR([--with-ensurepip=upgrade|install|no])]) -AC_MSG_RESULT($ENSUREPIP) -AC_SUBST(ENSUREPIP) +AC_MSG_RESULT([$ENSUREPIP]) +AC_SUBST([ENSUREPIP]) # check if the dirent structure of a d_type field and DT_UNKNOWN is defined AC_CACHE_CHECK([if the dirent structure of a d_type field], [ac_cv_dirent_d_type], [ @@ -6524,7 +6898,7 @@ AC_LINK_IFELSE( ]) AS_VAR_IF([ac_cv_dirent_d_type], [yes], [ - AC_DEFINE(HAVE_DIRENT_D_TYPE, 1, + AC_DEFINE([HAVE_DIRENT_D_TYPE], [1], [Define to 1 if the dirent structure has a d_type field]) ]) @@ -6551,7 +6925,7 @@ AC_LINK_IFELSE( ]) AS_VAR_IF([ac_cv_getrandom_syscall], [yes], [ - AC_DEFINE(HAVE_GETRANDOM_SYSCALL, 1, + AC_DEFINE([HAVE_GETRANDOM_SYSCALL], [1], [Define to 1 if the Linux getrandom() syscall is available]) ]) @@ -6577,7 +6951,7 @@ AC_LINK_IFELSE( ]) AS_VAR_IF([ac_cv_func_getrandom], [yes], [ - AC_DEFINE(HAVE_GETRANDOM, 1, + AC_DEFINE([HAVE_GETRANDOM], [1], [Define to 1 if the getrandom() function is available]) ]) @@ -6612,8 +6986,8 @@ AS_VAR_IF([GNULD], [yes], [ rpath_arg="-Wl,-rpath=" ]) -AC_MSG_CHECKING(for --with-openssl-rpath) -AC_ARG_WITH(openssl-rpath, +AC_MSG_CHECKING([for --with-openssl-rpath]) +AC_ARG_WITH([openssl-rpath], AS_HELP_STRING([--with-openssl-rpath=@<:@DIR|auto|no@:>@], [Set runtime library directory (rpath) for OpenSSL libraries, no (default): don't set rpath, @@ -6623,7 +6997,7 @@ AC_ARG_WITH(openssl-rpath, [], [with_openssl_rpath=no] ) -AS_CASE($with_openssl_rpath, +AS_CASE([$with_openssl_rpath], [auto|yes], [ OPENSSL_RPATH=auto dnl look for linker directories @@ -6643,8 +7017,7 @@ AS_CASE($with_openssl_rpath, AC_MSG_ERROR([--with-openssl-rpath "$with_openssl_rpath" is not a directory])) ] ) -AC_MSG_RESULT($OPENSSL_RPATH) -AC_SUBST([OPENSSL_RPATH]) +AC_MSG_RESULT([$OPENSSL_RPATH]) # This static linking is NOT OFFICIALLY SUPPORTED and not advertised. # Requires static OpenSSL build with position-independent code. Some features @@ -6725,50 +7098,55 @@ WITH_SAVE_ENV([ ]) # ssl module default cipher suite string -AH_TEMPLATE(PY_SSL_DEFAULT_CIPHERS, +AH_TEMPLATE([PY_SSL_DEFAULT_CIPHERS], [Default cipher suites list for ssl module. 1: Python's preferred selection, 2: leave OpenSSL defaults untouched, 0: custom string]) -AH_TEMPLATE(PY_SSL_DEFAULT_CIPHER_STRING, +AH_TEMPLATE([PY_SSL_DEFAULT_CIPHER_STRING], [Cipher suite string for PY_SSL_DEFAULT_CIPHERS=0] ) -AC_MSG_CHECKING(for --with-ssl-default-suites) -AC_ARG_WITH(ssl-default-suites, - AS_HELP_STRING([--with-ssl-default-suites=@<:@python|openssl|STRING@:>@], - [override default cipher suites string, - python: use Python's preferred selection (default), - openssl: leave OpenSSL's defaults untouched, - STRING: use a custom string, - python and STRING also set TLS 1.2 as minimum TLS version]), +AC_MSG_CHECKING([for --with-ssl-default-suites]) +AC_ARG_WITH( + [ssl-default-suites], + [AS_HELP_STRING( + [--with-ssl-default-suites=@<:@python|openssl|STRING@:>@], + [override default cipher suites string, + python: use Python's preferred selection (default), + openssl: leave OpenSSL's defaults untouched, + STRING: use a custom string, + python and STRING also set TLS 1.2 as minimum TLS version] + )], [ -AC_MSG_RESULT($withval) +AC_MSG_RESULT([$withval]) case "$withval" in python) - AC_DEFINE(PY_SSL_DEFAULT_CIPHERS, 1) + AC_DEFINE([PY_SSL_DEFAULT_CIPHERS], [1]) ;; openssl) - AC_DEFINE(PY_SSL_DEFAULT_CIPHERS, 2) + AC_DEFINE([PY_SSL_DEFAULT_CIPHERS], [2]) ;; *) - AC_DEFINE(PY_SSL_DEFAULT_CIPHERS, 0) - AC_DEFINE_UNQUOTED(PY_SSL_DEFAULT_CIPHER_STRING, "$withval") + AC_DEFINE([PY_SSL_DEFAULT_CIPHERS], [0]) + AC_DEFINE_UNQUOTED([PY_SSL_DEFAULT_CIPHER_STRING], ["$withval"]) ;; esac ], [ -AC_MSG_RESULT(python) -AC_DEFINE(PY_SSL_DEFAULT_CIPHERS, 1) +AC_MSG_RESULT([python]) +AC_DEFINE([PY_SSL_DEFAULT_CIPHERS], [1]) ]) # builtin hash modules -default_hashlib_hashes="md5,sha1,sha256,sha512,sha3,blake2" +default_hashlib_hashes="md5,sha1,sha2,sha3,blake2" AC_DEFINE([PY_BUILTIN_HASHLIB_HASHES], [], [enabled builtin hash modules] ) -AC_MSG_CHECKING(for --with-builtin-hashlib-hashes) -AC_ARG_WITH(builtin-hashlib-hashes, - AS_HELP_STRING([--with-builtin-hashlib-hashes=md5,sha1,sha256,sha512,sha3,blake2], - [builtin hash modules, - md5, sha1, sha256, sha512, sha3 (with shake), blake2]), +AC_MSG_CHECKING([for --with-builtin-hashlib-hashes]) +AC_ARG_WITH( + [builtin-hashlib-hashes], + [AS_HELP_STRING( + [--with-builtin-hashlib-hashes=md5,sha1,sha2,sha3,blake2], + [builtin hash modules, md5, sha1, sha2, sha3 (with shake), blake2] + )], [ AS_CASE([$with_builtin_hashlib_hashes], [yes], [with_builtin_hashlib_hashes=$default_hashlib_hashes], @@ -6776,17 +7154,17 @@ AC_ARG_WITH(builtin-hashlib-hashes, ) ], [with_builtin_hashlib_hashes=$default_hashlib_hashes]) -AC_MSG_RESULT($with_builtin_hashlib_hashes) -AC_DEFINE_UNQUOTED(PY_BUILTIN_HASHLIB_HASHES, "$with_builtin_hashlib_hashes") +AC_MSG_RESULT([$with_builtin_hashlib_hashes]) +AC_DEFINE_UNQUOTED([PY_BUILTIN_HASHLIB_HASHES], + ["$with_builtin_hashlib_hashes"]) as_save_IFS=$IFS IFS=, for builtin_hash in $with_builtin_hashlib_hashes; do - AS_CASE($builtin_hash, + AS_CASE([$builtin_hash], [md5], [with_builtin_md5=yes], [sha1], [with_builtin_sha1=yes], - [sha256], [with_builtin_sha256=yes], - [sha512], [with_builtin_sha512=yes], + [sha2], [with_builtin_sha2=yes], [sha3], [with_builtin_sha3=yes], [blake2], [with_builtin_blake2=yes] ) @@ -6850,6 +7228,7 @@ AS_CASE([$ac_sys_system], [_scproxy], [_tkinter], [_xxsubinterpreters], + [_xxinterpchannels], [grp], [nis], [ossaudiodev], @@ -6891,17 +7270,6 @@ AS_CASE([$host_cpu], ) AC_SUBST([MODULE_BUILDTYPE]) -dnl Use Modules/Setup.stdlib as additional provider? -AC_MSG_CHECKING([for additional Modules/Setup files]) -AS_CASE([$ac_sys_system], - [Emscripten], [MODULES_SETUP_STDLIB=Modules/Setup.stdlib], - [WASI], [MODULES_SETUP_STDLIB=Modules/Setup.stdlib], - [MODULES_SETUP_STDLIB=] -) -AC_MSG_RESULT([$MODULES_SETUP_STDLIB]) -AC_SUBST([MODULES_SETUP_STDLIB]) - - dnl _MODULE_BLOCK_ADD([VAR], [VALUE]) dnl internal: adds $1=quote($2) to MODULE_BLOCK AC_DEFUN([_MODULE_BLOCK_ADD], [AS_VAR_APPEND([MODULE_BLOCK], ["$1=_AS_QUOTE([$2])$as_nl"])]) @@ -6923,7 +7291,7 @@ AC_DEFUN([PY_STDLIB_MOD], [ m4_pushdef([modstate], [py_cv_module_$1])dnl dnl Check if module has been disabled by PY_STDLIB_MOD_SET_NA() AS_IF([test "$modstate" != "n/a"], [ - AS_IF(m4_ifblank([$2], [true], [$2]), + AS_IF([m4_ifblank([$2], [true], [$2])], [AS_IF([m4_ifblank([$3], [true], [$3])], [modstate=yes], [modstate=missing])], [modstate=disabled]) ]) @@ -6979,6 +7347,7 @@ PY_STDLIB_MOD_SIMPLE([select]) PY_STDLIB_MOD_SIMPLE([_struct]) PY_STDLIB_MOD_SIMPLE([_typing]) PY_STDLIB_MOD_SIMPLE([_xxsubinterpreters]) +PY_STDLIB_MOD_SIMPLE([_xxinterpchannels]) PY_STDLIB_MOD_SIMPLE([_zoneinfo]) dnl multiprocessing modules @@ -7024,7 +7393,9 @@ PY_STDLIB_MOD([syslog], [], [test "$ac_cv_header_syslog_h" = yes]) PY_STDLIB_MOD([termios], [], [test "$ac_cv_header_termios_h" = yes]) dnl _elementtree loads libexpat via CAPI hook in pyexpat -PY_STDLIB_MOD([pyexpat], [], [], [$LIBEXPAT_CFLAGS], [$LIBEXPAT_LDFLAGS]) +PY_STDLIB_MOD([pyexpat], + [], [test "$ac_cv_header_sys_time_h" = "yes"], + [$LIBEXPAT_CFLAGS], [$LIBEXPAT_LDFLAGS]) PY_STDLIB_MOD([_elementtree], [], [], [$LIBEXPAT_CFLAGS], []) PY_STDLIB_MOD_SIMPLE([_codecs_cn]) PY_STDLIB_MOD_SIMPLE([_codecs_hk]) @@ -7037,10 +7408,15 @@ PY_STDLIB_MOD_SIMPLE([unicodedata]) dnl By default we always compile these even when OpenSSL is available dnl (issue #14693). The modules are small. -PY_STDLIB_MOD([_md5], [test "$with_builtin_md5" = yes]) -PY_STDLIB_MOD([_sha1], [test "$with_builtin_sha1" = yes]) -PY_STDLIB_MOD([_sha256], [test "$with_builtin_sha256" = yes]) -PY_STDLIB_MOD([_sha512], [test "$with_builtin_sha512" = yes]) +PY_STDLIB_MOD([_md5], + [test "$with_builtin_md5" = yes], [], + [-I\$(srcdir)/Modules/_hacl/include -I\$(srcdir)/Modules/_hacl/internal -D_BSD_SOURCE -D_DEFAULT_SOURCE]) +PY_STDLIB_MOD([_sha1], + [test "$with_builtin_sha1" = yes], [], + [-I\$(srcdir)/Modules/_hacl/include -I\$(srcdir)/Modules/_hacl/internal -D_BSD_SOURCE -D_DEFAULT_SOURCE]) +PY_STDLIB_MOD([_sha2], + [test "$with_builtin_sha2" = yes], [], + [-I\$(srcdir)/Modules/_hacl/include -I\$(srcdir)/Modules/_hacl/internal -D_BSD_SOURCE -D_DEFAULT_SOURCE]) PY_STDLIB_MOD([_sha3], [test "$with_builtin_sha3" = yes]) PY_STDLIB_MOD([_blake2], [test "$with_builtin_blake2" = yes], [], @@ -7049,18 +7425,30 @@ PY_STDLIB_MOD([_blake2], PY_STDLIB_MOD([_crypt], [], [test "$ac_cv_crypt_crypt" = yes], [$LIBCRYPT_CFLAGS], [$LIBCRYPT_LIBS]) -dnl PY_STDLIB_MOD([_ctypes], [], [], [], []) -dnl PY_STDLIB_MOD([_curses], [], [], [], []) -dnl PY_STDLIB_MOD([_curses_panel], [], [], [], []) +PY_STDLIB_MOD([_ctypes], + [], [test "$have_libffi" = yes], + [$NO_STRICT_OVERFLOW_CFLAGS $LIBFFI_CFLAGS], [$LIBFFI_LIBS]) +PY_STDLIB_MOD([_curses], + [], [test "$have_curses" != "no"], + [$CURSES_CFLAGS], [$CURSES_LIBS] +) +PY_STDLIB_MOD([_curses_panel], + [], [test "$have_panel" != "no"], + [$PANEL_CFLAGS $CURSES_CFLAGS], [$PANEL_LIBS $CURSES_LIBS] +) PY_STDLIB_MOD([_decimal], [], [], [$LIBMPDEC_CFLAGS], [$LIBMPDEC_LDFLAGS]) -dnl PY_STDLIB_MOD([_dbm], [], [], [], []) +PY_STDLIB_MOD([_dbm], + [test -n "$with_dbmliborder"], [test "$have_dbm" != "no"], + [$DBM_CFLAGS], [$DBM_LIBS]) PY_STDLIB_MOD([_gdbm], [test "$have_gdbm_dbmliborder" = yes], [test "$have_gdbm" = yes], [$GDBM_CFLAGS], [$GDBM_LIBS]) PY_STDLIB_MOD([nis], [], [test "$have_nis" = yes -a "$ac_cv_header_rpc_rpc_h" = yes], [$LIBNSL_CFLAGS], [$LIBNSL_LIBS]) -dnl PY_STDLIB_MOD([readline], [], [], [], []) + PY_STDLIB_MOD([readline], + [], [test "$with_readline" != "no"], + [$READLINE_CFLAGS], [$READLINE_LIBS]) PY_STDLIB_MOD([_sqlite3], [test "$have_sqlite3" = "yes"], [test "$have_supported_sqlite3" = "yes"], @@ -7095,8 +7483,11 @@ PY_STDLIB_MOD([_testinternalcapi], [test "$TEST_MODULES" = yes]) PY_STDLIB_MOD([_testbuffer], [test "$TEST_MODULES" = yes]) PY_STDLIB_MOD([_testimportmultiple], [test "$TEST_MODULES" = yes], [test "$ac_cv_func_dlopen" = yes]) PY_STDLIB_MOD([_testmultiphase], [test "$TEST_MODULES" = yes], [test "$ac_cv_func_dlopen" = yes]) +PY_STDLIB_MOD([xxsubtype], [test "$TEST_MODULES" = yes]) PY_STDLIB_MOD([_xxtestfuzz], [test "$TEST_MODULES" = yes]) -PY_STDLIB_MOD([_ctypes_test], [test "$TEST_MODULES" = yes], [test "$ac_cv_func_dlopen" = yes], [], [-lm]) +PY_STDLIB_MOD([_ctypes_test], + [test "$TEST_MODULES" = yes], [test "$have_libffi" = yes -a "$ac_cv_func_dlopen" = yes], + [], [$LIBM]) dnl Limited API template modules. dnl The limited C API is not compatible with the Py_TRACE_REFS macro. @@ -7108,8 +7499,16 @@ PY_STDLIB_MOD([xxlimited_35], [test "$with_trace_refs" = "no"], [test "$ac_cv_fu AC_SUBST([MODULE_BLOCK]) # generate output files -AC_CONFIG_FILES(Makefile.pre Misc/python.pc Misc/python-embed.pc Misc/python-config.sh) -AC_CONFIG_FILES([Modules/Setup.bootstrap Modules/Setup.stdlib]) +AC_CONFIG_FILES(m4_normalize([ + Makefile.pre + Misc/python.pc + Misc/python-embed.pc + Misc/python-config.sh +])) +AC_CONFIG_FILES(m4_normalize([ + Modules/Setup.bootstrap + Modules/Setup.stdlib +])) AC_CONFIG_FILES([Modules/ld_so_aix], [chmod +x Modules/ld_so_aix]) AC_OUTPUT @@ -7122,7 +7521,11 @@ fi AC_MSG_NOTICE([creating Makefile]) $SHELL $srcdir/Modules/makesetup -c $srcdir/Modules/config.c.in \ -s Modules \ - Modules/Setup.local $MODULES_SETUP_STDLIB Modules/Setup.bootstrap $srcdir/Modules/Setup + Modules/Setup.local Modules/Setup.stdlib Modules/Setup.bootstrap $srcdir/Modules/Setup +if test $? -ne 0; then + AC_MSG_ERROR([makesetup failed]) +fi + mv config.c Modules if test -z "$PKG_CONFIG"; then diff --git a/pyconfig.h.in b/pyconfig.h.in index 75f1d90e..ada9dccf 100644 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -19,6 +19,9 @@ /* The normal alignment of `long', in bytes. */ #undef ALIGNOF_LONG +/* The normal alignment of `max_align_t', in bytes. */ +#undef ALIGNOF_MAX_ALIGN_T + /* The normal alignment of `size_t', in bytes. */ #undef ALIGNOF_SIZE_T @@ -302,6 +305,9 @@ /* Defined when any dynamic module loading is enabled. */ #undef HAVE_DYNAMIC_LOADING +/* Define to 1 if you have the header file. */ +#undef HAVE_EDITLINE_READLINE_H + /* Define to 1 if you have the header file. */ #undef HAVE_ENDIAN_H @@ -368,6 +374,15 @@ /* Define to 1 if you have the `fexecve' function. */ #undef HAVE_FEXECVE +/* Define if you have the 'ffi_closure_alloc' function. */ +#undef HAVE_FFI_CLOSURE_ALLOC + +/* Define if you have the 'ffi_prep_cif_var' function. */ +#undef HAVE_FFI_PREP_CIF_VAR + +/* Define if you have the 'ffi_prep_closure_loc' function. */ +#undef HAVE_FFI_PREP_CLOSURE_LOC + /* Define to 1 if you have the `flock' function. */ #undef HAVE_FLOCK @@ -664,21 +679,12 @@ /* Define to 1 if you have the `dld' library (-ldld). */ #undef HAVE_LIBDLD -/* Define to 1 if you have the `gdbm_compat' library (-lgdbm_compat). */ -#undef HAVE_LIBGDBM_COMPAT - /* Define to 1 if you have the `ieee' library (-lieee). */ #undef HAVE_LIBIEEE /* Define to 1 if you have the header file. */ #undef HAVE_LIBINTL_H -/* Define to 1 if you have the `ndbm' library (-lndbm). */ -#undef HAVE_LIBNDBM - -/* Define to build the readline module. */ -#undef HAVE_LIBREADLINE - /* Define to 1 if you have the `resolv' library (-lresolv). */ #undef HAVE_LIBRESOLV @@ -718,6 +724,12 @@ /* Define if compiling using Linux 4.1 or later. */ #undef HAVE_LINUX_CAN_RAW_JOIN_FILTERS +/* Define to 1 if you have the header file. */ +#undef HAVE_LINUX_FS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_LINUX_LIMITS_H + /* Define to 1 if you have the header file. */ #undef HAVE_LINUX_MEMFD_H @@ -781,12 +793,12 @@ /* Define if you have the 'memfd_create' function. */ #undef HAVE_MEMFD_CREATE -/* Define to 1 if you have the header file. */ -#undef HAVE_MEMORY_H - /* Define to 1 if you have the `memrchr' function. */ #undef HAVE_MEMRCHR +/* Define to 1 if you have the header file. */ +#undef HAVE_MINIX_CONFIG_H + /* Define to 1 if you have the `mkdirat' function. */ #undef HAVE_MKDIRAT @@ -814,6 +826,9 @@ /* Define to 1 if you have the `nanosleep' function. */ #undef HAVE_NANOSLEEP +/* Define to 1 if you have the `ncursesw' library. */ +#undef HAVE_NCURSESW + /* Define to 1 if you have the header file. */ #undef HAVE_NCURSES_H @@ -835,6 +850,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_NETPACKET_PACKET_H +/* Define to 1 if you have the header file. */ +#undef HAVE_NET_ETHERNET_H + /* Define to 1 if you have the header file. */ #undef HAVE_NET_IF_H @@ -854,6 +872,9 @@ /* Define to 1 if you have the `openpty' function. */ #undef HAVE_OPENPTY +/* Define to 1 if you have the header file. */ +#undef HAVE_PANEL_H + /* Define to 1 if you have the `pathconf' function. */ #undef HAVE_PATHCONF @@ -941,6 +962,9 @@ /* Define to 1 if you have the `pwritev2' function. */ #undef HAVE_PWRITEV2 +/* Define to 1 if you have the header file. */ +#undef HAVE_READLINE_READLINE_H + /* Define to 1 if you have the `readlink' function. */ #undef HAVE_READLINK @@ -1052,6 +1076,9 @@ /* Define to 1 if you have the `setlocale' function. */ #undef HAVE_SETLOCALE +/* Define to 1 if you have the `setns' function. */ +#undef HAVE_SETNS + /* Define to 1 if you have the `setpgid' function. */ #undef HAVE_SETPGID @@ -1166,13 +1193,12 @@ /* Define if you have struct stat.st_mtimensec */ #undef HAVE_STAT_TV_NSEC2 -/* Define if your compiler supports variable length function prototypes (e.g. - void fprintf(FILE *, char *, ...);) *and* */ -#undef HAVE_STDARG_PROTOTYPES - /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H +/* Define to 1 if you have the header file. */ +#undef HAVE_STDIO_H + /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H @@ -1426,6 +1452,9 @@ /* Define to 1 if you have the `unlinkat' function. */ #undef HAVE_UNLINKAT +/* Define to 1 if you have the `unshare' function. */ +#undef HAVE_UNSHARE + /* Define if you have a useable wchar_t type defined in wchar.h; useable means wchar_t must be an unsigned type with at least 16 bits. (see Include/unicodeobject.h). */ @@ -1557,8 +1586,8 @@ /* Define if you want to coerce the C locale to a UTF-8 based locale */ #undef PY_COERCE_C_LOCALE -/* Define to printf format modifier for Py_ssize_t */ -#undef PY_FORMAT_SIZE_T +/* Define to 1 if you have the perf trampoline. */ +#undef PY_HAVE_PERF_TRAMPOLINE /* Define to 1 to build the sqlite module with loadable extensions support. */ #undef PY_SQLITE_ENABLE_LOAD_EXTENSION @@ -1668,9 +1697,6 @@ /* Library needed by timemodule.c: librt may be needed for clock_gettime() */ #undef TIMEMODULE_LIB -/* Define to 1 if you can safely include both and . */ -#undef TIME_WITH_SYS_TIME - /* Define to 1 if your declares `struct tm'. */ #undef TM_IN_SYS_TIME @@ -1681,21 +1707,87 @@ #ifndef _ALL_SOURCE # undef _ALL_SOURCE #endif +/* Enable general extensions on macOS. */ +#ifndef _DARWIN_C_SOURCE +# undef _DARWIN_C_SOURCE +#endif +/* Enable general extensions on Solaris. */ +#ifndef __EXTENSIONS__ +# undef __EXTENSIONS__ +#endif /* Enable GNU extensions on systems that have them. */ #ifndef _GNU_SOURCE # undef _GNU_SOURCE #endif -/* Enable threading extensions on Solaris. */ +/* Enable X/Open compliant socket functions that do not require linking + with -lxnet on HP-UX 11.11. */ +#ifndef _HPUX_ALT_XOPEN_SOCKET_API +# undef _HPUX_ALT_XOPEN_SOCKET_API +#endif +/* Identify the host operating system as Minix. + This macro does not affect the system headers' behavior. + A future release of Autoconf may stop defining this macro. */ +#ifndef _MINIX +# undef _MINIX +#endif +/* Enable general extensions on NetBSD. + Enable NetBSD compatibility extensions on Minix. */ +#ifndef _NETBSD_SOURCE +# undef _NETBSD_SOURCE +#endif +/* Enable OpenBSD compatibility extensions on NetBSD. + Oddly enough, this does nothing on OpenBSD. */ +#ifndef _OPENBSD_SOURCE +# undef _OPENBSD_SOURCE +#endif +/* Define to 1 if needed for POSIX-compatible behavior. */ +#ifndef _POSIX_SOURCE +# undef _POSIX_SOURCE +#endif +/* Define to 2 if needed for POSIX-compatible behavior. */ +#ifndef _POSIX_1_SOURCE +# undef _POSIX_1_SOURCE +#endif +/* Enable POSIX-compatible threading on Solaris. */ #ifndef _POSIX_PTHREAD_SEMANTICS # undef _POSIX_PTHREAD_SEMANTICS #endif +/* Enable extensions specified by ISO/IEC TS 18661-5:2014. */ +#ifndef __STDC_WANT_IEC_60559_ATTRIBS_EXT__ +# undef __STDC_WANT_IEC_60559_ATTRIBS_EXT__ +#endif +/* Enable extensions specified by ISO/IEC TS 18661-1:2014. */ +#ifndef __STDC_WANT_IEC_60559_BFP_EXT__ +# undef __STDC_WANT_IEC_60559_BFP_EXT__ +#endif +/* Enable extensions specified by ISO/IEC TS 18661-2:2015. */ +#ifndef __STDC_WANT_IEC_60559_DFP_EXT__ +# undef __STDC_WANT_IEC_60559_DFP_EXT__ +#endif +/* Enable extensions specified by ISO/IEC TS 18661-4:2015. */ +#ifndef __STDC_WANT_IEC_60559_FUNCS_EXT__ +# undef __STDC_WANT_IEC_60559_FUNCS_EXT__ +#endif +/* Enable extensions specified by ISO/IEC TS 18661-3:2015. */ +#ifndef __STDC_WANT_IEC_60559_TYPES_EXT__ +# undef __STDC_WANT_IEC_60559_TYPES_EXT__ +#endif +/* Enable extensions specified by ISO/IEC TR 24731-2:2010. */ +#ifndef __STDC_WANT_LIB_EXT2__ +# undef __STDC_WANT_LIB_EXT2__ +#endif +/* Enable extensions specified by ISO/IEC 24747:2009. */ +#ifndef __STDC_WANT_MATH_SPEC_FUNCS__ +# undef __STDC_WANT_MATH_SPEC_FUNCS__ +#endif /* Enable extensions on HP NonStop. */ #ifndef _TANDEM_SOURCE # undef _TANDEM_SOURCE #endif -/* Enable general extensions on Solaris. */ -#ifndef __EXTENSIONS__ -# undef __EXTENSIONS__ +/* Enable X/Open extensions. Define to 500 only if necessary + to make mbstate_t available. */ +#ifndef _XOPEN_SOURCE +# undef _XOPEN_SOURCE #endif @@ -1717,7 +1809,7 @@ Dyld is necessary to support frameworks. */ #undef WITH_DYLD -/* Define to build the readline module against Editline. */ +/* Define to build the readline module against libedit. */ #undef WITH_EDITLINE /* Define if you want to compile in object freelists optimization */ @@ -1769,22 +1861,12 @@ /* This must be defined on AIX systems to enable large file support. */ #undef _LARGE_FILES -/* Define to 1 if on MINIX. */ -#undef _MINIX - /* Define on NetBSD to activate all library features */ #undef _NETBSD_SOURCE -/* Define to 2 if the system does not provide POSIX.1 features except with - this defined. */ -#undef _POSIX_1_SOURCE - /* Define to activate features from IEEE Stds 1003.1-2008 */ #undef _POSIX_C_SOURCE -/* Define to 1 if you need to in order for `stat' and other things to work. */ -#undef _POSIX_SOURCE - /* Define if you have POSIX threads, and your system does not define that. */ #undef _POSIX_THREADS @@ -1827,7 +1909,7 @@ /* Define to `long int' if does not define. */ #undef off_t -/* Define to `int' if does not define. */ +/* Define as a signed integer type capable of holding a process identifier. */ #undef pid_t /* Define to empty if the keyword does not work. */ diff --git a/setup.py b/setup.py deleted file mode 100644 index 4f122b62..00000000 --- a/setup.py +++ /dev/null @@ -1,1628 +0,0 @@ -# Autodetecting setup.py script for building the Python extensions - -import argparse -import importlib._bootstrap -import importlib.machinery -import importlib.util -import logging -import os -import re -import shlex -import sys -import sysconfig -import warnings -from glob import glob, escape -import _osx_support - - -try: - import subprocess - del subprocess - SUBPROCESS_BOOTSTRAP = False -except ImportError: - # Bootstrap Python: distutils.spawn uses subprocess to build C extensions, - # subprocess requires C extensions built by setup.py like _posixsubprocess. - # - # Use _bootsubprocess which only uses the os module. - # - # It is dropped from sys.modules as soon as all C extension modules - # are built. - import _bootsubprocess - sys.modules['subprocess'] = _bootsubprocess - del _bootsubprocess - SUBPROCESS_BOOTSTRAP = True - - -with warnings.catch_warnings(): - # bpo-41282 (PEP 632) deprecated distutils but setup.py still uses it - warnings.filterwarnings( - "ignore", - "The distutils package is deprecated", - DeprecationWarning - ) - warnings.filterwarnings( - "ignore", - "The distutils.sysconfig module is deprecated, use sysconfig instead", - DeprecationWarning - ) - - from distutils.command.build_ext import build_ext - from distutils.command.build_scripts import build_scripts - from distutils.command.install import install - from distutils.command.install_lib import install_lib - from distutils.core import Extension, setup - from distutils.errors import CCompilerError, DistutilsError - from distutils.spawn import find_executable - - -# This global variable is used to hold the list of modules to be disabled. -DISABLED_MODULE_LIST = [] - -# --list-module-names option used by Tools/scripts/generate_module_names.py -LIST_MODULE_NAMES = False - - -logging.basicConfig(format='%(message)s', level=logging.INFO) -log = logging.getLogger('setup') - - -def get_platform(): - # Cross compiling - if "_PYTHON_HOST_PLATFORM" in os.environ: - return os.environ["_PYTHON_HOST_PLATFORM"] - - # Get value of sys.platform - if sys.platform.startswith('osf1'): - return 'osf1' - return sys.platform - - -CROSS_COMPILING = ("_PYTHON_HOST_PLATFORM" in os.environ) -HOST_PLATFORM = get_platform() -MS_WINDOWS = (HOST_PLATFORM == 'win32') -CYGWIN = (HOST_PLATFORM == 'cygwin') -MACOS = (HOST_PLATFORM == 'darwin') -AIX = (HOST_PLATFORM.startswith('aix')) -VXWORKS = ('vxworks' in HOST_PLATFORM) -EMSCRIPTEN = HOST_PLATFORM == 'emscripten-wasm32' -CC = os.environ.get("CC") -if not CC: - CC = sysconfig.get_config_var("CC") - -if EMSCRIPTEN: - # emcc is a Python script from a different Python interpreter. - os.environ.pop("PYTHONPATH", None) - - -SUMMARY = """ -Python is an interpreted, interactive, object-oriented programming -language. It is often compared to Tcl, Perl, Scheme or Java. - -Python combines remarkable power with very clear syntax. It has -modules, classes, exceptions, very high level dynamic data types, and -dynamic typing. There are interfaces to many system calls and -libraries, as well as to various windowing systems (X11, Motif, Tk, -Mac, MFC). New built-in modules are easily written in C or C++. Python -is also usable as an extension language for applications that need a -programmable interface. - -The Python implementation is portable: it runs on many brands of UNIX, -on Windows, DOS, Mac, Amiga... If your favorite system isn't -listed here, it may still be supported, if there's a C compiler for -it. Ask around on comp.lang.python -- or just try compiling Python -yourself. -""" - -CLASSIFIERS = """ -Development Status :: 6 - Mature -License :: OSI Approved :: Python Software Foundation License -Natural Language :: English -Programming Language :: C -Programming Language :: Python -Topic :: Software Development -""" - - -def run_command(cmd): - status = os.system(cmd) - return os.waitstatus_to_exitcode(status) - - -# Set common compiler and linker flags derived from the Makefile, -# reserved for building the interpreter and the stdlib modules. -# See bpo-21121 and bpo-35257 -def set_compiler_flags(compiler_flags, compiler_py_flags_nodist): - flags = sysconfig.get_config_var(compiler_flags) - py_flags_nodist = sysconfig.get_config_var(compiler_py_flags_nodist) - sysconfig.get_config_vars()[compiler_flags] = flags + ' ' + py_flags_nodist - - -def add_dir_to_list(dirlist, dir): - """Add the directory 'dir' to the list 'dirlist' (after any relative - directories) if: - - 1) 'dir' is not already in 'dirlist' - 2) 'dir' actually exists, and is a directory. - """ - if dir is None or not os.path.isdir(dir) or dir in dirlist: - return - for i, path in enumerate(dirlist): - if not os.path.isabs(path): - dirlist.insert(i + 1, 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 - - -MACOS_SDK_ROOT = None -MACOS_SDK_SPECIFIED = None - -def macosx_sdk_root(): - """Return the directory of the current macOS SDK. - - If no SDK was explicitly configured, call the compiler to find which - include files paths are being searched by default. Use '/' if the - compiler is searching /usr/include (meaning system header files are - installed) or use the root of an SDK if that is being searched. - (The SDK may be supplied via Xcode or via the Command Line Tools). - The SDK paths used by Apple-supplied tool chains depend on the - setting of various variables; see the xcrun man page for more info. - Also sets MACOS_SDK_SPECIFIED for use by macosx_sdk_specified(). - """ - global MACOS_SDK_ROOT, MACOS_SDK_SPECIFIED - - # If already called, return cached result. - if MACOS_SDK_ROOT: - return MACOS_SDK_ROOT - - cflags = sysconfig.get_config_var('CFLAGS') - m = re.search(r'-isysroot\s*(\S+)', cflags) - if m is not None: - MACOS_SDK_ROOT = m.group(1) - MACOS_SDK_SPECIFIED = MACOS_SDK_ROOT != '/' - else: - MACOS_SDK_ROOT = _osx_support._default_sysroot( - sysconfig.get_config_var('CC')) - MACOS_SDK_SPECIFIED = False - - return MACOS_SDK_ROOT - - -def is_macosx_sdk_path(path): - """ - Returns True if 'path' can be located in a macOS SDK - """ - return ( (path.startswith('/usr/') and not path.startswith('/usr/local')) - or path.startswith('/System/Library') - or path.startswith('/System/iOSSupport') ) - - -def grep_headers_for(function, headers): - for header in headers: - with open(header, 'r', errors='surrogateescape') as f: - if function in f.read(): - return True - return False - - -def find_file(filename, std_dirs, paths): - """Searches for the directory where a given file is located, - and returns a possibly-empty list of additional directories, or None - if the file couldn't be found at all. - - 'filename' is the name of a file, such as readline.h or libcrypto.a. - 'std_dirs' is the list of standard system directories; if the - file is found in one of them, no additional directives are needed. - 'paths' is a list of additional locations to check; if the file is - found in one of them, the resulting list will contain the directory. - """ - if MACOS: - # Honor the MacOSX SDK setting when one was specified. - # An SDK is a directory with the same structure as a real - # system, but with only header files and libraries. - sysroot = macosx_sdk_root() - - # Check the standard locations - for dir_ in std_dirs: - f = os.path.join(dir_, filename) - - if MACOS and is_macosx_sdk_path(dir_): - f = os.path.join(sysroot, dir_[1:], filename) - - if os.path.exists(f): return [] - - # Check the additional directories - for dir_ in paths: - f = os.path.join(dir_, filename) - - if MACOS and is_macosx_sdk_path(dir_): - f = os.path.join(sysroot, dir_[1:], filename) - - if os.path.exists(f): - return [dir_] - - # Not found anywhere - return None - - -def validate_tzpath(): - base_tzpath = sysconfig.get_config_var('TZPATH') - if not base_tzpath: - return - - tzpaths = base_tzpath.split(os.pathsep) - bad_paths = [tzpath for tzpath in tzpaths if not os.path.isabs(tzpath)] - if bad_paths: - raise ValueError('TZPATH must contain only absolute paths, ' - + f'found:\n{tzpaths!r}\nwith invalid paths:\n' - + f'{bad_paths!r}') - - -def find_module_file(module, dirlist): - """Find a module in a set of possible folders. If it is not found - return the unadorned filename""" - dirs = find_file(module, [], dirlist) - if not dirs: - return module - if len(dirs) > 1: - log.info(f"WARNING: multiple copies of {module} found") - return os.path.abspath(os.path.join(dirs[0], module)) - - -class PyBuildExt(build_ext): - - def __init__(self, dist): - build_ext.__init__(self, dist) - self.srcdir = None - self.lib_dirs = None - self.inc_dirs = None - self.config_h_vars = None - self.failed = [] - self.failed_on_import = [] - self.missing = [] - self.disabled_configure = [] - if '-j' in os.environ.get('MAKEFLAGS', ''): - self.parallel = True - - def add(self, ext): - self.extensions.append(ext) - - def addext(self, ext, *, update_flags=True): - """Add extension with Makefile MODULE_{name} support - """ - if update_flags: - self.update_extension_flags(ext) - - state = sysconfig.get_config_var(f"MODULE_{ext.name.upper()}_STATE") - if state == "yes": - self.extensions.append(ext) - elif state == "disabled": - self.disabled_configure.append(ext.name) - elif state == "missing": - self.missing.append(ext.name) - elif state == "n/a": - # not available on current platform - pass - else: - # not migrated to MODULE_{name}_STATE yet. - self.announce( - f'WARNING: Makefile is missing module variable for "{ext.name}"', - level=2 - ) - self.extensions.append(ext) - - def update_extension_flags(self, ext): - """Update extension flags with module CFLAGS and LDFLAGS - - Reads MODULE_{name}_CFLAGS and _LDFLAGS - - Distutils appends extra args to the compiler arguments. Some flags like - -I must appear earlier, otherwise the pre-processor picks up files - from system include directories. - """ - upper_name = ext.name.upper() - # Parse compiler flags (-I, -D, -U, extra args) - cflags = sysconfig.get_config_var(f"MODULE_{upper_name}_CFLAGS") - if cflags: - for token in shlex.split(cflags): - switch = token[0:2] - value = token[2:] - if switch == '-I': - ext.include_dirs.append(value) - elif switch == '-D': - key, _, val = value.partition("=") - if not val: - val = None - ext.define_macros.append((key, val)) - elif switch == '-U': - ext.undef_macros.append(value) - else: - ext.extra_compile_args.append(token) - - # Parse linker flags (-L, -l, extra objects, extra args) - ldflags = sysconfig.get_config_var(f"MODULE_{upper_name}_LDFLAGS") - if ldflags: - for token in shlex.split(ldflags): - switch = token[0:2] - value = token[2:] - if switch == '-L': - ext.library_dirs.append(value) - elif switch == '-l': - ext.libraries.append(value) - elif ( - token[0] != '-' and - token.endswith(('.a', '.o', '.so', '.sl', '.dylib')) - ): - ext.extra_objects.append(token) - else: - ext.extra_link_args.append(token) - - return ext - - def set_srcdir(self): - self.srcdir = sysconfig.get_config_var('srcdir') - if not self.srcdir: - # Maybe running on Windows but not using CYGWIN? - raise ValueError("No source directory; cannot proceed.") - self.srcdir = os.path.abspath(self.srcdir) - - def remove_disabled(self): - # Remove modules that are present on the disabled list - extensions = [ext for ext in self.extensions - if ext.name not in DISABLED_MODULE_LIST] - # move ctypes to the end, it depends on other modules - ext_map = dict((ext.name, i) for i, ext in enumerate(extensions)) - if "_ctypes" in ext_map: - ctypes = extensions.pop(ext_map["_ctypes"]) - extensions.append(ctypes) - self.extensions = extensions - - def update_sources_depends(self): - # Fix up the autodetected modules, prefixing all the source files - # with Modules/. - # Add dependencies from MODULE_{name}_DEPS variable - moddirlist = [ - # files in Modules/ directory - os.path.join(self.srcdir, 'Modules'), - # files relative to build base, e.g. libmpdec.a, libexpat.a - os.getcwd() - ] - - # Fix up the paths for scripts, too - self.distribution.scripts = [os.path.join(self.srcdir, filename) - for filename in self.distribution.scripts] - - # Python header files - include_dir = escape(sysconfig.get_path('include')) - headers = [sysconfig.get_config_h_filename()] - headers.extend(glob(os.path.join(include_dir, "*.h"))) - headers.extend(glob(os.path.join(include_dir, "cpython", "*.h"))) - headers.extend(glob(os.path.join(include_dir, "internal", "*.h"))) - - for ext in self.extensions: - ext.sources = [ find_module_file(filename, moddirlist) - for filename in ext.sources ] - # Update dependencies from Makefile - makedeps = sysconfig.get_config_var(f"MODULE_{ext.name.upper()}_DEPS") - if makedeps: - # remove backslashes from line break continuations - ext.depends.extend( - dep for dep in makedeps.split() if dep != "\\" - ) - ext.depends = [ - find_module_file(filename, moddirlist) for filename in ext.depends - ] - # re-compile extensions if a header file has been changed - ext.depends.extend(headers) - - def handle_configured_extensions(self): - # The sysconfig variables built by makesetup that list the already - # built modules and the disabled modules as configured by the Setup - # files. - sysconf_built = set(sysconfig.get_config_var('MODBUILT_NAMES').split()) - sysconf_shared = set(sysconfig.get_config_var('MODSHARED_NAMES').split()) - sysconf_dis = set(sysconfig.get_config_var('MODDISABLED_NAMES').split()) - - mods_built = [] - mods_disabled = [] - for ext in self.extensions: - # If a module has already been built or has been disabled in the - # Setup files, don't build it here. - if ext.name in sysconf_built: - mods_built.append(ext) - if ext.name in sysconf_dis: - mods_disabled.append(ext) - - mods_configured = mods_built + mods_disabled - if mods_configured: - self.extensions = [x for x in self.extensions if x not in - mods_configured] - # Remove the shared libraries built by a previous build. - for ext in mods_configured: - # Don't remove shared extensions which have been built - # by Modules/Setup - if ext.name in sysconf_shared: - continue - fullpath = self.get_ext_fullpath(ext.name) - if os.path.lexists(fullpath): - os.unlink(fullpath) - - return mods_built, mods_disabled - - def set_compiler_executables(self): - # When you run "make CC=altcc" or something similar, you really want - # those environment variables passed into the setup.py phase. Here's - # a small set of useful ones. - compiler = os.environ.get('CC') - args = {} - # unfortunately, distutils doesn't let us provide separate C and C++ - # compilers - if compiler is not None: - (ccshared,cflags) = sysconfig.get_config_vars('CCSHARED','CFLAGS') - args['compiler_so'] = compiler + ' ' + ccshared + ' ' + cflags - self.compiler.set_executables(**args) - - def build_extensions(self): - self.set_srcdir() - self.set_compiler_executables() - self.configure_compiler() - self.init_inc_lib_dirs() - - # Detect which modules should be compiled - self.detect_modules() - - if not LIST_MODULE_NAMES: - self.remove_disabled() - - self.update_sources_depends() - mods_built, mods_disabled = self.handle_configured_extensions() - - if LIST_MODULE_NAMES: - for ext in self.extensions: - print(ext.name) - for name in self.missing: - print(name) - return - - build_ext.build_extensions(self) - - if SUBPROCESS_BOOTSTRAP: - # Drop our custom subprocess module: - # use the newly built subprocess module - del sys.modules['subprocess'] - - for ext in self.extensions: - self.check_extension_import(ext) - - self.summary(mods_built, mods_disabled) - - def summary(self, mods_built, mods_disabled): - longest = max([len(e.name) for e in self.extensions], default=0) - if self.failed or self.failed_on_import: - all_failed = self.failed + self.failed_on_import - longest = max(longest, max([len(name) for name in all_failed])) - - def print_three_column(lst): - lst.sort(key=str.lower) - # guarantee zip() doesn't drop anything - while len(lst) % 3: - lst.append("") - for e, f, g in zip(lst[::3], lst[1::3], lst[2::3]): - print("%-*s %-*s %-*s" % (longest, e, longest, f, - longest, g)) - - if self.missing: - print() - print("The necessary bits to build these optional modules were not " - "found:") - print_three_column(self.missing) - print("To find the necessary bits, look in setup.py in" - " detect_modules() for the module's name.") - print() - - if mods_built: - print() - print("The following modules found by detect_modules() in" - " setup.py, have been") - print("built by the Makefile instead, as configured by the" - " Setup files:") - print_three_column([ext.name for ext in mods_built]) - print() - - if mods_disabled: - print() - print("The following modules found by detect_modules() in" - " setup.py have not") - print("been built, they are *disabled* in the Setup files:") - print_three_column([ext.name for ext in mods_disabled]) - print() - - if self.disabled_configure: - print() - print("The following modules found by detect_modules() in" - " setup.py have not") - print("been built, they are *disabled* by configure:") - print_three_column(self.disabled_configure) - print() - - if self.failed: - failed = self.failed[:] - print() - print("Failed to build these modules:") - print_three_column(failed) - print() - - if self.failed_on_import: - failed = self.failed_on_import[:] - print() - print("Following modules built successfully" - " but were removed because they could not be imported:") - print_three_column(failed) - print() - - if any('_ssl' in l - for l in (self.missing, self.failed, self.failed_on_import)): - print() - print("Could not build the ssl module!") - print("Python requires a OpenSSL 1.1.1 or newer") - if sysconfig.get_config_var("OPENSSL_LDFLAGS"): - print("Custom linker flags may require --with-openssl-rpath=auto") - print() - - if os.environ.get("PYTHONSTRICTEXTENSIONBUILD") and ( - self.failed or self.failed_on_import or self.missing - ): - raise RuntimeError("Failed to build some stdlib modules") - - def build_extension(self, ext): - - if ext.name == '_ctypes': - if not self.configure_ctypes(ext): - self.failed.append(ext.name) - return - - try: - build_ext.build_extension(self, ext) - except (CCompilerError, DistutilsError) as why: - self.announce('WARNING: building of extension "%s" failed: %s' % - (ext.name, why)) - self.failed.append(ext.name) - return - - def check_extension_import(self, ext): - # Don't try to import an extension that has failed to compile - if ext.name in self.failed: - self.announce( - 'WARNING: skipping import check for failed build "%s"' % - ext.name, level=1) - return - - # Workaround for Mac OS X: The Carbon-based modules cannot be - # reliably imported into a command-line Python - if 'Carbon' in ext.extra_link_args: - self.announce( - 'WARNING: skipping import check for Carbon-based "%s"' % - ext.name) - return - - if MACOS and ( - sys.maxsize > 2**32 and '-arch' in ext.extra_link_args): - # Don't bother doing an import check when an extension was - # build with an explicit '-arch' flag on OSX. That's currently - # only used to build 32-bit only extensions in a 4-way - # universal build and loading 32-bit code into a 64-bit - # process will fail. - self.announce( - 'WARNING: skipping import check for "%s"' % - ext.name) - return - - # Workaround for Cygwin: Cygwin currently has fork issues when many - # modules have been imported - if CYGWIN: - self.announce('WARNING: skipping import check for Cygwin-based "%s"' - % ext.name) - return - ext_filename = os.path.join( - self.build_lib, - self.get_ext_filename(self.get_ext_fullname(ext.name))) - - # If the build directory didn't exist when setup.py was - # started, sys.path_importer_cache has a negative result - # cached. Clear that cache before trying to import. - sys.path_importer_cache.clear() - - # Don't try to load extensions for cross builds - if CROSS_COMPILING: - return - - loader = importlib.machinery.ExtensionFileLoader(ext.name, ext_filename) - spec = importlib.util.spec_from_file_location(ext.name, ext_filename, - loader=loader) - try: - importlib._bootstrap._load(spec) - except ImportError as why: - self.failed_on_import.append(ext.name) - self.announce('*** WARNING: renaming "%s" since importing it' - ' failed: %s' % (ext.name, why), level=3) - assert not self.inplace - basename, tail = os.path.splitext(ext_filename) - newname = basename + "_failed" + tail - if os.path.exists(newname): - os.remove(newname) - os.rename(ext_filename, newname) - - except: - exc_type, why, tb = sys.exc_info() - self.announce('*** WARNING: importing extension "%s" ' - 'failed with %s: %s' % (ext.name, exc_type, why), - level=3) - self.failed.append(ext.name) - - def add_multiarch_paths(self): - # Debian/Ubuntu multiarch support. - # https://wiki.ubuntu.com/MultiarchSpec - tmpfile = os.path.join(self.build_temp, 'multiarch') - if not os.path.exists(self.build_temp): - os.makedirs(self.build_temp) - ret = run_command( - '%s -print-multiarch > %s 2> /dev/null' % (CC, tmpfile)) - multiarch_path_component = '' - try: - if ret == 0: - with open(tmpfile) as fp: - multiarch_path_component = fp.readline().strip() - finally: - os.unlink(tmpfile) - - if multiarch_path_component != '': - add_dir_to_list(self.compiler.library_dirs, - '/usr/lib/' + multiarch_path_component) - add_dir_to_list(self.compiler.include_dirs, - '/usr/include/' + multiarch_path_component) - return - - if not find_executable('dpkg-architecture'): - return - opt = '' - if CROSS_COMPILING: - opt = '-t' + sysconfig.get_config_var('HOST_GNU_TYPE') - tmpfile = os.path.join(self.build_temp, 'multiarch') - if not os.path.exists(self.build_temp): - os.makedirs(self.build_temp) - ret = run_command( - 'dpkg-architecture %s -qDEB_HOST_MULTIARCH > %s 2> /dev/null' % - (opt, tmpfile)) - try: - if ret == 0: - with open(tmpfile) as fp: - multiarch_path_component = fp.readline().strip() - add_dir_to_list(self.compiler.library_dirs, - '/usr/lib/' + multiarch_path_component) - add_dir_to_list(self.compiler.include_dirs, - '/usr/include/' + multiarch_path_component) - finally: - os.unlink(tmpfile) - - def add_wrcc_search_dirs(self): - # add library search path by wr-cc, the compiler wrapper - - def convert_mixed_path(path): - # convert path like C:\folder1\folder2/folder3/folder4 - # to msys style /c/folder1/folder2/folder3/folder4 - drive = path[0].lower() - left = path[2:].replace("\\", "/") - return "/" + drive + left - - def add_search_path(line): - # On Windows building machine, VxWorks does - # cross builds under msys2 environment. - pathsep = (";" if sys.platform == "msys" else ":") - for d in line.strip().split("=")[1].split(pathsep): - d = d.strip() - if sys.platform == "msys": - # On Windows building machine, compiler - # returns mixed style path like: - # C:\folder1\folder2/folder3/folder4 - d = convert_mixed_path(d) - d = os.path.normpath(d) - add_dir_to_list(self.compiler.library_dirs, d) - - tmpfile = os.path.join(self.build_temp, 'wrccpaths') - os.makedirs(self.build_temp, exist_ok=True) - try: - ret = run_command('%s --print-search-dirs >%s' % (CC, tmpfile)) - if ret: - return - with open(tmpfile) as fp: - # Parse paths in libraries line. The line is like: - # On Linux, "libraries: = path1:path2:path3" - # On Windows, "libraries: = path1;path2;path3" - for line in fp: - if not line.startswith("libraries"): - continue - add_search_path(line) - finally: - try: - os.unlink(tmpfile) - except OSError: - pass - - def add_cross_compiling_paths(self): - tmpfile = os.path.join(self.build_temp, 'ccpaths') - if not os.path.exists(self.build_temp): - os.makedirs(self.build_temp) - # bpo-38472: With a German locale, GCC returns "gcc-Version 9.1.0 - # (GCC)", whereas it returns "gcc version 9.1.0" with the C locale. - ret = run_command('LC_ALL=C %s -E -v - %s 1>/dev/null' % (CC, tmpfile)) - is_gcc = False - is_clang = False - in_incdirs = False - try: - if ret == 0: - with open(tmpfile) as fp: - for line in fp.readlines(): - if line.startswith("gcc version"): - is_gcc = True - elif line.startswith("clang version"): - is_clang = True - elif line.startswith("#include <...>"): - in_incdirs = True - elif line.startswith("End of search list"): - in_incdirs = False - elif (is_gcc or is_clang) and line.startswith("LIBRARY_PATH"): - for d in line.strip().split("=")[1].split(":"): - d = os.path.normpath(d) - if '/gcc/' not in d: - add_dir_to_list(self.compiler.library_dirs, - d) - elif (is_gcc or is_clang) and in_incdirs and '/gcc/' not in line and '/clang/' not in line: - add_dir_to_list(self.compiler.include_dirs, - line.strip()) - finally: - os.unlink(tmpfile) - - if VXWORKS: - self.add_wrcc_search_dirs() - - def add_ldflags_cppflags(self): - # Add paths specified in the environment variables LDFLAGS and - # CPPFLAGS for header and library files. - # We must get the values from the Makefile and not the environment - # directly since an inconsistently reproducible issue comes up where - # the environment variable is not set even though the value were passed - # into configure and stored in the Makefile (issue found on OS X 10.3). - for env_var, arg_name, dir_list in ( - ('LDFLAGS', '-R', self.compiler.runtime_library_dirs), - ('LDFLAGS', '-L', self.compiler.library_dirs), - ('CPPFLAGS', '-I', self.compiler.include_dirs)): - env_val = sysconfig.get_config_var(env_var) - if env_val: - parser = argparse.ArgumentParser() - parser.add_argument(arg_name, dest="dirs", action="append") - - # To prevent argparse from raising an exception about any - # options in env_val that it mistakes for known option, we - # strip out all double dashes and any dashes followed by a - # character that is not for the option we are dealing with. - # - # Please note that order of the regex is important! We must - # strip out double-dashes first so that we don't end up with - # substituting "--Long" to "-Long" and thus lead to "ong" being - # used for a library directory. - env_val = re.sub(r'(^|\s+)-(-|(?!%s))' % arg_name[1], - ' ', env_val) - options, _ = parser.parse_known_args(env_val.split()) - if options.dirs: - for directory in reversed(options.dirs): - add_dir_to_list(dir_list, directory) - - def configure_compiler(self): - # Ensure that /usr/local is always used, but the local build - # directories (i.e. '.' and 'Include') must be first. See issue - # 10520. - if not CROSS_COMPILING: - add_dir_to_list(self.compiler.library_dirs, '/usr/local/lib') - add_dir_to_list(self.compiler.include_dirs, '/usr/local/include') - # only change this for cross builds for 3.3, issues on Mageia - if CROSS_COMPILING: - self.add_cross_compiling_paths() - self.add_multiarch_paths() - self.add_ldflags_cppflags() - - def init_inc_lib_dirs(self): - if (not CROSS_COMPILING and - os.path.normpath(sys.base_prefix) != '/usr' and - not sysconfig.get_config_var('PYTHONFRAMEWORK')): - # OSX note: Don't add LIBDIR and INCLUDEDIR to building a framework - # (PYTHONFRAMEWORK is set) to avoid # linking problems when - # building a framework with different architectures than - # the one that is currently installed (issue #7473) - add_dir_to_list(self.compiler.library_dirs, - sysconfig.get_config_var("LIBDIR")) - 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: - self.lib_dirs = self.compiler.library_dirs + system_lib_dirs - self.inc_dirs = self.compiler.include_dirs + system_include_dirs - else: - # Add the sysroot paths. 'sysroot' is a compiler option used to - # set the logical path of the standard system headers and - # libraries. - self.lib_dirs = (self.compiler.library_dirs + - sysroot_paths(('LDFLAGS', 'CC'), system_lib_dirs)) - self.inc_dirs = (self.compiler.include_dirs + - sysroot_paths(('CPPFLAGS', 'CFLAGS', 'CC'), - system_include_dirs)) - - config_h = sysconfig.get_config_h_filename() - with open(config_h) as file: - self.config_h_vars = sysconfig.parse_config_h(file) - - # OSF/1 and Unixware have some stuff in /usr/ccs/lib (like -ldb) - if HOST_PLATFORM in ['osf1', 'unixware7', 'openunix8']: - self.lib_dirs += ['/usr/ccs/lib'] - - # HP-UX11iv3 keeps files in lib/hpux folders. - if HOST_PLATFORM == 'hp-ux11': - self.lib_dirs += ['/usr/lib/hpux64', '/usr/lib/hpux32'] - - if MACOS: - # This should work on any unixy platform ;-) - # If the user has bothered specifying additional -I and -L flags - # in OPT and LDFLAGS we might as well use them here. - # - # NOTE: using shlex.split would technically be more correct, but - # also gives a bootstrap problem. Let's hope nobody uses - # directories with whitespace in the name to store libraries. - cflags, ldflags = sysconfig.get_config_vars( - 'CFLAGS', 'LDFLAGS') - for item in cflags.split(): - if item.startswith('-I'): - self.inc_dirs.append(item[2:]) - - for item in ldflags.split(): - if item.startswith('-L'): - self.lib_dirs.append(item[2:]) - - def detect_simple_extensions(self): - # - # The following modules are all pretty straightforward, and compile - # on pretty much any POSIXish platform. - # - - # array objects - self.addext(Extension('array', ['arraymodule.c'])) - - # Context Variables - self.addext(Extension('_contextvars', ['_contextvarsmodule.c'])) - - # math library functions, e.g. sin() - self.addext(Extension('math', ['mathmodule.c'])) - - # complex math library functions - self.addext(Extension('cmath', ['cmathmodule.c'])) - - # libm is needed by delta_new() that uses round() and by accum() that - # uses modf(). - self.addext(Extension('_datetime', ['_datetimemodule.c'])) - self.addext(Extension('_zoneinfo', ['_zoneinfo.c'])) - # random number generator implemented in C - self.addext(Extension("_random", ["_randommodule.c"])) - self.addext(Extension("_bisect", ["_bisectmodule.c"])) - self.addext(Extension("_heapq", ["_heapqmodule.c"])) - # C-optimized pickle replacement - self.addext(Extension("_pickle", ["_pickle.c"])) - # _json speedups - self.addext(Extension("_json", ["_json.c"])) - - # profiler (_lsprof is for cProfile.py) - self.addext(Extension('_lsprof', ['_lsprof.c', 'rotatingtree.c'])) - # static Unicode character database - self.addext(Extension('unicodedata', ['unicodedata.c'])) - self.addext(Extension('_opcode', ['_opcode.c'])) - - # asyncio speedups - self.addext(Extension("_asyncio", ["_asynciomodule.c"])) - - self.addext(Extension("_queue", ["_queuemodule.c"])) - self.addext(Extension("_statistics", ["_statisticsmodule.c"])) - self.addext(Extension("_struct", ["_struct.c"])) - self.addext(Extension("_typing", ["_typingmodule.c"])) - - # Modules with some UNIX dependencies -- on by default: - # (If you have a really backward UNIX, select and socket may not be - # supported...) - - # fcntl(2) and ioctl(2) - self.addext(Extension('fcntl', ['fcntlmodule.c'])) - # grp(3) - self.addext(Extension('grp', ['grpmodule.c'])) - - self.addext(Extension('_socket', ['socketmodule.c'])) - self.addext(Extension('spwd', ['spwdmodule.c'])) - - # select(2); not on ancient System V - self.addext(Extension('select', ['selectmodule.c'])) - - # Memory-mapped files (also works on Win32). - self.addext(Extension('mmap', ['mmapmodule.c'])) - - # Lance Ellinghaus's syslog module - # syslog daemon interface - self.addext(Extension('syslog', ['syslogmodule.c'])) - - # Python interface to subinterpreter C-API. - self.addext(Extension('_xxsubinterpreters', ['_xxsubinterpretersmodule.c'])) - - # - # Here ends the simple stuff. From here on, modules need certain - # libraries, are platform-specific, or present other surprises. - # - - # Multimedia modules - # These don't work for 64-bit platforms!!! - # These represent audio samples or images as strings: - # - # Operations on audio samples - # According to #993173, this one should actually work fine on - # 64-bit platforms. - # - # audioop needs libm for floor() in multiple functions. - self.addext(Extension('audioop', ['audioop.c'])) - - # CSV files - self.addext(Extension('_csv', ['_csv.c'])) - - # POSIX subprocess module helper. - self.addext(Extension('_posixsubprocess', ['_posixsubprocess.c'])) - - def detect_test_extensions(self): - # Python C API test module - self.addext(Extension('_testcapi', ['_testcapimodule.c'])) - - # Python Argument Clinc functional test module - self.addext(Extension('_testclinic', ['_testclinic.c'])) - - # Python Internal C API test module - self.addext(Extension('_testinternalcapi', ['_testinternalcapi.c'])) - - # Python PEP-3118 (buffer protocol) test module - self.addext(Extension('_testbuffer', ['_testbuffer.c'])) - - # Test loading multiple modules from one compiled file (https://bugs.python.org/issue16421) - self.addext(Extension('_testimportmultiple', ['_testimportmultiple.c'])) - - # Test multi-phase extension module init (PEP 489) - self.addext(Extension('_testmultiphase', ['_testmultiphase.c'])) - - # Fuzz tests. - self.addext(Extension( - '_xxtestfuzz', - ['_xxtestfuzz/_xxtestfuzz.c', '_xxtestfuzz/fuzzer.c'] - )) - - def detect_readline_curses(self): - # readline - readline_termcap_library = "" - curses_library = "" - # Cannot use os.popen here in py3k. - tmpfile = os.path.join(self.build_temp, 'readline_termcap_lib') - if not os.path.exists(self.build_temp): - os.makedirs(self.build_temp) - # Determine if readline is already linked against curses or tinfo. - if sysconfig.get_config_var('HAVE_LIBREADLINE'): - if sysconfig.get_config_var('WITH_EDITLINE'): - readline_lib = 'edit' - else: - readline_lib = 'readline' - do_readline = self.compiler.find_library_file(self.lib_dirs, - readline_lib) - if CROSS_COMPILING: - ret = run_command("%s -d %s | grep '(NEEDED)' > %s" - % (sysconfig.get_config_var('READELF'), - do_readline, tmpfile)) - elif find_executable('ldd'): - ret = run_command("ldd %s > %s" % (do_readline, tmpfile)) - else: - ret = 1 - if ret == 0: - with open(tmpfile) as fp: - for ln in fp: - if 'curses' in ln: - readline_termcap_library = re.sub( - r'.*lib(n?cursesw?)\.so.*', r'\1', ln - ).rstrip() - break - # termcap interface split out from ncurses - if 'tinfo' in ln: - readline_termcap_library = 'tinfo' - break - if os.path.exists(tmpfile): - os.unlink(tmpfile) - else: - do_readline = False - # Issue 7384: If readline is already linked against curses, - # use the same library for the readline and curses modules. - if 'curses' in readline_termcap_library: - curses_library = readline_termcap_library - elif self.compiler.find_library_file(self.lib_dirs, 'ncursesw'): - curses_library = 'ncursesw' - # Issue 36210: OSS provided ncurses does not link on AIX - # Use IBM supplied 'curses' for successful build of _curses - elif AIX and self.compiler.find_library_file(self.lib_dirs, 'curses'): - curses_library = 'curses' - elif self.compiler.find_library_file(self.lib_dirs, 'ncurses'): - curses_library = 'ncurses' - elif self.compiler.find_library_file(self.lib_dirs, 'curses'): - curses_library = 'curses' - - if MACOS: - os_release = int(os.uname()[2].split('.')[0]) - dep_target = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET') - if (dep_target and - (tuple(int(n) for n in dep_target.split('.')[0:2]) - < (10, 5) ) ): - os_release = 8 - if os_release < 9: - # MacOSX 10.4 has a broken readline. Don't try to build - # the readline module unless the user has installed a fixed - # readline package - if find_file('readline/rlconf.h', self.inc_dirs, []) is None: - do_readline = False - if do_readline: - readline_libs = [readline_lib] - if readline_termcap_library: - pass # Issue 7384: Already linked against curses or tinfo. - elif curses_library: - readline_libs.append(curses_library) - elif self.compiler.find_library_file(self.lib_dirs + - ['/usr/lib/termcap'], - 'termcap'): - readline_libs.append('termcap') - self.add(Extension('readline', ['readline.c'], - library_dirs=['/usr/lib/termcap'], - libraries=readline_libs)) - else: - self.missing.append('readline') - - # Curses support, requiring the System V version of curses, often - # provided by the ncurses library. - curses_defines = [] - curses_includes = [] - panel_library = 'panel' - if curses_library == 'ncursesw': - curses_defines.append(('HAVE_NCURSESW', '1')) - if not CROSS_COMPILING: - curses_includes.append('/usr/include/ncursesw') - # Bug 1464056: If _curses.so links with ncursesw, - # _curses_panel.so must link with panelw. - panel_library = 'panelw' - if MACOS: - # On OS X, there is no separate /usr/lib/libncursesw nor - # libpanelw. If we are here, we found a locally-supplied - # version of libncursesw. There should also be a - # libpanelw. _XOPEN_SOURCE defines are usually excluded - # for OS X but we need _XOPEN_SOURCE_EXTENDED here for - # ncurses wide char support - curses_defines.append(('_XOPEN_SOURCE_EXTENDED', '1')) - elif MACOS and curses_library == 'ncurses': - # Building with the system-suppied combined libncurses/libpanel - curses_defines.append(('HAVE_NCURSESW', '1')) - curses_defines.append(('_XOPEN_SOURCE_EXTENDED', '1')) - - curses_enabled = True - if curses_library.startswith('ncurses'): - curses_libs = [curses_library] - self.add(Extension('_curses', ['_cursesmodule.c'], - include_dirs=curses_includes, - define_macros=curses_defines, - libraries=curses_libs)) - elif curses_library == 'curses' and not MACOS: - # OSX has an old Berkeley curses, not good enough for - # the _curses module. - if (self.compiler.find_library_file(self.lib_dirs, 'terminfo')): - curses_libs = ['curses', 'terminfo'] - elif (self.compiler.find_library_file(self.lib_dirs, 'termcap')): - curses_libs = ['curses', 'termcap'] - else: - curses_libs = ['curses'] - - self.add(Extension('_curses', ['_cursesmodule.c'], - define_macros=curses_defines, - libraries=curses_libs)) - else: - curses_enabled = False - self.missing.append('_curses') - - # If the curses module is enabled, check for the panel module - # _curses_panel needs some form of ncurses - skip_curses_panel = True if AIX else False - if (curses_enabled and not skip_curses_panel and - self.compiler.find_library_file(self.lib_dirs, panel_library)): - self.add(Extension('_curses_panel', ['_curses_panel.c'], - include_dirs=curses_includes, - define_macros=curses_defines, - libraries=[panel_library, *curses_libs])) - elif not skip_curses_panel: - self.missing.append('_curses_panel') - - def detect_crypt(self): - self.addext(Extension('_crypt', ['_cryptmodule.c'])) - - def detect_dbm_gdbm(self): - # Modules that provide persistent dictionary-like semantics. You will - # probably want to arrange for at least one of them to be available on - # your machine, though none are defined by default because of library - # dependencies. The Python module dbm/__init__.py provides an - # implementation independent wrapper for these; dbm/dumb.py provides - # similar functionality (but slower of course) implemented in Python. - - dbm_setup_debug = False # verbose debug prints from this script? - dbm_order = ['gdbm'] - - # libdb, gdbm and ndbm headers and libraries - have_ndbm_h = sysconfig.get_config_var("HAVE_NDBM_H") - have_gdbm_ndbm_h = sysconfig.get_config_var("HAVE_GDBM_NDBM_H") - have_gdbm_dash_ndbm_h = sysconfig.get_config_var("HAVE_GDBM_DASH_NDBM_H") - have_libndbm = sysconfig.get_config_var("HAVE_LIBNDBM") - have_libgdbm_compat = sysconfig.get_config_var("HAVE_LIBGDBM_COMPAT") - have_libdb = sysconfig.get_config_var("HAVE_LIBDB") - - # The standard Unix dbm module: - if not CYGWIN: - config_args = [arg.strip("'") - for arg in sysconfig.get_config_var("CONFIG_ARGS").split()] - dbm_args = [arg for arg in config_args - if arg.startswith('--with-dbmliborder=')] - if dbm_args: - dbm_order = [arg.split('=')[-1] for arg in dbm_args][-1].split(":") - else: - dbm_order = "gdbm:ndbm:bdb".split(":") - dbmext = None - for cand in dbm_order: - if cand == "ndbm": - if have_ndbm_h: - # Some systems have -lndbm, others have -lgdbm_compat, - # others don't have either - if have_libndbm: - ndbm_libs = ['ndbm'] - elif have_libgdbm_compat: - ndbm_libs = ['gdbm_compat'] - else: - ndbm_libs = [] - if dbm_setup_debug: print("building dbm using ndbm") - dbmext = Extension( - '_dbm', ['_dbmmodule.c'], - define_macros=[('USE_NDBM', None)], - libraries=ndbm_libs - ) - break - elif cand == "gdbm": - # dbm_open() is provided by libgdbm_compat, which wraps libgdbm - if have_libgdbm_compat and (have_gdbm_ndbm_h or have_gdbm_dash_ndbm_h): - if dbm_setup_debug: print("building dbm using gdbm") - dbmext = Extension( - '_dbm', ['_dbmmodule.c'], - define_macros=[('USE_GDBM_COMPAT', None)], - libraries=['gdbm_compat'] - ) - break - elif cand == "bdb": - if have_libdb: - if dbm_setup_debug: print("building dbm using bdb") - dbmext = Extension( - '_dbm', ['_dbmmodule.c'], - define_macros=[('USE_BERKDB', None)], - libraries=['db'] - ) - break - if dbmext is not None: - self.add(dbmext) - else: - self.missing.append('_dbm') - - # Anthony Baxter's gdbm module. GNU dbm(3) will require -lgdbm: - self.addext(Extension('_gdbm', ['_gdbmmodule.c'])) - - def detect_sqlite(self): - sources = [ - "_sqlite/blob.c", - "_sqlite/connection.c", - "_sqlite/cursor.c", - "_sqlite/microprotocols.c", - "_sqlite/module.c", - "_sqlite/prepare_protocol.c", - "_sqlite/row.c", - "_sqlite/statement.c", - "_sqlite/util.c", - ] - self.addext(Extension("_sqlite3", sources=sources)) - - def detect_platform_specific_exts(self): - # Unix-only modules - # Steen Lumholt's termios module - self.addext(Extension('termios', ['termios.c'])) - # Jeremy Hylton's rlimit interface - self.addext(Extension('resource', ['resource.c'])) - # linux/soundcard.h or sys/soundcard.h - self.addext(Extension('ossaudiodev', ['ossaudiodev.c'])) - - # macOS-only, needs SystemConfiguration and CoreFoundation framework - self.addext(Extension('_scproxy', ['_scproxy.c'])) - - def detect_compress_exts(self): - # Andrew Kuchling's zlib module. - self.addext(Extension('zlib', ['zlibmodule.c'])) - - # Helper module for various ascii-encoders. Uses zlib for an optimized - # crc32 if we have it. Otherwise binascii uses its own. - self.addext(Extension('binascii', ['binascii.c'])) - - # Gustavo Niemeyer's bz2 module. - self.addext(Extension('_bz2', ['_bz2module.c'])) - - # LZMA compression support. - self.addext(Extension('_lzma', ['_lzmamodule.c'])) - - def detect_expat_elementtree(self): - # Interface to the Expat XML parser - # - # Expat was written by James Clark and is now maintained by a group of - # developers on SourceForge; see www.libexpat.org for more information. - # The pyexpat module was written by Paul Prescod after a prototype by - # Jack Jansen. The Expat source is included in Modules/expat/. Usage - # of a system shared libexpat.so is possible with --with-system-expat - # configure option. - # - # More information on Expat can be found at www.libexpat.org. - # - self.addext(Extension('pyexpat', sources=['pyexpat.c'])) - - # Fredrik Lundh's cElementTree module. Note that this also - # uses expat (via the CAPI hook in pyexpat). - self.addext(Extension('_elementtree', sources=['_elementtree.c'])) - - def detect_multibytecodecs(self): - # Hye-Shik Chang's CJKCodecs modules. - self.addext(Extension('_multibytecodec', - ['cjkcodecs/multibytecodec.c'])) - for loc in ('kr', 'jp', 'cn', 'tw', 'hk', 'iso2022'): - self.addext(Extension( - f'_codecs_{loc}', [f'cjkcodecs/_codecs_{loc}.c'] - )) - - def detect_multiprocessing(self): - # Richard Oudkerk's multiprocessing module - multiprocessing_srcs = ['_multiprocessing/multiprocessing.c'] - if ( - sysconfig.get_config_var('HAVE_SEM_OPEN') and not - sysconfig.get_config_var('POSIX_SEMAPHORES_NOT_ENABLED') - ): - multiprocessing_srcs.append('_multiprocessing/semaphore.c') - self.addext(Extension('_multiprocessing', multiprocessing_srcs)) - self.addext(Extension('_posixshmem', ['_multiprocessing/posixshmem.c'])) - - def detect_uuid(self): - # Build the _uuid module if possible - self.addext(Extension('_uuid', ['_uuidmodule.c'])) - - def detect_modules(self): - # remove dummy extension - self.extensions = [] - - # Some C extensions are built by entries in Modules/Setup.bootstrap. - # These are extensions are required to bootstrap the interpreter or - # build process. - self.detect_simple_extensions() - self.detect_test_extensions() - self.detect_readline_curses() - self.detect_crypt() - self.detect_openssl_hashlib() - self.detect_hash_builtins() - self.detect_dbm_gdbm() - self.detect_sqlite() - self.detect_platform_specific_exts() - self.detect_nis() - self.detect_compress_exts() - self.detect_expat_elementtree() - self.detect_multibytecodecs() - self.detect_decimal() - self.detect_ctypes() - self.detect_multiprocessing() - self.detect_tkinter() - self.detect_uuid() - - # Uncomment the next line if you want to play with xxmodule.c -# self.add(Extension('xx', ['xxmodule.c'])) - - self.addext(Extension('xxlimited', ['xxlimited.c'])) - self.addext(Extension('xxlimited_35', ['xxlimited_35.c'])) - - def detect_tkinter(self): - self.addext(Extension('_tkinter', ['_tkinter.c', 'tkappinit.c'])) - - def configure_ctypes(self, ext): - return True - - def detect_ctypes(self): - # Thomas Heller's _ctypes module - - if (not sysconfig.get_config_var("LIBFFI_INCLUDEDIR") and MACOS): - self.use_system_libffi = True - else: - self.use_system_libffi = '--with-system-ffi' in sysconfig.get_config_var("CONFIG_ARGS") - - include_dirs = [] - extra_compile_args = [] - extra_link_args = [] - sources = ['_ctypes/_ctypes.c', - '_ctypes/callbacks.c', - '_ctypes/callproc.c', - '_ctypes/stgdict.c', - '_ctypes/cfield.c'] - - if MACOS: - sources.append('_ctypes/malloc_closure.c') - extra_compile_args.append('-DUSING_MALLOC_CLOSURE_DOT_C=1') - extra_compile_args.append('-DMACOSX') - include_dirs.append('_ctypes/darwin') - - elif HOST_PLATFORM == 'sunos5': - # XXX This shouldn't be necessary; it appears that some - # of the assembler code is non-PIC (i.e. it has relocations - # when it shouldn't. The proper fix would be to rewrite - # the assembler code to be PIC. - # This only works with GCC; the Sun compiler likely refuses - # this option. If you want to compile ctypes with the Sun - # compiler, please research a proper solution, instead of - # finding some -z option for the Sun compiler. - extra_link_args.append('-mimpure-text') - - ext = Extension('_ctypes', - include_dirs=include_dirs, - extra_compile_args=extra_compile_args, - extra_link_args=extra_link_args, - libraries=[], - sources=sources) - self.add(ext) - # function my_sqrt() needs libm for sqrt() - self.addext(Extension('_ctypes_test', ['_ctypes/_ctypes_test.c'])) - - ffi_inc = sysconfig.get_config_var("LIBFFI_INCLUDEDIR") - ffi_lib = None - - ffi_inc_dirs = self.inc_dirs.copy() - if MACOS: - ffi_in_sdk = os.path.join(macosx_sdk_root(), "usr/include/ffi") - - if not ffi_inc: - if os.path.exists(ffi_in_sdk): - ext.extra_compile_args.append("-DUSING_APPLE_OS_LIBFFI=1") - ffi_inc = ffi_in_sdk - ffi_lib = 'ffi' - else: - # OS X 10.5 comes with libffi.dylib; the include files are - # in /usr/include/ffi - ffi_inc_dirs.append('/usr/include/ffi') - - if not ffi_inc: - found = find_file('ffi.h', [], ffi_inc_dirs) - if found: - ffi_inc = found[0] - if ffi_inc: - ffi_h = ffi_inc + '/ffi.h' - if not os.path.exists(ffi_h): - ffi_inc = None - print('Header file {} does not exist'.format(ffi_h)) - if ffi_lib is None and ffi_inc: - for lib_name in ('ffi', 'ffi_pic'): - if (self.compiler.find_library_file(self.lib_dirs, lib_name)): - ffi_lib = lib_name - break - - if ffi_inc and ffi_lib: - ffi_headers = glob(os.path.join(ffi_inc, '*.h')) - if grep_headers_for('ffi_prep_cif_var', ffi_headers): - ext.extra_compile_args.append("-DHAVE_FFI_PREP_CIF_VAR=1") - if grep_headers_for('ffi_prep_closure_loc', ffi_headers): - ext.extra_compile_args.append("-DHAVE_FFI_PREP_CLOSURE_LOC=1") - if grep_headers_for('ffi_closure_alloc', ffi_headers): - ext.extra_compile_args.append("-DHAVE_FFI_CLOSURE_ALLOC=1") - - ext.include_dirs.append(ffi_inc) - ext.libraries.append(ffi_lib) - self.use_system_libffi = True - - if sysconfig.get_config_var('HAVE_LIBDL'): - # for dlopen, see bpo-32647 - ext.libraries.append('dl') - - def detect_decimal(self): - # Stefan Krah's _decimal module - self.addext( - Extension( - '_decimal', - ['_decimal/_decimal.c'], - # Uncomment for extra functionality: - # define_macros=[('EXTRA_FUNCTIONALITY', 1)] - ) - ) - - def detect_openssl_hashlib(self): - self.addext(Extension('_ssl', ['_ssl.c'])) - self.addext(Extension('_hashlib', ['_hashopenssl.c'])) - - def detect_hash_builtins(self): - # By default we always compile these even when OpenSSL is available - # (issue #14693). It's harmless and the object code is tiny - # (40-50 KiB per module, only loaded when actually used). Modules can - # be disabled via the --with-builtin-hashlib-hashes configure flag. - - self.addext(Extension('_md5', ['md5module.c'])) - self.addext(Extension('_sha1', ['sha1module.c'])) - self.addext(Extension('_sha256', ['sha256module.c'])) - self.addext(Extension('_sha512', ['sha512module.c'])) - self.addext(Extension('_sha3', ['_sha3/sha3module.c'])) - self.addext(Extension('_blake2', - [ - '_blake2/blake2module.c', - '_blake2/blake2b_impl.c', - '_blake2/blake2s_impl.c' - ] - )) - - def detect_nis(self): - self.addext(Extension('nis', ['nismodule.c'])) - - -class PyBuildInstall(install): - # Suppress the warning about installation into the lib_dynload - # directory, which is not in sys.path when running Python during - # installation: - def initialize_options (self): - install.initialize_options(self) - self.warn_dir=0 - - # Customize subcommands to not install an egg-info file for Python - sub_commands = [('install_lib', install.has_lib), - ('install_headers', install.has_headers), - ('install_scripts', install.has_scripts), - ('install_data', install.has_data)] - - -class PyBuildInstallLib(install_lib): - # Do exactly what install_lib does but make sure correct access modes get - # set on installed directories and files. All installed files with get - # mode 644 unless they are a shared library in which case they will get - # mode 755. All installed directories will get mode 755. - - # this is works for EXT_SUFFIX too, which ends with SHLIB_SUFFIX - shlib_suffix = sysconfig.get_config_var("SHLIB_SUFFIX") - - def install(self): - outfiles = install_lib.install(self) - self.set_file_modes(outfiles, 0o644, 0o755) - self.set_dir_modes(self.install_dir, 0o755) - return outfiles - - def set_file_modes(self, files, defaultMode, sharedLibMode): - if not files: return - - for filename in files: - if os.path.islink(filename): continue - mode = defaultMode - if filename.endswith(self.shlib_suffix): mode = sharedLibMode - log.info("changing mode of %s to %o", filename, mode) - if not self.dry_run: os.chmod(filename, mode) - - def set_dir_modes(self, dirname, mode): - for dirpath, dirnames, fnames in os.walk(dirname): - if os.path.islink(dirpath): - continue - log.info("changing mode of %s to %o", dirpath, mode) - if not self.dry_run: os.chmod(dirpath, mode) - - -class PyBuildScripts(build_scripts): - def copy_scripts(self): - outfiles, updated_files = build_scripts.copy_scripts(self) - fullversion = '-{0[0]}.{0[1]}'.format(sys.version_info) - minoronly = '.{0[1]}'.format(sys.version_info) - newoutfiles = [] - newupdated_files = [] - for filename in outfiles: - if filename.endswith('2to3'): - newfilename = filename + fullversion - else: - newfilename = filename + minoronly - log.info(f'renaming {filename} to {newfilename}') - os.rename(filename, newfilename) - newoutfiles.append(newfilename) - if filename in updated_files: - newupdated_files.append(newfilename) - return newoutfiles, newupdated_files - - -def main(): - global LIST_MODULE_NAMES - - if "--list-module-names" in sys.argv: - LIST_MODULE_NAMES = True - sys.argv.remove("--list-module-names") - - set_compiler_flags('CFLAGS', 'PY_CFLAGS_NODIST') - set_compiler_flags('LDFLAGS', 'PY_LDFLAGS_NODIST') - - class DummyProcess: - """Hack for parallel build""" - ProcessPoolExecutor = None - - sys.modules['concurrent.futures.process'] = DummyProcess - validate_tzpath() - - # turn off warnings when deprecated modules are imported - import warnings - warnings.filterwarnings("ignore",category=DeprecationWarning) - setup(# PyPI Metadata (PEP 301) - name = "Python", - version = sys.version.split()[0], - url = "https://www.python.org/%d.%d" % sys.version_info[:2], - maintainer = "Guido van Rossum and the Python community", - maintainer_email = "python-dev@python.org", - description = "A high-level object-oriented programming language", - long_description = SUMMARY.strip(), - license = "PSF license", - classifiers = [x for x in CLASSIFIERS.split("\n") if x], - platforms = ["Many"], - - # Build info - cmdclass = {'build_ext': PyBuildExt, - 'build_scripts': PyBuildScripts, - 'install': PyBuildInstall, - 'install_lib': PyBuildInstallLib}, - # A dummy module is defined here, because build_ext won't be - # called unless there's at least one extension module defined. - ext_modules=[Extension('_dummy', ['_dummy.c'])], - - # If you change the scripts installed here, you also need to - # check the PyBuildScripts command above, and change the links - # created by the bininstall target in Makefile.pre.in - scripts = ["Tools/scripts/pydoc3", "Tools/scripts/idle3", - "Tools/scripts/2to3"] - ) - -# --install-platlib -if __name__ == '__main__': - main() -- 2.34.1